diff --git a/.github/actions/get-gtest/action.yml b/.github/actions/get-gtest/action.yml index 5de2b10cd3209..d38d33eabd846 100644 --- a/.github/actions/get-gtest/action.yml +++ b/.github/actions/get-gtest/action.yml @@ -49,6 +49,6 @@ runs: - name: 'Export path to where GTest is installed' id: path-name run: | - # Export the path - echo 'path=gtest' >> $GITHUB_OUTPUT + # Export the absolute path + echo "path=`pwd`/gtest" >> $GITHUB_OUTPUT shell: bash diff --git a/.github/actions/get-jtreg/action.yml b/.github/actions/get-jtreg/action.yml index 78a3a4c9edddd..4bb671d25d1bc 100644 --- a/.github/actions/get-jtreg/action.yml +++ b/.github/actions/get-jtreg/action.yml @@ -49,6 +49,6 @@ runs: - name: 'Export path to where JTReg is installed' id: path-name run: | - # Export the path - echo 'path=jtreg/installed' >> $GITHUB_OUTPUT + # Export the absolute path + echo "path=`pwd`/jtreg/installed" >> $GITHUB_OUTPUT shell: bash diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 210d53be65819..3ea07501477f8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -325,17 +325,6 @@ jobs: bootjdk-platform: linux-x64 runs-on: ubuntu-22.04 - test-macos-x64: - name: macos-x64 - needs: - - build-macos-x64 - uses: ./.github/workflows/test.yml - with: - platform: macos-x64 - bootjdk-platform: macos-x64 - runs-on: macos-13 - xcode-toolset-version: '14.3.1' - test-macos-aarch64: name: macos-aarch64 needs: diff --git a/.jcheck/conf b/.jcheck/conf index beb280d1a04ab..6ab5c2d64c215 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -36,6 +36,6 @@ pattern=^([124-8][0-9]{6}): (\S.*)$ dirs=test/jdk|test/langtools|test/lib-test|test/hotspot/jtreg|test/jaxp [checks "copyright"] -files=^(?!LICENSE|license\.txt|.*\.bin|.*\.gif|.*\.jpg|.*\.png|.*\.icon|.*\.tiff|.*\.dat|.*\.patch|.*\.wav|.*\.class|.*-header|.*\.jar|).* +files=^(?!LICENSE|license\.txt|.*\.bin|.*\.gif|.*\.jpg|.*\.png|.*\.icon|.*\.tiff|.*\.dat|.*\.patch|.*\.wav|.*\.class|.*-header|.*\.jar).* oracle_locator=.*Copyright \(c\)(.*)Oracle and/or its affiliates\. All rights reserved\. oracle_validator=.*Copyright \(c\) (\d{4})(?:, (\d{4}))?, Oracle and/or its affiliates\. All rights reserved\. diff --git a/Makefile b/Makefile index ebe52d5d7f2fa..751574e962031 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,9 @@ # ### -### This file is just a very small wrapper needed to run the real make/Init.gmk. -### It also performs some sanity checks on make. +### This file is just a very small wrapper which will include make/PreInit.gmk, +### where the real work is done. This wrapper also performs some sanity checks +### on make that must be done before we can include another file. ### # The shell code below will be executed on /usr/bin/make on Solaris, but not in GNU Make. @@ -58,7 +59,7 @@ ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),) else makefile_path := $(lastword $(MAKEFILE_LIST)) endif -topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path)))) +TOPDIR := $(strip $(patsubst %/, %, $(dir $(makefile_path)))) -# ... and then we can include the real makefile -include $(topdir)/make/Init.gmk +# ... and then we can include the real makefile to bootstrap the build +include $(TOPDIR)/make/PreInit.gmk diff --git a/bin/idea.sh b/bin/idea.sh index c85ae294454e5..eb37964f39685 100644 --- a/bin/idea.sh +++ b/bin/idea.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,7 @@ if [ "$VERBOSE" = "true" ] ; then echo "idea template dir: $IDEA_TEMPLATE" fi -cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I $MAKE_DIR/.. idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" $CONF_ARG || exit 1 +cd $TOP ; make idea-gen-config ALLOW=IDEA_OUTPUT,MODULES IDEA_OUTPUT=$IDEA_OUTPUT MODULES="$*" $CONF_ARG || exit 1 cd $SCRIPT_DIR . $IDEA_OUTPUT/env.cfg diff --git a/doc/hotspot-style.html b/doc/hotspot-style.html index 0305bfeca03bd..9f26fc6636205 100644 --- a/doc/hotspot-style.html +++ b/doc/hotspot-style.html @@ -217,10 +217,10 @@

Source Files

should be put in the .hpp file, and not in the .inline.hpp file. This rule exists to resolve problems with circular dependencies between .inline.hpp files.

-
  • All .cpp files include precompiled.hpp as the first include -line.

  • -
  • precompiled.hpp is just a build time optimization, so don't rely -on it to resolve include problems.

  • +
  • Some build configurations use precompiled headers to speed up the +build times. The precompiled headers are included in the precompiled.hpp +file. Note that precompiled.hpp is just a build time optimization, so +don't rely on it to resolve include problems.

  • Keep the include lines alphabetically sorted.

  • Put conditional inclusions (#if ...) at the end of the include list.

  • diff --git a/doc/hotspot-style.md b/doc/hotspot-style.md index f5e59648cb23c..0150662981736 100644 --- a/doc/hotspot-style.md +++ b/doc/hotspot-style.md @@ -150,10 +150,10 @@ the first include line. Declarations needed by other files should be put in the .hpp file, and not in the .inline.hpp file. This rule exists to resolve problems with circular dependencies between .inline.hpp files. -* All .cpp files include precompiled.hpp as the first include line. - -* precompiled.hpp is just a build time optimization, so don't rely on -it to resolve include problems. +* Some build configurations use precompiled headers to speed up the +build times. The precompiled headers are included in the precompiled.hpp +file. Note that precompiled.hpp is just a build time optimization, so +don't rely on it to resolve include problems. * Keep the include lines alphabetically sorted. diff --git a/doc/hotspot-unit-tests.html b/doc/hotspot-unit-tests.html index 556cfecc42d7f..fcd4a93f8e485 100644 --- a/doc/hotspot-unit-tests.html +++ b/doc/hotspot-unit-tests.html @@ -245,7 +245,7 @@

    Error messages

    All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18) +ASSERT_TRUE((val1 == val2 && isFail(foo(8))) || i == 18) prints only one value. If you use some complex predicates, please consider EXPECT_PRED* or EXPECT_FORMAT_PRED assertions family, they check that a predicate returns true/success and diff --git a/doc/hotspot-unit-tests.md b/doc/hotspot-unit-tests.md index 62ace4ef6ee8b..e1222baa2e3a4 100644 --- a/doc/hotspot-unit-tests.md +++ b/doc/hotspot-unit-tests.md @@ -172,7 +172,7 @@ Provide informative, but not too verbose error messages. All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. -`ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)` prints only +`ASSERT_TRUE((val1 == val2 && isFail(foo(8))) || i == 18)` prints only one value. If you use some complex predicates, please consider `EXPECT_PRED*` or `EXPECT_FORMAT_PRED` assertions family, they check that a predicate returns true/success and print out all parameters values. diff --git a/make/Bundles.gmk b/make/Bundles.gmk index 2ed04c1906421..58950b5fb1f71 100644 --- a/make/Bundles.gmk +++ b/make/Bundles.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include MakeIO.gmk @@ -43,8 +42,6 @@ ifeq ($(call isBuildOs, windows), true) TAR_IGNORE_EXIT_VALUE := || test "$$$$?" = "1" endif -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Bundles-pre.gmk)) ################################################################################ # BUNDLE : Name of bundle to create # FILES : Files in BASE_DIRS to add to bundle @@ -502,11 +499,6 @@ endif ################################################################################ -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Bundles.gmk)) - -################################################################################ - product-bundles: $(PRODUCT_TARGETS) legacy-bundles: $(LEGACY_TARGETS) test-bundles: $(TEST_TARGETS) @@ -517,6 +509,10 @@ static-libs-bundles: $(STATIC_LIBS_TARGETS) static-libs-graal-bundles: $(STATIC_LIBS_GRAAL_TARGETS) jcov-bundles: $(JCOV_TARGETS) -.PHONY: all default product-bundles test-bundles \ +.PHONY: product-bundles test-bundles \ docs-jdk-bundles docs-javase-bundles docs-reference-bundles \ static-libs-bundles static-libs-graal-bundles jcov-bundles + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/CompileCommands.gmk b/make/CompileCommands.gmk index 180bc76d4b849..baf07cf2e94f4 100644 --- a/make/CompileCommands.gmk +++ b/make/CompileCommands.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ # When FIXPATH is set, let it process the file to make sure all paths are usable # by system native tools. The FIXPATH tool assumes arguments preceded by an @ @@ -50,6 +49,6 @@ $(OUTPUTDIR)/compile_commands.json: $(wildcard $(MAKESUPPORT_OUTPUTDIR)/compile- TARGETS += $(OUTPUTDIR)/compile_commands.json -all: $(TARGETS) +################################################################################ -.PHONY: all +include MakeFileEnd.gmk diff --git a/make/CompileDemos.gmk b/make/CompileDemos.gmk index 6c751552e5042..503edf18e0012 100644 --- a/make/CompileDemos.gmk +++ b/make/CompileDemos.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,23 +23,17 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # Build demos for the JDK into $(SUPPORT_OUTPUTDIR)/demos/image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include JavaCompilation.gmk include TextFileProcessing.gmk include ZipArchive.gmk -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, CompileDemos-pre.gmk)) - # Prepare the find cache. DEMO_SRC_DIRS += $(TOPDIR)/src/demo @@ -132,12 +126,19 @@ define SetupBuildDemoBody JARMAIN := $$($1_MAIN_CLASS), \ MANIFEST := $(DEMO_MANIFEST), \ EXTRA_MANIFEST_ATTR := $$($1_EXTRA_MANIFEST_ATTR), \ - SRCZIP := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1/src.zip, \ EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \ DISABLED_WARNINGS := $$($1_DISABLED_WARNINGS), \ )) $1 += $$(BUILD_DEMO_$1) + + $$(eval $$(call SetupZipArchive, ZIP_SRC_DEMO_$1, \ + SRC := $$($1_MAIN_SRC) $$($1_EXTRA_SRC_DIR), \ + ZIP := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1/src.zip, \ + EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \ + )) + + $1 += $$(ZIP_SRC_DEMO_$1) endif # Copy files. Sort is needed to remove duplicates. @@ -257,11 +258,8 @@ ifneq ($(filter images, $(MAKECMDGOALS)), ) IMAGES_TARGETS := $(COPY_TO_TEST_IMAGE) endif -################################################################################ -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, CompileDemos-post.gmk)) - -all: $(TARGETS) images: $(IMAGES_TARGETS) -.PHONY: all +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/CompileInterimLangtools.gmk b/make/CompileInterimLangtools.gmk index dbb23de093c33..c869ea160c76d 100644 --- a/make/CompileInterimLangtools.gmk +++ b/make/CompileInterimLangtools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,9 @@ # questions. # -# This must be the first rule -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include JavaCompilation.gmk @@ -148,5 +146,4 @@ TARGETS += $(BUILD_JAVAC_SERVER) ################################################################################ - -all: $(TARGETS) +include MakeFileEnd.gmk diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index 7c86b77dd31ca..b4a193dfadee6 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,12 @@ # questions. # -# This must be the first rule -default: all +include MakeFileStart.gmk + +################################################################################ -include $(SPEC) -include MakeBase.gmk -include Modules.gmk include JavaCompilation.gmk +include Modules.gmk ################################################################################ # If this is an imported module that has prebuilt classes, only compile @@ -86,7 +85,15 @@ CreateHkTargets = \ ################################################################################ # Include module specific build settings --include Java.gmk +THIS_SNIPPET := modules/$(MODULE)/Java.gmk + +ifneq ($(wildcard $(THIS_SNIPPET)), ) + include MakeSnippetStart.gmk + + include $(THIS_SNIPPET) + + include MakeSnippetEnd.gmk +endif ################################################################################ # Setup the main compilation @@ -148,6 +155,4 @@ endif ################################################################################ -all: $(TARGETS) - -.PHONY: all +include MakeFileEnd.gmk diff --git a/make/CompileModuleTools.gmk b/make/CompileModuleTools.gmk index 888b8418eea87..1208855305529 100644 --- a/make/CompileModuleTools.gmk +++ b/make/CompileModuleTools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,12 @@ # questions. # -default: all - -include $(SPEC) -include MakeBase.gmk -include JavaCompilation.gmk +include MakeFileStart.gmk ################################################################################ +include JavaCompilation.gmk + TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes # When using an external BUILDJDK, make it possible to shortcut building of @@ -64,4 +62,4 @@ TARGETS += $(BUILD_JIGSAW_TOOLS) ################################################################################ -all: $(TARGETS) +include MakeFileEnd.gmk diff --git a/make/CompileToolsHotspot.gmk b/make/CompileToolsHotspot.gmk index 3fd3e5e8b8816..1ce6578de0798 100644 --- a/make/CompileToolsHotspot.gmk +++ b/make/CompileToolsHotspot.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,12 @@ # questions. # -# This must be the first rule -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include JavaCompilation.gmk -TARGETS := - -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, hotspot/CompileTools.gmk)) - ################################################################################ # Build tools needed for the JFR source code generation @@ -51,7 +44,6 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_HOTSPOT, \ TARGETS += $(BUILD_TOOLS_HOTSPOT) +################################################################################ -all: $(TARGETS) - -.PHONY: all +include MakeFileEnd.gmk diff --git a/make/CompileToolsJdk.gmk b/make/CompileToolsJdk.gmk index 41a19f90ace77..c291dbdba0a76 100644 --- a/make/CompileToolsJdk.gmk +++ b/make/CompileToolsJdk.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,21 +23,14 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include JavaCompilation.gmk include TextFileProcessing.gmk -################################################################################ - -$(eval $(call IncludeCustomExtension, CompileTools.gmk)) - -################################################################################ - # Use += to be able to add to this from a custom extension BUILD_TOOLS_SRC_DIRS += \ $(TOPDIR)/make/jdk/src/classes \ @@ -160,4 +153,6 @@ ifeq ($(ENABLE_PANDOC), true) TARGETS += $(PANDOC_HTML_MANPAGE_FILTER_SETUP) endif -all: $(TARGETS) +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/CopyImportModules.gmk b/make/CopyImportModules.gmk index 69a42f166baab..435468e48db86 100644 --- a/make/CopyImportModules.gmk +++ b/make/CopyImportModules.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,12 @@ # questions. # +include MakeFileStart.gmk + +################################################################################ # This makefile is called for every imported module to copy the non class # contents into the exploded jdk image. - -default: all - -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk @@ -103,4 +102,6 @@ ifneq ($(CONF_DIR), ) TARGETS += $(COPY_CONF) endif -all: $(TARGETS) +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/CopyInterimTZDB.gmk b/make/CopyInterimTZDB.gmk index 1e54cd8af11e2..9305ca4c4edf3 100644 --- a/make/CopyInterimTZDB.gmk +++ b/make/CopyInterimTZDB.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,12 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk -################################################################################ - ### TZDB tool needs files from java.time.zone package define tzdb_copyfiles @@ -51,3 +48,7 @@ $(eval $(call SetupCopyFiles, COPY_INTERIM_TZDB, \ ################################################################################ all: $(COPY_INTERIM_TZDB) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/Coverage.gmk b/make/Coverage.gmk index 503acbe03ab18..2fd4e4ec6d454 100644 --- a/make/Coverage.gmk +++ b/make/Coverage.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,7 @@ # or visit www.oracle.com if you need additional information or have any # questions. -include $(SPEC) -include MakeBase.gmk +include MakeFileStart.gmk ################################################################################ @@ -47,7 +46,6 @@ $(JCOV_IMAGE_DIR)/release: $(JCOV_INPUT_IMAGE_DIR)/release -t $(JCOV_TEMP)/$(JCOV_IMAGE_SUBDIR)/template.xml \ -rt $(JCOV_HOME)/lib/jcov_network_saver.jar \ -exclude 'java.lang.Object' \ - -exclude 'jdk.internal.org.objectweb.**' \ -exclude jdk.test.Main -exclude '**\$Proxy*' \ $(JCOV_FILTERS) \ $(JCOV_TEMP)/$(JCOV_IMAGE_SUBDIR) @@ -55,3 +53,7 @@ $(JCOV_IMAGE_DIR)/release: $(JCOV_INPUT_IMAGE_DIR)/release $(RMDIR) $(JCOV_TEMP) jcov-image: $(JCOV_IMAGE_DIR)/release + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/CreateJmods.gmk b/make/CreateJmods.gmk index 86bc3b8335ee9..40bceda69a97f 100644 --- a/make/CreateJmods.gmk +++ b/make/CreateJmods.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include Execute.gmk @@ -36,8 +35,6 @@ ifeq ($(MODULE), ) $(error MODULE must be set when calling CreateJmods.gmk) endif -$(eval $(call IncludeCustomExtension, CreateJmods.gmk)) - ################################################################################ JMODS_DIR := $(IMAGES_OUTPUTDIR)/jmods @@ -187,7 +184,15 @@ endif ################################################################################ # Include module specific build settings --include Jmod.gmk +THIS_SNIPPET := modules/$(MODULE)/Jmod.gmk + +ifneq ($(wildcard $(THIS_SNIPPET)), ) + include MakeSnippetStart.gmk + + include $(THIS_SNIPPET) + + include MakeSnippetEnd.gmk +endif # Set main class ifneq ($(JMOD_FLAGS_main_class), ) @@ -266,6 +271,4 @@ TARGETS += $(create_$(JMOD_FILE)) ################################################################################ -all: $(TARGETS) - -################################################################################ +include MakeFileEnd.gmk diff --git a/make/Docs.gmk b/make/Docs.gmk index fb2726e6dadf4..be9efbdc37077 100644 --- a/make/Docs.gmk +++ b/make/Docs.gmk @@ -1,4 +1,4 @@ -# Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -22,26 +22,7 @@ # questions. # -default: all - -include $(SPEC) -include MakeBase.gmk - -include CopyFiles.gmk -include Execute.gmk -include Modules.gmk -include ModuleTools.gmk -include ProcessMarkdown.gmk -include ToolsJdk.gmk -include ZipArchive.gmk -include TextFileProcessing.gmk - -# This is needed to properly setup DOCS_MODULES. -$(eval $(call ReadImportMetaData)) - -################################################################################ -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Docs.gmk)) +include MakeFileStart.gmk ################################################################################ # This file generates all documentation for OpenJDK. @@ -54,7 +35,19 @@ $(eval $(call IncludeCustomExtension, Docs.gmk)) # # We will also generate separate, free-standing specifications from either # markdown or existing html files. -# +################################################################################ + +include CopyFiles.gmk +include Execute.gmk +include Modules.gmk +include ProcessMarkdown.gmk +include TextFileProcessing.gmk +include ZipArchive.gmk +include $(TOPDIR)/make/ModuleTools.gmk +include $(TOPDIR)/make/ToolsJdk.gmk + +# This is needed to properly setup DOCS_MODULES. +$(eval $(call ReadImportMetaData)) ################################################################################ # Javadoc settings @@ -680,7 +673,7 @@ ifeq ($(ENABLE_PANDOC), true) $(foreach m, $(ALL_MODULES), \ $(eval MAN_$m := $(call ApplySpecFilter, $(filter %.md, $(call FindFiles, \ - $(call FindModuleManDirs, $m))))) \ + $(call FindModuleManDirsForDocs, $m))))) \ $(if $(MAN_$m), \ $(eval $(call SetupProcessMarkdown, MAN_TO_HTML_$m, \ FILES := $(MAN_$m), \ @@ -761,10 +754,6 @@ $(eval $(call SetupZipArchive, BUILD_JAVADOC_ZIP, \ ZIP_TARGETS += $(BUILD_JAVADOC_ZIP) -################################################################################ -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Docs-post.gmk)) - ################################################################################ # Bundles all generated specs into a zip archive, skipping javadocs. @@ -806,7 +795,11 @@ all: docs-jdk-api-javadoc docs-jdk-api-graphs docs-javase-api-javadoc \ docs-reference-api-graphs docs-jdk-specs docs-jdk-index docs-zip \ docs-specs-zip -.PHONY: default all docs-jdk-api-javadoc docs-jdk-api-graphs \ +.PHONY: docs-jdk-api-javadoc docs-jdk-api-graphs \ docs-javase-api-javadoc docs-javase-api-graphs \ docs-reference-api-javadoc docs-reference-api-graphs docs-jdk-specs \ docs-jdk-index docs-zip docs-specs-zip + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/Doctor.gmk b/make/Doctor.gmk index 39953cd28db3f..05de0730fa14f 100644 --- a/make/Doctor.gmk +++ b/make/Doctor.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,11 @@ # questions. # -default: all - -include $(SPEC) -include MakeBase.gmk - -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Doctor.gmk)) +include MakeFileStart.gmk ################################################################################ -# # Help user diagnose possible errors and problems with the build environment. -# +################################################################################ prologue: $(ECHO) @@ -145,4 +138,8 @@ doctor: $(TARGETS) all: doctor -.PHONY: default all doctor $(TARGETS) +.PHONY: doctor $(TARGETS) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/ExplodedImageOptimize.gmk b/make/ExplodedImageOptimize.gmk index a67b987d91dd5..928ff86f10f41 100644 --- a/make/ExplodedImageOptimize.gmk +++ b/make/ExplodedImageOptimize.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,15 @@ # questions. # -# Runs a tool on the exploded image to improve performance +include MakeFileStart.gmk -default: all +################################################################################ +# Runs a tool on the exploded image to improve performance +################################################################################ -include $(SPEC) -include MakeBase.gmk include Execute.gmk include $(TOPDIR)/make/ModuleTools.gmk -################################################################################ - ALL_MODULEINFO_CLASSES := $(wildcard $(JDK_OUTPUTDIR)/modules/*/module-info.class) $(eval $(call SetupExecute, optimize_image, \ @@ -47,6 +45,4 @@ TARGETS := $(optimize_image_TARGET) ################################################################################ -all: $(TARGETS) - -.PHONY: all default +include MakeFileEnd.gmk diff --git a/make/GenerateLinkOptData.gmk b/make/GenerateLinkOptData.gmk index b6989042d6aed..5fc745ba223f4 100644 --- a/make/GenerateLinkOptData.gmk +++ b/make/GenerateLinkOptData.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,12 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # Generate classlist ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include JavaCompilation.gmk @@ -148,4 +145,4 @@ TARGETS += $(COPY_JLI_TRACE) ################################################################################ -all: $(TARGETS) +include MakeFileEnd.gmk diff --git a/make/GenerateModuleSummary.gmk b/make/GenerateModuleSummary.gmk index 854d938c9caa4..5c6ec055c45f3 100644 --- a/make/GenerateModuleSummary.gmk +++ b/make/GenerateModuleSummary.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,11 @@ # questions. # -# Default target declared first -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk -include ModuleTools.gmk +################################################################################ + +include $(TOPDIR)/make/ModuleTools.gmk GENGRAPHS_DIR := $(IMAGES_OUTPUTDIR)/gengraphs SPEC_DOTFILES_DIR := $(GENGRAPHS_DIR)/spec-dotfiles @@ -50,3 +49,7 @@ $(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/tec $(TOOL_MODULESUMMARY) -o $@ --module-path $(IMAGES_OUTPUTDIR)/jmods all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html $(SPEC_DOTFILES_DIR)/java.se.dot + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/Global.gmk b/make/Global.gmk index 86487c1c2fc19..512c5b963aa99 100644 --- a/make/Global.gmk +++ b/make/Global.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -108,6 +108,7 @@ help: $(info $(_) MICRO="OPT1=x;OPT2=y" # Control the MICRO test harness, use 'make test-only MICRO=help' to list) $(info $(_) TEST_OPTS="OPT1=x;..." # Generic control of all test harnesses) $(info $(_) TEST_VM_OPTS="ARG ..." # Same as setting TEST_OPTS to VM_OPTIONS="ARG ...") + $(info $(_) ALLOW="FOO,BAR" # Do not warn that FOO and BAR are non-control variables) $(info ) $(if $(all_confs), $(info Available configurations in $(build_dir):) $(foreach var,$(all_confs),$(info * $(var))), \ $(info No configurations were found in $(build_dir).) $(info Run 'bash configure' to create a configuration.)) @@ -120,12 +121,12 @@ print-configurations: @true test-prebuilt: - @( cd $(topdir) && \ + @( cd $(TOPDIR) && \ $(MAKE) --no-print-directory -r -R -I make/common/ -f make/RunTestsPrebuilt.gmk \ test-prebuilt CUSTOM_MAKE_DIR=$(CUSTOM_MAKE_DIR) TEST="$(TEST)" ) test-prebuilt-with-exit-code: - @( cd $(topdir) && \ + @( cd $(TOPDIR) && \ $(MAKE) --no-print-directory -r -R -I make/common/ -f make/RunTestsPrebuilt.gmk \ test-prebuilt-with-exit-code CUSTOM_MAKE_DIR=$(CUSTOM_MAKE_DIR) TEST="$(TEST)" ) diff --git a/make/GraalBuilderImage.gmk b/make/GraalBuilderImage.gmk index 7fa90c6601966..d707e067a5505 100644 --- a/make/GraalBuilderImage.gmk +++ b/make/GraalBuilderImage.gmk @@ -23,19 +23,14 @@ # questions. # +include MakeFileStart.gmk + +################################################################################ # This makefile creates a jdk image overlaid with statically linked core # libraries. - -default: all - -include $(SPEC) -include MakeBase.gmk - -include CopyFiles.gmk - ################################################################################ -TARGETS := +include CopyFiles.gmk $(eval $(call SetupCopyFiles, COPY_JDK_IMG, \ SRC := $(JDK_IMAGE_DIR)/, \ @@ -54,6 +49,4 @@ TARGETS += $(COPY_STATIC_LIBS) ################################################################################ -all: $(TARGETS) - -.PHONY: all +include MakeFileEnd.gmk diff --git a/make/Hsdis.gmk b/make/Hsdis.gmk index 13d84f964bcdc..a0fc031be1b7a 100644 --- a/make/Hsdis.gmk +++ b/make/Hsdis.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,14 @@ # questions. # -default: all - -include $(SPEC) -include MakeBase.gmk -include JdkNativeCompilation.gmk +include MakeFileStart.gmk ################################################################################ # This makefile compiles and installs the hsdis library -# ################################################################################ +include JdkNativeCompilation.gmk + HSDIS_OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/hsdis REAL_HSDIS_NAME := hsdis-$(OPENJDK_TARGET_CPU_LEGACY_LIB)$(SHARED_LIBRARY_SUFFIX) BUILT_HSDIS_LIB := $(HSDIS_OUTPUT_DIR)/$(REAL_HSDIS_NAME) @@ -201,8 +198,8 @@ endif TARGETS += install -################################################################################ +.PHONY: build install -all: $(TARGETS) +################################################################################ -.PHONY: all default build install +include MakeFileEnd.gmk diff --git a/make/Images.gmk b/make/Images.gmk index c5d0ef11b5d2e..6c859fce7a543 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include DebugInfoUtils.gmk @@ -37,9 +36,6 @@ include Utils.gmk JDK_TARGETS := JRE_TARGETS := -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, Images-pre.gmk)) - ################################################################################ # All modules for the current target platform. @@ -309,12 +305,6 @@ $(call SetupCopyDebuginfo,SYMBOLS) ################################################################################ -# Include custom post hook here to make it possible to augment the target lists -# before actual target prerequisites are declared. -$(eval $(call IncludeCustomExtension, Images-post.gmk)) - -################################################################################ - $(JRE_TARGETS): $(JLINK_JRE_TARGETS) $(JDK_TARGETS): $(JLINK_JDK_TARGETS) @@ -324,4 +314,8 @@ symbols: $(SYMBOLS_TARGETS) all: jdk jre symbols -.PHONY: default all jdk jre symbols +.PHONY: jdk jre symbols + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/Init.gmk b/make/Init.gmk index f2cfe3625a520..6da2fb985b62f 100644 --- a/make/Init.gmk +++ b/make/Init.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,263 +23,84 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ -# This is the bootstrapping part of the build. This file is included from the -# top level Makefile, and is responsible for launching the Main.gmk file with -# the proper make and the proper make arguments. +# Init.gmk sits between PreInit.gmk and Main.gmk when bootstrapping the build. +# It is called from PreInit.gmk, and its main responsibility is to launch +# Main.gmk with the proper make and the proper make arguments. +# PreMain.gmk has provided us with a proper SPEC. This allows us to use the +# value of $(MAKE) for all further make calls. ################################################################################ -# This must be the first rule -default: -.PHONY: default +# Our helper functions. +include $(TOPDIR)/make/InitSupport.gmk +include LogUtils.gmk + +# Force early generation of module-deps.gmk and find-tests.gmk +GENERATE_MODULE_DEPS_FILE := true +include Modules.gmk +GENERATE_FIND_TESTS_FILE := true +include FindTests.gmk # Inclusion of this pseudo-target will cause make to execute this file # serially, regardless of -j. .NOTPARALLEL: -ifeq ($(HAS_SPEC), ) - ############################################################################## - # This is the default mode. We have not been recursively called with a SPEC. - ############################################################################## - - # Include our helper functions. - include $(topdir)/make/InitSupport.gmk - - # Here are "global" targets, i.e. targets that can be executed without having - # a configuration. This will define ALL_GLOBAL_TARGETS. - include $(topdir)/make/Global.gmk - - # Targets provided by Init.gmk. - ALL_INIT_TARGETS := print-modules print-targets print-configuration \ - print-tests reconfigure pre-compare-build post-compare-build - - # CALLED_TARGETS is the list of targets that the user provided, - # or "default" if unspecified. - CALLED_TARGETS := $(if $(MAKECMDGOALS), $(MAKECMDGOALS), default) - - # Extract non-global targets that require a spec file. - CALLED_SPEC_TARGETS := $(filter-out $(ALL_GLOBAL_TARGETS), $(CALLED_TARGETS)) - - # If we have only global targets, or if we are called with -qp (assuming an - # external part, e.g. bash completion, is trying to understand our targets), - # we will skip SPEC location and the sanity checks. - ifeq ($(CALLED_SPEC_TARGETS), ) - ONLY_GLOBAL_TARGETS := true - endif - ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq) - ONLY_GLOBAL_TARGETS := true - endif - - ifeq ($(ONLY_GLOBAL_TARGETS), true) - ############################################################################ - # We have only global targets, or are called with -pq. - ############################################################################ - - ifeq ($(wildcard $(SPEC)), ) - # If we have no SPEC provided, we will just make a "best effort" target list. - # First try to grab any available pre-existing main-targets.gmk. - main_targets_file := $(firstword $(wildcard $(build_dir)/*/make-support/main-targets.gmk)) - ifneq ($(main_targets_file), ) - # Extract the SPEC that corresponds to this main-targets.gmk file. - SPEC := $(patsubst %/make-support/main-targets.gmk, %/spec.gmk, $(main_targets_file)) - else - # None found, pick an arbitrary SPEC for which to generate a file - SPEC := $(firstword $(all_spec_files)) - endif - endif - - ifneq ($(wildcard $(SPEC)), ) - $(eval $(call DefineMainTargets, LAZY, $(SPEC))) - else - # If we have no configurations we can not provide any main targets. - ALL_MAIN_TARGETS := - endif +# Parse COMPARE_BUILD (for makefile development) +$(eval $(call ParseCompareBuild)) - ALL_TARGETS := $(sort $(ALL_GLOBAL_TARGETS) $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS)) +# Setup reproducible build environment +$(eval $(call SetupReproducibleBuild)) - # Just list all our targets. - $(ALL_TARGETS): - - .PHONY: $(ALL_TARGETS) - - else - ############################################################################ - # This is the normal case, we have been called from the command line by the - # user and we need to call ourself back with a proper SPEC. - # We have at least one non-global target, so we need to find a spec file. - ############################################################################ - - # Basic checks on environment and command line. - $(eval $(call CheckControlVariables)) - $(eval $(call CheckDeprecatedEnvironment)) - $(eval $(call CheckInvalidMakeFlags)) - - # Check that CONF_CHECK is valid. - $(eval $(call ParseConfCheckOption)) - - # Check that the LOG given is valid, and set LOG_LEVEL, LOG_NOFILE, MAKE_LOG_VARS and MAKE_LOG_FLAGS. +# If no LOG= was given on command line, but we have a non-standard default +# value, use that instead and re-parse log level. +ifeq ($(LOG), ) + ifneq ($(DEFAULT_LOG), ) + override LOG := $(DEFAULT_LOG) $(eval $(call ParseLogLevel)) - - # After this SPECS contain 1..N spec files (otherwise ParseConfAndSpec fails). - $(eval $(call ParseConfAndSpec)) - - # Extract main targets from Main.gmk using the spec(s) provided. In theory, - # with multiple specs, we should find the intersection of targets provided - # by all specs, but we approximate this by an arbitrary spec from the list. - # This will setup ALL_MAIN_TARGETS. - $(eval $(call DefineMainTargets, FORCE, $(firstword $(SPECS)))) - - # Separate called targets depending on type. - INIT_TARGETS := $(filter $(ALL_INIT_TARGETS), $(CALLED_SPEC_TARGETS)) - MAIN_TARGETS := $(filter $(ALL_MAIN_TARGETS), $(CALLED_SPEC_TARGETS)) - SEQUENTIAL_TARGETS := $(filter dist-clean clean%, $(MAIN_TARGETS)) - PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS)) - - # The spec files depend on the autoconf source code. This check makes sure - # the configuration is up to date after changes to configure. - $(SPECS): $(wildcard $(topdir)/make/autoconf/*) \ - $(if $(CUSTOM_CONFIG_DIR), $(wildcard $(CUSTOM_CONFIG_DIR)/*)) \ - $(addprefix $(topdir)/make/conf/, version-numbers.conf branding.conf) \ - $(if $(CUSTOM_CONF_DIR), $(wildcard $(addprefix $(CUSTOM_CONF_DIR)/, \ - version-numbers.conf branding.conf))) - ifeq ($(CONF_CHECK), fail) - @echo Error: The configuration is not up to date for \ - "'$(lastword $(subst /, , $(dir $@)))'." - $(call PrintConfCheckFailed) - @exit 2 - else ifeq ($(CONF_CHECK), auto) - @echo Note: The configuration is not up to date for \ - "'$(lastword $(subst /, , $(dir $@)))'." - @( cd $(topdir) && \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$@ HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - reconfigure ) - else ifeq ($(CONF_CHECK), ignore) - # Do nothing - endif - - # Do not let make delete spec files even if aborted while doing a reconfigure - .PRECIOUS: $(SPECS) - - # Unless reconfigure is explicitly called, let all main targets depend on - # the spec files to be up to date. - ifeq ($(findstring reconfigure, $(INIT_TARGETS)), ) - $(MAIN_TARGETS): $(SPECS) - endif - - make-info: - ifneq ($(findstring $(LOG_LEVEL), info debug trace), ) - $(info Running make as '$(strip $(MAKE) $(MFLAGS) \ - $(COMMAND_LINE_VARIABLES) $(MAKECMDGOALS))') - endif - - MAKE_INIT_WITH_SPEC_ARGUMENTS := ACTUAL_TOPDIR=$(topdir) \ - USER_MAKE_VARS="$(USER_MAKE_VARS)" MAKE_LOG_FLAGS=$(MAKE_LOG_FLAGS) \ - $(MAKE_LOG_VARS) \ - INIT_TARGETS="$(INIT_TARGETS)" \ - SEQUENTIAL_TARGETS="$(SEQUENTIAL_TARGETS)" \ - PARALLEL_TARGETS="$(PARALLEL_TARGETS)" - - # Now the init and main targets will be called, once for each SPEC. The - # recipe will be run once for every target specified, but we only want to - # execute the recipe a single time, hence the TARGET_DONE with a dummy - # command if true. - # The COMPARE_BUILD part implements special support for makefile development. - $(ALL_INIT_TARGETS) $(ALL_MAIN_TARGETS): make-info - @$(if $(TARGET_DONE), \ - true \ - , \ - ( cd $(topdir) && \ - $(foreach spec, $(SPECS), \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \ - main && \ - $(if $(and $(COMPARE_BUILD), $(PARALLEL_TARGETS)), \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - COMPARE_BUILD="$(COMPARE_BUILD)" pre-compare-build && \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true $(MAKE_INIT_WITH_SPEC_ARGUMENTS) \ - COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" main && \ - $(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -f $(topdir)/make/Init.gmk \ - SPEC=$(spec) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) \ - COMPARE_BUILD="$(COMPARE_BUILD):NODRYRUN=true" post-compare-build && \ - ) \ - ) true ) \ - $(eval TARGET_DONE=true) \ - ) - - .PHONY: $(ALL_MAIN_TARGETS) $(ALL_INIT_TARGETS) - - endif # $(ONLY_GLOBAL_TARGETS)!=true - -else # HAS_SPEC=true - - ############################################################################## - # Now we have a spec. This part provides the "main" target that acts as a - # trampoline to call the Main.gmk with the value of $(MAKE) found in the spec - # file. - ############################################################################## - - include $(SPEC) - - # Our helper functions. - include $(TOPDIR)/make/InitSupport.gmk - - # Parse COMPARE_BUILD (for makefile development) - $(eval $(call ParseCompareBuild)) - - # Setup reproducible build environment - $(eval $(call SetupReproducibleBuild)) - - # If no LOG= was given on command line, but we have a non-standard default - # value, use that instead and re-parse log level. - ifeq ($(LOG), ) - ifneq ($(DEFAULT_LOG), ) - override LOG := $(DEFAULT_LOG) - $(eval $(call ParseLogLevel)) - endif endif +endif - ifeq ($(LOG_NOFILE), true) - # Disable build log if LOG=[level,]nofile was given - override BUILD_LOG_PIPE := - override BUILD_LOG_PIPE_SIMPLE := - endif +ifeq ($(LOG_NOFILE), true) + # Disable build log if LOG=[level,]nofile was given + override BUILD_LOG_PIPE := + override BUILD_LOG_PIPE_SIMPLE := +endif - ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean) - # We can't have a log file if we're about to remove it. - override BUILD_LOG_PIPE := - override BUILD_LOG_PIPE_SIMPLE := - endif +ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean) + # We can't have a log file if we're about to remove it. + override BUILD_LOG_PIPE := + override BUILD_LOG_PIPE_SIMPLE := +endif - ifeq ($(OUTPUT_SYNC_SUPPORTED), true) - OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC) - endif +ifeq ($(OUTPUT_SYNC_SUPPORTED), true) + OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC) +endif - ############################################################################## - # Init targets - ############################################################################## +############################################################################## +# Init targets. These are handled fully, here and now. +############################################################################## - print-modules: +print-modules: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-modules ) - print-targets: +print-targets: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-targets ) - print-tests: +print-tests: ( cd $(TOPDIR) && \ $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ NO_RECIPES=true print-tests ) - print-configuration: - $(ECHO) $(CONFIGURE_COMMAND_LINE) +print-configuration: + $(ECHO) $(CONFIGURE_COMMAND_LINE) - reconfigure: +reconfigure: ifneq ($(REAL_CONFIGURE_COMMAND_EXEC_FULL), ) $(ECHO) "Re-running configure using original command line '$(REAL_CONFIGURE_COMMAND_EXEC_SHORT) $(REAL_CONFIGURE_COMMAND_LINE)'" $(eval RECONFIGURE_COMMAND := $(REAL_CONFIGURE_COMMAND_EXEC_FULL) $(REAL_CONFIGURE_COMMAND_LINE)) @@ -295,25 +116,27 @@ else # HAS_SPEC=true CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \ $(RECONFIGURE_COMMAND) ) - ############################################################################## - # The main target, for delegating into Main.gmk - ############################################################################## +.PHONY: print-modules print-targets print-tests print-configuration reconfigure - MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) - # If building the default target, add what they are to the description. - DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS)) - ifeq ($(DESCRIPTION_TARGETS), default) - DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET)) - endif - TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ - '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)' +############################################################################## +# The main target. This will delegate all other targets into Main.gmk. +############################################################################## - # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls. - # We need to clear it of the init-specific variables. The user-specified - # variables are explicitly propagated using $(USER_MAKE_VARS). - main: MAKEOVERRIDES := +MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) +# If building the default target, add what they are to the description. +DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS)) +ifeq ($(DESCRIPTION_TARGETS), default) + DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET)) +endif +TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ + '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)' + +# MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls. +# We need to clear it of the init-specific variables. The user-specified +# variables are explicitly propagated using $(USER_MAKE_VARS). +main: MAKEOVERRIDES := - main: $(INIT_TARGETS) +main: $(INIT_TARGETS) ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), ) $(call RotateLogFiles) $(PRINTF) "Building $(TARGET_DESCRIPTION)\n" $(BUILD_LOG_PIPE_SIMPLE) @@ -333,14 +156,14 @@ else # HAS_SPEC=true # treat it as NOT using jobs at all. ( cd $(TOPDIR) && \ $(NICE) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \ - $(if $(JOBS), -j $(JOBS)) \ + $(if $(JOBS), -j $(JOBS)) \ -f make/Main.gmk $(USER_MAKE_VARS) \ $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) $(BUILD_LOG_PIPE) || \ ( exitcode=$$? && \ $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" \ $(BUILD_LOG_PIPE_SIMPLE) && \ cd $(TOPDIR) && $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk \ - HAS_SPEC=true on-failure ; \ + on-failure ; \ exit $$exitcode ) ) $(call CleanupJavacServer) $(call StopGlobalTimer) @@ -353,7 +176,7 @@ else # HAS_SPEC=true $(call ReportProfileTimes) endif - on-failure: +on-failure: $(call CleanupJavacServer) $(call StopGlobalTimer) $(call ReportBuildTimes) @@ -365,15 +188,18 @@ else # HAS_SPEC=true $(call CleanupCompareBuild) endif - # Support targets for COMPARE_BUILD, used for makefile development - pre-compare-build: +# Support targets for COMPARE_BUILD, used for makefile development +pre-compare-build: $(call WaitForJavacServerFinish) $(call PrepareCompareBuild) - post-compare-build: +post-compare-build: $(call WaitForJavacServerFinish) $(call CleanupCompareBuild) $(call CompareBuildDoComparison) - .PHONY: print-targets print-modules reconfigure main on-failure -endif +.PHONY: main on-failure pre-compare-build post-compare-build + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/InitSupport.gmk b/make/InitSupport.gmk index eea593a80db95..a9af44e4225b1 100644 --- a/make/InitSupport.gmk +++ b/make/InitSupport.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,396 +23,114 @@ # questions. # +include MakeIncludeStart.gmk +ifeq ($(INCLUDE), true) + ################################################################################ # This file contains helper functions for Init.gmk. -# It is divided in two parts, depending on if a SPEC is present or not -# (HAS_SPEC is true or not). ################################################################################ -ifndef _INITSUPPORT_GMK -_INITSUPPORT_GMK := 1 - -ifeq ($(HAS_SPEC), ) - - # COMMA is defined in spec.gmk, but that is not included yet - COMMA := , - - # Include the corresponding closed file, if present. - ifneq ($(CUSTOM_MAKE_DIR), ) - -include $(CUSTOM_MAKE_DIR)/InitSupport.gmk - endif - - ############################################################################## - # Helper functions for the initial part of Init.gmk, before the spec file is - # loaded. Most of these functions provide parsing and setting up make options - # from the command-line. - ############################################################################## - - # Make control variables, handled by Init.gmk - INIT_CONTROL_VARIABLES += LOG CONF CONF_NAME SPEC JOBS TEST_JOBS CONF_CHECK \ - COMPARE_BUILD JTREG GTEST MICRO TEST_OPTS TEST_VM_OPTS TEST_DEPS - - # All known make control variables - MAKE_CONTROL_VARIABLES := $(INIT_CONTROL_VARIABLES) TEST JDK_FILTER SPEC_FILTER - - # Define a simple reverse function. - # Should maybe move to MakeBase.gmk, but we can't include that file now. - reverse = \ - $(if $(strip $(1)), $(call reverse, $(wordlist 2, $(words $(1)), $(1)))) \ - $(firstword $(1)) - - # The variable MAKEOVERRIDES contains variable assignments from the command - # line, but in reverse order to what the user entered. - # The '§' <=> '\ 'dance is needed to keep values with space in them connected. - COMMAND_LINE_VARIABLES := $(subst §,\ , $(call reverse, $(subst \ ,§,$(MAKEOVERRIDES)))) - - # A list like FOO="val1" BAR="val2" containing all user-supplied make - # variables that we should propagate. - # The '§' <=> '\ 'dance is needed to keep values with space in them connected. - USER_MAKE_VARS := $(subst §,\ , $(filter-out $(addsuffix =%, $(INIT_CONTROL_VARIABLES)), \ - $(subst \ ,§,$(MAKEOVERRIDES)))) - - # Setup information about available configurations, if any. - ifneq ($(CUSTOM_ROOT), ) - build_dir = $(CUSTOM_ROOT)/build - else - build_dir = $(topdir)/build +# Define basic logging setup +BUILD_LOG := $(OUTPUTDIR)/build.log +BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log + +BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait +# Use this for simple echo/printf commands that are never expected to print +# to stderr. +BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG) + +# Setup the build environment to match the requested specification on +# level of reproducible builds +define SetupReproducibleBuild + ifeq ($$(SOURCE_DATE), updated) + # For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk + export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s") + export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH)) endif - all_spec_files = $(wildcard $(build_dir)/*/spec.gmk) - # Extract the configuration names from the path - all_confs = $(patsubst %/spec.gmk, %, $(patsubst $(build_dir)/%, %, $(all_spec_files))) - - # Check for unknown command-line variables - define CheckControlVariables - command_line_variables := $$(strip $$(foreach var, \ - $$(subst \ ,_,$$(MAKEOVERRIDES)), \ - $$(firstword $$(subst =, , $$(var))))) - unknown_command_line_variables := $$(strip \ - $$(filter-out $$(MAKE_CONTROL_VARIABLES), $$(command_line_variables))) - ifneq ($$(unknown_command_line_variables), ) - $$(info Note: Command line contains non-control variables:) - $$(foreach var, $$(unknown_command_line_variables), $$(info * $$(var)=$$($$(var)))) - $$(info Make sure it is not mistyped, and that you intend to override this variable.) - $$(info 'make help' will list known control variables.) - $$(info ) - endif - endef - - # Check for deprecated ALT_ variables - define CheckDeprecatedEnvironment - defined_alt_variables := $$(filter ALT_%, $$(.VARIABLES)) - ifneq ($$(defined_alt_variables), ) - $$(info Warning: You have the following ALT_ variables set:) - $$(foreach var, $$(defined_alt_variables), $$(info * $$(var)=$$($$(var)))) - $$(info ALT_ variables are deprecated, and may result in a failed build.) - $$(info Please clean your environment.) - $$(info ) - endif - endef - - # Check for invalid make flags like -j - define CheckInvalidMakeFlags - # This is a trick to get this rule to execute before any other rules - # MAKEFLAGS only indicate -j if read in a recipe (!) - $$(topdir)/make/Init.gmk: .FORCE - $$(if $$(findstring --jobserver, $$(MAKEFLAGS)), \ - $$(info Error: 'make -jN' is not supported, use 'make JOBS=N') \ - $$(error Cannot continue) \ - ) - .FORCE: - .PHONY: .FORCE - endef - - # Check that the CONF_CHECK option is valid and set up handling - define ParseConfCheckOption - ifeq ($$(CONF_CHECK), ) - # Default behavior is fail - CONF_CHECK := fail - else ifneq ($$(filter-out auto fail ignore, $$(CONF_CHECK)), ) - $$(info Error: CONF_CHECK must be one of: auto, fail or ignore.) - $$(error Cannot continue) - endif - endef - - define ParseConfAndSpec - ifneq ($$(origin SPEC), undefined) - # We have been given a SPEC, check that it works out properly - ifneq ($$(origin CONF), undefined) - # We also have a CONF argument. We can't have both. - $$(info Error: Cannot use CONF=$$(CONF) and SPEC=$$(SPEC) at the same time. Choose one.) - $$(error Cannot continue) - endif - ifneq ($$(origin CONF_NAME), undefined) - # We also have a CONF_NAME argument. We can't have both. - $$(info Error: Cannot use CONF_NAME=$$(CONF_NAME) and SPEC=$$(SPEC) at the same time. Choose one.) - $$(error Cannot continue) - endif - ifeq ($$(wildcard $$(SPEC)), ) - $$(info Error: Cannot locate spec.gmk, given by SPEC=$$(SPEC).) - $$(error Cannot continue) - endif - ifeq ($$(filter /%, $$(SPEC)), ) - # If given with relative path, make it absolute - SPECS := $$(CURDIR)/$$(strip $$(SPEC)) - else - SPECS := $$(SPEC) - endif +endef - # For now, unset this SPEC variable. - override SPEC := +# Parse COMPARE_BUILD into COMPARE_BUILD_* +# Syntax: COMPARE_BUILD=CONF=:PATCH=: +# MAKE=:COMP_OPTS=: +# COMP_DIR=|: +# FAIL= +# If neither CONF or PATCH is given, assume means CONF if it +# begins with "--", otherwise assume it means PATCH. +# MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified. +# If any value contains "+", it will be replaced by space. +# FAIL can be set to false to have the return value of compare be ignored. +define ParseCompareBuild + ifneq ($$(COMPARE_BUILD), ) + COMPARE_BUILD_OUTPUTDIR := $(WORKSPACE_ROOT)/build/compare-build/$(CONF_NAME) + COMPARE_BUILD_FAIL := true + + ifneq ($$(findstring :, $$(COMPARE_BUILD)), ) + $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \ + $$(if $$(filter PATCH=%, $$(part)), \ + $$(eval COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(part)))) \ + ) \ + $$(if $$(filter CONF=%, $$(part)), \ + $$(eval COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ + ) \ + $$(if $$(filter MAKE=%, $$(part)), \ + $$(eval COMPARE_BUILD_MAKE = $$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ + ) \ + $$(if $$(filter COMP_OPTS=%, $$(part)), \ + $$(eval COMPARE_BUILD_COMP_OPTS = $$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ + ) \ + $$(if $$(filter COMP_DIR=%, $$(part)), \ + $$(eval COMPARE_BUILD_COMP_DIR = $$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ + ) \ + $$(if $$(filter FAIL=%, $$(part)), \ + $$(eval COMPARE_BUILD_FAIL = $$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ + ) \ + $$(if $$(filter NODRYRUN=%, $$(part)), \ + $$(eval COMPARE_BUILD_NODRYRUN = $$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ + ) \ + ) else - # Use spec.gmk files in the build output directory - ifeq ($$(all_spec_files), ) - ifneq ($(CUSTOM_ROOT), ) - $$(info Error: No configurations found for $$(CUSTOM_ROOT).) - else - $$(info Error: No configurations found for $$(topdir).) - endif - $$(info Please run 'bash configure' to create a configuration.) - $$(info ) - $$(error Cannot continue) - endif - - ifneq ($$(origin CONF_NAME), undefined) - ifneq ($$(origin CONF), undefined) - # We also have a CONF argument. We can't have both. - $$(info Error: Cannot use CONF=$$(CONF) and CONF_NAME=$$(CONF_NAME) at the same time. Choose one.) - $$(error Cannot continue) - endif - matching_conf := $$(strip $$(filter $$(CONF_NAME), $$(all_confs))) - ifeq ($$(matching_conf), ) - $$(info Error: No configurations found matching CONF_NAME=$$(CONF_NAME).) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(error Cannot continue) - else ifneq ($$(words $$(matching_conf)), 1) - $$(info Error: Matching more than one configuration CONF_NAME=$$(CONF_NAME).) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(error Cannot continue) - else - $$(info Building configuration '$$(matching_conf)' (matching CONF_NAME=$$(CONF_NAME))) - endif - # Create a SPEC definition. This will contain the path to exactly one spec file. - SPECS := $$(build_dir)/$$(matching_conf)/spec.gmk - else ifneq ($$(origin CONF), undefined) - # User have given a CONF= argument. - ifeq ($$(CONF), ) - # If given CONF=, match all configurations - matching_confs := $$(strip $$(all_confs)) - else - # Otherwise select those that contain the given CONF string - ifeq ($$(patsubst !%,,$$(CONF)), ) - # A CONF starting with ! means we should negate the search term - matching_confs := $$(strip $$(foreach var, $$(all_confs), \ - $$(if $$(findstring $$(subst !,,$$(CONF)), $$(var)), ,$$(var)))) - else - matching_confs := $$(strip $$(foreach var, $$(all_confs), \ - $$(if $$(findstring $$(CONF), $$(var)), $$(var)))) - endif - ifneq ($$(filter $$(CONF), $$(matching_confs)), ) - # If we found an exact match, use that - matching_confs := $$(CONF) - # Don't repeat this output on make restarts caused by including - # generated files. - ifeq ($$(MAKE_RESTARTS), ) - $$(info Using exact match for CONF=$$(CONF) (other matches are possible)) - endif - endif - endif - ifeq ($$(matching_confs), ) - $$(info Error: No configurations found matching CONF=$$(CONF).) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(error Cannot continue) - else - # Don't repeat this output on make restarts caused by including - # generated files. - ifeq ($$(MAKE_RESTARTS), ) - ifeq ($$(words $$(matching_confs)), 1) - ifneq ($$(findstring $$(LOG_LEVEL), info debug trace), ) - $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF))) - endif - else - $$(info Building these configurations (matching CONF=$$(CONF)):) - $$(foreach var, $$(matching_confs), $$(info * $$(var))) - endif - endif - endif - - # Create a SPEC definition. This will contain the path to one or more spec.gmk files. - SPECS := $$(addsuffix /spec.gmk, $$(addprefix $$(build_dir)/, $$(matching_confs))) + # Separate handling for single field case, to allow for spaces in values. + ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), ) + COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) + else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), ) + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) + else ifneq ($$(filter --%, $$(COMPARE_BUILD)), ) + # Assume CONF if value begins with -- + COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(COMPARE_BUILD))) else - # No CONF or SPEC given, check the available configurations - ifneq ($$(words $$(all_spec_files)), 1) - $$(info Error: No CONF given, but more than one configuration found.) - $$(info Available configurations in $$(build_dir):) - $$(foreach var, $$(all_confs), $$(info * $$(var))) - $$(info Please retry building with CONF= (or SPEC=).) - $$(info ) - $$(error Cannot continue) - endif - - # We found exactly one configuration, use it - SPECS := $$(strip $$(all_spec_files)) + # Otherwise assume patch file + COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) endif endif - endef - - # Extract main targets from Main.gmk using the spec provided in $2. - # - # Param 1: FORCE = force generation of main-targets.gmk or LAZY = do not force. - # Param 2: The SPEC file to use. - define DefineMainTargets - - # We will start by making sure the main-targets.gmk file is removed, if - # make has not been restarted. By the -include, we will trigger the - # rule for generating the file (which is never there since we removed it), - # thus generating it fresh, and make will restart, incrementing the restart - # count. - main_targets_file := $$(dir $(strip $2))make-support/main-targets.gmk - - ifeq ($$(MAKE_RESTARTS), ) - # Only do this if make has not been restarted, and if we do not force it. - ifeq ($(strip $1), FORCE) - $$(shell rm -f $$(main_targets_file)) + ifneq ($$(COMPARE_BUILD_PATCH), ) + ifneq ($$(wildcard $$(WORKSPACE_ROOT)/$$(COMPARE_BUILD_PATCH)), ) + # Assume relative path, if file exists + COMPARE_BUILD_PATCH := $$(wildcard $$(WORKSPACE_ROOT)/$$(COMPARE_BUILD_PATCH)) + else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), ) + $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist) endif - endif - - $$(main_targets_file): - @( cd $$(topdir) && \ - $$(MAKE) $$(MAKE_LOG_FLAGS) -r -R -f $$(topdir)/make/Main.gmk \ - -I $$(topdir)/make/common SPEC=$(strip $2) NO_RECIPES=true \ - $$(MAKE_LOG_VARS) \ - create-main-targets-include ) - - # Now include main-targets.gmk. This will define ALL_MAIN_TARGETS. - -include $$(main_targets_file) - endef - - define PrintConfCheckFailed - @echo ' ' - @echo "Please rerun configure! Easiest way to do this is by running" - @echo "'make reconfigure'." - @echo "This behavior may also be changed using CONF_CHECK=." - @echo ' ' - endef - -else # $(HAS_SPEC)=true - ############################################################################## - # Helper functions for the 'main' target. These functions assume a single, - # proper and existing SPEC is included. - ############################################################################## - - include $(TOPDIR)/make/common/MakeBase.gmk - - # Define basic logging setup - BUILD_LOG := $(OUTPUTDIR)/build.log - BUILD_PROFILE_LOG := $(OUTPUTDIR)/build-profile.log - - BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait - # Use this for simple echo/printf commands that are never expected to print - # to stderr. - BUILD_LOG_PIPE_SIMPLE := | $(TEE) -a $(BUILD_LOG) - - ifneq ($(CUSTOM_ROOT), ) - topdir = $(CUSTOM_ROOT) - else - topdir = $(TOPDIR) - endif - - # Setup the build environment to match the requested specification on - # level of reproducible builds - define SetupReproducibleBuild - ifeq ($$(SOURCE_DATE), updated) - # For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk - export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s") - export SOURCE_DATE_ISO_8601 := $$(call EpochToISO8601, $$(SOURCE_DATE_EPOCH)) - endif - endef - - # Parse COMPARE_BUILD into COMPARE_BUILD_* - # Syntax: COMPARE_BUILD=CONF=:PATCH=: - # MAKE=:COMP_OPTS=: - # COMP_DIR=|: - # FAIL= - # If neither CONF or PATCH is given, assume means CONF if it - # begins with "--", otherwise assume it means PATCH. - # MAKE and COMP_OPTS can only be used with CONF and/or PATCH specified. - # If any value contains "+", it will be replaced by space. - # FAIL can be set to false to have the return value of compare be ignored. - define ParseCompareBuild - ifneq ($$(COMPARE_BUILD), ) - COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME) - COMPARE_BUILD_FAIL := true - - ifneq ($$(findstring :, $$(COMPARE_BUILD)), ) - $$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \ - $$(if $$(filter PATCH=%, $$(part)), \ - $$(eval COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(part)))) \ - ) \ - $$(if $$(filter CONF=%, $$(part)), \ - $$(eval COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(part))))) \ - ) \ - $$(if $$(filter MAKE=%, $$(part)), \ - $$(eval COMPARE_BUILD_MAKE = $$(strip $$(subst +, , $$(patsubst MAKE=%, %, $$(part))))) \ - ) \ - $$(if $$(filter COMP_OPTS=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_OPTS = $$(strip $$(subst +, , $$(patsubst COMP_OPTS=%, %, $$(part))))) \ - ) \ - $$(if $$(filter COMP_DIR=%, $$(part)), \ - $$(eval COMPARE_BUILD_COMP_DIR = $$(strip $$(subst +, , $$(patsubst COMP_DIR=%, %, $$(part))))) \ - ) \ - $$(if $$(filter FAIL=%, $$(part)), \ - $$(eval COMPARE_BUILD_FAIL = $$(strip $$(subst +, , $$(patsubst FAIL=%, %, $$(part))))) \ - ) \ - $$(if $$(filter NODRYRUN=%, $$(part)), \ - $$(eval COMPARE_BUILD_NODRYRUN = $$(strip $$(subst +, , $$(patsubst NODRYRUN=%, %, $$(part))))) \ - ) \ - ) - else - # Separate handling for single field case, to allow for spaces in values. - ifneq ($$(filter PATCH=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_PATCH = $$(strip $$(patsubst PATCH=%, %, $$(COMPARE_BUILD))) - else ifneq ($$(filter CONF=%, $$(COMPARE_BUILD)), ) - COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(patsubst CONF=%, %, $$(COMPARE_BUILD)))) - else ifneq ($$(filter --%, $$(COMPARE_BUILD)), ) - # Assume CONF if value begins with -- - COMPARE_BUILD_CONF = $$(strip $$(subst +, , $$(COMPARE_BUILD))) - else - # Otherwise assume patch file - COMPARE_BUILD_PATCH = $$(strip $$(COMPARE_BUILD)) + ifneq ($$(COMPARE_BUILD_NODRYRUN), true) + PATCH_DRY_RUN := $$(shell cd $$(WORKSPACE_ROOT) && $$(PATCH) --dry-run -p1 < $$(COMPARE_BUILD_PATCH) > /dev/null 2>&1 || $$(ECHO) FAILED) + ifeq ($$(PATCH_DRY_RUN), FAILED) + $$(error Patch file $$(COMPARE_BUILD_PATCH) does not apply cleanly) endif endif - ifneq ($$(COMPARE_BUILD_PATCH), ) - ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), ) - # Assume relative path, if file exists - COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)) - else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), ) - $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist) - endif - ifneq ($$(COMPARE_BUILD_NODRYRUN), true) - PATCH_DRY_RUN := $$(shell cd $$(topdir) && $$(PATCH) --dry-run -p1 < $$(COMPARE_BUILD_PATCH) > /dev/null 2>&1 || $$(ECHO) FAILED) - ifeq ($$(PATCH_DRY_RUN), FAILED) - $$(error Patch file $$(COMPARE_BUILD_PATCH) does not apply cleanly) - endif - endif - endif - ifneq ($$(COMPARE_BUILD_FAIL), true) - COMPARE_BUILD_IGNORE_RESULT := || true - endif endif - endef + ifneq ($$(COMPARE_BUILD_FAIL), true) + COMPARE_BUILD_IGNORE_RESULT := || true + endif + endif +endef - # Prepare for a comparison rebuild - define PrepareCompareBuild +# Prepare for a comparison rebuild +define PrepareCompareBuild $(ECHO) "Preparing for comparison rebuild" # Apply patch, if any - $(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -p1 < $(COMPARE_BUILD_PATCH)) + $(if $(COMPARE_BUILD_PATCH), cd $(WORKSPACE_ROOT) && $(PATCH) -p1 < $(COMPARE_BUILD_PATCH)) # Move the first build away temporarily - $(RM) -r $(topdir)/build/.compare-build-temp - $(MKDIR) -p $(topdir)/build/.compare-build-temp - $(MV) $(OUTPUTDIR) $(topdir)/build/.compare-build-temp + $(RM) -r $(WORKSPACE_ROOT)/build/.compare-build-temp + $(MKDIR) -p $(WORKSPACE_ROOT)/build/.compare-build-temp + $(MV) $(OUTPUTDIR) $(WORKSPACE_ROOT)/build/.compare-build-temp # Restore an old compare-build, or create a new compare-build directory. if test -d $(COMPARE_BUILD_OUTPUTDIR); then \ $(MV) $(COMPARE_BUILD_OUTPUTDIR) $(OUTPUTDIR); \ @@ -422,23 +140,23 @@ else # $(HAS_SPEC)=true # Re-run configure with the same arguments (and possibly some additional), # must be done after patching. ( cd $(CONFIGURE_START_DIR) && PATH="$(ORIGINAL_PATH)" \ - $(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF)) - endef + $(BASH) $(WORKSPACE_ROOT)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF)) +endef - # Cleanup after a compare build - define CleanupCompareBuild +# Cleanup after a compare build +define CleanupCompareBuild # If running with a COMPARE_BUILD patch, reverse-apply it, but continue # even if that fails (can happen with removed files). - $(if $(COMPARE_BUILD_PATCH), cd $(topdir) && $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH) || true) + $(if $(COMPARE_BUILD_PATCH), cd $(WORKSPACE_ROOT) && $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH) || true) # Move this build away and restore the original build - $(MKDIR) -p $(topdir)/build/compare-build + $(MKDIR) -p $(WORKSPACE_ROOT)/build/compare-build $(MV) $(OUTPUTDIR) $(COMPARE_BUILD_OUTPUTDIR) - $(MV) $(topdir)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR) - $(RM) -r $(topdir)/build/.compare-build-temp - endef + $(MV) $(WORKSPACE_ROOT)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR) + $(RM) -r $(WORKSPACE_ROOT)/build/.compare-build-temp +endef - # Do the actual comparison of two builds - define CompareBuildDoComparison +# Do the actual comparison of two builds +define CompareBuildDoComparison # Compare first and second build. Ignore any error code from compare.sh. $(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)" $(if $(COMPARE_BUILD_COMP_DIR), \ @@ -448,9 +166,9 @@ else # $(HAS_SPEC)=true +(cd $(COMPARE_BUILD_OUTPUTDIR) && ./compare.sh --diffs $(COMPARE_BUILD_COMP_OPTS) \ -o $(OUTPUTDIR) $(COMPARE_BUILD_IGNORE_RESULT)) \ ) - endef +endef - define PrintFailureReports +define PrintFailureReports $(if $(filter none, $(LOG_REPORT)), , \ $(RM) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \ $(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log), \ @@ -472,9 +190,9 @@ else # $(HAS_SPEC)=true ) >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \ ) \ ) - endef +endef - define PrintBuildLogFailures +define PrintBuildLogFailures $(if $(filter none, $(LOG_REPORT)), , \ if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \ $(PRINTF) "\n=== Make failed targets repeated here ===\n" ; \ @@ -487,96 +205,96 @@ else # $(HAS_SPEC)=true fi >> $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log ; \ $(CAT) $(MAKESUPPORT_OUTPUTDIR)/failure-summary.log \ ) - endef +endef - define RotateLogFiles +define RotateLogFiles $(RM) $(BUILD_LOG).old 2> /dev/null && \ $(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true $(if $(findstring true, $(LOG_PROFILE_TIMES_FILE)), \ $(RM) $(BUILD_PROFILE_LOG).old 2> /dev/null && \ $(MV) $(BUILD_PROFILE_LOG) $(BUILD_PROFILE_LOG).old 2> /dev/null || true \ ) - endef +endef - # Failure logs are only supported for "parallel" main targets, not the - # (trivial) sequential make targets (such as clean and reconfigure), - # since the failure-logs directory creation will conflict with clean. - # We also make sure the javatmp directory exists, which is needed if a java - # process (like javac) is using java.io.tmpdir. - define PrepareFailureLogs +# Failure logs are only supported for "parallel" main targets, not the +# (trivial) sequential make targets (such as clean and reconfigure), +# since the failure-logs directory creation will conflict with clean. +# We also make sure the javatmp directory exists, which is needed if a java +# process (like javac) is using java.io.tmpdir. +define PrepareFailureLogs $(RM) -r $(MAKESUPPORT_OUTPUTDIR)/failure-logs 2> /dev/null && \ $(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR)/failure-logs $(MKDIR) -p $(JAVA_TMP_DIR) $(RM) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error 2> /dev/null - endef +endef - # Remove any javac server logs and port files. This - # prevents a new make run to reuse the previous servers. - define PrepareJavacServer +# Remove any javac server logs and port files. This +# prevents a new make run to reuse the previous servers. +define PrepareJavacServer $(if $(JAVAC_SERVER_DIR), \ $(RM) -r $(JAVAC_SERVER_DIR) 2> /dev/null && \ $(MKDIR) -p $(JAVAC_SERVER_DIR) \ ) - endef +endef - define CleanupJavacServer +define CleanupJavacServer [ -f $(JAVAC_SERVER_DIR)/server.port ] && $(ECHO) Stopping javac server && \ $(TOUCH) $(JAVAC_SERVER_DIR)/server.port.stop; true - endef +endef - ifeq ($(call isBuildOs, windows), true) - # On windows we need to synchronize with the javac server to be able to - # move or remove the build output directory. Since we have no proper - # synchronization process, wait for a while and hope it helps. This is only - # used by build comparisons. +ifeq ($(call isBuildOs, windows), true) + # On windows we need to synchronize with the javac server to be able to + # move or remove the build output directory. Since we have no proper + # synchronization process, wait for a while and hope it helps. This is only + # used by build comparisons. define WaitForJavacServerFinish $(if $(JAVAC_SERVER_DIR), \ sleep 5 \ ) - endef - else - define WaitForJavacServerFinish - endef - endif + endef +else + define WaitForJavacServerFinish + endef +endif - ############################################################################## - # Functions for timers - ############################################################################## +############################################################################## +# Functions for timers +############################################################################## - # Store the build times in this directory. - BUILDTIMESDIR = $(OUTPUTDIR)/make-support/build-times +# Store the build times in this directory. +BUILDTIMESDIR := $(OUTPUTDIR)/make-support/build-times - # Record starting time for build of a sub repository. - define RecordStartTime +# Record starting time for build of a sub repository. +define RecordStartTime $(DATE) '+%Y %m %d %H %M %S' | $(AWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_start_$(strip $1) && \ $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_start_$(strip $1)_human_readable - endef +endef - # Record ending time and calculate the difference and store it in a - # easy to read format. Handles builds that cross midnight. Expects - # that a build will never take 24 hours or more. - define RecordEndTime +# Record ending time and calculate the difference and store it in a +# easy to read format. Handles builds that cross midnight. Expects +# that a build will never take 24 hours or more. +define RecordEndTime $(DATE) '+%Y %m %d %H %M %S' | $(AWK) '{ print $$1,$$2,$$3,$$4,$$5,$$6,($$4*3600+$$5*60+$$6) }' > $(BUILDTIMESDIR)/build_time_end_$(strip $1) $(DATE) '+%Y-%m-%d %H:%M:%S' > $(BUILDTIMESDIR)/build_time_end_$(strip $1)_human_readable $(ECHO) `$(CAT) $(BUILDTIMESDIR)/build_time_start_$(strip $1)` `$(CAT) $(BUILDTIMESDIR)/build_time_end_$(strip $1)` $1 | \ $(AWK) '{ F=$$7; T=$$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); \ M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$$15); }' \ > $(BUILDTIMESDIR)/build_time_diff_$(strip $1) - endef +endef - define StartGlobalTimer +define StartGlobalTimer $(RM) -r $(BUILDTIMESDIR) 2> /dev/null && \ $(MKDIR) -p $(BUILDTIMESDIR) && \ $(call RecordStartTime,TOTAL) - endef +endef - define StopGlobalTimer +define StopGlobalTimer $(call RecordEndTime,TOTAL) - endef +endef - # Find all build_time_* files and print their contents in a list sorted - # on the name of the sub repository. - define ReportBuildTimes +# Find all build_time_* files and print their contents in a list sorted +# on the name of the sub repository. +define ReportBuildTimes $(PRINTF) $(LOG_INFO) -- \ "----- Build times -------\nStart %s\nEnd %s\n%s\n%s\n-------------------------\n" \ "`$(CAT) $(BUILDTIMESDIR)/build_time_start_TOTAL_human_readable`" \ @@ -585,119 +303,20 @@ else # $(HAS_SPEC)=true $(XARGS) $(CAT) | $(SORT) -k 2`" \ "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_TOTAL`" \ $(BUILD_LOG_PIPE_SIMPLE) - endef - - define ReportProfileTimes - $(if $(findstring true, $(LOG_PROFILE_TIMES_LOG)), \ - [ ! -f $(BUILD_PROFILE_LOG) ] || \ - { $(ECHO) Begin $(notdir $(BUILD_PROFILE_LOG)) && \ - $(CAT) $(BUILD_PROFILE_LOG) && \ - $(ECHO) End $(notdir $(BUILD_PROFILE_LOG)); \ - } \ - $(BUILD_LOG_PIPE_SIMPLE) - ) - endef - -endif # HAS_SPEC - -# Look for a given option in the LOG variable, and if found, set a variable -# and remove the option from the LOG variable -# $1: The option to look for -# $2: The variable to set to "true" if the option is found -define ParseLogOption - ifneq ($$(findstring $1, $$(LOG)), ) - override $2 := true - # First try to remove ",

    .txt. +################################################################################ # Put the generated Java classes used to interface X11 from awt here. GENSRC_X11WRAPPERS_OUTPUTDIR := $(SUPPORT_OUTPUTDIR)/gensrc/java.desktop/sun/awt/X11 @@ -45,3 +50,8 @@ $(eval $(call SetupExecute, gen_x11wrappers, \ )) TARGETS += $(gen_x11wrappers_TARGET) + +################################################################################ + +endif # include guard +include MakeIncludeEnd.gmk diff --git a/make/modules/java.desktop/lib/AwtLibraries.gmk b/make/modules/java.desktop/lib/AwtLibraries.gmk index 5ba7c819008b5..4d18038f2aac3 100644 --- a/make/modules/java.desktop/lib/AwtLibraries.gmk +++ b/make/modules/java.desktop/lib/AwtLibraries.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,16 @@ # questions. # -include CopyFiles.gmk +include MakeIncludeStart.gmk +ifeq ($(INCLUDE), true) ################################################################################ # This file will build all AWT/2D native libraries with "awt" in the name. # Note that this does not imply that the code they bring in belong to AWT. # This split is purely made to keep the size of the Makefiles reasonable. +################################################################################ + +include CopyFiles.gmk LIBAWT_DEFAULT_HEADER_DIRS := \ common/awt/utility \ @@ -437,3 +441,8 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(COPY_JAWT_LIB) endif + +################################################################################ + +endif # include guard +include MakeIncludeEnd.gmk diff --git a/make/modules/java.desktop/lib/ClientLibraries.gmk b/make/modules/java.desktop/lib/ClientLibraries.gmk index 41f3040222cc0..6599f655c1066 100644 --- a/make/modules/java.desktop/lib/ClientLibraries.gmk +++ b/make/modules/java.desktop/lib/ClientLibraries.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,15 @@ # questions. # +include MakeIncludeStart.gmk +ifeq ($(INCLUDE), true) + ################################################################################ # This file will build all AWT/2D native libraries that does not have "awt" in # the name. Note that this does not imply anything about the logical ownership # of the code they compile. # This split is purely made to keep the size of the Makefiles reasonable. +################################################################################ ################################################################################ ## Build libmlib_image @@ -222,7 +226,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false) EXCLUDE_SRC_PATTERNS := $(LIBSPLASHSCREEN_EXCLUDE_SRC_PATTERNS), \ EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \ EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \ - OPTIMIZATION := LOW, \ + OPTIMIZATION := SIZE, \ CFLAGS := $(LIBSPLASHSCREEN_CFLAGS) \ $(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS), \ CXXFLAGS := $(LIBSPLASHSCREEN_CFLAGS) \ @@ -360,8 +364,6 @@ else LIBFONTMANAGER_JDK_LIBS += libfreetype endif -LIBFONTMANAGER_OPTIMIZATION := HIGHEST - ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang), ) # gcc (and to an extent clang) is particularly bad at optimizing these files, # causing a massive spike in compile time. We don't care about these @@ -372,7 +374,6 @@ endif ifeq ($(call isTargetOs, windows), true) LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c X11TextRenderer.c - LIBFONTMANAGER_OPTIMIZATION := HIGHEST else ifeq ($(call isTargetOs, macosx), true) LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c X11TextRenderer.c \ fontpath.c lcdglyph.c @@ -393,7 +394,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \ AccelGlyphCache.c, \ CFLAGS := $(LIBFONTMANAGER_CFLAGS), \ CXXFLAGS := $(LIBFONTMANAGER_CFLAGS), \ - OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \ + OPTIMIZATION := HIGHEST, \ CFLAGS_windows = -DCC_NOEX, \ EXTRA_HEADER_DIRS := $(LIBFONTMANAGER_EXTRA_HEADER_DIRS), \ EXTRA_SRC := $(LIBFONTMANAGER_EXTRA_SRC), \ @@ -406,6 +407,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \ LDFLAGS_aix := -Wl$(COMMA)-berok, \ JDK_LIBS := libawt java.base:libjava $(LIBFONTMANAGER_JDK_LIBS), \ JDK_LIBS_macosx := libawt_lwawt, \ + JDK_LIBS_unix := java.base:libjvm, \ LIBS := $(LIBFONTMANAGER_LIBS), \ LIBS_unix := $(LIBM), \ LIBS_macosx := \ @@ -470,3 +472,8 @@ ifeq ($(call isTargetOs, macosx), true) $(BUILD_LIBOSXUI): $(SHADERS_LIB) endif + +################################################################################ + +endif # include guard +include MakeIncludeEnd.gmk diff --git a/make/modules/java.instrument/Java.gmk b/make/modules/java.instrument/Java.gmk index f49e425718e7f..6e5ea0e2c733b 100644 --- a/make/modules/java.instrument/Java.gmk +++ b/make/modules/java.instrument/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,5 +23,9 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.instrument/Lib.gmk b/make/modules/java.instrument/Lib.gmk index 675c1d8ccd3d7..0d1a3d81b50dd 100644 --- a/make/modules/java.instrument/Lib.gmk +++ b/make/modules/java.instrument/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -48,3 +50,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \ )) TARGETS += $(BUILD_LIBINSTRUMENT) + +################################################################################ diff --git a/make/modules/java.logging/Copy.gmk b/make/modules/java.logging/Copy.gmk index 8c9e677b861db..36d70ed555530 100644 --- a/make/modules/java.logging/Copy.gmk +++ b/make/modules/java.logging/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,10 @@ # questions. # -include CopyCommon.gmk - ################################################################################ +include CopyCommon.gmk + LOGGING_LIB_SRC := $(TOPDIR)/src/java.logging/share/conf $(CONF_DST_DIR)/logging.properties: $(LOGGING_LIB_SRC)/logging.properties diff --git a/make/modules/java.logging/Gensrc.gmk b/make/modules/java.logging/Gensrc.gmk index c28edd822b65f..3b166e0f0a612 100644 --- a/make/modules/java.logging/Gensrc.gmk +++ b/make/modules/java.logging/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -include GensrcCommon.gmk - ################################################################################ +include GensrcCommon.gmk include GensrcProperties.gmk $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ @@ -35,3 +34,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/java.logging/Java.gmk b/make/modules/java.logging/Java.gmk index 781370b2e1879..ab4e1b6144e1a 100644 --- a/make/modules/java.logging/Java.gmk +++ b/make/modules/java.logging/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.management.rmi/Java.gmk b/make/modules/java.management.rmi/Java.gmk index 4579fea684343..11f99c26bd3cb 100644 --- a/make/modules/java.management.rmi/Java.gmk +++ b/make/modules/java.management.rmi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,5 +23,9 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:javax.*' + +################################################################################ diff --git a/make/modules/java.management/Java.gmk b/make/modules/java.management/Java.gmk index 7a337946cd7df..44e3f328c7fc9 100644 --- a/make/modules/java.management/Java.gmk +++ b/make/modules/java.management/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.management/Lib.gmk b/make/modules/java.management/Lib.gmk index b9f79da451635..cfa96b012c95b 100644 --- a/make/modules/java.management/Lib.gmk +++ b/make/modules/java.management/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -45,3 +47,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT, \ )) TARGETS += $(BUILD_LIBMANAGEMENT) + +################################################################################ diff --git a/make/modules/java.naming/Java.gmk b/make/modules/java.naming/Java.gmk index 207329f594418..1c7a2a1668a71 100644 --- a/make/modules/java.naming/Java.gmk +++ b/make/modules/java.naming/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' CLEAN += jndiprovider.properties + +################################################################################ diff --git a/make/modules/java.prefs/Java.gmk b/make/modules/java.prefs/Java.gmk index e124e8844d3b3..6e5ea0e2c733b 100644 --- a/make/modules/java.prefs/Java.gmk +++ b/make/modules/java.prefs/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,5 +23,9 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.prefs/Lib.gmk b/make/modules/java.prefs/Lib.gmk index 033768ffa1dce..7590a5431b121 100644 --- a/make/modules/java.prefs/Lib.gmk +++ b/make/modules/java.prefs/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -46,3 +48,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBPREFS, \ )) TARGETS += $(BUILD_LIBPREFS) + +################################################################################ diff --git a/make/modules/java.rmi/Java.gmk b/make/modules/java.rmi/Java.gmk index 6c607bd0572f2..4f24edb6f677b 100644 --- a/make/modules/java.rmi/Java.gmk +++ b/make/modules/java.rmi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape DOCLINT += -Xdoclint:all/protected \ @@ -32,3 +34,5 @@ CLEAN_FILES += $(wildcard \ $(TOPDIR)/src/java.rmi/share/classes/sun/rmi/server/resources/*.properties) TARGETS += $(call CreateHkTargets, $(CLEAN_FILES)) + +################################################################################ diff --git a/make/modules/java.rmi/Launcher.gmk b/make/modules/java.rmi/Launcher.gmk index 8c335711da026..a72c107981c73 100644 --- a/make/modules/java.rmi/Launcher.gmk +++ b/make/modules/java.rmi/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,3 +34,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, rmiregistry, \ MAIN_CLASS := sun.rmi.registry.RegistryImpl, \ )) + +################################################################################ diff --git a/make/modules/java.rmi/Lib.gmk b/make/modules/java.rmi/Lib.gmk index 3f4a5bed893bc..0520af6b702ab 100644 --- a/make/modules/java.rmi/Lib.gmk +++ b/make/modules/java.rmi/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -37,3 +39,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBRMI, \ )) TARGETS += $(BUILD_LIBRMI) + +################################################################################ diff --git a/make/modules/java.scripting/Java.gmk b/make/modules/java.scripting/Java.gmk index c9060b5fa46b6..1909ec1a2dffd 100644 --- a/make/modules/java.scripting/Java.gmk +++ b/make/modules/java.scripting/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' COPY += .js CLEAN += .properties + +################################################################################ diff --git a/make/modules/java.scripting/Launcher.gmk b/make/modules/java.scripting/Launcher.gmk index a969b567d1e4f..ee6b93fbf2cc6 100644 --- a/make/modules/java.scripting/Launcher.gmk +++ b/make/modules/java.scripting/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -33,3 +35,5 @@ $(eval $(call SetupBuildLauncher, jrunscript, \ MAIN_CLASS := com.sun.tools.script.shell.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ )) + +################################################################################ diff --git a/make/modules/java.security.jgss/Java.gmk b/make/modules/java.security.jgss/Java.gmk index 7a337946cd7df..44e3f328c7fc9 100644 --- a/make/modules/java.security.jgss/Java.gmk +++ b/make/modules/java.security.jgss/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.security.jgss/Launcher.gmk b/make/modules/java.security.jgss/Launcher.gmk index b0e2fdcffd1d5..40a9385937824 100644 --- a/make/modules/java.security.jgss/Launcher.gmk +++ b/make/modules/java.security.jgss/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ifeq ($(call isTargetOs, windows), true) @@ -50,3 +52,5 @@ ifeq ($(call isTargetOs, windows), true) MAIN_CLASS := sun.security.krb5.internal.tools.Ktab, \ )) endif + +################################################################################ diff --git a/make/modules/java.security.jgss/Lib.gmk b/make/modules/java.security.jgss/Lib.gmk index 2c827b84109f7..4b05100e6a603 100644 --- a/make/modules/java.security.jgss/Lib.gmk +++ b/make/modules/java.security.jgss/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -94,3 +96,5 @@ ifneq ($(BUILD_CRYPTO), false) TARGETS += $(BUILD_LIBOSXKRB5) endif endif + +################################################################################ diff --git a/make/modules/java.security.sasl/Java.gmk b/make/modules/java.security.sasl/Java.gmk index 136b311a827a9..12d13b4910fac 100644 --- a/make/modules/java.security.sasl/Java.gmk +++ b/make/modules/java.security.sasl/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape + +################################################################################ diff --git a/make/modules/java.smartcardio/Java.gmk b/make/modules/java.smartcardio/Java.gmk index f49e425718e7f..6e5ea0e2c733b 100644 --- a/make/modules/java.smartcardio/Java.gmk +++ b/make/modules/java.smartcardio/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,5 +23,9 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.smartcardio/Lib.gmk b/make/modules/java.smartcardio/Lib.gmk index 1e647fd7e2403..8d8a2aef086bf 100644 --- a/make/modules/java.smartcardio/Lib.gmk +++ b/make/modules/java.smartcardio/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -41,3 +43,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJ2PCSC, \ )) TARGETS += $(BUILD_LIBJ2PCSC) + +################################################################################ diff --git a/make/modules/java.sql.rowset/Java.gmk b/make/modules/java.sql.rowset/Java.gmk index 6bc30e3693d00..ecfe3e6e6412d 100644 --- a/make/modules/java.sql.rowset/Java.gmk +++ b/make/modules/java.sql.rowset/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments DOCLINT += -Xdoclint:all/protected \ @@ -32,3 +34,5 @@ CLEAN_FILES += $(wildcard \ $(TOPDIR)/src/java.sql.rowset/share/classes/javax/sql/rowset/*.properties) TARGETS += $(call CreateHkTargets, $(CLEAN_FILES)) + +################################################################################ diff --git a/make/modules/java.sql/Java.gmk b/make/modules/java.sql/Java.gmk index 7a337946cd7df..44e3f328c7fc9 100644 --- a/make/modules/java.sql/Java.gmk +++ b/make/modules/java.sql/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' + +################################################################################ diff --git a/make/modules/java.transaction.xa/Java.gmk b/make/modules/java.transaction.xa/Java.gmk index 4579fea684343..11f99c26bd3cb 100644 --- a/make/modules/java.transaction.xa/Java.gmk +++ b/make/modules/java.transaction.xa/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,5 +23,9 @@ # questions. # +################################################################################ + DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:javax.*' + +################################################################################ diff --git a/make/modules/java.xml.crypto/Java.gmk b/make/modules/java.xml.crypto/Java.gmk index 9ee19c8c30297..68db8ed817a23 100644 --- a/make/modules/java.xml.crypto/Java.gmk +++ b/make/modules/java.xml.crypto/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,13 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' COPY += .dtd .xml CLEAN += .properties + +################################################################################ diff --git a/make/modules/java.xml/Copy.gmk b/make/modules/java.xml/Copy.gmk index f242cb2ac7611..f8c1896e526f2 100644 --- a/make/modules/java.xml/Copy.gmk +++ b/make/modules/java.xml/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,12 @@ # questions. # +################################################################################ + include CopyCommon.gmk include Modules.gmk ################################################################################ -# # Copy property and template files from share/conf to CONF_DST_DIR # $(eval $(call SetupCopyFiles, COPY_XML_MODULE_CONF, \ @@ -37,4 +38,5 @@ $(eval $(call SetupCopyFiles, COPY_XML_MODULE_CONF, \ )) TARGETS += $(COPY_XML_MODULE_CONF) + ################################################################################ diff --git a/make/modules/java.xml/Java.gmk b/make/modules/java.xml/Java.gmk index 0c174f2113e84..35f66238a7a96 100644 --- a/make/modules/java.xml/Java.gmk +++ b/make/modules/java.xml/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,13 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments lossy-conversions this-escape DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \ javax.xml.transform javax.xml.validation javax.xml.xpath)' COPY += .dtd .xsd .xml .ent .mod CLEAN += .properties + +################################################################################ diff --git a/make/modules/jdk.accessibility/Copy.gmk b/make/modules/jdk.accessibility/Copy.gmk index cd8aeba5a11d0..798b97902c6e9 100644 --- a/make/modules/jdk.accessibility/Copy.gmk +++ b/make/modules/jdk.accessibility/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,8 @@ # ################################################################################ -# Include CopyCommon.gmk to get exported header files to be properly copied. +# Include CopyCommon.gmk to get exported header files to be properly copied. include CopyCommon.gmk + +################################################################################ diff --git a/make/modules/jdk.accessibility/Java.gmk b/make/modules/jdk.accessibility/Java.gmk index fc8b2f832d713..7f1718a23ed76 100644 --- a/make/modules/jdk.accessibility/Java.gmk +++ b/make/modules/jdk.accessibility/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments + +################################################################################ diff --git a/make/modules/jdk.accessibility/Launcher.gmk b/make/modules/jdk.accessibility/Launcher.gmk index 86ad96b3a1ec4..04694b10e9e58 100644 --- a/make/modules/jdk.accessibility/Launcher.gmk +++ b/make/modules/jdk.accessibility/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ifeq ($(call isTargetOs, windows), true) @@ -89,3 +91,5 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_JACCESSWALKER) endif + +################################################################################ diff --git a/make/modules/jdk.accessibility/Lib.gmk b/make/modules/jdk.accessibility/Lib.gmk index 6323049c98577..6a3631bff675a 100644 --- a/make/modules/jdk.accessibility/Lib.gmk +++ b/make/modules/jdk.accessibility/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -80,3 +82,5 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_LIBWINDOWSACCESSBRIDGE) endif + +################################################################################ diff --git a/make/modules/jdk.attach/Lib.gmk b/make/modules/jdk.attach/Lib.gmk index 8eefe7a4ec057..78437d761d2e6 100644 --- a/make/modules/jdk.attach/Lib.gmk +++ b/make/modules/jdk.attach/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -46,3 +48,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBATTACH, \ )) TARGETS += $(BUILD_LIBATTACH) + +################################################################################ diff --git a/make/modules/jdk.charsets/Gensrc.gmk b/make/modules/jdk.charsets/Gensrc.gmk index e93ea19219d8f..82dc091cbfda1 100644 --- a/make/modules/jdk.charsets/Gensrc.gmk +++ b/make/modules/jdk.charsets/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,12 @@ # questions. # -include GensrcCommon.gmk - ################################################################################ -# # Generate files using the charsetmapping tool -# +################################################################################ + +include GensrcCommon.gmk + CHARSET_DATA_DIR := $(TOPDIR)/make/data/charsetmapping CHARSET_GENSRC_JAVA_DIR_CS := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.charsets/sun/nio/cs/ext @@ -82,3 +82,5 @@ TARGETS += \ $(CHARSET_DONE_CS)-euctw \ $(CHARSET_GENSRC_JAVA_DIR_CS)/sjis0213.dat \ # + +################################################################################ diff --git a/make/modules/jdk.charsets/Java.gmk b/make/modules/jdk.charsets/Java.gmk index 2eb5bd454568d..c5dbb1e2a603c 100644 --- a/make/modules/jdk.charsets/Java.gmk +++ b/make/modules/jdk.charsets/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += .dat + +################################################################################ diff --git a/make/modules/jdk.compiler/Gendata.gmk b/make/modules/jdk.compiler/Gendata.gmk index 57487c7c842f5..739625a5732a1 100644 --- a/make/modules/jdk.compiler/Gendata.gmk +++ b/make/modules/jdk.compiler/Gendata.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,13 @@ # questions. # +################################################################################ + include CopyFiles.gmk include JarArchive.gmk include JavaCompilation.gmk include Modules.gmk -################################################################################ - -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, modules/jdk.compiler/Gendata.gmk)) - # This is needed to properly setup DOCS_MODULES. $(eval $(call ReadImportMetaData)) diff --git a/make/modules/jdk.compiler/Gensrc.gmk b/make/modules/jdk.compiler/Gensrc.gmk index 14cc4f55a2b1e..c6c5879745cf4 100644 --- a/make/modules/jdk.compiler/Gensrc.gmk +++ b/make/modules/jdk.compiler/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk include Execute.gmk @@ -72,3 +74,5 @@ $(eval $(call SetupExecute, PARSEPROPERTIES, \ )) TARGETS += $(PARSEPROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.compiler/Java.gmk b/make/modules/jdk.compiler/Java.gmk index a2dd4f60fa681..3d6d22b278290 100644 --- a/make/modules/jdk.compiler/Java.gmk +++ b/make/modules/jdk.compiler/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + # To the extent technically possible, this module should be built with # -Werror and all lint warnings enabled. In particular, # DISABLED_WARNINGS_java should not be augmented. @@ -33,3 +35,5 @@ JAVAC_FLAGS += -XDstringConcat=inline CLEAN_FILES += $(wildcard \ $(patsubst %, $(TOPDIR)/src/jdk.compiler/share/classes/%/*.properties, \ sun/tools/serialver/resources)) + +################################################################################ diff --git a/make/modules/jdk.compiler/Launcher.gmk b/make/modules/jdk.compiler/Launcher.gmk index e80c31bcb18f3..74bd6896409c8 100644 --- a/make/modules/jdk.compiler/Launcher.gmk +++ b/make/modules/jdk.compiler/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,7 +34,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javac, \ MAIN_CLASS := com.sun.tools.javac.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -41,5 +43,7 @@ $(eval $(call SetupBuildLauncher, javac, \ $(eval $(call SetupBuildLauncher, serialver, \ MAIN_CLASS := sun.tools.serialver.SerialVer, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.crypto.cryptoki/Java.gmk b/make/modules/jdk.crypto.cryptoki/Java.gmk index fc8b2f832d713..7f1718a23ed76 100644 --- a/make/modules/jdk.crypto.cryptoki/Java.gmk +++ b/make/modules/jdk.crypto.cryptoki/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments + +################################################################################ diff --git a/make/modules/jdk.crypto.cryptoki/Lib.gmk b/make/modules/jdk.crypto.cryptoki/Lib.gmk index ec80aaf46b42b..29d1422cd787c 100644 --- a/make/modules/jdk.crypto.cryptoki/Lib.gmk +++ b/make/modules/jdk.crypto.cryptoki/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -40,3 +42,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJ2PKCS11, \ )) TARGETS += $(BUILD_LIBJ2PKCS11) + +################################################################################ diff --git a/make/modules/jdk.crypto.mscapi/Java.gmk b/make/modules/jdk.crypto.mscapi/Java.gmk index 269a1195b6a10..aca47fc97f704 100644 --- a/make/modules/jdk.crypto.mscapi/Java.gmk +++ b/make/modules/jdk.crypto.mscapi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape + +################################################################################ diff --git a/make/modules/jdk.crypto.mscapi/Lib.gmk b/make/modules/jdk.crypto.mscapi/Lib.gmk index 39b83a21ae94a..9c78621ec0cb7 100644 --- a/make/modules/jdk.crypto.mscapi/Lib.gmk +++ b/make/modules/jdk.crypto.mscapi/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ifeq ($(call isTargetOs, windows), true) @@ -40,3 +42,5 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_LIBSUNMSCAPI) endif + +################################################################################ diff --git a/make/modules/jdk.dev/Java.gmk b/make/modules/jdk.dev/Java.gmk index c26b4f9c8f691..5740117531408 100644 --- a/make/modules/jdk.dev/Java.gmk +++ b/make/modules/jdk.dev/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ # questions. # +################################################################################ + CLEAN_FILES += $(wildcard \ $(patsubst %, $(TOPDIR)/src/jdk.dev/share/classes/%/*.properties, \ com/sun/tools/script/shell)) COPY += .js oqlhelp.html .txt + +################################################################################ diff --git a/make/modules/jdk.dynalink/Java.gmk b/make/modules/jdk.dynalink/Java.gmk index 852e68c0d3141..f95e59bf36e26 100644 --- a/make/modules/jdk.dynalink/Java.gmk +++ b/make/modules/jdk.dynalink/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + CLEAN += .properties + +################################################################################ diff --git a/make/modules/jdk.editpad/Java.gmk b/make/modules/jdk.editpad/Java.gmk index ef2d3bcfa7c52..640335dae43f4 100644 --- a/make/modules/jdk.editpad/Java.gmk +++ b/make/modules/jdk.editpad/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += .properties + +################################################################################ diff --git a/make/modules/jdk.hotspot.agent/Gensrc.gmk b/make/modules/jdk.hotspot.agent/Gensrc.gmk index b2bd016a512d7..b5cfa6d15fc7b 100644 --- a/make/modules/jdk.hotspot.agent/Gensrc.gmk +++ b/make/modules/jdk.hotspot.agent/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -54,3 +54,5 @@ ifeq ($(call isTargetOs, macosx), true) TARGETS += $(MACH_EXC_SERVER) endif + +################################################################################ diff --git a/make/modules/jdk.hotspot.agent/Java.gmk b/make/modules/jdk.hotspot.agent/Java.gmk index 333d28a5aa0cf..eef2ccb4bb030 100644 --- a/make/modules/jdk.hotspot.agent/Java.gmk +++ b/make/modules/jdk.hotspot.agent/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += rawtypes serial cast static overrides \ dangling-doc-comments fallthrough this-escape COPY += .gif .png .properties + +################################################################################ diff --git a/make/modules/jdk.hotspot.agent/Launcher.gmk b/make/modules/jdk.hotspot.agent/Launcher.gmk index 94ad08bda0cec..83e640486c2da 100644 --- a/make/modules/jdk.hotspot.agent/Launcher.gmk +++ b/make/modules/jdk.hotspot.agent/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -33,3 +35,5 @@ $(eval $(call SetupBuildLauncher, jhsdb, \ MAIN_CLASS := sun.jvm.hotspot.SALauncher, \ MACOSX_PRIVILEGED := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.hotspot.agent/Lib.gmk b/make/modules/jdk.hotspot.agent/Lib.gmk index 12f1c1f2a9077..ed8de631dc351 100644 --- a/make/modules/jdk.hotspot.agent/Lib.gmk +++ b/make/modules/jdk.hotspot.agent/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -79,3 +81,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBSAPROC, \ )) TARGETS += $(BUILD_LIBSAPROC) + +################################################################################ diff --git a/make/modules/jdk.httpserver/Gensrc.gmk b/make/modules/jdk.httpserver/Gensrc.gmk index 37b51bb1d451f..baeb620781af8 100644 --- a/make/modules/jdk.httpserver/Gensrc.gmk +++ b/make/modules/jdk.httpserver/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,12 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk include Modules.gmk -################################################################################ - # Use wildcard so as to avoid getting non-existing directories back SIMPLESERVER_RESOURCES_DIRS := $(wildcard $(addsuffix /sun/net/httpserver/simpleserver/resources, \ $(call FindModuleSrcDirs, jdk.httpserver))) @@ -39,3 +39,5 @@ $(eval $(call SetupCompileProperties, SIMPLESERVER_PROPERTIES, \ )) TARGETS += $(SIMPLESERVER_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.httpserver/Java.gmk b/make/modules/jdk.httpserver/Java.gmk index 95c0f1eb6ab6b..f36d09919bc19 100644 --- a/make/modules/jdk.httpserver/Java.gmk +++ b/make/modules/jdk.httpserver/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape COPY += .ico + +################################################################################ diff --git a/make/modules/jdk.httpserver/Jmod.gmk b/make/modules/jdk.httpserver/Jmod.gmk index 9a216ef095878..72c87e19c29b2 100644 --- a/make/modules/jdk.httpserver/Jmod.gmk +++ b/make/modules/jdk.httpserver/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class sun.net.httpserver.simpleserver.Main + +################################################################################ diff --git a/make/modules/jdk.httpserver/Launcher.gmk b/make/modules/jdk.httpserver/Launcher.gmk index 0f0c060e6e3ac..d537ec1b50a36 100644 --- a/make/modules/jdk.httpserver/Launcher.gmk +++ b/make/modules/jdk.httpserver/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,3 +34,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jwebserver, \ MAIN_CLASS := sun.net.httpserver.simpleserver.JWebServer, \ )) + +################################################################################ diff --git a/make/modules/jdk.incubator.vector/Java.gmk b/make/modules/jdk.incubator.vector/Java.gmk index 6cd5301428f7e..e51ffe57ceaa4 100644 --- a/make/modules/jdk.incubator.vector/Java.gmk +++ b/make/modules/jdk.incubator.vector/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments DOCLINT += -Xdoclint:all/protected + +################################################################################ diff --git a/make/modules/jdk.incubator.vector/Lib.gmk b/make/modules/jdk.incubator.vector/Lib.gmk index 69da7ed059a6c..6d1259cfe6097 100644 --- a/make/modules/jdk.incubator.vector/Lib.gmk +++ b/make/modules/jdk.incubator.vector/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -64,8 +66,10 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, aarch64)+$(INCLUDE_COMPILER2 EXTRA_SRC := libsleef/generated, \ DISABLED_WARNINGS_gcc := unused-function sign-compare tautological-compare ignored-qualifiers, \ DISABLED_WARNINGS_clang := unused-function sign-compare tautological-compare ignored-qualifiers, \ - CFLAGS := $(SVE_CFLAGS), \ + vector_math_sve.c_CFLAGS := $(SVE_CFLAGS), \ )) TARGETS += $(BUILD_LIBSLEEF) endif + +################################################################################ diff --git a/make/modules/jdk.internal.jvmstat/Java.gmk b/make/modules/jdk.internal.jvmstat/Java.gmk index 4376b7e348494..108730a0fc593 100644 --- a/make/modules/jdk.internal.jvmstat/Java.gmk +++ b/make/modules/jdk.internal.jvmstat/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape COPY += aliasmap + +################################################################################ diff --git a/make/modules/jdk.internal.le/Java.gmk b/make/modules/jdk.internal.le/Java.gmk index 4c952b6357449..27c6eaf5f7f96 100644 --- a/make/modules/jdk.internal.le/Java.gmk +++ b/make/modules/jdk.internal.le/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape COPY += .properties .caps .txt + +################################################################################ diff --git a/make/modules/jdk.internal.md/Java.gmk b/make/modules/jdk.internal.md/Java.gmk index 2a850f5563743..638c12413c4cb 100644 --- a/make/modules/jdk.internal.md/Java.gmk +++ b/make/modules/jdk.internal.md/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += .txt + +################################################################################ diff --git a/make/modules/jdk.internal.opt/Java.gmk b/make/modules/jdk.internal.opt/Java.gmk index 0c65d9ad94ee8..08bb3a5334a73 100644 --- a/make/modules/jdk.internal.opt/Java.gmk +++ b/make/modules/jdk.internal.opt/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape COPY += .properties + +################################################################################ diff --git a/make/modules/jdk.internal.vm.ci/Java.gmk b/make/modules/jdk.internal.vm.ci/Java.gmk index 6bf8ad5e74c7f..cb569bb88170c 100644 --- a/make/modules/jdk.internal.vm.ci/Java.gmk +++ b/make/modules/jdk.internal.vm.ci/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments this-escape # -parameters provides method's parameters information in class file, @@ -30,3 +32,5 @@ DISABLED_WARNINGS_java += dangling-doc-comments this-escape # Don't use Indy strings concatenation to have good JVMCI startup performance. JAVAC_FLAGS += -parameters -XDstringConcat=inline + +################################################################################ diff --git a/make/modules/jdk.jartool/Gensrc.gmk b/make/modules/jdk.jartool/Gensrc.gmk index 06fbedfa40c9f..dc53aa0b6520e 100644 --- a/make/modules/jdk.jartool/Gensrc.gmk +++ b/make/modules/jdk.jartool/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -include GensrcCommon.gmk - ################################################################################ +include GensrcCommon.gmk include GensrcProperties.gmk $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ @@ -35,3 +34,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.jartool/Java.gmk b/make/modules/jdk.jartool/Java.gmk index 5e06f172070fb..806975d1e1832 100644 --- a/make/modules/jdk.jartool/Java.gmk +++ b/make/modules/jdk.jartool/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JAVAC_FLAGS += -XDstringConcat=inline + +################################################################################ diff --git a/make/modules/jdk.jartool/Jmod.gmk b/make/modules/jdk.jartool/Jmod.gmk index 8b42113ec84c9..42fd1f0532528 100644 --- a/make/modules/jdk.jartool/Jmod.gmk +++ b/make/modules/jdk.jartool/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class sun.tools.jar.Main + +################################################################################ diff --git a/make/modules/jdk.jartool/Launcher.gmk b/make/modules/jdk.jartool/Launcher.gmk index 3139fac45d5ff..f75f30d409886 100644 --- a/make/modules/jdk.jartool/Launcher.gmk +++ b/make/modules/jdk.jartool/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -40,3 +42,5 @@ $(eval $(call SetupBuildLauncher, jar, \ $(eval $(call SetupBuildLauncher, jarsigner, \ MAIN_CLASS := sun.security.tools.jarsigner.Main, \ )) + +################################################################################ diff --git a/make/modules/jdk.javadoc/Copy.gmk b/make/modules/jdk.javadoc/Copy.gmk index 031b4a91d33c5..1566911209c4c 100644 --- a/make/modules/jdk.javadoc/Copy.gmk +++ b/make/modules/jdk.javadoc/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include CopyCommon.gmk JDK_JAVADOC_DIR := $(JDK_OUTPUTDIR)/modules/jdk.javadoc diff --git a/make/modules/jdk.javadoc/Gendata.gmk b/make/modules/jdk.javadoc/Gendata.gmk index d733af65f1ea6..2cd812de779ef 100644 --- a/make/modules/jdk.javadoc/Gendata.gmk +++ b/make/modules/jdk.javadoc/Gendata.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,10 @@ # questions. # -include JavaCompilation.gmk -include Modules.gmk - ################################################################################ -# Hook to include the corresponding custom file, if present. -$(eval $(call IncludeCustomExtension, modules/jdk.javadoc/Gendata.gmk)) +include JavaCompilation.gmk +include Modules.gmk # This is needed to properly setup DOCS_MODULES. $(eval $(call ReadImportMetaData)) @@ -115,3 +112,5 @@ $(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker: $(JDK_JAVADOC_DIR)/_element_li TARGETS += $(JDK_JAVADOC_DIR)/_element_lists.marker \ $(INTERIM_JDK_JAVADOC_DIR)/_element_lists.marker + +################################################################################ diff --git a/make/modules/jdk.javadoc/Gensrc.gmk b/make/modules/jdk.javadoc/Gensrc.gmk index 0346e3832df53..e62988f883cfc 100644 --- a/make/modules/jdk.javadoc/Gensrc.gmk +++ b/make/modules/jdk.javadoc/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk @@ -37,3 +39,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.javadoc/Java.gmk b/make/modules/jdk.javadoc/Java.gmk index 1194797b13425..f5315019f008f 100644 --- a/make/modules/jdk.javadoc/Java.gmk +++ b/make/modules/jdk.javadoc/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ # questions. # +################################################################################ + # To the extent technically possible, this module should be built with # -Werror and all lint warnings enabled. In particular, # DISABLED_WARNINGS_java should not be augmented. COPY += .xml .css .svg .js .js.template .png .txt .woff .woff2 + +################################################################################ diff --git a/make/modules/jdk.javadoc/Launcher.gmk b/make/modules/jdk.javadoc/Launcher.gmk index 30d714be30d6a..9ed3b494117b2 100644 --- a/make/modules/jdk.javadoc/Launcher.gmk +++ b/make/modules/jdk.javadoc/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,5 +34,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javadoc, \ MAIN_CLASS := jdk.javadoc.internal.tool.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jcmd/Java.gmk b/make/modules/jdk.jcmd/Java.gmk index d19d9beb4d88d..5748e62f7bc14 100644 --- a/make/modules/jdk.jcmd/Java.gmk +++ b/make/modules/jdk.jcmd/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += _options + +################################################################################ diff --git a/make/modules/jdk.jcmd/Launcher.gmk b/make/modules/jdk.jcmd/Launcher.gmk index acff5a212c5d2..5d0da09d22bf3 100644 --- a/make/modules/jdk.jcmd/Launcher.gmk +++ b/make/modules/jdk.jcmd/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -84,3 +86,5 @@ $(eval $(call SetupBuildLauncher, jstat, \ $(eval $(call SetupBuildLauncher, jcmd, \ MAIN_CLASS := sun.tools.jcmd.JCmd, \ )) + +################################################################################ diff --git a/make/modules/jdk.jconsole/Java.gmk b/make/modules/jdk.jconsole/Java.gmk index 2de9321392d44..d6cf8689df341 100644 --- a/make/modules/jdk.jconsole/Java.gmk +++ b/make/modules/jdk.jconsole/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,11 @@ # questions. # +################################################################################ + COPY += .gif .png CLEAN_FILES += $(wildcard \ $(TOPDIR)/src/jdk.jconsole/share/classes/sun/tools/jconsole/resources/*.properties) + +################################################################################ diff --git a/make/modules/jdk.jconsole/Launcher.gmk b/make/modules/jdk.jconsole/Launcher.gmk index 3e65c3cccc37a..7cb40a1b13a1f 100644 --- a/make/modules/jdk.jconsole/Launcher.gmk +++ b/make/modules/jdk.jconsole/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -36,5 +38,7 @@ $(eval $(call SetupBuildLauncher, jconsole, \ --add-modules ALL-DEFAULT \ -Djconsole.showOutputViewer \ -Djdk.attach.allowAttachSelf=true, \ - CFLAGS_windows := -DJAVAW, \ + WINDOWS_JAVAW := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jdeps/Gensrc.gmk b/make/modules/jdk.jdeps/Gensrc.gmk index b5f1e702a7520..6ae92ee830a92 100644 --- a/make/modules/jdk.jdeps/Gensrc.gmk +++ b/make/modules/jdk.jdeps/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk @@ -40,3 +42,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.jdeps/Java.gmk b/make/modules/jdk.jdeps/Java.gmk index 69c7ae0433fc7..f2da87aeadec9 100644 --- a/make/modules/jdk.jdeps/Java.gmk +++ b/make/modules/jdk.jdeps/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ # questions. # +################################################################################ + COPY += .txt CLEAN_FILES += $(wildcard \ $(TOPDIR)/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/*.properties \ $(TOPDIR)/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/*.properties) + +################################################################################ diff --git a/make/modules/jdk.jdeps/Launcher.gmk b/make/modules/jdk.jdeps/Launcher.gmk index 1aa54e16f4564..debf36b62ae44 100644 --- a/make/modules/jdk.jdeps/Launcher.gmk +++ b/make/modules/jdk.jdeps/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -31,7 +33,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, javap, \ MAIN_CLASS := com.sun.tools.javap.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -40,7 +42,7 @@ $(eval $(call SetupBuildLauncher, javap, \ $(eval $(call SetupBuildLauncher, jdeps, \ MAIN_CLASS := com.sun.tools.jdeps.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -49,7 +51,7 @@ $(eval $(call SetupBuildLauncher, jdeps, \ $(eval $(call SetupBuildLauncher, jdeprscan, \ MAIN_CLASS := com.sun.tools.jdeprscan.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -58,5 +60,7 @@ $(eval $(call SetupBuildLauncher, jdeprscan, \ $(eval $(call SetupBuildLauncher, jnativescan, \ MAIN_CLASS := com.sun.tools.jnativescan.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jdi/Gensrc.gmk b/make/modules/jdk.jdi/Gensrc.gmk index 47f975064ad5f..57b8faee8a8ed 100644 --- a/make/modules/jdk.jdi/Gensrc.gmk +++ b/make/modules/jdk.jdi/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk ################################################################################ @@ -68,3 +70,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.jdi/Java.gmk b/make/modules/jdk.jdi/Java.gmk index 6577db98b0a12..d31008c318fdc 100644 --- a/make/modules/jdk.jdi/Java.gmk +++ b/make/modules/jdk.jdi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments EXCLUDES += \ @@ -33,3 +35,5 @@ EXCLUDES += \ # EXCLUDE_FILES += jdi-overview.html + +################################################################################ diff --git a/make/modules/jdk.jdi/Launcher.gmk b/make/modules/jdk.jdi/Launcher.gmk index 79be72e6ef340..a568e504b5a4d 100644 --- a/make/modules/jdk.jdi/Launcher.gmk +++ b/make/modules/jdk.jdi/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,3 +34,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jdb, \ MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \ )) + +################################################################################ diff --git a/make/modules/jdk.jdi/Lib.gmk b/make/modules/jdk.jdi/Lib.gmk index 80a5664289bf9..b59a3ab8ea43c 100644 --- a/make/modules/jdk.jdi/Lib.gmk +++ b/make/modules/jdk.jdi/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ifeq ($(call isTargetOs, windows), true) @@ -40,3 +42,5 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_LIBDT_SHMEM) endif + +################################################################################ diff --git a/make/modules/jdk.jdwp.agent/Copy.gmk b/make/modules/jdk.jdwp.agent/Copy.gmk index cd8aeba5a11d0..798b97902c6e9 100644 --- a/make/modules/jdk.jdwp.agent/Copy.gmk +++ b/make/modules/jdk.jdwp.agent/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,8 @@ # ################################################################################ -# Include CopyCommon.gmk to get exported header files to be properly copied. +# Include CopyCommon.gmk to get exported header files to be properly copied. include CopyCommon.gmk + +################################################################################ diff --git a/make/modules/jdk.jdwp.agent/Lib.gmk b/make/modules/jdk.jdwp.agent/Lib.gmk index 53b48cc7c453b..a1f9a0fca52fa 100644 --- a/make/modules/jdk.jdwp.agent/Lib.gmk +++ b/make/modules/jdk.jdwp.agent/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -77,3 +79,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \ )) TARGETS += $(BUILD_LIBJDWP) + +################################################################################ diff --git a/make/modules/jdk.jfr/Copy.gmk b/make/modules/jdk.jfr/Copy.gmk index f4fa3d97551ab..81dc58c13248e 100644 --- a/make/modules/jdk.jfr/Copy.gmk +++ b/make/modules/jdk.jfr/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,10 @@ # questions. # -include CopyCommon.gmk - ################################################################################ +include CopyCommon.gmk + JFR_CONF_DIR := $(TOPDIR)/src/jdk.jfr/share/conf/jfr $(eval $(call SetupCopyFiles, COPY_JFR_CONF, \ DEST := $(LIB_DST_DIR)/jfr, \ diff --git a/make/modules/jdk.jfr/Gendata.gmk b/make/modules/jdk.jfr/Gendata.gmk index 522eea70f32a6..0a5dd874c8193 100644 --- a/make/modules/jdk.jfr/Gendata.gmk +++ b/make/modules/jdk.jfr/Gendata.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,8 @@ ################################################################################ -include ToolsHotspot.gmk include Execute.gmk +include $(TOPDIR)/make/ToolsHotspot.gmk JFR_SRCDIR := $(TOPDIR)/src/hotspot/share/jfr/metadata JFR_DATA_OUTPUTDIR := $(OUTPUTDIR)/jdk/modules/jdk.jfr/jdk/jfr/internal/types @@ -46,3 +46,5 @@ $(eval $(call SetupExecute, jfr_gen_metadata, \ )) TARGETS += $(jfr_gen_metadata) + +################################################################################ diff --git a/make/modules/jdk.jfr/Java.gmk b/make/modules/jdk.jfr/Java.gmk index d07f9117c2dfc..5fabda8a4b777 100644 --- a/make/modules/jdk.jfr/Java.gmk +++ b/make/modules/jdk.jfr/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments exports COPY := .xsd .xml .dtd .ini JAVAC_FLAGS := -XDstringConcat=inline + +################################################################################ diff --git a/make/modules/jdk.jfr/Jmod.gmk b/make/modules/jdk.jfr/Jmod.gmk index 79a6a81c730b2..499ea142d3aa9 100644 --- a/make/modules/jdk.jfr/Jmod.gmk +++ b/make/modules/jdk.jfr/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class jdk.jfr.internal.tool.Main + +################################################################################ diff --git a/make/modules/jdk.jfr/Launcher.gmk b/make/modules/jdk.jfr/Launcher.gmk index 2dd3586a92072..80417cd67d362 100644 --- a/make/modules/jdk.jfr/Launcher.gmk +++ b/make/modules/jdk.jfr/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -31,5 +33,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jfr, \ MAIN_CLASS := jdk.jfr.internal.tool.Main, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jlink/Gensrc.gmk b/make/modules/jdk.jlink/Gensrc.gmk index c450ceea073f1..87703c7c8bb7d 100644 --- a/make/modules/jdk.jlink/Gensrc.gmk +++ b/make/modules/jdk.jlink/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,12 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk include Modules.gmk -################################################################################ - # Use wildcard so as to avoid getting non-existing directories back JLINK_RESOURCES_DIRS := $(wildcard $(addsuffix /jdk/tools/jlink/resources, \ $(call FindModuleSrcDirs, jdk.jlink))) @@ -50,3 +50,5 @@ $(eval $(call SetupCompileProperties, JIMAGE_PROPERTIES, \ TARGETS += $(JLINK_PROPERTIES) $(JMOD_PROPERTIES) $(JIMAGE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.jlink/Launcher.gmk b/make/modules/jdk.jlink/Launcher.gmk index d427906519357..312c40e47ab25 100644 --- a/make/modules/jdk.jlink/Launcher.gmk +++ b/make/modules/jdk.jlink/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -31,7 +33,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jimage, \ MAIN_CLASS := jdk.tools.jimage.Main, \ - CFLAGS := -DENABLE_ARG_FILES, \ + ENABLE_ARG_FILES := true, \ )) ################################################################################ @@ -41,7 +43,8 @@ $(eval $(call SetupBuildLauncher, jimage, \ $(eval $(call SetupBuildLauncher, jlink, \ MAIN_CLASS := jdk.tools.jlink.internal.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DENABLE_ARG_FILES -DEXPAND_CLASSPATH_WILDCARDS, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) ################################################################################ @@ -50,5 +53,8 @@ $(eval $(call SetupBuildLauncher, jlink, \ $(eval $(call SetupBuildLauncher, jmod, \ MAIN_CLASS := jdk.tools.jmod.Main, \ - CFLAGS := -DENABLE_ARG_FILES -DEXPAND_CLASSPATH_WILDCARDS, \ + ENABLE_ARG_FILES := true, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jpackage/Gensrc.gmk b/make/modules/jdk.jpackage/Gensrc.gmk index 434b42dc0bfe7..98311d89b879c 100644 --- a/make/modules/jdk.jpackage/Gensrc.gmk +++ b/make/modules/jdk.jpackage/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk ################################################################################ @@ -36,5 +38,7 @@ ifeq ($(call isTargetOs, macosx), true) $(ENTITLEMENTS_TARGET_FILE): $(ENTITLEMENTS_SRC_FILE) $(call install-file) - TARGETS := $(ENTITLEMENTS_TARGET_FILE) + TARGETS += $(ENTITLEMENTS_TARGET_FILE) endif + +################################################################################ diff --git a/make/modules/jdk.jpackage/Java.gmk b/make/modules/jdk.jpackage/Java.gmk index d60e9ac281488..da66fc1400901 100644 --- a/make/modules/jdk.jpackage/Java.gmk +++ b/make/modules/jdk.jpackage/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,14 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments COPY += .gif .png .txt .spec .script .prerm .preinst \ .postrm .postinst .list .sh .desktop .copyright .control .plist .template \ - .icns .scpt .wxs .wxl .wxi .ico .bmp .tiff .service .xsl + .icns .scpt .wxs .wxl .wxi .wxf .ico .bmp .tiff .service .xsl CLEAN += .properties + +################################################################################ diff --git a/make/modules/jdk.jpackage/Jmod.gmk b/make/modules/jdk.jpackage/Jmod.gmk index 8e0982202a7f7..27b03e1081eeb 100644 --- a/make/modules/jdk.jpackage/Jmod.gmk +++ b/make/modules/jdk.jpackage/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class jdk.jpackage.main.Main + +################################################################################ diff --git a/make/modules/jdk.jpackage/Launcher.gmk b/make/modules/jdk.jpackage/Launcher.gmk index f80c4ed83d376..80f644eea3f9a 100644 --- a/make/modules/jdk.jpackage/Launcher.gmk +++ b/make/modules/jdk.jpackage/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,3 +34,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jpackage, \ MAIN_CLASS := jdk.jpackage.main.Main, \ )) + +################################################################################ diff --git a/make/modules/jdk.jpackage/Lib.gmk b/make/modules/jdk.jpackage/Lib.gmk index 33d10336e6e47..a301447d73eed 100644 --- a/make/modules/jdk.jpackage/Lib.gmk +++ b/make/modules/jdk.jpackage/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,10 @@ # questions. # -include LibCommon.gmk +################################################################################ + include LauncherCommon.gmk +include LibCommon.gmk JPACKAGE_OUTPUT_DIR := \ $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources @@ -186,3 +188,5 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_JPACKAGEAPPLAUNCHERW) endif + +################################################################################ diff --git a/make/modules/jdk.jshell/Gensrc.gmk b/make/modules/jdk.jshell/Gensrc.gmk index 71d1ad4281703..deab53719a5df 100644 --- a/make/modules/jdk.jshell/Gensrc.gmk +++ b/make/modules/jdk.jshell/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk include GensrcProperties.gmk @@ -37,3 +39,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.jshell/Java.gmk b/make/modules/jdk.jshell/Java.gmk index 744c85d960a94..f4194b23af7e3 100644 --- a/make/modules/jdk.jshell/Java.gmk +++ b/make/modules/jdk.jshell/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += .jsh .properties + +################################################################################ diff --git a/make/modules/jdk.jshell/Jmod.gmk b/make/modules/jdk.jshell/Jmod.gmk index 12f22e9d9afda..ec599e44fcce1 100644 --- a/make/modules/jdk.jshell/Jmod.gmk +++ b/make/modules/jdk.jshell/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class jdk.internal.jshell.tool.JShellToolProvider + +################################################################################ diff --git a/make/modules/jdk.jshell/Launcher.gmk b/make/modules/jdk.jshell/Launcher.gmk index bf555d7f64c13..bdfcbf1911df1 100644 --- a/make/modules/jdk.jshell/Launcher.gmk +++ b/make/modules/jdk.jshell/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -31,5 +33,7 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jshell, \ MAIN_CLASS := jdk.internal.jshell.tool.JShellToolProvider, \ - CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ + EXPAND_CLASSPATH_WILDCARDS := true, \ )) + +################################################################################ diff --git a/make/modules/jdk.jstatd/Jmod.gmk b/make/modules/jdk.jstatd/Jmod.gmk index 2c95e094cfe00..1c2aa35a2c21a 100644 --- a/make/modules/jdk.jstatd/Jmod.gmk +++ b/make/modules/jdk.jstatd/Jmod.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + JMOD_FLAGS_main_class := --main-class sun.tools.jstatd.Jstatd + +################################################################################ diff --git a/make/modules/jdk.jstatd/Launcher.gmk b/make/modules/jdk.jstatd/Launcher.gmk index 209b810353f2d..d101cd3f4ed45 100644 --- a/make/modules/jdk.jstatd/Launcher.gmk +++ b/make/modules/jdk.jstatd/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LauncherCommon.gmk ################################################################################ @@ -32,3 +34,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jstatd, \ MAIN_CLASS := sun.tools.jstatd.Jstatd, \ )) + +################################################################################ diff --git a/make/modules/jdk.localedata/Gensrc.gmk b/make/modules/jdk.localedata/Gensrc.gmk index 4d9f15a20c9c0..a3c5cdf82e8cb 100644 --- a/make/modules/jdk.localedata/Gensrc.gmk +++ b/make/modules/jdk.localedata/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include GensrcCommon.gmk ################################################################################ @@ -47,3 +49,5 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ $(TOUCH) $@ TARGETS += $(CLDR_GEN_DONE) + +################################################################################ diff --git a/make/modules/jdk.localedata/Java.gmk b/make/modules/jdk.localedata/Java.gmk index 41696a641a7d4..c359f0ee03cfb 100644 --- a/make/modules/jdk.localedata/Java.gmk +++ b/make/modules/jdk.localedata/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,12 @@ # questions. # +################################################################################ + COPY += _dict _th # Exclude BreakIterator classes that are just used in compile process to generate # data files and shouldn't go in the product EXCLUDE_FILES += sun/text/resources/ext/BreakIteratorRules_th.java KEEP_ALL_TRANSLATIONS := true + +################################################################################ diff --git a/make/modules/jdk.management.agent/Copy.gmk b/make/modules/jdk.management.agent/Copy.gmk index 5600989b4d38a..ada75231ec71c 100644 --- a/make/modules/jdk.management.agent/Copy.gmk +++ b/make/modules/jdk.management.agent/Copy.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include CopyCommon.gmk ################################################################################ diff --git a/make/modules/jdk.management.agent/Gensrc.gmk b/make/modules/jdk.management.agent/Gensrc.gmk index c13f4da75fe81..4bafdd9503e6c 100644 --- a/make/modules/jdk.management.agent/Gensrc.gmk +++ b/make/modules/jdk.management.agent/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ # questions. # -include GensrcCommon.gmk - ################################################################################ +include GensrcCommon.gmk include GensrcProperties.gmk $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ @@ -35,3 +34,5 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \ )) TARGETS += $(COMPILE_PROPERTIES) + +################################################################################ diff --git a/make/modules/jdk.management.agent/Lib.gmk b/make/modules/jdk.management.agent/Lib.gmk index 89de59d7fecbb..17dd163f63cf1 100644 --- a/make/modules/jdk.management.agent/Lib.gmk +++ b/make/modules/jdk.management.agent/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -37,3 +39,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT_AGENT, \ )) TARGETS += $(BUILD_LIBMANAGEMENT_AGENT) + +################################################################################ diff --git a/make/modules/jdk.management/Java.gmk b/make/modules/jdk.management/Java.gmk index 269a1195b6a10..aca47fc97f704 100644 --- a/make/modules/jdk.management/Java.gmk +++ b/make/modules/jdk.management/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += this-escape + +################################################################################ diff --git a/make/modules/jdk.management/Lib.gmk b/make/modules/jdk.management/Lib.gmk index cb65b37bda80d..fd9345e8b8a60 100644 --- a/make/modules/jdk.management/Lib.gmk +++ b/make/modules/jdk.management/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -54,3 +56,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBMANAGEMENT_EXT, \ )) TARGETS += $(BUILD_LIBMANAGEMENT_EXT) + +################################################################################ diff --git a/make/modules/jdk.net/Lib.gmk b/make/modules/jdk.net/Lib.gmk index e43d8427f5a1c..00d243a7f534a 100644 --- a/make/modules/jdk.net/Lib.gmk +++ b/make/modules/jdk.net/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -38,3 +40,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBEXTNET, \ )) TARGETS += $(BUILD_LIBEXTNET) + +################################################################################ diff --git a/make/modules/jdk.sctp/Java.gmk b/make/modules/jdk.sctp/Java.gmk index cac0f770816fc..5c7c4eb41760f 100644 --- a/make/modules/jdk.sctp/Java.gmk +++ b/make/modules/jdk.sctp/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + # No SCTP implementation on Mac OS X or AIX. These classes should be excluded. SCTP_IMPL_CLASSES = \ $(TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/AssociationChange.java \ @@ -51,3 +53,5 @@ ifeq ($(call isTargetOsType, unix), true) EXCLUDE_FILES += $(TOPDIR)/src/jdk.sctp/share/classes/sun/nio/ch/sctp/UnsupportedUtil.java endif endif + +################################################################################ diff --git a/make/modules/jdk.sctp/Lib.gmk b/make/modules/jdk.sctp/Lib.gmk index a6d95a25154bd..2017805f52d53 100644 --- a/make/modules/jdk.sctp/Lib.gmk +++ b/make/modules/jdk.sctp/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ifeq ($(call isTargetOs, linux), true) @@ -44,3 +46,5 @@ ifeq ($(call isTargetOs, linux), true) TARGETS += $(BUILD_LIBSCTP) endif + +################################################################################ diff --git a/make/modules/jdk.security.auth/Java.gmk b/make/modules/jdk.security.auth/Java.gmk index fc8b2f832d713..7f1718a23ed76 100644 --- a/make/modules/jdk.security.auth/Java.gmk +++ b/make/modules/jdk.security.auth/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + DISABLED_WARNINGS_java += dangling-doc-comments + +################################################################################ diff --git a/make/modules/jdk.security.auth/Lib.gmk b/make/modules/jdk.security.auth/Lib.gmk index a0d410044891a..9ead32dbe121f 100644 --- a/make/modules/jdk.security.auth/Lib.gmk +++ b/make/modules/jdk.security.auth/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ # questions. # +################################################################################ + include LibCommon.gmk ################################################################################ @@ -37,3 +39,5 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJAAS, \ )) TARGETS += $(BUILD_LIBJAAS) + +################################################################################ diff --git a/make/modules/sun.charsets/Java.gmk b/make/modules/sun.charsets/Java.gmk index 2745327c8e46e..c5dbb1e2a603c 100644 --- a/make/modules/sun.charsets/Java.gmk +++ b/make/modules/sun.charsets/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,4 +23,8 @@ # questions. # +################################################################################ + COPY += .dat + +################################################################################ diff --git a/test/jdk/sun/security/util/Pem/encoding.sh b/make/scripts/aix/ld.sh similarity index 63% rename from test/jdk/sun/security/util/Pem/encoding.sh rename to make/scripts/aix/ld.sh index ef670b3aee5ba..faa77ce4ba5a8 100644 --- a/test/jdk/sun/security/util/Pem/encoding.sh +++ b/make/scripts/aix/ld.sh @@ -1,10 +1,13 @@ +#!/bin/bash # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2025 SAP SE. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -20,16 +23,5 @@ # or visit www.oracle.com if you need additional information or have any # questions. # - -# @test -# @bug 8158633 -# @summary BASE64 encoded cert not correctly parsed with UTF-16 -# @build PemEncoding -# @run shell encoding.sh - -# jtreg does not like -Dfile.encoding=UTF-16 inside a @run main line, -# therefore a shell test is written. - -$TESTJAVA/bin/java $TESTVMOPTS $TESTJAVAOPTS -cp $TESTCLASSES \ - -Dfile.encoding=UTF-16 \ - PemEncoding $TESTSRC/../HostnameChecker/cert5.crt +unset LIBPATH +exec /usr/bin/ld "$@" diff --git a/make/test/BuildFailureHandler.gmk b/make/test/BuildFailureHandler.gmk index e8f49e76b3268..b4f3d690b0d75 100644 --- a/make/test/BuildFailureHandler.gmk +++ b/make/test/BuildFailureHandler.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,13 @@ # questions. # -default: build +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include JavaCompilation.gmk -TARGETS := - -################################################################################ - FH_BASEDIR := $(TOPDIR)/test/failure_handler FH_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/failure_handler FH_JAR := $(FH_SUPPORT)/jtregFailureHandler.jar @@ -110,4 +105,8 @@ test: build: $(TARGETS) images: $(IMAGES_TARGETS) -.PHONY: all images test +.PHONY: images test + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/BuildJtregTestThreadFactory.gmk b/make/test/BuildJtregTestThreadFactory.gmk index 4f0ead24ece9e..94338626769dd 100644 --- a/make/test/BuildJtregTestThreadFactory.gmk +++ b/make/test/BuildJtregTestThreadFactory.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,13 @@ # questions. # -default: build +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include JavaCompilation.gmk -TARGETS := - -################################################################################ - TTF_BASEDIR := $(TOPDIR)/test/jtreg_test_thread_factory TTF_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/jtreg_test_thread_factory TTF_JAR := $(TTF_SUPPORT)/jtregTestThreadFactory.jar @@ -64,4 +59,8 @@ IMAGES_TARGETS += $(COPY_TTF) build: $(TARGETS) images: $(IMAGES_TARGETS) -.PHONY: all images +.PHONY: images + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1052e422f7b06..92f40472c3cb9 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,9 @@ # questions. # -# This must be the first rule -default: all +include MakeFileStart.gmk -include $(SPEC) -include MakeBase.gmk +################################################################################ include CopyFiles.gmk include JarArchive.gmk @@ -96,8 +94,6 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ --add-exports java.base/jdk.internal.util=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ --add-exports java.base/sun.invoke.util=ALL-UNNAMED \ --add-exports java.base/sun.security.util=ALL-UNNAMED \ @@ -126,9 +122,20 @@ $(JMH_UNPACKED_JARS_DONE): $(JMH_RUNTIME_JARS) $(RM) $(JMH_UNPACKED_DIR)/*.xml $(TOUCH) $@ +# Copy dependency files for inclusion in the benchmark JARs +$(eval $(call SetupCopyFiles, COPY_JAXP_TEST_XML, \ + SRC := $(TOPDIR)/test/jaxp/javax/xml/jaxp/unittest, \ + DEST := $(MICROBENCHMARK_CLASSES)/org/openjdk/bench/javax/xml, \ + FILES := \ + stream/XMLStreamWriterTest/message_12.xml \ + validation/tck/reZ003vExc23082309.xml \ + transform/msgAttach.xml, \ + FLATTEN := true, \ +)) + # Create benchmarks JAR file with benchmarks for both the old and new JDK $(eval $(call SetupJarArchive, BUILD_JDK_JAR, \ - DEPENDENCIES := $(BUILD_JDK_MICROBENCHMARK) $(JMH_UNPACKED_JARS_DONE), \ + DEPENDENCIES := $(BUILD_JDK_MICROBENCHMARK) $(JMH_UNPACKED_JARS_DONE) $(COPY_JAXP_TEST_XML), \ SRCS := $(MICROBENCHMARK_CLASSES) $(JMH_UNPACKED_DIR), \ BIN := $(MICROBENCHMARK_JAR_BIN), \ SUFFIXES := .*, \ @@ -157,4 +164,6 @@ $(eval $(call SetupCopyFiles, COPY_MICROBENCHMARK_NATIVE, \ all: $(MICROBENCHMARK_JAR) $(BUILD_MICROBENCHMARK_LIBRARIES) $(COPY_MICROBENCHMARK_NATIVE) -.PHONY: all +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/BuildTestLib.gmk b/make/test/BuildTestLib.gmk index 5659423826136..dc5e0a9bd64bc 100644 --- a/make/test/BuildTestLib.gmk +++ b/make/test/BuildTestLib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,14 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # This file builds the Java components of testlib. # It also covers the test-image part, where the built files are copied to the # test image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include JavaCompilation.gmk @@ -41,8 +38,6 @@ include JavaCompilation.gmk # Targets for building the test lib jars ################################################################################ -TARGETS := - TEST_LIB_SOURCE_DIR := $(TOPDIR)/test/lib TEST_LIB_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/lib @@ -57,19 +52,27 @@ $(eval $(call SetupJavaCompilation, BUILD_WB_JAR, \ TARGETS += $(BUILD_WB_JAR) +ifeq ($(call isTargetOs, linux), false) + BUILD_TEST_LIB_JAR_EXCLUDES := jdk/test/lib/containers +endif + $(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \ TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ SRC := $(TEST_LIB_SOURCE_DIR), \ - EXCLUDES := jdk/test/lib/containers jdk/test/lib/security, \ + EXCLUDES := $(BUILD_TEST_LIB_JAR_EXCLUDES), \ BIN := $(TEST_LIB_SUPPORT)/test-lib_classes, \ HEADERS := $(TEST_LIB_SUPPORT)/test-lib_headers, \ JAR := $(TEST_LIB_SUPPORT)/test-lib.jar, \ - DISABLED_WARNINGS := try deprecation rawtypes unchecked serial cast removal preview restricted dangling-doc-comments, \ JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED \ --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED \ --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED \ --add-exports java.base/jdk.internal.module=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.platform=ALL-UNNAMED \ + --add-exports java.base/sun.security.pkcs=ALL-UNNAMED \ + --add-exports java.base/sun.security.provider.certpath=ALL-UNNAMED \ + --add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED \ + --add-exports java.base/sun.security.x509=ALL-UNNAMED \ --enable-preview, \ )) @@ -86,10 +89,13 @@ $(eval $(call SetupCopyFiles, COPY_LIBTEST_JARS, \ DEST := $(TEST_IMAGE_DIR)/lib-test, \ FILES := $(BUILD_WB_JAR_JAR) $(BUILD_TEST_LIB_JAR_JAR), \ )) -# test-image-lib: $(COPY_LIBTEST_JARS) all: build-test-lib -.PHONY: default all build-test-lib test-image-lib +.PHONY: build-test-lib test-image-lib + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/BuildTestLibNative.gmk b/make/test/BuildTestLibNative.gmk index 63dcbbf008b65..f2a3aafeea956 100644 --- a/make/test/BuildTestLibNative.gmk +++ b/make/test/BuildTestLibNative.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,14 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # This file builds the native component of testlib. # It also covers the test-image part, where the built files are copied to the # test image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include TestFilesCompilation.gmk @@ -86,4 +83,8 @@ test-image-lib-native: $(COPY_LIBTEST_NATIVE_TO_HOTSPOT) $(COPY_LIBTEST_NATIVE_T all: build-test-lib-native -.PHONY: default all build-test-lib-native test-image-lib-native +.PHONY: build-test-lib-native test-image-lib-native + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/BuildTestSetupAOT.gmk b/make/test/BuildTestSetupAOT.gmk new file mode 100644 index 0000000000000..46b18005366dc --- /dev/null +++ b/make/test/BuildTestSetupAOT.gmk @@ -0,0 +1,69 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include MakeFileStart.gmk + +################################################################################ +# This file builds the TestSetupAOT.class, which is used by SetupAOT +# in ../RunTests.gmk +################################################################################ + +include CopyFiles.gmk +include JavaCompilation.gmk + +################################################################################ + +SETUP_AOT_BASEDIR := $(TOPDIR)/test/setup_aot +SETUP_AOT_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/setup_aot +SETUP_AOT_CLASS := $(SETUP_AOT_SUPPORT)/classes/TestSetupAOT.class + +$(eval $(call SetupJavaCompilation, BUILD_SETUP_AOT, \ + TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ + SRC := $(SETUP_AOT_BASEDIR), \ + BIN := $(SETUP_AOT_SUPPORT)/classes, \ +)) + +TARGETS += $(BUILD_SETUP_AOT) + +################################################################################ +# Targets for building test-image. +################################################################################ + +# Copy to hotspot jtreg test image +$(eval $(call SetupCopyFiles, COPY_SETUP_AOT, \ + SRC := $(SETUP_AOT_SUPPORT)/classes, \ + DEST := $(TEST_IMAGE_DIR)/setup_aot, \ + FILES := TestSetupAOT.class, \ +)) + +IMAGES_TARGETS += $(COPY_SETUP_AOT) + +images: $(IMAGES_TARGETS) + +.PHONY: images + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index 97f2f12cb7639..2ee26b422e0c2 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,22 +23,17 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # This file builds the native component of the JTReg tests for Hotspot. # It also covers the test-image part, where the built files are copied to the # test image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include TestFilesCompilation.gmk -$(eval $(call IncludeCustomExtension, test/JtregNativeHotspot.gmk)) - ################################################################################ # Targets for building the native tests themselves. ################################################################################ @@ -867,6 +862,7 @@ ifeq ($(call isTargetOs, linux), true) BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exestack-gap := -lpthread BUILD_TEST_exeinvoke_exeinvoke.c_OPTIMIZATION := NONE BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeFPRegs := -ldl + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ldl BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libAsyncGetCallTraceTest := -ldl BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libfast-math := -ffast-math else @@ -880,7 +876,6 @@ endif BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exesigtest := java.base:libjvm -BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libatExit := java.base:libjvm BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exedaemonDestroy := java.base:libjvm ifeq ($(call isTargetOs, windows), true) @@ -1588,4 +1583,8 @@ test-image-hotspot-jtreg-native: $(COPY_HOTSPOT_JTREG_NATIVE) all: build-test-hotspot-jtreg-native test-image: test-image-hotspot-jtreg-native -.PHONY: default all build-test-hotspot-jtreg-native test-image-hotspot-jtreg-native test-image +.PHONY: build-test-hotspot-jtreg-native test-image-hotspot-jtreg-native test-image + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index 90055cb5c0114..60a88ca1c9a5c 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,22 +23,17 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # This file builds the native component of the JTReg tests for JDK. # It also covers the test-image part, where the built files are copied to the # test image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include TestFilesCompilation.gmk -$(eval $(call IncludeCustomExtension, test/JtregNativeJdk.gmk)) - ################################################################################ # Targets for building the native tests themselves. ################################################################################ @@ -61,8 +56,6 @@ BUILD_JDK_JTREG_EXECUTABLES_JDK_LIBS_exeCallerAccessTest := java.base:libjvm BUILD_JDK_JTREG_EXECUTABLES_JDK_LIBS_exeNullCallerTest := java.base:libjvm BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libstringPlatformChars := java.base:libjava -BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libTracePinnedThreads := java.base:libjvm -BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libNewDirectByteBuffer := java.base:libjava BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libGetXSpace := java.base:libjava # Platform specific setup @@ -75,7 +68,6 @@ ifeq ($(call isTargetOs, windows), true) BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib BUILD_JDK_JTREG_EXECUTABLES_CFLAGS_exeNullCallerTest := /EHsc else - BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libDirectIO := java.base:libjava BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeThread := -pthread # java.lang.foreign tests @@ -85,12 +77,10 @@ else BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerModule := -pthread BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLoaderLookupInvoker := -pthread - BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libExplicitAttach := java.base:libjvm BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libExplicitAttach := -pthread BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libImplicitAttach := -pthread BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c ifeq ($(call isTargetOs, linux), true) - BUILD_JDK_JTREG_LIBRARIES_JDK_LIBS_libInheritedChannel := java.base:libjava BUILD_JDK_JTREG_EXECUTABLES_LIBS_exelauncher := -ldl endif BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerTest := $(LIBCXX) @@ -169,4 +159,8 @@ test-image-jdk-jtreg-native: $(COPY_JDK_JTREG_NATIVE) all: build-test-jdk-jtreg-native test-image: test-image-jdk-jtreg-native -.PHONY: default all build-test-jdk-jtreg-native test-image-jdk-jtreg-native test-image +.PHONY: build-test-jdk-jtreg-native test-image-jdk-jtreg-native test-image + +################################################################################ + +include MakeFileEnd.gmk diff --git a/make/test/JtregNativeLibTest.gmk b/make/test/JtregNativeLibTest.gmk index 1a0177e63b039..6a1441495d154 100644 --- a/make/test/JtregNativeLibTest.gmk +++ b/make/test/JtregNativeLibTest.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,22 +23,17 @@ # questions. # +include MakeFileStart.gmk + ################################################################################ # This file builds the native component of the JTReg tests for testlibrary. # It also covers the test-image part, where the built files are copied to the # test image. ################################################################################ -default: all - -include $(SPEC) -include MakeBase.gmk - include CopyFiles.gmk include TestFilesCompilation.gmk -$(eval $(call IncludeCustomExtension, test/JtregNativeLibTest.gmk)) - ################################################################################ # Targets for building the native tests themselves. ################################################################################ @@ -89,4 +84,8 @@ test-image-libtest-jtreg-native: $(COPY_LIBTEST_JTREG_NATIVE) all: build-test-libtest-jtreg-native test-image: test-image-libtest-jtreg-native -.PHONY: default all build-test-libtest-jtreg-native test-image-libtest-jtreg-native test-image +.PHONY: build-test-libtest-jtreg-native test-image-libtest-jtreg-native test-image + +################################################################################ + +include MakeFileEnd.gmk diff --git a/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp b/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp index 33a72263a2774..a3c729fdd56e7 100644 --- a/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/abstractInterpreter_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "oops/constMethod.hpp" #include "oops/klass.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index 76f88764416e3..b03344f2d8027 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020 Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/bytecodes_aarch64.cpp b/src/hotspot/cpu/aarch64/bytecodes_aarch64.cpp index 744a983b18341..119ad8baec368 100644 --- a/src/hotspot/cpu/aarch64/bytecodes_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/bytecodes_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecodes.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp index 89a97a4984fc8..2334cbdff24e4 100644 --- a/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp index 9470caae9fe5a..5f65ef5f04328 100644 --- a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,16 +41,17 @@ enum { // registers enum { + pd_nof_available_regs = 32, pd_nof_cpu_regs_frame_map = Register::number_of_registers, // number of GP registers used during code emission pd_nof_fpu_regs_frame_map = FloatRegister::number_of_registers, // number of FP registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls + pd_nof_caller_save_cpu_regs_frame_map = pd_nof_available_regs, // number of registers killed by calls pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls - pd_first_callee_saved_reg = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), - pd_last_callee_saved_reg = 26 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), + pd_first_callee_saved_reg = pd_nof_available_regs - 1, + pd_last_callee_saved_reg = pd_first_callee_saved_reg - 1, // in fact, no callee saved regs - pd_last_allocatable_cpu_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_allocatable_cpu_reg = pd_nof_available_regs - 1, pd_nof_cpu_regs_reg_alloc = pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator @@ -60,9 +61,9 @@ enum { pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan pd_nof_xmm_regs_linearscan = 0, // don't have vector registers pd_first_cpu_reg = 0, - pd_last_cpu_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_cpu_reg = pd_nof_available_regs - 1, pd_first_byte_reg = 0, - pd_last_byte_reg = 16 R18_RESERVED_ONLY(- 1), + pd_last_byte_reg = pd_last_cpu_reg, pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 31, diff --git a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp index c50da1c8bebf3..158af57603ca8 100644 --- a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,4 +28,3 @@ //-------------------------------------------------------- // No FPU stack on AARCH64 -#include "precompiled.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index 91582b6733e5e..9d30092b45aac 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" @@ -194,9 +193,26 @@ void FrameMap::initialize() { map_register(i, r25); r25_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r26); r26_opr = LIR_OprFact::single_cpu(i); i++; - map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + // r27 is allocated conditionally. With compressed oops it holds + // the heapbase value and is not visible to the allocator. + bool preserve_rheapbase = i >= nof_caller_save_cpu_regs(); + if (!preserve_rheapbase) { + map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + } + + if(!PreserveFramePointer) { + map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; + } + + // The unallocatable registers are at the end + + if (preserve_rheapbase) { + map_register(i, r27); r27_opr = LIR_OprFact::single_cpu(i); i++; // rheapbase + } map_register(i, r28); r28_opr = LIR_OprFact::single_cpu(i); i++; // rthread - map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; // rfp + if(PreserveFramePointer) { + map_register(i, r29); r29_opr = LIR_OprFact::single_cpu(i); i++; // rfp + } map_register(i, r30); r30_opr = LIR_OprFact::single_cpu(i); i++; // lr map_register(i, r31_sp); sp_opr = LIR_OprFact::single_cpu(i); i++; // sp map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1 @@ -240,6 +256,19 @@ void FrameMap::initialize() { _caller_save_cpu_regs[16] = r18_opr; #endif + _caller_save_cpu_regs[17 R18_RESERVED_ONLY(-1)] = r19_opr; + _caller_save_cpu_regs[18 R18_RESERVED_ONLY(-1)] = r20_opr; + _caller_save_cpu_regs[19 R18_RESERVED_ONLY(-1)] = r21_opr; + _caller_save_cpu_regs[20 R18_RESERVED_ONLY(-1)] = r22_opr; + _caller_save_cpu_regs[21 R18_RESERVED_ONLY(-1)] = r23_opr; + _caller_save_cpu_regs[22 R18_RESERVED_ONLY(-1)] = r24_opr; + _caller_save_cpu_regs[23 R18_RESERVED_ONLY(-1)] = r25_opr; + _caller_save_cpu_regs[24 R18_RESERVED_ONLY(-1)] = r26_opr; + + if (nof_caller_save_cpu_regs() > 25 R18_RESERVED_ONLY(-1)) { + _caller_save_cpu_regs[25 R18_RESERVED_ONLY(-1)] = r27_opr; + } + for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); } diff --git a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp index 3ec3ce1f67936..4d783418429cb 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -140,8 +140,27 @@ static bool is_caller_save_register (LIR_Opr opr) { return true; } static bool is_caller_save_register (Register r) { return true; } - static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; } - static int last_cpu_reg() { return pd_last_cpu_reg; } - static int last_byte_reg() { return pd_last_byte_reg; } + static int adjust_reg_range(int range, bool exclude_fp = true) { + // r27 is not allocatable when compressed oops is on and heapbase is not + // zero, compressed klass pointers doesn't use r27 after JDK-8234794 + if (UseCompressedOops && (CompressedOops::base() != nullptr)) { + range -= 1; + } + + // r29 is not allocatable when PreserveFramePointer is on, + // but fp saving is handled in MacroAssembler::build_frame()/remove_frame() + if (exclude_fp) { + range -= 1; + } + + // rscratch registers r8, r9 + // r28=rthread, r30=lr, r31=sp + // r18 on masOS/Windows + return range - 5 R18_RESERVED_ONLY(-1); + } + + static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); } + static int last_cpu_reg() { return adjust_reg_range(pd_last_cpu_reg, PreserveFramePointer); } + static int last_byte_reg() { return adjust_reg_range(pd_last_byte_reg, PreserveFramePointer); } #endif // CPU_AARCH64_C1_FRAMEMAP_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index b01360c3f7ebc..0c11d26a4766c 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "asm/assembler.hpp" #include "c1/c1_CodeStubs.hpp" @@ -1218,15 +1217,24 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { void LIR_Assembler::type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data, Register recv, Label* update_done) { + + // Given a profile data offset, generate an Address which points to + // the corresponding slot in mdo->data(). + // Clobbers rscratch2. + auto slot_at = [=](ByteSize offset) -> Address { + return __ form_address(rscratch2, mdo, + md->byte_offset_of_slot(data, offset), + LogBytesPerWord); + }; + for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { Label next_test; // See if the receiver is receiver[n]. - __ lea(rscratch2, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); - __ ldr(rscratch1, Address(rscratch2)); + __ ldr(rscratch1, slot_at(ReceiverTypeData::receiver_offset(i))); __ cmp(recv, rscratch1); __ br(Assembler::NE, next_test); - Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); - __ addptr(data_addr, DataLayout::counter_increment); + __ addptr(slot_at(ReceiverTypeData::receiver_count_offset(i)), + DataLayout::counter_increment); __ b(*update_done); __ bind(next_test); } @@ -1234,15 +1242,12 @@ void LIR_Assembler::type_profile_helper(Register mdo, // Didn't find receiver; find next empty slot and fill it in for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { Label next_test; - __ lea(rscratch2, - Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); - Address recv_addr(rscratch2); + Address recv_addr(slot_at(ReceiverTypeData::receiver_offset(i))); __ ldr(rscratch1, recv_addr); __ cbnz(rscratch1, next_test); __ str(recv, recv_addr); __ mov(rscratch1, DataLayout::counter_increment); - __ lea(rscratch2, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)))); - __ str(rscratch1, Address(rscratch2)); + __ str(rscratch1, slot_at(ReceiverTypeData::receiver_count_offset(i))); __ b(*update_done); __ bind(next_test); } @@ -1414,8 +1419,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // Object is null; update MDO and exit Address data_addr = __ form_address(rscratch2, mdo, - md->byte_offset_of_slot(data, DataLayout::flags_offset()), - 0); + md->byte_offset_of_slot(data, DataLayout::flags_offset()), 0); __ ldrb(rscratch1, data_addr); __ orr(rscratch1, rscratch1, BitData::null_seen_byte_constant()); __ strb(rscratch1, data_addr); @@ -2566,10 +2570,12 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { for (i = 0; i < VirtualCallData::row_limit(); i++) { ciKlass* receiver = vc_data->receiver(i); if (receiver == nullptr) { - Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); __ mov_metadata(rscratch1, known_klass->constant_encoding()); - __ lea(rscratch2, recv_addr); - __ str(rscratch1, Address(rscratch2)); + Address recv_addr = + __ form_address(rscratch2, mdo, + md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)), + LogBytesPerWord); + __ str(rscratch1, recv_addr); Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); __ addptr(data_addr, DataLayout::counter_increment); return; diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp index 4ae2da6680263..e85daed732429 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" @@ -779,13 +778,11 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { } case vmIntrinsics::_floatToFloat16: { LIR_Opr tmp = new_register(T_FLOAT); - __ move(LIR_OprFact::floatConst(-0.0), tmp); __ f2hf(src, dst, tmp); break; } case vmIntrinsics::_float16ToFloat: { LIR_Opr tmp = new_register(T_FLOAT); - __ move(LIR_OprFact::floatConst(-0.0), tmp); __ hf2f(src, dst, tmp); break; } @@ -1319,6 +1316,11 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return Runtime1::entry_for(C1StubId::is_instance_of_id); +} + void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); ValueTag tag = x->x()->type()->tag(); diff --git a/src/hotspot/cpu/aarch64/c1_LIR_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIR_aarch64.cpp index 0dd1a2156e89e..5d2890251d7d4 100644 --- a/src/hotspot/cpu/aarch64/c1_LIR_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIR_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "c1/c1_LIR.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.cpp index 4b426694cd7e3..d99916ecb8863 100644 --- a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp index 01a4d27532a5b..4062adf4154b6 100644 --- a/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_LinearScan_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,9 +41,9 @@ inline bool LinearScan::requires_adjacent_regs(BasicType type) { inline bool LinearScan::is_caller_save(int assigned_reg) { assert(assigned_reg >= 0 && assigned_reg < nof_regs, "should call this only for registers"); - if (assigned_reg < pd_first_callee_saved_reg) + if (assigned_reg < FrameMap::nof_caller_save_cpu_regs()) return true; - if (assigned_reg > pd_last_callee_saved_reg && assigned_reg < pd_first_callee_saved_fpu_reg) + if (assigned_reg >= pd_first_fpu_reg && assigned_reg < pd_first_callee_saved_fpu_reg) return true; if (assigned_reg > pd_last_callee_saved_fpu_reg && assigned_reg < pd_last_fpu_reg) return true; @@ -66,7 +66,7 @@ inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) { return true; } else if (cur->type() == T_INT || cur->type() == T_LONG || cur->type() == T_OBJECT || cur->type() == T_ADDRESS || cur->type() == T_METADATA) { _first_reg = pd_first_cpu_reg; - _last_reg = pd_last_allocatable_cpu_reg; + _last_reg = FrameMap::last_cpu_reg(); return true; } return false; diff --git a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp index fc6cadc8450cb..6b1a5a7f1e0c4 100644 --- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp index 19665d1b89404..063918ee20b7b 100644 --- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_Defs.hpp" @@ -258,15 +257,18 @@ static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) { int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); OopMap* oop_map = new OopMap(frame_size_in_slots, 0); - for (int i = 0; i < FrameMap::nof_cpu_regs; i++) { - Register r = as_Register(i); - if (r == rthread || (i <= 18 && i != rscratch1->encoding() && i != rscratch2->encoding())) { - int sp_offset = cpu_reg_save_offsets[i]; - oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), - r->as_VMReg()); - } + for (int i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) { + LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i); + Register r = opr->as_register(); + int reg_num = r->encoding(); + int sp_offset = cpu_reg_save_offsets[reg_num]; + oop_map->set_callee_saved(VMRegImpl::stack2reg(cpu_reg_save_offsets[reg_num]), r->as_VMReg()); } + Register r = rthread; + int reg_num = r->encoding(); + oop_map->set_callee_saved(VMRegImpl::stack2reg(cpu_reg_save_offsets[reg_num]), r->as_VMReg()); + if (save_fpu_registers) { for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { FloatRegister r = as_FloatRegister(i); @@ -901,6 +903,55 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { } break; + case C1StubId::is_instance_of_id: + { + // Mirror: c_rarg0 + // Object: c_rarg1 + // Temps: r3, r4, r5, r6 + // Result: r0 + + // Get the Klass* into c_rarg6 + Register klass = c_rarg6, obj = c_rarg1, result = r0; + __ ldr(klass, Address(c_rarg0, java_lang_Class::klass_offset())); + + Label fail, is_secondary, success; + + __ cbz(klass, fail); // Klass is null + __ cbz(obj, fail); // obj is null + + __ ldrw(r3, Address(klass, in_bytes(Klass::super_check_offset_offset()))); + __ cmpw(r3, in_bytes(Klass::secondary_super_cache_offset())); + __ br(Assembler::EQ, is_secondary); // Klass is a secondary superclass + + // Klass is a concrete class + __ load_klass(r5, obj); + __ ldr(rscratch1, Address(r5, r3)); + __ cmp(klass, rscratch1); + __ cset(result, Assembler::EQ); + __ ret(lr); + + __ bind(is_secondary); + + __ load_klass(obj, obj); + + // This is necessary because I am never in my own secondary_super list. + __ cmp(obj, klass); + __ br(Assembler::EQ, success); + + __ lookup_secondary_supers_table_var(obj, klass, + /*temps*/r3, r4, r5, v0, + result, + &success); + __ bind(fail); + __ mov(result, 0); + __ ret(lr); + + __ bind(success); + __ mov(result, 1); + __ ret(lr); + } + break; + case C1StubId::monitorexit_nofpu_id: save_fpu_registers = false; // fall through diff --git a/src/hotspot/cpu/aarch64/c2_CodeStubs_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_CodeStubs_aarch64.cpp index 90157a5668d94..5d8d1fbd9cb44 100644 --- a/src/hotspot/cpu/aarch64/c2_CodeStubs_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_CodeStubs_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/c2_MacroAssembler.hpp" #include "opto/c2_CodeStubs.hpp" #include "runtime/objectMonitor.hpp" diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 5cc579762969d..e3d197a457215 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "opto/c2_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp index 436e0c5e41c31..e1bf8e3d1af11 100644 --- a/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_init_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp index 31618414e31b7..97d9f7afdfb48 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.inline.hpp" #include "asm/macroAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp index b9248b01a0911..24a7a78b8004b 100644 --- a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp b/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp index 6ad6e3134bc51..0c2d9a32c8c13 100644 --- a/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "logging/log.hpp" #include "oops/compressedKlass.hpp" diff --git a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp index 4322eb1c4fcb6..7febbaa63bbc9 100644 --- a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp b/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp index 9d1a66f887126..1ed5e6f312f76 100644 --- a/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/vmreg.inline.hpp" #include "runtime/jniHandles.hpp" #include "runtime/jniHandles.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index 361b913fd2ea2..b07fa2fa9df64 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" @@ -163,6 +162,11 @@ bool frame::safe_for_sender(JavaThread *thread) { } if (Continuation::is_return_barrier_entry(sender_pc)) { + // sender_pc might be invalid so check that the frame + // actually belongs to a Continuation. + if (!Continuation::is_frame_in_continuation(thread, *this)) { + return false; + } // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); @@ -503,11 +507,11 @@ frame frame::sender_for_interpreter_frame(RegisterMap* map) const { intptr_t* unextended_sp = interpreter_frame_sender_sp(); intptr_t* sender_fp = link(); -#if COMPILER2_OR_JVMCI +#if defined(COMPILER1) || COMPILER2_OR_JVMCI if (map->update_map()) { update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset)); } -#endif // COMPILER2_OR_JVMCI +#endif // defined(COMPILER1) || COMPILER1_OR_COMPILER2 // For ROP protection, Interpreter will have signed the sender_pc, // but there is no requirement to authenticate it here. diff --git a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp index df521f94d1f84..42f3c4a015ac4 100644 --- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp index 0161843036bc5..828033975a065 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp index 5169a510154ab..c45611c882b5a 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nativeInst.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp index 6afdb285914fb..ea36183c9de95 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp index a50152d244fba..6890159189310 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp index 666335330ed1b..e33ef47cf3c38 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" #include "compiler/compilerDefinitions.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index f682e86cdfbdd..19270d9fecf57 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" diff --git a/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp index c656736aa6473..a58c91a6a41e1 100644 --- a/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/z/zAddress_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.hpp" @@ -85,7 +84,7 @@ static size_t probe_valid_max_address_bit() { munmap(result_addr, page_size); } } - log_info_p(gc, init)("Probing address space for the highest valid bit: " SIZE_FORMAT, max_address_bit); + log_info_p(gc, init)("Probing address space for the highest valid bit: %zu", max_address_bit); return MAX2(max_address_bit, MINIMUM_MAX_ADDRESS_BIT); #else // LINUX return DEFAULT_MAX_ADDRESS_BIT; diff --git a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp index 3f1898b6742e1..5d4f0801ec62f 100644 --- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/vmreg.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/icache_aarch64.cpp b/src/hotspot/cpu/aarch64/icache_aarch64.cpp index 8bdddd4f1516a..311f3a7de1f73 100644 --- a/src/hotspot/cpu/aarch64/icache_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/icache_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020 Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/icache.hpp" void ICacheStubGenerator::generate_icache_flush( diff --git a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp index 9c67a0dfeada9..024d554b98f54 100644 --- a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,6 @@ #include #include -#include "precompiled.hpp" #include "immediate_aarch64.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 836caa86cb0af..9892de21a8114 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/compiler_globals.hpp" #include "gc/shared/barrierSet.hpp" @@ -503,7 +502,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ldr(r1, Address(rfp, frame::interpreter_frame_method_offset * wordSize)); - ldr(r2, Address(r1, Method::access_flags_offset())); + ldrh(r2, Address(r1, Method::access_flags_offset())); tbz(r2, exact_log2(JVM_ACC_SYNCHRONIZED), unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp index 90c7ca6f08a3d..d6310a2d326c9 100644 --- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" diff --git a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp index aea268ea94443..8bec45b4b479a 100644 --- a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp index 45ad873ae2747..3015206dadc4d 100644 --- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "jvmci/jvmci.hpp" #include "jvmci/jvmciCodeInstaller.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index d561fb912a311..b6472b1b94812 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "ci/ciEnv.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 244de10d0e26c..bd537af59e471 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1173,7 +1173,10 @@ class MacroAssembler: public Assembler { // Arithmetics + // Clobber: rscratch1, rscratch2 void addptr(const Address &dst, int32_t src); + + // Clobber: rscratch1 void cmpptr(Register src1, Address src2); void cmpoop(Register obj1, Register obj2); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp index 03853a7ca46be..84b85b7b445cb 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_aes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_chacha.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_chacha.cpp index 9e53258730e50..1f7bb8f46f64f 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_chacha.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_chacha.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,6 @@ * */ -#include "precompiled.hpp" - -#include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_aarch64.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp index 91226dc78eb4f..d4bc983511f1d 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Cavium. All rights reserved. (By BELLSOFT) * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_aarch64.hpp" diff --git a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp index aa6a9d14ff176..588b8898d2d2a 100644 --- a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp index 1f6d729238974..33158d6b97a91 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/aarch64/registerMap_aarch64.cpp b/src/hotspot/cpu/aarch64/registerMap_aarch64.cpp index 7bf513eba31ed..b58386ec80291 100644 --- a/src/hotspot/cpu/aarch64/registerMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/registerMap_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "runtime/registerMap.hpp" #include "vmreg_aarch64.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/register_aarch64.cpp b/src/hotspot/cpu/aarch64/register_aarch64.cpp index 3a46e38a72a76..82683daae4f08 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "register_aarch64.hpp" Register::RegisterImpl all_RegisterImpls [Register::number_of_declared_registers + 1]; diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp index c4c8648d552d0..f5d7d9e4387ec 100644 --- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/nmethod.hpp" #include "code/relocInfo.hpp" diff --git a/src/hotspot/cpu/aarch64/runtime_aarch64.cpp b/src/hotspot/cpu/aarch64/runtime_aarch64.cpp index 5358a4e6a1d48..635c074eadc63 100644 --- a/src/hotspot/cpu/aarch64/runtime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/runtime_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index fa48092fd505a..b0b299876018a 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeCache.hpp" @@ -760,7 +759,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ ldrw(rscratch1, Address(rmethod, Method::access_flags_offset())); + __ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset())); __ andsw(zr, rscratch1, JVM_ACC_STATIC); __ br(Assembler::EQ, L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp new file mode 100644 index 0000000000000..1830bdf4a88d6 --- /dev/null +++ b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_AARCH64_STUBDECLARATIONS_HPP +#define CPU_AARCH64_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 10000) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 2000) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 30000 ZGC_ONLY(+10000)) \ + do_stub(compiler, vector_iota_indices) \ + do_arch_entry(aarch64, compiler, vector_iota_indices, \ + vector_iota_indices, vector_iota_indices) \ + do_stub(compiler, large_array_equals) \ + do_arch_entry(aarch64, compiler, large_array_equals, \ + large_array_equals, large_array_equals) \ + do_stub(compiler, large_arrays_hashcode_boolean) \ + do_arch_entry(aarch64, compiler, large_arrays_hashcode_boolean, \ + large_arrays_hashcode_boolean, \ + large_arrays_hashcode_boolean) \ + do_stub(compiler, large_arrays_hashcode_byte) \ + do_arch_entry(aarch64, compiler, large_arrays_hashcode_byte, \ + large_arrays_hashcode_byte, \ + large_arrays_hashcode_byte) \ + do_stub(compiler, large_arrays_hashcode_char) \ + do_arch_entry(aarch64, compiler, large_arrays_hashcode_char, \ + large_arrays_hashcode_char, \ + large_arrays_hashcode_char) \ + do_stub(compiler, large_arrays_hashcode_short) \ + do_arch_entry(aarch64, compiler, large_arrays_hashcode_short, \ + large_arrays_hashcode_short, \ + large_arrays_hashcode_short) \ + do_stub(compiler, large_arrays_hashcode_int) \ + do_arch_entry(aarch64, compiler, large_arrays_hashcode_int, \ + large_arrays_hashcode_int, \ + large_arrays_hashcode_int) \ + do_stub(compiler, large_byte_array_inflate) \ + do_arch_entry(aarch64, compiler, large_byte_array_inflate, \ + large_byte_array_inflate, large_byte_array_inflate) \ + do_stub(compiler, count_positives) \ + do_arch_entry(aarch64, compiler, count_positives, count_positives, \ + count_positives) \ + do_stub(compiler, count_positives_long) \ + do_arch_entry(aarch64, compiler, count_positives_long, \ + count_positives_long, count_positives_long) \ + do_stub(compiler, compare_long_string_LL) \ + do_arch_entry(aarch64, compiler, compare_long_string_LL, \ + compare_long_string_LL, compare_long_string_LL) \ + do_stub(compiler, compare_long_string_UU) \ + do_arch_entry(aarch64, compiler, compare_long_string_UU, \ + compare_long_string_UU, compare_long_string_UU) \ + do_stub(compiler, compare_long_string_LU) \ + do_arch_entry(aarch64, compiler, compare_long_string_LU, \ + compare_long_string_LU, compare_long_string_LU) \ + do_stub(compiler, compare_long_string_UL) \ + do_arch_entry(aarch64, compiler, compare_long_string_UL, \ + compare_long_string_UL, compare_long_string_UL) \ + do_stub(compiler, string_indexof_linear_ll) \ + do_arch_entry(aarch64, compiler, string_indexof_linear_ll, \ + string_indexof_linear_ll, string_indexof_linear_ll) \ + do_stub(compiler, string_indexof_linear_uu) \ + do_arch_entry(aarch64, compiler, string_indexof_linear_uu, \ + string_indexof_linear_uu, string_indexof_linear_uu) \ + do_stub(compiler, string_indexof_linear_ul) \ + do_arch_entry(aarch64, compiler, string_indexof_linear_ul, \ + string_indexof_linear_ul, string_indexof_linear_ul) \ + /* this uses the entry for ghash_processBlocks */ \ + do_stub(compiler, ghash_processBlocks_wide) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 20000 ZGC_ONLY(+100000)) \ + do_stub(final, copy_byte_f) \ + do_arch_entry(aarch64, final, copy_byte_f, copy_byte_f, \ + copy_byte_f) \ + do_stub(final, copy_byte_b) \ + do_arch_entry(aarch64, final, copy_byte_b, copy_byte_b, \ + copy_byte_b) \ + do_stub(final, copy_oop_f) \ + do_arch_entry(aarch64, final, copy_oop_f, copy_oop_f, copy_oop_f) \ + do_stub(final, copy_oop_b) \ + do_arch_entry(aarch64, final, copy_oop_b, copy_oop_b, copy_oop_b) \ + do_stub(final, copy_oop_uninit_f) \ + do_arch_entry(aarch64, final, copy_oop_uninit_f, copy_oop_uninit_f, \ + copy_oop_uninit_f) \ + do_stub(final, copy_oop_uninit_b) \ + do_arch_entry(aarch64, final, copy_oop_uninit_b, copy_oop_uninit_b, \ + copy_oop_uninit_b) \ + do_stub(final, zero_blocks) \ + do_arch_entry(aarch64, final, zero_blocks, zero_blocks, \ + zero_blocks) \ + do_stub(final, spin_wait) \ + do_arch_entry_init(aarch64, final, spin_wait, spin_wait, \ + spin_wait, empty_spin_wait) \ + /* stub only -- entries are not stored in StubRoutines::aarch64 */ \ + /* n.b. these are not the same as the generic atomic stubs */ \ + do_stub(final, atomic_entry_points) \ + + +#endif // CPU_AARCH64_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index de5df5c1af156..5f901a5e9ea11 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "asm/register.hpp" @@ -203,7 +202,8 @@ class StubGenerator: public StubCodeGenerator { (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, "adjust this code"); - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Address sp_after_call (rfp, sp_after_call_off * wordSize); @@ -422,7 +422,8 @@ class StubGenerator: public StubCodeGenerator { // r0: exception oop address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // same as in generate_call_stub(): @@ -477,7 +478,8 @@ class StubGenerator: public StubCodeGenerator { // so it just needs to be generated code with no x86 prolog address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Upon entry, LR points to the return address returning into @@ -566,8 +568,8 @@ class StubGenerator: public StubCodeGenerator { // [tos + 4]: saved r0 // [tos + 5]: saved rscratch1 address generate_verify_oop() { - - StubCodeMark mark(this, "StubRoutines", "verify_oop"); + StubGenStubId stub_id = StubGenStubId::verify_oop_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label exit, error; @@ -615,9 +617,9 @@ class StubGenerator: public StubCodeGenerator { } // Generate indices for iota vector. - address generate_iota_indices(const char *stub_name) { + address generate_iota_indices(StubGenStubId stub_id) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); // B __ emit_data64(0x0706050403020100, relocInfo::none); @@ -660,7 +662,8 @@ class StubGenerator: public StubCodeGenerator { Register base = r10, cnt = r11; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "zero_blocks"); + StubGenStubId stub_id = StubGenStubId::zero_blocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); if (UseBlockZeroing) { @@ -799,8 +802,39 @@ class StubGenerator: public StubCodeGenerator { // // s and d are adjusted to point to the remaining words to copy // - void generate_copy_longs(DecoratorSet decorators, BasicType type, Label &start, Register s, Register d, Register count, - copy_direction direction) { + void generate_copy_longs(StubGenStubId stub_id, DecoratorSet decorators, Label &start, Register s, Register d, Register count) { + BasicType type; + copy_direction direction; + + switch (stub_id) { + case copy_byte_f_id: + direction = copy_forwards; + type = T_BYTE; + break; + case copy_byte_b_id: + direction = copy_backwards; + type = T_BYTE; + break; + case copy_oop_f_id: + direction = copy_forwards; + type = T_OBJECT; + break; + case copy_oop_b_id: + direction = copy_backwards; + type = T_OBJECT; + break; + case copy_oop_uninit_f_id: + direction = copy_forwards; + type = T_OBJECT; + break; + case copy_oop_uninit_b_id: + direction = copy_backwards; + type = T_OBJECT; + break; + default: + ShouldNotReachHere(); + } + int unit = wordSize * direction; int bias = (UseSIMDForMemoryOps ? 4:2) * wordSize; @@ -815,15 +849,10 @@ class StubGenerator: public StubCodeGenerator { assert_different_registers(s, d, count, rscratch1, rscratch2); Label again, drain; - const char *stub_name; - if (direction == copy_forwards) - stub_name = "forward_copy_longs"; - else - stub_name = "backward_copy_longs"; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); __ bind(start); @@ -1478,10 +1507,11 @@ class StubGenerator: public StubCodeGenerator { } // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // is_oop - true => oop array, so generate store check code - // name - stub name string + // stub_id - is used to name the stub and identify all details of + // how to perform the copy. + // + // entry - is assigned to the stub's post push entry point unless + // it is null // // Inputs: // c_rarg0 - source array address @@ -1492,16 +1522,96 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - // Side Effects: - // disjoint_int_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_int_oop_copy(). + // Side Effects: entry is set to the (post push) entry point so it + // can be used by the corresponding conjoint copy + // method // - address generate_disjoint_copy(int size, bool aligned, bool is_oop, address *entry, - const char *name, bool dest_uninitialized = false) { + address generate_disjoint_copy(StubGenStubId stub_id, address *entry) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_reg = RegSet::of(s, d, count); + int size; + bool aligned; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + size = sizeof(jbyte); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jbyte_disjoint_arraycopy_id: + size = sizeof(jbyte); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_disjoint_arraycopy_id: + size = sizeof(jshort); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jshort_disjoint_arraycopy_id: + size = sizeof(jshort); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jint_disjoint_arraycopy_id: + size = sizeof(jint); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jint_disjoint_arraycopy_id: + size = sizeof(jint); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_disjoint_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case arrayof_jlong_disjoint_arraycopy + ShouldNotReachHere(); + break; + case arrayof_jlong_disjoint_arraycopy_id: + size = sizeof(jlong); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case arrayof_oop_disjoint_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + case arrayof_oop_disjoint_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + break; + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -1548,10 +1658,16 @@ class StubGenerator: public StubCodeGenerator { } // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // is_oop - true => oop array, so generate store check code - // name - stub name string + // stub_id - is used to name the stub and identify all details of + // how to perform the copy. + // + // nooverlap_target - identifes the (post push) entry for the + // corresponding disjoint copy routine which can be + // jumped to if the ranges do not actually overlap + // + // entry - is assigned to the stub's post push entry point unless + // it is null + // // // Inputs: // c_rarg0 - source array address @@ -1562,12 +1678,94 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - address generate_conjoint_copy(int size, bool aligned, bool is_oop, address nooverlap_target, - address *entry, const char *name, - bool dest_uninitialized = false) { + // Side Effects: + // entry is set to the no-overlap entry point so it can be used by + // some other conjoint copy method + // + address generate_conjoint_copy(StubGenStubId stub_id, address nooverlap_target, address *entry) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_regs = RegSet::of(s, d, count); - StubCodeMark mark(this, "StubRoutines", name); + int size; + bool aligned; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case jbyte_arraycopy_id: + size = sizeof(jbyte); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jbyte_arraycopy_id: + size = sizeof(jbyte); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_arraycopy_id: + size = sizeof(jshort); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jshort_arraycopy_id: + size = sizeof(jshort); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jint_arraycopy_id: + size = sizeof(jint); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jint_arraycopy_id: + size = sizeof(jint); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case arrayof_jlong_disjoint_arraycopy + ShouldNotReachHere(); + break; + case arrayof_jlong_arraycopy_id: + size = sizeof(jlong); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case oop_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case arrayof_oop_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case oop_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + case arrayof_oop_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -1613,230 +1811,8 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); return start; -} - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_byte_copy_entry is set to the no-overlap entry point // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_byte_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_byte_copy(). - // - address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jbyte), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, - address* entry, const char *name) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jbyte), aligned, not_oop, nooverlap_target, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we - // let the hardware handle it. The two or four words within dwords - // or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_short_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_short_copy(). - // - address generate_disjoint_short_copy(bool aligned, - address* entry, const char *name) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jshort), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we - // let the hardware handle it. The two or four words within dwords - // or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - address generate_conjoint_short_copy(bool aligned, address nooverlap_target, - address *entry, const char *name) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jshort), aligned, not_oop, nooverlap_target, entry, name); - - } - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let - // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomically. - // - // Side Effects: - // disjoint_int_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_int_oop_copy(). - // - address generate_disjoint_int_copy(bool aligned, address *entry, - const char *name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jint), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let - // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomically. - // - address generate_conjoint_int_copy(bool aligned, address nooverlap_target, - address *entry, const char *name, - bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jint), aligned, not_oop, nooverlap_target, entry, name); - } - - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - // Side Effects: - // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the - // no-overlap entry point used by generate_conjoint_long_oop_copy(). - // - address generate_disjoint_long_copy(bool aligned, address *entry, - const char *name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jlong), aligned, not_oop, entry, name); } - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - address generate_conjoint_long_copy(bool aligned, - address nooverlap_target, address *entry, - const char *name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jlong), aligned, not_oop, nooverlap_target, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - // Side Effects: - // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the - // no-overlap entry point used by generate_conjoint_long_oop_copy(). - // - address generate_disjoint_oop_copy(bool aligned, address *entry, - const char *name, bool dest_uninitialized) { - const bool is_oop = true; - const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); - return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - address generate_conjoint_oop_copy(bool aligned, - address nooverlap_target, address *entry, - const char *name, bool dest_uninitialized) { - const bool is_oop = true; - const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); - return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, - name, dest_uninitialized); - } - - // Helper for generating a dynamic type check. // Smashes rscratch1, rscratch2. void generate_type_check(Register sub_klass, @@ -1874,8 +1850,18 @@ class StubGenerator: public StubCodeGenerator { // r0 == 0 - success // r0 == -1^K - failure, where K is partial transfer count // - address generate_checkcast_copy(const char *name, address *entry, - bool dest_uninitialized = false) { + address generate_checkcast_copy(StubGenStubId stub_id, address *entry) { + bool dest_uninitialized; + switch (stub_id) { + case checkcast_arraycopy_id: + dest_uninitialized = false; + break; + case checkcast_arraycopy_uninit_id: + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } Label L_load_element, L_store_element, L_do_card_marks, L_done, L_done_pop; @@ -1909,7 +1895,7 @@ class StubGenerator: public StubCodeGenerator { copied_oop, r19_klass, count_save); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2081,16 +2067,17 @@ class StubGenerator: public StubCodeGenerator { // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // - address generate_unsafe_copy(const char *name, - address byte_copy_entry, + address generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + Label L_long_aligned, L_int_aligned, L_short_aligned; Register s = c_rarg0, d = c_rarg1, count = c_rarg2; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2134,10 +2121,10 @@ class StubGenerator: public StubCodeGenerator { // r0 == 0 - success // r0 == -1^K - failure, where K is partial transfer count // - address generate_generic_copy(const char *name, - address byte_copy_entry, address short_copy_entry, + address generate_generic_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry) { + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; Label L_failed, L_objArray; Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; @@ -2155,7 +2142,7 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -2408,9 +2395,41 @@ class StubGenerator: public StubCodeGenerator { // value: c_rarg1 // count: c_rarg2 treated as signed // - address generate_fill(BasicType t, bool aligned, const char *name) { + address generate_fill(StubGenStubId stub_id) { + BasicType t; + bool aligned; + + switch (stub_id) { + case jbyte_fill_id: + t = T_BYTE; + aligned = false; + break; + case jshort_fill_id: + t = T_SHORT; + aligned = false; + break; + case jint_fill_id: + t = T_INT; + aligned = false; + break; + case arrayof_jbyte_fill_id: + t = T_BYTE; + aligned = true; + break; + case arrayof_jshort_fill_id: + t = T_SHORT; + aligned = true; + break; + case arrayof_jint_fill_id: + t = T_INT; + aligned = true; + break; + default: + ShouldNotReachHere(); + }; + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -2552,7 +2571,8 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -2568,7 +2588,8 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_sync_id; + StubCodeMark mark(this, stub_id); // pre wbsync is a no-op // post wbsync translates to an sfence @@ -2594,61 +2615,44 @@ class StubGenerator: public StubCodeGenerator { address entry_jlong_arraycopy; address entry_checkcast_arraycopy; - generate_copy_longs(IN_HEAP | IS_ARRAY, T_BYTE, copy_f, r0, r1, r15, copy_forwards); - generate_copy_longs(IN_HEAP | IS_ARRAY, T_BYTE, copy_b, r0, r1, r15, copy_backwards); + generate_copy_longs(StubGenStubId::copy_byte_f_id, IN_HEAP | IS_ARRAY, copy_f, r0, r1, r15); + generate_copy_longs(StubGenStubId::copy_byte_b_id, IN_HEAP | IS_ARRAY, copy_b, r0, r1, r15); - generate_copy_longs(IN_HEAP | IS_ARRAY, T_OBJECT, copy_obj_f, r0, r1, r15, copy_forwards); - generate_copy_longs(IN_HEAP | IS_ARRAY, T_OBJECT, copy_obj_b, r0, r1, r15, copy_backwards); + generate_copy_longs(StubGenStubId::copy_oop_f_id, IN_HEAP | IS_ARRAY, copy_obj_f, r0, r1, r15); + generate_copy_longs(StubGenStubId::copy_oop_b_id, IN_HEAP | IS_ARRAY, copy_obj_b, r0, r1, r15); - generate_copy_longs(IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, T_OBJECT, copy_obj_uninit_f, r0, r1, r15, copy_forwards); - generate_copy_longs(IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, T_OBJECT, copy_obj_uninit_b, r0, r1, r15, copy_backwards); + generate_copy_longs(StubGenStubId::copy_oop_uninit_f_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_f, r0, r1, r15); + generate_copy_longs(StubGenStubId::copy_oop_uninit_b_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_b, r0, r1, r15); StubRoutines::aarch64::_zero_blocks = generate_zero_blocks(); //*** jbyte // Always need aligned and unaligned versions - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, - "jbyte_disjoint_arraycopy"); - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, - &entry_jbyte_arraycopy, - "jbyte_arraycopy"); - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, - "arrayof_jbyte_disjoint_arraycopy"); - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, nullptr, - "arrayof_jbyte_arraycopy"); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jbyte_disjoint_arraycopy_id, &entry); + StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubGenStubId::jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy); + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jbyte_arraycopy_id, entry, nullptr); //*** jshort // Always need aligned and unaligned versions - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, - "jshort_disjoint_arraycopy"); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, - &entry_jshort_arraycopy, - "jshort_arraycopy"); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, - "arrayof_jshort_disjoint_arraycopy"); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, nullptr, - "arrayof_jshort_arraycopy"); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jshort_disjoint_arraycopy_id, &entry); + StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubGenStubId::jshort_arraycopy_id, entry, &entry_jshort_arraycopy); + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jshort_arraycopy_id, entry, nullptr); //*** jint // Aligned versions - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, - "arrayof_jint_disjoint_arraycopy"); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, &entry_jint_arraycopy, - "arrayof_jint_arraycopy"); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jint_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jint_arraycopy_id, entry, &entry_jint_arraycopy); // In 64 bit we need both aligned and unaligned versions of jint arraycopy. // entry_jint_arraycopy always points to the unaligned version - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, - "jint_disjoint_arraycopy"); - StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, - &entry_jint_arraycopy, - "jint_arraycopy"); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jint_disjoint_arraycopy_id, &entry); + StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubGenStubId::jint_arraycopy_id, entry, &entry_jint_arraycopy); //*** jlong // It is always aligned - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, &entry, - "arrayof_jlong_disjoint_arraycopy"); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(true, entry, &entry_jlong_arraycopy, - "arrayof_jlong_arraycopy"); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jlong_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jlong_arraycopy_id, entry, &entry_jlong_arraycopy); StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; @@ -2659,18 +2663,14 @@ class StubGenerator: public StubCodeGenerator { bool aligned = !UseCompressedOops; StubRoutines::_arrayof_oop_disjoint_arraycopy - = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy", - /*dest_uninitialized*/false); + = generate_disjoint_copy(StubGenStubId::arrayof_oop_disjoint_arraycopy_id, &entry); StubRoutines::_arrayof_oop_arraycopy - = generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy", - /*dest_uninitialized*/false); + = generate_conjoint_copy(StubGenStubId::arrayof_oop_arraycopy_id, entry, &entry_oop_arraycopy); // Aligned versions without pre-barriers StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit - = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit", - /*dest_uninitialized*/true); + = generate_disjoint_copy(StubGenStubId::arrayof_oop_disjoint_arraycopy_uninit_id, &entry); StubRoutines::_arrayof_oop_arraycopy_uninit - = generate_conjoint_oop_copy(aligned, entry, nullptr, "arrayof_oop_arraycopy_uninit", - /*dest_uninitialized*/true); + = generate_conjoint_copy(StubGenStubId::arrayof_oop_arraycopy_uninit_id, entry, nullptr); } StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; @@ -2678,30 +2678,27 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); - StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", nullptr, - /*dest_uninitialized*/true); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_uninit_id, nullptr); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_jlong_arraycopy); - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_oop_arraycopy, entry_jlong_arraycopy, entry_checkcast_arraycopy); - StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); - StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); - StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); - StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); - StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); - StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); + StubRoutines::_jbyte_fill = generate_fill(StubGenStubId::jbyte_fill_id); + StubRoutines::_jshort_fill = generate_fill(StubGenStubId::jshort_fill_id); + StubRoutines::_jint_fill = generate_fill(StubGenStubId::jint_fill_id); + StubRoutines::_arrayof_jbyte_fill = generate_fill(StubGenStubId::arrayof_jbyte_fill_id); + StubRoutines::_arrayof_jshort_fill = generate_fill(StubGenStubId::arrayof_jshort_fill_id); + StubRoutines::_arrayof_jint_fill = generate_fill(StubGenStubId::arrayof_jint_fill_id); } void generate_math_stubs() { Unimplemented(); } @@ -2715,7 +2712,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_aescrypt_encryptBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -2748,7 +2746,8 @@ class StubGenerator: public StubCodeGenerator { address generate_aescrypt_decryptBlock() { assert(UseAES, "need AES cryptographic extension support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_doLast; const Register from = c_rarg0; // source array address @@ -2786,7 +2785,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cipherBlockChaining_encryptAESCrypt() { assert(UseAES, "need AES cryptographic extension support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; @@ -2890,7 +2890,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cipherBlockChaining_decryptAESCrypt() { assert(UseAES, "need AES cryptographic extension support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; @@ -3076,7 +3077,8 @@ class StubGenerator: public StubCodeGenerator { // Wide bulk encryption of whole blocks. __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::counterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); const address start = __ pc(); __ enter(); @@ -3285,7 +3287,8 @@ class StubGenerator: public StubCodeGenerator { __ emit_int64(0x87); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "galoisCounterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::galoisCounterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -3494,9 +3497,21 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - int offset // c_rarg3 - int limit // - address generate_md5_implCompress(bool multi_block, const char *name) { + address generate_md5_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case md5_implCompress_id: + multi_block = false; + break; + case md5_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -3635,9 +3650,22 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - int offset // c_rarg3 - int limit // - address generate_sha1_implCompress(bool multi_block, const char *name) { + address generate_sha1_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha1_implCompress_id: + multi_block = false; + break; + case sha1_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -3727,7 +3755,19 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - int offset // c_rarg3 - int limit // - address generate_sha256_implCompress(bool multi_block, const char *name) { + address generate_sha256_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha256_implCompress_id: + multi_block = false; + break; + case sha256_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + static const uint32_t round_consts[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, @@ -3746,8 +3786,10 @@ class StubGenerator: public StubCodeGenerator { 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, }; + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -3869,7 +3911,19 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - int offset // c_rarg3 - int limit // - address generate_sha512_implCompress(bool multi_block, const char *name) { + address generate_sha512_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha512_implCompress_id: + multi_block = false; + break; + case sha512_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + static const uint64_t round_consts[80] = { 0x428A2F98D728AE22L, 0x7137449123EF65CDL, 0xB5C0FBCFEC4D3B2FL, 0xE9B5DBA58189DBBCL, 0x3956C25BF348B538L, 0x59F111F1B605D019L, @@ -3901,7 +3955,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -4017,7 +4072,19 @@ class StubGenerator: public StubCodeGenerator { // c_rarg3 - int offset // c_rarg4 - int limit // - address generate_sha3_implCompress(bool multi_block, const char *name) { + address generate_sha3_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha3_implCompress_id: + multi_block = false; + break; + case sha3_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + static const uint64_t round_consts[24] = { 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, @@ -4030,7 +4097,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -4247,7 +4315,8 @@ class StubGenerator: public StubCodeGenerator { assert(UseCRC32Intrinsics, "what are we doing here?"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -4272,124 +4341,195 @@ class StubGenerator: public StubCodeGenerator { return start; } - // ChaCha20 block function. This version parallelizes by loading - // individual 32-bit state elements into vectors for four blocks - // (e.g. all four blocks' worth of state[0] in one register, etc.) + // ChaCha20 block function. This version parallelizes 4 quarter + // round operations at a time. It uses 16 SIMD registers to + // produce 4 blocks of key stream. // // state (int[16]) = c_rarg0 - // keystream (byte[1024]) = c_rarg1 + // keystream (byte[256]) = c_rarg1 // return - number of bytes of keystream (always 256) - address generate_chacha20Block_blockpar() { - Label L_twoRounds, L_cc20_const; + // + // In this approach, we load the 512-bit start state sequentially into + // 4 128-bit vectors. We then make 4 4-vector copies of that starting + // state, with each successive set of 4 vectors having a +1 added into + // the first 32-bit lane of the 4th vector in that group (the counter). + // By doing this, we can perform the block function on 4 512-bit blocks + // within one run of this intrinsic. + // The alignment of the data across the 4-vector group is such that at + // the start it is already aligned for the first round of each two-round + // loop iteration. In other words, the corresponding lanes of each vector + // will contain the values needed for that quarter round operation (e.g. + // elements 0/4/8/12, 1/5/9/13, 2/6/10/14, etc.). + // In between each full round, a lane shift must occur. Within a loop + // iteration, between the first and second rounds, the 2nd, 3rd, and 4th + // vectors are rotated left 32, 64 and 96 bits, respectively. The result + // is effectively a diagonal orientation in columnar form. After the + // second full round, those registers are left-rotated again, this time + // 96, 64, and 32 bits - returning the vectors to their columnar organization. + // After all 10 iterations, the original state is added to each 4-vector + // working state along with the add mask, and the 4 vector groups are + // sequentially written to the memory dedicated for the output key stream. + // + // For a more detailed explanation, see Goll and Gueron, "Vectorization of + // ChaCha Stream Cipher", 2014 11th Int. Conf. on Information Technology: + // New Generations, Las Vegas, NV, USA, April 2014, DOI: 10.1109/ITNG.2014.33 + address generate_chacha20Block_qrpar() { + Label L_Q_twoRounds, L_Q_cc20_const; // The constant data is broken into two 128-bit segments to be loaded - // onto FloatRegisters. The first 128 bits are a counter add overlay - // that adds +0/+1/+2/+3 to the vector holding replicated state[12]. + // onto SIMD registers. The first 128 bits are a counter add overlay + // that adds +1/+0/+0/+0 to the vectors holding replicated state[12]. // The second 128-bits is a table constant used for 8-bit left rotations. - __ BIND(L_cc20_const); - __ emit_int64(0x0000000100000000UL); - __ emit_int64(0x0000000300000002UL); + // on 32-bit lanes within a SIMD register. + __ BIND(L_Q_cc20_const); + __ emit_int64(0x0000000000000001UL); + __ emit_int64(0x0000000000000000UL); __ emit_int64(0x0605040702010003UL); __ emit_int64(0x0E0D0C0F0A09080BUL); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "chacha20Block"); + StubGenStubId stub_id = StubGenStubId::chacha20Block_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); - int i, j; const Register state = c_rarg0; const Register keystream = c_rarg1; const Register loopCtr = r10; const Register tmpAddr = r11; - const FloatRegister stateFirst = v0; - const FloatRegister stateSecond = v1; - const FloatRegister stateThird = v2; - const FloatRegister stateFourth = v3; - const FloatRegister origCtrState = v28; - const FloatRegister scratch = v29; + const FloatRegister aState = v0; + const FloatRegister bState = v1; + const FloatRegister cState = v2; + const FloatRegister dState = v3; + const FloatRegister a1Vec = v4; + const FloatRegister b1Vec = v5; + const FloatRegister c1Vec = v6; + const FloatRegister d1Vec = v7; + // Skip the callee-saved registers v8 - v15 + const FloatRegister a2Vec = v16; + const FloatRegister b2Vec = v17; + const FloatRegister c2Vec = v18; + const FloatRegister d2Vec = v19; + const FloatRegister a3Vec = v20; + const FloatRegister b3Vec = v21; + const FloatRegister c3Vec = v22; + const FloatRegister d3Vec = v23; + const FloatRegister a4Vec = v24; + const FloatRegister b4Vec = v25; + const FloatRegister c4Vec = v26; + const FloatRegister d4Vec = v27; + const FloatRegister scratch = v28; + const FloatRegister addMask = v29; const FloatRegister lrot8Tbl = v30; - // Organize SIMD registers in an array that facilitates - // putting repetitive opcodes into loop structures. It is - // important that each grouping of 4 registers is monotonically - // increasing to support the requirements of multi-register - // instructions (e.g. ld4r, st4, etc.) - const FloatRegister workSt[16] = { - v4, v5, v6, v7, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27 - }; - - // Load from memory and interlace across 16 SIMD registers, - // With each word from memory being broadcast to all lanes of - // each successive SIMD register. - // Addr(0) -> All lanes in workSt[i] - // Addr(4) -> All lanes workSt[i + 1], etc. - __ mov(tmpAddr, state); - for (i = 0; i < 16; i += 4) { - __ ld4r(workSt[i], workSt[i + 1], workSt[i + 2], workSt[i + 3], __ T4S, - __ post(tmpAddr, 16)); - } - - // Pull in constant data. The first 16 bytes are the add overlay - // which is applied to the vector holding the counter (state[12]). - // The second 16 bytes is the index register for the 8-bit left - // rotation tbl instruction. - __ adr(tmpAddr, L_cc20_const); - __ ldpq(origCtrState, lrot8Tbl, Address(tmpAddr)); - __ addv(workSt[12], __ T4S, workSt[12], origCtrState); - - // Set up the 10 iteration loop and perform all 8 quarter round ops + // Load the initial state in the first 4 quadword registers, + // then copy the initial state into the next 4 quadword registers + // that will be used for the working state. + __ ld1(aState, bState, cState, dState, __ T16B, Address(state)); + + // Load the index register for 2 constant 128-bit data fields. + // The first represents the +1/+0/+0/+0 add mask. The second is + // the 8-bit left rotation. + __ adr(tmpAddr, L_Q_cc20_const); + __ ldpq(addMask, lrot8Tbl, Address(tmpAddr)); + + __ mov(a1Vec, __ T16B, aState); + __ mov(b1Vec, __ T16B, bState); + __ mov(c1Vec, __ T16B, cState); + __ mov(d1Vec, __ T16B, dState); + + __ mov(a2Vec, __ T16B, aState); + __ mov(b2Vec, __ T16B, bState); + __ mov(c2Vec, __ T16B, cState); + __ addv(d2Vec, __ T4S, d1Vec, addMask); + + __ mov(a3Vec, __ T16B, aState); + __ mov(b3Vec, __ T16B, bState); + __ mov(c3Vec, __ T16B, cState); + __ addv(d3Vec, __ T4S, d2Vec, addMask); + + __ mov(a4Vec, __ T16B, aState); + __ mov(b4Vec, __ T16B, bState); + __ mov(c4Vec, __ T16B, cState); + __ addv(d4Vec, __ T4S, d3Vec, addMask); + + // Set up the 10 iteration loop __ mov(loopCtr, 10); - __ BIND(L_twoRounds); - - __ cc20_quarter_round(workSt[0], workSt[4], workSt[8], workSt[12], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[1], workSt[5], workSt[9], workSt[13], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[2], workSt[6], workSt[10], workSt[14], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[3], workSt[7], workSt[11], workSt[15], - scratch, lrot8Tbl); - - __ cc20_quarter_round(workSt[0], workSt[5], workSt[10], workSt[15], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[1], workSt[6], workSt[11], workSt[12], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[2], workSt[7], workSt[8], workSt[13], - scratch, lrot8Tbl); - __ cc20_quarter_round(workSt[3], workSt[4], workSt[9], workSt[14], - scratch, lrot8Tbl); + __ BIND(L_Q_twoRounds); + + // The first set of operations on the vectors covers the first 4 quarter + // round operations: + // Qround(state, 0, 4, 8,12) + // Qround(state, 1, 5, 9,13) + // Qround(state, 2, 6,10,14) + // Qround(state, 3, 7,11,15) + __ cc20_quarter_round(a1Vec, b1Vec, c1Vec, d1Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a2Vec, b2Vec, c2Vec, d2Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a3Vec, b3Vec, c3Vec, d3Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a4Vec, b4Vec, c4Vec, d4Vec, scratch, lrot8Tbl); + + // Shuffle the b1Vec/c1Vec/d1Vec to reorganize the state vectors to + // diagonals. The a1Vec does not need to change orientation. + __ cc20_shift_lane_org(b1Vec, c1Vec, d1Vec, true); + __ cc20_shift_lane_org(b2Vec, c2Vec, d2Vec, true); + __ cc20_shift_lane_org(b3Vec, c3Vec, d3Vec, true); + __ cc20_shift_lane_org(b4Vec, c4Vec, d4Vec, true); + + // The second set of operations on the vectors covers the second 4 quarter + // round operations, now acting on the diagonals: + // Qround(state, 0, 5,10,15) + // Qround(state, 1, 6,11,12) + // Qround(state, 2, 7, 8,13) + // Qround(state, 3, 4, 9,14) + __ cc20_quarter_round(a1Vec, b1Vec, c1Vec, d1Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a2Vec, b2Vec, c2Vec, d2Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a3Vec, b3Vec, c3Vec, d3Vec, scratch, lrot8Tbl); + __ cc20_quarter_round(a4Vec, b4Vec, c4Vec, d4Vec, scratch, lrot8Tbl); + + // Before we start the next iteration, we need to perform shuffles + // on the b/c/d vectors to move them back to columnar organizations + // from their current diagonal orientation. + __ cc20_shift_lane_org(b1Vec, c1Vec, d1Vec, false); + __ cc20_shift_lane_org(b2Vec, c2Vec, d2Vec, false); + __ cc20_shift_lane_org(b3Vec, c3Vec, d3Vec, false); + __ cc20_shift_lane_org(b4Vec, c4Vec, d4Vec, false); // Decrement and iterate __ sub(loopCtr, loopCtr, 1); - __ cbnz(loopCtr, L_twoRounds); - - __ mov(tmpAddr, state); - - // Add the starting state back to the post-loop keystream - // state. We read/interlace the state array from memory into - // 4 registers similar to what we did in the beginning. Then - // add the counter overlay onto workSt[12] at the end. - for (i = 0; i < 16; i += 4) { - __ ld4r(stateFirst, stateSecond, stateThird, stateFourth, __ T4S, - __ post(tmpAddr, 16)); - __ addv(workSt[i], __ T4S, workSt[i], stateFirst); - __ addv(workSt[i + 1], __ T4S, workSt[i + 1], stateSecond); - __ addv(workSt[i + 2], __ T4S, workSt[i + 2], stateThird); - __ addv(workSt[i + 3], __ T4S, workSt[i + 3], stateFourth); - } - __ addv(workSt[12], __ T4S, workSt[12], origCtrState); // Add ctr mask - - // Write to key stream, storing the same element out of workSt[0..15] - // to consecutive 4-byte offsets in the key stream buffer, then repeating - // for the next element position. - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j += 4) { - __ st4(workSt[j], workSt[j + 1], workSt[j + 2], workSt[j + 3], __ S, i, - __ post(keystream, 16)); - } - } + __ cbnz(loopCtr, L_Q_twoRounds); + + // Once the counter reaches zero, we fall out of the loop + // and need to add the initial state back into the working state + // represented by the a/b/c/d1Vec registers. This is destructive + // on the dState register but we no longer will need it. + __ addv(a1Vec, __ T4S, a1Vec, aState); + __ addv(b1Vec, __ T4S, b1Vec, bState); + __ addv(c1Vec, __ T4S, c1Vec, cState); + __ addv(d1Vec, __ T4S, d1Vec, dState); + + __ addv(a2Vec, __ T4S, a2Vec, aState); + __ addv(b2Vec, __ T4S, b2Vec, bState); + __ addv(c2Vec, __ T4S, c2Vec, cState); + __ addv(dState, __ T4S, dState, addMask); + __ addv(d2Vec, __ T4S, d2Vec, dState); + + __ addv(a3Vec, __ T4S, a3Vec, aState); + __ addv(b3Vec, __ T4S, b3Vec, bState); + __ addv(c3Vec, __ T4S, c3Vec, cState); + __ addv(dState, __ T4S, dState, addMask); + __ addv(d3Vec, __ T4S, d3Vec, dState); + + __ addv(a4Vec, __ T4S, a4Vec, aState); + __ addv(b4Vec, __ T4S, b4Vec, bState); + __ addv(c4Vec, __ T4S, c4Vec, cState); + __ addv(dState, __ T4S, dState, addMask); + __ addv(d4Vec, __ T4S, d4Vec, dState); + + // Write the final state back to the result buffer + __ st1(a1Vec, b1Vec, c1Vec, d1Vec, __ T16B, __ post(keystream, 64)); + __ st1(a2Vec, b2Vec, c2Vec, d2Vec, __ T16B, __ post(keystream, 64)); + __ st1(a3Vec, b3Vec, c3Vec, d3Vec, __ T16B, __ post(keystream, 64)); + __ st1(a4Vec, b4Vec, c4Vec, d4Vec, __ T16B, __ post(keystream, 64)); __ mov(r0, 256); // Return length of output keystream __ leave(); @@ -4414,7 +4554,8 @@ class StubGenerator: public StubCodeGenerator { assert(UseCRC32CIntrinsics, "what are we doing here?"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32C_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -4452,7 +4593,8 @@ class StubGenerator: public StubCodeGenerator { */ address generate_updateBytesAdler32() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesAdler32"); + StubGenStubId stub_id = StubGenStubId::updateBytesAdler32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_simple_by1_loop, L_nmax, L_nmax_loop, L_by16, L_by16_loop, L_by1_loop, L_do_mod, L_combine, L_by1; @@ -4673,7 +4815,8 @@ class StubGenerator: public StubCodeGenerator { */ address generate_multiplyToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); + StubGenStubId stub_id = StubGenStubId::multiplyToLen_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register x = r0; @@ -4705,7 +4848,8 @@ class StubGenerator: public StubCodeGenerator { // faster than multiply_to_len on some CPUs and slower on others, but // multiply_to_len shows a bit better overall results __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "squareToLen"); + StubGenStubId stub_id = StubGenStubId::squareToLen_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register x = r0; @@ -4738,7 +4882,8 @@ class StubGenerator: public StubCodeGenerator { address generate_mulAdd() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "mulAdd"); + StubGenStubId stub_id = StubGenStubId::mulAdd_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -4768,7 +4913,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_bigIntegerRightShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit; @@ -4890,7 +5036,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_bigIntegerLeftShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerLeftShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerLeftShiftWorker_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit; @@ -4998,7 +5145,8 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "count_positives"); + StubGenStubId stub_id = StubGenStubId::count_positives_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -5259,7 +5407,8 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "large_array_equals"); + StubGenStubId stub_id = StubGenStubId::large_array_equals_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); __ enter(); @@ -5384,29 +5533,29 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - const char *mark_name = ""; + StubGenStubId stub_id; switch (eltype) { case T_BOOLEAN: - mark_name = "_large_arrays_hashcode_boolean"; + stub_id = StubGenStubId::large_arrays_hashcode_boolean_id; break; case T_BYTE: - mark_name = "_large_arrays_hashcode_byte"; + stub_id = StubGenStubId::large_arrays_hashcode_byte_id; break; case T_CHAR: - mark_name = "_large_arrays_hashcode_char"; + stub_id = StubGenStubId::large_arrays_hashcode_char_id; break; case T_SHORT: - mark_name = "_large_arrays_hashcode_short"; + stub_id = StubGenStubId::large_arrays_hashcode_short_id; break; case T_INT: - mark_name = "_large_arrays_hashcode_int"; + stub_id = StubGenStubId::large_arrays_hashcode_int_id; break; default: - mark_name = "_large_arrays_hashcode_incorrect_type"; - __ should_not_reach_here(); + stub_id = StubGenStubId::NO_STUBID; + ShouldNotReachHere(); }; - StubCodeMark mark(this, "StubRoutines", mark_name); + StubCodeMark mark(this, stub_id); address entry = __ pc(); __ enter(); @@ -5639,7 +5788,8 @@ class StubGenerator: public StubCodeGenerator { address generate_dsin_dcos(bool isCos) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", isCos ? "libmDcos" : "libmDsin"); + StubGenStubId stub_id = (isCos ? StubGenStubId::dcos_id : StubGenStubId::dsin_id); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ generate_dsin_dcos(isCos, (address)StubRoutines::aarch64::_npio2_hw, (address)StubRoutines::aarch64::_two_over_pi, @@ -5690,9 +5840,8 @@ class StubGenerator: public StubCodeGenerator { // r11 = tmp2 address generate_compare_long_string_different_encoding(bool isLU) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", isLU - ? "compare_long_string_different_encoding LU" - : "compare_long_string_different_encoding UL"); + StubGenStubId stub_id = (isLU ? StubGenStubId::compare_long_string_LU_id : StubGenStubId::compare_long_string_UL_id); + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label SMALL_LOOP, TAIL, TAIL_LOAD_16, LOAD_LAST, DIFF1, DIFF2, DONE, CALCULATE_DIFFERENCE, LARGE_LOOP_PREFETCH, NO_PREFETCH, @@ -5801,7 +5950,8 @@ class StubGenerator: public StubCodeGenerator { // v1 = temporary float register address generate_float16ToFloat() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "float16ToFloat"); + StubGenStubId stub_id = StubGenStubId::hf2f_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); BLOCK_COMMENT("Entry:"); __ flt16_to_flt(v0, r0, v1); @@ -5814,7 +5964,8 @@ class StubGenerator: public StubCodeGenerator { // v1 = temporary float register address generate_floatToFloat16() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "floatToFloat16"); + StubGenStubId stub_id = StubGenStubId::f2hf_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); BLOCK_COMMENT("Entry:"); __ flt_to_flt16(r0, v0, v1); @@ -5824,7 +5975,8 @@ class StubGenerator: public StubCodeGenerator { address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); Label deoptimize_label; @@ -5889,9 +6041,8 @@ class StubGenerator: public StubCodeGenerator { // r11 = tmp2 address generate_compare_long_string_same_encoding(bool isLL) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", isLL - ? "compare_long_string_same_encoding LL" - : "compare_long_string_same_encoding UU"); + StubGenStubId stub_id = (isLL ? StubGenStubId::compare_long_string_LL_id : StubGenStubId::compare_long_string_UU_id); + StubCodeMark mark(this, stub_id); address entry = __ pc(); Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4, tmp1 = r10, tmp2 = r11, tmp1h = rscratch1, tmp2h = rscratch2; @@ -6021,6 +6172,15 @@ class StubGenerator: public StubCodeGenerator { // p0 = pgtmp1 // p1 = pgtmp2 address generate_compare_long_string_sve(string_compare_mode mode) { + StubGenStubId stub_id; + switch (mode) { + case LL: stub_id = StubGenStubId::compare_long_string_LL_id; break; + case LU: stub_id = StubGenStubId::compare_long_string_LU_id; break; + case UL: stub_id = StubGenStubId::compare_long_string_UL_id; break; + case UU: stub_id = StubGenStubId::compare_long_string_UU_id; break; + default: ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); address entry = __ pc(); Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4, @@ -6056,16 +6216,7 @@ class StubGenerator: public StubCodeGenerator { ShouldNotReachHere(); \ } - const char* stubname; - switch (mode) { - case LL: stubname = "compare_long_string_same_encoding LL"; break; - case LU: stubname = "compare_long_string_different_encoding LU"; break; - case UL: stubname = "compare_long_string_different_encoding UL"; break; - case UU: stubname = "compare_long_string_same_encoding UU"; break; - default: ShouldNotReachHere(); - } - - StubCodeMark mark(this, "StubRoutines", stubname); + StubCodeMark mark(this, stub_id); __ mov(idx, 0); __ sve_whilelt(pgtmp1, mode == LL ? __ B : __ H, idx, cnt); @@ -6157,11 +6308,22 @@ class StubGenerator: public StubCodeGenerator { // larger and a bit less readable, however, most of extra operations are // issued during loads or branches, so, penalty is minimal address generate_string_indexof_linear(bool str1_isL, bool str2_isL) { - const char* stubName = str1_isL - ? (str2_isL ? "indexof_linear_ll" : "indexof_linear_ul") - : "indexof_linear_uu"; + StubGenStubId stub_id; + if (str1_isL) { + if (str2_isL) { + stub_id = StubGenStubId::string_indexof_linear_ll_id; + } else { + stub_id = StubGenStubId::string_indexof_linear_ul_id; + } + } else { + if (str2_isL) { + ShouldNotReachHere(); + } else { + stub_id = StubGenStubId::string_indexof_linear_uu_id; + } + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stubName); + StubCodeMark mark(this, stub_id); address entry = __ pc(); int str1_chr_size = str1_isL ? 1 : 2; @@ -6459,7 +6621,8 @@ class StubGenerator: public StubCodeGenerator { // Clobbers: r0, r1, r3, rscratch1, rflags, v0-v6 address generate_large_byte_array_inflate() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "large_byte_array_inflate"); + StubGenStubId stub_id = StubGenStubId::large_byte_array_inflate_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label LOOP, LOOP_START, LOOP_PRFM, LOOP_PRFM_START, DONE; Register src = r0, dst = r1, len = r2, octetCounter = r3; @@ -6524,7 +6687,8 @@ class StubGenerator: public StubCodeGenerator { // that) and keep the data in little-endian bit order through the // calculation, bit-reversing the inputs and outputs. - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); __ align(wordSize * 2); address p = __ pc(); __ emit_int64(0x87); // The low-order bits of the field @@ -6590,7 +6754,8 @@ class StubGenerator: public StubCodeGenerator { address generate_ghash_processBlocks_wide() { address small = generate_ghash_processBlocks(); - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks_wide"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_wide_id; + StubCodeMark mark(this, stub_id); __ align(wordSize * 2); address p = __ pc(); __ emit_int64(0x87); // The low-order bits of the field @@ -6701,7 +6866,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "encodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_encodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Register src = c_rarg0; // source array @@ -6969,7 +7135,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "decodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_decodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Register src = c_rarg0; // source array @@ -7085,7 +7252,8 @@ class StubGenerator: public StubCodeGenerator { // Support for spin waits. address generate_spin_wait() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "spin_wait"); + StubGenStubId stub_id = StubGenStubId::spin_wait_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ spin_wait(); @@ -7094,10 +7262,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); + void generate_lookup_secondary_supers_table_stub() { + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_id; + StubCodeMark mark(this, stub_id); - address start = __ pc(); const Register r_super_klass = r0, r_array_base = r1, @@ -7109,21 +7277,23 @@ class StubGenerator: public StubCodeGenerator { const FloatRegister vtemp = v0; - Label L_success; - __ enter(); - __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, - r_array_base, r_array_length, r_array_index, - vtemp, result, super_klass_index, - /*stub_is_near*/true); - __ leave(); - __ ret(lr); - - return start; + for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + Label L_success; + __ enter(); + __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, + r_array_base, r_array_length, r_array_index, + vtemp, result, slot, + /*stub_is_near*/true); + __ leave(); + __ ret(lr); + } } // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub() { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table_slow_path"); + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_slow_path_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register @@ -7276,9 +7446,9 @@ class StubGenerator: public StubCodeGenerator { if (! UseLSE) { return; } - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "atomic entry points"); + StubGenStubId stub_id = StubGenStubId::atomic_entry_points_id; + StubCodeMark mark(this, stub_id); address first_entry = __ pc(); // ADD, memory_order_conservative @@ -7437,7 +7607,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_thaw() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines", "Cont thaw"); + StubGenStubId stub_id = StubGenStubId::cont_thaw_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_top); return start; @@ -7447,7 +7618,8 @@ class StubGenerator: public StubCodeGenerator { if (!Continuations::enabled()) return nullptr; // TODO: will probably need multiple return barriers depending on return type - StubCodeMark mark(this, "StubRoutines", "cont return barrier"); + StubGenStubId stub_id = StubGenStubId::cont_returnBarrier_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier); @@ -7458,7 +7630,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_returnBarrier_exception() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines", "cont return barrier exception handler"); + StubGenStubId stub_id = StubGenStubId::cont_returnBarrierExc_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier_exception); @@ -7468,7 +7641,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines","Continuation preempt stub"); + StubGenStubId stub_id = StubGenStubId::cont_preempt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ reset_last_Java_frame(true); @@ -7550,7 +7724,8 @@ class StubGenerator: public StubCodeGenerator { address generate_poly1305_processBlocks() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "poly1305_processBlocks"); + StubGenStubId stub_id = StubGenStubId::poly1305_processBlocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label here; __ enter(); @@ -7664,7 +7839,8 @@ class StubGenerator: public StubCodeGenerator { // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { - StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_exception_handler_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Native caller has no idea how to handle exceptions, @@ -7681,7 +7857,8 @@ class StubGenerator: public StubCodeGenerator { // j_rarg0 = jobject receiver // rmethod = result address generate_upcall_stub_load_target() { - StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_load_target_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ resolve_global_jobject(j_rarg0, rscratch1, rscratch2); @@ -8670,9 +8847,8 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::aarch64::_spin_wait = generate_spin_wait(); - if (UsePoly1305Intrinsics) { - StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks(); - } + StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler(); + StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target(); #if defined (LINUX) && !defined (__ARM_FEATURE_ATOMICS) @@ -8684,17 +8860,11 @@ class StubGenerator: public StubCodeGenerator { if (UseSecondarySupersTable) { StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); if (! InlineSecondarySupersTest) { - for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] - = generate_lookup_secondary_supers_table_stub(slot); - } + generate_lookup_secondary_supers_table_stub(); } } #endif - StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler(); - StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target(); - StubRoutines::aarch64::set_completed(); // Inidicate that arraycopy and zero_blocks stubs are generated } @@ -8702,7 +8872,7 @@ class StubGenerator: public StubCodeGenerator { #if COMPILER2_OR_JVMCI if (UseSVE == 0) { - StubRoutines::aarch64::_vector_iota_indices = generate_iota_indices("iota_indices"); + StubRoutines::aarch64::_vector_iota_indices = generate_iota_indices(StubGenStubId::vector_iota_indices_id); } // array equals stub for large arrays. @@ -8746,13 +8916,15 @@ class StubGenerator: public StubCodeGenerator { } if (UseMontgomeryMultiplyIntrinsic) { - StubCodeMark mark(this, "StubRoutines", "montgomeryMultiply"); + StubGenStubId stub_id = StubGenStubId::montgomeryMultiply_id; + StubCodeMark mark(this, stub_id); MontgomeryMultiplyGenerator g(_masm, /*squaring*/false); StubRoutines::_montgomeryMultiply = g.generate_multiply(); } if (UseMontgomerySquareIntrinsic) { - StubCodeMark mark(this, "StubRoutines", "montgomerySquare"); + StubGenStubId stub_id = StubGenStubId::montgomerySquare_id; + StubCodeMark mark(this, stub_id); MontgomeryMultiplyGenerator g(_masm, /*squaring*/true); // We use generate_multiply() rather than generate_square() // because it's faster for the sizes of modulus we care about. @@ -8764,7 +8936,7 @@ class StubGenerator: public StubCodeGenerator { #endif // COMPILER2 if (UseChaCha20Intrinsics) { - StubRoutines::_chacha20Block = generate_chacha20Block_blockpar(); + StubRoutines::_chacha20Block = generate_chacha20Block_qrpar(); } if (UseBASE64Intrinsics) { @@ -8792,24 +8964,28 @@ class StubGenerator: public StubCodeGenerator { } if (UseMD5Intrinsics) { - StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); - StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); + StubRoutines::_md5_implCompress = generate_md5_implCompress(StubGenStubId::md5_implCompress_id); + StubRoutines::_md5_implCompressMB = generate_md5_implCompress(StubGenStubId::md5_implCompressMB_id); } if (UseSHA1Intrinsics) { - StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); - StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); + StubRoutines::_sha1_implCompress = generate_sha1_implCompress(StubGenStubId::sha1_implCompress_id); + StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(StubGenStubId::sha1_implCompressMB_id); } if (UseSHA256Intrinsics) { - StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); - StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(StubGenStubId::sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { - StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); - StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); + StubRoutines::_sha512_implCompress = generate_sha512_implCompress(StubGenStubId::sha512_implCompress_id); + StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } if (UseSHA3Intrinsics) { - StubRoutines::_sha3_implCompress = generate_sha3_implCompress(false, "sha3_implCompress"); - StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(true, "sha3_implCompressMB"); + StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); + } + + if (UsePoly1305Intrinsics) { + StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks(); } // generate Adler32 intrinsics code @@ -8821,29 +8997,29 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp index dee615df5a51f..3fa1616bf6586 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,47 +23,28 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/globalDefinitions.hpp" -// Implementation of the platform-specific part of StubRoutines - for -// a description of how to extend it, see the stubRoutines.hpp file. +// function used as default for spin_wait stub -address StubRoutines::aarch64::_get_previous_sp_entry = nullptr; +static void empty_spin_wait() { } -address StubRoutines::aarch64::_f2i_fixup = nullptr; -address StubRoutines::aarch64::_f2l_fixup = nullptr; -address StubRoutines::aarch64::_d2i_fixup = nullptr; -address StubRoutines::aarch64::_d2l_fixup = nullptr; -address StubRoutines::aarch64::_vector_iota_indices = nullptr; -address StubRoutines::aarch64::_float_sign_mask = nullptr; -address StubRoutines::aarch64::_float_sign_flip = nullptr; -address StubRoutines::aarch64::_double_sign_mask = nullptr; -address StubRoutines::aarch64::_double_sign_flip = nullptr; -address StubRoutines::aarch64::_zero_blocks = nullptr; -address StubRoutines::aarch64::_count_positives = nullptr; -address StubRoutines::aarch64::_count_positives_long = nullptr; -address StubRoutines::aarch64::_large_array_equals = nullptr; -address StubRoutines::aarch64::_large_arrays_hashcode_boolean = nullptr; -address StubRoutines::aarch64::_large_arrays_hashcode_byte = nullptr; -address StubRoutines::aarch64::_large_arrays_hashcode_char = nullptr; -address StubRoutines::aarch64::_large_arrays_hashcode_int = nullptr; -address StubRoutines::aarch64::_large_arrays_hashcode_short = nullptr; -address StubRoutines::aarch64::_compare_long_string_LL = nullptr; -address StubRoutines::aarch64::_compare_long_string_UU = nullptr; -address StubRoutines::aarch64::_compare_long_string_LU = nullptr; -address StubRoutines::aarch64::_compare_long_string_UL = nullptr; -address StubRoutines::aarch64::_string_indexof_linear_ll = nullptr; -address StubRoutines::aarch64::_string_indexof_linear_uu = nullptr; -address StubRoutines::aarch64::_string_indexof_linear_ul = nullptr; -address StubRoutines::aarch64::_large_byte_array_inflate = nullptr; +// define fields for arch-specific entries -static void empty_spin_wait() { } -address StubRoutines::aarch64::_spin_wait = CAST_FROM_FN_PTR(address, empty_spin_wait); +#define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr; + +#define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function); + +STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) + +#undef DEFINE_ARCH_ENTRY_INIT +#undef DEFINE_ARCH_ENTRY bool StubRoutines::aarch64::_completed = false; diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp index 7d3b72a88363d..a5ed87cdca454 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp @@ -34,134 +34,66 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + enum platform_dependent_constants { - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 10000, - _continuation_stubs_code_size = 2000, - _compiler_stubs_code_size = 30000 ZGC_ONLY(+10000), - _final_stubs_code_size = 20000 ZGC_ONLY(+100000) + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + class aarch64 { friend class StubGenerator; +#if INCLUDE_JVMCI + friend class JVMCIVMStructs; +#endif - private: - static address _get_previous_sp_entry; - - static address _f2i_fixup; - static address _f2l_fixup; - static address _d2i_fixup; - static address _d2l_fixup; - - static address _vector_iota_indices; - static address _float_sign_mask; - static address _float_sign_flip; - static address _double_sign_mask; - static address _double_sign_flip; - - static address _zero_blocks; - - static address _large_array_equals; - static address _large_arrays_hashcode_boolean; - static address _large_arrays_hashcode_byte; - static address _large_arrays_hashcode_char; - static address _large_arrays_hashcode_int; - static address _large_arrays_hashcode_short; - static address _compare_long_string_LL; - static address _compare_long_string_LU; - static address _compare_long_string_UL; - static address _compare_long_string_UU; - static address _string_indexof_linear_ll; - static address _string_indexof_linear_uu; - static address _string_indexof_linear_ul; - static address _large_byte_array_inflate; - - static address _spin_wait; - - static bool _completed; - - public: - - static address _count_positives; - static address _count_positives_long; - - static address get_previous_sp_entry() - { - return _get_previous_sp_entry; - } + // declare fields for arch-specific entries - static address f2i_fixup() - { - return _f2i_fixup; - } +#define DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + static address STUB_FIELD_NAME(field_name) ; - static address f2l_fixup() - { - return _f2l_fixup; - } +#define DECLARE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) - static address d2i_fixup() - { - return _d2i_fixup; - } - - static address d2l_fixup() - { - return _d2l_fixup; - } +private: + STUBGEN_ARCH_ENTRIES_DO(DECLARE_ARCH_ENTRY, DECLARE_ARCH_ENTRY_INIT) - static address vector_iota_indices() { - return _vector_iota_indices; - } +#undef DECLARE_ARCH_ENTRY_INIT +#undef DECLARE_ARCH_ENTRY - static address float_sign_mask() - { - return _float_sign_mask; - } - - static address float_sign_flip() - { - return _float_sign_flip; - } + static bool _completed; - static address double_sign_mask() - { - return _double_sign_mask; - } + public: - static address double_sign_flip() - { - return _double_sign_flip; - } + // declare getters for arch-specific entries - static address zero_blocks() { - return _zero_blocks; - } +#define DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) \ + static address getter_name() { return STUB_FIELD_NAME(field_name) ; } - static address count_positives() { - return _count_positives; - } +#define DEFINE_ARCH_ENTRY_GETTER_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) - static address count_positives_long() { - return _count_positives_long; - } + STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY_GETTER, DEFINE_ARCH_ENTRY_GETTER_INIT) - static address large_array_equals() { - return _large_array_equals; - } +#undef DEFINE_ARCH_ENTRY_GETTER_INIT +#undef DEFINE_ARCH_ENTRY_GETTER static address large_arrays_hashcode(BasicType eltype) { switch (eltype) { case T_BOOLEAN: - return _large_arrays_hashcode_boolean; + return large_arrays_hashcode_boolean(); case T_BYTE: - return _large_arrays_hashcode_byte; + return large_arrays_hashcode_byte(); case T_CHAR: - return _large_arrays_hashcode_char; + return large_arrays_hashcode_char(); case T_SHORT: - return _large_arrays_hashcode_short; + return large_arrays_hashcode_short(); case T_INT: - return _large_arrays_hashcode_int; + return large_arrays_hashcode_int(); default: ShouldNotReachHere(); } @@ -169,42 +101,6 @@ class aarch64 { return nullptr; } - static address compare_long_string_LL() { - return _compare_long_string_LL; - } - - static address compare_long_string_LU() { - return _compare_long_string_LU; - } - - static address compare_long_string_UL() { - return _compare_long_string_UL; - } - - static address compare_long_string_UU() { - return _compare_long_string_UU; - } - - static address string_indexof_linear_ul() { - return _string_indexof_linear_ul; - } - - static address string_indexof_linear_ll() { - return _string_indexof_linear_ll; - } - - static address string_indexof_linear_uu() { - return _string_indexof_linear_uu; - } - - static address large_byte_array_inflate() { - return _large_byte_array_inflate; - } - - static address spin_wait() { - return _spin_wait; - } - static bool complete() { return _completed; } diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index f70450b722223..fbe06a6d78138 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "compiler/disassembler.hpp" @@ -809,7 +808,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::NE, L); __ stop("method doesn't need synchronization"); @@ -820,7 +819,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ldr(r0, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -1225,7 +1224,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1277,7 +1276,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); @@ -1354,7 +1353,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_STATIC), L); // get mirror __ load_mirror(t, rmethod, r10, rscratch2); @@ -1564,7 +1563,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ ldrw(t, Address(rmethod, Method::access_flags_offset())); + __ ldrh(t, Address(rmethod, Method::access_flags_offset())); __ tbz(t, exact_log2(JVM_ACC_SYNCHRONIZED), L); // the code below should be shared with interpreter macro // assembler implementation @@ -1695,7 +1694,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); { Label L; __ tst(r0, JVM_ACC_NATIVE); @@ -1751,7 +1750,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ ldrw(r0, access_flags); + __ ldrh(r0, access_flags); __ tst(r0, JVM_ACC_SYNCHRONIZED); __ br(Assembler::EQ, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index 60d4c3c511009..e50810486c80d 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" #include "compiler/compilerDefinitions.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index a2925f00b053f..ac597bea07d5c 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "logging/logStream.hpp" diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 87c7862e2503d..874f8a380ae48 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "pauth_aarch64.hpp" #include "register_aarch64.hpp" #include "runtime/arguments.hpp" @@ -158,6 +157,10 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) { FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2); } + if (FLAG_IS_DEFAULT(CodeEntryAlignment) && + (_model == CPU_MODEL_AMPERE_1A || _model == CPU_MODEL_AMPERE_1B)) { + FLAG_SET_DEFAULT(CodeEntryAlignment, 32); + } } // ThunderX diff --git a/src/hotspot/cpu/aarch64/vmreg_aarch64.cpp b/src/hotspot/cpu/aarch64/vmreg_aarch64.cpp index 49adb39834005..47ca0b30708b9 100644 --- a/src/hotspot/cpu/aarch64/vmreg_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vmreg_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" #include "vmreg_aarch64.inline.hpp" diff --git a/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp b/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp index 56da06433e0b8..11ea02621d765 100644 --- a/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp b/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp index 53e557fad86c8..075db4736f132 100644 --- a/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp +++ b/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "interpreter/bytecode.hpp" #include "interpreter/interpreter.hpp" diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index a3db5c0619ced..617745dee20ab 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -283,7 +283,7 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { } st->print_cr("PUSH R_FP|R_LR_LR"); st->print("\t"); if (framesize != 0) { - st->print ("SUB R_SP, R_SP, " SIZE_FORMAT,framesize); + st->print ("SUB R_SP, R_SP, %zu", framesize); } if (C->stub_function() == nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { @@ -362,7 +362,7 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { framesize -= 2*wordSize; if (framesize != 0) { - st->print("ADD R_SP, R_SP, " SIZE_FORMAT "\n\t",framesize); + st->print("ADD R_SP, R_SP, %zu\n\t",framesize); } st->print("POP R_FP|R_LR_LR"); diff --git a/src/hotspot/cpu/arm/assembler_arm.cpp b/src/hotspot/cpu/arm/assembler_arm.cpp index ec34912ad5113..246c25c6575c1 100644 --- a/src/hotspot/cpu/arm/assembler_arm.cpp +++ b/src/hotspot/cpu/arm/assembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "ci/ciEnv.hpp" diff --git a/src/hotspot/cpu/arm/assembler_arm_32.cpp b/src/hotspot/cpu/arm/assembler_arm_32.cpp index b140bce707633..36a0ae6ebacaa 100644 --- a/src/hotspot/cpu/arm/assembler_arm_32.cpp +++ b/src/hotspot/cpu/arm/assembler_arm_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "ci/ciEnv.hpp" diff --git a/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp b/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp index 8e85fa88a8749..bca6c7ca30cb8 100644 --- a/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp +++ b/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" diff --git a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp index 7eb4009be1136..0fd113c8ceb1b 100644 --- a/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp +++ b/src/hotspot/cpu/arm/c1_FrameMap_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp index b14e6f0b4ca0c..14a51bf4b1352 100644 --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_LIRAssembler.hpp" diff --git a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp index a70bf2cbda953..ef5691f84a32c 100644 --- a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" @@ -1126,6 +1125,11 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return CAST_FROM_FN_PTR(address, Runtime1::is_instance_of); +} + #ifdef __SOFTFP__ // Turn operator if (f g) into runtime call: diff --git a/src/hotspot/cpu/arm/c1_LIR_arm.cpp b/src/hotspot/cpu/arm/c1_LIR_arm.cpp index 9d70fd12f3558..b8d693093483b 100644 --- a/src/hotspot/cpu/arm/c1_LIR_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIR_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIR.hpp" FloatRegister LIR_Opr::as_float_reg() const { diff --git a/src/hotspot/cpu/arm/c1_LinearScan_arm.cpp b/src/hotspot/cpu/arm/c1_LinearScan_arm.cpp index 21030b9a23f95..f1d6c6a0ff94f 100644 --- a/src/hotspot/cpu/arm/c1_LinearScan_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LinearScan_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp index 70542d278acf7..195607d5c9119 100644 --- a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp index bae882ea93d93..949e985ab1eea 100644 --- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp +++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_LIRAssembler.hpp" diff --git a/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp b/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp index 900bd33fd9d46..89be6d288ffeb 100644 --- a/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "opto/c2_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/arm/compiledIC_arm.cpp b/src/hotspot/cpu/arm/compiledIC_arm.cpp index 2556a79126a6d..86927cd24ab9e 100644 --- a/src/hotspot/cpu/arm/compiledIC_arm.cpp +++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/nativeInst.hpp" diff --git a/src/hotspot/cpu/arm/downcallLinker_arm.cpp b/src/hotspot/cpu/arm/downcallLinker_arm.cpp index eb15424eb38cf..e0d32dbe154e0 100644 --- a/src/hotspot/cpu/arm/downcallLinker_arm.cpp +++ b/src/hotspot/cpu/arm/downcallLinker_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/downcallLinker.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/arm/foreignGlobals_arm.cpp b/src/hotspot/cpu/arm/foreignGlobals_arm.cpp index 5f5a4eb32e0c7..677440e380235 100644 --- a/src/hotspot/cpu/arm/foreignGlobals_arm.cpp +++ b/src/hotspot/cpu/arm/foreignGlobals_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/vmreg.hpp" #include "prims/foreignGlobals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/arm/frame_arm.cpp b/src/hotspot/cpu/arm/frame_arm.cpp index 13a5c471c6fea..2722f93edec55 100644 --- a/src/hotspot/cpu/arm/frame_arm.cpp +++ b/src/hotspot/cpu/arm/frame_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp index 17ac726ada774..466dcc8fe66c1 100644 --- a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp index 521c766bcd072..704ca71ce990d 100644 --- a/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp b/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp index ed15cc5ebcfe7..224a499ff5420 100644 --- a/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/barrierSetNMethod_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nativeInst.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp index 11b2ca2ef1d8c..91d3b8e9e5cee 100644 --- a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" diff --git a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp index 73208cec4e8fe..cb4058d48edb9 100644 --- a/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/modRefBarrierSetAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/arm/icache_arm.cpp b/src/hotspot/cpu/arm/icache_arm.cpp index 61fcb8a358048..53e9824756a2e 100644 --- a/src/hotspot/cpu/arm/icache_arm.cpp +++ b/src/hotspot/cpu/arm/icache_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.hpp" #include "runtime/icache.hpp" diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 3a81fdddb3c32..e9e6187a6d181 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" @@ -736,7 +735,7 @@ void InterpreterMacroAssembler::remove_activation(TosState state, Register ret_a ldrb(Rflag, do_not_unlock_if_synchronized); // get method access flags - ldr_u32(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); + ldrh(Raccess_flags, Address(Rmethod, Method::access_flags_offset())); strb(zero_register(Rtemp), do_not_unlock_if_synchronized); // reset the flag diff --git a/src/hotspot/cpu/arm/interpreterRT_arm.cpp b/src/hotspot/cpu/arm/interpreterRT_arm.cpp index c8996bc266ca3..20dcbcdd8be0e 100644 --- a/src/hotspot/cpu/arm/interpreterRT_arm.cpp +++ b/src/hotspot/cpu/arm/interpreterRT_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" diff --git a/src/hotspot/cpu/arm/jniFastGetField_arm.cpp b/src/hotspot/cpu/arm/jniFastGetField_arm.cpp index 2a7e16578fffa..3a5dd10e82eba 100644 --- a/src/hotspot/cpu/arm/jniFastGetField_arm.cpp +++ b/src/hotspot/cpu/arm/jniFastGetField_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.hpp" #include "code/codeBlob.hpp" diff --git a/src/hotspot/cpu/arm/macroAssembler_arm.cpp b/src/hotspot/cpu/arm/macroAssembler_arm.cpp index 8e7b323e535f1..638b3a5404c25 100644 --- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.hpp" diff --git a/src/hotspot/cpu/arm/methodHandles_arm.cpp b/src/hotspot/cpu/arm/methodHandles_arm.cpp index f59e01112e904..3710fa33f365e 100644 --- a/src/hotspot/cpu/arm/methodHandles_arm.cpp +++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ // cross platform development for JSR292. // Last synchronization: changeset f8c9417e3571 -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" #include "interpreter/interpreter.hpp" @@ -497,7 +496,7 @@ void trace_method_handle_stub(const char* adaptername, if (!has_mh) { mh_reg_name = "R5"; } - log_info(methodhandles)("MH %s %s=" PTR_FORMAT " sp=(" PTR_FORMAT "+" INTX_FORMAT ") stack_size=" INTX_FORMAT " bp=" PTR_FORMAT, + log_info(methodhandles)("MH %s %s=" PTR_FORMAT " sp=(" PTR_FORMAT "+%zd) stack_size=%zd bp=" PTR_FORMAT, adaptername, mh_reg_name, mh_reg, (intptr_t)entry_sp, (intptr_t)saved_sp - (intptr_t)entry_sp, (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); diff --git a/src/hotspot/cpu/arm/nativeInst_arm_32.cpp b/src/hotspot/cpu/arm/nativeInst_arm_32.cpp index 6a4062f29b3ba..2caf2d7587e53 100644 --- a/src/hotspot/cpu/arm/nativeInst_arm_32.cpp +++ b/src/hotspot/cpu/arm/nativeInst_arm_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/codeCache.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/arm/register_arm.cpp b/src/hotspot/cpu/arm/register_arm.cpp index a0ae9ff4f92a9..ea3ef87e6708f 100644 --- a/src/hotspot/cpu/arm/register_arm.cpp +++ b/src/hotspot/cpu/arm/register_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "register_arm.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/arm/relocInfo_arm.cpp b/src/hotspot/cpu/arm/relocInfo_arm.cpp index fb112cdcfc0fa..2006be978bcdf 100644 --- a/src/hotspot/cpu/arm/relocInfo_arm.cpp +++ b/src/hotspot/cpu/arm/relocInfo_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/relocInfo.hpp" #include "nativeInst_arm.hpp" diff --git a/src/hotspot/cpu/arm/runtime_arm.cpp b/src/hotspot/cpu/arm/runtime_arm.cpp index cd76843d6dfef..cf4b398cf1fb9 100644 --- a/src/hotspot/cpu/arm/runtime_arm.cpp +++ b/src/hotspot/cpu/arm/runtime_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/assembler.inline.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp index 82e16836acb57..c63d72920a5b6 100644 --- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp +++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/debugInfoRec.hpp" diff --git a/src/hotspot/cpu/arm/stubDeclarations_arm.hpp b/src/hotspot/cpu/arm/stubDeclarations_arm.hpp new file mode 100644 index 0000000000000..35df4b924d276 --- /dev/null +++ b/src/hotspot/cpu/arm/stubDeclarations_arm.hpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_ARM_STUBDECLARATIONS_HPP +#define CPU_ARM_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 9000) \ + do_stub(initial, idiv_irem) \ + do_arch_entry(Arm, initial, idiv_irem, \ + idiv_irem_entry, idiv_irem_entry) \ + do_stub(initial, atomic_load_long) \ + do_arch_entry(Arm, initial, atomic_load_long, \ + atomic_load_long_entry, atomic_load_long_entry) \ + do_stub(initial, atomic_store_long) \ + do_arch_entry(Arm, initial, atomic_load_long, \ + atomic_store_long_entry, atomic_store_long_entry) \ + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 2000) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 22000) \ + do_stub(compiler, partial_subtype_check) \ + do_arch_entry(Arm, compiler, partial_subtype_check, \ + partial_subtype_check, partial_subtype_check) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 22000) \ + + +#endif // CPU_ARM_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp index 9b91e02cf07f2..aad81e7891d46 100644 --- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/barrierSet.hpp" @@ -173,7 +172,8 @@ class StubGenerator: public StubCodeGenerator { private: address generate_call_stub(address& return_address) { - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -252,7 +252,8 @@ class StubGenerator: public StubCodeGenerator { // (in) Rexception_obj: exception oop address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ str(Rexception_obj, Address(Rthread, Thread::pending_exception_offset())); @@ -264,7 +265,8 @@ class StubGenerator: public StubCodeGenerator { // (in) Rexception_pc: return address address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ mov(c_rarg0, Rthread); @@ -313,6 +315,8 @@ class StubGenerator: public StubCodeGenerator { Register tmp = LR; assert(dividend == remainder, "must be"); + StubGenStubId stub_id = StubGenStubId::idiv_irem_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Check for special cases: divisor <= 0 or dividend < 0 @@ -454,7 +458,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_add() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_add"); + StubGenStubId stub_id = StubGenStubId::atomic_add_id; + StubCodeMark mark(this, stub_id); Label retry; start = __ pc(); Register addval = R0; @@ -505,7 +510,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_xchg() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_xchg"); + StubGenStubId stub_id = StubGenStubId::atomic_xchg_id; + StubCodeMark mark(this, stub_id); start = __ pc(); Register newval = R0; Register dest = R1; @@ -555,7 +561,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_cmpxchg() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg"); + StubGenStubId stub_id = StubGenStubId::atomic_cmpxchg_id; + StubCodeMark mark(this, stub_id); start = __ pc(); Register cmp = R0; Register newval = R1; @@ -593,7 +600,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_cmpxchg_long() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long"); + StubGenStubId stub_id = StubGenStubId::atomic_cmpxchg_long_id; + StubCodeMark mark(this, stub_id); start = __ pc(); Register cmp_lo = R0; Register cmp_hi = R1; @@ -630,7 +638,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_load_long() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_load_long"); + StubGenStubId stub_id = StubGenStubId::atomic_load_long_id; + StubCodeMark mark(this, stub_id); start = __ pc(); Register result_lo = R0; Register result_hi = R1; @@ -654,7 +663,8 @@ class StubGenerator: public StubCodeGenerator { address generate_atomic_store_long() { address start; - StubCodeMark mark(this, "StubRoutines", "atomic_store_long"); + StubGenStubId stub_id = StubGenStubId::atomic_store_long_id; + StubCodeMark mark(this, stub_id); start = __ pc(); Register newval_lo = R0; Register newval_hi = R1; @@ -696,7 +706,8 @@ class StubGenerator: public StubCodeGenerator { // raddr: LR, blown by call address generate_partial_subtype_check() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "partial_subtype_check"); + StubGenStubId stub_id = StubGenStubId::partial_subtype_check_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // based on SPARC check_klass_subtype_[fast|slow]_path (without CompressedOops) @@ -785,7 +796,8 @@ class StubGenerator: public StubCodeGenerator { // Non-destructive plausibility checks for oops address generate_verify_oop() { - StubCodeMark mark(this, "StubRoutines", "verify_oop"); + StubGenStubId stub_id = StubGenStubId::verify_oop_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Incoming arguments: @@ -1986,6 +1998,23 @@ class StubGenerator: public StubCodeGenerator { return start_pc; } + /* Internal development flag */ + /* enabled by defining TEST_C2_GENERIC_ARRAYCOPY */ + + // With this flag, the C2 stubs are tested by generating calls to + // generic_arraycopy instead of Runtime1::arraycopy + + // Runtime1::arraycopy return a status in R0 (0 if OK, else ~copied) + // and the result is tested to see whether the arraycopy stub should + // be called. + + // When we test arraycopy this way, we must generate extra code in the + // arraycopy methods callable from C2 generic_arraycopy to set the + // status to 0 for those who always succeed (calling the slow path stub might + // lead to errors since the copy has already been performed). + + static const bool set_status; + // // Generate stub for primitive array copy. If "aligned" is true, the // "from" and "to" addresses are assumed to be heapword aligned. @@ -1998,9 +2027,109 @@ class StubGenerator: public StubCodeGenerator { // to: R1 // count: R2 treated as signed 32-bit int // - address generate_primitive_copy(bool aligned, const char * name, bool status, int bytes_per_count, bool disjoint, address nooverlap_target = nullptr) { + address generate_primitive_copy(StubGenStubId stub_id, address nooverlap_target = nullptr) { + bool aligned; + bool status; + int bytes_per_count; + bool disjoint; + + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 1; + disjoint = true; + break; + case jshort_disjoint_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 2; + disjoint = true; + break; + case jint_disjoint_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 4; + disjoint = true; + break; + case jlong_disjoint_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 8; + disjoint = true; + break; + case arrayof_jbyte_disjoint_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 1; + disjoint = true; + break; + case arrayof_jshort_disjoint_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 2; + disjoint = true; + break; + case arrayof_jint_disjoint_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 4; + disjoint = true; + break; + case arrayof_jlong_disjoint_arraycopy_id: + aligned = false; + status = set_status; + bytes_per_count = 8; + disjoint = true; + break; + case jbyte_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 1; + disjoint = false; + break; + case jshort_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 2; + disjoint = false; + break; + case jint_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 4; + disjoint = false; + break; + case jlong_arraycopy_id: + aligned = false; + status = true; + bytes_per_count = 8; + disjoint = false; + break; + case arrayof_jbyte_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 1; + disjoint = false; + break; + case arrayof_jshort_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 2; + disjoint = false; + break; + case arrayof_jint_arraycopy_id: + aligned = true; + status = set_status; + bytes_per_count = 4; + disjoint = false; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = R0; // source array address @@ -2172,9 +2301,38 @@ class StubGenerator: public StubCodeGenerator { // to: R1 // count: R2 treated as signed 32-bit int // - address generate_oop_copy(bool aligned, const char * name, bool status, bool disjoint, address nooverlap_target = nullptr) { + address generate_oop_copy(StubGenStubId stub_id, address nooverlap_target = nullptr) { + bool aligned; + bool status; + bool disjoint; + + switch (stub_id) { + case oop_disjoint_arraycopy_id: + aligned = false; + status = true; + disjoint = true; + break; + case arrayof_oop_disjoint_arraycopy_id: + aligned = true; + status = set_status; + disjoint = true; + break; + case oop_arraycopy_id: + aligned = false; + status = true; + disjoint = false; + break; + case arrayof_oop_arraycopy_id: + aligned = true; + status = set_status; + disjoint = false; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register from = R0; @@ -2309,7 +2467,7 @@ class StubGenerator: public StubCodeGenerator { // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // - address generate_unsafe_copy(const char* name) { + address generate_unsafe_copy() { const Register R0_from = R0; // source array address const Register R1_to = R1; // destination array address @@ -2318,7 +2476,8 @@ class StubGenerator: public StubCodeGenerator { const Register R3_bits = R3; // test copy of low bits __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register tmp = Rtemp; @@ -2443,9 +2602,10 @@ class StubGenerator: public StubCodeGenerator { // ckval: R4 (super_klass) // ret: R0 zero for success; (-1^K) where K is partial transfer count (32-bit) // - address generate_checkcast_copy(const char * name) { + address generate_checkcast_copy() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::checkcast_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = R0; // source array address @@ -2596,7 +2756,7 @@ class StubGenerator: public StubCodeGenerator { // R0 == 0 - success // R0 < 0 - need to call System.arraycopy // - address generate_generic_copy(const char *name) { + address generate_generic_copy() { Label L_failed, L_objArray; // Input registers @@ -2612,7 +2772,8 @@ class StubGenerator: public StubCodeGenerator { const Register R8_temp = R8; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ zap_high_non_significant_bits(R1); @@ -2843,72 +3004,55 @@ class StubGenerator: public StubCodeGenerator { // Note: the disjoint stubs must be generated first, some of // the conjoint stubs use them. - bool status = false; // non failing C2 stubs need not return a status in R0 - -#ifdef TEST_C2_GENERIC_ARRAYCOPY /* Internal development flag */ - // With this flag, the C2 stubs are tested by generating calls to - // generic_arraycopy instead of Runtime1::arraycopy - - // Runtime1::arraycopy return a status in R0 (0 if OK, else ~copied) - // and the result is tested to see whether the arraycopy stub should - // be called. - - // When we test arraycopy this way, we must generate extra code in the - // arraycopy methods callable from C2 generic_arraycopy to set the - // status to 0 for those who always succeed (calling the slow path stub might - // lead to errors since the copy has already been performed). - - status = true; // generate a status compatible with C1 calls -#endif - address ucm_common_error_exit = generate_unsafecopy_common_error_exit(); UnsafeMemoryAccess::set_common_exit_stub_pc(ucm_common_error_exit); // these need always status in case they are called from generic_arraycopy - StubRoutines::_jbyte_disjoint_arraycopy = generate_primitive_copy(false, "jbyte_disjoint_arraycopy", true, 1, true); - StubRoutines::_jshort_disjoint_arraycopy = generate_primitive_copy(false, "jshort_disjoint_arraycopy", true, 2, true); - StubRoutines::_jint_disjoint_arraycopy = generate_primitive_copy(false, "jint_disjoint_arraycopy", true, 4, true); - StubRoutines::_jlong_disjoint_arraycopy = generate_primitive_copy(false, "jlong_disjoint_arraycopy", true, 8, true); - StubRoutines::_oop_disjoint_arraycopy = generate_oop_copy (false, "oop_disjoint_arraycopy", true, true); - - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_primitive_copy(true, "arrayof_jbyte_disjoint_arraycopy", status, 1, true); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_primitive_copy(true, "arrayof_jshort_disjoint_arraycopy",status, 2, true); - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_primitive_copy(true, "arrayof_jint_disjoint_arraycopy", status, 4, true); - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_primitive_copy(true, "arrayof_jlong_disjoint_arraycopy", status, 8, true); - StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_oop_copy (true, "arrayof_oop_disjoint_arraycopy", status, true); + StubRoutines::_jbyte_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::jbyte_disjoint_arraycopy_id); + StubRoutines::_jshort_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::jshort_disjoint_arraycopy_id); + StubRoutines::_jint_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::jint_disjoint_arraycopy_id); + StubRoutines::_jlong_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::jlong_disjoint_arraycopy_id); + StubRoutines::_oop_disjoint_arraycopy = generate_oop_copy (StubGenStubId::oop_disjoint_arraycopy_id); + + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id); + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jint_disjoint_arraycopy_id); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jlong_disjoint_arraycopy_id); + StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_oop_copy (StubGenStubId::arrayof_oop_disjoint_arraycopy_id); // these need always status in case they are called from generic_arraycopy - StubRoutines::_jbyte_arraycopy = generate_primitive_copy(false, "jbyte_arraycopy", true, 1, false, StubRoutines::_jbyte_disjoint_arraycopy); - StubRoutines::_jshort_arraycopy = generate_primitive_copy(false, "jshort_arraycopy", true, 2, false, StubRoutines::_jshort_disjoint_arraycopy); - StubRoutines::_jint_arraycopy = generate_primitive_copy(false, "jint_arraycopy", true, 4, false, StubRoutines::_jint_disjoint_arraycopy); - StubRoutines::_jlong_arraycopy = generate_primitive_copy(false, "jlong_arraycopy", true, 8, false, StubRoutines::_jlong_disjoint_arraycopy); - StubRoutines::_oop_arraycopy = generate_oop_copy (false, "oop_arraycopy", true, false, StubRoutines::_oop_disjoint_arraycopy); - - StubRoutines::_arrayof_jbyte_arraycopy = generate_primitive_copy(true, "arrayof_jbyte_arraycopy", status, 1, false, StubRoutines::_arrayof_jbyte_disjoint_arraycopy); - StubRoutines::_arrayof_jshort_arraycopy = generate_primitive_copy(true, "arrayof_jshort_arraycopy", status, 2, false, StubRoutines::_arrayof_jshort_disjoint_arraycopy); + StubRoutines::_jbyte_arraycopy = generate_primitive_copy(StubGenStubId::jbyte_arraycopy_id, StubRoutines::_jbyte_disjoint_arraycopy); + StubRoutines::_jshort_arraycopy = generate_primitive_copy(StubGenStubId::jshort_arraycopy_id, StubRoutines::_jshort_disjoint_arraycopy); + StubRoutines::_jint_arraycopy = generate_primitive_copy(StubGenStubId::jint_arraycopy_id, StubRoutines::_jint_disjoint_arraycopy); + StubRoutines::_jlong_arraycopy = generate_primitive_copy(StubGenStubId::jlong_arraycopy_id, StubRoutines::_jlong_disjoint_arraycopy); + StubRoutines::_oop_arraycopy = generate_oop_copy (StubGenStubId::oop_arraycopy_id, StubRoutines::_oop_disjoint_arraycopy); + + StubRoutines::_arrayof_jbyte_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jbyte_arraycopy_id, StubRoutines::_arrayof_jbyte_disjoint_arraycopy); + StubRoutines::_arrayof_jshort_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jshort_arraycopy_id, StubRoutines::_arrayof_jshort_disjoint_arraycopy); #ifdef _LP64 // since sizeof(jint) < sizeof(HeapWord), there's a different flavor: - StubRoutines::_arrayof_jint_arraycopy = generate_primitive_copy(true, "arrayof_jint_arraycopy", status, 4, false, StubRoutines::_arrayof_jint_disjoint_arraycopy); + StubRoutines::_arrayof_jint_arraycopy = generate_primitive_copy(StubGenStubId::arrayof_jint_arraycopy_id, StubRoutines::_arrayof_jint_disjoint_arraycopy); #else StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy; #endif if (BytesPerHeapOop < HeapWordSize) { - StubRoutines::_arrayof_oop_arraycopy = generate_oop_copy (true, "arrayof_oop_arraycopy", status, false, StubRoutines::_arrayof_oop_disjoint_arraycopy); + StubRoutines::_arrayof_oop_arraycopy = generate_oop_copy (StubGenStubId::arrayof_oop_arraycopy_id, StubRoutines::_arrayof_oop_disjoint_arraycopy); } else { StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; } StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy; - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy"); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy"); - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy"); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(); + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(); + StubRoutines::_generic_arraycopy = generate_generic_copy(); } address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); Label deoptimize_label; @@ -2961,22 +3105,22 @@ class StubGenerator: public StubCodeGenerator { #undef __ #define __ masm-> - address generate_cont_thaw(const char* label, Continuation::thaw_kind kind) { + address generate_cont_thaw(StubGenStubId stub_id) { if (!Continuations::enabled()) return nullptr; Unimplemented(); return nullptr; } address generate_cont_thaw() { - return generate_cont_thaw("Cont thaw", Continuation::thaw_top); + return generate_cont_thaw(StubGenStubId::cont_thaw_id); } address generate_cont_returnBarrier() { - return generate_cont_thaw("Cont thaw return barrier", Continuation::thaw_return_barrier); + return generate_cont_thaw(StubGenStubId::cont_returnBarrier_id); } address generate_cont_returnBarrier_exception() { - return generate_cont_thaw("Cont thaw return barrier exception", Continuation::thaw_return_barrier_exception); + return generate_cont_thaw(StubGenStubId::cont_returnBarrierExc_id); } //--------------------------------------------------------------------------- @@ -3008,8 +3152,8 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_atomic_xchg_entry = generate_atomic_xchg(); StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg(); StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); - StubRoutines::_atomic_load_long_entry = generate_atomic_load_long(); - StubRoutines::_atomic_store_long_entry = generate_atomic_store_long(); + StubRoutines::Arm::_atomic_load_long_entry = generate_atomic_load_long(); + StubRoutines::Arm::_atomic_store_long_entry = generate_atomic_store_long(); } @@ -3059,27 +3203,36 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } + +// implementation of internal development flag + +#ifdef TEST_C2_GENERIC_ARRAYCOPY +const bool StubGenerator::set_status = true; // generate a status compatible with C1 calls +#else +const bool StubGenerator::set_status = false; // non failing C2 stubs need not return a status in R0 +#endif + diff --git a/src/hotspot/cpu/arm/stubRoutinesCrypto_arm.cpp b/src/hotspot/cpu/arm/stubRoutinesCrypto_arm.cpp index 350636fbe93e1..b663cfd92989d 100644 --- a/src/hotspot/cpu/arm/stubRoutinesCrypto_arm.cpp +++ b/src/hotspot/cpu/arm/stubRoutinesCrypto_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -119,7 +119,8 @@ void aes_init() { address generate_aescrypt_encryptBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aesencryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -316,7 +317,8 @@ address generate_aescrypt_encryptBlock() { address generate_aescrypt_decryptBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aesdecryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -536,7 +538,8 @@ address generate_cipherBlockChaining_encryptAESCrypt() { // [sp+4] Transposition Box reference __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -601,7 +604,8 @@ address generate_cipherBlockChaining_encryptAESCrypt() { address generate_cipherBlockChaining_decryptAESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); diff --git a/src/hotspot/cpu/arm/stubRoutines_arm.cpp b/src/hotspot/cpu/arm/stubRoutines_arm.cpp index 0cd174d8da673..d843d89186ea1 100644 --- a/src/hotspot/cpu/arm/stubRoutines_arm.cpp +++ b/src/hotspot/cpu/arm/stubRoutines_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,14 +22,17 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/stubRoutines.hpp" -address StubRoutines::Arm::_idiv_irem_entry = nullptr; +#define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr; -address StubRoutines::Arm::_partial_subtype_check = nullptr; +#define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function); -address StubRoutines::_atomic_load_long_entry = nullptr; -address StubRoutines::_atomic_store_long_entry = nullptr; +STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) + +#undef DEFINE_ARCH_ENTRY_INIT +#undef DEFINE_ARCH_ENTRY diff --git a/src/hotspot/cpu/arm/stubRoutines_arm.hpp b/src/hotspot/cpu/arm/stubRoutines_arm.hpp index 05c82881cd5f6..838b3e6d3782f 100644 --- a/src/hotspot/cpu/arm/stubRoutines_arm.hpp +++ b/src/hotspot/cpu/arm/stubRoutines_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,38 +29,53 @@ // definition. See stubRoutines.hpp for a description on how to // extend it. +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + enum platform_dependent_constants { - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 9000, - _continuation_stubs_code_size = 2000, - _compiler_stubs_code_size = 22000, - _final_stubs_code_size = 22000 + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + +public: + static bool returns_to_call_stub(address return_pc) { + return return_pc == _call_stub_return_address; + } + class Arm { friend class StubGenerator; friend class VMStructs; - private: +#define DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + static address STUB_FIELD_NAME(field_name) ; - static address _idiv_irem_entry; - static address _partial_subtype_check; +#define DECLARE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) - public: +private: + STUBGEN_ARCH_ENTRIES_DO(DECLARE_ARCH_ENTRY, DECLARE_ARCH_ENTRY_INIT) - static address idiv_irem_entry() { return _idiv_irem_entry; } - static address partial_subtype_check() { return _partial_subtype_check; } -}; +#undef DECLARE_ARCH_ENTRY_INIT +#undef DECLARE_ARCH_ENTRY - static bool returns_to_call_stub(address return_pc) { - return return_pc == _call_stub_return_address; - } +public: + + // declare getters for arch-specific entries - static address _atomic_load_long_entry; - static address _atomic_store_long_entry; +#define DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) \ + static address getter_name() { return STUB_FIELD_NAME(field_name) ; } - static address atomic_load_long_entry() { return _atomic_load_long_entry; } - static address atomic_store_long_entry() { return _atomic_store_long_entry; } +#define DEFINE_ARCH_ENTRY_GETTER_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) + STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY_GETTER, DEFINE_ARCH_ENTRY_GETTER_INIT) + +#undef DEFINE_ARCH_ENTRY_GETTER_INIT +#undef DEFINE_ARCH_ENTRY_GETTER + +}; #endif // CPU_ARM_STUBROUTINES_ARM_HPP diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index 9df7a455eeb84..3f1cd1e23de8c 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" @@ -579,7 +578,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbnz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method doesn't need synchronization"); __ bind(L); @@ -588,7 +587,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tst(Rtemp, JVM_ACC_STATIC); __ ldr(R0, Address(Rlocals, Interpreter::local_offset_in_bytes(0)), eq); // get receiver (assume this is frequent case) __ b(done, eq); @@ -851,7 +850,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbnz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -893,7 +892,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); @@ -975,7 +974,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass JNIEnv and mirror for static methods { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ add(R0, Rthread, in_bytes(JavaThread::jni_environment_offset())); __ tbz(Rtemp, JVM_ACC_STATIC_BIT, L); __ load_mirror(Rtemp, Rmethod, Rtemp); @@ -1204,7 +1203,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); { Label L; __ tbz(Rtemp, JVM_ACC_NATIVE_BIT, L); @@ -1249,7 +1248,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // no synchronization necessary #ifdef ASSERT { Label L; - __ ldr_u32(Rtemp, Address(Rmethod, Method::access_flags_offset())); + __ ldrh(Rtemp, Address(Rmethod, Method::access_flags_offset())); __ tbz(Rtemp, JVM_ACC_SYNCHRONIZED_BIT, L); __ stop("method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp index 0974ff1f9a9c3..bbe5713090af5 100644 --- a/src/hotspot/cpu/arm/templateTable_arm.cpp +++ b/src/hotspot/cpu/arm/templateTable_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/collectedHeap.hpp" diff --git a/src/hotspot/cpu/arm/upcallLinker_arm.cpp b/src/hotspot/cpu/arm/upcallLinker_arm.cpp index 696b2001e6b7b..532ff7be8bc31 100644 --- a/src/hotspot/cpu/arm/upcallLinker_arm.cpp +++ b/src/hotspot/cpu/arm/upcallLinker_arm.cpp @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/upcallLinker.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/arm/vm_version_arm_32.cpp b/src/hotspot/cpu/arm/vm_version_arm_32.cpp index d3ba352f78b15..148786a55da41 100644 --- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "jvm.h" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/arm/vmreg_arm.cpp b/src/hotspot/cpu/arm/vmreg_arm.cpp index c7c972db5c9b6..4ce1dd0be20f5 100644 --- a/src/hotspot/cpu/arm/vmreg_arm.cpp +++ b/src/hotspot/cpu/arm/vmreg_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/arm/vtableStubs_arm.cpp b/src/hotspot/cpu/arm/vtableStubs_arm.cpp index 8f453558848b5..2d7ccd1969b0d 100644 --- a/src/hotspot/cpu/arm/vtableStubs_arm.cpp +++ b/src/hotspot/cpu/arm/vtableStubs_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp index 56f8fce5ce926..cc094ad4f995b 100644 --- a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp +++ b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "oops/constMethod.hpp" #include "oops/klass.inline.hpp" diff --git a/src/hotspot/cpu/ppc/assembler_ppc.cpp b/src/hotspot/cpu/ppc/assembler_ppc.cpp index 40c69dd290280..ab16fc437e9e1 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/collectedHeap.inline.hpp" @@ -563,20 +562,20 @@ void Assembler::test_asm() { li( R3, -4711); // PPC 1, section 3.3.9, Fixed-Point Compare Instructions - cmpi( CCR7, 0, R27, 4711); - cmp( CCR0, 1, R14, R11); - cmpli( CCR5, 1, R17, 45); - cmpl( CCR3, 0, R9, R10); + cmpi( CR7, 0, R27, 4711); + cmp( CR0, 1, R14, R11); + cmpli( CR5, 1, R17, 45); + cmpl( CR3, 0, R9, R10); - cmpwi( CCR7, R27, 4711); - cmpw( CCR0, R14, R11); - cmplwi( CCR5, R17, 45); - cmplw( CCR3, R9, R10); + cmpwi( CR7, R27, 4711); + cmpw( CR0, R14, R11); + cmplwi( CR5, R17, 45); + cmplw( CR3, R9, R10); - cmpdi( CCR7, R27, 4711); - cmpd( CCR0, R14, R11); - cmpldi( CCR5, R17, 45); - cmpld( CCR3, R9, R10); + cmpdi( CR7, R27, 4711); + cmpd( CR0, R14, R11); + cmpldi( CR5, R17, 45); + cmpld( CR3, R9, R10); // PPC 1, section 3.3.11, Fixed-Point Logical Instructions andi_( R4, R5, 0xff); @@ -716,23 +715,23 @@ void Assembler::test_asm() { bcctr( 4, 6, 0); bcctrl(4, 6, 0); - blt(CCR0, lbl2); - bgt(CCR1, lbl2); - beq(CCR2, lbl2); - bso(CCR3, lbl2); - bge(CCR4, lbl2); - ble(CCR5, lbl2); - bne(CCR6, lbl2); - bns(CCR7, lbl2); - - bltl(CCR0, lbl2); - bgtl(CCR1, lbl2); - beql(CCR2, lbl2); - bsol(CCR3, lbl2); - bgel(CCR4, lbl2); - blel(CCR5, lbl2); - bnel(CCR6, lbl2); - bnsl(CCR7, lbl2); + blt(CR0, lbl2); + bgt(CR1, lbl2); + beq(CR2, lbl2); + bso(CR3, lbl2); + bge(CR4, lbl2); + ble(CR5, lbl2); + bne(CR6, lbl2); + bns(CR7, lbl2); + + bltl(CR0, lbl2); + bgtl(CR1, lbl2); + beql(CR2, lbl2); + bsol(CR3, lbl2); + bgel(CR4, lbl2); + blel(CR5, lbl2); + bnel(CR6, lbl2); + bnsl(CR7, lbl2); blr(); sync(); @@ -795,7 +794,7 @@ void Assembler::test_asm() { fcfid( F22, F23); // PPC 1, section 4.6.7 Floating-Point Compare Instructions - fcmpu( CCR7, F24, F25); + fcmpu( CR7, F24, F25); tty->print_cr("\ntest_asm disassembly (0x%lx 0x%lx):", p2i(code()->insts_begin()), p2i(code()->insts_end())); code()->decode(); diff --git a/src/hotspot/cpu/ppc/assembler_ppc.hpp b/src/hotspot/cpu/ppc/assembler_ppc.hpp index 68a0c78e7cfb3..11532edaad9ce 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp @@ -294,6 +294,8 @@ class Assembler : public AbstractAssembler { CLRRWI_OPCODE = RLWINM_OPCODE, CLRLWI_OPCODE = RLWINM_OPCODE, + RLWNM_OPCODE = (23u << OPCODE_SHIFT), + RLWIMI_OPCODE = (20u << OPCODE_SHIFT), SLW_OPCODE = (31u << OPCODE_SHIFT | 24u << 1), @@ -424,6 +426,9 @@ class Assembler : public AbstractAssembler { RLDIC_OPCODE = (30u << OPCODE_SHIFT | 2u << XO_27_29_SHIFT), // MD-FORM RLDIMI_OPCODE = (30u << OPCODE_SHIFT | 3u << XO_27_29_SHIFT), // MD-FORM + RLDCL_OPCODE = (30u << OPCODE_SHIFT | 8u << 1), + RLDCR_OPCODE = (30u << OPCODE_SHIFT | 9u << 1), + SRADI_OPCODE = (31u << OPCODE_SHIFT | 413u << XO_21_29_SHIFT), // XS-FORM SLD_OPCODE = (31u << OPCODE_SHIFT | 27u << 1), // X-FORM @@ -1696,6 +1701,14 @@ class Assembler : public AbstractAssembler { inline void insrdi( Register a, Register s, int n, int b); inline void insrwi( Register a, Register s, int n, int b); + // Rotate variable + inline void rlwnm( Register a, Register s, Register b, int mb, int me); + inline void rlwnm_(Register a, Register s, Register b, int mb, int me); + inline void rldcl( Register a, Register s, Register b, int mb); + inline void rldcl_(Register a, Register s, Register b, int mb); + inline void rldcr( Register a, Register s, Register b, int me); + inline void rldcr_(Register a, Register s, Register b, int me); + // PPC 1, section 3.3.2 Fixed-Point Load Instructions // 4 bytes inline void lwzx( Register d, Register s1, Register s2); diff --git a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp index eae75da9fbff3..ab026d356628b 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -246,9 +246,9 @@ inline void Assembler::nop() { Assembler::ori(R0, R // NOP for FP and BR units (different versions to allow them to be in one group) inline void Assembler::fpnop0() { Assembler::fmr(F30, F30); } inline void Assembler::fpnop1() { Assembler::fmr(F31, F31); } -inline void Assembler::brnop0() { Assembler::mcrf(CCR2, CCR2); } -inline void Assembler::brnop1() { Assembler::mcrf(CCR3, CCR3); } -inline void Assembler::brnop2() { Assembler::mcrf(CCR4, CCR4); } +inline void Assembler::brnop0() { Assembler::mcrf(CR2, CR2); } +inline void Assembler::brnop1() { Assembler::mcrf(CR3, CR3); } +inline void Assembler::brnop2() { Assembler::mcrf(CR4, CR4); } inline void Assembler::mr( Register d, Register s) { Assembler::orr(d, s, s); } inline void Assembler::ori_opt( Register d, int ui16) { if (ui16!=0) Assembler::ori( d, d, ui16); } @@ -303,7 +303,7 @@ inline void Assembler::clrlsldi_(Register a, Register s, int clrl6, int shl6) { inline void Assembler::extrdi( Register a, Register s, int n, int b){ Assembler::rldicl(a, s, b+n, 64-n); } // testbit with condition register. inline void Assembler::testbitdi(ConditionRegister cr, Register a, Register s, int ui6) { - if (cr == CCR0) { + if (cr == CR0) { Assembler::rldicr_(a, s, 63-ui6, 0); } else { Assembler::rldicr(a, s, 63-ui6, 0); @@ -336,6 +336,13 @@ inline void Assembler::rldimi_( Register a, Register s, int sh6, int mb6) inline void Assembler::insrdi( Register a, Register s, int n, int b) { Assembler::rldimi(a, s, 64-(b+n), b); } inline void Assembler::insrwi( Register a, Register s, int n, int b) { Assembler::rlwimi(a, s, 32-(b+n), b, b+n-1); } +inline void Assembler::rlwnm( Register a, Register s, Register b, int mb, int me) { emit_int32(RLWNM_OPCODE | rta(a) | rs(s) | rb(b) | mb2125(mb) | me2630(me) | rc(0)); } +inline void Assembler::rlwnm_(Register a, Register s, Register b, int mb, int me) { emit_int32(RLWNM_OPCODE | rta(a) | rs(s) | rb(b) | mb2125(mb) | me2630(me) | rc(1)); } +inline void Assembler::rldcl( Register a, Register s, Register b, int mb) { emit_int32(RLDCL_OPCODE | rta(a) | rs(s) | rb(b) | mb2126(mb) | rc(0)); } +inline void Assembler::rldcl_( Register a, Register s, Register b, int mb) { emit_int32(RLDCL_OPCODE | rta(a) | rs(s) | rb(b) | mb2126(mb) | rc(1)); } +inline void Assembler::rldcr( Register a, Register s, Register b, int me) { emit_int32(RLDCR_OPCODE | rta(a) | rs(s) | rb(b) | me2126(me) | rc(0)); } +inline void Assembler::rldcr_( Register a, Register s, Register b, int me) { emit_int32(RLDCR_OPCODE | rta(a) | rs(s) | rb(b) | me2126(me) | rc(1)); } + // PPC 1, section 3.3.2 Fixed-Point Load Instructions inline void Assembler::lwzx( Register d, Register s1, Register s2) { emit_int32(LWZX_OPCODE | rt(d) | ra0mem(s1) | rb(s2));} inline void Assembler::lwz( Register d, Address &a) { diff --git a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp index 4d3927dc644b8..d4f5faa29a869 100644 --- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" @@ -368,9 +367,9 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { __ mr(R0, _obj); // spill __ ld(_obj, java_lang_Class::klass_offset(), _obj); __ ld(_obj, in_bytes(InstanceKlass::init_thread_offset()), _obj); - __ cmpd(CCR0, _obj, R16_thread); + __ cmpd(CR0, _obj, R16_thread); __ mr(_obj, R0); // restore - __ bne(CCR0, call_patch); + __ bne(CR0, call_patch); // Load_klass patches may execute the patched code before it's // copied back into place so we need to jump back into the main diff --git a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp index a776dbcc4ef58..e4684613e2589 100644 --- a/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_FrameMap_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index af426935b2f2b..cae192982d56e 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_LIRAssembler.hpp" @@ -49,7 +48,7 @@ #define __ _masm-> -const ConditionRegister LIR_Assembler::BOOL_RESULT = CCR5; +const ConditionRegister LIR_Assembler::BOOL_RESULT = CR5; bool LIR_Assembler::is_small_constant(LIR_Opr opr) { @@ -157,8 +156,8 @@ void LIR_Assembler::osr_entry() { { Label L; __ ld(R0, slot_offset + 1*BytesPerWord, OSR_buf); - __ cmpdi(CCR0, R0, 0); - __ bne(CCR0, L); + __ cmpdi(CR0, R0, 0); + __ bne(CR0, L); __ stop("locked object is null"); __ bind(L); } @@ -411,11 +410,11 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, Label regular, done; if (is_int) { - __ cmpwi(CCR0, Rdivisor, -1); + __ cmpwi(CR0, Rdivisor, -1); } else { - __ cmpdi(CCR0, Rdivisor, -1); + __ cmpdi(CR0, Rdivisor, -1); } - __ bne(CCR0, regular); + __ bne(CR0, regular); if (code == lir_idiv) { __ neg(Rresult, Rdividend); __ b(done); @@ -598,14 +597,14 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { Address addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : Address(); Label L; // Result must be 0 if value is NaN; test by comparing value to itself. - __ fcmpu(CCR0, rsrc, rsrc); + __ fcmpu(CR0, rsrc, rsrc); if (dst_in_memory) { __ li(R0, 0); // 0 in case of NAN __ std(R0, addr); } else { __ li(dst->as_register(), 0); } - __ bso(CCR0, L); + __ bso(CR0, L); __ fctiwz(rsrc, rsrc); // USE_KILL if (dst_in_memory) { __ stfd(rsrc, addr.disp(), addr.base()); @@ -622,14 +621,14 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { Address addr = dst_in_memory ? frame_map()->address_for_slot(dst->double_stack_ix()) : Address(); Label L; // Result must be 0 if value is NaN; test by comparing value to itself. - __ fcmpu(CCR0, rsrc, rsrc); + __ fcmpu(CR0, rsrc, rsrc); if (dst_in_memory) { __ li(R0, 0); // 0 in case of NAN __ std(R0, addr); } else { __ li(dst->as_register_lo(), 0); } - __ bso(CCR0, L); + __ bso(CR0, L); __ fctidz(rsrc, rsrc); // USE_KILL if (dst_in_memory) { __ stfd(rsrc, addr.disp(), addr.base()); @@ -1531,15 +1530,15 @@ void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Op if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) { bool is_unordered_less = (code == lir_ucmp_fd2i); if (left->is_single_fpu()) { - __ fcmpu(CCR0, left->as_float_reg(), right->as_float_reg()); + __ fcmpu(CR0, left->as_float_reg(), right->as_float_reg()); } else if (left->is_double_fpu()) { - __ fcmpu(CCR0, left->as_double_reg(), right->as_double_reg()); + __ fcmpu(CR0, left->as_double_reg(), right->as_double_reg()); } else { ShouldNotReachHere(); } __ set_cmpu3(Rdst, is_unordered_less); // is_unordered_less ? -1 : 1 } else if (code == lir_cmp_l2i) { - __ cmpd(CCR0, left->as_register_lo(), right->as_register_lo()); + __ cmpd(CR0, left->as_register_lo(), right->as_register_lo()); __ set_cmp3(Rdst); // set result as follows: <: -1, =: 0, >: 1 } else { ShouldNotReachHere(); @@ -1894,8 +1893,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ add(src_pos, tmp, src_pos); __ add(dst_pos, tmp, dst_pos); - __ cmpwi(CCR0, R3_RET, 0); - __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::less), *stub->entry()); + __ cmpwi(CR0, R3_RET, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::less), *stub->entry()); __ bind(*stub->continuation()); return; } @@ -1911,12 +1910,12 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // Use only one conditional branch for simple checks. if (simple_check_flag_set) { - ConditionRegister combined_check = CCR1, tmp_check = CCR1; + ConditionRegister combined_check = CR1, tmp_check = CR1; // Make sure src and dst are non-null. if (flags & LIR_OpArrayCopy::src_null_check) { __ cmpdi(combined_check, src, 0); - tmp_check = CCR0; + tmp_check = CR0; } if (flags & LIR_OpArrayCopy::dst_null_check) { @@ -1924,13 +1923,13 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { if (tmp_check != combined_check) { __ cror(combined_check, Assembler::equal, tmp_check, Assembler::equal); } - tmp_check = CCR0; + tmp_check = CR0; } // Clear combined_check.eq if not already used. if (tmp_check == combined_check) { __ crandc(combined_check, Assembler::equal, combined_check, Assembler::equal); - tmp_check = CCR0; + tmp_check = CR0; } if (flags & LIR_OpArrayCopy::src_pos_positive_check) { @@ -1961,15 +1960,15 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { if (!(flags & LIR_OpArrayCopy::dst_objarray)) { __ load_klass(tmp, dst); __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp); - __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value); - __ bge(CCR0, slow); + __ cmpwi(CR0, tmp2, Klass::_lh_neutral_value); + __ bge(CR0, slow); } if (!(flags & LIR_OpArrayCopy::src_objarray)) { __ load_klass(tmp, src); __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp); - __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value); - __ bge(CCR0, slow); + __ cmpwi(CR0, tmp2, Klass::_lh_neutral_value); + __ bge(CR0, slow); } } @@ -1980,16 +1979,16 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { if (flags & LIR_OpArrayCopy::src_range_check) { __ lwz(tmp2, arrayOopDesc::length_offset_in_bytes(), src); __ add(tmp, length, src_pos); - __ cmpld(CCR0, tmp2, tmp); - __ ble(CCR0, slow); + __ cmpld(CR0, tmp2, tmp); + __ ble(CR0, slow); } __ extsw(dst_pos, dst_pos); if (flags & LIR_OpArrayCopy::dst_range_check) { __ lwz(tmp2, arrayOopDesc::length_offset_in_bytes(), dst); __ add(tmp, length, dst_pos); - __ cmpld(CCR0, tmp2, tmp); - __ ble(CCR0, slow); + __ cmpld(CR0, tmp2, tmp); + __ ble(CR0, slow); } int shift = shift_amount(basic_type); @@ -2004,8 +2003,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // We don't know the array types are compatible. if (basic_type != T_OBJECT) { // Simple test for basic type arrays. - __ cmp_klasses_from_objects(CCR0, src, dst, tmp, tmp2); - __ beq(CCR0, cont); + __ cmp_klasses_from_objects(CR0, src, dst, tmp, tmp2); + __ beq(CR0, cont); } else { // For object arrays, if src is a sub class of dst then we can // safely do the copy. @@ -2025,7 +2024,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ calculate_address_from_global_toc(tmp, slow_stc, true, true, false); __ mtctr(tmp); __ bctrl(); // sets CR0 - __ beq(CCR0, cont); + __ beq(CR0, cont); if (copyfunc_addr != nullptr) { // Use stub if available. __ bind(copyfunc); @@ -2045,8 +2044,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { jint objArray_lh = Klass::array_layout_helper(T_OBJECT); __ load_const_optimized(tmp, objArray_lh); - __ cmpw(CCR0, tmp, tmp2); - __ bne(CCR0, slow); + __ cmpw(CR0, tmp, tmp2); + __ bne(CR0, slow); } Register src_ptr = R3_ARG1; @@ -2081,8 +2080,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { #ifndef PRODUCT if (PrintC1Statistics) { Label failed; - __ cmpwi(CCR0, R3_RET, 0); - __ bne(CCR0, failed); + __ cmpwi(CR0, R3_RET, 0); + __ bne(CR0, failed); address counter = (address)&Runtime1::_arraycopy_checkcast_cnt; int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); __ lwz(R11_scratch1, simm16_offs, tmp); @@ -2093,8 +2092,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { #endif __ nand(tmp, R3_RET, R3_RET); - __ cmpwi(CCR0, R3_RET, 0); - __ beq(CCR0, *stub->continuation()); + __ cmpwi(CR0, R3_RET, 0); + __ beq(CR0, *stub->continuation()); #ifndef PRODUCT if (PrintC1Statistics) { @@ -2127,15 +2126,15 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // but not necessarily exactly of type default_type. Label known_ok, halt; metadata2reg(default_type->constant_encoding(), tmp); - __ cmp_klass(CCR0, dst, tmp, R11_scratch1, R12_scratch2); + __ cmp_klass(CR0, dst, tmp, R11_scratch1, R12_scratch2); if (basic_type != T_OBJECT) { - __ bne(CCR0, halt); - __ cmp_klass(CCR0, src, tmp, R11_scratch1, R12_scratch2); - __ beq(CCR0, known_ok); + __ bne(CR0, halt); + __ cmp_klass(CR0, src, tmp, R11_scratch1, R12_scratch2); + __ beq(CR0, known_ok); } else { - __ beq(CCR0, known_ok); - __ cmpw(CCR0, src, dst); - __ beq(CCR0, known_ok); + __ beq(CR0, known_ok); + __ cmpw(CR0, src, dst); + __ beq(CR0, known_ok); } __ bind(halt); __ stop("incorrect type information in arraycopy"); @@ -2270,8 +2269,8 @@ void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { __ lbz(op->tmp1()->as_register(), in_bytes(InstanceKlass::init_state_offset()), op->klass()->as_register()); // acquire barrier included in membar_storestore() which follows the allocation immediately. - __ cmpwi(CCR0, op->tmp1()->as_register(), InstanceKlass::fully_initialized); - __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CCR0, Assembler::equal), *op->stub()->entry()); + __ cmpwi(CR0, op->tmp1()->as_register(), InstanceKlass::fully_initialized); + __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CR0, Assembler::equal), *op->stub()->entry()); } __ allocate_object(op->obj()->as_register(), op->tmp1()->as_register(), @@ -2318,8 +2317,8 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias, // See if the receiver is receiver[n]. __ ld(tmp1, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - mdo_offset_bias, mdo); __ verify_klass_ptr(tmp1); - __ cmpd(CCR0, recv, tmp1); - __ bne(CCR0, next_test); + __ cmpd(CR0, recv, tmp1); + __ bne(CR0, next_test); __ ld(tmp1, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - mdo_offset_bias, mdo); __ addi(tmp1, tmp1, DataLayout::counter_increment); @@ -2333,8 +2332,8 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias, for (i = 0; i < VirtualCallData::row_limit(); i++) { Label next_test; __ ld(tmp1, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - mdo_offset_bias, mdo); - __ cmpdi(CCR0, tmp1, 0); - __ bne(CCR0, next_test); + __ cmpdi(CR0, tmp1, 0); + __ bne(CR0, next_test); __ li(tmp1, DataLayout::counter_increment); __ std(recv, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) - mdo_offset_bias, mdo); __ std(tmp1, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) - mdo_offset_bias, mdo); @@ -2395,8 +2394,8 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L Label not_null; metadata2reg(md->constant_encoding(), mdo); __ add_const_optimized(mdo, mdo, mdo_offset_bias, R0); - __ cmpdi(CCR0, obj, 0); - __ bne(CCR0, not_null); + __ cmpdi(CR0, obj, 0); + __ bne(CR0, not_null); __ lbz(data_val, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias, mdo); __ ori(data_val, data_val, BitData::null_seen_byte_constant()); __ stb(data_val, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias, mdo); @@ -2413,8 +2412,8 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L __ std(Rtmp1, slot_offset, mdo); __ bind(update_done); } else { - __ cmpdi(CCR0, obj, 0); - __ beq(CCR0, *obj_is_null); + __ cmpdi(CR0, obj, 0); + __ beq(CR0, *obj_is_null); } // get object class @@ -2428,8 +2427,8 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L if (op->fast_check()) { assert_different_registers(klass_RInfo, k_RInfo); - __ cmpd(CCR0, k_RInfo, klass_RInfo); - __ beq(CCR0, *success); + __ cmpd(CR0, k_RInfo, klass_RInfo); + __ beq(CR0, *success); // Fall through to failure case. } else { bool need_slow_path = true; @@ -2463,7 +2462,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L __ mtctr(original_Rtmp1); __ bctrl(); // sets CR0 if (keep_obj_alive) { __ mr(obj, dst); } - __ beq(CCR0, *success); + __ beq(CR0, *success); // Fall through to failure case. } } @@ -2502,8 +2501,8 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { Register data_val = Rtmp1; metadata2reg(md->constant_encoding(), mdo); __ add_const_optimized(mdo, mdo, mdo_offset_bias, R0); - __ cmpdi(CCR0, value, 0); - __ bne(CCR0, not_null); + __ cmpdi(CR0, value, 0); + __ bne(CR0, not_null); __ lbz(data_val, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias, mdo); __ ori(data_val, data_val, BitData::null_seen_byte_constant()); __ stb(data_val, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias, mdo); @@ -2520,8 +2519,8 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { __ std(Rtmp1, slot_offset, mdo); __ bind(update_done); } else { - __ cmpdi(CCR0, value, 0); - __ beq(CCR0, done); + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); } if (!os::zero_page_read_protected() || !ImplicitNullChecks) { explicit_null_check(array, op->info_for_exception()); @@ -2544,7 +2543,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(slow_path)); __ mtctr(R0); __ bctrl(); // sets CR0 - __ beq(CCR0, done); + __ beq(CR0, done); __ bind(failure); __ b(*stub->entry()); @@ -2840,25 +2839,28 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { - // Stubs: Called via rt_call, but dest is a stub address (no function descriptor). + // Stubs: Called via rt_call, but dest is a stub address (no FunctionDescriptor). if (dest == Runtime1::entry_for(C1StubId::register_finalizer_id) || - dest == Runtime1::entry_for(C1StubId::new_multi_array_id )) { + dest == Runtime1::entry_for(C1StubId::new_multi_array_id ) || + dest == Runtime1::entry_for(C1StubId::is_instance_of_id )) { + assert(CodeCache::contains(dest), "simplified call is only for special C1 stubs"); //__ load_const_optimized(R0, dest); __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(dest)); __ mtctr(R0); __ bctrl(); - assert(info != nullptr, "sanity"); - add_call_info_here(info); - __ post_call_nop(); + if (info != nullptr) { + add_call_info_here(info); + __ post_call_nop(); + } return; } __ call_c(dest, relocInfo::runtime_call_type); + assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc"); if (info != nullptr) { add_call_info_here(info); + __ post_call_nop(); } - assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc"); - __ post_call_nop(); } @@ -3025,9 +3027,9 @@ void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr } if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - __ bne_predict_not_taken(CCR0, Lretry); + __ bne_predict_not_taken(CR0, Lretry); } else { - __ bne( CCR0, Lretry); + __ bne( CR0, Lretry); } if (UseCompressedOops && data->is_oop()) { @@ -3064,8 +3066,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { if (do_null) { if (!TypeEntries::was_null_seen(current_klass)) { - __ cmpdi(CCR0, obj, 0); - __ bne(CCR0, Lupdate); + __ cmpdi(CR0, obj, 0); + __ bne(CR0, Lupdate); __ ld(R0, index_or_disp(mdo_addr), mdo_addr->base()->as_pointer_register()); __ ori(R0, R0, TypeEntries::null_seen); if (do_update) { @@ -3075,14 +3077,14 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { } } else { if (do_update) { - __ cmpdi(CCR0, obj, 0); - __ beq(CCR0, Ldone); + __ cmpdi(CR0, obj, 0); + __ beq(CR0, Ldone); } } #ifdef ASSERT } else { - __ cmpdi(CCR0, obj, 0); - __ bne(CCR0, Lupdate); + __ cmpdi(CR0, obj, 0); + __ bne(CR0, Lupdate); __ stop("unexpected null obj"); #endif } @@ -3098,8 +3100,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { klass_reg_used = true; __ load_klass(klass, obj); metadata2reg(exact_klass->constant_encoding(), R0); - __ cmpd(CCR0, klass, R0); - __ beq(CCR0, ok); + __ cmpd(CR0, klass, R0); + __ beq(CR0, ok); __ stop("exact klass and actual klass differ"); __ bind(ok); } @@ -3119,20 +3121,20 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { // Like InterpreterMacroAssembler::profile_obj_type __ clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask)); // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask); - __ cmpd(CCR1, R0, klass); + __ cmpd(CR1, R0, klass); // Klass seen before, nothing to do (regardless of unknown bit). - //beq(CCR1, do_nothing); + //beq(CR1, do_nothing); __ andi_(R0, tmp, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. - //bne(CCR0, do_nothing); - __ crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne - __ beq(CCR0, Lnext); + //bne(CR0, do_nothing); + __ crorc(CR0, Assembler::equal, CR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne + __ beq(CR0, Lnext); if (TypeEntries::is_type_none(current_klass)) { __ clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); __ orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0). - __ beq(CCR0, Ldo_update); // First time here. Set profile type. + __ beq(CR0, Ldo_update); // First time here. Set profile type. } } else { @@ -3142,7 +3144,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ ld(tmp, index_or_disp(mdo_addr), mdo_addr->base()->as_pointer_register()); __ andi_(R0, tmp, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. - __ bne(CCR0, Lnext); + __ bne(CR0, Lnext); } // Different than before. Cannot keep accurate profile. @@ -3158,14 +3160,14 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask)); // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask); - __ cmpd(CCR1, R0, klass); + __ cmpd(CR1, R0, klass); // Klass seen before, nothing to do (regardless of unknown bit). - __ beq(CCR1, Lnext); + __ beq(CR1, Lnext); #ifdef ASSERT { Label ok; __ clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); - __ beq(CCR0, ok); // First time here. + __ beq(CR0, ok); // First time here. __ stop("unexpected profiling mismatch"); __ bind(ok); @@ -3179,7 +3181,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { // Already unknown. Nothing to do anymore. __ andi_(R0, tmp, TypeEntries::type_unknown); - __ bne(CCR0, Lnext); + __ bne(CR0, Lnext); // Different than before. Cannot keep accurate profile. __ ori(R0, tmp, TypeEntries::type_unknown); diff --git a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp index b332ffbcee7d1..b9c8ced8ef192 100644 --- a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" @@ -702,8 +701,6 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { value.load_item(); LIR_Opr dst = rlock_result(x); LIR_Opr tmp = new_register(T_FLOAT); - // f2hf treats tmp as live_in. Workaround: initialize to some value. - __ move(LIR_OprFact::floatConst(-0.0), tmp); // just to satisfy LinearScan __ f2hf(value.result(), dst, tmp); break; } @@ -1132,6 +1129,12 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return Runtime1::entry_for(C1StubId::is_instance_of_id); +} + + void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); ValueTag tag = x->x()->type()->tag(); diff --git a/src/hotspot/cpu/ppc/c1_LIR_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIR_ppc.cpp index d031aaa1e4061..56a9307f21f96 100644 --- a/src/hotspot/cpu/ppc/c1_LIR_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIR_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "c1/c1_LIR.hpp" diff --git a/src/hotspot/cpu/ppc/c1_LinearScan_ppc.cpp b/src/hotspot/cpu/ppc/c1_LinearScan_ppc.cpp index 026540f25b213..d6ceab8b27b1b 100644 --- a/src/hotspot/cpu/ppc/c1_LinearScan_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LinearScan_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp index 8cd21478d41a4..ac9c5984de050 100644 --- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" @@ -87,8 +86,8 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(Rscratch, Roop); lbz(Rscratch, in_bytes(Klass::misc_flags_offset()), Rscratch); - testbitdi(CCR0, R0, Rscratch, exact_log2(KlassFlags::_misc_is_value_based_class)); - bne(CCR0, slow_int); + testbitdi(CR0, R0, Rscratch, exact_log2(KlassFlags::_misc_is_value_based_class)); + bne(CR0, slow_int); } if (LockingMode == LM_LIGHTWEIGHT) { @@ -102,7 +101,7 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox // Compare object markWord with Rmark and if equal exchange Rscratch with object markWord. assert(oopDesc::mark_offset_in_bytes() == 0, "cas must take a zero displacement"); - cmpxchgd(/*flag=*/CCR0, + cmpxchgd(/*flag=*/CR0, /*current_value=*/Rscratch, /*compare_value=*/Rmark, /*exchange_value=*/Rbox, @@ -129,7 +128,7 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox load_const_optimized(R0, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); and_(R0/*==0?*/, Rscratch, R0); std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), Rbox); - bne(CCR0, slow_int); + bne(CR0, slow_int); } bind(done); @@ -150,8 +149,8 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb if (LockingMode != LM_LIGHTWEIGHT) { // Test first if it is a fast recursive unlock. ld(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox); - cmpdi(CCR0, Rmark, 0); - beq(CCR0, done); + cmpdi(CR0, Rmark, 0); + beq(CR0, done); } // Load object. @@ -163,7 +162,7 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb } else if (LockingMode == LM_LEGACY) { // Check if it is still a light weight lock, this is is true if we see // the stack address of the basicLock in the markWord of the object. - cmpxchgd(/*flag=*/CCR0, + cmpxchgd(/*flag=*/CR0, /*current_value=*/R0, /*compare_value=*/Rbox, /*exchange_value=*/Rmark, @@ -286,9 +285,9 @@ void C1_MacroAssembler::initialize_object( { lwz(t1, in_bytes(Klass::layout_helper_offset()), klass); if (var_size_in_bytes != noreg) { - cmpw(CCR0, t1, var_size_in_bytes); + cmpw(CR0, t1, var_size_in_bytes); } else { - cmpwi(CCR0, t1, con_size_in_bytes); + cmpwi(CR0, t1, con_size_in_bytes); } asm_assert_eq("bad size in initialize_object"); } @@ -341,8 +340,8 @@ void C1_MacroAssembler::allocate_array( if (max_tlab < max_length) { max_length = max_tlab; } } load_const_optimized(t1, max_length); - cmpld(CCR0, len, t1); - bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::greater), slow_case); + cmpld(CR0, len, t1); + bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::greater), slow_case); // compute array size // note: If 0 <= len <= max_length, len*elt_size + header + alignment is @@ -400,8 +399,8 @@ void C1_MacroAssembler::verify_stack_oop(int stack_offset) { void C1_MacroAssembler::verify_not_null_oop(Register r) { Label not_null; - cmpdi(CCR0, r, 0); - bne(CCR0, not_null); + cmpdi(CR0, r, 0); + bne(CR0, not_null); stop("non-null oop required"); bind(not_null); verify_oop(r, FILE_AND_LINE); @@ -415,7 +414,7 @@ void C1_MacroAssembler::null_check(Register r, Label* Lnull) { } else { // explicit //const address exception_entry = Runtime1::entry_for(C1StubId::throw_null_pointer_exception_id); assert(Lnull != nullptr, "must have Label for explicit check"); - cmpdi(CCR0, r, 0); - bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::equal), *Lnull); + cmpdi(CR0, r, 0); + bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::equal), *Lnull); } } diff --git a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp index 47cafc45f33ea..11c01dcdc60e6 100644 --- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2023 SAP SE. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_MacroAssembler.hpp" @@ -70,14 +69,14 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, // Check for pending exceptions. { ld(R0, in_bytes(Thread::pending_exception_offset()), R16_thread); - cmpdi(CCR0, R0, 0); + cmpdi(CR0, R0, 0); // This used to conditionally jump to forward_exception however it is // possible if we relocate that the branch will not reach. So we must jump // around so we can always reach. Label ok; - beq(CCR0, ok); + beq(CR0, ok); // Make sure that the vm_results are cleared. if (oop_result1->is_valid() || metadata_result->is_valid()) { @@ -369,7 +368,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { int call_offset = __ call_RT(noreg, noreg, target); OopMapSet* oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, oop_map); - __ cmpdi(CCR0, R3_RET, 0); + __ cmpdi(CR0, R3_RET, 0); // Re-execute the patched instruction or, if the nmethod was deoptmized, // return to the deoptimization handler entry that will cause re-execution @@ -383,7 +382,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { restore_live_registers(sasm, noreg, noreg); // Return if patching routine returned 0. - __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CCR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); + __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); address stub = deopt_blob->unpack_with_reexecution(); //__ load_const_optimized(R0, stub); @@ -449,8 +448,8 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { Label ok; __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R4_ARG2); __ srawi(R0, R0, Klass::_lh_array_tag_shift); - __ cmpwi(CCR0, R0, tag); - __ beq(CCR0, ok); + __ cmpwi(CR0, R0, tag); + __ beq(CR0, ok); __ stop("assert(is an array klass)"); __ should_not_reach_here(); __ bind(ok); @@ -486,9 +485,9 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { // Load the klass and check the has finalizer flag. __ load_klass(t, R3_ARG1); __ lbz(t, in_bytes(Klass::misc_flags_offset()), t); - __ testbitdi(CCR0, R0, t, exact_log2(KlassFlags::_misc_has_finalizer)); + __ testbitdi(CR0, R0, t, exact_log2(KlassFlags::_misc_has_finalizer)); // Return if has_finalizer bit == 0 (CR0.eq). - __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CCR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); + __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); __ mflr(R0); __ std(R0, _abi0(lr), R1_SP); @@ -603,10 +602,76 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super ); const Register sub_klass = R5, super_klass = R4, - temp1_reg = R6, - temp2_reg = R0; - __ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, temp2_reg); // returns with CR0.eq if successful - __ crandc(CCR0, Assembler::equal, CCR0, Assembler::equal); // failed: CR0.ne + temp1_reg = R6; + __ check_klass_subtype_slow_path(sub_klass, super_klass, temp1_reg, noreg); + // Result is in CR0. + __ blr(); + } + break; + + case C1StubId::is_instance_of_id: + { + // Called like a C function, but without FunctionDescriptor (see LIR_Assembler::rt_call). + + // Arguments and return value. + Register mirror = R3_ARG1; + Register obj = R4_ARG2; + Register result = R3_RET; + + // Other argument registers can be used as temp registers. + Register klass = R5; + Register offset = R6; + Register sub_klass = R7; + + Label is_secondary, success; + + // Get the Klass*. + __ ld(klass, java_lang_Class::klass_offset(), mirror); + + // Return false if obj or klass is null. + mirror = noreg; // killed by next instruction + __ li(result, 0); // assume result is false + __ cmpdi(CR0, obj, 0); + __ cmpdi(CR1, klass, 0); + __ cror(CR0, Assembler::equal, CR1, Assembler::equal); + __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintbhBCLRisReturn); + + __ lwz(offset, in_bytes(Klass::super_check_offset_offset()), klass); + __ load_klass(sub_klass, obj); + __ cmpwi(CR0, offset, in_bytes(Klass::secondary_super_cache_offset())); + __ beq(CR0, is_secondary); // Klass is a secondary superclass + + // Klass is a concrete class + __ ldx(R0, sub_klass, offset); + __ cmpd(CR0, klass, R0); + if (VM_Version::has_brw()) { + // Power10 can set the result by one instruction. No need for a branch. + __ setbc(result, CR0, Assembler::equal); + } else { + __ beq(CR0, success); + } + __ blr(); + + __ bind(is_secondary); + + // This is necessary because I am never in my own secondary_super list. + __ cmpd(CR0, sub_klass, klass); + __ beq(CR0, success); + + __ lookup_secondary_supers_table_var(sub_klass, klass, + /*temps*/R9, R10, R11, R12, + /*result*/R8); + __ cmpdi(CR0, R8, 0); // 0 means is subclass + if (VM_Version::has_brw()) { + // Power10 can set the result by one instruction. No need for a branch. + __ setbc(result, CR0, Assembler::equal); + } else { + __ beq(CR0, success); + } + __ blr(); + + __ bind(success); + __ li(result, 1); __ blr(); } break; @@ -807,10 +872,10 @@ OopMapSet* Runtime1::generate_handle_exception(C1StubId id, StubAssembler* sasm) // Check that fields in JavaThread for exception oop and issuing pc are // empty before writing to them. __ ld(R0, in_bytes(JavaThread::exception_oop_offset()), R16_thread); - __ cmpdi(CCR0, R0, 0); + __ cmpdi(CR0, R0, 0); __ asm_assert_eq("exception oop already set"); __ ld(R0, in_bytes(JavaThread::exception_pc_offset() ), R16_thread); - __ cmpdi(CCR0, R0, 0); + __ cmpdi(CR0, R0, 0); __ asm_assert_eq("exception pc already set"); #endif diff --git a/src/hotspot/cpu/ppc/c2_CodeStubs_ppc.cpp b/src/hotspot/cpu/ppc/c2_CodeStubs_ppc.cpp index 93ee0659a57f8..484e0fd0196db 100644 --- a/src/hotspot/cpu/ppc/c2_CodeStubs_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_CodeStubs_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022, SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "opto/c2_MacroAssembler.hpp" #include "opto/c2_CodeStubs.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp index d7f2aefd9c477..cddf08eceb15c 100644 --- a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "opto/c2_MacroAssembler.hpp" @@ -71,7 +70,7 @@ void C2_MacroAssembler::string_compress_16(Register src, Register dst, Register // Check if cnt >= 8 (= 16 bytes) lis(tmp1, byte_mask); // tmp1 = 0x00FF00FF00FF00FF (non ascii case) srwi_(tmp2, cnt, 3); - beq(CCR0, Lslow); + beq(CR0, Lslow); ori(tmp1, tmp1, byte_mask); rldimi(tmp1, tmp1, 32, 0); mtctr(tmp2); @@ -88,7 +87,7 @@ void C2_MacroAssembler::string_compress_16(Register src, Register dst, Register rldimi(tmp4, tmp4, 2*8, 2*8); // _4_6_7_7 andc_(tmp0, tmp0, tmp1); - bne(CCR0, Lfailure); // Not latin1/ascii. + bne(CR0, Lfailure); // Not latin1/ascii. addi(src, src, 16); rlwimi(tmp3, tmp2, 0*8, 24, 31);// _____1_3 @@ -116,8 +115,8 @@ void C2_MacroAssembler::string_compress(Register src, Register dst, Register cnt bind(Lloop); lhz(tmp, 0, src); - cmplwi(CCR0, tmp, byte_mask); - bgt(CCR0, Lfailure); // Not latin1/ascii. + cmplwi(CR0, tmp, byte_mask); + bgt(CR0, Lfailure); // Not latin1/ascii. addi(src, src, 2); stb(tmp, 0, dst); addi(dst, dst, 1); @@ -131,7 +130,7 @@ void C2_MacroAssembler::encode_iso_array(Register src, Register dst, Register le string_compress_16(src, dst, len, tmp1, tmp2, tmp3, tmp4, tmp5, Lfailure1, ascii); rldicl_(result, len, 0, 64-3); // Remaining characters. - beq(CCR0, Ldone); + beq(CR0, Ldone); bind(Lslow); string_compress(src, dst, result, tmp2, Lfailure2, ascii); li(result, 0); @@ -141,7 +140,7 @@ void C2_MacroAssembler::encode_iso_array(Register src, Register dst, Register le mr(result, len); mfctr(tmp1); rldimi_(result, tmp1, 3, 0); // Remaining characters. - beq(CCR0, Ldone); + beq(CR0, Ldone); b(Lslow); bind(Lfailure2); @@ -160,7 +159,7 @@ void C2_MacroAssembler::string_inflate_16(Register src, Register dst, Register c // Check if cnt >= 8 srwi_(tmp2, cnt, 3); - beq(CCR0, Lslow); + beq(CR0, Lslow); lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF ori(tmp1, tmp1, 0xFF); mtctr(tmp2); @@ -236,10 +235,10 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, subf_(diff, cnt2, cnt1); // diff = cnt1 - cnt2 // if (diff > 0) { cnt1 = cnt2; } if (VM_Version::has_isel()) { - isel(cnt1, CCR0, Assembler::greater, /*invert*/ false, cnt2); + isel(cnt1, CR0, Assembler::greater, /*invert*/ false, cnt2); } else { Label Lskip; - blt(CCR0, Lskip); + blt(CR0, Lskip); mr(cnt1, cnt2); bind(Lskip); } @@ -255,7 +254,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, Label Lfastloop, Lskipfast; srwi_(tmp0, cnt1, log2_chars_per_iter); - beq(CCR0, Lskipfast); + beq(CR0, Lskipfast); rldicl(cnt2, cnt1, 0, 64 - log2_chars_per_iter); // Remaining characters. li(cnt1, 1 << log2_chars_per_iter); // Initialize for failure case: Rescan characters from current iteration. mtctr(tmp0); @@ -263,8 +262,8 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, bind(Lfastloop); ld(chr1, 0, str1); ld(chr2, 0, str2); - cmpd(CCR0, chr1, chr2); - bne(CCR0, Lslow); + cmpd(CR0, chr1, chr2); + bne(CR0, Lslow); addi(str1, str1, stride1); addi(str2, str2, stride2); bdnz(Lfastloop); @@ -273,8 +272,8 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, } // Loop which searches the first difference character by character. - cmpwi(CCR0, cnt1, 0); - beq(CCR0, Lreturn_diff); + cmpwi(CR0, cnt1, 0); + beq(CR0, Lreturn_diff); bind(Lslow); mtctr(cnt1); @@ -290,7 +289,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, if (stride1 == 1) { lbz(chr1, 0, str1); } else { lhz(chr1, 0, str1); } if (stride2 == 1) { lbz(chr2, 0, str2); } else { lhz(chr2, 0, str2); } subf_(result, chr2, chr1); // result = chr1 - chr2 - bne(CCR0, Ldone); + bne(CR0, Ldone); addi(str1, str1, stride1); addi(str2, str2, stride2); bdnz(Lloop); @@ -318,23 +317,23 @@ void C2_MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register const int base_offset = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR); // Return true if the same array. - cmpd(CCR0, ary1, ary2); - beq(CCR0, Lskiploop); + cmpd(CR0, ary1, ary2); + beq(CR0, Lskiploop); // Return false if one of them is null. - cmpdi(CCR0, ary1, 0); - cmpdi(CCR1, ary2, 0); + cmpdi(CR0, ary1, 0); + cmpdi(CR1, ary2, 0); li(result, 0); - cror(CCR0, Assembler::equal, CCR1, Assembler::equal); - beq(CCR0, Ldone); + cror(CR0, Assembler::equal, CR1, Assembler::equal); + beq(CR0, Ldone); // Load the lengths of arrays. lwz(limit, length_offset, ary1); lwz(tmp0, length_offset, ary2); // Return false if the two arrays are not equal length. - cmpw(CCR0, limit, tmp0); - bne(CCR0, Ldone); + cmpw(CR0, limit, tmp0); + bne(CR0, Ldone); // Load array addresses. addi(ary1, ary1, base_offset); @@ -352,7 +351,7 @@ void C2_MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register const int log2_chars_per_iter = is_byte ? 3 : 2; srwi_(tmp0, limit, log2_chars_per_iter + (limit_needs_shift ? 1 : 0)); - beq(CCR0, Lskipfast); + beq(CR0, Lskipfast); mtctr(tmp0); bind(Lfastloop); @@ -360,13 +359,13 @@ void C2_MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ld(chr2, 0, ary2); addi(ary1, ary1, 8); addi(ary2, ary2, 8); - cmpd(CCR0, chr1, chr2); - bne(CCR0, Ldone); + cmpd(CR0, chr1, chr2); + bne(CR0, Ldone); bdnz(Lfastloop); bind(Lskipfast); rldicl_(limit, limit, limit_needs_shift ? 64 - 1 : 0, 64 - log2_chars_per_iter); // Remaining characters. - beq(CCR0, Lskiploop); + beq(CR0, Lskiploop); mtctr(limit); // Character by character. @@ -382,8 +381,8 @@ void C2_MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register addi(ary1, ary1, 2); addi(ary2, ary2, 2); } - cmpw(CCR0, chr1, chr2); - bne(CCR0, Ldone); + cmpw(CR0, chr1, chr2); + bne(CR0, Ldone); bdnz(Lloop); bind(Lskiploop); @@ -415,9 +414,9 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis clrldi(haycnt, haycnt, 32); // Ensure positive int is valid as 64 bit value. addi(addr, haystack, -h_csize); // Accesses use pre-increment. if (needlecntval == 0) { // variable needlecnt - cmpwi(CCR6, needlecnt, 2); + cmpwi(CR6, needlecnt, 2); clrldi(needlecnt, needlecnt, 32); // Ensure positive int is valid as 64 bit value. - blt(CCR6, L_TooShort); // Variable needlecnt: handle short needle separately. + blt(CR6, L_TooShort); // Variable needlecnt: handle short needle separately. } if (n_csize == 2) { lwz(n_start, 0, needle); } else { lhz(n_start, 0, needle); } // Load first 2 characters of needle. @@ -448,7 +447,7 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis subf(addr_diff, addr, last_addr); // Difference between already checked address and last address to check. addi(addr, addr, h_csize); // This is the new address we want to use for comparing. srdi_(ch2, addr_diff, h_csize); - beq(CCR0, L_FinalCheck); // 2 characters left? + beq(CR0, L_FinalCheck); // 2 characters left? mtctr(ch2); // num of characters / 2 bind(L_InnerLoop); // Main work horse (2x unrolled search loop) if (h_csize == 2) { // Load 2 characters of haystack (ignore alignment). @@ -458,18 +457,18 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis lhz(ch1, 0, addr); lhz(ch2, 1, addr); } - cmpw(CCR0, ch1, n_start); // Compare 2 characters (1 would be sufficient but try to reduce branches to CompLoop). - cmpw(CCR1, ch2, n_start); - beq(CCR0, L_Comp1); // Did we find the needle start? - beq(CCR1, L_Comp2); + cmpw(CR0, ch1, n_start); // Compare 2 characters (1 would be sufficient but try to reduce branches to CompLoop). + cmpw(CR1, ch2, n_start); + beq(CR0, L_Comp1); // Did we find the needle start? + beq(CR1, L_Comp2); addi(addr, addr, 2 * h_csize); bdnz(L_InnerLoop); bind(L_FinalCheck); andi_(addr_diff, addr_diff, h_csize); // Remaining characters not covered by InnerLoop: (num of characters) & 1. - beq(CCR0, L_NotFound); + beq(CR0, L_NotFound); if (h_csize == 2) { lwz(ch1, 0, addr); } else { lhz(ch1, 0, addr); } // One position left at which we have to compare. - cmpw(CCR1, ch1, n_start); - beq(CCR1, L_Comp1); + cmpw(CR1, ch1, n_start); + beq(CR1, L_Comp1); bind(L_NotFound); li(result, -1); // not found b(L_End); @@ -484,8 +483,8 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis if (n_csize == 2) { lhz(n_start, 0, needle); } else { lbz(n_start, 0, needle); } // First character of needle bind(L_OneCharLoop); if (h_csize == 2) { lhzu(ch1, 2, addr); } else { lbzu(ch1, 1, addr); } - cmpw(CCR1, ch1, n_start); - beq(CCR1, L_Found); // Did we find the one character needle? + cmpw(CR1, ch1, n_start); + beq(CR1, L_Found); // Did we find the one character needle? bdnz(L_OneCharLoop); li(result, -1); // Not found. b(L_End); @@ -501,7 +500,7 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis bind(L_Comp1); // Addr points to possible needle start. if (needlecntval != 2) { // Const needlecnt==2? if (needlecntval != 3) { - if (needlecntval == 0) { beq(CCR6, L_Found); } // Variable needlecnt==2? + if (needlecntval == 0) { beq(CR6, L_Found); } // Variable needlecnt==2? Register n_ind = tmp4, h_ind = n_ind; li(n_ind, 2 * n_csize); // First 2 characters are already compared, use index 2. @@ -514,15 +513,15 @@ void C2_MacroAssembler::string_indexof(Register result, Register haystack, Regis } if (n_csize == 2) { lhzx(ch2, needle, n_ind); } else { lbzx(ch2, needle, n_ind); } if (h_csize == 2) { lhzx(ch1, addr, h_ind); } else { lbzx(ch1, addr, h_ind); } - cmpw(CCR1, ch1, ch2); - bne(CCR1, L_OuterLoop); + cmpw(CR1, ch1, ch2); + bne(CR1, L_OuterLoop); addi(n_ind, n_ind, n_csize); bdnz(L_CompLoop); } else { // No loop required if there's only one needle character left. if (n_csize == 2) { lhz(ch2, 2 * 2, needle); } else { lbz(ch2, 2 * 1, needle); } if (h_csize == 2) { lhz(ch1, 2 * 2, addr); } else { lbz(ch1, 2 * 1, addr); } - cmpw(CCR1, ch1, ch2); - bne(CCR1, L_OuterLoop); + cmpw(CR1, ch1, ch2); + bne(CR1, L_OuterLoop); } } // Return index ... @@ -546,7 +545,7 @@ void C2_MacroAssembler::string_indexof_char(Register result, Register haystack, //4: srwi_(tmp2, haycnt, 1); // Shift right by exact_log2(UNROLL_FACTOR). mr(addr, haystack); - beq(CCR0, L_FinalCheck); + beq(CR0, L_FinalCheck); mtctr(tmp2); // Move to count register. //8: bind(L_InnerLoop); // Main work horse (2x unrolled search loop). @@ -557,19 +556,19 @@ void C2_MacroAssembler::string_indexof_char(Register result, Register haystack, lbz(ch1, 0, addr); lbz(ch2, 1, addr); } - (needle != R0) ? cmpw(CCR0, ch1, needle) : cmplwi(CCR0, ch1, (unsigned int)needleChar); - (needle != R0) ? cmpw(CCR1, ch2, needle) : cmplwi(CCR1, ch2, (unsigned int)needleChar); - beq(CCR0, L_Found1); // Did we find the needle? - beq(CCR1, L_Found2); + (needle != R0) ? cmpw(CR0, ch1, needle) : cmplwi(CR0, ch1, (unsigned int)needleChar); + (needle != R0) ? cmpw(CR1, ch2, needle) : cmplwi(CR1, ch2, (unsigned int)needleChar); + beq(CR0, L_Found1); // Did we find the needle? + beq(CR1, L_Found2); addi(addr, addr, 2 * h_csize); bdnz(L_InnerLoop); //16: bind(L_FinalCheck); andi_(R0, haycnt, 1); - beq(CCR0, L_NotFound); + beq(CR0, L_NotFound); if (!is_byte) { lhz(ch1, 0, addr); } else { lbz(ch1, 0, addr); } // One position left at which we have to compare. - (needle != R0) ? cmpw(CCR1, ch1, needle) : cmplwi(CCR1, ch1, (unsigned int)needleChar); - beq(CCR1, L_Found1); + (needle != R0) ? cmpw(CR1, ch1, needle) : cmplwi(CR1, ch1, (unsigned int)needleChar); + beq(CR1, L_Found1); //21: bind(L_NotFound); li(result, -1); // Not found. @@ -595,7 +594,7 @@ void C2_MacroAssembler::count_positives(Register src, Register cnt, Register res lis(tmp1, (int)(short)0x8080); // tmp1 = 0x8080808080808080 srwi_(tmp2, cnt, 4); mr(result, src); // Use result reg to point to the current position. - beq(CCR0, Lslow); + beq(CR0, Lslow); ori(tmp1, tmp1, 0x8080); rldimi(tmp1, tmp1, 32, 0); mtctr(tmp2); @@ -608,19 +607,19 @@ void C2_MacroAssembler::count_positives(Register src, Register cnt, Register res orr(tmp0, tmp2, tmp0); and_(tmp0, tmp0, tmp1); - bne(CCR0, Lslow); // Found negative byte. + bne(CR0, Lslow); // Found negative byte. addi(result, result, 16); bdnz(Lfastloop); bind(Lslow); // Fallback to slow version. subf(tmp0, src, result); // Bytes known positive. subf_(tmp0, tmp0, cnt); // Remaining Bytes. - beq(CCR0, Ldone); + beq(CR0, Ldone); mtctr(tmp0); bind(Lloop); lbz(tmp0, 0, result); andi_(tmp0, tmp0, 0x80); - bne(CCR0, Ldone); // Found negative byte. + bne(CR0, Ldone); // Found negative byte. addi(result, result, 1); bdnz(Lloop); diff --git a/src/hotspot/cpu/ppc/c2_init_ppc.cpp b/src/hotspot/cpu/ppc/c2_init_ppc.cpp index d570abc431a9d..3c524f3b80e94 100644 --- a/src/hotspot/cpu/ppc/c2_init_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_init_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/cpu/ppc/compiledIC_ppc.cpp b/src/hotspot/cpu/ppc/compiledIC_ppc.cpp index a7907b43c4bac..c8cb68e3eb4eb 100644 --- a/src/hotspot/cpu/ppc/compiledIC_ppc.cpp +++ b/src/hotspot/cpu/ppc/compiledIC_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp b/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp index 51012eef86594..060eb058cfa4e 100644 --- a/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp +++ b/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "oops/compressedKlass.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp index 45859f33bfb20..ad8640453e687 100644 --- a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, 2024 SAP SE. All rights reserved. - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025 SAP SE. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" @@ -283,8 +282,8 @@ void DowncallLinker::StubGenerator::generate() { __ safepoint_poll(L_safepoint_poll_slow_path, tmp, true /* at_return */, false /* in_nmethod */); __ lwz(tmp, in_bytes(JavaThread::suspend_flags_offset()), R16_thread); - __ cmpwi(CCR0, tmp, 0); - __ bne(CCR0, L_safepoint_poll_slow_path); + __ cmpwi(CR0, tmp, 0); + __ bne(CR0, L_safepoint_poll_slow_path); __ bind(L_after_safepoint_poll); // change thread state @@ -294,8 +293,8 @@ void DowncallLinker::StubGenerator::generate() { __ block_comment("reguard stack check"); __ lwz(tmp, in_bytes(JavaThread::stack_guard_state_offset()), R16_thread); - __ cmpwi(CCR0, tmp, StackOverflow::stack_guard_yellow_reserved_disabled); - __ beq(CCR0, L_reguard); + __ cmpwi(CR0, tmp, StackOverflow::stack_guard_yellow_reserved_disabled); + __ beq(CR0, L_reguard); __ bind(L_after_reguard); __ reset_last_Java_frame(); diff --git a/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp b/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp index 2143d1394992e..4d98b7630784f 100644 --- a/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp +++ b/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, 2023, SAP SE. All rights reserved. - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/vmreg.inline.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/cpu/ppc/frame_ppc.cpp b/src/hotspot/cpu/ppc/frame_ppc.cpp index f698b14d312b8..38c26e5e4970b 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.cpp +++ b/src/hotspot/cpu/ppc/frame_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" @@ -122,6 +121,11 @@ bool frame::safe_for_sender(JavaThread *thread) { address sender_pc = (address) sender_abi->lr; if (Continuation::is_return_barrier_entry(sender_pc)) { + // sender_pc might be invalid so check that the frame + // actually belongs to a Continuation. + if (!Continuation::is_frame_in_continuation(thread, *this)) { + return false; + } // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); diff --git a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp index 39693bdf925bf..4fb13422f59a2 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2024 SAP SE. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" @@ -52,7 +51,7 @@ static void generate_marking_inactive_test(MacroAssembler* masm) { int active_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()); assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); __ lbz(R0, active_offset, R16_thread); // tmp1 := *(mark queue active address) - __ cmpwi(CCR0, R0, 0); + __ cmpwi(CR0, R0, 0); } void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, @@ -69,7 +68,7 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm // Is marking active? generate_marking_inactive_test(masm); - __ beq(CCR0, filtered); + __ beq(CR0, filtered); __ save_LR(R0); __ push_frame(frame_size, R0); @@ -119,8 +118,8 @@ static void generate_queue_insertion(MacroAssembler* masm, ByteSize index_offset // Can we store a value in the given thread's buffer? // (The index field is typed as size_t.) __ ld(temp, in_bytes(index_offset), R16_thread); // temp := *(index address) - __ cmpdi(CCR0, temp, 0); // jump to runtime if index == 0 (full buffer) - __ beq(CCR0, runtime); + __ cmpdi(CR0, temp, 0); // jump to runtime if index == 0 (full buffer) + __ beq(CR0, runtime); // The buffer is not full, store value into it. __ ld(R0, in_bytes(buffer_offset), R16_thread); // R0 := buffer address __ addi(temp, temp, -wordSize); // temp := next index @@ -155,7 +154,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator Label runtime, filtered; generate_marking_inactive_test(masm); - __ beq(CCR0, filtered); + __ beq(CR0, filtered); // Do we need to load the previous value? if (!preloaded) { @@ -172,12 +171,12 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator // Is the previous value null? if (preloaded && not_null) { #ifdef ASSERT - __ cmpdi(CCR0, pre_val, 0); + __ cmpdi(CR0, pre_val, 0); __ asm_assert_ne("null oop not allowed (G1 pre)"); // Checked by caller. #endif } else { - __ cmpdi(CCR0, pre_val, 0); - __ beq(CCR0, filtered); + __ cmpdi(CR0, pre_val, 0); + __ beq(CR0, filtered); } if (!preloaded && UseCompressedOops) { @@ -241,14 +240,14 @@ static Address generate_card_young_test(MacroAssembler* masm, const Register sto __ load_const_optimized(tmp1, (address)(ct->card_table()->byte_map_base()), tmp2); __ srdi(tmp2, store_addr, CardTable::card_shift()); // tmp1 := card address relative to card table base __ lbzx(R0, tmp1, tmp2); // tmp1 := card address - __ cmpwi(CCR0, R0, (int)G1CardTable::g1_young_card_val()); + __ cmpwi(CR0, R0, (int)G1CardTable::g1_young_card_val()); return Address(tmp1, tmp2); // return card address } static void generate_card_dirty_test(MacroAssembler* masm, Address card_addr) { __ membar(Assembler::StoreLoad); // Must reload after StoreLoad membar due to concurrent refinement __ lbzx(R0, card_addr.base(), card_addr.index()); // tmp2 := card - __ cmpwi(CCR0, R0, (int)G1CardTable::dirty_card_val()); // tmp2 := card == dirty_card_val? + __ cmpwi(CR0, R0, (int)G1CardTable::dirty_card_val()); // tmp2 := card == dirty_card_val? } void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, DecoratorSet decorators, @@ -263,24 +262,24 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato CardTableBarrierSet* ct = barrier_set_cast(BarrierSet::barrier_set()); generate_region_crossing_test(masm, store_addr, new_val); - __ beq(CCR0, filtered); + __ beq(CR0, filtered); // Crosses regions, storing null? if (not_null) { #ifdef ASSERT - __ cmpdi(CCR0, new_val, 0); + __ cmpdi(CR0, new_val, 0); __ asm_assert_ne("null oop not allowed (G1 post)"); // Checked by caller. #endif } else { - __ cmpdi(CCR0, new_val, 0); - __ beq(CCR0, filtered); + __ cmpdi(CR0, new_val, 0); + __ beq(CR0, filtered); } Address card_addr = generate_card_young_test(masm, store_addr, tmp1, tmp2); - __ beq(CCR0, filtered); + __ beq(CR0, filtered); generate_card_dirty_test(masm, card_addr); - __ beq(CCR0, filtered); + __ beq(CR0, filtered); __ li(R0, (int)G1CardTable::dirty_card_val()); __ stbx(R0, card_addr.base(), card_addr.index()); // *(card address) := dirty_card_val @@ -372,14 +371,14 @@ void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value Register tmp1, Register tmp2, MacroAssembler::PreservationLevel preservation_level) { Label done, not_weak; - __ cmpdi(CCR0, value, 0); - __ beq(CCR0, done); // Use null as-is. + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); // Use null as-is. __ clrrdi(tmp1, value, JNIHandles::tag_size); __ andi_(tmp2, value, JNIHandles::TypeTag::weak_global); __ ld(value, 0, tmp1); // Resolve (untagged) jobject. - __ beq(CCR0, not_weak); // Test for jweak tag. + __ beq(CR0, not_weak); // Test for jweak tag. __ verify_oop(value, FILE_AND_LINE); g1_write_barrier_pre(masm, IN_NATIVE | ON_PHANTOM_OOP_REF, noreg, noreg, value, @@ -410,7 +409,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre_c2(MacroAssembler* masm, stub->initialize_registers(obj, pre_val, R16_thread, tmp1, tmp2); generate_marking_inactive_test(masm); - __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CCR0, Assembler::equal), *stub->entry()); + __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CR0, Assembler::equal), *stub->entry()); __ bind(*stub->continuation()); } @@ -434,8 +433,8 @@ void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm, __ ld(pre_val, 0, obj); } } - __ cmpdi(CCR0, pre_val, 0); - __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ cmpdi(CR0, pre_val, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::equal), *stub->continuation()); Register pre_val_decoded = pre_val; if (UseCompressedOops) { @@ -473,25 +472,25 @@ void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm, if (null_check_required && CompressedOops::base() != nullptr) { // We prefer doing the null check after the region crossing check. // Only compressed oop modes with base != null require a null check here. - __ cmpwi(CCR0, new_val, 0); - __ beq(CCR0, *stub->continuation()); + __ cmpwi(CR0, new_val, 0); + __ beq(CR0, *stub->continuation()); null_check_required = false; } new_val_decoded = __ decode_heap_oop_not_null(tmp2, new_val); } generate_region_crossing_test(masm, store_addr, new_val_decoded); - __ beq(CCR0, *stub->continuation()); + __ beq(CR0, *stub->continuation()); // crosses regions, storing null? if (null_check_required) { - __ cmpdi(CCR0, new_val_decoded, 0); - __ beq(CCR0, *stub->continuation()); + __ cmpdi(CR0, new_val_decoded, 0); + __ beq(CR0, *stub->continuation()); } Address card_addr = generate_card_young_test(masm, store_addr, tmp1, tmp2); assert(card_addr.base() == tmp1 && card_addr.index() == tmp2, "needed by post barrier stub"); - __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CCR0, Assembler::equal), *stub->entry()); + __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CR0, Assembler::equal), *stub->entry()); __ bind(*stub->continuation()); } @@ -505,7 +504,7 @@ void G1BarrierSetAssembler::generate_c2_post_barrier_stub(MacroAssembler* masm, __ bind(*stub->entry()); generate_card_dirty_test(masm, card_addr); - __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::equal), *stub->continuation()); __ li(R0, (int)G1CardTable::dirty_card_val()); __ stbx(R0, card_addr.base(), card_addr.index()); // *(card address) := dirty_card_val @@ -547,8 +546,8 @@ void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrier ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /*wide*/); } - __ cmpdi(CCR0, pre_val_reg, 0); - __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ cmpdi(CR0, pre_val_reg, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::equal), *stub->continuation()); address c_code = bs->pre_barrier_c1_runtime_code_blob()->code_begin(); //__ load_const_optimized(R0, c_code); @@ -568,8 +567,8 @@ void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarri Register addr_reg = stub->addr()->as_pointer_register(); Register new_val_reg = stub->new_val()->as_register(); - __ cmpdi(CCR0, new_val_reg, 0); - __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ cmpdi(CR0, new_val_reg, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CR0, Assembler::equal), *stub->continuation()); address c_code = bs->post_barrier_c1_runtime_code_blob()->code_begin(); //__ load_const_optimized(R0, c_code); @@ -605,7 +604,7 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* // Is marking still active? generate_marking_inactive_test(sasm); - __ beq(CCR0, marking_not_active); + __ beq(CR0, marking_not_active); __ bind(restart); // Load the index into the SATB buffer. SATBMarkQueue::_index is a @@ -613,8 +612,8 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* __ ld(tmp, satb_q_index_byte_offset, R16_thread); // index == 0? - __ cmpdi(CCR0, tmp, 0); - __ beq(CCR0, refill); + __ cmpdi(CR0, tmp, 0); + __ beq(CR0, refill); __ ld(tmp2, satb_q_buf_byte_offset, R16_thread); __ ld(pre_val, -8, R1_SP); // Load from stack. @@ -667,15 +666,15 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* __ lbz(tmp, 0, addr); // tmp := [addr + cardtable] // Return if young card. - __ cmpwi(CCR0, tmp, G1CardTable::g1_young_card_val()); - __ beq(CCR0, ret); + __ cmpwi(CR0, tmp, G1CardTable::g1_young_card_val()); + __ beq(CR0, ret); // Return if sequential consistent value is already dirty. __ membar(Assembler::StoreLoad); __ lbz(tmp, 0, addr); // tmp := [addr + cardtable] - __ cmpwi(CCR0, tmp, G1CardTable::dirty_card_val()); - __ beq(CCR0, ret); + __ cmpwi(CR0, tmp, G1CardTable::dirty_card_val()); + __ beq(CR0, ret); // Not dirty. @@ -693,8 +692,8 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* __ ld(tmp2, dirty_card_q_index_byte_offset, R16_thread); // index == 0? - __ cmpdi(CCR0, tmp2, 0); - __ beq(CCR0, refill); + __ cmpdi(CR0, tmp2, 0); + __ beq(CR0, refill); __ ld(tmp, dirty_card_q_buf_byte_offset, R16_thread); __ addi(tmp2, tmp2, -oopSize); diff --git a/src/hotspot/cpu/ppc/gc/g1/g1_ppc.ad b/src/hotspot/cpu/ppc/gc/g1/g1_ppc.ad index f4163242cad7b..4f24efe872b87 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1_ppc.ad +++ b/src/hotspot/cpu/ppc/gc/g1/g1_ppc.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2024 SAP SE. All rights reserved. +// Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2025 SAP SE. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -164,7 +164,7 @@ instruct g1CompareAndExchangeP(iRegPdst res, indirect mem, iRegPsrc oldval, iReg format %{ "cmpxchgd $newval, $mem" %} ins_encode %{ Label no_update; - __ cmpxchgd(CCR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -194,7 +194,7 @@ instruct g1CompareAndExchangeP_acq(iRegPdst res, indirect mem, iRegPsrc oldval, format %{ "cmpxchgd acq $newval, $mem" %} ins_encode %{ Label no_update; - __ cmpxchgd(CCR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -230,7 +230,7 @@ instruct g1CompareAndExchangeN(iRegNdst res, indirect mem, iRegNsrc oldval, iReg format %{ "cmpxchgw $newval, $mem" %} ins_encode %{ Label no_update; - __ cmpxchgw(CCR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -261,7 +261,7 @@ instruct g1CompareAndExchangeN_acq(iRegNdst res, indirect mem, iRegNsrc oldval, format %{ "cmpxchgw acq $newval, $mem" %} ins_encode %{ Label no_update; - __ cmpxchgw(CCR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, $res$$Register, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -299,7 +299,7 @@ instruct g1CompareAndSwapP(iRegIdst res, indirect mem, iRegPsrc oldval, iRegPsrc ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgd(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -332,7 +332,7 @@ instruct g1CompareAndSwapP_acq(iRegIdst res, indirect mem, iRegPsrc oldval, iReg ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgd(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -371,7 +371,7 @@ instruct g1CompareAndSwapN(iRegIdst res, indirect mem, iRegNsrc oldval, iRegNsrc ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgw(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -405,7 +405,7 @@ instruct g1CompareAndSwapN_acq(iRegIdst res, indirect mem, iRegNsrc oldval, iReg ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgw(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -445,7 +445,7 @@ instruct weakG1CompareAndSwapP(iRegIdst res, indirect mem, iRegPsrc oldval, iReg ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgd(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -478,7 +478,7 @@ instruct weakG1CompareAndSwapP_acq(iRegIdst res, indirect mem, iRegPsrc oldval, ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgd(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgd(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -517,7 +517,7 @@ instruct weakG1CompareAndSwapN(iRegIdst res, indirect mem, iRegNsrc oldval, iReg ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgw(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true, true); // Pass oldval to SATB which is the only value which can get overwritten. @@ -551,7 +551,7 @@ instruct weakG1CompareAndSwapN_acq(iRegIdst res, indirect mem, iRegNsrc oldval, ins_encode %{ Label no_update; __ li($res$$Register, 0); - __ cmpxchgw(CCR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, + __ cmpxchgw(CR0, R0, $oldval$$Register, $newval$$Register, $mem$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, &no_update, true, true); // Pass oldval to SATB which is the only value which can get overwritten. diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp index 956b082d194b4..fe10114a1954f 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2022 SAP SE. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -90,8 +89,8 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, if (UseCompressedOops && in_heap) { if (L_handle_null != nullptr) { // Label provided. __ lwz(dst, ind_or_offs, base); - __ cmpwi(CCR0, dst, 0); - __ beq(CCR0, *L_handle_null); + __ cmpwi(CR0, dst, 0); + __ beq(CR0, *L_handle_null); __ decode_heap_oop_not_null(dst); } else if (not_null) { // Guaranteed to be not null. Register narrowOop = (tmp1 != noreg && CompressedOops::base_disjoint()) ? tmp1 : dst; @@ -104,8 +103,8 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, } else { __ ld(dst, ind_or_offs, base); if (L_handle_null != nullptr) { - __ cmpdi(CCR0, dst, 0); - __ beq(CCR0, *L_handle_null); + __ cmpdi(CR0, dst, 0); + __ beq(CR0, *L_handle_null); } } break; @@ -119,11 +118,11 @@ void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2, MacroAssembler::PreservationLevel preservation_level) { Label done, tagged, weak_tagged, verify; - __ cmpdi(CCR0, value, 0); - __ beq(CCR0, done); // Use null as-is. + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); // Use null as-is. __ andi_(tmp1, value, JNIHandles::tag_mask); - __ bne(CCR0, tagged); // Test for tag. + __ bne(CR0, tagged); // Test for tag. __ access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, // no uncoloring value, (intptr_t)0, value, tmp1, tmp2, preservation_level); @@ -132,7 +131,7 @@ void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, __ bind(tagged); __ andi_(tmp1, value, JNIHandles::TypeTag::weak_global); __ clrrdi(value, value, JNIHandles::tag_size); // Untag. - __ bne(CCR0, weak_tagged); // Test for jweak tag. + __ bne(CR0, weak_tagged); // Test for jweak tag. __ access_load_at(T_OBJECT, IN_NATIVE, value, (intptr_t)0, value, tmp1, tmp2, preservation_level); @@ -153,14 +152,14 @@ void BarrierSetAssembler::resolve_global_jobject(MacroAssembler* masm, Register MacroAssembler::PreservationLevel preservation_level) { Label done; - __ cmpdi(CCR0, value, 0); - __ beq(CCR0, done); // Use null as-is. + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); // Use null as-is. #ifdef ASSERT { Label valid_global_tag; __ andi_(tmp1, value, JNIHandles::TypeTag::global); - __ bne(CCR0, valid_global_tag); // Test for global tag. + __ bne(CR0, valid_global_tag); // Test for global tag. __ stop("non global jobject using resolve_global_jobject"); __ bind(valid_global_tag); } @@ -201,9 +200,9 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register t // Low order half of 64 bit value is currently used. __ ld(R0, in_bytes(bs_nm->thread_disarmed_guard_value_offset()), R16_thread); - __ cmpw(CCR0, R0, tmp); + __ cmpw(CR0, R0, tmp); - __ bnectrl(CCR0); + __ bnectrl(CR0); // Oops may have been changed. Make those updates observable. // "isync" can serve both, data and instruction patching. @@ -230,8 +229,8 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler *masm, Register tmp1, Label bad_call, skip_barrier; // Fast path: If no method is given, the call is definitely bad. - __ cmpdi(CCR0, R19_method, 0); - __ beq(CCR0, bad_call); + __ cmpdi(CR0, R19_method, 0); + __ beq(CR0, bad_call); // Load class loader data to determine whether the method's holder is concurrently unloading. __ load_method_holder(tmp1, R19_method); @@ -239,14 +238,14 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler *masm, Register tmp1, // Fast path: If class loader is strong, the holder cannot be unloaded. __ lwz(tmp2, in_bytes(ClassLoaderData::keep_alive_ref_count_offset()), tmp1_class_loader_data); - __ cmpdi(CCR0, tmp2, 0); - __ bne(CCR0, skip_barrier); + __ cmpdi(CR0, tmp2, 0); + __ bne(CR0, skip_barrier); // Class loader is weak. Determine whether the holder is still alive. __ ld(tmp2, in_bytes(ClassLoaderData::holder_offset()), tmp1_class_loader_data); __ resolve_weak_handle(tmp2, tmp1, tmp3, MacroAssembler::PreservationLevel::PRESERVATION_FRAME_LR_GP_FP_REGS); - __ cmpdi(CCR0, tmp2, 0); - __ bne(CCR0, skip_barrier); + __ cmpdi(CR0, tmp2, 0); + __ bne(CR0, skip_barrier); __ bind(bad_call); diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp index d1d0e5ab02412..19084ed27c7c0 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetNMethod_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeBlob.hpp" #include "code/nmethod.hpp" #include "code/nativeInst.hpp" diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp index c9b6b94e1ee72..e1272ce508d72 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2021 SAP SE. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" @@ -50,7 +49,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl Label Lskip_loop, Lstore_loop; __ sldi_(count, count, LogBytesPerHeapOop); - __ beq(CCR0, Lskip_loop); // zero length + __ beq(CR0, Lskip_loop); // zero length __ addi(count, count, -BytesPerHeapOop); __ add(count, addr, count); // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.) diff --git a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp index a500a078c2d33..4cdf56f6ad60c 100644 --- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2021 SAP SE. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" #include "runtime/jniHandles.hpp" @@ -81,8 +80,8 @@ void ModRefBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register v Register tmp1, Register tmp2, MacroAssembler::PreservationLevel preservation_level) { Label done; - __ cmpdi(CCR0, value, 0); - __ beq(CCR0, done); // Use null as-is. + __ cmpdi(CR0, value, 0); + __ beq(CR0, done); // Use null as-is. __ clrrdi(tmp1, value, JNIHandles::tag_size); __ ld(value, 0, tmp1); // Resolve (untagged) jobject. diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp b/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp index ce12d1fcf03f1..48422bc66212e 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp index 9ce0b7c8eb4ee..f7e3072f0811a 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2024, Red Hat, Inc. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2018, 2025, Red Hat, Inc. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/gcArguments.hpp" #include "gc/shared/gc_globals.hpp" @@ -103,8 +102,8 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler *masm, Dec Label skip_prologue; // Fast path: Array is of length zero. - __ cmpdi(CCR0, count, 0); - __ beq(CCR0, skip_prologue); + __ cmpdi(CR0, count, 0); + __ beq(CR0, skip_prologue); /* ==== Check whether barrier is required (gc state) ==== */ __ lbz(R11_tmp, in_bytes(ShenandoahThreadLocalData::gc_state_offset()), @@ -119,7 +118,7 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler *masm, Dec : ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING; __ andi_(R11_tmp, R11_tmp, required_states); - __ beq(CCR0, skip_prologue); + __ beq(CR0, skip_prologue); /* ==== Invoke runtime ==== */ // Save to-be-preserved registers. @@ -217,7 +216,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm __ lbz(tmp1, in_bytes(ShenandoahThreadLocalData::gc_state_offset()), R16_thread); __ andi_(tmp1, tmp1, ShenandoahHeap::MARKING); - __ beq(CCR0, skip_barrier); + __ beq(CR0, skip_barrier); /* ==== Determine the reference's previous value ==== */ bool preloaded_mode = base == noreg; @@ -236,12 +235,12 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm if ((decorators & IS_NOT_NULL) != 0) { #ifdef ASSERT - __ cmpdi(CCR0, pre_val, 0); + __ cmpdi(CR0, pre_val, 0); __ asm_assert_ne("null oop is not allowed"); #endif // ASSERT } else { - __ cmpdi(CCR0, pre_val, 0); - __ beq(CCR0, skip_barrier); + __ cmpdi(CR0, pre_val, 0); + __ beq(CR0, skip_barrier); } } else { // Load from the reference address to determine the reference's current value (before the store is being performed). @@ -255,8 +254,8 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm __ ld(pre_val, ind_or_offs, base); } - __ cmpdi(CCR0, pre_val, 0); - __ beq(CCR0, skip_barrier); + __ cmpdi(CR0, pre_val, 0); + __ beq(CR0, skip_barrier); if (UseCompressedOops) { __ decode_heap_oop_not_null(pre_val); @@ -272,8 +271,8 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_impl(MacroAssembler *masm // If not, jump to the runtime to commit the buffer and to allocate a new one. // (The buffer's index corresponds to the amount of remaining free space.) __ ld(Rindex, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()), R16_thread); - __ cmpdi(CCR0, Rindex, 0); - __ beq(CCR0, runtime); // If index == 0 (buffer is full), goto runtime. + __ cmpdi(CR0, Rindex, 0); + __ beq(CR0, runtime); // If index == 0 (buffer is full), goto runtime. // Capacity suffices. Decrement the queue's size by the size of one oop. // (The buffer is filled contrary to the heap's growing direction, i.e., it is filled downwards.) @@ -363,9 +362,9 @@ void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssemb "marked value must equal the value obtained when all lock bits are being set"); if (VM_Version::has_isel()) { __ xori(tmp1, tmp1, markWord::lock_mask_in_place); - __ isel(dst, CCR0, Assembler::equal, false, tmp1); + __ isel(dst, CR0, Assembler::equal, false, tmp1); } else { - __ bne(CCR0, done); + __ bne(CR0, done); __ xori(dst, tmp1, markWord::lock_mask_in_place); } @@ -403,7 +402,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_impl( if (is_strong) { // For strong references, the heap is considered stable if "has forwarded" is not active. __ andi_(tmp1, tmp2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - __ beq(CCR0, skip_barrier); + __ beq(CR0, skip_barrier); #ifdef ASSERT // "evacuation" -> (implies) "has forwarded". If we reach this code, "has forwarded" must thus be set. __ andi_(tmp1, tmp1, ShenandoahHeap::HAS_FORWARDED); @@ -415,10 +414,10 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_impl( // The additional phase conditions are in place to avoid the resurrection of weak references (see JDK-8266440). Label skip_fastpath; __ andi_(tmp1, tmp2, ShenandoahHeap::WEAK_ROOTS); - __ bne(CCR0, skip_fastpath); + __ bne(CR0, skip_fastpath); __ andi_(tmp1, tmp2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION); - __ beq(CCR0, skip_barrier); + __ beq(CR0, skip_barrier); #ifdef ASSERT // "evacuation" -> (implies) "has forwarded". If we reach this code, "has forwarded" must thus be set. __ andi_(tmp1, tmp1, ShenandoahHeap::HAS_FORWARDED); @@ -454,7 +453,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_impl( __ srdi(tmp1, dst, ShenandoahHeapRegion::region_size_bytes_shift_jint()); __ lbzx(tmp2, tmp1, tmp2); __ andi_(tmp2, tmp2, 1); - __ beq(CCR0, skip_barrier); + __ beq(CR0, skip_barrier); } /* ==== Invoke runtime ==== */ @@ -640,8 +639,8 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler Label done; // Fast path: Reference is null (JNI tags are zero for null pointers). - __ cmpdi(CCR0, obj, 0); - __ beq(CCR0, done); + __ cmpdi(CR0, obj, 0); + __ beq(CR0, done); // Resolve jobject using standard implementation. BarrierSetAssembler::try_resolve_jobject_in_native(masm, dst, jni_env, obj, tmp, slowpath); @@ -652,7 +651,7 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler jni_env); __ andi_(tmp, tmp, ShenandoahHeap::EVACUATION | ShenandoahHeap::HAS_FORWARDED); - __ bne(CCR0, slowpath); + __ bne(CR0, slowpath); __ bind(done); __ block_comment("} try_resolve_jobject_in_native (shenandoahgc)"); @@ -702,23 +701,23 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler *masm, Register b // Given that 'expected' must refer to the to-space object of an evacuated object (strong to-space invariant), // no special processing is required. if (UseCompressedOops) { - __ cmpxchgw(CCR0, current_value, expected, new_val, base_addr, MacroAssembler::MemBarNone, + __ cmpxchgw(CR0, current_value, expected, new_val, base_addr, MacroAssembler::MemBarNone, false, success_flag, nullptr, true); } else { - __ cmpxchgd(CCR0, current_value, expected, new_val, base_addr, MacroAssembler::MemBarNone, + __ cmpxchgd(CR0, current_value, expected, new_val, base_addr, MacroAssembler::MemBarNone, false, success_flag, nullptr, true); } // Skip the rest of the barrier if the CAS operation succeeds immediately. // If it does not, the value stored at the address is either the from-space pointer of the // referenced object (success criteria s2)) or simply another object. - __ beq(CCR0, done); + __ beq(CR0, done); /* ==== Step 2 (Null check) ==== */ // The success criteria s2) cannot be matched with a null pointer // (null pointers cannot be subject to concurrent evacuation). The failure of the CAS operation is thus legitimate. - __ cmpdi(CCR0, current_value, 0); - __ beq(CCR0, done); + __ cmpdi(CR0, current_value, 0); + __ beq(CR0, done); /* ==== Step 3 (reference pointer refers to from-space version; success criteria s2)) ==== */ // To check whether the reference pointer refers to the from-space version, the forward @@ -738,15 +737,15 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler *masm, Register b // Load zero into register for the potential failure case. __ li(success_flag, 0); } - __ cmpd(CCR0, current_value, expected); - __ bne(CCR0, done); + __ cmpd(CR0, current_value, expected); + __ bne(CR0, done); // Discard fetched value as it might be a reference to the from-space version of an object. if (UseCompressedOops) { - __ cmpxchgw(CCR0, R0, initial_value, new_val, base_addr, MacroAssembler::MemBarNone, + __ cmpxchgw(CR0, R0, initial_value, new_val, base_addr, MacroAssembler::MemBarNone, false, success_flag); } else { - __ cmpxchgd(CCR0, R0, initial_value, new_val, base_addr, MacroAssembler::MemBarNone, + __ cmpxchgd(CR0, R0, initial_value, new_val, base_addr, MacroAssembler::MemBarNone, false, success_flag); } @@ -771,7 +770,7 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler *masm, Register b // guaranteed to be the case. // In case of a concurrent update, the CAS would be retried again. This is legitimate // in terms of program correctness (even though it is not desired). - __ bne(CCR0, step_four); + __ bne(CR0, step_four); __ bind(done); __ block_comment("} cmpxchg_oop (shenandoahgc)"); @@ -790,7 +789,7 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb __ sldi_(count, count, LogBytesPerHeapOop); // Zero length? Skip. - __ beq(CCR0, L_skip_loop); + __ beq(CR0, L_skip_loop); __ addi(count, count, -BytesPerHeapOop); __ add(count, addr, count); @@ -836,8 +835,8 @@ void ShenandoahBarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler *ce, Shen } // Fast path: Reference is null. - __ cmpdi(CCR0, pre_val, 0); - __ bc_far_optimized(Assembler::bcondCRbiIs1_bhintNoHint, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ cmpdi(CR0, pre_val, 0); + __ bc_far_optimized(Assembler::bcondCRbiIs1_bhintNoHint, __ bi0(CR0, Assembler::equal), *stub->continuation()); // Argument passing via the stack. __ std(pre_val, -8, R1_SP); @@ -867,7 +866,7 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble // Ensure that 'res' is 'R3_ARG1' and contains the same value as 'obj' to reduce the number of required // copy instructions. assert(R3_RET == res, "res must be r3"); - __ cmpd(CCR0, res, obj); + __ cmpd(CR0, res, obj); __ asm_assert_eq("result register must contain the reference stored in obj"); #endif @@ -889,7 +888,7 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble __ lbzx(tmp2, tmp1, tmp2); __ andi_(tmp2, tmp2, 1); - __ bc_far_optimized(Assembler::bcondCRbiIs1_bhintNoHint, __ bi0(CCR0, Assembler::equal), *stub->continuation()); + __ bc_far_optimized(Assembler::bcondCRbiIs1_bhintNoHint, __ bi0(CR0, Assembler::equal), *stub->continuation()); } address blob_addr = nullptr; @@ -947,13 +946,13 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss __ lbz(R12_tmp2, in_bytes(ShenandoahThreadLocalData::gc_state_offset()), R16_thread); __ andi_(R12_tmp2, R12_tmp2, ShenandoahHeap::MARKING); - __ beq(CCR0, skip_barrier); + __ beq(CR0, skip_barrier); /* ==== Add previous value directly to thread-local SATB mark queue ==== */ // Check queue's capacity. Jump to runtime if no free slot is available. __ ld(R12_tmp2, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()), R16_thread); - __ cmpdi(CCR0, R12_tmp2, 0); - __ beq(CCR0, runtime); + __ cmpdi(CR0, R12_tmp2, 0); + __ beq(CR0, runtime); // Capacity suffices. Decrement the queue's size by one slot (size of one oop). __ addi(R12_tmp2, R12_tmp2, -wordSize); diff --git a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp index 5891d50f715ee..28a57b2dc293f 100644 --- a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.inline.hpp" @@ -82,7 +81,7 @@ static size_t probe_valid_max_address_bit() { munmap(result_addr, page_size); } } - log_info_p(gc, init)("Probing address space for the highest valid bit: " SIZE_FORMAT, max_address_bit); + log_info_p(gc, init)("Probing address space for the highest valid bit: %zu", max_address_bit); return MAX2(max_address_bit, MINIMUM_MAX_ADDRESS_BIT); #else // LINUX return DEFAULT_MAX_ADDRESS_BIT; diff --git a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp index b9ea67dabe3d6..e30e8c82d23c5 100644 --- a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2021, 2024 SAP SE. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "asm/register.hpp" #include "code/codeBlob.hpp" @@ -170,7 +169,7 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators // if the pointer is not dirty. // Only dirty pointers must be processed by this barrier, so we can skip it in case the latter condition holds true. __ and_(tmp1, tmp1, dst); - __ beq(CCR0, uncolor); + __ beq(CR0, uncolor); /* ==== Invoke barrier ==== */ { @@ -194,8 +193,8 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators // Slow-path has already uncolored if (L_handle_null != nullptr) { - __ cmpdi(CCR0, dst, 0); - __ beq(CCR0, *L_handle_null); + __ cmpdi(CR0, dst, 0); + __ beq(CR0, *L_handle_null); } __ b(done); @@ -204,7 +203,7 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators __ srdi(dst, dst, ZPointerLoadShift); } else { __ srdi_(dst, dst, ZPointerLoadShift); - __ beq(CCR0, *L_handle_null); + __ beq(CR0, *L_handle_null); } __ bind(done); @@ -235,7 +234,7 @@ static void emit_store_fast_path_check(MacroAssembler* masm, Register base, Regi // A not relocatable object could have spurious raw null pointers in its fields after // getting promoted to the old generation. __ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatStoreGoodBits); - __ cmplwi(CCR0, R0, barrier_Relocation::unpatched); + __ cmplwi(CR0, R0, barrier_Relocation::unpatched); } else { __ ld(R0, ind_or_offs, base); // Stores on relocatable objects never need to deal with raw null pointers in fields. @@ -245,7 +244,7 @@ static void emit_store_fast_path_check(MacroAssembler* masm, Register base, Regi __ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatStoreBadMask); __ andi_(R0, R0, barrier_Relocation::unpatched); } - __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CCR0, Assembler::equal), medium_path); + __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CR0, Assembler::equal), medium_path); } void ZBarrierSetAssembler::store_barrier_fast(MacroAssembler* masm, @@ -275,7 +274,7 @@ void ZBarrierSetAssembler::store_barrier_fast(MacroAssembler* masm, __ ld(R0, ind_or_offset, ref_base); __ ld(rnew_zpointer, in_bytes(ZThreadLocalData::store_bad_mask_offset()), R16_thread); __ and_(R0, R0, rnew_zpointer); - __ bne(CCR0, medium_path); + __ bne(CR0, medium_path); __ bind(medium_path_continuation); __ ld(rnew_zpointer, in_bytes(ZThreadLocalData::store_good_mask_offset()), R16_thread); } @@ -294,7 +293,7 @@ static void store_barrier_buffer_add(MacroAssembler* masm, // Combined pointer bump and check if the buffer is disabled or full __ ld(R0, in_bytes(ZStoreBarrierBuffer::current_offset()), tmp1); __ addic_(R0, R0, -(int)sizeof(ZStoreBarrierEntry)); - __ blt(CCR0, slow_path); + __ blt(CR0, slow_path); __ std(R0, in_bytes(ZStoreBarrierBuffer::current_offset()), tmp1); // Entry is at ZStoreBarrierBuffer (tmp1) + buffer_offset + scaled index (R0) @@ -328,8 +327,8 @@ void ZBarrierSetAssembler::store_barrier_medium(MacroAssembler* masm, // Atomic accesses can get to the medium fast path because the value was a // raw null value. If it was not null, then there is no doubt we need to take a slow path. __ ld(tmp, ind_or_offs, ref_base); - __ cmpdi(CCR0, tmp, 0); - __ bne(CCR0, slow_path); + __ cmpdi(CR0, tmp, 0); + __ bne(CR0, slow_path); // If we get this far, we know there is a young raw null value in the field. // Try to self-heal null values for atomic accesses @@ -339,12 +338,12 @@ void ZBarrierSetAssembler::store_barrier_medium(MacroAssembler* masm, need_restore = true; } __ ld(R0, in_bytes(ZThreadLocalData::store_good_mask_offset()), R16_thread); - __ cmpxchgd(CCR0, tmp, (intptr_t)0, R0, ref_base, + __ cmpxchgd(CR0, tmp, (intptr_t)0, R0, ref_base, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, need_restore ? nullptr : &slow_path); if (need_restore) { __ sub(ref_base, ref_base, ind_or_offs); - __ bne(CCR0, slow_path); + __ bne(CR0, slow_path); } } else { // A non-atomic relocatable object won't get to the medium fast path due to a @@ -448,7 +447,7 @@ void ZBarrierSetAssembler::copy_load_at_fast(MacroAssembler* masm, Label& continuation) const { __ ldx(zpointer, addr); __ and_(R0, zpointer, load_bad_mask); - __ bne(CCR0, slow_path); + __ bne(CR0, slow_path); __ bind(continuation); } void ZBarrierSetAssembler::copy_load_at_slow(MacroAssembler* masm, @@ -481,7 +480,7 @@ void ZBarrierSetAssembler::copy_store_at_fast(MacroAssembler* masm, if (!dest_uninitialized) { __ ldx(R0, addr); __ and_(R0, R0, store_bad_mask); - __ bne(CCR0, medium_path); + __ bne(CR0, medium_path); __ bind(continuation); } __ rldimi(zpointer, store_good_mask, 0, 64 - ZPointerLoadShift); // Replace color bits. @@ -516,8 +515,8 @@ void ZBarrierSetAssembler::copy_store_at_slow(MacroAssembler* masm, void ZBarrierSetAssembler::generate_disjoint_oop_copy(MacroAssembler* masm, bool dest_uninitialized) { const Register zpointer = R2, tmp = R9; Label done, loop, load_bad, load_good, store_bad, store_good; - __ cmpdi(CCR0, R5_ARG3, 0); - __ beq(CCR0, done); + __ cmpdi(CR0, R5_ARG3, 0); + __ beq(CR0, done); __ mtctr(R5_ARG3); __ align(32); @@ -540,7 +539,7 @@ void ZBarrierSetAssembler::generate_conjoint_oop_copy(MacroAssembler* masm, bool const Register zpointer = R2, tmp = R9; Label done, loop, load_bad, load_good, store_bad, store_good; __ sldi_(R0, R5_ARG3, 3); - __ beq(CCR0, done); + __ beq(CR0, done); __ mtctr(R5_ARG3); // Point behind last elements and copy backwards. __ add(R3_ARG1, R3_ARG1, R0); @@ -571,12 +570,12 @@ void ZBarrierSetAssembler::check_oop(MacroAssembler *masm, Register obj, const c Label done, skip_uncolor; // Skip (colored) null. __ srdi_(R0, obj, ZPointerLoadShift); - __ beq(CCR0, done); + __ beq(CR0, done); // Check if ZAddressHeapBase << ZPointerLoadShift is set. If so, we need to uncolor. __ rldicl_(R0, obj, 64 - ZAddressHeapBaseShift - ZPointerLoadShift, 63); __ mr(R0, obj); - __ beq(CCR0, skip_uncolor); + __ beq(CR0, skip_uncolor); __ srdi(R0, obj, ZPointerLoadShift); __ bind(skip_uncolor); @@ -595,7 +594,7 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, R // Test for tag __ andi_(tmp, obj, JNIHandles::tag_mask); - __ bne(CCR0, tagged); + __ bne(CR0, tagged); // Resolve local handle __ ld(dst, 0, obj); @@ -606,7 +605,7 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, R // Test for weak tag __ andi_(tmp, obj, JNIHandles::TypeTag::weak_global); __ clrrdi(dst, obj, JNIHandles::tag_size); // Untag. - __ bne(CCR0, weak_tagged); + __ bne(CR0, weak_tagged); // Resolve global handle __ ld(dst, 0, dst); @@ -621,7 +620,7 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, R __ bind(check_color); __ and_(tmp, tmp, dst); - __ bne(CCR0, slowpath); + __ bne(CR0, slowpath); // Uncolor __ srdi(dst, dst, ZPointerLoadShift); @@ -667,7 +666,7 @@ void ZBarrierSetAssembler::generate_c1_load_barrier(LIR_Assembler* ce, ZLoadBarrierStubC1* stub, bool on_non_strong) const { check_color(ce, ref, on_non_strong); - __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CCR0, Assembler::equal), *stub->entry()); + __ bc_far_optimized(Assembler::bcondCRbiIs0, __ bi0(CR0, Assembler::equal), *stub->entry()); z_uncolor(ce, ref); __ bind(*stub->continuation()); } diff --git a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad index 5205138a6ee35..65fb206ad7e6c 100644 --- a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad +++ b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2021 SAP SE. All rights reserved. +// Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2025 SAP SE. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ static void z_load_barrier(MacroAssembler* masm, const MachNode* node, Address r check_color(masm, ref, on_non_strong); ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref); - __ bne_far(CCR0, *stub->entry(), MacroAssembler::bc_far_optimize_on_relocate); + __ bne_far(CR0, *stub->entry(), MacroAssembler::bc_far_optimize_on_relocate); z_uncolor(masm, ref); __ bind(*stub->continuation()); @@ -97,7 +97,7 @@ static void z_compare_and_swap(MacroAssembler* masm, const MachNode* node, Register rold_zpointer = tmp1, rnew_zpointer = tmp2; z_store_barrier(masm, node, mem, 0, newval, rnew_zpointer, true /* is_atomic */); z_color(masm, rold_zpointer, oldval); - __ cmpxchgd(CCR0, R0, rold_zpointer, rnew_zpointer, mem, + __ cmpxchgd(CR0, R0, rold_zpointer, rnew_zpointer, mem, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), res, nullptr, true, false /* we could support weak, but benefit is questionable */); @@ -119,7 +119,7 @@ static void z_compare_and_exchange(MacroAssembler* masm, const MachNode* node, Register rold_zpointer = R0, rnew_zpointer = tmp; z_store_barrier(masm, node, mem, 0, newval, rnew_zpointer, true /* is_atomic */); z_color(masm, rold_zpointer, oldval); - __ cmpxchgd(CCR0, res, rold_zpointer, rnew_zpointer, mem, + __ cmpxchgd(CR0, res, rold_zpointer, rnew_zpointer, mem, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true, false /* we could support weak, but benefit is questionable */); z_uncolor(masm, res); diff --git a/src/hotspot/cpu/ppc/icache_ppc.cpp b/src/hotspot/cpu/ppc/icache_ppc.cpp index 6901efc37b77a..05ad3c7a30d14 100644 --- a/src/hotspot/cpu/ppc/icache_ppc.cpp +++ b/src/hotspot/cpu/ppc/icache_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/icache.hpp" // Use inline assembler to implement icache flush. diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 67b9bdc04142f..000e3cdf2d9c1 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -127,10 +126,10 @@ void InterpreterMacroAssembler::check_and_handle_popframe(Register scratch_reg) // means that this code is called *during* popframe handling - we // don't want to reenter. andi_(R0, scratch_reg, JavaThread::popframe_pending_bit); - beq(CCR0, L); + beq(CR0, L); andi_(R0, scratch_reg, JavaThread::popframe_processing_bit); - bne(CCR0, L); + bne(CR0, L); // Call the Interpreter::remove_activation_preserving_args_entry() // func to get the address of the same-named entrypoint in the @@ -151,12 +150,12 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg) if (JvmtiExport::can_force_early_return()) { Label Lno_early_ret; ld(Rthr_state_addr, in_bytes(JavaThread::jvmti_thread_state_offset()), R16_thread); - cmpdi(CCR0, Rthr_state_addr, 0); - beq(CCR0, Lno_early_ret); + cmpdi(CR0, Rthr_state_addr, 0); + beq(CR0, Lno_early_ret); lwz(R0, in_bytes(JvmtiThreadState::earlyret_state_offset()), Rthr_state_addr); - cmpwi(CCR0, R0, JvmtiThreadState::earlyret_pending); - bne(CCR0, Lno_early_ret); + cmpwi(CR0, R0, JvmtiThreadState::earlyret_pending); + bne(CR0, Lno_early_ret); // Jump to Interpreter::_earlyret_entry. lwz(R3_ARG1, in_bytes(JvmtiThreadState::earlyret_tos_offset()), Rthr_state_addr); @@ -230,7 +229,7 @@ void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register byt ld(R0, in_bytes(JavaThread::polling_word_offset()), R16_thread); // Armed page has poll_bit set, if poll bit is cleared just continue. andi_(R0, R0, SafepointMechanism::poll_bit()); - beq(CCR0, dispatch); + beq(CR0, dispatch); load_dispatch_table(R11_scratch1, sfpt_tbl); align(32, 16); bind(dispatch); @@ -529,8 +528,8 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result Label index_ok; lwa(R0, arrayOopDesc::length_offset_in_bytes(), result); sldi(R0, R0, LogBytesPerHeapOop); - cmpd(CCR0, index, R0); - blt(CCR0, index_ok); + cmpd(CR0, index, R0); + blt(CR0, index_ok); stop("resolved reference index out of bounds"); bind(index_ok); #endif @@ -593,8 +592,8 @@ void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Registe // Array nullcheck if (!ImplicitNullChecks) { - cmpdi(CCR0, Rarray, 0); - beq(CCR0, LisNull); + cmpdi(CR0, Rarray, 0); + beq(CR0, LisNull); } else { null_check_throw(Rarray, arrayOopDesc::length_offset_in_bytes(), /*temp*/RsxtIndex); } @@ -606,9 +605,9 @@ void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Registe // Index check lwz(Rlength, arrayOopDesc::length_offset_in_bytes(), Rarray); - cmplw(CCR0, Rindex, Rlength); + cmplw(CR0, Rindex, Rlength); sldi(RsxtIndex, RsxtIndex, index_shift); - blt(CCR0, LnotOOR); + blt(CR0, LnotOOR); // Index should be in R17_tos, array should be in R4_ARG2. mr_if_needed(R17_tos, Rindex); mr_if_needed(R4_ARG2, Rarray); @@ -681,18 +680,18 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, // Check if synchronized method or unlocking prevented by // JavaThread::do_not_unlock_if_synchronized flag. lbz(Rdo_not_unlock_flag, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); - lwz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); + lhz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method); li(R0, 0); stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); // reset flag push(state); // Skip if we don't have to unlock. - rldicl_(R0, Raccess_flags, 64-JVM_ACC_SYNCHRONIZED_BIT, 63); // Extract bit and compare to 0. - beq(CCR0, Lunlocked); + testbitdi(CR0, R0, Raccess_flags, JVM_ACC_SYNCHRONIZED_BIT); + beq(CR0, Lunlocked); - cmpwi(CCR0, Rdo_not_unlock_flag, 0); - bne(CCR0, Lno_unlock); + cmpwi(CR0, Rdo_not_unlock_flag, 0); + bne(CR0, Lno_unlock); } // Unlock @@ -706,8 +705,8 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, -(frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base ld(R0, BasicObjectLock::obj_offset(), Rmonitor_base); - cmpdi(CCR0, R0, 0); - bne(CCR0, Lunlock); + cmpdi(CR0, R0, 0); + bne(CR0, Lunlock); // If it's already unlocked, throw exception. if (throw_monitor_exception) { @@ -741,7 +740,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, addi(Rmonitor_base, Rmonitor_base, - frame::ijava_state_size); // Monitor base subf_(Riterations, R26_monitor, Rmonitor_base); - ble(CCR0, Lno_unlock); + ble(CR0, Lno_unlock); addi(Rcurrent_obj_addr, Rmonitor_base, in_bytes(BasicObjectLock::obj_offset()) - frame::interpreter_frame_monitor_size_in_bytes()); @@ -760,8 +759,8 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, bind(Lloop); // Check if current entry is used. - cmpdi(CCR0, Rcurrent_obj, 0); - bne(CCR0, Lexception); + cmpdi(CR0, Rcurrent_obj, 0); + bne(CR0, Lexception); // Preload next iteration's compare value. ld(Rcurrent_obj, 0, Rcurrent_obj_addr); addi(Rcurrent_obj_addr, Rcurrent_obj_addr, -delta); @@ -817,29 +816,29 @@ void InterpreterMacroAssembler::narrow(Register result) { Label notBool, notByte, notChar, done; // common case first - cmpwi(CCR0, ret_type, T_INT); - beq(CCR0, done); + cmpwi(CR0, ret_type, T_INT); + beq(CR0, done); - cmpwi(CCR0, ret_type, T_BOOLEAN); - bne(CCR0, notBool); + cmpwi(CR0, ret_type, T_BOOLEAN); + bne(CR0, notBool); andi(result, result, 0x1); b(done); bind(notBool); - cmpwi(CCR0, ret_type, T_BYTE); - bne(CCR0, notByte); + cmpwi(CR0, ret_type, T_BYTE); + bne(CR0, notByte); extsb(result, result); b(done); bind(notByte); - cmpwi(CCR0, ret_type, T_CHAR); - bne(CCR0, notChar); + cmpwi(CR0, ret_type, T_CHAR); + bne(CR0, notChar); andi(result, result, 0xffff); b(done); bind(notChar); - // cmpwi(CCR0, ret_type, T_SHORT); // all that's left - // bne(CCR0, done); + // cmpwi(CR0, ret_type, T_SHORT); // all that's left + // bne(CR0, done); extsh(result, result); // Nothing to do for T_INT @@ -894,8 +893,8 @@ void InterpreterMacroAssembler::remove_activation(TosState state, // check if already enabled - if so no re-enabling needed assert(sizeof(StackOverflow::StackGuardState) == 4, "unexpected size"); lwz(R0, in_bytes(JavaThread::stack_guard_state_offset()), R16_thread); - cmpwi(CCR0, R0, StackOverflow::stack_guard_enabled); - beq_predict_taken(CCR0, no_reserved_zone_enabling); + cmpwi(CR0, R0, StackOverflow::stack_guard_enabled); + beq_predict_taken(CR0, no_reserved_zone_enabling); // Compare frame pointers. There is no good stack pointer, as with stack // frame compression we can get different SPs when we do calls. A subsequent @@ -903,8 +902,8 @@ void InterpreterMacroAssembler::remove_activation(TosState state, // inner call of the method annotated with ReservedStack. ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread); ld_ptr(R11_scratch1, _abi0(callers_sp), R1_SP); // Load frame pointer. - cmpld(CCR0, R11_scratch1, R0); - blt_predict_taken(CCR0, no_reserved_zone_enabling); + cmpld(CR0, R11_scratch1, R0); + blt_predict_taken(CR0, no_reserved_zone_enabling); // Enable reserved zone again, throw stack overflow exception. call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread); @@ -962,8 +961,8 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp, object); lbz(tmp, in_bytes(Klass::misc_flags_offset()), tmp); - testbitdi(CCR0, R0, tmp, exact_log2(KlassFlags::_misc_is_value_based_class)); - bne(CCR0, slow_case); + testbitdi(CR0, R0, tmp, exact_log2(KlassFlags::_misc_is_value_based_class)); + bne(CR0, slow_case); } if (LockingMode == LM_LIGHTWEIGHT) { @@ -990,8 +989,8 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); // Must fence, otherwise, preceding store(s) may float below cmpxchg. - // CmpxchgX sets CCR0 to cmpX(current, displaced). - cmpxchgd(/*flag=*/CCR0, + // CmpxchgX sets CR0 to cmpX(current, displaced). + cmpxchgd(/*flag=*/CR0, /*current_value=*/current_header, /*compare_value=*/header, /*exchange_value=*/monitor, /*where=*/object_mark_addr, @@ -1022,7 +1021,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { and_(R0/*==0?*/, current_header, tmp); // If condition is true we are done and hence we can store 0 in the displaced // header indicating it is a recursive lock. - bne(CCR0, slow_case); + bne(CR0, slow_case); std(R0/*==0!*/, mark_offset, monitor); b(count_locking); } @@ -1088,8 +1087,8 @@ void InterpreterMacroAssembler::unlock_object(Register monitor) { BasicLock::displaced_header_offset_in_bytes(), monitor); // If the displaced header is zero, we have a recursive unlock. - cmpdi(CCR0, header, 0); - beq(CCR0, free_slot); // recursive unlock + cmpdi(CR0, header, 0); + beq(CR0, free_slot); // recursive unlock } // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { @@ -1109,8 +1108,8 @@ void InterpreterMacroAssembler::unlock_object(Register monitor) { // We have the displaced header in displaced_header. If the lock is still // lightweight, it will contain the monitor address and we'll store the // displaced header back into the object's mark word. - // CmpxchgX sets CCR0 to cmpX(current, monitor). - cmpxchgd(/*flag=*/CCR0, + // CmpxchgX sets CR0 to cmpX(current, monitor). + cmpxchgd(/*flag=*/CR0, /*current_value=*/current_header, /*compare_value=*/monitor, /*exchange_value=*/header, /*where=*/object_mark_addr, @@ -1171,8 +1170,8 @@ void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, R // compiled code in threads for which the event is enabled. Check here for // interp_only_mode if these events CAN be enabled. Label done; - cmpwi(CCR0, Rinterp_only, 0); - beq(CCR0, done); + cmpwi(CR0, Rinterp_only, 0); + beq(CR0, done); ld(Rtarget_addr, in_bytes(Method::interpreter_entry_offset()), Rtarget_method); align(32, 12); bind(done); @@ -1181,8 +1180,8 @@ void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, R #ifdef ASSERT { Label Lok; - cmpdi(CCR0, Rtarget_addr, 0); - bne(CCR0, Lok); + cmpdi(CR0, Rtarget_addr, 0); + bne(CR0, Lok); stop("null entry point"); bind(Lok); } @@ -1212,7 +1211,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, R sldi(Rscratch1, Rscratch1, Interpreter::logStackElementSize); add(Rscratch1, Rscratch1, Rscratch2); // Rscratch2 contains fp // Compare sender_sp with the derelativized top_frame_sp - cmpd(CCR0, R21_sender_SP, Rscratch1); + cmpd(CR0, R21_sender_SP, Rscratch1); asm_assert_eq("top_frame_sp incorrect"); #endif @@ -1235,8 +1234,8 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { // Test ImethodDataPtr. If it is null, continue at the specified label. void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) { assert(ProfileInterpreter, "must be profiling interpreter"); - cmpdi(CCR0, R28_mdx, 0); - beq(CCR0, zero_continue); + cmpdi(CR0, R28_mdx, 0); + beq(CR0, zero_continue); } void InterpreterMacroAssembler::verify_method_data_pointer() { @@ -1251,8 +1250,8 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { ld(R12_scratch2, in_bytes(Method::const_offset()), R19_method); addi(R11_scratch1, R11_scratch1, in_bytes(ConstMethod::codes_offset())); add(R11_scratch1, R12_scratch2, R12_scratch2); - cmpd(CCR0, R11_scratch1, R14_bcp); - beq(CCR0, verify_continue); + cmpd(CR0, R11_scratch1, R14_bcp); + beq(CR0, verify_continue); call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp ), R19_method, R14_bcp, R28_mdx); @@ -1335,8 +1334,8 @@ void InterpreterMacroAssembler::test_mdp_data_at(int offset, assert(ProfileInterpreter, "must be profiling interpreter"); ld(test_out, offset, R28_mdx); - cmpd(CCR0, value, test_out); - bne(CCR0, not_equal_continue); + cmpd(CR0, value, test_out); + bne(CR0, not_equal_continue); } // Update the method data pointer by the displacement located at some fixed @@ -1492,8 +1491,8 @@ void InterpreterMacroAssembler::profile_virtual_call(Register Rreceiver, Label skip_receiver_profile; if (receiver_can_be_null) { Label not_null; - cmpdi(CCR0, Rreceiver, 0); - bne(CCR0, not_null); + cmpdi(CR0, Rreceiver, 0); + bne(CR0, not_null); // We are making a call. Increment the count for null receiver. increment_mdp_data_at(in_bytes(CounterData::count_offset()), Rscratch1, Rscratch2); b(skip_receiver_profile); @@ -1682,8 +1681,8 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (start_row == last_row) { // The only thing left to do is handle the null case. // Scratch1 contains test_out from test_mdp_data_at. - cmpdi(CCR0, scratch1, 0); - beq(CCR0, found_null); + cmpdi(CR0, scratch1, 0); + beq(CR0, found_null); // Receiver did not match any saved receiver and there is no empty row for it. // Increment total counter to indicate polymorphic case. increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2); @@ -1692,8 +1691,8 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( break; } // Since null is rare, make it be the branch-taken case. - cmpdi(CCR0, scratch1, 0); - beq(CCR0, found_null); + cmpdi(CR0, scratch1, 0); + beq(CR0, found_null); // Put all the "Case 3" tests here. record_klass_in_profile_helper(receiver, scratch1, scratch2, start_row + 1, done); @@ -1735,27 +1734,27 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr ld(tmp, mdo_addr_offs, mdo_addr_base); // Set null_seen if obj is 0. - cmpdi(CCR0, obj, 0); + cmpdi(CR0, obj, 0); ori(R0, tmp, TypeEntries::null_seen); - beq(CCR0, do_update); + beq(CR0, do_update); load_klass(klass, obj); clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask)); // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask); - cmpd(CCR1, R0, klass); + cmpd(CR1, R0, klass); // Klass seen before, nothing to do (regardless of unknown bit). - //beq(CCR1, do_nothing); + //beq(CR1, do_nothing); andi_(R0, tmp, TypeEntries::type_unknown); // Already unknown. Nothing to do anymore. - //bne(CCR0, do_nothing); - crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne - beq(CCR0, do_nothing); + //bne(CR0, do_nothing); + crorc(CR0, Assembler::equal, CR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne + beq(CR0, do_nothing); clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0). - beq(CCR0, do_update); // First time here. Set profile type. + beq(CR0, do_update); // First time here. Set profile type. // Different than before. Cannot keep accurate profile. ori(R0, tmp, TypeEntries::type_unknown); @@ -1786,8 +1785,8 @@ void InterpreterMacroAssembler::profile_arguments_type(Register callee, in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx); - cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); - bne(CCR0, profile_continue); + cmpwi(CR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); + bne(CR0, profile_continue); if (MethodData::profile_arguments()) { Label done; @@ -1798,9 +1797,9 @@ void InterpreterMacroAssembler::profile_arguments_type(Register callee, if (i > 0 || MethodData::profile_return()) { // If return value type is profiled we may have no argument to profile. ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx); - cmpdi(CCR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count()); + cmpdi(CR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count()); addi(tmp1, tmp1, -i*TypeStackSlotEntries::per_arg_count()); - blt(CCR0, done); + blt(CR0, done); } ld(tmp1, in_bytes(Method::const_offset()), callee); lhz(tmp1, in_bytes(ConstMethod::size_of_parameters_offset()), tmp1); @@ -1866,12 +1865,12 @@ void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, // length. lbz(tmp1, 0, R14_bcp); lbz(tmp2, in_bytes(Method::intrinsic_id_offset()), R19_method); - cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic); - cmpwi(CCR1, tmp1, Bytecodes::_invokehandle); - cror(CCR0, Assembler::equal, CCR1, Assembler::equal); - cmpwi(CCR1, tmp2, static_cast(vmIntrinsics::_compiledLambdaForm)); - cror(CCR0, Assembler::equal, CCR1, Assembler::equal); - bne(CCR0, profile_continue); + cmpwi(CR0, tmp1, Bytecodes::_invokedynamic); + cmpwi(CR1, tmp1, Bytecodes::_invokehandle); + cror(CR0, Assembler::equal, CR1, Assembler::equal); + cmpwi(CR1, tmp2, static_cast(vmIntrinsics::_compiledLambdaForm)); + cror(CR0, Assembler::equal, CR1, Assembler::equal); + bne(CR0, profile_continue); } profile_obj_type(ret, R28_mdx, -in_bytes(ReturnTypeEntry::size()), tmp1, tmp2); @@ -1891,8 +1890,8 @@ void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register // Load the offset of the area within the MDO used for // parameters. If it's negative we're not profiling any parameters. lwz(tmp1, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), R28_mdx); - cmpwi(CCR0, tmp1, 0); - blt(CCR0, profile_continue); + cmpwi(CR0, tmp1, 0); + blt(CR0, profile_continue); // Compute a pointer to the area for parameters from the offset // and move the pointer to the slot for the last @@ -1937,9 +1936,9 @@ void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register // Go to next parameter. int delta = TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base); - cmpdi(CCR0, entry_offset, off_base + delta); + cmpdi(CR0, entry_offset, off_base + delta); addi(entry_offset, entry_offset, -delta); - bge(CCR0, loop); + bge(CR0, loop); align(32, 12); bind(profile_continue); @@ -1976,7 +1975,7 @@ void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Regist subf(n_slots, esp, R26_monitor); srdi_(n_slots, n_slots, LogBytesPerWord); // Compute number of slots to copy. assert(LogBytesPerWord == 3, "conflicts assembler instructions"); - beq(CCR0, copy_slot_finished); // Nothing to copy. + beq(CR0, copy_slot_finished); // Nothing to copy. mtctr(n_slots); @@ -2116,8 +2115,8 @@ void InterpreterMacroAssembler::check_and_forward_exception(Register Rscratch1, Label Ldone; // Get pending exception oop. ld(Rexception, thread_(pending_exception)); - cmpdi(CCR0, Rexception, 0); - beq(CCR0, Ldone); + cmpdi(CR0, Rexception, 0); + beq(CR0, Ldone); li(Rtmp, 0); mr_if_needed(R3, Rexception); std(Rtmp, thread_(pending_exception)); // Clear exception in thread @@ -2169,7 +2168,7 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result, address Label resume_pc, not_preempted; DEBUG_ONLY(ld(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread)); - DEBUG_ONLY(cmpdi(CCR0, R0, 0)); + DEBUG_ONLY(cmpdi(CR0, R0, 0)); asm_assert_eq("Should not have alternate return address set"); // Preserve 2 registers @@ -2187,8 +2186,8 @@ void InterpreterMacroAssembler::call_VM_preemptable(Register oop_result, address // Jump to handler if the call was preempted ld(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); - cmpdi(CCR0, R0, 0); - beq(CCR0, not_preempted); + cmpdi(CR0, R0, 0); + beq(CR0, not_preempted); mtlr(R0); li(R0, 0); std(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); @@ -2216,8 +2215,8 @@ void InterpreterMacroAssembler::restore_after_resume(Register fp) { { Label ok; ld(R12_scratch2, 0, R1_SP); // load fp - cmpd(CCR0, R12_scratch2, R11_scratch1); - beq(CCR0, ok); + cmpd(CR0, R12_scratch2, R11_scratch1); + beq(CR0, ok); stop(FILE_AND_LINE ": FP is expected in R11_scratch1"); bind(ok); } @@ -2299,8 +2298,8 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool { Label Lok; subf(R0, R1_SP, scratch); - cmpdi(CCR0, R0, frame::top_ijava_frame_abi_size + frame::ijava_state_size); - bge(CCR0, Lok); + cmpdi(CR0, R0, frame::top_ijava_frame_abi_size + frame::ijava_state_size); + bge(CR0, Lok); stop("frame too small (restore istate)"); bind(Lok); } @@ -2313,13 +2312,13 @@ void InterpreterMacroAssembler::get_method_counters(Register method, BLOCK_COMMENT("Load and ev. allocate counter object {"); Label has_counters; ld(Rcounters, in_bytes(Method::method_counters_offset()), method); - cmpdi(CCR0, Rcounters, 0); - bne(CCR0, has_counters); + cmpdi(CR0, Rcounters, 0); + bne(CR0, has_counters); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), method); ld(Rcounters, in_bytes(Method::method_counters_offset()), method); - cmpdi(CCR0, Rcounters, 0); - beq(CCR0, skip); // No MethodCounters, OutOfMemory. + cmpdi(CR0, Rcounters, 0); + beq(CR0, skip); // No MethodCounters, OutOfMemory. BLOCK_COMMENT("} Load and ev. allocate counter object"); bind(has_counters); @@ -2399,7 +2398,7 @@ void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Regis const int log2_bytecode_size_limit = 16; srdi_(Rtmp, reg, log2_bytecode_size_limit); - bne(CCR0, test); + bne(CR0, test); address fd = CAST_FROM_FN_PTR(address, verify_return_address); const int nbytes_save = MacroAssembler::num_volatile_regs * 8; @@ -2443,8 +2442,8 @@ void InterpreterMacroAssembler::notify_method_entry() { Label jvmti_post_done; lwz(R0, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); - cmpwi(CCR0, R0, 0); - beq(CCR0, jvmti_post_done); + cmpwi(CR0, R0, 0); + beq(CR0, jvmti_post_done); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry)); bind(jvmti_post_done); @@ -2477,8 +2476,8 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, TosSta Label jvmti_post_done; lwz(R0, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); - cmpwi(CCR0, R0, 0); - beq(CCR0, jvmti_post_done); + cmpwi(CR0, R0, 0); + beq(CR0, jvmti_post_done); if (!is_native_method) { push(state); } // Expose tos to GC. call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit), check_exceptions); if (!is_native_method) { pop(state); } diff --git a/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp b/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp index e2043db71004b..dd2503bd54b8b 100644 --- a/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp +++ b/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" @@ -104,9 +103,9 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { Label do_null; if (do_null_check) { __ ld(R0, locals_j_arg_at(offset())); - __ cmpdi(CCR0, R0, 0); + __ cmpdi(CR0, R0, 0); __ li(r, 0); - __ beq(CCR0, do_null); + __ beq(CR0, do_null); } __ addir(r, locals_j_arg_at(offset())); __ bind(do_null); diff --git a/src/hotspot/cpu/ppc/jniFastGetField_ppc.cpp b/src/hotspot/cpu/ppc/jniFastGetField_ppc.cpp index 819ecaf550e38..1c48ee4412ec7 100644 --- a/src/hotspot/cpu/ppc/jniFastGetField_ppc.cpp +++ b/src/hotspot/cpu/ppc/jniFastGetField_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2019 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -76,7 +75,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { __ ld(Rcounter, counter_offs, Rcounter_addr); __ andi_(R0, Rcounter, 1); - __ bne(CCR0, slow); + __ bne(CR0, slow); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { // Field may be volatile. @@ -92,8 +91,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { int fac_offs = __ load_const_optimized(Rtmp, JvmtiExport::get_field_access_count_addr(), R0, true); __ lwa(Rtmp, fac_offs, Rtmp); - __ cmpwi(CCR0, Rtmp, 0); - __ bne(CCR0, slow); + __ cmpwi(CR0, Rtmp, 0); + __ bne(CR0, slow); } BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); @@ -119,8 +118,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { // Order preceding load(s) wrt. succeeding check (LoadStore for volatile field). if (is_fp) { Label next; - __ fcmpu(CCR0, F1_RET, F1_RET); - __ bne(CCR0, next); + __ fcmpu(CR0, F1_RET, F1_RET); + __ bne(CR0, next); __ bind(next); } else { __ twi_0(Rtmp); @@ -128,8 +127,8 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { __ isync(); __ ld(R0, counter_offs, Rcounter_addr); - __ cmpd(CCR0, R0, Rcounter); - __ bne(CCR0, slow); + __ cmpd(CR0, R0, Rcounter); + __ bne(CR0, slow); if (!is_fp) { __ mr(R3_RET, Rtmp); diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 971ed99f9eb50..6bdb4f8026643 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "compiler/disassembler.hpp" @@ -1304,8 +1303,8 @@ int MacroAssembler::ic_check(int end_alignment) { mtctr(tmp1); if (!implicit_null_checks_available) { - cmpdi(CCR0, receiver, 0); - beqctr(CCR0); + cmpdi(CR0, receiver, 0); + beqctr(CR0); } if (UseCompressedClassPointers) { lwz(tmp1, oopDesc::klass_offset_in_bytes(), receiver); @@ -1313,8 +1312,8 @@ int MacroAssembler::ic_check(int end_alignment) { ld(tmp1, oopDesc::klass_offset_in_bytes(), receiver); } ld(tmp2, in_bytes(CompiledICData::speculated_klass_offset()), data); - cmpd(CCR0, tmp1, tmp2); - bnectr(CCR0); + cmpd(CR0, tmp1, tmp2); + bnectr(CR0); } assert((offset() % end_alignment) == 0, "Misaligned verified entry point"); @@ -1528,8 +1527,8 @@ void MacroAssembler::reserved_stack_check(Register return_pc) { Label no_reserved_zone_enabling; ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread); - cmpld(CCR0, R1_SP, R0); - blt_predict_taken(CCR0, no_reserved_zone_enabling); + cmpld(CR0, R1_SP, R0); + blt_predict_taken(CR0, no_reserved_zone_enabling); // Enable reserved zone again, throw stack overflow exception. push_frame_reg_args(0, R0); @@ -1552,9 +1551,9 @@ void MacroAssembler::getandsetd(Register dest_current_value, Register exchange_v ldarx(dest_current_value, addr_base, cmpxchgx_hint); stdcx_(exchange_value, addr_base); if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0. + bne_predict_not_taken(CR0, retry); // StXcx_ sets CR0. } else { - bne( CCR0, retry); // StXcx_ sets CCR0. + bne( CR0, retry); // StXcx_ sets CR0. } } @@ -1566,9 +1565,9 @@ void MacroAssembler::getandaddd(Register dest_current_value, Register inc_value, add(tmp, dest_current_value, inc_value); stdcx_(tmp, addr_base); if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0. + bne_predict_not_taken(CR0, retry); // StXcx_ sets CR0. } else { - bne( CCR0, retry); // StXcx_ sets CCR0. + bne( CR0, retry); // StXcx_ sets CR0. } } @@ -1639,9 +1638,9 @@ void MacroAssembler::atomic_get_and_modify_generic(Register dest_current_value, } if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0. + bne_predict_not_taken(CR0, retry); // StXcx_ sets CR0. } else { - bne( CCR0, retry); // StXcx_ sets CCR0. + bne( CR0, retry); // StXcx_ sets CR0. } // l?arx zero-extends, but Java wants byte/short values sign-extended. @@ -1745,7 +1744,7 @@ void MacroAssembler::cmpxchg_generic(ConditionRegister flag, Register dest_curre bool preset_result_reg = (int_flag_success != dest_current_value && int_flag_success != compare_value.register_or_noreg() && int_flag_success != exchange_value && int_flag_success != addr_base && int_flag_success != tmp1 && int_flag_success != tmp2); - assert(!weak || flag == CCR0, "weak only supported with CCR0"); + assert(!weak || flag == CR0, "weak only supported with CR0"); assert(int_flag_success == noreg || failed_ext == nullptr, "cannot have both"); assert(size == 1 || size == 2 || size == 4, "unsupported"); @@ -1774,9 +1773,9 @@ void MacroAssembler::cmpxchg_generic(ConditionRegister flag, Register dest_curre retry, failed, cmpxchgx_hint, size); if (!weak || use_result_reg || failed_ext) { if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0. + bne_predict_not_taken(CR0, weak ? failed : retry); // StXcx_ sets CR0. } else { - bne( CCR0, weak ? failed : retry); // StXcx_ sets CCR0. + bne( CR0, weak ? failed : retry); // StXcx_ sets CR0. } } // fall through => (flag == eq), (dest_current_value == compare_value), (swapped) @@ -1838,7 +1837,7 @@ void MacroAssembler::cmpxchgd(ConditionRegister flag, Register dest_current_valu bool use_result_reg = (int_flag_success!=noreg); bool preset_result_reg = (int_flag_success!=dest_current_value && int_flag_success!=compare_value.register_or_noreg() && int_flag_success!=exchange_value && int_flag_success!=addr_base); - assert(!weak || flag == CCR0, "weak only supported with CCR0"); + assert(!weak || flag == CR0, "weak only supported with CR0"); assert(int_flag_success == noreg || failed_ext == nullptr, "cannot have both"); if (use_result_reg && preset_result_reg) { @@ -1871,9 +1870,9 @@ void MacroAssembler::cmpxchgd(ConditionRegister flag, Register dest_current_valu stdcx_(exchange_value, addr_base); if (!weak || use_result_reg || failed_ext) { if (UseStaticBranchPredictionInCompareAndSwapPPC64) { - bne_predict_not_taken(CCR0, weak ? failed : retry); // stXcx_ sets CCR0 + bne_predict_not_taken(CR0, weak ? failed : retry); // stXcx_ sets CR0 } else { - bne( CCR0, weak ? failed : retry); // stXcx_ sets CCR0 + bne( CR0, weak ? failed : retry); // stXcx_ sets CR0 } } @@ -1961,12 +1960,12 @@ void MacroAssembler::lookup_interface_method(Register recv_klass, // Check that this entry is non-null. A null entry means that // the receiver class doesn't implement the interface, and wasn't the // same as when the caller was compiled. - cmpd(CCR0, temp2, intf_klass); + cmpd(CR0, temp2, intf_klass); if (peel) { - beq(CCR0, found_method); + beq(CR0, found_method); } else { - bne(CCR0, search); + bne(CR0, search); // (invert the test to fall through to found_method...) } @@ -1974,8 +1973,8 @@ void MacroAssembler::lookup_interface_method(Register recv_klass, bind(search); - cmpdi(CCR0, temp2, 0); - beq(CCR0, L_no_such_interface); + cmpdi(CR0, temp2, 0); + beq(CR0, L_no_such_interface); addi(scan_temp, scan_temp, scan_step); } @@ -2045,8 +2044,8 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, // We move this check to the front of the fast path because many // type checks are in fact trivially successful in this manner, // so we get a nicely predicted branch right at the start of the check. - cmpd(CCR0, sub_klass, super_klass); - beq(CCR0, *L_success); + cmpd(CR0, sub_klass, super_klass); + beq(CR0, *L_success); // Check the supertype display: if (must_load_sco) { @@ -2059,7 +2058,7 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, // The loaded value is the offset from Klass. ld(cached_super, super_check_offset, sub_klass); - cmpd(CCR0, cached_super, super_klass); + cmpd(CR0, cached_super, super_klass); // This check has worked decisively for primary supers. // Secondary supers are sought in the super_cache ('super_cache_addr'). @@ -2075,29 +2074,29 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, #define FINAL_JUMP(label) if (&(label) != &L_fallthrough) { b(label); } if (super_check_offset.is_register()) { - beq(CCR0, *L_success); - cmpwi(CCR0, super_check_offset.as_register(), sc_offset); + beq(CR0, *L_success); + cmpwi(CR0, super_check_offset.as_register(), sc_offset); if (L_failure == &L_fallthrough) { - beq(CCR0, *L_slow_path); + beq(CR0, *L_slow_path); } else { - bne(CCR0, *L_failure); + bne(CR0, *L_failure); FINAL_JUMP(*L_slow_path); } } else { if (super_check_offset.as_constant() == sc_offset) { // Need a slow path; fast failure is impossible. if (L_slow_path == &L_fallthrough) { - beq(CCR0, *L_success); + beq(CR0, *L_success); } else { - bne(CCR0, *L_slow_path); + bne(CR0, *L_slow_path); FINAL_JUMP(*L_success); } } else { // No slow path; it's a fast decision. if (L_failure == &L_fallthrough) { - beq(CCR0, *L_success); + beq(CR0, *L_success); } else { - bne(CCR0, *L_failure); + bne(CR0, *L_failure); FINAL_JUMP(*L_success); } } @@ -2107,16 +2106,17 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, #undef FINAL_JUMP } -void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, - Register super_klass, - Register temp1_reg, - Register temp2_reg, - Label* L_success, - Register result_reg) { +void MacroAssembler::check_klass_subtype_slow_path_linear(Register sub_klass, + Register super_klass, + Register temp1_reg, + Register temp2_reg, + Label* L_success, + Register result_reg) { const Register array_ptr = temp1_reg; // current value from cache array const Register temp = temp2_reg; assert_different_registers(sub_klass, super_klass, array_ptr, temp); + assert(L_success == nullptr || result_reg == noreg, "can't have both"); int source_offset = in_bytes(Klass::secondary_supers_offset()); int target_offset = in_bytes(Klass::secondary_super_cache_offset()); @@ -2130,32 +2130,125 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, // TODO: PPC port: assert(4 == arrayOopDesc::length_length_in_bytes(), "precondition violated."); lwz(temp, length_offset, array_ptr); - cmpwi(CCR0, temp, 0); - beq(CCR0, result_reg!=noreg ? failure : fallthru); // length 0 + cmpwi(CR0, temp, 0); + beq(CR0, (L_success == nullptr) ? failure : fallthru); // indicate failure if length 0 mtctr(temp); // load ctr bind(loop); // Oops in table are NO MORE compressed. ld(temp, base_offset, array_ptr); - cmpd(CCR0, temp, super_klass); - beq(CCR0, hit); + cmpd(CR0, temp, super_klass); + beq(CR0, hit); addi(array_ptr, array_ptr, BytesPerWord); bdnz(loop); bind(failure); - if (result_reg!=noreg) li(result_reg, 1); // load non-zero result (indicates a miss) + if (result_reg != noreg) { + li(result_reg, 1); // load non-zero result (indicates a miss) + } else if (L_success == nullptr) { + crandc(CR0, Assembler::equal, CR0, Assembler::equal); // miss indicated by CR0.ne + } b(fallthru); bind(hit); std(super_klass, target_offset, sub_klass); // save result to cache - if (result_reg != noreg) { li(result_reg, 0); } // load zero result (indicates a hit) - if (L_success != nullptr) { b(*L_success); } - else if (result_reg == noreg) { blr(); } // return with CR0.eq if neither label nor result reg provided + if (result_reg != noreg) { + li(result_reg, 0); // load zero result (indicates a hit) + } else if (L_success != nullptr) { + b(*L_success); + } bind(fallthru); } +Register MacroAssembler::allocate_if_noreg(Register r, + RegSetIterator &available_regs, + RegSet ®s_to_push) { + if (!r->is_valid()) { + r = *available_regs++; + regs_to_push += r; + } + return r; +} + +void MacroAssembler::push_set(RegSet set) +{ + int spill_offset = 0; + for (RegSetIterator it = set.begin(); *it != noreg; ++it) { + spill_offset += wordSize; + std(*it, -spill_offset, R1_SP); + } +} + +void MacroAssembler::pop_set(RegSet set) +{ + int spill_offset = 0; + for (RegSetIterator it = set.begin(); *it != noreg; ++it) { + spill_offset += wordSize; + ld(*it, -spill_offset, R1_SP); + } +} + +void MacroAssembler::check_klass_subtype_slow_path_table(Register sub_klass, + Register super_klass, + Register temp1_reg, + Register temp2_reg, + Label* L_success, + Register result_reg) { + RegSet temps = RegSet::of(temp1_reg, temp2_reg); + + assert_different_registers(sub_klass, super_klass, temp1_reg, temp2_reg, result_reg, R0); + + Register temp3_reg = noreg, temp4_reg = noreg; + bool result_reg_provided = (result_reg != noreg); // otherwise, result will be in CR0 + + BLOCK_COMMENT("check_klass_subtype_slow_path_table"); + + RegSetIterator available_regs + = (RegSet::range(R2, R12) - temps - sub_klass - super_klass).begin(); + + RegSet pushed_regs; + + temp1_reg = allocate_if_noreg(temp1_reg, available_regs, pushed_regs); + temp2_reg = allocate_if_noreg(temp2_reg, available_regs, pushed_regs); + temp3_reg = allocate_if_noreg(temp3_reg, available_regs, pushed_regs); + temp4_reg = allocate_if_noreg(temp4_reg, available_regs, pushed_regs); + result_reg = allocate_if_noreg(result_reg, available_regs, pushed_regs); + + push_set(pushed_regs); + + lookup_secondary_supers_table_var(sub_klass, super_klass, + temp1_reg, temp2_reg, temp3_reg, temp4_reg, + result_reg); + + if (L_success != nullptr || !result_reg_provided) { + // result_reg may get overwritten by pop_set + cmpdi(CR0, result_reg, 0); + } + + // Unspill the temp. registers: + pop_set(pushed_regs); + + if (L_success != nullptr) { + beq(CR0, *L_success); + } +} + +void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, + Register super_klass, + Register temp1_reg, + Register temp2_reg, + Label* L_success, + Register result_reg) { + if (UseSecondarySupersTable) { + check_klass_subtype_slow_path_table(sub_klass, super_klass, temp1_reg, temp2_reg, L_success, result_reg); + } else { + if (temp2_reg == noreg) temp2_reg = R0; + check_klass_subtype_slow_path_linear(sub_klass, super_klass, temp1_reg, temp2_reg, L_success, result_reg); + } +} + // Try fast path, then go to slow one if not successful void MacroAssembler::check_klass_subtype(Register sub_klass, Register super_klass, @@ -2172,27 +2265,28 @@ void MacroAssembler::check_klass_subtype(Register sub_klass, // generic (count must be >0) // iff found: CR0 eq, scratch == 0 void MacroAssembler::repne_scan(Register addr, Register value, Register count, Register scratch) { - Label Lloop, Lexit; + Label Lloop, Lafter_loop, Lexit; -#ifdef ASSERT - { - Label ok; - cmpdi(CCR0, count, 0); - bgt(CCR0, ok); - stop("count must be positive"); - bind(ok); - } -#endif - - mtctr(count); + srdi_(scratch, count, 1); + beq(CR0, Lafter_loop); + mtctr(scratch); - bind(Lloop); - ld(scratch, 0 , addr); + bind(Lloop); // 2x unrolled + ld(scratch, 0, addr); + xor_(scratch, scratch, value); + beq(CR0, Lexit); + ld(scratch, 8, addr); xor_(scratch, scratch, value); - beq(CCR0, Lexit); - addi(addr, addr, wordSize); + beq(CR0, Lexit); + addi(addr, addr, 2 * wordSize); bdnz(Lloop); + bind(Lafter_loop); + andi_(scratch, count, 1); + beq(CR0, Lexit); // if taken: CR0 eq and scratch == 0 + ld(scratch, 0, addr); + xor_(scratch, scratch, value); + bind(Lexit); } @@ -2208,19 +2302,19 @@ do { \ (result == R8_ARG6 || result == noreg), "registers must match ppc64.ad"); \ } while(0) -void MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, - Register r_super_klass, - Register temp1, - Register temp2, - Register temp3, - Register temp4, - Register result, - u1 super_klass_slot) { +void MacroAssembler::lookup_secondary_supers_table_const(Register r_sub_klass, + Register r_super_klass, + Register temp1, + Register temp2, + Register temp3, + Register temp4, + Register result, + u1 super_klass_slot) { assert_different_registers(r_sub_klass, r_super_klass, temp1, temp2, temp3, temp4, result); Label L_done; - BLOCK_COMMENT("lookup_secondary_supers_table {"); + BLOCK_COMMENT("lookup_secondary_supers_table_const {"); const Register r_array_base = temp1, @@ -2228,7 +2322,7 @@ void MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, r_array_index = temp3, r_bitmap = temp4; - LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS; + LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS; // Required for stub call below. ld(r_bitmap, in_bytes(Klass::secondary_supers_bitmap_offset()), r_sub_klass); @@ -2243,7 +2337,7 @@ void MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, li(result, 1); // failure // We test the MSB of r_array_index, i.e. its sign bit - bge(CCR0, L_done); + bge(CR0, L_done); // We will consult the secondary-super array. ld(r_array_base, in_bytes(Klass::secondary_supers_offset()), r_sub_klass); @@ -2267,11 +2361,11 @@ void MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, } xor_(result, result, r_super_klass); - beq(CCR0, L_done); // Found a match (result == 0) + beq(CR0, L_done); // Found a match (result == 0) // Is there another entry to check? Consult the bitmap. - testbitdi(CCR0, /* temp */ r_array_length, r_bitmap, (bit + 1) & Klass::SECONDARY_SUPERS_TABLE_MASK); - beq(CCR0, L_done); // (result != 0) + testbitdi(CR0, /* temp */ r_array_length, r_bitmap, (bit + 1) & Klass::SECONDARY_SUPERS_TABLE_MASK); + beq(CR0, L_done); // (result != 0) // Linear probe. Rotate the bitmap so that the next bit to test is // in Bit 2 for the look-ahead check in the slow path. @@ -2290,7 +2384,90 @@ void MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, bctrl(); bind(L_done); - BLOCK_COMMENT("} lookup_secondary_supers_table"); + BLOCK_COMMENT("} lookup_secondary_supers_table_const"); + + if (VerifySecondarySupers) { + verify_secondary_supers_table(r_sub_klass, r_super_klass, result, + temp1, temp2, temp3); + } +} + +// At runtime, return 0 in result if r_super_klass is a superclass of +// r_sub_klass, otherwise return nonzero. Use this version of +// lookup_secondary_supers_table() if you don't know ahead of time +// which superclass will be searched for. Used by interpreter and +// runtime stubs. It is larger and has somewhat greater latency than +// the version above, which takes a constant super_klass_slot. +void MacroAssembler::lookup_secondary_supers_table_var(Register r_sub_klass, + Register r_super_klass, + Register temp1, + Register temp2, + Register temp3, + Register temp4, + Register result) { + assert_different_registers(r_sub_klass, r_super_klass, temp1, temp2, temp3, temp4, result, R0); + + Label L_done; + + BLOCK_COMMENT("lookup_secondary_supers_table_var {"); + + const Register + r_array_base = temp1, + slot = temp2, + r_array_index = temp3, + r_bitmap = temp4; + + lbz(slot, in_bytes(Klass::hash_slot_offset()), r_super_klass); + ld(r_bitmap, in_bytes(Klass::secondary_supers_bitmap_offset()), r_sub_klass); + + li(result, 1); // Make sure that result is nonzero if the test below misses. + + // First check the bitmap to see if super_klass might be present. If + // the bit is zero, we are certain that super_klass is not one of + // the secondary supers. + xori(R0, slot, Klass::SECONDARY_SUPERS_TABLE_SIZE - 1); // slot ^ 63 === 63 - slot (mod 64) + sld_(r_array_index, r_bitmap, R0); // shift left by 63-slot + + // We test the MSB of r_array_index, i.e. its sign bit + bge(CR0, L_done); + + // We will consult the secondary-super array. + ld(r_array_base, in_bytes(Klass::secondary_supers_offset()), r_sub_klass); + + // The value i in r_array_index is >= 1, so even though r_array_base + // points to the length, we don't need to adjust it to point to the data. + assert(Array::base_offset_in_bytes() == wordSize, "Adjust this code"); + assert(Array::length_offset_in_bytes() == 0, "Adjust this code"); + + // Get the first array index that can contain super_klass into r_array_index. + popcntd(r_array_index, r_array_index); + + // NB! r_array_index is off by 1. It is compensated by keeping r_array_base off by 1 word. + sldi(r_array_index, r_array_index, LogBytesPerWord); // scale + + ldx(R0, r_array_base, r_array_index); + xor_(result, R0, r_super_klass); + beq(CR0, L_done); // found a match, result is 0 in this case + + // Linear probe. Rotate the bitmap so that the next bit to test is + // in Bit 1. + neg(R0, slot); // rotate right + rldcl(r_bitmap, r_bitmap, R0, 0); + Register temp = slot; + andi_(temp, r_bitmap, 2); + beq(CR0, L_done); // fail (result != 0) + + // The slot we just inspected is at secondary_supers[r_array_index - 1]. + // The next slot to be inspected, by the logic we're about to call, + // is secondary_supers[r_array_index]. Bits 0 and 1 in the bitmap + // have been checked. + lookup_secondary_supers_table_slow_path(r_super_klass, r_array_base, r_array_index, + r_bitmap, result, temp); + // return whatever we got from slow path + + bind(L_done); + + BLOCK_COMMENT("} lookup_secondary_supers_table_var"); if (VerifySecondarySupers) { verify_secondary_supers_table(r_sub_klass, r_super_klass, result, @@ -2313,8 +2490,6 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl r_array_length = temp1, r_sub_klass = noreg; - LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS; - Label L_done; // Load the array length. @@ -2329,8 +2504,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl // The bitmap is full to bursting. // Implicit invariant: BITMAP_FULL implies (length > 0) - cmpwi(CCR0, r_array_length, (int32_t)Klass::SECONDARY_SUPERS_TABLE_SIZE - 2); - bgt(CCR0, L_huge); + cmpwi(CR0, r_array_length, (int32_t)Klass::SECONDARY_SUPERS_TABLE_SIZE - 2); + bgt(CR0, L_huge); // NB! Our caller has checked bits 0 and 1 in the bitmap. The // current slot (at secondary_supers[r_array_index]) has not yet @@ -2348,8 +2523,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl // We should only reach here after having found a bit in the bitmap. // Invariant: array_length == popcount(bitmap) Label ok; - cmpdi(CCR0, r_array_length, 0); - bgt(CCR0, ok); + cmpdi(CR0, r_array_length, 0); + bgt(CR0, ok); stop("array_length must be positive"); bind(ok); } @@ -2363,16 +2538,16 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl bind(L_loop); // Check for wraparound. - cmpd(CCR0, r_array_index, r_array_length); - isel_0(r_array_index, CCR0, Assembler::greater); + cmpd(CR0, r_array_index, r_array_length); + isel_0(r_array_index, CR0, Assembler::greater); ldx(result, r_array_base, r_array_index); xor_(result, result, r_super_klass); - beq(CCR0, L_done); // success (result == 0) + beq(CR0, L_done); // success (result == 0) // look-ahead check (Bit 2); result is non-zero - testbitdi(CCR0, R0, r_bitmap, 2); - beq(CCR0, L_done); // fail (result != 0) + testbitdi(CR0, R0, r_bitmap, 2); + beq(CR0, L_done); // fail (result != 0) rldicl(r_bitmap, r_bitmap, 64 - 1, 0); addi(r_array_index, r_array_index, BytesPerWord); @@ -2405,8 +2580,6 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass, r_array_index = temp3, r_bitmap = noreg; // unused - LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS; - BLOCK_COMMENT("verify_secondary_supers_table {"); Label passed, failure; @@ -2422,24 +2595,28 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass, normalize_bool(result, R0, true); const Register linear_result = r_array_index; // reuse li(linear_result, 1); - cmpdi(CCR0, r_array_length, 0); - ble(CCR0, failure); + cmpdi(CR0, r_array_length, 0); + ble(CR0, failure); repne_scan(r_array_base, r_super_klass, r_array_length, linear_result); bind(failure); // convert !=0 to 1 normalize_bool(linear_result, R0, true); - cmpd(CCR0, result, linear_result); - beq(CCR0, passed); + cmpd(CR0, result, linear_result); + beq(CR0, passed); + + // report fatal error and terminate VM + + // Argument shuffle. Using stack to avoid clashes. + std(r_super_klass, -8, R1_SP); + std(r_sub_klass, -16, R1_SP); + std(linear_result, -24, R1_SP); + mr_if_needed(R6_ARG4, result); + ld(R3_ARG1, -8, R1_SP); + ld(R4_ARG2, -16, R1_SP); + ld(R5_ARG3, -24, R1_SP); - assert_different_registers(R3_ARG1, r_sub_klass, linear_result, result); - mr_if_needed(R3_ARG1, r_super_klass); - assert_different_registers(R4_ARG2, linear_result, result); - mr_if_needed(R4_ARG2, r_sub_klass); - assert_different_registers(R5_ARG3, result); - neg(R5_ARG3, linear_result); - neg(R6_ARG4, result); const char* msg = "mismatch"; load_const_optimized(R7_ARG5, (intptr_t)msg, R0); call_VM_leaf(CAST_FROM_FN_PTR(address, Klass::on_secondary_supers_verification_failure)); @@ -2463,19 +2640,19 @@ void MacroAssembler::clinit_barrier(Register klass, Register thread, Label* L_fa // Fast path check: class is fully initialized lbz(R0, in_bytes(InstanceKlass::init_state_offset()), klass); // acquire by cmp-branch-isync if fully_initialized - cmpwi(CCR0, R0, InstanceKlass::fully_initialized); - bne(CCR0, L_check_thread); + cmpwi(CR0, R0, InstanceKlass::fully_initialized); + bne(CR0, L_check_thread); isync(); b(*L_fast_path); // Fast path check: current thread is initializer thread bind(L_check_thread); ld(R0, in_bytes(InstanceKlass::init_thread_offset()), klass); - cmpd(CCR0, thread, R0); + cmpd(CR0, thread, R0); if (L_slow_path == &L_fallthrough) { - beq(CCR0, *L_fast_path); + beq(CR0, *L_fast_path); } else if (L_fast_path == &L_fallthrough) { - bne(CCR0, *L_slow_path); + bne(CR0, *L_slow_path); } else { Unimplemented(); } @@ -2523,15 +2700,15 @@ void MacroAssembler::tlab_allocate( } else { add(new_top, obj, var_size_in_bytes); } - cmpld(CCR0, new_top, R0); - bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::greater), slow_case); + cmpld(CR0, new_top, R0); + bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::greater), slow_case); #ifdef ASSERT // make sure new free pointer is properly aligned { Label L; andi_(R0, new_top, MinObjAlignmentInBytesMask); - beq(CCR0, L); + beq(CR0, L); stop("updated TLAB free is not properly aligned"); bind(L); } @@ -2608,7 +2785,7 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register // Handle existing monitor. // The object has an existing monitor iff (mark & monitor_value) != 0. andi_(temp, displaced_header, markWord::monitor_value); - bne(CCR0, object_has_monitor); + bne(CR0, object_has_monitor); if (LockingMode == LM_MONITOR) { // Set NE to indicate 'failure' -> take slow-path. @@ -2654,10 +2831,10 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register // displaced header in the box, which indicates that it is a recursive lock. std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), box); - if (flag != CCR0) { - mcrf(flag, CCR0); + if (flag != CR0) { + mcrf(flag, CR0); } - beq(CCR0, success); + beq(CR0, success); b(failure); } @@ -2730,7 +2907,7 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe // The object has an existing monitor iff (mark & monitor_value) != 0. ld(current_header, oopDesc::mark_offset_in_bytes(), oop); andi_(R0, current_header, markWord::monitor_value); - bne(CCR0, object_has_monitor); + bne(CR0, object_has_monitor); if (LockingMode == LM_MONITOR) { // Set NE to indicate 'failure' -> take slow-path. @@ -2761,12 +2938,12 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe ld(displaced_header, in_bytes(ObjectMonitor::recursions_offset()), current_header); addic_(displaced_header, displaced_header, -1); - blt(CCR0, not_recursive); // Not recursive if negative after decrement. + blt(CR0, not_recursive); // Not recursive if negative after decrement. // Recursive unlock std(displaced_header, in_bytes(ObjectMonitor::recursions_offset()), current_header); - if (flag == CCR0) { // Otherwise, flag is already EQ, here. - crorc(CCR0, Assembler::equal, CCR0, Assembler::equal); // Set CCR0 EQ + if (flag == CR0) { // Otherwise, flag is already EQ, here. + crorc(CR0, Assembler::equal, CR0, Assembler::equal); // Set CR0 EQ } b(success); @@ -2825,7 +3002,7 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla Register tmp1, Register tmp2, Register tmp3) { assert_different_registers(obj, box, tmp1, tmp2, tmp3); assert(UseObjectMonitorTable || tmp3 == noreg, "tmp3 not needed"); - assert(flag == CCR0, "bad condition register"); + assert(flag == CR0, "bad condition register"); // Handle inflated monitor. Label inflated; @@ -2843,8 +3020,8 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla if (DiagnoseSyncOnValueBasedClasses != 0) { load_klass(tmp1, obj); lbz(tmp1, in_bytes(Klass::misc_flags_offset()), tmp1); - testbitdi(CCR0, R0, tmp1, exact_log2(KlassFlags::_misc_is_value_based_class)); - bne(CCR0, slow_path); + testbitdi(CR0, R0, tmp1, exact_log2(KlassFlags::_misc_is_value_based_class)); + bne(CR0, slow_path); } Register mark = tmp1; @@ -2858,8 +3035,8 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla // Check if lock-stack is full. lwz(top, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); - cmplwi(CCR0, top, LockStack::end_offset() - 1); - bgt(CCR0, slow_path); + cmplwi(CR0, top, LockStack::end_offset() - 1); + bgt(CR0, slow_path); // The underflow check is elided. The recursive check will always fail // when the lock stack is empty because of the _bad_oop_sentinel field. @@ -2867,15 +3044,15 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla // Check if recursive. subi(R0, top, oopSize); ldx(R0, R16_thread, R0); - cmpd(CCR0, obj, R0); - beq(CCR0, push); + cmpd(CR0, obj, R0); + beq(CR0, push); // Check for monitor (0b10) or locked (0b00). ld(mark, oopDesc::mark_offset_in_bytes(), obj); andi_(R0, mark, markWord::lock_mask_in_place); - cmpldi(CCR0, R0, markWord::unlocked_value); - bgt(CCR0, inflated); - bne(CCR0, slow_path); + cmpldi(CR0, R0, markWord::unlocked_value); + bgt(CR0, inflated); + bne(CR0, slow_path); // Not inflated. @@ -2915,8 +3092,8 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla const int num_unrolled = 2; for (int i = 0; i < num_unrolled; i++) { ld(R0, 0, cache_addr); - cmpd(CCR0, R0, obj); - beq(CCR0, monitor_found); + cmpd(CR0, R0, obj); + beq(CR0, monitor_found); addi(cache_addr, cache_addr, in_bytes(OMCache::oop_to_oop_difference())); } @@ -2927,14 +3104,14 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla // Check for match. ld(R0, 0, cache_addr); - cmpd(CCR0, R0, obj); - beq(CCR0, monitor_found); + cmpd(CR0, R0, obj); + beq(CR0, monitor_found); // Search until null encountered, guaranteed _null_sentinel at end. addi(cache_addr, cache_addr, in_bytes(OMCache::oop_to_oop_difference())); - cmpdi(CCR1, R0, 0); - bne(CCR1, loop); - // Cache Miss, CCR0.NE set from cmp above + cmpdi(CR1, R0, 0); + bne(CR1, loop); + // Cache Miss, CR0.NE set from cmp above b(slow_path); bind(monitor_found); @@ -2947,18 +3124,18 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla // Try to CAS owner (no owner => current thread's _monitor_owner_id). assert_different_registers(thread_id, monitor, owner_addr, box, R0); ld(thread_id, in_bytes(JavaThread::monitor_owner_id_offset()), R16_thread); - cmpxchgd(/*flag=*/CCR0, + cmpxchgd(/*flag=*/CR0, /*current_value=*/R0, /*compare_value=*/(intptr_t)0, /*exchange_value=*/thread_id, /*where=*/owner_addr, MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_acquire_lock()); - beq(CCR0, monitor_locked); + beq(CR0, monitor_locked); // Check if recursive. - cmpd(CCR0, R0, thread_id); - bne(CCR0, slow_path); + cmpd(CR0, R0, thread_id); + bne(CR0, slow_path); // Recursive. if (!UseObjectMonitorTable) { @@ -2984,13 +3161,13 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla #ifdef ASSERT // Check that locked label is reached with flag == EQ. Label flag_correct; - beq(CCR0, flag_correct); + beq(CR0, flag_correct); stop("Fast Lock Flag != EQ"); #endif bind(slow_path); #ifdef ASSERT // Check that slow_path label is reached with flag == NE. - bne(CCR0, flag_correct); + bne(CR0, flag_correct); stop("Fast Lock Flag != NE"); bind(flag_correct); #endif @@ -3000,7 +3177,7 @@ void MacroAssembler::compiler_fast_lock_lightweight_object(ConditionRegister fla void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister flag, Register obj, Register box, Register tmp1, Register tmp2, Register tmp3) { assert_different_registers(obj, tmp1, tmp2, tmp3); - assert(flag == CCR0, "bad condition register"); + assert(flag == CR0, "bad condition register"); // Handle inflated monitor. Label inflated, inflated_load_monitor; @@ -3020,9 +3197,9 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f lwz(top, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); subi(top, top, oopSize); ldx(t, R16_thread, top); - cmpd(CCR0, obj, t); + cmpd(CR0, obj, t); // Top of lock stack was not obj. Must be monitor. - bne(CCR0, inflated_load_monitor); + bne(CR0, inflated_load_monitor); // Pop lock-stack. DEBUG_ONLY(li(t, 0);) @@ -3035,8 +3212,8 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f // Check if recursive. subi(t, top, oopSize); ldx(t, R16_thread, t); - cmpd(CCR0, obj, t); - beq(CCR0, unlocked); + cmpd(CR0, obj, t); + beq(CR0, unlocked); // Not recursive. @@ -3044,16 +3221,16 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f ld(mark, oopDesc::mark_offset_in_bytes(), obj); andi_(t, mark, markWord::monitor_value); if (!UseObjectMonitorTable) { - bne(CCR0, inflated); + bne(CR0, inflated); } else { - bne(CCR0, push_and_slow); + bne(CR0, push_and_slow); } #ifdef ASSERT // Check header not unlocked (0b01). Label not_unlocked; andi_(t, mark, markWord::unlocked_value); - beq(CCR0, not_unlocked); + beq(CR0, not_unlocked); stop("lightweight_unlock already unlocked"); bind(not_unlocked); #endif @@ -3075,7 +3252,7 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f ld(mark, oopDesc::mark_offset_in_bytes(), obj); #ifdef ASSERT andi_(t, mark, markWord::monitor_value); - bne(CCR0, inflated); + bne(CR0, inflated); stop("Fast Unlock not monitor"); #endif @@ -3084,11 +3261,11 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f #ifdef ASSERT Label check_done; subi(top, top, oopSize); - cmplwi(CCR0, top, in_bytes(JavaThread::lock_stack_base_offset())); - blt(CCR0, check_done); + cmplwi(CR0, top, in_bytes(JavaThread::lock_stack_base_offset())); + blt(CR0, check_done); ldx(t, R16_thread, top); - cmpd(CCR0, obj, t); - bne(CCR0, inflated); + cmpd(CR0, obj, t); + bne(CR0, inflated); stop("Fast Unlock lock on stack"); bind(check_done); #endif @@ -3103,8 +3280,8 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f } else { ld(monitor, BasicLock::object_monitor_cache_offset_in_bytes(), box); // null check with Flags == NE, no valid pointer below alignof(ObjectMonitor*) - cmpldi(CCR0, monitor, checked_cast(alignof(ObjectMonitor*))); - blt(CCR0, slow_path); + cmpldi(CR0, monitor, checked_cast(alignof(ObjectMonitor*))); + blt(CR0, slow_path); } const Register recursions = tmp2; @@ -3113,11 +3290,11 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f // Check if recursive. ld(recursions, in_bytes(ObjectMonitor::recursions_offset()), monitor); addic_(recursions, recursions, -1); - blt(CCR0, not_recursive); + blt(CR0, not_recursive); // Recursive unlock. std(recursions, in_bytes(ObjectMonitor::recursions_offset()), monitor); - crorc(CCR0, Assembler::equal, CCR0, Assembler::equal); + crorc(CR0, Assembler::equal, CR0, Assembler::equal); b(unlocked); bind(not_recursive); @@ -3137,15 +3314,15 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f ld(t, in_bytes(ObjectMonitor::EntryList_offset()), monitor); ld(t2, in_bytes(ObjectMonitor::cxq_offset()), monitor); orr(t, t, t2); - cmpdi(CCR0, t, 0); - beq(CCR0, unlocked); // If so we are done. + cmpdi(CR0, t, 0); + beq(CR0, unlocked); // If so we are done. // Check if there is a successor. ld(t, in_bytes(ObjectMonitor::succ_offset()), monitor); - cmpdi(CCR0, t, 0); + cmpdi(CR0, t, 0); // Invert equal bit crnand(flag, Assembler::equal, flag, Assembler::equal); - beq(CCR0, unlocked); // If there is a successor we are done. + beq(CR0, unlocked); // If there is a successor we are done. // Save the monitor pointer in the current thread, so we can try // to reacquire the lock in SharedRuntime::monitor_exit_helper(). @@ -3158,13 +3335,13 @@ void MacroAssembler::compiler_fast_unlock_lightweight_object(ConditionRegister f #ifdef ASSERT // Check that unlocked label is reached with flag == EQ. Label flag_correct; - beq(CCR0, flag_correct); + beq(CR0, flag_correct); stop("Fast Lock Flag != EQ"); #endif bind(slow_path); #ifdef ASSERT // Check that slow_path label is reached with flag == NE. - bne(CCR0, flag_correct); + bne(CR0, flag_correct); stop("Fast Lock Flag != NE"); bind(flag_correct); #endif @@ -3181,21 +3358,21 @@ void MacroAssembler::safepoint_poll(Label& slow_path, Register temp, bool at_ret relocate(relocInfo::poll_return_type); td(traptoGreaterThanUnsigned, R1_SP, temp); } else { - cmpld(CCR0, R1_SP, temp); + cmpld(CR0, R1_SP, temp); // Stub may be out of range for short conditional branch. - bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CCR0, Assembler::greater), slow_path); + bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::greater), slow_path); } } else { // Not in nmethod. // Frame still on stack, need to get fp. Register fp = R0; ld(fp, _abi0(callers_sp), R1_SP); - cmpld(CCR0, fp, temp); - bgt(CCR0, slow_path); + cmpld(CR0, fp, temp); + bgt(CR0, slow_path); } } else { // Normal safepoint poll. Not at return. assert(!in_nmethod, "should use load_from_polling_page"); andi_(temp, temp, SafepointMechanism::poll_bit()); - bne(CCR0, slow_path); + bne(CR0, slow_path); } } @@ -3436,8 +3613,8 @@ void MacroAssembler::resolve_weak_handle(Register result, Register tmp1, Registe Label resolved; // A null weak handle resolves to null. - cmpdi(CCR0, result, 0); - beq(CCR0, resolved); + cmpdi(CR0, result, 0); + beq(CR0, resolved); access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, result, noreg, result, tmp1, tmp2, preservation_level); @@ -3498,11 +3675,11 @@ void MacroAssembler::clear_memory_doubleword(Register base_ptr, Register cnt_dwo load_const_optimized(cnt_dwords, const_cnt, tmp); } else { // cnt_dwords already loaded in register. Need to check size. - cmpdi(CCR1, cnt_dwords, min_cnt); // Big enough? (ensure >= dcbz_min lines included). - blt(CCR1, small_rest); + cmpdi(CR1, cnt_dwords, min_cnt); // Big enough? (ensure >= dcbz_min lines included). + blt(CR1, small_rest); } rldicl_(tmp, base_ptr, 64-3, 64-cl_dw_addr_bits); // Extract dword offset within first cache line. - beq(CCR0, fast); // Already 128byte aligned. + beq(CR0, fast); // Already 128byte aligned. subfic(tmp, tmp, cl_dwords); mtctr(tmp); // Set ctr to hit 128byte boundary (0=mainLoop_stepping is guaranteed). } else { sub(tmp, len, tmp2); // Remaining bytes for main loop. - cmpdi(CCR0, tmp, mainLoop_stepping); - blt(CCR0, L_tail); // For less than one mainloop_stepping left, do only tail processing + cmpdi(CR0, tmp, mainLoop_stepping); + blt(CR0, L_tail); // For less than one mainloop_stepping left, do only tail processing mr(len, tmp); // remaining bytes for main loop (>=mainLoop_stepping is guaranteed). } update_byteLoop_crc32(crc, buf, tmp2, table, data, false); @@ -3831,8 +4008,8 @@ void MacroAssembler::kernel_crc32_vpmsum(Register crc, Register buf, Register le neg(prealign, buf); addi(t1, len, -threshold); andi(prealign, prealign, alignment - 1); - cmpw(CCR0, t1, prealign); - blt(CCR0, L_tail); // len - prealign < threshold? + cmpw(CR0, t1, prealign); + blt(CR0, L_tail); // len - prealign < threshold? subf(len, prealign, len); update_byteLoop_crc32(crc, buf, prealign, constants, t2, false); @@ -3956,8 +4133,8 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg #define BE_swap_bytes(x) vperm(x, x, x, swap_bytes) #endif - cmpd(CCR0, len, num_bytes); - blt(CCR0, L_last); + cmpd(CR0, len, num_bytes); + blt(CR0, L_last); addi(cur_const, constants, outer_consts_size); // Point to consts for inner loop load_const_optimized(loop_count, unroll_factor / (2 * unroll_factor2) - 1); // One double-iteration peeled off. @@ -4044,8 +4221,8 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg vxor(data0[j], data0[j], data0[j+i]); } } - cmpd(CCR0, len, num_bytes); - bge(CCR0, L_outer_loop); + cmpd(CR0, len, num_bytes); + bge(CR0, L_outer_loop); // Last chance with lower num_bytes. bind(L_last); @@ -4057,7 +4234,7 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg subf(cur_const, R0, cur_const); // Point to constant to be used first. addic_(loop_count, loop_count, -1); // One double-iteration peeled off. - bgt(CCR0, L_outer_loop); + bgt(CR0, L_outer_loop); // ********** Main loop end ********** // Restore DSCR pre-fetch value. @@ -4072,7 +4249,7 @@ void MacroAssembler::kernel_crc32_vpmsum_aligned(Register crc, Register buf, Reg srdi_(t0, len, 4); // 16 bytes per iteration clrldi(len, len, 64-4); - beq(CCR0, L_done); + beq(CR0, L_done); // Point to const (same as last const for inner loop). add_const_optimized(cur_const, constants, outer_consts_size + inner_consts_size - 16); @@ -4191,7 +4368,7 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Label L_one_x, L_one_y, L_multiply; addic_(xstart, xstart, -1); - blt(CCR0, L_one_x); // Special case: length of x is 1. + blt(CR0, L_one_x); // Special case: length of x is 1. // Load next two integers of x. sldi(tmp, xstart, LogBytesPerInt); @@ -4203,10 +4380,10 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, align(32, 16); bind(L_first_loop); - cmpdi(CCR0, idx, 1); - blt(CCR0, L_first_loop_exit); + cmpdi(CR0, idx, 1); + blt(CR0, L_first_loop_exit); addi(idx, idx, -2); - beq(CCR0, L_one_y); + beq(CR0, L_one_y); // Load next two integers of y. sldi(tmp, idx, LogBytesPerInt); @@ -4314,7 +4491,7 @@ void MacroAssembler::multiply_128_x_128_loop(Register x_xstart, // Scale the index. srdi_(jdx, idx, 2); - beq(CCR0, L_third_loop_exit); + beq(CR0, L_third_loop_exit); mtctr(jdx); align(32, 16); @@ -4332,12 +4509,12 @@ void MacroAssembler::multiply_128_x_128_loop(Register x_xstart, bind(L_third_loop_exit); // Handle any left-over operand parts. andi_(idx, idx, 0x3); - beq(CCR0, L_post_third_loop_done); + beq(CR0, L_post_third_loop_done); Label L_check_1; addic_(idx, idx, -2); - blt(CCR0, L_check_1); + blt(CR0, L_check_1); multiply_add_128_x_128(x_xstart, y, z, yz_idx, idx, carry, product_high, product, tmp, 0); mr_if_needed(carry, product_high); @@ -4347,7 +4524,7 @@ void MacroAssembler::multiply_128_x_128_loop(Register x_xstart, addi(idx, idx, 0x2); andi_(idx, idx, 0x1); addic_(idx, idx, -1); - blt(CCR0, L_post_third_loop_done); + blt(CR0, L_post_third_loop_done); sldi(tmp, idx, LogBytesPerInt); lwzx(yz_idx, y, tmp); @@ -4375,12 +4552,12 @@ void MacroAssembler::muladd(Register out, Register in, Label LOOP, SKIP; // Make sure length is positive. - cmpdi (CCR0, len, 0); + cmpdi (CR0, len, 0); // Prepare variables subi (offset, offset, 4); li (carry, 0); - ble (CCR0, SKIP); + ble (CR0, SKIP); mtctr (len); subi (len, len, 1 ); @@ -4452,20 +4629,20 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Label L_done; addic_(xstart, xlen, -1); - blt(CCR0, L_done); + blt(CR0, L_done); multiply_64_x_64_loop(x, xstart, x_xstart, y, y_idx, z, carry, product_high, product, idx, kdx, tmp); Label L_second_loop; - cmpdi(CCR0, kdx, 0); - beq(CCR0, L_second_loop); + cmpdi(CR0, kdx, 0); + beq(CR0, L_second_loop); Label L_carry; addic_(kdx, kdx, -1); - beq(CCR0, L_carry); + beq(CR0, L_carry); // Store lower 32 bits of carry. sldi(tmp, kdx, LogBytesPerInt); @@ -4500,7 +4677,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, li(carry, 0); // carry = 0; addic_(xstart, xstart, -1); // i = xstart-1; - blt(CCR0, L_done); + blt(CR0, L_done); Register zsave = tmp10; @@ -4513,7 +4690,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, add(z, z, tmp); // z = z + k - j addi(z, z, 4); addic_(xstart, xstart, -1); // i = xstart-1; - blt(CCR0, L_last_x); + blt(CR0, L_last_x); sldi(tmp, xstart, LogBytesPerInt); ldx(x_xstart, x, tmp); @@ -4547,7 +4724,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, sldi(tmp, tmp3, LogBytesPerInt); stwx(carry, z, tmp); addic_(tmp3, tmp3, -1); - blt(CCR0, L_done); + blt(CR0, L_done); srdi(carry, carry, 32); sldi(tmp, tmp3, LogBytesPerInt); @@ -4567,9 +4744,9 @@ void MacroAssembler::asm_assert(bool check_equal, const char *msg) { #ifdef ASSERT Label ok; if (check_equal) { - beq(CCR0, ok); + beq(CR0, ok); } else { - bne(CCR0, ok); + bne(CR0, ok); } stop(msg); bind(ok); @@ -4582,11 +4759,11 @@ void MacroAssembler::asm_assert_mems_zero(bool check_equal, int size, int mem_of switch (size) { case 4: lwz(R0, mem_offset, mem_base); - cmpwi(CCR0, R0, 0); + cmpwi(CR0, R0, 0); break; case 8: ld(R0, mem_offset, mem_base); - cmpdi(CCR0, R0, 0); + cmpdi(CR0, R0, 0); break; default: ShouldNotReachHere(); @@ -4708,8 +4885,8 @@ void MacroAssembler::zap_from_to(Register low, int before, Register high, int af bind(loop); std(val, 0, addr); addi(addr, addr, 8); - cmpd(CCR6, addr, high); - ble(CCR6, loop); + cmpd(CR6, addr, high); + ble(CR6, loop); if (after) addi(high, high, -after * BytesPerWord); // Correct back to old value. } BLOCK_COMMENT("} zap memory region"); @@ -4741,8 +4918,8 @@ void MacroAssembler::push_cont_fastpath() { Label done; ld_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread); - cmpld(CCR0, R1_SP, R0); - ble(CCR0, done); + cmpld(CR0, R1_SP, R0); + ble(CR0, done); st_ptr(R1_SP, JavaThread::cont_fastpath_offset(), R16_thread); bind(done); } @@ -4752,48 +4929,48 @@ void MacroAssembler::pop_cont_fastpath() { Label done; ld_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread); - cmpld(CCR0, R1_SP, R0); - ble(CCR0, done); + cmpld(CR0, R1_SP, R0); + ble(CR0, done); li(R0, 0); st_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread); bind(done); } -// Note: Must preserve CCR0 EQ (invariant). +// Note: Must preserve CR0 EQ (invariant). void MacroAssembler::inc_held_monitor_count(Register tmp) { assert(LockingMode == LM_LEGACY, ""); ld(tmp, in_bytes(JavaThread::held_monitor_count_offset()), R16_thread); #ifdef ASSERT Label ok; - cmpdi(CCR0, tmp, 0); - bge_predict_taken(CCR0, ok); + cmpdi(CR0, tmp, 0); + bge_predict_taken(CR0, ok); stop("held monitor count is negativ at increment"); bind(ok); - crorc(CCR0, Assembler::equal, CCR0, Assembler::equal); // Restore CCR0 EQ + crorc(CR0, Assembler::equal, CR0, Assembler::equal); // Restore CR0 EQ #endif addi(tmp, tmp, 1); std(tmp, in_bytes(JavaThread::held_monitor_count_offset()), R16_thread); } -// Note: Must preserve CCR0 EQ (invariant). +// Note: Must preserve CR0 EQ (invariant). void MacroAssembler::dec_held_monitor_count(Register tmp) { assert(LockingMode == LM_LEGACY, ""); ld(tmp, in_bytes(JavaThread::held_monitor_count_offset()), R16_thread); #ifdef ASSERT Label ok; - cmpdi(CCR0, tmp, 0); - bgt_predict_taken(CCR0, ok); + cmpdi(CR0, tmp, 0); + bgt_predict_taken(CR0, ok); stop("held monitor count is <= 0 at decrement"); bind(ok); - crorc(CCR0, Assembler::equal, CCR0, Assembler::equal); // Restore CCR0 EQ + crorc(CR0, Assembler::equal, CR0, Assembler::equal); // Restore CR0 EQ #endif addi(tmp, tmp, -1); std(tmp, in_bytes(JavaThread::held_monitor_count_offset()), R16_thread); } // Function to flip between unlocked and locked state (fast locking). -// Branches to failed if the state is not as expected with CCR0 NE. -// Falls through upon success with CCR0 EQ. +// Branches to failed if the state is not as expected with CR0 NE. +// Falls through upon success with CR0 EQ. // This requires fewer instructions and registers and is easier to use than the // cmpxchg based implementation. void MacroAssembler::atomically_flip_locked_state(bool is_unlock, Register obj, Register tmp, Label& failed, int semantics) { @@ -4810,15 +4987,15 @@ void MacroAssembler::atomically_flip_locked_state(bool is_unlock, Register obj, ldarx(tmp, obj, MacroAssembler::cmpxchgx_hint_acquire_lock()); xori(tmp, tmp, markWord::unlocked_value); // flip unlocked bit andi_(R0, tmp, markWord::lock_mask_in_place); - bne(CCR0, failed); // failed if new header doesn't contain locked_value (which is 0) + bne(CR0, failed); // failed if new header doesn't contain locked_value (which is 0) } else { ldarx(tmp, obj, MacroAssembler::cmpxchgx_hint_release_lock()); andi_(R0, tmp, markWord::lock_mask_in_place); - bne(CCR0, failed); // failed if old header doesn't contain locked_value (which is 0) + bne(CR0, failed); // failed if old header doesn't contain locked_value (which is 0) ori(tmp, tmp, markWord::unlocked_value); // set unlocked bit } stdcx_(tmp, obj); - bne(CCR0, retry); + bne(CR0, retry); if (semantics & MemBarFenceAfter) { fence(); @@ -4848,8 +5025,8 @@ void MacroAssembler::lightweight_lock(Register box, Register obj, Register t1, R // Check if the lock-stack is full. lwz(top, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); - cmplwi(CCR0, top, LockStack::end_offset()); - bge(CCR0, slow); + cmplwi(CR0, top, LockStack::end_offset()); + bge(CR0, slow); // The underflow check is elided. The recursive check will always fail // when the lock stack is empty because of the _bad_oop_sentinel field. @@ -4857,14 +5034,14 @@ void MacroAssembler::lightweight_lock(Register box, Register obj, Register t1, R // Check for recursion. subi(t, top, oopSize); ldx(t, R16_thread, t); - cmpd(CCR0, obj, t); - beq(CCR0, push); + cmpd(CR0, obj, t); + beq(CR0, push); // Check header for monitor (0b10) or locked (0b00). ld(mark, oopDesc::mark_offset_in_bytes(), obj); xori(t, mark, markWord::unlocked_value); andi_(t, t, markWord::lock_mask_in_place); - bne(CCR0, slow); + bne(CR0, slow); // Try to lock. Transition lock bits 0b01 => 0b00 atomically_flip_locked_state(/* is_unlock */ false, obj, mark, slow, MacroAssembler::MemBarAcq); @@ -4893,8 +5070,8 @@ void MacroAssembler::lightweight_unlock(Register obj, Register t1, Label& slow) // Check for lock-stack underflow. Label stack_ok; lwz(t1, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); - cmplwi(CCR0, t1, LockStack::start_offset()); - bge(CCR0, stack_ok); + cmplwi(CR0, t1, LockStack::start_offset()); + bge(CR0, stack_ok); stop("Lock-stack underflow"); bind(stack_ok); } @@ -4909,8 +5086,8 @@ void MacroAssembler::lightweight_unlock(Register obj, Register t1, Label& slow) lwz(top, in_bytes(JavaThread::lock_stack_top_offset()), R16_thread); subi(top, top, oopSize); ldx(t, R16_thread, top); - cmpd(CCR0, obj, t); - bne(CCR0, slow); + cmpd(CR0, obj, t); + bne(CR0, slow); // Pop lock-stack. DEBUG_ONLY(li(t, 0);) @@ -4923,8 +5100,8 @@ void MacroAssembler::lightweight_unlock(Register obj, Register t1, Label& slow) // Check if recursive. subi(t, top, oopSize); ldx(t, R16_thread, t); - cmpd(CCR0, obj, t); - beq(CCR0, unlocked); + cmpd(CR0, obj, t); + beq(CR0, unlocked); // Use top as tmp t = top; @@ -4932,13 +5109,13 @@ void MacroAssembler::lightweight_unlock(Register obj, Register t1, Label& slow) // Not recursive. Check header for monitor (0b10). ld(mark, oopDesc::mark_offset_in_bytes(), obj); andi_(t, mark, markWord::monitor_value); - bne(CCR0, push_and_slow); + bne(CR0, push_and_slow); #ifdef ASSERT // Check header not unlocked (0b01). Label not_unlocked; andi_(t, mark, markWord::unlocked_value); - beq(CCR0, not_unlocked); + beq(CR0, not_unlocked); stop("lightweight_unlock already unlocked"); bind(not_unlocked); #endif diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp index 3e82c1c678578..69570517866d6 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,8 +179,8 @@ class MacroAssembler: public Assembler { // // branch, jump // - // set dst to -1, 0, +1 as follows: if CCR0bi is "greater than", dst is set to 1, - // if CCR0bi is "equal", dst is set to 0, otherwise it's set to -1. + // set dst to -1, 0, +1 as follows: if CR0bi is "greater than", dst is set to 1, + // if CR0bi is "equal", dst is set to 0, otherwise it's set to -1. void inline set_cmp3(Register dst); // set dst to (treat_unordered_like_less ? -1 : +1) void inline set_cmpu3(Register dst, bool treat_unordered_like_less); @@ -612,6 +612,20 @@ class MacroAssembler: public Assembler { // The temp_reg can be noreg, if no temps are available. // It can also be sub_klass or super_klass, meaning it's OK to kill that one. // Updates the sub's secondary super cache as necessary. + void check_klass_subtype_slow_path_linear(Register sub_klass, + Register super_klass, + Register temp1_reg, + Register temp2_reg, + Label* L_success = nullptr, + Register result_reg = noreg); + + void check_klass_subtype_slow_path_table(Register sub_klass, + Register super_klass, + Register temp1_reg, + Register temp2_reg, + Label* L_success = nullptr, + Register result_reg = noreg); + void check_klass_subtype_slow_path(Register sub_klass, Register super_klass, Register temp1_reg, @@ -619,6 +633,25 @@ class MacroAssembler: public Assembler { Label* L_success = nullptr, Register result_reg = noreg); + void lookup_secondary_supers_table_var(Register sub_klass, + Register r_super_klass, + Register temp1, + Register temp2, + Register temp3, + Register temp4, + Register result); + + // If r is valid, return r. + // If r is invalid, remove a register r2 from available_regs, add r2 + // to regs_to_push, then return r2. + Register allocate_if_noreg(const Register r, + RegSetIterator &available_regs, + RegSet ®s_to_push); + + // Frameless register spills (negative offset from SP) + void push_set(RegSet set); + void pop_set(RegSet set); + // Simplified, combined version, good for typical uses. // Falls through on failure. void check_klass_subtype(Register sub_klass, @@ -631,14 +664,14 @@ class MacroAssembler: public Assembler { // As above, but with a constant super_klass. // The result is in Register result, not the condition codes. - void lookup_secondary_supers_table(Register r_sub_klass, - Register r_super_klass, - Register temp1, - Register temp2, - Register temp3, - Register temp4, - Register result, - u1 super_klass_slot); + void lookup_secondary_supers_table_const(Register r_sub_klass, + Register r_super_klass, + Register temp1, + Register temp2, + Register temp3, + Register temp4, + Register result, + u1 super_klass_slot); void verify_secondary_supers_table(Register r_sub_klass, Register r_super_klass, diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp index 6f5cd8fbd9671..b2bcf72bd353a 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -248,14 +248,14 @@ inline bool MacroAssembler::is_bc_far_variant3_at(address instruction_addr) { is_endgroup(instruction_2); } -// set dst to -1, 0, +1 as follows: if CCR0bi is "greater than", dst is set to 1, -// if CCR0bi is "equal", dst is set to 0, otherwise it's set to -1. +// set dst to -1, 0, +1 as follows: if CR0bi is "greater than", dst is set to 1, +// if CR0bi is "equal", dst is set to 0, otherwise it's set to -1. inline void MacroAssembler::set_cmp3(Register dst) { assert_different_registers(dst, R0); // P10, prefer using setbc instructions if (VM_Version::has_brw()) { - setbc(R0, CCR0, Assembler::greater); // Set 1 to R0 if CCR0bi is "greater than", otherwise 0 - setnbc(dst, CCR0, Assembler::less); // Set -1 to dst if CCR0bi is "less than", otherwise 0 + setbc(R0, CR0, Assembler::greater); // Set 1 to R0 if CR0bi is "greater than", otherwise 0 + setnbc(dst, CR0, Assembler::less); // Set -1 to dst if CR0bi is "less than", otherwise 0 } else { mfcr(R0); // copy CR register to R0 srwi(dst, R0, 30); // copy the first two bits to dst @@ -267,9 +267,9 @@ inline void MacroAssembler::set_cmp3(Register dst) { // set dst to (treat_unordered_like_less ? -1 : +1) inline void MacroAssembler::set_cmpu3(Register dst, bool treat_unordered_like_less) { if (treat_unordered_like_less) { - cror(CCR0, Assembler::less, CCR0, Assembler::summary_overflow); // treat unordered like less + cror(CR0, Assembler::less, CR0, Assembler::summary_overflow); // treat unordered like less } else { - cror(CCR0, Assembler::greater, CCR0, Assembler::summary_overflow); // treat unordered like greater + cror(CR0, Assembler::greater, CR0, Assembler::summary_overflow); // treat unordered like greater } set_cmp3(dst); } @@ -280,11 +280,11 @@ inline void MacroAssembler::normalize_bool(Register dst, Register temp, bool is_ if (VM_Version::has_brw()) { if (is_64bit) { - cmpdi(CCR0, dst, 0); + cmpdi(CR0, dst, 0); } else { - cmpwi(CCR0, dst, 0); + cmpwi(CR0, dst, 0); } - setbcr(dst, CCR0, Assembler::equal); + setbcr(dst, CR0, Assembler::equal); } else { assert_different_registers(temp, dst); neg(temp, dst); @@ -373,8 +373,8 @@ inline void MacroAssembler::null_check_throw(Register a, int offset, Register te trap_null_check(a); } else { Label ok; - cmpdi(CCR0, a, 0); - bne(CCR0, ok); + cmpdi(CR0, a, 0); + bne(CR0, ok); load_const_optimized(temp_reg, exception_entry); mtctr(temp_reg); bctr(); @@ -390,8 +390,8 @@ inline void MacroAssembler::null_check(Register a, int offset, Label *Lis_null) trap_null_check(a); } else if (Lis_null){ Label ok; - cmpdi(CCR0, a, 0); - beq(CCR0, *Lis_null); + cmpdi(CR0, a, 0); + beq(CR0, *Lis_null); } } } @@ -468,14 +468,14 @@ inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register sr inline Register MacroAssembler::encode_heap_oop(Register d, Register src) { if (CompressedOops::base() != nullptr) { if (VM_Version::has_isel()) { - cmpdi(CCR0, src, 0); + cmpdi(CR0, src, 0); Register co = encode_heap_oop_not_null(d, src); assert(co == d, "sanity"); - isel_0(d, CCR0, Assembler::equal); + isel_0(d, CR0, Assembler::equal); } else { Label isNull; or_(d, src, src); // move and compare 0 - beq(CCR0, isNull); + beq(CR0, isNull); encode_heap_oop_not_null(d, src); bind(isNull); } @@ -509,16 +509,16 @@ inline void MacroAssembler::decode_heap_oop(Register d) { Label isNull; bool use_isel = false; if (CompressedOops::base() != nullptr) { - cmpwi(CCR0, d, 0); + cmpwi(CR0, d, 0); if (VM_Version::has_isel()) { use_isel = true; } else { - beq(CCR0, isNull); + beq(CR0, isNull); } } decode_heap_oop_not_null(d); if (use_isel) { - isel_0(d, CCR0, Assembler::equal); + isel_0(d, CR0, Assembler::equal); } bind(isNull); } diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc_sha.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc_sha.cpp index 3d0b5dab2db2b..bdf2d8d268ac8 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc_sha.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc_sha.cpp @@ -93,7 +93,7 @@ void MacroAssembler::sha256_load_h_vec(const VectorRegister a, lvx (a, hptr); addi (tmp, hptr, 16); lvx (e, tmp); - beq (CCR0, sha256_aligned); + beq (CR0, sha256_aligned); // handle unaligned accesses load_perm(vRb, hptr); @@ -121,7 +121,7 @@ void MacroAssembler::sha256_load_w_plus_k_vec(const Register buf_in, VectorRegister vRb = VR6; andi_ (tmp, buf_in, 0xF); - beq (CCR0, w_aligned); // address ends with 0x0, not 0x8 + beq (CR0, w_aligned); // address ends with 0x0, not 0x8 // deal with unaligned addresses lvx (ws[0], buf_in); @@ -318,7 +318,7 @@ void MacroAssembler::sha256_update_sha_state(const VectorRegister a, li (of16, 16); lvx (vt0, hptr); lvx (vt5, of16, hptr); - beq (CCR0, state_load_aligned); + beq (CR0, state_load_aligned); // handle unaligned accesses li (of32, 32); @@ -538,8 +538,8 @@ void MacroAssembler::sha256(bool multi_block) { if (multi_block) { addi(buf_in, buf_in, buf_size); addi(ofs, ofs, buf_size); - cmplw(CCR0, ofs, limit); - ble(CCR0, sha_loop); + cmplw(CR0, ofs, limit); + ble(CR0, sha_loop); // return ofs mr(R3_RET, ofs); @@ -567,7 +567,7 @@ void MacroAssembler::sha512_load_w_vec(const Register buf_in, Label is_aligned, after_alignment; andi_ (tmp, buf_in, 0xF); - beq (CCR0, is_aligned); // address ends with 0x0, not 0x8 + beq (CR0, is_aligned); // address ends with 0x0, not 0x8 // deal with unaligned addresses lvx (ws[0], buf_in); @@ -623,7 +623,7 @@ void MacroAssembler::sha512_update_sha_state(const Register state, VectorRegister aux = VR9; andi_(tmp, state, 0xf); - beq(CCR0, state_save_aligned); + beq(CR0, state_save_aligned); // deal with unaligned addresses { @@ -860,7 +860,7 @@ void MacroAssembler::sha512_load_h_vec(const Register state, Label state_aligned, after_state_aligned; andi_(tmp, state, 0xf); - beq(CCR0, state_aligned); + beq(CR0, state_aligned); // deal with unaligned addresses VectorRegister aux = VR9; @@ -1121,8 +1121,8 @@ void MacroAssembler::sha512(bool multi_block) { if (multi_block) { addi(buf_in, buf_in, buf_size); addi(ofs, ofs, buf_size); - cmplw(CCR0, ofs, limit); - ble(CCR0, sha_loop); + cmplw(CR0, ofs, limit); + ble(CR0, sha_loop); // return ofs mr(R3_RET, ofs); diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index aaac79325c421..441339b94c61b 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,10 +37,12 @@ return false; } - // PPC implementation uses VSX load/store instructions (if - // SuperwordUseVSX) which support 4 byte but not arbitrary alignment + // The PPC implementation uses VSX lxvd2x/stxvd2x instructions (if + // SuperwordUseVSX). They do not have alignment requirements. + // Some VSX storage access instructions cannot encode arbitrary displacements + // (e.g. lxv). None of them is currently used. static constexpr bool misaligned_vectors_ok() { - return false; + return true; } // Whether code generation need accurate ConvI2L types. diff --git a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp index ccec05e710530..13fb8ef79d640 100644 --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" @@ -84,16 +83,16 @@ void MethodHandles::verify_klass(MacroAssembler* _masm, Label L_ok, L_bad; BLOCK_COMMENT("verify_klass {"); __ verify_oop(obj_reg, FILE_AND_LINE); - __ cmpdi(CCR0, obj_reg, 0); - __ beq(CCR0, L_bad); + __ cmpdi(CR0, obj_reg, 0); + __ beq(CR0, L_bad); __ load_klass(temp_reg, obj_reg); __ load_const_optimized(temp2_reg, (address) klass_addr); __ ld(temp2_reg, 0, temp2_reg); - __ cmpd(CCR0, temp_reg, temp2_reg); - __ beq(CCR0, L_ok); + __ cmpd(CR0, temp_reg, temp2_reg); + __ beq(CR0, L_ok); __ ld(temp_reg, klass->super_check_offset(), temp_reg); - __ cmpd(CCR0, temp_reg, temp2_reg); - __ beq(CCR0, L_ok); + __ cmpd(CR0, temp_reg, temp2_reg); + __ beq(CR0, L_ok); __ BIND(L_bad); __ stop(error_message); __ BIND(L_ok); @@ -108,8 +107,8 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe // assert(sizeof(u4) == sizeof(java.lang.invoke.MemberName.flags), ""); __ srwi( temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT); __ andi(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK); - __ cmpwi(CCR1, temp, ref_kind); - __ beq(CCR1, L); + __ cmpwi(CR1, temp, ref_kind); + __ beq(CR1, L); { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal); jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind); if (ref_kind == JVM_REF_invokeVirtual || @@ -136,11 +135,11 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth // compiled code in threads for which the event is enabled. Check here for // interp_only_mode if these events CAN be enabled. __ lwz(temp, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); - __ cmplwi(CCR0, temp, 0); - __ beq(CCR0, run_compiled_code); + __ cmplwi(CR0, temp, 0); + __ beq(CR0, run_compiled_code); // Null method test is replicated below in compiled case. - __ cmplwi(CCR0, R19_method, 0); - __ beq(CCR0, L_no_such_method); + __ cmplwi(CR0, R19_method, 0); + __ beq(CR0, L_no_such_method); __ ld(target, in_bytes(Method::interpreter_entry_offset()), R19_method); __ mtctr(target); __ bctr(); @@ -148,8 +147,8 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth } // Compiled case, either static or fall-through from runtime conditional - __ cmplwi(CCR0, R19_method, 0); - __ beq(CCR0, L_no_such_method); + __ cmplwi(CR0, R19_method, 0); + __ beq(CR0, L_no_such_method); const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : Method::from_interpreted_offset(); @@ -201,8 +200,8 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, // assert(sizeof(u2) == sizeof(ConstMethod::_size_of_parameters), ""); Label L; __ ld(temp2, __ argument_offset(temp2, temp2, 0), R15_esp); - __ cmpd(CCR1, temp2, recv); - __ beq(CCR1, L); + __ cmpd(CR1, temp2, recv); + __ beq(CR1, L); __ stop("receiver not on stack"); __ BIND(L); } @@ -249,8 +248,8 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* BLOCK_COMMENT("verify_intrinsic_id {"); __ load_sized_value(R30_tmp1, in_bytes(Method::intrinsic_id_offset()), R19_method, sizeof(u2), /*is_signed*/ false); - __ cmpwi(CCR1, R30_tmp1, (int) iid); - __ beq(CCR1, L); + __ cmpwi(CR1, R30_tmp1, (int) iid); + __ beq(CR1, L); if (iid == vmIntrinsics::_linkToVirtual || iid == vmIntrinsics::_linkToSpecial) { // could do this for all kinds, but would explode assembly code size @@ -426,8 +425,8 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, if (VerifyMethodHandles) { Label L_index_ok; - __ cmpdi(CCR1, temp2_index, 0); - __ bge(CCR1, L_index_ok); + __ cmpdi(CR1, temp2_index, 0); + __ bge(CR1, L_index_ok); __ stop("no virtual index"); __ BIND(L_index_ok); } @@ -458,8 +457,8 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, __ ld(vtable_index, NONZERO(java_lang_invoke_MemberName::vmindex_offset()), member_reg); if (VerifyMethodHandles) { Label L_index_ok; - __ cmpdi(CCR1, vtable_index, 0); - __ bge(CCR1, L_index_ok); + __ cmpdi(CR1, vtable_index, 0); + __ bge(CR1, L_index_ok); __ stop("invalid vtable index for MH.invokeInterface"); __ BIND(L_index_ok); } diff --git a/src/hotspot/cpu/ppc/nativeInst_ppc.cpp b/src/hotspot/cpu/ppc/nativeInst_ppc.cpp index 78ed81be9cb75..1114da60d2bb6 100644 --- a/src/hotspot/cpu/ppc/nativeInst_ppc.cpp +++ b/src/hotspot/cpu/ppc/nativeInst_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 808dd02273895..2504c613d7855 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2012, 2024 SAP SE. All rights reserved. +// Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2012, 2025 SAP SE. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -236,14 +236,14 @@ register %{ // in the CR register. // types: v = volatile, nv = non-volatile, s = system - reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v - reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v - reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv - reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv - reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv - reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v - reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v - reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v + reg_def CR0(SOC, SOC, Op_RegFlags, 0, CR0->as_VMReg()); // v + reg_def CR1(SOC, SOC, Op_RegFlags, 1, CR1->as_VMReg()); // v + reg_def CR2(SOC, SOC, Op_RegFlags, 2, CR2->as_VMReg()); // nv + reg_def CR3(SOC, SOC, Op_RegFlags, 3, CR3->as_VMReg()); // nv + reg_def CR4(SOC, SOC, Op_RegFlags, 4, CR4->as_VMReg()); // nv + reg_def CR5(SOC, SOC, Op_RegFlags, 5, CR5->as_VMReg()); // v + reg_def CR6(SOC, SOC, Op_RegFlags, 6, CR6->as_VMReg()); // v + reg_def CR7(SOC, SOC, Op_RegFlags, 7, CR7->as_VMReg()); // v // Special registers of PPC64 @@ -443,14 +443,14 @@ alloc_class chunk1 ( alloc_class chunk2 ( // Chunk2 contains *all* 8 condition code registers. - CCR0, - CCR1, - CCR2, - CCR3, - CCR4, - CCR5, - CCR6, - CCR7 + CR0, + CR1, + CR2, + CR3, + CR4, + CR5, + CR6, + CR7 ); alloc_class chunk3 ( @@ -803,30 +803,30 @@ reg_class bits64_reg_ro( // Special Class for Condition Code Flags Register reg_class int_flags( -/*CCR0*/ // scratch -/*CCR1*/ // scratch -/*CCR2*/ // nv! -/*CCR3*/ // nv! -/*CCR4*/ // nv! - CCR5, - CCR6, - CCR7 +/*CR0*/ // scratch +/*CR1*/ // scratch +/*CR2*/ // nv! +/*CR3*/ // nv! +/*CR4*/ // nv! + CR5, + CR6, + CR7 ); reg_class int_flags_ro( - CCR0, - CCR1, - CCR2, - CCR3, - CCR4, - CCR5, - CCR6, - CCR7 + CR0, + CR1, + CR2, + CR3, + CR4, + CR5, + CR6, + CR7 ); -reg_class int_flags_CR0(CCR0); -reg_class int_flags_CR1(CCR1); -reg_class int_flags_CR6(CCR6); +reg_class int_flags_CR0(CR0); +reg_class int_flags_CR1(CR1); +reg_class int_flags_CR6(CR6); reg_class ctr_reg(SR_CTR); // ---------------------------- @@ -5568,8 +5568,8 @@ instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); Label next; __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); - __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); - __ bne(CCR0, next); + __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister); + __ bne(CR0, next); __ bind(next); __ isync(); %} @@ -5604,8 +5604,8 @@ instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); Label next; __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); - __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); - __ bne(CCR0, next); + __ fcmpu(CR0, $dst$$FloatRegister, $dst$$FloatRegister); + __ bne(CR0, next); __ bind(next); __ isync(); %} @@ -7394,8 +7394,8 @@ instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7413,8 +7413,8 @@ instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7432,8 +7432,8 @@ instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7451,8 +7451,8 @@ instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7469,8 +7469,8 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7488,8 +7488,8 @@ instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7506,8 +7506,8 @@ instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7525,8 +7525,8 @@ instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc predicate(n->as_LoadStore()->barrier_data() == 0); format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7546,8 +7546,8 @@ instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7560,8 +7560,8 @@ instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7574,8 +7574,8 @@ instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7588,8 +7588,8 @@ instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7602,8 +7602,8 @@ instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7616,8 +7616,8 @@ instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7630,8 +7630,8 @@ instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7644,8 +7644,8 @@ instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7658,8 +7658,8 @@ instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7672,10 +7672,10 @@ instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7688,8 +7688,8 @@ instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7702,10 +7702,10 @@ instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. - __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + __ cmpxchgw(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7718,9 +7718,9 @@ instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // value is never passed to caller. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7733,10 +7733,10 @@ instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7749,8 +7749,8 @@ instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7763,10 +7763,10 @@ instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and // value is never passed to caller. - __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + __ cmpxchgd(CR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, nullptr, true, /*weak*/ true); %} @@ -7781,8 +7781,8 @@ instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7795,8 +7795,8 @@ instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7809,8 +7809,8 @@ instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7829,8 +7829,8 @@ instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgb(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7849,8 +7849,8 @@ instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7863,8 +7863,8 @@ instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7877,8 +7877,8 @@ instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7897,8 +7897,8 @@ instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgh(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7917,8 +7917,8 @@ instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7931,8 +7931,8 @@ instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7951,8 +7951,8 @@ instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7965,8 +7965,8 @@ instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgw(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -7985,8 +7985,8 @@ instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -7999,8 +7999,8 @@ instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -8020,8 +8020,8 @@ instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iReg effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); %} @@ -8035,8 +8035,8 @@ instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, effect(TEMP_DEF res, TEMP cr0); format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} ins_encode %{ - // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. - __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, + // CmpxchgX sets CR0 to cmpX(src1, src2) and Rres to 'true'/'false'. + __ cmpxchgd(CR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), noreg, nullptr, true); if (support_IRIW_for_not_multiple_copy_atomic_cpu) { @@ -11389,7 +11389,7 @@ instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 c format %{ "cmpL3_reg_reg $dst, $src1, $src2" %} ins_encode %{ - __ cmpd(CCR0, $src1$$Register, $src2$$Register); + __ cmpd(CR0, $src1$$Register, $src2$$Register); __ set_cmp3($dst$$Register); %} ins_pipe(pipe_class_default); @@ -11661,11 +11661,11 @@ instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ // // block BXX: // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): - // cmpFUrd CCR6, F11, F9 + // cmpFUrd CR6, F11, F9 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): - // cmov CCR6 + // cmov CR6 // 8: instruct branchConSched: - // B_FARle CCR6, B56 P=0.500000 C=-1.000000 + // B_FARle CR6, B56 P=0.500000 C=-1.000000 match(Set crx (CmpF src1 src2)); ins_cost(DEFAULT_COST+BRANCH_COST); @@ -11724,7 +11724,7 @@ instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{ format %{ "cmpF3_reg_reg $dst, $src1, $src2" %} ins_encode %{ - __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); + __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister); __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less %} ins_pipe(pipe_class_default); @@ -11808,7 +11808,7 @@ instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{ format %{ "cmpD3_reg_reg $dst, $src1, $src2" %} ins_encode %{ - __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); + __ fcmpu(CR0, $src1$$FloatRegister, $src2$$FloatRegister); __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less %} ins_pipe(pipe_class_default); @@ -12069,6 +12069,7 @@ instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ match(Set result (PartialSubtypeCheck subklass superklass)); + predicate(!UseSecondarySupersTable); effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); ins_cost(DEFAULT_COST*10); @@ -12080,6 +12081,30 @@ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P supe ins_pipe(pipe_class_default); %} +// Two versions of partialSubtypeCheck, both used when we need to +// search for a super class in the secondary supers array. The first +// is used when we don't know _a priori_ the class being searched +// for. The second, far more common, is used when we do know: this is +// used for instanceof, checkcast, and any case where C2 can determine +// it by constant propagation. +instruct partialSubtypeCheckVarSuper(iRegPsrc sub, iRegPsrc super, iRegPdst result, + iRegPdst tempR1, iRegPdst tempR2, iRegPdst tempR3, iRegPdst tempR4, + flagsRegCR0 cr0, regCTR ctr) +%{ + match(Set result (PartialSubtypeCheck sub super)); + predicate(UseSecondarySupersTable); + effect(KILL cr0, KILL ctr, TEMP_DEF result, TEMP tempR1, TEMP tempR2, TEMP tempR3, TEMP tempR4); + + ins_cost(DEFAULT_COST * 10); // slightly larger than the next version + format %{ "partialSubtypeCheck $result, $sub, $super" %} + ins_encode %{ + __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, + $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register, + $result$$Register); + %} + ins_pipe(pipe_class_memory); +%} + instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP super_con, rarg6RegP result, rarg1RegP tempR1, rarg5RegP tempR2, rarg4RegP tempR3, rscratch1RegP tempR4, flagsRegCR0 cr0, regCTR ctr) @@ -12094,9 +12119,9 @@ instruct partialSubtypeCheckConstSuper(rarg3RegP sub, rarg2RegP super_reg, immP ins_encode %{ u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); if (InlineSecondarySupersTest) { - __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, - $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register, - $result$$Register, super_klass_slot); + __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, + $tempR1$$Register, $tempR2$$Register, $tempR3$$Register, $tempR4$$Register, + $result$$Register, super_klass_slot); } else { address stub = StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot); Register r_stub_addr = $tempR1$$Register; @@ -12745,7 +12770,7 @@ instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc l __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. - __ beq(CCR0, Ldone); + __ beq(CR0, Ldone); __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); __ bind(Ldone); %} @@ -12829,8 +12854,8 @@ instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC ins_cost(DEFAULT_COST*2); ins_encode %{ - __ cmpw(CCR0, $src1$$Register, $src2$$Register); - __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); + __ cmpw(CR0, $src1$$Register, $src2$$Register); + __ isel($dst$$Register, CR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); %} @@ -12862,8 +12887,8 @@ instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC ins_cost(DEFAULT_COST*2); ins_encode %{ - __ cmpw(CCR0, $src1$$Register, $src2$$Register); - __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); + __ cmpw(CR0, $src1$$Register, $src2$$Register); + __ isel($dst$$Register, CR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); %} ins_pipe(pipe_class_default); %} diff --git a/src/hotspot/cpu/ppc/register_ppc.cpp b/src/hotspot/cpu/ppc/register_ppc.cpp index e84f89373adb0..4591d3ec2e447 100644 --- a/src/hotspot/cpu/ppc/register_ppc.cpp +++ b/src/hotspot/cpu/ppc/register_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "register_ppc.hpp" const char* Register::name() const { diff --git a/src/hotspot/cpu/ppc/register_ppc.hpp b/src/hotspot/cpu/ppc/register_ppc.hpp index 1a7f496934780..565542ad7c0d2 100644 --- a/src/hotspot/cpu/ppc/register_ppc.hpp +++ b/src/hotspot/cpu/ppc/register_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2023 SAP SE. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,14 +179,14 @@ inline constexpr ConditionRegister as_ConditionRegister(int encoding) { return ConditionRegister(encoding); } -constexpr ConditionRegister CCR0 = as_ConditionRegister(0); -constexpr ConditionRegister CCR1 = as_ConditionRegister(1); -constexpr ConditionRegister CCR2 = as_ConditionRegister(2); -constexpr ConditionRegister CCR3 = as_ConditionRegister(3); -constexpr ConditionRegister CCR4 = as_ConditionRegister(4); -constexpr ConditionRegister CCR5 = as_ConditionRegister(5); -constexpr ConditionRegister CCR6 = as_ConditionRegister(6); -constexpr ConditionRegister CCR7 = as_ConditionRegister(7); +constexpr ConditionRegister CR0 = as_ConditionRegister(0); +constexpr ConditionRegister CR1 = as_ConditionRegister(1); +constexpr ConditionRegister CR2 = as_ConditionRegister(2); +constexpr ConditionRegister CR3 = as_ConditionRegister(3); +constexpr ConditionRegister CR4 = as_ConditionRegister(4); +constexpr ConditionRegister CR5 = as_ConditionRegister(5); +constexpr ConditionRegister CR6 = as_ConditionRegister(6); +constexpr ConditionRegister CR7 = as_ConditionRegister(7); class VectorSRegister; diff --git a/src/hotspot/cpu/ppc/relocInfo_ppc.cpp b/src/hotspot/cpu/ppc/relocInfo_ppc.cpp index c0fe87a1e13d4..559d30a8f23f7 100644 --- a/src/hotspot/cpu/ppc/relocInfo_ppc.cpp +++ b/src/hotspot/cpu/ppc/relocInfo_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/relocInfo.hpp" #include "nativeInst_ppc.hpp" diff --git a/src/hotspot/cpu/ppc/runtime_ppc.cpp b/src/hotspot/cpu/ppc/runtime_ppc.cpp index eceebc45c94e8..c5990e01e0df4 100644 --- a/src/hotspot/cpu/ppc/runtime_ppc.cpp +++ b/src/hotspot/cpu/ppc/runtime_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2023 SAP SE. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.inline.hpp" #include "code/vmreg.hpp" @@ -102,7 +101,7 @@ void OptoRuntime::generate_exception_blob() { __ call_c((address) OptoRuntime::handle_exception_C); address calls_return_pc = __ last_calls_return_pc(); # ifdef ASSERT - __ cmpdi(CCR0, R3_RET, 0); + __ cmpdi(CR0, R3_RET, 0); __ asm_assert_ne("handle_exception_C must not return null"); # endif diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index c2e4c2e9b55c9..f7e1410d10fa5 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/debugInfoRec.hpp" #include "code/compiledIC.hpp" @@ -909,9 +908,9 @@ static address gen_c2i_adapter(MacroAssembler *masm, // Does compiled code exists? If yes, patch the caller's callsite. __ ld(code, method_(code)); - __ cmpdi(CCR0, code, 0); + __ cmpdi(CR0, code, 0); __ ld(ientry, method_(interpreter_entry)); // preloaded - __ beq(CCR0, call_interpreter); + __ beq(CR0, call_interpreter); // Patch caller's callsite, method_(code) was not null which means that @@ -1185,9 +1184,9 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm // Argument is valid and klass is as expected, continue. __ ld(code, method_(code)); - __ cmpdi(CCR0, code, 0); + __ cmpdi(CR0, code, 0); __ ld(ientry, method_(interpreter_entry)); // preloaded - __ beq_predict_taken(CCR0, call_interpreter); + __ beq_predict_taken(CR0, call_interpreter); // Branch to ic_miss_stub. __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); @@ -1202,9 +1201,9 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_STATIC); - __ beq(CCR0, L_skip_barrier); // non-static + __ beq(CR0, L_skip_barrier); // non-static } Register klass = R11_scratch1; @@ -1252,8 +1251,8 @@ static void object_move(MacroAssembler* masm, __ addi(r_handle, r_caller_sp, reg2offset(src.first())); __ ld( r_temp_2, reg2offset(src.first()), r_caller_sp); - __ cmpdi(CCR0, r_temp_2, 0); - __ bne(CCR0, skip); + __ cmpdi(CR0, r_temp_2, 0); + __ bne(CR0, skip); // Use a null handle if oop is null. __ li(r_handle, 0); __ bind(skip); @@ -1282,8 +1281,8 @@ static void object_move(MacroAssembler* masm, __ std( r_oop, oop_offset, R1_SP); __ addi(r_handle, R1_SP, oop_offset); - __ cmpdi(CCR0, r_oop, 0); - __ bne(CCR0, skip); + __ cmpdi(CR0, r_oop, 0); + __ bne(CR0, skip); // Use a null handle if oop is null. __ li(r_handle, 0); __ bind(skip); @@ -1643,7 +1642,7 @@ static void continuation_enter_cleanup(MacroAssembler* masm) { #ifdef ASSERT __ block_comment("clean {"); __ ld_ptr(tmp1, JavaThread::cont_entry_offset(), R16_thread); - __ cmpd(CCR0, R1_SP, tmp1); + __ cmpd(CR0, R1_SP, tmp1); __ asm_assert_eq(FILE_AND_LINE ": incorrect R1_SP"); #endif @@ -1654,15 +1653,15 @@ static void continuation_enter_cleanup(MacroAssembler* masm) { // Check if this is a virtual thread continuation Label L_skip_vthread_code; __ lwz(R0, in_bytes(ContinuationEntry::flags_offset()), R1_SP); - __ cmpwi(CCR0, R0, 0); - __ beq(CCR0, L_skip_vthread_code); + __ cmpwi(CR0, R0, 0); + __ beq(CR0, L_skip_vthread_code); // If the held monitor count is > 0 and this vthread is terminating then // it failed to release a JNI monitor. So we issue the same log message // that JavaThread::exit does. __ ld(R0, in_bytes(JavaThread::jni_monitor_count_offset()), R16_thread); - __ cmpdi(CCR0, R0, 0); - __ beq(CCR0, L_skip_vthread_code); + __ cmpdi(CR0, R0, 0); + __ beq(CR0, L_skip_vthread_code); // Save return value potentially containing the exception oop Register ex_oop = R15_esp; // nonvolatile register @@ -1684,8 +1683,8 @@ static void continuation_enter_cleanup(MacroAssembler* masm) { // Check if this is a virtual thread continuation Label L_skip_vthread_code; __ lwz(R0, in_bytes(ContinuationEntry::flags_offset()), R1_SP); - __ cmpwi(CCR0, R0, 0); - __ beq(CCR0, L_skip_vthread_code); + __ cmpwi(CR0, R0, 0); + __ beq(CR0, L_skip_vthread_code); // See comment just above. If not checking JNI calls the JNI count is only // needed for assertion checking. @@ -1750,8 +1749,8 @@ static void gen_continuation_enter(MacroAssembler* masm, #ifdef ASSERT Label is_interp_only; __ lwz(R0, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread); - __ cmpwi(CCR0, R0, 0); - __ bne(CCR0, is_interp_only); + __ cmpwi(CR0, R0, 0); + __ bne(CR0, is_interp_only); __ stop("enterSpecial interpreter entry called when not in interp_only_mode"); __ bind(is_interp_only); #endif @@ -1771,8 +1770,8 @@ static void gen_continuation_enter(MacroAssembler* masm, fill_continuation_entry(masm, reg_cont_obj, reg_is_virtual); // If isContinue, call to thaw. Otherwise, call Continuation.enter(Continuation c, boolean isContinue) - __ cmpwi(CCR0, reg_is_cont, 0); - __ bne(CCR0, L_thaw); + __ cmpwi(CR0, reg_is_cont, 0); + __ bne(CR0, L_thaw); // --- call Continuation.enter(Continuation c, boolean isContinue) @@ -1819,8 +1818,8 @@ static void gen_continuation_enter(MacroAssembler* masm, fill_continuation_entry(masm, reg_cont_obj, reg_is_virtual); // If isContinue, call to thaw. Otherwise, call Continuation.enter(Continuation c, boolean isContinue) - __ cmpwi(CCR0, reg_is_cont, 0); - __ bne(CCR0, L_thaw); + __ cmpwi(CR0, reg_is_cont, 0); + __ bne(CR0, L_thaw); // --- call Continuation.enter(Continuation c, boolean isContinue) @@ -1870,7 +1869,7 @@ static void gen_continuation_enter(MacroAssembler* masm, // Pop frame and return DEBUG_ONLY(__ ld_ptr(R0, 0, R1_SP)); __ addi(R1_SP, R1_SP, framesize_words*wordSize); - DEBUG_ONLY(__ cmpd(CCR0, R0, R1_SP)); + DEBUG_ONLY(__ cmpd(CR0, R0, R1_SP)); __ asm_assert_eq(FILE_AND_LINE ": inconsistent frame size"); __ ld(R0, _abi0(lr), R1_SP); // Return pc __ mtlr(R0); @@ -1938,8 +1937,8 @@ static void gen_continuation_yield(MacroAssembler* masm, Label L_pinned; - __ cmpwi(CCR0, R3_RET, 0); - __ bne(CCR0, L_pinned); + __ cmpwi(CR0, R3_RET, 0); + __ bne(CR0, L_pinned); // yield succeeded @@ -1962,8 +1961,8 @@ static void gen_continuation_yield(MacroAssembler* masm, // handle pending exception thrown by freeze __ ld(tmp, in_bytes(JavaThread::pending_exception_offset()), R16_thread); - __ cmpdi(CCR0, tmp, 0); - __ beq(CCR0, L_return); // return if no exception is pending + __ cmpdi(CR0, tmp, 0); + __ beq(CR0, L_return); // return if no exception is pending __ pop_frame(); __ ld(R0, _abi0(lr), R1_SP); // Return pc __ mtlr(R0); @@ -2399,12 +2398,12 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if (LockingMode == LM_LIGHTWEIGHT) { // fast_lock kills r_temp_1, r_temp_2, r_temp_3. Register r_temp_3_or_noreg = UseObjectMonitorTable ? r_temp_3 : noreg; - __ compiler_fast_lock_lightweight_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3_or_noreg); + __ compiler_fast_lock_lightweight_object(CR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3_or_noreg); } else { // fast_lock kills r_temp_1, r_temp_2, r_temp_3. - __ compiler_fast_lock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); + __ compiler_fast_lock_object(CR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); } - __ beq(CCR0, locked); + __ beq(CR0, locked); // None of the above fast optimizations worked so we have to get into the // slow case of monitor enter. Inline a special case of call_VM that @@ -2539,8 +2538,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Not suspended. // TODO: PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); - __ cmpwi(CCR1, suspend_flags, 0); - __ beq(CCR1, no_block); + __ cmpwi(CR1, suspend_flags, 0); + __ beq(CR1, no_block); // Block. Save any potential method result value before the operation and // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this @@ -2573,8 +2572,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if (LockingMode != LM_LEGACY && method->is_object_wait0()) { Label not_preempted; __ ld(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); - __ cmpdi(CCR0, R0, 0); - __ beq(CCR0, not_preempted); + __ cmpdi(CR0, R0, 0); + __ beq(CR0, not_preempted); __ mtlr(R0); __ li(R0, 0); __ std(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); @@ -2592,8 +2591,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, Label no_reguard; __ lwz(r_temp_1, thread_(stack_guard_state)); - __ cmpwi(CCR0, r_temp_1, StackOverflow::stack_guard_yellow_reserved_disabled); - __ bne(CCR0, no_reguard); + __ cmpwi(CR0, r_temp_1, StackOverflow::stack_guard_yellow_reserved_disabled); + __ bne(CR0, no_reguard); save_native_result(masm, ret_type, workspace_slot_offset); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); @@ -2623,11 +2622,11 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Try fastpath for unlocking. if (LockingMode == LM_LIGHTWEIGHT) { - __ compiler_fast_unlock_lightweight_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); + __ compiler_fast_unlock_lightweight_object(CR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); } else { - __ compiler_fast_unlock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); + __ compiler_fast_unlock_object(CR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3); } - __ beq(CCR0, done); + __ beq(CR0, done); // Save and restore any potential method result value around the unlocking operation. save_native_result(masm, ret_type, workspace_slot_offset); @@ -2694,8 +2693,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // Check for pending exceptions. // -------------------------------------------------------------------------- __ ld(r_temp_2, thread_(pending_exception)); - __ cmpdi(CCR0, r_temp_2, 0); - __ bne(CCR0, handle_pending_exception); + __ cmpdi(CR0, r_temp_2, 0); + __ bne(CR0, handle_pending_exception); // Return // -------------------------------------------------------------------------- @@ -2852,7 +2851,7 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, #ifdef ASSERT // Make sure that there is at least one entry in the array. - __ cmpdi(CCR0, number_of_frames_reg, 0); + __ cmpdi(CR0, number_of_frames_reg, 0); __ asm_assert_ne("array_size must be > 0"); #endif @@ -2867,8 +2866,8 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, pcs_reg, frame_size_reg, pc_reg); - __ cmpdi(CCR0, number_of_frames_reg, 0); - __ bne(CCR0, loop); + __ cmpdi(CR0, number_of_frames_reg, 0); + __ bne(CR0, loop); // Get the return address pointing into the frame manager. __ ld(R0, 0, pcs_reg); @@ -3015,8 +3014,8 @@ void SharedRuntime::generate_deopt_blob() { // stored in the thread during exception entry above. The exception // oop will be the return value of this stub. Label skip_restore_excp; - __ cmpdi(CCR0, exec_mode_reg, Deoptimization::Unpack_exception); - __ bne(CCR0, skip_restore_excp); + __ cmpdi(CR0, exec_mode_reg, Deoptimization::Unpack_exception); + __ bne(CR0, skip_restore_excp); __ ld(R3_RET, in_bytes(JavaThread::exception_oop_offset()), R16_thread); __ ld(R4_ARG2, in_bytes(JavaThread::exception_pc_offset()), R16_thread); __ li(R0, 0); @@ -3166,7 +3165,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { #ifdef ASSERT __ lwz(R22_tmp2, in_bytes(Deoptimization::UnrollBlock::unpack_kind_offset()), unroll_block_reg); - __ cmpdi(CCR0, R22_tmp2, (unsigned)Deoptimization::Unpack_uncommon_trap); + __ cmpdi(CR0, R22_tmp2, (unsigned)Deoptimization::Unpack_uncommon_trap); __ asm_assert_eq("OptoRuntime::generate_uncommon_trap_blob: expected Unpack_uncommon_trap"); #endif @@ -3296,8 +3295,8 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal BLOCK_COMMENT(" Check pending exception."); const Register pending_exception = R0; __ ld(pending_exception, thread_(pending_exception)); - __ cmpdi(CCR0, pending_exception, 0); - __ beq(CCR0, noException); + __ cmpdi(CR0, pending_exception, 0); + __ beq(CR0, noException); // Exception pending RegisterSaver::restore_live_registers_and_pop_frame(masm, @@ -3316,8 +3315,8 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal Label no_adjust; // If our stashed return pc was modified by the runtime we avoid touching it __ ld(R0, frame_size_in_bytes + _abi0(lr), R1_SP); - __ cmpd(CCR0, R0, R31); - __ bne(CCR0, no_adjust); + __ cmpd(CR0, R0, R31); + __ bne(CR0, no_adjust); // Adjust return pc forward to step over the safepoint poll instruction __ addi(R31, R31, 4); @@ -3396,8 +3395,8 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(SharedStubId id, address desti BLOCK_COMMENT("Check for pending exceptions."); Label pending; __ ld(R11_scratch1, thread_(pending_exception)); - __ cmpdi(CCR0, R11_scratch1, 0); - __ bne(CCR0, pending); + __ cmpdi(CR0, R11_scratch1, 0); + __ bne(CR0, pending); __ mtctr(R3_RET); // Ctr will not be touched by restore_live_registers_and_pop_frame. @@ -3500,8 +3499,8 @@ RuntimeStub* SharedRuntime::generate_throw_exception(SharedStubId id, address ru __ ld(R0, in_bytes(Thread::pending_exception_offset()), R16_thread); - __ cmpdi(CCR0, R0, 0); - __ bne(CCR0, L); + __ cmpdi(CR0, R0, 0); + __ bne(CR0, L); __ stop("SharedRuntime::throw_exception: no pending exception"); __ bind(L); } diff --git a/src/hotspot/cpu/ppc/stubDeclarations_ppc.hpp b/src/hotspot/cpu/ppc/stubDeclarations_ppc.hpp new file mode 100644 index 0000000000000..1a19f1b8cf280 --- /dev/null +++ b/src/hotspot/cpu/ppc/stubDeclarations_ppc.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_PPC_STUBDECLARATIONS_HPP +#define CPU_PPC_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 20000) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 2000) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 24000) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 24000) \ + + +#endif // CPU_PPC_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index f1168b5d07bf2..1749447d43bec 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/barrierSet.hpp" @@ -90,7 +89,8 @@ class StubGenerator: public StubCodeGenerator { // Setup a new c frame, copy java arguments, call frame manager or // native_entry, and process result. - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -195,8 +195,8 @@ class StubGenerator: public StubCodeGenerator { r_top_of_arguments_addr, r_frame_alignment_in_bytes); // any arguments to copy? - __ cmpdi(CCR0, r_arg_argument_count, 0); - __ beq(CCR0, arguments_copied); + __ cmpdi(CR0, r_arg_argument_count, 0); + __ beq(CR0, arguments_copied); // prepare loop and copy arguments in reverse order { @@ -335,10 +335,10 @@ class StubGenerator: public StubCodeGenerator { // Store result depending on type. Everything that is not // T_OBJECT, T_LONG, T_FLOAT, or T_DOUBLE is treated as T_INT. - __ cmpwi(CCR0, r_arg_result_type, T_OBJECT); - __ cmpwi(CCR1, r_arg_result_type, T_LONG); - __ cmpwi(CCR5, r_arg_result_type, T_FLOAT); - __ cmpwi(CCR6, r_arg_result_type, T_DOUBLE); + __ cmpwi(CR0, r_arg_result_type, T_OBJECT); + __ cmpwi(CR1, r_arg_result_type, T_LONG); + __ cmpwi(CR5, r_arg_result_type, T_FLOAT); + __ cmpwi(CR6, r_arg_result_type, T_DOUBLE); // restore non-volatile registers __ restore_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14)); @@ -354,10 +354,10 @@ class StubGenerator: public StubCodeGenerator { // All non-volatiles have been restored at this point!! assert(R3_RET == R3, "R3_RET should be R3"); - __ beq(CCR0, ret_is_object); - __ beq(CCR1, ret_is_long); - __ beq(CCR5, ret_is_float); - __ beq(CCR6, ret_is_double); + __ beq(CR0, ret_is_object); + __ beq(CR1, ret_is_long); + __ beq(CR5, ret_is_float); + __ beq(CR6, ret_is_double); // default: __ stw(R3_RET, 0, r_arg_result_addr); @@ -393,7 +393,8 @@ class StubGenerator: public StubCodeGenerator { // within the VM. // address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -448,7 +449,8 @@ class StubGenerator: public StubCodeGenerator { // (LR is unchanged and is live out). // address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward_exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); if (VerifyOops) { @@ -459,8 +461,8 @@ class StubGenerator: public StubCodeGenerator { // Make sure that this code is only executed if there is a pending exception. { Label L; - __ cmpdi(CCR0, R3_ARG1, 0); - __ bne(CCR0, L); + __ cmpdi(CR0, R3_ARG1, 0); + __ bne(CR0, L); __ stop("StubRoutines::forward exception: no pending exception (1)"); __ bind(L); } @@ -497,8 +499,8 @@ class StubGenerator: public StubCodeGenerator { // Make sure exception is set. { Label L; - __ cmpdi(CCR0, R3_ARG1, 0); - __ bne(CCR0, L); + __ cmpdi(CR0, R3_ARG1, 0); + __ bne(CR0, L); __ stop("StubRoutines::forward exception: no pending exception (2)"); __ bind(L); } @@ -518,93 +520,6 @@ class StubGenerator: public StubCodeGenerator { #undef __ #define __ _masm-> - - // Support for void zero_words_aligned8(HeapWord* to, size_t count) - // - // Arguments: - // to: - // count: - // - // Destroys: - // - address generate_zero_words_aligned8() { - StubCodeMark mark(this, "StubRoutines", "zero_words_aligned8"); - - // Implemented as in ClearArray. - address start = __ function_entry(); - - Register base_ptr_reg = R3_ARG1; // tohw (needs to be 8b aligned) - Register cnt_dwords_reg = R4_ARG2; // count (in dwords) - Register tmp1_reg = R5_ARG3; - Register tmp2_reg = R6_ARG4; - Register zero_reg = R7_ARG5; - - // Procedure for large arrays (uses data cache block zero instruction). - Label dwloop, fast, fastloop, restloop, lastdword, done; - int cl_size = VM_Version::L1_data_cache_line_size(); - int cl_dwords = cl_size >> 3; - int cl_dwordaddr_bits = exact_log2(cl_dwords); - int min_dcbz = 2; // Needs to be positive, apply dcbz only to at least min_dcbz cache lines. - - // Clear up to 128byte boundary if long enough, dword_cnt=(16-(base>>3))%16. - __ dcbtst(base_ptr_reg); // Indicate write access to first cache line ... - __ andi(tmp2_reg, cnt_dwords_reg, 1); // to check if number of dwords is even. - __ srdi_(tmp1_reg, cnt_dwords_reg, 1); // number of double dwords - __ load_const_optimized(zero_reg, 0L); // Use as zero register. - - __ cmpdi(CCR1, tmp2_reg, 0); // cnt_dwords even? - __ beq(CCR0, lastdword); // size <= 1 - __ mtctr(tmp1_reg); // Speculatively preload counter for rest loop (>0). - __ cmpdi(CCR0, cnt_dwords_reg, (min_dcbz+1)*cl_dwords-1); // Big enough to ensure >=min_dcbz cache lines are included? - __ neg(tmp1_reg, base_ptr_reg); // bit 0..58: bogus, bit 57..60: (16-(base>>3))%16, bit 61..63: 000 - - __ blt(CCR0, restloop); // Too small. (<31=(2*cl_dwords)-1 is sufficient, but bigger performs better.) - __ rldicl_(tmp1_reg, tmp1_reg, 64-3, 64-cl_dwordaddr_bits); // Extract number of dwords to 128byte boundary=(16-(base>>3))%16. - - __ beq(CCR0, fast); // already 128byte aligned - __ mtctr(tmp1_reg); // Set ctr to hit 128byte boundary (00 since size>=256-8) - - // Clear in first cache line dword-by-dword if not already 128byte aligned. - __ bind(dwloop); - __ std(zero_reg, 0, base_ptr_reg); // Clear 8byte aligned block. - __ addi(base_ptr_reg, base_ptr_reg, 8); - __ bdnz(dwloop); - - // clear 128byte blocks - __ bind(fast); - __ srdi(tmp1_reg, cnt_dwords_reg, cl_dwordaddr_bits); // loop count for 128byte loop (>0 since size>=256-8) - __ andi(tmp2_reg, cnt_dwords_reg, 1); // to check if rest even - - __ mtctr(tmp1_reg); // load counter - __ cmpdi(CCR1, tmp2_reg, 0); // rest even? - __ rldicl_(tmp1_reg, cnt_dwords_reg, 63, 65-cl_dwordaddr_bits); // rest in double dwords - - __ bind(fastloop); - __ dcbz(base_ptr_reg); // Clear 128byte aligned block. - __ addi(base_ptr_reg, base_ptr_reg, cl_size); - __ bdnz(fastloop); - - //__ dcbtst(base_ptr_reg); // Indicate write access to last cache line. - __ beq(CCR0, lastdword); // rest<=1 - __ mtctr(tmp1_reg); // load counter - - // Clear rest. - __ bind(restloop); - __ std(zero_reg, 0, base_ptr_reg); // Clear 8byte aligned block. - __ std(zero_reg, 8, base_ptr_reg); // Clear 8byte aligned block. - __ addi(base_ptr_reg, base_ptr_reg, 16); - __ bdnz(restloop); - - __ bind(lastdword); - __ beq(CCR1, done); - __ std(zero_reg, 0, base_ptr_reg); - __ bind(done); - __ blr(); // return - - return start; - } - #if !defined(PRODUCT) // Wrapper which calls oopDesc::is_oop_or_null() // Only called by MacroAssembler::verify_oop @@ -648,8 +563,40 @@ class StubGenerator: public StubCodeGenerator { // value: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_fill(BasicType t, bool aligned, const char* name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_fill(StubGenStubId stub_id) { + BasicType t; + bool aligned; + + switch (stub_id) { + case jbyte_fill_id: + t = T_BYTE; + aligned = false; + break; + case jshort_fill_id: + t = T_SHORT; + aligned = false; + break; + case jint_fill_id: + t = T_INT; + aligned = false; + break; + case arrayof_jbyte_fill_id: + t = T_BYTE; + aligned = true; + break; + case arrayof_jshort_fill_id: + t = T_SHORT; + aligned = true; + break; + case arrayof_jint_fill_id: + t = T_INT; + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); const Register to = R3_ARG1; // source array address @@ -668,21 +615,21 @@ class StubGenerator: public StubCodeGenerator { shift = 2; // Clone bytes (zero extend not needed because store instructions below ignore high order bytes). __ rldimi(value, value, 8, 48); // 8 bit -> 16 bit - __ cmpdi(CCR0, count, 2< 32 bit break; case T_SHORT: shift = 1; // Clone bytes (zero extend not needed because store instructions below ignore high order bytes). __ rldimi(value, value, 16, 32); // 16 bit -> 32 bit - __ cmpdi(CCR0, count, 2< to or from is aligned -> copy 8 + __ bne(CR0, l_7); // not same alignment -> to or from is aligned -> copy 8 // copy a 2-element word if necessary to align to 8 bytes __ andi_(R0, R3_ARG1, 7); - __ beq(CCR0, l_7); + __ beq(CR0, l_7); __ lwzx(tmp2, R3_ARG1, tmp3); __ addi(R5_ARG3, R5_ARG3, -4); @@ -958,8 +917,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_7); { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 31); - __ ble(CCR0, l_6); // copy 2 at a time if less than 32 elements remain + __ cmpwi(CR0, R5_ARG3, 31); + __ ble(CR0, l_6); // copy 2 at a time if less than 32 elements remain __ srdi(tmp1, R5_ARG3, 5); __ andi_(R5_ARG3, R5_ARG3, 31); @@ -1024,8 +983,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_6); // copy 4 elements at a time - __ cmpwi(CCR0, R5_ARG3, 4); - __ blt(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 4); + __ blt(CR0, l_1); __ srdi(tmp1, R5_ARG3, 2); __ mtctr(tmp1); // is > 0 __ andi_(R5_ARG3, R5_ARG3, 3); @@ -1043,8 +1002,8 @@ class StubGenerator: public StubCodeGenerator { // do single element copy __ bind(l_1); - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_4); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_4); { // FasterArrayCopy __ mtctr(R5_ARG3); @@ -1073,8 +1032,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_conjoint_byte_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_byte_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jbyte_arraycopy_id: + aligned = false; + break; + case arrayof_jbyte_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); @@ -1099,7 +1070,7 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_2); __ addic_(R5_ARG3, R5_ARG3, -1); __ lbzx(tmp1, R3_ARG1, R5_ARG3); - __ bge(CCR0, l_1); + __ bge(CR0, l_1); } __ li(R3_RET, 0); // return 0 __ blr(); @@ -1162,8 +1133,20 @@ class StubGenerator: public StubCodeGenerator { // // 1. check if aligning the backbranch target of loops is beneficial // - address generate_disjoint_short_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_disjoint_short_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jshort_disjoint_arraycopy_id: + aligned = false; + break; + case arrayof_jshort_disjoint_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); Register tmp1 = R6_ARG4; Register tmp2 = R7_ARG5; @@ -1182,19 +1165,19 @@ class StubGenerator: public StubCodeGenerator { UnsafeMemoryAccessMark umam(this, !aligned, false); // don't try anything fancy if arrays don't have many elements __ li(tmp3, 0); - __ cmpwi(CCR0, R5_ARG3, 9); - __ ble(CCR0, l_6); // copy 2 at a time + __ cmpwi(CR0, R5_ARG3, 9); + __ ble(CR0, l_6); // copy 2 at a time if (!aligned) { __ xorr(tmp1, R3_ARG1, R4_ARG2); __ andi_(tmp1, tmp1, 3); - __ bne(CCR0, l_6); // if arrays don't have the same alignment mod 4, do 2 element copy + __ bne(CR0, l_6); // if arrays don't have the same alignment mod 4, do 2 element copy // At this point it is guaranteed that both, from and to have the same alignment mod 4. // Copy 1 element if necessary to align to 4 bytes. __ andi_(tmp1, R3_ARG1, 3); - __ beq(CCR0, l_2); + __ beq(CR0, l_2); __ lhz(tmp2, 0, R3_ARG1); __ addi(R3_ARG1, R3_ARG1, 2); @@ -1209,11 +1192,11 @@ class StubGenerator: public StubCodeGenerator { // Align to 8 bytes, but only if both, from and to, have same alignment mod 8. __ xorr(tmp2, R3_ARG1, R4_ARG2); __ andi_(tmp1, tmp2, 7); - __ bne(CCR0, l_7); // not same alignment mod 8 -> copy 4, either from or to will be unaligned + __ bne(CR0, l_7); // not same alignment mod 8 -> copy 4, either from or to will be unaligned // Copy a 2-element word if necessary to align to 8 bytes. __ andi_(R0, R3_ARG1, 7); - __ beq(CCR0, l_7); + __ beq(CR0, l_7); __ lwzx(tmp2, R3_ARG1, tmp3); __ addi(R5_ARG3, R5_ARG3, -2); @@ -1230,8 +1213,8 @@ class StubGenerator: public StubCodeGenerator { // be unaligned if aligned == false. { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 15); - __ ble(CCR0, l_6); // copy 2 at a time if less than 16 elements remain + __ cmpwi(CR0, R5_ARG3, 15); + __ ble(CR0, l_6); // copy 2 at a time if less than 16 elements remain __ srdi(tmp1, R5_ARG3, 4); __ andi_(R5_ARG3, R5_ARG3, 15); @@ -1295,8 +1278,8 @@ class StubGenerator: public StubCodeGenerator { // copy 2 elements at a time { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 2); - __ blt(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 2); + __ blt(CR0, l_1); __ srdi(tmp1, R5_ARG3, 1); __ andi_(R5_ARG3, R5_ARG3, 1); @@ -1315,8 +1298,8 @@ class StubGenerator: public StubCodeGenerator { // do single element copy __ bind(l_1); - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_4); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_4); { // FasterArrayCopy __ mtctr(R5_ARG3); @@ -1345,8 +1328,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_conjoint_short_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_short_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jshort_arraycopy_id: + aligned = false; + break; + case arrayof_jshort_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); @@ -1371,7 +1366,7 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_2); __ addic_(tmp1, tmp1, -2); __ lhzx(tmp2, R3_ARG1, tmp1); - __ bge(CCR0, l_1); + __ bge(CR0, l_1); } __ li(R3_RET, 0); // return 0 __ blr(); @@ -1400,19 +1395,19 @@ class StubGenerator: public StubCodeGenerator { // for short arrays, just do single element copy __ li(tmp3, 0); - __ cmpwi(CCR0, R5_ARG3, 5); - __ ble(CCR0, l_2); + __ cmpwi(CR0, R5_ARG3, 5); + __ ble(CR0, l_2); if (!aligned) { // check if arrays have same alignment mod 8. __ xorr(tmp1, R3_ARG1, R4_ARG2); __ andi_(R0, tmp1, 7); // Not the same alignment, but ld and std just need to be 4 byte aligned. - __ bne(CCR0, l_4); // to OR from is 8 byte aligned -> copy 2 at a time + __ bne(CR0, l_4); // to OR from is 8 byte aligned -> copy 2 at a time // copy 1 element to align to and from on an 8 byte boundary __ andi_(R0, R3_ARG1, 7); - __ beq(CCR0, l_4); + __ beq(CR0, l_4); __ lwzx(tmp2, R3_ARG1, tmp3); __ addi(R5_ARG3, R5_ARG3, -1); @@ -1425,8 +1420,8 @@ class StubGenerator: public StubCodeGenerator { } { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 7); - __ ble(CCR0, l_2); // copy 1 at a time if less than 8 elements remain + __ cmpwi(CR0, R5_ARG3, 7); + __ ble(CR0, l_2); // copy 1 at a time if less than 8 elements remain __ srdi(tmp1, R5_ARG3, 3); __ andi_(R5_ARG3, R5_ARG3, 7); @@ -1490,8 +1485,8 @@ class StubGenerator: public StubCodeGenerator { // copy 1 element at a time __ bind(l_2); - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_1); { // FasterArrayCopy __ mtctr(R5_ARG3); @@ -1516,8 +1511,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_disjoint_int_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_disjoint_int_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jint_disjoint_arraycopy_id: + aligned = false; + break; + case arrayof_jint_disjoint_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); { @@ -1554,8 +1561,8 @@ class StubGenerator: public StubCodeGenerator { VectorSRegister tmp_vsr2 = VSR2; { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_6); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_6); __ sldi(R5_ARG3, R5_ARG3, 2); __ add(R3_ARG1, R3_ARG1, R5_ARG3); @@ -1567,11 +1574,11 @@ class StubGenerator: public StubCodeGenerator { __ xorr(tmp1, R3_ARG1, R4_ARG2); __ andi_(R0, tmp1, 7); // Not the same alignment, but ld and std just need to be 4 byte aligned. - __ bne(CCR0, l_7); // to OR from is 8 byte aligned -> copy 2 at a time + __ bne(CR0, l_7); // to OR from is 8 byte aligned -> copy 2 at a time // copy 1 element to align to and from on an 8 byte boundary __ andi_(R0, R3_ARG1, 7); - __ beq(CCR0, l_7); + __ beq(CR0, l_7); __ addi(R3_ARG1, R3_ARG1, -4); __ addi(R4_ARG2, R4_ARG2, -4); @@ -1581,8 +1588,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(l_7); } - __ cmpwi(CCR0, R5_ARG3, 7); - __ ble(CCR0, l_5); // copy 1 at a time if less than 8 elements remain + __ cmpwi(CR0, R5_ARG3, 7); + __ ble(CR0, l_5); // copy 1 at a time if less than 8 elements remain __ srdi(tmp1, R5_ARG3, 3); __ andi(R5_ARG3, R5_ARG3, 7); @@ -1639,8 +1646,8 @@ class StubGenerator: public StubCodeGenerator { } } - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_6); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_6); __ bind(l_5); __ mtctr(R5_ARG3); @@ -1663,8 +1670,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_conjoint_int_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_int_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jint_arraycopy_id: + aligned = false; + break; + case arrayof_jint_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); address nooverlap_target = aligned ? @@ -1705,8 +1724,8 @@ class StubGenerator: public StubCodeGenerator { VectorSRegister tmp_vsr2 = VSR2; { // FasterArrayCopy - __ cmpwi(CCR0, R5_ARG3, 3); - __ ble(CCR0, l_3); // copy 1 at a time if less than 4 elements remain + __ cmpwi(CR0, R5_ARG3, 3); + __ ble(CR0, l_3); // copy 1 at a time if less than 4 elements remain __ srdi(tmp1, R5_ARG3, 2); __ andi_(R5_ARG3, R5_ARG3, 3); @@ -1769,8 +1788,8 @@ class StubGenerator: public StubCodeGenerator { // copy 1 element at a time __ bind(l_3); - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_1); { // FasterArrayCopy __ mtctr(R5_ARG3); @@ -1794,8 +1813,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_disjoint_long_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_disjoint_long_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jlong_disjoint_arraycopy_id: + aligned = false; + break; + case arrayof_jlong_disjoint_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); { @@ -1829,8 +1860,8 @@ class StubGenerator: public StubCodeGenerator { Label l_1, l_2, l_3, l_4, l_5; - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_1); { // FasterArrayCopy __ sldi(R5_ARG3, R5_ARG3, 3); @@ -1838,8 +1869,8 @@ class StubGenerator: public StubCodeGenerator { __ add(R4_ARG2, R4_ARG2, R5_ARG3); __ srdi(R5_ARG3, R5_ARG3, 3); - __ cmpwi(CCR0, R5_ARG3, 3); - __ ble(CCR0, l_5); // copy 1 at a time if less than 4 elements remain + __ cmpwi(CR0, R5_ARG3, 3); + __ ble(CR0, l_5); // copy 1 at a time if less than 4 elements remain __ srdi(tmp1, R5_ARG3, 2); __ andi(R5_ARG3, R5_ARG3, 3); @@ -1896,8 +1927,8 @@ class StubGenerator: public StubCodeGenerator { } } - __ cmpwi(CCR0, R5_ARG3, 0); - __ beq(CCR0, l_1); + __ cmpwi(CR0, R5_ARG3, 0); + __ beq(CR0, l_1); __ bind(l_5); __ mtctr(R5_ARG3); @@ -1920,8 +1951,20 @@ class StubGenerator: public StubCodeGenerator { // to: R4_ARG2 // count: R5_ARG3 treated as signed // - address generate_conjoint_long_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_long_copy(StubGenStubId stub_id) { + bool aligned; + switch (stub_id) { + case jlong_arraycopy_id: + aligned = false; + break; + case arrayof_jlong_arraycopy_id: + aligned = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); address nooverlap_target = aligned ? @@ -1949,9 +1992,31 @@ class StubGenerator: public StubCodeGenerator { // count: R5_ARG3 treated as signed // dest_uninitialized: G1 support // - address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_oop_copy(StubGenStubId stub_id) { + bool aligned; + bool dest_uninitialized; + switch (stub_id) { + case oop_arraycopy_id: + aligned = false; + dest_uninitialized = false; + break; + case arrayof_oop_arraycopy_id: + aligned = true; + dest_uninitialized = false; + break; + case oop_arraycopy_uninit_id: + aligned = false; + dest_uninitialized = true; + break; + case arrayof_oop_arraycopy_uninit_id: + aligned = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); address nooverlap_target = aligned ? @@ -1998,8 +2063,31 @@ class StubGenerator: public StubCodeGenerator { // count: R5_ARG3 treated as signed // dest_uninitialized: G1 support // - address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_disjoint_oop_copy(StubGenStubId stub_id) { + bool aligned; + bool dest_uninitialized; + switch (stub_id) { + case oop_disjoint_arraycopy_id: + aligned = false; + dest_uninitialized = false; + break; + case arrayof_oop_disjoint_arraycopy_id: + aligned = true; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_uninit_id: + aligned = false; + dest_uninitialized = true; + break; + case arrayof_oop_disjoint_arraycopy_uninit_id: + aligned = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ function_entry(); assert_positive_int(R5_ARG3); @@ -2039,7 +2127,8 @@ class StubGenerator: public StubCodeGenerator { void generate_type_check(Register sub_klass, Register super_check_offset, Register super_klass, - Register temp, + Register temp1, + Register temp2, Label& L_success) { assert_different_registers(sub_klass, super_check_offset, super_klass); @@ -2047,9 +2136,9 @@ class StubGenerator: public StubCodeGenerator { Label L_miss; - __ check_klass_subtype_fast_path(sub_klass, super_klass, temp, R0, &L_success, &L_miss, nullptr, + __ check_klass_subtype_fast_path(sub_klass, super_klass, temp1, temp2, &L_success, &L_miss, nullptr, super_check_offset); - __ check_klass_subtype_slow_path(sub_klass, super_klass, temp, R0, &L_success); + __ check_klass_subtype_slow_path(sub_klass, super_klass, temp1, temp2, &L_success); // Fall through on failure! __ bind(L_miss); @@ -2066,8 +2155,7 @@ class StubGenerator: public StubCodeGenerator { // ckval: R7 (super_klass) // ret: R3 zero for success; (-1^K) where K is partial transfer count // - address generate_checkcast_copy(const char *name, bool dest_uninitialized) { - + address generate_checkcast_copy(StubGenStubId stub_id) { const Register R3_from = R3_ARG1; // source array address const Register R4_to = R4_ARG2; // destination array address const Register R5_count = R5_ARG3; // elements count @@ -2079,11 +2167,21 @@ class StubGenerator: public StubCodeGenerator { const Register R10_oop = R10_ARG8; // actual oop copied const Register R11_klass = R11_scratch1; // oop._klass const Register R12_tmp = R12_scratch2; + const Register R2_tmp = R2; - const Register R2_minus1 = R2; - + bool dest_uninitialized; + switch (stub_id) { + case checkcast_arraycopy_id: + dest_uninitialized = false; + break; + case checkcast_arraycopy_uninit_id: + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } //__ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ function_entry(); // Assert that int is 64 bit sign extended and arrays are not conjoint. @@ -2094,12 +2192,12 @@ class StubGenerator: public StubCodeGenerator { Label no_overlap; __ subf(tmp1, R3_ARG1, R4_ARG2); // distance in bytes __ sldi(tmp2, R5_ARG3, LogBytesPerHeapOop); // size in bytes - __ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison! - __ cmpld(CCR1, tmp1, tmp2); - __ crnand(CCR0, Assembler::less, CCR1, Assembler::less); + __ cmpld(CR0, R3_ARG1, R4_ARG2); // Use unsigned comparison! + __ cmpld(CR1, tmp1, tmp2); + __ crnand(CR0, Assembler::less, CR1, Assembler::less); // Overlaps if Src before dst and distance smaller than size. // Branch to forward copy routine otherwise. - __ blt(CCR0, no_overlap); + __ blt(CR0, no_overlap); __ stop("overlap in checkcast_copy"); __ bind(no_overlap); } @@ -2118,8 +2216,7 @@ class StubGenerator: public StubCodeGenerator { Label load_element, store_element, store_null, success, do_epilogue; __ or_(R9_remain, R5_count, R5_count); // Initialize loop index, and test it. __ li(R8_offset, 0); // Offset from start of arrays. - __ li(R2_minus1, -1); - __ bne(CCR0, load_element); + __ bne(CR0, load_element); // Empty array: Nothing to do. __ li(R3_RET, 0); // Return 0 on (trivial) success. @@ -2146,8 +2243,8 @@ class StubGenerator: public StubCodeGenerator { } __ addi(R8_offset, R8_offset, heapOopSize); // Step to next offset. - __ add_(R9_remain, R2_minus1, R9_remain); // Decrement the count. - __ beq(CCR0, success); + __ addic_(R9_remain, R9_remain, -1); // Decrement the count. + __ beq(CR0, success); // ======== loop entry is here ======== __ bind(load_element); @@ -2166,7 +2263,7 @@ class StubGenerator: public StubCodeGenerator { __ load_klass(R11_klass, R10_oop); // Query the object klass. - generate_type_check(R11_klass, R6_ckoff, R7_ckval, R12_tmp, + generate_type_check(R11_klass, R6_ckoff, R7_ckval, R12_tmp, R2_tmp, // Branch to this on success: store_element); // ======== end loop ======== @@ -2177,7 +2274,7 @@ class StubGenerator: public StubCodeGenerator { // and report their number to the caller. __ subf_(R5_count, R9_remain, R5_count); __ nand(R3_RET, R5_count, R5_count); // report (-1^K) to caller - __ bne(CCR0, do_epilogue); + __ bne(CR0, do_epilogue); __ blr(); __ bind(success); @@ -2203,8 +2300,7 @@ class StubGenerator: public StubCodeGenerator { // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // - address generate_unsafe_copy(const char* name, - address byte_copy_entry, + address generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { @@ -2217,7 +2313,8 @@ class StubGenerator: public StubCodeGenerator { const Register R7_tmp = R7_ARG5; //__ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); // Bump this on entry, not on exit: @@ -2228,13 +2325,13 @@ class StubGenerator: public StubCodeGenerator { __ orr(R6_bits, R3_from, R4_to); __ orr(R6_bits, R6_bits, R5_count); __ andi_(R0, R6_bits, (BytesPerLong-1)); - __ beq(CCR0, long_copy); + __ beq(CR0, long_copy); __ andi_(R0, R6_bits, (BytesPerInt-1)); - __ beq(CCR0, int_copy); + __ beq(CR0, int_copy); __ andi_(R0, R6_bits, (BytesPerShort-1)); - __ beq(CCR0, short_copy); + __ beq(CR0, short_copy); // byte_copy: __ b(byte_copy_entry); @@ -2273,14 +2370,14 @@ class StubGenerator: public StubCodeGenerator { // if (src_pos + length > arrayOop(src)->length() ) FAIL; __ lwa(array_length, arrayOopDesc::length_offset_in_bytes(), src); __ add(end_pos, src_pos, length); // src_pos + length - __ cmpd(CCR0, end_pos, array_length); - __ bgt(CCR0, L_failed); + __ cmpd(CR0, end_pos, array_length); + __ bgt(CR0, L_failed); // if (dst_pos + length > arrayOop(dst)->length() ) FAIL; __ lwa(array_length, arrayOopDesc::length_offset_in_bytes(), dst); __ add(end_pos, dst_pos, length); // src_pos + length - __ cmpd(CCR0, end_pos, array_length); - __ bgt(CCR0, L_failed); + __ cmpd(CR0, end_pos, array_length); + __ bgt(CR0, L_failed); BLOCK_COMMENT("arraycopy_range_checks done"); } @@ -2300,8 +2397,7 @@ class StubGenerator: public StubCodeGenerator { // R3 == 0 - success // R3 == -1 - need to call System.arraycopy // - address generate_generic_copy(const char *name, - address entry_jbyte_arraycopy, + address generate_generic_copy(address entry_jbyte_arraycopy, address entry_jshort_arraycopy, address entry_jint_arraycopy, address entry_oop_arraycopy, @@ -2324,7 +2420,8 @@ class StubGenerator: public StubCodeGenerator { const Register temp = R2; //__ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); // Bump this on entry, not on exit: @@ -2346,16 +2443,16 @@ class StubGenerator: public StubCodeGenerator { // (8) dst_pos + length must not exceed length of dst. BLOCK_COMMENT("arraycopy initial argument checks"); - __ cmpdi(CCR1, src, 0); // if (src == nullptr) return -1; + __ cmpdi(CR1, src, 0); // if (src == nullptr) return -1; __ extsw_(src_pos, src_pos); // if (src_pos < 0) return -1; - __ cmpdi(CCR5, dst, 0); // if (dst == nullptr) return -1; - __ cror(CCR1, Assembler::equal, CCR0, Assembler::less); + __ cmpdi(CR5, dst, 0); // if (dst == nullptr) return -1; + __ cror(CR1, Assembler::equal, CR0, Assembler::less); __ extsw_(dst_pos, dst_pos); // if (src_pos < 0) return -1; - __ cror(CCR5, Assembler::equal, CCR0, Assembler::less); + __ cror(CR5, Assembler::equal, CR0, Assembler::less); __ extsw_(length, length); // if (length < 0) return -1; - __ cror(CCR1, Assembler::equal, CCR5, Assembler::equal); - __ cror(CCR1, Assembler::equal, CCR0, Assembler::less); - __ beq(CCR1, L_failed); + __ cror(CR1, Assembler::equal, CR5, Assembler::equal); + __ cror(CR1, Assembler::equal, CR0, Assembler::less); + __ beq(CR1, L_failed); BLOCK_COMMENT("arraycopy argument klass checks"); __ load_klass(src_klass, src); @@ -2377,22 +2474,22 @@ class StubGenerator: public StubCodeGenerator { // Handle objArrays completely differently... jint objArray_lh = Klass::array_layout_helper(T_OBJECT); __ load_const_optimized(temp, objArray_lh, R0); - __ cmpw(CCR0, lh, temp); - __ beq(CCR0, L_objArray); + __ cmpw(CR0, lh, temp); + __ beq(CR0, L_objArray); - __ cmpd(CCR5, src_klass, dst_klass); // if (src->klass() != dst->klass()) return -1; - __ cmpwi(CCR6, lh, Klass::_lh_neutral_value); // if (!src->is_Array()) return -1; + __ cmpd(CR5, src_klass, dst_klass); // if (src->klass() != dst->klass()) return -1; + __ cmpwi(CR6, lh, Klass::_lh_neutral_value); // if (!src->is_Array()) return -1; - __ crnand(CCR5, Assembler::equal, CCR6, Assembler::less); - __ beq(CCR5, L_failed); + __ crnand(CR5, Assembler::equal, CR6, Assembler::less); + __ beq(CR5, L_failed); // At this point, it is known to be a typeArray (array_tag 0x3). #ifdef ASSERT { Label L; jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift); __ load_const_optimized(temp, lh_prim_tag_in_place, R0); - __ cmpw(CCR0, lh, temp); - __ bge(CCR0, L); + __ cmpw(CR0, lh, temp); + __ bge(CR0, L); __ stop("must be a primitive array"); __ bind(L); } @@ -2432,17 +2529,17 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("choose copy loop based on element size"); // Using conditional branches with range 32kB. - const int bo = Assembler::bcondCRbiIs1, bi = Assembler::bi0(CCR0, Assembler::equal); - __ cmpwi(CCR0, elsize, 0); + const int bo = Assembler::bcondCRbiIs1, bi = Assembler::bi0(CR0, Assembler::equal); + __ cmpwi(CR0, elsize, 0); __ bc(bo, bi, entry_jbyte_arraycopy); - __ cmpwi(CCR0, elsize, LogBytesPerShort); + __ cmpwi(CR0, elsize, LogBytesPerShort); __ bc(bo, bi, entry_jshort_arraycopy); - __ cmpwi(CCR0, elsize, LogBytesPerInt); + __ cmpwi(CR0, elsize, LogBytesPerInt); __ bc(bo, bi, entry_jint_arraycopy); #ifdef ASSERT { Label L; - __ cmpwi(CCR0, elsize, LogBytesPerLong); - __ beq(CCR0, L); + __ cmpwi(CR0, elsize, LogBytesPerLong); + __ beq(CR0, L); __ stop("must be long copy, but elsize is wrong"); __ bind(L); } @@ -2455,8 +2552,8 @@ class StubGenerator: public StubCodeGenerator { Label L_disjoint_plain_copy, L_checkcast_copy; // test array classes for subtyping - __ cmpd(CCR0, src_klass, dst_klass); // usual case is exact equality - __ bne(CCR0, L_checkcast_copy); + __ cmpd(CR0, src_klass, dst_klass); // usual case is exact equality + __ bne(CR0, L_checkcast_copy); // Identically typed arrays can be copied without element-wise checks. arraycopy_range_checks(src, src_pos, dst, dst_pos, length, @@ -2476,8 +2573,8 @@ class StubGenerator: public StubCodeGenerator { { // Before looking at dst.length, make sure dst is also an objArray. __ lwz(temp, lh_offset, dst_klass); - __ cmpw(CCR0, lh, temp); - __ bne(CCR0, L_failed); + __ cmpw(CR0, lh, temp); + __ bne(CR0, L_failed); // It is safe to examine both src.length and dst.length. arraycopy_range_checks(src, src_pos, dst, dst_pos, length, @@ -2500,7 +2597,7 @@ class StubGenerator: public StubCodeGenerator { int sco_offset = in_bytes(Klass::super_check_offset_offset()); __ lwz(sco_temp, sco_offset, dst_klass); generate_type_check(src_klass, sco_temp, dst_klass, - temp, L_disjoint_plain_copy); + temp, /* temp */ R10_ARG8, L_disjoint_plain_copy); // Fetch destination element klass from the ObjArrayKlass header. int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); @@ -2526,7 +2623,8 @@ class StubGenerator: public StubCodeGenerator { // R5_ARG3 - round key array address generate_aescrypt_encryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); - StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -2654,8 +2752,8 @@ class StubGenerator: public StubCodeGenerator { __ vec_perm (vKey2, vTmp1, keyPerm); // if all round keys are loaded, skip next 4 rounds - __ cmpwi (CCR0, keylen, 44); - __ beq (CCR0, L_doLast); + __ cmpwi (CR0, keylen, 44); + __ beq (CR0, L_doLast); // 10th - 11th rounds __ vcipher (vRet, vRet, vKey1); @@ -2672,12 +2770,12 @@ class StubGenerator: public StubCodeGenerator { __ vec_perm (vKey2, vTmp1, keyPerm); // if all round keys are loaded, skip next 2 rounds - __ cmpwi (CCR0, keylen, 52); - __ beq (CCR0, L_doLast); + __ cmpwi (CR0, keylen, 52); + __ beq (CR0, L_doLast); #ifdef ASSERT - __ cmpwi (CCR0, keylen, 60); - __ bne (CCR0, L_error); + __ cmpwi (CR0, keylen, 60); + __ bne (CR0, L_error); #endif // 12th - 13th rounds @@ -2733,7 +2831,8 @@ class StubGenerator: public StubCodeGenerator { // R5_ARG3 - K (key) in little endian int array address generate_aescrypt_decryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); - StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -2791,15 +2890,15 @@ class StubGenerator: public StubCodeGenerator { __ vsldoi (keyPerm, keyPerm, keyPerm, 8); #endif - __ cmpwi (CCR0, keylen, 44); - __ beq (CCR0, L_do44); + __ cmpwi (CR0, keylen, 44); + __ beq (CR0, L_do44); - __ cmpwi (CCR0, keylen, 52); - __ beq (CCR0, L_do52); + __ cmpwi (CR0, keylen, 52); + __ beq (CR0, L_do52); #ifdef ASSERT - __ cmpwi (CCR0, keylen, 60); - __ bne (CCR0, L_error); + __ cmpwi (CR0, keylen, 60); + __ bne (CR0, L_error); #endif // load the 15th round key to vKey1 @@ -2970,9 +3069,20 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_sha256_implCompress(bool multi_block, const char *name) { + address generate_sha256_implCompress(StubGenStubId stub_id) { assert(UseSHA, "need SHA instructions"); - StubCodeMark mark(this, "StubRoutines", name); + bool multi_block; + switch (stub_id) { + case sha256_implCompress_id: + multi_block = false; + break; + case sha256_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); address start = __ function_entry(); __ sha256 (multi_block); @@ -2981,9 +3091,20 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_sha512_implCompress(bool multi_block, const char *name) { + address generate_sha512_implCompress(StubGenStubId stub_id) { assert(UseSHA, "need SHA instructions"); - StubCodeMark mark(this, "StubRoutines", name); + bool multi_block; + switch (stub_id) { + case sha512_implCompress_id: + multi_block = false; + break; + case sha512_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); address start = __ function_entry(); __ sha512 (multi_block); @@ -2994,7 +3115,8 @@ class StubGenerator: public StubCodeGenerator { address generate_data_cache_writeback() { const Register cacheline = R3_ARG1; - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ cache_wb(Address(cacheline)); @@ -3007,12 +3129,12 @@ class StubGenerator: public StubCodeGenerator { const Register is_presync = R3_ARG1; Register temp = R4; Label SKIP; - - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_sync_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ andi_(temp, is_presync, 1); - __ bne(CCR0, SKIP); + __ bne(CR0, SKIP); __ cache_wbsync(false); // post sync => emit 'sync' __ bind(SKIP); // pre sync => emit nothing __ blr(); @@ -3028,48 +3150,46 @@ class StubGenerator: public StubCodeGenerator { UnsafeMemoryAccess::set_common_exit_stub_pc(ucm_common_error_exit); // non-aligned disjoint versions - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy"); - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, "jint_disjoint_arraycopy"); - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(false, "jlong_disjoint_arraycopy"); - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy", false); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(false, "oop_disjoint_arraycopy_uninit", true); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(StubGenStubId::jbyte_disjoint_arraycopy_id); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(StubGenStubId::jshort_disjoint_arraycopy_id); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(StubGenStubId::jint_disjoint_arraycopy_id); + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy(StubGenStubId::jlong_disjoint_arraycopy_id); + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy(StubGenStubId::oop_disjoint_arraycopy_id); + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(StubGenStubId::oop_disjoint_arraycopy_uninit_id); // aligned disjoint versions - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, "arrayof_jbyte_disjoint_arraycopy"); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy"); - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, "arrayof_jint_disjoint_arraycopy"); - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, "arrayof_jlong_disjoint_arraycopy"); - StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(true, "arrayof_oop_disjoint_arraycopy", false); - StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(true, "oop_disjoint_arraycopy_uninit", true); + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id); + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(StubGenStubId::arrayof_jint_disjoint_arraycopy_id); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(StubGenStubId::arrayof_jlong_disjoint_arraycopy_id); + StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy(StubGenStubId::arrayof_oop_disjoint_arraycopy_id); + StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy(StubGenStubId::oop_disjoint_arraycopy_uninit_id); // non-aligned conjoint versions - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, "jbyte_arraycopy"); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); - StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, "jint_arraycopy"); - StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(false, "jlong_arraycopy"); - StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(false, "oop_arraycopy", false); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_oop_copy(false, "oop_arraycopy_uninit", true); + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(StubGenStubId::jbyte_arraycopy_id); + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(StubGenStubId::jshort_arraycopy_id); + StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(StubGenStubId::jint_arraycopy_id); + StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy(StubGenStubId::jlong_arraycopy_id); + StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::oop_arraycopy_id); + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::oop_arraycopy_uninit_id); // aligned conjoint versions - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, "arrayof_jbyte_arraycopy"); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy"); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, "arrayof_jint_arraycopy"); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(true, "arrayof_jlong_arraycopy"); - StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", false); - StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(true, "arrayof_oop_arraycopy", true); + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(StubGenStubId::arrayof_jbyte_arraycopy_id); + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(StubGenStubId::arrayof_jshort_arraycopy_id); + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(StubGenStubId::arrayof_jint_arraycopy_id); + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(StubGenStubId::arrayof_jlong_arraycopy_id); + StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_id); + StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_id); // special/generic versions - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", false); - StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", true); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_id); + StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_uninit_id); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", - STUB_ENTRY(jbyte_arraycopy()), + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(STUB_ENTRY(jbyte_arraycopy()), STUB_ENTRY(jshort_arraycopy()), STUB_ENTRY(jint_arraycopy()), STUB_ENTRY(jlong_arraycopy())); - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", - STUB_ENTRY(jbyte_arraycopy()), + StubRoutines::_generic_arraycopy = generate_generic_copy(STUB_ENTRY(jbyte_arraycopy()), STUB_ENTRY(jshort_arraycopy()), STUB_ENTRY(jint_arraycopy()), STUB_ENTRY(oop_arraycopy()), @@ -3080,12 +3200,12 @@ class StubGenerator: public StubCodeGenerator { // fill routines #ifdef COMPILER2 if (OptimizeFill) { - StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); - StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); - StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); - StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); - StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); - StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); + StubRoutines::_jbyte_fill = generate_fill(StubGenStubId::jbyte_fill_id); + StubRoutines::_jshort_fill = generate_fill(StubGenStubId::jshort_fill_id); + StubRoutines::_jint_fill = generate_fill(StubGenStubId::jint_fill_id); + StubRoutines::_arrayof_jbyte_fill = generate_fill(StubGenStubId::arrayof_jbyte_fill_id); + StubRoutines::_arrayof_jshort_fill = generate_fill(StubGenStubId::arrayof_jshort_fill_id); + StubRoutines::_arrayof_jint_fill = generate_fill(StubGenStubId::arrayof_jint_fill_id); } #endif } @@ -3103,7 +3223,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_multiplyToLen() { - StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); + StubGenStubId stub_id = StubGenStubId::multiplyToLen_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -3179,7 +3300,8 @@ class StubGenerator: public StubCodeGenerator { */ address generate_mulAdd() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "mulAdd"); + StubGenStubId stub_id = StubGenStubId::mulAdd_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -3209,7 +3331,8 @@ class StubGenerator: public StubCodeGenerator { */ address generate_squareToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "squareToLen"); + StubGenStubId stub_id = StubGenStubId::squareToLen_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); @@ -3269,10 +3392,10 @@ class StubGenerator: public StubCodeGenerator { // Store the squares, right shifted one bit (i.e., divided by 2) __ subi (out_aux, out, 8); __ subi (in_aux, in, 4); - __ cmpwi (CCR0, in_len, 0); + __ cmpwi (CR0, in_len, 0); // Initialize lplw outside of the loop __ xorr (lplw, lplw, lplw); - __ ble (CCR0, SKIP_LOOP_SQUARE); // in_len <= 0 + __ ble (CR0, SKIP_LOOP_SQUARE); // in_len <= 0 __ mtctr (in_len); __ bind(LOOP_SQUARE); @@ -3295,8 +3418,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(SKIP_LOOP_SQUARE); // Add in off-diagonal sums - __ cmpwi (CCR0, in_len, 0); - __ ble (CCR0, SKIP_DIAGONAL_SUM); + __ cmpwi (CR0, in_len, 0); + __ ble (CR0, SKIP_DIAGONAL_SUM); // Avoid CTR usage here in order to use it at mulAdd __ subi (i_minus1, in_len, 1); __ li (offset, 4); @@ -3327,25 +3450,25 @@ class StubGenerator: public StubCodeGenerator { // if (((uint64_t)s >> 32) != 0) { __ srdi_ (a, b, 32); - __ beq (CCR0, SKIP_ADDONE); + __ beq (CR0, SKIP_ADDONE); // while (--mlen >= 0) { __ bind(LOOP_ADDONE); __ subi (mlen, mlen, 4); - __ cmpwi (CCR0, mlen, 0); - __ beq (CCR0, SKIP_ADDONE); + __ cmpwi (CR0, mlen, 0); + __ beq (CR0, SKIP_ADDONE); // if (--offset_aux < 0) { // Carry out of number __ subi (off_aux, off_aux, 4); - __ cmpwi (CCR0, off_aux, 0); - __ blt (CCR0, SKIP_ADDONE); + __ cmpwi (CR0, off_aux, 0); + __ blt (CR0, SKIP_ADDONE); // } else { __ lwzx (b, off_aux, out); __ addi (b, b, 1); __ stwx (b, off_aux, out); - __ cmpwi (CCR0, b, 0); - __ bne (CCR0, SKIP_ADDONE); + __ cmpwi (CR0, b, 0); + __ bne (CR0, SKIP_ADDONE); __ b (LOOP_ADDONE); __ bind(SKIP_ADDONE); @@ -3353,16 +3476,16 @@ class StubGenerator: public StubCodeGenerator { __ addi (offset, offset, 8); __ subi (i_minus1, i_minus1, 1); - __ cmpwi (CCR0, i_minus1, 0); - __ bge (CCR0, LOOP_DIAGONAL_SUM); + __ cmpwi (CR0, i_minus1, 0); + __ bge (CR0, LOOP_DIAGONAL_SUM); __ bind(SKIP_DIAGONAL_SUM); // Shift back up and set low bit // Shifts 1 bit left up to len positions. Assumes no leading zeros // begin - __ cmpwi (CCR0, out_len, 0); - __ ble (CCR0, SKIP_LSHIFT); + __ cmpwi (CR0, out_len, 0); + __ ble (CR0, SKIP_LSHIFT); __ li (i, 0); __ lwz (c, 0, out); __ subi (b, out_len, 1); @@ -3442,9 +3565,20 @@ class StubGenerator: public StubCodeGenerator { * R3_RET - int crc result */ // Compute CRC32 function. - address generate_CRC32_updateBytes(bool is_crc32c) { + address generate_CRC32_updateBytes(StubGenStubId stub_id) { + bool is_crc32c; + switch (stub_id) { + case updateBytesCRC32_id: + is_crc32c = false; + break; + case updateBytesCRC32C_id: + is_crc32c = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", is_crc32c ? "CRC32C_updateBytes" : "CRC32_updateBytes"); + StubCodeMark mark(this, stub_id); address start = __ function_entry(); // Remember stub start address (is rtn value). __ crc32(R3_ARG1, R4_ARG2, R5_ARG3, R2, R6, R7, R8, R9, R10, R11, R12, is_crc32c); __ blr(); @@ -3471,7 +3605,8 @@ class StubGenerator: public StubCodeGenerator { address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); address stub_address = __ pc(); @@ -3495,10 +3630,10 @@ class StubGenerator: public StubCodeGenerator { __ restore_LR(R3_RET /* used as tmp register */); __ restore_volatile_gprs(R1_SP, -nbytes_save, true); - __ cmpdi(CCR0, R0, 0); + __ cmpdi(CR0, R0, 0); // Return to prologue if no deoptimization is required (bnelr) - __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CCR0, Assembler::equal), Assembler::bhintIsTaken); + __ bclr(Assembler::bcondCRbiIs1, Assembler::bi0(CR0, Assembler::equal), Assembler::bhintIsTaken); // Deoptimization required. // For actually handling the deoptimization, the 'wrong method stub' is invoked. @@ -3568,7 +3703,8 @@ class StubGenerator: public StubCodeGenerator { // Base64 decodeBlock intrinsic address generate_base64_decodeBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "base64_decodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_decodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); typedef struct { @@ -3779,7 +3915,7 @@ class StubGenerator: public StubCodeGenerator { // = sl >> block_size_shift. After the shift, if sl <= 0, there's too // little data to be processed by this intrinsic. __ srawi_(sl, sl, block_size_shift); - __ ble(CCR0, return_zero); + __ ble(CR0, return_zero); __ mtctr(sl); // Clear the other two parameter registers upper 32 bits. @@ -3818,8 +3954,8 @@ class StubGenerator: public StubCodeGenerator { // The rest of the constants use different values depending on the // setting of isURL - __ cmpwi(CCR0, isURL, 0); - __ beq(CCR0, not_URL); + __ cmpwi(CR0, isURL, 0); + __ beq(CR0, not_URL); // isURL != 0 (true) if (PowerArchitecturePPC64 >= 10) { @@ -3909,11 +4045,11 @@ class StubGenerator: public StubCodeGenerator { // __ vcmpequb_(non_match, non_match, vec_0s); } - // vmcmpequb_ sets the EQ bit of CCR6 if no elements compare equal. + // vmcmpequb_ sets the EQ bit of CR6 if no elements compare equal. // Any element comparing equal to zero means there is an error in // that element. Note that the comparison result register - // non_match is not referenced again. Only CCR6-EQ matters. - __ bne_predict_not_taken(CCR6, loop_exit); + // non_match is not referenced again. Only CR6-EQ matters. + __ bne_predict_not_taken(CR6, loop_exit); // The Base64 characters had no errors, so add the offsets, which in // the case of Power10 is a constant vector of all 0x80's (see earlier @@ -4156,7 +4292,8 @@ class StubGenerator: public StubCodeGenerator { address generate_base64_encodeBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "base64_encodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_encodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ function_entry(); typedef struct { @@ -4313,8 +4450,8 @@ class StubGenerator: public StubCodeGenerator { // Use a different translation lookup table depending on the // setting of isURL - __ cmpdi(CCR0, isURL, 0); - __ beq(CCR0, not_URL); + __ cmpdi(CR0, isURL, 0); + __ beq(CR0, not_URL); __ lxv(vec_base64_48_63->to_vsr(), BLK_OFFSETOF(base64_48_63_URL_val), const_ptr); __ b(calculate_size); @@ -4331,8 +4468,8 @@ class StubGenerator: public StubCodeGenerator { // __ sub(size, sl, sp); __ subi(size, size, 4); - __ cmpdi(CCR7, size, block_size); - __ bgt(CCR7, calculate_blocked_size); + __ cmpdi(CR7, size, block_size); + __ bgt(CR7, calculate_blocked_size); __ mr(remaining, size); // Add the 4 back into remaining again __ addi(remaining, remaining, 4); @@ -4390,8 +4527,8 @@ class StubGenerator: public StubCodeGenerator { __ addi(bytes_to_write, bytes_to_write, 2); __ divwu(bytes_to_write, bytes_to_write, three); - __ cmpwi(CCR7, bytes_to_write, 16); - __ ble_predict_taken(CCR7, le_16_to_write); + __ cmpwi(CR7, bytes_to_write, 16); + __ ble_predict_taken(CR7, le_16_to_write); __ stxv(expanded->to_vsr(), 0, out); // We've processed 12 of the 13-15 data bytes, so advance the pointers, @@ -4412,7 +4549,7 @@ class StubGenerator: public StubCodeGenerator { __ add(out, out, bytes_to_write); __ li(pad_char, '='); - __ rlwinm_(modulo_chars, bytes_to_write, 0, 30, 31); // bytes_to_write % 4, set CCR0 + __ rlwinm_(modulo_chars, bytes_to_write, 0, 30, 31); // bytes_to_write % 4, set CR0 // Examples: // remaining bytes_to_write modulo_chars num pad chars // 0 0 0 0 @@ -4426,9 +4563,9 @@ class StubGenerator: public StubCodeGenerator { // 13 18 2 2 // 14 19 3 1 // 15 20 0 0 - __ beq(CCR0, no_pad); - __ cmpwi(CCR7, modulo_chars, 3); - __ beq(CCR7, one_pad_char); + __ beq(CR0, no_pad); + __ cmpwi(CR7, modulo_chars, 3); + __ beq(CR7, one_pad_char); // two pad chars __ stb(pad_char, out); @@ -4445,10 +4582,10 @@ class StubGenerator: public StubCodeGenerator { #endif // VM_LITTLE_ENDIAN -address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); +void generate_lookup_secondary_supers_table_stub() { + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_id; + StubCodeMark mark(this, stub_id); - address start = __ pc(); const Register r_super_klass = R4_ARG2, r_array_base = R3_ARG1, @@ -4458,17 +4595,19 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { r_bitmap = R11_scratch1, result = R8_ARG6; - __ lookup_secondary_supers_table(r_sub_klass, r_super_klass, - r_array_base, r_array_length, r_array_index, - r_bitmap, result, super_klass_index); - __ blr(); - - return start; + for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, + r_array_base, r_array_length, r_array_index, + r_bitmap, result, slot); + __ blr(); + } } // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub() { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table_slow_path"); + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_slow_path_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register @@ -4485,13 +4624,33 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { return start; } - address generate_cont_thaw(const char* label, Continuation::thaw_kind kind) { + address generate_cont_thaw(StubGenStubId stub_id) { if (!Continuations::enabled()) return nullptr; - bool return_barrier = Continuation::is_thaw_return_barrier(kind); - bool return_barrier_exception = Continuation::is_thaw_return_barrier_exception(kind); + Continuation::thaw_kind kind; + bool return_barrier; + bool return_barrier_exception; - StubCodeMark mark(this, "StubRoutines", label); + switch (stub_id) { + case cont_thaw_id: + kind = Continuation::thaw_top; + return_barrier = false; + return_barrier_exception = false; + break; + case cont_returnBarrier_id: + kind = Continuation::thaw_return_barrier; + return_barrier = true; + return_barrier_exception = false; + break; + case cont_returnBarrierExc_id: + kind = Continuation::thaw_return_barrier_exception; + return_barrier = true; + return_barrier_exception = true; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); Register tmp1 = R10_ARG8; Register tmp2 = R9_ARG7; @@ -4511,13 +4670,13 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { __ ld_ptr(R1_SP, JavaThread::cont_entry_offset(), R16_thread); #ifdef ASSERT __ ld_ptr(tmp2, _abi0(callers_sp), R1_SP); - __ cmpd(CCR0, tmp1, tmp2); + __ cmpd(CR0, tmp1, tmp2); __ asm_assert_eq(FILE_AND_LINE ": callers sp is corrupt"); #endif } #ifdef ASSERT __ ld_ptr(tmp1, JavaThread::cont_entry_offset(), R16_thread); - __ cmpd(CCR0, R1_SP, tmp1); + __ cmpd(CR0, R1_SP, tmp1); __ asm_assert_eq(FILE_AND_LINE ": incorrect R1_SP"); #endif @@ -4526,14 +4685,14 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { #ifdef ASSERT DEBUG_ONLY(__ ld_ptr(tmp1, JavaThread::cont_entry_offset(), R16_thread)); - DEBUG_ONLY(__ cmpd(CCR0, R1_SP, tmp1)); + DEBUG_ONLY(__ cmpd(CR0, R1_SP, tmp1)); __ asm_assert_eq(FILE_AND_LINE ": incorrect R1_SP"); #endif // R3_RET contains the size of the frames to thaw, 0 if overflow or no more frames Label thaw_success; - __ cmpdi(CCR0, R3_RET, 0); - __ bne(CCR0, thaw_success); + __ cmpdi(CR0, R3_RET, 0); + __ bne(CR0, thaw_success); __ load_const_optimized(tmp1, (SharedRuntime::throw_StackOverflowError_entry()), R0); __ mtctr(tmp1); __ bctr(); __ bind(thaw_success); @@ -4580,22 +4739,23 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { } address generate_cont_thaw() { - return generate_cont_thaw("Cont thaw", Continuation::thaw_top); + return generate_cont_thaw(StubGenStubId::cont_thaw_id); } // TODO: will probably need multiple return barriers depending on return type address generate_cont_returnBarrier() { - return generate_cont_thaw("Cont thaw return barrier", Continuation::thaw_return_barrier); + return generate_cont_thaw(StubGenStubId::cont_returnBarrier_id); } address generate_cont_returnBarrier_exception() { - return generate_cont_thaw("Cont thaw return barrier exception", Continuation::thaw_return_barrier_exception); + return generate_cont_thaw(StubGenStubId::cont_returnBarrierExc_id); } address generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines","Continuation preempt stub"); + StubGenStubId stub_id = StubGenStubId::cont_preempt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ clobber_nonvolatile_registers(); // Except R16_thread and R29_TOC @@ -4607,8 +4767,8 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { Label preemption_cancelled; __ lbz(R11_scratch1, in_bytes(JavaThread::preemption_cancelled_offset()), R16_thread); - __ cmpwi(CCR0, R11_scratch1, 0); - __ bne(CCR0, preemption_cancelled); + __ cmpwi(CR0, R11_scratch1, 0); + __ bne(CR0, preemption_cancelled); // Remove enterSpecial frame from the stack and return to Continuation.run() to unmount. SharedRuntime::continuation_enter_cleanup(_masm); @@ -4630,7 +4790,8 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { - StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_exception_handler_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Native caller has no idea how to handle exceptions, @@ -4648,7 +4809,8 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { // R19_method = result Method* address generate_upcall_stub_load_target() { - StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_load_target_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ resolve_global_jobject(R3_ARG1, R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS); @@ -4688,13 +4850,13 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { // CRC32 Intrinsics. if (UseCRC32Intrinsics) { StubRoutines::_crc_table_adr = StubRoutines::ppc::generate_crc_constants(REVERSE_CRC32_POLY); - StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes(false); + StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes(StubGenStubId::updateBytesCRC32_id); } // CRC32C Intrinsics. if (UseCRC32CIntrinsics) { StubRoutines::_crc32c_table_addr = StubRoutines::ppc::generate_crc_constants(REVERSE_CRC32C_POLY); - StubRoutines::_updateBytesCRC32C = generate_CRC32_updateBytes(true); + StubRoutines::_updateBytesCRC32C = generate_CRC32_updateBytes(StubGenStubId::updateBytesCRC32C_id); } if (VM_Version::supports_float16()) { @@ -4727,15 +4889,14 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { // arraycopy stubs used by compilers generate_arraycopy_stubs(); +#ifdef COMPILER2 if (UseSecondarySupersTable) { StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); if (!InlineSecondarySupersTest) { - for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] - = generate_lookup_secondary_supers_table_stub(slot); - } + generate_lookup_secondary_supers_table_stub(); } } +#endif // COMPILER2 StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler(); StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target(); @@ -4776,12 +4937,12 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { } if (UseSHA256Intrinsics) { - StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); - StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(StubGenStubId::sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { - StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); - StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); + StubRoutines::_sha512_implCompress = generate_sha512_implCompress(StubGenStubId::sha512_implCompress_id); + StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } #ifdef VM_LITTLE_ENDIAN @@ -4795,27 +4956,28 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } }; -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } + diff --git a/src/hotspot/cpu/ppc/stubRoutines_ppc.hpp b/src/hotspot/cpu/ppc/stubRoutines_ppc.hpp index 4db0227e81b4e..a542d7947f85f 100644 --- a/src/hotspot/cpu/ppc/stubRoutines_ppc.hpp +++ b/src/hotspot/cpu/ppc/stubRoutines_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,14 +32,17 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + enum platform_dependent_constants { - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 20000, - _continuation_stubs_code_size = 2000, - _compiler_stubs_code_size = 24000, - _final_stubs_code_size = 24000 + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + // CRC32 Intrinsics. #define CRC32_TABLE_SIZE (4 * 256) #define REVERSE_CRC32_POLY 0xEDB88320 diff --git a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp index 7df905b90682c..60cca4efb5771 100644 --- a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/os.hpp" #include "runtime/stubRoutines.hpp" diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 9147dfc1677ab..544de15d3f24a 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015, 2024 SAP SE. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "compiler/disassembler.hpp" @@ -144,12 +143,12 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // TODO PPC port: requires change in shared code. //assert(in_bytes(AccessFlags::flags_offset()) == 0, // "MethodDesc._access_flags == MethodDesc._access_flags._flags"); - // _access_flags must be a 32 bit value. - assert(sizeof(AccessFlags) == 4, "wrong size"); - __ lwa(R11_scratch1/*access_flags*/, method_(access_flags)); + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "wrong size"); + __ lhz(R11_scratch1/*access_flags*/, method_(access_flags)); // testbit with condition register. - __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT); - __ btrue(CCR0, L); + __ testbitdi(CR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT); + __ btrue(CR0, L); // For non-static functions, pass "this" in R4_ARG2 and copy it // to 2nd C-arg slot. // We need to box the Java object here, so we use arg_java @@ -176,8 +175,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // signature points to '(' at entry #ifdef ASSERT __ lbz(sig_byte, 0, signature); - __ cmplwi(CCR0, sig_byte, '('); - __ bne(CCR0, do_dontreachhere); + __ cmplwi(CR0, sig_byte, '('); + __ bne(CR0, do_dontreachhere); #endif __ bind(loop_start); @@ -185,41 +184,41 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ addi(argcnt, argcnt, 1); __ lbzu(sig_byte, 1, signature); - __ cmplwi(CCR0, sig_byte, ')'); // end of signature - __ beq(CCR0, loop_end); + __ cmplwi(CR0, sig_byte, ')'); // end of signature + __ beq(CR0, loop_end); - __ cmplwi(CCR0, sig_byte, 'B'); // byte - __ beq(CCR0, do_int); + __ cmplwi(CR0, sig_byte, 'B'); // byte + __ beq(CR0, do_int); - __ cmplwi(CCR0, sig_byte, 'C'); // char - __ beq(CCR0, do_int); + __ cmplwi(CR0, sig_byte, 'C'); // char + __ beq(CR0, do_int); - __ cmplwi(CCR0, sig_byte, 'D'); // double - __ beq(CCR0, do_double); + __ cmplwi(CR0, sig_byte, 'D'); // double + __ beq(CR0, do_double); - __ cmplwi(CCR0, sig_byte, 'F'); // float - __ beq(CCR0, do_float); + __ cmplwi(CR0, sig_byte, 'F'); // float + __ beq(CR0, do_float); - __ cmplwi(CCR0, sig_byte, 'I'); // int - __ beq(CCR0, do_int); + __ cmplwi(CR0, sig_byte, 'I'); // int + __ beq(CR0, do_int); - __ cmplwi(CCR0, sig_byte, 'J'); // long - __ beq(CCR0, do_long); + __ cmplwi(CR0, sig_byte, 'J'); // long + __ beq(CR0, do_long); - __ cmplwi(CCR0, sig_byte, 'S'); // short - __ beq(CCR0, do_int); + __ cmplwi(CR0, sig_byte, 'S'); // short + __ beq(CR0, do_int); - __ cmplwi(CCR0, sig_byte, 'Z'); // boolean - __ beq(CCR0, do_int); + __ cmplwi(CR0, sig_byte, 'Z'); // boolean + __ beq(CR0, do_int); - __ cmplwi(CCR0, sig_byte, 'L'); // object - __ beq(CCR0, do_object); + __ cmplwi(CR0, sig_byte, 'L'); // object + __ beq(CR0, do_object); - __ cmplwi(CCR0, sig_byte, '['); // array - __ beq(CCR0, do_array); + __ cmplwi(CR0, sig_byte, '['); // array + __ beq(CR0, do_array); - // __ cmplwi(CCR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type - // __ beq(CCR0, do_void); + // __ cmplwi(CR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type + // __ beq(CR0, do_void); __ bind(do_dontreachhere); @@ -232,16 +231,16 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ bind(start_skip); __ lbzu(sig_byte, 1, signature); - __ cmplwi(CCR0, sig_byte, '['); - __ beq(CCR0, start_skip); // skip further brackets - __ cmplwi(CCR0, sig_byte, '9'); - __ bgt(CCR0, end_skip); // no optional size - __ cmplwi(CCR0, sig_byte, '0'); - __ bge(CCR0, start_skip); // skip optional size + __ cmplwi(CR0, sig_byte, '['); + __ beq(CR0, start_skip); // skip further brackets + __ cmplwi(CR0, sig_byte, '9'); + __ bgt(CR0, end_skip); // no optional size + __ cmplwi(CR0, sig_byte, '0'); + __ bge(CR0, start_skip); // skip optional size __ bind(end_skip); - __ cmplwi(CCR0, sig_byte, 'L'); - __ beq(CCR0, do_object); // for arrays of objects, the name of the object must be skipped + __ cmplwi(CR0, sig_byte, 'L'); + __ beq(CR0, do_object); // for arrays of objects, the name of the object must be skipped __ b(do_boxed); // otherwise, go directly to do_boxed } @@ -250,8 +249,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { Label L; __ bind(L); __ lbzu(sig_byte, 1, signature); - __ cmplwi(CCR0, sig_byte, ';'); - __ bne(CCR0, L); + __ cmplwi(CR0, sig_byte, ';'); + __ bne(CR0, L); } // Need to box the Java object here, so we use arg_java (address of // current Java stack slot) as argument and don't dereference it as @@ -259,16 +258,16 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { Label do_null; __ bind(do_boxed); __ ld(R0,0, arg_java); - __ cmpdi(CCR0, R0, 0); + __ cmpdi(CR0, R0, 0); __ li(intSlot,0); - __ beq(CCR0, do_null); + __ beq(CR0, do_null); __ mr(intSlot, arg_java); __ bind(do_null); __ std(intSlot, 0, arg_c); __ addi(arg_java, arg_java, -BytesPerWord); __ addi(arg_c, arg_c, BytesPerWord); - __ cmplwi(CCR0, argcnt, max_int_register_arguments); - __ blt(CCR0, move_intSlot_to_ARG); + __ cmplwi(CR0, argcnt, max_int_register_arguments); + __ blt(CR0, move_intSlot_to_ARG); __ b(loop_start); __ bind(do_int); @@ -276,8 +275,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ std(intSlot, 0, arg_c); __ addi(arg_java, arg_java, -BytesPerWord); __ addi(arg_c, arg_c, BytesPerWord); - __ cmplwi(CCR0, argcnt, max_int_register_arguments); - __ blt(CCR0, move_intSlot_to_ARG); + __ cmplwi(CR0, argcnt, max_int_register_arguments); + __ blt(CR0, move_intSlot_to_ARG); __ b(loop_start); __ bind(do_long); @@ -285,8 +284,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ std(intSlot, 0, arg_c); __ addi(arg_java, arg_java, - 2 * BytesPerWord); __ addi(arg_c, arg_c, BytesPerWord); - __ cmplwi(CCR0, argcnt, max_int_register_arguments); - __ blt(CCR0, move_intSlot_to_ARG); + __ cmplwi(CR0, argcnt, max_int_register_arguments); + __ blt(CR0, move_intSlot_to_ARG); __ b(loop_start); __ bind(do_float); @@ -294,8 +293,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ stfs(floatSlot, Argument::float_on_stack_offset_in_bytes_c, arg_c); __ addi(arg_java, arg_java, -BytesPerWord); __ addi(arg_c, arg_c, BytesPerWord); - __ cmplwi(CCR0, fpcnt, max_fp_register_arguments); - __ blt(CCR0, move_floatSlot_to_FARG); + __ cmplwi(CR0, fpcnt, max_fp_register_arguments); + __ blt(CR0, move_floatSlot_to_FARG); __ b(loop_start); __ bind(do_double); @@ -303,8 +302,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { __ stfd(floatSlot, 0, arg_c); __ addi(arg_java, arg_java, - 2 * BytesPerWord); __ addi(arg_c, arg_c, BytesPerWord); - __ cmplwi(CCR0, fpcnt, max_fp_register_arguments); - __ blt(CCR0, move_floatSlot_to_FARG); + __ cmplwi(CR0, fpcnt, max_fp_register_arguments); + __ blt(CR0, move_floatSlot_to_FARG); __ b(loop_start); __ bind(loop_end); @@ -511,8 +510,8 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { __ ld(R3_RET, Interpreter::stackElementSize, R15_esp); // get receiver // Check if receiver == nullptr and go the slow path. - __ cmpdi(CCR0, R3_RET, 0); - __ beq(CCR0, slow_path); + __ cmpdi(CR0, R3_RET, 0); + __ beq(CR0, slow_path); __ load_heap_oop(R3_RET, referent_offset, R3_RET, /* non-volatile temp */ R31, R11_scratch1, @@ -726,8 +725,8 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow) { if (ProfileInterpreter) { const Register Rmdo = R3_counters; __ ld(Rmdo, in_bytes(Method::method_data_offset()), R19_method); - __ cmpdi(CCR0, Rmdo, 0); - __ beq(CCR0, no_mdo); + __ cmpdi(CR0, Rmdo, 0); + __ beq(CR0, no_mdo); // Increment invocation counter in the MDO. const int mdo_ic_offs = in_bytes(MethodData::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); @@ -736,7 +735,7 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow) { __ addi(Rscratch2, Rscratch2, increment); __ stw(Rscratch2, mdo_ic_offs, Rmdo); __ and_(Rscratch1, Rscratch2, Rscratch1); - __ bne(CCR0, done); + __ bne(CR0, done); __ b(*overflow); } @@ -749,7 +748,7 @@ void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow) { __ addi(Rscratch2, Rscratch2, increment); __ stw(Rscratch2, mo_ic_offs, R3_counters); __ and_(Rscratch1, Rscratch2, Rscratch1); - __ beq(CCR0, *overflow); + __ beq(CR0, *overflow); __ bind(done); } @@ -790,8 +789,8 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rmem_f BLOCK_COMMENT("stack_overflow_check_with_compare {"); __ sub(Rmem_frame_size, R1_SP, Rmem_frame_size); __ ld(Rscratch1, thread_(stack_overflow_limit)); - __ cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1); - __ bgt(CCR0/*is_stack_overflow*/, done); + __ cmpld(CR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1); + __ bgt(CR0/*is_stack_overflow*/, done); // The stack overflows. Load target address of the runtime stub and call it. assert(SharedRuntime::throw_StackOverflowError_entry() != nullptr, "generated in wrong order"); @@ -800,13 +799,13 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rmem_f // Restore caller_sp (c2i adapter may exist, but no shrinking of interpreted caller frame). #ifdef ASSERT Label frame_not_shrunk; - __ cmpld(CCR0, R1_SP, R21_sender_SP); - __ ble(CCR0, frame_not_shrunk); + __ cmpld(CR0, R1_SP, R21_sender_SP); + __ ble(CR0, frame_not_shrunk); __ stop("frame shrunk"); __ bind(frame_not_shrunk); __ ld(Rscratch1, 0, R1_SP); __ ld(R0, 0, R21_sender_SP); - __ cmpd(CCR0, R0, Rscratch1); + __ cmpd(CR0, R0, Rscratch1); __ asm_assert_eq("backlink"); #endif // ASSERT __ mr(R1_SP, R21_sender_SP); @@ -823,15 +822,15 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc { if (!flags_preloaded) { - __ lwz(Rflags, method_(access_flags)); + __ lhz(Rflags, method_(access_flags)); } #ifdef ASSERT // Check if methods needs synchronization. { Label Lok; - __ testbitdi(CCR0, R0, Rflags, JVM_ACC_SYNCHRONIZED_BIT); - __ btrue(CCR0,Lok); + __ testbitdi(CR0, R0, Rflags, JVM_ACC_SYNCHRONIZED_BIT); + __ btrue(CR0,Lok); __ stop("method doesn't need synchronization"); __ bind(Lok); } @@ -843,8 +842,8 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc Label Lstatic; Label Ldone; - __ testbitdi(CCR0, R0, Rflags, JVM_ACC_STATIC_BIT); - __ btrue(CCR0, Lstatic); + __ testbitdi(CR0, R0, Rflags, JVM_ACC_STATIC_BIT); + __ btrue(CR0, Lstatic); // Non-static case: load receiver obj from stack and we're done. __ ld(Robj_to_lock, R18_locals); @@ -951,8 +950,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist // environment and one for a possible native mirror. Label skip_native_calculate_max_stack; __ addi(Rtop_frame_size, Rsize_of_parameters, 2); - __ cmpwi(CCR0, Rtop_frame_size, Argument::n_int_register_parameters_c); - __ bge(CCR0, skip_native_calculate_max_stack); + __ cmpwi(CR0, Rtop_frame_size, Argument::n_int_register_parameters_c); + __ bge(CR0, skip_native_calculate_max_stack); __ li(Rtop_frame_size, Argument::n_int_register_parameters_c); __ bind(skip_native_calculate_max_stack); __ sldi(Rsize_of_parameters, Rsize_of_parameters, Interpreter::logStackElementSize); @@ -1000,8 +999,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist if (ProfileInterpreter) { Label zero_continue; __ ld(R28_mdx, method_(method_data)); - __ cmpdi(CCR0, R28_mdx, 0); - __ beq(CCR0, zero_continue); + __ cmpdi(CR0, R28_mdx, 0); + __ beq(CR0, zero_continue); __ addi(R28_mdx, R28_mdx, in_bytes(MethodData::data_offset())); __ bind(zero_continue); } @@ -1301,8 +1300,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { assert(__ nonvolatile_accross_vthread_preemtion(access_flags), "access_flags not preserved"); // Type check. - assert(4 == sizeof(AccessFlags), "unexpected field size"); - __ lwz(access_flags, method_(access_flags)); + assert(2 == sizeof(AccessFlags), "unexpected field size"); + __ lhz(access_flags, method_(access_flags)); // We don't want to reload R19_method and access_flags after calls // to some helper functions. @@ -1331,8 +1330,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ ld(signature_handler_fd, method_(signature_handler)); Label call_signature_handler; - __ cmpdi(CCR0, signature_handler_fd, 0); - __ bne(CCR0, call_signature_handler); + __ cmpdi(CR0, signature_handler_fd, 0); + __ bne(CR0, call_signature_handler); // Method has never been called. Either generate a specialized // handler or point to the slow one. @@ -1343,8 +1342,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Check for an exception while looking up the target method. If we // incurred one, bail. __ ld(pending_exception, thread_(pending_exception)); - __ cmpdi(CCR0, pending_exception, 0); - __ bne(CCR0, exception_return_sync_check); // Has pending exception. + __ cmpdi(CR0, pending_exception, 0); + __ bne(CR0, exception_return_sync_check); // Has pending exception. // Reload signature handler, it may have been created/assigned in the meanwhile. __ ld(signature_handler_fd, method_(signature_handler)); @@ -1399,8 +1398,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Access_flags is non-volatile and still, no need to restore it. // Restore access flags. - __ testbitdi(CCR0, R0, access_flags, JVM_ACC_STATIC_BIT); - __ bfalse(CCR0, method_is_not_static); + __ testbitdi(CR0, R0, access_flags, JVM_ACC_STATIC_BIT); + __ bfalse(CR0, method_is_not_static); // Load mirror from interpreter frame (FP in R11_scratch1) __ ld(R21_tmp1, _ijava_state_neg(mirror), R11_scratch1); @@ -1509,8 +1508,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Not suspended. // TODO PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); - __ cmpwi(CCR1, suspend_flags, 0); - __ beq(CCR1, sync_check_done); + __ cmpwi(CR1, suspend_flags, 0); + __ beq(CR1, sync_check_done); __ bind(do_safepoint); __ isync(); @@ -1553,8 +1552,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Check preemption for Object.wait() Label not_preempted; __ ld(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); - __ cmpdi(CCR0, R0, 0); - __ beq(CCR0, not_preempted); + __ cmpdi(CR0, R0, 0); + __ beq(CR0, not_preempted); __ mtlr(R0); __ li(R0, 0); __ std(R0, in_bytes(JavaThread::preempt_alternate_return_offset()), R16_thread); @@ -1612,8 +1611,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { Label exception_return_sync_check_already_unlocked; __ ld(R0/*pending_exception*/, thread_(pending_exception)); - __ cmpdi(CCR0, R0/*pending_exception*/, 0); - __ bne(CCR0, exception_return_sync_check_already_unlocked); + __ cmpdi(CR0, R0/*pending_exception*/, 0); + __ bne(CR0, exception_return_sync_check_already_unlocked); //----------------------------------------------------------------------------- // No exception pending. @@ -1707,7 +1706,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals); __ subf(Rslot_addr, Rsize_of_parameters, R18_locals); __ srdi_(Rnum, Rnum, Interpreter::logStackElementSize); - __ beq(CCR0, Lno_locals); + __ beq(CR0, Lno_locals); __ li(R0, 0); __ mtctr(Rnum); @@ -1769,7 +1768,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT else { Label Lok; - __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method); + __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method); __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED); __ asm_assert_eq("method needs synchronization"); __ bind(Lok); @@ -2081,8 +2080,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ ld(return_pc, 0, R1_SP); __ ld(return_pc, _abi0(lr), return_pc); __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), return_pc); - __ cmpdi(CCR0, R3_RET, 0); - __ bne(CCR0, Lcaller_not_deoptimized); + __ cmpdi(CR0, R3_RET, 0); + __ bne(CR0, Lcaller_not_deoptimized); // The deoptimized case. // In this case, we can't call dispatch_next() after the frame is @@ -2128,16 +2127,16 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Label L_done; __ lbz(R11_scratch1, 0, R14_bcp); - __ cmpwi(CCR0, R11_scratch1, Bytecodes::_invokestatic); - __ bne(CCR0, L_done); + __ cmpwi(CR0, R11_scratch1, Bytecodes::_invokestatic); + __ bne(CR0, L_done); // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. // Detect such a case in the InterpreterRuntime function and return the member name argument, or null. __ ld(R4_ARG2, 0, R18_locals); __ call_VM(R4_ARG2, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), R4_ARG2, R19_method, R14_bcp); - __ cmpdi(CCR0, R4_ARG2, 0); - __ beq(CCR0, L_done); + __ cmpdi(CR0, R4_ARG2, 0); + __ beq(CR0, L_done); __ std(R4_ARG2, wordSize, R15_esp); __ bind(L_done); #endif // INCLUDE_JVMTI @@ -2322,8 +2321,8 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) { int offs2 = __ load_const_optimized(R12_scratch2, (address) &BytecodeCounter::_counter_value, R0, true); __ ld(R11_scratch1, offs1, R11_scratch1); __ lwa(R12_scratch2, offs2, R12_scratch2); - __ cmpd(CCR0, R12_scratch2, R11_scratch1); - __ blt(CCR0, Lskip_vm_call); + __ cmpd(CR0, R12_scratch2, R11_scratch1); + __ blt(CR0, Lskip_vm_call); } __ push(state); @@ -2397,8 +2396,8 @@ void TemplateInterpreterGenerator::stop_interpreter_at() { int offs2 = __ load_const_optimized(R12_scratch2, (address) &BytecodeCounter::_counter_value, R0, true); __ ld(R11_scratch1, offs1, R11_scratch1); __ lwa(R12_scratch2, offs2, R12_scratch2); - __ cmpd(CCR0, R12_scratch2, R11_scratch1); - __ bne(CCR0, L); + __ cmpd(CR0, R12_scratch2, R11_scratch1); + __ bne(CR0, L); __ illtrap(); __ bind(L); } diff --git a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp index 43e78dd9d1514..934bb1bd52918 100644 --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, 2024 SAP SE. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "cds/cdsConfig.hpp" #include "compiler/disassembler.hpp" @@ -124,9 +123,9 @@ void TemplateTable::patch_bytecode(Bytecodes::Code new_bc, Register Rnew_bc, Reg int code_offset = (byte_no == f1_byte) ? in_bytes(ResolvedFieldEntry::get_code_offset()) : in_bytes(ResolvedFieldEntry::put_code_offset()); __ lbz(Rnew_bc, code_offset, Rtemp); - __ cmpwi(CCR0, Rnew_bc, 0); + __ cmpwi(CR0, Rnew_bc, 0); __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc); - __ beq(CCR0, L_patch_done); + __ beq(CR0, L_patch_done); // __ isync(); // acquire not needed break; } @@ -141,8 +140,8 @@ void TemplateTable::patch_bytecode(Bytecodes::Code new_bc, Register Rnew_bc, Reg if (JvmtiExport::can_post_breakpoint()) { Label L_fast_patch; __ lbz(Rtemp, 0, R14_bcp); - __ cmpwi(CCR0, Rtemp, (unsigned int)(unsigned char)Bytecodes::_breakpoint); - __ bne(CCR0, L_fast_patch); + __ cmpwi(CR0, Rtemp, (unsigned int)(unsigned char)Bytecodes::_breakpoint); + __ bne(CR0, L_fast_patch); // Perform the quickening, slowly, in the bowels of the breakpoint table. __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), R19_method, R14_bcp, Rnew_bc); __ b(L_patch_done); @@ -262,14 +261,14 @@ void TemplateTable::ldc(LdcType type) { __ addi(Rscratch2, Rscratch2, tags_offset); __ lbzx(Rscratch2, Rscratch2, Rscratch1); - __ cmpwi(CCR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class? - __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state? - __ cror(CCR0, Assembler::equal, CCR1, Assembler::equal); + __ cmpwi(CR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class? + __ cmpwi(CR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state? + __ cror(CR0, Assembler::equal, CR1, Assembler::equal); // Resolved class - need to call vm to get java mirror of the class. - __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_Class); - __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); // Neither resolved class nor unresolved case from above? - __ beq(CCR0, notClass); + __ cmpwi(CR1, Rscratch2, JVM_CONSTANT_Class); + __ crnor(CR0, Assembler::equal, CR1, Assembler::equal); // Neither resolved class nor unresolved case from above? + __ beq(CR0, notClass); __ li(R4, is_ldc_wide(type) ? 1 : 0); call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), R4); @@ -280,16 +279,16 @@ void TemplateTable::ldc(LdcType type) { __ bind(notClass); __ addi(Rcpool, Rcpool, base_offset); __ sldi(Rscratch1, Rscratch1, LogBytesPerWord); - __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Integer); - __ bne(CCR0, notInt); + __ cmpdi(CR0, Rscratch2, JVM_CONSTANT_Integer); + __ bne(CR0, notInt); __ lwax(R17_tos, Rcpool, Rscratch1); __ push(itos); __ b(exit); __ align(32, 12); __ bind(notInt); - __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float); - __ bne(CCR0, notFloat); + __ cmpdi(CR0, Rscratch2, JVM_CONSTANT_Float); + __ bne(CR0, notFloat); __ lfsx(F15_ftos, Rcpool, Rscratch1); __ push(ftos); __ b(exit); @@ -319,12 +318,12 @@ void TemplateTable::fast_aldc(LdcType type) { int simm16_rest = __ load_const_optimized(R11_scratch1, Universe::the_null_sentinel_addr(), R0, true); __ ld(R31, simm16_rest, R11_scratch1); __ resolve_oop_handle(R31, R11_scratch1, R12_scratch2, MacroAssembler::PRESERVATION_NONE); - __ cmpld(CCR0, R17_tos, R31); + __ cmpld(CR0, R17_tos, R31); if (VM_Version::has_isel()) { - __ isel_0(R17_tos, CCR0, Assembler::equal); + __ isel_0(R17_tos, CR0, Assembler::equal); } else { Label not_sentinel; - __ bne(CCR0, not_sentinel); + __ bne(CR0, not_sentinel); __ li(R17_tos, 0); __ bind(not_sentinel); } @@ -360,15 +359,15 @@ void TemplateTable::ldc2_w() { __ lbzx(Rtag, Rtag, Rindex); __ sldi(Rindex, Rindex, LogBytesPerWord); - __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Double); - __ bne(CCR0, not_double); + __ cmpdi(CR0, Rtag, JVM_CONSTANT_Double); + __ bne(CR0, not_double); __ lfdx(F15_ftos, Rcpool, Rindex); __ push(dtos); __ b(exit); __ bind(not_double); - __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Long); - __ bne(CCR0, not_long); + __ cmpdi(CR0, Rtag, JVM_CONSTANT_Long); + __ bne(CR0, not_long); __ ldx(R17_tos, Rcpool, Rindex); __ push(ltos); __ b(exit); @@ -402,32 +401,32 @@ void TemplateTable::condy_helper(Label& Done) { { // tos in (itos, ftos, stos, btos, ctos, ztos) Label notInt, notFloat, notShort, notByte, notChar, notBool; - __ cmplwi(CCR0, flags, itos); - __ bne(CCR0, notInt); + __ cmplwi(CR0, flags, itos); + __ bne(CR0, notInt); // itos __ lwax(R17_tos, obj, off); __ push(itos); __ b(Done); __ bind(notInt); - __ cmplwi(CCR0, flags, ftos); - __ bne(CCR0, notFloat); + __ cmplwi(CR0, flags, ftos); + __ bne(CR0, notFloat); // ftos __ lfsx(F15_ftos, obj, off); __ push(ftos); __ b(Done); __ bind(notFloat); - __ cmplwi(CCR0, flags, stos); - __ bne(CCR0, notShort); + __ cmplwi(CR0, flags, stos); + __ bne(CR0, notShort); // stos __ lhax(R17_tos, obj, off); __ push(stos); __ b(Done); __ bind(notShort); - __ cmplwi(CCR0, flags, btos); - __ bne(CCR0, notByte); + __ cmplwi(CR0, flags, btos); + __ bne(CR0, notByte); // btos __ lbzx(R17_tos, obj, off); __ extsb(R17_tos, R17_tos); @@ -435,16 +434,16 @@ void TemplateTable::condy_helper(Label& Done) { __ b(Done); __ bind(notByte); - __ cmplwi(CCR0, flags, ctos); - __ bne(CCR0, notChar); + __ cmplwi(CR0, flags, ctos); + __ bne(CR0, notChar); // ctos __ lhzx(R17_tos, obj, off); __ push(ctos); __ b(Done); __ bind(notChar); - __ cmplwi(CCR0, flags, ztos); - __ bne(CCR0, notBool); + __ cmplwi(CR0, flags, ztos); + __ bne(CR0, notBool); // ztos __ lbzx(R17_tos, obj, off); __ push(ztos); @@ -457,16 +456,16 @@ void TemplateTable::condy_helper(Label& Done) { case Bytecodes::_ldc2_w: { Label notLong, notDouble; - __ cmplwi(CCR0, flags, ltos); - __ bne(CCR0, notLong); + __ cmplwi(CR0, flags, ltos); + __ bne(CR0, notLong); // ltos __ ldx(R17_tos, obj, off); __ push(ltos); __ b(Done); __ bind(notLong); - __ cmplwi(CCR0, flags, dtos); - __ bne(CCR0, notDouble); + __ cmplwi(CR0, flags, dtos); + __ bne(CR0, notDouble); // dtos __ lfdx(F15_ftos, obj, off); __ push(dtos); @@ -518,16 +517,16 @@ void TemplateTable::iload_internal(RewriteControl rc) { // last two iloads in a pair. Comparing against fast_iload means that // the next bytecode is neither an iload or a caload, and therefore // an iload pair. - __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_iload); - __ beq(CCR0, Ldone); + __ cmpwi(CR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_iload); + __ beq(CR0, Ldone); - __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_iload); + __ cmpwi(CR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_iload); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iload2); - __ beq(CCR1, Lrewrite); + __ beq(CR1, Lrewrite); - __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_caload); + __ cmpwi(CR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_caload); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_icaload); - __ beq(CCR0, Lrewrite); + __ beq(CR0, Lrewrite); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iload); @@ -813,20 +812,20 @@ void TemplateTable::aload_0_internal(RewriteControl rc) { __ lbz(Rnext_byte, Bytecodes::length_for(Bytecodes::_aload_0), R14_bcp); // If _getfield, wait to rewrite. We only want to rewrite the last two bytecodes in a pair. - __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_getfield); - __ beq(CCR0, Ldont_rewrite); + __ cmpwi(CR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_getfield); + __ beq(CR0, Ldont_rewrite); - __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_igetfield); + __ cmpwi(CR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_igetfield); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iaccess_0); - __ beq(CCR1, Lrewrite); + __ beq(CR1, Lrewrite); - __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_agetfield); + __ cmpwi(CR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_agetfield); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_aaccess_0); - __ beq(CCR0, Lrewrite); + __ beq(CR0, Lrewrite); - __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_fgetfield); + __ cmpwi(CR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_fgetfield); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_faccess_0); - __ beq(CCR1, Lrewrite); + __ beq(CR1, Lrewrite); __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_aload_0); @@ -998,8 +997,8 @@ void TemplateTable::aastore() { Register Rscratch3 = Rindex; // Do array store check - check for null value first. - __ cmpdi(CCR0, R17_tos, 0); - __ beq(CCR0, Lis_null); + __ cmpdi(CR0, R17_tos, 0); + __ beq(CR0, Lis_null); __ load_klass(Rarray_klass, Rarray); __ load_klass(Rvalue_klass, R17_tos); @@ -1046,9 +1045,9 @@ void TemplateTable::bastore() { __ load_klass(Rscratch, Rarray); __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch); int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit()); - __ testbitdi(CCR0, R0, Rscratch, diffbit); + __ testbitdi(CR0, R0, Rscratch, diffbit); Label L_skip; - __ bfalse(CCR0, L_skip); + __ bfalse(CR0, L_skip); __ andi(R17_tos, R17_tos, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 __ bind(L_skip); @@ -1263,11 +1262,11 @@ void TemplateTable::idiv() { Register Rdividend = R11_scratch1; // Used by irem. __ addi(R0, R17_tos, 1); - __ cmplwi(CCR0, R0, 2); - __ bgt(CCR0, Lnormal); // divisor <-1 or >1 + __ cmplwi(CR0, R0, 2); + __ bgt(CR0, Lnormal); // divisor <-1 or >1 - __ cmpwi(CCR1, R17_tos, 0); - __ beq(CCR1, Lexception); // divisor == 0 + __ cmpwi(CR1, R17_tos, 0); + __ beq(CR1, Lexception); // divisor == 0 __ pop_i(Rdividend); __ mullw(R17_tos, Rdividend, R17_tos); // div by +/-1 @@ -1308,11 +1307,11 @@ void TemplateTable::ldiv() { Register Rdividend = R11_scratch1; // Used by lrem. __ addi(R0, R17_tos, 1); - __ cmpldi(CCR0, R0, 2); - __ bgt(CCR0, Lnormal); // divisor <-1 or >1 + __ cmpldi(CR0, R0, 2); + __ bgt(CR0, Lnormal); // divisor <-1 or >1 - __ cmpdi(CCR1, R17_tos, 0); - __ beq(CCR1, Lexception); // divisor == 0 + __ cmpdi(CR1, R17_tos, 0); + __ beq(CR1, Lexception); // divisor == 0 __ pop_l(Rdividend); __ mulld(R17_tos, Rdividend, R17_tos); // div by +/-1 @@ -1566,18 +1565,18 @@ void TemplateTable::convert() { case Bytecodes::_d2i: case Bytecodes::_f2i: - __ fcmpu(CCR0, F15_ftos, F15_ftos); + __ fcmpu(CR0, F15_ftos, F15_ftos); __ li(R17_tos, 0); // 0 in case of NAN - __ bso(CCR0, done); + __ bso(CR0, done); __ fctiwz(F15_ftos, F15_ftos); __ move_d_to_l(); break; case Bytecodes::_d2l: case Bytecodes::_f2l: - __ fcmpu(CCR0, F15_ftos, F15_ftos); + __ fcmpu(CR0, F15_ftos, F15_ftos); __ li(R17_tos, 0); // 0 in case of NAN - __ bso(CCR0, done); + __ bso(CR0, done); __ fctidz(F15_ftos, F15_ftos); __ move_d_to_l(); break; @@ -1594,7 +1593,7 @@ void TemplateTable::lcmp() { const Register Rscratch = R11_scratch1; __ pop_l(Rscratch); // first operand, deeper in stack - __ cmpd(CCR0, Rscratch, R17_tos); // compare + __ cmpd(CR0, Rscratch, R17_tos); // compare __ set_cmp3(R17_tos); // set result as follows: <: -1, =: 0, >: 1 } @@ -1612,7 +1611,7 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) { __ pop_d(Rfirst); } - __ fcmpu(CCR0, Rfirst, Rsecond); // compare + __ fcmpu(CR0, Rfirst, Rsecond); // compare // if unordered_result is 1, treat unordered_result like 'greater than' assert(unordered_result == 1 || unordered_result == -1, "unordered_result can be either 1 or -1"); __ set_cmpu3(R17_tos, unordered_result != 1); @@ -1684,8 +1683,8 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { Label Lforward; // Check branch direction. - __ cmpdi(CCR0, Rdisp, 0); - __ bgt(CCR0, Lforward); + __ cmpdi(CR0, Rdisp, 0); + __ bgt(CR0, Lforward); __ get_method_counters(R19_method, R4_counters, Lforward); @@ -1696,8 +1695,8 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // If no method data exists, go to profile_continue. __ ld(Rmdo, in_bytes(Method::method_data_offset()), R19_method); - __ cmpdi(CCR0, Rmdo, 0); - __ beq(CCR0, Lno_mdo); + __ cmpdi(CR0, Rmdo, 0); + __ beq(CR0, Lno_mdo); // Increment backedge counter in the MDO. const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset()); @@ -1707,7 +1706,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ stw(Rscratch2, mdo_bc_offs, Rmdo); if (UseOnStackReplacement) { __ and_(Rscratch3, Rscratch2, Rscratch3); - __ bne(CCR0, Lforward); + __ bne(CR0, Lforward); __ b(Loverflow); } else { __ b(Lforward); @@ -1723,7 +1722,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ stw(Rscratch2, mo_bc_offs, R4_counters); if (UseOnStackReplacement) { __ and_(Rscratch3, Rscratch2, Rscratch3); - __ bne(CCR0, Lforward); + __ bne(CR0, Lforward); } else { __ b(Lforward); } @@ -1734,13 +1733,13 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), R4_ARG2, true); // Was an OSR adapter generated? - __ cmpdi(CCR0, R3_RET, 0); - __ beq(CCR0, Lforward); + __ cmpdi(CR0, R3_RET, 0); + __ beq(CR0, Lforward); // Has the nmethod been invalidated already? __ lbz(R0, in_bytes(nmethod::state_offset()), R3_RET); - __ cmpwi(CCR0, R0, nmethod::in_use); - __ bne(CCR0, Lforward); + __ cmpwi(CR0, R0, nmethod::in_use); + __ bne(CR0, Lforward); // Migrate the interpreter frame off of the stack. // We can use all registers because we will not return to interpreter from this point. @@ -1776,18 +1775,18 @@ void TemplateTable::if_cmp_common(Register Rfirst, Register Rsecond, Register Rs if (is_jint) { if (cmp0) { - __ cmpwi(CCR0, Rfirst, 0); + __ cmpwi(CR0, Rfirst, 0); } else { - __ cmpw(CCR0, Rfirst, Rsecond); + __ cmpw(CR0, Rfirst, Rsecond); } } else { if (cmp0) { - __ cmpdi(CCR0, Rfirst, 0); + __ cmpdi(CR0, Rfirst, 0); } else { - __ cmpd(CCR0, Rfirst, Rsecond); + __ cmpd(CR0, Rfirst, Rsecond); } } - branch_conditional(CCR0, cc, Lnot_taken, /*invert*/ true); + branch_conditional(CR0, cc, Lnot_taken, /*invert*/ true); // Conition is false => Jump! branch(false, false); @@ -1886,10 +1885,10 @@ void TemplateTable::tableswitch() { __ get_u4(Rhigh_byte, Rdef_offset_addr, 2 *BytesPerInt, InterpreterMacroAssembler::Unsigned); // Check for default case (=index outside [low,high]). - __ cmpw(CCR0, R17_tos, Rlow_byte); - __ cmpw(CCR1, R17_tos, Rhigh_byte); - __ blt(CCR0, Ldefault_case); - __ bgt(CCR1, Ldefault_case); + __ cmpw(CR0, R17_tos, Rlow_byte); + __ cmpw(CR1, R17_tos, Rhigh_byte); + __ blt(CR0, Ldefault_case); + __ bgt(CR1, Ldefault_case); // Lookup dispatch offset. __ sub(Rindex, R17_tos, Rlow_byte); @@ -1945,8 +1944,8 @@ void TemplateTable::fast_linearswitch() { __ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair. __ mtctr(Rcount); - __ cmpwi(CCR0, Rcount, 0); - __ bne(CCR0, Lloop_entry); + __ cmpwi(CR0, Rcount, 0); + __ bne(CR0, Lloop_entry); // Default case __ bind(Ldefault_case); @@ -1962,8 +1961,8 @@ void TemplateTable::fast_linearswitch() { __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt); __ bind(Lloop_entry); __ get_u4(Rvalue, Rcurrent_pair, 0, InterpreterMacroAssembler::Unsigned); - __ cmpw(CCR0, Rvalue, Rcmp_value); - __ bne(CCR0, Lsearch_loop); + __ cmpw(CR0, Rvalue, Rcmp_value); + __ bne(CR0, Lsearch_loop); // Found, load offset. __ get_u4(Roffset, Rcurrent_pair, BytesPerInt, InterpreterMacroAssembler::Signed); @@ -2058,8 +2057,8 @@ void TemplateTable::fast_binaryswitch() { // else // Rh = Ri Label Lgreater; - __ cmpw(CCR0, Rkey, Rscratch); - __ bge(CCR0, Lgreater); + __ cmpw(CR0, Rkey, Rscratch); + __ bge(CR0, Lgreater); __ mr(Rj, Rh); __ b(entry); __ bind(Lgreater); @@ -2068,10 +2067,10 @@ void TemplateTable::fast_binaryswitch() { // while (i+1 < j) __ bind(entry); __ addi(Rscratch, Ri, 1); - __ cmpw(CCR0, Rscratch, Rj); + __ cmpw(CR0, Rscratch, Rj); __ add(Rh, Ri, Rj); // start h = i + j >> 1; - __ blt(CCR0, loop); + __ blt(CR0, loop); } // End of binary search, result index is i (must check again!). @@ -2087,8 +2086,8 @@ void TemplateTable::fast_binaryswitch() { Label not_found; // Ri = offset offset - __ cmpw(CCR0, Rkey, Rscratch); - __ beq(CCR0, not_found); + __ cmpw(CR0, Rkey, Rscratch); + __ beq(CR0, not_found); // entry not found -> j = default offset __ get_u4(Rj, Rarray, -2 * BytesPerInt, InterpreterMacroAssembler::Unsigned); __ b(default_case); @@ -2131,8 +2130,8 @@ void TemplateTable::_return(TosState state) { // Load klass of this obj. __ load_klass(Rklass, R17_tos); __ lbz(Rklass_flags, in_bytes(Klass::misc_flags_offset()), Rklass); - __ testbitdi(CCR0, R0, Rklass_flags, exact_log2(KlassFlags::_misc_has_finalizer)); - __ bfalse(CCR0, Lskip_register_finalizer); + __ testbitdi(CR0, R0, Rklass_flags, exact_log2(KlassFlags::_misc_has_finalizer)); + __ bfalse(CR0, Lskip_register_finalizer); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), R17_tos /* obj */); @@ -2144,7 +2143,7 @@ void TemplateTable::_return(TosState state) { Label no_safepoint; __ ld(R11_scratch1, in_bytes(JavaThread::polling_word_offset()), R16_thread); __ andi_(R11_scratch1, R11_scratch1, SafepointMechanism::poll_bit()); - __ beq(CCR0, no_safepoint); + __ beq(CR0, no_safepoint); __ push(state); __ push_cont_fastpath(); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)); @@ -2215,8 +2214,8 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no, Register Rca // Load-acquire the bytecode to match store-release in InterpreterRuntime __ lbz(Rscratch, bytecode_offset, Rcache); // Acquire by cmp-br-isync (see below). - __ cmpdi(CCR0, Rscratch, (int)code); - __ beq(CCR0, Lresolved); + __ cmpdi(CR0, Rscratch, (int)code); + __ beq(CR0, Lresolved); // Class initialization barrier slow path lands here as well. __ bind(L_clinit_barrier_slow); @@ -2264,8 +2263,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no, int code_offset = (byte_no == f1_byte) ? in_bytes(ResolvedFieldEntry::get_code_offset()) : in_bytes(ResolvedFieldEntry::put_code_offset()); __ lbz(R0, code_offset, Rcache); - __ cmpwi(CCR0, R0, (int)code); // have we resolved this bytecode? - __ beq(CCR0, resolved); + __ cmpwi(CR0, R0, (int)code); // have we resolved this bytecode? + __ beq(CR0, resolved); // resolve first time through address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache); @@ -2333,8 +2332,8 @@ void TemplateTable::load_resolved_method_entry_handle(Register cache, // maybe push appendix to arguments (just before return address) Label L_no_push; - __ testbitdi(CCR0, R0, flags, ResolvedMethodEntry::has_appendix_shift); - __ bfalse(CCR0, L_no_push); + __ testbitdi(CR0, R0, flags, ResolvedMethodEntry::has_appendix_shift); + __ bfalse(CR0, L_no_push); // invokehandle uses an index into the resolved references array __ lhz(ref_index, in_bytes(ResolvedMethodEntry::resolved_references_index_offset()), cache); // Push the appendix as a trailing parameter. @@ -2396,8 +2395,8 @@ void TemplateTable::load_invokedynamic_entry(Register method) { __ ld_ptr(method, in_bytes(ResolvedIndyEntry::method_offset()), cache); // The invokedynamic is unresolved iff method is null - __ cmpdi(CCR0, method, 0); - __ bne(CCR0, resolved); + __ cmpdi(CR0, method, 0); + __ bne(CR0, resolved); Bytecodes::Code code = bytecode(); @@ -2409,7 +2408,7 @@ void TemplateTable::load_invokedynamic_entry(Register method) { __ load_resolved_indy_entry(cache, index); __ ld_ptr(method, in_bytes(ResolvedIndyEntry::method_offset()), cache); - DEBUG_ONLY(__ cmpdi(CCR0, method, 0)); + DEBUG_ONLY(__ cmpdi(CR0, method, 0)); __ asm_assert_ne("Should be resolved by now"); __ bind(resolved); __ isync(); // Order load wrt. succeeding loads. @@ -2418,7 +2417,7 @@ void TemplateTable::load_invokedynamic_entry(Register method) { // Check if there is an appendix __ lbz(index, in_bytes(ResolvedIndyEntry::flags_offset()), cache); __ rldicl_(R0, index, 64-ResolvedIndyEntry::has_appendix_shift, 63); - __ beq(CCR0, L_no_push); + __ beq(CR0, L_no_push); // Get appendix __ lhz(index, in_bytes(ResolvedIndyEntry::resolved_references_index_offset()), cache); @@ -2490,8 +2489,8 @@ void TemplateTable::jvmti_post_field_access(Register Rcache, Register Rscratch, int offs = __ load_const_optimized(Rscratch, JvmtiExport::get_field_access_count_addr(), R0, true); __ lwz(Rscratch, offs, Rscratch); - __ cmpwi(CCR0, Rscratch, 0); - __ beq(CCR0, Lno_field_access_post); + __ cmpwi(CR0, Rscratch, 0); + __ beq(CR0, Lno_field_access_post); // Post access enabled - do it! if (is_static) { @@ -2575,13 +2574,13 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr #ifdef ASSERT Label LFlagInvalid; - __ cmpldi(CCR0, Rtos_state, number_of_states); - __ bge(CCR0, LFlagInvalid); + __ cmpldi(CR0, Rtos_state, number_of_states); + __ bge(CR0, LFlagInvalid); #endif // Load from branch table and dispatch (volatile case: one instruction ahead). __ sldi(Rtos_state, Rtos_state, LogBytesPerWord); - __ cmpwi(CCR2, Rscratch, 1); // Volatile? + __ cmpwi(CR2, Rscratch, 1); // Volatile? if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // Volatile ? size of 1 instruction : 0. } @@ -2632,12 +2631,12 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr } { Label acquire_double; - __ beq(CCR2, acquire_double); // Volatile? + __ beq(CR2, acquire_double); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ bind(acquire_double); - __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. - __ beq_predict_taken(CCR0, Lisync); + __ fcmpu(CR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. + __ beq_predict_taken(CR0, Lisync); __ b(Lisync); // In case of NAN. } @@ -2653,12 +2652,12 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr } { Label acquire_float; - __ beq(CCR2, acquire_float); // Volatile? + __ beq(CR2, acquire_float); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ bind(acquire_float); - __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. - __ beq_predict_taken(CCR0, Lisync); + __ fcmpu(CR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. + __ beq_predict_taken(CR0, Lisync); __ b(Lisync); // In case of NAN. } @@ -2672,7 +2671,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2685,7 +2684,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2699,7 +2698,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2713,7 +2712,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr // use btos rewriting, no truncating to t/f bit is needed for getfield. patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2726,7 +2725,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2739,7 +2738,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 28, 28); // Align load. @@ -2754,7 +2753,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch); } - __ beq(CCR2, Lacquire); // Volatile? + __ beq(CR2, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); __ align(32, 12); @@ -2797,8 +2796,8 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rscratch, boo int offs = __ load_const_optimized(Rscratch, JvmtiExport::get_field_modification_count_addr(), R0, true); __ lwz(Rscratch, offs, Rscratch); - __ cmpwi(CCR0, Rscratch, 0); - __ beq(CCR0, Lno_field_mod_post); + __ cmpwi(CR0, Rscratch, 0); + __ beq(CR0, Lno_field_mod_post); // Do the post const Register Robj = Rscratch; @@ -2831,11 +2830,11 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rscratch, boo // the type to determine where the object is. __ lbz(Rtos_state, in_bytes(ResolvedFieldEntry::type_offset()), Rcache); - __ cmpwi(CCR0, Rtos_state, ltos); - __ cmpwi(CCR1, Rtos_state, dtos); + __ cmpwi(CR0, Rtos_state, ltos); + __ cmpwi(CR1, Rtos_state, dtos); __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(1)); - __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); - __ beq(CCR0, is_one_slot); + __ crnor(CR0, Assembler::equal, CR1, Assembler::equal); + __ beq(CR0, is_one_slot); __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(2)); __ bind(is_one_slot); break; @@ -2882,7 +2881,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr Rscratch2 = R12_scratch2, // used by load_field_cp_cache_entry Rscratch3 = R6_ARG4, Rbc = Rscratch3; - const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store). + const ConditionRegister CR_is_vol = CR2; // Non-volatile condition register (survives runtime call in do_oop_store). static address field_rw_branch_table[number_of_states], field_norw_branch_table[number_of_states], @@ -2908,8 +2907,8 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr #ifdef ASSERT Label LFlagInvalid; - __ cmpldi(CCR0, Rtos_state, number_of_states); - __ bge(CCR0, LFlagInvalid); + __ cmpldi(CR0, Rtos_state, number_of_states); + __ bge(CR0, LFlagInvalid); #endif // Load from branch table and dispatch (volatile case: one instruction ahead). @@ -3125,7 +3124,7 @@ void TemplateTable::fast_storefield(TosState state) { Rscratch = R11_scratch1, // used by load_field_cp_cache_entry Rscratch2 = R12_scratch2, // used by load_field_cp_cache_entry Rscratch3 = R4_ARG2; - const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store). + const ConditionRegister CR_is_vol = CR2; // Non-volatile condition register (survives runtime call in do_oop_store). // Constant pool already resolved => Load flags and offset of field. __ load_field_entry(Rcache, Rscratch); @@ -3140,7 +3139,7 @@ void TemplateTable::fast_storefield(TosState state) { if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ cmpdi(CR_is_vol, Rscratch, 1); } { Label LnotVolatile; - __ beq(CCR0, LnotVolatile); + __ beq(CR0, LnotVolatile); __ release(); __ align(32, 12); __ bind(LnotVolatile); @@ -3220,7 +3219,7 @@ void TemplateTable::fast_accessfield(TosState state) { // Get volatile flag. __ rldicl_(Rscratch, Rflags, 64-ResolvedFieldEntry::is_volatile_shift, 63); // Extract volatile bit. - __ bne(CCR0, LisVolatile); + __ bne(CR0, LisVolatile); switch(bytecode()) { case Bytecodes::_fast_agetfield: @@ -3308,8 +3307,8 @@ void TemplateTable::fast_accessfield(TosState state) { Label Ldummy; if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); } __ lfsx(F15_ftos, Rclass_or_obj, Roffset); - __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. - __ bne_predict_not_taken(CCR0, Ldummy); + __ fcmpu(CR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. + __ bne_predict_not_taken(CR0, Ldummy); __ bind(Ldummy); __ isync(); break; @@ -3323,8 +3322,8 @@ void TemplateTable::fast_accessfield(TosState state) { Label Ldummy; if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); } __ lfdx(F15_ftos, Rclass_or_obj, Roffset); - __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. - __ bne_predict_not_taken(CCR0, Ldummy); + __ fcmpu(CR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. + __ bne_predict_not_taken(CR0, Ldummy); __ bind(Ldummy); __ isync(); break; @@ -3361,7 +3360,7 @@ void TemplateTable::fast_xaccess(TosState state) { // Get volatile flag. __ rldicl_(Rscratch, Rflags, 64-ResolvedFieldEntry::is_volatile_shift, 63); // Extract volatile bit. - __ bne(CCR0, LisVolatile); + __ bne(CR0, LisVolatile); switch(state) { case atos: @@ -3399,8 +3398,8 @@ void TemplateTable::fast_xaccess(TosState state) { Label Ldummy; if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); } __ lfsx(F15_ftos, Rclass_or_obj, Roffset); - __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. - __ bne_predict_not_taken(CCR0, Ldummy); + __ fcmpu(CR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync. + __ bne_predict_not_taken(CR0, Ldummy); __ bind(Ldummy); __ isync(); break; @@ -3481,8 +3480,8 @@ void TemplateTable::invokevirtual(int byte_no) { load_resolved_method_entry_virtual(Rcache, noreg, Rflags); // Handle final method separately. - __ testbitdi(CCR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); - __ bfalse(CCR0, LnotFinal); + __ testbitdi(CR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); + __ bfalse(CR0, LnotFinal); if (RewriteBytecodes && !CDSConfig::is_using_archive() && !CDSConfig::is_dumping_static_archive()) { patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2); @@ -3588,8 +3587,8 @@ void TemplateTable::invokeinterface_object_method(Register Rrecv_klass, Label LnotFinal; // Check for vfinal. - __ testbitdi(CCR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); - __ bfalse(CCR0, LnotFinal); + __ testbitdi(CR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); + __ bfalse(CR0, LnotFinal); Register Rscratch = Rflags, // Rflags is dead now. Rmethod = Rtemp2, @@ -3642,8 +3641,8 @@ void TemplateTable::invokeinterface(int byte_no) { // to handle this corner case. Label LnotObjectMethod, Lthrow_ame; - __ testbitdi(CCR0, R0, Rflags, ResolvedMethodEntry::is_forced_virtual_shift); - __ bfalse(CCR0, LnotObjectMethod); + __ testbitdi(CR0, R0, Rflags, ResolvedMethodEntry::is_forced_virtual_shift); + __ bfalse(CR0, LnotObjectMethod); invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rcache, Rscratch1, Rscratch2); __ bind(LnotObjectMethod); @@ -3653,8 +3652,8 @@ void TemplateTable::invokeinterface(int byte_no) { // Check for private method invocation - indicated by vfinal Label LnotVFinal, L_no_such_interface, L_subtype; - __ testbitdi(CCR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); - __ bfalse(CCR0, LnotVFinal); + __ testbitdi(CR0, R0, Rflags, ResolvedMethodEntry::is_vfinal_shift); + __ bfalse(CR0, LnotVFinal); __ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch1, Rscratch2, L_subtype); // If we get here the typecheck failed @@ -3688,8 +3687,8 @@ void TemplateTable::invokeinterface(int byte_no) { __ lookup_interface_method(Rrecv_klass, Rinterface_klass, Rindex, Rmethod2, Rscratch1, Rscratch2, L_no_such_interface); - __ cmpdi(CCR0, Rmethod2, 0); - __ beq(CCR0, Lthrow_ame); + __ cmpdi(CR0, Rmethod2, 0); + __ beq(CR0, Lthrow_ame); // Found entry. Jump off! // Argument and return type profiling. __ profile_arguments_type(Rmethod2, Rscratch1, Rscratch2, true); @@ -3796,8 +3795,8 @@ void TemplateTable::_new() { __ addi(Rtags, Rtags, Array::base_offset_in_bytes()); __ lbzx(Rtags, Rindex, Rtags); - __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class); - __ bne(CCR0, Lslow_case); + __ cmpdi(CR0, Rtags, JVM_CONSTANT_Class); + __ bne(CR0, Lslow_case); // Get instanceKlass __ sldi(Roffset, Rindex, LogBytesPerWord); @@ -3811,7 +3810,7 @@ void TemplateTable::_new() { // Make sure klass is not abstract, or interface or java/lang/Class. __ andi_(R0, Rinstance_size, Klass::_lh_instance_slow_path_bit); // slow path bit equals 0? - __ bne(CCR0, Lslow_case); + __ bne(CR0, Lslow_case); // -------------------------------------------------------------------------- // Fast case: @@ -3830,8 +3829,8 @@ void TemplateTable::_new() { __ add(RnewTopValue, Rinstance_size, RoldTopValue); // If there is enough space, we do not CAS and do not clear. - __ cmpld(CCR0, RnewTopValue, RendValue); - __ bgt(CCR0, Lslow_case); + __ cmpld(CR0, RnewTopValue, RendValue); + __ bgt(CR0, Lslow_case); __ std(RnewTopValue, in_bytes(JavaThread::tlab_top_offset()), R16_thread); @@ -3948,8 +3947,8 @@ void TemplateTable::checkcast() { Rtags = R12_scratch2; // Null does not pass. - __ cmpdi(CCR0, R17_tos, 0); - __ beq(CCR0, Lis_null); + __ cmpdi(CR0, R17_tos, 0); + __ beq(CR0, Lis_null); // Get constant pool tag to find out if the bytecode has already been "quickened". __ get_cpool_and_tags(Rcpool, Rtags); @@ -3959,8 +3958,8 @@ void TemplateTable::checkcast() { __ addi(Rtags, Rtags, Array::base_offset_in_bytes()); __ lbzx(Rtags, Rtags, Roffset); - __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class); - __ beq(CCR0, Lquicked); + __ cmpdi(CR0, Rtags, JVM_CONSTANT_Class); + __ beq(CR0, Lquicked); // Call into the VM to "quicken" instanceof. __ push_ptr(); // for GC @@ -4010,8 +4009,8 @@ void TemplateTable::instanceof() { Rtags = R12_scratch2; // Null does not pass. - __ cmpdi(CCR0, R17_tos, 0); - __ beq(CCR0, Lis_null); + __ cmpdi(CR0, R17_tos, 0); + __ beq(CR0, Lis_null); // Get constant pool tag to find out if the bytecode has already been "quickened". __ get_cpool_and_tags(Rcpool, Rtags); @@ -4021,8 +4020,8 @@ void TemplateTable::instanceof() { __ addi(Rtags, Rtags, Array::base_offset_in_bytes()); __ lbzx(Rtags, Rtags, Roffset); - __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class); - __ beq(CCR0, Lquicked); + __ cmpdi(CR0, Rtags, JVM_CONSTANT_Class); + __ beq(CR0, Lquicked); // Call into the VM to "quicken" instanceof. __ push_ptr(); // for GC @@ -4128,8 +4127,8 @@ void TemplateTable::monitorenter() { __ null_check_throw(Robj_to_lock, -1, Rscratch1); // Check if any slot is present => short cut to allocation if not. - __ cmpld(CCR0, Rcurrent_monitor, Rbot); - __ beq(CCR0, Lallocate_new); + __ cmpld(CR0, Rcurrent_monitor, Rbot); + __ beq(CR0, Lallocate_new); // ------------------------------------------------------------------------------ // Find a free slot in the monitor block. @@ -4142,24 +4141,24 @@ void TemplateTable::monitorenter() { __ ld(Rcurrent_obj, in_bytes(BasicObjectLock::obj_offset()), Rcurrent_monitor); // Exit if current entry is for same object; this guarantees, that new monitor // used for recursive lock is above the older one. - __ cmpd(CCR0, Rcurrent_obj, Robj_to_lock); - __ beq(CCR0, Lexit); // recursive locking + __ cmpd(CR0, Rcurrent_obj, Robj_to_lock); + __ beq(CR0, Lexit); // recursive locking - __ cmpdi(CCR0, Rcurrent_obj, 0); - __ bne(CCR0, LnotFree); + __ cmpdi(CR0, Rcurrent_obj, 0); + __ bne(CR0, LnotFree); __ mr(Rfree_slot, Rcurrent_monitor); // remember free slot closest to the bottom __ bind(LnotFree); __ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes()); - __ cmpld(CCR0, Rcurrent_monitor, Rbot); - __ bne(CCR0, Lloop); + __ cmpld(CR0, Rcurrent_monitor, Rbot); + __ bne(CR0, Lloop); __ bind(Lexit); } // ------------------------------------------------------------------------------ // Check if we found a free slot. - __ cmpdi(CCR0, Rfree_slot, 0); - __ bne(CCR0, Lfound); + __ cmpdi(CR0, Rfree_slot, 0); + __ bne(CR0, Lfound); // We didn't find a free BasicObjLock => allocate one. __ bind(Lallocate_new); @@ -4207,8 +4206,8 @@ void TemplateTable::monitorexit() { __ null_check_throw(Robj_to_lock, -1, Rscratch); // Check corner case: unbalanced monitorEnter / Exit. - __ cmpld(CCR0, Rcurrent_monitor, Rbot); - __ beq(CCR0, Lillegal_monitor_state); + __ cmpld(CR0, Rcurrent_monitor, Rbot); + __ beq(CR0, Lillegal_monitor_state); // Find the corresponding slot in the monitors stack section. { @@ -4217,12 +4216,12 @@ void TemplateTable::monitorexit() { __ bind(Lloop); __ ld(Rcurrent_obj, in_bytes(BasicObjectLock::obj_offset()), Rcurrent_monitor); // Is this entry for same obj? - __ cmpd(CCR0, Rcurrent_obj, Robj_to_lock); - __ beq(CCR0, Lfound); + __ cmpd(CR0, Rcurrent_obj, Robj_to_lock); + __ beq(CR0, Lfound); __ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes()); - __ cmpld(CCR0, Rcurrent_monitor, Rbot); - __ bne(CCR0, Lloop); + __ cmpld(CR0, Rcurrent_monitor, Rbot); + __ bne(CR0, Lloop); } // Fell through without finding the basic obj lock => throw up! diff --git a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp index 40da31fa20932..872eee3b98e5a 100644 --- a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "logging/logStream.hpp" diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 9a4f13e41a04d..8ec69bffe15ea 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" @@ -90,7 +89,7 @@ void VM_Version::initialize() { default: break; } guarantee(PowerArchitecturePPC64_ok, "PowerArchitecturePPC64 cannot be set to " - UINTX_FORMAT " on this machine", PowerArchitecturePPC64); + "%zu on this machine", PowerArchitecturePPC64); // Power 8: Configure Data Stream Control Register. if (PowerArchitecturePPC64 >= 8 && has_mfdscr()) { @@ -132,6 +131,9 @@ void VM_Version::initialize() { } } MaxVectorSize = SuperwordUseVSX ? 16 : 8; + if (FLAG_IS_DEFAULT(AlignVector)) { + FLAG_SET_ERGO(AlignVector, false); + } if (PowerArchitecturePPC64 >= 9) { if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) { diff --git a/src/hotspot/cpu/ppc/vmreg_ppc.cpp b/src/hotspot/cpu/ppc/vmreg_ppc.cpp index e76a83bc26961..d8a5c35cac0f5 100644 --- a/src/hotspot/cpu/ppc/vmreg_ppc.cpp +++ b/src/hotspot/cpu/ppc/vmreg_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp b/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp index 567cfae8d0a5e..e25a8baa9da61 100644 --- a/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/vtableStubs_ppc_64.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/vtableStubs.hpp" @@ -92,8 +91,8 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // Check offset vs vtable length. const Register vtable_len = R12_scratch2; __ lwz(vtable_len, in_bytes(Klass::vtable_length_offset()), rcvr_klass); - __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size()); - __ bge(CCR0, L); + __ cmpwi(CR0, vtable_len, vtable_index*vtableEntry::size()); + __ bge(CR0, L); __ li(R12_scratch2, vtable_index); __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false); __ bind(L); @@ -109,8 +108,8 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { #ifndef PRODUCT if (DebugVtables) { Label L; - __ cmpdi(CCR0, R19_method, 0); - __ bne(CCR0, L); + __ cmpdi(CR0, R19_method, 0); + __ bne(CR0, L); __ stop("Vtable entry is ZERO"); __ bind(L); } @@ -195,8 +194,8 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { #ifndef PRODUCT if (DebugVtables) { Label ok; - __ cmpdi(CCR0, R19_method, 0); - __ bne(CCR0, ok); + __ cmpdi(CR0, R19_method, 0); + __ bne(CR0, ok); __ stop("method is null"); __ bind(ok); } diff --git a/src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp b/src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp index 7e7321501cbbc..843a58e28d712 100644 --- a/src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp +++ b/src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "oops/constMethod.hpp" #include "oops/klass.inline.hpp" diff --git a/src/hotspot/cpu/riscv/assembler_riscv.cpp b/src/hotspot/cpu/riscv/assembler_riscv.cpp index 6a581a4d08193..4659afc09b57c 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -27,7 +27,6 @@ #include #include -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 31713d7362a18..3a638357f0b37 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -330,7 +330,104 @@ class InternalAddress: public Address { }; class Assembler : public AbstractAssembler { -public: +protected: + + static int zfa_zli_lookup_double(uint64_t value) { + switch(value) { + case 0xbff0000000000000 : return 0; + case 0x0010000000000000 : return 1; + case 0x3ef0000000000000 : return 2; + case 0x3f00000000000000 : return 3; + case 0x3f70000000000000 : return 4; + case 0x3f80000000000000 : return 5; + case 0x3fb0000000000000 : return 6; + case 0x3fc0000000000000 : return 7; + case 0x3fd0000000000000 : return 8; + case 0x3fd4000000000000 : return 9; + case 0x3fd8000000000000 : return 10; + case 0x3fdc000000000000 : return 11; + case 0x3fe0000000000000 : return 12; + case 0x3fe4000000000000 : return 13; + case 0x3fe8000000000000 : return 14; + case 0x3fec000000000000 : return 15; + case 0x3ff0000000000000 : return 16; + case 0x3ff4000000000000 : return 17; + case 0x3ff8000000000000 : return 18; + case 0x3ffc000000000000 : return 19; + case 0x4000000000000000 : return 20; + case 0x4004000000000000 : return 21; + case 0x4008000000000000 : return 22; + case 0x4010000000000000 : return 23; + case 0x4020000000000000 : return 24; + case 0x4030000000000000 : return 25; + case 0x4060000000000000 : return 26; + case 0x4070000000000000 : return 27; + case 0x40e0000000000000 : return 28; + case 0x40f0000000000000 : return 29; + case 0x7ff0000000000000 : return 30; + case 0x7ff8000000000000 : return 31; + default: break; + } + return -1; + } + + + static int zfa_zli_lookup_float(uint32_t value) { + switch(value) { + case 0xbf800000 : return 0; + case 0x00800000 : return 1; + case 0x37800000 : return 2; + case 0x38000000 : return 3; + case 0x3b800000 : return 4; + case 0x3c000000 : return 5; + case 0x3d800000 : return 6; + case 0x3e000000 : return 7; + case 0x3e800000 : return 8; + case 0x3ea00000 : return 9; + case 0x3ec00000 : return 10; + case 0x3ee00000 : return 11; + case 0x3f000000 : return 12; + case 0x3f200000 : return 13; + case 0x3f400000 : return 14; + case 0x3f600000 : return 15; + case 0x3f800000 : return 16; + case 0x3fa00000 : return 17; + case 0x3fc00000 : return 18; + case 0x3fe00000 : return 19; + case 0x40000000 : return 20; + case 0x40200000 : return 21; + case 0x40400000 : return 22; + case 0x40800000 : return 23; + case 0x41000000 : return 24; + case 0x41800000 : return 25; + case 0x43000000 : return 26; + case 0x43800000 : return 27; + case 0x47000000 : return 28; + case 0x47800000 : return 29; + case 0x7f800000 : return 30; + case 0x7fc00000 : return 31; + default: break; + } + return -1; + } + + public: + + static bool can_zfa_zli_float(jfloat f) { + if (!UseZfa) { + return false; + } + uint32_t f_bits = (uint32_t)jint_cast(f); + return zfa_zli_lookup_float(f_bits) != -1; + } + + static bool can_zfa_zli_double(jdouble d) { + if (!UseZfa) { + return false; + } + uint64_t d_bits = (uint64_t)julong_cast(d); + return zfa_zli_lookup_double(d_bits) != -1; + } enum { instruction_size = 4, @@ -552,24 +649,6 @@ class Assembler : public AbstractAssembler { #undef INSN -#define INSN(NAME, op, funct3) \ - void NAME(FloatRegister Rd, Register Rs, const int32_t offset) { \ - guarantee(is_simm12(offset), "offset is invalid."); \ - unsigned insn = 0; \ - uint32_t val = offset & 0xfff; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch_reg((address)&insn, 15, Rs); \ - patch_reg((address)&insn, 7, Rd); \ - patch((address)&insn, 31, 20, val); \ - emit(insn); \ - } - - INSN(flw, 0b0000111, 0b010); - INSN(_fld, 0b0000111, 0b011); - -#undef INSN - #define INSN(NAME, op, funct3) \ void NAME(Register Rs1, Register Rs2, const int64_t offset) { \ guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \ @@ -813,29 +892,9 @@ enum operand_size { int8, int16, int32, uint32, int64 }; INSN(sc_d, 0b0101111, 0b011, 0b00011); #undef INSN -#define INSN(NAME, op, funct5, funct7) \ - void NAME(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, rm); \ - patch((address)&insn, 24, 20, funct5); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - emit(insn); \ - } - - INSN(fsqrt_s, 0b1010011, 0b00000, 0b0101100); - INSN(fsqrt_d, 0b1010011, 0b00000, 0b0101101); - INSN(fcvt_s_h, 0b1010011, 0b00010, 0b0100000); - INSN(fcvt_h_s, 0b1010011, 0b00000, 0b0100010); - INSN(fcvt_s_d, 0b1010011, 0b00001, 0b0100000); - INSN(fcvt_d_s, 0b1010011, 0b00000, 0b0100001); -#undef INSN - // Immediate Instruction #define INSN(NAME, op, funct3) \ - void NAME(Register Rd, Register Rs1, int32_t imm) { \ + void NAME(Register Rd, Register Rs1, int64_t imm) { \ guarantee(is_simm12(imm), "Immediate is out of validity"); \ unsigned insn = 0; \ patch((address)&insn, 6, 0, op); \ @@ -846,17 +905,17 @@ enum operand_size { int8, int16, int32, uint32, int64 }; emit(insn); \ } - INSN(_addi, 0b0010011, 0b000); - INSN(slti, 0b0010011, 0b010); - INSN(_addiw, 0b0011011, 0b000); - INSN(_and_imm12, 0b0010011, 0b111); - INSN(ori, 0b0010011, 0b110); - INSN(xori, 0b0010011, 0b100); + INSN(_addi, 0b0010011, 0b000); + INSN(_addiw, 0b0011011, 0b000); + INSN(_andi, 0b0010011, 0b111); + INSN(ori, 0b0010011, 0b110); + INSN(xori, 0b0010011, 0b100); + INSN(slti, 0b0010011, 0b010); #undef INSN #define INSN(NAME, op, funct3) \ - void NAME(Register Rd, Register Rs1, uint32_t imm) { \ + void NAME(Register Rd, Register Rs1, uint64_t imm) { \ guarantee(is_uimm12(imm), "Immediate is out of validity"); \ unsigned insn = 0; \ patch((address)&insn,6, 0, op); \ @@ -928,209 +987,427 @@ enum operand_size { int8, int16, int32, uint32, int64 }; #undef INSN -// Float and Double Rigster Instruction -#define INSN(NAME, op, funct2) \ - void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, rm); \ - patch((address)&insn, 26, 25, funct2); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch_reg((address)&insn, 20, Rs2); \ - patch_reg((address)&insn, 27, Rs3); \ - emit(insn); \ - } - - INSN(fmadd_s, 0b1000011, 0b00); - INSN(fmsub_s, 0b1000111, 0b00); - INSN(fnmsub_s, 0b1001011, 0b00); - INSN(fnmadd_s, 0b1001111, 0b00); - INSN(fmadd_d, 0b1000011, 0b01); - INSN(fmsub_d, 0b1000111, 0b01); - INSN(fnmsub_d, 0b1001011, 0b01); - INSN(fnmadd_d, 0b1001111, 0b01); - -#undef INSN - -// Float and Double Rigster Instruction -#define INSN(NAME, op, funct3, funct7) \ - void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch_reg((address)&insn, 20, Rs2); \ - emit(insn); \ - } - - INSN(fsgnj_s, 0b1010011, 0b000, 0b0010000); - INSN(fsgnjn_s, 0b1010011, 0b001, 0b0010000); - INSN(fsgnjx_s, 0b1010011, 0b010, 0b0010000); - INSN(fmin_s, 0b1010011, 0b000, 0b0010100); - INSN(fmax_s, 0b1010011, 0b001, 0b0010100); - INSN(fsgnj_d, 0b1010011, 0b000, 0b0010001); - INSN(fsgnjn_d, 0b1010011, 0b001, 0b0010001); - INSN(fsgnjx_d, 0b1010011, 0b010, 0b0010001); - INSN(fmin_d, 0b1010011, 0b000, 0b0010101); - INSN(fmax_d, 0b1010011, 0b001, 0b0010101); - -#undef INSN - -// Float and Double Rigster Arith Instruction -#define INSN(NAME, op, funct3, funct7) \ - void NAME(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch_reg((address)&insn, 20, Rs2); \ - emit(insn); \ +// ========================== +// Floating Point Instructions +// ========================== + static constexpr uint32_t OP_FP_MAJOR = 0b1010011; + + enum FmtPrecision : uint8_t { + S_32_sp = 0b00, + D_64_dp = 0b01, + H_16_hp = 0b10, + Q_128_qp = 0b11 + }; + + private: + + template + void fp_base(uint8_t Rd, uint8_t Rs1, uint8_t Rs2, RoundingMode rm) { + assert(Fmt != H_16_hp || UseZfh || UseZfhmin, "No half precision enabled"); + assert_cond(Fmt != Q_128_qp); + guarantee(is_uimm3(rm), "Rounding mode is out of validity"); + guarantee(is_uimm2(Fmt), "FMT is out of validity"); + guarantee(is_uimm5(funct5), "Funct5 is out of validity"); + uint32_t insn = 0; + patch((address)&insn, 6, 0, OP_FP_MAJOR); + patch((address)&insn, 11, 7, Rd); + patch((address)&insn, 14, 12, rm); + patch((address)&insn, 19, 15, Rs1); + patch((address)&insn, 24, 20, Rs2); + patch((address)&insn, 26, 25, Fmt); + patch((address)&insn, 31, 27, funct5); + emit(insn); } - INSN(feq_s, 0b1010011, 0b010, 0b1010000); - INSN(flt_s, 0b1010011, 0b001, 0b1010000); - INSN(fle_s, 0b1010011, 0b000, 0b1010000); - INSN(feq_d, 0b1010011, 0b010, 0b1010001); - INSN(fle_d, 0b1010011, 0b000, 0b1010001); - INSN(flt_d, 0b1010011, 0b001, 0b1010001); -#undef INSN + template + void fp_base(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm) { + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), rm); + } -// Float and Double Arith Instruction -#define INSN(NAME, op, funct7) \ - void NAME(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, rm); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch_reg((address)&insn, 20, Rs2); \ - emit(insn); \ + template + void fp_base(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, int8_t rm) { + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), (RoundingMode)rm); } - INSN(fadd_s, 0b1010011, 0b0000000); - INSN(fsub_s, 0b1010011, 0b0000100); - INSN(fmul_s, 0b1010011, 0b0001000); - INSN(fdiv_s, 0b1010011, 0b0001100); - INSN(fadd_d, 0b1010011, 0b0000001); - INSN(fsub_d, 0b1010011, 0b0000101); - INSN(fmul_d, 0b1010011, 0b0001001); - INSN(fdiv_d, 0b1010011, 0b0001101); + template + void fp_base(Register Rd, FloatRegister Rs1, FloatRegister Rs2, int8_t rm) { + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), (RoundingMode)rm); + } -#undef INSN + template + void fp_base(FloatRegister Rd, FloatRegister Rs1, int8_t Rs2, int8_t rm) { + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm); + } -// Whole Float and Double Conversion Instruction -#define INSN(NAME, op, funct5, funct7) \ - void NAME(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, rm); \ - patch((address)&insn, 24, 20, funct5); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - emit(insn); \ + template + void fp_base(FloatRegister Rd, Register Rs1, FloatRegister Rs2, RoundingMode rm) { + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2->raw_encoding(), rm); } - INSN(fcvt_s_w, 0b1010011, 0b00000, 0b1101000); - INSN(fcvt_s_wu, 0b1010011, 0b00001, 0b1101000); - INSN(fcvt_s_l, 0b1010011, 0b00010, 0b1101000); - INSN(fcvt_s_lu, 0b1010011, 0b00011, 0b1101000); - INSN(fcvt_d_w, 0b1010011, 0b00000, 0b1101001); - INSN(fcvt_d_wu, 0b1010011, 0b00001, 0b1101001); - INSN(fcvt_d_l, 0b1010011, 0b00010, 0b1101001); - INSN(fcvt_d_lu, 0b1010011, 0b00011, 0b1101001); + template + void fp_base(Register Rd, FloatRegister Rs1, uint8_t Rs2, RoundingMode rm) { + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, rm); + } -#undef INSN + template + void fp_base(Register Rd, FloatRegister Rs1, uint8_t Rs2, uint8_t rm) { + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm); + } -// Float and Double Conversion Instruction -#define INSN(NAME, op, funct5, funct7) \ - void NAME(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, rm); \ - patch((address)&insn, 24, 20, funct5); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - emit(insn); \ + template + void fp_base(FloatRegister Rd, Register Rs1, uint8_t Rs2, RoundingMode rm) { + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, rm); } - INSN(fcvt_w_s, 0b1010011, 0b00000, 0b1100000); - INSN(fcvt_l_s, 0b1010011, 0b00010, 0b1100000); - INSN(fcvt_wu_s, 0b1010011, 0b00001, 0b1100000); - INSN(fcvt_lu_s, 0b1010011, 0b00011, 0b1100000); - INSN(fcvt_w_d, 0b1010011, 0b00000, 0b1100001); - INSN(fcvt_wu_d, 0b1010011, 0b00001, 0b1100001); - INSN(fcvt_l_d, 0b1010011, 0b00010, 0b1100001); - INSN(fcvt_lu_d, 0b1010011, 0b00011, 0b1100001); - -#undef INSN - -// Float and Double Move Instruction -#define INSN(NAME, op, funct3, funct5, funct7) \ - void NAME(FloatRegister Rd, Register Rs1) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch((address)&insn, 20, funct5); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - emit(insn); \ - } - - INSN(fmv_h_x, 0b1010011, 0b000, 0b00000, 0b1111010); - INSN(fmv_w_x, 0b1010011, 0b000, 0b00000, 0b1111000); - INSN(fmv_d_x, 0b1010011, 0b000, 0b00000, 0b1111001); - -#undef INSN - -enum fclass_mask { - minf = 1 << 0, // negative infinite - mnorm = 1 << 1, // negative normal number - msubnorm = 1 << 2, // negative subnormal number - mzero = 1 << 3, // negative zero - pzero = 1 << 4, // positive zero - psubnorm = 1 << 5, // positive subnormal number - pnorm = 1 << 6, // positive normal number - pinf = 1 << 7, // positive infinite - snan = 1 << 8, // signaling NaN - qnan = 1 << 9, // quiet NaN - zero = mzero | pzero, - subnorm = msubnorm | psubnorm, - norm = mnorm | pnorm, - inf = minf | pinf, - nan = snan | qnan, - finite = zero | subnorm | norm, -}; + template + void fp_base(FloatRegister Rd, Register Rs1, uint8_t Rs2, int8_t rm) { + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1->raw_encoding(), Rs2, (RoundingMode)rm); + } -// Float and Double Conversion/Classify Instruction -#define INSN(NAME, op, funct3, funct5, funct7) \ - void NAME(Register Rd, FloatRegister Rs1) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch((address)&insn, 20, funct5); \ - patch((address)&insn, 31, 25, funct7); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - emit(insn); \ + template + void fp_base(FloatRegister Rd, uint8_t Rs1, uint8_t Rs2, int8_t rm) { + guarantee(is_uimm5(Rs1), "Rs1 is out of validity"); + guarantee(is_uimm5(Rs2), "Rs2 is out of validity"); + fp_base(Rd->raw_encoding(), Rs1, Rs2, (RoundingMode)rm); } - INSN(fclass_h, 0b1010011, 0b001, 0b00000, 0b1110010); - INSN(fclass_s, 0b1010011, 0b001, 0b00000, 0b1110000); - INSN(fclass_d, 0b1010011, 0b001, 0b00000, 0b1110001); - INSN(fmv_x_h, 0b1010011, 0b000, 0b00000, 0b1110010); - INSN(fmv_x_w, 0b1010011, 0b000, 0b00000, 0b1110000); - INSN(fmv_x_d, 0b1010011, 0b000, 0b00000, 0b1110001); + public: -#undef INSN + enum FClassBits { + minf = 1 << 0, // negative infinite + mnorm = 1 << 1, // negative normal number + msubnorm = 1 << 2, // negative subnormal number + mzero = 1 << 3, // negative zero + pzero = 1 << 4, // positive zero + psubnorm = 1 << 5, // positive subnormal number + pnorm = 1 << 6, // positive normal number + pinf = 1 << 7, // positive infinite + snan = 1 << 8, // signaling NaN + qnan = 1 << 9, // quiet NaN + zero = mzero | pzero, + subnorm = msubnorm | psubnorm, + norm = mnorm | pnorm, + inf = minf | pinf, + nan = snan | qnan, + finite = zero | subnorm | norm, + }; + + void fsqrt_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fsqrt_d(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fcvt_s_d(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00001, rm); + } + + void fcvt_d_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fsgnj_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void fsgnjn_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void fsgnjx_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b010); + } + + void fmin_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void fmax_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void fsgnj_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void fsgnjn_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void fsgnjx_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b010); + } + + void fmin_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void fmax_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void feq_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b010); + } + + void flt_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void fle_s(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void feq_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b010); + } + + void fle_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b000); + } + + void flt_d(Register Rd, FloatRegister Rs1, FloatRegister Rs2) { + fp_base(Rd, Rs1, Rs2, 0b001); + } + + void fadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fmul_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fdiv_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fmul_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fdiv_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, RoundingMode rm = rne) { + fp_base(Rd, Rs1, Rs2, rm); + } + + void fcvt_s_w(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fcvt_s_wu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00001, rm); + } + + void fcvt_s_l(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00010, rm); + } + + void fcvt_s_lu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00011, rm); + } + + void fcvt_d_w(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fcvt_d_wu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00001, rm); + } + + void fcvt_d_l(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00010, rm); + } + + void fcvt_d_lu(FloatRegister Rd, Register Rs1, RoundingMode rm = rne) { + fp_base(Rd, Rs1, 0b00011, rm); + } + + void fcvt_w_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fcvt_l_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00010, rm); + } + + void fcvt_wu_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00001, rm); + } + + void fcvt_lu_s(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00011, rm); + } + + void fcvt_w_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fcvt_wu_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00001, rm); + } + + void fcvt_l_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00010, rm); + } + + void fcvt_lu_d(Register Rd, FloatRegister Rs1, RoundingMode rm = rtz) { + fp_base(Rd, Rs1, 0b00011, rm); + } + + void fmv_w_x(FloatRegister Rd, Register Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b000); + } + + void fmv_d_x(FloatRegister Rd, Register Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b000); + } + + void fclass_s(Register Rd, FloatRegister Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b001); + } + + void fclass_d(Register Rd, FloatRegister Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b001); + } + + void fmv_x_w(Register Rd, FloatRegister Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b000); + } + + void fmv_x_d(Register Rd, FloatRegister Rs1) { + fp_base(Rd, Rs1, 0b00000, 0b000); + } + + private: + static constexpr unsigned int OP_LOAD_FP = 0b0000111; + + template + void fp_load(FloatRegister Rd, Register Rs, const int32_t offset) { + guarantee(is_uimm3(FpWidth), "Rounding mode is out of validity"); + guarantee(is_simm12(offset), "offset is invalid."); + unsigned insn = 0; + uint32_t val = offset & 0xfff; + patch((address)&insn, 6, 0, OP_LOAD_FP); + patch_reg((address)&insn, 7, Rd); + patch((address)&insn, 14, 12, FpWidth); + patch_reg((address)&insn, 15, Rs); + patch((address)&insn, 31, 20, val); + emit(insn); + } + + public: + + void flw(FloatRegister Rd, Register Rs, const int32_t offset) { fp_load<0b010>(Rd, Rs, offset); } + void _fld(FloatRegister Rd, Register Rs, const int32_t offset) { fp_load<0b011>(Rd, Rs, offset); } + + private: + template + void fp_fm(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm) { + assert_cond(Fmt != Q_128_qp); + guarantee(is_uimm3(rm), "Rounding mode is out of validity"); + guarantee(is_uimm2(Fmt), "FMT is out of validity"); + unsigned insn = 0; + patch((address)&insn, 6, 0, OpVal); + patch_reg((address)&insn, 7, Rd); + patch((address)&insn, 14, 12, rm); + patch_reg((address)&insn, 15, Rs1); + patch_reg((address)&insn, 20, Rs2); + patch((address)&insn, 26, 25, Fmt); + patch_reg((address)&insn, 27, Rs3); + emit(insn); + } + + public: + void fmadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fmsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fnmsub_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fnmadd_s(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fmadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fmsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fnmsub_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + + void fnmadd_d(FloatRegister Rd, FloatRegister Rs1, FloatRegister Rs2, FloatRegister Rs3, RoundingMode rm = rne) { + fp_fm(Rd, Rs1, Rs2, Rs3, rm); + } + +// -------------- ZFH Instruction Definitions -------------- +// Zfh Standard Extensions for Half-Precision Floating-Point + void fclass_h(Register Rd, FloatRegister Rs1) { + assert_cond(UseZfh); + fp_base(Rd, Rs1, 0b00000, 0b001); + } + +// Zfh and Zfhmin Half-Precision Floating-Point + void fcvt_s_h(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + assert_cond(UseZfh || UseZfhmin); + fp_base(Rd, Rs1, 0b00010, rm); + } + + void fcvt_h_s(FloatRegister Rd, FloatRegister Rs1, RoundingMode rm = rne) { + assert_cond(UseZfh || UseZfhmin); + fp_base(Rd, Rs1, 0b00000, rm); + } + + void fmv_h_x(FloatRegister Rd, Register Rs1) { + assert_cond(UseZfh || UseZfhmin); + fp_base(Rd, Rs1, 0b00000, 0b000); + } + + void fmv_x_h(Register Rd, FloatRegister Rs1) { + assert_cond(UseZfh || UseZfhmin); + fp_base(Rd, Rs1, 0b00000, 0b000); + } + +// -------------- ZFA Instruction Definitions -------------- +// Zfa Extension for Additional Floating-Point Instructions + void _fli_s(FloatRegister Rd, uint8_t Rs1) { + assert_cond(UseZfa); + fp_base(Rd, Rs1, 0b00001, 0b000); + } + + void _fli_d(FloatRegister Rd, uint8_t Rs1) { + assert_cond(UseZfa); + fp_base(Rd, Rs1, 0b00001, 0b000); + } // ========================== // RISC-V Vector Extension @@ -2015,10 +2292,10 @@ enum Nf { } INSN(add_uw, 0b0111011, 0b000, 0b0000100); - INSN(rol, 0b0110011, 0b001, 0b0110000); - INSN(rolw, 0b0111011, 0b001, 0b0110000); - INSN(ror, 0b0110011, 0b101, 0b0110000); - INSN(rorw, 0b0111011, 0b101, 0b0110000); + INSN(rolr, 0b0110011, 0b001, 0b0110000); + INSN(rolrw, 0b0111011, 0b001, 0b0110000); + INSN(rorr, 0b0110011, 0b101, 0b0110000); + INSN(rorrw, 0b0111011, 0b101, 0b0110000); INSN(sh1add, 0b0110011, 0b010, 0b0010000); INSN(sh2add, 0b0110011, 0b100, 0b0010000); INSN(sh3add, 0b0110011, 0b110, 0b0010000); @@ -2230,7 +2507,7 @@ enum Nf { } #define INSN(NAME, funct3, op) \ - void NAME(Register Rd_Rs1, int32_t imm) { \ + void NAME(Register Rd_Rs1, int64_t imm) { \ assert_cond(is_simm6(imm)); \ uint16_t insn = 0; \ c_patch((address)&insn, 1, 0, op); \ @@ -2247,7 +2524,7 @@ enum Nf { #undef INSN #define INSN(NAME, funct3, op) \ - void NAME(int32_t imm) { \ + void NAME(int64_t imm) { \ assert_cond(is_simm10(imm)); \ assert_cond((imm & 0b1111) == 0); \ assert_cond(imm != 0); \ @@ -2268,7 +2545,7 @@ enum Nf { #undef INSN #define INSN(NAME, funct3, op) \ - void NAME(Register Rd, uint32_t uimm) { \ + void NAME(Register Rd, uint64_t uimm) { \ assert_cond(is_uimm10(uimm)); \ assert_cond((uimm & 0b11) == 0); \ assert_cond(uimm != 0); \ @@ -2325,7 +2602,7 @@ enum Nf { #undef INSN #define INSN(NAME, funct3, funct2, op) \ - void NAME(Register Rd_Rs1, int32_t imm) { \ + void NAME(Register Rd_Rs1, int64_t imm) { \ assert_cond(is_simm6(imm)); \ uint16_t insn = 0; \ c_patch((address)&insn, 1, 0, op); \ @@ -2950,7 +3227,7 @@ enum Nf { // Immediate Instructions // -------------------------- #define INSN(NAME) \ - void NAME(Register Rd, Register Rs1, int32_t imm) { \ + void NAME(Register Rd, Register Rs1, int64_t imm) { \ /* addi -> c.addi/c.nop/c.mv/c.addi16sp/c.addi4spn */ \ if (do_compress()) { \ if (Rd == Rs1 && is_simm6(imm)) { \ @@ -2978,7 +3255,7 @@ enum Nf { // -------------------------- #define INSN(NAME) \ - void NAME(Register Rd, Register Rs1, int32_t imm) { \ + void NAME(Register Rd, Register Rs1, int64_t imm) { \ /* addiw -> c.addiw */ \ if (do_compress() && (Rd == Rs1 && Rd != x0 && is_simm6(imm))) { \ c_addiw(Rd, imm); \ @@ -2993,17 +3270,17 @@ enum Nf { // -------------------------- #define INSN(NAME) \ - void NAME(Register Rd, Register Rs1, int32_t imm) { \ - /* and_imm12 -> c.andi */ \ + void NAME(Register Rd, Register Rs1, int64_t imm) { \ + /* andi -> c.andi */ \ if (do_compress() && \ (Rd == Rs1 && Rd->is_compressed_valid() && is_simm6(imm))) { \ c_andi(Rd, imm); \ return; \ } \ - _and_imm12(Rd, Rs1, imm); \ + _andi(Rd, Rs1, imm); \ } - INSN(and_imm12); + INSN(andi); #undef INSN @@ -3070,42 +3347,63 @@ enum Nf { #undef INSN // Cache Management Operations -#define INSN(NAME, funct) \ - void NAME(Register Rs1) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, 0b0001111); \ - patch((address)&insn, 14, 12, 0b010); \ - patch_reg((address)&insn, 15, Rs1); \ - patch((address)&insn, 31, 20, funct); \ - emit(insn); \ +// These instruction may be turned off for user space. + private: + enum CBO_FUNCT : unsigned int { + CBO_INVAL = 0b0000000000000, + CBO_CLEAN = 0b0000000000001, + CBO_FLUSH = 0b0000000000010, + CBO_ZERO = 0b0000000000100 + }; + + template + void cbo_base(Register Rs1) { + assert((UseZicbom && FUNCT != CBO_ZERO) || UseZicboz, "sanity"); + unsigned insn = 0; + patch((address)&insn, 6, 0, 0b0001111); + patch((address)&insn, 14, 12, 0b010); + patch_reg((address)&insn, 15, Rs1); + patch((address)&insn, 31, 20, FUNCT); + emit(insn); } - INSN(cbo_inval, 0b0000000000000); - INSN(cbo_clean, 0b0000000000001); - INSN(cbo_flush, 0b0000000000010); - INSN(cbo_zero, 0b0000000000100); + // This instruction have some security implication. + // At this time it's not likely to be enabled for user mode. + void cbo_inval(Register Rs1) { cbo_base(Rs1); } + public: + // Zicbom + void cbo_clean(Register Rs1) { cbo_base(Rs1); } + void cbo_flush(Register Rs1) { cbo_base(Rs1); } + // Zicboz + void cbo_zero(Register Rs1) { cbo_base(Rs1); } -#undef INSN + private: + enum PREFETCH_FUNCT : unsigned int { + PREFETCH_I = 0b0000000000000, + PREFETCH_R = 0b0000000000001, + PREFETCH_W = 0b0000000000011 + }; -#define INSN(NAME, funct) \ - void NAME(Register Rs1, int32_t offset) { \ - guarantee((offset & 0x1f) == 0, "offset lowest 5 bits must be zero"); \ - int32_t upperOffset = offset >> 5; \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, 0b0010011); \ - patch((address)&insn, 14, 12, 0b110); \ - patch_reg((address)&insn, 15, Rs1); \ - patch((address)&insn, 24, 20, funct); \ - upperOffset &= 0x7f; \ - patch((address)&insn, 31, 25, upperOffset); \ - emit(insn); \ + template + void prefetch_base(Register Rs1, int32_t offset) { + assert_cond(UseZicbop); + guarantee((offset & 0x1f) == 0, "offset lowest 5 bits must be zero"); + int32_t upperOffset = offset >> 5; + unsigned insn = 0; + patch((address)&insn, 6, 0, 0b0010011); + patch((address)&insn, 14, 12, 0b110); + patch_reg((address)&insn, 15, Rs1); + patch((address)&insn, 24, 20, FUNCT); + upperOffset &= 0x7f; + patch((address)&insn, 31, 25, upperOffset); + emit(insn); } - INSN(prefetch_i, 0b0000000000000); - INSN(prefetch_r, 0b0000000000001); - INSN(prefetch_w, 0b0000000000011); - -#undef INSN + public: + // Zicbop + void prefetch_i(Register Rs1, int32_t offset) { prefetch_base(Rs1, offset); } + void prefetch_r(Register Rs1, int32_t offset) { prefetch_base(Rs1, offset); } + void prefetch_w(Register Rs1, int32_t offset) { prefetch_base(Rs1, offset); } // -------------- Zicond Instruction Definitions -------------- // Zicond conditional operations extension @@ -3381,6 +3679,7 @@ enum Nf { static bool is_simm18(int64_t x); static bool is_simm21(int64_t x); + static bool is_uimm2(uint64_t x); static bool is_uimm3(uint64_t x); static bool is_uimm5(uint64_t x); static bool is_uimm6(uint64_t x); diff --git a/src/hotspot/cpu/riscv/assembler_riscv.inline.hpp b/src/hotspot/cpu/riscv/assembler_riscv.inline.hpp index c51650881fc73..1f9e6df217206 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.inline.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.inline.hpp @@ -38,6 +38,7 @@ inline bool Assembler::is_simm13(int64_t x) { return is_simm(x, 13); } inline bool Assembler::is_simm18(int64_t x) { return is_simm(x, 18); } inline bool Assembler::is_simm21(int64_t x) { return is_simm(x, 21); } +inline bool Assembler::is_uimm2(uint64_t x) { return is_uimm(x, 2); } inline bool Assembler::is_uimm3(uint64_t x) { return is_uimm(x, 3); } inline bool Assembler::is_uimm5(uint64_t x) { return is_uimm(x, 5); } inline bool Assembler::is_uimm6(uint64_t x) { return is_uimm(x, 6); } diff --git a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp index 46af27a011f5a..b9bd7b356fa6b 100644 --- a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" diff --git a/src/hotspot/cpu/riscv/c1_FrameMap_riscv.cpp b/src/hotspot/cpu/riscv/c1_FrameMap_riscv.cpp index 172031941b2b0..d3ccd46048b06 100644 --- a/src/hotspot/cpu/riscv/c1_FrameMap_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_FrameMap_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp index ee6dedfcc076b..f84c44d6fea9b 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arith_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp index 7d673383cad26..5aa213fba7a7b 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_arraycopy_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" @@ -211,7 +210,7 @@ void LIR_Assembler::arraycopy_type_check(Register src, Register src_pos, Registe Label cont, slow; #define PUSH(r1, r2) \ - __ addi(sp, sp, -2 * wordSize); \ + __ subi(sp, sp, 2 * wordSize); \ __ sd(r1, Address(sp, 1 * wordSize)); \ __ sd(r2, Address(sp, 0)); @@ -337,10 +336,10 @@ void LIR_Assembler::arraycopy_prepare_params(Register src, Register src_pos, Reg Register dst, Register dst_pos, BasicType basic_type) { int scale = array_element_size(basic_type); __ shadd(c_rarg0, src_pos, src, t0, scale); - __ add(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); + __ addi(c_rarg0, c_rarg0, arrayOopDesc::base_offset_in_bytes(basic_type)); assert_different_registers(c_rarg0, dst, dst_pos, length); __ shadd(c_rarg1, dst_pos, dst, t0, scale); - __ add(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); + __ addi(c_rarg1, c_rarg1, arrayOopDesc::base_offset_in_bytes(basic_type)); assert_different_registers(c_rarg1, dst, length); __ mv(c_rarg2, length); assert_different_registers(c_rarg2, dst); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index d587a557a7312..c6af2de3cd420 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" @@ -426,6 +425,8 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod assert(dest->is_register(), "should not call otherwise"); LIR_Const* c = src->as_constant_ptr(); address const_addr = nullptr; + jfloat fconst; + jdouble dconst; switch (c->type()) { case T_INT: @@ -461,15 +462,25 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod break; case T_FLOAT: - const_addr = float_constant(c->as_jfloat()); - assert(const_addr != nullptr, "must create float constant in the constant table"); - __ flw(dest->as_float_reg(), InternalAddress(const_addr)); + fconst = c->as_jfloat(); + if (MacroAssembler::can_fp_imm_load(fconst)) { + __ fli_s(dest->as_float_reg(), fconst); + } else { + const_addr = float_constant(fconst); + assert(const_addr != nullptr, "must create float constant in the constant table"); + __ flw(dest->as_float_reg(), InternalAddress(const_addr)); + } break; case T_DOUBLE: - const_addr = double_constant(c->as_jdouble()); - assert(const_addr != nullptr, "must create double constant in the constant table"); - __ fld(dest->as_double_reg(), InternalAddress(const_addr)); + dconst = c->as_jdouble(); + if (MacroAssembler::can_dp_imm_load(dconst)) { + __ fli_d(dest->as_double_reg(), dconst); + } else { + const_addr = double_constant(c->as_jdouble()); + assert(const_addr != nullptr, "must create double constant in the constant table"); + __ fld(dest->as_double_reg(), InternalAddress(const_addr)); + } break; default: @@ -1084,7 +1095,7 @@ void LIR_Assembler::typecheck_helper_slowcheck(ciKlass *k, Register obj, Registe // check for self __ beq(klass_RInfo, k_RInfo, *success_target); - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(k_RInfo, Address(sp, 0)); // sub klass __ sd(klass_RInfo, Address(sp, wordSize)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); @@ -1099,7 +1110,7 @@ void LIR_Assembler::typecheck_helper_slowcheck(ciKlass *k, Register obj, Registe // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, nullptr); // call out-of-line instance of __ check_klass_subtytpe_slow_path(...) - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass __ sd(k_RInfo, Address(sp, 0)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); @@ -2139,7 +2150,7 @@ void LIR_Assembler::lir_store_slowcheck(Register k_RInfo, Register klass_RInfo, // perform the fast part of the checking logic __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, nullptr); // call out-of-line instance of __ check_klass_subtype_slow_path(...) - __ addi(sp, sp, -2 * wordSize); // 2: store k_RInfo and klass_RInfo + __ subi(sp, sp, 2 * wordSize); // 2: store k_RInfo and klass_RInfo __ sd(klass_RInfo, Address(sp, wordSize)); // sub klass __ sd(k_RInfo, Address(sp, 0)); // super klass __ far_call(RuntimeAddress(Runtime1::entry_for(C1StubId::slow_subtype_check_id))); diff --git a/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp index b328d457192ba..3868c5ea8293c 100644 --- a/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRGenerator_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" @@ -1103,6 +1102,11 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return Runtime1::entry_for(C1StubId::is_instance_of_id); +} + void LIRGenerator::do_If(If* x) { // If should have two successors assert(x->number_of_sux() == 2, "inconsistency"); diff --git a/src/hotspot/cpu/riscv/c1_LIR_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIR_riscv.cpp index 5f1c394ab3d46..6ce70f48cb459 100644 --- a/src/hotspot/cpu/riscv/c1_LIR_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIR_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "c1/c1_LIR.hpp" diff --git a/src/hotspot/cpu/riscv/c1_LinearScan_riscv.cpp b/src/hotspot/cpu/riscv/c1_LinearScan_riscv.cpp index 78a61128bdd5d..8a6dfbbdf1eb4 100644 --- a/src/hotspot/cpu/riscv/c1_LinearScan_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LinearScan_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/bitMap.inline.hpp" diff --git a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp index ed932dddcd8d8..76089e8dd4536 100644 --- a/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIR.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" @@ -199,16 +198,16 @@ void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int Label done; // len_in_bytes is positive and ptr sized - sub(len_in_bytes, len_in_bytes, hdr_size_in_bytes); + subi(len_in_bytes, len_in_bytes, hdr_size_in_bytes); beqz(len_in_bytes, done); // Preserve obj if (hdr_size_in_bytes) { - add(obj, obj, hdr_size_in_bytes); + addi(obj, obj, hdr_size_in_bytes); } zero_memory(obj, len_in_bytes, tmp); if (hdr_size_in_bytes) { - sub(obj, obj, hdr_size_in_bytes); + subi(obj, obj, hdr_size_in_bytes); } bind(done); @@ -262,7 +261,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register j(entry_point); bind(loop); - sub(index, index, 1); + subi(index, index, 1); for (int i = -unroll; i < 0; i++) { if (-i == remainder) { bind(entry_point); @@ -272,7 +271,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register if (remainder == 0) { bind(entry_point); } - add(t0, t0, unroll * wordSize); + addi(t0, t0, unroll * wordSize); bnez(index, loop); } } @@ -301,7 +300,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register tmp1 // align object end mv(arr_size, (int32_t)base_offset_in_bytes + MinObjAlignmentInBytesMask); shadd(arr_size, len, arr_size, t0, f); - andi(arr_size, arr_size, ~(uint)MinObjAlignmentInBytesMask); + andi(arr_size, arr_size, ~MinObjAlignmentInBytesMask); try_allocate(obj, arr_size, 0, tmp1, tmp2, slow_case); diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index 6f59f5c2b9559..0f1f1dd891c51 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_Defs.hpp" @@ -147,7 +146,7 @@ int StubAssembler::call_RT(Register oop_result, Register metadata_result, addres const int arg1_sp_offset = 0; const int arg2_sp_offset = 1; const int arg3_sp_offset = 2; - addi(sp, sp, -(arg_num + 1) * wordSize); + subi(sp, sp, (arg_num + 1) * wordSize); sd(arg1, Address(sp, arg1_sp_offset * wordSize)); sd(arg2, Address(sp, arg2_sp_offset * wordSize)); sd(arg3, Address(sp, arg3_sp_offset * wordSize)); @@ -301,14 +300,14 @@ static OopMap* save_live_registers(StubAssembler* sasm, if (save_fpu_registers) { // float registers - __ addi(sp, sp, -(FrameMap::nof_fpu_regs * wordSize)); + __ subi(sp, sp, FrameMap::nof_fpu_regs * wordSize); for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { __ fsd(as_FloatRegister(i), Address(sp, i * wordSize)); } } else { // we define reg_save_layout = 62 as the fixed frame size, // we should also sub 32 * wordSize to sp when save_fpu_registers == false - __ addi(sp, sp, -32 * wordSize); + __ subi(sp, sp, 32 * wordSize); } return generate_oop_map(sasm, save_fpu_registers); @@ -543,7 +542,7 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // Save our return address because // exception_handler_for_return_address will destroy it. We also // save exception_oop - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(exception_oop, Address(sp, wordSize)); __ sd(ra, Address(sp)); @@ -883,7 +882,13 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { __ ld(x10, Address(sp, (sup_k_off) * VMRegImpl::stack_slot_size)); // super klass Label miss; - __ check_klass_subtype_slow_path(x14, x10, x12, x15, nullptr, &miss); + __ check_klass_subtype_slow_path(x14, /*sub_klass*/ + x10, /*super_klass*/ + x12, /*tmp1_reg*/ + x15, /*tmp2_reg*/ + nullptr, /*L_success*/ + &miss /*L_failure*/); + // Need extras for table lookup: x7, x11, x13 // fallthrough on success: __ mv(t0, 1); @@ -920,6 +925,52 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { } break; + case C1StubId::is_instance_of_id: + { + // Mirror: x10 + // Object: x11 + // Temps: x13, x14, x15, x16, x17 + // Result: x10 + + // Get the Klass* into x16 + Register klass = x16, obj = x11, result = x10; + __ ld(klass, Address(x10, java_lang_Class::klass_offset())); + + Label fail, is_secondary, success; + + __ beqz(klass, fail); // Klass is null + __ beqz(obj, fail); // obj is null + + __ lwu(x13, Address(klass, in_bytes(Klass::super_check_offset_offset()))); + __ mv(x17, in_bytes(Klass::secondary_super_cache_offset())); + __ beq(x13, x17, is_secondary); // Klass is a secondary superclass + + // Klass is a concrete class + __ load_klass(x15, obj); + __ add(x17, x15, x13); + __ ld(x17, Address(x17)); + __ beq(klass, x17, success); + __ mv(result, 0); + __ ret(); + + __ bind(is_secondary); + __ load_klass(obj, obj); + + // This is necessary because I am never in my own secondary_super list. + __ beq(obj, klass, success); + + __ lookup_secondary_supers_table_var(obj, klass, result, x13, x14, x15, x17, &success); + + __ bind(fail); + __ mv(result, 0); + __ ret(); + + __ bind(success); + __ mv(result, 1); + __ ret(); + } + break; + case C1StubId::monitorexit_nofpu_id: save_fpu_registers = false; // fall through diff --git a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp index 6ed6a1979212d..3436f9f8fc9db 100644 --- a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "opto/c2_CodeStubs.hpp" #include "opto/c2_MacroAssembler.hpp" #include "runtime/objectMonitor.hpp" diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index a075895cd6c95..e52cf7565beb0 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "opto/c2_MacroAssembler.hpp" @@ -211,16 +210,14 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, // Handle existing monitor. bind(object_has_monitor); - STATIC_ASSERT(markWord::monitor_value <= INT_MAX); - add(tmp, tmp, -(int)markWord::monitor_value); // monitor - + subi(tmp, tmp, (int)markWord::monitor_value); // monitor ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); Label notRecursive; beqz(disp_hdr, notRecursive); // Will be 0 if not recursive. // Recursive lock - addi(disp_hdr, disp_hdr, -1); + subi(disp_hdr, disp_hdr, 1); sd(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset())); j(unlocked); @@ -537,7 +534,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, if (!UseObjectMonitorTable) { assert(tmp1_monitor == tmp1_mark, "should be the same here"); // Untag the monitor. - add(tmp1_monitor, tmp1_mark, -(int)markWord::monitor_value); + subi(tmp1_monitor, tmp1_mark, (int)markWord::monitor_value); } else { ld(tmp1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes())); // No valid pointer below alignof(ObjectMonitor*). Take the slow path. @@ -553,7 +550,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register box, beqz(tmp2_recursions, not_recursive); // Recursive unlock. - addi(tmp2_recursions, tmp2_recursions, -1); + subi(tmp2_recursions, tmp2_recursions, 1); sd(tmp2_recursions, Address(tmp1_monitor, ObjectMonitor::recursions_offset())); j(unlocked); @@ -732,7 +729,7 @@ void C2_MacroAssembler::string_indexof_char(Register str1, Register cnt1, BLOCK_COMMENT("string_indexof_char {"); beqz(cnt1, NOMATCH); - addi(t0, cnt1, isL ? -32 : -16); + subi(t0, cnt1, isL ? 32 : 16); bgtz(t0, DO_LONG); string_indexof_char_short(str1, cnt1, ch, result, isL); j(DONE); @@ -780,14 +777,15 @@ void C2_MacroAssembler::string_indexof_char(Register str1, Register cnt1, bind(CH1_LOOP); ld(ch1, Address(str1)); addi(str1, str1, 8); - addi(cnt1, cnt1, -8); + subi(cnt1, cnt1, 8); compute_match_mask(ch1, ch, match_mask, mask1, mask2); bnez(match_mask, HIT); bgtz(cnt1, CH1_LOOP); j(NOMATCH); bind(HIT); - ctzc_bit(trailing_char, match_mask, isL, ch1, result); + // count bits of trailing zero chars + ctzc_bits(trailing_char, match_mask, isL, ch1, result); srli(trailing_char, trailing_char, 3); addi(cnt1, cnt1, 8); ble(cnt1, trailing_char, NOMATCH); @@ -956,7 +954,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, const int ASIZE = 256; const int STORE_BYTES = 8; // 8 bytes stored per instruction(sd) - sub(sp, sp, ASIZE); + subi(sp, sp, ASIZE); // init BC offset table with default value: needle_len slli(t0, needle_len, 8); @@ -975,16 +973,16 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, for (int i = 0; i < 4; i++) { sd(tmp5, Address(ch1, i * wordSize)); } - add(ch1, ch1, 32); - sub(tmp6, tmp6, 4); + addi(ch1, ch1, 32); + subi(tmp6, tmp6, 4); bgtz(tmp6, BM_INIT_LOOP); - sub(nlen_tmp, needle_len, 1); // m - 1, index of the last element in pattern + subi(nlen_tmp, needle_len, 1); // m - 1, index of the last element in pattern Register orig_haystack = tmp5; mv(orig_haystack, haystack); // result_tmp = tmp4 shadd(haystack_end, result_tmp, haystack, haystack_end, haystack_chr_shift); - sub(ch2, needle_len, 1); // bc offset init value, ch2 is t1 + subi(ch2, needle_len, 1); // bc offset init value, ch2 is t1 mv(tmp3, needle); // for (i = 0; i < m - 1; ) { @@ -999,7 +997,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, // } bind(BCLOOP); (this->*needle_load_1chr)(ch1, Address(tmp3), noreg); - add(tmp3, tmp3, needle_chr_size); + addi(tmp3, tmp3, needle_chr_size); if (!needle_isL) { // ae == StrIntrinsicNode::UU mv(tmp6, ASIZE); @@ -1009,7 +1007,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, sb(ch2, Address(tmp4)); // store skip offset to BC offset table bind(BCSKIP); - sub(ch2, ch2, 1); // for next pattern element, skip distance -1 + subi(ch2, ch2, 1); // for next pattern element, skip distance -1 bgtz(ch2, BCLOOP); // tmp6: pattern end, address after needle @@ -1046,7 +1044,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, // compare pattern to source string backward shadd(result, nlen_tmp, haystack, result, haystack_chr_shift); (this->*haystack_load_1chr)(skipch, Address(result), noreg); - sub(nlen_tmp, nlen_tmp, firstStep); // nlen_tmp is positive here, because needle_len >= 8 + subi(nlen_tmp, nlen_tmp, firstStep); // nlen_tmp is positive here, because needle_len >= 8 if (needle_isL == haystack_isL) { // re-init tmp3. It's for free because it's executed in parallel with // load above. Alternative is to initialize it before loop, but it'll @@ -1065,7 +1063,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, if (isLL) { j(BMLOOPSTR1_AFTER_LOAD); } else { - sub(nlen_tmp, nlen_tmp, 1); // no need to branch for UU/UL case. cnt1 >= 8 + subi(nlen_tmp, nlen_tmp, 1); // no need to branch for UU/UL case. cnt1 >= 8 j(BMLOOPSTR1_CMP); } @@ -1076,7 +1074,7 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bind(BMLOOPSTR1_AFTER_LOAD); - sub(nlen_tmp, nlen_tmp, 1); + subi(nlen_tmp, nlen_tmp, 1); bltz(nlen_tmp, BMLOOPSTR1_LASTCMP); bind(BMLOOPSTR1_CMP); @@ -1098,11 +1096,11 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, lbu(result_tmp, Address(result_tmp)); // load skip offset bind(BMADV); - sub(nlen_tmp, needle_len, 1); + subi(nlen_tmp, needle_len, 1); // move haystack after bad char skip offset shadd(haystack, result_tmp, haystack, result, haystack_chr_shift); ble(haystack, haystack_end, BMLOOPSTR2); - add(sp, sp, ASIZE); + addi(sp, sp, ASIZE); j(NOMATCH); bind(BMLOOPSTR1_LASTCMP); @@ -1113,11 +1111,11 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle, if (!haystack_isL) { srli(result, result, 1); } - add(sp, sp, ASIZE); + addi(sp, sp, ASIZE); j(DONE); bind(LINEARSTUB); - sub(t0, needle_len, 16); // small patterns still should be handled by simple algorithm + subi(t0, needle_len, 16); // small patterns still should be handled by simple algorithm bltz(t0, LINEARSEARCH); mv(result, zr); RuntimeAddress stub = nullptr; @@ -1196,7 +1194,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne if (needle_con_cnt == -1) { Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT; - sub(t0, needle_len, needle_isL == haystack_isL ? 4 : 2); + subi(t0, needle_len, needle_isL == haystack_isL ? 4 : 2); bltz(t0, DOSHORT); (this->*needle_load_1chr)(first, Address(needle), noreg); @@ -1213,13 +1211,13 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne beq(first, ch2, STR1_LOOP); bind(STR2_NEXT); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, FIRST_LOOP); j(NOMATCH); bind(STR1_LOOP); - add(nlen_tmp, nlen_neg, needle_chr_size); - add(hlen_tmp, hlen_neg, haystack_chr_size); + addi(nlen_tmp, nlen_neg, needle_chr_size); + addi(hlen_tmp, hlen_neg, haystack_chr_size); bgez(nlen_tmp, MATCH); bind(STR1_NEXT); @@ -1228,14 +1226,14 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne add(ch2, haystack, hlen_tmp); (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bne(ch1, ch2, STR2_NEXT); - add(nlen_tmp, nlen_tmp, needle_chr_size); - add(hlen_tmp, hlen_tmp, haystack_chr_size); + addi(nlen_tmp, nlen_tmp, needle_chr_size); + addi(hlen_tmp, hlen_tmp, haystack_chr_size); bltz(nlen_tmp, STR1_NEXT); j(MATCH); bind(DOSHORT); if (needle_isL == haystack_isL) { - sub(t0, needle_len, 2); + subi(t0, needle_len, 2); bltz(t0, DO1); bgtz(t0, DO3); } @@ -1244,7 +1242,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne if (needle_con_cnt == 4) { Label CH1_LOOP; (this->*load_4chr)(ch1, Address(needle), noreg); - sub(result_tmp, haystack_len, 4); + subi(result_tmp, haystack_len, 4); slli(tmp3, result_tmp, haystack_chr_shift); // result as tmp add(haystack, haystack, tmp3); neg(hlen_neg, tmp3); @@ -1273,7 +1271,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_4chr)(ch2, Address(tmp3), noreg); } beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, CH1_LOOP); j(NOMATCH); } @@ -1284,7 +1282,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne bind(DO2); (this->*load_2chr)(ch1, Address(needle), noreg); if (needle_con_cnt == 2) { - sub(result_tmp, haystack_len, 2); + subi(result_tmp, haystack_len, 2); } slli(tmp3, result_tmp, haystack_chr_shift); add(haystack, haystack, tmp3); @@ -1307,7 +1305,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_2chr)(ch2, Address(tmp3), noreg); } beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, CH1_LOOP); j(NOMATCH); BLOCK_COMMENT("} string_indexof DO2"); @@ -1321,7 +1319,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne (this->*load_2chr)(first, Address(needle), noreg); (this->*needle_load_1chr)(ch1, Address(needle, 2 * needle_chr_size), noreg); if (needle_con_cnt == 3) { - sub(result_tmp, haystack_len, 3); + subi(result_tmp, haystack_len, 3); } slli(hlen_tmp, result_tmp, haystack_chr_shift); add(haystack, haystack, hlen_tmp); @@ -1340,12 +1338,12 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne beq(first, ch2, STR1_LOOP); bind(STR2_NEXT); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, FIRST_LOOP); j(NOMATCH); bind(STR1_LOOP); - add(hlen_tmp, hlen_neg, 2 * haystack_chr_size); + addi(hlen_tmp, hlen_neg, 2 * haystack_chr_size); add(ch2, haystack, hlen_tmp); (this->*haystack_load_1chr)(ch2, Address(ch2), noreg); bne(ch1, ch2, STR2_NEXT); @@ -1359,7 +1357,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne BLOCK_COMMENT("string_indexof DO1 {"); bind(DO1); (this->*needle_load_1chr)(ch1, Address(needle), noreg); - sub(result_tmp, haystack_len, 1); + subi(result_tmp, haystack_len, 1); slli(tmp3, result_tmp, haystack_chr_shift); add(haystack, haystack, tmp3); neg(hlen_neg, tmp3); @@ -1368,7 +1366,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne add(tmp3, haystack, hlen_neg); (this->*haystack_load_1chr)(ch2, Address(tmp3), noreg); beq(ch1, ch2, MATCH); - add(hlen_neg, hlen_neg, haystack_chr_size); + addi(hlen_neg, hlen_neg, haystack_chr_size); blez(hlen_neg, DO1_LOOP); BLOCK_COMMENT("} string_indexof DO1"); } @@ -1411,6 +1409,14 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, load_chr_insn str1_load_chr = str1_isL ? (load_chr_insn)&MacroAssembler::lbu : (load_chr_insn)&MacroAssembler::lhu; load_chr_insn str2_load_chr = str2_isL ? (load_chr_insn)&MacroAssembler::lbu : (load_chr_insn)&MacroAssembler::lhu; + int base_offset1 = arrayOopDesc::base_offset_in_bytes(T_BYTE); + int base_offset2 = arrayOopDesc::base_offset_in_bytes(T_CHAR); + + assert((base_offset1 % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + assert((base_offset2 % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + BLOCK_COMMENT("string_compare {"); // Bizarrely, the counts are passed in bytes, regardless of whether they @@ -1428,6 +1434,24 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, mv(cnt2, cnt1); bind(L); + // Load 4 bytes once to compare for alignment before main loop. Note that this + // is only possible for LL/UU case. We need to resort to load_long_misaligned + // for both LU and UL cases. + if (str1_isL == str2_isL) { // LL or UU + beq(str1, str2, DONE); + int base_offset = isLL ? base_offset1 : base_offset2; + if (AvoidUnalignedAccesses && (base_offset % 8) != 0) { + mv(t0, minCharsInWord / 2); + ble(cnt2, t0, SHORT_STRING); + lwu(tmp1, Address(str1)); + lwu(tmp2, Address(str2)); + bne(tmp1, tmp2, DIFFERENCE); + addi(str1, str1, 4); + addi(str2, str2, 4); + subi(cnt2, cnt2, minCharsInWord / 2); + } + } + // A very short string mv(t0, minCharsInWord); ble(cnt2, t0, SHORT_STRING); @@ -1436,14 +1460,22 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, // load first parts of strings and finish initialization while loading { if (str1_isL == str2_isL) { // LL or UU - // check if str1 and str2 is same pointer - beq(str1, str2, DONE); +#ifdef ASSERT + if (AvoidUnalignedAccesses) { + Label align_ok; + orr(t0, str1, str2); + andi(t0, t0, 0x7); + beqz(t0, align_ok); + stop("bad alignment"); + bind(align_ok); + } +#endif // load 8 bytes once to compare ld(tmp1, Address(str1)); ld(tmp2, Address(str2)); mv(t0, STUB_THRESHOLD); bge(cnt2, t0, STUB); - sub(cnt2, cnt2, minCharsInWord); + subi(cnt2, cnt2, minCharsInWord); beqz(cnt2, TAIL_CHECK); // convert cnt2 from characters to bytes if (!str1_isL) { @@ -1453,11 +1485,11 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, add(str1, str1, cnt2); sub(cnt2, zr, cnt2); } else if (isLU) { // LU case - lwu(tmp1, Address(str1)); - ld(tmp2, Address(str2)); mv(t0, STUB_THRESHOLD); bge(cnt2, t0, STUB); - addi(cnt2, cnt2, -4); + lwu(tmp1, Address(str1)); + load_long_misaligned(tmp2, Address(str2), tmp3, (base_offset2 % 8) != 0 ? 4 : 8); + subi(cnt2, cnt2, 4); add(str1, str1, cnt2); sub(cnt1, zr, cnt2); slli(cnt2, cnt2, 1); @@ -1467,11 +1499,11 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, sub(cnt2, zr, cnt2); addi(cnt1, cnt1, 4); } else { // UL case - ld(tmp1, Address(str1)); - lwu(tmp2, Address(str2)); mv(t0, STUB_THRESHOLD); bge(cnt2, t0, STUB); - addi(cnt2, cnt2, -4); + load_long_misaligned(tmp1, Address(str1), tmp3, (base_offset2 % 8) != 0 ? 4 : 8); + lwu(tmp2, Address(str2)); + subi(cnt2, cnt2, 4); slli(t0, cnt2, 1); sub(cnt1, zr, t0); add(str1, str1, t0); @@ -1488,6 +1520,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, // main loop bind(NEXT_WORD); if (str1_isL == str2_isL) { // LL or UU + // 8-byte aligned loads when AvoidUnalignedAccesses is enabled add(t0, str1, cnt2); ld(tmp1, Address(t0)); add(t0, str2, cnt2); @@ -1497,7 +1530,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, add(t0, str1, cnt1); lwu(tmp1, Address(t0)); add(t0, str2, cnt2); - ld(tmp2, Address(t0)); + load_long_misaligned(tmp2, Address(t0), tmp3, (base_offset2 % 8) != 0 ? 4 : 8); addi(cnt1, cnt1, 4); inflate_lo32(tmp3, tmp1); mv(tmp1, tmp3); @@ -1506,7 +1539,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, add(t0, str2, cnt2); lwu(tmp2, Address(t0)); add(t0, str1, cnt1); - ld(tmp1, Address(t0)); + load_long_misaligned(tmp1, Address(t0), tmp3, (base_offset2 % 8) != 0 ? 4 : 8); inflate_lo32(tmp3, tmp2); mv(tmp2, tmp3); addi(cnt1, cnt1, 8); @@ -1536,7 +1569,8 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, // compute their difference. bind(DIFFERENCE); xorr(tmp3, tmp1, tmp2); - ctzc_bit(result, tmp3, isLL); // count zero from lsb to msb + // count bits of trailing zero chars + ctzc_bits(result, tmp3, isLL); srl(tmp1, tmp1, result); srl(tmp2, tmp2, result); if (isLL) { @@ -1584,13 +1618,13 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, // while comparing previous (this->*str1_load_chr)(tmp1, Address(str1), t0); addi(str1, str1, str1_chr_size); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST_INIT); (this->*str2_load_chr)(cnt1, Address(str2), t0); addi(str2, str2, str2_chr_size); j(SHORT_LOOP_START); bind(SHORT_LOOP); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST); bind(SHORT_LOOP_START); (this->*str1_load_chr)(tmp2, Address(str1), t0); @@ -1598,7 +1632,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, (this->*str2_load_chr)(t0, Address(str2), t0); addi(str2, str2, str2_chr_size); bne(tmp1, cnt1, SHORT_LOOP_TAIL); - addi(cnt2, cnt2, -1); + subi(cnt2, cnt2, 1); beqz(cnt2, SHORT_LAST2); (this->*str1_load_chr)(tmp1, Address(str1), t0); addi(str1, str1, str1_chr_size); @@ -1633,11 +1667,14 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, assert(elem_size == 1 || elem_size == 2, "must be char or byte"); assert_different_registers(a1, a2, result, tmp1, tmp2, tmp3, t0); - int elem_per_word = wordSize/elem_size; + int elem_per_word = wordSize / elem_size; int log_elem_size = exact_log2(elem_size); int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE); + assert((base_offset % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + Register cnt1 = tmp3; Register cnt2 = tmp1; // cnt2 only used in array length compare Label DONE, SAME, NEXT_WORD, SHORT, TAIL03, TAIL01; @@ -1661,15 +1698,38 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, la(a1, Address(a1, base_offset)); la(a2, Address(a2, base_offset)); + + // Load 4 bytes once to compare for alignment before main loop. + if (AvoidUnalignedAccesses && (base_offset % 8) != 0) { + subi(cnt1, cnt1, elem_per_word / 2); + bltz(cnt1, TAIL03); + lwu(tmp1, Address(a1)); + lwu(tmp2, Address(a2)); + addi(a1, a1, 4); + addi(a2, a2, 4); + bne(tmp1, tmp2, DONE); + } + // Check for short strings, i.e. smaller than wordSize. - addi(cnt1, cnt1, -elem_per_word); + subi(cnt1, cnt1, elem_per_word); bltz(cnt1, SHORT); +#ifdef ASSERT + if (AvoidUnalignedAccesses) { + Label align_ok; + orr(t0, a1, a2); + andi(t0, t0, 0x7); + beqz(t0, align_ok); + stop("bad alignment"); + bind(align_ok); + } +#endif + // Main 8 byte comparison loop. bind(NEXT_WORD); { ld(tmp1, Address(a1)); ld(tmp2, Address(a2)); - addi(cnt1, cnt1, -elem_per_word); + subi(cnt1, cnt1, elem_per_word); addi(a1, a1, wordSize); addi(a2, a2, wordSize); bne(tmp1, tmp2, DONE); @@ -1730,25 +1790,52 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, void C2_MacroAssembler::string_equals(Register a1, Register a2, Register result, Register cnt1) { - Label SAME, DONE, SHORT, NEXT_WORD; + Label SAME, DONE, SHORT, NEXT_WORD, TAIL03, TAIL01; Register tmp1 = t0; Register tmp2 = t1; assert_different_registers(a1, a2, result, cnt1, tmp1, tmp2); + int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE); + + assert((base_offset % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + BLOCK_COMMENT("string_equals {"); mv(result, false); + // Load 4 bytes once to compare for alignment before main loop. + if (AvoidUnalignedAccesses && (base_offset % 8) != 0) { + subi(cnt1, cnt1, 4); + bltz(cnt1, TAIL03); + lwu(tmp1, Address(a1)); + lwu(tmp2, Address(a2)); + addi(a1, a1, 4); + addi(a2, a2, 4); + bne(tmp1, tmp2, DONE); + } + // Check for short strings, i.e. smaller than wordSize. - addi(cnt1, cnt1, -wordSize); + subi(cnt1, cnt1, wordSize); bltz(cnt1, SHORT); +#ifdef ASSERT + if (AvoidUnalignedAccesses) { + Label align_ok; + orr(t0, a1, a2); + andi(t0, t0, 0x7); + beqz(t0, align_ok); + stop("bad alignment"); + bind(align_ok); + } +#endif + // Main 8 byte comparison loop. bind(NEXT_WORD); { ld(tmp1, Address(a1)); ld(tmp2, Address(a2)); - addi(cnt1, cnt1, -wordSize); + subi(cnt1, cnt1, wordSize); addi(a1, a1, wordSize); addi(a2, a2, wordSize); bne(tmp1, tmp2, DONE); @@ -1758,8 +1845,6 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2, beqz(tmp1, SAME); bind(SHORT); - Label TAIL03, TAIL01; - // 0-7 bytes left. test_bit(tmp1, cnt1, 2); beqz(tmp1, TAIL03); @@ -1836,7 +1921,7 @@ void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register res beqz(cnt, DONE); - andi(chunks, cnt, ~(stride-1)); + andi(chunks, cnt, ~(stride - 1)); beqz(chunks, TAIL); mv(pow31_4, 923521); // [31^^4] @@ -1845,7 +1930,7 @@ void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register res slli(chunks_end, chunks, chunks_end_shift); add(chunks_end, ary, chunks_end); - andi(cnt, cnt, stride-1); // don't forget about tail! + andi(cnt, cnt, stride - 1); // don't forget about tail! bind(WIDE_LOOP); mulw(result, result, pow31_4); // 31^^4 * h @@ -2050,7 +2135,8 @@ void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Regis // Set dst to NaN if any NaN input. void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2, bool is_double, bool is_min) { - assert_different_registers(dst, src1, src2); + assert_different_registers(dst, src1); + assert_different_registers(dst, src2); Label Done, Compare; @@ -2059,7 +2145,7 @@ void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRe is_double ? fclass_d(t1, src2) : fclass_s(t1, src2); orr(t0, t0, t1); - andi(t0, t0, fclass_mask::nan); // if src1 or src2 is quiet or signaling NaN then return NaN + andi(t0, t0, FClassBits::nan); // if src1 or src2 is quiet or signaling NaN then return NaN beqz(t0, Compare); is_double ? fadd_d(dst, src1, src2) : fadd_s(dst, src1, src2); @@ -2153,7 +2239,7 @@ void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister one, bool is_ : fclass_s(t0, dst); // check if input is -0, +0, signaling NaN or quiet NaN - andi(t0, t0, fclass_mask::zero | fclass_mask::nan); + andi(t0, t0, FClassBits::zero | FClassBits::nan); bnez(t0, done); @@ -2369,7 +2455,7 @@ void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, Basi // check if input is -0, +0, signaling NaN or quiet NaN vfclass_v(v0, dst); - mv(t0, fclass_mask::zero | fclass_mask::nan); + mv(t0, FClassBits::zero | FClassBits::nan); vand_vx(v0, v0, t0); vmseq_vi(v0, v0, 0); @@ -2513,6 +2599,9 @@ void C2_MacroAssembler::arrays_equals_v(Register a1, Register a2, Register resul int length_offset = arrayOopDesc::length_offset_in_bytes(); int base_offset = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE); + assert((base_offset % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + BLOCK_COMMENT("arrays_equals_v {"); // if (a1 == a2), return true @@ -2866,6 +2955,45 @@ void C2_MacroAssembler::reduce_integral_v(Register dst, Register src1, vmv_x_s(dst, tmp); } +void C2_MacroAssembler::reduce_mul_integral_v(Register dst, Register src1, VectorRegister src2, + VectorRegister vtmp1, VectorRegister vtmp2, + BasicType bt, uint vector_length, VectorMask vm) { + assert(bt == T_BYTE || bt == T_SHORT || bt == T_INT || bt == T_LONG, "unsupported element type"); + vsetvli_helper(bt, vector_length); + + vector_length /= 2; + if (vm != Assembler::unmasked) { + // This behaviour is consistent with spec requirements of vector API, for `reduceLanes`: + // If no elements are selected, an operation-specific identity value is returned. + // If the operation is MUL, then the identity value is one. + vmv_v_i(vtmp1, 1); + vmerge_vvm(vtmp2, vtmp1, src2); // vm == v0 + vslidedown_vi(vtmp1, vtmp2, vector_length); + + vsetvli_helper(bt, vector_length); + vmul_vv(vtmp1, vtmp1, vtmp2); + } else { + vslidedown_vi(vtmp1, src2, vector_length); + + vsetvli_helper(bt, vector_length); + vmul_vv(vtmp1, vtmp1, src2); + } + + while (vector_length > 1) { + vector_length /= 2; + vslidedown_vi(vtmp2, vtmp1, vector_length); + vsetvli_helper(bt, vector_length); + vmul_vv(vtmp1, vtmp1, vtmp2); + } + + vmv_x_s(dst, vtmp1); + if (bt == T_INT) { + mulw(dst, dst, src1); + } else { + mul(dst, dst, src1); + } +} + // Set vl and vtype for full and partial vector operations. // (vma = mu, vta = tu, vill = false) void C2_MacroAssembler::vsetvli_helper(BasicType bt, uint vector_length, LMUL vlmul, Register tmp) { diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 114ad0a101c23..c79c360d2eb67 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -239,6 +239,10 @@ int opc, BasicType bt, uint vector_length, VectorMask vm = Assembler::unmasked); + void reduce_mul_integral_v(Register dst, Register src1, VectorRegister src2, + VectorRegister vtmp1, VectorRegister vtmp2, BasicType bt, + uint vector_length, VectorMask vm = Assembler::unmasked); + void vsetvli_helper(BasicType bt, uint vector_length, LMUL vlmul = Assembler::m1, Register tmp = t0); void compare_integral_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, int cond, diff --git a/src/hotspot/cpu/riscv/c2_init_riscv.cpp b/src/hotspot/cpu/riscv/c2_init_riscv.cpp index cdbd69807bee1..70a024f7f8afc 100644 --- a/src/hotspot/cpu/riscv/c2_init_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_init_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.cpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.cpp index e99183a5b5d91..280b3bd54e5ce 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.cpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.inline.hpp" #include "asm/macroAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index a864d7073dcfb..f541ac117eba0 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -33,6 +33,6 @@ public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } + static bool supports_shared_stubs() { return true; } #endif // CPU_RISCV_CODEBUFFER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/compiledIC_riscv.cpp b/src/hotspot/cpu/riscv/compiledIC_riscv.cpp index 65f3aa263aa02..a86e65ab58086 100644 --- a/src/hotspot/cpu/riscv/compiledIC_riscv.cpp +++ b/src/hotspot/cpu/riscv/compiledIC_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp index 7e596e0a7e99a..a2e732025d539 100644 --- a/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp +++ b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "oops/compressedKlass.hpp" #include "utilities/globalDefinitions.hpp" @@ -31,7 +30,7 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size char* result = nullptr; - // RiscV loads a 64-bit immediate in up to four separate steps, splitting it into four different sections + // RISC-V loads a 64-bit immediate in up to four separate steps, splitting it into four different sections // (two 32-bit sections, each split into two subsections of 20/12 bits). // // 63 ....... 44 43 ... 32 31 ....... 12 11 ... 0 @@ -51,11 +50,6 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size // with one instruction (2) result = reserve_address_space_for_unscaled_encoding(size, aslr); - // Failing that, attempt to reserve for base=zero shift>0 - if (result == nullptr && optimize_for_zero_base) { - result = reserve_address_space_for_zerobased_encoding(size, aslr); - } - // Failing that, optimize for case (3) - a base with only bits set between [32-44) if (result == nullptr) { const uintptr_t from = nth_bit(32); diff --git a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp index 97b168a98119e..1edb30a36ea78 100644 --- a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp b/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp index 2975b088b0c19..339e205c48afe 100644 --- a/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp +++ b/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "code/vmreg.inline.hpp" #include "runtime/jniHandles.hpp" #include "runtime/jniHandles.inline.hpp" diff --git a/src/hotspot/cpu/riscv/frame_riscv.cpp b/src/hotspot/cpu/riscv/frame_riscv.cpp index ecc450bd6b254..8ee6d11dcaf39 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.cpp +++ b/src/hotspot/cpu/riscv/frame_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" @@ -158,6 +157,11 @@ bool frame::safe_for_sender(JavaThread *thread) { } if (Continuation::is_return_barrier_entry(sender_pc)) { + // sender_pc might be invalid so check that the frame + // actually belongs to a Continuation. + if (!Continuation::is_frame_in_continuation(thread, *this)) { + return false; + } // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 6a3e4f95b9848..ef5dcdd8074a3 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" @@ -106,7 +105,7 @@ static void generate_queue_test_and_insertion(MacroAssembler* masm, ByteSize ind __ ld(tmp1, Address(thread, in_bytes(index_offset))); // tmp1 := *(index address) __ beqz(tmp1, runtime); // jump to runtime if index == 0 (full buffer) // The buffer is not full, store value into it. - __ sub(tmp1, tmp1, wordSize); // tmp1 := next index + __ subi(tmp1, tmp1, wordSize); // tmp1 := next index __ sd(tmp1, Address(thread, in_bytes(index_offset))); // *(index address) := next index __ ld(tmp2, Address(thread, in_bytes(buffer_offset))); // tmp2 := buffer address __ add(tmp2, tmp2, tmp1); @@ -490,7 +489,7 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* __ ld(tmp, queue_index); __ beqz(tmp, runtime); - __ sub(tmp, tmp, wordSize); + __ subi(tmp, tmp, wordSize); __ sd(tmp, queue_index); __ ld(t1, buffer); __ add(tmp, tmp, t1); @@ -557,7 +556,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* __ ld(t0, queue_index); __ beqz(t0, runtime); - __ sub(t0, t0, wordSize); + __ subi(t0, t0, wordSize); __ sd(t0, queue_index); // Reuse RA to hold buffer_addr diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp index d96d405aa2282..c49c8406befec 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp index 5373704c078a8..39da77181c674 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nativeInst.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp index 2ad44400687f2..df7ff65442ef9 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" @@ -69,7 +68,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ beqz(count, L_done); // zero count - nothing to do // end = start + count << LogBytesPerHeapOop __ shadd(end, count, start, count, LogBytesPerHeapOop); - __ sub(end, end, BytesPerHeapOop); // last element address to make inclusive + __ subi(end, end, BytesPerHeapOop); // last element address to make inclusive __ srli(start, start, CardTable::card_shift()); __ srli(end, end, CardTable::card_shift()); @@ -81,7 +80,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ bind(L_loop); __ add(tmp, start, count); __ sb(zr, Address(tmp)); - __ sub(count, count, 1); + __ subi(count, count, 1); __ bgez(count, L_loop); __ bind(L_done); } diff --git a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp index f2b0face0a9d3..6b0871007f488 100644 --- a/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/modRefBarrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp index d15b3aa31f905..2a96bd32cf8d7 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index 257d445f01187..97b83d78811a8 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" @@ -143,7 +142,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm, __ ld(tmp1, index); // tmp := *index_adr __ beqz(tmp1, runtime); // tmp == 0? If yes, goto runtime - __ sub(tmp1, tmp1, wordSize); // tmp := tmp - wordSize + __ subi(tmp1, tmp1, wordSize); // tmp := tmp - wordSize __ sd(tmp1, index); // *index_adr := tmp __ ld(tmp2, buffer); __ add(tmp1, tmp1, tmp2); // tmp := tmp + *buffer_adr @@ -562,7 +561,7 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb // end = start + count << LogBytesPerHeapOop // last element address to make inclusive __ shadd(end, count, start, tmp, LogBytesPerHeapOop); - __ sub(end, end, BytesPerHeapOop); + __ subi(end, end, BytesPerHeapOop); __ srli(start, start, CardTable::card_shift()); __ srli(end, end, CardTable::card_shift()); @@ -575,7 +574,7 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb __ bind(L_loop); __ add(tmp, start, count); __ sb(zr, Address(tmp)); - __ sub(count, count, 1); + __ subi(count, count, 1); __ bgez(count, L_loop); __ bind(L_done); } @@ -690,7 +689,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss __ ld(tmp, queue_index); __ beqz(tmp, runtime); - __ sub(tmp, tmp, wordSize); + __ subi(tmp, tmp, wordSize); __ sd(tmp, queue_index); __ ld(t1, buffer); __ add(tmp, tmp, t1); diff --git a/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp b/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp index 715f0d8aff7cb..683d892915f50 100644 --- a/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.hpp" @@ -84,7 +83,7 @@ static size_t probe_valid_max_address_bit() { munmap(result_addr, page_size); } } - log_info_p(gc, init)("Probing address space for the highest valid bit: " SIZE_FORMAT, max_address_bit); + log_info_p(gc, init)("Probing address space for the highest valid bit: %zu", max_address_bit); return MAX2(max_address_bit, MINIMUM_MAX_ADDRESS_BIT); #else // LINUX return DEFAULT_MAX_ADDRESS_BIT; diff --git a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp index 0b093838b8b68..09dea62b6d18f 100644 --- a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/vmreg.inline.hpp" @@ -241,7 +240,7 @@ static void store_barrier_buffer_add(MacroAssembler* masm, __ beqz(tmp2, slow_path); // Bump the pointer - __ sub(tmp2, tmp2, sizeof(ZStoreBarrierEntry)); + __ subi(tmp2, tmp2, sizeof(ZStoreBarrierEntry)); __ sd(tmp2, Address(tmp1, ZStoreBarrierBuffer::current_offset())); // Compute the buffer entry address @@ -848,10 +847,10 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce, // Save x10 unless it is the result or tmp register // Set up SP to accommdate parameters and maybe x10. if (ref != x10 && tmp != x10) { - __ sub(sp, sp, 32); + __ subi(sp, sp, 32); __ sd(x10, Address(sp, 16)); } else { - __ sub(sp, sp, 16); + __ subi(sp, sp, 16); } // Setup arguments and call runtime stub @@ -963,7 +962,7 @@ void ZBarrierSetAssembler::generate_c1_store_barrier_stub(LIR_Assembler* ce, __ la(stub->new_zpointer()->as_register(), ce->as_Address(stub->ref_addr()->as_address_ptr())); - __ sub(sp, sp, 16); + __ subi(sp, sp, 16); //Setup arguments and call runtime stub assert(stub->new_zpointer()->is_valid(), "invariant"); ce->store_parameter(stub->new_zpointer()->as_register(), 0); diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index 806cca16269ea..36c32d90cb3ee 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -103,7 +103,9 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZba, false, DIAGNOSTIC, "Use Zba instructions") \ product(bool, UseZbb, false, DIAGNOSTIC, "Use Zbb instructions") \ product(bool, UseZbs, false, DIAGNOSTIC, "Use Zbs instructions") \ + product(bool, UseZfa, false, EXPERIMENTAL, "Use Zfa instructions") \ product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \ + product(bool, UseZfhmin, false, DIAGNOSTIC, "Use Zfhmin instructions") \ product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \ product(bool, UseZcb, false, EXPERIMENTAL, "Use Zcb instructions") \ product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \ diff --git a/src/hotspot/cpu/riscv/icache_riscv.cpp b/src/hotspot/cpu/riscv/icache_riscv.cpp index d615dcfb9e9ae..258bc665770fd 100644 --- a/src/hotspot/cpu/riscv/icache_riscv.cpp +++ b/src/hotspot/cpu/riscv/icache_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "riscv_flush_icache.hpp" #include "runtime/java.hpp" diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index e17a3765b50ec..c132f9cda7a08 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -270,18 +269,18 @@ void InterpreterMacroAssembler::pop_l(Register r) { } void InterpreterMacroAssembler::push_ptr(Register r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); sd(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_i(Register r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); sext(r, r, 32); sd(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_l(Register r) { - addi(esp, esp, -2 * wordSize); + subi(esp, esp, 2 * wordSize); sd(zr, Address(esp, wordSize)); sd(r, Address(esp)); } @@ -297,12 +296,12 @@ void InterpreterMacroAssembler::pop_d(FloatRegister r) { } void InterpreterMacroAssembler::push_f(FloatRegister r) { - addi(esp, esp, -wordSize); + subi(esp, esp, wordSize); fsw(r, Address(esp, 0)); } void InterpreterMacroAssembler::push_d(FloatRegister r) { - addi(esp, esp, -2 * wordSize); + subi(esp, esp, 2 * wordSize); fsd(r, Address(esp, 0)); } @@ -544,7 +543,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags ld(x11, Address(fp, frame::interpreter_frame_method_offset * wordSize)); - ld(x12, Address(x11, Method::access_flags_offset())); + load_unsigned_short(x12, Address(x11, Method::access_flags_offset())); test_bit(t0, x12, exact_log2(JVM_ACC_SYNCHRONIZED)); beqz(t0, unlocked); @@ -895,7 +894,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { assert(ProfileInterpreter, "must be profiling interpreter"); #ifdef ASSERT Label verify_continue; - add(sp, sp, -4 * wordSize); + subi(sp, sp, 4 * wordSize); sd(x10, Address(sp, 0)); sd(x11, Address(sp, wordSize)); sd(x12, Address(sp, 2 * wordSize)); @@ -920,7 +919,7 @@ void InterpreterMacroAssembler::verify_method_data_pointer() { ld(x11, Address(sp, wordSize)); ld(x12, Address(sp, 2 * wordSize)); ld(x13, Address(sp, 3 * wordSize)); - add(sp, sp, 4 * wordSize); + addi(sp, sp, 4 * wordSize); #endif // ASSERT } @@ -961,7 +960,7 @@ void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, if (decrement) { ld(t0, addr); - addi(t0, t0, -DataLayout::counter_increment); + subi(t0, t0, DataLayout::counter_increment); Label L; bltz(t0, L); // skip store if counter underflow sd(t0, addr); @@ -1028,7 +1027,7 @@ void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - addi(mdp_in, mdp_in, (unsigned)constant); + add(mdp_in, mdp_in, (unsigned)constant); sd(mdp_in, Address(fp, frame::interpreter_frame_mdp_offset * wordSize)); } @@ -1037,7 +1036,7 @@ void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { assert(ProfileInterpreter, "must be profiling interpreter"); // save/restore across call_VM - addi(sp, sp, -2 * wordSize); + subi(sp, sp, 2 * wordSize); sd(zr, Address(sp, 0)); sd(return_bci, Address(sp, wordSize)); call_VM(noreg, @@ -1739,7 +1738,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca add(t0, mdp, t0); ld(t0, Address(t0)); sub(tmp, tmp, t0); - addi(tmp, tmp, -1); + subi(tmp, tmp, 1); Address arg_addr = argument_address(tmp); ld(tmp, arg_addr); @@ -1762,7 +1761,7 @@ void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register ca if (MethodData::profile_return()) { ld(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset()))); - addi(tmp, tmp, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + sub(tmp, tmp, TypeProfileArgsLimit * TypeStackSlotEntries::per_arg_count()); } add(t0, mdp, off_to_args); @@ -1849,7 +1848,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t // mdo start + parameters offset + array length - 1 add(mdp, mdp, tmp1); ld(tmp1, Address(mdp, ArrayData::array_len_offset())); - add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); + subi(tmp1, tmp1, TypeStackSlotEntries::per_arg_count()); Label loop; bind(loop); @@ -1875,7 +1874,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t profile_obj_type(tmp2, arg_type, tmp3); // go to next parameter - add(tmp1, tmp1, - TypeStackSlotEntries::per_arg_count()); + subi(tmp1, tmp1, TypeStackSlotEntries::per_arg_count()); bgez(tmp1, loop); bind(profile_continue); @@ -1890,7 +1889,7 @@ void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Registe ld(cache, Address(xcpool, in_bytes(ConstantPoolCache::invokedynamic_entries_offset()))); // Scale the index to be the entry index * sizeof(ResolvedIndyEntry) slli(index, index, log2i_exact(sizeof(ResolvedIndyEntry))); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } @@ -1906,7 +1905,7 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, } // Get address of field entries array ld(cache, Address(xcpool, ConstantPoolCache::field_entries_offset())); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); // Prevents stale data from being read after the bytecode is patched to the fast bytecode membar(MacroAssembler::LoadLoad); @@ -1932,7 +1931,7 @@ void InterpreterMacroAssembler::load_method_entry(Register cache, Register index // Get address of field entries array ld(cache, Address(xcpool, ConstantPoolCache::method_entries_offset())); - add(cache, cache, Array::base_offset_in_bytes()); + addi(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } diff --git a/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp b/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp index de34d84fecb00..c8e488d9d6919 100644 --- a/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp +++ b/src/hotspot/cpu/riscv/interpreterRT_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" @@ -138,10 +137,10 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { Register reg = next_gpr(); if (reg == c_rarg1) { assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); - __ addi(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); } else if (reg != noreg) { // c_rarg2-c_rarg7 - __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(x10, from(), Interpreter::local_offset_in_bytes(offset())); __ mv(reg, zr); //_num_reg_int_args:c_rarg -> 1:c_rarg2, 2:c_rarg3... __ ld(temp(), x10); Label L; @@ -150,7 +149,7 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { __ bind(L); } else { //to stack - __ addi(x10, from(), Interpreter::local_offset_in_bytes(offset())); + __ add(x10, from(), Interpreter::local_offset_in_bytes(offset())); __ ld(temp(), x10); Label L; __ bnez(temp(), L); diff --git a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp index 648a665fef5aa..b08e520393ab8 100644 --- a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp b/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp index 1c06d0b29aa6d..cbe387eed148c 100644 --- a/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp +++ b/src/hotspot/cpu/riscv/jvmciCodeInstaller_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "jvmci/jvmci.hpp" #include "jvmci/jvmciCodeInstaller.hpp" diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 27452e7a6842c..4276595ffccd2 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "code/compiledIC.hpp" @@ -245,7 +244,7 @@ void MacroAssembler::inc_held_monitor_count(Register tmp) { void MacroAssembler::dec_held_monitor_count(Register tmp) { Address dst(xthread, JavaThread::held_monitor_count_offset()); ld(tmp, dst); - addi(tmp, tmp, -1); + subi(tmp, tmp, 1); sd(tmp, dst); #ifdef ASSERT Label ok; @@ -794,7 +793,7 @@ void MacroAssembler::call_VM_leaf_base(address entry_point, Label *retaddr) { int32_t offset = 0; push_reg(RegSet::of(t1, xmethod), sp); // push << t1 & xmethod >> to sp - mv(t1, entry_point, offset); + movptr(t1, entry_point, offset, t0); jalr(t1, offset); if (retaddr != nullptr) { bind(*retaddr); @@ -1333,22 +1332,11 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist #undef INSN - -#define INSN(NAME, CSR) \ - void MacroAssembler::NAME(Register Rd) { \ - csrr(Rd, CSR); \ - } - - INSN(rdinstret, CSR_INSTRET); - INSN(rdcycle, CSR_CYCLE); - INSN(rdtime, CSR_TIME); - INSN(frcsr, CSR_FCSR); - INSN(frrm, CSR_FRM); - INSN(frflags, CSR_FFLAGS); - -#undef INSN - void MacroAssembler::csrr(Register Rd, unsigned csr) { + // These three are specified in zicntr and are unused. + // Before adding use-cases add the appropriate hwprobe and flag. + assert(csr != CSR_INSTRET && csr != CSR_CYCLE && csr != CSR_TIME, + "Not intended for use without enabling zicntr."); csrrs(Rd, csr, x0); } @@ -1430,7 +1418,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni(Register tmp) { void MacroAssembler::push_reg(Register Rs) { - addi(esp, esp, 0 - wordSize); + subi(esp, esp, wordSize); sd(Rs, Address(esp, 0)); } @@ -1462,7 +1450,7 @@ int MacroAssembler::push_reg(unsigned int bitset, Register stack) { int offset = is_even(count) ? 0 : wordSize; if (count) { - addi(stack, stack, -count * wordSize - offset); + sub(stack, stack, count * wordSize + offset); } for (int i = count - 1; i >= 0; i--) { sd(as_Register(regs[i]), Address(stack, (count - 1 - i) * wordSize + offset)); @@ -1487,7 +1475,7 @@ int MacroAssembler::pop_reg(unsigned int bitset, Register stack) { } if (count) { - addi(stack, stack, count * wordSize + offset); + add(stack, stack, count * wordSize + offset); } assert(words_popped == count, "oops, popped != count"); @@ -1503,7 +1491,7 @@ int MacroAssembler::push_fp(unsigned int bitset, Register stack) { int push_slots = count + (count & 1); if (count) { - addi(stack, stack, -push_slots * wordSize); + subi(stack, stack, push_slots * wordSize); } for (int i = count - 1; i >= 0; i--) { @@ -1632,7 +1620,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le Label VectorLoop; Label LastBlock; - add(tableN16, table3, 1*single_table_size*sizeof(juint), tmp1); + add(tableN16, table3, 1 * single_table_size * sizeof(juint), tmp1); mv(tmp5, 0xff); if (MaxVectorSize == 16) { @@ -1651,7 +1639,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le srli(blks, len, 6); slli(t1, blks, 6); sub(len, len, t1); - sub(blks, blks, 1); + subi(blks, blks, 1); blez(blks, LastBlock); bind(VectorLoop); @@ -1683,7 +1671,7 @@ void MacroAssembler::vector_update_crc32(Register crc, Register buf, Register le addi(tmp1, tmp1, 1); } - sub(blks, blks, 1); + subi(blks, blks, 1); bgtz(blks, VectorLoop); } @@ -2046,7 +2034,7 @@ void MacroAssembler::kernel_crc32_vclmul_fold(Register crc, Register buf, Regist Register vclmul_table = tmp3; la(vclmul_table, table_addr); - add(vclmul_table, vclmul_table, table_num*single_table_size*sizeof(juint), tmp1); + add(vclmul_table, vclmul_table, table_num * single_table_size * sizeof(juint), tmp1); la(table0, table_addr); if (MaxVectorSize == 16) { @@ -2092,25 +2080,25 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, const ExternalAddress table_addr = StubRoutines::crc_table_addr(); la(table0, table_addr); - add(table1, table0, 1*single_table_size*sizeof(juint), tmp1); - add(table2, table0, 2*single_table_size*sizeof(juint), tmp1); - add(table3, table2, 1*single_table_size*sizeof(juint), tmp1); + add(table1, table0, 1 * single_table_size * sizeof(juint), tmp1); + add(table2, table0, 2 * single_table_size * sizeof(juint), tmp1); + add(table3, table2, 1 * single_table_size * sizeof(juint), tmp1); // Ensure basic 4-byte alignment of input byte buffer mv(tmp1, 4); blt(len, tmp1, L_by1_loop); test_bit(tmp1, buf, 0); beqz(tmp1, L_skip1); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf)); - add(buf, buf, 1); + addi(buf, buf, 1); update_byte_crc32(crc, tmp1, table0); bind(L_skip1); test_bit(tmp1, buf, 1); beqz(tmp1, L_skip2); - subw(len, len, 2); + subiw(len, len, 2); lhu(tmp1, Address(buf)); - add(buf, buf, 2); + addi(buf, buf, 2); zext(tmp2, tmp1, 8); update_byte_crc32(crc, tmp2, table0); srli(tmp2, tmp1, 8); @@ -2134,8 +2122,8 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, align(CodeEntryAlignment); // Entry for L_unroll_loop - add(loop_buf_end, buf, len); // loop_buf_end will be used as endpoint for loop below - andi(len, len, unroll_words-1); // len = (len % unroll_words) + add(loop_buf_end, buf, len); // loop_buf_end will be used as endpoint for loop below + andi(len, len, unroll_words - 1); // len = (len % unroll_words) sub(loop_buf_end, loop_buf_end, len); bind(L_unroll_loop); for (int i = 0; i < unroll; i++) { @@ -2162,17 +2150,17 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, bind(L_by1_loop); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf)); update_byte_crc32(crc, tmp1, table0); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf, 1)); update_byte_crc32(crc, tmp1, table0); beqz(len, L_exit); - subw(len, len, 1); + subiw(len, len, 1); lbu(tmp1, Address(buf, 2)); update_byte_crc32(crc, tmp1, table0); @@ -2238,7 +2226,7 @@ void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) { push_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp); // Push float registers f0-f7, f10-f17, f28-f31. - addi(sp, sp, - wordSize * 20); + subi(sp, sp, wordSize * 20); int offset = 0; for (int i = 0; i < 32; i++) { if (i <= f7->encoding() || i >= f28->encoding() || (i >= f10->encoding() && i <= f17->encoding())) { @@ -2264,7 +2252,7 @@ void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) push_reg(RegSet::range(x5, x31), sp); // float registers - addi(sp, sp, - 32 * wordSize); + subi(sp, sp, 32 * wordSize); for (int i = 0; i < 32; i++) { fsd(as_FloatRegister(i), Address(sp, i * wordSize)); } @@ -2605,32 +2593,71 @@ void MacroAssembler::movptr2(Register Rd, uint64_t addr, int32_t &offset, Regist offset = lower12; } -void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register temp) { +// floating point imm move +bool MacroAssembler::can_fp_imm_load(float imm) { + jint f_bits = jint_cast(imm); + if (f_bits == 0) { + return true; + } + return can_zfa_zli_float(imm); +} + +bool MacroAssembler::can_dp_imm_load(double imm) { + julong d_bits = julong_cast(imm); + if (d_bits == 0) { + return true; + } + return can_zfa_zli_double(imm); +} + +void MacroAssembler::fli_s(FloatRegister Rd, float imm) { + jint f_bits = jint_cast(imm); + if (f_bits == 0) { + fmv_w_x(Rd, zr); + return; + } + int Rs = zfa_zli_lookup_float(f_bits); + assert(Rs != -1, "Must be"); + _fli_s(Rd, Rs); +} + +void MacroAssembler::fli_d(FloatRegister Rd, double imm) { + uint64_t d_bits = (uint64_t)julong_cast(imm); + if (d_bits == 0) { + fmv_d_x(Rd, zr); + return; + } + int Rs = zfa_zli_lookup_double(d_bits); + assert(Rs != -1, "Must be"); + _fli_d(Rd, Rs); +} + +void MacroAssembler::add(Register Rd, Register Rn, int64_t increment, Register tmp) { if (is_simm12(increment)) { addi(Rd, Rn, increment); } else { - assert_different_registers(Rn, temp); - li(temp, increment); - add(Rd, Rn, temp); + assert_different_registers(Rn, tmp); + mv(tmp, increment); + add(Rd, Rn, tmp); } } -void MacroAssembler::addw(Register Rd, Register Rn, int32_t increment, Register temp) { +void MacroAssembler::sub(Register Rd, Register Rn, int64_t decrement, Register tmp) { + add(Rd, Rn, -decrement, tmp); +} + +void MacroAssembler::addw(Register Rd, Register Rn, int64_t increment, Register tmp) { if (is_simm12(increment)) { addiw(Rd, Rn, increment); } else { - assert_different_registers(Rn, temp); - li(temp, increment); - addw(Rd, Rn, temp); + assert_different_registers(Rn, tmp); + mv(tmp, increment); + addw(Rd, Rn, tmp); } } -void MacroAssembler::sub(Register Rd, Register Rn, int64_t decrement, Register temp) { - add(Rd, Rn, -decrement, temp); -} - -void MacroAssembler::subw(Register Rd, Register Rn, int32_t decrement, Register temp) { - addw(Rd, Rn, -decrement, temp); +void MacroAssembler::subw(Register Rd, Register Rn, int64_t decrement, Register tmp) { + addw(Rd, Rn, -decrement, tmp); } void MacroAssembler::andrw(Register Rd, Register Rs1, Register Rs2) { @@ -2870,7 +2897,25 @@ void MacroAssembler::revb(Register Rd, Register Rs, Register tmp1, Register tmp2 } // rotate right with shift bits -void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Register tmp) +void MacroAssembler::ror(Register dst, Register src, Register shift, Register tmp) +{ + if (UseZbb) { + rorr(dst, src, shift); + return; + } + + assert_different_registers(dst, tmp); + assert_different_registers(src, tmp); + + mv(tmp, 64); + sub(tmp, tmp, shift); + sll(tmp, src, tmp); + srl(dst, src, shift); + orr(dst, dst, tmp); +} + +// rotate right with shift bits +void MacroAssembler::ror(Register dst, Register src, uint32_t shift, Register tmp) { if (UseZbb) { rori(dst, src, shift); @@ -2886,7 +2931,7 @@ void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Registe } // rotate left with shift bits, 32-bit version -void MacroAssembler::rolw_imm(Register dst, Register src, uint32_t shift, Register tmp) { +void MacroAssembler::rolw(Register dst, Register src, uint32_t shift, Register tmp) { if (UseZbb) { // no roliw available roriw(dst, src, 32 - shift); @@ -2901,16 +2946,6 @@ void MacroAssembler::rolw_imm(Register dst, Register src, uint32_t shift, Regist orr(dst, dst, tmp); } -void MacroAssembler::andi(Register Rd, Register Rn, int64_t imm, Register tmp) { - if (is_simm12(imm)) { - and_imm12(Rd, Rn, imm); - } else { - assert_different_registers(Rn, tmp); - mv(tmp, imm); - andr(Rd, Rn, tmp); - } -} - void MacroAssembler::orptr(Address adr, RegisterOrConstant src, Register tmp1, Register tmp2) { ld(tmp1, adr); if (src.is_register()) { @@ -4077,12 +4112,10 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, Label* L_failure, Label* L_slow_path, Register super_check_offset) { - assert_different_registers(sub_klass, super_klass, tmp_reg); - bool must_load_sco = (super_check_offset == noreg); + assert_different_registers(sub_klass, super_klass, tmp_reg, super_check_offset); + bool must_load_sco = !super_check_offset->is_valid(); if (must_load_sco) { assert(tmp_reg != noreg, "supply either a temp or a register offset"); - } else { - assert_different_registers(sub_klass, super_klass, super_check_offset); } Label L_fallthrough; @@ -4118,6 +4151,7 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, add(t0, sub_klass, super_check_offset); Address super_check_addr(t0); ld(t0, super_check_addr); // load displayed supertype + beq(super_klass, t0, *L_success); // This check has worked decisively for primary supers. // Secondary supers are sought in the super_cache ('super_cache_addr'). @@ -4130,7 +4164,6 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, // So if it was a primary super, we can just fail immediately. // Otherwise, it's the slow path for us (no success at this point). - beq(super_klass, t0, *L_success); mv(t1, sc_offset); if (L_failure == &L_fallthrough) { beq(super_check_offset, t1, *L_slow_path); @@ -4153,18 +4186,19 @@ void MacroAssembler::repne_scan(Register addr, Register value, Register count, bind(Lloop); ld(tmp, addr); beq(value, tmp, Lexit); - add(addr, addr, wordSize); - sub(count, count, 1); + addi(addr, addr, wordSize); + subi(count, count, 1); bnez(count, Lloop); bind(Lexit); } -void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, - Register super_klass, - Register tmp1_reg, - Register tmp2_reg, - Label* L_success, - Label* L_failure) { +void MacroAssembler::check_klass_subtype_slow_path_linear(Register sub_klass, + Register super_klass, + Register tmp1_reg, + Register tmp2_reg, + Label* L_success, + Label* L_failure, + bool set_cond_codes) { assert_different_registers(sub_klass, super_klass, tmp1_reg); if (tmp2_reg != noreg) { assert_different_registers(sub_klass, super_klass, tmp1_reg, tmp2_reg, t0); @@ -4222,7 +4256,7 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, // Load the array length. lwu(x12, Address(x15, Array::length_offset_in_bytes())); // Skip to start of data. - add(x15, x15, Array::base_offset_in_bytes()); + addi(x15, x15, Array::base_offset_in_bytes()); // Set t0 to an obvious invalid value, falling through by default mv(t0, -1); @@ -4238,7 +4272,9 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, bne(t1, t0, *L_failure); // Success. Cache the super we found an proceed in triumph. - sd(super_klass, super_cache_addr); + if (UseSecondarySupersCache) { + sd(super_klass, super_cache_addr); + } if (L_success != &L_fallthrough) { j(*L_success); @@ -4271,7 +4307,7 @@ void MacroAssembler::population_count(Register dst, Register src, { bind(loop); addi(dst, dst, 1); - addi(tmp2, tmp1, -1); + subi(tmp2, tmp1, 1); andr(tmp1, tmp1, tmp2); bnez(tmp1, loop); } @@ -4279,6 +4315,103 @@ void MacroAssembler::population_count(Register dst, Register src, } } +// If Register r is invalid, remove a new register from +// available_regs, and add new register to regs_to_push. +Register MacroAssembler::allocate_if_noreg(Register r, + RegSetIterator &available_regs, + RegSet ®s_to_push) { + if (!r->is_valid()) { + r = *available_regs++; + regs_to_push += r; + } + return r; +} + +// check_klass_subtype_slow_path_table() looks for super_klass in the +// hash table belonging to super_klass, branching to L_success or +// L_failure as appropriate. This is essentially a shim which +// allocates registers as necessary then calls +// lookup_secondary_supers_table() to do the work. Any of the tmp +// regs may be noreg, in which case this logic will chooses some +// registers push and pop them from the stack. +void MacroAssembler::check_klass_subtype_slow_path_table(Register sub_klass, + Register super_klass, + Register tmp1_reg, + Register tmp2_reg, + Label* L_success, + Label* L_failure, + bool set_cond_codes) { + RegSet tmps = RegSet::of(tmp1_reg, tmp2_reg); + + assert_different_registers(sub_klass, super_klass, tmp1_reg, tmp2_reg); + + Label L_fallthrough; + int label_nulls = 0; + if (L_success == nullptr) { L_success = &L_fallthrough; label_nulls++; } + if (L_failure == nullptr) { L_failure = &L_fallthrough; label_nulls++; } + assert(label_nulls <= 1, "at most one null in the batch"); + + BLOCK_COMMENT("check_klass_subtype_slow_path"); + + RegSet caller_save_regs = RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31); + RegSetIterator available_regs = (caller_save_regs - tmps - sub_klass - super_klass).begin(); + + RegSet pushed_regs; + + tmp1_reg = allocate_if_noreg(tmp1_reg, available_regs, pushed_regs); + tmp2_reg = allocate_if_noreg(tmp2_reg, available_regs, pushed_regs); + + Register tmp3_reg = noreg, tmp4_reg = noreg, result_reg = noreg; + + tmp3_reg = allocate_if_noreg(tmp3_reg, available_regs, pushed_regs); + tmp4_reg = allocate_if_noreg(tmp4_reg, available_regs, pushed_regs); + result_reg = allocate_if_noreg(result_reg, available_regs, pushed_regs); + + push_reg(pushed_regs, sp); + + lookup_secondary_supers_table_var(sub_klass, + super_klass, + result_reg, + tmp1_reg, tmp2_reg, tmp3_reg, + tmp4_reg, nullptr); + + // Move the result to t1 as we are about to unspill the tmp registers. + mv(t1, result_reg); + + // Unspill the tmp. registers: + pop_reg(pushed_regs, sp); + + // NB! Callers may assume that, when set_cond_codes is true, this + // code sets tmp2_reg to a nonzero value. + if (set_cond_codes) { + mv(tmp2_reg, 1); + } + + bnez(t1, *L_failure); + + if (L_success != &L_fallthrough) { + j(*L_success); + } + + bind(L_fallthrough); +} + +void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, + Register super_klass, + Register tmp1_reg, + Register tmp2_reg, + Label* L_success, + Label* L_failure, + bool set_cond_codes) { + if (UseSecondarySupersTable) { + check_klass_subtype_slow_path_table + (sub_klass, super_klass, tmp1_reg, tmp2_reg, L_success, L_failure, set_cond_codes); + } else { + check_klass_subtype_slow_path_linear + (sub_klass, super_klass, tmp1_reg, tmp2_reg, L_success, L_failure, set_cond_codes); + } +} + // Ensure that the inline code and the stub are using the same registers // as we need to call the stub from inline code when there is a collision // in the hashed lookup in the secondary supers array. @@ -4294,17 +4427,16 @@ do { (r_bitmap == x16 || r_bitmap == noreg), "registers must match riscv.ad"); \ } while(0) -// Return true: we succeeded in generating this code -bool MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, - Register r_super_klass, - Register result, - Register tmp1, - Register tmp2, - Register tmp3, - Register tmp4, - u1 super_klass_slot, - bool stub_is_near) { - assert_different_registers(r_sub_klass, r_super_klass, result, tmp1, tmp2, tmp3, tmp4, t0); +bool MacroAssembler::lookup_secondary_supers_table_const(Register r_sub_klass, + Register r_super_klass, + Register result, + Register tmp1, + Register tmp2, + Register tmp3, + Register tmp4, + u1 super_klass_slot, + bool stub_is_near) { + assert_different_registers(r_sub_klass, r_super_klass, result, tmp1, tmp2, tmp3, tmp4, t0, t1); Label L_fallthrough; @@ -4359,7 +4491,7 @@ bool MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, // Linear probe. if (bit != 0) { - ror_imm(r_bitmap, r_bitmap, bit); + ror(r_bitmap, r_bitmap, bit); } // The slot we just inspected is at secondary_supers[r_array_index - 1]. @@ -4379,6 +4511,98 @@ bool MacroAssembler::lookup_secondary_supers_table(Register r_sub_klass, return true; } +// At runtime, return 0 in result if r_super_klass is a superclass of +// r_sub_klass, otherwise return nonzero. Use this version of +// lookup_secondary_supers_table() if you don't know ahead of time +// which superclass will be searched for. Used by interpreter and +// runtime stubs. It is larger and has somewhat greater latency than +// the version above, which takes a constant super_klass_slot. +void MacroAssembler::lookup_secondary_supers_table_var(Register r_sub_klass, + Register r_super_klass, + Register result, + Register tmp1, + Register tmp2, + Register tmp3, + Register tmp4, + Label *L_success) { + assert_different_registers(r_sub_klass, r_super_klass, result, tmp1, tmp2, tmp3, tmp4, t0, t1); + + Label L_fallthrough; + + BLOCK_COMMENT("lookup_secondary_supers_table {"); + + const Register + r_array_index = tmp3, + r_bitmap = tmp4, + slot = t1; + + lbu(slot, Address(r_super_klass, Klass::hash_slot_offset())); + + // Make sure that result is nonzero if the test below misses. + mv(result, 1); + + ld(r_bitmap, Address(r_sub_klass, Klass::secondary_supers_bitmap_offset())); + + // First check the bitmap to see if super_klass might be present. If + // the bit is zero, we are certain that super_klass is not one of + // the secondary supers. + + // This next instruction is equivalent to: + // mv(tmp_reg, (u1)(Klass::SECONDARY_SUPERS_TABLE_SIZE - 1)); + // sub(r_array_index, slot, tmp_reg); + xori(r_array_index, slot, (u1)(Klass::SECONDARY_SUPERS_TABLE_SIZE - 1)); + sll(r_array_index, r_bitmap, r_array_index); + test_bit(t0, r_array_index, Klass::SECONDARY_SUPERS_TABLE_SIZE - 1); + beqz(t0, L_fallthrough); + + // Get the first array index that can contain super_klass into r_array_index. + population_count(r_array_index, r_array_index, tmp1, tmp2); + + // NB! r_array_index is off by 1. It is compensated by keeping r_array_base off by 1 word. + + const Register + r_array_base = tmp1, + r_array_length = tmp2; + + // The value i in r_array_index is >= 1, so even though r_array_base + // points to the length, we don't need to adjust it to point to the data. + assert(Array::base_offset_in_bytes() == wordSize, "Adjust this code"); + assert(Array::length_offset_in_bytes() == 0, "Adjust this code"); + + // We will consult the secondary-super array. + ld(r_array_base, Address(r_sub_klass, in_bytes(Klass::secondary_supers_offset()))); + + shadd(result, r_array_index, r_array_base, result, LogBytesPerWord); + ld(result, Address(result)); + xorr(result, result, r_super_klass); + beqz(result, L_success ? *L_success : L_fallthrough); // Found a match + + // Is there another entry to check? Consult the bitmap. + ror(r_bitmap, r_bitmap, slot); + test_bit(t0, r_bitmap, 1); + beqz(t0, L_fallthrough); + + // The slot we just inspected is at secondary_supers[r_array_index - 1]. + // The next slot to be inspected, by the logic we're about to call, + // is secondary_supers[r_array_index]. Bits 0 and 1 in the bitmap + // have been checked. + lookup_secondary_supers_table_slow_path(r_super_klass, r_array_base, r_array_index, + r_bitmap, result, r_array_length, false /*is_stub*/); + + BLOCK_COMMENT("} lookup_secondary_supers_table"); + + bind(L_fallthrough); + + if (VerifySecondarySupers) { + verify_secondary_supers_table(r_sub_klass, r_super_klass, + result, tmp1, tmp2, tmp3); + } + + if (L_success) { + beqz(result, *L_success); + } +} + // Called by code generated by check_klass_subtype_slow_path // above. This is called when there is a collision in the hashed // lookup in the secondary supers array. @@ -4387,15 +4611,18 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl Register r_array_index, Register r_bitmap, Register result, - Register tmp1) { - assert_different_registers(r_super_klass, r_array_base, r_array_index, r_bitmap, tmp1, result, t0); + Register tmp, + bool is_stub) { + assert_different_registers(r_super_klass, r_array_base, r_array_index, r_bitmap, tmp, result, t0); const Register - r_array_length = tmp1, + r_array_length = tmp, r_sub_klass = noreg; // unused - LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS(r_super_klass, r_array_base, r_array_length, - r_array_index, r_sub_klass, result, r_bitmap); + if (is_stub) { + LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS(r_super_klass, r_array_base, r_array_length, + r_array_index, r_sub_klass, result, r_bitmap); + } Label L_matched, L_fallthrough, L_bitmap_full; @@ -4422,8 +4649,10 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl { // This is conventional linear probing, but instead of terminating // when a null entry is found in the table, we maintain a bitmap // in which a 0 indicates missing entries. - // The check above guarantees there are 0s in the bitmap, so the loop - // eventually terminates. + // As long as the bitmap is not completely full, + // array_length == popcount(bitmap). The array_length check above + // guarantees there are 0s in the bitmap, so the loop eventually + // terminates. Label L_loop; bind(L_loop); @@ -4440,7 +4669,7 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl test_bit(t0, r_bitmap, 2); // look-ahead check (Bit 2); result is non-zero beqz(t0, L_fallthrough); - ror_imm(r_bitmap, r_bitmap, 1); + ror(r_bitmap, r_bitmap, 1); addi(r_array_index, r_array_index, 1); j(L_loop); } @@ -4475,9 +4704,6 @@ void MacroAssembler::verify_secondary_supers_table(Register r_sub_klass, r_array_index = noreg, // unused r_bitmap = noreg; // unused - LOOKUP_SECONDARY_SUPERS_TABLE_REGISTERS(r_super_klass, r_array_base, r_array_length, - r_array_index, r_sub_klass, result, r_bitmap); - BLOCK_COMMENT("verify_secondary_supers_table {"); // We will consult the secondary-super array. @@ -4914,11 +5140,11 @@ void MacroAssembler::mul_add(Register out, Register in, Register offset, blt(len, tmp, L_tail_loop); bind(L_unroll); for (int i = 0; i < unroll; i++) { - sub(in, in, BytesPerInt); + subi(in, in, BytesPerInt); lwu(t0, Address(in, 0)); mul(t1, t0, k); add(t0, t1, out); - sub(offset, offset, BytesPerInt); + subi(offset, offset, BytesPerInt); lwu(t1, Address(offset, 0)); add(t0, t0, t1); sw(t0, Address(offset, 0)); @@ -4929,16 +5155,16 @@ void MacroAssembler::mul_add(Register out, Register in, Register offset, bind(L_tail_loop); blez(len, L_end); - sub(in, in, BytesPerInt); + subi(in, in, BytesPerInt); lwu(t0, Address(in, 0)); mul(t1, t0, k); add(t0, t1, out); - sub(offset, offset, BytesPerInt); + subi(offset, offset, BytesPerInt); lwu(t1, Address(offset, 0)); add(t0, t0, t1); sw(t0, Address(offset, 0)); srli(out, t0, 32); - subw(len, len, 1); + subiw(len, len, 1); j(L_tail_loop); bind(L_end); @@ -5015,13 +5241,13 @@ void MacroAssembler::multiply_32_x_32_loop(Register x, Register xstart, Register lwu(x_xstart, Address(t0, 0)); bind(L_first_loop); - subw(idx, idx, 1); + subiw(idx, idx, 1); shadd(t0, idx, y, t0, LogBytesPerInt); lwu(y_idx, Address(t0, 0)); mul(product, x_xstart, y_idx); add(product, product, carry); srli(carry, product, 32); - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); shadd(t0, kdx, z, t0, LogBytesPerInt); sw(product, Address(t0, 0)); bgtz(idx, L_first_loop); @@ -5049,22 +5275,22 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register Label L_first_loop, L_first_loop_exit; Label L_one_x, L_one_y, L_multiply; - subw(xstart, xstart, 1); + subiw(xstart, xstart, 1); bltz(xstart, L_one_x); shadd(t0, xstart, x, t0, LogBytesPerInt); ld(x_xstart, Address(t0, 0)); - ror_imm(x_xstart, x_xstart, 32); // convert big-endian to little-endian + ror(x_xstart, x_xstart, 32); // convert big-endian to little-endian bind(L_first_loop); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_first_loop_exit); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_one_y); shadd(t0, idx, y, t0, LogBytesPerInt); ld(y_idx, Address(t0, 0)); - ror_imm(y_idx, y_idx, 32); // convert big-endian to little-endian + ror(y_idx, y_idx, 32); // convert big-endian to little-endian bind(L_multiply); mulhu(t0, x_xstart, y_idx); @@ -5072,8 +5298,8 @@ void MacroAssembler::multiply_64_x_64_loop(Register x, Register xstart, Register cad(product, product, carry, t1); adc(carry, t0, zr, t1); - subw(kdx, kdx, 2); - ror_imm(product, product, 32); // back to big-endian + subiw(kdx, kdx, 2); + ror(product, product, 32); // back to big-endian shadd(t0, kdx, z, t0, LogBytesPerInt); sd(product, Address(t0, 0)); @@ -5134,8 +5360,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, shadd(tmp6, idx, z, t0, LogBytesPerInt); - ror_imm(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian - ror_imm(yz_idx2, yz_idx2, 32); + ror(yz_idx1, yz_idx1, 32); // convert big-endian to little-endian + ror(yz_idx2, yz_idx2, 32); ld(t1, Address(tmp6, 0)); ld(t0, Address(tmp6, wordSize)); @@ -5143,8 +5369,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 mulhu(tmp4, product_hi, yz_idx1); - ror_imm(t0, t0, 32, tmp); // convert big-endian to little-endian - ror_imm(t1, t1, 32, tmp); + ror(t0, t0, 32, tmp); // convert big-endian to little-endian + ror(t1, t1, 32, tmp); mul(tmp, product_hi, yz_idx2); // yz_idx2 * product_hi -> carry2:tmp mulhu(carry2, product_hi, yz_idx2); @@ -5157,8 +5383,8 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, cad(tmp4, tmp4, t1, carry2); adc(carry, carry, zr, carry2); - ror_imm(tmp3, tmp3, 32); // convert little-endian to big-endian - ror_imm(tmp4, tmp4, 32); + ror(tmp3, tmp3, 32); // convert little-endian to big-endian + ror(tmp4, tmp4, 32); sd(tmp4, Address(tmp6, 0)); sd(tmp3, Address(tmp6, wordSize)); @@ -5170,29 +5396,29 @@ void MacroAssembler::multiply_128_x_128_loop(Register y, Register z, beqz(idx, L_post_third_loop_done); Label L_check_1; - subw(idx, idx, 2); + subiw(idx, idx, 2); bltz(idx, L_check_1); shadd(t0, idx, y, t0, LogBytesPerInt); ld(yz_idx1, Address(t0, 0)); - ror_imm(yz_idx1, yz_idx1, 32); + ror(yz_idx1, yz_idx1, 32); mul(tmp3, product_hi, yz_idx1); // yz_idx1 * product_hi -> tmp4:tmp3 mulhu(tmp4, product_hi, yz_idx1); shadd(t0, idx, z, t0, LogBytesPerInt); ld(yz_idx2, Address(t0, 0)); - ror_imm(yz_idx2, yz_idx2, 32, tmp); + ror(yz_idx2, yz_idx2, 32, tmp); add2_with_carry(carry, tmp4, tmp3, carry, yz_idx2, tmp); - ror_imm(tmp3, tmp3, 32, tmp); + ror(tmp3, tmp3, 32, tmp); sd(tmp3, Address(t0, 0)); bind(L_check_1); andi(idx, idx, 0x1); - subw(idx, idx, 1); + subiw(idx, idx, 1); bltz(idx, L_post_third_loop_done); shadd(t0, idx, y, t0, LogBytesPerInt); lwu(tmp4, Address(t0, 0)); @@ -5252,40 +5478,49 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi Label L_multiply_64_x_64_loop, L_done; - subw(xstart, xlen, 1); + subiw(xstart, xlen, 1); bltz(xstart, L_done); const Register jdx = tmp1; if (AvoidUnalignedAccesses) { - // Check if x and y are both 8-byte aligned. - orr(t0, xlen, ylen); - test_bit(t0, t0, 0); - beqz(t0, L_multiply_64_x_64_loop); + int base_offset = arrayOopDesc::base_offset_in_bytes(T_INT); + assert((base_offset % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + + if ((base_offset % 8) == 0) { + // multiply_64_x_64_loop emits 8-byte load/store to access two elements + // at a time from int arrays x and y. When base_offset is 8 bytes, these + // accesses are naturally aligned if both xlen and ylen are even numbers. + orr(t0, xlen, ylen); + test_bit(t0, t0, 0); + beqz(t0, L_multiply_64_x_64_loop); + } + + Label L_second_loop_unaligned, L_third_loop, L_third_loop_exit; multiply_32_x_32_loop(x, xstart, x_xstart, y, y_idx, z, carry, product, idx, kdx); shadd(t0, xstart, z, t0, LogBytesPerInt); sw(carry, Address(t0, 0)); - Label L_second_loop_unaligned; bind(L_second_loop_unaligned); mv(carry, zr); mv(jdx, ylen); - subw(xstart, xstart, 1); + subiw(xstart, xstart, 1); bltz(xstart, L_done); - sub(sp, sp, 2 * wordSize); + + subi(sp, sp, 2 * wordSize); sd(z, Address(sp, 0)); sd(zr, Address(sp, wordSize)); shadd(t0, xstart, z, t0, LogBytesPerInt); addi(z, t0, 4); shadd(t0, xstart, x, t0, LogBytesPerInt); lwu(product, Address(t0, 0)); - Label L_third_loop, L_third_loop_exit; blez(jdx, L_third_loop_exit); bind(L_third_loop); - subw(jdx, jdx, 1); + subiw(jdx, jdx, 1); shadd(t0, jdx, y, t0, LogBytesPerInt); lwu(t0, Address(t0, 0)); mul(t1, t0, product); @@ -5313,13 +5548,13 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi beqz(kdx, L_second_loop_aligned); Label L_carry; - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); beqz(kdx, L_carry); shadd(t0, kdx, z, t0, LogBytesPerInt); sw(carry, Address(t0, 0)); srli(carry, carry, 32); - subw(kdx, kdx, 1); + subiw(kdx, kdx, 1); bind(L_carry); shadd(t0, kdx, z, t0, LogBytesPerInt); @@ -5344,21 +5579,21 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi mv(carry, zr); // carry = 0; mv(jdx, ylen); // j = ystart+1 - subw(xstart, xstart, 1); // i = xstart-1; + subiw(xstart, xstart, 1); // i = xstart-1; bltz(xstart, L_done); - sub(sp, sp, 4 * wordSize); + subi(sp, sp, 4 * wordSize); sd(z, Address(sp, 0)); Label L_last_x; shadd(t0, xstart, z, t0, LogBytesPerInt); addi(z, t0, 4); - subw(xstart, xstart, 1); // i = xstart-1; + subiw(xstart, xstart, 1); // i = xstart-1; bltz(xstart, L_last_x); shadd(t0, xstart, x, t0, LogBytesPerInt); ld(product_hi, Address(t0, 0)); - ror_imm(product_hi, product_hi, 32); // convert big-endian to little-endian + ror(product_hi, product_hi, 32); // convert big-endian to little-endian Label L_third_loop_prologue; bind(L_third_loop_prologue); @@ -5378,7 +5613,7 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi shadd(t0, tmp3, z, t0, LogBytesPerInt); sw(carry, Address(t0, 0)); - subw(tmp3, tmp3, 1); + subiw(tmp3, tmp3, 1); bltz(tmp3, L_done); srli(carry, carry, 32); @@ -5395,28 +5630,26 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, Register y, Regi } #endif -// Count bits of trailing zero chars from lsb to msb until first non-zero element. -// For LL case, one byte for one element, so shift 8 bits once, and for other case, -// shift 16 bits once. -void MacroAssembler::ctzc_bit(Register Rd, Register Rs, bool isLL, Register tmp1, Register tmp2) { +// Count bits of trailing zero chars from lsb to msb until first non-zero +// char seen. For the LL case, shift 8 bits once as there is only one byte +// per each char. For other cases, shift 16 bits once. +void MacroAssembler::ctzc_bits(Register Rd, Register Rs, bool isLL, + Register tmp1, Register tmp2) { + int step = isLL ? 8 : 16; if (UseZbb) { - assert_different_registers(Rd, Rs, tmp1); - int step = isLL ? 8 : 16; ctz(Rd, Rs); - andi(tmp1, Rd, step - 1); - sub(Rd, Rd, tmp1); + andi(Rd, Rd, -step); return; } - assert_different_registers(Rd, Rs, tmp1, tmp2); + assert_different_registers(Rd, tmp1, tmp2); Label Loop; - int step = isLL ? 8 : 16; - mv(Rd, -step); mv(tmp2, Rs); + mv(Rd, -step); bind(Loop); addi(Rd, Rd, step); - andi(tmp1, tmp2, ((1 << step) - 1)); + zext(tmp1, tmp2, step); srli(tmp2, tmp2, step); beqz(tmp1, Loop); } @@ -5538,13 +5771,13 @@ void MacroAssembler::zero_words(Register base, uint64_t cnt) { Register loop_base = t1; cnt = cnt - remainder; mv(cnt_reg, cnt); - add(loop_base, base, remainder * wordSize); + addi(loop_base, base, remainder * wordSize); bind(loop); sub(cnt_reg, cnt_reg, unroll); for (int i = 0; i < unroll; i++) { sd(zr, Address(loop_base, i * wordSize)); } - add(loop_base, loop_base, unroll * wordSize); + addi(loop_base, loop_base, unroll * wordSize); bnez(cnt_reg, loop); } @@ -5595,12 +5828,12 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value) { jr(t1); bind(loop); - add(base, base, unroll * 8); + addi(base, base, unroll * wordSize); for (int i = -unroll; i < 0; i++) { sd(value, Address(base, i * 8)); } bind(entry); - sub(cnt, cnt, unroll); + subi(cnt, cnt, unroll); bgez(cnt, loop); bind(fini); @@ -5639,7 +5872,7 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm bind(loop); cbo_zero(base); sub(cnt, cnt, tmp1); - add(base, base, CacheLineSize); + addi(base, base, CacheLineSize); bge(cnt, tmp1, loop); } @@ -5701,7 +5934,7 @@ void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register t fclass_##FLOATSIG(tmp, src); \ mv(dst, zr); \ /* check if src is NaN */ \ - andi(tmp, tmp, fclass_mask::nan); \ + andi(tmp, tmp, FClassBits::nan); \ bnez(tmp, done); \ FLOATCVT(dst, src); \ bind(done); \ @@ -5725,7 +5958,7 @@ void MacroAssembler::FLOATTYPE##_compare(Register result, FloatRegister Rs1, /* Rs1 > Rs2, install 1 */ \ bgtz(result, Ldone); \ feq_##FLOATSIG(result, Rs1, Rs2); \ - addi(result, result, -1); \ + subi(result, result, 1); \ /* Rs1 = Rs2, install 0 */ \ /* NaN or Rs1 < Rs2, install -1 */ \ bind(Ldone); \ @@ -5736,7 +5969,7 @@ void MacroAssembler::FLOATTYPE##_compare(Register result, FloatRegister Rs1, /* Rs1 < Rs2, install -1 */ \ bgtz(result, Ldone); \ feq_##FLOATSIG(result, Rs1, Rs2); \ - addi(result, result, -1); \ + subi(result, result, 1); \ /* Rs1 = Rs2, install 0 */ \ /* NaN or Rs1 > Rs2, install 1 */ \ bind(Ldone); \ @@ -6144,10 +6377,10 @@ void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) { } int64_t imm = (int64_t)(1UL << bit_pos); if (is_simm12(imm)) { - and_imm12(Rd, Rs, imm); + andi(Rd, Rs, imm); } else { srli(Rd, Rs, bit_pos); - and_imm12(Rd, Rd, 1); + andi(Rd, Rd, 1); } } @@ -6200,7 +6433,7 @@ void MacroAssembler::lightweight_lock(Register basic_lock, Register obj, Registe // After successful lock, push object on lock-stack. add(t, xthread, top); sd(obj, Address(t)); - addw(top, top, oopSize); + addiw(top, top, oopSize); sw(top, Address(xthread, JavaThread::lock_stack_top_offset())); } @@ -6232,7 +6465,7 @@ void MacroAssembler::lightweight_unlock(Register obj, Register tmp1, Register tm // Check if obj is top of lock-stack. lwu(top, Address(xthread, JavaThread::lock_stack_top_offset())); - subw(top, top, oopSize); + subiw(top, top, oopSize); add(t, xthread, top); ld(t, Address(t)); bne(obj, t, slow, /* is_far */ true); @@ -6272,7 +6505,7 @@ void MacroAssembler::lightweight_unlock(Register obj, Register tmp1, Register tm // Restore lock-stack and handle the unlock in runtime. DEBUG_ONLY(add(t, xthread, top);) DEBUG_ONLY(sd(obj, Address(t));) - addw(top, top, oopSize); + addiw(top, top, oopSize); sw(top, Address(xthread, JavaThread::lock_stack_top_offset())); j(slow); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 1f5a47bf65acb..41ccd0c4b2f74 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -60,14 +60,14 @@ class MacroAssembler: public Assembler { // Note that SP must be updated to the right place before saving/restoring RA and FP // because signal based thread suspend/resume could happen asynchronously. void enter() { - addi(sp, sp, - 2 * wordSize); + subi(sp, sp, 2 * wordSize); sd(ra, Address(sp, wordSize)); sd(fp, Address(sp)); addi(fp, sp, 2 * wordSize); } void leave() { - addi(sp, fp, - 2 * wordSize); + subi(sp, fp, 2 * wordSize); ld(fp, Address(sp)); ld(ra, Address(sp, wordSize)); addi(sp, sp, 2 * wordSize); @@ -323,21 +323,55 @@ class MacroAssembler: public Assembler { Register tmp1_reg, Register tmp2_reg, Label* L_success, - Label* L_failure); + Label* L_failure, + bool set_cond_codes = false); + + void check_klass_subtype_slow_path_linear(Register sub_klass, + Register super_klass, + Register tmp1_reg, + Register tmp2_reg, + Label* L_success, + Label* L_failure, + bool set_cond_codes = false); + + void check_klass_subtype_slow_path_table(Register sub_klass, + Register super_klass, + Register tmp1_reg, + Register tmp2_reg, + Label* L_success, + Label* L_failure, + bool set_cond_codes = false); + + // If r is valid, return r. + // If r is invalid, remove a register r2 from available_regs, add r2 + // to regs_to_push, then return r2. + Register allocate_if_noreg(const Register r, + RegSetIterator &available_regs, + RegSet ®s_to_push); + + // Secondary subtype checking + void lookup_secondary_supers_table_var(Register sub_klass, + Register r_super_klass, + Register result, + Register tmp1, + Register tmp2, + Register tmp3, + Register tmp4, + Label *L_success); void population_count(Register dst, Register src, Register tmp1, Register tmp2); // As above, but with a constant super_klass. // The result is in Register result, not the condition codes. - bool lookup_secondary_supers_table(Register r_sub_klass, - Register r_super_klass, - Register result, - Register tmp1, - Register tmp2, - Register tmp3, - Register tmp4, - u1 super_klass_slot, - bool stub_is_near = false); + bool lookup_secondary_supers_table_const(Register r_sub_klass, + Register r_super_klass, + Register result, + Register tmp1, + Register tmp2, + Register tmp3, + Register tmp4, + u1 super_klass_slot, + bool stub_is_near = false); void verify_secondary_supers_table(Register r_sub_klass, Register r_super_klass, @@ -351,7 +385,8 @@ class MacroAssembler: public Assembler { Register r_array_index, Register r_bitmap, Register result, - Register tmp1); + Register tmp, + bool is_stub = true); void check_klass_subtype(Register sub_klass, Register super_klass, @@ -591,9 +626,6 @@ class MacroAssembler: public Assembler { } // Control and status pseudo instructions - void rdinstret(Register Rd); // read instruction-retired counter - void rdcycle(Register Rd); // read cycle counter - void rdtime(Register Rd); // read time void csrr(Register Rd, unsigned csr); // read csr void csrw(unsigned csr, Register Rs); // write csr void csrs(unsigned csr, Register Rs); // set bits in csr @@ -601,19 +633,23 @@ class MacroAssembler: public Assembler { void csrwi(unsigned csr, unsigned imm); void csrsi(unsigned csr, unsigned imm); void csrci(unsigned csr, unsigned imm); - void frcsr(Register Rd); // read float-point csr - void fscsr(Register Rd, Register Rs); // swap float-point csr - void fscsr(Register Rs); // write float-point csr - void frrm(Register Rd); // read float-point rounding mode - void fsrm(Register Rd, Register Rs); // swap float-point rounding mode - void fsrm(Register Rs); // write float-point rounding mode + void frcsr(Register Rd) { csrr(Rd, CSR_FCSR); }; // read float-point csr + void fscsr(Register Rd, Register Rs); // swap float-point csr + void fscsr(Register Rs); // write float-point csr + void frrm(Register Rd) { csrr(Rd, CSR_FRM); }; // read float-point rounding mode + void fsrm(Register Rd, Register Rs); // swap float-point rounding mode + void fsrm(Register Rs); // write float-point rounding mode void fsrmi(Register Rd, unsigned imm); void fsrmi(unsigned imm); - void frflags(Register Rd); // read float-point exception flags - void fsflags(Register Rd, Register Rs); // swap float-point exception flags - void fsflags(Register Rs); // write float-point exception flags + void frflags(Register Rd) { csrr(Rd, CSR_FFLAGS); }; // read float-point exception flags + void fsflags(Register Rd, Register Rs); // swap float-point exception flags + void fsflags(Register Rs); // write float-point exception flags void fsflagsi(Register Rd, unsigned imm); void fsflagsi(unsigned imm); + // Requires Zicntr + void rdinstret(Register Rd) { csrr(Rd, CSR_INSTRET); }; // read instruction-retired counter + void rdcycle(Register Rd) { csrr(Rd, CSR_CYCLE); }; // read cycle counter + void rdtime(Register Rd) { csrr(Rd, CSR_TIME); }; // read time // Restore cpu control state after JNI call void restore_cpu_control_state_after_jni(Register tmp); @@ -884,12 +920,27 @@ class MacroAssembler: public Assembler { void movptr1(Register Rd, uintptr_t addr, int32_t &offset); void movptr2(Register Rd, uintptr_t addr, int32_t &offset, Register tmp); public: + // float imm move + static bool can_fp_imm_load(float imm); + static bool can_dp_imm_load(double imm); + void fli_s(FloatRegister Rd, float imm); + void fli_d(FloatRegister Rd, double imm); // arith - void add (Register Rd, Register Rn, int64_t increment, Register temp = t0); - void addw(Register Rd, Register Rn, int32_t increment, Register temp = t0); - void sub (Register Rd, Register Rn, int64_t decrement, Register temp = t0); - void subw(Register Rd, Register Rn, int32_t decrement, Register temp = t0); + void add (Register Rd, Register Rn, int64_t increment, Register tmp = t0); + void sub (Register Rd, Register Rn, int64_t decrement, Register tmp = t0); + void addw(Register Rd, Register Rn, int64_t increment, Register tmp = t0); + void subw(Register Rd, Register Rn, int64_t decrement, Register tmp = t0); + + void subi(Register Rd, Register Rn, int64_t decrement) { + assert(is_simm12(-decrement), "Must be"); + addi(Rd, Rn, -decrement); + } + + void subiw(Register Rd, Register Rn, int64_t decrement) { + assert(is_simm12(-decrement), "Must be"); + addiw(Rd, Rn, -decrement); + } #define INSN(NAME) \ inline void NAME(Register Rd, Register Rs1, Register Rs2) { \ @@ -916,9 +967,10 @@ class MacroAssembler: public Assembler { void revbw(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2= t1); // reverse bytes in lower word, sign-extend void revb(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in doubleword - void ror_imm(Register dst, Register src, uint32_t shift, Register tmp = t0); - void rolw_imm(Register dst, Register src, uint32_t, Register tmp = t0); - void andi(Register Rd, Register Rn, int64_t imm, Register tmp = t0); + void ror(Register dst, Register src, Register shift, Register tmp = t0); + void ror(Register dst, Register src, uint32_t shift, Register tmp = t0); + void rolw(Register dst, Register src, uint32_t shift, Register tmp = t0); + void orptr(Address adr, RegisterOrConstant src, Register tmp1 = t0, Register tmp2 = t1); // Load and Store Instructions @@ -1362,7 +1414,8 @@ class MacroAssembler: public Assembler { void inflate_lo32(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); void inflate_hi32(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); - void ctzc_bit(Register Rd, Register Rs, bool isLL = false, Register tmp1 = t0, Register tmp2 = t1); + void ctzc_bits(Register Rd, Register Rs, bool isLL = false, + Register tmp1 = t0, Register tmp2 = t1); void zero_words(Register base, uint64_t cnt); address zero_words(Register ptr, Register cnt); diff --git a/src/hotspot/cpu/riscv/methodHandles_riscv.cpp b/src/hotspot/cpu/riscv/methodHandles_riscv.cpp index 8ed4b93ad4de9..39b6737631dc5 100644 --- a/src/hotspot/cpu/riscv/methodHandles_riscv.cpp +++ b/src/hotspot/cpu/riscv/methodHandles_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp index 48a9a84e481bf..6f20d54b222f2 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/compiledIC.hpp" #include "nativeInst_riscv.hpp" diff --git a/src/hotspot/cpu/riscv/registerMap_riscv.cpp b/src/hotspot/cpu/riscv/registerMap_riscv.cpp index e59fca777c1de..fa7b108c6ff12 100644 --- a/src/hotspot/cpu/riscv/registerMap_riscv.cpp +++ b/src/hotspot/cpu/riscv/registerMap_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/registerMap.hpp" #include "vmreg_riscv.inline.hpp" diff --git a/src/hotspot/cpu/riscv/register_riscv.cpp b/src/hotspot/cpu/riscv/register_riscv.cpp index 98aeafbfe9cbe..56a4483a989e6 100644 --- a/src/hotspot/cpu/riscv/register_riscv.cpp +++ b/src/hotspot/cpu/riscv/register_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "register_riscv.hpp" Register::RegisterImpl all_RegisterImpls [Register::number_of_registers + 1]; diff --git a/src/hotspot/cpu/riscv/relocInfo_riscv.cpp b/src/hotspot/cpu/riscv/relocInfo_riscv.cpp index 18b4302c7e68e..7bee372b0ef80 100644 --- a/src/hotspot/cpu/riscv/relocInfo_riscv.cpp +++ b/src/hotspot/cpu/riscv/relocInfo_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/relocInfo.hpp" #include "nativeInst_riscv.hpp" diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 7cb42a6b30c3c..b8660afb5fd4f 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1918,7 +1918,7 @@ bool Matcher::match_rule_supported(int opcode) { case Op_ConvHF2F: case Op_ConvF2HF: - return UseZfh; + return UseZfh || UseZfhmin; } return true; // Per default match rules are supported. @@ -2364,7 +2364,7 @@ encode %{ Label miss; Label done; __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, - nullptr, &miss); + nullptr, &miss, /*set_cond_codes*/ true); if ($primary) { __ mv(result_reg, zr); } else { @@ -4920,7 +4920,11 @@ instruct loadConF(fRegF dst, immF con) %{ %} ins_encode %{ - __ flw(as_FloatRegister($dst$$reg), $constantaddress($con)); + if (MacroAssembler::can_fp_imm_load($con$$constant)) { + __ fli_s(as_FloatRegister($dst$$reg), $con$$constant); + } else { + __ flw(as_FloatRegister($dst$$reg), $constantaddress($con)); + } %} ins_pipe(fp_load_constant_s); @@ -4950,7 +4954,11 @@ instruct loadConD(fRegD dst, immD con) %{ %} ins_encode %{ - __ fld(as_FloatRegister($dst$$reg), $constantaddress($con)); + if (MacroAssembler::can_dp_imm_load($con$$constant)) { + __ fli_d(as_FloatRegister($dst$$reg), $con$$constant); + } else { + __ fld(as_FloatRegister($dst$$reg), $constantaddress($con)); + } %} ins_pipe(fp_load_constant_d); @@ -6482,9 +6490,9 @@ instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ add(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ addi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6513,9 +6521,9 @@ instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ add(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ addi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6546,9 +6554,9 @@ instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{ ins_encode %{ // src2 is imm, so actually call the addiw - __ subw(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ subiw(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -6577,9 +6585,9 @@ instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{ ins_encode %{ // src2 is imm, so actually call the addi - __ sub(as_Register($dst$$reg), - as_Register($src1$$reg), - $src2$$constant); + __ subi(as_Register($dst$$reg), + as_Register($src1$$reg), + $src2$$constant); %} ins_pipe(ialu_reg_imm); @@ -7348,7 +7356,7 @@ instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src) format %{ "isInfinite $dst, $src" %} ins_encode %{ __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); - __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf); + __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf); __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); %} @@ -7363,7 +7371,7 @@ instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src) format %{ "isInfinite $dst, $src" %} ins_encode %{ __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); - __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf); + __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::inf); __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); %} @@ -7378,7 +7386,7 @@ instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src) format %{ "isFinite $dst, $src" %} ins_encode %{ __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); - __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite); + __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite); __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); %} @@ -7393,7 +7401,7 @@ instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src) format %{ "isFinite $dst, $src" %} ins_encode %{ __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); - __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite); + __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::FClassBits::finite); __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); %} @@ -10019,10 +10027,11 @@ instruct CallLeafNoFPDirect(method meth) instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, rFlagsReg cr) %{ + predicate(!UseSecondarySupersTable); match(Set result (PartialSubtypeCheck sub super)); effect(KILL tmp, KILL cr); - ins_cost(11 * DEFAULT_COST); + ins_cost(20 * DEFAULT_COST); format %{ "partialSubtypeCheck $result, $sub, $super\t#@partialSubtypeCheck" %} ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); @@ -10032,6 +10041,33 @@ instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, i ins_pipe(pipe_class_memory); %} +// Two versions of partialSubtypeCheck, both used when we need to +// search for a super class in the secondary supers array. The first +// is used when we don't know _a priori_ the class being searched +// for. The second, far more common, is used when we do know: this is +// used for instanceof, checkcast, and any case where C2 can determine +// it by constant propagation. + +instruct partialSubtypeCheckVarSuper(iRegP_R14 sub, iRegP_R10 super, iRegP_R15 result, + iRegP_R11 tmpR11, iRegP_R12 tmpR12, iRegP_R13 tmpR13, + iRegP_R16 tmpR16, rFlagsReg cr) +%{ + predicate(UseSecondarySupersTable); + match(Set result (PartialSubtypeCheck sub super)); + effect(TEMP tmpR11, TEMP tmpR12, TEMP tmpR13, TEMP tmpR16, KILL cr); + + ins_cost(10 * DEFAULT_COST); // slightly larger than the next version + format %{ "partialSubtypeCheck $result, $sub, $super" %} + + ins_encode %{ + __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $result$$Register, + $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register, + $tmpR16$$Register, nullptr /*L_success*/); + %} + + ins_pipe(pipe_class_memory); +%} + instruct partialSubtypeCheckConstSuper(iRegP_R14 sub, iRegP_R10 super_reg, immP super_con, iRegP_R15 result, iRegP_R11 tmpR11, iRegP_R12 tmpR12, iRegP_R13 tmpR13, iRegP_R16 tmpR16, rFlagsReg cr) %{ @@ -10039,16 +10075,16 @@ instruct partialSubtypeCheckConstSuper(iRegP_R14 sub, iRegP_R10 super_reg, immP match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); effect(TEMP tmpR11, TEMP tmpR12, TEMP tmpR13, TEMP tmpR16, KILL cr); - ins_cost(7 * DEFAULT_COST); // needs to be less than competing nodes + ins_cost(5 * DEFAULT_COST); // needs to be less than competing nodes format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} ins_encode %{ bool success = false; u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); if (InlineSecondarySupersTest) { - success = __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $result$$Register, - $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register, - $tmpR16$$Register, super_klass_slot); + success = __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $result$$Register, + $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register, + $tmpR16$$Register, super_klass_slot); } else { address call = __ reloc_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); success = (call != nullptr); @@ -10062,22 +10098,6 @@ instruct partialSubtypeCheckConstSuper(iRegP_R14 sub, iRegP_R10 super_reg, immP ins_pipe(pipe_class_memory); %} -instruct partialSubtypeCheckVsZero(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, - immP0 zero, rFlagsReg cr) -%{ - match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); - effect(KILL tmp, KILL result); - - ins_cost(11 * DEFAULT_COST); - format %{ "partialSubtypeCheck $result, $sub, $super == 0\t#@partialSubtypeCheckVsZero" %} - - ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); - - opcode(0x0); // Don't zero result reg on hit - - ins_pipe(pipe_class_memory); -%} - instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) %{ diff --git a/src/hotspot/cpu/riscv/riscv_b.ad b/src/hotspot/cpu/riscv/riscv_b.ad index 535c0fd534ddf..990d9eab87c7b 100644 --- a/src/hotspot/cpu/riscv/riscv_b.ad +++ b/src/hotspot/cpu/riscv/riscv_b.ad @@ -60,7 +60,7 @@ instruct rorI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ format %{ "rorw $dst, $src, $shift\t#@rorI_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rorw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rorrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -72,7 +72,7 @@ instruct rorL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ format %{ "ror $dst, $src, $shift\t#@rorL_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ ror(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rorr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -84,7 +84,7 @@ instruct rolI_reg_b(iRegINoSp dst, iRegI src, iRegI shift) %{ format %{ "rolw $dst, $src, $shift\t#@rolI_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rolw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rolrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} @@ -96,7 +96,7 @@ instruct rolL_reg_b(iRegLNoSp dst, iRegL src, iRegI shift) %{ format %{ "rol $dst, $src, $shift\t#@rolL_reg_b" %} ins_cost(ALU_COST); ins_encode %{ - __ rol(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); + __ rolr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); %} ins_pipe(ialu_reg_reg); %} diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 4b30a91115221..9892d2b9c0392 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -1,7 +1,8 @@ // -// Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 2020, 2023, Arm Limited. All rights reserved. // Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. +// Copyright (c) 2023, 2025, Rivos Inc. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -99,6 +100,12 @@ source %{ return false; } break; + case Op_MulReductionVI: + case Op_MulReductionVL: + // When vlen < 4, our log2(vlen) implementation does not help to gain performance improvement. + if (vlen < 4) { + return false; + } default: break; } @@ -109,6 +116,13 @@ source %{ if (!UseRVV) { return false; } + switch (opcode) { + case Op_SelectFromTwoVector: + // There is no masked version of selectFrom two vector, i.e. selectFrom(av, bv, mask) in vector API. + return false; + default: + break; + } return match_rule_supported_vector(opcode, vlen, bt); } @@ -2420,6 +2434,67 @@ instruct vreduce_minD_masked(fRegD dst, fRegD src1, vReg src2, vRegMask_V0 v0, v ins_pipe(pipe_slow); %} + +// ------------------------------ Vector reduction mul ------------------------- + +instruct reduce_mulI(iRegINoSp dst, iRegIorL2I isrc, vReg vsrc, + vReg tmp1, vReg tmp2) %{ + match(Set dst (MulReductionVI isrc vsrc)); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); + format %{ "reduce_mulI $dst, $isrc, $vsrc\t" %} + + ins_encode %{ + __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc)); + %} + ins_pipe(pipe_slow); +%} + +instruct reduce_mulI_masked(iRegINoSp dst, iRegIorL2I isrc, vReg vsrc, + vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{ + match(Set dst (MulReductionVI (Binary isrc vsrc) v0)); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); + format %{ "reduce_mulI_masked $dst, $isrc, $vsrc, $v0\t" %} + + ins_encode %{ + __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc), + Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct reduce_mulL(iRegLNoSp dst, iRegL isrc, vReg vsrc, + vReg tmp1, vReg tmp2) %{ + match(Set dst (MulReductionVL isrc vsrc)); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); + format %{ "reduce_mulL $dst, $isrc, $vsrc\t" %} + + ins_encode %{ + __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc)); + %} + ins_pipe(pipe_slow); +%} + +instruct reduce_mulL_masked(iRegLNoSp dst, iRegL isrc, vReg vsrc, + vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{ + match(Set dst (MulReductionVL (Binary isrc vsrc) v0)); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); + format %{ "reduce_mulL_masked $dst, $isrc, $vsrc, $v0\t" %} + + ins_encode %{ + __ reduce_mul_integral_v($dst$$Register, $isrc$$Register, as_VectorRegister($vsrc$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + Matcher::vector_element_basic_type(this, $vsrc), Matcher::vector_length(this, $vsrc), + Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // vector replicate instruct replicate(vReg dst, iRegIorL2I src) %{ @@ -4425,6 +4500,34 @@ instruct vmask_reinterpret_diff_esize(vRegMask dst, vRegMask_V0 src, vReg tmp) % ins_pipe(pipe_slow); %} +// ------------------------------ Vector selectFrom ----------------------------- + +instruct select_from_two_vectors(vReg dst, vReg src1, vReg src2, vReg index, vRegMask_V0 v0, vReg tmp) %{ + match(Set dst (SelectFromTwoVector (Binary index src1) src2)); + effect(TEMP_DEF dst, TEMP v0, TEMP tmp); + format %{ "select_from_two_vectors $dst, $src1, $src2, $index" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ vsetvli_helper(bt, Matcher::vector_length(this)); + __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), + as_VectorRegister($index$$reg)); + bool use_imm = __ is_simm5(Matcher::vector_length(this) - 1); + if (use_imm) { + __ vmsgtu_vi(v0, as_VectorRegister($index$$reg), Matcher::vector_length(this) - 1); + __ vadd_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($index$$reg), + -Matcher::vector_length(this), Assembler::v0_t); + } else { + __ mv(t0, Matcher::vector_length(this) - 1); + __ vmsgtu_vx(v0, as_VectorRegister($index$$reg), t0); + __ mv(t0, -Matcher::vector_length(this)); + __ vadd_vx(as_VectorRegister($tmp$$reg), as_VectorRegister($index$$reg), t0, Assembler::v0_t); + } + __ vrgather_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src2$$reg), + as_VectorRegister($tmp$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector rearrange ----------------------------- instruct rearrange(vReg dst, vReg src, vReg shuffle) %{ diff --git a/src/hotspot/cpu/riscv/runtime_riscv.cpp b/src/hotspot/cpu/riscv/runtime_riscv.cpp index 441bd1f241f28..a0879b68053d6 100644 --- a/src/hotspot/cpu/riscv/runtime_riscv.cpp +++ b/src/hotspot/cpu/riscv/runtime_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" @@ -73,7 +72,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { // Push self-frame. We get here with a return address in RA // and sp should be 16 byte aligned // push fp and retaddr by hand - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, wordSize)); __ sd(fp, Address(sp, 0)); // we don't expect an arg reg save area @@ -140,7 +139,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { __ lwu(x12, Address(x14, Deoptimization::UnrollBlock:: size_of_deoptimized_frame_offset())); - __ sub(x12, x12, 2 * wordSize); + __ subi(x12, x12, 2 * wordSize); __ add(sp, sp, x12); __ ld(fp, Address(sp, 0)); __ ld(ra, Address(sp, wordSize)); @@ -188,7 +187,7 @@ void OptoRuntime::generate_uncommon_trap_blob() { Label loop; __ bind(loop); __ ld(x11, Address(x15, 0)); // Load frame size - __ sub(x11, x11, 2 * wordSize); // We'll push pc and fp by hand + __ subi(x11, x11, 2 * wordSize); // We'll push pc and fp by hand __ ld(ra, Address(x12, 0)); // Save return address __ enter(); // and old fp & set new fp __ sub(sp, sp, x11); // Prolog @@ -196,9 +195,9 @@ void OptoRuntime::generate_uncommon_trap_blob() { // This value is corrected by layout_activation_impl __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); __ mv(sender_sp, sp); // Pass sender_sp to next frame - __ add(x15, x15, wordSize); // Bump array pointer (sizes) - __ add(x12, x12, wordSize); // Bump array pointer (pcs) - __ subw(x13, x13, 1); // Decrement counter + __ addi(x15, x15, wordSize); // Bump array pointer (sizes) + __ addi(x12, x12, wordSize); // Bump array pointer (pcs) + __ subiw(x13, x13, 1); // Decrement counter __ bgtz(x13, loop); __ ld(ra, Address(x12, 0)); // save final return address // Re-push self-frame @@ -292,7 +291,7 @@ void OptoRuntime::generate_exception_blob() { // push fp and retaddr by hand // Exception pc is 'return address' for stack walker - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, wordSize)); __ sd(fp, Address(sp)); // there are no callee save registers and we don't expect an @@ -346,7 +345,7 @@ void OptoRuntime::generate_exception_blob() { // and we dont' expect an arg reg save area __ ld(fp, Address(sp)); __ ld(x13, Address(sp, wordSize)); - __ addi(sp, sp , 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); // x10: exception handler @@ -378,5 +377,3 @@ void OptoRuntime::generate_exception_blob() { _exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1); } #endif // COMPILER2 - - diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 9af1b6a9bb128..49e630bbfdf91 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" @@ -641,7 +640,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ lwu(t0, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset())); __ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC)); __ beqz(t1, L_skip_barrier); // non-static } @@ -802,7 +801,7 @@ static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegP if (args[i].first()->is_Register()) { x = x + args[i].first()->as_Register(); } else if (args[i].first()->is_FloatRegister()) { - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(args[i].first()->as_FloatRegister(), Address(sp, 0)); } } @@ -824,7 +823,7 @@ static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMR ; } else if (args[i].first()->is_FloatRegister()) { __ fld(args[i].first()->as_FloatRegister(), Address(sp, 0)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } } } @@ -1715,7 +1714,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // NOTE: the oopMark is in swap_reg % 10 as the result of cmpxchg __ sub(swap_reg, swap_reg, sp); - __ andi(swap_reg, swap_reg, 3 - (int)os::vm_page_size()); + __ mv(t0, 3 - (int)os::vm_page_size()); + __ andr(swap_reg, swap_reg, t0); // Save the test result, for recursive case, the result is zero __ sd(swap_reg, Address(lock_reg, mark_word_offset)); @@ -2336,7 +2336,7 @@ void SharedRuntime::generate_deopt_blob() { // Pop deoptimized frame __ lwu(x12, Address(x15, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset())); - __ sub(x12, x12, 2 * wordSize); + __ subi(x12, x12, 2 * wordSize); __ add(sp, sp, x12); __ ld(fp, Address(sp, 0)); __ ld(ra, Address(sp, wordSize)); @@ -2379,7 +2379,7 @@ void SharedRuntime::generate_deopt_blob() { __ bind(loop); __ ld(x9, Address(x14, 0)); // Load frame size __ addi(x14, x14, wordSize); - __ sub(x9, x9, 2 * wordSize); // We'll push pc and fp by hand + __ subi(x9, x9, 2 * wordSize); // We'll push pc and fp by hand __ ld(ra, Address(x12, 0)); // Load pc __ addi(x12, x12, wordSize); __ enter(); // Save old & set new fp @@ -2388,7 +2388,7 @@ void SharedRuntime::generate_deopt_blob() { __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); __ sd(sender_sp, Address(fp, frame::interpreter_frame_sender_sp_offset * wordSize)); // Make it walkable __ mv(sender_sp, sp); // Pass sender_sp to next frame - __ addi(x13, x13, -1); // Decrement counter + __ subi(x13, x13, 1); // Decrement counter __ bnez(x13, loop); // Re-push self-frame @@ -2566,7 +2566,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal #endif // Adjust return pc forward to step over the safepoint poll instruction - __ add(x18, x18, NativeInstruction::instruction_size); + __ addi(x18, x18, NativeInstruction::instruction_size); __ sd(x18, Address(fp, frame::return_addr_offset * wordSize)); } @@ -2736,7 +2736,7 @@ RuntimeStub* SharedRuntime::generate_throw_exception(SharedStubId id, address ru assert(is_even(framesize / 2), "sp not 16-byte aligned"); // ra and fp are already in place - __ addi(sp, fp, 0 - ((unsigned)framesize << LogBytesPerInt)); // prolog + __ subi(sp, fp, (unsigned)framesize << LogBytesPerInt); // prolog int frame_complete = __ pc() - start; diff --git a/src/hotspot/cpu/riscv/stubDeclarations_riscv.hpp b/src/hotspot/cpu/riscv/stubDeclarations_riscv.hpp new file mode 100644 index 0000000000000..4905566c233a3 --- /dev/null +++ b/src/hotspot/cpu/riscv/stubDeclarations_riscv.hpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_RISCV_STUBDECLARATIONS_HPP +#define CPU_RISCV_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 10000) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 2000) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 45000) \ + do_stub(compiler, compare_long_string_LL) \ + do_arch_entry(riscv, compiler, compare_long_string_LL, \ + compare_long_string_LL, compare_long_string_LL) \ + do_stub(compiler, compare_long_string_UU) \ + do_arch_entry(riscv, compiler, compare_long_string_UU, \ + compare_long_string_UU, compare_long_string_UU) \ + do_stub(compiler, compare_long_string_LU) \ + do_arch_entry(riscv, compiler, compare_long_string_LU, \ + compare_long_string_LU, compare_long_string_LU) \ + do_stub(compiler, compare_long_string_UL) \ + do_arch_entry(riscv, compiler, compare_long_string_UL, \ + compare_long_string_UL, compare_long_string_UL) \ + do_stub(compiler, string_indexof_linear_ll) \ + do_arch_entry(riscv, compiler, string_indexof_linear_ll, \ + string_indexof_linear_ll, string_indexof_linear_ll) \ + do_stub(compiler, string_indexof_linear_uu) \ + do_arch_entry(riscv, compiler, string_indexof_linear_uu, \ + string_indexof_linear_uu, string_indexof_linear_uu) \ + do_stub(compiler, string_indexof_linear_ul) \ + do_arch_entry(riscv, compiler, string_indexof_linear_ul, \ + string_indexof_linear_ul, string_indexof_linear_ul) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 20000 ZGC_ONLY(+10000)) \ + do_stub(final, copy_byte_f) \ + do_arch_entry(riscv, final, copy_byte_f, copy_byte_f, \ + copy_byte_f) \ + do_stub(final, copy_byte_b) \ + do_arch_entry(riscv, final, copy_byte_b, copy_byte_b, \ + copy_byte_b) \ + do_stub(final, zero_blocks) \ + do_arch_entry(riscv, final, zero_blocks, zero_blocks, \ + zero_blocks) \ + + +#endif // CPU_RISCV_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 1afa3545afcf9..01ed7fcac9f87 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/oopMap.hpp" @@ -208,7 +207,8 @@ class StubGenerator: public StubCodeGenerator { (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, "adjust this code"); - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Address sp_after_call (fp, sp_after_call_off * wordSize); @@ -341,7 +341,7 @@ class StubGenerator: public StubCodeGenerator { address loop = __ pc(); __ ld(t0, Address(c_rarg5, 0)); __ addi(c_rarg5, c_rarg5, wordSize); - __ addi(c_rarg6, c_rarg6, -1); + __ subi(c_rarg6, c_rarg6, 1); __ push_reg(t0); __ bgtz(c_rarg6, loop); @@ -476,7 +476,8 @@ class StubGenerator: public StubCodeGenerator { // x10: exception oop address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // same as in generate_call_stub(): @@ -528,7 +529,8 @@ class StubGenerator: public StubCodeGenerator { // so it just needs to be generated code with no x86 prolog address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Upon entry, RA points to the return address returning into @@ -614,7 +616,8 @@ class StubGenerator: public StubCodeGenerator { // [tos + 5]: saved t0 address generate_verify_oop() { - StubCodeMark mark(this, "StubRoutines", "verify_oop"); + StubGenStubId stub_id = StubGenStubId::verify_oop_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label exit, error; @@ -623,7 +626,7 @@ class StubGenerator: public StubCodeGenerator { __ la(c_rarg2, ExternalAddress((address) StubRoutines::verify_oop_count_addr())); __ ld(c_rarg3, Address(c_rarg2)); - __ add(c_rarg3, c_rarg3, 1); + __ addi(c_rarg3, c_rarg3, 1); __ sd(c_rarg3, Address(c_rarg2)); // object is in x10 @@ -675,7 +678,8 @@ class StubGenerator: public StubCodeGenerator { const Register base = x28, cnt = x29, tmp1 = x30, tmp2 = x31; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "zero_blocks"); + StubGenStubId stub_id = StubGenStubId::zero_blocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); if (UseBlockZeroing) { @@ -698,8 +702,8 @@ class StubGenerator: public StubCodeGenerator { for (int i = 0; i < MacroAssembler::zero_words_block_size; i++) { __ sd(zr, Address(base, i * wordSize)); } - __ add(base, base, MacroAssembler::zero_words_block_size * wordSize); - __ sub(cnt, cnt, MacroAssembler::zero_words_block_size); + __ addi(base, base, MacroAssembler::zero_words_block_size * wordSize); + __ subi(cnt, cnt, MacroAssembler::zero_words_block_size); __ bge(cnt, tmp1, loop); __ bind(done); } @@ -727,8 +731,22 @@ class StubGenerator: public StubCodeGenerator { // // s and d are adjusted to point to the remaining words to copy // - void generate_copy_longs(Label &start, Register s, Register d, Register count, - copy_direction direction) { + void generate_copy_longs(StubGenStubId stub_id, Label &start, + Register s, Register d, Register count) { + BasicType type; + copy_direction direction; + switch (stub_id) { + case copy_byte_f_id: + direction = copy_forwards; + type = T_BYTE; + break; + case copy_byte_b_id: + direction = copy_backwards; + type = T_BYTE; + break; + default: + ShouldNotReachHere(); + } int unit = wordSize * direction; int bias = wordSize; @@ -742,13 +760,7 @@ class StubGenerator: public StubCodeGenerator { assert_different_registers(s, d, count, t0); Label again, drain; - const char* stub_name = nullptr; - if (direction == copy_forwards) { - stub_name = "forward_copy_longs"; - } else { - stub_name = "backward_copy_longs"; - } - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); __ align(CodeEntryAlignment); __ bind(start); @@ -779,7 +791,7 @@ class StubGenerator: public StubCodeGenerator { __ ld(tmp_reg7, Address(s, 8 * unit)); __ addi(s, s, 8 * unit); - __ sub(count, count, 16); + __ subi(count, count, 16); __ bltz(count, drain); __ bind(again); @@ -805,7 +817,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(s, s, 8 * unit); __ addi(d, d, 8 * unit); - __ sub(count, count, 8); + __ subi(count, count, 8); __ bgez(count, again); // Drain @@ -959,9 +971,9 @@ class StubGenerator: public StubCodeGenerator { } if (is_aligned) { - __ addi(t0, cnt, -32); + __ subi(t0, cnt, 32); __ bgez(t0, copy32_loop); - __ addi(t0, cnt, -8); + __ subi(t0, cnt, 8); __ bgez(t0, copy8_loop, is_far); __ j(copy_small); } else { @@ -985,7 +997,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, step); __ addi(dst, dst, step); } - __ addi(cnt, cnt, -granularity); + __ subi(cnt, cnt, granularity); __ beqz(cnt, done, is_far); __ j(same_aligned); @@ -996,8 +1008,8 @@ class StubGenerator: public StubCodeGenerator { __ bind(copy32_loop); if (is_backwards) { - __ addi(src, src, -wordSize * 4); - __ addi(dst, dst, -wordSize * 4); + __ subi(src, src, wordSize * 4); + __ subi(dst, dst, wordSize * 4); } // we first load 32 bytes, then write it, so the direction here doesn't matter bs_asm->copy_load_at(_masm, decorators, type, 8, tmp3, Address(src), gct1); @@ -1014,19 +1026,19 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, wordSize * 4); __ addi(dst, dst, wordSize * 4); } - __ addi(t0, cnt, -(32 + wordSize * 4)); - __ addi(cnt, cnt, -wordSize * 4); + __ subi(t0, cnt, 32 + wordSize * 4); + __ subi(cnt, cnt, wordSize * 4); __ bgez(t0, copy32_loop); // cnt >= 32, do next loop __ beqz(cnt, done); // if that's all - done - __ addi(t0, cnt, -8); // if not - copy the reminder + __ subi(t0, cnt, 8); // if not - copy the reminder __ bltz(t0, copy_small); // cnt < 8, go to copy_small, else fall through to copy8_loop __ bind(copy8_loop); if (is_backwards) { - __ addi(src, src, -wordSize); - __ addi(dst, dst, -wordSize); + __ subi(src, src, wordSize); + __ subi(dst, dst, wordSize); } bs_asm->copy_load_at(_masm, decorators, type, 8, tmp3, Address(src), gct1); bs_asm->copy_store_at(_masm, decorators, type, 8, Address(dst), tmp3, gct1, gct2, gct3); @@ -1035,8 +1047,8 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, wordSize); __ addi(dst, dst, wordSize); } - __ addi(t0, cnt, -(8 + wordSize)); - __ addi(cnt, cnt, -wordSize); + __ subi(t0, cnt, 8 + wordSize); + __ subi(cnt, cnt, wordSize); __ bgez(t0, copy8_loop); // cnt >= 8, do next loop __ beqz(cnt, done); // if that's all - done @@ -1054,7 +1066,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(src, src, step); __ addi(dst, dst, step); } - __ addi(cnt, cnt, -granularity); + __ subi(cnt, cnt, granularity); __ bgtz(cnt, copy_small); __ bind(done); @@ -1083,10 +1095,11 @@ class StubGenerator: public StubCodeGenerator { } // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // is_oop - true => oop array, so generate store check code - // name - stub name string + // stub_id - is used to name the stub and identify all details of + // how to perform the copy. + // + // entry - is assigned to the stub's post push entry point unless + // it is null // // Inputs: // c_rarg0 - source array address @@ -1097,16 +1110,96 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - // Side Effects: - // disjoint_int_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_int_oop_copy(). + // Side Effects: entry is set to the (post push) entry point so it + // can be used by the corresponding conjoint copy + // method // - address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address* entry, - const char* name, bool dest_uninitialized = false) { + address generate_disjoint_copy(StubGenStubId stub_id, address* entry) { + size_t size; + bool aligned; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + size = sizeof(jbyte); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jbyte_disjoint_arraycopy_id: + size = sizeof(jbyte); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_disjoint_arraycopy_id: + size = sizeof(jshort); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jshort_disjoint_arraycopy_id: + size = sizeof(jshort); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jint_disjoint_arraycopy_id: + size = sizeof(jint); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jint_disjoint_arraycopy_id: + size = sizeof(jint); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_disjoint_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case arrayof_jlong_disjoint_arraycopy + ShouldNotReachHere(); + break; + case arrayof_jlong_disjoint_arraycopy_id: + size = sizeof(jlong); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case arrayof_oop_disjoint_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + case arrayof_oop_disjoint_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + break; + } + const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_reg = RegSet::of(s, d, count); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -1155,10 +1248,15 @@ class StubGenerator: public StubCodeGenerator { } // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // is_oop - true => oop array, so generate store check code - // name - stub name string + // stub_id - is used to name the stub and identify all details of + // how to perform the copy. + // + // nooverlap_target - identifes the (post push) entry for the + // corresponding disjoint copy routine which can be + // jumped to if the ranges do not actually overlap + // + // entry - is assigned to the stub's post push entry point unless + // it is null // // Inputs: // c_rarg0 - source array address @@ -1169,12 +1267,94 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // - address generate_conjoint_copy(size_t size, bool aligned, bool is_oop, address nooverlap_target, - address* entry, const char* name, - bool dest_uninitialized = false) { + // Side Effects: + // entry is set to the no-overlap entry point so it can be used by + // some other conjoint copy method + // + address generate_conjoint_copy(StubGenStubId stub_id, address nooverlap_target, address *entry) { const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_regs = RegSet::of(s, d, count); - StubCodeMark mark(this, "StubRoutines", name); + int size; + bool aligned; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case jbyte_arraycopy_id: + size = sizeof(jbyte); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jbyte_arraycopy_id: + size = sizeof(jbyte); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_arraycopy_id: + size = sizeof(jshort); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jshort_arraycopy_id: + size = sizeof(jshort); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jint_arraycopy_id: + size = sizeof(jint); + aligned = false; + is_oop = false; + dest_uninitialized = false; + break; + case arrayof_jint_arraycopy_id: + size = sizeof(jint); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case arrayof_jlong_disjoint_arraycopy + ShouldNotReachHere(); + break; + case arrayof_jlong_arraycopy_id: + size = sizeof(jlong); + aligned = true; + is_oop = false; + dest_uninitialized = false; + break; + case oop_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case arrayof_oop_arraycopy_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = false; + break; + case oop_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + case arrayof_oop_arraycopy_uninit_id: + size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + aligned = !UseCompressedOops; + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -1228,232 +1408,14 @@ class StubGenerator: public StubCodeGenerator { return start; } - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_byte_copy_entry is set to the no-overlap entry point // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_byte_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_byte_copy(). - // - address generate_disjoint_byte_copy(bool aligned, address* entry, const char* name) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jbyte), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries, - // we let the hardware handle it. The one to eight bytes within words, - // dwords or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, - address* entry, const char* name) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jbyte), aligned, not_oop, nooverlap_target, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we - // let the hardware handle it. The two or four words within dwords - // or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - // Side Effects: - // disjoint_short_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_short_copy(). - // - address generate_disjoint_short_copy(bool aligned, - address* entry, const char* name) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jshort), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we - // let the hardware handle it. The two or four words within dwords - // or qwords that span cache line boundaries will still be loaded - // and stored atomically. - // - address generate_conjoint_short_copy(bool aligned, address nooverlap_target, - address* entry, const char* name) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jshort), aligned, not_oop, nooverlap_target, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let - // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomically. - // - // Side Effects: - // disjoint_int_copy_entry is set to the no-overlap entry point - // used by generate_conjoint_int_oop_copy(). - // - address generate_disjoint_int_copy(bool aligned, address* entry, - const char* name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jint), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as ssize_t, can be zero - // - // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let - // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomically. - // - address generate_conjoint_int_copy(bool aligned, address nooverlap_target, - address* entry, const char* name, - bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jint), aligned, not_oop, nooverlap_target, entry, name); - } - - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - // Side Effects: - // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the - // no-overlap entry point used by generate_conjoint_long_oop_copy(). - // - address generate_disjoint_long_copy(bool aligned, address* entry, - const char* name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_disjoint_copy(sizeof (jlong), aligned, not_oop, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - address generate_conjoint_long_copy(bool aligned, - address nooverlap_target, address* entry, - const char* name, bool dest_uninitialized = false) { - const bool not_oop = false; - return generate_conjoint_copy(sizeof (jlong), aligned, not_oop, nooverlap_target, entry, name); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - // Side Effects: - // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the - // no-overlap entry point used by generate_conjoint_long_oop_copy(). - // - address generate_disjoint_oop_copy(bool aligned, address* entry, - const char* name, bool dest_uninitialized) { - const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); - return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized); - } - - // Arguments: - // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes - // ignored - // name - stub name string - // - // Inputs: - // c_rarg0 - source array address - // c_rarg1 - destination array address - // c_rarg2 - element count, treated as size_t, can be zero - // - address generate_conjoint_oop_copy(bool aligned, - address nooverlap_target, address* entry, - const char* name, bool dest_uninitialized) { - const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); - return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, - name, dest_uninitialized); - } - // Helper for generating a dynamic type check. // Smashes t0, t1. void generate_type_check(Register sub_klass, Register super_check_offset, Register super_klass, + Register result, + Register tmp1, + Register tmp2, Label& L_success) { assert_different_registers(sub_klass, super_check_offset, super_klass); @@ -1462,7 +1424,7 @@ class StubGenerator: public StubCodeGenerator { Label L_miss; __ check_klass_subtype_fast_path(sub_klass, super_klass, noreg, &L_success, &L_miss, nullptr, super_check_offset); - __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, &L_success, nullptr); + __ check_klass_subtype_slow_path(sub_klass, super_klass, tmp1, tmp2, &L_success, nullptr); // Fall through on failure! __ BIND(L_miss); @@ -1482,8 +1444,19 @@ class StubGenerator: public StubCodeGenerator { // x10 == 0 - success // x10 == -1^K - failure, where K is partial transfer count // - address generate_checkcast_copy(const char* name, address* entry, - bool dest_uninitialized = false) { + address generate_checkcast_copy(StubGenStubId stub_id, address* entry) { + bool dest_uninitialized; + switch (stub_id) { + case checkcast_arraycopy_id: + dest_uninitialized = false; + break; + case checkcast_arraycopy_uninit_id: + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + Label L_load_element, L_store_element, L_do_card_marks, L_done, L_done_pop; // Input registers (after setup_arg_regs) @@ -1516,7 +1489,7 @@ class StubGenerator: public StubCodeGenerator { copied_oop, r9_klass, count_save); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -1578,8 +1551,8 @@ class StubGenerator: public StubCodeGenerator { bs->copy_store_at(_masm, decorators, T_OBJECT, element_size, Address(to, 0), copied_oop, gct1, gct2, gct3); - __ add(to, to, UseCompressedOops ? 4 : 8); - __ sub(count, count, 1); + __ addi(to, to, UseCompressedOops ? 4 : 8); + __ subi(count, count, 1); __ beqz(count, L_do_card_marks); // ======== loop entry is here ======== @@ -1587,11 +1560,22 @@ class StubGenerator: public StubCodeGenerator { bs->copy_load_at(_masm, decorators, T_OBJECT, element_size, copied_oop, Address(from, 0), gct1); - __ add(from, from, UseCompressedOops ? 4 : 8); + __ addi(from, from, UseCompressedOops ? 4 : 8); __ beqz(copied_oop, L_store_element); __ load_klass(r9_klass, copied_oop);// query the object klass - generate_type_check(r9_klass, ckoff, ckval, L_store_element); + + BLOCK_COMMENT("type_check:"); + generate_type_check(r9_klass, /*sub_klass*/ + ckoff, /*super_check_offset*/ + ckval, /*super_klass*/ + x10, /*result*/ + gct1, /*tmp1*/ + gct2, /*tmp2*/ + L_store_element); + + // Fall through on failure! + // ======== end loop ======== // It was a real error; we must depend on the caller to finish the job. @@ -1600,7 +1584,7 @@ class StubGenerator: public StubCodeGenerator { // their number to the caller. __ sub(count, count_save, count); // K = partially copied oop count - __ xori(count, count, -1); // report (-1^K) to caller + __ xori(count, count, -1); // report (-1^K) to caller __ beqz(count, L_done_pop); __ BIND(L_do_card_marks); @@ -1662,8 +1646,7 @@ class StubGenerator: public StubCodeGenerator { // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // - address generate_unsafe_copy(const char* name, - address byte_copy_entry, + address generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { @@ -1673,7 +1656,8 @@ class StubGenerator: public StubCodeGenerator { const Register s = c_rarg0, d = c_rarg1, count = c_rarg2; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -1718,8 +1702,7 @@ class StubGenerator: public StubCodeGenerator { // x10 == 0 - success // x10 == -1^K - failure, where K is partial transfer count // - address generate_generic_copy(const char* name, - address byte_copy_entry, address short_copy_entry, + address generate_generic_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry) { assert_cond(byte_copy_entry != nullptr && short_copy_entry != nullptr && @@ -1740,7 +1723,8 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -1929,9 +1913,9 @@ class StubGenerator: public StubCodeGenerator { t1, L_failed); __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); - __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); - __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ sext(count, scratch_length, 32); // length __ BIND(L_plain_copy); __ j(RuntimeAddress(oop_copy_entry)); @@ -1952,9 +1936,9 @@ class StubGenerator: public StubCodeGenerator { // Marshal the base address arguments now, freeing registers. __ shadd(from, src_pos, src, t0, LogBytesPerHeapOop); - __ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ shadd(to, dst_pos, dst, t0, LogBytesPerHeapOop); - __ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + __ addi(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); __ sext(count, length, 32); // length (reloaded) const Register sco_temp = c_rarg3; // this register is free now assert_different_registers(from, to, count, sco_temp, @@ -1965,7 +1949,7 @@ class StubGenerator: public StubCodeGenerator { __ lwu(sco_temp, Address(dst_klass, sco_offset)); // Smashes t0, t1 - generate_type_check(scratch_src_klass, sco_temp, dst_klass, L_plain_copy); + generate_type_check(scratch_src_klass, sco_temp, dst_klass, noreg, noreg, noreg, L_plain_copy); // Fetch destination element klass from the ObjArrayKlass header. int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); @@ -1996,9 +1980,41 @@ class StubGenerator: public StubCodeGenerator { // value: c_rarg1 // count: c_rarg2 treated as signed // - address generate_fill(BasicType t, bool aligned, const char* name) { + address generate_fill(StubGenStubId stub_id) { + BasicType t; + bool aligned; + + switch (stub_id) { + case jbyte_fill_id: + t = T_BYTE; + aligned = false; + break; + case jshort_fill_id: + t = T_SHORT; + aligned = false; + break; + case jint_fill_id: + t = T_INT; + aligned = false; + break; + case arrayof_jbyte_fill_id: + t = T_BYTE; + aligned = true; + break; + case arrayof_jshort_fill_id: + t = T_SHORT; + aligned = true; + break; + case arrayof_jint_fill_id: + t = T_INT; + aligned = true; + break; + default: + ShouldNotReachHere(); + }; + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -2068,7 +2084,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align1); __ sb(value, Address(to, 0)); __ addi(to, to, 1); - __ addiw(count, count, -1); + __ subiw(count, count, 1); __ bind(L_skip_align1); // Fallthrough case T_SHORT: @@ -2077,7 +2093,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align2); __ sh(value, Address(to, 0)); __ addi(to, to, 2); - __ addiw(count, count, -(2 >> shift)); + __ subiw(count, count, 2 >> shift); __ bind(L_skip_align2); // Fallthrough case T_INT: @@ -2086,7 +2102,7 @@ class StubGenerator: public StubCodeGenerator { __ beqz(t0, L_skip_align4); __ sw(value, Address(to, 0)); __ addi(to, to, 4); - __ addiw(count, count, -(4 >> shift)); + __ subiw(count, count, 4 >> shift); __ bind(L_skip_align4); break; default: ShouldNotReachHere(); @@ -2170,109 +2186,79 @@ class StubGenerator: public StubCodeGenerator { address entry_jlong_arraycopy = nullptr; address entry_checkcast_arraycopy = nullptr; - generate_copy_longs(copy_f, c_rarg0, c_rarg1, t1, copy_forwards); - generate_copy_longs(copy_b, c_rarg0, c_rarg1, t1, copy_backwards); + generate_copy_longs(StubGenStubId::copy_byte_f_id, copy_f, c_rarg0, c_rarg1, t1); + generate_copy_longs(StubGenStubId::copy_byte_b_id, copy_b, c_rarg0, c_rarg1, t1); StubRoutines::riscv::_zero_blocks = generate_zero_blocks(); //*** jbyte // Always need aligned and unaligned versions - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, - "jbyte_disjoint_arraycopy"); - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, - &entry_jbyte_arraycopy, - "jbyte_arraycopy"); - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(true, &entry, - "arrayof_jbyte_disjoint_arraycopy"); - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy(true, entry, nullptr, - "arrayof_jbyte_arraycopy"); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jbyte_disjoint_arraycopy_id, &entry); + StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubGenStubId::jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy); + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jbyte_arraycopy_id, entry, nullptr); //*** jshort // Always need aligned and unaligned versions - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, - "jshort_disjoint_arraycopy"); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, - &entry_jshort_arraycopy, - "jshort_arraycopy"); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, &entry, - "arrayof_jshort_disjoint_arraycopy"); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, entry, nullptr, - "arrayof_jshort_arraycopy"); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jshort_disjoint_arraycopy_id, &entry); + StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubGenStubId::jshort_arraycopy_id, entry, &entry_jshort_arraycopy); + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jshort_arraycopy_id, entry, nullptr); //*** jint // Aligned versions - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy(true, &entry, - "arrayof_jint_disjoint_arraycopy"); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy(true, entry, &entry_jint_arraycopy, - "arrayof_jint_arraycopy"); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jint_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jint_arraycopy_id, entry, &entry_jint_arraycopy); // In 64 bit we need both aligned and unaligned versions of jint arraycopy. // entry_jint_arraycopy always points to the unaligned version - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy(false, &entry, - "jint_disjoint_arraycopy"); - StubRoutines::_jint_arraycopy = generate_conjoint_int_copy(false, entry, - &entry_jint_arraycopy, - "jint_arraycopy"); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::jint_disjoint_arraycopy_id, &entry); + StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubGenStubId::jint_arraycopy_id, entry, &entry_jint_arraycopy); //*** jlong // It is always aligned - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy(true, &entry, - "arrayof_jlong_disjoint_arraycopy"); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy(true, entry, &entry_jlong_arraycopy, - "arrayof_jlong_arraycopy"); - StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; - StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubGenStubId::arrayof_jlong_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubGenStubId::arrayof_jlong_arraycopy_id, entry, &entry_jlong_arraycopy); + StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy; + StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy; //*** oops - { - // With compressed oops we need unaligned versions; notice that - // we overwrite entry_oop_arraycopy. - bool aligned = !UseCompressedOops; - - StubRoutines::_arrayof_oop_disjoint_arraycopy - = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy", - /*dest_uninitialized*/false); - StubRoutines::_arrayof_oop_arraycopy - = generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy", - /*dest_uninitialized*/false); - // Aligned versions without pre-barriers - StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit - = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit", - /*dest_uninitialized*/true); - StubRoutines::_arrayof_oop_arraycopy_uninit - = generate_conjoint_oop_copy(aligned, entry, nullptr, "arrayof_oop_arraycopy_uninit", - /*dest_uninitialized*/true); - } + StubRoutines::_arrayof_oop_disjoint_arraycopy + = generate_disjoint_copy(StubGenStubId::arrayof_oop_disjoint_arraycopy_id, &entry); + StubRoutines::_arrayof_oop_arraycopy + = generate_conjoint_copy(StubGenStubId::arrayof_oop_arraycopy_id, entry, &entry_oop_arraycopy); + // Aligned versions without pre-barriers + StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit + = generate_disjoint_copy(StubGenStubId::arrayof_oop_disjoint_arraycopy_uninit_id, &entry); + StubRoutines::_arrayof_oop_arraycopy_uninit + = generate_conjoint_copy(StubGenStubId::arrayof_oop_arraycopy_uninit_id, entry, nullptr); StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy; StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy; StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit; StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit; - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); - StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", nullptr, - /*dest_uninitialized*/true); + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_uninit_id, nullptr); - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_jlong_arraycopy); - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_oop_arraycopy, entry_jlong_arraycopy, entry_checkcast_arraycopy); - StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); - StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); - StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); - StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); - StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); - StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); + StubRoutines::_jbyte_fill = generate_fill(StubGenStubId::jbyte_fill_id); + StubRoutines::_jshort_fill = generate_fill(StubGenStubId::jshort_fill_id); + StubRoutines::_jint_fill = generate_fill(StubGenStubId::jint_fill_id); + StubRoutines::_arrayof_jbyte_fill = generate_fill(StubGenStubId::arrayof_jbyte_fill_id); + StubRoutines::_arrayof_jshort_fill = generate_fill(StubGenStubId::arrayof_jshort_fill_id); + StubRoutines::_arrayof_jint_fill = generate_fill(StubGenStubId::arrayof_jint_fill_id); } void generate_aes_loadkeys(const Register &key, VectorRegister *working_vregs, int rounds) { @@ -2308,7 +2294,8 @@ class StubGenerator: public StubCodeGenerator { assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_aes128, L_aes192; @@ -2386,7 +2373,8 @@ class StubGenerator: public StubCodeGenerator { assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_aes128, L_aes192; @@ -2461,17 +2449,36 @@ class StubGenerator: public StubCodeGenerator { } // code for comparing 8 characters of strings with Latin1 and Utf16 encoding - void compare_string_8_x_LU(Register tmpL, Register tmpU, Register strL, Register strU, Label& DIFF) { + void compare_string_8_x_LU(Register tmpL, Register tmpU, + Register strL, Register strU, Label& DIFF) { const Register tmp = x30, tmpLval = x12; + + int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); + + assert((base_offset % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + +#ifdef ASSERT + if (AvoidUnalignedAccesses) { + Label align_ok; + __ andi(t0, strL, 0x7); + __ beqz(t0, align_ok); + __ stop("bad alignment"); + __ bind(align_ok); + } +#endif __ ld(tmpLval, Address(strL)); __ addi(strL, strL, wordSize); - __ ld(tmpU, Address(strU)); + + // compare first 4 characters + __ load_long_misaligned(tmpU, Address(strU), tmp, (base_offset % 8) != 0 ? 4 : 8); __ addi(strU, strU, wordSize); __ inflate_lo32(tmpL, tmpLval); __ xorr(tmp, tmpU, tmpL); __ bnez(tmp, DIFF); - __ ld(tmpU, Address(strU)); + // compare second 4 characters + __ load_long_misaligned(tmpU, Address(strU), tmp, (base_offset % 8) != 0 ? 4 : 8); __ addi(strU, strU, wordSize); __ inflate_hi32(tmpL, tmpLval); __ xorr(tmp, tmpU, tmpL); @@ -2486,47 +2493,57 @@ class StubGenerator: public StubCodeGenerator { // x28 = tmp1 // x29 = tmp2 // x30 = tmp3 - address generate_compare_long_string_different_encoding(bool isLU) { + address generate_compare_long_string_different_encoding(StubGenStubId stub_id) { + bool isLU; + switch (stub_id) { + case compare_long_string_LU_id: + isLU = true; + break; + case compare_long_string_UL_id: + isLU = false; + break; + default: + ShouldNotReachHere(); + }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", isLU ? "compare_long_string_different_encoding LU" : "compare_long_string_different_encoding UL"); + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label SMALL_LOOP, TAIL, LOAD_LAST, DONE, CALCULATE_DIFFERENCE; const Register result = x10, str1 = x11, str2 = x13, cnt2 = x14, tmp1 = x28, tmp2 = x29, tmp3 = x30, tmp4 = x12; - // cnt2 == amount of characters left to compare - // Check already loaded first 4 symbols - __ inflate_lo32(tmp3, isLU ? tmp1 : tmp2); - __ mv(isLU ? tmp1 : tmp2, tmp3); - __ addi(str1, str1, isLU ? wordSize / 2 : wordSize); - __ addi(str2, str2, isLU ? wordSize : wordSize / 2); - __ sub(cnt2, cnt2, wordSize / 2); // Already loaded 4 symbols + int base_offset1 = arrayOopDesc::base_offset_in_bytes(T_BYTE); + int base_offset2 = arrayOopDesc::base_offset_in_bytes(T_CHAR); - __ xorr(tmp3, tmp1, tmp2); - __ bnez(tmp3, CALCULATE_DIFFERENCE); + assert((base_offset1 % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); + assert((base_offset2 % (UseCompactObjectHeaders ? 4 : + (UseCompressedClassPointers ? 8 : 4))) == 0, "Must be"); Register strU = isLU ? str2 : str1, strL = isLU ? str1 : str2, tmpU = isLU ? tmp2 : tmp1, // where to keep U for comparison tmpL = isLU ? tmp1 : tmp2; // where to keep L for comparison - // make sure main loop is 8 byte-aligned, we should load another 4 bytes from strL - // cnt2 is >= 68 here, no need to check it for >= 0 - __ lwu(tmpL, Address(strL)); - __ addi(strL, strL, wordSize / 2); - __ ld(tmpU, Address(strU)); - __ addi(strU, strU, wordSize); - __ inflate_lo32(tmp3, tmpL); - __ mv(tmpL, tmp3); - __ xorr(tmp3, tmpU, tmpL); - __ bnez(tmp3, CALCULATE_DIFFERENCE); - __ addi(cnt2, cnt2, -wordSize / 2); - - // we are now 8-bytes aligned on strL - __ sub(cnt2, cnt2, wordSize * 2); + if (AvoidUnalignedAccesses && (base_offset1 % 8) != 0) { + // Load 4 bytes from strL to make sure main loop is 8-byte aligned + // cnt2 is >= 68 here, no need to check it for >= 0 + __ lwu(tmpL, Address(strL)); + __ addi(strL, strL, wordSize / 2); + __ load_long_misaligned(tmpU, Address(strU), tmp4, (base_offset2 % 8) != 0 ? 4 : 8); + __ addi(strU, strU, wordSize); + __ inflate_lo32(tmp3, tmpL); + __ mv(tmpL, tmp3); + __ xorr(tmp3, tmpU, tmpL); + __ bnez(tmp3, CALCULATE_DIFFERENCE); + __ subi(cnt2, cnt2, wordSize / 2); + } + + // we are now 8-bytes aligned on strL when AvoidUnalignedAccesses is true + __ subi(cnt2, cnt2, wordSize * 2); __ bltz(cnt2, TAIL); __ bind(SMALL_LOOP); // smaller loop - __ sub(cnt2, cnt2, wordSize * 2); + __ subi(cnt2, cnt2, wordSize * 2); compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); __ bgez(cnt2, SMALL_LOOP); @@ -2540,11 +2557,11 @@ class StubGenerator: public StubCodeGenerator { __ bltz(t0, LOAD_LAST); // remaining characters are greater than or equals to 8, we can do one compare_string_8_x_LU compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE); - __ addi(cnt2, cnt2, -wordSize); + __ subi(cnt2, cnt2, wordSize); __ beqz(cnt2, DONE); // no character left __ bind(LOAD_LAST); // cnt2 = 1..7 characters left - __ addi(cnt2, cnt2, -wordSize); // cnt2 is now an offset in strL which points to last 8 bytes + __ subi(cnt2, cnt2, wordSize); // cnt2 is now an offset in strL which points to last 8 bytes __ slli(t0, cnt2, 1); // t0 is now an offset in strU which points to last 16 bytes __ add(strL, strL, cnt2); // Address of last 8 bytes in Latin1 string __ add(strU, strU, t0); // Address of last 16 bytes in UTF-16 string @@ -2568,7 +2585,8 @@ class StubGenerator: public StubCodeGenerator { // Find the first different characters in the longwords and // compute their difference. __ bind(CALCULATE_DIFFERENCE); - __ ctzc_bit(tmp4, tmp3); + // count bits of trailing zero chars + __ ctzc_bits(tmp4, tmp3); __ srl(tmp1, tmp1, tmp4); __ srl(tmp2, tmp2, tmp4); __ zext(tmp1, tmp1, 16); @@ -2581,7 +2599,8 @@ class StubGenerator: public StubCodeGenerator { address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); Label deoptimize_label; @@ -2609,9 +2628,9 @@ class StubGenerator: public StubCodeGenerator { __ set_last_Java_frame(sp, fp, ra); __ enter(); - __ add(t1, sp, wordSize); + __ addi(t1, sp, wordSize); - __ sub(sp, sp, 4 * wordSize); + __ subi(sp, sp, 4 * wordSize); __ push_call_clobbered_registers(); @@ -2651,10 +2670,20 @@ class StubGenerator: public StubCodeGenerator { // x29 = tmp2 // x30 = tmp3 // x31 = tmp4 - address generate_compare_long_string_same_encoding(bool isLL) { + address generate_compare_long_string_same_encoding(StubGenStubId stub_id) { + bool isLL; + switch (stub_id) { + case compare_long_string_LL_id: + isLL = true; + break; + case compare_long_string_UU_id: + isLL = false; + break; + default: + ShouldNotReachHere(); + }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", isLL ? - "compare_long_string_same_encoding LL" : "compare_long_string_same_encoding UU"); + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label SMALL_LOOP, CHECK_LAST, DIFF2, TAIL, LENGTH_DIFF, DIFF, LAST_CHECK_AND_LENGTH_DIFF; @@ -2664,22 +2693,22 @@ class StubGenerator: public StubCodeGenerator { // cnt1/cnt2 contains amount of characters to compare. cnt1 can be re-used // update cnt2 counter with already loaded 8 bytes - __ sub(cnt2, cnt2, wordSize / (isLL ? 1 : 2)); + __ subi(cnt2, cnt2, wordSize / (isLL ? 1 : 2)); // update pointers, because of previous read - __ add(str1, str1, wordSize); - __ add(str2, str2, wordSize); + __ addi(str1, str1, wordSize); + __ addi(str2, str2, wordSize); // less than 16 bytes left? - __ sub(cnt2, cnt2, isLL ? 16 : 8); + __ subi(cnt2, cnt2, isLL ? 16 : 8); __ push_reg(spilled_regs, sp); __ bltz(cnt2, TAIL); __ bind(SMALL_LOOP); compare_string_16_bytes_same(DIFF, DIFF2); - __ sub(cnt2, cnt2, isLL ? 16 : 8); + __ subi(cnt2, cnt2, isLL ? 16 : 8); __ bgez(cnt2, SMALL_LOOP); __ bind(TAIL); __ addi(cnt2, cnt2, isLL ? 16 : 8); __ beqz(cnt2, LAST_CHECK_AND_LENGTH_DIFF); - __ sub(cnt2, cnt2, isLL ? 8 : 4); + __ subi(cnt2, cnt2, isLL ? 8 : 4); __ blez(cnt2, CHECK_LAST); __ xorr(tmp4, tmp1, tmp2); __ bnez(tmp4, DIFF); @@ -2687,7 +2716,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(str1, str1, 8); __ ld(tmp2, Address(str2)); __ addi(str2, str2, 8); - __ sub(cnt2, cnt2, isLL ? 8 : 4); + __ subi(cnt2, cnt2, isLL ? 8 : 4); __ bind(CHECK_LAST); if (!isLL) { __ add(cnt2, cnt2, cnt2); // now in bytes @@ -2703,7 +2732,8 @@ class StubGenerator: public StubCodeGenerator { // Find the first different characters in the longwords and // compute their difference. __ bind(DIFF2); - __ ctzc_bit(tmp3, tmp4, isLL); // count zero from lsb to msb + // count bits of trailing zero chars + __ ctzc_bits(tmp3, tmp4, isLL); __ srl(tmp5, tmp5, tmp3); __ srl(cnt1, cnt1, tmp3); if (isLL) { @@ -2716,7 +2746,8 @@ class StubGenerator: public StubCodeGenerator { __ sub(result, tmp5, cnt1); __ j(LENGTH_DIFF); __ bind(DIFF); - __ ctzc_bit(tmp3, tmp4, isLL); // count zero from lsb to msb + // count bits of trailing zero chars + __ ctzc_bits(tmp3, tmp4, isLL); __ srl(tmp1, tmp1, tmp3); __ srl(tmp2, tmp2, tmp3); if (isLL) { @@ -2738,10 +2769,10 @@ class StubGenerator: public StubCodeGenerator { } void generate_compare_long_strings() { - StubRoutines::riscv::_compare_long_string_LL = generate_compare_long_string_same_encoding(true); - StubRoutines::riscv::_compare_long_string_UU = generate_compare_long_string_same_encoding(false); - StubRoutines::riscv::_compare_long_string_LU = generate_compare_long_string_different_encoding(true); - StubRoutines::riscv::_compare_long_string_UL = generate_compare_long_string_different_encoding(false); + StubRoutines::riscv::_compare_long_string_LL = generate_compare_long_string_same_encoding(StubGenStubId::compare_long_string_LL_id); + StubRoutines::riscv::_compare_long_string_UU = generate_compare_long_string_same_encoding(StubGenStubId::compare_long_string_UU_id); + StubRoutines::riscv::_compare_long_string_LU = generate_compare_long_string_different_encoding(StubGenStubId::compare_long_string_LU_id); + StubRoutines::riscv::_compare_long_string_UL = generate_compare_long_string_different_encoding(StubGenStubId::compare_long_string_UL_id); } // x10 result @@ -2749,13 +2780,29 @@ class StubGenerator: public StubCodeGenerator { // x12 src count // x13 pattern // x14 pattern count - address generate_string_indexof_linear(bool needle_isL, bool haystack_isL) + address generate_string_indexof_linear(StubGenStubId stub_id) { - const char* stubName = needle_isL - ? (haystack_isL ? "indexof_linear_ll" : "indexof_linear_ul") - : "indexof_linear_uu"; + bool needle_isL; + bool haystack_isL; + switch (stub_id) { + case string_indexof_linear_ll_id: + needle_isL = true; + haystack_isL = true; + break; + case string_indexof_linear_ul_id: + needle_isL = true; + haystack_isL = false; + break; + case string_indexof_linear_uu_id: + needle_isL = false; + haystack_isL = false; + break; + default: + ShouldNotReachHere(); + }; + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stubName); + StubCodeMark mark(this, stub_id); address entry = __ pc(); int needle_chr_size = needle_isL ? 1 : 2; @@ -2798,7 +2845,7 @@ class StubGenerator: public StubCodeGenerator { if (needle_isL != haystack_isL) { __ mv(tmp, ch1); } - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size - 1); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size - 1); __ blez(haystack_len, L_SMALL); if (needle_isL != haystack_isL) { @@ -2814,9 +2861,9 @@ class StubGenerator: public StubCodeGenerator { // search first char of needle, if success, goto L_HAS_ZERO; __ bnez(match_mask, L_HAS_ZERO); - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); - __ add(result, result, wordSize / haystack_chr_size); - __ add(haystack, haystack, wordSize); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size); + __ addi(result, result, wordSize / haystack_chr_size); + __ addi(haystack, haystack, wordSize); __ bltz(haystack_len, L_POST_LOOP); __ bind(L_LOOP); @@ -2825,9 +2872,9 @@ class StubGenerator: public StubCodeGenerator { __ bnez(match_mask, L_HAS_ZERO); __ bind(L_LOOP_PROCEED); - __ sub(haystack_len, haystack_len, wordSize / haystack_chr_size); - __ add(haystack, haystack, wordSize); - __ add(result, result, wordSize / haystack_chr_size); + __ subi(haystack_len, haystack_len, wordSize / haystack_chr_size); + __ addi(haystack, haystack, wordSize); + __ addi(result, result, wordSize / haystack_chr_size); __ bgez(haystack_len, L_LOOP); __ bind(L_POST_LOOP); @@ -2862,7 +2909,8 @@ class StubGenerator: public StubCodeGenerator { __ beqz(match_mask, NOMATCH); __ bind(L_SMALL_HAS_ZERO_LOOP); - __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, ch2, tmp); // count trailing zeros + // count bits of trailing zero chars + __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, ch2, tmp); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); __ mv(ch2, wordSize / haystack_chr_size); __ ble(needle_len, ch2, L_SMALL_CMP_LOOP_LAST_CMP2); @@ -2875,16 +2923,17 @@ class StubGenerator: public StubCodeGenerator { __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); needle_isL ? __ lbu(first, Address(first)) : __ lhu(first, Address(first)); haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); - __ add(trailing_zeros, trailing_zeros, 1); + __ addi(trailing_zeros, trailing_zeros, 1); __ bge(trailing_zeros, needle_len, L_SMALL_CMP_LOOP_LAST_CMP); __ beq(first, ch2, L_SMALL_CMP_LOOP); __ bind(L_SMALL_CMP_LOOP_NOMATCH); __ beqz(match_mask, NOMATCH); - __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, tmp, ch2); + // count bits of trailing zero chars + __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, tmp, ch2); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); - __ add(result, result, 1); - __ add(haystack, haystack, haystack_chr_size); + __ addi(result, result, 1); + __ addi(haystack, haystack, haystack_chr_size); __ j(L_SMALL_HAS_ZERO_LOOP); __ align(OptoLoopAlignment); @@ -2900,11 +2949,12 @@ class StubGenerator: public StubCodeGenerator { __ align(OptoLoopAlignment); __ bind(L_HAS_ZERO); - __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, tmp, ch2); + // count bits of trailing zero chars + __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, tmp, ch2); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); __ slli(needle_len, needle_len, BitsPerByte * wordSize / 2); __ orr(haystack_len, haystack_len, needle_len); // restore needle_len(32bits) - __ sub(result, result, 1); // array index from 0, so result -= 1 + __ subi(result, result, 1); // array index from 0, so result -= 1 __ bind(L_HAS_ZERO_LOOP); __ mv(needle_len, wordSize / haystack_chr_size); @@ -2912,7 +2962,7 @@ class StubGenerator: public StubCodeGenerator { __ bge(needle_len, ch2, L_CMP_LOOP_LAST_CMP2); // load next 8 bytes from haystack, and increase result index __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); - __ add(result, result, 1); + __ addi(result, result, 1); __ mv(trailing_zeros, wordSize / haystack_chr_size); __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); @@ -2922,16 +2972,17 @@ class StubGenerator: public StubCodeGenerator { needle_isL ? __ lbu(needle_len, Address(needle_len)) : __ lhu(needle_len, Address(needle_len)); __ shadd(ch2, trailing_zeros, haystack, ch2, haystack_chr_shift); haystack_isL ? __ lbu(ch2, Address(ch2)) : __ lhu(ch2, Address(ch2)); - __ add(trailing_zeros, trailing_zeros, 1); // next char index + __ addi(trailing_zeros, trailing_zeros, 1); // next char index __ srli(tmp, haystack_len, BitsPerByte * wordSize / 2); __ bge(trailing_zeros, tmp, L_CMP_LOOP_LAST_CMP); __ beq(needle_len, ch2, L_CMP_LOOP); __ bind(L_CMP_LOOP_NOMATCH); __ beqz(match_mask, L_HAS_ZERO_LOOP_NOMATCH); - __ ctzc_bit(trailing_zeros, match_mask, haystack_isL, needle_len, ch2); // find next "first" char index + // count bits of trailing zero chars + __ ctzc_bits(trailing_zeros, match_mask, haystack_isL, needle_len, ch2); __ addi(trailing_zeros, trailing_zeros, haystack_isL ? 7 : 15); - __ add(haystack, haystack, haystack_chr_size); + __ addi(haystack, haystack, haystack_chr_size); __ j(L_HAS_ZERO_LOOP); __ align(OptoLoopAlignment); @@ -2942,7 +2993,7 @@ class StubGenerator: public StubCodeGenerator { __ align(OptoLoopAlignment); __ bind(L_CMP_LOOP_LAST_CMP2); __ compute_index(haystack, trailing_zeros, match_mask, result, ch2, tmp, haystack_isL); - __ add(result, result, 1); + __ addi(result, result, 1); __ bne(ch1, ch2, L_CMP_LOOP_NOMATCH); __ j(DONE); @@ -2978,16 +3029,16 @@ class StubGenerator: public StubCodeGenerator { void generate_string_indexof_stubs() { - StubRoutines::riscv::_string_indexof_linear_ll = generate_string_indexof_linear(true, true); - StubRoutines::riscv::_string_indexof_linear_uu = generate_string_indexof_linear(false, false); - StubRoutines::riscv::_string_indexof_linear_ul = generate_string_indexof_linear(true, false); + StubRoutines::riscv::_string_indexof_linear_ll = generate_string_indexof_linear(StubGenStubId::string_indexof_linear_ll_id); + StubRoutines::riscv::_string_indexof_linear_uu = generate_string_indexof_linear(StubGenStubId::string_indexof_linear_uu_id); + StubRoutines::riscv::_string_indexof_linear_ul = generate_string_indexof_linear(StubGenStubId::string_indexof_linear_ul_id); } #ifdef COMPILER2 - address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); + void generate_lookup_secondary_supers_table_stub() { + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_id; + StubCodeMark mark(this, stub_id); - address start = __ pc(); const Register r_super_klass = x10, r_array_base = x11, @@ -2997,20 +3048,22 @@ class StubGenerator: public StubCodeGenerator { result = x15, r_bitmap = x16; - Label L_success; - __ enter(); - __ lookup_secondary_supers_table(r_sub_klass, r_super_klass, result, - r_array_base, r_array_length, r_array_index, - r_bitmap, super_klass_index, /*stub_is_near*/true); - __ leave(); - __ ret(); - - return start; + for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + Label L_success; + __ enter(); + __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, result, + r_array_base, r_array_length, r_array_index, + r_bitmap, slot, /*stub_is_near*/true); + __ leave(); + __ ret(); + } } // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub() { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table_slow_path"); + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_slow_path_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register @@ -3031,7 +3084,8 @@ class StubGenerator: public StubCodeGenerator { address generate_mulAdd() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "mulAdd"); + StubGenStubId stub_id = StubGenStubId::mulAdd_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -3064,7 +3118,8 @@ class StubGenerator: public StubCodeGenerator { address generate_multiplyToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); + StubGenStubId stub_id = StubGenStubId::multiplyToLen_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); const Register x = x10; @@ -3094,7 +3149,8 @@ class StubGenerator: public StubCodeGenerator { address generate_squareToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "squareToLen"); + StubGenStubId stub_id = StubGenStubId::squareToLen_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); const Register x = x10; @@ -3134,7 +3190,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_bigIntegerLeftShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerLeftShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerLeftShiftWorker_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label loop, exit; @@ -3185,7 +3242,8 @@ class StubGenerator: public StubCodeGenerator { // address generate_bigIntegerRightShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id; + StubCodeMark mark(this, stub_id); address entry = __ pc(); Label loop, exit; @@ -3303,7 +3361,7 @@ class StubGenerator: public StubCodeGenerator { (this->*block)(); bind(odd); (this->*block)(); - addi(count, count, -2); + subi(count, count, 2); bgtz(count, loop); bind(end); } @@ -3319,7 +3377,7 @@ class StubGenerator: public StubCodeGenerator { (this->*block)(d, s, tmp); bind(odd); (this->*block)(d, s, tmp); - addi(count, count, -2); + subi(count, count, 2); bgtz(count, loop); bind(end); } @@ -3371,7 +3429,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_ab, Ra, Rb); addi(Pa, Pa, wordSize); ld(Ra, Address(Pa)); - addi(Pb, Pb, -wordSize); + subi(Pb, Pb, wordSize); ld(Rb, Address(Pb)); acc(Rhi_mn, Rlo_mn, tmp0, tmp1, tmp2); // The pending m*n from the // previous iteration. @@ -3382,7 +3440,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_mn, Rm, Rn); addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - addi(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); acc(Rhi_ab, Rlo_ab, tmp0, tmp1, tmp2); } @@ -3426,7 +3484,7 @@ class StubGenerator: public StubCodeGenerator { // // mul(Rlo_mn, Rm, Rn); // cad(zr, tmp0, Rlo_mn); - addi(t0, tmp0, -1); + subi(t0, tmp0, 1); sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero cadc(tmp0, tmp1, Rhi_mn, t0); adc(tmp1, tmp2, zr, t0); @@ -3455,13 +3513,13 @@ class StubGenerator: public StubCodeGenerator { // Rb = *--Pb; // Rm = *++Pm; // Rn = *--Pn; - add(Pa, Pa, wordSize); + addi(Pa, Pa, wordSize); ld(Ra, Address(Pa)); - add(Pb, Pb, -wordSize); + subi(Pb, Pb, wordSize); ld(Rb, Address(Pb)); - add(Pm, Pm, wordSize); + addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - add(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); mv(Rhi_mn, zr); @@ -3516,15 +3574,15 @@ class StubGenerator: public StubCodeGenerator { slli(Rn, i, LogBytesPerWord); // Rn as temp register add(Rn, Pm_base, Rn); sd(Rm, Address(Rn)); - add(i, i, 1); + addi(i, i, 1); slli(Rn, i, LogBytesPerWord); add(Rm, Pm_base, Rn); ld(Rm, Address(Rm)); add(Rn, Pn_base, Rn); ld(Rn, Address(Rn)); - sub(cnt, cnt, 1); + subi(cnt, cnt, 1); } bnez(cnt, loop); - addi(tmp0, tmp0, -1); + subi(tmp0, tmp0, 1); add(tmp0, tmp0, t0); } bnez(tmp0, again); } bind(post); @@ -3547,9 +3605,9 @@ class StubGenerator: public StubCodeGenerator { } // [63...0] -> [31...0][63...32] void reverse1(Register d, Register s, Register tmp) { - addi(s, s, -wordSize); + subi(s, s, wordSize); ld(tmp, Address(s)); - ror_imm(tmp, tmp, 32, t0); + ror(tmp, tmp, 32, t0); sd(tmp, Address(d)); addi(d, d, wordSize); } @@ -3584,7 +3642,7 @@ class StubGenerator: public StubCodeGenerator { mul(Rlo_mn, Rm, Rn); addi(Pm, Pm, wordSize); ld(Rm, Address(Pm)); - addi(Pn, Pn, -wordSize); + subi(Pn, Pn, wordSize); ld(Rn, Address(Pn)); } @@ -3619,7 +3677,7 @@ class StubGenerator: public StubCodeGenerator { // // mul(Rlo_mn, Rm, Rn); // cad(zr, tmp, Rlo_mn); - addi(t0, tmp0, -1); + subi(t0, tmp0, 1); sltu(t0, t0, tmp0); // Set carry iff tmp0 is nonzero cadc(tmp0, tmp1, Rhi_mn, t0); adc(tmp1, tmp2, zr, t0); @@ -3725,7 +3783,7 @@ class StubGenerator: public StubCodeGenerator { } block_comment(" } // j"); post1(); - addw(Ri, Ri, 1); + addiw(Ri, Ri, 1); blt(Ri, Rlen, loop); bind(end); block_comment("} // i"); @@ -3743,12 +3801,12 @@ class StubGenerator: public StubCodeGenerator { block_comment(" for (j = len*2-i-1; j; j--) {"); { slliw(Rj, Rlen, 1); subw(Rj, Rj, Ri); - subw(Rj, Rj, 1); + subiw(Rj, Rj, 1); unroll_2(Rj, &MontgomeryMultiplyGenerator::step); } block_comment(" } // j"); post2(Ri, Rlen); - addw(Ri, Ri, 1); + addiw(Ri, Ri, 1); slli(t0, Rlen, 1); blt(Ri, t0, loop); bind(end); @@ -3859,7 +3917,7 @@ class StubGenerator: public StubCodeGenerator { block_comment(" for (j = (2*len-i-1)/2; j; j--) {"); { slli(Rj, Rlen, 1); sub(Rj, Rj, Ri); - sub(Rj, Rj, 1); + subi(Rj, Rj, 1); srliw(Rj, Rj, 1); unroll_2(Rj, &MontgomeryMultiplyGenerator::step_squaring); } block_comment(" } // j"); @@ -3921,7 +3979,7 @@ class StubGenerator: public StubCodeGenerator { if (return_barrier) { // preserve possible return value from a method returning to the return barrier - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(f10, Address(sp, 0 * wordSize)); __ sd(x10, Address(sp, 1 * wordSize)); } @@ -3934,7 +3992,7 @@ class StubGenerator: public StubCodeGenerator { // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) __ ld(x10, Address(sp, 1 * wordSize)); __ fld(f10, Address(sp, 0 * wordSize)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } #ifndef PRODUCT @@ -3959,7 +4017,7 @@ class StubGenerator: public StubCodeGenerator { if (return_barrier) { // save original return value -- again - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ fsd(f10, Address(sp, 0 * wordSize)); __ sd(x10, Address(sp, 1 * wordSize)); } @@ -3974,14 +4032,14 @@ class StubGenerator: public StubCodeGenerator { // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) __ ld(x10, Address(sp, 1 * wordSize)); __ fld(f10, Address(sp, 0 * wordSize)); - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); } else { __ mv(x10, zr); // return 0 (success) from doYield } // we're now on the yield frame (which is in an address above us b/c sp has been pushed down) __ mv(fp, t1); - __ sub(sp, t1, 2 * wordSize); // now pointing to fp spill + __ subi(sp, t1, 2 * wordSize); // now pointing to fp spill if (return_barrier_exception) { __ ld(c_rarg1, Address(fp, -1 * wordSize)); // return address @@ -4011,7 +4069,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_thaw() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines", "Cont thaw"); + StubGenStubId stub_id = StubGenStubId::cont_thaw_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_top); return start; @@ -4021,7 +4080,8 @@ class StubGenerator: public StubCodeGenerator { if (!Continuations::enabled()) return nullptr; // TODO: will probably need multiple return barriers depending on return type - StubCodeMark mark(this, "StubRoutines", "cont return barrier"); + StubGenStubId stub_id = StubGenStubId::cont_returnBarrier_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier); @@ -4032,7 +4092,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_returnBarrier_exception() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines", "cont return barrier exception handler"); + StubGenStubId stub_id = StubGenStubId::cont_returnBarrierExc_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier_exception); @@ -4042,7 +4103,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines","Continuation preempt stub"); + StubGenStubId stub_id = StubGenStubId::cont_preempt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ reset_last_Java_frame(true); @@ -4079,11 +4141,11 @@ class StubGenerator: public StubCodeGenerator { StubCodeGenerator* _cgen; public: Sha2Generator(MacroAssembler* masm, StubCodeGenerator* cgen) : MacroAssembler(masm->code()), _cgen(cgen) {} - address generate_sha256_implCompress(bool multi_block) { - return generate_sha2_implCompress(Assembler::e32, multi_block); + address generate_sha256_implCompress(StubGenStubId stub_id) { + return generate_sha2_implCompress(Assembler::e32, stub_id); } - address generate_sha512_implCompress(bool multi_block) { - return generate_sha2_implCompress(Assembler::e64, multi_block); + address generate_sha512_implCompress(StubGenStubId stub_id) { + return generate_sha2_implCompress(Assembler::e64, stub_id); } private: @@ -4208,15 +4270,6 @@ class StubGenerator: public StubCodeGenerator { } } - const char* stub_name(Assembler::SEW vset_sew, bool multi_block) { - if (vset_sew == Assembler::e32 && !multi_block) return "sha256_implCompress"; - if (vset_sew == Assembler::e32 && multi_block) return "sha256_implCompressMB"; - if (vset_sew == Assembler::e64 && !multi_block) return "sha512_implCompress"; - if (vset_sew == Assembler::e64 && multi_block) return "sha512_implCompressMB"; - ShouldNotReachHere(); - return "bad name lookup"; - } - // Arguments: // // Inputs: @@ -4225,7 +4278,7 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - int offset // c_rarg3 - int limit // - address generate_sha2_implCompress(Assembler::SEW vset_sew, bool multi_block) { + address generate_sha2_implCompress(Assembler::SEW vset_sew, StubGenStubId stub_id) { alignas(64) static const uint32_t round_consts_256[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, @@ -4275,8 +4328,29 @@ class StubGenerator: public StubCodeGenerator { }; const int const_add = vset_sew == Assembler::e32 ? 16 : 32; + bool multi_block; + switch (stub_id) { + case sha256_implCompress_id: + assert (vset_sew == Assembler::e32, "wrong macroassembler for stub"); + multi_block = false; + break; + case sha256_implCompressMB_id: + assert (vset_sew == Assembler::e32, "wrong macroassembler for stub"); + multi_block = true; + break; + case sha512_implCompress_id: + assert (vset_sew == Assembler::e64, "wrong macroassembler for stub"); + multi_block = false; + break; + case sha512_implCompressMB_id: + assert (vset_sew == Assembler::e64, "wrong macroassembler for stub"); + multi_block = true; + break; + default: + ShouldNotReachHere(); + }; __ align(CodeEntryAlignment); - StubCodeMark mark(_cgen, "StubRoutines", stub_name(vset_sew, multi_block)); + StubCodeMark mark(_cgen, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -4437,8 +4511,8 @@ class StubGenerator: public StubCodeGenerator { if (multi_block) { int total_adds = vset_sew == Assembler::e32 ? 240 : 608; - __ addi(consts, consts, -total_adds); - __ add(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128); + __ subi(consts, consts, total_adds); + __ addi(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128); __ ble(ofs, limit, multi_block_loop); __ mv(c_rarg0, ofs); // return ofs } @@ -4516,7 +4590,7 @@ class StubGenerator: public StubCodeGenerator { __ addw(a, a, value); // a = Integer.rotateLeft(a, s) + b; - __ rolw_imm(a, a, s); + __ rolw(a, a, s); __ addw(a, a, b); } @@ -4623,9 +4697,20 @@ class StubGenerator: public StubCodeGenerator { // x29 t4 buf5 // x30 t5 buf6 // x31 t6 buf7 - address generate_md5_implCompress(bool multi_block, const char *name) { + address generate_md5_implCompress(StubGenStubId stub_id) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + bool multi_block; + switch (stub_id) { + case md5_implCompress_id: + multi_block = false; + break; + case md5_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + }; + StubCodeMark mark(this, stub_id); address start = __ pc(); // rotation constants @@ -4879,7 +4964,8 @@ class StubGenerator: public StubCodeGenerator { Label L_Rounds; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "chacha20Block"); + StubGenStubId stub_id = StubGenStubId::chacha20Block_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -4932,7 +5018,7 @@ class StubGenerator: public StubCodeGenerator { chacha20_quarter_round(work_vrs[2], work_vrs[7], work_vrs[8], work_vrs[13], tmp_vr); chacha20_quarter_round(work_vrs[3], work_vrs[4], work_vrs[9], work_vrs[14], tmp_vr); - __ sub(loop, loop, 1); + __ subi(loop, loop, 1); __ bnez(loop, L_Rounds); } @@ -5021,7 +5107,7 @@ class StubGenerator: public StubCodeGenerator { __ xorr(cur_w, cur_w, t1); __ xorr(cur_w, cur_w, t0); - __ rolw_imm(cur_w, cur_w, 1, t0); + __ rolw(cur_w, cur_w, 1, t0); // copy the cur_w value to ws[8]. // now, valid w't values are at: @@ -5041,7 +5127,7 @@ class StubGenerator: public StubCodeGenerator { __ xorr(cur_w, ws[(idx-16)/2], ws[(idx-14)/2]); __ xorr(cur_w, cur_w, t0); - __ rolw_imm(cur_w, cur_w, 1, t0); + __ rolw(cur_w, cur_w, 1, t0); // copy the cur_w value to ws[8] __ zext(cur_w, cur_w, 32); @@ -5106,7 +5192,7 @@ class StubGenerator: public StubCodeGenerator { Register tmp3 = e; __ add(tmp2, cur_k, tmp2); __ add(tmp3, tmp3, tmp2); - __ rolw_imm(tmp2, a, 5, t0); + __ rolw(tmp2, a, 5, t0); sha1_f(tmp, b, c, d, round); @@ -5121,7 +5207,7 @@ class StubGenerator: public StubCodeGenerator { __ mv(e, d); __ mv(d, c); - __ rolw_imm(c, b, 30); + __ rolw(c, b, 30); __ mv(b, a); __ mv(a, tmp2); } @@ -5178,9 +5264,20 @@ class StubGenerator: public StubCodeGenerator { // - - - - - - below are only for implCompressMultiBlock0 - - - - - - // c_rarg0: int offset, when (multi_block == true) // - address generate_sha1_implCompress(bool multi_block, const char *name) { + address generate_sha1_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha1_implCompress_id: + multi_block = false; + break; + case sha1_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -5390,7 +5487,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "encodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_encodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -5512,7 +5610,7 @@ class StubGenerator: public StubCodeGenerator { __ sb(byte2, Address(dst, 2)); __ sb(combined24Bits, Address(dst, 3)); - __ sub(length, length, 3); + __ subi(length, length, 3); __ addi(dst, dst, 4); // loop back __ bnez(length, ScalarLoop); @@ -5646,7 +5744,8 @@ class StubGenerator: public StubCodeGenerator { }; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "decodeBlock"); + StubGenStubId stub_id = StubGenStubId::base64_decodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -5789,7 +5888,7 @@ class StubGenerator: public StubCodeGenerator { __ sb(byte1, Address(dst, 1)); __ sb(combined32Bits, Address(dst, 2)); - __ sub(length, length, 4); + __ subi(length, length, 4); __ addi(dst, dst, 3); // loop back __ bnez(length, ScalarLoop); @@ -5890,7 +5989,8 @@ class StubGenerator: public StubCodeGenerator { */ address generate_updateBytesAdler32() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesAdler32"); + StubGenStubId stub_id = StubGenStubId::updateBytesAdler32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_nmax, L_nmax_loop, L_nmax_loop_entry, L_by16, L_by16_loop, @@ -5972,23 +6072,23 @@ class StubGenerator: public StubCodeGenerator { __ beqz(len, L_combine); // Jumping to L_by1_loop - __ sub(len, len, step_1); + __ subi(len, len, step_1); __ j(L_by1_loop); __ bind(L_nmax); __ sub(len, len, nmax); - __ sub(count, nmax, 16); + __ subi(count, nmax, 16); __ bltz(len, L_by16); // Align L_nmax loop by 64 __ bind(L_nmax_loop_entry); - __ sub(count, count, 32); + __ subi(count, count, 32); __ bind(L_nmax_loop); adler32_process_bytes(buff, s1, s2, vtable_64, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_64, Assembler::m4); - __ sub(count, count, step_64); + __ subi(count, count, step_64); __ bgtz(count, L_nmax_loop); // There are three iterations left to do @@ -6005,7 +6105,7 @@ class StubGenerator: public StubCodeGenerator { __ remuw(s2, s2, base); __ sub(len, len, nmax); - __ sub(count, nmax, 16); + __ subi(count, nmax, 16); __ bgez(len, L_nmax_loop_entry); __ bind(L_by16); @@ -6019,7 +6119,7 @@ class StubGenerator: public StubCodeGenerator { adler32_process_bytes(buff, s1, s2, vtable_64, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_64, Assembler::m4); - __ sub(len, len, step_64); + __ subi(len, len, step_64); // By now the temp3 should still be 64 __ bge(len, temp3, L_by16_loop_unroll); @@ -6027,11 +6127,11 @@ class StubGenerator: public StubCodeGenerator { adler32_process_bytes(buff, s1, s2, vtable_16, vzero, vbytes, vs1acc, vs2acc, temp0, temp1, temp2, temp3, vtemp1, vtemp2, step_16, Assembler::m1); - __ sub(len, len, step_16); + __ subi(len, len, step_16); __ bgez(len, L_by16_loop); __ bind(L_by1); - __ add(len, len, 15); + __ addi(len, len, 15); __ bltz(len, L_do_mod); __ bind(L_by1_loop); @@ -6039,7 +6139,7 @@ class StubGenerator: public StubCodeGenerator { __ addi(buff, buff, step_1); __ add(s1, temp0, s1); __ add(s2, s2, s1); - __ sub(len, len, step_1); + __ subi(len, len, step_1); __ bgez(len, L_by1_loop); __ bind(L_do_mod); @@ -6148,7 +6248,8 @@ static const int64_t right_3_bits = right_n_bits(3); address generate_poly1305_processBlocks() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "poly1305_processBlocks"); + StubGenStubId stub_id = StubGenStubId::poly1305_processBlocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); Label here; @@ -6221,7 +6322,7 @@ static const int64_t right_3_bits = right_n_bits(3); // U_2:U_1:U_0: += (U_2 >> 2) * 5 poly1305_reduce(U_2, U_1, U_0, t1, t2); - __ sub(length, length, BLOCK_LENGTH); + __ subi(length, length, BLOCK_LENGTH); __ addi(input_start, input_start, BLOCK_LENGTH); __ mv(t1, BLOCK_LENGTH); __ bge(length, t1, LOOP); @@ -6337,7 +6438,8 @@ static const int64_t right_3_bits = right_n_bits(3); assert(UseCRC32Intrinsics, "what are we doing here?"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -6361,7 +6463,8 @@ static const int64_t right_3_bits = right_n_bits(3); // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { - StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_exception_handler_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Native caller has no idea how to handle exceptions, @@ -6378,7 +6481,8 @@ static const int64_t right_3_bits = right_n_bits(3); // xmethod = Method* result address generate_upcall_stub_load_target() { - StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_load_target_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ resolve_global_jobject(j_rarg0, t0, t1); @@ -6453,10 +6557,7 @@ static const int64_t right_3_bits = right_n_bits(3); if (UseSecondarySupersTable) { StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); if (!InlineSecondarySupersTest) { - for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] - = generate_lookup_secondary_supers_table_stub(slot); - } + generate_lookup_secondary_supers_table_stub(); } } #endif // COMPILER2 @@ -6482,13 +6583,15 @@ static const int64_t right_3_bits = right_n_bits(3); } if (UseMontgomeryMultiplyIntrinsic) { - StubCodeMark mark(this, "StubRoutines", "montgomeryMultiply"); + StubGenStubId stub_id = StubGenStubId::montgomeryMultiply_id; + StubCodeMark mark(this, stub_id); MontgomeryMultiplyGenerator g(_masm, /*squaring*/false); StubRoutines::_montgomeryMultiply = g.generate_multiply(); } if (UseMontgomerySquareIntrinsic) { - StubCodeMark mark(this, "StubRoutines", "montgomerySquare"); + StubGenStubId stub_id = StubGenStubId::montgomerySquare_id; + StubCodeMark mark(this, stub_id); MontgomeryMultiplyGenerator g(_masm, /*squaring*/true); StubRoutines::_montgomerySquare = g.generate_square(); } @@ -6509,19 +6612,19 @@ static const int64_t right_3_bits = right_n_bits(3); if (UseSHA256Intrinsics) { Sha2Generator sha2(_masm, this); - StubRoutines::_sha256_implCompress = sha2.generate_sha256_implCompress(false); - StubRoutines::_sha256_implCompressMB = sha2.generate_sha256_implCompress(true); + StubRoutines::_sha256_implCompress = sha2.generate_sha256_implCompress(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = sha2.generate_sha256_implCompress(StubGenStubId::sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { Sha2Generator sha2(_masm, this); - StubRoutines::_sha512_implCompress = sha2.generate_sha512_implCompress(false); - StubRoutines::_sha512_implCompressMB = sha2.generate_sha512_implCompress(true); + StubRoutines::_sha512_implCompress = sha2.generate_sha512_implCompress(StubGenStubId::sha512_implCompress_id); + StubRoutines::_sha512_implCompressMB = sha2.generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } if (UseMD5Intrinsics) { - StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); - StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); + StubRoutines::_md5_implCompress = generate_md5_implCompress(StubGenStubId::md5_implCompress_id); + StubRoutines::_md5_implCompressMB = generate_md5_implCompress(StubGenStubId::md5_implCompressMB_id); } if (UseChaCha20Intrinsics) { @@ -6529,8 +6632,8 @@ static const int64_t right_3_bits = right_n_bits(3); } if (UseSHA1Intrinsics) { - StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); - StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); + StubRoutines::_sha1_implCompress = generate_sha1_implCompress(StubGenStubId::sha1_implCompress_id); + StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(StubGenStubId::sha1_implCompressMB_id); } if (UseBASE64Intrinsics) { @@ -6552,27 +6655,27 @@ static const int64_t right_3_bits = right_n_bits(3); } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp index 66a3ac3a994d5..2a1150276c1be 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" @@ -34,14 +33,19 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::riscv::_zero_blocks = nullptr; -address StubRoutines::riscv::_compare_long_string_LL = nullptr; -address StubRoutines::riscv::_compare_long_string_UU = nullptr; -address StubRoutines::riscv::_compare_long_string_LU = nullptr; -address StubRoutines::riscv::_compare_long_string_UL = nullptr; -address StubRoutines::riscv::_string_indexof_linear_ll = nullptr; -address StubRoutines::riscv::_string_indexof_linear_uu = nullptr; -address StubRoutines::riscv::_string_indexof_linear_ul = nullptr; + +// define fields for arch-specific entries + +#define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr; + +#define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function); + +STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) + +#undef DEFINE_ARCH_ENTRY_INIT +#undef DEFINE_ARCH_ENTRY bool StubRoutines::riscv::_completed = false; diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp index 3bc5aeaa26826..1cd10b996dbcf 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp @@ -35,63 +35,53 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + enum platform_dependent_constants { - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 10000, - _continuation_stubs_code_size = 2000, - _compiler_stubs_code_size = 45000, - _final_stubs_code_size = 20000 ZGC_ONLY(+10000) + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + class riscv { friend class StubGenerator; +#if INCLUDE_JVMCI + friend class JVMCIVMStructs; +#endif - private: - static address _zero_blocks; + // declare fields for arch-specific entries - static address _compare_long_string_LL; - static address _compare_long_string_LU; - static address _compare_long_string_UL; - static address _compare_long_string_UU; - static address _string_indexof_linear_ll; - static address _string_indexof_linear_uu; - static address _string_indexof_linear_ul; +#define DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + static address STUB_FIELD_NAME(field_name) ; - static bool _completed; +#define DECLARE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) - public: +private: + STUBGEN_ARCH_ENTRIES_DO(DECLARE_ARCH_ENTRY, DECLARE_ARCH_ENTRY_INIT) - static address zero_blocks() { - return _zero_blocks; - } +#undef DECLARE_ARCH_ENTRY_INIT +#undef DECLARE_ARCH_ENTRY - static address compare_long_string_LL() { - return _compare_long_string_LL; - } + static bool _completed; - static address compare_long_string_LU() { - return _compare_long_string_LU; - } + public: - static address compare_long_string_UL() { - return _compare_long_string_UL; - } + // declare getters for arch-specific entries - static address compare_long_string_UU() { - return _compare_long_string_UU; - } +#define DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) \ + static address getter_name() { return STUB_FIELD_NAME(field_name) ; } - static address string_indexof_linear_ul() { - return _string_indexof_linear_ul; - } +#define DEFINE_ARCH_ENTRY_GETTER_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) - static address string_indexof_linear_ll() { - return _string_indexof_linear_ll; - } + STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY_GETTER, DEFINE_ARCH_ENTRY_GETTER_INIT) - static address string_indexof_linear_uu() { - return _string_indexof_linear_uu; - } +#undef DEFINE_ARCH_ENTRY_GETTER_INIT +#undef DEFINE_ARCH_ENTRY_GETTER static bool complete() { return _completed; diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index bc67de54c4bc6..79de9becbaedc 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "compiler/disassembler.hpp" @@ -85,8 +84,8 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // c_rarg3: first stack arg - wordSize // adjust sp - __ addi(sp, c_rarg3, -18 * wordSize); - __ addi(sp, sp, -2 * wordSize); + __ subi(sp, c_rarg3, 18 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(ra, Address(sp, 0)); __ call_VM(noreg, @@ -189,7 +188,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dsin()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_cos : @@ -202,7 +201,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dcos()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_tan : @@ -215,7 +214,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dtan()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_log : @@ -228,7 +227,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_log10 : @@ -241,7 +240,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dlog10()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_exp : @@ -254,7 +253,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dexp()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_pow : @@ -268,7 +267,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } else { fn = CAST_FROM_FN_PTR(address, StubRoutines::dpow()); } - __ call(fn); + __ rt_call(fn); __ mv(ra, x9); break; case Interpreter::java_lang_math_fmaD : @@ -714,14 +713,14 @@ void TemplateInterpreterGenerator::lock_method() { const int entry_size = frame::interpreter_frame_monitor_size_in_bytes(); #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method doesn't need synchronization", false); #endif // ASSERT // get synchronization object { Label done; - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ andi(t0, x10, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ ld(x10, Address(xlocals, Interpreter::local_offset_in_bytes(0))); @@ -742,8 +741,8 @@ void TemplateInterpreterGenerator::lock_method() { // add space for monitor & lock __ check_extended_sp(); - __ add(sp, sp, - entry_size); // add space for a monitor entry - __ add(esp, esp, - entry_size); + __ sub(sp, sp, entry_size); // add space for a monitor entry + __ sub(esp, esp, entry_size); __ sub(t0, sp, fp); __ srai(t0, t0, Interpreter::logStackElementSize); __ sd(t0, Address(fp, frame::interpreter_frame_extended_sp_offset * wordSize)); @@ -768,17 +767,17 @@ void TemplateInterpreterGenerator::lock_method() { void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame if (native_call) { - __ add(esp, sp, - 14 * wordSize); + __ subi(esp, sp, 14 * wordSize); __ mv(xbcp, zr); - __ add(sp, sp, - 14 * wordSize); + __ subi(sp, sp, 14 * wordSize); // add 2 zero-initialized slots for native calls __ sd(zr, Address(sp, 13 * wordSize)); __ sd(zr, Address(sp, 12 * wordSize)); } else { - __ add(esp, sp, - 12 * wordSize); + __ subi(esp, sp, 12 * wordSize); __ ld(t0, Address(xmethod, Method::const_offset())); // get ConstMethod __ add(xbcp, t0, in_bytes(ConstMethod::codes_offset())); // get codebase - __ add(sp, sp, - 12 * wordSize); + __ subi(sp, sp, 12 * wordSize); } __ sd(xbcp, Address(sp, wordSize)); __ mv(t0, frame::interpreter_frame_initial_sp_offset); @@ -833,7 +832,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { } else { // Make sure there is room for the exception oop pushed in case method throws // an exception (see TemplateInterpreterGenerator::generate_throw_exception()) - __ sub(t0, sp, 2 * wordSize); + __ subi(t0, sp, 2 * wordSize); __ sub(t1, t0, fp); __ srai(t1, t1, Interpreter::logStackElementSize); __ sd(t1, Address(sp, 5 * wordSize)); @@ -1018,7 +1017,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // compute beginning of parameters (xlocals) __ shadd(xlocals, x12, esp, xlocals, 3); - __ addi(xlocals, xlocals, -wordSize); + __ subi(xlocals, xlocals, wordSize); // Pull SP back to minimum size: this avoids holes in the stack __ andi(sp, esp, -16); @@ -1028,7 +1027,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute non-native method as native", false); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1066,7 +1065,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } @@ -1130,7 +1129,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_STATIC)); __ beqz(t0, L); // get mirror @@ -1175,7 +1174,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { { Label L; __ lwu(t, Address(xthread, JavaThread::thread_state_offset())); - __ addi(t0, zr, (u1)_thread_in_Java); + __ mv(t0, (u1)_thread_in_Java); __ beq(t, t0, L); __ stop("Wrong thread state in native stub"); __ bind(L); @@ -1202,7 +1201,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ restore_cpu_control_state_after_jni(t0); // make room for the pushes we're about to do - __ sub(t0, esp, 4 * wordSize); + __ subi(t0, esp, 4 * wordSize); __ andi(sp, t0, -16); // NOTE: The order of these pushes is known to frame::interpreter_frame_result @@ -1308,7 +1307,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { { Label no_reguard; __ lwu(t0, Address(xthread, in_bytes(JavaThread::stack_guard_state_offset()))); - __ addi(t1, zr, (u1)StackOverflow::stack_guard_yellow_reserved_disabled); + __ mv(t1, (u1)StackOverflow::stack_guard_yellow_reserved_disabled); __ bne(t0, t1, no_reguard); __ push_call_clobbered_registers(); @@ -1346,7 +1345,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ lwu(t, Address(xmethod, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(xmethod, Method::access_flags_offset())); __ test_bit(t0, t, exact_log2(JVM_ACC_SYNCHRONIZED)); __ beqz(t0, L); // the code below should be shared with interpreter macro @@ -1440,7 +1439,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // compute beginning of parameters (xlocals) __ shadd(xlocals, x12, esp, t1, 3); - __ add(xlocals, xlocals, -wordSize); + __ subi(xlocals, xlocals, wordSize); // Make room for additional locals __ slli(t1, x13, 3); @@ -1458,8 +1457,8 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { __ blez(x13, exit); // do nothing if x13 <= 0 __ bind(loop); __ sd(zr, Address(t0)); - __ add(t0, t0, wordSize); - __ add(x13, x13, -1); // until everything initialized + __ addi(t0, t0, wordSize); + __ subi(x13, x13, 1); // until everything initialized __ bnez(x13, loop); __ bind(exit); } @@ -1472,7 +1471,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_NATIVE, "tried to execute native method as non-native"); __ verify_access_flags(x10, JVM_ACC_ABSTRACT, "tried to execute abstract method in interpreter"); #endif @@ -1519,7 +1518,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { } else { // no synchronization necessary #ifdef ASSERT - __ lwu(x10, access_flags); + __ load_unsigned_short(x10, access_flags); __ verify_access_flags(x10, JVM_ACC_SYNCHRONIZED, "method needs synchronization"); #endif } @@ -1650,7 +1649,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ slli(x10, x10, Interpreter::logStackElementSize); __ restore_locals(); __ sub(xlocals, xlocals, x10); - __ add(xlocals, xlocals, wordSize); + __ addi(xlocals, xlocals, wordSize); // Save these arguments __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization:: @@ -1745,7 +1744,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // sp: expression stack of caller // fp: fp of caller // FIXME: There's no point saving ra here because VM calls don't trash it - __ sub(sp, sp, 2 * wordSize); + __ subi(sp, sp, 2 * wordSize); __ sd(x10, Address(sp, 0)); // save exception __ sd(ra, Address(sp, wordSize)); // save return address __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, @@ -1754,7 +1753,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ mv(x11, x10); // save exception handler __ ld(x10, Address(sp, 0)); // restore exception __ ld(ra, Address(sp, wordSize)); // restore return address - __ add(sp, sp, 2 * wordSize); + __ addi(sp, sp, 2 * wordSize); // We might be returning to a deopt handler that expects x13 to // contain the exception pc __ mv(x13, ra); diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index e51604569f688..cb4ded3c330b6 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -197,7 +196,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, Label L_fast_patch; // if a breakpoint is present we can't rewrite the stream directly __ load_unsigned_byte(temp_reg, at_bcp(0)); - __ addi(temp_reg, temp_reg, -Bytecodes::_breakpoint); // temp_reg is temporary register. + __ subi(temp_reg, temp_reg, Bytecodes::_breakpoint); // temp_reg is temporary register. __ bnez(temp_reg, L_fast_patch); // Let breakpoint table handling rewrite to quicker bytecode __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), xmethod, xbcp, bc_reg); @@ -209,7 +208,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, Label L_okay; __ load_unsigned_byte(temp_reg, at_bcp(0)); __ beq(temp_reg, bc_reg, L_okay); - __ addi(temp_reg, temp_reg, -(int) Bytecodes::java_code(bc)); + __ subi(temp_reg, temp_reg, (int)Bytecodes::java_code(bc)); __ beqz(temp_reg, L_okay); __ stop("patching the wrong bytecode"); __ bind(L_okay); @@ -737,7 +736,7 @@ void TemplateTable::iaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); __ shadd(x10, x11, x10, t0, 2); __ access_load_at(T_INT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); __ sext(x10, x10, 32); @@ -750,7 +749,7 @@ void TemplateTable::laload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); __ shadd(x10, x11, x10, t0, 3); __ access_load_at(T_LONG, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -762,7 +761,7 @@ void TemplateTable::faload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); __ shadd(x10, x11, x10, t0, 2); __ access_load_at(T_FLOAT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -774,7 +773,7 @@ void TemplateTable::daload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); __ shadd(x10, x11, x10, t0, 3); __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -786,7 +785,7 @@ void TemplateTable::aaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); __ shadd(x10, x11, x10, t0, LogBytesPerHeapOop); do_oop_load(_masm, Address(x10), x10, IS_ARRAY); } @@ -798,7 +797,7 @@ void TemplateTable::baload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); __ shadd(x10, x11, x10, t0, 0); __ access_load_at(T_BYTE, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -810,7 +809,7 @@ void TemplateTable::caload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -826,7 +825,7 @@ void TemplateTable::fast_icaload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11, kills t0 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); // addi, max imm is 2^11 + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); // addi, max imm is 2^11 __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -838,7 +837,7 @@ void TemplateTable::saload() { // x10: array // x11: index index_check(x10, x11); // leaves index in x11, kills t0 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_SHORT) >> 1); __ shadd(x10, x11, x10, t0, 1); __ access_load_at(T_SHORT, IN_HEAP | IS_ARRAY, x10, Address(x10), noreg, noreg); } @@ -1017,7 +1016,7 @@ void TemplateTable::iastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_INT) >> 2); __ shadd(t0, x11, x13, t0, 2); __ access_store_at(T_INT, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1030,7 +1029,7 @@ void TemplateTable::lastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_LONG) >> 3); __ shadd(t0, x11, x13, t0, 3); __ access_store_at(T_LONG, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1043,7 +1042,7 @@ void TemplateTable::fastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_FLOAT) >> 2); __ shadd(t0, x11, x13, t0, 2); __ access_store_at(T_FLOAT, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* ftos */, noreg, noreg, noreg); } @@ -1056,7 +1055,7 @@ void TemplateTable::dastore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) >> 3); __ shadd(t0, x11, x13, t0, 3); __ access_store_at(T_DOUBLE, IN_HEAP | IS_ARRAY, Address(t0, 0), noreg /* dtos */, noreg, noreg, noreg); } @@ -1070,7 +1069,7 @@ void TemplateTable::aastore() { __ ld(x13, at_tos_p2()); // array index_check(x13, x12); // kills x11 - __ add(x14, x12, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); + __ addi(x14, x12, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); __ shadd(x14, x14, x13, x14, LogBytesPerHeapOop); Address element_address(x14, 0); @@ -1112,7 +1111,7 @@ void TemplateTable::aastore() { // Pop stack arguments __ bind(done); - __ add(esp, esp, 3 * Interpreter::stackElementSize); + __ addi(esp, esp, 3 * Interpreter::stackElementSize); } void TemplateTable::bastore() { @@ -1134,7 +1133,7 @@ void TemplateTable::bastore() { __ andi(x10, x10, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 __ bind(L_skip); - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_BYTE) >> 0); __ add(x11, x13, x11); __ access_store_at(T_BYTE, IN_HEAP | IS_ARRAY, Address(x11, 0), x10, noreg, noreg, noreg); @@ -1148,7 +1147,7 @@ void TemplateTable::castore() { // x11: index // x13: array index_check(x13, x11); // prefer index in x11 - __ add(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); + __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_CHAR) >> 1); __ shadd(t0, x11, x13, t0, 1); __ access_store_at(T_CHAR, IN_HEAP | IS_ARRAY, Address(t0, 0), x10, noreg, noreg, noreg); } @@ -1883,7 +1882,7 @@ void TemplateTable::ret() { __ profile_ret(x11, x12); __ ld(xbcp, Address(xmethod, Method::const_offset())); __ add(xbcp, xbcp, x11); - __ addi(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); + __ add(xbcp, xbcp, in_bytes(ConstMethod::codes_offset())); __ dispatch_next(vtos, 0, /*generate_poll*/true); } @@ -1958,7 +1957,7 @@ void TemplateTable::fast_linearswitch() { __ lw(t0, Address(t0, 2 * BytesPerInt)); __ beq(x10, t0, found); __ bind(loop_entry); - __ addi(x11, x11, -1); + __ subi(x11, x11, 1); __ bgez(x11, loop); // default case __ profile_switch_default(x10); @@ -2544,7 +2543,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notByte); - __ sub(t0, tos_state, (u1)ztos); + __ subi(t0, tos_state, (u1)ztos); __ bnez(t0, notBool); // ztos (same code as btos) @@ -2558,7 +2557,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notBool); - __ sub(t0, tos_state, (u1)atos); + __ subi(t0, tos_state, (u1)atos); __ bnez(t0, notObj); // atos do_oop_load(_masm, field, x10, IN_HEAP); @@ -2569,7 +2568,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notObj); - __ sub(t0, tos_state, (u1)itos); + __ subi(t0, tos_state, (u1)itos); __ bnez(t0, notInt); // itos __ access_load_at(T_INT, IN_HEAP, x10, field, noreg, noreg); @@ -2582,7 +2581,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notInt); - __ sub(t0, tos_state, (u1)ctos); + __ subi(t0, tos_state, (u1)ctos); __ bnez(t0, notChar); // ctos __ access_load_at(T_CHAR, IN_HEAP, x10, field, noreg, noreg); @@ -2594,7 +2593,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notChar); - __ sub(t0, tos_state, (u1)stos); + __ subi(t0, tos_state, (u1)stos); __ bnez(t0, notShort); // stos __ access_load_at(T_SHORT, IN_HEAP, x10, field, noreg, noreg); @@ -2606,7 +2605,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notShort); - __ sub(t0, tos_state, (u1)ltos); + __ subi(t0, tos_state, (u1)ltos); __ bnez(t0, notLong); // ltos __ access_load_at(T_LONG, IN_HEAP, x10, field, noreg, noreg); @@ -2618,7 +2617,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ j(Done); __ bind(notLong); - __ sub(t0, tos_state, (u1)ftos); + __ subi(t0, tos_state, (u1)ftos); __ bnez(t0, notFloat); // ftos __ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg); @@ -2631,7 +2630,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ bind(notFloat); #ifdef ASSERT - __ sub(t0, tos_state, (u1)dtos); + __ subi(t0, tos_state, (u1)dtos); __ bnez(t0, notDouble); #endif // dtos @@ -2696,9 +2695,9 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is __ load_unsigned_byte(c_rarg3, Address(c_rarg2, in_bytes(ResolvedFieldEntry::type_offset()))); Label nope2, done, ok; __ ld(c_rarg1, at_tos_p1()); // initially assume a one word jvalue - __ sub(t0, c_rarg3, ltos); + __ subi(t0, c_rarg3, (u1)ltos); __ beqz(t0, ok); - __ sub(t0, c_rarg3, dtos); + __ subi(t0, c_rarg3, (u1)dtos); __ bnez(t0, nope2); __ bind(ok); __ ld(c_rarg1, at_tos_p2()); // ltos (two word jvalue); @@ -2772,7 +2771,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notByte); - __ sub(t0, tos_state, (u1)ztos); + __ subi(t0, tos_state, (u1)ztos); __ bnez(t0, notBool); // ztos @@ -2792,7 +2791,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notBool); - __ sub(t0, tos_state, (u1)atos); + __ subi(t0, tos_state, (u1)atos); __ bnez(t0, notObj); // atos @@ -2813,7 +2812,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notObj); - __ sub(t0, tos_state, (u1)itos); + __ subi(t0, tos_state, (u1)itos); __ bnez(t0, notInt); // itos @@ -2833,7 +2832,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notInt); - __ sub(t0, tos_state, (u1)ctos); + __ subi(t0, tos_state, (u1)ctos); __ bnez(t0, notChar); // ctos @@ -2853,7 +2852,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notChar); - __ sub(t0, tos_state, (u1)stos); + __ subi(t0, tos_state, (u1)stos); __ bnez(t0, notShort); // stos @@ -2873,7 +2872,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notShort); - __ sub(t0, tos_state, (u1)ltos); + __ subi(t0, tos_state, (u1)ltos); __ bnez(t0, notLong); // ltos @@ -2893,7 +2892,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr } __ bind(notLong); - __ sub(t0, tos_state, (u1)ftos); + __ subi(t0, tos_state, (u1)ftos); __ bnez(t0, notFloat); // ftos @@ -2914,7 +2913,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ bind(notFloat); #ifdef ASSERT - __ sub(t0, tos_state, (u1)dtos); + __ subi(t0, tos_state, (u1)dtos); __ bnez(t0, notDouble); #endif @@ -3207,7 +3206,7 @@ void TemplateTable::fast_xaccess(TosState state) { __ bind(notVolatile); } - __ sub(xbcp, xbcp, 1); + __ subi(xbcp, xbcp, 1); } //----------------------------------------------------------------------------- @@ -3521,7 +3520,7 @@ void TemplateTable::_new() { __ la(t0, Address(t0, tags_offset)); __ lbu(t0, t0); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t1, t0, (u1)JVM_CONSTANT_Class); + __ subi(t1, t0, (u1)JVM_CONSTANT_Class); __ bnez(t1, slow_case); // get InstanceKlass @@ -3558,9 +3557,9 @@ void TemplateTable::_new() { // zero, go directly to the header initialization. if (UseCompactObjectHeaders) { assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned"); - __ sub(x13, x13, oopDesc::base_offset_in_bytes()); + __ subi(x13, x13, oopDesc::base_offset_in_bytes()); } else { - __ sub(x13, x13, sizeof(oopDesc)); + __ subi(x13, x13, sizeof(oopDesc)); } __ beqz(x13, initialize_header); @@ -3568,15 +3567,15 @@ void TemplateTable::_new() { { if (UseCompactObjectHeaders) { assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned"); - __ add(x12, x10, oopDesc::base_offset_in_bytes()); + __ addi(x12, x10, oopDesc::base_offset_in_bytes()); } else { - __ add(x12, x10, sizeof(oopDesc)); + __ addi(x12, x10, sizeof(oopDesc)); } Label loop; __ bind(loop); __ sd(zr, Address(x12)); - __ add(x12, x12, BytesPerLong); - __ sub(x13, x13, BytesPerLong); + __ addi(x12, x12, BytesPerLong); + __ subi(x13, x13, BytesPerLong); __ bnez(x13, loop); } @@ -3649,11 +3648,11 @@ void TemplateTable::checkcast() { __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index // See if bytecode has already been quicked - __ add(t0, x13, Array::base_offset_in_bytes()); + __ addi(t0, x13, Array::base_offset_in_bytes()); __ add(x11, t0, x9); __ lbu(x11, x11); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t0, x11, (u1)JVM_CONSTANT_Class); + __ subi(t0, x11, (u1)JVM_CONSTANT_Class); __ beqz(t0, quicked); __ push(atos); // save receiver for result, and for GC @@ -3704,11 +3703,11 @@ void TemplateTable::instanceof() { __ get_cpool_and_tags(x12, x13); // x12=cpool, x13=tags array __ get_unsigned_2_byte_index_at_bcp(x9, 1); // x9=index // See if bytecode has already been quicked - __ add(t0, x13, Array::base_offset_in_bytes()); + __ addi(t0, x13, Array::base_offset_in_bytes()); __ add(x11, t0, x9); __ lbu(x11, x11); __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); - __ sub(t0, x11, (u1)JVM_CONSTANT_Class); + __ subi(t0, x11, (u1)JVM_CONSTANT_Class); __ beqz(t0, quicked); __ push(atos); // save receiver for result, and for GC @@ -3884,7 +3883,7 @@ void TemplateTable::monitorenter() { __ ld(c_rarg2, Address(c_rarg3, entry_size)); // load expression stack // word from old location __ sd(c_rarg2, Address(c_rarg3, 0)); // and store it at new location - __ add(c_rarg3, c_rarg3, wordSize); // advance to next word + __ addi(c_rarg3, c_rarg3, wordSize); // advance to next word __ bind(entry); __ bne(c_rarg3, c_rarg1, loop); // check if bottom reached.if not at bottom // then copy next word @@ -3979,7 +3978,7 @@ void TemplateTable::multianewarray() { // last dim is on top of stack; we want address of first one: // first_addr = last_addr + (ndims - 1) * wordSize __ shadd(c_rarg1, x10, esp, c_rarg1, 3); - __ sub(c_rarg1, c_rarg1, wordSize); + __ subi(c_rarg1, c_rarg1, wordSize); call_VM(x10, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), c_rarg1); diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index 8fb0530d98fa1..fa6fe60b71e3d 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "logging/logStream.hpp" diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index a30ae45160611..5d7ed4bda601c 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "runtime/java.hpp" #include "runtime/os.inline.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 59b41892fef0c..68665d12378a7 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -115,6 +115,7 @@ class VM_Version : public Abstract_VM_Version { // Zbs Single-bit instructions // // Zfh Half-Precision Floating-Point instructions + // Zfhmin Minimal Half-Precision Floating-Point instructions // // Zicond Conditional operations // @@ -156,8 +157,11 @@ class VM_Version : public Abstract_VM_Version { decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \ decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \ + decl(ext_Zfa , "Zfa" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \ decl(ext_Zfh , "Zfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \ + decl(ext_Zfhmin , "Zfhmin" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \ decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zicntr , "Zicntr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \ decl(ext_Ztso , "Ztso" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \ @@ -223,6 +227,8 @@ class VM_Version : public Abstract_VM_Version { RV_ENABLE_EXTENSION(UseZbb) \ RV_ENABLE_EXTENSION(UseZbs) \ RV_ENABLE_EXTENSION(UseZcb) \ + RV_ENABLE_EXTENSION(UseZfa) \ + RV_ENABLE_EXTENSION(UseZfhmin) \ RV_ENABLE_EXTENSION(UseZic64b) \ RV_ENABLE_EXTENSION(UseZicbom) \ RV_ENABLE_EXTENSION(UseZicbop) \ diff --git a/src/hotspot/cpu/riscv/vmreg_riscv.cpp b/src/hotspot/cpu/riscv/vmreg_riscv.cpp index ce11df57f84f3..dfc55062344ee 100644 --- a/src/hotspot/cpu/riscv/vmreg_riscv.cpp +++ b/src/hotspot/cpu/riscv/vmreg_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" #include "vmreg_riscv.inline.hpp" diff --git a/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp b/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp index 573c5d901fcfd..d889141c74437 100644 --- a/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/vtableStubs_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp index c24c2b56bf7a9..37aa9d9a0e8a3 100644 --- a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp +++ b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "oops/constMethod.hpp" #include "oops/klass.inline.hpp" @@ -191,7 +190,7 @@ void AbstractInterpreter::layout_activation(Method* method, assert(is_bottom_frame && (sender_sp == caller->unextended_sp()), "must initialize sender_sp of bottom skeleton frame when pushing it"); } else { - assert(caller->is_entry_frame(), "is there a new frame type??"); + assert(caller->is_entry_frame() || caller->is_upcall_stub_frame(), "is there a new frame type??"); sender_sp = caller->sp(); // Call_stub only uses it's fp. } @@ -201,6 +200,8 @@ void AbstractInterpreter::layout_activation(Method* method, interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor); *interpreter_frame->interpreter_frame_cache_addr() = method->constants()->cache(); interpreter_frame->interpreter_frame_set_tos_address(tos); - interpreter_frame->interpreter_frame_set_sender_sp(sender_sp); + if (!is_bottom_frame) { + interpreter_frame->interpreter_frame_set_sender_sp(sender_sp); + } interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp); } diff --git a/src/hotspot/cpu/s390/assembler_s390.cpp b/src/hotspot/cpu/s390/assembler_s390.cpp index 63cc7e28d5919..9a8ba8f296336 100644 --- a/src/hotspot/cpu/s390/assembler_s390.cpp +++ b/src/hotspot/cpu/s390/assembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/cpu/s390/assembler_s390.hpp b/src/hotspot/cpu/s390/assembler_s390.hpp index 1ba90b69d1748..c0cee5bd55537 100644 --- a/src/hotspot/cpu/s390/assembler_s390.hpp +++ b/src/hotspot/cpu/s390/assembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -140,7 +140,7 @@ class RelAddr { return 0; // Yet unknown branch destination. } else { guarantee(is_in_range_of_RelAddr(target, pc, shortForm), - "target not within reach at " INTPTR_FORMAT ", distance = " INTX_FORMAT, p2i(pc), (target - pc) ); + "target not within reach at " INTPTR_FORMAT ", distance = %zd", p2i(pc), (target - pc) ); return (int)((target - pc)>>1); } } diff --git a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp index e01e4458e38d3..c858a4b8cb14b 100644 --- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp +++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" diff --git a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp index 802d794c4e061..9fa6da8341ff8 100644 --- a/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp +++ b/src/hotspot/cpu/s390/c1_FrameMap_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index bb0494dc4785a..48bd5c3afdee2 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_LIRAssembler.hpp" diff --git a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp index c12f883ab58e2..8cb8cef2b6bb3 100644 --- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_Instruction.hpp" @@ -960,6 +959,11 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { x->profiled_method(), x->profiled_bci()); } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return CAST_FROM_FN_PTR(address, Runtime1::is_instance_of); +} + void LIRGenerator::do_If (If* x) { assert(x->number_of_sux() == 2, "inconsistency"); diff --git a/src/hotspot/cpu/s390/c1_LIR_s390.cpp b/src/hotspot/cpu/s390/c1_LIR_s390.cpp index 4788a398de8ab..3d36390a5ce52 100644 --- a/src/hotspot/cpu/s390/c1_LIR_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIR_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" diff --git a/src/hotspot/cpu/s390/c1_LinearScan_s390.cpp b/src/hotspot/cpu/s390/c1_LinearScan_s390.cpp index f48496f34d3ee..a5edd65ada845 100644 --- a/src/hotspot/cpu/s390/c1_LinearScan_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LinearScan_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index bc269f9353ceb..5691a2055b3a2 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index 0ada76ccef780..34b21ff3d15ca 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp index faa24bc880796..485efec6b9b68 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "opto/c2_MacroAssembler.hpp" diff --git a/src/hotspot/cpu/s390/c2_init_s390.cpp b/src/hotspot/cpu/s390/c2_init_s390.cpp index d2fa9f07f7897..ad18c71ee2f8b 100644 --- a/src/hotspot/cpu/s390/c2_init_s390.cpp +++ b/src/hotspot/cpu/s390/c2_init_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" diff --git a/src/hotspot/cpu/s390/compiledIC_s390.cpp b/src/hotspot/cpu/s390/compiledIC_s390.cpp index 7891e85b9115e..8501a0cb346a1 100644 --- a/src/hotspot/cpu/s390/compiledIC_s390.cpp +++ b/src/hotspot/cpu/s390/compiledIC_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/cpu/s390/compressedKlass_s390.cpp b/src/hotspot/cpu/s390/compressedKlass_s390.cpp index 868df0f02d7cb..06077b48f99a1 100644 --- a/src/hotspot/cpu/s390/compressedKlass_s390.cpp +++ b/src/hotspot/cpu/s390/compressedKlass_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "oops/compressedKlass.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp index 85ddc5bf18548..ad375fb20ce82 100644 --- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp index b716b9126f2c8..1ad0570bad8ab 100644 --- a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp +++ b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/vmreg.inline.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index f461aa67b08f2..01ed22c7d8620 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index 544c82d34a769..2054c3db36c50 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "registerSaver_s390.hpp" #include "gc/g1/g1CardTable.hpp" diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index 550bc9ba10938..d6fe10ac9c232 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp index a912cfcaf8253..85dcc0a4e73f3 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetNMethod_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/nativeInst.hpp" diff --git a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp index 760f77951fa03..f8f1fe839d232 100644 --- a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" diff --git a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp index f44a72c27abc1..4d37ae2e4ce5f 100644 --- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index 5e80817aaba7b..cb335e407347b 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,6 @@ // Major contributions by AHa, AS, JL, ML. -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -780,7 +779,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state, get_method(R_method); verify_oop(Z_tos, state); push(state); // Save tos/result. - testbit(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + testbit_ushort(method2_(R_method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); z_bfalse(unlocked); // Don't unlock anything if the _do_not_unlock_if_synchronized flag diff --git a/src/hotspot/cpu/s390/interpreterRT_s390.cpp b/src/hotspot/cpu/s390/interpreterRT_s390.cpp index 0f3c18144e9cb..dd5bdc071fc57 100644 --- a/src/hotspot/cpu/s390/interpreterRT_s390.cpp +++ b/src/hotspot/cpu/s390/interpreterRT_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" diff --git a/src/hotspot/cpu/s390/jniFastGetField_s390.cpp b/src/hotspot/cpu/s390/jniFastGetField_s390.cpp index 01b0bd528a8aa..f1c8095caa668 100644 --- a/src/hotspot/cpu/s390/jniFastGetField_s390.cpp +++ b/src/hotspot/cpu/s390/jniFastGetField_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index a069d6ceafbf0..83a5c61bfc6c1 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" @@ -1015,6 +1014,18 @@ void MacroAssembler::load_and_test_long(Register dst, const Address &a) { z_ltg(dst, a); } +// Test a bit in memory for 2 byte datatype. +void MacroAssembler::testbit_ushort(const Address &a, unsigned int bit) { + assert(a.index() == noreg, "no index reg allowed in testbit"); + if (bit <= 7) { + z_tm(a.disp() + 1, a.base(), 1 << bit); + } else if (bit <= 15) { + z_tm(a.disp() + 0, a.base(), 1 << (bit - 8)); + } else { + ShouldNotReachHere(); + } +} + // Test a bit in memory. void MacroAssembler::testbit(const Address &a, unsigned int bit) { assert(a.index() == noreg, "no index reg allowed in testbit"); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index 159688128189a..d45f1321e0f28 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * Copyright (c) 2024 IBM Corporation. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -199,6 +199,7 @@ class MacroAssembler: public Assembler { // Test a bit in memory. Result is reflected in CC. void testbit(const Address &a, unsigned int bit); + void testbit_ushort(const Address &a, unsigned int bit); // Test a bit in a register. Result is reflected in CC. void testbit(Register r, unsigned int bitPos); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp index d81562d9e9af0..72724fb66d110 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -75,7 +75,7 @@ inline void MacroAssembler::load_address(Register d, const Address &a) { } else if (Displacement::is_validDisp(a.disp())) { z_lay(d, a.disp(), a.indexOrR0(), a.baseOrR0()); } else { - guarantee(false, "displacement = " SIZE_FORMAT_X ", out of range for LA/LAY", a.disp()); + guarantee(false, "displacement = 0x%zx, out of range for LA/LAY", a.disp()); } } diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp index b2071e28478ea..e3de6d911be06 100644 --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/cpu/s390/nativeInst_s390.cpp b/src/hotspot/cpu/s390/nativeInst_s390.cpp index 6a6a774dfde58..9990c225a8986 100644 --- a/src/hotspot/cpu/s390/nativeInst_s390.cpp +++ b/src/hotspot/cpu/s390/nativeInst_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,6 @@ // Major contributions by JL, LS -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_s390.hpp" diff --git a/src/hotspot/cpu/s390/register_s390.cpp b/src/hotspot/cpu/s390/register_s390.cpp index 7292da43e5e0e..912984c5873dc 100644 --- a/src/hotspot/cpu/s390/register_s390.cpp +++ b/src/hotspot/cpu/s390/register_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "register_s390.hpp" const char* Register::name() const { diff --git a/src/hotspot/cpu/s390/relocInfo_s390.cpp b/src/hotspot/cpu/s390/relocInfo_s390.cpp index 8afd80df6cee6..fdaf00e2bc34a 100644 --- a/src/hotspot/cpu/s390/relocInfo_s390.cpp +++ b/src/hotspot/cpu/s390/relocInfo_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/relocInfo.hpp" #include "nativeInst_s390.hpp" diff --git a/src/hotspot/cpu/s390/runtime_s390.cpp b/src/hotspot/cpu/s390/runtime_s390.cpp index 18f40e87876c7..dfaf73b9a7c24 100644 --- a/src/hotspot/cpu/s390/runtime_s390.cpp +++ b/src/hotspot/cpu/s390/runtime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.inline.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 2396a2a71059f..9716a5d71b3e6 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/debugInfoRec.hpp" #include "code/vtableStubs.hpp" @@ -2395,7 +2394,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm Label L_skip_barrier; { // Bypass the barrier for non-static methods - __ testbit(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); + __ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT); __ z_bfalse(L_skip_barrier); // non-static } diff --git a/src/hotspot/cpu/s390/stubDeclarations_s390.hpp b/src/hotspot/cpu/s390/stubDeclarations_s390.hpp new file mode 100644 index 0000000000000..f382a319c489e --- /dev/null +++ b/src/hotspot/cpu/s390/stubDeclarations_s390.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_S390_STUBDECLARATIONS_HPP +#define CPU_S390_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 20000) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 2000) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 20000 ) \ + do_stub(compiler, partial_subtype_check) \ + do_arch_entry(zarch, compiler, partial_subtype_check, \ + partial_subtype_check, partial_subtype_check) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 20000) \ + + +#endif // CPU_S390_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 0ff7dcbeed2f7..f542c125b3639 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "registerSaver_s390.hpp" #include "gc/shared/barrierSet.hpp" @@ -119,7 +118,8 @@ class StubGenerator: public StubCodeGenerator { // Set up a new C frame, copy Java arguments, call frame manager // or native_entry, and process result. - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Register r_arg_call_wrapper_addr = Z_ARG1; @@ -459,7 +459,8 @@ class StubGenerator: public StubCodeGenerator { // pending exception stored in JavaThread that can be tested from // within the VM. address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -510,7 +511,8 @@ class StubGenerator: public StubCodeGenerator { // (Z_R14 is unchanged and is live out). // address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward_exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); #define pending_exception_offset in_bytes(Thread::pending_exception_offset()) @@ -590,7 +592,8 @@ class StubGenerator: public StubCodeGenerator { // raddr: Z_R14, blown by call // address generate_partial_subtype_check() { - StubCodeMark mark(this, "StubRoutines", "partial_subtype_check"); + StubGenStubId stub_id = StubGenStubId::partial_subtype_check_id; + StubCodeMark mark(this, stub_id); Label miss; address start = __ pc(); @@ -622,8 +625,9 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); + void generate_lookup_secondary_supers_table_stub() { + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_id; + StubCodeMark mark(this, stub_id); const Register r_super_klass = Z_ARG1, @@ -633,20 +637,20 @@ class StubGenerator: public StubCodeGenerator { r_array_base = Z_ARG5, r_bitmap = Z_R10, r_result = Z_R11; - address start = __ pc(); - - __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, - r_array_base, r_array_length, r_array_index, - r_bitmap, r_result, super_klass_index); - - __ z_br(Z_R14); + for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, + r_array_base, r_array_length, r_array_index, + r_bitmap, r_result, slot); - return start; + __ z_br(Z_R14); + } } // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub() { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table_slow_path"); + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_slow_path_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -1261,51 +1265,75 @@ class StubGenerator: public StubCodeGenerator { } } - // Generate stub for disjoint byte copy. If "aligned" is true, the - // "from" and "to" addresses are assumed to be heapword aligned. - address generate_disjoint_byte_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - - // This is the zarch specific stub generator for byte array copy. - // Refer to generate_disjoint_copy for a list of prereqs and features: - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - generate_disjoint_copy(aligned, 1, false, false); - return __ addr_at(start_off); - } - - - address generate_disjoint_short_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for short array copy. - // Refer to generate_disjoint_copy for a list of prereqs and features: - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - generate_disjoint_copy(aligned, 2, false, false); - return __ addr_at(start_off); - } - - - address generate_disjoint_int_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for int array copy. - // Refer to generate_disjoint_copy for a list of prereqs and features: - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - generate_disjoint_copy(aligned, 4, false, false); - return __ addr_at(start_off); - } - - - address generate_disjoint_long_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for long array copy. - // Refer to generate_disjoint_copy for a list of prereqs and features: + address generate_disjoint_nonoop_copy(StubGenStubId stub_id) { + bool aligned; + int element_size; + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + aligned = false; + element_size = 1; + break; + case arrayof_jbyte_disjoint_arraycopy_id: + aligned = true; + element_size = 1; + break; + case jshort_disjoint_arraycopy_id: + aligned = false; + element_size = 2; + break; + case arrayof_jshort_disjoint_arraycopy_id: + aligned = true; + element_size = 2; + break; + case jint_disjoint_arraycopy_id: + aligned = false; + element_size = 4; + break; + case arrayof_jint_disjoint_arraycopy_id: + aligned = true; + element_size = 4; + break; + case jlong_disjoint_arraycopy_id: + aligned = false; + element_size = 8; + break; + case arrayof_jlong_disjoint_arraycopy_id: + aligned = true; + element_size = 8; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - generate_disjoint_copy(aligned, 8, false, false); + generate_disjoint_copy(aligned, element_size, false, false); return __ addr_at(start_off); } - - address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_disjoint_oop_copy(StubGenStubId stub_id) { + bool aligned; + bool dest_uninitialized; + switch (stub_id) { + case oop_disjoint_arraycopy_id: + aligned = false; + dest_uninitialized = false; + break; + case arrayof_oop_disjoint_arraycopy_id: + aligned = true; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_uninit_id: + aligned = false; + dest_uninitialized = true; + break; + case arrayof_oop_disjoint_arraycopy_uninit_id: + aligned = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); // This is the zarch specific stub generator for oop array copy. // Refer to generate_disjoint_copy for a list of prereqs and features. unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). @@ -1329,77 +1357,96 @@ class StubGenerator: public StubCodeGenerator { return __ addr_at(start_off); } - - address generate_conjoint_byte_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for overlapping byte array copy. - // Refer to generate_conjoint_copy for a list of prereqs and features: - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - address nooverlap_target = aligned ? StubRoutines::arrayof_jbyte_disjoint_arraycopy() - : StubRoutines::jbyte_disjoint_arraycopy(); - - array_overlap_test(nooverlap_target, 0); // Branch away to nooverlap_target if disjoint. - generate_conjoint_copy(aligned, 1, false); - - return __ addr_at(start_off); - } - - - address generate_conjoint_short_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for overlapping short array copy. - // Refer to generate_conjoint_copy for a list of prereqs and features: - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - address nooverlap_target = aligned ? StubRoutines::arrayof_jshort_disjoint_arraycopy() - : StubRoutines::jshort_disjoint_arraycopy(); - - array_overlap_test(nooverlap_target, 1); // Branch away to nooverlap_target if disjoint. - generate_conjoint_copy(aligned, 2, false); - - return __ addr_at(start_off); - } - - address generate_conjoint_int_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for overlapping int array copy. - // Refer to generate_conjoint_copy for a list of prereqs and features: - - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - address nooverlap_target = aligned ? StubRoutines::arrayof_jint_disjoint_arraycopy() - : StubRoutines::jint_disjoint_arraycopy(); - - array_overlap_test(nooverlap_target, 2); // Branch away to nooverlap_target if disjoint. - generate_conjoint_copy(aligned, 4, false); - - return __ addr_at(start_off); - } - - address generate_conjoint_long_copy(bool aligned, const char * name) { - StubCodeMark mark(this, "StubRoutines", name); - // This is the zarch specific stub generator for overlapping long array copy. - // Refer to generate_conjoint_copy for a list of prereqs and features: - - unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - address nooverlap_target = aligned ? StubRoutines::arrayof_jlong_disjoint_arraycopy() - : StubRoutines::jlong_disjoint_arraycopy(); - - array_overlap_test(nooverlap_target, 3); // Branch away to nooverlap_target if disjoint. - generate_conjoint_copy(aligned, 8, false); - + address generate_conjoint_nonoop_copy(StubGenStubId stub_id) { + bool aligned; + int shift; // i.e. log2(element size) + address nooverlap_target; + switch (stub_id) { + case jbyte_arraycopy_id: + aligned = false; + shift = 0; + nooverlap_target = StubRoutines::jbyte_disjoint_arraycopy(); + break; + case arrayof_jbyte_arraycopy_id: + aligned = true; + shift = 0; + nooverlap_target = StubRoutines::arrayof_jbyte_disjoint_arraycopy(); + break; + case jshort_arraycopy_id: + aligned = false; + shift = 1; + nooverlap_target = StubRoutines::jshort_disjoint_arraycopy(); + break; + case arrayof_jshort_arraycopy_id: + aligned = true; + shift = 1; + nooverlap_target = StubRoutines::arrayof_jshort_disjoint_arraycopy(); + break; + case jint_arraycopy_id: + aligned = false; + shift = 2; + nooverlap_target = StubRoutines::jint_disjoint_arraycopy(); + break; + case arrayof_jint_arraycopy_id: + aligned = true; + shift = 2; + nooverlap_target = StubRoutines::arrayof_jint_disjoint_arraycopy(); + break; + case jlong_arraycopy_id: + aligned = false; + shift = 3; + nooverlap_target = StubRoutines::jlong_disjoint_arraycopy(); + break; + case arrayof_jlong_arraycopy_id: + aligned = true; + shift = 3; + nooverlap_target = StubRoutines::arrayof_jlong_disjoint_arraycopy(); + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); + unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). + array_overlap_test(nooverlap_target, shift); // Branch away to nooverlap_target if disjoint. + generate_conjoint_copy(aligned, 1 << shift, false); return __ addr_at(start_off); } - address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) { - StubCodeMark mark(this, "StubRoutines", name); + address generate_conjoint_oop_copy(StubGenStubId stub_id) { + bool aligned; + bool dest_uninitialized; + address nooverlap_target; + switch (stub_id) { + case oop_arraycopy_id: + aligned = false; + dest_uninitialized = false; + nooverlap_target = StubRoutines::oop_disjoint_arraycopy(dest_uninitialized); + break; + case arrayof_oop_arraycopy_id: + aligned = true; + dest_uninitialized = false; + nooverlap_target = StubRoutines::arrayof_oop_disjoint_arraycopy(dest_uninitialized); + break; + case oop_arraycopy_uninit_id: + aligned = false; + dest_uninitialized = true; + nooverlap_target = StubRoutines::oop_disjoint_arraycopy(dest_uninitialized); + break; + case arrayof_oop_arraycopy_uninit_id: + aligned = true; + dest_uninitialized = true; + nooverlap_target = StubRoutines::arrayof_oop_disjoint_arraycopy(dest_uninitialized); + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); // This is the zarch specific stub generator for overlapping oop array copy. // Refer to generate_conjoint_copy for a list of prereqs and features. unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). unsigned int size = UseCompressedOops ? 4 : 8; unsigned int shift = UseCompressedOops ? 2 : 3; - address nooverlap_target = aligned ? StubRoutines::arrayof_oop_disjoint_arraycopy(dest_uninitialized) - : StubRoutines::oop_disjoint_arraycopy(dest_uninitialized); - // Branch to disjoint_copy (if applicable) before pre_barrier to avoid double pre_barrier. array_overlap_test(nooverlap_target, shift); // Branch away to nooverlap_target if disjoint. @@ -1426,33 +1473,33 @@ class StubGenerator: public StubCodeGenerator { // Note: the disjoint stubs must be generated first, some of // the conjoint stubs use them. - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy (false, "jbyte_disjoint_arraycopy"); - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy"); - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_copy (false, "jint_disjoint_arraycopy"); - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_copy (false, "jlong_disjoint_arraycopy"); - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy (false, "oop_disjoint_arraycopy", false); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy (false, "oop_disjoint_arraycopy_uninit", true); - - StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy (true, "arrayof_jbyte_disjoint_arraycopy"); - StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_short_copy(true, "arrayof_jshort_disjoint_arraycopy"); - StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_int_copy (true, "arrayof_jint_disjoint_arraycopy"); - StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_long_copy (true, "arrayof_jlong_disjoint_arraycopy"); - StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy (true, "arrayof_oop_disjoint_arraycopy", false); - StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy (true, "arrayof_oop_disjoint_arraycopy_uninit", true); - - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy (false, "jbyte_arraycopy"); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, "jshort_arraycopy"); - StubRoutines::_jint_arraycopy = generate_conjoint_int_copy (false, "jint_arraycopy"); - StubRoutines::_jlong_arraycopy = generate_conjoint_long_copy (false, "jlong_arraycopy"); - StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy (false, "oop_arraycopy", false); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_oop_copy (false, "oop_arraycopy_uninit", true); - - StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_byte_copy (true, "arrayof_jbyte_arraycopy"); - StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_short_copy(true, "arrayof_jshort_arraycopy"); - StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_int_copy (true, "arrayof_jint_arraycopy"); - StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_long_copy (true, "arrayof_jlong_arraycopy"); - StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy (true, "arrayof_oop_arraycopy", false); - StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy (true, "arrayof_oop_arraycopy_uninit", true); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jbyte_disjoint_arraycopy_id); + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_nonoop_copy(StubGenStubId::jshort_disjoint_arraycopy_id); + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jint_disjoint_arraycopy_id); + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jlong_disjoint_arraycopy_id); + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_oop_copy (StubGenStubId::oop_disjoint_arraycopy_id); + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy (StubGenStubId::oop_disjoint_arraycopy_uninit_id); + + StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id); + StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_nonoop_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id); + StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::arrayof_jint_disjoint_arraycopy_id); + StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::arrayof_jlong_disjoint_arraycopy_id); + StubRoutines::_arrayof_oop_disjoint_arraycopy = generate_disjoint_oop_copy (StubGenStubId::arrayof_oop_disjoint_arraycopy_id); + StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = generate_disjoint_oop_copy (StubGenStubId::arrayof_oop_disjoint_arraycopy_uninit_id); + + StubRoutines::_jbyte_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::jbyte_arraycopy_id); + StubRoutines::_jshort_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::jshort_arraycopy_id); + StubRoutines::_jint_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::jint_arraycopy_id); + StubRoutines::_jlong_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::jlong_arraycopy_id); + StubRoutines::_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::oop_arraycopy_id); + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::oop_arraycopy_uninit_id); + + StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::arrayof_jbyte_arraycopy_id); + StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::arrayof_jshort_arraycopy_id); + StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_nonoop_copy (StubGenStubId::arrayof_jint_arraycopy_id); + StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::arrayof_jlong_arraycopy_id); + StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_id); + StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_uninit_id); } // Call interface for AES_encryptBlock, AES_decryptBlock stubs. @@ -1734,9 +1781,10 @@ class StubGenerator: public StubCodeGenerator { } // Compute AES encrypt function. - address generate_AES_encryptBlock(const char* name) { + address generate_AES_encryptBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). generate_AES_cipherBlock(false); @@ -1745,9 +1793,10 @@ class StubGenerator: public StubCodeGenerator { } // Compute AES decrypt function. - address generate_AES_decryptBlock(const char* name) { + address generate_AES_decryptBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). generate_AES_cipherBlock(true); @@ -1805,9 +1854,10 @@ class StubGenerator: public StubCodeGenerator { } // Compute chained AES encrypt function. - address generate_cipherBlockChaining_AES_encrypt(const char* name) { + address generate_cipherBlockChaining_AES_encrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). generate_AES_cipherBlockChaining(false); @@ -1816,9 +1866,10 @@ class StubGenerator: public StubCodeGenerator { } // Compute chained AES decrypt function. - address generate_cipherBlockChaining_AES_decrypt(const char* name) { + address generate_cipherBlockChaining_AES_decrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). generate_AES_cipherBlockChaining(true); @@ -2522,9 +2573,10 @@ class StubGenerator: public StubCodeGenerator { // Compute AES-CTR crypto function. // Encrypt or decrypt is selected via parameters. Only one stub is necessary. - address generate_counterMode_AESCrypt(const char* name) { + address generate_counterMode_AESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::counterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). generate_counterMode_AES(false); @@ -2537,7 +2589,8 @@ class StubGenerator: public StubCodeGenerator { // Compute GHASH function. address generate_ghash_processBlocks() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). const Register state = Z_ARG1; @@ -2614,9 +2667,20 @@ class StubGenerator: public StubCodeGenerator { // provides for a large enough source data buffer. // // Compute SHA-1 function. - address generate_SHA1_stub(bool multiBlock, const char* name) { + address generate_SHA1_stub(StubGenStubId stub_id) { + bool multiBlock; + switch (stub_id) { + case sha1_implCompress_id: + multiBlock = false; + break; + case sha1_implCompressMB_id: + multiBlock = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). const Register srcBuff = Z_ARG1; // Points to first block to process (offset already added). @@ -2696,9 +2760,20 @@ class StubGenerator: public StubCodeGenerator { } // Compute SHA-256 function. - address generate_SHA256_stub(bool multiBlock, const char* name) { + address generate_SHA256_stub(StubGenStubId stub_id) { + bool multiBlock; + switch (stub_id) { + case sha256_implCompress_id: + multiBlock = false; + break; + case sha256_implCompressMB_id: + multiBlock = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). const Register srcBuff = Z_ARG1; @@ -2776,9 +2851,20 @@ class StubGenerator: public StubCodeGenerator { } // Compute SHA-512 function. - address generate_SHA512_stub(bool multiBlock, const char* name) { + address generate_SHA512_stub(StubGenStubId stub_id) { + bool multiBlock; + switch (stub_id) { + case sha512_implCompress_id: + multiBlock = false; + break; + case sha512_implCompressMB_id: + multiBlock = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). const Register srcBuff = Z_ARG1; @@ -2868,7 +2954,7 @@ class StubGenerator: public StubCodeGenerator { * Z_RET - int crc result **/ // Compute CRC function (generic, for all polynomials). - void generate_CRC_updateBytes(const char* name, Register table, bool invertCRC) { + void generate_CRC_updateBytes(Register table, bool invertCRC) { // arguments to kernel_crc32: Register crc = Z_ARG1; // Current checksum, preset by caller or result from previous call, int. @@ -2899,18 +2985,19 @@ class StubGenerator: public StubCodeGenerator { // Compute CRC32 function. - address generate_CRC32_updateBytes(const char* name) { + address generate_CRC32_updateBytes() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - assert(UseCRC32Intrinsics, "should not generate this stub (%s) with CRC32 intrinsics disabled", name); + assert(UseCRC32Intrinsics, "should not generate this stub (%s) with CRC32 intrinsics disabled", StubRoutines::get_stub_name(stub_id)); BLOCK_COMMENT("CRC32_updateBytes {"); Register table = Z_ARG4; // crc32 table address. StubRoutines::zarch::generate_load_crc_table_addr(_masm, table); - generate_CRC_updateBytes(name, table, true); + generate_CRC_updateBytes(table, true); BLOCK_COMMENT("} CRC32_updateBytes"); return __ addr_at(start_off); @@ -2918,18 +3005,19 @@ class StubGenerator: public StubCodeGenerator { // Compute CRC32C function. - address generate_CRC32C_updateBytes(const char* name) { + address generate_CRC32C_updateBytes() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32C_id; + StubCodeMark mark(this, stub_id); unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). - assert(UseCRC32CIntrinsics, "should not generate this stub (%s) with CRC32C intrinsics disabled", name); + assert(UseCRC32CIntrinsics, "should not generate this stub (%s) with CRC32C intrinsics disabled", StubRoutines::get_stub_name(stub_id)); BLOCK_COMMENT("CRC32C_updateBytes {"); Register table = Z_ARG4; // crc32c table address. StubRoutines::zarch::generate_load_crc32c_table_addr(_masm, table); - generate_CRC_updateBytes(name, table, false); + generate_CRC_updateBytes(table, false); BLOCK_COMMENT("} CRC32C_updateBytes"); return __ addr_at(start_off); @@ -2944,7 +3032,8 @@ class StubGenerator: public StubCodeGenerator { // Z_ARG5 - z address address generate_multiplyToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); + StubGenStubId stub_id = StubGenStubId::multiplyToLen_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -2975,7 +3064,8 @@ class StubGenerator: public StubCodeGenerator { address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3040,7 +3130,8 @@ class StubGenerator: public StubCodeGenerator { // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { - StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_exception_handler_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Native caller has no idea how to handle exceptions, @@ -3057,7 +3148,8 @@ class StubGenerator: public StubCodeGenerator { // Z_ARG1 = jobject receiver // Z_method = Method* result address generate_upcall_stub_load_target() { - StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_load_target_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ resolve_global_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2); @@ -3094,12 +3186,12 @@ class StubGenerator: public StubCodeGenerator { if (UseCRC32Intrinsics) { StubRoutines::_crc_table_adr = (address)StubRoutines::zarch::_crc_table; - StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes("CRC32_updateBytes"); + StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes(); } if (UseCRC32CIntrinsics) { StubRoutines::_crc32c_table_addr = (address)StubRoutines::zarch::_crc32c_table; - StubRoutines::_updateBytesCRC32C = generate_CRC32C_updateBytes("CRC32C_updateBytes"); + StubRoutines::_updateBytesCRC32C = generate_CRC32C_updateBytes(); } // Comapct string intrinsics: Translate table for string inflate intrinsic. Used by trot instruction. @@ -3118,8 +3210,6 @@ class StubGenerator: public StubCodeGenerator { void generate_final_stubs() { // Generates all stubs and initializes the entry points. - StubRoutines::zarch::_partial_subtype_check = generate_partial_subtype_check(); - // Support for verify_oop (must happen after universe_init). StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop_subroutine(); @@ -3132,19 +3222,31 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_method_entry_barrier = generate_method_entry_barrier(); } +#ifdef COMPILER2 + if (UseSecondarySupersTable) { + StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); + if (!InlineSecondarySupersTest) { + generate_lookup_secondary_supers_table_stub(); + } + } +#endif // COMPILER2 + StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler(); StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target(); } void generate_compiler_stubs() { + + StubRoutines::zarch::_partial_subtype_check = generate_partial_subtype_check(); + #if COMPILER2_OR_JVMCI // Generate AES intrinsics code. if (UseAESIntrinsics) { if (VM_Version::has_Crypto_AES()) { - StubRoutines::_aescrypt_encryptBlock = generate_AES_encryptBlock("AES_encryptBlock"); - StubRoutines::_aescrypt_decryptBlock = generate_AES_decryptBlock("AES_decryptBlock"); - StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_AES_encrypt("AES_encryptBlock_chaining"); - StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_AES_decrypt("AES_decryptBlock_chaining"); + StubRoutines::_aescrypt_encryptBlock = generate_AES_encryptBlock(); + StubRoutines::_aescrypt_decryptBlock = generate_AES_decryptBlock(); + StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_AES_encrypt(); + StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_AES_decrypt(); } else { // In PRODUCT builds, the function pointers will keep their initial (null) value. // LibraryCallKit::try_to_inline() will return false then, preventing the intrinsic to be called. @@ -3154,7 +3256,7 @@ class StubGenerator: public StubCodeGenerator { if (UseAESCTRIntrinsics) { if (VM_Version::has_Crypto_AES_CTR()) { - StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt("counterMode_AESCrypt"); + StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt(); } else { // In PRODUCT builds, the function pointers will keep their initial (null) value. // LibraryCallKit::try_to_inline() will return false then, preventing the intrinsic to be called. @@ -3169,16 +3271,16 @@ class StubGenerator: public StubCodeGenerator { // Generate SHA1/SHA256/SHA512 intrinsics code. if (UseSHA1Intrinsics) { - StubRoutines::_sha1_implCompress = generate_SHA1_stub(false, "SHA1_singleBlock"); - StubRoutines::_sha1_implCompressMB = generate_SHA1_stub(true, "SHA1_multiBlock"); + StubRoutines::_sha1_implCompress = generate_SHA1_stub(StubGenStubId::sha1_implCompress_id); + StubRoutines::_sha1_implCompressMB = generate_SHA1_stub(StubGenStubId::sha1_implCompressMB_id); } if (UseSHA256Intrinsics) { - StubRoutines::_sha256_implCompress = generate_SHA256_stub(false, "SHA256_singleBlock"); - StubRoutines::_sha256_implCompressMB = generate_SHA256_stub(true, "SHA256_multiBlock"); + StubRoutines::_sha256_implCompress = generate_SHA256_stub(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = generate_SHA256_stub(StubGenStubId::sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { - StubRoutines::_sha512_implCompress = generate_SHA512_stub(false, "SHA512_singleBlock"); - StubRoutines::_sha512_implCompressMB = generate_SHA512_stub(true, "SHA512_multiBlock"); + StubRoutines::_sha512_implCompress = generate_SHA512_stub(StubGenStubId::sha512_implCompress_id); + StubRoutines::_sha512_implCompressMB = generate_SHA512_stub(StubGenStubId::sha512_implCompressMB_id); } #ifdef COMPILER2 @@ -3193,35 +3295,27 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_montgomerySquare = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square); } - if (UseSecondarySupersTable) { - StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); - if (!InlineSecondarySupersTest) { - for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] = generate_lookup_secondary_supers_table_stub(slot); - } - } - } #endif #endif // COMPILER2_OR_JVMCI } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } @@ -3260,6 +3354,6 @@ class StubGenerator: public StubCodeGenerator { }; -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } diff --git a/src/hotspot/cpu/s390/stubRoutines_s390.cpp b/src/hotspot/cpu/s390/stubRoutines_s390.cpp index 2a60f71557c71..e75928ad00e61 100644 --- a/src/hotspot/cpu/s390/stubRoutines_s390.cpp +++ b/src/hotspot/cpu/s390/stubRoutines_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" @@ -33,7 +32,18 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::zarch::_partial_subtype_check = nullptr; +// define fields for arch-specific entries + +#define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr; + +#define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function); + +STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) + +#undef DEFINE_ARCH_ENTRY_INIT +#undef DEFINE_ARCH_ENTRY // Comapct string intrinsics: Translate table for string inflate intrinsic. Used by trot instruction. address StubRoutines::zarch::_trot_table_addr = nullptr; diff --git a/src/hotspot/cpu/s390/stubRoutines_s390.hpp b/src/hotspot/cpu/s390/stubRoutines_s390.hpp index 7116d441715ad..7a4bc18eb7d4c 100644 --- a/src/hotspot/cpu/s390/stubRoutines_s390.hpp +++ b/src/hotspot/cpu/s390/stubRoutines_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,14 +31,17 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } -enum { // Platform dependent constants. - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 20000, - _continuation_stubs_code_size = 2000, - _compiler_stubs_code_size = 20000, - _final_stubs_code_size = 20000 +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + +enum platform_dependent_constants { + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + // MethodHandles adapters enum method_handles_platform_dependent_constants { method_handles_adapters_code_size = 5000 @@ -69,10 +72,24 @@ class zarch { locked = 1 }; + // declare fields for arch-specific entries + +#define DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + static address STUB_FIELD_NAME(field_name) ; + +#define DECLARE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) + +private: + STUBGEN_ARCH_ENTRIES_DO(DECLARE_ARCH_ENTRY, DECLARE_ARCH_ENTRY_INIT) + +#undef DECLARE_ARCH_ENTRY_INIT +#undef DECLARE_ARCH_ENTRY + private: + static int _atomic_memory_operation_lock; - static address _partial_subtype_check; static juint _crc_table[CRC32_TABLES][CRC32_COLUMN_SIZE]; static juint _crc32c_table[CRC32_TABLES][CRC32_COLUMN_SIZE]; @@ -81,6 +98,20 @@ class zarch { static jlong _trot_table[TROT_COLUMN_SIZE]; public: + + // declare getters for arch-specific entries + +#define DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) \ + static address getter_name() { return STUB_FIELD_NAME(field_name) ; } + +#define DEFINE_ARCH_ENTRY_GETTER_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) + + STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY_GETTER, DEFINE_ARCH_ENTRY_GETTER_INIT) + +#undef DEFINE_ARCH_ENTRY_GETTER_INIT +#undef DEFINE_ARCH_ENTRY_GETTER + // Global lock for everyone who needs to use atomic_compare_and_exchange // or atomic_increment -- should probably use more locks for more // scalability -- for instance one for each eden space or group of. @@ -92,8 +123,6 @@ class zarch { static int atomic_memory_operation_lock() { return _atomic_memory_operation_lock; } static void set_atomic_memory_operation_lock(int value) { _atomic_memory_operation_lock = value; } - static address partial_subtype_check() { return _partial_subtype_check; } - static void generate_load_absolute_address(MacroAssembler* masm, Register table, address table_addr, uint64_t table_contents); static void generate_load_crc_table_addr(MacroAssembler* masm, Register table); static void generate_load_crc32c_table_addr(MacroAssembler* masm, Register table); diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 1c4089d5beb07..c40be5edec754 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "compiler/disassembler.hpp" @@ -164,7 +163,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Therefore add 3 to address that byte within "_flags". // Reload method. VM call above may have destroyed register contents __ get_method(method); - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); method = noreg; // end of life __ z_btrue(isStatic); @@ -883,7 +882,7 @@ void TemplateInterpreterGenerator::lock_method(void) { address reentry = nullptr; { Label L; - __ testbit(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "method doesn't need synchronization"); __ bind(L); @@ -897,7 +896,7 @@ void TemplateInterpreterGenerator::lock_method(void) { Label done; Label static_method; - __ testbit(method2_(method, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(method, access_flags), JVM_ACC_STATIC_BIT); __ z_btrue(static_method); // non-static method: Load receiver obj from stack. @@ -1349,15 +1348,17 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Make sure method is native and not abstract. #ifdef ASSERT + // _access_flags must be a 16 bit value. + assert(sizeof(AccessFlags) == 2, "testbit_ushort will fail"); address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_btrue(L); reentry = __ stop_chain_static(reentry, "tried to execute non-native method as native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1403,7 +1404,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); @@ -1461,7 +1462,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Pass mirror handle if static call. { Label method_is_not_static; - __ testbit(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); + __ testbit_ushort(method2_(Rmethod, access_flags), JVM_ACC_STATIC_BIT); __ z_bfalse(method_is_not_static); // Load mirror from interpreter frame. __ z_lg(Z_R1, _z_ijava_state_neg(mirror), Z_fp); @@ -1719,13 +1720,13 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT address reentry = nullptr; { Label L; - __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute native method as non-native"); __ bind(L); } { Label L; - __ testbit(method_(access_flags), JVM_ACC_ABSTRACT_BIT); + __ testbit_ushort(method_(access_flags), JVM_ACC_ABSTRACT_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "tried to execute abstract method as non-abstract"); __ bind(L); @@ -1775,7 +1776,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; __ get_method(Z_R1_scratch); - __ testbit(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); + __ testbit_ushort(method2_(Z_R1_scratch, access_flags), JVM_ACC_SYNCHRONIZED_BIT); __ z_bfalse(L); reentry = __ stop_chain_static(reentry, "method needs synchronization"); __ bind(L); diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp index 3cb1aba810df4..e6c0c7781a3ba 100644 --- a/src/hotspot/cpu/s390/templateTable_s390.cpp +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp index 8baad40a519a4..ab8bf7718123d 100644 --- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.hpp" #include "logging/logStream.hpp" diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index a5195e753bbf8..157b945e6e1a4 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" #include "code/compiledIC.hpp" @@ -308,6 +307,12 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true); } + + // The OptoScheduling information is not maintained in s390.ad. + if (OptoScheduling) { + warning("OptoScheduling is not supported on this CPU."); + FLAG_SET_DEFAULT(OptoScheduling, false); + } #endif if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { FLAG_SET_DEFAULT(UsePopCountInstruction, true); @@ -323,12 +328,6 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) { FLAG_SET_DEFAULT(UseUnalignedAccesses, true); } - - // The OptoScheduling information is not maintained in s390.ad. - if (OptoScheduling) { - warning("OptoScheduling is not supported on this CPU."); - FLAG_SET_DEFAULT(OptoScheduling, false); - } } diff --git a/src/hotspot/cpu/s390/vmreg_s390.cpp b/src/hotspot/cpu/s390/vmreg_s390.cpp index d4d230eeb0466..0587cebb19987 100644 --- a/src/hotspot/cpu/s390/vmreg_s390.cpp +++ b/src/hotspot/cpu/s390/vmreg_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/s390/vtableStubs_s390.cpp b/src/hotspot/cpu/s390/vtableStubs_s390.cpp index d3af7fefcf133..f60d91183da6b 100644 --- a/src/hotspot/cpu/s390/vtableStubs_s390.cpp +++ b/src/hotspot/cpu/s390/vtableStubs_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp b/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp index fef137257b020..68ac5b6ca9a97 100644 --- a/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp +++ b/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethod.hpp" #include "interpreter/interpreter.hpp" #include "oops/klass.inline.hpp" diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index c2fcbcea71e24..085ae4a6dddce 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -3476,6 +3475,22 @@ void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) { emit_int16(0x6F, (0xC0 | encode)); } +void Assembler::vmovw(XMMRegister dst, Register src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes, true); + emit_int16(0x6E, (0xC0 | encode)); +} + +void Assembler::vmovw(Register dst, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes, true); + emit_int16(0x7E, (0xC0 | encode)); +} + void Assembler::vmovdqu(XMMRegister dst, Address src) { assert(UseAVX > 0, ""); InstructionMark im(this); @@ -8443,6 +8458,70 @@ void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector emit_operand(dst, src, 0); } +void Assembler::vaddsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x58, (0xC0 | encode)); +} + +void Assembler::vsubsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x5C, (0xC0 | encode)); +} + +void Assembler::vdivsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x5E, (0xC0 | encode)); +} + +void Assembler::vmulsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x59, (0xC0 | encode)); +} + +void Assembler::vmaxsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x5F, (0xC0 | encode)); +} + +void Assembler::vminsh(XMMRegister dst, XMMRegister nds, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x5D, (0xC0 | encode)); +} + +void Assembler::vsqrtsh(XMMRegister dst, XMMRegister src) { + assert(VM_Version::supports_avx512_fp16(), "requires AVX512-FP16"); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes); + emit_int16(0x51, (0xC0 | encode)); +} + +void Assembler::vfmadd132sh(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + assert(VM_Version::supports_avx512_fp16(), ""); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP6, &attributes); + emit_int16((unsigned char)0x99, (0xC0 | encode)); +} + void Assembler::vpaddsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(UseAVX > 0 && (vector_len == Assembler::AVX_512bit || (!needs_evex(dst, nds, src) || VM_Version::supports_avx512vl())), ""); assert(!needs_evex(dst, nds, src) || VM_Version::supports_avx512bw(), ""); diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 25be0d6a48d32..1eb12fb93f023 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -585,6 +585,8 @@ class Assembler : public AbstractAssembler { VEX_OPCODE_0F_38 = 0x2, VEX_OPCODE_0F_3A = 0x3, VEX_OPCODE_0F_3C = 0x4, + VEX_OPCODE_MAP5 = 0x5, + VEX_OPCODE_MAP6 = 0x6, VEX_OPCODE_MASK = 0x1F }; @@ -1815,6 +1817,9 @@ class Assembler : public AbstractAssembler { void movsbl(Register dst, Address src); void movsbl(Register dst, Register src); + void vmovw(XMMRegister dst, Register src); + void vmovw(Register dst, XMMRegister src); + #ifdef _LP64 void movsbq(Register dst, Address src); void movsbq(Register dst, Register src); @@ -2691,6 +2696,16 @@ class Assembler : public AbstractAssembler { void vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len); + // FP16 instructions + void vaddsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vsubsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vmulsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vdivsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vmaxsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vminsh(XMMRegister dst, XMMRegister nds, XMMRegister src); + void vsqrtsh(XMMRegister dst, XMMRegister src); + void vfmadd132sh(XMMRegister dst, XMMRegister src1, XMMRegister src2); + // Saturating packed insturctions. void vpaddsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpaddsw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); diff --git a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp index 71ca9351f86c9..71d2898f45c7f 100644 --- a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp +++ b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIRAssembler.hpp" diff --git a/src/hotspot/cpu/x86/c1_FpuStackSim_x86.cpp b/src/hotspot/cpu/x86/c1_FpuStackSim_x86.cpp index 3ec182a350b8d..878c94c99da40 100644 --- a/src/hotspot/cpu/x86/c1_FpuStackSim_x86.cpp +++ b/src/hotspot/cpu/x86/c1_FpuStackSim_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FpuStackSim.hpp" #include "c1/c1_FrameMap.hpp" #include "utilities/growableArray.hpp" diff --git a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp index 4153c37729bfc..cff2be393bc9e 100644 --- a/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp +++ b/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index ff6d18e48e1a8..de1fa1a9cc635 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "c1/c1_CodeStubs.hpp" @@ -2393,21 +2392,13 @@ void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr tmp, LIR_ switch(code) { case lir_abs : { -#ifdef _LP64 - if (UseAVX > 2 && !VM_Version::supports_avx512vl()) { - assert(tmp->is_valid(), "need temporary"); - __ vpandn(dest->as_xmm_double_reg(), tmp->as_xmm_double_reg(), value->as_xmm_double_reg(), 2); - } else -#endif - { - if (dest->as_xmm_double_reg() != value->as_xmm_double_reg()) { - __ movdbl(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); - } - assert(!tmp->is_valid(), "do not need temporary"); - __ andpd(dest->as_xmm_double_reg(), - ExternalAddress((address)double_signmask_pool), - rscratch1); + if (dest->as_xmm_double_reg() != value->as_xmm_double_reg()) { + __ movdbl(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); } + assert(!tmp->is_valid(), "do not need temporary"); + __ andpd(dest->as_xmm_double_reg(), + ExternalAddress((address)double_signmask_pool), + rscratch1); } break; @@ -3798,41 +3789,21 @@ void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) { #endif // _LP64 } else if (dest->is_single_xmm()) { -#ifdef _LP64 - if (UseAVX > 2 && !VM_Version::supports_avx512vl()) { - assert(tmp->is_valid(), "need temporary"); - assert_different_registers(left->as_xmm_float_reg(), tmp->as_xmm_float_reg()); - __ vpxor(dest->as_xmm_float_reg(), tmp->as_xmm_float_reg(), left->as_xmm_float_reg(), 2); - } - else -#endif - { - assert(!tmp->is_valid(), "do not need temporary"); - if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) { - __ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg()); - } - __ xorps(dest->as_xmm_float_reg(), - ExternalAddress((address)float_signflip_pool), - rscratch1); + assert(!tmp->is_valid(), "do not need temporary"); + if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) { + __ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg()); } + __ xorps(dest->as_xmm_float_reg(), + ExternalAddress((address)float_signflip_pool), + rscratch1); } else if (dest->is_double_xmm()) { -#ifdef _LP64 - if (UseAVX > 2 && !VM_Version::supports_avx512vl()) { - assert(tmp->is_valid(), "need temporary"); - assert_different_registers(left->as_xmm_double_reg(), tmp->as_xmm_double_reg()); - __ vpxor(dest->as_xmm_double_reg(), tmp->as_xmm_double_reg(), left->as_xmm_double_reg(), 2); - } - else -#endif - { - assert(!tmp->is_valid(), "do not need temporary"); - if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) { - __ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg()); - } - __ xorpd(dest->as_xmm_double_reg(), - ExternalAddress((address)double_signflip_pool), - rscratch1); + assert(!tmp->is_valid(), "do not need temporary"); + if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) { + __ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg()); } + __ xorpd(dest->as_xmm_double_reg(), + ExternalAddress((address)double_signflip_pool), + rscratch1); #ifndef _LP64 } else if (left->is_single_fpu() || left->is_double_fpu()) { assert(left->fpu() == 0, "arg must be on TOS"); diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp index 36e2021138f2e..7e28b288f71d3 100644 --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_Instruction.hpp" @@ -344,20 +343,7 @@ void LIRGenerator::do_NegateOp(NegateOp* x) { value.load_item(); LIR_Opr reg = rlock(x); - LIR_Opr tmp = LIR_OprFact::illegalOpr; -#ifdef _LP64 - if (UseAVX > 2 && !VM_Version::supports_avx512vl()) { - if (x->type()->tag() == doubleTag) { - tmp = new_register(T_DOUBLE); - __ move(LIR_OprFact::doubleConst(-0.0), tmp); - } - else if (x->type()->tag() == floatTag) { - tmp = new_register(T_FLOAT); - __ move(LIR_OprFact::floatConst(-0.0), tmp); - } - } -#endif - __ negate(value.result(), reg, tmp); + __ negate(value.result(), reg); set_result(x, round_item(reg)); } @@ -830,16 +816,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { LIR_Opr calc_result = rlock_result(x); LIR_Opr tmp = LIR_OprFact::illegalOpr; -#ifdef _LP64 - if (UseAVX > 2 && (!VM_Version::supports_avx512vl()) && - (x->id() == vmIntrinsics::_dabs)) { - tmp = new_register(T_DOUBLE); - __ move(LIR_OprFact::doubleConst(-0.0), tmp); - } -#endif if (x->id() == vmIntrinsics::_floatToFloat16) { tmp = new_register(T_FLOAT); - __ move(LIR_OprFact::floatConst(-0.0), tmp); } switch(x->id()) { @@ -1512,6 +1490,11 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci()); } +// Intrinsic for Class::isInstance +address LIRGenerator::isInstance_entry() { + return Runtime1::entry_for(C1StubId::is_instance_of_id); +} + void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); diff --git a/src/hotspot/cpu/x86/c1_LIR_x86.cpp b/src/hotspot/cpu/x86/c1_LIR_x86.cpp index 6bdbfd1824caa..adcc53c44ce14 100644 --- a/src/hotspot/cpu/x86/c1_LIR_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIR_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" diff --git a/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp b/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp index 917031faf8962..7c4da998db895 100644 --- a/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LinearScan_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_LinearScan.hpp" #include "utilities/bitMap.inline.hpp" @@ -635,6 +634,23 @@ void FpuStackAllocator::handle_op1(LIR_Op1* op1) { break; } + case lir_abs: + case lir_sqrt: + case lir_neg: { + assert(in->is_fpu_register(), "must be"); + assert(res->is_fpu_register(), "must be"); + assert(in->is_last_use(), "old value gets destroyed"); + + insert_free_if_dead(res, in); + insert_exchange(in); + do_rename(in, res); + + new_in = to_fpu_stack_top(res); + new_res = new_in; + + break; + } + default: { assert(!in->is_float_kind() && !res->is_float_kind(), "missed a fpu-operation"); } @@ -756,26 +772,6 @@ void FpuStackAllocator::handle_op2(LIR_Op2* op2) { break; } - case lir_abs: - case lir_sqrt: - case lir_neg: { - // Right argument appears to be unused - assert(right->is_illegal(), "must be"); - assert(left->is_fpu_register(), "must be"); - assert(res->is_fpu_register(), "must be"); - assert(left->is_last_use(), "old value gets destroyed"); - - insert_free_if_dead(res, left); - insert_exchange(left); - do_rename(left, res); - - new_left = to_fpu_stack_top(res); - new_res = new_left; - - op2->set_fpu_stack_size(sim()->stack_size()); - break; - } - default: { assert(false, "missed a fpu-operation"); } diff --git a/src/hotspot/cpu/x86/c1_LinearScan_x86.hpp b/src/hotspot/cpu/x86/c1_LinearScan_x86.hpp index 50cdd14154c42..e40de213e7a8b 100644 --- a/src/hotspot/cpu/x86/c1_LinearScan_x86.hpp +++ b/src/hotspot/cpu/x86/c1_LinearScan_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,35 +66,7 @@ inline bool LinearScan::is_caller_save(int assigned_reg) { inline void LinearScan::pd_add_temps(LIR_Op* op) { - switch (op->code()) { - case lir_tan: { - // The slow path for these functions may need to save and - // restore all live registers but we don't want to save and - // restore everything all the time, so mark the xmms as being - // killed. If the slow path were explicit or we could propagate - // live register masks down to the assembly we could do better - // but we don't have any easy way to do that right now. We - // could also consider not killing all xmm registers if we - // assume that slow paths are uncommon but it's not clear that - // would be a good idea. - if (UseSSE > 0) { -#ifdef ASSERT - if (TraceLinearScanLevel >= 2) { - tty->print_cr("killing XMMs for trig"); - } -#endif - int num_caller_save_xmm_regs = FrameMap::get_num_caller_save_xmms(); - int op_id = op->id(); - for (int xmm = 0; xmm < num_caller_save_xmm_regs; xmm++) { - LIR_Opr opr = FrameMap::caller_save_xmm_reg_at(xmm); - add_temp(reg_num(opr), op_id, noUse, T_ILLEGAL); - } - } - break; - } - default: - break; - } + // No special case behaviours yet } diff --git a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp index f53a25ed3e646..e3c8792decd2b 100644 --- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_Runtime1.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp index 5cc8ffd9befe4..cb4cb3af8c3d4 100644 --- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp +++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_FrameMap.hpp" @@ -1318,6 +1317,60 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) { } break; + case C1StubId::is_instance_of_id: + { + // Mirror: c_rarg0 (Windows: rcx, SysV: rdi) + // Object: c_rarg1 (Windows: rdx, SysV: rsi) + // ObjClass: r9 + // Temps: rcx, r8, r10, r11 + // Result: rax + + Register klass = r9, obj = c_rarg1, result = rax; + Register temp0 = rcx, temp1 = r8, temp2 = r10, temp3 = r11; + + // Get the Klass* into r9. c_rarg0 is now dead. + __ movptr(klass, Address(c_rarg0, java_lang_Class::klass_offset())); + + Label done, is_secondary, same; + + __ xorq(result, result); + __ testq(klass, klass); + __ jcc(Assembler::equal, done); // Klass is null + + __ testq(obj, obj); + __ jcc(Assembler::equal, done); // obj is null + + __ movl(temp0, Address(klass, in_bytes(Klass::super_check_offset_offset()))); + __ cmpl(temp0, in_bytes(Klass::secondary_super_cache_offset())); + __ jcc(Assembler::equal, is_secondary); // Klass is a secondary superclass + + // Klass is a concrete class + __ load_klass(temp2, obj, /*tmp*/temp1); + __ cmpptr(klass, Address(temp2, temp0)); + __ setcc(Assembler::equal, result); + __ ret(0); + + __ bind(is_secondary); + + __ load_klass(obj, obj, /*tmp*/temp1); + + // This is necessary because I am never in my own secondary_super list. + __ cmpptr(obj, klass); + __ jcc(Assembler::equal, same); + + __ lookup_secondary_supers_table_var(obj, klass, + /*temps*/temp0, temp1, temp2, temp3, + result); + __ testq(result, result); + + __ bind(same); + __ setcc(Assembler::equal, result); + + __ bind(done); + __ ret(0); + } + break; + case C1StubId::monitorenter_nofpu_id: save_fpu_registers = false; // fall through diff --git a/src/hotspot/cpu/x86/c2_CodeStubs_x86.cpp b/src/hotspot/cpu/x86/c2_CodeStubs_x86.cpp index 44f897529e7ce..83ecdee52199b 100644 --- a/src/hotspot/cpu/x86/c2_CodeStubs_x86.cpp +++ b/src/hotspot/cpu/x86/c2_CodeStubs_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/c2_MacroAssembler.hpp" #include "opto/c2_CodeStubs.hpp" #include "runtime/objectMonitor.hpp" diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 50ed4750d47fd..7356f5a1913c9 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "gc/shared/barrierSet.hpp" @@ -6676,6 +6675,18 @@ void C2_MacroAssembler::vector_rearrange_int_float(BasicType bt, XMMRegister dst } } +void C2_MacroAssembler::efp16sh(int opcode, XMMRegister dst, XMMRegister src1, XMMRegister src2) { + switch(opcode) { + case Op_AddHF: vaddsh(dst, src1, src2); break; + case Op_SubHF: vsubsh(dst, src1, src2); break; + case Op_MulHF: vmulsh(dst, src1, src2); break; + case Op_DivHF: vdivsh(dst, src1, src2); break; + case Op_MaxHF: vmaxsh(dst, src1, src2); break; + case Op_MinHF: vminsh(dst, src1, src2); break; + default: assert(false, "%s", NodeClassNames[opcode]); break; + } +} + void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc) { switch(elem_bt) { case T_BYTE: diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index 6e49cdefa6c94..4fe2cc397b5ae 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -505,6 +505,7 @@ void vector_rearrange_int_float(BasicType bt, XMMRegister dst, XMMRegister shuffle, XMMRegister src, int vlen_enc); + void efp16sh(int opcode, XMMRegister dst, XMMRegister src1, XMMRegister src2); void vgather_subword(BasicType elem_ty, XMMRegister dst, Register base, Register idx_base, Register offset, Register mask, XMMRegister xtmp1, XMMRegister xtmp2, XMMRegister xtmp3, Register rtmp, diff --git a/src/hotspot/cpu/x86/c2_init_x86.cpp b/src/hotspot/cpu/x86/c2_init_x86.cpp index ee8937230b7b4..b286c3a34f2f1 100644 --- a/src/hotspot/cpu/x86/c2_init_x86.cpp +++ b/src/hotspot/cpu/x86/c2_init_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" #include "opto/optoreg.hpp" diff --git a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp index f726a831c9f15..909554cdf764d 100644 --- a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp +++ b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "c2_intelJccErratum_x86.hpp" #include "opto/compile.hpp" diff --git a/src/hotspot/cpu/x86/c2_stubGenerator_x86_64_string.cpp b/src/hotspot/cpu/x86/c2_stubGenerator_x86_64_string.cpp index 2837a85800f47..ee2d6d8a0bedc 100644 --- a/src/hotspot/cpu/x86/c2_stubGenerator_x86_64_string.cpp +++ b/src/hotspot/cpu/x86/c2_stubGenerator_x86_64_string.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" #include "oops/arrayOop.hpp" @@ -200,13 +199,14 @@ void StubGenerator::generate_string_indexof(address *fnptrs) { static void generate_string_indexof_stubs(StubGenerator *stubgen, address *fnptrs, StrIntrinsicNode::ArgEncoding ae, MacroAssembler *_masm) { - StubCodeMark mark(stubgen, "StubRoutines", "stringIndexOf"); bool isLL = (ae == StrIntrinsicNode::LL); bool isUL = (ae == StrIntrinsicNode::UL); bool isUU = (ae == StrIntrinsicNode::UU); bool isU = isUL || isUU; // At least one is UTF-16 assert(isLL || isUL || isUU, "Encoding not recognized"); + StubGenStubId stub_id = (isLL ? StubGenStubId::string_indexof_linear_ll_id : (isUL ? StubGenStubId::string_indexof_linear_ul_id : StubGenStubId::string_indexof_linear_uu_id)); + StubCodeMark mark(stubgen, stub_id); // Keep track of isUL since we need to generate UU code in the main body // for the case where we expand the needle from bytes to words on the stack. // This is done at L_wcharBegin. The algorithm used is: diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.cpp b/src/hotspot/cpu/x86/codeBuffer_x86.cpp index 3c406ed1b198e..75cc9b9896bb0 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.cpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.inline.hpp" #include "asm/macroAssembler.hpp" diff --git a/src/hotspot/cpu/x86/compiledIC_x86.cpp b/src/hotspot/cpu/x86/compiledIC_x86.cpp index 51563d35d5dfd..53ad9aeec9162 100644 --- a/src/hotspot/cpu/x86/compiledIC_x86.cpp +++ b/src/hotspot/cpu/x86/compiledIC_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/x86/compressedKlass_x86.cpp b/src/hotspot/cpu/x86/compressedKlass_x86.cpp index 5b5a405bcef86..8a06a7ba3d503 100644 --- a/src/hotspot/cpu/x86/compressedKlass_x86.cpp +++ b/src/hotspot/cpu/x86/compressedKlass_x86.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #ifdef _LP64 #include "oops/compressedKlass.hpp" diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp index 4e549552e96da..3c7d93fc79e91 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/downcallLinker.hpp" RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 00cc69651f15f..7f531ca56b143 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/codeBlob.hpp" #include "logging/logStream.hpp" diff --git a/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp b/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp index c62021c32637c..18aa454e61cbf 100644 --- a/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp +++ b/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/vmreg.hpp" #include "prims/foreignGlobals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp b/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp index 658ff6fecddb9..cc5627f6ffd82 100644 --- a/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp +++ b/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "runtime/jniHandles.inline.hpp" #include "oops/typeArrayOop.inline.hpp" diff --git a/src/hotspot/cpu/x86/frame_x86.cpp b/src/hotspot/cpu/x86/frame_x86.cpp index 4e28dc125341a..a5700134f60c7 100644 --- a/src/hotspot/cpu/x86/frame_x86.cpp +++ b/src/hotspot/cpu/x86/frame_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" @@ -154,6 +153,11 @@ bool frame::safe_for_sender(JavaThread *thread) { } if (Continuation::is_return_barrier_entry(sender_pc)) { + // sender_pc might be invalid so check that the frame + // actually belongs to a Continuation. + if (!Continuation::is_frame_in_continuation(thread, *this)) { + return false; + } // If our sender_pc is the return barrier, then our "real" sender is the continuation entry frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp); sender_sp = s.sp(); diff --git a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp index 5af36d84e6ed8..4aa02c4d6278b 100644 --- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp index cd0e43b68bf9e..50dea42d5a300 100644 --- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp index dfd9d59016f0a..e99774cbc401a 100644 --- a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nativeInst.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp index b04ab35862a3e..7954ce38d03ef 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" diff --git a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp index 618095bdfa634..76066409a7caa 100644 --- a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/modRefBarrierSetAssembler.hpp" diff --git a/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp index eb6da25d1bc7a..063f4c2cc5ddf 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIRAssembler.hpp" #include "c1/c1_MacroAssembler.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp index a452850b1e814..75ab8fca05152 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" diff --git a/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp b/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp index ed177f37e0d45..3667a52050c7a 100644 --- a/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" diff --git a/src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp b/src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp index e0be06395946a..d0816aee74f76 100644 --- a/src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp +++ b/src/hotspot/cpu/x86/gc/z/zAddress_x86.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ inline uintptr_t ZPointer::remap_bits(uintptr_t colored) { inline constexpr int ZPointer::load_shift_lookup(uintptr_t value) { const size_t index = load_shift_lookup_index(value); - assert(index == 0 || is_power_of_2(index), "Incorrect load shift: " SIZE_FORMAT, index); + assert(index == 0 || is_power_of_2(index), "Incorrect load shift: %zu", index); return ZPointerLoadShiftTable[index]; } diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp index 1bc8e5c45443b..f7b1e25cf3b5d 100644 --- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/codeBlob.hpp" #include "code/vmreg.inline.hpp" diff --git a/src/hotspot/cpu/x86/icache_x86.cpp b/src/hotspot/cpu/x86/icache_x86.cpp index b9ec2f6d18649..45679332ecaca 100644 --- a/src/hotspot/cpu/x86/icache_x86.cpp +++ b/src/hotspot/cpu/x86/icache_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "runtime/icache.hpp" diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 3a3f01a640983..44087663a34b5 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compiler_globals.hpp" #include "interp_masm_x86.hpp" #include "interpreter/interpreter.hpp" @@ -1030,7 +1029,7 @@ void InterpreterMacroAssembler::remove_activation( // get method access flags movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); - movl(rcx, Address(rcx, Method::access_flags_offset())); + load_unsigned_short(rcx, Address(rcx, Method::access_flags_offset())); testl(rcx, JVM_ACC_SYNCHRONIZED); jcc(Assembler::zero, unlocked); diff --git a/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp b/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp index 4f463b1d77140..14f11596924a5 100644 --- a/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp +++ b/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp index c37287635bab9..8909df5b3f081 100644 --- a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp +++ b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp index 123362894122c..eee82a5c6820e 100644 --- a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "memory/resourceArea.hpp" #include "prims/jniFastGetField.hpp" diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp index e94b7d12b0b3c..09ba4537854fa 100644 --- a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/codeBlob.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp index 8eff2590bfcea..9e6a4789dc2cd 100644 --- a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp +++ b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "compiler/disassembler.hpp" #include "oops/compressedKlass.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index a798dea08cc79..00f9358de6706 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "code/compiledIC.hpp" @@ -779,9 +778,17 @@ void MacroAssembler::warn(const char* msg) { andq(rsp, -16); // align stack as required by push_CPU_state and call push_CPU_state(); // keeps alignment at 16 bytes +#ifdef _WIN64 + // Windows always allocates space for its register args + subq(rsp, frame::arg_reg_save_area_bytes); +#endif lea(c_rarg0, ExternalAddress((address) msg)); call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); +#ifdef _WIN64 + // restore stack pointer + addq(rsp, frame::arg_reg_save_area_bytes); +#endif pop_CPU_state(); mov(rsp, rbp); pop(rbp); @@ -1194,7 +1201,11 @@ void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src, Register rscratc assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes"); assert(rscratch != noreg || always_reachable(src), "missing"); - if (reachable(src)) { + if (UseAVX > 2 && + (!VM_Version::supports_avx512dq() || !VM_Version::supports_avx512vl()) && + (dst->encoding() >= 16)) { + vpand(dst, dst, src, AVX_512bit, rscratch); + } else if (reachable(src)) { Assembler::andpd(dst, as_Address(src)); } else { lea(rscratch, src); @@ -2376,6 +2387,22 @@ void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst, Register rscratch } } +void MacroAssembler::cmp32_mxcsr_std(Address mxcsr_save, Register tmp, Register rscratch) { + ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); + assert(rscratch != noreg || always_reachable(mxcsr_std), "missing"); + + stmxcsr(mxcsr_save); + movl(tmp, mxcsr_save); + if (EnableX86ECoreOpts) { + // The mxcsr_std has status bits set for performance on ECore + orl(tmp, 0x003f); + } else { + // Mask out status bits (only check control and mask bits) + andl(tmp, 0xFFC0); + } + cmp32(tmp, mxcsr_std, rscratch); +} + void MacroAssembler::ldmxcsr(AddressLiteral src, Register rscratch) { assert(rscratch != noreg || always_reachable(src), "missing"); @@ -3332,7 +3359,12 @@ void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src, Register rscratc // Used in sign-bit flipping with aligned address. assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes"); - if (reachable(src)) { + + if (UseAVX > 2 && + (!VM_Version::supports_avx512dq() || !VM_Version::supports_avx512vl()) && + (dst->encoding() >= 16)) { + vpxor(dst, dst, src, Assembler::AVX_512bit, rscratch); + } else if (reachable(src)) { Assembler::xorpd(dst, as_Address(src)); } else { lea(rscratch, src); @@ -3341,16 +3373,19 @@ void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src, Register rscratc } void MacroAssembler::xorpd(XMMRegister dst, XMMRegister src) { - if (UseAVX > 2 && !VM_Version::supports_avx512dq() && (dst->encoding() == src->encoding())) { + if (UseAVX > 2 && + (!VM_Version::supports_avx512dq() || !VM_Version::supports_avx512vl()) && + ((dst->encoding() >= 16) || (src->encoding() >= 16))) { Assembler::vpxor(dst, dst, src, Assembler::AVX_512bit); - } - else { + } else { Assembler::xorpd(dst, src); } } void MacroAssembler::xorps(XMMRegister dst, XMMRegister src) { - if (UseAVX > 2 && !VM_Version::supports_avx512dq() && (dst->encoding() == src->encoding())) { + if (UseAVX > 2 && + (!VM_Version::supports_avx512dq() || !VM_Version::supports_avx512vl()) && + ((dst->encoding() >= 16) || (src->encoding() >= 16))) { Assembler::vpxor(dst, dst, src, Assembler::AVX_512bit); } else { Assembler::xorps(dst, src); @@ -3362,7 +3397,12 @@ void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src, Register rscratc // Used in sign-bit flipping with aligned address. assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes"); - if (reachable(src)) { + + if (UseAVX > 2 && + (!VM_Version::supports_avx512dq() || !VM_Version::supports_avx512vl()) && + (dst->encoding() >= 16)) { + vpxor(dst, dst, src, Assembler::AVX_512bit, rscratch); + } else if (reachable(src)) { Assembler::xorps(dst, as_Address(src)); } else { lea(rscratch, src); @@ -9120,14 +9160,14 @@ void MacroAssembler::crc32c_ipl_alg2_alt2(Register in_out, Register in1, Registe Label L_exit; if (is_pclmulqdq_supported ) { - const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr; - const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr+1); + const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::crc32c_table_addr(); + const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 1); - const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2); - const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3); + const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 2); + const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 3); - const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4); - const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5); + const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 4); + const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 5); assert((CRC32C_NUM_PRECOMPUTED_CONSTANTS - 1 ) == 5, "Checking whether you declared all of the constants based on the number of \"chunks\""); } else { const_or_pre_comp_const_index[0] = 1; @@ -9200,14 +9240,14 @@ void MacroAssembler::crc32c_ipl_alg2_alt2(Register in_out, Register in1, Registe Label L_exit; if (is_pclmulqdq_supported) { - const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::_crc32c_table_addr; - const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 1); + const_or_pre_comp_const_index[1] = *(uint32_t *)StubRoutines::crc32c_table_addr(); + const_or_pre_comp_const_index[0] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 1); - const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 2); - const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 3); + const_or_pre_comp_const_index[3] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 2); + const_or_pre_comp_const_index[2] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 3); - const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 4); - const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::_crc32c_table_addr + 5); + const_or_pre_comp_const_index[5] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 4); + const_or_pre_comp_const_index[4] = *((uint32_t *)StubRoutines::crc32c_table_addr() + 5); } else { const_or_pre_comp_const_index[0] = 1; const_or_pre_comp_const_index[1] = 0; diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index c6e5b2a115f03..b6f229661a8e9 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -1135,6 +1135,7 @@ class MacroAssembler: public Assembler { void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); } #endif // !_LP64 + void cmp32_mxcsr_std(Address mxcsr_save, Register tmp, Register rscratch = noreg); void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } void ldmxcsr(AddressLiteral src, Register rscratch = noreg); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_constants.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_constants.cpp index e177c7d94624b..6fdda4c2f7130 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_constants.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_constants.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" ATTRIBUTE_ALIGNED(16) static const juint _ONES[] = { diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_cos.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_cos.cpp index ce71bb50d8232..dce16756a6651 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_cos.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_cos.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_exp.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_exp.cpp index a490510b959d3..2e6c1a617bb85 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_exp.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_exp.cpp @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_log.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_log.cpp index 515717e2179ca..abaabef674105 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_log.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_log.cpp @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_log10.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_log10.cpp index fa8c3b4623518..1fc5f49cf7503 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_log10.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_log10.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_pow.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_pow.cpp index 7afad2fcc73b2..2d8a8ef91ac4f 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_pow.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_pow.cpp @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_sin.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_sin.cpp index 492d596f84b46..cd593ba335648 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_sin.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_sin.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_32_tan.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_32_tan.cpp index f2bc1efb483f9..4e8be8a1f1dc7 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_32_tan.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_32_tan.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "macroAssembler_x86.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_md5.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_md5.cpp index 09d379a4296d4..9d48838ab6e1b 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_md5.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_md5.cpp @@ -43,7 +43,6 @@ * Software. */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp index e7d728c2e9672..5fd6db868cc8b 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp index fd738b7333e4f..0d95af133fa81 100644 --- a/src/hotspot/cpu/x86/methodHandles_x86.cpp +++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/vmClasses.hpp" #include "compiler/disassembler.hpp" diff --git a/src/hotspot/cpu/x86/nativeInst_x86.cpp b/src/hotspot/cpu/x86/nativeInst_x86.cpp index d5021c29ed6b0..4ee741077dc06 100644 --- a/src/hotspot/cpu/x86/nativeInst_x86.cpp +++ b/src/hotspot/cpu/x86/nativeInst_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/compiledIC.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/cpu/x86/peephole_x86_64.cpp b/src/hotspot/cpu/x86/peephole_x86_64.cpp index 92a29490edaf8..2197055d1ecc0 100644 --- a/src/hotspot/cpu/x86/peephole_x86_64.cpp +++ b/src/hotspot/cpu/x86/peephole_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #ifdef COMPILER2 diff --git a/src/hotspot/cpu/x86/rdtsc_x86.cpp b/src/hotspot/cpu/x86/rdtsc_x86.cpp index 8a927dd15e4e4..aac336019508d 100644 --- a/src/hotspot/cpu/x86/rdtsc_x86.cpp +++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "rdtsc_x86.hpp" #include "runtime/globals_extension.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/cpu/x86/registerMap_x86.cpp b/src/hotspot/cpu/x86/registerMap_x86.cpp index 34713ec4d38c9..295a8c0eb896b 100644 --- a/src/hotspot/cpu/x86/registerMap_x86.cpp +++ b/src/hotspot/cpu/x86/registerMap_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/registerMap.hpp" #include "vmreg_x86.inline.hpp" diff --git a/src/hotspot/cpu/x86/register_x86.cpp b/src/hotspot/cpu/x86/register_x86.cpp index dc5aba3c17801..e60834293445b 100644 --- a/src/hotspot/cpu/x86/register_x86.cpp +++ b/src/hotspot/cpu/x86/register_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "register_x86.hpp" diff --git a/src/hotspot/cpu/x86/relocInfo_x86.cpp b/src/hotspot/cpu/x86/relocInfo_x86.cpp index 2df98c4311b2c..a447c5aca9d92 100644 --- a/src/hotspot/cpu/x86/relocInfo_x86.cpp +++ b/src/hotspot/cpu/x86/relocInfo_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/relocInfo.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/cpu/x86/runtime_x86_32.cpp b/src/hotspot/cpu/x86/runtime_x86_32.cpp index 9bd4239d665f3..bcba609387132 100644 --- a/src/hotspot/cpu/x86/runtime_x86_32.cpp +++ b/src/hotspot/cpu/x86/runtime_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" diff --git a/src/hotspot/cpu/x86/runtime_x86_64.cpp b/src/hotspot/cpu/x86/runtime_x86_64.cpp index 45f863b697b6b..d7d8fc1895b38 100644 --- a/src/hotspot/cpu/x86/runtime_x86_64.cpp +++ b/src/hotspot/cpu/x86/runtime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifdef COMPILER2 #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86.cpp index ebdd47f3a3f87..0a277a4eb69f6 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/sharedRuntime.hpp" diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp index a6a662b3d1e0c..8e5e54f244cf9 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index ab7cbb9437453..bbe62db33f00e 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifndef _WINDOWS #include "alloca.h" #endif @@ -1099,7 +1098,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm { // Bypass the barrier for non-static methods Register flags = rscratch1; - __ movl(flags, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(flags, Address(method, Method::access_flags_offset())); __ testl(flags, JVM_ACC_STATIC); __ jcc(Assembler::zero, L_skip_barrier); // non-static } @@ -3020,7 +3019,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal // Allocate space for the code. Setup code generation tools. const char* name = SharedRuntime::stub_name(id); - CodeBuffer buffer(name, 2348, 1024); + CodeBuffer buffer(name, 2548, 1024); MacroAssembler* masm = new MacroAssembler(&buffer); address start = __ pc(); @@ -3086,11 +3085,11 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal Label bail; #endif if (!cause_return) { - Label no_prefix, not_special; + Label no_prefix, not_special, check_rex_prefix; // If our stashed return pc was modified by the runtime we avoid touching it __ cmpptr(rbx, Address(rbp, wordSize)); - __ jccb(Assembler::notEqual, no_adjust); + __ jcc(Assembler::notEqual, no_adjust); // Skip over the poll instruction. // See NativeInstruction::is_safepoint_poll() @@ -3113,9 +3112,29 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal // 41 85 04 24 test %eax,(%r12) // 85 45 00 test %eax,0x0(%rbp) // 41 85 45 00 test %eax,0x0(%r13) - + // + // Notes: + // Format of legacy MAP0 test instruction:- + // [REX/REX2] [OPCODE] [ModRM] [SIB] [DISP] [IMM32] + // o For safepoint polling instruction "test %eax,(%rax)", encoding of first register + // operand and base register of memory operand is b/w [0-8), hence we do not require + // additional REX prefix where REX.B bit stores MSB bit of register encoding, which + // is why two bytes encoding is sufficient here. + // o For safepoint polling instruction like "test %eax,(%r8)", register encoding of BASE + // register of memory operand is 1000, thus we need additional REX prefix in this case, + // there by adding additional byte to instruction encoding. + // o In case BASE register is one of the 32 extended GPR registers available only on targets + // supporting Intel APX extension, then we need to emit two bytes REX2 prefix to hold + // most significant two bits of 5 bit register encoding. + + if (VM_Version::supports_apx_f()) { + __ cmpb(Address(rbx, 0), Assembler::REX2); + __ jccb(Assembler::notEqual, check_rex_prefix); + __ addptr(rbx, 2); + __ bind(check_rex_prefix); + } __ cmpb(Address(rbx, 0), NativeTstRegMem::instruction_rex_b_prefix); - __ jcc(Assembler::notEqual, no_prefix); + __ jccb(Assembler::notEqual, no_prefix); __ addptr(rbx, 1); __ bind(no_prefix); #ifdef ASSERT @@ -3128,7 +3147,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05 __ subptr(rcx, 4); // looking for 0x00 .. 0x01 __ cmpptr(rcx, 1); - __ jcc(Assembler::above, not_special); + __ jccb(Assembler::above, not_special); __ addptr(rbx, 1); __ bind(not_special); #ifdef ASSERT diff --git a/src/hotspot/cpu/x86/stubDeclarations_x86.hpp b/src/hotspot/cpu/x86/stubDeclarations_x86.hpp new file mode 100644 index 0000000000000..9f6c1ec60ef19 --- /dev/null +++ b/src/hotspot/cpu/x86/stubDeclarations_x86.hpp @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_X86_STUBDECLARATIONS_HPP +#define CPU_X86_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 20000 WINDOWS_ONLY(+1000)) \ + do_stub(initial, verify_mxcsr) \ + do_arch_entry(x86, initial, verify_mxcsr, verify_mxcsr_entry, \ + verify_mxcsr_entry) \ + LP64_ONLY( \ + do_stub(initial, get_previous_sp) \ + do_arch_entry(x86, initial, get_previous_sp, \ + get_previous_sp_entry, \ + get_previous_sp_entry) \ + do_stub(initial, f2i_fixup) \ + do_arch_entry(x86, initial, f2i_fixup, f2i_fixup, f2i_fixup) \ + do_stub(initial, f2l_fixup) \ + do_arch_entry(x86, initial, f2l_fixup, f2l_fixup, f2l_fixup) \ + do_stub(initial, d2i_fixup) \ + do_arch_entry(x86, initial, d2i_fixup, d2i_fixup, d2i_fixup) \ + do_stub(initial, d2l_fixup) \ + do_arch_entry(x86, initial, d2l_fixup, d2l_fixup, d2l_fixup) \ + do_stub(initial, float_sign_mask) \ + do_arch_entry(x86, initial, float_sign_mask, float_sign_mask, \ + float_sign_mask) \ + do_stub(initial, float_sign_flip) \ + do_arch_entry(x86, initial, float_sign_flip, float_sign_flip, \ + float_sign_flip) \ + do_stub(initial, double_sign_mask) \ + do_arch_entry(x86, initial, double_sign_mask, double_sign_mask, \ + double_sign_mask) \ + do_stub(initial, double_sign_flip) \ + do_arch_entry(x86, initial, double_sign_flip, double_sign_flip, \ + double_sign_flip) \ + ) \ + NOT_LP64( \ + do_stub(initial, verify_fpu_cntrl_word) \ + do_arch_entry(x86, initial, verify_fpu_cntrl_word, \ + verify_fpu_cntrl_wrd_entry, \ + verify_fpu_cntrl_wrd_entry) \ + do_stub(initial, d2i_wrapper) \ + do_arch_entry(x86, initial, d2i_wrapper, d2i_wrapper, \ + d2i_wrapper) \ + do_stub(initial, d2l_wrapper) \ + do_arch_entry(x86, initial, d2l_wrapper, d2l_wrapper, \ + d2l_wrapper) \ + ) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 1000 LP64_ONLY(+2000)) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 20000 LP64_ONLY(+64000) WINDOWS_ONLY(+2000)) \ + do_stub(compiler, vector_float_sign_mask) \ + do_arch_entry(x86, compiler, vector_float_sign_mask, \ + vector_float_sign_mask, vector_float_sign_mask) \ + do_stub(compiler, vector_float_sign_flip) \ + do_arch_entry(x86, compiler, vector_float_sign_flip, \ + vector_float_sign_flip, vector_float_sign_flip) \ + do_stub(compiler, vector_double_sign_mask) \ + do_arch_entry(x86, compiler, vector_double_sign_mask, \ + vector_double_sign_mask, vector_double_sign_mask) \ + do_stub(compiler, vector_double_sign_flip) \ + do_arch_entry(x86, compiler, vector_double_sign_flip, \ + vector_double_sign_flip, vector_double_sign_flip) \ + do_stub(compiler, vector_all_bits_set) \ + do_arch_entry(x86, compiler, vector_all_bits_set, \ + vector_all_bits_set, vector_all_bits_set) \ + do_stub(compiler, vector_int_mask_cmp_bits) \ + do_arch_entry(x86, compiler, vector_int_mask_cmp_bits, \ + vector_int_mask_cmp_bits, vector_int_mask_cmp_bits) \ + do_stub(compiler, vector_short_to_byte_mask) \ + do_arch_entry(x86, compiler, vector_short_to_byte_mask, \ + vector_short_to_byte_mask, vector_short_to_byte_mask) \ + do_stub(compiler, vector_byte_perm_mask) \ + do_arch_entry(x86, compiler,vector_byte_perm_mask, \ + vector_byte_perm_mask, vector_byte_perm_mask) \ + do_stub(compiler, vector_int_to_byte_mask) \ + do_arch_entry(x86, compiler, vector_int_to_byte_mask, \ + vector_int_to_byte_mask, vector_int_to_byte_mask) \ + do_stub(compiler, vector_int_to_short_mask) \ + do_arch_entry(x86, compiler, vector_int_to_short_mask, \ + vector_int_to_short_mask, vector_int_to_short_mask) \ + do_stub(compiler, vector_32_bit_mask) \ + do_arch_entry(x86, compiler, vector_32_bit_mask, \ + vector_32_bit_mask, vector_32_bit_mask) \ + do_stub(compiler, vector_64_bit_mask) \ + do_arch_entry(x86, compiler, vector_64_bit_mask, \ + vector_64_bit_mask, vector_64_bit_mask) \ + do_stub(compiler, vector_byte_shuffle_mask) \ + do_arch_entry(x86, compiler, vector_int_shuffle_mask, \ + vector_byte_shuffle_mask, vector_byte_shuffle_mask) \ + do_stub(compiler, vector_short_shuffle_mask) \ + do_arch_entry(x86, compiler, vector_int_shuffle_mask, \ + vector_short_shuffle_mask, vector_short_shuffle_mask) \ + do_stub(compiler, vector_int_shuffle_mask) \ + do_arch_entry(x86, compiler, vector_int_shuffle_mask, \ + vector_int_shuffle_mask, vector_int_shuffle_mask) \ + do_stub(compiler, vector_long_shuffle_mask) \ + do_arch_entry(x86, compiler, vector_long_shuffle_mask, \ + vector_long_shuffle_mask, vector_long_shuffle_mask) \ + do_stub(compiler, vector_long_sign_mask) \ + do_arch_entry(x86, compiler, vector_long_sign_mask, \ + vector_long_sign_mask, vector_long_sign_mask) \ + do_stub(compiler, vector_iota_indices) \ + do_arch_entry(x86, compiler, vector_iota_indices, \ + vector_iota_indices, vector_iota_indices) \ + do_stub(compiler, vector_count_leading_zeros_lut) \ + do_arch_entry(x86, compiler, vector_count_leading_zeros_lut, \ + vector_count_leading_zeros_lut, \ + vector_count_leading_zeros_lut) \ + do_stub(compiler, vector_reverse_bit_lut) \ + do_arch_entry(x86, compiler, vector_reverse_bit_lut, \ + vector_reverse_bit_lut, vector_reverse_bit_lut) \ + do_stub(compiler, vector_reverse_byte_perm_mask_short) \ + do_arch_entry(x86, compiler, vector_reverse_byte_perm_mask_short, \ + vector_reverse_byte_perm_mask_short, \ + vector_reverse_byte_perm_mask_short) \ + do_stub(compiler, vector_reverse_byte_perm_mask_int) \ + do_arch_entry(x86, compiler, vector_reverse_byte_perm_mask_int, \ + vector_reverse_byte_perm_mask_int, \ + vector_reverse_byte_perm_mask_int) \ + do_stub(compiler, vector_reverse_byte_perm_mask_long) \ + do_arch_entry(x86, compiler, vector_reverse_byte_perm_mask_long, \ + vector_reverse_byte_perm_mask_long, \ + vector_reverse_byte_perm_mask_long) \ + do_stub(compiler, vector_popcount_lut) \ + do_arch_entry(x86, compiler, vector_popcount_lut, \ + vector_popcount_lut, vector_popcount_lut) \ + do_stub(compiler, upper_word_mask) \ + do_arch_entry(x86, compiler, upper_word_mask, upper_word_mask_addr, \ + upper_word_mask_addr) \ + do_stub(compiler, shuffle_byte_flip_mask) \ + do_arch_entry(x86, compiler, shuffle_byte_flip_mask, \ + shuffle_byte_flip_mask_addr, \ + shuffle_byte_flip_mask_addr) \ + do_stub(compiler, pshuffle_byte_flip_mask) \ + do_arch_entry(x86, compiler, pshuffle_byte_flip_mask, \ + pshuffle_byte_flip_mask_addr, \ + pshuffle_byte_flip_mask_addr) \ + LP64_ONLY( \ + /* x86_64 exposes these 3 stubs via a generic entry array */ \ + /* oher arches use arch-specific entries */ \ + /* this really needs rationalising */ \ + do_stub(compiler, string_indexof_linear_ll) \ + do_stub(compiler, string_indexof_linear_uu) \ + do_stub(compiler, string_indexof_linear_ul) \ + do_stub(compiler, pshuffle_byte_flip_mask_sha512) \ + do_arch_entry(x86, compiler, pshuffle_byte_flip_mask_sha512, \ + pshuffle_byte_flip_mask_addr_sha512, \ + pshuffle_byte_flip_mask_addr_sha512) \ + do_stub(compiler, compress_perm_table32) \ + do_arch_entry(x86, compiler, compress_perm_table32, \ + compress_perm_table32, compress_perm_table32) \ + do_stub(compiler, compress_perm_table64) \ + do_arch_entry(x86, compiler, compress_perm_table64, \ + compress_perm_table64, compress_perm_table64) \ + do_stub(compiler, expand_perm_table32) \ + do_arch_entry(x86, compiler, expand_perm_table32, \ + expand_perm_table32, expand_perm_table32) \ + do_stub(compiler, expand_perm_table64) \ + do_arch_entry(x86, compiler, expand_perm_table64, \ + expand_perm_table64, expand_perm_table64) \ + do_stub(compiler, avx2_shuffle_base64) \ + do_arch_entry(x86, compiler, avx2_shuffle_base64, \ + avx2_shuffle_base64, base64_avx2_shuffle_addr) \ + do_stub(compiler, avx2_input_mask_base64) \ + do_arch_entry(x86, compiler, avx2_input_mask_base64, \ + avx2_input_mask_base64, \ + base64_avx2_input_mask_addr) \ + do_stub(compiler, avx2_lut_base64) \ + do_arch_entry(x86, compiler, avx2_lut_base64, \ + avx2_lut_base64, base64_avx2_lut_addr) \ + do_stub(compiler, avx2_decode_tables_base64) \ + do_arch_entry(x86, compiler, avx2_decode_tables_base64, \ + avx2_decode_tables_base64, \ + base64_AVX2_decode_tables_addr) \ + do_stub(compiler, avx2_decode_lut_tables_base64) \ + do_arch_entry(x86, compiler, avx2_decode_lut_tables_base64, \ + avx2_decode_lut_tables_base64, \ + base64_AVX2_decode_LUT_tables_addr) \ + do_stub(compiler, shuffle_base64) \ + do_arch_entry(x86, compiler, shuffle_base64, shuffle_base64, \ + base64_shuffle_addr) \ + do_stub(compiler, lookup_lo_base64) \ + do_arch_entry(x86, compiler, lookup_lo_base64, lookup_lo_base64, \ + base64_vbmi_lookup_lo_addr) \ + do_stub(compiler, lookup_hi_base64) \ + do_arch_entry(x86, compiler, lookup_hi_base64, lookup_hi_base64, \ + base64_vbmi_lookup_hi_addr) \ + do_stub(compiler, lookup_lo_base64url) \ + do_arch_entry(x86, compiler, lookup_lo_base64url, \ + lookup_lo_base64url, \ + base64_vbmi_lookup_lo_url_addr) \ + do_stub(compiler, lookup_hi_base64url) \ + do_arch_entry(x86, compiler, lookup_hi_base64url, \ + lookup_hi_base64url, \ + base64_vbmi_lookup_hi_url_addr) \ + do_stub(compiler, pack_vec_base64) \ + do_arch_entry(x86, compiler, pack_vec_base64, pack_vec_base64, \ + base64_vbmi_pack_vec_addr) \ + do_stub(compiler, join_0_1_base64) \ + do_arch_entry(x86, compiler, join_0_1_base64, join_0_1_base64, \ + base64_vbmi_join_0_1_addr) \ + do_stub(compiler, join_1_2_base64) \ + do_arch_entry(x86, compiler, join_1_2_base64, join_1_2_base64, \ + base64_vbmi_join_1_2_addr) \ + do_stub(compiler, join_2_3_base64) \ + do_arch_entry(x86, compiler, join_2_3_base64, join_2_3_base64, \ + base64_vbmi_join_2_3_addr) \ + do_stub(compiler, encoding_table_base64) \ + do_arch_entry(x86, compiler, encoding_table_base64, \ + encoding_table_base64, base64_encoding_table_addr) \ + do_stub(compiler, decoding_table_base64) \ + do_arch_entry(x86, compiler, decoding_table_base64, \ + decoding_table_base64, base64_decoding_table_addr) \ + ) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 11000 LP64_ONLY(+20000) \ + WINDOWS_ONLY(+22000) ZGC_ONLY(+20000)) \ + +#endif // CPU_X86_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp index de13772dcfb0d..27dc804a73d28 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/oopMap.hpp" @@ -62,7 +61,6 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") -const int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions const int FPU_CNTRL_WRD_MASK = 0xFFFF; ATTRIBUTE_ALIGNED(16) static const uint32_t KEY_SHUFFLE_MASK[] = { @@ -138,7 +136,8 @@ class StubGenerator: public StubCodeGenerator { address generate_call_stub(address& return_address) { - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // stub code parameters / addresses @@ -175,11 +174,7 @@ class StubGenerator: public StubCodeGenerator { // save and initialize %mxcsr if (sse_save) { Label skip_ldmx; - __ stmxcsr(mxcsr_save); - __ movl(rax, mxcsr_save); - __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); - __ cmp32(rax, mxcsr_std); + __ cmp32_mxcsr_std(mxcsr_save, rax); __ jcc(Assembler::equal, skip_ldmx); __ ldmxcsr(mxcsr_std); __ bind(skip_ldmx); @@ -340,7 +335,8 @@ class StubGenerator: public StubCodeGenerator { // rax,: exception oop address generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_call_stub()! const Address thread (rbp, 9 * wordSize); // same as in generate_call_stub()! address start = __ pc(); @@ -383,7 +379,8 @@ class StubGenerator: public StubCodeGenerator { // NOTE: At entry of this stub, exception-pc must be on stack !! address generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register thread = rcx; @@ -455,24 +452,22 @@ class StubGenerator: public StubCodeGenerator { address generate_verify_mxcsr() { - StubCodeMark mark(this, "StubRoutines", "verify_mxcsr"); + StubGenStubId stub_id = StubGenStubId::verify_mxcsr_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Address mxcsr_save(rsp, 0); if (CheckJNICalls && UseSSE > 0 ) { Label ok_ret; - ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); __ push(rax); __ subptr(rsp, wordSize); // allocate a temp location - __ stmxcsr(mxcsr_save); - __ movl(rax, mxcsr_save); - __ andl(rax, MXCSR_MASK); - __ cmp32(rax, mxcsr_std); + __ cmp32_mxcsr_std(mxcsr_save, rax); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code."); + ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); __ ldmxcsr(mxcsr_std); __ bind(ok_ret); @@ -494,7 +489,8 @@ class StubGenerator: public StubCodeGenerator { // FP control word to our expected state. address generate_verify_fpu_cntrl_wrd() { - StubCodeMark mark(this, "StubRoutines", "verify_spcw"); + StubGenStubId stub_id = StubGenStubId::verify_fpu_cntrl_word_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Address fpu_cntrl_wrd_save(rsp, 0); @@ -532,7 +528,8 @@ class StubGenerator: public StubCodeGenerator { // Output: rax, (rdx): integer (long) result address generate_d2i_wrapper(BasicType t, address fcn) { - StubCodeMark mark(this, "StubRoutines", "d2i_wrapper"); + StubGenStubId stub_id = StubGenStubId::d2i_wrapper_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Capture info about frame layout @@ -592,9 +589,9 @@ class StubGenerator: public StubCodeGenerator { } //--------------------------------------------------------------------------------------------------- - address generate_vector_mask(const char *stub_name, int32_t mask) { + address generate_vector_mask(StubGenStubId stub_id, int32_t mask) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); for (int i = 0; i < 16; i++) { @@ -604,9 +601,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_count_leading_zeros_lut(const char *stub_name) { + address generate_count_leading_zeros_lut() { __ align64(); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_count_leading_zeros_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x02020304, relocInfo::none, 0); __ emit_data(0x01010101, relocInfo::none, 0); @@ -628,9 +626,10 @@ class StubGenerator: public StubCodeGenerator { } - address generate_popcount_avx_lut(const char *stub_name) { + address generate_popcount_avx_lut() { __ align64(); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_popcount_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x02010100, relocInfo::none, 0); __ emit_data(0x03020201, relocInfo::none, 0); @@ -652,9 +651,10 @@ class StubGenerator: public StubCodeGenerator { } - address generate_iota_indices(const char *stub_name) { + address generate_iota_indices() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_iota_indices_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // B __ emit_data(0x03020100, relocInfo::none, 0); @@ -766,9 +766,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_reverse_bit_lut(const char *stub_name) { + address generate_vector_reverse_bit_lut() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_bit_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x0C040800, relocInfo::none, 0); __ emit_data(0x0E060A02, relocInfo::none, 0); @@ -789,9 +790,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_reverse_byte_perm_mask_long(const char *stub_name) { + address generate_vector_reverse_byte_perm_mask_long() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_long_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x04050607, relocInfo::none, 0); __ emit_data(0x00010203, relocInfo::none, 0); @@ -812,9 +814,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_reverse_byte_perm_mask_int(const char *stub_name) { + address generate_vector_reverse_byte_perm_mask_int() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_int_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x00010203, relocInfo::none, 0); __ emit_data(0x04050607, relocInfo::none, 0); @@ -835,9 +838,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_reverse_byte_perm_mask_short(const char *stub_name) { + address generate_vector_reverse_byte_perm_mask_short() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_short_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x02030001, relocInfo::none, 0); __ emit_data(0x06070405, relocInfo::none, 0); @@ -858,9 +862,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_byte_shuffle_mask(const char *stub_name) { + address generate_vector_byte_shuffle_mask() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_byte_shuffle_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x70707070, relocInfo::none, 0); __ emit_data(0x70707070, relocInfo::none, 0); @@ -873,9 +878,9 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_mask_long_double(const char *stub_name, int32_t maskhi, int32_t masklo) { + address generate_vector_mask_long_double(StubGenStubId stub_id, int32_t maskhi, int32_t masklo) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); for (int i = 0; i < 8; i++) { @@ -888,9 +893,10 @@ class StubGenerator: public StubCodeGenerator { //---------------------------------------------------------------------------------------------------- - address generate_vector_byte_perm_mask(const char *stub_name) { + address generate_vector_byte_perm_mask() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_byte_perm_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x00000001, relocInfo::none, 0); @@ -913,13 +919,13 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_vector_custom_i32(const char *stub_name, Assembler::AvxVectorLen len, + address generate_vector_custom_i32(StubGenStubId stub_id, Assembler::AvxVectorLen len, int32_t val0, int32_t val1, int32_t val2, int32_t val3, int32_t val4 = 0, int32_t val5 = 0, int32_t val6 = 0, int32_t val7 = 0, int32_t val8 = 0, int32_t val9 = 0, int32_t val10 = 0, int32_t val11 = 0, int32_t val12 = 0, int32_t val13 = 0, int32_t val14 = 0, int32_t val15 = 0) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(len != Assembler::AVX_NoVec, "vector len must be specified"); @@ -951,7 +957,8 @@ class StubGenerator: public StubCodeGenerator { // Non-destructive plausibility checks for oops address generate_verify_oop() { - StubCodeMark mark(this, "StubRoutines", "verify_oop"); + StubGenStubId stub_id = StubGenStubId::verify_oop_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Incoming arguments on stack after saving rax,: @@ -1083,12 +1090,82 @@ class StubGenerator: public StubCodeGenerator { __ BIND(L_exit); } - address generate_disjoint_copy(BasicType t, bool aligned, - Address::ScaleFactor sf, - address* entry, const char *name, - bool dest_uninitialized = false) { + address generate_disjoint_copy(StubGenStubId stub_id, address* entry) { + BasicType t; + bool aligned; + Address::ScaleFactor sf; + bool dest_uninitialized; + + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + t = T_BYTE; + aligned = false; + sf = Address::times_1; + dest_uninitialized = false; + break; + case arrayof_jbyte_disjoint_arraycopy_id: + t = T_BYTE; + aligned = true; + sf = Address::times_1; + dest_uninitialized = false; + break; + case jshort_disjoint_arraycopy_id: + t = T_SHORT; + aligned = false; + sf = Address::times_2; + dest_uninitialized = false; + break; + case arrayof_jshort_disjoint_arraycopy_id: + t = T_SHORT; + aligned = true; + sf = Address::times_2; + dest_uninitialized = false; + break; + case jint_disjoint_arraycopy_id: + t = T_INT; + aligned = true; + sf = Address::times_4; + dest_uninitialized = false; + break; + case arrayof_jint_disjoint_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case jint_disjoint_arraycopy + ShouldNotReachHere(); + break; + case jlong_disjoint_arraycopy_id: + case arrayof_jlong_disjoint_arraycopy_id: + // Handled by a special generator routine on 32 bit + ShouldNotReachHere(); + break; + case oop_disjoint_arraycopy_id: + t = T_OBJECT; + aligned = true; + sf = Address::times_ptr; + dest_uninitialized = false; + break; + case arrayof_oop_disjoint_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case oop_disjoint_arraycopy + ShouldNotReachHere(); + break; + case oop_disjoint_arraycopy_uninit_id: + t = T_OBJECT; + aligned = true; + sf = Address::times_ptr; + dest_uninitialized = true; + break; + case arrayof_oop_disjoint_arraycopy_uninit_id: + // since this is always aligned we can (should!) use the same + // stub as for case oop_disjoint_arraycopy_uninit + ShouldNotReachHere(); + break; + default: + ShouldNotReachHere(); + break; + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; @@ -1231,9 +1308,41 @@ class StubGenerator: public StubCodeGenerator { } - address generate_fill(BasicType t, bool aligned, const char *name) { + address generate_fill(StubGenStubId stub_id) { + BasicType t; + bool aligned; + switch(stub_id) { + case jbyte_fill_id: + t = T_BYTE; + aligned = false; + break; + case jshort_fill_id: + t = T_SHORT; + aligned = false; + break; + case jint_fill_id: + t = T_INT; + aligned = false; + break; + case arrayof_jbyte_fill_id: + t = T_BYTE; + aligned = true; + break; + case arrayof_jshort_fill_id: + t = T_SHORT; + aligned = true; + break; + case arrayof_jint_fill_id: + t = T_INT; + aligned = true; + break; + default: + ShouldNotReachHere(); + break; + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -1258,13 +1367,84 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_conjoint_copy(BasicType t, bool aligned, - Address::ScaleFactor sf, + address generate_conjoint_copy(StubGenStubId stub_id, address nooverlap_target, - address* entry, const char *name, - bool dest_uninitialized = false) { + address* entry) { + BasicType t; + bool aligned; + Address::ScaleFactor sf; + bool dest_uninitialized; + + switch (stub_id) { + case jbyte_arraycopy_id: + t = T_BYTE; + aligned = false; + sf = Address::times_1; + dest_uninitialized = false; + break; + case arrayof_jbyte_arraycopy_id: + t = T_BYTE; + aligned = true; + sf = Address::times_1; + dest_uninitialized = false; + break; + case jshort_arraycopy_id: + t = T_SHORT; + aligned = false; + sf = Address::times_2; + dest_uninitialized = false; + break; + case arrayof_jshort_arraycopy_id: + t = T_SHORT; + aligned = true; + sf = Address::times_2; + dest_uninitialized = false; + break; + case jint_arraycopy_id: + t = T_INT; + aligned = true; + sf = Address::times_4; + dest_uninitialized = false; + break; + case arrayof_jint_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case jint_arraycopy + ShouldNotReachHere(); + break; + case jlong_arraycopy_id: + case arrayof_jlong_arraycopy_id: + // Handled by a special generator routine on 32 bit + ShouldNotReachHere(); + break; + case oop_arraycopy_id: + t = T_OBJECT; + aligned = true; + sf = Address::times_ptr; + dest_uninitialized = false; + break; + case arrayof_oop_arraycopy_id: + // since this is always aligned we can (should!) use the same + // stub as for case oop_arraycopy + ShouldNotReachHere(); + break; + case oop_arraycopy_uninit_id: + t = T_OBJECT; + aligned = true; + sf = Address::times_ptr; + dest_uninitialized = true; + break; + case arrayof_oop_arraycopy_uninit_id: + // since this is always aligned we can (should!) use the same + // stub as for case oop_arraycopy_uninit + ShouldNotReachHere(); + break; + default: + ShouldNotReachHere(); + break; + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; @@ -1430,9 +1610,10 @@ class StubGenerator: public StubCodeGenerator { } - address generate_disjoint_long_copy(address* entry, const char *name) { + address generate_disjoint_long_copy(address* entry) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::jlong_disjoint_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_8_bytes, L_copy_8_bytes_loop; @@ -1475,10 +1656,10 @@ class StubGenerator: public StubCodeGenerator { return start; } - address generate_conjoint_long_copy(address nooverlap_target, - address* entry, const char *name) { + address generate_conjoint_long_copy(address nooverlap_target, address* entry) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::jlong_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_8_bytes, L_copy_8_bytes_loop; @@ -1599,9 +1780,21 @@ class StubGenerator: public StubCodeGenerator { // rax, == 0 - success // rax, == -1^K - failure, where K is partial transfer count // - address generate_checkcast_copy(const char *name, address* entry, bool dest_uninitialized = false) { + address generate_checkcast_copy(StubGenStubId stub_id, address* entry) { + bool dest_uninitialized; + switch(stub_id) { + case checkcast_arraycopy_id: + dest_uninitialized = false; + break; + case checkcast_arraycopy_uninit_id: + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_load_element, L_store_element, L_do_card_marks, L_done; @@ -1756,8 +1949,7 @@ class StubGenerator: public StubCodeGenerator { // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // - address generate_unsafe_copy(const char *name, - address byte_copy_entry, + address generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { @@ -1765,7 +1957,8 @@ class StubGenerator: public StubCodeGenerator { Label L_long_aligned, L_int_aligned, L_short_aligned; __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = rax; // source array address @@ -1862,8 +2055,7 @@ class StubGenerator: public StubCodeGenerator { // rax, == 0 - success // rax, == -1^K - failure, where K is partial transfer count // - address generate_generic_copy(const char *name, - address entry_jbyte_arraycopy, + address generate_generic_copy(address entry_jbyte_arraycopy, address entry_jshort_arraycopy, address entry_jint_arraycopy, address entry_oop_arraycopy, @@ -1877,7 +2069,8 @@ class StubGenerator: public StubCodeGenerator { if (advance < 0) advance += modulus; if (advance > 0) __ nop(advance); } - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; + StubCodeMark mark(this, stub_id); // Short-hop target to L_failed. Makes for denser prologue code. __ BIND(L_failed_0); @@ -2190,67 +2383,50 @@ class StubGenerator: public StubCodeGenerator { address entry_checkcast_arraycopy; StubRoutines::_arrayof_jbyte_disjoint_arraycopy = - generate_disjoint_copy(T_BYTE, true, Address::times_1, &entry, - "arrayof_jbyte_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::arrayof_jbyte_disjoint_arraycopy_id, &entry); StubRoutines::_arrayof_jbyte_arraycopy = - generate_conjoint_copy(T_BYTE, true, Address::times_1, entry, - nullptr, "arrayof_jbyte_arraycopy"); + generate_conjoint_copy(StubGenStubId::arrayof_jbyte_arraycopy_id, entry, nullptr); StubRoutines::_jbyte_disjoint_arraycopy = - generate_disjoint_copy(T_BYTE, false, Address::times_1, &entry, - "jbyte_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::jbyte_disjoint_arraycopy_id, &entry); StubRoutines::_jbyte_arraycopy = - generate_conjoint_copy(T_BYTE, false, Address::times_1, entry, - &entry_jbyte_arraycopy, "jbyte_arraycopy"); + generate_conjoint_copy(StubGenStubId::jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy); StubRoutines::_arrayof_jshort_disjoint_arraycopy = - generate_disjoint_copy(T_SHORT, true, Address::times_2, &entry, - "arrayof_jshort_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::arrayof_jshort_disjoint_arraycopy_id, &entry); StubRoutines::_arrayof_jshort_arraycopy = - generate_conjoint_copy(T_SHORT, true, Address::times_2, entry, - nullptr, "arrayof_jshort_arraycopy"); + generate_conjoint_copy(StubGenStubId::arrayof_jshort_arraycopy_id, entry, nullptr); StubRoutines::_jshort_disjoint_arraycopy = - generate_disjoint_copy(T_SHORT, false, Address::times_2, &entry, - "jshort_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::jshort_disjoint_arraycopy_id, &entry); StubRoutines::_jshort_arraycopy = - generate_conjoint_copy(T_SHORT, false, Address::times_2, entry, - &entry_jshort_arraycopy, "jshort_arraycopy"); + generate_conjoint_copy(StubGenStubId::jshort_arraycopy_id, entry, &entry_jshort_arraycopy); // Next arrays are always aligned on 4 bytes at least. StubRoutines::_jint_disjoint_arraycopy = - generate_disjoint_copy(T_INT, true, Address::times_4, &entry, - "jint_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::jint_disjoint_arraycopy_id, &entry); StubRoutines::_jint_arraycopy = - generate_conjoint_copy(T_INT, true, Address::times_4, entry, - &entry_jint_arraycopy, "jint_arraycopy"); + generate_conjoint_copy(StubGenStubId::jint_arraycopy_id, entry, &entry_jint_arraycopy); StubRoutines::_oop_disjoint_arraycopy = - generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry, - "oop_disjoint_arraycopy"); + generate_disjoint_copy(StubGenStubId::oop_disjoint_arraycopy_id, &entry); StubRoutines::_oop_arraycopy = - generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry, - &entry_oop_arraycopy, "oop_arraycopy"); + generate_conjoint_copy(StubGenStubId::oop_arraycopy_id, entry, &entry_oop_arraycopy); StubRoutines::_oop_disjoint_arraycopy_uninit = - generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry, - "oop_disjoint_arraycopy_uninit", - /*dest_uninitialized*/true); + generate_disjoint_copy(StubGenStubId::oop_disjoint_arraycopy_uninit_id, &entry); StubRoutines::_oop_arraycopy_uninit = - generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry, - nullptr, "oop_arraycopy_uninit", - /*dest_uninitialized*/true); + generate_conjoint_copy(StubGenStubId::oop_arraycopy_uninit_id, entry, nullptr); StubRoutines::_jlong_disjoint_arraycopy = - generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy"); + generate_disjoint_long_copy(&entry); StubRoutines::_jlong_arraycopy = - generate_conjoint_long_copy(entry, &entry_jlong_arraycopy, - "jlong_arraycopy"); + generate_conjoint_long_copy(entry, &entry_jlong_arraycopy); - StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); - StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); - StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); - StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); - StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); - StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); + StubRoutines::_jbyte_fill = generate_fill(StubGenStubId::jbyte_fill_id); + StubRoutines::_jshort_fill = generate_fill(StubGenStubId::jshort_fill_id); + StubRoutines::_jint_fill = generate_fill(StubGenStubId::jint_fill_id); + StubRoutines::_arrayof_jbyte_fill = generate_fill(StubGenStubId::arrayof_jbyte_fill_id); + StubRoutines::_arrayof_jshort_fill = generate_fill(StubGenStubId::arrayof_jshort_fill_id); + StubRoutines::_arrayof_jint_fill = generate_fill(StubGenStubId::arrayof_jint_fill_id); StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy; StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy; @@ -2263,20 +2439,18 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy; StubRoutines::_checkcast_arraycopy = - generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); + generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_id, &entry_checkcast_arraycopy); StubRoutines::_checkcast_arraycopy_uninit = - generate_checkcast_copy("checkcast_arraycopy_uninit", nullptr, /*dest_uninitialized*/true); + generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_uninit_id, nullptr); StubRoutines::_unsafe_arraycopy = - generate_unsafe_copy("unsafe_arraycopy", - entry_jbyte_arraycopy, - entry_jshort_arraycopy, - entry_jint_arraycopy, - entry_jlong_arraycopy); + generate_unsafe_copy(entry_jbyte_arraycopy, + entry_jshort_arraycopy, + entry_jint_arraycopy, + entry_jlong_arraycopy); StubRoutines::_generic_arraycopy = - generate_generic_copy("generic_arraycopy", - entry_jbyte_arraycopy, + generate_generic_copy( entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_oop_arraycopy, @@ -2356,7 +2530,8 @@ class StubGenerator: public StubCodeGenerator { address generate_aescrypt_encryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_doLast; address start = __ pc(); @@ -2455,7 +2630,8 @@ class StubGenerator: public StubCodeGenerator { address generate_aescrypt_decryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_doLast; address start = __ pc(); @@ -2579,7 +2755,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cipherBlockChaining_encryptAESCrypt() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256; @@ -2737,7 +2914,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = rsi; // source array address @@ -2910,7 +3088,8 @@ class StubGenerator: public StubCodeGenerator { address generate_counterMode_AESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::counterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = rsi; // source array address const Register to = rdx; // destination array address @@ -3192,9 +3371,21 @@ class StubGenerator: public StubCodeGenerator { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.MD5.implCompress(byte[] b, int ofs) - address generate_md5_implCompress(bool multi_block, const char *name) { + address generate_md5_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch(stub_id) { + case StubGenStubId::md5_implCompress_id: + multi_block = false; + break; + case StubGenStubId::md5_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register buf_param = rbp; @@ -3232,7 +3423,8 @@ class StubGenerator: public StubCodeGenerator { address generate_upper_word_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "upper_word_mask"); + StubGenStubId stub_id = StubGenStubId::upper_word_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x00000000, relocInfo::none, 0); __ emit_data(0x00000000, relocInfo::none, 0); @@ -3243,7 +3435,8 @@ class StubGenerator: public StubCodeGenerator { address generate_shuffle_byte_flip_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "shuffle_byte_flip_mask"); + StubGenStubId stub_id = StubGenStubId::shuffle_byte_flip_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x0c0d0e0f, relocInfo::none, 0); __ emit_data(0x08090a0b, relocInfo::none, 0); @@ -3254,9 +3447,21 @@ class StubGenerator: public StubCodeGenerator { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) - address generate_sha1_implCompress(bool multi_block, const char *name) { + address generate_sha1_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch(stub_id) { + case StubGenStubId::sha1_implCompress_id: + multi_block = false; + break; + case StubGenStubId::sha1_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = rax; @@ -3302,7 +3507,8 @@ class StubGenerator: public StubCodeGenerator { address generate_pshuffle_byte_flip_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask"); + StubGenStubId stub_id = StubGenStubId::pshuffle_byte_flip_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data(0x00010203, relocInfo::none, 0); __ emit_data(0x04050607, relocInfo::none, 0); @@ -3313,9 +3519,21 @@ class StubGenerator: public StubCodeGenerator { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) - address generate_sha256_implCompress(bool multi_block, const char *name) { + address generate_sha256_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch(stub_id) { + case StubGenStubId::sha256_implCompress_id: + multi_block = false; + break; + case StubGenStubId::sha256_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = rbx; @@ -3373,7 +3591,9 @@ class StubGenerator: public StubCodeGenerator { assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support"); __ align(CodeEntryAlignment); Label L_ghash_loop, L_exit; - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); + address start = __ pc(); const Register state = rdi; @@ -3521,7 +3741,8 @@ class StubGenerator: public StubCodeGenerator { assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3576,7 +3797,9 @@ class StubGenerator: public StubCodeGenerator { address generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { assert(UseCRC32CIntrinsics, "need SSE4_2"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32C_id; + StubCodeMark mark(this, stub_id); + address start = __ pc(); const Register crc = rax; // crc const Register buf = rcx; // source java byte array address @@ -3619,7 +3842,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmExp() { - StubCodeMark mark(this, "StubRoutines", "libmExp"); + StubGenStubId stub_id = StubGenStubId::dexp_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3635,7 +3859,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmLog() { - StubCodeMark mark(this, "StubRoutines", "libmLog"); + StubGenStubId stub_id = StubGenStubId::dlog_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3651,7 +3876,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmLog10() { - StubCodeMark mark(this, "StubRoutines", "libmLog10"); + StubGenStubId stub_id = StubGenStubId::dlog10_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3667,7 +3893,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmPow() { - StubCodeMark mark(this, "StubRoutines", "libmPow"); + StubGenStubId stub_id = StubGenStubId::dpow_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3683,7 +3910,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libm_reduce_pi04l() { - StubCodeMark mark(this, "StubRoutines", "libm_reduce_pi04l"); + StubGenStubId stub_id = StubGenStubId::dlibm_reduce_pi04l_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3695,7 +3923,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libm_sin_cos_huge() { - StubCodeMark mark(this, "StubRoutines", "libm_sin_cos_huge"); + StubGenStubId stub_id = StubGenStubId::dlibm_sin_cos_huge_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3707,7 +3936,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmSin() { - StubCodeMark mark(this, "StubRoutines", "libmSin"); + StubGenStubId stub_id = StubGenStubId::dsin_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3723,7 +3953,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmCos() { - StubCodeMark mark(this, "StubRoutines", "libmCos"); + StubGenStubId stub_id = StubGenStubId::dcos_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3739,7 +3970,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libm_tan_cot_huge() { - StubCodeMark mark(this, "StubRoutines", "libm_tan_cot_huge"); + StubGenStubId stub_id = StubGenStubId::dlibm_tan_cot_huge_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3751,7 +3983,8 @@ class StubGenerator: public StubCodeGenerator { } address generate_libmTan() { - StubCodeMark mark(this, "StubRoutines", "libmTan"); + StubGenStubId stub_id = StubGenStubId::dtan_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3768,7 +4001,8 @@ class StubGenerator: public StubCodeGenerator { address generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); Label deoptimize_label; @@ -3988,35 +4222,35 @@ class StubGenerator: public StubCodeGenerator { // entry points that are C2/JVMCI specific - StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask("vector_float_sign_mask", 0x7FFFFFFF); - StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask("vector_float_sign_flip", 0x80000000); - StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask_long_double("vector_double_sign_mask", 0x7FFFFFFF, 0xFFFFFFFF); - StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask_long_double("vector_double_sign_flip", 0x80000000, 0x00000000); - StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask("vector_short_to_byte_mask", 0x00ff00ff); - StubRoutines::x86::_vector_int_to_byte_mask = generate_vector_mask("vector_int_to_byte_mask", 0x000000ff); - StubRoutines::x86::_vector_int_to_short_mask = generate_vector_mask("vector_int_to_short_mask", 0x0000ffff); - StubRoutines::x86::_vector_32_bit_mask = generate_vector_custom_i32("vector_32_bit_mask", Assembler::AVX_512bit, + StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask(StubGenStubId::vector_float_sign_mask_id, 0x7FFFFFFF); + StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask(StubGenStubId::vector_float_sign_flip_id, 0x80000000); + StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask_long_double(StubGenStubId::vector_double_sign_mask_id, 0x7FFFFFFF, 0xFFFFFFFF); + StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask_long_double(StubGenStubId::vector_double_sign_flip_id, 0x80000000, 0x00000000); + StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask(StubGenStubId::vector_short_to_byte_mask_id, 0x00ff00ff); + StubRoutines::x86::_vector_int_to_byte_mask = generate_vector_mask(StubGenStubId::vector_int_to_byte_mask_id, 0x000000ff); + StubRoutines::x86::_vector_int_to_short_mask = generate_vector_mask(StubGenStubId::vector_int_to_short_mask_id, 0x0000ffff); + StubRoutines::x86::_vector_32_bit_mask = generate_vector_custom_i32(StubGenStubId::vector_32_bit_mask_id, Assembler::AVX_512bit, 0xFFFFFFFF, 0, 0, 0); - StubRoutines::x86::_vector_64_bit_mask = generate_vector_custom_i32("vector_64_bit_mask", Assembler::AVX_512bit, + StubRoutines::x86::_vector_64_bit_mask = generate_vector_custom_i32(StubGenStubId::vector_64_bit_mask_id, Assembler::AVX_512bit, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0); - StubRoutines::x86::_vector_int_shuffle_mask = generate_vector_mask("vector_int_shuffle_mask", 0x03020100); - StubRoutines::x86::_vector_byte_shuffle_mask = generate_vector_byte_shuffle_mask("vector_byte_shuffle_mask"); - StubRoutines::x86::_vector_short_shuffle_mask = generate_vector_mask("vector_short_shuffle_mask", 0x01000100); - StubRoutines::x86::_vector_long_shuffle_mask = generate_vector_mask_long_double("vector_long_shuffle_mask", 0x00000001, 0x0); - StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask("vector_byte_perm_mask"); - StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask_long_double("vector_long_sign_mask", 0x80000000, 0x00000000); - StubRoutines::x86::_vector_all_bits_set = generate_vector_mask("vector_all_bits_set", 0xFFFFFFFF); - StubRoutines::x86::_vector_int_mask_cmp_bits = generate_vector_mask("vector_int_mask_cmp_bits", 0x00000001); - StubRoutines::x86::_vector_iota_indices = generate_iota_indices("iota_indices"); - StubRoutines::x86::_vector_count_leading_zeros_lut = generate_count_leading_zeros_lut("count_leading_zeros_lut"); - StubRoutines::x86::_vector_reverse_bit_lut = generate_vector_reverse_bit_lut("reverse_bit_lut"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_long = generate_vector_reverse_byte_perm_mask_long("perm_mask_long"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_int = generate_vector_reverse_byte_perm_mask_int("perm_mask_int"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_short = generate_vector_reverse_byte_perm_mask_short("perm_mask_short"); + StubRoutines::x86::_vector_int_shuffle_mask = generate_vector_mask(StubGenStubId::vector_int_shuffle_mask_id, 0x03020100); + StubRoutines::x86::_vector_byte_shuffle_mask = generate_vector_byte_shuffle_mask(); + StubRoutines::x86::_vector_short_shuffle_mask = generate_vector_mask(StubGenStubId::vector_short_shuffle_mask_id, 0x01000100); + StubRoutines::x86::_vector_long_shuffle_mask = generate_vector_mask_long_double(StubGenStubId::vector_long_shuffle_mask_id, 0x00000001, 0x0); + StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask(); + StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask_long_double(StubGenStubId::vector_long_sign_mask_id, 0x80000000, 0x00000000); + StubRoutines::x86::_vector_all_bits_set = generate_vector_mask(StubGenStubId::vector_all_bits_set_id, 0xFFFFFFFF); + StubRoutines::x86::_vector_int_mask_cmp_bits = generate_vector_mask(StubGenStubId::vector_int_mask_cmp_bits_id, 0x00000001); + StubRoutines::x86::_vector_iota_indices = generate_iota_indices(); + StubRoutines::x86::_vector_count_leading_zeros_lut = generate_count_leading_zeros_lut(); + StubRoutines::x86::_vector_reverse_bit_lut = generate_vector_reverse_bit_lut(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_long = generate_vector_reverse_byte_perm_mask_long(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_int = generate_vector_reverse_byte_perm_mask_int(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_short = generate_vector_reverse_byte_perm_mask_short(); if (VM_Version::supports_avx2() && !VM_Version::supports_avx512_vpopcntdq()) { // lut implementation influenced by counting 1s algorithm from section 5-1 of Hackers' Delight. - StubRoutines::x86::_vector_popcount_lut = generate_popcount_avx_lut("popcount_lut"); + StubRoutines::x86::_vector_popcount_lut = generate_popcount_avx_lut(); } // don't bother generating these AES intrinsic stubs unless global flag is set @@ -4032,20 +4266,20 @@ class StubGenerator: public StubCodeGenerator { } if (UseMD5Intrinsics) { - StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); - StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); + StubRoutines::_md5_implCompress = generate_md5_implCompress(StubGenStubId::md5_implCompress_id); + StubRoutines::_md5_implCompressMB = generate_md5_implCompress(StubGenStubId::md5_implCompressMB_id); } if (UseSHA1Intrinsics) { StubRoutines::x86::_upper_word_mask_addr = generate_upper_word_mask(); StubRoutines::x86::_shuffle_byte_flip_mask_addr = generate_shuffle_byte_flip_mask(); - StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); - StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); + StubRoutines::_sha1_implCompress = generate_sha1_implCompress(StubGenStubId::sha1_implCompress_id); + StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(StubGenStubId::sha1_implCompressMB_id); } if (UseSHA256Intrinsics) { StubRoutines::x86::_k256_adr = (address)StubRoutines::x86::_k256; StubRoutines::x86::_pshuffle_byte_flip_mask_addr = generate_pshuffle_byte_flip_mask(); - StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); - StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(StubGenStubId::sha256_implCompressMB_id); } // Generate GHASH intrinsics code @@ -4057,27 +4291,27 @@ class StubGenerator: public StubCodeGenerator { public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - switch(kind) { - case Initial_stubs: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); break; - case Continuation_stubs: + case continuation_id: generate_continuation_stubs(); break; - case Compiler_stubs: + case compiler_id: generate_compiler_stubs(); break; - case Final_stubs: + case final_id: generate_final_stubs(); break; default: - fatal("unexpected stubs kind: %d", kind); + fatal("unexpected blob id: %d", blob_id); break; }; } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index 3979237619c92..d2a0c81b2c98a 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "classfile/vmIntrinsics.hpp" @@ -188,7 +187,8 @@ address StubGenerator::generate_call_stub(address& return_address) { assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 && (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, "adjust this code"); - StubCodeMark mark(this, "StubRoutines", "call_stub"); + StubGenStubId stub_id = StubGenStubId::call_stub_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // same as in generate_catch_exception()! @@ -248,12 +248,9 @@ address StubGenerator::generate_call_stub(address& return_address) { const Address mxcsr_save(rbp, mxcsr_off * wordSize); { Label skip_ldmx; - __ stmxcsr(mxcsr_save); - __ movl(rax, mxcsr_save); - __ andl(rax, 0xFFC0); // Mask out any pending exceptions (only check control and mask bits) - ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); - __ cmp32(rax, mxcsr_std, rscratch1); + __ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1); __ jcc(Assembler::equal, skip_ldmx); + ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); __ ldmxcsr(mxcsr_std, rscratch1); __ bind(skip_ldmx); } @@ -413,7 +410,8 @@ address StubGenerator::generate_call_stub(address& return_address) { // rax: exception oop address StubGenerator::generate_catch_exception() { - StubCodeMark mark(this, "StubRoutines", "catch_exception"); + StubGenStubId stub_id = StubGenStubId::catch_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // same as in generate_call_stub(): @@ -468,7 +466,8 @@ address StubGenerator::generate_catch_exception() { // NOTE: At entry of this stub, exception-pc must be on stack !! address StubGenerator::generate_forward_exception() { - StubCodeMark mark(this, "StubRoutines", "forward exception"); + StubGenStubId stub_id = StubGenStubId::forward_exception_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Upon entry, the sp points to the return address returning into @@ -531,7 +530,8 @@ address StubGenerator::generate_forward_exception() { // // Result: address StubGenerator::generate_orderaccess_fence() { - StubCodeMark mark(this, "StubRoutines", "orderaccess_fence"); + StubGenStubId stub_id = StubGenStubId::fence_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ membar(Assembler::StoreLoad); @@ -546,7 +546,8 @@ address StubGenerator::generate_orderaccess_fence() { // This routine is used to find the previous stack pointer for the // caller. address StubGenerator::generate_get_previous_sp() { - StubCodeMark mark(this, "StubRoutines", "get_previous_sp"); + StubGenStubId stub_id = StubGenStubId::get_previous_sp_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ movptr(rax, rsp); @@ -564,7 +565,8 @@ address StubGenerator::generate_get_previous_sp() { // MXCSR register to our expected state. address StubGenerator::generate_verify_mxcsr() { - StubCodeMark mark(this, "StubRoutines", "verify_mxcsr"); + StubGenStubId stub_id = StubGenStubId::verify_mxcsr_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Address mxcsr_save(rsp, 0); @@ -574,10 +576,7 @@ address StubGenerator::generate_verify_mxcsr() { ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); __ push(rax); __ subptr(rsp, wordSize); // allocate a temp location - __ stmxcsr(mxcsr_save); - __ movl(rax, mxcsr_save); - __ andl(rax, 0xFFC0); // Mask out any pending exceptions (only check control and mask bits) - __ cmp32(rax, mxcsr_std, rscratch1); + __ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); @@ -595,7 +594,8 @@ address StubGenerator::generate_verify_mxcsr() { } address StubGenerator::generate_f2i_fixup() { - StubCodeMark mark(this, "StubRoutines", "f2i_fixup"); + StubGenStubId stub_id = StubGenStubId::f2i_fixup_id; + StubCodeMark mark(this, stub_id); Address inout(rsp, 5 * wordSize); // return address + 4 saves address start = __ pc(); @@ -633,7 +633,8 @@ address StubGenerator::generate_f2i_fixup() { } address StubGenerator::generate_f2l_fixup() { - StubCodeMark mark(this, "StubRoutines", "f2l_fixup"); + StubGenStubId stub_id = StubGenStubId::f2l_fixup_id; + StubCodeMark mark(this, stub_id); Address inout(rsp, 5 * wordSize); // return address + 4 saves address start = __ pc(); @@ -670,7 +671,8 @@ address StubGenerator::generate_f2l_fixup() { } address StubGenerator::generate_d2i_fixup() { - StubCodeMark mark(this, "StubRoutines", "d2i_fixup"); + StubGenStubId stub_id = StubGenStubId::d2i_fixup_id; + StubCodeMark mark(this, stub_id); Address inout(rsp, 6 * wordSize); // return address + 5 saves address start = __ pc(); @@ -717,7 +719,8 @@ address StubGenerator::generate_d2i_fixup() { } address StubGenerator::generate_d2l_fixup() { - StubCodeMark mark(this, "StubRoutines", "d2l_fixup"); + StubGenStubId stub_id = StubGenStubId::d2l_fixup_id; + StubCodeMark mark(this, stub_id); Address inout(rsp, 6 * wordSize); // return address + 5 saves address start = __ pc(); @@ -763,9 +766,10 @@ address StubGenerator::generate_d2l_fixup() { return start; } -address StubGenerator::generate_count_leading_zeros_lut(const char *stub_name) { +address StubGenerator::generate_count_leading_zeros_lut() { __ align64(); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_count_leading_zeros_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0101010102020304, relocInfo::none); @@ -780,9 +784,10 @@ address StubGenerator::generate_count_leading_zeros_lut(const char *stub_name) { return start; } -address StubGenerator::generate_popcount_avx_lut(const char *stub_name) { +address StubGenerator::generate_popcount_avx_lut() { __ align64(); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_popcount_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0302020102010100, relocInfo::none); @@ -797,9 +802,10 @@ address StubGenerator::generate_popcount_avx_lut(const char *stub_name) { return start; } -address StubGenerator::generate_iota_indices(const char *stub_name) { +address StubGenerator::generate_iota_indices() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_iota_indices_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // B __ emit_data64(0x0706050403020100, relocInfo::none); @@ -858,9 +864,10 @@ address StubGenerator::generate_iota_indices(const char *stub_name) { return start; } -address StubGenerator::generate_vector_reverse_bit_lut(const char *stub_name) { +address StubGenerator::generate_vector_reverse_bit_lut() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_bit_lut_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0E060A020C040800, relocInfo::none); @@ -875,9 +882,10 @@ address StubGenerator::generate_vector_reverse_bit_lut(const char *stub_name) { return start; } -address StubGenerator::generate_vector_reverse_byte_perm_mask_long(const char *stub_name) { +address StubGenerator::generate_vector_reverse_byte_perm_mask_long() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_long_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0001020304050607, relocInfo::none); @@ -892,9 +900,10 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_long(const char *s return start; } -address StubGenerator::generate_vector_reverse_byte_perm_mask_int(const char *stub_name) { +address StubGenerator::generate_vector_reverse_byte_perm_mask_int() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_int_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0405060700010203, relocInfo::none); @@ -909,9 +918,10 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_int(const char *st return start; } -address StubGenerator::generate_vector_reverse_byte_perm_mask_short(const char *stub_name) { +address StubGenerator::generate_vector_reverse_byte_perm_mask_short() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_reverse_byte_perm_mask_short_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0607040502030001, relocInfo::none); @@ -926,9 +936,10 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_short(const char * return start; } -address StubGenerator::generate_vector_byte_shuffle_mask(const char *stub_name) { +address StubGenerator::generate_vector_byte_shuffle_mask() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_byte_shuffle_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x7070707070707070, relocInfo::none); @@ -939,9 +950,9 @@ address StubGenerator::generate_vector_byte_shuffle_mask(const char *stub_name) return start; } -address StubGenerator::generate_fp_mask(const char *stub_name, int64_t mask) { +address StubGenerator::generate_fp_mask(StubGenStubId stub_id, int64_t mask) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64( mask, relocInfo::none ); @@ -950,9 +961,20 @@ address StubGenerator::generate_fp_mask(const char *stub_name, int64_t mask) { return start; } -address StubGenerator::generate_compress_perm_table(const char *stub_name, int32_t esize) { +address StubGenerator::generate_compress_perm_table(StubGenStubId stub_id) { + int esize; + switch (stub_id) { + case compress_perm_table32_id: + esize = 32; + break; + case compress_perm_table64_id: + esize = 64; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); if (esize == 32) { // Loop to generate 256 x 8 int compression permute index table. A row is @@ -994,9 +1016,20 @@ address StubGenerator::generate_compress_perm_table(const char *stub_name, int32 return start; } -address StubGenerator::generate_expand_perm_table(const char *stub_name, int32_t esize) { +address StubGenerator::generate_expand_perm_table(StubGenStubId stub_id) { + int esize; + switch (stub_id) { + case expand_perm_table32_id: + esize = 32; + break; + case expand_perm_table64_id: + esize = 64; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); if (esize == 32) { // Loop to generate 256 x 8 int expand permute index table. A row is accessed @@ -1036,9 +1069,9 @@ address StubGenerator::generate_expand_perm_table(const char *stub_name, int32_t return start; } -address StubGenerator::generate_vector_mask(const char *stub_name, int64_t mask) { +address StubGenerator::generate_vector_mask(StubGenStubId stub_id, int64_t mask) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(mask, relocInfo::none); @@ -1053,9 +1086,10 @@ address StubGenerator::generate_vector_mask(const char *stub_name, int64_t mask) return start; } -address StubGenerator::generate_vector_byte_perm_mask(const char *stub_name) { +address StubGenerator::generate_vector_byte_perm_mask() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubGenStubId stub_id = StubGenStubId::vector_byte_perm_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0000000000000001, relocInfo::none); @@ -1070,9 +1104,9 @@ address StubGenerator::generate_vector_byte_perm_mask(const char *stub_name) { return start; } -address StubGenerator::generate_vector_fp_mask(const char *stub_name, int64_t mask) { +address StubGenerator::generate_vector_fp_mask(StubGenStubId stub_id, int64_t mask) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(mask, relocInfo::none); @@ -1087,13 +1121,13 @@ address StubGenerator::generate_vector_fp_mask(const char *stub_name, int64_t ma return start; } -address StubGenerator::generate_vector_custom_i32(const char *stub_name, Assembler::AvxVectorLen len, +address StubGenerator::generate_vector_custom_i32(StubGenStubId stub_id, Assembler::AvxVectorLen len, int32_t val0, int32_t val1, int32_t val2, int32_t val3, int32_t val4, int32_t val5, int32_t val6, int32_t val7, int32_t val8, int32_t val9, int32_t val10, int32_t val11, int32_t val12, int32_t val13, int32_t val14, int32_t val15) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", stub_name); + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(len != Assembler::AVX_NoVec, "vector len must be specified"); @@ -1137,7 +1171,8 @@ address StubGenerator::generate_vector_custom_i32(const char *stub_name, Assembl // * [tos + 8]: saved r10 (rscratch1) - saved by caller // * = popped on exit address StubGenerator::generate_verify_oop() { - StubCodeMark mark(this, "StubRoutines", "verify_oop"); + StubGenStubId stub_id = StubGenStubId::verify_oop_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label exit, error; @@ -1334,7 +1369,8 @@ address StubGenerator::generate_data_cache_writeback() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -1351,7 +1387,8 @@ address StubGenerator::generate_data_cache_writeback_sync() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync"); + StubGenStubId stub_id = StubGenStubId::data_cache_writeback_sync_id; + StubCodeMark mark(this, stub_id); // pre wbsync is a no-op // post wbsync translates to an sfence @@ -1372,9 +1409,20 @@ address StubGenerator::generate_data_cache_writeback_sync() { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.MD5.implCompress(byte[] b, int ofs) -address StubGenerator::generate_md5_implCompress(bool multi_block, const char *name) { +address StubGenerator::generate_md5_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case md5_implCompress_id: + multi_block = false; + break; + case md5_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register buf_param = r15; @@ -1410,7 +1458,8 @@ address StubGenerator::generate_md5_implCompress(bool multi_block, const char *n address StubGenerator::generate_upper_word_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "upper_word_mask"); + StubGenStubId stub_id = StubGenStubId::upper_word_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0000000000000000, relocInfo::none); @@ -1421,7 +1470,8 @@ address StubGenerator::generate_upper_word_mask() { address StubGenerator::generate_shuffle_byte_flip_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "shuffle_byte_flip_mask"); + StubGenStubId stub_id = StubGenStubId::shuffle_byte_flip_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none); @@ -1432,9 +1482,20 @@ address StubGenerator::generate_shuffle_byte_flip_mask() { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) -address StubGenerator::generate_sha1_implCompress(bool multi_block, const char *name) { +address StubGenerator::generate_sha1_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha1_implCompress_id: + multi_block = false; + break; + case sha1_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -1469,7 +1530,8 @@ address StubGenerator::generate_sha1_implCompress(bool multi_block, const char * address StubGenerator::generate_pshuffle_byte_flip_mask() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask"); + StubGenStubId stub_id = StubGenStubId::pshuffle_byte_flip_mask_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0405060700010203, relocInfo::none); @@ -1496,7 +1558,8 @@ address StubGenerator::generate_pshuffle_byte_flip_mask() { //Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. address StubGenerator::generate_pshuffle_byte_flip_mask_sha512() { __ align32(); - StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask_sha512"); + StubGenStubId stub_id = StubGenStubId::pshuffle_byte_flip_mask_sha512_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); if (VM_Version::supports_avx2()) { @@ -1515,10 +1578,21 @@ address StubGenerator::generate_pshuffle_byte_flip_mask_sha512() { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) -address StubGenerator::generate_sha256_implCompress(bool multi_block, const char *name) { +address StubGenerator::generate_sha256_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha256_implCompress_id: + multi_block = false; + break; + case sha256_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } assert(VM_Version::supports_sha() || VM_Version::supports_avx2(), ""); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -1557,11 +1631,22 @@ address StubGenerator::generate_sha256_implCompress(bool multi_block, const char return start; } -address StubGenerator::generate_sha512_implCompress(bool multi_block, const char *name) { +address StubGenerator::generate_sha512_implCompress(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha512_implCompress_id: + multi_block = false; + break; + case sha512_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } assert(VM_Version::supports_avx2(), ""); assert(VM_Version::supports_bmi2() || VM_Version::supports_sha512(), ""); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Register buf = c_rarg0; @@ -1596,7 +1681,8 @@ address StubGenerator::generate_sha512_implCompress(bool multi_block, const char address StubGenerator::base64_shuffle_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "shuffle_base64"); + StubGenStubId stub_id = StubGenStubId::shuffle_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -1615,7 +1701,8 @@ address StubGenerator::base64_shuffle_addr() { address StubGenerator::base64_avx2_shuffle_addr() { __ align32(); - StubCodeMark mark(this, "StubRoutines", "avx2_shuffle_base64"); + StubGenStubId stub_id = StubGenStubId::avx2_shuffle_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x0809070805060405, relocInfo::none); @@ -1628,7 +1715,8 @@ address StubGenerator::base64_avx2_shuffle_addr() { address StubGenerator::base64_avx2_input_mask_addr() { __ align32(); - StubCodeMark mark(this, "StubRoutines", "avx2_input_mask_base64"); + StubGenStubId stub_id = StubGenStubId::avx2_input_mask_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0x8000000000000000, relocInfo::none); @@ -1641,7 +1729,8 @@ address StubGenerator::base64_avx2_input_mask_addr() { address StubGenerator::base64_avx2_lut_addr() { __ align32(); - StubCodeMark mark(this, "StubRoutines", "avx2_lut_base64"); + StubGenStubId stub_id = StubGenStubId::avx2_lut_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); @@ -1660,7 +1749,8 @@ address StubGenerator::base64_avx2_lut_addr() { address StubGenerator::base64_encoding_table_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "encoding_table_base64"); + StubGenStubId stub_id = StubGenStubId::encoding_table_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -1693,7 +1783,8 @@ address StubGenerator::base64_encoding_table_addr() { address StubGenerator::generate_base64_encodeBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "implEncode"); + StubGenStubId stub_id = StubGenStubId::base64_encodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -2075,7 +2166,8 @@ address StubGenerator::generate_base64_encodeBlock() // base64 AVX512vbmi tables address StubGenerator::base64_vbmi_lookup_lo_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "lookup_lo_base64"); + StubGenStubId stub_id = StubGenStubId::lookup_lo_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2094,7 +2186,8 @@ address StubGenerator::base64_vbmi_lookup_lo_addr() { address StubGenerator::base64_vbmi_lookup_hi_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "lookup_hi_base64"); + StubGenStubId stub_id = StubGenStubId::lookup_hi_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2112,7 +2205,8 @@ address StubGenerator::base64_vbmi_lookup_hi_addr() { } address StubGenerator::base64_vbmi_lookup_lo_url_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "lookup_lo_base64url"); + StubGenStubId stub_id = StubGenStubId::lookup_lo_base64url_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2131,7 +2225,8 @@ address StubGenerator::base64_vbmi_lookup_lo_url_addr() { address StubGenerator::base64_vbmi_lookup_hi_url_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "lookup_hi_base64url"); + StubGenStubId stub_id = StubGenStubId::lookup_hi_base64url_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2150,7 +2245,8 @@ address StubGenerator::base64_vbmi_lookup_hi_url_addr() { address StubGenerator::base64_vbmi_pack_vec_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "pack_vec_base64"); + StubGenStubId stub_id = StubGenStubId::pack_vec_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2169,7 +2265,8 @@ address StubGenerator::base64_vbmi_pack_vec_addr() { address StubGenerator::base64_vbmi_join_0_1_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "join_0_1_base64"); + StubGenStubId stub_id = StubGenStubId::join_0_1_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2188,7 +2285,8 @@ address StubGenerator::base64_vbmi_join_0_1_addr() { address StubGenerator::base64_vbmi_join_1_2_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "join_1_2_base64"); + StubGenStubId stub_id = StubGenStubId::join_1_2_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2207,7 +2305,8 @@ address StubGenerator::base64_vbmi_join_1_2_addr() { address StubGenerator::base64_vbmi_join_2_3_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "join_2_3_base64"); + StubGenStubId stub_id = StubGenStubId::join_2_3_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2226,7 +2325,8 @@ address StubGenerator::base64_vbmi_join_2_3_addr() { address StubGenerator::base64_AVX2_decode_tables_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "AVX2_tables_base64"); + StubGenStubId stub_id = StubGenStubId::avx2_decode_tables_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2260,7 +2360,8 @@ address StubGenerator::base64_AVX2_decode_tables_addr() { address StubGenerator::base64_AVX2_decode_LUT_tables_addr() { __ align64(); - StubCodeMark mark(this, "StubRoutines", "AVX2_tables_URL_base64"); + StubGenStubId stub_id = StubGenStubId::avx2_decode_lut_tables_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, @@ -2299,7 +2400,8 @@ address StubGenerator::base64_AVX2_decode_LUT_tables_addr() { } address StubGenerator::base64_decoding_table_addr() { - StubCodeMark mark(this, "StubRoutines", "decoding_table_base64"); + StubGenStubId stub_id = StubGenStubId::decoding_table_base64_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ emit_data64(0xffffffffffffffff, relocInfo::none); @@ -2381,7 +2483,8 @@ address StubGenerator::base64_decoding_table_addr() { // private void decodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL, isMIME) { address StubGenerator::generate_base64_decodeBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "implDecode"); + StubGenStubId stub_id = StubGenStubId::base64_decodeBlock_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -2914,7 +3017,8 @@ address StubGenerator::generate_updateBytesCRC32() { assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -2970,7 +3074,8 @@ address StubGenerator::generate_updateBytesCRC32() { address StubGenerator::generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { assert(UseCRC32CIntrinsics, "need SSE4_2"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C"); + StubGenStubId stub_id = StubGenStubId::updateBytesCRC32C_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); //reg.arg int#0 int#1 int#2 int#3 int#4 int#5 float regs @@ -3050,7 +3155,8 @@ address StubGenerator::generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { */ address StubGenerator::generate_multiplyToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); + StubGenStubId stub_id = StubGenStubId::multiplyToLen_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3106,7 +3212,8 @@ address StubGenerator::generate_multiplyToLen() { */ address StubGenerator::generate_vectorizedMismatch() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "vectorizedMismatch"); + StubGenStubId stub_id = StubGenStubId::vectorizedMismatch_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -3157,7 +3264,8 @@ address StubGenerator::generate_vectorizedMismatch() { address StubGenerator::generate_squareToLen() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "squareToLen"); + StubGenStubId stub_id = StubGenStubId::squareToLen_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3192,7 +3300,8 @@ address StubGenerator::generate_squareToLen() { address StubGenerator::generate_method_entry_barrier() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier"); + StubGenStubId stub_id = StubGenStubId::method_entry_barrier_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label deoptimize_label; @@ -3281,7 +3390,8 @@ address StubGenerator::generate_method_entry_barrier() { */ address StubGenerator::generate_mulAdd() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "mulAdd"); + StubGenStubId stub_id = StubGenStubId::mulAdd_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3322,7 +3432,8 @@ address StubGenerator::generate_mulAdd() { address StubGenerator::generate_bigIntegerRightShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerRightShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerRightShiftWorker_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label Shift512Loop, ShiftTwo, ShiftTwoLoop, ShiftOne, Exit; @@ -3457,7 +3568,8 @@ address StubGenerator::generate_bigIntegerRightShift() { */ address StubGenerator::generate_bigIntegerLeftShift() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bigIntegerLeftShiftWorker"); + StubGenStubId stub_id = StubGenStubId::bigIntegerLeftShiftWorker_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label Shift512Loop, ShiftTwo, ShiftTwoLoop, ShiftOne, Exit; @@ -3605,7 +3717,8 @@ void StubGenerator::generate_libm_stubs() { * xmm0 - float */ address StubGenerator::generate_float16ToFloat() { - StubCodeMark mark(this, "StubRoutines", "float16ToFloat"); + StubGenStubId stub_id = StubGenStubId::hf2f_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3630,7 +3743,8 @@ address StubGenerator::generate_float16ToFloat() { * rax - float16 jshort */ address StubGenerator::generate_floatToFloat16() { - StubCodeMark mark(this, "StubRoutines", "floatToFloat16"); + StubGenStubId stub_id = StubGenStubId::f2hf_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3645,13 +3759,33 @@ address StubGenerator::generate_floatToFloat16() { return start; } -address StubGenerator::generate_cont_thaw(const char* label, Continuation::thaw_kind kind) { +address StubGenerator::generate_cont_thaw(StubGenStubId stub_id) { if (!Continuations::enabled()) return nullptr; - bool return_barrier = Continuation::is_thaw_return_barrier(kind); - bool return_barrier_exception = Continuation::is_thaw_return_barrier_exception(kind); - - StubCodeMark mark(this, "StubRoutines", label); + bool return_barrier; + bool return_barrier_exception; + Continuation::thaw_kind kind; + + switch (stub_id) { + case cont_thaw_id: + return_barrier = false; + return_barrier_exception = false; + kind = Continuation::thaw_top; + break; + case cont_returnBarrier_id: + return_barrier = true; + return_barrier_exception = false; + kind = Continuation::thaw_return_barrier; + break; + case cont_returnBarrierExc_id: + return_barrier = true; + return_barrier_exception = true; + kind = Continuation::thaw_return_barrier_exception; + break; + default: + ShouldNotReachHere(); + } + StubCodeMark mark(this, stub_id); address start = __ pc(); // TODO: Handle Valhalla return types. May require generating different return barriers. @@ -3769,22 +3903,23 @@ address StubGenerator::generate_cont_thaw(const char* label, Continuation::thaw_ } address StubGenerator::generate_cont_thaw() { - return generate_cont_thaw("Cont thaw", Continuation::thaw_top); + return generate_cont_thaw(StubGenStubId::cont_thaw_id); } // TODO: will probably need multiple return barriers depending on return type address StubGenerator::generate_cont_returnBarrier() { - return generate_cont_thaw("Cont thaw return barrier", Continuation::thaw_return_barrier); + return generate_cont_thaw(StubGenStubId::cont_returnBarrier_id); } address StubGenerator::generate_cont_returnBarrier_exception() { - return generate_cont_thaw("Cont thaw return barrier exception", Continuation::thaw_return_barrier_exception); + return generate_cont_thaw(StubGenStubId::cont_returnBarrierExc_id); } address StubGenerator::generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; - StubCodeMark mark(this, "StubRoutines","Continuation preempt stub"); + StubGenStubId stub_id = StubGenStubId::cont_preempt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ reset_last_Java_frame(true); @@ -3814,7 +3949,8 @@ address StubGenerator::generate_cont_preempt_stub() { // exception handler for upcall stubs address StubGenerator::generate_upcall_stub_exception_handler() { - StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_exception_handler_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // native caller has no idea how to handle exceptions @@ -3834,7 +3970,8 @@ address StubGenerator::generate_upcall_stub_exception_handler() { // j_rarg0 = jobject receiver // rbx = result address StubGenerator::generate_upcall_stub_load_target() { - StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target"); + StubGenStubId stub_id = StubGenStubId::upcall_stub_load_target_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ resolve_global_jobject(j_rarg0, r15_thread, rscratch1); @@ -3852,28 +3989,29 @@ address StubGenerator::generate_upcall_stub_load_target() { return start; } -address StubGenerator::generate_lookup_secondary_supers_table_stub(u1 super_klass_index) { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); - - address start = __ pc(); +void StubGenerator::generate_lookup_secondary_supers_table_stub() { + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_id; + StubCodeMark mark(this, stub_id); const Register r_super_klass = rax, r_sub_klass = rsi, result = rdi; - __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, - rdx, rcx, rbx, r11, // temps - result, - super_klass_index); - __ ret(0); - - return start; + for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, + rdx, rcx, rbx, r11, // temps + result, + slot); + __ ret(0); + } } // Slow path implementation for UseSecondarySupersTable. address StubGenerator::generate_lookup_secondary_supers_table_slow_path_stub() { - StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table"); + StubGenStubId stub_id = StubGenStubId::lookup_secondary_supers_table_slow_path_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); @@ -3946,10 +4084,10 @@ void StubGenerator::generate_initial_stubs() { StubRoutines::x86::_d2i_fixup = generate_d2i_fixup(); StubRoutines::x86::_d2l_fixup = generate_d2l_fixup(); - StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF); - StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000); - StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF); - StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000); + StubRoutines::x86::_float_sign_mask = generate_fp_mask(StubGenStubId::float_sign_mask_id, 0x7FFFFFFF7FFFFFFF); + StubRoutines::x86::_float_sign_flip = generate_fp_mask(StubGenStubId::float_sign_flip_id, 0x8000000080000000); + StubRoutines::x86::_double_sign_mask = generate_fp_mask(StubGenStubId::double_sign_mask_id, 0x7FFFFFFFFFFFFFFF); + StubRoutines::x86::_double_sign_flip = generate_fp_mask(StubGenStubId::double_sign_flip_id, 0x8000000000000000); if (UseCRC32Intrinsics) { // set table address before stub generation which use it @@ -3995,10 +4133,6 @@ void StubGenerator::generate_final_stubs() { StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); } - // data cache line writeback - StubRoutines::_data_cache_writeback = generate_data_cache_writeback(); - StubRoutines::_data_cache_writeback_sync = generate_data_cache_writeback_sync(); - // arraycopy stubs used by compilers generate_arraycopy_stubs(); @@ -4007,6 +4141,15 @@ void StubGenerator::generate_final_stubs() { StubRoutines::_method_entry_barrier = generate_method_entry_barrier(); } +#ifdef COMPILER2 + if (UseSecondarySupersTable) { + StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); + if (! InlineSecondarySupersTest) { + generate_lookup_secondary_supers_table_stub(); + } + } +#endif // COMPILER2 + if (UseVectorizedMismatchIntrinsic) { StubRoutines::_vectorizedMismatch = generate_vectorizedMismatch(); } @@ -4020,42 +4163,42 @@ void StubGenerator::generate_compiler_stubs() { // Entry points that are C2 compiler specific. - StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask("vector_float_sign_mask", 0x7FFFFFFF7FFFFFFF); - StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask("vector_float_sign_flip", 0x8000000080000000); - StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask("vector_double_sign_mask", 0x7FFFFFFFFFFFFFFF); - StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask("vector_double_sign_flip", 0x8000000000000000); - StubRoutines::x86::_vector_all_bits_set = generate_vector_mask("vector_all_bits_set", 0xFFFFFFFFFFFFFFFF); - StubRoutines::x86::_vector_int_mask_cmp_bits = generate_vector_mask("vector_int_mask_cmp_bits", 0x0000000100000001); - StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask("vector_short_to_byte_mask", 0x00ff00ff00ff00ff); - StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask("vector_byte_perm_mask"); - StubRoutines::x86::_vector_int_to_byte_mask = generate_vector_mask("vector_int_to_byte_mask", 0x000000ff000000ff); - StubRoutines::x86::_vector_int_to_short_mask = generate_vector_mask("vector_int_to_short_mask", 0x0000ffff0000ffff); - StubRoutines::x86::_vector_32_bit_mask = generate_vector_custom_i32("vector_32_bit_mask", Assembler::AVX_512bit, + StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask(StubGenStubId::vector_float_sign_mask_id, 0x7FFFFFFF7FFFFFFF); + StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask(StubGenStubId::vector_float_sign_flip_id, 0x8000000080000000); + StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask(StubGenStubId::vector_double_sign_mask_id, 0x7FFFFFFFFFFFFFFF); + StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask(StubGenStubId::vector_double_sign_flip_id, 0x8000000000000000); + StubRoutines::x86::_vector_all_bits_set = generate_vector_mask(StubGenStubId::vector_all_bits_set_id, 0xFFFFFFFFFFFFFFFF); + StubRoutines::x86::_vector_int_mask_cmp_bits = generate_vector_mask(StubGenStubId::vector_int_mask_cmp_bits_id, 0x0000000100000001); + StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask(StubGenStubId::vector_short_to_byte_mask_id, 0x00ff00ff00ff00ff); + StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask(); + StubRoutines::x86::_vector_int_to_byte_mask = generate_vector_mask(StubGenStubId::vector_int_to_byte_mask_id, 0x000000ff000000ff); + StubRoutines::x86::_vector_int_to_short_mask = generate_vector_mask(StubGenStubId::vector_int_to_short_mask_id, 0x0000ffff0000ffff); + StubRoutines::x86::_vector_32_bit_mask = generate_vector_custom_i32(StubGenStubId::vector_32_bit_mask_id, Assembler::AVX_512bit, 0xFFFFFFFF, 0, 0, 0); - StubRoutines::x86::_vector_64_bit_mask = generate_vector_custom_i32("vector_64_bit_mask", Assembler::AVX_512bit, + StubRoutines::x86::_vector_64_bit_mask = generate_vector_custom_i32(StubGenStubId::vector_64_bit_mask_id, Assembler::AVX_512bit, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0); - StubRoutines::x86::_vector_int_shuffle_mask = generate_vector_mask("vector_int_shuffle_mask", 0x0302010003020100); - StubRoutines::x86::_vector_byte_shuffle_mask = generate_vector_byte_shuffle_mask("vector_byte_shuffle_mask"); - StubRoutines::x86::_vector_short_shuffle_mask = generate_vector_mask("vector_short_shuffle_mask", 0x0100010001000100); - StubRoutines::x86::_vector_long_shuffle_mask = generate_vector_mask("vector_long_shuffle_mask", 0x0000000100000000); - StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask("vector_long_sign_mask", 0x8000000000000000); - StubRoutines::x86::_vector_iota_indices = generate_iota_indices("iota_indices"); - StubRoutines::x86::_vector_count_leading_zeros_lut = generate_count_leading_zeros_lut("count_leading_zeros_lut"); - StubRoutines::x86::_vector_reverse_bit_lut = generate_vector_reverse_bit_lut("reverse_bit_lut"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_long = generate_vector_reverse_byte_perm_mask_long("perm_mask_long"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_int = generate_vector_reverse_byte_perm_mask_int("perm_mask_int"); - StubRoutines::x86::_vector_reverse_byte_perm_mask_short = generate_vector_reverse_byte_perm_mask_short("perm_mask_short"); + StubRoutines::x86::_vector_int_shuffle_mask = generate_vector_mask(StubGenStubId::vector_int_shuffle_mask_id, 0x0302010003020100); + StubRoutines::x86::_vector_byte_shuffle_mask = generate_vector_byte_shuffle_mask(); + StubRoutines::x86::_vector_short_shuffle_mask = generate_vector_mask(StubGenStubId::vector_short_shuffle_mask_id, 0x0100010001000100); + StubRoutines::x86::_vector_long_shuffle_mask = generate_vector_mask(StubGenStubId::vector_long_shuffle_mask_id, 0x0000000100000000); + StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask(StubGenStubId::vector_long_sign_mask_id, 0x8000000000000000); + StubRoutines::x86::_vector_iota_indices = generate_iota_indices(); + StubRoutines::x86::_vector_count_leading_zeros_lut = generate_count_leading_zeros_lut(); + StubRoutines::x86::_vector_reverse_bit_lut = generate_vector_reverse_bit_lut(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_long = generate_vector_reverse_byte_perm_mask_long(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_int = generate_vector_reverse_byte_perm_mask_int(); + StubRoutines::x86::_vector_reverse_byte_perm_mask_short = generate_vector_reverse_byte_perm_mask_short(); if (VM_Version::supports_avx2() && !VM_Version::supports_avx512vl()) { - StubRoutines::x86::_compress_perm_table32 = generate_compress_perm_table("compress_perm_table32", 32); - StubRoutines::x86::_compress_perm_table64 = generate_compress_perm_table("compress_perm_table64", 64); - StubRoutines::x86::_expand_perm_table32 = generate_expand_perm_table("expand_perm_table32", 32); - StubRoutines::x86::_expand_perm_table64 = generate_expand_perm_table("expand_perm_table64", 64); + StubRoutines::x86::_compress_perm_table32 = generate_compress_perm_table(StubGenStubId::compress_perm_table32_id); + StubRoutines::x86::_compress_perm_table64 = generate_compress_perm_table(StubGenStubId::compress_perm_table64_id); + StubRoutines::x86::_expand_perm_table32 = generate_expand_perm_table(StubGenStubId::expand_perm_table32_id); + StubRoutines::x86::_expand_perm_table64 = generate_expand_perm_table(StubGenStubId::expand_perm_table64_id); } if (VM_Version::supports_avx2() && !VM_Version::supports_avx512_vpopcntdq()) { // lut implementation influenced by counting 1s algorithm from section 5-1 of Hackers' Delight. - StubRoutines::x86::_vector_popcount_lut = generate_popcount_avx_lut("popcount_lut"); + StubRoutines::x86::_vector_popcount_lut = generate_popcount_avx_lut(); } generate_aes_stubs(); @@ -4066,6 +4209,10 @@ void StubGenerator::generate_compiler_stubs() { generate_sha3_stubs(); + // data cache line writeback + StubRoutines::_data_cache_writeback = generate_data_cache_writeback(); + StubRoutines::_data_cache_writeback_sync = generate_data_cache_writeback_sync(); + #ifdef COMPILER2 if ((UseAVX == 2) && EnableX86ECoreOpts) { generate_string_indexof(StubRoutines::_string_indexof_array); @@ -4086,15 +4233,15 @@ void StubGenerator::generate_compiler_stubs() { } if (UseMD5Intrinsics) { - StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); - StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); + StubRoutines::_md5_implCompress = generate_md5_implCompress(StubGenStubId::md5_implCompress_id); + StubRoutines::_md5_implCompressMB = generate_md5_implCompress(StubGenStubId::md5_implCompressMB_id); } if (UseSHA1Intrinsics) { StubRoutines::x86::_upper_word_mask_addr = generate_upper_word_mask(); StubRoutines::x86::_shuffle_byte_flip_mask_addr = generate_shuffle_byte_flip_mask(); - StubRoutines::_sha1_implCompress = generate_sha1_implCompress(false, "sha1_implCompress"); - StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); + StubRoutines::_sha1_implCompress = generate_sha1_implCompress(StubGenStubId::sha1_implCompress_id); + StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(StubGenStubId::sha1_implCompressMB_id); } if (UseSHA256Intrinsics) { @@ -4107,15 +4254,15 @@ void StubGenerator::generate_compiler_stubs() { } StubRoutines::x86::_k256_W_adr = (address)StubRoutines::x86::_k256_W; StubRoutines::x86::_pshuffle_byte_flip_mask_addr = generate_pshuffle_byte_flip_mask(); - StubRoutines::_sha256_implCompress = generate_sha256_implCompress(false, "sha256_implCompress"); - StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB"); + StubRoutines::_sha256_implCompress = generate_sha256_implCompress(StubGenStubId::sha256_implCompress_id); + StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(StubGenStubId::sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { StubRoutines::x86::_k512_W_addr = (address)StubRoutines::x86::_k512_W; StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = generate_pshuffle_byte_flip_mask_sha512(); - StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); - StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); + StubRoutines::_sha512_implCompress = generate_sha512_implCompress(StubGenStubId::sha512_implCompress_id); + StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } if (UseBASE64Intrinsics) { @@ -4157,14 +4304,6 @@ void StubGenerator::generate_compiler_stubs() { StubRoutines::_bigIntegerRightShiftWorker = generate_bigIntegerRightShift(); StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift(); } - if (UseSecondarySupersTable) { - StubRoutines::_lookup_secondary_supers_table_slow_path_stub = generate_lookup_secondary_supers_table_slow_path_stub(); - if (! InlineSecondarySupersTest) { - for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] = generate_lookup_secondary_supers_table_stub(slot); - } - } - } if (UseMontgomeryMultiplyIntrinsic) { StubRoutines::_montgomeryMultiply = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_multiply); @@ -4263,29 +4402,28 @@ void StubGenerator::generate_compiler_stubs() { #endif // COMPILER2_OR_JVMCI } -StubGenerator::StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - DEBUG_ONLY( _regs_in_thread = false; ) - switch(kind) { - case Initial_stubs: - generate_initial_stubs(); - break; - case Continuation_stubs: - generate_continuation_stubs(); - break; - case Compiler_stubs: - generate_compiler_stubs(); - break; - case Final_stubs: - generate_final_stubs(); - break; - default: - fatal("unexpected stubs kind: %d", kind); - break; - }; +StubGenerator::StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: + generate_initial_stubs(); + break; + case continuation_id: + generate_continuation_stubs(); + break; + case compiler_id: + generate_compiler_stubs(); + break; + case final_id: + generate_final_stubs(); + break; + default: + fatal("unexpected blob id: %d", blob_id); + break; + }; } -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } #undef __ diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp index f883b6453a690..2263188216c41 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "code/codeBlob.hpp" #include "runtime/continuation.hpp" #include "runtime/stubCodeGenerator.hpp" +#include "runtime/stubRoutines.hpp" // Stub Code definitions @@ -87,29 +88,29 @@ class StubGenerator: public StubCodeGenerator { address generate_d2i_fixup(); address generate_d2l_fixup(); - address generate_count_leading_zeros_lut(const char *stub_name); - address generate_popcount_avx_lut(const char *stub_name); - address generate_iota_indices(const char *stub_name); - address generate_vector_reverse_bit_lut(const char *stub_name); + address generate_count_leading_zeros_lut(); + address generate_popcount_avx_lut(); + address generate_iota_indices(); + address generate_vector_reverse_bit_lut(); - address generate_vector_reverse_byte_perm_mask_long(const char *stub_name); - address generate_vector_reverse_byte_perm_mask_int(const char *stub_name); - address generate_vector_reverse_byte_perm_mask_short(const char *stub_name); - address generate_vector_byte_shuffle_mask(const char *stub_name); + address generate_vector_reverse_byte_perm_mask_long(); + address generate_vector_reverse_byte_perm_mask_int(); + address generate_vector_reverse_byte_perm_mask_short(); + address generate_vector_byte_shuffle_mask(); - address generate_fp_mask(const char *stub_name, int64_t mask); + address generate_fp_mask(StubGenStubId stub_id, int64_t mask); - address generate_compress_perm_table(const char *stub_name, int32_t esize); + address generate_compress_perm_table(StubGenStubId stub_id); - address generate_expand_perm_table(const char *stub_name, int32_t esize); + address generate_expand_perm_table(StubGenStubId stub_id); - address generate_vector_mask(const char *stub_name, int64_t mask); + address generate_vector_mask(StubGenStubId stub_id, int64_t mask); - address generate_vector_byte_perm_mask(const char *stub_name); + address generate_vector_byte_perm_mask(); - address generate_vector_fp_mask(const char *stub_name, int64_t mask); + address generate_vector_fp_mask(StubGenStubId stub_id, int64_t mask); - address generate_vector_custom_i32(const char *stub_name, Assembler::AvxVectorLen len, + address generate_vector_custom_i32(StubGenStubId stub_id, Assembler::AvxVectorLen len, int32_t val0, int32_t val1, int32_t val2, int32_t val3, int32_t val4 = 0, int32_t val5 = 0, int32_t val6 = 0, int32_t val7 = 0, int32_t val8 = 0, int32_t val9 = 0, int32_t val10 = 0, int32_t val11 = 0, @@ -179,12 +180,10 @@ class StubGenerator: public StubCodeGenerator { // - If user sets AVX3Threshold=0, then special cases for small blocks sizes operate over // 64 byte vector registers (ZMMs). - address generate_disjoint_copy_avx3_masked(address* entry, const char *name, int shift, - bool aligned, bool is_oop, bool dest_uninitialized); + address generate_disjoint_copy_avx3_masked(StubGenStubId stub_id, address* entry); - address generate_conjoint_copy_avx3_masked(address* entry, const char *name, int shift, - address nooverlap_target, bool aligned, bool is_oop, - bool dest_uninitialized); + address generate_conjoint_copy_avx3_masked(StubGenStubId stub_id, address* entry, + address nooverlap_target); void arraycopy_avx3_special_cases(XMMRegister xmm, KRegister mask, Register from, Register to, Register count, int shift, @@ -225,27 +224,21 @@ class StubGenerator: public StubCodeGenerator { Register temp, int shift = Address::times_1, int offset = 0); #endif // COMPILER2_OR_JVMCI - address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name); + address generate_disjoint_byte_copy(address* entry); - address generate_conjoint_byte_copy(bool aligned, address nooverlap_target, - address* entry, const char *name); + address generate_conjoint_byte_copy(address nooverlap_target, address* entry); - address generate_disjoint_short_copy(bool aligned, address *entry, const char *name); + address generate_disjoint_short_copy(address *entry); - address generate_fill(BasicType t, bool aligned, const char *name); + address generate_fill(StubGenStubId stub_id); - address generate_conjoint_short_copy(bool aligned, address nooverlap_target, - address *entry, const char *name); - address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, - const char *name, bool dest_uninitialized = false); - address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target, - address *entry, const char *name, - bool dest_uninitialized = false); - address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, - const char *name, bool dest_uninitialized = false); - address generate_conjoint_long_oop_copy(bool aligned, bool is_oop, - address nooverlap_target, address *entry, - const char *name, bool dest_uninitialized = false); + address generate_conjoint_short_copy(address nooverlap_target, address *entry); + address generate_disjoint_int_oop_copy(StubGenStubId stub_id, address* entry); + address generate_conjoint_int_oop_copy(StubGenStubId stub_id, address nooverlap_target, + address *entry); + address generate_disjoint_long_oop_copy(StubGenStubId stub_id, address* entry); + address generate_conjoint_long_oop_copy(StubGenStubId stub_id, address nooverlap_target, + address *entry); // Helper for generating a dynamic type check. // Smashes no registers. @@ -255,8 +248,7 @@ class StubGenerator: public StubCodeGenerator { Label& L_success); // Generate checkcasting array copy stub - address generate_checkcast_copy(const char *name, address *entry, - bool dest_uninitialized = false); + address generate_checkcast_copy(StubGenStubId stub_id, address *entry); // Generate 'unsafe' array copy stub // Though just as safe as the other stubs, it takes an unscaled @@ -264,8 +256,7 @@ class StubGenerator: public StubCodeGenerator { // // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. - address generate_unsafe_copy(const char *name, - address byte_copy_entry, address short_copy_entry, + address generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry); // Generate 'unsafe' set memory stub @@ -274,7 +265,7 @@ class StubGenerator: public StubCodeGenerator { // // Examines the alignment of the operands and dispatches // to an int, short, or byte copy loop. - address generate_unsafe_setmemory(const char *name, address byte_copy_entry); + address generate_unsafe_setmemory(address byte_copy_entry); // Perform range checks on the proposed arraycopy. // Kills temp, but nothing else. @@ -288,8 +279,7 @@ class StubGenerator: public StubCodeGenerator { Label& L_failed); // Generate generic array copy stubs - address generate_generic_copy(const char *name, - address byte_copy_entry, address short_copy_entry, + address generate_generic_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry); @@ -304,19 +294,19 @@ class StubGenerator: public StubCodeGenerator { // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.MD5.implCompress(byte[] b, int ofs) - address generate_md5_implCompress(bool multi_block, const char *name); + address generate_md5_implCompress(StubGenStubId stub_id); // SHA stubs // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) - address generate_sha1_implCompress(bool multi_block, const char *name); + address generate_sha1_implCompress(StubGenStubId stub_id); // ofs and limit are use for multi-block byte array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) - address generate_sha256_implCompress(bool multi_block, const char *name); - address generate_sha512_implCompress(bool multi_block, const char *name); + address generate_sha256_implCompress(StubGenStubId stub_id); + address generate_sha512_implCompress(StubGenStubId stub_id); // Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. address generate_pshuffle_byte_flip_mask_sha512(); @@ -499,7 +489,7 @@ class StubGenerator: public StubCodeGenerator { // SHA3 stubs void generate_sha3_stubs(); - address generate_sha3_implCompress(bool multiBlock, const char *name); + address generate_sha3_implCompress(StubGenStubId stub_id); // BASE64 stubs @@ -595,7 +585,7 @@ class StubGenerator: public StubCodeGenerator { void generate_string_indexof(address *fnptrs); #endif - address generate_cont_thaw(const char* label, Continuation::thaw_kind kind); + address generate_cont_thaw(StubGenStubId stub_id); address generate_cont_thaw(); // TODO: will probably need multiple return barriers depending on return type @@ -604,6 +594,8 @@ class StubGenerator: public StubCodeGenerator { address generate_cont_preempt_stub(); + // TODO -- delete this as it is not implemented? + // // Continuation point for throwing of implicit exceptions that are // not handled in the current activation. Fabricates an exception // oop and initiates normal exception dispatching in this @@ -629,7 +621,7 @@ class StubGenerator: public StubCodeGenerator { address generate_upcall_stub_load_target(); // Specialized stub implementations for UseSecondarySupersTable. - address generate_lookup_secondary_supers_table_stub(u1 super_klass_index); + void generate_lookup_secondary_supers_table_stub(); // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub(); @@ -642,8 +634,8 @@ class StubGenerator: public StubCodeGenerator { void generate_compiler_stubs(); void generate_final_stubs(); - public: - StubGenerator(CodeBuffer* code, StubsKind kind); +public: + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id); }; #endif // CPU_X86_STUBGENERATOR_X86_64_HPP diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp index 84f5cc80b0d3a..8a2aeaa5887a6 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021, 2023, Intel Corporation. All rights reserved. +* Copyright (c) 2021, 2024, Intel Corporation. All rights reserved. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "utilities/globalDefinitions.hpp" @@ -67,7 +66,8 @@ address StubGenerator::generate_updateBytesAdler32() { assert(UseAdler32Intrinsics, ""); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "updateBytesAdler32"); + StubGenStubId stub_id = StubGenStubId::updateBytesAdler32_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // Choose an appropriate LIMIT for inner loop based on the granularity diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp index f14d368c376e1..26bf3f7d725e7 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" @@ -250,7 +249,8 @@ void StubGenerator::generate_aes_stubs() { // rax - number of processed bytes address StubGenerator::generate_galoisCounterMode_AESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "galoisCounterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::galoisCounterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register in = c_rarg0; @@ -336,7 +336,8 @@ address StubGenerator::generate_galoisCounterMode_AESCrypt() { // rax - number of processed bytes address StubGenerator::generate_avx2_galoisCounterMode_AESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "galoisCounterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::galoisCounterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register in = c_rarg0; @@ -407,7 +408,8 @@ address StubGenerator::generate_avx2_galoisCounterMode_AESCrypt() { // Vector AES Counter implementation address StubGenerator::generate_counterMode_VectorAESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::counterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address @@ -495,7 +497,8 @@ address StubGenerator::generate_counterMode_VectorAESCrypt() { address StubGenerator::generate_counterMode_AESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "counterMode_AESCrypt"); + StubGenStubId stub_id = StubGenStubId::counterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address @@ -782,7 +785,8 @@ address StubGenerator::generate_counterMode_AESCrypt_Parallel() { address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() { assert(VM_Version::supports_avx512_vaes(), "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address @@ -1064,7 +1068,8 @@ address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() { address StubGenerator::generate_aescrypt_encryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_encryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_doLast; address start = __ pc(); @@ -1158,7 +1163,8 @@ address StubGenerator::generate_aescrypt_encryptBlock() { address StubGenerator::generate_aescrypt_decryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock"); + StubGenStubId stub_id = StubGenStubId::aescrypt_decryptBlock_id; + StubCodeMark mark(this, stub_id); Label L_doLast; address start = __ pc(); @@ -1259,7 +1265,8 @@ address StubGenerator::generate_aescrypt_decryptBlock() { address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256; @@ -1410,7 +1417,8 @@ address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() { address StubGenerator::generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::cipherBlockChaining_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address @@ -1652,7 +1660,8 @@ __ opc(xmm_result3, src_reg); \ address StubGenerator::generate_electronicCodeBook_encryptAESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "electronicCodeBook_encryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::electronicCodeBook_encryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address @@ -1672,7 +1681,8 @@ address StubGenerator::generate_electronicCodeBook_encryptAESCrypt() { address StubGenerator::generate_electronicCodeBook_decryptAESCrypt() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "electronicCodeBook_decryptAESCrypt"); + StubGenStubId stub_id = StubGenStubId::electronicCodeBook_decryptAESCrypt_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register from = c_rarg0; // source array address diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp index c72c32e796d2d..ccc8e456d5717 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" @@ -85,74 +84,51 @@ void StubGenerator::generate_arraycopy_stubs() { address entry_jlong_arraycopy; address entry_checkcast_arraycopy; - StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry, - "jbyte_disjoint_arraycopy"); - StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy, - "jbyte_arraycopy"); - - StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry, - "jshort_disjoint_arraycopy"); - StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy, - "jshort_arraycopy"); - - StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry, - "jint_disjoint_arraycopy"); - StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry, - &entry_jint_arraycopy, "jint_arraycopy"); - - StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry, - "jlong_disjoint_arraycopy"); - StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry, - &entry_jlong_arraycopy, "jlong_arraycopy"); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(&entry); + StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(entry, &entry_jbyte_arraycopy); + + StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(&entry); + StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(entry, &entry_jshort_arraycopy); + + StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubGenStubId::jint_disjoint_arraycopy_id, &entry); + StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(StubGenStubId::jint_arraycopy_id, entry, &entry_jint_arraycopy); + + StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubGenStubId::jlong_disjoint_arraycopy_id, &entry); + StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(StubGenStubId::jlong_arraycopy_id, entry, &entry_jlong_arraycopy); if (UseCompressedOops) { - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry, - "oop_disjoint_arraycopy"); - StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry, - &entry_oop_arraycopy, "oop_arraycopy"); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(false, true, &entry, - "oop_disjoint_arraycopy_uninit", - /*dest_uninitialized*/true); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(false, true, entry, - nullptr, "oop_arraycopy_uninit", - /*dest_uninitialized*/true); + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(StubGenStubId::oop_disjoint_arraycopy_id, &entry); + StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(StubGenStubId::oop_arraycopy_id, entry, &entry_oop_arraycopy); + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(StubGenStubId::oop_disjoint_arraycopy_uninit_id, &entry); + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(StubGenStubId::oop_arraycopy_uninit_id, entry, nullptr); } else { - StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry, - "oop_disjoint_arraycopy"); - StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry, - &entry_oop_arraycopy, "oop_arraycopy"); - StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(false, true, &entry, - "oop_disjoint_arraycopy_uninit", - /*dest_uninitialized*/true); - StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(false, true, entry, - nullptr, "oop_arraycopy_uninit", - /*dest_uninitialized*/true); - } - - StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy); - StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", nullptr, - /*dest_uninitialized*/true); - - StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(StubGenStubId::oop_disjoint_arraycopy_id, &entry); + StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(StubGenStubId::oop_arraycopy_id, entry, &entry_oop_arraycopy); + StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(StubGenStubId::oop_disjoint_arraycopy_uninit_id, &entry); + StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(StubGenStubId::oop_arraycopy_uninit_id, entry, nullptr); + } + + StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_id, &entry_checkcast_arraycopy); + StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubGenStubId::checkcast_arraycopy_uninit_id, nullptr); + + StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_jlong_arraycopy); - StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy", - entry_jbyte_arraycopy, + StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy, entry_jshort_arraycopy, entry_jint_arraycopy, entry_oop_arraycopy, entry_jlong_arraycopy, entry_checkcast_arraycopy); - StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); - StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); - StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); - StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); - StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); - StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); + StubRoutines::_jbyte_fill = generate_fill(StubGenStubId::jbyte_fill_id); + StubRoutines::_jshort_fill = generate_fill(StubGenStubId::jshort_fill_id); + StubRoutines::_jint_fill = generate_fill(StubGenStubId::jint_fill_id); + StubRoutines::_arrayof_jbyte_fill = generate_fill(StubGenStubId::arrayof_jbyte_fill_id); + StubRoutines::_arrayof_jshort_fill = generate_fill(StubGenStubId::arrayof_jshort_fill_id); + StubRoutines::_arrayof_jint_fill = generate_fill(StubGenStubId::arrayof_jint_fill_id); - StubRoutines::_unsafe_setmemory = generate_unsafe_setmemory("unsafe_setmemory", StubRoutines::_jbyte_fill); + StubRoutines::_unsafe_setmemory = generate_unsafe_setmemory(StubRoutines::_jbyte_fill); // We don't generate specialized code for HeapWord-aligned source // arrays, so just use the code we've already generated @@ -508,11 +484,50 @@ void StubGenerator::copy_bytes_backward(Register from, Register dest, // disjoint_copy_avx3_masked is set to the no-overlap entry point // used by generate_conjoint_[byte/int/short/long]_copy(). // -address StubGenerator::generate_disjoint_copy_avx3_masked(address* entry, const char *name, - int shift, bool aligned, bool is_oop, - bool dest_uninitialized) { +address StubGenerator::generate_disjoint_copy_avx3_masked(StubGenStubId stub_id, address* entry) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + int shift; + bool is_oop; + bool dest_uninitialized; + + switch (stub_id) { + case jbyte_disjoint_arraycopy_id: + shift = 0; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_disjoint_arraycopy_id: + shift = 1; + is_oop = false; + dest_uninitialized = false; + break; + case jint_disjoint_arraycopy_id: + shift = 2; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_disjoint_arraycopy_id: + shift = 3; + is_oop = false; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_id: + shift = (UseCompressedOops ? 2 : 3); + is_oop = true; + dest_uninitialized = false; + break; + case oop_disjoint_arraycopy_uninit_id: + shift = (UseCompressedOops ? 2 : 3); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); int avx3threshold = VM_Version::avx3_threshold(); @@ -807,11 +822,50 @@ void StubGenerator::arraycopy_avx3_large(Register to, Register from, Register te // c_rarg2 - element count, treated as ssize_t, can be zero // // -address StubGenerator::generate_conjoint_copy_avx3_masked(address* entry, const char *name, int shift, - address nooverlap_target, bool aligned, - bool is_oop, bool dest_uninitialized) { +address StubGenerator::generate_conjoint_copy_avx3_masked(StubGenStubId stub_id, address* entry, address nooverlap_target) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + int shift; + bool is_oop; + bool dest_uninitialized; + + switch (stub_id) { + case jbyte_arraycopy_id: + shift = 0; + is_oop = false; + dest_uninitialized = false; + break; + case jshort_arraycopy_id: + shift = 1; + is_oop = false; + dest_uninitialized = false; + break; + case jint_arraycopy_id: + shift = 2; + is_oop = false; + dest_uninitialized = false; + break; + case jlong_arraycopy_id: + shift = 3; + is_oop = false; + dest_uninitialized = false; + break; + case oop_arraycopy_id: + shift = (UseCompressedOops ? 2 : 3); + is_oop = true; + dest_uninitialized = false; + break; + case oop_arraycopy_uninit_id: + shift = (UseCompressedOops ? 2 : 3); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); int avx3threshold = VM_Version::avx3_threshold(); @@ -1263,9 +1317,7 @@ void StubGenerator::copy64_avx(Register dst, Register src, Register index, XMMRe // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored -// name - stub name string +// entry - location for return of (post-push) entry // // Inputs: // c_rarg0 - source array address @@ -1278,18 +1330,20 @@ void StubGenerator::copy64_avx(Register dst, Register src, Register index, XMMRe // and stored atomically. // // Side Effects: -// disjoint_byte_copy_entry is set to the no-overlap entry point +// entry is set to the no-overlap entry point // used by generate_conjoint_byte_copy(). // -address StubGenerator::generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) { +address StubGenerator::generate_disjoint_byte_copy(address* entry) { + StubGenStubId stub_id = StubGenStubId::jbyte_disjoint_arraycopy_id; + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; #if COMPILER2_OR_JVMCI if (VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_disjoint_copy_avx3_masked(entry, "jbyte_disjoint_arraycopy_avx3", 0, - aligned, false, false); + return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; @@ -1384,9 +1438,8 @@ __ BIND(L_exit); // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored -// name - stub name string +// entry - location for return of (post-push) entry +// nooverlap_target - entry to branch to if no overlap detected // // Inputs: // c_rarg0 - source array address @@ -1398,16 +1451,17 @@ __ BIND(L_exit); // dwords or qwords that span cache line boundaries will still be loaded // and stored atomically. // -address StubGenerator::generate_conjoint_byte_copy(bool aligned, address nooverlap_target, - address* entry, const char *name) { +address StubGenerator::generate_conjoint_byte_copy(address nooverlap_target, address* entry) { + StubGenStubId stub_id = StubGenStubId::jbyte_arraycopy_id; + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; #if COMPILER2_OR_JVMCI if (VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_conjoint_copy_avx3_masked(entry, "jbyte_conjoint_arraycopy_avx3", 0, - nooverlap_target, aligned, false, false); + return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY; @@ -1494,9 +1548,7 @@ address StubGenerator::generate_conjoint_byte_copy(bool aligned, address nooverl // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored -// name - stub name string +// entry - location for return of (post-push) entry // // Inputs: // c_rarg0 - source array address @@ -1509,19 +1561,21 @@ address StubGenerator::generate_conjoint_byte_copy(bool aligned, address nooverl // and stored atomically. // // Side Effects: -// disjoint_short_copy_entry is set to the no-overlap entry point +// entry is set to the no-overlap entry point // used by generate_conjoint_short_copy(). // -address StubGenerator::generate_disjoint_short_copy(bool aligned, address *entry, const char *name) { +address StubGenerator::generate_disjoint_short_copy(address *entry) { + StubGenStubId stub_id = StubGenStubId::jshort_disjoint_arraycopy_id; + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; #if COMPILER2_OR_JVMCI if (VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_disjoint_copy_avx3_masked(entry, "jshort_disjoint_arraycopy_avx3", 1, - aligned, false, false); + return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; @@ -1608,9 +1662,41 @@ __ BIND(L_exit); } -address StubGenerator::generate_fill(BasicType t, bool aligned, const char *name) { +address StubGenerator::generate_fill(StubGenStubId stub_id) { + BasicType t; + bool aligned; + + switch (stub_id) { + case jbyte_fill_id: + t = T_BYTE; + aligned = false; + break; + case jshort_fill_id: + t = T_SHORT; + aligned = false; + break; + case jint_fill_id: + t = T_INT; + aligned = false; + break; + case arrayof_jbyte_fill_id: + t = T_BYTE; + aligned = true; + break; + case arrayof_jshort_fill_id: + t = T_SHORT; + aligned = true; + break; + case arrayof_jint_fill_id: + t = T_INT; + aligned = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -1637,9 +1723,8 @@ address StubGenerator::generate_fill(BasicType t, bool aligned, const char *name // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored -// name - stub name string +// entry - location for return of (post-push) entry +// nooverlap_target - entry to branch to if no overlap detected // // Inputs: // c_rarg0 - source array address @@ -1651,16 +1736,18 @@ address StubGenerator::generate_fill(BasicType t, bool aligned, const char *name // or qwords that span cache line boundaries will still be loaded // and stored atomically. // -address StubGenerator::generate_conjoint_short_copy(bool aligned, address nooverlap_target, - address *entry, const char *name) { +address StubGenerator::generate_conjoint_short_copy(address nooverlap_target, address *entry) { + StubGenStubId stub_id = StubGenStubId::jshort_arraycopy_id; + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; #if COMPILER2_OR_JVMCI if (VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_conjoint_copy_avx3_masked(entry, "jshort_conjoint_arraycopy_avx3", 1, - nooverlap_target, aligned, false, false); + return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY; @@ -1739,10 +1826,9 @@ address StubGenerator::generate_conjoint_short_copy(bool aligned, address noover // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored -// is_oop - true => oop array, so generate store check code -// name - stub name string +// stub_id - unqiue id for stub to generate +// entry - location for return of (post-push) entry +// is_oop - true => oop array, so generate store check code // // Inputs: // c_rarg0 - source array address @@ -1757,18 +1843,39 @@ address StubGenerator::generate_conjoint_short_copy(bool aligned, address noover // disjoint_int_copy_entry is set to the no-overlap entry point // used by generate_conjoint_int_oop_copy(). // -address StubGenerator::generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry, - const char *name, bool dest_uninitialized) { +address StubGenerator::generate_disjoint_int_oop_copy(StubGenStubId stub_id, address* entry) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case StubGenStubId::jint_disjoint_arraycopy_id: + is_oop = false; + dest_uninitialized = false; + break; + case StubGenStubId::oop_disjoint_arraycopy_id: + assert(UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = false; + break; + case StubGenStubId::oop_disjoint_arraycopy_uninit_id: + assert(UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); #if COMPILER2_OR_JVMCI if ((!is_oop || bs->supports_avx3_masked_arraycopy()) && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_disjoint_copy_avx3_masked(entry, "jint_disjoint_arraycopy_avx3", 2, - aligned, is_oop, dest_uninitialized); + return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; @@ -1854,10 +1961,9 @@ __ BIND(L_exit); // Arguments: -// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary -// ignored +// entry - location for return of (post-push) entry +// nooverlap_target - entry to branch to if no overlap detected // is_oop - true => oop array, so generate store check code -// name - stub name string // // Inputs: // c_rarg0 - source array address @@ -1868,18 +1974,39 @@ __ BIND(L_exit); // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomically. // -address StubGenerator::generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target, - address *entry, const char *name, - bool dest_uninitialized) { +address StubGenerator::generate_conjoint_int_oop_copy(StubGenStubId stub_id, address nooverlap_target, address *entry) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case StubGenStubId::jint_arraycopy_id: + is_oop = false; + dest_uninitialized = false; + break; + case StubGenStubId::oop_arraycopy_id: + assert(UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = false; + break; + case StubGenStubId::oop_arraycopy_uninit_id: + assert(UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); #if COMPILER2_OR_JVMCI if ((!is_oop || bs->supports_avx3_masked_arraycopy()) && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_conjoint_copy_avx3_masked(entry, "jint_conjoint_arraycopy_avx3", 2, - nooverlap_target, aligned, is_oop, dest_uninitialized); + return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; @@ -1969,10 +2096,7 @@ __ BIND(L_exit); // Arguments: -// aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes -// ignored -// is_oop - true => oop array, so generate store check code -// name - stub name string +// entry - location for return of (post-push) entry // // Inputs: // c_rarg0 - source array address @@ -1983,17 +2107,39 @@ __ BIND(L_exit); // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the // no-overlap entry point used by generate_conjoint_long_oop_copy(). // -address StubGenerator::generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry, - const char *name, bool dest_uninitialized) { +address StubGenerator::generate_disjoint_long_oop_copy(StubGenStubId stub_id, address *entry) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case StubGenStubId::jlong_disjoint_arraycopy_id: + is_oop = false; + dest_uninitialized = false; + break; + case StubGenStubId::oop_disjoint_arraycopy_id: + assert(!UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = false; + break; + case StubGenStubId::oop_disjoint_arraycopy_uninit_id: + assert(!UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); #if COMPILER2_OR_JVMCI if ((!is_oop || bs->supports_avx3_masked_arraycopy()) && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_disjoint_copy_avx3_masked(entry, "jlong_disjoint_arraycopy_avx3", 3, - aligned, is_oop, dest_uninitialized); + return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; @@ -2085,28 +2231,48 @@ address StubGenerator::generate_disjoint_long_oop_copy(bool aligned, bool is_oop // Arguments: -// aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes -// ignored +// entry - location for return of (post-push) entry +// nooverlap_target - entry to branch to if no overlap detected // is_oop - true => oop array, so generate store check code -// name - stub name string // // Inputs: // c_rarg0 - source array address // c_rarg1 - destination array address // c_rarg2 - element count, treated as ssize_t, can be zero // -address StubGenerator::generate_conjoint_long_oop_copy(bool aligned, bool is_oop, address nooverlap_target, - address *entry, const char *name, - bool dest_uninitialized) { +address StubGenerator::generate_conjoint_long_oop_copy(StubGenStubId stub_id, address nooverlap_target, address *entry) { + // aligned is always false -- x86_64 always uses the unaligned code + const bool aligned = false; + bool is_oop; + bool dest_uninitialized; + switch (stub_id) { + case StubGenStubId::jlong_arraycopy_id: + is_oop = false; + dest_uninitialized = false; + break; + case StubGenStubId::oop_arraycopy_id: + assert(!UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = false; + break; + case StubGenStubId::oop_arraycopy_uninit_id: + assert(!UseCompressedOops, "inconsistent oop copy size!"); + is_oop = true; + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } + BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler(); #if COMPILER2_OR_JVMCI if ((!is_oop || bs->supports_avx3_masked_arraycopy()) && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2() && MaxVectorSize >= 32) { - return generate_conjoint_copy_avx3_masked(entry, "jlong_conjoint_arraycopy_avx3", 3, - nooverlap_target, aligned, is_oop, dest_uninitialized); + return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; @@ -2225,7 +2391,19 @@ void StubGenerator::generate_type_check(Register sub_klass, // rax == 0 - success // rax == -1^K - failure, where K is partial transfer count // -address StubGenerator::generate_checkcast_copy(const char *name, address *entry, bool dest_uninitialized) { +address StubGenerator::generate_checkcast_copy(StubGenStubId stub_id, address *entry) { + + bool dest_uninitialized; + switch (stub_id) { + case StubGenStubId::checkcast_arraycopy_id: + dest_uninitialized = false; + break; + case StubGenStubId::checkcast_arraycopy_uninit_id: + dest_uninitialized = true; + break; + default: + ShouldNotReachHere(); + } Label L_load_element, L_store_element, L_do_card_marks, L_done; @@ -2255,7 +2433,7 @@ address StubGenerator::generate_checkcast_copy(const char *name, address *entry, // checked. __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2431,8 +2609,7 @@ address StubGenerator::generate_checkcast_copy(const char *name, address *entry, // Examines the alignment of the operands and dispatches // to a long, int, short, or byte copy loop. // -address StubGenerator::generate_unsafe_copy(const char *name, - address byte_copy_entry, address short_copy_entry, +address StubGenerator::generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { Label L_long_aligned, L_int_aligned, L_short_aligned; @@ -2446,7 +2623,8 @@ address StubGenerator::generate_unsafe_copy(const char *name, const Register bits = rax; // test copy of low bits __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_arraycopy_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2579,10 +2757,10 @@ static void do_setmemory_atomic_loop(USM_TYPE type, Register dest, // Examines the alignment of the operands and dispatches // to an int, short, or byte fill loop. // -address StubGenerator::generate_unsafe_setmemory(const char *name, - address unsafe_byte_fill) { +address StubGenerator::generate_unsafe_setmemory(address unsafe_byte_fill) { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::unsafe_setmemory_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2725,8 +2903,7 @@ void StubGenerator::arraycopy_range_checks(Register src, // source array oop // rax == 0 - success // rax == -1^K - failure, where K is partial transfer count // -address StubGenerator::generate_generic_copy(const char *name, - address byte_copy_entry, address short_copy_entry, +address StubGenerator::generate_generic_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry) { @@ -2752,7 +2929,8 @@ address StubGenerator::generate_generic_copy(const char *name, if (advance < 0) advance += modulus; if (advance > 0) __ nop(advance); } - StubCodeMark mark(this, "StubRoutines", name); + StubGenStubId stub_id = StubGenStubId::generic_arraycopy_id; + StubCodeMark mark(this, stub_id); // Short-hop target to L_failed. Makes for denser prologue code. __ BIND(L_failed_0); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp index 47354f4fc7cf7..f7fb402407772 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" -#include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" #include "macroAssembler_x86.hpp" @@ -114,7 +112,8 @@ void StubGenerator::generate_chacha_stubs() { /* The 2-block AVX/AVX2-enabled ChaCha20 block function implementation */ address StubGenerator::generate_chacha20Block_avx() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "chacha20Block"); + StubGenStubId stub_id = StubGenStubId::chacha20Block_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_twoRounds; @@ -302,7 +301,8 @@ address StubGenerator::generate_chacha20Block_avx() { /* The 4-block AVX512-enabled ChaCha20 block function implementation */ address StubGenerator::generate_chacha20Block_avx512() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "chacha20Block"); + StubGenStubId stub_id = StubGenStubId::chacha20Block_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_twoRounds; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp index a5b8de75d0fd4..93fa7e650db6a 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "stubGenerator_x86_64.hpp" // Constants for libm trigonometric stubs diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp index 315f705768980..3f037a919d784 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. + * Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Intel Math Library (LIBM) Source Code * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -174,7 +173,8 @@ #define __ _masm-> address StubGenerator::generate_libmCos() { - StubCodeMark mark(this, "StubRoutines", "libmCos"); + StubGenStubId stub_id = StubGenStubId::dcos_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp index f716e2a7282d9..b48ed80788b17 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. +* Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. * Intel Math Library (LIBM) Source Code * @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -166,7 +165,8 @@ ATTRIBUTE_ALIGNED(4) static const juint _INF[] = #define __ _masm-> address StubGenerator::generate_libmExp() { - StubCodeMark mark(this, "StubRoutines", "libmExp"); + StubGenStubId stub_id = StubGenStubId::dexp_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp index 26b5b594424d2..958f65c883ac4 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Intel Corporation. All rights reserved. + * Copyright (c) 2023, 2024, Intel Corporation. All rights reserved. * Intel Math Library (LIBM) Source Code * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" #include "runtime/stubRoutines.hpp" @@ -74,7 +73,8 @@ ATTRIBUTE_ALIGNED(32) static const uint64_t CONST_e307[] = { address StubGenerator::generate_libmFmod() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "libmFmod"); + StubGenStubId stub_id = StubGenStubId::fmod_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp index 5a9b084841376..6d1f9fbd5a18f 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" -#include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" #include "macroAssembler_x86.hpp" @@ -84,7 +82,8 @@ void StubGenerator::generate_ghash_stubs() { address StubGenerator::generate_ghash_processBlocks() { __ align(CodeEntryAlignment); Label L_ghash_loop, L_exit; - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register state = c_rarg0; @@ -220,7 +219,8 @@ address StubGenerator::generate_ghash_processBlocks() { address StubGenerator::generate_avx_ghash_processBlocks() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); + StubGenStubId stub_id = StubGenStubId::ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); // arguments diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp index c9d339680c44c..6aacfaaea03de 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. +* Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. * Intel Math Library (LIBM) Source Code * @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -177,7 +176,8 @@ ATTRIBUTE_ALIGNED(16) static const juint _coeff[] = #define __ _masm-> address StubGenerator::generate_libmLog() { - StubCodeMark mark(this, "StubRoutines", "libmLog"); + StubGenStubId stub_id = StubGenStubId::dlog_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; @@ -515,7 +515,8 @@ ATTRIBUTE_ALIGNED(16) static const juint _coeff_log10[] = }; address StubGenerator::generate_libmLog10() { - StubCodeMark mark(this, "StubRoutines", "libmLog10"); + StubGenStubId stub_id = StubGenStubId::dlog10_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp index 6d3da2e6c759f..dfd4ca21dbd28 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -911,7 +910,8 @@ void StubGenerator::poly1305_process_blocks_avx512( // and accumulator will point to the current accumulator value address StubGenerator::generate_poly1305_processBlocks() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "poly1305_processBlocks"); + StubGenStubId stub_id = StubGenStubId::poly1305_processBlocks_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp index 4e909afbacc70..b75162dbb47ad 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -238,7 +237,8 @@ void montgomeryMultiply(const Register aLimbs, const Register bLimbs, const Regi address StubGenerator::generate_intpoly_montgomeryMult_P256() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "intpoly_montgomeryMult_P256"); + StubGenStubId stub_id = StubGenStubId::intpoly_montgomeryMult_P256_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); @@ -296,7 +296,8 @@ address StubGenerator::generate_intpoly_assign() { // Special Cases 5, 10, 14, 16, 19 __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "intpoly_assign"); + StubGenStubId stub_id = StubGenStubId::intpoly_assign_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); __ enter(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp index 2e9ea125abcb4..4029e53d1b14e 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. +* Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. * Intel Math Library (LIBM) Source Code * @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -760,7 +759,8 @@ ATTRIBUTE_ALIGNED(8) static const juint _DOUBLE0DOT5[] = { #define __ _masm-> address StubGenerator::generate_libmPow() { - StubCodeMark mark(this, "StubRoutines", "libmPow"); + StubGenStubId stub_id = StubGenStubId::dpow_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp index 49c39226708e3..7d1051711f20c 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "runtime/stubRoutines.hpp" @@ -82,8 +81,8 @@ static address permsAndRotsAddr() { void StubGenerator::generate_sha3_stubs() { if (UseSHA3Intrinsics) { - StubRoutines::_sha3_implCompress = generate_sha3_implCompress(false,"sha3_implCompress"); - StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(true, "sha3_implCompressMB"); + StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); } } @@ -96,9 +95,21 @@ void StubGenerator::generate_sha3_stubs() { // c_rarg3 - int offset // c_rarg4 - int limit // -address StubGenerator::generate_sha3_implCompress(bool multiBlock, const char *name) { +address StubGenerator::generate_sha3_implCompress(StubGenStubId stub_id) { + bool multiBlock; + switch(stub_id) { + case sha3_implCompress_id: + multiBlock = false; + break; + case sha3_implCompressMB_id: + multiBlock = true; + break; + default: + ShouldNotReachHere(); + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", name); + StubCodeMark mark(this, stub_id); address start = __ pc(); const Register buf = c_rarg0; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp index 1f07229034dd4..362eeb95e41a3 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. + * Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Intel Math Library (LIBM) Source Code * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -181,7 +180,8 @@ ATTRIBUTE_ALIGNED(8) static const juint _ALL_ONES[] = #define __ _masm-> address StubGenerator::generate_libmSin() { - StubCodeMark mark(this, "StubRoutines", "libmSin"); + StubGenStubId stub_id = StubGenStubId::dsin_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp index 58165aa6f9866..46cb0801a81ff 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Intel Corporation. All rights reserved. +* Copyright (c) 2016, 2024, Intel Corporation. All rights reserved. * Intel Math Library (LIBM) Source Code * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -456,7 +455,8 @@ ATTRIBUTE_ALIGNED(8) static const juint _QQ_2_tan[] = #define __ _masm-> address StubGenerator::generate_libmTan() { - StubCodeMark mark(this, "StubRoutines", "libmTan"); + StubGenStubId stub_id = StubGenStubId::dtan_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp index 92ac78e15cba9..d13809bfcd911 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "macroAssembler_x86.hpp" #include "stubGenerator_x86_64.hpp" @@ -303,7 +302,8 @@ ATTRIBUTE_ALIGNED(16) static const juint _T2_neg_f[] = #define __ _masm-> address StubGenerator::generate_libmTanh() { - StubCodeMark mark(this, "StubRoutines", "libmTanh"); + StubGenStubId stub_id = StubGenStubId::dtanh_id; + StubCodeMark mark(this, stub_id); address start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; diff --git a/src/hotspot/cpu/x86/stubRoutines_x86.cpp b/src/hotspot/cpu/x86/stubRoutines_x86.cpp index bc1cbdbba26b5..861c1e1216e3b 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" @@ -33,61 +32,24 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::x86::_verify_mxcsr_entry = nullptr; -address StubRoutines::x86::_upper_word_mask_addr = nullptr; -address StubRoutines::x86::_shuffle_byte_flip_mask_addr = nullptr; +// define fields for arch-specific entries + +#define DEFINE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = nullptr; + +#define DEFINE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + address StubRoutines:: arch :: STUB_FIELD_NAME(field_name) = CAST_FROM_FN_PTR(address, init_function); + +STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) + +#undef DEFINE_ARCH_ENTRY_INIT +#undef DEFINE_ARCH_ENTRY + address StubRoutines::x86::_k256_adr = nullptr; -address StubRoutines::x86::_vector_short_to_byte_mask = nullptr; -address StubRoutines::x86::_vector_int_to_byte_mask = nullptr; -address StubRoutines::x86::_vector_int_to_short_mask = nullptr; -address StubRoutines::x86::_vector_all_bits_set = nullptr; -address StubRoutines::x86::_vector_byte_shuffle_mask = nullptr; -address StubRoutines::x86::_vector_int_mask_cmp_bits = nullptr; -address StubRoutines::x86::_vector_short_shuffle_mask = nullptr; -address StubRoutines::x86::_vector_int_shuffle_mask = nullptr; -address StubRoutines::x86::_vector_long_shuffle_mask = nullptr; -address StubRoutines::x86::_vector_float_sign_mask = nullptr; -address StubRoutines::x86::_vector_float_sign_flip = nullptr; -address StubRoutines::x86::_vector_double_sign_mask = nullptr; -address StubRoutines::x86::_vector_double_sign_flip = nullptr; -address StubRoutines::x86::_vector_byte_perm_mask = nullptr; -address StubRoutines::x86::_vector_long_sign_mask = nullptr; -address StubRoutines::x86::_vector_iota_indices = nullptr; -address StubRoutines::x86::_vector_reverse_bit_lut = nullptr; -address StubRoutines::x86::_vector_reverse_byte_perm_mask_long = nullptr; -address StubRoutines::x86::_vector_reverse_byte_perm_mask_int = nullptr; -address StubRoutines::x86::_vector_reverse_byte_perm_mask_short = nullptr; -address StubRoutines::x86::_vector_popcount_lut = nullptr; -address StubRoutines::x86::_vector_count_leading_zeros_lut = nullptr; -address StubRoutines::x86::_vector_32_bit_mask = nullptr; -address StubRoutines::x86::_vector_64_bit_mask = nullptr; #ifdef _LP64 address StubRoutines::x86::_k256_W_adr = nullptr; address StubRoutines::x86::_k512_W_addr = nullptr; -address StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = nullptr; -// Base64 masks -address StubRoutines::x86::_encoding_table_base64 = nullptr; -address StubRoutines::x86::_shuffle_base64 = nullptr; -address StubRoutines::x86::_avx2_shuffle_base64 = nullptr; -address StubRoutines::x86::_avx2_input_mask_base64 = nullptr; -address StubRoutines::x86::_avx2_lut_base64 = nullptr; -address StubRoutines::x86::_avx2_decode_tables_base64 = nullptr; -address StubRoutines::x86::_avx2_decode_lut_tables_base64 = nullptr; -address StubRoutines::x86::_lookup_lo_base64 = nullptr; -address StubRoutines::x86::_lookup_hi_base64 = nullptr; -address StubRoutines::x86::_lookup_lo_base64url = nullptr; -address StubRoutines::x86::_lookup_hi_base64url = nullptr; -address StubRoutines::x86::_pack_vec_base64 = nullptr; -address StubRoutines::x86::_join_0_1_base64 = nullptr; -address StubRoutines::x86::_join_1_2_base64 = nullptr; -address StubRoutines::x86::_join_2_3_base64 = nullptr; -address StubRoutines::x86::_decoding_table_base64 = nullptr; -address StubRoutines::x86::_compress_perm_table32 = nullptr; -address StubRoutines::x86::_compress_perm_table64 = nullptr; -address StubRoutines::x86::_expand_perm_table32 = nullptr; -address StubRoutines::x86::_expand_perm_table64 = nullptr; #endif -address StubRoutines::x86::_pshuffle_byte_flip_mask_addr = nullptr; const uint64_t StubRoutines::x86::_crc_by128_masks[] = { diff --git a/src/hotspot/cpu/x86/stubRoutines_x86.hpp b/src/hotspot/cpu/x86/stubRoutines_x86.hpp index 0a6d091de8c7f..aaf84eb843777 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86.hpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86.hpp @@ -31,82 +31,52 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; } +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + enum platform_dependent_constants { - // simply increase sizes if too small (assembler will crash if too small) - _initial_stubs_code_size = 20000 WINDOWS_ONLY(+1000), - _continuation_stubs_code_size = 1000 LP64_ONLY(+2000), - // AVX512 intrinsics add more code in 64-bit VM, - // Windows have more code to save/restore registers - _compiler_stubs_code_size = 20000 LP64_ONLY(+47000) WINDOWS_ONLY(+2000), - _final_stubs_code_size = 10000 LP64_ONLY(+20000) WINDOWS_ONLY(+22000) ZGC_ONLY(+20000) + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) }; +#undef DEFINE_BLOB_SIZE + class x86 { friend class StubGenerator; friend class VMStructs; -#ifdef _LP64 - private: - static address _get_previous_sp_entry; - - static address _f2i_fixup; - static address _f2l_fixup; - static address _d2i_fixup; - static address _d2l_fixup; + // declare fields for arch-specific entries - static address _float_sign_mask; - static address _float_sign_flip; - static address _double_sign_mask; - static address _double_sign_flip; - static address _compress_perm_table32; - static address _compress_perm_table64; - static address _expand_perm_table32; - static address _expand_perm_table64; +#define DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) \ + static address STUB_FIELD_NAME(field_name) ; - public: +#define DECLARE_ARCH_ENTRY_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DECLARE_ARCH_ENTRY(arch, blob_name, stub_name, field_name, getter_name) - static address get_previous_sp_entry() { - return _get_previous_sp_entry; - } +private: + STUBGEN_ARCH_ENTRIES_DO(DECLARE_ARCH_ENTRY, DECLARE_ARCH_ENTRY_INIT) - static address f2i_fixup() { - return _f2i_fixup; - } +#undef DECLARE_ARCH_ENTRY_INIT +#undef DECLARE_ARCH_ENTRY - static address f2l_fixup() { - return _f2l_fixup; - } - static address d2i_fixup() { - return _d2i_fixup; - } + // define getters for arch-specific entries - static address d2l_fixup() { - return _d2l_fixup; - } +#define DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) \ + static address getter_name() { return STUB_FIELD_NAME(field_name); } - static address float_sign_mask() { - return _float_sign_mask; - } +#define DEFINE_ARCH_ENTRY_GETTER_INIT(arch, blob_name, stub_name, field_name, getter_name, init_function) \ + DEFINE_ARCH_ENTRY_GETTER(arch, blob_name, stub_name, field_name, getter_name) - static address float_sign_flip() { - return _float_sign_flip; - } +public: + STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY_GETTER, DEFINE_ARCH_ENTRY_GETTER_INIT) - static address double_sign_mask() { - return _double_sign_mask; - } +#undef DEFINE_ARCH_ENTRY_GETTER_INIT +#undef DEFINE_ARCH_GETTER_ENTRY - static address double_sign_flip() { - return _double_sign_flip; - } -#else // !LP64 - - private: - static address _verify_fpu_cntrl_wrd_entry; - static address _d2i_wrapper; - static address _d2l_wrapper; +#ifndef _LP64 static jint _fpu_cntrl_wrd_std; static jint _fpu_cntrl_wrd_24; @@ -115,10 +85,6 @@ class x86 { static jint _fpu_subnormal_bias1[3]; static jint _fpu_subnormal_bias2[3]; - public: - static address verify_fpu_cntrl_wrd_entry() { return _verify_fpu_cntrl_wrd_entry; } - static address d2i_wrapper() { return _d2i_wrapper; } - static address d2l_wrapper() { return _d2l_wrapper; } static address addr_fpu_cntrl_wrd_std() { return (address)&_fpu_cntrl_wrd_std; } static address addr_fpu_cntrl_wrd_24() { return (address)&_fpu_cntrl_wrd_24; } static address addr_fpu_cntrl_wrd_trunc() { return (address)&_fpu_cntrl_wrd_trunc; } @@ -133,9 +99,6 @@ class x86 { #ifdef _LP64 static jint _mxcsr_rz; #endif // _LP64 - - static address _verify_mxcsr_entry; - // masks and table for CRC32 static const uint64_t _crc_by128_masks[]; static const juint _crc_table[]; @@ -149,73 +112,21 @@ class x86 { static juint* _crc32c_table; // table for arrays_hashcode static const jint _arrays_hashcode_powers_of_31[]; - - // upper word mask for sha1 - static address _upper_word_mask_addr; - // byte flip mask for sha1 - static address _shuffle_byte_flip_mask_addr; - //k256 table for sha256 static const juint _k256[]; static address _k256_adr; - static address _vector_short_to_byte_mask; - static address _vector_float_sign_mask; - static address _vector_float_sign_flip; - static address _vector_double_sign_mask; - static address _vector_double_sign_flip; - static address _vector_long_sign_mask; - static address _vector_all_bits_set; - static address _vector_int_mask_cmp_bits; - static address _vector_byte_perm_mask; - static address _vector_int_to_byte_mask; - static address _vector_int_to_short_mask; - static address _vector_32_bit_mask; - static address _vector_64_bit_mask; - static address _vector_int_shuffle_mask; - static address _vector_byte_shuffle_mask; - static address _vector_short_shuffle_mask; - static address _vector_long_shuffle_mask; - static address _vector_iota_indices; - static address _vector_popcount_lut; - static address _vector_count_leading_zeros_lut; - static address _vector_reverse_bit_lut; - static address _vector_reverse_byte_perm_mask_long; - static address _vector_reverse_byte_perm_mask_int; - static address _vector_reverse_byte_perm_mask_short; #ifdef _LP64 static juint _k256_W[]; static address _k256_W_adr; static const julong _k512_W[]; static address _k512_W_addr; - // byte flip mask for sha512 - static address _pshuffle_byte_flip_mask_addr_sha512; - // Masks for base64 - static address _encoding_table_base64; - static address _shuffle_base64; - static address _avx2_shuffle_base64; - static address _avx2_input_mask_base64; - static address _avx2_lut_base64; - static address _avx2_decode_tables_base64; - static address _avx2_decode_lut_tables_base64; - static address _lookup_lo_base64; - static address _lookup_hi_base64; - static address _lookup_lo_base64url; - static address _lookup_hi_base64url; - static address _pack_vec_base64; - static address _join_0_1_base64; - static address _join_1_2_base64; - static address _join_2_3_base64; - static address _decoding_table_base64; #endif - // byte flip mask for sha256 - static address _pshuffle_byte_flip_mask_addr; public: static address addr_mxcsr_std() { return (address)&_mxcsr_std; } #ifdef _LP64 static address addr_mxcsr_rz() { return (address)&_mxcsr_rz; } #endif // _LP64 - static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } static address crc_by128_masks_addr() { return (address)_crc_by128_masks; } #ifdef _LP64 static address crc_by128_masks_avx512_addr() { return (address)_crc_by128_masks_avx512; } @@ -223,131 +134,12 @@ class x86 { static address crc_table_avx512_addr() { return (address)_crc_table_avx512; } static address crc32c_table_avx512_addr() { return (address)_crc32c_table_avx512; } #endif // _LP64 - static address upper_word_mask_addr() { return _upper_word_mask_addr; } - static address shuffle_byte_flip_mask_addr() { return _shuffle_byte_flip_mask_addr; } static address k256_addr() { return _k256_adr; } - static address method_entry_barrier() { return _method_entry_barrier; } - - static address vector_short_to_byte_mask() { - return _vector_short_to_byte_mask; - } - static address vector_float_sign_mask() { - return _vector_float_sign_mask; - } - - static address vector_float_sign_flip() { - return _vector_float_sign_flip; - } - - static address vector_double_sign_mask() { - return _vector_double_sign_mask; - } - - static address vector_double_sign_flip() { - return _vector_double_sign_flip; - } - - static address vector_all_bits_set() { - return _vector_all_bits_set; - } - - static address vector_int_mask_cmp_bits() { - return _vector_int_mask_cmp_bits; - } - - static address vector_byte_perm_mask() { - return _vector_byte_perm_mask; - } - - static address vector_int_to_byte_mask() { - return _vector_int_to_byte_mask; - } - - static address vector_int_to_short_mask() { - return _vector_int_to_short_mask; - } - - static address vector_32_bit_mask() { - return _vector_32_bit_mask; - } - - static address vector_64_bit_mask() { - return _vector_64_bit_mask; - } - - static address vector_int_shuffle_mask() { - return _vector_int_shuffle_mask; - } - - static address vector_byte_shuffle_mask() { - return _vector_byte_shuffle_mask; - } - - static address vector_short_shuffle_mask() { - return _vector_short_shuffle_mask; - } - - static address vector_long_shuffle_mask() { - return _vector_long_shuffle_mask; - } - - static address vector_long_sign_mask() { - return _vector_long_sign_mask; - } - - static address vector_iota_indices() { - return _vector_iota_indices; - } - - static address vector_count_leading_zeros_lut() { - return _vector_count_leading_zeros_lut; - } - - static address vector_reverse_bit_lut() { - return _vector_reverse_bit_lut; - } - - static address vector_reverse_byte_perm_mask_long() { - return _vector_reverse_byte_perm_mask_long; - } - - static address vector_reverse_byte_perm_mask_int() { - return _vector_reverse_byte_perm_mask_int; - } - - static address vector_reverse_byte_perm_mask_short() { - return _vector_reverse_byte_perm_mask_short; - } - - static address vector_popcount_lut() { - return _vector_popcount_lut; - } #ifdef _LP64 static address k256_W_addr() { return _k256_W_adr; } static address k512_W_addr() { return _k512_W_addr; } - static address pshuffle_byte_flip_mask_addr_sha512() { return _pshuffle_byte_flip_mask_addr_sha512; } - static address base64_encoding_table_addr() { return _encoding_table_base64; } - static address base64_shuffle_addr() { return _shuffle_base64; } - static address base64_avx2_shuffle_addr() { return _avx2_shuffle_base64; } - static address base64_avx2_input_mask_addr() { return _avx2_input_mask_base64; } - static address base64_avx2_lut_addr() { return _avx2_lut_base64; } - static address base64_vbmi_lookup_lo_addr() { return _lookup_lo_base64; } - static address base64_vbmi_lookup_hi_addr() { return _lookup_hi_base64; } - static address base64_vbmi_lookup_lo_url_addr() { return _lookup_lo_base64url; } - static address base64_vbmi_lookup_hi_url_addr() { return _lookup_hi_base64url; } - static address base64_vbmi_pack_vec_addr() { return _pack_vec_base64; } - static address base64_vbmi_join_0_1_addr() { return _join_0_1_base64; } - static address base64_vbmi_join_1_2_addr() { return _join_1_2_base64; } - static address base64_vbmi_join_2_3_addr() { return _join_2_3_base64; } - static address base64_decoding_table_addr() { return _decoding_table_base64; } - static address base64_AVX2_decode_tables_addr() { return _avx2_decode_tables_base64; } - static address base64_AVX2_decode_LUT_tables_addr() { return _avx2_decode_lut_tables_base64; } - static address compress_perm_table32() { return _compress_perm_table32; } - static address compress_perm_table64() { return _compress_perm_table64; } - static address expand_perm_table32() { return _expand_perm_table32; } - static address expand_perm_table64() { return _expand_perm_table64; } #endif - static address pshuffle_byte_flip_mask_addr() { return _pshuffle_byte_flip_mask_addr; } + static address arrays_hashcode_powers_of_31() { return (address)_arrays_hashcode_powers_of_31; } static void generate_CRC32C_table(bool is_pclmulqdq_supported); }; diff --git a/src/hotspot/cpu/x86/stubRoutines_x86_32.cpp b/src/hotspot/cpu/x86/stubRoutines_x86_32.cpp index 7916a3b36305a..810f421f1418c 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86_32.cpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" @@ -31,11 +30,6 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = nullptr; - -address StubRoutines::x86::_d2i_wrapper = nullptr; -address StubRoutines::x86::_d2l_wrapper = nullptr; - jint StubRoutines::x86::_fpu_cntrl_wrd_std = 0; jint StubRoutines::x86::_fpu_cntrl_wrd_24 = 0; jint StubRoutines::x86::_fpu_cntrl_wrd_trunc = 0; diff --git a/src/hotspot/cpu/x86/stubRoutines_x86_64.cpp b/src/hotspot/cpu/x86/stubRoutines_x86_64.cpp index f37d6698d39fc..0825ba63b4fe8 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" @@ -33,14 +32,3 @@ jint StubRoutines::x86::_mxcsr_std = 0; jint StubRoutines::x86::_mxcsr_rz = 0; - -address StubRoutines::x86::_get_previous_sp_entry = nullptr; - -address StubRoutines::x86::_f2i_fixup = nullptr; -address StubRoutines::x86::_f2l_fixup = nullptr; -address StubRoutines::x86::_d2i_fixup = nullptr; -address StubRoutines::x86::_d2l_fixup = nullptr; -address StubRoutines::x86::_float_sign_mask = nullptr; -address StubRoutines::x86::_float_sign_flip = nullptr; -address StubRoutines::x86::_double_sign_mask = nullptr; -address StubRoutines::x86::_double_sign_flip = nullptr; diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index 823b965a09b51..548243cba838d 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "compiler/compiler_globals.hpp" @@ -596,7 +595,7 @@ void TemplateInterpreterGenerator::lock_method() { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::notZero, L); __ stop("method doesn't need synchronization"); @@ -607,7 +606,7 @@ void TemplateInterpreterGenerator::lock_method() { // get synchronization object { Label done; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_STATIC); // get receiver (assume this is frequent case) __ movptr(rax, Address(rlocals, Interpreter::local_offset_in_bytes(0))); @@ -855,7 +854,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // make sure method is native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -909,7 +908,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); @@ -999,7 +998,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // pass mirror handle if static call { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_STATIC); __ jcc(Assembler::zero, L); // get mirror @@ -1280,7 +1279,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // do unlocking if necessary { Label L; - __ movl(t, Address(method, Method::access_flags_offset())); + __ load_unsigned_short(t, Address(method, Method::access_flags_offset())); __ testl(t, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); // the code below should be shared with interpreter macro @@ -1432,7 +1431,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // make sure method is not native & not abstract #ifdef ASSERT - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); { Label L; __ testl(rax, JVM_ACC_NATIVE); @@ -1489,7 +1488,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { #ifdef ASSERT { Label L; - __ movl(rax, access_flags); + __ load_unsigned_short(rax, access_flags); __ testl(rax, JVM_ACC_SYNCHRONIZED); __ jcc(Assembler::zero, L); __ stop("method needs synchronization"); diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp index 75611524e3b0a..df8633bdd1502 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interp_masm.hpp" diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index 5ea2d8eba259b..af5c0fa94b1c0 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interp_masm.hpp" @@ -74,7 +73,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // Do Int register here switch ( i ) { case 0: - __ movl(rscratch1, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(rscratch1, Address(rbx, Method::access_flags_offset())); __ testl(rscratch1, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); break; @@ -159,7 +158,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { } // Now handle integrals. Only do c_rarg1 if not static. - __ movl(c_rarg3, Address(rbx, Method::access_flags_offset())); + __ load_unsigned_short(c_rarg3, Address(rbx, Method::access_flags_offset())); __ testl(c_rarg3, JVM_ACC_STATIC); __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp index 441e4c8a0b877..55bdb52c442d0 100644 --- a/src/hotspot/cpu/x86/templateTable_x86.cpp +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "compiler/disassembler.hpp" #include "gc/shared/collectedHeap.hpp" diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_32.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_32.cpp index 6ccf965a771d3..6dd2ddd58747d 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_32.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/upcallLinker.hpp" address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature, diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index e2dadf7f0ef98..08884c99f9b98 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "code/codeBlob.hpp" @@ -77,8 +76,6 @@ static int compute_reg_save_area_size(const ABIDescriptor& abi) { return size; } -constexpr int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions - static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { // 1. iterate all registers in the architecture // - check if they are volatile or not for the given abi @@ -115,12 +112,9 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc { const Address mxcsr_save(rsp, offset); Label skip_ldmx; - __ stmxcsr(mxcsr_save); - __ movl(rax, mxcsr_save); - __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); - __ cmp32(rax, mxcsr_std, rscratch1); + __ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1); __ jcc(Assembler::equal, skip_ldmx); + ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std()); __ ldmxcsr(mxcsr_std, rscratch1); __ bind(skip_ldmx); } diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 688cd4fa5a6d1..68fc4380a59c9 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "classfile/vmIntrinsics.hpp" @@ -929,7 +928,8 @@ void VM_Version::get_processor_features() { // Check if processor has Intel Ecore if (FLAG_IS_DEFAULT(EnableX86ECoreOpts) && is_intel() && cpu_family() == 6 && - (_model == 0x97 || _model == 0xAA || _model == 0xAC || _model == 0xAF)) { + (_model == 0x97 || _model == 0xAA || _model == 0xAC || _model == 0xAF || + _model == 0xCC || _model == 0xDD)) { FLAG_SET_DEFAULT(EnableX86ECoreOpts, true); } @@ -1028,6 +1028,7 @@ void VM_Version::get_processor_features() { _features &= ~CPU_AVX512_BITALG; _features &= ~CPU_AVX512_IFMA; _features &= ~CPU_APX_F; + _features &= ~CPU_AVX512_FP16; } // Currently APX support is only enabled for targets supporting AVX512VL feature. @@ -1078,6 +1079,7 @@ void VM_Version::get_processor_features() { _features &= ~CPU_AVX512_BITALG; _features &= ~CPU_AVX512_IFMA; _features &= ~CPU_AVX_IFMA; + _features &= ~CPU_AVX512_FP16; } } @@ -1722,9 +1724,9 @@ void VM_Version::get_processor_features() { if (ArrayOperationPartialInlineSize > MaxVectorSize) { ArrayOperationPartialInlineSize = MaxVectorSize >= 16 ? MaxVectorSize : 0; if (ArrayOperationPartialInlineSize) { - warning("Setting ArrayOperationPartialInlineSize as MaxVectorSize" INTX_FORMAT ")", MaxVectorSize); + warning("Setting ArrayOperationPartialInlineSize as MaxVectorSize=%zd", MaxVectorSize); } else { - warning("Setting ArrayOperationPartialInlineSize as " INTX_FORMAT, ArrayOperationPartialInlineSize); + warning("Setting ArrayOperationPartialInlineSize as %zd", ArrayOperationPartialInlineSize); } } } @@ -3110,6 +3112,9 @@ uint64_t VM_Version::CpuidInfo::feature_flags() const { } if (sef_cpuid7_edx.bits.serialize != 0) result |= CPU_SERIALIZE; + + if (_cpuid_info.sef_cpuid7_edx.bits.avx512_fp16 != 0) + result |= CPU_AVX512_FP16; } // ZX features. diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index 004b64ebe6eb1..9bd3116cf84de 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -276,7 +276,9 @@ class VM_Version : public Abstract_VM_Version { serialize : 1, : 5, cet_ibt : 1, - : 11; + : 2, + avx512_fp16 : 1, + : 8; } bits; }; @@ -416,8 +418,9 @@ class VM_Version : public Abstract_VM_Version { decl(CET_SS, "cet_ss", 57) /* Control Flow Enforcement - Shadow Stack */ \ decl(AVX512_IFMA, "avx512_ifma", 58) /* Integer Vector FMA instructions*/ \ decl(AVX_IFMA, "avx_ifma", 59) /* 256-bit VEX-coded variant of AVX512-IFMA*/ \ - decl(APX_F, "apx_f", 60) /* Intel Advanced Performance Extensions*/\ - decl(SHA512, "sha512", 61) /* SHA512 instructions*/ + decl(APX_F, "apx_f", 60) /* Intel Advanced Performance Extensions*/ \ + decl(SHA512, "sha512", 61) /* SHA512 instructions*/ \ + decl(AVX512_FP16, "avx512_fp16", 62) /* AVX512 FP16 ISA support*/ #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1ULL << bit), CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG) @@ -753,6 +756,7 @@ class VM_Version : public Abstract_VM_Version { static bool supports_avx512_bitalg() { return (_features & CPU_AVX512_BITALG) != 0; } static bool supports_avx512_vbmi() { return (_features & CPU_AVX512_VBMI) != 0; } static bool supports_avx512_vbmi2() { return (_features & CPU_AVX512_VBMI2) != 0; } + static bool supports_avx512_fp16() { return (_features & CPU_AVX512_FP16) != 0; } static bool supports_hv() { return (_features & CPU_HV) != 0; } static bool supports_serialize() { return (_features & CPU_SERIALIZE) != 0; } static bool supports_f16c() { return (_features & CPU_F16C) != 0; } @@ -840,7 +844,7 @@ class VM_Version : public Abstract_VM_Version { // For AVX CPUs only. f16c support is disabled if UseAVX == 0. static bool supports_float16() { - return supports_f16c() || supports_avx512vl(); + return supports_f16c() || supports_avx512vl() || supports_avx512_fp16(); } // Check intrinsic support diff --git a/src/hotspot/cpu/x86/vmreg_x86.cpp b/src/hotspot/cpu/x86/vmreg_x86.cpp index d40a6eaa4b2ac..44aee56ef15ce 100644 --- a/src/hotspot/cpu/x86/vmreg_x86.cpp +++ b/src/hotspot/cpu/x86/vmreg_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" #include "vmreg_x86.inline.hpp" diff --git a/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp b/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp index 8d3ceca7b4ab1..3e70a45b58b02 100644 --- a/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp +++ b/src/hotspot/cpu/x86/vtableStubs_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/compiledIC.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp b/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp index 20fb035905227..b27755a243f24 100644 --- a/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp +++ b/src/hotspot/cpu/x86/vtableStubs_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "code/compiledIC.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 95b761ad44ead..8b2c583554470 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1461,6 +1461,20 @@ bool Matcher::match_rule_supported(int opcode) { return false; } break; + case Op_AddHF: + case Op_DivHF: + case Op_FmaHF: + case Op_MaxHF: + case Op_MinHF: + case Op_MulHF: + case Op_ReinterpretS2HF: + case Op_ReinterpretHF2S: + case Op_SubHF: + case Op_SqrtHF: + if (!VM_Version::supports_avx512_fp16()) { + return false; + } + break; case Op_VectorLoadShuffle: case Op_VectorRearrange: case Op_MulReductionVI: @@ -4521,6 +4535,35 @@ instruct vReplS_reg(vec dst, rRegI src) %{ ins_pipe( pipe_slow ); %} +#ifdef _LP64 +instruct ReplHF_imm(vec dst, immH con, rRegI rtmp) %{ + match(Set dst (Replicate con)); + effect(TEMP rtmp); + format %{ "replicateHF $dst, $con \t! using $rtmp as TEMP" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + BasicType bt = Matcher::vector_element_basic_type(this); + assert(VM_Version::supports_avx512_fp16() && bt == T_SHORT, ""); + __ movl($rtmp$$Register, $con$$constant); + __ evpbroadcastw($dst$$XMMRegister, $rtmp$$Register, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + +instruct ReplHF_reg(vec dst, regF src, rRegI rtmp) %{ + predicate(VM_Version::supports_avx512_fp16() && Matcher::vector_element_basic_type(n) == T_SHORT); + match(Set dst (Replicate src)); + effect(TEMP rtmp); + format %{ "replicateHF $dst, $src \t! using $rtmp as TEMP" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + __ vmovw($rtmp$$Register, $src$$XMMRegister); + __ evpbroadcastw($dst$$XMMRegister, $rtmp$$Register, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} +#endif + instruct ReplS_mem(vec dst, memory mem) %{ predicate(UseAVX >= 2 && Matcher::vector_element_basic_type(n) == T_SHORT); match(Set dst (Replicate (LoadS mem))); @@ -10837,3 +10880,80 @@ instruct vector_selectfrom_twovectors_reg_evex(vec index, vec src1, vec src2) %} ins_pipe(pipe_slow); %} + +instruct reinterpretS2HF(regF dst, rRegI src) +%{ + match(Set dst (ReinterpretS2HF src)); + format %{ "vmovw $dst, $src" %} + ins_encode %{ + __ vmovw($dst$$XMMRegister, $src$$Register); + %} + ins_pipe(pipe_slow); +%} + +instruct convF2HFAndS2HF(regF dst, regF src) +%{ + match(Set dst (ReinterpretS2HF (ConvF2HF src))); + format %{ "convF2HFAndS2HF $dst, $src" %} + ins_encode %{ + __ vcvtps2ph($dst$$XMMRegister, $src$$XMMRegister, 0x04, Assembler::AVX_128bit); + %} + ins_pipe(pipe_slow); +%} + +instruct convHF2SAndHF2F(regF dst, regF src) +%{ + match(Set dst (ConvHF2F (ReinterpretHF2S src))); + format %{ "convHF2SAndHF2F $dst, $src" %} + ins_encode %{ + __ vcvtph2ps($dst$$XMMRegister, $src$$XMMRegister, Assembler::AVX_128bit); + %} + ins_pipe(pipe_slow); +%} + +instruct reinterpretHF2S(rRegI dst, regF src) +%{ + match(Set dst (ReinterpretHF2S src)); + format %{ "vmovw $dst, $src" %} + ins_encode %{ + __ vmovw($dst$$Register, $src$$XMMRegister); + %} + ins_pipe(pipe_slow); +%} + +instruct scalar_sqrt_HF_reg(regF dst, regF src) +%{ + match(Set dst (SqrtHF src)); + format %{ "scalar_sqrt_fp16 $dst, $src" %} + ins_encode %{ + __ vsqrtsh($dst$$XMMRegister, $src$$XMMRegister); + %} + ins_pipe(pipe_slow); +%} + +instruct scalar_binOps_HF_reg(regF dst, regF src1, regF src2) +%{ + match(Set dst (AddHF src1 src2)); + match(Set dst (DivHF src1 src2)); + match(Set dst (MaxHF src1 src2)); + match(Set dst (MinHF src1 src2)); + match(Set dst (MulHF src1 src2)); + match(Set dst (SubHF src1 src2)); + format %{ "scalar_binop_fp16 $dst, $src1, $src2" %} + ins_encode %{ + int opcode = this->ideal_Opcode(); + __ efp16sh(opcode, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister); + %} + ins_pipe(pipe_slow); +%} + +instruct scalar_fma_HF_reg(regF dst, regF src1, regF src2) +%{ + match(Set dst (FmaHF src2 (Binary dst src1))); + effect(DEF dst); + format %{ "scalar_fma_fp16 $dst, $src1, $src2\t# $dst = $dst * $src1 + $src2 fma packedH" %} + ins_encode %{ + __ vfmadd132sh($dst$$XMMRegister, $src2$$XMMRegister, $src1$$XMMRegister); + %} + ins_pipe( pipe_slow ); +%} diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 02c0f9362085e..0b8dee7392aea 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -2443,22 +2443,6 @@ encode %{ } %} - enc_class Push_ModD_encoding(regD src0, regD src1) %{ - __ subptr(rsp, 8); - __ movdbl(Address(rsp, 0), $src1$$XMMRegister); - __ fld_d(Address(rsp, 0)); - __ movdbl(Address(rsp, 0), $src0$$XMMRegister); - __ fld_d(Address(rsp, 0)); - %} - - enc_class Push_ModF_encoding(regF src0, regF src1) %{ - __ subptr(rsp, 4); - __ movflt(Address(rsp, 0), $src1$$XMMRegister); - __ fld_s(Address(rsp, 0)); - __ movflt(Address(rsp, 0), $src0$$XMMRegister); - __ fld_s(Address(rsp, 0)); - %} - enc_class Push_ResultD(regD dst) %{ __ fstp_d(Address(rsp, 0)); __ movdbl($dst$$XMMRegister, Address(rsp, 0)); @@ -2490,20 +2474,6 @@ encode %{ __ fld_d(Address(rsp, 0)); %} - enc_class Push_Result_Mod_DPR( regDPR src) %{ - if ($src$$reg != FPR1L_enc) { - // fincstp - emit_opcode (masm, 0xD9); - emit_opcode (masm, 0xF7); - // FXCH FPR1 with src - emit_opcode(masm, 0xD9); - emit_d8(masm, 0xC8-1+$src$$reg ); - // fdecstp - emit_opcode (masm, 0xD9); - emit_opcode (masm, 0xF6); - } - %} - enc_class fnstsw_sahf_skip_parity() %{ // fnstsw ax emit_opcode( masm, 0xDF ); @@ -2515,28 +2485,6 @@ encode %{ emit_opcode( masm, 0x05 ); %} - enc_class emitModDPR() %{ - // fprem must be iterative - // :: loop - // fprem - emit_opcode( masm, 0xD9 ); - emit_opcode( masm, 0xF8 ); - // wait - emit_opcode( masm, 0x9b ); - // fnstsw ax - emit_opcode( masm, 0xDF ); - emit_opcode( masm, 0xE0 ); - // sahf - emit_opcode( masm, 0x9E ); - // jp ::loop - emit_opcode( masm, 0x0F ); - emit_opcode( masm, 0x8A ); - emit_opcode( masm, 0xF4 ); - emit_opcode( masm, 0xFF ); - emit_opcode( masm, 0xFF ); - emit_opcode( masm, 0xFF ); - %} - enc_class fpu_flags() %{ // fnstsw_ax emit_opcode( masm, 0xDF); @@ -9801,45 +9749,6 @@ instruct strictfp_divDPR_reg(regDPR1 dst, regnotDPR1 src) %{ ins_pipe( fpu_reg_reg ); %} -instruct modDPR_reg(regDPR dst, regDPR src, eAXRegI rax, eFlagsReg cr) %{ - predicate(UseSSE<=1); - match(Set dst (ModD dst src)); - effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS - - format %{ "DMOD $dst,$src" %} - ins_cost(250); - ins_encode(Push_Reg_Mod_DPR(dst, src), - emitModDPR(), - Push_Result_Mod_DPR(src), - Pop_Reg_DPR(dst)); - ins_pipe( pipe_slow ); -%} - -instruct modD_reg(regD dst, regD src0, regD src1, eAXRegI rax, eFlagsReg cr) %{ - predicate(UseSSE>=2); - match(Set dst (ModD src0 src1)); - effect(KILL rax, KILL cr); - - format %{ "SUB ESP,8\t # DMOD\n" - "\tMOVSD [ESP+0],$src1\n" - "\tFLD_D [ESP+0]\n" - "\tMOVSD [ESP+0],$src0\n" - "\tFLD_D [ESP+0]\n" - "loop:\tFPREM\n" - "\tFWAIT\n" - "\tFNSTSW AX\n" - "\tSAHF\n" - "\tJP loop\n" - "\tFSTP_D [ESP+0]\n" - "\tMOVSD $dst,[ESP+0]\n" - "\tADD ESP,8\n" - "\tFSTP ST0\t # Restore FPU Stack" - %} - ins_cost(250); - ins_encode( Push_ModD_encoding(src0, src1), emitModDPR(), Push_ResultD(dst), PopFPU); - ins_pipe( pipe_slow ); -%} - instruct atanDPR_reg(regDPR dst, regDPR src) %{ predicate (UseSSE<=1); match(Set dst(AtanD dst src)); @@ -10445,59 +10354,6 @@ instruct divFPR_reg(regFPR dst, regFPR src) %{ %} -// Spill to obtain 24-bit precision -instruct modFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{ - predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); - match(Set dst (ModF src1 src2)); - effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS - - format %{ "FMOD $dst,$src1,$src2" %} - ins_encode( Push_Reg_Mod_DPR(src1, src2), - emitModDPR(), - Push_Result_Mod_DPR(src2), - Pop_Mem_FPR(dst)); - ins_pipe( pipe_slow ); -%} -// -// This instruction does not round to 24-bits -instruct modFPR_reg(regFPR dst, regFPR src, eAXRegI rax, eFlagsReg cr) %{ - predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); - match(Set dst (ModF dst src)); - effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS - - format %{ "FMOD $dst,$src" %} - ins_encode(Push_Reg_Mod_DPR(dst, src), - emitModDPR(), - Push_Result_Mod_DPR(src), - Pop_Reg_FPR(dst)); - ins_pipe( pipe_slow ); -%} - -instruct modF_reg(regF dst, regF src0, regF src1, eAXRegI rax, eFlagsReg cr) %{ - predicate(UseSSE>=1); - match(Set dst (ModF src0 src1)); - effect(KILL rax, KILL cr); - format %{ "SUB ESP,4\t # FMOD\n" - "\tMOVSS [ESP+0],$src1\n" - "\tFLD_S [ESP+0]\n" - "\tMOVSS [ESP+0],$src0\n" - "\tFLD_S [ESP+0]\n" - "loop:\tFPREM\n" - "\tFWAIT\n" - "\tFNSTSW AX\n" - "\tSAHF\n" - "\tJP loop\n" - "\tFSTP_S [ESP+0]\n" - "\tMOVSS $dst,[ESP+0]\n" - "\tADD ESP,4\n" - "\tFSTP ST0\t # Restore FPU Stack" - %} - ins_cost(250); - ins_encode( Push_ModF_encoding(src0, src1), emitModDPR(), Push_ResultF(dst,0x4), PopFPU); - ins_pipe( pipe_slow ); -%} - - //----------Arithmetic Conversion Instructions--------------------------------- // The conversions operations are all Alpha sorted. Please keep it that way! diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 4667922505cbc..8cc4a970bfd9f 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -1,5 +1,5 @@ // -// Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -2382,6 +2382,16 @@ operand immF() interface(CONST_INTER); %} +// Half Float Immediate +operand immH() +%{ + match(ConH); + + op_cost(15); + format %{ %} + interface(CONST_INTER); +%} + // Double Immediate zero operand immD0() %{ @@ -4840,6 +4850,16 @@ instruct loadConF(regF dst, immF con) %{ ins_pipe(pipe_slow); %} +instruct loadConH(regF dst, immH con) %{ + match(Set dst con); + ins_cost(125); + format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} + ins_encode %{ + __ movflt($dst$$XMMRegister, $constantaddress($con)); + %} + ins_pipe(pipe_slow); +%} + instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ match(Set dst src); effect(KILL cr); @@ -7022,6 +7042,17 @@ instruct castFF(regF dst) ins_pipe(empty); %} +instruct castHH(regF dst) +%{ + match(Set dst (CastHH dst)); + + size(0); + format %{ "# castHH of $dst" %} + ins_encode(/* empty encoding */); + ins_cost(0); + ins_pipe(empty); +%} + instruct castDD(regD dst) %{ match(Set dst (CastDD dst)); diff --git a/src/hotspot/cpu/zero/abstractInterpreter_zero.cpp b/src/hotspot/cpu/zero/abstractInterpreter_zero.cpp index bf0d13f02f87e..ec293cfa41ab9 100644 --- a/src/hotspot/cpu/zero/abstractInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/abstractInterpreter_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/zero/bytecodeInterpreter.hpp" #include "interpreter/zero/zeroInterpreter.hpp" #include "runtime/frame.inline.hpp" diff --git a/src/hotspot/cpu/zero/assembler_zero.cpp b/src/hotspot/cpu/zero/assembler_zero.cpp index fe0f168885630..82815a57f8f26 100644 --- a/src/hotspot/cpu/zero/assembler_zero.cpp +++ b/src/hotspot/cpu/zero/assembler_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp index 3f02ff573fa72..17e845146e2d5 100644 --- a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2008 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/cpu/zero/compiledIC_zero.cpp b/src/hotspot/cpu/zero/compiledIC_zero.cpp index 869d96e65f844..a32bc2809aeb9 100644 --- a/src/hotspot/cpu/zero/compiledIC_zero.cpp +++ b/src/hotspot/cpu/zero/compiledIC_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/cpu/zero/disassembler_zero.cpp b/src/hotspot/cpu/zero/disassembler_zero.cpp index 944a52f5dd963..1fdb09eb73c15 100644 --- a/src/hotspot/cpu/zero/disassembler_zero.cpp +++ b/src/hotspot/cpu/zero/disassembler_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,6 +23,5 @@ * */ -#include "precompiled.hpp" // This file is intentionally empty diff --git a/src/hotspot/cpu/zero/downcallLinker_zero.cpp b/src/hotspot/cpu/zero/downcallLinker_zero.cpp index 4e549552e96da..3c7d93fc79e91 100644 --- a/src/hotspot/cpu/zero/downcallLinker_zero.cpp +++ b/src/hotspot/cpu/zero/downcallLinker_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/downcallLinker.hpp" RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, diff --git a/src/hotspot/cpu/zero/foreignGlobals_zero.cpp b/src/hotspot/cpu/zero/foreignGlobals_zero.cpp index d28a4c7c2f170..57433ffb98c1a 100644 --- a/src/hotspot/cpu/zero/foreignGlobals_zero.cpp +++ b/src/hotspot/cpu/zero/foreignGlobals_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/vmreg.hpp" #include "prims/foreignGlobals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/zero/frame_zero.cpp b/src/hotspot/cpu/zero/frame_zero.cpp index 7c65387f2388d..4b4bd1e2b87af 100644 --- a/src/hotspot/cpu/zero/frame_zero.cpp +++ b/src/hotspot/cpu/zero/frame_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp b/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp index 90f971a315243..62e7134ed61ee 100644 --- a/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp +++ b/src/hotspot/cpu/zero/gc/shared/barrierSetNMethod_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/zero/icache_zero.cpp b/src/hotspot/cpu/zero/icache_zero.cpp index 3b255befd55ac..25018110d9c98 100644 --- a/src/hotspot/cpu/zero/icache_zero.cpp +++ b/src/hotspot/cpu/zero/icache_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "runtime/icache.hpp" diff --git a/src/hotspot/cpu/zero/interpreterRT_zero.cpp b/src/hotspot/cpu/zero/interpreterRT_zero.cpp index 5aeb5a0981de0..85199524a888a 100644 --- a/src/hotspot/cpu/zero/interpreterRT_zero.cpp +++ b/src/hotspot/cpu/zero/interpreterRT_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/cpu/zero/jniFastGetField_zero.cpp b/src/hotspot/cpu/zero/jniFastGetField_zero.cpp index dea7d7c3b831b..3c43ccf69c1b4 100644 --- a/src/hotspot/cpu/zero/jniFastGetField_zero.cpp +++ b/src/hotspot/cpu/zero/jniFastGetField_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/jniFastGetField.hpp" diff --git a/src/hotspot/cpu/zero/methodHandles_zero.cpp b/src/hotspot/cpu/zero/methodHandles_zero.cpp index 4021d0e74b681..3bf8c46f56c8a 100644 --- a/src/hotspot/cpu/zero/methodHandles_zero.cpp +++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/cpu/zero/nativeInst_zero.cpp b/src/hotspot/cpu/zero/nativeInst_zero.cpp index 53f6fcef83019..0d2747f7fa698 100644 --- a/src/hotspot/cpu/zero/nativeInst_zero.cpp +++ b/src/hotspot/cpu/zero/nativeInst_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2008 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "entry_zero.hpp" #include "interpreter/zero/zeroInterpreter.hpp" diff --git a/src/hotspot/cpu/zero/register_zero.cpp b/src/hotspot/cpu/zero/register_zero.cpp index 812119b66af70..eef89153896a6 100644 --- a/src/hotspot/cpu/zero/register_zero.cpp +++ b/src/hotspot/cpu/zero/register_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "register_zero.hpp" const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers; diff --git a/src/hotspot/cpu/zero/relocInfo_zero.cpp b/src/hotspot/cpu/zero/relocInfo_zero.cpp index b926f20cfe7d8..647d5be31314c 100644 --- a/src/hotspot/cpu/zero/relocInfo_zero.cpp +++ b/src/hotspot/cpu/zero/relocInfo_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "code/relocInfo.hpp" #include "nativeInst_zero.hpp" diff --git a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp index 672f1d73dc1c0..f141135ff9571 100644 --- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp +++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/debugInfoRec.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/cpu/zero/stack_zero.cpp b/src/hotspot/cpu/zero/stack_zero.cpp index ef986111cf890..67692a2bb7bc0 100644 --- a/src/hotspot/cpu/zero/stack_zero.cpp +++ b/src/hotspot/cpu/zero/stack_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreterRuntime.hpp" #include "interpreter/zero/bytecodeInterpreter.hpp" #include "runtime/frame.inline.hpp" diff --git a/src/hotspot/cpu/zero/stubDeclarations_zero.hpp b/src/hotspot/cpu/zero/stubDeclarations_zero.hpp new file mode 100644 index 0000000000000..5808ae3bd8fa1 --- /dev/null +++ b/src/hotspot/cpu/zero/stubDeclarations_zero.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_ZERO_STUBDECLARATIONS_HPP +#define CPU_ZERO_STUBDECLARATIONS_HPP + +#define STUBGEN_INITIAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(initial, 0) \ + + +#define STUBGEN_CONTINUATION_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(continuation, 0) \ + + +#define STUBGEN_COMPILER_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(compiler, 0) \ + + +#define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ + do_arch_blob, \ + do_arch_entry, \ + do_arch_entry_init) \ + do_arch_blob(final, 0) \ + + +#endif // CPU_ZERO_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/zero/stubGenerator_zero.cpp b/src/hotspot/cpu/zero/stubGenerator_zero.cpp index b6905791e9884..07b4e2a92afbe 100644 --- a/src/hotspot/cpu/zero/stubGenerator_zero.cpp +++ b/src/hotspot/cpu/zero/stubGenerator_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2010, 2015 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_zero.hpp" @@ -180,8 +179,6 @@ class StubGenerator: public StubCodeGenerator { } void generate_initial_stubs() { - // Generates all stubs and initializes the entry points - // entry points that exist in all platforms Note: This is code // that could be shared among different platforms - however the // benefit seems to be smaller than the disadvantage of having a @@ -200,26 +197,44 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_fence_entry = ShouldNotCallThisStub(); } - void generate_final_stubs() { - // Generates all stubs and initializes the entry points + void generate_continuation_stubs() { + // do nothing + } + void generate_compiler_stubs() { + // do nothing + } + + void generate_final_stubs() { // arraycopy stubs used by compilers generate_arraycopy_stubs(); } public: - StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) { - if (kind == Initial_stubs) { + StubGenerator(CodeBuffer* code, StubGenBlobId blob_id) : StubCodeGenerator(code, blob_id) { + switch(blob_id) { + case initial_id: generate_initial_stubs(); - } else if (kind == Final_stubs) { + break; + case continuation_id: + generate_continuation_stubs(); + break; + case compiler_id: + // do nothing + break; + case final_id: generate_final_stubs(); - } + break; + default: + fatal("unexpected blob id: %d", blob_id); + break; + }; } }; -void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) { - StubGenerator g(code, kind); +void StubGenerator_generate(CodeBuffer* code, StubGenBlobId blob_id) { + StubGenerator g(code, blob_id); } EntryFrame *EntryFrame::build(const intptr_t* parameters, diff --git a/src/hotspot/cpu/zero/stubRoutines_zero.cpp b/src/hotspot/cpu/zero/stubRoutines_zero.cpp index 0a9e3558711dd..47d2c27eefdf1 100644 --- a/src/hotspot/cpu/zero/stubRoutines_zero.cpp +++ b/src/hotspot/cpu/zero/stubRoutines_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,8 +23,9 @@ * */ -#include "precompiled.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" #include "runtime/stubRoutines.hpp" + +// zero has no arch-specific stubs nor any associated entries diff --git a/src/hotspot/cpu/zero/stubRoutines_zero.hpp b/src/hotspot/cpu/zero/stubRoutines_zero.hpp index bd04fdddc3d56..2002efc9f51d5 100644 --- a/src/hotspot/cpu/zero/stubRoutines_zero.hpp +++ b/src/hotspot/cpu/zero/stubRoutines_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,14 +39,18 @@ return return_pc == call_stub_return_pc(); } - enum platform_dependent_constants { - // The assembler will fail with a guarantee if these are too small. - // Simply increase them if that happens. - _initial_stubs_code_size = 0, - _continuation_stubs_code_size = 0, - _compiler_stubs_code_size = 0, - _final_stubs_code_size = 0 - }; +// emit enum used to size per-blob code buffers + +#define DEFINE_BLOB_SIZE(blob_name, size) \ + _ ## blob_name ## _code_size = size, + +enum platform_dependent_constants { + STUBGEN_ARCH_BLOBS_DO(DEFINE_BLOB_SIZE) +}; + +#undef DEFINE_BLOB_SIZE + +// zero has no arch-specific stubs nor any associated entries enum method_handles_platform_dependent_constants { method_handles_adapters_code_size = 0 diff --git a/src/hotspot/cpu/zero/upcallLinker_zero.cpp b/src/hotspot/cpu/zero/upcallLinker_zero.cpp index 5dbc3cb62972d..55479a4b34176 100644 --- a/src/hotspot/cpu/zero/upcallLinker_zero.cpp +++ b/src/hotspot/cpu/zero/upcallLinker_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "prims/upcallLinker.hpp" address UpcallLinker::make_upcall_stub(jobject mh, Symbol* signature, diff --git a/src/hotspot/cpu/zero/vm_version_zero.cpp b/src/hotspot/cpu/zero/vm_version_zero.cpp index 1706be3089d78..e38561e19c571 100644 --- a/src/hotspot/cpu/zero/vm_version_zero.cpp +++ b/src/hotspot/cpu/zero/vm_version_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/cpu/zero/vmreg_zero.cpp b/src/hotspot/cpu/zero/vmreg_zero.cpp index f9f410de9c805..dfaec25540fef 100644 --- a/src/hotspot/cpu/zero/vmreg_zero.cpp +++ b/src/hotspot/cpu/zero/vmreg_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/cpu/zero/vtableStubs_zero.cpp b/src/hotspot/cpu/zero/vtableStubs_zero.cpp index 6258762279ee0..12819b484b2b6 100644 --- a/src/hotspot/cpu/zero/vtableStubs_zero.cpp +++ b/src/hotspot/cpu/zero/vtableStubs_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "code/vtableStubs.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp index 3e05eb1448dd6..029ccbded1366 100644 --- a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/os/aix/attachListener_aix.cpp b/src/hotspot/os/aix/attachListener_aix.cpp index 721901bb0e244..218ee04fdcc0e 100644 --- a/src/hotspot/os/aix/attachListener_aix.cpp +++ b/src/hotspot/os/aix/attachListener_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "os_posix.hpp" #include "runtime/interfaceSupport.inline.hpp" diff --git a/src/hotspot/os/aix/loadlib_aix.cpp b/src/hotspot/os/aix/loadlib_aix.cpp index bc21aef383698..2c38e1b637ca7 100644 --- a/src/hotspot/os/aix/loadlib_aix.cpp +++ b/src/hotspot/os/aix/loadlib_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * Copyright (c) 2022, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -203,7 +203,7 @@ static bool reload_table() { } } - trcVerbose("loadquery buffer size is " SIZE_FORMAT ".", buflen); + trcVerbose("loadquery buffer size is %zu.", buflen); // Iterate over the loadquery result. For details see sys/ldr.h on AIX. ldi = (struct ld_info*) buffer; @@ -262,7 +262,7 @@ static bool reload_table() { lm->is_in_vm = true; } - trcVerbose("entry: %p " SIZE_FORMAT ", %p " SIZE_FORMAT ", %s %s %s, %d", + trcVerbose("entry: %p %zu, %p %zu, %s %s %s, %d", lm->text, lm->text_len, lm->data, lm->data_len, lm->path, lm->shortname, diff --git a/src/hotspot/os/aix/osThread_aix.cpp b/src/hotspot/os/aix/osThread_aix.cpp index 86d9821e5a520..204b271ceee11 100644 --- a/src/hotspot/os/aix/osThread_aix.cpp +++ b/src/hotspot/os/aix/osThread_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "runtime/mutex.hpp" #include "runtime/osThread.hpp" diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 26627c2f8fb3b..e452bfdfd7c82 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "classfile/vmSymbols.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" @@ -165,6 +164,12 @@ extern "C" int getargs(procsinfo*, int, char*, int); #ifndef PV_10_Compat #define PV_10_Compat 0x508000 /* Power PC 10 */ #endif +#ifndef PV_11 + #define PV_11 0x600000 /* Power PC 11 */ +#endif +#ifndef PV_11_Compat + #define PV_11_Compat 0x608000 /* Power PC 11 */ +#endif static address resolve_function_descriptor_to_code_pointer(address p); @@ -450,7 +455,7 @@ static void query_multipage_support() { if (p != (void*) -1) { const size_t real_pagesize = os::Aix::query_pagesize(p); if (real_pagesize != pagesize) { - log_warning(pagesize)("real page size (" SIZE_FORMAT_X ") differs.", real_pagesize); + log_warning(pagesize)("real page size (0x%zx) differs.", real_pagesize); } else { can_use = true; } @@ -631,8 +636,8 @@ static void *thread_native_entry(Thread *thread) { if (lt.is_enabled()) { address low_address = thread->stack_end(); address high_address = thread->stack_base(); - lt.print("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT - ", stack [" PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k using %luk pages)).", + lt.print("Thread is alive (tid: %zu, kernel thread id: %zu" + ", stack [" PTR_FORMAT " - " PTR_FORMAT " (%zuk using %luk pages)).", os::current_thread_id(), (uintx) kernel_thread_id, p2i(low_address), p2i(high_address), (high_address - low_address) / K, os::Aix::query_pagesize(low_address) / K); } @@ -681,7 +686,7 @@ static void *thread_native_entry(Thread *thread) { // Prevent dereferencing it from here on out. thread = nullptr; - log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").", + log_info(os, thread)("Thread finished (tid: %zu, kernel thread id: %zu).", os::current_thread_id(), (uintx) kernel_thread_id); return 0; @@ -706,8 +711,12 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // Init thread attributes. pthread_attr_t attr; int rslt = pthread_attr_init(&attr); - guarantee(rslt == 0, "pthread_attr_init has to return 0"); - guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???"); + if (rslt != 0) { + thread->set_osthread(nullptr); + delete osthread; + return false; + } + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // Make sure we run in 1:1 kernel-user-thread mode. guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???"); @@ -733,7 +742,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // guard pages might not fit on the tiny stack created. int ret = pthread_attr_setstacksize(&attr, stack_size); if (ret != 0) { - log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k", + log_warning(os, thread)("The %sthread stack size specified is invalid: %zuk", (thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "), stack_size / K); thread->set_osthread(nullptr); @@ -761,7 +770,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, if (ret == 0) { char buf[64]; - log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ", + log_info(os, thread)("Thread \"%s\" started (pthread id: %zu, attributes: %s). ", thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr)); } else { char buf[64]; @@ -769,7 +778,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, thread->name(), ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr)); // Log some OS information which might explain why creating the thread failed. log_warning(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads()); - log_warning(os, thread)("Checking JVM parameter MaxExpectedDataSegmentSize (currently " SIZE_FORMAT "k) might be helpful", MaxExpectedDataSegmentSize/K); + log_warning(os, thread)("Checking JVM parameter MaxExpectedDataSegmentSize (currently %zuk) might be helpful", MaxExpectedDataSegmentSize/K); LogStream st(Log(os, thread)::info()); os::Posix::print_rlimit_info(&st); os::print_memory_info(&st); @@ -839,8 +848,8 @@ bool os::create_attached_thread(JavaThread* thread) { // and save the caller's signal mask PosixSignals::hotspot_sigmask(thread); - log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", + log_info(os, thread)("Thread attached (tid: %zu, kernel thread id: %zu" + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (%zuK) ).", os::current_thread_id(), (uintx) kernel_thread_id, p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); @@ -1067,21 +1076,24 @@ static void* dll_load_library(const char *filename, int *eno, char *ebuf, int eb // If filename matches .so, and loading fails, repeat with .a. void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { void* result = nullptr; - char* const file_path = strdup(filename); - char* const pointer_to_dot = strrchr(file_path, '.'); const char old_extension[] = ".so"; const char new_extension[] = ".a"; - STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension)); // First try to load the existing file. - int eno=0; + int eno = 0; result = dll_load_library(filename, &eno, ebuf, ebuflen); - // If the load fails,we try to reload by changing the extension to .a for .so files only. + // If the load fails, we try to reload by changing the extension to .a for .so files only. // Shared object in .so format dont have braces, hence they get removed for archives with members. - if (result == nullptr && eno == ENOENT && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) { - snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension); - result = dll_load_library(file_path, &eno, ebuf, ebuflen); + if (result == nullptr && eno == ENOENT) { + const char* pointer_to_dot = strrchr(filename, '.'); + if (pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) { + STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension)); + char* tmp_path = os::strdup(filename); + size_t prefix_size = pointer_delta(pointer_to_dot, filename, 1); + os::snprintf(tmp_path + prefix_size, sizeof(old_extension), "%s", new_extension); + result = dll_load_library(tmp_path, &eno, ebuf, ebuflen); + os::free(tmp_path); + } } - FREE_C_HEAP_ARRAY(char, file_path); return result; } @@ -1191,10 +1203,10 @@ void os::print_memory_info(outputStream* st) { os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { - st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); - st->print_cr("physical free : " SIZE_FORMAT, mi.real_free); - st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total); - st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free); + st->print_cr("physical total : %zu", mi.real_total); + st->print_cr("physical free : %zu", mi.real_free); + st->print_cr("swap total : %zu", mi.pgsp_total); + st->print_cr("swap free : %zu", mi.pgsp_free); } st->cr(); @@ -1202,10 +1214,10 @@ void os::print_memory_info(outputStream* st) { st->print_cr("Program break at VM startup: " PTR_FORMAT ".", p2i(g_brk_at_startup)); address brk_now = (address)::sbrk(0); if (brk_now != (address)-1) { - st->print_cr("Program break now : " PTR_FORMAT " (distance: " SIZE_FORMAT "k).", + st->print_cr("Program break now : " PTR_FORMAT " (distance: %zuk).", p2i(brk_now), (size_t)((brk_now - g_brk_at_startup) / K)); } - st->print_cr("MaxExpectedDataSegmentSize : " SIZE_FORMAT "k.", MaxExpectedDataSegmentSize / K); + st->print_cr("MaxExpectedDataSegmentSize : %zuk.", MaxExpectedDataSegmentSize / K); st->cr(); // Print segments allocated with os::reserve_memory. @@ -1217,6 +1229,9 @@ void os::print_memory_info(outputStream* st) { void os::get_summary_cpu_info(char* buf, size_t buflen) { // read _system_configuration.version switch (_system_configuration.version) { + case PV_11: + strncpy(buf, "Power PC 11", buflen); + break; case PV_10: strncpy(buf, "Power PC 10", buflen); break; @@ -1262,6 +1277,9 @@ void os::get_summary_cpu_info(char* buf, size_t buflen) { case PV_10_Compat: strncpy(buf, "PV_10_Compat", buflen); break; + case PV_11_Compat: + strncpy(buf, "PV_11_Compat", buflen); + break; default: strncpy(buf, "unknown", buflen); } @@ -1379,7 +1397,7 @@ struct vmembk_t { } void print_on(outputStream* os) const { - os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (" UINTX_FORMAT + os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (%zu" " bytes, %ld %s pages), %s", p2i(addr), p2i(addr) + size - 1, size, size / pagesize, describe_pagesize(pagesize), (type == VMEM_SHMATED ? "shmat" : "mmap") @@ -1456,7 +1474,7 @@ static void vmembk_print_on(outputStream* os) { // If is null, function will attach the memory anywhere. static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { - trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress " + trcVerbose("reserve_shmated_memory %zu bytes, wishaddress " PTR_FORMAT "...", bytes, p2i(requested_addr)); // We must prevent anyone from attaching too close to the @@ -1477,7 +1495,7 @@ static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR); if (shmid == -1) { ErrnoPreserver ep; - log_trace(os, map)("shmget(.., " UINTX_FORMAT ", ..) failed (errno=%s).", + log_trace(os, map)("shmget(.., %zu, ..) failed (errno=%s).", size, os::strerror(ep.saved_errno())); return nullptr; } @@ -1493,7 +1511,7 @@ static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { shmbuf.shm_pagesize = 64*K; if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) != 0) { assert(false, - "Failed to set page size (need " UINTX_FORMAT + "Failed to set page size (need %zu" " 64K pages) - shmctl failed. (errno=%s).", size / (64 * K), os::strerror(os::get_last_error())); } @@ -1530,13 +1548,13 @@ static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { // work (see above), the system may have given us something other then 4K (LDR_CNTRL). const size_t real_pagesize = os::Aix::query_pagesize(addr); if (real_pagesize != (size_t)shmbuf.shm_pagesize) { - log_trace(os, map)("pagesize is, surprisingly, " SIZE_FORMAT, + log_trace(os, map)("pagesize is, surprisingly, %zu", real_pagesize); } if (addr) { log_trace(os, map)("shm-allocated succeeded: " RANGEFMT - " (" UINTX_FORMAT " %s pages)", + " (%zu %s pages)", RANGEFMTARGS(addr, size), size / real_pagesize, describe_pagesize(real_pagesize)); @@ -1545,7 +1563,7 @@ static char* reserve_shmated_memory (size_t bytes, char* requested_addr) { log_trace(os, map)("shm-allocate failed: " RANGEFMT, RANGEFMTARGS(requested_addr, size)); } else { - log_trace(os, map)("failed to shm-allocate " UINTX_FORMAT + log_trace(os, map)("failed to shm-allocate %zu" " bytes at any address.", size); } @@ -1587,7 +1605,7 @@ static bool uncommit_shmated_memory(char* addr, size_t size) { if (rc != 0) { ErrnoPreserver ep; - log_warning(os)("disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed, %s\n", p2i(addr), size, os::strerror(ep.saved_errno())); + log_warning(os)("disclaim64(" PTR_FORMAT ", %zu) failed, %s\n", p2i(addr), size, os::strerror(ep.saved_errno())); return false; } return true; @@ -1599,7 +1617,7 @@ static bool uncommit_shmated_memory(char* addr, size_t size) { // If is given, an attempt is made to attach at the given address. // Failing that, memory is allocated at any address. static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) { - trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT "...", + trcVerbose("reserve_mmaped_memory %zu bytes, wishaddress " PTR_FORMAT "...", bytes, p2i(requested_addr)); if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) { @@ -1689,7 +1707,7 @@ static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) { } addr = addr_aligned; - trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)", + trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (%zu bytes)", p2i(addr), p2i(addr + bytes), bytes); // bookkeeping @@ -1756,9 +1774,8 @@ static bool uncommit_mmaped_memory(char* addr, size_t size) { #ifdef PRODUCT static void warn_fail_commit_memory(char* addr, size_t size, bool exec, int err) { - warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT - ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec, - os::errno_name(err), err); + warning("INFO: os::commit_memory(" PTR_FORMAT ", %zu, %d) failed; error='%s' (errno=%d)", + p2i(addr), size, exec, os::errno_name(err), err); } #endif @@ -1775,10 +1792,10 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, bool os::pd_commit_memory(char* addr, size_t size, bool exec) { assert(is_aligned_to(addr, os::vm_page_size()), - "addr " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")", + "addr " PTR_FORMAT " not aligned to vm_page_size (%zu)", p2i(addr), os::vm_page_size()); assert(is_aligned_to(size, os::vm_page_size()), - "size " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")", + "size " PTR_FORMAT " not aligned to vm_page_size (%zu)", size, os::vm_page_size()); vmembk_t* const vmi = vmembk_find(addr); @@ -1810,10 +1827,10 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) { assert(is_aligned_to(addr, os::vm_page_size()), - "addr " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")", + "addr " PTR_FORMAT " not aligned to vm_page_size (%zu)", p2i(addr), os::vm_page_size()); assert(is_aligned_to(size, os::vm_page_size()), - "size " PTR_FORMAT " not aligned to vm_page_size (" SIZE_FORMAT ")", + "size " PTR_FORMAT " not aligned to vm_page_size (%zu)", size, os::vm_page_size()); // Dynamically do different things for mmap/shmat. @@ -2783,7 +2800,7 @@ bool os::start_debugging(char *buf, int buflen) { jio_snprintf(p, buflen -len, "\n\n" "Do you want to debug the problem?\n\n" - "To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n" + "To debug, run 'dbx -a %d'; then switch to thread tid %zd, k-tid %zd\n" "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n" "Otherwise, press RETURN to abort...", os::current_process_id(), diff --git a/src/hotspot/os/aix/os_perf_aix.cpp b/src/hotspot/os/aix/os_perf_aix.cpp index b5ae1a6a725a5..0b008a197ded7 100644 --- a/src/hotspot/os/aix/os_perf_aix.cpp +++ b/src/hotspot/os/aix/os_perf_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "jvm.h" #include "libperfstat_aix.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/os/aix/safepointMechanism_aix.cpp b/src/hotspot/os/aix/safepointMechanism_aix.cpp index 0a36c89bec6a9..e1f717cdd1490 100644 --- a/src/hotspot/os/aix/safepointMechanism_aix.cpp +++ b/src/hotspot/os/aix/safepointMechanism_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "nmt/memTracker.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/os/bsd/decoder_machO.cpp b/src/hotspot/os/bsd/decoder_machO.cpp index 417e7139a5897..173e030a7b51c 100644 --- a/src/hotspot/os/bsd/decoder_machO.cpp +++ b/src/hotspot/os/bsd/decoder_machO.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifdef __APPLE__ #include "decoder_machO.hpp" diff --git a/src/hotspot/os/bsd/gc/z/zLargePages_bsd.cpp b/src/hotspot/os/bsd/gc/z/zLargePages_bsd.cpp index 6e26741a5071f..0c42d7790886e 100644 --- a/src/hotspot/os/bsd/gc/z/zLargePages_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zLargePages_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zLargePages.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp index e5b3895c44e6d..3cd9338f1d66d 100644 --- a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zNUMA.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp b/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp index 16835c8303931..37c855c2e2be5 100644 --- a/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zErrno.hpp" #include "gc/z/zGlobals.hpp" @@ -102,7 +101,7 @@ bool ZPhysicalMemoryBacking::commit_inner(zoffset offset, size_t length) const { assert(is_aligned(untype(offset), os::vm_page_size()), "Invalid offset"); assert(is_aligned(length, os::vm_page_size()), "Invalid length"); - log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Committing memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); const uintptr_t addr = _base + untype(offset); @@ -149,7 +148,7 @@ size_t ZPhysicalMemoryBacking::uncommit(zoffset offset, size_t length) const { assert(is_aligned(untype(offset), os::vm_page_size()), "Invalid offset"); assert(is_aligned(length, os::vm_page_size()), "Invalid length"); - log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Uncommitting memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); const uintptr_t start = _base + untype(offset); diff --git a/src/hotspot/os/bsd/memMapPrinter_macosx.cpp b/src/hotspot/os/bsd/memMapPrinter_macosx.cpp index 33c30ab6f7099..477803001cb9f 100644 --- a/src/hotspot/os/bsd/memMapPrinter_macosx.cpp +++ b/src/hotspot/os/bsd/memMapPrinter_macosx.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,8 +25,6 @@ #if defined(__APPLE__) -#include "precompiled.hpp" - #include "nmt/memMapPrinter.hpp" #include "runtime/os.hpp" #include "utilities/align.hpp" @@ -380,4 +378,4 @@ void MemMapPrinter::pd_print_all_mappings(const MappingPrintSession& session) { summary.print_on(session); st->cr(); } -#endif // __APPLE__ \ No newline at end of file +#endif // __APPLE__ diff --git a/src/hotspot/os/bsd/osThread_bsd.cpp b/src/hotspot/os/bsd/osThread_bsd.cpp index d9624040bc740..db476e529ac2b 100644 --- a/src/hotspot/os/bsd/osThread_bsd.cpp +++ b/src/hotspot/os/bsd/osThread_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "runtime/mutex.hpp" #include "runtime/osThread.hpp" diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 5db846275d4b4..c538c54e86fe1 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "classfile/vmSymbols.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" @@ -605,7 +604,7 @@ static void *thread_native_entry(Thread *thread) { } } - log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", + log_info(os, thread)("Thread is alive (tid: %zu, pthread id: %zu).", os::current_thread_id(), (uintx) pthread_self()); // call one more level start routine @@ -615,7 +614,7 @@ static void *thread_native_entry(Thread *thread) { // Prevent dereferencing it from here on out. thread = nullptr; - log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", + log_info(os, thread)("Thread finished (tid: %zu, pthread id: %zu).", os::current_thread_id(), (uintx) pthread_self()); return 0; @@ -638,7 +637,12 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // init thread attributes pthread_attr_t attr; - pthread_attr_init(&attr); + int rslt = pthread_attr_init(&attr); + if (rslt != 0) { + thread->set_osthread(nullptr); + delete osthread; + return false; + } pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // calculate stack size if it's not specified by caller @@ -660,7 +664,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, char buf[64]; if (ret == 0) { - log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ", + log_info(os, thread)("Thread \"%s\" started (pthread id: %zu, attributes: %s). ", thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr)); } else { log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%s) for attributes: %s.", @@ -744,8 +748,8 @@ bool os::create_attached_thread(JavaThread* thread) { // and save the caller's signal mask PosixSignals::hotspot_sigmask(thread); - log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", + log_info(os, thread)("Thread attached (tid: %zu, pthread id: %zu" + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (%zuK) ).", os::current_thread_id(), (uintx) pthread_self(), p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; @@ -1459,7 +1463,7 @@ void os::print_memory_info(outputStream* st) { size_t size = sizeof(swap_usage); st->print("Memory:"); - st->print(" " SIZE_FORMAT "k page", os::vm_page_size()>>10); + st->print(" %zuk page", os::vm_page_size()>>10); st->print(", physical " UINT64_FORMAT "k", os::physical_memory() >> 10); @@ -1586,7 +1590,7 @@ void os::jvm_path(char *buf, jint buflen) { static void warn_fail_commit_memory(char* addr, size_t size, bool exec, int err) { - warning("INFO: os::commit_memory(" INTPTR_FORMAT ", " SIZE_FORMAT + warning("INFO: os::commit_memory(" INTPTR_FORMAT ", %zu" ", %d) failed; error='%s' (errno=%d)", (intptr_t)addr, size, exec, os::errno_name(err), err); } @@ -2524,7 +2528,7 @@ bool os::start_debugging(char *buf, int buflen) { jio_snprintf(p, buflen-len, "\n\n" "Do you want to debug the problem?\n\n" - "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n" + "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread %zd (" INTPTR_FORMAT ")\n" "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n" "Otherwise, press RETURN to abort...", os::current_process_id(), os::current_process_id(), diff --git a/src/hotspot/os/bsd/os_perf_bsd.cpp b/src/hotspot/os/bsd/os_perf_bsd.cpp index 631d2135b6475..78d9519c3a71a 100644 --- a/src/hotspot/os/bsd/os_perf_bsd.cpp +++ b/src/hotspot/os/bsd/os_perf_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/bsd/semaphore_bsd.cpp b/src/hotspot/os/bsd/semaphore_bsd.cpp index 849dafb36ee6d..771756ea5e028 100644 --- a/src/hotspot/os/bsd/semaphore_bsd.cpp +++ b/src/hotspot/os/bsd/semaphore_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "semaphore_bsd.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp index 4a8fda432d894..bb51d4f3b8ee0 100644 --- a/src/hotspot/os/linux/cgroupSubsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupSubsystem_linux.cpp @@ -37,7 +37,7 @@ #include "utilities/globalDefinitions.hpp" // controller names have to match the *_IDX indices -static const char* cg_controller_name[] = { "cpu", "cpuset", "cpuacct", "memory", "pids" }; +static const char* cg_controller_name[] = { "cpuset", "cpu", "cpuacct", "memory", "pids" }; CgroupSubsystem* CgroupSubsystemFactory::create() { CgroupV1MemoryController* memory = nullptr; @@ -226,9 +226,10 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, char buf[MAXPATHLEN+1]; char *p; bool is_cgroupsV2; - // true iff all required controllers, memory, cpu, cpuset, cpuacct are enabled + // true iff all required controllers, memory, cpu, cpuacct are enabled // at the kernel level. // pids might not be enabled on older Linux distros (SLES 12.1, RHEL 7.1) + // cpuset might not be enabled on newer Linux distros (Fedora 41) bool all_required_controllers_enabled; /* @@ -260,6 +261,7 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, cg_infos[MEMORY_IDX]._hierarchy_id = hierarchy_id; cg_infos[MEMORY_IDX]._enabled = (enabled == 1); } else if (strcmp(name, "cpuset") == 0) { + log_debug(os, container)("Detected optional cpuset controller entry in %s", proc_cgroups); cg_infos[CPUSET_IDX]._name = os::strdup(name); cg_infos[CPUSET_IDX]._hierarchy_id = hierarchy_id; cg_infos[CPUSET_IDX]._enabled = (enabled == 1); @@ -283,8 +285,8 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, is_cgroupsV2 = true; all_required_controllers_enabled = true; for (int i = 0; i < CG_INFO_LENGTH; i++) { - // pids controller is optional. All other controllers are required - if (i != PIDS_IDX) { + // pids and cpuset controllers are optional. All other controllers are required + if (i != PIDS_IDX && i != CPUSET_IDX) { is_cgroupsV2 = is_cgroupsV2 && cg_infos[i]._hierarchy_id == 0; all_required_controllers_enabled = all_required_controllers_enabled && cg_infos[i]._enabled; } diff --git a/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp b/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp index a00572f08e769..c9f99a4b6db4d 100644 --- a/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zLargePages.hpp" #include "hugepages.hpp" #include "os_linux.hpp" diff --git a/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp b/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp index e24367219aa48..60ce39179ff14 100644 --- a/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zArray.inline.hpp" #include "gc/z/zErrno.hpp" diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index b648876ac602c..1ae4e18fcf142 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zArray.inline.hpp" @@ -185,13 +184,13 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) // Make sure the filesystem block size is compatible if (ZGranuleSize % _block_size != 0) { - ZInitialize::error("Filesystem backing the heap has incompatible block size (" SIZE_FORMAT ")", + ZInitialize::error("Filesystem backing the heap has incompatible block size (%zu)", _block_size); return; } if (is_hugetlbfs() && _block_size != ZGranuleSize) { - ZInitialize::error("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", + ZInitialize::error("%s filesystem has unexpected block size %zu (expected %zu)", ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize); return; } @@ -316,7 +315,7 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max_capacity) const { return; } - log_info_p(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M", _available / M); + log_info_p(gc, init)("Available space on backing filesystem: %zuM", _available / M); // Warn if the filesystem doesn't currently have enough space available to hold // the max heap size. The max heap size will be capped if we later hit this limit @@ -324,9 +323,9 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max_capacity) const { if (_available < max_capacity) { log_warning_p(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); log_warning_p(gc)("Not enough space available on the backing filesystem to hold the current max Java heap"); - log_warning_p(gc)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem accordingly " + log_warning_p(gc)("size (%zuM). Please adjust the size of the backing filesystem accordingly " "(available", max_capacity / M); - log_warning_p(gc)("space is currently " SIZE_FORMAT "M). Continuing execution with the current filesystem " + log_warning_p(gc)("space is currently %zuM). Continuing execution with the current filesystem " "size could", _available / M); log_warning_p(gc)("lead to a premature OutOfMemoryError being thrown, due to failure to commit memory."); } @@ -342,7 +341,7 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max_capacity) const { } size_t actual_max_map_count = 0; - const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count); + const int result = fscanf(file, "%zu", &actual_max_map_count); fclose(file); if (result != 1) { // Failed to read file, skip check @@ -359,9 +358,9 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max_capacity) const { if (actual_max_map_count < required_max_map_count) { log_warning_p(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****"); log_warning_p(gc)("The system limit on number of memory mappings per process might be too low for the given"); - log_warning_p(gc)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at", + log_warning_p(gc)("max Java heap size (%zuM). Please adjust %s to allow for at", max_capacity / M, filename); - log_warning_p(gc)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing execution " + log_warning_p(gc)("least %zu mappings (current limit is %zu). Continuing execution " "with the current", required_max_map_count, actual_max_map_count); log_warning_p(gc)("limit could lead to a premature OutOfMemoryError being thrown, due to failure to map memory."); } @@ -598,7 +597,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate(bool punch_hole, zoffset offset, size_t } bool ZPhysicalMemoryBacking::commit_inner(zoffset offset, size_t length) const { - log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Committing memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); retry: @@ -698,7 +697,7 @@ size_t ZPhysicalMemoryBacking::commit(zoffset offset, size_t length) const { } size_t ZPhysicalMemoryBacking::uncommit(zoffset offset, size_t length) const { - log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Uncommitting memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); const ZErrno err = fallocate(true /* punch_hole */, offset, length); diff --git a/src/hotspot/os/linux/gc/z/zSyscall_linux.cpp b/src/hotspot/os/linux/gc/z/zSyscall_linux.cpp index ba26cbfcb2456..83225be506ff1 100644 --- a/src/hotspot/os/linux/gc/z/zSyscall_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zSyscall_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zSyscall_linux.hpp" #include OS_CPU_HEADER(gc/z/zSyscall) diff --git a/src/hotspot/os/linux/hugepages.cpp b/src/hotspot/os/linux/hugepages.cpp index c04ff7a4ca0e3..5472c093d3f30 100644 --- a/src/hotspot/os/linux/hugepages.cpp +++ b/src/hotspot/os/linux/hugepages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2024, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,9 +23,7 @@ * */ -#include "precompiled.hpp" #include "hugepages.hpp" - #include "logging/log.hpp" #include "logging/logStream.hpp" #include "runtime/globals_extension.hpp" @@ -95,7 +93,7 @@ static bool read_number_file(const char* file, size_t* out) { bool rc = false; if (f != nullptr) { uint64_t i = 0; - if (::fscanf(f, SIZE_FORMAT, out) == 1) { + if (::fscanf(f, "%zu", out) == 1) { rc = true; } ::fclose(f); @@ -155,7 +153,7 @@ void ExplicitHugePageSupport::scan_os() { // that only exposes /proc/meminfo but not /sys/kernel/mm/hugepages. In that case, we are not // sure about the state of hugepage support by the kernel, so we won't use explicit hugepages. if (!_pagesizes.contains(_default_hugepage_size)) { - log_info(pagesize)("Unexpected configuration: default pagesize (" SIZE_FORMAT ") " + log_info(pagesize)("Unexpected configuration: default pagesize (%zu) " "has no associated directory in /sys/kernel/mm/hugepages..", _default_hugepage_size); _inconsistent = true; } diff --git a/src/hotspot/os/linux/mallocInfoDcmd.cpp b/src/hotspot/os/linux/mallocInfoDcmd.cpp index 9fd35e6fe6dbc..ad98d5edece19 100644 --- a/src/hotspot/os/linux/mallocInfoDcmd.cpp +++ b/src/hotspot/os/linux/mallocInfoDcmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "mallocInfoDcmd.hpp" #include "os_linux.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/os/linux/memMapPrinter_linux.cpp b/src/hotspot/os/linux/memMapPrinter_linux.cpp index 0b696b9914efe..b84921dd3bb08 100644 --- a/src/hotspot/os/linux/memMapPrinter_linux.cpp +++ b/src/hotspot/os/linux/memMapPrinter_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "nmt/memMapPrinter.hpp" #include "procMapsParser.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/linux/osThread_linux.cpp b/src/hotspot/os/linux/osThread_linux.cpp index c9a44eb413f43..88e26a5d69b54 100644 --- a/src/hotspot/os/linux/osThread_linux.cpp +++ b/src/hotspot/os/linux/osThread_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "runtime/mutex.hpp" #include "runtime/osThread.hpp" diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index ac94309691747..57b8a37baf253 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "classfile/vmSymbols.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" @@ -379,9 +378,10 @@ static void next_line(FILE *f) { } while (c != '\n' && c != EOF); } -void os::Linux::kernel_version(long* major, long* minor) { - *major = -1; - *minor = -1; +void os::Linux::kernel_version(long* major, long* minor, long* patch) { + *major = 0; + *minor = 0; + *patch = 0; struct utsname buffer; int ret = uname(&buffer); @@ -389,12 +389,29 @@ void os::Linux::kernel_version(long* major, long* minor) { log_warning(os)("uname(2) failed to get kernel version: %s", os::errno_name(ret)); return; } - int nr_matched = sscanf(buffer.release, "%ld.%ld", major, minor); - if (nr_matched != 2) { - log_warning(os)("Parsing kernel version failed, expected 2 version numbers, only matched %d", nr_matched); + int nr_matched = sscanf(buffer.release, "%ld.%ld.%ld", major, minor, patch); + if (nr_matched != 3) { + log_warning(os)("Parsing kernel version failed, expected 3 version numbers, only matched %d", nr_matched); } } +int os::Linux::kernel_version_compare(long major1, long minor1, long patch1, + long major2, long minor2, long patch2) { + // Compare major versions + if (major1 > major2) return 1; + if (major1 < major2) return -1; + + // Compare minor versions + if (minor1 > minor2) return 1; + if (minor1 < minor2) return -1; + + // Compare patchlevel versions + if (patch1 > patch2) return 1; + if (patch1 < patch2) return -1; + + return 0; +} + bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu) { FILE* fh; uint64_t userTicks, niceTicks, systemTicks, idleTicks; @@ -847,7 +864,7 @@ static void *thread_native_entry(Thread *thread) { } } - log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", + log_info(os, thread)("Thread is alive (tid: %zu, pthread id: %zu).", os::current_thread_id(), (uintx) pthread_self()); assert(osthread->pthread_id() != 0, "pthread_id was not set as expected"); @@ -863,7 +880,7 @@ static void *thread_native_entry(Thread *thread) { // Prevent dereferencing it from here on out. thread = nullptr; - log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", + log_info(os, thread)("Thread finished (tid: %zu, pthread id: %zu).", os::current_thread_id(), (uintx) pthread_self()); return nullptr; @@ -925,7 +942,7 @@ static size_t get_static_tls_area_size(const pthread_attr_t *attr) { } } - log_info(os, thread)("Stack size adjustment for TLS is " SIZE_FORMAT, + log_info(os, thread)("Stack size adjustment for TLS is %zu", tls_size); return tls_size; } @@ -1032,7 +1049,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // pthread_attr_setstacksize() function can fail // if the stack size exceeds a system-imposed limit. assert_status(status == EINVAL, status, "pthread_attr_setstacksize"); - log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k", + log_warning(os, thread)("The %sthread stack size specified is invalid: %zuk", (thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "), stack_size / K); thread->set_osthread(nullptr); @@ -1054,7 +1071,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, char buf[64]; if (ret == 0) { - log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ", + log_info(os, thread)("Thread \"%s\" started (pthread id: %zu, attributes: %s). ", thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr)); // Print current timer slack if override is enabled and timer slack value is available. @@ -1062,7 +1079,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, if (TimerSlack >= 0) { int slack = prctl(PR_GET_TIMERSLACK); if (slack >= 0) { - log_info(os, thread)("Thread \"%s\" (pthread id: " UINTX_FORMAT ") timer slack: %dns", + log_info(os, thread)("Thread \"%s\" (pthread id: %zu) timer slack: %dns", thread->name(), (uintx) tid, slack); } } @@ -1170,8 +1187,8 @@ bool os::create_attached_thread(JavaThread* thread) { // and save the caller's signal mask PosixSignals::hotspot_sigmask(thread); - log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", + log_info(os, thread)("Thread attached (tid: %zu, pthread id: %zu" + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (%zuK) ).", os::current_thread_id(), (uintx) pthread_self(), p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); @@ -1366,12 +1383,9 @@ void os::Linux::capture_initial_stack(size_t max_size) { // Skip blank chars do { s++; } while (s && isspace((unsigned char) *s)); -#define _UFM UINTX_FORMAT -#define _DFM INTX_FORMAT - - // 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 - // 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 - i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM, + // 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 + // 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 + i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %zu %zu %zd %zu %zu %zu %zu", &state, // 3 %c &ppid, // 4 %d &pgrp, // 5 %d @@ -1391,18 +1405,15 @@ void os::Linux::capture_initial_stack(size_t max_size) { &nice, // 19 %ld &junk, // 20 %ld &it_real, // 21 %ld - &start, // 22 UINTX_FORMAT - &vsize, // 23 UINTX_FORMAT - &rss, // 24 INTX_FORMAT - &rsslim, // 25 UINTX_FORMAT - &scodes, // 26 UINTX_FORMAT - &ecode, // 27 UINTX_FORMAT - &stack_start); // 28 UINTX_FORMAT + &start, // 22 %zu + &vsize, // 23 %zu + &rss, // 24 %zd + &rsslim, // 25 %zu + &scodes, // 26 %zu + &ecode, // 27 %zu + &stack_start); // 28 %zu } -#undef _UFM -#undef _DFM - if (i != 28 - 2) { assert(false, "Bad conversion from /proc/self/stat"); // product mode - assume we are the primordial thread, good luck in the @@ -1463,8 +1474,8 @@ void os::Linux::capture_initial_stack(size_t max_size) { bool primordial = uintptr_t(&rlim) > uintptr_t(_initial_thread_stack_bottom) && uintptr_t(&rlim) < stack_top; - log_info(os, thread)("Capturing initial stack in %s thread: req. size: " SIZE_FORMAT "K, actual size: " - SIZE_FORMAT "K, top=" INTPTR_FORMAT ", bottom=" INTPTR_FORMAT, + log_info(os, thread)("Capturing initial stack in %s thread: req. size: %zuK, actual size: " + "%zuK, top=" INTPTR_FORMAT ", bottom=" INTPTR_FORMAT, primordial ? "primordial" : "user", max_size / K, _initial_thread_stack_size / K, stack_top, intptr_t(_initial_thread_stack_bottom)); } @@ -2312,14 +2323,14 @@ bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) { info->rssanon = info->rssfile = info->rssshmem = -1; if (f != nullptr) { while (::fgets(buf, sizeof(buf), f) != nullptr && num_found < num_values) { - if ( (info->vmsize == -1 && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &info->vmsize) == 1) || - (info->vmpeak == -1 && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &info->vmpeak) == 1) || - (info->vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &info->vmswap) == 1) || - (info->vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &info->vmhwm) == 1) || - (info->vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &info->vmrss) == 1) || - (info->rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &info->rssanon) == 1) || // Needs Linux 4.5 - (info->rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &info->rssfile) == 1) || // Needs Linux 4.5 - (info->rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &info->rssshmem) == 1) // Needs Linux 4.5 + if ( (info->vmsize == -1 && sscanf(buf, "VmSize: %zd kB", &info->vmsize) == 1) || + (info->vmpeak == -1 && sscanf(buf, "VmPeak: %zd kB", &info->vmpeak) == 1) || + (info->vmswap == -1 && sscanf(buf, "VmSwap: %zd kB", &info->vmswap) == 1) || + (info->vmhwm == -1 && sscanf(buf, "VmHWM: %zd kB", &info->vmhwm) == 1) || + (info->vmrss == -1 && sscanf(buf, "VmRSS: %zd kB", &info->vmrss) == 1) || + (info->rssanon == -1 && sscanf(buf, "RssAnon: %zd kB", &info->rssanon) == 1) || // Needs Linux 4.5 + (info->rssfile == -1 && sscanf(buf, "RssFile: %zd kB", &info->rssfile) == 1) || // Needs Linux 4.5 + (info->rssshmem == -1 && sscanf(buf, "RssShmem: %zd kB", &info->rssshmem) == 1) // Needs Linux 4.5 ) { num_found ++; @@ -2367,15 +2378,15 @@ void os::Linux::print_process_memory_info(outputStream* st) { // rss its components if the kernel is recent enough. meminfo_t info; if (query_process_memory_info(&info)) { - st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", info.vmsize, info.vmpeak); - st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", info.vmrss, info.vmhwm); + st->print_cr("Virtual Size: %zdK (peak: %zdK)", info.vmsize, info.vmpeak); + st->print("Resident Set Size: %zdK (peak: %zdK)", info.vmrss, info.vmhwm); if (info.rssanon != -1) { // requires kernel >= 4.5 - st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)", + st->print(" (anon: %zdK, file: %zdK, shmem: %zdK)", info.rssanon, info.rssfile, info.rssshmem); } st->cr(); if (info.vmswap != -1) { // requires kernel >= 2.6.34 - st->print_cr("Swapped out: " SSIZE_FORMAT "K", info.vmswap); + st->print_cr("Swapped out: %zdK", info.vmswap); } } else { st->print_cr("Could not open /proc/self/status to get process memory related information"); @@ -2396,7 +2407,7 @@ void os::Linux::print_process_memory_info(outputStream* st) { // If legacy mallinfo(), we can still print the values if we are sure they cannot have wrapped. might_have_wrapped = might_have_wrapped && (info.vmsize * K) > UINT_MAX; #endif - st->print_cr("C-Heap outstanding allocations: " SIZE_FORMAT "K, retained: " SIZE_FORMAT "K%s", + st->print_cr("C-Heap outstanding allocations: %zuK, retained: %zuK%s", total_allocated / K, free_retained / K, might_have_wrapped ? " (may have wrapped)" : ""); // Tunables @@ -2524,7 +2535,7 @@ void os::Linux::print_steal_info(outputStream* st) { void os::print_memory_info(outputStream* st) { st->print("Memory:"); - st->print(" " SIZE_FORMAT "k page", os::vm_page_size()>>10); + st->print(" %zuk page", os::vm_page_size()>>10); // values in struct sysinfo are "unsigned long" struct sysinfo si; @@ -2889,17 +2900,15 @@ static bool recoverable_mmap_error(int err) { static void warn_fail_commit_memory(char* addr, size_t size, bool exec, int err) { - warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT - ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec, - os::strerror(err), err); + warning("INFO: os::commit_memory(" PTR_FORMAT ", %zu, %d) failed; error='%s' (errno=%d)", + p2i(addr), size, exec, os::strerror(err), err); } static void warn_fail_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec, int err) { - warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT - ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, - alignment_hint, exec, os::strerror(err), err); + warning("INFO: os::commit_memory(" PTR_FORMAT ", %zu, %zu, %d) failed; error='%s' (errno=%d)", + p2i(addr), size, alignment_hint, exec, os::strerror(err), err); } // NOTE: Linux kernel does not really reserve the pages for us. @@ -3049,7 +3058,7 @@ size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) { // OS will initially always use small pages. return os::vm_page_size(); } else if (err != 0) { - log_info(gc, os)("::madvise(" PTR_FORMAT ", " SIZE_FORMAT ", %d) failed; " + log_info(gc, os)("::madvise(" PTR_FORMAT ", %zu, %d) failed; " "error='%s' (errno=%d)", p2i(first), len, MADV_POPULATE_WRITE, os::strerror(err), err); } @@ -3247,6 +3256,8 @@ bool os::Linux::libnuma_init() { libnuma_dlsym(handle, "numa_set_bind_policy"))); set_numa_bitmask_isbitset(CAST_TO_FN_PTR(numa_bitmask_isbitset_func_t, libnuma_dlsym(handle, "numa_bitmask_isbitset"))); + set_numa_bitmask_equal(CAST_TO_FN_PTR(numa_bitmask_equal_func_t, + libnuma_dlsym(handle, "numa_bitmask_equal"))); set_numa_distance(CAST_TO_FN_PTR(numa_distance_func_t, libnuma_dlsym(handle, "numa_distance"))); set_numa_get_membind(CAST_TO_FN_PTR(numa_get_membind_func_t, @@ -3257,6 +3268,8 @@ bool os::Linux::libnuma_init() { libnuma_dlsym(handle, "numa_move_pages"))); set_numa_set_preferred(CAST_TO_FN_PTR(numa_set_preferred_func_t, libnuma_dlsym(handle, "numa_set_preferred"))); + set_numa_get_run_node_mask(CAST_TO_FN_PTR(numa_get_run_node_mask_func_t, + libnuma_v2_dlsym(handle, "numa_get_run_node_mask"))); if (numa_available() != -1) { set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes")); @@ -3264,6 +3277,7 @@ bool os::Linux::libnuma_init() { set_numa_nodes_ptr((struct bitmask **)libnuma_dlsym(handle, "numa_nodes_ptr")); set_numa_interleave_bitmask(_numa_get_interleave_mask()); set_numa_membind_bitmask(_numa_get_membind()); + set_numa_cpunodebind_bitmask(_numa_get_run_node_mask()); // Create an index -> node mapping, since nodes are not always consecutive _nindex_to_node = new (mtInternal) GrowableArray(0, mtInternal); rebuild_nindex_to_node_map(); @@ -3440,9 +3454,11 @@ os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; os::Linux::numa_interleave_memory_v2_func_t os::Linux::_numa_interleave_memory_v2; os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy; os::Linux::numa_bitmask_isbitset_func_t os::Linux::_numa_bitmask_isbitset; +os::Linux::numa_bitmask_equal_func_t os::Linux::_numa_bitmask_equal; os::Linux::numa_distance_func_t os::Linux::_numa_distance; os::Linux::numa_get_membind_func_t os::Linux::_numa_get_membind; os::Linux::numa_get_interleave_mask_func_t os::Linux::_numa_get_interleave_mask; +os::Linux::numa_get_run_node_mask_func_t os::Linux::_numa_get_run_node_mask; os::Linux::numa_move_pages_func_t os::Linux::_numa_move_pages; os::Linux::numa_set_preferred_func_t os::Linux::_numa_set_preferred; os::Linux::NumaAllocationPolicy os::Linux::_current_numa_policy; @@ -3451,6 +3467,7 @@ struct bitmask* os::Linux::_numa_all_nodes_ptr; struct bitmask* os::Linux::_numa_nodes_ptr; struct bitmask* os::Linux::_numa_interleave_bitmask; struct bitmask* os::Linux::_numa_membind_bitmask; +struct bitmask* os::Linux::_numa_cpunodebind_bitmask; bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) { uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, @@ -3758,7 +3775,7 @@ static bool hugetlbfs_sanity_check(size_t page_size) { munmap(p, page_size); return true; } else { - log_info(pagesize)("Large page size (" SIZE_FORMAT "%s) failed sanity check, " + log_info(pagesize)("Large page size (%zu%s) failed sanity check, " "checking if smaller large page sizes are usable", byte_size_in_exact_unit(page_size), exact_unit_for_byte_size(page_size)); @@ -3770,7 +3787,7 @@ static bool hugetlbfs_sanity_check(size_t page_size) { if (p != MAP_FAILED) { // Mapping succeeded, sanity check passed. munmap(p, page_size_); - log_info(pagesize)("Large page size (" SIZE_FORMAT "%s) passed sanity check", + log_info(pagesize)("Large page size (%zu%s) passed sanity check", byte_size_in_exact_unit(page_size_), exact_unit_for_byte_size(page_size_)); return true; @@ -3969,22 +3986,22 @@ void os::Linux::large_page_init() { LargePageSizeInBytes == 0 || LargePageSizeInBytes == default_large_page_size) { large_page_size = default_large_page_size; - log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s", + log_info(pagesize)("Using the default large page size: %zu%s", byte_size_in_exact_unit(large_page_size), exact_unit_for_byte_size(large_page_size)); } else { if (all_large_pages.contains(LargePageSizeInBytes)) { large_page_size = LargePageSizeInBytes; - log_info(pagesize)("Overriding default large page size (" SIZE_FORMAT "%s) " - "using LargePageSizeInBytes: " SIZE_FORMAT "%s", + log_info(pagesize)("Overriding default large page size (%zu%s) " + "using LargePageSizeInBytes: %zu%s", byte_size_in_exact_unit(default_large_page_size), exact_unit_for_byte_size(default_large_page_size), byte_size_in_exact_unit(large_page_size), exact_unit_for_byte_size(large_page_size)); } else { large_page_size = default_large_page_size; - log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (" SIZE_FORMAT "%s) " - "using the default large page size: " SIZE_FORMAT "%s", + log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (%zu%s) " + "using the default large page size: %zu%s", byte_size_in_exact_unit(LargePageSizeInBytes), exact_unit_for_byte_size(LargePageSizeInBytes), byte_size_in_exact_unit(large_page_size), @@ -4029,7 +4046,7 @@ static void log_on_commit_special_failure(char* req_addr, size_t bytes, assert(error == ENOMEM, "Only expect to fail if no memory is available"); log_info(pagesize)("Failed to reserve and commit memory with given page size. req_addr: " PTR_FORMAT - " size: " SIZE_FORMAT "%s, page size: " SIZE_FORMAT "%s, (errno = %d)", + " size: %zu%s, page size: %zu%s, (errno = %d)", p2i(req_addr), byte_size_in_exact_unit(bytes), exact_unit_for_byte_size(bytes), byte_size_in_exact_unit(page_size), exact_unit_for_byte_size(page_size), error); } @@ -4058,8 +4075,7 @@ static bool commit_memory_special(size_t bytes, return false; } - log_debug(pagesize)("Commit special mapping: " PTR_FORMAT ", size=" SIZE_FORMAT "%s, page size=" - SIZE_FORMAT "%s", + log_debug(pagesize)("Commit special mapping: " PTR_FORMAT ", size=%zu%s, page size=%zu%s", p2i(addr), byte_size_in_exact_unit(bytes), exact_unit_for_byte_size(bytes), byte_size_in_exact_unit(page_size), @@ -4475,19 +4491,19 @@ void os::Linux::numa_init() { // bitmask when externally configured to run on all or fewer nodes. if (!Linux::libnuma_init()) { - FLAG_SET_ERGO(UseNUMA, false); - FLAG_SET_ERGO(UseNUMAInterleaving, false); // Also depends on libnuma. + disable_numa("Failed to initialize libnuma", true); } else { - if ((Linux::numa_max_node() < 1) || Linux::is_bound_to_single_node()) { - // If there's only one node (they start from 0) or if the process - // is bound explicitly to a single node using membind, disable NUMA - UseNUMA = false; + Linux::set_configured_numa_policy(Linux::identify_numa_policy()); + if (Linux::numa_max_node() < 1) { + disable_numa("Only a single NUMA node is available", false); + } else if (Linux::is_bound_to_single_mem_node()) { + disable_numa("The process is bound to a single NUMA node", true); + } else if (Linux::mem_and_cpu_node_mismatch()) { + disable_numa("The process memory and cpu node configuration does not match", true); } else { LogTarget(Info,os) log; LogStream ls(log); - Linux::set_configured_numa_policy(Linux::identify_numa_policy()); - struct bitmask* bmp = Linux::_numa_membind_bitmask; const char* numa_mode = "membind"; @@ -4525,6 +4541,20 @@ void os::Linux::numa_init() { } } +void os::Linux::disable_numa(const char* reason, bool warning) { + if ((UseNUMA && FLAG_IS_CMDLINE(UseNUMA)) || + (UseNUMAInterleaving && FLAG_IS_CMDLINE(UseNUMAInterleaving))) { + // Only issue a message if the user explicitly asked for NUMA support + if (warning) { + log_warning(os)("NUMA support disabled: %s", reason); + } else { + log_info(os)("NUMA support disabled: %s", reason); + } + } + FLAG_SET_ERGO(UseNUMA, false); + FLAG_SET_ERGO(UseNUMAInterleaving, false); +} + #if defined(IA32) && !defined(ZERO) /* * Work-around (execute code at a high address) for broken NX emulation using CS limit, @@ -5261,7 +5291,7 @@ bool os::start_debugging(char *buf, int buflen) { jio_snprintf(p, buflen-len, "\n\n" "Do you want to debug the problem?\n\n" - "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n" + "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread %zu (" INTPTR_FORMAT ")\n" "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n" "Otherwise, press RETURN to abort...", os::current_process_id(), os::current_process_id(), diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index a2a13baa24f96..bd2e1ea323048 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -91,7 +91,13 @@ class os::Linux { }; static int active_processor_count(); - static void kernel_version(long* major, long* minor); + static void kernel_version(long* major, long* minor, long* patch); + + // If kernel1 > kernel2 return 1 + // If kernel1 < kernel2 return -1 + // If kernel1 = kernel2 return 0 + static int kernel_version_compare(long major1, long minor1, long patch1, + long major2, long minor2, long patch2); // which_logical_cpu=-1 returns accumulated ticks for all cpus. static bool get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu); @@ -193,6 +199,7 @@ class os::Linux { private: static void numa_init(); + static void disable_numa(const char* reason, bool warning); typedef int (*sched_getcpu_func_t)(void); typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); typedef int (*numa_node_to_cpus_v2_func_t)(int node, void *mask); @@ -204,10 +211,12 @@ class os::Linux { typedef void (*numa_interleave_memory_v2_func_t)(void *start, size_t size, struct bitmask* mask); typedef struct bitmask* (*numa_get_membind_func_t)(void); typedef struct bitmask* (*numa_get_interleave_mask_func_t)(void); + typedef struct bitmask* (*numa_get_run_node_mask_func_t)(void); typedef long (*numa_move_pages_func_t)(int pid, unsigned long count, void **pages, const int *nodes, int *status, int flags); typedef void (*numa_set_preferred_func_t)(int node); typedef void (*numa_set_bind_policy_func_t)(int policy); typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n); + typedef int (*numa_bitmask_equal_func_t)(struct bitmask *bmp1, struct bitmask *bmp2); typedef int (*numa_distance_func_t)(int node1, int node2); static sched_getcpu_func_t _sched_getcpu; @@ -221,8 +230,10 @@ class os::Linux { static numa_interleave_memory_v2_func_t _numa_interleave_memory_v2; static numa_set_bind_policy_func_t _numa_set_bind_policy; static numa_bitmask_isbitset_func_t _numa_bitmask_isbitset; + static numa_bitmask_equal_func_t _numa_bitmask_equal; static numa_distance_func_t _numa_distance; static numa_get_membind_func_t _numa_get_membind; + static numa_get_run_node_mask_func_t _numa_get_run_node_mask; static numa_get_interleave_mask_func_t _numa_get_interleave_mask; static numa_move_pages_func_t _numa_move_pages; static numa_set_preferred_func_t _numa_set_preferred; @@ -231,6 +242,7 @@ class os::Linux { static struct bitmask* _numa_nodes_ptr; static struct bitmask* _numa_interleave_bitmask; static struct bitmask* _numa_membind_bitmask; + static struct bitmask* _numa_cpunodebind_bitmask; static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; } @@ -243,8 +255,10 @@ class os::Linux { static void set_numa_interleave_memory_v2(numa_interleave_memory_v2_func_t func) { _numa_interleave_memory_v2 = func; } static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; } + static void set_numa_bitmask_equal(numa_bitmask_equal_func_t func) { _numa_bitmask_equal = func; } static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; } static void set_numa_get_membind(numa_get_membind_func_t func) { _numa_get_membind = func; } + static void set_numa_get_run_node_mask(numa_get_run_node_mask_func_t func) { _numa_get_run_node_mask = func; } static void set_numa_get_interleave_mask(numa_get_interleave_mask_func_t func) { _numa_get_interleave_mask = func; } static void set_numa_move_pages(numa_move_pages_func_t func) { _numa_move_pages = func; } static void set_numa_set_preferred(numa_set_preferred_func_t func) { _numa_set_preferred = func; } @@ -253,6 +267,7 @@ class os::Linux { static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = (ptr == nullptr ? nullptr : *ptr); } static void set_numa_interleave_bitmask(struct bitmask* ptr) { _numa_interleave_bitmask = ptr ; } static void set_numa_membind_bitmask(struct bitmask* ptr) { _numa_membind_bitmask = ptr ; } + static void set_numa_cpunodebind_bitmask(struct bitmask* ptr) { _numa_cpunodebind_bitmask = ptr ; } static int sched_getcpu_syscall(void); enum NumaAllocationPolicy{ @@ -358,21 +373,26 @@ class os::Linux { } return false; } - // Check if bound to only one numa node. - // Returns true if bound to a single numa node, otherwise returns false. - static bool is_bound_to_single_node() { + // Check if memory is bound to only one numa node. + // Returns true if memory is bound to a single numa node, otherwise returns false. + static bool is_bound_to_single_mem_node() { int nodes = 0; unsigned int node = 0; unsigned int highest_node_number = 0; - if (_numa_membind_bitmask != nullptr && _numa_max_node != nullptr && _numa_bitmask_isbitset != nullptr) { + struct bitmask* mem_nodes_bitmask = Linux::_numa_membind_bitmask; + if (Linux::is_running_in_interleave_mode()) { + mem_nodes_bitmask = Linux::_numa_interleave_bitmask; + } + + if (mem_nodes_bitmask != nullptr && _numa_max_node != nullptr && _numa_bitmask_isbitset != nullptr) { highest_node_number = _numa_max_node(); } else { return false; } for (node = 0; node <= highest_node_number; node++) { - if (_numa_bitmask_isbitset(_numa_membind_bitmask, node)) { + if (_numa_bitmask_isbitset(mem_nodes_bitmask, node)) { nodes++; } } @@ -383,6 +403,19 @@ class os::Linux { return false; } } + // Check if cpu and memory nodes are aligned, returns true if nodes misalign + static bool mem_and_cpu_node_mismatch() { + struct bitmask* mem_nodes_bitmask = Linux::_numa_membind_bitmask; + if (Linux::is_running_in_interleave_mode()) { + mem_nodes_bitmask = Linux::_numa_interleave_bitmask; + } + + if (mem_nodes_bitmask == nullptr || Linux::_numa_cpunodebind_bitmask == nullptr) { + return false; + } + + return !_numa_bitmask_equal(mem_nodes_bitmask, Linux::_numa_cpunodebind_bitmask); + } static const GrowableArray* numa_nindex_to_node() { return _nindex_to_node; diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp index 996f83611b048..ea7535edb870f 100644 --- a/src/hotspot/os/linux/os_perf_linux.cpp +++ b/src/hotspot/os/linux/os_perf_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jvm.h" #include "memory/allocation.inline.hpp" #include "os_linux.inline.hpp" diff --git a/src/hotspot/os/linux/procMapsParser.cpp b/src/hotspot/os/linux/procMapsParser.cpp index 6dfd49a0596e3..71b828bcefbc5 100644 --- a/src/hotspot/os/linux/procMapsParser.cpp +++ b/src/hotspot/os/linux/procMapsParser.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2024, Red Hat, Inc. and/or its affiliates. - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "procMapsParser.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp index 2398beb736033..766bb70a97710 100644 --- a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp +++ b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "os_linux.hpp" #include "utilities/debug.hpp" @@ -67,11 +66,11 @@ bool LinuxSystemMemoryBarrier::initialize() { // RISCV port was introduced in kernel 4.4. // 4.4 also made membar private expedited mandatory. // But RISCV actually don't support it until 6.9. - long major, minor; - os::Linux::kernel_version(&major, &minor); - if (!(major > 6 || (major == 6 && minor >= 9))) { - log_info(os)("Linux kernel %ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.", - major, minor); + long major, minor, patch; + os::Linux::kernel_version(&major, &minor, &patch); + if (os::Linux::kernel_version_compare(major, minor, patch, 6, 9, 0) == -1) { + log_info(os)("Linux kernel %ld.%ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.", + major, minor, patch); return false; } #endif diff --git a/src/hotspot/os/linux/trimCHeapDCmd.cpp b/src/hotspot/os/linux/trimCHeapDCmd.cpp index 26c066ffe5b6e..6b4cad03c1b55 100644 --- a/src/hotspot/os/linux/trimCHeapDCmd.cpp +++ b/src/hotspot/os/linux/trimCHeapDCmd.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 SAP SE. All rights reserved. - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "runtime/os.inline.hpp" #include "trimCHeapDCmd.hpp" diff --git a/src/hotspot/os/linux/waitBarrier_linux.cpp b/src/hotspot/os/linux/waitBarrier_linux.cpp index 2be31ce8366bb..f1f5be0515213 100644 --- a/src/hotspot/os/linux/waitBarrier_linux.cpp +++ b/src/hotspot/os/linux/waitBarrier_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/os/posix/attachListener_posix.cpp b/src/hotspot/os/posix/attachListener_posix.cpp index fea2075296a40..27728d0ca1f6e 100644 --- a/src/hotspot/os/posix/attachListener_posix.cpp +++ b/src/hotspot/os/posix/attachListener_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" diff --git a/src/hotspot/os/posix/gc/z/zArguments_posix.cpp b/src/hotspot/os/posix/gc/z/zArguments_posix.cpp index 4e6d43b16e918..dd84ef169907e 100644 --- a/src/hotspot/os/posix/gc/z/zArguments_posix.cpp +++ b/src/hotspot/os/posix/gc/z/zArguments_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zArguments.hpp" bool ZArguments::is_os_supported() { diff --git a/src/hotspot/os/posix/gc/z/zInitialize_posix.cpp b/src/hotspot/os/posix/gc/z/zInitialize_posix.cpp index ad4af504d8daf..193cae28a4cce 100644 --- a/src/hotspot/os/posix/gc/z/zInitialize_posix.cpp +++ b/src/hotspot/os/posix/gc/z/zInitialize_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zInitialize.hpp" void ZInitialize::pd_initialize() { diff --git a/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp b/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp index 936e734e8ff07..a177fe2b63647 100644 --- a/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp +++ b/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zVirtualMemory.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/os/posix/jvm_posix.cpp b/src/hotspot/os/posix/jvm_posix.cpp index a552e2695b59e..d34f2fc198b61 100644 --- a/src/hotspot/os/posix/jvm_posix.cpp +++ b/src/hotspot/os/posix/jvm_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jvm.h" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/osThread.hpp" diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 61214a4296998..6f756fbf64831 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -972,7 +972,7 @@ char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_a // Work around glibc stack guard issue, see os::create_thread() in os_linux.cpp. LINUX_ONLY(if (os::Linux::adjustStackSizeForGuardPages()) stack_size -= guard_size;) pthread_attr_getdetachstate(attr, &detachstate); - jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s", + jio_snprintf(buf, buflen, "stacksize: %zuk, guardsize: %zuk, %s", stack_size / K, guard_size / K, (detachstate == PTHREAD_CREATE_DETACHED ? "detached" : "joinable")); return buf; diff --git a/src/hotspot/os/posix/perfMemory_posix.cpp b/src/hotspot/os/posix/perfMemory_posix.cpp index 5fbd5e76c5aca..4d6fc1e4b8c9e 100644 --- a/src/hotspot/os/posix/perfMemory_posix.cpp +++ b/src/hotspot/os/posix/perfMemory_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmSymbols.hpp" #include "jvm_io.h" #include "logging/log.hpp" @@ -1086,16 +1085,16 @@ static char* mmap_create_shared(size_t size) { static void unmap_shared(char* addr, size_t bytes) { int res; if (MemTracker::enabled()) { - ThreadCritical tc; + MemTracker::NmtVirtualMemoryLocker nvml; res = ::munmap(addr, bytes); if (res == 0) { - MemTracker::record_virtual_memory_release((address)addr, bytes); + MemTracker::record_virtual_memory_release(addr, bytes); } } else { res = ::munmap(addr, bytes); } if (res != 0) { - log_info(os)("os::release_memory failed (" PTR_FORMAT ", " SIZE_FORMAT ")", p2i(addr), bytes); + log_info(os)("os::release_memory failed (" PTR_FORMAT ", %zu)", p2i(addr), bytes); } } @@ -1227,7 +1226,7 @@ static void mmap_attach_shared(int vmid, char** addr, size_t* sizep, TRAPS) { *addr = mapAddress; *sizep = size; - log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at " + log_debug(perf, memops)("mapped %zu bytes for vmid %d at " INTPTR_FORMAT, size, vmid, p2i((void*)mapAddress)); } diff --git a/src/hotspot/os/posix/safefetch_sigjmp.cpp b/src/hotspot/os/posix/safefetch_sigjmp.cpp index e141b8fb57317..57f0f8460bf7d 100644 --- a/src/hotspot/os/posix/safefetch_sigjmp.cpp +++ b/src/hotspot/os/posix/safefetch_sigjmp.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 SAP SE. All rights reserved. - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/safefetch.hpp" #include "sanitizers/address.hpp" diff --git a/src/hotspot/os/posix/safefetch_static_posix.cpp b/src/hotspot/os/posix/safefetch_static_posix.cpp index 5685a9e09f920..0e8f47fb2667d 100644 --- a/src/hotspot/os/posix/safefetch_static_posix.cpp +++ b/src/hotspot/os/posix/safefetch_static_posix.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 SAP SE. All rights reserved. - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "os_posix.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/posix/semaphore_posix.cpp b/src/hotspot/os/posix/semaphore_posix.cpp index 625abdf335b8b..23a5225eba3ef 100644 --- a/src/hotspot/os/posix/semaphore_posix.cpp +++ b/src/hotspot/os/posix/semaphore_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #ifndef __APPLE__ #include "os_posix.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index ddc7a05c2ff57..2c0ab6732c168 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nativeInst.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/os/posix/suspendResume_posix.cpp b/src/hotspot/os/posix/suspendResume_posix.cpp index 5256d9d888113..dbd0e791d77af 100644 --- a/src/hotspot/os/posix/suspendResume_posix.cpp +++ b/src/hotspot/os/posix/suspendResume_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/atomic.hpp" #include "suspendResume_posix.hpp" diff --git a/src/hotspot/os/posix/threadCrashProtection_posix.cpp b/src/hotspot/os/posix/threadCrashProtection_posix.cpp index 7d19b060479bc..06ecc844317e6 100644 --- a/src/hotspot/os/posix/threadCrashProtection_posix.cpp +++ b/src/hotspot/os/posix/threadCrashProtection_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/thread.hpp" #include "runtime/threadCrashProtection.hpp" diff --git a/src/hotspot/os/posix/threadCritical_posix.cpp b/src/hotspot/os/posix/threadCritical_posix.cpp index cd3b42e71ba8b..47fe98c7429f3 100644 --- a/src/hotspot/os/posix/threadCritical_posix.cpp +++ b/src/hotspot/os/posix/threadCritical_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/javaThread.hpp" #include "runtime/threadCritical.hpp" #include "utilities/compilerWarnings.hpp" diff --git a/src/hotspot/os/posix/vmError_posix.cpp b/src/hotspot/os/posix/vmError_posix.cpp index c1d89efa85596..9d6cd175c669b 100644 --- a/src/hotspot/os/posix/vmError_posix.cpp +++ b/src/hotspot/os/posix/vmError_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" #include "os_posix.hpp" diff --git a/src/hotspot/os/windows/attachListener_windows.cpp b/src/hotspot/os/windows/attachListener_windows.cpp index 8423fe42b7560..4e6f39b8f8189 100644 --- a/src/hotspot/os/windows/attachListener_windows.cpp +++ b/src/hotspot/os/windows/attachListener_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/windows/decoder_windows.cpp b/src/hotspot/os/windows/decoder_windows.cpp index 6a67a4eba9f2f..9bcab878e874f 100644 --- a/src/hotspot/os/windows/decoder_windows.cpp +++ b/src/hotspot/os/windows/decoder_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "utilities/decoder.hpp" #include "symbolengine.hpp" #include "windbghelp.hpp" diff --git a/src/hotspot/os/windows/gc/z/zArguments_windows.cpp b/src/hotspot/os/windows/gc/z/zArguments_windows.cpp index e10a06648f0e7..f5449d6232071 100644 --- a/src/hotspot/os/windows/gc/z/zArguments_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zArguments_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zArguments.hpp" #include "gc/z/zSyscall_windows.hpp" diff --git a/src/hotspot/os/windows/gc/z/zInitialize_windows.cpp b/src/hotspot/os/windows/gc/z/zInitialize_windows.cpp index 06b15c7db4172..a4751617ce7bd 100644 --- a/src/hotspot/os/windows/gc/z/zInitialize_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zInitialize_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zInitialize.hpp" #include "gc/z/zSyscall_windows.hpp" diff --git a/src/hotspot/os/windows/gc/z/zLargePages_windows.cpp b/src/hotspot/os/windows/gc/z/zLargePages_windows.cpp index f5455cbc58b80..dcd178da8212b 100644 --- a/src/hotspot/os/windows/gc/z/zLargePages_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zLargePages_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zLargePages.hpp" #include "gc/z/zSyscall_windows.hpp" diff --git a/src/hotspot/os/windows/gc/z/zMapper_windows.cpp b/src/hotspot/os/windows/gc/z/zMapper_windows.cpp index b2923a300e4bc..eadabcbb03026 100644 --- a/src/hotspot/os/windows/gc/z/zMapper_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zMapper_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zMapper_windows.hpp" #include "gc/z/zSyscall_windows.hpp" @@ -57,7 +56,7 @@ // they will be split before being used. #define fatal_error(msg, addr, size) \ - fatal(msg ": " PTR_FORMAT " " SIZE_FORMAT "M (%d)", \ + fatal(msg ": " PTR_FORMAT " %zuM (%d)", \ (addr), (size) / M, GetLastError()) zaddress_unsafe ZMapper::reserve(zaddress_unsafe addr, size_t size) { @@ -251,7 +250,7 @@ void ZMapper::unreserve_for_shared_awe(zaddress_unsafe addr, size_t size) { ); if (!res) { - fatal("Failed to unreserve memory: " PTR_FORMAT " " SIZE_FORMAT "M (%d)", + fatal("Failed to unreserve memory: " PTR_FORMAT " %zuM (%d)", untype(addr), size / M, GetLastError()); } } diff --git a/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp b/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp index a0fe34c65041e..8a93b66f38902 100644 --- a/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zNUMA.hpp" void ZNUMA::pd_initialize() { diff --git a/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp b/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp index 0a66f04d31c30..2764f51c13b98 100644 --- a/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zPhysicalMemoryBacking_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zGranuleMap.inline.hpp" @@ -157,10 +156,10 @@ class ZPhysicalMemoryBackingLargePages : public ZPhysicalMemoryBackingImpl { size_t npages_res = npages; const bool res = AllocateUserPhysicalPages(ZAWESection, &npages_res, &_page_array[index]); if (!res) { - fatal("Failed to allocate physical memory " SIZE_FORMAT "M @ " PTR_FORMAT " (%d)", + fatal("Failed to allocate physical memory %zuM @ " PTR_FORMAT " (%d)", size / M, untype(offset), GetLastError()); } else { - log_debug(gc)("Allocated physical memory: " SIZE_FORMAT "M @ " PTR_FORMAT, size / M, untype(offset)); + log_debug(gc)("Allocated physical memory: %zuM @ " PTR_FORMAT, size / M, untype(offset)); } // AllocateUserPhysicalPages might not be able to allocate the requested amount of memory. @@ -175,7 +174,7 @@ class ZPhysicalMemoryBackingLargePages : public ZPhysicalMemoryBackingImpl { size_t npages_res = npages; const bool res = FreeUserPhysicalPages(ZAWESection, &npages_res, &_page_array[index]); if (!res) { - fatal("Failed to uncommit physical memory " SIZE_FORMAT "M @ " PTR_FORMAT " (%d)", + fatal("Failed to uncommit physical memory %zuM @ " PTR_FORMAT " (%d)", size, untype(offset), GetLastError()); } @@ -188,7 +187,7 @@ class ZPhysicalMemoryBackingLargePages : public ZPhysicalMemoryBackingImpl { const bool res = MapUserPhysicalPages((char*)untype(addr), npages, &_page_array[index]); if (!res) { - fatal("Failed to map view " PTR_FORMAT " " SIZE_FORMAT "M @ " PTR_FORMAT " (%d)", + fatal("Failed to map view " PTR_FORMAT " %zuM @ " PTR_FORMAT " (%d)", untype(addr), size / M, untype(offset), GetLastError()); } } @@ -198,7 +197,7 @@ class ZPhysicalMemoryBackingLargePages : public ZPhysicalMemoryBackingImpl { const bool res = MapUserPhysicalPages((char*)untype(addr), npages, nullptr); if (!res) { - fatal("Failed to unmap view " PTR_FORMAT " " SIZE_FORMAT "M (%d)", + fatal("Failed to unmap view " PTR_FORMAT " %zuM (%d)", addr, size / M, GetLastError()); } } @@ -224,14 +223,14 @@ void ZPhysicalMemoryBacking::warn_commit_limits(size_t max_capacity) const { } size_t ZPhysicalMemoryBacking::commit(zoffset offset, size_t length) { - log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Committing memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); return _impl->commit(offset, length); } size_t ZPhysicalMemoryBacking::uncommit(zoffset offset, size_t length) { - log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)", + log_trace(gc, heap)("Uncommitting memory: %zuM-%zuM (%zuM)", untype(offset) / M, untype(to_zoffset_end(offset, length)) / M, length / M); return _impl->uncommit(offset, length); diff --git a/src/hotspot/os/windows/gc/z/zSyscall_windows.cpp b/src/hotspot/os/windows/gc/z/zSyscall_windows.cpp index 68ebee5e655cc..527958770c0ea 100644 --- a/src/hotspot/os/windows/gc/z/zSyscall_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zSyscall_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zSyscall_windows.hpp" #include "runtime/java.hpp" diff --git a/src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp b/src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp index 294935eda866c..392b16e38a308 100644 --- a/src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zVirtualMemory_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zLargePages.inline.hpp" diff --git a/src/hotspot/os/windows/include/jvm_md.h b/src/hotspot/os/windows/include/jvm_md.h index a0e44a4561365..165b25a82f919 100644 --- a/src/hotspot/os/windows/include/jvm_md.h +++ b/src/hotspot/os/windows/include/jvm_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,12 @@ * JNI conversion, which should be sorted out later. */ +#include "jni.h" + #include #include #include -#include "jni.h" - typedef int socklen_t; #define JNI_LIB_PREFIX "" diff --git a/src/hotspot/os/windows/iphlp_interface.cpp b/src/hotspot/os/windows/iphlp_interface.cpp index 0d6a08b0bd0d4..d30def1749004 100644 --- a/src/hotspot/os/windows/iphlp_interface.cpp +++ b/src/hotspot/os/windows/iphlp_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "iphlp_interface.hpp" #include "os_windows.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/windows/jvm_windows.cpp b/src/hotspot/os/windows/jvm_windows.cpp index c3fa1645fcc58..da29b156ad688 100644 --- a/src/hotspot/os/windows/jvm_windows.cpp +++ b/src/hotspot/os/windows/jvm_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jvm.h" #include "os_windows.hpp" #include "runtime/interfaceSupport.inline.hpp" diff --git a/src/hotspot/os/windows/memMapPrinter_windows.cpp b/src/hotspot/os/windows/memMapPrinter_windows.cpp index ff27aea02c592..075a64f5863b2 100644 --- a/src/hotspot/os/windows/memMapPrinter_windows.cpp +++ b/src/hotspot/os/windows/memMapPrinter_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "nmt/memMapPrinter.hpp" #include "os_windows.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os/windows/osThread_windows.cpp b/src/hotspot/os/windows/osThread_windows.cpp index abbff6b3a78f9..f36e95c51c106 100644 --- a/src/hotspot/os/windows/osThread_windows.cpp +++ b/src/hotspot/os/windows/osThread_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/osThread.hpp" #include diff --git a/src/hotspot/os/windows/os_perf_windows.cpp b/src/hotspot/os/windows/os_perf_windows.cpp index 57dcd2710c876..9d04ae65954cc 100644 --- a/src/hotspot/os/windows/os_perf_windows.cpp +++ b/src/hotspot/os/windows/os_perf_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "iphlp_interface.hpp" #include "jvm_io.h" #include "logging/log.hpp" diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index afd8fe01752b0..7ad9f80141c20 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ // API level must be at least Windows Vista or Server 2008 to use InitOnceExecuteOnce -// no precompiled headers #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/nativeInst.hpp" @@ -146,26 +145,34 @@ LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = nullptr; HINSTANCE vm_lib_handle; +static void windows_preinit(HINSTANCE hinst) { + vm_lib_handle = hinst; + if (ForceTimeHighResolution) { + timeBeginPeriod(1L); + } + WindowsDbgHelp::pre_initialize(); + SymbolEngine::pre_initialize(); +} + +static void windows_atexit() { + if (ForceTimeHighResolution) { + timeEndPeriod(1L); + } +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + if (topLevelVectoredExceptionHandler != nullptr) { + RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler); + topLevelVectoredExceptionHandler = nullptr; + } +#endif +} + BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: - vm_lib_handle = hinst; - if (ForceTimeHighResolution) { - timeBeginPeriod(1L); - } - WindowsDbgHelp::pre_initialize(); - SymbolEngine::pre_initialize(); + windows_preinit(hinst); break; case DLL_PROCESS_DETACH: - if (ForceTimeHighResolution) { - timeEndPeriod(1L); - } -#if defined(USE_VECTORED_EXCEPTION_HANDLING) - if (topLevelVectoredExceptionHandler != nullptr) { - RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler); - topLevelVectoredExceptionHandler = nullptr; - } -#endif + windows_atexit(); break; default: break; @@ -198,12 +205,12 @@ struct PreserveLastError { static LPVOID virtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) { LPVOID result = ::VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect); if (result != nullptr) { - log_trace(os)("VirtualAlloc(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x) returned " PTR_FORMAT "%s.", + log_trace(os)("VirtualAlloc(" PTR_FORMAT ", %zu, %x, %x) returned " PTR_FORMAT "%s.", p2i(lpAddress), dwSize, flAllocationType, flProtect, p2i(result), ((lpAddress != nullptr && result != lpAddress) ? " " : "")); } else { PreserveLastError ple; - log_info(os)("VirtualAlloc(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x) failed (%u).", + log_info(os)("VirtualAlloc(" PTR_FORMAT ", %zu, %x, %x) failed (%u).", p2i(lpAddress), dwSize, flAllocationType, flProtect, ple.v); } return result; @@ -213,11 +220,11 @@ static LPVOID virtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationTy static BOOL virtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) { BOOL result = ::VirtualFree(lpAddress, dwSize, dwFreeType); if (result != FALSE) { - log_trace(os)("VirtualFree(" PTR_FORMAT ", " SIZE_FORMAT ", %x) succeeded", + log_trace(os)("VirtualFree(" PTR_FORMAT ", %zu, %x) succeeded", p2i(lpAddress), dwSize, dwFreeType); } else { PreserveLastError ple; - log_info(os)("VirtualFree(" PTR_FORMAT ", " SIZE_FORMAT ", %x) failed (%u).", + log_info(os)("VirtualFree(" PTR_FORMAT ", %zu, %x) failed (%u).", p2i(lpAddress), dwSize, dwFreeType, ple.v); } return result; @@ -228,12 +235,12 @@ static LPVOID virtualAllocExNuma(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSiz DWORD flProtect, DWORD nndPreferred) { LPVOID result = ::VirtualAllocExNuma(hProcess, lpAddress, dwSize, flAllocationType, flProtect, nndPreferred); if (result != nullptr) { - log_trace(os)("VirtualAllocExNuma(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x, %x) returned " PTR_FORMAT "%s.", + log_trace(os)("VirtualAllocExNuma(" PTR_FORMAT ", %zu, %x, %x, %x) returned " PTR_FORMAT "%s.", p2i(lpAddress), dwSize, flAllocationType, flProtect, nndPreferred, p2i(result), ((lpAddress != nullptr && result != lpAddress) ? " " : "")); } else { PreserveLastError ple; - log_info(os)("VirtualAllocExNuma(" PTR_FORMAT ", " SIZE_FORMAT ", %x, %x, %x) failed (%u).", + log_info(os)("VirtualAllocExNuma(" PTR_FORMAT ", %zu, %x, %x, %x) failed (%u).", p2i(lpAddress), dwSize, flAllocationType, flProtect, nndPreferred, ple.v); } return result; @@ -245,12 +252,12 @@ static LPVOID mapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, LPVOID result = ::MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress); if (result != nullptr) { - log_trace(os)("MapViewOfFileEx(" PTR_FORMAT ", " SIZE_FORMAT ") returned " PTR_FORMAT "%s.", + log_trace(os)("MapViewOfFileEx(" PTR_FORMAT ", %zu) returned " PTR_FORMAT "%s.", p2i(lpBaseAddress), dwNumberOfBytesToMap, p2i(result), ((lpBaseAddress != nullptr && result != lpBaseAddress) ? " " : "")); } else { PreserveLastError ple; - log_info(os)("MapViewOfFileEx(" PTR_FORMAT ", " SIZE_FORMAT ") failed (%u).", + log_info(os)("MapViewOfFileEx(" PTR_FORMAT ", %zu) failed (%u).", p2i(lpBaseAddress), dwNumberOfBytesToMap, ple.v); } return result; @@ -285,6 +292,8 @@ void os::run_periodic_checks(outputStream* st) { static LONG WINAPI Uncaught_Exception_Handler(struct _EXCEPTION_POINTERS* exceptionInfo); +#define JVM_LIB_NAME "jvm.dll" + void os::init_system_properties_values() { // sysclasspath, java_home, dll_dir { @@ -300,15 +309,27 @@ void os::init_system_properties_values() { home_dir[MAX_PATH] = '\0'; } else { os::jvm_path(home_dir, sizeof(home_dir)); - // Found the full path to jvm.dll. - // Now cut the path to /jre if we can. - *(strrchr(home_dir, '\\')) = '\0'; // get rid of \jvm.dll + // Found the full path to the binary. It is normally of this structure: + // /bin//jvm.dll + // but can also be like this for a statically linked binary: + // /bin/.exe pslash = strrchr(home_dir, '\\'); if (pslash != nullptr) { - *pslash = '\0'; // get rid of \{client|server} + if (strncmp(pslash + 1, JVM_LIB_NAME, strlen(JVM_LIB_NAME)) == 0) { + // Binary name is jvm.dll. Get rid of \jvm.dll. + *pslash = '\0'; + } + + // Get rid of \hotspot_variant>, if binary is jvm.dll, + // or cut off \, if it is a statically linked binary. pslash = strrchr(home_dir, '\\'); if (pslash != nullptr) { - *pslash = '\0'; // get rid of \bin + *pslash = '\0'; + // Get rid of \bin + pslash = strrchr(home_dir, '\\'); + if (pslash != nullptr) { + *pslash = '\0'; + } } } } @@ -530,7 +551,7 @@ static unsigned thread_native_entry(void* t) { res = 20115; // java thread } - log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", stacksize: " SIZE_FORMAT "k).", os::current_thread_id(), thread->stack_size() / K); + log_info(os, thread)("Thread is alive (tid: %zu, stacksize: %zuk).", os::current_thread_id(), thread->stack_size() / K); #ifdef USE_VECTORED_EXCEPTION_HANDLING // Any exception is caught by the Vectored Exception Handler, so VM can @@ -552,7 +573,7 @@ static unsigned thread_native_entry(void* t) { // Note: at this point the thread object may already have deleted itself. // Do not dereference it from here on out. - log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); + log_info(os, thread)("Thread finished (tid: %zu).", os::current_thread_id()); // Thread must not return from exit_process_or_thread(), but if it does, // let it proceed to exit normally @@ -615,8 +636,8 @@ bool os::create_attached_thread(JavaThread* thread) { thread->set_osthread(osthread); - log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", stack: " - PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", + log_info(os, thread)("Thread attached (tid: %zu, stack: " + PTR_FORMAT " - " PTR_FORMAT " (%zuK) ).", os::current_thread_id(), p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); @@ -649,7 +670,7 @@ static char* describe_beginthreadex_attributes(char* buf, size_t buflen, if (stacksize == 0) { ss.print("stacksize: default, "); } else { - ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / K); + ss.print("stacksize: %zuk, ", stacksize / K); } ss.print("flags: "); #define PRINT_FLAG(f) if (initflag & f) ss.print( #f " "); @@ -1402,9 +1423,7 @@ void* os::dll_lookup(void *lib, const char *name) { } void* os::lookup_function(const char* name) { - // This is needed only for static builds which are not supported on Windows - ShouldNotReachHere(); - return nullptr; // Satisfy compiler + return ::GetProcAddress(nullptr, name); } // Directory routines copied from src/win32/native/java/io/dirent_md.c @@ -2071,7 +2090,7 @@ void os::get_summary_cpu_info(char* buf, size_t buflen) { void os::print_memory_info(outputStream* st) { st->print("Memory:"); - st->print(" " SIZE_FORMAT "k page", os::vm_page_size()>>10); + st->print(" %zuk page", os::vm_page_size()>>10); // Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect // value if total memory is larger than 4GB @@ -2570,38 +2589,6 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { return EXCEPTION_CONTINUE_EXECUTION; } -#if defined(_M_AMD64) -//----------------------------------------------------------------------------- -static bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) { - // handle exception caused by native method modifying control word - DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; - - switch (exception_code) { - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_FLT_INEXACT_RESULT: - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_OVERFLOW: - case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_FLT_UNDERFLOW: { - PCONTEXT ctx = exceptionInfo->ContextRecord; - // On Windows, the mxcsr control bits are non-volatile across calls - // See also CR 6192333 - // - jint MxCsr = INITIAL_MXCSR; - // we can't use StubRoutines::x86::addr_mxcsr_std() - // because in Win64 mxcsr is not saved there - if (MxCsr != ctx->MxCsr) { - ctx->MxCsr = MxCsr; - return true; - } - } - } - - return false; -} -#endif - static inline void report_error(Thread* t, DWORD exception_code, address addr, void* siginfo, void* context) { VMError::report_and_die(t, exception_code, addr, siginfo, context); @@ -2786,6 +2773,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { } #if defined(_M_AMD64) + extern bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo); if ((in_java || in_native) && handle_FLT_exception(exceptionInfo)) { return EXCEPTION_CONTINUE_EXECUTION; } @@ -3337,7 +3325,7 @@ char* os::pd_attempt_reserve_memory_at(char* addr, size_t bytes, bool exec) { } if (Verbose && PrintMiscellaneous) { reserveTimer.stop(); - tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes, + tty->print_cr("reserve_memory of %zx bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes, reserveTimer.milliseconds(), reserveTimer.ticks()); } } @@ -3421,7 +3409,7 @@ static char* find_aligned_address(size_t size, size_t alignment) { } static char* reserve_large_pages_aligned(size_t size, size_t alignment, bool exec) { - log_debug(pagesize)("Reserving large pages at an aligned address, alignment=" SIZE_FORMAT "%s", + log_debug(pagesize)("Reserving large pages at an aligned address, alignment=%zu%s", byte_size_in_exact_unit(alignment), exact_unit_for_byte_size(alignment)); // Will try to find a suitable address at most 20 times. The reason we need to try @@ -3483,7 +3471,7 @@ static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) { int err = os::get_last_error(); char buf[256]; size_t buf_len = os::lasterror(buf, sizeof(buf)); - warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT + warning("INFO: os::commit_memory(" PTR_FORMAT ", %zu" ", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes, exec, buf_len != 0 ? buf : "", err); } @@ -3619,10 +3607,7 @@ bool os::pd_release_memory(char* addr, size_t bytes) { // Handle mapping error. We assert in debug, unconditionally print a warning in release. if (err != nullptr) { log_warning(os)("bad release: [" PTR_FORMAT "-" PTR_FORMAT "): %s", p2i(start), p2i(end), err); -#ifdef ASSERT - os::print_memory_mappings((char*)start, bytes, tty); assert(false, "bad release: [" PTR_FORMAT "-" PTR_FORMAT "): %s", p2i(start), p2i(end), err); -#endif return false; } // Free this range @@ -3713,7 +3698,7 @@ bool os::protect_memory(char* addr, size_t bytes, ProtType prot, int err = os::get_last_error(); char buf[256]; size_t buf_len = os::lasterror(buf, sizeof(buf)); - warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT + warning("INFO: os::protect_memory(" PTR_FORMAT ", %zu" ") failed; error='%s' (DOS error/errno=%d)", addr, bytes, buf_len != 0 ? buf : "", err); } @@ -4415,6 +4400,14 @@ bool os::message_box(const char* title, const char* message) { // This is called _before_ the global arguments have been parsed void os::init(void) { + if (is_vm_statically_linked()) { + // Mimick what is done in DllMain for non-static builds + HMODULE hModule = nullptr; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nullptr, &hModule); + windows_preinit(hModule); + atexit(windows_atexit); + } + _initial_pid = _getpid(); win32::initialize_windows_version(); diff --git a/src/hotspot/os/windows/pdh_interface.cpp b/src/hotspot/os/windows/pdh_interface.cpp index 3134dc3f24cce..6f63452e7d9d7 100644 --- a/src/hotspot/os/windows/pdh_interface.cpp +++ b/src/hotspot/os/windows/pdh_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "os_windows.hpp" #include "pdh_interface.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os/windows/perfMemory_windows.cpp b/src/hotspot/os/windows/perfMemory_windows.cpp index 06b057315cbdd..dda0acde79346 100644 --- a/src/hotspot/os/windows/perfMemory_windows.cpp +++ b/src/hotspot/os/windows/perfMemory_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "memory/allocation.inline.hpp" @@ -1561,7 +1560,7 @@ static size_t sharedmem_filesize(const char* filename, TRAPS) { if ((statbuf.st_size == 0) || (statbuf.st_size % os::vm_page_size() != 0)) { if (PrintMiscellaneous && Verbose) { - warning("unexpected file size: size = " SIZE_FORMAT "\n", + warning("unexpected file size: size = %zu\n", statbuf.st_size); } THROW_MSG_0(vmSymbols::java_io_IOException(), @@ -1660,7 +1659,7 @@ static void open_file_mapping(int vmid, char** addrp, size_t* sizep, TRAPS) { // invalidating the mapped view of the file CloseHandle(fmh); - log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at " + log_debug(perf, memops)("mapped %zu bytes for vmid %d at " INTPTR_FORMAT, size, vmid, mapAddress); } @@ -1803,9 +1802,9 @@ void PerfMemory::detach(char* addr, size_t bytes) { if (MemTracker::enabled()) { // it does not go through os api, the operation has to record from here - ThreadCritical tc; + MemTracker::NmtVirtualMemoryLocker nvml; remove_file_mapping(addr); - MemTracker::record_virtual_memory_release((address)addr, bytes); + MemTracker::record_virtual_memory_release(addr, bytes); } else { remove_file_mapping(addr); } diff --git a/src/hotspot/os/windows/semaphore_windows.cpp b/src/hotspot/os/windows/semaphore_windows.cpp index 22b06241841ff..098ca526803a1 100644 --- a/src/hotspot/os/windows/semaphore_windows.cpp +++ b/src/hotspot/os/windows/semaphore_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "semaphore_windows.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/os/windows/sharedRuntimeRem.cpp b/src/hotspot/os/windows/sharedRuntimeRem.cpp index 62a85e55a0107..aae93f701ec7b 100644 --- a/src/hotspot/os/windows/sharedRuntimeRem.cpp +++ b/src/hotspot/os/windows/sharedRuntimeRem.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/sharedRuntime.hpp" // These are copied defines originally from fdlibm.h. diff --git a/src/hotspot/os/windows/symbolengine.cpp b/src/hotspot/os/windows/symbolengine.cpp index 0d461e671bb34..83cb930f7bfec 100644 --- a/src/hotspot/os/windows/symbolengine.cpp +++ b/src/hotspot/os/windows/symbolengine.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "utilities/globalDefinitions.hpp" #include "symbolengine.hpp" #include "utilities/debug.hpp" @@ -526,7 +525,7 @@ namespace { // Do not export. }; } -// Called at DLL_PROCESS_ATTACH. +// Called at DLL_PROCESS_ATTACH for dynamic builds, and from os::init() for static builds. void SymbolEngine::pre_initialize() { ::InitializeCriticalSection(&g_cs); } diff --git a/src/hotspot/os/windows/symbolengine.hpp b/src/hotspot/os/windows/symbolengine.hpp index 02d3ba9487d44..6f0f671f982e7 100644 --- a/src/hotspot/os/windows/symbolengine.hpp +++ b/src/hotspot/os/windows/symbolengine.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -58,7 +58,7 @@ namespace SymbolEngine { // missing - if any, and the dbhelp API version) void print_state_on(outputStream* st); - // Call at DLL_PROCESS_ATTACH. + // Called at DLL_PROCESS_ATTACH for dynamic builds, and from os::init() for static builds. void pre_initialize(); }; diff --git a/src/hotspot/os/windows/systemMemoryBarrier_windows.cpp b/src/hotspot/os/windows/systemMemoryBarrier_windows.cpp index 1ba27c4ced577..03811fcd64b69 100644 --- a/src/hotspot/os/windows/systemMemoryBarrier_windows.cpp +++ b/src/hotspot/os/windows/systemMemoryBarrier_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "systemMemoryBarrier_windows.hpp" #include diff --git a/src/hotspot/os/windows/threadCrashProtection_windows.cpp b/src/hotspot/os/windows/threadCrashProtection_windows.cpp index b8caa7aff5e78..07248c07426ac 100644 --- a/src/hotspot/os/windows/threadCrashProtection_windows.cpp +++ b/src/hotspot/os/windows/threadCrashProtection_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/thread.hpp" #include "runtime/threadCrashProtection.hpp" diff --git a/src/hotspot/os/windows/threadCritical_windows.cpp b/src/hotspot/os/windows/threadCritical_windows.cpp index c85143f80930d..35aa0839089bf 100644 --- a/src/hotspot/os/windows/threadCritical_windows.cpp +++ b/src/hotspot/os/windows/threadCritical_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/atomic.hpp" #include "runtime/javaThread.hpp" #include "runtime/threadCritical.hpp" diff --git a/src/hotspot/os/windows/threadLocalStorage_windows.cpp b/src/hotspot/os/windows/threadLocalStorage_windows.cpp index 7d809518aab33..f18c3fcb0a39f 100644 --- a/src/hotspot/os/windows/threadLocalStorage_windows.cpp +++ b/src/hotspot/os/windows/threadLocalStorage_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/threadLocalStorage.hpp" #include "utilities/debug.hpp" #include diff --git a/src/hotspot/os/windows/vmError_windows.cpp b/src/hotspot/os/windows/vmError_windows.cpp index 705e04e77db45..1613f52136fb1 100644 --- a/src/hotspot/os/windows/vmError_windows.cpp +++ b/src/hotspot/os/windows/vmError_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/os/windows/windbghelp.cpp b/src/hotspot/os/windows/windbghelp.cpp index 92c88d08cfc17..0de702580a306 100644 --- a/src/hotspot/os/windows/windbghelp.cpp +++ b/src/hotspot/os/windows/windbghelp.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "utilities/ostream.hpp" #include "windbghelp.hpp" @@ -141,7 +140,7 @@ namespace { // Do not export. }; } -// Called at DLL_PROCESS_ATTACH. +// Called at DLL_PROCESS_ATTACH for dynamic builds, and from os::init() for static builds. void WindowsDbgHelp::pre_initialize() { ::InitializeCriticalSection(&g_cs); } diff --git a/src/hotspot/os/windows/windbghelp.hpp b/src/hotspot/os/windows/windbghelp.hpp index e3e3826db29aa..cdfe781c3435a 100644 --- a/src/hotspot/os/windows/windbghelp.hpp +++ b/src/hotspot/os/windows/windbghelp.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ namespace WindowsDbgHelp { // missing - if any, and the dbhelp API version) void print_state_on(outputStream* st); - // Call at DLL_PROCESS_ATTACH. + // Called at DLL_PROCESS_ATTACH for dynamic builds, and from os::init() for static builds. void pre_initialize(); }; diff --git a/src/hotspot/os_cpu/aix_ppc/javaThread_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/javaThread_aix_ppc.cpp index 94e0c387a81dc..7cd57b65d32b3 100644 --- a/src/hotspot/os_cpu/aix_ppc/javaThread_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/javaThread_aix_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * Copyright (c) 2022, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp index 45d91c60ed42a..3d11bfe037acd 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "assembler_ppc.hpp" #include "asm/assembler.inline.hpp" #include "classfile/vmSymbols.hpp" @@ -448,7 +447,7 @@ void os::print_context(outputStream *st, const void *context) { } void os::print_register_info(outputStream *st, const void *context, int& continuation) { - const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, sp */; + const int register_count = 32 /* r0-r31 */ + 3 /* pc, lr, sp */; int n = continuation; assert(n >= 0 && n <= register_count, "Invalid continuation value"); if (context == nullptr || n == register_count) { diff --git a/src/hotspot/os_cpu/bsd_aarch64/javaThread_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/javaThread_bsd_aarch64.cpp index 336f194e276e4..fa40ef2b8f1c4 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/javaThread_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/javaThread_bsd_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "cds/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp index 1e3602d08f428..7b35317882da8 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp index cbfda539321f3..5424b58da6d10 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/assembler_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/assembler_bsd_x86.cpp index dd20ea833c8d2..2dc6b32998ac5 100644 --- a/src/hotspot/os_cpu/bsd_x86/assembler_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/assembler_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/javaThread_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/javaThread_bsd_x86.cpp index c636d147768d0..0b5e5b6e7bdd6 100644 --- a/src/hotspot/os_cpu/bsd_x86/javaThread_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/javaThread_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp index 153c5ad7e2b76..d11e7d8b90b62 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp index 3455a845eb97f..2d84caf2e84a6 100644 --- a/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/vm_version_bsd_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/bsd_zero/javaThread_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/javaThread_bsd_zero.cpp index d09516ff9eab6..0300103f72772 100644 --- a/src/hotspot/os_cpu/bsd_zero/javaThread_bsd_zero.cpp +++ b/src/hotspot/os_cpu/bsd_zero/javaThread_bsd_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp index fa64c857eeeaa..29efae1adc874 100644 --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "asm/assembler.inline.hpp" #include "atomic_bsd_zero.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp index eaf1b85e4be58..48a9d1f835220 100644 --- a/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp +++ b/src/hotspot/os_cpu/bsd_zero/vm_version_bsd_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp index 533151096b341..d4d428c9ddca3 100644 --- a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index a7ec163f78553..7728c62682c3b 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -355,7 +354,7 @@ void os::print_context(outputStream *st, const void *context) { } void os::print_register_info(outputStream *st, const void *context, int& continuation) { - const int register_count = 32 /* r0-r31 */; + const int register_count = 31 /* r0-r30 */; int n = continuation; assert(n >= 0 && n <= register_count, "Invalid continuation value"); if (context == nullptr || n == register_count) { diff --git a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp index 53e5631fc2b14..dabc69403f3d5 100644 --- a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/os.inline.hpp" #include "runtime/vm_version.hpp" @@ -185,7 +184,14 @@ static bool read_fully(const char *fname, char *buf, size_t buflen) { assert(buflen >= 1, "invalid argument"); int fd = os::open(fname, O_RDONLY, 0); if (fd != -1) { + PRAGMA_DIAG_PUSH + PRAGMA_NONNULL_IGNORED + // Suppress false positive gcc warning, which may be an example of + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87489 + // The warning also hasn't been seen with vanilla gcc release, so may also + // involve some distro-specific gcc patch. ssize_t read_sz = ::read(fd, buf, buflen); + PRAGMA_DIAG_POP ::close(fd); // Skip if the contents is just "\n" because some machine only sets diff --git a/src/hotspot/os_cpu/linux_arm/javaThread_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/javaThread_linux_arm.cpp index 738017a08957a..3dc0035ed8716 100644 --- a/src/hotspot/os_cpu/linux_arm/javaThread_linux_arm.cpp +++ b/src/hotspot/os_cpu/linux_arm/javaThread_linux_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.inline.hpp" diff --git a/src/hotspot/os_cpu/linux_arm/macroAssembler_linux_arm_32.cpp b/src/hotspot/os_cpu/linux_arm/macroAssembler_linux_arm_32.cpp index 0a3968ffa7064..e74daaa6d666a 100644 --- a/src/hotspot/os_cpu/linux_arm/macroAssembler_linux_arm_32.cpp +++ b/src/hotspot/os_cpu/linux_arm/macroAssembler_linux_arm_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp index 861d0d20153f7..5723e86f8594c 100644 --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "asm/assembler.inline.hpp" #include "classfile/vmSymbols.hpp" #include "code/vtableStubs.hpp" @@ -538,7 +537,7 @@ int64_t ARMAtomicFuncs::cmpxchg_long_bootstrap(int64_t compare_value, int64_t ex int64_t ARMAtomicFuncs::load_long_bootstrap(const volatile int64_t* src) { // try to use the stub: - load_long_func_t func = CAST_TO_FN_PTR(load_long_func_t, StubRoutines::atomic_load_long_entry()); + load_long_func_t func = CAST_TO_FN_PTR(load_long_func_t, StubRoutines::Arm::atomic_load_long_entry()); if (func != nullptr) { _load_long_func = func; @@ -552,7 +551,7 @@ int64_t ARMAtomicFuncs::load_long_bootstrap(const volatile int64_t* src) { void ARMAtomicFuncs::store_long_bootstrap(int64_t val, volatile int64_t* dest) { // try to use the stub: - store_long_func_t func = CAST_TO_FN_PTR(store_long_func_t, StubRoutines::atomic_store_long_entry()); + store_long_func_t func = CAST_TO_FN_PTR(store_long_func_t, StubRoutines::Arm::atomic_store_long_entry()); if (func != nullptr) { _store_long_func = func; diff --git a/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp b/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp index f1d29556e13cb..d1ef511d9d45c 100644 --- a/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp +++ b/src/hotspot/os_cpu/linux_arm/vm_version_linux_arm_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/linux_ppc/javaThread_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/javaThread_linux_ppc.cpp index f9fc6cec7fac9..a1c3d616eea5d 100644 --- a/src/hotspot/os_cpu/linux_ppc/javaThread_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/javaThread_linux_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index f3f9a3a88df67..81fede02956d4 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "assembler_ppc.hpp" #include "asm/assembler.inline.hpp" #include "classfile/vmSymbols.hpp" @@ -468,7 +467,7 @@ void os::print_context(outputStream *st, const void *context) { } void os::print_register_info(outputStream *st, const void *context, int& continuation) { - const int register_count = 32 /* r0-r32 */ + 3 /* pc, lr, ctr */; + const int register_count = 32 /* r0-r31 */ + 3 /* pc, lr, ctr */; int n = continuation; assert(n >= 0 && n <= register_count, "Invalid continuation value"); if (context == nullptr || n == register_count) { diff --git a/src/hotspot/os_cpu/linux_riscv/javaThread_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/javaThread_linux_riscv.cpp index c0dcba0ec51ea..4490ebcfdbf08 100644 --- a/src/hotspot/os_cpu/linux_riscv/javaThread_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/javaThread_linux_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp index a00659f37cb42..945280bca10b9 100644 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -56,8 +55,9 @@ // put OS-includes here # include -# include # include +# include +# include # include # include # include @@ -350,6 +350,72 @@ void os::print_context(outputStream *st, const void *context) { st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]); } st->cr(); + const struct __riscv_mc_d_ext_state * const f_ext_state = &(uc->uc_mcontext.__fpregs.__d); + st->print_cr("Floating point state:"); + st->print_cr("fcsr=" UINT32_FORMAT, f_ext_state->__fcsr); + st->print_cr("Floating point registers:"); + for (int r = 0; r < 32; r++) { + st->print_cr("f%d=" INTPTR_FORMAT, r, (intptr_t)f_ext_state->__f[r]); + } + st->cr(); + +#ifdef NO_RVV_SIGCONTEXT + st->print_cr("Vector state: JVM compiled without vector sigcontext support"); +#else // ifndef NO_RVV_SIGCONTEXT +// This magic number is not in any user-space header. +// No other choice but to define it (arch/riscv/include/uapi/asm/sigcontext.h). +#ifndef RISCV_V_MAGIC +#define RISCV_V_MAGIC 0x53465457 +#endif + + // Find the vector context + struct __riscv_extra_ext_header *ext = (struct __riscv_extra_ext_header *)(&uc->uc_mcontext.__fpregs); + if (ext->hdr.magic != RISCV_V_MAGIC) { + st->print_cr("Vector state: not found"); + return; + } + + // The size passed to user-space is calculated accordingly: + // size = sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state) + riscv_v_vsize; + uint32_t ext_size = ext->hdr.size; + + if (ext_size < (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state))) { + st->print_cr("Vector state: not found, invalid size"); + return; + } + + struct __riscv_v_ext_state *v_ext_state = (struct __riscv_v_ext_state *)((char *)(ext) + sizeof(struct __riscv_extra_ext_header)); + + st->print_cr("Vector state:"); + st->print_cr("vstart=" INTPTR_FORMAT, v_ext_state->vstart); + st->print_cr("vl =" INTPTR_FORMAT, v_ext_state->vl); + st->print_cr("vtype =" INTPTR_FORMAT, v_ext_state->vtype); + st->print_cr("vcsr =" INTPTR_FORMAT, v_ext_state->vcsr); + st->print_cr("vlenb =" INTPTR_FORMAT, v_ext_state->vlenb); + st->print_cr("Vector registers:"); + + uint64_t vr_size = v_ext_state->vlenb; + + // Registers are after the v extensions header. + ext_size -= (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state)); + + if (ext_size != (32 * vr_size)) { + st->print_cr("Vector registers: not found, invalid size"); + return; + } + + // datap format is undocumented, but is generated by kernel function riscv_v_vstate_save(). + uint8_t *regp = (uint8_t *)v_ext_state->datap; + for (int r = 0; r < 32; r++) { + st->print("v%d=0x", r); + for (int i = vr_size; i > 0; i--) { + st->print("%02" PRIx8, regp[i-1]); + } + st->print_cr(""); + regp += vr_size; + } + st->cr(); +#endif // #ifndef NO_RVV_SIGCONTEXT } void os::print_register_info(outputStream *st, const void *context, int& continuation) { diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp index 4ca977bd57609..16c1445179bb8 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "riscv_flush_icache.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index e65254fc5718f..5b427693a8dfd 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,8 +23,9 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" +#include "logging/logMessage.hpp" +#include "os_linux.hpp" #include "riscv_hwprobe.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" @@ -164,7 +165,18 @@ void RiscvHwprobe::add_features_from_query_result() { VM_Version::ext_C.enable_feature(); } if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_V)) { - VM_Version::ext_V.enable_feature(); + // Linux signal return bug when using vector with vlen > 128b in pre 6.8.5. + long major, minor, patch; + os::Linux::kernel_version(&major, &minor, &patch); + if (os::Linux::kernel_version_compare(major, minor, patch, 6, 8, 5) == -1) { + LogMessage(os) log; + if (log.is_info()) { + log.info("Linux kernels before 6.8.5 (current %ld.%ld.%ld) have a known bug when using Vector and signals.", major, minor, patch); + log.info("Vector not enabled automatically via hwprobe, but can be turned on with -XX:+UseRVV."); + } + } else { + VM_Version::ext_V.enable_feature(); + } } if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBA)) { VM_Version::ext_Zba.enable_feature(); @@ -178,6 +190,9 @@ void RiscvHwprobe::add_features_from_query_result() { if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZFH)) { VM_Version::ext_Zfh.enable_feature(); } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZFHMIN)) { + VM_Version::ext_Zfhmin.enable_feature(); + } if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVBC)) { VM_Version::ext_Zvbc.enable_feature(); } diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp index 323cab446274a..b6095c279cbf0 100644 --- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2023, Rivos Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" #include "logging/log.hpp" #include "riscv_hwprobe.hpp" diff --git a/src/hotspot/os_cpu/linux_s390/javaThread_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/javaThread_linux_s390.cpp index 2e930396ce460..5da39b13a144e 100644 --- a/src/hotspot/os_cpu/linux_s390/javaThread_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/javaThread_linux_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index d599359d52903..192bfb6d537c2 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,6 @@ // This file is organized as os_linux_x86.cpp. -// no precompiled headers #include "asm/assembler.inline.hpp" #include "classfile/vmSymbols.hpp" #include "code/nativeInst.hpp" diff --git a/src/hotspot/os_cpu/linux_x86/assembler_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/assembler_linux_x86.cpp index dd20ea833c8d2..2dc6b32998ac5 100644 --- a/src/hotspot/os_cpu/linux_x86/assembler_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/assembler_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/os_cpu/linux_x86/javaThread_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/javaThread_linux_x86.cpp index 145b9a3f0220a..6f0cd49951d6a 100644 --- a/src/hotspot/os_cpu/linux_x86/javaThread_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/javaThread_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index e357747bfea46..3eb91412d8c48 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp index ef85f6fb920f8..6907d2bf72790 100644 --- a/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/vm_version_linux_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/linux_zero/javaThread_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/javaThread_linux_zero.cpp index 4f4f4efad2eb6..0aadd9db18921 100644 --- a/src/hotspot/os_cpu/linux_zero/javaThread_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/javaThread_linux_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp index e8d67bcdddc28..01e207b73c863 100644 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -// no precompiled headers #include "asm/assembler.inline.hpp" #include "atomic_linux_zero.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp index eaf1b85e4be58..48a9d1f835220 100644 --- a/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/vm_version_linux_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp index 965613fd1e5bd..fefcfcb496d0c 100644 --- a/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp @@ -23,4 +23,3 @@ */ // nothing required here -#include "precompiled.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/javaThread_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/javaThread_windows_aarch64.cpp index df434398deb5c..8f6f1ccd38abe 100644 --- a/src/hotspot/os_cpu/windows_aarch64/javaThread_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/javaThread_windows_aarch64.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp index 24410ed920314..df77502b8606d 100644 --- a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, Microsoft Corporation. All rights reserved. - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp index 3813287af0591..de9bf76fdb0ce 100644 --- a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp index c541213615cac..c0dd1ca23aae3 100644 --- a/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/assembler_windows_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" void MacroAssembler::int3() { diff --git a/src/hotspot/os_cpu/windows_x86/javaThread_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/javaThread_windows_x86.cpp index 23819d594a3e2..63edd9d8eda1b 100644 --- a/src/hotspot/os_cpu/windows_x86/javaThread_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/javaThread_windows_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 9a23ac6733521..6414bb9eaf6c9 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "asm/macroAssembler.hpp" #include "classfile/vmSymbols.hpp" #include "code/vtableStubs.hpp" @@ -160,6 +159,43 @@ bool os::win32::register_code_area(char *low, char *high) { return true; } +#if defined(_M_AMD64) +//----------------------------------------------------------------------------- +bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) { + // handle exception caused by native method modifying control word + DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; + + switch (exception_code) { + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: { + PCONTEXT ctx = exceptionInfo->ContextRecord; + // On Windows, the mxcsr control bits are non-volatile across calls + // See also CR 6192333 + // + jint MxCsr = INITIAL_MXCSR; // set to 0x1f80` in winnt.h + if (EnableX86ECoreOpts) { + // On ECore restore with status bits enabled + MxCsr |= 0x3F; + } + + // we can't use StubRoutines::x86::addr_mxcsr_std() + // because in Win64 mxcsr is not saved there + if (MxCsr != ctx->MxCsr) { + ctx->MxCsr = MxCsr; + return true; + } + } + } + + return false; +} +#endif + #ifdef HAVE_PLATFORM_PRINT_NATIVE_STACK /* * Windows/x64 does not use stack frames the way expected by Java: diff --git a/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp index ef85f6fb920f8..6907d2bf72790 100644 --- a/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/vm_version_windows_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/share/adlc/archDesc.cpp b/src/hotspot/share/adlc/archDesc.cpp index f084f506bf587..edb07d2d22c93 100644 --- a/src/hotspot/share/adlc/archDesc.cpp +++ b/src/hotspot/share/adlc/archDesc.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1053,6 +1053,7 @@ const char *ArchDesc::getIdealType(const char *idealOp) { case 'P': return "TypePtr::BOTTOM"; case 'N': return "TypeNarrowOop::BOTTOM"; case 'F': return "Type::FLOAT"; + case 'H': return "Type::HALF_FLOAT"; case 'D': return "Type::DOUBLE"; case 'L': return "TypeLong::LONG"; case 's': return "TypeInt::CC /*flags*/"; @@ -1090,7 +1091,7 @@ void ArchDesc::initBaseOpTypes() { char *ident = (char *)NodeClassNames[j]; if (!strcmp(ident, "ConI") || !strcmp(ident, "ConP") || !strcmp(ident, "ConN") || !strcmp(ident, "ConNKlass") || - !strcmp(ident, "ConF") || !strcmp(ident, "ConD") || + !strcmp(ident, "ConH") || !strcmp(ident, "ConF") || !strcmp(ident, "ConD") || !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) || !strcmp(ident, "Bool")) { constructOperand(ident, true); diff --git a/src/hotspot/share/adlc/forms.cpp b/src/hotspot/share/adlc/forms.cpp index c34a73ea1e13f..e2265f70ed946 100644 --- a/src/hotspot/share/adlc/forms.cpp +++ b/src/hotspot/share/adlc/forms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -220,6 +220,7 @@ Form::DataType Form::ideal_to_const_type(const char *name) const { if (strcmp(name,"ConNKlass")==0) return Form::idealNKlass; if (strcmp(name,"ConL")==0) return Form::idealL; if (strcmp(name,"ConF")==0) return Form::idealF; + if (strcmp(name,"ConH")==0) return Form::idealH; if (strcmp(name,"ConD")==0) return Form::idealD; if (strcmp(name,"Bool")==0) return Form::idealI; diff --git a/src/hotspot/share/adlc/forms.hpp b/src/hotspot/share/adlc/forms.hpp index a82b9bbb3382d..0b673bf854205 100644 --- a/src/hotspot/share/adlc/forms.hpp +++ b/src/hotspot/share/adlc/forms.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -183,7 +183,8 @@ class Form { idealS = 8, // String type idealN = 9, // Narrow oop types idealNKlass = 10, // Narrow klass types - idealV = 11 // Vector type + idealV = 11, // Vector type + idealH = 12 // HalfFloat type }; // Convert ideal name to a DataType, return DataType::none if not a 'ConX' Form::DataType ideal_to_const_type(const char *ideal_type_name) const; diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index dfa414ef56484..f18e9eddba53d 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1088,7 +1088,7 @@ uint InstructForm::reloc(FormDict &globals) { } else if ( oper ) { // floats and doubles loaded out of method's constant pool require reloc info Form::DataType type = oper->is_base_constant(globals); - if ( (type == Form::idealF) || (type == Form::idealD) ) { + if ( (type == Form::idealH) || (type == Form::idealF) || (type == Form::idealD) ) { ++reloc_entries; } } @@ -1099,7 +1099,7 @@ uint InstructForm::reloc(FormDict &globals) { // !!!!! // Check for any component being an immediate float or double. Form::DataType data_type = is_chain_of_constant(globals); - if( data_type==idealD || data_type==idealF ) { + if( data_type==idealH || data_type==idealD || data_type==idealF ) { reloc_entries++; } @@ -2662,6 +2662,7 @@ void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break; case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; + case Form::idealH: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break; case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; default: assert( false, "ShouldNotReachHere()"); @@ -2743,6 +2744,7 @@ void OperandForm::access_constant(FILE *fp, FormDict &globals, case idealP: fprintf(fp,"_c%d->get_con()",const_index); break; case idealL: fprintf(fp,"_c%d", const_index); break; case idealF: fprintf(fp,"_c%d", const_index); break; + case idealH: fprintf(fp,"_c%d", const_index); break; case idealD: fprintf(fp,"_c%d", const_index); break; default: assert( false, "ShouldNotReachHere()"); @@ -3953,11 +3955,12 @@ bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) { // which could be swapped. void MatchNode::count_commutative_op(int& count) { static const char *commut_op_list[] = { - "AddI","AddL","AddF","AddD", + "AddI","AddL","AddHF","AddF","AddD", "AndI","AndL", - "MaxI","MinI","MaxF","MinF","MaxD","MinD", - "MulI","MulL","MulF","MulD", - "OrI","OrL", "XorI","XorL", + "MaxI","MinI","MaxHF","MinHF","MaxF","MinF","MaxD","MinD", + "MulI","MulL","MulHF","MulF","MulD", + "OrI","OrL", + "XorI","XorL" "UMax","UMin" }; @@ -4193,6 +4196,7 @@ int MatchRule::is_expensive() const { if( strcmp(opType,"AtanD")==0 || strcmp(opType,"DivD")==0 || strcmp(opType,"DivF")==0 || + strcmp(opType,"DivHF")==0 || strcmp(opType,"DivI")==0 || strcmp(opType,"Log10D")==0 || strcmp(opType,"ModD")==0 || @@ -4200,6 +4204,7 @@ int MatchRule::is_expensive() const { strcmp(opType,"ModI")==0 || strcmp(opType,"SqrtD")==0 || strcmp(opType,"SqrtF")==0 || + strcmp(opType,"SqrtHF")==0 || strcmp(opType,"TanD")==0 || strcmp(opType,"ConvD2F")==0 || strcmp(opType,"ConvD2I")==0 || @@ -4219,6 +4224,7 @@ int MatchRule::is_expensive() const { strcmp(opType,"DecodeNKlass")==0 || strcmp(opType,"FmaD") == 0 || strcmp(opType,"FmaF") == 0 || + strcmp(opType,"FmaHF") == 0 || strcmp(opType,"RoundDouble")==0 || strcmp(opType,"RoundDoubleMode")==0 || strcmp(opType,"RoundFloat")==0 || diff --git a/src/hotspot/share/adlc/main.cpp b/src/hotspot/share/adlc/main.cpp index f15b6e8813ff1..16fd4ddcf93c6 100644 --- a/src/hotspot/share/adlc/main.cpp +++ b/src/hotspot/share/adlc/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -210,7 +210,6 @@ int main(int argc, char *argv[]) AD.addIncludeGuardStart(AD._HPP_file, "GENERATED_ADFILES_AD_HPP"); // .hpp AD.addIncludeGuardStart(AD._VM_file, "GENERATED_ADFILES_ADGLOBALS_HPP"); // .hpp // Add includes - AD.addInclude(AD._CPP_file, "precompiled.hpp"); AD.addInclude(AD._CPP_file, "adfiles", get_basename(AD._VM_file._name)); AD.addInclude(AD._CPP_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_file, "memory/allocation.inline.hpp"); @@ -245,26 +244,18 @@ int main(int argc, char *argv[]) AD.addInclude(AD._HPP_file, "opto/regalloc.hpp"); AD.addInclude(AD._HPP_file, "opto/subnode.hpp"); AD.addInclude(AD._HPP_file, "opto/vectornode.hpp"); - AD.addInclude(AD._CPP_CLONE_file, "precompiled.hpp"); AD.addInclude(AD._CPP_CLONE_file, "adfiles", get_basename(AD._HPP_file._name)); - AD.addInclude(AD._CPP_EXPAND_file, "precompiled.hpp"); AD.addInclude(AD._CPP_EXPAND_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_EXPAND_file, "oops/compressedOops.hpp"); - AD.addInclude(AD._CPP_FORMAT_file, "precompiled.hpp"); AD.addInclude(AD._CPP_FORMAT_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_FORMAT_file, "compiler/oopMap.hpp"); - AD.addInclude(AD._CPP_GEN_file, "precompiled.hpp"); AD.addInclude(AD._CPP_GEN_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._CPP_GEN_file, "opto/cfgnode.hpp"); AD.addInclude(AD._CPP_GEN_file, "opto/locknode.hpp"); AD.addInclude(AD._CPP_GEN_file, "opto/rootnode.hpp"); - AD.addInclude(AD._CPP_MISC_file, "precompiled.hpp"); AD.addInclude(AD._CPP_MISC_file, "adfiles", get_basename(AD._HPP_file._name)); - AD.addInclude(AD._CPP_PEEPHOLE_file, "precompiled.hpp"); AD.addInclude(AD._CPP_PEEPHOLE_file, "adfiles", get_basename(AD._HPP_file._name)); - AD.addInclude(AD._CPP_PIPELINE_file, "precompiled.hpp"); AD.addInclude(AD._CPP_PIPELINE_file, "adfiles", get_basename(AD._HPP_file._name)); - AD.addInclude(AD._DFA_file, "precompiled.hpp"); AD.addInclude(AD._DFA_file, "adfiles", get_basename(AD._HPP_file._name)); AD.addInclude(AD._DFA_file, "oops/compressedOops.hpp"); AD.addInclude(AD._DFA_file, "opto/cfgnode.hpp"); // Use PROB_MAX in predicate. diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index cc6ed278b4901..0620f2f4496bf 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2421,6 +2421,8 @@ class DefineEmitState { if( _constant_status == LITERAL_NOT_SEEN ) { if ( _constant_type == Form::idealD ) { fprintf(_fp,"->constantD()"); + } else if ( _constant_type == Form::idealH ) { + fprintf(_fp,"->constantH()"); } else if ( _constant_type == Form::idealF ) { fprintf(_fp,"->constantF()"); } else if ( _constant_type == Form::idealL ) { @@ -3789,6 +3791,8 @@ static void path_to_constant(FILE *fp, FormDict &globals, fprintf(fp, "_leaf->bottom_type()->is_narrowoop()"); } else if ( (strcmp(optype,"ConNKlass") == 0) ) { fprintf(fp, "_leaf->bottom_type()->is_narrowklass()"); + } else if ( (strcmp(optype,"ConH") == 0) ) { + fprintf(fp, "_leaf->geth()"); } else if ( (strcmp(optype,"ConF") == 0) ) { fprintf(fp, "_leaf->getf()"); } else if ( (strcmp(optype,"ConD") == 0) ) { diff --git a/src/hotspot/share/adlc/output_h.cpp b/src/hotspot/share/adlc/output_h.cpp index d6767bc1f7efc..a4ab29008f0af 100644 --- a/src/hotspot/share/adlc/output_h.cpp +++ b/src/hotspot/share/adlc/output_h.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,6 +233,10 @@ static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) if (i > 0) fprintf(fp,", "); fprintf(fp," jfloat _c%d;\n", i); } + else if (!strcmp(type, "ConH")) { + if (i > 0) fprintf(fp,", "); + fprintf(fp," jshort _c%d;\n", i); + } else if (!strcmp(type, "ConD")) { if (i > 0) fprintf(fp,", "); fprintf(fp," jdouble _c%d;\n", i); @@ -269,6 +273,10 @@ static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) fprintf(fp," jlong _c%d;\n", i); i++; } + else if (!strcmp(comp->base_type(globals), "ConH")) { + fprintf(fp," jshort _c%d;\n", i); + i++; + } else if (!strcmp(comp->base_type(globals), "ConF")) { fprintf(fp," jfloat _c%d;\n", i); i++; @@ -314,6 +322,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, case Form::idealNKlass : { fprintf(fp,"const TypeNarrowKlass *c%d", i); break; } case Form::idealP : { fprintf(fp,"const TypePtr *c%d", i); break; } case Form::idealL : { fprintf(fp,"jlong c%d", i); break; } + case Form::idealH : { fprintf(fp,"jshort c%d", i); break; } case Form::idealF : { fprintf(fp,"jfloat c%d", i); break; } case Form::idealD : { fprintf(fp,"jdouble c%d", i); break; } default: @@ -403,6 +412,11 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand fprintf(fp," st->print(\"/0x%%08x\", _c%d);\n", i); ++i; } + else if (!strcmp(ideal_type, "ConH")) { + fprintf(fp," st->print(\"#%%d\", _c%d);\n", i); + fprintf(fp," st->print(\"/0x%%08x\", _c%d);\n", i); + ++i; + } else if (!strcmp(ideal_type, "ConP")) { fprintf(fp," _c%d->dump_on(st);\n", i); ++i; @@ -1281,6 +1295,7 @@ void ArchDesc::declareClasses(FILE *fp) { case Form::idealF: type = "Type::FLOAT"; break; case Form::idealD: type = "Type::DOUBLE"; break; case Form::idealL: type = "TypeLong::LONG"; break; + case Form::idealH: type = "Type::HALF_FLOAT"; break; case Form::none: // fall through default: assert( false, "No support for this type of stackSlot"); @@ -1425,6 +1440,14 @@ void ArchDesc::declareClasses(FILE *fp) { fprintf(fp, " return _c0;"); fprintf(fp, " }\n"); } + else if (!strcmp(oper->ideal_type(_globalNames), "ConH")) { + fprintf(fp," virtual intptr_t constant() const {"); + fprintf(fp, " ShouldNotReachHere(); return 0; "); + fprintf(fp, " }\n"); + fprintf(fp," virtual jshort constantH() const {"); + fprintf(fp, " return (jshort)_c0;"); + fprintf(fp, " }\n"); + } else if (!strcmp(oper->ideal_type(_globalNames), "ConF")) { fprintf(fp," virtual intptr_t constant() const {"); fprintf(fp, " ShouldNotReachHere(); return 0; "); @@ -1897,6 +1920,9 @@ void ArchDesc::declareClasses(FILE *fp) { case Form::idealD: fprintf(fp," return TypeD::make(opnd_array(1)->constantD());\n"); break; + case Form::idealH: + fprintf(fp," return TypeH::make(opnd_array(1)->constantH());\n"); + break; case Form::idealF: fprintf(fp," return TypeF::make(opnd_array(1)->constantF());\n"); break; diff --git a/src/hotspot/share/asm/assembler.cpp b/src/hotspot/share/asm/assembler.cpp index 4e19effff61ac..d415ddf004a25 100644 --- a/src/hotspot/share/asm/assembler.cpp +++ b/src/hotspot/share/asm/assembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 4aaf8b6daa248..2aa77abc5f2e7 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "code/compiledIC.hpp" #include "code/oopRecorder.inline.hpp" diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 343981e1a7bc5..025aa641d2c8b 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -607,7 +607,6 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { // Properties const char* name() const { return _name; } - void set_name(const char* name) { _name = name; } CodeBuffer* before_expand() const { return _before_expand; } BufferBlob* blob() const { return _blob; } void set_blob(BufferBlob* blob); diff --git a/src/hotspot/share/asm/register.cpp b/src/hotspot/share/asm/register.cpp index 85da369ca2098..c6ea693e4a9f5 100644 --- a/src/hotspot/share/asm/register.cpp +++ b/src/hotspot/share/asm/register.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/register.hpp" diff --git a/src/hotspot/share/c1/c1_CFGPrinter.cpp b/src/hotspot/share/c1/c1_CFGPrinter.cpp index 5e167f5660c39..d178b69923864 100644 --- a/src/hotspot/share/c1/c1_CFGPrinter.cpp +++ b/src/hotspot/share/c1/c1_CFGPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CFGPrinter.hpp" #include "c1/c1_IR.hpp" #include "c1/c1_InstructionPrinter.hpp" @@ -63,7 +62,7 @@ CFGPrinterOutput::CFGPrinterOutput(Compilation* compilation) _do_print_LIR(false) { char file_name[O_BUFLEN]; - jio_snprintf(file_name, sizeof(file_name), "output_tid" UINTX_FORMAT "_pid%u.cfg", + jio_snprintf(file_name, sizeof(file_name), "output_tid%zu_pid%u.cfg", os::current_thread_id(), os::current_process_id()); _output = new (mtCompiler) fileStream(file_name, "at"); } diff --git a/src/hotspot/share/c1/c1_Canonicalizer.cpp b/src/hotspot/share/c1/c1_Canonicalizer.cpp index 87657038a4ce0..f5a1d14e69431 100644 --- a/src/hotspot/share/c1/c1_Canonicalizer.cpp +++ b/src/hotspot/share/c1/c1_Canonicalizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Canonicalizer.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_ValueStack.hpp" @@ -524,7 +523,7 @@ void Canonicalizer::do_Intrinsic (Intrinsic* x) { ciType* t = c->value()->java_mirror_type(); if (t->is_klass()) { // substitute cls.isInstance(obj) of a constant Class into - // an InstantOf instruction + // an InstanceOf instruction InstanceOf* i = new InstanceOf(t->as_klass(), x->argument_at(1), x->state_before()); set_canonical(i); // and try to canonicalize even further @@ -537,33 +536,6 @@ void Canonicalizer::do_Intrinsic (Intrinsic* x) { } break; } - case vmIntrinsics::_isPrimitive : { - assert(x->number_of_arguments() == 1, "wrong type"); - - // Class.isPrimitive is known on constant classes: - InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant(); - if (c != nullptr && !c->value()->is_null_object()) { - ciType* t = c->value()->java_mirror_type(); - set_constant(t->is_primitive_type()); - } - break; - } - case vmIntrinsics::_getModifiers: { - assert(x->number_of_arguments() == 1, "wrong type"); - - // Optimize for Foo.class.getModifier() - InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant(); - if (c != nullptr && !c->value()->is_null_object()) { - ciType* t = c->value()->java_mirror_type(); - if (t->is_klass()) { - set_constant(t->as_klass()->modifier_flags()); - } else { - assert(t->is_primitive_type(), "should be a primitive type"); - set_constant(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - } - } - break; - } default: break; } diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp index 7e0d439aff4ef..9b80c8a20a852 100644 --- a/src/hotspot/share/c1/c1_Compilation.cpp +++ b/src/hotspot/share/c1/c1_Compilation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CFGPrinter.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_IR.hpp" diff --git a/src/hotspot/share/c1/c1_Compilation.hpp b/src/hotspot/share/c1/c1_Compilation.hpp index 5f554496f932b..dab584ac3b084 100644 --- a/src/hotspot/share/c1/c1_Compilation.hpp +++ b/src/hotspot/share/c1/c1_Compilation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "code/exceptionHandlerTable.hpp" #include "compiler/compiler_globals.hpp" #include "compiler/compilerDefinitions.inline.hpp" +#include "compiler/compilerDirectives.hpp" #include "runtime/deoptimization.hpp" class CompilationFailureInfo; diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index a0944c864e68f..eb7c42e457633 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_Compiler.hpp" #include "c1/c1_FrameMap.hpp" @@ -50,8 +49,8 @@ Compiler::Compiler() : AbstractCompiler(compiler_c1) { void Compiler::init_c1_runtime() { BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); - Runtime1::initialize(buffer_blob); FrameMap::initialize(); + Runtime1::initialize(buffer_blob); // initialize data structures ValueType::initialize(); GraphBuilder::initialize(); @@ -156,8 +155,6 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_longBitsToDouble: case vmIntrinsics::_getClass: case vmIntrinsics::_isInstance: - case vmIntrinsics::_isPrimitive: - case vmIntrinsics::_getModifiers: case vmIntrinsics::_currentCarrierThread: case vmIntrinsics::_currentThread: case vmIntrinsics::_scopedValueCache: diff --git a/src/hotspot/share/c1/c1_FrameMap.cpp b/src/hotspot/share/c1/c1_FrameMap.cpp index a38e55572d4cd..f42a9f7035b67 100644 --- a/src/hotspot/share/c1/c1_FrameMap.cpp +++ b/src/hotspot/share/c1/c1_FrameMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "code/vmreg.inline.hpp" diff --git a/src/hotspot/share/c1/c1_FrameMap.hpp b/src/hotspot/share/c1/c1_FrameMap.hpp index 1fd7dd3edffe3..dab3aa6e734e0 100644 --- a/src/hotspot/share/c1/c1_FrameMap.hpp +++ b/src/hotspot/share/c1/c1_FrameMap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "runtime/frame.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +#include "oops/compressedOops.hpp" class ciMethod; class CallingConvention; diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 9925c592f6f10..e918aa7d19ae7 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CFGPrinter.hpp" #include "c1/c1_Canonicalizer.hpp" #include "c1/c1_Compilation.hpp" diff --git a/src/hotspot/share/c1/c1_IR.cpp b/src/hotspot/share/c1/c1_IR.cpp index b3faa54cc69b8..7f006c0b3ff5d 100644 --- a/src/hotspot/share/c1/c1_IR.cpp +++ b/src/hotspot/share/c1/c1_IR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_GraphBuilder.hpp" diff --git a/src/hotspot/share/c1/c1_IR.hpp b/src/hotspot/share/c1/c1_IR.hpp index 9dfcb8419c3f1..a9a7a02639095 100644 --- a/src/hotspot/share/c1/c1_IR.hpp +++ b/src/hotspot/share/c1/c1_IR.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "c1/c1_Instruction.hpp" #include "ci/ciExceptionHandler.hpp" +#include "ci/ciStreams.hpp" #include "memory/allocation.hpp" // An XHandler is a C1 internal description for an exception handler diff --git a/src/hotspot/share/c1/c1_Instruction.cpp b/src/hotspot/share/c1/c1_Instruction.cpp index 431bcea42cb5b..92affba99b24e 100644 --- a/src/hotspot/share/c1/c1_Instruction.cpp +++ b/src/hotspot/share/c1/c1_Instruction.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_IR.hpp" #include "c1/c1_Instruction.hpp" #include "c1/c1_InstructionPrinter.hpp" diff --git a/src/hotspot/share/c1/c1_InstructionPrinter.cpp b/src/hotspot/share/c1/c1_InstructionPrinter.cpp index 5f865ae518d00..35818188496f8 100644 --- a/src/hotspot/share/c1/c1_InstructionPrinter.cpp +++ b/src/hotspot/share/c1/c1_InstructionPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmSymbols.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_ValueStack.hpp" diff --git a/src/hotspot/share/c1/c1_LIR.cpp b/src/hotspot/share/c1/c1_LIR.cpp index 048eb6047ede9..fc90530ec95d8 100644 --- a/src/hotspot/share/c1/c1_LIR.cpp +++ b/src/hotspot/share/c1/c1_LIR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_LIR.hpp" @@ -452,12 +451,18 @@ void LIR_OpVisitState::visit(LIR_Op* op) { case lir_monaddr: // input and result always valid, info always invalid case lir_null_check: // input and info always valid, result always invalid case lir_move: // input and result always valid, may have info + case lir_sqrt: // FP Ops have no info, but input and result + case lir_abs: + case lir_neg: + case lir_f2hf: + case lir_hf2f: { assert(op->as_Op1() != nullptr, "must be"); LIR_Op1* op1 = (LIR_Op1*)op; if (op1->_info) do_info(op1->_info); if (op1->_opr->is_valid()) do_input(op1->_opr); + if (op1->_tmp->is_valid()) do_temp(op1->_tmp); if (op1->_result->is_valid()) do_output(op1->_result); break; @@ -483,6 +488,7 @@ void LIR_OpVisitState::visit(LIR_Op* op) { assert(op1->_info != nullptr, ""); do_info(op1->_info); if (op1->_opr->is_valid()) do_temp(op1->_opr); // safepoints on SPARC need temporary register + assert(op1->_tmp->is_illegal(), "not used"); assert(op1->_result->is_illegal(), "safepoint does not produce value"); break; @@ -566,11 +572,6 @@ void LIR_OpVisitState::visit(LIR_Op* op) { case lir_add: case lir_sub: case lir_rem: - case lir_sqrt: - case lir_abs: - case lir_neg: - case lir_f2hf: - case lir_hf2f: case lir_logic_and: case lir_logic_or: case lir_logic_xor: @@ -667,6 +668,7 @@ void LIR_OpVisitState::visit(LIR_Op* op) { assert(op1->_info == nullptr, "no info"); assert(op1->_opr->is_valid(), "exception oop"); do_input(op1->_opr); + assert(op1->_tmp->is_illegal(), "not used"); assert(op1->_result->is_illegal(), "no result"); break; @@ -1614,7 +1616,7 @@ void LIR_Address::print_value_on(outputStream* out) const { case times_8: out->print(" * 8"); break; } } - out->print(" Disp: " INTX_FORMAT, _disp); + out->print(" Disp: %zd", _disp); } // debug output of block header without InstructionPrinter @@ -1730,6 +1732,11 @@ const char * LIR_Op::name() const { case lir_cond_float_branch: s = "flt_cond_br"; break; case lir_move: s = "move"; break; case lir_roundfp: s = "roundfp"; break; + case lir_abs: s = "abs"; break; + case lir_neg: s = "neg"; break; + case lir_sqrt: s = "sqrt"; break; + case lir_f2hf: s = "f2hf"; break; + case lir_hf2f: s = "hf2f"; break; case lir_rtcall: s = "rtcall"; break; case lir_throw: s = "throw"; break; case lir_unwind: s = "unwind"; break; @@ -1746,11 +1753,6 @@ const char * LIR_Op::name() const { case lir_mul: s = "mul"; break; case lir_div: s = "div"; break; case lir_rem: s = "rem"; break; - case lir_abs: s = "abs"; break; - case lir_neg: s = "neg"; break; - case lir_sqrt: s = "sqrt"; break; - case lir_f2hf: s = "f2hf"; break; - case lir_hf2f: s = "hf2f"; break; case lir_logic_and: s = "logic_and"; break; case lir_logic_or: s = "logic_or"; break; case lir_logic_xor: s = "logic_xor"; break; diff --git a/src/hotspot/share/c1/c1_LIR.hpp b/src/hotspot/share/c1/c1_LIR.hpp index c568caeca4b30..d9005c49c89d4 100644 --- a/src/hotspot/share/c1/c1_LIR.hpp +++ b/src/hotspot/share/c1/c1_LIR.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -939,6 +939,11 @@ enum LIR_Code { , lir_alloc_object , lir_monaddr , lir_roundfp + , lir_sqrt + , lir_abs + , lir_neg + , lir_f2hf + , lir_hf2f , lir_safepoint , lir_unwind , lir_load_klass @@ -955,13 +960,6 @@ enum LIR_Code { , lir_mul , lir_div , lir_rem - , lir_sqrt - , lir_abs - , lir_neg - , lir_tan - , lir_f2hf - , lir_hf2f - , lir_log10 , lir_logic_and , lir_logic_or , lir_logic_xor @@ -1018,7 +1016,7 @@ enum LIR_Code { , begin_opAssert , lir_assert , end_opAssert -#ifdef INCLUDE_ZGC +#if INCLUDE_ZGC , begin_opXLoadBarrierTest , lir_xloadbarrier_test , end_opXLoadBarrierTest @@ -1357,6 +1355,7 @@ class LIR_Op1: public LIR_Op { protected: LIR_Opr _opr; // input operand + LIR_Opr _tmp; BasicType _type; // Operand types LIR_PatchCode _patch; // only required with patchin (NEEDS_CLEANUP: do we want a special instruction for patching?) @@ -1371,12 +1370,21 @@ class LIR_Op1: public LIR_Op { LIR_Op1(LIR_Code code, LIR_Opr opr, LIR_Opr result = LIR_OprFact::illegalOpr, BasicType type = T_ILLEGAL, LIR_PatchCode patch = lir_patch_none, CodeEmitInfo* info = nullptr) : LIR_Op(code, result, info) , _opr(opr) + , _tmp(LIR_OprFact::illegalOpr) + , _type(type) + , _patch(patch) { assert(is_in_range(code, begin_op1, end_op1), "code check"); } + + LIR_Op1(LIR_Code code, LIR_Opr opr, LIR_Opr result, LIR_Opr tmp, BasicType type = T_ILLEGAL, LIR_PatchCode patch = lir_patch_none, CodeEmitInfo* info = nullptr) + : LIR_Op(code, result, info) + , _opr(opr) + , _tmp(tmp) , _type(type) , _patch(patch) { assert(is_in_range(code, begin_op1, end_op1), "code check"); } LIR_Op1(LIR_Code code, LIR_Opr opr, LIR_Opr result, BasicType type, LIR_PatchCode patch, CodeEmitInfo* info, LIR_MoveKind kind) : LIR_Op(code, result, info) , _opr(opr) + , _tmp(LIR_OprFact::illegalOpr) , _type(type) , _patch(patch) { assert(code == lir_move, "must be"); @@ -1386,10 +1394,12 @@ class LIR_Op1: public LIR_Op { LIR_Op1(LIR_Code code, LIR_Opr opr, CodeEmitInfo* info) : LIR_Op(code, LIR_OprFact::illegalOpr, info) , _opr(opr) + , _tmp(LIR_OprFact::illegalOpr) , _type(T_ILLEGAL) , _patch(lir_patch_none) { assert(is_in_range(code, begin_op1, end_op1), "code check"); } LIR_Opr in_opr() const { return _opr; } + LIR_Opr tmp_opr() const { return _tmp; } LIR_PatchCode patch_code() const { return _patch; } BasicType type() const { return _type; } @@ -1589,8 +1599,6 @@ class LIR_OpTypeCheck: public LIR_Op { class LIR_Op2: public LIR_Op { friend class LIR_OpVisitState; - int _fpu_stack_size; // for sin/cos implementation on Intel - protected: LIR_Opr _opr1; LIR_Opr _opr2; @@ -1607,7 +1615,6 @@ class LIR_Op2: public LIR_Op { public: LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, CodeEmitInfo* info = nullptr, BasicType type = T_ILLEGAL) : LIR_Op(code, LIR_OprFact::illegalOpr, info) - , _fpu_stack_size(0) , _opr1(opr1) , _opr2(opr2) , _tmp1(LIR_OprFact::illegalOpr) @@ -1622,7 +1629,6 @@ class LIR_Op2: public LIR_Op { LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) : LIR_Op(code, result, nullptr) - , _fpu_stack_size(0) , _opr1(opr1) , _opr2(opr2) , _tmp1(LIR_OprFact::illegalOpr) @@ -1639,7 +1645,6 @@ class LIR_Op2: public LIR_Op { LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result = LIR_OprFact::illegalOpr, CodeEmitInfo* info = nullptr, BasicType type = T_ILLEGAL) : LIR_Op(code, result, info) - , _fpu_stack_size(0) , _opr1(opr1) , _opr2(opr2) , _tmp1(LIR_OprFact::illegalOpr) @@ -1655,7 +1660,6 @@ class LIR_Op2: public LIR_Op { LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2 = LIR_OprFact::illegalOpr, LIR_Opr tmp3 = LIR_OprFact::illegalOpr, LIR_Opr tmp4 = LIR_OprFact::illegalOpr, LIR_Opr tmp5 = LIR_OprFact::illegalOpr) : LIR_Op(code, result, nullptr) - , _fpu_stack_size(0) , _opr1(opr1) , _opr2(opr2) , _tmp1(tmp1) @@ -1683,9 +1687,6 @@ class LIR_Op2: public LIR_Op { assert(code() == lir_cmp || code() == lir_branch || code() == lir_cond_float_branch, "only valid for branch"); _condition = condition; } - void set_fpu_stack_size(int size) { _fpu_stack_size = size; } - int fpu_stack_size() const { return _fpu_stack_size; } - void set_in_opr1(LIR_Opr opr) { _opr1 = opr; } void set_in_opr2(LIR_Opr opr) { _opr2 = opr; } @@ -2272,15 +2273,13 @@ class LIR_List: public CompilationResourceObj { void cas_int(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2, LIR_Opr result = LIR_OprFact::illegalOpr); - void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_abs , from, tmp, to)); } - void negate(LIR_Opr from, LIR_Opr to, LIR_Opr tmp = LIR_OprFact::illegalOpr) { append(new LIR_Op2(lir_neg, from, tmp, to)); } - void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_sqrt, from, tmp, to)); } + void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op1(lir_abs , from, to, tmp)); } + void negate(LIR_Opr from, LIR_Opr to, LIR_Opr tmp = LIR_OprFact::illegalOpr) { append(new LIR_Op1(lir_neg, from, to, tmp)); } + void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op1(lir_sqrt, from, to, tmp)); } void fmad(LIR_Opr from, LIR_Opr from1, LIR_Opr from2, LIR_Opr to) { append(new LIR_Op3(lir_fmad, from, from1, from2, to)); } void fmaf(LIR_Opr from, LIR_Opr from1, LIR_Opr from2, LIR_Opr to) { append(new LIR_Op3(lir_fmaf, from, from1, from2, to)); } - void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); } - void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); } - void f2hf(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_f2hf, from, tmp, to)); } - void hf2f(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_hf2f, from, tmp, to)); } + void f2hf(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op1(lir_f2hf, from, to, tmp)); } + void hf2f(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op1(lir_hf2f, from, to, tmp)); } void add (LIR_Opr left, LIR_Opr right, LIR_Opr res) { append(new LIR_Op2(lir_add, left, right, res)); } void sub (LIR_Opr left, LIR_Opr right, LIR_Opr res, CodeEmitInfo* info = nullptr) { append(new LIR_Op2(lir_sub, left, right, res, info)); } diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 0fa4b3a4c93d7..a5930ba54d880 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_Instruction.hpp" @@ -526,6 +525,17 @@ void LIR_Assembler::emit_op1(LIR_Op1* op) { break; } + case lir_abs: + case lir_sqrt: + case lir_f2hf: + case lir_hf2f: + intrinsic_op(op->code(), op->in_opr(), op->tmp_opr(), op->result_opr(), op); + break; + + case lir_neg: + negate(op->in_opr(), op->result_opr(), op->tmp_opr()); + break; + case lir_return: { assert(op->as_OpReturn() != nullptr, "sanity"); LIR_OpReturn *ret_op = (LIR_OpReturn*)op; @@ -723,19 +733,6 @@ void LIR_Assembler::emit_op2(LIR_Op2* op) { op->fpu_pop_count() == 1); break; - case lir_abs: - case lir_sqrt: - case lir_tan: - case lir_log10: - case lir_f2hf: - case lir_hf2f: - intrinsic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op); - break; - - case lir_neg: - negate(op->in_opr1(), op->result_opr(), op->in_opr2()); - break; - case lir_logic_and: case lir_logic_or: case lir_logic_xor: diff --git a/src/hotspot/share/c1/c1_LIRAssembler.hpp b/src/hotspot/share/c1/c1_LIRAssembler.hpp index eb89e3ea24870..34aa679daedd0 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.hpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -208,7 +208,7 @@ class LIR_Assembler: public CompilationResourceObj { void arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack); void arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info); - void intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op); + void intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr temp, LIR_Opr dest, LIR_Op* op); #ifdef ASSERT void emit_assert(LIR_OpAssert* op); #endif diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 74fdf7a5b76a3..959e49749c5e5 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Compilation.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_FrameMap.hpp" @@ -1232,13 +1231,6 @@ void LIRGenerator::do_Reference_get(Intrinsic* x) { void LIRGenerator::do_isInstance(Intrinsic* x) { assert(x->number_of_arguments() == 2, "wrong type"); - // TODO could try to substitute this node with an equivalent InstanceOf - // if clazz is known to be a constant Class. This will pick up newly found - // constants after HIR construction. I'll leave this to a future change. - - // as a first cut, make a simple leaf call to runtime to stay platform independent. - // could follow the aastore example in a future change. - LIRItem clazz(x->argument_at(0), this); LIRItem object(x->argument_at(1), this); clazz.load_item(); @@ -1251,8 +1243,9 @@ void LIRGenerator::do_isInstance(Intrinsic* x) { __ null_check(clazz.result(), info); } + address pd_instanceof_fn = isInstance_entry(); LIR_Opr call_result = call_runtime(clazz.value(), object.value(), - CAST_FROM_FN_PTR(address, Runtime1::is_instance_of), + pd_instanceof_fn, x->type(), nullptr); // null CodeEmitInfo results in a leaf call __ move(call_result, result); @@ -1285,61 +1278,6 @@ void LIRGenerator::do_getClass(Intrinsic* x) { LIR_OprFact::address(new LIR_Address(temp, T_OBJECT)), result); } -// java.lang.Class::isPrimitive() -void LIRGenerator::do_isPrimitive(Intrinsic* x) { - assert(x->number_of_arguments() == 1, "wrong type"); - - LIRItem rcvr(x->argument_at(0), this); - rcvr.load_item(); - LIR_Opr temp = new_register(T_METADATA); - LIR_Opr result = rlock_result(x); - - CodeEmitInfo* info = nullptr; - if (x->needs_null_check()) { - info = state_for(x); - } - - __ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset(), T_ADDRESS), temp, info); - __ cmp(lir_cond_notEqual, temp, LIR_OprFact::metadataConst(nullptr)); - __ cmove(lir_cond_notEqual, LIR_OprFact::intConst(0), LIR_OprFact::intConst(1), result, T_BOOLEAN); -} - -// Example: Foo.class.getModifiers() -void LIRGenerator::do_getModifiers(Intrinsic* x) { - assert(x->number_of_arguments() == 1, "wrong type"); - - LIRItem receiver(x->argument_at(0), this); - receiver.load_item(); - LIR_Opr result = rlock_result(x); - - CodeEmitInfo* info = nullptr; - if (x->needs_null_check()) { - info = state_for(x); - } - - // While reading off the universal constant mirror is less efficient than doing - // another branch and returning the constant answer, this branchless code runs into - // much less risk of confusion for C1 register allocator. The choice of the universe - // object here is correct as long as it returns the same modifiers we would expect - // from the primitive class itself. See spec for Class.getModifiers that provides - // the typed array klasses with similar modifiers as their component types. - - Klass* univ_klass = Universe::byteArrayKlass(); - assert(univ_klass->modifier_flags() == (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC), "Sanity"); - LIR_Opr prim_klass = LIR_OprFact::metadataConst(univ_klass); - - LIR_Opr recv_klass = new_register(T_METADATA); - __ move(new LIR_Address(receiver.result(), java_lang_Class::klass_offset(), T_ADDRESS), recv_klass, info); - - // Check if this is a Java mirror of primitive type, and select the appropriate klass. - LIR_Opr klass = new_register(T_METADATA); - __ cmp(lir_cond_equal, recv_klass, LIR_OprFact::metadataConst(nullptr)); - __ cmove(lir_cond_equal, prim_klass, recv_klass, klass, T_ADDRESS); - - // Get the answer. - __ move(new LIR_Address(klass, in_bytes(Klass::modifier_flags_offset()), T_INT), result); -} - void LIRGenerator::do_getObjectSize(Intrinsic* x) { assert(x->number_of_arguments() == 3, "wrong type"); LIR_Opr result_reg = rlock_result(x); @@ -2957,8 +2895,6 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break; case vmIntrinsics::_isInstance: do_isInstance(x); break; - case vmIntrinsics::_isPrimitive: do_isPrimitive(x); break; - case vmIntrinsics::_getModifiers: do_getModifiers(x); break; case vmIntrinsics::_getClass: do_getClass(x); break; case vmIntrinsics::_getObjectSize: do_getObjectSize(x); break; case vmIntrinsics::_currentCarrierThread: do_currentCarrierThread(x); break; diff --git a/src/hotspot/share/c1/c1_LIRGenerator.hpp b/src/hotspot/share/c1/c1_LIRGenerator.hpp index a66758054d7d4..73bd883a7468e 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.hpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -254,8 +254,6 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_RegisterFinalizer(Intrinsic* x); void do_isInstance(Intrinsic* x); - void do_isPrimitive(Intrinsic* x); - void do_getModifiers(Intrinsic* x); void do_getClass(Intrinsic* x); void do_getObjectSize(Intrinsic* x); void do_currentCarrierThread(Intrinsic* x); @@ -536,6 +534,9 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { LIR_Opr syncTempOpr(); LIR_Opr atomicLockOpr(); + // Intrinsic for Class::isInstance + address isInstance_entry(); + // returns a register suitable for saving the thread in a // call_runtime_leaf if one is needed. LIR_Opr getThreadTemp(); diff --git a/src/hotspot/share/c1/c1_LinearScan.cpp b/src/hotspot/share/c1/c1_LinearScan.cpp index a4d955e52a004..c099bb47d9726 100644 --- a/src/hotspot/share/c1/c1_LinearScan.cpp +++ b/src/hotspot/share/c1/c1_LinearScan.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_CFGPrinter.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_Compilation.hpp" @@ -6739,7 +6738,6 @@ void LinearScanStatistic::collect(LinearScan* allocator) { case lir_abs: case lir_f2hf: case lir_hf2f: - case lir_log10: case lir_logic_and: case lir_logic_or: case lir_logic_xor: diff --git a/src/hotspot/share/c1/c1_Optimizer.cpp b/src/hotspot/share/c1/c1_Optimizer.cpp index d33e4d28bd0dd..f8339b0004993 100644 --- a/src/hotspot/share/c1/c1_Optimizer.cpp +++ b/src/hotspot/share/c1/c1_Optimizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Optimizer.hpp" #include "c1/c1_ValueSet.hpp" #include "c1/c1_ValueStack.hpp" diff --git a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp index a4c2976d26f13..6320fc15efefe 100644 --- a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp +++ b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_ValueStack.hpp" #include "c1/c1_RangeCheckElimination.hpp" #include "c1/c1_IR.hpp" diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 4ef2f8f3b0a80..3a30c9846aab7 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "c1/c1_CodeStubs.hpp" #include "c1/c1_Defs.hpp" @@ -247,6 +246,7 @@ void Runtime1::generate_blob_for(BufferBlob* buffer_blob, C1StubId id) { case C1StubId::fpu2long_stub_id: case C1StubId::unwind_exception_id: case C1StubId::counter_overflow_id: + case C1StubId::is_instance_of_id: expect_oop_map = false; break; default: diff --git a/src/hotspot/share/c1/c1_ValueMap.cpp b/src/hotspot/share/c1/c1_ValueMap.cpp index d9e1e11a3b876..2d7634f6308a5 100644 --- a/src/hotspot/share/c1/c1_ValueMap.cpp +++ b/src/hotspot/share/c1/c1_ValueMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_IR.hpp" #include "c1/c1_ValueMap.hpp" #include "c1/c1_ValueSet.hpp" diff --git a/src/hotspot/share/c1/c1_ValueStack.cpp b/src/hotspot/share/c1/c1_ValueStack.cpp index 41424e36d0784..f1ac940bf162c 100644 --- a/src/hotspot/share/c1/c1_ValueStack.cpp +++ b/src/hotspot/share/c1/c1_ValueStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_IR.hpp" #include "c1/c1_InstructionPrinter.hpp" #include "c1/c1_ValueStack.hpp" diff --git a/src/hotspot/share/c1/c1_ValueType.cpp b/src/hotspot/share/c1/c1_ValueType.cpp index d35d8adadfa99..7bfb884e8c804 100644 --- a/src/hotspot/share/c1/c1_ValueType.cpp +++ b/src/hotspot/share/c1/c1_ValueType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_ValueType.hpp" #include "ci/ciArray.hpp" #include "ci/ciInstance.hpp" diff --git a/src/hotspot/share/cds/aotArtifactFinder.cpp b/src/hotspot/share/cds/aotArtifactFinder.cpp new file mode 100644 index 0000000000000..48f31635c63b9 --- /dev/null +++ b/src/hotspot/share/cds/aotArtifactFinder.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "cds/aotClassLinker.hpp" +#include "cds/aotArtifactFinder.hpp" +#include "cds/aotClassInitializer.hpp" +#include "cds/dumpTimeClassInfo.inline.hpp" +#include "cds/heapShared.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "logging/log.hpp" +#include "memory/metaspaceClosure.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/objArrayKlass.hpp" +#include "utilities/resourceHash.hpp" + +// All the classes that should be included in the AOT cache (in at least the "allocated" state) +static GrowableArrayCHeap* _all_cached_classes = nullptr; + +// This is a stack that tracks all the AOT-inited classes that are waiting to be passed +// to HeapShared::copy_and_rescan_aot_inited_mirror(). +static GrowableArrayCHeap* _pending_aot_inited_classes = nullptr; + +static const int TABLE_SIZE = 15889; // prime number +using ClassesTable = ResourceHashtable; +static ClassesTable* _seen_classes; // all classes that have been seen by AOTArtifactFinder +static ClassesTable* _aot_inited_classes; // all classes that need to be AOT-initialized. + +void AOTArtifactFinder::initialize() { + _all_cached_classes = new GrowableArrayCHeap(); + _pending_aot_inited_classes = new GrowableArrayCHeap(); + _seen_classes = new (mtClass)ClassesTable(); + _aot_inited_classes = new (mtClass)ClassesTable(); +} + +void AOTArtifactFinder::dispose() { + delete _all_cached_classes; + delete _seen_classes; + delete _aot_inited_classes; + delete _pending_aot_inited_classes; + _all_cached_classes = nullptr; + _seen_classes = nullptr; + _aot_inited_classes = nullptr; + _pending_aot_inited_classes = nullptr; +} + +// Find all Klasses and oops that should be included in the AOT cache. See aotArtifactFinder.hpp +void AOTArtifactFinder::find_artifacts() { + // Some classes might have been marked as excluded as a side effect of running + // AOTConstantPoolResolver. Make sure we check all the remaining ones. + // + // Note, if a class is not excluded, it does NOT mean it will be automatically included + // into the AOT cache -- that will be decided by the code below. + SystemDictionaryShared::finish_exclusion_checks(); + + start_scanning_for_oops(); + + // Add the primitive array classes + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + BasicType bt = (BasicType)i; + if (is_java_primitive(bt)) { + add_cached_type_array_class(Universe::typeArrayKlass(bt)); + } + } + +#if INCLUDE_CDS_JAVA_HEAP + // Add the mirrors that aren't associated with a Klass + // - primitive mirrors (E.g., "int.class" in Java code) + // - mirror of fillerArrayKlass + if (CDSConfig::is_dumping_heap()) { + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + BasicType bt = (BasicType)i; + if (!is_reference_type(bt)) { + oop orig_mirror = Universe::java_mirror(bt); + oop scratch_mirror = HeapShared::scratch_java_mirror(bt); + HeapShared::scan_java_mirror(orig_mirror); + log_trace(cds, heap, mirror)( + "Archived %s mirror object from " PTR_FORMAT, + type2name(bt), p2i(scratch_mirror)); + Universe::set_archived_basic_type_mirror_index(bt, HeapShared::append_root(scratch_mirror)); + } + } + + // Universe::fillerArrayKlass() isn't in the class hierarchy, so handle it specially. + HeapShared::scan_java_mirror(Universe::fillerArrayKlass()->java_mirror()); + } +#endif + + // Add all the InstanceKlasses (and their array classes) that are always included. + SystemDictionaryShared::dumptime_table()->iterate_all_live_classes([&] (InstanceKlass* ik, DumpTimeClassInfo& info) { + if (!info.is_excluded()) { + bool add = false; + if (!ik->is_hidden()) { + // All non-hidden classes are always included into the AOT cache + add = true; + } else { + if (!CDSConfig::is_dumping_invokedynamic()) { + // Legacy support of lambda proxies -- these are always included into the AOT cache + if (SystemDictionaryShared::is_registered_lambda_proxy_class(ik)) { + add = true; + } + } else { + assert(!SystemDictionaryShared::is_registered_lambda_proxy_class(ik), + "registered lambda proxies are only for legacy lambda proxy support"); + } + } + + if (add) { + add_cached_instance_class(ik); + if (AOTClassInitializer::can_archive_initialized_mirror(ik)) { + add_aot_inited_class(ik); + } + } + } + }); + +#if INCLUDE_CDS_JAVA_HEAP + // Keep scanning until we discover no more class that need to be AOT-initialized. + if (CDSConfig::is_initing_classes_at_dump_time()) { + while (_pending_aot_inited_classes->length() > 0) { + InstanceKlass* ik = _pending_aot_inited_classes->pop(); + HeapShared::copy_and_rescan_aot_inited_mirror(ik); + } + } +#endif + + // Exclude all the (hidden) classes that have not been discovered by the code above. + SystemDictionaryShared::dumptime_table()->iterate_all_live_classes([&] (InstanceKlass* k, DumpTimeClassInfo& info) { + if (!info.is_excluded() && _seen_classes->get(k) == nullptr) { + info.set_excluded(); + assert(k->is_hidden(), "must be"); + if (log_is_enabled(Info, cds)) { + ResourceMark rm; + log_info(cds)("Skipping %s: Hidden class", k->name()->as_C_string()); + } + } + }); + + end_scanning_for_oops(); +} + +void AOTArtifactFinder::start_scanning_for_oops() { +#if INCLUDE_CDS_JAVA_HEAP + if (CDSConfig::is_dumping_heap()) { + HeapShared::start_scanning_for_oops(); + } +#endif +} + +void AOTArtifactFinder::end_scanning_for_oops() { +#if INCLUDE_CDS_JAVA_HEAP + if (CDSConfig::is_dumping_heap()) { + HeapShared::end_scanning_for_oops(); + } +#endif +} + +void AOTArtifactFinder::add_aot_inited_class(InstanceKlass* ik) { + if (CDSConfig::is_initing_classes_at_dump_time()) { + assert(ik->is_initialized(), "must be"); + add_cached_instance_class(ik); + + bool created; + _aot_inited_classes->put_if_absent(ik, &created); + if (created) { + _pending_aot_inited_classes->push(ik); + + InstanceKlass* s = ik->java_super(); + if (s != nullptr) { + add_aot_inited_class(s); + } + + Array* interfaces = ik->local_interfaces(); + int len = interfaces->length(); + for (int i = 0; i < len; i++) { + InstanceKlass* intf = interfaces->at(i); + if (intf->is_initialized()) { + add_aot_inited_class(intf); + } + } + } + } +} + +void AOTArtifactFinder::add_cached_instance_class(InstanceKlass* ik) { + bool created; + _seen_classes->put_if_absent(ik, &created); + if (created) { + _all_cached_classes->append(ik); + scan_oops_in_instance_class(ik); + if (ik->is_hidden() && CDSConfig::is_initing_classes_at_dump_time()) { + bool succeed = AOTClassLinker::try_add_candidate(ik); + guarantee(succeed, "All cached hidden classes must be aot-linkable"); + add_aot_inited_class(ik); + } + } +} + +void AOTArtifactFinder::add_cached_type_array_class(TypeArrayKlass* tak) { + bool created; + _seen_classes->put_if_absent(tak, &created); + if (created) { + _all_cached_classes->append(tak); + scan_oops_in_array_class(tak); + } +} + +void AOTArtifactFinder::add_cached_class(Klass* k) { + if (k->is_typeArray_klass()) { + add_cached_type_array_class(TypeArrayKlass::cast(k)); + } else if (k->is_objArray_klass()) { + add_cached_class(ObjArrayKlass::cast(k)->element_klass()); + } else { + add_cached_instance_class(InstanceKlass::cast(k)); + } +} + +void AOTArtifactFinder::scan_oops_in_instance_class(InstanceKlass* ik) { +#if INCLUDE_CDS_JAVA_HEAP + if (CDSConfig::is_dumping_heap()) { + HeapShared::scan_java_class(ik); + scan_oops_in_array_class(ik->array_klasses()); + } +#endif +} + +void AOTArtifactFinder::scan_oops_in_array_class(ArrayKlass* ak) { +#if INCLUDE_CDS_JAVA_HEAP + if (CDSConfig::is_dumping_heap()) { + while (ak != nullptr) { + HeapShared::scan_java_class(ak); + ak = ak->array_klass_or_null(); + } + } +#endif +} + +void AOTArtifactFinder::all_cached_classes_do(MetaspaceClosure* it) { + for (int i = 0; i < _all_cached_classes->length(); i++) { + it->push(_all_cached_classes->adr_at(i)); + } +} diff --git a/src/hotspot/share/cds/aotArtifactFinder.hpp b/src/hotspot/share/cds/aotArtifactFinder.hpp new file mode 100644 index 0000000000000..d890d874af9ef --- /dev/null +++ b/src/hotspot/share/cds/aotArtifactFinder.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTARTIFACTFINDER_HPP +#define SHARE_CDS_AOTARTIFACTFINDER_HPP + +#include "memory/allStatic.hpp" +#include "utilities/exceptions.hpp" + +class ArrayKlass; +class InstanceKlass; +class MetaspaceClosure; +class TypeArrayKlass; + +// AOTArtifactFinder finds (the roots of) all artifacts that should be included in the AOT cache. These include: +// [1] C++ Klasses +// [2] Java heap objects +// It also decides what Klasses must be cached in aot-initialized state. +// +// ArchiveBuilder uses [1] as roots to scan for all MetaspaceObjs that need to be cached. +// ArchiveHeapWriter uses [2] to create an image of the archived heap. +// +// [1] is stored in _all_cached_classes in aotArtifactFinder.cpp. +// [2] is stored in HeapShared::archived_object_cache(). +// +// Although many Klasses and heap objects are created in the assembly phase, we only store a subset of them into +// the AOT cache. For example: +// - Klasses that fail verification are excluded +// - Many Klasses are stored in non-initialized state, so any initialized static fields in their +// java mirrors must be cleared. +// - To conserve space, we exclude any hidden classes that are not referenced. +// +// The discovery of [1] and [2] is interdependent, and is done inside AOTArtifactFinder::find() +// - We first add a set of roots that must be included in the AOT cache +// - mirrors of primitive classes (e.g., int.class in Java source code). +// - primitive array classes +// - non hidden classes +// - registered lambda proxy classes +// - Whenever a class is added, we scan its constant pool. This will discover references +// to hidden classes. All such hidden classes are added. +// - As heap objects (**Note2) and classes are discovered, we find out what classes must +// be AOT-initialized: +// - If we discover at least one instance of class X, then class X is AOT-initialized (** Note1). +// - If AOTClassInitializer::can_archive_initialized_mirror(X) is true, then X is AOT-initialized. +// - For each AOT-initialized class, we scan all the static fields in its java mirror. This will in +// turn discover more Klasses and java heap objects. +// - The scanning continues until we reach a steady state. +// +// Note1: See TODO comments in HeapShared::archive_object() for exceptions to this rule. +// +// Note2: The scanning of Java objects is done in heapShared.cpp. Please see calls into the HeapShared class +// from AOTArtifactFinder. + +class AOTArtifactFinder : AllStatic { + static void start_scanning_for_oops(); + static void end_scanning_for_oops(); + static void scan_oops_in_instance_class(InstanceKlass* ik); + static void scan_oops_in_array_class(ArrayKlass* ak); + static void add_cached_type_array_class(TypeArrayKlass* tak); + static void add_cached_instance_class(InstanceKlass* ik); +public: + static void initialize(); + static void find_artifacts(); + static void add_cached_class(Klass* k); + static void add_aot_inited_class(InstanceKlass* ik); + static void all_cached_classes_do(MetaspaceClosure* it); + static void dispose(); +}; + +#endif // SHARE_CDS_AOTARTIFACTFINDER_HPP diff --git a/src/hotspot/share/cds/aotClassInitializer.cpp b/src/hotspot/share/cds/aotClassInitializer.cpp index b09dfcde6b105..5b022cae24465 100644 --- a/src/hotspot/share/cds/aotClassInitializer.cpp +++ b/src/hotspot/share/cds/aotClassInitializer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassInitializer.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" @@ -103,25 +102,17 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { return false; } - if (ik->is_hidden()) { - return HeapShared::is_archivable_hidden_klass(ik); - } - - if (ik->is_enum_subclass()) { - return true; - } - // About "static field that may hold a different value" errors: // // Automatic selection for aot-inited classes // ========================================== // // When CDSConfig::is_initing_classes_at_dump_time() is enabled, - // HeapShared::find_all_aot_initialized_classes() finds the classes of all + // AOTArtifactFinder::find_artifacts() finds the classes of all // heap objects that are reachable from HeapShared::_run_time_special_subgraph, // and mark these classes as aot-inited. This preserves the initialized // mirrors of these classes, and their methods are NOT executed - // at runtime. + // at runtime. See aotArtifactFinder.hpp for more info. // // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle @@ -268,9 +259,7 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { // everybody's favorite super {"java/lang/Object"}, - // above we selected all enums; we must include their super as well - {"java/lang/Enum"}, - {nullptr} + {nullptr} }; if (is_allowed(specs, ik)) { return true; @@ -356,4 +345,3 @@ void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* } } } - diff --git a/src/hotspot/share/cds/aotClassLinker.cpp b/src/hotspot/share/cds/aotClassLinker.cpp index 8525ce928a817..a1cacd735dd68 100644 --- a/src/hotspot/share/cds/aotClassLinker.cpp +++ b/src/hotspot/share/cds/aotClassLinker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassLinker.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/aotLinkedClassTable.hpp" @@ -146,9 +145,6 @@ bool AOTClassLinker::try_add_candidate(InstanceKlass* ik) { if (!CDSConfig::is_dumping_invokedynamic()) { return false; } - if (!SystemDictionaryShared::should_hidden_class_be_archived(ik)) { - return false; - } if (HeapShared::is_lambda_proxy_klass(ik)) { InstanceKlass* nest_host = ik->nest_host_not_null(); if (!try_add_candidate(nest_host)) { @@ -316,4 +312,3 @@ const char* AOTClassLinker::class_category_name(AOTLinkedClassCategory category) return "unreg"; } } - diff --git a/src/hotspot/share/cds/aotClassLocation.cpp b/src/hotspot/share/cds/aotClassLocation.cpp new file mode 100644 index 0000000000000..8d453fe17738d --- /dev/null +++ b/src/hotspot/share/cds/aotClassLocation.cpp @@ -0,0 +1,999 @@ +/* + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "cds/aotClassLocation.hpp" +#include "cds/archiveBuilder.hpp" +#include "cds/cdsConfig.hpp" +#include "cds/dynamicArchive.hpp" +#include "cds/filemap.hpp" +#include "cds/metaspaceShared.hpp" +#include "cds/serializeClosure.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/classLoaderData.hpp" +#include "classfile/javaClasses.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" +#include "memory/metadataFactory.hpp" +#include "memory/metaspaceClosure.hpp" +#include "memory/resourceArea.hpp" +#include "oops/array.hpp" +#include "oops/objArrayKlass.hpp" +#include "runtime/arguments.hpp" +#include "utilities/classpathStream.hpp" +#include "utilities/formatBuffer.hpp" +#include "utilities/stringUtils.hpp" + +#include +#include + +AOTClassLocationConfig* AOTClassLocationConfig::_dumptime_instance = nullptr; +const AOTClassLocationConfig* AOTClassLocationConfig::_runtime_instance = nullptr; + +// A ClassLocationStream represents a list of code locations, which can be iterated using +// start() and has_next(). +class ClassLocationStream { +protected: + GrowableArray _array; + int _current; + + // Add one path to this stream. + void add_one_path(const char* path) { + _array.append(path); + } + + // Add all paths specified in cp; cp must be from -classpath or -Xbootclasspath/a. + void add_paths_in_classpath(const char* cp) { + ClasspathStream cp_stream(cp); + while (cp_stream.has_next()) { + add_one_path(cp_stream.get_next()); + } + } + +public: + ClassLocationStream() : _array(), _current(0) {} + + void print(outputStream* st) const { + const char* sep = ""; + for (int i = 0; i < _array.length(); i++) { + st->print("%s%s", sep, _array.at(i)); + sep = os::path_separator(); + } + } + + void add(ClassLocationStream& css) { + for (css.start(); css.has_next();) { + add_one_path(css.get_next()); + } + } + + // Iteration + void start() { _current = 0; } + bool has_next() const { return _current < _array.length(); } + const char* get_next() { + return _array.at(_current++); + } + + int current() const { return _current; } + bool is_empty() const { return _array.length() == 0; } +}; + +class BootCpClassLocationStream : public ClassLocationStream { +public: + BootCpClassLocationStream() : ClassLocationStream() { + // Arguments::get_boot_class_path() contains $JAVA_HOME/lib/modules, but we treat that separately + for (const char* bootcp = Arguments::get_boot_class_path(); *bootcp != '\0'; ++bootcp) { + if (*bootcp == *os::path_separator()) { + ++bootcp; + add_paths_in_classpath(bootcp); + break; + } + } + } +}; + +class AppCpClassLocationStream : public ClassLocationStream { +public: + AppCpClassLocationStream() : ClassLocationStream() { + const char* appcp = Arguments::get_appclasspath(); + if (strcmp(appcp, ".") == 0) { + appcp = ""; + } + add_paths_in_classpath(appcp); + } +}; + +class ModulePathClassLocationStream : public ClassLocationStream { + bool _has_non_jar_modules; +public: + ModulePathClassLocationStream(); + bool has_non_jar_modules() { return _has_non_jar_modules; } +}; + +// AllClassLocationStreams is used to iterate over all the code locations that +// are available to the application from -Xbootclasspath, -classpath and --module-path. +// When creating an AOT cache, we store the contents from AllClassLocationStreams +// into an array of AOTClassLocations. See AOTClassLocationConfig::dumptime_init_helper(). +// When loading the AOT cache in a production run, we compare the contents of the +// stored AOTClassLocations against the current AllClassLocationStreams to determine whether +// the AOT cache is compatible with the current JVM. See AOTClassLocationConfig::validate(). +class AllClassLocationStreams { + BootCpClassLocationStream _boot_cp; // Specified by -Xbootclasspath/a + AppCpClassLocationStream _app_cp; // Specified by -classpath + ModulePathClassLocationStream _module_path; // Specified by --module-path + ClassLocationStream _boot_and_app_cp; // Convenience for iterating over both _boot and _app +public: + BootCpClassLocationStream& boot_cp() { return _boot_cp; } + AppCpClassLocationStream& app_cp() { return _app_cp; } + ModulePathClassLocationStream& module_path() { return _module_path; } + ClassLocationStream& boot_and_app_cp() { return _boot_and_app_cp; } + + AllClassLocationStreams() : _boot_cp(), _app_cp(), _module_path(), _boot_and_app_cp() { + _boot_and_app_cp.add(_boot_cp); + _boot_and_app_cp.add(_app_cp); + } +}; + +static bool has_jar_suffix(const char* filename) { + // In jdk.internal.module.ModulePath.readModule(), it checks for the ".jar" suffix. + // Performing the same check here. + const char* dot = strrchr(filename, '.'); + if (dot != nullptr && strcmp(dot + 1, "jar") == 0) { + return true; + } + return false; +} + +static int compare_module_path_by_name(const char** p1, const char** p2) { + return strcmp(*p1, *p2); +} + +ModulePathClassLocationStream::ModulePathClassLocationStream() : ClassLocationStream(), _has_non_jar_modules(false) { + // Note: for handling of --module-path, see + // https://openjdk.org/jeps/261#Module-paths + // https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/lang/module/ModuleFinder.html#of(java.nio.file.Path...) + + const char* jdk_module_path = Arguments::get_property("jdk.module.path"); + if (jdk_module_path == nullptr) { + return; + } + + ClasspathStream cp_stream(jdk_module_path); + while (cp_stream.has_next()) { + const char* path = cp_stream.get_next(); + DIR* dirp = os::opendir(path); + if (dirp == nullptr && errno == ENOTDIR && has_jar_suffix(path)) { + add_one_path(path); + } else if (dirp != nullptr) { + struct dirent* dentry; + bool found_jar = false; + while ((dentry = os::readdir(dirp)) != nullptr) { + const char* file_name = dentry->d_name; + if (has_jar_suffix(file_name)) { + size_t full_name_len = strlen(path) + strlen(file_name) + strlen(os::file_separator()) + 1; + char* full_name = NEW_RESOURCE_ARRAY(char, full_name_len); + int n = os::snprintf(full_name, full_name_len, "%s%s%s", path, os::file_separator(), file_name); + assert((size_t)n == full_name_len - 1, "Unexpected number of characters in string"); + add_one_path(full_name); + found_jar = true; + } else if (strcmp(file_name, ".") != 0 && strcmp(file_name, "..") != 0) { + // Found some non jar entries + _has_non_jar_modules = true; + log_info(class, path)("Found non-jar path: '%s%s%s'", path, os::file_separator(), file_name); + } + } + if (!found_jar) { + log_info(class, path)("Found exploded module path: '%s'", path); + _has_non_jar_modules = true; + } + os::closedir(dirp); + } else { + _has_non_jar_modules = true; + } + } + + _array.sort(compare_module_path_by_name); +} + +AOTClassLocation* AOTClassLocation::allocate(JavaThread* current, const char* path, int index, + Group group, bool from_cpattr, bool is_jrt) { + size_t path_length = 0; + size_t manifest_length = 0; + bool check_time = false; + time_t timestamp = 0; + int64_t filesize = 0; + FileType type = FileType::NORMAL; + // Do not record the actual path of the jrt, as the entire JDK can be moved to a different + // directory. + const char* recorded_path = is_jrt ? "" : path; + path_length = strlen(recorded_path); + + struct stat st; + if (os::stat(path, &st) == 0) { + if ((st.st_mode & S_IFMT) == S_IFDIR) { + type = FileType::DIR; + } else { + timestamp = st.st_mtime; + filesize = st.st_size; + + // The timestamp of $JAVA_HOME/lib/modules is not checked at runtime. + check_time = !is_jrt; + } +#ifdef _WINDOWS + } else if (errno == ERROR_FILE_NOT_FOUND || errno == ERROR_PATH_NOT_FOUND) { + // On Windows, the errno could be ERROR_PATH_NOT_FOUND (3) in case the directory + // path doesn't exist. + type = FileType::NOT_EXIST; +#endif + } else if (errno == ENOENT) { + // We allow the file to not exist, as long as it also doesn't exist during runtime. + type = FileType::NOT_EXIST; + } else { + log_error(cds)("Unable to open file %s.", path); + MetaspaceShared::unrecoverable_loading_error(); + } + + ResourceMark rm(current); + char* manifest = nullptr; + + if (!is_jrt && type == FileType::NORMAL) { + manifest = read_manifest(current, path, manifest_length); // resource allocated + } + + size_t cs_size = header_size() + + + path_length + 1 /* nul-terminated */ + + manifest_length + 1; /* nul-terminated */ + + AOTClassLocation* cs = (AOTClassLocation*)os::malloc(cs_size, mtClassShared); + memset(cs, 0, cs_size); + cs->_path_length = path_length; + cs->_manifest_length = manifest_length; + cs->_check_time = check_time; + cs->_from_cpattr = from_cpattr; + cs->_timestamp = timestamp; + cs->_filesize = filesize; + cs->_file_type = type; + cs->_group = group; + cs->_index = index; + + strcpy(((char*)cs) + cs->path_offset(), recorded_path); + if (manifest_length > 0) { + memcpy(((char*)cs) + cs->manifest_offset(), manifest, manifest_length); + } + assert(*(cs->manifest() + cs->manifest_length()) == '\0', "should be nul-terminated"); + + if (strstr(cs->manifest(), "Multi-Release: true") != nullptr) { + cs->_is_multi_release_jar = true; + } + + if (strstr(cs->manifest(), "Extension-List:") != nullptr) { + vm_exit_during_cds_dumping(err_msg("-Xshare:dump does not support Extension-List in JAR manifest: %s", path)); + } + + return cs; +} + +char* AOTClassLocation::read_manifest(JavaThread* current, const char* path, size_t& manifest_length) { + manifest_length = 0; + + struct stat st; + if (os::stat(path, &st) != 0) { + return nullptr; + } + + ClassPathEntry* cpe = ClassLoader::create_class_path_entry(current, path, &st); + if (cpe == nullptr) { + // is a file, but not a JAR file + return nullptr; + } + assert(cpe->is_jar_file(), "should not be called with a directory"); + + const char* name = "META-INF/MANIFEST.MF"; + char* manifest; + jint size; + manifest = (char*) ((ClassPathZipEntry*)cpe)->open_entry(current, name, &size, true); + + if (manifest == nullptr || size <= 0) { // No Manifest + manifest_length = 0; + } else { + manifest_length = (size_t)size; + } + + delete cpe; + return manifest; +} + +// The result is resource allocated. +char* AOTClassLocation::get_cpattr() const { + if (_manifest_length == 0) { + return nullptr; + } + + size_t buf_size = _manifest_length + 1; + char* buf = NEW_RESOURCE_ARRAY(char, buf_size); + memcpy(buf, manifest(), _manifest_length); + buf[_manifest_length] = 0; // make sure it's 0-terminated + + // See http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest + // Replace all CR/LF and CR with LF + StringUtils::replace_no_expand(buf, "\r\n", "\n"); + // Remove all new-line continuation (remove all "\n " substrings) + StringUtils::replace_no_expand(buf, "\n ", ""); + + const char* tag = "Class-Path: "; + size_t tag_len = strlen(tag); + char* found = nullptr; + char* line_start = buf; + char* end = buf + _manifest_length; + + assert(*end == 0, "must be nul-terminated"); + + while (line_start < end) { + char* line_end = strchr(line_start, '\n'); + if (line_end == nullptr) { + // JAR spec require the manifest file to be terminated by a new line. + break; + } + if (strncmp(tag, line_start, tag_len) == 0) { + if (found != nullptr) { + // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java + // If duplicated entries are found, the last one is used. + log_warning(cds)("Warning: Duplicate name in Manifest: %s.\n" + "Ensure that the manifest does not have duplicate entries, and\n" + "that blank lines separate individual sections in both your\n" + "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, path()); + } + found = line_start + tag_len; + assert(found <= line_end, "sanity"); + *line_end = '\0'; + } + line_start = line_end + 1; + } + + return found; +} + +AOTClassLocation* AOTClassLocation::write_to_archive() const { + AOTClassLocation* archived_copy = (AOTClassLocation*)ArchiveBuilder::ro_region_alloc(total_size()); + memcpy((char*)archived_copy, (char*)this, total_size()); + return archived_copy; +} + +const char* AOTClassLocation::file_type_string() const { + switch (_file_type) { + case FileType::NORMAL: return "file"; + case FileType::DIR: return "dir"; + case FileType::NOT_EXIST: default: return "not-exist"; + } +} + +bool AOTClassLocation::check(const char* runtime_path, bool has_aot_linked_classes) const { + struct stat st; + if (os::stat(runtime_path, &st) != 0) { + if (_file_type != FileType::NOT_EXIST) { + log_warning(cds)("Required classpath entry does not exist: %s", runtime_path); + return false; + } + } else if ((st.st_mode & S_IFMT) == S_IFDIR) { + if (_file_type == FileType::NOT_EXIST) { + log_warning(cds)("'%s' must not exist", runtime_path); + return false; + } + if (_file_type == FileType::NORMAL) { + log_warning(cds)("'%s' must be a file", runtime_path); + return false; + } + if (!os::dir_is_empty(runtime_path)) { + log_warning(cds)("directory is not empty: '%s'", runtime_path); + return false; + } + } else { + if (_file_type == FileType::NOT_EXIST) { + log_warning(cds)("'%s' must not exist", runtime_path); + if (has_aot_linked_classes) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used because the " + "file %s exists", runtime_path); + return false; + } else { + log_warning(cds)("Archived non-system classes are disabled because the " + "file %s exists", runtime_path); + FileMapInfo::current_info()->set_has_platform_or_app_classes(false); + if (DynamicArchive::is_mapped()) { + FileMapInfo::dynamic_info()->set_has_platform_or_app_classes(false); + } + } + } + if (_file_type == FileType::DIR) { + log_warning(cds)("'%s' must be a directory", runtime_path); + return false; + } + bool size_differs = _filesize != st.st_size; + bool time_differs = _check_time && (_timestamp != st.st_mtime); + if (size_differs || time_differs) { + log_warning(cds)("This file is not the one used while building the shared archive file: '%s'%s%s", + runtime_path, + time_differs ? ", timestamp has changed" : "", + size_differs ? ", size has changed" : ""); + return false; + } + } + + log_info(class, path)("ok"); + return true; +} + +void AOTClassLocationConfig::dumptime_init(JavaThread* current) { + assert(CDSConfig::is_dumping_archive(), ""); + _dumptime_instance = NEW_C_HEAP_OBJ(AOTClassLocationConfig, mtClassShared); + _dumptime_instance->dumptime_init_helper(current); + if (current->has_pending_exception()) { + // we can get an exception only when we run out of metaspace, but that + // shouldn't happen this early in bootstrap. + java_lang_Throwable::print(current->pending_exception(), tty); + vm_exit_during_initialization("AOTClassLocationConfig::dumptime_init_helper() failed unexpectedly"); + } +} + +void AOTClassLocationConfig::dumptime_init_helper(TRAPS) { + ResourceMark rm; + GrowableClassLocationArray tmp_array; + AllClassLocationStreams all_css; + + AOTClassLocation* jrt = AOTClassLocation::allocate(THREAD, ClassLoader::get_jrt_entry()->name(), + 0, Group::MODULES_IMAGE, + /*from_cpattr*/false, /*is_jrt*/true); + tmp_array.append(jrt); + + parse(THREAD, tmp_array, all_css.boot_cp(), Group::BOOT_CLASSPATH, /*parse_manifest*/true); + _boot_classpath_end = tmp_array.length(); + + parse(THREAD, tmp_array, all_css.app_cp(), Group::APP_CLASSPATH, /*parse_manifest*/true); + _app_classpath_end = tmp_array.length(); + + parse(THREAD, tmp_array, all_css.module_path(), Group::MODULE_PATH, /*parse_manifest*/false); + _module_end = tmp_array.length(); + + _class_locations = MetadataFactory::new_array(ClassLoaderData::the_null_class_loader_data(), + tmp_array.length(), CHECK); + for (int i = 0; i < tmp_array.length(); i++) { + _class_locations->at_put(i, tmp_array.at(i)); + } + + const char* lcp = find_lcp(all_css.boot_and_app_cp(), _dumptime_lcp_len); + if (_dumptime_lcp_len > 0) { + os::free((void*)lcp); + log_info(class, path)("Longest common prefix = %s (%zu chars)", lcp, _dumptime_lcp_len); + } else { + assert(_dumptime_lcp_len == 0, "sanity"); + log_info(class, path)("Longest common prefix = (0 chars)"); + } + + _has_non_jar_modules = all_css.module_path().has_non_jar_modules(); + _has_platform_classes = false; + _has_app_classes = false; + _max_used_index = 0; +} + +// Find the longest common prefix of two paths, up to max_lcp_len. +// E.g. p1 = "/a/b/foo" +// p2 = "/a/b/bar" +// max_lcp_len = 3 +// -> returns 3 +static size_t find_lcp_of_two_paths(const char* p1, const char* p2, size_t max_lcp_len) { + size_t lcp_len = 0; + char sep = os::file_separator()[0]; + for (size_t i = 0; ; i++) { + char c1 = *p1++; + char c2 = *p2++; + if (c1 == 0 || c2 == 0 || c1 != c2) { + break; + } + if (c1 == sep) { + lcp_len = i + 1; + assert(lcp_len <= max_lcp_len, "sanity"); + if (lcp_len == max_lcp_len) { + break; + } + } + } + return lcp_len; +} + +// cheap-allocated if lcp_len > 0 +const char* AOTClassLocationConfig::find_lcp(ClassLocationStream& css, size_t& lcp_len) { + const char* first_path = nullptr; + char sep = os::file_separator()[0]; + + for (css.start(); css.has_next(); ) { + const char* path = css.get_next(); + if (first_path == nullptr) { + first_path = path; + const char* p = strrchr(first_path, sep); + if (p == nullptr) { + lcp_len = 0; + return ""; + } else { + lcp_len = p - first_path + 1; + } + } else { + lcp_len = find_lcp_of_two_paths(first_path, path, lcp_len); + if (lcp_len == 0) { + return ""; + } + } + } + + if (first_path != nullptr && lcp_len > 0) { + char* lcp = NEW_C_HEAP_ARRAY(char, lcp_len + 1, mtClassShared); + lcp[0] = 0; + strncat(lcp, first_path, lcp_len); + return lcp; + } else { + lcp_len = 0; + return ""; + } +} + +void AOTClassLocationConfig::parse(JavaThread* current, GrowableClassLocationArray& tmp_array, + ClassLocationStream& css, Group group, bool parse_manifest) { + for (css.start(); css.has_next(); ) { + add_class_location(current, tmp_array, css.get_next(), group, parse_manifest, /*from_cpattr*/false); + } +} + +void AOTClassLocationConfig::add_class_location(JavaThread* current, GrowableClassLocationArray& tmp_array, + const char* path, Group group, bool parse_manifest, bool from_cpattr) { + AOTClassLocation* cs = AOTClassLocation::allocate(current, path, tmp_array.length(), group, from_cpattr); + tmp_array.append(cs); + + if (!parse_manifest) { + // parse_manifest is true for -classpath and -Xbootclasspath/a, and false for --module-path. + return; + } + + ResourceMark rm; + char* cp_attr = cs->get_cpattr(); // resource allocated + if (cp_attr != nullptr && strlen(cp_attr) > 0) { + //trace_class_path("found Class-Path: ", cp_attr); FIXME + + char sep = os::file_separator()[0]; + const char* dir_name = cs->path(); + const char* dir_tail = strrchr(dir_name, sep); +#ifdef _WINDOWS + // On Windows, we also support forward slash as the file separator when locating entries in the classpath entry. + const char* dir_tail2 = strrchr(dir_name, '/'); + if (dir_tail == nullptr) { + dir_tail = dir_tail2; + } else if (dir_tail2 != nullptr && dir_tail2 > dir_tail) { + dir_tail = dir_tail2; + } +#endif + int dir_len; + if (dir_tail == nullptr) { + dir_len = 0; + } else { + dir_len = pointer_delta_as_int(dir_tail, dir_name) + 1; + } + + // Split the cp_attr by spaces, and add each file + char* file_start = cp_attr; + char* end = file_start + strlen(file_start); + + while (file_start < end) { + char* file_end = strchr(file_start, ' '); + if (file_end != nullptr) { + *file_end = 0; + file_end += 1; + } else { + file_end = end; + } + + size_t name_len = strlen(file_start); + if (name_len > 0) { + ResourceMark rm(current); + size_t libname_len = dir_len + name_len; + char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1); + int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); + assert((size_t)n == libname_len, "Unexpected number of characters in string"); + + // Avoid infinite recursion when two JAR files refer to each + // other via cpattr. + bool found_duplicate = false; + for (int i = boot_cp_start_index(); i < tmp_array.length(); i++) { + if (strcmp(tmp_array.at(i)->path(), libname) == 0) { + found_duplicate = true; + break; + } + } + if (!found_duplicate) { + add_class_location(current, tmp_array, libname, group, parse_manifest, /*from_cpattr*/true); + } + } + + file_start = file_end; + } + } +} + +AOTClassLocation const* AOTClassLocationConfig::class_location_at(int index) const { + return _class_locations->at(index); +} + +int AOTClassLocationConfig::get_module_shared_path_index(Symbol* location) const { + if (location->starts_with("jrt:", 4)) { + assert(class_location_at(0)->is_modules_image(), "sanity"); + return 0; + } + + if (num_module_paths() == 0) { + // The archive(s) were created without --module-path option + return -1; + } + + if (!location->starts_with("file:", 5)) { + return -1; + } + + // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table() + ResourceMark rm; + const char* file = ClassLoader::uri_to_path(location->as_C_string()); + for (int i = module_path_start_index(); i < module_path_end_index(); i++) { + const AOTClassLocation* cs = class_location_at(i); + assert(!cs->has_unnamed_module(), "must be"); + bool same = os::same_files(file, cs->path()); + log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i, + location->as_C_string(), cs->path(), same ? "same" : "different"); + if (same) { + return i; + } + } + return -1; +} + +// We allow non-empty dirs as long as no classes have been loaded from them. +void AOTClassLocationConfig::check_nonempty_dirs() const { + assert(CDSConfig::is_dumping_archive(), "sanity"); + + bool has_nonempty_dir = false; + dumptime_iterate([&](AOTClassLocation* cs) { + if (cs->index() > _max_used_index) { + return false; // stop iterating + } + if (cs->is_dir()) { + if (!os::dir_is_empty(cs->path())) { + log_error(cds)("Error: non-empty directory '%s'", cs->path()); + has_nonempty_dir = true; + } + } + return true; // keep iterating + }); + + if (has_nonempty_dir) { + vm_exit_during_cds_dumping("Cannot have non-empty directory in paths", nullptr); + } +} + +AOTClassLocationConfig* AOTClassLocationConfig::write_to_archive() const { + Array* archived_copy = ArchiveBuilder::new_ro_array(_class_locations->length()); + for (int i = 0; i < _class_locations->length(); i++) { + archived_copy->at_put(i, _class_locations->at(i)->write_to_archive()); + ArchivePtrMarker::mark_pointer((address*)archived_copy->adr_at(i)); + } + + AOTClassLocationConfig* dumped = (AOTClassLocationConfig*)ArchiveBuilder::ro_region_alloc(sizeof(AOTClassLocationConfig)); + memcpy(dumped, this, sizeof(AOTClassLocationConfig)); + dumped->_class_locations = archived_copy; + ArchivePtrMarker::mark_pointer(&dumped->_class_locations); + + return dumped; +} + +bool AOTClassLocationConfig::check_classpaths(bool is_boot_classpath, bool has_aot_linked_classes, + int index_start, int index_end, + ClassLocationStream& runtime_css, + bool use_lcp_match, const char* runtime_lcp, + size_t runtime_lcp_len) const { + if (index_start >= index_end && runtime_css.is_empty()) { // nothing to check + return true; + } + + ResourceMark rm; + const char* which = is_boot_classpath ? "boot" : "app"; + LogTarget(Info, class, path) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print("Checking %s classpath", which); + ls.print_cr("%s", use_lcp_match ? " (with longest common prefix substitution)" : ""); + ls.print("- expected : '"); + print_dumptime_classpath(ls, index_start, index_end, use_lcp_match, _dumptime_lcp_len, runtime_lcp, runtime_lcp_len); + ls.print_cr("'"); + ls.print("- actual : '"); + runtime_css.print(&ls); + ls.print_cr("'"); + } + + runtime_css.start(); + for (int i = index_start; i < index_end; i++) { + ResourceMark rm; + const AOTClassLocation* cs = class_location_at(i); + const char* effective_dumptime_path = cs->path(); + if (use_lcp_match && _dumptime_lcp_len > 0) { + effective_dumptime_path = substitute(effective_dumptime_path, _dumptime_lcp_len, runtime_lcp, runtime_lcp_len); + } + + log_info(class, path)("Checking '%s' %s%s", effective_dumptime_path, cs->file_type_string(), + cs->from_cpattr() ? " (from JAR manifest ClassPath attribute)" : ""); + if (!cs->from_cpattr() && file_exists(effective_dumptime_path)) { + if (!runtime_css.has_next()) { + log_warning(cds)("%s classpath has fewer elements than expected", which); + return false; + } + const char* runtime_path = runtime_css.get_next(); + while (!file_exists(runtime_path) && runtime_css.has_next()) { + runtime_path = runtime_css.get_next(); + } + if (!os::same_files(effective_dumptime_path, runtime_path)) { + log_warning(cds)("The name of %s classpath [%d] does not match: expected '%s', got '%s'", + which, runtime_css.current(), effective_dumptime_path, runtime_path); + return false; + } + } + + if (!cs->check(effective_dumptime_path, has_aot_linked_classes)) { + return false; + } + } + + // Check if the runtime boot classpath has more entries than the one stored in the archive and if the app classpath + // or the module path requires validation. + if (is_boot_classpath && runtime_css.has_next() && (need_to_check_app_classpath() || num_module_paths() > 0)) { + // the check passes if all the extra runtime boot classpath entries are non-existent + if (check_paths_existence(runtime_css)) { + log_warning(cds)("boot classpath is longer than expected"); + return false; + } + } + + return true; +} + +bool AOTClassLocationConfig::file_exists(const char* filename) const{ + struct stat st; + return (os::stat(filename, &st) == 0 && st.st_size > 0); +} + +bool AOTClassLocationConfig::check_paths_existence(ClassLocationStream& runtime_css) const { + bool exist = false; + while (runtime_css.has_next()) { + const char* path = runtime_css.get_next(); + if (file_exists(path)) { + exist = true; + break; + } + } + return exist; +} + +bool AOTClassLocationConfig::check_module_paths(bool has_aot_linked_classes, int index_start, int index_end, + ClassLocationStream& runtime_css, + bool* has_extra_module_paths) const { + if (index_start >= index_end && runtime_css.is_empty()) { // nothing to check + return true; + } + + ResourceMark rm; + + LogTarget(Info, class, path) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print_cr("Checking module paths"); + ls.print("- expected : '"); + print_dumptime_classpath(ls, index_start, index_end, false, 0, nullptr, 0); + ls.print_cr("'"); + ls.print("- actual : '"); + runtime_css.print(&ls); + ls.print_cr("'"); + } + + // Make sure all the dumptime module paths exist and are unchanged + for (int i = index_start; i < index_end; i++) { + const AOTClassLocation* cs = class_location_at(i); + const char* dumptime_path = cs->path(); + + assert(!cs->from_cpattr(), "not applicable for module path"); + log_info(class, path)("Checking '%s' %s", dumptime_path, cs->file_type_string()); + + if (!cs->check(dumptime_path, has_aot_linked_classes)) { + return false; + } + } + + // We allow runtime_css to be a superset of the module paths specified in dumptime. E.g., + // Dumptime: A:C + // Runtime: A:B:C + runtime_css.start(); + for (int i = index_start; i < index_end; i++) { + const AOTClassLocation* cs = class_location_at(i); + const char* dumptime_path = cs->path(); + + while (true) { + if (!runtime_css.has_next()) { + log_warning(cds)("module path has fewer elements than expected"); + *has_extra_module_paths = true; + return true; + } + // Both this->class_locations() and runtime_css are alphabetically sorted. Skip + // items in runtime_css until we see dumptime_path. + const char* runtime_path = runtime_css.get_next(); + if (!os::same_files(dumptime_path, runtime_path)) { + *has_extra_module_paths = true; + return true; + } else { + break; + } + } + } + + if (runtime_css.has_next()) { + *has_extra_module_paths = true; + } + + return true; +} + +void AOTClassLocationConfig::print_dumptime_classpath(LogStream& ls, int index_start, int index_end, + bool do_substitute, size_t remove_prefix_len, + const char* prepend, size_t prepend_len) const { + const char* sep = ""; + for (int i = index_start; i < index_end; i++) { + ResourceMark rm; + const AOTClassLocation* cs = class_location_at(i); + const char* path = cs->path(); + if (!cs->from_cpattr()) { + ls.print("%s", sep); + if (do_substitute) { + path = substitute(path, remove_prefix_len, prepend, prepend_len); + } + ls.print("%s", path); + sep = os::path_separator(); + } + } +} + +// Returned path is resource-allocated +const char* AOTClassLocationConfig::substitute(const char* path, // start with this path (which was recorded from dump time) + size_t remove_prefix_len, // remove this number of chars from the beginning + const char* prepend, // prepend this string + size_t prepend_len) { // length of the prepended string + size_t len = strlen(path); + assert(len > remove_prefix_len, "sanity"); + assert(prepend_len == strlen(prepend), "sanity"); + len -= remove_prefix_len; + len += prepend_len; + + char* buf = NEW_RESOURCE_ARRAY(char, len + 1); + int n = os::snprintf(buf, len + 1, "%s%s", prepend, path + remove_prefix_len); + assert(size_t(n) == len, "sanity"); + + return buf; +} + +// For performance, we avoid using LCP match if there's at least one +// AOTClassLocation can be matched exactly: this means all other AOTClassLocations must be +// matched exactly. +bool AOTClassLocationConfig::need_lcp_match(AllClassLocationStreams& all_css) const { + if (app_cp_end_index() == boot_cp_start_index()) { + // No need to use lcp-match when there are no boot/app paths. + // TODO: LCP-match not yet supported for modules. + return false; + } + + if (need_lcp_match_helper(boot_cp_start_index(), boot_cp_end_index(), all_css.boot_cp()) && + need_lcp_match_helper(app_cp_start_index(), app_cp_end_index(), all_css.app_cp())) { + return true; + } else { + return false; + } +} + +bool AOTClassLocationConfig::need_lcp_match_helper(int start, int end, ClassLocationStream& css) const { + int i = start; + for (css.start(); i < end && css.has_next(); ) { + const AOTClassLocation* cs = class_location_at(i++); + const char* runtime_path = css.get_next(); + if (cs->must_exist() && os::same_files(cs->path(), runtime_path)) { + // Most likely, we will come to here at the first iteration. + return false; + } + } + return true; +} + +bool AOTClassLocationConfig::validate(bool has_aot_linked_classes, bool* has_extra_module_paths) const { + ResourceMark rm; + AllClassLocationStreams all_css; + + const char* jrt = ClassLoader::get_jrt_entry()->name(); + bool success = class_location_at(0)->check(jrt, has_aot_linked_classes); + log_info(class, path)("Modules image %s validation: %s", jrt, success ? "passed" : "failed"); + if (!success) { + return false; + } + if (class_locations()->length() == 1) { + if ((module_path_start_index() >= module_path_end_index()) && Arguments::get_property("jdk.module.path") != nullptr) { + *has_extra_module_paths = true; + } else { + *has_extra_module_paths = false; + } + } else { + bool use_lcp_match = need_lcp_match(all_css); + const char* runtime_lcp; + size_t runtime_lcp_len; + + log_info(class, path)("Longest common prefix substitution in boot/app classpath matching: %s", + use_lcp_match ? "yes" : "no"); + if (use_lcp_match) { + runtime_lcp = find_lcp(all_css.boot_and_app_cp(), runtime_lcp_len); + log_info(class, path)("Longest common prefix: %s (%zu chars)", runtime_lcp, runtime_lcp_len); + } else { + runtime_lcp = nullptr; + runtime_lcp_len = 0; + } + + success = check_classpaths(true, has_aot_linked_classes, boot_cp_start_index(), boot_cp_end_index(), all_css.boot_cp(), + use_lcp_match, runtime_lcp, runtime_lcp_len); + log_info(class, path)("Archived boot classpath validation: %s", success ? "passed" : "failed"); + + if (success && need_to_check_app_classpath()) { + success = check_classpaths(false, has_aot_linked_classes, app_cp_start_index(), app_cp_end_index(), all_css.app_cp(), + use_lcp_match, runtime_lcp, runtime_lcp_len); + log_info(class, path)("Archived app classpath validation: %s", success ? "passed" : "failed"); + } + + if (success) { + success = check_module_paths(has_aot_linked_classes, module_path_start_index(), module_path_end_index(), + all_css.module_path(), has_extra_module_paths); + log_info(class, path)("Archived module path validation: %s%s", success ? "passed" : "failed", + (*has_extra_module_paths) ? " (extra module paths found)" : ""); + } + + if (runtime_lcp_len > 0) { + os::free((void*)runtime_lcp); + } + } + + if (success) { + _runtime_instance = this; + } else { + const char* mismatch_msg = "shared class paths mismatch"; + const char* hint_msg = log_is_enabled(Info, class, path) ? + "" : " (hint: enable -Xlog:class+path=info to diagnose the failure)"; + if (RequireSharedSpaces && !PrintSharedArchiveAndExit) { + log_error(cds)("%s%s", mismatch_msg, hint_msg); + MetaspaceShared::unrecoverable_loading_error(); + } else { + log_warning(cds)("%s%s", mismatch_msg, hint_msg); + } + } + return success; +} diff --git a/src/hotspot/share/cds/aotClassLocation.hpp b/src/hotspot/share/cds/aotClassLocation.hpp new file mode 100644 index 0000000000000..cb53e9c96e9d4 --- /dev/null +++ b/src/hotspot/share/cds/aotClassLocation.hpp @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTCLASSLOCATION_HPP +#define SHARE_CDS_AOTCLASSLOCATION_HPP + +#include "memory/allocation.hpp" +#include "oops/array.hpp" +#include "utilities/exceptions.hpp" +#include "utilities/growableArray.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" + +class AllClassLocationStreams; +class ClassLocationStream; +class LogStream; + +// An AOTClassLocation is a location where the application is configured to load Java classes +// from. It can be: +// - the location of $JAVA_HOME/lib/modules +// - an entry in -Xbootclasspath/a +// - an entry in -classpath +// - a JAR file specified using --module-path. +// +// AOTClassLocation is similar to java.security.CodeSource, except: +// - Only local files/dirs are allowed. Directories must be empty. Network locations are not allowed. +// - No code signing information is recorded. +// +// We avoid using pointers in AOTClassLocation to avoid runtime pointer relocation. Each AOTClassLocation +// is a variable-size structure: +// [ all fields specified below (sizeof(AOTClassLocation) bytes) ] +// [ path (_path_length bytes, including the terminating zero) ] +// [ manifest (_manifest_length bytes, including the terminating zero) ] +class AOTClassLocation { +public: + enum class Group : int { + MODULES_IMAGE, + BOOT_CLASSPATH, + APP_CLASSPATH, + MODULE_PATH + }; +private: + enum class FileType : int { + NORMAL, + DIR, + NOT_EXIST + }; + size_t _path_length; // does NOT include terminating zero + size_t _manifest_length; // does NOT include terminating zero + bool _check_time; + bool _from_cpattr; + bool _is_multi_release_jar; // is this a JAR file that has multi-release classes? + FileType _file_type; + Group _group; + int _index; // index of this AOTClassLocation inside AOTClassLocationConfig::_class_locations + time_t _timestamp; + int64_t _filesize; + + static size_t header_size() { return sizeof(AOTClassLocation); } // bytes + size_t path_offset() const { return header_size(); } + size_t manifest_offset() const { return path_offset() + _path_length + 1; } + static char* read_manifest(JavaThread* current, const char* path, size_t& manifest_length); + +public: + static AOTClassLocation* allocate(JavaThread* current, const char* path, int index, Group group, + bool from_cpattr = false, bool is_jrt = false); + + size_t total_size() const { return manifest_offset() + _manifest_length + 1; } + const char* path() const { return ((const char*)this) + path_offset(); } + size_t manifest_length() const { return _manifest_length; } + const char* manifest() const { return ((const char*)this) + manifest_offset(); } + bool must_exist() const { return _file_type != FileType::NOT_EXIST; } + bool must_not_exist() const { return _file_type == FileType::NOT_EXIST; } + bool is_dir() const { return _file_type == FileType::DIR; } + int index() const { return _index; } + bool is_modules_image() const { return _group == Group::MODULES_IMAGE; } + bool from_boot_classpath() const { return _group == Group::BOOT_CLASSPATH; } + bool from_app_classpath() const { return _group == Group::APP_CLASSPATH; } + bool from_module_path() const { return _group == Group::MODULE_PATH; } + bool is_multi_release_jar() const { return _is_multi_release_jar; } + + // Only boot/app classpaths can contain unnamed module + bool has_unnamed_module() const { return from_boot_classpath() || from_app_classpath(); } + + char* get_cpattr() const; + AOTClassLocation* write_to_archive() const; + + // Returns true IFF this AOTClassLocation is discovered from the -classpath or -Xbootclasspath/a by parsing the + // "Class-Path" attribute of a JAR file. + bool from_cpattr() const { return _from_cpattr; } + const char* file_type_string() const; + bool check(const char* runtime_path, bool has_aot_linked_classes) const; +}; + +// AOTClassLocationConfig +// +// Keep track of the set of AOTClassLocations used when an AOTCache is created. +// To load the AOTCache in a production run, the JVM must be using a compatible set of +// AOTClassLocations (subjected to AOTClassLocationConfig::validate()). +// +// In general, validation is performed on the AOTClassLocations to ensure the code locations used +// during AOTCache creation are the same as when the AOTCache is used during runtime. +// Non-existent entries are recorded during AOTCache creation. Those non-existent entries, +// if they are specified at runtime, must not exist. +// +// Some details on validation: +// - the boot classpath can be appended to at runtime if there's no app classpath and no +// module path specified when an AOTCache is created; +// - the app classpath can be appended to at runtime; +// - the module path at runtime can be a superset of the one specified during AOTCache creation. + +class AOTClassLocationConfig : public CHeapObj { + using Group = AOTClassLocation::Group; + using GrowableClassLocationArray = GrowableArrayCHeap; + + // Note: both of the following are non-null if we are dumping a dynamic archive. + static AOTClassLocationConfig* _dumptime_instance; + static const AOTClassLocationConfig* _runtime_instance; + + Array* _class_locations; // jrt -> -Xbootclasspath/a -> -classpath -> --module_path + int _boot_classpath_end; + int _app_classpath_end; + int _module_end; + bool _has_non_jar_modules; + bool _has_platform_classes; + bool _has_app_classes; + int _max_used_index; + size_t _dumptime_lcp_len; + + // accessors + Array* class_locations() const { return _class_locations; } + + void parse(JavaThread* current, GrowableClassLocationArray& tmp_array, ClassLocationStream& css, + Group group, bool parse_manifest); + void add_class_location(JavaThread* current, GrowableClassLocationArray& tmp_array, const char* path, + Group group, bool parse_manifest, bool from_cpattr); + void dumptime_init_helper(TRAPS); + + bool check_classpaths(bool is_boot_classpath, bool has_aot_linked_classes, + int index_start, int index_end, ClassLocationStream& runtime_css, + bool use_lcp_match, const char* runtime_lcp, size_t runtime_lcp_len) const; + bool check_module_paths(bool has_aot_linked_classes, int index_start, int index_end, ClassLocationStream& runtime_css, + bool* has_extra_module_paths) const; + bool file_exists(const char* filename) const; + bool check_paths_existence(ClassLocationStream& runtime_css) const; + + static const char* substitute(const char* path, size_t remove_prefix_len, + const char* prepend, size_t prepend_len); + static const char* find_lcp(ClassLocationStream& css, size_t& lcp_len); + bool need_lcp_match(AllClassLocationStreams& all_css) const; + bool need_lcp_match_helper(int start, int end, ClassLocationStream& css) const; + + template void dumptime_iterate_helper(FUNC func) const { + assert(_class_locations != nullptr, "sanity"); + int n = _class_locations->length(); + for (int i = 0; i < n; i++) { + if (!func(_class_locations->at(i))) { + break; + } + } + } + + template void iterate(FUNC func) const { + int n = class_locations()->length(); + for (int i = 0; i < n; i++) { + if (!func(class_locations()->at(i))) { + break; + } + } + } + + void check_nonempty_dirs() const; + bool need_to_check_app_classpath() const { + return (num_app_classpaths() > 0) && (_max_used_index >= app_cp_start_index()) && has_platform_or_app_classes(); + } + + void print_dumptime_classpath(LogStream& ls, int index_start, int index_limit, + bool do_substitute, size_t remove_prefix_len, + const char* prepend, size_t prepend_len) const; +public: + static AOTClassLocationConfig* dumptime() { + assert(_dumptime_instance != nullptr, "can only be called when dumping an AOT cache"); + return _dumptime_instance; + } + + static const AOTClassLocationConfig* runtime() { + assert(_runtime_instance != nullptr, "can only be called when using an AOT cache"); + return _runtime_instance; + } + + // Common accessors + int boot_cp_start_index() const { return 1; } + int boot_cp_end_index() const { return _boot_classpath_end; } + int app_cp_start_index() const { return boot_cp_end_index(); } + int app_cp_end_index() const { return _app_classpath_end; } + int module_path_start_index() const { return app_cp_end_index(); } + int module_path_end_index() const { return _module_end; } + bool has_platform_or_app_classes() const { return _has_app_classes || _has_platform_classes; } + bool has_non_jar_modules() const { return _has_non_jar_modules; } + int num_boot_classpaths() const { return boot_cp_end_index() - boot_cp_start_index(); } + int num_app_classpaths() const { return app_cp_end_index() - app_cp_start_index(); } + int num_module_paths() const { return module_path_end_index() - module_path_start_index(); } + + int length() const { + return _class_locations->length(); + } + + const AOTClassLocation* class_location_at(int index) const; + int get_module_shared_path_index(Symbol* location) const; + + // Functions used only during dumptime + static void dumptime_init(JavaThread* current); + + static void dumptime_set_has_app_classes() { + _dumptime_instance->_has_app_classes = true; + } + + static void dumptime_set_has_platform_classes() { + _dumptime_instance->_has_platform_classes = true; + } + + static void dumptime_update_max_used_index(int index) { + if (_dumptime_instance == nullptr) { + assert(index == 0, "sanity"); + } else if (_dumptime_instance->_max_used_index < index) { + _dumptime_instance->_max_used_index = index; + } + } + + static void dumptime_check_nonempty_dirs() { + _dumptime_instance->check_nonempty_dirs(); + } + + static bool dumptime_is_ready() { + return _dumptime_instance != nullptr; + } + template static void dumptime_iterate(FUNC func) { + _dumptime_instance->dumptime_iterate_helper(func); + } + + AOTClassLocationConfig* write_to_archive() const; + + // Functions used only during runtime + bool validate(bool has_aot_linked_classes, bool* has_extra_module_paths) const; +}; + + +#endif // SHARE_CDS_AOTCLASSLOCATION_HPP diff --git a/src/hotspot/share/cds/aotConstantPoolResolver.cpp b/src/hotspot/share/cds/aotConstantPoolResolver.cpp index 584be7085cef3..15ca2b2c2a0d7 100644 --- a/src/hotspot/share/cds/aotConstantPoolResolver.cpp +++ b/src/hotspot/share/cds/aotConstantPoolResolver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassLinker.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveBuilder.hpp" diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp index 9bab6042436d5..31d95024e3bfd 100644 --- a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassInitializer.hpp" #include "cds/aotClassLinker.hpp" #include "cds/aotLinkedClassBulkLoader.hpp" @@ -89,7 +88,7 @@ void AOTLinkedClassBulkLoader::exit_on_exception(JavaThread* current) { ResourceMark rm(current); if (current->pending_exception()->is_a(vmClasses::OutOfMemoryError_klass())) { log_error(cds)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " - SIZE_FORMAT "M", MaxHeapSize/M); + "%zuM", MaxHeapSize/M); } else { log_error(cds)("%s: %s", current->pending_exception()->klass()->external_name(), java_lang_String::as_utf8_string(java_lang_Throwable::message(current->pending_exception()))); diff --git a/src/hotspot/share/cds/aotLinkedClassTable.cpp b/src/hotspot/share/cds/aotLinkedClassTable.cpp index bed090f00a972..b602c599f542f 100644 --- a/src/hotspot/share/cds/aotLinkedClassTable.cpp +++ b/src/hotspot/share/cds/aotLinkedClassTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotLinkedClassTable.hpp" #include "cds/cdsConfig.hpp" #include "cds/serializeClosure.hpp" diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 1cd9d13c3bab9..afd2d909595f5 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "cds/aotArtifactFinder.hpp" #include "cds/aotClassLinker.hpp" #include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveBuilder.hpp" @@ -47,6 +47,7 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allStatic.hpp" +#include "memory/memoryReserver.hpp" #include "memory/memRegion.hpp" #include "memory/resourceArea.hpp" #include "oops/compressedKlass.inline.hpp" @@ -152,9 +153,7 @@ void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) { ArchiveBuilder::ArchiveBuilder() : _current_dump_region(nullptr), _buffer_bottom(nullptr), - _last_verified_top(nullptr), _num_dump_regions_used(0), - _other_region_used_bytes(0), _requested_static_archive_bottom(nullptr), _requested_static_archive_top(nullptr), _requested_dynamic_archive_bottom(nullptr), @@ -171,9 +170,7 @@ ArchiveBuilder::ArchiveBuilder() : _ro_src_objs(), _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), - _total_heap_region_size(0), - _estimated_metaspaceobj_bytes(0), - _estimated_hashtable_bytes(0) + _total_heap_region_size(0) { _klasses = new (mtClassShared) GrowableArray(4 * K, mtClassShared); _symbols = new (mtClassShared) GrowableArray(256 * K, mtClassShared); @@ -193,8 +190,10 @@ ArchiveBuilder::~ArchiveBuilder() { delete _klasses; delete _symbols; if (_shared_rs.is_reserved()) { - _shared_rs.release(); + MemoryReserver::release(_shared_rs); } + + AOTArtifactFinder::dispose(); } // Returns a deterministic sequence of pseudo random numbers. The main purpose is NOT @@ -232,13 +231,8 @@ bool ArchiveBuilder::gather_klass_and_symbol(MetaspaceClosure::Ref* ref, bool re _klasses->append(klass); if (klass->is_hidden()) { assert(klass->is_instance_klass(), "must be"); - assert(SystemDictionaryShared::should_hidden_class_be_archived(InstanceKlass::cast(klass)), "must be"); } } - // See RunTimeClassInfo::get_for(): make sure we have enough space for both maximum - // Klass alignment as well as the RuntimeInfo* pointer we will embed in front of a Klass. - _estimated_metaspaceobj_bytes += align_up(BytesPerWord, CompressedKlassPointers::klass_alignment_in_bytes()) + - align_up(sizeof(void*), SharedSpaceObjectAlignment); } else if (ref->msotype() == MetaspaceObj::SymbolType) { // Make sure the symbol won't be GC'ed while we are dumping the archive. Symbol* sym = (Symbol*)ref->obj(); @@ -246,14 +240,15 @@ bool ArchiveBuilder::gather_klass_and_symbol(MetaspaceClosure::Ref* ref, bool re _symbols->append(sym); } - int bytes = ref->size() * BytesPerWord; - _estimated_metaspaceobj_bytes += align_up(bytes, SharedSpaceObjectAlignment); - return true; // recurse } void ArchiveBuilder::gather_klasses_and_symbols() { ResourceMark rm; + + AOTArtifactFinder::initialize(); + AOTArtifactFinder::find_artifacts(); + log_info(cds)("Gathering classes and symbols ... "); GatherKlassesAndSymbols doit(this); iterate_roots(&doit); @@ -287,10 +282,6 @@ void ArchiveBuilder::gather_klasses_and_symbols() { log_info(cds)("Sorting symbols ... "); _symbols->sort(compare_symbols_by_address); sort_klasses(); - - // TODO -- we need a proper estimate for the archived modules, etc, - // but this should be enough for now - _estimated_metaspaceobj_bytes += 200 * 1024 * 1024; } AOTClassLinker::add_candidates(); @@ -314,57 +305,26 @@ void ArchiveBuilder::sort_klasses() { _klasses->sort(compare_klass_by_name); } -size_t ArchiveBuilder::estimate_archive_size() { - // size of the symbol table and two dictionaries, plus the RunTimeClassInfo's - size_t symbol_table_est = SymbolTable::estimate_size_for_archive(); - size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive(); - _estimated_hashtable_bytes = symbol_table_est + dictionary_est; - - if (CDSConfig::is_dumping_aot_linked_classes()) { - // This is difficult to estimate when dumping the dynamic archive, as the - // AOTLinkedClassTable may need to contain classes in the static archive as well. - // - // Just give a generous estimate for now. We will remove estimate_archive_size() - // in JDK-8340416 - _estimated_hashtable_bytes += 20 * 1024 * 1024; - } - - size_t total = 0; - - total += _estimated_metaspaceobj_bytes; - total += _estimated_hashtable_bytes; - - // allow fragmentation at the end of each dump region - total += _total_dump_regions * MetaspaceShared::core_region_alignment(); - - log_info(cds)("_estimated_hashtable_bytes = " SIZE_FORMAT " + " SIZE_FORMAT " = " SIZE_FORMAT, - symbol_table_est, dictionary_est, _estimated_hashtable_bytes); - log_info(cds)("_estimated_metaspaceobj_bytes = " SIZE_FORMAT, _estimated_metaspaceobj_bytes); - log_info(cds)("total estimate bytes = " SIZE_FORMAT, total); - - return align_up(total, MetaspaceShared::core_region_alignment()); -} - address ArchiveBuilder::reserve_buffer() { - size_t buffer_size = estimate_archive_size(); - ReservedSpace rs(buffer_size, MetaspaceShared::core_region_alignment(), os::vm_page_size()); + size_t buffer_size = LP64_ONLY(CompressedClassSpaceSize) NOT_LP64(256 * M); + ReservedSpace rs = MemoryReserver::reserve(buffer_size, + MetaspaceShared::core_region_alignment(), + os::vm_page_size()); if (!rs.is_reserved()) { - log_error(cds)("Failed to reserve " SIZE_FORMAT " bytes of output buffer.", buffer_size); + log_error(cds)("Failed to reserve %zu bytes of output buffer.", buffer_size); MetaspaceShared::unrecoverable_writing_error(); } // buffer_bottom is the lowest address of the 2 core regions (rw, ro) when // we are copying the class metadata into the buffer. address buffer_bottom = (address)rs.base(); - log_info(cds)("Reserved output buffer space at " PTR_FORMAT " [" SIZE_FORMAT " bytes]", + log_info(cds)("Reserved output buffer space at " PTR_FORMAT " [%zu bytes]", p2i(buffer_bottom), buffer_size); _shared_rs = rs; _buffer_bottom = buffer_bottom; - _last_verified_top = buffer_bottom; _current_dump_region = &_rw_region; _num_dump_regions_used = 1; - _other_region_used_bytes = 0; _current_dump_region->init(&_shared_rs, &_shared_vs); ArchivePtrMarker::initialize(&_ptrmap, &_shared_vs); @@ -583,28 +543,9 @@ ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref } void ArchiveBuilder::start_dump_region(DumpRegion* next) { - address bottom = _last_verified_top; - address top = (address)(current_dump_region()->top()); - _other_region_used_bytes += size_t(top - bottom); - current_dump_region()->pack(next); _current_dump_region = next; _num_dump_regions_used ++; - - _last_verified_top = (address)(current_dump_region()->top()); -} - -void ArchiveBuilder::verify_estimate_size(size_t estimate, const char* which) { - address bottom = _last_verified_top; - address top = (address)(current_dump_region()->top()); - size_t used = size_t(top - bottom) + _other_region_used_bytes; - int diff = int(estimate) - int(used); - - log_info(cds)("%s estimate = " SIZE_FORMAT " used = " SIZE_FORMAT "; diff = %d bytes", which, estimate, used, diff); - assert(diff >= 0, "Estimate is too small"); - - _last_verified_top = top; - _other_region_used_bytes = 0; } char* ArchiveBuilder::ro_strdup(const char* s) { @@ -1242,7 +1183,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { log_as_hex(last_obj_base, last_obj_end, last_obj_base + buffer_to_runtime_delta()); if (last_obj_end < region_end) { - log_debug(cds, map)(PTR_FORMAT ": @@ Misc data " SIZE_FORMAT " bytes", + log_debug(cds, map)(PTR_FORMAT ": @@ Misc data %zu bytes", p2i(last_obj_end + buffer_to_runtime_delta()), size_t(region_end - last_obj_end)); log_as_hex(last_obj_end, region_end, last_obj_end + buffer_to_runtime_delta()); @@ -1262,7 +1203,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { size_t size = top - base; base = requested_base; top = requested_base + size; - log_info(cds, map)("[%-18s " PTR_FORMAT " - " PTR_FORMAT " " SIZE_FORMAT_W(9) " bytes]", + log_info(cds, map)("[%-18s " PTR_FORMAT " - " PTR_FORMAT " %9zu bytes]", name, p2i(base), p2i(top), size); } @@ -1303,7 +1244,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { // We have a filler oop, which also does not exist in BufferOffsetToSourceObjectTable. // Example: // 0x00000007ffc3ffd8: @@ Object filler 40 bytes - st.print_cr("filler " SIZE_FORMAT " bytes", byte_size); + st.print_cr("filler %zu bytes", byte_size); } else { ShouldNotReachHere(); } @@ -1406,7 +1347,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { print_oop_info_cr(&st, obj); } } else { - st.print_cr(" - fields (" SIZE_FORMAT " words):", source_oop->size()); + st.print_cr(" - fields (%zu words):", source_oop->size()); ArchivedFieldPrinter print_field(heap_info, &st, source_oop, buffered_addr); InstanceKlass::cast(source_klass)->print_nonstatic_fields(&print_field); @@ -1631,12 +1572,12 @@ void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* h print_heap_region_stats(heap_info, total_reserved); } - log_debug(cds)("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", + log_debug(cds)("total : %9zu [100.0%% of total] out of %9zu bytes [%5.1f%% used]", total_bytes, total_reserved, total_u_perc); } void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) { - log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]", + log_debug(cds)("bm space: %9zu [ %4.1f%% of total] out of %9zu bytes [100.0%% used]", size, size/double(total_size)*100.0, size); } @@ -1644,7 +1585,7 @@ void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total char* start = info->buffer_start(); size_t size = info->buffer_byte_size(); char* top = start + size; - log_debug(cds)("hp space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT, + log_debug(cds)("hp space: %9zu [ %4.1f%% of total] out of %9zu bytes [100.0%% used] at " INTPTR_FORMAT, size, size/double(total_size)*100.0, size, p2i(start)); } diff --git a/src/hotspot/share/cds/archiveBuilder.hpp b/src/hotspot/share/cds/archiveBuilder.hpp index e42b2f478ec08..e3efedd46f14c 100644 --- a/src/hotspot/share/cds/archiveBuilder.hpp +++ b/src/hotspot/share/cds/archiveBuilder.hpp @@ -29,6 +29,8 @@ #include "cds/dumpAllocStats.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceClosure.hpp" +#include "memory/reservedSpace.hpp" +#include "memory/virtualspace.hpp" #include "oops/array.hpp" #include "oops/klass.hpp" #include "runtime/os.hpp" @@ -94,9 +96,7 @@ class ArchiveBuilder : public StackObj { protected: DumpRegion* _current_dump_region; address _buffer_bottom; // for writing the contents of rw/ro regions - address _last_verified_top; int _num_dump_regions_used; - size_t _other_region_used_bytes; // These are the addresses where we will request the static and dynamic archives to be // mapped at run time. If the request fails (due to ASLR), we will map the archives at @@ -271,16 +271,9 @@ class ArchiveBuilder : public StackObj { protected: virtual void iterate_roots(MetaspaceClosure* it) = 0; - // Conservative estimate for number of bytes needed for: - size_t _estimated_metaspaceobj_bytes; // all archived MetaspaceObj's. - size_t _estimated_hashtable_bytes; // symbol table and dictionaries - static const int _total_dump_regions = 2; - size_t estimate_archive_size(); - void start_dump_region(DumpRegion* next); - void verify_estimate_size(size_t estimate, const char* which); public: address reserve_buffer(); diff --git a/src/hotspot/share/cds/archiveHeapLoader.cpp b/src/hotspot/share/cds/archiveHeapLoader.cpp index b05fd20f4f59f..68015e319c3f8 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.cpp +++ b/src/hotspot/share/cds/archiveHeapLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapLoader.inline.hpp" #include "cds/cdsConfig.hpp" #include "cds/heapShared.hpp" @@ -308,7 +307,7 @@ bool ArchiveHeapLoader::load_heap_region_impl(FileMapInfo* mapinfo, LoadedArchiv } assert(r->mapped_base() == (char*)load_address, "sanity"); log_info(cds)("Loaded heap region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT - " size " SIZE_FORMAT_W(6) " delta " INTX_FORMAT, + " size %6zu delta %zd", loaded_region->_region_index, load_address, load_address + loaded_region->_region_size, loaded_region->_region_size, loaded_region->_runtime_offset); diff --git a/src/hotspot/share/cds/archiveHeapLoader.hpp b/src/hotspot/share/cds/archiveHeapLoader.hpp index 8b9fab91aa3fd..e559b447ebf5e 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.hpp +++ b/src/hotspot/share/cds/archiveHeapLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ #ifndef SHARE_CDS_ARCHIVEHEAPLOADER_HPP #define SHARE_CDS_ARCHIVEHEAPLOADER_HPP -#include "cds/filemap.hpp" #include "gc/shared/gc_globals.hpp" #include "memory/allocation.hpp" #include "memory/allStatic.hpp" diff --git a/src/hotspot/share/cds/archiveHeapWriter.cpp b/src/hotspot/share/cds/archiveHeapWriter.cpp index be821044a96ba..5684066105f1f 100644 --- a/src/hotspot/share/cds/archiveHeapWriter.cpp +++ b/src/hotspot/share/cds/archiveHeapWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,12 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/cdsConfig.hpp" #include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/modules.hpp" #include "classfile/systemDictionary.hpp" #include "gc/shared/collectedHeap.hpp" #include "memory/iterator.inline.hpp" @@ -78,7 +78,7 @@ static FillersTable* _fillers; static int _num_native_ptrs = 0; void ArchiveHeapWriter::init() { - if (HeapShared::can_write()) { + if (CDSConfig::is_dumping_heap()) { Universe::heap()->collect(GCCause::_java_lang_system_gc); _buffer_offset_to_source_obj_table = new BufferOffsetToSourceObjectTable(/*size (prime)*/36137, /*max size*/1 * M); @@ -99,7 +99,7 @@ void ArchiveHeapWriter::add_source_obj(oop src_obj) { void ArchiveHeapWriter::write(GrowableArrayCHeap* roots, ArchiveHeapInfo* heap_info) { - assert(HeapShared::can_write(), "sanity"); + assert(CDSConfig::is_dumping_heap(), "sanity"); allocate_buffer(); copy_source_objs_to_buffer(roots); set_requested_address(heap_info); @@ -217,7 +217,7 @@ void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeapat(root_index++)); } - log_info(cds, heap)("archived obj root segment [%d] = " SIZE_FORMAT " bytes, obj = " PTR_FORMAT, + log_info(cds, heap)("archived obj root segment [%d] = %zu bytes, obj = " PTR_FORMAT, size_elems, size_bytes, p2i(seg_oop)); } @@ -323,9 +323,13 @@ void ArchiveHeapWriter::copy_source_objs_to_buffer(GrowableArrayCHeapput_when_absent(buffer_offset, src_obj); _buffer_offset_to_source_obj_table->maybe_grow(); + + if (java_lang_Module::is_instance(src_obj)) { + Modules::check_archived_module_oop(src_obj); + } } - log_info(cds)("Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots, %d native ptrs", + log_info(cds)("Size of heap region = %zu bytes, %d objects, %d roots, %d native ptrs", _buffer_used, _source_objs->length() + 1, roots->length(), _num_native_ptrs); } @@ -391,7 +395,7 @@ void ArchiveHeapWriter::maybe_fill_gc_region_gap(size_t required_byte_size) { ensure_buffer_space(filler_end); int array_length = filler_array_length(fill_bytes); - log_info(cds, heap)("Inserting filler obj array of %d elements (" SIZE_FORMAT " bytes total) @ buffer offset " SIZE_FORMAT, + log_info(cds, heap)("Inserting filler obj array of %d elements (%zu bytes total) @ buffer offset %zu", array_length, fill_bytes, _buffer_used); HeapWord* filler = init_filler_array_at_buffer_top(array_length, fill_bytes); _buffer_used = filler_end; @@ -622,7 +626,7 @@ static void log_bitmap_usage(const char* which, BitMap* bitmap, size_t total_bit // The whole heap is covered by total_bits, but there are only non-zero bits within [start ... end). size_t start = bitmap->find_first_set_bit(0); size_t end = bitmap->size(); - log_info(cds)("%s = " SIZE_FORMAT_W(7) " ... " SIZE_FORMAT_W(7) " (%3zu%% ... %3zu%% = %3zu%%)", which, + log_info(cds)("%s = %7zu ... %7zu (%3zu%% ... %3zu%% = %3zu%%)", which, start, end, start * 100 / total_bits, end * 100 / total_bits, @@ -749,7 +753,7 @@ void ArchiveHeapWriter::compute_ptrmap(ArchiveHeapInfo* heap_info) { } heap_info->ptrmap()->resize(max_idx + 1); - log_info(cds, heap)("calculate_ptrmap: marked %d non-null native pointers for heap region (" SIZE_FORMAT " bits)", + log_info(cds, heap)("calculate_ptrmap: marked %d non-null native pointers for heap region (%zu bits)", num_non_null_ptrs, size_t(heap_info->ptrmap()->size())); } diff --git a/src/hotspot/share/cds/archiveHeapWriter.hpp b/src/hotspot/share/cds/archiveHeapWriter.hpp index 70c1207bb91f7..1e1319cccc34a 100644 --- a/src/hotspot/share/cds/archiveHeapWriter.hpp +++ b/src/hotspot/share/cds/archiveHeapWriter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,8 +72,9 @@ class ArchiveHeapWriter : AllStatic { // - "source objects" are regular Java objects allocated during the execution // of "java -Xshare:dump". They can be used as regular oops. // - // HeapShared::archive_objects() recursively searches for the oops that need to be - // stored into the CDS archive. These are entered into HeapShared::archived_object_cache(). + // Between HeapShared::start_scanning_for_oops() and HeapShared::end_scanning_for_oops(), + // we recursively search for the oops that need to be stored into the CDS archive. + // These are entered into HeapShared::archived_object_cache(). // // - "buffered objects" are copies of the "source objects", and are stored in into // ArchiveHeapWriter::_buffer, which is a GrowableArray that sits outside of diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 3530fcff2b3f9..90eefd13d469a 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.inline.hpp" #include "cds/archiveUtils.hpp" @@ -124,7 +123,7 @@ void ArchivePtrMarker::mark_pointer(address* ptr_loc) { } assert(idx < _ptrmap->size(), "must be"); _ptrmap->set_bit(idx); - //tty->print_cr("Marking pointer [" PTR_FORMAT "] -> " PTR_FORMAT " @ " SIZE_FORMAT_W(5), p2i(ptr_loc), p2i(*ptr_loc), idx); + //tty->print_cr("Marking pointer [" PTR_FORMAT "] -> " PTR_FORMAT " @ %5zu", p2i(ptr_loc), p2i(*ptr_loc), idx); } } } @@ -138,7 +137,7 @@ void ArchivePtrMarker::clear_pointer(address* ptr_loc) { size_t idx = ptr_loc - ptr_base(); assert(idx < _ptrmap->size(), "cannot clear pointers that have not been marked"); _ptrmap->clear_bit(idx); - //tty->print_cr("Clearing pointer [" PTR_FORMAT "] -> " PTR_FORMAT " @ " SIZE_FORMAT_W(5), p2i(ptr_loc), p2i(*ptr_loc), idx); + //tty->print_cr("Clearing pointer [" PTR_FORMAT "] -> " PTR_FORMAT " @ %5zu", p2i(ptr_loc), p2i(*ptr_loc), idx); } class ArchivePtrBitmapCleaner: public BitMapClosure { @@ -163,7 +162,7 @@ class ArchivePtrBitmapCleaner: public BitMapClosure { } } else { _ptrmap->clear_bit(offset); - DEBUG_ONLY(log_trace(cds, reloc)("Clearing pointer [" PTR_FORMAT "] -> null @ " SIZE_FORMAT_W(9), p2i(ptr_loc), offset)); + DEBUG_ONLY(log_trace(cds, reloc)("Clearing pointer [" PTR_FORMAT "] -> null @ %9zu", p2i(ptr_loc), offset)); } return true; @@ -228,7 +227,7 @@ void DumpRegion::commit_to(char* newtop) { assert(commit <= uncommitted, "sanity"); if (!_vs->expand_by(commit, false)) { - log_error(cds)("Failed to expand shared space to " SIZE_FORMAT " bytes", + log_error(cds)("Failed to expand shared space to %zu bytes", need_committed_size); MetaspaceShared::unrecoverable_writing_error(); } @@ -239,7 +238,7 @@ void DumpRegion::commit_to(char* newtop) { } else { which = "shared"; } - log_debug(cds)("Expanding %s spaces by " SIZE_FORMAT_W(7) " bytes [total " SIZE_FORMAT_W(9) " bytes ending at %p]", + log_debug(cds)("Expanding %s spaces by %7zu bytes [total %9zu bytes ending at %p]", which, commit, _vs->actual_committed_size(), _vs->high()); } @@ -265,7 +264,7 @@ void DumpRegion::append_intptr_t(intptr_t n, bool need_to_mark) { } void DumpRegion::print(size_t total_bytes) const { - log_debug(cds)("%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT, + log_debug(cds)("%s space: %9zu [ %4.1f%% of total] out of %9zu bytes [%5.1f%% used] at " INTPTR_FORMAT, _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), p2i(ArchiveBuilder::current()->to_requested(_base))); } diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 6ab77bf000746..564298fa5c8e9 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,10 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" #include "cds/classListWriter.hpp" +#include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoaderDataShared.hpp" #include "classfile/moduleEntry.hpp" @@ -47,6 +47,7 @@ bool CDSConfig::_is_using_full_module_graph = true; bool CDSConfig::_has_aot_linked_classes = false; bool CDSConfig::_has_archived_invokedynamic = false; bool CDSConfig::_old_cds_flags_used = false; +bool CDSConfig::_disable_heap_dumping = false; char* CDSConfig::_default_archive_path = nullptr; char* CDSConfig::_static_archive_path = nullptr; @@ -420,6 +421,11 @@ void CDSConfig::check_flag_aliases() { bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { check_flag_aliases(); + if (!FLAG_IS_DEFAULT(AOTMode)) { + // Using any form of the new AOTMode switch enables enhanced optimizations. + FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true); + } + if (AOTClassLinking) { // If AOTClassLinking is specified, enable all AOT optimizations by default. FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true); @@ -528,10 +534,53 @@ bool CDSConfig::current_thread_is_vm_or_dumper() { return t != nullptr && (t->is_VM_thread() || t == _dumper_thread); } +// If an incompatible VM options is found, return a text message that explains why +static const char* check_options_incompatible_with_dumping_heap() { +#if INCLUDE_CDS_JAVA_HEAP + if (!UseCompressedClassPointers) { + return "UseCompressedClassPointers must be true"; + } + + // Almost all GCs support heap region dump, except ZGC (so far). + if (UseZGC) { + return "ZGC is not supported"; + } + + return nullptr; +#else + return "JVM not configured for writing Java heap objects"; +#endif +} + +void CDSConfig::log_reasons_for_not_dumping_heap() { + const char* reason; + + assert(!is_dumping_heap(), "sanity"); + + if (_disable_heap_dumping) { + reason = "Programmatically disabled"; + } else { + reason = check_options_incompatible_with_dumping_heap(); + } + + assert(reason != nullptr, "sanity"); + log_info(cds)("Archived java heap is not supported: %s", reason); +} + #if INCLUDE_CDS_JAVA_HEAP +bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() { + return check_options_incompatible_with_dumping_heap() != nullptr; +} + + bool CDSConfig::is_dumping_heap() { - // heap dump is not supported in dynamic dump - return is_dumping_static_archive() && HeapShared::can_write(); + if (!is_dumping_static_archive() // heap dump is not supported in dynamic dump + || are_vm_options_incompatible_with_dumping_heap() + || _disable_heap_dumping) { + return false; + } + + return true; } bool CDSConfig::is_loading_heap() { diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp index cceaceeb6d768..c2dc2b41a93c5 100644 --- a/src/hotspot/share/cds/cdsConfig.hpp +++ b/src/hotspot/share/cds/cdsConfig.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,7 @@ class CDSConfig : public AllStatic { static char* _dynamic_archive_path; static bool _old_cds_flags_used; + static bool _disable_heap_dumping; static JavaThread* _dumper_thread; #endif @@ -116,6 +117,10 @@ class CDSConfig : public AllStatic { // --- Archived java objects + static bool are_vm_options_incompatible_with_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(true); + static void log_reasons_for_not_dumping_heap(); + + static void disable_heap_dumping() { CDS_ONLY(_disable_heap_dumping = true); } static bool is_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_loading_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_initing_classes_at_dump_time() NOT_CDS_JAVA_HEAP_RETURN_(false); diff --git a/src/hotspot/share/cds/cdsConstants.cpp b/src/hotspot/share/cds/cdsConstants.cpp index 6dbacb2774f12..81b5920cc534f 100644 --- a/src/hotspot/share/cds/cdsConstants.cpp +++ b/src/hotspot/share/cds/cdsConstants.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConstants.hpp" #include "cds/dynamicArchive.hpp" #include "cds/filemap.hpp" @@ -38,7 +37,6 @@ CDSConst CDSConstants::offsets[] = { { "GenericCDSFileMapHeader::_base_archive_name_size", offset_of(GenericCDSFileMapHeader, _base_archive_name_size) }, { "CDSFileMapHeaderBase::_regions[0]", offset_of(CDSFileMapHeaderBase, _regions) }, { "FileMapHeader::_jvm_ident", offset_of(FileMapHeader, _jvm_ident) }, - { "FileMapHeader::_common_app_classpath_prefix_size", offset_of(FileMapHeader, _common_app_classpath_prefix_size) }, { "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc) }, { "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used) }, { "DynamicArchiveHeader::_base_region_crc", offset_of(DynamicArchiveHeader, _base_region_crc) } diff --git a/src/hotspot/share/cds/cdsEnumKlass.cpp b/src/hotspot/share/cds/cdsEnumKlass.cpp index 17438428c8092..ffce9fb269a89 100644 --- a/src/hotspot/share/cds/cdsEnumKlass.cpp +++ b/src/hotspot/share/cds/cdsEnumKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsEnumKlass.hpp" #include "cds/heapShared.hpp" @@ -37,7 +36,6 @@ bool CDSEnumKlass::is_enum_obj(oop orig_obj) { Klass* k = orig_obj->klass(); - Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); return k->is_instance_klass() && InstanceKlass::cast(k)->is_enum_subclass(); } @@ -73,7 +71,6 @@ void CDSEnumKlass::handle_enum_obj(int level, } ik->set_has_archived_enum_objs(); - ArchiveBuilder::get_buffered_klass(ik)->set_has_archived_enum_objs(); oop mirror = ik->java_mirror(); for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { diff --git a/src/hotspot/share/cds/cdsHeapVerifier.cpp b/src/hotspot/share/cds/cdsHeapVerifier.cpp index fbc58e503ca36..f9e613a74cee8 100644 --- a/src/hotspot/share/cds/cdsHeapVerifier.cpp +++ b/src/hotspot/share/cds/cdsHeapVerifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassInitializer.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsHeapVerifier.hpp" @@ -258,20 +257,19 @@ void CDSHeapVerifier::add_static_obj_field(InstanceKlass* ik, oop field, Symbol* _table.put(field, info); } +// This function is called once for every archived heap object. Warn if this object is referenced by +// a static field of a class that's not aot-initialized. inline bool CDSHeapVerifier::do_entry(oop& orig_obj, HeapShared::CachedOopInfo& value) { _archived_objs++; + if (java_lang_String::is_instance(orig_obj) && HeapShared::is_dumped_interned_string(orig_obj)) { + // It's quite often for static fields to have interned strings. These are most likely not + // problematic (and are hard to filter). So we will ignore them. + return true; /* keep on iterating */ + } + StaticFieldInfo* info = _table.get(orig_obj); if (info != nullptr) { - if (value.orig_referrer() == nullptr && java_lang_String::is_instance(orig_obj)) { - // This string object is not referenced by any of the archived object graphs. It's archived - // only because it's in the interned string table. So we are not in a condition that - // should be flagged by CDSHeapVerifier. - return true; /* keep on iterating */ - } - if (info->_holder->is_hidden()) { - return true; - } ResourceMark rm; char* class_name = info->_holder->name()->as_C_string(); char* field_name = info->_name->as_C_string(); diff --git a/src/hotspot/share/cds/cdsProtectionDomain.cpp b/src/hotspot/share/cds/cdsProtectionDomain.cpp index 2eb47ff2788d9..dc3d8621db1b0 100644 --- a/src/hotspot/share/cds/cdsProtectionDomain.cpp +++ b/src/hotspot/share/cds/cdsProtectionDomain.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/cdsConfig.hpp" #include "cds/cdsProtectionDomain.hpp" #include "classfile/classLoader.hpp" @@ -50,10 +50,10 @@ OopHandle CDSProtectionDomain::_shared_jar_manifests; Handle CDSProtectionDomain::init_security_info(Handle class_loader, InstanceKlass* ik, PackageEntry* pkg_entry, TRAPS) { int index = ik->shared_classpath_index(); assert(index >= 0, "Sanity"); - SharedClassPathEntry* ent = FileMapInfo::shared_path(index); + const AOTClassLocation* cl = AOTClassLocationConfig::runtime()->class_location_at(index); Symbol* class_name = ik->name(); - if (ent->is_modules_image()) { + if (cl->is_modules_image()) { // For shared app/platform classes originated from the run-time image: // The ProtectionDomains are cached in the corresponding ModuleEntries // for fast access by the VM. @@ -64,15 +64,14 @@ Handle CDSProtectionDomain::init_security_info(Handle class_loader, InstanceKlas return get_shared_protection_domain(class_loader, mod_entry, THREAD); } else { // For shared app/platform classes originated from JAR files on the class path: - // Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length - // as the shared classpath table in the shared archive (see - // FileMap::_shared_path_table in filemap.hpp for details). + // Each of the 3 CDSProtectionDomain::_shared_xxx arrays has the same length + // as the shared classpath table in the shared archive. // // If a shared InstanceKlass k is loaded from the class path, let // - // index = k->shared_classpath_index(): + // index = k->shared_classpath_index(); // - // FileMap::_shared_path_table[index] identifies the JAR file that contains k. + // AOTClassLocationConfig::_runtime_instance->_array->at(index) identifies the JAR file that contains k. // // k's protection domain is: // @@ -85,10 +84,10 @@ Handle CDSProtectionDomain::init_security_info(Handle class_loader, InstanceKlas // define_shared_package(class_name, class_loader, manifest, url, CHECK_NH); // // Note that if an element of these 3 _shared_xxx arrays is null, it will be initialized by - // the corresponding SystemDictionaryShared::get_shared_xxx() function. + // the corresponding CDSProtectionDomain::get_shared_xxx() function. Handle manifest = get_shared_jar_manifest(index, CHECK_NH); Handle url = get_shared_jar_url(index, CHECK_NH); - int index_offset = index - ClassLoaderExt::app_class_paths_start_index(); + int index_offset = index - AOTClassLocationConfig::runtime()->app_cp_start_index(); if (index_offset < PackageEntry::max_index_for_defined_in_class_path()) { if (pkg_entry == nullptr || !pkg_entry->is_defined_by_cds_in_class_path(index_offset)) { // define_shared_package only needs to be called once for each package in a jar specified @@ -179,14 +178,14 @@ Handle CDSProtectionDomain::create_jar_manifest(const char* manifest_chars, size Handle CDSProtectionDomain::get_shared_jar_manifest(int shared_path_index, TRAPS) { Handle manifest; if (shared_jar_manifest(shared_path_index) == nullptr) { - SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index); - size_t size = (size_t)ent->manifest_size(); + const AOTClassLocation* cl = AOTClassLocationConfig::runtime()->class_location_at(shared_path_index); + size_t size = cl->manifest_length(); if (size == 0) { return Handle(); } // ByteArrayInputStream bais = new ByteArrayInputStream(buf); - const char* src = ent->manifest(); + const char* src = cl->manifest(); assert(src != nullptr, "No Manifest data"); manifest = create_jar_manifest(src, size, CHECK_NH); atomic_set_shared_jar_manifest(shared_path_index, manifest()); @@ -199,7 +198,7 @@ Handle CDSProtectionDomain::get_shared_jar_manifest(int shared_path_index, TRAPS Handle CDSProtectionDomain::get_shared_jar_url(int shared_path_index, TRAPS) { Handle url_h; if (shared_jar_url(shared_path_index) == nullptr) { - const char* path = FileMapInfo::shared_path_name(shared_path_index); + const char* path = AOTClassLocationConfig::runtime()->class_location_at(shared_path_index)->path(); oop result_oop = to_file_URL(path, url_h, CHECK_(url_h)); atomic_set_shared_jar_url(shared_path_index, result_oop); } diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index 47925f578ea1f..e0c008678caf2 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveUtils.hpp" #include "cds/classListParser.hpp" @@ -43,6 +42,7 @@ #include "jvm.h" #include "logging/log.hpp" #include "logging/logTag.hpp" +#include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/constantPool.inline.hpp" #include "runtime/atomic.hpp" @@ -112,6 +112,12 @@ ClassListParser::~ClassListParser() { _instance = nullptr; } +void ClassListParser::parse_classlist(const char* classlist_path, ParseMode parse_mode, TRAPS) { + UnregisteredClasses::initialize(CHECK); + ClassListParser parser(classlist_path, parse_mode); + parser.parse(THREAD); +} + void ClassListParser::parse(TRAPS) { for (; !_input_stream.done(); _input_stream.next()) { _line = _input_stream.current_line(); @@ -388,6 +394,19 @@ bool ClassListParser::parse_uint_option(const char* option_name, int* value) { return false; } +objArrayOop ClassListParser::get_specified_interfaces(TRAPS) { + const int n = _interfaces->length(); + if (n == 0) { + return nullptr; + } else { + objArrayOop array = oopFactory::new_objArray(vmClasses::Class_klass(), n, CHECK_NULL); + for (int i = 0; i < n; i++) { + array->obj_at_put(i, lookup_class_by_id(_interfaces->at(i))->java_mirror()); + } + return array; + } +} + void ClassListParser::print_specified_interfaces() { const int n = _interfaces->length(); jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n); @@ -424,10 +443,9 @@ void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, v error_index = 0; } - jio_fprintf(defaultStream::error_stream(), - "An error has occurred while processing class list file %s %zu:%d.\n", - _classlist_file, lineno(), (error_index + 1)); - jio_vfprintf(defaultStream::error_stream(), msg, ap); + st->print("An error has occurred while processing class list file %s %zu:%d.\n", + _classlist_file, lineno(), (error_index + 1)); + st->vprint(msg, ap); if (_line_len <= 0) { st->print("\n"); @@ -515,7 +533,17 @@ InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS ResourceMark rm; char * source_path = os::strdup_check_oom(ClassLoader::uri_to_path(_source)); - InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, CHECK_NULL); + InstanceKlass* specified_super = lookup_class_by_id(_super); + Handle super_class(THREAD, specified_super->java_mirror()); + objArrayOop r = get_specified_interfaces(CHECK_NULL); + objArrayHandle interfaces(THREAD, r); + InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, + super_class, interfaces, CHECK_NULL); + if (k->java_super() != specified_super) { + error("The specified super class %s (id %d) does not match actual super class %s", + specified_super->external_name(), _super, + k->java_super()->external_name()); + } if (k->local_interfaces()->length() != _interfaces->length()) { print_specified_interfaces(); print_actual_interfaces(k); @@ -735,49 +763,6 @@ InstanceKlass* ClassListParser::lookup_class_by_id(int id) { return *klass_ptr; } - -InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) { - if (!is_loading_from_source()) { - return nullptr; - } - - InstanceKlass* k = lookup_class_by_id(super()); - if (super_name != k->name()) { - error("The specified super class %s (id %d) does not match actual super class %s", - k->name()->as_klass_external_name(), super(), - super_name->as_klass_external_name()); - } - return k; -} - -InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) { - if (!is_loading_from_source()) { - return nullptr; - } - - const int n = _interfaces->length(); - if (n == 0) { - error("Class %s implements the interface %s, but no interface has been specified in the input line", - _class_name, interface_name->as_klass_external_name()); - ShouldNotReachHere(); - } - - int i; - for (i=0; iat(i)); - if (interface_name == k->name()) { - return k; - } - } - - // interface_name is not specified by the "interfaces:" keyword. - print_specified_interfaces(); - error("The interface %s implemented by class %s does not match any of the specified interface IDs", - interface_name->as_klass_external_name(), _class_name); - ShouldNotReachHere(); - return nullptr; -} - InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) { Handle class_loader(current, class_loader_oop); return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader); @@ -861,6 +846,14 @@ void ClassListParser::parse_constant_pool_tag() { } } + if (SystemDictionaryShared::should_be_excluded(ik)) { + if (log_is_enabled(Warning, cds, resolve)) { + ResourceMark rm; + log_warning(cds, resolve)("Cannot aot-resolve constants for %s because it is excluded", ik->external_name()); + } + return; + } + if (preresolve_class) { AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list); } diff --git a/src/hotspot/share/cds/classListParser.hpp b/src/hotspot/share/cds/classListParser.hpp index 540e61335d0ad..1b059b4d85a4b 100644 --- a/src/hotspot/share/cds/classListParser.hpp +++ b/src/hotspot/share/cds/classListParser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,12 +137,10 @@ class ClassListParser : public StackObj { void print_diagnostic_info(outputStream* st, const char* msg, ...) ATTRIBUTE_PRINTF(3, 0); void constant_pool_resolution_warning(const char* msg, ...) ATTRIBUTE_PRINTF(2, 0); void error(const char* msg, ...) ATTRIBUTE_PRINTF(2, 0); + objArrayOop get_specified_interfaces(TRAPS); public: - static void parse_classlist(const char* classlist_path, ParseMode parse_mode, TRAPS) { - ClassListParser parser(classlist_path, parse_mode); - parser.parse(THREAD); - } + static void parse_classlist(const char* classlist_path, ParseMode parse_mode, TRAPS); static bool is_parsing_thread(); static ClassListParser* instance() { @@ -201,12 +199,6 @@ class ClassListParser : public StackObj { } bool is_loading_from_source(); - - // Look up the super or interface of the current class being loaded - // (in this->load_current_class()). - InstanceKlass* lookup_super_for_current_class(Symbol* super_name); - InstanceKlass* lookup_interface_for_current_class(Symbol* interface_name); - static void populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS); }; #endif // SHARE_CDS_CLASSLISTPARSER_HPP diff --git a/src/hotspot/share/cds/classListWriter.cpp b/src/hotspot/share/cds/classListWriter.cpp index 78a6857ff73a7..2a3513c45f5f4 100644 --- a/src/hotspot/share/cds/classListWriter.cpp +++ b/src/hotspot/share/cds/classListWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cds_globals.hpp" #include "cds/classListWriter.hpp" #include "cds/lambdaFormInvokers.inline.hpp" diff --git a/src/hotspot/share/cds/cppVtables.cpp b/src/hotspot/share/cds/cppVtables.cpp index 3de858d32997a..39849571015e1 100644 --- a/src/hotspot/share/cds/cppVtables.cpp +++ b/src/hotspot/share/cds/cppVtables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveUtils.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" @@ -259,7 +258,6 @@ intptr_t* CppVtables::get_archived_vtable(MetaspaceObj::Type msotype, address ob case MetaspaceObj::ConstantPoolCacheType: case MetaspaceObj::AnnotationsType: case MetaspaceObj::MethodCountersType: - case MetaspaceObj::SharedClassPathEntryType: case MetaspaceObj::RecordComponentType: // These have no vtables. break; diff --git a/src/hotspot/share/cds/dumpAllocStats.cpp b/src/hotspot/share/cds/dumpAllocStats.cpp index e88a77de7adb7..5587ac2fac82a 100644 --- a/src/hotspot/share/cds/dumpAllocStats.cpp +++ b/src/hotspot/share/cds/dumpAllocStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassLinker.hpp" #include "cds/dumpAllocStats.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.cpp b/src/hotspot/share/cds/dumpTimeClassInfo.cpp index 6ee18c17a57da..18136d6eeec66 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.cpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/dumpTimeClassInfo.inline.hpp" #include "cds/runTimeClassInfo.hpp" diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index c060601f1fb01..79ede224bb6e7 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,6 @@ class DumpTimeClassInfo: public CHeapObj { bool _excluded; bool _is_early_klass; bool _has_checked_exclusion; - bool _is_required_hidden_class; - bool _has_scanned_constant_pool; class DTLoaderConstraint { Symbol* _name; char _loader_type1; @@ -123,7 +121,7 @@ class DumpTimeClassInfo: public CHeapObj { InstanceKlass* _klass; InstanceKlass* _nest_host; bool _failed_verification; - bool _is_archived_lambda_proxy; + bool _is_registered_lambda_proxy; int _id; int _clsfile_size; int _clsfile_crc32; @@ -136,10 +134,8 @@ class DumpTimeClassInfo: public CHeapObj { _klass = nullptr; _nest_host = nullptr; _failed_verification = false; - _is_archived_lambda_proxy = false; + _is_registered_lambda_proxy = false; _has_checked_exclusion = false; - _is_required_hidden_class = false; - _has_scanned_constant_pool = false; _id = -1; _clsfile_size = -1; _clsfile_crc32 = -1; @@ -217,11 +213,6 @@ class DumpTimeClassInfo: public CHeapObj { InstanceKlass* nest_host() const { return _nest_host; } void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; } - bool is_required_hidden_class() const { return _is_required_hidden_class; } - void set_is_required_hidden_class() { _is_required_hidden_class = true; } - bool has_scanned_constant_pool() const { return _has_scanned_constant_pool; } - void set_has_scanned_constant_pool() { _has_scanned_constant_pool = true; } - size_t runtime_info_bytesize() const; }; diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index f102282f68201..4ccf23ff91c9d 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,9 @@ * */ -#include "precompiled.hpp" +#include "cds/aotArtifactFinder.hpp" #include "cds/aotClassLinker.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/archiveUtils.inline.hpp" @@ -89,7 +90,7 @@ class DynamicArchiveBuilder : public ArchiveBuilder { void sort_methods(); void sort_methods(InstanceKlass* ik) const; void remark_pointers_for_instance_klass(InstanceKlass* k, bool should_mark) const; - void write_archive(char* serialized_data); + void write_archive(char* serialized_data, AOTClassLocationConfig* cl_config); void gather_array_klasses(); public: @@ -112,7 +113,6 @@ class DynamicArchiveBuilder : public ArchiveBuilder { // Block concurrent class unloading from changing the _dumptime_table MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); - SystemDictionaryShared::find_all_archivable_classes(); if (SystemDictionaryShared::is_dumptime_table_empty()) { log_warning(cds, dynamic)("There is no class to be included in the dynamic archive."); @@ -133,14 +133,13 @@ class DynamicArchiveBuilder : public ArchiveBuilder { dump_ro_metadata(); relocate_metaspaceobj_embedded_pointers(); - verify_estimate_size(_estimated_metaspaceobj_bytes, "MetaspaceObjs"); - sort_methods(); log_info(cds)("Make classes shareable"); make_klasses_shareable(); char* serialized_data; + AOTClassLocationConfig* cl_config; { // Write the symbol table and system dictionaries to the RO space. // Note that these tables still point to the *original* objects, so @@ -151,6 +150,7 @@ class DynamicArchiveBuilder : public ArchiveBuilder { ArchiveBuilder::OtherROAllocMark mark; SystemDictionaryShared::write_to_archive(false); + cl_config = AOTClassLocationConfig::dumptime()->write_to_archive(); DynamicArchive::dump_array_klasses(); AOTClassLinker::write_to_archive(); @@ -159,14 +159,12 @@ class DynamicArchiveBuilder : public ArchiveBuilder { ArchiveBuilder::serialize_dynamic_archivable_items(&wc); } - verify_estimate_size(_estimated_hashtable_bytes, "Hashtables"); - log_info(cds)("Adjust lambda proxy class dictionary"); SystemDictionaryShared::adjust_lambda_proxy_class_dictionary(); relocate_to_requested(); - write_archive(serialized_data); + write_archive(serialized_data, cl_config); release_header(); DynamicArchive::post_dump(); @@ -177,7 +175,7 @@ class DynamicArchiveBuilder : public ArchiveBuilder { } virtual void iterate_roots(MetaspaceClosure* it) { - FileMapInfo::metaspace_pointers_do(it); + AOTArtifactFinder::all_cached_classes_do(it); SystemDictionaryShared::dumptime_classes_do(it); iterate_primitive_array_klasses(it); } @@ -339,8 +337,8 @@ void DynamicArchiveBuilder::remark_pointers_for_instance_klass(InstanceKlass* k, } } -void DynamicArchiveBuilder::write_archive(char* serialized_data) { - _header->set_shared_path_table(FileMapInfo::shared_path_table().table()); +void DynamicArchiveBuilder::write_archive(char* serialized_data, AOTClassLocationConfig* cl_config) { + _header->set_class_location_config(cl_config); _header->set_serialized_data(serialized_data); FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); @@ -355,7 +353,7 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) { size_t file_size = pointer_delta(top, base, sizeof(char)); log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT - " [" UINT32_FORMAT " bytes header, " SIZE_FORMAT " bytes total]", + " [" UINT32_FORMAT " bytes header, %zu bytes total]", p2i(base), p2i(top), _header->header_size(), file_size); log_info(cds, dynamic)("%d klasses; %d symbols", klasses()->length(), symbols()->length()); @@ -393,8 +391,7 @@ class VM_PopulateDynamicDumpSharedSpace: public VM_GC_Sync_Operation { log_warning(cds)("This archive was created with AllowArchivingWithJavaAgent. It should be used " "for testing purposes only and should not be used in a production environment"); } - FileMapInfo::check_nonempty_dir_in_shared_path_table(); - + AOTClassLocationConfig::dumptime_check_nonempty_dirs(); _builder.doit(); } ~VM_PopulateDynamicDumpSharedSpace() { @@ -509,12 +506,9 @@ void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) JavaThread* THREAD = current; // For TRAPS processing related to link_shared_classes MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD); if (!HAS_PENDING_EXCEPTION) { - // copy shared path table to saved. - if (!HAS_PENDING_EXCEPTION) { - VM_PopulateDynamicDumpSharedSpace op(archive_name); - VMThread::execute(&op); - return; - } + VM_PopulateDynamicDumpSharedSpace op(archive_name); + VMThread::execute(&op); + return; } // One of the prepatory steps failed diff --git a/src/hotspot/share/cds/dynamicArchive.hpp b/src/hotspot/share/cds/dynamicArchive.hpp index 479e7daa153db..eb5fd5f9aba8d 100644 --- a/src/hotspot/share/cds/dynamicArchive.hpp +++ b/src/hotspot/share/cds/dynamicArchive.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ #include "classfile/compactHashtable.hpp" #include "memory/allStatic.hpp" #include "memory/memRegion.hpp" -#include "memory/virtualspace.hpp" #include "oops/array.hpp" #include "oops/oop.hpp" #include "utilities/exceptions.hpp" diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index c87081d9d14e6..7db8e78743e20 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.inline.hpp" #include "cds/archiveHeapWriter.hpp" @@ -157,7 +157,6 @@ void FileMapInfo::populate_header(size_t core_region_alignment) { size_t header_size; size_t base_archive_name_size = 0; size_t base_archive_name_offset = 0; - size_t longest_common_prefix_size = 0; if (is_static()) { c_header_size = sizeof(FileMapHeader); header_size = c_header_size; @@ -174,30 +173,24 @@ void FileMapInfo::populate_header(size_t core_region_alignment) { base_archive_name_offset = c_header_size; } } - ResourceMark rm; - GrowableArray* app_cp_array = create_dumptime_app_classpath_array(); - int len = app_cp_array->length(); - longest_common_prefix_size = longest_common_app_classpath_prefix_len(len, app_cp_array); _header = (FileMapHeader*)os::malloc(header_size, mtInternal); memset((void*)_header, 0, header_size); _header->populate(this, core_region_alignment, header_size, base_archive_name_size, - base_archive_name_offset, - longest_common_prefix_size); + base_archive_name_offset); } void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, size_t header_size, size_t base_archive_name_size, - size_t base_archive_name_offset, size_t common_app_classpath_prefix_size) { + size_t base_archive_name_offset) { // 1. We require _generic_header._magic to be at the beginning of the file // 2. FileMapHeader also assumes that _generic_header is at the beginning of the file assert(offset_of(FileMapHeader, _generic_header) == 0, "must be"); set_header_size((unsigned int)header_size); set_base_archive_name_offset((unsigned int)base_archive_name_offset); set_base_archive_name_size((unsigned int)base_archive_name_size); - set_common_app_classpath_prefix_size((unsigned int)common_app_classpath_prefix_size); set_magic(CDSConfig::is_dumping_dynamic_archive() ? CDS_DYNAMIC_ARCHIVE_MAGIC : CDS_ARCHIVE_MAGIC); set_version(CURRENT_CDS_ARCHIVE_VERSION); @@ -237,22 +230,12 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, // JVM version string ... changes on each build. get_header_version(_jvm_ident); - _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index(); - _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index(); - _max_used_path_index = ClassLoaderExt::max_used_path_index(); - _num_module_paths = ClassLoader::num_module_path_entries(); - _verify_local = BytecodeVerificationLocal; _verify_remote = BytecodeVerificationRemote; - _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes(); - _has_non_jar_in_classpath = ClassLoaderExt::has_non_jar_in_classpath(); + _has_platform_or_app_classes = AOTClassLocationConfig::dumptime()->has_platform_or_app_classes(); _requested_base_address = (char*)SharedBaseAddress; _mapped_base_address = (char*)SharedBaseAddress; _allow_archiving_with_java_agent = AllowArchivingWithJavaAgent; - - if (!CDSConfig::is_dumping_dynamic_archive()) { - set_shared_path_table(info->_shared_path_table); - } } void FileMapHeader::copy_base_archive_name(const char* archive) { @@ -269,7 +252,6 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- crc: 0x%08x", crc()); st->print_cr("- version: 0x%x", version()); st->print_cr("- header_size: " UINT32_FORMAT, header_size()); - st->print_cr("- common_app_classpath_size: " UINT32_FORMAT, common_app_classpath_prefix_size()); st->print_cr("- base_archive_name_offset: " UINT32_FORMAT, base_archive_name_offset()); st->print_cr("- base_archive_name_size: " UINT32_FORMAT, base_archive_name_size()); @@ -279,42 +261,37 @@ void FileMapHeader::print(outputStream* st) { } st->print_cr("============ end regions ======== "); - st->print_cr("- core_region_alignment: " SIZE_FORMAT, _core_region_alignment); + st->print_cr("- core_region_alignment: %zu", _core_region_alignment); st->print_cr("- obj_alignment: %d", _obj_alignment); st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base)); st->print_cr("- narrow_oop_shift %d", _narrow_oop_shift); st->print_cr("- compact_strings: %d", _compact_strings); st->print_cr("- compact_headers: %d", _compact_headers); - st->print_cr("- max_heap_size: " UINTX_FORMAT, _max_heap_size); + st->print_cr("- max_heap_size: %zu", _max_heap_size); st->print_cr("- narrow_oop_mode: %d", _narrow_oop_mode); st->print_cr("- compressed_oops: %d", _compressed_oops); st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs); st->print_cr("- narrow_klass_pointer_bits: %d", _narrow_klass_pointer_bits); st->print_cr("- narrow_klass_shift: %d", _narrow_klass_shift); - st->print_cr("- cloned_vtables_offset: " SIZE_FORMAT_X, _cloned_vtables_offset); - st->print_cr("- early_serialized_data_offset: " SIZE_FORMAT_X, _early_serialized_data_offset); - st->print_cr("- serialized_data_offset: " SIZE_FORMAT_X, _serialized_data_offset); + st->print_cr("- cloned_vtables_offset: 0x%zx", _cloned_vtables_offset); + st->print_cr("- early_serialized_data_offset: 0x%zx", _early_serialized_data_offset); + st->print_cr("- serialized_data_offset: 0x%zx", _serialized_data_offset); st->print_cr("- jvm_ident: %s", _jvm_ident); - st->print_cr("- shared_path_table_offset: " SIZE_FORMAT_X, _shared_path_table_offset); - st->print_cr("- app_class_paths_start_index: %d", _app_class_paths_start_index); - st->print_cr("- app_module_paths_start_index: %d", _app_module_paths_start_index); - st->print_cr("- num_module_paths: %d", _num_module_paths); - st->print_cr("- max_used_path_index: %d", _max_used_path_index); + st->print_cr("- class_location_config_offset: 0x%zx", _class_location_config_offset); st->print_cr("- verify_local: %d", _verify_local); st->print_cr("- verify_remote: %d", _verify_remote); st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes); - st->print_cr("- has_non_jar_in_classpath: %d", _has_non_jar_in_classpath); st->print_cr("- requested_base_address: " INTPTR_FORMAT, p2i(_requested_base_address)); st->print_cr("- mapped_base_address: " INTPTR_FORMAT, p2i(_mapped_base_address)); st->print_cr("- heap_root_segments.roots_count: %d" , _heap_root_segments.roots_count()); - st->print_cr("- heap_root_segments.base_offset: " SIZE_FORMAT_X, _heap_root_segments.base_offset()); - st->print_cr("- heap_root_segments.count: " SIZE_FORMAT, _heap_root_segments.count()); + st->print_cr("- heap_root_segments.base_offset: 0x%zx", _heap_root_segments.base_offset()); + st->print_cr("- heap_root_segments.count: %zu", _heap_root_segments.count()); st->print_cr("- heap_root_segments.max_size_elems: %d", _heap_root_segments.max_size_in_elems()); st->print_cr("- heap_root_segments.max_size_bytes: %d", _heap_root_segments.max_size_in_bytes()); - st->print_cr("- _heap_oopmap_start_pos: " SIZE_FORMAT, _heap_oopmap_start_pos); - st->print_cr("- _heap_ptrmap_start_pos: " SIZE_FORMAT, _heap_ptrmap_start_pos); - st->print_cr("- _rw_ptrmap_start_pos: " SIZE_FORMAT, _rw_ptrmap_start_pos); - st->print_cr("- _ro_ptrmap_start_pos: " SIZE_FORMAT, _ro_ptrmap_start_pos); + st->print_cr("- _heap_oopmap_start_pos: %zu", _heap_oopmap_start_pos); + st->print_cr("- _heap_ptrmap_start_pos: %zu", _heap_ptrmap_start_pos); + st->print_cr("- _rw_ptrmap_start_pos: %zu", _rw_ptrmap_start_pos); + st->print_cr("- _ro_ptrmap_start_pos: %zu", _ro_ptrmap_start_pos); st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent); st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling); st->print_cr("- has_full_module_graph %d", _has_full_module_graph); @@ -322,676 +299,23 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- has_archived_invokedynamic %d", _has_archived_invokedynamic); } -void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) { - _type = non_existent_entry; - set_name(path, CHECK); -} - -void SharedClassPathEntry::init(bool is_modules_image, - bool is_module_path, - ClassPathEntry* cpe, TRAPS) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - _timestamp = 0; - _filesize = 0; - _from_class_path_attr = false; - - struct stat st; - if (os::stat(cpe->name(), &st) == 0) { - if ((st.st_mode & S_IFMT) == S_IFDIR) { - _type = dir_entry; - } else { - // The timestamp of the modules_image is not checked at runtime. - if (is_modules_image) { - _type = modules_image_entry; - } else { - _type = jar_entry; - _timestamp = st.st_mtime; - _from_class_path_attr = cpe->from_class_path_attr(); - _is_multi_release = cpe->is_multi_release_jar(); - } - _filesize = st.st_size; - _is_module_path = is_module_path; - } - } else { - // The file/dir must exist, or it would not have been added - // into ClassLoader::classpath_entry(). - // - // If we can't access a jar file in the boot path, then we can't - // make assumptions about where classes get loaded from. - log_error(cds)("Unable to open file %s.", cpe->name()); - MetaspaceShared::unrecoverable_loading_error(); - } - - // No need to save the name of the module file, as it will be computed at run time - // to allow relocation of the JDK directory. - const char* name = is_modules_image ? "" : cpe->name(); - set_name(name, CHECK); -} - -void SharedClassPathEntry::set_name(const char* name, TRAPS) { - size_t len = strlen(name) + 1; - _name = MetadataFactory::new_array(ClassLoaderData::the_null_class_loader_data(), (int)len, CHECK); - strcpy(_name->data(), name); -} - -void SharedClassPathEntry::copy_from(SharedClassPathEntry* ent, ClassLoaderData* loader_data, TRAPS) { - assert(ent != nullptr, "sanity"); - _type = ent->_type; - _is_module_path = ent->_is_module_path; - _timestamp = ent->_timestamp; - _filesize = ent->_filesize; - _from_class_path_attr = ent->_from_class_path_attr; - set_name(ent->name(), CHECK); - - if (ent->is_jar() && ent->manifest() != nullptr) { - Array* buf = MetadataFactory::new_array(loader_data, - ent->manifest_size(), - CHECK); - char* p = (char*)(buf->data()); - memcpy(p, ent->manifest(), ent->manifest_size()); - set_manifest(buf); - } -} - -const char* SharedClassPathEntry::name() const { - if (CDSConfig::is_using_archive() && is_modules_image()) { - // In order to validate the runtime modules image file size against the archived - // size information, we need to obtain the runtime modules image path. The recorded - // dump time modules image path in the archive may be different from the runtime path - // if the JDK image has beed moved after generating the archive. - return ClassLoader::get_jrt_entry()->name(); - } else { - return _name->data(); - } -} - -bool SharedClassPathEntry::validate(bool is_class_path) const { +bool FileMapInfo::validate_class_location() { assert(CDSConfig::is_using_archive(), "runtime only"); - struct stat st; - const char* name = this->name(); - - bool ok = true; - log_info(class, path)("checking shared classpath entry: %s", name); - if (os::stat(name, &st) != 0 && is_class_path) { - // If the archived module path entry does not exist at runtime, it is not fatal - // (no need to invalid the shared archive) because the shared runtime visibility check - // filters out any archived module classes that do not have a matching runtime - // module path location. - log_warning(cds)("Required classpath entry does not exist: %s", name); - ok = false; - } else if (is_dir()) { - if (!os::dir_is_empty(name)) { - log_warning(cds)("directory is not empty: %s", name); - ok = false; - } - } else { - bool size_differs = _filesize != st.st_size; - bool time_differs = has_timestamp() && _timestamp != st.st_mtime; - if (time_differs || size_differs) { - ok = false; - if (PrintSharedArchiveAndExit) { - log_warning(cds)(time_differs ? "Timestamp mismatch" : "File size mismatch"); - } else { - const char* bad_file_msg = "This file is not the one used while building the shared archive file:"; - log_warning(cds)("%s %s", bad_file_msg, name); - if (!log_is_enabled(Info, cds)) { - log_warning(cds)("%s %s", bad_file_msg, name); - } - if (time_differs) { - log_warning(cds)("%s timestamp has changed.", name); - } - if (size_differs) { - log_warning(cds)("%s size has changed.", name); - } - } - } - } - - if (PrintSharedArchiveAndExit && !ok) { - // If PrintSharedArchiveAndExit is enabled, don't report failure to the - // caller. Please see above comments for more details. - ok = true; - MetaspaceShared::set_archive_loading_failed(); - } - return ok; -} - -bool SharedClassPathEntry::check_non_existent() const { - assert(_type == non_existent_entry, "must be"); - log_info(class, path)("should be non-existent: %s", name()); - struct stat st; - if (os::stat(name(), &st) != 0) { - log_info(class, path)("ok"); - return true; // file doesn't exist - } else { - return false; - } -} - -void SharedClassPathEntry::metaspace_pointers_do(MetaspaceClosure* it) { - it->push(&_name); - it->push(&_manifest); -} - -void SharedPathTable::metaspace_pointers_do(MetaspaceClosure* it) { - it->push(&_entries); -} - -void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, TRAPS) { - const int num_entries = - ClassLoader::num_boot_classpath_entries() + - ClassLoader::num_app_classpath_entries() + - ClassLoader::num_module_path_entries() + - FileMapInfo::num_non_existent_class_paths(); - _entries = MetadataFactory::new_array(loader_data, num_entries, CHECK); - for (int i = 0; i < num_entries; i++) { - SharedClassPathEntry* ent = - new (loader_data, SharedClassPathEntry::size(), MetaspaceObj::SharedClassPathEntryType, THREAD) SharedClassPathEntry; - _entries->at_put(i, ent); - } -} - -void FileMapInfo::allocate_shared_path_table(TRAPS) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - - ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); - ClassPathEntry* jrt = ClassLoader::get_jrt_entry(); - - assert(jrt != nullptr, - "No modular java runtime image present when allocating the CDS classpath entry table"); - - _shared_path_table.dumptime_init(loader_data, CHECK); - - // 1. boot class path - int i = 0; - i = add_shared_classpaths(i, "boot", jrt, CHECK); - i = add_shared_classpaths(i, "app", ClassLoader::app_classpath_entries(), CHECK); - i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), CHECK); - - for (int x = 0; x < num_non_existent_class_paths(); x++, i++) { - const char* path = _non_existent_class_paths->at(x); - shared_path(i)->init_as_non_existent(path, CHECK); - } - - assert(i == _shared_path_table.size(), "number of shared path entry mismatch"); -} - -int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS) { - while (cpe != nullptr) { - bool is_jrt = (cpe == ClassLoader::get_jrt_entry()); - bool is_module_path = i >= ClassLoaderExt::app_module_paths_start_index(); - const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir")); - log_info(class, path)("add %s shared path (%s) %s", which, type, cpe->name()); - SharedClassPathEntry* ent = shared_path(i); - ent->init(is_jrt, is_module_path, cpe, CHECK_0); - if (cpe->is_jar_file()) { - update_jar_manifest(cpe, ent, CHECK_0); - } - if (is_jrt) { - cpe = ClassLoader::get_next_boot_classpath_entry(cpe); - } else { - cpe = cpe->next(); - } - i++; - } - - return i; -} - -void FileMapInfo::check_nonempty_dir_in_shared_path_table() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - - bool has_nonempty_dir = false; - - int last = _shared_path_table.size() - 1; - if (last > ClassLoaderExt::max_used_path_index()) { - // no need to check any path beyond max_used_path_index - last = ClassLoaderExt::max_used_path_index(); - } - - for (int i = 0; i <= last; i++) { - SharedClassPathEntry *e = shared_path(i); - if (e->is_dir()) { - const char* path = e->name(); - if (!os::dir_is_empty(path)) { - log_error(cds)("Error: non-empty directory '%s'", path); - has_nonempty_dir = true; - } - } - } - - if (has_nonempty_dir) { - ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", nullptr); - } -} - -void FileMapInfo::record_non_existent_class_path_entry(const char* path) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - log_info(class, path)("non-existent Class-Path entry %s", path); - if (_non_existent_class_paths == nullptr) { - _non_existent_class_paths = new (mtClass) GrowableArray(10, mtClass); - } - _non_existent_class_paths->append(os::strdup(path)); -} - -int FileMapInfo::num_non_existent_class_paths() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - if (_non_existent_class_paths != nullptr) { - return _non_existent_class_paths->length(); - } else { - return 0; - } -} - -int FileMapInfo::get_module_shared_path_index(Symbol* location) { - if (location->starts_with("jrt:", 4) && get_number_of_shared_paths() > 0) { - assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image"); - return 0; - } - - if (ClassLoaderExt::app_module_paths_start_index() >= get_number_of_shared_paths()) { - // The archive(s) were created without --module-path option - return -1; - } - - if (!location->starts_with("file:", 5)) { - return -1; - } - - // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table() - ResourceMark rm; - const char* file = ClassLoader::uri_to_path(location->as_C_string()); - for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) { - SharedClassPathEntry* ent = shared_path(i); - if (!ent->is_non_existent()) { - assert(ent->in_named_module(), "must be"); - bool cond = strcmp(file, ent->name()) == 0; - log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i, - location->as_C_string(), ent->name(), cond ? "same" : "different"); - if (cond) { - return i; - } - } - } - - return -1; -} - -class ManifestStream: public ResourceObj { - private: - u1* _buffer_start; // Buffer bottom - u1* _buffer_end; // Buffer top (one past last element) - u1* _current; // Current buffer position - - public: - // Constructor - ManifestStream(u1* buffer, int length) : _buffer_start(buffer), - _current(buffer) { - _buffer_end = buffer + length; - } - - static bool is_attr(u1* attr, const char* name) { - return strncmp((const char*)attr, name, strlen(name)) == 0; - } - - static char* copy_attr(u1* value, size_t len) { - char* buf = NEW_RESOURCE_ARRAY(char, len + 1); - strncpy(buf, (char*)value, len); - buf[len] = 0; - return buf; - } -}; - -void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) { - ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); - ResourceMark rm(THREAD); - jint manifest_size; - - assert(cpe->is_jar_file() && ent->is_jar(), "the shared class path entry is not a JAR file"); - char* manifest = ClassLoaderExt::read_manifest(THREAD, cpe, &manifest_size); - if (manifest != nullptr) { - ManifestStream* stream = new ManifestStream((u1*)manifest, - manifest_size); - // Copy the manifest into the shared archive - manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size); - Array* buf = MetadataFactory::new_array(loader_data, - manifest_size, - CHECK); - char* p = (char*)(buf->data()); - memcpy(p, manifest, manifest_size); - ent->set_manifest(buf); - } -} - -char* FileMapInfo::skip_first_path_entry(const char* path) { - size_t path_sep_len = strlen(os::path_separator()); - char* p = strstr((char*)path, os::path_separator()); - if (p != nullptr) { - debug_only( { - size_t image_name_len = strlen(MODULES_IMAGE_NAME); - assert(strncmp(p - image_name_len, MODULES_IMAGE_NAME, image_name_len) == 0, - "first entry must be the modules image"); - } ); - p += path_sep_len; - } else { - debug_only( { - assert(ClassLoader::string_ends_with(path, MODULES_IMAGE_NAME), - "first entry must be the modules image"); - } ); - } - return p; -} - -int FileMapInfo::num_paths(const char* path) { - if (path == nullptr) { - return 0; - } - int npaths = 1; - char* p = (char*)path; - while (p != nullptr) { - char* prev = p; - p = strstr((char*)p, os::path_separator()); - if (p != nullptr) { - p++; - // don't count empty path - if ((p - prev) > 1) { - npaths++; - } - } - } - return npaths; -} - -// Returns true if a path within the paths exists and has non-zero size. -bool FileMapInfo::check_paths_existence(const char* paths) { - ClasspathStream cp_stream(paths); - bool exist = false; - struct stat st; - while (cp_stream.has_next()) { - const char* path = cp_stream.get_next(); - if (os::stat(path, &st) == 0 && st.st_size > 0) { - exist = true; - break; - } - } - return exist; -} - -GrowableArray* FileMapInfo::create_dumptime_app_classpath_array() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - GrowableArray* path_array = new GrowableArray(10); - ClassPathEntry* cpe = ClassLoader::app_classpath_entries(); - while (cpe != nullptr) { - path_array->append(cpe->name()); - cpe = cpe->next(); - } - return path_array; -} - -GrowableArray* FileMapInfo::create_path_array(const char* paths) { - GrowableArray* path_array = new GrowableArray(10); - JavaThread* current = JavaThread::current(); - ClasspathStream cp_stream(paths); - bool non_jar_in_cp = header()->has_non_jar_in_classpath(); - while (cp_stream.has_next()) { - const char* path = cp_stream.get_next(); - if (!non_jar_in_cp) { - struct stat st; - if (os::stat(path, &st) == 0) { - path_array->append(path); - } + AOTClassLocationConfig* config = header()->class_location_config(); + bool has_extra_module_paths = false; + if (!config->validate(header()->has_aot_linked_classes(), &has_extra_module_paths)) { + if (PrintSharedArchiveAndExit) { + MetaspaceShared::set_archive_loading_failed(); + return true; } else { - const char* canonical_path = ClassLoader::get_canonical_path(path, current); - if (canonical_path != nullptr) { - char* error_msg = nullptr; - jzfile* zip = ClassLoader::open_zip_file(canonical_path, &error_msg, current); - if (zip != nullptr && error_msg == nullptr) { - path_array->append(path); - } - } - } - } - return path_array; -} - -bool FileMapInfo::classpath_failure(const char* msg, const char* name) { - ClassLoader::trace_class_path(msg, name); - if (PrintSharedArchiveAndExit) { - MetaspaceShared::set_archive_loading_failed(); - } - return false; -} - -unsigned int FileMapInfo::longest_common_app_classpath_prefix_len(int num_paths, - GrowableArray* rp_array) { - if (num_paths == 0) { - return 0; - } - unsigned int pos; - for (pos = 0; ; pos++) { - for (int i = 0; i < num_paths; i++) { - if (rp_array->at(i)[pos] != '\0' && rp_array->at(i)[pos] == rp_array->at(0)[pos]) { - continue; - } - // search backward for the pos before the file separator char - while (pos > 0) { - if (rp_array->at(0)[--pos] == *os::file_separator()) { - return pos + 1; - } - } - return 0; - } - } - return 0; -} - -bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray* rp_array, - unsigned int dumptime_prefix_len, unsigned int runtime_prefix_len) { - int i = 0; - int j = shared_path_start_idx; - while (i < num_paths) { - while (shared_path(j)->from_class_path_attr()) { - // shared_path(j) was expanded from the JAR file attribute "Class-Path:" - // during dump time. It's not included in the -classpath VM argument. - j++; - } - assert(strlen(shared_path(j)->name()) > (size_t)dumptime_prefix_len, "sanity"); - const char* dumptime_path = shared_path(j)->name() + dumptime_prefix_len; - assert(strlen(rp_array->at(i)) > (size_t)runtime_prefix_len, "sanity"); - const char* runtime_path = rp_array->at(i) + runtime_prefix_len; - if (!os::same_files(dumptime_path, runtime_path)) { return false; } - i++; - j++; - } - return true; -} - -bool FileMapInfo::validate_boot_class_paths() { - // - // - Archive contains boot classes only - relaxed boot path check: - // Extra path elements appended to the boot path at runtime are allowed. - // - // - Archive contains application or platform classes - strict boot path check: - // Validate the entire runtime boot path, which must be compatible - // with the dump time boot path. Appending boot path at runtime is not - // allowed. - // - - // The first entry in boot path is the modules_image (guaranteed by - // ClassLoader::setup_boot_search_path()). Skip the first entry. The - // path of the runtime modules_image may be different from the dump - // time path (e.g. the JDK image is copied to a different location - // after generating the shared archive), which is acceptable. For most - // common cases, the dump time boot path might contain modules_image only. - char* runtime_boot_path = Arguments::get_boot_class_path(); - char* rp = skip_first_path_entry(runtime_boot_path); - assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image"); - int dp_len = header()->app_class_paths_start_index() - 1; // ignore the first path to the module image - bool match = true; - - bool relaxed_check = !header()->has_platform_or_app_classes(); - if (dp_len == 0 && rp == nullptr) { - return true; // ok, both runtime and dump time boot paths have modules_images only - } else if (dp_len == 0 && rp != nullptr) { - if (relaxed_check) { - return true; // ok, relaxed check, runtime has extra boot append path entries - } else { - ResourceMark rm; - if (check_paths_existence(rp)) { - // If a path exists in the runtime boot paths, it is considered a mismatch - // since there's no boot path specified during dump time. - match = false; - } - } - } else if (dp_len > 0 && rp != nullptr) { - int num; - ResourceMark rm; - GrowableArray* rp_array = create_path_array(rp); - int rp_len = rp_array->length(); - if (rp_len >= dp_len) { - if (relaxed_check) { - // only check the leading entries in the runtime boot path, up to - // the length of the dump time boot path - num = dp_len; - } else { - // check the full runtime boot path, must match with dump time - num = rp_len; - } - match = check_paths(1, num, rp_array, 0, 0); - } else { - // create_path_array() ignores non-existing paths. Although the dump time and runtime boot classpath lengths - // are the same initially, after the call to create_path_array(), the runtime boot classpath length could become - // shorter. We consider boot classpath mismatch in this case. - match = false; - } - } - - if (!match) { - // The paths are different - return classpath_failure("[BOOT classpath mismatch, actual =", runtime_boot_path); - } - return true; -} - -bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) { - const char *appcp = Arguments::get_appclasspath(); - assert(appcp != nullptr, "null app classpath"); - int rp_len = num_paths(appcp); - bool match = false; - if (rp_len < shared_app_paths_len) { - return classpath_failure("Run time APP classpath is shorter than the one at dump time: ", appcp); - } - if (shared_app_paths_len != 0 && rp_len != 0) { - // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar. - ResourceMark rm; - GrowableArray* rp_array = create_path_array(appcp); - if (rp_array->length() == 0) { - // None of the jar file specified in the runtime -cp exists. - return classpath_failure("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp); - } - if (rp_array->length() < shared_app_paths_len) { - // create_path_array() ignores non-existing paths. Although the dump time and runtime app classpath lengths - // are the same initially, after the call to create_path_array(), the runtime app classpath length could become - // shorter. We consider app classpath mismatch in this case. - return classpath_failure("[APP classpath mismatch, actual: -Djava.class.path=", appcp); - } - - // Handling of non-existent entries in the classpath: we eliminate all the non-existent - // entries from both the dump time classpath (ClassLoader::update_class_path_entry_list) - // and the runtime classpath (FileMapInfo::create_path_array), and check the remaining - // entries. E.g.: - // - // dump : -cp a.jar:NE1:NE2:b.jar -> a.jar:b.jar -> recorded in archive. - // run 1: -cp NE3:a.jar:NE4:b.jar -> a.jar:b.jar -> matched - // run 2: -cp x.jar:NE4:b.jar -> x.jar:b.jar -> mismatched - - int j = header()->app_class_paths_start_index(); - match = check_paths(j, shared_app_paths_len, rp_array, 0, 0); - if (!match) { - // To facilitate app deployment, we allow the JAR files to be moved *together* to - // a different location, as long as they are still stored under the same directory - // structure. E.g., the following is OK. - // java -Xshare:dump -cp /a/Foo.jar:/a/b/Bar.jar ... - // java -Xshare:auto -cp /x/y/Foo.jar:/x/y/b/Bar.jar ... - unsigned int dumptime_prefix_len = header()->common_app_classpath_prefix_size(); - unsigned int runtime_prefix_len = longest_common_app_classpath_prefix_len(shared_app_paths_len, rp_array); - if (dumptime_prefix_len != 0 || runtime_prefix_len != 0) { - log_info(class, path)("LCP length for app classpath (dumptime: %u, runtime: %u)", - dumptime_prefix_len, runtime_prefix_len); - match = check_paths(j, shared_app_paths_len, rp_array, - dumptime_prefix_len, runtime_prefix_len); - } - if (!match) { - return classpath_failure("[APP classpath mismatch, actual: -Djava.class.path=", appcp); - } - } - } - return true; -} - -void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) { - LogTarget(Info, class, path) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("%s", msg); - const char* prefix = ""; - for (int i = start_idx; i < end_idx; i++) { - ls.print("%s%s", prefix, shared_path(i)->name()); - prefix = os::path_separator(); - } - ls.cr(); - } -} - -void FileMapInfo::extract_module_paths(const char* runtime_path, GrowableArray* module_paths) { - GrowableArray* path_array = create_path_array(runtime_path); - int num_paths = path_array->length(); - for (int i = 0; i < num_paths; i++) { - const char* name = path_array->at(i); - ClassLoaderExt::extract_jar_files_from_path(name, module_paths); - } - // module paths are stored in sorted order in the CDS archive. - module_paths->sort(ClassLoaderExt::compare_module_names); -} - -bool FileMapInfo::check_module_paths() { - const char* runtime_path = Arguments::get_property("jdk.module.path"); - int archived_num_module_paths = header()->num_module_paths(); - if (runtime_path == nullptr && archived_num_module_paths == 0) { - return true; - } - if ((runtime_path == nullptr && archived_num_module_paths > 0) || - (runtime_path != nullptr && archived_num_module_paths == 0)) { - return false; - } - ResourceMark rm; - GrowableArray* module_paths = new GrowableArray(3); - extract_module_paths(runtime_path, module_paths); - int num_paths = module_paths->length(); - if (num_paths != archived_num_module_paths) { - return false; } - return check_paths(header()->app_module_paths_start_index(), num_paths, module_paths, 0, 0); -} - -bool FileMapInfo::validate_shared_path_table() { - assert(CDSConfig::is_using_archive(), "runtime only"); - - _validating_shared_path_table = true; - // Load the shared path table info from the archive header - _shared_path_table = header()->shared_path_table(); - - bool matched_module_paths = true; - if (CDSConfig::is_dumping_dynamic_archive() || header()->has_full_module_graph()) { - matched_module_paths = check_module_paths(); - } - if (header()->has_full_module_graph() && !matched_module_paths) { + if (header()->has_full_module_graph() && has_extra_module_paths) { CDSConfig::stop_using_optimized_module_handling(); - log_info(cds)("optimized module handling: disabled because of mismatched module paths"); + log_info(cds)("optimized module handling: disabled because extra module path(s) are specified"); } if (CDSConfig::is_dumping_dynamic_archive()) { @@ -999,17 +323,13 @@ bool FileMapInfo::validate_shared_path_table() { // or a simple base archive. // If the base layer archive contains additional path component besides // the runtime image and the -cp, dynamic dumping is disabled. - // - // When dynamic archiving is enabled, the _shared_path_table is overwritten - // to include the application path and stored in the top layer archive. - assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image"); - if (header()->app_class_paths_start_index() > 1) { + if (config->num_boot_classpaths() > 0) { CDSConfig::disable_dumping_dynamic_archive(); log_warning(cds)( "Dynamic archiving is disabled because base layer archive has appended boot classpath"); } - if (header()->num_module_paths() > 0) { - if (!matched_module_paths) { + if (config->num_module_paths() > 0) { + if (has_extra_module_paths) { CDSConfig::disable_dumping_dynamic_archive(); log_warning(cds)( "Dynamic archiving is disabled because base layer archive has a different module path"); @@ -1017,68 +337,11 @@ bool FileMapInfo::validate_shared_path_table() { } } - log_paths("Expecting BOOT path=", 0, header()->app_class_paths_start_index()); - log_paths("Expecting -Djava.class.path=", header()->app_class_paths_start_index(), header()->app_module_paths_start_index()); - - int module_paths_start_index = header()->app_module_paths_start_index(); - int shared_app_paths_len = 0; - - // validate the path entries up to the _max_used_path_index - for (int i=0; i < header()->max_used_path_index() + 1; i++) { - if (i < module_paths_start_index) { - if (shared_path(i)->validate()) { - // Only count the app class paths not from the "Class-path" attribute of a jar manifest. - if (!shared_path(i)->from_class_path_attr() && i >= header()->app_class_paths_start_index()) { - shared_app_paths_len++; - } - log_info(class, path)("ok"); - } else { - if (_dynamic_archive_info != nullptr && _dynamic_archive_info->_is_static) { - assert(!CDSConfig::is_using_archive(), "UseSharedSpaces should be disabled"); - } - return false; - } - } else if (i >= module_paths_start_index) { - if (shared_path(i)->validate(false /* not a class path entry */)) { - log_info(class, path)("ok"); - } else { - if (_dynamic_archive_info != nullptr && _dynamic_archive_info->_is_static) { - assert(!CDSConfig::is_using_archive(), "UseSharedSpaces should be disabled"); - } - return false; - } - } - } - - if (header()->max_used_path_index() == 0) { - // default archive only contains the module image in the bootclasspath - assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image"); - } else { - if (!validate_boot_class_paths() || !validate_app_class_paths(shared_app_paths_len)) { - const char* mismatch_msg = "shared class paths mismatch"; - const char* hint_msg = log_is_enabled(Info, class, path) ? - "" : " (hint: enable -Xlog:class+path=info to diagnose the failure)"; - if (RequireSharedSpaces) { - log_error(cds)("%s%s", mismatch_msg, hint_msg); - MetaspaceShared::unrecoverable_loading_error(); - } else { - log_warning(cds)("%s%s", mismatch_msg, hint_msg); - } - return false; - } - } - - if (!validate_non_existent_class_paths()) { - return false; - } - - _validating_shared_path_table = false; - #if INCLUDE_JVMTI if (_classpath_entries_for_jvmti != nullptr) { os::free(_classpath_entries_for_jvmti); } - size_t sz = sizeof(ClassPathEntry*) * get_number_of_shared_paths(); + size_t sz = sizeof(ClassPathEntry*) * AOTClassLocationConfig::runtime()->length(); _classpath_entries_for_jvmti = (ClassPathEntry**)os::malloc(sz, mtClass); memset((void*)_classpath_entries_for_jvmti, 0, sz); #endif @@ -1086,34 +349,6 @@ bool FileMapInfo::validate_shared_path_table() { return true; } -bool FileMapInfo::validate_non_existent_class_paths() { - // All of the recorded non-existent paths came from the Class-Path: attribute from the JAR - // files on the app classpath. If any of these are found to exist during runtime, - // it will change how classes are loading for the app loader. For safety, disable - // loading of archived platform/app classes (currently there's no way to disable just the - // app classes). - - assert(CDSConfig::is_using_archive(), "runtime only"); - for (int i = header()->app_module_paths_start_index() + header()->num_module_paths(); - i < get_number_of_shared_paths(); - i++) { - SharedClassPathEntry* ent = shared_path(i); - if (!ent->check_non_existent()) { - if (header()->has_aot_linked_classes()) { - log_error(cds)("CDS archive has aot-linked classes. It cannot be used because the " - "file %s exists", ent->name()); - return false; - } else { - log_warning(cds)("Archived non-system classes are disabled because the " - "file %s exists", ent->name()); - header()->set_has_platform_or_app_classes(false); - } - } - } - - return true; -} - // A utility class for reading/validating the GenericCDSFileMapHeader portion of // a CDS archive's header. The file header of all CDS archives with versions from // CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION (12) are guaranteed to always start @@ -1366,19 +601,12 @@ bool FileMapInfo::init_from_file(int fd) { return false; } - int common_path_size = header()->common_app_classpath_prefix_size(); - if (common_path_size < 0) { - log_warning(cds)("common app classpath prefix len < 0"); - return false; - } - unsigned int base_offset = header()->base_archive_name_offset(); unsigned int name_size = header()->base_archive_name_size(); unsigned int header_size = header()->header_size(); if (base_offset != 0 && name_size != 0) { if (header_size != base_offset + name_size) { log_info(cds)("_header_size: " UINT32_FORMAT, header_size); - log_info(cds)("common_app_classpath_size: " UINT32_FORMAT, header()->common_app_classpath_prefix_size()); log_info(cds)("base_archive_name_size: " UINT32_FORMAT, header()->base_archive_name_size()); log_info(cds)("base_archive_name_offset: " UINT32_FORMAT, header()->base_archive_name_offset()); log_warning(cds)("The shared archive file has an incorrect header size."); @@ -1420,7 +648,7 @@ bool FileMapInfo::init_from_file(int fd) { void FileMapInfo::seek_to_position(size_t pos) { if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) { - log_error(cds)("Unable to seek to position " SIZE_FORMAT, pos); + log_error(cds)("Unable to seek to position %zu", pos); MetaspaceShared::unrecoverable_loading_error(); } } @@ -1508,6 +736,7 @@ void FileMapRegion::init(int region_index, size_t mapping_offset, size_t size, b _crc = crc; _mapped_from_file = false; _mapped_base = nullptr; + _in_reserved_space = false; } void FileMapRegion::init_oopmap(size_t offset, size_t size_in_bits) { @@ -1554,7 +783,7 @@ BitMapView FileMapInfo::bitmap_view(int region_index, bool is_oopmap) { bitmap_base += is_oopmap ? r->oopmap_offset() : r->ptrmap_offset(); size_t size_in_bits = is_oopmap ? r->oopmap_size_in_bits() : r->ptrmap_size_in_bits(); - log_debug(cds, reloc)("mapped %s relocation %smap @ " INTPTR_FORMAT " (" SIZE_FORMAT " bits)", + log_debug(cds, reloc)("mapped %s relocation %smap @ " INTPTR_FORMAT " (%zu bits)", region_name(region_index), is_oopmap ? "oop" : "ptr", p2i(bitmap_base), size_in_bits); @@ -1577,13 +806,13 @@ void FileMapRegion::print(outputStream* st, int region_index) { st->print_cr("- is_heap_region: %d", _is_heap_region); st->print_cr("- is_bitmap_region: %d", _is_bitmap_region); st->print_cr("- mapped_from_file: %d", _mapped_from_file); - st->print_cr("- file_offset: " SIZE_FORMAT_X, _file_offset); - st->print_cr("- mapping_offset: " SIZE_FORMAT_X, _mapping_offset); - st->print_cr("- used: " SIZE_FORMAT, _used); - st->print_cr("- oopmap_offset: " SIZE_FORMAT_X, _oopmap_offset); - st->print_cr("- oopmap_size_in_bits: " SIZE_FORMAT, _oopmap_size_in_bits); - st->print_cr("- ptrmap_offset: " SIZE_FORMAT_X, _ptrmap_offset); - st->print_cr("- ptrmap_size_in_bits: " SIZE_FORMAT, _ptrmap_size_in_bits); + st->print_cr("- file_offset: 0x%zx", _file_offset); + st->print_cr("- mapping_offset: 0x%zx", _mapping_offset); + st->print_cr("- used: %zu", _used); + st->print_cr("- oopmap_offset: 0x%zx", _oopmap_offset); + st->print_cr("- oopmap_size_in_bits: %zu", _oopmap_size_in_bits); + st->print_cr("- ptrmap_offset: 0x%zx", _ptrmap_offset); + st->print_cr("- ptrmap_size_in_bits: %zu", _ptrmap_size_in_bits); st->print_cr("- mapped_base: " INTPTR_FORMAT, p2i(_mapped_base)); } @@ -1601,7 +830,7 @@ void FileMapInfo::write_region(int region, char* base, size_t size, // This is an unused region (e.g., a heap region when !INCLUDE_CDS_JAVA_HEAP) requested_base = nullptr; } else if (HeapShared::is_heap_region(region)) { - assert(HeapShared::can_write(), "sanity"); + assert(CDSConfig::is_dumping_heap(), "sanity"); #if INCLUDE_CDS_JAVA_HEAP assert(!CDSConfig::is_dumping_dynamic_archive(), "must be"); requested_base = (char*)ArchiveHeapWriter::requested_address(); @@ -1622,7 +851,7 @@ void FileMapInfo::write_region(int region, char* base, size_t size, r->set_file_offset(_file_offset); int crc = ClassLoader::crc32(0, base, (jint)size); if (size > 0) { - log_info(cds)("Shared file region (%s) %d: " SIZE_FORMAT_W(8) + log_info(cds)("Shared file region (%s) %d: %8zu" " bytes, addr " INTPTR_FORMAT " file offset 0x%08" PRIxPTR " crc 0x%08x", region_name(region), region, size, p2i(requested_base), _file_offset, crc); @@ -1889,10 +1118,11 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba FileMapRegion* r = region_at(i); size_t size = r->used_aligned(); char *requested_addr = mapped_base_address + r->mapping_offset(); - assert(r->mapped_base() == nullptr, "must be not mapped yet"); + assert(!is_mapped(), "must be not mapped yet"); assert(requested_addr != nullptr, "must be specified"); r->set_mapped_from_file(false); + r->set_in_reserved_space(false); if (MetaspaceShared::use_windows_memory_mapping()) { // Windows cannot remap read-only shared memory to read-write when required for @@ -1917,7 +1147,6 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba return MAP_ARCHIVE_OTHER_FAILURE; // oom or I/O error. } else { assert(r->mapped_base() != nullptr, "must be initialized"); - return MAP_ARCHIVE_SUCCESS; } } else { // Note that this may either be a "fresh" mapping into unreserved address @@ -1939,9 +1168,16 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba r->set_mapped_from_file(true); r->set_mapped_base(requested_addr); + } - return MAP_ARCHIVE_SUCCESS; + if (rs.is_reserved()) { + char* mapped_base = r->mapped_base(); + assert(rs.base() <= mapped_base && mapped_base + size <= rs.end(), + PTR_FORMAT " <= " PTR_FORMAT " < " PTR_FORMAT " <= " PTR_FORMAT, + p2i(rs.base()), p2i(mapped_base), p2i(mapped_base + size), p2i(rs.end())); + r->set_in_reserved_space(rs.is_reserved()); } + return MAP_ARCHIVE_SUCCESS; } // The return value is the location of the archive relocation bitmap. @@ -2101,7 +1337,7 @@ MemRegion FileMapInfo::get_heap_region_requested_range() { address start = heap_region_requested_address(); address end = start + size; - log_info(cds)("Requested heap region [" INTPTR_FORMAT " - " INTPTR_FORMAT "] = " SIZE_FORMAT_W(8) " bytes", + log_info(cds)("Requested heap region [" INTPTR_FORMAT " - " INTPTR_FORMAT "] = %8zu bytes", p2i(start), p2i(end), size); return MemRegion((HeapWord*)start, (HeapWord*)end); @@ -2163,13 +1399,13 @@ bool FileMapInfo::can_use_heap_region() { const int archive_narrow_klass_pointer_bits = header()->narrow_klass_pointer_bits(); const int archive_narrow_klass_shift = header()->narrow_klass_shift(); - log_info(cds)("CDS archive was created with max heap size = " SIZE_FORMAT "M, and the following configuration:", + log_info(cds)("CDS archive was created with max heap size = %zuM, and the following configuration:", max_heap_size()/M); log_info(cds)(" narrow_klass_base at mapping start address, narrow_klass_pointer_bits = %d, narrow_klass_shift = %d", archive_narrow_klass_pointer_bits, archive_narrow_klass_shift); log_info(cds)(" narrow_oop_mode = %d, narrow_oop_base = " PTR_FORMAT ", narrow_oop_shift = %d", narrow_oop_mode(), p2i(narrow_oop_base()), narrow_oop_shift()); - log_info(cds)("The current max heap size = " SIZE_FORMAT "M, G1HeapRegion::GrainBytes = " SIZE_FORMAT, + log_info(cds)("The current max heap size = %zuM, G1HeapRegion::GrainBytes = %zu", MaxHeapSize/M, G1HeapRegion::GrainBytes); log_info(cds)(" narrow_klass_base = " PTR_FORMAT ", arrow_klass_pointer_bits = %d, narrow_klass_shift = %d", p2i(CompressedKlassPointers::base()), CompressedKlassPointers::narrow_klass_pointer_bits(), CompressedKlassPointers::shift()); @@ -2326,7 +1562,7 @@ bool FileMapInfo::map_heap_region_impl() { if (base == nullptr || base != addr) { dealloc_heap_region(); log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. " - INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes", + INTPTR_FORMAT ", size = %zu bytes", p2i(addr), _mapped_heap_memregion.byte_size()); return false; } @@ -2359,14 +1595,13 @@ bool FileMapInfo::map_heap_region_impl() { if (bitmap_base == nullptr) { log_info(cds)("CDS heap cannot be used because bitmap region cannot be mapped"); dealloc_heap_region(); - unmap_region(MetaspaceShared::hp); _heap_pointers_need_patching = false; return false; } } - log_info(cds)("Heap data mapped at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes", + log_info(cds)("Heap data mapped at " INTPTR_FORMAT ", size = %8zu bytes", p2i(mapped_start), _mapped_heap_memregion.byte_size()); - log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta); + log_info(cds)("CDS heap data relocation delta = %zd bytes", delta); return true; } @@ -2428,8 +1663,14 @@ void FileMapInfo::unmap_region(int i) { if (size > 0 && r->mapped_from_file()) { log_info(cds)("Unmapping region #%d at base " INTPTR_FORMAT " (%s)", i, p2i(mapped_base), shared_region_name[i]); - if (!os::unmap_memory(mapped_base, size)) { - fatal("os::unmap_memory failed"); + if (r->in_reserved_space()) { + // This region was mapped inside a ReservedSpace. Its memory will be freed when the ReservedSpace + // is released. Zero it so that we don't accidentally read its content. + log_info(cds)("Region #%d (%s) is in a reserved space, it will be freed when the space is released", i, shared_region_name[i]); + } else { + if (!os::unmap_memory(mapped_base, size)) { + fatal("os::unmap_memory failed"); + } } } r->set_mapped_base(nullptr); @@ -2445,10 +1686,7 @@ void FileMapInfo::assert_mark(bool check) { FileMapInfo* FileMapInfo::_current_info = nullptr; FileMapInfo* FileMapInfo::_dynamic_archive_info = nullptr; bool FileMapInfo::_heap_pointers_need_patching = false; -SharedPathTable FileMapInfo::_shared_path_table; -bool FileMapInfo::_validating_shared_path_table = false; bool FileMapInfo::_memory_mapping_failed = false; -GrowableArray* FileMapInfo::_non_existent_class_paths = nullptr; // Open the shared archive file, read and validate the header // information (version, boot classpath, etc.). If initialization @@ -2457,7 +1695,7 @@ GrowableArray* FileMapInfo::_non_existent_class_paths = nullptr; // Validation of the archive is done in two steps: // // [1] validate_header() - done here. -// [2] validate_shared_path_table - this is done later, because the table is in the RW +// [2] validate_shared_path_table - this is done later, because the table is in the RO // region of the archive, which is not mapped yet. bool FileMapInfo::initialize() { assert(CDSConfig::is_using_archive(), "UseSharedSpaces expected."); @@ -2512,6 +1750,13 @@ bool FileMapInfo::validate_aot_class_linking() { log_error(cds)("CDS archive has aot-linked classes. It cannot be used with -Djava.security.manager=%s.", prop); return false; } + +#if INCLUDE_JVMTI + if (Arguments::has_jdwp_agent()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used with JDWP agent"); + return false; + } +#endif } return true; @@ -2671,17 +1916,15 @@ ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) { } ClassPathEntry* ent = _classpath_entries_for_jvmti[i]; if (ent == nullptr) { - SharedClassPathEntry* scpe = shared_path(i); - assert(scpe->is_jar(), "must be"); // other types of scpe will not produce archived classes - - const char* path = scpe->name(); + const AOTClassLocation* cl = AOTClassLocationConfig::runtime()->class_location_at(i); + const char* path = cl->path(); struct stat st; if (os::stat(path, &st) != 0) { char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); jio_snprintf(msg, strlen(path) + 127, "error in finding JAR file %s", path); THROW_MSG_(vmSymbols::java_io_IOException(), msg, nullptr); } else { - ent = ClassLoader::create_class_path_entry(THREAD, path, &st, false, false, scpe->is_multi_release()); + ent = ClassLoader::create_class_path_entry(THREAD, path, &st); if (ent == nullptr) { char *msg = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(path) + 128); jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path); @@ -2705,7 +1948,7 @@ ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) { ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle class_loader, TRAPS) { int path_index = ik->shared_classpath_index(); assert(path_index >= 0, "should be called for shared built-in classes only"); - assert(path_index < (int)get_number_of_shared_paths(), "sanity"); + assert(path_index < AOTClassLocationConfig::runtime()->length(), "sanity"); ClassPathEntry* cpe = get_classpath_entry_for_jvmti(path_index, CHECK_NULL); assert(cpe != nullptr, "must be"); @@ -2715,8 +1958,12 @@ ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle cl const char* const file_name = ClassLoader::file_name_for_class_name(class_name, name->utf8_length()); ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); + const AOTClassLocation* cl = AOTClassLocationConfig::runtime()->class_location_at(path_index); ClassFileStream* cfs; - if (class_loader() != nullptr && !cpe->is_modules_image() && cpe->is_multi_release_jar()) { + if (class_loader() != nullptr && cl->is_multi_release_jar()) { + // This class was loaded from a multi-release JAR file during dump time. The + // process for finding its classfile is complex. Let's defer to the Java code + // in java.lang.ClassLoader. cfs = get_stream_from_class_loader(class_loader, cpe, file_name, CHECK_NULL); } else { cfs = cpe->open_stream_for_loader(THREAD, file_name, loader_data); diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 6759b4a5020a6..22f70635e17ca 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,7 @@ static const int JVM_IDENT_MAX = 256; +class AOTClassLocationConfig; class ArchiveHeapInfo; class BitMapView; class CHeapBitMap; @@ -49,89 +50,7 @@ class ClassFileStream; class ClassLoaderData; class ClassPathEntry; class outputStream; - -class SharedClassPathEntry : public MetaspaceObj { - enum { - modules_image_entry, - jar_entry, - dir_entry, - non_existent_entry, - unknown_entry - }; - - void set_name(const char* name, TRAPS); - - u1 _type; - bool _is_module_path; - bool _from_class_path_attr; - bool _is_multi_release; - time_t _timestamp; // jar timestamp, 0 if is directory, modules image or other - int64_t _filesize; // jar/jimage file size, -1 if is directory, -2 if other - Array* _name; - Array* _manifest; - -public: - SharedClassPathEntry() : _type(0), _is_module_path(false), - _from_class_path_attr(false), _is_multi_release(false), _timestamp(0), - _filesize(0), _name(nullptr), _manifest(nullptr) {} - static int size() { - static_assert(is_aligned(sizeof(SharedClassPathEntry), wordSize), "must be"); - return (int)(sizeof(SharedClassPathEntry) / wordSize); - } - void init(bool is_modules_image, bool is_module_path, ClassPathEntry* cpe, TRAPS); - void init_as_non_existent(const char* path, TRAPS); - void metaspace_pointers_do(MetaspaceClosure* it); - MetaspaceObj::Type type() const { return SharedClassPathEntryType; } - bool validate(bool is_class_path = true) const; - - // The _timestamp only gets set for jar files. - bool has_timestamp() const { - return _timestamp != 0; - } - bool is_dir() const { return _type == dir_entry; } - bool is_modules_image() const { return _type == modules_image_entry; } - bool is_jar() const { return _type == jar_entry; } - bool is_non_existent() const { return _type == non_existent_entry; } - bool from_class_path_attr() { return _from_class_path_attr; } - bool is_multi_release() { return _is_multi_release; } - time_t timestamp() const { return _timestamp; } - const char* name() const; - const char* manifest() const { - return (_manifest == nullptr) ? nullptr : (const char*)_manifest->data(); - } - int manifest_size() const { - return (_manifest == nullptr) ? 0 : _manifest->length(); - } - void set_manifest(Array* manifest) { - _manifest = manifest; - } - bool check_non_existent() const; - void copy_from(SharedClassPathEntry* ent, ClassLoaderData* loader_data, TRAPS); - bool in_named_module() { - return is_modules_image() || // modules image doesn't contain unnamed modules - _is_module_path; // module path doesn't contain unnamed modules - } -}; - -class SharedPathTable { - Array* _entries; -public: - SharedPathTable() : _entries(nullptr) {} - SharedPathTable(Array* entries) : _entries(entries) {} - - void dumptime_init(ClassLoaderData* loader_data, TRAPS); - void metaspace_pointers_do(MetaspaceClosure* it); - - int size() { - return _entries == nullptr ? 0 : _entries->length(); - } - SharedClassPathEntry* path_at(int index) { - return _entries->at(index); - } - Array* table() {return _entries;} - void set_table(Array* table) {_entries = table;} -}; - +class ReservedSpace; class FileMapRegion: private CDSFileMapRegion { public: @@ -162,11 +81,13 @@ class FileMapRegion: private CDSFileMapRegion { size_t oopmap_size_in_bits() const { assert_is_heap_region(); return _oopmap_size_in_bits; } size_t ptrmap_offset() const { return _ptrmap_offset; } size_t ptrmap_size_in_bits() const { return _ptrmap_size_in_bits; } + bool in_reserved_space() const { return _in_reserved_space; } void set_file_offset(size_t s) { _file_offset = s; } void set_read_only(bool v) { _read_only = v; } void set_mapped_base(char* p) { _mapped_base = p; } void set_mapped_from_file(bool v) { _mapped_from_file = v; } + void set_in_reserved_space(bool is_reserved) { _in_reserved_space = is_reserved; } void init(int region_index, size_t mapping_offset, size_t size, bool read_only, bool allow_exec, int crc); void init_oopmap(size_t offset, size_t size_in_bits); @@ -200,30 +121,17 @@ class FileMapHeader: private CDSFileMapHeaderBase { size_t _cloned_vtables_offset; // The address of the first cloned vtable size_t _early_serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize() size_t _serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize() - bool _has_non_jar_in_classpath; // non-jar file entry exists in classpath - unsigned int _common_app_classpath_prefix_size; // size of the common prefix of app class paths - // 0 if no common prefix exists // The following fields are all sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's // invoked with. char _jvm_ident[JVM_IDENT_MAX]; // identifier string of the jvm that created this dump - // The following is a table of all the boot/app/module path entries that were used - // during dumping. At run time, we validate these entries according to their - // SharedClassPathEntry::_type. See: - // check_nonempty_dir_in_shared_path_table() - // validate_shared_path_table() - // validate_non_existent_class_paths() - size_t _shared_path_table_offset; - - jshort _app_class_paths_start_index; // Index of first app classpath entry - jshort _app_module_paths_start_index; // Index of first module path entry - jshort _max_used_path_index; // max path index referenced during CDS dump - int _num_module_paths; // number of module path entries + size_t _class_location_config_offset; + bool _verify_local; // BytecodeVerificationLocal setting bool _verify_remote; // BytecodeVerificationRemote setting - bool _has_platform_or_app_classes; // Archive contains app classes + bool _has_platform_or_app_classes; // Archive contains app or platform classes char* _requested_base_address; // Archive relocation is not necessary if we map with this base address. char* _mapped_base_address; // Actual base address where archive is mapped. @@ -238,10 +146,14 @@ class FileMapHeader: private CDSFileMapHeaderBase { size_t _heap_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap. size_t _rw_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the rw region size_t _ro_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the ro region - char* from_mapped_offset(size_t offset) const { - return mapped_base_address() + offset; + template T from_mapped_offset(size_t offset) const { + return (T)(mapped_base_address() + offset); } void set_as_offset(char* p, size_t *offset); + template void set_as_offset(T p, size_t *offset) { + set_as_offset((char*)p, offset); + } + public: // Accessors -- fields declared in GenericCDSFileMapHeader unsigned int magic() const { return _generic_header._magic; } @@ -250,7 +162,6 @@ class FileMapHeader: private CDSFileMapHeaderBase { unsigned int header_size() const { return _generic_header._header_size; } unsigned int base_archive_name_offset() const { return _generic_header._base_archive_name_offset; } unsigned int base_archive_name_size() const { return _generic_header._base_archive_name_size; } - unsigned int common_app_classpath_prefix_size() const { return _common_app_classpath_prefix_size; } void set_magic(unsigned int m) { _generic_header._magic = m; } void set_crc(int crc_value) { _generic_header._crc = crc_value; } @@ -258,7 +169,6 @@ class FileMapHeader: private CDSFileMapHeaderBase { void set_header_size(unsigned int s) { _generic_header._header_size = s; } void set_base_archive_name_offset(unsigned int s) { _generic_header._base_archive_name_offset = s; } void set_base_archive_name_size(unsigned int s) { _generic_header._base_archive_name_size = s; } - void set_common_app_classpath_prefix_size(unsigned int s) { _common_app_classpath_prefix_size = s; } bool is_static() const { return magic() == CDS_ARCHIVE_MAGIC; } size_t core_region_alignment() const { return _core_region_alignment; } @@ -269,14 +179,13 @@ class FileMapHeader: private CDSFileMapHeaderBase { bool compact_headers() const { return _compact_headers; } uintx max_heap_size() const { return _max_heap_size; } CompressedOops::Mode narrow_oop_mode() const { return _narrow_oop_mode; } - char* cloned_vtables() const { return from_mapped_offset(_cloned_vtables_offset); } - char* early_serialized_data() const { return from_mapped_offset(_early_serialized_data_offset); } - char* serialized_data() const { return from_mapped_offset(_serialized_data_offset); } + char* cloned_vtables() const { return from_mapped_offset(_cloned_vtables_offset); } + char* early_serialized_data() const { return from_mapped_offset(_early_serialized_data_offset); } + char* serialized_data() const { return from_mapped_offset(_serialized_data_offset); } const char* jvm_ident() const { return _jvm_ident; } char* requested_base_address() const { return _requested_base_address; } char* mapped_base_address() const { return _mapped_base_address; } bool has_platform_or_app_classes() const { return _has_platform_or_app_classes; } - bool has_non_jar_in_classpath() const { return _has_non_jar_in_classpath; } bool has_aot_linked_classes() const { return _has_aot_linked_classes; } bool compressed_oops() const { return _compressed_oops; } bool compressed_class_pointers() const { return _compressed_class_ptrs; } @@ -288,11 +197,6 @@ class FileMapHeader: private CDSFileMapHeaderBase { size_t heap_ptrmap_start_pos() const { return _heap_ptrmap_start_pos; } size_t rw_ptrmap_start_pos() const { return _rw_ptrmap_start_pos; } size_t ro_ptrmap_start_pos() const { return _ro_ptrmap_start_pos; } - // FIXME: These should really return int - jshort max_used_path_index() const { return _max_used_path_index; } - jshort app_module_paths_start_index() const { return _app_module_paths_start_index; } - jshort app_class_paths_start_index() const { return _app_class_paths_start_index; } - int num_module_paths() const { return _num_module_paths; } void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; } void set_cloned_vtables(char* p) { set_as_offset(p, &_cloned_vtables_offset); } @@ -306,8 +210,12 @@ class FileMapHeader: private CDSFileMapHeaderBase { void set_ro_ptrmap_start_pos(size_t n) { _ro_ptrmap_start_pos = n; } void copy_base_archive_name(const char* name); - void set_shared_path_table(SharedPathTable table) { - set_as_offset((char*)table.table(), &_shared_path_table_offset); + void set_class_location_config(AOTClassLocationConfig* table) { + set_as_offset(table, &_class_location_config_offset); + } + + AOTClassLocationConfig* class_location_config() { + return from_mapped_offset(_class_location_config_offset); } void set_requested_base(char* b) { @@ -315,11 +223,6 @@ class FileMapHeader: private CDSFileMapHeaderBase { _mapped_base_address = nullptr; } - SharedPathTable shared_path_table() const { - return SharedPathTable((Array*) - from_mapped_offset(_shared_path_table_offset)); - } - bool validate(); int compute_crc(); @@ -329,8 +232,7 @@ class FileMapHeader: private CDSFileMapHeaderBase { } void populate(FileMapInfo *info, size_t core_region_alignment, size_t header_size, - size_t base_archive_name_size, size_t base_archive_name_offset, - size_t common_app_classpath_size); + size_t base_archive_name_size, size_t base_archive_name_offset); static bool is_valid_region(int region) { return (0 <= region && region < NUM_CDS_REGIONS); } @@ -355,9 +257,6 @@ class FileMapInfo : public CHeapObj { const char* _base_archive_name; FileMapHeader* _header; - static SharedPathTable _shared_path_table; - static bool _validating_shared_path_table; - // FileMapHeader describes the shared space data in the file to be // mapped. This structure gets written to a file. It is not a class, so // that the compilers don't add any compiler-private data to it. @@ -366,20 +265,12 @@ class FileMapInfo : public CHeapObj { static FileMapInfo* _dynamic_archive_info; static bool _heap_pointers_need_patching; static bool _memory_mapping_failed; - static GrowableArray* _non_existent_class_paths; public: FileMapHeader *header() const { return _header; } static bool get_base_archive_name_from_header(const char* archive_name, char** base_archive_name); - static SharedPathTable shared_path_table() { - return _shared_path_table; - } - bool init_from_file(int fd); - static void metaspace_pointers_do(MetaspaceClosure* it) { - _shared_path_table.metaspace_pointers_do(it); - } void log_paths(const char* msg, int start_idx, int end_idx); @@ -405,8 +296,6 @@ class FileMapInfo : public CHeapObj { size_t heap_ptrmap_start_pos() const { return header()->heap_ptrmap_start_pos(); } CompressedOops::Mode narrow_oop_mode() const { return header()->narrow_oop_mode(); } - jshort app_module_paths_start_index() const { return header()->app_module_paths_start_index(); } - jshort app_class_paths_start_index() const { return header()->app_class_paths_start_index(); } char* cloned_vtables() const { return header()->cloned_vtables(); } void set_cloned_vtables(char* p) const { header()->set_cloned_vtables(p); } @@ -481,7 +370,6 @@ class FileMapInfo : public CHeapObj { void unmap_region(int i); void close(); bool is_open() { return _file_open; } - ReservedSpace reserve_shared_memory(); // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private. @@ -492,19 +380,8 @@ class FileMapInfo : public CHeapObj { NOT_CDS(return false;) } - static void allocate_shared_path_table(TRAPS); - static int add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS); - static void check_nonempty_dir_in_shared_path_table(); - bool check_module_paths(); - bool validate_shared_path_table(); - bool validate_non_existent_class_paths(); + bool validate_class_location(); bool validate_aot_class_linking(); - static void set_shared_path_table(FileMapInfo* info) { - _shared_path_table = info->header()->shared_path_table(); - } - static void update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS); - static int num_non_existent_class_paths(); - static void record_non_existent_class_path_entry(const char* path); #if INCLUDE_JVMTI // Caller needs a ResourceMark because parts of the returned cfs are resource-allocated. @@ -515,21 +392,6 @@ class FileMapInfo : public CHeapObj { TRAPS); #endif - static SharedClassPathEntry* shared_path(int index) { - return _shared_path_table.path_at(index); - } - - static const char* shared_path_name(int index) { - assert(index >= 0, "Sanity"); - return shared_path(index)->name(); - } - - static int get_number_of_shared_paths() { - return _shared_path_table.size(); - } - - static int get_module_shared_path_index(Symbol* location) NOT_CDS_RETURN_(-1); - // The offset of the first core region in the archive, relative to SharedBaseAddress size_t mapping_base_offset() const { return first_core_region()->mapping_offset(); } // The offset of the (exclusive) end of the last core region in this archive, relative to SharedBaseAddress @@ -562,22 +424,6 @@ class FileMapInfo : public CHeapObj { private: void seek_to_position(size_t pos); - char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(nullptr); - int num_paths(const char* path) NOT_CDS_RETURN_(0); - bool check_paths_existence(const char* paths) NOT_CDS_RETURN_(false); - GrowableArray* create_dumptime_app_classpath_array() NOT_CDS_RETURN_(nullptr); - GrowableArray* create_path_array(const char* path) NOT_CDS_RETURN_(nullptr); - bool classpath_failure(const char* msg, const char* name) NOT_CDS_RETURN_(false); - unsigned int longest_common_app_classpath_prefix_len(int num_paths, - GrowableArray* rp_array) - NOT_CDS_RETURN_(0); - bool check_paths(int shared_path_start_idx, int num_paths, - GrowableArray* rp_array, - unsigned int dumptime_prefix_len, - unsigned int runtime_prefix_len) NOT_CDS_RETURN_(false); - void extract_module_paths(const char* runtime_path, GrowableArray* module_paths); - bool validate_boot_class_paths() NOT_CDS_RETURN_(false); - bool validate_app_class_paths(int shared_app_paths_len) NOT_CDS_RETURN_(false); bool map_heap_region_impl() NOT_CDS_JAVA_HEAP_RETURN_(false); void dealloc_heap_region() NOT_CDS_JAVA_HEAP_RETURN; bool can_use_heap_region(); diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index d2ab109cc7267..5aa456ea43864 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,9 @@ * */ -#include "precompiled.hpp" +#include "cds/aotArtifactFinder.hpp" #include "cds/aotClassInitializer.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/archiveHeapWriter.hpp" @@ -86,7 +87,6 @@ struct ArchivableStaticFieldInfo { } }; -bool HeapShared::_disable_writing = false; DumpedInternedStrings *HeapShared::_dumped_interned_strings = nullptr; size_t HeapShared::_alloc_count[HeapShared::ALLOC_STAT_SLOTS]; @@ -220,7 +220,9 @@ bool HeapShared::has_been_archived(oop obj) { int HeapShared::append_root(oop obj) { assert(CDSConfig::is_dumping_heap(), "dump-time only"); - + if (obj != nullptr) { + assert(has_been_archived(obj), "must be"); + } // No GC should happen since we aren't scanning _pending_roots. assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); @@ -234,9 +236,6 @@ int HeapShared::append_root(oop obj) { objArrayOop HeapShared::root_segment(int segment_idx) { if (CDSConfig::is_dumping_heap()) { assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); - if (!HeapShared::can_write()) { - return nullptr; - } } else { assert(CDSConfig::is_using_archive(), "must be"); } @@ -290,7 +289,7 @@ void HeapShared::clear_root(int index) { } } -bool HeapShared::archive_object(oop obj) { +bool HeapShared::archive_object(oop obj, KlassSubGraphInfo* subgraph_info) { assert(CDSConfig::is_dumping_heap(), "dump-time only"); assert(!obj->is_stackChunk(), "do not archive stack chunks"); @@ -299,7 +298,7 @@ bool HeapShared::archive_object(oop obj) { } if (ArchiveHeapWriter::is_too_large_to_archive(obj->size())) { - log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT, + log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: %zu", p2i(obj), obj->size()); debug_trace(); return false; @@ -311,6 +310,36 @@ bool HeapShared::archive_object(oop obj) { archived_object_cache()->maybe_grow(); mark_native_pointers(obj); + Klass* k = obj->klass(); + if (k->is_instance_klass()) { + // Whenever we see a non-array Java object of type X, we mark X to be aot-initialized. + // This ensures that during the production run, whenever Java code sees a cached object + // of type X, we know that X is already initialized. (see TODO comment below ...) + + if (InstanceKlass::cast(k)->is_enum_subclass() + // We can't rerun of enum classes (see cdsEnumKlass.cpp) so + // we must store them as AOT-initialized. + || (subgraph_info == _dump_time_special_subgraph)) + // TODO: we do this only for the special subgraph for now. Extending this to + // other subgraphs would require more refactoring of the core library (such as + // move some initialization logic into runtimeSetup()). + // + // For the other subgraphs, we have a weaker mechanism to ensure that + // all classes in a subgraph are initialized before the subgraph is programmatically + // returned from jdk.internal.misc.CDS::initializeFromArchive(). + // See HeapShared::initialize_from_archived_subgraph(). + { + AOTArtifactFinder::add_aot_inited_class(InstanceKlass::cast(k)); + } + + if (java_lang_Class::is_instance(obj)) { + Klass* mirror_k = java_lang_Class::as_Klass(obj); + if (mirror_k != nullptr) { + AOTArtifactFinder::add_cached_class(mirror_k); + } + } + } + if (log_is_enabled(Debug, cds, heap)) { ResourceMark rm; LogTarget(Debug, cds, heap) log; @@ -328,10 +357,6 @@ bool HeapShared::archive_object(oop obj) { out.cr(); } - if (java_lang_Module::is_instance(obj) && Modules::check_archived_module_oop(obj)) { - Modules::update_oops_in_archived_module(obj, append_root(obj)); - } - return true; } } @@ -367,7 +392,9 @@ class MetaspaceObjToOopHandleTable: public ResourceHashtableset_oop(src, dest); + if (SystemDictionaryShared::is_builtin_loader(src->pool_holder()->class_loader_data())) { + _scratch_references_table->set_oop(src, dest); + } } objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) { @@ -466,11 +493,15 @@ bool HeapShared::is_archivable_hidden_klass(InstanceKlass* ik) { (is_lambda_form_klass(ik) || is_lambda_proxy_klass(ik) || is_string_concat_klass(ik)); } -void HeapShared::copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop m) { - assert(orig_k->is_instance_klass(), "sanity"); - InstanceKlass* ik = InstanceKlass::cast(orig_k); - InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(ik); +void HeapShared::copy_and_rescan_aot_inited_mirror(InstanceKlass* ik) { + ik->set_has_aot_initialized_mirror(); + if (AOTClassInitializer::is_runtime_setup_required(ik)) { + ik->set_is_runtime_setup_required(); + } + + oop orig_mirror = ik->java_mirror(); + oop m = scratch_java_mirror(ik); assert(ik->is_initialized(), "must be"); int nfields = 0; @@ -481,7 +512,19 @@ void HeapShared::copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop switch (fd.field_type()) { case T_OBJECT: case T_ARRAY: - m->obj_field_put(offset, orig_mirror->obj_field(offset)); + { + oop field_obj = orig_mirror->obj_field(offset); + if (offset == java_lang_Class::reflection_data_offset()) { + // Class::reflectData use SoftReference, which cannot be archived. Set it + // to null and it will be recreated at runtime. + field_obj = nullptr; + } + m->obj_field_put(offset, field_obj); + if (field_obj != nullptr) { + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, field_obj); + assert(success, "sanity"); + } + } break; case T_BOOLEAN: m->bool_field_put(offset, orig_mirror->bool_field(offset)); @@ -514,16 +557,18 @@ void HeapShared::copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop } } - java_lang_Class::set_class_data(m, java_lang_Class::class_data(orig_mirror)); - - // Class::reflectData use SoftReference, which cannot be archived. Set it - // to null and it will be recreated at runtime. - java_lang_Class::set_reflection_data(m, nullptr); + oop class_data = java_lang_Class::class_data(orig_mirror); + java_lang_Class::set_class_data(m, class_data); + if (class_data != nullptr) { + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, class_data); + assert(success, "sanity"); + } if (log_is_enabled(Info, cds, init)) { ResourceMark rm; - log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s", nfields, ik->external_name(), - ik->is_hidden() ? " (hidden)" : ""); + log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s%s", nfields, ik->external_name(), + ik->is_hidden() ? " (hidden)" : "", + ik->is_enum_subclass() ? " (enum)" : ""); } } @@ -546,10 +591,7 @@ static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) { } static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) { - InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik); - if (buffered_ik->is_shared_boot_class() || - buffered_ik->is_shared_platform_class() || - buffered_ik->is_shared_app_class()) { + if (SystemDictionaryShared::is_builtin_loader(src_ik->class_loader_data())) { objArrayOop rr = src_ik->constants()->resolved_references_or_null(); if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) { return HeapShared::scratch_resolved_references(src_ik->constants()); @@ -558,68 +600,8 @@ static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) { return nullptr; } -void HeapShared::archive_java_mirrors() { - for (int i = T_BOOLEAN; i < T_VOID+1; i++) { - BasicType bt = (BasicType)i; - if (!is_reference_type(bt)) { - oop orig_mirror = Universe::java_mirror(bt); - oop m = _scratch_basic_type_mirrors[i].resolve(); - assert(m != nullptr, "sanity"); - copy_java_mirror_hashcode(orig_mirror, m); - bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m); - assert(success, "sanity"); - - log_trace(cds, heap, mirror)( - "Archived %s mirror object from " PTR_FORMAT, - type2name(bt), p2i(m)); - - Universe::set_archived_basic_type_mirror_index(bt, append_root(m)); - } - } - - GrowableArray* klasses = ArchiveBuilder::current()->klasses(); - assert(klasses != nullptr, "sanity"); - - for (int i = 0; i < klasses->length(); i++) { - Klass* orig_k = klasses->at(i); - oop orig_mirror = orig_k->java_mirror(); - oop m = scratch_java_mirror(orig_k); - if (m != nullptr) { - copy_java_mirror_hashcode(orig_mirror, m); - } - } - - for (int i = 0; i < klasses->length(); i++) { - Klass* orig_k = klasses->at(i); - oop orig_mirror = orig_k->java_mirror(); - oop m = scratch_java_mirror(orig_k); - if (m != nullptr) { - Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k); - bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m); - guarantee(success, "scratch mirrors must point to only archivable objects"); - buffered_k->set_archived_java_mirror(append_root(m)); - ResourceMark rm; - log_trace(cds, heap, mirror)( - "Archived %s mirror object from " PTR_FORMAT, - buffered_k->external_name(), p2i(m)); - - // archive the resolved_referenes array - if (buffered_k->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(buffered_k); - objArrayOop rr = get_archived_resolved_references(InstanceKlass::cast(orig_k)); - if (rr != nullptr) { - bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr); - assert(success, "must be"); - int root_index = append_root(rr); - ik->constants()->cache()->set_archived_references(root_index); - } - } - } - } -} - void HeapShared::archive_strings() { - oop shared_strings_array = StringTable::init_shared_table(_dumped_interned_strings); + oop shared_strings_array = StringTable::init_shared_strings_array(_dumped_interned_strings); bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, shared_strings_array); // We must succeed because: // - _dumped_interned_strings do not contain any large strings. @@ -656,115 +638,9 @@ void HeapShared::set_has_native_pointers(oop src_obj) { info->set_has_native_pointers(); } -void HeapShared::start_finding_required_hidden_classes() { - if (!CDSConfig::is_dumping_invokedynamic()) { - return; - } - NoSafepointVerifier nsv; - - init_seen_objects_table(); - - // We first scan the objects that are known to be archived (from the archive_subgraph - // tables) - find_required_hidden_classes_helper(archive_subgraph_entry_fields); - if (CDSConfig::is_dumping_full_module_graph()) { - find_required_hidden_classes_helper(fmg_archive_subgraph_entry_fields); - } - - // Later, SystemDictionaryShared::find_all_archivable_classes_impl() will start - // scanning the constant pools of all classes that it decides to archive. -} - -void HeapShared::end_finding_required_hidden_classes() { - if (!CDSConfig::is_dumping_invokedynamic()) { - return; - } - NoSafepointVerifier nsv; - - delete_seen_objects_table(); -} - -void HeapShared::find_required_hidden_classes_helper(ArchivableStaticFieldInfo fields[]) { - if (!CDSConfig::is_dumping_heap()) { - return; - } - for (int i = 0; fields[i].valid(); i++) { - ArchivableStaticFieldInfo* f = &fields[i]; - InstanceKlass* k = f->klass; - oop m = k->java_mirror(); - oop o = m->obj_field(f->offset); - if (o != nullptr) { - find_required_hidden_classes_in_object(o); - } - } -} - -class HeapShared::FindRequiredHiddenClassesOopClosure: public BasicOopIterateClosure { - GrowableArray _stack; - template void do_oop_work(T *p) { - // Recurse on a GrowableArray to avoid overflowing the C stack. - oop o = RawAccess<>::oop_load(p); - if (o != nullptr) { - _stack.append(o); - } - } - - public: - - void do_oop(narrowOop *p) { FindRequiredHiddenClassesOopClosure::do_oop_work(p); } - void do_oop( oop *p) { FindRequiredHiddenClassesOopClosure::do_oop_work(p); } - - FindRequiredHiddenClassesOopClosure(oop o) { - _stack.append(o); - } - oop pop() { - if (_stack.length() == 0) { - return nullptr; - } else { - return _stack.pop(); - } - } -}; - -static void mark_required_if_hidden_class(Klass* k) { - if (k != nullptr && k->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(k); - if (ik->is_hidden()) { - SystemDictionaryShared::mark_required_hidden_class(ik); - } - } -} - - -void HeapShared::find_required_hidden_classes_in_object(oop root) { - ResourceMark rm; - FindRequiredHiddenClassesOopClosure c(root); - oop o; - while ((o = c.pop()) != nullptr) { - if (!has_been_seen_during_subgraph_recording(o)) { - set_has_been_seen_during_subgraph_recording(o); - - // Mark the klass of this object - mark_required_if_hidden_class(o->klass()); - - // For special objects, mark the klass that they contain information about. - // - a Class that refers to an hidden class - // - a ResolvedMethodName that refers to a method declared in a hidden class - if (java_lang_Class::is_instance(o)) { - mark_required_if_hidden_class(java_lang_Class::as_Klass(o)); - } else if (java_lang_invoke_ResolvedMethodName::is_instance(o)) { - Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(o); - if (m != nullptr) { - mark_required_if_hidden_class(m->method_holder()); - } - } - - o->oop_iterate(&c); - } - } -} - -void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { +// Between start_scanning_for_oops() and end_scanning_for_oops(), we discover all Java heap objects that +// should be stored in the AOT cache. The scanning is coordinated by AOTArtifactFinder. +void HeapShared::start_scanning_for_oops() { { NoSafepointVerifier nsv; @@ -782,262 +658,69 @@ void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { UseCompressedOops ? p2i(CompressedOops::end()) : p2i((address)G1CollectedHeap::heap()->reserved().end())); } - copy_objects(); - CDSHeapVerifier::verify(); - check_special_subgraph_classes(); + archive_subgraphs(); } - ArchiveHeapWriter::write(_pending_roots, heap_info); -} - -void HeapShared::copy_interned_strings() { init_seen_objects_table(); - - auto copier = [&] (oop s, bool value_ignored) { - assert(s != nullptr, "sanity"); - assert(!ArchiveHeapWriter::is_string_too_large_to_archive(s), "large strings must have been filtered"); - bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, s); - assert(success, "must be"); - // Prevent string deduplication from changing the value field to - // something not in the archive. - java_lang_String::set_deduplication_forbidden(s); - }; - _dumped_interned_strings->iterate_all(copier); - - delete_seen_objects_table(); + Universe::archive_exception_instances(); } -void HeapShared::copy_special_subgraph() { - copy_interned_strings(); - - init_seen_objects_table(); - { - archive_java_mirrors(); - archive_strings(); - Universe::archive_exception_instances(); - } +void HeapShared::end_scanning_for_oops() { + archive_strings(); delete_seen_objects_table(); } -void HeapShared::prepare_resolved_references() { - GrowableArray* klasses = ArchiveBuilder::current()->klasses(); - for (int i = 0; i < klasses->length(); i++) { - Klass* src_k = klasses->at(i); - if (src_k->is_instance_klass()) { - InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_k)); - buffered_ik->constants()->prepare_resolved_references_for_archiving(); - } +void HeapShared::write_heap(ArchiveHeapInfo *heap_info) { + { + NoSafepointVerifier nsv; + CDSHeapVerifier::verify(); + check_special_subgraph_classes(); } -} -void HeapShared::copy_objects() { - assert(HeapShared::can_write(), "must be"); - - prepare_resolved_references(); - find_all_aot_initialized_classes(); - copy_special_subgraph(); - - archive_object_subgraphs(archive_subgraph_entry_fields, - false /* is_full_module_graph */); + StringTable::write_shared_table(_dumped_interned_strings); + ArchiveHeapWriter::write(_pending_roots, heap_info); - if (CDSConfig::is_dumping_full_module_graph()) { - archive_object_subgraphs(fmg_archive_subgraph_entry_fields, - true /* is_full_module_graph */); - Modules::verify_archived_modules(); - } + ArchiveBuilder::OtherROAllocMark mark; + write_subgraph_info_table(); } -// Closure used by HeapShared::scan_for_aot_initialized_classes() to look for all objects -// that are reachable from a given root. -class HeapShared::AOTInitializedClassScanner : public BasicOopIterateClosure { - bool _made_progress; - - template void check(T *p) { - oop obj = HeapAccess<>::oop_load(p); - if (!java_lang_Class::is_instance(obj)) { - // Don't scan the mirrors, as we may see an orig_mirror while scanning - // the object graph, .... TODO more info - _made_progress |= HeapShared::scan_for_aot_initialized_classes(obj); - } - } - -public: - AOTInitializedClassScanner() : _made_progress(false) {} - void do_oop(narrowOop *p) { check(p); } - void do_oop( oop *p) { check(p); } - bool made_progress() { return _made_progress; } -}; - -// If has been initialized during the assembly phase, mark its -// has_aot_initialized_mirror bit. And then do the same for all supertypes of -// . -// -// Note: a super interface of may not have been initialized, if -// has not declared any default methods. -// -// Note: this function doesn not call InstanceKlass::initialize() -- we are inside -// a safepoint. -// -// Returns true if one or more classes have been newly marked. -static bool mark_for_aot_initialization(InstanceKlass* buffered_ik) { - assert(SafepointSynchronize::is_at_safepoint(), "sanity"); - assert(ArchiveBuilder::current()->is_in_buffer_space(buffered_ik), "sanity"); - - if (buffered_ik->has_aot_initialized_mirror()) { // already marked - return false; +void HeapShared::scan_java_mirror(oop orig_mirror) { + oop m = scratch_java_mirror(orig_mirror); + if (m != nullptr) { // nullptr if for custom class loader + copy_java_mirror_hashcode(orig_mirror, m); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m); + assert(success, "sanity"); } +} - bool made_progress = false; - if (buffered_ik->is_initialized()) { - if (log_is_enabled(Info, cds, init)) { - ResourceMark rm; - log_info(cds, init)("Mark class for aot-init: %s", buffered_ik->external_name()); - } - - InstanceKlass* src_ik = ArchiveBuilder::current()->get_source_addr(buffered_ik); - - // If we get here with a "wild" user class, which may have - // uncontrolled code, exit with an error. Obviously - // filtering logic upstream needs to detect APP classes and not mark - // them for aot-init in the first place, but this will be the final - // firewall. - -#ifndef PRODUCT - // ArchiveHeapTestClass is used for a very small number of internal regression - // tests (non-product builds only). It may initialize some unexpected classes. - if (ArchiveHeapTestClass == nullptr) -#endif - { - if (!src_ik->in_javabase_module()) { - // Class/interface types in the boot loader may have been initialized as side effects - // of JVM bootstrap code, so they are fine. But we need to check all other classes. - if (buffered_ik->is_interface()) { - // This probably means a bug in AOTConstantPoolResolver.::is_indy_resolution_deterministic() - guarantee(!buffered_ik->interface_needs_clinit_execution_as_super(), - "should not have initialized an interface whose might have unpredictable side effects"); - } else { - // "normal" classes - guarantee(HeapShared::is_archivable_hidden_klass(buffered_ik), - "should not have initialized any non-interface, non-hidden classes outside of java.base"); - } - } - } - - buffered_ik->set_has_aot_initialized_mirror(); - if (AOTClassInitializer::is_runtime_setup_required(src_ik)) { - buffered_ik->set_is_runtime_setup_required(); - } - made_progress = true; +void HeapShared::scan_java_class(Klass* orig_k) { + scan_java_mirror(orig_k->java_mirror()); - InstanceKlass* super = buffered_ik->java_super(); - if (super != nullptr) { - mark_for_aot_initialization(super); + if (orig_k->is_instance_klass()) { + InstanceKlass* orig_ik = InstanceKlass::cast(orig_k); + orig_ik->constants()->prepare_resolved_references_for_archiving(); + objArrayOop rr = get_archived_resolved_references(orig_ik); + if (rr != nullptr) { + bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr); + assert(success, "must be"); } - Array* interfaces = buffered_ik->transitive_interfaces(); - for (int i = 0; i < interfaces->length(); i++) { - InstanceKlass* intf = interfaces->at(i); - mark_for_aot_initialization(intf); - if (!intf->is_initialized()) { - assert(!intf->interface_needs_clinit_execution_as_super(/*also_check_supers*/false), "sanity"); - assert(!intf->has_aot_initialized_mirror(), "must not be marked"); - } - } + orig_ik->constants()->add_dumped_interned_strings(); } - - return made_progress; } -void HeapShared::find_all_aot_initialized_classes() { - if (!CDSConfig::is_dumping_aot_linked_classes()) { - return; - } - - init_seen_objects_table(); - find_all_aot_initialized_classes_helper(); - delete_seen_objects_table(); -} - -// Recursively find all class that should be aot-initialized: -// - the class has at least one instance that can be reachable from the special subgraph; or -// - the class is hard-coded in AOTClassInitializer::can_archive_initialized_mirror() -void HeapShared::find_all_aot_initialized_classes_helper() { - GrowableArray* klasses = ArchiveBuilder::current()->klasses(); - assert(klasses != nullptr, "sanity"); - - // First scan all resolved constant pools references. - for (int i = 0; i < klasses->length(); i++) { - Klass* src_k = klasses->at(i); - if (src_k->is_instance_klass()) { - InstanceKlass* src_ik = InstanceKlass::cast(src_k); - InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik); - objArrayOop rr = get_archived_resolved_references(src_ik); - if (rr != nullptr) { - objArrayOop scratch_rr = scratch_resolved_references(src_ik->constants()); - for (int i = 0; i < scratch_rr->length(); i++) { - scan_for_aot_initialized_classes(scratch_rr->obj_at(i)); - } - } - - // If a class is hard-coded to be aot-initialize, mark it as such. - if (AOTClassInitializer::can_archive_initialized_mirror(src_ik)) { - mark_for_aot_initialization(buffered_ik); - } - } - } - - // These objects also belong to the special subgraph - scan_for_aot_initialized_classes(Universe::null_ptr_exception_instance()); - scan_for_aot_initialized_classes(Universe::arithmetic_exception_instance()); - scan_for_aot_initialized_classes(Universe::internal_error_instance()); - scan_for_aot_initialized_classes(Universe::array_index_out_of_bounds_exception_instance()); - scan_for_aot_initialized_classes(Universe::array_store_exception_instance()); - scan_for_aot_initialized_classes(Universe::class_cast_exception_instance()); - - bool made_progress; - do { - // In each pass, we copy the scratch mirrors of the classes that were marked - // as aot-init in the previous pass. We then scan these mirrors, which may - // mark more classes. Keep iterating until no more progress can be made. - made_progress = false; - for (int i = 0; i < klasses->length(); i++) { - Klass* orig_k = klasses->at(i); - if (orig_k->is_instance_klass()) { - InstanceKlass* orig_ik = InstanceKlass::cast(orig_k); - if (ArchiveBuilder::current()->get_buffered_addr(orig_ik)->has_aot_initialized_mirror()) { - oop orig_mirror = orig_ik->java_mirror(); - oop scratch_mirror = scratch_java_mirror(orig_k); - if (!has_been_seen_during_subgraph_recording(scratch_mirror)) { - // Scan scratch_mirror instead of orig_mirror (which has fields like ClassLoader that - // are not archived). - copy_aot_initialized_mirror(orig_k, orig_mirror, scratch_mirror); - made_progress |= scan_for_aot_initialized_classes(scratch_mirror); - } - } - } - } - } while (made_progress); -} +void HeapShared::archive_subgraphs() { + assert(CDSConfig::is_dumping_heap(), "must be"); -bool HeapShared::scan_for_aot_initialized_classes(oop obj) { - if (obj == nullptr || has_been_seen_during_subgraph_recording(obj)) { - return false; - } - set_has_been_seen_during_subgraph_recording(obj); + archive_object_subgraphs(archive_subgraph_entry_fields, + false /* is_full_module_graph */); - bool made_progress = false; - Klass* k = obj->klass(); - if (k->is_instance_klass()) { - InstanceKlass* orig_ik = InstanceKlass::cast(k); - InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(orig_ik); - made_progress = mark_for_aot_initialization(buffered_ik); + if (CDSConfig::is_dumping_full_module_graph()) { + archive_object_subgraphs(fmg_archive_subgraph_entry_fields, + true /* is_full_module_graph */); + Modules::verify_archived_modules(); } - - AOTInitializedClassScanner scanner; - obj->oop_iterate(&scanner); - made_progress |= scanner.made_progress(); - return made_progress; } // @@ -1052,9 +735,8 @@ HeapShared::RunTimeKlassSubGraphInfoTable HeapShared::_run_time_subgraph_info_ KlassSubGraphInfo* HeapShared::init_subgraph_info(Klass* k, bool is_full_module_graph) { assert(CDSConfig::is_dumping_heap(), "dump time only"); bool created; - Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); KlassSubGraphInfo* info = - _dump_time_subgraph_info_table->put_if_absent(k, KlassSubGraphInfo(buffered_k, is_full_module_graph), + _dump_time_subgraph_info_table->put_if_absent(k, KlassSubGraphInfo(k, is_full_module_graph), &created); assert(created, "must not initialize twice"); return info; @@ -1082,30 +764,29 @@ void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) // Only objects of boot classes can be included in sub-graph. void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) { assert(CDSConfig::is_dumping_heap(), "dump time only"); - Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k); if (_subgraph_object_klasses == nullptr) { _subgraph_object_klasses = new (mtClass) GrowableArray(50, mtClass); } - assert(ArchiveBuilder::current()->is_in_buffer_space(buffered_k), "must be a shared class"); - - if (_k == buffered_k) { + if (_k == orig_k) { // Don't add the Klass containing the sub-graph to it's own klass // initialization list. return; } - if (buffered_k->is_instance_klass()) { + if (orig_k->is_instance_klass()) { +#ifdef ASSERT + InstanceKlass* ik = InstanceKlass::cast(orig_k); if (CDSConfig::is_dumping_invokedynamic()) { - assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class() || - HeapShared::is_lambda_proxy_klass(InstanceKlass::cast(buffered_k)), + assert(ik->class_loader() == nullptr || + HeapShared::is_lambda_proxy_klass(ik), "we can archive only instances of boot classes or lambda proxy classes"); } else { - assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class(), - "must be boot class"); + assert(ik->class_loader() == nullptr, "must be boot class"); } +#endif // vmClasses::xxx_klass() are not updated, need to check // the original Klass* if (orig_k == vmClasses::String_klass() || @@ -1114,37 +795,33 @@ void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) { // to the sub-graph object class list. return; } - if (buffered_k->has_aot_initialized_mirror()) { - // No need to add to the runtime-init list. - return; - } check_allowed_klass(InstanceKlass::cast(orig_k)); - } else if (buffered_k->is_objArray_klass()) { - Klass* abk = ObjArrayKlass::cast(buffered_k)->bottom_klass(); + } else if (orig_k->is_objArray_klass()) { + Klass* abk = ObjArrayKlass::cast(orig_k)->bottom_klass(); if (abk->is_instance_klass()) { assert(InstanceKlass::cast(abk)->is_shared_boot_class(), "must be boot class"); check_allowed_klass(InstanceKlass::cast(ObjArrayKlass::cast(orig_k)->bottom_klass())); } - if (buffered_k == Universe::objectArrayKlass()) { + if (orig_k == Universe::objectArrayKlass()) { // Initialized early during Universe::genesis. No need to be added // to the list. return; } } else { - assert(buffered_k->is_typeArray_klass(), "must be"); + assert(orig_k->is_typeArray_klass(), "must be"); // Primitive type arrays are created early during Universe::genesis. return; } if (log_is_enabled(Debug, cds, heap)) { - if (!_subgraph_object_klasses->contains(buffered_k)) { + if (!_subgraph_object_klasses->contains(orig_k)) { ResourceMark rm; log_debug(cds, heap)("Adding klass %s", orig_k->external_name()); } } - _subgraph_object_klasses->append_if_missing(buffered_k); + _subgraph_object_klasses->append_if_missing(orig_k); _has_non_early_klasses |= is_non_early_klass(orig_k); } @@ -1200,7 +877,7 @@ bool KlassSubGraphInfo::is_non_early_klass(Klass* k) { // Initialize an archived subgraph_info_record from the given KlassSubGraphInfo. void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { - _k = info->klass(); + _k = ArchiveBuilder::get_buffered_klass(info->klass()); _entry_field_records = nullptr; _subgraph_object_klasses = nullptr; _is_full_module_graph = info->is_full_module_graph(); @@ -1233,15 +910,28 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { } } - // the Klasses of the objects in the sub-graphs - GrowableArray* subgraph_object_klasses = info->subgraph_object_klasses(); - if (subgraph_object_klasses != nullptr) { - int num_subgraphs_klasses = subgraph_object_klasses->length(); - _subgraph_object_klasses = - ArchiveBuilder::new_ro_array(num_subgraphs_klasses); + // has the Klasses of all the objects that are referenced by this subgraph. + // Copy those that need to be explicitly initialized into <_subgraph_object_klasses>. + GrowableArray* recorded_klasses = info->subgraph_object_klasses(); + if (recorded_klasses != nullptr) { + // AOT-inited classes are automatically marked as "initialized" during bootstrap. When + // programmatically loading a subgraph, we only need to explicitly initialize the classes + // that are not aot-inited. + int num_to_copy = 0; + for (int i = 0; i < recorded_klasses->length(); i++) { + Klass* subgraph_k = ArchiveBuilder::get_buffered_klass(recorded_klasses->at(i)); + if (!subgraph_k->has_aot_initialized_mirror()) { + num_to_copy ++; + } + } + + _subgraph_object_klasses = ArchiveBuilder::new_ro_array(num_to_copy); bool is_special = (_k == ArchiveBuilder::get_buffered_klass(vmClasses::Object_klass())); - for (int i = 0; i < num_subgraphs_klasses; i++) { - Klass* subgraph_k = subgraph_object_klasses->at(i); + for (int i = 0, n = 0; i < recorded_klasses->length(); i++) { + Klass* subgraph_k = ArchiveBuilder::get_buffered_klass(recorded_klasses->at(i)); + if (subgraph_k->has_aot_initialized_mirror()) { + continue; + } if (log_is_enabled(Info, cds, heap)) { ResourceMark rm; const char* owner_name = is_special ? "" : _k->external_name(); @@ -1250,10 +940,11 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { } log_info(cds, heap)( "Archived object klass %s (%2d) => %s", - owner_name, i, subgraph_k->external_name()); + owner_name, n, subgraph_k->external_name()); } - _subgraph_object_klasses->at_put(i, subgraph_k); - ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i)); + _subgraph_object_klasses->at_put(n, subgraph_k); + ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(n)); + n++; } } @@ -1481,11 +1172,12 @@ void HeapShared::initialize_from_archived_subgraph(JavaThread* current, Klass* k if (k->name()->equals("jdk/internal/module/ArchivedModuleGraph") && !CDSConfig::is_using_optimized_module_handling() && // archive was created with --module-path - ClassLoaderExt::num_module_paths() > 0) { + AOTClassLocationConfig::runtime()->num_module_paths() > 0) { // ArchivedModuleGraph was created with a --module-path that's different than the runtime --module-path. // Thus, it might contain references to modules that do not exist at runtime. We cannot use it. log_info(cds, heap)("Skip initializing ArchivedModuleGraph subgraph: is_using_optimized_module_handling=%s num_module_paths=%d", - BOOL_TO_STR(CDSConfig::is_using_optimized_module_handling()), ClassLoaderExt::num_module_paths()); + BOOL_TO_STR(CDSConfig::is_using_optimized_module_handling()), + AOTClassLocationConfig::runtime()->num_module_paths()); return; } @@ -1693,7 +1385,7 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure { if (!_record_klasses_only && log_is_enabled(Debug, cds, heap)) { ResourceMark rm; - log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size " SIZE_FORMAT " %s", _level, + log_debug(cds, heap)("(%d) %s[%zu] ==> " PTR_FORMAT " size %zu %s", _level, _referencing_obj->klass()->external_name(), field_delta, p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name()); if (log_is_enabled(Trace, cds, heap)) { @@ -1831,12 +1523,12 @@ bool HeapShared::archive_reachable_objects_from(int level, bool record_klasses_only = already_archived; if (!already_archived) { ++_num_new_archived_objs; - if (!archive_object(orig_obj)) { + if (!archive_object(orig_obj, subgraph_info)) { // Skip archiving the sub-graph referenced from the current entry field. ResourceMark rm; log_error(cds, heap)( "Cannot archive the sub-graph referenced from %s object (" - PTR_FORMAT ") size " SIZE_FORMAT ", skipped.", + PTR_FORMAT ") size %zu, skipped.", orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize); if (level == 1) { // Don't archive a subgraph root that's too big. For archives static fields, that's OK @@ -2011,7 +1703,7 @@ void HeapShared::check_special_subgraph_classes() { int num = klasses->length(); for (int i = 0; i < num; i++) { Klass* subgraph_k = klasses->at(i); - Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name()); + Symbol* name = subgraph_k->name(); if (subgraph_k->is_instance_klass() && name != vmSymbols::java_lang_Class() && name != vmSymbols::java_lang_String() && @@ -2180,7 +1872,7 @@ void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], } void HeapShared::init_subgraph_entry_fields(TRAPS) { - assert(HeapShared::can_write(), "must be"); + assert(CDSConfig::is_dumping_heap(), "must be"); _dump_time_subgraph_info_table = new (mtClass)DumpTimeKlassSubGraphInfoTable(); init_subgraph_entry_fields(archive_subgraph_entry_fields, CHECK); if (CDSConfig::is_dumping_full_module_graph()) { @@ -2269,7 +1961,7 @@ void HeapShared::initialize_test_class_from_archive(JavaThread* current) { #endif void HeapShared::init_for_dumping(TRAPS) { - if (HeapShared::can_write()) { + if (CDSConfig::is_dumping_heap()) { setup_test_class(ArchiveHeapTestClass); _dumped_interned_strings = new (mtClass)DumpedInternedStrings(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE); init_subgraph_entry_fields(CHECK); @@ -2337,10 +2029,17 @@ void HeapShared::add_to_dumped_interned_strings(oop string) { bool created; _dumped_interned_strings->put_if_absent(string, true, &created); if (created) { + // Prevent string deduplication from changing the value field to + // something not in the archive. + java_lang_String::set_deduplication_forbidden(string); _dumped_interned_strings->maybe_grow(); } } +bool HeapShared::is_dumped_interned_string(oop o) { + return _dumped_interned_strings->get(o) != nullptr; +} + void HeapShared::debug_trace() { ResourceMark rm; WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current(); @@ -2417,18 +2116,18 @@ void HeapShared::print_stats() { size_t byte_size_limit = (size_t(1) << i) * HeapWordSize; size_t count = _alloc_count[i]; size_t size = _alloc_size[i]; - log_info(cds, heap)(SIZE_FORMAT_W(8) " objects are <= " SIZE_FORMAT_W(-6) - " bytes (total " SIZE_FORMAT_W(8) " bytes, avg %8.1f bytes)", + log_info(cds, heap)("%8zu objects are <= %-6zu" + " bytes (total %8zu bytes, avg %8.1f bytes)", count, byte_size_limit, size * HeapWordSize, avg_size(size, count)); huge_count -= count; huge_size -= size; } - log_info(cds, heap)(SIZE_FORMAT_W(8) " huge objects (total " SIZE_FORMAT_W(8) " bytes" + log_info(cds, heap)("%8zu huge objects (total %8zu bytes" ", avg %8.1f bytes)", huge_count, huge_size * HeapWordSize, avg_size(huge_size, huge_count)); - log_info(cds, heap)(SIZE_FORMAT_W(8) " total objects (total " SIZE_FORMAT_W(8) " bytes" + log_info(cds, heap)("%8zu total objects (total %8zu bytes" ", avg %8.1f bytes)", _total_obj_count, _total_obj_size * HeapWordSize, avg_size(_total_obj_size, _total_obj_count)); diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 618adeb308f94..11250f1a35cda 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,26 +143,6 @@ class HeapShared: AllStatic { friend class VerifySharedOopClosure; public: - // Can this VM write a heap region into the CDS archive? - static bool can_write() { - CDS_JAVA_HEAP_ONLY( - if (_disable_writing) { - return false; - } - // Need compressed class pointers for heap region dump. - if (!UseCompressedClassPointers) { - return false; - } - // Almost all GCs support heap region dump, except ZGC (so far). - return !UseZGC; - ) - NOT_CDS_JAVA_HEAP(return false;) - } - - static void disable_writing() { - CDS_JAVA_HEAP_ONLY(_disable_writing = true;) - } - static bool is_subgraph_root_class(InstanceKlass* ik); // Scratch objects for archiving Klass::java_mirror() @@ -171,14 +151,8 @@ class HeapShared: AllStatic { static oop scratch_java_mirror(oop java_mirror) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); static bool is_archived_boot_layer_available(JavaThread* current) NOT_CDS_JAVA_HEAP_RETURN_(false); - // Look for all hidden classes that are referenced by archived objects. - static void start_finding_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; - static void find_required_hidden_classes_in_object(oop o) NOT_CDS_JAVA_HEAP_RETURN; - static void end_finding_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; - private: #if INCLUDE_CDS_JAVA_HEAP - static bool _disable_writing; static DumpedInternedStrings *_dumped_interned_strings; // statistics @@ -260,9 +234,6 @@ class HeapShared: AllStatic { static DumpTimeKlassSubGraphInfoTable* _dump_time_subgraph_info_table; static RunTimeKlassSubGraphInfoTable _run_time_subgraph_info_table; - class FindRequiredHiddenClassesOopClosure; - static void find_required_hidden_classes_helper(ArchivableStaticFieldInfo fields[]); - static CachedOopInfo make_cached_oop_info(oop obj); static ArchivedKlassSubGraphInfoRecord* archive_subgraph_info(KlassSubGraphInfo* info); static void archive_object_subgraphs(ArchivableStaticFieldInfo fields[], @@ -344,9 +315,7 @@ class HeapShared: AllStatic { static bool has_been_seen_during_subgraph_recording(oop obj); static void set_has_been_seen_during_subgraph_recording(oop obj); - static bool archive_object(oop obj); - static void copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop m); - static void copy_interned_strings(); + static bool archive_object(oop obj, KlassSubGraphInfo* subgraph_info); static void resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]); static void resolve_classes_for_subgraph_of(JavaThread* current, Klass* k); @@ -369,14 +338,8 @@ class HeapShared: AllStatic { static void mark_native_pointers(oop orig_obj); static bool has_been_archived(oop orig_obj); static void prepare_resolved_references(); - static void archive_java_mirrors(); static void archive_strings(); - static void copy_special_subgraph(); - - class AOTInitializedClassScanner; - static void find_all_aot_initialized_classes(); - static void find_all_aot_initialized_classes_helper(); - static bool scan_for_aot_initialized_classes(oop obj); + static void archive_subgraphs(); public: static void reset_archived_object_states(TRAPS); @@ -393,14 +356,13 @@ class HeapShared: AllStatic { } static int archive_exception_instance(oop exception); - static void archive_objects(ArchiveHeapInfo* heap_info); - static void copy_objects(); static bool archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj); static void add_to_dumped_interned_strings(oop string); + static bool is_dumped_interned_string(oop o); // Scratch objects for archiving Klass::java_mirror() static void set_scratch_java_mirror(Klass* k, oop mirror); @@ -440,6 +402,7 @@ class HeapShared: AllStatic { #endif // INCLUDE_CDS_JAVA_HEAP public: + static void write_heap(ArchiveHeapInfo* heap_info) NOT_CDS_JAVA_HEAP_RETURN; static objArrayOop scratch_resolved_references(ConstantPool* src); static void add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) NOT_CDS_JAVA_HEAP_RETURN; static void init_scratch_objects(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; @@ -470,6 +433,13 @@ class HeapShared: AllStatic { static bool is_lambda_proxy_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_string_concat_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_archivable_hidden_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); + + // Used by AOTArtifactFinder + static void start_scanning_for_oops(); + static void end_scanning_for_oops(); + static void scan_java_class(Klass* k); + static void scan_java_mirror(oop orig_mirror); + static void copy_and_rescan_aot_inited_mirror(InstanceKlass* ik); }; #if INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/lambdaFormInvokers.cpp b/src/hotspot/share/cds/lambdaFormInvokers.cpp index 7765bc26aa3ec..ee3e9cff782ae 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.cpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/lambdaFormInvokers.hpp" #include "cds/metaspaceShared.hpp" diff --git a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp index b8220a34047e3..91f677055a68d 100644 --- a/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp +++ b/src/hotspot/share/cds/lambdaProxyClassDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/lambdaProxyClassDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 6348b04cbe193..b95d524cb1d35 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,9 @@ * */ -#include "precompiled.hpp" +#include "cds/aotArtifactFinder.hpp" #include "cds/aotClassLinker.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveBuilder.hpp" @@ -62,6 +63,7 @@ #include "logging/log.hpp" #include "logging/logMessage.hpp" #include "logging/logStream.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" @@ -121,7 +123,7 @@ bool MetaspaceShared::_use_optimized_module_handling = true; // [5] SymbolTable, StringTable, SystemDictionary, and a few other read-only data // are copied into the ro region as read-only tables. // -// The heap region is populated by HeapShared::archive_objects. +// The heap region is written by HeapShared::write_heap(). // // The bitmap region is used to relocate the ro/rw/hp regions. @@ -213,34 +215,64 @@ void MetaspaceShared::dump_loaded_classes(const char* file_name, TRAPS) { } } -static bool shared_base_too_high(char* specified_base, char* aligned_base, size_t cds_max) { - if (specified_base != nullptr && aligned_base < specified_base) { - // SharedBaseAddress is very high (e.g., 0xffffffffffffff00) so - // align_up(SharedBaseAddress, MetaspaceShared::core_region_alignment()) has wrapped around. - return true; +// If p is not aligned, move it up to the next address that's aligned with alignment. +// If this is not possible (because p is too high), return nullptr. Example: +// p = 0xffffffffffff0000, alignment= 0x10000 => return nullptr. +static char* align_up_or_null(char* p, size_t alignment) { + assert(p != nullptr, "sanity"); + if (is_aligned(p, alignment)) { + return p; + } + + char* down = align_down(p, alignment); + if (max_uintx - uintx(down) < uintx(alignment)) { + // Run out of address space to align up. + return nullptr; } + + char* aligned = align_up(p, alignment); + assert(aligned >= p, "sanity"); + assert(aligned != nullptr, "sanity"); + return aligned; +} + +static bool shared_base_too_high(char* specified_base, char* aligned_base, size_t cds_max) { + // Caller should have checked if align_up_or_null( returns nullptr (comparing specified_base + // with nullptr is UB). + assert(aligned_base != nullptr, "sanity"); + assert(aligned_base >= specified_base, "sanity"); + if (max_uintx - uintx(aligned_base) < uintx(cds_max)) { - // The end of the archive will wrap around + // Not enough address space to hold an archive of cds_max bytes from aligned_base. return true; + } else { + return false; } - - return false; } static char* compute_shared_base(size_t cds_max) { char* specified_base = (char*)SharedBaseAddress; - char* aligned_base = align_up(specified_base, MetaspaceShared::core_region_alignment()); + size_t alignment = MetaspaceShared::core_region_alignment(); if (UseCompressedClassPointers) { - aligned_base = align_up(specified_base, Metaspace::reserve_alignment()); + alignment = MAX2(alignment, Metaspace::reserve_alignment()); + } + + if (SharedBaseAddress == 0) { + // Special meaning of -XX:SharedBaseAddress=0 -> Always map archive at os-selected address. + return specified_base; } + char* aligned_base = align_up_or_null(specified_base, alignment); + if (aligned_base != specified_base) { log_info(cds)("SharedBaseAddress (" INTPTR_FORMAT ") aligned up to " INTPTR_FORMAT, p2i(specified_base), p2i(aligned_base)); } const char* err = nullptr; - if (shared_base_too_high(specified_base, aligned_base, cds_max)) { + if (aligned_base == nullptr) { + err = "too high"; + } else if (shared_base_too_high(specified_base, aligned_base, cds_max)) { err = "too high"; } else if (!shared_base_valid(aligned_base)) { err = "invalid for this platform"; @@ -248,12 +280,15 @@ static char* compute_shared_base(size_t cds_max) { return aligned_base; } + // Arguments::default_SharedBaseAddress() is hard-coded in cds_globals.hpp. It must be carefully + // picked that (a) the align_up() below will always return a valid value; (b) none of + // the following asserts will fail. log_warning(cds)("SharedBaseAddress (" INTPTR_FORMAT ") is %s. Reverted to " INTPTR_FORMAT, p2i((void*)SharedBaseAddress), err, p2i((void*)Arguments::default_SharedBaseAddress())); specified_base = (char*)Arguments::default_SharedBaseAddress(); - aligned_base = align_up(specified_base, MetaspaceShared::core_region_alignment()); + aligned_base = align_up(specified_base, alignment); // Make sure the default value of SharedBaseAddress specified in globals.hpp is sane. assert(!shared_base_too_high(specified_base, aligned_base, cds_max), "Sanity"); @@ -263,7 +298,7 @@ static char* compute_shared_base(size_t cds_max) { void MetaspaceShared::initialize_for_static_dump() { assert(CDSConfig::is_dumping_static_archive(), "sanity"); - log_info(cds)("Core region alignment: " SIZE_FORMAT, core_region_alignment()); + log_info(cds)("Core region alignment: %zu", core_region_alignment()); // The max allowed size for CDS archive. We use this to limit SharedBaseAddress // to avoid address space wrap around. size_t cds_max; @@ -282,9 +317,12 @@ void MetaspaceShared::initialize_for_static_dump() { SharedBaseAddress = (size_t)_requested_base_address; size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M); - _symbol_rs = ReservedSpace(symbol_rs_size, mtClassShared); + _symbol_rs = MemoryReserver::reserve(symbol_rs_size, + os::vm_allocation_granularity(), + os::vm_page_size(), + mtClassShared); if (!_symbol_rs.is_reserved()) { - log_error(cds)("Unable to reserve memory for symbols: " SIZE_FORMAT " bytes.", symbol_rs_size); + log_error(cds)("Unable to reserve memory for symbols: %zu bytes.", symbol_rs_size); MetaspaceShared::unrecoverable_writing_error(); } _symbol_region.init(&_symbol_rs, &_symbol_vs); @@ -293,20 +331,9 @@ void MetaspaceShared::initialize_for_static_dump() { // Called by universe_post_init() void MetaspaceShared::post_initialize(TRAPS) { if (CDSConfig::is_using_archive()) { - int size = FileMapInfo::get_number_of_shared_paths(); + int size = AOTClassLocationConfig::runtime()->length(); if (size > 0) { CDSProtectionDomain::allocate_shared_data_arrays(size, CHECK); - if (!CDSConfig::is_dumping_dynamic_archive()) { - FileMapInfo* info; - if (FileMapInfo::dynamic_info() == nullptr) { - info = FileMapInfo::current_info(); - } else { - info = FileMapInfo::dynamic_info(); - } - ClassLoaderExt::init_paths_start_index(info->app_class_paths_start_index()); - ClassLoaderExt::init_app_module_paths_start_index(info->app_module_paths_start_index()); - ClassLoaderExt::init_num_module_paths(info->header()->num_module_paths()); - } } } } @@ -515,13 +542,13 @@ class VM_PopulateDumpSharedSpace : public VM_Operation { FileMapInfo* _map_info; StaticArchiveBuilder& _builder; - void dump_java_heap_objects(GrowableArray* klasses) NOT_CDS_JAVA_HEAP_RETURN; + void dump_java_heap_objects(); void dump_shared_symbol_table(GrowableArray* symbols) { log_info(cds)("Dumping symbol table ..."); SymbolTable::write_to_archive(symbols); } char* dump_early_read_only_tables(); - char* dump_read_only_tables(); + char* dump_read_only_tables(AOTClassLocationConfig*& cl_config); public: @@ -542,7 +569,7 @@ class StaticArchiveBuilder : public ArchiveBuilder { StaticArchiveBuilder() : ArchiveBuilder() {} virtual void iterate_roots(MetaspaceClosure* it) { - FileMapInfo::metaspace_pointers_do(it); + AOTArtifactFinder::all_cached_classes_do(it); SystemDictionaryShared::dumptime_classes_do(it); Universe::metaspace_pointers_do(it); vmSymbols::metaspace_pointers_do(it); @@ -576,10 +603,11 @@ char* VM_PopulateDumpSharedSpace::dump_early_read_only_tables() { return start; } -char* VM_PopulateDumpSharedSpace::dump_read_only_tables() { +char* VM_PopulateDumpSharedSpace::dump_read_only_tables(AOTClassLocationConfig*& cl_config) { ArchiveBuilder::OtherROAllocMark mark; SystemDictionaryShared::write_to_archive(); + cl_config = AOTClassLocationConfig::dumptime()->write_to_archive(); AOTClassLinker::write_to_archive(); MetaspaceShared::write_method_handle_intrinsics(); @@ -607,13 +635,21 @@ void VM_PopulateDumpSharedSpace::doit() { SystemDictionary::get_all_method_handle_intrinsics(_pending_method_handle_intrinsics); } - FileMapInfo::check_nonempty_dir_in_shared_path_table(); + AOTClassLocationConfig::dumptime_check_nonempty_dirs(); NOT_PRODUCT(SystemDictionary::verify();) // Block concurrent class unloading from changing the _dumptime_table MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); - SystemDictionaryShared::find_all_archivable_classes(); + +#if INCLUDE_CDS_JAVA_HEAP + if (CDSConfig::is_dumping_heap() && _extra_interned_strings != nullptr) { + for (int i = 0; i < _extra_interned_strings->length(); i ++) { + OopHandle string = _extra_interned_strings->at(i); + HeapShared::add_to_dumped_interned_strings(string.resolve()); + } + } +#endif _builder.gather_source_objs(); _builder.reserve_buffer(); @@ -625,15 +661,16 @@ void VM_PopulateDumpSharedSpace::doit() { _builder.dump_ro_metadata(); _builder.relocate_metaspaceobj_embedded_pointers(); - dump_java_heap_objects(_builder.klasses()); - dump_shared_symbol_table(_builder.symbols()); - log_info(cds)("Make classes shareable"); _builder.make_klasses_shareable(); MetaspaceShared::make_method_handle_intrinsics_shareable(); + dump_java_heap_objects(); + dump_shared_symbol_table(_builder.symbols()); + char* early_serialized_data = dump_early_read_only_tables(); - char* serialized_data = dump_read_only_tables(); + AOTClassLocationConfig* cl_config; + char* serialized_data = dump_read_only_tables(cl_config); SystemDictionaryShared::adjust_lambda_proxy_class_dictionary(); @@ -649,6 +686,7 @@ void VM_PopulateDumpSharedSpace::doit() { _map_info->set_early_serialized_data(early_serialized_data); _map_info->set_serialized_data(serialized_data); _map_info->set_cloned_vtables(CppVtables::vtables_serialized_base()); + _map_info->header()->set_class_location_config(cl_config); } class CollectCLDClosure : public CLDClosure { @@ -745,7 +783,6 @@ void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) { void MetaspaceShared::prepare_for_dumping() { assert(CDSConfig::is_dumping_archive(), "sanity"); CDSConfig::check_unsupported_dumping_module_options(); - ClassLoader::initialize_shared_path(JavaThread::current()); } // Preload classes from a list, populate the shared spaces and dump to a @@ -758,7 +795,7 @@ void MetaspaceShared::preload_and_dump(TRAPS) { if (HAS_PENDING_EXCEPTION) { if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) { log_error(cds)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " - SIZE_FORMAT "M", MaxHeapSize/M); + "%zuM", MaxHeapSize/M); MetaspaceShared::writing_error(); } else { log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), @@ -787,15 +824,15 @@ void MetaspaceShared::adjust_heap_sizes_for_dumping() { julong max_heap_size = (julong)(4 * G); if (MinHeapSize > max_heap_size) { - log_debug(cds)("Setting MinHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MinHeapSize/M); + log_debug(cds)("Setting MinHeapSize to 4G for CDS dumping, original size = %zuM", MinHeapSize/M); FLAG_SET_ERGO(MinHeapSize, max_heap_size); } if (InitialHeapSize > max_heap_size) { - log_debug(cds)("Setting InitialHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", InitialHeapSize/M); + log_debug(cds)("Setting InitialHeapSize to 4G for CDS dumping, original size = %zuM", InitialHeapSize/M); FLAG_SET_ERGO(InitialHeapSize, max_heap_size); } if (MaxHeapSize > max_heap_size) { - log_debug(cds)("Setting MaxHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MaxHeapSize/M); + log_debug(cds)("Setting MaxHeapSize to 4G for CDS dumping, original size = %zuM", MaxHeapSize/M); FLAG_SET_ERGO(MaxHeapSize, max_heap_size); } } @@ -900,6 +937,7 @@ void MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder& builder, TRAPS HeapShared::init_for_dumping(CHECK); ArchiveHeapWriter::init(); if (CDSConfig::is_dumping_full_module_graph()) { + ClassLoaderDataShared::ensure_module_entry_tables_exist(); HeapShared::reset_archived_object_states(CHECK); } @@ -986,8 +1024,10 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { ik->external_name()); CLEAR_PENDING_EXCEPTION; SystemDictionaryShared::set_class_has_failed_verification(ik); + } else { + assert(!SystemDictionaryShared::has_class_failed_verification(ik), "sanity"); + ik->compute_has_loops_flag_for_methods(); } - ik->compute_has_loops_flag_for_methods(); BytecodeVerificationLocal = saved; return true; } else { @@ -995,37 +1035,13 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { } } -#if INCLUDE_CDS_JAVA_HEAP -void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray* klasses) { - if(!HeapShared::can_write()) { - log_info(cds)( - "Archived java heap is not supported as UseG1GC " - "and UseCompressedClassPointers are required." - "Current settings: UseG1GC=%s, UseCompressedClassPointers=%s.", - BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedClassPointers)); - return; - } - // Find all the interned strings that should be dumped. - int i; - for (i = 0; i < klasses->length(); i++) { - Klass* k = klasses->at(i); - if (k->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(k); - ik->constants()->add_dumped_interned_strings(); - } - } - if (_extra_interned_strings != nullptr) { - for (i = 0; i < _extra_interned_strings->length(); i ++) { - OopHandle string = _extra_interned_strings->at(i); - HeapShared::add_to_dumped_interned_strings(string.resolve()); - } +void VM_PopulateDumpSharedSpace::dump_java_heap_objects() { + if (CDSConfig::is_dumping_heap()) { + HeapShared::write_heap(&_heap_info); + } else { + CDSConfig::log_reasons_for_not_dumping_heap(); } - - HeapShared::archive_objects(&_heap_info); - ArchiveBuilder::OtherROAllocMark mark; - HeapShared::write_subgraph_info_table(); } -#endif // INCLUDE_CDS_JAVA_HEAP void MetaspaceShared::set_shared_metaspace_range(void* base, void *static_top, void* top) { assert(base <= static_top && static_top <= top, "must be"); @@ -1087,7 +1103,7 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { FileMapInfo* dynamic_mapinfo = nullptr; if (static_mapinfo != nullptr) { - log_info(cds)("Core region alignment: " SIZE_FORMAT, static_mapinfo->core_region_alignment()); + log_info(cds)("Core region alignment: %zu", static_mapinfo->core_region_alignment()); dynamic_mapinfo = open_dynamic_archive(); // First try to map at the requested address @@ -1110,11 +1126,8 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { _relocation_delta = static_mapinfo->relocation_delta(); _requested_base_address = static_mapinfo->requested_base_address(); if (dynamic_mapped) { - FileMapInfo::set_shared_path_table(dynamic_mapinfo); // turn AutoCreateSharedArchive off if successfully mapped AutoCreateSharedArchive = false; - } else { - FileMapInfo::set_shared_path_table(static_mapinfo); } } else { set_shared_metaspace_range(nullptr, nullptr, nullptr); @@ -1241,9 +1254,9 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File } #endif // ASSERT - log_info(cds)("Reserved archive_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (" SIZE_FORMAT ") bytes", + log_info(cds)("Reserved archive_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (%zu) bytes", p2i(archive_space_rs.base()), p2i(archive_space_rs.end()), archive_space_rs.size()); - log_info(cds)("Reserved class_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (" SIZE_FORMAT ") bytes", + log_info(cds)("Reserved class_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT "] (%zu) bytes", p2i(class_space_rs.base()), p2i(class_space_rs.end()), class_space_rs.size()); if (MetaspaceShared::use_windows_memory_mapping()) { @@ -1266,7 +1279,9 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File if (use_requested_addr) { assert(!total_space_rs.is_reserved(), "Should not be reserved for Windows"); log_info(cds)("Windows mmap workaround: releasing archive space."); - archive_space_rs.release(); + MemoryReserver::release(archive_space_rs); + // Mark as not reserved + archive_space_rs = {}; } } MapArchiveResult static_result = map_archive(static_mapinfo, mapped_base_address, archive_space_rs); @@ -1438,8 +1453,10 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma "Archive base address unaligned: " PTR_FORMAT ", needs alignment: %zu.", p2i(base_address), archive_space_alignment); - archive_space_rs = ReservedSpace(archive_space_size, archive_space_alignment, - os::vm_page_size(), (char*)base_address); + archive_space_rs = MemoryReserver::reserve((char*)base_address, + archive_space_size, + archive_space_alignment, + os::vm_page_size()); if (archive_space_rs.is_reserved()) { assert(base_address == nullptr || (address)archive_space_rs.base() == base_address, "Sanity"); @@ -1468,8 +1485,7 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma size_t class_space_size = CompressedClassSpaceSize; assert(CompressedClassSpaceSize > 0 && is_aligned(CompressedClassSpaceSize, class_space_alignment), - "CompressedClassSpaceSize malformed: " - SIZE_FORMAT, CompressedClassSpaceSize); + "CompressedClassSpaceSize malformed: %zu", CompressedClassSpaceSize); const size_t ccs_begin_offset = align_up(archive_space_size, class_space_alignment); const size_t gap_size = ccs_begin_offset - archive_space_size; @@ -1479,7 +1495,7 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma guarantee(archive_space_size < max_encoding_range_size - class_space_alignment, "Archive too large"); if ((archive_space_size + gap_size + class_space_size) > max_encoding_range_size) { class_space_size = align_down(max_encoding_range_size - archive_space_size - gap_size, class_space_alignment); - log_info(metaspace)("CDS initialization: reducing class space size from " SIZE_FORMAT " to " SIZE_FORMAT, + log_info(metaspace)("CDS initialization: reducing class space size from %zu to %zu", CompressedClassSpaceSize, class_space_size); FLAG_SET_ERGO(CompressedClassSpaceSize, class_space_size); } @@ -1505,10 +1521,14 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma // caller will not split the combined space for mapping, instead read the archive data // via sequential file IO. address ccs_base = base_address + archive_space_size + gap_size; - archive_space_rs = ReservedSpace(archive_space_size, archive_space_alignment, - os::vm_page_size(), (char*)base_address); - class_space_rs = ReservedSpace(class_space_size, class_space_alignment, - os::vm_page_size(), (char*)ccs_base); + archive_space_rs = MemoryReserver::reserve((char*)base_address, + archive_space_size, + archive_space_alignment, + os::vm_page_size()); + class_space_rs = MemoryReserver::reserve((char*)ccs_base, + class_space_size, + class_space_alignment, + os::vm_page_size()); } if (!archive_space_rs.is_reserved() || !class_space_rs.is_reserved()) { release_reserved_spaces(total_space_rs, archive_space_rs, class_space_rs); @@ -1519,8 +1539,10 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma MemTracker::record_virtual_memory_tag(class_space_rs.base(), mtClass); } else { if (use_archive_base_addr && base_address != nullptr) { - total_space_rs = ReservedSpace(total_range_size, base_address_alignment, - os::vm_page_size(), (char*) base_address); + total_space_rs = MemoryReserver::reserve((char*) base_address, + total_range_size, + base_address_alignment, + os::vm_page_size()); } else { // We did not manage to reserve at the preferred address, or were instructed to relocate. In that // case we reserve wherever possible, but the start address needs to be encodable as narrow Klass @@ -1568,15 +1590,18 @@ void MetaspaceShared::release_reserved_spaces(ReservedSpace& total_space_rs, ReservedSpace& class_space_rs) { if (total_space_rs.is_reserved()) { log_debug(cds)("Released shared space (archive + class) " INTPTR_FORMAT, p2i(total_space_rs.base())); - total_space_rs.release(); + MemoryReserver::release(total_space_rs); + total_space_rs = {}; } else { if (archive_space_rs.is_reserved()) { log_debug(cds)("Released shared space (archive) " INTPTR_FORMAT, p2i(archive_space_rs.base())); - archive_space_rs.release(); + MemoryReserver::release(archive_space_rs); + archive_space_rs = {}; } if (class_space_rs.is_reserved()) { log_debug(cds)("Released shared space (classes) " INTPTR_FORMAT, p2i(class_space_rs.base())); - class_space_rs.release(); + MemoryReserver::release(class_space_rs); + class_space_rs = {}; } } } @@ -1592,8 +1617,8 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped mapinfo->set_is_mapped(false); if (mapinfo->core_region_alignment() != (size_t)core_region_alignment()) { - log_info(cds)("Unable to map CDS archive -- core_region_alignment() expected: " SIZE_FORMAT - " actual: " SIZE_FORMAT, mapinfo->core_region_alignment(), core_region_alignment()); + log_info(cds)("Unable to map CDS archive -- core_region_alignment() expected: %zu" + " actual: %zu", mapinfo->core_region_alignment(), core_region_alignment()); return MAP_ARCHIVE_OTHER_FAILURE; } @@ -1605,7 +1630,7 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped return result; } - if (!mapinfo->validate_shared_path_table()) { + if (!mapinfo->validate_class_location()) { unmap_archive(mapinfo); return MAP_ARCHIVE_OTHER_FAILURE; } @@ -1762,7 +1787,7 @@ void MetaspaceShared::print_on(outputStream* st) { address static_top = (address)_shared_metaspace_static_top; address top = (address)MetaspaceObj::shared_metaspace_top(); st->print("[" PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "), ", p2i(base), p2i(static_top), p2i(top)); - st->print("size " SIZE_FORMAT ", ", top - base); + st->print("size %zu, ", top - base); st->print("SharedBaseAddress: " PTR_FORMAT ", ArchiveRelocationMode: %d.", SharedBaseAddress, ArchiveRelocationMode); } else { st->print("CDS archive(s) not mapped"); diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index aaa649d3c0fd3..6d5f273041a83 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "memory/memRegion.hpp" +#include "memory/reservedSpace.hpp" #include "memory/virtualspace.hpp" #include "oops/oop.hpp" #include "utilities/macros.hpp" @@ -40,7 +41,6 @@ class SerializeClosure; class StaticArchiveBuilder; template class Array; -template class GrowableArray; enum MapArchiveResult { MAP_ARCHIVE_SUCCESS, diff --git a/src/hotspot/share/cds/regeneratedClasses.cpp b/src/hotspot/share/cds/regeneratedClasses.cpp index 6c7be18edd90b..37d5e89598a7c 100644 --- a/src/hotspot/share/cds/regeneratedClasses.cpp +++ b/src/hotspot/share/cds/regeneratedClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/regeneratedClasses.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp index e2d41cd1de261..3d237e6759aaf 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.cpp +++ b/src/hotspot/share/cds/runTimeClassInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/dumpTimeClassInfo.hpp" #include "cds/runTimeClassInfo.hpp" diff --git a/src/hotspot/share/cds/unregisteredClasses.cpp b/src/hotspot/share/cds/unregisteredClasses.cpp index 2aeb2fc94e77f..2e985b7231011 100644 --- a/src/hotspot/share/cds/unregisteredClasses.cpp +++ b/src/hotspot/share/cds/unregisteredClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,14 +22,14 @@ * */ -#include "precompiled.hpp" +#include "cds/cdsConfig.hpp" #include "cds/unregisteredClasses.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.inline.hpp" #include "classfile/classLoaderExt.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" -#include "classfile/systemDictionaryShared.hpp" +#include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" @@ -39,10 +39,22 @@ #include "runtime/javaCalls.hpp" #include "services/threadService.hpp" +InstanceKlass* UnregisteredClasses::_UnregisteredClassLoader_klass = nullptr; + +void UnregisteredClasses::initialize(TRAPS) { + if (_UnregisteredClassLoader_klass == nullptr) { + // no need for synchronization as this function is called single-threaded. + Symbol* klass_name = SymbolTable::new_symbol("jdk/internal/misc/CDS$UnregisteredClassLoader"); + Klass* k = SystemDictionary::resolve_or_fail(klass_name, true, CHECK); + _UnregisteredClassLoader_klass = InstanceKlass::cast(k); + } +} + // Load the class of the given name from the location given by path. The path is specified by // the "source:" in the class list file (see classListParser.cpp), and can be a directory or // a JAR file. -InstanceKlass* UnregisteredClasses::load_class(Symbol* name, const char* path, TRAPS) { +InstanceKlass* UnregisteredClasses::load_class(Symbol* name, const char* path, + Handle super_class, objArrayHandle interfaces, TRAPS) { assert(name != nullptr, "invariant"); assert(CDSConfig::is_dumping_static_archive(), "this function is only used with -Xshare:dump"); @@ -50,19 +62,23 @@ InstanceKlass* UnregisteredClasses::load_class(Symbol* name, const char* path, T THREAD->get_thread_stat()->perf_timers_addr(), PerfClassTraceTime::CLASS_LOAD); + // Call CDS$UnregisteredClassLoader::load(String name, Class superClass, Class[] interfaces) + Symbol* methodName = SymbolTable::new_symbol("load"); + Symbol* methodSignature = SymbolTable::new_symbol("(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Class;"); Symbol* path_symbol = SymbolTable::new_symbol(path); - Symbol* findClass = SymbolTable::new_symbol("findClass"); - Handle url_classloader = get_url_classloader(path_symbol, CHECK_NULL); + Handle classloader = get_classloader(path_symbol, CHECK_NULL); Handle ext_class_name = java_lang_String::externalize_classname(name, CHECK_NULL); JavaValue result(T_OBJECT); - JavaCallArguments args(2); - args.set_receiver(url_classloader); + JavaCallArguments args(3); + args.set_receiver(classloader); args.push_oop(ext_class_name); + args.push_oop(super_class); + args.push_oop(interfaces); JavaCalls::call_virtual(&result, - vmClasses::URLClassLoader_klass(), - findClass, - vmSymbols::string_class_signature(), + UnregisteredClassLoader_klass(), + methodName, + methodSignature, &args, CHECK_NULL); assert(result.get_type() == T_OBJECT, "just checking"); @@ -70,45 +86,35 @@ InstanceKlass* UnregisteredClasses::load_class(Symbol* name, const char* path, T return InstanceKlass::cast(java_lang_Class::as_Klass(obj)); } -class URLClassLoaderTable : public ResourceHashtable< +class UnregisteredClasses::ClassLoaderTable : public ResourceHashtable< Symbol*, OopHandle, 137, // prime number AnyObj::C_HEAP> {}; -static URLClassLoaderTable* _url_classloader_table = nullptr; +static UnregisteredClasses::ClassLoaderTable* _classloader_table = nullptr; -Handle UnregisteredClasses::create_url_classloader(Symbol* path, TRAPS) { +Handle UnregisteredClasses::create_classloader(Symbol* path, TRAPS) { ResourceMark rm(THREAD); JavaValue result(T_OBJECT); Handle path_string = java_lang_String::create_from_str(path->as_C_string(), CHECK_NH); - JavaCalls::call_static(&result, - vmClasses::jdk_internal_loader_ClassLoaders_klass(), - vmSymbols::toFileURL_name(), - vmSymbols::toFileURL_signature(), - path_string, CHECK_NH); - assert(result.get_type() == T_OBJECT, "just checking"); - oop url_h = result.get_oop(); - objArrayHandle urls = oopFactory::new_objArray_handle(vmClasses::URL_klass(), 1, CHECK_NH); - urls->obj_at_put(0, url_h); - - Handle url_classloader = JavaCalls::construct_new_instance( - vmClasses::URLClassLoader_klass(), - vmSymbols::url_array_classloader_void_signature(), - urls, Handle(), CHECK_NH); - return url_classloader; + Handle classloader = JavaCalls::construct_new_instance( + UnregisteredClassLoader_klass(), + vmSymbols::string_void_signature(), + path_string, CHECK_NH); + return classloader; } -Handle UnregisteredClasses::get_url_classloader(Symbol* path, TRAPS) { - if (_url_classloader_table == nullptr) { - _url_classloader_table = new (mtClass)URLClassLoaderTable(); +Handle UnregisteredClasses::get_classloader(Symbol* path, TRAPS) { + if (_classloader_table == nullptr) { + _classloader_table = new (mtClass)ClassLoaderTable(); } - OopHandle* url_classloader_ptr = _url_classloader_table->get(path); - if (url_classloader_ptr != nullptr) { - return Handle(THREAD, (*url_classloader_ptr).resolve()); + OopHandle* classloader_ptr = _classloader_table->get(path); + if (classloader_ptr != nullptr) { + return Handle(THREAD, (*classloader_ptr).resolve()); } else { - Handle url_classloader = create_url_classloader(path, CHECK_NH); - _url_classloader_table->put(path, OopHandle(Universe::vm_global(), url_classloader())); + Handle classloader = create_classloader(path, CHECK_NH); + _classloader_table->put(path, OopHandle(Universe::vm_global(), classloader())); path->increment_refcount(); - return url_classloader; + return classloader; } } diff --git a/src/hotspot/share/cds/unregisteredClasses.hpp b/src/hotspot/share/cds/unregisteredClasses.hpp index a9f7dceaead62..ea3a308c2de24 100644 --- a/src/hotspot/share/cds/unregisteredClasses.hpp +++ b/src/hotspot/share/cds/unregisteredClasses.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,30 @@ #ifndef SHARE_CDS_UNREGISTEREDCLASSES_HPP #define SHARE_CDS_UNREGISTEREDCLASSES_HPP +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" +class InstanceKlass; +class Symbol; + class UnregisteredClasses: AllStatic { public: - static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS); + static InstanceKlass* load_class(Symbol* h_name, const char* path, + Handle super_class, objArrayHandle interfaces, + TRAPS); + static void initialize(TRAPS); + static InstanceKlass* UnregisteredClassLoader_klass() { + return _UnregisteredClassLoader_klass; + } + + class ClassLoaderTable; private: - static Handle create_url_classloader(Symbol* path, TRAPS); - static Handle get_url_classloader(Symbol* path, TRAPS); + // Don't put this in vmClasses as it's used only with CDS dumping. + static InstanceKlass* _UnregisteredClassLoader_klass; + + static Handle create_classloader(Symbol* path, TRAPS); + static Handle get_classloader(Symbol* path, TRAPS); }; #endif // SHARE_CDS_UNREGISTEREDCLASSES_HPP diff --git a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp index 16ecab7dfac05..cf7b839c98241 100644 --- a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp +++ b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmIntrinsics.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "ci/ciConstant.hpp" diff --git a/src/hotspot/share/ci/ciArray.cpp b/src/hotspot/share/ci/ciArray.cpp index 6f601c87ff2de..6b1a30fec6aa8 100644 --- a/src/hotspot/share/ci/ciArray.cpp +++ b/src/hotspot/share/ci/ciArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciArray.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciConstant.hpp" diff --git a/src/hotspot/share/ci/ciArrayKlass.cpp b/src/hotspot/share/ci/ciArrayKlass.cpp index 6bcb2526cd693..947cc0cb6fcb2 100644 --- a/src/hotspot/share/ci/ciArrayKlass.cpp +++ b/src/hotspot/share/ci/ciArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciObjArrayKlass.hpp" #include "ci/ciTypeArrayKlass.hpp" diff --git a/src/hotspot/share/ci/ciBaseObject.cpp b/src/hotspot/share/ci/ciBaseObject.cpp index aeeaad73fbf82..8c4a9c5cb122f 100644 --- a/src/hotspot/share/ci/ciBaseObject.cpp +++ b/src/hotspot/share/ci/ciBaseObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciBaseObject.hpp" #include "ci/ciUtilities.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/share/ci/ciCallSite.cpp b/src/hotspot/share/ci/ciCallSite.cpp index 8b67d9ec6ac59..3271e4ea7c7a5 100644 --- a/src/hotspot/share/ci/ciCallSite.cpp +++ b/src/hotspot/share/ci/ciCallSite.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "ci/ciCallSite.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciConstant.cpp b/src/hotspot/share/ci/ciConstant.cpp index 62ff0ab08c914..234cd8171c46b 100644 --- a/src/hotspot/share/ci/ciConstant.cpp +++ b/src/hotspot/share/ci/ciConstant.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciConstant.hpp" #include "ci/ciUtilities.hpp" #include "memory/allocation.hpp" diff --git a/src/hotspot/share/ci/ciConstantPoolCache.cpp b/src/hotspot/share/ci/ciConstantPoolCache.cpp index e831516b0f70b..cfb031aff60b5 100644 --- a/src/hotspot/share/ci/ciConstantPoolCache.cpp +++ b/src/hotspot/share/ci/ciConstantPoolCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciConstantPoolCache.hpp" #include "ci/ciUtilities.inline.hpp" #include "memory/allocation.hpp" diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index eb7d1eaf64dd4..e87c5ba08e95e 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciConstant.hpp" #include "ci/ciEnv.hpp" #include "ci/ciField.hpp" diff --git a/src/hotspot/share/ci/ciExceptionHandler.cpp b/src/hotspot/share/ci/ciExceptionHandler.cpp index 6c30e71596545..1896ada69fc3a 100644 --- a/src/hotspot/share/ci/ciExceptionHandler.cpp +++ b/src/hotspot/share/ci/ciExceptionHandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciExceptionHandler.hpp" #include "ci/ciUtilities.inline.hpp" #include "runtime/handles.inline.hpp" diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp index 0eddd87200ae0..cbe0cadbc9304 100644 --- a/src/hotspot/share/ci/ciField.cpp +++ b/src/hotspot/share/ci/ciField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciField.hpp" #include "ci/ciInstanceKlass.hpp" #include "ci/ciSymbols.hpp" @@ -103,8 +102,6 @@ ciField::ciField(ciInstanceKlass* klass, int index, Bytecodes::Code bc) : _type = ciType::make(field_type); } - _name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name); - // Get the field's declared holder. // // Note: we actually create a ciInstanceKlass for this klass, diff --git a/src/hotspot/share/ci/ciFlags.cpp b/src/hotspot/share/ci/ciFlags.cpp index 1401a432a9e18..5eade4a12c168 100644 --- a/src/hotspot/share/ci/ciFlags.cpp +++ b/src/hotspot/share/ci/ciFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciFlags.hpp" // ciFlags @@ -92,5 +91,5 @@ void ciFlags::print_member_flags(outputStream* st) { // ------------------------------------------------------------------ // ciFlags::print void ciFlags::print(outputStream* st) { - st->print(" flags=%x", _flags); + st->print(" flags=%x", _flags.as_unsigned_short()); } diff --git a/src/hotspot/share/ci/ciFlags.hpp b/src/hotspot/share/ci/ciFlags.hpp index dd1df622487f3..426f953611fee 100644 --- a/src/hotspot/share/ci/ciFlags.hpp +++ b/src/hotspot/share/ci/ciFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ #define SHARE_CI_CIFLAGS_HPP #include "ci/ciClassList.hpp" -#include "jvm_constants.h" #include "utilities/accessFlags.hpp" #include "utilities/ostream.hpp" @@ -39,37 +38,37 @@ class ciFlags { friend class ciField; friend class ciMethod; - jint _flags; + AccessFlags _flags; bool _stable; - bool _intialized_final_update; + bool _initialized_final_update; - ciFlags() :_flags(0), _stable(false), _intialized_final_update(false) { } + ciFlags() :_flags(0), _stable(false), _initialized_final_update(false) { } ciFlags(AccessFlags flags, bool is_stable = false, bool is_initialized_final_update = false) : - _flags(flags.as_int()), _stable(is_stable), _intialized_final_update(is_initialized_final_update) { } + _flags(flags), _stable(is_stable), _initialized_final_update(is_initialized_final_update) { } public: // Java access flags - bool is_public () const { return (_flags & JVM_ACC_PUBLIC ) != 0; } - bool is_private () const { return (_flags & JVM_ACC_PRIVATE ) != 0; } - bool is_protected () const { return (_flags & JVM_ACC_PROTECTED ) != 0; } - bool is_static () const { return (_flags & JVM_ACC_STATIC ) != 0; } - bool is_final () const { return (_flags & JVM_ACC_FINAL ) != 0; } - bool is_synchronized () const { return (_flags & JVM_ACC_SYNCHRONIZED ) != 0; } - bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; } - bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; } - bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; } - bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; } - bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } - bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } + bool is_public () const { return _flags.is_public(); } + bool is_private () const { return _flags.is_private(); } + bool is_protected () const { return _flags.is_protected(); } + bool is_static () const { return _flags.is_static(); } + bool is_final () const { return _flags.is_final(); } + bool is_synchronized () const { return _flags.is_synchronized(); } + bool is_super () const { return _flags.is_super(); } + bool is_volatile () const { return _flags.is_volatile(); } + bool is_transient () const { return _flags.is_transient(); } + bool is_native () const { return _flags.is_native(); } + bool is_interface () const { return _flags.is_interface(); } + bool is_abstract () const { return _flags.is_abstract(); } bool is_stable () const { return _stable; } // In case the current object represents a field, return true if // the field is modified outside of instance initializer methods // (or class/initializer methods if the field is static) and false // otherwise. - bool has_initialized_final_update() const { return _intialized_final_update; }; + bool has_initialized_final_update() const { return _initialized_final_update; }; // Conversion - jint as_int() { return _flags; } + jint as_int() { return _flags.as_unsigned_short(); } void print_klass_flags(outputStream* st = tty); void print_member_flags(outputStream* st = tty); diff --git a/src/hotspot/share/ci/ciInstance.cpp b/src/hotspot/share/ci/ciInstance.cpp index 6ede59dd72309..edd8f8b0f4067 100644 --- a/src/hotspot/share/ci/ciInstance.cpp +++ b/src/hotspot/share/ci/ciInstance.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "ci/ciConstant.hpp" #include "ci/ciField.hpp" diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp index a9342eeada48b..5799f30ad6748 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.cpp +++ b/src/hotspot/share/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciField.hpp" #include "ci/ciInstance.hpp" #include "ci/ciInstanceKlass.hpp" @@ -90,14 +89,10 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : JavaThread *thread = JavaThread::current(); if (ciObjectFactory::is_initialized()) { _loader = JNIHandles::make_local(thread, ik->class_loader()); - _protection_domain = JNIHandles::make_local(thread, - ik->protection_domain()); _is_shared = false; } else { Handle h_loader(thread, ik->class_loader()); - Handle h_protection_domain(thread, ik->protection_domain()); _loader = JNIHandles::make_global(h_loader); - _protection_domain = JNIHandles::make_global(h_protection_domain); _is_shared = true; } @@ -119,7 +114,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : // Version for unloaded classes: ciInstanceKlass::ciInstanceKlass(ciSymbol* name, - jobject loader, jobject protection_domain) + jobject loader) : ciKlass(name, T_OBJECT) { assert(name->char_at(0) != JVM_SIGNATURE_ARRAY, "not an instance klass"); @@ -130,7 +125,6 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name, _is_hidden = false; _is_record = false; _loader = loader; - _protection_domain = protection_domain; _is_shared = false; _super = nullptr; _java_mirror = nullptr; @@ -172,19 +166,6 @@ jobject ciInstanceKlass::loader_handle() { return _loader; } -// ------------------------------------------------------------------ -// ciInstanceKlass::protection_domain -oop ciInstanceKlass::protection_domain() { - ASSERT_IN_VM; - return JNIHandles::resolve(_protection_domain); -} - -// ------------------------------------------------------------------ -// ciInstanceKlass::protection_domain_handle -jobject ciInstanceKlass::protection_domain_handle() { - return _protection_domain; -} - // ------------------------------------------------------------------ // ciInstanceKlass::field_cache // diff --git a/src/hotspot/share/ci/ciInstanceKlass.hpp b/src/hotspot/share/ci/ciInstanceKlass.hpp index 4c327e1f32d68..9c1c416780d21 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.hpp +++ b/src/hotspot/share/ci/ciInstanceKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,6 @@ class ciInstanceKlass : public ciKlass { enum SubklassValue { subklass_unknown, subklass_false, subklass_true }; jobject _loader; - jobject _protection_domain; InstanceKlass::ClassState _init_state; // state of class bool _is_shared; @@ -84,7 +83,7 @@ class ciInstanceKlass : public ciKlass { protected: ciInstanceKlass(Klass* k); - ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); + ciInstanceKlass(ciSymbol* name, jobject loader); InstanceKlass* get_instanceKlass() const { return InstanceKlass::cast(get_Klass()); @@ -93,9 +92,6 @@ class ciInstanceKlass : public ciKlass { oop loader(); jobject loader_handle(); - oop protection_domain(); - jobject protection_domain_handle(); - const char* type_string() { return "ciInstanceKlass"; } bool is_in_package_impl(const char* packagename, int len); diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index f65d4a0311c82..f3e49634d2984 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciKlass.hpp" #include "ci/ciSymbol.hpp" #include "ci/ciUtilities.inline.hpp" @@ -222,7 +221,7 @@ jint ciKlass::modifier_flags() { jint ciKlass::access_flags() { assert(is_loaded(), "not loaded"); GUARDED_VM_ENTRY( - return get_Klass()->access_flags().as_int(); + return get_Klass()->access_flags().as_unsigned_short(); ) } diff --git a/src/hotspot/share/ci/ciKlass.hpp b/src/hotspot/share/ci/ciKlass.hpp index 7b8d871eb561f..37091471a2a6a 100644 --- a/src/hotspot/share/ci/ciKlass.hpp +++ b/src/hotspot/share/ci/ciKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,9 +65,6 @@ class ciKlass : public ciType { virtual oop loader() { return nullptr; } virtual jobject loader_handle() { return nullptr; } - virtual oop protection_domain() { return nullptr; } - virtual jobject protection_domain_handle() { return nullptr; } - const char* type_string() { return "ciKlass"; } void print_impl(outputStream* st); @@ -122,7 +119,7 @@ class ciKlass : public ciType { // Get the instance of java.lang.Class corresponding to this klass. ciInstance* java_mirror(); - // Fetch Klass::modifier_flags. + // Fetch modifier flags. jint modifier_flags(); // Fetch Klass::access_flags. diff --git a/src/hotspot/share/ci/ciMemberName.cpp b/src/hotspot/share/ci/ciMemberName.cpp index 4306e6e649ee2..aec4d4c4d19c1 100644 --- a/src/hotspot/share/ci/ciMemberName.cpp +++ b/src/hotspot/share/ci/ciMemberName.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciClassList.hpp" #include "ci/ciMemberName.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciMetadata.cpp b/src/hotspot/share/ci/ciMetadata.cpp index f0d1fcf4357e0..a2c21289a2cb6 100644 --- a/src/hotspot/share/ci/ciMetadata.cpp +++ b/src/hotspot/share/ci/ciMetadata.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciObject.hpp" #include "ci/ciUtilities.inline.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp index 80277b91d2264..96cb0bb904094 100644 --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciCallProfile.hpp" #include "ci/ciExceptionHandler.hpp" #include "ci/ciInstanceKlass.hpp" diff --git a/src/hotspot/share/ci/ciMethodBlocks.cpp b/src/hotspot/share/ci/ciMethodBlocks.cpp index 03dd2c31f993a..ea2ea04e8c072 100644 --- a/src/hotspot/share/ci/ciMethodBlocks.cpp +++ b/src/hotspot/share/ci/ciMethodBlocks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodBlocks.hpp" #include "ci/ciStreams.hpp" #include "interpreter/bytecode.hpp" diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index 5abb342d03119..a37e4ba75e6f5 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMetadata.hpp" #include "ci/ciMethodData.hpp" #include "ci/ciReplay.hpp" @@ -785,7 +784,7 @@ void ciMethodData::dump_replay_data(outputStream* out) { // We could use INTPTR_FORMAT here but that's zero justified // which makes comparing it with the SA version of this output // harder. data()'s element type is intptr_t. - out->print(" " INTX_FORMAT_X, data()[i]); + out->print(" 0x%zx", data()[i]); } // The MDO contained oop references as ciObjects, so scan for those diff --git a/src/hotspot/share/ci/ciMethodHandle.cpp b/src/hotspot/share/ci/ciMethodHandle.cpp index 49de75353a63f..2e2a57036a687 100644 --- a/src/hotspot/share/ci/ciMethodHandle.cpp +++ b/src/hotspot/share/ci/ciMethodHandle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciClassList.hpp" #include "ci/ciMethodHandle.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciMethodType.cpp b/src/hotspot/share/ci/ciMethodType.cpp index f9cd22001a310..3051dbeeddd8f 100644 --- a/src/hotspot/share/ci/ciMethodType.cpp +++ b/src/hotspot/share/ci/ciMethodType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciInstance.hpp" #include "ci/ciMethodType.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciNullObject.cpp b/src/hotspot/share/ci/ciNullObject.cpp index e79b8dc5ecea0..c030d9f57371f 100644 --- a/src/hotspot/share/ci/ciNullObject.cpp +++ b/src/hotspot/share/ci/ciNullObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciNullObject.hpp" #include "ci/ciUtilities.hpp" diff --git a/src/hotspot/share/ci/ciObjArray.cpp b/src/hotspot/share/ci/ciObjArray.cpp index d06665d616393..2a485fb26182d 100644 --- a/src/hotspot/share/ci/ciObjArray.cpp +++ b/src/hotspot/share/ci/ciObjArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciNullObject.hpp" #include "ci/ciObjArray.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciObjArrayKlass.cpp b/src/hotspot/share/ci/ciObjArrayKlass.cpp index 1b47702599b53..191e4e67522ac 100644 --- a/src/hotspot/share/ci/ciObjArrayKlass.cpp +++ b/src/hotspot/share/ci/ciObjArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciInstanceKlass.hpp" #include "ci/ciObjArrayKlass.hpp" #include "ci/ciSymbol.hpp" diff --git a/src/hotspot/share/ci/ciObjArrayKlass.hpp b/src/hotspot/share/ci/ciObjArrayKlass.hpp index 27ca6d30cf5bb..3fb37c5088c5c 100644 --- a/src/hotspot/share/ci/ciObjArrayKlass.hpp +++ b/src/hotspot/share/ci/ciObjArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,10 +58,6 @@ class ciObjArrayKlass : public ciArrayKlass { oop loader() { return _base_element_klass->loader(); } jobject loader_handle() { return _base_element_klass->loader_handle(); } - oop protection_domain() { return _base_element_klass->protection_domain(); } - jobject protection_domain_handle() { return _base_element_klass->protection_domain_handle(); } - - public: // The one-level type of the array elements. ciKlass* element_klass(); diff --git a/src/hotspot/share/ci/ciObject.cpp b/src/hotspot/share/ci/ciObject.cpp index 2fe8b91b8215f..23696b6b70a8d 100644 --- a/src/hotspot/share/ci/ciObject.cpp +++ b/src/hotspot/share/ci/ciObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciObject.hpp" #include "ci/ciUtilities.inline.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/share/ci/ciObjectFactory.cpp b/src/hotspot/share/ci/ciObjectFactory.cpp index bf8e561d1a298..35ec27b8aaaf8 100644 --- a/src/hotspot/share/ci/ciObjectFactory.cpp +++ b/src/hotspot/share/ci/ciObjectFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciCallSite.hpp" #include "ci/ciInstance.hpp" #include "ci/ciInstanceKlass.hpp" @@ -174,7 +173,7 @@ void ciObjectFactory::init_shared_objects() { ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); // Create dummy InstanceKlass and ObjArrayKlass object and assign them idents - ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, nullptr, nullptr); + ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, nullptr); init_ident_of(ciEnv::_unloaded_ciinstance_klass); ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); init_ident_of(ciEnv::_unloaded_ciobjarrayklass); @@ -468,13 +467,11 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass, oop domain = nullptr; if (accessing_klass != nullptr) { loader = accessing_klass->loader(); - domain = accessing_klass->protection_domain(); } for (int i = 0; i < _unloaded_klasses.length(); i++) { ciKlass* entry = _unloaded_klasses.at(i); if (entry->name()->equals(name) && - entry->loader() == loader && - entry->protection_domain() == domain) { + entry->loader() == loader) { // We've found a match. return entry; } @@ -513,12 +510,10 @@ ciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass, new_klass = new (arena()) ciObjArrayKlass(name, element_klass, dimension); } else { jobject loader_handle = nullptr; - jobject domain_handle = nullptr; if (accessing_klass != nullptr) { loader_handle = accessing_klass->loader_handle(); - domain_handle = accessing_klass->protection_domain_handle(); } - new_klass = new (arena()) ciInstanceKlass(name, loader_handle, domain_handle); + new_klass = new (arena()) ciInstanceKlass(name, loader_handle); } init_ident_of(new_klass); _unloaded_klasses.append(new_klass); diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index c4127263df1cf..1385bb637a99d 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "ci/ciReplay.hpp" #include "ci/ciSymbol.hpp" diff --git a/src/hotspot/share/ci/ciSignature.cpp b/src/hotspot/share/ci/ciSignature.cpp index efa056ef985f2..973e96b93ba2b 100644 --- a/src/hotspot/share/ci/ciSignature.cpp +++ b/src/hotspot/share/ci/ciSignature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodType.hpp" #include "ci/ciSignature.hpp" #include "ci/ciStreams.hpp" diff --git a/src/hotspot/share/ci/ciStreams.cpp b/src/hotspot/share/ci/ciStreams.cpp index 18d2a46a6862c..259e72a341259 100644 --- a/src/hotspot/share/ci/ciStreams.cpp +++ b/src/hotspot/share/ci/ciStreams.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciConstant.hpp" #include "ci/ciField.hpp" #include "ci/ciKlass.hpp" diff --git a/src/hotspot/share/ci/ciSymbol.cpp b/src/hotspot/share/ci/ciSymbol.cpp index 40b23deaa7f9d..c3e2b8d53e4b0 100644 --- a/src/hotspot/share/ci/ciSymbol.cpp +++ b/src/hotspot/share/ci/ciSymbol.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciSymbol.hpp" #include "ci/ciSymbols.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciType.cpp b/src/hotspot/share/ci/ciType.cpp index 05645478086c1..9340f1cda3db2 100644 --- a/src/hotspot/share/ci/ciType.cpp +++ b/src/hotspot/share/ci/ciType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciEnv.hpp" #include "ci/ciType.hpp" #include "ci/ciUtilities.inline.hpp" diff --git a/src/hotspot/share/ci/ciTypeArray.cpp b/src/hotspot/share/ci/ciTypeArray.cpp index fb7c2b04646b1..5182cfef53676 100644 --- a/src/hotspot/share/ci/ciTypeArray.cpp +++ b/src/hotspot/share/ci/ciTypeArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciTypeArray.hpp" #include "ci/ciUtilities.inline.hpp" #include "oops/typeArrayOop.inline.hpp" diff --git a/src/hotspot/share/ci/ciTypeArrayKlass.cpp b/src/hotspot/share/ci/ciTypeArrayKlass.cpp index 6a5d5faadc6fd..59b687ccb8bc7 100644 --- a/src/hotspot/share/ci/ciTypeArrayKlass.cpp +++ b/src/hotspot/share/ci/ciTypeArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciTypeArrayKlass.hpp" #include "ci/ciUtilities.inline.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 36b4a2991cc9e..3caca6424bc98 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciConstant.hpp" #include "ci/ciField.hpp" #include "ci/ciMethod.hpp" diff --git a/src/hotspot/share/ci/ciUtilities.cpp b/src/hotspot/share/ci/ciUtilities.cpp index 931a1c75d605a..1a91ded937142 100644 --- a/src/hotspot/share/ci/ciUtilities.cpp +++ b/src/hotspot/share/ci/ciUtilities.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciUtilities.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/cardTable.hpp" diff --git a/src/hotspot/share/classfile/altHashing.cpp b/src/hotspot/share/classfile/altHashing.cpp index 1d43d6ebf1ed0..1f7a84f745c2b 100644 --- a/src/hotspot/share/classfile/altHashing.cpp +++ b/src/hotspot/share/classfile/altHashing.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ . */ -#include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/vmClasses.hpp" #include "oops/klass.inline.hpp" diff --git a/src/hotspot/share/classfile/bytecodeAssembler.cpp b/src/hotspot/share/classfile/bytecodeAssembler.cpp index e1e54b56e412b..6c34d160042ba 100644 --- a/src/hotspot/share/classfile/bytecodeAssembler.cpp +++ b/src/hotspot/share/classfile/bytecodeAssembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/bytecodeAssembler.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/classfile/classFileError.cpp b/src/hotspot/share/classfile/classFileError.cpp index 901bda5eea31c..b0a61e8cbd5d0 100644 --- a/src/hotspot/share/classfile/classFileError.cpp +++ b/src/hotspot/share/classfile/classFileError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classFileParser.hpp" #include "classfile/stackMapTable.hpp" #include "classfile/verifier.hpp" @@ -45,11 +44,11 @@ void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) const { msg, _class_name->as_C_string()); } +// The caller is required/expected to have a ResourceMark in this case. void ClassFileParser::classfile_parse_error(const char* msg, int index, TRAPS) const { assert(_class_name != nullptr, "invariant"); - ResourceMark rm(THREAD); Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), msg, index, _class_name->as_C_string()); } @@ -92,6 +91,12 @@ void ClassFileParser::classfile_icce_error(const char* msg, msg, _class_name->as_klass_external_name(), k->external_name()); } +void ClassFileParser::classfile_icce_error(const char* msg, + TRAPS) const { + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), msg); +} + void ClassFileParser::classfile_ucve_error(const char* msg, const Symbol* class_name, u2 major, diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 050359056ee84..ae66ee22511eb 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" @@ -2127,7 +2126,7 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs, // access_flags, name_index, descriptor_index, attributes_count cfs->guarantee_more(8, CHECK_NULL); - int flags = cfs->get_u2_fast(); + u2 flags = cfs->get_u2_fast(); const u2 name_index = cfs->get_u2_fast(); const int cp_size = cp->length(); guarantee_property( @@ -2981,7 +2980,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea "Class is both outer and inner class in class file %s", CHECK_0); } // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE); @@ -2998,7 +2997,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea inner_classes->at_put(index++, inner_class_info_index); inner_classes->at_put(index++, outer_class_info_index); inner_classes->at_put(index++, inner_name_index); - inner_classes->at_put(index++, inner_access_flags.as_short()); + inner_classes->at_put(index++, inner_access_flags.as_unsigned_short()); } // Check for circular and duplicate entries. @@ -3748,11 +3747,6 @@ void ClassFileParser::apply_parsed_class_metadata( this_klass->set_permitted_subclasses(_permitted_subclasses); this_klass->set_record_components(_record_components); - // Initialize cached modifier_flags to support Class.getModifiers(). - // This must follow setting inner_class attributes. - int computed_modifiers = this_klass->compute_modifier_flags(); - this_klass->set_modifier_flags(computed_modifiers); - // Delay the setting of _local_interfaces and _transitive_interfaces until after // initialize_supers() in fill_instance_klass(). It is because the _local_interfaces could // be shared with _transitive_interfaces and _transitive_interfaces may be shared with @@ -4070,9 +4064,13 @@ void ClassFileParser::check_super_class_access(const InstanceKlass* this_klass, return; } - if (super_ik->is_sealed() && !super_ik->has_as_permitted_subclass(this_klass)) { - classfile_icce_error("class %s cannot inherit from sealed class %s", super_ik, THREAD); - return; + if (super_ik->is_sealed()) { + stringStream ss; + ResourceMark rm(THREAD); + if (!super_ik->has_as_permitted_subclass(this_klass, ss)) { + classfile_icce_error(ss.as_string(), THREAD); + return; + } } Reflection::VerifyClassAccessResults vca_result = @@ -4117,12 +4115,13 @@ void ClassFileParser::check_super_interface_access(const InstanceKlass* this_kla InstanceKlass* const k = local_interfaces->at(i); assert (k != nullptr && k->is_interface(), "invalid interface"); - if (k->is_sealed() && !k->has_as_permitted_subclass(this_klass)) { - classfile_icce_error(this_klass->is_interface() ? - "class %s cannot extend sealed interface %s" : - "class %s cannot implement sealed interface %s", - k, THREAD); - return; + if (k->is_sealed()) { + stringStream ss; + ResourceMark rm(THREAD); + if (!k->has_as_permitted_subclass(this_klass, ss)) { + classfile_icce_error(ss.as_string(), THREAD); + return; + } } Reflection::VerifyClassAccessResults vca_result = @@ -5331,7 +5330,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, assert(_stream != nullptr, "invariant"); assert(_stream->buffer() == _stream->current(), "invariant"); assert(_class_name != nullptr, "invariant"); - assert(0 == _access_flags.as_int(), "invariant"); + assert(0 == _access_flags.as_unsigned_short(), "invariant"); // Figure out whether we can skip format checking (matching classic VM behavior) _need_verify = Verifier::should_verify_for(_loader_data->class_loader()); @@ -5483,7 +5482,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, stream->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len // Access flags - jint flags; + u2 flags; // JVM_ACC_MODULE is defined in JDK-9 and later. if (_major_version >= JAVA_9_VERSION) { flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE); @@ -5658,7 +5657,7 @@ void ClassFileParser::mangle_hidden_class_name(InstanceKlass* const ik) { static volatile size_t counter = 0; Atomic::cmpxchg(&counter, (size_t)0, Arguments::default_SharedBaseAddress()); // initialize it size_t new_id = Atomic::add(&counter, (size_t)1); - jio_snprintf(addr_buf, 20, SIZE_FORMAT_X, new_id); + jio_snprintf(addr_buf, 20, "0x%zx", new_id); } else { jio_snprintf(addr_buf, 20, INTPTR_FORMAT, p2i(ik)); } diff --git a/src/hotspot/share/classfile/classFileParser.hpp b/src/hotspot/share/classfile/classFileParser.hpp index e993120d14005..8f9f4ebea4d22 100644 --- a/src/hotspot/share/classfile/classFileParser.hpp +++ b/src/hotspot/share/classfile/classFileParser.hpp @@ -367,6 +367,10 @@ class ClassFileParser { const Klass* k, TRAPS) const; + // Uses msg directly in the ICCE, with no additional content + void classfile_icce_error(const char* msg, + TRAPS) const; + void classfile_ucve_error(const char* msg, const Symbol* class_name, u2 major, diff --git a/src/hotspot/share/classfile/classFileStream.cpp b/src/hotspot/share/classfile/classFileStream.cpp index a934cbafa45dd..0fc3e5b390c03 100644 --- a/src/hotspot/share/classfile/classFileStream.cpp +++ b/src/hotspot/share/classfile/classFileStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 83d0e803ee10e..3ca1ec237e866 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" -#include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.inline.hpp" @@ -159,12 +158,6 @@ ClassPathEntry* ClassLoader::_jrt_entry = nullptr; ClassPathEntry* volatile ClassLoader::_first_append_entry_list = nullptr; ClassPathEntry* volatile ClassLoader::_last_append_entry = nullptr; -#if INCLUDE_CDS -ClassPathEntry* ClassLoader::_app_classpath_entries = nullptr; -ClassPathEntry* ClassLoader::_last_app_classpath_entry = nullptr; -ClassPathEntry* ClassLoader::_module_path_entries = nullptr; -ClassPathEntry* ClassLoader::_last_module_path_entry = nullptr; -#endif // helper routines #if INCLUDE_CDS @@ -302,12 +295,9 @@ ClassFileStream* ClassPathDirEntry::open_stream(JavaThread* current, const char* return nullptr; } -ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, - bool is_boot_append, bool from_class_path_attr, bool multi_release) : ClassPathEntry() { +ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() { _zip = zip; _zip_name = copy_path(zip_name); - _from_class_path_attr = from_class_path_attr; - _multi_release = multi_release; } ClassPathZipEntry::~ClassPathZipEntry() { @@ -464,14 +454,6 @@ bool ClassPathImageEntry::is_modules_image() const { return true; } -#if INCLUDE_CDS -void ClassLoader::exit_with_path_failure(const char* error, const char* message) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - tty->print_cr("Hint: enable -Xlog:class+path=info to diagnose the failure"); - vm_exit_during_cds_dumping(error, message); -} -#endif - ModuleClassPathList::ModuleClassPathList(Symbol* module_name) { _module_name = module_name; _module_first_entry = nullptr; @@ -534,57 +516,6 @@ void ClassLoader::setup_bootstrap_search_path(JavaThread* current) { setup_bootstrap_search_path_impl(current, bootcp); } -#if INCLUDE_CDS -void ClassLoader::setup_app_search_path(JavaThread* current, const char *class_path) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - - ResourceMark rm(current); - ClasspathStream cp_stream(class_path); - - while (cp_stream.has_next()) { - const char* path = cp_stream.get_next(); - update_class_path_entry_list(current, path, /* check_for_duplicates */ true, - /* is_boot_append */ false, /* from_class_path_attr */ false); - } -} - -void ClassLoader::add_to_module_path_entries(const char* path, - ClassPathEntry* entry) { - assert(entry != nullptr, "ClassPathEntry should not be nullptr"); - assert(CDSConfig::is_dumping_archive(), "sanity"); - - // The entry does not exist, add to the list - if (_module_path_entries == nullptr) { - assert(_last_module_path_entry == nullptr, "Sanity"); - _module_path_entries = _last_module_path_entry = entry; - } else { - _last_module_path_entry->set_next(entry); - _last_module_path_entry = entry; - } -} - -// Add a module path to the _module_path_entries list. -void ClassLoader::setup_module_search_path(JavaThread* current, const char* path) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - struct stat st; - if (os::stat(path, &st) != 0) { - tty->print_cr("os::stat error %d (%s). CDS dump aborted (path was \"%s\").", - errno, os::errno_name(errno), path); - vm_exit_during_initialization(); - } - // File or directory found - ClassPathEntry* new_entry = nullptr; - new_entry = create_class_path_entry(current, path, &st, - false /*is_boot_append */, false /* from_class_path_attr */); - if (new_entry != nullptr) { - // ClassLoaderExt::process_module_table() filters out non-jar entries before calling this function. - assert(new_entry->is_jar_file(), "module path entry %s is not a jar file", new_entry->name()); - add_to_module_path_entries(path, new_entry); - } -} - -#endif // INCLUDE_CDS - void ClassLoader::close_jrt_image() { // Not applicable for exploded builds if (!ClassLoader::has_jrt_entry()) return; @@ -617,7 +548,7 @@ void ClassLoader::setup_patch_mod_entries() { struct stat st; if (os::stat(path, &st) == 0) { // File or directory found - ClassPathEntry* new_entry = create_class_path_entry(current, path, &st, false, false); + ClassPathEntry* new_entry = create_class_path_entry(current, path, &st); // If the path specification is valid, enter it into this module's list if (new_entry != nullptr) { module_cpl->add_to_list(new_entry); @@ -691,8 +622,7 @@ void ClassLoader::setup_bootstrap_search_path_impl(JavaThread* current, const ch } else { // Every entry on the boot class path after the initial base piece, // which is set by os::set_boot_path(), is considered an appended entry. - update_class_path_entry_list(current, path, /* check_for_duplicates */ false, - /* is_boot_append */ true, /* from_class_path_attr */ false); + update_class_path_entry_list(current, path); } } } @@ -723,7 +653,7 @@ void ClassLoader::add_to_exploded_build_list(JavaThread* current, Symbol* module struct stat st; if (os::stat(path, &st) == 0) { // Directory found - ClassPathEntry* new_entry = create_class_path_entry(current, path, &st, false, false); + ClassPathEntry* new_entry = create_class_path_entry(current, path, &st); // If the path specification is valid, enter it into this module's list. // There is no need to check for duplicate modules in the exploded entry list, @@ -749,10 +679,7 @@ jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg, } ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current, - const char *path, const struct stat* st, - bool is_boot_append, - bool from_class_path_attr, - bool is_multi_release) { + const char *path, const struct stat* st) { ClassPathEntry* new_entry = nullptr; if ((st->st_mode & S_IFMT) == S_IFREG) { ResourceMark rm(current); @@ -765,11 +692,8 @@ ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current, char* error_msg = nullptr; jzfile* zip = open_zip_file(canonical_path, &error_msg, current); if (zip != nullptr && error_msg == nullptr) { - new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr, is_multi_release); + new_entry = new ClassPathZipEntry(zip, path); } else { -#if INCLUDE_CDS - ClassLoaderExt::set_has_non_jar_in_classpath(); -#endif return nullptr; } log_info(class, path)("opened: %s", path); @@ -785,7 +709,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current, // Create a class path zip entry for a given path (return null if not found // or zip/JAR file cannot be opened) -ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bool is_boot_append) { +ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path) { // check for a regular file struct stat st; if (os::stat(path, &st) == 0) { @@ -798,7 +722,7 @@ ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bo jzfile* zip = open_zip_file(canonical_path, &error_msg, thread); if (zip != nullptr && error_msg == nullptr) { // create using canonical path - return new ClassPathZipEntry(zip, canonical_path, is_boot_append, false, false); + return new ClassPathZipEntry(zip, canonical_path); } } } @@ -821,70 +745,20 @@ void ClassLoader::add_to_boot_append_entries(ClassPathEntry *new_entry) { } } -// Record the path entries specified in -cp during dump time. The recorded -// information will be used at runtime for loading the archived app classes. -// -// Note that at dump time, ClassLoader::_app_classpath_entries are NOT used for -// loading app classes. Instead, the app class are loaded by the -// jdk/internal/loader/ClassLoaders$AppClassLoader instance. -bool ClassLoader::add_to_app_classpath_entries(JavaThread* current, - ClassPathEntry* entry, - bool check_for_duplicates) { -#if INCLUDE_CDS - assert(entry != nullptr, "ClassPathEntry should not be nullptr"); - ClassPathEntry* e = _app_classpath_entries; - if (check_for_duplicates) { - while (e != nullptr) { - if (strcmp(e->name(), entry->name()) == 0 && - e->from_class_path_attr() == entry->from_class_path_attr()) { - // entry already exists - return false; - } - e = e->next(); - } - } - - // The entry does not exist, add to the list - if (_app_classpath_entries == nullptr) { - assert(_last_app_classpath_entry == nullptr, "Sanity"); - _app_classpath_entries = _last_app_classpath_entry = entry; - } else { - _last_app_classpath_entry->set_next(entry); - _last_app_classpath_entry = entry; - } - - if (entry->is_jar_file()) { - ClassLoaderExt::process_jar_manifest(current, entry); - } -#endif - return true; -} - // Returns true IFF the file/dir exists and the entry was successfully created. -bool ClassLoader::update_class_path_entry_list(JavaThread* current, - const char *path, - bool check_for_duplicates, - bool is_boot_append, - bool from_class_path_attr) { +bool ClassLoader::update_class_path_entry_list(JavaThread* current, const char *path) { struct stat st; if (os::stat(path, &st) == 0) { // File or directory found ClassPathEntry* new_entry = nullptr; - new_entry = create_class_path_entry(current, path, &st, is_boot_append, from_class_path_attr); + new_entry = create_class_path_entry(current, path, &st); if (new_entry == nullptr) { return false; } // Do not reorder the bootclasspath which would break get_system_package(). // Add new entry to linked list - if (is_boot_append) { - add_to_boot_append_entries(new_entry); - } else { - if (!add_to_app_classpath_entries(current, new_entry, check_for_duplicates)) { - // new_entry is not saved, free it now - delete new_entry; - } - } + add_to_boot_append_entries(new_entry); return true; } else { return false; @@ -1319,63 +1193,61 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, int classpath_index = -1; PackageEntry* pkg_entry = ik->package(); - if (FileMapInfo::get_number_of_shared_paths() > 0) { + if (!AOTClassLocationConfig::dumptime_is_ready()) { + // The shared path table is set up after module system initialization. + // The path table contains no entry before that. Any classes loaded prior + // to the setup of the shared path table must be from the modules image. + assert(stream->from_boot_loader_modules_image(), "stream must be loaded by boot loader from modules image"); + classpath_index = 0; + } else { // Save the path from the file: protocol or the module name from the jrt: protocol // if no protocol prefix is found, path is the same as stream->source(). This path // must be valid since the class has been successfully parsed. const char* path = ClassLoader::uri_to_path(src); assert(path != nullptr, "sanity"); - for (int i = 0; i < FileMapInfo::get_number_of_shared_paths(); i++) { - SharedClassPathEntry* ent = FileMapInfo::shared_path(i); - // A shared path has been validated during its creation in ClassLoader::create_class_path_entry(), - // it must be valid here. - assert(ent->name() != nullptr, "sanity"); - // If the path (from the class stream source) is the same as the shared - // class or module path, then we have a match. - // src may come from the App/Platform class loaders, which would canonicalize - // the file name. We cannot use strcmp to check for equality against ent->name(). - // We must use os::same_files (which is faster than canonicalizing ent->name()). - if (os::same_files(ent->name(), path)) { + AOTClassLocationConfig::dumptime_iterate([&] (AOTClassLocation* cl) { + int i = cl->index(); + // for index 0 and the stream->source() is the modules image or has the jrt: protocol. + // The class must be from the runtime modules image. + if (cl->is_modules_image() && (stream->from_boot_loader_modules_image() || string_starts_with(src, "jrt:"))) { + classpath_index = i; + } else if (os::same_files(cl->path(), path)) { + // If the path (from the class stream source) is the same as the shared + // class or module path, then we have a match. + // src may come from the App/Platform class loaders, which would canonicalize + // the file name. We cannot use strcmp to check for equality against cs->path(). + // We must use os::same_files (which is faster than canonicalizing cs->path()). + // null pkg_entry and pkg_entry in an unnamed module implies the class // is from the -cp or boot loader append path which consists of -Xbootclasspath/a // and jvmti appended entries. if ((pkg_entry == nullptr) || (pkg_entry->in_unnamed_module())) { // Ensure the index is within the -cp range before assigning // to the classpath_index. - if (SystemDictionary::is_system_class_loader(loader) && - (i >= ClassLoaderExt::app_class_paths_start_index()) && - (i < ClassLoaderExt::app_module_paths_start_index())) { + if (SystemDictionary::is_system_class_loader(loader) && cl->from_app_classpath()) { classpath_index = i; - break; } else { - if ((i >= 1) && - (i < ClassLoaderExt::app_class_paths_start_index())) { + if (cl->from_boot_classpath()) { // The class must be from boot loader append path which consists of // -Xbootclasspath/a and jvmti appended entries. assert(loader == nullptr, "sanity"); classpath_index = i; - break; } } } else { // A class from a named module from the --module-path. Ensure the index is // within the --module-path range before assigning to the classpath_index. - if ((pkg_entry != nullptr) && !(pkg_entry->in_unnamed_module()) && (i > 0)) { - if (i >= ClassLoaderExt::app_module_paths_start_index() && - i < FileMapInfo::get_number_of_shared_paths()) { - classpath_index = i; - break; - } + if ((pkg_entry != nullptr) && !(pkg_entry->in_unnamed_module()) && cl->from_module_path()) { + classpath_index = i; } } } - // for index 0 and the stream->source() is the modules image or has the jrt: protocol. - // The class must be from the runtime modules image. - if (i == 0 && (stream->from_boot_loader_modules_image() || string_starts_with(src, "jrt:"))) { - classpath_index = i; - break; + if (classpath_index >= 0) { + return false; // quit iterating + } else { + return true; // Keep iterating } - } + }); // No path entry found for this class: most likely a shared class loaded by the // user defined classloader. @@ -1385,13 +1257,6 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, SystemDictionaryShared::set_shared_class_misc_info(ik, (ClassFileStream*)stream); return; } - } else { - // The shared path table is set up after module system initialization. - // The path table contains no entry before that. Any classes loaded prior - // to the setup of the shared path table must be from the modules image. - assert(stream->from_boot_loader_modules_image(), "stream must be loaded by boot loader from modules image"); - assert(FileMapInfo::get_number_of_shared_paths() == 0, "shared path table must not have been setup"); - classpath_index = 0; } const char* const class_name = ik->name()->as_C_string(); @@ -1432,7 +1297,7 @@ void ClassLoader::record_hidden_class(InstanceKlass* ik) { } else { // Generated invoker classes. if (classloader_type == ClassLoader::APP_LOADER) { - ik->set_shared_classpath_index(ClassLoaderExt::app_class_paths_start_index()); + ik->set_shared_classpath_index(AOTClassLocationConfig::dumptime()->app_cp_start_index()); } else { ik->set_shared_classpath_index(0); } @@ -1541,34 +1406,6 @@ bool ClassLoader::is_module_observable(const char* module_name) { return (*JImageFindResource)(JImage_file, module_name, jimage_version, "module-info.class", &size) != 0; } -#if INCLUDE_CDS -void ClassLoader::initialize_shared_path(JavaThread* current) { - if (CDSConfig::is_dumping_archive()) { - ClassLoaderExt::setup_search_paths(current); - } -} - -void ClassLoader::initialize_module_path(TRAPS) { - if (CDSConfig::is_dumping_archive()) { - ClassLoaderExt::setup_module_paths(THREAD); - FileMapInfo::allocate_shared_path_table(CHECK); - } -} - -// Helper function used by CDS code to get the number of module path -// entries during shared classpath setup time. -int ClassLoader::num_module_path_entries() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - int num_entries = 0; - ClassPathEntry* e= ClassLoader::_module_path_entries; - while (e != nullptr) { - num_entries ++; - e = e->next(); - } - return num_entries; -} -#endif - jlong ClassLoader::classloader_time_ms() { return UsePerfData ? Management::ticks_to_ms(_perf_accumulated_time->get_value()) : -1; diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index 8eb6593f07aa9..7827b6066e5b3 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,10 +58,6 @@ class ClassPathEntry : public CHeapObj { virtual bool is_modules_image() const { return false; } virtual bool is_jar_file() const { return false; } - virtual bool is_multi_release_jar() const { return false; } - virtual void set_multi_release_jar() {} - // Is this entry created from the "Class-path" attribute from a JAR Manifest? - virtual bool from_class_path_attr() const { return false; } virtual const char* name() const = 0; virtual JImageFile* jimage() const { return nullptr; } virtual void close_jimage() {} @@ -92,15 +88,10 @@ class ClassPathZipEntry: public ClassPathEntry { private: jzfile* _zip; // The zip archive const char* _zip_name; // Name of zip archive - bool _from_class_path_attr; // From the "Class-path" attribute of a jar file - bool _multi_release; // multi-release jar public: bool is_jar_file() const { return true; } - bool is_multi_release_jar() const { return _multi_release; } - void set_multi_release_jar() { _multi_release = true; } - bool from_class_path_attr() const { return _from_class_path_attr; } const char* name() const { return _zip_name; } - ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr, bool multi_release); + ClassPathZipEntry(jzfile* zip, const char* zip_name); virtual ~ClassPathZipEntry(); u1* open_entry(JavaThread* current, const char* name, jint* filesize, bool nul_terminate); ClassFileStream* open_stream(JavaThread* current, const char* name); @@ -226,22 +217,7 @@ class ClassLoader: AllStatic { // Last entry in linked list of appended ClassPathEntry instances static ClassPathEntry* volatile _last_append_entry; - // Info used by CDS - CDS_ONLY(static ClassPathEntry* _app_classpath_entries;) - CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;) - CDS_ONLY(static ClassPathEntry* _module_path_entries;) - CDS_ONLY(static ClassPathEntry* _last_module_path_entry;) - CDS_ONLY(static void setup_app_search_path(JavaThread* current, const char* class_path);) - CDS_ONLY(static void setup_module_search_path(JavaThread* current, const char* path);) - static bool add_to_app_classpath_entries(JavaThread* current, - ClassPathEntry* entry, - bool check_for_duplicates); - CDS_ONLY(static void add_to_module_path_entries(const char* path, - ClassPathEntry* entry);) - public: - CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;}) - CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;}) static bool has_bootclasspath_append() { return first_append_entry() != nullptr; } @@ -263,10 +239,7 @@ class ClassLoader: AllStatic { static void* zip_library_handle(); static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread); static ClassPathEntry* create_class_path_entry(JavaThread* current, - const char *path, const struct stat* st, - bool is_boot_append, - bool from_class_path_attr, - bool is_multi_release = false); + const char *path, const struct stat* st); // Canonicalizes path names, so strcmp will work properly. This is mainly // to avoid confusing the zip library @@ -276,10 +249,7 @@ class ClassLoader: AllStatic { static PackageEntry* get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data); static int crc32(int crc, const char* buf, int len); static bool update_class_path_entry_list(JavaThread* current, - const char *path, - bool check_for_duplicates, - bool is_boot_append, - bool from_class_path_attr); + const char *path); static void print_bootclasspath(); // Timing @@ -363,8 +333,6 @@ class ClassLoader: AllStatic { // Initialization static void initialize(TRAPS); static void classLoader_init2(JavaThread* current); - CDS_ONLY(static void initialize_shared_path(JavaThread* current);) - CDS_ONLY(static void initialize_module_path(TRAPS);) static int compute_Object_vtable(); @@ -373,22 +341,6 @@ class ClassLoader: AllStatic { static bool is_in_patch_mod_entries(Symbol* module_name); #if INCLUDE_CDS - // Sharing dump and restore - - // Helper function used by CDS code to get the number of boot classpath - // entries during shared classpath setup time. - static int num_boot_classpath_entries(); - - static ClassPathEntry* get_next_boot_classpath_entry(ClassPathEntry* e); - - // Helper function used by CDS code to get the number of app classpath - // entries during shared classpath setup time. - static int num_app_classpath_entries(); - - // Helper function used by CDS code to get the number of module path - // entries during shared classpath setup time. - static int num_module_path_entries(); - static void exit_with_path_failure(const char* error, const char* message); static char* uri_to_path(const char* uri); static void record_result(JavaThread* current, InstanceKlass* ik, const ClassFileStream* stream, bool redefined); @@ -419,7 +371,7 @@ class ClassLoader: AllStatic { static void add_to_boot_append_entries(ClassPathEntry* new_entry); // creates a class path zip entry (returns null if JAR file cannot be opened) - static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append); + static ClassPathZipEntry* create_class_path_zip_entry(const char *path); static bool string_ends_with(const char* str, const char* str_to_find); diff --git a/src/hotspot/share/classfile/classLoader.inline.hpp b/src/hotspot/share/classfile/classLoader.inline.hpp index 7f158a4c85476..ec3993b089ea7 100644 --- a/src/hotspot/share/classfile/classLoader.inline.hpp +++ b/src/hotspot/share/classfile/classLoader.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ #include "classfile/classLoader.hpp" -#include "cds/cdsConfig.hpp" #include "runtime/atomic.hpp" // Next entry in class path @@ -58,44 +57,4 @@ inline ClassPathEntry* ClassLoader::classpath_entry(int n) { } } -#if INCLUDE_CDS - -// Helper function used by CDS code to get the number of boot classpath -// entries during shared classpath setup time. - -inline int ClassLoader::num_boot_classpath_entries() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - assert(has_jrt_entry(), "must have a java runtime image"); - int num_entries = 1; // count the runtime image - ClassPathEntry* e = first_append_entry(); - while (e != nullptr) { - num_entries ++; - e = e->next(); - } - return num_entries; -} - -inline ClassPathEntry* ClassLoader::get_next_boot_classpath_entry(ClassPathEntry* e) { - if (e == ClassLoader::_jrt_entry) { - return first_append_entry(); - } else { - return e->next(); - } -} - -// Helper function used by CDS code to get the number of app classpath -// entries during shared classpath setup time. -inline int ClassLoader::num_app_classpath_entries() { - assert(CDSConfig::is_dumping_archive(), "sanity"); - int num_entries = 0; - ClassPathEntry* e= ClassLoader::_app_classpath_entries; - while (e != nullptr) { - num_entries ++; - e = e->next(); - } - return num_entries; -} - -#endif // INCLUDE_CDS - #endif // SHARE_CLASSFILE_CLASSLOADER_INLINE_HPP diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index de0b16a907afb..825072cb13bef 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ // The bootstrap loader (represented by null) also has a ClassLoaderData, // the singleton class the_null_class_loader_data(). -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "classfile/dictionary.hpp" diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index c7051cd58e7d6..fca6a9e74ad31 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "classfile/dictionary.hpp" diff --git a/src/hotspot/share/classfile/classLoaderDataShared.cpp b/src/hotspot/share/classfile/classLoaderDataShared.cpp index 8abe469ea2531..5cfe2df61b108 100644 --- a/src/hotspot/share/classfile/classLoaderDataShared.cpp +++ b/src/hotspot/share/classfile/classLoaderDataShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,16 +22,17 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/serializeClosure.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataShared.hpp" #include "classfile/moduleEntry.hpp" +#include "classfile/modules.hpp" #include "classfile/packageEntry.hpp" #include "classfile/systemDictionary.hpp" #include "logging/log.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/safepoint.hpp" #if INCLUDE_CDS_JAVA_HEAP @@ -144,6 +145,21 @@ static ClassLoaderData* java_system_loader_data_or_null() { return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader()); } +// ModuleEntryTables (even if empty) are required for iterate_symbols() to scan the +// platform/system loaders inside the CDS safepoint, but the tables can be created only +// when outside of safepoints. Let's do that now. +void ClassLoaderDataShared::ensure_module_entry_tables_exist() { + assert(!SafepointSynchronize::is_at_safepoint(), "sanity"); + ensure_module_entry_table_exists(SystemDictionary::java_platform_loader()); + ensure_module_entry_table_exists(SystemDictionary::java_system_loader()); +} + +void ClassLoaderDataShared::ensure_module_entry_table_exists(oop class_loader) { + Handle h_loader(JavaThread::current(), class_loader); + ModuleEntryTable* met = Modules::get_module_entry_table(h_loader); + assert(met != nullptr, "sanity"); +} + void ClassLoaderDataShared::iterate_symbols(MetaspaceClosure* closure) { assert(CDSConfig::is_dumping_full_module_graph(), "must be"); _archived_boot_loader_data.iterate_symbols (null_class_loader_data(), closure); diff --git a/src/hotspot/share/classfile/classLoaderDataShared.hpp b/src/hotspot/share/classfile/classLoaderDataShared.hpp index 957c705afdef1..b802f75103005 100644 --- a/src/hotspot/share/classfile/classLoaderDataShared.hpp +++ b/src/hotspot/share/classfile/classLoaderDataShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,9 @@ class SerializeClosure; class ClassLoaderDataShared : AllStatic { static bool _full_module_graph_loaded; + static void ensure_module_entry_table_exists(oop class_loader); public: + static void ensure_module_entry_tables_exist(); static void allocate_archived_tables(); static void iterate_symbols(MetaspaceClosure* closure); static void init_archived_tables(); diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp index f7b2906394d54..3a6fd0d933c45 100644 --- a/src/hotspot/share/classfile/classLoaderExt.cpp +++ b/src/hotspot/share/classfile/classLoaderExt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" #include "cds/dynamicArchive.hpp" @@ -52,14 +52,6 @@ #include "utilities/checkedCast.hpp" #include "utilities/stringUtils.hpp" -jshort ClassLoaderExt::_app_class_paths_start_index = ClassLoaderExt::max_classpath_index; -jshort ClassLoaderExt::_app_module_paths_start_index = ClassLoaderExt::max_classpath_index; -jshort ClassLoaderExt::_max_used_path_index = 0; -int ClassLoaderExt::_num_module_paths = 0; -bool ClassLoaderExt::_has_app_classes = false; -bool ClassLoaderExt::_has_platform_classes = false; -bool ClassLoaderExt::_has_non_jar_in_classpath = false; - void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) { if (CDSConfig::is_using_archive()) { warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended"); @@ -71,245 +63,10 @@ void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) { ClassLoader::add_to_boot_append_entries(new_entry); } -void ClassLoaderExt::setup_app_search_path(JavaThread* current) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - int start_index = ClassLoader::num_boot_classpath_entries(); - _app_class_paths_start_index = checked_cast(start_index); - char* app_class_path = os::strdup_check_oom(Arguments::get_appclasspath(), mtClass); - - if (strcmp(app_class_path, ".") == 0) { - // This doesn't make any sense, even for AppCDS, so let's skip it. We - // don't want to throw an error here because -cp "." is usually assigned - // by the launcher when classpath is not specified. - trace_class_path("app loader class path (skipped)=", app_class_path); - } else { - trace_class_path("app loader class path=", app_class_path); - ClassLoader::setup_app_search_path(current, app_class_path); - } - - os::free(app_class_path); -} - int ClassLoaderExt::compare_module_names(const char** p1, const char** p2) { return strcmp(*p1, *p2); } -void ClassLoaderExt::process_module_table(JavaThread* current, ModuleEntryTable* met) { - ResourceMark rm(current); - GrowableArray* module_paths = new GrowableArray(5); - - class ModulePathsGatherer : public ModuleClosure { - JavaThread* _current; - GrowableArray* _module_paths; - public: - ModulePathsGatherer(JavaThread* current, GrowableArray* module_paths) : - _current(current), _module_paths(module_paths) {} - void do_module(ModuleEntry* m) { - char* uri = m->location()->as_C_string(); - if (strncmp(uri, "file:", 5) == 0) { - char* path = ClassLoader::uri_to_path(uri); - extract_jar_files_from_path(path, _module_paths); - } - } - }; - - ModulePathsGatherer gatherer(current, module_paths); - { - MutexLocker ml(Module_lock); - met->modules_do(&gatherer); - } - - // Sort the module paths before storing into CDS archive for simpler - // checking at runtime. - module_paths->sort(compare_module_names); - - for (int i = 0; i < module_paths->length(); i++) { - ClassLoader::setup_module_search_path(current, module_paths->at(i)); - } -} - -void ClassLoaderExt::setup_module_paths(JavaThread* current) { - assert(CDSConfig::is_dumping_archive(), "sanity"); - int start_index = ClassLoader::num_boot_classpath_entries() + - ClassLoader::num_app_classpath_entries(); - _app_module_paths_start_index = checked_cast(start_index); - Handle system_class_loader (current, SystemDictionary::java_system_loader()); - ModuleEntryTable* met = Modules::get_module_entry_table(system_class_loader); - process_module_table(current, met); -} - -bool ClassLoaderExt::has_jar_suffix(const char* filename) { - // In jdk.internal.module.ModulePath.readModule(), it checks for the ".jar" suffix. - // Performing the same check here. - const char* dot = strrchr(filename, '.'); - if (dot != nullptr && strcmp(dot + 1, "jar") == 0) { - return true; - } - return false; -} - -void ClassLoaderExt::extract_jar_files_from_path(const char* path, GrowableArray* module_paths) { - DIR* dirp = os::opendir(path); - if (dirp == nullptr && errno == ENOTDIR && has_jar_suffix(path)) { - module_paths->append(path); - } else { - if (dirp != nullptr) { - struct dirent* dentry; - while ((dentry = os::readdir(dirp)) != nullptr) { - const char* file_name = dentry->d_name; - if (has_jar_suffix(file_name)) { - size_t full_name_len = strlen(path) + strlen(file_name) + strlen(os::file_separator()) + 1; - char* full_name = NEW_RESOURCE_ARRAY(char, full_name_len); - int n = os::snprintf(full_name, full_name_len, "%s%s%s", path, os::file_separator(), file_name); - assert((size_t)n == full_name_len - 1, "Unexpected number of characters in string"); - module_paths->append(full_name); - } - } - os::closedir(dirp); - } - } -} - -char* ClassLoaderExt::read_manifest(JavaThread* current, ClassPathEntry* entry, - jint *manifest_size, bool clean_text) { - const char* name = "META-INF/MANIFEST.MF"; - char* manifest; - jint size; - - assert(entry->is_jar_file(), "must be"); - manifest = (char*) ((ClassPathZipEntry*)entry )->open_entry(current, name, &size, true); - - if (manifest == nullptr) { // No Manifest - *manifest_size = 0; - return nullptr; - } - - - if (clean_text) { - // See http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest - // (1): replace all CR/LF and CR with LF - StringUtils::replace_no_expand(manifest, "\r\n", "\n"); - - // (2) remove all new-line continuation (remove all "\n " substrings) - StringUtils::replace_no_expand(manifest, "\n ", ""); - } - - *manifest_size = (jint)strlen(manifest); - return manifest; -} - -char* ClassLoaderExt::get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size) { - const char* tag = "Class-Path: "; - const int tag_len = (int)strlen(tag); - char* found = nullptr; - char* line_start = manifest; - char* end = manifest + manifest_size; - - assert(*end == 0, "must be nul-terminated"); - - while (line_start < end) { - char* line_end = strchr(line_start, '\n'); - if (line_end == nullptr) { - // JAR spec require the manifest file to be terminated by a new line. - break; - } - if (strncmp(tag, line_start, tag_len) == 0) { - if (found != nullptr) { - // Same behavior as jdk/src/share/classes/java/util/jar/Attributes.java - // If duplicated entries are found, the last one is used. - log_warning(cds)("Warning: Duplicate name in Manifest: %s.\n" - "Ensure that the manifest does not have duplicate entries, and\n" - "that blank lines separate individual sections in both your\n" - "manifest and in the META-INF/MANIFEST.MF entry in the jar file:\n%s\n", tag, jar_path); - } - found = line_start + tag_len; - assert(found <= line_end, "sanity"); - *line_end = '\0'; - } - line_start = line_end + 1; - } - return found; -} - -void ClassLoaderExt::process_jar_manifest(JavaThread* current, ClassPathEntry* entry) { - ResourceMark rm(current); - jint manifest_size; - char* manifest = read_manifest(current, entry, &manifest_size); - - if (manifest == nullptr) { - return; - } - - if (strstr(manifest, "Extension-List:") != nullptr) { - vm_exit_during_cds_dumping(err_msg("-Xshare:dump does not support Extension-List in JAR manifest: %s", entry->name())); - } - - if (strstr(manifest, "Multi-Release: true") != nullptr) { - entry->set_multi_release_jar(); - } - - char* cp_attr = get_class_path_attr(entry->name(), manifest, manifest_size); - - if (cp_attr != nullptr && strlen(cp_attr) > 0) { - trace_class_path("found Class-Path: ", cp_attr); - - char sep = os::file_separator()[0]; - const char* dir_name = entry->name(); - const char* dir_tail = strrchr(dir_name, sep); -#ifdef _WINDOWS - // On Windows, we also support forward slash as the file separator when locating entries in the classpath entry. - const char* dir_tail2 = strrchr(dir_name, '/'); - if (dir_tail == nullptr) { - dir_tail = dir_tail2; - } else if (dir_tail2 != nullptr && dir_tail2 > dir_tail) { - dir_tail = dir_tail2; - } -#endif - int dir_len; - if (dir_tail == nullptr) { - dir_len = 0; - } else { - dir_len = pointer_delta_as_int(dir_tail, dir_name) + 1; - } - - // Split the cp_attr by spaces, and add each file - char* file_start = cp_attr; - char* end = file_start + strlen(file_start); - - while (file_start < end) { - char* file_end = strchr(file_start, ' '); - if (file_end != nullptr) { - *file_end = 0; - file_end += 1; - } else { - file_end = end; - } - - size_t name_len = strlen(file_start); - if (name_len > 0) { - ResourceMark rm(current); - size_t libname_len = dir_len + name_len; - char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1); - int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); - assert((size_t)n == libname_len, "Unexpected number of characters in string"); - if (ClassLoader::update_class_path_entry_list(current, libname, true, false, true /* from_class_path_attr */)) { - trace_class_path("library = ", libname); - } else { - trace_class_path("library (non-existent) = ", libname); - FileMapInfo::record_non_existent_class_path_entry(libname); - } - } - - file_start = file_end; - } - } - return; -} - -void ClassLoaderExt::setup_search_paths(JavaThread* current) { - ClassLoaderExt::setup_app_search_path(current); -} - void ClassLoaderExt::record_result(const s2 classpath_index, InstanceKlass* result, bool redefined) { assert(CDSConfig::is_dumping_archive(), "sanity"); @@ -318,14 +75,12 @@ void ClassLoaderExt::record_result(const s2 classpath_index, InstanceKlass* resu s2 classloader_type = ClassLoader::BOOT_LOADER; if (SystemDictionary::is_system_class_loader(loader)) { classloader_type = ClassLoader::APP_LOADER; - ClassLoaderExt::set_has_app_classes(); + AOTClassLocationConfig::dumptime_set_has_app_classes(); } else if (SystemDictionary::is_platform_class_loader(loader)) { classloader_type = ClassLoader::PLATFORM_LOADER; - ClassLoaderExt::set_has_platform_classes(); - } - if (classpath_index > ClassLoaderExt::max_used_path_index()) { - ClassLoaderExt::set_max_used_path_index(classpath_index); + AOTClassLocationConfig::dumptime_set_has_platform_classes(); } + AOTClassLocationConfig::dumptime_update_max_used_index(classpath_index); result->set_shared_classpath_index(classpath_index); result->set_shared_class_loader_type(classloader_type); #if INCLUDE_CDS_JAVA_HEAP @@ -335,14 +90,14 @@ void ClassLoaderExt::record_result(const s2 classpath_index, InstanceKlass* resu // loaders are always loaded from known locations (jimage, classpath or modulepath), // so classpath_index should always be >= 0. // The only exception is when a java agent is used during dump time (for testing - // purposes only). If a class is transformed by the agent, the CodeSource of + // purposes only). If a class is transformed by the agent, the AOTClassLocation of // this class may point to an unknown location. This may break heap object archiving, // which requires all the boot classes to be from known locations. This is an // uncommon scenario (even in test cases). Let's simply disable heap object archiving. ResourceMark rm; log_warning(cds)("CDS heap objects cannot be written because class %s maybe modified by ClassFileLoadHook.", result->external_name()); - HeapShared::disable_writing(); + CDSConfig::disable_heap_dumping(); } #endif // INCLUDE_CDS_JAVA_HEAP } diff --git a/src/hotspot/share/classfile/classLoaderExt.hpp b/src/hotspot/share/classfile/classLoaderExt.hpp index ce0013b9d4948..86bd5cce7baa7 100644 --- a/src/hotspot/share/classfile/classLoaderExt.hpp +++ b/src/hotspot/share/classfile/classLoaderExt.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,99 +34,13 @@ class ClassListParser; class ClassLoaderExt: public ClassLoader { // AllStatic public: #if INCLUDE_CDS -private: - enum SomeConstants { - max_classpath_index = 0x7fff - }; - - static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size); - static void setup_app_search_path(JavaThread* current); // Only when -Xshare:dump - static void process_module_table(JavaThread* current, ModuleEntryTable* met); - // index of first app JAR in shared classpath entry table - static jshort _app_class_paths_start_index; - // index of first modular JAR in shared modulepath entry table - static jshort _app_module_paths_start_index; - // the largest path index being used during CDS dump time - static jshort _max_used_path_index; - // number of module paths - static int _num_module_paths; - - static bool _has_app_classes; - static bool _has_platform_classes; - static bool _has_non_jar_in_classpath; - - static char* read_manifest(JavaThread* current, ClassPathEntry* entry, jint *manifest_size, bool clean_text); - static bool has_jar_suffix(const char* filename); - public: - static void process_jar_manifest(JavaThread* current, ClassPathEntry* entry); - // Called by JVMTI code to add boot classpath + static void append_boot_classpath(ClassPathEntry* new_entry); - static void setup_search_paths(JavaThread* current); - static void setup_module_paths(JavaThread* current); - static void extract_jar_files_from_path(const char* path, GrowableArray* module_paths); static int compare_module_names(const char** p1, const char** p2); - - static char* read_manifest(JavaThread* current, ClassPathEntry* entry, jint *manifest_size) { - // Remove all the new-line continuations (which wrap long lines at 72 characters, see - // http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest), so - // that the manifest is easier to parse. - return read_manifest(current, entry, manifest_size, true); - } - static char* read_raw_manifest(JavaThread* current, ClassPathEntry* entry, jint *manifest_size) { - // Do not remove new-line continuations, so we can easily pass it as an argument to - // java.util.jar.Manifest.getManifest() at run-time. - return read_manifest(current, entry, manifest_size, false); - } - - static jshort app_class_paths_start_index() { return _app_class_paths_start_index; } - - static jshort app_module_paths_start_index() { return _app_module_paths_start_index; } - - static jshort max_used_path_index() { return _max_used_path_index; } - - static int num_module_paths() { return _num_module_paths; } - - static void set_max_used_path_index(jshort used_index) { - _max_used_path_index = used_index; - } - - static void init_paths_start_index(jshort app_start) { - _app_class_paths_start_index = app_start; - } - - static void init_app_module_paths_start_index(jshort module_start) { - _app_module_paths_start_index = module_start; - } - - static void init_num_module_paths(int num_module_paths) { - _num_module_paths = num_module_paths; - } - - static bool is_boot_classpath(int classpath_index) { - return classpath_index < _app_class_paths_start_index; - } - - static bool has_platform_or_app_classes() { - return _has_app_classes || _has_platform_classes; - } - - static bool has_non_jar_in_classpath() { - return _has_non_jar_in_classpath; - } - static void record_result(const s2 classpath_index, InstanceKlass* result, bool redefined); - static void set_has_app_classes() { - _has_app_classes = true; - } - static void set_has_platform_classes() { - _has_platform_classes = true; - } - static void set_has_non_jar_in_classpath() { - _has_non_jar_in_classpath = true; - } #endif // INCLUDE_CDS }; diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp index 8a8113db4036d..2eadb813d7eee 100644 --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" diff --git a/src/hotspot/share/classfile/classLoaderStats.cpp b/src/hotspot/share/classfile/classLoaderStats.cpp index 5fbd4ce00d922..d74e8c1deba2e 100644 --- a/src/hotspot/share/classfile/classLoaderStats.cpp +++ b/src/hotspot/share/classfile/classLoaderStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classLoaderStats.hpp" @@ -112,7 +111,7 @@ bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats const& c Klass* class_loader_klass = (cls._class_loader == nullptr ? nullptr : cls._class_loader->klass()); Klass* parent_klass = (cls._parent == nullptr ? nullptr : cls._parent->klass()); - _out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", + _out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " %6zu %8zu %8zu ", p2i(class_loader_klass), p2i(parent_klass), p2i(cls._cld), cls._classes_count, cls._chunk_sz, cls._block_sz); @@ -123,7 +122,7 @@ bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats const& c } _out->cr(); if (cls._hidden_classes_count > 0) { - _out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + hidden classes", + _out->print_cr(SPACE SPACE SPACE " %6zu %8zu %8zu + hidden classes", "", "", "", cls._hidden_classes_count, cls._hidden_chunk_sz, cls._hidden_block_sz); @@ -135,9 +134,9 @@ bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats const& c void ClassLoaderStatsClosure::print() { _out->print_cr("ClassLoader" SPACE " Parent" SPACE " CLD*" SPACE " Classes ChunkSz BlockSz Type", "", "", ""); _stats->iterate(this); - _out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders); + _out->print("Total = %-6zu", _total_loaders); _out->print(SPACE SPACE SPACE " ", "", "", ""); - _out->print_cr(UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ", + _out->print_cr("%6zu %8zu %8zu ", _total_classes, _total_chunk_sz, _total_block_sz); diff --git a/src/hotspot/share/classfile/classPrinter.cpp b/src/hotspot/share/classfile/classPrinter.cpp index 45a1eff4aed7b..c4b6a024242e7 100644 --- a/src/hotspot/share/classfile/classPrinter.cpp +++ b/src/hotspot/share/classfile/classPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classPrinter.hpp" diff --git a/src/hotspot/share/classfile/compactHashtable.cpp b/src/hotspot/share/classfile/compactHashtable.cpp index 2df8d47a3f4cb..5a3c6998904db 100644 --- a/src/hotspot/share/classfile/compactHashtable.cpp +++ b/src/hotspot/share/classfile/compactHashtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" diff --git a/src/hotspot/share/classfile/defaultMethods.cpp b/src/hotspot/share/classfile/defaultMethods.cpp index 58d24c16ad3d8..75bc33a308307 100644 --- a/src/hotspot/share/classfile/defaultMethods.cpp +++ b/src/hotspot/share/classfile/defaultMethods.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/bytecodeAssembler.hpp" #include "classfile/defaultMethods.hpp" diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index a6df19ef91598..0f79e7a5a69b5 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/dictionary.hpp" @@ -46,7 +45,7 @@ Dictionary::Dictionary(ClassLoaderData* loader_data, size_t table_size) size_t start_size_log_2 = MAX2(log2i_ceil(table_size), 2); // 2 is minimum size even though some dictionaries only have one entry size_t current_size = ((size_t)1) << start_size_log_2; - log_info(class, loader, data)("Dictionary start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", + log_info(class, loader, data)("Dictionary start size: %zu (%zu)", current_size, start_size_log_2); _table = new ConcurrentTable(start_size_log_2, END_SIZE, REHASH_LEN); } diff --git a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp index f9353465ca7c4..1af9bb8336194 100644 --- a/src/hotspot/share/classfile/fieldLayoutBuilder.cpp +++ b/src/hotspot/share/classfile/fieldLayoutBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classFileParser.hpp" #include "classfile/fieldLayoutBuilder.hpp" #include "jvm.h" diff --git a/src/hotspot/share/classfile/javaAssertions.cpp b/src/hotspot/share/classfile/javaAssertions.cpp index cf51bfb21d676..2a8f94d81b95b 100644 --- a/src/hotspot/share/classfile/javaAssertions.cpp +++ b/src/hotspot/share/classfile/javaAssertions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 1aedb43973c57..a224ef481b025 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" @@ -868,6 +867,8 @@ int java_lang_Class::_source_file_offset; int java_lang_Class::_classData_offset; int java_lang_Class::_classRedefinedCount_offset; int java_lang_Class::_reflectionData_offset; +int java_lang_Class::_modifiers_offset; +int java_lang_Class::_is_primitive_offset; bool java_lang_Class::_offsets_computed = false; GrowableArray* java_lang_Class::_fixup_mirror_list = nullptr; @@ -1061,6 +1062,10 @@ void java_lang_Class::allocate_mirror(Klass* k, bool is_scratch, Handle protecti // Setup indirection from mirror->klass set_klass(mirror(), k); + // Set the modifiers flag. + u2 computed_modifiers = k->compute_modifier_flags(); + set_modifiers(mirror(), computed_modifiers); + InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); @@ -1242,8 +1247,8 @@ void java_lang_Class::fixup_module_field(Klass* k, Handle module) { void java_lang_Class::set_oop_size(HeapWord* java_class, size_t size) { assert(_oop_size_offset != 0, "must be set"); - assert(size > 0, "Oop size must be greater than zero, not " SIZE_FORMAT, size); - assert(size <= INT_MAX, "Lossy conversion: " SIZE_FORMAT, size); + assert(size > 0, "Oop size must be greater than zero, not %zu", size); + assert(size <= INT_MAX, "Lossy conversion: %zu", size); *(int*)(((char*)java_class) + _oop_size_offset) = (int)size; } @@ -1268,8 +1273,11 @@ void java_lang_Class::set_protection_domain(oop java_class, oop pd) { void java_lang_Class::set_component_mirror(oop java_class, oop comp_mirror) { assert(_component_mirror_offset != 0, "must be set"); - java_class->obj_field_put(_component_mirror_offset, comp_mirror); - } + assert(java_lang_Class::as_Klass(java_class) != nullptr && + java_lang_Class::as_Klass(java_class)->is_array_klass(), "must be"); + java_class->obj_field_put(_component_mirror_offset, comp_mirror); +} + oop java_lang_Class::component_mirror(oop java_class) { assert(_component_mirror_offset != 0, "must be set"); return java_class->obj_field(_component_mirror_offset); @@ -1343,9 +1351,14 @@ void java_lang_Class::set_source_file(oop java_class, oop source_file) { java_class->obj_field_put(_source_file_offset, source_file); } +void java_lang_Class::set_is_primitive(oop java_class) { + assert(_is_primitive_offset != 0, "must be set"); + java_class->bool_field_put(_is_primitive_offset, true); +} + + oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { - // This should be improved by adding a field at the Java level or by - // introducing a new VM klass (see comment in ClassFileParser) + // Mirrors for basic types have a null klass field, which makes them special. oop java_class = InstanceMirrorKlass::cast(vmClasses::Class_klass())->allocate_instance(nullptr, CHECK_NULL); if (type != T_VOID) { Klass* aklass = Universe::typeArrayKlass(type); @@ -1356,6 +1369,8 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(vmClasses::Class_klass()); assert(static_oop_field_count(java_class) == 0, "should have been zeroed by allocation"); #endif + set_modifiers(java_class, JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); + set_is_primitive(java_class); return java_class; } @@ -1494,7 +1509,10 @@ oop java_lang_Class::primitive_mirror(BasicType t) { macro(_name_offset, k, "name", string_signature, false); \ macro(_classData_offset, k, "classData", object_signature, false); \ macro(_reflectionData_offset, k, "reflectionData", java_lang_ref_SoftReference_signature, false); \ - macro(_signers_offset, k, "signers", object_array_signature, false); + macro(_signers_offset, k, "signers", object_array_signature, false); \ + macro(_modifiers_offset, k, vmSymbols::modifiers_name(), char_signature, false); \ + macro(_protection_domain_offset, k, "protectionDomain", java_security_ProtectionDomain_signature, false); \ + macro(_is_primitive_offset, k, "primitive", bool_signature, false); void java_lang_Class::compute_offsets() { if (_offsets_computed) { @@ -1528,6 +1546,16 @@ void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) { the_class_mirror->int_field_put(_classRedefinedCount_offset, value); } +int java_lang_Class::modifiers(oop the_class_mirror) { + assert(_modifiers_offset != 0, "offsets should have been initialized"); + return the_class_mirror->char_field(_modifiers_offset); +} + +void java_lang_Class::set_modifiers(oop the_class_mirror, u2 value) { + assert(_modifiers_offset != 0, "offsets should have been initialized"); + the_class_mirror->char_field_put(_modifiers_offset, value); +} + // Note: JDK1.1 and before had a privateInfo_offset field which was used for the // platform thread structure, and a eetop offset which was used for thread @@ -3169,7 +3197,7 @@ void java_lang_ClassFrameInfo::serialize_offsets(SerializeClosure* f) { #endif static int get_flags(const methodHandle& m) { - int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int flags = m->access_flags().as_method_flags(); if (m->is_object_initializer()) { flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR; } else { @@ -4668,28 +4696,31 @@ int java_lang_invoke_MethodType::rtype_slot_count(oop mt) { // Support for java_lang_invoke_CallSite int java_lang_invoke_CallSite::_target_offset; -int java_lang_invoke_CallSite::_context_offset; +int java_lang_invoke_CallSite::_vmdependencies_offset; +int java_lang_invoke_CallSite::_last_cleanup_offset; #define CALLSITE_FIELDS_DO(macro) \ macro(_target_offset, k, "target", java_lang_invoke_MethodHandle_signature, false); \ - macro(_context_offset, k, "context", java_lang_invoke_MethodHandleNatives_CallSiteContext_signature, false) void java_lang_invoke_CallSite::compute_offsets() { InstanceKlass* k = vmClasses::CallSite_klass(); CALLSITE_FIELDS_DO(FIELD_COMPUTE_OFFSET); + CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } #if INCLUDE_CDS void java_lang_invoke_CallSite::serialize_offsets(SerializeClosure* f) { CALLSITE_FIELDS_DO(FIELD_SERIALIZE_OFFSET); + CALLSITE_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET); } #endif -oop java_lang_invoke_CallSite::context_no_keepalive(oop call_site) { +DependencyContext java_lang_invoke_CallSite::vmdependencies(oop call_site) { assert(java_lang_invoke_CallSite::is_instance(call_site), ""); - - oop dep_oop = call_site->obj_field_access(_context_offset); - return dep_oop; + nmethodBucket* volatile* vmdeps_addr = call_site->field_addr(_vmdependencies_offset); + volatile uint64_t* last_cleanup_addr = call_site->field_addr(_last_cleanup_offset); + DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr); + return dep_ctx; } // Support for java_lang_invoke_ConstantCallSite @@ -4710,30 +4741,6 @@ void java_lang_invoke_ConstantCallSite::serialize_offsets(SerializeClosure* f) { } #endif -// Support for java_lang_invoke_MethodHandleNatives_CallSiteContext - -int java_lang_invoke_MethodHandleNatives_CallSiteContext::_vmdependencies_offset; -int java_lang_invoke_MethodHandleNatives_CallSiteContext::_last_cleanup_offset; - -void java_lang_invoke_MethodHandleNatives_CallSiteContext::compute_offsets() { - InstanceKlass* k = vmClasses::Context_klass(); - CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); -} - -#if INCLUDE_CDS -void java_lang_invoke_MethodHandleNatives_CallSiteContext::serialize_offsets(SerializeClosure* f) { - CALLSITECONTEXT_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET); -} -#endif - -DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) { - assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), ""); - nmethodBucket* volatile* vmdeps_addr = call_site->field_addr(_vmdependencies_offset); - volatile uint64_t* last_cleanup_addr = call_site->field_addr(_last_cleanup_offset); - DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr); - return dep_ctx; -} - // Support for java_lang_ClassLoader int java_lang_ClassLoader::_loader_data_offset; @@ -5383,7 +5390,6 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) { f(java_lang_invoke_MethodType) \ f(java_lang_invoke_CallSite) \ f(java_lang_invoke_ConstantCallSite) \ - f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \ f(java_lang_reflect_AccessibleObject) \ f(java_lang_reflect_Method) \ f(java_lang_reflect_Constructor) \ @@ -5449,8 +5455,7 @@ bool JavaClasses::is_supported_for_archiving(oop obj) { if (!CDSConfig::is_dumping_invokedynamic()) { // These are supported by CDS only when CDSConfig::is_dumping_invokedynamic() is enabled. if (klass == vmClasses::ResolvedMethodName_klass() || - klass == vmClasses::MemberName_klass() || - klass == vmClasses::Context_klass()) { + klass == vmClasses::MemberName_klass()) { return false; } } @@ -5537,7 +5542,7 @@ int InjectedField::compute_offset() { ik->print(); tty->print_cr("all fields:"); for (AllFieldStream fs(ik); !fs.done(); fs.next()) { - tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); + tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_field_flags()); } #endif //PRODUCT vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class"); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 0d0fa5954b1e7..37ca22e92957b 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,7 +228,6 @@ class java_lang_String : AllStatic { macro(java_lang_Class, array_klass, intptr_signature, false) \ macro(java_lang_Class, oop_size, int_signature, false) \ macro(java_lang_Class, static_oop_field_count, int_signature, false) \ - macro(java_lang_Class, protection_domain, object_signature, false) \ macro(java_lang_Class, source_file, object_signature, false) \ macro(java_lang_Class, init_lock, object_signature, false) @@ -257,6 +256,8 @@ class java_lang_Class : AllStatic { static int _classData_offset; static int _classRedefinedCount_offset; static int _reflectionData_offset; + static int _modifiers_offset; + static int _is_primitive_offset; static bool _offsets_computed; @@ -302,6 +303,7 @@ class java_lang_Class : AllStatic { static bool is_instance(oop obj); static bool is_primitive(oop java_class); + static void set_is_primitive(oop java_class); static BasicType primitive_type(oop java_class); static oop primitive_mirror(BasicType t); // JVM_NewArray support @@ -321,12 +323,12 @@ class java_lang_Class : AllStatic { set_init_lock(java_class, nullptr); } static oop component_mirror(oop java_class); + static int component_mirror_offset() { return _component_mirror_offset; } static objArrayOop signers(oop java_class); static oop class_data(oop java_class); static void set_class_data(oop java_class, oop classData); static void set_reflection_data(oop java_class, oop reflection_data); - - static int component_mirror_offset() { return _component_mirror_offset; } + static int reflection_data_offset() { return _reflectionData_offset; } static oop class_loader(oop java_class); static void set_module(oop java_class, oop module); @@ -337,6 +339,9 @@ class java_lang_Class : AllStatic { static oop source_file(oop java_class); static void set_source_file(oop java_class, oop source_file); + static int modifiers(oop java_class); + static void set_modifiers(oop java_class, u2 value); + static size_t oop_size(oop java_class); static void set_oop_size(HeapWord* java_class, size_t size); static int static_oop_field_count(oop java_class); @@ -1409,13 +1414,17 @@ class java_lang_invoke_MethodType: AllStatic { // Interface to java.lang.invoke.CallSite objects +#define CALLSITE_INJECTED_FIELDS(macro) \ + macro(java_lang_invoke_CallSite, vmdependencies, intptr_signature, false) \ + macro(java_lang_invoke_CallSite, last_cleanup, long_signature, false) class java_lang_invoke_CallSite: AllStatic { friend class JavaClasses; private: static int _target_offset; - static int _context_offset; + static int _vmdependencies_offset; + static int _last_cleanup_offset; static void compute_offsets(); @@ -1426,7 +1435,7 @@ class java_lang_invoke_CallSite: AllStatic { static void set_target( oop site, oop target); static void set_target_volatile( oop site, oop target); - static oop context_no_keepalive(oop site); + static DependencyContext vmdependencies(oop call_site); // Testers static bool is_subclass(Klass* klass) { @@ -1436,7 +1445,6 @@ class java_lang_invoke_CallSite: AllStatic { // Accessors for code generation: static int target_offset() { CHECK_INIT(_target_offset); } - static int context_offset() { CHECK_INIT(_context_offset); } }; // Interface to java.lang.invoke.ConstantCallSite objects @@ -1461,35 +1469,6 @@ class java_lang_invoke_ConstantCallSite: AllStatic { static bool is_instance(oop obj); }; -// Interface to java.lang.invoke.MethodHandleNatives$CallSiteContext objects - -#define CALLSITECONTEXT_INJECTED_FIELDS(macro) \ - macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, vmdependencies, intptr_signature, false) \ - macro(java_lang_invoke_MethodHandleNatives_CallSiteContext, last_cleanup, long_signature, false) - -class DependencyContext; - -class java_lang_invoke_MethodHandleNatives_CallSiteContext : AllStatic { - friend class JavaClasses; - -private: - static int _vmdependencies_offset; - static int _last_cleanup_offset; - - static void compute_offsets(); - -public: - static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; - // Accessors - static DependencyContext vmdependencies(oop context); - - // Testers - static bool is_subclass(Klass* klass) { - return klass->is_subclass_of(vmClasses::Context_klass()); - } - static bool is_instance(oop obj); -}; - // Interface to java.lang.ClassLoader objects #define CLASSLOADER_INJECTED_FIELDS(macro) \ diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 682806b8f3dfa..66ecca4bbeaa4 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -263,10 +263,6 @@ inline bool java_lang_invoke_ConstantCallSite::is_instance(oop obj) { return obj != nullptr && is_subclass(obj->klass()); } -inline bool java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(oop obj) { - return obj != nullptr && is_subclass(obj->klass()); -} - inline bool java_lang_invoke_MemberName::is_instance(oop obj) { return obj != nullptr && obj->klass() == vmClasses::MemberName_klass(); } @@ -297,11 +293,13 @@ inline Klass* java_lang_Class::as_Klass(oop java_class) { inline bool java_lang_Class::is_primitive(oop java_class) { // should assert: - //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); + // assert(java_lang_Class::is_instance(java_class), "must be a Class object"); bool is_primitive = (java_class->metadata_field(_klass_offset) == nullptr); #ifdef ASSERT - if (is_primitive) { + // The heapwalker walks through Classes that have had their Klass pointers removed, so can't assert this. + // assert(is_primitive == java_class->bool_field(_is_primitive_offset), "must match what we told Java"); + if (java_class->bool_field(_is_primitive_offset)) { Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset)); assert(k == nullptr || is_java_primitive(ArrayKlass::cast(k)->element_type()), "Should be either the T_VOID primitive or a java primitive"); diff --git a/src/hotspot/share/classfile/javaClassesImpl.hpp b/src/hotspot/share/classfile/javaClassesImpl.hpp index 5f4df9391e388..b450a4e3cc417 100644 --- a/src/hotspot/share/classfile/javaClassesImpl.hpp +++ b/src/hotspot/share/classfile/javaClassesImpl.hpp @@ -36,7 +36,7 @@ CLASSLOADER_INJECTED_FIELDS(macro) \ RESOLVEDMETHOD_INJECTED_FIELDS(macro) \ MEMBERNAME_INJECTED_FIELDS(macro) \ - CALLSITECONTEXT_INJECTED_FIELDS(macro) \ + CALLSITE_INJECTED_FIELDS(macro) \ STACKFRAMEINFO_INJECTED_FIELDS(macro) \ MODULE_INJECTED_FIELDS(macro) \ THREAD_INJECTED_FIELDS(macro) \ diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp index 493fc27dd4308..52da747d8b6e9 100644 --- a/src/hotspot/share/classfile/klassFactory.cpp +++ b/src/hotspot/share/classfile/klassFactory.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/filemap.hpp" #include "classfile/classFileParser.hpp" diff --git a/src/hotspot/share/classfile/loaderConstraints.cpp b/src/hotspot/share/classfile/loaderConstraints.cpp index 99d0c07ed42d4..21161f443260c 100644 --- a/src/hotspot/share/classfile/loaderConstraints.cpp +++ b/src/hotspot/share/classfile/loaderConstraints.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/dictionary.hpp" diff --git a/src/hotspot/share/classfile/metadataOnStackMark.cpp b/src/hotspot/share/classfile/metadataOnStackMark.cpp index faf1053dd87e8..51ce2c263a357 100644 --- a/src/hotspot/share/classfile/metadataOnStackMark.cpp +++ b/src/hotspot/share/classfile/metadataOnStackMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/metadataOnStackMark.hpp" #include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index af4332ca6912e..55363d7f41fcb 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,10 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" -#include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -62,7 +61,7 @@ void ModuleEntry::set_location(Symbol* location) { if (location != nullptr) { location->increment_refcount(); CDS_ONLY(if (CDSConfig::is_using_archive()) { - _shared_path_index = FileMapInfo::get_module_shared_path_index(location); + _shared_path_index = AOTClassLocationConfig::runtime()->get_module_shared_path_index(_location); }); } } @@ -400,7 +399,12 @@ ModuleEntry* ModuleEntry::allocate_archived_entry() const { assert(is_named(), "unnamed packages/modules are not archived"); ModuleEntry* archived_entry = (ModuleEntry*)ArchiveBuilder::rw_region_alloc(sizeof(ModuleEntry)); memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry)); - archived_entry->_archived_module_index = -1; + + if (CDSConfig::is_dumping_full_module_graph()) { + archived_entry->_archived_module_index = HeapShared::append_root(module()); + } else { + archived_entry->_archived_module_index = -1; + } if (_archive_modules_entries == nullptr) { _archive_modules_entries = new (mtClass)ArchivedModuleEntries(); @@ -409,6 +413,14 @@ ModuleEntry* ModuleEntry::allocate_archived_entry() const { _archive_modules_entries->put(this, archived_entry); DEBUG_ONLY(_num_archived_module_entries++); + assert(archived_entry->shared_protection_domain() == nullptr, "never set during -Xshare:dump"); + // Clear handles and restore at run time. Handles cannot be archived. + OopHandle null_handle; + archived_entry->_module = null_handle; + + // For verify_archived_module_entries() + DEBUG_ONLY(_num_inited_module_entries++); + if (log_is_enabled(Info, cds, module)) { ResourceMark rm; LogStream ls(Log(cds, module)::info()); @@ -471,7 +483,7 @@ void ModuleEntry::init_as_archived_entry() { set_archived_reads(write_growable_array(reads())); _loader_data = nullptr; // re-init at runtime - _shared_path_index = FileMapInfo::get_module_shared_path_index(_location); + _shared_path_index = AOTClassLocationConfig::dumptime()->get_module_shared_path_index(_location); if (name() != nullptr) { _name = ArchiveBuilder::get_buffered_symbol(_name); ArchivePtrMarker::mark_pointer((address*)&_name); @@ -489,22 +501,6 @@ void ModuleEntry::init_as_archived_entry() { ArchivePtrMarker::mark_pointer((address*)&_location); } -void ModuleEntry::update_oops_in_archived_module(int root_oop_index) { - assert(CDSConfig::is_dumping_full_module_graph(), "sanity"); - assert(_archived_module_index == -1, "must be set exactly once"); - assert(root_oop_index >= 0, "sanity"); - - _archived_module_index = root_oop_index; - - assert(shared_protection_domain() == nullptr, "never set during -Xshare:dump"); - // Clear handles and restore at run time. Handles cannot be archived. - OopHandle null_handle; - _module = null_handle; - - // For verify_archived_module_entries() - DEBUG_ONLY(_num_inited_module_entries++); -} - #ifndef PRODUCT void ModuleEntry::verify_archived_module_entries() { assert(_num_archived_module_entries == _num_inited_module_entries, @@ -742,7 +738,7 @@ void ModuleEntryTable::modules_do(ModuleClosure* closure) { void ModuleEntry::print(outputStream* st) { st->print_cr("entry " PTR_FORMAT " name %s module " PTR_FORMAT " loader %s version %s location %s strict %s", p2i(this), - name() == nullptr ? UNNAMED_MODULE : name()->as_C_string(), + name_as_C_string(), p2i(module()), loader_data()->loader_name_and_id(), version() != nullptr ? version()->as_C_string() : "nullptr", diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp index 1100dbf85700d..9ad7bde8954e3 100644 --- a/src/hotspot/share/classfile/moduleEntry.hpp +++ b/src/hotspot/share/classfile/moduleEntry.hpp @@ -185,6 +185,10 @@ class ModuleEntry : public CHeapObj { static ModuleEntry* create_boot_unnamed_module(ClassLoaderData* cld); static ModuleEntry* new_unnamed_module_entry(Handle module_handle, ClassLoaderData* cld); + // Note caller requires ResourceMark + const char* name_as_C_string() { + return is_named() ? name()->as_C_string() : UNNAMED_MODULE; + } void print(outputStream* st = tty); void verify(); diff --git a/src/hotspot/share/classfile/modules.cpp b/src/hotspot/share/classfile/modules.cpp index 7e26febda89f2..950ca699a8e92 100644 --- a/src/hotspot/share/classfile/modules.cpp +++ b/src/hotspot/share/classfile/modules.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" @@ -483,9 +482,7 @@ static bool _seen_platform_unnamed_module = false; static bool _seen_system_unnamed_module = false; // Validate the states of an java.lang.Module oop to be archived. -// -// Returns true iff the oop has an archived ModuleEntry. -bool Modules::check_archived_module_oop(oop orig_module_obj) { +void Modules::check_archived_module_oop(oop orig_module_obj) { assert(CDSConfig::is_dumping_full_module_graph(), "must be"); assert(java_lang_Module::is_instance(orig_module_obj), "must be"); @@ -498,7 +495,6 @@ bool Modules::check_archived_module_oop(oop orig_module_obj) { // jdk.internal.loader.ClassLoaders$BootClassLoader::unnamedModule log_info(cds, module)("Archived java.lang.Module oop " PTR_FORMAT " with no ModuleEntry*", p2i(orig_module_obj)); assert(java_lang_Module::name(orig_module_obj) == nullptr, "must be unnamed"); - return false; } else { // This java.lang.Module oop has an ModuleEntry*. Check if the latter is archived. if (log_is_enabled(Info, cds, module)) { @@ -516,7 +512,6 @@ bool Modules::check_archived_module_oop(oop orig_module_obj) { if (orig_module_ent->name() != nullptr) { // For each named module, we archive both the java.lang.Module oop and the ModuleEntry. assert(orig_module_ent->has_been_archived(), "sanity"); - return true; } else { // We only archive two unnamed module oops (for platform and system loaders). These do NOT have an archived // ModuleEntry. @@ -538,24 +533,10 @@ bool Modules::check_archived_module_oop(oop orig_module_obj) { // not in the archived module graph. These are always allocated at runtime. ShouldNotReachHere(); } - return false; } } } -void Modules::update_oops_in_archived_module(oop orig_module_obj, int archived_module_root_index) { - // This java.lang.Module oop must have an archived ModuleEntry - assert(check_archived_module_oop(orig_module_obj) == true, "sanity"); - - // We remember the oop inside the ModuleEntry::_archived_module_index. At runtime, we use - // this index to reinitialize the ModuleEntry inside ModuleEntry::restore_archived_oops(). - // - // ModuleEntry::verify_archived_module_entries(), called below, ensures that every archived - // ModuleEntry has been assigned an _archived_module_index. - ModuleEntry* orig_module_ent = java_lang_Module::module_entry_raw(orig_module_obj); - ModuleEntry::get_archived_entry(orig_module_ent)->update_oops_in_archived_module(archived_module_root_index); -} - void Modules::verify_archived_modules() { ModuleEntry::verify_archived_module_entries(); } @@ -628,12 +609,14 @@ void Modules::serialize(SerializeClosure* soc) { } void Modules::dump_native_access_flag() { + ResourceMark rm; const char* native_access_names = get_native_access_flags_as_sorted_string(); if (native_access_names != nullptr) { _archived_native_access_flags = ArchiveBuilder::current()->ro_strdup(native_access_names); } } +// Caller needs ResourceMark const char* Modules::get_native_access_flags_as_sorted_string() { return get_numbered_property_as_sorted_string("jdk.module.enable.native.access"); } @@ -641,6 +624,7 @@ const char* Modules::get_native_access_flags_as_sorted_string() { void Modules::serialize_native_access_flags(SerializeClosure* soc) { soc->do_ptr(&_archived_native_access_flags); if (soc->reading()) { + ResourceMark rm; check_archived_flag_consistency(_archived_native_access_flags, get_native_access_flags_as_sorted_string(), "jdk.module.enable.native.access"); // Don't hold onto the pointer, in case we might decide to unmap the archive. @@ -649,12 +633,14 @@ void Modules::serialize_native_access_flags(SerializeClosure* soc) { } void Modules::dump_addmods_names() { + ResourceMark rm; const char* addmods_names = get_addmods_names_as_sorted_string(); if (addmods_names != nullptr) { _archived_addmods_names = ArchiveBuilder::current()->ro_strdup(addmods_names); } } +// Caller needs ResourceMark const char* Modules::get_addmods_names_as_sorted_string() { return get_numbered_property_as_sorted_string("jdk.module.addmods"); } @@ -662,6 +648,7 @@ const char* Modules::get_addmods_names_as_sorted_string() { void Modules::serialize_addmods_names(SerializeClosure* soc) { soc->do_ptr(&_archived_addmods_names); if (soc->reading()) { + ResourceMark rm; check_archived_flag_consistency(_archived_addmods_names, get_addmods_names_as_sorted_string(), "jdk.module.addmods"); // Don't hold onto the pointer, in case we might decide to unmap the archive. @@ -669,8 +656,8 @@ void Modules::serialize_addmods_names(SerializeClosure* soc) { } } +// Caller needs ResourceMark const char* Modules::get_numbered_property_as_sorted_string(const char* property) { - ResourceMark rm; // theoretical string size limit for decimal int, but the following loop will end much sooner due to // OS command-line size limit. const int max_digits = 10; @@ -723,7 +710,7 @@ const char* Modules::get_numbered_property_as_sorted_string(const char* property } } - return (st.size() > 0) ? os::strdup(st.as_string()) : nullptr; // Example: "java.base,java.compiler" + return (st.size() > 0) ? st.as_string() : nullptr; // Example: "java.base,java.compiler" } void Modules::define_archived_modules(Handle h_platform_loader, Handle h_system_loader, TRAPS) { diff --git a/src/hotspot/share/classfile/modules.hpp b/src/hotspot/share/classfile/modules.hpp index 03069bd345209..2c23ab5f6ea65 100644 --- a/src/hotspot/share/classfile/modules.hpp +++ b/src/hotspot/share/classfile/modules.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,9 +53,7 @@ class Modules : AllStatic { static void define_module(Handle module, jboolean is_open, jstring version, jstring location, jobjectArray packages, TRAPS); - static bool check_archived_module_oop(oop orig_module_obj) NOT_CDS_JAVA_HEAP_RETURN_(false); - static void update_oops_in_archived_module(oop orig_module_obj, int archived_module_root_index) - NOT_CDS_JAVA_HEAP_RETURN; + static void check_archived_module_oop(oop orig_module_obj) NOT_CDS_JAVA_HEAP_RETURN; static void define_archived_modules(Handle h_platform_loader, Handle h_system_loader, TRAPS) NOT_CDS_JAVA_HEAP_RETURN; static void verify_archived_modules() NOT_CDS_JAVA_HEAP_RETURN; diff --git a/src/hotspot/share/classfile/packageEntry.cpp b/src/hotspot/share/classfile/packageEntry.cpp index 052960e1735dd..eaa311c4bd386 100644 --- a/src/hotspot/share/classfile/packageEntry.cpp +++ b/src/hotspot/share/classfile/packageEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" diff --git a/src/hotspot/share/classfile/placeholders.cpp b/src/hotspot/share/classfile/placeholders.cpp index 38d359efcc245..6ee421fa023e9 100644 --- a/src/hotspot/share/classfile/placeholders.cpp +++ b/src/hotspot/share/classfile/placeholders.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/placeholders.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index 1f2e75e92571f..03af71bc26f71 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/resolutionErrors.hpp" #include "memory/allocation.hpp" #include "oops/constantPool.hpp" diff --git a/src/hotspot/share/classfile/stackMapFrame.cpp b/src/hotspot/share/classfile/stackMapFrame.cpp index d9a5fa5ce93cf..c71a278e0b8d0 100644 --- a/src/hotspot/share/classfile/stackMapFrame.cpp +++ b/src/hotspot/share/classfile/stackMapFrame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/stackMapFrame.hpp" #include "classfile/verifier.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/classfile/stackMapTable.cpp b/src/hotspot/share/classfile/stackMapTable.cpp index fa2a57f96b473..b452beecb0093 100644 --- a/src/hotspot/share/classfile/stackMapTable.cpp +++ b/src/hotspot/share/classfile/stackMapTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/stackMapTable.hpp" #include "classfile/verifier.hpp" #include "memory/resourceArea.hpp" @@ -30,38 +29,49 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" -StackMapTable::StackMapTable(StackMapReader* reader, StackMapFrame* init_frame, - u2 max_locals, u2 max_stack, - char* code_data, int code_len, TRAPS) { - _code_length = code_len; +StackMapTable::StackMapTable(StackMapReader* reader, TRAPS) { + _code_length = reader->code_length(); _frame_count = reader->get_frame_count(); if (_frame_count > 0) { - _frame_array = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, - StackMapFrame*, _frame_count); - StackMapFrame* pre_frame = init_frame; - for (int32_t i = 0; i < _frame_count; i++) { - StackMapFrame* frame = reader->next( - pre_frame, i == 0, max_locals, max_stack, - CHECK_VERIFY(pre_frame->verifier())); - _frame_array[i] = frame; - int offset = frame->offset(); - if (offset >= code_len || code_data[offset] == 0) { - frame->verifier()->verify_error( - ErrorContext::bad_stackmap(i, frame), - "StackMapTable error: bad offset"); - return; + _frame_array = new GrowableArray(_frame_count); + while (!reader->at_end()) { + StackMapFrame* frame = reader->next(CHECK_VERIFY(reader->prev_frame()->verifier())); + if (frame != nullptr) { + _frame_array->push(frame); } - pre_frame = frame; } + reader->check_end(CHECK); + // Correct frame count based on how many actual frames are generated + _frame_count = _frame_array->length(); + } +} + +void StackMapReader::check_offset(StackMapFrame* frame) { + int offset = frame->offset(); + if (offset >= _code_length || _code_data[offset] == 0) { + _verifier->verify_error(ErrorContext::bad_stackmap(0, frame), + "StackMapTable error: bad offset"); + } +} + +void StackMapReader::check_size(TRAPS) { + if (_frame_count < _parsed_frame_count) { + StackMapStream::stackmap_format_error("wrong attribute size", THREAD); + } +} + +void StackMapReader::check_end(TRAPS) { + assert(_stream->at_end(), "must be"); + if (_frame_count != _parsed_frame_count) { + StackMapStream::stackmap_format_error("wrong attribute size", THREAD); } - reader->check_end(CHECK); } // This method is only called by method in StackMapTable. int StackMapTable::get_index_from_offset(int32_t offset) const { int i = 0; for (; i < _frame_count; i++) { - if (_frame_array[i]->offset() == offset) { + if (_frame_array->at(i)->offset() == offset) { return i; } } @@ -96,7 +106,7 @@ bool StackMapTable::match_stackmap( return false; } - StackMapFrame *stackmap_frame = _frame_array[frame_index]; + StackMapFrame* stackmap_frame = _frame_array->at(frame_index); bool result = true; if (match) { // Has direct control flow from last instruction, need to match the two @@ -138,16 +148,20 @@ void StackMapTable::print_on(outputStream* str) const { { streamIndentor si(str); for (int32_t i = 0; i < _frame_count; ++i) { - _frame_array[i]->print_on(str); + _frame_array->at(i)->print_on(str); } } str->print_cr(" }"); } -StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data, - int32_t code_len, TRAPS) : - _verifier(v), _stream(stream), - _code_data(code_data), _code_length(code_len) { +StackMapReader::StackMapReader(ClassVerifier* v, StackMapStream* stream, + char* code_data, int32_t code_len, + StackMapFrame* init_frame, + u2 max_locals, u2 max_stack, TRAPS) : + _verifier(v), _stream(stream), _code_data(code_data), + _code_length(code_len), _parsed_frame_count(0), + _prev_frame(init_frame), _max_locals(max_locals), + _max_stack(max_stack), _first(true) { methodHandle m = v->method(); if (m->has_stackmap_table()) { _cp = constantPoolHandle(THREAD, m->constants()); @@ -211,45 +225,59 @@ VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) { return VerificationType::bogus_type(); } -StackMapFrame* StackMapReader::next( - StackMapFrame* pre_frame, bool first, u2 max_locals, u2 max_stack, TRAPS) { +StackMapFrame* StackMapReader::next(TRAPS) { + _parsed_frame_count++; + check_size(CHECK_NULL); + StackMapFrame* frame = next_helper(CHECK_VERIFY_(_verifier, nullptr)); + if (frame != nullptr) { + check_offset(frame); + if (frame->verifier()->has_error()) { + return nullptr; + } + _prev_frame = frame; + } + return frame; +} + +StackMapFrame* StackMapReader::next_helper(TRAPS) { StackMapFrame* frame; int offset; VerificationType* locals = nullptr; u1 frame_type = _stream->get_u1(CHECK_NULL); if (frame_type < 64) { // same_frame - if (first) { + if (_first) { offset = frame_type; // Can't share the locals array since that is updated by the verifier. - if (pre_frame->locals_size() > 0) { + if (_prev_frame->locals_size() > 0) { locals = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, VerificationType, pre_frame->locals_size()); + THREAD, VerificationType, _prev_frame->locals_size()); } } else { - offset = pre_frame->offset() + frame_type + 1; - locals = pre_frame->locals(); + offset = _prev_frame->offset() + frame_type + 1; + locals = _prev_frame->locals(); } frame = new StackMapFrame( - offset, pre_frame->flags(), pre_frame->locals_size(), 0, - max_locals, max_stack, locals, nullptr, _verifier); - if (first && locals != nullptr) { - frame->copy_locals(pre_frame); + offset, _prev_frame->flags(), _prev_frame->locals_size(), 0, + _max_locals, _max_stack, locals, nullptr, _verifier); + if (_first && locals != nullptr) { + frame->copy_locals(_prev_frame); } + _first = false; return frame; } if (frame_type < 128) { // same_locals_1_stack_item_frame - if (first) { + if (_first) { offset = frame_type - 64; // Can't share the locals array since that is updated by the verifier. - if (pre_frame->locals_size() > 0) { + if (_prev_frame->locals_size() > 0) { locals = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, VerificationType, pre_frame->locals_size()); + THREAD, VerificationType, _prev_frame->locals_size()); } } else { - offset = pre_frame->offset() + frame_type - 63; - locals = pre_frame->locals(); + offset = _prev_frame->offset() + frame_type - 63; + locals = _prev_frame->locals(); } VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, VerificationType, 2); @@ -260,13 +288,14 @@ StackMapFrame* StackMapReader::next( stack_size = 2; } check_verification_type_array_size( - stack_size, max_stack, CHECK_VERIFY_(_verifier, nullptr)); + stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr)); frame = new StackMapFrame( - offset, pre_frame->flags(), pre_frame->locals_size(), stack_size, - max_locals, max_stack, locals, stack, _verifier); - if (first && locals != nullptr) { - frame->copy_locals(pre_frame); + offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size, + _max_locals, _max_stack, locals, stack, _verifier); + if (_first && locals != nullptr) { + frame->copy_locals(_prev_frame); } + _first = false; return frame; } @@ -280,16 +309,16 @@ StackMapFrame* StackMapReader::next( if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) { // same_locals_1_stack_item_frame_extended - if (first) { + if (_first) { offset = offset_delta; // Can't share the locals array since that is updated by the verifier. - if (pre_frame->locals_size() > 0) { + if (_prev_frame->locals_size() > 0) { locals = NEW_RESOURCE_ARRAY_IN_THREAD( - THREAD, VerificationType, pre_frame->locals_size()); + THREAD, VerificationType, _prev_frame->locals_size()); } } else { - offset = pre_frame->offset() + offset_delta + 1; - locals = pre_frame->locals(); + offset = _prev_frame->offset() + offset_delta + 1; + locals = _prev_frame->locals(); } VerificationType* stack = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, VerificationType, 2); @@ -300,27 +329,28 @@ StackMapFrame* StackMapReader::next( stack_size = 2; } check_verification_type_array_size( - stack_size, max_stack, CHECK_VERIFY_(_verifier, nullptr)); + stack_size, _max_stack, CHECK_VERIFY_(_verifier, nullptr)); frame = new StackMapFrame( - offset, pre_frame->flags(), pre_frame->locals_size(), stack_size, - max_locals, max_stack, locals, stack, _verifier); - if (first && locals != nullptr) { - frame->copy_locals(pre_frame); + offset, _prev_frame->flags(), _prev_frame->locals_size(), stack_size, + _max_locals, _max_stack, locals, stack, _verifier); + if (_first && locals != nullptr) { + frame->copy_locals(_prev_frame); } + _first = false; return frame; } if (frame_type <= SAME_EXTENDED) { // chop_frame or same_frame_extended - locals = pre_frame->locals(); - int length = pre_frame->locals_size(); + locals = _prev_frame->locals(); + int length = _prev_frame->locals_size(); int chops = SAME_EXTENDED - frame_type; int new_length = length; - u1 flags = pre_frame->flags(); + u1 flags = _prev_frame->flags(); if (chops != 0) { new_length = chop(locals, length, chops); check_verification_type_array_size( - new_length, max_locals, CHECK_VERIFY_(_verifier, nullptr)); + new_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr)); // Recompute flags since uninitializedThis could have been chopped. flags = 0; for (int i=0; i 0) { @@ -340,28 +370,28 @@ StackMapFrame* StackMapReader::next( locals = nullptr; } } else { - offset = pre_frame->offset() + offset_delta + 1; + offset = _prev_frame->offset() + offset_delta + 1; } frame = new StackMapFrame( - offset, flags, new_length, 0, max_locals, max_stack, + offset, flags, new_length, 0, _max_locals, _max_stack, locals, nullptr, _verifier); - if (first && locals != nullptr) { - frame->copy_locals(pre_frame); + if (_first && locals != nullptr) { + frame->copy_locals(_prev_frame); } + _first = false; return frame; } else if (frame_type < SAME_EXTENDED + 4) { // append_frame int appends = frame_type - SAME_EXTENDED; - int real_length = pre_frame->locals_size(); + int real_length = _prev_frame->locals_size(); int new_length = real_length + appends*2; locals = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, new_length); - VerificationType* pre_locals = pre_frame->locals(); - int i; - for (i=0; ilocals_size(); i++) { + VerificationType* pre_locals = _prev_frame->locals(); + for (int i = 0; i < _prev_frame->locals_size(); i++) { locals[i] = pre_locals[i]; } - u1 flags = pre_frame->flags(); - for (i=0; iflags(); + for (int i = 0; i < appends; i++) { locals[real_length] = parse_verification_type(&flags, CHECK_NULL); if (locals[real_length].is_category2()) { locals[real_length + 1] = locals[real_length].to_category2_2nd(); @@ -370,15 +400,16 @@ StackMapFrame* StackMapReader::next( ++real_length; } check_verification_type_array_size( - real_length, max_locals, CHECK_VERIFY_(_verifier, nullptr)); - if (first) { + real_length, _max_locals, CHECK_VERIFY_(_verifier, nullptr)); + if (_first) { offset = offset_delta; } else { - offset = pre_frame->offset() + offset_delta + 1; + offset = _prev_frame->offset() + offset_delta + 1; } frame = new StackMapFrame( - offset, flags, real_length, 0, max_locals, - max_stack, locals, nullptr, _verifier); + offset, flags, real_length, 0, _max_locals, + _max_stack, locals, nullptr, _verifier); + _first = false; return frame; } if (frame_type == FULL) { @@ -390,8 +421,7 @@ StackMapFrame* StackMapReader::next( locals = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, VerificationType, locals_size*2); } - int i; - for (i=0; iget_u2(CHECK_NULL); int real_stack_size = 0; VerificationType* stack = nullptr; @@ -409,7 +439,7 @@ StackMapFrame* StackMapReader::next( stack = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, VerificationType, stack_size*2); } - for (i=0; ioffset() + offset_delta + 1; + offset = _prev_frame->offset() + offset_delta + 1; } frame = new StackMapFrame( offset, flags, real_locals_size, real_stack_size, - max_locals, max_stack, locals, stack, _verifier); + _max_locals, _max_stack, locals, stack, _verifier); + _first = false; return frame; } _stream->stackmap_format_error( - "reserved frame type", CHECK_VERIFY_(pre_frame->verifier(), nullptr)); + "reserved frame type", CHECK_VERIFY_(_prev_frame->verifier(), nullptr)); return nullptr; } diff --git a/src/hotspot/share/classfile/stackMapTable.hpp b/src/hotspot/share/classfile/stackMapTable.hpp index a8ec3fc45dbbf..cc4202f32806a 100644 --- a/src/hotspot/share/classfile/stackMapTable.hpp +++ b/src/hotspot/share/classfile/stackMapTable.hpp @@ -44,16 +44,14 @@ class StackMapTable : public StackObj { // Widening the type and making it signed will help detect these. int32_t _code_length; int32_t _frame_count; // Stackmap frame count - StackMapFrame** _frame_array; + GrowableArray* _frame_array; public: - StackMapTable(StackMapReader* reader, StackMapFrame* init_frame, - u2 max_locals, u2 max_stack, - char* code_data, int code_len, TRAPS); + StackMapTable(StackMapReader* reader, TRAPS); inline int32_t get_frame_count() const { return _frame_count; } inline int get_offset(int index) const { - return _frame_array[index]->offset(); + return _frame_array->at(index)->offset(); } // Match and/or update current_frame to the frame in stackmap table with @@ -116,9 +114,25 @@ class StackMapReader : StackObj { char* _code_data; int32_t _code_length; - // information get from the attribute - int32_t _frame_count; // frame count + // information from the attribute + int32_t _frame_count; + // Number of frames parsed + int32_t _parsed_frame_count; + + // Previous frame buffer + StackMapFrame* _prev_frame; + + // information from method + u2 _max_locals; + u2 _max_stack; + + // Check if reading first entry + bool _first; + + StackMapFrame* next_helper(TRAPS); + void check_offset(StackMapFrame* frame); + void check_size(TRAPS); int32_t chop(VerificationType* locals, int32_t length, int32_t chops); VerificationType parse_verification_type(u1* flags, TRAPS); void check_verification_type_array_size( @@ -141,18 +155,19 @@ class StackMapReader : StackObj { public: // Constructor - StackMapReader(ClassVerifier* v, StackMapStream* stream, char* code_data, - int32_t code_len, TRAPS); - - inline int32_t get_frame_count() const { return _frame_count; } - StackMapFrame* next(StackMapFrame* pre_frame, bool first, - u2 max_locals, u2 max_stack, TRAPS); - - void check_end(TRAPS) { - if (!_stream->at_end()) { - StackMapStream::stackmap_format_error("wrong attribute size", CHECK); - } - } + StackMapReader(ClassVerifier* v, StackMapStream* stream, + char* code_data, int32_t code_len, + StackMapFrame* init_frame, + u2 max_locals, u2 max_stack, TRAPS); + + inline int32_t get_frame_count() const { return _frame_count; } + inline StackMapFrame* prev_frame() const { return _prev_frame; } + inline char* code_data() const { return _code_data; } + inline int32_t code_length() const { return _code_length; } + inline bool at_end() const { return _stream->at_end(); } + + StackMapFrame* next(TRAPS); + void check_end(TRAPS); }; #endif // SHARE_CLASSFILE_STACKMAPTABLE_HPP diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index d6aedcbb157fb..22ccb4e4b04ba 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,10 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.inline.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/cdsConfig.hpp" -#include "cds/filemap.hpp" #include "cds/heapShared.hpp" #include "classfile/altHashing.hpp" #include "classfile/compactHashtable.hpp" @@ -311,7 +309,7 @@ class StringTableLookupOop : public StringTableLookup { void StringTable::create_table() { size_t start_size_log_2 = log2i_ceil(StringTableSize); _current_size = ((size_t)1) << start_size_log_2; - log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", + log_trace(stringtable)("Start size: %zu (%zu)", _current_size, start_size_log_2); _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN, true); _oop_storage = OopStorageSet::create_weak("StringTable Weak", mtSymbol); @@ -582,7 +580,7 @@ void StringTable::grow(JavaThread* jt) { } gt.done(jt); _current_size = table_size(); - log_debug(stringtable)("Grown to size:" SIZE_FORMAT, _current_size); + log_debug(stringtable)("Grown to size:%zu", _current_size); } struct StringTableDoDelete : StackObj { @@ -631,7 +629,7 @@ void StringTable::clean_dead_entries(JavaThread* jt) { } void StringTable::gc_notification(size_t num_dead) { - log_trace(stringtable)("Uncleaned items:" SIZE_FORMAT, num_dead); + log_trace(stringtable)("Uncleaned items:%zu", num_dead); if (has_work()) { return; @@ -1012,20 +1010,14 @@ void StringTable::verify_secondary_array_index_bits() { // For each shared string: // [1] Store it into _shared_strings_array. Encode its position as a 32-bit index. // [2] Store the index and hashcode into _shared_table. -oop StringTable::init_shared_table(const DumpedInternedStrings* dumped_interned_strings) { - assert(HeapShared::can_write(), "must be"); +oop StringTable::init_shared_strings_array(const DumpedInternedStrings* dumped_interned_strings) { + assert(CDSConfig::is_dumping_heap(), "must be"); objArrayOop array = (objArrayOop)(_shared_strings_array.resolve()); verify_secondary_array_index_bits(); - _shared_table.reset(); - CompactHashtableWriter writer((int)_items_count, ArchiveBuilder::string_stats()); - int index = 0; auto copy_into_array = [&] (oop string, bool value_ignored) { - unsigned int hash = java_lang_String::hash_code(string); - writer.add(hash, index); - if (!_is_two_dimensional_shared_strings_array) { assert(index < array->length(), "no strings should have been added"); array->obj_at_put(index, string); @@ -1045,11 +1037,24 @@ oop StringTable::init_shared_table(const DumpedInternedStrings* dumped_interned_ }; dumped_interned_strings->iterate_all(copy_into_array); - writer.dump(&_shared_table, "string"); - return array; } +void StringTable::write_shared_table(const DumpedInternedStrings* dumped_interned_strings) { + _shared_table.reset(); + CompactHashtableWriter writer((int)_items_count, ArchiveBuilder::string_stats()); + + int index = 0; + auto copy_into_shared_table = [&] (oop string, bool value_ignored) { + unsigned int hash = java_lang_String::hash_code(string); + writer.add(hash, index); + index ++; + }; + dumped_interned_strings->iterate_all(copy_into_shared_table); + + writer.dump(&_shared_table, "string"); +} + void StringTable::set_shared_strings_array_index(int root_index) { _shared_strings_array_root_index = root_index; } diff --git a/src/hotspot/share/classfile/stringTable.hpp b/src/hotspot/share/classfile/stringTable.hpp index 38abb9c875c8d..0d58e09f2083a 100644 --- a/src/hotspot/share/classfile/stringTable.hpp +++ b/src/hotspot/share/classfile/stringTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,7 +148,8 @@ class StringTable : AllStatic { static oop lookup_shared(const jchar* name, int len) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); static size_t shared_entry_count() NOT_CDS_JAVA_HEAP_RETURN_(0); static void allocate_shared_strings_array(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; - static oop init_shared_table(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static oop init_shared_strings_array(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static void write_shared_table(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN; static void set_shared_strings_array_index(int root_index) NOT_CDS_JAVA_HEAP_RETURN; static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN; diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index 040ba4795e45a..84c0a5a39dee0 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" #include "cds/dynamicArchive.hpp" @@ -214,7 +213,7 @@ class SymbolTableConfig : public AllStatic { void SymbolTable::create_table () { size_t start_size_log_2 = log2i_ceil(SymbolTableSize); _current_size = ((size_t)1) << start_size_log_2; - log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", + log_trace(symboltable)("Start size: %zu (%zu)", _current_size, start_size_log_2); _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN, true); @@ -749,7 +748,7 @@ void SymbolTable::grow(JavaThread* jt) { } gt.done(jt); _current_size = table_size(); - log_debug(symboltable)("Grown to size:" SIZE_FORMAT, _current_size); + log_debug(symboltable)("Grown to size:%zu", _current_size); } struct SymbolTableDoDelete : StackObj { @@ -798,7 +797,7 @@ void SymbolTable::clean_dead_entries(JavaThread* jt) { Atomic::add(&_symbols_counted, stdc._processed); - log_debug(symboltable)("Cleaned " SIZE_FORMAT " of " SIZE_FORMAT, + log_debug(symboltable)("Cleaned %zu of %zu", stdd._deleted, stdc._processed); } @@ -931,29 +930,29 @@ void SymbolTable::print_histogram() { HistogramIterator hi; _local_table->do_scan(Thread::current(), hi); tty->print_cr("Symbol Table Histogram:"); - tty->print_cr(" Total number of symbols " SIZE_FORMAT_W(7), hi.total_count); - tty->print_cr(" Total size in memory " SIZE_FORMAT_W(7) "K", (hi.total_size * wordSize) / K); - tty->print_cr(" Total counted " SIZE_FORMAT_W(7), _symbols_counted); - tty->print_cr(" Total removed " SIZE_FORMAT_W(7), _symbols_removed); + tty->print_cr(" Total number of symbols %7zu", hi.total_count); + tty->print_cr(" Total size in memory %7zuK", (hi.total_size * wordSize) / K); + tty->print_cr(" Total counted %7zu", _symbols_counted); + tty->print_cr(" Total removed %7zu", _symbols_removed); if (_symbols_counted > 0) { tty->print_cr(" Percent removed %3.2f", ((double)_symbols_removed / (double)_symbols_counted) * 100); } - tty->print_cr(" Reference counts " SIZE_FORMAT_W(7), Symbol::_total_count); - tty->print_cr(" Symbol arena used " SIZE_FORMAT_W(7) "K", arena()->used() / K); - tty->print_cr(" Symbol arena size " SIZE_FORMAT_W(7) "K", arena()->size_in_bytes() / K); - tty->print_cr(" Total symbol length " SIZE_FORMAT_W(7), hi.total_length); - tty->print_cr(" Maximum symbol length " SIZE_FORMAT_W(7), hi.max_length); + tty->print_cr(" Reference counts %7zu", Symbol::_total_count); + tty->print_cr(" Symbol arena used %7zuK", arena()->used() / K); + tty->print_cr(" Symbol arena size %7zuK", arena()->size_in_bytes() / K); + tty->print_cr(" Total symbol length %7zu", hi.total_length); + tty->print_cr(" Maximum symbol length %7zu", hi.max_length); tty->print_cr(" Average symbol length %7.2f", ((double)hi.total_length / (double)hi.total_count)); tty->print_cr(" Symbol length histogram:"); tty->print_cr(" %6s %10s %10s", "Length", "#Symbols", "Size"); for (size_t i = 0; i < hi.results_length; i++) { if (hi.counts[i] > 0) { - tty->print_cr(" " SIZE_FORMAT_W(6) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) "K", + tty->print_cr(" %6zu %10zu %10zuK", i, hi.counts[i], (hi.sizes[i] * wordSize) / K); } } - tty->print_cr(" >=" SIZE_FORMAT_W(6) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) "K\n", + tty->print_cr(" >= %6zu %10zu %10zuK\n", hi.results_length, hi.out_of_range_count, (hi.out_of_range_size*wordSize) / K); } #endif // PRODUCT diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 0cd9886bd0160..68f9556099f0e 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "cds/aotClassLocation.hpp" #include "cds/cdsConfig.hpp" #include "cds/heapShared.hpp" #include "classfile/classFileParser.hpp" @@ -424,47 +424,40 @@ InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* clas assert(next_name != nullptr, "null superclass for resolving"); assert(!Signature::is_array(next_name), "invalid superclass name"); -#if INCLUDE_CDS - if (CDSConfig::is_dumping_static_archive()) { - // Special processing for handling UNREGISTERED shared classes. - InstanceKlass* k = SystemDictionaryShared::lookup_super_for_unregistered_class(class_name, - next_name, is_superclass); - if (k) { - return k; - } - } -#endif // INCLUDE_CDS - - // If class_name is already loaded, just return the superclass or superinterface. - // Make sure there's a placeholder for the class_name before resolving. - // This is used as a claim that this thread is currently loading superclass/classloader - // and for ClassCircularity checks. ClassLoaderData* loader_data = class_loader_data(class_loader); - Dictionary* dictionary = loader_data->dictionary(); + + if (is_superclass) { + InstanceKlass* klassk = loader_data->dictionary()->find_class(THREAD, class_name); + if (klassk != nullptr) { + // We can come here for two reasons: + // (a) RedefineClasses -- the class is already loaded + // (b) Rarely, the class might have been loaded by a parallel thread + // We can do a quick check against the already assigned superclass's name and loader. + InstanceKlass* superk = klassk->java_super(); + if (superk != nullptr && + superk->name() == next_name && + superk->class_loader() == class_loader()) { + return superk; + } + } + } // can't throw error holding a lock bool throw_circularity_error = false; { MutexLocker mu(THREAD, SystemDictionary_lock); - InstanceKlass* klassk = dictionary->find_class(THREAD, class_name); - InstanceKlass* quicksuperk; - // To support parallel loading: if class is done loading, just return the superclass - // if the next_name matches class->super()->name() and if the class loaders match. - if (klassk != nullptr && is_superclass && - ((quicksuperk = klassk->java_super()) != nullptr) && - ((quicksuperk->name() == next_name) && - (quicksuperk->class_loader() == class_loader()))) { - return quicksuperk; - } else { - // Must check ClassCircularity before checking if superclass is already loaded. - PlaceholderEntry* probe = PlaceholderTable::get_entry(class_name, loader_data); - if (probe && probe->check_seen_thread(THREAD, PlaceholderTable::DETECT_CIRCULARITY)) { - log_circularity_error(class_name, probe); - throw_circularity_error = true; - } + + // Must check ClassCircularity before resolving next_name (superclass or interface). + PlaceholderEntry* probe = PlaceholderTable::get_entry(class_name, loader_data); + if (probe != nullptr && probe->check_seen_thread(THREAD, PlaceholderTable::DETECT_CIRCULARITY)) { + log_circularity_error(class_name, probe); + throw_circularity_error = true; } + // Make sure there's a placeholder for the class_name before resolving. + // This is used as a claim that this thread is currently loading superclass/classloader + // and for ClassCircularity checks. if (!throw_circularity_error) { // Be careful not to exit resolve_with_circularity_detection without removing this placeholder. PlaceholderEntry* newprobe = PlaceholderTable::find_and_add(class_name, @@ -512,12 +505,11 @@ static void handle_parallel_super_load(Symbol* name, TRAPS) { // The result superk is not used; resolve_with_circularity_detection is called for circularity check only. - // This passes true to is_superclass even though it might not be the super class in order to perform the - // optimization anyway. + // This passes false to is_superclass to skip doing the unlikely optimization. Klass* superk = SystemDictionary::resolve_with_circularity_detection(name, superclassname, class_loader, - true, + false, CHECK); } @@ -971,14 +963,14 @@ bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name, int scp_index = ik->shared_classpath_index(); assert(!ik->is_shared_unregistered_class(), "this function should be called for built-in classes only"); assert(scp_index >= 0, "must be"); - SharedClassPathEntry* scp_entry = FileMapInfo::shared_path(scp_index); + const AOTClassLocation* cl = AOTClassLocationConfig::runtime()->class_location_at(scp_index); if (!Universe::is_module_initialized()) { - assert(scp_entry != nullptr, "must be"); + assert(cl != nullptr, "must be"); // At this point, no modules have been defined yet. KlassSubGraphInfo::check_allowed_klass() // has restricted the classes can be loaded at this step to be only: - // [1] scp_entry->is_modules_image(): classes in java.base, or, + // [1] cs->is_modules_image(): classes in java.base, or, // [2] HeapShared::is_a_test_class_in_unnamed_module(ik): classes in bootstrap/unnamed module - assert(scp_entry->is_modules_image() || HeapShared::is_a_test_class_in_unnamed_module(ik), + assert(cl->is_modules_image() || HeapShared::is_a_test_class_in_unnamed_module(ik), "only these classes can be loaded before the module system is initialized"); assert(class_loader.is_null(), "sanity"); return true; @@ -995,7 +987,7 @@ bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name, ModuleEntry* mod_entry = (pkg_entry == nullptr) ? nullptr : pkg_entry->module(); bool should_be_in_named_module = (mod_entry != nullptr && mod_entry->is_named()); - bool was_archived_from_named_module = scp_entry->in_named_module(); + bool was_archived_from_named_module = !cl->has_unnamed_module(); bool visible; if (was_archived_from_named_module) { @@ -1596,6 +1588,9 @@ void SystemDictionary::initialize(TRAPS) { PlaceholderTable::initialize(); #if INCLUDE_CDS SystemDictionaryShared::initialize(); + if (CDSConfig::is_dumping_archive()) { + AOTClassLocationConfig::dumptime_init(THREAD); + } #endif // Resolve basic classes vmClasses::resolve_all(CHECK); diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 5883b76b64b3b..7432166ba4e34 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 180ba73e68144..b8e24bb2caace 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/archiveUtils.hpp" @@ -36,6 +35,7 @@ #include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "cds/runTimeClassInfo.hpp" +#include "cds/unregisteredClasses.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -205,15 +205,6 @@ DumpTimeClassInfo* SystemDictionaryShared::get_info_locked(InstanceKlass* k) { return info; } -void SystemDictionaryShared::mark_required_hidden_class(InstanceKlass* k) { - assert(k->is_hidden(), "sanity"); - DumpTimeClassInfo* info = _dumptime_table->get(k); - ResourceMark rm; - if (info != nullptr) { - info->set_is_required_hidden_class(); - } -} - bool SystemDictionaryShared::check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info) { if (MetaspaceShared::is_in_shared_metaspace(k)) { // We have reached a super type that's already in the base archive. Treat it @@ -256,13 +247,17 @@ bool SystemDictionaryShared::is_jfr_event_class(InstanceKlass *k) { bool SystemDictionaryShared::is_registered_lambda_proxy_class(InstanceKlass* ik) { DumpTimeClassInfo* info = _dumptime_table->get(ik); - return (info != nullptr) ? info->_is_archived_lambda_proxy : false; + bool result = (info != nullptr) ? info->_is_registered_lambda_proxy : false; + if (result) { + assert(!CDSConfig::is_dumping_invokedynamic(), "only used in legacy lambda proxy support"); + } + return result; } void SystemDictionaryShared::reset_registered_lambda_proxy_class(InstanceKlass* ik) { DumpTimeClassInfo* info = _dumptime_table->get(ik); if (info != nullptr) { - info->_is_archived_lambda_proxy = false; + info->_is_registered_lambda_proxy = false; info->set_excluded(); } } @@ -327,6 +322,13 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { if (!k->is_linked()) { if (has_class_failed_verification(k)) { return warn_excluded(k, "Failed verification"); + } else if (CDSConfig::is_dumping_aot_linked_classes()) { + // Most loaded classes should have been speculatively linked by MetaspaceShared::link_class_for_cds(). + // However, we do not speculatively link old classes, as they are not recorded by + // SystemDictionaryShared::record_linking_constraint(). As a result, such an unlinked + // class may fail to verify in AOTLinkedClassBulkLoader::init_required_classes_for_loader(), + // causing the JVM to fail at bootstrap. + return warn_excluded(k, "Unlinked class not supported by AOTClassLinking"); } } else { if (!k->can_be_verified_at_dumptime()) { @@ -340,11 +342,6 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { } } - if (k->is_hidden() && !should_hidden_class_be_archived(k)) { - log_info(cds)("Skipping %s: Hidden class", k->name()->as_C_string()); - return true; - } - InstanceKlass* super = k->java_super(); if (super != nullptr && check_for_exclusion(super, nullptr)) { ResourceMark rm; @@ -363,6 +360,12 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { } } + if (k == UnregisteredClasses::UnregisteredClassLoader_klass()) { + ResourceMark rm; + log_info(cds)("Skipping %s: used only when dumping CDS archive", k->name()->as_C_string()); + return true; + } + return false; // false == k should NOT be excluded } @@ -481,45 +484,6 @@ bool SystemDictionaryShared::add_unregistered_class(Thread* current, InstanceKla return (klass == *v); } -// This function is called to lookup the super/interfaces of shared classes for -// unregistered loaders. E.g., SharedClass in the below example -// where "super:" (and optionally "interface:") have been specified. -// -// java/lang/Object id: 0 -// Interface id: 2 super: 0 source: cust.jar -// SharedClass id: 4 super: 0 interfaces: 2 source: cust.jar -InstanceKlass* SystemDictionaryShared::lookup_super_for_unregistered_class( - Symbol* class_name, Symbol* super_name, bool is_superclass) { - - assert(CDSConfig::is_dumping_static_archive(), "only when static dumping"); - - if (!ClassListParser::is_parsing_thread()) { - // Unregistered classes can be created only by ClassListParser::_parsing_thread. - - return nullptr; - } - - ClassListParser* parser = ClassListParser::instance(); - if (parser == nullptr) { - // We're still loading the well-known classes, before the ClassListParser is created. - return nullptr; - } - if (class_name->equals(parser->current_class_name())) { - // When this function is called, all the numbered super and interface types - // must have already been loaded. Hence this function is never recursively called. - if (is_superclass) { - return parser->lookup_super_for_current_class(super_name); - } else { - return parser->lookup_interface_for_current_class(super_name); - } - } else { - // The VM is not trying to resolve a super type of parser->current_class_name(). - // Instead, it's resolving an error class (because parser->current_class_name() has - // failed parsing or verification). Don't do anything here. - return nullptr; - } -} - void SystemDictionaryShared::set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs) { assert(CDSConfig::is_dumping_archive(), "sanity"); assert(!is_builtin(k), "must be unregistered class"); @@ -601,9 +565,7 @@ void SystemDictionaryShared::validate_before_archiving(InstanceKlass* k) { guarantee(!info->is_excluded(), "Should not attempt to archive excluded class %s", name); if (is_builtin(k)) { if (k->is_hidden()) { - if (CDSConfig::is_dumping_invokedynamic()) { - assert(should_hidden_class_be_archived(k), "unexpected hidden class %s", name); - } else { + if (!CDSConfig::is_dumping_invokedynamic()) { assert(is_registered_lambda_proxy_class(k), "unexpected hidden class %s", name); } } @@ -657,29 +619,6 @@ class UnregisteredClassesDuplicationChecker : StackObj { } }; -void SystemDictionaryShared::scan_constant_pool(InstanceKlass* k) { - if (CDSConfig::is_dumping_invokedynamic()) { - k->constants()->find_required_hidden_classes(); - } -} - -bool SystemDictionaryShared::should_hidden_class_be_archived(InstanceKlass* k) { - assert(k->is_hidden(), "sanity"); - if (is_registered_lambda_proxy_class(k)) { - return true; - } - - if (CDSConfig::is_dumping_invokedynamic()) { - DumpTimeClassInfo* info = _dumptime_table->get(k); - if (info != nullptr && info->is_required_hidden_class()) { - guarantee(HeapShared::is_archivable_hidden_klass(k), "required hidden class must be archivable"); - return true; - } - } - - return false; -} - // Returns true if the class should be excluded. This can be called by // AOTConstantPoolResolver before or after we enter the CDS safepoint. // When called before the safepoint, we need to link the class so that @@ -729,24 +668,7 @@ bool SystemDictionaryShared::should_be_excluded(Klass* k) { } } -void SystemDictionaryShared::find_all_archivable_classes() { - HeapShared::start_finding_required_hidden_classes(); - find_all_archivable_classes_impl(); - HeapShared::end_finding_required_hidden_classes(); -} - -// Iterate over all the classes in _dumptime_table, marking the ones that must be -// excluded from the archive. Those that are not excluded will be archivable. -// -// (a) Non-hidden classes are easy. They are only check by the rules in -// SystemDictionaryShared::check_for_exclusion(). -// (b) For hidden classes, we only archive those that are required (i.e., they are -// referenced by Java objects (such as CallSites) that are reachable from -// ConstantPools). This needs help from HeapShared. -void SystemDictionaryShared::find_all_archivable_classes_impl() { - assert(!class_loading_may_happen(), "class loading must be disabled"); - assert_lock_strong(DumpTimeTable_lock); - +void SystemDictionaryShared::finish_exclusion_checks() { if (CDSConfig::is_dumping_dynamic_archive()) { // Do this first -- if a base class is excluded due to duplication, // all of its subclasses will also be excluded. @@ -756,58 +678,11 @@ void SystemDictionaryShared::find_all_archivable_classes_impl() { dup_checker.mark_duplicated_classes(); } - ResourceMark rm; - - // First, scan all non-hidden classes - auto check_non_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { - if (!k->is_hidden()) { - SystemDictionaryShared::check_for_exclusion(k, &info); - if (!info.is_excluded() && !info.has_scanned_constant_pool()) { - scan_constant_pool(k); - info.set_has_scanned_constant_pool(); - } - } - }; - _dumptime_table->iterate_all_live_classes(check_non_hidden); - - // Then, scan all the hidden classes that have been marked as required to - // discover more hidden classes. Stop when we cannot make progress anymore. - bool made_progress; - do { - made_progress = false; - auto check_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { - if (k->is_hidden() && should_hidden_class_be_archived(k)) { - SystemDictionaryShared::check_for_exclusion(k, &info); - if (info.is_excluded()) { - guarantee(!info.is_required_hidden_class(), "A required hidden class cannot be marked as excluded"); - } else if (!info.has_scanned_constant_pool()) { - scan_constant_pool(k); - info.set_has_scanned_constant_pool(); - // The CP entries in k *MAY* refer to other hidden classes, so scan - // every hidden class again. - made_progress = true; - } - } - }; - _dumptime_table->iterate_all_live_classes(check_hidden); - } while (made_progress); + _dumptime_table->iterate_all_live_classes([&] (InstanceKlass* k, DumpTimeClassInfo& info) { + SystemDictionaryShared::check_for_exclusion(k, &info); + }); - // Now, all hidden classes that have not yet been scanned must be marked as excluded - auto exclude_remaining_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { - if (k->is_hidden()) { - SystemDictionaryShared::check_for_exclusion(k, &info); - if (CDSConfig::is_dumping_invokedynamic()) { - if (should_hidden_class_be_archived(k)) { - guarantee(!info.is_excluded(), "Must be"); - } else { - guarantee(info.is_excluded(), "Must be"); - } - } - } - }; - _dumptime_table->iterate_all_live_classes(exclude_remaining_hidden); _dumptime_table->update_counts(); - cleanup_lambda_proxy_class_dictionary(); } @@ -936,9 +811,9 @@ void SystemDictionaryShared::add_lambda_proxy_class(InstanceKlass* caller_ik, if (info != nullptr && !lambda_ik->is_non_strong_hidden() && is_builtin(lambda_ik) && is_builtin(caller_ik) // Don't include the lambda proxy if its nest host is not in the "linked" state. && nest_host->is_linked()) { - // Set _is_archived_lambda_proxy in DumpTimeClassInfo so that the lambda_ik - // won't be excluded during dumping of shared archive. See ExcludeDumpTimeSharedClasses. - info->_is_archived_lambda_proxy = true; + // Set _is_registered_lambda_proxy in DumpTimeClassInfo so that the lambda_ik + // won't be excluded during dumping of shared archive. + info->_is_registered_lambda_proxy = true; info->set_nest_host(nest_host); LambdaProxyClassKey key(caller_ik, @@ -1347,13 +1222,6 @@ class CopyLambdaProxyClassInfoToArchive : StackObj { bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) { // In static dump, info._proxy_klasses->at(0) is already relocated to point to the archived class // (not the original class). - // - // The following check has been moved to SystemDictionaryShared::find_all_archivable_classes(), which - // happens before the classes are copied. - // - // if (SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) { - // return true; - //} ResourceMark rm; log_info(cds,dynamic)("Archiving hidden %s", info._proxy_klasses->at(0)->external_name()); size_t byte_size = sizeof(RunTimeLambdaProxyClassInfo); diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index 5e0c54a6ffcc7..41e3d9c971667 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,7 +137,6 @@ class SharedClassLoadingMark { }; class SystemDictionaryShared: public SystemDictionary { - friend class ExcludeDumpTimeSharedClasses; friend class CleanupDumpTimeLambdaProxyClassTable; struct ArchiveInfo { @@ -188,24 +187,20 @@ class SystemDictionaryShared: public SystemDictionary { static DumpTimeClassInfo* get_info(InstanceKlass* k); static DumpTimeClassInfo* get_info_locked(InstanceKlass* k); - static void find_all_archivable_classes_impl(); static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin); static void write_lambda_proxy_class_dictionary(LambdaProxyClassDictionary* dictionary); static void cleanup_lambda_proxy_class_dictionary(); static void reset_registered_lambda_proxy_class(InstanceKlass* ik); static bool is_jfr_event_class(InstanceKlass *k); - static bool is_registered_lambda_proxy_class(InstanceKlass* ik); static bool check_for_exclusion_impl(InstanceKlass* k); static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; static bool has_been_redefined(InstanceKlass* k); static InstanceKlass* retrieve_lambda_proxy_class(const RunTimeLambdaProxyClassInfo* info) NOT_CDS_RETURN_(nullptr); - static void scan_constant_pool(InstanceKlass* k); DEBUG_ONLY(static bool _class_loading_may_happen;) public: - static bool should_hidden_class_be_archived(InstanceKlass* k); - static void mark_required_hidden_class(InstanceKlass* k); + static bool is_registered_lambda_proxy_class(InstanceKlass* ik); static bool is_hidden_lambda_proxy(InstanceKlass* ik); static bool is_early_klass(InstanceKlass* k); // Was k loaded while JvmtiExport::is_early_phase()==true static bool has_archived_enum_objs(InstanceKlass* ik); @@ -291,7 +286,9 @@ class SystemDictionaryShared: public SystemDictionary { } static bool add_unregistered_class(Thread* current, InstanceKlass* k); - static void find_all_archivable_classes(); + static void finish_exclusion_checks(); + static DumpTimeSharedClassTable* dumptime_table() { return _dumptime_table; } + static bool should_be_excluded(Klass* k); static bool check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info); static void validate_before_archiving(InstanceKlass* k); diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index ddeee499814f8..d0541a0d20f93 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index 0ac2cc350b18d..4434b06c0b880 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.hpp" @@ -32,7 +31,6 @@ #include "classfile/stackMapTableFormat.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" -#include "classfile/systemDictionaryShared.hpp" #include "classfile/verifier.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" @@ -61,6 +59,9 @@ #include "services/threadService.hpp" #include "utilities/align.hpp" #include "utilities/bytes.hpp" +#if INCLUDE_CDS +#include "classfile/systemDictionaryShared.hpp" +#endif #define NOFAILOVER_MAJOR_VERSION 51 #define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION 51 @@ -235,11 +236,13 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) { exception_name == vmSymbols::java_lang_ClassFormatError())) { log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name()); log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name()); +#if INCLUDE_CDS // Exclude any classes that fail over during dynamic dumping if (CDSConfig::is_dumping_dynamic_archive()) { SystemDictionaryShared::warn_excluded(klass, "Failed over class verification while dynamic dumping"); SystemDictionaryShared::set_excluded(klass); } +#endif message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len); exception_message = message_buffer; exception_name = inference_verify( @@ -737,9 +740,8 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) { Array* stackmap_data = m->stackmap_data(); StackMapStream stream(stackmap_data); - StackMapReader reader(this, &stream, code_data, code_length, THREAD); - StackMapTable stackmap_table(&reader, ¤t_frame, max_locals, max_stack, - code_data, code_length, CHECK_VERIFY(this)); + StackMapReader reader(this, &stream, code_data, code_length, ¤t_frame, max_locals, max_stack, THREAD); + StackMapTable stackmap_table(&reader, CHECK_VERIFY(this)); LogTarget(Debug, verification) lt; if (lt.is_enabled()) { @@ -2038,7 +2040,8 @@ void ClassVerifier::verify_cp_type( verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); unsigned int tag = cp->tag_at(index).value(); - if ((types & (1 << tag)) == 0) { + // tags up to JVM_CONSTANT_ExternalMax are verifiable and valid for shift op + if (tag > JVM_CONSTANT_ExternalMax || (types & (1 << tag)) == 0) { verify_error(ErrorContext::bad_cp_index(bci, index), "Illegal type at constant pool entry %d in class %s", index, cp->pool_holder()->external_name()); diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 395034d4a21a6..351b9b0b53f24 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,7 +123,6 @@ do_klass(ABIDescriptor_klass, jdk_internal_foreign_abi_ABIDescriptor ) \ do_klass(VMStorage_klass, jdk_internal_foreign_abi_VMStorage ) \ do_klass(CallConv_klass, jdk_internal_foreign_abi_CallConv ) \ - do_klass(Context_klass, java_lang_invoke_MethodHandleNatives_CallSiteContext ) \ do_klass(ConstantCallSite_klass, java_lang_invoke_ConstantCallSite ) \ do_klass(MutableCallSite_klass, java_lang_invoke_MutableCallSite ) \ do_klass(VolatileCallSite_klass, java_lang_invoke_VolatileCallSite ) \ @@ -138,7 +137,6 @@ /* support for CDS */ \ do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream ) \ do_klass(URL_klass, java_net_URL ) \ - do_klass(URLClassLoader_klass, java_net_URLClassLoader ) \ do_klass(Enum_klass, java_lang_Enum ) \ do_klass(Jar_Manifest_klass, java_util_jar_Manifest ) \ do_klass(jdk_internal_loader_BuiltinClassLoader_klass,jdk_internal_loader_BuiltinClassLoader ) \ diff --git a/src/hotspot/share/classfile/vmClasses.cpp b/src/hotspot/share/classfile/vmClasses.cpp index 553864ef0b991..ac359d4cacbf3 100644 --- a/src/hotspot/share/classfile/vmClasses.cpp +++ b/src/hotspot/share/classfile/vmClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 407cdafaf2017..2943f9d4af379 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmIntrinsics.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compilerDirectives.hpp" @@ -36,31 +35,31 @@ #include "utilities/tribool.hpp" // These are flag-matching functions: -inline bool match_F_R(jshort flags) { +inline bool match_F_R(u2 flags) { const int req = 0; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_Y(jshort flags) { +inline bool match_F_Y(u2 flags) { const int req = JVM_ACC_SYNCHRONIZED; const int neg = JVM_ACC_STATIC | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_RN(jshort flags) { +inline bool match_F_RN(u2 flags) { const int req = JVM_ACC_NATIVE; const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; } -inline bool match_F_S(jshort flags) { +inline bool match_F_S(u2 flags) { const int req = JVM_ACC_STATIC; const int neg = JVM_ACC_SYNCHRONIZED | JVM_ACC_NATIVE; return (flags & (req | neg)) == req; } -inline bool match_F_SN(jshort flags) { +inline bool match_F_SN(u2 flags) { const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE; const int neg = JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; @@ -257,10 +256,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { switch (id) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isAssignableFrom: - case vmIntrinsics::_getModifiers: - case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_Class_cast: @@ -711,7 +706,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbolID holder, vmSymbolID name, vmSymbolID sig, - jshort flags) { + u2 flags) { assert((int)vmSymbolID::SID_LIMIT <= (1< + +// Virtual methods are not allowed in code blobs to simplify caching compiled code. +// Check all "leaf" subclasses of CodeBlob class. + +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in nmethod"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +#ifdef COMPILER2 +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +static_assert(!std::is_polymorphic::value, "no virtual methods are allowed in code blobs"); +#endif + +// Add proxy vtables. +// We need only few for now - they are used only from prints. +const nmethod::Vptr nmethod::_vpntr; +const BufferBlob::Vptr BufferBlob::_vpntr; +const RuntimeStub::Vptr RuntimeStub::_vpntr; +const SingletonBlob::Vptr SingletonBlob::_vpntr; +const DeoptimizationBlob::Vptr DeoptimizationBlob::_vpntr; +const UpcallStub::Vptr UpcallStub::_vpntr; + +const CodeBlob::Vptr* CodeBlob::vptr() const { + constexpr const CodeBlob::Vptr* array[(size_t)CodeBlobKind::Number_Of_Kinds] = { + nullptr/* None */, + &nmethod::_vpntr, + &BufferBlob::_vpntr, + &AdapterBlob::_vpntr, + &VtableBlob::_vpntr, + &MethodHandlesAdapterBlob::_vpntr, + &RuntimeStub::_vpntr, + &DeoptimizationBlob::_vpntr, + &SafepointBlob::_vpntr, +#ifdef COMPILER2 + &ExceptionBlob::_vpntr, + &UncommonTrapBlob::_vpntr, +#endif + &UpcallStub::_vpntr + }; + + return array[(size_t)_kind]; +} unsigned int CodeBlob::align_code_offset(int offset) { // align the size to CodeEntryAlignment @@ -387,7 +433,7 @@ RuntimeStub::RuntimeStub( OopMapSet* oop_maps, bool caller_must_gc_arguments ) -: RuntimeBlob(name, CodeBlobKind::Runtime_Stub, cb, size, sizeof(RuntimeStub), +: RuntimeBlob(name, CodeBlobKind::RuntimeStub, cb, size, sizeof(RuntimeStub), frame_complete, frame_size, oop_maps, caller_must_gc_arguments) { } @@ -483,18 +529,18 @@ DeoptimizationBlob* DeoptimizationBlob::create( return blob; } +#ifdef COMPILER2 //---------------------------------------------------------------------------------------------------- // Implementation of UncommonTrapBlob -#ifdef COMPILER2 UncommonTrapBlob::UncommonTrapBlob( CodeBuffer* cb, int size, OopMapSet* oop_maps, int frame_size ) -: SingletonBlob("UncommonTrapBlob", CodeBlobKind::Uncommon_Trap, cb, +: SingletonBlob("UncommonTrapBlob", CodeBlobKind::UncommonTrap, cb, size, sizeof(UncommonTrapBlob), frame_size, oop_maps) {} @@ -517,14 +563,9 @@ UncommonTrapBlob* UncommonTrapBlob::create( return blob; } - -#endif // COMPILER2 - - //---------------------------------------------------------------------------------------------------- // Implementation of ExceptionBlob -#ifdef COMPILER2 ExceptionBlob::ExceptionBlob( CodeBuffer* cb, int size, @@ -554,10 +595,8 @@ ExceptionBlob* ExceptionBlob::create( return blob; } - #endif // COMPILER2 - //---------------------------------------------------------------------------------------------------- // Implementation of SafepointBlob @@ -645,19 +684,47 @@ void UpcallStub::free(UpcallStub* blob) { //---------------------------------------------------------------------------------------------------- // Verification and printing +void CodeBlob::verify() { + if (is_nmethod()) { + as_nmethod()->verify(); + } +} + void CodeBlob::print_on(outputStream* st) const { - st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this)); - st->print_cr("Framesize: %d", _frame_size); + vptr()->print_on(this, st); } void CodeBlob::print() const { print_on(tty); } void CodeBlob::print_value_on(outputStream* st) const { + vptr()->print_value_on(this, st); +} + +void CodeBlob::print_on_impl(outputStream* st) const { + st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this)); + st->print_cr("Framesize: %d", _frame_size); +} + +void CodeBlob::print_value_on_impl(outputStream* st) const { st->print_cr("[CodeBlob]"); } +void CodeBlob::print_block_comment(outputStream* stream, address block_begin) const { +#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY) + if (is_nmethod()) { + as_nmethod()->print_nmethod_labels(stream, block_begin); + } +#endif + +#ifndef PRODUCT + ptrdiff_t offset = block_begin - code_begin(); + assert(offset >= 0, "Expecting non-negative offset!"); + _asm_remarks.print(uint(offset), stream); +#endif + } + void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const { - if (is_buffer_blob()) { + if (is_buffer_blob() || is_adapter_blob() || is_vtable_blob() || is_method_handles_adapter_blob()) { // the interpreter is generated into a buffer blob InterpreterCodelet* i = Interpreter::codelet_containing(addr); if (i != nullptr) { @@ -709,7 +776,7 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const // verbose is only ever true when called from findpc in debug.cpp nm->print_nmethod(true); } else { - nm->print(st); + nm->print_on(st); } return; } @@ -717,61 +784,45 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const print_on(st); } -void BufferBlob::verify() { - // unimplemented +void BufferBlob::print_on_impl(outputStream* st) const { + RuntimeBlob::print_on_impl(st); + print_value_on_impl(st); } -void BufferBlob::print_on(outputStream* st) const { - RuntimeBlob::print_on(st); - print_value_on(st); -} - -void BufferBlob::print_value_on(outputStream* st) const { +void BufferBlob::print_value_on_impl(outputStream* st) const { st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name()); } -void RuntimeStub::verify() { - // unimplemented -} - -void RuntimeStub::print_on(outputStream* st) const { +void RuntimeStub::print_on_impl(outputStream* st) const { ttyLocker ttyl; - RuntimeBlob::print_on(st); + RuntimeBlob::print_on_impl(st); st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this)); st->print_cr("%s", name()); Disassembler::decode((RuntimeBlob*)this, st); } -void RuntimeStub::print_value_on(outputStream* st) const { +void RuntimeStub::print_value_on_impl(outputStream* st) const { st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name()); } -void SingletonBlob::verify() { - // unimplemented -} - -void SingletonBlob::print_on(outputStream* st) const { +void SingletonBlob::print_on_impl(outputStream* st) const { ttyLocker ttyl; - RuntimeBlob::print_on(st); + RuntimeBlob::print_on_impl(st); st->print_cr("%s", name()); Disassembler::decode((RuntimeBlob*)this, st); } -void SingletonBlob::print_value_on(outputStream* st) const { +void SingletonBlob::print_value_on_impl(outputStream* st) const { st->print_cr("%s", name()); } -void DeoptimizationBlob::print_value_on(outputStream* st) const { +void DeoptimizationBlob::print_value_on_impl(outputStream* st) const { st->print_cr("Deoptimization (frame not available)"); } -void UpcallStub::verify() { - // unimplemented -} - -void UpcallStub::print_on(outputStream* st) const { - RuntimeBlob::print_on(st); - print_value_on(st); +void UpcallStub::print_on_impl(outputStream* st) const { + RuntimeBlob::print_on_impl(st); + print_value_on_impl(st); st->print_cr("Frame data offset: %d", (int) _frame_data_offset); oop recv = JNIHandles::resolve(_receiver); st->print("Receiver MH="); @@ -779,6 +830,6 @@ void UpcallStub::print_on(outputStream* st) const { Disassembler::decode((RuntimeBlob*)this, st); } -void UpcallStub::print_value_on(outputStream* st) const { +void UpcallStub::print_value_on_impl(outputStream* st) const { st->print_cr("UpcallStub (" INTPTR_FORMAT ") used for %s", p2i(this), name()); } diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 8ecd9e21537df..d0ac2bf1b5fa6 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,8 +61,8 @@ enum class CodeBlobType { // RuntimeStub : Call to VM runtime methods // SingletonBlob : Super-class for all blobs that exist in only one instance // DeoptimizationBlob : Used for deoptimization -// ExceptionBlob : Used for stack unrolling // SafepointBlob : Used to handle illegal instruction exceptions +// ExceptionBlob : Used for stack unrolling // UncommonTrapBlob : Used to handle uncommon traps // UpcallStub : Used for upcalls from native code // @@ -80,12 +80,14 @@ enum class CodeBlobKind : u1 { Buffer, Adapter, Vtable, - MH_Adapter, - Runtime_Stub, + MHAdapter, + RuntimeStub, Deoptimization, - Exception, Safepoint, - Uncommon_Trap, +#ifdef COMPILER2 + Exception, + UncommonTrap, +#endif Upcall, Number_Of_Kinds }; @@ -97,7 +99,6 @@ class JavaFrameAnchor; // for UpcallStub::jfa_for_frame class CodeBlob { friend class VMStructs; friend class JVMCIVMStructs; - friend class CodeCacheDumper; protected: // order fields from large to small to minimize padding between fields @@ -129,6 +130,17 @@ class CodeBlob { DbgStrings _dbg_strings; #endif + void print_on_impl(outputStream* st) const; + void print_value_on_impl(outputStream* st) const; + + class Vptr { + public: + virtual void print_on(const CodeBlob* instance, outputStream* st) const = 0; + virtual void print_value_on(const CodeBlob* instance, outputStream* st) const = 0; + }; + + const Vptr* vptr() const; + CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments); @@ -139,7 +151,7 @@ class CodeBlob { public: - virtual ~CodeBlob() { + ~CodeBlob() { assert(_oop_maps == nullptr, "Not flushed"); } @@ -153,20 +165,25 @@ class CodeBlob { // Typing bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; } bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; } - bool is_runtime_stub() const { return _kind == CodeBlobKind::Runtime_Stub; } + bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; } bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; } - bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::Uncommon_Trap; } +#ifdef COMPILER2 + bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; } bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; } +#else + bool is_uncommon_trap_stub() const { return false; } + bool is_exception_stub() const { return false; } +#endif bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; } bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; } bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; } - bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MH_Adapter; } + bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; } bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; } // Casting - nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : nullptr; } - nmethod* as_nmethod() { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; } - CodeBlob* as_codeblob_or_null() const { return (CodeBlob*) this; } + nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; } + nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; } + CodeBlob* as_codeblob() const { return (CodeBlob*) this; } UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; } RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; } @@ -234,21 +251,16 @@ class CodeBlob { void set_name(const char* name) { _name = name; } // Debugging - virtual void verify() = 0; - virtual void print() const; - virtual void print_on(outputStream* st) const; - virtual void print_value_on(outputStream* st) const; + void verify(); + void print() const; + void print_on(outputStream* st) const; + void print_value_on(outputStream* st) const; + void dump_for_addr(address addr, outputStream* st, bool verbose) const; void print_code_on(outputStream* st); // Print to stream, any comments associated with offset. - virtual void print_block_comment(outputStream* stream, address block_begin) const { -#ifndef PRODUCT - ptrdiff_t offset = block_begin - code_begin(); - assert(offset >= 0, "Expecting non-negative offset!"); - _asm_remarks.print(uint(offset), stream); -#endif - } + void print_block_comment(outputStream* stream, address block_begin) const; #ifndef PRODUCT AsmRemarks &asm_remarks() { return _asm_remarks; } @@ -291,6 +303,9 @@ class RuntimeBlob : public CodeBlob { // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService. static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = ""); + + class Vptr : public CodeBlob::Vptr { + }; }; class WhiteBox; @@ -319,11 +334,19 @@ class BufferBlob: public RuntimeBlob { static void free(BufferBlob* buf); - // Verification support - void verify() override; + void print_on_impl(outputStream* st) const; + void print_value_on_impl(outputStream* st) const; + + class Vptr : public RuntimeBlob::Vptr { + void print_on(const CodeBlob* instance, outputStream* st) const override { + ((const BufferBlob*)instance)->print_on_impl(st); + } + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + ((const BufferBlob*)instance)->print_value_on_impl(st); + } + }; - void print_on(outputStream* st) const override; - void print_value_on(outputStream* st) const override; + static const Vptr _vpntr; }; @@ -356,7 +379,7 @@ class VtableBlob: public BufferBlob { class MethodHandlesAdapterBlob: public BufferBlob { private: - MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MH_Adapter, size) {} + MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {} public: // Creation @@ -397,13 +420,21 @@ class RuntimeStub: public RuntimeBlob { static void free(RuntimeStub* stub) { RuntimeBlob::free(stub); } - address entry_point() const { return code_begin(); } + address entry_point() const { return code_begin(); } - // Verification support - void verify() override; + void print_on_impl(outputStream* st) const; + void print_value_on_impl(outputStream* st) const; - void print_on(outputStream* st) const override; - void print_value_on(outputStream* st) const override; + class Vptr : public RuntimeBlob::Vptr { + void print_on(const CodeBlob* instance, outputStream* st) const override { + instance->as_runtime_stub()->print_on_impl(st); + } + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + instance->as_runtime_stub()->print_value_on_impl(st); + } + }; + + static const Vptr _vpntr; }; @@ -431,11 +462,19 @@ class SingletonBlob: public RuntimeBlob { address entry_point() { return code_begin(); } - // Verification support - void verify() override; // does nothing + void print_on_impl(outputStream* st) const; + void print_value_on_impl(outputStream* st) const; + + class Vptr : public RuntimeBlob::Vptr { + void print_on(const CodeBlob* instance, outputStream* st) const override { + ((const SingletonBlob*)instance)->print_on_impl(st); + } + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + ((const SingletonBlob*)instance)->print_value_on_impl(st); + } + }; - void print_on(outputStream* st) const override; - void print_value_on(outputStream* st) const override; + static const Vptr _vpntr; }; @@ -480,9 +519,6 @@ class DeoptimizationBlob: public SingletonBlob { int frame_size ); - // Printing - void print_value_on(outputStream* st) const override; - address unpack() const { return code_begin() + _unpack_offset; } address unpack_with_exception() const { return code_begin() + _unpack_with_exception; } address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; } @@ -512,6 +548,16 @@ class DeoptimizationBlob: public SingletonBlob { } address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; } #endif // INCLUDE_JVMCI + + void print_value_on_impl(outputStream* st) const; + + class Vptr : public SingletonBlob::Vptr { + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + ((const DeoptimizationBlob*)instance)->print_value_on_impl(st); + } + }; + + static const Vptr _vpntr; }; @@ -624,13 +670,22 @@ class UpcallStub: public RuntimeBlob { JavaFrameAnchor* jfa_for_frame(const frame& frame) const; - // GC/Verification support + // GC support void oops_do(OopClosure* f, const frame& frame); - void verify() override; - // Misc. - void print_on(outputStream* st) const override; - void print_value_on(outputStream* st) const override; + void print_on_impl(outputStream* st) const; + void print_value_on_impl(outputStream* st) const; + + class Vptr : public RuntimeBlob::Vptr { + void print_on(const CodeBlob* instance, outputStream* st) const override { + instance->as_upcall_stub()->print_on_impl(st); + } + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + instance->as_upcall_stub()->print_value_on_impl(st); + } + }; + + static const Vptr _vpntr; }; #endif // SHARE_CODE_CODEBLOB_HPP diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index a0a02c25158a7..3b237e9643e6a 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" #include "code/codeHeapState.hpp" @@ -44,6 +43,7 @@ #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/iterator.hpp" +#include "memory/memoryReserver.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/method.inline.hpp" @@ -177,10 +177,10 @@ GrowableArray* CodeCache::_allocable_heaps = new(mtCode) GrowableArra static void check_min_size(const char* codeheap, size_t size, size_t required_size) { if (size < required_size) { - log_debug(codecache)("Code heap (%s) size " SIZE_FORMAT "K below required minimal size " SIZE_FORMAT "K", + log_debug(codecache)("Code heap (%s) size %zuK below required minimal size %zuK", codeheap, size/K, required_size/K); err_msg title("Not enough space in %s to run VM", codeheap); - err_msg message(SIZE_FORMAT "K < " SIZE_FORMAT "K", size/K, required_size/K); + err_msg message("%zuK < %zuK", size/K, required_size/K); vm_exit_during_initialization(title, message); } } @@ -205,7 +205,7 @@ void CodeCache::initialize_heaps() { const bool cache_size_set = FLAG_IS_CMDLINE(ReservedCodeCacheSize); const size_t ps = page_size(false, 8); const size_t min_size = MAX2(os::vm_allocation_granularity(), ps); - const size_t min_cache_size = CompilerConfig::min_code_cache_size(); // Make sure we have enough space for VM internal code + const size_t min_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3); // Make sure we have enough space for VM internal code size_t cache_size = align_up(ReservedCodeCacheSize, min_size); // Prerequisites @@ -255,15 +255,15 @@ void CodeCache::initialize_heaps() { size_t total = non_nmethod.size + profiled.size + non_profiled.size; if (total != cache_size && !cache_size_set) { - log_info(codecache)("ReservedCodeCache size " SIZE_FORMAT "K changed to total segments size NonNMethod " - SIZE_FORMAT "K NonProfiled " SIZE_FORMAT "K Profiled " SIZE_FORMAT "K = " SIZE_FORMAT "K", + log_info(codecache)("ReservedCodeCache size %zuK changed to total segments size NonNMethod " + "%zuK NonProfiled %zuK Profiled %zuK = %zuK", cache_size/K, non_nmethod.size/K, non_profiled.size/K, profiled.size/K, total/K); // Adjust ReservedCodeCacheSize as necessary because it was not set explicitly cache_size = total; } - log_debug(codecache)("Initializing code heaps ReservedCodeCache " SIZE_FORMAT "K NonNMethod " SIZE_FORMAT "K" - " NonProfiled " SIZE_FORMAT "K Profiled " SIZE_FORMAT "K", + log_debug(codecache)("Initializing code heaps ReservedCodeCache %zuK NonNMethod %zuK" + " NonProfiled %zuK Profiled %zuK", cache_size/K, non_nmethod.size/K, non_profiled.size/K, profiled.size/K); // Validation @@ -281,16 +281,16 @@ void CodeCache::initialize_heaps() { // ReservedCodeCacheSize was set explicitly, so report an error and abort if it doesn't match the segment sizes if (total != cache_size && cache_size_set) { - err_msg message("NonNMethodCodeHeapSize (" SIZE_FORMAT "K)", non_nmethod.size/K); + err_msg message("NonNMethodCodeHeapSize (%zuK)", non_nmethod.size/K); if (profiled.enabled) { - message.append(" + ProfiledCodeHeapSize (" SIZE_FORMAT "K)", profiled.size/K); + message.append(" + ProfiledCodeHeapSize (%zuK)", profiled.size/K); } if (non_profiled.enabled) { - message.append(" + NonProfiledCodeHeapSize (" SIZE_FORMAT "K)", non_profiled.size/K); + message.append(" + NonProfiledCodeHeapSize (%zuK)", non_profiled.size/K); } - message.append(" = " SIZE_FORMAT "K", total/K); + message.append(" = %zuK", total/K); message.append((total > cache_size) ? " is greater than " : " is less than "); - message.append("ReservedCodeCacheSize (" SIZE_FORMAT "K).", cache_size/K); + message.append("ReservedCodeCacheSize (%zuK).", cache_size/K); vm_exit_during_initialization("Invalid code heap sizes", message); } @@ -318,7 +318,7 @@ void CodeCache::initialize_heaps() { FLAG_SET_ERGO(NonProfiledCodeHeapSize, non_profiled.size); FLAG_SET_ERGO(ReservedCodeCacheSize, cache_size); - ReservedCodeSpace rs = reserve_heap_memory(cache_size, ps); + ReservedSpace rs = reserve_heap_memory(cache_size, ps); // Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory. LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size()); @@ -348,13 +348,14 @@ size_t CodeCache::page_size(bool aligned, size_t min_pages) { os::page_size_for_region_unaligned(ReservedCodeCacheSize, min_pages); } -ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size, size_t rs_ps) { +ReservedSpace CodeCache::reserve_heap_memory(size_t size, size_t rs_ps) { // Align and reserve space for code cache const size_t rs_align = MAX2(rs_ps, os::vm_allocation_granularity()); const size_t rs_size = align_up(size, rs_align); - ReservedCodeSpace rs(rs_size, rs_align, rs_ps); + + ReservedSpace rs = CodeMemoryReserver::reserve(rs_size, rs_align, rs_ps); if (!rs.is_reserved()) { - vm_exit_during_initialization(err_msg("Could not reserve enough space for code cache (" SIZE_FORMAT "K)", + vm_exit_during_initialization(err_msg("Could not reserve enough space for code cache (%zuK)", rs_size/K)); } @@ -435,7 +436,7 @@ void CodeCache::add_heap(ReservedSpace rs, const char* name, CodeBlobType code_b size_t size_initial = MIN2((size_t)InitialCodeCacheSize, rs.size()); size_initial = align_up(size_initial, rs.page_size()); if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) { - vm_exit_during_initialization(err_msg("Could not reserve enough space in %s (" SIZE_FORMAT "K)", + vm_exit_during_initialization(err_msg("Could not reserve enough space in %s (%zuK)", heap->name(), size_initial/K)); } @@ -563,7 +564,7 @@ CodeBlob* CodeCache::allocate(uint size, CodeBlobType code_blob_type, bool handl } else { tty->print("CodeCache"); } - tty->print_cr(" extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (" SSIZE_FORMAT " bytes)", + tty->print_cr(" extended to [" INTPTR_FORMAT ", " INTPTR_FORMAT "] (%zd bytes)", (intptr_t)heap->low_boundary(), (intptr_t)heap->high(), (address)heap->high() - (address)heap->low_boundary()); } @@ -1130,7 +1131,7 @@ void CodeCache::initialize() { // If InitialCodeCacheSize is equal to ReservedCodeCacheSize, then it's more likely // users want to use the largest available page. const size_t min_pages = (InitialCodeCacheSize == ReservedCodeCacheSize) ? 1 : 8; - ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, min_pages)); + ReservedSpace rs = reserve_heap_memory(ReservedCodeCacheSize, page_size(false, min_pages)); // Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory. LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size()); add_heap(rs, "CodeCache", CodeBlobType::All); @@ -1489,10 +1490,10 @@ void CodeCache::print_memory_overhead() { } // Print bytes that are allocated in the freelist ttyLocker ttl; - tty->print_cr("Number of elements in freelist: " SSIZE_FORMAT, freelists_length()); - tty->print_cr("Allocated in freelist: " SSIZE_FORMAT "kB", bytes_allocated_in_freelists()/K); - tty->print_cr("Unused bytes in CodeBlobs: " SSIZE_FORMAT "kB", (wasted_bytes/K)); - tty->print_cr("Segment map size: " SSIZE_FORMAT "kB", allocated_segments()/K); // 1 byte per segment + tty->print_cr("Number of elements in freelist: %zd", freelists_length()); + tty->print_cr("Allocated in freelist: %zdkB", bytes_allocated_in_freelists()/K); + tty->print_cr("Unused bytes in CodeBlobs: %zdkB", (wasted_bytes/K)); + tty->print_cr("Segment map size: %zdkB", allocated_segments()/K); // 1 byte per segment } //------------------------------------------------------------------------------------------------ @@ -1515,9 +1516,14 @@ void CodeCache::print_trace(const char* event, CodeBlob* cb, uint size) { void CodeCache::print_internals() { int nmethodCount = 0; int runtimeStubCount = 0; + int upcallStubCount = 0; int adapterCount = 0; + int mhAdapterCount = 0; + int vtableBlobCount = 0; int deoptimizationStubCount = 0; int uncommonTrapStubCount = 0; + int exceptionStubCount = 0; + int safepointStubCount = 0; int bufferBlobCount = 0; int total = 0; int nmethodNotEntrant = 0; @@ -1554,12 +1560,22 @@ void CodeCache::print_internals() { } } else if (cb->is_runtime_stub()) { runtimeStubCount++; + } else if (cb->is_upcall_stub()) { + upcallStubCount++; } else if (cb->is_deoptimization_stub()) { deoptimizationStubCount++; } else if (cb->is_uncommon_trap_stub()) { uncommonTrapStubCount++; + } else if (cb->is_exception_stub()) { + exceptionStubCount++; + } else if (cb->is_safepoint_stub()) { + safepointStubCount++; } else if (cb->is_adapter_blob()) { adapterCount++; + } else if (cb->is_method_handles_adapter_blob()) { + mhAdapterCount++; + } else if (cb->is_vtable_blob()) { + vtableBlobCount++; } else if (cb->is_buffer_blob()) { bufferBlobCount++; } @@ -1586,10 +1602,15 @@ void CodeCache::print_internals() { tty->print_cr("\tjava: %d",nmethodJava); tty->print_cr("\tnative: %d",nmethodNative); tty->print_cr("runtime_stubs: %d",runtimeStubCount); + tty->print_cr("upcall_stubs: %d",upcallStubCount); tty->print_cr("adapters: %d",adapterCount); + tty->print_cr("MH adapters: %d",mhAdapterCount); + tty->print_cr("VTables: %d",vtableBlobCount); tty->print_cr("buffer blobs: %d",bufferBlobCount); tty->print_cr("deoptimization_stubs: %d",deoptimizationStubCount); tty->print_cr("uncommon_traps: %d",uncommonTrapStubCount); + tty->print_cr("exception_stubs: %d",exceptionStubCount); + tty->print_cr("safepoint_stubs: %d",safepointStubCount); tty->print_cr("\nnmethod size distribution"); tty->print_cr("-------------------------------------------------"); @@ -1615,9 +1636,14 @@ void CodeCache::print() { CodeBlob_sizes live[CompLevel_full_optimization + 1]; CodeBlob_sizes runtimeStub; + CodeBlob_sizes upcallStub; CodeBlob_sizes uncommonTrapStub; CodeBlob_sizes deoptimizationStub; + CodeBlob_sizes exceptionStub; + CodeBlob_sizes safepointStub; CodeBlob_sizes adapter; + CodeBlob_sizes mhAdapter; + CodeBlob_sizes vtableBlob; CodeBlob_sizes bufferBlob; CodeBlob_sizes other; @@ -1629,12 +1655,22 @@ void CodeCache::print() { live[level].add(cb); } else if (cb->is_runtime_stub()) { runtimeStub.add(cb); + } else if (cb->is_upcall_stub()) { + upcallStub.add(cb); } else if (cb->is_deoptimization_stub()) { deoptimizationStub.add(cb); } else if (cb->is_uncommon_trap_stub()) { uncommonTrapStub.add(cb); + } else if (cb->is_exception_stub()) { + exceptionStub.add(cb); + } else if (cb->is_safepoint_stub()) { + safepointStub.add(cb); } else if (cb->is_adapter_blob()) { adapter.add(cb); + } else if (cb->is_method_handles_adapter_blob()) { + mhAdapter.add(cb); + } else if (cb->is_vtable_blob()) { + vtableBlob.add(cb); } else if (cb->is_buffer_blob()) { bufferBlob.add(cb); } else { @@ -1665,9 +1701,14 @@ void CodeCache::print() { const CodeBlob_sizes* sizes; } non_nmethod_blobs[] = { { "runtime", &runtimeStub }, + { "upcall", &upcallStub }, { "uncommon trap", &uncommonTrapStub }, { "deoptimization", &deoptimizationStub }, + { "exception", &exceptionStub }, + { "safepoint", &safepointStub }, { "adapter", &adapter }, + { "mh_adapter", &mhAdapter }, + { "vtable", &vtableBlob }, { "buffer blob", &bufferBlob }, { "other", &other }, }; @@ -1725,8 +1766,8 @@ void CodeCache::print_summary(outputStream* st, bool detailed) { total_used += used; total_max_used += max_used; total_free += free; - st->print_cr(" size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT - "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb", + st->print_cr(" size=%zuKb used=%zu" + "Kb max_used=%zuKb free=%zuKb", size, used, max_used, free); if (detailed) { @@ -1786,7 +1827,7 @@ void CodeCache::print_layout(outputStream* st) { void CodeCache::log_state(outputStream* st) { st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" - " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", + " adapters='" UINT32_FORMAT "' free_code_cache='%zu'", blob_count(), nmethod_count(), adapter_count(), unallocated_capacity()); } diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index b724268b65000..3e446ab8430fe 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -79,6 +79,7 @@ class OopClosure; class ShenandoahParallelCodeHeapIterator; class NativePostCallNop; class DeoptimizationScope; +class ReservedSpace; #ifdef LINUX #define DEFAULT_PERFMAP_FILENAME "/tmp/perf-%p.map" @@ -89,7 +90,6 @@ class CodeCache : AllStatic { friend class JVMCIVMStructs; template friend class CodeBlobIterator; friend class WhiteBox; - friend class CodeCacheLoader; friend class ShenandoahParallelCodeHeapIterator; private: // CodeHeaps of the cache @@ -122,7 +122,7 @@ class CodeCache : AllStatic { static CodeHeap* get_code_heap(CodeBlobType code_blob_type); // Returns the CodeHeap for the given CodeBlobType // Returns the name of the VM option to set the size of the corresponding CodeHeap static const char* get_code_heap_flag_name(CodeBlobType code_blob_type); - static ReservedCodeSpace reserve_heap_memory(size_t size, size_t rs_ps); // Reserves one continuous chunk of memory for the CodeHeaps + static ReservedSpace reserve_heap_memory(size_t size, size_t rs_ps); // Reserves one continuous chunk of memory for the CodeHeaps // Iteration static CodeBlob* first_blob(CodeHeap* heap); // Returns the first CodeBlob on the given CodeHeap diff --git a/src/hotspot/share/code/codeHeapState.cpp b/src/hotspot/share/code/codeHeapState.cpp index 0fa7c7386c7ee..065aab5c2500d 100644 --- a/src/hotspot/share/code/codeHeapState.cpp +++ b/src/hotspot/share/code/codeHeapState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "code/codeHeapState.hpp" #include "compiler/compileBroker.hpp" #include "oops/klass.inline.hpp" @@ -370,7 +369,7 @@ void CodeHeapState::prepare_StatArray(outputStream* out, size_t nElem, size_t gr if (StatArray == nullptr) { //---< just do nothing if allocation failed >--- out->print_cr("Statistics could not be collected for %s, probably out of memory.", heapName); - out->print_cr("Current granularity is " SIZE_FORMAT " bytes. Try a coarser granularity.", granularity); + out->print_cr("Current granularity is %zu bytes. Try a coarser granularity.", granularity); alloc_granules = 0; granule_size = 0; } else { @@ -621,11 +620,11 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular " collected data to be consistent. Only the method names and signatures\n" " are retrieved at print time. That may lead to rare cases where the\n" " name of a method is no longer available, e.g. because it was unloaded.\n"); - ast->print_cr(" CodeHeap committed size " SIZE_FORMAT "K (" SIZE_FORMAT "M), reserved size " SIZE_FORMAT "K (" SIZE_FORMAT "M), %d%% occupied.", + ast->print_cr(" CodeHeap committed size %zuK (%zuM), reserved size %zuK (%zuM), %d%% occupied.", size/(size_t)K, size/(size_t)M, res_size/(size_t)K, res_size/(size_t)M, (unsigned int)(100.0*size/res_size)); - ast->print_cr(" CodeHeap allocation segment size is " SIZE_FORMAT " bytes. This is the smallest possible granularity.", seg_size); - ast->print_cr(" CodeHeap (committed part) is mapped to " SIZE_FORMAT " granules of size " SIZE_FORMAT " bytes.", granules, granularity); - ast->print_cr(" Each granule takes " SIZE_FORMAT " bytes of C heap, that is " SIZE_FORMAT "K in total for statistics data.", sizeof(StatElement), (sizeof(StatElement)*granules)/(size_t)K); + ast->print_cr(" CodeHeap allocation segment size is %zu bytes. This is the smallest possible granularity.", seg_size); + ast->print_cr(" CodeHeap (committed part) is mapped to %zu granules of size %zu bytes.", granules, granularity); + ast->print_cr(" Each granule takes %zu bytes of C heap, that is %zuK in total for statistics data.", sizeof(StatElement), (sizeof(StatElement)*granules)/(size_t)K); ast->print_cr(" The number of granules is limited to %dk, requiring a granules size of at least %d bytes for a 1GB heap.", (unsigned int)(max_granules/K), (unsigned int)(G/max_granules)); BUFFEREDSTREAM_FLUSH("\n") @@ -697,10 +696,10 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular insane = true; ast->print_cr("Sanity check: HeapBlock @%p outside used range (%p)", (char*)h, low_bound + size); } if (ix_end >= granules) { - insane = true; ast->print_cr("Sanity check: end index (%d) out of bounds (" SIZE_FORMAT ")", ix_end, granules); + insane = true; ast->print_cr("Sanity check: end index (%d) out of bounds (%zu)", ix_end, granules); } if (size != heap->capacity()) { - insane = true; ast->print_cr("Sanity check: code heap capacity has changed (" SIZE_FORMAT "K to " SIZE_FORMAT "K)", size/(size_t)K, heap->capacity()/(size_t)K); + insane = true; ast->print_cr("Sanity check: code heap capacity has changed (%zuK to %zuK)", size/(size_t)K, heap->capacity()/(size_t)K); } if (ix_beg > ix_end) { insane = true; ast->print_cr("Sanity check: end index (%d) lower than begin index (%d)", ix_end, ix_beg); @@ -1042,19 +1041,19 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular // interspersed with print data from other threads. We take this risk intentionally. // Getting stalled waiting for tty_lock while holding the CodeCache_lock is not desirable. printBox(ast, '-', "Global CodeHeap statistics for segment ", heapName); - ast->print_cr("freeSpace = " SIZE_FORMAT_W(8) "k, nBlocks_free = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", freeSpace/(size_t)K, nBlocks_free, (100.0*freeSpace)/size, (100.0*freeSpace)/res_size); - ast->print_cr("usedSpace = " SIZE_FORMAT_W(8) "k, nBlocks_used = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", usedSpace/(size_t)K, nBlocks_used, (100.0*usedSpace)/size, (100.0*usedSpace)/res_size); - ast->print_cr(" Tier1 Space = " SIZE_FORMAT_W(8) "k, nBlocks_t1 = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", t1Space/(size_t)K, nBlocks_t1, (100.0*t1Space)/size, (100.0*t1Space)/res_size); - ast->print_cr(" Tier2 Space = " SIZE_FORMAT_W(8) "k, nBlocks_t2 = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", t2Space/(size_t)K, nBlocks_t2, (100.0*t2Space)/size, (100.0*t2Space)/res_size); - ast->print_cr(" Alive Space = " SIZE_FORMAT_W(8) "k, nBlocks_alive = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", aliveSpace/(size_t)K, nBlocks_alive, (100.0*aliveSpace)/size, (100.0*aliveSpace)/res_size); - ast->print_cr(" disconnected = " SIZE_FORMAT_W(8) "k, nBlocks_disconn = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", disconnSpace/(size_t)K, nBlocks_disconn, (100.0*disconnSpace)/size, (100.0*disconnSpace)/res_size); - ast->print_cr(" not entrant = " SIZE_FORMAT_W(8) "k, nBlocks_notentr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", notentrSpace/(size_t)K, nBlocks_notentr, (100.0*notentrSpace)/size, (100.0*notentrSpace)/res_size); - ast->print_cr(" stubSpace = " SIZE_FORMAT_W(8) "k, nBlocks_stub = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", stubSpace/(size_t)K, nBlocks_stub, (100.0*stubSpace)/size, (100.0*stubSpace)/res_size); + ast->print_cr("freeSpace = %8zuk, nBlocks_free = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", freeSpace/(size_t)K, nBlocks_free, (100.0*freeSpace)/size, (100.0*freeSpace)/res_size); + ast->print_cr("usedSpace = %8zuk, nBlocks_used = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", usedSpace/(size_t)K, nBlocks_used, (100.0*usedSpace)/size, (100.0*usedSpace)/res_size); + ast->print_cr(" Tier1 Space = %8zuk, nBlocks_t1 = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", t1Space/(size_t)K, nBlocks_t1, (100.0*t1Space)/size, (100.0*t1Space)/res_size); + ast->print_cr(" Tier2 Space = %8zuk, nBlocks_t2 = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", t2Space/(size_t)K, nBlocks_t2, (100.0*t2Space)/size, (100.0*t2Space)/res_size); + ast->print_cr(" Alive Space = %8zuk, nBlocks_alive = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", aliveSpace/(size_t)K, nBlocks_alive, (100.0*aliveSpace)/size, (100.0*aliveSpace)/res_size); + ast->print_cr(" disconnected = %8zuk, nBlocks_disconn = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", disconnSpace/(size_t)K, nBlocks_disconn, (100.0*disconnSpace)/size, (100.0*disconnSpace)/res_size); + ast->print_cr(" not entrant = %8zuk, nBlocks_notentr = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", notentrSpace/(size_t)K, nBlocks_notentr, (100.0*notentrSpace)/size, (100.0*notentrSpace)/res_size); + ast->print_cr(" stubSpace = %8zuk, nBlocks_stub = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", stubSpace/(size_t)K, nBlocks_stub, (100.0*stubSpace)/size, (100.0*stubSpace)/res_size); ast->print_cr("ZombieBlocks = %8d. These are HeapBlocks which could not be identified as CodeBlobs.", nBlocks_zomb); ast->cr(); - ast->print_cr("Segment start = " INTPTR_FORMAT ", used space = " SIZE_FORMAT_W(8)"k", p2i(low_bound), size/K); - ast->print_cr("Segment end (used) = " INTPTR_FORMAT ", remaining space = " SIZE_FORMAT_W(8)"k", p2i(low_bound) + size, (res_size - size)/K); - ast->print_cr("Segment end (reserved) = " INTPTR_FORMAT ", reserved space = " SIZE_FORMAT_W(8)"k", p2i(low_bound) + res_size, res_size/K); + ast->print_cr("Segment start = " INTPTR_FORMAT ", used space = %8zuk", p2i(low_bound), size/K); + ast->print_cr("Segment end (used) = " INTPTR_FORMAT ", remaining space = %8zuk", p2i(low_bound) + size, (res_size - size)/K); + ast->print_cr("Segment end (reserved) = " INTPTR_FORMAT ", reserved space = %8zuk", p2i(low_bound) + res_size, res_size/K); ast->cr(); ast->print_cr("latest allocated compilation id = %d", latest_compilation_id); ast->print_cr("highest observed compilation id = %d", highest_compilation_id); @@ -1134,7 +1133,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular ast->print_cr(" The aggregate step collects information about all free blocks in CodeHeap.\n" " Subsequent print functions create their output based on this snapshot.\n"); ast->print_cr(" Free space in %s is distributed over %d free blocks.", heapName, nBlocks_free); - ast->print_cr(" Each free block takes " SIZE_FORMAT " bytes of C heap for statistics data, that is " SIZE_FORMAT "K in total.", sizeof(FreeBlk), (sizeof(FreeBlk)*nBlocks_free)/K); + ast->print_cr(" Each free block takes %zu bytes of C heap for statistics data, that is %zuK in total.", sizeof(FreeBlk), (sizeof(FreeBlk)*nBlocks_free)/K); BUFFEREDSTREAM_FLUSH("\n") //---------------------------------------- @@ -1303,7 +1302,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) { if (is_nmethod) { //---< nMethod size in hex >--- ast->print(UINT32_FORMAT_X_0, TopSizeArray[i].nm_size); - ast->print("(" SIZE_FORMAT_W(4) "K)", TopSizeArray[i].nm_size/K); + ast->print("(%4zuK)", TopSizeArray[i].nm_size/K); ast->fill_to(51); ast->print(" %c", blobTypeChar[TopSizeArray[i].type]); //---< compiler information >--- @@ -1315,7 +1314,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) { } else { //---< block size in hex >--- ast->print(UINT32_FORMAT_X_0, (unsigned int)(TopSizeArray[i].len<print("(" SIZE_FORMAT_W(4) "K)", (TopSizeArray[i].len<print("(%4zuK)", (TopSizeArray[i].len<--- ast->fill_to(56); //---< name and signature >--- @@ -1362,17 +1361,17 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) { ast->print_cr("[Size Range)------avg.-size-+----count-+"); for (unsigned int i = 0; i < nSizeDistElements; i++) { if (SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) " .." SIZE_FORMAT_W(5) " ): " + ast->print("[%5zu ..%5zu ): " ,(size_t)(SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) "K.." SIZE_FORMAT_W(5) "K): " + ast->print("[%5zuK..%5zuK): " ,(SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) "M.." SIZE_FORMAT_W(5) "M): " + ast->print("[%5zuM..%5zuM): " ,(SizeDistributionArray[i].rangeStart<print_cr("[Size Range)------avg.-size-+----count-+"); for (unsigned int i = 0; i < nSizeDistElements; i++) { if (SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) " .." SIZE_FORMAT_W(5) " ): " + ast->print("[%5zu ..%5zu ): " ,(size_t)(SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) "K.." SIZE_FORMAT_W(5) "K): " + ast->print("[%5zuK..%5zuK): " ,(SizeDistributionArray[i].rangeStart<print("[" SIZE_FORMAT_W(5) "M.." SIZE_FORMAT_W(5) "M): " + ast->print("[%5zuM..%5zuM): " ,(SizeDistributionArray[i].rangeStart<cr(); ast->print_cr("--------------------------------------------------------------------"); - ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), " SIZE_FORMAT "k", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K); + ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), %zuk", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K); ast->print_cr("--------------------------------------------------------------------"); BUFFEREDSTREAM_FLUSH_AUTO("") } @@ -2170,7 +2169,7 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) { bool get_name = (cbType == nMethod_inuse) || (cbType == nMethod_notused); //---< nMethod size in hex >--- ast->print(UINT32_FORMAT_X_0, total_size); - ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K); + ast->print("(%4zuK)", total_size/K); //---< compiler information >--- ast->fill_to(51); ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level); diff --git a/src/hotspot/share/code/compiledIC.cpp b/src/hotspot/share/code/compiledIC.cpp index 684aee509ee53..2547b8711db16 100644 --- a/src/hotspot/share/code/compiledIC.cpp +++ b/src/hotspot/share/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeBehaviours.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" diff --git a/src/hotspot/share/code/compressedStream.cpp b/src/hotspot/share/code/compressedStream.cpp index 6a4174fb6ce0e..db86a1acd3c8f 100644 --- a/src/hotspot/share/code/compressedStream.cpp +++ b/src/hotspot/share/code/compressedStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/compressedStream.hpp" #include "utilities/ostream.hpp" #include "utilities/reverse_bits.hpp" diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp index ccee142c93808..9e895ecf152f3 100644 --- a/src/hotspot/share/code/debugInfo.cpp +++ b/src/hotspot/share/code/debugInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfo.hpp" #include "code/debugInfoRec.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/share/code/debugInfoRec.cpp b/src/hotspot/share/code/debugInfoRec.cpp index 71da21f1e99cd..02cd23407bf90 100644 --- a/src/hotspot/share/code/debugInfoRec.cpp +++ b/src/hotspot/share/code/debugInfoRec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfoRec.hpp" #include "code/scopeDesc.hpp" #include "compiler/oopMap.hpp" diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 260da40b87a42..7f925388eb039 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciEnv.hpp" #include "ci/ciKlass.hpp" diff --git a/src/hotspot/share/code/dependencyContext.cpp b/src/hotspot/share/code/dependencyContext.cpp index 0e6b99d172dcb..2b3253030c5c9 100644 --- a/src/hotspot/share/code/dependencyContext.cpp +++ b/src/hotspot/share/code/dependencyContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "code/dependencies.hpp" #include "code/dependencyContext.hpp" @@ -168,12 +167,6 @@ void DependencyContext::clean_unloading_dependents() { } } -nmethodBucket* DependencyContext::release_and_get_next_not_unloading(nmethodBucket* b) { - nmethodBucket* next = b->next_not_unloading(); - release(b); - return next; - } - // // Invalidate all dependencies in the context void DependencyContext::remove_all_dependents() { @@ -214,18 +207,6 @@ void DependencyContext::remove_all_dependents() { set_dependencies(nullptr); } -void DependencyContext::remove_and_mark_for_deoptimization_all_dependents(DeoptimizationScope* deopt_scope) { - nmethodBucket* b = dependencies_not_unloading(); - set_dependencies(nullptr); - while (b != nullptr) { - nmethod* nm = b->get_nmethod(); - // Also count already (concurrently) marked nmethods to make sure - // deoptimization is triggered before execution in this thread continues. - deopt_scope->mark(nm); - b = release_and_get_next_not_unloading(b); - } -} - #ifndef PRODUCT bool DependencyContext::is_empty() { return dependencies() == nullptr; @@ -237,7 +218,7 @@ void DependencyContext::print_dependent_nmethods(bool verbose) { nmethod* nm = b->get_nmethod(); tty->print("[%d] { ", idx++); if (!verbose) { - nm->print_on(tty, "nmethod"); + nm->print_on_with_msg(tty, "nmethod"); tty->print_cr(" } "); } else { nm->print(); diff --git a/src/hotspot/share/code/dependencyContext.hpp b/src/hotspot/share/code/dependencyContext.hpp index 13b845cb59dde..7e8f71635096e 100644 --- a/src/hotspot/share/code/dependencyContext.hpp +++ b/src/hotspot/share/code/dependencyContext.hpp @@ -63,7 +63,7 @@ class nmethodBucket: public CHeapObj { // // Utility class to manipulate nmethod dependency context. // Dependency context can be attached either to an InstanceKlass (_dep_context field) -// or CallSiteContext oop for call_site_target dependencies (see javaClasses.hpp). +// or CallSite oop for call_site_target dependencies (see javaClasses.hpp). // DependencyContext class operates on some location which holds a nmethodBucket* value // and uint64_t integer recording the safepoint counter at the last cleanup. // @@ -92,7 +92,6 @@ class DependencyContext : public StackObj { #ifdef ASSERT // Safepoints are forbidden during DC lifetime. GC can invalidate // _dependency_context_addr if it relocates the holder - // (e.g. CallSiteContext Java object). SafepointStateTracker _safepoint_tracker; DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr) @@ -114,9 +113,7 @@ class DependencyContext : public StackObj { void mark_dependent_nmethods(DeoptimizationScope* deopt_scope, DepChange& changes); void add_dependent_nmethod(nmethod* nm); void remove_all_dependents(); - void remove_and_mark_for_deoptimization_all_dependents(DeoptimizationScope* deopt_scope); void clean_unloading_dependents(); - static nmethodBucket* release_and_get_next_not_unloading(nmethodBucket* b); static void purge_dependency_contexts(); static void release(nmethodBucket* b); static void cleaning_start(); diff --git a/src/hotspot/share/code/exceptionHandlerTable.cpp b/src/hotspot/share/code/exceptionHandlerTable.cpp index aedeb0e9e049f..a295d1271aa65 100644 --- a/src/hotspot/share/code/exceptionHandlerTable.cpp +++ b/src/hotspot/share/code/exceptionHandlerTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/exceptionHandlerTable.hpp" #include "code/nmethod.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/code/location.cpp b/src/hotspot/share/code/location.cpp index ba8859b60a887..ec9d0797dc3a3 100644 --- a/src/hotspot/share/code/location.cpp +++ b/src/hotspot/share/code/location.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfo.hpp" #include "code/location.hpp" #include "runtime/handles.inline.hpp" diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 754a7786605ff..4f72c193d7ff0 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" @@ -1586,7 +1585,7 @@ void nmethod::log_identity(xmlStream* log) const { #define LOG_OFFSET(log, name) \ if (p2i(name##_end()) - p2i(name##_begin())) \ - log->print(" " XSTR(name) "_offset='" INTX_FORMAT "'" , \ + log->print(" " XSTR(name) "_offset='%zd'" , \ p2i(name##_begin()) - p2i(this)) @@ -1620,7 +1619,7 @@ void nmethod::log_new_nmethod() const { // Print out more verbose output usually for a newly created nmethod. -void nmethod::print_on(outputStream* st, const char* msg) const { +void nmethod::print_on_with_msg(outputStream* st, const char* msg) const { if (st != nullptr) { ttyLocker ttyl; if (WizardMode) { @@ -1962,7 +1961,7 @@ void nmethod::log_state_change() const { if (LogCompilation) { if (xtty != nullptr) { ttyLocker ttyl; // keep the following output all in one block - xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'", + xtty->begin_elem("make_not_entrant thread='%zu'", os::current_thread_id()); log_identity(xtty); xtty->stamp(); @@ -1972,7 +1971,7 @@ void nmethod::log_state_change() const { CompileTask::print_ul(this, "made not entrant"); if (PrintCompilation) { - print_on(tty, "made not entrant"); + print_on_with_msg(tty, "made not entrant"); } } @@ -2110,7 +2109,7 @@ void nmethod::purge(bool unregister_nmethod) { // completely deallocate this method Events::log_nmethod_flush(Thread::current(), "flushing %s nmethod " INTPTR_FORMAT, is_osr_method() ? "osr" : "", p2i(this)); log_debug(codecache)("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT - "/Free CodeCache:" SIZE_FORMAT "Kb", + "/Free CodeCache:%zuKb", is_osr_method() ? "osr" : "",_compile_id, p2i(this), CodeCache::blob_count(), CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024); @@ -2144,14 +2143,18 @@ oop nmethod::oop_at(int index) const { if (index == 0) { return nullptr; } - return NMethodAccess::oop_load(oop_addr_at(index)); + + BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); + return bs_nm->oop_load_no_keepalive(this, index); } oop nmethod::oop_at_phantom(int index) const { if (index == 0) { return nullptr; } - return NMethodAccess::oop_load(oop_addr_at(index)); + + BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); + return bs_nm->oop_load_phantom(this, index); } // @@ -3030,12 +3033,7 @@ void nmethod::verify_scopes() { // ----------------------------------------------------------------------------- // Printing operations -void nmethod::print() const { - ttyLocker ttyl; // keep the following output all in one block - print(tty); -} - -void nmethod::print(outputStream* st) const { +void nmethod::print_on_impl(outputStream* st) const { ResourceMark rm; st->print("Compiled method "); @@ -3050,7 +3048,7 @@ void nmethod::print(outputStream* st) const { st->print("(n/a) "); } - print_on(st, nullptr); + print_on_with_msg(st, nullptr); if (WizardMode) { st->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this)); @@ -3401,7 +3399,7 @@ void nmethod::decode2(outputStream* ost) const { #endif st->cr(); - this->print(st); + this->print_on(st); st->cr(); #if defined(SUPPORT_ASSEMBLY) @@ -3950,12 +3948,12 @@ address nmethod::call_instruction_address(address pc) const { return nullptr; } +void nmethod::print_value_on_impl(outputStream* st) const { + st->print_cr("nmethod"); #if defined(SUPPORT_DATA_STRUCTS) -void nmethod::print_value_on(outputStream* st) const { - st->print("nmethod"); - print_on(st, nullptr); -} + print_on_with_msg(st, nullptr); #endif +} #ifndef PRODUCT diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 095c0ba4a26a4..ac9b1a7098f8d 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -900,7 +900,7 @@ class nmethod : public CodeBlob { void post_compiled_method_load_event(JvmtiThreadState* state = nullptr); // verify operations - void verify() override; + void verify(); void verify_scopes(); void verify_interrupt_point(address interrupt_point, bool is_inline_cache); @@ -912,9 +912,9 @@ class nmethod : public CodeBlob { void decode(outputStream* st) const { decode2(st); } // just delegate here. // printing support - void print() const override; - void print(outputStream* st) const; + void print_on_impl(outputStream* st) const; void print_code(); + void print_value_on_impl(outputStream* st) const; #if defined(SUPPORT_DATA_STRUCTS) // print output in opt build for disassembler library @@ -922,7 +922,6 @@ class nmethod : public CodeBlob { void print_pcs_on(outputStream* st); void print_scopes() { print_scopes_on(tty); } void print_scopes_on(outputStream* st) PRODUCT_RETURN; - void print_value_on(outputStream* st) const override; void print_handler_table(); void print_nul_chk_table(); void print_recorded_oop(int log_n, int index); @@ -941,9 +940,7 @@ class nmethod : public CodeBlob { void maybe_print_nmethod(const DirectiveSet* directive); void print_nmethod(bool print_code); - // need to re-define this from CodeBlob else the overload hides it - void print_on(outputStream* st) const override { CodeBlob::print_on(st); } - void print_on(outputStream* st, const char* msg) const; + void print_on_with_msg(outputStream* st, const char* msg) const; // Logging void log_identity(xmlStream* log) const; @@ -951,13 +948,6 @@ class nmethod : public CodeBlob { void log_state_change() const; // Prints block-level comments, including nmethod specific block labels: - void print_block_comment(outputStream* stream, address block_begin) const override { -#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY) - print_nmethod_labels(stream, block_begin); - CodeBlob::print_block_comment(stream, block_begin); -#endif - } - void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const; const char* nmethod_section_label(address pos) const; @@ -995,6 +985,18 @@ class nmethod : public CodeBlob { void make_deoptimized(); void finalize_relocations(); + + class Vptr : public CodeBlob::Vptr { + void print_on(const CodeBlob* instance, outputStream* st) const override { + ttyLocker ttyl; + instance->as_nmethod()->print_on_impl(st); + } + void print_value_on(const CodeBlob* instance, outputStream* st) const override { + instance->as_nmethod()->print_value_on_impl(st); + } + }; + + static const Vptr _vpntr; }; #endif // SHARE_CODE_NMETHOD_HPP diff --git a/src/hotspot/share/code/oopRecorder.cpp b/src/hotspot/share/code/oopRecorder.cpp index 1849493974ca4..af23bf12b4386 100644 --- a/src/hotspot/share/code/oopRecorder.cpp +++ b/src/hotspot/share/code/oopRecorder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciEnv.hpp" #include "ci/ciInstance.hpp" #include "ci/ciMetadata.hpp" diff --git a/src/hotspot/share/code/pcDesc.cpp b/src/hotspot/share/code/pcDesc.cpp index 241eee03a9c13..23f0c9f80c5fe 100644 --- a/src/hotspot/share/code/pcDesc.cpp +++ b/src/hotspot/share/code/pcDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfoRec.hpp" #include "code/nmethod.hpp" #include "code/pcDesc.hpp" diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp index a379f88ddc180..9dc4eced9662b 100644 --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/share/code/scopeDesc.cpp b/src/hotspot/share/code/scopeDesc.cpp index d22d3352f4e4e..d3e08a886e6e4 100644 --- a/src/hotspot/share/code/scopeDesc.cpp +++ b/src/hotspot/share/code/scopeDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "code/debugInfoRec.hpp" #include "code/pcDesc.hpp" diff --git a/src/hotspot/share/code/stubs.cpp b/src/hotspot/share/code/stubs.cpp index 95cee4edb43c9..074241ff61133 100644 --- a/src/hotspot/share/code/stubs.cpp +++ b/src/hotspot/share/code/stubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" #include "code/stubs.hpp" diff --git a/src/hotspot/share/code/vmreg.cpp b/src/hotspot/share/code/vmreg.cpp index b9ee4a6b3e7a5..7407eceac0580 100644 --- a/src/hotspot/share/code/vmreg.cpp +++ b/src/hotspot/share/code/vmreg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "code/vmreg.hpp" diff --git a/src/hotspot/share/code/vtableStubs.cpp b/src/hotspot/share/code/vtableStubs.cpp index 6a0c52ae828c4..00826f820366d 100644 --- a/src/hotspot/share/code/vtableStubs.cpp +++ b/src/hotspot/share/code/vtableStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" @@ -79,7 +78,7 @@ void* VtableStub::operator new(size_t size, int code_size) throw() { void VtableStub::print_on(outputStream* st) const { - st->print("vtable stub (index = %d, receiver_location = " INTX_FORMAT ", code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "])", + st->print("vtable stub (index = %d, receiver_location = %zd, code = [" INTPTR_FORMAT ", " INTPTR_FORMAT "])", index(), p2i(receiver_location()), p2i(code_begin()), p2i(code_end())); } @@ -226,7 +225,7 @@ address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { enter(is_vtable_stub, vtable_index, s); if (PrintAdapterHandlers) { - tty->print_cr("Decoding VtableStub %s[%d]@" PTR_FORMAT " [" PTR_FORMAT ", " PTR_FORMAT "] (" SIZE_FORMAT " bytes)", + tty->print_cr("Decoding VtableStub %s[%d]@" PTR_FORMAT " [" PTR_FORMAT ", " PTR_FORMAT "] (%zu bytes)", is_vtable_stub? "vtbl": "itbl", vtable_index, p2i(VtableStub::receiver_location()), p2i(s->code_begin()), p2i(s->code_end()), pointer_delta(s->code_end(), s->code_begin(), 1)); Disassembler::decode(s->code_begin(), s->code_end()); diff --git a/src/hotspot/share/compiler/abstractCompiler.cpp b/src/hotspot/share/compiler/abstractCompiler.cpp index 0c094c75d8b59..386243850ddb2 100644 --- a/src/hotspot/share/compiler/abstractCompiler.cpp +++ b/src/hotspot/share/compiler/abstractCompiler.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ // questions. // -#include "precompiled.hpp" #include "compiler/abstractCompiler.hpp" #include "compiler/compileBroker.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/compiler/abstractDisassembler.cpp b/src/hotspot/share/compiler/abstractDisassembler.cpp index 6117108155fe8..32f37e7b5139b 100644 --- a/src/hotspot/share/compiler/abstractDisassembler.cpp +++ b/src/hotspot/share/compiler/abstractDisassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,6 @@ // AbstractDisassembler is the base class for // platform-specific Disassembler classes. -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "compiler/abstractDisassembler.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/compiler/cHeapStringHolder.cpp b/src/hotspot/share/compiler/cHeapStringHolder.cpp index 0383e738a47c9..261658e04eb1c 100644 --- a/src/hotspot/share/compiler/cHeapStringHolder.cpp +++ b/src/hotspot/share/compiler/cHeapStringHolder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/cHeapStringHolder.hpp" void CHeapStringHolder::set(const char* string) { diff --git a/src/hotspot/share/compiler/compilationFailureInfo.cpp b/src/hotspot/share/compiler/compilationFailureInfo.cpp index fb94102ef1654..aaa9cb79d1211 100644 --- a/src/hotspot/share/compiler/compilationFailureInfo.cpp +++ b/src/hotspot/share/compiler/compilationFailureInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #if defined(COMPILER1) || defined(COMPILER2) #ifdef COMPILER1 diff --git a/src/hotspot/share/compiler/compilationLog.cpp b/src/hotspot/share/compiler/compilationLog.cpp index 822ff1a7ff4ab..f8dc24d3aaaf3 100644 --- a/src/hotspot/share/compiler/compilationLog.cpp +++ b/src/hotspot/share/compiler/compilationLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "compiler/compilationLog.hpp" #include "compiler/compileTask.hpp" diff --git a/src/hotspot/share/compiler/compilationMemoryStatistic.cpp b/src/hotspot/share/compiler/compilationMemoryStatistic.cpp index 4cc2043656efa..89d0b60212e22 100644 --- a/src/hotspot/share/compiler/compilationMemoryStatistic.cpp +++ b/src/hotspot/share/compiler/compilationMemoryStatistic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #ifdef COMPILER1 diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index 8fc70619abe7e..82061d92daa7c 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/scopeDesc.hpp" #include "compiler/compilationPolicy.hpp" #include "compiler/compileBroker.hpp" @@ -455,7 +454,7 @@ void CompilationPolicy::initialize() { c2_size = C2Compiler::initial_code_buffer_size(); #endif size_t buffer_size = c1_only ? c1_size : (c1_size/3 + 2*c2_size/3); - int max_count = (ReservedCodeCacheSize - (int)CompilerConfig::min_code_cache_size()) / (int)buffer_size; + int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size; if (count > max_count) { // Lower the compiler count such that all buffers fit into the code cache count = MAX2(max_count, c1_only ? 1 : 2); @@ -634,6 +633,11 @@ CompileTask* CompilationPolicy::select_task(CompileQueue* compile_queue) { task = next_task; continue; } + if (task->is_blocking() && task->compile_reason() == CompileTask::Reason_Whitebox) { + // CTW tasks, submitted as blocking Whitebox requests, do not participate in rate + // selection and/or any level adjustments. Just return them in order. + return task; + } Method* method = task->method(); methodHandle mh(Thread::current(), method); if (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, mh) && !is_old(mh)) { diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 30956b6c793bd..c34d9eb785e6f 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/vmClasses.hpp" @@ -366,13 +365,24 @@ void CompileQueue::free_all() { while (next != nullptr) { CompileTask* current = next; next = current->next(); + bool found_waiter = false; { - // Wake up thread that blocks on the compile task. MutexLocker ct_lock(current->lock()); - current->lock()->notify(); + assert(current->waiting_for_completion_count() <= 1, "more than one thread are waiting for task"); + if (current->waiting_for_completion_count() > 0) { + // If another thread waits for this task, we must wake them up + // so they will stop waiting and free the task. + current->lock()->notify(); + found_waiter = true; + } + } + if (!found_waiter) { + // If no one was waiting for this task, we need to free it ourselves. In this case, the task + // is also certainly unlocked, because, again, there is no waiter. + // Otherwise, by convention, it's the waiters responsibility to free the task. + // Put the task back on the freelist. + CompileTask::free(current); } - // Put the task back on the freelist. - CompileTask::free(current); } _first = nullptr; _last = nullptr; @@ -774,20 +784,6 @@ void CompileBroker::compilation_init(JavaThread* THREAD) { } #if defined(ASSERT) && COMPILER2_OR_JVMCI -// Stress testing. Dedicated threads revert optimizations based on escape analysis concurrently to -// the running java application. Configured with vm options DeoptimizeObjectsALot*. -class DeoptimizeObjectsALotThread : public JavaThread { - - static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS); - void deoptimize_objects_alot_loop_single(); - void deoptimize_objects_alot_loop_all(); - -public: - DeoptimizeObjectsALotThread() : JavaThread(&deopt_objs_alot_thread_entry) { } - - bool is_hidden_from_external_view() const { return true; } -}; - // Entry for DeoptimizeObjectsALotThread. The threads are started in // CompileBroker::init_compiler_threads() iff DeoptimizeObjectsALot is enabled void DeoptimizeObjectsALotThread::deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS) { @@ -1737,9 +1733,11 @@ void CompileBroker::wait_for_completion(CompileTask* task) { { MonitorLocker ml(thread, task->lock()); free_task = true; + task->inc_waiting_for_completion(); while (!task->is_complete() && !is_compilation_disabled_forever()) { ml.wait(); } + task->dec_waiting_for_completion(); } if (free_task) { @@ -1917,7 +1915,7 @@ void CompileBroker::compiler_thread_loop() { // Open a log. CompileLog* log = get_log(thread); if (log != nullptr) { - log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'", + log->begin_elem("start_compile_thread name='%s' thread='%zu' process='%d'", thread->name(), os::current_thread_id(), os::current_process_id()); @@ -2008,11 +2006,11 @@ void CompileBroker::init_compiler_thread_log() { for (int try_temp_dir = 1; try_temp_dir >= 0; try_temp_dir--) { const char* dir = (try_temp_dir ? os::get_temp_directory() : nullptr); if (dir == nullptr) { - jio_snprintf(file_name, sizeof(file_name), "hs_c" UINTX_FORMAT "_pid%u.log", + jio_snprintf(file_name, sizeof(file_name), "hs_c%zu_pid%u.log", thread_id, os::current_process_id()); } else { jio_snprintf(file_name, sizeof(file_name), - "%s%shs_c" UINTX_FORMAT "_pid%u.log", dir, + "%s%shs_c%zu_pid%u.log", dir, os::file_separator(), thread_id, os::current_process_id()); } @@ -2031,7 +2029,7 @@ void CompileBroker::init_compiler_thread_log() { if (xtty != nullptr) { ttyLocker ttyl; // Record any per thread log files - xtty->elem("thread_logfile thread='" INTX_FORMAT "' filename='%s'", thread_id, file_name); + xtty->elem("thread_logfile thread='%zd' filename='%s'", thread_id, file_name); } return; } @@ -2076,7 +2074,21 @@ void CompileBroker::maybe_block() { if (PrintCompilation && (Verbose || WizardMode)) tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", p2i(Thread::current())); #endif + // If we are executing a task during the request to block, report the task + // before disappearing. + CompilerThread* thread = CompilerThread::current(); + if (thread != nullptr) { + CompileTask* task = thread->task(); + if (task != nullptr) { + if (PrintCompilation) { + task->print(tty, "blocked"); + } + task->print_ul("blocked"); + } + } + // Go to VM state and block for final VM shutdown safepoint. ThreadInVMfromNative tivfn(JavaThread::current()); + assert(false, "Should never unblock from TIVNM entry"); } } @@ -2532,6 +2544,11 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time // C1 and C2 counters are counting both successful and unsuccessful compiles _t_total_compilation.add(time); + // Update compilation times. Used by the implementation of JFR CompilerStatistics + // and java.lang.management.CompilationMXBean. + _perf_total_compilation->inc(time.ticks()); + _peak_compilation_time = MAX2(time.milliseconds(), _peak_compilation_time); + if (!success) { _total_bailout_count++; if (UsePerfData) { @@ -2550,12 +2567,6 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time _t_invalidated_compilation.add(time); } else { // Compilation succeeded - - // update compilation ticks - used by the implementation of - // java.lang.management.CompilationMXBean - _perf_total_compilation->inc(time.ticks()); - _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time; - if (CITime) { int bytes_compiled = method->code_size() + task->num_inlined_bytecodes(); if (is_osr) { @@ -2779,9 +2790,9 @@ void CompileBroker::print_info(outputStream *out) { out->print_cr("CodeCache overview"); out->print_cr("--------------------------------------------------------"); out->cr(); - out->print_cr(" Reserved size : " SIZE_FORMAT_W(7) " KB", CodeCache::max_capacity() / K); - out->print_cr(" Committed size : " SIZE_FORMAT_W(7) " KB", CodeCache::capacity() / K); - out->print_cr(" Unallocated capacity : " SIZE_FORMAT_W(7) " KB", CodeCache::unallocated_capacity() / K); + out->print_cr(" Reserved size : %7zu KB", CodeCache::max_capacity() / K); + out->print_cr(" Committed size : %7zu KB", CodeCache::capacity() / K); + out->print_cr(" Unallocated capacity : %7zu KB", CodeCache::unallocated_capacity() / K); out->cr(); } diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index f6067f75d32aa..ac62a20bc6ff2 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,22 @@ class nmethod; +#if defined(ASSERT) && COMPILER2_OR_JVMCI +// Stress testing. Dedicated threads revert optimizations based on escape analysis concurrently to +// the running java application. Configured with vm options DeoptimizeObjectsALot*. +class DeoptimizeObjectsALotThread : public JavaThread { + + static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS); + void deoptimize_objects_alot_loop_single(); + void deoptimize_objects_alot_loop_all(); + +public: + DeoptimizeObjectsALotThread() : JavaThread(&deopt_objs_alot_thread_entry) { } + + bool is_hidden_from_external_view() const { return true; } +}; +#endif + // CompilerCounters // // Per Compiler Performance Counters. diff --git a/src/hotspot/share/compiler/compileLog.cpp b/src/hotspot/share/compiler/compileLog.cpp index 7b780fec492f9..85b8cbdf5921a 100644 --- a/src/hotspot/share/compiler/compileLog.cpp +++ b/src/hotspot/share/compiler/compileLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethod.hpp" #include "code/codeCache.hpp" #include "compiler/compileLog.hpp" @@ -212,7 +211,7 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen) // print/print_cr may need to allocate large stack buffer to format // strings, here we use snprintf() and print_raw() instead. file->print_raw(""); diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index 1a2af5721665f..6668f212b214e 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilationPolicy.hpp" #include "compiler/compileTask.hpp" #include "compiler/compileLog.hpp" @@ -32,6 +31,7 @@ #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" #include "oops/klass.inline.hpp" +#include "oops/method.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" #include "runtime/mutexLocker.hpp" @@ -107,6 +107,8 @@ void CompileTask::initialize(int compile_id, _comp_level = comp_level; _num_inlined_bytecodes = 0; + _waiting_count = 0; + _is_complete = false; _is_success = false; @@ -283,21 +285,6 @@ void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, i } } -void CompileTask::print_inline_indent(int inline_level, outputStream* st) { - // 1234567 - st->print(" "); // print timestamp - // 1234 - st->print(" "); // print compilation number - // %s!bn - st->print(" "); // print method attributes - if (TieredCompilation) { - st->print(" "); - } - st->print(" "); // more indent - st->print(" "); // initial inlining indent - for (int i = 0; i < inline_level; i++) st->print(" "); -} - // ------------------------------------------------------------------ // CompileTask::print_compilation void CompileTask::print(outputStream* st, const char* msg, bool short_form, bool cr) { @@ -411,45 +398,76 @@ bool CompileTask::check_break_at_flags() { // ------------------------------------------------------------------ // CompileTask::print_inlining void CompileTask::print_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg) { + print_inlining_header(st, method, inline_level, bci); + print_inlining_inner_message(st, result, msg); + st->cr(); +} + +void CompileTask::print_inlining_header(outputStream* st, ciMethod* method, int inline_level, int bci) { // 1234567 - st->print(" "); // print timestamp + st->print(" "); // print timestamp // 1234 - st->print(" "); // print compilation number + st->print(" "); // print compilation number // method attributes if (method->is_loaded()) { - const char sync_char = method->is_synchronized() ? 's' : ' '; + const char sync_char = method->is_synchronized() ? 's' : ' '; const char exception_char = method->has_exception_handlers() ? '!' : ' '; - const char monitors_char = method->has_monitor_bytecodes() ? 'm' : ' '; + const char monitors_char = method->has_monitor_bytecodes() ? 'm' : ' '; // print method attributes st->print(" %c%c%c ", sync_char, exception_char, monitors_char); } else { // %s!bn - st->print(" "); // print method attributes + st->print(" "); // print method attributes } if (TieredCompilation) { st->print(" "); } - st->print(" "); // more indent - st->print(" "); // initial inlining indent + st->print(" "); // more indent + st->print(" "); // initial inlining indent - for (int i = 0; i < inline_level; i++) st->print(" "); + for (int i = 0; i < inline_level; i++) { + st->print(" "); + } + + st->print("@ %d ", bci); // print bci + print_inline_inner_method_info(st, method); +} - st->print("@ %d ", bci); // print bci +void CompileTask::print_inline_inner_method_info(outputStream* st, ciMethod* method) { method->print_short_name(st); - if (method->is_loaded()) + if (method->is_loaded()) { st->print(" (%d bytes)", method->code_size()); - else + } else { st->print(" (not loaded)"); + } +} + +void CompileTask::print_inline_indent(int inline_level, outputStream* st) { + // 1234567 + st->print(" "); // print timestamp + // 1234 + st->print(" "); // print compilation number + // %s!bn + st->print(" "); // print method attributes + if (TieredCompilation) { + st->print(" "); + } + st->print(" "); // more indent + st->print(" "); // initial inlining indent + for (int i = 0; i < inline_level; i++) { + st->print(" "); + } +} +void CompileTask::print_inlining_inner_message(outputStream* st, InliningResult result, const char* msg) { if (msg != nullptr) { st->print(" %s%s", result == InliningResult::SUCCESS ? "" : "failed to inline: ", msg); } else if (result == InliningResult::FAILURE) { st->print(" %s", "failed to inline"); } - st->cr(); } void CompileTask::print_ul(const char* msg){ diff --git a/src/hotspot/share/compiler/compileTask.hpp b/src/hotspot/share/compiler/compileTask.hpp index 37459bd0ff52f..04ad7e35a139b 100644 --- a/src/hotspot/share/compiler/compileTask.hpp +++ b/src/hotspot/share/compiler/compileTask.hpp @@ -98,6 +98,7 @@ class CompileTask : public CHeapObj { // Compilation state for a blocking JVMCI compilation JVMCICompileState* _blocking_jvmci_compile_state; #endif + int _waiting_count; // See waiting_for_completion_count() int _comp_level; int _num_inlined_bytecodes; CompileTask* _next, *_prev; @@ -174,6 +175,23 @@ class CompileTask : public CHeapObj { Monitor* lock() const { return _lock; } + // See how many threads are waiting for this task. Must have lock to read this. + int waiting_for_completion_count() { + assert(_lock->owned_by_self(), "must have lock to use waiting_for_completion_count()"); + return _waiting_count; + } + // Indicates that a thread is waiting for this task to complete. Must have lock to use this. + void inc_waiting_for_completion() { + assert(_lock->owned_by_self(), "must have lock to use inc_waiting_for_completion()"); + _waiting_count++; + } + // Indicates that a thread stopped waiting for this task to complete. Must have lock to use this. + void dec_waiting_for_completion() { + assert(_lock->owned_by_self(), "must have lock to use dec_waiting_for_completion()"); + assert(_waiting_count > 0, "waiting count is not positive"); + _waiting_count--; + } + void mark_complete() { _is_complete = true; } void mark_success() { _is_success = true; } void mark_started(jlong time) { _time_started = time; } @@ -181,6 +199,8 @@ class CompileTask : public CHeapObj { int comp_level() { return _comp_level;} void set_comp_level(int comp_level) { _comp_level = comp_level;} + CompileReason compile_reason() { return _compile_reason; } + AbstractCompiler* compiler() const; CompileTask* select_for_compilation(); @@ -218,6 +238,9 @@ class CompileTask : public CHeapObj { } static void print_ul(const nmethod* nm, const char* msg = nullptr); + /** + * @deprecated Please rely on Compile::inline_printer. Do not directly write inlining information to tty. + */ static void print_inline_indent(int inline_level, outputStream* st = tty); void print_tty(); @@ -235,7 +258,11 @@ class CompileTask : public CHeapObj { bool check_break_at_flags(); + static void print_inlining_header(outputStream* st, ciMethod* method, int inline_level, int bci); static void print_inlining_inner(outputStream* st, ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg = nullptr); + static void print_inline_inner_method_info(outputStream* st, ciMethod* method); + static void print_inlining_inner_message(outputStream* st, InliningResult result, const char* msg); + static void print_inlining_tty(ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg = nullptr) { print_inlining_inner(tty, method, inline_level, bci, result, msg); } diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp index ad3d14012ff62..f82e96be6ae7e 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.cpp +++ b/src/hotspot/share/compiler/compilerDefinitions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "compiler/compilerDefinitions.inline.hpp" #include "interpreter/invocationCounter.hpp" @@ -475,7 +474,8 @@ void CompilerConfig::set_jvmci_specific_flags() { bool CompilerConfig::check_args_consistency(bool status) { // Check lower bounds of the code cache - size_t min_code_cache_size = CompilerConfig::min_code_cache_size(); + // Template Interpreter code is approximately 3X larger in debug builds. + uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3); if (ReservedCodeCacheSize < InitialCodeCacheSize) { jio_fprintf(defaultStream::error_stream(), "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n", diff --git a/src/hotspot/share/compiler/compilerDefinitions.hpp b/src/hotspot/share/compiler/compilerDefinitions.hpp index a72e82e32bd56..bdaa6dffb8f5f 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,8 +148,6 @@ class CompilerConfig : public AllStatic { inline static bool is_c2_or_jvmci_compiler_only(); inline static bool is_c2_or_jvmci_compiler_enabled(); - inline static size_t min_code_cache_size(); - private: static bool is_compilation_mode_selected(); static void set_compilation_policy_flags(); diff --git a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp index 5d04ef307d0f7..45df9b0b8b005 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,6 @@ #ifndef SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP #define SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP -#ifdef COMPILER1 -#include "c1/c1_Compiler.hpp" -#endif -#ifdef COMPILER2 -#include "opto/c2compiler.hpp" -#endif #include "compiler/compilerDefinitions.hpp" #include "compiler/compiler_globals.hpp" #include "runtime/arguments.hpp" @@ -136,13 +130,4 @@ inline bool CompilerConfig::is_c2_or_jvmci_compiler_enabled() { return is_c2_enabled() || is_jvmci_compiler_enabled(); } -inline size_t CompilerConfig::min_code_cache_size() { - size_t min_code_cache_size = CodeCacheMinimumUseSpace; - // Template Interpreter code is approximately 3X larger in debug builds. - DEBUG_ONLY(min_code_cache_size *= 3); - COMPILER1_PRESENT(min_code_cache_size += Compiler::code_buffer_size()); - COMPILER2_PRESENT(min_code_cache_size += C2Compiler::initial_code_buffer_size()); - return min_code_cache_size; -} - #endif // SHARE_COMPILER_COMPILERDEFINITIONS_INLINE_HPP diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index 46750cacc35db..5431b03f6a142 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethod.hpp" #include "ci/ciUtilities.inline.hpp" #include "compiler/abstractCompiler.hpp" diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index 620874508f483..74e3d8b9b38e7 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -218,8 +218,8 @@ void set_##name(void* value) { \ return _trace_merge_stores_tags; }; - void print_intx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" INTX_FORMAT " ", n, v); } } - void print_uintx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" UINTX_FORMAT " ", n, v); } } + void print_intx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:%zd ", n, v); } } + void print_uintx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:%zu ", n, v); } } void print_bool(outputStream* st, ccstr n, bool v, bool mod) { if (mod) { st->print("%s:%s ", n, v ? "true" : "false"); } } void print_double(outputStream* st, ccstr n, double v, bool mod) { if (mod) { st->print("%s:%f ", n, v); } } void print_ccstr(outputStream* st, ccstr n, ccstr v, bool mod) { if (mod) { st->print("%s:%s ", n, v); } } diff --git a/src/hotspot/share/compiler/compilerEvent.cpp b/src/hotspot/share/compiler/compilerEvent.cpp index d2f6e7ba88670..4bc859ef0d642 100644 --- a/src/hotspot/share/compiler/compilerEvent.cpp +++ b/src/hotspot/share/compiler/compilerEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "ci/ciMethod.hpp" #include "compiler/compilerEvent.hpp" #include "jfr/jfr.hpp" diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index 107350794a02d..8e296226feec1 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "compiler/compilerDirectives.hpp" #include "compiler/compilerOracle.hpp" @@ -236,10 +235,10 @@ void TypedMethodOptionMatcher::print() { enum OptionType type = option2type(_option); switch (type) { case OptionType::Intx: - tty->print_cr(" intx %s = " INTX_FORMAT, name, value()); + tty->print_cr(" intx %s = %zd", name, value()); break; case OptionType::Uintx: - tty->print_cr(" uintx %s = " UINTX_FORMAT, name, value()); + tty->print_cr(" uintx %s = %zu", name, value()); break; case OptionType::Bool: tty->print_cr(" bool %s = %s", name, value() ? "true" : "false"); @@ -736,7 +735,7 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, success = parseMemLimit(line, value, bytes_read, errorbuf, buf_size); } else { // Is it a raw number? - success = sscanf(line, "" INTX_FORMAT "%n", &value, &bytes_read) == 1; + success = sscanf(line, "%zd%n", &value, &bytes_read) == 1; } if (success) { total_bytes_read += bytes_read; @@ -754,7 +753,7 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, success = parseMemStat(line, value, bytes_read, errorbuf, buf_size); } else { // parse as raw number - success = sscanf(line, "" UINTX_FORMAT "%n", &value, &bytes_read) == 1; + success = sscanf(line, "%zu%n", &value, &bytes_read) == 1; } if (success) { total_bytes_read += bytes_read; diff --git a/src/hotspot/share/compiler/compilerThread.cpp b/src/hotspot/share/compiler/compilerThread.cpp index e6329f3e65579..a72fc48b9a116 100644 --- a/src/hotspot/share/compiler/compilerThread.cpp +++ b/src/hotspot/share/compiler/compilerThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilationMemoryStatistic.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compileTask.hpp" diff --git a/src/hotspot/share/compiler/directivesParser.cpp b/src/hotspot/share/compiler/directivesParser.cpp index 731bf33d799dd..72cc0612c492f 100644 --- a/src/hotspot/share/compiler/directivesParser.cpp +++ b/src/hotspot/share/compiler/directivesParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileBroker.hpp" #include "compiler/directivesParser.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp index 6556ce4ae1df2..f8313db66aa2d 100644 --- a/src/hotspot/share/compiler/disassembler.cpp +++ b/src/hotspot/share/compiler/disassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "asm/macroAssembler.hpp" #include "ci/ciUtilities.hpp" @@ -597,7 +596,7 @@ void decode_env::print_address(address adr) { if (desc != nullptr) { st->print("Stub::%s", desc->name()); if (desc->begin() != adr) { - st->print(INTX_FORMAT_W(+) " " PTR_FORMAT, adr - desc->begin(), p2i(adr)); + st->print("%+zd " PTR_FORMAT, adr - desc->begin(), p2i(adr)); } else if (WizardMode) { st->print(" " PTR_FORMAT, p2i(adr)); } diff --git a/src/hotspot/share/compiler/methodLiveness.cpp b/src/hotspot/share/compiler/methodLiveness.cpp index 7d65b20a1595e..af21321e05d59 100644 --- a/src/hotspot/share/compiler/methodLiveness.cpp +++ b/src/hotspot/share/compiler/methodLiveness.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethod.hpp" #include "ci/ciMethodBlocks.hpp" #include "ci/ciStreams.hpp" diff --git a/src/hotspot/share/compiler/methodMatcher.cpp b/src/hotspot/share/compiler/methodMatcher.cpp index 0bd5cdd8501fc..1f401d2e409b7 100644 --- a/src/hotspot/share/compiler/methodMatcher.cpp +++ b/src/hotspot/share/compiler/methodMatcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compilerOracle.hpp" diff --git a/src/hotspot/share/compiler/oopMap.cpp b/src/hotspot/share/compiler/oopMap.cpp index 376057aa72e25..ea2c770d66f74 100644 --- a/src/hotspot/share/compiler/oopMap.cpp +++ b/src/hotspot/share/compiler/oopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" #include "code/nmethod.hpp" @@ -929,7 +928,7 @@ void DerivedPointerTable::add(derived_pointer* derived_loc, derived_base* base_l tty->print_cr( "Add derived pointer@" INTPTR_FORMAT " - Derived: " INTPTR_FORMAT - " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")", + " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: %zd)", p2i(derived_loc), derived_pointer_value(*derived_loc), intptr_t(*base_loc), p2i(base_loc), offset ); } @@ -959,7 +958,7 @@ void DerivedPointerTable::update_pointers() { if (TraceDerivedPointers) { tty->print_cr("Updating derived pointer@" INTPTR_FORMAT - " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: " INTX_FORMAT ")", + " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (Offset: %zd)", p2i(derived_loc), derived_pointer_value(*derived_loc), p2i(base), offset); } diff --git a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp index ba023e8799bc5..fc2ee7dff013b 100644 --- a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonArguments.hpp" #include "gc/epsilon/epsilonHeap.hpp" #include "gc/shared/gcArguments.hpp" @@ -46,7 +45,7 @@ void EpsilonArguments::initialize() { } if (EpsilonMaxTLABSize < MinTLABSize) { - log_warning(gc)("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize); + log_warning(gc)("EpsilonMaxTLABSize < MinTLABSize, adjusting it to %zu", MinTLABSize); EpsilonMaxTLABSize = MinTLABSize; } diff --git a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp index 6444ea344c2d5..e02da30d8e5ae 100644 --- a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonBarrierSet.hpp" #include "gc/epsilon/epsilonThreadLocalData.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp index 3cd5665e04534..8bc98835844ed 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonHeap.hpp" #include "gc/epsilon/epsilonInitLogger.hpp" #include "gc/epsilon/epsilonMemoryPool.hpp" @@ -103,7 +102,7 @@ EpsilonHeap* EpsilonHeap::heap() { } HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) { - assert(is_object_aligned(size), "Allocation size should be aligned: " SIZE_FORMAT, size); + assert(is_object_aligned(size), "Allocation size should be aligned: %zu", size); HeapWord* res = nullptr; while (true) { @@ -129,7 +128,7 @@ HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) { size_t unused_space = max_capacity() - used(); size_t want_space = MAX2(size_in_bytes, EpsilonMinHeapExpand); assert(unused_space >= uncommitted_space, - "Unused (" SIZE_FORMAT ") >= uncommitted (" SIZE_FORMAT ")", + "Unused (%zu) >= uncommitted (%zu)", unused_space, uncommitted_space); if (want_space < uncommitted_space) { @@ -218,18 +217,18 @@ HeapWord* EpsilonHeap::allocate_new_tlab(size_t min_size, // Check that adjustments did not break local and global invariants assert(is_object_aligned(size), - "Size honors object alignment: " SIZE_FORMAT, size); + "Size honors object alignment: %zu", size); assert(min_size <= size, - "Size honors min size: " SIZE_FORMAT " <= " SIZE_FORMAT, min_size, size); + "Size honors min size: %zu <= %zu", min_size, size); assert(size <= _max_tlab_size, - "Size honors max size: " SIZE_FORMAT " <= " SIZE_FORMAT, size, _max_tlab_size); + "Size honors max size: %zu <= %zu", size, _max_tlab_size); assert(size <= CollectedHeap::max_tlab_size(), - "Size honors global max size: " SIZE_FORMAT " <= " SIZE_FORMAT, size, CollectedHeap::max_tlab_size()); + "Size honors global max size: %zu <= %zu", size, CollectedHeap::max_tlab_size()); if (log_is_enabled(Trace, gc)) { ResourceMark rm; - log_trace(gc)("TLAB size for \"%s\" (Requested: " SIZE_FORMAT "K, Min: " SIZE_FORMAT - "K, Max: " SIZE_FORMAT "K, Ergo: " SIZE_FORMAT "K) -> " SIZE_FORMAT "K", + log_trace(gc)("TLAB size for \"%s\" (Requested: %zuK, Min: %zu" + "K, Max: %zuK, Ergo: %zuK) -> %zuK", thread->name(), requested_size * HeapWordSize / K, min_size * HeapWordSize / K, @@ -325,8 +324,8 @@ void EpsilonHeap::print_heap_info(size_t used) const { size_t committed = capacity(); if (reserved != 0) { - log_info(gc)("Heap: " SIZE_FORMAT "%s reserved, " SIZE_FORMAT "%s (%.2f%%) committed, " - SIZE_FORMAT "%s (%.2f%%) used", + log_info(gc)("Heap: %zu%s reserved, %zu%s (%.2f%%) committed, " + "%zu%s (%.2f%%) used", byte_size_in_proper_unit(reserved), proper_unit_for_byte_size(reserved), byte_size_in_proper_unit(committed), proper_unit_for_byte_size(committed), committed * 100.0 / reserved, @@ -344,8 +343,8 @@ void EpsilonHeap::print_metaspace_info() const { size_t used = stats.used(); if (reserved != 0) { - log_info(gc, metaspace)("Metaspace: " SIZE_FORMAT "%s reserved, " SIZE_FORMAT "%s (%.2f%%) committed, " - SIZE_FORMAT "%s (%.2f%%) used", + log_info(gc, metaspace)("Metaspace: %zu%s reserved, %zu%s (%.2f%%) committed, " + "%zu%s (%.2f%%) used", byte_size_in_proper_unit(reserved), proper_unit_for_byte_size(reserved), byte_size_in_proper_unit(committed), proper_unit_for_byte_size(committed), committed * 100.0 / reserved, diff --git a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp index a75e9e7679da7..fec5110fba338 100644 --- a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonHeap.hpp" #include "gc/epsilon/epsilonInitLogger.hpp" #include "gc/shared/tlab_globals.hpp" @@ -32,31 +31,31 @@ #include "utilities/globalDefinitions.hpp" void EpsilonInitLogger::print_gc_specific() { - // Warn users that non-resizable heap might be better for some configurations. - // We are not adjusting the heap size by ourselves, because it affects startup time. - if (InitialHeapSize != MaxHeapSize) { - log_warning(gc, init)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups"); - } - - // Warn users that AlwaysPreTouch might be better for some configurations. - // We are not turning this on by ourselves, because it affects startup time. - if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) { - log_warning(gc, init)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups"); - } - if (UseTLAB) { size_t max_tlab = EpsilonHeap::heap()->max_tlab_size() * HeapWordSize; - log_info(gc, init)("TLAB Size Max: " SIZE_FORMAT "%s", + log_info(gc, init)("TLAB Size Max: %zu%s", byte_size_in_exact_unit(max_tlab), exact_unit_for_byte_size(max_tlab)); if (EpsilonElasticTLAB) { log_info(gc, init)("TLAB Size Elasticity: %.2fx", EpsilonTLABElasticity); } if (EpsilonElasticTLABDecay) { - log_info(gc, init)("TLAB Size Decay Time: " SIZE_FORMAT "ms", EpsilonTLABDecayTime); + log_info(gc, init)("TLAB Size Decay Time: %zums", EpsilonTLABDecayTime); } } else { log_info(gc, init)("TLAB: Disabled"); } + + // Suggest that non-resizable heap might be better for some configurations. + // We are not adjusting the heap size by ourselves, because it affects startup time. + if (InitialHeapSize != MaxHeapSize) { + log_info(gc)("Consider setting -Xms equal to -Xmx to avoid resizing hiccups"); + } + + // Suggest that AlwaysPreTouch might be better for some configurations. + // We are not turning this on by ourselves, because it affects startup time. + if (FLAG_IS_DEFAULT(AlwaysPreTouch) && !AlwaysPreTouch) { + log_info(gc)("Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups"); + } } void EpsilonInitLogger::print() { diff --git a/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp index b90d6e38d28d5..013b00d505a9f 100644 --- a/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonHeap.hpp" #include "gc/epsilon/epsilonMemoryPool.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp index 93d84d5604ccf..540ede9dd83ac 100644 --- a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp +++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/epsilon/epsilonMonitoringSupport.hpp" #include "gc/epsilon/epsilonHeap.hpp" #include "gc/shared/generationCounters.hpp" @@ -91,8 +90,8 @@ class EpsilonGenerationCounters : public GenerationCounters { _heap(heap) {}; - virtual void update_all() { - _current_size->set_value(_heap->capacity()); + void update_all() { + GenerationCounters::update_all(_heap->capacity()); } }; diff --git a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp index 73cfc94361265..67a60d9277848 100644 --- a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp @@ -27,13 +27,13 @@ #include "memory/allocation.hpp" -class GenerationCounters; +class EpsilonGenerationCounters; class EpsilonSpaceCounters; class EpsilonHeap; class EpsilonMonitoringSupport : public CHeapObj { private: - GenerationCounters* _heap_counters; + EpsilonGenerationCounters* _heap_counters; EpsilonSpaceCounters* _space_counters; public: diff --git a/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp b/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp index 449ff2e4acf8b..1e91e067f330b 100644 --- a/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp +++ b/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_LIRGenerator.hpp" #include "c1/c1_CodeStubs.hpp" #include "gc/g1/c1/g1BarrierSetC1.hpp" diff --git a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp index 315aa469dbe56..71fd3ec66108d 100644 --- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp +++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "code/vmreg.inline.hpp" #include "gc/g1/c2/g1BarrierSetC2.hpp" @@ -530,8 +529,65 @@ int G1BarrierSetC2::get_store_barrier(C2Access& access) const { return barriers; } +void G1BarrierSetC2::elide_dominated_barrier(MachNode* mach) const { + uint8_t barrier_data = mach->barrier_data(); + barrier_data &= ~G1C2BarrierPre; + if (CardTableBarrierSetC2::use_ReduceInitialCardMarks()) { + barrier_data &= ~G1C2BarrierPost; + barrier_data &= ~G1C2BarrierPostNotNull; + } + mach->set_barrier_data(barrier_data); +} + +void G1BarrierSetC2::analyze_dominating_barriers() const { + ResourceMark rm; + PhaseCFG* const cfg = Compile::current()->cfg(); + + // Find allocations and memory accesses (stores and atomic operations), and + // track them in lists. + Node_List accesses; + Node_List allocations; + for (uint i = 0; i < cfg->number_of_blocks(); ++i) { + const Block* const block = cfg->get_block(i); + for (uint j = 0; j < block->number_of_nodes(); ++j) { + Node* const node = block->get_node(j); + if (node->is_Phi()) { + if (BarrierSetC2::is_allocation(node)) { + allocations.push(node); + } + continue; + } else if (!node->is_Mach()) { + continue; + } + + MachNode* const mach = node->as_Mach(); + switch (mach->ideal_Opcode()) { + case Op_StoreP: + case Op_StoreN: + case Op_CompareAndExchangeP: + case Op_CompareAndSwapP: + case Op_GetAndSetP: + case Op_CompareAndExchangeN: + case Op_CompareAndSwapN: + case Op_GetAndSetN: + if (mach->barrier_data() != 0) { + accesses.push(mach); + } + break; + default: + break; + } + } + } + + // Find dominating allocations for each memory access (store or atomic + // operation) and elide barriers if there is no safepoint poll in between. + elide_dominated_barriers(accesses, allocations); +} + void G1BarrierSetC2::late_barrier_analysis() const { compute_liveness_at_stubs(); + analyze_dominating_barriers(); } void G1BarrierSetC2::emit_stubs(CodeBuffer& cb) const { diff --git a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp index 81e67df29ce97..5f85714d88979 100644 --- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp +++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,6 +86,9 @@ class G1PostBarrierStubC2 : public G1BarrierStubC2 { }; class G1BarrierSetC2: public CardTableBarrierSetC2 { +private: + void analyze_dominating_barriers() const; + protected: bool g1_can_remove_pre_barrier(GraphKit* kit, PhaseValues* phase, @@ -117,6 +120,7 @@ class G1BarrierSetC2: public CardTableBarrierSetC2 { ArrayCopyNode* ac) const; virtual void* create_barrier_state(Arena* comp_arena) const; virtual void emit_stubs(CodeBuffer& cb) const; + virtual void elide_dominated_barrier(MachNode* mach) const; virtual void late_barrier_analysis() const; #ifndef PRODUCT diff --git a/src/hotspot/share/gc/g1/g1AllocRegion.cpp b/src/hotspot/share/gc/g1/g1AllocRegion.cpp index a0a2b31ed6a18..47d7e3a6bffa7 100644 --- a/src/hotspot/share/gc/g1/g1AllocRegion.cpp +++ b/src/hotspot/share/gc/g1/g1AllocRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1AllocRegion.inline.hpp" #include "gc/g1/g1EvacStats.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" @@ -225,10 +224,10 @@ void G1AllocRegion::trace(const char* str, size_t min_word_size, size_t desired_ if (detailed_info) { if (result != nullptr) { - out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT, + out->print(" min %zu desired %zu actual %zu " PTR_FORMAT, min_word_size, desired_word_size, actual_word_size, p2i(result)); } else if (min_word_size != 0) { - out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size); + out->print(" min %zu desired %zu", min_word_size, desired_word_size); } } out->cr(); @@ -319,7 +318,7 @@ G1HeapRegion* MutatorAllocRegion::release() { _wasted_bytes += retire_internal(_retained_alloc_region, false); _retained_alloc_region = nullptr; } - log_debug(gc, alloc, region)("Mutator Allocation stats, regions: %u, wasted size: " SIZE_FORMAT "%s (%4.1f%%)", + log_debug(gc, alloc, region)("Mutator Allocation stats, regions: %u, wasted size: %zu%s (%4.1f%%)", count(), byte_size_in_proper_unit(_wasted_bytes), proper_unit_for_byte_size(_wasted_bytes), diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index be8c39ba440b2..56dbeb9eac140 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1AllocRegion.inline.hpp" #include "gc/g1/g1EvacInfo.hpp" @@ -218,7 +217,7 @@ HeapWord* G1Allocator::par_allocate_during_gc(G1HeapRegionAttr dest, size_t temp = 0; HeapWord* result = par_allocate_during_gc(dest, word_size, word_size, &temp, node_index); assert(result == nullptr || temp == word_size, - "Requested " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT, + "Requested %zu words, but got %zu at " PTR_FORMAT, word_size, temp, p2i(result)); return result; } diff --git a/src/hotspot/share/gc/g1/g1Analytics.cpp b/src/hotspot/share/gc/g1/g1Analytics.cpp index 5809bfa2b6c5e..59d1a48cd8529 100644 --- a/src/hotspot/share/gc/g1/g1Analytics.cpp +++ b/src/hotspot/share/gc/g1/g1Analytics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1AnalyticsSequences.inline.hpp" #include "gc/g1/g1Predictions.hpp" diff --git a/src/hotspot/share/gc/g1/g1Arguments.cpp b/src/hotspot/share/gc/g1/g1Arguments.cpp index 1ae5f2ce76fef..b1cf9fd304620 100644 --- a/src/hotspot/share/gc/g1/g1Arguments.cpp +++ b/src/hotspot/share/gc/g1/g1Arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "gc/g1/g1Arguments.hpp" #include "gc/g1/g1CardSet.hpp" diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.cpp b/src/hotspot/share/gc/g1/g1BarrierSet.cpp index 4eb3fcf600b04..c56434340cd5a 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.cpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" #include "gc/g1/g1BarrierSetAssembler.hpp" #include "gc/g1/g1CardTable.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1BarrierSetRuntime.cpp b/src/hotspot/share/gc/g1/g1BarrierSetRuntime.cpp index ab67321242e71..ce0d53e4891cc 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSetRuntime.cpp +++ b/src/hotspot/share/gc/g1/g1BarrierSetRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" #include "gc/g1/g1BarrierSetRuntime.hpp" #include "gc/g1/g1ThreadLocalData.hpp" diff --git a/src/hotspot/share/gc/g1/g1BatchedTask.cpp b/src/hotspot/share/gc/g1/g1BatchedTask.cpp index 804ec06688054..9089ffedf61de 100644 --- a/src/hotspot/share/gc/g1/g1BatchedTask.cpp +++ b/src/hotspot/share/gc/g1/g1BatchedTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BatchedTask.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1BiasedArray.cpp b/src/hotspot/share/gc/g1/g1BiasedArray.cpp index 22b07db3d85d6..05b8d7834e764 100644 --- a/src/hotspot/share/gc/g1/g1BiasedArray.cpp +++ b/src/hotspot/share/gc/g1/g1BiasedArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BiasedArray.hpp" #include "memory/padded.inline.hpp" @@ -48,20 +47,20 @@ address G1BiasedMappedArrayBase::create_new_base_array(size_t length, size_t ele #ifndef PRODUCT void G1BiasedMappedArrayBase::verify_index(idx_t index) const { guarantee(_base != nullptr, "Array not initialized"); - guarantee(index < length(), "Index out of bounds index: " SIZE_FORMAT " length: " SIZE_FORMAT, index, length()); + guarantee(index < length(), "Index out of bounds index: %zu length: %zu", index, length()); } void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const { guarantee(_biased_base != nullptr, "Array not initialized"); guarantee(biased_index >= bias() && biased_index < (bias() + length()), - "Biased index out of bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, + "Biased index out of bounds, index: %zu bias: %zu length: %zu", biased_index, bias(), length()); } void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const { guarantee(_biased_base != nullptr, "Array not initialized"); guarantee(biased_index >= bias() && biased_index <= (bias() + length()), - "Biased index out of inclusive bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, + "Biased index out of inclusive bounds, index: %zu bias: %zu length: %zu", biased_index, bias(), length()); } diff --git a/src/hotspot/share/gc/g1/g1BiasedArray.hpp b/src/hotspot/share/gc/g1/g1BiasedArray.hpp index 67b4c6bbe3084..da99f928ab599 100644 --- a/src/hotspot/share/gc/g1/g1BiasedArray.hpp +++ b/src/hotspot/share/gc/g1/g1BiasedArray.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,12 +72,12 @@ class G1BiasedMappedArrayBase : public CHeapObj { void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) { assert(mapping_granularity_in_bytes > 0, "just checking"); assert(is_power_of_2(mapping_granularity_in_bytes), - "mapping granularity must be power of 2, is " SIZE_FORMAT, mapping_granularity_in_bytes); + "mapping granularity must be power of 2, is %zu", mapping_granularity_in_bytes); assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, - "bottom mapping area address must be a multiple of mapping granularity " SIZE_FORMAT ", is " PTR_FORMAT, + "bottom mapping area address must be a multiple of mapping granularity %zu, is " PTR_FORMAT, mapping_granularity_in_bytes, p2i(bottom)); assert((uintptr_t)end % mapping_granularity_in_bytes == 0, - "end mapping area address must be a multiple of mapping granularity " SIZE_FORMAT ", is " PTR_FORMAT, + "end mapping area address must be a multiple of mapping granularity %zu, is " PTR_FORMAT, mapping_granularity_in_bytes, p2i(end)); size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes); idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp index a8c558743184b..dcd1979343acb 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1HeapRegion.inline.hpp" @@ -44,7 +43,7 @@ G1BlockOffsetTable::G1BlockOffsetTable(MemRegion heap, G1RegionToSpaceMapper* st _offset_base = ((uint8_t*)bot_reserved.start() - (uintptr_t(_reserved.start()) >> CardTable::card_shift())); log_trace(gc, bot)("G1BlockOffsetTable::G1BlockOffsetTable: "); - log_trace(gc, bot)(" rs.base(): " PTR_FORMAT " rs.size(): " SIZE_FORMAT " rs end(): " PTR_FORMAT, + log_trace(gc, bot)(" rs.base(): " PTR_FORMAT " rs.size(): %zu rs end(): " PTR_FORMAT, p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end())); } diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp index e0454d803f1e4..59d5c4efcef21 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ class G1BlockOffsetTable: public CHeapObj { void check_offset(size_t offset, const char* msg) const { assert(offset < CardTable::card_size_in_words(), - "%s - offset: " SIZE_FORMAT ", N_words: %u", + "%s - offset: %zu, N_words: %u", msg, offset, CardTable::card_size_in_words()); } diff --git a/src/hotspot/share/gc/g1/g1CardSet.cpp b/src/hotspot/share/gc/g1/g1CardSet.cpp index 5c11a1a967700..5286a764996cc 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.cpp +++ b/src/hotspot/share/gc/g1/g1CardSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CardSet.inline.hpp" #include "gc/g1/g1CardSetContainers.inline.hpp" #include "gc/g1/g1CardSetMemory.inline.hpp" @@ -780,6 +779,15 @@ G1AddCardResult G1CardSet::add_card(uintptr_t card) { uint card_within_region; split_card(card, card_region, card_within_region); +#ifdef ASSERT + { + uint region_idx = card_region >> config()->log2_card_regions_per_heap_region(); + G1HeapRegion* r = G1CollectedHeap::heap()->region_at(region_idx); + assert(!r->rem_set()->is_added_to_cset_group() || + r->rem_set()->cset_group()->card_set() != this, "Should not be sharing a cardset"); + } +#endif + return add_card(card_region, card_within_region, true /* increment_total */); } diff --git a/src/hotspot/share/gc/g1/g1CardSetContainers.cpp b/src/hotspot/share/gc/g1/g1CardSetContainers.cpp index adee0a8e5a947..6ee1dfb2f95a5 100644 --- a/src/hotspot/share/gc/g1/g1CardSetContainers.cpp +++ b/src/hotspot/share/gc/g1/g1CardSetContainers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CardSetContainers.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/g1/g1CardSetMemory.cpp b/src/hotspot/share/gc/g1/g1CardSetMemory.cpp index 28ed698b248e7..6f683e777fb94 100644 --- a/src/hotspot/share/gc/g1/g1CardSetMemory.cpp +++ b/src/hotspot/share/gc/g1/g1CardSetMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CardSetContainers.inline.hpp" #include "gc/g1/g1CardSetMemory.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1CardTable.cpp b/src/hotspot/share/gc/g1/g1CardTable.cpp index fa8203a1f58a6..303b8cda91fa3 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.cpp +++ b/src/hotspot/share/gc/g1/g1CardTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CardTable.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" diff --git a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp index e72e5e8d377ed..40534b9b4c98a 100644 --- a/src/hotspot/share/gc/g1/g1CodeRootSet.cpp +++ b/src/hotspot/share/gc/g1/g1CodeRootSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" - #include "code/codeCache.hpp" #include "code/nmethod.hpp" #include "gc/g1/g1CodeRootSet.hpp" diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 9c9ef7ff9ee6a..6cd4cd07dd838 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/metadataOnStackMark.hpp" #include "classfile/systemDictionary.hpp" @@ -98,6 +97,7 @@ #include "memory/allocation.hpp" #include "memory/heapInspection.hpp" #include "memory/iterator.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspaceUtils.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -178,11 +178,11 @@ G1HeapRegion* G1CollectedHeap::new_region(size_t word_size, // safepoint. assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - log_debug(gc, ergo, heap)("Attempt heap expansion (region allocation request failed). Allocation request: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Attempt heap expansion (region allocation request failed). Allocation request: %zuB", word_size * HeapWordSize); assert(word_size * HeapWordSize < G1HeapRegion::GrainBytes, - "This kind of expansion should never be more than one region. Size: " SIZE_FORMAT, + "This kind of expansion should never be more than one region. Size: %zu", word_size * HeapWordSize); if (expand_single_region(node_index)) { // Given that expand_single_region() succeeded in expanding the heap, and we @@ -334,7 +334,7 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(G1HeapRegion* first_h } size_t G1CollectedHeap::humongous_obj_size_in_regions(size_t word_size) { - assert(is_humongous(word_size), "Object of size " SIZE_FORMAT " must be humongous here", word_size); + assert(is_humongous(word_size), "Object of size %zu must be humongous here", word_size); return align_up(word_size, G1HeapRegion::GrainWords) / G1HeapRegion::GrainWords; } @@ -357,7 +357,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) { humongous_start = _hrm.expand_and_allocate_humongous(obj_regions); if (humongous_start != nullptr) { // We managed to find a region by expanding the heap. - log_debug(gc, ergo, heap)("Heap expansion (humongous allocation request). Allocation request: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Heap expansion (humongous allocation request). Allocation request: %zuB", word_size * HeapWordSize); policy()->record_new_heap_size(num_regions()); } else { @@ -443,7 +443,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size) { return result; } - log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT " words", + log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating %zu words", Thread::current()->name(), word_size); // We can reach here if we were unsuccessful in scheduling a collection (because @@ -461,7 +461,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size) { // Give a warning if we seem to be looping forever. if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { - log_warning(gc, alloc)("%s: Retried allocation %u times for " SIZE_FORMAT " words", + log_warning(gc, alloc)("%s: Retried allocation %u times for %zu words", Thread::current()->name(), try_count, word_size); } } @@ -494,8 +494,8 @@ HeapWord* G1CollectedHeap::alloc_archive_region(size_t word_size, HeapWord* pref MemRegion reserved = _hrm.reserved(); if (reserved.word_size() <= word_size) { - log_info(gc, heap)("Unable to allocate regions as archive heap is too large; size requested = " SIZE_FORMAT - " bytes, heap = " SIZE_FORMAT " bytes", word_size, reserved.word_size()); + log_info(gc, heap)("Unable to allocate regions as archive heap is too large; size requested = %zu" + " bytes, heap = %zu bytes", word_size, reserved.word_size()); return nullptr; } @@ -513,7 +513,7 @@ HeapWord* G1CollectedHeap::alloc_archive_region(size_t word_size, HeapWord* pref } increase_used(word_size * HeapWordSize); if (commits != 0) { - log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: %zuB", G1HeapRegion::GrainWords * HeapWordSize * commits); } @@ -572,7 +572,7 @@ void G1CollectedHeap::dealloc_archive_regions(MemRegion range) { iterate_regions_in_range(range, dealloc_archive_region); if (shrink_count != 0) { - log_debug(gc, ergo, heap)("Attempt heap shrinking (CDS archive regions). Total size: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Attempt heap shrinking (CDS archive regions). Total size: %zuB", G1HeapRegion::GrainWords * HeapWordSize * shrink_count); // Explicit uncommit. uncommit_regions(shrink_count); @@ -672,7 +672,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) { return result; } - log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT "", + log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating %zu", Thread::current()->name(), word_size); // We can reach here if we were unsuccessful in scheduling a collection (because @@ -977,7 +977,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) { _verifier->verify_region_sets_optional(); size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); - log_debug(gc, ergo, heap)("Attempt heap expansion (allocation request failed). Allocation request: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Attempt heap expansion (allocation request failed). Allocation request: %zuB", word_size * HeapWordSize); @@ -994,7 +994,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes, WorkerThreads* pretouch_worker size_t aligned_expand_bytes = os::align_up_vm_page_size(expand_bytes); aligned_expand_bytes = align_up(aligned_expand_bytes, G1HeapRegion::GrainBytes); - log_debug(gc, ergo, heap)("Expand the heap. requested expansion amount: " SIZE_FORMAT "B expansion amount: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Expand the heap. requested expansion amount: %zuB expansion amount: %zuB", expand_bytes, aligned_expand_bytes); if (is_maximal_no_gc()) { @@ -1041,7 +1041,7 @@ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove); size_t shrunk_bytes = num_regions_removed * G1HeapRegion::GrainBytes; - log_debug(gc, ergo, heap)("Shrink the heap. requested shrinking amount: " SIZE_FORMAT "B aligned shrinking amount: " SIZE_FORMAT "B actual amount shrunk: " SIZE_FORMAT "B", + log_debug(gc, ergo, heap)("Shrink the heap. requested shrinking amount: %zuB aligned shrinking amount: %zuB actual amount shrunk: %zuB", shrink_bytes, aligned_shrink_bytes, shrunk_bytes); if (num_regions_removed > 0) { log_debug(gc, heap)("Uncommittable regions after shrink: %u", num_regions_removed); @@ -1159,8 +1159,7 @@ G1CollectedHeap::G1CollectedHeap() : _rem_set(nullptr), _card_set_config(), _card_set_freelist_pool(G1CardSetConfiguration::num_mem_object_types()), - _young_regions_cardset_mm(card_set_config(), card_set_freelist_pool()), - _young_regions_cardset(card_set_config(), &_young_regions_cardset_mm), + _young_regions_cset_group(card_set_config(), &_card_set_freelist_pool, 1u /* group_id */), _cm(nullptr), _cm_thread(nullptr), _cr(nullptr), @@ -1212,8 +1211,21 @@ G1RegionToSpaceMapper* G1CollectedHeap::create_aux_memory_mapper(const char* des size_t size, size_t translation_factor) { size_t preferred_page_size = os::page_size_for_region_unaligned(size, 1); + + // When a page size is given we don't want to mix large + // and normal pages. If the size is not a multiple of the + // page size it will be aligned up to achieve this. + size_t alignment = os::vm_allocation_granularity(); + if (preferred_page_size != os::vm_page_size()) { + alignment = MAX2(preferred_page_size, alignment); + size = align_up(size, alignment); + } + // Allocate a new reserved space, preferring to use large pages. - ReservedSpace rs(size, preferred_page_size); + ReservedSpace rs = MemoryReserver::reserve(size, + alignment, + preferred_page_size); + size_t page_size = rs.page_size(); G1RegionToSpaceMapper* result = G1RegionToSpaceMapper::create_mapper(rs, @@ -1288,7 +1300,7 @@ jint G1CollectedHeap::initialize() { initialize_reserved_region(heap_rs); // Create the barrier set for the entire reserved region. - G1CardTable* ct = new G1CardTable(heap_rs.region()); + G1CardTable* ct = new G1CardTable(_reserved); G1BarrierSet* bs = new G1BarrierSet(ct); bs->initialize(); assert(bs->is_a(BarrierSet::G1BarrierSet), "sanity"); @@ -1440,7 +1452,7 @@ jint G1CollectedHeap::initialize() { G1InitLogger::print(); - FullGCForwarding::initialize(heap_rs.region()); + FullGCForwarding::initialize(_reserved); return JNI_OK; } @@ -1861,7 +1873,7 @@ bool G1CollectedHeap::try_collect(GCCause::Cause cause, return try_collect_concurrently(cause, counters_before.total_collections(), counters_before.old_marking_cycles_started()); - } else if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc + } else if (cause == GCCause::_wb_young_gc DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { // Schedule a standard evacuation pause. We're setting word_size @@ -2103,12 +2115,12 @@ void G1CollectedHeap::print_on(outputStream* st) const { p2i(_hrm.reserved().start()), p2i(_hrm.reserved().end())); st->cr(); - st->print(" region size " SIZE_FORMAT "K, ", G1HeapRegion::GrainBytes / K); + st->print(" region size %zuK, ", G1HeapRegion::GrainBytes / K); uint young_regions = young_regions_count(); - st->print("%u young (" SIZE_FORMAT "K), ", young_regions, + st->print("%u young (%zuK), ", young_regions, (size_t) young_regions * G1HeapRegion::GrainBytes / K); uint survivor_regions = survivor_regions_count(); - st->print("%u survivors (" SIZE_FORMAT "K)", survivor_regions, + st->print("%u survivors (%zuK)", survivor_regions, (size_t) survivor_regions * G1HeapRegion::GrainBytes / K); st->cr(); if (_numa->is_enabled()) { @@ -2703,7 +2715,7 @@ bool G1CollectedHeap::is_old_gc_alloc_region(G1HeapRegion* hr) { void G1CollectedHeap::set_region_short_lived_locked(G1HeapRegion* hr) { _eden.add(hr); _policy->set_region_eden(hr); - hr->install_group_cardset(young_regions_cardset()); + young_regions_cset_group()->add(hr); } #ifdef ASSERT @@ -2760,7 +2772,7 @@ void G1CollectedHeap::increase_used(size_t bytes) { void G1CollectedHeap::decrease_used(size_t bytes) { assert(_summary_bytes_used >= bytes, - "invariant: _summary_bytes_used: " SIZE_FORMAT " should be >= bytes: " SIZE_FORMAT, + "invariant: _summary_bytes_used: %zu should be >= bytes: %zu", _summary_bytes_used, bytes); _summary_bytes_used -= bytes; } @@ -2914,7 +2926,7 @@ G1HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, G1HeapRegio _survivor.add(new_alloc_region); register_new_survivor_region_with_region_attr(new_alloc_region); // Install the group cardset. - new_alloc_region->install_group_cardset(young_regions_cardset()); + young_regions_cset_group()->add(new_alloc_region); } else { new_alloc_region->set_old(); } @@ -3057,6 +3069,8 @@ void G1CollectedHeap::finish_codecache_marking_cycle() { CodeCache::arm_all_nmethods(); } -void G1CollectedHeap::prepare_group_cardsets_for_scan () { - _young_regions_cardset.reset_table_scanner_for_groups(); +void G1CollectedHeap::prepare_group_cardsets_for_scan() { + young_regions_cardset()->reset_table_scanner_for_groups(); + + collection_set()->prepare_groups_for_scan(); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 1b840392769cd..16d73537d5c9f 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -361,8 +361,8 @@ class G1CollectedHeap : public CollectedHeap { do { \ size_t cur_used_bytes = g1h->used(); \ size_t recal_used_bytes = g1h->recalculate_used(); \ - assert(cur_used_bytes == recal_used_bytes, "Used(" SIZE_FORMAT ") is not" \ - " same as recalculated used(" SIZE_FORMAT ").", \ + assert(cur_used_bytes == recal_used_bytes, "Used(%zu) is not" \ + " same as recalculated used(%zu).", \ cur_used_bytes, recal_used_bytes); \ } while (0) #else @@ -781,15 +781,15 @@ class G1CollectedHeap : public CollectedHeap { G1MonotonicArenaFreePool _card_set_freelist_pool; // Group cardsets - G1CardSetMemoryManager _young_regions_cardset_mm; - G1CardSet _young_regions_cardset; + G1CSetCandidateGroup _young_regions_cset_group; public: G1CardSetConfiguration* card_set_config() { return &_card_set_config; } - G1CardSet* young_regions_cardset() { return &_young_regions_cardset; }; + G1CSetCandidateGroup* young_regions_cset_group() { return &_young_regions_cset_group; } + G1CardSet* young_regions_cardset() { return _young_regions_cset_group.card_set(); }; - G1CardSetMemoryManager* young_regions_card_set_mm() { return &_young_regions_cardset_mm; } + G1MonotonicArenaMemoryStats young_regions_card_set_memory_stats() { return _young_regions_cset_group.card_set_memory_stats(); } void prepare_group_cardsets_for_scan(); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index 63eceb4a5baa5..943c68b74c77a 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -225,7 +225,6 @@ void G1CollectedHeap::register_region_with_region_attr(G1HeapRegion* r) { } void G1CollectedHeap::register_old_region_with_region_attr(G1HeapRegion* r) { - assert(!r->has_pinned_objects(), "must be"); assert(r->rem_set()->is_complete(), "must be"); _region_attr.set_in_old(r->hrm_index(), true); _rem_set->exclude_region_from_scan(r->hrm_index()); diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.cpp b/src/hotspot/share/gc/g1/g1CollectionSet.cpp index ec90fd377503d..075951ab07ca3 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" -#include "gc/g1/g1CollectionSet.hpp" +#include "gc/g1/g1CollectionSet.inline.hpp" #include "gc/g1/g1CollectionSetCandidates.inline.hpp" #include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1HeapRegion.inline.hpp" @@ -54,10 +53,13 @@ G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) : _collection_set_regions(nullptr), _collection_set_cur_length(0), _collection_set_max_length(0), + _collection_set_groups(), + _selected_groups_cur_length(0), + _selected_groups_inc_part_start(0), _eden_region_length(0), _survivor_region_length(0), _initial_old_region_length(0), - _optional_old_regions(), + _optional_groups(), _inc_build_state(Inactive), _inc_part_start(0) { } @@ -78,7 +80,8 @@ void G1CollectionSet::init_region_lengths(uint eden_cset_region_length, "Young region length %u should match collection set length %u", young_region_length(), _collection_set_cur_length); _initial_old_region_length = 0; - _optional_old_regions.clear(); + assert(_optional_groups.length() == 0, "Should not have any optional groups yet"); + _optional_groups.clear(); } void G1CollectionSet::initialize(uint max_region_length) { @@ -92,7 +95,10 @@ void G1CollectionSet::initialize(uint max_region_length) { void G1CollectionSet::abandon_all_candidates() { _candidates.clear(); _initial_old_region_length = 0; - _optional_old_regions.clear(); +} + +void G1CollectionSet::prepare_groups_for_scan () { + collection_set_groups()->prepare_for_scan(); } void G1CollectionSet::add_old_region(G1HeapRegion* hr) { @@ -102,6 +108,8 @@ void G1CollectionSet::add_old_region(G1HeapRegion* hr) { "Precondition, actively building cset or adding optional later on"); assert(hr->is_old(), "the region should be old"); + assert(!hr->rem_set()->is_added_to_cset_group(), "Should have already uninstalled group remset"); + assert(!hr->in_collection_set(), "should not already be in the collection set"); _g1h->register_old_region_with_region_attr(hr); @@ -127,6 +135,7 @@ void G1CollectionSet::finalize_incremental_building() { void G1CollectionSet::clear() { assert_at_safepoint_on_vm_thread(); _collection_set_cur_length = 0; + _collection_set_groups.clear(); } void G1CollectionSet::iterate(G1HeapRegionClosure* cl) const { @@ -152,10 +161,10 @@ void G1CollectionSet::par_iterate(G1HeapRegionClosure* cl, void G1CollectionSet::iterate_optional(G1HeapRegionClosure* cl) const { assert_at_safepoint(); - for (G1HeapRegion* r : _optional_old_regions) { + _optional_groups.iterate([&] (G1HeapRegion* r) { bool result = cl->do_heap_region(r); guarantee(!result, "Must not cancel iteration"); - } + }); } void G1CollectionSet::iterate_incremental_part_from(G1HeapRegionClosure* cl, @@ -284,7 +293,7 @@ double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1Survi size_t pending_cards = _policy->pending_cards_at_gc_start(); - log_trace(gc, ergo, cset)("Start choosing CSet. Pending cards: " SIZE_FORMAT " target pause time: %1.2fms", + log_trace(gc, ergo, cset)("Start choosing CSet. Pending cards: %zu target pause time: %1.2fms", pending_cards, target_pause_time_ms); // The young list is laid with the survivor regions from the previous @@ -321,59 +330,40 @@ static int compare_region_idx(const uint a, const uint b) { return static_cast(a-b); } -// The current mechanism skips evacuation of pinned old regions like g1 does for -// young regions: -// * evacuating pinned marking collection set candidate regions (available during mixed -// gc) like young regions would not result in any memory gain but only take additional -// time away from processing regions that would actually result in memory being freed. -// To advance mixed gc progress (we committed to evacuate all marking collection set -// candidate regions within the maximum number of mixed gcs in the phase), move them -// to the optional collection set candidates to reclaim them asap as time permits. -// * evacuating out retained collection set candidates would also just take up time with -// no actual space freed in old gen. Better to concentrate on others. -// Retained collection set candidates are aged out, ie. made to regular old regions -// without remembered sets after a few attempts to save computation costs of keeping -// them candidates for very long living pinned regions. +// The current mechanism for evacuating pinned old regions is as below: +// * pinned regions in the marking collection set candidate list (available during mixed gc) are evacuated like +// pinned young regions to avoid the complexity of dealing with pinned regions that are part of a +// collection group sharing a single cardset. These regions will be partially evacuated and added to the +// retained collection set by the evacuation failure handling mechanism. +// * evacuating pinned regions out of retained collection set candidates would also just take up time +// with no actual space freed in old gen. Better to concentrate on others. So we skip over pinned +// regions in retained collection set candidates. Retained collection set candidates are aged out, ie. +// made to regular old regions without remembered sets after a few attempts to save computation costs +// of keeping them candidates for very long living pinned regions. void G1CollectionSet::finalize_old_part(double time_remaining_ms) { double non_young_start_time_sec = os::elapsedTime(); + _selected_groups_cur_length = 0; + _selected_groups_inc_part_start = 0; + if (!candidates()->is_empty()) { candidates()->verify(); - G1CollectionCandidateRegionList initial_old_regions; - assert(_optional_old_regions.length() == 0, "must be"); - G1CollectionCandidateRegionList pinned_marking_regions; - G1CollectionCandidateRegionList pinned_retained_regions; - if (collector_state()->in_mixed_phase()) { - time_remaining_ms = select_candidates_from_marking(time_remaining_ms, - &initial_old_regions, - &pinned_marking_regions); + time_remaining_ms = select_candidates_from_marking(time_remaining_ms); } else { log_debug(gc, ergo, cset)("Do not add marking candidates to collection set due to pause type."); } - select_candidates_from_retained(time_remaining_ms, - &initial_old_regions, - &pinned_retained_regions); - - // Move initially selected old regions to collection set directly. - move_candidates_to_collection_set(&initial_old_regions); - // Only prepare selected optional regions for now. - prepare_optional_regions(&_optional_old_regions); - // Move pinned marking regions we came across to retained candidates so that - // there is progress in the mixed gc phase. - move_pinned_marking_to_retained(&pinned_marking_regions); - // Drop pinned retained regions to make progress with retained regions. Regions - // in that list must have been pinned for at least G1NumCollectionsKeepPinned - // GCs and hence are considered "long lived". - drop_pinned_retained_regions(&pinned_retained_regions); - + if (candidates()->retained_groups().num_regions() > 0) { + select_candidates_from_retained(time_remaining_ms); + } candidates()->verify(); } else { log_debug(gc, ergo, cset)("No candidates to reclaim."); } + _selected_groups_cur_length = collection_set_groups()->length(); stop_incremental_building(); double non_young_end_time_sec = os::elapsedTime(); @@ -382,75 +372,62 @@ void G1CollectionSet::finalize_old_part(double time_remaining_ms) { QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx); } -void G1CollectionSet::move_candidates_to_collection_set(G1CollectionCandidateRegionList* regions) { - for (G1HeapRegion* r : *regions) { - _g1h->clear_region_attr(r); - add_old_region(r); - } - candidates()->remove(regions); -} - static void print_finish_message(const char* reason, bool from_marking) { log_debug(gc, ergo, cset)("Finish adding %s candidates to collection set (%s).", from_marking ? "marking" : "retained", reason); } -double G1CollectionSet::select_candidates_from_marking(double time_remaining_ms, - G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* pinned_old_regions) { +double G1CollectionSet::select_candidates_from_marking(double time_remaining_ms) { uint num_expensive_regions = 0; + uint num_inital_regions = 0; + uint num_initial_groups = 0; + uint num_optional_regions = 0; - uint num_initial_regions_selected = 0; - uint num_optional_regions_selected = 0; - uint num_pinned_regions = 0; + assert(_optional_groups.num_regions() == 0, "Optional regions should not already be selected"); double predicted_initial_time_ms = 0.0; double predicted_optional_time_ms = 0.0; double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction(); - const uint min_old_cset_length = _policy->calc_min_old_cset_length(candidates()->last_marking_candidates_length()); - const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length()); - const uint max_optional_regions = max_old_cset_length - min_old_cset_length; + uint min_old_cset_length = _policy->calc_min_old_cset_length(candidates()->last_marking_candidates_length()); + uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length()); bool check_time_remaining = _policy->use_adaptive_young_list_length(); - G1CollectionCandidateList* marking_list = &candidates()->marking_regions(); - assert(marking_list != nullptr, "must be"); + G1CSetCandidateGroupList* from_marking_groups = &candidates()->from_marking_groups(); log_debug(gc, ergo, cset)("Start adding marking candidates to collection set. " - "Min %u regions, max %u regions, available %u regions" + "Min %u regions, max %u regions, available %u regions (%u groups), " "time remaining %1.2fms, optional threshold %1.2fms", - min_old_cset_length, max_old_cset_length, marking_list->length(), time_remaining_ms, optional_threshold_ms); + min_old_cset_length, max_old_cset_length, from_marking_groups->num_regions(), from_marking_groups->length(), + time_remaining_ms, optional_threshold_ms); + + G1CSetCandidateGroupList selected_groups; - G1CollectionCandidateListIterator iter = marking_list->begin(); - for (; iter != marking_list->end(); ++iter) { - if (num_initial_regions_selected + num_optional_regions_selected >= max_old_cset_length) { + for (G1CSetCandidateGroup* group : *from_marking_groups) { + if (num_inital_regions + num_optional_regions >= max_old_cset_length) { // Added maximum number of old regions to the CSet. print_finish_message("Maximum number of regions reached", true); break; } - G1HeapRegion* hr = (*iter)->_r; - // Skip evacuating pinned marking regions because we are not getting any free - // space from them (and we expect to get free space from marking candidates). - // Also prepare to move them to retained regions to be evacuated optionally later - // to not impact the mixed phase too much. - if (hr->has_pinned_objects()) { - num_pinned_regions++; - (*iter)->update_num_unreclaimed(); - log_trace(gc, ergo, cset)("Marking candidate %u can not be reclaimed currently. Skipping.", hr->hrm_index()); - pinned_old_regions->append(hr); - continue; - } - double predicted_time_ms = _policy->predict_region_total_time_ms(hr, false); + + double predicted_time_ms = group->predict_group_total_time_ms(); + time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); // Add regions to old set until we reach the minimum amount - if (initial_old_regions->length() < min_old_cset_length) { - initial_old_regions->append(hr); - num_initial_regions_selected++; + if (num_inital_regions < min_old_cset_length) { + + num_initial_groups++; + + add_group_to_collection_set(group); + selected_groups.append(group); + + num_inital_regions += group->length(); + predicted_initial_time_ms += predicted_time_ms; // Record the number of regions added with no time remaining if (time_remaining_ms == 0.0) { - num_expensive_regions++; + num_expensive_regions += group->length(); } } else if (!check_time_remaining) { // In the non-auto-tuning case, we'll finish adding regions @@ -460,22 +437,34 @@ double G1CollectionSet::select_candidates_from_marking(double time_remaining_ms, } else { // Keep adding regions to old set until we reach the optional threshold if (time_remaining_ms > optional_threshold_ms) { + num_initial_groups++; + + add_group_to_collection_set(group); + selected_groups.append(group); + + num_inital_regions += group->length(); + predicted_initial_time_ms += predicted_time_ms; - initial_old_regions->append(hr); - num_initial_regions_selected++; + } else if (time_remaining_ms > 0) { // Keep adding optional regions until time is up. - assert(_optional_old_regions.length() < max_optional_regions, "Should not be possible."); + _optional_groups.append(group); + prepare_optional_group(group, num_optional_regions); + num_optional_regions += group->length(); predicted_optional_time_ms += predicted_time_ms; - _optional_old_regions.append(hr); - num_optional_regions_selected++; } else { print_finish_message("Predicted time too high", true); break; } } } - if (iter == marking_list->end()) { + + // Remove selected groups from list of candidate groups. + if (num_initial_groups > 0) { + candidates()->remove(&selected_groups); + } + + if (from_marking_groups->length() == 0) { log_debug(gc, ergo, cset)("Marking candidates exhausted."); } @@ -484,22 +473,21 @@ double G1CollectionSet::select_candidates_from_marking(double time_remaining_ms, num_expensive_regions); } - log_debug(gc, ergo, cset)("Finish adding marking candidates to collection set. Initial: %u, optional: %u, pinned: %u, " + log_debug(gc, ergo, cset)("Finish adding marking candidates to collection set. Initial: %u regions (%u groups), optional: %u regions (%u groups), " "predicted initial time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2fms", - num_initial_regions_selected, num_optional_regions_selected, num_pinned_regions, + selected_groups.num_regions(), selected_groups.length(), _optional_groups.num_regions(), _optional_groups.length(), predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms); - assert(initial_old_regions->length() == num_initial_regions_selected, "must be"); - assert(_optional_old_regions.length() == num_optional_regions_selected, "must be"); + assert(selected_groups.num_regions() == num_inital_regions, "must be"); + assert(_optional_groups.num_regions() == num_optional_regions, "must be"); return time_remaining_ms; } -void G1CollectionSet::select_candidates_from_retained(double time_remaining_ms, - G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* pinned_old_regions) { - uint num_initial_regions_selected = 0; - uint num_optional_regions_selected = 0; - uint num_expensive_regions_selected = 0; +void G1CollectionSet::select_candidates_from_retained(double time_remaining_ms) { + uint num_initial_regions = 0; + uint prev_num_optional_regions = _optional_groups.num_regions(); + uint num_optional_regions = prev_num_optional_regions; + uint num_expensive_regions = 0; uint num_pinned_regions = 0; double predicted_initial_time_ms = 0.0; @@ -514,17 +502,27 @@ void G1CollectionSet::select_candidates_from_retained(double time_remaining_ms, double optional_time_remaining_ms = _policy->max_time_for_retaining(); time_remaining_ms = MIN2(time_remaining_ms, optional_time_remaining_ms); - G1CollectionCandidateList* retained_list = &candidates()->retained_regions(); + G1CSetCandidateGroupList* retained_groups = &candidates()->retained_groups(); log_debug(gc, ergo, cset)("Start adding retained candidates to collection set. " - "Min %u regions, available %u, " + "Min %u regions, available %u regions (%u groups), " "time remaining %1.2fms, optional remaining %1.2fms", - min_regions, retained_list->length(), time_remaining_ms, optional_time_remaining_ms); + min_regions, retained_groups->num_regions(), retained_groups->length(), + time_remaining_ms, optional_time_remaining_ms); + + G1CSetCandidateGroupList remove_from_retained; + G1CSetCandidateGroupList groups_to_abandon; + + for (G1CSetCandidateGroup* group : *retained_groups) { + assert(group->length() == 1, "Retained groups should have only 1 region"); + + double predicted_time_ms = group->predict_group_total_time_ms(); - for (G1CollectionSetCandidateInfo* ci : *retained_list) { - G1HeapRegion* r = ci->_r; - double predicted_time_ms = _policy->predict_region_total_time_ms(r, collector_state()->in_young_only_phase()); bool fits_in_remaining_time = predicted_time_ms <= time_remaining_ms; + + G1CollectionSetCandidateInfo* ci = group->at(0); // We only have one region in the group. + G1HeapRegion* r = ci->_r; + // If we can't reclaim that region ignore it for now. if (r->has_pinned_objects()) { num_pinned_regions++; @@ -532,22 +530,32 @@ void G1CollectionSet::select_candidates_from_retained(double time_remaining_ms, log_trace(gc, ergo, cset)("Retained candidate %u can not be reclaimed currently. Skipping.", r->hrm_index()); } else { log_trace(gc, ergo, cset)("Retained candidate %u can not be reclaimed currently. Dropping.", r->hrm_index()); - pinned_old_regions->append(r); + // Drop pinned retained regions to make progress with retained regions. Regions + // in that list must have been pinned for at least G1NumCollectionsKeepPinned + // GCs and hence are considered "long lived". + _g1h->clear_region_attr(r); + groups_to_abandon.append(group); + remove_from_retained.append(group); } continue; } - if (fits_in_remaining_time || (num_expensive_regions_selected < min_regions)) { + if (fits_in_remaining_time || (num_expensive_regions < min_regions)) { predicted_initial_time_ms += predicted_time_ms; if (!fits_in_remaining_time) { - num_expensive_regions_selected++; + num_expensive_regions++; } - initial_old_regions->append(r); - num_initial_regions_selected++; + + add_group_to_collection_set(group); + remove_from_retained.append(group); + + num_initial_regions += group->length(); } else if (predicted_time_ms <= optional_time_remaining_ms) { + // Prepare optional collection region. + _optional_groups.append(group); + prepare_optional_group(group, num_optional_regions); + num_optional_regions += group->length(); predicted_optional_time_ms += predicted_time_ms; - _optional_old_regions.append(r); - num_optional_regions_selected++; } else { // Fits neither initial nor optional time limit. Exit. break; @@ -556,85 +564,109 @@ void G1CollectionSet::select_candidates_from_retained(double time_remaining_ms, optional_time_remaining_ms = MAX2(0.0, optional_time_remaining_ms - predicted_time_ms); } - uint num_regions_selected = num_initial_regions_selected + num_optional_regions_selected; - if (num_regions_selected == retained_list->length()) { + if (num_initial_regions == retained_groups->num_regions()) { log_debug(gc, ergo, cset)("Retained candidates exhausted."); } - if (num_expensive_regions_selected > 0) { + + if (num_expensive_regions > 0) { log_debug(gc, ergo, cset)("Added %u retained candidates to collection set although the predicted time was too high.", - num_expensive_regions_selected); + num_expensive_regions); } + // Remove groups from retained and also do some bookkeeping on CandidateOrigin + // for the regions in these groups. + candidates()->remove(&remove_from_retained); + + groups_to_abandon.clear(true /* uninstall_group_cardset */); + + assert(num_optional_regions >= prev_num_optional_regions, "Sanity"); + uint selected_optional_regions = num_optional_regions - prev_num_optional_regions; + log_debug(gc, ergo, cset)("Finish adding retained candidates to collection set. Initial: %u, optional: %u, pinned: %u, " "predicted initial time: %1.2fms, predicted optional time: %1.2fms, " "time remaining: %1.2fms optional time remaining %1.2fms", - num_initial_regions_selected, num_optional_regions_selected, num_pinned_regions, + num_initial_regions, selected_optional_regions, num_pinned_regions, predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms, optional_time_remaining_ms); } -void G1CollectionSet::select_candidates_from_optional_regions(double time_remaining_ms, - G1CollectionCandidateRegionList* selected_regions) { - assert(optional_region_length() > 0, +double G1CollectionSet::select_candidates_from_optional_groups(double time_remaining_ms, uint& num_regions_selected) { + + assert(_optional_groups.num_regions() > 0, "Should only be called when there are optional regions"); + uint num_groups_selected = 0; double total_prediction_ms = 0.0; + G1CSetCandidateGroupList selected; + for (G1CSetCandidateGroup* group : _optional_groups) { + double predicted_time_ms = group->predict_group_total_time_ms(); - for (G1HeapRegion* r : _optional_old_regions) { - double prediction_ms = _policy->predict_region_total_time_ms(r, false); - - if (prediction_ms > time_remaining_ms) { - log_debug(gc, ergo, cset)("Prediction %.3fms for region %u does not fit remaining time: %.3fms.", - prediction_ms, r->hrm_index(), time_remaining_ms); + if (predicted_time_ms > time_remaining_ms) { + log_debug(gc, ergo, cset)("Prediction %.3fms for group with %u regions does not fit remaining time: %.3fms.", + predicted_time_ms, group->length(), time_remaining_ms); break; } - // This region will be included in the next optional evacuation. - total_prediction_ms += prediction_ms; - time_remaining_ms -= prediction_ms; + total_prediction_ms += predicted_time_ms; + time_remaining_ms -= predicted_time_ms; - selected_regions->append(r); + num_regions_selected += group->length(); + num_groups_selected++; + + add_group_to_collection_set(group); + selected.append(group); } + log_debug(gc, ergo, cset) ("Completed with groups, selected %u", num_regions_selected); + // Remove selected groups from candidate list. + if (num_groups_selected > 0) { + _optional_groups.remove(&selected); + candidates()->remove(&selected); + } + return total_prediction_ms; +} + +uint G1CollectionSet::select_optional_collection_set_regions(double time_remaining_ms) { + uint optional_regions_count = num_optional_regions(); + assert(optional_regions_count > 0, + "Should only be called when there are optional regions"); + + uint num_regions_selected = 0; + + double total_prediction_ms = select_candidates_from_optional_groups(time_remaining_ms, num_regions_selected); + + time_remaining_ms -= total_prediction_ms; + log_debug(gc, ergo, cset)("Prepared %u regions out of %u for optional evacuation. Total predicted time: %.3fms", - selected_regions->length(), _optional_old_regions.length(), total_prediction_ms); + num_regions_selected, optional_regions_count, total_prediction_ms); + return num_regions_selected; } -void G1CollectionSet::prepare_optional_regions(G1CollectionCandidateRegionList* regions){ - uint cur_index = 0; - for (G1HeapRegion* r : *regions) { +void G1CollectionSet::prepare_optional_group(G1CSetCandidateGroup* gr, uint cur_index) { + for (G1CollectionSetCandidateInfo ci : *gr) { + G1HeapRegion* r = ci._r; + assert(r->is_old(), "the region should be old"); assert(!r->in_collection_set(), "should not already be in the CSet"); _g1h->register_optional_region_with_region_attr(r); - r->set_index_in_opt_cset(cur_index++); } } -void G1CollectionSet::move_pinned_marking_to_retained(G1CollectionCandidateRegionList* regions) { - if (regions->length() == 0) { - return; - } - candidates()->remove(regions); - - for (G1HeapRegion* r : *regions) { - assert(r->has_pinned_objects(), "must be pinned"); - assert(r->rem_set()->is_complete(), "must be complete"); - candidates()->add_retained_region_unsorted(r); +void G1CollectionSet::add_group_to_collection_set(G1CSetCandidateGroup* gr) { + for (G1CollectionSetCandidateInfo ci : *gr) { + G1HeapRegion* r = ci._r; + r->uninstall_cset_group(); + assert(r->rem_set()->is_complete(), "must be"); + add_region_to_collection_set(r); } - candidates()->sort_by_efficiency(); + _collection_set_groups.append(gr); } -void G1CollectionSet::drop_pinned_retained_regions(G1CollectionCandidateRegionList* regions) { - if (regions->length() == 0) { - return; - } - candidates()->remove(regions); - - // We can now drop these region's remembered sets. - for (G1HeapRegion* r : *regions) { - r->rem_set()->clear(true /* only_cardset */); - } +void G1CollectionSet::add_region_to_collection_set(G1HeapRegion* r) { + _g1h->clear_region_attr(r); + assert(r->rem_set()->is_complete(), "Remset for region %u complete", r->hrm_index()); + add_old_region(r); } void G1CollectionSet::finalize_initial_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor) { @@ -645,31 +677,31 @@ void G1CollectionSet::finalize_initial_collection_set(double target_pause_time_m bool G1CollectionSet::finalize_optional_for_evacuation(double remaining_pause_time) { update_incremental_marker(); - G1CollectionCandidateRegionList selected_regions; - select_candidates_from_optional_regions(remaining_pause_time, - &selected_regions); - - move_candidates_to_collection_set(&selected_regions); - - _optional_old_regions.remove_prefix(&selected_regions); + uint num_regions_selected = select_optional_collection_set_regions(remaining_pause_time); + _selected_groups_cur_length = collection_set_groups()->length(); stop_incremental_building(); _g1h->verify_region_attr_remset_is_tracked(); - return selected_regions.length() > 0; + return num_regions_selected > 0; } void G1CollectionSet::abandon_optional_collection_set(G1ParScanThreadStateSet* pss) { - for (G1HeapRegion* r : _optional_old_regions) { - pss->record_unused_optional_region(r); - // Clear collection set marker and make sure that the remembered set information - // is correct as we still need it later. - _g1h->clear_region_attr(r); - _g1h->register_region_with_region_attr(r); - r->clear_index_in_opt_cset(); + if (_optional_groups.length() > 0) { + auto reset = [&] (G1HeapRegion* r) { + pss->record_unused_optional_region(r); + // Clear collection set marker and make sure that the remembered set information + // is correct as we still need it later. + _g1h->clear_region_attr(r); + _g1h->register_region_with_region_attr(r); + r->clear_index_in_opt_cset(); + }; + + _optional_groups.iterate(reset); + // Remove groups from list without deleting the groups or clearing the associated cardsets. + _optional_groups.remove_selected(_optional_groups.length(), _optional_groups.num_regions()); } - _optional_old_regions.clear(); _g1h->verify_region_attr_remset_is_tracked(); } diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.hpp b/src/hotspot/share/gc/g1/g1CollectionSet.hpp index 5280ba7d0fd6c..c703e13a056f4 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSet.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSet.hpp @@ -146,13 +146,21 @@ class G1CollectionSet { volatile uint _collection_set_cur_length; uint _collection_set_max_length; + // Old gen groups selected for evacuation. + G1CSetCandidateGroupList _collection_set_groups; + + // Groups are added to the collection set in increments when performing optional evacuations. + // We use the value below to track these increments. + uint _selected_groups_cur_length; + uint _selected_groups_inc_part_start; + uint _eden_region_length; uint _survivor_region_length; uint _initial_old_region_length; // When doing mixed collections we can add old regions to the collection set, which // will be collected only if there is enough time. We call these optional (old) regions. - G1CollectionCandidateRegionList _optional_old_regions; + G1CSetCandidateGroupList _optional_groups; enum CSetBuildType { Active, // We are actively building the collection set @@ -173,16 +181,20 @@ class G1CollectionSet { // Add the given old region to the head of the current collection set. void add_old_region(G1HeapRegion* hr); - void move_candidates_to_collection_set(G1CollectionCandidateRegionList* regions); - // Prepares old regions in the given set for optional collection later. Does not - // add the region to collection set yet. - void prepare_optional_regions(G1CollectionCandidateRegionList* regions); - // Moves given old regions from the marking candidates to the retained candidates. - // This makes sure that marking candidates will not remain there to unnecessarily - // prolong the mixed phase. - void move_pinned_marking_to_retained(G1CollectionCandidateRegionList* regions); - // Removes the given list of regions from the retained candidates. - void drop_pinned_retained_regions(G1CollectionCandidateRegionList* regions); + void prepare_optional_group(G1CSetCandidateGroup* gr, uint cur_index); + + void add_group_to_collection_set(G1CSetCandidateGroup* gr); + + void add_region_to_collection_set(G1HeapRegion* r); + + double select_candidates_from_marking(double time_remaining_ms); + + void select_candidates_from_retained(double time_remaining_ms); + + // Select regions for evacuation from the optional candidates given the remaining time + // and return the number of actually selected regions. + uint select_optional_collection_set_regions(double time_remaining_ms); + double select_candidates_from_optional_groups(double time_remaining_ms, uint& num_regions_selected); // Finalize the young part of the initial collection set. Relabel survivor regions // as Eden and calculate a prediction on how long the evacuation of all young regions @@ -196,22 +208,6 @@ class G1CollectionSet { // and retained collection set candidates. void finalize_old_part(double time_remaining_ms); - // Calculate and fill in the initial, optional and pinned old gen candidate regions from - // the given candidate list and the remaining time. - // Returns the remaining time. - double select_candidates_from_marking(double time_remaining_ms, - G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* pinned_old_regions); - - void select_candidates_from_retained(double time_remaining_ms, - G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* pinned_old_regions); - - // Calculate the number of optional regions from the given collection set candidates, - // the remaining time and the maximum number of these regions. - void select_candidates_from_optional_regions(double time_remaining_ms, - G1CollectionCandidateRegionList* selected); - // Iterate the part of the collection set given by the offset and length applying the given // G1HeapRegionClosure. The worker_id will determine where in the part to start the iteration // to allow for more efficient parallel iteration. @@ -232,6 +228,11 @@ class G1CollectionSet { G1CollectionSetCandidates* candidates() { return &_candidates; } const G1CollectionSetCandidates* candidates() const { return &_candidates; } + G1CSetCandidateGroupList* collection_set_groups() { return &_collection_set_groups; } + const G1CSetCandidateGroupList* collection_set_groups() const { return &_collection_set_groups; } + + void prepare_groups_for_scan(); + void init_region_lengths(uint eden_cset_region_length, uint survivor_cset_region_length); @@ -243,9 +244,12 @@ class G1CollectionSet { uint eden_region_length() const { return _eden_region_length; } uint survivor_region_length() const { return _survivor_region_length; } uint initial_old_region_length() const { return _initial_old_region_length; } - uint optional_region_length() const { return _optional_old_regions.length(); } + uint num_optional_regions() const { return _optional_groups.num_regions(); } + + bool only_contains_young_regions() const { return (initial_old_region_length() + num_optional_regions()) == 0; } - bool only_contains_young_regions() const { return (initial_old_region_length() + optional_region_length()) == 0; } + template + inline void merge_cardsets_for_collection_groups(CardOrRangeVisitor& cl, uint worker_id, uint num_workers); // Reset the contents of the collection set. void clear(); @@ -255,7 +259,11 @@ class G1CollectionSet { // Initialize incremental collection set info. void start_incremental_building(); // Start a new collection set increment. - void update_incremental_marker() { _inc_build_state = Active; _inc_part_start = _collection_set_cur_length; } + void update_incremental_marker() { + _inc_build_state = Active; + _inc_part_start = _collection_set_cur_length; + _selected_groups_inc_part_start = _selected_groups_cur_length; + } // Stop adding regions to the current collection set increment. void stop_incremental_building() { _inc_build_state = Inactive; } @@ -268,6 +276,8 @@ class G1CollectionSet { // Returns the length of the whole current collection set in number of regions size_t cur_length() const { return _collection_set_cur_length; } + uint collection_groups_increment_length() const { return _selected_groups_cur_length - _selected_groups_inc_part_start; } + // Iterate over the entire collection set (all increments calculated so far), applying // the given G1HeapRegionClosure on all of them. void iterate(G1HeapRegionClosure* cl) const; diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.inline.hpp b/src/hotspot/share/gc/g1/g1CollectionSet.inline.hpp new file mode 100644 index 0000000000000..f295eff3edd2b --- /dev/null +++ b/src/hotspot/share/gc/g1/g1CollectionSet.inline.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_G1_G1COLLECTIONSET_INLINE_HPP +#define SHARE_GC_G1_G1COLLECTIONSET_INLINE_HPP + +#include "gc/g1/g1CollectionSet.hpp" +#include "gc/g1/g1HeapRegionRemSet.hpp" + +template +inline void G1CollectionSet::merge_cardsets_for_collection_groups(CardOrRangeVisitor& cl, uint worker_id, uint num_workers) { + uint length = collection_groups_increment_length(); + uint offset = _selected_groups_inc_part_start; + if (length == 0) { + return; + } + + uint start_pos = (worker_id * length) / num_workers; + uint cur_pos = start_pos; + uint count = 0; + do { + G1HeapRegionRemSet::iterate_for_merge(collection_set_groups()->at(offset + cur_pos)->card_set(), cl); + cur_pos++; + count++; + if (cur_pos == length) { + cur_pos = 0; + } + } while (cur_pos != start_pos); +} +#endif /* SHARE_GC_G1_G1COLLECTIONSET_INLINE_HPP */ diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp index 05e6457c095a5..7784eb645d36a 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,83 +22,108 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectionSetCandidates.inline.hpp" #include "gc/g1/g1CollectionSetChooser.hpp" #include "gc/g1/g1HeapRegion.inline.hpp" -#include "utilities/bitMap.inline.hpp" #include "utilities/growableArray.hpp" -G1CollectionCandidateList::G1CollectionCandidateList() : _candidates(2, mtGC) { } +uint G1CSetCandidateGroup::_next_group_id = 2; -void G1CollectionCandidateList::set(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos) { - assert(_candidates.is_empty(), "must be"); +G1CSetCandidateGroup::G1CSetCandidateGroup(G1CardSetConfiguration* config, G1MonotonicArenaFreePool* card_set_freelist_pool, uint group_id) : + _candidates(4, mtGCCardSet), + _card_set_mm(config, card_set_freelist_pool), + _card_set(config, &_card_set_mm), + _reclaimable_bytes(size_t(0)), + _gc_efficiency(0.0), + _group_id(group_id) +{ } - GrowableArrayFromArray a(candidate_infos, (int)num_infos); - _candidates.appendAll(&a); -} +G1CSetCandidateGroup::G1CSetCandidateGroup() : + G1CSetCandidateGroup(G1CollectedHeap::heap()->card_set_config(), G1CollectedHeap::heap()->card_set_freelist_pool(), _next_group_id++) +{ } -void G1CollectionCandidateList::append_unsorted(G1HeapRegion* r) { - G1CollectionSetCandidateInfo c(r, r->calc_gc_efficiency()); - _candidates.append(c); +void G1CSetCandidateGroup::add(G1HeapRegion* hr) { + G1CollectionSetCandidateInfo c(hr); + add(c); } -void G1CollectionCandidateList::sort_by_efficiency() { - _candidates.sort(compare_gc_efficiency); +void G1CSetCandidateGroup::add(G1CollectionSetCandidateInfo& hr_info) { + G1HeapRegion* hr = hr_info._r; + _candidates.append(hr_info); + hr->install_cset_group(this); } -void G1CollectionCandidateList::remove(G1CollectionCandidateRegionList* other) { - guarantee((uint)_candidates.length() >= other->length(), "must be"); - - if (other->length() == 0) { - // Nothing to remove or nothing in the original set. - return; +void G1CSetCandidateGroup::calculate_efficiency() { + _reclaimable_bytes = 0; + uint num_candidates = _candidates.length(); + for (uint i = 0; i < num_candidates; i++) { + G1HeapRegion* hr = region_at(i); + _reclaimable_bytes += hr->reclaimable_bytes(); } + _gc_efficiency = _reclaimable_bytes / predict_group_total_time_ms(); +} - // Create a list from scratch, copying over the elements from the candidate - // list not in the other list. Finally deallocate and overwrite the old list. - int new_length = _candidates.length() - other->length(); - GrowableArray new_list(new_length, mtGC); +size_t G1CSetCandidateGroup::liveness() const { + size_t capacity = length() * G1HeapRegion::GrainBytes; - uint other_idx = 0; + return (size_t) ceil(((capacity - _reclaimable_bytes) * 100.0) / capacity); +} - for (uint candidate_idx = 0; candidate_idx < (uint)_candidates.length(); candidate_idx++) { - if ((other_idx == other->length()) || _candidates.at(candidate_idx)._r != other->at(other_idx)) { - new_list.append(_candidates.at(candidate_idx)); - } else { - other_idx++; +void G1CSetCandidateGroup::clear(bool uninstall_group_cardset) { + if (uninstall_group_cardset) { + for (G1CollectionSetCandidateInfo ci : _candidates) { + G1HeapRegion* r = ci._r; + r->uninstall_cset_group(); + r->rem_set()->clear(true /* only_cardset */); } } - _candidates.swap(&new_list); - - verify(); - assert(_candidates.length() == new_length, "must be %u %u", _candidates.length(), new_length); -} - -void G1CollectionCandidateList::clear() { + _card_set.clear(); _candidates.clear(); } -#ifndef PRODUCT -void G1CollectionCandidateList::verify() { - G1CollectionSetCandidateInfo* prev = nullptr; - - for (uint i = 0; i < (uint)_candidates.length(); i++) { - G1CollectionSetCandidateInfo& ci = _candidates.at(i); - assert(prev == nullptr || prev->_gc_efficiency >= ci._gc_efficiency, - "Stored gc efficiency must be descending from region %u to %u", - prev->_r->hrm_index(), ci._r->hrm_index()); - prev = &ci; - assert(ci._r->rem_set()->is_tracked(), "remset for region %u must be tracked", ci._r->hrm_index()); +double G1CSetCandidateGroup::predict_group_total_time_ms() const { + G1Policy* p = G1CollectedHeap::heap()->policy(); + + double predicted_copy_time_ms = 0.0; + double predict_code_root_scan_time_ms = 0.0; + size_t predict_bytes_to_copy = 0.0; + + for (G1CollectionSetCandidateInfo ci : _candidates) { + G1HeapRegion* r = ci._r; + assert(r->rem_set()->cset_group() == this, "Must be!"); + + predict_bytes_to_copy += p->predict_bytes_to_copy(r); + predicted_copy_time_ms += p->predict_region_copy_time_ms(r, false /* for_young_only_phase */); + predict_code_root_scan_time_ms += p->predict_region_code_root_scan_time(r, false /* for_young_only_phase */); } -} -#endif -int G1CollectionCandidateList::compare_gc_efficiency(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2) { - assert(ci1->_r != nullptr && ci2->_r != nullptr, "Should not be!"); + size_t card_rs_length = _card_set.occupied(); + + double merge_scan_time_ms = p->predict_merge_scan_time(card_rs_length); + double non_young_other_time_ms = p->predict_non_young_other_time_ms(length()); + + double total_time_ms = merge_scan_time_ms + + predict_code_root_scan_time_ms + + predicted_copy_time_ms + + non_young_other_time_ms; - double gc_eff1 = ci1->_gc_efficiency; - double gc_eff2 = ci2->_gc_efficiency; + log_trace(gc, ergo, cset) ("Prediction for group %u (%u regions): total_time %.2fms card_rs_length %zu merge_scan_time %.2fms code_root_scan_time_ms %.2fms evac_time_ms %.2fms other_time %.2fms bytes_to_copy %zu", + group_id(), + length(), + total_time_ms, + card_rs_length, + merge_scan_time_ms, + predict_code_root_scan_time_ms, + predicted_copy_time_ms, + non_young_other_time_ms, + predict_bytes_to_copy); + + return total_time_ms; +} + +int G1CSetCandidateGroup::compare_gc_efficiency(G1CSetCandidateGroup** gr1, G1CSetCandidateGroup** gr2) { + double gc_eff1 = (*gr1)->gc_efficiency(); + double gc_eff2 = (*gr2)->gc_efficiency(); if (gc_eff1 > gc_eff2) { return -1; @@ -109,7 +134,7 @@ int G1CollectionCandidateList::compare_gc_efficiency(G1CollectionSetCandidateInf } } -int G1CollectionCandidateList::compare_reclaimble_bytes(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2) { +int G1CSetCandidateGroup::compare_reclaimble_bytes(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2) { // Make sure that null entries are moved to the end. if (ci1->_r == nullptr) { if (ci2->_r == nullptr) { @@ -133,47 +158,95 @@ int G1CollectionCandidateList::compare_reclaimble_bytes(G1CollectionSetCandidate } } -G1CollectionCandidateRegionList::G1CollectionCandidateRegionList() : _regions(2, mtGC) { } +G1CSetCandidateGroupList::G1CSetCandidateGroupList() : _groups(8, mtGC), _num_regions(0) { } + +void G1CSetCandidateGroupList::append(G1CSetCandidateGroup* group) { + assert(group->length() > 0, "Do not add empty groups"); + assert(!_groups.contains(group), "Already added to list"); + _groups.append(group); + _num_regions += group->length(); +} + +G1CSetCandidateGroup* G1CSetCandidateGroupList::at(uint index) { + return _groups.at(index); +} -void G1CollectionCandidateRegionList::append(G1HeapRegion* r) { - assert(!_regions.contains(r), "must be"); - _regions.append(r); +void G1CSetCandidateGroupList::clear(bool uninstall_group_cardset) { + for (G1CSetCandidateGroup* gr : _groups) { + gr->clear(uninstall_group_cardset); + delete gr; + } + _groups.clear(); + _num_regions = 0; } -void G1CollectionCandidateRegionList::remove_prefix(G1CollectionCandidateRegionList* other) { -#ifdef ASSERT - // Check that the given list is a prefix of this list. - int i = 0; - for (G1HeapRegion* r : *other) { - assert(_regions.at(i) == r, "must be in order, but element %d is not", i); - i++; +void G1CSetCandidateGroupList::prepare_for_scan() { + for (G1CSetCandidateGroup* gr : _groups) { + gr->card_set()->reset_table_scanner_for_groups(); } -#endif +} + +void G1CSetCandidateGroupList::remove_selected(uint count, uint num_regions) { + _groups.remove_till(count); + _num_regions -= num_regions; +} + +void G1CSetCandidateGroupList::remove(G1CSetCandidateGroupList* other) { + guarantee((uint)_groups.length() >= other->length(), "Other should be a subset of this list"); if (other->length() == 0) { + // Nothing to remove or nothing in the original set. return; } - _regions.remove_till(other->length()); + + // Create a list from scratch, copying over the elements from the candidate + // list not in the other list. Finally deallocate and overwrite the old list. + int new_length = _groups.length() - other->length(); + _num_regions = num_regions() - other->num_regions(); + GrowableArray new_list(new_length, mtGC); + + uint other_idx = 0; + for (G1CSetCandidateGroup* gr : _groups) { + if (other_idx == other->length() || gr != other->at(other_idx)) { + new_list.append(gr); + } else { + other_idx++; + } + } + _groups.swap(&new_list); + + verify(); + assert(_groups.length() == new_length, "Must be"); } -G1HeapRegion* G1CollectionCandidateRegionList::at(uint index) { - return _regions.at(index); +void G1CSetCandidateGroupList::sort_by_efficiency() { + _groups.sort(G1CSetCandidateGroup::compare_gc_efficiency); } -void G1CollectionCandidateRegionList::clear() { - _regions.clear(); +#ifndef PRODUCT +void G1CSetCandidateGroupList::verify() const { + G1CSetCandidateGroup* prev = nullptr; + + for (G1CSetCandidateGroup* gr : _groups) { + assert(prev == nullptr || prev->gc_efficiency() >= gr->gc_efficiency(), + "Stored gc efficiency must be descending"); + prev = gr; + } } +#endif G1CollectionSetCandidates::G1CollectionSetCandidates() : - _marking_regions(), - _retained_regions(), _contains_map(nullptr), + _from_marking_groups(), + _retained_groups(), _max_regions(0), _last_marking_candidates_length(0) { } G1CollectionSetCandidates::~G1CollectionSetCandidates() { FREE_C_HEAP_ARRAY(CandidateOrigin, _contains_map); + _from_marking_groups.clear(); + _retained_groups.clear(); } bool G1CollectionSetCandidates::is_from_marking(G1HeapRegion* r) const { @@ -189,8 +262,8 @@ void G1CollectionSetCandidates::initialize(uint max_regions) { } void G1CollectionSetCandidates::clear() { - _marking_regions.clear(); - _retained_regions.clear(); + _retained_groups.clear(true /* uninstall_group_cardset */); + _from_marking_groups.clear(true /* uninstall_group_cardset */); for (uint i = 0; i < _max_regions; i++) { _contains_map[i] = CandidateOrigin::Invalid; } @@ -198,28 +271,62 @@ void G1CollectionSetCandidates::clear() { } void G1CollectionSetCandidates::sort_marking_by_efficiency() { - G1CollectionCandidateListIterator iter = _marking_regions.begin(); - for (; iter != _marking_regions.end(); ++iter) { - G1HeapRegion* hr = (*iter)->_r; - (*iter)->_gc_efficiency = hr->calc_gc_efficiency(); + for (G1CSetCandidateGroup* gr : _from_marking_groups) { + gr->calculate_efficiency(); } - _marking_regions.sort_by_efficiency(); + _from_marking_groups.sort_by_efficiency(); - _marking_regions.verify(); + _from_marking_groups.verify(); } void G1CollectionSetCandidates::set_candidates_from_marking(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos) { - assert(_marking_regions.length() == 0, "must be empty before adding new ones"); + if (num_infos == 0) { + log_debug(gc, ergo, cset) ("No regions selected from marking."); + return; + } + assert(_from_marking_groups.length() == 0, "must be empty at the start of a cycle"); verify(); - _marking_regions.set(candidate_infos, num_infos); + G1Policy* p = G1CollectedHeap::heap()->policy(); + // During each Mixed GC, we must collect at least G1Policy::calc_min_old_cset_length regions to meet + // the G1MixedGCCountTarget. For the first collection in a Mixed GC cycle, we can add all regions + // required to meet this threshold to the same remset group. We are certain these will be collected in + // the same MixedGC. + uint group_limit = p->calc_min_old_cset_length(num_infos); + + uint num_added_to_group = 0; + + G1CSetCandidateGroup::reset_next_group_id(); + G1CSetCandidateGroup* current = nullptr; + + current = new G1CSetCandidateGroup(); + for (uint i = 0; i < num_infos; i++) { G1HeapRegion* r = candidate_infos[i]._r; assert(!contains(r), "must not contain region %u", r->hrm_index()); _contains_map[r->hrm_index()] = CandidateOrigin::Marking; + + if (num_added_to_group == group_limit) { + if (group_limit != G1OldCSetGroupSize) { + group_limit = G1OldCSetGroupSize; + } + + _from_marking_groups.append(current); + + current = new G1CSetCandidateGroup(); + num_added_to_group = 0; + } + current->add(candidate_infos[i]); + num_added_to_group++; } + + _from_marking_groups.append(current); + + assert(_from_marking_groups.num_regions() == num_infos, "Must be!"); + + log_debug(gc, ergo, cset) ("Finished creating %u collection groups from %u regions", _from_marking_groups.length(), num_infos); _last_marking_candidates_length = num_infos; verify(); @@ -228,46 +335,53 @@ void G1CollectionSetCandidates::set_candidates_from_marking(G1CollectionSetCandi void G1CollectionSetCandidates::sort_by_efficiency() { // From marking regions must always be sorted so no reason to actually sort // them. - _marking_regions.verify(); - _retained_regions.sort_by_efficiency(); - _retained_regions.verify(); -} - -void G1CollectionSetCandidates::add_retained_region_unsorted(G1HeapRegion* r) { - assert(!contains(r), "must not contain region %u", r->hrm_index()); - _contains_map[r->hrm_index()] = CandidateOrigin::Retained; - _retained_regions.append_unsorted(r); + _from_marking_groups.verify(); + _retained_groups.sort_by_efficiency(); + _retained_groups.verify(); } -void G1CollectionSetCandidates::remove(G1CollectionCandidateRegionList* other) { +void G1CollectionSetCandidates::remove(G1CSetCandidateGroupList* other) { // During removal, we exploit the fact that elements in the marking_regions, // retained_regions and other list are sorted by gc_efficiency. Furthermore, // all regions in the passed other list are in one of the two other lists. // // Split original list into elements for the marking list and elements from the // retained list. - G1CollectionCandidateRegionList other_marking_regions; - G1CollectionCandidateRegionList other_retained_regions; + G1CSetCandidateGroupList other_marking_groups; + G1CSetCandidateGroupList other_retained_groups; - for (G1HeapRegion* r : *other) { + for (G1CSetCandidateGroup* group : *other) { + assert(group->length() > 0, "Should not have empty groups"); + // Regions in the same group have the same source (i.e from_marking or retained). + G1HeapRegion* r = group->region_at(0); if (is_from_marking(r)) { - other_marking_regions.append(r); + other_marking_groups.append(group); } else { - other_retained_regions.append(r); + other_retained_groups.append(group); } } - _marking_regions.remove(&other_marking_regions); - _retained_regions.remove(&other_retained_regions); + _from_marking_groups.remove(&other_marking_groups); + _retained_groups.remove(&other_retained_groups); - for (G1HeapRegion* r : *other) { - assert(contains(r), "must contain region %u", r->hrm_index()); + other->iterate([&] (G1HeapRegion* r) { + assert(contains(r), "Must contain region %u", r->hrm_index()); _contains_map[r->hrm_index()] = CandidateOrigin::Invalid; - } + }); verify(); } +void G1CollectionSetCandidates::add_retained_region_unsorted(G1HeapRegion* r) { + assert(!contains(r), "Must not already contain region %u", r->hrm_index()); + _contains_map[r->hrm_index()] = CandidateOrigin::Retained; + + G1CSetCandidateGroup* gr = new G1CSetCandidateGroup(); + gr->add(r); + + _retained_groups.append(gr); +} + bool G1CollectionSetCandidates::is_empty() const { return length() == 0; } @@ -277,29 +391,31 @@ bool G1CollectionSetCandidates::has_more_marking_candidates() const { } uint G1CollectionSetCandidates::marking_regions_length() const { - return _marking_regions.length(); + return _from_marking_groups.num_regions(); } uint G1CollectionSetCandidates::retained_regions_length() const { - return _retained_regions.length(); + return _retained_groups.num_regions(); } #ifndef PRODUCT -void G1CollectionSetCandidates::verify_helper(G1CollectionCandidateList* list, uint& from_marking, CandidateOrigin* verify_map) { +void G1CollectionSetCandidates::verify_helper(G1CSetCandidateGroupList* list, uint& from_marking, CandidateOrigin* verify_map) { list->verify(); - for (uint i = 0; i < (uint)list->length(); i++) { - G1HeapRegion* r = list->at(i)._r; + for (G1CSetCandidateGroup* gr : *list) { + for (G1CollectionSetCandidateInfo ci : *gr) { + G1HeapRegion* r = ci._r; - if (is_from_marking(r)) { - from_marking++; - } - const uint hrm_index = r->hrm_index(); - assert(_contains_map[hrm_index] == CandidateOrigin::Marking || _contains_map[hrm_index] == CandidateOrigin::Retained, - "must be %u is %u", hrm_index, (uint)_contains_map[hrm_index]); - assert(verify_map[hrm_index] == CandidateOrigin::Invalid, "already added"); + if (is_from_marking(r)) { + from_marking++; + } + const uint hrm_index = r->hrm_index(); + assert(_contains_map[hrm_index] == CandidateOrigin::Marking || _contains_map[hrm_index] == CandidateOrigin::Retained, + "must be %u is %u", hrm_index, (uint)_contains_map[hrm_index]); + assert(verify_map[hrm_index] == CandidateOrigin::Invalid, "already added"); - verify_map[hrm_index] = CandidateOrigin::Verify; + verify_map[hrm_index] = CandidateOrigin::Verify; + } } } @@ -311,11 +427,11 @@ void G1CollectionSetCandidates::verify() { verify_map[i] = CandidateOrigin::Invalid; } - verify_helper(&_marking_regions, from_marking, verify_map); + verify_helper(&_from_marking_groups, from_marking, verify_map); assert(from_marking == marking_regions_length(), "must be"); uint from_marking_retained = 0; - verify_helper(&_retained_regions, from_marking_retained, verify_map); + verify_helper(&_retained_groups, from_marking_retained, verify_map); assert(from_marking_retained == 0, "must be"); assert(length() >= marking_regions_length(), "must be"); diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp index e629aa8f36324..b60af7d067de3 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp @@ -25,53 +25,24 @@ #ifndef SHARE_GC_G1_G1COLLECTIONSETCANDIDATES_HPP #define SHARE_GC_G1_G1COLLECTIONSETCANDIDATES_HPP +#include "gc/g1/g1CardSetMemory.hpp" #include "gc/g1/g1CollectionSetCandidates.hpp" #include "gc/shared/gc_globals.hpp" -#include "gc/shared/workerThread.hpp" #include "memory/allocation.hpp" #include "runtime/globals.hpp" -#include "utilities/bitMap.hpp" #include "utilities/growableArray.hpp" -class G1CollectionCandidateList; class G1CollectionSetCandidates; +class G1CSetCandidateGroupList; class G1HeapRegion; class G1HeapRegionClosure; -using G1CollectionCandidateRegionListIterator = GrowableArrayIterator; - -// A set of G1HeapRegion*, a thin wrapper around GrowableArray. -class G1CollectionCandidateRegionList { - GrowableArray _regions; - -public: - G1CollectionCandidateRegionList(); - - // Append a G1HeapRegion to the end of this list. The region must not be in the list - // already. - void append(G1HeapRegion* r); - // Remove the given list of G1HeapRegion* from this list. The given list must be a prefix - // of this list. - void remove_prefix(G1CollectionCandidateRegionList* list); - - // Empty contents of the list. - void clear(); - - G1HeapRegion* at(uint index); - - uint length() const { return (uint)_regions.length(); } - - G1CollectionCandidateRegionListIterator begin() const { return _regions.begin(); } - G1CollectionCandidateRegionListIterator end() const { return _regions.end(); } -}; - struct G1CollectionSetCandidateInfo { G1HeapRegion* _r; - double _gc_efficiency; uint _num_unreclaimed; // Number of GCs this region has been found unreclaimable. - G1CollectionSetCandidateInfo() : G1CollectionSetCandidateInfo(nullptr, 0.0) { } - G1CollectionSetCandidateInfo(G1HeapRegion* r, double gc_efficiency) : _r(r), _gc_efficiency(gc_efficiency), _num_unreclaimed(0) { } + G1CollectionSetCandidateInfo() : G1CollectionSetCandidateInfo(nullptr) { } + G1CollectionSetCandidateInfo(G1HeapRegion* r) : _r(r), _num_unreclaimed(0) { } bool update_num_unreclaimed() { ++_num_unreclaimed; @@ -79,100 +50,159 @@ struct G1CollectionSetCandidateInfo { } }; -class G1CollectionCandidateListIterator : public StackObj { - G1CollectionCandidateList* _which; - uint _position; +using G1CSetCandidateGroupIterator = GrowableArrayIterator; -public: - G1CollectionCandidateListIterator(G1CollectionCandidateList* which, uint position); - - G1CollectionCandidateListIterator& operator++(); - G1CollectionSetCandidateInfo* operator*(); +// G1CSetCandidateGroup groups candidate regions that will be selected for evacuation at the same time. +// Grouping occurs both for candidates from marking or regions retained during evacuation failure, but a group +// can not contain regions from both types of regions. +// +// Humongous objects are excluded from the candidate groups because regions associated with these +// objects are never selected for evacuation. +// +// All regions in the group share a G1CardSet instance, which tracks remembered set entries for the +// regions in the group. We do not have track to cross-region references for regions that are in the +// same group saving memory. +class G1CSetCandidateGroup : public CHeapObj{ + GrowableArray _candidates; - bool operator==(const G1CollectionCandidateListIterator& rhs); - bool operator!=(const G1CollectionCandidateListIterator& rhs); -}; + G1CardSetMemoryManager _card_set_mm; -// List of collection set candidates (regions with their efficiency) ordered by -// decreasing gc efficiency. -class G1CollectionCandidateList : public CHeapObj { - friend class G1CollectionCandidateListIterator; + // The set of cards in the Java heap + G1CardSet _card_set; - GrowableArray _candidates; + size_t _reclaimable_bytes; + double _gc_efficiency; + // The _group_id is primarily used when printing out per-region liveness information, + // making it easier to associate regions with their assigned G1CSetCandidateGroup, if any. + // Note: + // * _group_id 0 is reserved for special G1CSetCandidateGroups that hold only a single region, + // such as G1CSetCandidateGroups for retained regions. + // * _group_id 1 is reserved for the G1CSetCandidateGroup that contains all young regions. + const uint _group_id; + static uint _next_group_id; public: - G1CollectionCandidateList(); - - // Put the given set of candidates into this list, preserving the efficiency ordering. - void set(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos); - // Add the given G1HeapRegion to this list at the end, (potentially) making the list unsorted. - void append_unsorted(G1HeapRegion* r); - // Restore sorting order by decreasing gc efficiency, using the existing efficiency - // values. - void sort_by_efficiency(); - // Removes any heap regions stored in this list also in the other list. The other - // list may only contain regions in this list, sorted by gc efficiency. It need - // not be a prefix of this list. Returns the number of regions removed. - // E.g. if this list is "A B G H", the other list may be "A G H", but not "F" (not in - // this list) or "A H G" (wrong order). - void remove(G1CollectionCandidateRegionList* other); - - void clear(); + G1CSetCandidateGroup(); + G1CSetCandidateGroup(G1CardSetConfiguration* config, G1MonotonicArenaFreePool* card_set_freelist_pool, uint group_id); + ~G1CSetCandidateGroup() { + assert(length() == 0, "post condition!"); + } - G1CollectionSetCandidateInfo& at(uint position) { return _candidates.at(position); } + void add(G1HeapRegion* hr); + void add(G1CollectionSetCandidateInfo& hr_info); uint length() const { return (uint)_candidates.length(); } - void verify() PRODUCT_RETURN; + G1CardSet* card_set() { return &_card_set; } + const G1CardSet* card_set() const { return &_card_set; } + + uint group_id() const { return _group_id; } + void calculate_efficiency(); + + size_t liveness() const; // Comparison function to order regions in decreasing GC efficiency order. This // will cause regions with a lot of live objects and large remembered sets to end // up at the end of the list. - static int compare_gc_efficiency(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2); + static int compare_gc_efficiency(G1CSetCandidateGroup** gr1, G1CSetCandidateGroup** gr2); static int compare_reclaimble_bytes(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2); - G1CollectionCandidateListIterator begin() { - return G1CollectionCandidateListIterator(this, 0); + double gc_efficiency() const { return _gc_efficiency; } + + G1HeapRegion* region_at(uint i) const { return _candidates.at(i)._r; } + + G1CollectionSetCandidateInfo* at(uint i) { return &_candidates.at(i); } + + double predict_group_total_time_ms() const; + + G1MonotonicArenaMemoryStats card_set_memory_stats() const { + return _card_set_mm.memory_stats(); + } + + void clear(bool uninstall_group_cardset = false); + + G1CSetCandidateGroupIterator begin() const { + return _candidates.begin(); + } + + G1CSetCandidateGroupIterator end() const { + return _candidates.end(); } - G1CollectionCandidateListIterator end() { - return G1CollectionCandidateListIterator(this, length()); + static void reset_next_group_id() { + _next_group_id = 2; } }; -// Iterator for G1CollectionSetCandidates. There are no guarantees on the order -// of the regions returned. -class G1CollectionSetCandidatesIterator : public StackObj { - G1CollectionSetCandidates* _which; - uint _position; +using G1CSetCandidateGroupListIterator = GrowableArrayIterator; + +class G1CSetCandidateGroupList { + GrowableArray _groups; + volatile uint _num_regions; + +public: + G1CSetCandidateGroupList(); + void append(G1CSetCandidateGroup* group); + + // Delete all groups from the list. The cardset cleanup for regions within the + // groups could have been done elsewhere (e.g. when adding groups to the + // collection set or to retained regions). The uninstall_group_cardset is set to + // true if cleanup needs to happen as we clear the groups from the list. + void clear(bool uninstall_group_cardset = false); + + G1CSetCandidateGroup* at(uint index); + + uint length() const { return (uint)_groups.length(); } + + uint num_regions() const { return _num_regions; } + + void remove_selected(uint count, uint num_regions); - public: - G1CollectionSetCandidatesIterator(G1CollectionSetCandidates* which, uint position); + // Removes any candidate groups stored in this list and also in the other list. The other + // list may only contain candidate groups in this list, sorted by gc efficiency. It need + // not be a prefix of this list. + // E.g. if this list is "A B G H", the other list may be "A G H", but not "F" (not in + // this list) or "A H G" (wrong order). + void remove(G1CSetCandidateGroupList* other); + + void prepare_for_scan(); + + void sort_by_efficiency(); + + GrowableArray* groups() { + return &_groups; + } - G1CollectionSetCandidatesIterator& operator++(); - G1HeapRegion* operator*(); + void verify() const PRODUCT_RETURN; - bool operator==(const G1CollectionSetCandidatesIterator& rhs); - bool operator!=(const G1CollectionSetCandidatesIterator& rhs); + G1CSetCandidateGroupListIterator begin() const { + return _groups.begin(); + } + + G1CSetCandidateGroupListIterator end() const { + return _groups.end(); + } + + template + void iterate(Func&& f) const; }; -// Tracks all collection set candidates, i.e. regions that could/should be evacuated soon. +// Tracks all collection set candidates, i.e. region groups that could/should be evacuated soon. // -// These candidate regions are tracked in two list of regions, sorted by decreasing +// These candidate groups are tracked in two list of region groups, sorted by decreasing // "gc efficiency". // -// * marking_regions: the set of regions selected by concurrent marking to be -// evacuated to keep overall heap occupancy stable. -// They are guaranteed to be evacuated and cleared out during -// the mixed phase. +// * from_marking_groups: the set of region groups selected by concurrent marking to be +// evacuated to keep overall heap occupancy stable. +// They are guaranteed to be evacuated and cleared out during +// the mixed phase. // -// * retained_regions: set of regions selected for evacuation during evacuation -// failure. -// Any young collection will try to evacuate them. +// * retained_groups: set of region groups selected for evacuation during evacuation +// failure. +// Any young collection will try to evacuate them. // class G1CollectionSetCandidates : public CHeapObj { - friend class G1CollectionSetCandidatesIterator; enum class CandidateOrigin : uint8_t { Invalid, @@ -181,10 +211,12 @@ class G1CollectionSetCandidates : public CHeapObj { Verify // Special value for verification. }; - G1CollectionCandidateList _marking_regions; // Set of regions selected by concurrent marking. - G1CollectionCandidateList _retained_regions; // Set of regions selected from evacuation failed regions. - CandidateOrigin* _contains_map; + G1CSetCandidateGroupList _from_marking_groups; // Set of regions selected by concurrent marking. + // Set of regions retained due to evacuation failure. Groups added to this list + // should contain only one region each, making it easier to evacuate retained regions + // in any young collection. + G1CSetCandidateGroupList _retained_groups; uint _max_regions; // The number of regions from the last merge of candidates from the marking. @@ -196,8 +228,8 @@ class G1CollectionSetCandidates : public CHeapObj { G1CollectionSetCandidates(); ~G1CollectionSetCandidates(); - G1CollectionCandidateList& marking_regions() { return _marking_regions; } - G1CollectionCandidateList& retained_regions() { return _retained_regions; } + G1CSetCandidateGroupList& from_marking_groups() { return _from_marking_groups; } + G1CSetCandidateGroupList& retained_groups() { return _retained_groups; } void initialize(uint max_regions); @@ -219,9 +251,9 @@ class G1CollectionSetCandidates : public CHeapObj { // Add the given region to the set of retained regions without regards to the // gc efficiency sorting. The retained regions must be re-sorted manually later. void add_retained_region_unsorted(G1HeapRegion* r); - // Remove the given regions from the candidates. All given regions must be part + // Remove the given groups from the candidates. All given regions must be part // of the candidates. - void remove(G1CollectionCandidateRegionList* other); + void remove(G1CSetCandidateGroupList* other); bool contains(const G1HeapRegion* r) const; @@ -234,21 +266,15 @@ class G1CollectionSetCandidates : public CHeapObj { uint retained_regions_length() const; private: - void verify_helper(G1CollectionCandidateList* list, uint& from_marking, CandidateOrigin* verify_map) PRODUCT_RETURN; + void verify_helper(G1CSetCandidateGroupList* list, uint& from_marking, CandidateOrigin* verify_map) PRODUCT_RETURN; public: void verify() PRODUCT_RETURN; uint length() const { return marking_regions_length() + retained_regions_length(); } - // Iteration - G1CollectionSetCandidatesIterator begin() { - return G1CollectionSetCandidatesIterator(this, 0); - } - - G1CollectionSetCandidatesIterator end() { - return G1CollectionSetCandidatesIterator(this, length()); - } + template + void iterate_regions(Func&& f) const; }; #endif /* SHARE_GC_G1_G1COLLECTIONSETCANDIDATES_HPP */ diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp index cc2c24fbba073..d32c7990d4eb8 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp @@ -29,54 +29,21 @@ #include "utilities/growableArray.hpp" -inline G1CollectionCandidateListIterator::G1CollectionCandidateListIterator(G1CollectionCandidateList* which, uint position) : - _which(which), _position(position) { } - -inline G1CollectionCandidateListIterator& G1CollectionCandidateListIterator::operator++() { - assert(_position < _which->length(), "must be"); - _position++; - return *this; -} - -inline G1CollectionSetCandidateInfo* G1CollectionCandidateListIterator::operator*() { - return &_which->_candidates.at(_position); -} - -inline bool G1CollectionCandidateListIterator::operator==(const G1CollectionCandidateListIterator& rhs) { - assert(_which == rhs._which, "iterator belongs to different array"); - return _position == rhs._position; -} - -inline bool G1CollectionCandidateListIterator::operator!=(const G1CollectionCandidateListIterator& rhs) { - return !(*this == rhs); -} - -inline G1CollectionSetCandidatesIterator::G1CollectionSetCandidatesIterator(G1CollectionSetCandidates* which, uint position) : - _which(which), _position(position) { -} - -inline G1CollectionSetCandidatesIterator& G1CollectionSetCandidatesIterator::operator++() { - assert(_position < _which->length(), "must not be at end already"); - _position++; - return *this; -} - -inline G1HeapRegion* G1CollectionSetCandidatesIterator::operator*() { - uint length = _which->marking_regions_length(); - if (_position < length) { - return _which->_marking_regions.at(_position)._r; - } else { - return _which->_retained_regions.at(_position - length)._r; +template +void G1CSetCandidateGroupList::iterate(Func&& f) const { + for (G1CSetCandidateGroup* group : _groups) { + for (G1CollectionSetCandidateInfo ci : *group) { + G1HeapRegion* r = ci._r; + f(r); + } } } -inline bool G1CollectionSetCandidatesIterator::operator==(const G1CollectionSetCandidatesIterator& rhs) { - assert(_which == rhs._which, "iterator belongs to different array"); - return _position == rhs._position; -} +template +void G1CollectionSetCandidates::iterate_regions(Func&& f) const { + _from_marking_groups.iterate(f); -inline bool G1CollectionSetCandidatesIterator::operator!=(const G1CollectionSetCandidatesIterator& rhs) { - return !(*this == rhs); + _retained_groups.iterate(f); } #endif /* SHARE_GC_G1_G1COLLECTIONSETCANDIDATES_INLINE_HPP */ diff --git a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp index 630fb8a7a1122..3531d97fd3a86 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSetCandidates.hpp" #include "gc/g1/g1CollectionSetChooser.hpp" @@ -94,7 +93,7 @@ class G1BuildCandidateRegionsTask : public WorkerTask { void set(uint idx, G1HeapRegion* hr) { assert(idx < _max_size, "Index %u out of bounds %u", idx, _max_size); assert(_data[idx]._r == nullptr, "Value must not have been set."); - _data[idx] = CandidateInfo(hr, 0.0); + _data[idx] = CandidateInfo(hr); } void sort_by_reclaimable_bytes() { @@ -104,7 +103,7 @@ class G1BuildCandidateRegionsTask : public WorkerTask { for (uint i = _cur_claim_idx; i < _max_size; i++) { assert(_data[i]._r == nullptr, "must be"); } - qsort(_data, _cur_claim_idx, sizeof(_data[0]), (_sort_Fn)G1CollectionCandidateList::compare_reclaimble_bytes); + qsort(_data, _cur_claim_idx, sizeof(_data[0]), (_sort_Fn)G1CSetCandidateGroup::compare_reclaimble_bytes); for (uint i = _cur_claim_idx; i < _max_size; i++) { assert(_data[i]._r == nullptr, "must be"); } @@ -224,7 +223,7 @@ class G1BuildCandidateRegionsTask : public WorkerTask { num_pruned++; } - log_debug(gc, ergo, cset)("Pruned %u regions out of %u, leaving " SIZE_FORMAT " bytes waste (allowed " SIZE_FORMAT ")", + log_debug(gc, ergo, cset)("Pruned %u regions out of %u, leaving %zu bytes waste (allowed %zu)", num_pruned, num_candidates, wasted_bytes, diff --git a/src/hotspot/share/gc/g1/g1CollectorState.cpp b/src/hotspot/share/gc/g1/g1CollectorState.cpp index 581ab4f16bf63..d41ee22fdcead 100644 --- a/src/hotspot/share/gc/g1/g1CollectorState.cpp +++ b/src/hotspot/share/gc/g1/g1CollectorState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1GCPauseType.hpp" diff --git a/src/hotspot/share/gc/g1/g1CommittedRegionMap.cpp b/src/hotspot/share/gc/g1/g1CommittedRegionMap.cpp index 6919cc7d0c911..d8454cd5cf88c 100644 --- a/src/hotspot/share/gc/g1/g1CommittedRegionMap.cpp +++ b/src/hotspot/share/gc/g1/g1CommittedRegionMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CommittedRegionMap.inline.hpp" #include "logging/log.hpp" #include "memory/universe.hpp" @@ -233,7 +232,7 @@ void G1CommittedRegionMap::verify_free_range(uint start, uint end) const { void G1CommittedRegionMap::verify_no_inactive_regons() const { BitMap::idx_t first_inactive = _inactive.find_first_set_bit(0); - assert(first_inactive == _inactive.size(), "Should be no inactive regions, but was at index: " SIZE_FORMAT, first_inactive); + assert(first_inactive == _inactive.size(), "Should be no inactive regions, but was at index: %zu", first_inactive); } void G1CommittedRegionMap::verify_active_count(uint start, uint end, uint expected) const { diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index d0879e9967cd3..87b384b1c9425 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/g1/g1BarrierSet.hpp" @@ -140,7 +139,7 @@ bool G1CMMarkStack::initialize() { log_trace(gc)("MarkStackSize: %uk MarkStackSizeMax: %uk", (uint)(MarkStackSize / K), (uint)(MarkStackSizeMax / K)); - log_debug(gc)("Initialize mark stack with " SIZE_FORMAT " chunks, maximum " SIZE_FORMAT, + log_debug(gc)("Initialize mark stack with %zu chunks, maximum %zu", initial_num_chunks, max_capacity); return _chunk_allocator.initialize(initial_num_chunks, max_num_chunks); @@ -205,7 +204,7 @@ bool G1CMMarkStack::ChunkAllocator::initialize(size_t initial_capacity, size_t m size_t new_capacity = bucket_size(0); if (!reserve(new_capacity)) { - log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", new_capacity, new_capacity * sizeof(TaskQueueEntryChunk)); + log_warning(gc)("Failed to reserve memory for new overflow mark stack with %zu chunks and size %zuB.", new_capacity, new_capacity * sizeof(TaskQueueEntryChunk)); return false; } return true; @@ -213,7 +212,7 @@ bool G1CMMarkStack::ChunkAllocator::initialize(size_t initial_capacity, size_t m bool G1CMMarkStack::ChunkAllocator::try_expand_to(size_t desired_capacity) { if (_capacity == _max_capacity) { - log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " chunks.", _capacity); + log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of %zu chunks.", _capacity); return false; } @@ -221,7 +220,7 @@ bool G1CMMarkStack::ChunkAllocator::try_expand_to(size_t desired_capacity) { desired_capacity = MIN2(desired_capacity, _max_capacity); if (reserve(desired_capacity)) { - log_debug(gc)("Expanded the mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks", + log_debug(gc)("Expanded the mark stack capacity from %zu to %zu chunks", old_capacity, desired_capacity); return true; } @@ -249,7 +248,7 @@ G1CMMarkStack::ChunkAllocator::~ChunkAllocator() { } bool G1CMMarkStack::ChunkAllocator::reserve(size_t new_capacity) { - assert(new_capacity <= _max_capacity, "Cannot expand overflow mark stack beyond the max_capacity" SIZE_FORMAT " chunks.", _max_capacity); + assert(new_capacity <= _max_capacity, "Cannot expand overflow mark stack beyond the max_capacity of %zu chunks.", _max_capacity); size_t highest_bucket = get_bucket(new_capacity - 1); size_t i = get_bucket(_capacity); @@ -273,7 +272,7 @@ bool G1CMMarkStack::ChunkAllocator::reserve(size_t new_capacity) { TaskQueueEntryChunk* bucket_base = MmapArrayAllocator::allocate_or_null(bucket_capacity, mtGC); if (bucket_base == nullptr) { - log_warning(gc)("Failed to reserve memory for increasing the overflow mark stack capacity with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", + log_warning(gc)("Failed to reserve memory for increasing the overflow mark stack capacity with %zu chunks and size %zuB.", bucket_capacity, bucket_capacity * sizeof(TaskQueueEntryChunk)); return false; } @@ -384,7 +383,7 @@ void G1CMRootMemRegions::reset() { void G1CMRootMemRegions::add(HeapWord* start, HeapWord* end) { assert_at_safepoint(); size_t idx = Atomic::fetch_then_add(&_num_root_regions, 1u); - assert(idx < _max_regions, "Trying to add more root MemRegions than there is space " SIZE_FORMAT, _max_regions); + assert(idx < _max_regions, "Trying to add more root MemRegions than there is space %zu", _max_regions); assert(start != nullptr && end != nullptr && start <= end, "Start (" PTR_FORMAT ") should be less or equal to " "end (" PTR_FORMAT ")", p2i(start), p2i(end)); _root_regions[idx].set_start(start); @@ -446,7 +445,7 @@ void G1CMRootMemRegions::scan_finished() { if (!_should_abort) { assert(_claimed_root_regions >= num_root_regions(), - "we should have claimed all root regions, claimed " SIZE_FORMAT ", length = %u", + "we should have claimed all root regions, claimed %zu, length = %u", _claimed_root_regions, num_root_regions()); } @@ -790,7 +789,7 @@ void G1ConcurrentMark::clear_bitmap(WorkerThreads* workers, bool may_yield) { G1ClearBitMapTask cl(this, num_workers, may_yield); - log_debug(gc, ergo)("Running %s with %u workers for " SIZE_FORMAT " work units.", cl.name(), num_workers, num_chunks); + log_debug(gc, ergo)("Running %s with %u workers for %zu work units.", cl.name(), num_workers, num_chunks); workers->run_task(&cl, num_workers); guarantee(may_yield || cl.is_complete(), "Must have completed iteration when not yielding."); } @@ -1737,7 +1736,7 @@ void G1ConcurrentMark::weak_refs_work() { // We can not trust g1_is_alive and the contents of the heap if the marking stack // overflowed while processing references. Exit the VM. fatal("Overflow during reference processing, can not continue. Current mark stack depth: " - SIZE_FORMAT ", MarkStackSize: " SIZE_FORMAT ", MarkStackSizeMax: " SIZE_FORMAT ". " + "%zu, MarkStackSize: %zu, MarkStackSizeMax: %zu. " "Please increase MarkStackSize and/or MarkStackSizeMax and restart.", _global_mark_stack.size(), MarkStackSize, MarkStackSizeMax); return; @@ -1882,7 +1881,7 @@ void G1ConcurrentMark::finalize_marking() { SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set(); guarantee(has_overflown() || satb_mq_set.completed_buffers_num() == 0, - "Invariant: has_overflown = %s, num buffers = " SIZE_FORMAT, + "Invariant: has_overflown = %s, num buffers = %zu", BOOL_TO_STR(has_overflown()), satb_mq_set.completed_buffers_num()); @@ -1898,7 +1897,7 @@ void G1ConcurrentMark::flush_all_task_caches() { misses += stats.second; } size_t sum = hits + misses; - log_debug(gc, stats)("Mark stats cache hits " SIZE_FORMAT " misses " SIZE_FORMAT " ratio %1.3lf", + log_debug(gc, stats)("Mark stats cache hits %zu misses %zu ratio %1.3lf", hits, misses, percent_of(hits, sum)); } @@ -2475,7 +2474,7 @@ void G1CMTask::print_stats() { _step_times_ms.sum()); size_t const hits = _mark_stats_cache.hits(); size_t const misses = _mark_stats_cache.misses(); - log_debug(gc, stats)(" Mark Stats Cache: hits " SIZE_FORMAT " misses " SIZE_FORMAT " ratio %.3f", + log_debug(gc, stats)(" Mark Stats Cache: hits %zu misses %zu ratio %.3f", hits, misses, percent_of(hits, hits + misses)); } @@ -2976,15 +2975,20 @@ G1CMTask::G1CMTask(uint worker_id, #define G1PPRL_TYPE_H_FORMAT " %4s" #define G1PPRL_STATE_FORMAT " %-5s" #define G1PPRL_STATE_H_FORMAT " %5s" -#define G1PPRL_BYTE_FORMAT " " SIZE_FORMAT_W(9) +#define G1PPRL_BYTE_FORMAT " %9zu" #define G1PPRL_BYTE_H_FORMAT " %9s" #define G1PPRL_DOUBLE_FORMAT "%14.1f" #define G1PPRL_GCEFF_FORMAT " %14s" #define G1PPRL_GCEFF_H_FORMAT " %14s" +#define G1PPRL_GID_H_FORMAT " %9s" +#define G1PPRL_GID_FORMAT " " UINT32_FORMAT_W(9) +#define G1PPRL_LEN_FORMAT " " UINT32_FORMAT_W(14) +#define G1PPRL_LEN_H_FORMAT " %14s" +#define G1PPRL_GID_GCEFF_FORMAT " %14.1f" // For summary info #define G1PPRL_SUM_ADDR_FORMAT(tag) " " tag ":" G1PPRL_ADDR_BASE_FORMAT -#define G1PPRL_SUM_BYTE_FORMAT(tag) " " tag ": " SIZE_FORMAT +#define G1PPRL_SUM_BYTE_FORMAT(tag) " " tag ": %zu" #define G1PPRL_SUM_MB_FORMAT(tag) " " tag ": %1.2f MB" #define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%" @@ -2993,7 +2997,6 @@ G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* p _total_capacity_bytes(0), _total_live_bytes(0), _total_remset_bytes(0), - _young_cardset_bytes_per_region(0), _total_code_roots_bytes(0) { if (!log_is_enabled(Trace, gc, liveness)) { @@ -3004,13 +3007,6 @@ G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* p MemRegion reserved = g1h->reserved(); double now = os::elapsedTime(); - uint num_young_regions = g1h->young_regions_count(); - size_t young_cardset_bytes = g1h->young_regions_cardset()->mem_size(); - - if (num_young_regions > 0) { - _young_cardset_bytes_per_region = young_cardset_bytes / num_young_regions; - } - // Print the header of the output. log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" HEAP" @@ -3024,25 +3020,24 @@ G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* p G1PPRL_ADDR_BASE_H_FORMAT G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT - G1PPRL_GCEFF_H_FORMAT - G1PPRL_BYTE_H_FORMAT G1PPRL_STATE_H_FORMAT - G1PPRL_BYTE_H_FORMAT, + G1PPRL_BYTE_H_FORMAT + G1PPRL_GID_H_FORMAT, "type", "address-range", - "used", "live", "gc-eff", - "remset", "state", "code-roots"); + "used", "live", + "state", "code-roots", + "group-id"); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX G1PPRL_TYPE_H_FORMAT G1PPRL_ADDR_BASE_H_FORMAT G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT - G1PPRL_GCEFF_H_FORMAT - G1PPRL_BYTE_H_FORMAT G1PPRL_STATE_H_FORMAT - G1PPRL_BYTE_H_FORMAT, + G1PPRL_BYTE_H_FORMAT + G1PPRL_GID_H_FORMAT, "", "", - "(bytes)", "(bytes)", "(bytes/ms)", - "(bytes)", "", "(bytes)"); + "(bytes)", "(bytes)", + "", "(bytes)", ""); } bool G1PrintRegionLivenessInfoClosure::do_heap_region(G1HeapRegion* r) { @@ -3056,14 +3051,13 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(G1HeapRegion* r) { size_t capacity_bytes = r->capacity(); size_t used_bytes = r->used(); size_t live_bytes = r->live_bytes(); - double gc_eff = r->calc_gc_efficiency(); size_t remset_bytes = r->rem_set()->mem_size(); size_t code_roots_bytes = r->rem_set()->code_roots_mem_size(); const char* remset_type = r->rem_set()->get_short_state_str(); - FormatBuffer<16> gc_efficiency(""); + uint cset_groud_gid = 0; - if (r->is_young()) { - remset_bytes = _young_cardset_bytes_per_region; + if (r->rem_set()->is_added_to_cset_group()) { + cset_groud_gid = r->rem_set()->cset_group_id(); } _total_used_bytes += used_bytes; @@ -3072,25 +3066,19 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(G1HeapRegion* r) { _total_remset_bytes += remset_bytes; _total_code_roots_bytes += code_roots_bytes; - if(gc_eff < 0) { - gc_efficiency.append("-"); - } else { - gc_efficiency.append(G1PPRL_DOUBLE_FORMAT, gc_eff); - } - // Print a line for this particular region. log_trace(gc, liveness)(G1PPRL_LINE_PREFIX G1PPRL_TYPE_FORMAT G1PPRL_ADDR_BASE_FORMAT G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT - G1PPRL_GCEFF_FORMAT - G1PPRL_BYTE_FORMAT G1PPRL_STATE_FORMAT - G1PPRL_BYTE_FORMAT, + G1PPRL_BYTE_FORMAT + G1PPRL_GID_FORMAT, type, p2i(bottom), p2i(end), - used_bytes, live_bytes, gc_efficiency.buffer(), - remset_bytes, remset_type, code_roots_bytes); + used_bytes, live_bytes, + remset_type, code_roots_bytes, + cset_groud_gid); return false; } @@ -3104,6 +3092,9 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { _total_remset_bytes += g1h->card_set_freelist_pool()->mem_size(); // add static memory usages to remembered set sizes _total_remset_bytes += G1HeapRegionRemSet::static_mem_size(); + + do_cset_groups(); + // Print the footer of the output. log_trace(gc, liveness)(G1PPRL_LINE_PREFIX); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX @@ -3121,3 +3112,77 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { bytes_to_mb(_total_remset_bytes), bytes_to_mb(_total_code_roots_bytes)); } + +void G1PrintRegionLivenessInfoClosure::do_cset_groups() { + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX); + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" Collectionset Candidate Groups"); + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX " Types: Y=Young Regions, M=From Marking Regions, R=Retained Regions"); + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX + G1PPRL_GID_H_FORMAT + G1PPRL_LEN_H_FORMAT + G1PPRL_GCEFF_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_TYPE_H_FORMAT, + "groud-id", "num-regions", + "gc-eff", "liveness", + "remset", "type"); + + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX + G1PPRL_GID_H_FORMAT + G1PPRL_LEN_H_FORMAT + G1PPRL_GCEFF_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_BYTE_H_FORMAT + G1PPRL_TYPE_H_FORMAT, + "", "", + "(bytes/ms)", "%", + "(bytes)", ""); + + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1CSetCandidateGroup* young_only_cset_group =g1h->young_regions_cset_group(); + + _total_remset_bytes += young_only_cset_group->card_set()->mem_size(); + + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX + G1PPRL_GID_FORMAT + G1PPRL_LEN_FORMAT + G1PPRL_GCEFF_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_TYPE_H_FORMAT, + young_only_cset_group->group_id(), young_only_cset_group->length(), + "-", + size_t(0), young_only_cset_group->card_set()->mem_size(), + "Y"); + + for (G1CSetCandidateGroup* group : g1h->policy()->candidates()->from_marking_groups()) { + _total_remset_bytes += group->card_set()->mem_size(); + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX + G1PPRL_GID_FORMAT + G1PPRL_LEN_FORMAT + G1PPRL_GID_GCEFF_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_TYPE_H_FORMAT, + group->group_id(), group->length(), + group->gc_efficiency(), + group->liveness(), group->card_set()->mem_size(), + "M"); + } + + for (G1CSetCandidateGroup* group : g1h->policy()->candidates()->retained_groups()) { + _total_remset_bytes += group->card_set()->mem_size(); + log_trace(gc, liveness)(G1PPRL_LINE_PREFIX + G1PPRL_GID_FORMAT + G1PPRL_LEN_FORMAT + G1PPRL_GID_GCEFF_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_BYTE_FORMAT + G1PPRL_TYPE_H_FORMAT, + group->group_id(), group->length(), + group->gc_efficiency(), + group->liveness(), group->card_set()->mem_size(), + "R"); + } +} diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index fed624df85179..3ffa9fd9c7c96 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -973,8 +973,6 @@ class G1PrintRegionLivenessInfoClosure : public G1HeapRegionClosure { // Accumulator for the remembered set size size_t _total_remset_bytes; - size_t _young_cardset_bytes_per_region; - // Accumulator for code roots memory size size_t _total_code_roots_bytes; @@ -982,6 +980,8 @@ class G1PrintRegionLivenessInfoClosure : public G1HeapRegionClosure { return (double) val / (double) M; } + void do_cset_groups(); + public: // The header and footer are printed in the constructor and // destructor respectively. diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp index 039169794c543..c5ad269ae6902 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,7 @@ inline void G1CMMarkStack::iterate(Fn fn) const { TaskQueueEntryChunk* cur = _chunk_list; while (cur != nullptr) { - guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks); + guarantee(num_chunks <= _chunks_in_chunk_list, "Found %zu oop chunks which is more than there should be", num_chunks); for (size_t i = 0; i < EntriesPerChunk; ++i) { if (cur->data[i].is_null()) { diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp index d4200edcdcb1c..3d2e6c0f84906 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,9 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1HeapRegion.hpp" -#include "memory/virtualspace.hpp" G1CMBitMap::G1CMBitMap() : MarkBitMap(), _listener() { _listener.set_bitmap(this); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp index ee1b1d6555a36..7f62e5527d5df 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkObjArrayProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1ConcurrentMarkObjArrayProcessor.inline.hpp" @@ -48,7 +47,7 @@ size_t G1CMObjArrayProcessor::process_array_slice(objArrayOop obj, HeapWord* sta } size_t G1CMObjArrayProcessor::process_obj(oop obj) { - assert(should_be_sliced(obj), "Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), obj->size()); + assert(should_be_sliced(obj), "Must be an array object %d and large %zu", obj->is_objArray(), obj->size()); return process_array_slice(objArrayOop(obj), cast_from_oop(obj), objArrayOop(obj)->size()); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp index 37e76a73fe79c..83d547966ed47 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRebuildAndScrub.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRebuildAndScrub.cpp index f62d42069004f..993df8b47ce3d 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRebuildAndScrub.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRebuildAndScrub.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1ConcurrentRebuildAndScrub.hpp" diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index 8357737ef6a7d..2e48e438fc955 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1CollectionSet.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp index 3e8f83326b270..7f0bcc5b50fcc 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" G1ConcurrentRefineStats::G1ConcurrentRefineStats() : diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp index ed69ac08d1bf0..da1f85eba7343 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThreadsNeeded.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThreadsNeeded.cpp index b016ff87adca4..d34229bd35942 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThreadsNeeded.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThreadsNeeded.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,12 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1ConcurrentRefineThreadsNeeded.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1Policy.hpp" #include "utilities/globalDefinitions.hpp" + #include G1ConcurrentRefineThreadsNeeded::G1ConcurrentRefineThreadsNeeded(G1Policy* policy, diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index 96c212bd2ed28..a2b463ecb347f 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" #include "gc/g1/g1CardTableEntryClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" @@ -174,7 +173,7 @@ void G1DirtyCardQueueSet::verify_num_cards() const { actual += cur->size(); } assert(actual == Atomic::load(&_num_cards), - "Num entries in completed buffers should be " SIZE_FORMAT " but are " SIZE_FORMAT, + "Num entries in completed buffers should be %zu but are %zu", Atomic::load(&_num_cards), actual); } #endif // ASSERT diff --git a/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp b/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp index afc1602639a30..86ceb40e97edb 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BatchedTask.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1EvacStats.cpp b/src/hotspot/share/gc/g1/g1EvacStats.cpp index e632dd2eeddb2..b0e5f7b6864f2 100644 --- a/src/hotspot/share/gc/g1/g1EvacStats.cpp +++ b/src/hotspot/share/gc/g1/g1EvacStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1EvacStats.hpp" #include "gc/shared/gcId.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/share/gc/g1/g1FreeIdSet.cpp b/src/hotspot/share/gc/g1/g1FreeIdSet.cpp index e3cb99acf8da6..6ff863920df23 100644 --- a/src/hotspot/share/gc/g1/g1FreeIdSet.cpp +++ b/src/hotspot/share/gc/g1/g1FreeIdSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1FreeIdSet.hpp" #include "memory/allocation.inline.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.cpp b/src/hotspot/share/gc/g1/g1FromCardCache.cpp index 062130f40ab7f..4a29bcbc6dc41 100644 --- a/src/hotspot/share/gc/g1/g1FromCardCache.cpp +++ b/src/hotspot/share/gc/g1/g1FromCardCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1DirtyCardQueue.hpp" #include "gc/g1/g1FromCardCache.hpp" @@ -57,7 +56,7 @@ void G1FromCardCache::initialize(uint max_reserved_regions) { void G1FromCardCache::invalidate(uint start_idx, size_t new_num_regions) { guarantee((size_t)start_idx + new_num_regions <= max_uintx, - "Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT, + "Trying to invalidate beyond maximum region, from %u size %zu", start_idx, new_num_regions); uint end_idx = (start_idx + (uint)new_num_regions); assert(end_idx <= _max_reserved_regions, "Must be within max."); @@ -73,7 +72,7 @@ void G1FromCardCache::invalidate(uint start_idx, size_t new_num_regions) { void G1FromCardCache::print(outputStream* out) { for (uint i = 0; i < num_par_rem_sets(); i++) { for (uint j = 0; j < _max_reserved_regions; j++) { - out->print_cr("_from_card_cache[%u][%u] = " SIZE_FORMAT ".", + out->print_cr("_from_card_cache[%u][%u] = %zu.", i, j, at(i, j)); } } diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 5789b44e6189e..e9d6d23149fda 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1FullCollector.inline.hpp" @@ -247,7 +246,7 @@ void G1FullCollector::complete_collection() { _heap->resize_all_tlabs(); - _heap->young_regions_cardset()->clear(); + _heap->young_regions_cset_group()->clear(); _heap->policy()->record_full_collection_end(); _heap->gc_epilogue(true); diff --git a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp index 0d4adbe632e39..9a1dd4d1ff54e 100644 --- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/g1/g1CollectedHeap.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp index bee3656ead5e4..cc71cf861720b 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1FullCollector.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index ddd1b7c0999b8..d9d1957fc72bb 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCCompactionPoint.hpp" #include "gc/g1/g1HeapRegion.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp index 288331b398f7b..25002186280d8 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1FullCollector.hpp" #include "gc/g1/g1FullGCMarker.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.cpp b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp index 8fcc957b1682b..f3a8d23cbba3d 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/g1/g1FullGCMarker.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp b/src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp index ebc7852d150e7..d9cf64a365589 100644 --- a/src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1FullCollector.hpp" #include "gc/g1/g1FullGCMarker.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp index bed17e91ae9fb..86297086b444d 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1FullCollector.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp index 1d2a023ed3a64..f9868bba67893 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ inline bool G1DetermineCompactionQueueClosure::do_heap_region(G1HeapRegion* hr) // Too many live objects in the region; skip compacting it. _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); - log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, + log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: %zu", hr->hrm_index(), _collector->live_words(hr->hrm_index())); } diff --git a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp index 2022ff795256d..ae9a78a9cdfb9 100644 --- a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCResetMetadataTask.hpp" #include "utilities/ticks.hpp" @@ -37,7 +36,10 @@ void G1FullGCResetMetadataTask::G1ResetMetadataClosure::reset_region_metadata(G1 } bool G1FullGCResetMetadataTask::G1ResetMetadataClosure::do_heap_region(G1HeapRegion* hr) { - hr->uninstall_group_cardset(); + if (!hr->is_humongous()) { + hr->uninstall_cset_group(); + } + uint const region_idx = hr->hrm_index(); if (!_collector->is_compaction_target(region_idx)) { diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index 9352b7df2d9bf..5879442b82b12 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1FullGCScope.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCTask.cpp b/src/hotspot/share/gc/g1/g1FullGCTask.cpp index b9faa7af60375..633eae186e21e 100644 --- a/src/hotspot/share/gc/g1/g1FullGCTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1FullGCTask.hpp" #include "logging/log.hpp" #include "utilities/ticks.hpp" diff --git a/src/hotspot/share/gc/g1/g1GCCounters.cpp b/src/hotspot/share/gc/g1/g1GCCounters.cpp index bd9546e799164..9133b28d896ff 100644 --- a/src/hotspot/share/gc/g1/g1GCCounters.cpp +++ b/src/hotspot/share/gc/g1/g1GCCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1GCCounters.hpp" diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp index 4ec708ae09392..6d98dc220ffb0 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1GCParPhaseTimesTracker.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" @@ -405,7 +404,7 @@ void G1GCPhaseTimes::trace_time(const char* name, double value) const { } void G1GCPhaseTimes::trace_count(const char* name, size_t value) const { - log_trace(gc, phases)(" %s: " SIZE_FORMAT, name, value); + log_trace(gc, phases)(" %s: %zu", name, value); } double G1GCPhaseTimes::print_pre_evacuate_collection_set() const { diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.cpp b/src/hotspot/share/gc/g1/g1HeapRegion.cpp index 9cb2650f8208c..428b708fa5647 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" @@ -119,7 +118,7 @@ void G1HeapRegion::hr_clear(bool clear_space) { clear_young_index_in_cset(); clear_index_in_opt_cset(); uninstall_surv_rate_group(); - uninstall_group_cardset(); + uninstall_cset_group(); set_free(); reset_pre_dummy_top(); @@ -138,18 +137,6 @@ void G1HeapRegion::clear_cardtable() { ct->clear_MemRegion(MemRegion(bottom(), end())); } -double G1HeapRegion::calc_gc_efficiency() { - // GC efficiency is the ratio of how much space would be - // reclaimed over how long we predict it would take to reclaim it. - G1Policy* policy = G1CollectedHeap::heap()->policy(); - - // Retrieve a prediction of the elapsed time for this region for - // a mixed gc because the region will only be evacuated during a - // mixed gc. - double region_elapsed_time_ms = policy->predict_region_total_time_ms(this, false /* for_young_only_phase */); - return (double)reclaimable_bytes() / region_elapsed_time_ms; -} - void G1HeapRegion::set_free() { if (!is_free()) { report_region_type_change(G1HeapRegionTraceType::Free); @@ -192,6 +179,9 @@ void G1HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) { _type.set_starts_humongous(); _humongous_start_region = this; + G1CSetCandidateGroup* cset_group = new G1CSetCandidateGroup(); + cset_group->add(this); + _bot->update_for_block(bottom(), obj_top); if (fill_size > 0) { _bot->update_for_block(obj_top, obj_top + fill_size); @@ -212,12 +202,19 @@ void G1HeapRegion::clear_humongous() { assert(is_humongous(), "pre-condition"); assert(capacity() == G1HeapRegion::GrainBytes, "pre-condition"); + if (is_starts_humongous()) { + G1CSetCandidateGroup* cset_group = _rem_set->cset_group(); + assert(cset_group != nullptr, "pre-condition %u missing cardset", hrm_index()); + uninstall_cset_group(); + cset_group->clear(); + delete cset_group; + } _humongous_start_region = nullptr; } void G1HeapRegion::prepare_remset_for_scan() { if (is_young()) { - uninstall_group_cardset(); + uninstall_cset_group(); } _rem_set->reset_table_scanner(); } @@ -251,7 +248,7 @@ G1HeapRegion::G1HeapRegion(uint hrm_index, assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), "invalid space boundaries"); - _rem_set = new G1HeapRegionRemSet(this, config); + _rem_set = new G1HeapRegionRemSet(this); initialize(); } @@ -389,7 +386,7 @@ bool G1HeapRegion::verify_code_roots(VerifyOption vo) const { if (is_empty()) { bool has_code_roots = code_roots_length > 0; if (has_code_roots) { - log_error(gc, verify)("region " HR_FORMAT " is empty but has " SIZE_FORMAT " code root entries", + log_error(gc, verify)("region " HR_FORMAT " is empty but has %zu code root entries", HR_FORMAT_PARAMS(this), code_roots_length); } return has_code_roots; @@ -398,7 +395,7 @@ bool G1HeapRegion::verify_code_roots(VerifyOption vo) const { if (is_continues_humongous()) { bool has_code_roots = code_roots_length > 0; if (has_code_roots) { - log_error(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries", + log_error(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has %zu code root entries", HR_FORMAT_PARAMS(this), code_roots_length); } return has_code_roots; @@ -601,7 +598,9 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure { } bool failed() const { - if (_from != _to && !_from->is_young() && _to->rem_set()->is_complete()) { + if (_from != _to && !_from->is_young() && + _to->rem_set()->is_complete() && + _from->rem_set()->cset_group() != _to->rem_set()->cset_group()) { const CardValue dirty = G1CardTable::dirty_card_val(); return !(_to->rem_set()->contains_reference(this->_p) || (this->_containing_obj->is_objArray() ? diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.hpp b/src/hotspot/share/gc/g1/g1HeapRegion.hpp index c17183d40344b..fbf13e1b571d8 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.hpp @@ -40,6 +40,7 @@ class G1CardSet; class G1CardSetConfiguration; class G1CollectedHeap; class G1CMBitMap; +class G1CSetCandidateGroup; class G1Predictions; class G1HeapRegion; class G1HeapRegionRemSet; @@ -488,8 +489,6 @@ class G1HeapRegion : public CHeapObj { void set_index_in_opt_cset(uint index) { _index_in_opt_cset = index; } void clear_index_in_opt_cset() { _index_in_opt_cset = InvalidCSetIndex; } - double calc_gc_efficiency(); - uint young_index_in_cset() const { return _young_index_in_cset; } void clear_young_index_in_cset() { _young_index_in_cset = 0; } void set_young_index_in_cset(uint index) { @@ -509,8 +508,8 @@ class G1HeapRegion : public CHeapObj { void install_surv_rate_group(G1SurvRateGroup* surv_rate_group); void uninstall_surv_rate_group(); - void install_group_cardset(G1CardSet* group_cardset); - void uninstall_group_cardset(); + void install_cset_group(G1CSetCandidateGroup* cset_group); + void uninstall_cset_group(); void record_surv_words_in_group(size_t words_survived); diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp b/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp index 4a87c5f25141d..7c4342d3371a1 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp @@ -511,12 +511,12 @@ inline void G1HeapRegion::add_pinned_object_count(size_t value) { Atomic::add(&_pinned_object_count, value, memory_order_relaxed); } -inline void G1HeapRegion::install_group_cardset(G1CardSet* group_cardset) { - _rem_set->install_group_cardset(group_cardset); +inline void G1HeapRegion::install_cset_group(G1CSetCandidateGroup* cset_group) { + _rem_set->install_cset_group(cset_group); } -inline void G1HeapRegion::uninstall_group_cardset() { - _rem_set->uninstall_group_cardset(); +inline void G1HeapRegion::uninstall_cset_group() { + _rem_set->uninstall_cset_group(); } #endif // SHARE_GC_G1_G1HEAPREGION_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.cpp b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.cpp index 3be3ec2410c7e..79a2688e6b466 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1HeapRegionEventSender.hpp" diff --git a/src/hotspot/share/gc/g1/g1HeapRegionManager.cpp b/src/hotspot/share/gc/g1/g1HeapRegionManager.cpp index 9fb56f7c58fb2..016b2046265d8 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionManager.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Arguments.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp index c1343fd7dbffc..7852bb7e8e370 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CardSetContainers.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" @@ -53,52 +52,56 @@ void G1HeapRegionRemSet::initialize(MemRegion reserved) { _heap_base_address = reserved.start(); } -void G1HeapRegionRemSet::uninstall_group_cardset() { - if (_saved_card_set != nullptr) { - _card_set = _saved_card_set; - _saved_card_set = nullptr; - } +void G1HeapRegionRemSet::uninstall_cset_group() { + _cset_group = nullptr; } -G1HeapRegionRemSet::G1HeapRegionRemSet(G1HeapRegion* hr, - G1CardSetConfiguration* config) : +G1HeapRegionRemSet::G1HeapRegionRemSet(G1HeapRegion* hr) : _code_roots(), - _card_set_mm(config, G1CollectedHeap::heap()->card_set_freelist_pool()), - _card_set(new G1CardSet(config, &_card_set_mm)), - _saved_card_set(nullptr), + _cset_group(nullptr), _hr(hr), _state(Untracked) { } +G1HeapRegionRemSet::~G1HeapRegionRemSet() { + assert(!is_added_to_cset_group(), "Still assigned to a CSet group"); +} + void G1HeapRegionRemSet::clear_fcc() { G1FromCardCache::clear(_hr->hrm_index()); } void G1HeapRegionRemSet::clear(bool only_cardset, bool keep_tracked) { - assert(_saved_card_set == nullptr, "pre-condition"); if (!only_cardset) { _code_roots.clear(); } clear_fcc(); - _card_set->clear(); + + if (is_added_to_cset_group()) { + card_set()->clear(); + assert(card_set()->occupied() == 0, "Should be clear."); + } + if (!keep_tracked) { set_state_untracked(); } else { assert(is_tracked(), "must be"); } - assert(occupied() == 0, "Should be clear."); } void G1HeapRegionRemSet::reset_table_scanner() { _code_roots.reset_table_scanner(); - _card_set->reset_table_scanner(); + if (is_added_to_cset_group()) { + card_set()->reset_table_scanner(); + } } G1MonotonicArenaMemoryStats G1HeapRegionRemSet::card_set_memory_stats() const { - return _card_set_mm.memory_stats(); + assert(is_added_to_cset_group(), "pre-condition"); + return cset_group()->card_set_memory_stats(); } void G1HeapRegionRemSet::print_static_mem_size(outputStream* out) { - out->print_cr(" Static structures = " SIZE_FORMAT, G1HeapRegionRemSet::static_mem_size()); + out->print_cr(" Static structures = %zu", G1HeapRegionRemSet::static_mem_size()); } // Code roots support diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp index 843eb76bbc9c9..d2d502636faec 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp @@ -28,6 +28,7 @@ #include "gc/g1/g1CardSet.hpp" #include "gc/g1/g1CardSetMemory.hpp" #include "gc/g1/g1CodeRootSet.hpp" +#include "gc/g1/g1CollectionSetCandidates.hpp" #include "gc/g1/g1FromCardCache.hpp" #include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" @@ -35,6 +36,7 @@ #include "utilities/bitMap.hpp" class G1CardSetMemoryManager; +class G1CSetCandidateGroup; class outputStream; class G1HeapRegionRemSet : public CHeapObj { @@ -44,11 +46,8 @@ class G1HeapRegionRemSet : public CHeapObj { // the region that owns this RSet. G1CodeRootSet _code_roots; - G1CardSetMemoryManager _card_set_mm; - - // The set of cards in the Java heap - G1CardSet* _card_set; - G1CardSet* _saved_card_set; + // The collection set groups to which the region owning this RSet is assigned. + G1CSetCandidateGroup* _cset_group; G1HeapRegion* _hr; @@ -57,26 +56,48 @@ class G1HeapRegionRemSet : public CHeapObj { void clear_fcc(); + G1CardSet* card_set() { + assert(is_added_to_cset_group(), "pre-condition"); + return cset_group()->card_set(); + } + + const G1CardSet* card_set() const { + assert(is_added_to_cset_group(), "pre-condition"); + return cset_group()->card_set(); + } + public: - G1HeapRegionRemSet(G1HeapRegion* hr, G1CardSetConfiguration* config); - ~G1HeapRegionRemSet() { delete _card_set; } + G1HeapRegionRemSet(G1HeapRegion* hr); + ~G1HeapRegionRemSet(); bool cardset_is_empty() const { - return _card_set->is_empty(); + return !is_added_to_cset_group() || card_set()->is_empty(); } - void install_group_cardset(G1CardSet* group_cardset) { - assert(group_cardset != nullptr, "pre-condition"); - assert(_saved_card_set == nullptr, "pre-condition"); + void install_cset_group(G1CSetCandidateGroup* cset_group) { + assert(cset_group != nullptr, "pre-condition"); + assert(_cset_group == nullptr, "pre-condition"); - _saved_card_set = _card_set; - _card_set = group_cardset; + _cset_group = cset_group; } - void uninstall_group_cardset(); + void uninstall_cset_group(); + + bool is_added_to_cset_group() const { + return _cset_group != nullptr; + } - bool has_group_cardset() { - return _saved_card_set != nullptr; + G1CSetCandidateGroup* cset_group() { + return _cset_group; + } + + const G1CSetCandidateGroup* cset_group() const { + return _cset_group; + } + + uint cset_group_id() const { + assert(is_added_to_cset_group(), "pre-condition"); + return cset_group()->group_id(); } bool is_empty() const { @@ -84,7 +105,7 @@ class G1HeapRegionRemSet : public CHeapObj { } bool occupancy_less_or_equal_than(size_t occ) const { - return (code_roots_list_length() == 0) && _card_set->occupancy_less_or_equal_to(occ); + return (code_roots_list_length() == 0) && card_set()->occupancy_less_or_equal_to(occ); } // Iterate the card based remembered set for merging them into the card table. @@ -97,10 +118,10 @@ class G1HeapRegionRemSet : public CHeapObj { inline static void iterate_for_merge(G1CardSet* card_set, CardOrRangeVisitor& cl); size_t occupied() { - return _card_set->occupied(); + assert(is_added_to_cset_group(), "pre-condition"); + return card_set()->occupied(); } - G1CardSet* card_set() { return _card_set; } static void initialize(MemRegion reserved); @@ -146,13 +167,7 @@ class G1HeapRegionRemSet : public CHeapObj { // The actual # of bytes this hr_remset takes up. Also includes the code // root set. size_t mem_size() { - return _card_set->mem_size() - + (sizeof(G1HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. - + code_roots_mem_size(); - } - - size_t unused_mem_size() { - return _card_set->unused_mem_size(); + return sizeof(G1HeapRegionRemSet) + code_roots_mem_size(); } // Returns the memory occupancy of all static data structures associated diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp index 0df9874e9dd91..428586e160a88 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp @@ -108,7 +108,7 @@ class G1HeapRegionRemSetMergeCardClosure : public G1CardSet::ContainerPtrClosure template inline void G1HeapRegionRemSet::iterate_for_merge(CardOrRangeVisitor& cl) { - iterate_for_merge(_card_set, cl); + iterate_for_merge(card_set(), cl); } template @@ -125,6 +125,8 @@ uintptr_t G1HeapRegionRemSet::to_card(OopOrNarrowOopStar from) const { } void G1HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) { + assert(is_added_to_cset_group(), "pre-condition"); + assert(_state != Untracked, "must be"); uint cur_idx = _hr->hrm_index(); @@ -137,15 +139,15 @@ void G1HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) { return; } - _card_set->add_card(to_card(from)); + card_set()->add_card(to_card(from)); } bool G1HeapRegionRemSet::contains_reference(OopOrNarrowOopStar from) { - return _card_set->contains_card(to_card(from)); + return card_set()->contains_card(to_card(from)); } void G1HeapRegionRemSet::print_info(outputStream* st, OopOrNarrowOopStar from) { - _card_set->print_info(st, to_card(from)); + card_set()->print_info(st, to_card(from)); } #endif // SHARE_VM_GC_G1_G1HEAPREGIONREMSET_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1HeapRegionSet.cpp b/src/hotspot/share/gc/g1/g1HeapRegionSet.cpp index 38796239168ef..70186adcdfcee 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionSet.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1HeapRegionRemSet.inline.hpp" #include "gc/g1/g1HeapRegionSet.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1HeapRegionTracer.cpp b/src/hotspot/share/gc/g1/g1HeapRegionTracer.cpp index 749b7d2d1f5cc..2517b53c17c95 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionTracer.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegionTracer.hpp" #include "jfr/jfrEvents.hpp" diff --git a/src/hotspot/share/gc/g1/g1HeapRegionType.cpp b/src/hotspot/share/gc/g1/g1HeapRegionType.cpp index c6d38e341be33..ba6bf7e870de8 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionType.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegionTraceType.hpp" #include "gc/g1/g1HeapRegionType.hpp" diff --git a/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp b/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp index 0b7db7836d6a8..c35ce7c356d28 100644 --- a/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1HeapSizingPolicy.hpp" @@ -74,7 +73,7 @@ static void log_expansion(double short_term_pause_time_ratio, log_debug(gc, ergo, heap)("Heap expansion: " "short term pause time ratio %1.2f%% long term pause time ratio %1.2f%% " "threshold %1.2f%% pause time ratio %1.2f%% fully expanded %s " - "resize by " SIZE_FORMAT "B", + "resize by %zuB", short_term_pause_time_ratio * 100.0, long_term_pause_time_ratio * 100.0, threshold * 100.0, @@ -198,6 +197,14 @@ size_t G1HeapSizingPolicy::young_collection_expansion_amount() { } static size_t target_heap_capacity(size_t used_bytes, uintx free_ratio) { + assert(free_ratio <= 100, "precondition"); + if (free_ratio == 100) { + // If 100 then below calculations will divide by zero and return min of + // resulting infinity and MaxHeapSize. Avoid issues of UB vs is_iec559 + // and ubsan warnings, and just immediately return MaxHeapSize. + return MaxHeapSize; + } + const double desired_free_percentage = (double) free_ratio / 100.0; const double desired_used_percentage = 1.0 - desired_free_percentage; @@ -232,8 +239,8 @@ size_t G1HeapSizingPolicy::full_collection_resize_amount(bool& expand) { // This assert only makes sense here, before we adjust them // with respect to the min and max heap size. assert(minimum_desired_capacity <= maximum_desired_capacity, - "minimum_desired_capacity = " SIZE_FORMAT ", " - "maximum_desired_capacity = " SIZE_FORMAT, + "minimum_desired_capacity = %zu, " + "maximum_desired_capacity = %zu", minimum_desired_capacity, maximum_desired_capacity); // Should not be greater than the heap max size. No need to adjust @@ -250,8 +257,8 @@ size_t G1HeapSizingPolicy::full_collection_resize_amount(bool& expand) { size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; log_debug(gc, ergo, heap)("Attempt heap expansion (capacity lower than min desired capacity). " - "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B " - "min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", + "Capacity: %zuB occupancy: %zuB live: %zuB " + "min_desired_capacity: %zuB (%zu %%)", capacity_after_gc, used_after_gc, _g1h->used(), minimum_desired_capacity, MinHeapFreeRatio); expand = true; @@ -262,8 +269,8 @@ size_t G1HeapSizingPolicy::full_collection_resize_amount(bool& expand) { size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; log_debug(gc, ergo, heap)("Attempt heap shrinking (capacity higher than max desired capacity). " - "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B " - "maximum_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", + "Capacity: %zuB occupancy: %zuB live: %zuB " + "maximum_desired_capacity: %zuB (%zu %%)", capacity_after_gc, used_after_gc, _g1h->used(), maximum_desired_capacity, MaxHeapFreeRatio); expand = false; diff --git a/src/hotspot/share/gc/g1/g1HeapTransition.cpp b/src/hotspot/share/gc/g1/g1HeapTransition.cpp index 815b701c4be90..30ad4c72bf663 100644 --- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp +++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1HeapTransition.hpp" #include "gc/g1/g1Policy.hpp" @@ -96,7 +95,7 @@ class G1HeapTransition::DetailedUsageClosure: public G1HeapRegionClosure { _usage._humongous_used += r->used(); _usage._humongous_region_count++; } else { - assert(r->used() == 0, "Expected used to be 0 but it was " SIZE_FORMAT, r->used()); + assert(r->used() == 0, "Expected used to be 0 but it was %zu", r->used()); } return false; } @@ -109,7 +108,7 @@ static void log_regions(const char* msg, size_t before_length, size_t after_leng if (lt.is_enabled()) { LogStream ls(lt); - ls.print("%s regions: " SIZE_FORMAT "->" SIZE_FORMAT "(" SIZE_FORMAT ")", + ls.print("%s regions: %zu->%zu(%zu)", msg, before_length, after_length, capacity); // Not null only if gc+heap+numa at Debug level is enabled. if (before_per_node_length != nullptr && after_per_node_length != nullptr) { @@ -141,12 +140,12 @@ void G1HeapTransition::print() { DetailedUsageClosure blk; _g1_heap->heap_region_iterate(&blk); usage = blk._usage; - assert(usage._eden_region_count == 0, "Expected no eden regions, but got " SIZE_FORMAT, usage._eden_region_count); - assert(usage._survivor_region_count == after._survivor_length, "Expected survivors to be " SIZE_FORMAT " but was " SIZE_FORMAT, + assert(usage._eden_region_count == 0, "Expected no eden regions, but got %zu", usage._eden_region_count); + assert(usage._survivor_region_count == after._survivor_length, "Expected survivors to be %zu but was %zu", after._survivor_length, usage._survivor_region_count); - assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT, + assert(usage._old_region_count == after._old_length, "Expected old to be %zu but was %zu", after._old_length, usage._old_region_count); - assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, + assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be %zu but was %zu", after._humongous_length, usage._humongous_region_count); } @@ -156,17 +155,17 @@ void G1HeapTransition::print() { log_regions("Survivor", _before._survivor_length, after._survivor_length, survivor_capacity_length_before_gc, _before._survivor_length_per_node, after._survivor_length_per_node); - log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", + log_trace(gc, heap)(" Used: %zuK, Waste: %zuK", usage._survivor_used / K, ((after._survivor_length * G1HeapRegion::GrainBytes) - usage._survivor_used) / K); - log_info(gc, heap)("Old regions: " SIZE_FORMAT "->" SIZE_FORMAT, + log_info(gc, heap)("Old regions: %zu->%zu", _before._old_length, after._old_length); - log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", + log_trace(gc, heap)(" Used: %zuK, Waste: %zuK", usage._old_used / K, ((after._old_length * G1HeapRegion::GrainBytes) - usage._old_used) / K); - log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT, + log_info(gc, heap)("Humongous regions: %zu->%zu", _before._humongous_length, after._humongous_length); - log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", + log_trace(gc, heap)(" Used: %zuK, Waste: %zuK", usage._humongous_used / K, ((after._humongous_length * G1HeapRegion::GrainBytes) - usage._humongous_used) / K); MetaspaceUtils::print_metaspace_change(_before._meta_sizes); diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp index 7d399b8265e65..6bec1094579ad 100644 --- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1IHOPControl.cpp b/src/hotspot/share/gc/g1/g1IHOPControl.cpp index db8426d940139..5c05169c29ded 100644 --- a/src/hotspot/share/gc/g1/g1IHOPControl.cpp +++ b/src/hotspot/share/gc/g1/g1IHOPControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1IHOPControl.hpp" #include "gc/g1/g1Predictions.hpp" @@ -40,7 +39,7 @@ G1IHOPControl::G1IHOPControl(double initial_ihop_percent, } void G1IHOPControl::update_target_occupancy(size_t new_target_occupancy) { - log_debug(gc, ihop)("Target occupancy update: old: " SIZE_FORMAT "B, new: " SIZE_FORMAT "B", + log_debug(gc, ihop)("Target occupancy update: old: %zuB, new: %zuB", _target_occupancy, new_target_occupancy); _target_occupancy = new_target_occupancy; } @@ -54,8 +53,8 @@ void G1IHOPControl::update_allocation_info(double allocation_time_s, size_t addi void G1IHOPControl::print() { assert(_target_occupancy > 0, "Target occupancy still not updated yet."); size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold(); - log_debug(gc, ihop)("Basic information (value update), threshold: " SIZE_FORMAT "B (%1.2f), target occupancy: " SIZE_FORMAT "B, current occupancy: " SIZE_FORMAT "B, " - "recent allocation size: " SIZE_FORMAT "B, recent allocation duration: %1.2fms, recent old gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms", + log_debug(gc, ihop)("Basic information (value update), threshold: %zuB (%1.2f), target occupancy: %zuB, current occupancy: %zuB, " + "recent allocation size: %zuB, recent allocation duration: %1.2fms, recent old gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms", cur_conc_mark_start_threshold, percent_of(cur_conc_mark_start_threshold, _target_occupancy), _target_occupancy, @@ -169,8 +168,8 @@ void G1AdaptiveIHOPControl::update_marking_length(double marking_length_s) { void G1AdaptiveIHOPControl::print() { G1IHOPControl::print(); size_t actual_target = actual_target_threshold(); - log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: " SIZE_FORMAT "B (%1.2f), internal target occupancy: " SIZE_FORMAT "B, " - "occupancy: " SIZE_FORMAT "B, additional buffer size: " SIZE_FORMAT "B, predicted old gen allocation rate: %1.2fB/s, " + log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: %zuB (%1.2f), internal target occupancy: %zuB, " + "occupancy: %zuB, additional buffer size: %zuB, predicted old gen allocation rate: %1.2fB/s, " "predicted marking phase length: %1.2fms, prediction active: %s", get_conc_mark_start_threshold(), percent_of(get_conc_mark_start_threshold(), actual_target), diff --git a/src/hotspot/share/gc/g1/g1InitLogger.cpp b/src/hotspot/share/gc/g1/g1InitLogger.cpp index 2f5753f9ff6a5..1e09eed904315 100644 --- a/src/hotspot/share/gc/g1/g1InitLogger.cpp +++ b/src/hotspot/share/gc/g1/g1InitLogger.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1InitLogger.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" @@ -30,7 +29,7 @@ #include "utilities/globalDefinitions.hpp" void G1InitLogger::print_heap() { - log_info_p(gc, init)("Heap Region Size: " SIZE_FORMAT "M", G1HeapRegionSize / M); + log_info_p(gc, init)("Heap Region Size: %zuM", G1HeapRegionSize / M); GCInitLogger::print_heap(); } @@ -45,7 +44,7 @@ void G1InitLogger::print_gc_specific() { // Print a message about periodic GC configuration. if (G1PeriodicGCInterval != 0) { log_info_p(gc, init)("Periodic GC: Enabled"); - log_info_p(gc, init)("Periodic GC Interval: " UINTX_FORMAT "ms", G1PeriodicGCInterval); + log_info_p(gc, init)("Periodic GC Interval: %zums", G1PeriodicGCInterval); } else { log_info_p(gc, init)("Periodic GC: Disabled"); } diff --git a/src/hotspot/share/gc/g1/g1MMUTracker.cpp b/src/hotspot/share/gc/g1/g1MMUTracker.cpp index 24776a5334d99..391c165e82274 100644 --- a/src/hotspot/share/gc/g1/g1MMUTracker.cpp +++ b/src/hotspot/share/gc/g1/g1MMUTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1MMUTracker.hpp" #include "gc/g1/g1Trace.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/g1/g1MemoryPool.cpp b/src/hotspot/share/gc/g1/g1MemoryPool.cpp index ccff848192627..bc5f27617b1b9 100644 --- a/src/hotspot/share/gc/g1/g1MemoryPool.cpp +++ b/src/hotspot/share/gc/g1/g1MemoryPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1MemoryPool.hpp" diff --git a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp index 203ef473fa258..03bd1840206f7 100644 --- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp +++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1MonitoringSupport.hpp" #include "gc/g1/g1Policy.hpp" @@ -61,9 +60,9 @@ class G1YoungGenerationCounters : public G1GenerationCounters { } } - virtual void update_all() { + void update_all() { size_t committed = _monitoring_support->young_gen_committed(); - _current_size->set_value(committed); + GenerationCounters::update_all(committed); } }; @@ -82,9 +81,9 @@ class G1OldGenerationCounters : public G1GenerationCounters { } } - virtual void update_all() { + void update_all() { size_t committed = _monitoring_support->old_gen_committed(); - _current_size->set_value(committed); + GenerationCounters::update_all(committed); } }; @@ -285,12 +284,12 @@ void G1MonitoringSupport::recalculate_sizes() { _eden_space_used = MIN2(_eden_space_used, _eden_space_committed); // _survivor_space_used is calculated during a safepoint and _survivor_space_committed // is calculated from survivor region count * heap region size. - assert(_survivor_space_used <= _survivor_space_committed, "Survivor used bytes(" SIZE_FORMAT - ") should be less than or equal to survivor committed(" SIZE_FORMAT ")", + assert(_survivor_space_used <= _survivor_space_committed, "Survivor used bytes(%zu)" + " should be less than or equal to survivor committed(%zu)", _survivor_space_used, _survivor_space_committed); // _old_gen_committed is calculated in terms of _old_gen_used value. - assert(_old_gen_used <= _old_gen_committed, "Old gen used bytes(" SIZE_FORMAT - ") should be less than or equal to old gen committed(" SIZE_FORMAT ")", + assert(_old_gen_used <= _old_gen_committed, "Old gen used bytes(%zu)" + " should be less than or equal to old gen committed(%zu)", _old_gen_used, _old_gen_committed); } diff --git a/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp b/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp index 1f62b53d97c06..f22581ad9b152 100644 --- a/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp +++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp @@ -33,6 +33,8 @@ class CollectorCounters; class G1CollectedHeap; +class G1OldGenerationCounters; +class G1YoungGenerationCounters; class HSpaceCounters; class MemoryPool; @@ -146,10 +148,10 @@ class G1MonitoringSupport : public CHeapObj { // young collection set counters. The _eden_counters, // _from_counters, and _to_counters are associated with // this "generational" counter. - GenerationCounters* _young_gen_counters; + G1YoungGenerationCounters* _young_gen_counters; // old collection set counters. The _old_space_counters // below are associated with this "generational" counter. - GenerationCounters* _old_gen_counters; + G1OldGenerationCounters* _old_gen_counters; // Counters for the capacity and used for // the whole heap HSpaceCounters* _old_space_counters; diff --git a/src/hotspot/share/gc/g1/g1MonotonicArena.cpp b/src/hotspot/share/gc/g1/g1MonotonicArena.cpp index b2706d7a9463c..4c7a411d87867 100644 --- a/src/hotspot/share/gc/g1/g1MonotonicArena.cpp +++ b/src/hotspot/share/gc/g1/g1MonotonicArena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1MonotonicArena.inline.hpp" #include "memory/allocation.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/g1/g1MonotonicArenaFreeMemoryTask.cpp b/src/hotspot/share/gc/g1/g1MonotonicArenaFreeMemoryTask.cpp index 59a1afe6f3408..cc857a5396907 100644 --- a/src/hotspot/share/gc/g1/g1MonotonicArenaFreeMemoryTask.cpp +++ b/src/hotspot/share/gc/g1/g1MonotonicArenaFreeMemoryTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciUtilities.hpp" #include "gc/g1/g1CardSetMemory.inline.hpp" #include "gc/g1/g1CollectedHeap.hpp" diff --git a/src/hotspot/share/gc/g1/g1MonotonicArenaFreePool.cpp b/src/hotspot/share/gc/g1/g1MonotonicArenaFreePool.cpp index 76df02d2a7142..922c68bfba4a5 100644 --- a/src/hotspot/share/gc/g1/g1MonotonicArenaFreePool.cpp +++ b/src/hotspot/share/gc/g1/g1MonotonicArenaFreePool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1MonotonicArena.inline.hpp" #include "gc/g1/g1MonotonicArenaFreePool.hpp" diff --git a/src/hotspot/share/gc/g1/g1NMethodClosure.cpp b/src/hotspot/share/gc/g1/g1NMethodClosure.cpp index 379b1f935e103..8dca2d7cccf7b 100644 --- a/src/hotspot/share/gc/g1/g1NMethodClosure.cpp +++ b/src/hotspot/share/gc/g1/g1NMethodClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "gc/g1/g1NMethodClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1NUMA.cpp b/src/hotspot/share/gc/g1/g1NUMA.cpp index 923d3af621d70..cd7dc55d0fe5b 100644 --- a/src/hotspot/share/gc/g1/g1NUMA.cpp +++ b/src/hotspot/share/gc/g1/g1NUMA.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1NUMA.hpp" #include "gc/shared/gc_globals.hpp" #include "logging/logStream.hpp" @@ -215,7 +214,7 @@ void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint node_index = preferred_node_index_for_index(region_index); assert(is_aligned(aligned_address, page_size()), "Given address (" PTR_FORMAT ") should be aligned.", p2i(aligned_address)); - assert(is_aligned(size_in_bytes, page_size()), "Given size (" SIZE_FORMAT ") should be aligned.", size_in_bytes); + assert(is_aligned(size_in_bytes, page_size()), "Given size (%zu) should be aligned.", size_in_bytes); log_trace(gc, heap, numa)("Request memory [" PTR_FORMAT ", " PTR_FORMAT ") to be NUMA id (%u)", p2i(aligned_address), p2i((char*)aligned_address + size_in_bytes), _node_ids[node_index]); diff --git a/src/hotspot/share/gc/g1/g1NUMAStats.cpp b/src/hotspot/share/gc/g1/g1NUMAStats.cpp index 089e4c0e8b83a..aaebfa1be8f32 100644 --- a/src/hotspot/share/gc/g1/g1NUMAStats.cpp +++ b/src/hotspot/share/gc/g1/g1NUMAStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1NUMAStats.hpp" #include "logging/logStream.hpp" @@ -162,7 +161,7 @@ static const char* phase_to_explanatory_string(G1NUMAStats::NodeDataItems phase) } } -#define RATE_TOTAL_FORMAT "%0.0f%% " SIZE_FORMAT "/" SIZE_FORMAT +#define RATE_TOTAL_FORMAT "%0.0f%% %zu/%zu" void G1NUMAStats::print_info(G1NUMAStats::NodeDataItems phase) { LogTarget(Info, gc, heap, numa) lt; @@ -206,18 +205,18 @@ void G1NUMAStats::print_mutator_alloc_stat_debug() { for (uint req = 0; req < array_width; req++) { ls.print("%3d ", _node_ids[req]); for (uint alloc = 0; alloc < array_width; alloc++) { - ls.print(SIZE_FORMAT_W(8), _node_data[NewRegionAlloc]->get(req, alloc)); + ls.print("%8zu", _node_data[NewRegionAlloc]->get(req, alloc)); } - ls.print(SIZE_FORMAT_W(8), _node_data[NewRegionAlloc]->sum(req)); + ls.print("%8zu", _node_data[NewRegionAlloc]->sum(req)); ls.print_cr(""); // Add padding to align with the string 'Requested NUMA id'. ls.print(" "); } ls.print("Any "); for (uint alloc = 0; alloc < array_width; alloc++) { - ls.print(SIZE_FORMAT_W(8), _node_data[NewRegionAlloc]->get(array_width, alloc)); + ls.print("%8zu", _node_data[NewRegionAlloc]->get(array_width, alloc)); } - ls.print(SIZE_FORMAT_W(8), _node_data[NewRegionAlloc]->sum(array_width)); + ls.print("%8zu", _node_data[NewRegionAlloc]->sum(array_width)); ls.print_cr(""); } } diff --git a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp index 89ac76eef6079..ec3d39d7e5043 100644 --- a/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp +++ b/src/hotspot/share/gc/g1/g1OldGenAllocationTracker.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1OldGenAllocationTracker.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/g1/g1OopClosures.cpp b/src/hotspot/share/gc/g1/g1OopClosures.cpp index 9b30595e82f75..44085269d4554 100644 --- a/src/hotspot/share/gc/g1/g1OopClosures.cpp +++ b/src/hotspot/share/gc/g1/g1OopClosures.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1OopClosures.inline.hpp" #include "gc/g1/g1ParScanThreadState.hpp" diff --git a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp index 5b3bbedfeb289..5ab1f58bce11a 100644 --- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp +++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp @@ -150,7 +150,11 @@ inline void G1ConcurrentRefineOopClosure::do_oop_work(T* p) { assert(to_rem_set != nullptr, "Need per-region 'into' remsets."); if (to_rem_set->is_tracked()) { - to_rem_set->add_reference(p, _worker_id); + G1HeapRegion* from = _g1h->heap_region_containing(p); + + if (from->rem_set()->cset_group() != to_rem_set->cset_group()) { + to_rem_set->add_reference(p, _worker_id); + } } } @@ -268,7 +272,11 @@ template void G1RebuildRemSetClosure::do_oop_work(T* p) { G1HeapRegion* to = _g1h->heap_region_containing(obj); G1HeapRegionRemSet* rem_set = to->rem_set(); if (rem_set->is_tracked()) { - rem_set->add_reference(p, _worker_id); + G1HeapRegion* from = _g1h->heap_region_containing(p); + + if (from->rem_set()->cset_group() != rem_set->cset_group()) { + rem_set->add_reference(p, _worker_id); + } } } diff --git a/src/hotspot/share/gc/g1/g1OopStarChunkedList.cpp b/src/hotspot/share/gc/g1/g1OopStarChunkedList.cpp index 48f69d51db929..5d19503ad9c1b 100644 --- a/src/hotspot/share/gc/g1/g1OopStarChunkedList.cpp +++ b/src/hotspot/share/gc/g1/g1OopStarChunkedList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1OopStarChunkedList.inline.hpp" G1OopStarChunkedList::~G1OopStarChunkedList() { diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp index 41c4fc3a34cec..eb76106d91c82 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1PageBasedVirtualSpace.hpp" #include "gc/shared/pretouchTask.hpp" #include "gc/shared/workerThread.hpp" @@ -48,13 +47,13 @@ void G1PageBasedVirtualSpace::initialize_with_page_size(ReservedSpace rs, size_t vmassert(page_size > 0, "Page size must be non-zero."); guarantee(is_aligned(rs.base(), page_size), - "Reserved space base " PTR_FORMAT " is not aligned to requested page size " SIZE_FORMAT, p2i(rs.base()), page_size); + "Reserved space base " PTR_FORMAT " is not aligned to requested page size %zu", p2i(rs.base()), page_size); guarantee(is_aligned(used_size, os::vm_page_size()), - "Given used reserved space size needs to be OS page size aligned (" SIZE_FORMAT " bytes) but is " SIZE_FORMAT, os::vm_page_size(), used_size); + "Given used reserved space size needs to be OS page size aligned (%zu bytes) but is %zu", os::vm_page_size(), used_size); guarantee(used_size <= rs.size(), - "Used size of reserved space " SIZE_FORMAT " bytes is smaller than reservation at " SIZE_FORMAT " bytes", used_size, rs.size()); + "Used size of reserved space %zu bytes is smaller than reservation at %zu bytes", used_size, rs.size()); guarantee(is_aligned(rs.size(), page_size), - "Expected that the virtual space is size aligned, but " SIZE_FORMAT " is not aligned to page size " SIZE_FORMAT, rs.size(), page_size); + "Expected that the virtual space is size aligned, but %zu is not aligned to page size %zu", rs.size(), page_size); _low_boundary = rs.base(); _high_boundary = _low_boundary + used_size; @@ -121,15 +120,15 @@ size_t G1PageBasedVirtualSpace::page_size() const { bool G1PageBasedVirtualSpace::is_after_last_page(size_t index) const { guarantee(index <= _committed.size(), - "Given boundary page " SIZE_FORMAT " is beyond managed page count " SIZE_FORMAT, index, _committed.size()); + "Given boundary page %zu is beyond managed page count %zu", index, _committed.size()); return index == _committed.size(); } void G1PageBasedVirtualSpace::commit_preferred_pages(size_t start, size_t num_pages) { vmassert(num_pages > 0, "No full pages to commit"); vmassert(start + num_pages <= _committed.size(), - "Tried to commit area from page " SIZE_FORMAT " to page " SIZE_FORMAT " " - "that is outside of managed space of " SIZE_FORMAT " pages", + "Tried to commit area from page %zu to page %zu " + "that is outside of managed space of %zu pages", start, start + num_pages, _committed.size()); char* start_addr = page_start(start); @@ -147,9 +146,9 @@ void G1PageBasedVirtualSpace::commit_tail() { void G1PageBasedVirtualSpace::commit_internal(size_t start_page, size_t end_page) { guarantee(start_page < end_page, - "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page); + "Given start page %zu is larger or equal to end page %zu", start_page, end_page); guarantee(end_page <= _committed.size(), - "Given end page " SIZE_FORMAT " is beyond end of managed page amount of " SIZE_FORMAT, end_page, _committed.size()); + "Given end page %zu is beyond end of managed page amount of %zu", end_page, _committed.size()); size_t pages = end_page - start_page; bool need_to_commit_tail = is_after_last_page(end_page) && is_last_page_partial(); @@ -176,7 +175,7 @@ char* G1PageBasedVirtualSpace::bounded_end_addr(size_t end_page) const { bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { // We need to make sure to commit all pages covered by the given area. guarantee(is_area_uncommitted(start_page, size_in_pages), - "Specified area is not uncommitted, start page: " SIZE_FORMAT ", page count: " SIZE_FORMAT, + "Specified area is not uncommitted, start page: %zu, page count: %zu", start_page, size_in_pages); bool zero_filled = true; @@ -198,7 +197,7 @@ bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { void G1PageBasedVirtualSpace::uncommit_internal(size_t start_page, size_t end_page) { guarantee(start_page < end_page, - "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page); + "Given start page %zu is larger or equal to end page %zu", start_page, end_page); char* start_addr = page_start(start_page); os::uncommit_memory(start_addr, pointer_delta(bounded_end_addr(end_page), start_addr, sizeof(char))); @@ -206,7 +205,7 @@ void G1PageBasedVirtualSpace::uncommit_internal(size_t start_page, size_t end_pa void G1PageBasedVirtualSpace::uncommit(size_t start_page, size_t size_in_pages) { guarantee(is_area_committed(start_page, size_in_pages), - "Specified area is not committed, start page: " SIZE_FORMAT ", page count: " SIZE_FORMAT, + "Specified area is not committed, start page: %zu, page count: %zu", start_page, size_in_pages); size_t end_page = start_page + size_in_pages; @@ -236,9 +235,9 @@ void G1PageBasedVirtualSpace::print_on(outputStream* out) { out->print ("Virtual space:"); if (_special) out->print(" (pinned in memory)"); out->cr(); - out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); - out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); - out->print_cr(" - preferred page size: " SIZE_FORMAT, _page_size); + out->print_cr(" - committed: %zu", committed_size()); + out->print_cr(" - reserved: %zu", reserved_size()); + out->print_cr(" - preferred page size: %zu", _page_size); out->print_cr(" - [low_b, high_b]: [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(_low_boundary), p2i(_high_boundary)); } diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp index 52b8ebd31f2c2..303acf62d0b41 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,10 +26,10 @@ #define SHARE_GC_G1_G1PAGEBASEDVIRTUALSPACE_HPP #include "memory/memRegion.hpp" -#include "memory/virtualspace.hpp" #include "utilities/align.hpp" #include "utilities/bitMap.hpp" +class ReservedSpace; class WorkerThreads; // Virtual space management helper for a virtual space with an OS page allocation diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index f3b7e87bc784b..e8da6c50d8773 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSet.hpp" @@ -35,8 +34,9 @@ #include "gc/g1/g1Trace.hpp" #include "gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" +#include "gc/shared/partialArraySplitter.inline.hpp" #include "gc/shared/partialArrayState.hpp" -#include "gc/shared/partialArrayTaskStepper.inline.hpp" +#include "gc/shared/partialArrayTaskStats.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "memory/allocation.inline.hpp" @@ -80,10 +80,9 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _surviving_young_words(nullptr), _surviving_words_length(collection_set->young_region_length() + 1), _old_gen_is_full(false), - _partial_array_state_allocator(g1h->partial_array_state_manager()), - _partial_array_stepper(num_workers, ParGCArrayScanChunk), + _partial_array_splitter(g1h->partial_array_state_manager(), num_workers), _string_dedup_requests(), - _max_num_optional_regions(collection_set->optional_region_length()), + _max_num_optional_regions(collection_set->num_optional_regions()), _numa(g1h->numa()), _obj_alloc_stat(nullptr), ALLOCATION_FAILURE_INJECTOR_ONLY(_allocation_failure_inject_counter(0) COMMA) @@ -169,9 +168,12 @@ void G1ParScanThreadState::verify_task(oop* task) const { } void G1ParScanThreadState::verify_task(PartialArrayState* task) const { - // Must be in the collection set--it's already been copied. - oop p = task->source(); - assert(_g1h->is_in_cset(p), "p=" PTR_FORMAT, p2i(p)); + assert(task != nullptr, "invariant"); + // Source isn't used for processing, so not recorded in task. + assert(task->source() == nullptr, "invariant"); + oop p = task->destination(); + assert(_g1h->is_in_reserved(p), + "task=" PTR_FORMAT " dest=" PTR_FORMAT, p2i(task), p2i(p)); } void G1ParScanThreadState::verify_task(ScannerTask task) const { @@ -222,38 +224,17 @@ void G1ParScanThreadState::do_oop_evac(T* p) { } MAYBE_INLINE_EVACUATION -void G1ParScanThreadState::do_partial_array(PartialArrayState* state) { - oop to_obj = state->destination(); - -#ifdef ASSERT - oop from_obj = state->source(); - assert(_g1h->is_in_reserved(from_obj), "must be in heap."); - assert(from_obj->is_forwarded(), "must be forwarded"); - assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); - assert(to_obj->is_objArray(), "must be obj array"); -#endif // ASSERT - - objArrayOop to_array = objArrayOop(to_obj); - - // Claim a chunk and get number of additional tasks to enqueue. - PartialArrayTaskStepper::Step step = _partial_array_stepper.next(state); - // Push any additional partial scan tasks needed. Pushed before processing - // the claimed chunk to allow other workers to steal while we're processing. - if (step._ncreate > 0) { - state->add_references(step._ncreate); - for (uint i = 0; i < step._ncreate; ++i) { - push_on_queue(ScannerTask(state)); - } - } - +void G1ParScanThreadState::do_partial_array(PartialArrayState* state, bool stolen) { + // Access state before release by claim(). + objArrayOop to_array = objArrayOop(state->destination()); + PartialArraySplitter::Claim claim = + _partial_array_splitter.claim(state, _task_queue, stolen); G1HeapRegionAttr dest_attr = _g1h->region_attr(to_array); G1SkipCardEnqueueSetter x(&_scanner, dest_attr.is_new_survivor()); // Process claimed task. to_array->oop_iterate_range(&_scanner, - checked_cast(step._index), - checked_cast(step._index + _partial_array_stepper.chunk_size())); - // Release reference to the state, now that we're done with it. - _partial_array_state_allocator.release(state); + checked_cast(claim._start), + checked_cast(claim._end)); } MAYBE_INLINE_EVACUATION @@ -265,27 +246,10 @@ void G1ParScanThreadState::start_partial_objarray(G1HeapRegionAttr dest_attr, assert(to_obj->is_objArray(), "precondition"); objArrayOop to_array = objArrayOop(to_obj); - size_t array_length = to_array->length(); - PartialArrayTaskStepper::Step step = _partial_array_stepper.start(array_length); - - // Push any needed partial scan tasks. Pushed before processing the - // initial chunk to allow other workers to steal while we're processing. - if (step._ncreate > 0) { - assert(step._index < array_length, "invariant"); - assert(((array_length - step._index) % _partial_array_stepper.chunk_size()) == 0, - "invariant"); - PartialArrayState* state = - _partial_array_state_allocator.allocate(from_obj, to_obj, - step._index, - array_length, - step._ncreate); - for (uint i = 0; i < step._ncreate; ++i) { - push_on_queue(ScannerTask(state)); - } - } else { - assert(step._index == array_length, "invariant"); - } + size_t initial_chunk_size = + // The source array is unused when processing states. + _partial_array_splitter.start(_task_queue, nullptr, to_array, array_length); // Skip the card enqueue iff the object (to_array) is in survivor region. // However, G1HeapRegion::is_survivor() is too expensive here. @@ -296,18 +260,18 @@ void G1ParScanThreadState::start_partial_objarray(G1HeapRegionAttr dest_attr, // Process the initial chunk. No need to process the type in the // klass, as it will already be handled by processing the built-in // module. - to_array->oop_iterate_range(&_scanner, 0, checked_cast(step._index)); + to_array->oop_iterate_range(&_scanner, 0, checked_cast(initial_chunk_size)); } MAYBE_INLINE_EVACUATION -void G1ParScanThreadState::dispatch_task(ScannerTask task) { +void G1ParScanThreadState::dispatch_task(ScannerTask task, bool stolen) { verify_task(task); if (task.is_narrow_oop_ptr()) { do_oop_evac(task.to_narrow_oop_ptr()); } else if (task.is_oop_ptr()) { do_oop_evac(task.to_oop_ptr()); } else { - do_partial_array(task.to_partial_array_state()); + do_partial_array(task.to_partial_array_state(), stolen); } } @@ -320,11 +284,11 @@ void G1ParScanThreadState::trim_queue_to_threshold(uint threshold) { do { while (_task_queue->pop_overflow(task)) { if (!_task_queue->try_push_to_taskqueue(task)) { - dispatch_task(task); + dispatch_task(task, false); } } while (_task_queue->pop_local(task, threshold)) { - dispatch_task(task); + dispatch_task(task, false); } } while (!_task_queue->overflow_empty()); } @@ -333,7 +297,7 @@ ATTRIBUTE_FLATTEN void G1ParScanThreadState::steal_and_trim_queue(G1ScannerTasksQueueSet* task_queues) { ScannerTask stolen_task; while (task_queues->steal(_worker_id, stolen_task)) { - dispatch_task(stolen_task); + dispatch_task(stolen_task, true); // Processing stolen task may have added tasks to our queue. trim_queue(); } @@ -717,6 +681,14 @@ void G1ParScanThreadState::update_numa_stats(uint node_index) { } } +#if TASKQUEUE_STATS + +PartialArrayTaskStats* G1ParScanThreadState::partial_array_task_stats() { + return _partial_array_splitter.stats(); +} + +#endif // TASKQUEUE_STATS + G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, uint num_workers, G1CollectionSet* collection_set, @@ -744,3 +716,15 @@ G1ParScanThreadStateSet::~G1ParScanThreadStateSet() { FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_total); FREE_C_HEAP_ARRAY(BufferNodeList, _rdc_buffers); } + +#if TASKQUEUE_STATS + +void G1ParScanThreadStateSet::print_partial_array_task_stats() { + auto get_stats = [&](uint i) { + return state_for_worker(i)->partial_array_task_stats(); + }; + PartialArrayTaskStats::log_set(_num_workers, get_stats, + "Partial Array Task Stats"); +} + +#endif // TASKQUEUE_STATS diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index 27aa29ee30c98..f5dccaee9cf4b 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -32,8 +32,8 @@ #include "gc/shared/ageTable.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gc_globals.hpp" +#include "gc/shared/partialArraySplitter.hpp" #include "gc/shared/partialArrayState.hpp" -#include "gc/shared/partialArrayTaskStepper.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/taskqueue.hpp" #include "memory/allocation.hpp" @@ -84,8 +84,7 @@ class G1ParScanThreadState : public CHeapObj { // Indicates whether in the last generation (old) there is no more space // available for allocation. bool _old_gen_is_full; - PartialArrayStateAllocator _partial_array_state_allocator; - PartialArrayTaskStepper _partial_array_stepper; + PartialArraySplitter _partial_array_splitter; StringDedup::Requests _string_dedup_requests; G1CardTable* ct() { return _ct; } @@ -163,8 +162,12 @@ class G1ParScanThreadState : public CHeapObj { // HeapWords copied. size_t flush_stats(size_t* surviving_young_words, uint num_workers, BufferNodeList* buffer_log); +#if TASKQUEUE_STATS + PartialArrayTaskStats* partial_array_task_stats(); +#endif // TASKQUEUE_STATS + private: - void do_partial_array(PartialArrayState* state); + void do_partial_array(PartialArrayState* state, bool stolen); void start_partial_objarray(G1HeapRegionAttr dest_dir, oop from, oop to); HeapWord* allocate_copy_slow(G1HeapRegionAttr* dest_attr, @@ -187,7 +190,7 @@ class G1ParScanThreadState : public CHeapObj { // This method is applied to the fields of the objects that have just been copied. template void do_oop_evac(T* p); - void dispatch_task(ScannerTask task); + void dispatch_task(ScannerTask task, bool stolen); // Tries to allocate word_sz in the PLAB of the next "generation" after trying to // allocate into dest. Previous_plab_refill_failed indicates whether previous @@ -259,6 +262,9 @@ class G1ParScanThreadStateSet : public StackObj { void flush_stats(); void record_unused_optional_region(G1HeapRegion* hr); +#if TASKQUEUE_STATS + void print_partial_array_task_stats(); +#endif // TASKQUEUE_STATS G1ParScanThreadState* state_for_worker(uint worker_id); uint num_workers() const { return _num_workers; } diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp index f96a24007390c..148284e7ef7c1 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ inline void G1ParScanThreadState::remember_root_into_optional_region(T* p) { oop o = RawAccess::oop_load(p); uint index = _g1h->heap_region_containing(o)->index_in_opt_cset(); assert(index < _max_num_optional_regions, - "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _max_num_optional_regions); + "Trying to access optional region idx %u beyond %zu", index, _max_num_optional_regions); _oops_into_optional_regions[index].push_root(p); } @@ -84,14 +84,14 @@ inline void G1ParScanThreadState::remember_reference_into_optional_region(T* p) oop o = RawAccess::oop_load(p); uint index = _g1h->heap_region_containing(o)->index_in_opt_cset(); assert(index < _max_num_optional_regions, - "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _max_num_optional_regions); + "Trying to access optional region idx %u beyond %zu", index, _max_num_optional_regions); _oops_into_optional_regions[index].push_oop(p); verify_task(p); } G1OopStarChunkedList* G1ParScanThreadState::oops_into_optional_region(const G1HeapRegion* hr) { assert(hr->index_in_opt_cset() < _max_num_optional_regions, - "Trying to access optional region idx %u beyond " SIZE_FORMAT " " HR_FORMAT, + "Trying to access optional region idx %u beyond %zu " HR_FORMAT, hr->index_in_opt_cset(), _max_num_optional_regions, HR_FORMAT_PARAMS(hr)); return &_oops_into_optional_regions[hr->index_in_opt_cset()]; } diff --git a/src/hotspot/share/gc/g1/g1ParallelCleaning.cpp b/src/hotspot/share/gc/g1/g1ParallelCleaning.cpp index 3525f5764639d..a4c79cbed7a9a 100644 --- a/src/hotspot/share/gc/g1/g1ParallelCleaning.cpp +++ b/src/hotspot/share/gc/g1/g1ParallelCleaning.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1ParallelCleaning.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/g1/g1PeriodicGCTask.cpp b/src/hotspot/share/gc/g1/g1PeriodicGCTask.cpp index fea7c2f3c8687..afbd0f35ce6e6 100644 --- a/src/hotspot/share/gc/g1/g1PeriodicGCTask.cpp +++ b/src/hotspot/share/gc/g1/g1PeriodicGCTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" @@ -48,7 +47,7 @@ bool G1PeriodicGCTask::should_start_periodic_gc(G1CollectedHeap* g1h, // Check if enough time has passed since the last GC. uintx time_since_last_gc = (uintx)g1h->time_since_last_collection().milliseconds(); if ((time_since_last_gc < G1PeriodicGCInterval)) { - log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.", + log_debug(gc, periodic)("Last GC occurred %zums before which is below threshold %zums. Skipping.", time_since_last_gc, G1PeriodicGCInterval); return false; } diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index 1b71901f0fe05..8e81327b42df6 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Allocator.hpp" #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1Arguments.hpp" @@ -489,16 +488,15 @@ uint G1Policy::calculate_desired_eden_length_before_mixed(double base_time_ms, uint min_eden_length, uint max_eden_length) const { uint min_marking_candidates = MIN2(calc_min_old_cset_length(candidates()->last_marking_candidates_length()), - candidates()->marking_regions_length()); + candidates()->from_marking_groups().num_regions()); double predicted_region_evac_time_ms = base_time_ms; - for (G1CollectionSetCandidateInfo* ci : candidates()->marking_regions()) { - // We optimistically assume that any of these marking candidate regions will - // not be pinned, so just consider them as normal. - if (min_marking_candidates == 0) { + uint selected_candidates = 0; + for (G1CSetCandidateGroup* gr : candidates()->from_marking_groups()) { + if (selected_candidates >= min_marking_candidates) { break; } - predicted_region_evac_time_ms += predict_region_total_time_ms(ci->_r, false /* for_young_only_phase */); - min_marking_candidates--; + predicted_region_evac_time_ms += gr->predict_group_total_time_ms(); + selected_candidates += gr->length(); } return calculate_desired_eden_length_before_young_only(predicted_region_evac_time_ms, @@ -524,12 +522,13 @@ double G1Policy::predict_retained_regions_evac_time() const { double result = 0.0; - G1CollectionCandidateList& list = candidates()->retained_regions(); + G1CSetCandidateGroupList* retained_groups = &candidates()->retained_groups(); uint min_regions_left = MIN2(min_retained_old_cset_length(), - list.length()); + retained_groups->num_regions()); - for (G1CollectionSetCandidateInfo* ci : list) { - G1HeapRegion* r = ci->_r; + for (G1CSetCandidateGroup* group : *retained_groups) { + assert(group->length() == 1, "We should only have one region in a retained group"); + G1HeapRegion* r = group->region_at(0); // We only have one region per group. // We optimistically assume that any of these marking candidate regions will // be reclaimable the next gc, so just consider them as normal. if (r->has_pinned_objects()) { @@ -540,12 +539,12 @@ double G1Policy::predict_retained_regions_evac_time() const { break; } min_regions_left--; - result += predict_region_total_time_ms(r, collector_state()->in_young_only_phase()); + result += group->predict_group_total_time_ms(); num_regions++; } log_trace(gc, ergo, heap)("Selected %u of %u retained candidates (pinned %u) taking %1.3fms additional time", - num_regions, list.length(), num_pinned_regions, result); + num_regions, retained_groups->num_regions(), num_pinned_regions, result); return result; } @@ -606,8 +605,8 @@ void G1Policy::record_full_collection_end() { static void log_refinement_stats(const char* kind, const G1ConcurrentRefineStats& stats) { log_debug(gc, refine, stats) - ("%s refinement: %.2fms, refined: " SIZE_FORMAT - ", precleaned: " SIZE_FORMAT ", dirtied: " SIZE_FORMAT, + ("%s refinement: %.2fms, refined: %zu" + ", precleaned: %zu, dirtied: %zu", kind, stats.refinement_time().seconds() * MILLIUNITS, stats.refined_cards(), @@ -757,7 +756,7 @@ bool G1Policy::need_to_start_conc_mark(const char* source, size_t alloc_word_siz bool result = false; if (marking_request_bytes > marking_initiating_used_threshold) { result = collector_state()->in_young_only_phase(); - log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s", + log_debug(gc, ergo, ihop)("%s occupancy: %zuB allocation request: %zuB threshold: %zuB (%1.2f) source: %s", result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)", cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1h->capacity() * 100, source); } @@ -1112,6 +1111,10 @@ double G1Policy::predict_young_region_other_time_ms(uint count) const { return _analytics->predict_young_other_time_ms(count); } +double G1Policy::predict_non_young_other_time_ms(uint count) const { + return _analytics->predict_non_young_other_time_ms(count); +} + double G1Policy::predict_eden_copy_time_ms(uint count, size_t* bytes_to_copy) const { if (count == 0) { return 0.0; @@ -1128,13 +1131,12 @@ double G1Policy::predict_region_copy_time_ms(G1HeapRegion* hr, bool for_young_on return _analytics->predict_object_copy_time_ms(bytes_to_copy, for_young_only_phase); } -double G1Policy::predict_region_merge_scan_time(G1HeapRegion* hr, bool for_young_only_phase) const { - size_t card_rs_length = hr->rem_set()->occupied(); - size_t scan_card_num = _analytics->predict_scan_card_num(card_rs_length, for_young_only_phase); +double G1Policy::predict_merge_scan_time(size_t card_rs_length) const { + size_t scan_card_num = _analytics->predict_scan_card_num(card_rs_length, false); return - _analytics->predict_card_merge_time_ms(card_rs_length, for_young_only_phase) + - _analytics->predict_card_scan_time_ms(scan_card_num, for_young_only_phase); + _analytics->predict_card_merge_time_ms(card_rs_length, false) + + _analytics->predict_card_scan_time_ms(scan_card_num, false); } double G1Policy::predict_region_code_root_scan_time(G1HeapRegion* hr, bool for_young_only_phase) const { @@ -1144,27 +1146,6 @@ double G1Policy::predict_region_code_root_scan_time(G1HeapRegion* hr, bool for_y _analytics->predict_code_root_scan_time_ms(code_root_length, for_young_only_phase); } -double G1Policy::predict_region_non_copy_time_ms(G1HeapRegion* hr, - bool for_young_only_phase) const { - - double region_elapsed_time_ms = predict_region_merge_scan_time(hr, for_young_only_phase) + - predict_region_code_root_scan_time(hr, for_young_only_phase); - // The prediction of the "other" time for this region is based - // upon the region type and NOT the GC type. - if (hr->is_young()) { - region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1); - } else { - region_elapsed_time_ms += _analytics->predict_non_young_other_time_ms(1); - } - return region_elapsed_time_ms; -} - -double G1Policy::predict_region_total_time_ms(G1HeapRegion* hr, bool for_young_only_phase) const { - return - predict_region_non_copy_time_ms(hr, for_young_only_phase) + - predict_region_copy_time_ms(hr, for_young_only_phase); -} - bool G1Policy::should_allocate_mutator_region() const { uint young_list_length = _g1h->young_regions_count(); return young_list_length < young_list_target_length(); @@ -1340,11 +1321,6 @@ void G1Policy::record_concurrent_mark_cleanup_end(bool has_rebuilt_remembered_se } void G1Policy::abandon_collection_set_candidates() { - // Clear remembered sets of remaining candidate regions and the actual candidate - // set. - for (G1HeapRegion* r : *candidates()) { - r->rem_set()->clear(true /* only_cardset */); - } _collection_set->abandon_all_candidates(); } diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp index 6fcc3ed6b30e2..ca64f4c8c2337 100644 --- a/src/hotspot/share/gc/g1/g1Policy.hpp +++ b/src/hotspot/share/gc/g1/g1Policy.hpp @@ -46,10 +46,8 @@ class G1HeapRegion; class G1CollectionSet; -class G1CollectionCandidateList; class G1CollectionSetCandidates; class G1CollectionSetChooser; -class G1CollectionCandidateRegionList; class G1IHOPControl; class G1Analytics; class G1SurvivorRegions; @@ -140,7 +138,6 @@ class G1Policy: public CHeapObj { double predict_base_time_ms(size_t pending_cards, size_t card_rs_length) const; -private: // Base time contains handling remembered sets and constant other time of the // whole young gen, refinement buffers, and copying survivors. // Basically everything but copying eden regions. @@ -148,24 +145,16 @@ class G1Policy: public CHeapObj { // Copy time for a region is copying live data. double predict_region_copy_time_ms(G1HeapRegion* hr, bool for_young_only_phase) const; - // Merge-scan time for a region is handling card-based remembered sets of that region - // (as a single unit). - double predict_region_merge_scan_time(G1HeapRegion* hr, bool for_young_only_phase) const; // Code root scan time prediction for the given region. double predict_region_code_root_scan_time(G1HeapRegion* hr, bool for_young_only_phase) const; - // Non-copy time for a region is handling remembered sets and other time. - double predict_region_non_copy_time_ms(G1HeapRegion* hr, bool for_young_only_phase) const; - -public: + double predict_merge_scan_time(size_t card_rs_length) const; // Predict other time for count young regions. double predict_young_region_other_time_ms(uint count) const; + double predict_non_young_other_time_ms(uint count) const; // Predict copying live data time for count eden regions. Return the predict bytes if // bytes_to_copy is non-null. double predict_eden_copy_time_ms(uint count, size_t* bytes_to_copy = nullptr) const; - // Total time for a region is handling remembered sets (as a single unit), copying its live data - // and other time. - double predict_region_total_time_ms(G1HeapRegion* hr, bool for_young_only_phase) const; void cset_regions_freed() { bool update = should_update_surv_rate_group_predictors(); @@ -247,11 +236,11 @@ class G1Policy: public CHeapObj { // Limit the given desired young length to available free regions. uint calculate_young_target_length(uint desired_young_length) const; - size_t predict_bytes_to_copy(G1HeapRegion* hr) const; double predict_survivor_regions_evac_time() const; double predict_retained_regions_evac_time() const; public: + size_t predict_bytes_to_copy(G1HeapRegion* hr) const; size_t pending_cards_at_gc_start() const { return _pending_cards_at_gc_start; } // The minimum number of retained regions we will add to the CSet during a young GC. diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp index 59501447878b2..c89812ad08f28 100644 --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1RedirtyCardsQueue.hpp" #include "gc/shared/bufferNode.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp b/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp index e8b7c00b27e8b..eca0f78aed917 100644 --- a/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp +++ b/src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1RegionMarkStatsCache.inline.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp index 4403b4c8dd981..33a9df7934917 100644 --- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp +++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,12 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BiasedArray.hpp" #include "gc/g1/g1NUMA.hpp" #include "gc/g1/g1RegionToSpaceMapper.hpp" #include "gc/shared/gc_globals.hpp" #include "memory/allocation.inline.hpp" -#include "memory/virtualspace.hpp" +#include "memory/reservedSpace.hpp" #include "nmt/memTracker.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/align.hpp" @@ -91,7 +90,7 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper { virtual void commit_regions(uint start_idx, size_t num_regions, WorkerThreads* pretouch_workers) { guarantee(is_range_uncommitted(start_idx, num_regions), - "Range not uncommitted, start: %u, num_regions: " SIZE_FORMAT, + "Range not uncommitted, start: %u, num_regions: %zu", start_idx, num_regions); const size_t start_page = (size_t)start_idx * _pages_per_region; @@ -113,7 +112,7 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper { virtual void uncommit_regions(uint start_idx, size_t num_regions) { guarantee(is_range_committed(start_idx, num_regions), - "Range not committed, start: %u, num_regions: " SIZE_FORMAT, + "Range not committed, start: %u, num_regions: %zu", start_idx, num_regions); _storage.uncommit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region); diff --git a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp index 5ef0f8ec5ab51..823fa549f3688 100644 --- a/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp +++ b/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp @@ -29,6 +29,7 @@ #include "memory/allocation.hpp" #include "utilities/debug.hpp" +class ReservedSpace; class WorkerThreads; class G1MappingChangedListener { diff --git a/src/hotspot/share/gc/g1/g1RegionsOnNodes.cpp b/src/hotspot/share/gc/g1/g1RegionsOnNodes.cpp index b72d3687c6728..91f6ee4909524 100644 --- a/src/hotspot/share/gc/g1/g1RegionsOnNodes.cpp +++ b/src/hotspot/share/gc/g1/g1RegionsOnNodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1NUMA.hpp" #include "gc/g1/g1RegionsOnNodes.hpp" diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 7ae81de1d074f..beb73e7355aac 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BatchedTask.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" @@ -30,6 +29,7 @@ #include "gc/g1/g1CardTable.inline.hpp" #include "gc/g1/g1CardTableEntryClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1CollectionSet.inline.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1DirtyCardQueue.hpp" #include "gc/g1/g1FromCardCache.hpp" @@ -107,7 +107,7 @@ class G1RemSetScanState : public CHeapObj { // dirty card, i.e. actually needs scanning. bool chunk_needs_scan(uint const region_idx, uint const card_in_region) const { size_t const idx = ((size_t)region_idx << _log_scan_chunks_per_region) + (card_in_region >> _scan_chunks_shift); - assert(idx < _num_total_scan_chunks, "Index " SIZE_FORMAT " out of bounds " SIZE_FORMAT, + assert(idx < _num_total_scan_chunks, "Index %zu out of bounds %zu", idx, _num_total_scan_chunks); return _region_scan_chunks[idx]; } @@ -347,7 +347,7 @@ class G1RemSetScanState : public CHeapObj { void set_chunk_dirty(size_t const card_idx) { assert((card_idx >> _scan_chunks_shift) < _num_total_scan_chunks, - "Trying to access index " SIZE_FORMAT " out of bounds " SIZE_FORMAT, + "Trying to access index %zu out of bounds %zu", card_idx >> _scan_chunks_shift, _num_total_scan_chunks); size_t const chunk_idx = card_idx >> _scan_chunks_shift; _region_scan_chunks[chunk_idx] = true; @@ -1119,6 +1119,7 @@ class G1MergeHeapRootsTask : public WorkerTask { // This is needed to be able to use the bitmap for evacuation failure handling. class G1ClearBitmapClosure : public G1HeapRegionClosure { G1CollectedHeap* _g1h; + G1RemSetScanState* _scan_state; void assert_bitmap_clear(G1HeapRegion* hr, const G1CMBitMap* bitmap) { assert(bitmap->get_next_marked_addr(hr->bottom(), hr->end()) == hr->end(), @@ -1143,7 +1144,10 @@ class G1MergeHeapRootsTask : public WorkerTask { } public: - G1ClearBitmapClosure(G1CollectedHeap* g1h) : _g1h(g1h) { } + G1ClearBitmapClosure(G1CollectedHeap* g1h, G1RemSetScanState* scan_state) : + _g1h(g1h), + _scan_state(scan_state) + { } bool do_heap_region(G1HeapRegion* hr) { assert(_g1h->is_in_cset(hr), "Should only be used iterating the collection set"); @@ -1157,26 +1161,11 @@ class G1MergeHeapRootsTask : public WorkerTask { assert_bitmap_clear(hr, _g1h->concurrent_mark()->mark_bitmap()); } _g1h->concurrent_mark()->clear_statistics(hr); + _scan_state->add_all_dirty_region(hr->hrm_index()); return false; } }; - // Helper to allow two closure to be applied when - // iterating through the collection set. - class G1CombinedClosure : public G1HeapRegionClosure { - G1HeapRegionClosure* _closure1; - G1HeapRegionClosure* _closure2; - public: - G1CombinedClosure(G1HeapRegionClosure* cl1, G1HeapRegionClosure* cl2) : - _closure1(cl1), - _closure2(cl2) { } - - bool do_heap_region(G1HeapRegion* hr) { - return _closure1->do_heap_region(hr) || - _closure2->do_heap_region(hr); - } - }; - // Visitor for the remembered sets of humongous candidate regions to merge their // remembered set into the card table. class G1FlushHumongousCandidateRemSets : public G1HeapRegionIndexClosure { @@ -1277,6 +1266,7 @@ class G1MergeHeapRootsTask : public WorkerTask { }; uint _num_workers; + G1HeapRegionClaimer _hr_claimer; G1RemSetScanState* _scan_state; // To mitigate contention due multiple threads accessing and popping BufferNodes from a shared @@ -1306,6 +1296,7 @@ class G1MergeHeapRootsTask : public WorkerTask { G1MergeHeapRootsTask(G1RemSetScanState* scan_state, uint num_workers, bool initial_evacuation) : WorkerTask("G1 Merge Heap Roots"), _num_workers(num_workers), + _hr_claimer(num_workers), _scan_state(scan_state), _dirty_card_buffers(nullptr), _initial_evacuation(initial_evacuation), @@ -1395,14 +1386,13 @@ class G1MergeHeapRootsTask : public WorkerTask { { // 2. collection set G1MergeCardSetClosure merge(_scan_state); - G1ClearBitmapClosure clear(g1h); - G1CombinedClosure combined(&merge, &clear); if (_initial_evacuation) { G1HeapRegionRemSet::iterate_for_merge(g1h->young_regions_cardset(), merge); } - g1h->collection_set_iterate_increment_from(&combined, nullptr, worker_id); + g1h->collection_set()->merge_cardsets_for_collection_groups(merge, worker_id, _num_workers); + G1MergeCardSetStats stats = merge.stats(); for (uint i = 0; i < G1GCPhaseTimes::MergeRSContainersSentinel; i++) { @@ -1411,6 +1401,12 @@ class G1MergeHeapRootsTask : public WorkerTask { } } + // Preparation for evacuation failure handling. + { + G1ClearBitmapClosure clear(g1h, _scan_state); + g1h->collection_set_iterate_increment_from(&clear, &_hr_claimer, worker_id); + } + // Now apply the closure to all remaining log entries. if (_initial_evacuation) { assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase"); @@ -1438,7 +1434,7 @@ void G1RemSet::print_merge_heap_roots_stats() { size_t total_old_region_cards = (g1h->num_regions() - (g1h->num_free_regions() - g1h->collection_set()->cur_length())) * G1HeapRegion::CardsPerRegion; - ls.print_cr("Visited cards " SIZE_FORMAT " Total dirty " SIZE_FORMAT " (%.2lf%%) Total old " SIZE_FORMAT " (%.2lf%%)", + ls.print_cr("Visited cards %zu Total dirty %zu (%.2lf%%) Total old %zu (%.2lf%%)", num_visited_cards, total_dirty_region_cards, percent_of(num_visited_cards, total_dirty_region_cards), @@ -1471,11 +1467,21 @@ void G1RemSet::merge_heap_roots(bool initial_evacuation) { { G1MergeHeapRootsTask cl(_scan_state, num_workers, initial_evacuation); - log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " regions", + log_debug(gc, ergo)("Running %s using %u workers for %zu regions", cl.name(), num_workers, increment_length); workers->run_task(&cl, num_workers); } + { + size_t young_rs_length = g1h->young_regions_cardset()->occupied(); + // We only use young_rs_length statistics to estimate young regions length. + g1h->policy()->record_card_rs_length(young_rs_length); + + // Clear current young only collection set. Survivor regions will be added + // to the set during evacuation. + g1h->young_regions_cset_group()->clear(); + } + print_merge_heap_roots_stats(); } @@ -1504,7 +1510,7 @@ inline void check_card_ptr(CardTable::CardValue* card_ptr, G1CardTable* ct) { #ifdef ASSERT G1CollectedHeap* g1h = G1CollectedHeap::heap(); assert(g1h->is_in(ct->addr_for(card_ptr)), - "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap", + "Card at " PTR_FORMAT " index %zu representing heap at " PTR_FORMAT " (%u) must be in committed heap", p2i(card_ptr), ct->index_for(ct->addr_for(card_ptr)), p2i(ct->addr_for(card_ptr)), diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index 5ea3500a7b0f7..38f874d5359e0 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1CardSetMemory.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" @@ -153,29 +152,29 @@ class RegionTypeCounter { size_t code_root_elems() const { return _code_root_elems; } void print_rs_mem_info_on(outputStream * out, size_t total) { - out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) by " SIZE_FORMAT " " - "(" SIZE_FORMAT ") %s regions unused " SIZE_FORMAT, + out->print_cr(" %8zu (%5.1f%%) by %zu " + "(%zu) %s regions unused %zu", rs_mem_size(), rs_mem_size_percent_of(total), amount_tracked(), amount(), _name, rs_unused_mem_size()); } void print_cards_occupied_info_on(outputStream * out, size_t total) { - out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) entries by " SIZE_FORMAT " " - "(" SIZE_FORMAT ") %s regions", + out->print_cr(" %8zu (%5.1f%%) entries by %zu " + "(%zu) %s regions", cards_occupied(), cards_occupied_percent_of(total), amount_tracked(), amount(), _name); } void print_code_root_mem_info_on(outputStream * out, size_t total) { - out->print_cr(" " SIZE_FORMAT_W(8) "%s (%5.1f%%) by " SIZE_FORMAT " %s regions", + out->print_cr(" %8zu%s (%5.1f%%) by %zu %s regions", byte_size_in_proper_unit(code_root_mem_size()), proper_unit_for_byte_size(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); } void print_code_root_elems_info_on(outputStream * out, size_t total) { - out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) elements by " SIZE_FORMAT " %s regions", + out->print_cr(" %8zu (%5.1f%%) elements by %zu %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); } }; @@ -192,6 +191,12 @@ class HRRSStatsIter: public G1HeapRegionClosure { size_t _max_rs_mem_sz; G1HeapRegion* _max_rs_mem_sz_region; + size_t _max_code_root_mem_sz; + G1HeapRegion* _max_code_root_mem_sz_region; + + size_t _max_group_cardset_mem_sz; + G1CSetCandidateGroup* _max_cardset_mem_sz_group; + size_t total_rs_unused_mem_sz() const { return _all.rs_unused_mem_size(); } size_t total_rs_mem_sz() const { return _all.rs_mem_size(); } size_t total_cards_occupied() const { return _all.cards_occupied(); } @@ -199,8 +204,8 @@ class HRRSStatsIter: public G1HeapRegionClosure { size_t max_rs_mem_sz() const { return _max_rs_mem_sz; } G1HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; } - size_t _max_code_root_mem_sz; - G1HeapRegion* _max_code_root_mem_sz_region; + size_t max_group_cardset_mem_sz() const { return _max_group_cardset_mem_sz; } + G1CSetCandidateGroup* max_cardset_mem_sz_group() const { return _max_cardset_mem_sz_group; } size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); } size_t total_code_root_elems() const { return _all.code_root_elems(); } @@ -212,28 +217,29 @@ class HRRSStatsIter: public G1HeapRegionClosure { HRRSStatsIter() : _young("Young"), _humongous("Humongous"), _free("Free"), _old("Old"), _all("All"), _max_rs_mem_sz(0), _max_rs_mem_sz_region(nullptr), - _max_code_root_mem_sz(0), _max_code_root_mem_sz_region(nullptr) + _max_code_root_mem_sz(0), _max_code_root_mem_sz_region(nullptr), + _max_group_cardset_mem_sz(0), _max_cardset_mem_sz_group(nullptr) {} bool do_heap_region(G1HeapRegion* r) { G1HeapRegionRemSet* hrrs = r->rem_set(); - - size_t occupied_cards = hrrs->occupied(); - // G1HeapRegionRemSet::mem_size() includes the - // size of the code roots - size_t rs_unused_mem_sz = hrrs->unused_mem_size(); - size_t rs_mem_sz = hrrs->mem_size(); - - if (r->is_young()) { - uint num_young = G1CollectedHeap::heap()->young_regions_count(); - occupied_cards /= num_young; - rs_unused_mem_sz /= num_young; - rs_mem_sz /= num_young; - } - - if (rs_mem_sz > _max_rs_mem_sz) { - _max_rs_mem_sz = rs_mem_sz; - _max_rs_mem_sz_region = r; + size_t rs_mem_sz = 0; + size_t rs_unused_mem_sz = 0; + size_t occupied_cards = 0; + + // Accumulate card set details for regions that are assigned to single region + // groups. G1HeapRegionRemSet::mem_size() includes the size of the code roots + if (hrrs->is_added_to_cset_group() && hrrs->cset_group()->length() == 1) { + G1CardSet* card_set = hrrs->cset_group()->card_set(); + + rs_mem_sz = hrrs->mem_size() + card_set->mem_size(); + rs_unused_mem_sz = card_set->unused_mem_size(); + occupied_cards = hrrs->occupied(); + + if (rs_mem_sz > _max_rs_mem_sz) { + _max_rs_mem_sz = rs_mem_sz; + _max_rs_mem_sz_region = r; + } } size_t code_root_mem_sz = hrrs->code_roots_mem_size(); @@ -263,12 +269,53 @@ class HRRSStatsIter: public G1HeapRegionClosure { return false; } + void do_cset_groups() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1CSetCandidateGroup* young_only_cset_group = g1h->young_regions_cset_group(); + + // If the group has only a single region, then stats were accumulated + // during region iteration. + if (young_only_cset_group->length() > 1) { + G1CardSet* young_only_card_set = young_only_cset_group->card_set(); + size_t rs_mem_sz = young_only_card_set->mem_size(); + size_t rs_unused_mem_sz = young_only_card_set->unused_mem_size(); + size_t occupied_cards = young_only_card_set->occupied(); + + _max_group_cardset_mem_sz = rs_mem_sz; + _max_cardset_mem_sz_group = young_only_cset_group; + + // Only update cardset details + _young.add(rs_unused_mem_sz, rs_mem_sz, occupied_cards, 0, 0, false); + _all.add(rs_unused_mem_sz, rs_mem_sz, occupied_cards, 0, 0, false); + } + + + RegionTypeCounter* current = &_old; + for (G1CSetCandidateGroup* group : g1h->policy()->candidates()->from_marking_groups()) { + if (group->length() > 1) { + G1CardSet* group_card_set = group->card_set(); + size_t rs_mem_sz = group_card_set->mem_size(); + size_t rs_unused_mem_sz = group_card_set->unused_mem_size(); + size_t occupied_cards = group_card_set->occupied(); + + if (rs_mem_sz > _max_group_cardset_mem_sz) { + _max_group_cardset_mem_sz = rs_mem_sz; + _max_cardset_mem_sz_group = group; + } + + // Only update cardset details + _old.add(rs_unused_mem_sz, rs_mem_sz, occupied_cards, 0, 0, false); + _all.add(rs_unused_mem_sz, rs_mem_sz, occupied_cards, 0, 0, false); + } + } + } + void print_summary_on(outputStream* out) { RegionTypeCounter* counters[] = { &_young, &_humongous, &_free, &_old, nullptr }; out->print_cr(" Current rem set statistics"); - out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT - " Max = " SIZE_FORMAT " unused = " SIZE_FORMAT, + out->print_cr(" Total per region rem sets sizes = %zu" + " Max = %zu unused = %zu", total_rs_mem_sz(), max_rs_mem_sz(), total_rs_unused_mem_sz()); @@ -276,19 +323,30 @@ class HRRSStatsIter: public G1HeapRegionClosure { (*current)->print_rs_mem_info_on(out, total_rs_mem_sz()); } - out->print_cr(" " SIZE_FORMAT " occupied cards represented.", + out->print_cr(" %zu occupied cards represented.", total_cards_occupied()); for (RegionTypeCounter** current = &counters[0]; *current != nullptr; current++) { (*current)->print_cards_occupied_info_on(out, total_cards_occupied()); } - // Largest sized rem set region statistics - G1HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); - out->print_cr(" Region with largest rem set = " HR_FORMAT ", " - "size = " SIZE_FORMAT " occupied = " SIZE_FORMAT, - HR_FORMAT_PARAMS(max_rs_mem_sz_region()), - rem_set->mem_size(), - rem_set->occupied()); + // Largest sized single region rem set statistics + if (max_rs_mem_sz_region() != nullptr) { + G1HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); + out->print_cr(" Region with largest rem set = " HR_FORMAT ", " + "size = %zu occupied = %zu", + HR_FORMAT_PARAMS(max_rs_mem_sz_region()), + rem_set->mem_size(), + rem_set->occupied()); + } + + if (max_cardset_mem_sz_group() != nullptr) { + G1CSetCandidateGroup* cset_group = max_cardset_mem_sz_group(); + out->print_cr(" Collectionset Candidate Group with largest cardset = %u:(%u regions), " + "size = %zu occupied = %zu", + cset_group->group_id(), cset_group->length(), + cset_group->card_set()->mem_size(), + cset_group->card_set()->occupied()); + } G1HeapRegionRemSet::print_static_mem_size(out); G1CollectedHeap* g1h = G1CollectedHeap::heap(); @@ -296,8 +354,8 @@ class HRRSStatsIter: public G1HeapRegionClosure { // Code root statistics G1HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); - out->print_cr(" Total heap region code root sets sizes = " SIZE_FORMAT "%s." - " Max = " SIZE_FORMAT "%s.", + out->print_cr(" Total heap region code root sets sizes = %zu%s." + " Max = %zu%s.", byte_size_in_proper_unit(total_code_root_mem_sz()), proper_unit_for_byte_size(total_code_root_mem_sz()), byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), @@ -306,14 +364,14 @@ class HRRSStatsIter: public G1HeapRegionClosure { (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); } - out->print_cr(" " SIZE_FORMAT " code roots represented.", + out->print_cr(" %zu code roots represented.", total_code_root_elems()); for (RegionTypeCounter** current = &counters[0]; *current != nullptr; current++) { (*current)->print_code_root_elems_info_on(out, total_code_root_elems()); } out->print_cr(" Region with largest amount of code roots = " HR_FORMAT ", " - "size = " SIZE_FORMAT "%s, num_slots = " SIZE_FORMAT ".", + "size = %zu%s, num_slots = %zu.", HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), proper_unit_for_byte_size(max_code_root_rem_set->code_roots_mem_size()), @@ -330,8 +388,8 @@ void G1RemSetSummary::print_on(outputStream* out, bool show_thread_times) { } out->cr(); } - HRRSStatsIter blk; G1CollectedHeap::heap()->heap_region_iterate(&blk); + blk.do_cset_groups(); blk.print_summary_on(out); } diff --git a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp index 6538dffd998e8..a5c8882e05753 100644 --- a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSetChooser.hpp" #include "gc/g1/g1HeapRegion.inline.hpp" @@ -105,6 +104,17 @@ void G1RemSetTrackingPolicy::update_after_rebuild(G1HeapRegion* r) { r->rem_set()->clear(true /* only_cardset */); }); } + + size_t remset_bytes = r->rem_set()->mem_size(); + size_t occupied = 0; + // per region cardset details only valid if group contains a single region. + if (r->rem_set()->is_added_to_cset_group() && + r->rem_set()->cset_group()->length() == 1 ) { + G1CardSet *card_set = r->rem_set()->cset_group()->card_set(); + remset_bytes += card_set->mem_size(); + occupied = card_set->occupied(); + } + G1ConcurrentMark* cm = G1CollectedHeap::heap()->concurrent_mark(); log_trace(gc, remset, tracking)("After rebuild region %u " "(tams " PTR_FORMAT " " @@ -114,7 +124,7 @@ void G1RemSetTrackingPolicy::update_after_rebuild(G1HeapRegion* r) { r->hrm_index(), p2i(cm->top_at_mark_start(r)), cm->live_bytes(r->hrm_index()), - r->rem_set()->occupied(), - r->rem_set()->mem_size()); + occupied, + remset_bytes); } } diff --git a/src/hotspot/share/gc/g1/g1RootClosures.cpp b/src/hotspot/share/gc/g1/g1RootClosures.cpp index 7acc3adc83611..f03681487cbc7 100644 --- a/src/hotspot/share/gc/g1/g1RootClosures.cpp +++ b/src/hotspot/share/gc/g1/g1RootClosures.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1OopClosures.inline.hpp" #include "gc/g1/g1RootClosures.hpp" #include "gc/g1/g1SharedClosures.hpp" diff --git a/src/hotspot/share/gc/g1/g1RootProcessor.cpp b/src/hotspot/share/gc/g1/g1RootProcessor.cpp index 07ae66cfb0ba7..cf28c53648d74 100644 --- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp +++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp index 17a0f9326b5fe..f0b29a5bbaba1 100644 --- a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp +++ b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1HeapRegion.hpp" diff --git a/src/hotspot/share/gc/g1/g1ServiceThread.cpp b/src/hotspot/share/gc/g1/g1ServiceThread.cpp index 655220c349bbd..5f664cfba3a21 100644 --- a/src/hotspot/share/gc/g1/g1ServiceThread.cpp +++ b/src/hotspot/share/gc/g1/g1ServiceThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1ServiceThread.hpp" #include "logging/log.hpp" #include "runtime/cpuTimeCounters.hpp" diff --git a/src/hotspot/share/gc/g1/g1StringDedup.cpp b/src/hotspot/share/gc/g1/g1StringDedup.cpp index 6881c606114dd..97b15df537e33 100644 --- a/src/hotspot/share/gc/g1/g1StringDedup.cpp +++ b/src/hotspot/share/gc/g1/g1StringDedup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1StringDedup.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" diff --git a/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp b/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp index 40f15446fecc0..1eaaf44a1fbde 100644 --- a/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp +++ b/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1Predictions.hpp" #include "gc/g1/g1SurvRateGroup.hpp" diff --git a/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp b/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp index 53febea0a495b..dd3323f4079e2 100644 --- a/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp +++ b/src/hotspot/share/gc/g1/g1SurvivorRegions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1SurvivorRegions.hpp" #include "utilities/growableArray.hpp" diff --git a/src/hotspot/share/gc/g1/g1Trace.cpp b/src/hotspot/share/gc/g1/g1Trace.cpp index 598a238e93b92..3cc8a8a28e176 100644 --- a/src/hotspot/share/gc/g1/g1Trace.cpp +++ b/src/hotspot/share/gc/g1/g1Trace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1EvacInfo.hpp" #include "gc/g1/g1HeapRegionTraceType.hpp" #include "gc/g1/g1Trace.hpp" diff --git a/src/hotspot/share/gc/g1/g1UncommitRegionTask.cpp b/src/hotspot/share/gc/g1/g1UncommitRegionTask.cpp index 31ca32d9ea2f5..e1203229557a0 100644 --- a/src/hotspot/share/gc/g1/g1UncommitRegionTask.cpp +++ b/src/hotspot/share/gc/g1/g1UncommitRegionTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1UncommitRegionTask.hpp" #include "gc/shared/suspendibleThreadSet.hpp" @@ -82,7 +81,7 @@ void G1UncommitRegionTask::report_execution(Tickspan time, uint regions) { _summary_region_count += regions; _summary_duration += time; - log_trace(gc, heap)("Concurrent Uncommit: " SIZE_FORMAT "%s, %u regions, %1.3fms", + log_trace(gc, heap)("Concurrent Uncommit: %zu%s, %u regions, %1.3fms", byte_size_in_proper_unit(regions * G1HeapRegion::GrainBytes), proper_unit_for_byte_size(regions * G1HeapRegion::GrainBytes), regions, @@ -90,7 +89,7 @@ void G1UncommitRegionTask::report_execution(Tickspan time, uint regions) { } void G1UncommitRegionTask::report_summary() { - log_debug(gc, heap)("Concurrent Uncommit Summary: " SIZE_FORMAT "%s, %u regions, %1.3fms", + log_debug(gc, heap)("Concurrent Uncommit Summary: %zu%s, %u regions, %1.3fms", byte_size_in_proper_unit(_summary_region_count * G1HeapRegion::GrainBytes), proper_unit_for_byte_size(_summary_region_count * G1HeapRegion::GrainBytes), _summary_region_count, diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 634cdf6265fd4..9552bd6d41812 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" #include "gc/g1/g1Policy.hpp" diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index 13c4e9949ed82..2223d66799860 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "classfile/javaClasses.inline.hpp" @@ -273,7 +272,7 @@ void G1YoungCollector::calculate_collection_set(G1EvacInfo* evacuation_info, dou collection_set()->finalize_initial_collection_set(target_pause_time_ms, survivor_regions()); evacuation_info->set_collection_set_regions(collection_set()->region_length() + - collection_set()->optional_region_length()); + collection_set()->num_optional_regions()); concurrent_mark()->verify_no_collection_set_oops(); @@ -516,7 +515,7 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info) Tickspan task_time = run_task_timed(&g1_prep_task); G1MonotonicArenaMemoryStats sampled_card_set_stats = g1_prep_task.all_card_set_stats(); - sampled_card_set_stats.add(_g1h->young_regions_card_set_mm()->memory_stats()); + sampled_card_set_stats.add(_g1h->young_regions_card_set_memory_stats()); _g1h->set_young_gen_card_set_stats(sampled_card_set_stats); _g1h->set_humongous_stats(g1_prep_task.humongous_total(), g1_prep_task.humongous_candidates()); @@ -791,7 +790,7 @@ void G1YoungCollector::evacuate_next_optional_regions(G1ParScanThreadStateSet* p void G1YoungCollector::evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states) { const double collection_start_time_ms = phase_times()->cur_collection_start_sec() * 1000.0; - while (!evacuation_alloc_failed() && collection_set()->optional_region_length() > 0) { + while (!evacuation_alloc_failed() && collection_set()->num_optional_regions() > 0) { double time_used_ms = os::elapsedTime() * 1000.0 - collection_start_time_ms; double time_left_ms = MaxGCPauseMillis - time_used_ms; @@ -799,7 +798,7 @@ void G1YoungCollector::evacuate_optional_collection_set(G1ParScanThreadStateSet* if (time_left_ms < 0 || !collection_set()->finalize_optional_for_evacuation(time_left_ms * policy()->optional_evacuation_fraction())) { log_trace(gc, ergo, cset)("Skipping evacuation of %u optional regions, no more regions can be evacuated in %.3fms", - collection_set()->optional_region_length(), time_left_ms); + collection_set()->num_optional_regions(), time_left_ms); break; } @@ -990,9 +989,9 @@ void G1YoungCollector::enqueue_candidates_as_root_regions() { assert(collector_state()->in_concurrent_start_gc(), "must be"); G1CollectionSetCandidates* candidates = collection_set()->candidates(); - for (G1HeapRegion* r : *candidates) { + candidates->iterate_regions([&] (G1HeapRegion* r) { _g1h->concurrent_mark()->add_root_region(r); - } + }); } void G1YoungCollector::post_evacuate_collection_set(G1EvacInfo* evacuation_info, @@ -1013,6 +1012,12 @@ void G1YoungCollector::post_evacuate_collection_set(G1EvacInfo* evacuation_info, allocator()->release_gc_alloc_regions(evacuation_info); +#if TASKQUEUE_STATS + // Logging uses thread states, which are deleted by cleanup, so this must + // be done before cleanup. + per_thread_states->print_partial_array_task_stats(); +#endif // TASKQUEUE_STATS + post_evacuate_cleanup_1(per_thread_states); post_evacuate_cleanup_2(per_thread_states, evacuation_info); @@ -1106,7 +1111,7 @@ void G1YoungCollector::collect() { collection_set(), &_evac_failure_regions); - bool may_do_optional_evacuation = collection_set()->optional_region_length() != 0; + bool may_do_optional_evacuation = collection_set()->num_optional_regions() != 0; // Actually do the work... evacuate_initial_collection_set(&per_thread_states, may_do_optional_evacuation); diff --git a/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp index dcf42b31bb133..ceb859d249b79 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" - #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp index c72dcc9661821..4dfa026e42096 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "gc/g1/g1CardSetMemory.hpp" @@ -107,8 +106,12 @@ class G1PostEvacuateCollectionSetCleanupTask1::SampleCollectionSetCandidatesTask G1MonotonicArenaMemoryStats _total; G1CollectionSetCandidates* candidates = g1h->collection_set()->candidates(); - for (G1HeapRegion* r : *candidates) { - _total.add(r->rem_set()->card_set_memory_stats()); + for (G1CSetCandidateGroup* gr : candidates->from_marking_groups()) { + _total.add(gr->card_set_memory_stats()); + } + + for (G1CSetCandidateGroup* gr : candidates->retained_groups()) { + _total.add(gr->card_set_memory_stats()); } g1h->set_collection_set_candidates_stats(_total); } @@ -394,7 +397,7 @@ class G1FreeHumongousRegionClosure : public G1HeapRegionIndexClosure { "Only eagerly reclaiming type arrays is supported, but the object " PTR_FORMAT " is not.", p2i(r->bottom())); - log_debug(gc, humongous)("Reclaimed humongous region %u (object size " SIZE_FORMAT " @ " PTR_FORMAT ")", + log_debug(gc, humongous)("Reclaimed humongous region %u (object size %zu @ " PTR_FORMAT ")", region_index, obj->size() * HeapWordSize, p2i(r->bottom()) @@ -618,7 +621,6 @@ class FreeCSetStats { size_t _bytes_allocated_in_old_since_last_gc; // Size of young regions turned into old size_t _failure_used_words; // Live size in failed regions size_t _failure_waste_words; // Wasted size in failed regions - size_t _card_rs_length; // (Card Set) Remembered set size uint _regions_freed; // Number of regions freed public: @@ -628,7 +630,6 @@ class FreeCSetStats { _bytes_allocated_in_old_since_last_gc(0), _failure_used_words(0), _failure_waste_words(0), - _card_rs_length(0), _regions_freed(0) { } void merge_stats(FreeCSetStats* other) { @@ -638,7 +639,6 @@ class FreeCSetStats { _bytes_allocated_in_old_since_last_gc += other->_bytes_allocated_in_old_since_last_gc; _failure_used_words += other->_failure_used_words; _failure_waste_words += other->_failure_waste_words; - _card_rs_length += other->_card_rs_length; _regions_freed += other->_regions_freed; } @@ -653,10 +653,6 @@ class FreeCSetStats { G1Policy *policy = g1h->policy(); policy->old_gen_alloc_tracker()->add_allocated_bytes_since_last_gc(_bytes_allocated_in_old_since_last_gc); - // Add the cards from the group cardsets. - _card_rs_length += g1h->young_regions_cardset()->occupied(); - - policy->record_card_rs_length(_card_rs_length); policy->cset_regions_freed(); } @@ -682,10 +678,6 @@ class FreeCSetStats { _before_used_bytes += used; _regions_freed += 1; } - - void account_card_rs_length(G1HeapRegion* r) { - _card_rs_length += r->rem_set()->occupied(); - } }; // Closure applied to all regions in the collection set. @@ -807,8 +799,6 @@ class FreeCSetClosure : public G1HeapRegionClosure { if (r->is_young()) { - // We only use card_rs_length statistics to estimate young regions length. - stats()->account_card_rs_length(r); assert_tracks_surviving_words(r); r->record_surv_words_in_group(_surviving_young_words[r->young_index_in_cset()]); } @@ -895,8 +885,6 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 p->record_serial_free_cset_time_ms((Ticks::now() - serial_time).seconds() * 1000.0); _g1h->clear_collection_set(); - - _g1h->young_regions_cardset()->clear(); } double worker_cost() const override { return G1CollectedHeap::heap()->collection_set()->region_length(); } diff --git a/src/hotspot/share/gc/g1/g1YoungGCPreEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPreEvacuateTasks.cpp index d746062366966..63e7797981210 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPreEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPreEvacuateTasks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" - #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" #include "gc/g1/g1DirtyCardQueue.hpp" diff --git a/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp b/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp index 0c4b0b90df0aa..a8209eb19ba37 100644 --- a/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGenSizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1Arguments.hpp" #include "gc/g1/g1HeapRegion.hpp" #include "gc/g1/g1YoungGenSizer.hpp" @@ -44,8 +43,8 @@ G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), if (NewSize > MaxNewSize) { if (FLAG_IS_CMDLINE(MaxNewSize)) { - log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " - "A new max generation size of " SIZE_FORMAT "k will be used.", + log_warning(gc, ergo)("NewSize (%zuk) is greater than the MaxNewSize (%zuk). " + "A new max generation size of %zuk will be used.", NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(MaxNewSize, NewSize); diff --git a/src/hotspot/share/gc/g1/g1_globals.hpp b/src/hotspot/share/gc/g1/g1_globals.hpp index ed02ba2dc5cad..44d0d22257eed 100644 --- a/src/hotspot/share/gc/g1/g1_globals.hpp +++ b/src/hotspot/share/gc/g1/g1_globals.hpp @@ -277,6 +277,14 @@ "as a percentage of the heap size.") \ range(0, 100) \ \ + product(uint, G1OldCSetGroupSize, 5, EXPERIMENTAL, \ + "The maximum number of old CSet regions in a collection group. " \ + "All regions in a group will be evacuated in the same GC pause." \ + "The first group calculated after marking from marking " \ + "candidates may exceed this limit as it is calculated based on " \ + "G1MixedGCCountTarget.") \ + range(1, 256) \ + \ product(bool, G1VerifyHeapRegionCodeRoots, false, DIAGNOSTIC, \ "Verify the code root lists attached to each heap region.") \ \ diff --git a/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.cpp b/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.cpp index 0a29caed8ccd8..68da7400256a7 100644 --- a/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.cpp +++ b/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/g1/g1HeapRegionBounds.inline.hpp" #include "gc/g1/jvmFlagConstraintsG1.hpp" #include "gc/shared/bufferNode.hpp" @@ -83,7 +82,7 @@ JVMFlag::Error G1HeapRegionSizeConstraintFunc(size_t value, bool verbose) { // Default value of G1HeapRegionSize=0 means will be set ergonomically. if (FLAG_IS_CMDLINE(G1HeapRegionSize) && (value < G1HeapRegionBounds::min_size())) { JVMFlag::printError(verbose, - "G1HeapRegionSize (" SIZE_FORMAT ") must be " + "G1HeapRegionSize (%zu) must be " "greater than or equal to ergonomic heap region minimum size\n", value); return JVMFlag::VIOLATES_CONSTRAINT; @@ -123,8 +122,8 @@ JVMFlag::Error G1MaxNewSizePercentConstraintFunc(uint value, bool verbose) { JVMFlag::Error MaxGCPauseMillisConstraintFuncG1(uintx value, bool verbose) { if (UseG1GC && FLAG_IS_CMDLINE(MaxGCPauseMillis) && (value >= GCPauseIntervalMillis)) { JVMFlag::printError(verbose, - "MaxGCPauseMillis (" UINTX_FORMAT ") must be " - "less than GCPauseIntervalMillis (" UINTX_FORMAT ")\n", + "MaxGCPauseMillis (%zu) must be " + "less than GCPauseIntervalMillis (%zu)\n", value, GCPauseIntervalMillis); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -137,7 +136,7 @@ JVMFlag::Error GCPauseIntervalMillisConstraintFuncG1(uintx value, bool verbose) if (FLAG_IS_CMDLINE(GCPauseIntervalMillis)) { if (value < 1) { JVMFlag::printError(verbose, - "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " + "GCPauseIntervalMillis (%zu) must be " "greater than or equal to 1\n", value); return JVMFlag::VIOLATES_CONSTRAINT; @@ -152,8 +151,8 @@ JVMFlag::Error GCPauseIntervalMillisConstraintFuncG1(uintx value, bool verbose) if (value <= MaxGCPauseMillis) { JVMFlag::printError(verbose, - "GCPauseIntervalMillis (" UINTX_FORMAT ") must be " - "greater than MaxGCPauseMillis (" UINTX_FORMAT ")\n", + "GCPauseIntervalMillis (%zu) must be " + "greater than MaxGCPauseMillis (%zu)\n", value, MaxGCPauseMillis); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -171,7 +170,7 @@ JVMFlag::Error NewSizeConstraintFuncG1(size_t value, bool verbose) { // So maximum of NewSize should be 'max_juint * 1M' if (UseG1GC && (value > (max_juint * 1 * M))) { JVMFlag::printError(verbose, - "NewSize (" SIZE_FORMAT ") must be less than ergonomic maximum value\n", + "NewSize (%zu) must be less than ergonomic maximum value\n", value); return JVMFlag::VIOLATES_CONSTRAINT; } diff --git a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.cpp b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.cpp index 9f0b5961ea0e1..47c09befb400d 100644 --- a/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.cpp +++ b/src/hotspot/share/gc/parallel/gcAdaptivePolicyCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/gcAdaptivePolicyCounters.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.cpp b/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.cpp index 99c795341df8d..94e2d306165db 100644 --- a/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.cpp +++ b/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/jvmFlagConstraintsParallel.hpp" #include "gc/shared/gc_globals.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp b/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp index 06aa3d5fc72b2..874d3974ead53 100644 --- a/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp +++ b/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/mutableNUMASpace.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" @@ -99,7 +98,7 @@ void MutableNUMASpace::ensure_parsability() { while (words_left_to_fill > 0) { size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size()); assert(words_to_fill >= CollectedHeap::min_fill_size(), - "Remaining size (" SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")", + "Remaining size (%zu) is too small to fill (based on %zu and %zu)", words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size()); CollectedHeap::fill_with_object(cur_top, words_to_fill); cur_top += words_to_fill; @@ -619,8 +618,8 @@ void MutableNUMASpace::print_on(outputStream* st) const { for (int i = 0; i < lgrp_spaces()->length(); i++) { lgrp_spaces()->at(i)->accumulate_statistics(page_size()); } - st->print(" local/remote/unbiased/uncommitted: " SIZE_FORMAT "K/" - SIZE_FORMAT "K/" SIZE_FORMAT "K/" SIZE_FORMAT "K\n", + st->print(" local/remote/unbiased/uncommitted: %zuK/" + "%zuK/%zuK/%zuK\n", ls->space_stats()->_local_space / K, ls->space_stats()->_remote_space / K, ls->space_stats()->_unbiased_space / K, diff --git a/src/hotspot/share/gc/parallel/mutableSpace.cpp b/src/hotspot/share/gc/parallel/mutableSpace.cpp index 74801f4870b24..19ec0fcf83991 100644 --- a/src/hotspot/share/gc/parallel/mutableSpace.cpp +++ b/src/hotspot/share/gc/parallel/mutableSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/shared/pretouchTask.hpp" #include "gc/shared/spaceDecorator.hpp" @@ -233,7 +232,7 @@ void MutableSpace::object_iterate(ObjectClosure* cl) { void MutableSpace::print_short() const { print_short_on(tty); } void MutableSpace::print_short_on( outputStream* st) const { - st->print(" space " SIZE_FORMAT "K, %d%% used", capacity_in_bytes() / K, + st->print(" space %zuK, %d%% used", capacity_in_bytes() / K, (int) ((double) used_in_bytes() * 100 / capacity_in_bytes())); } diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp index 2a0f12ec70e72..e8d94b28d1879 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.cpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,9 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/shared/cardTableBarrierSet.hpp" -#include "nmt/memTracker.hpp" +#include "memory/memoryReserver.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "utilities/align.hpp" @@ -47,7 +46,7 @@ void ObjectStartArray::initialize(MemRegion reserved_region) { // Do not use large-pages for the backing store. The one large page region // will be used for the heap proper. - ReservedSpace backing_store(bytes_to_reserve, mtGC); + ReservedSpace backing_store = MemoryReserver::reserve(bytes_to_reserve, mtGC); if (!backing_store.is_reserved()) { vm_exit_during_initialization("Could not reserve space for ObjectStartArray"); } diff --git a/src/hotspot/share/gc/parallel/parMarkBitMap.cpp b/src/hotspot/share/gc/parallel/parMarkBitMap.cpp index 46a178500e576..f1d309807b5dc 100644 --- a/src/hotspot/share/gc/parallel/parMarkBitMap.cpp +++ b/src/hotspot/share/gc/parallel/parMarkBitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,10 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/parMarkBitMap.inline.hpp" #include "gc/parallel/psCompactionManager.inline.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" +#include "memory/memoryReserver.hpp" #include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" @@ -42,11 +42,19 @@ ParMarkBitMap::initialize(MemRegion covered_region) const size_t raw_bytes = words * sizeof(idx_t); const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10); const size_t granularity = os::vm_allocation_granularity(); - _reserved_byte_size = align_up(raw_bytes, MAX2(page_sz, granularity)); + const size_t rs_align = MAX2(page_sz, granularity); + + _reserved_byte_size = align_up(raw_bytes, rs_align); + + ReservedSpace rs = MemoryReserver::reserve(_reserved_byte_size, + rs_align, + page_sz); + + if (!rs.is_reserved()) { + // Failed to reserve memory for the bitmap, + return false; + } - const size_t rs_align = page_sz == os::vm_page_size() ? 0 : - MAX2(page_sz, granularity); - ReservedSpace rs(_reserved_byte_size, rs_align, page_sz); const size_t used_page_sz = rs.page_size(); os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, rs.base(), rs.size(), used_page_sz); @@ -54,23 +62,24 @@ ParMarkBitMap::initialize(MemRegion covered_region) MemTracker::record_virtual_memory_tag((address)rs.base(), mtGC); _virtual_space = new PSVirtualSpace(rs, page_sz); - if (_virtual_space != nullptr && _virtual_space->expand_by(_reserved_byte_size)) { - _heap_start = covered_region.start(); - _heap_size = covered_region.word_size(); - BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr(); - _beg_bits = BitMapView(map, bits); - return true; - } - _heap_start = nullptr; - _heap_size = 0; - if (_virtual_space != nullptr) { + if (!_virtual_space->expand_by(_reserved_byte_size)) { + // Failed to commit memory for the bitmap. + delete _virtual_space; - _virtual_space = nullptr; + // Release memory reserved in the space. - rs.release(); + MemoryReserver::release(rs); + + return false; } - return false; + + _heap_start = covered_region.start(); + _heap_size = covered_region.word_size(); + BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr(); + _beg_bits = BitMapView(map, bits); + + return true; } #ifdef ASSERT diff --git a/src/hotspot/share/gc/parallel/parallelArguments.cpp b/src/hotspot/share/gc/parallel/parallelArguments.cpp index d9972ccc146c6..6309f52c82ed2 100644 --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/parallelArguments.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/shared/adaptiveSizePolicy.hpp" diff --git a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp index 555b96e26319b..b6d1034f60a1c 100644 --- a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp +++ b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,16 +22,15 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/parallelInitLogger.hpp" #include "gc/shared/genArguments.hpp" #include "gc/shared/gcLogPrecious.hpp" void ParallelInitLogger::print_heap() { log_info_p(gc, init)("Alignments:" - " Space " SIZE_FORMAT "%s," - " Generation " SIZE_FORMAT "%s," - " Heap " SIZE_FORMAT "%s", + " Space %zu%s," + " Generation %zu%s," + " Heap %zu%s", byte_size_in_exact_unit(SpaceAlignment), exact_unit_for_byte_size(SpaceAlignment), byte_size_in_exact_unit(GenAlignment), exact_unit_for_byte_size(GenAlignment), byte_size_in_exact_unit(HeapAlignment), exact_unit_for_byte_size(HeapAlignment)); diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index f2693349b1f7b..24cc30e191811 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/parallel/parallelArguments.hpp" #include "gc/parallel/parallelInitLogger.hpp" @@ -45,8 +44,8 @@ #include "memory/iterator.hpp" #include "memory/metaspaceCounters.hpp" #include "memory/metaspaceUtils.hpp" +#include "memory/reservedSpace.hpp" #include "memory/universe.hpp" -#include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" #include "runtime/cpuTimeCounters.hpp" #include "runtime/handles.inline.hpp" @@ -74,7 +73,7 @@ jint ParallelScavengeHeap::initialize() { ReservedSpace young_rs = heap_rs.last_part(MaxOldSize, GenAlignment); assert(young_rs.size() == MaxNewSize, "Didn't reserve all of the heap"); - PSCardTable* card_table = new PSCardTable(heap_rs.region()); + PSCardTable* card_table = new PSCardTable(_reserved); card_table->initialize(old_rs.base(), young_rs.base()); CardTableBarrierSet* const barrier_set = new CardTableBarrierSet(card_table); @@ -130,7 +129,7 @@ jint ParallelScavengeHeap::initialize() { ParallelInitLogger::print(); - FullGCForwarding::initialize(heap_rs.region()); + FullGCForwarding::initialize(_reserved); return JNI_OK; } @@ -189,6 +188,7 @@ void ParallelScavengeHeap::post_initialize() { PSPromotionManager::initialize(); ScavengableNMethods::initialize(&_is_scavengable); + GCLocker::initialize(); } void ParallelScavengeHeap::update_counters() { @@ -289,7 +289,6 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, uint loop_count = 0; uint gc_count = 0; - uint gclocker_stalled_count = 0; while (result == nullptr) { // We don't want to have multiple collections for a single filled generation. @@ -319,37 +318,10 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, return result; } } - - if (gclocker_stalled_count > GCLockerRetryAllocationCount) { - return nullptr; - } - - // Failed to allocate without a gc. - if (GCLocker::is_active_and_needs_gc()) { - // If this thread is not in a jni critical section, we stall - // the requestor until the critical section has cleared and - // GC allowed. When the critical section clears, a GC is - // initiated by the last thread exiting the critical section; so - // we retry the allocation sequence from the beginning of the loop, - // rather than causing more, now probably unnecessary, GC attempts. - JavaThread* jthr = JavaThread::current(); - if (!jthr->in_critical()) { - MutexUnlocker mul(Heap_lock); - GCLocker::stall_until_clear(); - gclocker_stalled_count += 1; - continue; - } else { - if (CheckJNICalls) { - fatal("Possible deadlock due to allocating while" - " in jni critical section"); - } - return nullptr; - } - } } - if (result == nullptr) { - // Generate a VM operation + assert(result == nullptr, "inv"); + { VM_ParallelCollectForAllocation op(size, is_tlab, gc_count); VMThread::execute(&op); @@ -359,13 +331,6 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, if (op.prologue_succeeded()) { assert(is_in_or_null(op.result()), "result not in heap"); - // If GC was locked out during VM operation then retry allocation - // and/or stall as necessary. - if (op.gc_locked()) { - assert(op.result() == nullptr, "must be null if gc_locked() is true"); - continue; // retry and/or stall as necessary - } - // Exit the loop if the gc time limit has been exceeded. // The allocation must have failed above ("result" guarding // this path is null) and the most recent collection has exceeded the @@ -400,7 +365,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, if ((result == nullptr) && (QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { log_warning(gc)("ParallelScavengeHeap::mem_allocate retries %d times", loop_count); - log_warning(gc)("\tsize=" SIZE_FORMAT, size); + log_warning(gc)("\tsize=%zu", size); } } @@ -417,8 +382,8 @@ HeapWord* ParallelScavengeHeap::allocate_old_gen_and_record(size_t size) { } HeapWord* ParallelScavengeHeap::mem_allocate_old_gen(size_t size) { - if (!should_alloc_in_eden(size) || GCLocker::is_active_and_needs_gc()) { - // Size is too big for eden, or gc is locked out. + if (!should_alloc_in_eden(size)) { + // Size is too big for eden. return allocate_old_gen_and_record(size); } @@ -426,9 +391,6 @@ HeapWord* ParallelScavengeHeap::mem_allocate_old_gen(size_t size) { } void ParallelScavengeHeap::do_full_collection(bool clear_all_soft_refs) { - if (GCLocker::check_active_before_gc()) { - return; - } PSParallelCompact::invoke(clear_all_soft_refs); } @@ -447,11 +409,6 @@ HeapWord* ParallelScavengeHeap::satisfy_failed_allocation(size_t size, bool is_t HeapWord* result = nullptr; - GCLocker::check_active_before_gc(); - if (GCLocker::is_active_and_needs_gc()) { - return expand_heap_and_allocate(size, is_tlab); - } - // If young-gen can handle this allocation, attempt young-gc firstly. bool should_run_young_gc = is_tlab || should_alloc_in_eden(size); collect_at_safepoint(!should_run_young_gc); @@ -545,10 +502,6 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) { full_gc_count = total_full_collections(); } - if (GCLocker::should_discard(cause, gc_count)) { - return; - } - while (true) { VM_ParallelGCCollect op(gc_count, full_gc_count, cause); VMThread::execute(&op); @@ -563,20 +516,7 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) { return; } } - - if (GCLocker::is_active_and_needs_gc()) { - // If GCLocker is active, wait until clear before retrying. - GCLocker::stall_until_clear(); - } - } -} - -void ParallelScavengeHeap::try_collect_at_safepoint(bool full) { - assert(SafepointSynchronize::is_at_safepoint(), "precondition"); - if (GCLocker::check_active_before_gc()) { - return; } - collect_at_safepoint(full); } bool ParallelScavengeHeap::must_clear_all_soft_refs() { @@ -890,11 +830,11 @@ GrowableArray ParallelScavengeHeap::memory_pools() { } void ParallelScavengeHeap::pin_object(JavaThread* thread, oop obj) { - GCLocker::lock_critical(thread); + GCLocker::enter(thread); } void ParallelScavengeHeap::unpin_object(JavaThread* thread, oop obj) { - GCLocker::unlock_critical(thread); + GCLocker::exit(thread); } void ParallelScavengeHeap::update_parallel_worker_threads_cpu_time() { diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index 22d1296507d13..ef9a4b4d5a1f9 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -44,6 +44,7 @@ class MemoryPool; class PSAdaptiveSizePolicy; class PSCardTable; class PSHeapSummary; +class ReservedSpace; // ParallelScavengeHeap is the implementation of CollectedHeap for Parallel GC. // @@ -94,8 +95,6 @@ class ParallelScavengeHeap : public CollectedHeap { void update_parallel_worker_threads_cpu_time(); - void collect_at_safepoint(bool full); - bool must_clear_all_soft_refs(); HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) override; @@ -197,7 +196,7 @@ class ParallelScavengeHeap : public CollectedHeap { // Support for System.gc() void collect(GCCause::Cause cause) override; - void try_collect_at_safepoint(bool full); + void collect_at_safepoint(bool full); void ensure_parsability(bool retire_tlabs) override; void resize_all_tlabs() override; diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp index 288a21fd35d05..3bb0c0bf1192a 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psAdaptiveSizePolicy.hpp" #include "gc/parallel/psGCAdaptivePolicyCounters.hpp" @@ -315,12 +314,12 @@ void PSAdaptiveSizePolicy::compute_eden_space_size( if (desired_eden_size > eden_limit) { log_debug(gc, ergo)( "PSAdaptiveSizePolicy::compute_eden_space_size limits:" - " desired_eden_size: " SIZE_FORMAT - " old_eden_size: " SIZE_FORMAT - " eden_limit: " SIZE_FORMAT - " cur_eden: " SIZE_FORMAT - " max_eden_size: " SIZE_FORMAT - " avg_young_live: " SIZE_FORMAT, + " desired_eden_size: %zu" + " old_eden_size: %zu" + " eden_limit: %zu" + " cur_eden: %zu" + " max_eden_size: %zu" + " avg_young_live: %zu", desired_eden_size, _eden_size, eden_limit, cur_eden, max_eden_size, (size_t)avg_young_live()->average()); } @@ -358,14 +357,14 @@ void PSAdaptiveSizePolicy::compute_eden_space_size( _avg_major_interval->average(), gc_pause_goal_sec()); - log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT, + log_debug(gc, ergo)("Live_space: %zu free_space: %zu", live_space(), free_space()); - log_trace(gc, ergo)("avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, + log_trace(gc, ergo)("avg_young_live: %zu avg_old_live: %zu", (size_t)avg_young_live()->average(), (size_t)avg_old_live()->average()); - log_debug(gc, ergo)("Old eden_size: " SIZE_FORMAT " desired_eden_size: " SIZE_FORMAT, + log_debug(gc, ergo)("Old eden_size: %zu desired_eden_size: %zu", _eden_size, desired_eden_size); set_eden_size(desired_eden_size); @@ -492,11 +491,11 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space( size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average()); log_debug(gc, ergo)( "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:" - " desired_promo_size: " SIZE_FORMAT - " promo_limit: " SIZE_FORMAT - " free_in_old_gen: " SIZE_FORMAT - " max_old_gen_size: " SIZE_FORMAT - " avg_old_live: " SIZE_FORMAT, + " desired_promo_size: %zu" + " promo_limit: %zu" + " free_in_old_gen: %zu" + " max_old_gen_size: %zu" + " avg_old_live: %zu", desired_promo_size, promo_limit, free_in_old_gen, max_old_gen_size, (size_t) avg_old_live()->average()); } @@ -529,14 +528,14 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space( gc_pause_goal_sec()); // Footprint stats - log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT, + log_debug(gc, ergo)("Live_space: %zu free_space: %zu", live_space(), free_space()); - log_trace(gc, ergo)("avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, + log_trace(gc, ergo)("avg_young_live: %zu avg_old_live: %zu", (size_t)avg_young_live()->average(), (size_t)avg_old_live()->average()); - log_debug(gc, ergo)("Old promo_size: " SIZE_FORMAT " desired_promo_size: " SIZE_FORMAT, + log_debug(gc, ergo)("Old promo_size: %zu desired_promo_size: %zu", _promo_size, desired_promo_size); set_promo_size(desired_promo_size); @@ -603,7 +602,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t* desired_promo_siz log_trace(gc, ergo)( "PSAdaptiveSizePolicy::adjust_promo_for_pause_time " "adjusting gen sizes for major pause (avg %f goal %f). " - "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT, + "desired_promo_size %zu promo delta %zu", _avg_major_pause->average(), gc_pause_goal_sec(), *desired_promo_size_ptr, promo_heap_delta); } @@ -620,7 +619,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t* desired_eden_size_ log_trace(gc, ergo)( "PSAdaptiveSizePolicy::adjust_eden_for_pause_time " "adjusting gen sizes for major pause (avg %f goal %f). " - "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT, + "desired_eden_size %zu eden delta %zu", _avg_major_pause->average(), gc_pause_goal_sec(), *desired_eden_size_ptr, eden_heap_delta); } @@ -636,7 +635,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc, return; } - log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_promo_for_throughput(is_full: %d, promo: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f", + log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_promo_for_throughput(is_full: %d, promo: %zu): mutator_cost %f major_gc_cost %f minor_gc_cost %f", is_full_gc, *desired_promo_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost()); // Tenured generation @@ -650,7 +649,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc, double scale_by_ratio = major_gc_cost() / gc_cost(); scaled_promo_heap_delta = (size_t) (scale_by_ratio * (double) promo_heap_delta); - log_trace(gc, ergo)("Scaled tenured increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT, + log_trace(gc, ergo)("Scaled tenured increment: %zu by %f down to %zu", promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta); } else if (major_gc_cost() >= 0.0) { // Scaling is not going to work. If the major gc time is the @@ -697,7 +696,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc, _old_gen_change_for_major_throughput++; } - log_trace(gc, ergo)("Adjusting tenured gen for throughput (avg %f goal %f). desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT , + log_trace(gc, ergo)("Adjusting tenured gen for throughput (avg %f goal %f). desired_promo_size %zu promo_delta %zu", mutator_cost(), _throughput_goal, *desired_promo_size_ptr, scaled_promo_heap_delta); @@ -715,7 +714,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc, return; } - log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_eden_for_throughput(is_full: %d, cur_eden: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f", + log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_eden_for_throughput(is_full: %d, cur_eden: %zu): mutator_cost %f major_gc_cost %f minor_gc_cost %f", is_full_gc, *desired_eden_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost()); // Young generation @@ -728,7 +727,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc, assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong"); scaled_eden_heap_delta = (size_t) (scale_by_ratio * (double) eden_heap_delta); - log_trace(gc, ergo)("Scaled eden increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT, + log_trace(gc, ergo)("Scaled eden increment: %zu by %f down to %zu", eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta); } else if (minor_gc_cost() >= 0.0) { // Scaling is not going to work. If the minor gc time is the @@ -774,7 +773,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc, _young_gen_change_for_minor_throughput++; } - log_trace(gc, ergo)("Adjusting eden for throughput (avg %f goal %f). desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT, + log_trace(gc, ergo)("Adjusting eden for throughput (avg %f goal %f). desired_eden_size %zu eden delta %zu", mutator_cost(), _throughput_goal, *desired_eden_size_ptr, scaled_eden_heap_delta); } @@ -791,9 +790,9 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint( log_trace(gc, ergo)( "AdaptiveSizePolicy::adjust_promo_for_footprint " "adjusting tenured gen for footprint. " - "starting promo size " SIZE_FORMAT - " reduced promo size " SIZE_FORMAT - " promo delta " SIZE_FORMAT, + "starting promo size %zu" + " reduced promo size %zu" + " promo delta %zu", desired_promo_size, reduced_size, change ); assert(reduced_size <= desired_promo_size, "Inconsistent result"); @@ -813,9 +812,9 @@ size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint( log_trace(gc, ergo)( "AdaptiveSizePolicy::adjust_eden_for_footprint " "adjusting eden for footprint. " - " starting eden size " SIZE_FORMAT - " reduced eden size " SIZE_FORMAT - " eden delta " SIZE_FORMAT, + " starting eden size %zu" + " reduced eden size %zu" + " eden delta %zu", desired_eden_size, reduced_size, change); assert(reduced_size <= desired_eden_size, "Inconsistent result"); @@ -947,12 +946,10 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold( // Finally, increment or decrement the tenuring threshold, as decided above. // We test for decrementing first, as we might have hit the target size // limit. - if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) { - if (tenuring_threshold > 1) { + if (!(AlwaysTenure || NeverTenure)) { + if (decr_tenuring_threshold && tenuring_threshold > 1) { tenuring_threshold--; - } - } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) { - if (tenuring_threshold < MaxTenuringThreshold) { + } else if (incr_tenuring_threshold && tenuring_threshold < MaxTenuringThreshold) { tenuring_threshold++; } } @@ -966,7 +963,7 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold( log_debug(gc, ergo)("avg_survived_padded_avg: %f", _avg_survived->padded_average()); log_trace(gc, ergo)("avg_promoted_avg: %f avg_promoted_dev: %f", avg_promoted()->average(), avg_promoted()->deviation()); - log_debug(gc, ergo)("avg_promoted_padded_avg: %f avg_pretenured_padded_avg: %f tenuring_thresh: %d target_size: " SIZE_FORMAT, + log_debug(gc, ergo)("avg_promoted_padded_avg: %f avg_pretenured_padded_avg: %f tenuring_thresh: %d target_size: %zu", avg_promoted()->padded_average(), _avg_pretenured->padded_average(), tenuring_threshold, target_size); @@ -989,7 +986,7 @@ void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow, } avg_promoted()->sample(promoted); - log_trace(gc, ergo)("AdaptiveSizePolicy::update_averages: survived: " SIZE_FORMAT " promoted: " SIZE_FORMAT " overflow: %s", + log_trace(gc, ergo)("AdaptiveSizePolicy::update_averages: survived: %zu promoted: %zu overflow: %s", survived, promoted, is_survivor_overflow ? "true" : "false"); } diff --git a/src/hotspot/share/gc/parallel/psCardTable.cpp b/src/hotspot/share/gc/parallel/psCardTable.cpp index b80a1b13b007f..f8841b9a164f5 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.cpp +++ b/src/hotspot/share/gc/parallel/psCardTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/parallel/parallelScavengeHeap.inline.hpp" #include "gc/parallel/psCardTable.hpp" @@ -122,13 +121,38 @@ class PSStripeShadowCardTable { const uint _card_shift; const uint _card_size; CardValue _table[PSCardTable::num_cards_in_stripe]; - const CardValue* _table_base; + uintptr_t _table_base; + + // Avoid UB pointer operations by using integers internally. + + static_assert(sizeof(uintptr_t) == sizeof(CardValue*), "simplifying assumption"); + static_assert(sizeof(CardValue) == 1, "simplifying assumption"); + + static uintptr_t iaddr(const void* p) { + return reinterpret_cast(p); + } + + uintptr_t compute_table_base(HeapWord* start) const { + uintptr_t offset = iaddr(start) >> _card_shift; + return iaddr(_table) - offset; + } + + void verify_card_inclusive(const CardValue* card) const { + assert(iaddr(card) >= iaddr(_table), "out of bounds"); + assert(iaddr(card) <= (iaddr(_table) + sizeof(_table)), "out of bounds"); + } + + void verify_card_exclusive(const CardValue* card) const { + assert(iaddr(card) >= iaddr(_table), "out of bounds"); + assert(iaddr(card) < (iaddr(_table) + sizeof(_table)), "out of bounds"); + } public: PSStripeShadowCardTable(PSCardTable* pst, HeapWord* const start, HeapWord* const end) : _card_shift(CardTable::card_shift()), _card_size(CardTable::card_size()), - _table_base(_table - (uintptr_t(start) >> _card_shift)) { + _table_base(compute_table_base(start)) + { size_t stripe_byte_size = pointer_delta(end, start) * HeapWordSize; size_t copy_length = align_up(stripe_byte_size, _card_size) >> _card_shift; // The end of the last stripe may not be card aligned as it is equal to old @@ -143,12 +167,16 @@ class PSStripeShadowCardTable { } HeapWord* addr_for(const CardValue* const card) { - assert(card >= _table && card <= &_table[PSCardTable::num_cards_in_stripe], "out of bounds"); - return (HeapWord*) ((card - _table_base) << _card_shift); + verify_card_inclusive(card); + uintptr_t addr = (iaddr(card) - _table_base) << _card_shift; + return reinterpret_cast(addr); } const CardValue* card_for(HeapWord* addr) { - return &_table_base[uintptr_t(addr) >> _card_shift]; + uintptr_t icard = _table_base + (iaddr(addr) >> _card_shift); + const CardValue* card = reinterpret_cast(icard); + verify_card_inclusive(card); + return card; } bool is_dirty(const CardValue* const card) { @@ -156,7 +184,7 @@ class PSStripeShadowCardTable { } bool is_clean(const CardValue* const card) { - assert(card >= _table && card < &_table[PSCardTable::num_cards_in_stripe], "out of bounds"); + verify_card_exclusive(card); return *card == PSCardTable::clean_card_val(); } diff --git a/src/hotspot/share/gc/parallel/psClosure.inline.hpp b/src/hotspot/share/gc/parallel/psClosure.inline.hpp index 7425b65739d16..5cc059a09f50d 100644 --- a/src/hotspot/share/gc/parallel/psClosure.inline.hpp +++ b/src/hotspot/share/gc/parallel/psClosure.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ class PSAdjustWeakRootsClosure final: public OopClosure { oop new_obj = o->forwardee(); if (log_develop_is_enabled(Trace, gc, scavenge)) { ResourceMark rm; // required by internal_name() - log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (" SIZE_FORMAT ")}", + log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%zu)}", "forwarding", new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); } diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp index 19bb22fb91523..f00e18c3297b9 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,14 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/objectStartArray.hpp" #include "gc/parallel/parMarkBitMap.inline.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psCompactionManager.inline.hpp" #include "gc/parallel/psOldGen.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" +#include "gc/shared/partialArraySplitter.inline.hpp" +#include "gc/shared/partialArrayState.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "logging/log.hpp" @@ -43,9 +44,9 @@ PSOldGen* ParCompactionManager::_old_gen = nullptr; ParCompactionManager** ParCompactionManager::_manager_array = nullptr; -ParCompactionManager::OopTaskQueueSet* ParCompactionManager::_oop_task_queues = nullptr; -ParCompactionManager::ObjArrayTaskQueueSet* ParCompactionManager::_objarray_task_queues = nullptr; +ParCompactionManager::PSMarkTasksQueueSet* ParCompactionManager::_marking_stacks = nullptr; ParCompactionManager::RegionTaskQueueSet* ParCompactionManager::_region_task_queues = nullptr; +PartialArrayStateManager* ParCompactionManager::_partial_array_state_manager = nullptr; ObjectStartArray* ParCompactionManager::_start_array = nullptr; ParMarkBitMap* ParCompactionManager::_mark_bitmap = nullptr; @@ -55,8 +56,10 @@ Monitor* ParCompactionManager::_shadow_region_monitor = nullptr; PreservedMarksSet* ParCompactionManager::_preserved_marks_set = nullptr; ParCompactionManager::ParCompactionManager(PreservedMarks* preserved_marks, - ReferenceProcessor* ref_processor) - : _mark_and_push_closure(this, ref_processor) { + ReferenceProcessor* ref_processor, + uint parallel_gc_threads) + :_partial_array_splitter(_partial_array_state_manager, parallel_gc_threads), + _mark_and_push_closure(this, ref_processor) { ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); @@ -79,8 +82,10 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { assert(_manager_array == nullptr, "Attempt to initialize twice"); _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads, mtGC); - _oop_task_queues = new OopTaskQueueSet(parallel_gc_threads); - _objarray_task_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); + assert(_partial_array_state_manager == nullptr, "Attempt to initialize twice"); + _partial_array_state_manager + = new PartialArrayStateManager(parallel_gc_threads); + _marking_stacks = new PSMarkTasksQueueSet(parallel_gc_threads); _region_task_queues = new RegionTaskQueueSet(parallel_gc_threads); _preserved_marks_set = new PreservedMarksSet(true); @@ -89,16 +94,15 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { // Create and register the ParCompactionManager(s) for the worker threads. for(uint i=0; iget(i), - PSParallelCompact::ref_processor()); - oop_task_queues()->register_queue(i, _manager_array[i]->oop_stack()); - _objarray_task_queues->register_queue(i, &_manager_array[i]->_objarray_stack); + PSParallelCompact::ref_processor(), + parallel_gc_threads); + marking_stacks()->register_queue(i, _manager_array[i]->marking_stack()); region_task_queues()->register_queue(i, _manager_array[i]->region_stack()); } _shadow_region_array = new (mtGC) GrowableArray(10, mtGC); _shadow_region_monitor = new Monitor(Mutex::nosafepoint, "CompactionManager_lock"); - } void ParCompactionManager::flush_all_string_dedup_requests() { @@ -115,42 +119,41 @@ ParCompactionManager::gc_thread_compaction_manager(uint index) { return _manager_array[index]; } -inline void ParCompactionManager::publish_and_drain_oop_tasks() { - oop obj; - while (oop_stack()->pop_overflow(obj)) { - if (!oop_stack()->try_push_to_taskqueue(obj)) { - follow_contents(obj); - } - } - while (oop_stack()->pop_local(obj)) { - follow_contents(obj); - } +void ParCompactionManager::push_objArray(oop obj) { + assert(obj->is_objArray(), "precondition"); + _mark_and_push_closure.do_klass(obj->klass()); + + objArrayOop obj_array = objArrayOop(obj); + size_t array_length = obj_array->length(); + size_t initial_chunk_size = + _partial_array_splitter.start(&_marking_stack, obj_array, nullptr, array_length); + follow_array(obj_array, 0, initial_chunk_size); } -bool ParCompactionManager::publish_or_pop_objarray_tasks(ObjArrayTask& task) { - while (_objarray_stack.pop_overflow(task)) { - if (!_objarray_stack.try_push_to_taskqueue(task)) { - return true; - } - } - return false; +void ParCompactionManager::process_array_chunk(PartialArrayState* state, bool stolen) { + // Access before release by claim(). + oop obj = state->source(); + PartialArraySplitter::Claim claim = + _partial_array_splitter.claim(state, &_marking_stack, stolen); + follow_array(objArrayOop(obj), claim._start, claim._end); } void ParCompactionManager::follow_marking_stacks() { + ScannerTask task; do { // First, try to move tasks from the overflow stack into the shared buffer, so // that other threads can steal. Otherwise process the overflow stack first. - publish_and_drain_oop_tasks(); - - // Process ObjArrays one at a time to avoid marking stack bloat. - ObjArrayTask task; - if (publish_or_pop_objarray_tasks(task) || - _objarray_stack.pop_local(task)) { - follow_array((objArrayOop)task.obj(), task.index()); + while (marking_stack()->pop_overflow(task)) { + if (!marking_stack()->try_push_to_taskqueue(task)) { + follow_contents(task, false); + } + } + while (marking_stack()->pop_local(task)) { + follow_contents(task, false); } - } while (!marking_stacks_empty()); + } while (!marking_stack_empty()); - assert(marking_stacks_empty(), "Sanity"); + assert(marking_stack_empty(), "Sanity"); } void ParCompactionManager::drain_region_stacks() { @@ -197,11 +200,32 @@ void ParCompactionManager::remove_all_shadow_regions() { _shadow_region_array->clear(); } + +#if TASKQUEUE_STATS +void ParCompactionManager::print_and_reset_taskqueue_stats() { + marking_stacks()->print_and_reset_taskqueue_stats("Marking Stacks"); + + auto get_pa_stats = [&](uint i) { + return _manager_array[i]->partial_array_task_stats(); + }; + PartialArrayTaskStats::log_set(ParallelGCThreads, get_pa_stats, + "Partial Array Task Stats"); + uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); + for (uint i = 0; i < parallel_gc_threads; ++i) { + get_pa_stats(i)->reset(); + } +} + +PartialArrayTaskStats* ParCompactionManager::partial_array_task_stats() { + return _partial_array_splitter.stats(); +} +#endif // TASKQUEUE_STATS + #ifdef ASSERT void ParCompactionManager::verify_all_marking_stack_empty() { uint parallel_gc_threads = ParallelGCThreads; for (uint i = 0; i < parallel_gc_threads; i++) { - assert(_manager_array[i]->marking_stacks_empty(), "Marking stack should be empty"); + assert(_manager_array[i]->marking_stack_empty(), "Marking stack should be empty"); } } diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index cd4eefe775b57..739d2cb1cc7e2 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -27,6 +27,9 @@ #include "classfile/classLoaderData.hpp" #include "gc/parallel/psParallelCompact.hpp" +#include "gc/shared/partialArraySplitter.hpp" +#include "gc/shared/partialArrayTaskStats.hpp" +#include "gc/shared/partialArrayState.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/taskqueue.hpp" @@ -64,26 +67,22 @@ class ParCompactionManager : public CHeapObj { friend class PCAddThreadRootsMarkingTaskClosure; private: - typedef OverflowTaskQueue OopTaskQueue; - typedef GenericTaskQueueSet OopTaskQueueSet; - - // 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB - #define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13)) - typedef OverflowTaskQueue ObjArrayTaskQueue; - typedef GenericTaskQueueSet ObjArrayTaskQueueSet; - #undef QUEUE_SIZE - typedef OverflowTaskQueue RegionTaskQueue; - typedef GenericTaskQueueSet RegionTaskQueueSet; + typedef OverflowTaskQueue PSMarkTaskQueue; + typedef GenericTaskQueueSet PSMarkTasksQueueSet; + typedef OverflowTaskQueue RegionTaskQueue; + typedef GenericTaskQueueSet RegionTaskQueueSet; static ParCompactionManager** _manager_array; - static OopTaskQueueSet* _oop_task_queues; - static ObjArrayTaskQueueSet* _objarray_task_queues; + static PSMarkTasksQueueSet* _marking_stacks; static ObjectStartArray* _start_array; static RegionTaskQueueSet* _region_task_queues; static PSOldGen* _old_gen; - OopTaskQueue _oop_stack; - ObjArrayTaskQueue _objarray_stack; + static PartialArrayStateManager* _partial_array_state_manager; + PartialArraySplitter _partial_array_splitter; + + PSMarkTaskQueue _marking_stack; + size_t _next_shadow_region; PCMarkAndPushClosure _mark_and_push_closure; @@ -109,23 +108,20 @@ class ParCompactionManager : public CHeapObj { static PSOldGen* old_gen() { return _old_gen; } static ObjectStartArray* start_array() { return _start_array; } - static OopTaskQueueSet* oop_task_queues() { return _oop_task_queues; } + static PSMarkTasksQueueSet* marking_stacks() { return _marking_stacks; } static void initialize(ParMarkBitMap* mbm); - void publish_and_drain_oop_tasks(); - // Try to publish all contents from the objArray task queue overflow stack to - // the shared objArray stack. - // Returns true and a valid task if there has not been enough space in the shared - // objArray stack, otherwise returns false and the task is invalid. - bool publish_or_pop_objarray_tasks(ObjArrayTask& task); - ParCompactionManager(PreservedMarks* preserved_marks, - ReferenceProcessor* ref_processor); + ReferenceProcessor* ref_processor, + uint parallel_gc_threads); // Array of task queues. Needed by the task terminator. static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; } - OopTaskQueue* oop_stack() { return &_oop_stack; } + + inline PSMarkTaskQueue* marking_stack() { return &_marking_stack; } + inline void push(PartialArrayState* stat); + void push_objArray(oop obj); // To collect per-region live-words in a worker local cache in order to // reduce threads contention. @@ -155,6 +151,11 @@ class ParCompactionManager : public CHeapObj { MarkingStatsCache* _marking_stats_cache; +#if TASKQUEUE_STATS + static void print_and_reset_taskqueue_stats(); + PartialArrayTaskStats* partial_array_task_stats(); +#endif // TASKQUEUE_STATS + public: static const size_t InvalidShadow = ~0; static size_t pop_shadow_region_mt_safe(PSParallelCompact::RegionData* region_ptr); @@ -189,7 +190,6 @@ class ParCompactionManager : public CHeapObj { // Save for later processing. Must not fail. inline void push(oop obj); - inline void push_objarray(oop objarray, size_t index); inline void push_region(size_t index); // Check mark and maybe push on marking stack. @@ -198,19 +198,19 @@ class ParCompactionManager : public CHeapObj { // Access function for compaction managers static ParCompactionManager* gc_thread_compaction_manager(uint index); - static bool steal(int queue_num, oop& t); - static bool steal_objarray(int queue_num, ObjArrayTask& t); + static bool steal(int queue_num, ScannerTask& t); static bool steal(int queue_num, size_t& region); - // Process tasks remaining on any marking stack + // Process tasks remaining on marking stack void follow_marking_stacks(); - inline bool marking_stacks_empty() const; + inline bool marking_stack_empty() const; // Process tasks remaining on any stack void drain_region_stacks(); - void follow_contents(oop obj); - void follow_array(objArrayOop array, int index); + inline void follow_contents(const ScannerTask& task, bool stolen); + inline void follow_array(objArrayOop array, size_t start, size_t end); + void process_array_chunk(PartialArrayState* state, bool stolen); class FollowStackClosure: public VoidClosure { private: @@ -234,8 +234,8 @@ class ParCompactionManager : public CHeapObj { static void verify_all_region_stack_empty() NOT_DEBUG_RETURN; }; -bool ParCompactionManager::marking_stacks_empty() const { - return _oop_stack.is_empty() && _objarray_stack.is_empty(); +bool ParCompactionManager::marking_stack_empty() const { + return _marking_stack.is_empty(); } #endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp index 94529d2742305..2c0b8480726ab 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp @@ -32,6 +32,8 @@ #include "gc/parallel/parMarkBitMap.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" #include "gc/parallel/psStringDedup.hpp" +#include "gc/shared/partialArrayState.hpp" +#include "gc/shared/partialArrayTaskStepper.inline.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "oops/access.inline.hpp" #include "oops/arrayOop.hpp" @@ -46,12 +48,8 @@ inline void PCMarkAndPushClosure::do_oop_work(T* p) { _compaction_manager->mark_and_push(p); } -inline bool ParCompactionManager::steal(int queue_num, oop& t) { - return oop_task_queues()->steal(queue_num, t); -} - -inline bool ParCompactionManager::steal_objarray(int queue_num, ObjArrayTask& t) { - return _objarray_task_queues->steal(queue_num, t); +inline bool ParCompactionManager::steal(int queue_num, ScannerTask& t) { + return marking_stacks()->steal(queue_num, t); } inline bool ParCompactionManager::steal(int queue_num, size_t& region) { @@ -59,14 +57,11 @@ inline bool ParCompactionManager::steal(int queue_num, size_t& region) { } inline void ParCompactionManager::push(oop obj) { - _oop_stack.push(obj); + marking_stack()->push(ScannerTask(obj)); } -void ParCompactionManager::push_objarray(oop obj, size_t index) -{ - ObjArrayTask task(obj, index); - assert(task.is_valid(), "bad ObjArrayTask"); - _objarray_stack.push(task); +inline void ParCompactionManager::push(PartialArrayState* stat) { + marking_stack()->push(ScannerTask(stat)); } void ParCompactionManager::push_region(size_t index) @@ -111,43 +106,38 @@ inline void ParCompactionManager::FollowStackClosure::do_void() { } template -inline void follow_array_specialized(objArrayOop obj, int index, ParCompactionManager* cm) { - const size_t len = size_t(obj->length()); - const size_t beg_index = size_t(index); - assert(beg_index < len || len == 0, "index too large"); - - const size_t stride = MIN2(len - beg_index, (size_t)ObjArrayMarkingStride); - const size_t end_index = beg_index + stride; +inline void follow_array_specialized(objArrayOop obj, size_t start, size_t end, ParCompactionManager* cm) { + assert(start <= end, "invariant"); T* const base = (T*)obj->base(); - T* const beg = base + beg_index; - T* const end = base + end_index; - - if (end_index < len) { - cm->push_objarray(obj, end_index); // Push the continuation. - } + T* const beg = base + start; + T* const chunk_end = base + end; // Push the non-null elements of the next stride on the marking stack. - for (T* e = beg; e < end; e++) { + for (T* e = beg; e < chunk_end; e++) { cm->mark_and_push(e); } } -inline void ParCompactionManager::follow_array(objArrayOop obj, int index) { +inline void ParCompactionManager::follow_array(objArrayOop obj, size_t start, size_t end) { if (UseCompressedOops) { - follow_array_specialized(obj, index, this); + follow_array_specialized(obj, start, end, this); } else { - follow_array_specialized(obj, index, this); + follow_array_specialized(obj, start, end, this); } } -inline void ParCompactionManager::follow_contents(oop obj) { - assert(PSParallelCompact::mark_bitmap()->is_marked(obj), "should be marked"); - - if (obj->is_objArray()) { - _mark_and_push_closure.do_klass(obj->klass()); - follow_array(objArrayOop(obj), 0); +inline void ParCompactionManager::follow_contents(const ScannerTask& task, bool stolen) { + if (task.is_partial_array_state()) { + assert(PSParallelCompact::mark_bitmap()->is_marked(task.to_partial_array_state()->source()), "should be marked"); + process_array_chunk(task.to_partial_array_state(), stolen); } else { - obj->oop_iterate(&_mark_and_push_closure); + oop obj = task.to_oop(); + assert(PSParallelCompact::mark_bitmap()->is_marked(obj), "should be marked"); + if (obj->is_objArray()) { + push_objArray(obj); + } else { + obj->oop_iterate(&_mark_and_push_closure); + } } } @@ -219,5 +209,4 @@ inline void ParCompactionManager::flush_and_destroy_marking_stats_cache() { delete _marking_stats_cache; _marking_stats_cache = nullptr; } - #endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_INLINE_HPP diff --git a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp index ed96c5c418157..561d6009d59f0 100644 --- a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp +++ b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/psGCAdaptivePolicyCounters.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/parallel/psGenerationCounters.cpp b/src/hotspot/share/gc/parallel/psGenerationCounters.cpp deleted file mode 100644 index 1b0e8d320a93e..0000000000000 --- a/src/hotspot/share/gc/parallel/psGenerationCounters.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -/* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/psGenerationCounters.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/resourceArea.hpp" - -PSGenerationCounters::PSGenerationCounters(const char* name, - int ordinal, int spaces, - size_t min_capacity, - size_t max_capacity, - PSVirtualSpace* v): - _ps_virtual_space(v) { - - if (UsePerfData) { - - EXCEPTION_MARK; - ResourceMark rm; - - const char* cns = PerfDataManager::name_space("generation", ordinal); - - _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC); - strcpy(_name_space, cns); - - const char* cname = PerfDataManager::counter_name(_name_space, "name"); - PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "spaces"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, - spaces, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "minCapacity"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, - min_capacity, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, - max_capacity, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "capacity"); - _current_size = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, _ps_virtual_space->committed_size(), CHECK); - } -} diff --git a/src/hotspot/share/gc/parallel/psGenerationCounters.hpp b/src/hotspot/share/gc/parallel/psGenerationCounters.hpp deleted file mode 100644 index 60385965feb70..0000000000000 --- a/src/hotspot/share/gc/parallel/psGenerationCounters.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_PSGENERATIONCOUNTERS_HPP -#define SHARE_GC_PARALLEL_PSGENERATIONCOUNTERS_HPP - -#include "gc/parallel/psVirtualspace.hpp" -#include "gc/shared/generationCounters.hpp" -#include "runtime/perfData.hpp" - -// A PSGenerationCounter is a holder class for performance counters -// that track a generation - -class PSGenerationCounters: public GenerationCounters { - friend class VMStructs; - - private: - PSVirtualSpace* _ps_virtual_space; - - public: - PSGenerationCounters(const char* name, int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, PSVirtualSpace* v); - - void update_all() { - assert(_virtual_space == nullptr, "Only one should be in use"); - _current_size->set_value(_ps_virtual_space->committed_size()); - } -}; - -#endif // SHARE_GC_PARALLEL_PSGENERATIONCOUNTERS_HPP diff --git a/src/hotspot/share/gc/parallel/psMemoryPool.cpp b/src/hotspot/share/gc/parallel/psMemoryPool.cpp index cd92e86c98b57..c120664600bb1 100644 --- a/src/hotspot/share/gc/parallel/psMemoryPool.cpp +++ b/src/hotspot/share/gc/parallel/psMemoryPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/psMemoryPool.hpp" PSGenerationPool::PSGenerationPool(PSOldGen* old_gen, diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 52ea4dc042cbb..0a95a55b6481c 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/parallel/parallelArguments.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" @@ -114,8 +113,8 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) { // Generation Counters, generation 'level', 1 subspace - _gen_counters = new PSGenerationCounters(perf_data_name, level, 1, min_gen_size(), - max_gen_size(), virtual_space()); + _gen_counters = new GenerationCounters(perf_data_name, level, 1, min_gen_size(), + max_gen_size(), virtual_space()->committed_size()); _space_counters = new SpaceCounters(perf_data_name, 0, virtual_space()->reserved_size(), _object_space, _gen_counters); @@ -218,9 +217,6 @@ bool PSOldGen::expand(size_t bytes) { success = expand_to_reserved(); } - if (success && GCLocker::is_active_and_needs_gc()) { - log_debug(gc)("Garbage collection disabled, expanded heap instead"); - } return success; } @@ -244,14 +240,14 @@ bool PSOldGen::expand_by(size_t bytes) { post_resize(); if (UsePerfData) { _space_counters->update_capacity(); - _gen_counters->update_all(); + _gen_counters->update_all(_virtual_space->committed_size()); } } if (result) { size_t new_mem_size = virtual_space()->committed_size(); size_t old_mem_size = new_mem_size - bytes; - log_debug(gc)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", + log_debug(gc)("Expanding %s from %zuK by %zuK to %zuK", name(), old_mem_size/K, bytes/K, new_mem_size/K); } @@ -279,7 +275,7 @@ void PSOldGen::shrink(size_t bytes) { size_t new_mem_size = virtual_space()->committed_size(); size_t old_mem_size = new_mem_size + bytes; - log_debug(gc)("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", + log_debug(gc)("Shrinking %s from %zuK by %zuK to %zuK", name(), old_mem_size/K, bytes/K, new_mem_size/K); } } @@ -309,9 +305,9 @@ void PSOldGen::resize(size_t desired_free_space) { const size_t current_size = capacity_in_bytes(); log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: " - "desired free: " SIZE_FORMAT " used: " SIZE_FORMAT - " new size: " SIZE_FORMAT " current size " SIZE_FORMAT - " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT, + "desired free: %zu used: %zu" + " new size: %zu current size %zu" + " gen limits: %zu / %zu", desired_free_space, used_in_bytes(), new_size, current_size, max_gen_size(), min_gen_size()); @@ -329,7 +325,7 @@ void PSOldGen::resize(size_t desired_free_space) { shrink(change_bytes); } - log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: collection: %d (" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ", + log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: collection: %d (%zu) -> (%zu) ", ParallelScavengeHeap::heap()->total_collections(), size_before, virtual_space()->committed_size()); @@ -367,7 +363,7 @@ void PSOldGen::post_resize() { void PSOldGen::print() const { print_on(tty);} void PSOldGen::print_on(outputStream* st) const { st->print(" %-15s", name()); - st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", + st->print(" total %zuK, used %zuK", capacity_in_bytes()/K, used_in_bytes()/K); st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", p2i(virtual_space()->low_boundary()), @@ -380,7 +376,7 @@ void PSOldGen::print_on(outputStream* st) const { void PSOldGen::update_counters() { if (UsePerfData) { _space_counters->update_all(); - _gen_counters->update_all(); + _gen_counters->update_all(_virtual_space->committed_size()); } } diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index 6fc86eb2d29c5..138b2a5b30c8a 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -27,12 +27,13 @@ #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/objectStartArray.hpp" -#include "gc/parallel/psGenerationCounters.hpp" #include "gc/parallel/psVirtualspace.hpp" #include "gc/parallel/spaceCounters.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/safepoint.hpp" +class ReservedSpace; + class PSOldGen : public CHeapObj { friend class VMStructs; private: @@ -41,7 +42,7 @@ class PSOldGen : public CHeapObj { MutableSpace* _object_space; // Where all the objects live // Performance Counters - PSGenerationCounters* _gen_counters; + GenerationCounters* _gen_counters; SpaceCounters* _space_counters; // Sizing information, in bytes, set in constructor diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 4fbf6cee4dff6..9f51aba080e60 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" @@ -70,6 +69,7 @@ #include "gc/shared/workerUtils.hpp" #include "logging/log.hpp" #include "memory/iterator.inline.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspaceUtils.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -240,27 +240,38 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size) const size_t raw_bytes = count * element_size; const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10); const size_t granularity = os::vm_allocation_granularity(); - _reserved_byte_size = align_up(raw_bytes, MAX2(page_sz, granularity)); + const size_t rs_align = MAX2(page_sz, granularity); + + _reserved_byte_size = align_up(raw_bytes, rs_align); + + ReservedSpace rs = MemoryReserver::reserve(_reserved_byte_size, + rs_align, + page_sz); + + if (!rs.is_reserved()) { + // Failed to reserve memory. + return nullptr; + } - const size_t rs_align = page_sz == os::vm_page_size() ? 0 : - MAX2(page_sz, granularity); - ReservedSpace rs(_reserved_byte_size, rs_align, page_sz); os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, rs.base(), rs.size(), page_sz); MemTracker::record_virtual_memory_tag((address)rs.base(), mtGC); PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz); - if (vspace != nullptr) { - if (vspace->expand_by(_reserved_byte_size)) { - return vspace; - } + + if (!vspace->expand_by(_reserved_byte_size)) { + // Failed to commit memory. + delete vspace; + // Release memory reserved in the space. - rs.release(); + MemoryReserver::release(rs); + + return nullptr; } - return nullptr; + return vspace; } bool ParallelCompactData::initialize_region_data(size_t heap_size) @@ -577,16 +588,16 @@ bool PSParallelCompact::initialize_aux_data() { if (!_mark_bitmap.initialize(mr)) { vm_shutdown_during_initialization( - err_msg("Unable to allocate " SIZE_FORMAT "KB bitmaps for parallel " - "garbage collection for the requested " SIZE_FORMAT "KB heap.", + err_msg("Unable to allocate %zuKB bitmaps for parallel " + "garbage collection for the requested %zuKB heap.", _mark_bitmap.reserved_byte_size()/K, mr.byte_size()/K)); return false; } if (!_summary_data.initialize(mr)) { vm_shutdown_during_initialization( - err_msg("Unable to allocate " SIZE_FORMAT "KB card tables for parallel " - "garbage collection for the requested " SIZE_FORMAT "KB heap.", + err_msg("Unable to allocate %zuKB card tables for parallel " + "garbage collection for the requested %zuKB heap.", _summary_data.reserved_byte_size()/K, mr.byte_size()/K)); return false; } @@ -982,10 +993,6 @@ bool PSParallelCompact::invoke_no_policy(bool clear_all_soft_refs) { assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); assert(ref_processor() != nullptr, "Sanity"); - if (GCLocker::check_active_before_gc()) { - return false; - } - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); GCIdMark gc_id_mark; @@ -1068,7 +1075,7 @@ bool PSParallelCompact::invoke_no_policy(bool clear_all_soft_refs) { if (UseAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections()); - log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT, + log_trace(gc, ergo)("old_gen_capacity: %zu young_gen_capacity: %zu", old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes()); // Don't check if the size_policy is ready here. Let @@ -1203,12 +1210,9 @@ void steal_marking_work(TaskTerminator& terminator, uint worker_id) { ParCompactionManager::gc_thread_compaction_manager(worker_id); do { - oop obj = nullptr; - ObjArrayTask task; - if (ParCompactionManager::steal_objarray(worker_id, task)) { - cm->follow_array((objArrayOop)task.obj(), task.index()); - } else if (ParCompactionManager::steal(worker_id, obj)) { - cm->follow_contents(obj); + ScannerTask task; + if (ParCompactionManager::steal(worker_id, task)) { + cm->follow_contents(task, true); } cm->follow_marking_stacks(); } while (!terminator.offer_termination()); @@ -1224,7 +1228,7 @@ class MarkFromRootsTask : public WorkerTask { MarkFromRootsTask(uint active_workers) : WorkerTask("MarkFromRootsTask"), _strong_roots_scope(active_workers), - _terminator(active_workers, ParCompactionManager::oop_task_queues()), + _terminator(active_workers, ParCompactionManager::marking_stacks()), _active_workers(active_workers) {} virtual void work(uint worker_id) { @@ -1262,7 +1266,7 @@ class ParallelCompactRefProcProxyTask : public RefProcProxyTask { public: ParallelCompactRefProcProxyTask(uint max_workers) : RefProcProxyTask("ParallelCompactRefProcProxyTask", max_workers), - _terminator(_max_workers, ParCompactionManager::oop_task_queues()) {} + _terminator(_max_workers, ParCompactionManager::marking_stacks()) {} void work(uint worker_id) override { assert(worker_id < _max_workers, "sanity"); @@ -1372,8 +1376,7 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { _gc_tracer.report_object_count_after_gc(is_alive_closure(), &ParallelScavengeHeap::heap()->workers()); } #if TASKQUEUE_STATS - ParCompactionManager::oop_task_queues()->print_and_reset_taskqueue_stats("Oop Queue"); - ParCompactionManager::_objarray_task_queues->print_and_reset_taskqueue_stats("ObjArrayOop Queue"); + ParCompactionManager::print_and_reset_taskqueue_stats(); #endif } @@ -1681,7 +1684,7 @@ class FillableRegionLogger : public StackObj { public: FillableRegionLogger() : _next_index(0), _enabled(log_develop_is_enabled(Trace, gc, compaction)), _total_regions(0) { } ~FillableRegionLogger() { - log.trace(SIZE_FORMAT " initially fillable regions", _total_regions); + log.trace("%zu initially fillable regions", _total_regions); } void print_line() { @@ -1690,7 +1693,7 @@ class FillableRegionLogger : public StackObj { } FormatBuffer<> line("Fillable: "); for (int i = 0; i < _next_index; i++) { - line.append(" " SIZE_FORMAT_W(7), _regions[i]); + line.append(" %7zu", _regions[i]); } log.trace("%s", line.buffer()); _next_index = 0; @@ -2471,4 +2474,3 @@ void MoveAndUpdateShadowClosure::complete_region(HeapWord* dest_addr, PSParallel ParCompactionManager::push_shadow_region_mt_safe(_shadow); } } - diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp index 4c3367cdf9c98..e3ed819ceb1ef 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psPromotionLAB.hpp" diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 525285471c7d9..12758f1b66147 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" @@ -31,8 +30,8 @@ #include "gc/parallel/psScavenge.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" #include "gc/shared/gcTrace.hpp" +#include "gc/shared/partialArraySplitter.inline.hpp" #include "gc/shared/partialArrayState.hpp" -#include "gc/shared/partialArrayTaskStepper.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "logging/log.hpp" @@ -121,7 +120,7 @@ void PSPromotionManager::pre_scavenge() { bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { bool promotion_failure_occurred = false; - TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); + TASKQUEUE_STATS_ONLY(print_and_reset_taskqueue_stats()); for (uint i = 0; i < ParallelGCThreads; i++) { PSPromotionManager* manager = manager_array(i); assert(manager->claimed_stack_depth()->is_empty(), "should be empty"); @@ -145,49 +144,29 @@ bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { } #if TASKQUEUE_STATS -void -PSPromotionManager::print_local_stats(outputStream* const out, uint i) const { - #define FMT " " SIZE_FORMAT_W(10) - out->print_cr("%3u" FMT FMT FMT FMT, - i, _array_chunk_pushes, _array_chunk_steals, - _arrays_chunked, _array_chunks_processed); - #undef FMT -} - -static const char* const pm_stats_hdr[] = { - " ----partial array---- arrays array", - "thr push steal chunked chunks", - "--- ---------- ---------- ---------- ----------" -}; - -void PSPromotionManager::print_taskqueue_stats() { - if (!log_is_enabled(Trace, gc, task, stats)) { - return; - } - Log(gc, task, stats) log; - ResourceMark rm; - LogStream ls(log.trace()); - stack_array_depth()->print_taskqueue_stats(&ls, "Oop Queue"); +void PSPromotionManager::print_and_reset_taskqueue_stats() { + stack_array_depth()->print_and_reset_taskqueue_stats("Oop Queue"); - const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); - for (uint i = 0; i < hlines; ++i) ls.print_cr("%s", pm_stats_hdr[i]); + auto get_pa_stats = [&](uint i) { + return manager_array(i)->partial_array_task_stats(); + }; + PartialArrayTaskStats::log_set(ParallelGCThreads, get_pa_stats, + "Partial Array Task Stats"); for (uint i = 0; i < ParallelGCThreads; ++i) { - manager_array(i)->print_local_stats(&ls, i); + get_pa_stats(i)->reset(); } } -void PSPromotionManager::reset_stats() { - claimed_stack_depth()->stats.reset(); - _array_chunk_pushes = _array_chunk_steals = 0; - _arrays_chunked = _array_chunks_processed = 0; +PartialArrayTaskStats* PSPromotionManager::partial_array_task_stats() { + return _partial_array_splitter.stats(); } + #endif // TASKQUEUE_STATS // Most members are initialized either by initialize() or reset(). PSPromotionManager::PSPromotionManager() - : _partial_array_state_allocator(_partial_array_state_manager), - _partial_array_stepper(ParallelGCThreads, ParGCArrayScanChunk) + : _partial_array_splitter(_partial_array_state_manager, ParallelGCThreads) { // We set the old lab's start array. _old_lab.set_start_array(old_gen()->start_array()); @@ -221,8 +200,6 @@ void PSPromotionManager::reset() { _old_gen_is_full = false; _promotion_failed_info.reset(); - - TASKQUEUE_STATS_ONLY(reset_stats()); } void PSPromotionManager::register_preserved_marks(PreservedMarks* preserved_marks) { @@ -246,12 +223,12 @@ void PSPromotionManager::drain_stacks_depth(bool totally_drain) { // claimed stack while we work. while (tq->pop_overflow(task)) { if (!tq->try_push_to_taskqueue(task)) { - process_popped_location_depth(task); + process_popped_location_depth(task, false); } } while (tq->pop_local(task, threshold)) { - process_popped_location_depth(task); + process_popped_location_depth(task, false); } } while (!tq->overflow_empty()); @@ -279,9 +256,8 @@ void PSPromotionManager::flush_labs() { } } -template void PSPromotionManager::process_array_chunk_work( - oop obj, - int start, int end) { +template +void PSPromotionManager::process_array_chunk_work(oop obj, int start, int end) { assert(start <= end, "invariant"); T* const base = (T*)objArrayOop(obj)->base(); T* p = base + start; @@ -292,29 +268,18 @@ template void PSPromotionManager::process_array_chunk_work( } } -void PSPromotionManager::process_array_chunk(PartialArrayState* state) { - TASKQUEUE_STATS_ONLY(++_array_chunks_processed); - - // Claim a chunk. Push additional tasks before processing the claimed - // chunk to allow other workers to steal while we're processing. - PartialArrayTaskStepper::Step step = _partial_array_stepper.next(state); - if (step._ncreate > 0) { - state->add_references(step._ncreate); - for (uint i = 0; i < step._ncreate; ++i) { - push_depth(ScannerTask(state)); - } - TASKQUEUE_STATS_ONLY(_array_chunk_pushes += step._ncreate); - } - int start = checked_cast(step._index); - int end = checked_cast(step._index + _partial_array_stepper.chunk_size()); - assert(start < end, "invariant"); +void PSPromotionManager::process_array_chunk(PartialArrayState* state, bool stolen) { + // Access before release by claim(). + oop new_obj = state->destination(); + PartialArraySplitter::Claim claim = + _partial_array_splitter.claim(state, &_claimed_stack_depth, stolen); + int start = checked_cast(claim._start); + int end = checked_cast(claim._end); if (UseCompressedOops) { - process_array_chunk_work(state->destination(), start, end); + process_array_chunk_work(new_obj, start, end); } else { - process_array_chunk_work(state->destination(), start, end); + process_array_chunk_work(new_obj, start, end); } - // Release reference to state, now that we're done with it. - _partial_array_state_allocator.release(state); } void PSPromotionManager::push_objArray(oop old_obj, oop new_obj) { @@ -322,25 +287,16 @@ void PSPromotionManager::push_objArray(oop old_obj, oop new_obj) { assert(old_obj->forwardee() == new_obj, "precondition"); assert(new_obj->is_objArray(), "precondition"); - size_t array_length = objArrayOop(new_obj)->length(); - PartialArrayTaskStepper::Step step = _partial_array_stepper.start(array_length); - - if (step._ncreate > 0) { - TASKQUEUE_STATS_ONLY(++_arrays_chunked); - PartialArrayState* state = - _partial_array_state_allocator.allocate(old_obj, new_obj, - step._index, - array_length, - step._ncreate); - for (uint i = 0; i < step._ncreate; ++i) { - push_depth(ScannerTask(state)); - } - TASKQUEUE_STATS_ONLY(_array_chunk_pushes += step._ncreate); - } + objArrayOop to_array = objArrayOop(new_obj); + size_t array_length = to_array->length(); + size_t initial_chunk_size = + // The source array is unused when processing states. + _partial_array_splitter.start(&_claimed_stack_depth, nullptr, to_array, array_length); + int end = checked_cast(initial_chunk_size); if (UseCompressedOops) { - process_array_chunk_work(new_obj, 0, checked_cast(step._index)); + process_array_chunk_work(to_array, 0, end); } else { - process_array_chunk_work(new_obj, 0, checked_cast(step._index)); + process_array_chunk_work(to_array, 0, end); } } diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.hpp index a6de8623281c9..9397ad52a9b24 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.hpp @@ -28,8 +28,9 @@ #include "gc/parallel/psPromotionLAB.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gcTrace.hpp" +#include "gc/shared/partialArraySplitter.hpp" #include "gc/shared/partialArrayState.hpp" -#include "gc/shared/partialArrayTaskStepper.hpp" +#include "gc/shared/partialArrayTaskStats.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/taskqueue.hpp" @@ -67,15 +68,8 @@ class PSPromotionManager { static MutableSpace* _young_space; #if TASKQUEUE_STATS - size_t _array_chunk_pushes; - size_t _array_chunk_steals; - size_t _arrays_chunked; - size_t _array_chunks_processed; - - void print_local_stats(outputStream* const out, uint i) const; - static void print_taskqueue_stats(); - - void reset_stats(); + static void print_and_reset_taskqueue_stats(); + PartialArrayTaskStats* partial_array_task_stats(); #endif // TASKQUEUE_STATS PSYoungPromotionLAB _young_lab; @@ -88,8 +82,7 @@ class PSPromotionManager { uint _target_stack_size; static PartialArrayStateManager* _partial_array_state_manager; - PartialArrayStateAllocator _partial_array_state_allocator; - PartialArrayTaskStepper _partial_array_stepper; + PartialArraySplitter _partial_array_splitter; uint _min_array_size_for_chunking; PreservedMarks* _preserved_marks; @@ -105,7 +98,7 @@ class PSPromotionManager { template void process_array_chunk_work(oop obj, int start, int end); - void process_array_chunk(PartialArrayState* state); + void process_array_chunk(PartialArrayState* state, bool stolen); void push_objArray(oop old_obj, oop new_obj); void push_depth(ScannerTask task); @@ -164,7 +157,7 @@ class PSPromotionManager { return claimed_stack_depth()->is_empty(); } - inline void process_popped_location_depth(ScannerTask task); + inline void process_popped_location_depth(ScannerTask task, bool stolen); static bool should_scavenge(oop* p, bool check_to_space = false); static bool should_scavenge(narrowOop* p, bool check_to_space = false); @@ -174,8 +167,6 @@ class PSPromotionManager { template inline void claim_or_forward_depth(T* p); - TASKQUEUE_STATS_ONLY(inline void record_steal(ScannerTask task);) - void push_contents(oop obj); void push_contents_bounded(oop obj, HeapWord* left, HeapWord* right); }; diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index ed517c06a4028..4f3d135c91998 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -331,10 +331,11 @@ inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) { } } -inline void PSPromotionManager::process_popped_location_depth(ScannerTask task) { +inline void PSPromotionManager::process_popped_location_depth(ScannerTask task, + bool stolen) { if (task.is_partial_array_state()) { assert(PSChunkLargeArrays, "invariant"); - process_array_chunk(task.to_partial_array_state()); + process_array_chunk(task.to_partial_array_state(), stolen); } else { if (task.is_narrow_oop_ptr()) { assert(UseCompressedOops, "Error"); @@ -349,12 +350,4 @@ inline bool PSPromotionManager::steal_depth(int queue_num, ScannerTask& t) { return stack_array_depth()->steal(queue_num, t); } -#if TASKQUEUE_STATS -void PSPromotionManager::record_steal(ScannerTask task) { - if (task.is_partial_array_state()) { - ++_array_chunk_steals; - } -} -#endif // TASKQUEUE_STATS - #endif // SHARE_GC_PARALLEL_PSPROMOTIONMANAGER_INLINE_HPP diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 7701cea313b6a..be31da5b05d3c 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "code/codeCache.hpp" @@ -128,8 +127,7 @@ static void steal_work(TaskTerminator& terminator, uint worker_id) { while (true) { ScannerTask task; if (PSPromotionManager::steal_depth(worker_id, task)) { - TASKQUEUE_STATS_ONLY(pm->record_steal(task)); - pm->process_popped_location_depth(task); + pm->process_popped_location_depth(task, true); pm->drain_stacks_depth(true); } else { if (terminator.offer_termination()) { @@ -206,7 +204,7 @@ class ParallelScavengeRefProcProxyTask : public RefProcProxyTask { public: ParallelScavengeRefProcProxyTask(uint max_workers) : RefProcProxyTask("ParallelScavengeRefProcProxyTask", max_workers), - _terminator(max_workers, ParCompactionManager::oop_task_queues()) {} + _terminator(max_workers, ParCompactionManager::marking_stacks()) {} void work(uint worker_id) override { assert(worker_id < _max_workers, "sanity"); @@ -461,7 +459,7 @@ bool PSScavenge::invoke(bool clear_soft_refs) { // Calculate the new survivor size and tenuring threshold log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections()); - log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT, + log_trace(gc, ergo)("old_gen_capacity: %zu young_gen_capacity: %zu", old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes()); if (UsePerfData) { @@ -629,7 +627,7 @@ bool PSScavenge::should_attempt_scavenge() { size_t free_in_old_gen = old_gen->max_gen_size() - old_gen->used_in_bytes(); bool result = promotion_estimate < free_in_old_gen; - log_trace(ergo)("%s scavenge: average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT, + log_trace(ergo)("%s scavenge: average_promoted %zu padded_average_promoted %zu free in old gen %zu", result ? "Do" : "Skip", (size_t) policy->average_promoted_in_bytes(), (size_t) policy->padded_average_promoted_in_bytes(), free_in_old_gen); diff --git a/src/hotspot/share/gc/parallel/psVMOperations.cpp b/src/hotspot/share/gc/parallel/psVMOperations.cpp index d4d2e1df21f24..4873853a3ddfd 100644 --- a/src/hotspot/share/gc/parallel/psVMOperations.cpp +++ b/src/hotspot/share/gc/parallel/psVMOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" #include "gc/parallel/parallelScavengeHeap.inline.hpp" #include "gc/parallel/psScavenge.hpp" @@ -44,14 +43,10 @@ void VM_ParallelCollectForAllocation::doit() { GCCauseSetter gccs(heap, _gc_cause); _result = heap->satisfy_failed_allocation(_word_size, _is_tlab); - - if (_result == nullptr && GCLocker::is_active_and_needs_gc()) { - set_gc_locked(); - } } static bool is_cause_full(GCCause::Cause cause) { - return (cause != GCCause::_gc_locker) && (cause != GCCause::_wb_young_gc) + return (cause != GCCause::_wb_young_gc) DEBUG_ONLY(&& (cause != GCCause::_scavenge_alot)); } @@ -65,5 +60,5 @@ void VM_ParallelGCCollect::doit() { ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); GCCauseSetter gccs(heap, _gc_cause); - heap->try_collect_at_safepoint(_full); + heap->collect_at_safepoint(_full); } diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.cpp b/src/hotspot/share/gc/parallel/psVirtualspace.cpp index a4d686d867042..ce4cd4ad977a6 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.cpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,8 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/psVirtualspace.hpp" -#include "memory/virtualspace.hpp" +#include "memory/reservedSpace.hpp" #include "runtime/os.hpp" #include "utilities/align.hpp" diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.hpp b/src/hotspot/share/gc/parallel/psVirtualspace.hpp index e2cb08160bec6..4c2aa8eef3f56 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.hpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #define SHARE_GC_PARALLEL_PSVIRTUALSPACE_HPP #include "memory/allocation.hpp" +#include "memory/reservedSpace.hpp" #include "memory/virtualspace.hpp" // VirtualSpace for the parallel scavenge collector. diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp index dd9619e454656..309b293e5accf 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.cpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/mutableNUMASpace.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/psScavenge.hpp" @@ -92,8 +91,8 @@ void PSYoungGen::initialize_work() { _to_space = new MutableSpace(virtual_space()->alignment()); // Generation Counters - generation 0, 3 subspaces - _gen_counters = new PSGenerationCounters("new", 0, 3, min_gen_size(), - max_gen_size(), virtual_space()); + _gen_counters = new GenerationCounters("new", 0, 3, min_gen_size(), + max_gen_size(), virtual_space()->committed_size()); // Compute maximum space sizes for performance counters size_t alignment = SpaceAlignment; @@ -256,9 +255,9 @@ void PSYoungGen::resize(size_t eden_size, size_t survivor_size) { space_invariants(); log_trace(gc, ergo)("Young generation size: " - "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT - " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT - " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT, + "desired eden: %zu survivor: %zu" + " used: %zu capacity: %zu" + " gen limits: %zu / %zu", eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(), max_gen_size(), min_gen_size()); } @@ -315,15 +314,15 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { } } else { if (orig_size == max_gen_size()) { - log_trace(gc)("PSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K); + log_trace(gc)("PSYoung generation size at maximum: %zuK", orig_size/K); } else if (orig_size == min_gen_size()) { - log_trace(gc)("PSYoung generation size at minimum: " SIZE_FORMAT "K", orig_size/K); + log_trace(gc)("PSYoung generation size at minimum: %zuK", orig_size/K); } } if (size_changed) { post_resize(); - log_trace(gc)("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", + log_trace(gc)("PSYoung generation size changed: %zuK->%zuK", orig_size/K, virtual_space()->committed_size()/K); } @@ -420,21 +419,21 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, return; } - log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: " SIZE_FORMAT ", requested_survivor_size: " SIZE_FORMAT ")", + log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: %zu, requested_survivor_size: %zu)", requested_eden_size, requested_survivor_size); - log_trace(gc, ergo)(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") %zu", p2i(eden_space()->bottom()), p2i(eden_space()->end()), pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char))); - log_trace(gc, ergo)(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" from: [" PTR_FORMAT ".." PTR_FORMAT ") %zu", p2i(from_space()->bottom()), p2i(from_space()->end()), pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char))); - log_trace(gc, ergo)(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" to: [" PTR_FORMAT ".." PTR_FORMAT ") %zu", p2i(to_space()->bottom()), p2i(to_space()->end()), pointer_delta( to_space()->end(), @@ -525,15 +524,15 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, guarantee(to_start != to_end, "to space is zero sized"); - log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(eden_start), p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); - log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(from_start), p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); - log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(to_start), p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); @@ -575,15 +574,15 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, eden_end = MAX2(eden_end, eden_start + SpaceAlignment); to_start = MAX2(to_start, eden_end); - log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(eden_start), p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char))); - log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(to_start), p2i(to_end), pointer_delta( to_end, to_start, sizeof(char))); - log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, + log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") %zu", p2i(from_start), p2i(from_end), pointer_delta(from_end, from_start, sizeof(char))); @@ -646,7 +645,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, assert(from_space()->top() == old_from_top, "from top changed!"); - log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: collection: %d (" SIZE_FORMAT ", " SIZE_FORMAT ") -> (" SIZE_FORMAT ", " SIZE_FORMAT ") ", + log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: collection: %d (%zu, %zu) -> (%zu, %zu) ", ParallelScavengeHeap::heap()->total_collections(), old_from, old_to, from_space()->capacity_in_bytes(), @@ -702,7 +701,7 @@ void PSYoungGen::object_iterate(ObjectClosure* blk) { void PSYoungGen::print() const { print_on(tty); } void PSYoungGen::print_on(outputStream* st) const { st->print(" %-15s", "PSYoungGen"); - st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", + st->print(" total %zuK, used %zuK", capacity_in_bytes()/K, used_in_bytes()/K); virtual_space()->print_space_boundaries_on(st); st->print(" eden"); eden_space()->print_on(st); @@ -810,7 +809,7 @@ void PSYoungGen::update_counters() { _eden_counters->update_all(); _from_counters->update_all(); _to_counters->update_all(); - _gen_counters->update_all(); + _gen_counters->update_all(_virtual_space->committed_size()); } } diff --git a/src/hotspot/share/gc/parallel/psYoungGen.hpp b/src/hotspot/share/gc/parallel/psYoungGen.hpp index 6e256e81d9775..5140ea08bd161 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.hpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.hpp @@ -27,10 +27,11 @@ #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/objectStartArray.hpp" -#include "gc/parallel/psGenerationCounters.hpp" #include "gc/parallel/psVirtualspace.hpp" #include "gc/parallel/spaceCounters.hpp" +class ReservedSpace; + class PSYoungGen : public CHeapObj { friend class VMStructs; friend class ParallelScavengeHeap; @@ -49,7 +50,7 @@ class PSYoungGen : public CHeapObj { const size_t _max_gen_size; // Performance counters - PSGenerationCounters* _gen_counters; + GenerationCounters* _gen_counters; SpaceCounters* _eden_counters; SpaceCounters* _from_counters; SpaceCounters* _to_counters; diff --git a/src/hotspot/share/gc/parallel/spaceCounters.cpp b/src/hotspot/share/gc/parallel/spaceCounters.cpp index 588c743d86587..4133fc2e2480a 100644 --- a/src/hotspot/share/gc/parallel/spaceCounters.cpp +++ b/src/hotspot/share/gc/parallel/spaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/parallel/spaceCounters.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/serial/cSpaceCounters.cpp b/src/hotspot/share/gc/serial/cSpaceCounters.cpp index 6a9b51245783a..9f8b91e205cd0 100644 --- a/src/hotspot/share/gc/serial/cSpaceCounters.cpp +++ b/src/hotspot/share/gc/serial/cSpaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/cSpaceCounters.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/serial/cardTableRS.cpp b/src/hotspot/share/gc/serial/cardTableRS.cpp index 1c1781e280efa..80985424a62ad 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.cpp +++ b/src/hotspot/share/gc/serial/cardTableRS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/serial/cardTableRS.hpp" #include "gc/serial/generation.hpp" diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 3792bb5a721c4..8ad42bc702dcb 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/cardTableRS.hpp" #include "gc/serial/serialGcRefProcProxyTask.hpp" #include "gc/serial/serialHeap.inline.hpp" @@ -47,6 +46,7 @@ #include "gc/shared/weakProcessor.hpp" #include "logging/log.hpp" #include "memory/iterator.inline.hpp" +#include "memory/reservedSpace.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" @@ -250,7 +250,7 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, // Generation counters -- generation 0, 3 subspaces _gen_counters = new GenerationCounters("new", 0, 3, - min_size, max_size, &_virtual_space); + min_size, max_size, _virtual_space.committed_size()); _gc_counters = new CollectorCounters(policy, 0); _eden_counters = new CSpaceCounters("eden", 0, _max_eden_size, _eden_space, @@ -367,18 +367,6 @@ bool DefNewGeneration::expand(size_t bytes) { SpaceMangler::mangle_region(mangle_region); } - // Do not attempt an expand-to-the reserve size. The - // request should properly observe the maximum size of - // the generation so an expand-to-reserve should be - // unnecessary. Also a second call to expand-to-reserve - // value potentially can cause an undue expansion. - // For example if the first expand fail for unknown reasons, - // but the second succeeds and expands the heap to its maximum - // value. - if (GCLocker::is_active()) { - log_debug(gc)("Garbage collection disabled, expanded heap instead"); - } - return success; } @@ -479,11 +467,11 @@ void DefNewGeneration::compute_new_size() { gch->rem_set()->resize_covered_region(cmr); log_debug(gc, ergo, heap)( - "New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]", + "New generation size %zuK->%zuK [eden=%zuK,survivor=%zuK]", new_size_before/K, _virtual_space.committed_size()/K, eden()->capacity()/K, from()->capacity()/K); log_trace(gc, ergo, heap)( - " [allowed " SIZE_FORMAT "K extra for %d threads]", + " [allowed %zuK extra for %d threads]", thread_increase_size/K, threads_count); } } @@ -714,7 +702,7 @@ void DefNewGeneration::remove_forwarding_pointers() { } void DefNewGeneration::handle_promotion_failure(oop old) { - log_debug(gc, promotion)("Promotion failure size = " SIZE_FORMAT ") ", old->size()); + log_debug(gc, promotion)("Promotion failure size = %zu) ", old->size()); _promotion_failed = true; _promotion_failed_info.register_copy_failure(old->size()); @@ -826,7 +814,7 @@ void DefNewGeneration::update_counters() { _eden_counters->update_all(); _from_counters->update_all(); _to_counters->update_all(); - _gen_counters->update_all(); + _gen_counters->update_all(_virtual_space.committed_size()); } } @@ -839,7 +827,7 @@ void DefNewGeneration::verify() { void DefNewGeneration::print_on(outputStream* st) const { st->print(" %-10s", name()); - st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", + st->print(" total %zuK, used %zuK", capacity()/K, used()/K); st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", p2i(_virtual_space.low_boundary()), diff --git a/src/hotspot/share/gc/serial/generation.cpp b/src/hotspot/share/gc/serial/generation.cpp index b15b071d7103f..61b128464e135 100644 --- a/src/hotspot/share/gc/serial/generation.cpp +++ b/src/hotspot/share/gc/serial/generation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/cardTableRS.hpp" #include "gc/serial/generation.hpp" #include "gc/serial/serialHeap.hpp" diff --git a/src/hotspot/share/gc/serial/generation.hpp b/src/hotspot/share/gc/serial/generation.hpp index e13b42956e1af..8c9da3b42b745 100644 --- a/src/hotspot/share/gc/serial/generation.hpp +++ b/src/hotspot/share/gc/serial/generation.hpp @@ -54,6 +54,7 @@ class DefNewGeneration; class GCMemoryManager; class ContiguousSpace; class OopClosure; +class ReservedSpace; class Generation: public CHeapObj { friend class VMStructs; diff --git a/src/hotspot/share/gc/serial/serialArguments.cpp b/src/hotspot/share/gc/serial/serialArguments.cpp index c9d2caf9063c8..9b55e0cd9f69b 100644 --- a/src/hotspot/share/gc/serial/serialArguments.cpp +++ b/src/hotspot/share/gc/serial/serialArguments.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/fullGCForwarding.hpp" #include "gc/shared/gcArguments.hpp" #include "gc/serial/serialArguments.hpp" diff --git a/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp b/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp index 8d257c0bf3330..5baad7f995adf 100644 --- a/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp +++ b/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,14 +22,13 @@ * */ -#include "precompiled.hpp" #include "gc/serial/serialBlockOffsetTable.inline.hpp" #include "gc/shared/blockOffsetTable.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "logging/log.hpp" #include "memory/iterator.hpp" +#include "memory/memoryReserver.hpp" #include "memory/universe.hpp" -#include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" @@ -47,14 +46,17 @@ SerialBlockOffsetTable::SerialBlockOffsetTable(MemRegion reserved, size_t init_word_size): _reserved(reserved) { size_t size = compute_size(reserved.word_size()); - ReservedSpace rs(size, mtGC); + + ReservedSpace rs = MemoryReserver::reserve(size, mtGC); + if (!rs.is_reserved()) { vm_exit_during_initialization("Could not reserve enough space for heap offset array"); } - if (!_vs.initialize(rs, 0)) { - vm_exit_during_initialization("Could not reserve enough space for heap offset array"); - } + const bool initialized = _vs.initialize(rs, 0 /* committed_size */); + + assert(initialized, "Should never fail when commmitted_size is 0"); + _offset_base = (uint8_t*)(_vs.low_boundary() - (uintptr_t(reserved.start()) >> CardTable::card_shift())); resize(init_word_size); log_trace(gc, bot)("SerialBlockOffsetTable::SerialBlockOffsetTable: "); diff --git a/src/hotspot/share/gc/serial/serialFullGC.cpp b/src/hotspot/share/gc/serial/serialFullGC.cpp index 0df28fa7bd5d2..9d0dc1932fcbc 100644 --- a/src/hotspot/share/gc/serial/serialFullGC.cpp +++ b/src/hotspot/share/gc/serial/serialFullGC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.inline.hpp" @@ -133,7 +132,7 @@ class DeadSpacer : StackObj { // obj->set_mark(obj->mark().set_marked()); assert(dead_length == obj->size(), "bad filler object size"); - log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b", + log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", %zub", p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize); return true; @@ -651,7 +650,7 @@ void SerialFullGC::adjust_marks() { } void SerialFullGC::restore_marks() { - log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_overflow_stack_set.get()->size()); + log_trace(gc)("Restoring %zu marks", _preserved_count + _preserved_overflow_stack_set.get()->size()); // restore the marks we saved earlier for (size_t i = 0; i < _preserved_count; i++) { diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 81cc59146daa3..fcf57909a032e 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" @@ -63,6 +62,7 @@ #include "memory/iterator.hpp" #include "memory/metaspaceCounters.hpp" #include "memory/metaspaceUtils.hpp" +#include "memory/reservedSpace.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" @@ -95,11 +95,13 @@ SerialHeap::SerialHeap() : _gc_policy_counters(new GCPolicyCounters("Copy:MSC", 2, 2)), _young_manager(nullptr), _old_manager(nullptr), + _is_heap_almost_full(false), _eden_pool(nullptr), _survivor_pool(nullptr), _old_pool(nullptr) { _young_manager = new GCMemoryManager("Copy"); _old_manager = new GCMemoryManager("MarkSweepCompact"); + GCLocker::initialize(); } void SerialHeap::initialize_serviceability() { @@ -166,11 +168,11 @@ void SerialHeap::complete_loaded_archive_space(MemRegion archive_space) { } void SerialHeap::pin_object(JavaThread* thread, oop obj) { - GCLocker::lock_critical(thread); + GCLocker::enter(thread); } void SerialHeap::unpin_object(JavaThread* thread, oop obj) { - GCLocker::unlock_critical(thread); + GCLocker::exit(thread); } jint SerialHeap::initialize() { @@ -189,7 +191,7 @@ jint SerialHeap::initialize() { ReservedSpace young_rs = heap_rs.first_part(MaxNewSize, GenAlignment); ReservedSpace old_rs = heap_rs.last_part(MaxNewSize, GenAlignment); - _rem_set = new CardTableRS(heap_rs.region()); + _rem_set = new CardTableRS(_reserved); _rem_set->initialize(young_rs.base(), old_rs.base()); CardTableBarrierSet *bs = new CardTableBarrierSet(_rem_set); @@ -218,8 +220,7 @@ ReservedHeapSpace SerialHeap::allocate(size_t alignment) { "the maximum representable size"); } assert(total_reserved % alignment == 0, - "Gen size; total_reserved=" SIZE_FORMAT ", alignment=" - SIZE_FORMAT, total_reserved, alignment); + "Gen size; total_reserved=%zu, alignment=%zu", total_reserved, alignment); ReservedHeapSpace heap_rs = Universe::reserve_heap(total_reserved, alignment); size_t used_page_size = heap_rs.page_size(); @@ -282,14 +283,11 @@ size_t SerialHeap::max_capacity() const { // Return true if any of the following is true: // . the allocation won't fit into the current young gen heap -// . gc locker is occupied (jni critical section) -// . heap memory is tight -- the most recent previous collection -// was a full collection because a partial collection (would -// have) failed and is likely to fail again +// . heap memory is tight bool SerialHeap::should_try_older_generation_allocation(size_t word_size) const { size_t young_capacity = _young_gen->capacity_before_gc(); return (word_size > heap_word_size(young_capacity)) - || GCLocker::is_active_and_needs_gc(); + || _is_heap_almost_full; } HeapWord* SerialHeap::expand_heap_and_allocate(size_t size, bool is_tlab) { @@ -307,14 +305,11 @@ HeapWord* SerialHeap::expand_heap_and_allocate(size_t size, bool is_tlab) { return result; } -HeapWord* SerialHeap::mem_allocate_work(size_t size, - bool is_tlab) { - +HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) { HeapWord* result = nullptr; // Loop until the allocation is satisfied, or unsatisfied after GC. - for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) { - + for (uint try_count = 1; /* return or throw */; try_count += 1) { // First allocation attempt is lock-free. DefNewGeneration *young = _young_gen; if (young->should_allocate(size, is_tlab)) { @@ -338,45 +333,6 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, return result; } - if (GCLocker::is_active_and_needs_gc()) { - if (is_tlab) { - return nullptr; // Caller will retry allocating individual object. - } - if (!is_maximal_no_gc()) { - // Try and expand heap to satisfy request. - result = expand_heap_and_allocate(size, is_tlab); - // Result could be null if we are out of space. - if (result != nullptr) { - return result; - } - } - - if (gclocker_stalled_count > GCLockerRetryAllocationCount) { - return nullptr; // We didn't get to do a GC and we didn't get any memory. - } - - // If this thread is not in a jni critical section, we stall - // the requestor until the critical section has cleared and - // GC allowed. When the critical section clears, a GC is - // initiated by the last thread exiting the critical section; so - // we retry the allocation sequence from the beginning of the loop, - // rather than causing more, now probably unnecessary, GC attempts. - JavaThread* jthr = JavaThread::current(); - if (!jthr->in_critical()) { - MutexUnlocker mul(Heap_lock); - // Wait for JNI critical section to be exited - GCLocker::stall_until_clear(); - gclocker_stalled_count += 1; - continue; - } else { - if (CheckJNICalls) { - fatal("Possible deadlock due to allocating while" - " in jni critical section"); - } - return nullptr; - } - } - // Read the gc count while the heap lock is held. gc_count_before = total_collections(); } @@ -385,10 +341,6 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, VMThread::execute(&op); if (op.prologue_succeeded()) { result = op.result(); - if (op.gc_locked()) { - assert(result == nullptr, "must be null if gc_locked() is true"); - continue; // Retry and/or stall as necessary. - } assert(result == nullptr || is_in_reserved(result), "result not in heap"); @@ -398,8 +350,8 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, // Give a warning if we seem to be looping forever. if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { - log_warning(gc, ergo)("SerialHeap::mem_allocate_work retries %d times," - " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : ""); + log_warning(gc, ergo)("SerialHeap::mem_allocate_work retries %d times," + " size=%zu %s", try_count, size, is_tlab ? "(TLAB)" : ""); } } } @@ -461,7 +413,7 @@ bool SerialHeap::do_young_collection(bool clear_soft_refs) { prepare_for_verify(); Universe::verify("Before GC"); } - gc_prologue(false); + gc_prologue(); COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::clear()); save_marks(); @@ -518,16 +470,6 @@ HeapWord* SerialHeap::satisfy_failed_allocation(size_t size, bool is_tlab) { HeapWord* result = nullptr; - GCLocker::check_active_before_gc(); - if (GCLocker::is_active_and_needs_gc()) { - // GC locker is active; instead of a collection we will attempt - // to expand the heap, if there's room for expansion. - if (!is_maximal_no_gc()) { - result = expand_heap_and_allocate(size, is_tlab); - } - return result; // Could be null if we are out of space. - } - // If young-gen can handle this allocation, attempt young-gc firstly. bool should_run_young_gc = _young_gen->should_allocate(size, is_tlab); collect_at_safepoint(!should_run_young_gc); @@ -551,7 +493,7 @@ HeapWord* SerialHeap::satisfy_failed_allocation(size_t size, bool is_tlab) { { UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted const bool clear_all_soft_refs = true; - do_full_collection_no_gc_locker(clear_all_soft_refs); + do_full_collection(clear_all_soft_refs); } result = attempt_allocation(size, is_tlab, false /* first_only */); @@ -633,14 +575,6 @@ void SerialHeap::scan_evacuated_objs(YoungGenScanClosure* young_cl, guarantee(young_gen()->promo_failure_scan_is_complete(), "Failed to finish scan"); } -void SerialHeap::try_collect_at_safepoint(bool full) { - assert(SafepointSynchronize::is_at_safepoint(), "precondition"); - if (GCLocker::check_active_before_gc()) { - return; - } - collect_at_safepoint(full); -} - void SerialHeap::collect_at_safepoint(bool full) { assert(!GCLocker::is_active(), "precondition"); bool clear_soft_refs = must_clear_all_soft_refs(); @@ -652,7 +586,7 @@ void SerialHeap::collect_at_safepoint(bool full) { } // Upgrade to Full-GC if young-gc fails } - do_full_collection_no_gc_locker(clear_soft_refs); + do_full_collection(clear_soft_refs); } // public collection interfaces @@ -670,12 +604,7 @@ void SerialHeap::collect(GCCause::Cause cause) { full_gc_count_before = total_full_collections(); } - if (GCLocker::should_discard(cause, gc_count_before)) { - return; - } - bool should_run_young_gc = (cause == GCCause::_wb_young_gc) - || (cause == GCCause::_gc_locker) DEBUG_ONLY(|| (cause == GCCause::_scavenge_alot)); while (true) { @@ -684,7 +613,6 @@ void SerialHeap::collect(GCCause::Cause cause) { full_gc_count_before, cause); VMThread::execute(&op); - if (!GCCause::is_explicit_full_gc(cause)) { return; } @@ -696,22 +624,10 @@ void SerialHeap::collect(GCCause::Cause cause) { return; } } - - if (GCLocker::is_active_and_needs_gc()) { - // If GCLocker is active, wait until clear before retrying. - GCLocker::stall_until_clear(); - } } } void SerialHeap::do_full_collection(bool clear_all_soft_refs) { - if (GCLocker::check_active_before_gc()) { - return; - } - do_full_collection_no_gc_locker(clear_all_soft_refs); -} - -void SerialHeap::do_full_collection_no_gc_locker(bool clear_all_soft_refs) { IsSTWGCActiveMark gc_active_mark; SvcGCMarker sgcm(SvcGCMarker::FULL); GCIdMark gc_id_mark; @@ -729,7 +645,7 @@ void SerialHeap::do_full_collection_no_gc_locker(bool clear_all_soft_refs) { Universe::verify("Before GC"); } - gc_prologue(true); + gc_prologue(); COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::clear()); CodeCache::on_gc_marking_cycle_start(); ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, @@ -935,7 +851,7 @@ void SerialHeap::print_heap_change(const PreGenGCValues& pre_gc_values) const { MetaspaceUtils::print_metaspace_change(pre_gc_values.metaspace_sizes()); } -void SerialHeap::gc_prologue(bool full) { +void SerialHeap::gc_prologue() { // Fill TLAB's and such ensure_parsability(true); // retire TLABs @@ -952,5 +868,18 @@ void SerialHeap::gc_epilogue(bool full) { _young_gen->gc_epilogue(full); _old_gen->gc_epilogue(); + if (_is_heap_almost_full) { + // Reset the emergency state if eden is empty after a young/full gc + if (_young_gen->eden()->is_empty()) { + _is_heap_almost_full = false; + } + } else { + if (full && !_young_gen->eden()->is_empty()) { + // Usually eden should be empty after a full GC, so heap is probably too + // full now; entering emergency state. + _is_heap_almost_full = true; + } + } + MetaspaceCounters::update_performance_counters(); }; diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index d787d216e37ab..754f6741cfec3 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -95,15 +95,19 @@ class SerialHeap : public CollectedHeap { GCMemoryManager* _young_manager; GCMemoryManager* _old_manager; + // Indicate whether heap is almost or approaching full. + // Usually, there is some memory headroom for application/gc to run properly. + // However, in extreme cases, e.g. young-gen is non-empty after a full gc, we + // will attempt some uncommon measures, e.g. alllocating small objs in + // old-gen. + bool _is_heap_almost_full; + // Helper functions for allocation HeapWord* attempt_allocation(size_t size, bool is_tlab, bool first_only); void do_full_collection(bool clear_all_soft_refs) override; - void do_full_collection_no_gc_locker(bool clear_all_soft_refs); - - void collect_at_safepoint(bool full); // Does the "cause" of GC indicate that // we absolutely __must__ clear soft refs? @@ -111,6 +115,9 @@ class SerialHeap : public CollectedHeap { bool is_young_gc_safe() const; + void gc_prologue(); + void gc_epilogue(bool full); + public: // Returns JNI_OK on success jint initialize() override; @@ -137,7 +144,7 @@ class SerialHeap : public CollectedHeap { HeapWord* satisfy_failed_allocation(size_t size, bool is_tlab); // Callback from VM_SerialGCCollect. - void try_collect_at_safepoint(bool full); + void collect_at_safepoint(bool full); // Perform a full collection of the heap; intended for use in implementing // "System.gc". This implies as full a collection as the CollectedHeap @@ -226,10 +233,6 @@ class SerialHeap : public CollectedHeap { SO_ScavengeCodeCache = 0x10 }; - protected: - virtual void gc_prologue(bool full); - virtual void gc_epilogue(bool full); - public: // Apply closures on various roots in Young GC or marking/adjust phases of Full GC. void process_roots(ScanningOption so, @@ -251,8 +254,7 @@ class SerialHeap : public CollectedHeap { // Try to allocate space by expanding the heap. HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); - HeapWord* mem_allocate_work(size_t size, - bool is_tlab); + HeapWord* mem_allocate_work(size_t size, bool is_tlab); MemoryPool* _eden_pool; MemoryPool* _survivor_pool; diff --git a/src/hotspot/share/gc/serial/serialMemoryPools.cpp b/src/hotspot/share/gc/serial/serialMemoryPools.cpp index b82252b5a094f..723b53a3e2b0b 100644 --- a/src/hotspot/share/gc/serial/serialMemoryPools.cpp +++ b/src/hotspot/share/gc/serial/serialMemoryPools.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/defNewGeneration.hpp" #include "gc/serial/serialMemoryPools.hpp" #include "gc/serial/tenuredGeneration.hpp" diff --git a/src/hotspot/share/gc/serial/serialStringDedup.cpp b/src/hotspot/share/gc/serial/serialStringDedup.cpp index 93910ae65d375..486affd3d20a3 100644 --- a/src/hotspot/share/gc/serial/serialStringDedup.cpp +++ b/src/hotspot/share/gc/serial/serialStringDedup.cpp @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/serial/defNewGeneration.hpp" #include "gc/serial/serialHeap.hpp" #include "gc/serial/serialStringDedup.hpp" diff --git a/src/hotspot/share/gc/serial/serialVMOperations.cpp b/src/hotspot/share/gc/serial/serialVMOperations.cpp index 36805f619ecb8..ef9ce4e425d64 100644 --- a/src/hotspot/share/gc/serial/serialVMOperations.cpp +++ b/src/hotspot/share/gc/serial/serialVMOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/serialVMOperations.hpp" #include "gc/shared/gcLocker.hpp" @@ -31,14 +30,10 @@ void VM_SerialCollectForAllocation::doit() { GCCauseSetter gccs(gch, _gc_cause); _result = gch->satisfy_failed_allocation(_word_size, _tlab); assert(_result == nullptr || gch->is_in_reserved(_result), "result not in heap"); - - if (_result == nullptr && GCLocker::is_active_and_needs_gc()) { - set_gc_locked(); - } } void VM_SerialGCCollect::doit() { SerialHeap* gch = SerialHeap::heap(); GCCauseSetter gccs(gch, _gc_cause); - gch->try_collect_at_safepoint(_full); + gch->collect_at_safepoint(_full); } diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index 2b7711e9b0a9e..22c4808a0bd17 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/cardTableRS.hpp" #include "gc/serial/serialBlockOffsetTable.inline.hpp" #include "gc/serial/serialFullGC.hpp" @@ -69,7 +68,7 @@ bool TenuredGeneration::grow_by(size_t bytes) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size - bytes; - log_trace(gc, heap)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", + log_trace(gc, heap)("Expanding %s from %zuK by %zuK to %zuK", name(), old_mem_size/K, bytes/K, new_mem_size/K); } return result; @@ -101,9 +100,6 @@ bool TenuredGeneration::expand(size_t bytes, size_t expand_bytes) { if (!success) { success = grow_to_reserved(); } - if (success && GCLocker::is_active_and_needs_gc()) { - log_trace(gc, heap)("Garbage collection disabled, expanded heap instead"); - } return success; } @@ -140,7 +136,7 @@ void TenuredGeneration::shrink(size_t bytes) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size + size; - log_trace(gc, heap)("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", + log_trace(gc, heap)("Shrinking %s from %zuK to %zuK", name(), old_mem_size/K, new_mem_size/K); } @@ -236,7 +232,7 @@ void TenuredGeneration::compute_new_size_inner() { assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); log_trace(gc, heap)(" shrinking: initSize: %.1fK maximum_desired_capacity: %.1fK", OldSize / (double) K, maximum_desired_capacity / (double) K); - log_trace(gc, heap)(" shrink_bytes: %.1fK current_shrink_factor: " SIZE_FORMAT " new shrink factor: " SIZE_FORMAT " _min_heap_delta_bytes: %.1fK", + log_trace(gc, heap)(" shrink_bytes: %.1fK current_shrink_factor: %zu new shrink factor: %zu _min_heap_delta_bytes: %.1fK", shrink_bytes / (double) K, current_shrink_factor, _shrink_factor, @@ -330,7 +326,7 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs, const char* gen_name = "old"; // Generation Counters -- generation 1, 1 subspace _gen_counters = new GenerationCounters(gen_name, 1, 1, - min_byte_size, max_byte_size, &_virtual_space); + min_byte_size, max_byte_size, _virtual_space.committed_size()); _gc_counters = new CollectorCounters("Serial full collection pauses", 1); @@ -354,8 +350,8 @@ void TenuredGeneration::compute_new_size() { compute_new_size_inner(); assert(used() == used_after_gc && used_after_gc <= capacity(), - "used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT - " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity()); + "used: %zu used_after_gc: %zu" + " capacity: %zu", used(), used_after_gc, capacity()); } void TenuredGeneration::update_promote_stats() { @@ -372,7 +368,7 @@ void TenuredGeneration::update_promote_stats() { void TenuredGeneration::update_counters() { if (UsePerfData) { _space_counters->update_all(); - _gen_counters->update_all(); + _gen_counters->update_all(_virtual_space.committed_size()); } } @@ -384,7 +380,7 @@ bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) bool res = (promotion_estimate <= available); - log_trace(gc)("Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "), max_promo(" SIZE_FORMAT ")", + log_trace(gc)("Tenured: promo attempt is%s safe: available(%zu) %s av_promo(%zu), max_promo(%zu)", res? "":" not", available, res? ">=":"<", avg_promoted, max_promotion_in_bytes); return res; @@ -445,7 +441,7 @@ void TenuredGeneration::verify() { void TenuredGeneration::print_on(outputStream* st) const { st->print(" %-10s", name()); - st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", + st->print(" total %zuK, used %zuK", capacity()/K, used()/K); st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", p2i(_virtual_space.low_boundary()), diff --git a/src/hotspot/share/gc/shared/accessBarrierSupport.cpp b/src/hotspot/share/gc/shared/accessBarrierSupport.cpp index 93e88f82dba6a..35ea85571c2d3 100644 --- a/src/hotspot/share/gc/shared/accessBarrierSupport.cpp +++ b/src/hotspot/share/gc/shared/accessBarrierSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "gc/shared/accessBarrierSupport.inline.hpp" #include "oops/access.hpp" diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp index 1454a2b21e94d..3ebcdaaaf21b8 100644 --- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/adaptiveSizePolicy.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcUtil.hpp" @@ -337,11 +336,11 @@ class AdaptiveSizePolicySpaceOverheadTester: public GCOverheadTester { log_trace(gc, ergo)( "AdaptiveSizePolicySpaceOverheadTester::is_exceeded:" - " promo_limit: " SIZE_FORMAT - " total_free_limit: " SIZE_FORMAT - " max_old_gen_size: " SIZE_FORMAT - " max_eden_size: " SIZE_FORMAT - " mem_free_limit: " SIZE_FORMAT, + " promo_limit: %zu" + " total_free_limit: %zu" + " max_old_gen_size: %zu" + " max_eden_size: %zu" + " mem_free_limit: %zu", promo_limit, total_free_limit, _max_old_gen_size, _max_eden_size, (size_t)mem_free_limit); diff --git a/src/hotspot/share/gc/shared/ageTable.cpp b/src/hotspot/share/gc/shared/ageTable.cpp index 28f17a4220b89..f5b62466556ed 100644 --- a/src/hotspot/share/gc/shared/ageTable.cpp +++ b/src/hotspot/share/gc/shared/ageTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/ageTable.inline.hpp" #include "gc/shared/ageTableTracer.hpp" #include "gc/shared/collectedHeap.hpp" @@ -35,7 +34,7 @@ #include "utilities/copy.hpp" #include "logging/logStream.hpp" -/* Copyright (c) 1992, 2024, Oracle and/or its affiliates, and Stanford University. +/* Copyright (c) 1992, 2025, Oracle and/or its affiliates, and Stanford University. See the LICENSE file for license information. */ AgeTable::AgeTable(bool global) : _use_perf_data(UsePerfData && global) { @@ -108,7 +107,7 @@ uint AgeTable::compute_tenuring_threshold(size_t desired_survivor_size) { } - log_debug(gc, age)("Desired survivor size %zu bytes, new threshold " UINTX_FORMAT " (max threshold %u)", + log_debug(gc, age)("Desired survivor size %zu bytes, new threshold %zu (max threshold %u)", desired_survivor_size * oopSize, (uintx) result, MaxTenuringThreshold); return result; @@ -131,7 +130,7 @@ void AgeTable::print_on(outputStream* st) { size_t word_size = sizes[age]; total += word_size; if (word_size > 0) { - st->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", + st->print_cr("- age %3u: %10zu bytes, %10zu total", age, word_size * oopSize, total * oopSize); } AgeTableTracer::send_tenuring_distribution_event(age, word_size * oopSize); diff --git a/src/hotspot/share/gc/shared/ageTableTracer.cpp b/src/hotspot/share/gc/shared/ageTableTracer.cpp index 5e0fbcfbcb11e..c178ce99f565c 100644 --- a/src/hotspot/share/gc/shared/ageTableTracer.cpp +++ b/src/hotspot/share/gc/shared/ageTableTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/ageTableTracer.hpp" #include "gc/shared/gcId.hpp" #include "jfr/jfrEvents.hpp" diff --git a/src/hotspot/share/gc/shared/allocTracer.cpp b/src/hotspot/share/gc/shared/allocTracer.cpp index 45fa0c7e631bd..bfd4ed75914af 100644 --- a/src/hotspot/share/gc/shared/allocTracer.cpp +++ b/src/hotspot/share/gc/shared/allocTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/allocTracer.hpp" #include "jfr/jfrEvents.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/barrierSet.cpp b/src/hotspot/share/gc/shared/barrierSet.cpp index c3a0c9cbbff0d..65ad476adc426 100644 --- a/src/hotspot/share/gc/shared/barrierSet.cpp +++ b/src/hotspot/share/gc/shared/barrierSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/share/gc/shared/barrierSetNMethod.cpp b/src/hotspot/share/gc/shared/barrierSetNMethod.cpp index d61664cf5a6fc..c5d8a7e54015f 100644 --- a/src/hotspot/share/gc/shared/barrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shared/barrierSetNMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nmethod.hpp" #include "gc/shared/barrierSet.hpp" @@ -213,3 +212,11 @@ bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) { OrderAccess::cross_modify_fence(); return result; } + +oop BarrierSetNMethod::oop_load_no_keepalive(const nmethod* nm, int index) { + return NativeAccess::oop_load(nm->oop_addr_at(index)); +} + +oop BarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) { + return NativeAccess::oop_load(nm->oop_addr_at(index)); +} diff --git a/src/hotspot/share/gc/shared/barrierSetNMethod.hpp b/src/hotspot/share/gc/shared/barrierSetNMethod.hpp index d003abe9bbe0d..756dc43b3f1da 100644 --- a/src/hotspot/share/gc/shared/barrierSetNMethod.hpp +++ b/src/hotspot/share/gc/shared/barrierSetNMethod.hpp @@ -26,6 +26,7 @@ #define SHARE_GC_SHARED_BARRIERSETNMETHOD_HPP #include "memory/allocation.hpp" +#include "oops/oopsHierarchy.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/sizes.hpp" @@ -57,6 +58,9 @@ class BarrierSetNMethod: public CHeapObj { void arm_all_nmethods(); + virtual oop oop_load_no_keepalive(const nmethod* nm, int index); + virtual oop oop_load_phantom(const nmethod* nm, int index); + #if INCLUDE_JVMCI bool verify_barrier(nmethod* nm, FormatBuffer<>& msg); #endif diff --git a/src/hotspot/share/gc/shared/barrierSetStackChunk.cpp b/src/hotspot/share/gc/shared/barrierSetStackChunk.cpp index aa5dfe787f7c6..9bbfdf5ba7ace 100644 --- a/src/hotspot/share/gc/shared/barrierSetStackChunk.cpp +++ b/src/hotspot/share/gc/shared/barrierSetStackChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSetStackChunk.hpp" #include "memory/iterator.hpp" #include "oops/access.inline.hpp" diff --git a/src/hotspot/share/gc/shared/bufferNode.cpp b/src/hotspot/share/gc/shared/bufferNode.cpp index 9baa812c56ecd..e27b1279c7904 100644 --- a/src/hotspot/share/gc/shared/bufferNode.cpp +++ b/src/hotspot/share/gc/shared/bufferNode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/bufferNode.hpp" #include "utilities/debug.hpp" #include "memory/allocation.inline.hpp" @@ -68,4 +67,3 @@ void BufferNode::Allocator::release(BufferNode* node) { node->~BufferNode(); _free_list.release(node); } - diff --git a/src/hotspot/share/gc/shared/bufferNodeList.cpp b/src/hotspot/share/gc/shared/bufferNodeList.cpp index 4a527b3d64241..768f40e0985c2 100644 --- a/src/hotspot/share/gc/shared/bufferNodeList.cpp +++ b/src/hotspot/share/gc/shared/bufferNodeList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/bufferNodeList.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp index 046a7ee586572..ac640fb88d259 100644 --- a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_Defs.hpp" #include "c1/c1_LIRGenerator.hpp" #include "classfile/javaClasses.hpp" diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp index 21b1ef7ea7e54..1cf629ca6b21c 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/c1/cardTableBarrierSetC1.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" diff --git a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp index c2074c2859fe3..d7d463d252e4e 100644 --- a/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/modRefBarrierSetC1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/c1/modRefBarrierSetC1.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp index 080af1c9693ed..b0082b6444df2 100644 --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/vmreg.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/tlab_globals.hpp" @@ -897,6 +896,262 @@ void BarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac #undef XTOP +static bool block_has_safepoint(const Block* block, uint from, uint to) { + for (uint i = from; i < to; i++) { + if (block->get_node(i)->is_MachSafePoint()) { + // Safepoint found + return true; + } + } + + // Safepoint not found + return false; +} + +static bool block_has_safepoint(const Block* block) { + return block_has_safepoint(block, 0, block->number_of_nodes()); +} + +static uint block_index(const Block* block, const Node* node) { + for (uint j = 0; j < block->number_of_nodes(); ++j) { + if (block->get_node(j) == node) { + return j; + } + } + ShouldNotReachHere(); + return 0; +} + +// Look through various node aliases +static const Node* look_through_node(const Node* node) { + while (node != nullptr) { + const Node* new_node = node; + if (node->is_Mach()) { + const MachNode* const node_mach = node->as_Mach(); + if (node_mach->ideal_Opcode() == Op_CheckCastPP) { + new_node = node->in(1); + } + if (node_mach->is_SpillCopy()) { + new_node = node->in(1); + } + } + if (new_node == node || new_node == nullptr) { + break; + } else { + node = new_node; + } + } + + return node; +} + +// Whether the given offset is undefined. +static bool is_undefined(intptr_t offset) { + return offset == Type::OffsetTop; +} + +// Whether the given offset is unknown. +static bool is_unknown(intptr_t offset) { + return offset == Type::OffsetBot; +} + +// Whether the given offset is concrete (defined and compile-time known). +static bool is_concrete(intptr_t offset) { + return !is_undefined(offset) && !is_unknown(offset); +} + +// Compute base + offset components of the memory address accessed by mach. +// Return a node representing the base address, or null if the base cannot be +// found or the offset is undefined or a concrete negative value. If a non-null +// base is returned, the offset is a concrete, nonnegative value or unknown. +static const Node* get_base_and_offset(const MachNode* mach, intptr_t& offset) { + const TypePtr* adr_type = nullptr; + offset = 0; + const Node* base = mach->get_base_and_disp(offset, adr_type); + + if (base == nullptr || base == NodeSentinel) { + return nullptr; + } + + if (offset == 0 && base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_AddP) { + // The memory address is computed by 'base' and fed to 'mach' via an + // indirect memory operand (indicated by offset == 0). The ultimate base and + // offset can be fetched directly from the inputs and Ideal type of 'base'. + const TypeOopPtr* oopptr = base->bottom_type()->isa_oopptr(); + if (oopptr == nullptr) return nullptr; + offset = oopptr->offset(); + // Even if 'base' is not an Ideal AddP node anymore, Matcher::ReduceInst() + // guarantees that the base address is still available at the same slot. + base = base->in(AddPNode::Base); + assert(base != nullptr, ""); + } + + if (is_undefined(offset) || (is_concrete(offset) && offset < 0)) { + return nullptr; + } + + return look_through_node(base); +} + +// Whether a phi node corresponds to an array allocation. +// This test is incomplete: in some edge cases, it might return false even +// though the node does correspond to an array allocation. +static bool is_array_allocation(const Node* phi) { + precond(phi->is_Phi()); + // Check whether phi has a successor cast (CheckCastPP) to Java array pointer, + // possibly below spill copies and other cast nodes. Limit the exploration to + // a single path from the phi node consisting of these node types. + const Node* current = phi; + while (true) { + const Node* next = nullptr; + for (DUIterator_Fast imax, i = current->fast_outs(imax); i < imax; i++) { + if (!current->fast_out(i)->isa_Mach()) { + continue; + } + const MachNode* succ = current->fast_out(i)->as_Mach(); + if (succ->ideal_Opcode() == Op_CheckCastPP) { + if (succ->get_ptr_type()->isa_aryptr()) { + // Cast to Java array pointer: phi corresponds to an array allocation. + return true; + } + // Other cast: record as candidate for further exploration. + next = succ; + } else if (succ->is_SpillCopy() && next == nullptr) { + // Spill copy, and no better candidate found: record as candidate. + next = succ; + } + } + if (next == nullptr) { + // No evidence found that phi corresponds to an array allocation, and no + // candidates available to continue exploring. + return false; + } + // Continue exploring from the best candidate found. + current = next; + } + ShouldNotReachHere(); +} + +bool BarrierSetC2::is_allocation(const Node* node) { + assert(node->is_Phi(), "expected phi node"); + if (node->req() != 3) { + return false; + } + const Node* const fast_node = node->in(2); + if (!fast_node->is_Mach()) { + return false; + } + const MachNode* const fast_mach = fast_node->as_Mach(); + if (fast_mach->ideal_Opcode() != Op_LoadP) { + return false; + } + intptr_t offset; + const Node* const base = get_base_and_offset(fast_mach, offset); + if (base == nullptr || !base->is_Mach() || !is_concrete(offset)) { + return false; + } + const MachNode* const base_mach = base->as_Mach(); + if (base_mach->ideal_Opcode() != Op_ThreadLocal) { + return false; + } + return offset == in_bytes(Thread::tlab_top_offset()); +} + +void BarrierSetC2::elide_dominated_barriers(Node_List& accesses, Node_List& access_dominators) const { + Compile* const C = Compile::current(); + PhaseCFG* const cfg = C->cfg(); + + for (uint i = 0; i < accesses.size(); i++) { + MachNode* const access = accesses.at(i)->as_Mach(); + intptr_t access_offset; + const Node* const access_obj = get_base_and_offset(access, access_offset); + Block* const access_block = cfg->get_block_for_node(access); + const uint access_index = block_index(access_block, access); + + if (access_obj == nullptr) { + // No information available + continue; + } + + for (uint j = 0; j < access_dominators.size(); j++) { + const Node* const mem = access_dominators.at(j); + if (mem->is_Phi()) { + assert(is_allocation(mem), "expected allocation phi node"); + if (mem != access_obj) { + continue; + } + if (is_unknown(access_offset) && !is_array_allocation(mem)) { + // The accessed address has an unknown offset, but the allocated + // object cannot be determined to be an array. Avoid eliding in this + // case, to be on the safe side. + continue; + } + assert((is_concrete(access_offset) && access_offset >= 0) || (is_unknown(access_offset) && is_array_allocation(mem)), + "candidate allocation-dominated access offsets must be either concrete and nonnegative, or unknown (for array allocations only)"); + } else { + // Access node + const MachNode* const mem_mach = mem->as_Mach(); + intptr_t mem_offset; + const Node* const mem_obj = get_base_and_offset(mem_mach, mem_offset); + + if (mem_obj == nullptr || + !is_concrete(access_offset) || + !is_concrete(mem_offset)) { + // No information available + continue; + } + + if (mem_obj != access_obj || mem_offset != access_offset) { + // Not the same addresses, not a candidate + continue; + } + assert(is_concrete(access_offset) && access_offset >= 0, + "candidate non-allocation-dominated access offsets must be concrete and nonnegative"); + } + + Block* mem_block = cfg->get_block_for_node(mem); + const uint mem_index = block_index(mem_block, mem); + + if (access_block == mem_block) { + // Earlier accesses in the same block + if (mem_index < access_index && !block_has_safepoint(mem_block, mem_index + 1, access_index)) { + elide_dominated_barrier(access); + } + } else if (mem_block->dominates(access_block)) { + // Dominating block? Look around for safepoints + ResourceMark rm; + Block_List stack; + VectorSet visited; + stack.push(access_block); + bool safepoint_found = block_has_safepoint(access_block); + while (!safepoint_found && stack.size() > 0) { + const Block* const block = stack.pop(); + if (visited.test_set(block->_pre_order)) { + continue; + } + if (block_has_safepoint(block)) { + safepoint_found = true; + break; + } + if (block == mem_block) { + continue; + } + + // Push predecessor blocks + for (uint p = 1; p < block->num_preds(); ++p) { + Block* const pred = cfg->get_block_for_node(block->pred(p)); + stack.push(pred); + } + } + + if (!safepoint_found) { + elide_dominated_barrier(access); + } + } + } + } +} + void BarrierSetC2::compute_liveness_at_stubs() const { ResourceMark rm; Compile* const C = Compile::current(); diff --git a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp index a78fd434ad94e..7b9cb985cff6e 100644 --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -364,6 +364,14 @@ class BarrierSetC2: public CHeapObj { virtual bool matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const { return false; }; virtual bool matcher_is_store_load_barrier(Node* x, uint xop) const { return false; } + // Whether the given phi node joins OOPs from fast and slow allocation paths. + static bool is_allocation(const Node* node); + // Elide GC barriers from a Mach node according to elide_dominated_barriers(). + virtual void elide_dominated_barrier(MachNode* mach) const { } + // Elide GC barriers from instructions in 'accesses' if they are dominated by + // instructions in 'access_dominators' (according to elide_mach_barrier()) and + // there is no safepoint poll in between. + void elide_dominated_barriers(Node_List& accesses, Node_List& access_dominators) const; virtual void late_barrier_analysis() const { } virtual void compute_liveness_at_stubs() const; virtual int estimate_stub_size() const { return 0; } diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp index 7997492188b9d..7df210d9fb622 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciUtilities.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -50,13 +49,9 @@ Node* CardTableBarrierSetC2::byte_map_base_node(GraphKit* kit) const { // Insert a write-barrier store. This is to let generational GC work; we have // to flag all oop-stores before the next GC point. void CardTableBarrierSetC2::post_barrier(GraphKit* kit, - Node* ctl, - Node* oop_store, Node* obj, Node* adr, - uint adr_idx, Node* val, - BasicType bt, bool use_precise) const { // No store check needed if we're storing a null. if (val != nullptr && val->is_Con()) { @@ -125,7 +120,7 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, kit->final_sync(ideal); } -bool CardTableBarrierSetC2::use_ReduceInitialCardMarks() const { +bool CardTableBarrierSetC2::use_ReduceInitialCardMarks() { return ReduceInitialCardMarks; } diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp index 3abb6068f4a47..1263030a8b5a3 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,13 +30,9 @@ class CardTableBarrierSetC2: public ModRefBarrierSetC2 { protected: virtual void post_barrier(GraphKit* kit, - Node* ctl, - Node* store, Node* obj, Node* adr, - uint adr_idx, Node* val, - BasicType bt, bool use_precise) const; Node* byte_map_base_node(GraphKit* kit) const; @@ -45,7 +41,7 @@ class CardTableBarrierSetC2: public ModRefBarrierSetC2 { virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const; virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, bool is_clone_instance, ArrayCopyPhase phase) const; - bool use_ReduceInitialCardMarks() const; + static bool use_ReduceInitialCardMarks(); }; #endif // SHARE_GC_SHARED_C2_CARDTABLEBARRIERSETC2_HPP diff --git a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp index a8a1fb58fce16..cf5d3fc7e1668 100644 --- a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,18 +22,14 @@ * */ -#include "precompiled.hpp" #include "opto/arraycopynode.hpp" #include "opto/graphKit.hpp" #include "opto/idealKit.hpp" -#include "opto/narrowptrnode.hpp" #include "gc/shared/c2/modRefBarrierSetC2.hpp" -#include "utilities/macros.hpp" Node* ModRefBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const { DecoratorSet decorators = access.decorators(); - const TypePtr* adr_type = access.addr().type(); Node* adr = access.addr().node(); bool is_array = (decorators & IS_ARRAY) != 0; @@ -48,36 +44,22 @@ Node* ModRefBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val assert(access.is_parse_access(), "entry not supported at optimization time"); C2ParseAccess& parse_access = static_cast(access); - GraphKit* kit = parse_access.kit(); - uint adr_idx = kit->C->get_alias_index(adr_type); - assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); - - pre_barrier(kit, true /* do_load */, kit->control(), access.base(), adr, adr_idx, val.node(), - static_cast(val.type()), nullptr /* pre_val */, access.type()); Node* store = BarrierSetC2::store_at_resolved(access, val); - post_barrier(kit, kit->control(), access.raw_access(), access.base(), adr, adr_idx, val.node(), - access.type(), use_precise); + post_barrier(parse_access.kit(), access.base(), adr, val.node(), use_precise); return store; } Node* ModRefBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* value_type) const { - GraphKit* kit = access.kit(); - if (!access.is_oop()) { return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); } - pre_barrier(kit, false /* do_load */, - kit->control(), nullptr, nullptr, max_juint, nullptr, nullptr, - expected_val /* pre_val */, T_OBJECT); - Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); - post_barrier(kit, kit->control(), access.raw_access(), access.base(), - access.addr().node(), access.alias_idx(), new_val, T_OBJECT, true); + post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); return result; } @@ -90,10 +72,6 @@ Node* ModRefBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& a return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); } - pre_barrier(kit, false /* do_load */, - kit->control(), nullptr, nullptr, max_juint, nullptr, nullptr, - expected_val /* pre_val */, T_OBJECT); - Node* load_store = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); // Emit the post barrier only when the actual store happened. This makes sense @@ -109,8 +87,7 @@ Node* ModRefBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& a IdealKit ideal(kit); ideal.if_then(load_store, BoolTest::ne, ideal.ConI(0), PROB_STATIC_FREQUENT); { kit->sync_kit(ideal); - post_barrier(kit, ideal.ctrl(), access.raw_access(), access.base(), - access.addr().node(), access.alias_idx(), new_val, T_OBJECT, true); + post_barrier(kit, access.base(), access.addr().node(), new_val, true); ideal.sync_kit(kit); } ideal.end_if(); kit->final_sync(ideal); @@ -119,21 +96,12 @@ Node* ModRefBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& a } Node* ModRefBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { - GraphKit* kit = access.kit(); - Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, value_type); if (!access.is_oop()) { return result; } - // Don't need to load pre_val. The old value is returned by load_store. - // The pre_barrier can execute after the xchg as long as no safepoint - // gets inserted between them. - pre_barrier(kit, false /* do_load */, - kit->control(), nullptr, nullptr, max_juint, nullptr, nullptr, - result /* pre_val */, T_OBJECT); - post_barrier(kit, kit->control(), access.raw_access(), access.base(), access.addr().node(), - access.alias_idx(), new_val, T_OBJECT, true); + post_barrier(access.kit(), access.base(), access.addr().node(), new_val, true); return result; } diff --git a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp index cd19076f2ca72..42fe3f7d0b6a4 100644 --- a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp +++ b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,25 +31,10 @@ class TypeOopPtr; class ModRefBarrierSetC2: public BarrierSetC2 { protected: - virtual void pre_barrier(GraphKit* kit, - bool do_load, - Node* ctl, - Node* obj, - Node* adr, - uint adr_idx, - Node* val, - const TypeOopPtr* val_type, - Node* pre_val, - BasicType bt) const {} - virtual void post_barrier(GraphKit* kit, - Node* ctl, - Node* store, Node* obj, Node* adr, - uint adr_idx, Node* val, - BasicType bt, bool use_precise) const {} virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index 53d98ba817e95..fbfc07a4e0903 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,14 +22,13 @@ * */ -#include "precompiled.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/space.hpp" #include "logging/log.hpp" -#include "memory/virtualspace.hpp" +#include "memory/memoryReserver.hpp" #include "nmt/memTracker.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" @@ -80,24 +79,24 @@ void CardTable::initialize(void* region0_start, void* region1_start) { HeapWord* low_bound = _whole_heap.start(); HeapWord* high_bound = _whole_heap.end(); - const size_t rs_align = _page_size == os::vm_page_size() ? 0 : - MAX2(_page_size, os::vm_allocation_granularity()); - ReservedSpace heap_rs(_byte_map_size, rs_align, _page_size); + const size_t rs_align = MAX2(_page_size, os::vm_allocation_granularity()); + ReservedSpace rs = MemoryReserver::reserve(_byte_map_size, rs_align, _page_size); - MemTracker::record_virtual_memory_tag((address)heap_rs.base(), mtGC); - - os::trace_page_sizes("Card Table", num_bytes, num_bytes, - heap_rs.base(), heap_rs.size(), _page_size); - if (!heap_rs.is_reserved()) { + if (!rs.is_reserved()) { vm_exit_during_initialization("Could not reserve enough space for the " "card marking array"); } + MemTracker::record_virtual_memory_tag((address)rs.base(), mtGC); + + os::trace_page_sizes("Card Table", num_bytes, num_bytes, + rs.base(), rs.size(), _page_size); + // The assembler store_check code will do an unsigned shift of the oop, // then add it to _byte_map_base, i.e. // // _byte_map = _byte_map_base + (uintptr_t(low_bound) >> card_shift) - _byte_map = (CardValue*) heap_rs.base(); + _byte_map = (CardValue*) rs.base(); _byte_map_base = _byte_map - (uintptr_t(low_bound) >> _card_shift); assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); assert(byte_for(high_bound-1) <= &_byte_map[last_valid_index()], "Checking end of map"); diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp index 1277cd9929326..84bf3eac13046 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilerDefinitions.inline.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/cardTableBarrierSet.inline.hpp" @@ -30,7 +29,6 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/space.hpp" #include "logging/log.hpp" -#include "memory/virtualspace.hpp" #include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.cpp b/src/hotspot/share/gc/shared/classUnloadingContext.cpp index fdf84d69b6a86..4eac2561e679f 100644 --- a/src/hotspot/share/gc/shared/classUnloadingContext.cpp +++ b/src/hotspot/share/gc/shared/classUnloadingContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" - #include "classfile/classLoaderData.inline.hpp" #include "code/nmethod.hpp" #include "gc/shared/classUnloadingContext.hpp" diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index 3f0447b6558df..fba9593170351 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/vmClasses.hpp" @@ -30,7 +29,7 @@ #include "gc/shared/barrierSet.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/collectedHeap.inline.hpp" -#include "gc/shared/gcLocker.inline.hpp" +#include "gc/shared/gcLocker.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/gcTrace.hpp" @@ -45,6 +44,7 @@ #include "memory/classLoaderMetaspace.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceUtils.hpp" +#include "memory/reservedSpace.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/instanceMirrorKlass.hpp" @@ -350,36 +350,10 @@ MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loa return result; } - if (GCLocker::is_active_and_needs_gc()) { - // If the GCLocker is active, just expand and allocate. - // If that does not succeed, wait if this thread is not - // in a critical section itself. - result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype); - if (result != nullptr) { - return result; - } - JavaThread* jthr = JavaThread::current(); - if (!jthr->in_critical()) { - // Wait for JNI critical section to be exited - GCLocker::stall_until_clear(); - // The GC invoked by the last thread leaving the critical - // section will be a young collection and a full collection - // is (currently) needed for unloading classes so continue - // to the next iteration to get a full GC. - continue; - } else { - if (CheckJNICalls) { - fatal("Possible deadlock due to allocating while" - " in jni critical section"); - } - return nullptr; - } - } - { // Need lock to get self consistent gc_count's MutexLocker ml(Heap_lock); - gc_count = Universe::heap()->total_collections(); - full_gc_count = Universe::heap()->total_full_collections(); + gc_count = total_collections(); + full_gc_count = total_full_collections(); } // Generate a VM operation @@ -389,13 +363,8 @@ MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loa gc_count, full_gc_count, GCCause::_metadata_GC_threshold); - VMThread::execute(&op); - // If GC was locked out, try again. Check before checking success because the - // prologue could have succeeded and the GC still have been locked out. - if (op.gc_locked()) { - continue; - } + VMThread::execute(&op); if (op.prologue_succeeded()) { return op.result(); @@ -404,7 +373,7 @@ MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loa if ((QueuedAllocationWarningCount > 0) && (loop_count % QueuedAllocationWarningCount == 0)) { log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times," - " size=" SIZE_FORMAT, loop_count, word_size); + " size=%zu", loop_count, word_size); } } while (true); // Until a GC is done } @@ -480,7 +449,7 @@ CollectedHeap::fill_with_array(HeapWord* start, size_t words, bool zap) const size_t payload_size = words - filler_array_hdr_size(); const size_t len = payload_size * HeapWordSize / sizeof(jint); - assert((int)len >= 0, "size too large " SIZE_FORMAT " becomes %d", words, (int)len); + assert((int)len >= 0, "size too large %zu becomes %d", words, (int)len); ObjArrayAllocator allocator(Universe::fillerArrayKlass(), words, (int)len, /* do_zero */ false); allocator.initialize(start); diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 036bc0230c877..31a224597a048 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -383,12 +383,10 @@ class CollectedHeap : public CHeapObj { void increment_total_collections(bool full = false) { _total_collections++; if (full) { - increment_total_full_collections(); + _total_full_collections++; } } - void increment_total_full_collections() { _total_full_collections++; } - // Return the SoftRefPolicy for the heap; SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; } diff --git a/src/hotspot/share/gc/shared/collectorCounters.cpp b/src/hotspot/share/gc/shared/collectorCounters.cpp index 3a81dc383265c..f01997f985475 100644 --- a/src/hotspot/share/gc/shared/collectorCounters.cpp +++ b/src/hotspot/share/gc/shared/collectorCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectorCounters.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.cpp b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.cpp index 9b0b4bd7b1031..3a974952fea5c 100644 --- a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.cpp +++ b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/shared/concurrentGCThread.cpp b/src/hotspot/share/gc/shared/concurrentGCThread.cpp index 04cf571749fe4..7d0cecde528bf 100644 --- a/src/hotspot/share/gc/shared/concurrentGCThread.cpp +++ b/src/hotspot/share/gc/shared/concurrentGCThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/concurrentGCThread.hpp" #include "runtime/atomic.hpp" #include "runtime/init.hpp" diff --git a/src/hotspot/share/gc/shared/freeListAllocator.cpp b/src/hotspot/share/gc/shared/freeListAllocator.cpp index ef7d12ab0242f..27f1cd8aeb373 100644 --- a/src/hotspot/share/gc/shared/freeListAllocator.cpp +++ b/src/hotspot/share/gc/shared/freeListAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/freeListAllocator.hpp" #include "logging/log.hpp" #include "utilities/globalCounter.inline.hpp" diff --git a/src/hotspot/share/gc/shared/fullGCForwarding.cpp b/src/hotspot/share/gc/shared/fullGCForwarding.cpp index 4880b08887e56..474a3209d7431 100644 --- a/src/hotspot/share/gc/shared/fullGCForwarding.cpp +++ b/src/hotspot/share/gc/shared/fullGCForwarding.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/fullGCForwarding.hpp" #include "memory/memRegion.hpp" #include "runtime/globals_extension.hpp" @@ -34,8 +33,8 @@ void FullGCForwarding::initialize_flags(size_t max_heap_size) { #ifdef _LP64 size_t max_narrow_heap_size = right_n_bits(NumLowBitsNarrow - Shift); if (UseCompactObjectHeaders && max_heap_size > max_narrow_heap_size * HeapWordSize) { - warning("Compact object headers require a java heap size smaller than " SIZE_FORMAT - "%s (given: " SIZE_FORMAT "%s). Disabling compact object headers.", + warning("Compact object headers require a java heap size smaller than %zu" + "%s (given: %zu%s). Disabling compact object headers.", byte_size_in_proper_unit(max_narrow_heap_size * HeapWordSize), proper_unit_for_byte_size(max_narrow_heap_size * HeapWordSize), byte_size_in_proper_unit(max_heap_size), diff --git a/src/hotspot/share/gc/shared/gcArguments.cpp b/src/hotspot/share/gc/shared/gcArguments.cpp index c20c8c4922ef5..d45e6a9c7ddb0 100644 --- a/src/hotspot/share/gc/shared/gcArguments.cpp +++ b/src/hotspot/share/gc/shared/gcArguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/gcArguments.hpp" #include "logging/log.hpp" @@ -99,7 +98,7 @@ void GCArguments::assert_size_info() { #endif // ASSERT void GCArguments::initialize_size_info() { - log_debug(gc, heap)("Minimum heap " SIZE_FORMAT " Initial heap " SIZE_FORMAT " Maximum heap " SIZE_FORMAT, + log_debug(gc, heap)("Minimum heap %zu Initial heap %zu Maximum heap %zu", MinHeapSize, InitialHeapSize, MaxHeapSize); DEBUG_ONLY(assert_size_info();) @@ -109,10 +108,10 @@ void GCArguments::initialize_heap_flags_and_sizes() { assert(SpaceAlignment != 0, "Space alignment not set up properly"); assert(HeapAlignment != 0, "Heap alignment not set up properly"); assert(HeapAlignment >= SpaceAlignment, - "HeapAlignment: " SIZE_FORMAT " less than SpaceAlignment: " SIZE_FORMAT, + "HeapAlignment: %zu less than SpaceAlignment: %zu", HeapAlignment, SpaceAlignment); assert(HeapAlignment % SpaceAlignment == 0, - "HeapAlignment: " SIZE_FORMAT " not aligned by SpaceAlignment: " SIZE_FORMAT, + "HeapAlignment: %zu not aligned by SpaceAlignment: %zu", HeapAlignment, SpaceAlignment); if (FLAG_IS_CMDLINE(MaxHeapSize)) { diff --git a/src/hotspot/share/gc/shared/gcBehaviours.cpp b/src/hotspot/share/gc/shared/gcBehaviours.cpp index b52ef9e7d3dc6..02971943874bd 100644 --- a/src/hotspot/share/gc/shared/gcBehaviours.cpp +++ b/src/hotspot/share/gc/shared/gcBehaviours.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "gc/shared/gcBehaviours.hpp" diff --git a/src/hotspot/share/gc/shared/gcCause.cpp b/src/hotspot/share/gc/shared/gcCause.cpp index f73d3146aa3c2..51ce73861e081 100644 --- a/src/hotspot/share/gc/shared/gcCause.cpp +++ b/src/hotspot/share/gc/shared/gcCause.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcCause.hpp" const char* GCCause::to_string(GCCause::Cause cause) { @@ -42,9 +41,6 @@ const char* GCCause::to_string(GCCause::Cause cause) { case _jvmti_force_gc: return "JvmtiEnv ForceGarbageCollection"; - case _gc_locker: - return "GCLocker Initiated GC"; - case _heap_inspection: return "Heap Inspection Initiated GC"; diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index 347e32be86a3c..bd819e8f5c909 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -47,7 +47,6 @@ class GCCause : public AllStatic { _scavenge_alot, _allocation_profiler, _jvmti_force_gc, - _gc_locker, _heap_inspection, _heap_dump, _wb_young_gc, diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp index bb9d0806a5312..402bd0caacddc 100644 --- a/src/hotspot/share/gc/shared/gcConfig.cpp +++ b/src/hotspot/share/gc/shared/gcConfig.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcConfig.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" diff --git a/src/hotspot/share/gc/shared/gcConfiguration.cpp b/src/hotspot/share/gc/shared/gcConfiguration.cpp index 4c94cfeab8b61..1c24c2353a19c 100644 --- a/src/hotspot/share/gc/shared/gcConfiguration.cpp +++ b/src/hotspot/share/gc/shared/gcConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcArguments.hpp" diff --git a/src/hotspot/share/gc/shared/gcId.cpp b/src/hotspot/share/gc/shared/gcId.cpp index 8d123386180cb..6a182e41ee27a 100644 --- a/src/hotspot/share/gc/shared/gcId.cpp +++ b/src/hotspot/share/gc/shared/gcId.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcId.hpp" #include "jvm.h" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/gc/shared/gcInitLogger.cpp b/src/hotspot/share/gc/shared/gcInitLogger.cpp index 1dfc27c533377..0a327ea7dfe2e 100644 --- a/src/hotspot/share/gc/shared/gcInitLogger.cpp +++ b/src/hotspot/share/gc/shared/gcInitLogger.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcInitLogger.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" @@ -75,7 +74,7 @@ void GCInitLogger::print_large_pages() { void GCInitLogger::print_numa() { if (UseNUMA) { log_info_p(gc, init)("NUMA Support: Enabled"); - log_info_p(gc, init)("NUMA Nodes: " SIZE_FORMAT, os::numa_get_groups_num()); + log_info_p(gc, init)("NUMA Nodes: %zu", os::numa_get_groups_num()); } else { log_info_p(gc, init)("NUMA Support: Disabled"); } @@ -91,11 +90,11 @@ void GCInitLogger::print_compressed_oops() { } void GCInitLogger::print_heap() { - log_info_p(gc, init)("Heap Min Capacity: " SIZE_FORMAT "%s", + log_info_p(gc, init)("Heap Min Capacity: %zu%s", byte_size_in_exact_unit(MinHeapSize), exact_unit_for_byte_size(MinHeapSize)); - log_info_p(gc, init)("Heap Initial Capacity: " SIZE_FORMAT "%s", + log_info_p(gc, init)("Heap Initial Capacity: %zu%s", byte_size_in_exact_unit(InitialHeapSize), exact_unit_for_byte_size(InitialHeapSize)); - log_info_p(gc, init)("Heap Max Capacity: " SIZE_FORMAT "%s", + log_info_p(gc, init)("Heap Max Capacity: %zu%s", byte_size_in_exact_unit(MaxHeapSize), exact_unit_for_byte_size(MaxHeapSize)); log_info_p(gc, init)("Pre-touch: %s", AlwaysPreTouch ? "Enabled" : "Disabled"); diff --git a/src/hotspot/share/gc/shared/gcLocker.cpp b/src/hotspot/share/gc/shared/gcLocker.cpp index d4e10b2671225..aa13209a37a02 100644 --- a/src/hotspot/share/gc/shared/gcLocker.cpp +++ b/src/hotspot/share/gc/shared/gcLocker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/gcTrace.hpp" @@ -30,15 +29,13 @@ #include "memory/universe.hpp" #include "logging/log.hpp" #include "runtime/atomic.hpp" +#include "runtime/interfaceSupport.inline.hpp" #include "runtime/javaThread.inline.hpp" #include "runtime/safepoint.hpp" +#include "utilities/spinYield.hpp" #include "runtime/threadSMR.hpp" #include "utilities/ticks.hpp" -volatile jint GCLocker::_jni_lock_count = 0; -volatile bool GCLocker::_needs_gc = false; -unsigned int GCLocker::_total_collections = 0; - // GCLockerTimingDebugLogger tracks specific timing information for GC lock waits. class GCLockerTimingDebugLogger : public StackObj { const char* _log_message; @@ -47,7 +44,9 @@ class GCLockerTimingDebugLogger : public StackObj { public: GCLockerTimingDebugLogger(const char* log_message) : _log_message(log_message) { assert(_log_message != nullptr, "GC locker debug message must be set."); - _start = Ticks::now(); + if (log_is_enabled(Debug, gc, jni)) { + _start = Ticks::now(); + } } ~GCLockerTimingDebugLogger() { @@ -60,138 +59,89 @@ class GCLockerTimingDebugLogger : public StackObj { } }; -#ifdef ASSERT -volatile jint GCLocker::_debug_jni_lock_count = 0; -#endif +Monitor* GCLocker::_lock; +volatile bool GCLocker::_is_gc_request_pending; +DEBUG_ONLY(uint64_t GCLocker::_verify_in_cr_count;) -#ifdef ASSERT -void GCLocker::verify_critical_count() { - if (SafepointSynchronize::is_at_safepoint()) { - assert(!needs_gc() || _debug_jni_lock_count == _jni_lock_count, "must agree"); - int count = 0; - // Count the number of threads with critical operations in progress - JavaThreadIteratorWithHandle jtiwh; - for (; JavaThread *thr = jtiwh.next(); ) { - if (thr->in_critical()) { - count++; - } - } - if (_jni_lock_count != count) { - log_error(gc, verify)("critical counts don't match: %d != %d", _jni_lock_count, count); - jtiwh.rewind(); - for (; JavaThread *thr = jtiwh.next(); ) { - if (thr->in_critical()) { - log_error(gc, verify)(PTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical()); - } - } +void GCLocker::initialize() { + assert(Heap_lock != nullptr, "inv"); + _lock = Heap_lock; + _is_gc_request_pending = false; + + DEBUG_ONLY(_verify_in_cr_count = 0;) +} + +bool GCLocker::is_active() { + for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); /* empty */) { + if (cur->in_critical_atomic()) { + return true; } - assert(_jni_lock_count == count, "must be equal"); } + return false; } -// In debug mode track the locking state at all times -void GCLocker::increment_debug_jni_lock_count() { - assert(_debug_jni_lock_count >= 0, "bad value"); - Atomic::inc(&_debug_jni_lock_count); -} +void GCLocker::block() { + assert(_lock->is_locked(), "precondition"); + assert(Atomic::load(&_is_gc_request_pending) == false, "precondition"); -void GCLocker::decrement_debug_jni_lock_count() { - assert(_debug_jni_lock_count > 0, "bad value"); - Atomic::dec(&_debug_jni_lock_count); -} -#endif + GCLockerTimingDebugLogger logger("Thread blocked to start GC."); -void GCLocker::log_debug_jni(const char* msg) { - Log(gc, jni) log; - if (log.is_debug()) { - ResourceMark rm; // JavaThread::name() allocates to convert to UTF8 - log.debug("%s Thread \"%s\" %d locked.", msg, Thread::current()->name(), _jni_lock_count); - } -} + Atomic::store(&_is_gc_request_pending, true); -bool GCLocker::is_at_safepoint() { - return SafepointSynchronize::is_at_safepoint(); -} + // The _is_gc_request_pending and _jni_active_critical (inside + // in_critical_atomic()) variables form a Dekker duality. On the GC side, the + // _is_gc_request_pending is set and _jni_active_critical is subsequently + // loaded. For Java threads, the opposite is true, just like a Dekker lock. + // That's why there is a fence to order the accesses involved in the Dekker + // synchronization. + OrderAccess::fence(); -bool GCLocker::check_active_before_gc() { - assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); - if (is_active() && !_needs_gc) { - verify_critical_count(); - _needs_gc = true; - GCLockerTracer::start_gc_locker(_jni_lock_count); - log_debug_jni("Setting _needs_gc."); - } - return is_active(); -} + JavaThread* java_thread = JavaThread::current(); + ThreadBlockInVM tbivm(java_thread); -void GCLocker::stall_until_clear() { - assert(!JavaThread::current()->in_critical(), "Would deadlock"); - MonitorLocker ml(JNICritical_lock); - - if (needs_gc()) { - GCLockerTracer::inc_stall_count(); - log_debug_jni("Allocation failed. Thread stalled by JNI critical section."); - GCLockerTimingDebugLogger logger("Thread stalled by JNI critical section."); - // Wait for _needs_gc to be cleared - while (needs_gc()) { - ml.wait(); + // Wait for threads leaving critical section + SpinYield spin_yield; + for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); /* empty */) { + while (cur->in_critical_atomic()) { + spin_yield.wait(); } } -} -bool GCLocker::should_discard(GCCause::Cause cause, uint total_collections) { - return (cause == GCCause::_gc_locker) && - (_total_collections != total_collections); +#ifdef ASSERT + // Matching the storestore in GCLocker::exit. + OrderAccess::loadload(); + assert(Atomic::load(&_verify_in_cr_count) == 0, "inv"); +#endif } -void GCLocker::jni_lock(JavaThread* thread) { - assert(!thread->in_critical(), "shouldn't currently be in a critical region"); - MonitorLocker ml(JNICritical_lock); - // Block entering threads if there's a pending GC request. - if (needs_gc()) { - log_debug_jni("Blocking thread as there is a pending GC request"); - GCLockerTimingDebugLogger logger("Thread blocked to enter critical region."); - while (needs_gc()) { - // There's at least one thread that has not left the critical region (CR) - // completely. When that last thread (no new threads can enter CR due to the - // blocking) exits CR, it calls `jni_unlock`, which sets `_needs_gc` - // to false and wakes up all blocked threads. - // We would like to assert #threads in CR to be > 0, `_jni_lock_count > 0` - // in the code, but it's too strong; it's possible that the last thread - // has called `jni_unlock`, but not yet finished the call, e.g. initiating - // a GCCause::_gc_locker GC. - ml.wait(); - } - } - thread->enter_critical(); - _jni_lock_count++; - increment_debug_jni_lock_count(); +void GCLocker::unblock() { + assert(_lock->is_locked(), "precondition"); + assert(Atomic::load(&_is_gc_request_pending) == true, "precondition"); + + Atomic::store(&_is_gc_request_pending, false); } -void GCLocker::jni_unlock(JavaThread* thread) { - assert(thread->in_last_critical(), "should be exiting critical region"); - MutexLocker mu(JNICritical_lock); - _jni_lock_count--; - decrement_debug_jni_lock_count(); - log_debug_jni("Thread exiting critical region."); - thread->exit_critical(); - if (needs_gc() && !is_active_internal()) { - // We're the last thread out. Request a GC. - // Capture the current total collections, to allow detection of - // other collections that make this one unnecessary. The value of - // total_collections() is only changed at a safepoint, so there - // must not be a safepoint between the lock becoming inactive and - // getting the count, else there may be unnecessary GCLocker GCs. - _total_collections = Universe::heap()->total_collections(); - GCLockerTracer::report_gc_locker(); +void GCLocker::enter_slow(JavaThread* current_thread) { + assert(current_thread == JavaThread::current(), "Must be this thread"); + + GCLockerTimingDebugLogger logger("Thread blocked to enter critical region."); + while (true) { { - // Must give up the lock while at a safepoint - MutexUnlocker munlock(JNICritical_lock); - log_debug_jni("Last thread exiting. Performing GC after exiting critical section."); - Universe::heap()->collect(GCCause::_gc_locker); + // There is a pending gc request and _lock is locked. Wait for the + // completion of a gc. It's enough to do an empty locker section. + MutexLocker locker(_lock); } - _needs_gc = false; - JNICritical_lock->notify_all(); + + current_thread->enter_critical(); + + // Same as fast path. + OrderAccess::fence(); + + if (!Atomic::load(&_is_gc_request_pending)) { + return; + } + + current_thread->exit_critical(); } } diff --git a/src/hotspot/share/gc/shared/gcLocker.hpp b/src/hotspot/share/gc/shared/gcLocker.hpp index e567d0c1f1689..33d10f0eecd0c 100644 --- a/src/hotspot/share/gc/shared/gcLocker.hpp +++ b/src/hotspot/share/gc/shared/gcLocker.hpp @@ -27,126 +27,43 @@ #include "gc/shared/gcCause.hpp" #include "memory/allStatic.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/macros.hpp" - -class JavaThread; - -// The direct lock/unlock calls do not force a collection if an unlock -// decrements the count to zero. Avoid calling these if at all possible. +#include "runtime/mutex.hpp" + +// GCLocker provides synchronization between the garbage collector (GC) and +// threads using JNI critical APIs. When threads enter a critical region (CR), +// certain GC implementations may suspend garbage collection until all such +// threads have exited. +// +// Threads that need to trigger a GC should use the `block()` and `unblock()` +// APIs. `block()` will block the caller and prevent new threads from entering +// the CR. +// +// Threads entering or exiting a CR must call the `enter` and `exit` APIs to +// ensure proper synchronization with the GC. class GCLocker: public AllStatic { - private: - // The _jni_lock_count keeps track of the number of threads that are - // currently in a critical region. It's only kept up to date when - // _needs_gc is true. The current value is computed during - // safepointing and decremented during the slow path of GCLocker - // unlocking. - static volatile jint _jni_lock_count; // number of jni active instances. - static volatile bool _needs_gc; // heap is filling, we need a GC - static uint _total_collections; // value for _gc_locker collection + static Monitor* _lock; + static volatile bool _is_gc_request_pending; #ifdef ASSERT - // This lock count is updated for all operations and is used to - // validate the jni_lock_count that is computed during safepoints. - static volatile jint _debug_jni_lock_count; + // Debug-only: to track the number of java threads in critical-region. + static uint64_t _verify_in_cr_count; #endif + static void enter_slow(JavaThread* current_thread); - // At a safepoint, visit all threads and count the number of active - // critical sections. This is used to ensure that all active - // critical sections are exited before a new one is started. - static void verify_critical_count() NOT_DEBUG_RETURN; - - static void jni_lock(JavaThread* thread); - static void jni_unlock(JavaThread* thread); - - static bool is_active_internal() { - verify_critical_count(); - return _jni_lock_count > 0; - } - - static void log_debug_jni(const char* msg); - - static bool is_at_safepoint(); - - public: - // Accessors - static bool is_active() { - assert(GCLocker::is_at_safepoint(), "only read at safepoint"); - return is_active_internal(); - } - static bool needs_gc() { return _needs_gc; } - - // Shorthand - static bool is_active_and_needs_gc() { - // Use is_active_internal since _needs_gc can change from true to - // false outside of a safepoint, triggering the assert in - // is_active. - return needs_gc() && is_active_internal(); - } - - // In debug mode track the locking state at all times - static void increment_debug_jni_lock_count() NOT_DEBUG_RETURN; - static void decrement_debug_jni_lock_count() NOT_DEBUG_RETURN; - - // Set the current lock count - static void set_jni_lock_count(int count) { - _jni_lock_count = count; - verify_critical_count(); - } - - // Sets _needs_gc if is_active() is true. Returns is_active(). - static bool check_active_before_gc(); +public: + static void initialize(); - // Return true if the designated collection is a GCLocker request - // that should be discarded. Returns true if cause == GCCause::_gc_locker - // and the given total collection value indicates a collection has been - // done since the GCLocker request was made. - static bool should_discard(GCCause::Cause cause, uint total_collections); + // To query current GCLocker state. Can become outdated if called outside a safepoint. + static bool is_active(); - // Stalls the caller (who should not be in a jni critical section) - // until needs_gc() clears. Note however that needs_gc() may be - // set at a subsequent safepoint and/or cleared under the - // JNICritical_lock, so the caller may not safely assert upon - // return from this method that "!needs_gc()" since that is - // not a stable predicate. - static void stall_until_clear(); + // For use by Java threads requesting GC. + static void block(); + static void unblock(); - // The following two methods are used for JNI critical regions. - // If we find that we failed to perform a GC because the GCLocker - // was active, arrange for one as soon as possible by allowing - // all threads in critical regions to complete, but not allowing - // other critical regions to be entered. The reasons for that are: - // 1) a GC request won't be starved by overlapping JNI critical - // region activities, which can cause unnecessary OutOfMemory errors. - // 2) even if allocation requests can still be satisfied before GC locker - // becomes inactive, for example, in tenured generation possibly with - // heap expansion, those allocations can trigger lots of safepointing - // attempts (ineffective GC attempts) and require Heap_lock which - // slow down allocations tremendously. - // - // Note that critical regions can be nested in a single thread, so - // we must allow threads already in critical regions to continue. - // - // JNI critical regions are the only participants in this scheme - // because they are, by spec, well bounded while in a critical region. - // - // Each of the following two method is split into a fast path and a - // slow path. JNICritical_lock is only grabbed in the slow path. - // _needs_gc is initially false and every java thread will go - // through the fast path, which simply increments or decrements the - // current thread's critical count. When GC happens at a safepoint, - // GCLocker::is_active() is checked. Since there is no safepoint in - // the fast path of lock_critical() and unlock_critical(), there is - // no race condition between the fast path and GC. After _needs_gc - // is set at a safepoint, every thread will go through the slow path - // after the safepoint. Since after a safepoint, each of the - // following two methods is either entered from the method entry and - // falls into the slow path, or is resumed from the safepoints in - // the method, which only exist in the slow path. So when _needs_gc - // is set, the slow path is always taken, till _needs_gc is cleared. - inline static void lock_critical(JavaThread* thread); - inline static void unlock_critical(JavaThread* thread); + // For use by Java threads entering/leaving critical-region. + inline static void enter(JavaThread* current_thread); + inline static void exit(JavaThread* current_thread); }; #endif // SHARE_GC_SHARED_GCLOCKER_HPP diff --git a/src/hotspot/share/gc/shared/gcLocker.inline.hpp b/src/hotspot/share/gc/shared/gcLocker.inline.hpp index 82cc4bb544235..357b788ce52d0 100644 --- a/src/hotspot/share/gc/shared/gcLocker.inline.hpp +++ b/src/hotspot/share/gc/shared/gcLocker.inline.hpp @@ -29,30 +29,39 @@ #include "runtime/javaThread.inline.hpp" -void GCLocker::lock_critical(JavaThread* thread) { - if (!thread->in_critical()) { - if (needs_gc()) { - // jni_lock call calls enter_critical under the lock so that the - // global lock count and per thread count are in agreement. - jni_lock(thread); - return; +void GCLocker::enter(JavaThread* current_thread) { + assert(current_thread == JavaThread::current(), "Must be this thread"); + + if (!current_thread->in_critical()) { + current_thread->enter_critical(); + + // Matching the fence in GCLocker::block. + OrderAccess::fence(); + + if (Atomic::load(&_is_gc_request_pending)) { + current_thread->exit_critical(); + // slow-path + enter_slow(current_thread); } - increment_debug_jni_lock_count(); + + DEBUG_ONLY(Atomic::add(&_verify_in_cr_count, (uint64_t)1);) + } else { + current_thread->enter_critical(); } - thread->enter_critical(); } -void GCLocker::unlock_critical(JavaThread* thread) { - if (thread->in_last_critical()) { - if (needs_gc()) { - // jni_unlock call calls exit_critical under the lock so that - // the global lock count and per thread count are in agreement. - jni_unlock(thread); - return; - } - decrement_debug_jni_lock_count(); +void GCLocker::exit(JavaThread* current_thread) { + assert(current_thread == JavaThread::current(), "Must be this thread"); + +#ifdef ASSERT + if (current_thread->in_last_critical()) { + Atomic::add(&_verify_in_cr_count, (uint64_t)-1); + // Matching the loadload in GCLocker::block. + OrderAccess::storestore(); } - thread->exit_critical(); +#endif + + current_thread->exit_critical(); } #endif // SHARE_GC_SHARED_GCLOCKER_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/gcLogPrecious.cpp b/src/hotspot/share/gc/shared/gcLogPrecious.cpp index afc42e7cfcc46..43bd58db1aa08 100644 --- a/src/hotspot/share/gc/shared/gcLogPrecious.cpp +++ b/src/hotspot/share/gc/shared/gcLogPrecious.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/gc/shared/gcOverheadChecker.cpp b/src/hotspot/share/gc/shared/gcOverheadChecker.cpp index 4eb5a459e7474..c6c89a51f54b6 100644 --- a/src/hotspot/share/gc/shared/gcOverheadChecker.cpp +++ b/src/hotspot/share/gc/shared/gcOverheadChecker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Google and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcOverheadChecker.hpp" #include "gc/shared/softRefPolicy.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/shared/gcPolicyCounters.cpp b/src/hotspot/share/gc/shared/gcPolicyCounters.cpp index dba53e9ee3193..d24ad745aa14d 100644 --- a/src/hotspot/share/gc/shared/gcPolicyCounters.cpp +++ b/src/hotspot/share/gc/shared/gcPolicyCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gc_globals.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/shared/gcTimer.cpp b/src/hotspot/share/gc/shared/gcTimer.cpp index e293cb335a89d..8585975015184 100644 --- a/src/hotspot/share/gc/shared/gcTimer.cpp +++ b/src/hotspot/share/gc/shared/gcTimer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gc_globals.hpp" #include "utilities/growableArray.hpp" diff --git a/src/hotspot/share/gc/shared/gcTrace.cpp b/src/hotspot/share/gc/shared/gcTrace.cpp index 1c84c3ca88bdc..bad9c707b1e51 100644 --- a/src/hotspot/share/gc/shared/gcTrace.cpp +++ b/src/hotspot/share/gc/shared/gcTrace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcId.hpp" diff --git a/src/hotspot/share/gc/shared/gcTrace.hpp b/src/hotspot/share/gc/shared/gcTrace.hpp index 9c747e139df1d..6a47e54090f88 100644 --- a/src/hotspot/share/gc/shared/gcTrace.hpp +++ b/src/hotspot/share/gc/shared/gcTrace.hpp @@ -212,19 +212,4 @@ class DefNewTracer : public YoungGCTracer, public CHeapObj { DefNewTracer() : YoungGCTracer(DefNew) {} }; -class GCLockerTracer : public AllStatic { -#if INCLUDE_JFR -private: - static Ticks _needs_gc_start_timestamp; - static volatile jint _jni_lock_count; - static volatile jint _stall_count; -#endif - - static bool is_started() NOT_JFR_RETURN_(false); - -public: - static void start_gc_locker(jint jni_lock_count) NOT_JFR_RETURN(); - static void inc_stall_count() NOT_JFR_RETURN(); - static void report_gc_locker() NOT_JFR_RETURN(); -}; #endif // SHARE_GC_SHARED_GCTRACE_HPP diff --git a/src/hotspot/share/gc/shared/gcTraceSend.cpp b/src/hotspot/share/gc/shared/gcTraceSend.cpp index 31ec2871cd05e..e244930079f89 100644 --- a/src/hotspot/share/gc/shared/gcTraceSend.cpp +++ b/src/hotspot/share/gc/shared/gcTraceSend.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcTimer.hpp" @@ -359,49 +358,3 @@ void GCTracer::send_phase_events(TimePartitions* time_partitions) const { phase->accept(&phase_reporter); } } - -#if INCLUDE_JFR -Ticks GCLockerTracer::_needs_gc_start_timestamp; -volatile jint GCLockerTracer::_jni_lock_count = 0; -volatile jint GCLockerTracer::_stall_count = 0; - -bool GCLockerTracer::is_started() { - return _needs_gc_start_timestamp != Ticks(); -} - -void GCLockerTracer::start_gc_locker(const jint jni_lock_count) { - assert(SafepointSynchronize::is_at_safepoint(), "sanity"); - assert(!is_started(), "sanity"); - assert(_jni_lock_count == 0, "sanity"); - assert(_stall_count == 0, "sanity"); - if (EventGCLocker::is_enabled()) { - _needs_gc_start_timestamp.stamp(); - _jni_lock_count = jni_lock_count; - } -} - -void GCLockerTracer::inc_stall_count() { - if (is_started()) { - _stall_count++; - } -} - -void GCLockerTracer::report_gc_locker() { - if (is_started()) { - EventGCLocker event(UNTIMED); - if (event.should_commit()) { - event.set_starttime(_needs_gc_start_timestamp); - event.set_endtime(_needs_gc_start_timestamp); - event.set_lockCount(_jni_lock_count); - event.set_stallCount(_stall_count); - event.commit(); - } - // reset - _needs_gc_start_timestamp = Ticks(); - _jni_lock_count = 0; - _stall_count = 0; - - assert(!is_started(), "sanity"); - } -} -#endif diff --git a/src/hotspot/share/gc/shared/gcTraceTime.cpp b/src/hotspot/share/gc/shared/gcTraceTime.cpp index af375039d12e2..def8a3f3f5c0c 100644 --- a/src/hotspot/share/gc/shared/gcTraceTime.cpp +++ b/src/hotspot/share/gc/shared/gcTraceTime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/gcTrace.hpp" @@ -63,7 +62,7 @@ void GCTraceTimeLoggerImpl::log_end(Ticks end) { size_t used_before_m = _heap_usage_before / M; size_t used_m = heap->used() / M; size_t capacity_m = heap->capacity() / M; - out.print(" " SIZE_FORMAT "M->" SIZE_FORMAT "M(" SIZE_FORMAT "M)", used_before_m, used_m, capacity_m); + out.print(" %zuM->%zuM(%zuM)", used_before_m, used_m, capacity_m); } out.print_cr(" %.3fms", duration_in_ms); diff --git a/src/hotspot/share/gc/shared/gcUtil.cpp b/src/hotspot/share/gc/shared/gcUtil.cpp index 2c4010e75983b..6a4aa6d53dd25 100644 --- a/src/hotspot/share/gc/shared/gcUtil.cpp +++ b/src/hotspot/share/gc/shared/gcUtil.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcUtil.hpp" // Catch-all file for utility classes diff --git a/src/hotspot/share/gc/shared/gcVMOperations.cpp b/src/hotspot/share/gc/shared/gcVMOperations.cpp index 4cc75f4745991..b28007962d3e2 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.cpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" #include "gc/shared/allocTracer.hpp" @@ -86,19 +85,11 @@ void VM_GC_Operation::notify_gc_end() { // Allocations may fail in several threads at about the same time, // resulting in multiple gc requests. We only want to do one of them. -// In case a GC locker is active and the need for a GC is already signaled, -// we want to skip this GC attempt altogether, without doing a futile -// safepoint operation. bool VM_GC_Operation::skip_operation() const { bool skip = (_gc_count_before != Universe::heap()->total_collections()); if (_full && skip) { skip = (_full_gc_count_before != Universe::heap()->total_full_collections()); } - if (!skip && GCLocker::is_active_and_needs_gc()) { - skip = Universe::heap()->is_maximal_no_gc(); - assert(!(skip && (_gc_cause == GCCause::_gc_locker)), - "GCLocker cannot be active when initiating GC"); - } return skip; } @@ -110,7 +101,7 @@ bool VM_GC_Operation::doit_prologue() { if (!is_init_completed()) { vm_exit_during_initialization( err_msg("GC triggered before VM initialization completed. Try increasing " - "NewSize, current value " SIZE_FORMAT "%s.", + "NewSize, current value %zu%s.", byte_size_in_proper_unit(NewSize), proper_unit_for_byte_size(NewSize))); } @@ -123,6 +114,9 @@ bool VM_GC_Operation::doit_prologue() { Heap_lock->unlock(); _prologue_succeeded = false; } else { + if (UseSerialGC || UseParallelGC) { + GCLocker::block(); + } _prologue_succeeded = true; } return _prologue_succeeded; @@ -130,6 +124,9 @@ bool VM_GC_Operation::doit_prologue() { void VM_GC_Operation::doit_epilogue() { + if (UseSerialGC || UseParallelGC) { + GCLocker::unblock(); + } // GC thread root traversal likely used OopMapCache a lot, which // might have created lots of old entries. Trigger the cleanup now. OopMapCache::try_trigger_cleanup(); @@ -140,8 +137,8 @@ void VM_GC_Operation::doit_epilogue() { } bool VM_GC_HeapInspection::doit_prologue() { - if (_full_gc && UseZGC) { - // ZGC cannot perform a synchronous GC cycle from within the VM thread. + if (_full_gc && (UseZGC || UseShenandoahGC)) { + // ZGC and Shenandoah cannot perform a synchronous GC cycle from within the VM thread. // So VM_GC_HeapInspection::collect() is a noop. To respect the _full_gc // flag a synchronous GC cycle is performed from the caller thread in the // prologue. @@ -259,11 +256,7 @@ void VM_CollectForMetadataAllocation::doit() { return; } - log_debug(gc)("After Metaspace GC failed to allocate size " SIZE_FORMAT, _size); - - if (GCLocker::is_active_and_needs_gc()) { - set_gc_locked(); - } + log_debug(gc)("After Metaspace GC failed to allocate size %zu", _size); } VM_CollectForAllocation::VM_CollectForAllocation(size_t word_size, uint gc_count_before, GCCause::Cause cause) diff --git a/src/hotspot/share/gc/shared/gcVMOperations.hpp b/src/hotspot/share/gc/shared/gcVMOperations.hpp index e9281198fdfa1..5893986a70db7 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.hpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.hpp @@ -108,7 +108,6 @@ class VM_GC_Operation: public VM_GC_Sync_Operation { bool _full; // whether a "full" collection bool _prologue_succeeded; // whether doit_prologue succeeded GCCause::Cause _gc_cause; // the putative cause for this gc op - bool _gc_locked; // will be set if gc was locked virtual bool skip_operation() const; @@ -123,8 +122,6 @@ class VM_GC_Operation: public VM_GC_Sync_Operation { _gc_cause = _cause; - _gc_locked = false; - _full_gc_count_before = full_gc_count_before; // In ParallelScavengeHeap::mem_allocate() collections can be // executed within a loop and _all_soft_refs_clear can be set @@ -148,9 +145,6 @@ class VM_GC_Operation: public VM_GC_Sync_Operation { virtual bool allow_nested_vm_operations() const { return true; } bool prologue_succeeded() const { return _prologue_succeeded; } - void set_gc_locked() { _gc_locked = true; } - bool gc_locked() const { return _gc_locked; } - static void notify_gc_begin(bool full = false); static void notify_gc_end(); }; diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 9086c25ee48fb..ba29daf2fe144 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -155,11 +155,6 @@ "A System.gc() request invokes a concurrent collection; " \ "(effective only when using concurrent collectors)") \ \ - product(uintx, GCLockerRetryAllocationCount, 2, DIAGNOSTIC, \ - "Number of times to retry allocations when " \ - "blocked by the GC locker") \ - range(0, max_uintx) \ - \ product(uint, ParallelGCBufferWastePct, 10, \ "Wasted fraction of parallel allocation buffer") \ range(0, 100) \ diff --git a/src/hotspot/share/gc/shared/genArguments.cpp b/src/hotspot/share/gc/shared/genArguments.cpp index c94ca56722f62..90617b1675fa0 100644 --- a/src/hotspot/share/gc/shared/genArguments.cpp +++ b/src/hotspot/share/gc/shared/genArguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/generation.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/genArguments.hpp" @@ -79,13 +78,13 @@ void GenArguments::initialize_heap_flags_and_sizes() { assert(GenAlignment != 0, "Generation alignment not set up properly"); assert(HeapAlignment >= GenAlignment, - "HeapAlignment: " SIZE_FORMAT " less than GenAlignment: " SIZE_FORMAT, + "HeapAlignment: %zu less than GenAlignment: %zu", HeapAlignment, GenAlignment); assert(GenAlignment % SpaceAlignment == 0, - "GenAlignment: " SIZE_FORMAT " not aligned by SpaceAlignment: " SIZE_FORMAT, + "GenAlignment: %zu not aligned by SpaceAlignment: %zu", GenAlignment, SpaceAlignment); assert(HeapAlignment % GenAlignment == 0, - "HeapAlignment: " SIZE_FORMAT " not aligned by GenAlignment: " SIZE_FORMAT, + "HeapAlignment: %zu not aligned by GenAlignment: %zu", HeapAlignment, GenAlignment); // All generational heaps have a young gen; handle those flags here @@ -128,8 +127,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { // Make sure there is room for an old generation size_t smaller_max_new_size = MaxHeapSize - GenAlignment; if (FLAG_IS_CMDLINE(MaxNewSize)) { - log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire " - "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.", + log_warning(gc, ergo)("MaxNewSize (%zuk) is equal to or greater than the entire " + "heap (%zuk). A new max generation size of %zuk will be used.", MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K); } FLAG_SET_ERGO(MaxNewSize, smaller_max_new_size); @@ -147,8 +146,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { // At this point this should only happen if the user specifies a large NewSize and/or // a small (but not too small) MaxNewSize. if (FLAG_IS_CMDLINE(MaxNewSize)) { - log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " - "A new max generation size of " SIZE_FORMAT "k will be used.", + log_warning(gc, ergo)("NewSize (%zuk) is greater than the MaxNewSize (%zuk). " + "A new max generation size of %zuk will be used.", NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(MaxNewSize, NewSize); @@ -245,7 +244,7 @@ void GenArguments::initialize_size_info() { } } - log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT, + log_trace(gc, heap)("1: Minimum young %zu Initial young %zu Maximum young %zu", MinNewSize, initial_young_size, max_young_size); // At this point the minimum, initial and maximum sizes @@ -287,7 +286,7 @@ void GenArguments::initialize_size_info() { initial_young_size = desired_young_size; } - log_trace(gc, heap)("2: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT, + log_trace(gc, heap)("2: Minimum young %zu Initial young %zu Maximum young %zu", MinNewSize, initial_young_size, max_young_size); } @@ -304,7 +303,7 @@ void GenArguments::initialize_size_info() { OldSize = initial_old_size; } - log_trace(gc, heap)("Minimum old " SIZE_FORMAT " Initial old " SIZE_FORMAT " Maximum old " SIZE_FORMAT, + log_trace(gc, heap)("Minimum old %zu Initial old %zu Maximum old %zu", MinOldSize, OldSize, MaxOldSize); DEBUG_ONLY(assert_size_info();) diff --git a/src/hotspot/share/gc/shared/generationCounters.cpp b/src/hotspot/share/gc/shared/generationCounters.cpp index 05460ea889898..4af7b412aea55 100644 --- a/src/hotspot/share/gc/shared/generationCounters.cpp +++ b/src/hotspot/share/gc/shared/generationCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,15 +22,16 @@ * */ -#include "precompiled.hpp" #include "gc/shared/generationCounters.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "memory/virtualspace.hpp" #include "runtime/perfData.hpp" -void GenerationCounters::initialize(const char* name, int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, - size_t curr_capacity) { +GenerationCounters::GenerationCounters(const char* name, + int ordinal, int spaces, + size_t min_capacity, size_t max_capacity, + size_t curr_capacity) { if (UsePerfData) { EXCEPTION_MARK; ResourceMark rm; @@ -62,29 +63,11 @@ void GenerationCounters::initialize(const char* name, int ordinal, int spaces, } } -GenerationCounters::GenerationCounters(const char* name, - int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, - VirtualSpace* v) - : _virtual_space(v) { - assert(v != nullptr, "don't call this constructor if v == nullptr"); - initialize(name, ordinal, spaces, - min_capacity, max_capacity, v->committed_size()); -} - -GenerationCounters::GenerationCounters(const char* name, - int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, - size_t curr_capacity) - : _virtual_space(nullptr) { - initialize(name, ordinal, spaces, min_capacity, max_capacity, curr_capacity); -} - GenerationCounters::~GenerationCounters() { FREE_C_HEAP_ARRAY(char, _name_space); } -void GenerationCounters::update_all() { - assert(_virtual_space != nullptr, "otherwise, override this method"); - _current_size->set_value(_virtual_space->committed_size()); +void GenerationCounters::update_all(size_t curr_capacity) { + _current_size->set_value(curr_capacity); } + diff --git a/src/hotspot/share/gc/shared/generationCounters.hpp b/src/hotspot/share/gc/shared/generationCounters.hpp index 292ea61d46d26..50672ab5d74f8 100644 --- a/src/hotspot/share/gc/shared/generationCounters.hpp +++ b/src/hotspot/share/gc/shared/generationCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_GENERATIONCOUNTERS_HPP #define SHARE_GC_SHARED_GENERATIONCOUNTERS_HPP -#include "memory/virtualspace.hpp" +#include "memory/allocation.hpp" #include "runtime/perfDataTypes.hpp" // A GenerationCounter is a holder class for performance counters @@ -34,14 +34,7 @@ class GenerationCounters: public CHeapObj { friend class VMStructs; -private: - void initialize(const char* name, int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, - size_t curr_capacity); - - protected: PerfVariable* _current_size; - VirtualSpace* _virtual_space; // Constant PerfData types don't need to retain a reference. // However, it's a good idea to document them here. @@ -52,27 +45,15 @@ class GenerationCounters: public CHeapObj { char* _name_space; - // This constructor is only meant for use with the PSGenerationCounters - // constructor. The need for such an constructor should be eliminated - // when VirtualSpace and PSVirtualSpace are unified. - GenerationCounters() - : _current_size(nullptr), _virtual_space(nullptr), _name_space(nullptr) {} - - // This constructor is used for subclasses that do not have a space - // associated with them (e.g, in G1). + public: GenerationCounters(const char* name, int ordinal, int spaces, size_t min_capacity, size_t max_capacity, size_t curr_capacity); - public: - GenerationCounters(const char* name, int ordinal, int spaces, - size_t min_capacity, size_t max_capacity, VirtualSpace* v); - ~GenerationCounters(); - virtual void update_all(); + void update_all(size_t curr_capacity); const char* name_space() const { return _name_space; } - }; #endif // SHARE_GC_SHARED_GENERATIONCOUNTERS_HPP diff --git a/src/hotspot/share/gc/shared/hSpaceCounters.cpp b/src/hotspot/share/gc/shared/hSpaceCounters.cpp index 5800e05a0a534..de5dd2912a505 100644 --- a/src/hotspot/share/gc/shared/hSpaceCounters.cpp +++ b/src/hotspot/share/gc/shared/hSpaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/hSpaceCounters.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/gc/shared/isGCActiveMark.cpp b/src/hotspot/share/gc/shared/isGCActiveMark.cpp index 70d289794270c..5dd1bd59031fc 100644 --- a/src/hotspot/share/gc/shared/isGCActiveMark.cpp +++ b/src/hotspot/share/gc/shared/isGCActiveMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/isGCActiveMark.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp index cb36962e61e58..1ed3701fdab09 100644 --- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp +++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/serial/cardTableRS.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gcArguments.hpp" @@ -57,8 +56,8 @@ static JVMFlag::Error MinPLABSizeBounds(const char* name, size_t value, bool ver if ((GCConfig::is_gc_selected(CollectedHeap::G1) || GCConfig::is_gc_selected(CollectedHeap::Parallel)) && (value < PLAB::min_size())) { JVMFlag::printError(verbose, - "%s (" SIZE_FORMAT ") must be " - "greater than or equal to ergonomic PLAB minimum size (" SIZE_FORMAT ")\n", + "%s (%zu) must be " + "greater than or equal to ergonomic PLAB minimum size (%zu)\n", name, value, PLAB::min_size()); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -70,8 +69,8 @@ JVMFlag::Error MaxPLABSizeBounds(const char* name, size_t value, bool verbose) { if ((GCConfig::is_gc_selected(CollectedHeap::G1) || GCConfig::is_gc_selected(CollectedHeap::Parallel)) && (value > PLAB::max_size())) { JVMFlag::printError(verbose, - "%s (" SIZE_FORMAT ") must be " - "less than or equal to ergonomic PLAB maximum size (" SIZE_FORMAT ")\n", + "%s (%zu) must be " + "less than or equal to ergonomic PLAB maximum size (%zu)\n", name, value, PLAB::max_size()); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -99,8 +98,8 @@ JVMFlag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose) { JVMFlag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) { if (value > MaxHeapFreeRatio) { JVMFlag::printError(verbose, - "MinHeapFreeRatio (" UINTX_FORMAT ") must be " - "less than or equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n", + "MinHeapFreeRatio (%zu) must be " + "less than or equal to MaxHeapFreeRatio (%zu)\n", value, MaxHeapFreeRatio); return JVMFlag::VIOLATES_CONSTRAINT; } else { @@ -111,8 +110,8 @@ JVMFlag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose) { JVMFlag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose) { if (value < MinHeapFreeRatio) { JVMFlag::printError(verbose, - "MaxHeapFreeRatio (" UINTX_FORMAT ") must be " - "greater than or equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n", + "MaxHeapFreeRatio (%zu) must be " + "greater than or equal to MinHeapFreeRatio (%zu)\n", value, MinHeapFreeRatio); return JVMFlag::VIOLATES_CONSTRAINT; } else { @@ -124,8 +123,8 @@ static JVMFlag::Error CheckMaxHeapSizeAndSoftRefLRUPolicyMSPerMB(size_t maxHeap, if ((softRef > 0) && ((maxHeap / M) > (max_uintx / softRef))) { JVMFlag::printError(verbose, "Desired lifetime of SoftReferences cannot be expressed correctly. " - "MaxHeapSize (" SIZE_FORMAT ") or SoftRefLRUPolicyMSPerMB " - "(" INTX_FORMAT ") is too large\n", + "MaxHeapSize (%zu) or SoftRefLRUPolicyMSPerMB " + "(%zd) is too large\n", maxHeap, softRef); return JVMFlag::VIOLATES_CONSTRAINT; } else { @@ -141,8 +140,8 @@ JVMFlag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose) { // value == 0 is handled by the range constraint. if (value > MarkStackSizeMax) { JVMFlag::printError(verbose, - "MarkStackSize (" SIZE_FORMAT ") must be " - "less than or equal to MarkStackSizeMax (" SIZE_FORMAT ")\n", + "MarkStackSize (%zu) must be " + "less than or equal to MarkStackSizeMax (%zu)\n", value, MarkStackSizeMax); return JVMFlag::VIOLATES_CONSTRAINT; } else { @@ -233,8 +232,8 @@ static JVMFlag::Error MaxSizeForAlignment(const char* name, size_t value, size_t size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1)); if (value > aligned_max) { JVMFlag::printError(verbose, - "%s (" SIZE_FORMAT ") must be " - "less than or equal to aligned maximum value (" SIZE_FORMAT ")\n", + "%s (%zu) must be " + "less than or equal to aligned maximum value (%zu)\n", name, value, aligned_max); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -288,8 +287,8 @@ JVMFlag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose) { // Check for this by ensuring that MaxHeapSize plus the requested min base address still fit within max_uintx. if (UseCompressedOops && FLAG_IS_ERGO(MaxHeapSize) && (value > (max_uintx - MaxHeapSize))) { JVMFlag::printError(verbose, - "HeapBaseMinAddress (" SIZE_FORMAT ") or MaxHeapSize (" SIZE_FORMAT ") is too large. " - "Sum of them must be less than or equal to maximum of size_t (" SIZE_FORMAT ")\n", + "HeapBaseMinAddress (%zu) or MaxHeapSize (%zu) is too large. " + "Sum of them must be less than or equal to maximum of size_t (%zu)\n", value, MaxHeapSize, max_uintx); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -312,15 +311,15 @@ JVMFlag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose) { // At least, alignment reserve area is needed. if (value < ThreadLocalAllocBuffer::alignment_reserve_in_bytes()) { JVMFlag::printError(verbose, - "MinTLABSize (" SIZE_FORMAT ") must be " - "greater than or equal to reserved area in TLAB (" SIZE_FORMAT ")\n", + "MinTLABSize (%zu) must be " + "greater than or equal to reserved area in TLAB (%zu)\n", value, ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); return JVMFlag::VIOLATES_CONSTRAINT; } if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { JVMFlag::printError(verbose, - "MinTLABSize (" SIZE_FORMAT ") must be " - "less than or equal to ergonomic TLAB maximum (" SIZE_FORMAT ")\n", + "MinTLABSize (%zu) must be " + "less than or equal to ergonomic TLAB maximum (%zu)\n", value, ThreadLocalAllocBuffer::max_size() * HeapWordSize); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -332,15 +331,15 @@ JVMFlag::Error TLABSizeConstraintFunc(size_t value, bool verbose) { if (FLAG_IS_CMDLINE(TLABSize)) { if (value < MinTLABSize) { JVMFlag::printError(verbose, - "TLABSize (" SIZE_FORMAT ") must be " - "greater than or equal to MinTLABSize (" SIZE_FORMAT ")\n", + "TLABSize (%zu) must be " + "greater than or equal to MinTLABSize (%zu)\n", value, MinTLABSize); return JVMFlag::VIOLATES_CONSTRAINT; } if (value > (ThreadLocalAllocBuffer::max_size() * HeapWordSize)) { JVMFlag::printError(verbose, - "TLABSize (" SIZE_FORMAT ") must be " - "less than or equal to ergonomic TLAB maximum size (" SIZE_FORMAT ")\n", + "TLABSize (%zu) must be " + "less than or equal to ergonomic TLAB maximum size (%zu)\n", value, (ThreadLocalAllocBuffer::max_size() * HeapWordSize)); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -357,8 +356,8 @@ JVMFlag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose) { // Compare with 'max_uintx' as ThreadLocalAllocBuffer::_refill_waste_limit is 'size_t'. if (refill_waste_limit > (max_uintx - value)) { JVMFlag::printError(verbose, - "TLABWasteIncrement (" UINTX_FORMAT ") must be " - "less than or equal to ergonomic TLAB waste increment maximum size(" SIZE_FORMAT ")\n", + "TLABWasteIncrement (%zu) must be " + "less than or equal to ergonomic TLAB waste increment maximum size(%zu)\n", value, (max_uintx - refill_waste_limit)); return JVMFlag::VIOLATES_CONSTRAINT; } @@ -370,8 +369,8 @@ JVMFlag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) { if (FLAG_IS_CMDLINE(SurvivorRatio) && (value > (MaxHeapSize / SpaceAlignment))) { JVMFlag::printError(verbose, - "SurvivorRatio (" UINTX_FORMAT ") must be " - "less than or equal to ergonomic SurvivorRatio maximum (" SIZE_FORMAT ")\n", + "SurvivorRatio (%zu) must be " + "less than or equal to ergonomic SurvivorRatio maximum (%zu)\n", value, (MaxHeapSize / SpaceAlignment)); return JVMFlag::VIOLATES_CONSTRAINT; @@ -383,8 +382,8 @@ JVMFlag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose) { JVMFlag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) { if (value > MaxMetaspaceSize) { JVMFlag::printError(verbose, - "MetaspaceSize (" SIZE_FORMAT ") must be " - "less than or equal to MaxMetaspaceSize (" SIZE_FORMAT ")\n", + "MetaspaceSize (%zu) must be " + "less than or equal to MaxMetaspaceSize (%zu)\n", value, MaxMetaspaceSize); return JVMFlag::VIOLATES_CONSTRAINT; } else { @@ -395,8 +394,8 @@ JVMFlag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose) { JVMFlag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) { if (value < MetaspaceSize) { JVMFlag::printError(verbose, - "MaxMetaspaceSize (" SIZE_FORMAT ") must be " - "greater than or equal to MetaspaceSize (" SIZE_FORMAT ")\n", + "MaxMetaspaceSize (%zu) must be " + "greater than or equal to MetaspaceSize (%zu)\n", value, MaxMetaspaceSize); return JVMFlag::VIOLATES_CONSTRAINT; } else { diff --git a/src/hotspot/share/gc/shared/locationPrinter.cpp b/src/hotspot/share/gc/shared/locationPrinter.cpp index 62c5ce0df4706..b5efb540d459a 100644 --- a/src/hotspot/share/gc/shared/locationPrinter.cpp +++ b/src/hotspot/share/gc/shared/locationPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/locationPrinter.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/gc/shared/markBitMap.cpp b/src/hotspot/share/gc/shared/markBitMap.cpp index bc90032206c42..b2b1e80246226 100644 --- a/src/hotspot/share/gc/shared/markBitMap.cpp +++ b/src/hotspot/share/gc/shared/markBitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/markBitMap.inline.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/gc/shared/memAllocator.cpp b/src/hotspot/share/gc/shared/memAllocator.cpp index f96ec50e3b0a2..64ca463571890 100644 --- a/src/hotspot/share/gc/shared/memAllocator.cpp +++ b/src/hotspot/share/gc/shared/memAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "classfile/vmClasses.hpp" #include "gc/shared/allocTracer.hpp" @@ -294,13 +293,13 @@ HeapWord* MemAllocator::mem_allocate_inside_tlab_slow(Allocation& allocation) co mem = Universe::heap()->allocate_new_tlab(min_tlab_size, new_tlab_size, &allocation._allocated_tlab_size); if (mem == nullptr) { assert(allocation._allocated_tlab_size == 0, - "Allocation failed, but actual size was updated. min: " SIZE_FORMAT - ", desired: " SIZE_FORMAT ", actual: " SIZE_FORMAT, + "Allocation failed, but actual size was updated. min: %zu" + ", desired: %zu, actual: %zu", min_tlab_size, new_tlab_size, allocation._allocated_tlab_size); return nullptr; } assert(allocation._allocated_tlab_size != 0, "Allocation succeeded but actual size not updated. mem at: " - PTR_FORMAT " min: " SIZE_FORMAT ", desired: " SIZE_FORMAT, + PTR_FORMAT " min: %zu, desired: %zu", p2i(mem), min_tlab_size, new_tlab_size); // ...and clear or zap just allocated TLAB, if needed. diff --git a/src/hotspot/share/gc/shared/objectCountEventSender.cpp b/src/hotspot/share/gc/shared/objectCountEventSender.cpp index ce78b84770869..a28c52e5c901d 100644 --- a/src/hotspot/share/gc/shared/objectCountEventSender.cpp +++ b/src/hotspot/share/gc/shared/objectCountEventSender.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ */ -#include "precompiled.hpp" #include "gc/shared/gcId.hpp" #include "gc/shared/objectCountEventSender.hpp" #include "jfr/jfrEvents.hpp" diff --git a/src/hotspot/share/gc/shared/oopStorage.cpp b/src/hotspot/share/gc/shared/oopStorage.cpp index 2373d6b1d93a8..ae3e9c46197f1 100644 --- a/src/hotspot/share/gc/shared/oopStorage.cpp +++ b/src/hotspot/share/gc/shared/oopStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/oopStorage.inline.hpp" #include "gc/shared/oopStorageParState.inline.hpp" #include "logging/log.hpp" @@ -323,7 +322,7 @@ void OopStorage::Block::atomic_add_allocated(uintx add) { // facto verifies the precondition held; if there were any set bits in // common, then after the add at least one of them will be zero. uintx sum = Atomic::add(&_allocated_bitmask, add); - assert((sum & add) == add, "some already present: " UINTX_FORMAT ":" UINTX_FORMAT, + assert((sum & add) == add, "some already present: %zu:%zu", sum, add); } @@ -579,7 +578,7 @@ bool OopStorage::expand_active_array() { assert_lock_strong(_allocation_mutex); ActiveArray* old_array = _active_array; size_t new_size = 2 * old_array->size(); - log_debug(oopstorage, blocks)("%s: expand active array " SIZE_FORMAT, + log_debug(oopstorage, blocks)("%s: expand active array %zu", name(), new_size); ActiveArray* new_array = ActiveArray::create(new_size, mem_tag(), @@ -1121,8 +1120,8 @@ bool OopStorage::BasicParState::claim_next_segment(IterationData* data) { bool OopStorage::BasicParState::finish_iteration(const IterationData* data) const { log_info(oopstorage, blocks, stats) - ("Parallel iteration on %s: blocks = " SIZE_FORMAT - ", processed = " SIZE_FORMAT " (%2.f%%)", + ("Parallel iteration on %s: blocks = %zu" + ", processed = %zu (%2.f%%)", _storage->name(), _block_count, data->_processed, percent_of(data->_processed, _block_count)); return false; @@ -1171,7 +1170,7 @@ void OopStorage::print_on(outputStream* st) const { double data_size = section_size * section_count; double alloc_percentage = percent_of((double)allocations, blocks * data_size); - st->print("%s: " SIZE_FORMAT " entries in " SIZE_FORMAT " blocks (%.F%%), " SIZE_FORMAT " bytes", + st->print("%s: %zu entries in %zu blocks (%.F%%), %zu bytes", name(), allocations, blocks, alloc_percentage, total_memory_usage()); if (_concurrent_iteration_count > 0) { st->print(", concurrent iteration active"); diff --git a/src/hotspot/share/gc/shared/oopStorageSet.cpp b/src/hotspot/share/gc/shared/oopStorageSet.cpp index e3a9fccbad3dc..8ff9e1664b273 100644 --- a/src/hotspot/share/gc/shared/oopStorageSet.cpp +++ b/src/hotspot/share/gc/shared/oopStorageSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/gc/shared/parallelCleaning.cpp b/src/hotspot/share/gc/shared/parallelCleaning.cpp index 3671500995ea8..1b1eaf4d79ae2 100644 --- a/src/hotspot/share/gc/shared/parallelCleaning.cpp +++ b/src/hotspot/share/gc/shared/parallelCleaning.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/stringTable.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/share/gc/shared/partialArraySplitter.cpp b/src/hotspot/share/gc/shared/partialArraySplitter.cpp new file mode 100644 index 0000000000000..12dd387fbfa5c --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArraySplitter.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "gc/shared/gc_globals.hpp" +#include "gc/shared/partialArraySplitter.hpp" +#include "gc/shared/partialArrayState.hpp" +#include "utilities/macros.hpp" + +PartialArraySplitter::PartialArraySplitter(PartialArrayStateManager* manager, + uint num_workers) + : _allocator(manager), + _stepper(num_workers, ParGCArrayScanChunk) + TASKQUEUE_STATS_ONLY(COMMA _stats()) +{} + +#if TASKQUEUE_STATS +PartialArrayTaskStats* PartialArraySplitter::stats() { + return &_stats; +} +#endif // TASKQUEUE_STATS diff --git a/src/hotspot/share/gc/shared/partialArraySplitter.hpp b/src/hotspot/share/gc/shared/partialArraySplitter.hpp new file mode 100644 index 0000000000000..0dd2072c5908c --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArraySplitter.hpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHARED_PARTIALARRAYSPLITTER_HPP +#define SHARE_GC_SHARED_PARTIALARRAYSPLITTER_HPP + +#include "gc/shared/partialArrayState.hpp" +#include "gc/shared/partialArrayTaskStats.hpp" +#include "gc/shared/partialArrayTaskStepper.hpp" +#include "oops/oop.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" + +class outputStream; + +// Helper class for splitting the processing of a large objArray into multiple +// tasks, to permit multiple threads to work on different pieces of the array +// in parallel. +class PartialArraySplitter { + PartialArrayStateAllocator _allocator; + PartialArrayTaskStepper _stepper; + TASKQUEUE_STATS_ONLY(PartialArrayTaskStats _stats;) + +public: + PartialArraySplitter(PartialArrayStateManager* manager, uint num_workers); + ~PartialArraySplitter() = default; + + NONCOPYABLE(PartialArraySplitter); + + // Setup to process an objArray in chunks. + // + // from_array is the array found by the collector that needs processing. It + // may be null if to_array contains everything needed for processing. + // + // to_array is an unprocessed (possibly partial) copy of from_array, or null + // if a copy of from_array is not required. + // + // length is their length in elements. + // + // If t is a ScannerTask, queue->push(t) must be a valid expression. The + // result of that expression is ignored. + // + // Returns the size of the initial chunk that is to be processed by the + // caller. + // + // Adds PartialArrayState ScannerTasks to the queue if needed to process the + // array in chunks. This permits other workers to steal and process them + // even while the caller is processing the initial chunk. If length doesn't + // exceed the chunk size then the result will be length, indicating the + // caller is to process the entire array. In this case, no tasks will have + // been added to the queue. + template + size_t start(Queue* queue, + objArrayOop from_array, + objArrayOop to_array, + size_t length); + + // Result type for claim(), carrying multiple values. Provides the claimed + // chunk's start and end array indices. + struct Claim { + size_t _start; + size_t _end; + }; + + // Claims a chunk from state, returning the index range for that chunk. The + // caller is expected to process that chunk. Adds more state-based tasks to + // the queue if needed, permitting other workers to steal and process them + // even while the caller is processing this claim. + // + // Releases the state. Callers must not use state after the call to this + // function. The state may have been recycled and reused. + // + // The queue has the same requirements as for start(). + // + // stolen indicates whether the state task was obtained from this queue or + // stolen from some other queue. + template + Claim claim(PartialArrayState* state, Queue* queue, bool stolen); + + TASKQUEUE_STATS_ONLY(PartialArrayTaskStats* stats();) +}; + +#endif // SHARE_GC_SHARED_PARTIALARRAYSPLITTER_HPP diff --git a/src/hotspot/share/gc/shared/partialArraySplitter.inline.hpp b/src/hotspot/share/gc/shared/partialArraySplitter.inline.hpp new file mode 100644 index 0000000000000..abb0cf1310165 --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArraySplitter.inline.hpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHARED_PARTIALARRAYSPLITTER_INLINE_HPP +#define SHARE_GC_SHARED_PARTIALARRAYSPLITTER_INLINE_HPP + +#include "gc/shared/partialArraySplitter.hpp" + +#include "gc/shared/partialArrayTaskStats.hpp" +#include "gc/shared/partialArrayTaskStepper.inline.hpp" +#include "gc/shared/taskqueue.inline.hpp" +#include "oops/oop.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" + +template +size_t PartialArraySplitter::start(Queue* queue, + objArrayOop source, + objArrayOop destination, + size_t length) { + PartialArrayTaskStepper::Step step = _stepper.start(length); + // Push initial partial scan tasks. + if (step._ncreate > 0) { + TASKQUEUE_STATS_ONLY(_stats.inc_split();); + TASKQUEUE_STATS_ONLY(_stats.inc_pushed(step._ncreate);) + PartialArrayState* state = + _allocator.allocate(source, destination, step._index, length, step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + queue->push(ScannerTask(state)); + } + } else { + assert(step._index == length, "invariant"); + } + return step._index; +} + +template +PartialArraySplitter::Claim +PartialArraySplitter::claim(PartialArrayState* state, Queue* queue, bool stolen) { +#if TASKQUEUE_STATS + if (stolen) _stats.inc_stolen(); + _stats.inc_processed(); +#endif // TASKQUEUE_STATS + + // Claim a chunk and get number of additional tasks to enqueue. + PartialArrayTaskStepper::Step step = _stepper.next(state); + // Push additional tasks. + if (step._ncreate > 0) { + TASKQUEUE_STATS_ONLY(_stats.inc_pushed(step._ncreate);) + // Adjust reference count for tasks being added to the queue. + state->add_references(step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + queue->push(ScannerTask(state)); + } + } + // Release state, decrementing refcount, now that we're done with it. + _allocator.release(state); + return Claim{step._index, step._index + _stepper.chunk_size()}; +} + +#endif // SHARE_GC_SHARED_PARTIALARRAYSPLITTER_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/partialArrayState.cpp b/src/hotspot/share/gc/shared/partialArrayState.cpp index 60067c6547b86..f79e012a36d4f 100644 --- a/src/hotspot/share/gc/shared/partialArrayState.cpp +++ b/src/hotspot/share/gc/shared/partialArrayState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/partialArrayState.hpp" #include "memory/allocation.inline.hpp" #include "memory/arena.hpp" diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStats.cpp b/src/hotspot/share/gc/shared/partialArrayTaskStats.cpp new file mode 100644 index 0000000000000..ac8a380ec9ad0 --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArrayTaskStats.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "gc/shared/partialArrayTaskStats.hpp" +#include "logging/log.hpp" +#include "logging/logHandle.hpp" +#include "logging/logStream.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" +#include "utilities/ostream.hpp" + +#if TASKQUEUE_STATS + +PartialArrayTaskStats::PartialArrayTaskStats() + : _split(0), _pushed(0), _stolen(0), _processed(0) +{} + +void PartialArrayTaskStats::accumulate(const PartialArrayTaskStats& stats) { + _split += stats._split; + _pushed += stats._pushed; + _stolen += stats._stolen; + _processed += stats._processed; +} + +void PartialArrayTaskStats::reset() { + *this = PartialArrayTaskStats(); +} + +LogTargetHandle PartialArrayTaskStats::log_target() { + LogTarget(Trace, gc, task, stats) lt; + return LogTargetHandle(lt); +} + +bool PartialArrayTaskStats::is_log_enabled() { + return log_target().is_enabled(); +} + +static const char* const stats_hdr[] = { + " ----partial array---- arrays array", + "thread push steal chunked chunks", + "------ ---------- ---------- ---------- ----------" +}; + +void PartialArrayTaskStats::print_header(outputStream* s, const char* title) { + s->print_cr("%s:", title); + for (uint i = 0; i < ARRAY_SIZE(stats_hdr); ++i) { + s->print_cr("%s", stats_hdr[i]); + } +} + +void PartialArrayTaskStats::print_values_impl(outputStream* s) const { + // 10 digits for each counter, matching the segments in stats_hdr. + s->print_cr(" %10zu %10zu %10zu %10zu", + _pushed, _stolen, _split, _processed); +} + +void PartialArrayTaskStats::print_values(outputStream* s, uint id) const { + // 6 digits for thread number, matching the segement in stats_hdr. + s->print("%6u", id); + print_values_impl(s); +} + +void PartialArrayTaskStats::print_total(outputStream* s) const { + // 6 characters for "total" id, matching the segment in stats_hdr. + s->print("%6s", "total"); + print_values_impl(s); +} + +#endif // TASKQUEUE_STATS diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStats.hpp b/src/hotspot/share/gc/shared/partialArrayTaskStats.hpp new file mode 100644 index 0000000000000..e02a9f460b09a --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArrayTaskStats.hpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHARED_PARTIALARRAYTASKSTATS_HPP +#define SHARE_GC_SHARED_PARTIALARRAYTASKSTATS_HPP + +#include "logging/logHandle.hpp" +#include "logging/logStream.hpp" +#include "utilities/globalDefinitions.hpp" + +#if TASKQUEUE_STATS + +class outputStream; + +// Repository for collecting and reporting statistics about partial array task +// processing. Not thread-safe; each processing thread should have its own +// stats object. +class PartialArrayTaskStats { + size_t _split; + size_t _pushed; + size_t _stolen; + size_t _processed; + + static LogTargetHandle log_target(); + static bool is_log_enabled(); + static void print_header(outputStream* s, const char* title); + void print_values(outputStream* s, uint id) const; + void print_total(outputStream* s) const; + void print_values_impl(outputStream* s) const; + + void accumulate(const PartialArrayTaskStats& stats); + +public: + // All counters are initially zero. + PartialArrayTaskStats(); + + // Trivially copied and destroyed. + + // Number of arrays split into partial array tasks. + size_t split() const { return _split; } + + // Number of partial array tasks pushed onto a queue. + size_t pushed() const { return _pushed; } + + // Number of partial array tasks stolen from some other queue. + size_t stolen() const { return _stolen; } + + // Number of partial array tasks processed. + size_t processed() const { return _processed; } + + void inc_split() { _split += 1; } + void inc_pushed(size_t n) { _pushed += n; } + void inc_stolen() { _stolen += 1; } + void inc_processed() { _processed += 1; } + + // Set all counters to zero. + void reset(); + + // Log a table of statistics, if logging is enabled (gc+task+stats=trace). + // + // num_stats: The number of stats objects to include in the table, one row + // for each. + // + // access: A function taking a uint value < num_stats, and returning a + // pointer to the corresponding stats object. + // + // title: A string title for the table. + template + static void log_set(uint num_stats, StatsAccess access, const char* title) { + if (is_log_enabled()) { + LogStream ls(log_target()); + PartialArrayTaskStats total; + print_header(&ls, title); + for (uint i = 0; i < num_stats; ++i) { + const PartialArrayTaskStats* stats = access(i); + stats->print_values(&ls, i); + total.accumulate(*stats); + } + total.print_total(&ls); + } + } +}; + +#endif // TASKQUEUE_STATS + +#endif // SHARE_GC_SHARED_PARTIALARRAYTASKSTATS_HPP diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp b/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp index 6faa162ac7bed..d91ba347d6c8c 100644 --- a/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp +++ b/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/partialArrayTaskStepper.hpp" #include "oops/arrayOop.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/gc/shared/plab.cpp b/src/hotspot/share/gc/shared/plab.cpp index ac2025e97a152..7b637709f11b9 100644 --- a/src/hotspot/share/gc/shared/plab.cpp +++ b/src/hotspot/share/gc/shared/plab.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/plab.inline.hpp" @@ -65,7 +64,7 @@ PLAB::PLAB(size_t desired_plab_sz_) : _end(nullptr), _hard_end(nullptr), _allocated(0), _wasted(0), _undo_wasted(0) { assert(min_size() > CollectedHeap::lab_alignment_reserve(), - "Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " " + "Minimum PLAB size %zu must be larger than alignment reserve %zu " "to be able to contain objects", min_size(), CollectedHeap::lab_alignment_reserve()); } diff --git a/src/hotspot/share/gc/shared/preservedMarks.cpp b/src/hotspot/share/gc/shared/preservedMarks.cpp index bc241fb5daf45..0576757524347 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.cpp +++ b/src/hotspot/share/gc/shared/preservedMarks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/fullGCForwarding.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/workerThread.hpp" @@ -67,10 +66,10 @@ void PreservedMarks::restore_and_increment(volatile size_t* const total_size_add #ifndef PRODUCT void PreservedMarks::assert_empty() { - assert(_stack.is_empty(), "stack expected to be empty, size = " SIZE_FORMAT, + assert(_stack.is_empty(), "stack expected to be empty, size = %zu", _stack.size()); assert(_stack.cache_size() == 0, - "stack expected to have no cached segments, cache size = " SIZE_FORMAT, + "stack expected to have no cached segments, cache size = %zu", _stack.cache_size()); } #endif // ndef PRODUCT diff --git a/src/hotspot/share/gc/shared/pretouchTask.cpp b/src/hotspot/share/gc/shared/pretouchTask.cpp index 427d14fd4e7e3..e06c561b6a8ad 100644 --- a/src/hotspot/share/gc/shared/pretouchTask.cpp +++ b/src/hotspot/share/gc/shared/pretouchTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/pretouchTask.hpp" #include "logging/log.hpp" @@ -43,7 +42,7 @@ PretouchTask::PretouchTask(const char* task_name, _chunk_size(chunk_size) { assert(chunk_size >= page_size, - "Chunk size " SIZE_FORMAT " is smaller than page size " SIZE_FORMAT, + "Chunk size %zu is smaller than page size %zu", chunk_size, page_size); } @@ -79,12 +78,12 @@ void PretouchTask::pretouch(const char* task_name, char* start_address, char* en size_t num_chunks = ((total_bytes - 1) / chunk_size) + 1; uint num_workers = (uint)MIN2(num_chunks, (size_t)pretouch_workers->max_workers()); - log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", + log_debug(gc, heap)("Running %s with %u workers for %zu work units pre-touching %zuB.", task.name(), num_workers, num_chunks, total_bytes); pretouch_workers->run_task(&task, num_workers); } else { - log_debug(gc, heap)("Running %s pre-touching " SIZE_FORMAT "B.", + log_debug(gc, heap)("Running %s pre-touching %zuB.", task.name(), total_bytes); task.work(0); } diff --git a/src/hotspot/share/gc/shared/ptrQueue.cpp b/src/hotspot/share/gc/shared/ptrQueue.cpp index 9723db8391298..fd7011700f472 100644 --- a/src/hotspot/share/gc/shared/ptrQueue.cpp +++ b/src/hotspot/share/gc/shared/ptrQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/bufferNode.hpp" #include "gc/shared/ptrQueue.hpp" diff --git a/src/hotspot/share/gc/shared/referencePolicy.cpp b/src/hotspot/share/gc/shared/referencePolicy.cpp index 22ef4eabbe6a1..d1867291479c2 100644 --- a/src/hotspot/share/gc/shared/referencePolicy.cpp +++ b/src/hotspot/share/gc/shared/referencePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp index ff7530f2d32f3..0ee4ac134c2c4 100644 --- a/src/hotspot/share/gc/shared/referenceProcessor.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "compiler/compilerDefinitions.inline.hpp" #include "gc/shared/collectedHeap.hpp" @@ -175,7 +174,7 @@ size_t ReferenceProcessor::total_count(DiscoveredList lists[]) const { #ifdef ASSERT void ReferenceProcessor::verify_total_count_zero(DiscoveredList lists[], const char* type) { size_t count = total_count(lists); - assert(count == 0, "%ss must be empty but has " SIZE_FORMAT " elements", type, count); + assert(count == 0, "%ss must be empty but has %zu elements", type, count); } #endif @@ -365,7 +364,7 @@ size_t ReferenceProcessor::process_discovered_list_work(DiscoveredList& refs_ refs_list.clear(); } - log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT + log_develop_trace(gc, ref)(" Dropped %zu active Refs out of %zu" " Refs in discovered list " PTR_FORMAT, iter.removed(), iter.processed(), p2i(&refs_list)); return iter.removed(); @@ -559,10 +558,10 @@ void ReferenceProcessor::log_reflist(const char* prefix, DiscoveredList list[], LogStream ls(lt); ls.print("%s", prefix); for (uint i = 0; i < num_active_queues; i++) { - ls.print(SIZE_FORMAT " ", list[i].length()); + ls.print("%zu ", list[i].length()); total += list[i].length(); } - ls.print_cr("(" SIZE_FORMAT ")", total); + ls.print_cr("(%zu)", total); } #ifndef PRODUCT @@ -574,7 +573,7 @@ void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint num log_reflist("", ref_lists, num_active_queues); #ifdef ASSERT for (uint i = num_active_queues; i < _max_num_queues; i++) { - assert(ref_lists[i].length() == 0, SIZE_FORMAT " unexpected References in %u", + assert(ref_lists[i].length() == 0, "%zu unexpected References in %u", ref_lists[i].length(), i); } #endif @@ -1095,7 +1094,7 @@ bool ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_lis } if (iter.processed() > 0) { - log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT " Refs in discovered list " PTR_FORMAT, + log_develop_trace(gc, ref)(" Dropped %zu Refs out of %zu Refs in discovered list " PTR_FORMAT, iter.removed(), iter.processed(), p2i(&refs_list)); } return false; diff --git a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp index 2ad55b95424f9..f4b30866d776e 100644 --- a/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessorPhaseTimes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/referenceProcessor.inline.hpp" diff --git a/src/hotspot/share/gc/shared/satbMarkQueue.cpp b/src/hotspot/share/gc/shared/satbMarkQueue.cpp index a0efcc8e66ae8..6e33d27897ccc 100644 --- a/src/hotspot/share/gc/shared/satbMarkQueue.cpp +++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/satbMarkQueue.hpp" #include "gc/shared/collectedHeap.hpp" #include "logging/log.hpp" @@ -54,8 +53,8 @@ static void print_satb_buffer(const char* name, void** buf, size_t index, size_t capacity) { - tty->print_cr(" SATB BUFFER [%s] buf: " PTR_FORMAT " index: " SIZE_FORMAT - " capacity: " SIZE_FORMAT, + tty->print_cr(" SATB BUFFER [%s] buf: " PTR_FORMAT " index: %zu" + " capacity: %zu", name, p2i(buf), index, capacity); } diff --git a/src/hotspot/share/gc/shared/scavengableNMethods.cpp b/src/hotspot/share/gc/shared/scavengableNMethods.cpp index c619ddb764aeb..0dff5526911af 100644 --- a/src/hotspot/share/gc/shared/scavengableNMethods.cpp +++ b/src/hotspot/share/gc/shared/scavengableNMethods.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nmethod.hpp" #include "gc/shared/scavengableNMethods.hpp" diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index 0eb9d2520b739..6a9b2b90f44db 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/share/gc/shared/spaceDecorator.cpp b/src/hotspot/share/gc/shared/spaceDecorator.cpp index cb554f48e5911..b0668c56e2dc8 100644 --- a/src/hotspot/share/gc/shared/spaceDecorator.cpp +++ b/src/hotspot/share/gc/shared/spaceDecorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/spaceDecorator.hpp" #include "utilities/copy.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp index 7c37d642836d3..9ad8decec7e08 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.cpp index 3fa3df12891ec..50155a669515d 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupConfig.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "gc/shared/stringdedup/stringDedupConfig.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp index ab85c293941df..f4f69c8269ff6 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" #include "gc/shared/oopStorage.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupStat.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupStat.cpp index cffda333b1335..28e5e9adf2002 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupStat.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupStat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/stringdedup/stringDedupStat.hpp" #include "logging/log.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupStorageUse.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupStorageUse.cpp index ee5fc6db5d57e..175c63421e191 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupStorageUse.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupStorageUse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/stringdedup/stringDedupStorageUse.hpp" #include "runtime/atomic.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp index ac8fc0759cafc..5c6628cba5cdd 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupThread.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupThread.cpp index ef983883e166a..49eb49ca4012a 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupThread.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "gc/shared/stringdedup/stringDedupProcessor.hpp" #include "gc/shared/stringdedup/stringDedupThread.hpp" diff --git a/src/hotspot/share/gc/shared/strongRootsScope.cpp b/src/hotspot/share/gc/shared/strongRootsScope.cpp index 0839c72ca5d13..1316df68e5f9d 100644 --- a/src/hotspot/share/gc/shared/strongRootsScope.cpp +++ b/src/hotspot/share/gc/shared/strongRootsScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/stringTable.hpp" #include "code/nmethod.hpp" #include "gc/shared/strongRootsScope.hpp" diff --git a/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp b/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp index a0d83ac298da6..35a446de532e9 100644 --- a/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp +++ b/src/hotspot/share/gc/shared/suspendibleThreadSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/gc/shared/taskTerminator.cpp b/src/hotspot/share/gc/shared/taskTerminator.cpp index cd225699f37fe..1353c3f8c8a06 100644 --- a/src/hotspot/share/gc/shared/taskTerminator.cpp +++ b/src/hotspot/share/gc/shared/taskTerminator.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved. - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/taskTerminator.hpp" #include "gc/shared/taskqueue.hpp" diff --git a/src/hotspot/share/gc/shared/taskqueue.cpp b/src/hotspot/share/gc/shared/taskqueue.cpp index 61e2899b6738d..a244ba454150b 100644 --- a/src/hotspot/share/gc/shared/taskqueue.cpp +++ b/src/hotspot/share/gc/shared/taskqueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/taskqueue.hpp" #include "oops/oop.inline.hpp" #include "logging/log.hpp" @@ -75,10 +74,9 @@ void TaskQueueStats::print_header(unsigned int line, outputStream* const stream, void TaskQueueStats::print(outputStream* stream, unsigned int width) const { - #define FMT SIZE_FORMAT_W(*) - stream->print(FMT, width, _stats[0]); + stream->print("%*zu", width, _stats[0]); for (unsigned int i = 1; i < last_stat_id; ++i) { - stream->print(" " FMT, width, _stats[i]); + stream->print(" %*zu", width, _stats[i]); } #undef FMT } diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index efbc1882fbed8..42d32f3dc96b9 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -34,20 +34,6 @@ #include "utilities/ostream.hpp" #include "utilities/stack.hpp" -// Simple TaskQueue stats that are collected by default in debug builds. - -#if !defined(TASKQUEUE_STATS) && defined(ASSERT) -#define TASKQUEUE_STATS 1 -#elif !defined(TASKQUEUE_STATS) -#define TASKQUEUE_STATS 0 -#endif - -#if TASKQUEUE_STATS -#define TASKQUEUE_STATS_ONLY(code) code -#else -#define TASKQUEUE_STATS_ONLY(code) -#endif // TASKQUEUE_STATS - #if TASKQUEUE_STATS class TaskQueueStats { public: @@ -575,8 +561,10 @@ class ObjArrayTask class PartialArrayState; -// Discriminated union over oop*, narrowOop*, and PartialArrayState. +// Discriminated union over oop/oop*, narrowOop*, and PartialArrayState. // Uses a low tag in the associated pointer to identify the category. +// Oop/oop* are overloaded using the same tag because they can not appear at the +// same time. // Used as a task queue element type. class ScannerTask { void* _p; @@ -609,6 +597,8 @@ class ScannerTask { public: ScannerTask() : _p(nullptr) {} + explicit ScannerTask(oop p) : _p(encode(p, OopTag)) {} + explicit ScannerTask(oop* p) : _p(encode(p, OopTag)) {} explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {} @@ -636,6 +626,10 @@ class ScannerTask { return static_cast(decode(OopTag)); } + oop to_oop() const { + return cast_to_oop(decode(OopTag)); + } + narrowOop* to_narrow_oop_ptr() const { return static_cast(decode(NarrowOopTag)); } diff --git a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp index e967a65555a15..aa0079d814db9 100644 --- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp +++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilerDefinitions.inline.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/threadLocalAllocBuffer.inline.hpp" @@ -164,7 +163,7 @@ void ThreadLocalAllocBuffer::resize() { size_t aligned_new_size = align_object_size(new_size); log_trace(gc, tlab)("TLAB new size: thread: " PTR_FORMAT " [id: %2d]" - " refills %d alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT, + " refills %d alloc: %8.6f desired_size: %zu -> %zu", p2i(thread()), thread()->osthread()->thread_id(), _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size); @@ -263,7 +262,7 @@ void ThreadLocalAllocBuffer::startup_initialization() { guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread"); Thread::current()->tlab().initialize(); - log_develop_trace(gc, tlab)("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT, + log_develop_trace(gc, tlab)("TLAB min: %zu initial: %zu max: %zu", min_size(), Thread::current()->tlab().initial_desired_size(), max_size()); } @@ -299,8 +298,8 @@ void ThreadLocalAllocBuffer::print_stats(const char* tag) { double waste_percent = percent_of(waste, _allocated_size); size_t tlab_used = Universe::heap()->tlab_used(thrd); log.trace("TLAB: %s thread: " PTR_FORMAT " [id: %2d]" - " desired_size: " SIZE_FORMAT "KB" - " slow allocs: %d refill waste: " SIZE_FORMAT "B" + " desired_size: %zuKB" + " slow allocs: %d refill waste: %zuB" " alloc:%8.5f %8.0fKB refills: %d waste %4.1f%% gc: %dB" " slow: %dB", tag, p2i(thrd), thrd->osthread()->thread_id(), @@ -451,8 +450,8 @@ void ThreadLocalAllocStats::publish() { const double waste_percent = percent_of(waste, _total_allocations); log_debug(gc, tlab)("TLAB totals: thrds: %d refills: %d max: %d" " slow allocs: %d max %d waste: %4.1f%%" - " gc: " SIZE_FORMAT "B max: " SIZE_FORMAT "B" - " slow: " SIZE_FORMAT "B max: " SIZE_FORMAT "B", + " gc: %zuB max: %zuB" + " slow: %zuB max: %zuB", _allocating_threads, _total_refills, _max_refills, _total_slow_allocations, _max_slow_allocations, waste_percent, _total_gc_waste * HeapWordSize, _max_gc_waste * HeapWordSize, diff --git a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp index 6910d9c186061..32a830a2bb138 100644 --- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp +++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,11 +61,11 @@ inline size_t ThreadLocalAllocBuffer::compute_size(size_t obj_size) { // Make sure there's enough room for object and filler int[]. if (new_tlab_size < compute_min_size(obj_size)) { // If there isn't enough room for the allocation, return failure. - log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ") returns failure", + log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(%zu) returns failure", obj_size); return 0; } - log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ") returns " SIZE_FORMAT, + log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(%zu) returns %zu", obj_size, new_tlab_size); return new_tlab_size; } @@ -86,9 +86,9 @@ void ThreadLocalAllocBuffer::record_slow_allocation(size_t obj_size) { _slow_allocations++; log_develop_trace(gc, tlab)("TLAB: %s thread: " PTR_FORMAT " [id: %2d]" - " obj: " SIZE_FORMAT - " free: " SIZE_FORMAT - " waste: " SIZE_FORMAT, + " obj: %zu" + " free: %zu" + " waste: %zu", "slow", p2i(thread()), thread()->osthread()->thread_id(), obj_size, free(), refill_waste_limit()); } diff --git a/src/hotspot/share/gc/shared/weakProcessor.cpp b/src/hotspot/share/gc/shared/weakProcessor.cpp index 8adf3fab7d5c1..d7de8b5d8a88a 100644 --- a/src/hotspot/share/gc/shared/weakProcessor.cpp +++ b/src/hotspot/share/gc/shared/weakProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/stringTable.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/oopStorage.inline.hpp" diff --git a/src/hotspot/share/gc/shared/weakProcessorTimes.cpp b/src/hotspot/share/gc/shared/weakProcessorTimes.cpp index 64fc961162394..88fb309882446 100644 --- a/src/hotspot/share/gc/shared/weakProcessorTimes.cpp +++ b/src/hotspot/share/gc/shared/weakProcessorTimes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/weakProcessor.hpp" #include "gc/shared/weakProcessorTimes.hpp" diff --git a/src/hotspot/share/gc/shared/workerDataArray.cpp b/src/hotspot/share/gc/shared/workerDataArray.cpp index a16e3219255df..7b3e9e50cb464 100644 --- a/src/hotspot/share/gc/shared/workerDataArray.cpp +++ b/src/hotspot/share/gc/shared/workerDataArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/workerDataArray.inline.hpp" #include "utilities/ostream.hpp" @@ -49,9 +48,9 @@ void WorkerDataArray::WDAPrinter::summary(outputStream* out, double min, template <> void WorkerDataArray::WDAPrinter::summary(outputStream* out, size_t min, double avg, size_t max, size_t diff, size_t sum, bool print_sum) { - out->print(" Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT, min, avg, max, diff); + out->print(" Min: %zu, Avg: %4.1lf, Max: %zu, Diff: %zu", min, avg, max, diff); if (print_sum) { - out->print(", Sum: " SIZE_FORMAT, sum); + out->print(", Sum: %zu", sum); } } @@ -75,7 +74,7 @@ void WorkerDataArray::WDAPrinter::details(const WorkerDataArray* for (uint i = 0; i < phase->_length; ++i) { size_t value = phase->get(i); if (value != phase->uninitialized()) { - out->print(" " SIZE_FORMAT, phase->get(i)); + out->print(" %zu", phase->get(i)); } else { out->print(" -"); } diff --git a/src/hotspot/share/gc/shared/workerPolicy.cpp b/src/hotspot/share/gc/shared/workerPolicy.cpp index 4ab178dd6a70f..7ab019d13d57f 100644 --- a/src/hotspot/share/gc/shared/workerPolicy.cpp +++ b/src/hotspot/share/gc/shared/workerPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/workerPolicy.hpp" #include "logging/log.hpp" @@ -130,9 +129,9 @@ uint WorkerPolicy::calc_default_active_workers(uintx total_workers, assert(new_active_workers <= total_workers, "Total workers not observed"); log_trace(gc, task)("WorkerPolicy::calc_default_active_workers() : " - "active_workers(): " UINTX_FORMAT " new_active_workers: " UINTX_FORMAT " " - "prev_active_workers: " UINTX_FORMAT "\n" - " active_workers_by_JT: " UINTX_FORMAT " active_workers_by_heap_size: " UINTX_FORMAT, + "active_workers(): %zu new_active_workers: %zu " + "prev_active_workers: %zu\n" + " active_workers_by_JT: %zu active_workers_by_heap_size: %zu", active_workers, new_active_workers, prev_active_workers, active_workers_by_JT, active_workers_by_heap_size); assert(new_active_workers > 0, "Always need at least 1"); diff --git a/src/hotspot/share/gc/shared/workerThread.cpp b/src/hotspot/share/gc/shared/workerThread.cpp index 4dde8e3938797..ffeb3a4194b7b 100644 --- a/src/hotspot/share/gc/shared/workerThread.cpp +++ b/src/hotspot/share/gc/shared/workerThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/workerThread.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/shared/workerUtils.cpp b/src/hotspot/share/gc/shared/workerUtils.cpp index 41662092966df..40b78d3f6223b 100644 --- a/src/hotspot/share/gc/shared/workerUtils.cpp +++ b/src/hotspot/share/gc/shared/workerUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/workerUtils.hpp" #include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp index ade0504b9730c..d27b98adc9f47 100644 --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "c1/c1_IR.hpp" #include "gc/shared/satbMarkQueue.hpp" #include "gc/shenandoah/mode/shenandoahMode.hpp" diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index 9adc74aae3ae1..514cc8fd83913 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index fd127df3cdec3..860bcb38038ff 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "gc/shenandoah/c2/shenandoahSupport.hpp" diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp index 94c544a7ea36b..7a624d4d4a482 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" @@ -96,8 +96,8 @@ void ShenandoahAdaptiveHeuristics::choose_collection_set_from_regiondata(Shenand size_t free_target = (capacity / 100 * ShenandoahMinFreeThreshold) + max_cset; size_t min_garbage = (free_target > actual_free ? (free_target - actual_free) : 0); - log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "%s, Actual Free: " - SIZE_FORMAT "%s, Max Evacuation: " SIZE_FORMAT "%s, Min Garbage: " SIZE_FORMAT "%s", + log_info(gc, ergo)("Adaptive CSet Selection. Target Free: %zu%s, Actual Free: " + "%zu%s, Max Evacuation: %zu%s, Min Garbage: %zu%s", byte_size_in_proper_unit(free_target), proper_unit_for_byte_size(free_target), byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset), @@ -142,7 +142,7 @@ void ShenandoahAdaptiveHeuristics::record_success_concurrent() { if (available_sd > 0) { double available_avg = _available.avg(); z_score = (double(available) - available_avg) / available_sd; - log_debug(gc, ergo)("Available: " SIZE_FORMAT " %sB, z-score=%.3f. Average available: %.1f %sB +/- %.1f %sB.", + log_debug(gc, ergo)("Available: %zu %sB, z-score=%.3f. Average available: %.1f %sB +/- %.1f %sB.", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), z_score, byte_size_in_proper_unit(available_avg), proper_unit_for_byte_size(available_avg), @@ -237,8 +237,12 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { size_t available = _space_info->soft_available(); size_t allocated = _space_info->bytes_allocated_since_gc_start(); - log_debug(gc)("should_start_gc? available: " SIZE_FORMAT ", soft_max_capacity: " SIZE_FORMAT - ", allocated: " SIZE_FORMAT, available, capacity, allocated); + log_debug(gc)("should_start_gc? available: %zu, soft_max_capacity: %zu" + ", allocated: %zu", available, capacity, allocated); + + if (_start_gc_is_pending) { + return true; + } // Track allocation rate even if we decide to start a cycle for other reasons. double rate = _allocation_rate.sample(allocated); @@ -246,9 +250,10 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { size_t min_threshold = min_free_threshold(); if (available < min_threshold) { - log_trigger("Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); + accept_trigger_with_type(OTHER); return true; } @@ -257,10 +262,11 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { if (_gc_times_learned < max_learn) { size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold; if (available < init_threshold) { - log_trigger("Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "%s) is below initial threshold (" SIZE_FORMAT "%s)", + log_trigger("Learning %zu of %zu. Free (%zu%s) is below initial threshold (%zu%s)", _gc_times_learned + 1, max_learn, byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(init_threshold), proper_unit_for_byte_size(init_threshold)); + accept_trigger_with_type(OTHER); return true; } } @@ -282,32 +288,37 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { avg_cycle_time * 1000, byte_size_in_proper_unit(avg_alloc_rate), proper_unit_for_byte_size(avg_alloc_rate)); if (avg_cycle_time * avg_alloc_rate > allocation_headroom) { log_trigger("Average GC time (%.2f ms) is above the time for average allocation rate (%.0f %sB/s)" - " to deplete free headroom (" SIZE_FORMAT "%s) (margin of error = %.2f)", + " to deplete free headroom (%zu%s) (margin of error = %.2f)", avg_cycle_time * 1000, byte_size_in_proper_unit(avg_alloc_rate), proper_unit_for_byte_size(avg_alloc_rate), byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom), _margin_of_error_sd); - log_info(gc, ergo)("Free headroom: " SIZE_FORMAT "%s (free) - " SIZE_FORMAT "%s (spike) - " SIZE_FORMAT "%s (penalties) = " SIZE_FORMAT "%s", + log_info(gc, ergo)("Free headroom: %zu%s (free) - %zu%s (spike) - %zu%s (penalties) = %zu%s", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(spike_headroom), proper_unit_for_byte_size(spike_headroom), byte_size_in_proper_unit(penalties), proper_unit_for_byte_size(penalties), byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom)); - _last_trigger = RATE; + accept_trigger_with_type(RATE); return true; } bool is_spiking = _allocation_rate.is_spiking(rate, _spike_threshold_sd); if (is_spiking && avg_cycle_time > allocation_headroom / rate) { - log_trigger("Average GC time (%.2f ms) is above the time for instantaneous allocation rate (%.0f %sB/s) to deplete free headroom (" SIZE_FORMAT "%s) (spike threshold = %.2f)", + log_trigger("Average GC time (%.2f ms) is above the time for instantaneous allocation rate (%.0f %sB/s) to deplete free headroom (%zu%s) (spike threshold = %.2f)", avg_cycle_time * 1000, byte_size_in_proper_unit(rate), proper_unit_for_byte_size(rate), byte_size_in_proper_unit(allocation_headroom), proper_unit_for_byte_size(allocation_headroom), _spike_threshold_sd); - _last_trigger = SPIKE; + accept_trigger_with_type(SPIKE); return true; } - return ShenandoahHeuristics::should_start_gc(); + if (ShenandoahHeuristics::should_start_gc()) { + _start_gc_is_pending = true; + return true; + } else { + return false; + } } void ShenandoahAdaptiveHeuristics::adjust_last_trigger_parameters(double amount) { diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp index 5ee10c6bebf49..a47024f3a4b87 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp @@ -145,6 +145,11 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics { // this threshold, or we might consider this when dynamically resizing generations // in the generational case. Controlled by global flag ShenandoahMinFreeThreshold. size_t min_free_threshold(); + + inline void accept_trigger_with_type(Trigger trigger_type) { + _last_trigger = trigger_type; + ShenandoahHeuristics::accept_trigger(); + } }; #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp index cdae9bb1285a2..a833e39631c48 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" @@ -53,6 +52,7 @@ void ShenandoahAggressiveHeuristics::choose_collection_set_from_regiondata(Shena bool ShenandoahAggressiveHeuristics::should_start_gc() { log_trigger("Start next cycle immediately"); + accept_trigger(); return true; } diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp index 2c7594e10dc5d..9d211314474a7 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" @@ -58,17 +58,19 @@ bool ShenandoahCompactHeuristics::should_start_gc() { size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold; if (available < min_threshold) { - log_trigger("Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); + accept_trigger(); return true; } size_t bytes_allocated = _space_info->bytes_allocated_since_gc_start(); if (bytes_allocated > threshold_bytes_allocated) { - log_trigger("Allocated since last cycle (" SIZE_FORMAT "%s) is larger than allocation threshold (" SIZE_FORMAT "%s)", + log_trigger("Allocated since last cycle (%zu%s) is larger than allocation threshold (%zu%s)", byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated), byte_size_in_proper_unit(threshold_bytes_allocated), proper_unit_for_byte_size(threshold_bytes_allocated)); + accept_trigger(); return true; } @@ -81,7 +83,7 @@ void ShenandoahCompactHeuristics::choose_collection_set_from_regiondata(Shenando // Do not select too large CSet that would overflow the available free space size_t max_cset = actual_free * 3 / 4; - log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s", + log_info(gc, ergo)("CSet Selection. Actual Free: %zu%s, Max CSet: %zu%s", byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset)); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp index 5b6d82d97a4c9..0568d9b4fff95 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/heuristics/shenandoahGenerationalHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -134,7 +133,7 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio bool reg_live = region->has_live(); bool bm_live = heap->complete_marking_context()->is_marked(cast_to_oop(region->bottom())); assert(reg_live == bm_live, - "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, + "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: %zu", BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words()); #endif if (!region->has_live()) { @@ -158,8 +157,8 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio } heap->old_generation()->set_expected_humongous_region_promotions(humongous_regions_promoted); heap->old_generation()->set_expected_regular_region_promotions(regular_regions_promoted_in_place); - log_info(gc, ergo)("Planning to promote in place " SIZE_FORMAT " humongous regions and " SIZE_FORMAT - " regular regions, spanning a total of " SIZE_FORMAT " used bytes", + log_info(gc, ergo)("Planning to promote in place %zu humongous regions and %zu" + " regular regions, spanning a total of %zu used bytes", humongous_regions_promoted, regular_regions_promoted_in_place, humongous_regions_promoted * ShenandoahHeapRegion::region_size_bytes() + regular_regions_promoted_usage); @@ -168,7 +167,7 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio // given the amount of immediately reclaimable garbage. If we do, figure out the collection set. assert (immediate_garbage <= total_garbage, - "Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "%s vs " SIZE_FORMAT "%s", + "Cannot have more immediate garbage than total garbage: %zu%s vs %zu%s", byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage), byte_size_in_proper_unit(total_garbage), proper_unit_for_byte_size(total_garbage)); @@ -193,9 +192,9 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio size_t collectable_garbage = collection_set->garbage() + immediate_garbage; size_t collectable_garbage_percent = (total_garbage == 0) ? 0 : (collectable_garbage * 100 / total_garbage); - log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " - "Immediate: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " SIZE_FORMAT " regions, " - "CSet: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " SIZE_FORMAT " regions", + log_info(gc, ergo)("Collectable Garbage: %zu%s (%zu%%), " + "Immediate: %zu%s (%zu%%), %zu regions, " + "CSet: %zu%s (%zu%%), %zu regions", byte_size_in_proper_unit(collectable_garbage), proper_unit_for_byte_size(collectable_garbage), @@ -216,10 +215,10 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio size_t promote_evac_bytes = collection_set->get_young_bytes_to_be_promoted(); size_t old_evac_bytes = collection_set->get_old_bytes_reserved_for_evacuation(); size_t total_evac_bytes = young_evac_bytes + promote_evac_bytes + old_evac_bytes; - log_info(gc, ergo)("Evacuation Targets: YOUNG: " SIZE_FORMAT "%s, " - "PROMOTE: " SIZE_FORMAT "%s, " - "OLD: " SIZE_FORMAT "%s, " - "TOTAL: " SIZE_FORMAT "%s", + log_info(gc, ergo)("Evacuation Targets: YOUNG: %zu%s, " + "PROMOTE: %zu%s, " + "OLD: %zu%s, " + "TOTAL: %zu%s", byte_size_in_proper_unit(young_evac_bytes), proper_unit_for_byte_size(young_evac_bytes), byte_size_in_proper_unit(promote_evac_bytes), proper_unit_for_byte_size(promote_evac_bytes), byte_size_in_proper_unit(old_evac_bytes), proper_unit_for_byte_size(old_evac_bytes), @@ -238,7 +237,7 @@ void ShenandoahGenerationalHeuristics::choose_collection_set(ShenandoahCollectio evacInfo.set_regular_promoted_free(regular_regions_promoted_free); evacInfo.set_regions_immediate(immediate_regions); evacInfo.set_immediate_size(immediate_garbage); - evacInfo.set_regions_freed(free_regions); + evacInfo.set_free_regions(free_regions); ShenandoahTracer().report_evacuation_info(&evacInfo); } @@ -282,8 +281,8 @@ void ShenandoahGenerationalHeuristics::log_cset_composition(ShenandoahCollection size_t collected_young = cset->get_young_bytes_reserved_for_evacuation(); log_info(gc, ergo)( - "Chosen CSet evacuates young: " SIZE_FORMAT "%s (of which at least: " SIZE_FORMAT "%s are to be promoted), " - "old: " SIZE_FORMAT "%s", + "Chosen CSet evacuates young: %zu%s (of which at least: %zu%s are to be promoted), " + "old: %zu%s", byte_size_in_proper_unit(collected_young), proper_unit_for_byte_size(collected_young), byte_size_in_proper_unit(collected_promoted), proper_unit_for_byte_size(collected_promoted), byte_size_in_proper_unit(collected_old), proper_unit_for_byte_size(collected_old)); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp index 4c1e6b7bdff1e..919f6c88afa9e 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahGlobalHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/heuristics/shenandoahGlobalHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahGlobalGeneration.hpp" @@ -92,8 +91,8 @@ void ShenandoahGlobalHeuristics::choose_global_collection_set(ShenandoahCollecti size_t free_target = (capacity * ShenandoahMinFreeThreshold) / 100 + max_young_cset; size_t min_garbage = (free_target > actual_free) ? (free_target - actual_free) : 0; - log_info(gc, ergo)("Adaptive CSet Selection for GLOBAL. Max Young Evacuation: " SIZE_FORMAT - "%s, Max Old Evacuation: " SIZE_FORMAT "%s, Actual Free: " SIZE_FORMAT "%s.", + log_info(gc, ergo)("Adaptive CSet Selection for GLOBAL. Max Young Evacuation: %zu" + "%s, Max Old Evacuation: %zu%s, Actual Free: %zu%s.", byte_size_in_proper_unit(max_young_cset), proper_unit_for_byte_size(max_young_cset), byte_size_in_proper_unit(max_old_cset), proper_unit_for_byte_size(max_old_cset), byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free)); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index c2ad809f43a2f..f5bc74b2b1bfe 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" @@ -46,6 +46,9 @@ int ShenandoahHeuristics::compare_by_garbage(RegionData a, RegionData b) { } ShenandoahHeuristics::ShenandoahHeuristics(ShenandoahSpaceInfo* space_info) : + _start_gc_is_pending(false), + _declined_trigger_count(0), + _most_recent_declined_trigger_count(0), _space_info(space_info), _region_data(nullptr), _guaranteed_gc_interval(0), @@ -121,7 +124,7 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec bool reg_live = region->has_live(); bool bm_live = ctx->is_marked(cast_to_oop(region->bottom())); assert(reg_live == bm_live, - "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, + "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: %zu", BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words()); #endif if (!region->has_live()) { @@ -142,7 +145,7 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec // given the amount of immediately reclaimable garbage. If we do, figure out the collection set. assert (immediate_garbage <= total_garbage, - "Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "%s vs " SIZE_FORMAT "%s", + "Cannot have more immediate garbage than total garbage: %zu%s vs %zu%s", byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage), byte_size_in_proper_unit(total_garbage), proper_unit_for_byte_size(total_garbage)); @@ -156,9 +159,9 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec size_t collectable_garbage = collection_set->garbage() + immediate_garbage; size_t collectable_garbage_percent = (total_garbage == 0) ? 0 : (collectable_garbage * 100 / total_garbage); - log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " - "Immediate: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " SIZE_FORMAT " regions, " - "CSet: " SIZE_FORMAT "%s (" SIZE_FORMAT "%%), " SIZE_FORMAT " regions", + log_info(gc, ergo)("Collectable Garbage: %zu%s (%zu%%), " + "Immediate: %zu%s (%zu%%), %zu regions, " + "CSet: %zu%s (%zu%%), %zu regions", byte_size_in_proper_unit(collectable_garbage), proper_unit_for_byte_size(collectable_garbage), @@ -184,22 +187,27 @@ void ShenandoahHeuristics::record_cycle_end() { } bool ShenandoahHeuristics::should_start_gc() { + if (_start_gc_is_pending) { + return true; + } // Perform GC to cleanup metaspace if (has_metaspace_oom()) { // Some of vmTestbase/metaspace tests depend on following line to count GC cycles log_trigger("%s", GCCause::to_string(GCCause::_metadata_GC_threshold)); + accept_trigger(); return true; } if (_guaranteed_gc_interval > 0) { double last_time_ms = (os::elapsedTime() - _last_cycle_end) * 1000; if (last_time_ms > _guaranteed_gc_interval) { - log_trigger("Time since last GC (%.0f ms) is larger than guaranteed interval (" UINTX_FORMAT " ms)", + log_trigger("Time since last GC (%.0f ms) is larger than guaranteed interval (%zu ms)", last_time_ms, _guaranteed_gc_interval); + accept_trigger(); return true; } } - + decline_trigger(); return false; } @@ -209,7 +217,13 @@ bool ShenandoahHeuristics::should_degenerate_cycle() { void ShenandoahHeuristics::adjust_penalty(intx step) { assert(0 <= _gc_time_penalties && _gc_time_penalties <= 100, - "In range before adjustment: " INTX_FORMAT, _gc_time_penalties); + "In range before adjustment: %zd", _gc_time_penalties); + + if ((_most_recent_declined_trigger_count <= Penalty_Free_Declinations) && (step > 0)) { + // Don't penalize if heuristics are not responsible for a negative outcome. Allow Penalty_Free_Declinations following + // previous GC for self calibration without penalty. + step = 0; + } intx new_val = _gc_time_penalties + step; if (new_val < 0) { @@ -221,7 +235,7 @@ void ShenandoahHeuristics::adjust_penalty(intx step) { _gc_time_penalties = new_val; assert(0 <= _gc_time_penalties && _gc_time_penalties <= 100, - "In range after adjustment: " INTX_FORMAT, _gc_time_penalties); + "In range after adjustment: %zd", _gc_time_penalties); } void ShenandoahHeuristics::log_trigger(const char* fmt, ...) { diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index 8bd5c7775c42e..d036a62a32cf9 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -69,6 +69,9 @@ class ShenandoahHeuristics : public CHeapObj { static const intx Degenerated_Penalty = 10; // how much to penalize average GC duration history on Degenerated GC static const intx Full_Penalty = 20; // how much to penalize average GC duration history on Full GC + // How many times can I decline a trigger opportunity without being penalized for excessive idle span before trigger? + static const size_t Penalty_Free_Declinations = 16; + #ifdef ASSERT enum UnionTag { is_uninitialized, is_garbage, is_live_data @@ -78,6 +81,18 @@ class ShenandoahHeuristics : public CHeapObj { protected: static const uint Moving_Average_Samples = 10; // Number of samples to store in moving averages + bool _start_gc_is_pending; // True denotes that GC has been triggered, so no need to trigger again. + size_t _declined_trigger_count; // This counts how many times since previous GC finished that this + // heuristic has answered false to should_start_gc(). + size_t _most_recent_declined_trigger_count; + ; // This represents the value of _declined_trigger_count as captured at the + // moment the most recent GC effort was triggered. In case the most recent + // concurrent GC effort degenerates, the value of this variable allows us to + // differentiate between degeneration because heuristic was overly optimistic + // in delaying the trigger vs. degeneration for other reasons (such as the + // most recent GC triggered "immediately" after previous GC finished, but the + // free headroom has already been depleted). + class RegionData { private: ShenandoahHeapRegion* _region; @@ -167,6 +182,16 @@ class ShenandoahHeuristics : public CHeapObj { void adjust_penalty(intx step); + inline void accept_trigger() { + _most_recent_declined_trigger_count = _declined_trigger_count; + _declined_trigger_count = 0; + _start_gc_is_pending = true; + } + + inline void decline_trigger() { + _declined_trigger_count++; + } + public: ShenandoahHeuristics(ShenandoahSpaceInfo* space_info); virtual ~ShenandoahHeuristics(); @@ -185,6 +210,10 @@ class ShenandoahHeuristics : public CHeapObj { virtual bool should_start_gc(); + inline void cancel_trigger_request() { + _start_gc_is_pending = false; + } + virtual bool should_degenerate_cycle(); virtual void record_success_concurrent(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp index abb2b7b266ad7..0393a2bb3664a 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -122,7 +121,7 @@ bool ShenandoahOldHeuristics::prime_collection_set(ShenandoahCollectionSet* coll } size_t remaining_old_evacuation_budget = old_evacuation_budget; - log_debug(gc)("Choose old regions for mixed collection: old evacuation budget: " SIZE_FORMAT "%s, candidates: %u", + log_debug(gc)("Choose old regions for mixed collection: old evacuation budget: %zu%s, candidates: %u", byte_size_in_proper_unit(old_evacuation_budget), proper_unit_for_byte_size(old_evacuation_budget), unprocessed_old_collection_candidates()); @@ -362,7 +361,7 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { immediate_regions++; immediate_garbage += garbage; size_t region_count = heap->trash_humongous_region_at(region); - log_debug(gc)("Trashed " SIZE_FORMAT " regions for humongous object.", region_count); + log_debug(gc)("Trashed %zu regions for humongous object.", region_count); } } else if (region->is_trash()) { // Count humongous objects made into trash here. @@ -443,7 +442,7 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { while ((defrag_count < bound_on_additional_regions) && (total_uncollected_old_regions < 7 * span_of_uncollected_regions / 8)) { ShenandoahHeapRegion* r = candidates[_last_old_collection_candidate].get_region(); - assert(r->is_regular() || r->is_regular_pinned(), "Region " SIZE_FORMAT " has wrong state for collection: %s", + assert(r->is_regular() || r->is_regular_pinned(), "Region %zu has wrong state for collection: %s", r->index(), ShenandoahHeapRegion::region_state_to_string(r->state())); const size_t region_garbage = r->garbage(); const size_t region_free = r->free(); @@ -466,12 +465,12 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { const size_t mixed_evac_live = old_candidates * region_size_bytes - (candidates_garbage + unfragmented); set_unprocessed_old_collection_candidates_live_memory(mixed_evac_live); - log_info(gc, ergo)("Old-Gen Collectable Garbage: " PROPERFMT " consolidated with free: " PROPERFMT ", over " SIZE_FORMAT " regions", + log_info(gc, ergo)("Old-Gen Collectable Garbage: " PROPERFMT " consolidated with free: " PROPERFMT ", over %zu regions", PROPERFMTARGS(collectable_garbage), PROPERFMTARGS(unfragmented), old_candidates); - log_info(gc, ergo)("Old-Gen Immediate Garbage: " PROPERFMT " over " SIZE_FORMAT " regions", + log_info(gc, ergo)("Old-Gen Immediate Garbage: " PROPERFMT " over %zu regions", PROPERFMTARGS(immediate_garbage), immediate_regions); - log_info(gc, ergo)("Old regions selected for defragmentation: " SIZE_FORMAT, defrag_count); - log_info(gc, ergo)("Old regions not selected: " SIZE_FORMAT, total_uncollected_old_regions); + log_info(gc, ergo)("Old regions selected for defragmentation: %zu", defrag_count); + log_info(gc, ergo)("Old regions not selected: %zu", total_uncollected_old_regions); if (unprocessed_old_collection_candidates() > 0) { _old_generation->transition_to(ShenandoahOldGeneration::EVACUATING); @@ -608,7 +607,7 @@ void ShenandoahOldHeuristics::set_trigger_if_old_is_overgrown() { size_t trigger_threshold = _old_gen->usage_trigger_threshold(); // Detects unsigned arithmetic underflow assert(old_used <= _heap->capacity(), - "Old used (" SIZE_FORMAT ", " SIZE_FORMAT") must not be more than heap capacity (" SIZE_FORMAT ")", + "Old used (%zu, %zu) must not be more than heap capacity (%zu)", _old_gen->used(), _old_gen->get_humongous_waste(), _heap->capacity()); if (old_used > trigger_threshold) { _growth_trigger = true; @@ -635,7 +634,7 @@ bool ShenandoahOldHeuristics::should_start_gc() { const size_t old_gen_capacity = _old_generation->max_capacity(); const size_t heap_capacity = heap->capacity(); const double percent = percent_of(old_gen_capacity, heap_capacity); - log_trigger("Expansion failure, current size: " SIZE_FORMAT "%s which is %.1f%% of total heap size", + log_trigger("Expansion failure, current size: %zu%s which is %.1f%% of total heap size", byte_size_in_proper_unit(old_gen_capacity), proper_unit_for_byte_size(old_gen_capacity), percent); return true; } @@ -655,8 +654,8 @@ bool ShenandoahOldHeuristics::should_start_gc() { const size_t fragmented_free = used_regions_size - used; log_trigger("Old has become fragmented: " - SIZE_FORMAT "%s available bytes spread between range spanned from " - SIZE_FORMAT " to " SIZE_FORMAT " (" SIZE_FORMAT "), density: %.1f%%", + "%zu%s available bytes spread between range spanned from " + "%zu to %zu (%zu), density: %.1f%%", byte_size_in_proper_unit(fragmented_free), proper_unit_for_byte_size(fragmented_free), first_old_region, last_old_region, span_of_old_regions, density * 100); return true; @@ -673,8 +672,8 @@ bool ShenandoahOldHeuristics::should_start_gc() { if ((current_usage < ignore_threshold) && ((consecutive_young_cycles = heap->shenandoah_policy()->consecutive_young_gc_count()) < ShenandoahDoNotIgnoreGrowthAfterYoungCycles)) { - log_debug(gc)("Ignoring Trigger: Old has overgrown: usage (" SIZE_FORMAT "%s) is below threshold (" - SIZE_FORMAT "%s) after " SIZE_FORMAT " consecutive completed young GCs", + log_debug(gc)("Ignoring Trigger: Old has overgrown: usage (%zu%s) is below threshold (" + "%zu%s) after %zu consecutive completed young GCs", byte_size_in_proper_unit(current_usage), proper_unit_for_byte_size(current_usage), byte_size_in_proper_unit(ignore_threshold), proper_unit_for_byte_size(ignore_threshold), consecutive_young_cycles); @@ -683,7 +682,7 @@ bool ShenandoahOldHeuristics::should_start_gc() { const size_t live_at_previous_old = _old_generation->get_live_bytes_after_last_mark(); const double percent_growth = percent_of(current_usage - live_at_previous_old, live_at_previous_old); log_trigger("Old has overgrown, live at end of previous OLD marking: " - SIZE_FORMAT "%s, current usage: " SIZE_FORMAT "%s, percent growth: %.1f%%", + "%zu%s, current usage: %zu%s, percent growth: %.1f%%", byte_size_in_proper_unit(live_at_previous_old), proper_unit_for_byte_size(live_at_previous_old), byte_size_in_proper_unit(current_usage), proper_unit_for_byte_size(current_usage), percent_growth); return true; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp index 7c65482d8c4f8..b5e9cc433ea6e 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" @@ -36,6 +36,7 @@ ShenandoahPassiveHeuristics::ShenandoahPassiveHeuristics(ShenandoahSpaceInfo* sp bool ShenandoahPassiveHeuristics::should_start_gc() { // Never do concurrent GCs. + decline_trigger(); return false; } @@ -60,7 +61,7 @@ void ShenandoahPassiveHeuristics::choose_collection_set_from_regiondata(Shenando size_t available = MAX2(max_capacity / 100 * ShenandoahEvacReserve, actual_free); size_t max_cset = (size_t)(available / ShenandoahEvacWaste); - log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "%s, Max CSet: " SIZE_FORMAT "%s", + log_info(gc, ergo)("CSet Selection. Actual Free: %zu%s, Max CSet: %zu%s", byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free), byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset)); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp index db179d0a80a81..e6f60dc1c836e 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" @@ -52,9 +52,10 @@ bool ShenandoahStaticHeuristics::should_start_gc() { size_t threshold_available = capacity / 100 * ShenandoahMinFreeThreshold; if (available < threshold_available) { - log_trigger("Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)", + log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(threshold_available), proper_unit_for_byte_size(threshold_available)); + accept_trigger(); return true; } return ShenandoahHeuristics::should_start_gc(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp index ced406611b1e0..9f8c6225d23d8 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahYoungHeuristics.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahYoungHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -82,7 +81,7 @@ void ShenandoahYoungHeuristics::choose_young_collection_set(ShenandoahCollection log_info(gc, ergo)( - "Adaptive CSet Selection for YOUNG. Max Evacuation: " SIZE_FORMAT "%s, Actual Free: " SIZE_FORMAT "%s.", + "Adaptive CSet Selection for YOUNG. Max Evacuation: %zu%s, Actual Free: %zu%s.", byte_size_in_proper_unit(max_cset), proper_unit_for_byte_size(max_cset), byte_size_in_proper_unit(actual_free), proper_unit_for_byte_size(actual_free)); @@ -120,6 +119,8 @@ bool ShenandoahYoungHeuristics::should_start_gc() { if (old_generation->is_preparing_for_mark() || old_generation->is_concurrent_mark_in_progress()) { size_t old_time_elapsed = size_t(old_heuristics->elapsed_cycle_time() * 1000); if (old_time_elapsed < ShenandoahMinimumOldTimeMs) { + // Do not decline_trigger() when waiting for minimum quantum of Old-gen marking. It is not at our discretion + // to trigger at this time. return false; } } @@ -141,6 +142,7 @@ bool ShenandoahYoungHeuristics::should_start_gc() { // Detect unsigned arithmetic underflow assert(promo_potential < heap->capacity(), "Sanity"); log_trigger("Expedite promotion of " PROPERFMT, PROPERFMTARGS(promo_potential)); + accept_trigger(); return true; } @@ -150,10 +152,12 @@ bool ShenandoahYoungHeuristics::should_start_gc() { // If concurrent weak root processing is in progress, it means the old cycle has chosen mixed collection // candidates, but has not completed. There is no point in trying to start the young cycle before the old // cycle completes. - log_trigger("Expedite mixed evacuation of " SIZE_FORMAT " regions", mixed_candidates); + log_trigger("Expedite mixed evacuation of %zu regions", mixed_candidates); + accept_trigger(); return true; } + // Don't decline_trigger() here That was done in ShenandoahAdaptiveHeuristics::should_start_gc() return false; } @@ -221,4 +225,3 @@ size_t ShenandoahYoungHeuristics::bytes_of_allocation_runway_before_gc_trigger(s size_t evac_min_threshold = (anticipated_available > threshold)? anticipated_available - threshold: 0; return MIN3(evac_slack_spiking, evac_slack_avg, evac_min_threshold); } - diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahGenerationalMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahGenerationalMode.cpp index 3a34a9aa6a88a..6c8858341555d 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahGenerationalMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahGenerationalMode.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahYoungHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahGenerationalMode.hpp" diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.cpp index 126062ab9931a..5ef21719ed474 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahMode.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" @@ -51,4 +50,3 @@ ShenandoahHeuristics* ShenandoahMode::initialize_heuristics(ShenandoahSpaceInfo* ShouldNotReachHere(); return nullptr; } - diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp index 5c0ec2f884f03..893321db1dc2f 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp" #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp index f5023c7cae963..7ac2d7b818f79 100644 --- a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp +++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahSATBMode.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp index 7c574a9d0dd7e..94c98b78f1bc0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/mode/shenandoahGenerationalMode.hpp" #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -32,8 +31,8 @@ ShenandoahAgeCensus::ShenandoahAgeCensus() { assert(ShenandoahHeap::heap()->mode()->is_generational(), "Only in generational mode"); if (ShenandoahGenerationalMinTenuringAge > ShenandoahGenerationalMaxTenuringAge) { vm_exit_during_initialization( - err_msg("ShenandoahGenerationalMinTenuringAge=" SIZE_FORMAT - " should be no more than ShenandoahGenerationalMaxTenuringAge=" SIZE_FORMAT, + err_msg("ShenandoahGenerationalMinTenuringAge=%zu" + " should be no more than ShenandoahGenerationalMaxTenuringAge=%zu", ShenandoahGenerationalMinTenuringAge, ShenandoahGenerationalMaxTenuringAge)); } @@ -247,7 +246,7 @@ void ShenandoahAgeCensus::update_tenuring_threshold() { _tenuring_threshold[_epoch] = tt; } print(); - log_trace(gc, age)("New tenuring threshold " UINTX_FORMAT " (min " UINTX_FORMAT ", max " UINTX_FORMAT")", + log_trace(gc, age)("New tenuring threshold %zu (min %zu, max %zu)", (uintx) _tenuring_threshold[_epoch], ShenandoahGenerationalMinTenuringAge, ShenandoahGenerationalMaxTenuringAge); } @@ -326,7 +325,7 @@ double ShenandoahAgeCensus::mortality_rate(size_t prev_pop, size_t cur_pop) { // or increased. if (cur_pop > prev_pop) { log_trace(gc, age) - (" (dark matter) Cohort population " SIZE_FORMAT_W(10) " to " SIZE_FORMAT_W(10), + (" (dark matter) Cohort population %10zu to %10zu", prev_pop*oopSize, cur_pop*oopSize); } return 0.0; @@ -355,7 +354,7 @@ void ShenandoahAgeCensus::print() { // Suppress printing when everything is zero if (prev_pop + cur_pop > 0) { log_info(gc, age) - (" - age %3u: prev " SIZE_FORMAT_W(10) " bytes, curr " SIZE_FORMAT_W(10) " bytes, mortality %.2f ", + (" - age %3u: prev %10zu bytes, curr %10zu bytes, mortality %.2f ", i, prev_pop*oopSize, cur_pop*oopSize, mr); } total += cur_pop; @@ -374,8 +373,8 @@ void ShenandoahNoiseStats::print(size_t total) { float f_aged = (float)aged/(float)total; float f_clamped = (float)clamped/(float)total; float f_young = (float)young/(float)total; - log_info(gc, age)("Skipped: " SIZE_FORMAT_W(10) " (%.2f), R-Aged: " SIZE_FORMAT_W(10) " (%.2f), " - "Clamped: " SIZE_FORMAT_W(10) " (%.2f), R-Young: " SIZE_FORMAT_W(10) " (%.2f)", + log_info(gc, age)("Skipped: %10zu (%.2f), R-Aged: %10zu (%.2f), " + "Clamped: %10zu (%.2f), R-Young: %10zu (%.2f)", skipped*oopSize, f_skipped, aged*oopSize, f_aged, clamped*oopSize, f_clamped, young*oopSize, f_young); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp index fa3f9019af425..cd1949b19ad51 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2022, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/fullGCForwarding.hpp" #include "gc/shared/gcArguments.hpp" #include "gc/shared/tlab_globals.hpp" @@ -60,7 +60,7 @@ void ShenandoahArguments::initialize() { if (UseLargePages) { size_t large_page_size = os::large_page_size(); if ((align_up(MaxHeapSize, large_page_size) / large_page_size) < ShenandoahHeapRegion::MIN_NUM_REGIONS) { - warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit", + warning("Large pages size (%zuK) is too large to afford page-sized regions, disabling uncommit", os::large_page_size() / K); FLAG_SET_DEFAULT(ShenandoahUncommit, false); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp index 437646becce6a..ffafcc5840d78 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index 62067bccb1ed7..37470067ed9b8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "gc/shenandoah/shenandoahBarrierSetClone.inline.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" @@ -114,8 +113,10 @@ void ShenandoahBarrierSet::on_thread_attach(Thread *thread) { assert(queue.buffer() == nullptr, "SATB queue should not have a buffer"); assert(queue.index() == 0, "SATB queue index should be zero"); queue.set_active(_satb_mark_queue_set.is_active()); + + ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state()); + if (thread->is_Java_thread()) { - ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state()); ShenandoahThreadLocalData::initialize_gclab(thread); BarrierSetNMethod* bs_nm = barrier_set_nmethod(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index f3ce9418d35de..5d00688f67119 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -67,8 +67,7 @@ inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, T* load oop fwd = resolve_forwarded_not_null_mutator(obj); if (obj == fwd) { - assert(_heap->is_evacuation_in_progress(), - "evac should be in progress"); + assert(_heap->is_evacuation_in_progress(), "evac should be in progress"); Thread* const t = Thread::current(); ShenandoahEvacOOMScope scope(t); fwd = _heap->evacuate_object(obj, t); @@ -86,8 +85,8 @@ inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj) { if (!ShenandoahLoadRefBarrier) { return obj; } - if (_heap->has_forwarded_objects() && - _heap->in_collection_set(obj)) { // Subsumes null-check + if (_heap->has_forwarded_objects() && _heap->in_collection_set(obj)) { + // Subsumes null-check assert(obj != nullptr, "cset check must have subsumed null-check"); oop fwd = resolve_forwarded_not_null(obj); if (obj == fwd && _heap->is_evacuation_in_progress()) { @@ -381,7 +380,7 @@ void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) { // this barrier will be called with ENQUEUE=true and HAS_FWD=false, even though the young generation // may have forwarded objects. In this case, the `arraycopy_work` is first called with HAS_FWD=true and // ENQUEUE=false. - assert(HAS_FWD == _heap->has_forwarded_objects() || (_heap->gc_state() & ShenandoahHeap::OLD_MARKING) != 0, + assert(HAS_FWD == _heap->has_forwarded_objects() || _heap->is_concurrent_old_mark_in_progress(), "Forwarded object status is sane"); // This function cannot be called to handle marking and evacuation at the same time (they operate on // different sides of the copy). @@ -418,10 +417,10 @@ void ShenandoahBarrierSet::arraycopy_barrier(T* src, T* dst, size_t count) { return; } - int gc_state = _heap->gc_state(); + char gc_state = ShenandoahThreadLocalData::gc_state(Thread::current()); if ((gc_state & ShenandoahHeap::EVACUATION) != 0) { arraycopy_evacuation(src, count); - } else if ((gc_state & ShenandoahHeap::UPDATEREFS) != 0) { + } else if ((gc_state & ShenandoahHeap::UPDATE_REFS) != 0) { arraycopy_update(src, count); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp index 3b7bf9864deb0..8b83cc6b32cf9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp @@ -95,8 +95,7 @@ void ShenandoahBarrierSet::clone_barrier(oop obj) { assert(ShenandoahCloneBarrier, "only get here with clone barriers enabled"); shenandoah_assert_correct(nullptr, obj); - int gc_state = _heap->gc_state(); - if ((gc_state & ShenandoahHeap::EVACUATION) != 0) { + if (_heap->is_evacuation_in_progress()) { clone_evacuation(obj); } else { clone_update(obj); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp index 7b30e1ecbac70..c6e6108fda81c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSetNMethod.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetStackChunk.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetStackChunk.cpp index 658b1da090233..224d9e1870a80 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetStackChunk.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetStackChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc/shenandoah/shenandoahBarrierSetStackChunk.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.cpp index fb0de2bc74106..af18a8219b1a3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2021, Red Hat, Inc. All rights reserved. - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/shenandoah/shenandoahBreakpoint.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCardStats.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCardStats.cpp index ef2d6e134b2e2..fc59af99817e1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCardStats.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCardStats.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCardStats.hpp" #include "logging/log.hpp" @@ -31,9 +31,9 @@ #ifndef PRODUCT void ShenandoahCardStats::log() const { if (ShenandoahEnableCardStats) { - log_info(gc,remset)("Card stats: dirty " SIZE_FORMAT " (max run: " SIZE_FORMAT ")," - " clean " SIZE_FORMAT " (max run: " SIZE_FORMAT ")," - " dirty scans/objs " SIZE_FORMAT, + log_info(gc,remset)("Card stats: dirty %zu (max run: %zu)," + " clean %zu (max run: %zu)," + " dirty scans/objs %zu", _dirty_card_cnt, _max_dirty_run, _clean_card_cnt, _max_clean_run, _dirty_scan_obj_cnt); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCardTable.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCardTable.cpp index 6ecb93717dfc2..b3284051ee712 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCardTable.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCardTable.cpp @@ -22,12 +22,13 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCardTable.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" -#include "runtime/init.hpp" +#include "memory/memoryReserver.hpp" +#include "memory/reservedSpace.hpp" #include "nmt/memTracker.hpp" +#include "runtime/init.hpp" void ShenandoahCardTable::initialize() { size_t num_cards = cards_required(_whole_heap.word_size()); @@ -41,9 +42,9 @@ void ShenandoahCardTable::initialize() { HeapWord* high_bound = _whole_heap.end(); // ReservedSpace constructor would assert rs_align >= os::vm_page_size(). - const size_t rs_align = _page_size == os::vm_page_size() ? 0 : MAX2(_page_size, granularity); + const size_t rs_align = MAX2(_page_size, granularity); - ReservedSpace write_space(_byte_map_size, rs_align, _page_size); + ReservedSpace write_space = MemoryReserver::reserve(_byte_map_size, rs_align, _page_size); initialize(write_space); // The assembler store_check code will do an unsigned shift of the oop, @@ -58,7 +59,7 @@ void ShenandoahCardTable::initialize() { _write_byte_map = _byte_map; _write_byte_map_base = _byte_map_base; - ReservedSpace read_space(_byte_map_size, rs_align, _page_size); + ReservedSpace read_space = MemoryReserver::reserve(_byte_map_size, rs_align, _page_size); initialize(read_space); _read_byte_map = (CardValue*) read_space.base(); @@ -78,13 +79,14 @@ void ShenandoahCardTable::initialize() { } void ShenandoahCardTable::initialize(const ReservedSpace& card_table) { + if (!card_table.is_reserved()) { + vm_exit_during_initialization("Could not reserve enough space for the card marking array"); + } + MemTracker::record_virtual_memory_tag((address)card_table.base(), mtGC); os::trace_page_sizes("Card Table", _byte_map_size, _byte_map_size, card_table.base(), card_table.size(), _page_size); - if (!card_table.is_reserved()) { - vm_exit_during_initialization("Could not reserve enough space for the card marking array"); - } os::commit_memory_or_exit(card_table.base(), _byte_map_size, card_table.alignment(), false, "Cannot commit memory for card table"); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 657cd681f4f64..49d2df0cc936c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/nmethod.hpp" #include "gc/shared/classUnloadingContext.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp index 124ab1958eb2e..c27b790fbf7dd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" @@ -32,8 +31,8 @@ #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" -#include "runtime/atomic.hpp" #include "nmt/memTracker.hpp" +#include "runtime/atomic.hpp" #include "utilities/copy.hpp" ShenandoahCollectionSet::ShenandoahCollectionSet(ShenandoahHeap* heap, ReservedSpace space, char* heap_base) : @@ -186,7 +185,7 @@ ShenandoahHeapRegion* ShenandoahCollectionSet::next() { void ShenandoahCollectionSet::print_on(outputStream* out) const { out->print_cr("Collection Set: Regions: " - SIZE_FORMAT ", Garbage: " SIZE_FORMAT "%s, Live: " SIZE_FORMAT "%s, Used: " SIZE_FORMAT "%s", count(), + "%zu, Garbage: %zu%s, Live: %zu%s, Used: %zu%s", count(), byte_size_in_proper_unit(garbage()), proper_unit_for_byte_size(garbage()), byte_size_in_proper_unit(live()), proper_unit_for_byte_size(live()), byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp index ae1971f30d668..4f9f6fc20522f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp @@ -26,11 +26,12 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCOLLECTIONSET_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHCOLLECTIONSET_HPP -#include "memory/allocation.hpp" -#include "memory/virtualspace.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" +#include "memory/allocation.hpp" +#include "memory/reservedSpace.hpp" +#include "memory/virtualspace.hpp" class ShenandoahCollectionSet : public CHeapObj { friend class ShenandoahHeap; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp index 42500ae877892..782db285c2ad0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahGC.hpp" @@ -179,7 +179,7 @@ void ShenandoahCollectorPolicy::print_gc_stats(outputStream* out) const { out->cr(); size_t completed_gcs = _success_full_gcs + _success_degenerated_gcs + _success_concurrent_gcs + _success_old_gcs; - out->print_cr(SIZE_FORMAT_W(5) " Completed GCs", completed_gcs); + out->print_cr("%5zu Completed GCs", completed_gcs); size_t explicit_requests = 0; size_t implicit_requests = 0; @@ -193,48 +193,48 @@ void ShenandoahCollectorPolicy::print_gc_stats(outputStream* out) const { implicit_requests += cause_count; } const char* desc = GCCause::to_string(cause); - out->print_cr(" " SIZE_FORMAT_W(5) " caused by %s (%.2f%%)", cause_count, desc, percent_of(cause_count, completed_gcs)); + out->print_cr(" %5zu caused by %s (%.2f%%)", cause_count, desc, percent_of(cause_count, completed_gcs)); } } out->cr(); - out->print_cr(SIZE_FORMAT_W(5) " Successful Concurrent GCs (%.2f%%)", _success_concurrent_gcs, percent_of(_success_concurrent_gcs, completed_gcs)); + out->print_cr("%5zu Successful Concurrent GCs (%.2f%%)", _success_concurrent_gcs, percent_of(_success_concurrent_gcs, completed_gcs)); if (ExplicitGCInvokesConcurrent) { - out->print_cr(" " SIZE_FORMAT_W(5) " invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_concurrent_gcs)); } if (ShenandoahImplicitGCInvokesConcurrent) { - out->print_cr(" " SIZE_FORMAT_W(5) " invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_concurrent_gcs)); } - out->print_cr(" " SIZE_FORMAT_W(5) " abbreviated (%.2f%%)", _abbreviated_concurrent_gcs, percent_of(_abbreviated_concurrent_gcs, _success_concurrent_gcs)); + out->print_cr(" %5zu abbreviated (%.2f%%)", _abbreviated_concurrent_gcs, percent_of(_abbreviated_concurrent_gcs, _success_concurrent_gcs)); out->cr(); if (ShenandoahHeap::heap()->mode()->is_generational()) { - out->print_cr(SIZE_FORMAT_W(5) " Completed Old GCs (%.2f%%)", _success_old_gcs, percent_of(_success_old_gcs, completed_gcs)); - out->print_cr(" " SIZE_FORMAT_W(5) " mixed", _mixed_gcs); - out->print_cr(" " SIZE_FORMAT_W(5) " interruptions", _interrupted_old_gcs); + out->print_cr("%5zu Completed Old GCs (%.2f%%)", _success_old_gcs, percent_of(_success_old_gcs, completed_gcs)); + out->print_cr(" %5zu mixed", _mixed_gcs); + out->print_cr(" %5zu interruptions", _interrupted_old_gcs); out->cr(); } size_t degenerated_gcs = _alloc_failure_degenerated_upgrade_to_full + _success_degenerated_gcs; - out->print_cr(SIZE_FORMAT_W(5) " Degenerated GCs (%.2f%%)", degenerated_gcs, percent_of(degenerated_gcs, completed_gcs)); - out->print_cr(" " SIZE_FORMAT_W(5) " upgraded to Full GC (%.2f%%)", _alloc_failure_degenerated_upgrade_to_full, percent_of(_alloc_failure_degenerated_upgrade_to_full, degenerated_gcs)); - out->print_cr(" " SIZE_FORMAT_W(5) " caused by allocation failure (%.2f%%)", _alloc_failure_degenerated, percent_of(_alloc_failure_degenerated, degenerated_gcs)); - out->print_cr(" " SIZE_FORMAT_W(5) " abbreviated (%.2f%%)", _abbreviated_degenerated_gcs, percent_of(_abbreviated_degenerated_gcs, degenerated_gcs)); + out->print_cr("%5zu Degenerated GCs (%.2f%%)", degenerated_gcs, percent_of(degenerated_gcs, completed_gcs)); + out->print_cr(" %5zu upgraded to Full GC (%.2f%%)", _alloc_failure_degenerated_upgrade_to_full, percent_of(_alloc_failure_degenerated_upgrade_to_full, degenerated_gcs)); + out->print_cr(" %5zu caused by allocation failure (%.2f%%)", _alloc_failure_degenerated, percent_of(_alloc_failure_degenerated, degenerated_gcs)); + out->print_cr(" %5zu abbreviated (%.2f%%)", _abbreviated_degenerated_gcs, percent_of(_abbreviated_degenerated_gcs, degenerated_gcs)); for (int c = 0; c < ShenandoahGC::_DEGENERATED_LIMIT; c++) { if (_degen_point_counts[c] > 0) { const char* desc = ShenandoahGC::degen_point_to_string((ShenandoahGC::ShenandoahDegenPoint)c); - out->print_cr(" " SIZE_FORMAT_W(5) " happened at %s", _degen_point_counts[c], desc); + out->print_cr(" %5zu happened at %s", _degen_point_counts[c], desc); } } out->cr(); - out->print_cr(SIZE_FORMAT_W(5) " Full GCs (%.2f%%)", _success_full_gcs, percent_of(_success_full_gcs, completed_gcs)); + out->print_cr("%5zu Full GCs (%.2f%%)", _success_full_gcs, percent_of(_success_full_gcs, completed_gcs)); if (!ExplicitGCInvokesConcurrent) { - out->print_cr(" " SIZE_FORMAT_W(5) " invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_concurrent_gcs)); } if (!ShenandoahImplicitGCInvokesConcurrent) { - out->print_cr(" " SIZE_FORMAT_W(5) " invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_concurrent_gcs)); } - out->print_cr(" " SIZE_FORMAT_W(5) " caused by allocation failure (%.2f%%)", _alloc_failure_full, percent_of(_alloc_failure_full, _success_full_gcs)); - out->print_cr(" " SIZE_FORMAT_W(5) " upgraded from Degenerated GC (%.2f%%)", _alloc_failure_degenerated_upgrade_to_full, percent_of(_alloc_failure_degenerated_upgrade_to_full, _success_full_gcs)); + out->print_cr(" %5zu caused by allocation failure (%.2f%%)", _alloc_failure_full, percent_of(_alloc_failure_full, _success_full_gcs)); + out->print_cr(" %5zu upgraded from Degenerated GC (%.2f%%)", _alloc_failure_degenerated_upgrade_to_full, percent_of(_alloc_failure_degenerated_upgrade_to_full, _success_full_gcs)); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp index b1c2e72ef82b6..beff760cdfedf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "gc/shared/collectorCounters.hpp" @@ -192,20 +191,26 @@ bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) { return false; } + // Evacuation is complete, retire gc labs + heap->concurrent_prepare_for_update_refs(); + // Perform update-refs phase. - vmop_entry_init_updaterefs(); - entry_updaterefs(); - if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_updaterefs)) { + if (ShenandoahVerify || ShenandoahPacing) { + vmop_entry_init_update_refs(); + } + + entry_update_refs(); + if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_update_refs)) { return false; } // Concurrent update thread roots entry_update_thread_roots(); - if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_updaterefs)) { + if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_update_refs)) { return false; } - vmop_entry_final_updaterefs(); + vmop_entry_final_update_refs(); // Update references freed up collection set, kick the cleanup to reclaim the space. entry_cleanup_complete(); @@ -259,7 +264,7 @@ void ShenandoahConcurrentGC::vmop_entry_final_mark() { VMThread::execute(&op); // jump to entry_final_mark under safepoint } -void ShenandoahConcurrentGC::vmop_entry_init_updaterefs() { +void ShenandoahConcurrentGC::vmop_entry_init_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters()); ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross); @@ -269,7 +274,7 @@ void ShenandoahConcurrentGC::vmop_entry_init_updaterefs() { VMThread::execute(&op); } -void ShenandoahConcurrentGC::vmop_entry_final_updaterefs() { +void ShenandoahConcurrentGC::vmop_entry_final_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters()); ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross); @@ -314,16 +319,16 @@ void ShenandoahConcurrentGC::entry_final_mark() { op_final_mark(); } -void ShenandoahConcurrentGC::entry_init_updaterefs() { +void ShenandoahConcurrentGC::entry_init_update_refs() { static const char* msg = "Pause Init Update Refs"; ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_update_refs); EventMark em("%s", msg); // No workers used in this phase, no setup required - op_init_updaterefs(); + op_init_update_refs(); } -void ShenandoahConcurrentGC::entry_final_updaterefs() { +void ShenandoahConcurrentGC::entry_final_update_refs() { static const char* msg = "Pause Final Update Refs"; ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_update_refs); EventMark em("%s", msg); @@ -332,7 +337,7 @@ void ShenandoahConcurrentGC::entry_final_updaterefs() { ShenandoahWorkerPolicy::calc_workers_for_final_update_ref(), "final reference update"); - op_final_updaterefs(); + op_final_update_refs(); } void ShenandoahConcurrentGC::entry_final_roots() { @@ -551,7 +556,7 @@ void ShenandoahConcurrentGC::entry_update_thread_roots() { op_update_thread_roots(); } -void ShenandoahConcurrentGC::entry_updaterefs() { +void ShenandoahConcurrentGC::entry_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters()); static const char* msg = "Concurrent update references"; @@ -563,7 +568,7 @@ void ShenandoahConcurrentGC::entry_updaterefs() { "concurrent reference update"); heap->try_inject_alloc_failure(); - op_updaterefs(); + op_update_refs(); } void ShenandoahConcurrentGC::entry_cleanup_complete() { @@ -593,7 +598,7 @@ class ShenandoahInitMarkUpdateRegionStateClosure : public ShenandoahHeapRegionCl ShenandoahInitMarkUpdateRegionStateClosure() : _ctx(ShenandoahHeap::heap()->marking_context()) {} void heap_region_do(ShenandoahHeapRegion* r) { - assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index()); + assert(!r->has_live(), "Region %zu should have no live data", r->index()); if (r->is_active()) { // Check if region needs updating its TAMS. We have updated it already during concurrent // reset, so it is very likely we don't need to do another write here. Since most regions @@ -603,7 +608,7 @@ class ShenandoahInitMarkUpdateRegionStateClosure : public ShenandoahHeapRegionCl } } else { assert(_ctx->top_at_mark_start(r) == r->top(), - "Region " SIZE_FORMAT " should already have correct TAMS", r->index()); + "Region %zu should already have correct TAMS", r->index()); } } @@ -748,10 +753,6 @@ void ShenandoahConcurrentGC::op_final_mark() { heap->verifier()->verify_after_concmark(); } } - - if (VerifyAfterGC) { - Universe::verify(); - } } } } @@ -920,8 +921,8 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public WorkerTask { } // If we are going to perform concurrent class unloading later on, we need to - // cleanup the weak oops in CLD and determinate nmethod's unloading state, so that we - // can cleanup immediate garbage sooner. + // clean up the weak oops in CLD and determine nmethod's unloading state, so that we + // can clean up immediate garbage sooner. if (ShenandoahHeap::heap()->unload_classes()) { // Applies ShenandoahIsCLDAlive closure to CLDs, native barrier will either null the // CLD's holder or evacuate it. @@ -946,22 +947,25 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public WorkerTask { void ShenandoahConcurrentGC::op_weak_roots() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); assert(heap->is_concurrent_weak_root_in_progress(), "Only during this phase"); - // Concurrent weak root processing { + // Concurrent weak root processing ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_work); ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_roots_work); ShenandoahConcurrentWeakRootsEvacUpdateTask task(ShenandoahPhaseTimings::conc_weak_roots_work); heap->workers()->run_task(&task); } - // Perform handshake to flush out dead oops { + // It is possible for mutators executing the load reference barrier to have + // loaded an oop through a weak handle that has since been nulled out by + // weak root processing. Handshaking here forces them to complete the + // barrier before the GC cycle continues and does something that would + // change the evaluation of the barrier (for example, resetting the TAMS + // on trashed regions could make an oop appear to be marked _after_ the + // region has been recycled). ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous); heap->rendezvous_threads("Shenandoah Concurrent Weak Roots"); } - // We can only toggle concurrent_weak_root_in_progress flag - // at a safepoint, so that mutators see a consistent - // value. The flag will be cleared at the next safepoint. } void ShenandoahConcurrentGC::op_class_unloading() { @@ -1056,21 +1060,17 @@ void ShenandoahConcurrentGC::op_evacuate() { ShenandoahHeap::heap()->evacuate_collection_set(true /*concurrent*/); } -void ShenandoahConcurrentGC::op_init_updaterefs() { +void ShenandoahConcurrentGC::op_init_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); - heap->set_evacuation_in_progress(false); - heap->set_concurrent_weak_root_in_progress(false); - heap->prepare_update_heap_references(true /*concurrent*/); - heap->set_update_refs_in_progress(true); if (ShenandoahVerify) { - heap->verifier()->verify_before_updaterefs(); + heap->verifier()->verify_before_update_refs(); } if (ShenandoahPacing) { - heap->pacer()->setup_for_updaterefs(); + heap->pacer()->setup_for_update_refs(); } } -void ShenandoahConcurrentGC::op_updaterefs() { +void ShenandoahConcurrentGC::op_update_refs() { ShenandoahHeap::heap()->update_heap_references(true /*concurrent*/); } @@ -1102,7 +1102,7 @@ void ShenandoahConcurrentGC::op_update_thread_roots() { Handshake::execute(&cl); } -void ShenandoahConcurrentGC::op_final_updaterefs() { +void ShenandoahConcurrentGC::op_final_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "must be at safepoint"); assert(!heap->_update_refs_iterator.has_next(), "Should have finished update references"); @@ -1150,7 +1150,7 @@ void ShenandoahConcurrentGC::op_final_updaterefs() { } if (ShenandoahVerify) { - heap->verifier()->verify_after_updaterefs(); + heap->verifier()->verify_after_update_refs(); } if (VerifyAfterGC) { @@ -1178,6 +1178,10 @@ void ShenandoahConcurrentGC::op_final_roots() { ShenandoahGenerationalHeap::heap()->update_region_ages(_generation->complete_marking_context()); } } + + if (VerifyAfterGC) { + Universe::verify(); + } } void ShenandoahConcurrentGC::op_cleanup_complete() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.hpp index a1837068a7cc0..b4c858bb24551 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.hpp @@ -67,16 +67,16 @@ class ShenandoahConcurrentGC : public ShenandoahGC { // call the entry method below void vmop_entry_init_mark(); void vmop_entry_final_mark(); - void vmop_entry_init_updaterefs(); - void vmop_entry_final_updaterefs(); + void vmop_entry_init_update_refs(); + void vmop_entry_final_update_refs(); void vmop_entry_final_roots(); // Entry methods to normally STW GC operations. These set up logging, monitoring // and workers for net VM operation void entry_init_mark(); void entry_final_mark(); - void entry_init_updaterefs(); - void entry_final_updaterefs(); + void entry_init_update_refs(); + void entry_final_update_refs(); void entry_final_roots(); // Entry methods to normally concurrent GC operations. These set up logging, monitoring @@ -93,7 +93,7 @@ class ShenandoahConcurrentGC : public ShenandoahGC { void entry_cleanup_early(); void entry_evacuate(); void entry_update_thread_roots(); - void entry_updaterefs(); + void entry_update_refs(); void entry_cleanup_complete(); // Called when the collection set is empty, but the generational mode has regions to promote in place @@ -112,10 +112,10 @@ class ShenandoahConcurrentGC : public ShenandoahGC { void op_strong_roots(); void op_cleanup_early(); void op_evacuate(); - void op_init_updaterefs(); - void op_updaterefs(); + void op_init_update_refs(); + void op_update_refs(); void op_update_thread_roots(); - void op_final_updaterefs(); + void op_final_update_refs(); void op_final_roots(); void op_cleanup_complete(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index 1709844a8c39a..1feb19f6e4a9a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/satbMarkQueue.hpp" #include "gc/shared/strongRootsScope.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 136ac22d840ff..1ddfb6b7054cf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentGC.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" @@ -132,6 +131,8 @@ void ShenandoahControlThread::run_service() { // GC is starting, bump the internal ID update_gc_id(); + heuristics->cancel_trigger_request(); + heap->reset_bytes_allocated_since_gc_start(); MetaspaceCombinedStats meta_sizes = MetaspaceUtils::get_combined_statistics(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahController.cpp b/src/hotspot/share/gc/shenandoah/shenandoahController.cpp index effa4a8f1fc9c..a4d5a57234918 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahController.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahController.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shenandoah/shenandoahController.hpp" @@ -61,7 +61,7 @@ void ShenandoahController::handle_alloc_failure(ShenandoahAllocRequest& req, boo if (try_set_alloc_failure_gc(is_humongous)) { // Only report the first allocation failure - log_info(gc)("Failed to allocate %s, " SIZE_FORMAT "%s", + log_info(gc)("Failed to allocate %s, %zu%s", req.type_string(), byte_size_in_proper_unit(req.size() * HeapWordSize), proper_unit_for_byte_size(req.size() * HeapWordSize)); @@ -84,7 +84,7 @@ void ShenandoahController::handle_alloc_failure_evac(size_t words) { if (try_set_alloc_failure_gc(is_humongous)) { // Only report the first allocation failure - log_info(gc)("Failed to allocate " SIZE_FORMAT "%s for evacuation", + log_info(gc)("Failed to allocate %zu%s for evacuation", byte_size_in_proper_unit(words * HeapWordSize), proper_unit_for_byte_size(words * HeapWordSize)); } @@ -109,4 +109,3 @@ bool ShenandoahController::try_set_alloc_failure_gc(bool is_humongous) { bool ShenandoahController::is_alloc_failure_gc() { return _alloc_failure_gc.is_set(); } - diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp index 7d2690ef5f614..17af519392ebc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -264,15 +263,15 @@ void ShenandoahDegenGC::op_degenerated() { // If heuristics thinks we should do the cycle, this flag would be set, // and we need to do update-refs. Otherwise, it would be the shortcut cycle. if (heap->has_forwarded_objects()) { - op_init_updaterefs(); + op_init_update_refs(); assert(!heap->cancelled_gc(), "STW reference update can not OOM"); } else { _abbreviated = true; } - case _degenerated_updaterefs: + case _degenerated_update_refs: if (heap->has_forwarded_objects()) { - op_updaterefs(); + op_update_refs(); op_update_roots(); assert(!heap->cancelled_gc(), "STW reference update can not OOM"); } @@ -304,7 +303,7 @@ void ShenandoahDegenGC::op_degenerated() { // Check for futility and fail. There is no reason to do several back-to-back Degenerated cycles, // because that probably means the heap is overloaded and/or fragmented. - if (!metrics.is_good_progress()) { + if (!metrics.is_good_progress(_generation)) { heap->cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); op_degenerated_futile(); } else { @@ -387,16 +386,16 @@ void ShenandoahDegenGC::op_evacuate() { ShenandoahHeap::heap()->evacuate_collection_set(false /* concurrent*/); } -void ShenandoahDegenGC::op_init_updaterefs() { +void ShenandoahDegenGC::op_init_update_refs() { // Evacuation has completed ShenandoahHeap* const heap = ShenandoahHeap::heap(); heap->prepare_update_heap_references(false /*concurrent*/); heap->set_update_refs_in_progress(true); } -void ShenandoahDegenGC::op_updaterefs() { +void ShenandoahDegenGC::op_update_refs() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); - ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc_updaterefs); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc_update_refs); // Handed over from concurrent update references phase heap->update_heap_references(false /*concurrent*/); @@ -412,7 +411,7 @@ void ShenandoahDegenGC::op_update_roots() { heap->update_heap_region_states(false /*concurrent*/); if (ShenandoahVerify) { - heap->verifier()->verify_after_updaterefs(); + heap->verifier()->verify_after_update_refs(); } if (VerifyAfterGC) { @@ -447,7 +446,7 @@ const char* ShenandoahDegenGC::degen_event_message(ShenandoahDegenPoint point) c SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Degenerated GC", " (Mark)"); case _degenerated_evac: SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Degenerated GC", " (Evacuation)"); - case _degenerated_updaterefs: + case _degenerated_update_refs: SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Degenerated GC", " (Update Refs)"); default: ShouldNotReachHere(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.hpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.hpp index 8dc8ecea75fb2..971bd67eb0df8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.hpp @@ -53,8 +53,8 @@ class ShenandoahDegenGC : public ShenandoahGC { void op_cleanup_early(); void op_evacuate(); - void op_init_updaterefs(); - void op_updaterefs(); + void op_init_update_refs(); + void op_update_refs(); void op_update_roots(); void op_cleanup_complete(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp index 5ca657638336d..8069fd13afa60 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacInfo.hpp @@ -35,20 +35,20 @@ class ShenandoahEvacuationInformation : public StackObj { size_t _collected_old; size_t _collected_promoted; size_t _collected_young; + size_t _free_regions; size_t _regions_promoted_humongous; size_t _regions_promoted_regular; size_t _regular_promoted_garbage; size_t _regular_promoted_free; - size_t _regions_freed; size_t _regions_immediate; size_t _immediate_size; public: ShenandoahEvacuationInformation() : _collection_set_regions(0), _collection_set_used_before(0), _collection_set_used_after(0), - _collected_old(0), _collected_promoted(0), _collected_young(0), _regions_promoted_humongous(0), - _regions_promoted_regular(0), _regular_promoted_garbage(0), _regular_promoted_free(0), - _regions_freed(0), _regions_immediate(0), _immediate_size(0) { } + _collected_old(0), _collected_promoted(0), _collected_young(0), _free_regions(0), + _regions_promoted_humongous(0), _regions_promoted_regular(0), _regular_promoted_garbage(0), + _regular_promoted_free(0), _regions_immediate(0), _immediate_size(0) { } void set_collection_set_regions(size_t collection_set_regions) { _collection_set_regions = collection_set_regions; @@ -74,8 +74,8 @@ class ShenandoahEvacuationInformation : public StackObj { _collected_young = collected; } - void set_regions_freed(size_t freed) { - _regions_freed = freed; + void set_free_regions(size_t freed) { + _free_regions = freed; } void set_regions_promoted_humongous(size_t humongous) { @@ -112,7 +112,7 @@ class ShenandoahEvacuationInformation : public StackObj { size_t regions_promoted_regular() { return _regions_promoted_regular; } size_t regular_promoted_garbage() { return _regular_promoted_garbage; } size_t regular_promoted_free() { return _regular_promoted_free; } - size_t regions_freed() { return _regions_freed; } + size_t free_regions() { return _free_regions; } size_t regions_immediate() { return _regions_immediate; } size_t immediate_size() { return _immediate_size; } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp index 8334126b6f829..9c84ac41e8415 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacOOMHandler.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahEvacOOMHandler.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp index ededb99b24ecf..3ddc8bf636e91 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -84,8 +84,8 @@ void ShenandoahEvacuationStats::print_on(outputStream* st) { #ifndef PRODUCT size_t abandoned_size = _bytes_attempted - _bytes_completed; size_t abandoned_count = _evacuations_attempted - _evacuations_completed; - st->print_cr("Evacuated " SIZE_FORMAT "%s across " SIZE_FORMAT " objects, " - "abandoned " SIZE_FORMAT "%s across " SIZE_FORMAT " objects.", + st->print_cr("Evacuated %zu%s across %zu objects, " + "abandoned %zu%s across %zu objects.", byte_size_in_proper_unit(_bytes_completed), proper_unit_for_byte_size(_bytes_completed), _evacuations_completed, byte_size_in_proper_unit(abandoned_size), proper_unit_for_byte_size(abandoned_size), diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index 89a04d23cec92..138e032074831 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, 2021, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/tlab_globals.hpp" #include "gc/shenandoah/shenandoahAffiliation.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" @@ -65,7 +65,7 @@ class ShenandoahLeftRightIterator { bool has_next() const { if (_idx <= _end) { - assert(_partitions->in_free_set(_partition, _idx), "Boundaries or find_last_set_bit failed: " SSIZE_FORMAT, _idx); + assert(_partitions->in_free_set(_partition, _idx), "Boundaries or find_last_set_bit failed: %zd", _idx); return true; } return false; @@ -96,7 +96,7 @@ class ShenandoahRightLeftIterator { bool has_next() const { if (_idx >= _end) { - assert(_partitions->in_free_set(_partition, _idx), "Boundaries or find_last_set_bit failed: " SSIZE_FORMAT, _idx); + assert(_partitions->in_free_set(_partition, _idx), "Boundaries or find_last_set_bit failed: %zd", _idx); return true; } return false; @@ -114,17 +114,17 @@ class ShenandoahRightLeftIterator { #ifndef PRODUCT void ShenandoahRegionPartitions::dump_bitmap() const { - log_debug(gc)("Mutator range [" SSIZE_FORMAT ", " SSIZE_FORMAT "], Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT - "], Old Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]", + log_debug(gc)("Mutator range [%zd, %zd], Collector range [%zd, %zd" + "], Old Collector range [%zd, %zd]", _leftmosts[int(ShenandoahFreeSetPartitionId::Mutator)], _rightmosts[int(ShenandoahFreeSetPartitionId::Mutator)], _leftmosts[int(ShenandoahFreeSetPartitionId::Collector)], _rightmosts[int(ShenandoahFreeSetPartitionId::Collector)], _leftmosts[int(ShenandoahFreeSetPartitionId::OldCollector)], _rightmosts[int(ShenandoahFreeSetPartitionId::OldCollector)]); - log_debug(gc)("Empty Mutator range [" SSIZE_FORMAT ", " SSIZE_FORMAT - "], Empty Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT - "], Empty Old Collecto range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]", + log_debug(gc)("Empty Mutator range [%zd, %zd" + "], Empty Collector range [%zd, %zd" + "], Empty Old Collecto range [%zd, %zd]", _leftmosts_empty[int(ShenandoahFreeSetPartitionId::Mutator)], _rightmosts_empty[int(ShenandoahFreeSetPartitionId::Mutator)], _leftmosts_empty[int(ShenandoahFreeSetPartitionId::Collector)], @@ -156,7 +156,7 @@ void ShenandoahRegionPartitions::dump_bitmap_row(idx_t region_idx) const { uintx old_collector_bits = _membership[int(ShenandoahFreeSetPartitionId::OldCollector)].bits_at(aligned_idx); uintx free_bits = mutator_bits | collector_bits | old_collector_bits; uintx notfree_bits = ~free_bits; - log_debug(gc)(SSIZE_FORMAT_W(6) ": " SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0, + log_debug(gc)("%6zd : " SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0 " 0x" SIZE_FORMAT_X_0, aligned_idx, mutator_bits, collector_bits, old_collector_bits, notfree_bits); } #endif @@ -272,7 +272,7 @@ void ShenandoahRegionPartitions::increase_used(ShenandoahFreeSetPartitionId whic assert (which_partition < NumPartitions, "Partition must be valid"); _used[int(which_partition)] += bytes; assert (_used[int(which_partition)] <= _capacity[int(which_partition)], - "Must not use (" SIZE_FORMAT ") more than capacity (" SIZE_FORMAT ") after increase by " SIZE_FORMAT, + "Must not use (%zu) more than capacity (%zu) after increase by %zu", _used[int(which_partition)], _capacity[int(which_partition)], bytes); } @@ -337,7 +337,7 @@ void ShenandoahRegionPartitions::retire_range_from_partition( ShenandoahFreeSetPartitionId partition, idx_t low_idx, idx_t high_idx) { // Note: we may remove from free partition even if region is not entirely full, such as when available < PLAB::min_size() - assert ((low_idx < _max) && (high_idx < _max), "Both indices are sane: " SIZE_FORMAT " and " SIZE_FORMAT " < " SIZE_FORMAT, + assert ((low_idx < _max) && (high_idx < _max), "Both indices are sane: %zu and %zu < %zu", low_idx, high_idx, _max); assert (partition < NumPartitions, "Cannot remove from free partitions if not already free"); @@ -352,7 +352,7 @@ void ShenandoahRegionPartitions::retire_range_from_partition( void ShenandoahRegionPartitions::retire_from_partition(ShenandoahFreeSetPartitionId partition, idx_t idx, size_t used_bytes) { // Note: we may remove from free partition even if region is not entirely full, such as when available < PLAB::min_size() - assert (idx < _max, "index is sane: " SIZE_FORMAT " < " SIZE_FORMAT, idx, _max); + assert (idx < _max, "index is sane: %zu < %zu", idx, _max); assert (partition < NumPartitions, "Cannot remove from free partitions if not already free"); assert (in_free_set(partition, idx), "Must be in partition to remove from partition"); @@ -366,7 +366,7 @@ void ShenandoahRegionPartitions::retire_from_partition(ShenandoahFreeSetPartitio } void ShenandoahRegionPartitions::make_free(idx_t idx, ShenandoahFreeSetPartitionId which_partition, size_t available) { - assert (idx < _max, "index is sane: " SIZE_FORMAT " < " SIZE_FORMAT, idx, _max); + assert (idx < _max, "index is sane: %zu < %zu", idx, _max); assert (membership(idx) == ShenandoahFreeSetPartitionId::NotFree, "Cannot make free if already free"); assert (which_partition < NumPartitions, "selected free partition must be valid"); assert (available <= _region_size_bytes, "Available cannot exceed region size"); @@ -398,14 +398,14 @@ bool ShenandoahRegionPartitions::available_implies_empty(size_t available_in_reg void ShenandoahRegionPartitions::move_from_partition_to_partition(idx_t idx, ShenandoahFreeSetPartitionId orig_partition, ShenandoahFreeSetPartitionId new_partition, size_t available) { ShenandoahHeapRegion* r = ShenandoahHeap::heap()->get_region(idx); - assert (idx < _max, "index is sane: " SIZE_FORMAT " < " SIZE_FORMAT, idx, _max); + assert (idx < _max, "index is sane: %zu < %zu", idx, _max); assert (orig_partition < NumPartitions, "Original partition must be valid"); assert (new_partition < NumPartitions, "New partition must be valid"); assert (available <= _region_size_bytes, "Available cannot exceed region size"); assert (_membership[int(orig_partition)].is_set(idx), "Cannot move from partition unless in partition"); assert ((r != nullptr) && ((r->is_trash() && (available == _region_size_bytes)) || (r->used() + available == _region_size_bytes)), - "Used: " SIZE_FORMAT " + available: " SIZE_FORMAT " should equal region size: " SIZE_FORMAT, + "Used: %zu + available: %zu should equal region size: %zu", ShenandoahHeap::heap()->get_region(idx)->used(), available, _region_size_bytes); // Expected transitions: @@ -422,13 +422,13 @@ void ShenandoahRegionPartitions::move_from_partition_to_partition(idx_t idx, She (is_young_collector_partition(orig_partition) && is_mutator_partition(new_partition)) || (is_old_collector_partition(orig_partition) && available_implies_empty(available) && is_mutator_partition(new_partition)), - "Unexpected movement between partitions, available: " SIZE_FORMAT ", _region_size_bytes: " SIZE_FORMAT + "Unexpected movement between partitions, available: %zu, _region_size_bytes: %zu" ", orig_partition: %s, new_partition: %s", available, _region_size_bytes, partition_name(orig_partition), partition_name(new_partition)); size_t used = _region_size_bytes - available; assert (_used[int(orig_partition)] >= used, - "Orig partition used: " SIZE_FORMAT " must exceed moved used: " SIZE_FORMAT " within region " SSIZE_FORMAT, + "Orig partition used: %zu must exceed moved used: %zu within region %zd", _used[int(orig_partition)], used, idx); _membership[int(orig_partition)].clear_bit(idx); @@ -451,7 +451,7 @@ const char* ShenandoahRegionPartitions::partition_membership_name(idx_t idx) con } inline ShenandoahFreeSetPartitionId ShenandoahRegionPartitions::membership(idx_t idx) const { - assert (idx < _max, "index is sane: " SIZE_FORMAT " < " SIZE_FORMAT, idx, _max); + assert (idx < _max, "index is sane: %zu < %zu", idx, _max); ShenandoahFreeSetPartitionId result = ShenandoahFreeSetPartitionId::NotFree; for (uint partition_id = 0; partition_id < UIntNumPartitions; partition_id++) { if (_membership[partition_id].is_set(idx)) { @@ -464,7 +464,7 @@ inline ShenandoahFreeSetPartitionId ShenandoahRegionPartitions::membership(idx_t #ifdef ASSERT inline bool ShenandoahRegionPartitions::partition_id_matches(idx_t idx, ShenandoahFreeSetPartitionId test_partition) const { - assert (idx < _max, "index is sane: " SIZE_FORMAT " < " SIZE_FORMAT, idx, _max); + assert (idx < _max, "index is sane: %zu < %zu", idx, _max); assert (test_partition < ShenandoahFreeSetPartitionId::NotFree, "must be a valid partition"); return membership(idx) == test_partition; @@ -543,7 +543,7 @@ idx_t ShenandoahRegionPartitions::leftmost_empty(ShenandoahFreeSetPartitionId wh } for (idx_t idx = find_index_of_next_available_region(which_partition, _leftmosts_empty[int(which_partition)]); idx < max_regions; ) { - assert(in_free_set(which_partition, idx), "Boundaries or find_last_set_bit failed: " SSIZE_FORMAT, idx); + assert(in_free_set(which_partition, idx), "Boundaries or find_last_set_bit failed: %zd", idx); if (_free_set->alloc_capacity(idx) == _region_size_bytes) { _leftmosts_empty[int(which_partition)] = idx; return idx; @@ -562,7 +562,7 @@ idx_t ShenandoahRegionPartitions::rightmost_empty(ShenandoahFreeSetPartitionId w } for (idx_t idx = find_index_of_previous_available_region(which_partition, _rightmosts_empty[int(which_partition)]); idx >= 0; ) { - assert(in_free_set(which_partition, idx), "Boundaries or find_last_set_bit failed: " SSIZE_FORMAT, idx); + assert(in_free_set(which_partition, idx), "Boundaries or find_last_set_bit failed: %zd", idx); if (_free_set->alloc_capacity(idx) == _region_size_bytes) { _rightmosts_empty[int(which_partition)] = idx; return idx; @@ -625,103 +625,103 @@ void ShenandoahRegionPartitions::assert_bounds() { // Performance invariants. Failing these would not break the free partition, but performance would suffer. assert (leftmost(ShenandoahFreeSetPartitionId::Mutator) <= _max, - "leftmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, leftmost(ShenandoahFreeSetPartitionId::Mutator), _max); + "leftmost in bounds: %zd < %zd", leftmost(ShenandoahFreeSetPartitionId::Mutator), _max); assert (rightmost(ShenandoahFreeSetPartitionId::Mutator) < _max, - "rightmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, rightmost(ShenandoahFreeSetPartitionId::Mutator), _max); + "rightmost in bounds: %zd < %zd", rightmost(ShenandoahFreeSetPartitionId::Mutator), _max); assert (leftmost(ShenandoahFreeSetPartitionId::Mutator) == _max || partition_id_matches(leftmost(ShenandoahFreeSetPartitionId::Mutator), ShenandoahFreeSetPartitionId::Mutator), - "leftmost region should be free: " SSIZE_FORMAT, leftmost(ShenandoahFreeSetPartitionId::Mutator)); + "leftmost region should be free: %zd", leftmost(ShenandoahFreeSetPartitionId::Mutator)); assert (leftmost(ShenandoahFreeSetPartitionId::Mutator) == _max || partition_id_matches(rightmost(ShenandoahFreeSetPartitionId::Mutator), ShenandoahFreeSetPartitionId::Mutator), - "rightmost region should be free: " SSIZE_FORMAT, rightmost(ShenandoahFreeSetPartitionId::Mutator)); + "rightmost region should be free: %zd", rightmost(ShenandoahFreeSetPartitionId::Mutator)); // If Mutator partition is empty, leftmosts will both equal max, rightmosts will both equal zero. // Likewise for empty region partitions. idx_t beg_off = leftmosts[int(ShenandoahFreeSetPartitionId::Mutator)]; idx_t end_off = rightmosts[int(ShenandoahFreeSetPartitionId::Mutator)]; assert (beg_off >= leftmost(ShenandoahFreeSetPartitionId::Mutator), - "free regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions before the leftmost: %zd, bound %zd", beg_off, leftmost(ShenandoahFreeSetPartitionId::Mutator)); assert (end_off <= rightmost(ShenandoahFreeSetPartitionId::Mutator), - "free regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions past the rightmost: %zd, bound %zd", end_off, rightmost(ShenandoahFreeSetPartitionId::Mutator)); beg_off = empty_leftmosts[int(ShenandoahFreeSetPartitionId::Mutator)]; end_off = empty_rightmosts[int(ShenandoahFreeSetPartitionId::Mutator)]; assert (beg_off >= leftmost_empty(ShenandoahFreeSetPartitionId::Mutator), - "free empty regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions before the leftmost: %zd, bound %zd", beg_off, leftmost_empty(ShenandoahFreeSetPartitionId::Mutator)); assert (end_off <= rightmost_empty(ShenandoahFreeSetPartitionId::Mutator), - "free empty regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions past the rightmost: %zd, bound %zd", end_off, rightmost_empty(ShenandoahFreeSetPartitionId::Mutator)); // Performance invariants. Failing these would not break the free partition, but performance would suffer. - assert (leftmost(ShenandoahFreeSetPartitionId::Collector) <= _max, "leftmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, + assert (leftmost(ShenandoahFreeSetPartitionId::Collector) <= _max, "leftmost in bounds: %zd < %zd", leftmost(ShenandoahFreeSetPartitionId::Collector), _max); - assert (rightmost(ShenandoahFreeSetPartitionId::Collector) < _max, "rightmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, + assert (rightmost(ShenandoahFreeSetPartitionId::Collector) < _max, "rightmost in bounds: %zd < %zd", rightmost(ShenandoahFreeSetPartitionId::Collector), _max); assert (leftmost(ShenandoahFreeSetPartitionId::Collector) == _max || partition_id_matches(leftmost(ShenandoahFreeSetPartitionId::Collector), ShenandoahFreeSetPartitionId::Collector), - "leftmost region should be free: " SSIZE_FORMAT, leftmost(ShenandoahFreeSetPartitionId::Collector)); + "leftmost region should be free: %zd", leftmost(ShenandoahFreeSetPartitionId::Collector)); assert (leftmost(ShenandoahFreeSetPartitionId::Collector) == _max || partition_id_matches(rightmost(ShenandoahFreeSetPartitionId::Collector), ShenandoahFreeSetPartitionId::Collector), - "rightmost region should be free: " SSIZE_FORMAT, rightmost(ShenandoahFreeSetPartitionId::Collector)); + "rightmost region should be free: %zd", rightmost(ShenandoahFreeSetPartitionId::Collector)); // If Collector partition is empty, leftmosts will both equal max, rightmosts will both equal zero. // Likewise for empty region partitions. beg_off = leftmosts[int(ShenandoahFreeSetPartitionId::Collector)]; end_off = rightmosts[int(ShenandoahFreeSetPartitionId::Collector)]; assert (beg_off >= leftmost(ShenandoahFreeSetPartitionId::Collector), - "free regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions before the leftmost: %zd, bound %zd", beg_off, leftmost(ShenandoahFreeSetPartitionId::Collector)); assert (end_off <= rightmost(ShenandoahFreeSetPartitionId::Collector), - "free regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions past the rightmost: %zd, bound %zd", end_off, rightmost(ShenandoahFreeSetPartitionId::Collector)); beg_off = empty_leftmosts[int(ShenandoahFreeSetPartitionId::Collector)]; end_off = empty_rightmosts[int(ShenandoahFreeSetPartitionId::Collector)]; assert (beg_off >= _leftmosts_empty[int(ShenandoahFreeSetPartitionId::Collector)], - "free empty regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions before the leftmost: %zd, bound %zd", beg_off, leftmost_empty(ShenandoahFreeSetPartitionId::Collector)); assert (end_off <= _rightmosts_empty[int(ShenandoahFreeSetPartitionId::Collector)], - "free empty regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions past the rightmost: %zd, bound %zd", end_off, rightmost_empty(ShenandoahFreeSetPartitionId::Collector)); // Performance invariants. Failing these would not break the free partition, but performance would suffer. - assert (leftmost(ShenandoahFreeSetPartitionId::OldCollector) <= _max, "leftmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, + assert (leftmost(ShenandoahFreeSetPartitionId::OldCollector) <= _max, "leftmost in bounds: %zd < %zd", leftmost(ShenandoahFreeSetPartitionId::OldCollector), _max); - assert (rightmost(ShenandoahFreeSetPartitionId::OldCollector) < _max, "rightmost in bounds: " SSIZE_FORMAT " < " SSIZE_FORMAT, + assert (rightmost(ShenandoahFreeSetPartitionId::OldCollector) < _max, "rightmost in bounds: %zd < %zd", rightmost(ShenandoahFreeSetPartitionId::OldCollector), _max); assert (leftmost(ShenandoahFreeSetPartitionId::OldCollector) == _max || partition_id_matches(leftmost(ShenandoahFreeSetPartitionId::OldCollector), ShenandoahFreeSetPartitionId::OldCollector), - "leftmost region should be free: " SSIZE_FORMAT, leftmost(ShenandoahFreeSetPartitionId::OldCollector)); + "leftmost region should be free: %zd", leftmost(ShenandoahFreeSetPartitionId::OldCollector)); assert (leftmost(ShenandoahFreeSetPartitionId::OldCollector) == _max || partition_id_matches(rightmost(ShenandoahFreeSetPartitionId::OldCollector), ShenandoahFreeSetPartitionId::OldCollector), - "rightmost region should be free: " SSIZE_FORMAT, rightmost(ShenandoahFreeSetPartitionId::OldCollector)); + "rightmost region should be free: %zd", rightmost(ShenandoahFreeSetPartitionId::OldCollector)); // If OldCollector partition is empty, leftmosts will both equal max, rightmosts will both equal zero. // Likewise for empty region partitions. beg_off = leftmosts[int(ShenandoahFreeSetPartitionId::OldCollector)]; end_off = rightmosts[int(ShenandoahFreeSetPartitionId::OldCollector)]; assert (beg_off >= leftmost(ShenandoahFreeSetPartitionId::OldCollector), - "free regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions before the leftmost: %zd, bound %zd", beg_off, leftmost(ShenandoahFreeSetPartitionId::OldCollector)); assert (end_off <= rightmost(ShenandoahFreeSetPartitionId::OldCollector), - "free regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free regions past the rightmost: %zd, bound %zd", end_off, rightmost(ShenandoahFreeSetPartitionId::OldCollector)); beg_off = empty_leftmosts[int(ShenandoahFreeSetPartitionId::OldCollector)]; end_off = empty_rightmosts[int(ShenandoahFreeSetPartitionId::OldCollector)]; assert (beg_off >= _leftmosts_empty[int(ShenandoahFreeSetPartitionId::OldCollector)], - "free empty regions before the leftmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions before the leftmost: %zd, bound %zd", beg_off, leftmost_empty(ShenandoahFreeSetPartitionId::OldCollector)); assert (end_off <= _rightmosts_empty[int(ShenandoahFreeSetPartitionId::OldCollector)], - "free empty regions past the rightmost: " SSIZE_FORMAT ", bound " SSIZE_FORMAT, + "free empty regions past the rightmost: %zd, bound %zd", end_off, rightmost_empty(ShenandoahFreeSetPartitionId::OldCollector)); } #endif @@ -937,7 +937,7 @@ HeapWord* ShenandoahFreeSet::try_allocate_from_mutator(ShenandoahAllocRequest& r } // Region r is entirely empty. If try_allocate_in fails on region r, something else is really wrong. // Don't bother to retry with other regions. - log_debug(gc, free)("Flipped region " SIZE_FORMAT " to gc for request: " PTR_FORMAT, idx, p2i(&req)); + log_debug(gc, free)("Flipped region %zu to gc for request: " PTR_FORMAT, idx, p2i(&req)); return try_allocate_in(r, req, in_new_region); } } @@ -996,8 +996,10 @@ HeapWord* ShenandoahFreeSet::allocate_aligned_plab(size_t size, ShenandoahAllocR } HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, ShenandoahAllocRequest& req, bool& in_new_region) { - assert (has_alloc_capacity(r), "Performance: should avoid full regions on this path: " SIZE_FORMAT, r->index()); + assert (has_alloc_capacity(r), "Performance: should avoid full regions on this path: %zu", r->index()); if (_heap->is_concurrent_weak_root_in_progress() && r->is_trash()) { + // We cannot use this region for allocation when weak roots are in progress because the collector may need + // to reference unmarked oops during concurrent classunloading. return nullptr; } HeapWord* result = nullptr; @@ -1005,9 +1007,10 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah in_new_region = r->is_empty(); if (in_new_region) { - log_debug(gc)("Using new region (" SIZE_FORMAT ") for %s (" PTR_FORMAT ").", - r->index(), ShenandoahAllocRequest::alloc_type_to_string(req.type()), p2i(&req)); - assert(!r->is_affiliated(), "New region " SIZE_FORMAT " should be unaffiliated", r->index()); + log_debug(gc, free)("Using new region (%zu) for %s (" PTR_FORMAT ").", + r->index(), ShenandoahAllocRequest::alloc_type_to_string(req.type()), p2i(&req)); + assert(!r->is_affiliated(), "New region %zu should be unaffiliated", r->index()); + r->set_affiliation(req.affiliation()); if (r->is_old()) { // Any OLD region allocated during concurrent coalesce-and-fill does not need to be coalesced and filled because @@ -1026,10 +1029,10 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah assert(ctx->top_at_mark_start(r) == r->bottom(), "Newly established allocation region starts with TAMS equal to bottom"); assert(ctx->is_bitmap_range_within_region_clear(ctx->top_bitmap(r), r->end()), "Bitmap above top_bitmap() must be clear"); #endif - log_debug(gc)("Using new region (" SIZE_FORMAT ") for %s (" PTR_FORMAT ").", - r->index(), ShenandoahAllocRequest::alloc_type_to_string(req.type()), p2i(&req)); + log_debug(gc, free)("Using new region (%zu) for %s (" PTR_FORMAT ").", + r->index(), ShenandoahAllocRequest::alloc_type_to_string(req.type()), p2i(&req)); } else { - assert(r->is_affiliated(), "Region " SIZE_FORMAT " that is not new should be affiliated", r->index()); + assert(r->is_affiliated(), "Region %zu that is not new should be affiliated", r->index()); if (r->affiliation() != req.affiliation()) { assert(_heap->mode()->is_generational(), "Request for %s from %s region should only happen in generational mode.", req.affiliation_name(), r->affiliation_name()); @@ -1060,8 +1063,8 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah req.set_actual_size(adjusted_size); } else { // Otherwise, leave result == nullptr because the adjusted size is smaller than min size. - log_trace(gc, free)("Failed to shrink PLAB request (" SIZE_FORMAT ") in region " SIZE_FORMAT " to " SIZE_FORMAT - " because min_size() is " SIZE_FORMAT, req.size(), r->index(), adjusted_size, req.min_size()); + log_trace(gc, free)("Failed to shrink PLAB request (%zu) in region %zu to %zu" + " because min_size() is %zu", req.size(), r->index(), adjusted_size, req.min_size()); } } else { // This is a GCLAB or a TLAB allocation @@ -1072,11 +1075,11 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah } if (adjusted_size >= req.min_size()) { result = r->allocate(adjusted_size, req); - assert (result != nullptr, "Allocation must succeed: free " SIZE_FORMAT ", actual " SIZE_FORMAT, free, adjusted_size); + assert (result != nullptr, "Allocation must succeed: free %zu, actual %zu", free, adjusted_size); req.set_actual_size(adjusted_size); } else { - log_trace(gc, free)("Failed to shrink TLAB or GCLAB request (" SIZE_FORMAT ") in region " SIZE_FORMAT " to " SIZE_FORMAT - " because min_size() is " SIZE_FORMAT, req.size(), r->index(), adjusted_size, req.min_size()); + log_trace(gc, free)("Failed to shrink TLAB or GCLAB request (%zu) in region %zu to %zu" + " because min_size() is %zu", req.size(), r->index(), adjusted_size, req.min_size()); } } } else { @@ -1292,7 +1295,7 @@ void ShenandoahFreeSet::flip_to_old_gc(ShenandoahHeapRegion* r) { _heap->old_generation()->augment_evacuation_reserve(region_capacity); bool transferred = gen_heap->generation_sizer()->transfer_to_old(1); if (!transferred) { - log_warning(gc, free)("Forcing transfer of " SIZE_FORMAT " to old reserve.", idx); + log_warning(gc, free)("Forcing transfer of %zu to old reserve.", idx); gen_heap->generation_sizer()->force_transfer_to_old(1); } // We do not ensure that the region is no longer trash, relying on try_allocate_in(), which always comes next, @@ -1424,23 +1427,24 @@ void ShenandoahFreeSet::find_regions_with_alloc_capacity(size_t &young_cset_regi } } } - log_debug(gc)(" At end of prep_to_rebuild, mutator_leftmost: " SIZE_FORMAT - ", mutator_rightmost: " SIZE_FORMAT - ", mutator_leftmost_empty: " SIZE_FORMAT - ", mutator_rightmost_empty: " SIZE_FORMAT - ", mutator_regions: " SIZE_FORMAT - ", mutator_used: " SIZE_FORMAT, - mutator_leftmost, mutator_rightmost, mutator_leftmost_empty, mutator_rightmost_empty, - mutator_regions, mutator_used); - - log_debug(gc)(" old_collector_leftmost: " SIZE_FORMAT - ", old_collector_rightmost: " SIZE_FORMAT - ", old_collector_leftmost_empty: " SIZE_FORMAT - ", old_collector_rightmost_empty: " SIZE_FORMAT - ", old_collector_regions: " SIZE_FORMAT - ", old_collector_used: " SIZE_FORMAT, - old_collector_leftmost, old_collector_rightmost, old_collector_leftmost_empty, old_collector_rightmost_empty, - old_collector_regions, old_collector_used); + log_debug(gc, free)(" At end of prep_to_rebuild, mutator_leftmost: %zu" + ", mutator_rightmost: %zu" + ", mutator_leftmost_empty: %zu" + ", mutator_rightmost_empty: %zu" + ", mutator_regions: %zu" + ", mutator_used: %zu", + mutator_leftmost, mutator_rightmost, mutator_leftmost_empty, mutator_rightmost_empty, + mutator_regions, mutator_used); + + log_debug(gc, free)(" old_collector_leftmost: %zu" + ", old_collector_rightmost: %zu" + ", old_collector_leftmost_empty: %zu" + ", old_collector_rightmost_empty: %zu" + ", old_collector_regions: %zu" + ", old_collector_used: %zu", + old_collector_leftmost, old_collector_rightmost, old_collector_leftmost_empty, old_collector_rightmost_empty, + old_collector_regions, old_collector_used); + idx_t rightmost_idx = (mutator_leftmost == max_regions)? -1: (idx_t) mutator_rightmost; idx_t rightmost_empty_idx = (mutator_leftmost_empty == max_regions)? -1: (idx_t) mutator_rightmost_empty; @@ -1450,12 +1454,12 @@ void ShenandoahFreeSet::find_regions_with_alloc_capacity(size_t &young_cset_regi rightmost_empty_idx = (old_collector_leftmost_empty == max_regions)? -1: (idx_t) old_collector_rightmost_empty; _partitions.establish_old_collector_intervals(old_collector_leftmost, rightmost_idx, old_collector_leftmost_empty, rightmost_empty_idx, old_collector_regions, old_collector_used); - log_debug(gc)(" After find_regions_with_alloc_capacity(), Mutator range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]," - " Old Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]", - _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), - _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector)); + log_debug(gc, free)(" After find_regions_with_alloc_capacity(), Mutator range [%zd, %zd]," + " Old Collector range [%zd, %zd]", + _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), + _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector)); } // Returns number of regions transferred, adds transferred bytes to var argument bytes_transferred @@ -1466,7 +1470,6 @@ size_t ShenandoahFreeSet::transfer_empty_regions_from_collector_set_to_mutator_s const size_t region_size_bytes = ShenandoahHeapRegion::region_size_bytes(); size_t transferred_regions = 0; ShenandoahLeftRightIterator iterator(&_partitions, which_collector, true); - idx_t rightmost = _partitions.rightmost_empty(which_collector); for (idx_t idx = iterator.current(); transferred_regions < max_xfer_regions && iterator.has_next(); idx = iterator.next()) { // Note: can_allocate_from() denotes that region is entirely empty if (can_allocate_from(idx)) { @@ -1534,8 +1537,8 @@ void ShenandoahFreeSet::move_regions_from_collector_to_mutator(size_t max_xfer_r } size_t total_xfer = collector_xfer + old_collector_xfer; - log_info(gc, ergo)("At start of update refs, moving " SIZE_FORMAT "%s to Mutator free set from Collector Reserve (" - SIZE_FORMAT "%s) and from Old Collector Reserve (" SIZE_FORMAT "%s)", + log_info(gc, ergo)("At start of update refs, moving %zu%s to Mutator free set from Collector Reserve (" + "%zu%s) and from Old Collector Reserve (%zu%s)", byte_size_in_proper_unit(total_xfer), proper_unit_for_byte_size(total_xfer), byte_size_in_proper_unit(collector_xfer), proper_unit_for_byte_size(collector_xfer), byte_size_in_proper_unit(old_collector_xfer), proper_unit_for_byte_size(old_collector_xfer)); @@ -1571,11 +1574,11 @@ void ShenandoahFreeSet::establish_generation_sizes(size_t young_region_count, si if (new_old_capacity > original_old_capacity) { size_t region_count = (new_old_capacity - original_old_capacity) / region_size_bytes; - log_info(gc, ergo)("Transfer " SIZE_FORMAT " region(s) from %s to %s, yielding increased size: " PROPERFMT, + log_info(gc, ergo)("Transfer %zu region(s) from %s to %s, yielding increased size: " PROPERFMT, region_count, young_gen->name(), old_gen->name(), PROPERFMTARGS(new_old_capacity)); } else if (new_old_capacity < original_old_capacity) { size_t region_count = (original_old_capacity - new_old_capacity) / region_size_bytes; - log_info(gc, ergo)("Transfer " SIZE_FORMAT " region(s) from %s to %s, yielding increased size: " PROPERFMT, + log_info(gc, ergo)("Transfer %zu region(s) from %s to %s, yielding increased size: " PROPERFMT, region_count, old_gen->name(), young_gen->name(), PROPERFMTARGS(new_young_capacity)); } // This balances generations, so clear any pending request to balance. @@ -1653,7 +1656,7 @@ void ShenandoahFreeSet::compute_young_and_old_reserves(size_t young_cset_regions young_reserve_result = young_generation->get_evacuation_reserve(); old_reserve_result = promoted_reserve + old_evac_reserve; assert(old_reserve_result <= old_available, - "Cannot reserve (" SIZE_FORMAT " + " SIZE_FORMAT") more OLD than is available: " SIZE_FORMAT, + "Cannot reserve (%zu + %zu) more OLD than is available: %zu", promoted_reserve, old_evac_reserve, old_available); } else { // We are rebuilding at end of GC, so we set aside budgets specified on command line (or defaults) @@ -1712,13 +1715,14 @@ void ShenandoahFreeSet::reserve_regions(size_t to_reserve, size_t to_reserve_old // OLD regions that have available memory are already in the old_collector free set. _partitions.move_from_partition_to_partition(idx, ShenandoahFreeSetPartitionId::Mutator, ShenandoahFreeSetPartitionId::OldCollector, ac); - log_debug(gc)(" Shifting region " SIZE_FORMAT " from mutator_free to old_collector_free", idx); - log_debug(gc)(" Shifted Mutator range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]," - " Old Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]", - _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), - _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector)); + log_trace(gc, free)(" Shifting region %zu from mutator_free to old_collector_free", idx); + log_trace(gc, free)(" Shifted Mutator range [%zd, %zd]," + " Old Collector range [%zd, %zd]", + _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), + _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector)); + old_region_count++; continue; } @@ -1735,13 +1739,14 @@ void ShenandoahFreeSet::reserve_regions(size_t to_reserve, size_t to_reserve_old // collection set, and they are easily evacuated because they have low density of live objects. _partitions.move_from_partition_to_partition(idx, ShenandoahFreeSetPartitionId::Mutator, ShenandoahFreeSetPartitionId::Collector, ac); - log_debug(gc)(" Shifting region " SIZE_FORMAT " from mutator_free to collector_free", idx); - log_debug(gc)(" Shifted Mutator range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]," - " Collector range [" SSIZE_FORMAT ", " SSIZE_FORMAT "]", - _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.leftmost(ShenandoahFreeSetPartitionId::Collector), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Collector)); + log_trace(gc, free)(" Shifting region %zu from mutator_free to collector_free", idx); + log_trace(gc, free)(" Shifted Mutator range [%zd, %zd]," + " Collector range [%zd, %zd]", + _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.leftmost(ShenandoahFreeSetPartitionId::Collector), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Collector)); + } } @@ -1753,8 +1758,8 @@ void ShenandoahFreeSet::reserve_regions(size_t to_reserve, size_t to_reserve_old } size_t reserve = _partitions.available_in(ShenandoahFreeSetPartitionId::Collector); if (reserve < to_reserve) { - log_debug(gc)("Wanted " PROPERFMT " for young reserve, but only reserved: " PROPERFMT, - PROPERFMTARGS(to_reserve), PROPERFMTARGS(reserve)); + log_info(gc, free)("Wanted " PROPERFMT " for young reserve, but only reserved: " PROPERFMT, + PROPERFMTARGS(to_reserve), PROPERFMTARGS(reserve)); } } } @@ -1805,34 +1810,42 @@ void ShenandoahFreeSet::log_status() { #ifdef ASSERT // Dump of the FreeSet details is only enabled if assertions are enabled - if (LogTarget(Debug, gc, free)::is_enabled()) { + LogTarget(Debug, gc, free) debug_free; + if (debug_free.is_enabled()) { #define BUFFER_SIZE 80 + LogStream ls(debug_free); char buffer[BUFFER_SIZE]; for (uint i = 0; i < BUFFER_SIZE; i++) { buffer[i] = '\0'; } - log_debug(gc)("FreeSet map legend:" - " M:mutator_free C:collector_free O:old_collector_free" - " H:humongous ~:retired old _:retired young"); - log_debug(gc)(" mutator free range [" SIZE_FORMAT ".." SIZE_FORMAT "] allocating from %s, " - " collector free range [" SIZE_FORMAT ".." SIZE_FORMAT "], " - "old collector free range [" SIZE_FORMAT ".." SIZE_FORMAT "] allocates from %s", - _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), - _partitions.alloc_from_left_bias(ShenandoahFreeSetPartitionId::Mutator)? "left to right": "right to left", - _partitions.leftmost(ShenandoahFreeSetPartitionId::Collector), - _partitions.rightmost(ShenandoahFreeSetPartitionId::Collector), - _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), - _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector), - _partitions.alloc_from_left_bias(ShenandoahFreeSetPartitionId::OldCollector)? "left to right": "right to left"); + + ls.cr(); + ls.print_cr("Mutator free range [%zd..%zd] allocating from %s", + _partitions.leftmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Mutator), + _partitions.alloc_from_left_bias(ShenandoahFreeSetPartitionId::Mutator)? "left to right": "right to left"); + + ls.print_cr("Collector free range [%zd..%zd] allocating from %s", + _partitions.leftmost(ShenandoahFreeSetPartitionId::Collector), + _partitions.rightmost(ShenandoahFreeSetPartitionId::Collector), + _partitions.alloc_from_left_bias(ShenandoahFreeSetPartitionId::Collector)? "left to right": "right to left"); + + ls.print_cr("Old collector free range [%zd..%zd] allocates from %s", + _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector), + _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector), + _partitions.alloc_from_left_bias(ShenandoahFreeSetPartitionId::OldCollector)? "left to right": "right to left"); + ls.cr(); + ls.print_cr("FreeSet map legend:"); + ls.print_cr(" M/m:mutator, C/c:collector O/o:old_collector (Empty/Occupied)"); + ls.print_cr(" H/h:humongous, X/x:no alloc capacity, ~/_:retired (Old/Young)"); for (uint i = 0; i < _heap->num_regions(); i++) { ShenandoahHeapRegion *r = _heap->get_region(i); uint idx = i % 64; if ((i != 0) && (idx == 0)) { - log_debug(gc)(" %6u: %s", i-64, buffer); + ls.print_cr(" %6u: %s", i-64, buffer); } if (_partitions.in_free_set(ShenandoahFreeSetPartitionId::Mutator, i)) { size_t capacity = alloc_capacity(r); @@ -1846,17 +1859,11 @@ void ShenandoahFreeSet::log_status() { size_t capacity = alloc_capacity(r); buffer[idx] = (capacity == ShenandoahHeapRegion::region_size_bytes()) ? 'O' : 'o'; } else if (r->is_humongous()) { - if (r->is_old()) { - buffer[idx] = 'H'; - } else { - buffer[idx] = 'h'; - } + buffer[idx] = (r->is_old() ? 'H' : 'h'); + } else if (alloc_capacity(r) == 0) { + buffer[idx] = (r->is_old() ? 'X' : 'x'); } else { - if (r->is_old()) { - buffer[idx] = '~'; - } else { - buffer[idx] = '_'; - } + buffer[idx] = (r->is_old() ? '~' : '_'); } } uint remnant = _heap->num_regions() % 64; @@ -1865,7 +1872,7 @@ void ShenandoahFreeSet::log_status() { } else { remnant = 64; } - log_debug(gc)(" %6u: %s", (uint) (_heap->num_regions() - remnant), buffer); + ls.print_cr(" %6u: %s", (uint) (_heap->num_regions() - remnant), buffer); } #endif @@ -1914,7 +1921,7 @@ void ShenandoahFreeSet::log_status() { // retired, the sum of used and capacities within regions that are still in the Mutator free partition may not match // my internally tracked values of used() and free(). assert(free == total_free, "Free memory should match"); - ls.print("Free: " SIZE_FORMAT "%s, Max: " SIZE_FORMAT "%s regular, " SIZE_FORMAT "%s humongous, ", + ls.print("Free: %zu%s, Max: %zu%s regular, %zu%s humongous, ", byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), byte_size_in_proper_unit(max_humongous), proper_unit_for_byte_size(max_humongous) @@ -1927,7 +1934,7 @@ void ShenandoahFreeSet::log_status() { } else { frag_ext = 0; } - ls.print(SIZE_FORMAT "%% external, ", frag_ext); + ls.print("%zu%% external, ", frag_ext); size_t frag_int; if (_partitions.count(ShenandoahFreeSetPartitionId::Mutator) > 0) { @@ -1936,8 +1943,8 @@ void ShenandoahFreeSet::log_status() { } else { frag_int = 0; } - ls.print(SIZE_FORMAT "%% internal; ", frag_int); - ls.print("Used: " SIZE_FORMAT "%s, Mutator Free: " SIZE_FORMAT, + ls.print("%zu%% internal; ", frag_int); + ls.print("Used: %zu%s, Mutator Free: %zu", byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used), _partitions.count(ShenandoahFreeSetPartitionId::Mutator)); } @@ -1957,7 +1964,7 @@ void ShenandoahFreeSet::log_status() { total_used += r->used(); } } - ls.print(" Collector Reserve: " SIZE_FORMAT "%s, Max: " SIZE_FORMAT "%s; Used: " SIZE_FORMAT "%s", + ls.print(" Collector Reserve: %zu%s, Max: %zu%s; Used: %zu%s", byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used)); @@ -1978,7 +1985,7 @@ void ShenandoahFreeSet::log_status() { total_used += r->used(); } } - ls.print_cr(" Old Collector Reserve: " SIZE_FORMAT "%s, Max: " SIZE_FORMAT "%s; Used: " SIZE_FORMAT "%s", + ls.print_cr(" Old Collector Reserve: %zu%s, Max: %zu%s; Used: %zu%s", byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used)); @@ -1998,7 +2005,7 @@ HeapWord* ShenandoahFreeSet::allocate(ShenandoahAllocRequest& req, bool& in_new_ case ShenandoahAllocRequest::_alloc_gclab: case ShenandoahAllocRequest::_alloc_tlab: in_new_region = false; - assert(false, "Trying to allocate TLAB in humongous region: " SIZE_FORMAT, req.size()); + assert(false, "Trying to allocate TLAB in humongous region: %zu", req.size()); return nullptr; default: ShouldNotReachHere(); @@ -2010,20 +2017,20 @@ HeapWord* ShenandoahFreeSet::allocate(ShenandoahAllocRequest& req, bool& in_new_ } void ShenandoahFreeSet::print_on(outputStream* out) const { - out->print_cr("Mutator Free Set: " SIZE_FORMAT "", _partitions.count(ShenandoahFreeSetPartitionId::Mutator)); + out->print_cr("Mutator Free Set: %zu", _partitions.count(ShenandoahFreeSetPartitionId::Mutator)); ShenandoahLeftRightIterator mutator(const_cast(&_partitions), ShenandoahFreeSetPartitionId::Mutator); for (idx_t index = mutator.current(); mutator.has_next(); index = mutator.next()) { _heap->get_region(index)->print_on(out); } - out->print_cr("Collector Free Set: " SIZE_FORMAT "", _partitions.count(ShenandoahFreeSetPartitionId::Collector)); + out->print_cr("Collector Free Set: %zu", _partitions.count(ShenandoahFreeSetPartitionId::Collector)); ShenandoahLeftRightIterator collector(const_cast(&_partitions), ShenandoahFreeSetPartitionId::Collector); for (idx_t index = collector.current(); collector.has_next(); index = collector.next()) { _heap->get_region(index)->print_on(out); } if (_heap->mode()->is_generational()) { - out->print_cr("Old Collector Free Set: " SIZE_FORMAT "", _partitions.count(ShenandoahFreeSetPartitionId::OldCollector)); + out->print_cr("Old Collector Free Set: %zu", _partitions.count(ShenandoahFreeSetPartitionId::OldCollector)); for (idx_t index = _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector); index <= _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector); index++) { if (_partitions.in_free_set(ShenandoahFreeSetPartitionId::OldCollector, index)) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp index 45b33e5253be5..d475416723672 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp @@ -435,8 +435,12 @@ class ShenandoahFreeSet : public CHeapObj { // Acquire heap lock and log status, assuming heap lock is not acquired by the caller. void log_status_under_lock(); + // Note that capacity is the number of regions that had available memory at most recent rebuild. It is not the + // entire size of the young or global generation. (Regions within the generation that were fully utilized at time of + // rebuild are not counted as part of capacity.) inline size_t capacity() const { return _partitions.capacity_of(ShenandoahFreeSetPartitionId::Mutator); } inline size_t used() const { return _partitions.used_by(ShenandoahFreeSetPartitionId::Mutator); } + inline size_t available() const { assert(used() <= capacity(), "must use less than capacity"); return capacity() - used(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp index 2847d7c78ba18..5f8543ca751e4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/continuationGCSupport.hpp" @@ -119,7 +119,7 @@ void ShenandoahFullGC::op_full(GCCause::Cause cause) { metrics.snap_after(); - if (metrics.is_good_progress()) { + if (metrics.is_good_progress(heap->global_generation())) { heap->notify_gc_progress(); } else { // Nothing to do. Tell the allocation path that we have failed to make @@ -501,7 +501,7 @@ void ShenandoahFullGC::calculate_target_humongous_objects() { size_t to_begin = heap->num_regions(); size_t to_end = heap->num_regions(); - log_debug(gc)("Full GC calculating target humongous objects from end " SIZE_FORMAT, to_end); + log_debug(gc)("Full GC calculating target humongous objects from end %zu", to_end); for (size_t c = heap->num_regions(); c > 0; c--) { ShenandoahHeapRegion *r = heap->get_region(c - 1); if (r->is_humongous_continuation() || (r->new_top() == r->bottom())) { @@ -550,7 +550,7 @@ class ShenandoahEnsureHeapActiveClosure: public ShenandoahHeapRegionClosure { if (r->is_empty_uncommitted()) { r->make_committed_bypass(); } - assert (r->is_committed(), "only committed regions in heap now, see region " SIZE_FORMAT, r->index()); + assert (r->is_committed(), "only committed regions in heap now, see region %zu", r->index()); // Record current region occupancy: this communicates empty regions are free // to the rest of Full GC code. @@ -572,14 +572,14 @@ class ShenandoahTrashImmediateGarbageClosure: public ShenandoahHeapRegionClosure if (r->is_humongous_start()) { oop humongous_obj = cast_to_oop(r->bottom()); if (!_ctx->is_marked(humongous_obj)) { - assert(!r->has_live(), "Region " SIZE_FORMAT " is not marked, should not have live", r->index()); + assert(!r->has_live(), "Region %zu is not marked, should not have live", r->index()); _heap->trash_humongous_region_at(r); } else { - assert(r->has_live(), "Region " SIZE_FORMAT " should have live", r->index()); + assert(r->has_live(), "Region %zu should have live", r->index()); } } else if (r->is_humongous_continuation()) { // If we hit continuation, the non-live humongous starts should have been trashed already - assert(r->humongous_start_region()->has_live(), "Region " SIZE_FORMAT " should have live", r->index()); + assert(r->humongous_start_region()->has_live(), "Region %zu should have live", r->index()); } else if (r->is_regular()) { if (!r->has_live()) { r->make_trash_immediate(); @@ -715,8 +715,8 @@ void ShenandoahFullGC::distribute_slices(ShenandoahHeapRegionSet** worker_slices ShenandoahHeapRegion* r = it.next(); while (r != nullptr) { size_t idx = r->index(); - assert(ShenandoahPrepareForCompactionTask::is_candidate_region(r), "Sanity: " SIZE_FORMAT, idx); - assert(!map.at(idx), "No region distributed twice: " SIZE_FORMAT, idx); + assert(ShenandoahPrepareForCompactionTask::is_candidate_region(r), "Sanity: %zu", idx); + assert(!map.at(idx), "No region distributed twice: %zu", idx); map.at_put(idx, true); r = it.next(); } @@ -725,7 +725,7 @@ void ShenandoahFullGC::distribute_slices(ShenandoahHeapRegionSet** worker_slices for (size_t rid = 0; rid < n_regions; rid++) { bool is_candidate = ShenandoahPrepareForCompactionTask::is_candidate_region(heap->get_region(rid)); bool is_distributed = map.at(rid); - assert(is_distributed || !is_candidate, "All candidates are distributed: " SIZE_FORMAT, rid); + assert(is_distributed || !is_candidate, "All candidates are distributed: %zu", rid); } #endif } @@ -1045,9 +1045,9 @@ void ShenandoahFullGC::compact_humongous_objects() { size_t new_start = heap->heap_region_index_containing(FullGCForwarding::forwardee(old_obj)); size_t new_end = new_start + num_regions - 1; assert(old_start != new_start, "must be real move"); - assert(r->is_stw_move_allowed(), "Region " SIZE_FORMAT " should be movable", r->index()); + assert(r->is_stw_move_allowed(), "Region %zu should be movable", r->index()); - log_debug(gc)("Full GC compaction moves humongous object from region " SIZE_FORMAT " to region " SIZE_FORMAT, old_start, new_start); + log_debug(gc)("Full GC compaction moves humongous object from region %zu to region %zu", old_start, new_start); Copy::aligned_conjoint_words(r->bottom(), heap->get_region(new_start)->bottom(), words_size); ContinuationGCSupport::relativize_stack_chunk(cast_to_oop(r->bottom())); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGC.cpp index 99ee88d98d126..5a1e8b67694d7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGC.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/workerThread.hpp" @@ -45,7 +44,7 @@ const char* ShenandoahGC::degen_point_to_string(ShenandoahDegenPoint point) { return "Mark"; case _degenerated_evac: return "Evacuation"; - case _degenerated_updaterefs: + case _degenerated_update_refs: return "Update References"; default: ShouldNotReachHere(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGC.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGC.hpp index 37b228489177c..f10d5eef969da 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGC.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGC.hpp @@ -53,7 +53,7 @@ class ShenandoahGC : public StackObj { _degenerated_roots, _degenerated_mark, _degenerated_evac, - _degenerated_updaterefs, + _degenerated_update_refs, _DEGENERATED_LIMIT }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp index 2bebac05f158f..d00d5168ee7c3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahCollectionSetPreselector.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" @@ -205,21 +205,24 @@ void ShenandoahGeneration::log_status(const char *msg) const { // Not under a lock here, so read each of these once to make sure // byte size in proper unit and proper unit for byte size are consistent. - size_t v_used = used(); - size_t v_used_regions = used_regions_size(); - size_t v_soft_max_capacity = soft_max_capacity(); - size_t v_max_capacity = max_capacity(); - size_t v_available = available(); - size_t v_humongous_waste = get_humongous_waste(); - LogGcInfo::print("%s: %s generation used: " SIZE_FORMAT "%s, used regions: " SIZE_FORMAT "%s, " - "humongous waste: " SIZE_FORMAT "%s, soft capacity: " SIZE_FORMAT "%s, max capacity: " SIZE_FORMAT "%s, " - "available: " SIZE_FORMAT "%s", msg, name(), - byte_size_in_proper_unit(v_used), proper_unit_for_byte_size(v_used), - byte_size_in_proper_unit(v_used_regions), proper_unit_for_byte_size(v_used_regions), - byte_size_in_proper_unit(v_humongous_waste), proper_unit_for_byte_size(v_humongous_waste), - byte_size_in_proper_unit(v_soft_max_capacity), proper_unit_for_byte_size(v_soft_max_capacity), - byte_size_in_proper_unit(v_max_capacity), proper_unit_for_byte_size(v_max_capacity), - byte_size_in_proper_unit(v_available), proper_unit_for_byte_size(v_available)); + const size_t v_used = used(); + const size_t v_used_regions = used_regions_size(); + const size_t v_soft_max_capacity = soft_max_capacity(); + const size_t v_max_capacity = max_capacity(); + const size_t v_available = available(); + const size_t v_humongous_waste = get_humongous_waste(); + + const LogGcInfo target; + LogStream ls(target); + ls.print("%s: ", msg); + if (_type != NON_GEN) { + ls.print("%s generation ", name()); + } + + ls.print_cr("used: " PROPERFMT ", used regions: " PROPERFMT ", humongous waste: " PROPERFMT + ", soft capacity: " PROPERFMT ", max capacity: " PROPERFMT ", available: " PROPERFMT, + PROPERFMTARGS(v_used), PROPERFMTARGS(v_used_regions), PROPERFMTARGS(v_humongous_waste), + PROPERFMTARGS(v_soft_max_capacity), PROPERFMTARGS(v_max_capacity), PROPERFMTARGS(v_available)); } void ShenandoahGeneration::reset_mark_bitmap() { @@ -416,7 +419,7 @@ void ShenandoahGeneration::adjust_evacuation_budgets(ShenandoahHeap* const heap, if (old_evacuated_committed > old_evacuation_reserve) { // This should only happen due to round-off errors when enforcing ShenandoahOldEvacWaste assert(old_evacuated_committed <= (33 * old_evacuation_reserve) / 32, - "Round-off errors should be less than 3.125%%, committed: " SIZE_FORMAT ", reserved: " SIZE_FORMAT, + "Round-off errors should be less than 3.125%%, committed: %zu, reserved: %zu", old_evacuated_committed, old_evacuation_reserve); old_evacuated_committed = old_evacuation_reserve; // Leave old_evac_reserve as previously configured @@ -446,13 +449,13 @@ void ShenandoahGeneration::adjust_evacuation_budgets(ShenandoahHeap* const heap, // This can happen due to round-off errors when adding the results of truncated integer arithmetic. // We've already truncated old_evacuated_committed. Truncate young_advance_promoted_reserve_used here. assert(young_advance_promoted_reserve_used <= (33 * (old_available - old_evacuated_committed)) / 32, - "Round-off errors should be less than 3.125%%, committed: " SIZE_FORMAT ", reserved: " SIZE_FORMAT, + "Round-off errors should be less than 3.125%%, committed: %zu, reserved: %zu", young_advance_promoted_reserve_used, old_available - old_evacuated_committed); young_advance_promoted_reserve_used = old_available - old_evacuated_committed; old_consumed = old_evacuated_committed + young_advance_promoted_reserve_used; } - assert(old_available >= old_consumed, "Cannot consume (" SIZE_FORMAT ") more than is available (" SIZE_FORMAT ")", + assert(old_available >= old_consumed, "Cannot consume (%zu) more than is available (%zu)", old_consumed, old_available); size_t excess_old = old_available - old_consumed; size_t unaffiliated_old_regions = old_generation->free_unaffiliated_regions(); @@ -491,10 +494,10 @@ void ShenandoahGeneration::adjust_evacuation_budgets(ShenandoahHeap* const heap, if (regions_to_xfer > 0) { bool result = ShenandoahGenerationalHeap::cast(heap)->generation_sizer()->transfer_to_young(regions_to_xfer); assert(excess_old >= regions_to_xfer * region_size_bytes, - "Cannot transfer (" SIZE_FORMAT ", " SIZE_FORMAT ") more than excess old (" SIZE_FORMAT ")", + "Cannot transfer (%zu, %zu) more than excess old (%zu)", regions_to_xfer, region_size_bytes, excess_old); excess_old -= regions_to_xfer * region_size_bytes; - log_debug(gc, ergo)("%s transferred " SIZE_FORMAT " excess regions to young before start of evacuation", + log_debug(gc, ergo)("%s transferred %zu excess regions to young before start of evacuation", result? "Successfully": "Unsuccessfully", regions_to_xfer); } @@ -524,7 +527,7 @@ inline void assert_no_in_place_promotions() { public: void heap_region_do(ShenandoahHeapRegion *r) override { assert(r->get_top_before_promote() == nullptr, - "Region " SIZE_FORMAT " should not be ready for in-place promotion", r->index()); + "Region %zu should not be ready for in-place promotion", r->index()); } } cl; ShenandoahHeap::heap()->heap_region_iterate(&cl); @@ -668,8 +671,8 @@ size_t ShenandoahGeneration::select_aged_regions(size_t old_available) { // We keep going even if one region is excluded from selection because we need to accumulate all eligible // regions that are not preselected into promo_potential } - log_debug(gc)("Preselected " SIZE_FORMAT " regions containing " SIZE_FORMAT " live bytes," - " consuming: " SIZE_FORMAT " of budgeted: " SIZE_FORMAT, + log_debug(gc)("Preselected %zu regions containing %zu live bytes," + " consuming: %zu of budgeted: %zu", selected_regions, selected_live, old_consumed, old_available); } @@ -721,7 +724,7 @@ void ShenandoahGeneration::prepare_regions_and_collection_set(bool concurrent) { // We use integer division so anything up to just less than 2 is considered // reasonable, and the "+1" is to avoid divide-by-zero. assert((total_pop+1)/(total_census+1) == 1, "Extreme divergence: " - SIZE_FORMAT "/" SIZE_FORMAT, total_pop, total_census); + "%zu/%zu", total_pop, total_census); #endif } @@ -938,7 +941,7 @@ void ShenandoahGeneration::increase_humongous_waste(size_t bytes) { void ShenandoahGeneration::decrease_humongous_waste(size_t bytes) { if (bytes > 0) { assert(ShenandoahHeap::heap()->is_full_gc_in_progress() || (_humongous_waste >= bytes), - "Waste (" SIZE_FORMAT ") cannot be negative (after subtracting " SIZE_FORMAT ")", _humongous_waste, bytes); + "Waste (%zu) cannot be negative (after subtracting %zu)", _humongous_waste, bytes); Atomic::sub(&_humongous_waste, bytes); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationSizer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationSizer.cpp index dfbc6b673ffab..c6827878cd1f2 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationSizer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationSizer.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/shenandoahGeneration.hpp" #include "gc/shenandoah/shenandoahGenerationSizer.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -51,8 +50,8 @@ ShenandoahGenerationSizer::ShenandoahGenerationSizer() if (NewSize > MaxNewSize) { if (FLAG_IS_CMDLINE(MaxNewSize)) { - log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " - "A new max generation size of " SIZE_FORMAT "k will be used.", + log_warning(gc, ergo)("NewSize (%zuk) is greater than the MaxNewSize (%zuk). " + "A new max generation size of %zuk will be used.", NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(MaxNewSize, NewSize); @@ -138,7 +137,7 @@ bool ShenandoahGenerationSizer::transfer_regions(ShenandoahGeneration* src, Shen src->decrease_capacity(bytes_to_transfer); dst->increase_capacity(bytes_to_transfer); const size_t new_size = dst->max_capacity(); - log_info(gc, ergo)("Transfer " SIZE_FORMAT " region(s) from %s to %s, yielding increased size: " PROPERFMT, + log_info(gc, ergo)("Transfer %zu region(s) from %s to %s, yielding increased size: " PROPERFMT, regions, src->name(), dst->name(), PROPERFMTARGS(new_size)); return true; } @@ -190,7 +189,7 @@ void ShenandoahGenerationSizer::force_transfer_to_old(size_t regions) const { young_gen->decrease_capacity(bytes_to_transfer); old_gen->increase_capacity(bytes_to_transfer); const size_t new_size = old_gen->max_capacity(); - log_info(gc, ergo)("Forcing transfer of " SIZE_FORMAT " region(s) from %s to %s, yielding increased size: " PROPERFMT, + log_info(gc, ergo)("Forcing transfer of %zu region(s) from %s to %s, yielding increased size: " PROPERFMT, regions, young_gen->name(), old_gen->name(), PROPERFMTARGS(new_size)); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index 33af35c6b9555..db4b517a1f50b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/mode/shenandoahMode.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -318,6 +317,8 @@ void ShenandoahGenerationalControlThread::run_service() { } } + set_gc_mode(stopped); + // Wait for the actual stop(), can't leave run_service() earlier. while (!should_terminate()) { os::naked_short_sleep(ShenandoahControlIntervalMin); @@ -813,6 +814,7 @@ const char* ShenandoahGenerationalControlThread::gc_mode_name(ShenandoahGenerati case stw_full: return "full"; case servicing_old: return "old"; case bootstrapping_old: return "bootstrap"; + case stopped: return "stopped"; default: return "unknown"; } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp index 295882fe6d91f..46072b982550b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp @@ -48,7 +48,8 @@ class ShenandoahGenerationalControlThread: public ShenandoahController { stw_degenerated, stw_full, bootstrapping_old, - servicing_old + servicing_old, + stopped } GCMode; private: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp index 9dcdf002b7e8c..5672463799af4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahGenerationalEvacuationTask.hpp" @@ -89,7 +88,7 @@ void ShenandoahGenerationalEvacuationTask::do_work() { } void log_region(const ShenandoahHeapRegion* r, LogStream* ls) { - ls->print_cr("GenerationalEvacuationTask, looking at %s region " SIZE_FORMAT ", (age: %d) [%s, %s, %s]", + ls->print_cr("GenerationalEvacuationTask, looking at %s region %zu, (age: %d) [%s, %s, %s]", r->is_old()? "old": r->is_young()? "young": "free", r->index(), r->age(), r->is_active()? "active": "inactive", r->is_humongous()? (r->is_humongous_start()? "humongous_start": "humongous_continuation"): "regular", @@ -126,7 +125,7 @@ void ShenandoahGenerationalEvacuationTask::evacuate_and_promote_regions() { } if (r->is_cset()) { - assert(r->has_live(), "Region " SIZE_FORMAT " should have been reclaimed early", r->index()); + assert(r->has_live(), "Region %zu should have been reclaimed early", r->index()); _heap->marked_object_iterate(r, &cl); if (ShenandoahPacing) { _heap->pacer()->report_evac(r->used() >> LogHeapWordSize); @@ -177,11 +176,11 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion const size_t old_garbage_threshold = (ShenandoahHeapRegion::region_size_bytes() * ShenandoahOldGarbageThreshold) / 100; shenandoah_assert_generations_reconciled(); assert(!_heap->is_concurrent_old_mark_in_progress(), "Cannot promote in place during old marking"); - assert(region->garbage_before_padded_for_promote() < old_garbage_threshold, "Region " SIZE_FORMAT " has too much garbage for promotion", region->index()); + assert(region->garbage_before_padded_for_promote() < old_garbage_threshold, "Region %zu has too much garbage for promotion", region->index()); assert(region->is_young(), "Only young regions can be promoted"); assert(region->is_regular(), "Use different service to promote humongous regions"); assert(region->age() >= _tenuring_threshold, "Only promote regions that are sufficiently aged"); - assert(region->get_top_before_promote() == tams, "Region " SIZE_FORMAT " has been used for allocations before promotion", region->index()); + assert(region->get_top_before_promote() == tams, "Region %zu has been used for allocations before promotion", region->index()); } ShenandoahOldGeneration* const old_gen = _heap->old_generation(); @@ -280,7 +279,7 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio // We promote humongous objects unconditionally, without checking for availability. We adjust // usage totals, including humongous waste, after evacuation is done. - log_debug(gc)("promoting humongous region " SIZE_FORMAT ", spanning " SIZE_FORMAT, region->index(), spanned_regions); + log_debug(gc)("promoting humongous region %zu, spanning %zu", region->index(), spanned_regions); young_gen->decrease_used(used_bytes); young_gen->decrease_humongous_waste(humongous_waste); @@ -294,7 +293,7 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio // in the last humongous region that is not spanned by obj is currently not used. for (size_t i = region->index(); i < index_limit; i++) { ShenandoahHeapRegion* r = _heap->get_region(i); - log_debug(gc)("promoting humongous region " SIZE_FORMAT ", from " PTR_FORMAT " to " PTR_FORMAT, + log_debug(gc)("promoting humongous region %zu, from " PTR_FORMAT " to " PTR_FORMAT, r->index(), p2i(r->bottom()), p2i(r->top())); // We mark the entire humongous object's range as dirty after loop terminates, so no need to dirty the range here r->set_affiliation(OLD_GENERATION); @@ -314,13 +313,12 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio if (obj->is_typeArray()) { // Primitive arrays don't need to be scanned. - log_debug(gc)("Clean cards for promoted humongous object (Region " SIZE_FORMAT ") from " PTR_FORMAT " to " PTR_FORMAT, + log_debug(gc)("Clean cards for promoted humongous object (Region %zu) from " PTR_FORMAT " to " PTR_FORMAT, region->index(), p2i(humongous_bottom), p2i(humongous_bottom + obj->size())); scanner->mark_range_as_clean(humongous_bottom, obj->size()); } else { - log_debug(gc)("Dirty cards for promoted humongous object (Region " SIZE_FORMAT ") from " PTR_FORMAT " to " PTR_FORMAT, + log_debug(gc)("Dirty cards for promoted humongous object (Region %zu) from " PTR_FORMAT " to " PTR_FORMAT, region->index(), p2i(humongous_bottom), p2i(humongous_bottom + obj->size())); scanner->mark_range_as_dirty(humongous_bottom, obj->size()); } } - diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp index fe38c996bd81c..a54f219faefc3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +23,6 @@ * */ - -#include "precompiled.hpp" - #include "gc/shared/fullGCForwarding.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shenandoah/shenandoahGenerationalFullGC.hpp" @@ -219,7 +217,7 @@ ShenandoahPrepareForGenerationalCompactionObjectClosure::ShenandoahPrepareForGen } void ShenandoahPrepareForGenerationalCompactionObjectClosure::set_from_region(ShenandoahHeapRegion* from_region) { - log_debug(gc)("Worker %u compacting %s Region " SIZE_FORMAT " which had used " SIZE_FORMAT " and %s live", + log_debug(gc)("Worker %u compacting %s Region %zu which had used %zu and %s live", _worker_id, from_region->affiliation_name(), from_region->index(), from_region->used(), from_region->has_live()? "has": "does not have"); @@ -248,7 +246,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::finish() { void ShenandoahPrepareForGenerationalCompactionObjectClosure::finish_old_region() { if (_old_to_region != nullptr) { - log_debug(gc)("Planned compaction into Old Region " SIZE_FORMAT ", used: " SIZE_FORMAT " tabulated by worker %u", + log_debug(gc)("Planned compaction into Old Region %zu, used: %zu tabulated by worker %u", _old_to_region->index(), _old_compact_point - _old_to_region->bottom(), _worker_id); _old_to_region->set_new_top(_old_compact_point); _old_to_region = nullptr; @@ -257,7 +255,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::finish_old_region( void ShenandoahPrepareForGenerationalCompactionObjectClosure::finish_young_region() { if (_young_to_region != nullptr) { - log_debug(gc)("Worker %u planned compaction into Young Region " SIZE_FORMAT ", used: " SIZE_FORMAT, + log_debug(gc)("Worker %u planned compaction into Young Region %zu, used: %zu", _worker_id, _young_to_region->index(), _young_compact_point - _young_to_region->bottom()); _young_to_region->set_new_top(_young_compact_point); _young_to_region = nullptr; @@ -307,7 +305,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::do_object(oop p) { if (_old_compact_point + obj_size > _old_to_region->end()) { ShenandoahHeapRegion* new_to_region; - log_debug(gc)("Worker %u finishing old region " SIZE_FORMAT ", compact_point: " PTR_FORMAT ", obj_size: " SIZE_FORMAT + log_debug(gc)("Worker %u finishing old region %zu, compact_point: " PTR_FORMAT ", obj_size: %zu" ", &compact_point[obj_size]: " PTR_FORMAT ", region end: " PTR_FORMAT, _worker_id, _old_to_region->index(), p2i(_old_compact_point), obj_size, p2i(_old_compact_point + obj_size), p2i(_old_to_region->end())); @@ -354,7 +352,7 @@ void ShenandoahPrepareForGenerationalCompactionObjectClosure::do_object(oop p) { if (_young_compact_point + obj_size > _young_to_region->end()) { ShenandoahHeapRegion* new_to_region; - log_debug(gc)("Worker %u finishing young region " SIZE_FORMAT ", compact_point: " PTR_FORMAT ", obj_size: " SIZE_FORMAT + log_debug(gc)("Worker %u finishing young region %zu, compact_point: " PTR_FORMAT ", obj_size: %zu" ", &compact_point[obj_size]: " PTR_FORMAT ", region end: " PTR_FORMAT, _worker_id, _young_to_region->index(), p2i(_young_compact_point), obj_size, p2i(_young_compact_point + obj_size), p2i(_young_to_region->end())); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp index 2ad35fcb288b4..09b985e3b8d55 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" @@ -460,20 +459,20 @@ HeapWord* ShenandoahGenerationalHeap::allocate_from_plab_slow(Thread* thread, si size_t future_size = MIN2(cur_size * 2, plab_max_size()); // Doubling, starting at a card-multiple, should give us a card-multiple. (Ceiling and floor // are card multiples.) - assert(is_aligned(future_size, CardTable::card_size_in_words()), "Card multiple by construction, future_size: " SIZE_FORMAT - ", card_size: " SIZE_FORMAT ", cur_size: " SIZE_FORMAT ", max: " SIZE_FORMAT, + assert(is_aligned(future_size, CardTable::card_size_in_words()), "Card multiple by construction, future_size: %zu" + ", card_size: %zu, cur_size: %zu, max: %zu", future_size, (size_t) CardTable::card_size_in_words(), cur_size, plab_max_size()); // Record new heuristic value even if we take any shortcut. This captures // the case when moderately-sized objects always take a shortcut. At some point, // heuristics should catch up with them. Note that the requested cur_size may // not be honored, but we remember that this is the preferred size. - log_debug(gc, free)("Set new PLAB size: " SIZE_FORMAT, future_size); + log_debug(gc, free)("Set new PLAB size: %zu", future_size); ShenandoahThreadLocalData::set_plab_size(thread, future_size); if (cur_size < size) { // The PLAB to be allocated is still not large enough to hold the object. Fall back to shared allocation. // This avoids retiring perfectly good PLABs in order to represent a single large object allocation. - log_debug(gc, free)("Current PLAB size (" SIZE_FORMAT ") is too small for " SIZE_FORMAT, cur_size, size); + log_debug(gc, free)("Current PLAB size (%zu) is too small for %zu", cur_size, size); return nullptr; } @@ -570,7 +569,7 @@ void ShenandoahGenerationalHeap::retire_plab(PLAB* plab, Thread* thread) { if (top != nullptr && plab->waste() > original_waste && is_in_old(top)) { // If retiring the plab created a filler object, then we need to register it with our card scanner so it can // safely walk the region backing the plab. - log_debug(gc)("retire_plab() is registering remnant of size " SIZE_FORMAT " at " PTR_FORMAT, + log_debug(gc)("retire_plab() is registering remnant of size %zu at " PTR_FORMAT, plab->waste() - original_waste, p2i(top)); // No lock is necessary because the PLAB memory is aligned on card boundaries. old_generation()->card_scan()->register_object_without_lock(top); @@ -714,7 +713,7 @@ void ShenandoahGenerationalHeap::TransferResult::print_on(const char* when, outp ShenandoahOldGeneration* const old_gen = heap->old_generation(); const size_t young_available = young_gen->available(); const size_t old_available = old_gen->available(); - ss->print_cr("After %s, %s " SIZE_FORMAT " regions to %s to prepare for next gc, old available: " + ss->print_cr("After %s, %s %zu regions to %s to prepare for next gc, old available: " PROPERFMT ", young_available: " PROPERFMT, when, success? "successfully transferred": "failed to transfer", region_count, region_destination, @@ -819,7 +818,7 @@ class ShenandoahGenerationalUpdateHeapRefsTask : public WorkerTask { HeapWord* update_watermark = r->get_update_watermark(); assert(update_watermark >= r->bottom(), "sanity"); - log_debug(gc)("Update refs worker " UINT32_FORMAT ", looking at region " SIZE_FORMAT, worker_id, r->index()); + log_debug(gc)("Update refs worker " UINT32_FORMAT ", looking at region %zu", worker_id, r->index()); bool region_progress = false; if (r->is_active() && !r->is_cset()) { if (r->is_young()) { @@ -845,13 +844,13 @@ class ShenandoahGenerationalUpdateHeapRefsTask : public WorkerTask { // updated. assert(r->get_update_watermark() == r->bottom(), - "%s Region " SIZE_FORMAT " is_active but not recognized as YOUNG or OLD so must be newly transitioned from FREE", + "%s Region %zu is_active but not recognized as YOUNG or OLD so must be newly transitioned from FREE", r->affiliation_name(), r->index()); } } if (region_progress && ShenandoahPacing) { - _heap->pacer()->report_updaterefs(pointer_delta(update_watermark, r->bottom())); + _heap->pacer()->report_update_refs(pointer_delta(update_watermark, r->bottom())); } if (_heap->check_cancelled_gc_and_yield(CONCURRENT)) { @@ -911,7 +910,7 @@ class ShenandoahGenerationalUpdateHeapRefsTask : public WorkerTask { } if (ShenandoahPacing) { - _heap->pacer()->report_updaterefs(pointer_delta(end_of_range, start_of_range)); + _heap->pacer()->report_update_refs(pointer_delta(end_of_range, start_of_range)); } } } @@ -1071,7 +1070,7 @@ void ShenandoahGenerationalHeap::complete_degenerated_cycle() { shenandoah_assert_heaplocked_or_safepoint(); if (is_concurrent_old_mark_in_progress()) { // This is still necessary for degenerated cycles because the degeneration point may occur - // after final mark of the young generation. See ShenandoahConcurrentGC::op_final_updaterefs for + // after final mark of the young generation. See ShenandoahConcurrentGC::op_final_update_refs for // a more detailed explanation. old_generation()->transfer_pointers_from_satb(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp index 9b13c7c95af78..230fff162527b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/heuristics/shenandoahGlobalHeuristics.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index cdcc5dbd267f1..68b83cbf75a87 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2022, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,11 +24,9 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapWriter.hpp" #include "classfile/systemDictionary.hpp" -#include "code/codeCache.hpp" #include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/fullGCForwarding.hpp" @@ -86,9 +84,10 @@ #include "gc/shenandoah/shenandoahJfrSupport.hpp" #endif - +#include "memory/allocation.hpp" #include "memory/allocation.hpp" #include "memory/classLoaderMetaspace.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspaceUtils.hpp" #include "memory/universe.hpp" #include "nmt/mallocTracker.hpp" @@ -102,6 +101,7 @@ #include "runtime/orderAccess.hpp" #include "runtime/safepointMechanism.hpp" #include "runtime/stackWatermarkSet.hpp" +#include "runtime/threads.hpp" #include "runtime/vmThread.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/events.hpp" @@ -145,7 +145,7 @@ class ShenandoahPretouchBitmapTask : public WorkerTask { while (r != nullptr) { size_t start = r->index() * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); size_t end = (r->index() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); - assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); + assert (end <= _bitmap_size, "end is sane: %zu < %zu", end, _bitmap_size); if (r->is_committed()) { os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _page_size); @@ -156,6 +156,23 @@ class ShenandoahPretouchBitmapTask : public WorkerTask { } }; +static ReservedSpace reserve(size_t size, size_t preferred_page_size) { + // When a page size is given we don't want to mix large + // and normal pages. If the size is not a multiple of the + // page size it will be aligned up to achieve this. + size_t alignment = os::vm_allocation_granularity(); + if (preferred_page_size != os::vm_page_size()) { + alignment = MAX2(preferred_page_size, alignment); + size = align_up(size, alignment); + } + + const ReservedSpace reserved = MemoryReserver::reserve(size, alignment, preferred_page_size); + if (!reserved.is_reserved()) { + vm_exit_during_initialization("Could not reserve space"); + } + return reserved; +} + jint ShenandoahHeap::initialize() { // // Figure out heap sizing @@ -173,7 +190,7 @@ jint ShenandoahHeap::initialize() { _num_regions = ShenandoahHeapRegion::region_count(); assert(_num_regions == (max_byte_size / reg_size_bytes), - "Regions should cover entire heap exactly: " SIZE_FORMAT " != " SIZE_FORMAT "/" SIZE_FORMAT, + "Regions should cover entire heap exactly: %zu != %zu/%zu", _num_regions, max_byte_size, reg_size_bytes); size_t num_committed_regions = init_byte_size / reg_size_bytes; @@ -263,7 +280,7 @@ jint ShenandoahHeap::initialize() { guarantee(bitmap_bytes_per_region != 0, "Bitmap bytes per region should not be zero"); guarantee(is_power_of_2(bitmap_bytes_per_region), - "Bitmap bytes per region should be power of two: " SIZE_FORMAT, bitmap_bytes_per_region); + "Bitmap bytes per region should be power of two: %zu", bitmap_bytes_per_region); if (bitmap_page_size > bitmap_bytes_per_region) { _bitmap_regions_per_slice = bitmap_page_size / bitmap_bytes_per_region; @@ -274,14 +291,14 @@ jint ShenandoahHeap::initialize() { } guarantee(_bitmap_regions_per_slice >= 1, - "Should have at least one region per slice: " SIZE_FORMAT, + "Should have at least one region per slice: %zu", _bitmap_regions_per_slice); guarantee(((_bitmap_bytes_per_slice) % bitmap_page_size) == 0, - "Bitmap slices should be page-granular: bps = " SIZE_FORMAT ", page size = " SIZE_FORMAT, + "Bitmap slices should be page-granular: bps = %zu, page size = %zu", _bitmap_bytes_per_slice, bitmap_page_size); - ReservedSpace bitmap(_bitmap_size, bitmap_page_size); + ReservedSpace bitmap = reserve(_bitmap_size, bitmap_page_size); os::trace_page_sizes_for_requested_size("Mark Bitmap", bitmap_size_orig, bitmap_page_size, bitmap.base(), @@ -301,7 +318,7 @@ jint ShenandoahHeap::initialize() { _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); if (ShenandoahVerify) { - ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); + ReservedSpace verify_bitmap = reserve(_bitmap_size, bitmap_page_size); os::trace_page_sizes_for_requested_size("Verify Bitmap", bitmap_size_orig, bitmap_page_size, verify_bitmap.base(), @@ -319,7 +336,7 @@ jint ShenandoahHeap::initialize() { // Reserve aux bitmap for use in object_iterate(). We don't commit it here. size_t aux_bitmap_page_size = bitmap_page_size; - ReservedSpace aux_bitmap(_bitmap_size, aux_bitmap_page_size); + ReservedSpace aux_bitmap = reserve(_bitmap_size, aux_bitmap_page_size); os::trace_page_sizes_for_requested_size("Aux Bitmap", bitmap_size_orig, aux_bitmap_page_size, aux_bitmap.base(), @@ -337,7 +354,7 @@ jint ShenandoahHeap::initialize() { size_t region_storage_size = align_up(region_storage_size_orig, MAX2(region_page_size, os::vm_allocation_granularity())); - ReservedSpace region_storage(region_storage_size, region_page_size); + ReservedSpace region_storage = reserve(region_storage_size, region_page_size); os::trace_page_sizes_for_requested_size("Region Storage", region_storage_size_orig, region_page_size, region_storage.base(), @@ -363,7 +380,7 @@ jint ShenandoahHeap::initialize() { for (uintptr_t addr = min; addr <= max; addr <<= 1u) { char* req_addr = (char*)addr; assert(is_aligned(req_addr, cset_align), "Should be aligned"); - cset_rs = ReservedSpace(cset_size, cset_align, cset_page_size, req_addr); + cset_rs = MemoryReserver::reserve(req_addr, cset_size, cset_align, cset_page_size); if (cset_rs.is_reserved()) { assert(cset_rs.base() == req_addr, "Allocated where requested: " PTR_FORMAT ", " PTR_FORMAT, p2i(cset_rs.base()), addr); _collection_set = new ShenandoahCollectionSet(this, cset_rs, sh_rs.base()); @@ -372,7 +389,11 @@ jint ShenandoahHeap::initialize() { } if (_collection_set == nullptr) { - cset_rs = ReservedSpace(cset_size, cset_align, os::vm_page_size()); + cset_rs = MemoryReserver::reserve(cset_size, cset_align, os::vm_page_size()); + if (!cset_rs.is_reserved()) { + vm_exit_during_initialization("Cannot reserve memory for collection set"); + } + _collection_set = new ShenandoahCollectionSet(this, cset_rs, sh_rs.base()); } os::trace_page_sizes_for_requested_size("Collection Set", @@ -570,12 +591,12 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : void ShenandoahHeap::print_on(outputStream* st) const { st->print_cr("Shenandoah Heap"); - st->print_cr(" " SIZE_FORMAT "%s max, " SIZE_FORMAT "%s soft max, " SIZE_FORMAT "%s committed, " SIZE_FORMAT "%s used", + st->print_cr(" %zu%s max, %zu%s soft max, %zu%s committed, %zu%s used", byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity()), byte_size_in_proper_unit(soft_max_capacity()), proper_unit_for_byte_size(soft_max_capacity()), byte_size_in_proper_unit(committed()), proper_unit_for_byte_size(committed()), byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); - st->print_cr(" " SIZE_FORMAT " x " SIZE_FORMAT"%s regions", + st->print_cr(" %zu x %zu %s regions", num_regions(), byte_size_in_proper_unit(ShenandoahHeapRegion::region_size_bytes()), proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes())); @@ -631,7 +652,6 @@ class ShenandoahInitWorkerGCLABClosure : public ThreadClosure { public: void do_thread(Thread* thread) { assert(thread != nullptr, "Sanity"); - assert(thread->is_Worker_thread(), "Only worker thread expected"); ShenandoahThreadLocalData::initialize_gclab(thread); } }; @@ -650,6 +670,9 @@ void ShenandoahHeap::post_initialize() { // gclab can not be initialized early during VM startup, as it can not determinate its max_size. // Now, we will let WorkerThreads to initialize gclab when new worker is created. _workers->set_initialize_gclab(); + + // Note that the safepoint workers may require gclabs if the threads are used to create a heap dump + // during a concurrent evacuation phase. if (_safepoint_workers != nullptr) { _safepoint_workers->threads_do(&init_gclabs); _safepoint_workers->set_initialize_gclab(); @@ -773,14 +796,14 @@ size_t ShenandoahHeap::max_capacity() const { size_t ShenandoahHeap::soft_max_capacity() const { size_t v = Atomic::load(&_soft_max_size); assert(min_capacity() <= v && v <= max_capacity(), - "Should be in bounds: " SIZE_FORMAT " <= " SIZE_FORMAT " <= " SIZE_FORMAT, + "Should be in bounds: %zu <= %zu <= %zu", min_capacity(), v, max_capacity()); return v; } void ShenandoahHeap::set_soft_max_capacity(size_t v) { assert(min_capacity() <= v && v <= max_capacity(), - "Should be in bounds: " SIZE_FORMAT " <= " SIZE_FORMAT " <= " SIZE_FORMAT, + "Should be in bounds: %zu <= %zu <= %zu", min_capacity(), v, max_capacity()); Atomic::store(&_soft_max_size, v); } @@ -827,7 +850,7 @@ bool ShenandoahHeap::check_soft_max_changed() { new_soft_max = MAX2(min_capacity(), new_soft_max); new_soft_max = MIN2(max_capacity(), new_soft_max); if (new_soft_max != old_soft_max) { - log_info(gc)("Soft Max Heap Size: " SIZE_FORMAT "%s -> " SIZE_FORMAT "%s", + log_info(gc)("Soft Max Heap Size: %zu%s -> %zu%s", byte_size_in_proper_unit(old_soft_max), proper_unit_for_byte_size(old_soft_max), byte_size_in_proper_unit(new_soft_max), proper_unit_for_byte_size(new_soft_max) ); @@ -866,13 +889,13 @@ HeapWord* ShenandoahHeap::allocate_from_gclab_slow(Thread* thread, size_t size) // Record new heuristic value even if we take any shortcut. This captures // the case when moderately-sized objects always take a shortcut. At some point, // heuristics should catch up with them. - log_debug(gc, free)("Set new GCLAB size: " SIZE_FORMAT, new_size); + log_debug(gc, free)("Set new GCLAB size: %zu", new_size); ShenandoahThreadLocalData::set_gclab_size(thread, new_size); if (new_size < size) { // New size still does not fit the object. Fall back to shared allocation. // This avoids retiring perfectly good GCLABs, when we encounter a large object. - log_debug(gc, free)("New gclab size (" SIZE_FORMAT ") is too small for " SIZE_FORMAT, new_size, size); + log_debug(gc, free)("New gclab size (%zu) is too small for %zu", new_size, size); return nullptr; } @@ -981,8 +1004,8 @@ HeapWord* ShenandoahHeap::allocate_memory(ShenandoahAllocRequest& req) { } if (log_develop_is_enabled(Debug, gc, alloc)) { ResourceMark rm; - log_debug(gc, alloc)("Thread: %s, Result: " PTR_FORMAT ", Request: %s, Size: " SIZE_FORMAT - ", Original: " SIZE_FORMAT ", Latest: " SIZE_FORMAT, + log_debug(gc, alloc)("Thread: %s, Result: " PTR_FORMAT ", Request: %s, Size: %zu" + ", Original: %zu, Latest: %zu", Thread::current()->name(), p2i(result), req.type_string(), req.size(), original_count, get_gc_no_progress_count()); } @@ -1011,7 +1034,7 @@ HeapWord* ShenandoahHeap::allocate_memory(ShenandoahAllocRequest& req) { size_t actual = req.actual_size(); assert (req.is_lab_alloc() || (requested == actual), - "Only LAB allocations are elastic: %s, requested = " SIZE_FORMAT ", actual = " SIZE_FORMAT, + "Only LAB allocations are elastic: %s, requested = %zu, actual = %zu", ShenandoahAllocRequest::alloc_type_to_string(req.type()), requested, actual); if (req.is_mutator_alloc()) { @@ -1163,7 +1186,7 @@ class ShenandoahEvacuationTask : public WorkerTask { ShenandoahConcurrentEvacuateRegionObjectClosure cl(_sh); ShenandoahHeapRegion* r; while ((r =_cs->claim_next()) != nullptr) { - assert(r->has_live(), "Region " SIZE_FORMAT " should have been reclaimed early", r->index()); + assert(r->has_live(), "Region %zu should have been reclaimed early", r->index()); _sh->marked_object_iterate(r, &cl); if (ShenandoahPacing) { @@ -1177,11 +1200,93 @@ class ShenandoahEvacuationTask : public WorkerTask { } }; +class ShenandoahRetireGCLABClosure : public ThreadClosure { +private: + bool const _resize; +public: + explicit ShenandoahRetireGCLABClosure(bool resize) : _resize(resize) {} + void do_thread(Thread* thread) override { + PLAB* gclab = ShenandoahThreadLocalData::gclab(thread); + assert(gclab != nullptr, "GCLAB should be initialized for %s", thread->name()); + gclab->retire(); + if (_resize && ShenandoahThreadLocalData::gclab_size(thread) > 0) { + ShenandoahThreadLocalData::set_gclab_size(thread, 0); + } + + if (ShenandoahHeap::heap()->mode()->is_generational()) { + PLAB* plab = ShenandoahThreadLocalData::plab(thread); + assert(plab != nullptr, "PLAB should be initialized for %s", thread->name()); + + // There are two reasons to retire all plabs between old-gen evacuation passes. + // 1. We need to make the plab memory parsable by remembered-set scanning. + // 2. We need to establish a trustworthy UpdateWaterMark value within each old-gen heap region + ShenandoahGenerationalHeap::heap()->retire_plab(plab, thread); + if (_resize && ShenandoahThreadLocalData::plab_size(thread) > 0) { + ShenandoahThreadLocalData::set_plab_size(thread, 0); + } + } + } +}; + +class ShenandoahGCStatePropagator : public ThreadClosure { +public: + explicit ShenandoahGCStatePropagator(char gc_state) : _gc_state(gc_state) {} + + void do_thread(Thread* thread) override { + ShenandoahThreadLocalData::set_gc_state(thread, _gc_state); + } +private: + char _gc_state; +}; + +class ShenandoahPrepareForUpdateRefs : public HandshakeClosure { +public: + explicit ShenandoahPrepareForUpdateRefs(char gc_state) : + HandshakeClosure("Shenandoah Prepare for Update Refs"), + _retire(ResizeTLAB), _propagator(gc_state) {} + + void do_thread(Thread* thread) override { + _propagator.do_thread(thread); + if (ShenandoahThreadLocalData::gclab(thread) != nullptr) { + _retire.do_thread(thread); + } + } +private: + ShenandoahRetireGCLABClosure _retire; + ShenandoahGCStatePropagator _propagator; +}; + void ShenandoahHeap::evacuate_collection_set(bool concurrent) { ShenandoahEvacuationTask task(this, _collection_set, concurrent); workers()->run_task(&task); } +void ShenandoahHeap::concurrent_prepare_for_update_refs() { + { + // Java threads take this lock while they are being attached and added to the list of thread. + // If another thread holds this lock before we update the gc state, it will receive a stale + // gc state, but they will have been added to the list of java threads and so will be corrected + // by the following handshake. + MutexLocker lock(Threads_lock); + + // A cancellation at this point means the degenerated cycle must resume from update-refs. + set_gc_state_concurrent(EVACUATION, false); + set_gc_state_concurrent(WEAK_ROOTS, false); + set_gc_state_concurrent(UPDATE_REFS, true); + } + + // This will propagate the gc state and retire gclabs and plabs for threads that require it. + ShenandoahPrepareForUpdateRefs prepare_for_update_refs(_gc_state.raw_value()); + + // The handshake won't touch worker threads (or control thread, or VM thread), so do those separately. + Threads::non_java_threads_do(&prepare_for_update_refs); + + // Now retire gclabs and plabs and propagate gc_state for mutator threads + Handshake::execute(&prepare_for_update_refs); + + _update_refs_iterator.reset(); +} + oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) { assert(thread == Thread::current(), "Expected thread parameter to be current thread."); if (ShenandoahThreadLocalData::is_oom_during_evac(thread)) { @@ -1336,34 +1441,6 @@ class ShenandoahCheckCleanGCLABClosure : public ThreadClosure { } }; -class ShenandoahRetireGCLABClosure : public ThreadClosure { -private: - bool const _resize; -public: - ShenandoahRetireGCLABClosure(bool resize) : _resize(resize) {} - void do_thread(Thread* thread) { - PLAB* gclab = ShenandoahThreadLocalData::gclab(thread); - assert(gclab != nullptr, "GCLAB should be initialized for %s", thread->name()); - gclab->retire(); - if (_resize && ShenandoahThreadLocalData::gclab_size(thread) > 0) { - ShenandoahThreadLocalData::set_gclab_size(thread, 0); - } - - if (ShenandoahHeap::heap()->mode()->is_generational()) { - PLAB* plab = ShenandoahThreadLocalData::plab(thread); - assert(plab != nullptr, "PLAB should be initialized for %s", thread->name()); - - // There are two reasons to retire all plabs between old-gen evacuation passes. - // 1. We need to make the plab memory parsable by remembered-set scanning. - // 2. We need to establish a trustworthy UpdateWaterMark value within each old-gen heap region - ShenandoahGenerationalHeap::heap()->retire_plab(plab, thread); - if (_resize && ShenandoahThreadLocalData::plab_size(thread) > 0) { - ShenandoahThreadLocalData::set_plab_size(thread, 0); - } - } - } -}; - void ShenandoahHeap::labs_make_parsable() { assert(UseTLAB, "Only call with UseTLAB"); @@ -1376,6 +1453,10 @@ void ShenandoahHeap::labs_make_parsable() { } workers()->threads_do(&cl); + + if (safepoint_workers() != nullptr) { + safepoint_workers()->threads_do(&cl); + } } void ShenandoahHeap::tlabs_retire(bool resize) { @@ -1411,6 +1492,7 @@ void ShenandoahHeap::gclabs_retire(bool resize) { for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { cl.do_thread(t); } + workers()->threads_do(&cl); if (safepoint_workers() != nullptr) { @@ -1430,6 +1512,18 @@ size_t ShenandoahHeap::max_tlab_size() const { return ShenandoahHeapRegion::max_tlab_size_words(); } +void ShenandoahHeap::collect_as_vm_thread(GCCause::Cause cause) { + // These requests are ignored because we can't easily have Shenandoah jump into + // a synchronous (degenerated or full) cycle while it is in the middle of a concurrent + // cycle. We _could_ cancel the concurrent cycle and then try to run a cycle directly + // on the VM thread, but this would confuse the control thread mightily and doesn't + // seem worth the trouble. Instead, we will have the caller thread run (and wait for) a + // concurrent cycle in the prologue of the heap inspect/dump operation. This is how + // other concurrent collectors in the JVM handle this scenario as well. + assert(Thread::current()->is_VM_thread(), "Should be the VM thread"); + guarantee(cause == GCCause::_heap_dump || cause == GCCause::_heap_inspection, "Invalid cause"); +} + void ShenandoahHeap::collect(GCCause::Cause cause) { control_thread()->request_gc(cause); } @@ -1514,7 +1608,9 @@ void ShenandoahHeap::set_active_generation() { void ShenandoahHeap::on_cycle_start(GCCause::Cause cause, ShenandoahGeneration* generation) { shenandoah_policy()->record_collection_cause(cause); - assert(gc_cause() == GCCause::_no_gc, "Over-writing cause"); + const GCCause::Cause current = gc_cause(); + assert(current == GCCause::_no_gc, "Over-writing cause: %s, with: %s", + GCCause::to_string(current), GCCause::to_string(cause)); assert(_gc_generation == nullptr, "Over-writing _gc_generation"); set_gc_cause(cause); @@ -1920,23 +2016,31 @@ void ShenandoahHeap::prepare_update_heap_references(bool concurrent) { _update_refs_iterator.reset(); } -void ShenandoahHeap::propagate_gc_state_to_java_threads() { +void ShenandoahHeap::propagate_gc_state_to_all_threads() { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); if (_gc_state_changed) { + ShenandoahGCStatePropagator propagator(_gc_state.raw_value()); + Threads::threads_do(&propagator); _gc_state_changed = false; - char state = gc_state(); - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - ShenandoahThreadLocalData::set_gc_state(t, state); - } } } -void ShenandoahHeap::set_gc_state(uint mask, bool value) { +void ShenandoahHeap::set_gc_state_at_safepoint(uint mask, bool value) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint"); _gc_state.set_cond(mask, value); _gc_state_changed = true; } +void ShenandoahHeap::set_gc_state_concurrent(uint mask, bool value) { + // Holding the thread lock here assures that any thread created after we change the gc + // state will have the correct state. It also prevents attaching threads from seeing + // an inconsistent state. See ShenandoahBarrierSet::on_thread_attach for reference. Established + // threads will use their thread local copy of the gc state (changed by a handshake, or on a + // safepoint). + assert(Threads_lock->is_locked(), "Must hold thread lock for concurrent gc state change"); + _gc_state.set_cond(mask, value); +} + void ShenandoahHeap::set_concurrent_young_mark_in_progress(bool in_progress) { uint mask; assert(!has_forwarded_objects(), "Young marking is not concurrent with evacuation"); @@ -1948,15 +2052,15 @@ void ShenandoahHeap::set_concurrent_young_mark_in_progress(bool in_progress) { } else { mask = MARKING | YOUNG_MARKING; } - set_gc_state(mask, in_progress); + set_gc_state_at_safepoint(mask, in_progress); manage_satb_barrier(in_progress); } void ShenandoahHeap::set_concurrent_old_mark_in_progress(bool in_progress) { #ifdef ASSERT - // has_forwarded_objects() iff UPDATEREFS or EVACUATION + // has_forwarded_objects() iff UPDATE_REFS or EVACUATION bool has_forwarded = has_forwarded_objects(); - bool updating_or_evacuating = _gc_state.is_set(UPDATEREFS | EVACUATION); + bool updating_or_evacuating = _gc_state.is_set(UPDATE_REFS | EVACUATION); bool evacuating = _gc_state.is_set(EVACUATION); assert ((has_forwarded == updating_or_evacuating) || (evacuating && !has_forwarded && collection_set()->is_empty()), "Updating or evacuating iff has forwarded objects, or if evacuation phase is promoting in place without forwarding"); @@ -1964,9 +2068,9 @@ void ShenandoahHeap::set_concurrent_old_mark_in_progress(bool in_progress) { if (!in_progress && is_concurrent_young_mark_in_progress()) { // If young-marking is in progress when we turn off OLD_MARKING, leave MARKING (and YOUNG_MARKING) on assert(_gc_state.is_set(MARKING), "concurrent_young_marking_in_progress implies MARKING"); - set_gc_state(OLD_MARKING, in_progress); + set_gc_state_at_safepoint(OLD_MARKING, in_progress); } else { - set_gc_state(MARKING | OLD_MARKING, in_progress); + set_gc_state_at_safepoint(MARKING | OLD_MARKING, in_progress); } manage_satb_barrier(in_progress); } @@ -1993,7 +2097,7 @@ void ShenandoahHeap::manage_satb_barrier(bool active) { void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint"); - set_gc_state(EVACUATION, in_progress); + set_gc_state_at_safepoint(EVACUATION, in_progress); } void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { @@ -2005,7 +2109,7 @@ void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { } void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool cond) { - set_gc_state(WEAK_ROOTS, cond); + set_gc_state_at_safepoint(WEAK_ROOTS, cond); } GCTracer* ShenandoahHeap::tracer() { @@ -2108,7 +2212,7 @@ void ShenandoahHeap::stw_unload_classes(bool full_gc) { DEBUG_ONLY(MetaspaceUtils::verify();) } -// Weak roots are either pre-evacuated (final mark) or updated (final updaterefs), +// Weak roots are either pre-evacuated (final mark) or updated (final update refs), // so they should not have forwarded oops. // However, we do need to "null" dead oops in the roots, if can not be done // in concurrent cycles. @@ -2152,7 +2256,7 @@ void ShenandoahHeap::parallel_cleaning(bool full_gc) { } void ShenandoahHeap::set_has_forwarded_objects(bool cond) { - set_gc_state(HAS_FORWARDED, cond); + set_gc_state_at_safepoint(HAS_FORWARDED, cond); } void ShenandoahHeap::set_unload_classes(bool uc) { @@ -2192,7 +2296,7 @@ void ShenandoahHeap::set_full_gc_move_in_progress(bool in_progress) { } void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) { - set_gc_state(UPDATEREFS, in_progress); + set_gc_state_at_safepoint(UPDATE_REFS, in_progress); } void ShenandoahHeap::register_nmethod(nmethod* nm) { @@ -2210,7 +2314,7 @@ void ShenandoahHeap::pin_object(JavaThread* thr, oop o) { void ShenandoahHeap::unpin_object(JavaThread* thr, oop o) { ShenandoahHeapRegion* r = heap_region_containing(o); assert(r != nullptr, "Sanity"); - assert(r->pin_count() > 0, "Region " SIZE_FORMAT " should have non-zero pins", r->index()); + assert(r->pin_count() > 0, "Region %zu should have non-zero pins", r->index()); r->record_unpin(); } @@ -2242,7 +2346,7 @@ void ShenandoahHeap::assert_pinned_region_status() { shenandoah_assert_generations_reconciled(); if (gc_generation()->contains(r)) { assert((r->is_pinned() && r->pin_count() > 0) || (!r->is_pinned() && r->pin_count() == 0), - "Region " SIZE_FORMAT " pinning status is inconsistent", i); + "Region %zu pinning status is inconsistent", i); } } } @@ -2338,7 +2442,7 @@ class ShenandoahUpdateHeapRefsTask : public WorkerTask { if (r->is_active() && !r->is_cset()) { _heap->marked_object_oop_iterate(r, &cl, update_watermark); if (ShenandoahPacing) { - _heap->pacer()->report_updaterefs(pointer_delta(update_watermark, r->bottom())); + _heap->pacer()->report_update_refs(pointer_delta(update_watermark, r->bottom())); } } if (_heap->check_cancelled_gc_and_yield(CONCURRENT)) { @@ -2400,7 +2504,7 @@ void ShenandoahHeap::rebuild_free_set(bool concurrent) { assert((first_old_region > last_old_region) || ((last_old_region + 1 - first_old_region >= old_region_count) && get_region(first_old_region)->is_old() && get_region(last_old_region)->is_old()), - "sanity: old_region_count: " SIZE_FORMAT ", first_old_region: " SIZE_FORMAT ", last_old_region: " SIZE_FORMAT, + "sanity: old_region_count: %zu, first_old_region: %zu, last_old_region: %zu", old_region_count, first_old_region, last_old_region); if (mode()->is_generational()) { @@ -2597,6 +2701,14 @@ char ShenandoahHeap::gc_state() const { return _gc_state.raw_value(); } +bool ShenandoahHeap::is_gc_state(GCState state) const { + // If the global gc state has been changed, but hasn't yet been propagated to all threads, then + // the global gc state is the correct value. Once the gc state has been synchronized with all threads, + // _gc_state_changed will be toggled to false and we need to use the thread local state. + return _gc_state_changed ? _gc_state.is_set(state) : ShenandoahThreadLocalData::is_gc_state(state); +} + + ShenandoahLiveData* ShenandoahHeap::get_liveness_cache(uint worker_id) { #ifdef ASSERT assert(_liveness_cache != nullptr, "sanity"); @@ -2738,4 +2850,3 @@ void ShenandoahHeap::log_heap_status(const char* msg) const { global_generation()->log_status(msg); } } - diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 5beced0544cf6..785e1742b0cdc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -329,7 +329,7 @@ class ShenandoahHeap : public CollectedHeap { EVACUATION_BITPOS = 2, // Heap is under updating: needs no additional barriers. - UPDATEREFS_BITPOS = 3, + UPDATE_REFS_BITPOS = 3, // Heap is under weak-reference/roots processing: needs weak-LRB barriers. WEAK_ROOTS_BITPOS = 4, @@ -346,7 +346,7 @@ class ShenandoahHeap : public CollectedHeap { HAS_FORWARDED = 1 << HAS_FORWARDED_BITPOS, MARKING = 1 << MARKING_BITPOS, EVACUATION = 1 << EVACUATION_BITPOS, - UPDATEREFS = 1 << UPDATEREFS_BITPOS, + UPDATE_REFS = 1 << UPDATE_REFS_BITPOS, WEAK_ROOTS = 1 << WEAK_ROOTS_BITPOS, YOUNG_MARKING = 1 << YOUNG_MARKING_BITPOS, OLD_MARKING = 1 << OLD_MARKING_BITPOS @@ -363,18 +363,35 @@ class ShenandoahHeap : public CollectedHeap { size_t _gc_no_progress_count; - // This updates the singlular, global gc state. This must happen on a safepoint. - void set_gc_state(uint mask, bool value); + // This updates the singular, global gc state. This call must happen on a safepoint. + void set_gc_state_at_safepoint(uint mask, bool value); + + // This also updates the global gc state, but does not need to be called on a safepoint. + // Critically, this method will _not_ flag that the global gc state has changed and threads + // will continue to use their thread local copy. This is expected to be used in conjunction + // with a handshake operation to propagate the new gc state. + void set_gc_state_concurrent(uint mask, bool value); public: + // This returns the raw value of the singular, global gc state. char gc_state() const; - // This copies the global gc state into a thread local variable for java threads. - // It is primarily intended to support quick access at barriers. - void propagate_gc_state_to_java_threads(); + // Compares the given state against either the global gc state, or the thread local state. + // The global gc state may change on a safepoint and is the correct value to use until + // the global gc state has been propagated to all threads (after which, this method will + // compare against the thread local state). The thread local gc state may also be changed + // by a handshake operation, in which case, this function continues using the updated thread + // local value. + bool is_gc_state(GCState state) const; + + // This copies the global gc state into a thread local variable for all threads. + // The thread local gc state is primarily intended to support quick access at barriers. + // All threads are updated because in some cases the control thread or the vm thread may + // need to execute the load reference barrier. + void propagate_gc_state_to_all_threads(); // This is public to support assertions that the state hasn't been changed off of - // a safepoint and that any changes were propagated to java threads after the safepoint. + // a safepoint and that any changes were propagated to threads after the safepoint. bool has_gc_state_changed() const { return _gc_state_changed; } // Returns true if allocations have occurred in new regions or if regions have been @@ -394,9 +411,7 @@ class ShenandoahHeap : public CollectedHeap { void set_concurrent_strong_root_in_progress(bool cond); void set_concurrent_weak_root_in_progress(bool cond); - inline bool is_stable() const; inline bool is_idle() const; - inline bool is_concurrent_mark_in_progress() const; inline bool is_concurrent_young_mark_in_progress() const; inline bool is_concurrent_old_mark_in_progress() const; @@ -464,6 +479,10 @@ class ShenandoahHeap : public CollectedHeap { void do_class_unloading(); // Reference updating void prepare_update_heap_references(bool concurrent); + + // Retires LABs used for evacuation + void concurrent_prepare_for_update_refs(); + virtual void update_heap_references(bool concurrent); // Final update region states void update_heap_region_states(bool concurrent); @@ -615,6 +634,7 @@ class ShenandoahHeap : public CollectedHeap { MemRegion reserved_region() const { return _reserved; } bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); } + void collect_as_vm_thread(GCCause::Cause cause) override; void collect(GCCause::Cause cause) override; void do_full_collection(bool clear_all_soft_refs) override; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index 6a38266489e03..461447cf9ba77 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,10 +65,6 @@ inline ShenandoahHeapRegion* ShenandoahRegionIterator::next() { return _heap->get_region(new_index - 1); } -inline bool ShenandoahHeap::has_forwarded_objects() const { - return _gc_state.is_set(HAS_FORWARDED); -} - inline WorkerThreads* ShenandoahHeap::workers() const { return _workers; } @@ -382,7 +379,7 @@ inline bool ShenandoahHeap::is_in_active_generation(oop obj) const { // Old regions are in old and global collections, not in young collections return !gen->is_young(); default: - assert(false, "Bad affiliation (%d) for region " SIZE_FORMAT, region_affiliation(index), index); + assert(false, "Bad affiliation (%d) for region %zu", region_affiliation(index), index); return false; } } @@ -450,28 +447,36 @@ inline bool ShenandoahHeap::in_collection_set_loc(void* p) const { return collection_set()->is_in_loc(p); } -inline bool ShenandoahHeap::is_stable() const { - return _gc_state.is_clear(); +inline bool ShenandoahHeap::is_idle() const { + return _gc_state_changed ? _gc_state.is_clear() : ShenandoahThreadLocalData::gc_state(Thread::current()) == 0; } -inline bool ShenandoahHeap::is_idle() const { - return _gc_state.is_unset(MARKING | EVACUATION | UPDATEREFS); +inline bool ShenandoahHeap::has_forwarded_objects() const { + return is_gc_state(HAS_FORWARDED); } inline bool ShenandoahHeap::is_concurrent_mark_in_progress() const { - return _gc_state.is_set(MARKING); + return is_gc_state(MARKING); } inline bool ShenandoahHeap::is_concurrent_young_mark_in_progress() const { - return _gc_state.is_set(YOUNG_MARKING); + return is_gc_state(YOUNG_MARKING); } inline bool ShenandoahHeap::is_concurrent_old_mark_in_progress() const { - return _gc_state.is_set(OLD_MARKING); + return is_gc_state(OLD_MARKING); } inline bool ShenandoahHeap::is_evacuation_in_progress() const { - return _gc_state.is_set(EVACUATION); + return is_gc_state(EVACUATION); +} + +inline bool ShenandoahHeap::is_update_refs_in_progress() const { + return is_gc_state(UPDATE_REFS); +} + +inline bool ShenandoahHeap::is_concurrent_weak_root_in_progress() const { + return is_gc_state(WEAK_ROOTS); } inline bool ShenandoahHeap::is_degenerated_gc_in_progress() const { @@ -486,10 +491,6 @@ inline bool ShenandoahHeap::is_full_gc_move_in_progress() const { return _full_gc_move_in_progress.is_set(); } -inline bool ShenandoahHeap::is_update_refs_in_progress() const { - return _gc_state.is_set(UPDATEREFS); -} - inline bool ShenandoahHeap::is_stw_gc_in_progress() const { return is_full_gc_in_progress() || is_degenerated_gc_in_progress(); } @@ -498,10 +499,6 @@ inline bool ShenandoahHeap::is_concurrent_strong_root_in_progress() const { return _concurrent_strong_root_in_progress.is_set(); } -inline bool ShenandoahHeap::is_concurrent_weak_root_in_progress() const { - return _gc_state.is_set(WEAK_ROOTS); -} - template inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, T* cl) { marked_object_iterate(region, cl, region->top()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index d46b76c937652..42237a0ab0600 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/cardTable.hpp" #include "gc/shared/space.hpp" #include "gc/shared/tlab_globals.hpp" @@ -242,7 +241,7 @@ void ShenandoahHeapRegion::make_humongous_cont_bypass(ShenandoahAffiliation affi void ShenandoahHeapRegion::make_pinned() { shenandoah_assert_heaplocked(); - assert(pin_count() > 0, "Should have pins: " SIZE_FORMAT, pin_count()); + assert(pin_count() > 0, "Should have pins: %zu", pin_count()); switch (state()) { case _regular: @@ -264,7 +263,7 @@ void ShenandoahHeapRegion::make_pinned() { void ShenandoahHeapRegion::make_unpinned() { shenandoah_assert_heaplocked(); - assert(pin_count() == 0, "Should not have pins: " SIZE_FORMAT, pin_count()); + assert(pin_count() == 0, "Should not have pins: %zu", pin_count()); switch (state()) { case _pinned: @@ -398,7 +397,7 @@ void ShenandoahHeapRegion::set_live_data(size_t s) { void ShenandoahHeapRegion::print_on(outputStream* st) const { st->print("|"); - st->print(SIZE_FORMAT_W(5), this->_index); + st->print("%5zu", this->_index); switch (state()) { case _empty_uncommitted: @@ -445,15 +444,15 @@ void ShenandoahHeapRegion::print_on(outputStream* st) const { p2i(ShenandoahHeap::heap()->marking_context()->top_at_mark_start(const_cast(this)))); st->print("|UWM " SHR_PTR_FORMAT, p2i(_update_watermark)); - st->print("|U " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); - st->print("|T " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_tlab_allocs()), proper_unit_for_byte_size(get_tlab_allocs())); - st->print("|G " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs())); + st->print("|U %5zu%1s", byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); + st->print("|T %5zu%1s", byte_size_in_proper_unit(get_tlab_allocs()), proper_unit_for_byte_size(get_tlab_allocs())); + st->print("|G %5zu%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs())); if (ShenandoahHeap::heap()->mode()->is_generational()) { - st->print("|P " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_plab_allocs()), proper_unit_for_byte_size(get_plab_allocs())); + st->print("|P %5zu%1s", byte_size_in_proper_unit(get_plab_allocs()), proper_unit_for_byte_size(get_plab_allocs())); } - st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs())); - st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes())); - st->print("|CP " SIZE_FORMAT_W(3), pin_count()); + st->print("|S %5zu%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs())); + st->print("|L %5zu%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes())); + st->print("|CP %3zu", pin_count()); st->cr(); #undef SHR_PTR_FORMAT @@ -675,33 +674,33 @@ size_t ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) { size_t region_size; if (FLAG_IS_DEFAULT(ShenandoahRegionSize)) { if (ShenandoahMinRegionSize > max_heap_size / MIN_NUM_REGIONS) { - err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number " - "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "%s).", + err_msg message("Max heap size (%zu%s) is too low to afford the minimum number " + "of regions (%zu) of minimum region size (%zu%s).", byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size), MIN_NUM_REGIONS, byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMinRegionSize < MIN_REGION_SIZE) { - err_msg message("" SIZE_FORMAT "%s should not be lower than minimum region size (" SIZE_FORMAT "%s).", + err_msg message("%zu%s should not be lower than minimum region size (%zu%s).", byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize), byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMinRegionSize < MinTLABSize) { - err_msg message("" SIZE_FORMAT "%s should not be lower than TLAB size size (" SIZE_FORMAT "%s).", + err_msg message("%zu%s should not be lower than TLAB size size (%zu%s).", byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize), byte_size_in_proper_unit(MinTLABSize), proper_unit_for_byte_size(MinTLABSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message); } if (ShenandoahMaxRegionSize < MIN_REGION_SIZE) { - err_msg message("" SIZE_FORMAT "%s should not be lower than min region size (" SIZE_FORMAT "%s).", + err_msg message("%zu%s should not be lower than min region size (%zu%s).", byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize), byte_size_in_proper_unit(MIN_REGION_SIZE), proper_unit_for_byte_size(MIN_REGION_SIZE)); vm_exit_during_initialization("Invalid -XX:ShenandoahMaxRegionSize option", message); } if (ShenandoahMinRegionSize > ShenandoahMaxRegionSize) { - err_msg message("Minimum (" SIZE_FORMAT "%s) should be larger than maximum (" SIZE_FORMAT "%s).", + err_msg message("Minimum (%zu%s) should be larger than maximum (%zu%s).", byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize), byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize or -XX:ShenandoahMaxRegionSize", message); @@ -717,21 +716,21 @@ size_t ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) { } else { if (ShenandoahRegionSize > max_heap_size / MIN_NUM_REGIONS) { - err_msg message("Max heap size (" SIZE_FORMAT "%s) is too low to afford the minimum number " - "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "%s).", + err_msg message("Max heap size (%zu%s) is too low to afford the minimum number " + "of regions (%zu) of requested size (%zu%s).", byte_size_in_proper_unit(max_heap_size), proper_unit_for_byte_size(max_heap_size), MIN_NUM_REGIONS, byte_size_in_proper_unit(ShenandoahRegionSize), proper_unit_for_byte_size(ShenandoahRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message); } if (ShenandoahRegionSize < ShenandoahMinRegionSize) { - err_msg message("Heap region size (" SIZE_FORMAT "%s) should be larger than min region size (" SIZE_FORMAT "%s).", + err_msg message("Heap region size (%zu%s) should be larger than min region size (%zu%s).", byte_size_in_proper_unit(ShenandoahRegionSize), proper_unit_for_byte_size(ShenandoahRegionSize), byte_size_in_proper_unit(ShenandoahMinRegionSize), proper_unit_for_byte_size(ShenandoahMinRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message); } if (ShenandoahRegionSize > ShenandoahMaxRegionSize) { - err_msg message("Heap region size (" SIZE_FORMAT "%s) should be lower than max region size (" SIZE_FORMAT "%s).", + err_msg message("Heap region size (%zu%s) should be lower than max region size (%zu%s).", byte_size_in_proper_unit(ShenandoahRegionSize), proper_unit_for_byte_size(ShenandoahRegionSize), byte_size_in_proper_unit(ShenandoahMaxRegionSize), proper_unit_for_byte_size(ShenandoahMaxRegionSize)); vm_exit_during_initialization("Invalid -XX:ShenandoahRegionSize option", message); @@ -843,7 +842,7 @@ void ShenandoahHeapRegion::record_pin() { } void ShenandoahHeapRegion::record_unpin() { - assert(pin_count() > 0, "Region " SIZE_FORMAT " should have non-zero pins", index()); + assert(pin_count() > 0, "Region %zu should have non-zero pins", index()); Atomic::sub(&_critical_pins, (size_t)1); } @@ -857,7 +856,7 @@ void ShenandoahHeapRegion::set_affiliation(ShenandoahAffiliation new_affiliation ShenandoahAffiliation region_affiliation = heap->region_affiliation(this); { ShenandoahMarkingContext* const ctx = heap->complete_marking_context(); - log_debug(gc)("Setting affiliation of Region " SIZE_FORMAT " from %s to %s, top: " PTR_FORMAT ", TAMS: " PTR_FORMAT + log_debug(gc)("Setting affiliation of Region %zu from %s to %s, top: " PTR_FORMAT ", TAMS: " PTR_FORMAT ", watermark: " PTR_FORMAT ", top_bitmap: " PTR_FORMAT, index(), shenandoah_affiliation_name(region_affiliation), shenandoah_affiliation_name(new_affiliation), p2i(top()), p2i(ctx->top_at_mark_start(this)), p2i(_update_watermark), p2i(ctx->top_bitmap(this))); @@ -871,7 +870,7 @@ void ShenandoahHeapRegion::set_affiliation(ShenandoahAffiliation new_affiliation HeapWord* top_bitmap = ctx->top_bitmap(this); assert(ctx->is_bitmap_range_within_region_clear(top_bitmap, _end), - "Region " SIZE_FORMAT ", bitmap should be clear between top_bitmap: " PTR_FORMAT " and end: " PTR_FORMAT, idx, + "Region %zu, bitmap should be clear between top_bitmap: " PTR_FORMAT " and end: " PTR_FORMAT, idx, p2i(top_bitmap), p2i(_end)); } #endif diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp index 382d9ba942ccd..7f29a8628aab5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +37,7 @@ HeapWord* ShenandoahHeapRegion::allocate_aligned(size_t size, ShenandoahAllocRequest &req, size_t alignment_in_bytes) { shenandoah_assert_heaplocked_or_safepoint(); assert(req.is_lab_alloc(), "allocate_aligned() only applies to LAB allocations"); - assert(is_object_aligned(size), "alloc size breaks alignment: " SIZE_FORMAT, size); + assert(is_object_aligned(size), "alloc size breaks alignment: %zu", size); assert(is_old(), "aligned allocations are only taken from OLD regions to support PLABs"); assert(is_aligned(alignment_in_bytes, HeapWordSize), "Expect heap word alignment"); @@ -88,7 +89,7 @@ HeapWord* ShenandoahHeapRegion::allocate_aligned(size_t size, ShenandoahAllocReq HeapWord* ShenandoahHeapRegion::allocate(size_t size, const ShenandoahAllocRequest& req) { shenandoah_assert_heaplocked_or_safepoint(); - assert(is_object_aligned(size), "alloc size breaks alignment: " SIZE_FORMAT, size); + assert(is_object_aligned(size), "alloc size breaks alignment: %zu", size); HeapWord* obj = top(); if (pointer_delta(end(), obj) >= size) { @@ -160,7 +161,7 @@ inline bool ShenandoahHeapRegion::has_live() const { inline size_t ShenandoahHeapRegion::garbage() const { assert(used() >= get_live_data_bytes(), - "Live Data must be a subset of used() live: " SIZE_FORMAT " used: " SIZE_FORMAT, + "Live Data must be a subset of used() live: %zu used: %zu", get_live_data_bytes(), used()); size_t result = used() - get_live_data_bytes(); @@ -171,7 +172,7 @@ inline size_t ShenandoahHeapRegion::garbage_before_padded_for_promote() const { assert(get_top_before_promote() != nullptr, "top before promote should not equal null"); size_t used_before_promote = byte_size(bottom(), get_top_before_promote()); assert(used_before_promote >= get_live_data_bytes(), - "Live Data must be a subset of used before promotion live: " SIZE_FORMAT " used: " SIZE_FORMAT, + "Live Data must be a subset of used before promotion live: %zu used: %zu", get_live_data_bytes(), used_before_promote); size_t result = used_before_promote - get_live_data_bytes(); return result; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionClosures.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionClosures.cpp index 3d3483a5b694f..3c6fe1a3df12d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionClosures.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionClosures.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/shenandoahHeapRegionClosures.hpp" #include "gc/shenandoah/shenandoahMarkingContext.hpp" #include "gc/shenandoah/shenandoahSharedVariables.hpp" @@ -82,8 +81,8 @@ void ShenandoahFinalMarkUpdateRegionStateClosure::heap_region_do(ShenandoahHeapR // from-space-refs written from here on. r->set_update_watermark_at_safepoint(r->top()); } else { - assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index()); + assert(!r->has_live(), "Region %zu should have no live data", r->index()); assert(_ctx == nullptr || _ctx->top_at_mark_start(r) == r->top(), - "Region " SIZE_FORMAT " should have correct TAMS", r->index()); + "Region %zu should have correct TAMS", r->index()); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp index 73250cecd6fe5..360c7d2d649a5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, 2020, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahGeneration.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -91,7 +91,7 @@ void ShenandoahHeapRegionCounters::write_snapshot(PerfLongVariable** regions, ResourceMark rm; LogStream ls(lt); - ls.print_cr(JLONG_FORMAT " " JLONG_FORMAT " " SIZE_FORMAT " " SIZE_FORMAT " " SIZE_FORMAT, + ls.print_cr(JLONG_FORMAT " " JLONG_FORMAT " %zu %zu %zu", ts->get_value(), status->get_value(), num_regions, region_size, protocol_version); if (num_regions > 0) { ls.print(JLONG_FORMAT, regions[0]->get_value()); @@ -147,10 +147,10 @@ static int encode_phase(ShenandoahHeap* heap) { if (heap->is_update_refs_in_progress() || heap->is_full_gc_move_in_progress()) { return 3; } - if (heap->is_concurrent_mark_in_progress() || heap->is_full_gc_in_progress()) { + if (heap->is_concurrent_mark_in_progress() || heap->is_concurrent_weak_root_in_progress() || heap->is_full_gc_in_progress()) { return 1; } - assert(heap->is_idle(), "What is it doing?"); + assert(heap->is_idle(), "Unexpected gc_state: %d", heap->gc_state()); return 0; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionSet.cpp index d18bfb0d62598..46d54c70fe159 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionSet.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" @@ -81,7 +81,7 @@ ShenandoahHeapRegion* ShenandoahHeapRegionSetIterator::next() { } void ShenandoahHeapRegionSet::print_on(outputStream* out) const { - out->print_cr("Region Set : " SIZE_FORMAT "", count()); + out->print_cr("Region Set : %zu", count()); for (size_t index = 0; index < _heap->num_regions(); index++) { if (is_in(index)) { _heap->get_region(index)->print_on(out); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp b/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp index baf95a5bdf7e4..b4ea327965b34 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahInitLogger.hpp" @@ -40,7 +40,7 @@ void ShenandoahInitLogger::print() { void ShenandoahInitLogger::print_heap() { GCInitLogger::print_heap(); - log_info(gc, init)("Heap Region Count: " SIZE_FORMAT, ShenandoahHeapRegion::region_count()); + log_info(gc, init)("Heap Region Count: %zu", ShenandoahHeapRegion::region_count()); log_info(gc, init)("Heap Region Size: " EXACTFMT, EXACTFMTARGS(ShenandoahHeapRegion::region_size_bytes())); log_info(gc, init)("TLAB Size Max: " EXACTFMT, EXACTFMTARGS(ShenandoahHeapRegion::max_tlab_size_bytes())); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp index cd555e12c6f4d..97307e85a9b04 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahJfrSupport.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp index 63c6c9ea88624..47a144a638f0e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "runtime/os.hpp" @@ -46,6 +45,7 @@ void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) { assert(!ALLOW_BLOCK || java_thread != nullptr, "Must have a Java thread when allowing block."); // Spin this much, but only on multi-processor systems. int ctr = os::is_MP() ? 0xFF : 0; + int yields = 0; // Apply TTAS to avoid more expensive CAS calls if the lock is still held by other thread. while (Atomic::load(&_state) == locked || Atomic::cmpxchg(&_state, unlocked, locked) != unlocked) { @@ -68,17 +68,29 @@ void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) { // VM thread to arm the poll sooner. while (SafepointSynchronize::is_synchronizing() && !SafepointMechanism::local_poll_armed(java_thread)) { - os::naked_yield(); + yield_or_sleep(yields); } } else { - os::naked_yield(); + yield_or_sleep(yields); } } else { - os::naked_yield(); + yield_or_sleep(yields); } } } +void ShenandoahLock::yield_or_sleep(int &yields) { + // Simple yield-sleep policy: do one 100us sleep after every N yields. + // Tested with different values of N, and chose 3 for best performance. + if (yields < 3) { + os::naked_yield(); + yields++; + } else { + os::naked_short_nanosleep(100000); + yields = 0; + } +} + ShenandoahSimpleLock::ShenandoahSimpleLock() { assert(os::mutex_init_done(), "Too early!"); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp index 4d7eefd460c46..0cef2414c0d99 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp @@ -42,6 +42,8 @@ class ShenandoahLock { template void contended_lock_internal(JavaThread* java_thread); + static void yield_or_sleep(int &yields); + public: ShenandoahLock() : _state(unlocked), _owner(nullptr) {}; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp index 686295c3e1b71..2a4149ee44dc4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp @@ -24,7 +24,6 @@ */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp index 0239f961c65f1..2dc0813e51354 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2015, 2022, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -128,7 +129,7 @@ inline void ShenandoahMark::count_liveness(ShenandoahLiveData* live_data, oop ob if (!region->is_humongous_start()) { assert(!region->is_humongous(), "Cannot have continuations here"); - assert(region->is_affiliated(), "Do not count live data within Free Regular Region " SIZE_FORMAT, region_idx); + assert(region->is_affiliated(), "Do not count live data within Free Regular Region %zu", region_idx); ShenandoahLiveData cur = live_data[region_idx]; size_t new_val = size + cur; if (new_val >= SHENANDOAH_LIVEDATA_MAX) { @@ -143,11 +144,11 @@ inline void ShenandoahMark::count_liveness(ShenandoahLiveData* live_data, oop ob shenandoah_assert_in_correct_region(nullptr, obj); size_t num_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize); - assert(region->is_affiliated(), "Do not count live data within FREE Humongous Start Region " SIZE_FORMAT, region_idx); + assert(region->is_affiliated(), "Do not count live data within FREE Humongous Start Region %zu", region_idx); for (size_t i = region_idx; i < region_idx + num_regions; i++) { ShenandoahHeapRegion* chain_reg = heap->get_region(i); assert(chain_reg->is_humongous(), "Expecting a humongous region"); - assert(chain_reg->is_affiliated(), "Do not count live data within FREE Humongous Continuation Region " SIZE_FORMAT, i); + assert(chain_reg->is_affiliated(), "Do not count live data within FREE Humongous Continuation Region %zu", i); chain_reg->increase_live_data_gc_words(chain_reg->used() >> LogHeapWordSize); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp index cd0f31ae14ffe..9986afc6f2019 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahMarkBitMap.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "runtime/os.hpp" @@ -154,19 +153,19 @@ void ShenandoahMarkBitMap::check_mark(HeapWord* addr) const { void ShenandoahMarkBitMap::verify_index(idx_t bit) const { assert(bit < _size, - "BitMap index out of bounds: " SIZE_FORMAT " >= " SIZE_FORMAT, + "BitMap index out of bounds: %zu >= %zu", bit, _size); } void ShenandoahMarkBitMap::verify_limit(idx_t bit) const { assert(bit <= _size, - "BitMap limit out of bounds: " SIZE_FORMAT " > " SIZE_FORMAT, + "BitMap limit out of bounds: %zu > %zu", bit, _size); } void ShenandoahMarkBitMap::verify_range(idx_t beg, idx_t end) const { assert(beg <= end, - "BitMap range error: " SIZE_FORMAT " > " SIZE_FORMAT, beg, end); + "BitMap range error: %zu > %zu", beg, end); verify_limit(end); } #endif diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp index ded9fbd97f5b1..4fa006e60fb61 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/markBitMap.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahMarkingContext.hpp" @@ -56,7 +56,7 @@ bool ShenandoahMarkingContext::is_bitmap_range_within_region_clear(const HeapWor size_t start_idx = heap->heap_region_index_containing(start); #ifdef ASSERT size_t end_idx = heap->heap_region_index_containing(end - 1); - assert(start_idx == end_idx, "Expected range to be within same region (" SIZE_FORMAT ", " SIZE_FORMAT ")", start_idx, end_idx); + assert(start_idx == end_idx, "Expected range to be within same region (%zu, %zu)", start_idx, end_idx); #endif ShenandoahHeapRegion* r = heap->get_region(start_idx); if (!heap->is_bitmap_slice_committed(r)) { @@ -73,7 +73,7 @@ void ShenandoahMarkingContext::initialize_top_at_mark_start(ShenandoahHeapRegion _top_at_mark_starts_base[idx] = bottom; _top_bitmaps[idx] = bottom; - log_debug(gc)("SMC:initialize_top_at_mark_start for Region " SIZE_FORMAT ", TAMS: " PTR_FORMAT ", TopOfBitMap: " PTR_FORMAT, + log_debug(gc)("SMC:initialize_top_at_mark_start for Region %zu, TAMS: " PTR_FORMAT ", TopOfBitMap: " PTR_FORMAT, r->index(), p2i(bottom), p2i(r->end())); } @@ -85,7 +85,7 @@ void ShenandoahMarkingContext::clear_bitmap(ShenandoahHeapRegion* r) { HeapWord* bottom = r->bottom(); HeapWord* top_bitmap = _top_bitmaps[r->index()]; - log_debug(gc)("SMC:clear_bitmap for %s Region " SIZE_FORMAT ", top_bitmap: " PTR_FORMAT, + log_debug(gc)("SMC:clear_bitmap for %s Region %zu, top_bitmap: " PTR_FORMAT, r->affiliation_name(), r->index(), p2i(top_bitmap)); if (top_bitmap > bottom) { @@ -94,7 +94,7 @@ void ShenandoahMarkingContext::clear_bitmap(ShenandoahHeapRegion* r) { } assert(is_bitmap_range_within_region_clear(bottom, r->end()), - "Region " SIZE_FORMAT " should have no marks in bitmap", r->index()); + "Region %zu should have no marks in bitmap", r->index()); } bool ShenandoahMarkingContext::is_complete() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp index 75a16e1554992..d9bddd5fbb6b9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,16 +94,16 @@ inline void ShenandoahMarkingContext::capture_top_at_mark_start(ShenandoahHeapRe HeapWord* new_tams = r->top(); assert(new_tams >= old_tams, - "Region " SIZE_FORMAT", TAMS updates should be monotonic: " PTR_FORMAT " -> " PTR_FORMAT, + "Region %zu, TAMS updates should be monotonic: " PTR_FORMAT " -> " PTR_FORMAT, idx, p2i(old_tams), p2i(new_tams)); assert((new_tams == r->bottom()) || (old_tams == r->bottom()) || (new_tams >= _top_bitmaps[idx]), - "Region " SIZE_FORMAT", top_bitmaps updates should be monotonic: " PTR_FORMAT " -> " PTR_FORMAT, + "Region %zu, top_bitmaps updates should be monotonic: " PTR_FORMAT " -> " PTR_FORMAT, idx, p2i(_top_bitmaps[idx]), p2i(new_tams)); assert(old_tams == r->bottom() || is_bitmap_range_within_region_clear(old_tams, new_tams), - "Region " SIZE_FORMAT ", bitmap should be clear while adjusting TAMS: " PTR_FORMAT " -> " PTR_FORMAT, + "Region %zu, bitmap should be clear while adjusting TAMS: " PTR_FORMAT " -> " PTR_FORMAT, idx, p2i(old_tams), p2i(new_tams)); - log_debug(gc)("Capturing TAMS for %s Region " SIZE_FORMAT ", was: " PTR_FORMAT ", now: " PTR_FORMAT, + log_debug(gc)("Capturing TAMS for %s Region %zu, was: " PTR_FORMAT ", now: " PTR_FORMAT, r->affiliation_name(), idx, p2i(old_tams), p2i(new_tams)); _top_at_mark_starts_base[idx] = new_tams; @@ -119,7 +120,7 @@ inline HeapWord* ShenandoahMarkingContext::top_at_mark_start(const ShenandoahHea inline void ShenandoahMarkingContext::reset_top_bitmap(ShenandoahHeapRegion* r) { assert(is_bitmap_range_within_region_clear(r->bottom(), r->end()), - "Region " SIZE_FORMAT " should have no marks in bitmap", r->index()); + "Region %zu should have no marks in bitmap", r->index()); _top_bitmaps[r->index()] = r->bottom(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp index 6cbb5454ac173..e9aa69b5555c5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahMemoryPool.hpp" #include "gc/shenandoah/shenandoahYoungGeneration.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" @@ -54,15 +54,15 @@ MemoryUsage ShenandoahMemoryPool::get_memory_usage() { size_t committed = _heap->committed(); // These asserts can never fail: max is stable, and all updates to other values never overflow max. - assert(initial <= max, "initial: " SIZE_FORMAT ", max: " SIZE_FORMAT, initial, max); - assert(used <= max, "used: " SIZE_FORMAT ", max: " SIZE_FORMAT, used, max); - assert(committed <= max, "committed: " SIZE_FORMAT ", max: " SIZE_FORMAT, committed, max); + assert(initial <= max, "initial: %zu, max: %zu", initial, max); + assert(used <= max, "used: %zu, max: %zu", used, max); + assert(committed <= max, "committed: %zu, max: %zu", committed, max); // Committed and used are updated concurrently and independently. They can momentarily break // the assert below, which would also fail in downstream code. To avoid that, adjust values // to make sense under the race. See JDK-8207200. committed = MAX2(used, committed); - assert(used <= committed, "used: " SIZE_FORMAT ", committed: " SIZE_FORMAT, used, committed); + assert(used <= committed, "used: %zu, committed: %zu", used, committed); return MemoryUsage(initial, used, committed, max); } @@ -93,11 +93,6 @@ size_t ShenandoahGenerationalMemoryPool::used_in_bytes() { return _generation->used(); } -size_t ShenandoahGenerationalMemoryPool::max_size() const { - return _generation->max_capacity(); -} - - ShenandoahYoungGenMemoryPool::ShenandoahYoungGenMemoryPool(ShenandoahHeap* heap) : ShenandoahGenerationalMemoryPool(heap, "Shenandoah Young Gen", diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp index e26d61a3a6c56..ccdfdddede950 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMemoryPool.hpp @@ -55,7 +55,6 @@ class ShenandoahGenerationalMemoryPool: public ShenandoahMemoryPool { explicit ShenandoahGenerationalMemoryPool(ShenandoahHeap* heap, const char* name, ShenandoahGeneration* generation); MemoryUsage get_memory_usage() override; size_t used_in_bytes() override; - size_t max_size() const override; }; class ShenandoahYoungGenMemoryPool : public ShenandoahGenerationalMemoryPool { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMetrics.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMetrics.cpp index 8b2412ff9ab05..32386e6aec052 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMetrics.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMetrics.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahMetrics.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" @@ -43,12 +43,30 @@ void ShenandoahMetricsSnapshot::snap_after() { _ef_after = _heap->free_set()->external_fragmentation(); } -bool ShenandoahMetricsSnapshot::is_good_progress() { +// For degenerated GC, generation is Young in generational mode, Global in non-generational mode. +// For full GC, generation is always Global. +// +// Note that the size of the chosen collection set is proportional to the relevant generation's collection set. +// Note also that the generation size may change following selection of the collection set, as a side effect +// of evacuation. Evacuation may promote objects, causing old to grow and young to shrink. Or this may be a +// mixed evacuation. When old regions are evacuated, this typically allows young to expand. In all of these +// various scenarios, the purpose of asking is_good_progress() is to determine if there is enough memory available +// within young generation to justify making an attempt to perform a concurrent collection. For this reason, we'll +// use the current size of the generation (which may not be different than when the collection set was chosen) to +// assess how much free memory we require in order to consider the most recent GC to have had good progress. + +bool ShenandoahMetricsSnapshot::is_good_progress(ShenandoahGeneration* generation) { // Under the critical threshold? - size_t free_actual = _heap->free_set()->available(); - size_t free_expected = _heap->max_capacity() / 100 * ShenandoahCriticalFreeThreshold; + ShenandoahFreeSet* free_set = _heap->free_set(); + size_t free_actual = free_set->available(); + + // ShenandoahCriticalFreeThreshold is expressed as a percentage. We multiple this percentage by 1/100th + // of the generation capacity to determine whether the available memory within the generation exceeds the + // critical threshold. + size_t free_expected = (generation->max_capacity() / 100) * ShenandoahCriticalFreeThreshold; + bool prog_free = free_actual >= free_expected; - log_info(gc, ergo)("%s progress for free space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", + log_info(gc, ergo)("%s progress for free space: %zu%s, need %zu%s", prog_free ? "Good" : "Bad", byte_size_in_proper_unit(free_actual), proper_unit_for_byte_size(free_actual), byte_size_in_proper_unit(free_expected), proper_unit_for_byte_size(free_expected)); @@ -60,7 +78,7 @@ bool ShenandoahMetricsSnapshot::is_good_progress() { size_t progress_actual = (_used_before > _used_after) ? _used_before - _used_after : 0; size_t progress_expected = ShenandoahHeapRegion::region_size_bytes(); bool prog_used = progress_actual >= progress_expected; - log_info(gc, ergo)("%s progress for used space: " SIZE_FORMAT "%s, need " SIZE_FORMAT "%s", + log_info(gc, ergo)("%s progress for used space: %zu%s, need %zu%s", prog_used ? "Good" : "Bad", byte_size_in_proper_unit(progress_actual), proper_unit_for_byte_size(progress_actual), byte_size_in_proper_unit(progress_expected), proper_unit_for_byte_size(progress_expected)); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMetrics.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMetrics.hpp index 202d90bb1be23..20d8ebfd59572 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMetrics.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMetrics.hpp @@ -40,7 +40,7 @@ class ShenandoahMetricsSnapshot : public StackObj { void snap_before(); void snap_after(); - bool is_good_progress(); + bool is_good_progress(ShenandoahGeneration *generation); }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHMETRICS_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMmuTracker.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMmuTracker.cpp index d9cec36e6c9c7..663864b1294ce 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMmuTracker.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMmuTracker.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahMmuTracker.hpp" @@ -48,7 +48,7 @@ class ThreadTimeAccumulator : public ThreadClosure { size_t total_time; ThreadTimeAccumulator() : total_time(0) {} void do_thread(Thread* thread) override { - assert(!thread->has_terminated(), "Cannot get cpu time for terminated thread: " UINTX_FORMAT, thread->osthread()->thread_id_for_printing()); + assert(!thread->has_terminated(), "Cannot get cpu time for terminated thread: %zu", thread->osthread()->thread_id_for_printing()); total_time += os::thread_cpu_time(thread); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.cpp index ffeab9b635102..31265addda886 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/generationCounters.hpp" #include "gc/shared/hSpaceCounters.hpp" @@ -37,7 +36,7 @@ class ShenandoahYoungGenerationCounters : public GenerationCounters { ShenandoahYoungGenerationCounters() : GenerationCounters("Young", 0, 0, 0, (size_t)0, (size_t)0) {}; - void update_all() override { + void update_all() { // no update } }; @@ -51,8 +50,8 @@ class ShenandoahGenerationCounters : public GenerationCounters { _heap(heap) {}; - void update_all() override { - _current_size->set_value(_heap->capacity()); + void update_all() { + GenerationCounters::update_all(_heap->capacity()); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.hpp index 2d90f88770763..c58c91e162294 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.hpp @@ -29,12 +29,13 @@ #include "memory/allocation.hpp" #include "runtime/task.hpp" -class GenerationCounters; class HSpaceCounters; class ShenandoahHeap; class CollectorCounters; class ShenandoahHeapRegionCounters; class ShenandoahMonitoringSupport; +class ShenandoahGenerationCounters; +class ShenandoahYoungGenerationCounters; class ShenandoahPeriodicCountersUpdateTask : public PeriodicTask { private: @@ -60,8 +61,8 @@ class ShenandoahMonitoringSupport : public CHeapObj { CollectorCounters* _partial_counters; CollectorCounters* _full_counters; - GenerationCounters* _young_counters; - GenerationCounters* _heap_counters; + ShenandoahYoungGenerationCounters* _young_counters; + ShenandoahGenerationCounters* _heap_counters; HSpaceCounters* _space_counters; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index 5ba241590882c..53dd3ae1b1ef8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp index 3c7ba8e424300..be032a60db70a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahNumberSeq.hpp" #include "runtime/atomic.hpp" @@ -208,12 +208,12 @@ void BinaryMagnitudeSeq::add(size_t val) { // Defensively saturate for product bits: if (mag < 0) { - assert (false, "bucket index (%d) underflow for value (" SIZE_FORMAT ")", mag, val); + assert (false, "bucket index (%d) underflow for value (%zu)", mag, val); mag = 0; } if (mag >= BitsPerSize_t) { - assert (false, "bucket index (%d) overflow for value (" SIZE_FORMAT ")", mag, val); + assert (false, "bucket index (%d) overflow for value (%zu)", mag, val); mag = BitsPerSize_t - 1; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOldGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahOldGC.cpp index a5d3302091c00..708d27db16525 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOldGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOldGC.cpp @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/heuristics/shenandoahYoungHeuristics.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp index 36007023d4600..388872172553b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +23,6 @@ * */ - -#include "precompiled.hpp" - #include "gc/shared/strongRootsScope.hpp" #include "gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" @@ -108,7 +106,7 @@ class ShenandoahPurgeSATBTask : public WorkerTask { ~ShenandoahPurgeSATBTask() { if (_trashed_oops > 0) { - log_debug(gc)("Purged " SIZE_FORMAT " oops from old generation SATB buffers", _trashed_oops); + log_debug(gc)("Purged %zu oops from old generation SATB buffers", _trashed_oops); } } @@ -653,9 +651,9 @@ void ShenandoahOldGeneration::handle_failed_promotion(Thread* thread, size_t siz const size_t words_remaining = (plab == nullptr)? 0: plab->words_remaining(); const char* promote_enabled = ShenandoahThreadLocalData::allow_plab_promotions(thread)? "enabled": "disabled"; - log_info(gc, ergo)("Promotion failed, size " SIZE_FORMAT ", has plab? %s, PLAB remaining: " SIZE_FORMAT - ", plab promotions %s, promotion reserve: " SIZE_FORMAT ", promotion expended: " SIZE_FORMAT - ", old capacity: " SIZE_FORMAT ", old_used: " SIZE_FORMAT ", old unaffiliated regions: " SIZE_FORMAT, + log_info(gc, ergo)("Promotion failed, size %zu, has plab? %s, PLAB remaining: %zu" + ", plab promotions %s, promotion reserve: %zu, promotion expended: %zu" + ", old capacity: %zu, old_used: %zu, old unaffiliated regions: %zu", size * HeapWordSize, plab == nullptr? "no": "yes", words_remaining * HeapWordSize, promote_enabled, promotion_reserve, promotion_expended, max_capacity(), used(), free_unaffiliated_regions()); @@ -700,7 +698,7 @@ void ShenandoahOldGeneration::abandon_collection_candidates() { void ShenandoahOldGeneration::prepare_for_mixed_collections_after_global_gc() { assert(is_mark_complete(), "Expected old generation mark to be complete after global cycle."); _old_heuristics->prepare_for_old_collections(); - log_info(gc, ergo)("After choosing global collection set, mixed candidates: " UINT32_FORMAT ", coalescing candidates: " SIZE_FORMAT, + log_info(gc, ergo)("After choosing global collection set, mixed candidates: " UINT32_FORMAT ", coalescing candidates: %zu", _old_heuristics->unprocessed_old_collection_candidates(), _old_heuristics->coalesce_and_fill_candidates_count()); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp index e7d5a2e00c5b2..06b9d072aeb91 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -73,8 +73,8 @@ void ShenandoahPacer::setup_for_mark() { restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Mark. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " - "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + log_info(gc, ergo)("Pacer for Mark. Expected Live: %zu%s, Free: %zu%s, " + "Non-Taxable: %zu%s, Alloc Tax Rate: %.1fx", byte_size_in_proper_unit(live), proper_unit_for_byte_size(live), byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), @@ -98,15 +98,15 @@ void ShenandoahPacer::setup_for_evac() { restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Evacuation. Used CSet: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " - "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + log_info(gc, ergo)("Pacer for Evacuation. Used CSet: %zu%s, Free: %zu%s, " + "Non-Taxable: %zu%s, Alloc Tax Rate: %.1fx", byte_size_in_proper_unit(used), proper_unit_for_byte_size(used), byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), tax); } -void ShenandoahPacer::setup_for_updaterefs() { +void ShenandoahPacer::setup_for_update_refs() { assert(ShenandoahPacing, "Only be here when pacing is enabled"); size_t used = _heap->used(); @@ -123,8 +123,8 @@ void ShenandoahPacer::setup_for_updaterefs() { restart_with(non_taxable, tax); - log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, " - "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + log_info(gc, ergo)("Pacer for Update Refs. Used: %zu%s, Free: %zu%s, " + "Non-Taxable: %zu%s, Alloc Tax Rate: %.1fx", byte_size_in_proper_unit(used), proper_unit_for_byte_size(used), byte_size_in_proper_unit(free), proper_unit_for_byte_size(free), byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable), @@ -148,7 +148,7 @@ void ShenandoahPacer::setup_for_idle() { restart_with(initial, tax); - log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx", + log_info(gc, ergo)("Pacer for Idle. Initial: %zu%s, Alloc Tax Rate: %.1fx", byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial), tax); } @@ -164,7 +164,7 @@ void ShenandoahPacer::setup_for_reset() { size_t initial = _heap->max_capacity(); restart_with(initial, 1.0); - log_info(gc, ergo)("Pacer for Reset. Non-Taxable: " SIZE_FORMAT "%s", + log_info(gc, ergo)("Pacer for Reset. Non-Taxable: %zu%s", byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial)); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp index 44ad2700f8704..fd922d5572960 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp @@ -97,13 +97,13 @@ class ShenandoahPacer : public CHeapObj { void setup_for_idle(); void setup_for_mark(); void setup_for_evac(); - void setup_for_updaterefs(); + void setup_for_update_refs(); void setup_for_reset(); inline void report_mark(size_t words); inline void report_evac(size_t words); - inline void report_updaterefs(size_t words); + inline void report_update_refs(size_t words); inline void report_alloc(size_t words); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp index 38ce12437a38d..881b8a9590ac7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp @@ -38,7 +38,7 @@ inline void ShenandoahPacer::report_evac(size_t words) { report_internal(words); } -inline void ShenandoahPacer::report_updaterefs(size_t words) { +inline void ShenandoahPacer::report_update_refs(size_t words) { report_internal(words); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp index bc2c0b54b5ae5..99c739026cc7d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahParallelCleaning.cpp @@ -23,7 +23,6 @@ */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index f247308ec560d..b25edfd3cb700 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/workerDataArray.inline.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp index 4c8cb8c20570d..7a8fed9f54837 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp @@ -146,7 +146,7 @@ class outputStream; f(degen_gc_final_rebuild_freeset, " Rebuild Free Set") \ f(degen_gc_stw_evac, " Evacuation") \ f(degen_gc_init_update_refs_manage_gclabs, " Manage GCLABs") \ - f(degen_gc_updaterefs, " Update References") \ + f(degen_gc_update_refs, " Update References") \ f(degen_gc_final_update_refs_finish_work, " Finish Work") \ f(degen_gc_final_update_refs_update_region_states," Update Region States") \ f(degen_gc_final_update_refs_trash_cset, " Trash Collection Set") \ diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp index 07d2fd3c4e342..04d38d97f61af 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021, Red Hat, Inc. and/or its affiliates. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "gc/shared/workerThread.hpp" #include "gc/shenandoah/shenandoahGeneration.hpp" @@ -673,10 +672,10 @@ void ShenandoahReferenceProcessor::collect_statistics() { discovered[REF_FINAL], discovered[REF_PHANTOM]); - log_info(gc,ref)("Encountered references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + log_info(gc,ref)("Encountered references: Soft: %zu, Weak: %zu, Final: %zu, Phantom: %zu", encountered[REF_SOFT], encountered[REF_WEAK], encountered[REF_FINAL], encountered[REF_PHANTOM]); - log_info(gc,ref)("Discovered references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + log_info(gc,ref)("Discovered references: Soft: %zu, Weak: %zu, Final: %zu, Phantom: %zu", discovered[REF_SOFT], discovered[REF_WEAK], discovered[REF_FINAL], discovered[REF_PHANTOM]); - log_info(gc,ref)("Enqueued references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + log_info(gc,ref)("Enqueued references: Soft: %zu, Weak: %zu, Final: %zu, Phantom: %zu", enqueued[REF_SOFT], enqueued[REF_WEAK], enqueued[REF_FINAL], enqueued[REF_PHANTOM]); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp index 696e0a9b6956a..a684e8ff228b4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "gc/shenandoah/mode/shenandoahMode.hpp" @@ -64,7 +63,9 @@ void ShenandoahRegulatorThread::regulate_young_and_old_cycles() { if (mode == ShenandoahGenerationalControlThread::none) { if (should_start_metaspace_gc()) { if (request_concurrent_gc(GLOBAL)) { - log_debug(gc)("Heuristics request for global (unload classes) accepted."); + // Some of vmTestbase/metaspace tests depend on following line to count GC cycles + _global_heuristics->log_trigger("%s", GCCause::to_string(GCCause::_metadata_GC_threshold)); + _global_heuristics->cancel_trigger_request(); } } else { if (_young_heuristics->should_start_gc()) { @@ -72,14 +73,17 @@ void ShenandoahRegulatorThread::regulate_young_and_old_cycles() { // begins with a 'bootstrap' cycle that will also collect young. if (start_old_cycle()) { log_debug(gc)("Heuristics request for old collection accepted"); + _young_heuristics->cancel_trigger_request(); } else if (request_concurrent_gc(YOUNG)) { log_debug(gc)("Heuristics request for young collection accepted"); + _young_heuristics->cancel_trigger_request(); } } } } else if (mode == ShenandoahGenerationalControlThread::servicing_old) { if (start_young_cycle()) { log_debug(gc)("Heuristics request to interrupt old for young collection accepted"); + _young_heuristics->cancel_trigger_request(); } } @@ -93,8 +97,10 @@ void ShenandoahRegulatorThread::regulate_young_and_global_cycles() { if (_control_thread->gc_mode() == ShenandoahGenerationalControlThread::none) { if (start_global_cycle()) { log_debug(gc)("Heuristics request for global collection accepted."); + _global_heuristics->cancel_trigger_request(); } else if (start_young_cycle()) { log_debug(gc)("Heuristics request for young collection accepted."); + _young_heuristics->cancel_trigger_request(); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp index 804d643e753be..b3b5109f6b376 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "code/nmethod.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp index b9d7b34cc7c10..3fbf3e8d6d5f7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp @@ -24,7 +24,6 @@ */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp index b217c641824c2..2984debd9f861 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc/shenandoah/shenandoahBarrierSetClone.inline.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp index ec00167f0e3b8..547ebb1a2296f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp index 1b565006f7417..c2bfea664fdcf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp @@ -24,7 +24,6 @@ */ -#include "precompiled.hpp" #include "gc/shared/strongRootsScope.hpp" #include "gc/shared/taskTerminator.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp index 5f09801b92951..b9f52909cbe9f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +23,6 @@ * */ - -#include "precompiled.hpp" - #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahOldGeneration.hpp" @@ -686,7 +684,7 @@ void ShenandoahScanRememberedTask::do_work(uint worker_id) { while (_work_list->next(&assignment)) { ShenandoahHeapRegion* region = assignment._r; log_debug(gc)("ShenandoahScanRememberedTask::do_work(%u), processing slice of region " - SIZE_FORMAT " at offset " SIZE_FORMAT ", size: " SIZE_FORMAT, + "%zu at offset %zu, size: %zu", worker_id, region->index(), assignment._chunk_offset, assignment._chunk_size); if (region->is_old()) { size_t cluster_size = @@ -856,7 +854,7 @@ ShenandoahRegionChunkIterator::ShenandoahRegionChunkIterator(ShenandoahHeap* hea { #ifdef ASSERT size_t expected_chunk_size_words = _clusters_in_smallest_chunk * CardTable::card_size_in_words() * ShenandoahCardCluster::CardsPerCluster; - assert(smallest_chunk_size_words() == expected_chunk_size_words, "_smallest_chunk_size (" SIZE_FORMAT") is not valid because it does not equal (" SIZE_FORMAT ")", + assert(smallest_chunk_size_words() == expected_chunk_size_words, "_smallest_chunk_size (%zu) is not valid because it does not equal (%zu)", smallest_chunk_size_words(), expected_chunk_size_words); #endif assert(_num_groups <= _maximum_groups, @@ -897,13 +895,13 @@ ShenandoahRegionChunkIterator::ShenandoahRegionChunkIterator(ShenandoahHeap* hea } if (_group_entries[_num_groups-1] < _total_chunks) { assert((_total_chunks - _group_entries[_num_groups-1]) * _group_chunk_size[_num_groups-1] + previous_group_span == - heap->num_regions() * words_in_region, "Total region chunks (" SIZE_FORMAT - ") do not span total heap regions (" SIZE_FORMAT ")", _total_chunks, _heap->num_regions()); + heap->num_regions() * words_in_region, "Total region chunks (%zu" + ") do not span total heap regions (%zu)", _total_chunks, _heap->num_regions()); previous_group_span += (_total_chunks - _group_entries[_num_groups-1]) * _group_chunk_size[_num_groups-1]; _group_entries[_num_groups-1] = _total_chunks; } - assert(previous_group_span == heap->num_regions() * words_in_region, "Total region chunks (" SIZE_FORMAT - ") do not span total heap regions (" SIZE_FORMAT "): " SIZE_FORMAT " does not equal " SIZE_FORMAT, + assert(previous_group_span == heap->num_regions() * words_in_region, "Total region chunks (%zu" + ") do not span total heap regions (%zu): %zu does not equal %zu", _total_chunks, _heap->num_regions(), previous_group_span, heap->num_regions() * words_in_region); // Not necessary, but keeps things tidy diff --git a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp index ec00adc4040b1..b0fc55631e067 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,8 +70,8 @@ void ShenandoahScanRemembered::process_clusters(size_t first_cluster, size_t cou const size_t whole_cards = (end_addr - start_addr + CardTable::card_size_in_words() - 1)/CardTable::card_size_in_words(); const size_t end_card_index = start_card_index + whole_cards - 1; - log_debug(gc, remset)("Worker %u: cluster = " SIZE_FORMAT " count = " SIZE_FORMAT " eor = " INTPTR_FORMAT - " start_addr = " INTPTR_FORMAT " end_addr = " INTPTR_FORMAT " cards = " SIZE_FORMAT, + log_debug(gc, remset)("Worker %u: cluster = %zu count = %zu eor = " INTPTR_FORMAT + " start_addr = " INTPTR_FORMAT " end_addr = " INTPTR_FORMAT " cards = %zu", worker_id, first_cluster, count, p2i(end_of_range), p2i(start_addr), p2i(end_addr), whole_cards); // use_write_table states whether we are using the card table that is being @@ -341,7 +342,7 @@ ShenandoahScanRemembered::process_region_slice(ShenandoahHeapRegion *region, siz } } - log_debug(gc)("Remembered set scan processing Region " SIZE_FORMAT ", from " PTR_FORMAT " to " PTR_FORMAT ", using %s table", + log_debug(gc)("Remembered set scan processing Region %zu, from " PTR_FORMAT " to " PTR_FORMAT ", using %s table", region->index(), p2i(start_of_range), p2i(end_of_range), use_write_table? "read/write (updating)": "read (marking)"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSimpleBitMap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSimpleBitMap.cpp index 127e6324fb01e..3f4bbafb755e3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahSimpleBitMap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahSimpleBitMap.cpp @@ -1,5 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahSimpleBitMap.inline.hpp" ShenandoahSimpleBitMap::ShenandoahSimpleBitMap(size_t num_bits) : @@ -95,7 +95,7 @@ size_t ShenandoahSimpleBitMap::count_trailing_ones(idx_t last_idx) const { bool ShenandoahSimpleBitMap::is_forward_consecutive_ones(idx_t start_idx, idx_t count) const { while (count > 0) { - assert((start_idx >= 0) && (start_idx < _num_bits), "precondition: start_idx: " SSIZE_FORMAT ", count: " SSIZE_FORMAT, + assert((start_idx >= 0) && (start_idx < _num_bits), "precondition: start_idx: %zd, count: %zd", start_idx, count); assert(start_idx + count <= (idx_t) _num_bits, "precondition"); size_t array_idx = start_idx >> LogBitsPerWord; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStackWatermark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahStackWatermark.cpp index df05604762268..73449bdae54d1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahStackWatermark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahStackWatermark.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2021, Red Hat, Inc. All rights reserved. - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp index eb185c197bd5d..637bbfcb898a6 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.cpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.cpp index 3901e0c7b7f1a..afeba3dbbf7db 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.cpp @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #include "gc/shenandoah/mode/shenandoahMode.hpp" #include "gc/shenandoah/shenandoahEvacTracker.hpp" #include "gc/shenandoah/shenandoahGenerationalHeap.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp index c226b1ad2545e..9e1777dd82c4f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp @@ -111,12 +111,18 @@ class ShenandoahThreadLocalData { } static char gc_state(Thread* thread) { - assert(thread->is_Java_thread(), "GC state is only synchronized to java threads"); return data(thread)->_gc_state; } + static bool is_gc_state(Thread* thread, ShenandoahHeap::GCState state) { + return (gc_state(thread) & state) != 0; + } + + static bool is_gc_state(ShenandoahHeap::GCState state) { + return is_gc_state(Thread::current(), state); + } + static void initialize_gclab(Thread* thread) { - assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs"); assert(data(thread)->_gclab == nullptr, "Only initialize once"); data(thread)->_gclab = new PLAB(PLAB::min_size()); data(thread)->_gclab_size = 0; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp index 0e6453c9b358c..dd153718c9f1c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTrace.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahEvacInfo.hpp" #include "gc/shenandoah/shenandoahTrace.hpp" #include "jfr/jfrEvents.hpp" @@ -45,7 +44,7 @@ void ShenandoahTracer::send_evacuation_info_event(ShenandoahEvacuationInformatio e.set_regionsPromotedRegular(info->regions_promoted_regular()); e.set_regularPromotedGarbage(info->regular_promoted_garbage()); e.set_regularPromotedFree(info->regular_promoted_free()); - e.set_regionsFreed(info->regions_freed()); + e.set_freeRegions(info->free_regions()); e.set_regionsImmediate(info->regions_immediate()); e.set_immediateBytes(info->immediate_size()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUncommitThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUncommitThread.cpp index 85bb3349d5c97..5f9bc7c9b91c5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUncommitThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUncommitThread.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahUncommitThread.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index f33b76bcd4e1c..24fb56b80377c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2021, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp index 518cb325efbc1..ecca550d5532c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "gc/shared/gcCause.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp index da32601eed7f0..30a677fc12684 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahConcurrentGC.hpp" #include "gc/shenandoah/shenandoahDegeneratedGC.hpp" @@ -82,47 +81,47 @@ void VM_ShenandoahInitMark::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT); set_active_generation(); _gc->entry_init_mark(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahFinalMarkStartEvac::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT); set_active_generation(); _gc->entry_final_mark(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahFullGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL); set_active_generation(); _full_gc->entry_full(_gc_cause); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahDegeneratedGC::doit() { ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT); set_active_generation(); _gc->entry_degenerated(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahInitUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT); set_active_generation(); - _gc->entry_init_updaterefs(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + _gc->entry_init_update_refs(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahFinalUpdateRefs::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT); set_active_generation(); - _gc->entry_final_updaterefs(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + _gc->entry_final_update_refs(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } void VM_ShenandoahFinalRoots::doit() { ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT); set_active_generation(); _gc->entry_final_roots(); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index bde8638140b52..db752395c1bfd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved. * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/tlab_globals.hpp" #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahForwarding.inline.hpp" @@ -383,7 +383,7 @@ class ShenandoahCalculateRegionStatsClosure : public ShenandoahHeapRegionClosure _trashed_regions++; } _regions++; - log_debug(gc)("ShenandoahCalculateRegionStatsClosure: adding " SIZE_FORMAT " for %s Region " SIZE_FORMAT ", yielding: " SIZE_FORMAT, + log_debug(gc)("ShenandoahCalculateRegionStatsClosure: adding %zu for %s Region %zu, yielding: %zu", r->used(), (r->is_humongous() ? "humongous" : "regular"), r->index(), _used); } @@ -422,7 +422,7 @@ class ShenandoahGenerationStatsClosure : public ShenandoahHeapRegionClosure { } static void log_usage(ShenandoahGeneration* generation, ShenandoahCalculateRegionStatsClosure& stats) { - log_debug(gc)("Safepoint verification: %s verified usage: " SIZE_FORMAT "%s, recorded usage: " SIZE_FORMAT "%s", + log_debug(gc)("Safepoint verification: %s verified usage: %zu%s, recorded usage: %zu%s", generation->name(), byte_size_in_proper_unit(generation->used()), proper_unit_for_byte_size(generation->used()), byte_size_in_proper_unit(stats.used()), proper_unit_for_byte_size(stats.used())); @@ -443,12 +443,12 @@ class ShenandoahGenerationStatsClosure : public ShenandoahHeapRegionClosure { label, generation->name(), PROPERFMTARGS(generation_used), PROPERFMTARGS(stats.used())); guarantee(stats.regions() == generation_used_regions, - "%s: generation (%s) used regions (" SIZE_FORMAT ") must equal regions that are in use (" SIZE_FORMAT ")", + "%s: generation (%s) used regions (%zu) must equal regions that are in use (%zu)", label, generation->name(), generation->used_regions(), stats.regions()); size_t generation_capacity = generation->max_capacity(); guarantee(stats.non_trashed_span() <= generation_capacity, - "%s: generation (%s) size spanned by regions (" SIZE_FORMAT ") * region size (" PROPERFMT + "%s: generation (%s) size spanned by regions (%zu) * region size (" PROPERFMT ") must not exceed current capacity (" PROPERFMT ")", label, generation->name(), stats.regions(), PROPERFMTARGS(ShenandoahHeapRegion::region_size_bytes()), PROPERFMTARGS(generation_capacity)); @@ -796,12 +796,12 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label, guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens"); guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize"); - ShenandoahHeap::heap()->propagate_gc_state_to_java_threads(); + ShenandoahHeap::heap()->propagate_gc_state_to_all_threads(); // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/); - log_info(gc,start)("Verify %s, Level " INTX_FORMAT, label, ShenandoahVerifyLevel); + log_info(gc,start)("Verify %s, Level %zd", label, ShenandoahVerifyLevel); // GC state checks { @@ -817,7 +817,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label, break; case _verify_gcstate_updating: enabled = true; - expected = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::UPDATEREFS; + expected = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::UPDATE_REFS; break; case _verify_gcstate_stable: enabled = true; @@ -871,14 +871,14 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label, } if (sizeness != _verify_size_disable) { guarantee(cl.used() == heap_used, - "%s: heap used size must be consistent: heap-used = " SIZE_FORMAT "%s, regions-used = " SIZE_FORMAT "%s", + "%s: heap used size must be consistent: heap-used = %zu%s, regions-used = %zu%s", label, byte_size_in_proper_unit(heap_used), proper_unit_for_byte_size(heap_used), byte_size_in_proper_unit(cl.used()), proper_unit_for_byte_size(cl.used())); } size_t heap_committed = _heap->committed(); guarantee(cl.committed() == heap_committed, - "%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "%s, regions-committed = " SIZE_FORMAT "%s", + "%s: heap committed size must be consistent: heap-committed = %zu%s, regions-committed = %zu%s", label, byte_size_in_proper_unit(heap_committed), proper_unit_for_byte_size(heap_committed), byte_size_in_proper_unit(cl.committed()), proper_unit_for_byte_size(cl.committed())); @@ -1025,7 +1025,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label, if (reg_live != verf_live) { stringStream ss; r->print_on(&ss); - fatal("%s: Live data should match: region-live = " SIZE_FORMAT ", verifier-live = " UINT32_FORMAT "\n%s", + fatal("%s: Live data should match: region-live = %zu, verifier-live = " UINT32_FORMAT "\n%s", label, reg_live, verf_live, ss.freeze()); } } @@ -1034,7 +1034,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label, log_debug(gc)("Safepoint verification finished accumulation of liveness data"); - log_info(gc)("Verify %s, Level " INTX_FORMAT " (" SIZE_FORMAT " reachable, " SIZE_FORMAT " marked)", + log_info(gc)("Verify %s, Level %zd (%zu reachable, %zu marked)", label, ShenandoahVerifyLevel, count_reachable, count_marked); FREE_C_HEAP_ARRAY(ShenandoahLivenessData, ld); @@ -1113,7 +1113,7 @@ void ShenandoahVerifier::verify_before_evacuation() { ); } -void ShenandoahVerifier::verify_before_updaterefs() { +void ShenandoahVerifier::verify_before_update_refs() { verify_at_safepoint( "Before Updating References", _verify_remembered_before_updating_references, // verify read-write remembered set @@ -1128,7 +1128,7 @@ void ShenandoahVerifier::verify_before_updaterefs() { } // We have not yet cleanup (reclaimed) the collection set -void ShenandoahVerifier::verify_after_updaterefs() { +void ShenandoahVerifier::verify_after_update_refs() { verify_at_safepoint( "After Updating References", _verify_remembered_disable, // do not verify remembered set diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp index e49b7b43376bc..a6076ed176bc8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp @@ -214,8 +214,8 @@ class ShenandoahVerifier : public CHeapObj { void verify_after_concmark(); void verify_after_concmark_with_promotions(); void verify_before_evacuation(); - void verify_before_updaterefs(); - void verify_after_updaterefs(); + void verify_before_update_refs(); + void verify_after_update_refs(); void verify_before_fullgc(); void verify_after_fullgc(); void verify_after_degenerated(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp index 4a49d28ea861b..d6c47339f28a9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkGroup.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" @@ -73,7 +73,6 @@ ShenandoahPushWorkerScope::~ShenandoahPushWorkerScope() { } void ShenandoahWorkerThreads::on_create_worker(WorkerThread* worker) { - ShenandoahThreadLocalData::create(worker); if (_initialize_gclab) { ShenandoahThreadLocalData::initialize_gclab(worker); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp index 30651f0ccf1a4..87095e87406f3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp index 59c33a015c24f..8663515d019d0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "gc/shenandoah/shenandoahAgeCensus.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" diff --git a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp index 9c16714b26e3f..87bfc1f9c66c9 100644 --- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp +++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "c1/c1_FrameMap.hpp" #include "c1/c1_LIR.hpp" #include "c1/c1_LIRAssembler.hpp" diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp index 3f9c09f1c8c07..650918e2d30ab 100644 --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "classfile/javaClasses.hpp" #include "gc/z/c2/zBarrierSetC2.hpp" @@ -29,7 +28,6 @@ #include "gc/z/zBarrierSetAssembler.hpp" #include "gc/z/zBarrierSetRuntime.hpp" #include "opto/arraycopynode.hpp" -#include "opto/addnode.hpp" #include "opto/block.hpp" #include "opto/compile.hpp" #include "opto/graphKit.hpp" @@ -39,7 +37,6 @@ #include "opto/node.hpp" #include "opto/output.hpp" #include "opto/regalloc.hpp" -#include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/type.hpp" #include "utilities/debug.hpp" @@ -476,267 +473,10 @@ void ZBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* a #undef XTOP -// == Dominating barrier elision == - -static bool block_has_safepoint(const Block* block, uint from, uint to) { - for (uint i = from; i < to; i++) { - if (block->get_node(i)->is_MachSafePoint()) { - // Safepoint found - return true; - } - } - - // Safepoint not found - return false; -} - -static bool block_has_safepoint(const Block* block) { - return block_has_safepoint(block, 0, block->number_of_nodes()); -} - -static uint block_index(const Block* block, const Node* node) { - for (uint j = 0; j < block->number_of_nodes(); ++j) { - if (block->get_node(j) == node) { - return j; - } - } - ShouldNotReachHere(); - return 0; -} - -// Look through various node aliases -static const Node* look_through_node(const Node* node) { - while (node != nullptr) { - const Node* new_node = node; - if (node->is_Mach()) { - const MachNode* const node_mach = node->as_Mach(); - if (node_mach->ideal_Opcode() == Op_CheckCastPP) { - new_node = node->in(1); - } - if (node_mach->is_SpillCopy()) { - new_node = node->in(1); - } - } - if (new_node == node || new_node == nullptr) { - break; - } else { - node = new_node; - } - } - - return node; -} - -// Whether the given offset is undefined. -static bool is_undefined(intptr_t offset) { - return offset == Type::OffsetTop; -} - -// Whether the given offset is unknown. -static bool is_unknown(intptr_t offset) { - return offset == Type::OffsetBot; -} - -// Whether the given offset is concrete (defined and compile-time known). -static bool is_concrete(intptr_t offset) { - return !is_undefined(offset) && !is_unknown(offset); -} - -// Compute base + offset components of the memory address accessed by mach. -// Return a node representing the base address, or null if the base cannot be -// found or the offset is undefined or a concrete negative value. If a non-null -// base is returned, the offset is a concrete, nonnegative value or unknown. -static const Node* get_base_and_offset(const MachNode* mach, intptr_t& offset) { - const TypePtr* adr_type = nullptr; - offset = 0; - const Node* base = mach->get_base_and_disp(offset, adr_type); - - if (base == nullptr || base == NodeSentinel) { - return nullptr; - } - - if (offset == 0 && base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_AddP) { - // The memory address is computed by 'base' and fed to 'mach' via an - // indirect memory operand (indicated by offset == 0). The ultimate base and - // offset can be fetched directly from the inputs and Ideal type of 'base'. - offset = base->bottom_type()->isa_oopptr()->offset(); - // Even if 'base' is not an Ideal AddP node anymore, Matcher::ReduceInst() - // guarantees that the base address is still available at the same slot. - base = base->in(AddPNode::Base); - assert(base != nullptr, ""); - } - - if (is_undefined(offset) || (is_concrete(offset) && offset < 0)) { - return nullptr; - } - - return look_through_node(base); -} - -// Whether a phi node corresponds to an array allocation. -// This test is incomplete: in some edge cases, it might return false even -// though the node does correspond to an array allocation. -static bool is_array_allocation(const Node* phi) { - precond(phi->is_Phi()); - // Check whether phi has a successor cast (CheckCastPP) to Java array pointer, - // possibly below spill copies and other cast nodes. Limit the exploration to - // a single path from the phi node consisting of these node types. - const Node* current = phi; - while (true) { - const Node* next = nullptr; - for (DUIterator_Fast imax, i = current->fast_outs(imax); i < imax; i++) { - if (!current->fast_out(i)->isa_Mach()) { - continue; - } - const MachNode* succ = current->fast_out(i)->as_Mach(); - if (succ->ideal_Opcode() == Op_CheckCastPP) { - if (succ->get_ptr_type()->isa_aryptr()) { - // Cast to Java array pointer: phi corresponds to an array allocation. - return true; - } - // Other cast: record as candidate for further exploration. - next = succ; - } else if (succ->is_SpillCopy() && next == nullptr) { - // Spill copy, and no better candidate found: record as candidate. - next = succ; - } - } - if (next == nullptr) { - // No evidence found that phi corresponds to an array allocation, and no - // candidates available to continue exploring. - return false; - } - // Continue exploring from the best candidate found. - current = next; - } - ShouldNotReachHere(); -} - -// Match the phi node that connects a TLAB allocation fast path with its slowpath -static bool is_allocation(const Node* node) { - if (node->req() != 3) { - return false; - } - const Node* const fast_node = node->in(2); - if (!fast_node->is_Mach()) { - return false; - } - const MachNode* const fast_mach = fast_node->as_Mach(); - if (fast_mach->ideal_Opcode() != Op_LoadP) { - return false; - } - const TypePtr* const adr_type = nullptr; - intptr_t offset; - const Node* const base = get_base_and_offset(fast_mach, offset); - if (base == nullptr || !base->is_Mach() || !is_concrete(offset)) { - return false; - } - const MachNode* const base_mach = base->as_Mach(); - if (base_mach->ideal_Opcode() != Op_ThreadLocal) { - return false; - } - return offset == in_bytes(Thread::tlab_top_offset()); -} - -static void elide_mach_barrier(MachNode* mach) { +void ZBarrierSetC2::elide_dominated_barrier(MachNode* mach) const { mach->set_barrier_data(ZBarrierElided); } -void ZBarrierSetC2::analyze_dominating_barriers_impl(Node_List& accesses, Node_List& access_dominators) const { - Compile* const C = Compile::current(); - PhaseCFG* const cfg = C->cfg(); - - for (uint i = 0; i < accesses.size(); i++) { - MachNode* const access = accesses.at(i)->as_Mach(); - intptr_t access_offset; - const Node* const access_obj = get_base_and_offset(access, access_offset); - Block* const access_block = cfg->get_block_for_node(access); - const uint access_index = block_index(access_block, access); - - if (access_obj == nullptr) { - // No information available - continue; - } - - for (uint j = 0; j < access_dominators.size(); j++) { - const Node* const mem = access_dominators.at(j); - if (mem->is_Phi()) { - // Allocation node - if (mem != access_obj) { - continue; - } - if (is_unknown(access_offset) && !is_array_allocation(mem)) { - // The accessed address has an unknown offset, but the allocated - // object cannot be determined to be an array. Avoid eliding in this - // case, to be on the safe side. - continue; - } - assert((is_concrete(access_offset) && access_offset >= 0) || (is_unknown(access_offset) && is_array_allocation(mem)), - "candidate allocation-dominated access offsets must be either concrete and nonnegative, or unknown (for array allocations only)"); - } else { - // Access node - const MachNode* const mem_mach = mem->as_Mach(); - intptr_t mem_offset; - const Node* const mem_obj = get_base_and_offset(mem_mach, mem_offset); - - if (mem_obj == nullptr || - !is_concrete(access_offset) || - !is_concrete(mem_offset)) { - // No information available - continue; - } - - if (mem_obj != access_obj || mem_offset != access_offset) { - // Not the same addresses, not a candidate - continue; - } - assert(is_concrete(access_offset) && access_offset >= 0, - "candidate non-allocation-dominated access offsets must be concrete and nonnegative"); - } - - Block* mem_block = cfg->get_block_for_node(mem); - const uint mem_index = block_index(mem_block, mem); - - if (access_block == mem_block) { - // Earlier accesses in the same block - if (mem_index < access_index && !block_has_safepoint(mem_block, mem_index + 1, access_index)) { - elide_mach_barrier(access); - } - } else if (mem_block->dominates(access_block)) { - // Dominating block? Look around for safepoints - ResourceMark rm; - Block_List stack; - VectorSet visited; - stack.push(access_block); - bool safepoint_found = block_has_safepoint(access_block); - while (!safepoint_found && stack.size() > 0) { - const Block* const block = stack.pop(); - if (visited.test_set(block->_pre_order)) { - continue; - } - if (block_has_safepoint(block)) { - safepoint_found = true; - break; - } - if (block == mem_block) { - continue; - } - - // Push predecessor blocks - for (uint p = 1; p < block->num_preds(); ++p) { - Block* const pred = cfg->get_block_for_node(block->pred(p)); - stack.push(pred); - } - } - - if (!safepoint_found) { - elide_mach_barrier(access); - } - } - } - } -} - void ZBarrierSetC2::analyze_dominating_barriers() const { ResourceMark rm; Compile* const C = Compile::current(); @@ -806,9 +546,9 @@ void ZBarrierSetC2::analyze_dominating_barriers() const { } // Step 2 - Find dominating accesses or allocations for each access - analyze_dominating_barriers_impl(loads, load_dominators); - analyze_dominating_barriers_impl(stores, store_dominators); - analyze_dominating_barriers_impl(atomics, atomic_dominators); + elide_dominated_barriers(loads, load_dominators); + elide_dominated_barriers(stores, store_dominators); + elide_dominated_barriers(atomics, atomic_dominators); } void ZBarrierSetC2::eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const { diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp index 2aa4d0daa85c9..370a543f381b2 100644 --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,6 @@ class ZStoreBarrierStubC2 : public ZBarrierStubC2 { class ZBarrierSetC2 : public BarrierSetC2 { private: - void analyze_dominating_barriers_impl(Node_List& accesses, Node_List& access_dominators) const; void analyze_dominating_barriers() const; protected: @@ -128,6 +127,7 @@ class ZBarrierSetC2 : public BarrierSetC2 { virtual void clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const; + virtual void elide_dominated_barrier(MachNode* mach) const; virtual void late_barrier_analysis() const; virtual int estimate_stub_size() const; virtual void emit_stubs(CodeBuffer& cb) const; diff --git a/src/hotspot/share/gc/z/vmStructs_z.cpp b/src/hotspot/share/gc/z/vmStructs_z.cpp index 2ae826663d222..f77253202ba0b 100644 --- a/src/hotspot/share/gc/z/vmStructs_z.cpp +++ b/src/hotspot/share/gc/z/vmStructs_z.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/vmStructs_z.hpp" #include "gc/z/zAddress.hpp" diff --git a/src/hotspot/share/gc/z/zAbort.cpp b/src/hotspot/share/gc/z/zAbort.cpp index 938e77b7d8007..7e4f23c1c7a8a 100644 --- a/src/hotspot/share/gc/z/zAbort.cpp +++ b/src/hotspot/share/gc/z/zAbort.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAbort.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/gc/z/zAddress.cpp b/src/hotspot/share/gc/z/zAddress.cpp index 1cd33e44a05d1..59489f62372c4 100644 --- a/src/hotspot/share/gc/z/zAddress.cpp +++ b/src/hotspot/share/gc/z/zAddress.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.inline.hpp" @@ -106,7 +105,7 @@ void ZGlobalsPointers::initialize() { // Check max supported heap size if (MaxHeapSize > ZAddressOffsetMax) { vm_exit_during_initialization( - err_msg("Java heap too large (max supported heap size is " SIZE_FORMAT "G)", + err_msg("Java heap too large (max supported heap size is %zuG)", ZAddressOffsetMax / G)); } diff --git a/src/hotspot/share/gc/z/zAddressSpaceLimit.cpp b/src/hotspot/share/gc/z/zAddressSpaceLimit.cpp index 41ae19566b980..fc42d9f3db1fa 100644 --- a/src/hotspot/share/gc/z/zAddressSpaceLimit.cpp +++ b/src/hotspot/share/gc/z/zAddressSpaceLimit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddressSpaceLimit.hpp" #include "gc/z/zGlobals.hpp" @@ -40,12 +39,6 @@ static size_t address_space_limit() { return SIZE_MAX; } -size_t ZAddressSpaceLimit::mark_stack() { - // Allow mark stacks to occupy 10% of the address space - const size_t limit = address_space_limit() / 10; - return align_up(limit, ZMarkStackSpaceExpandSize); -} - size_t ZAddressSpaceLimit::heap() { // Allow the heap to occupy 50% of the address space const size_t limit = address_space_limit() / MaxVirtMemFraction; diff --git a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp index d8e7e7cfd3617..66e01f0ebb08c 100644 --- a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp +++ b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp @@ -29,7 +29,6 @@ class ZAddressSpaceLimit : public AllStatic { public: - static size_t mark_stack(); static size_t heap(); }; diff --git a/src/hotspot/share/gc/z/zAllocator.cpp b/src/hotspot/share/gc/z/zAllocator.cpp index f75a67fd2117c..87e1f6f76f941 100644 --- a/src/hotspot/share/gc/z/zAllocator.cpp +++ b/src/hotspot/share/gc/z/zAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAllocator.hpp" #include "gc/z/zObjectAllocator.hpp" diff --git a/src/hotspot/share/gc/z/zArguments.cpp b/src/hotspot/share/gc/z/zArguments.cpp index 331ca9f7c9423..ee761d03e1848 100644 --- a/src/hotspot/share/gc/z/zArguments.cpp +++ b/src/hotspot/share/gc/z/zArguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddressSpaceLimit.hpp" #include "gc/z/zArguments.hpp" #include "gc/z/zCollectedHeap.hpp" @@ -121,15 +120,6 @@ void ZArguments::select_max_gc_threads() { void ZArguments::initialize() { GCArguments::initialize(); - // Check mark stack size - const size_t mark_stack_space_limit = ZAddressSpaceLimit::mark_stack(); - if (ZMarkStackSpaceLimit > mark_stack_space_limit) { - if (!FLAG_IS_DEFAULT(ZMarkStackSpaceLimit)) { - vm_exit_during_initialization("ZMarkStackSpaceLimit too large for limited address space"); - } - FLAG_SET_DEFAULT(ZMarkStackSpaceLimit, mark_stack_space_limit); - } - // Enable NUMA by default if (FLAG_IS_DEFAULT(UseNUMA)) { FLAG_SET_DEFAULT(UseNUMA, true); @@ -142,10 +132,6 @@ void ZArguments::initialize() { FLAG_SET_ERGO_IF_DEFAULT(ZCollectionIntervalMajor, ZCollectionInterval); } - if (FLAG_IS_DEFAULT(ZFragmentationLimit)) { - FLAG_SET_DEFAULT(ZFragmentationLimit, 5.0); - } - // Set medium page size here because MaxTenuringThreshold may use it. ZHeuristics::set_medium_page_size(); @@ -180,7 +166,7 @@ void ZArguments::initialize() { // Large page size must match granule size if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != ZGranuleSize) { vm_exit_during_initialization(err_msg("Incompatible -XX:LargePageSizeInBytes, only " - SIZE_FORMAT "M large pages are supported by ZGC", + "%zuM large pages are supported by ZGC", ZGranuleSize / M)); } diff --git a/src/hotspot/share/gc/z/zBarrier.cpp b/src/hotspot/share/gc/z/zBarrier.cpp index 7d7f1284bdfdc..2b3f3f25fa64e 100644 --- a/src/hotspot/share/gc/z/zBarrier.cpp +++ b/src/hotspot/share/gc/z/zBarrier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zBarrier.inline.hpp" diff --git a/src/hotspot/share/gc/z/zBarrierSet.cpp b/src/hotspot/share/gc/z/zBarrierSet.cpp index 4ce591a507a67..a4893fc351aa8 100644 --- a/src/hotspot/share/gc/z/zBarrierSet.cpp +++ b/src/hotspot/share/gc/z/zBarrierSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zBarrierSet.hpp" #include "gc/z/zBarrierSetAssembler.hpp" #include "gc/z/zBarrierSetNMethod.hpp" @@ -102,7 +101,7 @@ void ZBarrierSet::on_thread_attach(Thread* thread) { void ZBarrierSet::on_thread_detach(Thread* thread) { // Flush and free any remaining mark stacks - ZHeap::heap()->mark_flush_and_free(thread); + ZHeap::heap()->mark_flush(thread); } static void deoptimize_allocation(JavaThread* thread) { diff --git a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp index 174cdfd9e909d..f7baf85efbfa1 100644 --- a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp @@ -473,11 +473,7 @@ template inline oop ZBarrierSet::AccessBarrier::oop_load_not_in_heap(oop* p) { verify_decorators_absent(); - if (HasDecorator::value) { - return ZNMethod::load_oop(p, decorators); - } else { - return oop_load_not_in_heap((zpointer*)p); - } + return oop_load_not_in_heap((zpointer*)p); } template diff --git a/src/hotspot/share/gc/z/zBarrierSetAssembler.cpp b/src/hotspot/share/gc/z/zBarrierSetAssembler.cpp index e68142f0778ba..b46810c7c00a2 100644 --- a/src/hotspot/share/gc/z/zBarrierSetAssembler.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetAssembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zBarrierSetAssembler.hpp" #include "gc/z/zThreadLocalData.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp index 33894f166a3e9..0d6be2b789f77 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/z/zAddress.hpp" @@ -98,3 +97,11 @@ int* ZBarrierSetNMethod::disarmed_guard_value_address() const { ByteSize ZBarrierSetNMethod::thread_disarmed_guard_value_offset() const { return ZThreadLocalData::nmethod_disarmed_offset(); } + +oop ZBarrierSetNMethod::oop_load_no_keepalive(const nmethod* nm, int index) { + return ZNMethod::oop_load_no_keepalive(nm, index); +} + +oop ZBarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) { + return ZNMethod::oop_load_phantom(nm, index); +} diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp index ed9f06672e745..780d3772123e3 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.hpp @@ -36,6 +36,9 @@ class ZBarrierSetNMethod : public BarrierSetNMethod { public: virtual ByteSize thread_disarmed_guard_value_offset() const; virtual int* disarmed_guard_value_address() const; + + virtual oop oop_load_no_keepalive(const nmethod* nm, int index); + virtual oop oop_load_phantom(const nmethod* nm, int index); }; #endif // SHARE_GC_Z_ZBARRIERSETNMETHOD_HPP diff --git a/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp b/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp index 935238c4e4f54..78376149d9082 100644 --- a/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zBarrier.inline.hpp" #include "gc/z/zBarrierSetRuntime.hpp" #include "oops/access.hpp" diff --git a/src/hotspot/share/gc/z/zBarrierSetStackChunk.cpp b/src/hotspot/share/gc/z/zBarrierSetStackChunk.cpp index e33b86ef22b85..22b766ecd1a2d 100644 --- a/src/hotspot/share/gc/z/zBarrierSetStackChunk.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetStackChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/z/zBarrierSetStackChunk.hpp" #include "gc/z/zContinuation.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/gc/z/zBreakpoint.cpp b/src/hotspot/share/gc/z/zBreakpoint.cpp index f9db1d54c8cc9..00e91c2c28aab 100644 --- a/src/hotspot/share/gc/z/zBreakpoint.cpp +++ b/src/hotspot/share/gc/z/zBreakpoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/z/zBreakpoint.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/gc/z/zCPU.cpp b/src/hotspot/share/gc/z/zCPU.cpp index f6aaa96476f75..8ba8ea9986365 100644 --- a/src/hotspot/share/gc/z/zCPU.cpp +++ b/src/hotspot/share/gc/z/zCPU.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zCPU.inline.hpp" #include "memory/padded.inline.hpp" diff --git a/src/hotspot/share/gc/z/zCollectedHeap.cpp b/src/hotspot/share/gc/z/zCollectedHeap.cpp index 8afefd5a7cc1c..c43090f9699fc 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.cpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcLogPrecious.hpp" @@ -363,12 +362,12 @@ void ZCollectedHeap::print_on_error(outputStream* st) const { st->print_cr("ZGC Globals:"); st->print_cr(" Young Collection: %s/%u", ZGeneration::young()->phase_to_string(), ZGeneration::young()->seqnum()); st->print_cr(" Old Collection: %s/%u", ZGeneration::old()->phase_to_string(), ZGeneration::old()->seqnum()); - st->print_cr(" Offset Max: " SIZE_FORMAT "%s (" PTR_FORMAT ")", + st->print_cr(" Offset Max: %zu%s (" PTR_FORMAT ")", byte_size_in_exact_unit(ZAddressOffsetMax), exact_unit_for_byte_size(ZAddressOffsetMax), ZAddressOffsetMax); - st->print_cr(" Page Size Small: " SIZE_FORMAT "M", ZPageSizeSmall / M); - st->print_cr(" Page Size Medium: " SIZE_FORMAT "M", ZPageSizeMedium / M); + st->print_cr(" Page Size Small: %zuM", ZPageSizeSmall / M); + st->print_cr(" Page Size Medium: %zuM", ZPageSizeMedium / M); st->cr(); st->print_cr("ZGC Metadata Bits:"); st->print_cr(" LoadGood: " PTR_FORMAT, ZPointerLoadGoodMask); diff --git a/src/hotspot/share/gc/z/zContinuation.cpp b/src/hotspot/share/gc/z/zContinuation.cpp index 3a4390b472bbd..6c02f64528c28 100644 --- a/src/hotspot/share/gc/z/zContinuation.cpp +++ b/src/hotspot/share/gc/z/zContinuation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zBarrier.inline.hpp" #include "gc/z/zContinuation.inline.hpp" diff --git a/src/hotspot/share/gc/z/zDirector.cpp b/src/hotspot/share/gc/z/zDirector.cpp index 48e426f068aa6..f1256eecd19bf 100644 --- a/src/hotspot/share/gc/z/zDirector.cpp +++ b/src/hotspot/share/gc/z/zDirector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zCollectedHeap.hpp" #include "gc/z/zDirector.hpp" @@ -194,7 +193,7 @@ static ZDriverRequest rule_minor_allocation_rate_dynamic(const ZDirectorStats& s const double time_until_gc = time_until_oom - actual_gc_duration; log_debug(gc, director)("Rule Minor: Allocation Rate (Dynamic GC Workers), " - "MaxAllocRate: %.1fMB/s (+/-%.1f%%), Free: " SIZE_FORMAT "MB, GCCPUTime: %.3f, " + "MaxAllocRate: %.1fMB/s (+/-%.1f%%), Free: %zuMB, GCCPUTime: %.3f, " "GCDuration: %.3fs, TimeUntilOOM: %.3fs, TimeUntilGC: %.3fs, GCWorkers: %u", alloc_rate / M, alloc_rate_sd_percent * 100, @@ -288,7 +287,7 @@ static bool rule_minor_allocation_rate_static(const ZDirectorStats& stats) { // time and end up starting the GC too late in the next interval. const double time_until_gc = time_until_oom - gc_duration; - log_debug(gc, director)("Rule Minor: Allocation Rate (Static GC Workers), MaxAllocRate: %.1fMB/s, Free: " SIZE_FORMAT "MB, GCDuration: %.3fs, TimeUntilGC: %.3fs", + log_debug(gc, director)("Rule Minor: Allocation Rate (Static GC Workers), MaxAllocRate: %.1fMB/s, Free: %zuMB, GCDuration: %.3fs, TimeUntilGC: %.3fs", max_alloc_rate / M, free / M, gc_duration, time_until_gc); return time_until_gc <= 0; @@ -386,7 +385,7 @@ static bool rule_minor_high_usage(const ZDirectorStats& stats) { const double free_percent = percent_of(free, soft_max_capacity); auto print_function = [&](size_t free, double free_percent) { - log_debug(gc, director)("Rule Minor: High Usage, Free: " SIZE_FORMAT "MB(%.1f%%)", + log_debug(gc, director)("Rule Minor: High Usage, Free: %zuMB(%.1f%%)", free / M, free_percent); }; @@ -430,7 +429,7 @@ static bool rule_major_warmup(const ZDirectorStats& stats) { const double used_threshold_percent = (stats._old_stats._cycle._nwarmup_cycles + 1) * 0.1; const size_t used_threshold = (size_t)(soft_max_capacity * used_threshold_percent); - log_debug(gc, director)("Rule Major: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB", + log_debug(gc, director)("Rule Major: Warmup %.0f%%, Used: %zuMB, UsedThreshold: %zuMB", used_threshold_percent * 100, used / M, used_threshold / M); return used >= used_threshold; @@ -593,7 +592,7 @@ static bool rule_major_proactive(const ZDirectorStats& stats) { const double time_since_last_gc_threshold = 5 * 60; // 5 minutes if (used < used_threshold && time_since_last_gc < time_since_last_gc_threshold) { // Don't even consider doing a proactive GC - log_debug(gc, director)("Rule Major: Proactive, UsedUntilEnabled: " SIZE_FORMAT "MB, TimeUntilEnabled: %.3fs", + log_debug(gc, director)("Rule Major: Proactive, UsedUntilEnabled: %zuMB, TimeUntilEnabled: %.3fs", (used_threshold - used) / M, time_since_last_gc_threshold - time_since_last_gc); return false; diff --git a/src/hotspot/share/gc/z/zDriver.cpp b/src/hotspot/share/gc/z/zDriver.cpp index c91de172fee46..e8f7af179cb4c 100644 --- a/src/hotspot/share/gc/z/zDriver.cpp +++ b/src/hotspot/share/gc/z/zDriver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcId.hpp" diff --git a/src/hotspot/share/gc/z/zDriverPort.cpp b/src/hotspot/share/gc/z/zDriverPort.cpp index 28c8fbc732cd6..02732dd149024 100644 --- a/src/hotspot/share/gc/z/zDriverPort.cpp +++ b/src/hotspot/share/gc/z/zDriverPort.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zDriverPort.hpp" #include "gc/z/zFuture.inline.hpp" #include "gc/z/zList.inline.hpp" diff --git a/src/hotspot/share/gc/z/zErrno.cpp b/src/hotspot/share/gc/z/zErrno.cpp index a3847181c2c84..fc9b1706ce9ee 100644 --- a/src/hotspot/share/gc/z/zErrno.cpp +++ b/src/hotspot/share/gc/z/zErrno.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zErrno.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/share/gc/z/zForwarding.cpp b/src/hotspot/share/gc/z/zForwarding.cpp index 622f271a6d309..df0e986d2c596 100644 --- a/src/hotspot/share/gc/z/zForwarding.cpp +++ b/src/hotspot/share/gc/z/zForwarding.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zCollectedHeap.hpp" diff --git a/src/hotspot/share/gc/z/zForwardingAllocator.cpp b/src/hotspot/share/gc/z/zForwardingAllocator.cpp index 617745dc08d02..0b4e6c7b08c54 100644 --- a/src/hotspot/share/gc/z/zForwardingAllocator.cpp +++ b/src/hotspot/share/gc/z/zForwardingAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zForwardingAllocator.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/gc/z/zGCIdPrinter.cpp b/src/hotspot/share/gc/z/zGCIdPrinter.cpp index 80ca72e4f48de..25141264f2cd3 100644 --- a/src/hotspot/share/gc/z/zGCIdPrinter.cpp +++ b/src/hotspot/share/gc/z/zGCIdPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zGCIdPrinter.hpp" #include "include/jvm.h" diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 655f47ba49cd8..0dc8e93b8e716 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" #include "gc/shared/classUnloadingContext.hpp" @@ -132,10 +131,6 @@ ZGeneration::ZGeneration(ZGenerationId id, ZPageTable* page_table, ZPageAllocato _stat_relocation(), _gc_timer(nullptr) {} -bool ZGeneration::is_initialized() const { - return _mark.is_initialized(); -} - ZWorkers* ZGeneration::workers() { return &_workers; } @@ -152,8 +147,8 @@ void ZGeneration::threads_do(ThreadClosure* tc) const { _workers.threads_do(tc); } -void ZGeneration::mark_flush_and_free(Thread* thread) { - _mark.flush_and_free(thread); +void ZGeneration::mark_flush(Thread* thread) { + _mark.flush(thread); } void ZGeneration::mark_free() { @@ -361,7 +356,7 @@ void ZGeneration::log_phase_switch(Phase from, Phase to) { index += 1; } - assert(index < ARRAY_SIZE(str), "OOB: " SIZE_FORMAT " < " SIZE_FORMAT, index, ARRAY_SIZE(str)); + assert(index < ARRAY_SIZE(str), "OOB: %zu < %zu", index, ARRAY_SIZE(str)); Events::log_zgc_phase_switch("%-21s %4u", str[index], seqnum()); } @@ -796,8 +791,8 @@ uint ZGenerationYoung::compute_tenuring_threshold(ZRelocationSetSelectorStats st // if the GC is finding it hard to keep up with the allocation rate. const double tenuring_threshold_raw = young_life_decay_factor * young_log_residency; - log_trace(gc, reloc)("Young Allocated: " SIZE_FORMAT "M", young_allocated / M); - log_trace(gc, reloc)("Young Garbage: " SIZE_FORMAT "M", young_garbage / M); + log_trace(gc, reloc)("Young Allocated: %zuM", young_allocated / M); + log_trace(gc, reloc)("Young Garbage: %zuM", young_garbage / M); log_debug(gc, reloc)("Allocated To Garbage: %.1f", allocated_garbage_ratio); log_trace(gc, reloc)("Young Log: %.1f", young_log); log_trace(gc, reloc)("Young Residency Reciprocal: %.1f", young_residency_reciprocal); diff --git a/src/hotspot/share/gc/z/zGeneration.hpp b/src/hotspot/share/gc/z/zGeneration.hpp index 3e18919eee43a..2670ab5169909 100644 --- a/src/hotspot/share/gc/z/zGeneration.hpp +++ b/src/hotspot/share/gc/z/zGeneration.hpp @@ -99,8 +99,6 @@ class ZGeneration { void log_phase_switch(Phase from, Phase to); public: - bool is_initialized() const; - // GC phases void set_phase(Phase new_phase); bool is_phase_relocate() const; @@ -161,7 +159,7 @@ class ZGeneration { void mark_object(zaddress addr); template void mark_object_if_active(zaddress addr); - void mark_flush_and_free(Thread* thread); + void mark_flush(Thread* thread); // Relocation void synchronize_relocation(); diff --git a/src/hotspot/share/gc/z/zGlobals.cpp b/src/hotspot/share/gc/z/zGlobals.cpp index 460ed4f09fe5d..2cb9a70eb7e10 100644 --- a/src/hotspot/share/gc/z/zGlobals.cpp +++ b/src/hotspot/share/gc/z/zGlobals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zGlobals.hpp" size_t ZPageSizeMediumShift; diff --git a/src/hotspot/share/gc/z/zGlobals.hpp b/src/hotspot/share/gc/z/zGlobals.hpp index f7c0a3eaa2698..918301b18532c 100644 --- a/src/hotspot/share/gc/z/zGlobals.hpp +++ b/src/hotspot/share/gc/z/zGlobals.hpp @@ -67,17 +67,6 @@ const int ZObjectAlignmentLarge = 1 << ZObjectAlignmentLargeShif const size_t ZCacheLineSize = ZPlatformCacheLineSize; #define ZCACHE_ALIGNED ATTRIBUTE_ALIGNED(ZCacheLineSize) -// Mark stack space -const size_t ZMarkStackSpaceExpandSize = (size_t)1 << 25; // 32M - -// Mark stack and magazine sizes -const size_t ZMarkStackSizeShift = 11; // 2K -const size_t ZMarkStackSize = (size_t)1 << ZMarkStackSizeShift; -const size_t ZMarkStackHeaderSize = (size_t)1 << 4; // 16B -const size_t ZMarkStackSlots = (ZMarkStackSize - ZMarkStackHeaderSize) / sizeof(uintptr_t); -const size_t ZMarkStackMagazineSize = (size_t)1 << 15; // 32K -const size_t ZMarkStackMagazineSlots = (ZMarkStackMagazineSize / ZMarkStackSize) - 1; - // Mark stripe size const size_t ZMarkStripeShift = ZGranuleSizeShift; diff --git a/src/hotspot/share/gc/z/zHeap.cpp b/src/hotspot/share/gc/z/zHeap.cpp index d29a5d15795f4..bca9e2f8c4156 100644 --- a/src/hotspot/share/gc/z/zHeap.cpp +++ b/src/hotspot/share/gc/z/zHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcLogPrecious.hpp" @@ -69,13 +68,13 @@ ZHeap::ZHeap() assert(_heap == nullptr, "Already initialized"); _heap = this; - if (!_page_allocator.is_initialized() || !_young.is_initialized() || !_old.is_initialized()) { + if (!_page_allocator.is_initialized()) { return; } // Prime cache if (!_page_allocator.prime_cache(_old.workers(), InitialHeapSize)) { - ZInitialize::error("Failed to allocate initial Java heap (" SIZE_FORMAT "M)", InitialHeapSize / M); + ZInitialize::error("Failed to allocate initial Java heap (%zuM)", InitialHeapSize / M); return; } @@ -238,7 +237,7 @@ void ZHeap::undo_alloc_page(ZPage* page) { assert(page->is_allocating(), "Invalid page state"); ZStatInc(ZCounterUndoPageAllocation); - log_trace(gc)("Undo page allocation, thread: " PTR_FORMAT " (%s), page: " PTR_FORMAT ", size: " SIZE_FORMAT, + log_trace(gc)("Undo page allocation, thread: " PTR_FORMAT " (%s), page: " PTR_FORMAT ", size: %zu", p2i(Thread::current()), ZUtils::thread_name(), p2i(page), page->size()); free_page(page, false /* allow_defragment */); @@ -272,9 +271,9 @@ void ZHeap::keep_alive(oop obj) { ZBarrier::mark(addr); } -void ZHeap::mark_flush_and_free(Thread* thread) { - _young.mark_flush_and_free(thread); - _old.mark_flush_and_free(thread); +void ZHeap::mark_flush(Thread* thread) { + _young.mark_flush(thread); + _old.mark_flush(thread); } bool ZHeap::is_allocating(zaddress addr) const { @@ -320,7 +319,7 @@ ZServiceabilityCounters* ZHeap::serviceability_counters() { } void ZHeap::print_on(outputStream* st) const { - st->print_cr(" ZHeap used " SIZE_FORMAT "M, capacity " SIZE_FORMAT "M, max capacity " SIZE_FORMAT "M", + st->print_cr(" ZHeap used %zuM, capacity %zuM, max capacity %zuM", used() / M, capacity() / M, max_capacity() / M); diff --git a/src/hotspot/share/gc/z/zHeap.hpp b/src/hotspot/share/gc/z/zHeap.hpp index 955cdf6fd79e4..4bf4727c3e35c 100644 --- a/src/hotspot/share/gc/z/zHeap.hpp +++ b/src/hotspot/share/gc/z/zHeap.hpp @@ -99,7 +99,7 @@ class ZHeap { bool is_object_live(zaddress addr) const; bool is_object_strongly_live(zaddress addr) const; void keep_alive(oop obj); - void mark_flush_and_free(Thread* thread); + void mark_flush(Thread* thread); // Page allocation ZPage* alloc_page(ZPageType type, size_t size, ZAllocationFlags flags, ZPageAge age); diff --git a/src/hotspot/share/gc/z/zHeapIterator.cpp b/src/hotspot/share/gc/z/zHeapIterator.cpp index e149a976add92..63bede6143ba1 100644 --- a/src/hotspot/share/gc/z/zHeapIterator.cpp +++ b/src/hotspot/share/gc/z/zHeapIterator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/share/gc/z/zHeuristics.cpp b/src/hotspot/share/gc/z/zHeuristics.cpp index ebf979af79518..d13cdef3bb57c 100644 --- a/src/hotspot/share/gc/z/zHeuristics.cpp +++ b/src/hotspot/share/gc/z/zHeuristics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zCPU.inline.hpp" diff --git a/src/hotspot/share/gc/z/zIndexDistributor.inline.hpp b/src/hotspot/share/gc/z/zIndexDistributor.inline.hpp index 26afdef9d052d..c582be8fcee8f 100644 --- a/src/hotspot/share/gc/z/zIndexDistributor.inline.hpp +++ b/src/hotspot/share/gc/z/zIndexDistributor.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -274,7 +274,7 @@ class ZIndexDistributorClaimTree : public CHeapObj { assert((levels_size(ClaimLevels - 1) << _last_level_segment_size_shift) == count, "Incorrectly setup"); #if 0 - tty->print_cr("ZIndexDistributorClaimTree count: %d byte size: " SIZE_FORMAT, count, claim_variables_size() + os::vm_page_size()); + tty->print_cr("ZIndexDistributorClaimTree count: %d byte size: %zu", count, claim_variables_size() + os::vm_page_size()); #endif memset(_malloced, 0, claim_variables_size() + os::vm_page_size()); diff --git a/src/hotspot/share/gc/z/zInitialize.cpp b/src/hotspot/share/gc/z/zInitialize.cpp index e37fc550bfe2a..125231355ac2e 100644 --- a/src/hotspot/share/gc/z/zInitialize.cpp +++ b/src/hotspot/share/gc/z/zInitialize.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zBarrierSet.hpp" @@ -32,7 +31,6 @@ #include "gc/z/zInitialize.hpp" #include "gc/z/zJNICritical.hpp" #include "gc/z/zLargePages.hpp" -#include "gc/z/zMarkStackAllocator.hpp" #include "gc/z/zNMT.hpp" #include "gc/z/zNUMA.hpp" #include "gc/z/zStat.hpp" diff --git a/src/hotspot/share/gc/z/zJNICritical.cpp b/src/hotspot/share/gc/z/zJNICritical.cpp index d096367e12f79..608b8f2249313 100644 --- a/src/hotspot/share/gc/z/zJNICritical.cpp +++ b/src/hotspot/share/gc/z/zJNICritical.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zJNICritical.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zStat.hpp" diff --git a/src/hotspot/share/gc/z/zLargePages.cpp b/src/hotspot/share/gc/z/zLargePages.cpp index a65bf3b10ebad..56c94a75713cd 100644 --- a/src/hotspot/share/gc/z/zLargePages.cpp +++ b/src/hotspot/share/gc/z/zLargePages.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zLargePages.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/share/gc/z/zLiveMap.cpp b/src/hotspot/share/gc/z/zLiveMap.cpp index 715ebc6291724..cc7271f99a7dc 100644 --- a/src/hotspot/share/gc/z/zLiveMap.cpp +++ b/src/hotspot/share/gc/z/zLiveMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zGeneration.inline.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zLiveMap.inline.hpp" @@ -103,7 +102,7 @@ void ZLiveMap::reset_segment(BitMap::idx_t segment) { ZStatInc(ZCounterMarkSegmentResetContention); contention = true; - log_trace(gc)("Mark segment reset contention, thread: " PTR_FORMAT " (%s), map: " PTR_FORMAT ", segment: " SIZE_FORMAT, + log_trace(gc)("Mark segment reset contention, thread: " PTR_FORMAT " (%s), map: " PTR_FORMAT ", segment: %zu", p2i(Thread::current()), ZUtils::thread_name(), p2i(this), segment); } } diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index d33b86c83e57c..e0c68213ca3e8 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.inline.hpp" @@ -82,8 +81,8 @@ static const ZStatSubPhase ZSubPhaseConcurrentMarkRootColoredOld("Concurrent Mar ZMark::ZMark(ZGeneration* generation, ZPageTable* page_table) : _generation(generation), _page_table(page_table), - _allocator(), - _stripes(_allocator.start()), + _marking_smr(), + _stripes(), _terminate(), _work_nproactiveflush(0), _work_nterminateflush(0), @@ -93,10 +92,6 @@ ZMark::ZMark(ZGeneration* generation, ZPageTable* page_table) _ncontinue(0), _nworkers(0) {} -bool ZMark::is_initialized() const { - return _allocator.is_initialized(); -} - size_t ZMark::calculate_nstripes(uint nworkers) const { // Calculate the number of stripes from the number of workers we use, // where the number of stripes must be a power of two and we want to @@ -135,7 +130,7 @@ void ZMark::start() { for (uint worker_id = 0; worker_id < _nworkers; worker_id++) { const ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, worker_id); const size_t stripe_id = _stripes.stripe_id(stripe); - log.print(" Worker %u(%u) -> Stripe " SIZE_FORMAT "(" SIZE_FORMAT ")", + log.print(" Worker %u(%u) -> Stripe %zu(%zu)", worker_id, _nworkers, stripe_id, nstripes); } } @@ -194,10 +189,10 @@ void ZMark::push_partial_array(zpointer* addr, size_t length, bool finalizable) const uintptr_t offset = encode_partial_array_offset(addr); const ZMarkStackEntry entry(offset, length, finalizable); - log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (" SIZE_FORMAT "), stripe: " SIZE_FORMAT, + log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (%zu), stripe: %zu", p2i(addr), length, _stripes.stripe_id(stripe)); - stacks->push(&_allocator, &_stripes, stripe, &_terminate, entry, false /* publish */); + stacks->push(&_stripes, stripe, &_terminate, entry, false /* publish */); } static void mark_barrier_on_oop_array(volatile zpointer* p, size_t length, bool finalizable, bool young) { @@ -213,7 +208,7 @@ static void mark_barrier_on_oop_array(volatile zpointer* p, size_t length, bool void ZMark::follow_array_elements_small(zpointer* addr, size_t length, bool finalizable) { assert(length <= ZMarkPartialArrayMinLength, "Too large, should be split"); - log_develop_trace(gc, marking)("Array follow small: " PTR_FORMAT " (" SIZE_FORMAT ")", p2i(addr), length); + log_develop_trace(gc, marking)("Array follow small: " PTR_FORMAT " (%zu)", p2i(addr), length); mark_barrier_on_oop_array(addr, length, finalizable, _generation->is_young()); } @@ -232,8 +227,8 @@ void ZMark::follow_array_elements_large(zpointer* addr, size_t length, bool fina const size_t middle_length = align_down(end - middle_start, ZMarkPartialArrayMinLength); zpointer* const middle_end = middle_start + middle_length; - log_develop_trace(gc, marking)("Array follow large: " PTR_FORMAT "-" PTR_FORMAT" (" SIZE_FORMAT "), " - "middle: " PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT ")", + log_develop_trace(gc, marking)("Array follow large: " PTR_FORMAT "-" PTR_FORMAT" (%zu), " + "middle: " PTR_FORMAT "-" PTR_FORMAT " (%zu)", p2i(start), p2i(end), length, p2i(middle_start), p2i(middle_end), middle_length); // Push unaligned trailing part @@ -472,21 +467,26 @@ bool ZMark::rebalance_work(ZMarkContext* context) { const size_t nstripes = _stripes.nstripes(); if (assumed_nstripes != nstripes) { + // The number of stripes has changed; reflect that change locally context->set_nstripes(nstripes); - } else if (nstripes < calculate_nstripes(_nworkers) && _allocator.clear_and_get_expanded_recently()) { + } else if (nstripes < calculate_nstripes(_nworkers) && _stripes.is_crowded()) { + // We are running on a reduced number of threads to minimize the amount of work + // hidden in local stacks when the stripes are less well balanced. When this situation + // starts getting crowded, we bump the number of stripes again. const size_t new_nstripes = nstripes << 1; - _stripes.set_nstripes(new_nstripes); - context->set_nstripes(new_nstripes); + if (_stripes.try_set_nstripes(nstripes, new_nstripes)) { + context->set_nstripes(new_nstripes); + } } ZMarkStripe* stripe = _stripes.stripe_for_worker(_nworkers, WorkerThread::worker_id()); if (context->stripe() != stripe) { // Need to switch stripe context->set_stripe(stripe); - flush_and_free(); + flush(Thread::current()); } else if (!_terminate.saturated()) { // Work imbalance detected; striped marking is likely going to be in the way - flush_and_free(); + flush(Thread::current()); } SuspendibleThreadSet::yield(); @@ -503,7 +503,7 @@ bool ZMark::drain(ZMarkContext* context) { context->set_nstripes(_stripes.nstripes()); // Drain stripe stacks - while (stacks->pop(&_allocator, &_stripes, context->stripe(), entry)) { + while (stacks->pop(&_marking_smr, &_stripes, context->stripe(), &entry)) { mark_and_follow(context, entry); if ((processed++ & 31) == 0 && rebalance_work(context)) { @@ -542,7 +542,7 @@ bool ZMark::try_steal_global(ZMarkContext* context) { for (ZMarkStripe* victim_stripe = _stripes.stripe_next(stripe); victim_stripe != stripe; victim_stripe = _stripes.stripe_next(victim_stripe)) { - ZMarkStack* const stack = victim_stripe->steal_stack(); + ZMarkStack* const stack = victim_stripe->steal_stack(&_marking_smr); if (stack != nullptr) { // Success, install the stolen stack stacks->install(&_stripes, stripe, stack); @@ -558,19 +558,19 @@ bool ZMark::try_steal(ZMarkContext* context) { return try_steal_local(context) || try_steal_global(context); } -class ZMarkFlushAndFreeStacksClosure : public HandshakeClosure { +class ZMarkFlushStacksClosure : public HandshakeClosure { private: ZMark* const _mark; bool _flushed; public: - ZMarkFlushAndFreeStacksClosure(ZMark* mark) - : HandshakeClosure("ZMarkFlushAndFreeStacks"), + ZMarkFlushStacksClosure(ZMark* mark) + : HandshakeClosure("ZMarkFlushStacks"), _mark(mark), _flushed(false) {} void do_thread(Thread* thread) { - if (_mark->flush_and_free(thread)) { + if (_mark->flush(thread)) { _flushed = true; if (SafepointSynchronize::is_at_safepoint()) { log_debug(gc, marking)("Thread broke mark termination %s", thread->name()); @@ -607,7 +607,7 @@ class VM_ZMarkFlushOperation : public VM_Operation { }; bool ZMark::flush() { - ZMarkFlushAndFreeStacksClosure cl(this); + ZMarkFlushStacksClosure cl(this); VM_ZMarkFlushOperation vm_cl(&cl); Handshake::execute(&cl); VMThread::execute(&vm_cl); @@ -624,8 +624,7 @@ bool ZMark::try_terminate_flush() { verify_worker_stacks_empty(); } - return flush() || - _terminate.resurrected(); + return flush() || _terminate.resurrected(); } bool ZMark::try_proactive_flush() { @@ -851,7 +850,7 @@ class ZMarkOldRootsTask : public ZTask { // the set of workers executing during root scanning // can be different from the set of workers executing // during mark. - ZHeap::heap()->mark_flush_and_free(Thread::current()); + ZHeap::heap()->mark_flush(Thread::current()); } }; @@ -909,7 +908,7 @@ class ZMarkYoungRootsTask : public ZTask { // the set of workers executing during root scanning // can be different from the set of workers executing // during mark. - ZHeap::heap()->mark_flush_and_free(Thread::current()); + ZHeap::heap()->mark_flush(Thread::current()); } }; @@ -935,7 +934,7 @@ class ZMarkTask : public ZRestartableTask { // publish such marking stacks to prevent that generation from getting a mark continue. // We also flush in case of a resize where a new worker thread continues the marking // work, causing a mark continue for the collected generation. - ZHeap::heap()->mark_flush_and_free(Thread::current()); + ZHeap::heap()->mark_flush(Thread::current()); } virtual void resize_workers(uint nworkers) { @@ -979,7 +978,7 @@ bool ZMark::try_end() { } // Try end marking - ZMarkFlushAndFreeStacksClosure cl(this); + ZMarkFlushStacksClosure cl(this); Threads::non_java_threads_do(&cl); // Check if non-java threads have any pending marking @@ -1013,25 +1012,15 @@ bool ZMark::end() { void ZMark::free() { // Free any unused mark stack space - _allocator.free(); - - // Update statistics - _generation->stat_mark()->at_mark_free(_allocator.size()); -} - -void ZMark::flush_and_free() { - Thread* const thread = Thread::current(); - flush_and_free(thread); + _marking_smr.free(); } -bool ZMark::flush_and_free(Thread* thread) { +bool ZMark::flush(Thread* thread) { if (thread->is_Java_thread()) { ZThreadLocalData::store_barrier_buffer(thread)->flush(); } ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::mark_stacks(thread, _generation->id()); - const bool flushed = stacks->flush(&_allocator, &_stripes, &_terminate); - stacks->free(&_allocator); - return flushed; + return stacks->flush(&_stripes, &_terminate); } class ZVerifyMarkStacksEmptyClosure : public ThreadClosure { diff --git a/src/hotspot/share/gc/z/zMark.hpp b/src/hotspot/share/gc/z/zMark.hpp index 552bf3b959ddd..07e73849af6cf 100644 --- a/src/hotspot/share/gc/z/zMark.hpp +++ b/src/hotspot/share/gc/z/zMark.hpp @@ -25,8 +25,8 @@ #define SHARE_GC_Z_ZMARK_HPP #include "gc/z/zAddress.hpp" +#include "gc/z/zMarkingSMR.hpp" #include "gc/z/zMarkStack.hpp" -#include "gc/z/zMarkStackAllocator.hpp" #include "gc/z/zMarkStackEntry.hpp" #include "gc/z/zMarkTerminate.hpp" #include "oops/oopsHierarchy.hpp" @@ -55,18 +55,18 @@ class ZMark { static const bool Finalizable = true; private: - ZGeneration* const _generation; - ZPageTable* const _page_table; - ZMarkStackAllocator _allocator; - ZMarkStripeSet _stripes; - ZMarkTerminate _terminate; - volatile size_t _work_nproactiveflush; - volatile size_t _work_nterminateflush; - size_t _nproactiveflush; - size_t _nterminateflush; - size_t _ntrycomplete; - size_t _ncontinue; - uint _nworkers; + ZGeneration* const _generation; + ZPageTable* const _page_table; + ZMarkingSMR _marking_smr; + ZMarkStripeSet _stripes; + ZMarkTerminate _terminate; + volatile size_t _work_nproactiveflush; + volatile size_t _work_nterminateflush; + size_t _nproactiveflush; + size_t _nterminateflush; + size_t _ntrycomplete; + size_t _ncontinue; + uint _nworkers; size_t calculate_nstripes(uint nworkers) const; @@ -101,8 +101,6 @@ class ZMark { public: ZMark(ZGeneration* generation, ZPageTable* page_table); - bool is_initialized() const; - template void mark_object(zaddress addr); @@ -113,8 +111,7 @@ class ZMark { bool end(); void free(); - void flush_and_free(); - bool flush_and_free(Thread* thread); + bool flush(Thread* thread); // Following work void prepare_work(); diff --git a/src/hotspot/share/gc/z/zMark.inline.hpp b/src/hotspot/share/gc/z/zMark.inline.hpp index 9edc57a60002e..26c84679cc074 100644 --- a/src/hotspot/share/gc/z/zMark.inline.hpp +++ b/src/hotspot/share/gc/z/zMark.inline.hpp @@ -84,7 +84,7 @@ inline void ZMark::mark_object(zaddress addr) { assert(ZHeap::heap()->is_young(addr) == _generation->is_young(), "Phase/object mismatch"); const bool publish = !gc_thread; - stacks->push(&_allocator, &_stripes, stripe, &_terminate, entry, publish); + stacks->push(&_stripes, stripe, &_terminate, entry, publish); } #endif // SHARE_GC_Z_ZMARK_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zMarkCache.cpp b/src/hotspot/share/gc/z/zMarkCache.cpp index 0eecfbfaa6773..c920bb897b0c1 100644 --- a/src/hotspot/share/gc/z/zMarkCache.cpp +++ b/src/hotspot/share/gc/z/zMarkCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zMarkCache.inline.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/powerOfTwo.hpp" diff --git a/src/hotspot/share/gc/z/zMarkStack.cpp b/src/hotspot/share/gc/z/zMarkStack.cpp index c4938af0a5f6d..692defc50f184 100644 --- a/src/hotspot/share/gc/z/zMarkStack.cpp +++ b/src/hotspot/share/gc/z/zMarkStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,40 +21,212 @@ * questions. */ -#include "precompiled.hpp" +#include "gc/z/zMarkingSMR.hpp" #include "gc/z/zMarkStack.inline.hpp" -#include "gc/z/zMarkStackAllocator.hpp" #include "gc/z/zMarkTerminate.inline.hpp" #include "logging/log.hpp" #include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" #include "utilities/debug.hpp" #include "utilities/powerOfTwo.hpp" -ZMarkStripe::ZMarkStripe(uintptr_t base) - : _published(base), - _overflowed(base) {} +ZMarkStack* ZMarkStack::create(bool first_stack) { + // When allocating the first stack on a stripe, we try to use a + // smaller mark stack to promote sharing of stacks with other + // threads instead. Once more than one stack is needed, we revert + // to a larger stack size instead, which reduces synchronization + // overhead of churning around stacks on a stripe. + const size_t capacity = first_stack ? 128 : 512; -ZMarkStripeSet::ZMarkStripeSet(uintptr_t base) - : _nstripes_mask(0), - _stripes() { + void* const memory = AttachedArray::alloc(capacity); + return ::new (memory) ZMarkStack(capacity); +} + +void ZMarkStack::destroy(ZMarkStack* stack) { + stack->~ZMarkStack(); + AttachedArray::free(stack); +} + +ZMarkStack::ZMarkStack(size_t capacity) + : _top(0), + _entries(capacity) {} + +ZMarkStackListNode::ZMarkStackListNode(ZMarkStack* stack) + : _stack(stack), + _next() {} + +ZMarkStack* ZMarkStackListNode::stack() const { + return _stack; +} + +ZMarkStackListNode* ZMarkStackListNode::next() const { + return _next; +} + +void ZMarkStackListNode::set_next(ZMarkStackListNode* next) { + _next = next; +} + +ZMarkStackList::ZMarkStackList() + : _head(), + _length() {} + +bool ZMarkStackList::is_empty() const { + return Atomic::load(&_head) == nullptr; +} + +void ZMarkStackList::push(ZMarkStack* stack) { + ZMarkStackListNode* const node = new ZMarkStackListNode(stack); + ZMarkStackListNode* head = Atomic::load(&_head); + for (;;) { + node->set_next(head); + // Between reading the head and the linearizing CAS that pushes + // the node onto the list, there could be an ABA problem. Except, + // on the pushing side, that is benign. The node is never + // dereferenced while pushing and if we were to detect the ABA + // situation and run this loop one more time, we would end up + // having the same side effects: set the next pointer to the same + // head again, and CAS the head link. + ZMarkStackListNode* prev = Atomic::cmpxchg(&_head, head, node, memory_order_release); + + if (prev == head) { + // Success + + // Bookkeep the population count + Atomic::inc(&_length, memory_order_relaxed); + return; + } + + // Retry + head = prev; + } +} + +ZMarkStack* ZMarkStackList::pop(ZMarkingSMR* marking_smr) { + ZMarkStackListNode* volatile* const hazard_ptr = marking_smr->hazard_ptr(); + + ZMarkStackListNode* head = Atomic::load(&_head); + for (;;) { + if (head == nullptr) { + // Stack is empty + return nullptr; + } + + // Establish what the head is and publish a hazard pointer denoting + // that the head is not safe to concurrently free while we are in the + // middle of popping it and finding out that we lost the race. + Atomic::store(hazard_ptr, head); + + // A full fence is needed to ensure the store and subsequent load do + // not reorder. If they did reorder, the second head load could happen + // before other threads scanning hazard pointers can observe it, meaning + // it could get concurrently freed. + OrderAccess::fence(); + + // The acquire fence when loading the head is necessary to make sure + // the next pointer load below observes the next pointer published + // with the releasing CAS for the push operation that published the + // marking stack. + ZMarkStackListNode* const head_after_publish = Atomic::load_acquire(&_head); + if (head_after_publish != head) { + // Race during hazard pointer publishing + head = head_after_publish; + continue; + } + + // With the hazard pointer published, we can read the next pointer, + // knowing that it is indeed the next pointer of the intended logical + // head node that we established above. + ZMarkStackListNode* const next = head->next(); + + // Popping entries from the list does not require any particular memory + // ordering. + ZMarkStackListNode* const prev = Atomic::cmpxchg(&_head, head, next, memory_order_relaxed); + + if (prev == head) { + // Success + + // The ABA hazard is gone after the CAS. We use release_store to ensure + // that the relinquishing of the hazard pointer becomes observable after + // the unlinking CAS. + Atomic::release_store(hazard_ptr, (ZMarkStackListNode*)nullptr); + + // Perform bookkeeping of the population count. + Atomic::dec(&_length, memory_order_relaxed); + + ZMarkStack* result = head->stack(); + + marking_smr->free_node(head); + + return result; + } + + // Retry + head = prev; + } +} - // Re-construct array elements with the correct base - for (size_t i = 0; i < ARRAY_SIZE(_stripes); i++) { - _stripes[i] = ZMarkStripe(base); +size_t ZMarkStackList::length() const { + const ssize_t result = Atomic::load(&_length); + + if (result < 0) { + return 0; + } + + return (size_t)result; +} + +ZMarkStripe::ZMarkStripe() + : _published(), + _overflowed() {} + +ZMarkStack* ZMarkStripe::steal_stack(ZMarkingSMR* marking_smr) { + // Steal overflowed stacks first, then published stacks + ZMarkStack* const stack = _overflowed.pop(marking_smr); + if (stack != nullptr) { + return stack; } + + return _published.pop(marking_smr); } +size_t ZMarkStripe::population() const { + return _overflowed.length() + _published.length(); +} + +ZMarkStripeSet::ZMarkStripeSet() + : _nstripes_mask(0), + _stripes() {} + void ZMarkStripeSet::set_nstripes(size_t nstripes) { assert(is_power_of_2(nstripes), "Must be a power of two"); assert(is_power_of_2(ZMarkStripesMax), "Must be a power of two"); assert(nstripes >= 1, "Invalid number of stripes"); assert(nstripes <= ZMarkStripesMax, "Invalid number of stripes"); + const size_t new_nstripes_mask = nstripes - 1; + _nstripes_mask = new_nstripes_mask; + + log_debug(gc, marking)("Using %zu mark stripes", nstripes); +} + +bool ZMarkStripeSet::try_set_nstripes(size_t old_nstripes, size_t new_nstripes) { + assert(is_power_of_2(new_nstripes), "Must be a power of two"); + assert(is_power_of_2(ZMarkStripesMax), "Must be a power of two"); + assert(new_nstripes >= 1, "Invalid number of stripes"); + assert(new_nstripes <= ZMarkStripesMax, "Invalid number of stripes"); + + const size_t old_nstripes_mask = old_nstripes - 1; + const size_t new_nstripes_mask = new_nstripes - 1; + // Mutators may read these values concurrently. It doesn't matter // if they see the old or new values. - Atomic::store(&_nstripes_mask, nstripes - 1); + if (Atomic::cmpxchg(&_nstripes_mask, old_nstripes_mask, new_nstripes_mask) == old_nstripes_mask) { + log_debug(gc, marking)("Using %zu mark stripes", new_nstripes); + return true; + } - log_debug(gc, marking)("Using " SIZE_FORMAT " mark stripes", nstripes); + return false; } size_t ZMarkStripeSet::nstripes() const { @@ -71,6 +243,20 @@ bool ZMarkStripeSet::is_empty() const { return true; } +bool ZMarkStripeSet::is_crowded() const { + size_t population = 0; + const size_t crowded_threshold = nstripes() << 4; + + for (size_t i = 0; i < ZMarkStripesMax; i++) { + population += _stripes[i].population(); + if (population > crowded_threshold) { + return true; + } + } + + return false; +} + ZMarkStripe* ZMarkStripeSet::stripe_for_worker(uint nworkers, uint worker_id) { const size_t mask = Atomic::load(&_nstripes_mask); const size_t nstripes = mask + 1; @@ -93,8 +279,7 @@ ZMarkStripe* ZMarkStripeSet::stripe_for_worker(uint nworkers, uint worker_id) { return &_stripes[index]; } -ZMarkThreadLocalStacks::ZMarkThreadLocalStacks() - : _magazine(nullptr) { +ZMarkThreadLocalStacks::ZMarkThreadLocalStacks() { for (size_t i = 0; i < ZMarkStripesMax; i++) { _stacks[i] = nullptr; } @@ -111,104 +296,8 @@ bool ZMarkThreadLocalStacks::is_empty(const ZMarkStripeSet* stripes) const { return true; } -ZMarkStack* ZMarkThreadLocalStacks::allocate_stack(ZMarkStackAllocator* allocator) { - if (_magazine == nullptr) { - // Allocate new magazine - _magazine = allocator->alloc_magazine(); - if (_magazine == nullptr) { - return nullptr; - } - } - - ZMarkStack* stack = nullptr; - - if (!_magazine->pop(stack)) { - // Magazine is empty, convert magazine into a new stack - _magazine->~ZMarkStackMagazine(); - stack = new ((void*)_magazine) ZMarkStack(); - _magazine = nullptr; - } - - return stack; -} - -void ZMarkThreadLocalStacks::free_stack(ZMarkStackAllocator* allocator, ZMarkStack* stack) { - for (;;) { - if (_magazine == nullptr) { - // Convert stack into a new magazine - stack->~ZMarkStack(); - _magazine = new ((void*)stack) ZMarkStackMagazine(); - return; - } - - if (_magazine->push(stack)) { - // Success - return; - } - - // Free and uninstall full magazine - allocator->free_magazine(_magazine); - _magazine = nullptr; - } -} - -bool ZMarkThreadLocalStacks::push_slow(ZMarkStackAllocator* allocator, - ZMarkStripe* stripe, - ZMarkStack** stackp, - ZMarkTerminate* terminate, - ZMarkStackEntry entry, - bool publish) { - ZMarkStack* stack = *stackp; - - for (;;) { - if (stack == nullptr) { - // Allocate and install new stack - *stackp = stack = allocate_stack(allocator); - if (stack == nullptr) { - // Out of mark stack memory - return false; - } - } - - if (stack->push(entry)) { - // Success - return true; - } - - // Publish/Overflow and uninstall stack - stripe->publish_stack(stack, terminate, publish); - *stackp = stack = nullptr; - } -} - -bool ZMarkThreadLocalStacks::pop_slow(ZMarkStackAllocator* allocator, - ZMarkStripe* stripe, - ZMarkStack** stackp, - ZMarkStackEntry& entry) { - ZMarkStack* stack = *stackp; - - for (;;) { - if (stack == nullptr) { - // Try steal and install stack - *stackp = stack = stripe->steal_stack(); - if (stack == nullptr) { - // Nothing to steal - return false; - } - } - - if (stack->pop(entry)) { - // Success - return true; - } - - // Free and uninstall stack - free_stack(allocator, stack); - *stackp = stack = nullptr; - } -} - -bool ZMarkThreadLocalStacks::flush(ZMarkStackAllocator* allocator, ZMarkStripeSet* stripes, ZMarkTerminate* terminate) { +bool ZMarkThreadLocalStacks::flush(ZMarkStripeSet* stripes, + ZMarkTerminate* terminate) { bool flushed = false; // Flush all stacks @@ -221,22 +310,10 @@ bool ZMarkThreadLocalStacks::flush(ZMarkStackAllocator* allocator, ZMarkStripeSe } // Free/Publish and uninstall stack - if (stack->is_empty()) { - free_stack(allocator, stack); - } else { - stripe->publish_stack(stack, terminate, true /* publish */); - flushed = true; - } + stripe->publish_stack(stack, terminate, true /* publish */); + flushed = true; *stackp = nullptr; } return flushed; } - -void ZMarkThreadLocalStacks::free(ZMarkStackAllocator* allocator) { - // Free and uninstall magazine - if (_magazine != nullptr) { - allocator->free_magazine(_magazine); - _magazine = nullptr; - } -} diff --git a/src/hotspot/share/gc/z/zMarkStack.hpp b/src/hotspot/share/gc/z/zMarkStack.hpp index 8a24c84c8d9c8..7c0e6d4c71209 100644 --- a/src/hotspot/share/gc/z/zMarkStack.hpp +++ b/src/hotspot/share/gc/z/zMarkStack.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,73 +24,81 @@ #ifndef SHARE_GC_Z_ZMARKSTACK_HPP #define SHARE_GC_Z_ZMARKSTACK_HPP +#include "gc/z/zAttachedArray.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zMarkStackEntry.hpp" +#include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" +class ZMarkingSMR; +class ZMarkStripe; class ZMarkTerminate; -template -class ZStack { +class ZMarkStack { private: - size_t _top; - ZStack* _next; - T _slots[S]; + using AttachedArray = ZAttachedArray; - bool is_full() const; + size_t _top; + const AttachedArray _entries; + + ZMarkStackEntry* slots(); + + ZMarkStack(size_t capacity); public: - ZStack(); + static ZMarkStack* create(bool first_stack); + static void destroy(ZMarkStack* stack); bool is_empty() const; + bool is_full() const; - bool push(T value); - bool pop(T& value); - - ZStack* next() const; - ZStack** next_addr(); + void push(ZMarkStackEntry value); + ZMarkStackEntry pop(); }; -template -class ZCACHE_ALIGNED ZStackList { +class ZMarkStackListNode : public CHeapObj { private: - uintptr_t _base; - T* volatile _head; + ZMarkStack* const _stack; + ZMarkStackListNode* _next; + +public: + ZMarkStackListNode(ZMarkStack* stack); + + ZMarkStack* stack() const; + + ZMarkStackListNode* next() const; + void set_next(ZMarkStackListNode* next); +}; - T* encode_versioned_pointer(const T* stack, uint32_t version) const; - void decode_versioned_pointer(const T* vstack, T** stack, uint32_t* version) const; +class ZCACHE_ALIGNED ZMarkStackList { +private: + ZMarkStackListNode* volatile _head; + ssize_t volatile _length; public: - explicit ZStackList(uintptr_t base); + ZMarkStackList(); bool is_empty() const; - void push(T* stack); - T* pop(); + size_t length() const; - void clear(); + void push(ZMarkStack* stack); + ZMarkStack* pop(ZMarkingSMR* marking_smr); }; -using ZMarkStack = ZStack; -using ZMarkStackList = ZStackList; -using ZMarkStackMagazine = ZStack; -using ZMarkStackMagazineList = ZStackList; - -static_assert(sizeof(ZMarkStack) == ZMarkStackSize, "ZMarkStack size mismatch"); -static_assert(sizeof(ZMarkStackMagazine) <= ZMarkStackSize, "ZMarkStackMagazine size too large"); - class ZMarkStripe { private: ZCACHE_ALIGNED ZMarkStackList _published; ZCACHE_ALIGNED ZMarkStackList _overflowed; public: - explicit ZMarkStripe(uintptr_t base = 0); + explicit ZMarkStripe(); bool is_empty() const; + size_t population() const; void publish_stack(ZMarkStack* stack, ZMarkTerminate* terminate, bool publish); - ZMarkStack* steal_stack(); + ZMarkStack* steal_stack(ZMarkingSMR* marking_smr); }; class ZMarkStripeSet { @@ -99,12 +107,14 @@ class ZMarkStripeSet { ZMarkStripe _stripes[ZMarkStripesMax]; public: - explicit ZMarkStripeSet(uintptr_t base); + explicit ZMarkStripeSet(); void set_nstripes(size_t nstripes); + bool try_set_nstripes(size_t old_nstripes, size_t new_nstripes); size_t nstripes() const; bool is_empty() const; + bool is_crowded() const; size_t stripe_id(const ZMarkStripe* stripe) const; ZMarkStripe* stripe_at(size_t index); @@ -113,27 +123,9 @@ class ZMarkStripeSet { ZMarkStripe* stripe_for_addr(uintptr_t addr); }; -class ZMarkStackAllocator; - class ZMarkThreadLocalStacks { private: - ZMarkStackMagazine* _magazine; - ZMarkStack* _stacks[ZMarkStripesMax]; - - ZMarkStack* allocate_stack(ZMarkStackAllocator* allocator); - void free_stack(ZMarkStackAllocator* allocator, ZMarkStack* stack); - - bool push_slow(ZMarkStackAllocator* allocator, - ZMarkStripe* stripe, - ZMarkStack** stackp, - ZMarkTerminate* terminate, - ZMarkStackEntry entry, - bool publish); - - bool pop_slow(ZMarkStackAllocator* allocator, - ZMarkStripe* stripe, - ZMarkStack** stackp, - ZMarkStackEntry& entry); + ZMarkStack* _stacks[ZMarkStripesMax]; public: ZMarkThreadLocalStacks(); @@ -147,23 +139,19 @@ class ZMarkThreadLocalStacks { ZMarkStack* steal(ZMarkStripeSet* stripes, ZMarkStripe* stripe); - bool push(ZMarkStackAllocator* allocator, - ZMarkStripeSet* stripes, + void push(ZMarkStripeSet* stripes, ZMarkStripe* stripe, ZMarkTerminate* terminate, ZMarkStackEntry entry, bool publish); - bool pop(ZMarkStackAllocator* allocator, + bool pop(ZMarkingSMR* marking_smr, ZMarkStripeSet* stripes, ZMarkStripe* stripe, - ZMarkStackEntry& entry); + ZMarkStackEntry* entry); - bool flush(ZMarkStackAllocator* allocator, - ZMarkStripeSet* stripes, + bool flush(ZMarkStripeSet* stripes, ZMarkTerminate* terminate); - - void free(ZMarkStackAllocator* allocator); }; #endif // SHARE_GC_Z_ZMARKSTACK_HPP diff --git a/src/hotspot/share/gc/z/zMarkStack.inline.hpp b/src/hotspot/share/gc/z/zMarkStack.inline.hpp index cd8667dd73ff9..ed3b167762cde 100644 --- a/src/hotspot/share/gc/z/zMarkStack.inline.hpp +++ b/src/hotspot/share/gc/z/zMarkStack.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,142 +26,30 @@ #include "gc/z/zMarkStack.hpp" +#include "gc/z/zAttachedArray.inline.hpp" #include "gc/z/zMarkTerminate.inline.hpp" -#include "runtime/atomic.hpp" #include "utilities/debug.hpp" -template -inline ZStack::ZStack() - : _top(0), - _next(nullptr) {} - -template -inline bool ZStack::is_empty() const { +inline bool ZMarkStack::is_empty() const { return _top == 0; } -template -inline bool ZStack::is_full() const { - return _top == S; +inline bool ZMarkStack::is_full() const { + return _top == _entries.length(); } -template -inline bool ZStack::push(T value) { - if (is_full()) { - return false; - } - - _slots[_top++] = value; - return true; -} - -template -inline bool ZStack::pop(T& value) { - if (is_empty()) { - return false; - } - - value = _slots[--_top]; - return true; -} - -template -inline ZStack* ZStack::next() const { - return _next; -} - -template -inline ZStack** ZStack::next_addr() { - return &_next; -} - -template -inline ZStackList::ZStackList(uintptr_t base) - : _base(base), - _head(encode_versioned_pointer(nullptr, 0)) {} - -template -inline T* ZStackList::encode_versioned_pointer(const T* stack, uint32_t version) const { - uint64_t addr; - - if (stack == nullptr) { - addr = (uint32_t)-1; - } else { - addr = ((uint64_t)stack - _base) >> ZMarkStackSizeShift; - } - - return (T*)((addr << 32) | (uint64_t)version); -} - -template -inline void ZStackList::decode_versioned_pointer(const T* vstack, T** stack, uint32_t* version) const { - const uint64_t addr = (uint64_t)vstack >> 32; - - if (addr == (uint32_t)-1) { - *stack = nullptr; - } else { - *stack = (T*)((addr << ZMarkStackSizeShift) + _base); - } - - *version = (uint32_t)(uint64_t)vstack; -} - -template -inline bool ZStackList::is_empty() const { - const T* vstack = _head; - T* stack = nullptr; - uint32_t version = 0; - - decode_versioned_pointer(vstack, &stack, &version); - return stack == nullptr; -} - -template -inline void ZStackList::push(T* stack) { - T* vstack = _head; - uint32_t version = 0; - - for (;;) { - decode_versioned_pointer(vstack, stack->next_addr(), &version); - T* const new_vstack = encode_versioned_pointer(stack, version + 1); - T* const prev_vstack = Atomic::cmpxchg(&_head, vstack, new_vstack); - if (prev_vstack == vstack) { - // Success - break; - } - - // Retry - vstack = prev_vstack; - } +inline ZMarkStackEntry* ZMarkStack::slots() { + return _entries(this); } -template -inline T* ZStackList::pop() { - T* vstack = _head; - T* stack = nullptr; - uint32_t version = 0; - - for (;;) { - decode_versioned_pointer(vstack, &stack, &version); - if (stack == nullptr) { - return nullptr; - } - - T* const new_vstack = encode_versioned_pointer(stack->next(), version + 1); - T* const prev_vstack = Atomic::cmpxchg(&_head, vstack, new_vstack); - if (prev_vstack == vstack) { - // Success - return stack; - } - - // Retry - vstack = prev_vstack; - } +inline void ZMarkStack::push(ZMarkStackEntry value) { + assert(!is_full(), "can't push to full stack"); + slots()[_top++] = value; } -template -inline void ZStackList::clear() { - _head = encode_versioned_pointer(nullptr, 0); +inline ZMarkStackEntry ZMarkStack::pop() { + assert(!is_empty(), "can't pop from empty stack"); + return slots()[--_top]; } inline bool ZMarkStripe::is_empty() const { @@ -175,6 +63,8 @@ inline void ZMarkStripe::publish_stack(ZMarkStack* stack, ZMarkTerminate* termin // to publish stacks that overflowed. The intention here is to avoid // contention between mutators and GC workers as much as possible, while // still allowing GC workers to help out and steal work from each other. + assert(!stack->is_empty(), "we never publish empty stacks"); + if (publish) { _published.push(stack); } else { @@ -184,16 +74,6 @@ inline void ZMarkStripe::publish_stack(ZMarkStack* stack, ZMarkTerminate* termin terminate->wake_up(); } -inline ZMarkStack* ZMarkStripe::steal_stack() { - // Steal overflowed stacks first, then published stacks - ZMarkStack* const stack = _overflowed.pop(); - if (stack != nullptr) { - return stack; - } - - return _published.pop(); -} - inline size_t ZMarkStripeSet::stripe_id(const ZMarkStripe* stripe) const { const size_t index = ((uintptr_t)stripe - (uintptr_t)_stripes) / sizeof(ZMarkStripe); assert(index < ZMarkStripesMax, "Invalid index"); @@ -236,32 +116,63 @@ inline ZMarkStack* ZMarkThreadLocalStacks::steal(ZMarkStripeSet* stripes, return stack; } -inline bool ZMarkThreadLocalStacks::push(ZMarkStackAllocator* allocator, - ZMarkStripeSet* stripes, +inline void ZMarkThreadLocalStacks::push(ZMarkStripeSet* stripes, ZMarkStripe* stripe, ZMarkTerminate* terminate, ZMarkStackEntry entry, bool publish) { - ZMarkStack** const stackp = &_stacks[stripes->stripe_id(stripe)]; - ZMarkStack* const stack = *stackp; - if (stack != nullptr && stack->push(entry)) { - return true; + const size_t stripe_id = stripes->stripe_id(stripe); + ZMarkStack** const stackp = &_stacks[stripe_id]; + ZMarkStack* const prev_stack = *stackp; + + if (prev_stack != nullptr) { + if (!prev_stack->is_full()) { + // There's a stack and it isn't full: just push + prev_stack->push(entry); + return; + } + + // Publish full stacks + stripe->publish_stack(prev_stack, terminate, publish); + *stackp = nullptr; } - return push_slow(allocator, stripe, stackp, terminate, entry, publish); + // If no stack was available, allocate one and push to it + const bool first_stack = prev_stack == nullptr; + ZMarkStack* const new_stack = ZMarkStack::create(first_stack); + *stackp = new_stack; + + new_stack->push(entry); } -inline bool ZMarkThreadLocalStacks::pop(ZMarkStackAllocator* allocator, +inline bool ZMarkThreadLocalStacks::pop(ZMarkingSMR* marking_smr, ZMarkStripeSet* stripes, ZMarkStripe* stripe, - ZMarkStackEntry& entry) { + ZMarkStackEntry* entry) { ZMarkStack** const stackp = &_stacks[stripes->stripe_id(stripe)]; - ZMarkStack* const stack = *stackp; - if (stack != nullptr && stack->pop(entry)) { - return true; + ZMarkStack* stack = *stackp; + + // First make sure there is a stack to pop from + if (stack == nullptr) { + // If we have no stack, try to steal one + stack = stripe->steal_stack(marking_smr); + *stackp = stack; + + if (stack == nullptr) { + // Out of stacks to pop from + return false; + } + } + + *entry = stack->pop(); + + if (stack->is_empty()) { + // Eagerly free empty stacks while on a worker thread + ZMarkStack::destroy(stack); + *stackp = nullptr; } - return pop_slow(allocator, stripe, stackp, entry); + return true; } #endif // SHARE_GC_Z_ZMARKSTACK_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zMarkStackAllocator.cpp b/src/hotspot/share/gc/z/zMarkStackAllocator.cpp deleted file mode 100644 index 2bc37a0483a36..0000000000000 --- a/src/hotspot/share/gc/z/zMarkStackAllocator.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "precompiled.hpp" -#include "gc/shared/gc_globals.hpp" -#include "gc/z/zInitialize.hpp" -#include "gc/z/zLock.inline.hpp" -#include "gc/z/zMarkStack.inline.hpp" -#include "gc/z/zMarkStackAllocator.hpp" -#include "logging/log.hpp" -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" - -ZMarkStackSpace::ZMarkStackSpace() - : _expand_lock(), - _start(0), - _top(0), - _end(0) { - assert(ZMarkStackSpaceLimit >= ZMarkStackSpaceExpandSize, "ZMarkStackSpaceLimit too small"); - - // Reserve address space - const size_t size = ZMarkStackSpaceLimit; - const uintptr_t addr = (uintptr_t)os::reserve_memory(size, !ExecMem, mtGC); - if (addr == 0) { - ZInitialize::error_d("Failed to reserve address space for mark stacks"); - return; - } - - // Successfully initialized - _start = _top = _end = addr; - - // Prime space - _end += expand_space(); -} - -bool ZMarkStackSpace::is_initialized() const { - return _start != 0; -} - -uintptr_t ZMarkStackSpace::start() const { - return _start; -} - -size_t ZMarkStackSpace::size() const { - return _end - _start; -} - -size_t ZMarkStackSpace::used() const { - return _top - _start; -} - -size_t ZMarkStackSpace::expand_space() { - const size_t expand_size = ZMarkStackSpaceExpandSize; - const size_t old_size = size(); - const size_t new_size = old_size + expand_size; - - if (new_size > ZMarkStackSpaceLimit) { - // Expansion limit reached. This is a fatal error since we - // currently can't recover from running out of mark stack space. - fatal("Mark stack space exhausted. Use -XX:ZMarkStackSpaceLimit= to increase the " - "maximum number of bytes allocated for mark stacks. Current limit is " SIZE_FORMAT "M.", - ZMarkStackSpaceLimit / M); - } - - log_debug(gc, marking)("Expanding mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M", - old_size / M, new_size / M); - - // Expand - os::commit_memory_or_exit((char*)_end, expand_size, false /* executable */, "Mark stack space"); - - return expand_size; -} - -size_t ZMarkStackSpace::shrink_space() { - // Shrink to what is currently used - const size_t old_size = size(); - const size_t new_size = align_up(used(), ZMarkStackSpaceExpandSize); - const size_t shrink_size = old_size - new_size; - - if (shrink_size > 0) { - // Shrink - log_debug(gc, marking)("Shrinking mark stack space: " SIZE_FORMAT "M->" SIZE_FORMAT "M", - old_size / M, new_size / M); - - const uintptr_t shrink_start = _end - shrink_size; - os::uncommit_memory((char*)shrink_start, shrink_size, false /* executable */); - } - - return shrink_size; -} - -uintptr_t ZMarkStackSpace::alloc_space(size_t size) { - uintptr_t top = Atomic::load(&_top); - - for (;;) { - const uintptr_t end = Atomic::load(&_end); - const uintptr_t new_top = top + size; - if (new_top > end) { - // Not enough space left - return 0; - } - - const uintptr_t prev_top = Atomic::cmpxchg(&_top, top, new_top); - if (prev_top == top) { - // Success - return top; - } - - // Retry - top = prev_top; - } -} - -uintptr_t ZMarkStackSpace::expand_and_alloc_space(size_t size) { - ZLocker locker(&_expand_lock); - - // Retry allocation before expanding - uintptr_t addr = alloc_space(size); - if (addr != 0) { - return addr; - } - - // Expand - const size_t expand_size = expand_space(); - - // Increment top before end to make sure another - // thread can't steal out newly expanded space. - addr = Atomic::fetch_then_add(&_top, size); - Atomic::add(&_end, expand_size); - - return addr; -} - -uintptr_t ZMarkStackSpace::alloc(size_t size) { - assert(size <= ZMarkStackSpaceExpandSize, "Invalid size"); - - const uintptr_t addr = alloc_space(size); - if (addr != 0) { - return addr; - } - - return expand_and_alloc_space(size); -} - -void ZMarkStackSpace::free() { - _end -= shrink_space(); - _top = _start; -} - -ZMarkStackAllocator::ZMarkStackAllocator() - : _space(), - _freelist(_space.start()), - _expanded_recently(false) {} - -bool ZMarkStackAllocator::is_initialized() const { - return _space.is_initialized(); -} - -uintptr_t ZMarkStackAllocator::start() const { - return _space.start(); -} - -size_t ZMarkStackAllocator::size() const { - return _space.size(); -} - -ZMarkStackMagazine* ZMarkStackAllocator::create_magazine_from_space(uintptr_t addr, size_t size) { - assert(is_aligned(size, ZMarkStackSize), "Invalid size"); - - // Use first stack as magazine - ZMarkStackMagazine* const magazine = new ((void*)addr) ZMarkStackMagazine(); - for (size_t i = ZMarkStackSize; i < size; i += ZMarkStackSize) { - ZMarkStack* const stack = new ((void*)(addr + i)) ZMarkStack(); - const bool success = magazine->push(stack); - assert(success, "Magazine should never get full"); - } - - return magazine; -} - -ZMarkStackMagazine* ZMarkStackAllocator::alloc_magazine() { - // Try allocating from the free list first - ZMarkStackMagazine* const magazine = _freelist.pop(); - if (magazine != nullptr) { - return magazine; - } - - if (!Atomic::load(&_expanded_recently)) { - Atomic::cmpxchg(&_expanded_recently, false, true); - } - - // Allocate new magazine - const uintptr_t addr = _space.alloc(ZMarkStackMagazineSize); - if (addr == 0) { - return nullptr; - } - - return create_magazine_from_space(addr, ZMarkStackMagazineSize); -} - -bool ZMarkStackAllocator::clear_and_get_expanded_recently() { - if (!Atomic::load(&_expanded_recently)) { - return false; - } - - return Atomic::cmpxchg(&_expanded_recently, true, false); -} - -void ZMarkStackAllocator::free_magazine(ZMarkStackMagazine* magazine) { - _freelist.push(magazine); -} - -void ZMarkStackAllocator::free() { - _freelist.clear(); - _space.free(); -} diff --git a/src/hotspot/share/gc/z/zMarkStackAllocator.hpp b/src/hotspot/share/gc/z/zMarkStackAllocator.hpp deleted file mode 100644 index dc18a23e101e6..0000000000000 --- a/src/hotspot/share/gc/z/zMarkStackAllocator.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP -#define SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP - -#include "gc/z/zGlobals.hpp" -#include "gc/z/zLock.hpp" -#include "gc/z/zMarkStack.hpp" -#include "utilities/globalDefinitions.hpp" - -class ZMarkStackSpace { -private: - ZLock _expand_lock; - uintptr_t _start; - volatile uintptr_t _top; - volatile uintptr_t _end; - volatile bool _recently_expanded; - - size_t used() const; - - size_t expand_space(); - size_t shrink_space(); - - uintptr_t alloc_space(size_t size); - uintptr_t expand_and_alloc_space(size_t size); - -public: - ZMarkStackSpace(); - - bool is_initialized() const; - - uintptr_t start() const; - size_t size() const; - - uintptr_t alloc(size_t size); - void free(); -}; - -class ZMarkStackAllocator : public CHeapObj { -private: - ZCACHE_ALIGNED ZMarkStackSpace _space; - ZCACHE_ALIGNED ZMarkStackMagazineList _freelist; - ZCACHE_ALIGNED volatile bool _expanded_recently; - - ZMarkStackMagazine* create_magazine_from_space(uintptr_t addr, size_t size); - -public: - ZMarkStackAllocator(); - - bool is_initialized() const; - - uintptr_t start() const; - size_t size() const; - - bool clear_and_get_expanded_recently(); - - ZMarkStackMagazine* alloc_magazine(); - void free_magazine(ZMarkStackMagazine* magazine); - - void free(); -}; - -#endif // SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP diff --git a/src/hotspot/share/gc/z/zMarkTerminate.inline.hpp b/src/hotspot/share/gc/z/zMarkTerminate.inline.hpp index 79d3f8ef2a018..cdd9e7dce2525 100644 --- a/src/hotspot/share/gc/z/zMarkTerminate.inline.hpp +++ b/src/hotspot/share/gc/z/zMarkTerminate.inline.hpp @@ -28,6 +28,7 @@ #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zLock.inline.hpp" +#include "gc/z/zMarkStack.hpp" #include "logging/log.hpp" #include "runtime/atomic.hpp" #include "runtime/osThread.hpp" @@ -60,8 +61,7 @@ inline void ZMarkTerminate::leave() { inline void ZMarkTerminate::maybe_reduce_stripes(ZMarkStripeSet* stripes, size_t used_nstripes) { size_t nstripes = stripes->nstripes(); if (used_nstripes == nstripes && nstripes > 1u) { - nstripes >>= 1; - stripes->set_nstripes(nstripes); + stripes->try_set_nstripes(nstripes, nstripes >> 1); } } diff --git a/src/hotspot/share/gc/z/zMarkingSMR.cpp b/src/hotspot/share/gc/z/zMarkingSMR.cpp new file mode 100644 index 0000000000000..2335d009c74ff --- /dev/null +++ b/src/hotspot/share/gc/z/zMarkingSMR.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "gc/z/zMarkingSMR.hpp" +#include "gc/z/zMarkStack.inline.hpp" +#include "gc/z/zValue.inline.hpp" +#include "runtime/atomic.hpp" + +ZMarkingSMR::ZMarkingSMR() + : _worker_states(), + _expanded_recently() { +} + +void ZMarkingSMR::free_node(ZMarkStackListNode* node) { + // We use hazard pointers as an safe memory reclamation (SMR) technique, + // for marking stacks. Each stripe has a lock-free stack of mark stacks. + // When a GC thread (1) pops a mark stack from this lock-free stack, + // there is a small window of time when the head has been read and we + // are about to read its next pointer. It is then of great importance + // that the node is not concurrently freed by another concurrent GC + // thread (2), popping the same entry. In such an event, the memory + // of the freed node could, for example become part of a separate + // node, and potentially pushed onto a separate stripe, with a + // different next pointer referring to a node of the other stripe. + // When GC thread (1) then reads the next pointer of what it believed + // to be the current head node of the first stripe, it actually read + // a next pointer of a logically different node, pointing into the + // other stripe. GC thread (2) could then pop the node from the second + // mark stripe and re-insert it as the head of the first stripe. + // Disaster eventually hits when GC thread (1) succeeds with its + // CAS (ABA problem), switching the loaded head to the loaded next + // pointer of the head. Due to the next pointer belonging to a logically + // different node than the logical head, we can accidentally corrupt the + // stack integrity. Using hazard pointers involves publishing what head + // was observed by GC thread (1), so that GC thread (2) knows not to + // free the node when popping it in this race. This prevents the racy + // interactions from causing any such use-after-free problems. + + assert(Thread::current()->is_Worker_thread(), "must be a worker"); + + ZWorkerState* const local_state = _worker_states.addr(); + ZArray* const freeing = &local_state->_freeing; + freeing->append(node); + + if (freeing->length() < (int)ZPerWorkerStorage::count() * 8) { + return; + } + + ZPerWorkerIterator iter(&_worker_states); + ZArray* const scanned_hazards = &local_state->_scanned_hazards; + + for (ZWorkerState* remote_state; iter.next(&remote_state);) { + ZMarkStackListNode* const hazard = Atomic::load(&remote_state->_hazard_ptr); + + if (hazard != nullptr) { + scanned_hazards->append(hazard); + } + } + + int kept = 0; + for (int i = 0; i < freeing->length(); ++i) { + ZMarkStackListNode* node = freeing->at(i); + freeing->at_put(i, nullptr); + + if (scanned_hazards->contains(node)) { + // Keep + freeing->at_put(kept++, node); + } else { + // Delete + delete node; + } + } + + scanned_hazards->clear(); + freeing->trunc_to(kept); +} + +void ZMarkingSMR::free() { + // Here it is free by definition to free mark stacks. + ZPerWorkerIterator iter(&_worker_states); + for (ZWorkerState* worker_state; iter.next(&worker_state);) { + ZArray* const freeing = &worker_state->_freeing; + for (ZMarkStackListNode* node: *freeing) { + delete node; + } + freeing->clear(); + } +} + +ZMarkStackListNode* volatile* ZMarkingSMR::hazard_ptr() { + return &_worker_states.addr()->_hazard_ptr; +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/DeoptimizationBlob.java b/src/hotspot/share/gc/z/zMarkingSMR.hpp similarity index 54% rename from src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/DeoptimizationBlob.java rename to src/hotspot/share/gc/z/zMarkingSMR.hpp index d6686e1bb96b4..a6c5afe76c941 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/DeoptimizationBlob.java +++ b/src/hotspot/share/gc/z/zMarkingSMR.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,38 +19,35 @@ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. - * */ -package sun.jvm.hotspot.code; +#ifndef SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP +#define SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP -import java.util.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.types.*; -import sun.jvm.hotspot.utilities.Observable; -import sun.jvm.hotspot.utilities.Observer; +#include "gc/z/zArray.hpp" +#include "gc/z/zValue.hpp" +#include "utilities/globalDefinitions.hpp" +#include "memory/allocation.hpp" -public class DeoptimizationBlob extends SingletonBlob { - static { - VM.registerVMInitializedObserver(new Observer() { - public void update(Observable o, Object data) { - initialize(VM.getVM().getTypeDataBase()); - } - }); - } +class ZMarkStackListNode; - private static void initialize(TypeDataBase db) { - Type type = db.lookupType("DeoptimizationBlob"); +class ZMarkingSMR: public CHeapObj { +private: + struct ZWorkerState { + ZMarkStackListNode* volatile _hazard_ptr; + ZArray _scanned_hazards; + ZArray _freeing; + }; - // FIXME: add any needed fields - } + ZPerWorker _worker_states; + volatile bool _expanded_recently; - public DeoptimizationBlob(Address addr) { - super(addr); - } +public: + ZMarkingSMR(); + void free(); + ZMarkStackListNode* allocate_stack(); + void free_node(ZMarkStackListNode* stack); + ZMarkStackListNode* volatile* hazard_ptr(); +}; - public boolean isDeoptimizationStub() { - return true; - } -} +#endif // SHARE_GC_Z_ZMARKSTACKALLOCATOR_HPP diff --git a/src/hotspot/share/gc/z/zMemory.cpp b/src/hotspot/share/gc/z/zMemory.cpp index 7bc6b7379c599..14578c2db8a26 100644 --- a/src/hotspot/share/gc/z/zMemory.cpp +++ b/src/hotspot/share/gc/z/zMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zList.inline.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zMemory.inline.hpp" diff --git a/src/hotspot/share/gc/z/zMetronome.cpp b/src/hotspot/share/gc/z/zMetronome.cpp index 876b1f6922799..d719017ddc45a 100644 --- a/src/hotspot/share/gc/z/zMetronome.cpp +++ b/src/hotspot/share/gc/z/zMetronome.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zMetronome.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/timer.hpp" diff --git a/src/hotspot/share/gc/z/zNMT.cpp b/src/hotspot/share/gc/z/zNMT.cpp index b23452eb15647..07ea8df13252f 100644 --- a/src/hotspot/share/gc/z/zNMT.cpp +++ b/src/hotspot/share/gc/z/zNMT.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zNMT.hpp" diff --git a/src/hotspot/share/gc/z/zNMethod.cpp b/src/hotspot/share/gc/z/zNMethod.cpp index 7c5b1e06edbb0..4ae440ea23123 100644 --- a/src/hotspot/share/gc/z/zNMethod.cpp +++ b/src/hotspot/share/gc/z/zNMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/relocInfo.hpp" #include "code/nmethod.hpp" @@ -306,26 +305,32 @@ uintptr_t ZNMethod::color(nmethod* nm) { return (uintptr_t)bs_nm->guard_value(nm); } -oop ZNMethod::load_oop(oop* p, DecoratorSet decorators) { - assert((decorators & ON_WEAK_OOP_REF) == 0, - "nmethod oops have phantom strength, not weak"); - nmethod* const nm = CodeCache::find_nmethod((void*)p); - assert(nm != nullptr, "did not find nmethod"); +oop ZNMethod::oop_load_no_keepalive(const nmethod* nm, int index) { + return oop_load(nm, index, false /* keep_alive */); +} + +oop ZNMethod::oop_load_phantom(const nmethod* nm, int index) { + return oop_load(nm, index, true /* keep_alive */); +} + +oop ZNMethod::oop_load(const nmethod* const_nm, int index, bool keep_alive) { + // The rest of the code is not ready to handle const nmethod, so cast it away + // until we are more consistent with our const corectness. + nmethod* nm = const_cast(const_nm); + if (!is_armed(nm)) { // If the nmethod entry barrier isn't armed, then it has been applied // already. The implication is that the contents of the memory location // is already a valid oop, and the barrier would have kept it alive if // necessary. Therefore, no action is required, and we are allowed to // simply read the oop. - return *p; + return *nm->oop_addr_at(index); } - const bool keep_alive = (decorators & ON_PHANTOM_OOP_REF) != 0 && - (decorators & AS_NO_KEEPALIVE) == 0; ZLocker locker(ZNMethod::lock_for_nmethod(nm)); // Make a local root - zaddress_unsafe obj = *ZUncoloredRoot::cast(p); + zaddress_unsafe obj = *ZUncoloredRoot::cast(nm->oop_addr_at(index)); if (keep_alive) { ZUncoloredRoot::process(&obj, ZNMethod::color(nm)); diff --git a/src/hotspot/share/gc/z/zNMethod.hpp b/src/hotspot/share/gc/z/zNMethod.hpp index 2c92e1f5efbba..5d797f3fd5542 100644 --- a/src/hotspot/share/gc/z/zNMethod.hpp +++ b/src/hotspot/share/gc/z/zNMethod.hpp @@ -42,6 +42,8 @@ class ZNMethod : public AllStatic { static void log_unregister(const nmethod* nm); static void log_purge(const nmethod* nm); + static oop oop_load(const nmethod* nm, int index, bool keep_alive); + public: static void register_nmethod(nmethod* nm); static void unregister_nmethod(nmethod* nm); @@ -69,7 +71,9 @@ class ZNMethod : public AllStatic { static void purge(); static uintptr_t color(nmethod* nm); - static oop load_oop(oop* p, DecoratorSet decorators); + + static oop oop_load_no_keepalive(const nmethod* nm, int index); + static oop oop_load_phantom(const nmethod* nm, int index); }; #endif // SHARE_GC_Z_ZNMETHOD_HPP diff --git a/src/hotspot/share/gc/z/zNMethodData.cpp b/src/hotspot/share/gc/z/zNMethodData.cpp index 467553bd7a6b4..deb56340a8f07 100644 --- a/src/hotspot/share/gc/z/zNMethodData.cpp +++ b/src/hotspot/share/gc/z/zNMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zNMethodData.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/gc/z/zNMethodTable.cpp b/src/hotspot/share/gc/z/zNMethodTable.cpp index 9714bee4bd88f..0aec0d5a9c7f4 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.cpp +++ b/src/hotspot/share/gc/z/zNMethodTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "code/relocInfo.hpp" #include "code/nmethod.hpp" #include "gc/shared/barrierSet.hpp" @@ -110,9 +109,9 @@ void ZNMethodTable::rebuild(size_t new_size) { assert(is_power_of_2(new_size), "Invalid size"); log_debug(gc, nmethod)("Rebuilding NMethod Table: " - SIZE_FORMAT "->" SIZE_FORMAT " entries, " - SIZE_FORMAT "(%.0f%%->%.0f%%) registered, " - SIZE_FORMAT "(%.0f%%->%.0f%%) unregistered", + "%zu->%zu entries, " + "%zu(%.0f%%->%.0f%%) registered, " + "%zu(%.0f%%->%.0f%%) unregistered", _size, new_size, _nregistered, percent_of(_nregistered, _size), percent_of(_nregistered, new_size), _nunregistered, percent_of(_nunregistered, _size), 0.0); diff --git a/src/hotspot/share/gc/z/zNMethodTableIteration.cpp b/src/hotspot/share/gc/z/zNMethodTableIteration.cpp index d6eb728f9614d..f34f520875237 100644 --- a/src/hotspot/share/gc/z/zNMethodTableIteration.cpp +++ b/src/hotspot/share/gc/z/zNMethodTableIteration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zNMethodTableEntry.hpp" #include "gc/z/zNMethodTableIteration.hpp" #include "memory/iterator.hpp" diff --git a/src/hotspot/share/gc/z/zNUMA.cpp b/src/hotspot/share/gc/z/zNUMA.cpp index 2ee790ede30c3..2c37b25f87bb9 100644 --- a/src/hotspot/share/gc/z/zNUMA.cpp +++ b/src/hotspot/share/gc/z/zNUMA.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zNUMA.hpp" diff --git a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp index c63b989dc4eb0..a4484ba10237b 100644 --- a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp +++ b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zThreadLocalData.hpp" #include "gc/z/zObjArrayAllocator.hpp" #include "gc/z/zUtils.inline.hpp" diff --git a/src/hotspot/share/gc/z/zObjectAllocator.cpp b/src/hotspot/share/gc/z/zObjectAllocator.cpp index c088e20244ae0..81a92aa6cc646 100644 --- a/src/hotspot/share/gc/z/zObjectAllocator.cpp +++ b/src/hotspot/share/gc/z/zObjectAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zHeuristics.hpp" diff --git a/src/hotspot/share/gc/z/zPage.cpp b/src/hotspot/share/gc/z/zPage.cpp index ff56768e9ad99..5264076c8a9bf 100644 --- a/src/hotspot/share/gc/z/zPage.cpp +++ b/src/hotspot/share/gc/z/zPage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zGeneration.inline.hpp" #include "gc/z/zList.inline.hpp" diff --git a/src/hotspot/share/gc/z/zPageAllocator.cpp b/src/hotspot/share/gc/z/zPageAllocator.cpp index ecd9f3e34b9b9..7913aa68fbe1b 100644 --- a/src/hotspot/share/gc/z/zPageAllocator.cpp +++ b/src/hotspot/share/gc/z/zPageAllocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zArray.inline.hpp" @@ -207,12 +206,12 @@ ZPageAllocator::ZPageAllocator(size_t min_capacity, return; } - log_info_p(gc, init)("Min Capacity: " SIZE_FORMAT "M", min_capacity / M); - log_info_p(gc, init)("Initial Capacity: " SIZE_FORMAT "M", initial_capacity / M); - log_info_p(gc, init)("Max Capacity: " SIZE_FORMAT "M", max_capacity / M); - log_info_p(gc, init)("Soft Max Capacity: " SIZE_FORMAT "M", soft_max_capacity / M); + log_info_p(gc, init)("Min Capacity: %zuM", min_capacity / M); + log_info_p(gc, init)("Initial Capacity: %zuM", initial_capacity / M); + log_info_p(gc, init)("Max Capacity: %zuM", max_capacity / M); + log_info_p(gc, init)("Soft Max Capacity: %zuM", soft_max_capacity / M); if (ZPageSizeMedium > 0) { - log_info_p(gc, init)("Medium Page Size: " SIZE_FORMAT "M", ZPageSizeMedium / M); + log_info_p(gc, init)("Medium Page Size: %zuM", ZPageSizeMedium / M); } else { log_info_p(gc, init)("Medium Page Size: N/A"); } @@ -377,7 +376,7 @@ void ZPageAllocator::decrease_capacity(size_t size, bool set_max_capacity) { if (set_max_capacity) { // Adjust current max capacity to avoid further attempts to increase capacity log_error_p(gc)("Forced to lower max Java heap size from " - SIZE_FORMAT "M(%.0f%%) to " SIZE_FORMAT "M(%.0f%%)", + "%zuM(%.0f%%) to %zuM(%.0f%%)", _current_max_capacity / M, percent_of(_current_max_capacity, _max_capacity), _capacity / M, percent_of(_capacity, _max_capacity)); @@ -650,7 +649,7 @@ ZPage* ZPageAllocator::alloc_page_create(ZPageAllocation* allocation) { // Update statistics ZStatInc(ZCounterPageCacheFlush, flushed); - log_debug(gc, heap)("Page Cache Flushed: " SIZE_FORMAT "M", flushed / M); + log_debug(gc, heap)("Page Cache Flushed: %zuM", flushed / M); } // Allocate any remaining physical memory. Capacity and used has diff --git a/src/hotspot/share/gc/z/zPageCache.cpp b/src/hotspot/share/gc/z/zPageCache.cpp index 163bb395560de..b689a274de06c 100644 --- a/src/hotspot/share/gc/z/zPageCache.cpp +++ b/src/hotspot/share/gc/z/zPageCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zList.inline.hpp" #include "gc/z/zNUMA.hpp" diff --git a/src/hotspot/share/gc/z/zPageTable.cpp b/src/hotspot/share/gc/z/zPageTable.cpp index 459d26e9df3f4..9a4bbc85d0450 100644 --- a/src/hotspot/share/gc/z/zPageTable.cpp +++ b/src/hotspot/share/gc/z/zPageTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zGranuleMap.inline.hpp" #include "gc/z/zPage.inline.hpp" diff --git a/src/hotspot/share/gc/z/zPhysicalMemory.cpp b/src/hotspot/share/gc/z/zPhysicalMemory.cpp index a04fce2d9a9d8..541e60051c312 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemory.cpp +++ b/src/hotspot/share/gc/z/zPhysicalMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zArray.inline.hpp" @@ -277,7 +276,7 @@ void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max } log_info_p(gc, init)("Uncommit: Enabled"); - log_info_p(gc, init)("Uncommit Delay: " UINTX_FORMAT "s", ZUncommitDelay); + log_info_p(gc, init)("Uncommit Delay: %zus", ZUncommitDelay); } void ZPhysicalMemoryManager::alloc(ZPhysicalMemory& pmem, size_t size) { diff --git a/src/hotspot/share/gc/z/zReferenceProcessor.cpp b/src/hotspot/share/gc/z/zReferenceProcessor.cpp index 797bd96353687..1af4deaec0339 100644 --- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp +++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "gc/shared/referencePolicy.hpp" #include "gc/shared/referenceProcessorStats.hpp" diff --git a/src/hotspot/share/gc/z/zRelocate.cpp b/src/hotspot/share/gc/z/zRelocate.cpp index 7f69c0752bc5a..805044f9deb88 100644 --- a/src/hotspot/share/gc/z/zRelocate.cpp +++ b/src/hotspot/share/gc/z/zRelocate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zAbort.inline.hpp" diff --git a/src/hotspot/share/gc/z/zRelocationSet.cpp b/src/hotspot/share/gc/z/zRelocationSet.cpp index 5c82f55bbbfe7..8cc7bceb8e849 100644 --- a/src/hotspot/share/gc/z/zRelocationSet.cpp +++ b/src/hotspot/share/gc/z/zRelocationSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zArray.inline.hpp" #include "gc/z/zCollectedHeap.hpp" #include "gc/z/zForwarding.inline.hpp" diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp index ec904b914fb0b..03835689ec594 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zArray.inline.hpp" #include "gc/z/zForwarding.inline.hpp" @@ -153,7 +152,7 @@ void ZRelocationSetSelectorGroup::select_inner() { } log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): %d->%d, " - "%.1f%% relative defragmentation, " SIZE_FORMAT " forwarding entries, %s, live %d", + "%.1f%% relative defragmentation, %zu forwarding entries, %s, live %d", _name, from, to, diff_reclaimable, from_forwarding_entries, (selected_from == from) ? "Selected" : "Rejected", int(page_live_bytes * 100 / page->size())); @@ -175,7 +174,7 @@ void ZRelocationSetSelectorGroup::select_inner() { _stats[i]._npages_selected = npages_selected[i]; } - log_debug(gc, reloc)("Relocation Set (%s Pages): %d->%d, %d skipped, " SIZE_FORMAT " forwarding entries", + log_debug(gc, reloc)("Relocation Set (%s Pages): %d->%d, %d skipped, %zu forwarding entries", _name, selected_from, selected_to, npages - selected_from, selected_forwarding_entries); } diff --git a/src/hotspot/share/gc/z/zRemembered.cpp b/src/hotspot/share/gc/z/zRemembered.cpp index 18657c44c5c4f..3bb17152d4192 100644 --- a/src/hotspot/share/gc/z/zRemembered.cpp +++ b/src/hotspot/share/gc/z/zRemembered.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zForwarding.inline.hpp" #include "gc/z/zGeneration.inline.hpp" @@ -551,7 +550,7 @@ class ZRememberedScanMarkFollowTask : public ZRestartableTask { // publish such marking stacks to prevent that generation from getting a mark continue. // We also flush in case of a resize where a new worker thread continues the marking // work, causing a mark continue for the collected generation. - ZHeap::heap()->mark_flush_and_free(Thread::current()); + ZHeap::heap()->mark_flush(Thread::current()); } virtual void resize_workers(uint nworkers) { diff --git a/src/hotspot/share/gc/z/zRememberedSet.cpp b/src/hotspot/share/gc/z/zRememberedSet.cpp index f605401648dfb..f833c5b233616 100644 --- a/src/hotspot/share/gc/z/zRememberedSet.cpp +++ b/src/hotspot/share/gc/z/zRememberedSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zBitMap.inline.hpp" #include "gc/z/zHeap.inline.hpp" @@ -206,5 +205,5 @@ bool ZRememberedSetContainingInLiveIterator::next(ZRememberedSetContaining* cont } void ZRememberedSetContainingInLiveIterator::print_statistics() const { - _page->log_msg(" (remembered iter count: " SIZE_FORMAT " skipped: " SIZE_FORMAT ")", _count, _count_skipped); + _page->log_msg(" (remembered iter count: %zu skipped: %zu)", _count, _count_skipped); } diff --git a/src/hotspot/share/gc/z/zResurrection.cpp b/src/hotspot/share/gc/z/zResurrection.cpp index 2e7b4c7b4b98e..4e9aa0448da3f 100644 --- a/src/hotspot/share/gc/z/zResurrection.cpp +++ b/src/hotspot/share/gc/z/zResurrection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zResurrection.hpp" #include "runtime/atomic.hpp" #include "runtime/safepoint.hpp" diff --git a/src/hotspot/share/gc/z/zRootsIterator.cpp b/src/hotspot/share/gc/z/zRootsIterator.cpp index 086d90781dd63..d5c413f593881 100644 --- a/src/hotspot/share/gc/z/zRootsIterator.cpp +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/oopStorageSetParState.inline.hpp" #include "gc/z/zNMethod.hpp" diff --git a/src/hotspot/share/gc/z/zRuntimeWorkers.cpp b/src/hotspot/share/gc/z/zRuntimeWorkers.cpp index 488df66edc61c..f19e5cd54697a 100644 --- a/src/hotspot/share/gc/z/zRuntimeWorkers.cpp +++ b/src/hotspot/share/gc/z/zRuntimeWorkers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zRuntimeWorkers.hpp" diff --git a/src/hotspot/share/gc/z/zServiceability.cpp b/src/hotspot/share/gc/z/zServiceability.cpp index 50fc172f55c02..076d310ff717c 100644 --- a/src/hotspot/share/gc/z/zServiceability.cpp +++ b/src/hotspot/share/gc/z/zServiceability.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/generationCounters.hpp" #include "gc/shared/hSpaceCounters.hpp" #include "gc/z/zCollectedHeap.hpp" @@ -67,7 +66,7 @@ class ZGenerationCounters : public GenerationCounters { curr_capacity) {} void update_capacity(size_t capacity) { - _current_size->set_value(capacity); + update_all(capacity); } }; diff --git a/src/hotspot/share/gc/z/zStackWatermark.cpp b/src/hotspot/share/gc/z/zStackWatermark.cpp index a4962416f811f..4a50dea0cec01 100644 --- a/src/hotspot/share/gc/z/zStackWatermark.cpp +++ b/src/hotspot/share/gc/z/zStackWatermark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zBarrier.inline.hpp" #include "gc/z/zGeneration.inline.hpp" diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index 96cfa7d3a3718..558ccdf105acd 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAbort.inline.hpp" #include "gc/z/zCollectedHeap.hpp" @@ -48,12 +47,12 @@ #include -#define ZSIZE_FMT SIZE_FORMAT "M(%.0f%%)" +#define ZSIZE_FMT "%zuM(%.0f%%)" #define ZSIZE_ARGS_WITH_MAX(size, max) ((size) / M), (percent_of(size, max)) #define ZSIZE_ARGS(size) ZSIZE_ARGS_WITH_MAX(size, ZStatHeap::max_capacity()) #define ZTABLE_ARGS_NA "%9s", "-" -#define ZTABLE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0f%%)", \ +#define ZTABLE_ARGS(size) "%8zuM (%.0f%%)", \ ((size) / M), (percent_of(size, ZStatHeap::max_capacity())) // @@ -1425,8 +1424,7 @@ ZStatMark::ZStatMark() _nproactiveflush(), _nterminateflush(), _ntrycomplete(), - _ncontinue(), - _mark_stack_usage() {} + _ncontinue() {} void ZStatMark::at_mark_start(size_t nstripes) { _nstripes = nstripes; @@ -1442,24 +1440,18 @@ void ZStatMark::at_mark_end(size_t nproactiveflush, _ncontinue = ncontinue; } -void ZStatMark::at_mark_free(size_t mark_stack_usage) { - _mark_stack_usage = mark_stack_usage; -} - void ZStatMark::print() { log_info(gc, marking)("Mark: " - SIZE_FORMAT " stripe(s), " - SIZE_FORMAT " proactive flush(es), " - SIZE_FORMAT " terminate flush(es), " - SIZE_FORMAT " completion(s), " - SIZE_FORMAT " continuation(s) ", + "%zu stripe(s), " + "%zu proactive flush(es), " + "%zu terminate flush(es), " + "%zu completion(s), " + "%zu continuation(s) ", _nstripes, _nproactiveflush, _nterminateflush, _ntrycomplete, _ncontinue); - - log_info(gc, marking)("Mark Stack Usage: " SIZE_FORMAT "M", _mark_stack_usage / M); } // @@ -1544,7 +1536,7 @@ void ZStatRelocation::print_page_summary() { } print_summary("Large", large_summary, 0 /* in_place_count */); - lt.print("Forwarding Usage: " SIZE_FORMAT "M", _forwarding_usage / M); + lt.print("Forwarding Usage: %zuM", _forwarding_usage / M); } void ZStatRelocation::print_age_table() { @@ -1610,13 +1602,13 @@ void ZStatRelocation::print_age_table() { lt.print("%s", create_age_table() .left(ZTABLE_ARGS(total[i] - live[i])) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, + .left("%7zu / %zu", _selector_stats.small(age).npages_candidates(), _selector_stats.small(age).npages_selected()) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, + .left("%7zu / %zu", _selector_stats.medium(age).npages_candidates(), _selector_stats.medium(age).npages_selected()) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, + .left("%7zu / %zu", _selector_stats.large(age).npages_candidates(), _selector_stats.large(age).npages_selected()) .end()); @@ -1627,7 +1619,7 @@ void ZStatRelocation::print_age_table() { // Stat nmethods // void ZStatNMethods::print() { - log_info(gc, nmethod)("NMethods: " SIZE_FORMAT " registered, " SIZE_FORMAT " unregistered", + log_info(gc, nmethod)("NMethods: %zu registered, %zu unregistered", ZNMethodTable::registered_nmethods(), ZNMethodTable::unregistered_nmethods()); } @@ -1638,8 +1630,8 @@ void ZStatNMethods::print() { void ZStatMetaspace::print() { const MetaspaceCombinedStats stats = MetaspaceUtils::get_combined_statistics(); log_info(gc, metaspace)("Metaspace: " - SIZE_FORMAT "M used, " - SIZE_FORMAT "M committed, " SIZE_FORMAT "M reserved", + "%zuM used, " + "%zuM committed, %zuM reserved", stats.used() / M, stats.committed() / M, stats.reserved() / M); diff --git a/src/hotspot/share/gc/z/zStat.hpp b/src/hotspot/share/gc/z/zStat.hpp index d169385791890..0078c9636264a 100644 --- a/src/hotspot/share/gc/z/zStat.hpp +++ b/src/hotspot/share/gc/z/zStat.hpp @@ -506,7 +506,6 @@ class ZStatMark { size_t nterminateflush, size_t ntrycomplete, size_t ncontinue); - void at_mark_free(size_t mark_stack_usage); void print(); }; diff --git a/src/hotspot/share/gc/z/zStoreBarrierBuffer.cpp b/src/hotspot/share/gc/z/zStoreBarrierBuffer.cpp index 78106aad729b7..a4895ca11cc26 100644 --- a/src/hotspot/share/gc/z/zStoreBarrierBuffer.cpp +++ b/src/hotspot/share/gc/z/zStoreBarrierBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zBarrier.inline.hpp" diff --git a/src/hotspot/share/gc/z/zTask.cpp b/src/hotspot/share/gc/z/zTask.cpp index 3125b67c29a95..208a20c1914a6 100644 --- a/src/hotspot/share/gc/z/zTask.cpp +++ b/src/hotspot/share/gc/z/zTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zTask.hpp" ZTask::Task::Task(ZTask* task, const char* name) diff --git a/src/hotspot/share/gc/z/zThread.cpp b/src/hotspot/share/gc/z/zThread.cpp index 3203da6430f35..0e5860a3951bd 100644 --- a/src/hotspot/share/gc/z/zThread.cpp +++ b/src/hotspot/share/gc/z/zThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zThread.hpp" #include "runtime/mutexLocker.hpp" diff --git a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp index 530db62f258df..f0261f51d3c98 100644 --- a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp +++ b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/tlab_globals.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zStackWatermark.hpp" diff --git a/src/hotspot/share/gc/z/zTracer.cpp b/src/hotspot/share/gc/z/zTracer.cpp index 7c7fff5624ccc..6ab16f6c88693 100644 --- a/src/hotspot/share/gc/z/zTracer.cpp +++ b/src/hotspot/share/gc/z/zTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gcId.hpp" #include "gc/z/zGeneration.inline.hpp" #include "gc/z/zGlobals.hpp" diff --git a/src/hotspot/share/gc/z/zUncoloredRoot.cpp b/src/hotspot/share/gc/z/zUncoloredRoot.cpp index 505e10628d7f8..03b9862f2a379 100644 --- a/src/hotspot/share/gc/z/zUncoloredRoot.cpp +++ b/src/hotspot/share/gc/z/zUncoloredRoot.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zUncoloredRoot.inline.hpp" void ZUncoloredRootClosure::do_oop(oop* p) { diff --git a/src/hotspot/share/gc/z/zUncommitter.cpp b/src/hotspot/share/gc/z/zUncommitter.cpp index a6a455d4a08b4..50731592108c6 100644 --- a/src/hotspot/share/gc/z/zUncommitter.cpp +++ b/src/hotspot/share/gc/z/zUncommitter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zLock.inline.hpp" @@ -80,7 +79,7 @@ void ZUncommitter::run_thread() { if (uncommitted > 0) { // Update statistics ZStatInc(ZCounterUncommit, uncommitted); - log_info(gc, heap)("Uncommitted: " SIZE_FORMAT "M(%.0f%%)", + log_info(gc, heap)("Uncommitted: %zuM(%.0f%%)", uncommitted / M, percent_of(uncommitted, ZHeap::heap()->max_capacity())); // Send event diff --git a/src/hotspot/share/gc/z/zUnload.cpp b/src/hotspot/share/gc/z/zUnload.cpp index 03827a6929dd3..3dc7ecd3edc41 100644 --- a/src/hotspot/share/gc/z/zUnload.cpp +++ b/src/hotspot/share/gc/z/zUnload.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeBehaviours.hpp" diff --git a/src/hotspot/share/gc/z/zUnmapper.cpp b/src/hotspot/share/gc/z/zUnmapper.cpp index b6ef40b6b059f..edd31805c49eb 100644 --- a/src/hotspot/share/gc/z/zUnmapper.cpp +++ b/src/hotspot/share/gc/z/zUnmapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zList.inline.hpp" @@ -70,11 +69,11 @@ bool ZUnmapper::try_enqueue(ZPage* page) { _warned_sync_unmapping = true; log_warning_p(gc)("WARNING: Encountered synchronous unmapping because asynchronous unmapping could not keep up"); } - log_debug(gc, unmap)("Synchronous unmapping " SIZE_FORMAT "M page", page->size() / M); + log_debug(gc, unmap)("Synchronous unmapping %zuM page", page->size() / M); return false; } - log_trace(gc, unmap)("Asynchronous unmapping " SIZE_FORMAT "M page (" SIZE_FORMAT "M / " SIZE_FORMAT "M enqueued)", + log_trace(gc, unmap)("Asynchronous unmapping %zuM page (%zuM / %zuM enqueued)", page->size() / M, _enqueued_bytes / M, queue_capacity() / M); _queue.insert_last(page); diff --git a/src/hotspot/share/gc/z/zUtils.cpp b/src/hotspot/share/gc/z/zUtils.cpp index 7997242f39124..73d9c42d5fb16 100644 --- a/src/hotspot/share/gc/z/zUtils.cpp +++ b/src/hotspot/share/gc/z/zUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/z/zUtils.hpp" #include "runtime/nonJavaThread.hpp" diff --git a/src/hotspot/share/gc/z/zVerify.cpp b/src/hotspot/share/gc/z/zVerify.cpp index 03b50e110e4c4..8e2022d781a4c 100644 --- a/src/hotspot/share/gc/z/zVerify.cpp +++ b/src/hotspot/share/gc/z/zVerify.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/isGCActiveMark.hpp" @@ -515,7 +514,7 @@ static ZStoreBarrierBufferTable* z_verify_store_barrier_buffer_table = nullptr; #define BAD_REMSET_ARG(p, ptr, addr) \ "Missing remembered set at " PTR_FORMAT " pointing at " PTR_FORMAT \ - " (" PTR_FORMAT " + " INTX_FORMAT ")" \ + " (" PTR_FORMAT " + %zd)" \ , p2i(p), untype(ptr), untype(addr), p2i(p) - untype(addr) class ZVerifyRemsetBeforeOopClosure : public BasicOopIterateClosure { diff --git a/src/hotspot/share/gc/z/zVirtualMemory.cpp b/src/hotspot/share/gc/z/zVirtualMemory.cpp index f645eef740840..ccc30626a3fd0 100644 --- a/src/hotspot/share/gc/z/zVirtualMemory.cpp +++ b/src/hotspot/share/gc/z/zVirtualMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.inline.hpp" @@ -138,7 +137,7 @@ size_t ZVirtualMemoryManager::reserve_discontiguous(size_t size) { } bool ZVirtualMemoryManager::reserve_contiguous(zoffset start, size_t size) { - assert(is_aligned(size, ZGranuleSize), "Must be granule aligned " SIZE_FORMAT_X, size); + assert(is_aligned(size, ZGranuleSize), "Must be granule aligned 0x%zx", size); // Reserve address views const zaddress_unsafe addr = ZOffset::address_unsafe(start); @@ -201,7 +200,7 @@ bool ZVirtualMemoryManager::reserve(size_t max_capacity) { (contiguous ? "Contiguous" : "Discontiguous"), (limit == ZAddressOffsetMax ? "Unrestricted" : "Restricted"), (reserved == size ? "Complete" : "Degraded")); - log_info_p(gc, init)("Address Space Size: " SIZE_FORMAT "M", reserved / M); + log_info_p(gc, init)("Address Space Size: %zuM", reserved / M); // Record reserved _reserved = reserved; diff --git a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp index c40aae19a5fbc..7373f451cea3b 100644 --- a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp +++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zBarrier.inline.hpp" diff --git a/src/hotspot/share/gc/z/zWorkers.cpp b/src/hotspot/share/gc/z/zWorkers.cpp index 7db603c73bae5..1e7144a0c261e 100644 --- a/src/hotspot/share/gc/z/zWorkers.cpp +++ b/src/hotspot/share/gc/z/zWorkers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zHeap.inline.hpp" diff --git a/src/hotspot/share/gc/z/z_globals.hpp b/src/hotspot/share/gc/z/z_globals.hpp index 4e3076329691b..4555b470cac92 100644 --- a/src/hotspot/share/gc/z/z_globals.hpp +++ b/src/hotspot/share/gc/z/z_globals.hpp @@ -41,10 +41,6 @@ "Maximum allowed heap fragmentation") \ range(0, 100) \ \ - product(size_t, ZMarkStackSpaceLimit, 8*G, \ - "Maximum number of bytes allocated for mark stacks") \ - range(32*M, 1024*G) \ - \ product(double, ZCollectionInterval, 0, \ "Force GC at a fixed time interval (in seconds). " \ "Backwards compatible alias for ZCollectionIntervalMajor") \ diff --git a/src/hotspot/share/include/cds.h b/src/hotspot/share/include/cds.h index eb8010d625fdc..16d9d74e3982f 100644 --- a/src/hotspot/share/include/cds.h +++ b/src/hotspot/share/include/cds.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,6 +70,7 @@ typedef struct CDSFileMapRegion { // (The base address is the bottom of the BM region). size_t _ptrmap_size_in_bits; char* _mapped_base; // Actually mapped address (null if this region is not mapped). + bool _in_reserved_space; // Is this region in a ReservedSpace } CDSFileMapRegion; // This portion of the archive file header must remain unchanged for diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 474d5baa487bd..c1d20387d0db9 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,9 @@ #include #include "jni.h" -#include "jvm_md.h" #include "jvm_constants.h" #include "jvm_io.h" +#include "jvm_md.h" #ifdef __cplusplus extern "C" { @@ -546,21 +546,9 @@ JVM_GetClassInterfaces(JNIEnv *env, jclass cls); JNIEXPORT jboolean JNICALL JVM_IsInterface(JNIEnv *env, jclass cls); -JNIEXPORT jobject JNICALL -JVM_GetProtectionDomain(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsArrayClass(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); - JNIEXPORT jboolean JNICALL JVM_IsHiddenClass(JNIEnv *env, jclass cls); -JNIEXPORT jint JNICALL -JVM_GetClassModifiers(JNIEnv *env, jclass cls); - JNIEXPORT jobjectArray JNICALL JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); diff --git a/src/hotspot/share/interpreter/abstractInterpreter.cpp b/src/hotspot/share/interpreter/abstractInterpreter.cpp index 616ba29c62b33..18cd9babf0592 100644 --- a/src/hotspot/share/interpreter/abstractInterpreter.cpp +++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "cds/metaspaceShared.hpp" diff --git a/src/hotspot/share/interpreter/bootstrapInfo.cpp b/src/hotspot/share/interpreter/bootstrapInfo.cpp index 44ef81666031f..c8553615d0c64 100644 --- a/src/hotspot/share/interpreter/bootstrapInfo.cpp +++ b/src/hotspot/share/interpreter/bootstrapInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/interpreter/bytecode.cpp b/src/hotspot/share/interpreter/bytecode.cpp index a1d125ed162a5..37feb834a5d1f 100644 --- a/src/hotspot/share/interpreter/bytecode.cpp +++ b/src/hotspot/share/interpreter/bytecode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecode.inline.hpp" #include "interpreter/linkResolver.hpp" #include "oops/constantPool.hpp" diff --git a/src/hotspot/share/interpreter/bytecodeHistogram.cpp b/src/hotspot/share/interpreter/bytecodeHistogram.cpp index 9b023f1a66272..e416aa40e7b7f 100644 --- a/src/hotspot/share/interpreter/bytecodeHistogram.cpp +++ b/src/hotspot/share/interpreter/bytecodeHistogram.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "memory/resourceArea.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/share/interpreter/bytecodeStream.cpp b/src/hotspot/share/interpreter/bytecodeStream.cpp index 418795a856bf0..7454c74982822 100644 --- a/src/hotspot/share/interpreter/bytecodeStream.cpp +++ b/src/hotspot/share/interpreter/bytecodeStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/bytecodes.hpp" #include "runtime/handles.inline.hpp" diff --git a/src/hotspot/share/interpreter/bytecodeTracer.cpp b/src/hotspot/share/interpreter/bytecodeTracer.cpp index cdb53b62f8c40..f576ad2f07f15 100644 --- a/src/hotspot/share/interpreter/bytecodeTracer.cpp +++ b/src/hotspot/share/interpreter/bytecodeTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classPrinter.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/bytecodeHistogram.hpp" @@ -105,7 +104,7 @@ class BytecodePrinter { // the incoming method. We could lose a line of trace output. // This is acceptable in a debug-only feature. st->cr(); - st->print("[" UINTX_FORMAT "] ", Thread::current()->osthread()->thread_id_for_printing()); + st->print("[%zu] ", Thread::current()->osthread()->thread_id_for_printing()); method->print_name(st); st->cr(); _current_method = method(); @@ -128,7 +127,7 @@ class BytecodePrinter { code == Bytecodes::_return_register_finalizer || (code >= Bytecodes::_ireturn && code <= Bytecodes::_return)) { int bci = (int)(bcp - method->code_base()); - st->print("[" UINTX_FORMAT "] ", Thread::current()->osthread()->thread_id_for_printing()); + st->print("[%zu] ", Thread::current()->osthread()->thread_id_for_printing()); if (Verbose) { st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s", BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code)); diff --git a/src/hotspot/share/interpreter/bytecodeUtils.cpp b/src/hotspot/share/interpreter/bytecodeUtils.cpp index 9c76a6c571b09..eb4557d6ba09d 100644 --- a/src/hotspot/share/interpreter/bytecodeUtils.cpp +++ b/src/hotspot/share/interpreter/bytecodeUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" #include "gc/shared/gcLocker.hpp" diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp index c1304df6d3413..1526b3c330e9a 100644 --- a/src/hotspot/share/interpreter/bytecodes.cpp +++ b/src/hotspot/share/interpreter/bytecodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecodes.hpp" #include "memory/resourceArea.hpp" #include "oops/method.hpp" diff --git a/src/hotspot/share/interpreter/interpreter.cpp b/src/hotspot/share/interpreter/interpreter.cpp index cba26f5aa6a6d..6272deea34939 100644 --- a/src/hotspot/share/interpreter/interpreter.cpp +++ b/src/hotspot/share/interpreter/interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "compiler/disassembler.hpp" diff --git a/src/hotspot/share/interpreter/interpreter.hpp b/src/hotspot/share/interpreter/interpreter.hpp index 85f9be5b3db04..800429913fd95 100644 --- a/src/hotspot/share/interpreter/interpreter.hpp +++ b/src/hotspot/share/interpreter/interpreter.hpp @@ -44,7 +44,6 @@ class InterpreterMacroAssembler; class InterpreterCodelet: public Stub { friend class VMStructs; - friend class CodeCacheDumper; // possible extension [do not remove] private: NOT_PRODUCT(AsmRemarks _asm_remarks;) // Comments for annotating assembler output. NOT_PRODUCT(DbgStrings _dbg_strings;) // Debug strings used in generated code. diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp index 9d953d9db54fd..2377c74868499 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/vmClasses.hpp" @@ -1431,38 +1430,6 @@ void SignatureHandlerLibrary::add(const methodHandle& method) { #endif // ASSERT } -void SignatureHandlerLibrary::add(uint64_t fingerprint, address handler) { - int handler_index = -1; - // use customized signature handler - MutexLocker mu(SignatureHandlerLibrary_lock); - // make sure data structure is initialized - initialize(); - fingerprint = InterpreterRuntime::normalize_fast_native_fingerprint(fingerprint); - handler_index = _fingerprints->find(fingerprint); - // create handler if necessary - if (handler_index < 0) { - if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) { - tty->cr(); - tty->print_cr("argument handler #%d at " PTR_FORMAT " for fingerprint " UINT64_FORMAT, - _handlers->length(), - p2i(handler), - fingerprint); - } - _fingerprints->append(fingerprint); - _handlers->append(handler); - } else { - if (PrintSignatureHandlers) { - tty->cr(); - tty->print_cr("duplicate argument handler #%d for fingerprint " UINT64_FORMAT "(old: " PTR_FORMAT ", new : " PTR_FORMAT ")", - _handlers->length(), - fingerprint, - p2i(_handlers->at(handler_index)), - p2i(handler)); - } - } -} - - BufferBlob* SignatureHandlerLibrary::_handler_blob = nullptr; address SignatureHandlerLibrary::_handler = nullptr; GrowableArray* SignatureHandlerLibrary::_fingerprints = nullptr; diff --git a/src/hotspot/share/interpreter/interpreterRuntime.hpp b/src/hotspot/share/interpreter/interpreterRuntime.hpp index 3635433f43432..3cc7a938a6aa0 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.hpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp @@ -192,7 +192,6 @@ class SignatureHandlerLibrary: public AllStatic { public: static void add(const methodHandle& method); - static void add(uint64_t fingerprint, address handler); }; #endif // SHARE_INTERPRETER_INTERPRETERRUNTIME_HPP diff --git a/src/hotspot/share/interpreter/invocationCounter.cpp b/src/hotspot/share/interpreter/invocationCounter.cpp index 6793ff039e060..7133d8beb62ed 100644 --- a/src/hotspot/share/interpreter/invocationCounter.cpp +++ b/src/hotspot/share/interpreter/invocationCounter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compiler_globals.hpp" #include "interpreter/invocationCounter.hpp" @@ -61,7 +60,7 @@ void InvocationCounter::reset() { void InvocationCounter::print() { uint counter = raw_counter(); - tty->print_cr("invocation count: up = %d, limit = " INTX_FORMAT ", carry = %s", + tty->print_cr("invocation count: up = %d, limit = %zd, carry = %s", extract_count(counter), limit(), extract_carry(counter) ? "true" : "false"); } diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index ca8a85c8bba5f..b26c643d15fce 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveUtils.hpp" #include "classfile/classLoader.hpp" #include "classfile/defaultMethods.hpp" @@ -583,7 +582,7 @@ void LinkResolver::check_method_accessability(Klass* ref_klass, resolved_klass->is_array_klass()) { // We need to change "protected" to "public". assert(flags.is_protected(), "clone not protected?"); - jint new_flags = flags.as_int(); + u2 new_flags = flags.as_method_flags(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; flags.set_flags(new_flags); diff --git a/src/hotspot/share/interpreter/oopMapCache.cpp b/src/hotspot/share/interpreter/oopMapCache.cpp index 3406c85df7fe0..62ce860594b9b 100644 --- a/src/hotspot/share/interpreter/oopMapCache.cpp +++ b/src/hotspot/share/interpreter/oopMapCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/oopMapCache.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/interpreter/rewriter.cpp b/src/hotspot/share/interpreter/rewriter.cpp index afc8df4b9a0a2..d64954b50bdd4 100644 --- a/src/hotspot/share/interpreter/rewriter.cpp +++ b/src/hotspot/share/interpreter/rewriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/share/interpreter/templateInterpreter.cpp b/src/hotspot/share/interpreter/templateInterpreter.cpp index dc3e4b67b33fd..0dd82addbfead 100644 --- a/src/hotspot/share/interpreter/templateInterpreter.cpp +++ b/src/hotspot/share/interpreter/templateInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "interpreter/interp_masm.hpp" diff --git a/src/hotspot/share/interpreter/templateInterpreter.hpp b/src/hotspot/share/interpreter/templateInterpreter.hpp index 224d9b973edf7..8f118bb6ec828 100644 --- a/src/hotspot/share/interpreter/templateInterpreter.hpp +++ b/src/hotspot/share/interpreter/templateInterpreter.hpp @@ -88,7 +88,6 @@ class TemplateInterpreter: public AbstractInterpreter { friend class InterpreterMacroAssembler; friend class TemplateInterpreterGenerator; friend class TemplateTable; - friend class CodeCacheExtensions; // friend class Interpreter; public: diff --git a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp index 91c302888431e..e9f1e568a19bf 100644 --- a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp +++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" @@ -244,7 +243,6 @@ void TemplateInterpreterGenerator::generate_all() { set_entry_points_for_all_bytes(); // installation of code in other places in the runtime - // (ExcutableCodeManager calls not needed to copy the entries) set_safepoints_for_all_bytes(); { CodeletMark cm(_masm, "deoptimization entry points"); diff --git a/src/hotspot/share/interpreter/templateTable.cpp b/src/hotspot/share/interpreter/templateTable.cpp index 28e42ca1e02ae..55dd0bb8e0f15 100644 --- a/src/hotspot/share/interpreter/templateTable.cpp +++ b/src/hotspot/share/interpreter/templateTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "interpreter/interp_masm.hpp" #include "interpreter/templateTable.hpp" diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp index 3f3632c0eea5d..43b618dcc1e13 100644 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers #include "cds/cdsConfig.hpp" #include "classfile/javaClasses.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp b/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp index 27ea1b9706719..faa36fc1ab1f5 100644 --- a/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp +++ b/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp index 56e006ab25cf3..e7ba0e8f7ca7e 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmSymbols.hpp" #include "jfr/jfr.hpp" diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp index c2a4016478735..8c3b895345f5a 100644 --- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp +++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classFileParser.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoadInfo.hpp" @@ -1322,7 +1321,7 @@ static u1* schema_extend_event_subklass_bytes(const InstanceKlass* ik, const jint new_buffer_size = extra_stream_bytes + orig_stream_size; u1* const new_buffer = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, u1, new_buffer_size); if (new_buffer == nullptr) { - log_error(jfr, system) ("Thread local allocation (native) for " SIZE_FORMAT + log_error(jfr, system) ("Thread local allocation (native) for %zu" " bytes failed in JfrEventClassTransformer::on_klass_creation", static_cast(new_buffer_size)); return nullptr; } @@ -1563,7 +1562,7 @@ static void cache_class_file_data(InstanceKlass* new_ik, const ClassFileStream* JvmtiCachedClassFileData* p = (JvmtiCachedClassFileData*)NEW_C_HEAP_ARRAY_RETURN_NULL(u1, offset_of(JvmtiCachedClassFileData, data) + stream_len, mtInternal); if (p == nullptr) { - log_error(jfr, system)("Allocation using C_HEAP_ARRAY for " SIZE_FORMAT " bytes failed in JfrEventClassTransformer::cache_class_file_data", + log_error(jfr, system)("Allocation using C_HEAP_ARRAY for %zu bytes failed in JfrEventClassTransformer::cache_class_file_data", static_cast(offset_of(JvmtiCachedClassFileData, data) + stream_len)); return; } diff --git a/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp b/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp index f8f975528cb47..31dd55f702d2d 100644 --- a/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp +++ b/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/instrumentation/jfrJvmtiAgent.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/jni/jfrUpcalls.hpp" @@ -103,7 +102,7 @@ static jclass* create_classes_array(jint classes_count, TRAPS) { if (nullptr == classes) { char error_buffer[ERROR_MSG_BUFFER_SIZE]; jio_snprintf(error_buffer, ERROR_MSG_BUFFER_SIZE, - "Thread local allocation (native) of " SIZE_FORMAT " bytes failed " + "Thread local allocation (native) of %zu bytes failed " "in retransform classes", sizeof(jclass) * classes_count); log_error(jfr, system)("%s", error_buffer); JfrJavaSupport::throw_out_of_memory_error(error_buffer, CHECK_NULL); diff --git a/src/hotspot/share/jfr/jfr.cpp b/src/hotspot/share/jfr/jfr.cpp index 1ba374ef24af9..08e2b9f66757a 100644 --- a/src/hotspot/share/jfr/jfr.cpp +++ b/src/hotspot/share/jfr/jfr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfr.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" diff --git a/src/hotspot/share/jfr/jfr.hpp b/src/hotspot/share/jfr/jfr.hpp index 4b34784558ef3..df19ebc5808d0 100644 --- a/src/hotspot/share/jfr/jfr.hpp +++ b/src/hotspot/share/jfr/jfr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ #include "jni.h" #include "memory/allStatic.hpp" -#include "utilities/exceptions.hpp" #include "oops/oopsHierarchy.hpp" +#include "utilities/exceptions.hpp" #include "utilities/globalDefinitions.hpp" class CallInfo; diff --git a/src/hotspot/share/jfr/jni/jfrJavaCall.cpp b/src/hotspot/share/jfr/jni/jfrJavaCall.cpp index 9eaf506db7309..9c0bcb415b4e0 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaCall.cpp +++ b/src/hotspot/share/jfr/jni/jfrJavaCall.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "jfr/jni/jfrJavaCall.hpp" diff --git a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp index 777c4ced8a33d..25badd191a5ea 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp +++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/modules.hpp" #include "classfile/symbolTable.hpp" diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index 143248ef714ec..e0e6979a4e6a3 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfr.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index 4702cbe467b6f..d131d070de5d5 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJniMethod.hpp" #include "jfr/jni/jfrJniMethodRegistration.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/jfr/jni/jfrUpcalls.cpp b/src/hotspot/share/jfr/jni/jfrUpcalls.cpp index 1915c127b4faf..718e62a9ce816 100644 --- a/src/hotspot/share/jfr/jni/jfrUpcalls.cpp +++ b/src/hotspot/share/jfr/jni/jfrUpcalls.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -107,7 +106,7 @@ static const size_t ERROR_MSG_BUFFER_SIZE = 256; static void log_error_and_throw_oom(jint new_bytes_length, TRAPS) { char error_buffer[ERROR_MSG_BUFFER_SIZE]; jio_snprintf(error_buffer, ERROR_MSG_BUFFER_SIZE, - "Thread local allocation (native) for " SIZE_FORMAT " bytes failed in JfrUpcalls", (size_t)new_bytes_length); + "Thread local allocation (native) for %zu bytes failed in JfrUpcalls", (size_t)new_bytes_length); log_error(jfr, system)("%s", error_buffer); JfrJavaSupport::throw_out_of_memory_error(error_buffer, CHECK); } diff --git a/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp b/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp index ea96a4ccd7aea..45fd4a7dc57dd 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/chains/bfsClosure.hpp" #include "jfr/leakprofiler/chains/dfsClosure.hpp" #include "jfr/leakprofiler/chains/edge.hpp" @@ -55,7 +54,7 @@ static void log_frontier_level_summary(size_t level, size_t edge_size) { const size_t nof_edges_in_frontier = high_idx - low_idx; log_trace(jfr, system)( - "BFS front: " SIZE_FORMAT " edges: " SIZE_FORMAT " size: " SIZE_FORMAT " [KB]", + "BFS front: %zu edges: %zu size: %zu [KB]", level, nof_edges_in_frontier, (nof_edges_in_frontier * edge_size) / K @@ -85,14 +84,14 @@ void BFSClosure::log_dfs_fallback() const { // additional information about DFS fallover log_trace(jfr, system)( - "BFS front: " SIZE_FORMAT " filled edge queue at edge: " SIZE_FORMAT, + "BFS front: %zu filled edge queue at edge: %zu", _current_frontier_level, _dfs_fallback_idx ); const size_t nof_dfs_completed_edges = _edge_queue->bottom() - _dfs_fallback_idx; log_trace(jfr, system)( - "DFS to complete " SIZE_FORMAT " edges size: " SIZE_FORMAT " [KB]", + "DFS to complete %zu edges size: %zu [KB]", nof_dfs_completed_edges, (nof_dfs_completed_edges * edge_size) / K ); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp b/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp index 4ba2e3329f818..83eee96091e00 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/chains/dfsClosure.hpp" #include "jfr/leakprofiler/chains/edge.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edge.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edge.cpp index d66c1c0f87024..9be7cf7596ddb 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edge.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "jfr/leakprofiler/chains/edge.hpp" #include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeQueue.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeQueue.cpp index 75ca304b84789..2f9a57b6dc3bb 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeQueue.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/chains/edgeQueue.hpp" #include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp" #include "jfr/recorder/storage/jfrVirtualMemory.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp index c08cc543f2f96..9aef92c41826a 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" #include "jfr/leakprofiler/chains/edgeUtils.hpp" #include "jfr/leakprofiler/sampling/objectSample.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp index edb87c7fc8e41..6a38553403d71 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "jfr/leakprofiler/chains/edge.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" @@ -72,7 +71,7 @@ const Symbol* EdgeUtils::field_name(const Edge& edge, jshort* modifiers) { JavaFieldStream jfs(ik); while (!jfs.done()) { if (offset == jfs.offset()) { - *modifiers = jfs.access_flags().as_short(); + *modifiers = jfs.access_flags().as_field_flags(); return jfs.name(); } jfs.next(); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp b/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp index b6fd556a03e7b..ca7650d68763c 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/gc_globals.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" @@ -70,9 +69,9 @@ static size_t edge_queue_memory_commit_size(size_t memory_reservation_bytes) { } static void log_edge_queue_summary(const EdgeQueue& edge_queue) { - log_trace(jfr, system)("EdgeQueue reserved size total: " SIZE_FORMAT " [KB]", edge_queue.reserved_size() / K); - log_trace(jfr, system)("EdgeQueue edges total: " SIZE_FORMAT, edge_queue.top()); - log_trace(jfr, system)("EdgeQueue liveset total: " SIZE_FORMAT " [KB]", edge_queue.live_set() / K); + log_trace(jfr, system)("EdgeQueue reserved size total: %zu [KB]", edge_queue.reserved_size() / K); + log_trace(jfr, system)("EdgeQueue edges total: %zu", edge_queue.top()); + log_trace(jfr, system)("EdgeQueue liveset total: %zu [KB]", edge_queue.live_set() / K); if (edge_queue.reserved_size() > 0) { log_trace(jfr, system)("EdgeQueue commit reserve ratio: %f\n", ((double)edge_queue.live_set() / (double)edge_queue.reserved_size())); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp index b14bbb77d2a72..04ba9477fabdd 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "gc/shared/oopStorage.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp index 8b28c4f797404..ffb583bc5f3e1 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Datadog, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" #include "jfr/leakprofiler/chains/pathToGcRootsOperation.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp index b7f9b733c0fd0..112469b9888a6 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp index eb898318c9709..519e81a69e230 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp index 87851c71cdb75..ff1f9efd01787 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfrfiles/jfrTypes.hpp" #include "jfr/leakprofiler/chains/edge.hpp" #include "jfr/leakprofiler/chains/edgeStore.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp index 57b29a09d016f..d1ae48e4a75c9 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "gc/shared/oopStorage.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp b/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp index 7ae0ef8b48463..a5b4babb2b197 100644 --- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp +++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" #include "jfr/leakprofiler/startOperation.hpp" #include "jfr/leakprofiler/stopOperation.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.cpp index 21d3338f51528..61cf8b7acf7ef 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSample.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/sampling/objectSample.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp index a004bad34cde1..86b8712698bdc 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp index 28cddeee70e85..4ff95f1775675 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/sampling/objectSample.hpp" #include "jfr/leakprofiler/sampling/sampleList.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/samplePriorityQueue.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/samplePriorityQueue.cpp index caa77d2bbb9fd..644cd25ec8a26 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/samplePriorityQueue.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/samplePriorityQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/sampling/objectSample.hpp" #include "jfr/leakprofiler/sampling/samplePriorityQueue.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.cpp b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.cpp index 0ce0068d73ff5..5aa8dd9cc95a8 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.cpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/utilities/granularTimer.hpp" long GranularTimer::_granularity = 0; diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp index f066cd5df31f2..9b06caae555b4 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" #include "jfr/leakprofiler/utilities/rootType.hpp" diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 3b5e24ca9a256..a4b9bc7890007 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -46,10 +46,10 @@ $ jfr print dump.jfr Programmatic access: - try (var rf = new RecordingFile(Path.of("dump.jfr)) { + try (var rf = new RecordingFile(Path.of("dump.jfr"))) { while (rf.hasMoreEvents()) { RecordedEvent e = rf.readEvent(); - System.out.println(e.getName() + " " + e.getDuration())); + System.out.println(e.getName() + " " + e.getDuration()); } }; !--> @@ -1220,7 +1220,7 @@ - + @@ -1241,11 +1241,6 @@ - - - - - diff --git a/src/hotspot/share/jfr/periodic/jfrCompilerQueueUtilization.cpp b/src/hotspot/share/jfr/periodic/jfrCompilerQueueUtilization.cpp index 1ba31876cb91a..a9bafa99b34b5 100644 --- a/src/hotspot/share/jfr/periodic/jfrCompilerQueueUtilization.cpp +++ b/src/hotspot/share/jfr/periodic/jfrCompilerQueueUtilization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileBroker.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrCompilerQueueUtilization.hpp" @@ -88,4 +87,4 @@ void JfrCompilerQueueUtilization::send_events() { last_sample_instant = cur_time; } -} \ No newline at end of file +} diff --git a/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.cpp b/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.cpp index 908dae2227739..ec734a505e01a 100644 --- a/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.cpp +++ b/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "utilities/macros.hpp" #if INCLUDE_MANAGEMENT #include "classfile/classLoaderDataGraph.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrModuleEvent.cpp b/src/hotspot/share/jfr/periodic/jfrModuleEvent.cpp index d9b628593a423..ed0fb23f2d7b1 100644 --- a/src/hotspot/share/jfr/periodic/jfrModuleEvent.cpp +++ b/src/hotspot/share/jfr/periodic/jfrModuleEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/moduleEntry.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrNativeMemoryEvent.cpp b/src/hotspot/share/jfr/periodic/jfrNativeMemoryEvent.cpp index 6c0584f50ff31..875db3773005f 100644 --- a/src/hotspot/share/jfr/periodic/jfrNativeMemoryEvent.cpp +++ b/src/hotspot/share/jfr/periodic/jfrNativeMemoryEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrNativeMemoryEvent.hpp" #include "nmt/memTracker.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp b/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp index 9d57cddb44808..c18248e105662 100644 --- a/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp +++ b/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/metadata/jfrSerializer.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp b/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp index 9d9ec751fa642..2d4b99d59abdf 100644 --- a/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp +++ b/src/hotspot/share/jfr/periodic/jfrOSInterface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrNetworkUtilization.hpp" #include "jfr/periodic/jfrOSInterface.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp index d9aae89b99341..f22098bb52e18 100644 --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classLoaderStats.hpp" #include "classfile/javaClasses.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp index ff1d7ad280ac3..1863b1af800be 100644 --- a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp +++ b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrThreadCPULoadEvent.hpp" diff --git a/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.cpp b/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.cpp index 1b296fc4555b3..69bf10d5fd54d 100644 --- a/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.cpp +++ b/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/dcmd/jfrDcmds.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrThreadDumpEvent.hpp" diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCallTrace.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrCallTrace.cpp index 5d12af6d9370e..72cad299f8b5e 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrCallTrace.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrCallTrace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfoRec.hpp" #include "code/nmethod.hpp" #include "code/pcDesc.hpp" diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp index 5cef25c54cb51..29f4c88881b23 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaThreadStatus.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/recorder/jfrRecorder.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp index a2e887e71a32a..26b5116a59944 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp index 02829c40a712c..04a517ff46340 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/utilities/jfrBlob.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp index 08f7d2ae87d8f..bf27fa5903172 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/jni/jfrUpcalls.hpp" #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp index f16542d13ac39..a4817cbc87d0d 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp" #include "jfr/utilities/jfrTypes.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp index f6bf3e685b6e7..cdd7adebe4fd2 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp index 4b054a86ba143..01cad49e1835e 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "code/codeBlob.hpp" #include "code/codeCache.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp index 20c1100994722..334bdc40cb33b 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "jfr/metadata/jfrSerializer.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index a53eaa474f3f0..8128674dc1e58 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/moduleEntry.hpp" @@ -227,9 +226,9 @@ static traceid method_id(KlassPtr klass, MethodPtr method) { } template -static s4 get_flags(const T* ptr) { +static u2 get_flags(const T* ptr) { assert(ptr != nullptr, "invariant"); - return ptr->access_flags().get_flags(); + return ptr->access_flags().as_unsigned_short(); } // Same as JVM_GetClassModifiers @@ -968,7 +967,7 @@ static int write_method(JfrCheckpointWriter* writer, MethodPtr method, bool leak writer->write(artifact_id(klass)); writer->write(mark_symbol(method->name(), leakp)); writer->write(mark_symbol(method->signature(), leakp)); - writer->write(static_cast(get_flags(method))); + writer->write(get_flags(method)); writer->write(get_visibility(method)); return 1; } diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp index 3db940156a800..5e70fdcb941d6 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp" #include "jfr/utilities/jfrPredicate.hpp" #include "jfr/utilities/jfrRelation.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp index d2973f748729a..7006d6c865a55 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp index 328c3a7c9e1a4..743923d674cdf 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" #include "jfr/support/jfrThreadId.inline.hpp" #include "runtime/safepoint.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp index 30f2afd880c43..e821b52870771 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp index db0faafdc99a7..8f600431333d9 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdKlassQueue.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp index f53eecad2cf9e..b487b5e667001 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp @@ -97,7 +97,7 @@ #define METHOD_USED_THIS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (THIS_EPOCH_METHOD_BIT))) #define METHOD_NOT_USED_THIS_EPOCH(kls) (!(METHOD_USED_THIS_EPOCH(kls))) #define METHOD_USED_PREVIOUS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (PREVIOUS_EPOCH_METHOD_BIT))) -#define METHOD_USED_ANY_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (EPOCH_1_METHOD_BIT) | EPOCH_0_METHOD_BIT))) +#define METHOD_USED_ANY_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (EPOCH_1_METHOD_BIT | EPOCH_0_METHOD_BIT))) #define METHOD_AND_CLASS_USED_THIS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (THIS_EPOCH_METHOD_AND_CLASS_BITS))) #define METHOD_AND_CLASS_USED_PREVIOUS_EPOCH(kls) (TRACE_ID_PREDICATE(kls, (PREVIOUS_EPOCH_METHOD_AND_CLASS_BITS))) #define METHOD_AND_CLASS_USED_ANY_EPOCH(kls) (METHOD_USED_ANY_EPOCH(kls) && USED_ANY_EPOCH(kls)) diff --git a/src/hotspot/share/jfr/recorder/jfrEventSetting.cpp b/src/hotspot/share/jfr/recorder/jfrEventSetting.cpp index 175ee30496576..13bb328d2f465 100644 --- a/src/hotspot/share/jfr/recorder/jfrEventSetting.cpp +++ b/src/hotspot/share/jfr/recorder/jfrEventSetting.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/jfrEventSetting.inline.hpp" JfrNativeSettings JfrEventSetting::_jvm_event_settings; diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp index af6543e2a75ba..d6fea53fcc910 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/javaClasses.hpp" #include "jfr/dcmd/jfrDcmds.hpp" diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp b/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp index a35b046e56c92..f697f19b4885d 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/repository/jfrChunk.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/utilities/jfrTime.hpp" diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp index 2940126374117..930f5be0b039b 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/repository/jfrChunkRotation.hpp" #include "jfr/recorder/repository/jfrChunkWriter.hpp" diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp index 4b08ea6b1354e..99fbc0e69bfad 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/repository/jfrChunk.hpp" #include "jfr/recorder/repository/jfrChunkWriter.hpp" #include "jfr/utilities/jfrTime.hpp" diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp index eaee79497bb4d..b49ce4556c7c2 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" diff --git a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp index 3bd1157ac359f..9f6071874d8d9 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfr.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/jfrRecorder.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrEvent.cpp b/src/hotspot/share/jfr/recorder/service/jfrEvent.cpp index aceeabcedf473..7462aa2fce1be 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrEvent.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/service/jfrEvent.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp index af0697b5e28ca..6b8b5f0cc8c7b 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Datadog, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/service/jfrEventThrottler.hpp" #include "jfr/utilities/jfrSpinlockHelper.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.cpp b/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.cpp index af17659e2ec36..a2e2a9d3cf0e3 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/service/jfrMemorySizer.hpp" #include "logging/log.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp index 4982e24e8987d..b212ee4ccba48 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/javaClasses.hpp" #include "jfr/dcmd/jfrDcmds.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp b/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp index cf487d48f5450..b1bddfff466a2 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/service/jfrPostBox.hpp" #include "jfr/utilities/jfrTryLock.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp index 9f24bddcd3cd7..31b2311af6ce8 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfrfiles/jfrEventClasses.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp index e1cb8e889d33e..de0a77a0c8209 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderThreadLoop.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderThreadLoop.cpp index 9742ae986de4f..d549ea55dee5a 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderThreadLoop.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderThreadLoop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/service/jfrPostBox.hpp" diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilter.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilter.cpp index bf10c531c637a..1eb057b564ec1 100644 --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilter.cpp +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/stacktrace/jfrStackFilter.hpp" #include "oops/method.hpp" #include "oops/symbol.hpp" diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilterRegistry.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilterRegistry.cpp index 481dcbdc840c6..de20cd3637570 100644 --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilterRegistry.cpp +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackFilterRegistry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/stacktrace/jfrStackFilter.hpp" #include "jfr/recorder/stacktrace/jfrStackFilterRegistry.hpp" diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp index 29cd6a17b1314..cbe686fa910ca 100644 --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTrace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp" #include "jfr/recorder/repository/jfrChunkWriter.hpp" diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp index 0cb8561ad9f92..a30c0d8f2624d 100644 --- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp +++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/metadata/jfrSerializer.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/repository/jfrChunkWriter.hpp" diff --git a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp index edbf5ef6981d8..5c734e5c3690b 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/storage/jfrBuffer.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/jfr/recorder/storage/jfrEpochStorage.inline.hpp b/src/hotspot/share/jfr/recorder/storage/jfrEpochStorage.inline.hpp index ae52f20436d9b..230d5dd1a985b 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrEpochStorage.inline.hpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrEpochStorage.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ template class RetrievalPolicy, bool Eag inline NodeType* JfrEpochStorageHost::acquire(size_t size, Thread* thread) { BufferPtr buffer = mspace_acquire_to_live_list(size, _mspace, thread); if (buffer == nullptr) { - log_warning(jfr)("Unable to allocate " SIZE_FORMAT " bytes of %s.", _mspace->min_element_size(), "epoch storage"); + log_warning(jfr)("Unable to allocate %zu bytes of %s.", _mspace->min_element_size(), "epoch storage"); return nullptr; } assert(buffer->acquired_by_self(), "invariant"); diff --git a/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp b/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp index 8812d0a8ffd80..18ed2272cfad7 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -203,7 +203,7 @@ inline bool JfrMemorySpace< Client, RetrievalPolicy, FreeListType, FullListType, // allocations are even multiples of the mspace min size static inline size_t align_allocation_size(size_t requested_size, size_t min_element_size) { if (requested_size > static_cast(min_intx)) { - assert(false, "requested size: " SIZE_FORMAT " is too large", requested_size); + assert(false, "requested size: %zu is too large", requested_size); return 0; } u8 alloc_size_bytes = min_element_size; diff --git a/src/hotspot/share/jfr/recorder/storage/jfrReferenceCountedStorage.cpp b/src/hotspot/share/jfr/recorder/storage/jfrReferenceCountedStorage.cpp index ac652905c5b83..d28b7212571d9 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrReferenceCountedStorage.cpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrReferenceCountedStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/storage/jfrReferenceCountedStorage.hpp" diff --git a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp index 8b920d163b0da..a7a21f65944bc 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -137,7 +136,7 @@ JfrStorageControl& JfrStorage::control() { } static void log_allocation_failure(const char* msg, size_t size) { - log_warning(jfr)("Unable to allocate " SIZE_FORMAT " bytes of %s.", size, msg); + log_warning(jfr)("Unable to allocate %zu bytes of %s.", size, msg); } BufferPtr JfrStorage::acquire_thread_local(Thread* thread, size_t size /* 0 */) { @@ -327,8 +326,8 @@ static void log_discard(size_t pre_full_count, size_t post_full_count, size_t am if (log_is_enabled(Debug, jfr, system)) { const size_t number_of_discards = pre_full_count - post_full_count; if (number_of_discards > 0) { - log_debug(jfr, system)("Cleared " SIZE_FORMAT " full buffer(s) of " SIZE_FORMAT" bytes.", number_of_discards, amount); - log_debug(jfr, system)("Current number of full buffers " SIZE_FORMAT "", number_of_discards); + log_debug(jfr, system)("Cleared %zu full buffer(s) of %zu bytes.", number_of_discards, amount); + log_debug(jfr, system)("Current number of full buffers %zu", number_of_discards); } } } @@ -566,7 +565,7 @@ static size_t process_full(Processor& processor, JfrFullList* list, JfrStorageCo static void log(size_t count, size_t amount, bool clear = false) { if (log_is_enabled(Debug, jfr, system)) { if (count > 0) { - log_debug(jfr, system)("%s " SIZE_FORMAT " full buffer(s) of " SIZE_FORMAT" B of data%s", + log_debug(jfr, system)("%s %zu full buffer(s) of %zu B of data%s", clear ? "Discarded" : "Wrote", count, amount, clear ? "." : " to chunk."); } } diff --git a/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp b/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp index 7691d8bb99324..52a747fdad1bb 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/storage/jfrStorageControl.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/jfr/recorder/storage/jfrVirtualMemory.cpp b/src/hotspot/share/jfr/recorder/storage/jfrVirtualMemory.cpp index 000ab5e235a34..c91da0075210d 100644 --- a/src/hotspot/share/jfr/recorder/storage/jfrVirtualMemory.cpp +++ b/src/hotspot/share/jfr/recorder/storage/jfrVirtualMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,8 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/storage/jfrVirtualMemory.hpp" +#include "memory/memoryReserver.hpp" #include "memory/virtualspace.hpp" #include "nmt/memTracker.hpp" #include "runtime/globals.hpp" @@ -97,14 +97,16 @@ JfrVirtualMemorySegment::JfrVirtualMemorySegment() : JfrVirtualMemorySegment::~JfrVirtualMemorySegment() { decommit(); - _rs.release(); + if (_rs.is_reserved()) { + MemoryReserver::release(_rs); + } } bool JfrVirtualMemorySegment::initialize(size_t reservation_size_request_bytes) { assert(is_aligned(reservation_size_request_bytes, os::vm_allocation_granularity()), "invariant"); - _rs = ReservedSpace(reservation_size_request_bytes, - os::vm_allocation_granularity(), - os::vm_page_size()); + _rs = MemoryReserver::reserve(reservation_size_request_bytes, + os::vm_allocation_granularity(), + os::vm_page_size()); if (!_rs.is_reserved()) { return false; } diff --git a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp index 217b6dbddc3c4..a9e39094f7906 100644 --- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp +++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp index f130431bcf066..f5f15be2899b2 100644 --- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp +++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/stringpool/jfrStringPoolBuffer.hpp" JfrStringPoolBuffer::JfrStringPoolBuffer() : JfrBuffer(), _string_count_pos(0), _string_count_top(0) {} diff --git a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolWriter.cpp b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolWriter.cpp index 8cbe37f1403a8..5ef64e67f0922 100644 --- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolWriter.cpp +++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPoolWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/stringpool/jfrStringPool.hpp" #include "jfr/recorder/stringpool/jfrStringPoolWriter.hpp" #include "jfr/writers/jfrEventWriterHost.inline.hpp" diff --git a/src/hotspot/share/jfr/support/jfrAdaptiveSampler.cpp b/src/hotspot/share/jfr/support/jfrAdaptiveSampler.cpp index 9ef85ecbbe9fb..aa351a81ff3c3 100644 --- a/src/hotspot/share/jfr/support/jfrAdaptiveSampler.cpp +++ b/src/hotspot/share/jfr/support/jfrAdaptiveSampler.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Datadog, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "jfr/support/jfrAdaptiveSampler.hpp" #include "jfr/utilities/jfrRandom.inline.hpp" #include "jfr/utilities/jfrSpinlockHelper.hpp" diff --git a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp index 8d56be89c13c2..a1245d7bafe3a 100644 --- a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp +++ b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" #include "jfr/support/jfrAllocationTracer.hpp" #include "jfr/support/jfrObjectAllocationSample.hpp" diff --git a/src/hotspot/share/jfr/support/jfrDeprecationEventWriter.cpp b/src/hotspot/share/jfr/support/jfrDeprecationEventWriter.cpp index 4aa61bdddff7f..49b5e20e49a8b 100644 --- a/src/hotspot/share/jfr/support/jfrDeprecationEventWriter.cpp +++ b/src/hotspot/share/jfr/support/jfrDeprecationEventWriter.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfrfiles/jfrEventIds.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" #include "jfr/recorder/jfrEventSetting.inline.hpp" diff --git a/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp b/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp index 79bcb37e5c0e1..ef1f25c84b308 100644 --- a/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp +++ b/src/hotspot/share/jfr/support/jfrDeprecationManager.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/moduleEntry.hpp" #include "interpreter/bytecodes.hpp" #include "jfrfiles/jfrEventIds.hpp" diff --git a/src/hotspot/share/jfr/support/jfrFlush.cpp b/src/hotspot/share/jfr/support/jfrFlush.cpp index 42e4f5f45818a..0179cde3d4acb 100644 --- a/src/hotspot/share/jfr/support/jfrFlush.cpp +++ b/src/hotspot/share/jfr/support/jfrFlush.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/jfrEventSetting.inline.hpp" #include "jfr/recorder/storage/jfrStorage.hpp" #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" diff --git a/src/hotspot/share/jfr/support/jfrIntrinsics.cpp b/src/hotspot/share/jfr/support/jfrIntrinsics.cpp index 63d0e686021f2..306e223ee2ebd 100644 --- a/src/hotspot/share/jfr/support/jfrIntrinsics.cpp +++ b/src/hotspot/share/jfr/support/jfrIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.inline.hpp" diff --git a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp index 77affc69926f0..31a81e7d7b544 100644 --- a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp +++ b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ class JfrIntrinsicSupport : AllStatic { #define JFR_TEMPLATES(template) \ template(jdk_jfr_internal_management_HiddenWait, "jdk/jfr/internal/management/HiddenWait") \ template(jdk_jfr_internal_JVM, "jdk/jfr/internal/JVM") \ - template(jdk_jfr_internal_event_EventWriterFactory, "jdk/jfr/internal/event/EventWriterFactory") \ + template(jdk_jfr_internal_event_EventWriter, "jdk/jfr/internal/event/EventWriter") \ template(jdk_jfr_internal_event_EventConfiguration_signature, "Ljdk/jfr/internal/event/EventConfiguration;") \ template(getEventWriter_signature, "()Ljdk/jfr/internal/event/EventWriter;") \ template(eventConfiguration_name, "eventConfiguration") \ diff --git a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp index b8dc7a6b3b5d9..ff1f4cdd39845 100644 --- a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp +++ b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/jfr/support/jfrKlassUnloading.cpp b/src/hotspot/share/jfr/support/jfrKlassUnloading.cpp index e0f26a800ba52..31eb83e16674a 100644 --- a/src/hotspot/share/jfr/support/jfrKlassUnloading.cpp +++ b/src/hotspot/share/jfr/support/jfrKlassUnloading.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/periodic/jfrFinalizerStatisticsEvent.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp" diff --git a/src/hotspot/share/jfr/support/jfrMethodData.cpp b/src/hotspot/share/jfr/support/jfrMethodData.cpp index af5d19c262ccb..633019106547b 100644 --- a/src/hotspot/share/jfr/support/jfrMethodData.cpp +++ b/src/hotspot/share/jfr/support/jfrMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/support/jfrMethodData.hpp" #include "memory/resourceArea.hpp" #include "oops/method.inline.hpp" diff --git a/src/hotspot/share/jfr/support/jfrMethodLookup.cpp b/src/hotspot/share/jfr/support/jfrMethodLookup.cpp index f83fc95d2700b..69cf6ebe0f645 100644 --- a/src/hotspot/share/jfr/support/jfrMethodLookup.cpp +++ b/src/hotspot/share/jfr/support/jfrMethodLookup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.inline.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp" diff --git a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp index 5e80e31a9987a..2958c1130747d 100644 --- a/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp +++ b/src/hotspot/share/jfr/support/jfrNativeLibraryLoadEvent.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/support/jfrNativeLibraryLoadEvent.hpp" #include "jfr/utilities/jfrTime.hpp" diff --git a/src/hotspot/share/jfr/support/jfrObjectAllocationSample.cpp b/src/hotspot/share/jfr/support/jfrObjectAllocationSample.cpp index 55ea5225e2450..6a99271a80e14 100644 --- a/src/hotspot/share/jfr/support/jfrObjectAllocationSample.cpp +++ b/src/hotspot/share/jfr/support/jfrObjectAllocationSample.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/threadLocalAllocBuffer.inline.hpp" #include "gc/shared/tlab_globals.hpp" #include "jfr/jfrEvents.hpp" diff --git a/src/hotspot/share/jfr/support/jfrResolution.cpp b/src/hotspot/share/jfr/support/jfrResolution.cpp index 486067c485a72..4027de2fb3d7e 100644 --- a/src/hotspot/share/jfr/support/jfrResolution.cpp +++ b/src/hotspot/share/jfr/support/jfrResolution.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciKlass.hpp" #include "ci/ciMethod.hpp" #include "classfile/vmSymbols.hpp" @@ -182,7 +181,7 @@ static inline const Method* ljf_sender_method(JavaThread* jt) { return ljf.method(); } -static const char* const link_error_msg = "illegal access linking method 'jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)'"; +static const char* const link_error_msg = "illegal access linking method 'jdk.jfr.internal.event.EventWriter.getEventWriter()'"; void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { assert(info.selected_method() != nullptr, "invariant"); @@ -199,12 +198,12 @@ void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { if (method->name() != event_writer_method_name) { return; } - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (info.resolved_klass()->name() != event_writer_factory_klass_name) { + static const Symbol* const event_writer_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriter(); + assert(event_writer_klass_name != nullptr, "invariant"); + if (info.resolved_klass()->name() != event_writer_klass_name) { return; } - // Attempting to link against jdk.jfr.internal.event.EventWriterFactory.getEventWriter(). + // Attempting to link against jdk.jfr.internal.event.EventWriter.getEventWriter(). // The sender, i.e. the method attempting to link, is in the ljf (if one exists). const Method* const sender = ljf_sender_method(THREAD); if (sender == nullptr) { @@ -228,9 +227,9 @@ void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { } static inline bool is_compiler_linking_event_writer(const Symbol* holder, const Symbol* name) { - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (holder != event_writer_factory_klass_name) { + static const Symbol* const event_writer_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriter(); + assert(event_writer_klass_name != nullptr, "invariant"); + if (holder != event_writer_klass_name) { return false; } static const Symbol* const event_writer_method_name = vmSymbols::getEventWriter_name(); diff --git a/src/hotspot/share/jfr/support/jfrStackTraceMark.cpp b/src/hotspot/share/jfr/support/jfrStackTraceMark.cpp index d1fa55e6dde6f..ef7cb88514789 100644 --- a/src/hotspot/share/jfr/support/jfrStackTraceMark.cpp +++ b/src/hotspot/share/jfr/support/jfrStackTraceMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/jfrEventSetting.inline.hpp" #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" #include "jfr/support/jfrStackTraceMark.hpp" diff --git a/src/hotspot/share/jfr/support/jfrSymbolTable.cpp b/src/hotspot/share/jfr/support/jfrSymbolTable.cpp index e3c34e46a1a4a..3fc639ffb5cf3 100644 --- a/src/hotspot/share/jfr/support/jfrSymbolTable.cpp +++ b/src/hotspot/share/jfr/support/jfrSymbolTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" #include "jfr/support/jfrSymbolTable.hpp" diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp index 9fc6be3d4c844..e1f72606c50a2 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" diff --git a/src/hotspot/share/jfr/utilities/jfrAllocation.cpp b/src/hotspot/share/jfr/utilities/jfrAllocation.cpp index c94765bbc8fe7..f97838c786957 100644 --- a/src/hotspot/share/jfr/utilities/jfrAllocation.cpp +++ b/src/hotspot/share/jfr/utilities/jfrAllocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/utilities/jfrAllocation.hpp" #include "logging/log.hpp" @@ -53,7 +52,7 @@ static void add(size_t alloc_size) { if (!JfrRecorder::is_created()) { const jlong total_allocated = atomic_add_jlong((jlong)alloc_size, &_allocated_bytes); const jlong current_live_set = atomic_add_jlong((jlong)alloc_size, &_live_set_bytes); - log_trace(jfr, system)("Allocation: [" SIZE_FORMAT "] bytes", alloc_size); + log_trace(jfr, system)("Allocation: [%zu] bytes", alloc_size); log_trace(jfr, system)("Total alloc [" JLONG_FORMAT "] bytes", total_allocated); log_trace(jfr, system)("Liveset: [" JLONG_FORMAT "] bytes", current_live_set); } @@ -63,7 +62,7 @@ static void subtract(size_t dealloc_size) { if (!JfrRecorder::is_created()) { const jlong total_deallocated = atomic_add_jlong((jlong)dealloc_size, &_deallocated_bytes); const jlong current_live_set = atomic_add_jlong(((jlong)dealloc_size * -1), &_live_set_bytes); - log_trace(jfr, system)("Deallocation: [" SIZE_FORMAT "] bytes", dealloc_size); + log_trace(jfr, system)("Deallocation: [%zu] bytes", dealloc_size); log_trace(jfr, system)("Total dealloc [" JLONG_FORMAT "] bytes", total_deallocated); log_trace(jfr, system)("Liveset: [" JLONG_FORMAT "] bytes", current_live_set); } @@ -77,7 +76,7 @@ static void hook_memory_deallocation(size_t dealloc_size) { static void hook_memory_allocation(const char* allocation, size_t alloc_size) { if (nullptr == allocation) { if (!JfrRecorder::is_created()) { - log_warning(jfr, system)("Memory allocation failed for size [" SIZE_FORMAT "] bytes", alloc_size); + log_warning(jfr, system)("Memory allocation failed for size [%zu] bytes", alloc_size); return; } else { // after critical startup, fail as by default diff --git a/src/hotspot/share/jfr/utilities/jfrBlob.cpp b/src/hotspot/share/jfr/utilities/jfrBlob.cpp index f326ff69d4795..108c473bf363b 100644 --- a/src/hotspot/share/jfr/utilities/jfrBlob.cpp +++ b/src/hotspot/share/jfr/utilities/jfrBlob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/utilities/jfrBlob.hpp" JfrBlob::JfrBlob(const u1* checkpoint, size_t size) : diff --git a/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp b/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp index 44b97488f5cb8..2f46853b042ee 100644 --- a/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp +++ b/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/utilities/jfrJavaLog.hpp" #include "jfr/utilities/jfrLogTagSets.hpp" diff --git a/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp b/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp index 30de22c5f58a9..2425f7c43ecde 100644 --- a/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp +++ b/src/hotspot/share/jfr/utilities/jfrThreadIterator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "jfr/utilities/jfrThreadIterator.hpp" #include "runtime/javaThread.inline.hpp" diff --git a/src/hotspot/share/jfr/utilities/jfrTime.cpp b/src/hotspot/share/jfr/utilities/jfrTime.cpp index 363550a78e4c6..75c3bc5cd28ba 100644 --- a/src/hotspot/share/jfr/utilities/jfrTime.cpp +++ b/src/hotspot/share/jfr/utilities/jfrTime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/utilities/jfrTime.hpp" #include "runtime/os.inline.hpp" #if defined(X86) && !defined(ZERO) diff --git a/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp b/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp index 4a6ab84400a6b..2ea0fd383d6e7 100644 --- a/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp +++ b/src/hotspot/share/jfr/utilities/jfrTimeConverter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "jfr/utilities/jfrTimeConverter.hpp" #include "jfr/utilities/jfrTime.hpp" #include "runtime/os.inline.hpp" diff --git a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp index d9610bcc97005..7f2d931623b5b 100644 --- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp +++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,6 @@ * */ -#include "precompiled.hpp" -#include "jni.h" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" @@ -32,6 +30,7 @@ #include "jfr/support/jfrThreadLocal.hpp" #include "jfr/utilities/jfrTypes.hpp" #include "jfr/writers/jfrJavaEventWriter.hpp" +#include "jni.h" #include "memory/iterator.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp index b93d6ad8cacc0..92a9a7a693e50 100644 --- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp +++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,8 @@ #ifndef SHARE_JFR_WRITERS_JFRJAVAEVENTWRITER_HPP #define SHARE_JFR_WRITERS_JFRJAVAEVENTWRITER_HPP -#include "jni.h" #include "jfr/utilities/jfrTypes.hpp" +#include "jni.h" #include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" diff --git a/src/hotspot/share/jfr/writers/jfrWriterHost.hpp b/src/hotspot/share/jfr/writers/jfrWriterHost.hpp index 2d28e84fd298e..2d07c8239ceaf 100644 --- a/src/hotspot/share/jfr/writers/jfrWriterHost.hpp +++ b/src/hotspot/share/jfr/writers/jfrWriterHost.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,9 @@ #ifndef SHARE_JFR_WRITERS_JFRWRITERHOST_HPP #define SHARE_JFR_WRITERS_JFRWRITERHOST_HPP +#include "jfr/utilities/jfrTime.hpp" #include "jni.h" #include "utilities/globalDefinitions.hpp" -#include "jfr/utilities/jfrTime.hpp" class ClassLoaderData; class Klass; diff --git a/src/hotspot/share/jvmci/jvmci.cpp b/src/hotspot/share/jvmci/jvmci.cpp index 9442c241e1637..609617b4a2073 100644 --- a/src/hotspot/share/jvmci/jvmci.cpp +++ b/src/hotspot/share/jvmci/jvmci.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "compiler/abstractCompiler.hpp" #include "compiler/compileTask.hpp" @@ -380,7 +379,7 @@ void JVMCI::fatal_log(const char* buf, size_t count) { _fatal_log_fd = log_fd; } else if (_first_error_tid != current_thread_id) { // This is not the first thread reporting a libjvmci error - tty->print_cr("[thread " INTX_FORMAT " also had an error in the JVMCI native library]", + tty->print_cr("[thread %zd also had an error in the JVMCI native library]", current_thread_id); // Fatal error reporting is single threaded so just block this thread. diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index dc3eecd57917e..1732719d64c07 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "code/compiledIC.hpp" #include "compiler/compileBroker.hpp" @@ -815,6 +814,12 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler); nm->maybe_print_nmethod(directive); DirectivesStack::release(directive); + + // Since this compilation didn't pass through the broker it wasn't logged yet. + if (PrintCompilation) { + ttyLocker ttyl; + CompileTask::print(tty, nm, "(hosted JVMCI compilation)"); + } } BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); diff --git a/src/hotspot/share/jvmci/jvmciCompiler.cpp b/src/hotspot/share/jvmci/jvmciCompiler.cpp index 04cdb4b4b4fda..f3f68a00b4f40 100644 --- a/src/hotspot/share/jvmci/jvmciCompiler.cpp +++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/vmClasses.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compilerDefinitions.inline.hpp" diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 9052e6228945b..f2807dbecd79c 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" @@ -1000,7 +999,7 @@ C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, ARGUMENT_PA if (info.is_null() || JVMCIENV->get_length(info) != 4) { JVMCI_ERROR_NULL("info must not be null and have a length of 4"); } - JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int()); + JVMCIENV->put_int_at(info, 0, fd.access_flags().as_field_flags()); JVMCIENV->put_int_at(info, 1, fd.offset()); JVMCIENV->put_int_at(info, 2, fd.index()); JVMCIENV->put_int_at(info, 3, fd.field_flags().as_uint()); @@ -2725,7 +2724,7 @@ C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jb if (res == JNI_OK) { guarantee(peerJNIEnv != nullptr, "must be"); runtime->init_JavaVM_info(javaVM_info, JVMCI_CHECK_0); - JVMCI_event_1("attached to JavaVM[%d] for JVMCI runtime %d", runtime->get_shared_library_javavm_id(), runtime->id()); + JVMCI_event_1("attached to JavaVM[" JLONG_FORMAT "] for JVMCI runtime %d", runtime->get_shared_library_javavm_id(), runtime->id()); return true; } JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name)); @@ -2758,7 +2757,7 @@ C2V_VMENTRY_PREFIX(jboolean, detachCurrentThread, (JNIEnv* env, jobject c2vm, jb if (res != JNI_OK) { JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, thread->name())); } - JVMCI_event_1("detached from JavaVM[%d] for JVMCI runtime %d", + JVMCI_event_1("detached from JavaVM[" JLONG_FORMAT "] for JVMCI runtime %d", runtime->get_shared_library_javavm_id(), runtime->id()); if (release) { return runtime->detach_thread(thread, "user thread detach"); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index faa23a8417866..a2f6f7f6d5213 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -// no precompiled headers #ifdef COMPILER1 #include "c1/c1_Compiler.hpp" #endif diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 712745e2a021c..78f5bca476957 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -1592,7 +1591,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index()); HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index()); HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset()); - HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_int()); + HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags()); HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint()); HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index()); return wrap(obj_h()); @@ -1603,7 +1602,7 @@ JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { (jint)fieldinfo->name_index(), (jint)fieldinfo->signature_index(), (jint)fieldinfo->offset(), - (jint)fieldinfo->access_flags().as_int(), + (jint)fieldinfo->access_flags().as_field_flags(), (jint)fieldinfo->field_flags().as_uint(), (jint)fieldinfo->initializer_index()); diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp index aa32e0e3eca02..b8d3d4e3b7ebf 100644 --- a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp +++ b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index ac972e97b1b6f..c88a4390590d0 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -1008,7 +1007,7 @@ static void _fatal() { } } intx current_thread_id = os::current_thread_id(); - fatal("thread " INTX_FORMAT ": Fatal error in JVMCI shared library", current_thread_id); + fatal("thread %zd: Fatal error in JVMCI shared library", current_thread_id); } JVMCIRuntime::JVMCIRuntime(JVMCIRuntime* next, int id, bool for_compile_broker) : @@ -1570,7 +1569,7 @@ bool JVMCIRuntime::destroy_shared_library_javavm() { guarantee(_num_attached_threads == cannot_be_attached, "cannot destroy JavaVM for JVMCI runtime %d with %d attached threads", _id, _num_attached_threads); JavaVM* javaVM; - int javaVM_id = _shared_library_javavm_id; + jlong javaVM_id = _shared_library_javavm_id; { // Exactly one thread can destroy the JavaVM // and release the handle to it. @@ -1589,9 +1588,9 @@ bool JVMCIRuntime::destroy_shared_library_javavm() { result = javaVM->DestroyJavaVM(); } if (result == JNI_OK) { - JVMCI_event_1("destroyed JavaVM[%d]@" PTR_FORMAT " for JVMCI runtime %d", javaVM_id, p2i(javaVM), _id); + JVMCI_event_1("destroyed JavaVM[" JLONG_FORMAT "]@" PTR_FORMAT " for JVMCI runtime %d", javaVM_id, p2i(javaVM), _id); } else { - warning("Non-zero result (%d) when calling JNI_DestroyJavaVM on JavaVM[%d]@" PTR_FORMAT, result, javaVM_id, p2i(javaVM)); + warning("Non-zero result (%d) when calling JNI_DestroyJavaVM on JavaVM[" JLONG_FORMAT "]@" PTR_FORMAT, result, javaVM_id, p2i(javaVM)); } return true; } diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index 99738393b5b0d..884d11f792e2a 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -183,7 +183,7 @@ class JVMCIRuntime: public CHeapObj { JavaVM* _shared_library_javavm; // Id for _shared_library_javavm. - int _shared_library_javavm_id; + jlong _shared_library_javavm_id; // Position and link in global list of JVMCI shared library runtimes. // The HotSpot heap based runtime will have an id of -1 and the @@ -280,7 +280,7 @@ class JVMCIRuntime: public CHeapObj { bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; } // Gets an ID for the JVMCI shared library JavaVM associated with this runtime. - int get_shared_library_javavm_id() { return _shared_library_javavm_id; } + jlong get_shared_library_javavm_id() { return _shared_library_javavm_id; } // Copies info about the JVMCI shared library JavaVM associated with this // runtime into `info` as follows: diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp index 2ae38044df0ff..dfc7e6b597046 100644 --- a/src/hotspot/share/jvmci/jvmci_globals.cpp +++ b/src/hotspot/share/jvmci/jvmci_globals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilerDefinitions.hpp" #include "gc/shared/gcConfig.hpp" #include "jvm.h" diff --git a/src/hotspot/share/jvmci/metadataHandles.cpp b/src/hotspot/share/jvmci/metadataHandles.cpp index 8bfea49fd0d86..3df7ebe573ae9 100644 --- a/src/hotspot/share/jvmci/metadataHandles.cpp +++ b/src/hotspot/share/jvmci/metadataHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "jvmci/metadataHandles.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index ba47e5599578f..8c964b5693169 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/codeCache.hpp" #include "code/compiledIC.hpp" #include "compiler/compileBroker.hpp" @@ -273,7 +272,6 @@ nonstatic_field(Klass, _name, Symbol*) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _secondary_supers_bitmap, uintx) \ @@ -488,7 +486,6 @@ declare_constant(InvocationEntryBci) \ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ \ - declare_constant(JVM_ACC_WRITTEN_FLAGS) \ declare_constant(FieldInfo::FieldFlags::_ff_injected) \ declare_constant(FieldInfo::FieldFlags::_ff_stable) \ declare_preprocessor_constant("JVM_ACC_VARARGS", JVM_ACC_VARARGS) \ diff --git a/src/hotspot/share/libadt/dict.cpp b/src/hotspot/share/libadt/dict.cpp index 0343125018e6c..e31df74807380 100644 --- a/src/hotspot/share/libadt/dict.cpp +++ b/src/hotspot/share/libadt/dict.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/dict.hpp" #include "utilities/powerOfTwo.hpp" diff --git a/src/hotspot/share/libadt/vectset.cpp b/src/hotspot/share/libadt/vectset.cpp index feb3ab10c65f2..a4224b0adb152 100644 --- a/src/hotspot/share/libadt/vectset.cpp +++ b/src/hotspot/share/libadt/vectset.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/vectset.hpp" #include "memory/arena.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/logging/logAsyncWriter.cpp b/src/hotspot/share/logging/logAsyncWriter.cpp index 3d987d04b8d42..737f001c04949 100644 --- a/src/hotspot/share/logging/logAsyncWriter.cpp +++ b/src/hotspot/share/logging/logAsyncWriter.cpp @@ -1,6 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logAsyncWriter.hpp" #include "logging/logConfiguration.hpp" #include "logging/logFileOutput.hpp" @@ -31,19 +30,35 @@ #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" +#include "runtime/globals.hpp" + class AsyncLogWriter::AsyncLogLocker : public StackObj { - public: + static Thread* _holder; +public: + static Thread* current_holder() { return _holder; } AsyncLogLocker() { assert(_instance != nullptr, "AsyncLogWriter::_lock is unavailable"); _instance->_lock.lock(); + _holder = Thread::current_or_null(); } ~AsyncLogLocker() { + assert(_holder == Thread::current_or_null(), "must be"); + _holder = nullptr; _instance->_lock.unlock(); } + + void wait() { + Thread* saved_holder = _holder; + _holder = nullptr; + _instance->_lock.wait(0/* no timeout */); + _holder = saved_holder; + } }; +Thread* AsyncLogWriter::AsyncLogLocker::_holder = nullptr; + // LogDecorator::None applies to 'constant initialization' because of its constexpr constructor. const LogDecorations& AsyncLogWriter::None = LogDecorations(LogLevel::Warning, LogTagSetMapping::tagset(), LogDecorators::None); @@ -85,19 +100,73 @@ void AsyncLogWriter::enqueue_locked(LogFileStreamOutput* output, const LogDecora _lock.notify(); } -void AsyncLogWriter::enqueue(LogFileStreamOutput& output, const LogDecorations& decorations, const char* msg) { +// This function checks for cases where continuing with asynchronous logging may lead to stability issues, such as a deadlock. +// If this returns false then we give up on logging asynchronously and do so synchronously instead. +bool AsyncLogWriter::is_enqueue_allowed() { + AsyncLogWriter* alw = AsyncLogWriter::instance(); + Thread* holding_thread = AsyncLogWriter::AsyncLogLocker::current_holder(); + Thread* this_thread = Thread::current_or_null(); + if (this_thread == nullptr) { + // The current thread is unattached. + return false; + } + + if (holding_thread == this_thread) { + // A thread, while enqueuing a message, has attempted to log something. + // Do not log while holding the Async log lock. + // Try to catch possible occurrences in debug builds. +#ifdef ASSERT + if (!TestingAsyncLoggingDeathTestNoCrash) { + ShouldNotReachHere(); + } +#endif // ASSERT + + return false; + } + + if (alw == nullptr) { + // There is no AsyncLogWriter instance yet. + return false; + } + + if (this_thread == alw) { + // The async log producer is attempting to log, leading to recursive logging. + return false; + } + + return true; +} + +bool AsyncLogWriter::enqueue(LogFileStreamOutput& output, const LogDecorations& decorations, const char* msg) { + if (!is_enqueue_allowed()) { + return false; + } + AsyncLogLocker locker; - enqueue_locked(&output, decorations, msg); + +#ifdef ASSERT + if (TestingAsyncLoggingDeathTest || TestingAsyncLoggingDeathTestNoCrash) { + log_debug(deathtest)("Induce a recursive log for testing"); + } +#endif // ASSERT + + AsyncLogWriter::instance()->enqueue_locked(&output, decorations, msg); + return true; } // LogMessageBuffer consists of a multiple-part/multiple-line message. // The lock here guarantees its integrity. -void AsyncLogWriter::enqueue(LogFileStreamOutput& output, LogMessageBuffer::Iterator msg_iterator) { - AsyncLogLocker locker; +bool AsyncLogWriter::enqueue(LogFileStreamOutput& output, LogMessageBuffer::Iterator msg_iterator) { + if (!is_enqueue_allowed()) { + return false; + } + // If we get here we know the AsyncLogWriter is initialized. + AsyncLogLocker locker; for (; !msg_iterator.is_at_end(); msg_iterator++) { - enqueue_locked(&output, msg_iterator.decorations(), msg_iterator.message()); + AsyncLogWriter::instance()->enqueue_locked(&output, msg_iterator.decorations(), msg_iterator.message()); } + return true; } AsyncLogWriter::AsyncLogWriter() @@ -108,7 +177,7 @@ AsyncLogWriter::AsyncLogWriter() size_t size = AsyncLogBufferSize / 2; _buffer = new Buffer(size); _buffer_staging = new Buffer(size); - log_info(logging)("AsyncLogBuffer estimates memory use: " SIZE_FORMAT " bytes", size * 2); + log_info(logging)("AsyncLogBuffer estimates memory use: %zu bytes", size * 2); if (os::create_thread(this, os::asynclog_thread)) { _initialized = true; } else { @@ -156,7 +225,7 @@ void AsyncLogWriter::run() { AsyncLogLocker locker; while (!_data_available) { - _lock.wait(0/* no timeout */); + locker.wait(); } // Only doing a swap and statistics under the lock to // guarantee that I/O jobs don't block logsites. diff --git a/src/hotspot/share/logging/logAsyncWriter.hpp b/src/hotspot/share/logging/logAsyncWriter.hpp index 97bae2a581745..00818634bdd16 100644 --- a/src/hotspot/share/logging/logAsyncWriter.hpp +++ b/src/hotspot/share/logging/logAsyncWriter.hpp @@ -1,6 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,7 +176,7 @@ class AsyncLogWriter : public NonJavaThread { void run() override; void pre_run() override { NonJavaThread::pre_run(); - log_debug(logging, thread)("starting AsyncLog Thread tid = " INTX_FORMAT, os::current_thread_id()); + log_debug(logging, thread)("starting AsyncLog Thread tid = %zd", os::current_thread_id()); } const char* type_name() const override { return "AsyncLogWriter"; } void print_on(outputStream* st) const override { @@ -195,9 +195,11 @@ class AsyncLogWriter : public NonJavaThread { ~BufferUpdater(); }; - public: - void enqueue(LogFileStreamOutput& output, const LogDecorations& decorations, const char* msg); - void enqueue(LogFileStreamOutput& output, LogMessageBuffer::Iterator msg_iterator); + static bool is_enqueue_allowed(); + +public: + static bool enqueue(LogFileStreamOutput& output, const LogDecorations& decorations, const char* msg); + static bool enqueue(LogFileStreamOutput& output, LogMessageBuffer::Iterator msg_iterator); static AsyncLogWriter* instance(); static void initialize(); diff --git a/src/hotspot/share/logging/logConfiguration.cpp b/src/hotspot/share/logging/logConfiguration.cpp index dfddfff2f05c0..5f8a045c356fa 100644 --- a/src/hotspot/share/logging/logConfiguration.cpp +++ b/src/hotspot/share/logging/logConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/log.hpp" #include "logging/logAsyncWriter.hpp" @@ -214,8 +213,8 @@ size_t LogConfiguration::add_output(LogOutput* output) { void LogConfiguration::delete_output(size_t idx) { assert(idx > 1 && idx < _n_outputs, - "idx must be in range 1 < idx < _n_outputs, but idx = " SIZE_FORMAT - " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs); + "idx must be in range 1 < idx < _n_outputs, but idx = %zu" + " and _n_outputs = %zu", idx, _n_outputs); LogOutput* output = _outputs[idx]; // Swap places with the last output and shrink the array _outputs[idx] = _outputs[--_n_outputs]; @@ -240,7 +239,7 @@ void LogConfiguration::delete_output(size_t idx) { // void LogConfiguration::configure_output(size_t idx, const LogSelectionList& selections, const LogDecorators& decorators) { assert(ConfigurationLock::current_thread_has_lock(), "Must hold configuration lock to call this function."); - assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs); + assert(idx < _n_outputs, "Invalid index, idx = %zu and _n_outputs = %zu", idx, _n_outputs); LogOutput* output = _outputs[idx]; output->_reconfigured = true; @@ -351,7 +350,7 @@ void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ... } } assert(i < LogTag::MaxTags || static_cast(va_arg(ap, int)) == LogTag::__NO_TAG, - "Too many tags specified! Can only have up to " SIZE_FORMAT " tags in a tag set.", LogTag::MaxTags); + "Too many tags specified! Can only have up to %zu tags in a tag set.", LogTag::MaxTags); va_end(ap); LogSelection selection(tags, !exact_match, level); @@ -500,7 +499,7 @@ bool LogConfiguration::parse_log_arguments(const char* outputstr, size_t idx; bool added = false; if (outputstr[0] == '#') { // Output specified using index - int ret = sscanf(outputstr + 1, SIZE_FORMAT, &idx); + int ret = sscanf(outputstr + 1, "%zu", &idx); if (ret != 1 || idx >= _n_outputs) { errstream->print_cr("Invalid output index '%s'", outputstr); return false; @@ -566,7 +565,7 @@ void LogConfiguration::describe_available(outputStream* out) { void LogConfiguration::describe_current_configuration(outputStream* out) { out->print_cr("Log output configuration:"); for (size_t i = 0; i < _n_outputs; i++) { - out->print(" #" SIZE_FORMAT ": ", i); + out->print(" #%zu: ", i); _outputs[i]->describe(out); if (_outputs[i]->is_reconfigured()) { out->print(" (reconfigured)"); diff --git a/src/hotspot/share/logging/logDecorations.cpp b/src/hotspot/share/logging/logDecorations.cpp index 058bd7ab2aad0..e08c6c9cb137d 100644 --- a/src/hotspot/share/logging/logDecorations.cpp +++ b/src/hotspot/share/logging/logDecorations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/logConfiguration.hpp" #include "logging/logDecorations.hpp" @@ -127,7 +126,7 @@ void LogDecorations::print_pid_decoration(outputStream* st) const { } void LogDecorations::print_tid_decoration(outputStream* st) const { - st->print(INTX_FORMAT, _tid); + st->print("%zd", _tid); } void LogDecorations::print_level_decoration(outputStream* st) const { diff --git a/src/hotspot/share/logging/logDecorators.cpp b/src/hotspot/share/logging/logDecorators.cpp index 6c06bd4571627..0b1470f1a2ed3 100644 --- a/src/hotspot/share/logging/logDecorators.cpp +++ b/src/hotspot/share/logging/logDecorators.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logDecorators.hpp" #include "runtime/os.hpp" @@ -100,7 +99,9 @@ bool LogDecorators::parse(const char* decorator_args, outputStream* errstream) { break; } tmp_decorators |= mask(d); - token = comma_pos + 1; + if (comma_pos != nullptr) { + token = comma_pos + 1; + } } while (comma_pos != nullptr); os::free(args_copy); if (result) { diff --git a/src/hotspot/share/logging/logDiagnosticCommand.cpp b/src/hotspot/share/logging/logDiagnosticCommand.cpp index dfd45d611884a..adf596afc9405 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.cpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logConfiguration.hpp" #include "logging/logDiagnosticCommand.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/logging/logFileOutput.cpp b/src/hotspot/share/logging/logFileOutput.cpp index 783be86586147..9d6d19d739eb3 100644 --- a/src/hotspot/share/logging/logFileOutput.cpp +++ b/src/hotspot/share/logging/logFileOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/log.hpp" #include "logging/logAsyncWriter.hpp" @@ -185,7 +184,7 @@ bool LogFileOutput::set_option(const char* key, const char* value, outputStream* success = Arguments::atojulong(value, &longval); if (!success || (longval > SIZE_MAX)) { errstream->print_cr("Invalid option: %s must be in range [0, " - SIZE_FORMAT "]", FileSizeOptionKey, (size_t)SIZE_MAX); + "%zu]", FileSizeOptionKey, (size_t)SIZE_MAX); success = false; } else { _rotate_size = static_cast(longval); @@ -215,7 +214,7 @@ bool LogFileOutput::initialize(const char* options, outputStream* errstream) { } log_trace(logging)("Initializing logging to file '%s' (filecount: %u" - ", filesize: " SIZE_FORMAT " KiB).", + ", filesize: %zu KiB).", _file_name, _file_count, _rotate_size / K); if (_file_count > 0 && file_exist) { @@ -293,9 +292,7 @@ int LogFileOutput::write(const LogDecorations& decorations, const char* msg) { return 0; } - AsyncLogWriter* aio_writer = AsyncLogWriter::instance(); - if (aio_writer != nullptr) { - aio_writer->enqueue(*this, decorations, msg); + if (AsyncLogWriter::enqueue(*this, decorations, msg)) { return 0; } @@ -307,10 +304,7 @@ int LogFileOutput::write(LogMessageBuffer::Iterator msg_iterator) { // An error has occurred with this output, avoid writing to it. return 0; } - - AsyncLogWriter* aio_writer = AsyncLogWriter::instance(); - if (aio_writer != nullptr) { - aio_writer->enqueue(*this, msg_iterator); + if (AsyncLogWriter::enqueue(*this, msg_iterator)) { return 0; } @@ -461,7 +455,7 @@ char* LogFileOutput::make_file_name(const char* file_name, void LogFileOutput::describe(outputStream *out) { LogFileStreamOutput::describe(out); - out->print(",filecount=%u,filesize=" SIZE_FORMAT "%s,async=%s", _file_count, + out->print(",filecount=%u,filesize=%zu%s,async=%s", _file_count, byte_size_in_proper_unit(_rotate_size), proper_unit_for_byte_size(_rotate_size), LogConfiguration::is_async_mode() ? "true" : "false"); diff --git a/src/hotspot/share/logging/logFileStreamOutput.cpp b/src/hotspot/share/logging/logFileStreamOutput.cpp index dc34a9b8b1449..2464bc806c201 100644 --- a/src/hotspot/share/logging/logFileStreamOutput.cpp +++ b/src/hotspot/share/logging/logFileStreamOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/logAsyncWriter.hpp" #include "logging/logDecorations.hpp" @@ -174,9 +173,7 @@ int LogFileStreamOutput::write_blocking(const LogDecorations& decorations, const } int LogFileStreamOutput::write(const LogDecorations& decorations, const char* msg) { - AsyncLogWriter* aio_writer = AsyncLogWriter::instance(); - if (aio_writer != nullptr) { - aio_writer->enqueue(*this, decorations, msg); + if (AsyncLogWriter::enqueue(*this, decorations, msg)) { return 0; } @@ -187,9 +184,7 @@ int LogFileStreamOutput::write(const LogDecorations& decorations, const char* ms } int LogFileStreamOutput::write(LogMessageBuffer::Iterator msg_iterator) { - AsyncLogWriter* aio_writer = AsyncLogWriter::instance(); - if (aio_writer != nullptr) { - aio_writer->enqueue(*this, msg_iterator); + if (AsyncLogWriter::enqueue(*this, msg_iterator)) { return 0; } diff --git a/src/hotspot/share/logging/logLevel.cpp b/src/hotspot/share/logging/logLevel.cpp index 2b9ef795163c6..9efe07b05e9e6 100644 --- a/src/hotspot/share/logging/logLevel.cpp +++ b/src/hotspot/share/logging/logLevel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logLevel.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/stringUtils.hpp" diff --git a/src/hotspot/share/logging/logMessageBuffer.cpp b/src/hotspot/share/logging/logMessageBuffer.cpp index 268cc191418cb..8f308b1f01506 100644 --- a/src/hotspot/share/logging/logMessageBuffer.cpp +++ b/src/hotspot/share/logging/logMessageBuffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logMessageBuffer.hpp" #include "memory/allocation.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/logging/logOutput.cpp b/src/hotspot/share/logging/logOutput.cpp index 17d0e8b555d60..e3c68b49b1305 100644 --- a/src/hotspot/share/logging/logOutput.cpp +++ b/src/hotspot/share/logging/logOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/log.hpp" #include "logging/logFileStreamOutput.hpp" @@ -354,7 +353,9 @@ bool LogOutput::parse_options(const char* options, outputStream* errstream) { } break; } - pos = comma_pos + 1; + if (comma_pos != nullptr) { + pos = comma_pos + 1; + } } while (comma_pos != nullptr); os::free(opts); diff --git a/src/hotspot/share/logging/logOutputList.cpp b/src/hotspot/share/logging/logOutputList.cpp index 6367577b1b001..fab06860a4807 100644 --- a/src/hotspot/share/logging/logOutputList.cpp +++ b/src/hotspot/share/logging/logOutputList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logLevel.hpp" #include "logging/logOutputList.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/logging/logSelection.cpp b/src/hotspot/share/logging/logSelection.cpp index 99ecc9f87f272..476fdebc9c540 100644 --- a/src/hotspot/share/logging/logSelection.cpp +++ b/src/hotspot/share/logging/logSelection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm_io.h" #include "logging/log.hpp" #include "logging/logSelection.hpp" @@ -145,13 +144,15 @@ static LogSelection parse_internal(char *str, outputStream* errstream) { } if (ntags == LogTag::MaxTags) { if (errstream != nullptr) { - errstream->print_cr("Too many tags in log selection '%s' (can only have up to " SIZE_FORMAT " tags).", + errstream->print_cr("Too many tags in log selection '%s' (can only have up to %zu tags).", str, LogTag::MaxTags); } return LogSelection::Invalid; } tags[ntags++] = tag; - cur_tag = plus_pos + 1; + if (plus_pos != nullptr) { + cur_tag = plus_pos + 1; + } } while (plus_pos != nullptr); for (size_t i = 0; i < ntags; i++) { diff --git a/src/hotspot/share/logging/logSelectionList.cpp b/src/hotspot/share/logging/logSelectionList.cpp index ac63f20512c2a..f8c2d9e7cfb69 100644 --- a/src/hotspot/share/logging/logSelectionList.cpp +++ b/src/hotspot/share/logging/logSelectionList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/logSelectionList.hpp" #include "logging/logTagSet.hpp" #include "runtime/os.hpp" @@ -69,10 +68,10 @@ bool LogSelectionList::parse(const char* str, outputStream* errstream) { } char* copy = os::strdup_check_oom(str, mtLogging); // Split string on commas - for (char *comma_pos = copy, *cur = copy; success && comma_pos != nullptr; cur = comma_pos + 1) { + for (char *comma_pos = copy, *cur = copy; success; cur = comma_pos + 1) { if (_nselections == MaxSelections) { if (errstream != nullptr) { - errstream->print_cr("Can not have more than " SIZE_FORMAT " log selections in a single configuration.", + errstream->print_cr("Can not have more than %zu log selections in a single configuration.", MaxSelections); } success = false; @@ -90,6 +89,10 @@ bool LogSelectionList::parse(const char* str, outputStream* errstream) { break; } _selections[_nselections++] = selection; + + if (comma_pos == nullptr) { + break; + } } os::free(copy); diff --git a/src/hotspot/share/logging/logStream.cpp b/src/hotspot/share/logging/logStream.cpp index efbd806733d01..813b0aceb4a52 100644 --- a/src/hotspot/share/logging/logStream.cpp +++ b/src/hotspot/share/logging/logStream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/logStream.hpp" #include "runtime/os.hpp" #include "utilities/align.hpp" diff --git a/src/hotspot/share/logging/logTag.cpp b/src/hotspot/share/logging/logTag.cpp index a4cd535cf7afe..d2aeeebfc7996 100644 --- a/src/hotspot/share/logging/logTag.cpp +++ b/src/hotspot/share/logging/logTag.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logTag.hpp" #include "utilities/stringUtils.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index 15ac30d09ab8f..d61e2461e8da6 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -68,6 +68,7 @@ class outputStream; LOG_TAG(data) \ LOG_TAG(datacreation) \ LOG_TAG(dcmd) \ + DEBUG_ONLY(LOG_TAG(deathtest)) /* Log Internal death test tag */ \ LOG_TAG(decoder) \ LOG_TAG(defaultmethods) \ LOG_TAG(deoptimization) \ diff --git a/src/hotspot/share/logging/logTagSet.cpp b/src/hotspot/share/logging/logTagSet.cpp index 04da1a1e28d16..f7b0e01331c91 100644 --- a/src/hotspot/share/logging/logTagSet.cpp +++ b/src/hotspot/share/logging/logTagSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,8 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" +#include "logging/logAsyncWriter.hpp" #include "logging/logDecorations.hpp" #include "logging/logFileStreamOutput.hpp" #include "logging/logLevel.hpp" diff --git a/src/hotspot/share/logging/logTagSetDescriptions.cpp b/src/hotspot/share/logging/logTagSetDescriptions.cpp index cc0501771619f..f8edfb9a4c55a 100644 --- a/src/hotspot/share/logging/logTagSetDescriptions.cpp +++ b/src/hotspot/share/logging/logTagSetDescriptions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/logTag.hpp" #include "logging/logTagSet.hpp" #include "logging/logTagSetDescriptions.hpp" diff --git a/src/hotspot/share/memory/allocation.cpp b/src/hotspot/share/memory/allocation.cpp index 096ee6964210e..13280006fe692 100644 --- a/src/hotspot/share/memory/allocation.cpp +++ b/src/hotspot/share/memory/allocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/arena.hpp" diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index ae834ec9a729f..b67dcd43e4d40 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -314,7 +314,6 @@ class MetaspaceObj { f(ConstantPoolCache) \ f(Annotations) \ f(MethodCounters) \ - f(SharedClassPathEntry) \ f(RecordComponent) #define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type, diff --git a/src/hotspot/share/memory/arena.cpp b/src/hotspot/share/memory/arena.cpp index 51d7cda9c61ec..055c6405590b5 100644 --- a/src/hotspot/share/memory/arena.cpp +++ b/src/hotspot/share/memory/arena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compilationMemoryStatistic.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" @@ -142,8 +141,7 @@ Chunk* ChunkPool::allocate_chunk(size_t length, AllocFailType alloc_failmode) { // - the payload size (length) must be aligned to 64-bit, which takes care of 64-bit // aligning (D) - assert(is_aligned(length, ARENA_AMALLOC_ALIGNMENT), "chunk payload length misaligned: " - SIZE_FORMAT ".", length); + assert(is_aligned(length, ARENA_AMALLOC_ALIGNMENT), "chunk payload length misaligned: %zu.", length); // Try to reuse a freed chunk from the pool ChunkPool* pool = ChunkPool::get_pool_for_size(length); Chunk* chunk = nullptr; diff --git a/src/hotspot/share/memory/classLoaderMetaspace.cpp b/src/hotspot/share/memory/classLoaderMetaspace.cpp index 4bcbb862a5a4e..efa6adc7a7bf5 100644 --- a/src/hotspot/share/memory/classLoaderMetaspace.cpp +++ b/src/hotspot/share/memory/classLoaderMetaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/classLoaderMetaspace.hpp" #include "memory/metaspace.hpp" @@ -148,8 +147,8 @@ MetaWord* ClassLoaderMetaspace::expand_and_allocate(size_t word_size, Metaspace: Metaspace::tracer()->report_gc_threshold(before, after, MetaspaceGCThresholdUpdater::ExpandAndAllocate); // Keeping both for now until I am sure the old variant (gc + metaspace) is not needed anymore - log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after); - UL2(info, "GC threshold increased: " SIZE_FORMAT "->" SIZE_FORMAT ".", before, after); + log_trace(gc, metaspace)("Increase capacity to GC from %zu to %zu", before, after); + UL2(info, "GC threshold increased: %zu->%zu.", before, after); } return res; diff --git a/src/hotspot/share/memory/guardedMemory.cpp b/src/hotspot/share/memory/guardedMemory.cpp index 12ffde3cc1b94..4165ccdb62080 100644 --- a/src/hotspot/share/memory/guardedMemory.cpp +++ b/src/hotspot/share/memory/guardedMemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "memory/guardedMemory.hpp" #include "nmt/memTag.hpp" #include "runtime/os.hpp" @@ -59,7 +58,7 @@ void GuardedMemory::print_on(outputStream* st) const { return; } st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT - " tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT, + " tag=" PTR_FORMAT " user_size=%zu user_data=" PTR_FORMAT, p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr())); Guard* guard = get_head_guard(); diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index f88f5c4dc1266..bcb9d2e6114b9 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,8 @@ * */ -#include "precompiled.hpp" #include "memory/heap.hpp" -#include "nmt/memTracker.hpp" +#include "memory/memoryReserver.hpp" #include "oops/oop.inline.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" @@ -223,7 +222,7 @@ bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_s const size_t committed_segments_size = align_to_page_size(_number_of_committed_segments); // reserve space for _segmap - ReservedSpace seg_rs(reserved_segments_size, mtCode); + ReservedSpace seg_rs = MemoryReserver::reserve(reserved_segments_size, mtCode); if (!_segmap.initialize(seg_rs, committed_segments_size)) { return false; } diff --git a/src/hotspot/share/memory/heap.hpp b/src/hotspot/share/memory/heap.hpp index a7b9b95050da2..e54f99c8c5477 100644 --- a/src/hotspot/share/memory/heap.hpp +++ b/src/hotspot/share/memory/heap.hpp @@ -31,6 +31,8 @@ #include "runtime/atomic.hpp" #include "utilities/macros.hpp" +class ReservedSpace; + // Blocks class HeapBlock { diff --git a/src/hotspot/share/memory/heapInspection.cpp b/src/hotspot/share/memory/heapInspection.cpp index bf9deb530f03a..867ccc6106d8e 100644 --- a/src/hotspot/share/memory/heapInspection.cpp +++ b/src/hotspot/share/memory/heapInspection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/moduleEntry.hpp" @@ -592,7 +591,7 @@ void HeapInspection::heap_inspection(outputStream* st, WorkerThreads* workers) { // populate table with object allocation info uintx missed_count = populate_table(&cit, nullptr, workers); if (missed_count != 0) { - log_info(gc, classhisto)("WARNING: Ran out of C-heap; undercounted " UINTX_FORMAT + log_info(gc, classhisto)("WARNING: Ran out of C-heap; undercounted %zu" " total instances in data below", missed_count); } diff --git a/src/hotspot/share/memory/iterator.cpp b/src/hotspot/share/memory/iterator.cpp index d2d478cb51851..9569822e03f6f 100644 --- a/src/hotspot/share/memory/iterator.cpp +++ b/src/hotspot/share/memory/iterator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/share/memory/memRegion.cpp b/src/hotspot/share/memory/memRegion.cpp index d6565b0032442..4391e25aec33b 100644 --- a/src/hotspot/share/memory/memRegion.cpp +++ b/src/hotspot/share/memory/memRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/memRegion.hpp" diff --git a/src/hotspot/share/memory/memoryReserver.cpp b/src/hotspot/share/memory/memoryReserver.cpp new file mode 100644 index 0000000000000..dad88ae97e53b --- /dev/null +++ b/src/hotspot/share/memory/memoryReserver.cpp @@ -0,0 +1,689 @@ +/* + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "jvm.h" +#include "logging/log.hpp" +#include "memory/memoryReserver.hpp" +#include "oops/compressedOops.hpp" +#include "oops/markWord.hpp" +#include "runtime/globals_extension.hpp" +#include "runtime/java.hpp" +#include "runtime/os.inline.hpp" +#include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/powerOfTwo.hpp" + +static void sanity_check_size_and_alignment(size_t size, size_t alignment) { + assert(size > 0, "Precondition"); + + DEBUG_ONLY(const size_t granularity = os::vm_allocation_granularity()); + assert(is_aligned(size, granularity), "size not aligned to os::vm_allocation_granularity()"); + + assert(alignment >= granularity, "Must be set"); + assert(is_power_of_2(alignment), "not a power of 2"); + assert(is_aligned(alignment, granularity), "alignment not aligned to os::vm_allocation_granularity()"); +} + +static void sanity_check_page_size(size_t page_size) { + assert(page_size >= os::vm_page_size(), "Invalid page size"); + assert(is_power_of_2(page_size), "Invalid page size"); +} + +static void sanity_check_arguments(size_t size, size_t alignment, size_t page_size) { + sanity_check_size_and_alignment(size, alignment); + sanity_check_page_size(page_size); +} + +static bool large_pages_requested() { + return UseLargePages && + (!FLAG_IS_DEFAULT(UseLargePages) || !FLAG_IS_DEFAULT(LargePageSizeInBytes)); +} + +static void log_on_large_pages_failure(char* req_addr, size_t bytes) { + if (large_pages_requested()) { + // Compressed oops logging. + log_debug(gc, heap, coops)("Reserve regular memory without large pages"); + // JVM style warning that we did not succeed in using large pages. + char msg[128]; + jio_snprintf(msg, sizeof(msg), "Failed to reserve and commit memory using large pages. " + "req_addr: " PTR_FORMAT " bytes: %zu", + req_addr, bytes); + warning("%s", msg); + } +} + +static bool use_explicit_large_pages(size_t page_size) { + return !os::can_commit_large_page_memory() && + page_size != os::vm_page_size(); +} + +static char* reserve_memory_inner(char* requested_address, + size_t size, + size_t alignment, + bool exec, + MemTag mem_tag) { + // If the memory was requested at a particular address, use + // os::attempt_reserve_memory_at() to avoid mapping over something + // important. If the reservation fails, return null. + if (requested_address != nullptr) { + assert(is_aligned(requested_address, alignment), + "Requested address " PTR_FORMAT " must be aligned to %zu", + p2i(requested_address), alignment); + return os::attempt_reserve_memory_at(requested_address, size, exec, mem_tag); + } + + // Optimistically assume that the OS returns an aligned base pointer. + // When reserving a large address range, most OSes seem to align to at + // least 64K. + char* base = os::reserve_memory(size, exec, mem_tag); + if (is_aligned(base, alignment)) { + return base; + } + + // Base not aligned, retry. + if (!os::release_memory(base, size)) { + fatal("os::release_memory failed"); + } + + // Map using the requested alignment. + return os::reserve_memory_aligned(size, alignment, exec); +} + +ReservedSpace MemoryReserver::reserve_memory(char* requested_address, + size_t size, + size_t alignment, + bool exec, + MemTag mem_tag) { + char* base = reserve_memory_inner(requested_address, size, alignment, exec, mem_tag); + + if (base != nullptr) { + return ReservedSpace(base, size, alignment, os::vm_page_size(), exec, false /* special */); + } + + // Failed + return {}; +} + +ReservedSpace MemoryReserver::reserve_memory_special(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + bool exec) { + log_trace(pagesize)("Attempt special mapping: size: %zu%s, alignment: %zu%s", + byte_size_in_exact_unit(size), exact_unit_for_byte_size(size), + byte_size_in_exact_unit(alignment), exact_unit_for_byte_size(alignment)); + + char* base = os::reserve_memory_special(size, alignment, page_size, requested_address, exec); + + if (base != nullptr) { + assert(is_aligned(base, alignment), + "reserve_memory_special() returned an unaligned address, " + "base: " PTR_FORMAT " alignment: 0x%zx", + p2i(base), alignment); + + return ReservedSpace(base, size, alignment, page_size, exec, true /* special */); + } + + // Failed + return {}; +} + +ReservedSpace MemoryReserver::reserve(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + bool executable, + MemTag mem_tag) { + sanity_check_arguments(size, alignment, page_size); + + // Reserve the memory. + + // There are basically three different cases that we need to handle: + // 1. Mapping backed by a file + // 2. Mapping backed by explicit large pages + // 3. Mapping backed by normal pages or transparent huge pages + // The first two have restrictions that requires the whole mapping to be + // committed up front. To record this the ReservedSpace is marked 'special'. + + // == Case 1 == + // This case is contained within the HeapReserver + + // == Case 2 == + if (use_explicit_large_pages(page_size)) { + // System can't commit large pages i.e. use transparent huge pages and + // the caller requested large pages. To satisfy this request we use + // explicit large pages and these have to be committed up front to ensure + // no reservations are lost. + do { + ReservedSpace reserved = reserve_memory_special(requested_address, size, alignment, page_size, executable); + if (reserved.is_reserved()) { + // Successful reservation using large pages. + return reserved; + } + page_size = os::page_sizes().next_smaller(page_size); + } while (page_size > os::vm_page_size()); + + // Failed to reserve explicit large pages, do proper logging. + log_on_large_pages_failure(requested_address, size); + // Now fall back to normal reservation. + assert(page_size == os::vm_page_size(), "inv"); + } + + // == Case 3 == + return reserve_memory(requested_address, size, alignment, executable, mem_tag); +} + +ReservedSpace MemoryReserver::reserve(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + MemTag mem_tag) { + return reserve(requested_address, + size, + alignment, + page_size, + !ExecMem, + mem_tag); +} + + +ReservedSpace MemoryReserver::reserve(size_t size, + size_t alignment, + size_t page_size, + MemTag mem_tag) { + return reserve(nullptr /* requested_address */, + size, + alignment, + page_size, + mem_tag); +} + +ReservedSpace MemoryReserver::reserve(size_t size, + MemTag mem_tag) { + // Want to use large pages where possible. If the size is + // not large page aligned the mapping will be a mix of + // large and normal pages. + size_t page_size = os::page_size_for_region_unaligned(size, 1); + size_t alignment = os::vm_allocation_granularity(); + + return reserve(size, + alignment, + page_size, + mem_tag); +} + +bool MemoryReserver::release(const ReservedSpace& reserved) { + assert(reserved.is_reserved(), "Precondition"); + + if (reserved.special()) { + return os::release_memory_special(reserved.base(), reserved.size()); + } else { + return os::release_memory(reserved.base(), reserved.size()); + } +} + +static char* map_memory_to_file(char* requested_address, + size_t size, + size_t alignment, + int fd, + MemTag mem_tag) { + // If the memory was requested at a particular address, use + // os::attempt_reserve_memory_at() to avoid mapping over something + // important. If the reservation fails, return null. + if (requested_address != nullptr) { + assert(is_aligned(requested_address, alignment), + "Requested address " PTR_FORMAT " must be aligned to %zu", + p2i(requested_address), alignment); + return os::attempt_map_memory_to_file_at(requested_address, size, fd, mem_tag); + } + + // Optimistically assume that the OS returns an aligned base pointer. + // When reserving a large address range, most OSes seem to align to at + // least 64K. + char* base = os::map_memory_to_file(size, fd); + if (is_aligned(base, alignment)) { + return base; + } + + + // Base not aligned, retry. + if (!os::unmap_memory(base, size)) { + fatal("os::unmap_memory failed"); + } + + // Map using the requested alignment. + return os::map_memory_to_file_aligned(size, alignment, fd, mem_tag); +} + +ReservedSpace FileMappedMemoryReserver::reserve(char* requested_address, + size_t size, + size_t alignment, + int fd, + MemTag mem_tag) { + sanity_check_size_and_alignment(size, alignment); + + char* base = map_memory_to_file(requested_address, size, alignment, fd, mem_tag); + + if (base != nullptr) { + return ReservedSpace(base, size, alignment, os::vm_page_size(), !ExecMem, true /* special */); + } + + // Failed + return {}; +} + +ReservedSpace CodeMemoryReserver::reserve(size_t size, + size_t alignment, + size_t page_size) { + return MemoryReserver::reserve(nullptr /* requested_address */, + size, + alignment, + page_size, + ExecMem, + mtCode); +} + +ReservedHeapSpace HeapReserver::Instance::reserve_uncompressed_oops_heap(size_t size, + size_t alignment, + size_t page_size) { + ReservedSpace reserved = reserve_memory(size, alignment, page_size); + + if (reserved.is_reserved()) { + return ReservedHeapSpace(reserved, 0 /* noaccess_prefix */); + } + + // Failed + return {}; +} + + +static int maybe_create_file(const char* heap_allocation_directory) { + if (heap_allocation_directory == nullptr) { + return -1; + } + + int fd = os::create_file_for_heap(heap_allocation_directory); + if (fd == -1) { + vm_exit_during_initialization( + err_msg("Could not create file for Heap at location %s", heap_allocation_directory)); + } + + return fd; +} + +HeapReserver::Instance::Instance(const char* heap_allocation_directory) + : _fd(maybe_create_file(heap_allocation_directory)) {} + +HeapReserver::Instance::~Instance() { + if (_fd != -1) { + ::close(_fd); + } +} + +ReservedSpace HeapReserver::Instance::reserve_memory(size_t size, + size_t alignment, + size_t page_size, + char* requested_address) { + + // There are basically three different cases that we need to handle below: + // 1. Mapping backed by a file + // 2. Mapping backed by explicit large pages + // 3. Mapping backed by normal pages or transparent huge pages + // The first two have restrictions that requires the whole mapping to be + // committed up front. To record this the ReservedSpace is marked 'special'. + + // == Case 1 == + if (_fd != -1) { + // When there is a backing file directory for this space then whether + // large pages are allocated is up to the filesystem of the backing file. + // So UseLargePages is not taken into account for this reservation. + // + // If requested, let the user know that explicit large pages can't be used. + if (use_explicit_large_pages(page_size) && large_pages_requested()) { + log_debug(gc, heap)("Cannot allocate explicit large pages for Java Heap when AllocateHeapAt option is set."); + } + + // Always return, not possible to fall back to reservation not using a file. + return FileMappedMemoryReserver::reserve(requested_address, size, alignment, _fd, mtJavaHeap); + } + + // == Case 2 & 3 == + return MemoryReserver::reserve(requested_address, size, alignment, page_size, mtJavaHeap); +} + +// Compressed oop support is not relevant in 32bit builds. +#ifdef _LP64 + +void HeapReserver::Instance::release(const ReservedSpace& reserved) { + if (reserved.is_reserved()) { + if (_fd == -1) { + if (reserved.special()) { + os::release_memory_special(reserved.base(), reserved.size()); + } else{ + os::release_memory(reserved.base(), reserved.size()); + } + } else { + os::unmap_memory(reserved.base(), reserved.size()); + } + } +} + +// Tries to allocate memory of size 'size' at address requested_address with alignment 'alignment'. +// Does not check whether the reserved memory actually is at requested_address, as the memory returned +// might still fulfill the wishes of the caller. +// Assures the memory is aligned to 'alignment'. +ReservedSpace HeapReserver::Instance::try_reserve_memory(size_t size, + size_t alignment, + size_t page_size, + char* requested_address) { + // Try to reserve the memory for the heap. + log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT + " heap of size 0x%zx", + p2i(requested_address), + size); + + ReservedSpace reserved = reserve_memory(size, alignment, page_size, requested_address); + + if (reserved.is_reserved()) { + // Check alignment constraints. + assert(reserved.alignment() == alignment, "Unexpected"); + assert(is_aligned(reserved.base(), alignment), "Unexpected"); + return reserved; + } + + // Failed + return {}; +} + +ReservedSpace HeapReserver::Instance::try_reserve_range(char *highest_start, + char *lowest_start, + size_t attach_point_alignment, + char *aligned_heap_base_min_address, + char *upper_bound, + size_t size, + size_t alignment, + size_t page_size) { + assert(is_aligned(highest_start, attach_point_alignment), "precondition"); + assert(is_aligned(lowest_start, attach_point_alignment), "precondition"); + + const size_t attach_range = pointer_delta(highest_start, lowest_start, sizeof(char)); + const size_t num_attempts_possible = (attach_range / attach_point_alignment) + 1; + const size_t num_attempts_to_try = MIN2((size_t)HeapSearchSteps, num_attempts_possible); + const size_t num_intervals = num_attempts_to_try - 1; + const size_t stepsize = num_intervals == 0 ? 0 : align_down(attach_range / num_intervals, attach_point_alignment); + + for (size_t i = 0; i < num_attempts_to_try; ++i) { + char* const attach_point = highest_start - stepsize * i; + ReservedSpace reserved = try_reserve_memory(size, alignment, page_size, attach_point); + + if (reserved.is_reserved()) { + if (reserved.base() >= aligned_heap_base_min_address && + size <= (uintptr_t)(upper_bound - reserved.base())) { + // Got a successful reservation. + return reserved; + } + + release(reserved); + } + } + + // Failed + return {}; +} + +#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) +#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) +#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) + +// Helper for heap allocation. Returns an array with addresses +// (OS-specific) which are suited for disjoint base mode. Array is +// null terminated. +static char** get_attach_addresses_for_disjoint_mode() { + static uint64_t addresses[] = { + 2 * SIZE_32G, + 3 * SIZE_32G, + 4 * SIZE_32G, + 8 * SIZE_32G, + 10 * SIZE_32G, + 1 * SIZE_64K * SIZE_32G, + 2 * SIZE_64K * SIZE_32G, + 3 * SIZE_64K * SIZE_32G, + 4 * SIZE_64K * SIZE_32G, + 16 * SIZE_64K * SIZE_32G, + 32 * SIZE_64K * SIZE_32G, + 34 * SIZE_64K * SIZE_32G, + 0 + }; + + // Sort out addresses smaller than HeapBaseMinAddress. This assumes + // the array is sorted. + uint i = 0; + while (addresses[i] != 0 && + (addresses[i] < OopEncodingHeapMax || addresses[i] < HeapBaseMinAddress)) { + i++; + } + uint start = i; + + // Avoid more steps than requested. + i = 0; + while (addresses[start+i] != 0) { + if (i == HeapSearchSteps) { + addresses[start+i] = 0; + break; + } + i++; + } + + return (char**) &addresses[start]; +} + +// Create protection page at the beginning of the space. +static ReservedSpace establish_noaccess_prefix(const ReservedSpace& reserved, size_t noaccess_prefix) { + assert(reserved.alignment() >= os::vm_page_size(), "must be at least page size big"); + assert(reserved.is_reserved(), "should only be called on a reserved memory area"); + + if (reserved.end() > (char *)OopEncodingHeapMax) { + if (true + WIN64_ONLY(&& !UseLargePages) + AIX_ONLY(&& (os::Aix::supports_64K_mmap_pages() || os::vm_page_size() == 4*K))) { + // Protect memory at the base of the allocated region. + if (!os::protect_memory(reserved.base(), noaccess_prefix, os::MEM_PROT_NONE, reserved.special())) { + fatal("cannot protect protection page"); + } + log_debug(gc, heap, coops)("Protected page at the reserved heap base: " + PTR_FORMAT " / %zd bytes", + p2i(reserved.base()), + noaccess_prefix); + assert(CompressedOops::use_implicit_null_checks() == true, "not initialized?"); + } else { + CompressedOops::set_use_implicit_null_checks(false); + } + } + + return reserved.last_part(noaccess_prefix); +} + +ReservedHeapSpace HeapReserver::Instance::reserve_compressed_oops_heap(const size_t size, size_t alignment, size_t page_size) { + const size_t noaccess_prefix_size = lcm(os::vm_page_size(), alignment); + const size_t granularity = os::vm_allocation_granularity(); + + assert(size + noaccess_prefix_size <= OopEncodingHeapMax, "can not allocate compressed oop heap for this size"); + assert(is_aligned(size, granularity), "size not aligned to os::vm_allocation_granularity()"); + + assert(alignment >= os::vm_page_size(), "alignment too small"); + assert(is_aligned(alignment, granularity), "alignment not aligned to os::vm_allocation_granularity()"); + assert(is_power_of_2(alignment), "not a power of 2"); + + // The necessary attach point alignment for generated wish addresses. + // This is needed to increase the chance of attaching for mmap and shmat. + // AIX is the only platform that uses System V shm for reserving virtual memory. + // In this case, the required alignment of the allocated size (64K) and the alignment + // of possible start points of the memory region (256M) differ. + // This is not reflected by os_allocation_granularity(). + // The logic here is dual to the one in pd_reserve_memory in os_aix.cpp + const size_t os_attach_point_alignment = + AIX_ONLY(os::vm_page_size() == 4*K ? 4*K : 256*M) + NOT_AIX(os::vm_allocation_granularity()); + + const size_t attach_point_alignment = lcm(alignment, os_attach_point_alignment); + + char* aligned_heap_base_min_address = align_up((char*)HeapBaseMinAddress, alignment); + size_t noaccess_prefix = ((aligned_heap_base_min_address + size) > (char*)OopEncodingHeapMax) ? + noaccess_prefix_size : 0; + + ReservedSpace reserved{}; + + // Attempt to alloc at user-given address. + if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) { + reserved = try_reserve_memory(size + noaccess_prefix, alignment, page_size, aligned_heap_base_min_address); + if (reserved.base() != aligned_heap_base_min_address) { // Enforce this exact address. + release(reserved); + reserved = {}; + } + } + + // Keep heap at HeapBaseMinAddress. + if (!reserved.is_reserved()) { + + // Try to allocate the heap at addresses that allow efficient oop compression. + // Different schemes are tried, in order of decreasing optimization potential. + // + // For this, try_reserve_heap() is called with the desired heap base addresses. + // A call into the os layer to allocate at a given address can return memory + // at a different address than requested. Still, this might be memory at a useful + // address. try_reserve_heap() always returns this allocated memory, as only here + // the criteria for a good heap are checked. + + // Attempt to allocate so that we can run without base and scale (32-Bit unscaled compressed oops). + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= (char *)UnscaledOopHeapMax) { + + // Calc address range within we try to attach (range of possible start addresses). + char* const highest_start = align_down((char *)UnscaledOopHeapMax - size, attach_point_alignment); + char* const lowest_start = align_up(aligned_heap_base_min_address, attach_point_alignment); + reserved = try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, page_size); + } + + // zerobased: Attempt to allocate in the lower 32G. + char *zerobased_max = (char *)OopEncodingHeapMax; + + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= zerobased_max && // Zerobased theoretical possible. + ((!reserved.is_reserved()) || // No previous try succeeded. + (reserved.end() > zerobased_max))) { // Unscaled delivered an arbitrary address. + + // Release previous reservation + release(reserved); + + // Calc address range within we try to attach (range of possible start addresses). + char *const highest_start = align_down(zerobased_max - size, attach_point_alignment); + // Need to be careful about size being guaranteed to be less + // than UnscaledOopHeapMax due to type constraints. + char *lowest_start = aligned_heap_base_min_address; + uint64_t unscaled_end = UnscaledOopHeapMax - size; + if (unscaled_end < UnscaledOopHeapMax) { // unscaled_end wrapped if size is large + lowest_start = MAX2(lowest_start, (char*)unscaled_end); + } + lowest_start = align_up(lowest_start, attach_point_alignment); + reserved = try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, zerobased_max, size, alignment, page_size); + } + + // Now we go for heaps with base != 0. We need a noaccess prefix to efficiently + // implement null checks. + noaccess_prefix = noaccess_prefix_size; + + // Try to attach at addresses that are aligned to OopEncodingHeapMax. Disjointbase mode. + char** addresses = get_attach_addresses_for_disjoint_mode(); + int i = 0; + while ((addresses[i] != nullptr) && // End of array not yet reached. + ((!reserved.is_reserved()) || // No previous try succeeded. + (reserved.end() > zerobased_max && // Not zerobased or unscaled address. + // Not disjoint address. + !CompressedOops::is_disjoint_heap_base_address((address)reserved.base())))) { + + // Release previous reservation + release(reserved); + + char* const attach_point = addresses[i]; + assert(attach_point >= aligned_heap_base_min_address, "Flag support broken"); + reserved = try_reserve_memory(size + noaccess_prefix, alignment, page_size, attach_point); + i++; + } + + // Last, desperate try without any placement. + if (!reserved.is_reserved()) { + log_trace(gc, heap, coops)("Trying to allocate at address null heap of size 0x%zx", size + noaccess_prefix); + assert(alignment >= os::vm_page_size(), "Unexpected"); + reserved = reserve_memory(size + noaccess_prefix, alignment, page_size); + } + } + + // No more reserve attempts + + if (reserved.is_reserved()) { + // Successfully found and reserved memory for the heap. + + if (reserved.size() > size) { + // We reserved heap memory with a noaccess prefix. + + assert(reserved.size() == size + noaccess_prefix, "Prefix should be included"); + // It can happen we get a zerobased/unscaled heap with noaccess prefix, + // if we had to try at arbitrary address. + reserved = establish_noaccess_prefix(reserved, noaccess_prefix); + assert(reserved.size() == size, "Prefix should be gone"); + return ReservedHeapSpace(reserved, noaccess_prefix); + } + + // We reserved heap memory without a noaccess prefix. + return ReservedHeapSpace(reserved, 0 /* noaccess_prefix */); + } + + // Failed + return {}; +} + +#endif // _LP64 + +ReservedHeapSpace HeapReserver::Instance::reserve_heap(size_t size, size_t alignment, size_t page_size) { + if (UseCompressedOops) { +#ifdef _LP64 + return reserve_compressed_oops_heap(size, alignment, page_size); +#endif + } else { + return reserve_uncompressed_oops_heap(size, alignment, page_size); + } +} + +ReservedHeapSpace HeapReserver::reserve(size_t size, size_t alignment, size_t page_size, const char* heap_allocation_directory) { + sanity_check_arguments(size, alignment, page_size); + + assert(alignment != 0, "Precondition"); + assert(is_aligned(size, alignment), "Precondition"); + + Instance instance(heap_allocation_directory); + + return instance.reserve_heap(size, alignment, page_size); +} diff --git a/src/hotspot/share/memory/memoryReserver.hpp b/src/hotspot/share/memory/memoryReserver.hpp new file mode 100644 index 0000000000000..1e16ec252a9de --- /dev/null +++ b/src/hotspot/share/memory/memoryReserver.hpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_MEMORY_MEMORYRESERVER_HPP +#define SHARE_MEMORY_MEMORYRESERVER_HPP + +#include "memory/allStatic.hpp" +#include "memory/reservedSpace.hpp" +#include "nmt/memTag.hpp" +#include "utilities/globalDefinitions.hpp" + +class MemoryReserver : AllStatic { + static ReservedSpace reserve_memory(char* requested_address, + size_t size, + size_t alignment, + bool exec, + MemTag mem_tag); + + static ReservedSpace reserve_memory_special(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + bool exec); + +public: + // Final destination + static ReservedSpace reserve(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + bool executable, + MemTag mem_tag); + + // Convenience overloads + + static ReservedSpace reserve(char* requested_address, + size_t size, + size_t alignment, + size_t page_size, + MemTag mem_tag = mtNone); + + static ReservedSpace reserve(size_t size, + size_t alignment, + size_t page_size, + MemTag mem_tag = mtNone); + + static ReservedSpace reserve(size_t size, + MemTag mem_tag); + + // Release reserved memory + static bool release(const ReservedSpace& reserved); +}; + +class CodeMemoryReserver : AllStatic { +public: + static ReservedSpace reserve(size_t size, + size_t alignment, + size_t page_size); +}; + +class FileMappedMemoryReserver : AllStatic { +public: + static ReservedSpace reserve(char* requested_address, + size_t size, + size_t alignment, + int fd, + MemTag mem_tag); +}; + +class HeapReserver : AllStatic { + class Instance { + const int _fd; + + NONCOPYABLE(Instance); + + ReservedSpace reserve_memory(size_t size, + size_t alignment, + size_t page_size, + char* requested_address = nullptr); + + void release(const ReservedSpace& reserved); + + // CompressedOops support +#ifdef _LP64 + + ReservedSpace try_reserve_memory(size_t size, + size_t alignment, + size_t page_size, + char* requested_address); + + ReservedSpace try_reserve_range(char *highest_start, + char *lowest_start, + size_t attach_point_alignment, + char *aligned_heap_base_min_address, + char *upper_bound, + size_t size, + size_t alignment, + size_t page_size); + + ReservedHeapSpace reserve_compressed_oops_heap(size_t size, + size_t alignment, + size_t page_size); + +#endif // _LP64 + + ReservedHeapSpace reserve_uncompressed_oops_heap(size_t size, + size_t alignment, + size_t page_size); + + public: + Instance(const char* heap_allocation_directory); + ~Instance(); + + ReservedHeapSpace reserve_heap(size_t size, + size_t alignment, + size_t page_size); + }; // Instance + +public: + static ReservedHeapSpace reserve(size_t size, + size_t alignment, + size_t page_size, + const char* heap_allocation_directory); +}; + +#endif // SHARE_MEMORY_MEMORYRESERVER_HPP diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp index aa592a3a6aa68..c1fc0bf669bbd 100644 --- a/src/hotspot/share/memory/metaspace.cpp +++ b/src/hotspot/share/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2021 SAP SE. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/classLoaderData.hpp" @@ -32,6 +31,7 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/classLoaderMetaspace.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspace.hpp" #include "memory/metaspace/chunkHeaderPool.hpp" #include "memory/metaspace/chunkManager.hpp" @@ -57,11 +57,11 @@ #include "runtime/globals_extension.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" +#include "runtime/mutexLocker.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" -#include "virtualspace.hpp" using metaspace::ChunkManager; using metaspace::CommitLimiter; @@ -216,18 +216,18 @@ void MetaspaceUtils::print_on(outputStream* out) { // Used from all GCs. It first prints out totals, then, separately, the class space portion. MetaspaceCombinedStats stats = get_combined_statistics(); out->print_cr(" Metaspace " - "used " SIZE_FORMAT "K, " - "committed " SIZE_FORMAT "K, " - "reserved " SIZE_FORMAT "K", + "used %zuK, " + "committed %zuK, " + "reserved %zuK", stats.used()/K, stats.committed()/K, stats.reserved()/K); if (Metaspace::using_class_space()) { out->print_cr(" class space " - "used " SIZE_FORMAT "K, " - "committed " SIZE_FORMAT "K, " - "reserved " SIZE_FORMAT "K", + "used %zuK, " + "committed %zuK, " + "reserved %zuK", stats.class_space_stats().used()/K, stats.class_space_stats().committed()/K, stats.class_space_stats().reserved()/K); @@ -385,7 +385,7 @@ bool MetaspaceGC::can_expand(size_t word_size, bool is_class) { if (is_class && Metaspace::using_class_space()) { size_t class_committed = MetaspaceUtils::committed_bytes(Metaspace::ClassType); if (class_committed + word_size * BytesPerWord > CompressedClassSpaceSize) { - log_trace(gc, metaspace, freelist)("Cannot expand %s metaspace by " SIZE_FORMAT " words (CompressedClassSpaceSize = " SIZE_FORMAT " words)", + log_trace(gc, metaspace, freelist)("Cannot expand %s metaspace by %zu words (CompressedClassSpaceSize = %zu words)", (is_class ? "class" : "non-class"), word_size, CompressedClassSpaceSize / sizeof(MetaWord)); return false; } @@ -394,7 +394,7 @@ bool MetaspaceGC::can_expand(size_t word_size, bool is_class) { // Check if the user has imposed a limit on the metaspace memory. size_t committed_bytes = MetaspaceUtils::committed_bytes(); if (committed_bytes + word_size * BytesPerWord > MaxMetaspaceSize) { - log_trace(gc, metaspace, freelist)("Cannot expand %s metaspace by " SIZE_FORMAT " words (MaxMetaspaceSize = " SIZE_FORMAT " words)", + log_trace(gc, metaspace, freelist)("Cannot expand %s metaspace by %zu words (MaxMetaspaceSize = %zu words)", (is_class ? "class" : "non-class"), word_size, MaxMetaspaceSize / sizeof(MetaWord)); return false; } @@ -412,8 +412,8 @@ size_t MetaspaceGC::allowed_expansion() { size_t left_until_GC = capacity_until_gc > committed_bytes ? capacity_until_gc - committed_bytes : 0; size_t left_to_commit = MIN2(left_until_GC, left_until_max); - log_trace(gc, metaspace, freelist)("allowed expansion words: " SIZE_FORMAT - " (left_until_max: " SIZE_FORMAT ", left_until_GC: " SIZE_FORMAT ".", + log_trace(gc, metaspace, freelist)("allowed expansion words: %zu" + " (left_until_max: %zu, left_until_GC: %zu.", left_to_commit / BytesPerWord, left_until_max / BytesPerWord, left_until_GC / BytesPerWord); return left_to_commit / BytesPerWord; @@ -477,7 +477,7 @@ void MetaspaceGC::compute_new_size() { // No expansion, now see if we want to shrink // We would never want to shrink more than this assert(capacity_until_GC >= minimum_desired_capacity, - SIZE_FORMAT " >= " SIZE_FORMAT, + "%zu >= %zu", capacity_until_GC, minimum_desired_capacity); size_t max_shrink_bytes = capacity_until_GC - minimum_desired_capacity; @@ -511,7 +511,7 @@ void MetaspaceGC::compute_new_size() { shrink_bytes = align_down(shrink_bytes, Metaspace::commit_alignment()); assert(shrink_bytes <= max_shrink_bytes, - "invalid shrink size " SIZE_FORMAT " not <= " SIZE_FORMAT, + "invalid shrink size %zu not <= %zu", shrink_bytes, max_shrink_bytes); if (current_shrink_factor == 0) { _shrink_factor = 10; @@ -553,7 +553,7 @@ void Metaspace::print_compressed_class_space(outputStream* st) { MetaWord* base = VirtualSpaceList::vslist_class()->base_of_first_node(); size_t size = VirtualSpaceList::vslist_class()->word_size_of_first_node(); MetaWord* top = base + size; - st->print("Compressed class space mapped at: " PTR_FORMAT "-" PTR_FORMAT ", reserved size: " SIZE_FORMAT, + st->print("Compressed class space mapped at: " PTR_FORMAT "-" PTR_FORMAT ", reserved size: %zu", p2i(base), p2i(top), (top - base) * BytesPerWord); st->cr(); } @@ -562,10 +562,10 @@ void Metaspace::print_compressed_class_space(outputStream* st) { // Given a prereserved space, use that to set up the compressed class space list. void Metaspace::initialize_class_space(ReservedSpace rs) { assert(rs.size() >= CompressedClassSpaceSize, - SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize); + "%zu != %zu", rs.size(), CompressedClassSpaceSize); assert(using_class_space(), "Must be using class space"); - assert(rs.size() == CompressedClassSpaceSize, SIZE_FORMAT " != " SIZE_FORMAT, + assert(rs.size() == CompressedClassSpaceSize, "%zu != %zu", rs.size(), CompressedClassSpaceSize); assert(is_aligned(rs.base(), Metaspace::reserve_alignment()) && is_aligned(rs.size(), Metaspace::reserve_alignment()), @@ -597,17 +597,20 @@ ReservedSpace Metaspace::reserve_address_space_for_compressed_classes(size_t siz } // Wrap resulting range in ReservedSpace - ReservedSpace rs; if (result != nullptr) { log_debug(metaspace, map)("Mapped at " PTR_FORMAT, p2i(result)); assert(is_aligned(result, Metaspace::reserve_alignment()), "Alignment too small for metaspace"); - rs = ReservedSpace::space_for_range(result, size, Metaspace::reserve_alignment(), - os::vm_page_size(), false, false); + + return ReservedSpace(result, + size, + Metaspace::reserve_alignment(), + os::vm_page_size(), + !ExecMem, + false /* special */); } else { log_debug(metaspace, map)("Failed to map."); - rs = ReservedSpace(); + return {}; } - return rs; } #endif // _LP64 @@ -688,7 +691,7 @@ void Metaspace::ergo_initialize() { // Lets just live with that, its not a big deal. if (adjusted_ccs_size != CompressedClassSpaceSize) { FLAG_SET_ERGO(CompressedClassSpaceSize, adjusted_ccs_size); - log_info(metaspace)("Setting CompressedClassSpaceSize to " SIZE_FORMAT ".", + log_info(metaspace)("Setting CompressedClassSpaceSize to %zu.", CompressedClassSpaceSize); } } @@ -757,11 +760,15 @@ void Metaspace::global_initialize() { if (!is_aligned(base, Metaspace::reserve_alignment())) { vm_exit_during_initialization( err_msg("CompressedClassSpaceBaseAddress=" PTR_FORMAT " invalid " - "(must be aligned to " SIZE_FORMAT_X ").", + "(must be aligned to 0x%zx).", CompressedClassSpaceBaseAddress, Metaspace::reserve_alignment())); } - rs = ReservedSpace(size, Metaspace::reserve_alignment(), - os::vm_page_size() /* large */, (char*)base); + + rs = MemoryReserver::reserve((char*)base, + size, + Metaspace::reserve_alignment(), + os::vm_page_size()); + if (rs.is_reserved()) { log_info(metaspace)("Successfully forced class space address to " PTR_FORMAT, p2i(base)); } else { @@ -785,7 +792,7 @@ void Metaspace::global_initialize() { // ...failing that, give up. if (!rs.is_reserved()) { vm_exit_during_initialization( - err_msg("Could not allocate compressed class space: " SIZE_FORMAT " bytes", + err_msg("Could not allocate compressed class space: %zu bytes", CompressedClassSpaceSize)); } @@ -851,7 +858,7 @@ size_t Metaspace::max_allocation_word_size() { MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, bool use_class_space) { assert(word_size <= Metaspace::max_allocation_word_size(), - "allocation size too large (" SIZE_FORMAT ")", word_size); + "allocation size too large (%zu)", word_size); assert(loader_data != nullptr, "Should never pass around a null loader_data. " "ClassLoaderData::the_null_class_loader_data() should have been used."); @@ -927,7 +934,7 @@ void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_s { LogMessage(gc, metaspace, freelist, oom) log; if (log.is_info()) { - log.info("Metaspace (%s) allocation failed for size " SIZE_FORMAT, + log.info("Metaspace (%s) allocation failed for size %zu", is_class_space_allocation(mdtype) ? "class" : "data", word_size); ResourceMark rm; if (log.is_debug()) { @@ -1021,4 +1028,3 @@ bool Metaspace::is_in_shared_metaspace(const void* ptr) { bool Metaspace::is_in_nonclass_metaspace(const void* ptr) { return VirtualSpaceList::vslist_nonclass()->contains((MetaWord*)ptr); } - diff --git a/src/hotspot/share/memory/metaspace.hpp b/src/hotspot/share/memory/metaspace.hpp index 7adebfd826baa..293782c0d758a 100644 --- a/src/hotspot/share/memory/metaspace.hpp +++ b/src/hotspot/share/memory/metaspace.hpp @@ -26,7 +26,6 @@ #define SHARE_MEMORY_METASPACE_HPP #include "memory/allocation.hpp" -#include "memory/virtualspace.hpp" #include "runtime/globals.hpp" #include "utilities/exceptions.hpp" #include "utilities/globalDefinitions.hpp" @@ -36,6 +35,7 @@ class MetaspaceShared; class MetaspaceTracer; class Mutex; class outputStream; +class ReservedSpace; ////////////////// Metaspace /////////////////////// diff --git a/src/hotspot/share/memory/metaspace/binList.hpp b/src/hotspot/share/memory/metaspace/binList.hpp index 9442ea3cd5200..18e1b2c7fb86d 100644 --- a/src/hotspot/share/memory/metaspace/binList.hpp +++ b/src/hotspot/share/memory/metaspace/binList.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * Copyright (c) 2023 Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -78,7 +78,7 @@ class BinListImpl { Block(Block* next) : _next(next) {} }; -#define BLOCK_FORMAT "Block @" PTR_FORMAT ": size: " SIZE_FORMAT ", next: " PTR_FORMAT +#define BLOCK_FORMAT "Block @" PTR_FORMAT ": size: %zu, next: " PTR_FORMAT #define BLOCK_FORMAT_ARGS(b, sz) p2i(b), (sz), p2i((b)->_next) // Block size must be exactly one word size. @@ -161,7 +161,7 @@ class BinListImpl { // Block may be larger. MetaBlock remove_block(size_t word_size) { assert(word_size >= MinWordSize && - word_size <= MaxWordSize, "bad block size " SIZE_FORMAT ".", word_size); + word_size <= MaxWordSize, "bad block size %zu.", word_size); MetaBlock result; int index = index_for_word_size(word_size); index = index_for_next_non_empty_list(index); diff --git a/src/hotspot/share/memory/metaspace/blockTree.cpp b/src/hotspot/share/memory/metaspace/blockTree.cpp index 85e7750883667..33237494b50b0 100644 --- a/src/hotspot/share/memory/metaspace/blockTree.cpp +++ b/src/hotspot/share/memory/metaspace/blockTree.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/chunklevel.hpp" #include "memory/metaspace/blockTree.hpp" #include "memory/resourceArea.hpp" @@ -44,7 +43,7 @@ const size_t BlockTree::MinWordSize; ", left " PTR_FORMAT \ ", right " PTR_FORMAT \ ", next " PTR_FORMAT \ - ", size " SIZE_FORMAT + ", size %zu" #define NODE_FORMAT_ARGS(n) \ p2i(n), \ diff --git a/src/hotspot/share/memory/metaspace/blockTree.hpp b/src/hotspot/share/memory/metaspace/blockTree.hpp index 8bcdd30919ae9..a01f60b166f14 100644 --- a/src/hotspot/share/memory/metaspace/blockTree.hpp +++ b/src/hotspot/share/memory/metaspace/blockTree.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -348,7 +348,7 @@ class BlockTree: public CHeapObj { void add_block(MetaBlock block) { DEBUG_ONLY(zap_block(block);) const size_t word_size = block.word_size(); - assert(word_size >= MinWordSize, "invalid block size " SIZE_FORMAT, word_size); + assert(word_size >= MinWordSize, "invalid block size %zu", word_size); Node* n = new(block.base()) Node(word_size); if (_root == nullptr) { _root = n; @@ -361,7 +361,7 @@ class BlockTree: public CHeapObj { // Given a word_size, search and return the smallest block that is equal or // larger than that size. MetaBlock remove_block(size_t word_size) { - assert(word_size >= MinWordSize, "invalid block size " SIZE_FORMAT, word_size); + assert(word_size >= MinWordSize, "invalid block size %zu", word_size); MetaBlock result; Node* n = find_closest_fit(word_size); diff --git a/src/hotspot/share/memory/metaspace/chunkHeaderPool.cpp b/src/hotspot/share/memory/metaspace/chunkHeaderPool.cpp index 050dd74276358..ac63d0d022593 100644 --- a/src/hotspot/share/memory/metaspace/chunkHeaderPool.cpp +++ b/src/hotspot/share/memory/metaspace/chunkHeaderPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/chunkHeaderPool.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/memory/metaspace/chunkManager.cpp b/src/hotspot/share/memory/metaspace/chunkManager.cpp index 7b51198bc79a3..2c787046ce8d9 100644 --- a/src/hotspot/share/memory/metaspace/chunkManager.cpp +++ b/src/hotspot/share/memory/metaspace/chunkManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/metaspace/chunkManager.hpp" @@ -141,7 +140,7 @@ Metachunk* ChunkManager::get_chunk_locked(chunklevel_t preferred_level, chunklev DEBUG_ONLY(chunklevel::check_valid_level(preferred_level);) UL2(debug, "requested chunk: pref_level: " CHKLVL_FORMAT - ", max_level: " CHKLVL_FORMAT ", min committed size: " SIZE_FORMAT ".", + ", max_level: " CHKLVL_FORMAT ", min committed size: %zu.", preferred_level, max_level, min_committed_words); // First, optimistically look for a chunk which is already committed far enough to hold min_word_size. @@ -212,7 +211,7 @@ Metachunk* ChunkManager::get_chunk_locked(chunklevel_t preferred_level, chunklev const size_t to_commit = min_committed_words; if (c->committed_words() < to_commit) { if (c->ensure_committed_locked(to_commit) == false) { - UL2(info, "failed to commit " SIZE_FORMAT " words on chunk " METACHUNK_FORMAT ".", + UL2(info, "failed to commit %zu words on chunk " METACHUNK_FORMAT ".", to_commit, METACHUNK_FORMAT_ARGS(c)); return_chunk_locked(c); c = nullptr; @@ -434,7 +433,7 @@ void ChunkManager::print_on(outputStream* st) const { void ChunkManager::print_on_locked(outputStream* st) const { assert_lock_strong(Metaspace_lock); - st->print_cr("cm %s: %d chunks, total word size: " SIZE_FORMAT ".", _name, + st->print_cr("cm %s: %d chunks, total word size: %zu.", _name, total_num_chunks(), total_word_size()); _chunks.print_on(st); } diff --git a/src/hotspot/share/memory/metaspace/chunklevel.cpp b/src/hotspot/share/memory/metaspace/chunklevel.cpp index c8bb19373d600..371ba0e68cd14 100644 --- a/src/hotspot/share/memory/metaspace/chunklevel.cpp +++ b/src/hotspot/share/memory/metaspace/chunklevel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/chunklevel.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" @@ -36,7 +35,7 @@ using namespace chunklevel; chunklevel_t chunklevel::level_fitting_word_size(size_t word_size) { assert(MAX_CHUNK_WORD_SIZE >= word_size, - SIZE_FORMAT " - too large allocation size.", word_size * BytesPerWord); + "%zu - too large allocation size.", word_size * BytesPerWord); if (word_size <= MIN_CHUNK_WORD_SIZE) { return HIGHEST_CHUNK_LEVEL; } diff --git a/src/hotspot/share/memory/metaspace/commitLimiter.cpp b/src/hotspot/share/memory/metaspace/commitLimiter.cpp index 8887804b030d1..97bf9faa9c659 100644 --- a/src/hotspot/share/memory/metaspace/commitLimiter.cpp +++ b/src/hotspot/share/memory/metaspace/commitLimiter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "memory/metaspace/commitLimiter.hpp" #include "memory/metaspaceUtils.hpp" diff --git a/src/hotspot/share/memory/metaspace/commitMask.cpp b/src/hotspot/share/memory/metaspace/commitMask.cpp index a1bc985210bf1..b6227f16b8ad3 100644 --- a/src/hotspot/share/memory/metaspace/commitMask.cpp +++ b/src/hotspot/share/memory/metaspace/commitMask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/commitMask.hpp" #include "memory/metaspace/metaspaceCommon.hpp" #include "memory/metaspace/metaspaceSettings.hpp" @@ -61,7 +60,7 @@ void CommitMask::check_pointer(const MetaWord* p) const { void CommitMask::check_pointer_aligned(const MetaWord* p) const { check_pointer(p); assert(is_aligned(p, _words_per_bit * BytesPerWord), - "Pointer " PTR_FORMAT " should be aligned to commit granule size " SIZE_FORMAT ".", + "Pointer " PTR_FORMAT " should be aligned to commit granule size %zu.", p2i(p), _words_per_bit * BytesPerWord); } // Given a range, check if it points into the range this bitmap covers, @@ -69,7 +68,7 @@ void CommitMask::check_pointer_aligned(const MetaWord* p) const { void CommitMask::check_range(const MetaWord* start, size_t word_size) const { check_pointer_aligned(start); assert(is_aligned(word_size, _words_per_bit), - "Range " SIZE_FORMAT " should be aligned to commit granule size " SIZE_FORMAT ".", + "Range %zu should be aligned to commit granule size %zu.", word_size, _words_per_bit); check_pointer(start + word_size - 1); } diff --git a/src/hotspot/share/memory/metaspace/freeBlocks.cpp b/src/hotspot/share/memory/metaspace/freeBlocks.cpp index ab65387043a7e..93f68d89ecd4d 100644 --- a/src/hotspot/share/memory/metaspace/freeBlocks.cpp +++ b/src/hotspot/share/memory/metaspace/freeBlocks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/freeBlocks.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/memory/metaspace/freeChunkList.cpp b/src/hotspot/share/memory/metaspace/freeChunkList.cpp index 65eace074f933..3640f9d354d90 100644 --- a/src/hotspot/share/memory/metaspace/freeChunkList.cpp +++ b/src/hotspot/share/memory/metaspace/freeChunkList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/freeChunkList.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" @@ -155,7 +154,7 @@ void FreeChunkListVector::print_on(outputStream* st) const { list_for_level(l)->print_on(st); st->cr(); } - st->print_cr("total chunks: %d, total word size: " SIZE_FORMAT ".", + st->print_cr("total chunks: %d, total word size: %zu.", num_chunks(), word_size()); } diff --git a/src/hotspot/share/memory/metaspace/internalStats.cpp b/src/hotspot/share/memory/metaspace/internalStats.cpp index d7b0e4495051e..0f386eb33a5c1 100644 --- a/src/hotspot/share/memory/metaspace/internalStats.cpp +++ b/src/hotspot/share/memory/metaspace/internalStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/internalStats.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/ostream.hpp" @@ -41,7 +40,7 @@ void InternalStats::print_on(outputStream* st) { #define xstr(s) str(s) #define str(s) #s -#define PRINT_COUNTER(name) st->print_cr("%s: " UINTX_FORMAT ".", xstr(name), _##name); +#define PRINT_COUNTER(name) st->print_cr("%s: %zu.", xstr(name), _##name); ALL_MY_COUNTERS(PRINT_COUNTER, PRINT_COUNTER) #undef PRINT_COUNTER diff --git a/src/hotspot/share/memory/metaspace/metablock.hpp b/src/hotspot/share/memory/metaspace/metablock.hpp index 96e27ff8702e8..4b2dfdfe6803e 100644 --- a/src/hotspot/share/memory/metaspace/metablock.hpp +++ b/src/hotspot/share/memory/metaspace/metablock.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023 Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ class MetaBlock { void print_on(outputStream* st) const; }; -#define METABLOCKFORMAT "block (@" PTR_FORMAT " word size " SIZE_FORMAT ")" +#define METABLOCKFORMAT "block (@" PTR_FORMAT " word size %zu)" #define METABLOCKFORMATARGS(__block__) p2i((__block__).base()), (__block__).word_size() } // namespace metaspace diff --git a/src/hotspot/share/memory/metaspace/metachunk.cpp b/src/hotspot/share/memory/metaspace/metachunk.cpp index 0bf7e98f13022..df3718d7bfa54 100644 --- a/src/hotspot/share/memory/metaspace/metachunk.cpp +++ b/src/hotspot/share/memory/metaspace/metachunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/metaspace/metachunk.hpp" #include "memory/metaspace/metaspaceCommon.hpp" @@ -102,7 +101,7 @@ bool Metachunk::commit_up_to(size_t new_committed_words) { assert(commit_to <= word_size(), "Sanity"); if (commit_to > commit_from) { log_debug(metaspace)("Chunk " METACHUNK_FORMAT ": attempting to move commit line to " - SIZE_FORMAT " words.", METACHUNK_FORMAT_ARGS(this), commit_to); + "%zu words.", METACHUNK_FORMAT_ARGS(this), commit_to); if (!_vsnode->ensure_range_is_committed(base() + commit_from, commit_to - commit_from)) { DEBUG_ONLY(verify();) return false; @@ -271,10 +270,10 @@ void Metachunk::verify() const { assert(base() != nullptr, "No base ptr"); assert(committed_words() >= used_words(), - "mismatch: committed: " SIZE_FORMAT ", used: " SIZE_FORMAT ".", + "mismatch: committed: %zu, used: %zu.", committed_words(), used_words()); assert(word_size() >= committed_words(), - "mismatch: word_size: " SIZE_FORMAT ", committed: " SIZE_FORMAT ".", + "mismatch: word_size: %zu, committed: %zu.", word_size(), committed_words()); // Test base pointer @@ -304,8 +303,8 @@ void Metachunk::verify() const { void Metachunk::print_on(outputStream* st) const { // Note: must also work with invalid/random data. (e.g. do not call word_size()) st->print("Chunk @" PTR_FORMAT ", state %c, base " PTR_FORMAT ", " - "level " CHKLVL_FORMAT " (" SIZE_FORMAT " words), " - "used " SIZE_FORMAT " words, committed " SIZE_FORMAT " words.", + "level " CHKLVL_FORMAT " (%zu words), " + "used %zu words, committed %zu words.", p2i(this), get_state_char(), p2i(base()), level(), (chunklevel::is_valid_level(level()) ? chunklevel::word_size_for_level(level()) : SIZE_MAX), used_words(), committed_words()); diff --git a/src/hotspot/share/memory/metaspace/metachunk.hpp b/src/hotspot/share/memory/metaspace/metachunk.hpp index efd849c6e5a36..c025343231b1c 100644 --- a/src/hotspot/share/memory/metaspace/metachunk.hpp +++ b/src/hotspot/share/memory/metaspace/metachunk.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -362,7 +362,7 @@ class Metachunk { #define METACHUNK_FORMAT "@" PTR_FORMAT ", %c, base " PTR_FORMAT ", level " CHKLVL_FORMAT #define METACHUNK_FORMAT_ARGS(chunk) p2i(chunk), chunk->get_state_char(), p2i(chunk->base()), chunk->level() -#define METACHUNK_FULL_FORMAT "@" PTR_FORMAT ", %c, base " PTR_FORMAT ", level " CHKLVL_FORMAT " (" SIZE_FORMAT "), used: " SIZE_FORMAT ", committed: " SIZE_FORMAT ", committed-free: " SIZE_FORMAT +#define METACHUNK_FULL_FORMAT "@" PTR_FORMAT ", %c, base " PTR_FORMAT ", level " CHKLVL_FORMAT " (%zu), used: %zu, committed: %zu, committed-free: %zu" #define METACHUNK_FULL_FORMAT_ARGS(chunk) p2i(chunk), chunk->get_state_char(), p2i(chunk->base()), chunk->level(), chunk->word_size(), chunk->used_words(), chunk->committed_words(), chunk->free_below_committed_words() } // namespace metaspace diff --git a/src/hotspot/share/memory/metaspace/metachunkList.cpp b/src/hotspot/share/memory/metaspace/metachunkList.cpp index e691f9e359425..d8a956060683a 100644 --- a/src/hotspot/share/memory/metaspace/metachunkList.cpp +++ b/src/hotspot/share/memory/metaspace/metachunkList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/metachunkList.hpp" #include "memory/metaspace/metaspaceCommon.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceArena.cpp b/src/hotspot/share/memory/metaspace/metaspaceArena.cpp index 33f1bfc46a31d..709bbfd90a119 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceArena.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceArena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/metaspace/chunkManager.hpp" @@ -84,7 +83,7 @@ MetaBlock MetaspaceArena::salvage_chunk(Metachunk* c) { Metachunk* MetaspaceArena::allocate_new_chunk(size_t requested_word_size) { // Should this ever happen, we need to increase the maximum possible chunk size. guarantee(requested_word_size <= chunklevel::MAX_CHUNK_WORD_SIZE, - "Requested size too large (" SIZE_FORMAT ") - max allowed size per allocation is " SIZE_FORMAT ".", + "Requested size too large (%zu) - max allowed size per allocation is %zu.", requested_word_size, chunklevel::MAX_CHUNK_WORD_SIZE); const chunklevel_t max_level = chunklevel::level_fitting_word_size(requested_word_size); @@ -150,7 +149,7 @@ MetaspaceArena::~MetaspaceArena() { c = c2; } - UL2(debug, "returned %d chunks, total capacity " SIZE_FORMAT " words.", + UL2(debug, "returned %d chunks, total capacity %zu words.", return_counter.count(), return_counter.total_size()); _total_used_words_counter->decrement_by(return_counter.total_size()); @@ -216,7 +215,7 @@ bool MetaspaceArena::attempt_enlarge_current_chunk(size_t requested_word_size) { // 4) Attempt to get a new chunk and allocate from that chunk. // At any point, if we hit a commit limit, we return null. MetaBlock MetaspaceArena::allocate(size_t requested_word_size, MetaBlock& wastage) { - UL2(trace, "requested " SIZE_FORMAT " words.", requested_word_size); + UL2(trace, "requested %zu words.", requested_word_size); const size_t aligned_word_size = get_raw_word_size_for_requested_word_size(requested_word_size); @@ -234,7 +233,7 @@ MetaBlock MetaspaceArena::allocate(size_t requested_word_size, MetaBlock& wastag wastage = result.split_off_tail(result.word_size() - aligned_word_size); // Stats, logging DEBUG_ONLY(InternalStats::inc_num_allocs_from_deallocated_blocks();) - UL2(trace, "returning " METABLOCKFORMAT " with wastage " METABLOCKFORMAT " - taken from fbl (now: %d, " SIZE_FORMAT ").", + UL2(trace, "returning " METABLOCKFORMAT " with wastage " METABLOCKFORMAT " - taken from fbl (now: %d, %zu).", METABLOCKFORMATARGS(result), METABLOCKFORMATARGS(wastage), _fbl->count(), _fbl->total_size()); // Note: free blocks in freeblock dictionary still count as "used" as far as statistics go; // therefore we don't need to adjust any usage counters (see epilogue of allocate_inner()). @@ -314,7 +313,7 @@ MetaBlock MetaspaceArena::allocate_inner(size_t word_size, MetaBlock& wastage) { // chunk. if (!current_chunk_too_small) { if (!current_chunk()->ensure_committed_additional(word_size_plus_alignment)) { - UL2(info, "commit failure (requested size: " SIZE_FORMAT ")", word_size_plus_alignment); + UL2(info, "commit failure (requested size: %zu)", word_size_plus_alignment); commit_failure = true; } } @@ -339,7 +338,7 @@ MetaBlock MetaspaceArena::allocate_inner(size_t word_size, MetaBlock& wastage) { Metachunk* new_chunk = allocate_new_chunk(word_size); if (new_chunk != nullptr) { - UL2(debug, "allocated new chunk " METACHUNK_FORMAT " for requested word size " SIZE_FORMAT ".", + UL2(debug, "allocated new chunk " METACHUNK_FORMAT " for requested word size %zu.", METACHUNK_FORMAT_ARGS(new_chunk), word_size); assert(new_chunk->free_below_committed_words() >= word_size, "Sanity"); @@ -359,7 +358,7 @@ MetaBlock MetaspaceArena::allocate_inner(size_t word_size, MetaBlock& wastage) { assert(p != nullptr, "Allocation from chunk failed."); result = MetaBlock(p, word_size); } else { - UL2(info, "failed to allocate new chunk for requested word size " SIZE_FORMAT ".", word_size); + UL2(info, "failed to allocate new chunk for requested word size %zu.", word_size); } } @@ -407,7 +406,7 @@ void MetaspaceArena::deallocate(MetaBlock block) { #else add_allocation_to_fbl(block); #endif - UL2(trace, "added to fbl: " METABLOCKFORMAT ", (now: %d, " SIZE_FORMAT ").", + UL2(trace, "added to fbl: " METABLOCKFORMAT ", (now: %d, %zu).", METABLOCKFORMATARGS(block), _fbl->count(), _fbl->total_size()); SOMETIMES(verify();) } @@ -482,7 +481,7 @@ bool MetaspaceArena::contains(MetaBlock bl) const { #endif // ASSERT void MetaspaceArena::print_on(outputStream* st) const { - st->print_cr("sm %s: %d chunks, total word size: " SIZE_FORMAT ", committed word size: " SIZE_FORMAT, _name, + st->print_cr("sm %s: %d chunks, total word size: %zu, committed word size: %zu", _name, _chunks.count(), _chunks.calc_word_size(), _chunks.calc_committed_word_size()); _chunks.print_on(st); st->cr(); diff --git a/src/hotspot/share/memory/metaspace/metaspaceArenaGrowthPolicy.cpp b/src/hotspot/share/memory/metaspace/metaspaceArenaGrowthPolicy.cpp index 0698c1509cf38..b16f2d216103c 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceArenaGrowthPolicy.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceArenaGrowthPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceCommon.cpp b/src/hotspot/share/memory/metaspace/metaspaceCommon.cpp index aec656201fe81..947b4843436fe 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceCommon.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceCommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/freeBlocks.hpp" #include "memory/metaspace/metaspaceCommon.hpp" #include "memory/metaspace/metaspaceSettings.hpp" @@ -98,9 +97,9 @@ void print_human_readable_size(outputStream* st, size_t byte_size, size_t scale, if (width == -1) { if (scale == 1) { - st->print(SIZE_FORMAT " bytes", byte_size); + st->print("%zu bytes", byte_size); } else if (scale == BytesPerWord) { - st->print(SIZE_FORMAT " words", byte_size / BytesPerWord); + st->print("%zu words", byte_size / BytesPerWord); } else { const char* display_unit = display_unit_for_scale(scale); float display_value = (float) byte_size / (float)scale; @@ -162,9 +161,9 @@ const char* classes_plural(uintx num) { } void print_number_of_classes(outputStream* out, uintx classes, uintx classes_shared) { - out->print(UINTX_FORMAT " %s", classes, classes_plural(classes)); + out->print("%zu %s", classes, classes_plural(classes)); if (classes_shared > 0) { - out->print(" (" UINTX_FORMAT " shared)", classes_shared); + out->print(" (%zu shared)", classes_shared); } } diff --git a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp index d296ffd6cd7f0..e9f51d05aa5cb 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -80,8 +80,8 @@ void print_percentage(outputStream* st, size_t total, size_t part); #ifdef ASSERT #define assert_is_aligned(value, alignment) \ assert(is_aligned((value), (alignment)), \ - SIZE_FORMAT_X " is not aligned to " \ - SIZE_FORMAT_X, (size_t)(uintptr_t)value, (size_t)(alignment)) + "0x%zx is not aligned to 0x%zx", \ + (size_t)(uintptr_t)value, (size_t)(alignment)) #define assert_is_aligned_metaspace_pointer(p) \ assert_is_aligned((p), metaspace::AllocationAlignmentByteSize) #else diff --git a/src/hotspot/share/memory/metaspace/metaspaceContext.cpp b/src/hotspot/share/memory/metaspace/metaspaceContext.cpp index b43f4cd3b15b2..b38e32e23f63a 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceContext.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/chunkManager.hpp" #include "memory/metaspace/commitLimiter.hpp" #include "memory/metaspace/metaspaceContext.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceContext.hpp b/src/hotspot/share/memory/metaspace/metaspaceContext.hpp index c773c6385b3ec..6601810ce8d7f 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceContext.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceContext.hpp @@ -28,10 +28,10 @@ #include "memory/allocation.hpp" #include "memory/metaspace/counters.hpp" -#include "memory/virtualspace.hpp" #include "utilities/debug.hpp" class outputStream; +class ReservedSpace; namespace metaspace { diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp index 32fee96ad7d09..0ab83b44a7627 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "memory/metaspace/metaspaceDCmd.hpp" #include "memory/metaspace/metaspaceReporter.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp b/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp index cbd2400444ff0..3cff2a50d033f 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" @@ -218,7 +217,7 @@ void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags) { uintx num_loaders = cl._num_loaders_by_spacetype[space_type]; uintx num_classes = cl._num_classes_by_spacetype[space_type]; - out->print("%s - " UINTX_FORMAT " %s", + out->print("%s - %zu %s", describe_spacetype((Metaspace::MetaspaceType)space_type), num_loaders, loaders_plural(num_loaders)); if (num_classes > 0) { @@ -239,7 +238,7 @@ void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags) out->cr(); { uintx num_loaders = cl._num_loaders; - out->print("Total Usage - " UINTX_FORMAT " %s, ", + out->print("Total Usage - %zu %s, ", num_loaders, loaders_plural(num_loaders)); print_number_of_classes(out, cl._num_classes, cl._num_classes_shared); out->print(":"); @@ -360,7 +359,7 @@ void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags) cl._stats_total._arena_stats_class._free_blocks_word_size; out->print("Deallocated from chunks in use: "); print_scaled_words_and_percentage(out, free_blocks_cap_words, committed_words, scale, 6); - out->print(" (" UINTX_FORMAT " blocks)", free_blocks_num); + out->print(" (%zu blocks)", free_blocks_num); out->cr(); // Print total waste. diff --git a/src/hotspot/share/memory/metaspace/metaspaceSettings.cpp b/src/hotspot/share/memory/metaspace/metaspaceSettings.cpp index b812341a2da34..23d38e0d77544 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceSettings.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceSettings.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/metaspace/metaspaceSettings.hpp" @@ -49,9 +48,9 @@ void Settings::ergo_initialize() { } void Settings::print_on(outputStream* st) { - st->print_cr(" - commit_granule_bytes: " SIZE_FORMAT ".", commit_granule_bytes()); - st->print_cr(" - commit_granule_words: " SIZE_FORMAT ".", commit_granule_words()); - st->print_cr(" - virtual_space_node_default_size: " SIZE_FORMAT ".", virtual_space_node_default_word_size()); + st->print_cr(" - commit_granule_bytes: %zu.", commit_granule_bytes()); + st->print_cr(" - commit_granule_words: %zu.", commit_granule_words()); + st->print_cr(" - virtual_space_node_default_size: %zu.", virtual_space_node_default_word_size()); st->print_cr(" - enlarge_chunks_in_place: %d.", (int)enlarge_chunks_in_place()); } diff --git a/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp b/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp index 32329831e7cc5..d4cf551d05428 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceStatistics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/metaspaceCommon.hpp" #include "memory/metaspace/metaspaceStatistics.hpp" #include "utilities/debug.hpp" @@ -128,7 +127,7 @@ void InUseChunkStats::print_on(outputStream* st, size_t scale) const { void InUseChunkStats::verify() const { assert(_word_size >= _committed_words && _committed_words == _used_words + _free_words + _waste_words, - "Sanity: cap " SIZE_FORMAT ", committed " SIZE_FORMAT ", used " SIZE_FORMAT ", free " SIZE_FORMAT ", waste " SIZE_FORMAT ".", + "Sanity: cap %zu, committed %zu, used %zu, free %zu, waste %zu.", _word_size, _committed_words, _used_words, _free_words, _waste_words); } #endif @@ -174,13 +173,13 @@ void ArenaStats::print_on(outputStream* st, size_t scale, bool detailed) const } if (_free_blocks_num > 0) { st->cr_indent(); - st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num); + st->print("deallocated: %zu blocks with ", _free_blocks_num); print_scaled_words(st, _free_blocks_word_size, scale); } } else { totals().print_on(st, scale); st->print(", "); - st->print("deallocated: " UINTX_FORMAT " blocks with ", _free_blocks_num); + st->print("deallocated: %zu blocks with ", _free_blocks_num); print_scaled_words(st, _free_blocks_word_size, scale); } } diff --git a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp index 100a009ca8738..8dc16cd177746 100644 --- a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp +++ b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.hpp" #include "memory/classLoaderMetaspace.hpp" @@ -106,7 +105,7 @@ void PrintCLDMetaspaceInfoClosure::do_cld(ClassLoaderData* cld) { // Optionally, print if (_do_print) { - _out->print(UINTX_FORMAT_W(4) ": ", _num_loaders); + _out->print("%4zu: ", _num_loaders); // Print "CLD for [,] instance of " // or "CLD for , loaded by [,] instance of " diff --git a/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp b/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp index ce975d673f1bc..d91ee55ef9738 100644 --- a/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp +++ b/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, SAP and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "memory/metaspace/printMetaspaceInfoKlassClosure.hpp" #include "memory/resourceArea.hpp" #include "oops/klass.hpp" @@ -38,7 +37,7 @@ PrintMetaspaceInfoKlassClosure::PrintMetaspaceInfoKlassClosure(outputStream* out void PrintMetaspaceInfoKlassClosure::do_klass(Klass* k) { _cnt++; _out->cr_indent(); - _out->print(UINTX_FORMAT_W(4) ": ", _cnt); + _out->print("%4zu: ", _cnt); // Print a 's' for shared classes _out->put(k->is_shared() ? 's': ' '); diff --git a/src/hotspot/share/memory/metaspace/rootChunkArea.cpp b/src/hotspot/share/memory/metaspace/rootChunkArea.cpp index 24377ec25ad12..a178e12278819 100644 --- a/src/hotspot/share/memory/metaspace/rootChunkArea.cpp +++ b/src/hotspot/share/memory/metaspace/rootChunkArea.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/allocation.hpp" #include "memory/metaspace/chunkHeaderPool.hpp" diff --git a/src/hotspot/share/memory/metaspace/runningCounters.cpp b/src/hotspot/share/memory/metaspace/runningCounters.cpp index 75fc4b9792c81..db497cf33872a 100644 --- a/src/hotspot/share/memory/metaspace/runningCounters.cpp +++ b/src/hotspot/share/memory/metaspace/runningCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace/chunkManager.hpp" #include "memory/metaspace/metaspaceContext.hpp" #include "memory/metaspace/runningCounters.hpp" diff --git a/src/hotspot/share/memory/metaspace/testHelpers.cpp b/src/hotspot/share/memory/metaspace/testHelpers.cpp index b974f06f2439b..76fa1e36c4523 100644 --- a/src/hotspot/share/memory/metaspace/testHelpers.cpp +++ b/src/hotspot/share/memory/metaspace/testHelpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,7 @@ * */ -#include "precompiled.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspace/chunkManager.hpp" #include "memory/metaspace/metaspaceArena.hpp" #include "memory/metaspace/metaspaceArenaGrowthPolicy.hpp" @@ -77,12 +77,12 @@ MetaspaceTestContext::MetaspaceTestContext(const char* name, size_t commit_limit _commit_limiter(commit_limit == 0 ? max_uintx : commit_limit), // commit_limit == 0 -> no limit _rs() { - assert(is_aligned(reserve_limit, Metaspace::reserve_alignment_words()), "reserve_limit (" SIZE_FORMAT ") " - "not aligned to metaspace reserve alignment (" SIZE_FORMAT ")", + assert(is_aligned(reserve_limit, Metaspace::reserve_alignment_words()), "reserve_limit (%zu) " + "not aligned to metaspace reserve alignment (%zu)", reserve_limit, Metaspace::reserve_alignment_words()); if (reserve_limit > 0) { // have reserve limit -> non-expandable context - _rs = ReservedSpace(reserve_limit * BytesPerWord, Metaspace::reserve_alignment(), os::vm_page_size()); + _rs = MemoryReserver::reserve(reserve_limit * BytesPerWord, Metaspace::reserve_alignment(), os::vm_page_size()); _context = MetaspaceContext::create_nonexpandable_context(name, _rs, &_commit_limiter); } else { // no reserve limit -> expandable vslist @@ -96,7 +96,7 @@ MetaspaceTestContext::~MetaspaceTestContext() { MutexLocker fcl(Metaspace_lock, Mutex::_no_safepoint_check_flag); delete _context; if (_rs.is_reserved()) { - _rs.release(); + MemoryReserver::release(_rs); } } diff --git a/src/hotspot/share/memory/metaspace/testHelpers.hpp b/src/hotspot/share/memory/metaspace/testHelpers.hpp index 65d5ee4751249..ce77b53c24f5e 100644 --- a/src/hotspot/share/memory/metaspace/testHelpers.hpp +++ b/src/hotspot/share/memory/metaspace/testHelpers.hpp @@ -31,7 +31,7 @@ #include "memory/metaspace/commitLimiter.hpp" #include "memory/metaspace/counters.hpp" #include "memory/metaspace/metaspaceContext.hpp" -#include "memory/virtualspace.hpp" +#include "memory/reservedSpace.hpp" #include "utilities/globalDefinitions.hpp" // This is just convenience classes for metaspace-related tests diff --git a/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp b/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp index 32ceeb45c4fb5..64a17fcbfa9de 100644 --- a/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp +++ b/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/metaspace.hpp" #include "memory/metaspace/chunkManager.hpp" @@ -150,7 +149,7 @@ void VirtualSpaceList::print_on(outputStream* st) const { vsn = vsn->next(); n++; } - st->print_cr("- total %d nodes, " SIZE_FORMAT " reserved words, " SIZE_FORMAT " committed words.", + st->print_cr("- total %d nodes, %zu reserved words, %zu committed words.", n, reserved_words(), committed_words()); } diff --git a/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp b/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp index 83a591e4cad8a..500649dc92665 100644 --- a/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp +++ b/src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,9 +23,9 @@ * */ -#include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" #include "logging/log.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metaspace.hpp" #include "memory/metaspace/chunkHeaderPool.hpp" #include "memory/metaspace/chunklevel.hpp" @@ -64,7 +64,7 @@ static void check_pointer_is_aligned_to_commit_granule(const MetaWord* p) { } static void check_word_size_is_aligned_to_commit_granule(size_t word_size) { assert(is_aligned(word_size, Settings::commit_granule_words()), - "Not aligned to commit granule size: " SIZE_FORMAT ".", word_size); + "Not aligned to commit granule size: %zu.", word_size); } #endif @@ -94,7 +94,7 @@ bool VirtualSpaceNode::commit_range(MetaWord* p, size_t word_size) { // were we to commit the given address range completely. const size_t commit_increase_words = word_size - committed_words_in_range; - UL2(debug, "committing range " PTR_FORMAT ".." PTR_FORMAT "(" SIZE_FORMAT " words)", + UL2(debug, "committing range " PTR_FORMAT ".." PTR_FORMAT "(%zu words)", p2i(p), p2i(p + word_size), word_size); if (commit_increase_words == 0) { @@ -117,7 +117,7 @@ bool VirtualSpaceNode::commit_range(MetaWord* p, size_t word_size) { os::pretouch_memory(p, p + word_size); } - UL2(debug, "... committed " SIZE_FORMAT " additional words.", commit_increase_words); + UL2(debug, "... committed %zu additional words.", commit_increase_words); // ... tell commit limiter... _commit_limiter->increase_committed(commit_increase_words); @@ -179,7 +179,7 @@ void VirtualSpaceNode::uncommit_range(MetaWord* p, size_t word_size) { const size_t committed_words_in_range = _commit_mask.get_committed_size_in_range(p, word_size); DEBUG_ONLY(check_word_size_is_aligned_to_commit_granule(committed_words_in_range);) - UL2(debug, "uncommitting range " PTR_FORMAT ".." PTR_FORMAT "(" SIZE_FORMAT " words)", + UL2(debug, "uncommitting range " PTR_FORMAT ".." PTR_FORMAT "(%zu words)", p2i(p), p2i(p + word_size), word_size); if (committed_words_in_range == 0) { @@ -193,7 +193,7 @@ void VirtualSpaceNode::uncommit_range(MetaWord* p, size_t word_size) { fatal("Failed to uncommit metaspace."); } - UL2(debug, "... uncommitted " SIZE_FORMAT " words.", committed_words_in_range); + UL2(debug, "... uncommitted %zu words.", committed_words_in_range); // ... tell commit limiter... _commit_limiter->decrease_committed(committed_words_in_range); @@ -230,7 +230,7 @@ VirtualSpaceNode::VirtualSpaceNode(ReservedSpace rs, bool owns_rs, CommitLimiter _total_reserved_words_counter(reserve_counter), _total_committed_words_counter(commit_counter) { - UL2(debug, "born (word_size " SIZE_FORMAT ").", _word_size); + UL2(debug, "born (word_size %zu).", _word_size); // Update reserved counter in vslist _total_reserved_words_counter->increment_by(_word_size); @@ -253,9 +253,10 @@ VirtualSpaceNode* VirtualSpaceNode::create_node(size_t word_size, SizeCounter* commit_words_counter) { DEBUG_ONLY(assert_is_aligned(word_size, chunklevel::MAX_CHUNK_WORD_SIZE);) - ReservedSpace rs(word_size * BytesPerWord, - Settings::virtual_space_node_reserve_alignment_words() * BytesPerWord, - os::vm_page_size()); + + ReservedSpace rs = MemoryReserver::reserve(word_size * BytesPerWord, + Settings::virtual_space_node_reserve_alignment_words() * BytesPerWord, + os::vm_page_size()); if (!rs.is_reserved()) { vm_exit_out_of_memory(word_size * BytesPerWord, OOM_MMAP_ERROR, "Failed to reserve memory for metaspace"); } @@ -286,7 +287,9 @@ VirtualSpaceNode::~VirtualSpaceNode() { UL(debug, ": dies."); if (_owns_rs) { - _rs.release(); + if (_rs.is_reserved()) { + MemoryReserver::release(_rs); + } } // Update counters in vslist diff --git a/src/hotspot/share/memory/metaspace/virtualSpaceNode.hpp b/src/hotspot/share/memory/metaspace/virtualSpaceNode.hpp index ab99185371215..2ab8f840c3ae4 100644 --- a/src/hotspot/share/memory/metaspace/virtualSpaceNode.hpp +++ b/src/hotspot/share/memory/metaspace/virtualSpaceNode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,7 +32,7 @@ #include "memory/metaspace/counters.hpp" #include "memory/metaspace/metaspaceSettings.hpp" #include "memory/metaspace/rootChunkArea.hpp" -#include "memory/virtualspace.hpp" +#include "memory/reservedSpace.hpp" #include "utilities/bitMap.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/memory/metaspaceClosure.cpp b/src/hotspot/share/memory/metaspaceClosure.cpp index 50262f5f469cf..46e80ec3a1f5e 100644 --- a/src/hotspot/share/memory/metaspaceClosure.cpp +++ b/src/hotspot/share/memory/metaspaceClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspaceClosure.hpp" void MetaspaceClosure::push_impl(MetaspaceClosure::Ref* ref) { diff --git a/src/hotspot/share/memory/metaspaceCounters.cpp b/src/hotspot/share/memory/metaspaceCounters.cpp index 818172b968458..b57373516f9a5 100644 --- a/src/hotspot/share/memory/metaspaceCounters.cpp +++ b/src/hotspot/share/memory/metaspaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceCounters.hpp" #include "memory/metaspaceStats.hpp" diff --git a/src/hotspot/share/memory/metaspaceCriticalAllocation.cpp b/src/hotspot/share/memory/metaspaceCriticalAllocation.cpp index a25c4c68f1023..b5eff08e740e7 100644 --- a/src/hotspot/share/memory/metaspaceCriticalAllocation.cpp +++ b/src/hotspot/share/memory/metaspaceCriticalAllocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "gc/shared/collectedHeap.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/memory/metaspaceTracer.cpp b/src/hotspot/share/memory/metaspaceTracer.cpp index 5899a2140fe29..05dc01c280b0e 100644 --- a/src/hotspot/share/memory/metaspaceTracer.cpp +++ b/src/hotspot/share/memory/metaspaceTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "jfr/jfrEvents.hpp" #include "memory/metaspaceTracer.hpp" diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp index 440b93a2a4688..83140aa44f5b2 100644 --- a/src/hotspot/share/memory/oopFactory.cpp +++ b/src/hotspot/share/memory/oopFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ServiceThread.java b/src/hotspot/share/memory/reservedSpace.cpp similarity index 67% rename from src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ServiceThread.java rename to src/hotspot/share/memory/reservedSpace.cpp index d4e28404176d4..712eceac772ab 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ServiceThread.java +++ b/src/hotspot/share/memory/reservedSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,20 +22,15 @@ * */ -package sun.jvm.hotspot.runtime; - -import java.io.*; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.types.*; - -public class ServiceThread extends JavaThread { - public ServiceThread(Address addr) { - super(addr); - } - - public boolean isJavaThread() { return false; } - public boolean isHiddenFromExternalView() { return true; } - public boolean isServiceThread() { return true; } +#include "memory/reservedSpace.hpp" +#include "runtime/os.hpp" +#include "utilities/align.hpp" +#ifdef ASSERT +void ReservedSpace::sanity_checks() { + assert(is_aligned(_base, os::vm_allocation_granularity()), "Unaligned base"); + assert(is_aligned(_base, _alignment), "Unaligned base"); + assert(is_aligned(_size, os::vm_page_size()), "Unaligned size"); + assert(os::page_sizes().contains(_page_size), "Invalid pagesize"); } +#endif diff --git a/src/hotspot/share/memory/reservedSpace.hpp b/src/hotspot/share/memory/reservedSpace.hpp new file mode 100644 index 0000000000000..1b466a9858340 --- /dev/null +++ b/src/hotspot/share/memory/reservedSpace.hpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_MEMORY_RESERVEDSPACE_HPP +#define SHARE_MEMORY_RESERVEDSPACE_HPP + +#include "utilities/align.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" + +// ReservedSpace is a data structure for describing a reserved contiguous address range. + +class ReservedSpace { + char* _base; + size_t _size; + size_t _alignment; + size_t _page_size; + bool _executable; + bool _special; + + void sanity_checks() NOT_DEBUG_RETURN; + +public: + // Constructor for non-reserved memory. + ReservedSpace() + : _base(nullptr), + _size(0), + _alignment(0), + _page_size(0), + _executable(false), + _special(false) {} + + // Main constructor + ReservedSpace(char* base, + size_t size, + size_t alignment, + size_t page_size, + bool executable, + bool special) + : _base(base), + _size(size), + _alignment(alignment), + _page_size(page_size), + _executable(executable), + _special(special) { + sanity_checks(); + } + + bool is_reserved() const { + return _base != nullptr; + } + + char* base() const { + return _base; + } + + size_t size() const { + return _size; + } + + char* end() const { + return _base + _size; + } + + size_t alignment() const { + return _alignment; + } + + size_t page_size() const { + return _page_size; + } + + bool executable() const { + return _executable; + } + + bool special() const { + return _special; + } + + ReservedSpace partition(size_t offset, size_t partition_size, size_t alignment) const { + assert(offset + partition_size <= size(), "partition failed"); + + char* const partition_base = base() + offset; + assert(is_aligned(partition_base, alignment), "partition base must be aligned"); + + return ReservedSpace(partition_base, + partition_size, + alignment, + _page_size, + _executable, + _special); + } + + ReservedSpace partition(size_t offset, size_t partition_size) const { + return partition(offset, partition_size, _alignment); + } + + ReservedSpace first_part(size_t split_offset, size_t alignment) const { + return partition(0, split_offset, alignment); + } + + ReservedSpace first_part(size_t split_offset) const { + return first_part(split_offset, _alignment); + } + + ReservedSpace last_part (size_t split_offset, size_t alignment) const { + return partition(split_offset, _size - split_offset, alignment); + } + + ReservedSpace last_part (size_t split_offset) const { + return last_part(split_offset, _alignment); + } +}; + +// Class encapsulating behavior specific to memory reserved for the Java heap. +class ReservedHeapSpace : public ReservedSpace { +private: + const size_t _noaccess_prefix; + +public: + // Constructor for non-reserved memory. + ReservedHeapSpace() + : ReservedSpace(), + _noaccess_prefix() {} + + ReservedHeapSpace(const ReservedSpace& reserved, size_t noaccess_prefix) + : ReservedSpace(reserved), + _noaccess_prefix(noaccess_prefix) {} + + size_t noaccess_prefix() const { return _noaccess_prefix; } + + // Returns the base to be used for compression, i.e. so that null can be + // encoded safely and implicit null checks can work. + char* compressed_oop_base() const { return base() - _noaccess_prefix; } +}; + +#endif // SHARE_MEMORY_RESERVEDSPACE_HPP diff --git a/src/hotspot/share/memory/resourceArea.cpp b/src/hotspot/share/memory/resourceArea.cpp index d5a7513ba19d2..7b0de1fd71708 100644 --- a/src/hotspot/share/memory/resourceArea.cpp +++ b/src/hotspot/share/memory/resourceArea.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.inline.hpp" #include "nmt/memTracker.hpp" diff --git a/src/hotspot/share/memory/resourceArea.hpp b/src/hotspot/share/memory/resourceArea.hpp index b9a1904b5078c..29dea9ad2f466 100644 --- a/src/hotspot/share/memory/resourceArea.hpp +++ b/src/hotspot/share/memory/resourceArea.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ class ResourceArea: public Arena { // Reset size before deleting chunks. Otherwise, the total // size could exceed the total chunk size. assert(size_in_bytes() > state._size_in_bytes, - "size: " SIZE_FORMAT ", saved size: " SIZE_FORMAT, + "size: %zu, saved size: %zu", size_in_bytes(), state._size_in_bytes); set_size_in_bytes(state._size_in_bytes); Chunk::next_chop(state._chunk); diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index ad4dd045bcb58..3097ad1be1005 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" #include "cds/dynamicArchive.hpp" @@ -50,6 +49,7 @@ #include "gc/shared/tlab_globals.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" +#include "memory/memoryReserver.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/metaspaceCounters.hpp" @@ -370,7 +370,7 @@ void Universe::serialize(SerializeClosure* f) { void Universe::check_alignment(uintx size, uintx alignment, const char* name) { if (size < alignment || size % alignment != 0) { vm_exit_during_initialization( - err_msg("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment)); + err_msg("Size of %s (%zu bytes) must be aligned to %zu bytes", name, size, alignment)); } } @@ -939,7 +939,7 @@ void Universe::initialize_tlab() { ReservedHeapSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { assert(alignment <= Arguments::conservative_max_heap_alignment(), - "actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT, + "actual alignment %zu must be within maximum heap alignment %zu", alignment, Arguments::conservative_max_heap_alignment()); size_t total_reserved = align_up(heap_size, alignment); @@ -956,33 +956,36 @@ ReservedHeapSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { } // Now create the space. - ReservedHeapSpace total_rs(total_reserved, alignment, page_size, AllocateHeapAt); + ReservedHeapSpace rhs = HeapReserver::reserve(total_reserved, alignment, page_size, AllocateHeapAt); - if (total_rs.is_reserved()) { - assert((total_reserved == total_rs.size()) && ((uintptr_t)total_rs.base() % alignment == 0), - "must be exactly of required size and alignment"); - // We are good. + if (!rhs.is_reserved()) { + vm_exit_during_initialization( + err_msg("Could not reserve enough space for %zu KB object heap", + total_reserved/K)); + } - if (AllocateHeapAt != nullptr) { - log_info(gc,heap)("Successfully allocated Java heap at location %s", AllocateHeapAt); - } + assert(total_reserved == rhs.size(), "must be exactly of required size"); + assert(is_aligned(rhs.base(),alignment),"must be exactly of required alignment"); - if (UseCompressedOops) { - CompressedOops::initialize(total_rs); - } + assert(markWord::encode_pointer_as_mark(rhs.base()).decode_pointer() == rhs.base(), + "area must be distinguishable from marks for mark-sweep"); + assert(markWord::encode_pointer_as_mark(&rhs.base()[rhs.size()]).decode_pointer() == + &rhs.base()[rhs.size()], + "area must be distinguishable from marks for mark-sweep"); + + // We are good. - Universe::calculate_verify_data((HeapWord*)total_rs.base(), (HeapWord*)total_rs.end()); + if (AllocateHeapAt != nullptr) { + log_info(gc,heap)("Successfully allocated Java heap at location %s", AllocateHeapAt); + } - return total_rs; + if (UseCompressedOops) { + CompressedOops::initialize(rhs); } - vm_exit_during_initialization( - err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", - total_reserved/K)); + Universe::calculate_verify_data((HeapWord*)rhs.base(), (HeapWord*)rhs.end()); - // satisfy compiler - ShouldNotReachHere(); - return ReservedHeapSpace(0, 0, os::vm_page_size()); + return rhs; } OopStorage* Universe::vm_weak() { diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp index 0a3b9eaae01eb..69f8642d6dafe 100644 --- a/src/hotspot/share/memory/universe.hpp +++ b/src/hotspot/share/memory/universe.hpp @@ -26,6 +26,7 @@ #define SHARE_MEMORY_UNIVERSE_HPP #include "gc/shared/verifyOption.hpp" +#include "memory/reservedSpace.hpp" #include "oops/array.hpp" #include "oops/oopHandle.hpp" #include "runtime/handles.hpp" @@ -42,7 +43,6 @@ class CollectedHeap; class DeferredObjAllocEvent; class OopStorage; -class ReservedHeapSpace; class SerializeClosure; class Universe: AllStatic { @@ -51,7 +51,6 @@ class Universe: AllStatic { friend class oopDesc; friend class ClassLoader; friend class SystemDictionary; - friend class ReservedHeapSpace; friend class VMStructs; friend class VM_PopulateDumpSharedSpace; friend class Metaspace; diff --git a/src/hotspot/share/memory/virtualspace.cpp b/src/hotspot/share/memory/virtualspace.cpp index 69b39fcbdeb82..2ea90a6c9ddda 100644 --- a/src/hotspot/share/memory/virtualspace.cpp +++ b/src/hotspot/share/memory/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,649 +22,13 @@ * */ -#include "precompiled.hpp" -#include "logging/log.hpp" -#include "memory/resourceArea.hpp" +#include "gc/shared/gc_globals.hpp" +#include "memory/reservedSpace.hpp" #include "memory/virtualspace.hpp" -#include "nmt/memTracker.hpp" -#include "oops/compressedKlass.hpp" -#include "oops/compressedOops.hpp" -#include "oops/markWord.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/globals_extension.hpp" -#include "runtime/java.hpp" #include "runtime/os.hpp" #include "utilities/align.hpp" -#include "utilities/formatBuffer.hpp" -#include "utilities/powerOfTwo.hpp" - -// ReservedSpace - -// Dummy constructor -ReservedSpace::ReservedSpace() : _base(nullptr), _size(0), _noaccess_prefix(0), - _alignment(0), _special(false), _fd_for_heap(-1), _executable(false) { -} - -ReservedSpace::ReservedSpace(size_t size, MemTag mem_tag) : _fd_for_heap(-1) { - // Want to use large pages where possible. If the size is - // not large page aligned the mapping will be a mix of - // large and normal pages. - size_t page_size = os::page_size_for_region_unaligned(size, 1); - size_t alignment = os::vm_allocation_granularity(); - initialize(size, alignment, page_size, nullptr, false, mem_tag); -} - -ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _fd_for_heap(-1) { - // When a page size is given we don't want to mix large - // and normal pages. If the size is not a multiple of the - // page size it will be aligned up to achieve this. - size_t alignment = os::vm_allocation_granularity(); - if (preferred_page_size != os::vm_page_size()) { - alignment = MAX2(preferred_page_size, alignment); - size = align_up(size, alignment); - } - initialize(size, alignment, preferred_page_size, nullptr, false); -} - -ReservedSpace::ReservedSpace(size_t size, - size_t alignment, - size_t page_size, - char* requested_address) : _fd_for_heap(-1) { - initialize(size, alignment, page_size, requested_address, false); -} - -ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, size_t page_size, - bool special, bool executable) : _fd_for_heap(-1) { - assert((size % os::vm_allocation_granularity()) == 0, - "size not allocation aligned"); - initialize_members(base, size, alignment, page_size, special, executable); -} - -// Helper method -static char* attempt_map_or_reserve_memory_at(char* base, size_t size, int fd, bool executable, MemTag mem_tag) { - if (fd != -1) { - return os::attempt_map_memory_to_file_at(base, size, fd); - } - return os::attempt_reserve_memory_at(base, size, executable, mem_tag); -} - -// Helper method -static char* map_or_reserve_memory(size_t size, int fd, bool executable, MemTag mem_tag) { - if (fd != -1) { - return os::map_memory_to_file(size, fd); - } - return os::reserve_memory(size, executable, mem_tag); -} - -// Helper method -static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fd, bool executable) { - if (fd != -1) { - return os::map_memory_to_file_aligned(size, alignment, fd); - } - return os::reserve_memory_aligned(size, alignment, executable); -} - -// Helper method -static void unmap_or_release_memory(char* base, size_t size, bool is_file_mapped) { - if (is_file_mapped) { - if (!os::unmap_memory(base, size)) { - fatal("os::unmap_memory failed"); - } - } else if (!os::release_memory(base, size)) { - fatal("os::release_memory failed"); - } -} - -// Helper method -static bool failed_to_reserve_as_requested(char* base, char* requested_address) { - if (base == requested_address || requested_address == nullptr) { - return false; // did not fail - } - - if (base != nullptr) { - // Different reserve address may be acceptable in other cases - // but for compressed oops heap should be at requested address. - assert(UseCompressedOops, "currently requested address used only for compressed oops"); - log_debug(gc, heap, coops)("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address)); - } - return true; -} - -static bool use_explicit_large_pages(size_t page_size) { - return !os::can_commit_large_page_memory() && - page_size != os::vm_page_size(); -} - -static bool large_pages_requested() { - return UseLargePages && - (!FLAG_IS_DEFAULT(UseLargePages) || !FLAG_IS_DEFAULT(LargePageSizeInBytes)); -} - -static void log_on_large_pages_failure(char* req_addr, size_t bytes) { - if (large_pages_requested()) { - // Compressed oops logging. - log_debug(gc, heap, coops)("Reserve regular memory without large pages"); - // JVM style warning that we did not succeed in using large pages. - char msg[128]; - jio_snprintf(msg, sizeof(msg), "Failed to reserve and commit memory using large pages. " - "req_addr: " PTR_FORMAT " bytes: " SIZE_FORMAT, - req_addr, bytes); - warning("%s", msg); - } -} - -static char* reserve_memory(char* requested_address, const size_t size, - const size_t alignment, int fd, bool exec, MemTag mem_tag) { - char* base; - // If the memory was requested at a particular address, use - // os::attempt_reserve_memory_at() to avoid mapping over something - // important. If the reservation fails, return null. - if (requested_address != nullptr) { - assert(is_aligned(requested_address, alignment), - "Requested address " PTR_FORMAT " must be aligned to " SIZE_FORMAT, - p2i(requested_address), alignment); - base = attempt_map_or_reserve_memory_at(requested_address, size, fd, exec, mem_tag); - } else { - // Optimistically assume that the OS returns an aligned base pointer. - // When reserving a large address range, most OSes seem to align to at - // least 64K. - base = map_or_reserve_memory(size, fd, exec, mem_tag); - // Check alignment constraints. This is only needed when there is - // no requested address. - if (!is_aligned(base, alignment)) { - // Base not aligned, retry. - unmap_or_release_memory(base, size, fd != -1 /*is_file_mapped*/); - // Map using the requested alignment. - base = map_or_reserve_memory_aligned(size, alignment, fd, exec); - } - } - - return base; -} - -static char* reserve_memory_special(char* requested_address, const size_t size, - const size_t alignment, const size_t page_size, bool exec) { - - log_trace(pagesize)("Attempt special mapping: size: " SIZE_FORMAT "%s, " - "alignment: " SIZE_FORMAT "%s", - byte_size_in_exact_unit(size), exact_unit_for_byte_size(size), - byte_size_in_exact_unit(alignment), exact_unit_for_byte_size(alignment)); - - char* base = os::reserve_memory_special(size, alignment, page_size, requested_address, exec); - if (base != nullptr) { - // Check alignment constraints. - assert(is_aligned(base, alignment), - "reserve_memory_special() returned an unaligned address, base: " PTR_FORMAT - " alignment: " SIZE_FORMAT_X, - p2i(base), alignment); - } - return base; -} - -void ReservedSpace::clear_members() { - initialize_members(nullptr, 0, 0, 0, false, false); -} - -void ReservedSpace::initialize_members(char* base, size_t size, size_t alignment, - size_t page_size, bool special, bool executable) { - _base = base; - _size = size; - _alignment = alignment; - _page_size = page_size; - _special = special; - _executable = executable; - _noaccess_prefix = 0; -} - -void ReservedSpace::reserve(size_t size, - size_t alignment, - size_t page_size, - char* requested_address, - bool executable, - MemTag mem_tag) { - assert(is_aligned(size, alignment), "Size must be aligned to the requested alignment"); - - // There are basically three different cases that we need to handle below: - // 1. Mapping backed by a file - // 2. Mapping backed by explicit large pages - // 3. Mapping backed by normal pages or transparent huge pages - // The first two have restrictions that requires the whole mapping to be - // committed up front. To record this the ReservedSpace is marked 'special'. - - // == Case 1 == - if (_fd_for_heap != -1) { - // When there is a backing file directory for this space then whether - // large pages are allocated is up to the filesystem of the backing file. - // So UseLargePages is not taken into account for this reservation. - char* base = reserve_memory(requested_address, size, alignment, _fd_for_heap, executable, mem_tag); - if (base != nullptr) { - initialize_members(base, size, alignment, os::vm_page_size(), true, executable); - } - // Always return, not possible to fall back to reservation not using a file. - return; - } - - // == Case 2 == - if (use_explicit_large_pages(page_size)) { - // System can't commit large pages i.e. use transparent huge pages and - // the caller requested large pages. To satisfy this request we use - // explicit large pages and these have to be committed up front to ensure - // no reservations are lost. - do { - char* base = reserve_memory_special(requested_address, size, alignment, page_size, executable); - if (base != nullptr) { - // Successful reservation using large pages. - initialize_members(base, size, alignment, page_size, true, executable); - return; - } - page_size = os::page_sizes().next_smaller(page_size); - } while (page_size > os::vm_page_size()); - - // Failed to reserve explicit large pages, do proper logging. - log_on_large_pages_failure(requested_address, size); - // Now fall back to normal reservation. - assert(page_size == os::vm_page_size(), "inv"); - } - - // == Case 3 == - char* base = reserve_memory(requested_address, size, alignment, -1, executable, mem_tag); - if (base != nullptr) { - // Successful mapping. - initialize_members(base, size, alignment, page_size, false, executable); - } -} - -void ReservedSpace::initialize(size_t size, - size_t alignment, - size_t page_size, - char* requested_address, - bool executable, - MemTag mem_tag) { - const size_t granularity = os::vm_allocation_granularity(); - assert((size & (granularity - 1)) == 0, - "size not aligned to os::vm_allocation_granularity()"); - assert((alignment & (granularity - 1)) == 0, - "alignment not aligned to os::vm_allocation_granularity()"); - assert(alignment == 0 || is_power_of_2((intptr_t)alignment), - "not a power of 2"); - assert(page_size >= os::vm_page_size(), "Invalid page size"); - assert(is_power_of_2(page_size), "Invalid page size"); - - clear_members(); - - if (size == 0) { - return; - } - - // Adjust alignment to not be 0. - alignment = MAX2(alignment, os::vm_page_size()); - - // Reserve the memory. - reserve(size, alignment, page_size, requested_address, executable, mem_tag); - - // Check that the requested address is used if given. - if (failed_to_reserve_as_requested(_base, requested_address)) { - // OS ignored the requested address, release the reservation. - release(); - return; - } -} - -ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment) { - assert(partition_size <= size(), "partition failed"); - ReservedSpace result(base(), partition_size, alignment, page_size(), special(), executable()); - return result; -} - -ReservedSpace ReservedSpace::last_part(size_t partition_size, size_t alignment) { - assert(partition_size <= size(), "partition failed"); - ReservedSpace result(base() + partition_size, size() - partition_size, - alignment, page_size(), special(), executable()); - return result; -} - -ReservedSpace ReservedSpace::partition(size_t offset, size_t partition_size, size_t alignment) { - assert(offset + partition_size <= size(), "partition failed"); - ReservedSpace result(base() + offset, partition_size, alignment, page_size(), special(), executable()); - return result; -} - -void ReservedSpace::release() { - if (is_reserved()) { - char *real_base = _base - _noaccess_prefix; - const size_t real_size = _size + _noaccess_prefix; - if (special()) { - if (_fd_for_heap != -1) { - os::unmap_memory(real_base, real_size); - } else { - os::release_memory_special(real_base, real_size); - } - } else{ - os::release_memory(real_base, real_size); - } - clear_members(); - } -} - -// Put a ReservedSpace over an existing range -ReservedSpace ReservedSpace::space_for_range(char* base, size_t size, size_t alignment, - size_t page_size, bool special, bool executable) { - assert(is_aligned(base, os::vm_allocation_granularity()), "Unaligned base"); - assert(is_aligned(size, os::vm_page_size()), "Unaligned size"); - assert(os::page_sizes().contains(page_size), "Invalid pagesize"); - ReservedSpace space; - space.initialize_members(base, size, alignment, page_size, special, executable); - return space; -} - -// Compressed oop support is not relevant in 32bit builds. -#ifdef _LP64 - -static size_t noaccess_prefix_size(size_t alignment) { - return lcm(os::vm_page_size(), alignment); -} - -void ReservedHeapSpace::establish_noaccess_prefix() { - assert(_alignment >= os::vm_page_size(), "must be at least page size big"); - _noaccess_prefix = noaccess_prefix_size(_alignment); - - if (base() && base() + _size > (char *)OopEncodingHeapMax) { - if (true - WIN64_ONLY(&& !UseLargePages) - AIX_ONLY(&& (os::Aix::supports_64K_mmap_pages() || os::vm_page_size() == 4*K))) { - // Protect memory at the base of the allocated region. - // If special, the page was committed (only matters on windows) - if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) { - fatal("cannot protect protection page"); - } - log_debug(gc, heap, coops)("Protected page at the reserved heap base: " - PTR_FORMAT " / " INTX_FORMAT " bytes", - p2i(_base), - _noaccess_prefix); - assert(CompressedOops::use_implicit_null_checks() == true, "not initialized?"); - } else { - CompressedOops::set_use_implicit_null_checks(false); - } - } - - _base += _noaccess_prefix; - _size -= _noaccess_prefix; - assert(((uintptr_t)_base % _alignment == 0), "must be exactly of required alignment"); -} - -// Tries to allocate memory of size 'size' at address requested_address with alignment 'alignment'. -// Does not check whether the reserved memory actually is at requested_address, as the memory returned -// might still fulfill the wishes of the caller. -// Assures the memory is aligned to 'alignment'. -// NOTE: If ReservedHeapSpace already points to some reserved memory this is freed, first. -void ReservedHeapSpace::try_reserve_heap(size_t size, - size_t alignment, - size_t page_size, - char* requested_address) { - if (_base != nullptr) { - // We tried before, but we didn't like the address delivered. - release(); - } - - // Try to reserve the memory for the heap. - log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT - " heap of size " SIZE_FORMAT_X, - p2i(requested_address), - size); - - reserve(size, alignment, page_size, requested_address, false, mtJavaHeap); - - // Check alignment constraints. - if (is_reserved() && !is_aligned(_base, _alignment)) { - // Base not aligned, retry. - release(); - } -} - -void ReservedHeapSpace::try_reserve_range(char *highest_start, - char *lowest_start, - size_t attach_point_alignment, - char *aligned_heap_base_min_address, - char *upper_bound, - size_t size, - size_t alignment, - size_t page_size) { - const size_t attach_range = highest_start - lowest_start; - // Cap num_attempts at possible number. - // At least one is possible even for 0 sized attach range. - const uint64_t num_attempts_possible = (attach_range / attach_point_alignment) + 1; - const uint64_t num_attempts_to_try = MIN2((uint64_t)HeapSearchSteps, num_attempts_possible); - - const size_t stepsize = (attach_range == 0) ? // Only one try. - (size_t) highest_start : align_up(attach_range / num_attempts_to_try, attach_point_alignment); - - // Try attach points from top to bottom. - char* attach_point = highest_start; - while (attach_point >= lowest_start && - attach_point <= highest_start && // Avoid wrap around. - ((_base == nullptr) || - (_base < aligned_heap_base_min_address || size > (uintptr_t)(upper_bound - _base)))) { - try_reserve_heap(size, alignment, page_size, attach_point); - attach_point -= stepsize; - } -} - -#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) -#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) -#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) - -// Helper for heap allocation. Returns an array with addresses -// (OS-specific) which are suited for disjoint base mode. Array is -// null terminated. -static char** get_attach_addresses_for_disjoint_mode() { - static uint64_t addresses[] = { - 2 * SIZE_32G, - 3 * SIZE_32G, - 4 * SIZE_32G, - 8 * SIZE_32G, - 10 * SIZE_32G, - 1 * SIZE_64K * SIZE_32G, - 2 * SIZE_64K * SIZE_32G, - 3 * SIZE_64K * SIZE_32G, - 4 * SIZE_64K * SIZE_32G, - 16 * SIZE_64K * SIZE_32G, - 32 * SIZE_64K * SIZE_32G, - 34 * SIZE_64K * SIZE_32G, - 0 - }; - - // Sort out addresses smaller than HeapBaseMinAddress. This assumes - // the array is sorted. - uint i = 0; - while (addresses[i] != 0 && - (addresses[i] < OopEncodingHeapMax || addresses[i] < HeapBaseMinAddress)) { - i++; - } - uint start = i; - - // Avoid more steps than requested. - i = 0; - while (addresses[start+i] != 0) { - if (i == HeapSearchSteps) { - addresses[start+i] = 0; - break; - } - i++; - } - - return (char**) &addresses[start]; -} - -void ReservedHeapSpace::initialize_compressed_heap(const size_t size, size_t alignment, size_t page_size) { - guarantee(size + noaccess_prefix_size(alignment) <= OopEncodingHeapMax, - "can not allocate compressed oop heap for this size"); - guarantee(alignment == MAX2(alignment, os::vm_page_size()), "alignment too small"); - - const size_t granularity = os::vm_allocation_granularity(); - assert((size & (granularity - 1)) == 0, - "size not aligned to os::vm_allocation_granularity()"); - assert((alignment & (granularity - 1)) == 0, - "alignment not aligned to os::vm_allocation_granularity()"); - assert(alignment == 0 || is_power_of_2((intptr_t)alignment), - "not a power of 2"); - - // The necessary attach point alignment for generated wish addresses. - // This is needed to increase the chance of attaching for mmap and shmat. - // AIX is the only platform that uses System V shm for reserving virtual memory. - // In this case, the required alignment of the allocated size (64K) and the alignment - // of possible start points of the memory region (256M) differ. - // This is not reflected by os_allocation_granularity(). - // The logic here is dual to the one in pd_reserve_memory in os_aix.cpp - const size_t os_attach_point_alignment = - AIX_ONLY(os::vm_page_size() == 4*K ? 4*K : 256*M) - NOT_AIX(os::vm_allocation_granularity()); - - const size_t attach_point_alignment = lcm(alignment, os_attach_point_alignment); - - char *aligned_heap_base_min_address = (char *)align_up((void *)HeapBaseMinAddress, alignment); - size_t noaccess_prefix = ((aligned_heap_base_min_address + size) > (char*)OopEncodingHeapMax) ? - noaccess_prefix_size(alignment) : 0; - - // Attempt to alloc at user-given address. - if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) { - try_reserve_heap(size + noaccess_prefix, alignment, page_size, aligned_heap_base_min_address); - if (_base != aligned_heap_base_min_address) { // Enforce this exact address. - release(); - } - } - - // Keep heap at HeapBaseMinAddress. - if (_base == nullptr) { - - // Try to allocate the heap at addresses that allow efficient oop compression. - // Different schemes are tried, in order of decreasing optimization potential. - // - // For this, try_reserve_heap() is called with the desired heap base addresses. - // A call into the os layer to allocate at a given address can return memory - // at a different address than requested. Still, this might be memory at a useful - // address. try_reserve_heap() always returns this allocated memory, as only here - // the criteria for a good heap are checked. - - // Attempt to allocate so that we can run without base and scale (32-Bit unscaled compressed oops). - // Give it several tries from top of range to bottom. - if (aligned_heap_base_min_address + size <= (char *)UnscaledOopHeapMax) { - - // Calc address range within we try to attach (range of possible start addresses). - char* const highest_start = align_down((char *)UnscaledOopHeapMax - size, attach_point_alignment); - char* const lowest_start = align_up(aligned_heap_base_min_address, attach_point_alignment); - try_reserve_range(highest_start, lowest_start, attach_point_alignment, - aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, page_size); - } - - // zerobased: Attempt to allocate in the lower 32G. - char *zerobased_max = (char *)OopEncodingHeapMax; - - // Give it several tries from top of range to bottom. - if (aligned_heap_base_min_address + size <= zerobased_max && // Zerobased theoretical possible. - ((_base == nullptr) || // No previous try succeeded. - (_base + size > zerobased_max))) { // Unscaled delivered an arbitrary address. - - // Calc address range within we try to attach (range of possible start addresses). - char *const highest_start = align_down(zerobased_max - size, attach_point_alignment); - // Need to be careful about size being guaranteed to be less - // than UnscaledOopHeapMax due to type constraints. - char *lowest_start = aligned_heap_base_min_address; - uint64_t unscaled_end = UnscaledOopHeapMax - size; - if (unscaled_end < UnscaledOopHeapMax) { // unscaled_end wrapped if size is large - lowest_start = MAX2(lowest_start, (char*)unscaled_end); - } - lowest_start = align_up(lowest_start, attach_point_alignment); - try_reserve_range(highest_start, lowest_start, attach_point_alignment, - aligned_heap_base_min_address, zerobased_max, size, alignment, page_size); - } - - // Now we go for heaps with base != 0. We need a noaccess prefix to efficiently - // implement null checks. - noaccess_prefix = noaccess_prefix_size(alignment); - - // Try to attach at addresses that are aligned to OopEncodingHeapMax. Disjointbase mode. - char** addresses = get_attach_addresses_for_disjoint_mode(); - int i = 0; - while ((addresses[i] != nullptr) && // End of array not yet reached. - ((_base == nullptr) || // No previous try succeeded. - (_base + size > (char *)OopEncodingHeapMax && // Not zerobased or unscaled address. - !CompressedOops::is_disjoint_heap_base_address((address)_base)))) { // Not disjoint address. - char* const attach_point = addresses[i]; - assert(attach_point >= aligned_heap_base_min_address, "Flag support broken"); - try_reserve_heap(size + noaccess_prefix, alignment, page_size, attach_point); - i++; - } - - // Last, desperate try without any placement. - if (_base == nullptr) { - log_trace(gc, heap, coops)("Trying to allocate at address null heap of size " SIZE_FORMAT_X, size + noaccess_prefix); - initialize(size + noaccess_prefix, alignment, page_size, nullptr, false, mtJavaHeap); - } - } -} - -#endif // _LP64 - -ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, size_t page_size, const char* heap_allocation_directory) : ReservedSpace() { - - if (size == 0) { - return; - } - - if (heap_allocation_directory != nullptr) { - _fd_for_heap = os::create_file_for_heap(heap_allocation_directory); - if (_fd_for_heap == -1) { - vm_exit_during_initialization( - err_msg("Could not create file for Heap at location %s", heap_allocation_directory)); - } - // When there is a backing file directory for this space then whether - // large pages are allocated is up to the filesystem of the backing file. - // If requested, let the user know that explicit large pages can't be used. - if (use_explicit_large_pages(page_size) && large_pages_requested()) { - log_debug(gc, heap)("Cannot allocate explicit large pages for Java Heap when AllocateHeapAt option is set."); - } - } - - // Heap size should be aligned to alignment, too. - guarantee(is_aligned(size, alignment), "set by caller"); - - if (UseCompressedOops) { -#ifdef _LP64 - initialize_compressed_heap(size, alignment, page_size); - if (_size > size) { - // We allocated heap with noaccess prefix. - // It can happen we get a zerobased/unscaled heap with noaccess prefix, - // if we had to try at arbitrary address. - establish_noaccess_prefix(); - } -#else - ShouldNotReachHere(); -#endif // _LP64 - } else { - initialize(size, alignment, page_size, nullptr, false, mtJavaHeap); - } - - assert(markWord::encode_pointer_as_mark(_base).decode_pointer() == _base, - "area must be distinguishable from marks for mark-sweep"); - assert(markWord::encode_pointer_as_mark(&_base[size]).decode_pointer() == &_base[size], - "area must be distinguishable from marks for mark-sweep"); - - if (_fd_for_heap != -1) { - ::close(_fd_for_heap); - } -} - -MemRegion ReservedHeapSpace::region() const { - return MemRegion((HeapWord*)base(), (HeapWord*)end()); -} - -// Reserve space for code segment. Same as Java heap only we mark this as -// executable. -ReservedCodeSpace::ReservedCodeSpace(size_t r_size, - size_t rs_align, - size_t rs_page_size) : ReservedSpace() { - initialize(r_size, rs_align, rs_page_size, /*requested address*/ nullptr, /*executable*/ true, mtCode); -} +#include "utilities/debug.hpp" +#include "utilities/ostream.hpp" // VirtualSpace @@ -693,7 +57,7 @@ bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { } bool VirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t committed_size, size_t max_commit_granularity) { - if(!rs.is_reserved()) return false; // allocation failed. + assert(rs.is_reserved(), "ReservedSpace should have been initialized"); assert(_low_boundary == nullptr, "VirtualSpace already initialized"); assert(max_commit_granularity > 0, "Granularity must be non-zero."); @@ -838,7 +202,7 @@ static bool commit_expanded(char* start, size_t size, size_t alignment, bool pre debug_only(warning( "INFO: os::commit_memory(" PTR_FORMAT ", " PTR_FORMAT - " size=" SIZE_FORMAT ", executable=%d) failed", + " size=%zu, executable=%d) failed", p2i(start), p2i(start + size), size, executable);) return false; @@ -1061,8 +425,8 @@ void VirtualSpace::print_on(outputStream* out) const { out->print ("Virtual space:"); if (special()) out->print(" (pinned in memory)"); out->cr(); - out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); - out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); + out->print_cr(" - committed: %zu", committed_size()); + out->print_cr(" - reserved: %zu", reserved_size()); out->print_cr(" - [low, high]: [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(low()), p2i(high())); out->print_cr(" - [low_b, high_b]: [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(low_boundary()), p2i(high_boundary())); } diff --git a/src/hotspot/share/memory/virtualspace.hpp b/src/hotspot/share/memory/virtualspace.hpp index c78953912b30b..d5abf13b720fd 100644 --- a/src/hotspot/share/memory/virtualspace.hpp +++ b/src/hotspot/share/memory/virtualspace.hpp @@ -25,143 +25,11 @@ #ifndef SHARE_MEMORY_VIRTUALSPACE_HPP #define SHARE_MEMORY_VIRTUALSPACE_HPP -#include "memory/memRegion.hpp" -#include "nmt/memTag.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" class outputStream; - -// ReservedSpace is a data structure for reserving a contiguous address range. - -class ReservedSpace { - friend class VMStructs; - protected: - char* _base; - size_t _size; - size_t _noaccess_prefix; - size_t _alignment; - size_t _page_size; - bool _special; - int _fd_for_heap; - private: - bool _executable; - - // ReservedSpace - ReservedSpace(char* base, size_t size, size_t alignment, - size_t page_size, bool special, bool executable); - protected: - // Helpers to clear and set members during initialization. Two members - // require special treatment: - // * _fd_for_heap - The fd is set once and should not be cleared - // even if the reservation has to be retried. - // * _noaccess_prefix - Used for compressed heaps and updated after - // the reservation is initialized. Always set to - // 0 during initialization. - void clear_members(); - void initialize_members(char* base, size_t size, size_t alignment, - size_t page_size, bool special, bool executable); - - void initialize(size_t size, size_t alignment, size_t page_size, - char* requested_address, bool executable, MemTag mem_tag = mtNone); - - void reserve(size_t size, size_t alignment, size_t page_size, - char* requested_address, bool executable, MemTag mem_tag); - public: - // Constructor - ReservedSpace(); - // Initialize the reserved space with the given size. Depending on the size - // a suitable page size and alignment will be used. - ReservedSpace(size_t size, MemTag mem_tag); - // Initialize the reserved space with the given size. The preferred_page_size - // is used as the minimum page size/alignment. This may waste some space if - // the given size is not aligned to that value, as the reservation will be - // aligned up to the final alignment in this case. - ReservedSpace(size_t size, size_t preferred_page_size); - ReservedSpace(size_t size, size_t alignment, size_t page_size, - char* requested_address = nullptr); - - // Accessors - char* base() const { return _base; } - size_t size() const { return _size; } - char* end() const { return _base + _size; } - size_t alignment() const { return _alignment; } - size_t page_size() const { return _page_size; } - bool special() const { return _special; } - bool executable() const { return _executable; } - size_t noaccess_prefix() const { return _noaccess_prefix; } - bool is_reserved() const { return _base != nullptr; } - void release(); - - // Splitting - // This splits the space into two spaces, the first part of which will be returned. - ReservedSpace first_part(size_t partition_size, size_t alignment); - ReservedSpace last_part (size_t partition_size, size_t alignment); - ReservedSpace partition (size_t offset, size_t partition_size, size_t alignment); - - // These simply call the above using the default alignment. - inline ReservedSpace first_part(size_t partition_size); - inline ReservedSpace last_part (size_t partition_size); - inline ReservedSpace partition (size_t offset, size_t partition_size); - - bool contains(const void* p) const { - return (base() <= ((char*)p)) && (((char*)p) < (base() + size())); - } - - // Put a ReservedSpace over an existing range - static ReservedSpace space_for_range(char* base, size_t size, size_t alignment, - size_t page_size, bool special, bool executable); -}; - -ReservedSpace ReservedSpace::first_part(size_t partition_size) -{ - return first_part(partition_size, alignment()); -} - -ReservedSpace ReservedSpace::last_part(size_t partition_size) -{ - return last_part(partition_size, alignment()); -} - -ReservedSpace ReservedSpace::partition(size_t offset, size_t partition_size) -{ - return partition(offset, partition_size, alignment()); -} - -// Class encapsulating behavior specific of memory space reserved for Java heap. -class ReservedHeapSpace : public ReservedSpace { - private: - - // Compressed oop support is not relevant in 32bit builds. -#ifdef _LP64 - - void try_reserve_heap(size_t size, size_t alignment, size_t page_size, - char *requested_address); - void try_reserve_range(char *highest_start, char *lowest_start, - size_t attach_point_alignment, char *aligned_HBMA, - char *upper_bound, size_t size, size_t alignment, size_t page_size); - void initialize_compressed_heap(const size_t size, size_t alignment, size_t page_size); - // Create protection page at the beginning of the space. - void establish_noaccess_prefix(); - -#endif // _LP64 - - public: - // Constructor. Tries to find a heap that is good for compressed oops. - // heap_allocation_directory is the path to the backing memory for Java heap. When set, Java heap will be allocated - // on the device which is managed by the file system where the directory resides. - ReservedHeapSpace(size_t size, size_t forced_base_alignment, size_t page_size, const char* heap_allocation_directory = nullptr); - // Returns the base to be used for compression, i.e. so that null can be - // encoded safely and implicit null checks can work. - char *compressed_oop_base() const { return _base - _noaccess_prefix; } - MemRegion region() const; -}; - -// Class encapsulating behavior specific memory space for Code -class ReservedCodeSpace : public ReservedSpace { - public: - // Constructor - ReservedCodeSpace(size_t r_size, size_t rs_align, size_t page_size); -}; +class ReservedSpace; // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks. diff --git a/src/hotspot/share/nmt/mallocHeader.cpp b/src/hotspot/share/nmt/mallocHeader.cpp index defe2fc045d41..2b59a2b66480f 100644 --- a/src/hotspot/share/nmt/mallocHeader.cpp +++ b/src/hotspot/share/nmt/mallocHeader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "nmt/mallocHeader.inline.hpp" #include "nmt/mallocSiteTable.hpp" diff --git a/src/hotspot/share/nmt/mallocHeader.hpp b/src/hotspot/share/nmt/mallocHeader.hpp index 6711c2b993e6f..8472b5f8ce888 100644 --- a/src/hotspot/share/nmt/mallocHeader.hpp +++ b/src/hotspot/share/nmt/mallocHeader.hpp @@ -36,7 +36,7 @@ class outputStream; /* * Malloc tracking header. * - * If NMT is active (state >= minimal), we need to track allocations. A simple and cheap way to + * If NMT is active (state >= summary), we need to track allocations. A simple and cheap way to * do this is by using malloc headers. * * The user allocation is preceded by a header and is immediately followed by a (possibly unaligned) diff --git a/src/hotspot/share/nmt/mallocLimit.cpp b/src/hotspot/share/nmt/mallocLimit.cpp index 5e16a406821ea..ed479725cf9e7 100644 --- a/src/hotspot/share/nmt/mallocLimit.cpp +++ b/src/hotspot/share/nmt/mallocLimit.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2023 SAP SE. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "nmt/mallocLimit.hpp" #include "nmt/memTag.hpp" #include "nmt/nmtCommon.hpp" @@ -230,4 +229,3 @@ void MallocLimitHandler::print_on(outputStream* st) { st->print_cr("MallocLimit: unset"); } } - diff --git a/src/hotspot/share/nmt/mallocSiteTable.cpp b/src/hotspot/share/nmt/mallocSiteTable.cpp index 9411f76c491ac..71e75551e2fb2 100644 --- a/src/hotspot/share/nmt/mallocSiteTable.cpp +++ b/src/hotspot/share/nmt/mallocSiteTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "nmt/mallocSiteTable.hpp" @@ -180,7 +179,11 @@ MallocSite* MallocSiteTable::malloc_site(uint32_t marker) { MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key, MemTag mem_tag) { void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT, *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL); - return ::new (p) MallocSiteHashtableEntry(key, mem_tag); + if (p == nullptr) { + return nullptr; + } else { + return ::new (p) MallocSiteHashtableEntry(key, mem_tag); + } } bool MallocSiteTable::walk_malloc_site(MallocSiteWalker* walker) { diff --git a/src/hotspot/share/nmt/mallocTracker.cpp b/src/hotspot/share/nmt/mallocTracker.cpp index 6829db90b4bc1..3c3236d2cbcce 100644 --- a/src/hotspot/share/nmt/mallocTracker.cpp +++ b/src/hotspot/share/nmt/mallocTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023 SAP SE. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * @@ -25,7 +25,6 @@ * */ -#include "precompiled.hpp" #include "jvm_io.h" #include "logging/log.hpp" #include "logging/logStream.hpp" @@ -231,6 +230,10 @@ bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { address addr = (address)p; + if (p2u(addr) < MAX2(os::vm_min_address(), (size_t)16 * M)) { + return false; // bail out + } + // Carefully feel your way upwards and try to find a malloc header. Then check if // we are within the block. // We give preference to found live blocks; but if no live block had been found, @@ -239,13 +242,12 @@ bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { const MallocHeader* likely_live_block = nullptr; { const size_t smallest_possible_alignment = sizeof(void*); - const uint8_t* here = align_down(addr, smallest_possible_alignment); - const uint8_t* const end = here - (0x1000 + sizeof(MallocHeader)); // stop searching after 4k + uintptr_t here = (uintptr_t)align_down(addr, smallest_possible_alignment); + uintptr_t end = MAX2(smallest_possible_alignment, here - (0x1000 + sizeof(MallocHeader))); // stop searching after 4k for (; here >= end; here -= smallest_possible_alignment) { // JDK-8306561: cast to a MallocHeader needs to guarantee it can reside in readable memory - if (!os::is_readable_range(here, here + sizeof(MallocHeader))) { - // Probably OOB, give up - break; + if (!os::is_readable_range((void*)here, (void*)(here + sizeof(MallocHeader)))) { + break; // Probably OOB, give up } const MallocHeader* const candidate = (const MallocHeader*)here; if (!candidate->looks_valid()) { @@ -292,7 +294,7 @@ bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { } else { where = "just outside of"; } - st->print_cr(PTR_FORMAT " %s %s malloced block starting at " PTR_FORMAT ", size " SIZE_FORMAT ", tag %s", + st->print_cr(PTR_FORMAT " %s %s malloced block starting at " PTR_FORMAT ", size %zu, tag %s", p2i(p), where, (block->is_dead() ? "dead" : "live"), p2i(block + 1), // lets print the payload start, not the header diff --git a/src/hotspot/share/nmt/memBaseline.cpp b/src/hotspot/share/nmt/memBaseline.cpp index 6f82b2de9f106..6b18dad21bd66 100644 --- a/src/hotspot/share/nmt/memBaseline.cpp +++ b/src/hotspot/share/nmt/memBaseline.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "memory/allocation.hpp" @@ -141,7 +140,7 @@ void MemBaseline::baseline_summary() { MallocMemorySummary::snapshot(&_malloc_memory_snapshot); VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); { - MemoryFileTracker::Instance::Locker lock; + MemTracker::NmtVirtualMemoryLocker nvml; MemoryFileTracker::Instance::summary_snapshot(&_virtual_memory_snapshot); } diff --git a/src/hotspot/share/nmt/memMapPrinter.cpp b/src/hotspot/share/nmt/memMapPrinter.cpp index 5c164e19b57e3..db67321fb1d45 100644 --- a/src/hotspot/share/nmt/memMapPrinter.cpp +++ b/src/hotspot/share/nmt/memMapPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,8 +23,6 @@ * */ -#include "precompiled.hpp" - #if defined(LINUX) || defined(_WIN64) || defined(__APPLE__) #include "gc/shared/collectedHeap.hpp" @@ -172,7 +170,8 @@ static bool vma_touches_thread_stack(const void* from, const void* to, const Thr // Very rarely however is a VMA backing a thread stack folded together with another adjacent VMA by the // kernel. That can happen, e.g., for non-java threads that don't have guard pages. // Therefore we go for the simplest way here and check for intersection between VMA and thread stack. - return range_intersects(from, to, (const void*)t->stack_end(), (const void*)t->stack_base()); + // Note it is possible to encounter a brand new thread that has not yet initialized its stack fields. + return t->stack_base_or_null() != nullptr && range_intersects(from, to, (const void*)t->stack_end(), (const void*)t->stack_base()); } struct GCThreadClosure : public ThreadClosure { @@ -194,7 +193,7 @@ static void print_thread_details(uintx thread_id, const char* name, outputStream // avoid commas and spaces in output to ease post-processing via awk char tmp[64]; stringStream ss(tmp, sizeof(tmp)); - ss.print(":" UINTX_FORMAT "-%s", (uintx)thread_id, name); + ss.print(":%zu-%s", (uintx)thread_id, name); for (int i = 0; tmp[i] != '\0'; i++) { if (!isalnum(tmp[i])) { tmp[i] = '-'; diff --git a/src/hotspot/share/nmt/memReporter.cpp b/src/hotspot/share/nmt/memReporter.cpp index 6ce6206ebcc2a..38c1ab5a6674d 100644 --- a/src/hotspot/share/nmt/memReporter.cpp +++ b/src/hotspot/share/nmt/memReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,13 +21,13 @@ * questions. * */ -#include "precompiled.hpp" #include "cds/filemap.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceUtils.hpp" #include "nmt/mallocTracker.hpp" #include "nmt/memTag.hpp" #include "nmt/memReporter.hpp" +#include "nmt/memTracker.hpp" #include "nmt/memoryFileTracker.hpp" #include "nmt/threadStackTracker.hpp" #include "nmt/virtualMemoryTracker.hpp" @@ -42,8 +42,8 @@ // Diff two counters, express them as signed, with range checks static ssize_t counter_diff(size_t c1, size_t c2) { - assert(c1 <= SSIZE_MAX, "counter out of range: " SIZE_FORMAT ".", c1); - assert(c2 <= SSIZE_MAX, "counter out of range: " SIZE_FORMAT ".", c2); + assert(c1 <= SSIZE_MAX, "counter out of range: %zu.", c1); + assert(c2 <= SSIZE_MAX, "counter out of range: %zu.", c2); if (c1 > SSIZE_MAX || c2 > SSIZE_MAX) { return 0; } @@ -63,10 +63,10 @@ size_t MemReporterBase::committed_total(const MallocMemory* malloc, const Virtua void MemReporterBase::print_total(size_t reserved, size_t committed, size_t peak) const { const char* scale = current_scale(); - output()->print("reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s", + output()->print("reserved=%zu%s, committed=%zu%s", amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); if (peak != 0) { - output()->print(", peak=" SIZE_FORMAT "%s", amount_in_current_scale(peak), scale); + output()->print(", peak=%zu%s", amount_in_current_scale(peak), scale); } } @@ -79,16 +79,16 @@ void MemReporterBase::print_malloc(const MemoryCounter* c, MemTag mem_tag) const const size_t count = c->count(); if (mem_tag != mtNone) { - out->print("(%s" SIZE_FORMAT "%s type=%s", alloc_type, + out->print("(%s%zu%s type=%s", alloc_type, amount_in_current_scale(amount), scale, NMTUtil::tag_to_name(mem_tag)); } else { - out->print("(%s" SIZE_FORMAT "%s", alloc_type, + out->print("(%s%zu%s", alloc_type, amount_in_current_scale(amount), scale); } // blends out mtChunk count number if (count > 0) { - out->print(" #" SIZE_FORMAT "", count); + out->print(" #%zu", count); } out->print(")"); @@ -98,7 +98,7 @@ void MemReporterBase::print_malloc(const MemoryCounter* c, MemTag mem_tag) const out->print_raw(" (at peak)"); } else if (pk_amount > amount) { size_t pk_count = c->peak_count(); - out->print(" (peak=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", + out->print(" (peak=%zu%s #%zu)", amount_in_current_scale(pk_amount), scale, pk_count); } } @@ -106,12 +106,12 @@ void MemReporterBase::print_malloc(const MemoryCounter* c, MemTag mem_tag) const void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed, size_t peak) const { outputStream* out = output(); const char* scale = current_scale(); - out->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s, ", + out->print("(mmap: reserved=%zu%s, committed=%zu%s, ", amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); if (peak == committed) { out->print_raw("at peak)"); } else { - out->print("peak=" SIZE_FORMAT "%s)", amount_in_current_scale(peak), scale); + out->print("peak=%zu%s)", amount_in_current_scale(peak), scale); } } @@ -122,7 +122,7 @@ void MemReporterBase::print_arena(const MemoryCounter* c) const { const size_t amount = c->size(); const size_t count = c->count(); - out->print("(arena=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", + out->print("(arena=%zu%s #%zu)", amount_in_current_scale(amount), scale, count); size_t pk_amount = c->peak_size(); @@ -130,14 +130,14 @@ void MemReporterBase::print_arena(const MemoryCounter* c) const { out->print_raw(" (at peak)"); } else if (pk_amount > amount) { size_t pk_count = c->peak_count(); - out->print(" (peak=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", + out->print(" (peak=%zu%s #%zu)", amount_in_current_scale(pk_amount), scale, pk_count); } } void MemReporterBase::print_virtual_memory_region(const char* type, address base, size_t size) const { const char* scale = current_scale(); - output()->print("[" PTR_FORMAT " - " PTR_FORMAT "] %s " SIZE_FORMAT "%s", + output()->print("[" PTR_FORMAT " - " PTR_FORMAT "] %s %zu%s", p2i(base), p2i(base + size), type, amount_in_current_scale(size), scale); } @@ -165,7 +165,7 @@ void MemSummaryReporter::report() { print_total(total_reserved_amount, total_committed_amount); out->cr(); INDENT_BY(7, - out->print_cr("malloc: " SIZE_FORMAT "%s #" SIZE_FORMAT ", peak=" SIZE_FORMAT "%s #" SIZE_FORMAT, + out->print_cr("malloc: %zu%s #%zu, peak=%zu%s #%zu", amount_in_current_scale(total_malloced_bytes), current_scale(), _malloc_snapshot->total_count(), amount_in_current_scale(_malloc_snapshot->total_peak()), @@ -224,7 +224,7 @@ void MemSummaryReporter::report_summary_of_type(MemTag mem_tag, #if INCLUDE_CDS if (mem_tag == mtClassShared) { size_t read_only_bytes = FileMapInfo::readonly_total(); - output()->print(", readonly=" SIZE_FORMAT "%s", + output()->print(", readonly=%zu%s", amount_in_current_scale(read_only_bytes), scale); } #endif @@ -234,14 +234,14 @@ void MemSummaryReporter::report_summary_of_type(MemTag mem_tag, if (mem_tag == mtClass) { // report class count - out->print_cr("(classes #" SIZE_FORMAT ")", (_instance_class_count + _array_class_count)); - out->print_cr("( instance classes #" SIZE_FORMAT ", array classes #" SIZE_FORMAT ")", + out->print_cr("(classes #%zu)", (_instance_class_count + _array_class_count)); + out->print_cr("( instance classes #%zu, array classes #%zu)", _instance_class_count, _array_class_count); } else if (mem_tag == mtThread) { const VirtualMemory* thread_stack_usage = _vm_snapshot->by_type(mtThreadStack); // report thread count - out->print_cr("(threads #" SIZE_FORMAT ")", ThreadStackTracker::thread_count()); + out->print_cr("(threads #%zu)", ThreadStackTracker::thread_count()); out->print("(stack: "); print_total(thread_stack_usage->reserved(), thread_stack_usage->committed(), thread_stack_usage->peak_size()); out->print_cr(")"); @@ -265,7 +265,7 @@ void MemSummaryReporter::report_summary_of_type(MemTag mem_tag, if (mem_tag == mtNMT && amount_in_current_scale(_malloc_snapshot->malloc_overhead()) > 0) { - out->print_cr("(tracking overhead=" SIZE_FORMAT "%s)", + out->print_cr("(tracking overhead=%zu%s)", amount_in_current_scale(_malloc_snapshot->malloc_overhead()), scale); } else if (mem_tag == mtClass) { // Metadata information @@ -301,8 +301,8 @@ void MemSummaryReporter::report_metadata(Metaspace::MetadataType type) const { out->print("( "); print_total(stats.reserved(), stats.committed()); out->print_cr(")"); - out->print_cr("( used=" SIZE_FORMAT "%s)", amount_in_current_scale(stats.used()), scale); - out->print_cr("( waste=" SIZE_FORMAT "%s =%2.2f%%)", amount_in_current_scale(waste), + out->print_cr("( used=%zu%s)", amount_in_current_scale(stats.used()), scale); + out->print_cr("( waste=%zu%s =%2.2f%%)", amount_in_current_scale(waste), scale, waste_percentage); } @@ -465,7 +465,7 @@ void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion* void MemDetailReporter::report_memory_file_allocations() { stringStream st; { - MemoryFileTracker::Instance::Locker lock; + MemTracker::NmtVirtualMemoryLocker nvml; MemoryFileTracker::Instance::print_all_reports_on(&st, scale()); } output()->print_raw(st.freeze()); @@ -540,7 +540,7 @@ void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t cur outputStream* out = output(); const char* alloc_tag = (mem_tag == mtThread) ? "" : "malloc="; - out->print("%s" SIZE_FORMAT "%s", alloc_tag, amount_in_current_scale(current_amount), scale); + out->print("%s%zu%s", alloc_tag, amount_in_current_scale(current_amount), scale); // Report type only if it is valid and not under "thread" category if (mem_tag != mtNone && mem_tag != mtThread) { out->print(" type=%s", NMTUtil::tag_to_name(mem_tag)); @@ -551,10 +551,10 @@ void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t cur out->print(" " INT64_PLUS_FORMAT "%s", amount_diff, scale); } if (current_count > 0) { - out->print(" #" SIZE_FORMAT "", current_count); + out->print(" #%zu", current_count); const ssize_t delta_count = counter_diff(current_count, early_count); if (delta_count != 0) { - out->print(" " SSIZE_PLUS_FORMAT, delta_count); + out->print(" %+zd", delta_count); } } } @@ -563,16 +563,16 @@ void MemSummaryDiffReporter::print_arena_diff(size_t current_amount, size_t curr size_t early_amount, size_t early_count) const { const char* scale = current_scale(); outputStream* out = output(); - out->print("arena=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale); + out->print("arena=%zu%s", amount_in_current_scale(current_amount), scale); int64_t amount_diff = diff_in_current_scale(current_amount, early_amount); if (amount_diff != 0) { out->print(" " INT64_PLUS_FORMAT "%s", amount_diff, scale); } - out->print(" #" SIZE_FORMAT "", current_count); + out->print(" #%zu", current_count); const ssize_t delta_count = counter_diff(current_count, early_count); if (delta_count != 0) { - out->print(" " SSIZE_PLUS_FORMAT, delta_count); + out->print(" %+zd", delta_count); } } @@ -580,13 +580,13 @@ void MemSummaryDiffReporter::print_virtual_memory_diff(size_t current_reserved, size_t early_reserved, size_t early_committed) const { const char* scale = current_scale(); outputStream* out = output(); - out->print("reserved=" SIZE_FORMAT "%s", amount_in_current_scale(current_reserved), scale); + out->print("reserved=%zu%s", amount_in_current_scale(current_reserved), scale); int64_t reserved_diff = diff_in_current_scale(current_reserved, early_reserved); if (reserved_diff != 0) { out->print(" " INT64_PLUS_FORMAT "%s", reserved_diff, scale); } - out->print(", committed=" SIZE_FORMAT "%s", amount_in_current_scale(current_committed), scale); + out->print(", committed=%zu%s", amount_in_current_scale(current_committed), scale); int64_t committed_diff = diff_in_current_scale(current_committed, early_committed); if (committed_diff != 0) { out->print(" " INT64_PLUS_FORMAT "%s", committed_diff, scale); @@ -646,34 +646,34 @@ void MemSummaryDiffReporter::diff_summary_of_type(MemTag mem_tag, // detail lines if (mem_tag == mtClass) { // report class count - out->print("(classes #" SIZE_FORMAT, _current_baseline.class_count()); + out->print("(classes #%zu", _current_baseline.class_count()); const ssize_t class_count_diff = counter_diff(_current_baseline.class_count(), _early_baseline.class_count()); if (class_count_diff != 0) { - out->print(" " SSIZE_PLUS_FORMAT, class_count_diff); + out->print(" %+zd", class_count_diff); } out->print_cr(")"); - out->print("( instance classes #" SIZE_FORMAT, _current_baseline.instance_class_count()); + out->print("( instance classes #%zu", _current_baseline.instance_class_count()); const ssize_t instance_class_count_diff = counter_diff(_current_baseline.instance_class_count(), _early_baseline.instance_class_count()); if (instance_class_count_diff != 0) { - out->print(" " SSIZE_PLUS_FORMAT, instance_class_count_diff); + out->print(" %+zd", instance_class_count_diff); } - out->print(", array classes #" SIZE_FORMAT, _current_baseline.array_class_count()); + out->print(", array classes #%zu", _current_baseline.array_class_count()); const ssize_t array_class_count_diff = counter_diff(_current_baseline.array_class_count(), _early_baseline.array_class_count()); if (array_class_count_diff != 0) { - out->print(" " SSIZE_PLUS_FORMAT, array_class_count_diff); + out->print(" %+zd", array_class_count_diff); } out->print_cr(")"); } else if (mem_tag == mtThread) { // report thread count - out->print("(threads #" SIZE_FORMAT, _current_baseline.thread_count()); + out->print("(threads #%zu", _current_baseline.thread_count()); const ssize_t thread_count_diff = counter_diff(_current_baseline.thread_count(), _early_baseline.thread_count()); if (thread_count_diff != 0) { - out->print(" " SSIZE_PLUS_FORMAT, thread_count_diff); + out->print(" %+zd", thread_count_diff); } out->print_cr(")"); @@ -724,7 +724,7 @@ void MemSummaryDiffReporter::diff_summary_of_type(MemTag mem_tag, size_t current_tracking_overhead = amount_in_current_scale(_current_baseline.malloc_tracking_overhead()); size_t early_tracking_overhead = amount_in_current_scale(_early_baseline.malloc_tracking_overhead()); - out->print("(tracking overhead=" SIZE_FORMAT "%s", + out->print("(tracking overhead=%zu%s", amount_in_current_scale(_current_baseline.malloc_tracking_overhead()), scale); int64_t overhead_diff = diff_in_current_scale(_current_baseline.malloc_tracking_overhead(), @@ -770,7 +770,7 @@ void MemSummaryDiffReporter::print_metaspace_diff(const char* header, int64_t diff_waste = diff_in_current_scale(current_waste, early_waste); // Diff used - out->print("( used=" SIZE_FORMAT "%s", + out->print("( used=%zu%s", amount_in_current_scale(current_stats.used()), scale); if (diff_used != 0) { out->print(" " INT64_PLUS_FORMAT "%s", diff_used, scale); @@ -780,7 +780,7 @@ void MemSummaryDiffReporter::print_metaspace_diff(const char* header, // Diff waste const float waste_percentage = current_stats.committed() == 0 ? 0.0f : ((float)current_waste * 100.0f) / (float)current_stats.committed(); - out->print("( waste=" SIZE_FORMAT "%s =%2.2f%%", + out->print("( waste=%zu%s =%2.2f%%", amount_in_current_scale(current_waste), scale, waste_percentage); if (diff_waste != 0) { out->print(" " INT64_PLUS_FORMAT "%s", diff_waste, scale); diff --git a/src/hotspot/share/nmt/memTracker.cpp b/src/hotspot/share/nmt/memTracker.cpp index fb9c9a50db1f7..8f84948fa5ce4 100644 --- a/src/hotspot/share/nmt/memTracker.cpp +++ b/src/hotspot/share/nmt/memTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. * */ -#include "precompiled.hpp" #include "jvm.h" #include "logging/log.hpp" #include "logging/logStream.hpp" @@ -52,6 +51,8 @@ NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown; MemBaseline MemTracker::_baseline; +bool MemTracker::NmtVirtualMemoryLocker::_safe_to_use; + void MemTracker::initialize() { bool rc = true; assert(_tracking_level == NMT_unknown, "only call once"); diff --git a/src/hotspot/share/nmt/memTracker.hpp b/src/hotspot/share/nmt/memTracker.hpp index 6ba1db2e7ffe6..70125a1a01929 100644 --- a/src/hotspot/share/nmt/memTracker.hpp +++ b/src/hotspot/share/nmt/memTracker.hpp @@ -31,7 +31,6 @@ #include "nmt/threadStackTracker.hpp" #include "nmt/virtualMemoryTracker.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/threadCritical.hpp" #include "utilities/debug.hpp" #include "utilities/nativeCallStack.hpp" @@ -62,6 +61,12 @@ class MemTracker : AllStatic { return _tracking_level != NMT_unknown; } + // This may be called on a detached thread during VM init, so we should check that first. + static inline void assert_locked() { + assert(!NmtVirtualMemoryLocker::is_safe_to_use() || NmtVirtualMemory_lock->owned_by_self(), + "should have acquired NmtVirtualMemory_lock"); + } + static inline NMT_TrackingLevel tracking_level() { return _tracking_level; } @@ -125,12 +130,12 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { - ThreadCritical tc; + NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, mem_tag); } } - static inline void record_virtual_memory_release(address addr, size_t size) { + static inline void record_virtual_memory_release(void* addr, size_t size) { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { @@ -138,7 +143,7 @@ class MemTracker : AllStatic { } } - static inline void record_virtual_memory_uncommit(address addr, size_t size) { + static inline void record_virtual_memory_uncommit(void* addr, size_t size) { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { @@ -151,7 +156,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { - ThreadCritical tc; + NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, mem_tag); VirtualMemoryTracker::add_committed_region((address)addr, size, stack); } @@ -162,7 +167,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { - ThreadCritical tc; + NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::add_committed_region((address)addr, size, stack); } } @@ -170,7 +175,7 @@ class MemTracker : AllStatic { static inline MemoryFileTracker::MemoryFile* register_file(const char* descriptive_name) { assert_post_init(); if (!enabled()) return nullptr; - MemoryFileTracker::Instance::Locker lock; + NmtVirtualMemoryLocker nvml; return MemoryFileTracker::Instance::make_file(descriptive_name); } @@ -178,7 +183,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; assert(file != nullptr, "must be"); - MemoryFileTracker::Instance::Locker lock; + NmtVirtualMemoryLocker nvml; MemoryFileTracker::Instance::free_file(file); } @@ -187,7 +192,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; assert(file != nullptr, "must be"); - MemoryFileTracker::Instance::Locker lock; + NmtVirtualMemoryLocker nvml; MemoryFileTracker::Instance::allocate_memory(file, offset, size, stack, mem_tag); } @@ -196,7 +201,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; assert(file != nullptr, "must be"); - MemoryFileTracker::Instance::Locker lock; + NmtVirtualMemoryLocker nvml; MemoryFileTracker::Instance::free_memory(file, offset, size); } @@ -210,7 +215,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { - ThreadCritical tc; + NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::split_reserved_region((address)addr, size, split, mem_tag, split_tag); } } @@ -219,7 +224,7 @@ class MemTracker : AllStatic { assert_post_init(); if (!enabled()) return; if (addr != nullptr) { - ThreadCritical tc; + NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::set_reserved_region_type((address)addr, mem_tag); } } @@ -269,6 +274,39 @@ class MemTracker : AllStatic { // and return true; false if not found. static bool print_containing_region(const void* p, outputStream* out); + /* + * NmtVirtualMemoryLocker is similar to MutexLocker but can be used during VM init before mutexes are ready or + * current thread has been assigned. Performs no action during VM init. + * + * Unlike malloc, NMT requires locking for virtual memory operations. This is because it must synchronize the usage + * of global data structures used for modelling the effect of virtual memory operations. + * It is important that locking is used such that the actual OS memory operations (mmap) are done atomically with the + * corresponding NMT accounting (updating the internal model). Currently, this is not the case in all situations + * (see JDK-8341491), but this should be changed in the future. + * + * An issue with using Mutex is that NMT is used early during VM initialization before mutexes are initialized + * and current thread is attached. Mutexes do not work under those conditions, so we must use a flag to avoid + * attempting to lock until initialization is finished. Lack of synchronization here should not be a problem since it + * is single threaded at that point in time anyway. + */ + class NmtVirtualMemoryLocker: StackObj { + // Returns true if it is safe to start using this locker. + static bool _safe_to_use; + ConditionalMutexLocker _cml; + + public: + NmtVirtualMemoryLocker(): _cml(NmtVirtualMemory_lock, _safe_to_use, Mutex::_no_safepoint_check_flag){} + + static inline bool is_safe_to_use() { + return _safe_to_use; + } + + // Set in Threads::create_vm once threads and mutexes have been initialized. + static inline void set_safe_to_use() { + _safe_to_use = true; + } + }; + private: static void report(bool summary_only, outputStream* output, size_t scale); @@ -277,8 +315,6 @@ class MemTracker : AllStatic { static NMT_TrackingLevel _tracking_level; // Stored baseline static MemBaseline _baseline; - // Query lock - static Mutex* _query_lock; }; #endif // SHARE_NMT_MEMTRACKER_HPP diff --git a/src/hotspot/share/nmt/memoryFileTracker.cpp b/src/hotspot/share/nmt/memoryFileTracker.cpp index 0777d5aafc32d..f4dac97d2dab7 100644 --- a/src/hotspot/share/nmt/memoryFileTracker.cpp +++ b/src/hotspot/share/nmt/memoryFileTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,20 +22,17 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "nmt/memTracker.hpp" #include "nmt/memoryFileTracker.hpp" #include "nmt/nmtCommon.hpp" #include "nmt/nmtNativeCallStackStorage.hpp" #include "nmt/vmatree.hpp" -#include "runtime/mutex.hpp" #include "utilities/growableArray.hpp" #include "utilities/nativeCallStack.hpp" #include "utilities/ostream.hpp" MemoryFileTracker* MemoryFileTracker::Instance::_tracker = nullptr; -PlatformMutex* MemoryFileTracker::Instance::_mutex = nullptr; MemoryFileTracker::MemoryFileTracker(bool is_detailed_mode) : _stack_storage(is_detailed_mode), _files() {} @@ -87,7 +84,7 @@ void MemoryFileTracker::print_report_on(const MemoryFile* file, outputStream* st if (prev->val().out.type() == VMATree::StateType::Committed) { const VMATree::position& start_addr = prev->key(); const VMATree::position& end_addr = current->key(); - stream->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] allocated " SIZE_FORMAT "%s" " for %s from", + stream->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] allocated %zu%s" " for %s from", start_addr, end_addr, NMTUtil::amount_in_scale(end_addr - start_addr, scale), NMTUtil::scale_name(scale), @@ -132,7 +129,6 @@ bool MemoryFileTracker::Instance::initialize(NMT_TrackingLevel tracking_level) { _tracker = static_cast(os::malloc(sizeof(MemoryFileTracker), mtNMT)); if (_tracker == nullptr) return false; new (_tracker) MemoryFileTracker(tracking_level == NMT_TrackingLevel::NMT_detail); - _mutex = new PlatformMutex(); return true; } @@ -189,11 +185,3 @@ void MemoryFileTracker::summary_snapshot(VirtualMemorySnapshot* snapshot) const void MemoryFileTracker::Instance::summary_snapshot(VirtualMemorySnapshot* snapshot) { _tracker->summary_snapshot(snapshot); } - -MemoryFileTracker::Instance::Locker::Locker() { - MemoryFileTracker::Instance::_mutex->lock(); -} - -MemoryFileTracker::Instance::Locker::~Locker() { - MemoryFileTracker::Instance::_mutex->unlock(); -} diff --git a/src/hotspot/share/nmt/memoryFileTracker.hpp b/src/hotspot/share/nmt/memoryFileTracker.hpp index 94f9cb2006cdc..035e9b466e264 100644 --- a/src/hotspot/share/nmt/memoryFileTracker.hpp +++ b/src/hotspot/share/nmt/memoryFileTracker.hpp @@ -30,7 +30,6 @@ #include "nmt/nmtNativeCallStackStorage.hpp" #include "nmt/virtualMemoryTracker.hpp" #include "nmt/vmatree.hpp" -#include "runtime/mutex.hpp" #include "runtime/os.inline.hpp" #include "utilities/growableArray.hpp" #include "utilities/nativeCallStack.hpp" @@ -93,14 +92,8 @@ class MemoryFileTracker { class Instance : public AllStatic { static MemoryFileTracker* _tracker; - static PlatformMutex* _mutex; public: - class Locker : public StackObj { - public: - Locker(); - ~Locker(); - }; static bool initialize(NMT_TrackingLevel tracking_level); diff --git a/src/hotspot/share/nmt/nativeCallStackPrinter.cpp b/src/hotspot/share/nmt/nativeCallStackPrinter.cpp index 70031698a7d80..c2a54961abe76 100644 --- a/src/hotspot/share/nmt/nativeCallStackPrinter.cpp +++ b/src/hotspot/share/nmt/nativeCallStackPrinter.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2024, Red Hat, Inc. All rights reserved. - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "nmt/nativeCallStackPrinter.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/nmt/nmtCommon.cpp b/src/hotspot/share/nmt/nmtCommon.cpp index 24a4cb1105adf..318762a7ce768 100644 --- a/src/hotspot/share/nmt/nmtCommon.cpp +++ b/src/hotspot/share/nmt/nmtCommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. * */ -#include "precompiled.hpp" + #include "nmt/nmtCommon.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/nmt/nmtDCmd.cpp b/src/hotspot/share/nmt/nmtDCmd.cpp index cb42212ba6b15..0c6dc5241a2a3 100644 --- a/src/hotspot/share/nmt/nmtDCmd.cpp +++ b/src/hotspot/share/nmt/nmtDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "memory/resourceArea.hpp" #include "nmt/memReporter.hpp" #include "nmt/memTracker.hpp" diff --git a/src/hotspot/share/nmt/nmtNativeCallStackStorage.cpp b/src/hotspot/share/nmt/nmtNativeCallStackStorage.cpp index fd7a67a358e87..3e5c1d2f0ea65 100644 --- a/src/hotspot/share/nmt/nmtNativeCallStackStorage.cpp +++ b/src/hotspot/share/nmt/nmtNativeCallStackStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "nmt/nmtNativeCallStackStorage.hpp" diff --git a/src/hotspot/share/nmt/nmtPreInit.cpp b/src/hotspot/share/nmt/nmtPreInit.cpp index 0aa74566f42cb..34a2d8dd7d2ee 100644 --- a/src/hotspot/share/nmt/nmtPreInit.cpp +++ b/src/hotspot/share/nmt/nmtPreInit.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2022, 2023 SAP SE. All rights reserved. - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "nmt/nmtPreInit.hpp" #include "runtime/os.hpp" #include "utilities/align.hpp" @@ -132,7 +131,7 @@ void NMTPreInitAllocationTable::print_state(outputStream* st) const { num_entries += chain_len; longest_chain = MAX2(chain_len, longest_chain); } - st->print("entries: %d (primary: %d, empties: %d), sum bytes: " SIZE_FORMAT + st->print("entries: %d (primary: %d, empties: %d), sum bytes: %zu" ", longest chain length: %d", num_entries, num_primary_entries, table_size - num_primary_entries, sum_bytes, longest_chain); @@ -143,7 +142,7 @@ void NMTPreInitAllocationTable::print_map(outputStream* st) const { for (int i = 0; i < table_size; i++) { st->print("[%d]: ", i); for (NMTPreInitAllocation* a = _entries[i]; a != nullptr; a = a->next) { - st->print( PTR_FORMAT "(" SIZE_FORMAT ") ", p2i(a->payload), a->size); + st->print( PTR_FORMAT "(%zu) ", p2i(a->payload), a->size); } st->cr(); } diff --git a/src/hotspot/share/nmt/nmtTreap.hpp b/src/hotspot/share/nmt/nmtTreap.hpp index b6be654f12777..7e4ad3df95bf1 100644 --- a/src/hotspot/share/nmt/nmtTreap.hpp +++ b/src/hotspot/share/nmt/nmtTreap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/powerOfTwo.hpp" +#include // A Treap is a self-balanced binary tree where each node is equipped with a // priority. It adds the invariant that the priority of a parent P is strictly larger @@ -65,6 +66,8 @@ class Treap { TreapNode* _right; public: + TreapNode(const K& k, uint64_t p) : _priority(p), _key(k), _left(nullptr), _right(nullptr) {} + TreapNode(const K& k, const V& v, uint64_t p) : _priority(p), _key(k), @@ -228,7 +231,9 @@ class Treap { : _allocator(), _root(nullptr), _prng_seed(_initial_seed), - _node_count(0) {} + _node_count(0) { + static_assert(std::is_trivially_destructible::value, "must be"); + } ~Treap() { this->remove_all(); @@ -266,6 +271,7 @@ class Treap { if (second_split.right != nullptr) { // The key k existed, we delete it. _node_count--; + second_split.right->_value.~V(); _allocator.free(second_split.right); } // Merge together everything @@ -283,6 +289,7 @@ class Treap { if (head == nullptr) continue; to_delete.push(head->_left); to_delete.push(head->_right); + head->_value.~V(); _allocator.free(head); } _root = nullptr; @@ -308,6 +315,30 @@ class Treap { return candidate; } + struct FindResult { + FindResult(TreapNode* node, bool new_node) : node(node), new_node(new_node) {} + TreapNode* const node; + bool const new_node; + }; + + // Finds the node for the given k in the tree or inserts a new node with the default constructed value. + FindResult find(const K& k) { + if (TreapNode* found = find(_root, k)) { + return FindResult(found, false); + } + _node_count++; + // Doesn't exist, make node + void* node_place = _allocator.allocate(sizeof(TreapNode)); + uint64_t prio = prng_next(); + TreapNode* node = new (node_place) TreapNode(k, prio); + + // (LEQ_k, GT_k) + node_pair split_up = split(this->_root, k); + // merge(merge(LEQ_k, EQ_k), GT_k) + this->_root = merge(merge(split_up.left, node), split_up.right); + return FindResult(node, true); + } + TreapNode* closest_gt(const K& key) { TreapNode* candidate = nullptr; TreapNode* pos = _root; diff --git a/src/hotspot/share/nmt/nmtUsage.cpp b/src/hotspot/share/nmt/nmtUsage.cpp index aa1d681b8a531..771f507616089 100644 --- a/src/hotspot/share/nmt/nmtUsage.cpp +++ b/src/hotspot/share/nmt/nmtUsage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,9 @@ * */ -#include "precompiled.hpp" #include "nmt/mallocTracker.hpp" #include "nmt/memoryFileTracker.hpp" +#include "nmt/memTracker.hpp" #include "nmt/nmtCommon.hpp" #include "nmt/nmtUsage.hpp" #include "nmt/threadStackTracker.hpp" @@ -94,7 +94,7 @@ void NMTUsage::update_vm_usage() { { // MemoryFileTracker addition using MFT = MemoryFileTracker::Instance; - MFT::Locker lock; + MemTracker::NmtVirtualMemoryLocker nvml; MFT::iterate_summary([&](MemTag tag, const VirtualMemory* vm) { int i = NMTUtil::tag_to_index(tag); _vm_by_type[i].committed += vm->committed(); diff --git a/src/hotspot/share/nmt/threadStackTracker.cpp b/src/hotspot/share/nmt/threadStackTracker.cpp index 6f112fa8fc5c2..dabb23f0801e3 100644 --- a/src/hotspot/share/nmt/threadStackTracker.cpp +++ b/src/hotspot/share/nmt/threadStackTracker.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, 2024, Red Hat, Inc. All rights reserved. - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,11 @@ * */ -#include "precompiled.hpp" #include "nmt/memTracker.hpp" #include "nmt/threadStackTracker.hpp" #include "nmt/virtualMemoryTracker.hpp" #include "runtime/os.hpp" -#include "runtime/threadCritical.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" @@ -53,7 +51,7 @@ void ThreadStackTracker::new_thread_stack(void* base, size_t size, const NativeC assert(base != nullptr, "Should have been filtered"); align_thread_stack_boundaries_inward(base, size); - ThreadCritical tc; + MemTracker::NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::add_reserved_region((address)base, size, stack, mtThreadStack); _thread_count++; } @@ -63,7 +61,7 @@ void ThreadStackTracker::delete_thread_stack(void* base, size_t size) { assert(base != nullptr, "Should have been filtered"); align_thread_stack_boundaries_inward(base, size); - ThreadCritical tc; + MemTracker::NmtVirtualMemoryLocker nvml; VirtualMemoryTracker::remove_released_region((address)base, size); _thread_count--; } diff --git a/src/hotspot/share/nmt/virtualMemoryTracker.cpp b/src/hotspot/share/nmt/virtualMemoryTracker.cpp index d298381f1038f..231ca6f8875bb 100644 --- a/src/hotspot/share/nmt/virtualMemoryTracker.cpp +++ b/src/hotspot/share/nmt/virtualMemoryTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/metaspaceStats.hpp" #include "memory/metaspaceUtils.hpp" @@ -30,7 +29,6 @@ #include "nmt/threadStackTracker.hpp" #include "nmt/virtualMemoryTracker.hpp" #include "runtime/os.hpp" -#include "runtime/threadCritical.hpp" #include "utilities/ostream.hpp" VirtualMemorySnapshot VirtualMemorySummary::_snapshot; @@ -338,10 +336,12 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, assert(base_addr != nullptr, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); + ReservedMemoryRegion rgn(base_addr, size, stack, mem_tag); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); - log_debug(nmt)("Add reserved region \'%s\' (" INTPTR_FORMAT ", " SIZE_FORMAT ")", + log_debug(nmt)("Add reserved region \'%s\' (" INTPTR_FORMAT ", %zu)", rgn.mem_tag_name(), p2i(rgn.base()), rgn.size()); if (reserved_rgn == nullptr) { VirtualMemorySummary::record_reserved_memory(size, mem_tag); @@ -381,7 +381,7 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, // CDS reserves the whole region for mapping CDS archive, then maps each section into the region. // NMT reports CDS as a whole. if (reserved_rgn->mem_tag() == mtClassShared) { - log_debug(nmt)("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT ", " SIZE_FORMAT ")", + log_debug(nmt)("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT ", %zu)", reserved_rgn->mem_tag_name(), p2i(reserved_rgn->base()), reserved_rgn->size()); assert(reserved_rgn->contain_region(base_addr, size), "Reserved CDS region should contain this mapping region"); return true; @@ -390,7 +390,7 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, // Mapped CDS string region. // The string region(s) is part of the java heap. if (reserved_rgn->mem_tag() == mtJavaHeap) { - log_debug(nmt)("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT ", " SIZE_FORMAT ")", + log_debug(nmt)("CDS reserved region \'%s\' as a whole (" INTPTR_FORMAT ", %zu)", reserved_rgn->mem_tag_name(), p2i(reserved_rgn->base()), reserved_rgn->size()); assert(reserved_rgn->contain_region(base_addr, size), "Reserved heap region should contain this mapping region"); return true; @@ -416,6 +416,7 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, void VirtualMemoryTracker::set_reserved_region_type(address addr, MemTag mem_tag) { assert(addr != nullptr, "Invalid address"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); ReservedMemoryRegion rgn(addr, 1); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); @@ -434,18 +435,19 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size, assert(addr != nullptr, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); if (reserved_rgn == nullptr) { - log_debug(nmt)("Add committed region \'%s\', No reserved region found for (" INTPTR_FORMAT ", " SIZE_FORMAT ")", + log_debug(nmt)("Add committed region \'%s\', No reserved region found for (" INTPTR_FORMAT ", %zu)", rgn.mem_tag_name(), p2i(rgn.base()), rgn.size()); } assert(reserved_rgn != nullptr, "Add committed region, No reserved region found"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); bool result = reserved_rgn->add_committed_region(addr, size, stack); - log_debug(nmt)("Add committed region \'%s\'(" INTPTR_FORMAT ", " SIZE_FORMAT ") %s", + log_debug(nmt)("Add committed region \'%s\'(" INTPTR_FORMAT ", %zu) %s", reserved_rgn->mem_tag_name(), p2i(rgn.base()), rgn.size(), (result ? "Succeeded" : "Failed")); return result; } @@ -454,14 +456,15 @@ bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) assert(addr != nullptr, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); - assert(reserved_rgn != nullptr, "No reserved region (" INTPTR_FORMAT ", " SIZE_FORMAT ")", p2i(addr), size); + assert(reserved_rgn != nullptr, "No reserved region (" INTPTR_FORMAT ", %zu)", p2i(addr), size); assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); const char* type_name = reserved_rgn->mem_tag_name(); // after remove, info is not complete bool result = reserved_rgn->remove_uncommitted_region(addr, size); - log_debug(nmt)("Removed uncommitted region \'%s\' (" INTPTR_FORMAT ", " SIZE_FORMAT ") %s", + log_debug(nmt)("Removed uncommitted region \'%s\' (" INTPTR_FORMAT ", %zu) %s", type_name, p2i(addr), size, (result ? " Succeeded" : "Failed")); return result; } @@ -469,11 +472,12 @@ bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) bool VirtualMemoryTracker::remove_released_region(ReservedMemoryRegion* rgn) { assert(rgn != nullptr, "Sanity check"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); // uncommit regions within the released region ReservedMemoryRegion backup(*rgn); bool result = rgn->remove_uncommitted_region(rgn->base(), rgn->size()); - log_debug(nmt)("Remove uncommitted region \'%s\' (" INTPTR_FORMAT ", " SIZE_FORMAT ") %s", + log_debug(nmt)("Remove uncommitted region \'%s\' (" INTPTR_FORMAT ", %zu) %s", backup.mem_tag_name(), p2i(backup.base()), backup.size(), (result ? "Succeeded" : "Failed")); if (!result) { return false; @@ -481,7 +485,7 @@ bool VirtualMemoryTracker::remove_released_region(ReservedMemoryRegion* rgn) { VirtualMemorySummary::record_released_memory(rgn->size(), rgn->mem_tag()); result = _reserved_regions->remove(*rgn); - log_debug(nmt)("Removed region \'%s\' (" INTPTR_FORMAT ", " SIZE_FORMAT ") from _reserved_regions %s" , + log_debug(nmt)("Removed region \'%s\' (" INTPTR_FORMAT ", %zu) from _reserved_regions %s" , backup.mem_tag_name(), p2i(backup.base()), backup.size(), (result ? "Succeeded" : "Failed")); return result; } @@ -490,12 +494,13 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { assert(addr != nullptr, "Invalid address"); assert(size > 0, "Invalid size"); assert(_reserved_regions != nullptr, "Sanity check"); + MemTracker::assert_locked(); ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); if (reserved_rgn == nullptr) { - log_debug(nmt)("No reserved region found for (" INTPTR_FORMAT ", " SIZE_FORMAT ")!", + log_debug(nmt)("No reserved region found for (" INTPTR_FORMAT ", %zu)!", p2i(rgn.base()), rgn.size()); } assert(reserved_rgn != nullptr, "No reserved region"); @@ -571,7 +576,7 @@ bool VirtualMemoryTracker::split_reserved_region(address addr, size_t size, size const char* name = reserved_rgn->mem_tag_name(); remove_released_region(reserved_rgn); - log_debug(nmt)("Split region \'%s\' (" INTPTR_FORMAT ", " SIZE_FORMAT ") with size " SIZE_FORMAT, + log_debug(nmt)("Split region \'%s\' (" INTPTR_FORMAT ", %zu) with size %zu", name, p2i(rgn.base()), rgn.size(), split); // Now, create two new regions. add_reserved_region(addr, split, original_stack, mem_tag); @@ -621,6 +626,9 @@ class SnapshotThreadStackWalker : public VirtualMemoryWalker { SnapshotThreadStackWalker() {} bool do_allocation_site(const ReservedMemoryRegion* rgn) { + if (MemTracker::NmtVirtualMemoryLocker::is_safe_to_use()) { + assert_lock_strong(NmtVirtualMemory_lock); + } if (rgn->mem_tag() == mtThreadStack) { address stack_bottom = rgn->thread_stack_uncommitted_bottom(); address committed_start; @@ -661,7 +669,7 @@ void VirtualMemoryTracker::snapshot_thread_stacks() { bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { assert(_reserved_regions != nullptr, "Sanity check"); - ThreadCritical tc; + MemTracker::NmtVirtualMemoryLocker nvml; // Check that the _reserved_regions haven't been deleted. if (_reserved_regions != nullptr) { LinkedListNode* head = _reserved_regions->head(); diff --git a/src/hotspot/share/nmt/vmatree.cpp b/src/hotspot/share/nmt/vmatree.cpp index ec4f405f1c9cd..21aee26ca8782 100644 --- a/src/hotspot/share/nmt/vmatree.cpp +++ b/src/hotspot/share/nmt/vmatree.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "nmt/vmatree.hpp" #include "utilities/globalDefinitions.hpp" @@ -220,7 +219,7 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType #ifdef ASSERT void VMATree::print_on(outputStream* out) { visit_in_order([&](TreapNode* current) { - out->print(SIZE_FORMAT " (%s) - %s - ", current->key(), NMTUtil::tag_to_name(out_state(current).mem_tag()), + out->print("%zu (%s) - %s - ", current->key(), NMTUtil::tag_to_name(out_state(current).mem_tag()), statetype_to_string(out_state(current).type())); }); out->cr(); diff --git a/src/hotspot/share/oops/access.hpp b/src/hotspot/share/oops/access.hpp index 34393462d0319..917627f445e17 100644 --- a/src/hotspot/share/oops/access.hpp +++ b/src/hotspot/share/oops/access.hpp @@ -284,11 +284,6 @@ class HeapAccess: public Access {}; template class NativeAccess: public Access {}; -// Helper for performing accesses in nmethods. These accesses -// may resolve an accessor on a GC barrier set. -template -class NMethodAccess: public Access {}; - // Helper for array access. template class ArrayAccess: public HeapAccess { @@ -366,7 +361,6 @@ void Access::verify_decorators() { const DecoratorSet location_decorators = decorators & IN_DECORATOR_MASK; STATIC_ASSERT(location_decorators == 0 || ( // make sure location decorators are disjoint if set (location_decorators ^ IN_NATIVE) == 0 || - (location_decorators ^ IN_NMETHOD) == 0 || (location_decorators ^ IN_HEAP) == 0 )); } diff --git a/src/hotspot/share/oops/accessBackend.cpp b/src/hotspot/share/oops/accessBackend.cpp index be191316f25d2..3b64bbb61f24d 100644 --- a/src/hotspot/share/oops/accessBackend.cpp +++ b/src/hotspot/share/oops/accessBackend.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "accessBackend.inline.hpp" #include "gc/shared/collectedHeap.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/oops/accessDecorators.hpp b/src/hotspot/share/oops/accessDecorators.hpp index fc5860d6487f9..3d89b5c433440 100644 --- a/src/hotspot/share/oops/accessDecorators.hpp +++ b/src/hotspot/share/oops/accessDecorators.hpp @@ -173,11 +173,9 @@ const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF | // * IN_HEAP: The access is performed in the heap. Many barriers such as card marking will // be omitted if this decorator is not set. // * IN_NATIVE: The access is performed in an off-heap data structure. -// * IN_NMETHOD: The access is performed inside of an nmethod. const DecoratorSet IN_HEAP = UCONST64(1) << 18; const DecoratorSet IN_NATIVE = UCONST64(1) << 19; -const DecoratorSet IN_NMETHOD = UCONST64(1) << 20; -const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE | IN_NMETHOD; +const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE; // == Boolean Flag Decorators == // * IS_ARRAY: The access is performed on a heap allocated array. This is sometimes a special case @@ -185,9 +183,9 @@ const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE | IN_NMETHOD; // * IS_DEST_UNINITIALIZED: This property can be important to e.g. SATB barriers by // marking that the previous value is uninitialized nonsense rather than a real value. // * IS_NOT_NULL: This property can make certain barriers faster such as compressing oops. -const DecoratorSet IS_ARRAY = UCONST64(1) << 21; -const DecoratorSet IS_DEST_UNINITIALIZED = UCONST64(1) << 22; -const DecoratorSet IS_NOT_NULL = UCONST64(1) << 23; +const DecoratorSet IS_ARRAY = UCONST64(1) << 20; +const DecoratorSet IS_DEST_UNINITIALIZED = UCONST64(1) << 21; +const DecoratorSet IS_NOT_NULL = UCONST64(1) << 22; // == Arraycopy Decorators == // * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source @@ -199,11 +197,11 @@ const DecoratorSet IS_NOT_NULL = UCONST64(1) << 23; // * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form. // * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements. // * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord. -const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 24; -const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 25; -const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 26; -const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 27; -const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 28; +const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 23; +const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 24; +const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 25; +const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 26; +const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 27; const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT | ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF | ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED; @@ -212,11 +210,11 @@ const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYC // * ACCESS_READ: Indicate that the resolved object is accessed read-only. This allows the GC // backend to use weaker and more efficient barriers. // * ACCESS_WRITE: Indicate that the resolved object is used for write access. -const DecoratorSet ACCESS_READ = UCONST64(1) << 29; -const DecoratorSet ACCESS_WRITE = UCONST64(1) << 30; +const DecoratorSet ACCESS_READ = UCONST64(1) << 28; +const DecoratorSet ACCESS_WRITE = UCONST64(1) << 29; // Keep track of the last decorator. -const DecoratorSet DECORATOR_LAST = UCONST64(1) << 30; +const DecoratorSet DECORATOR_LAST = UCONST64(1) << 29; namespace AccessInternal { // This class adds implied decorators that follow according to decorator rules. diff --git a/src/hotspot/share/oops/annotations.cpp b/src/hotspot/share/oops/annotations.cpp index 8b2b236960dd7..606c18b350d04 100644 --- a/src/hotspot/share/oops/annotations.cpp +++ b/src/hotspot/share/oops/annotations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "logging/log.hpp" #include "memory/metadataFactory.hpp" diff --git a/src/hotspot/share/oops/array.hpp b/src/hotspot/share/oops/array.hpp index 25dd8cd6bebe7..12e23080166ec 100644 --- a/src/hotspot/share/oops/array.hpp +++ b/src/hotspot/share/oops/array.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,12 +74,12 @@ class Array: public MetaspaceObj { assert(is_aligned(left, sizeof(T)), "Must be"); size_t elements = left / sizeof(T); - assert(elements <= (size_t)INT_MAX, "number of elements " SIZE_FORMAT "doesn't fit into an int.", elements); + assert(elements <= (size_t)INT_MAX, "number of elements %zu doesn't fit into an int.", elements); int length = (int)elements; assert((size_t)size(length) * BytesPerWord == (size_t)bytes, - "Expected: " SIZE_FORMAT " got: " SIZE_FORMAT, + "Expected: %zu got: %zu", bytes, (size_t)size(length) * BytesPerWord); return length; @@ -135,7 +135,7 @@ class Array: public MetaspaceObj { size_t bytes = align_up(byte_sizeof(length), BytesPerWord); size_t words = bytes / BytesPerWord; - assert(words <= INT_MAX, "Overflow: " SIZE_FORMAT, words); + assert(words <= INT_MAX, "Overflow: %zu", words); return (int)words; } diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp index 54b02cfd948d0..8b6a97fd62d68 100644 --- a/src/hotspot/share/oops/arrayKlass.cpp +++ b/src/hotspot/share/oops/arrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/javaClasses.hpp" diff --git a/src/hotspot/share/oops/compressedKlass.cpp b/src/hotspot/share/oops/compressedKlass.cpp index 21c28af876686..fc8c0513ca036 100644 --- a/src/hotspot/share/oops/compressedKlass.cpp +++ b/src/hotspot/share/oops/compressedKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/metaspace.hpp" #include "oops/compressedKlass.inline.hpp" @@ -96,7 +95,7 @@ void CompressedKlassPointers::sanity_check_after_initialization() { // Check that Klass range is fully engulfed in the encoding range const address encoding_start = _base; - const address encoding_end = _base + nth_bit(narrow_klass_pointer_bits() + _shift); + const address encoding_end = (address)(p2u(_base) + (uintptr_t)nth_bit(narrow_klass_pointer_bits() + _shift)); ASSERT_HERE_2(_klass_range_start >= _base && _klass_range_end <= encoding_end, "Resulting encoding range does not fully cover the class range"); diff --git a/src/hotspot/share/oops/compressedOops.cpp b/src/hotspot/share/oops/compressedOops.cpp index ec41dd8521918..675b5b44f5367 100644 --- a/src/hotspot/share/oops/compressedOops.cpp +++ b/src/hotspot/share/oops/compressedOops.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,12 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/memRegion.hpp" +#include "memory/reservedSpace.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "memory/virtualspace.hpp" #include "oops/compressedOops.hpp" #include "gc/shared/collectedHeap.hpp" #include "runtime/arguments.hpp" @@ -66,7 +65,7 @@ void CompressedOops::initialize(const ReservedHeapSpace& heap_space) { set_base((address)heap_space.compressed_oop_base()); } - _heap_address_range = heap_space.region(); + _heap_address_range = MemRegion((HeapWord*)heap_space.base(), (HeapWord*)heap_space.end()); LogTarget(Debug, gc, heap, coops) lt; if (lt.is_enabled()) { @@ -161,7 +160,7 @@ bool CompressedOops::base_overlaps() { } void CompressedOops::print_mode(outputStream* st) { - st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", + st->print("Heap address: " PTR_FORMAT ", size: %zu MB", p2i(_heap_address_range.start()), _heap_address_range.byte_size()/M); st->print(", Compressed Oops mode: %s", mode_to_string(mode())); diff --git a/src/hotspot/share/oops/constMethod.cpp b/src/hotspot/share/oops/constMethod.cpp index a6a93d6f48a94..1fed47f7ff226 100644 --- a/src/hotspot/share/oops/constMethod.cpp +++ b/src/hotspot/share/oops/constMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "interpreter/interpreter.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" diff --git a/src/hotspot/share/oops/constMethodFlags.cpp b/src/hotspot/share/oops/constMethodFlags.cpp index 69b017cb18055..16bf2aab61374 100644 --- a/src/hotspot/share/oops/constMethodFlags.cpp +++ b/src/hotspot/share/oops/constMethodFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/constMethodFlags.hpp" #include "runtime/atomic.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 22896d9e00fb1..8aba2bb2ba354 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" @@ -332,8 +331,7 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { } InstanceKlass *ik = pool_holder(); - if (!(ik->is_shared_boot_class() || ik->is_shared_platform_class() || - ik->is_shared_app_class())) { + if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) { // Archiving resolved references for classes from non-builtin loaders // is not yet supported. return nullptr; @@ -345,12 +343,11 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { int rr_len = rr->length(); GrowableArray keep_resolved_refs(rr_len, rr_len, false); - ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this); - src_cp->iterate_archivable_resolved_references([&](int rr_index) { + iterate_archivable_resolved_references([&](int rr_index) { keep_resolved_refs.at_put(rr_index, true); }); - objArrayOop scratch_rr = HeapShared::scratch_resolved_references(src_cp); + objArrayOop scratch_rr = HeapShared::scratch_resolved_references(this); Array* ref_map = reference_map(); int ref_map_len = ref_map == nullptr ? 0 : ref_map->length(); for (int i = 0; i < rr_len; i++) { @@ -378,32 +375,6 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { return rr; } -void ConstantPool::find_required_hidden_classes() { - if (_cache == nullptr) { - return; - } - - ClassLoaderData* loader_data = pool_holder()->class_loader_data(); - if (loader_data == nullptr) { - // These are custom loader classes from the preimage - return; - } - - if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { - // Archiving resolved references for classes from non-builtin loaders - // is not yet supported. - return; - } - - objArrayOop rr = resolved_references(); - if (rr != nullptr) { - iterate_archivable_resolved_references([&](int rr_index) { - oop obj = rr->obj_at(rr_index); - HeapShared::find_required_hidden_classes_in_object(obj); - }); - } -} - void ConstantPool::add_dumped_interned_strings() { InstanceKlass* ik = pool_holder(); if (!ik->is_linked()) { @@ -2046,138 +2017,6 @@ const char* ConstantPool::printable_name_at(int cp_index) { #endif // PRODUCT -// JVMTI GetConstantPool support - -// For debugging of constant pool -const bool debug_cpool = false; - -#define DBG(code) do { if (debug_cpool) { (code); } } while(0) - -static void print_cpool_bytes(jint cnt, u1 *bytes) { - const char* WARN_MSG = "Must not be such entry!"; - jint size = 0; - u2 idx1, idx2; - - for (jint idx = 1; idx < cnt; idx++) { - jint ent_size = 0; - u1 tag = *bytes++; - size++; // count tag - - printf("const #%03d, tag: %02d ", idx, tag); - switch(tag) { - case JVM_CONSTANT_Invalid: { - printf("Invalid"); - break; - } - case JVM_CONSTANT_Unicode: { - printf("Unicode %s", WARN_MSG); - break; - } - case JVM_CONSTANT_Utf8: { - u2 len = Bytes::get_Java_u2(bytes); - char str[128]; - if (len > 127) { - len = 127; - } - strncpy(str, (char *) (bytes+2), len); - str[len] = '\0'; - printf("Utf8 \"%s\"", str); - ent_size = 2 + len; - break; - } - case JVM_CONSTANT_Integer: { - u4 val = Bytes::get_Java_u4(bytes); - printf("int %d", *(int *) &val); - ent_size = 4; - break; - } - case JVM_CONSTANT_Float: { - u4 val = Bytes::get_Java_u4(bytes); - printf("float %5.3ff", *(float *) &val); - ent_size = 4; - break; - } - case JVM_CONSTANT_Long: { - u8 val = Bytes::get_Java_u8(bytes); - printf("long " INT64_FORMAT, (int64_t) *(jlong *) &val); - ent_size = 8; - idx++; // Long takes two cpool slots - break; - } - case JVM_CONSTANT_Double: { - u8 val = Bytes::get_Java_u8(bytes); - printf("double %5.3fd", *(jdouble *)&val); - ent_size = 8; - idx++; // Double takes two cpool slots - break; - } - case JVM_CONSTANT_Class: { - idx1 = Bytes::get_Java_u2(bytes); - printf("class #%03d", idx1); - ent_size = 2; - break; - } - case JVM_CONSTANT_String: { - idx1 = Bytes::get_Java_u2(bytes); - printf("String #%03d", idx1); - ent_size = 2; - break; - } - case JVM_CONSTANT_Fieldref: { - idx1 = Bytes::get_Java_u2(bytes); - idx2 = Bytes::get_Java_u2(bytes+2); - printf("Field #%03d, #%03d", (int) idx1, (int) idx2); - ent_size = 4; - break; - } - case JVM_CONSTANT_Methodref: { - idx1 = Bytes::get_Java_u2(bytes); - idx2 = Bytes::get_Java_u2(bytes+2); - printf("Method #%03d, #%03d", idx1, idx2); - ent_size = 4; - break; - } - case JVM_CONSTANT_InterfaceMethodref: { - idx1 = Bytes::get_Java_u2(bytes); - idx2 = Bytes::get_Java_u2(bytes+2); - printf("InterfMethod #%03d, #%03d", idx1, idx2); - ent_size = 4; - break; - } - case JVM_CONSTANT_NameAndType: { - idx1 = Bytes::get_Java_u2(bytes); - idx2 = Bytes::get_Java_u2(bytes+2); - printf("NameAndType #%03d, #%03d", idx1, idx2); - ent_size = 4; - break; - } - case JVM_CONSTANT_ClassIndex: { - printf("ClassIndex %s", WARN_MSG); - break; - } - case JVM_CONSTANT_UnresolvedClass: { - printf("UnresolvedClass: %s", WARN_MSG); - break; - } - case JVM_CONSTANT_UnresolvedClassInError: { - printf("UnresolvedClassInErr: %s", WARN_MSG); - break; - } - case JVM_CONSTANT_StringIndex: { - printf("StringIndex: %s", WARN_MSG); - break; - } - } - printf(";\n"); - bytes += ent_size; - size += ent_size; - } - printf("Cpool size: %d\n", size); - fflush(nullptr); - return; -} /* end print_cpool_bytes */ - - // Returns size of constant pool entry. jint ConstantPool::cpool_entry_size(jint idx) { switch(tag_at(idx).value()) { @@ -2240,7 +2079,6 @@ jint ConstantPool::hash_entries_to(SymbolHash *symmap, case JVM_CONSTANT_Utf8: { Symbol* sym = symbol_at(idx); symmap->add_if_absent(sym, idx); - DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx)); break; } case JVM_CONSTANT_Class: @@ -2248,7 +2086,6 @@ jint ConstantPool::hash_entries_to(SymbolHash *symmap, case JVM_CONSTANT_UnresolvedClassInError: { Symbol* sym = klass_name_at(idx); classmap->add_if_absent(sym, idx); - DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx)); break; } case JVM_CONSTANT_Long: @@ -2282,15 +2119,12 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, assert(size + ent_size <= cpool_size, "Size mismatch"); *bytes = tag; - DBG(printf("#%03hd tag=%03hd, ", (short)idx, (short)tag)); switch(tag) { case JVM_CONSTANT_Invalid: { - DBG(printf("JVM_CONSTANT_Invalid")); break; } case JVM_CONSTANT_Unicode: { assert(false, "Wrong constant pool tag: JVM_CONSTANT_Unicode"); - DBG(printf("JVM_CONSTANT_Unicode")); break; } case JVM_CONSTANT_Utf8: { @@ -2302,7 +2136,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, for (int i = 0; i < len; i++) { bytes[3+i] = (u1) str[i]; } - DBG(printf("JVM_CONSTANT_Utf8: %s ", str)); break; } case JVM_CONSTANT_Integer: { @@ -2335,7 +2168,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, idx1 = tbl->symbol_to_value(sym); assert(idx1 != 0, "Have not found a hashtable entry"); Bytes::put_Java_u2((address) (bytes+1), idx1); - DBG(printf("JVM_CONSTANT_Class: idx=#%03hd, %s", idx1, sym->as_utf8())); break; } case JVM_CONSTANT_String: { @@ -2344,7 +2176,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, idx1 = tbl->symbol_to_value(sym); assert(idx1 != 0, "Have not found a hashtable entry"); Bytes::put_Java_u2((address) (bytes+1), idx1); - DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, sym->as_utf8())); break; } case JVM_CONSTANT_Fieldref: @@ -2354,7 +2185,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, idx2 = uncached_name_and_type_ref_index_at(idx); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); - DBG(printf("JVM_CONSTANT_Methodref: %hd %hd", idx1, idx2)); break; } case JVM_CONSTANT_NameAndType: { @@ -2362,21 +2192,18 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, idx2 = signature_ref_index_at(idx); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); - DBG(printf("JVM_CONSTANT_NameAndType: %hd %hd", idx1, idx2)); break; } case JVM_CONSTANT_ClassIndex: { *bytes = JVM_CONSTANT_Class; idx1 = checked_cast(klass_index_at(idx)); Bytes::put_Java_u2((address) (bytes+1), idx1); - DBG(printf("JVM_CONSTANT_ClassIndex: %hd", idx1)); break; } case JVM_CONSTANT_StringIndex: { *bytes = JVM_CONSTANT_String; idx1 = checked_cast(string_index_at(idx)); Bytes::put_Java_u2((address) (bytes+1), idx1); - DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1)); break; } case JVM_CONSTANT_MethodHandle: @@ -2386,7 +2213,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, idx1 = checked_cast(method_handle_index_at(idx)); *(bytes+1) = (unsigned char) kind; Bytes::put_Java_u2((address) (bytes+2), idx1); - DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); break; } case JVM_CONSTANT_MethodType: @@ -2394,7 +2220,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, *bytes = JVM_CONSTANT_MethodType; idx1 = checked_cast(method_type_index_at(idx)); Bytes::put_Java_u2((address) (bytes+1), idx1); - DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); break; } case JVM_CONSTANT_Dynamic: @@ -2405,7 +2230,6 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, assert(idx2 == bootstrap_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); - DBG(printf("JVM_CONSTANT_Dynamic: %hd %hd", idx1, idx2)); break; } case JVM_CONSTANT_InvokeDynamic: { @@ -2415,23 +2239,17 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, assert(idx2 == bootstrap_name_and_type_ref_index_at(idx), "correct half of u4"); Bytes::put_Java_u2((address) (bytes+1), idx1); Bytes::put_Java_u2((address) (bytes+3), idx2); - DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); break; } } - DBG(printf("\n")); bytes += ent_size; size += ent_size; } assert(size == cpool_size, "Size mismatch"); - // Keep temporarily for debugging until it's stable. - DBG(print_cpool_bytes(cnt, start_bytes)); return (int)(bytes - start_bytes); } /* end copy_cpool_bytes */ -#undef DBG - bool ConstantPool::is_maybe_on_stack() const { // This method uses the similar logic as nmethod::is_maybe_on_stack() if (!Continuations::enabled()) { diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp index 935151c7cda7d..4457f8a84e7c8 100644 --- a/src/hotspot/share/oops/constantPool.hpp +++ b/src/hotspot/share/oops/constantPool.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -684,7 +684,6 @@ class ConstantPool : public Metadata { #if INCLUDE_CDS // CDS support objArrayOop prepare_resolved_references_for_archiving() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - void find_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; void add_dumped_interned_strings() NOT_CDS_JAVA_HEAP_RETURN; void remove_unshareable_info(); void restore_unshareable_info(TRAPS); diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 66650ee65bf56..f4c53c0089e62 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" @@ -409,6 +408,17 @@ void ConstantPoolCache::remove_unshareable_info() { if (_resolved_method_entries != nullptr) { remove_resolved_method_entries_if_non_deterministic(); } + +#if INCLUDE_CDS_JAVA_HEAP + _archived_references_index = -1; + if (CDSConfig::is_dumping_heap()) { + ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(constant_pool()); + oop rr = HeapShared::scratch_resolved_references(src_cp); + if (rr != nullptr) { + _archived_references_index = HeapShared::append_root(rr); + } + } +#endif } void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() { @@ -610,11 +620,6 @@ void ConstantPoolCache::clear_archived_references() { _archived_references_index = -1; } } - -void ConstantPoolCache::set_archived_references(int root_index) { - assert(CDSConfig::is_dumping_heap(), "sanity"); - _archived_references_index = root_index; -} #endif #if INCLUDE_JVMTI diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp index 8652409a1a446..6490a012e9aeb 100644 --- a/src/hotspot/share/oops/cpCache.hpp +++ b/src/hotspot/share/oops/cpCache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,7 +110,6 @@ class ConstantPoolCache: public MetaspaceObj { MetaspaceObj::Type type() const { return ConstantPoolCacheType; } oop archived_references() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - void set_archived_references(int root_index) NOT_CDS_JAVA_HEAP_RETURN; void clear_archived_references() NOT_CDS_JAVA_HEAP_RETURN; inline objArrayOop resolved_references(); diff --git a/src/hotspot/share/oops/fieldInfo.cpp b/src/hotspot/share/oops/fieldInfo.cpp index 50a3b427d178e..300b45277ada6 100644 --- a/src/hotspot/share/oops/fieldInfo.cpp +++ b/src/hotspot/share/oops/fieldInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/fieldInfo.inline.hpp" #include "runtime/atomic.hpp" @@ -34,7 +33,7 @@ void FieldInfo::print(outputStream* os, ConstantPool* cp) { name_index(), name(cp)->as_utf8(), signature_index(), signature(cp)->as_utf8(), offset(), - access_flags().as_int(), + access_flags().as_field_flags(), field_flags().as_uint(), initializer_index(), generic_signature_index(), @@ -97,7 +96,7 @@ Array* FieldInfoStream::create_FieldInfoStream(GrowableArray* fie assert(fi_ref->name_index() == fi.name_index(), "Must be"); assert(fi_ref->signature_index() == fi.signature_index(), "Must be"); assert(fi_ref->offset() == fi.offset(), "Must be"); - assert(fi_ref->access_flags().as_int() == fi.access_flags().as_int(), "Must be"); + assert(fi_ref->access_flags().as_field_flags() == fi.access_flags().as_field_flags(), "Must be"); assert(fi_ref->field_flags().as_uint() == fi.field_flags().as_uint(), " Must be"); if(fi_ref->field_flags().is_initialized()) { assert(fi_ref->initializer_index() == fi.initializer_index(), "Must be"); diff --git a/src/hotspot/share/oops/fieldInfo.inline.hpp b/src/hotspot/share/oops/fieldInfo.inline.hpp index 2e6727f1fb9f1..d3d4d765081d0 100644 --- a/src/hotspot/share/oops/fieldInfo.inline.hpp +++ b/src/hotspot/share/oops/fieldInfo.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ inline void Mapper::map_field_info(const FieldInfo& fi) { _consumer->accept_uint(fi.name_index()); _consumer->accept_uint(fi.signature_index()); _consumer->accept_uint(fi.offset()); - _consumer->accept_uint(fi.access_flags().as_int()); + _consumer->accept_uint(fi.access_flags().as_field_flags()); _consumer->accept_uint(fi.field_flags().as_uint()); if(fi.field_flags().has_any_optionals()) { if (fi.field_flags().is_initialized()) { @@ -102,7 +102,7 @@ inline void FieldInfoReader::read_field_info(FieldInfo& fi) { fi._name_index = checked_cast(next_uint()); fi._signature_index = checked_cast(next_uint()); fi._offset = next_uint(); - fi._access_flags = AccessFlags(next_uint()); + fi._access_flags = AccessFlags(checked_cast(next_uint())); fi._field_flags = FieldInfo::FieldFlags(next_uint()); if (fi._field_flags.is_initialized()) { fi._initializer_index = checked_cast(next_uint()); diff --git a/src/hotspot/share/oops/generateOopMap.cpp b/src/hotspot/share/oops/generateOopMap.cpp index 918e6969713c9..e3119a24cef44 100644 --- a/src/hotspot/share/oops/generateOopMap.cpp +++ b/src/hotspot/share/oops/generateOopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/bytecodeStream.hpp" #include "logging/log.hpp" diff --git a/src/hotspot/share/oops/instanceClassLoaderKlass.cpp b/src/hotspot/share/oops/instanceClassLoaderKlass.cpp index 386f0b457ef5c..982a715c32413 100644 --- a/src/hotspot/share/oops/instanceClassLoaderKlass.cpp +++ b/src/hotspot/share/oops/instanceClassLoaderKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "oops/instanceClassLoaderKlass.hpp" diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 5fd51ffd6b730..9e3f73596e27b 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/aotClassInitializer.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" @@ -212,8 +211,10 @@ bool InstanceKlass::has_nest_member(JavaThread* current, InstanceKlass* k) const return false; } -// Called to verify that k is a permitted subclass of this class -bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k) const { +// Called to verify that k is a permitted subclass of this class. +// The incoming stringStream is used to format the messages for error logging and for the caller +// to use for exception throwing. +bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k, stringStream& ss) const { Thread* current = Thread::current(); assert(k != nullptr, "sanity check"); assert(_permitted_subclasses != nullptr && _permitted_subclasses != Universe::the_empty_short_array(), @@ -221,22 +222,34 @@ bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k) const { if (log_is_enabled(Trace, class, sealed)) { ResourceMark rm(current); - log_trace(class, sealed)("Checking for permitted subclass of %s in %s", + log_trace(class, sealed)("Checking for permitted subclass %s in %s", k->external_name(), this->external_name()); } // Check that the class and its super are in the same module. if (k->module() != this->module()) { - ResourceMark rm(current); - log_trace(class, sealed)("Check failed for same module of permitted subclass %s and sealed class %s", - k->external_name(), this->external_name()); + ss.print("Failed same module check: subclass %s is in module '%s' with loader %s, " + "and sealed class %s is in module '%s' with loader %s", + k->external_name(), + k->module()->name_as_C_string(), + k->module()->loader_data()->loader_name_and_id(), + this->external_name(), + this->module()->name_as_C_string(), + this->module()->loader_data()->loader_name_and_id()); + log_trace(class, sealed)(" - %s", ss.as_string()); return false; } if (!k->is_public() && !is_same_class_package(k)) { - ResourceMark rm(current); - log_trace(class, sealed)("Check failed, subclass %s not public and not in the same package as sealed class %s", - k->external_name(), this->external_name()); + ss.print("Failed same package check: non-public subclass %s is in package '%s' with classloader %s, " + "and sealed class %s is in package '%s' with classloader %s", + k->external_name(), + k->package() != nullptr ? k->package()->name()->as_C_string() : "unnamed", + k->module()->loader_data()->loader_name_and_id(), + this->external_name(), + this->package() != nullptr ? this->package()->name()->as_C_string() : "unnamed", + this->module()->loader_data()->loader_name_and_id()); + log_trace(class, sealed)(" - %s", ss.as_string()); return false; } @@ -248,7 +261,10 @@ bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k) const { return true; } } - log_trace(class, sealed)("- class is NOT a permitted subclass!"); + + ss.print("Failed listed permitted subclass check: class %s is not a permitted subclass of %s", + k->external_name(), this->external_name()); + log_trace(class, sealed)(" - %s", ss.as_string()); return false; } @@ -3322,8 +3338,8 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA return outer_klass; } -jint InstanceKlass::compute_modifier_flags() const { - jint access = access_flags().as_int(); +u2 InstanceKlass::compute_modifier_flags() const { + u2 access = access_flags().as_unsigned_short(); // But check if it happens to be member class. InnerClassesIterator iter(this); @@ -3343,7 +3359,7 @@ jint InstanceKlass::compute_modifier_flags() const { } } // Remember to strip ACC_SUPER bit - return (access & (~JVM_ACC_SUPER)) & JVM_ACC_WRITTEN_FLAGS; + return (access & (~JVM_ACC_SUPER)); } jint InstanceKlass::jvmti_class_status() const { @@ -3637,7 +3653,7 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(" "); } } - if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize); + if (n >= MaxSubklassPrintSize) st->print("(%zd more klasses...)", n - MaxSubklassPrintSize); st->cr(); if (is_interface()) { @@ -3789,7 +3805,7 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) { } } - st->print_cr(BULLET"---- fields (total size " SIZE_FORMAT " words):", oop_size(obj)); + st->print_cr(BULLET"---- fields (total size %zu words):", oop_size(obj)); FieldPrinter print_field(st, obj); print_nonstatic_fields(&print_field); diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 13b50859ee366..cedc17e9bafde 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -391,7 +391,7 @@ class InstanceKlass: public Klass { public: int field_offset (int index) const { return field(index).offset(); } - int field_access_flags(int index) const { return field(index).access_flags().as_int(); } + int field_access_flags(int index) const { return field(index).access_flags().as_field_flags(); } FieldInfo::FieldFlags field_flags(int index) const { return field(index).field_flags(); } FieldStatus field_status(int index) const { return fields_status()->at(index); } inline Symbol* field_name (int index) const; @@ -456,8 +456,10 @@ class InstanceKlass: public Klass { // Check if this klass is a nestmate of k - resolves this nest-host and k's bool has_nestmate_access_to(InstanceKlass* k, TRAPS); - // Called to verify that k is a permitted subclass of this class - bool has_as_permitted_subclass(const InstanceKlass* k) const; + // Called to verify that k is a permitted subclass of this class. + // The incoming stringStream is used for logging, and for the caller to create + // a detailed exception message on failure. + bool has_as_permitted_subclass(const InstanceKlass* k, stringStream& ss) const; enum InnerClassAttributeOffset { // From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814 @@ -680,8 +682,6 @@ class InstanceKlass: public Klass { #if INCLUDE_JVMTI // Redefinition locking. Class can only be redefined by one thread at a time. - // The flag is in access_flags so that it can be set and reset using atomic - // operations, and not be reset by other misc_flag settings. bool is_being_redefined() const { return _misc_flags.is_being_redefined(); } void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); } @@ -1125,7 +1125,7 @@ class InstanceKlass: public Klass { void compute_has_loops_flag_for_methods(); #endif - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // JVMTI support diff --git a/src/hotspot/share/oops/instanceKlassFlags.cpp b/src/hotspot/share/oops/instanceKlassFlags.cpp index 864fe60af2ea3..8d2adfba9046a 100644 --- a/src/hotspot/share/oops/instanceKlassFlags.cpp +++ b/src/hotspot/share/oops/instanceKlassFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "oops/instanceKlassFlags.hpp" diff --git a/src/hotspot/share/oops/instanceMirrorKlass.cpp b/src/hotspot/share/oops/instanceMirrorKlass.cpp index a90c9284b1a9a..798d5115143e0 100644 --- a/src/hotspot/share/oops/instanceMirrorKlass.cpp +++ b/src/hotspot/share/oops/instanceMirrorKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/serializeClosure.hpp" #include "classfile/javaClasses.inline.hpp" @@ -54,7 +53,7 @@ size_t InstanceMirrorKlass::instance_size(Klass* k) { instanceOop InstanceMirrorKlass::allocate_instance(Klass* k, TRAPS) { // Query before forming handle. size_t size = instance_size(k); - assert(size > 0, "total object size must be non-zero: " SIZE_FORMAT, size); + assert(size > 0, "total object size must be non-zero: %zu", size); // Since mirrors can be variable sized because of the static fields, store // the size in the mirror itself. diff --git a/src/hotspot/share/oops/instanceOop.cpp b/src/hotspot/share/oops/instanceOop.cpp index 8f58feccec4d2..faba5d18acf51 100644 --- a/src/hotspot/share/oops/instanceOop.cpp +++ b/src/hotspot/share/oops/instanceOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/instanceOop.hpp" // <> diff --git a/src/hotspot/share/oops/instanceRefKlass.cpp b/src/hotspot/share/oops/instanceRefKlass.cpp index 1fea112dc8754..eb507495cf554 100644 --- a/src/hotspot/share/oops/instanceRefKlass.cpp +++ b/src/hotspot/share/oops/instanceRefKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classFileParser.hpp" #include "classfile/javaClasses.hpp" diff --git a/src/hotspot/share/oops/instanceStackChunkKlass.cpp b/src/hotspot/share/oops/instanceStackChunkKlass.cpp index 2b819b27f642e..bf08cfd25ab7d 100644 --- a/src/hotspot/share/oops/instanceStackChunkKlass.cpp +++ b/src/hotspot/share/oops/instanceStackChunkKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/serializeClosure.hpp" #include "classfile/vmClasses.hpp" diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 884816764a079..9f166e13751a7 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" #include "cds/heapShared.hpp" @@ -329,6 +328,12 @@ jint Klass::array_layout_helper(BasicType etype) { return lh; } +int Klass::modifier_flags() const { + int mods = java_lang_Class::modifiers(java_mirror()); + assert(mods == compute_modifier_flags(), "should be same"); + return mods; +} + bool Klass::can_be_primary_super_slow() const { if (super() == nullptr) return true; @@ -817,6 +822,19 @@ void Klass::remove_java_mirror() { ResourceMark rm; log_trace(cds, unshareable)("remove java_mirror: %s", external_name()); } + +#if INCLUDE_CDS_JAVA_HEAP + _archived_mirror_index = -1; + if (CDSConfig::is_dumping_heap()) { + Klass* src_k = ArchiveBuilder::current()->get_source_addr(this); + oop orig_mirror = src_k->java_mirror(); + oop scratch_mirror = HeapShared::scratch_java_mirror(orig_mirror); + if (scratch_mirror != nullptr) { + _archived_mirror_index = HeapShared::append_root(scratch_mirror); + } + } +#endif + // Just null out the mirror. The class_loader_data() no longer exists. clear_java_mirror_handle(); } @@ -900,12 +918,6 @@ void Klass::clear_archived_mirror_index() { } _archived_mirror_index = -1; } - -// No GC barrier -void Klass::set_archived_java_mirror(int mirror_index) { - assert(CDSConfig::is_dumping_heap(), "sanity"); - _archived_mirror_index = mirror_index; -} #endif // INCLUDE_CDS_JAVA_HEAP void Klass::check_array_allocation_length(int length, int max_length, TRAPS) { @@ -1305,7 +1317,7 @@ static void print_negative_lookup_stats(uintx bitmap, outputStream* st) { void Klass::print_secondary_supers_on(outputStream* st) const { if (secondary_supers() != nullptr) { st->print(" - "); st->print("%d elements;", _secondary_supers->length()); - st->print_cr(" bitmap: " UINTX_FORMAT_X_0 ";", _secondary_supers_bitmap); + st->print_cr(" bitmap: " UINTX_FORMAT_X_0, _secondary_supers_bitmap); if (_secondary_supers_bitmap != SECONDARY_SUPERS_BITMAP_EMPTY && _secondary_supers_bitmap != SECONDARY_SUPERS_BITMAP_FULL) { st->print(" - "); print_positive_lookup_stats(secondary_supers(), diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 2c75d6da3b8cb..e7631f9dfe346 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ class Klass : public Metadata { friend class JVMCIVMStructs; public: // Klass Kinds for all subclasses of Klass - enum KlassKind { + enum KlassKind : u2 { InstanceKlassKind, InstanceRefKlassKind, InstanceMirrorKlassKind, @@ -113,15 +113,17 @@ class Klass : public Metadata { // // Final note: This comes first, immediately after C++ vtable, // because it is frequently queried. - jint _layout_helper; + jint _layout_helper; // Klass kind used to resolve the runtime type of the instance. // - Used to implement devirtualized oop closure dispatching. // - Various type checking in the JVM const KlassKind _kind; - // Processed access flags, for use by Class.getModifiers. - jint _modifier_flags; + AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. + KlassFlags _misc_flags; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers // and _primary_supers all help make fast subtype checks. See big discussion @@ -157,26 +159,16 @@ class Klass : public Metadata { // Provide access the corresponding instance java.lang.ClassLoader. ClassLoaderData* _class_loader_data; + markWord _prototype_header; // Used to initialize objects' header + // Bitmap and hash code used by hashed secondary supers. uintx _secondary_supers_bitmap; uint8_t _hash_slot; - markWord _prototype_header; // Used to initialize objects' header - - int _vtable_len; // vtable length. This field may be read very often when we - // have lots of itable dispatches (e.g., lambdas and streams). - // Keep it away from the beginning of a Klass to avoid cacheline - // contention that may happen when a nearby object is modified. - AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. - // Some flags created by the JVM, not in the class file itself, - // are in _misc_flags below. - - JFR_ONLY(DEFINE_TRACE_ID_FIELD;) - private: - // This is an index into FileMapHeader::_shared_path_table[], to - // associate this class with the JAR file where it's loaded from during - // dump time. If a class is not loaded from the shared archive, this field is + // This is an index into AOTClassLocationConfig::class_locations(), to + // indicate the AOTClassLocation where this class is loaded from during + // dump time. If a class is not loaded from the AOT cache, this field is // -1. s2 _shared_class_path_index; @@ -200,10 +192,17 @@ class Klass : public Metadata { }; #endif - KlassFlags _misc_flags; + int _vtable_len; // vtable length. This field may be read very often when we + // have lots of itable dispatches (e.g., lambdas and streams). + // Keep it away from the beginning of a Klass to avoid cacheline + // contention that may happen when a nearby object is modified. CDS_JAVA_HEAP_ONLY(int _archived_mirror_index;) +public: + + JFR_ONLY(DEFINE_TRACE_ID_FIELD;) + protected: Klass(KlassKind kind); @@ -281,7 +280,6 @@ class Klass : public Metadata { void set_java_mirror(Handle m); oop archived_java_mirror() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - void set_archived_java_mirror(int mirror_index) NOT_CDS_JAVA_HEAP_RETURN; // Temporary mirror switch used by RedefineClasses OopHandle java_mirror_handle() const { return _java_mirror; } @@ -291,10 +289,6 @@ class Klass : public Metadata { // This leaves the OopHandle in the CLD, but that's ok, you can't release them. void clear_java_mirror_handle() { _java_mirror = OopHandle(); } - // modifier flags - jint modifier_flags() const { return _modifier_flags; } - void set_modifier_flags(jint flags) { _modifier_flags = flags; } - // size helper int layout_helper() const { return _layout_helper; } void set_layout_helper(int lh) { _layout_helper = lh; } @@ -447,7 +441,6 @@ class Klass : public Metadata { static ByteSize secondary_supers_offset() { return byte_offset_of(Klass, _secondary_supers); } static ByteSize java_mirror_offset() { return byte_offset_of(Klass, _java_mirror); } static ByteSize class_loader_data_offset() { return byte_offset_of(Klass, _class_loader_data); } - static ByteSize modifier_flags_offset() { return byte_offset_of(Klass, _modifier_flags); } static ByteSize layout_helper_offset() { return byte_offset_of(Klass, _layout_helper); } static ByteSize access_flags_offset() { return byte_offset_of(Klass, _access_flags); } #if INCLUDE_JVMCI @@ -756,7 +749,8 @@ class Klass : public Metadata { virtual void release_C_heap_structures(bool release_constant_pool = true); public: - virtual jint compute_modifier_flags() const = 0; + virtual u2 compute_modifier_flags() const = 0; + int modifier_flags() const; // JVMTI support virtual jint jvmti_class_status() const; diff --git a/src/hotspot/share/oops/klassFlags.cpp b/src/hotspot/share/oops/klassFlags.cpp index 6399762e8df56..e5d6d68901f2d 100644 --- a/src/hotspot/share/oops/klassFlags.cpp +++ b/src/hotspot/share/oops/klassFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/klassFlags.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/oops/klassVtable.cpp b/src/hotspot/share/oops/klassVtable.cpp index e1bffc90d5129..20a8063771d97 100644 --- a/src/hotspot/share/oops/klassVtable.cpp +++ b/src/hotspot/share/oops/klassVtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.hpp" diff --git a/src/hotspot/share/oops/markWord.cpp b/src/hotspot/share/oops/markWord.cpp index a9b1a7b026ac6..2ba57cddc67cd 100644 --- a/src/hotspot/share/oops/markWord.cpp +++ b/src/hotspot/share/oops/markWord.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/markWord.hpp" #include "runtime/basicLock.inline.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/oops/markWord.hpp b/src/hotspot/share/oops/markWord.hpp index 1e1b8d77a903f..9cb46f4697d19 100644 --- a/src/hotspot/share/oops/markWord.hpp +++ b/src/hotspot/share/oops/markWord.hpp @@ -188,7 +188,7 @@ class markWord { static markWord INFLATING() { return zero(); } // inflate-in-progress // Should this header be preserved during GC? - bool must_be_preserved(const oopDesc* obj) const { + bool must_be_preserved() const { return (!is_unlocked() || !has_no_hash()); } diff --git a/src/hotspot/share/oops/metadata.cpp b/src/hotspot/share/oops/metadata.cpp index 242fc89c4137e..be3b523c5d5b1 100644 --- a/src/hotspot/share/oops/metadata.cpp +++ b/src/hotspot/share/oops/metadata.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/metadata.hpp" #include "memory/resourceArea.hpp" #include "prims/jvmtiRedefineClasses.hpp" diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index d0b29a4a30992..1a3b908434f1d 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/cppVtables.hpp" #include "cds/metaspaceShared.hpp" @@ -1021,7 +1020,7 @@ void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report, } if ((TraceDeoptimization || LogCompilation) && (xtty != nullptr)) { ttyLocker ttyl; - xtty->begin_elem("make_not_compilable thread='" UINTX_FORMAT "' osr='%d' level='%d'", + xtty->begin_elem("make_not_compilable thread='%zu' osr='%d' level='%d'", os::current_thread_id(), is_osr, comp_level); if (reason != nullptr) { xtty->print(" reason=\'%s\'", reason); @@ -1435,7 +1434,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, cp->set_is_for_method_handle_intrinsic(); // decide on access bits: public or not? - int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL); + u2 flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL); bool must_be_static = MethodHandles::is_signature_polymorphic_static(iid); if (must_be_static) flags_bits |= JVM_ACC_STATIC; assert((flags_bits & JVM_ACC_PUBLIC) == 0, "do not expose these methods"); @@ -1652,8 +1651,8 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) { && sig_id == vmSymbolID::NO_SID) { return; } - jshort flags = access_flags().as_short(); + u2 flags = access_flags().as_method_flags(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); if (id != vmIntrinsics::_none) { set_intrinsic_id(id); @@ -1920,39 +1919,6 @@ void Method::clear_all_breakpoints() { #endif // INCLUDE_JVMTI -int Method::invocation_count() const { - MethodCounters* mcs = method_counters(); - MethodData* mdo = method_data(); - if (((mcs != nullptr) ? mcs->invocation_counter()->carry() : false) || - ((mdo != nullptr) ? mdo->invocation_counter()->carry() : false)) { - return InvocationCounter::count_limit; - } else { - return ((mcs != nullptr) ? mcs->invocation_counter()->count() : 0) + - ((mdo != nullptr) ? mdo->invocation_counter()->count() : 0); - } -} - -int Method::backedge_count() const { - MethodCounters* mcs = method_counters(); - MethodData* mdo = method_data(); - if (((mcs != nullptr) ? mcs->backedge_counter()->carry() : false) || - ((mdo != nullptr) ? mdo->backedge_counter()->carry() : false)) { - return InvocationCounter::count_limit; - } else { - return ((mcs != nullptr) ? mcs->backedge_counter()->count() : 0) + - ((mdo != nullptr) ? mdo->backedge_counter()->count() : 0); - } -} - -int Method::highest_comp_level() const { - const MethodCounters* mcs = method_counters(); - if (mcs != nullptr) { - return mcs->highest_comp_level(); - } else { - return CompLevel_none; - } -} - int Method::highest_osr_comp_level() const { const MethodCounters* mcs = method_counters(); if (mcs != nullptr) { @@ -2300,7 +2266,7 @@ void Method::print_on(outputStream* st) const { st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr(); st->print (" - constants: " PTR_FORMAT " ", p2i(constants())); constants()->print_value_on(st); st->cr(); - st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr(); + st->print (" - access: 0x%x ", access_flags().as_method_flags()); access_flags().print_on(st); st->cr(); st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr(); st->print (" - name: "); name()->print_value_on(st); st->cr(); st->print (" - signature: "); signature()->print_value_on(st); st->cr(); diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 271d8b3986378..5daa572a46ccf 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,8 +75,8 @@ class Method : public Metadata { MethodData* _method_data; MethodCounters* _method_counters; AdapterHandlerEntry* _adapter; - AccessFlags _access_flags; // Access flags int _vtable_index; // vtable index of this method (see VtableIndexFlag) + AccessFlags _access_flags; // Access flags MethodFlags _flags; u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) @@ -255,7 +255,7 @@ class Method : public Metadata { void set_deprecated_for_removal() { constMethod()->set_deprecated_for_removal(); } bool deprecated_for_removal() const { return constMethod()->deprecated_for_removal(); } - int highest_comp_level() const; + inline int highest_comp_level() const; void set_highest_comp_level(int level); int highest_osr_comp_level() const; void set_highest_osr_comp_level(int level); @@ -334,8 +334,8 @@ class Method : public Metadata { inline float rate() const; inline void set_rate(float rate); - int invocation_count() const; - int backedge_count() const; + inline int invocation_count() const; + inline int backedge_count() const; bool was_executed_more_than(int n); bool was_never_executed() { return !was_executed_more_than(0); } @@ -344,7 +344,7 @@ class Method : public Metadata { static MethodCounters* build_method_counters(Thread* current, Method* m); - int interpreter_invocation_count() { return invocation_count(); } + inline int interpreter_invocation_count() const; #ifndef PRODUCT int64_t compiled_invocation_count() const { return _compiled_invocation_count;} diff --git a/src/hotspot/share/oops/method.inline.hpp b/src/hotspot/share/oops/method.inline.hpp index f27834de30b68..18fca354b6b66 100644 --- a/src/hotspot/share/oops/method.inline.hpp +++ b/src/hotspot/share/oops/method.inline.hpp @@ -28,7 +28,9 @@ #include "oops/method.hpp" #include "classfile/vmIntrinsics.hpp" +#include "code/nmethod.inline.hpp" #include "oops/methodCounters.hpp" +#include "oops/methodData.inline.hpp" #include "runtime/atomic.hpp" inline address Method::from_compiled_entry() const { @@ -188,4 +190,41 @@ inline void Method::set_rate(float rate) { } } +inline int Method::invocation_count() const { + MethodCounters* mcs = method_counters(); + MethodData* mdo = method_data(); + if (((mcs != nullptr) ? mcs->invocation_counter()->carry() : false) || + ((mdo != nullptr) ? mdo->invocation_counter()->carry() : false)) { + return InvocationCounter::count_limit; + } else { + return ((mcs != nullptr) ? mcs->invocation_counter()->count() : 0) + + ((mdo != nullptr) ? mdo->invocation_counter()->count() : 0); + } +} + +inline int Method::backedge_count() const { + MethodCounters* mcs = method_counters(); + MethodData* mdo = method_data(); + if (((mcs != nullptr) ? mcs->backedge_counter()->carry() : false) || + ((mdo != nullptr) ? mdo->backedge_counter()->carry() : false)) { + return InvocationCounter::count_limit; + } else { + return ((mcs != nullptr) ? mcs->backedge_counter()->count() : 0) + + ((mdo != nullptr) ? mdo->backedge_counter()->count() : 0); + } +} + +inline int Method::highest_comp_level() const { + const MethodCounters* mcs = method_counters(); + if (mcs != nullptr) { + return mcs->highest_comp_level(); + } else { + return CompLevel_none; + } +} + +inline int Method::interpreter_invocation_count() const { + return invocation_count(); +} + #endif // SHARE_OOPS_METHOD_INLINE_HPP diff --git a/src/hotspot/share/oops/methodCounters.cpp b/src/hotspot/share/oops/methodCounters.cpp index 93fd7e65c6bcd..4abf9ba53e7f9 100644 --- a/src/hotspot/share/oops/methodCounters.cpp +++ b/src/hotspot/share/oops/methodCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compiler_globals.hpp" #include "compiler/compilerOracle.hpp" #include "oops/method.hpp" diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 3c0c0b5468971..2d366168f08c6 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compilationPolicy.hpp" @@ -34,6 +33,7 @@ #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "oops/klass.inline.hpp" +#include "oops/method.inline.hpp" #include "oops/methodData.inline.hpp" #include "prims/jvmtiRedefineClasses.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/oops/methodFlags.cpp b/src/hotspot/share/oops/methodFlags.cpp index 4945dcc4b8396..ae73726b26845 100644 --- a/src/hotspot/share/oops/methodFlags.cpp +++ b/src/hotspot/share/oops/methodFlags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/methodFlags.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 04bc374e5226c..7af6b963052f1 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "classfile/symbolTable.hpp" @@ -140,9 +139,6 @@ ObjArrayKlass::ObjArrayKlass(int n, Klass* element_klass, Symbol* name) : ArrayK set_layout_helper(array_layout_helper(T_OBJECT)); assert(is_array_klass(), "sanity"); assert(is_objArray_klass(), "sanity"); - - // Compute modifier flags after bottom_klass and element_klass are initialized. - set_modifier_flags(compute_modifier_flags()); } size_t ObjArrayKlass::oop_size(oop obj) const { @@ -341,12 +337,12 @@ void ObjArrayKlass::metaspace_pointers_do(MetaspaceClosure* it) { it->push(&_bottom_klass); } -jint ObjArrayKlass::compute_modifier_flags() const { +u2 ObjArrayKlass::compute_modifier_flags() const { // The modifier for an objectArray is the same as its element assert (element_klass() != nullptr, "should be initialized"); // Return the flags of the bottom element type. - jint element_flags = bottom_klass()->compute_modifier_flags(); + u2 element_flags = bottom_klass()->compute_modifier_flags(); return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED)) | (JVM_ACC_ABSTRACT | JVM_ACC_FINAL); diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index e16f1f2eb0fcd..c44c8d28f6247 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,7 @@ class ObjArrayKlass : public ArrayKlass { inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high); public: - jint compute_modifier_flags() const; + u2 compute_modifier_flags() const; public: // Printing diff --git a/src/hotspot/share/oops/objArrayOop.cpp b/src/hotspot/share/oops/objArrayOop.cpp index 18a93fb54834d..363f6710da85f 100644 --- a/src/hotspot/share/oops/objArrayOop.cpp +++ b/src/hotspot/share/oops/objArrayOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/access.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" diff --git a/src/hotspot/share/oops/objLayout.cpp b/src/hotspot/share/oops/objLayout.cpp index 3d18d319ed209..774fe24d376e8 100644 --- a/src/hotspot/share/oops/objLayout.cpp +++ b/src/hotspot/share/oops/objLayout.cpp @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "oops/markWord.hpp" #include "oops/objLayout.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index 11cab4c043b5c..7f0068f747343 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "classfile/altHashing.hpp" #include "classfile/javaClasses.inline.hpp" diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index 45902e63147bd..3dad778a73a47 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -220,8 +220,8 @@ size_t oopDesc::size_given_klass(Klass* klass) { } } - assert(s > 0, "Oop size must be greater than zero, not " SIZE_FORMAT, s); - assert(is_object_aligned(s), "Oop size is not properly aligned: " SIZE_FORMAT, s); + assert(s > 0, "Oop size must be greater than zero, not %zu", s); + assert(is_object_aligned(s), "Oop size is not properly aligned: %zu", s); return s; } @@ -452,7 +452,7 @@ bool oopDesc::mark_must_be_preserved() const { } bool oopDesc::mark_must_be_preserved(markWord m) const { - return m.must_be_preserved(this); + return m.must_be_preserved(); } #endif // SHARE_OOPS_OOP_INLINE_HPP diff --git a/src/hotspot/share/oops/oopHandle.inline.hpp b/src/hotspot/share/oops/oopHandle.inline.hpp index 06acd2912745c..be5078704a4dc 100644 --- a/src/hotspot/share/oops/oopHandle.inline.hpp +++ b/src/hotspot/share/oops/oopHandle.inline.hpp @@ -31,11 +31,23 @@ #include "gc/shared/oopStorage.inline.hpp" inline oop OopHandle::resolve() const { - return (_obj == nullptr) ? (oop)nullptr : NativeAccess<>::oop_load(_obj); + if (_obj == nullptr) { + return (oop) nullptr; + } else { + oop oop = NativeAccess<>::oop_load(_obj); + assert(oopDesc::is_oop_or_null(oop), "Should be oop: " PTR_FORMAT, p2i(oop)); + return oop; + } } inline oop OopHandle::peek() const { - return (_obj == nullptr) ? (oop)nullptr : NativeAccess::oop_load(_obj); + if (_obj == nullptr) { + return (oop) nullptr; + } else { + oop obj = NativeAccess::oop_load(_obj); + assert(oopDesc::is_oop_or_null(obj), "Should be oop: " PTR_FORMAT, p2i(obj)); + return obj; + } } inline OopHandle::OopHandle(OopStorage* storage, oop obj) : @@ -44,6 +56,7 @@ inline OopHandle::OopHandle(OopStorage* storage, oop obj) : vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR, "Cannot create oop handle"); } + assert(oopDesc::is_oop_or_null(obj), "Should be oop: " PTR_FORMAT, p2i(obj)); NativeAccess<>::oop_store(_obj, obj); } @@ -58,15 +71,22 @@ inline void OopHandle::release(OopStorage* storage) { inline void OopHandle::replace(oop obj) { assert(!is_empty(), "should not use replace"); + assert(oopDesc::is_oop_or_null(obj), "Should be oop: " PTR_FORMAT, p2i(obj)); NativeAccess<>::oop_store(_obj, obj); } inline oop OopHandle::xchg(oop new_value) { - return NativeAccess::oop_atomic_xchg(_obj, new_value); + assert(oopDesc::is_oop_or_null(new_value), "Should be oop: " PTR_FORMAT, p2i(new_value)); + oop obj = NativeAccess::oop_atomic_xchg(_obj, new_value); + assert(oopDesc::is_oop_or_null(obj), "Should be oop: " PTR_FORMAT, p2i(obj)); + return obj; } inline oop OopHandle::cmpxchg(oop old_value, oop new_value) { - return NativeAccess::oop_atomic_cmpxchg(_obj, old_value, new_value); + assert(oopDesc::is_oop_or_null(new_value), "Should be oop: " PTR_FORMAT, p2i(new_value)); + oop obj = NativeAccess::oop_atomic_cmpxchg(_obj, old_value, new_value); + assert(oopDesc::is_oop_or_null(obj), "Should be oop: " PTR_FORMAT, p2i(obj)); + return obj; } #endif // SHARE_OOPS_OOPHANDLE_INLINE_HPP diff --git a/src/hotspot/share/oops/oopsHierarchy.cpp b/src/hotspot/share/oops/oopsHierarchy.cpp index 21260f5b1c99e..a62d37ce2ba31 100644 --- a/src/hotspot/share/oops/oopsHierarchy.cpp +++ b/src/hotspot/share/oops/oopsHierarchy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/universe.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/javaThread.hpp" diff --git a/src/hotspot/share/oops/recordComponent.cpp b/src/hotspot/share/oops/recordComponent.cpp index 5007bebfb9b59..176e83820e473 100644 --- a/src/hotspot/share/oops/recordComponent.cpp +++ b/src/hotspot/share/oops/recordComponent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "logging/log.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" diff --git a/src/hotspot/share/oops/resolvedFieldEntry.cpp b/src/hotspot/share/oops/resolvedFieldEntry.cpp index 8324325130696..dd0a81ce0f3cb 100644 --- a/src/hotspot/share/oops/resolvedFieldEntry.cpp +++ b/src/hotspot/share/oops/resolvedFieldEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "oops/resolvedFieldEntry.hpp" diff --git a/src/hotspot/share/oops/resolvedIndyEntry.cpp b/src/hotspot/share/oops/resolvedIndyEntry.cpp index 93ba3d6916c3e..09060596caae2 100644 --- a/src/hotspot/share/oops/resolvedIndyEntry.cpp +++ b/src/hotspot/share/oops/resolvedIndyEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "code/compressedStream.hpp" #include "oops/method.hpp" diff --git a/src/hotspot/share/oops/resolvedMethodEntry.cpp b/src/hotspot/share/oops/resolvedMethodEntry.cpp index 9564dbbcdc4b5..2dc533dbee00a 100644 --- a/src/hotspot/share/oops/resolvedMethodEntry.cpp +++ b/src/hotspot/share/oops/resolvedMethodEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "oops/method.hpp" #include "oops/resolvedMethodEntry.hpp" diff --git a/src/hotspot/share/oops/stackChunkOop.cpp b/src/hotspot/share/oops/stackChunkOop.cpp index 7319e93b6679c..13a94d65f8ebe 100644 --- a/src/hotspot/share/oops/stackChunkOop.cpp +++ b/src/hotspot/share/oops/stackChunkOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "code/scopeDesc.hpp" #include "gc/shared/barrierSet.hpp" @@ -497,7 +496,7 @@ class StackChunkVerifyOopsClosure : public OopClosure { assert(obj == nullptr || dbg_is_good_oop(obj), "p: " PTR_FORMAT " obj: " PTR_FORMAT, p2i(p), p2i(obj)); if (_chunk->has_bitmap()) { BitMap::idx_t index = _chunk->bit_index_for(p); - assert(_chunk->bitmap().at(index), "Bit not set at index " SIZE_FORMAT " corresponding to " PTR_FORMAT, index, p2i(p)); + assert(_chunk->bitmap().at(index), "Bit not set at index %zu corresponding to " PTR_FORMAT, index, p2i(p)); } } @@ -582,7 +581,7 @@ class StackChunkVerifyBitmapClosure : public BitMapClosure { oop obj = _chunk->load_oop(p); assert(obj == nullptr || dbg_is_good_oop(obj), - "p: " PTR_FORMAT " obj: " PTR_FORMAT " index: " SIZE_FORMAT, + "p: " PTR_FORMAT " obj: " PTR_FORMAT " index: %zu", p2i(p), p2i((oopDesc*)obj), index); return true; // continue processing diff --git a/src/hotspot/share/oops/symbol.cpp b/src/hotspot/share/oops/symbol.cpp index 276a201824117..4fc120ff19fca 100644 --- a/src/hotspot/share/oops/symbol.cpp +++ b/src/hotspot/share/oops/symbol.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/archiveBuilder.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/altHashing.hpp" diff --git a/src/hotspot/share/oops/symbolHandle.cpp b/src/hotspot/share/oops/symbolHandle.cpp index 350f0dd96c863..0ed441ebb0feb 100644 --- a/src/hotspot/share/oops/symbolHandle.cpp +++ b/src/hotspot/share/oops/symbolHandle.cpp @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "oops/symbolHandle.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 8ca6a49fc46a4..39385bb0184e7 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "classfile/symbolTable.hpp" @@ -75,7 +74,7 @@ TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType return new (loader_data, size, THREAD) TypeArrayKlass(type, name); } -jint TypeArrayKlass::compute_modifier_flags() const { +u2 TypeArrayKlass::compute_modifier_flags() const { return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; } @@ -88,9 +87,6 @@ TypeArrayKlass::TypeArrayKlass(BasicType type, Symbol* name) : ArrayKlass(name, assert(size() >= TypeArrayKlass::header_size(), "bad size"); set_class_loader_data(ClassLoaderData::the_null_class_loader_data()); - - // Compute modifier flags. - set_modifier_flags(compute_modifier_flags()); } typeArrayOop TypeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) { diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 9dc3ed607fe3a..fa4e301e3e446 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,8 @@ class TypeArrayKlass : public ArrayKlass { jint max_length() { return _max_length; } void set_max_length(jint m) { _max_length = m; } + u2 compute_modifier_flags() const; + // testers DEBUG_ONLY(bool is_typeArray_klass_slow() const { return true; }) @@ -73,8 +75,6 @@ class TypeArrayKlass : public ArrayKlass { // Copying void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); - jint compute_modifier_flags() const; - // Oop iterators. Since there are no oops in TypeArrayKlasses, // these functions only return the size of the object. diff --git a/src/hotspot/share/oops/weakHandle.cpp b/src/hotspot/share/oops/weakHandle.cpp index 9671ad97bbea0..36241689bbb34 100644 --- a/src/hotspot/share/oops/weakHandle.cpp +++ b/src/hotspot/share/oops/weakHandle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/oopStorage.hpp" #include "oops/access.inline.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index b44aa53f298c4..8406fe8b69ea0 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/castnode.hpp" @@ -33,6 +32,7 @@ #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" #include "opto/subnode.hpp" +#include "runtime/stubRoutines.hpp" // Portions of code courtesy of Clifford Click @@ -395,159 +395,9 @@ Node* AddNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) { } } - // Convert a + a + ... + a into a*n - Node* serial_additions = convert_serial_additions(phase, bt); - if (serial_additions != nullptr) { - return serial_additions; - } - return AddNode::Ideal(phase, can_reshape); } -// Try to convert a serial of additions into a single multiplication. Also convert `(a * CON) + a` to `(CON + 1) * a` as -// a side effect. On success, a new MulNode is returned. -Node* AddNode::convert_serial_additions(PhaseGVN* phase, BasicType bt) { - // We need to make sure that the current AddNode is not part of a MulNode that has already been optimized to a - // power-of-2 addition (e.g., 3 * a => (a << 2) + a). Without this check, GVN would keep trying to optimize the same - // node and can't progress. For example, 3 * a => (a << 2) + a => 3 * a => (a << 2) + a => ... - if (find_power_of_two_addition_pattern(this, bt, nullptr) != nullptr) { - return nullptr; - } - - Node* in1 = in(1); - Node* in2 = in(2); - jlong multiplier; - - // While multiplications can be potentially optimized to power-of-2 subtractions (e.g., a * 7 => (a << 3) - a), - // (x - y) + y => x is already handled by the Identity() methods. So, we don't need to check for that pattern here. - if (find_simple_addition_pattern(in1, bt, &multiplier) == in2 - || find_simple_lshift_pattern(in1, bt, &multiplier) == in2 - || find_simple_multiplication_pattern(in1, bt, &multiplier) == in2 - || find_power_of_two_addition_pattern(in1, bt, &multiplier) == in2) { - multiplier++; // +1 for the in2 term - - Node* con = (bt == T_INT) - ? (Node*) phase->intcon((jint) multiplier) // intentional type narrowing to allow overflow at max_jint - : (Node*) phase->longcon(multiplier); - return MulNode::make(con, in2, bt); - } - - return nullptr; -} - -// Try to match `a + a`. On success, return `a` and set `2` as `multiplier`. -// The method matches `n` for pattern: AddNode(a, a). -Node* AddNode::find_simple_addition_pattern(Node* n, BasicType bt, jlong* multiplier) { - if (n->Opcode() == Op_Add(bt) && n->in(1) == n->in(2)) { - *multiplier = 2; - return n->in(1); - } - - return nullptr; -} - -// Try to match `a << CON`. On success, return `a` and set `1 << CON` as `multiplier`. -// Match `n` for pattern: LShiftNode(a, CON). -// Note that the power-of-2 multiplication optimization could potentially convert a MulNode to this pattern. -Node* AddNode::find_simple_lshift_pattern(Node* n, BasicType bt, jlong* multiplier) { - // Note that power-of-2 multiplication optimization could potentially convert a MulNode to this pattern - if (n->Opcode() == Op_LShift(bt) && n->in(2)->is_Con()) { - Node* con = n->in(2); - if (con->is_top()) { - return nullptr; - } - - *multiplier = ((jlong) 1 << con->get_int()); - return n->in(1); - } - - return nullptr; -} - -// Try to match `CON * a`. On success, return `a` and set `CON` as `multiplier`. -// Match `n` for patterns: -// - MulNode(CON, a) -// - MulNode(a, CON) -Node* AddNode::find_simple_multiplication_pattern(Node* n, BasicType bt, jlong* multiplier) { - // This optimization technically only produces MulNode(CON, a), but we might as match MulNode(a, CON), too. - if (n->Opcode() == Op_Mul(bt) && (n->in(1)->is_Con() || n->in(2)->is_Con())) { - Node* con = n->in(1); - Node* base = n->in(2); - - // swap ConNode to lhs for easier matching - if (!con->is_Con()) { - swap(con, base); - } - - if (con->is_top()) { - return nullptr; - } - - *multiplier = con->get_integer_as_long(bt); - return base; - } - - return nullptr; -} - -// Try to match `(a << CON1) + (a << CON2)`. On success, return `a` and set `(1 << CON1) + (1 << CON2)` as `multiplier`. -// Match `n` for patterns: -// - AddNode(LShiftNode(a, CON), LShiftNode(a, CON)/a) -// - AddNode(LShiftNode(a, CON)/a, LShiftNode(a, CON)) -// given that lhs is different from rhs. -// Note that one of the term of the addition could simply be `a` (i.e., a << 0). Calling this function with `multiplier` -// being null is safe. -Node* AddNode::find_power_of_two_addition_pattern(Node* n, BasicType bt, jlong* multiplier) { - if (n->Opcode() == Op_Add(bt) && n->in(1) != n->in(2)) { - Node* lhs = n->in(1); - Node* rhs = n->in(2); - - // swap LShiftNode to lhs for easier matching - if (lhs->Opcode() != Op_LShift(bt)) { - swap(lhs, rhs); - } - - // AddNode(LShiftNode(a, CON), *)? - if (lhs->Opcode() != Op_LShift(bt) || !lhs->in(2)->is_Con()) { - return nullptr; - } - - jlong lhs_multiplier = 0; - if (multiplier != nullptr) { - Node* con = lhs->in(2); - if (con->is_top()) { - return nullptr; - } - - lhs_multiplier = (jlong) 1 << con->get_int(); - } - - // AddNode(LShiftNode(a, CON), a)? - if (lhs->in(1) == rhs) { - if (multiplier != nullptr) { - *multiplier = lhs_multiplier + 1; - } - - return rhs; - } - - // AddNode(LShiftNode(a, CON), LShiftNode(a, CON2))? - if (rhs->Opcode() == Op_LShift(bt) && lhs->in(1) == rhs->in(1) && rhs->in(2)->is_Con()) { - if (multiplier != nullptr) { - Node* con = rhs->in(2); - if (con->is_top()) { - return nullptr; - } - - *multiplier = lhs_multiplier + ((jlong) 1 << con->get_int()); - } - - return lhs->in(1); - } - return nullptr; - } - return nullptr; -} Node* AddINode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* in1 = in(1); @@ -706,6 +556,22 @@ Node *AddFNode::Ideal(PhaseGVN *phase, bool can_reshape) { return commute(phase, this) ? this : nullptr; } +//============================================================================= +//------------------------------add_of_identity-------------------------------- +// Check for addition of the identity +const Type* AddHFNode::add_of_identity(const Type* t1, const Type* t2) const { + return nullptr; +} + +// Supplied function returns the sum of the inputs. +// This also type-checks the inputs for sanity. Guaranteed never to +// be passed a TOP or BOTTOM type, these are filtered out by pre-check. +const Type* AddHFNode::add_ring(const Type* t0, const Type* t1) const { + if (!t0->isa_half_float_constant() || !t1->isa_half_float_constant()) { + return bottom_type(); + } + return TypeH::make(t0->getf() + t1->getf()); +} //============================================================================= //------------------------------add_of_identity-------------------------------- @@ -1270,7 +1136,7 @@ Node* MaxNode::build_min_max(Node* a, Node* b, bool is_max, bool is_unsigned, co cmp = gvn.transform(CmpNode::make(b, a, bt, is_unsigned)); } Node* bol = gvn.transform(new BoolNode(cmp, BoolTest::lt)); - res = gvn.transform(CMoveNode::make(nullptr, bol, a, b, t)); + res = gvn.transform(CMoveNode::make(bol, a, b, t)); } if (hook != nullptr) { hook->destruct(&gvn); @@ -1299,7 +1165,7 @@ Node* MaxNode::build_min_max_diff_with_zero(Node* a, Node* b, bool is_max, const } Node* sub = gvn.transform(SubNode::make(a, b, bt)); Node* bol = gvn.transform(new BoolNode(cmp, BoolTest::lt)); - Node* res = gvn.transform(CMoveNode::make(nullptr, bol, sub, zero, t)); + Node* res = gvn.transform(CMoveNode::make(bol, sub, zero, t)); if (hook != nullptr) { hook->destruct(&gvn); } @@ -1655,6 +1521,33 @@ Node* MaxNode::Identity(PhaseGVN* phase) { return AddNode::Identity(phase); } +//------------------------------add_ring--------------------------------------- +const Type* MinHFNode::add_ring(const Type* t0, const Type* t1) const { + const TypeH* r0 = t0->isa_half_float_constant(); + const TypeH* r1 = t1->isa_half_float_constant(); + if (r0 == nullptr || r1 == nullptr) { + return bottom_type(); + } + + if (r0->is_nan()) { + return r0; + } + if (r1->is_nan()) { + return r1; + } + + float f0 = r0->getf(); + float f1 = r1->getf(); + if (f0 != 0.0f || f1 != 0.0f) { + return f0 < f1 ? r0 : r1; + } + + // As per IEEE 754 specification, floating point comparison consider +ve and -ve + // zeros as equals. Thus, performing signed integral comparison for min value + // detection. + return (jint_cast(f0) < jint_cast(f1)) ? r0 : r1; +} + //------------------------------add_ring--------------------------------------- const Type* MinFNode::add_ring(const Type* t0, const Type* t1 ) const { const TypeF* r0 = t0->isa_float_constant(); @@ -1705,6 +1598,34 @@ const Type* MinDNode::add_ring(const Type* t0, const Type* t1) const { return (jlong_cast(d0) < jlong_cast(d1)) ? r0 : r1; } +//------------------------------add_ring--------------------------------------- +const Type* MaxHFNode::add_ring(const Type* t0, const Type* t1) const { + const TypeH* r0 = t0->isa_half_float_constant(); + const TypeH* r1 = t1->isa_half_float_constant(); + if (r0 == nullptr || r1 == nullptr) { + return bottom_type(); + } + + if (r0->is_nan()) { + return r0; + } + if (r1->is_nan()) { + return r1; + } + + float f0 = r0->getf(); + float f1 = r1->getf(); + if (f0 != 0.0f || f1 != 0.0f) { + return f0 > f1 ? r0 : r1; + } + + // As per IEEE 754 specification, floating point comparison consider +ve and -ve + // zeros as equals. Thus, performing signed integral comparison for max value + // detection. + return (jint_cast(f0) > jint_cast(f1)) ? r0 : r1; +} + + //------------------------------add_ring--------------------------------------- const Type* MaxFNode::add_ring(const Type* t0, const Type* t1) const { const TypeF* r0 = t0->isa_float_constant(); diff --git a/src/hotspot/share/opto/addnode.hpp b/src/hotspot/share/opto/addnode.hpp index 0a2c42b7796d0..456a8d9f9a031 100644 --- a/src/hotspot/share/opto/addnode.hpp +++ b/src/hotspot/share/opto/addnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,13 +42,6 @@ typedef const Pair ConstAddOperands; // by virtual functions. class AddNode : public Node { virtual uint hash() const; - - Node* convert_serial_additions(PhaseGVN* phase, BasicType bt); - static Node* find_simple_addition_pattern(Node* n, BasicType bt, jlong* multiplier); - static Node* find_simple_lshift_pattern(Node* n, BasicType bt, jlong* multiplier); - static Node* find_simple_multiplication_pattern(Node* n, BasicType bt, jlong* multiplier); - static Node* find_power_of_two_addition_pattern(Node* n, BasicType bt, jlong* multiplier); - public: AddNode( Node *in1, Node *in2 ) : Node(nullptr,in1,in2) { init_class_id(Class_Add); @@ -162,6 +155,22 @@ class AddDNode : public AddNode { virtual uint ideal_reg() const { return Op_RegD; } }; +//------------------------------AddHFNode--------------------------------------- +// Add 2 half-precision floats +class AddHFNode : public AddNode { +public: + AddHFNode(Node* in1, Node* in2) : AddNode(in1,in2) {} + virtual int Opcode() const; + virtual const Type* add_of_identity(const Type* t1, const Type* t2) const; + virtual const Type* add_ring(const Type*, const Type*) const; + virtual const Type* add_id() const { return TypeH::ZERO; } + virtual const Type* bottom_type() const { return Type::HALF_FLOAT; } + int max_opcode() const { return Op_MaxHF; } + int min_opcode() const { return Op_MinHF; } + virtual Node* Identity(PhaseGVN* phase) { return this; } + virtual uint ideal_reg() const { return Op_RegF; } +}; + //------------------------------AddPNode--------------------------------------- // Add pointer plus integer to get pointer. NOT commutative, really. // So not really an AddNode. Lives here, because people associate it with @@ -409,6 +418,34 @@ class MinFNode : public MaxNode { int min_opcode() const { return Op_MinF; } }; +//------------------------------MaxHFNode-------------------------------------- +// Maximum of 2 half floats. +class MaxHFNode : public MaxNode { +public: + MaxHFNode(Node* in1, Node* in2) : MaxNode(in1, in2) {} + virtual int Opcode() const; + virtual const Type* add_ring(const Type*, const Type*) const; + virtual const Type* add_id() const { return TypeH::NEG_INF; } + virtual const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + int max_opcode() const { return Op_MaxHF; } + int min_opcode() const { return Op_MinHF; } +}; + +//------------------------------MinHFNode--------------------------------------- +// Minimum of 2 half floats. +class MinHFNode : public MaxNode { +public: + MinHFNode(Node* in1, Node* in2) : MaxNode(in1, in2) {} + virtual int Opcode() const; + virtual const Type* add_ring(const Type*, const Type*) const; + virtual const Type* add_id() const { return TypeH::POS_INF; } + virtual const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + int max_opcode() const { return Op_MaxHF; } + int min_opcode() const { return Op_MinHF; } +}; + //------------------------------MaxDNode--------------------------------------- // Maximum of 2 doubles. class MaxDNode : public MaxNode { diff --git a/src/hotspot/share/opto/arraycopynode.cpp b/src/hotspot/share/opto/arraycopynode.cpp index 724164d7f4fd6..23a6ee31fffde 100644 --- a/src/hotspot/share/opto/arraycopynode.cpp +++ b/src/hotspot/share/opto/arraycopynode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "gc/shared/c2/cardTableBarrierSetC2.hpp" @@ -33,6 +32,8 @@ #include "utilities/macros.hpp" #include "utilities/powerOfTwo.hpp" +const TypeFunc* ArrayCopyNode::_arraycopy_type_Type = nullptr; + ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard) : CallNode(arraycopy_type(), nullptr, TypePtr::BOTTOM), _kind(None), diff --git a/src/hotspot/share/opto/arraycopynode.hpp b/src/hotspot/share/opto/arraycopynode.hpp index 12004b970bd8d..f792722068fe3 100644 --- a/src/hotspot/share/opto/arraycopynode.hpp +++ b/src/hotspot/share/opto/arraycopynode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ class GraphKit; class ArrayCopyNode : public CallNode { + static const TypeFunc* _arraycopy_type_Type; private: // What kind of arraycopy variant is this? @@ -65,7 +66,15 @@ class ArrayCopyNode : public CallNode { bool _arguments_validated; +public: + static const TypeFunc* arraycopy_type() { + assert(_arraycopy_type_Type != nullptr, "should be initialized"); + return _arraycopy_type_Type; + } + + static void initialize_arraycopy_Type() { + assert(_arraycopy_type_Type == nullptr, "should be"); const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms); fields[Src] = TypeInstPtr::BOTTOM; fields[SrcPos] = TypeInt::INT; @@ -83,9 +92,10 @@ class ArrayCopyNode : public CallNode { const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); - return TypeFunc::make(domain, range); + _arraycopy_type_Type = TypeFunc::make(domain, range); } +private: ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard); intptr_t get_length_if_constant(PhaseGVN *phase) const; diff --git a/src/hotspot/share/opto/block.cpp b/src/hotspot/share/opto/block.cpp index 14bc9e0797cc6..8e49226c26275 100644 --- a/src/hotspot/share/opto/block.cpp +++ b/src/hotspot/share/opto/block.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/vectset.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/opto/buildOopMap.cpp b/src/hotspot/share/opto/buildOopMap.cpp index c2f771bedb701..f135df211145e 100644 --- a/src/hotspot/share/opto/buildOopMap.cpp +++ b/src/hotspot/share/opto/buildOopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/vmreg.inline.hpp" #include "compiler/oopMap.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/opto/bytecodeInfo.cpp b/src/hotspot/share/opto/bytecodeInfo.cpp index 35365f37f485f..e618a708f618e 100644 --- a/src/hotspot/share/opto/bytecodeInfo.cpp +++ b/src/hotspot/share/opto/bytecodeInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciReplay.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compilationPolicy.hpp" @@ -114,7 +113,8 @@ static bool is_unboxing_method(ciMethod* callee_method, Compile* C) { // positive filter: should callee be inlined? bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, - int caller_bci, bool& should_delay, ciCallProfile& profile) { + JVMState* caller_jvms, bool& should_delay, ciCallProfile& profile) { + int caller_bci = caller_jvms->bci(); // Allows targeted inlining if (C->directive()->should_inline(callee_method)) { set_msg("force inline by CompileCommand"); @@ -144,9 +144,9 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, // Check for too many throws (and not too huge) if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { - if (C->print_inlining() && Verbose) { - CompileTask::print_inline_indent(inline_level()); - tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); + if (Verbose) { + outputStream* stream = C->inline_printer()->record(callee_method, caller_jvms, InliningResult::SUCCESS); + stream->print("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); } set_msg("many throws"); return true; @@ -169,11 +169,8 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, max_inline_size = C->freq_inline_size(); if (size <= max_inline_size && TraceFrequencyInlining) { - CompileTask::print_inline_indent(inline_level()); - tty->print_cr("Inlined frequent method (freq=%lf):", freq); - CompileTask::print_inline_indent(inline_level()); - callee_method->print(); - tty->cr(); + outputStream* stream = C->inline_printer()->record(callee_method, caller_jvms, InliningResult::SUCCESS); + stream->print("Inlined frequent method (freq=%lf):", freq); } } else { // Not hot. Check for medium-sized pre-existing nmethod at cold sites. @@ -377,7 +374,7 @@ bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, _forced_inline = false; // Reset // 'should_delay' can be overridden during replay compilation - if (!should_inline(callee_method, caller_method, caller_bci, should_delay, profile)) { + if (!should_inline(callee_method, caller_method, jvms, should_delay, profile)) { return false; } // 'should_delay' can be overridden during replay compilation @@ -535,8 +532,9 @@ const char* InlineTree::check_can_parse(ciMethod* callee) { } //------------------------------print_inlining--------------------------------- -void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, - ciMethod* caller_method, bool success) const { +void InlineTree::print_inlining(ciMethod* callee_method, JVMState* jvm, bool success) const { + int caller_bci = jvm->bci(); + ciMethod* caller_method = jvm->method(); const char* inline_msg = msg(); assert(inline_msg != nullptr, "just checking"); if (C->log() != nullptr) { @@ -546,19 +544,11 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, C->log()->inline_fail(inline_msg); } } - CompileTask::print_inlining_ul(callee_method, inline_level(), - caller_bci, inlining_result_of(success), inline_msg); - if (C->print_inlining()) { - C->print_inlining(callee_method, inline_level(), caller_bci, inlining_result_of(success), inline_msg); - guarantee(callee_method != nullptr, "would crash in CompilerEvent::InlineEvent::post"); - if (Verbose) { - const InlineTree *top = this; - while (top->caller_tree() != nullptr) { top = top->caller_tree(); } - //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); - } - } + CompileTask::print_inlining_ul(callee_method, inline_level(), caller_bci, inlining_result_of(success), inline_msg); + C->inline_printer()->record(callee_method, jvm, inlining_result_of(success), inline_msg); EventCompilerInlining event; if (event.should_commit()) { + guarantee(callee_method != nullptr, "would crash in CompilerEvent::InlineEvent::post"); CompilerEvent::InlineEvent::post(event, C->compile_id(), caller_method->get_Method(), callee_method, success, inline_msg, caller_bci); } } @@ -583,14 +573,14 @@ bool InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallPro // Do some initial checks. if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { set_msg("failed initial checks"); - print_inlining(callee_method, caller_bci, caller_method, false /* !success */); + print_inlining(callee_method, jvms, false /* !success */); return false; } // Do some parse checks. set_msg(check_can_parse(callee_method)); if (msg() != nullptr) { - print_inlining(callee_method, caller_bci, caller_method, false /* !success */); + print_inlining(callee_method, jvms, false /* !success */); return false; } @@ -602,7 +592,7 @@ bool InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallPro if (msg() == nullptr) { set_msg("inline (hot)"); } - print_inlining(callee_method, caller_bci, caller_method, true /* success */); + print_inlining(callee_method, jvms, true /* success */); InlineTree* callee_tree = build_inline_tree_for_callee(callee_method, jvms, caller_bci); if (should_delay) { // Record late inlining decision in order to dump it for compiler replay @@ -614,7 +604,7 @@ bool InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallPro if (msg() == nullptr) { set_msg("too cold to inline"); } - print_inlining(callee_method, caller_bci, caller_method, false /* !success */ ); + print_inlining(callee_method, jvms, false /* !success */); return false; } } @@ -635,8 +625,7 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implementation } if (max_inline_level_adjust != 0 && C->print_inlining() && (Verbose || WizardMode)) { - CompileTask::print_inline_indent(inline_level()); - tty->print_cr(" \\-> discounting inline depth"); + C->inline_printer()->record(callee_method, caller_jvms, InliningResult::SUCCESS, " \\-> discounting inline depth"); } if (max_inline_level_adjust != 0 && C->log()) { int id1 = C->log()->identify(caller_jvms->method()); diff --git a/src/hotspot/share/opto/c2_CodeStubs.cpp b/src/hotspot/share/opto/c2_CodeStubs.cpp index bbdb7a1c85600..e99d48cd8419a 100644 --- a/src/hotspot/share/opto/c2_CodeStubs.cpp +++ b/src/hotspot/share/opto/c2_CodeStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "code/codeBlob.hpp" #include "opto/c2_CodeStubs.hpp" diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index d4b55ec2d8d12..caa0474c4755a 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -633,6 +633,9 @@ develop(bool, VerifyLoopOptimizations, false, \ "verify major loop optimizations") \ \ + develop(bool, VerifyNoNewIrreducibleLoops, false, \ + "Verify that no new irreducible loops are created after parsing") \ + \ product(bool, ProfileDynamicTypes, true, DIAGNOSTIC, \ "do extra type profiling and use it more aggressively") \ \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index c6744d0c7bd0b..0a769211c82c6 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmClasses.hpp" #include "compiler/compilationMemoryStatistic.hpp" #include "compiler/compilerDefinitions.inline.hpp" @@ -353,6 +352,12 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_floatToFloat16: if (!Matcher::match_rule_supported(Op_ConvF2HF)) return false; break; + case vmIntrinsics::_sqrt_float16: + if (!Matcher::match_rule_supported(Op_SqrtHF)) return false; + break; + case vmIntrinsics::_fma_float16: + if (!Matcher::match_rule_supported(Op_FmaHF)) return false; + break; /* CompareAndSet, Object: */ case vmIntrinsics::_compareAndSetReference: @@ -750,10 +755,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_clone: case vmIntrinsics::_isAssignableFrom: case vmIntrinsics::_isInstance: - case vmIntrinsics::_getModifiers: - case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp index 514fece6bb479..ec7117e3568ca 100644 --- a/src/hotspot/share/opto/callGenerator.cpp +++ b/src/hotspot/share/opto/callGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "ci/ciCallSite.hpp" #include "ci/ciObjArray.hpp" @@ -85,7 +84,6 @@ class ParseGenerator : public InlineCallGenerator { JVMState* ParseGenerator::generate(JVMState* jvms) { Compile* C = Compile::current(); - C->print_inlining_update(this); if (is_osr()) { // The JVMS for a OSR has a single argument (see its TypeFunc). @@ -144,7 +142,6 @@ class DirectCallGenerator : public CallGenerator { JVMState* DirectCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); - kit.C->print_inlining_update(this); bool is_static = method()->is_static(); address target = is_static ? SharedRuntime::get_resolve_static_call_stub() : SharedRuntime::get_resolve_opt_virtual_call_stub(); @@ -219,8 +216,6 @@ JVMState* VirtualCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); Node* receiver = kit.argument(0); - kit.C->print_inlining_update(this); - if (kit.C->log() != nullptr) { kit.C->log()->elem("virtual_call bci='%d'", jvms->bci()); } @@ -354,15 +349,6 @@ class LateInlineCallGenerator : public DirectCallGenerator { return DirectCallGenerator::generate(jvms); } - virtual void print_inlining_late(InliningResult result, const char* msg) { - CallNode* call = call_node(); - Compile* C = Compile::current(); - C->print_inlining_assert_ready(); - C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), result, msg); - C->print_inlining_move_to(this); - C->print_inlining_update_delayed(this); - } - virtual void set_unique_id(jlong id) { _unique_id = id; } @@ -432,9 +418,9 @@ bool LateInlineMHCallGenerator::do_late_inline_check(Compile* C, JVMState* jvms) assert(!input_not_const, "sanity"); // shouldn't have been scheduled for inlining in the first place if (cg != nullptr) { - if (!allow_inline && (C->print_inlining() || C->print_intrinsics())) { - C->print_inlining(cg->method(), jvms->depth()-1, call_node()->jvms()->bci(), InliningResult::FAILURE, - "late method handle call resolution"); + if (!allow_inline) { + C->inline_printer()->record(cg->method(), call_node()->jvms(), InliningResult::FAILURE, + "late method handle call resolution"); } assert(!cg->is_late_inline() || cg->is_mh_late_inline() || AlwaysIncrementalInline || StressIncrementalInlining, "we're doing late inlining"); _inline_cg = cg; @@ -500,15 +486,6 @@ class LateInlineVirtualCallGenerator : public VirtualCallGenerator { return new_jvms; } - virtual void print_inlining_late(InliningResult result, const char* msg) { - CallNode* call = call_node(); - Compile* C = Compile::current(); - C->print_inlining_assert_ready(); - C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), result, msg); - C->print_inlining_move_to(this); - C->print_inlining_update_delayed(this); - } - virtual void set_unique_id(jlong id) { _unique_id = id; } @@ -532,20 +509,16 @@ bool LateInlineVirtualCallGenerator::do_late_inline_check(Compile* C, JVMState* Node* receiver = jvms->map()->argument(jvms, 0); const Type* recv_type = C->initial_gvn()->type(receiver); if (recv_type->maybe_null()) { - if (C->print_inlining() || C->print_intrinsics()) { - C->print_inlining(method(), jvms->depth()-1, call_node()->jvms()->bci(), InliningResult::FAILURE, - "late call devirtualization failed (receiver may be null)"); - } + C->inline_printer()->record(method(), call_node()->jvms(), InliningResult::FAILURE, + "late call devirtualization failed (receiver may be null)"); return false; } // Even if inlining is not allowed, a virtual call can be strength-reduced to a direct call. bool allow_inline = C->inlining_incrementally(); if (!allow_inline && _callee->holder()->is_interface()) { // Don't convert the interface call to a direct call guarded by an interface subtype check. - if (C->print_inlining() || C->print_intrinsics()) { - C->print_inlining(method(), jvms->depth()-1, call_node()->jvms()->bci(), InliningResult::FAILURE, - "late call devirtualization failed (interface call)"); - } + C->inline_printer()->record(method(), call_node()->jvms(), InliningResult::FAILURE, + "late call devirtualization failed (interface call)"); return false; } CallGenerator* cg = C->call_generator(_callee, @@ -558,9 +531,8 @@ bool LateInlineVirtualCallGenerator::do_late_inline_check(Compile* C, JVMState* true /*allow_intrinsics*/); if (cg != nullptr) { - if (!allow_inline && (C->print_inlining() || C->print_intrinsics())) { - C->print_inlining(cg->method(), jvms->depth()-1, call_node()->jvms()->bci(), InliningResult::FAILURE, - "late call devirtualization"); + if (!allow_inline) { + C->inline_printer()->record(cg->method(), call_node()->jvms(), InliningResult::FAILURE, "late call devirtualization"); } assert(!cg->is_late_inline() || cg->is_mh_late_inline() || AlwaysIncrementalInline || StressIncrementalInlining, "we're doing late inlining"); _inline_cg = cg; @@ -683,21 +655,13 @@ void CallGenerator::do_late_inline_helper() { map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1)); } - C->print_inlining_assert_ready(); - - C->print_inlining_move_to(this); - C->log_late_inline(this); // JVMState is ready, so time to perform some checks and prepare for inlining attempt. if (!do_late_inline_check(C, jvms)) { map->disconnect_inputs(C); - C->print_inlining_update_delayed(this); return; } - if (C->print_inlining() && (is_mh_late_inline() || is_virtual_late_inline())) { - C->print_inlining_update_delayed(this); - } // Setup default node notes to be picked up by the inlining Node_Notes* old_nn = C->node_notes_at(call->_idx); @@ -712,6 +676,18 @@ void CallGenerator::do_late_inline_helper() { if (new_jvms == nullptr) return; // no change if (C->failing()) return; + if (is_mh_late_inline()) { + C->inline_printer()->record(method(), jvms, InliningResult::SUCCESS, "late inline succeeded (method handle)"); + } else if (is_string_late_inline()) { + C->inline_printer()->record(method(), jvms, InliningResult::SUCCESS, "late inline succeeded (string method)"); + } else if (is_boxing_late_inline()) { + C->inline_printer()->record(method(), jvms, InliningResult::SUCCESS, "late inline succeeded (boxing method)"); + } else if (is_vector_reboxing_late_inline()) { + C->inline_printer()->record(method(), jvms, InliningResult::SUCCESS, "late inline succeeded (vector reboxing method)"); + } else { + C->inline_printer()->record(method(), jvms, InliningResult::SUCCESS, "late inline succeeded"); + } + // Capture any exceptional control flow GraphKit kit(new_jvms); @@ -783,6 +759,8 @@ class LateInlineBoxingCallGenerator : public LateInlineCallGenerator { return new_jvms; } + virtual bool is_boxing_late_inline() const { return true; } + virtual CallGenerator* with_call_node(CallNode* call) { LateInlineBoxingCallGenerator* cg = new LateInlineBoxingCallGenerator(method(), _inline_cg); cg->set_call_node(call->as_CallStaticJava()); @@ -811,6 +789,8 @@ class LateInlineVectorReboxingCallGenerator : public LateInlineCallGenerator { return new_jvms; } + virtual bool is_vector_reboxing_late_inline() const { return true; } + virtual CallGenerator* with_call_node(CallNode* call) { LateInlineVectorReboxingCallGenerator* cg = new LateInlineVectorReboxingCallGenerator(method(), _inline_cg); cg->set_call_node(call->as_CallStaticJava()); @@ -876,7 +856,6 @@ CallGenerator* CallGenerator::for_guarded_call(ciKlass* guarded_receiver, JVMState* PredictedCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); - kit.C->print_inlining_update(this); PhaseGVN& gvn = kit.gvn(); // We need an explicit receiver null_check before checking its type. // We share a map with the caller, so his JVMS gets adjusted. @@ -933,6 +912,9 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { // Make the hot call: JVMState* new_jvms = _if_hit->generate(kit.sync_jvms()); + if (kit.failing()) { + return nullptr; + } if (new_jvms == nullptr) { // Inline failed, so make a direct call. assert(_if_hit->is_inline(), "must have been a failed inline"); @@ -1046,8 +1028,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* const int vtable_index = Method::invalid_vtable_index; if (!ciMethod::is_consistent_info(callee, target)) { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "signatures mismatch"); + print_inlining_failure(C, callee, jvms, "signatures mismatch"); return nullptr; } @@ -1060,15 +1041,12 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* } else { assert(receiver->bottom_type() == TypePtr::NULL_PTR, "not a null: %s", Type::str(receiver->bottom_type())); - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "receiver is always null"); + print_inlining_failure(C, callee, jvms, "receiver is always null"); } } else { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "receiver not constant"); + print_inlining_failure(C, callee, jvms, "receiver not constant"); } - } - break; + } break; case vmIntrinsics::_linkToVirtual: case vmIntrinsics::_linkToStatic: @@ -1083,8 +1061,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget(); if (!ciMethod::is_consistent_info(callee, target)) { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "signatures mismatch"); + print_inlining_failure(C, callee, jvms, "signatures mismatch"); return nullptr; } @@ -1099,8 +1076,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* Node* recv = kit.argument(0); Node* casted_recv = kit.maybe_narrow_object_type(recv, signature->accessing_klass()); if (casted_recv->is_top()) { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "argument types mismatch"); + print_inlining_failure(C, callee, jvms, "argument types mismatch"); return nullptr; // FIXME: effectively dead; issue a halt node instead } else if (casted_recv != recv) { kit.set_argument(0, casted_recv); @@ -1113,8 +1089,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* Node* arg = kit.argument(receiver_skip + j); Node* casted_arg = kit.maybe_narrow_object_type(arg, t->as_klass()); if (casted_arg->is_top()) { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "argument types mismatch"); + print_inlining_failure(C, callee, jvms, "argument types mismatch"); return nullptr; // FIXME: effectively dead; issue a halt node instead } else if (casted_arg != arg) { kit.set_argument(receiver_skip + j, casted_arg); @@ -1152,15 +1127,12 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* speculative_receiver_type); return cg; } else { - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "member_name not constant"); + print_inlining_failure(C, callee, jvms, "member_name not constant"); } - } - break; + } break; - case vmIntrinsics::_linkToNative: - print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), - "native call"); + case vmIntrinsics::_linkToNative: + print_inlining_failure(C, callee, jvms, "native call"); break; default: @@ -1260,6 +1232,9 @@ JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms) { PreserveJVMState pjvms(&kit); // Generate intrinsic code: JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms()); + if (kit.failing()) { + return nullptr; + } if (new_jvms == nullptr) { // Intrinsic failed, use normal compilation path for this predicate. slow_region->add_req(kit.control()); @@ -1405,7 +1380,6 @@ CallGenerator::for_uncommon_trap(ciMethod* m, JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); - kit.C->print_inlining_update(this); // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver). // Callsite signature can be different from actual method being called (i.e _linkTo* sites). // Use callsite signature always. diff --git a/src/hotspot/share/opto/callGenerator.hpp b/src/hotspot/share/opto/callGenerator.hpp index 77182580207ca..82b195e0c7603 100644 --- a/src/hotspot/share/opto/callGenerator.hpp +++ b/src/hotspot/share/opto/callGenerator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,8 @@ class CallGenerator : public ArenaObj { // same but for method handle calls virtual bool is_mh_late_inline() const { return false; } virtual bool is_string_late_inline() const { return false; } + virtual bool is_boxing_late_inline() const { return false; } + virtual bool is_vector_reboxing_late_inline() const { return false; } virtual bool is_virtual_late_inline() const { return false; } // Replace the call with an inline version of the code @@ -171,28 +173,14 @@ class CallGenerator : public ArenaObj { CallGenerator* cg); virtual Node* generate_predicate(JVMState* jvms, int predicate) { return nullptr; }; - virtual void print_inlining_late(InliningResult result, const char* msg) { ShouldNotReachHere(); } - - static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { - print_inlining_impl(C, callee, inline_level, bci, InliningResult::SUCCESS, msg); - } - - static void print_inlining_failure(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { - print_inlining_impl(C, callee, inline_level, bci, InliningResult::FAILURE, msg); + static void print_inlining_failure(Compile* C, ciMethod* callee, JVMState* jvms, const char* msg) { + C->inline_printer()->record(callee, jvms, InliningResult::FAILURE, msg); C->log_inline_failure(msg); } static bool is_inlined_method_handle_intrinsic(JVMState* jvms, ciMethod* m); static bool is_inlined_method_handle_intrinsic(ciMethod* caller, int bci, ciMethod* m); static bool is_inlined_method_handle_intrinsic(ciMethod* symbolic_info, ciMethod* m); - -private: - static void print_inlining_impl(Compile* C, ciMethod* callee, int inline_level, int bci, - InliningResult result, const char* msg) { - if (C->print_inlining()) { - C->print_inlining(callee, inline_level, bci, result, msg); - } - } }; diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp index 83ea2eea1a8aa..e330115a81de5 100644 --- a/src/hotspot/share/opto/callnode.cpp +++ b/src/hotspot/share/opto/callnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "compiler/oopMap.hpp" @@ -718,7 +717,9 @@ void CallNode::dump_spec(outputStream *st) const { const Type *CallNode::bottom_type() const { return tf()->range(); } const Type* CallNode::Value(PhaseGVN* phase) const { - if (phase->type(in(0)) == Type::TOP) return Type::TOP; + if (in(0) == nullptr || phase->type(in(0)) == Type::TOP) { + return Type::TOP; + } return tf()->range(); } @@ -1666,6 +1667,8 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu } //============================================================================= +const TypeFunc* LockNode::_lock_type_Type = nullptr; + uint LockNode::size_of() const { return sizeof(*this); } // Redundant lock elimination diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp index 2d3835b71ad42..ad5e9daa8f69d 100644 --- a/src/hotspot/share/opto/callnode.hpp +++ b/src/hotspot/share/opto/callnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1190,9 +1190,16 @@ class AbstractLockNode: public CallNode { // 2 - a FastLockNode // class LockNode : public AbstractLockNode { + static const TypeFunc* _lock_type_Type; public: - static const TypeFunc *lock_type() { + static inline const TypeFunc* lock_type() { + assert(_lock_type_Type != nullptr, "should be initialized"); + return _lock_type_Type; + } + + static void initialize_lock_Type() { + assert(_lock_type_Type == nullptr, "should be called once"); // create input type (domain) const Type **fields = TypeTuple::fields(3); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked @@ -1205,7 +1212,7 @@ class LockNode : public AbstractLockNode { const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); - return TypeFunc::make(domain,range); + _lock_type_Type = TypeFunc::make(domain,range); } virtual int Opcode() const; diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp index 63ed54df4fd9d..68ba291986bcf 100644 --- a/src/hotspot/share/opto/castnode.cpp +++ b/src/hotspot/share/opto/castnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" #include "opto/castnode.hpp" @@ -213,19 +212,15 @@ const Type* CastIINode::Value(PhaseGVN* phase) const { // Similar to ConvI2LNode::Value() for the same reasons // see if we can remove type assertion after loop opts - // But here we have to pay extra attention: - // Do not narrow the type of range check dependent CastIINodes to - // avoid corruption of the graph if a CastII is replaced by TOP but - // the corresponding range check is not removed. - if (!_range_check_dependency) { - res = widen_type(phase, res, T_INT); - } + res = widen_type(phase, res, T_INT); return res; } -static Node* find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInteger* type, ConstraintCastNode::DependencyType dependency, BasicType bt) { - Node* n = ConstraintCastNode::make_cast_for_basic_type(control, parent, type, dependency, bt); +Node* ConstraintCastNode::find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, const TypeInteger* type) const { + Node* n = clone(); + n->set_req(1, parent); + n->as_ConstraintCast()->set_type(type); Node* existing = igvn->hash_find_insert(n); if (existing != nullptr) { n->destruct(igvn); @@ -239,13 +234,14 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) { if (progress != nullptr) { return progress; } - if (can_reshape && !_range_check_dependency && !phase->C->post_loop_opts_phase()) { + if (can_reshape && !phase->C->post_loop_opts_phase()) { // makes sure we run ::Value to potentially remove type assertion after loop opts phase->C->record_for_post_loop_opts_igvn(this); } - if (!_range_check_dependency) { + if (!_range_check_dependency || phase->C->post_loop_opts_phase()) { return optimize_integer_cast(phase, T_INT); } + phase->C->record_for_post_loop_opts_igvn(this); return nullptr; } @@ -254,13 +250,6 @@ Node* CastIINode::Identity(PhaseGVN* phase) { if (progress != this) { return progress; } - if (_range_check_dependency) { - if (phase->C->post_loop_opts_phase()) { - return this->in(1); - } else { - phase->C->record_for_post_loop_opts_igvn(this); - } - } return this; } @@ -289,6 +278,34 @@ CastIINode* CastIINode::pin_array_access_node() const { return nullptr; } +void CastIINode::remove_range_check_cast(Compile* C) { + if (has_range_check()) { + // Range check CastII nodes feed into an address computation subgraph. Remove them to let that subgraph float freely. + // For memory access or integer divisions nodes that depend on the cast, record the dependency on the cast's control + // as a precedence edge, so they can't float above the cast in case that cast's narrowed type helped eliminate a + // range check or a null divisor check. + assert(in(0) != nullptr, "All RangeCheck CastII must have a control dependency"); + ResourceMark rm; + Unique_Node_List wq; + wq.push(this); + for (uint next = 0; next < wq.size(); ++next) { + Node* m = wq.at(next); + for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { + Node* use = m->fast_out(i); + if (use->is_Mem() || use->is_div_or_mod(T_INT) || use->is_div_or_mod(T_LONG)) { + use->ensure_control_or_add_prec(in(0)); + } else if (!use->is_CFG() && !use->is_Phi()) { + wq.push(use); + } + } + } + subsume_by(in(1), C); + if (outcnt() == 0) { + disconnect_inputs(C); + } + } +} + const Type* CastLLNode::Value(PhaseGVN* phase) const { const Type* res = ConstraintCastNode::Value(phase); @@ -458,6 +475,8 @@ Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type return new CastIINode(c, in, type, dependency, false, types); } else if (type->isa_long()) { return new CastLLNode(c, in, type, dependency, types); + } else if (type->isa_half_float()) { + return new CastHHNode(c, in, type, dependency, types); } else if (type->isa_float()) { return new CastFFNode(c, in, type, dependency, types); } else if (type->isa_double()) { @@ -489,8 +508,8 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) { Node* x = z->in(1); Node* y = z->in(2); - Node* cx = find_or_make_integer_cast(igvn, x, in(0), rx, _dependency, bt); - Node* cy = find_or_make_integer_cast(igvn, y, in(0), ry, _dependency, bt); + Node* cx = find_or_make_integer_cast(igvn, x, rx); + Node* cy = find_or_make_integer_cast(igvn, y, ry); if (op == Op_Add(bt)) { return AddNode::make(cx, cy, bt); } else { diff --git a/src/hotspot/share/opto/castnode.hpp b/src/hotspot/share/opto/castnode.hpp index c193d406f939f..1b848e5efdf24 100644 --- a/src/hotspot/share/opto/castnode.hpp +++ b/src/hotspot/share/opto/castnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ class ConstraintCastNode: public TypeNode { virtual uint size_of() const; virtual uint hash() const; // Check the type const Type* widen_type(const PhaseGVN* phase, const Type* res, BasicType bt) const; + Node* find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, const TypeInteger* type) const; private: // PhiNode::Ideal() transforms a Phi that merges a single uncasted value into a single cast pinned at the region. @@ -121,6 +122,7 @@ class CastIINode: public ConstraintCastNode { } CastIINode* pin_array_access_node() const; + void remove_range_check_cast(Compile* C); #ifndef PRODUCT virtual void dump_spec(outputStream* st) const; @@ -141,6 +143,17 @@ class CastLLNode: public ConstraintCastNode { virtual uint ideal_reg() const { return Op_RegL; } }; +class CastHHNode: public ConstraintCastNode { +public: + CastHHNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) + : ConstraintCastNode(ctrl, n, t, dependency, types) { + assert(ctrl != nullptr, "control must be set"); + init_class_id(Class_CastHH); + } + virtual int Opcode() const; + virtual uint ideal_reg() const { return in(1)->ideal_reg(); } +}; + class CastFFNode: public ConstraintCastNode { public: CastFFNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr) diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 3e451fc789eeb..01cbacd72f3f6 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "memory/allocation.inline.hpp" @@ -437,15 +436,18 @@ bool RegionNode::are_all_nodes_in_infinite_subgraph(Unique_Node_List& worklist) void RegionNode::set_loop_status(RegionNode::LoopStatus status) { assert(loop_status() == RegionNode::LoopStatus::NeverIrreducibleEntry, "why set our status again?"); + assert(status != RegionNode::LoopStatus::MaybeIrreducibleEntry || !is_Loop(), "LoopNode is never irreducible entry."); _loop_status = status; } -#ifdef ASSERT -void RegionNode::verify_can_be_irreducible_entry() const { - assert(loop_status() == RegionNode::LoopStatus::MaybeIrreducibleEntry, "must be marked irreducible"); - assert(!is_Loop(), "LoopNode cannot be irreducible loop entry"); +// A Region can only be an irreducible entry if: +// - It is marked as "maybe irreducible entry". Any other loop status would guarantee +// that it is never an irreducible loop entry. +// - And it is not a LoopNode, those are guaranteed to be reducible loop entries. +bool RegionNode::can_be_irreducible_entry() const { + return loop_status() == RegionNode::LoopStatus::MaybeIrreducibleEntry && + !is_Loop(); } -#endif //ASSERT void RegionNode::try_clean_mem_phis(PhaseIterGVN* igvn) { // Incremental inlining + PhaseStringOpts sometimes produce: diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index 1d287c2f43df8..899e3c9bb8586 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -119,7 +119,7 @@ class RegionNode : public Node { #endif //ASSERT LoopStatus loop_status() const { return _loop_status; }; void set_loop_status(LoopStatus status); - DEBUG_ONLY(void verify_can_be_irreducible_entry() const;) + bool can_be_irreducible_entry() const; virtual int Opcode() const; virtual uint size_of() const { return sizeof(*this); } diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 4a200241bb7f2..30d8e1ac287ce 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "compiler/oopMap.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/opto/classes.cpp b/src/hotspot/share/opto/classes.cpp index 0297125da9eec..61d164773a29e 100644 --- a/src/hotspot/share/opto/classes.cpp +++ b/src/hotspot/share/opto/classes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/arraycopynode.hpp" #include "opto/callnode.hpp" diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index 60ee3e01137b0..918d8156b5fd4 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ macro(AddF) macro(AddI) macro(AddL) macro(AddP) +macro(AddHF) macro(Allocate) macro(AllocateArray) macro(AndI) @@ -64,6 +65,7 @@ macro(CallLeafVector) macro(CallRuntime) macro(CallStaticJava) macro(CastDD) +macro(CastHH) macro(CastFF) macro(CastII) macro(CastLL) @@ -132,6 +134,7 @@ macro(Con) macro(ConN) macro(ConNKlass) macro(ConD) +macro(ConH) macro(ConF) macro(ConI) macro(ConL) @@ -166,6 +169,7 @@ macro(CountTrailingZerosV) macro(CreateEx) macro(DecodeN) macro(DecodeNKlass) +macro(DivHF) macro(DivD) macro(DivF) macro(DivI) @@ -184,6 +188,7 @@ macro(FastLock) macro(FastUnlock) macro(FmaD) macro(FmaF) +macro(FmaHF) macro(ForwardException) macro(Goto) macro(Halt) @@ -222,6 +227,7 @@ macro(MachProj) macro(MulAddS2I) macro(MaxI) macro(MaxL) +macro(MaxHF) macro(MaxD) macro(MaxF) macro(MemBarAcquire) @@ -237,6 +243,7 @@ macro(MemBarStoreStore) macro(MergeMem) macro(MinI) macro(MinL) +macro(MinHF) macro(MinF) macro(MinD) macro(ModD) @@ -253,6 +260,7 @@ macro(IsInfiniteF) macro(IsFiniteF) macro(IsInfiniteD) macro(IsFiniteD) +macro(MulHF) macro(MulD) macro(MulF) macro(MulHiL) @@ -338,6 +346,7 @@ macro(SignumVF) macro(SignumVD) macro(SqrtD) macro(SqrtF) +macro(SqrtHF) macro(RoundF) macro(RoundD) macro(Start) @@ -357,6 +366,7 @@ macro(StrEquals) macro(StrIndexOf) macro(StrIndexOfChar) macro(StrInflatedCopy) +macro(SubHF) macro(SubD) macro(SubF) macro(SubI) @@ -485,6 +495,8 @@ macro(ExtractF) macro(ExtractD) macro(Digit) macro(LowerCase) +macro(ReinterpretS2HF) +macro(ReinterpretHF2S) macro(UpperCase) macro(Whitespace) macro(SelectFromTwoVector) diff --git a/src/hotspot/share/opto/coalesce.cpp b/src/hotspot/share/opto/coalesce.cpp index 9625a97666ddc..42e3f31492753 100644 --- a/src/hotspot/share/opto/coalesce.cpp +++ b/src/hotspot/share/opto/coalesce.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/block.hpp" #include "opto/c2compiler.hpp" diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 10af40a54e649..7a03ac418a892 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" #include "ci/ciReplay.hpp" @@ -611,77 +610,75 @@ void Compile::print_ideal_ir(const char* phase_name) { // the continuation bci for on stack replacement. -Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci, - Options options, DirectiveSet* directive) - : Phase(Compiler), - _compile_id(ci_env->compile_id()), - _options(options), - _method(target), - _entry_bci(osr_bci), - _ilt(nullptr), - _stub_function(nullptr), - _stub_name(nullptr), - _stub_entry_point(nullptr), - _max_node_limit(MaxNodeLimit), - _post_loop_opts_phase(false), - _allow_macro_nodes(true), - _inlining_progress(false), - _inlining_incrementally(false), - _do_cleanup(false), - _has_reserved_stack_access(target->has_reserved_stack_access()), +Compile::Compile(ciEnv* ci_env, ciMethod* target, int osr_bci, + Options options, DirectiveSet* directive) + : Phase(Compiler), + _compile_id(ci_env->compile_id()), + _options(options), + _method(target), + _entry_bci(osr_bci), + _ilt(nullptr), + _stub_function(nullptr), + _stub_name(nullptr), + _stub_entry_point(nullptr), + _max_node_limit(MaxNodeLimit), + _post_loop_opts_phase(false), + _allow_macro_nodes(true), + _inlining_progress(false), + _inlining_incrementally(false), + _do_cleanup(false), + _has_reserved_stack_access(target->has_reserved_stack_access()), #ifndef PRODUCT - _igv_idx(0), - _trace_opto_output(directive->TraceOptoOutputOption), + _igv_idx(0), + _trace_opto_output(directive->TraceOptoOutputOption), #endif - _has_method_handle_invokes(false), - _clinit_barrier_on_entry(false), - _stress_seed(0), - _comp_arena(mtCompiler), - _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())), - _env(ci_env), - _directive(directive), - _log(ci_env->log()), - _first_failure_details(nullptr), - _intrinsics (comp_arena(), 0, 0, nullptr), - _macro_nodes (comp_arena(), 8, 0, nullptr), - _parse_predicates (comp_arena(), 8, 0, nullptr), - _template_assertion_predicate_opaqs (comp_arena(), 8, 0, nullptr), - _expensive_nodes (comp_arena(), 8, 0, nullptr), - _for_post_loop_igvn(comp_arena(), 8, 0, nullptr), - _unstable_if_traps (comp_arena(), 8, 0, nullptr), - _coarsened_locks (comp_arena(), 8, 0, nullptr), - _congraph(nullptr), - NOT_PRODUCT(_igv_printer(nullptr) COMMA) - _unique(0), - _dead_node_count(0), - _dead_node_list(comp_arena()), - _node_arena_one(mtCompiler, Arena::Tag::tag_node), - _node_arena_two(mtCompiler, Arena::Tag::tag_node), - _node_arena(&_node_arena_one), - _mach_constant_base_node(nullptr), - _Compile_types(mtCompiler), - _initial_gvn(nullptr), - _igvn_worklist(nullptr), - _types(nullptr), - _node_hash(nullptr), - _late_inlines(comp_arena(), 2, 0, nullptr), - _string_late_inlines(comp_arena(), 2, 0, nullptr), - _boxing_late_inlines(comp_arena(), 2, 0, nullptr), - _vector_reboxing_late_inlines(comp_arena(), 2, 0, nullptr), - _late_inlines_pos(0), - _number_of_mh_late_inlines(0), - _oom(false), - _print_inlining_stream(new (mtCompiler) stringStream()), - _print_inlining_list(nullptr), - _print_inlining_idx(0), - _print_inlining_output(nullptr), - _replay_inline_data(nullptr), - _java_calls(0), - _inner_loops(0), - _interpreter_frame_size(0), - _output(nullptr) + _has_method_handle_invokes(false), + _clinit_barrier_on_entry(false), + _stress_seed(0), + _comp_arena(mtCompiler), + _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())), + _env(ci_env), + _directive(directive), + _log(ci_env->log()), + _first_failure_details(nullptr), + _intrinsics(comp_arena(), 0, 0, nullptr), + _macro_nodes(comp_arena(), 8, 0, nullptr), + _parse_predicates(comp_arena(), 8, 0, nullptr), + _template_assertion_predicate_opaqs(comp_arena(), 8, 0, nullptr), + _expensive_nodes(comp_arena(), 8, 0, nullptr), + _for_post_loop_igvn(comp_arena(), 8, 0, nullptr), + _unstable_if_traps(comp_arena(), 8, 0, nullptr), + _coarsened_locks(comp_arena(), 8, 0, nullptr), + _congraph(nullptr), + NOT_PRODUCT(_igv_printer(nullptr) COMMA) + _unique(0), + _dead_node_count(0), + _dead_node_list(comp_arena()), + _node_arena_one(mtCompiler, Arena::Tag::tag_node), + _node_arena_two(mtCompiler, Arena::Tag::tag_node), + _node_arena(&_node_arena_one), + _mach_constant_base_node(nullptr), + _Compile_types(mtCompiler), + _initial_gvn(nullptr), + _igvn_worklist(nullptr), + _types(nullptr), + _node_hash(nullptr), + _late_inlines(comp_arena(), 2, 0, nullptr), + _string_late_inlines(comp_arena(), 2, 0, nullptr), + _boxing_late_inlines(comp_arena(), 2, 0, nullptr), + _vector_reboxing_late_inlines(comp_arena(), 2, 0, nullptr), + _late_inlines_pos(0), + _number_of_mh_late_inlines(0), + _oom(false), + _replay_inline_data(nullptr), + _inline_printer(this), + _java_calls(0), + _inner_loops(0), + _interpreter_frame_size(0), + _output(nullptr) #ifndef PRODUCT - , _in_dump_cnt(0) + , + _in_dump_cnt(0) #endif { C = this; @@ -744,7 +741,6 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci, PhaseGVN gvn; set_initial_gvn(&gvn); - print_inlining_init(); { // Scope for timing the parser TracePhase tp(_t_parser); @@ -887,71 +883,68 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci, //------------------------------Compile---------------------------------------- // Compile a runtime stub -Compile::Compile( ciEnv* ci_env, - TypeFunc_generator generator, - address stub_function, - const char *stub_name, - int is_fancy_jump, - bool pass_tls, - bool return_pc, - DirectiveSet* directive) - : Phase(Compiler), - _compile_id(0), - _options(Options::for_runtime_stub()), - _method(nullptr), - _entry_bci(InvocationEntryBci), - _stub_function(stub_function), - _stub_name(stub_name), - _stub_entry_point(nullptr), - _max_node_limit(MaxNodeLimit), - _post_loop_opts_phase(false), - _allow_macro_nodes(true), - _inlining_progress(false), - _inlining_incrementally(false), - _has_reserved_stack_access(false), +Compile::Compile(ciEnv* ci_env, + TypeFunc_generator generator, + address stub_function, + const char* stub_name, + int is_fancy_jump, + bool pass_tls, + bool return_pc, + DirectiveSet* directive) + : Phase(Compiler), + _compile_id(0), + _options(Options::for_runtime_stub()), + _method(nullptr), + _entry_bci(InvocationEntryBci), + _stub_function(stub_function), + _stub_name(stub_name), + _stub_entry_point(nullptr), + _max_node_limit(MaxNodeLimit), + _post_loop_opts_phase(false), + _allow_macro_nodes(true), + _inlining_progress(false), + _inlining_incrementally(false), + _has_reserved_stack_access(false), #ifndef PRODUCT - _igv_idx(0), - _trace_opto_output(directive->TraceOptoOutputOption), + _igv_idx(0), + _trace_opto_output(directive->TraceOptoOutputOption), #endif - _has_method_handle_invokes(false), - _clinit_barrier_on_entry(false), - _stress_seed(0), - _comp_arena(mtCompiler), - _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())), - _env(ci_env), - _directive(directive), - _log(ci_env->log()), - _first_failure_details(nullptr), - _for_post_loop_igvn(comp_arena(), 8, 0, nullptr), - _congraph(nullptr), - NOT_PRODUCT(_igv_printer(nullptr) COMMA) - _unique(0), - _dead_node_count(0), - _dead_node_list(comp_arena()), - _node_arena_one(mtCompiler), - _node_arena_two(mtCompiler), - _node_arena(&_node_arena_one), - _mach_constant_base_node(nullptr), - _Compile_types(mtCompiler), - _initial_gvn(nullptr), - _igvn_worklist(nullptr), - _types(nullptr), - _node_hash(nullptr), - _number_of_mh_late_inlines(0), - _oom(false), - _print_inlining_stream(new (mtCompiler) stringStream()), - _print_inlining_list(nullptr), - _print_inlining_idx(0), - _print_inlining_output(nullptr), - _replay_inline_data(nullptr), - _java_calls(0), - _inner_loops(0), - _interpreter_frame_size(0), - _output(nullptr), + _has_method_handle_invokes(false), + _clinit_barrier_on_entry(false), + _stress_seed(0), + _comp_arena(mtCompiler), + _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())), + _env(ci_env), + _directive(directive), + _log(ci_env->log()), + _first_failure_details(nullptr), + _for_post_loop_igvn(comp_arena(), 8, 0, nullptr), + _congraph(nullptr), + NOT_PRODUCT(_igv_printer(nullptr) COMMA) + _unique(0), + _dead_node_count(0), + _dead_node_list(comp_arena()), + _node_arena_one(mtCompiler), + _node_arena_two(mtCompiler), + _node_arena(&_node_arena_one), + _mach_constant_base_node(nullptr), + _Compile_types(mtCompiler), + _initial_gvn(nullptr), + _igvn_worklist(nullptr), + _types(nullptr), + _node_hash(nullptr), + _number_of_mh_late_inlines(0), + _oom(false), + _replay_inline_data(nullptr), + _inline_printer(this), + _java_calls(0), + _inner_loops(0), + _interpreter_frame_size(0), + _output(nullptr), #ifndef PRODUCT - _in_dump_cnt(0), + _in_dump_cnt(0), #endif - _allowed_reasons(0) { + _allowed_reasons(0) { C = this; TraceTime t1(nullptr, &_t_totalCompilation, CITime, false); @@ -992,7 +985,6 @@ Compile::Compile( ciEnv* ci_env, } Compile::~Compile() { - delete _print_inlining_stream; delete _first_failure_details; }; @@ -1707,8 +1699,6 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr } if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) alias_type(idx)->set_rewritable(false); - if (flat->offset() == in_bytes(Klass::modifier_flags_offset())) - alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::access_flags_offset())) alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::misc_flags_offset())) @@ -2113,7 +2103,7 @@ void Compile::inline_incrementally(PhaseIterGVN& igvn) { CallGenerator* cg = _late_inlines.at(i); const char* msg = "live nodes > LiveNodeCountInliningCutoff"; if (do_print_inlining) { - cg->print_inlining_late(InliningResult::FAILURE, msg); + inline_printer()->record(cg->method(), cg->call_node()->jvms(), InliningResult::FAILURE, msg); } log_late_inline_failure(cg, msg); } @@ -2233,8 +2223,6 @@ void Compile::Optimize() { ResourceMark rm; - print_inlining_reinit(); - NOT_PRODUCT( verify_graph_edges(); ) print_method(PHASE_AFTER_PARSING, 1); @@ -2485,8 +2473,6 @@ void Compile::Optimize() { check_no_dead_use(); - process_print_inlining(); - // We will never use the NodeHash table any more. Clear it so that final_graph_reshaping does not have // to remove hashes to unlock nodes for modifications. C->node_hash()->clear(); @@ -3146,6 +3132,13 @@ void Compile::handle_div_mod_op(Node* n, BasicType bt, bool is_unsigned) { // Replace them with a fused divmod if supported if (Matcher::has_match_rule(Op_DivModIL(bt, is_unsigned))) { DivModNode* divmod = DivModNode::make(n, bt, is_unsigned); + // If the divisor input for a Div (or Mod etc.) is not zero, then the control input of the Div is set to zero. + // It could be that the divisor input is found not zero because its type is narrowed down by a CastII in the + // subgraph for that input. Range check CastIIs are removed during final graph reshape. To preserve the dependency + // carried by a CastII, precedence edges are added to the Div node. We need to transfer the precedence edges to the + // DivMod node so the dependency is not lost. + divmod->add_prec_from(n); + divmod->add_prec_from(d); d->subsume_by(divmod->div_proj(), this); n->subsume_by(divmod->mod_proj(), this); } else { @@ -3431,6 +3424,10 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f } break; } + case Op_CastII: { + n->as_CastII()->remove_range_check_cast(this); + break; + } #ifdef _LP64 case Op_CmpP: // Do this transformation here to preserve CmpPNode::sub() and @@ -3582,16 +3579,6 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f #endif -#ifdef ASSERT - case Op_CastII: - // Verify that all range check dependent CastII nodes were removed. - if (n->isa_CastII()->has_range_check()) { - n->dump(3); - assert(false, "Range check dependent CastII node was not removed"); - } - break; -#endif - case Op_ModI: handle_div_mod_op(n, T_INT, false); break; @@ -4439,126 +4426,8 @@ Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* return phase->transform(new ConvI2LNode(value, ltype)); } -// The message about the current inlining is accumulated in -// _print_inlining_stream and transferred into the _print_inlining_list -// once we know whether inlining succeeds or not. For regular -// inlining, messages are appended to the buffer pointed by -// _print_inlining_idx in the _print_inlining_list. For late inlining, -// a new buffer is added after _print_inlining_idx in the list. This -// way we can update the inlining message for late inlining call site -// when the inlining is attempted again. -void Compile::print_inlining_init() { - if (print_inlining() || print_intrinsics()) { - // print_inlining_init is actually called several times. - print_inlining_reset(); - _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, new PrintInliningBuffer()); - } -} - -void Compile::print_inlining_reinit() { - if (print_inlining() || print_intrinsics()) { - print_inlining_reset(); - } -} - -void Compile::print_inlining_reset() { - _print_inlining_stream->reset(); -} - -void Compile::print_inlining_commit() { - assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); - // Transfer the message from _print_inlining_stream to the current - // _print_inlining_list buffer and clear _print_inlining_stream. - _print_inlining_list->at(_print_inlining_idx)->ss()->write(_print_inlining_stream->base(), _print_inlining_stream->size()); - print_inlining_reset(); -} - -void Compile::print_inlining_push() { - // Add new buffer to the _print_inlining_list at current position - _print_inlining_idx++; - _print_inlining_list->insert_before(_print_inlining_idx, new PrintInliningBuffer()); -} - -Compile::PrintInliningBuffer* Compile::print_inlining_current() { - return _print_inlining_list->at(_print_inlining_idx); -} - -void Compile::print_inlining_update(CallGenerator* cg) { - if (print_inlining() || print_intrinsics()) { - if (cg->is_late_inline()) { - if (print_inlining_current()->cg() != cg && - (print_inlining_current()->cg() != nullptr || - print_inlining_current()->ss()->size() != 0)) { - print_inlining_push(); - } - print_inlining_commit(); - print_inlining_current()->set_cg(cg); - } else { - if (print_inlining_current()->cg() != nullptr) { - print_inlining_push(); - } - print_inlining_commit(); - } - } -} - -void Compile::print_inlining_move_to(CallGenerator* cg) { - // We resume inlining at a late inlining call site. Locate the - // corresponding inlining buffer so that we can update it. - if (print_inlining() || print_intrinsics()) { - for (int i = 0; i < _print_inlining_list->length(); i++) { - if (_print_inlining_list->at(i)->cg() == cg) { - _print_inlining_idx = i; - return; - } - } - ShouldNotReachHere(); - } -} - -void Compile::print_inlining_update_delayed(CallGenerator* cg) { - if (print_inlining() || print_intrinsics()) { - assert(_print_inlining_stream->size() > 0, "missing inlining msg"); - assert(print_inlining_current()->cg() == cg, "wrong entry"); - // replace message with new message - _print_inlining_list->at_put(_print_inlining_idx, new PrintInliningBuffer()); - print_inlining_commit(); - print_inlining_current()->set_cg(cg); - } -} - -void Compile::print_inlining_assert_ready() { - assert(!_print_inlining || _print_inlining_stream->size() == 0, "losing data"); -} - -void Compile::process_print_inlining() { - assert(_late_inlines.length() == 0, "not drained yet"); - if (print_inlining() || print_intrinsics()) { - ResourceMark rm; - stringStream ss; - assert(_print_inlining_list != nullptr, "process_print_inlining should be called only once."); - for (int i = 0; i < _print_inlining_list->length(); i++) { - PrintInliningBuffer* pib = _print_inlining_list->at(i); - ss.print("%s", pib->ss()->freeze()); - delete pib; - DEBUG_ONLY(_print_inlining_list->at_put(i, nullptr)); - } - // Reset _print_inlining_list, it only contains destructed objects. - // It is on the arena, so it will be freed when the arena is reset. - _print_inlining_list = nullptr; - // _print_inlining_stream won't be used anymore, either. - print_inlining_reset(); - size_t end = ss.size(); - _print_inlining_output = NEW_ARENA_ARRAY(comp_arena(), char, end+1); - strncpy(_print_inlining_output, ss.freeze(), end+1); - _print_inlining_output[end] = 0; - } -} - void Compile::dump_print_inlining() { - if (_print_inlining_output != nullptr) { - tty->print_raw(_print_inlining_output); - } + inline_printer()->print_on(tty); } void Compile::log_late_inline(CallGenerator* cg) { diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 223e703376103..9325289120704 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -46,6 +46,7 @@ #include "runtime/vmThread.hpp" #include "utilities/ticks.hpp" #include "utilities/vmEnums.hpp" +#include "opto/printinlining.hpp" class AbstractLockNode; class AddPNode; @@ -472,29 +473,6 @@ class Compile : public Phase { // "MemLimit" directive was specified and the memory limit was hit during compilation bool _oom; - // Inlining may not happen in parse order which would make - // PrintInlining output confusing. Keep track of PrintInlining - // pieces in order. - class PrintInliningBuffer : public CHeapObj { - private: - CallGenerator* _cg; - stringStream _ss; - static const size_t default_stream_buffer_size = 128; - - public: - PrintInliningBuffer() - : _cg(nullptr), _ss(default_stream_buffer_size) {} - - stringStream* ss() { return &_ss; } - CallGenerator* cg() { return _cg; } - void set_cg(CallGenerator* cg) { _cg = cg; } - }; - - stringStream* _print_inlining_stream; - GrowableArray* _print_inlining_list; - int _print_inlining_idx; - char* _print_inlining_output; - // Only keep nodes in the expensive node list that need to be optimized void cleanup_expensive_nodes(PhaseIterGVN &igvn); // Use for sorting expensive nodes to bring similar nodes together @@ -506,37 +484,17 @@ class Compile : public Phase { void* _replay_inline_data; // Pointer to data loaded from file - void print_inlining_init(); - void print_inlining_reinit(); - void print_inlining_commit(); - void print_inlining_push(); - PrintInliningBuffer* print_inlining_current(); - void log_late_inline_failure(CallGenerator* cg, const char* msg); DEBUG_ONLY(bool _exception_backedge;) void record_method_not_compilable_oom(); - public: + InlinePrinter _inline_printer; +public: void* barrier_set_state() const { return _barrier_set_state; } - stringStream* print_inlining_stream() { - assert(print_inlining() || print_intrinsics(), "PrintInlining off?"); - return _print_inlining_stream; - } - - void print_inlining_update(CallGenerator* cg); - void print_inlining_update_delayed(CallGenerator* cg); - void print_inlining_move_to(CallGenerator* cg); - void print_inlining_assert_ready(); - void print_inlining_reset(); - - void print_inlining(ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg = nullptr) { - stringStream ss; - CompileTask::print_inlining_inner(&ss, method, inline_level, bci, result, msg); - print_inlining_stream()->print("%s", ss.freeze()); - } + InlinePrinter* inline_printer() { return &_inline_printer; } #ifndef PRODUCT IdealGraphPrinter* igv_printer() { return _igv_printer; } @@ -1100,7 +1058,6 @@ class Compile : public Phase { void remove_useless_coarsened_locks(Unique_Node_List& useful); - void process_print_inlining(); void dump_print_inlining(); bool over_inlining_cutoff() const { diff --git a/src/hotspot/share/opto/connode.cpp b/src/hotspot/share/opto/connode.cpp index 00049c6f19e36..3538342b5d45f 100644 --- a/src/hotspot/share/opto/connode.cpp +++ b/src/hotspot/share/opto/connode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/compile.hpp" @@ -44,6 +43,9 @@ uint ConNode::hash() const { //------------------------------make------------------------------------------- ConNode *ConNode::make(const Type *t) { + if (t->isa_half_float_constant()) { + return new ConHNode( t->is_half_float_constant() ); + } switch( t->basic_type() ) { case T_INT: return new ConINode( t->is_int() ); case T_LONG: return new ConLNode( t->is_long() ); diff --git a/src/hotspot/share/opto/connode.hpp b/src/hotspot/share/opto/connode.hpp index 618326ec52711..3b7657320e2e4 100644 --- a/src/hotspot/share/opto/connode.hpp +++ b/src/hotspot/share/opto/connode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,6 +115,19 @@ class ConLNode : public ConNode { }; +//------------------------------ConHNode--------------------------------------- +// Simple half float constants +class ConHNode : public ConNode { +public: + ConHNode(const TypeH* t) : ConNode(t) {} + virtual int Opcode() const; + + // Factory method: + static ConHNode* make(float con) { + return new ConHNode(TypeH::make(con)); + } +}; + //------------------------------ConFNode--------------------------------------- // Simple float constants class ConFNode : public ConNode { diff --git a/src/hotspot/share/opto/constantTable.cpp b/src/hotspot/share/opto/constantTable.cpp index bcfc048746f5e..aba71e45e1cf9 100644 --- a/src/hotspot/share/opto/constantTable.cpp +++ b/src/hotspot/share/opto/constantTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.hpp" #include "opto/block.hpp" @@ -50,6 +49,7 @@ bool ConstantTable::Constant::operator==(const Constant& other) { // For floating point values we compare the bit pattern. switch (type()) { + case T_SHORT: return (_v._value.i == other._v._value.i); case T_INT: return (_v._value.i == other._v._value.i); case T_FLOAT: return jint_cast(_v._value.f) == jint_cast(other._v._value.f); case T_LONG: return (_v._value.j == other._v._value.j); @@ -103,6 +103,7 @@ static int constant_size(ConstantTable::Constant* con) { return con->get_array()->length(); } switch (con->type()) { + case T_SHORT: return sizeof(jint ); case T_INT: return sizeof(jint ); case T_LONG: return sizeof(jlong ); case T_FLOAT: return sizeof(jfloat ); @@ -168,6 +169,7 @@ bool ConstantTable::emit(C2_MacroAssembler* masm) const { constant_addr = masm->array_constant(con.get_array(), con.alignment()); } else { switch (con.type()) { + case T_SHORT: constant_addr = masm->int_constant( con.get_jint() ); break; case T_INT: constant_addr = masm->int_constant( con.get_jint() ); break; case T_LONG: constant_addr = masm->long_constant( con.get_jlong() ); break; case T_FLOAT: constant_addr = masm->float_constant( con.get_jfloat() ); break; @@ -282,6 +284,7 @@ ConstantTable::Constant ConstantTable::add(MachConstantNode* n, MachOper* oper) BasicType type = oper->type()->basic_type(); switch (type) { case T_LONG: value.j = oper->constantL(); break; + case T_SHORT: value.i = oper->constantH(); break; case T_INT: value.i = oper->constant(); break; case T_FLOAT: value.f = oper->constantF(); break; case T_DOUBLE: value.d = oper->constantD(); break; diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index 0a2131782a237..bdfb211da834e 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,13 +22,14 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/castnode.hpp" #include "opto/connode.hpp" #include "opto/convertnode.hpp" +#include "opto/divnode.hpp" #include "opto/matcher.hpp" #include "opto/movenode.hpp" +#include "opto/mulnode.hpp" #include "opto/phaseX.hpp" #include "opto/subnode.hpp" #include "runtime/stubRoutines.hpp" @@ -249,6 +250,37 @@ const Type* ConvF2HFNode::Value(PhaseGVN* phase) const { return TypeInt::make( StubRoutines::f2hf(tf->getf()) ); } +//------------------------------Ideal------------------------------------------ +Node* ConvF2HFNode::Ideal(PhaseGVN* phase, bool can_reshape) { + // Float16 instance encapsulates a short field holding IEEE 754 + // binary16 value. On unboxing, this short field is loaded into a + // GPR register while FP operation operates over floating point + // registers. ConvHF2F converts incoming short value to a FP32 value + // to perform operation at FP32 granularity. However, if target + // support FP16 ISA we can save this redundant up casting and + // optimize the graph pallet using following transformation. + // + // ConvF2HF(FP32BinOp(ConvHF2F(x), ConvHF2F(y))) => + // ReinterpretHF2S(FP16BinOp(ReinterpretS2HF(x), ReinterpretS2HF(y))) + // + // Please note we need to inject appropriate reinterpretation + // IR to move the values b/w GPR and floating point register + // before and after FP16 operation. + + if (Float16NodeFactory::is_float32_binary_oper(in(1)->Opcode()) && + in(1)->in(1)->Opcode() == Op_ConvHF2F && + in(1)->in(2)->Opcode() == Op_ConvHF2F) { + if (Matcher::match_rule_supported(Float16NodeFactory::get_float16_binary_oper(in(1)->Opcode())) && + Matcher::match_rule_supported(Op_ReinterpretS2HF) && + Matcher::match_rule_supported(Op_ReinterpretHF2S)) { + Node* in1 = phase->transform(new ReinterpretS2HFNode(in(1)->in(1)->in(1))); + Node* in2 = phase->transform(new ReinterpretS2HFNode(in(1)->in(2)->in(1))); + Node* binop = phase->transform(Float16NodeFactory::make(in(1)->Opcode(), in(1)->in(0), in1, in2)); + return new ReinterpretHF2SNode(binop); + } + } + return nullptr; +} //============================================================================= //------------------------------Value------------------------------------------ const Type* ConvF2INode::Value(PhaseGVN* phase) const { @@ -897,3 +929,75 @@ const Type* RoundDoubleModeNode::Value(PhaseGVN* phase) const { return Type::DOUBLE; } //============================================================================= + +const Type* ReinterpretS2HFNode::Value(PhaseGVN* phase) const { + const Type* type = phase->type(in(1)); + // Convert short constant value to a Half Float constant value + if ((type->isa_int() && type->is_int()->is_con())) { + jshort hfval = type->is_int()->get_con(); + return TypeH::make(hfval); + } + return Type::HALF_FLOAT; +} + +Node* ReinterpretS2HFNode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_ReinterpretHF2S) { + assert(in(1)->in(1)->bottom_type()->isa_half_float(), ""); + return in(1)->in(1); + } + return this; +} + +const Type* ReinterpretHF2SNode::Value(PhaseGVN* phase) const { + const Type* type = phase->type(in(1)); + // Convert Half float constant value to short constant value. + if (type->isa_half_float_constant()) { + jshort hfval = type->is_half_float_constant()->_f; + return TypeInt::make(hfval); + } + return TypeInt::SHORT; +} + +bool Float16NodeFactory::is_float32_binary_oper(int opc) { + switch(opc) { + case Op_AddF: + case Op_SubF: + case Op_MulF: + case Op_DivF: + case Op_MaxF: + case Op_MinF: + return true; + default: + return false; + } +} + +int Float16NodeFactory::get_float16_binary_oper(int opc) { + switch(opc) { + case Op_AddF: + return Op_AddHF; + case Op_SubF: + return Op_SubHF; + case Op_MulF: + return Op_MulHF; + case Op_DivF: + return Op_DivHF; + case Op_MaxF: + return Op_MaxHF; + case Op_MinF: + return Op_MinHF; + default: ShouldNotReachHere(); + } +} + +Node* Float16NodeFactory::make(int opc, Node* c, Node* in1, Node* in2) { + switch(opc) { + case Op_AddF: return new AddHFNode(in1, in2); + case Op_SubF: return new SubHFNode(in1, in2); + case Op_MulF: return new MulHFNode(in1, in2); + case Op_DivF: return new DivHFNode(c, in1, in2); + case Op_MaxF: return new MaxHFNode(in1, in2); + case Op_MinF: return new MinHFNode(in1, in2); + default: ShouldNotReachHere(); + } +} diff --git a/src/hotspot/share/opto/convertnode.hpp b/src/hotspot/share/opto/convertnode.hpp index 9438176a9f996..64b2d2571b2a1 100644 --- a/src/hotspot/share/opto/convertnode.hpp +++ b/src/hotspot/share/opto/convertnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,6 +112,7 @@ class ConvF2HFNode : public ConvertNode { virtual int Opcode() const; virtual const Type* in_type() const { return TypeInt::FLOAT; } virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------ConvF2INode------------------------------------ @@ -213,6 +214,30 @@ class ConvL2INode : public ConvertNode { virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; + +//-----------------------------ReinterpretS2HFNode --------------------------- +// Reinterpret Short to Half Float +class ReinterpretS2HFNode : public Node { + public: + ReinterpretS2HFNode(Node* in1) : Node(nullptr, in1) {} + virtual int Opcode() const; + virtual const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual const Type* Value(PhaseGVN* phase) const; + virtual Node* Identity(PhaseGVN* phase); + virtual uint ideal_reg() const { return Op_RegF; } +}; + +//-----------------------------ReinterpretS2HFNode --------------------------- +// Reinterpret Half Float to Short +class ReinterpretHF2SNode : public Node { + public: + ReinterpretHF2SNode(Node* in1) : Node(nullptr, in1) {} + virtual int Opcode() const; + virtual const Type* Value(PhaseGVN* phase) const; + virtual const Type* bottom_type() const { return TypeInt::SHORT; } + virtual uint ideal_reg() const { return Op_RegI; } +}; + class RoundDNode : public Node { public: RoundDNode(Node* in1) : Node(nullptr, in1) {} @@ -269,5 +294,11 @@ class RoundDoubleModeNode: public Node { virtual const Type* Value(PhaseGVN* phase) const; }; +class Float16NodeFactory { + public: + static bool is_float32_binary_oper(int opc); + static int get_float16_binary_oper(int opc); + static Node* make(int opc, Node* c, Node* in1, Node* in2); +}; #endif // SHARE_OPTO_CONVERTNODE_HPP diff --git a/src/hotspot/share/opto/countbitsnode.cpp b/src/hotspot/share/opto/countbitsnode.cpp index f9de303ffe474..4023678b51c68 100644 --- a/src/hotspot/share/opto/countbitsnode.cpp +++ b/src/hotspot/share/opto/countbitsnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/countbitsnode.hpp" #include "opto/opcodes.hpp" #include "opto/phaseX.hpp" diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp index e1b143f65f8cb..bb66ad47ed7e1 100644 --- a/src/hotspot/share/opto/divnode.cpp +++ b/src/hotspot/share/opto/divnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/connode.hpp" @@ -35,6 +34,7 @@ #include "opto/phaseX.hpp" #include "opto/subnode.hpp" #include "utilities/powerOfTwo.hpp" +#include "opto/runtime.hpp" // Portions of code courtesy of Clifford Click @@ -42,6 +42,23 @@ #include +ModFloatingNode::ModFloatingNode(Compile* C, const TypeFunc* tf, const char* name) : CallLeafNode(tf, nullptr, name, TypeRawPtr::BOTTOM) { + add_flag(Flag_is_macro); + C->add_macro_node(this); +} + +ModDNode::ModDNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::Math_DD_D_Type(), "drem") { + init_req(TypeFunc::Parms + 0, a); + init_req(TypeFunc::Parms + 1, C->top()); + init_req(TypeFunc::Parms + 2, b); + init_req(TypeFunc::Parms + 3, C->top()); +} + +ModFNode::ModFNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::modf_Type(), "frem") { + init_req(TypeFunc::Parms + 0, a); + init_req(TypeFunc::Parms + 1, b); +} + //----------------------magic_int_divide_constants----------------------------- // Compute magic multiplier and shift constant for converting a 32 bit divide // by constant into a multiply/shift/add series. Return false if calculations @@ -788,6 +805,115 @@ Node *DivFNode::Ideal(PhaseGVN *phase, bool can_reshape) { // return multiplication by the reciprocal return (new MulFNode(in(1), phase->makecon(TypeF::make(reciprocal)))); } +//============================================================================= +//------------------------------Value------------------------------------------ +// An DivHFNode divides its inputs. The third input is a Control input, used to +// prevent hoisting the divide above an unsafe test. +const Type* DivHFNode::Value(PhaseGVN* phase) const { + // Either input is TOP ==> the result is TOP + const Type* t1 = phase->type(in(1)); + const Type* t2 = phase->type(in(2)); + if(t1 == Type::TOP) { return Type::TOP; } + if(t2 == Type::TOP) { return Type::TOP; } + + // Either input is BOTTOM ==> the result is the local BOTTOM + const Type* bot = bottom_type(); + if((t1 == bot) || (t2 == bot) || + (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM)) { + return bot; + } + + // x/x == 1, we ignore 0/0. + // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) + // Does not work for variables because of NaN's + if (in(1) == in(2) && t1->base() == Type::HalfFloatCon && + !g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) { // could be negative ZERO or NaN + return TypeH::ONE; + } + + if (t2 == TypeH::ONE) { + return t1; + } + + // If divisor is a constant and not zero, divide the numbers + if (t1->base() == Type::HalfFloatCon && + t2->base() == Type::HalfFloatCon && + t2->getf() != 0.0) { + // could be negative zero + return TypeH::make(t1->getf() / t2->getf()); + } + + // If the dividend is a constant zero + // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) + // Test TypeHF::ZERO is not sufficient as it could be negative zero + + if (t1 == TypeH::ZERO && !g_isnan(t2->getf()) && t2->getf() != 0.0) { + return TypeH::ZERO; + } + + // If divisor or dividend is nan then result is nan. + if (g_isnan(t1->getf()) || g_isnan(t2->getf())) { + return TypeH::make(NAN); + } + + // Otherwise we give up all hope + return Type::HALF_FLOAT; +} + +//----------------------------------------------------------------------------- +// Dividing by self is 1. +// IF the divisor is 1, we are an identity on the dividend. +Node* DivHFNode::Identity(PhaseGVN* phase) { + return (phase->type( in(2) ) == TypeH::ONE) ? in(1) : this; +} + + +//------------------------------Idealize--------------------------------------- +Node* DivHFNode::Ideal(PhaseGVN* phase, bool can_reshape) { + if (in(0) != nullptr && remove_dead_region(phase, can_reshape)) return this; + // Don't bother trying to transform a dead node + if (in(0) != nullptr && in(0)->is_top()) { return nullptr; } + + const Type* t2 = phase->type(in(2)); + if (t2 == TypeH::ONE) { // Identity? + return nullptr; // Skip it + } + const TypeH* tf = t2->isa_half_float_constant(); + if(tf == nullptr) { return nullptr; } + if(tf->base() != Type::HalfFloatCon) { return nullptr; } + + // Check for out of range values + if(tf->is_nan() || !tf->is_finite()) { return nullptr; } + + // Get the value + float f = tf->getf(); + int exp; + + // Consider the following geometric progression series of POT(power of two) numbers. + // 0.5 x 2^0 = 0.5, 0.5 x 2^1 = 1.0, 0.5 x 2^2 = 2.0, 0.5 x 2^3 = 4.0 ... 0.5 x 2^n, + // In all the above cases, normalized mantissa returned by frexp routine will + // be exactly equal to 0.5 while exponent will be 0,1,2,3...n + // Perform division to multiplication transform only if divisor is a POT value. + if(frexp((double)f, &exp) != 0.5) { return nullptr; } + + // Limit the range of acceptable exponents + if(exp < -14 || exp > 15) { return nullptr; } + + // Since divisor is a POT number, hence its reciprocal will never + // overflow 11 bits precision range of Float16 + // value if exponent returned by frexp routine strictly lie + // within the exponent range of normal min(0x1.0P-14) and + // normal max(0x1.ffcP+15) values. + // Thus we can safely compute the reciprocal of divisor without + // any concerns about the precision loss and transform the division + // into a multiplication operation. + float reciprocal = ((float)1.0) / f; + + assert(frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2"); + + // return multiplication by the reciprocal + return (new MulHFNode(in(1), phase->makecon(TypeH::make(reciprocal)))); +} //============================================================================= //------------------------------Value------------------------------------------ @@ -1377,39 +1503,48 @@ const Type* ModLNode::Value(PhaseGVN* phase) const { return TypeLong::make( i1->get_con() % i2->get_con() ); } +Node *UModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { + return unsigned_mod_ideal(phase, can_reshape, this); +} -//============================================================================= -//------------------------------Value------------------------------------------ -const Type* ModFNode::Value(PhaseGVN* phase) const { - // Either input is TOP ==> the result is TOP - const Type *t1 = phase->type( in(1) ); - const Type *t2 = phase->type( in(2) ); - if( t1 == Type::TOP ) return Type::TOP; - if( t2 == Type::TOP ) return Type::TOP; +const Type* UModLNode::Value(PhaseGVN* phase) const { + return unsigned_mod_value(phase, this); +} - // Either input is BOTTOM ==> the result is the local BOTTOM - const Type *bot = bottom_type(); - if( (t1 == bot) || (t2 == bot) || - (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) - return bot; +Node* ModFNode::Ideal(PhaseGVN* phase, bool can_reshape) { + if (!can_reshape) { + return nullptr; + } + + // Either input is TOP ==> the result is TOP + const Type* t1 = phase->type(dividend()); + const Type* t2 = phase->type(divisor()); + if (t1 == Type::TOP || t2 == Type::TOP) { + return phase->C->top(); + } // If either number is not a constant, we know nothing. if ((t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon)) { - return Type::FLOAT; // note: x%x can be either NaN or 0 + return nullptr; // note: x%x can be either NaN or 0 } float f1 = t1->getf(); float f2 = t2->getf(); - jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1 - jint x2 = jint_cast(f2); + jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1 + jint x2 = jint_cast(f2); // If either is a NaN, return an input NaN - if (g_isnan(f1)) return t1; - if (g_isnan(f2)) return t2; + if (g_isnan(f1)) { + return replace_with_con(phase, t1); + } + if (g_isnan(f2)) { + return replace_with_con(phase, t2); + } // If an operand is infinity or the divisor is +/- zero, punt. - if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) - return Type::FLOAT; + if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) { + return nullptr; + } // We must be modulo'ing 2 float constants. // Make sure that the sign of the fmod is equal to the sign of the dividend @@ -1418,51 +1553,43 @@ const Type* ModFNode::Value(PhaseGVN* phase) const { xr ^= min_jint; } - return TypeF::make(jfloat_cast(xr)); + return replace_with_con(phase, TypeF::make(jfloat_cast(xr))); } -//============================================================================= -//------------------------------Idealize--------------------------------------- -Node *UModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { - return unsigned_mod_ideal(phase, can_reshape, this); -} - -const Type* UModLNode::Value(PhaseGVN* phase) const { - return unsigned_mod_value(phase, this); -} +Node* ModDNode::Ideal(PhaseGVN* phase, bool can_reshape) { + if (!can_reshape) { + return nullptr; + } -//============================================================================= -//------------------------------Value------------------------------------------ -const Type* ModDNode::Value(PhaseGVN* phase) const { // Either input is TOP ==> the result is TOP - const Type *t1 = phase->type( in(1) ); - const Type *t2 = phase->type( in(2) ); - if( t1 == Type::TOP ) return Type::TOP; - if( t2 == Type::TOP ) return Type::TOP; - - // Either input is BOTTOM ==> the result is the local BOTTOM - const Type *bot = bottom_type(); - if( (t1 == bot) || (t2 == bot) || - (t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) ) - return bot; + const Type* t1 = phase->type(dividend()); + const Type* t2 = phase->type(divisor()); + if (t1 == Type::TOP || t2 == Type::TOP) { + return nullptr; + } // If either number is not a constant, we know nothing. if ((t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon)) { - return Type::DOUBLE; // note: x%x can be either NaN or 0 + return nullptr; // note: x%x can be either NaN or 0 } double f1 = t1->getd(); double f2 = t2->getd(); - jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1 - jlong x2 = jlong_cast(f2); + jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1 + jlong x2 = jlong_cast(f2); // If either is a NaN, return an input NaN - if (g_isnan(f1)) return t1; - if (g_isnan(f2)) return t2; + if (g_isnan(f1)) { + return replace_with_con(phase, t1); + } + if (g_isnan(f2)) { + return replace_with_con(phase, t2); + } // If an operand is infinity or the divisor is +/- zero, punt. - if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) - return Type::DOUBLE; + if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) { + return nullptr; + } // We must be modulo'ing 2 double constants. // Make sure that the sign of the fmod is equal to the sign of the dividend @@ -1471,7 +1598,36 @@ const Type* ModDNode::Value(PhaseGVN* phase) const { xr ^= min_jlong; } - return TypeD::make(jdouble_cast(xr)); + return replace_with_con(phase, TypeD::make(jdouble_cast(xr))); +} + +Node* ModFloatingNode::replace_with_con(PhaseGVN* phase, const Type* con) { + Compile* C = phase->C; + Node* con_node = phase->makecon(con); + CallProjections projs; + extract_projections(&projs, false, false); + C->gvn_replace_by(projs.fallthrough_proj, in(TypeFunc::Control)); + if (projs.fallthrough_catchproj != nullptr) { + C->gvn_replace_by(projs.fallthrough_catchproj, in(TypeFunc::Control)); + } + if (projs.fallthrough_memproj != nullptr) { + C->gvn_replace_by(projs.fallthrough_memproj, in(TypeFunc::Memory)); + } + if (projs.catchall_memproj != nullptr) { + C->gvn_replace_by(projs.catchall_memproj, C->top()); + } + if (projs.fallthrough_ioproj != nullptr) { + C->gvn_replace_by(projs.fallthrough_ioproj, in(TypeFunc::I_O)); + } + assert(projs.catchall_ioproj == nullptr, "no exceptions from floating mod"); + assert(projs.catchall_catchproj == nullptr, "no exceptions from floating mod"); + if (projs.resproj != nullptr) { + C->gvn_replace_by(projs.resproj, con_node); + } + C->gvn_replace_by(this, C->top()); + C->remove_macro_node(this); + disconnect_inputs(C); + return nullptr; } //============================================================================= diff --git a/src/hotspot/share/opto/divnode.hpp b/src/hotspot/share/opto/divnode.hpp index b9a4a32d156e9..a926f4ab12289 100644 --- a/src/hotspot/share/opto/divnode.hpp +++ b/src/hotspot/share/opto/divnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #ifndef SHARE_OPTO_DIVNODE_HPP #define SHARE_OPTO_DIVNODE_HPP +#include "opto/callnode.hpp" #include "opto/multnode.hpp" #include "opto/node.hpp" #include "opto/opcodes.hpp" @@ -77,6 +78,20 @@ class DivFNode : public Node { virtual uint ideal_reg() const { return Op_RegF; } }; + +//------------------------------DivHFNode-------------------------------------- +// Half float division +class DivHFNode : public Node { +public: + DivHFNode(Node* c, Node* dividend, Node* divisor) : Node(c, dividend, divisor) {} + virtual int Opcode() const; + virtual Node* Identity(PhaseGVN* phase); + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); + virtual const Type* Value(PhaseGVN* phase) const; + virtual const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } +}; + //------------------------------DivDNode--------------------------------------- // Double division class DivDNode : public Node { @@ -140,26 +155,41 @@ class ModLNode : public Node { virtual uint ideal_reg() const { return Op_RegL; } }; -//------------------------------ModFNode--------------------------------------- +// Base class for float and double modulus +class ModFloatingNode : public CallLeafNode { +protected: + Node* replace_with_con(PhaseGVN* phase, const Type* con); + +public: + ModFloatingNode(Compile* C, const TypeFunc* tf, const char *name); +}; + // Float Modulus -class ModFNode : public Node { +class ModFNode : public ModFloatingNode { +private: + Node* dividend() const { return in(TypeFunc::Parms + 0); } + Node* divisor() const { return in(TypeFunc::Parms + 1); } + public: - ModFNode( Node *c, Node *in1, Node *in2 ) : Node(c,in1, in2) {} + ModFNode(Compile* C, Node* a, Node* b); virtual int Opcode() const; - virtual const Type* Value(PhaseGVN* phase) const; - virtual const Type *bottom_type() const { return Type::FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } + virtual uint size_of() const { return sizeof(*this); } + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; -//------------------------------ModDNode--------------------------------------- // Double Modulus -class ModDNode : public Node { +class ModDNode : public ModFloatingNode { +private: + Node* dividend() const { return in(TypeFunc::Parms + 0); } + Node* divisor() const { return in(TypeFunc::Parms + 2); } + public: - ModDNode( Node *c, Node *in1, Node *in2 ) : Node(c, in1, in2) {} + ModDNode(Compile* C, Node* a, Node* b); virtual int Opcode() const; - virtual const Type* Value(PhaseGVN* phase) const; - virtual const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } + virtual uint size_of() const { return sizeof(*this); } + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------UModINode--------------------------------------- diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index 0a5e27ed5b13f..f4b36674968f5 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciCallSite.hpp" #include "ci/ciMethodHandle.hpp" #include "ci/ciSymbols.hpp" @@ -50,33 +49,40 @@ #include "jfr/jfr.hpp" #endif -static void print_trace_type_profile(outputStream* out, int depth, ciKlass* prof_klass, int site_count, int receiver_count) { - CompileTask::print_inline_indent(depth, out); +static void print_trace_type_profile(outputStream* out, int depth, ciKlass* prof_klass, int site_count, int receiver_count, + bool with_deco) { + if (with_deco) { + CompileTask::print_inline_indent(depth, out); + } out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count); prof_klass->name()->print_symbol_on(out); - out->cr(); + if (with_deco) { + out->cr(); + } } -static void trace_type_profile(Compile* C, ciMethod* method, int depth, int bci, ciMethod* prof_method, - ciKlass* prof_klass, int site_count, int receiver_count) { +static void trace_type_profile(Compile* C, ciMethod* method, JVMState* jvms, + ciMethod* prof_method, ciKlass* prof_klass, int site_count, int receiver_count) { + int depth = jvms->depth() - 1; + int bci = jvms->bci(); if (TraceTypeProfile || C->print_inlining()) { - outputStream* out = tty; if (!C->print_inlining()) { if (!PrintOpto && !PrintCompilation) { method->print_short_name(); tty->cr(); } CompileTask::print_inlining_tty(prof_method, depth, bci, InliningResult::SUCCESS); + print_trace_type_profile(tty, depth, prof_klass, site_count, receiver_count, true); } else { - out = C->print_inlining_stream(); + auto stream = C->inline_printer()->record(method, jvms, InliningResult::SUCCESS); + print_trace_type_profile(stream, depth, prof_klass, site_count, receiver_count, false); } - print_trace_type_profile(out, depth, prof_klass, site_count, receiver_count); } LogTarget(Debug, jit, inlining) lt; if (lt.is_enabled()) { LogStream ls(lt); - print_trace_type_profile(&ls, depth, prof_klass, site_count, receiver_count); + print_trace_type_profile(&ls, depth, prof_klass, site_count, receiver_count, true); } } @@ -295,17 +301,19 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool if (miss_cg != nullptr) { if (next_hit_cg != nullptr) { assert(speculative_receiver_type == nullptr, "shouldn't end up here if we used speculation"); - trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)); + trace_type_profile(C, jvms->method(), jvms, next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)); // We don't need to record dependency on a receiver here and below. // Whenever we inline, the dependency is added by Parse::Parse(). miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX); } if (miss_cg != nullptr) { ciKlass* k = speculative_receiver_type != nullptr ? speculative_receiver_type : profile.receiver(0); - trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, k, site_count, receiver_count); + trace_type_profile(C, jvms->method(), jvms, receiver_method, k, site_count, receiver_count); float hit_prob = speculative_receiver_type != nullptr ? 1.0 : profile.receiver_prob(0); CallGenerator* cg = CallGenerator::for_predicted_call(k, miss_cg, hit_cg, hit_prob); - if (cg != nullptr) return cg; + if (cg != nullptr) { + return cg; + } } } } @@ -372,9 +380,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // Use a more generic tactic, like a simple call. if (call_does_dispatch) { const char* msg = "virtual call"; - if (C->print_inlining()) { - print_inlining(callee, jvms->depth() - 1, jvms->bci(), InliningResult::FAILURE, msg); - } + C->inline_printer()->record(callee, jvms, InliningResult::FAILURE, msg); C->log_inline_failure(msg); if (IncrementalInlineVirtual && allow_inline) { return CallGenerator::for_late_inline_virtual(callee, vtable_index, prof_factor); // attempt to inline through virtual call later @@ -513,8 +519,6 @@ void Parse::do_call() { // our contribution to it is cleaned up right here. kill_dead_locals(); - C->print_inlining_assert_ready(); - // Set frequently used booleans const bool is_virtual = bc() == Bytecodes::_invokevirtual; const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface; @@ -943,7 +947,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { Node* ex_klass_node = nullptr; if (has_exception_handler() && !ex_type->klass_is_exact()) { Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes()); - ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT)); + ex_klass_node = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT)); // Compute the exception klass a little more cleverly. // Obvious solution is to simple do a LoadKlass from the 'ex_node'. @@ -961,7 +965,7 @@ void Parse::catch_inline_exceptions(SafePointNode* ex_map) { continue; } Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes()); - Node* k = _gvn.transform( LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT)); + Node* k = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeInstKlassPtr::OBJECT)); ex_klass_node->init_req( i, k ); } ex_klass_node = _gvn.transform(ex_klass_node); diff --git a/src/hotspot/share/opto/domgraph.cpp b/src/hotspot/share/opto/domgraph.cpp index 6bed1b1a2bd57..a80358e1d0f7d 100644 --- a/src/hotspot/share/opto/domgraph.cpp +++ b/src/hotspot/share/opto/domgraph.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/vectset.hpp" #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp index 6d845c86a5f88..0ab911c18be87 100644 --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/barrierSet.hpp" @@ -982,10 +981,11 @@ void ConnectionGraph::reduce_phi_on_cmp(Node* cmp) { Node* other = cmp->in(1)->is_Con() ? cmp->in(1) : cmp->in(2); Node* zero = _igvn->intcon(0); + Node* one = _igvn->intcon(1); BoolTest::mask mask = cmp->unique_out()->as_Bool()->_test._test; // This Phi will merge the result of the Cmps split through the Phi - Node* res_phi = _igvn->transform(PhiNode::make(ophi->in(0), zero, TypeInt::INT)); + Node* res_phi = PhiNode::make(ophi->in(0), zero, TypeInt::INT); for (uint i=1; ireq(); i++) { Node* ophi_input = ophi->in(i); @@ -993,7 +993,12 @@ void ConnectionGraph::reduce_phi_on_cmp(Node* cmp) { const TypeInt* tcmp = optimize_ptr_compare(ophi_input, other); if (tcmp->singleton()) { - res_phi_input = _igvn->makecon(tcmp); + if ((mask == BoolTest::mask::eq && tcmp == TypeInt::CC_EQ) || + (mask == BoolTest::mask::ne && tcmp == TypeInt::CC_GT)) { + res_phi_input = one; + } else { + res_phi_input = zero; + } } else { Node* ncmp = _igvn->transform(cmp->clone()); ncmp->set_req(1, ophi_input); @@ -1005,7 +1010,8 @@ void ConnectionGraph::reduce_phi_on_cmp(Node* cmp) { res_phi->set_req(i, res_phi_input); } - Node* new_cmp = _igvn->transform(new CmpINode(res_phi, zero)); + // This CMP always compares whether the output of "res_phi" is TRUE as far as the "mask". + Node* new_cmp = _igvn->transform(new CmpINode(_igvn->transform(res_phi), (mask == BoolTest::mask::eq) ? one : zero)); _igvn->replace_node(cmp, new_cmp); } @@ -4605,6 +4611,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, op == Op_StrEquals || op == Op_VectorizedHashCode || op == Op_StrIndexOf || op == Op_StrIndexOfChar || op == Op_SubTypeCheck || + op == Op_ReinterpretS2HF || BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(use))) { n->dump(); use->dump(); diff --git a/src/hotspot/share/opto/gcm.cpp b/src/hotspot/share/opto/gcm.cpp index ebdefe597ff1f..c9cdd235f03bb 100644 --- a/src/hotspot/share/opto/gcm.cpp +++ b/src/hotspot/share/opto/gcm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/vectset.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" @@ -1265,13 +1264,15 @@ bool PhaseCFG::is_cheaper_block(Block* LCA, Node* self, uint target_latency, return C->randomized_select(cand_cnt); } - // Better Frequency - if (LCA->_freq < least_freq) { + const double delta = 1 + PROB_UNLIKELY_MAG(4); + + // Better Frequency. Add a small delta to the comparison to not needlessly + // hoist because of, e.g., small numerical inaccuracies. + if (LCA->_freq * delta < least_freq) { return true; } // Otherwise, choose with latency - const double delta = 1 + PROB_UNLIKELY_MAG(4); if (!in_latency && // No block containing latency LCA->_freq < least_freq * delta && // No worse frequency target_latency >= end_latency && // within latency range diff --git a/src/hotspot/share/opto/generateOptoStub.cpp b/src/hotspot/share/opto/generateOptoStub.cpp index b6f09dcc439f3..b13504ab10e56 100644 --- a/src/hotspot/share/opto/generateOptoStub.cpp +++ b/src/hotspot/share/opto/generateOptoStub.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/resourceArea.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 0cc68c426398e..2af70960f5469 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciUtilities.hpp" #include "classfile/javaClasses.hpp" #include "ci/ciObjArray.hpp" @@ -1201,7 +1200,7 @@ Node* GraphKit::load_object_klass(Node* obj) { Node* akls = AllocateNode::Ideal_klass(obj, &_gvn); if (akls != nullptr) return akls; Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); - return _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), k_adr, TypeInstPtr::KLASS)); + return _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS)); } //-------------------------load_array_length----------------------------------- @@ -2780,7 +2779,7 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, No if (might_be_cache && mem != nullptr) { kmem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(C->get_alias_index(gvn.type(p2)->is_ptr())) : mem; } - Node *nkls = gvn.transform(LoadKlassNode::make(gvn, nullptr, kmem, p2, gvn.type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL)); + Node* nkls = gvn.transform(LoadKlassNode::make(gvn, kmem, p2, gvn.type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL)); // Compile speed common case: ARE a subtype and we canNOT fail if (superklass == nkls) { diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 42726a34d015e..f6ec1a72506ab 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/resourceArea.hpp" #include "opto/chaitin.hpp" #include "opto/idealGraphPrinter.hpp" @@ -210,7 +209,7 @@ void IdealGraphPrinter::end_head() { void IdealGraphPrinter::print_attr(const char *name, intptr_t val) { stringStream stream; - stream.print(INTX_FORMAT, val); + stream.print("%zd", val); print_attr(name, stream.freeze()); } @@ -543,6 +542,31 @@ void IdealGraphPrinter::visit_node(Node* n, bool edges) { assert(s2.size() < sizeof(buffer), "size in range"); print_prop("dump_spec", buffer); + const TypePtr* adr_type = node->adr_type(); + if (adr_type != nullptr && C->have_alias_type(adr_type)) { + Compile::AliasType* at = C->alias_type(adr_type); + if (at != nullptr) { + print_prop("alias_index", at->index()); + // The value of at->field(), if present, is already dumped in the + // "source"/"destination" properties. + const Type* element = at->element(); + if (element != nullptr) { + stringStream element_stream; + element->dump_on(&element_stream); + print_prop("alias_element", element_stream.freeze()); + } + if (at->is_rewritable()) { + print_prop("alias_is_rewritable", "true"); + } + if (at->is_volatile()) { + print_prop("alias_is_volatile", "true"); + } + if (at->general_index() != at->index()) { + print_prop("alias_general_index", at->general_index()); + } + } + } + if (node->is_block_proj()) { print_prop("is_block_proj", "true"); } @@ -945,7 +969,7 @@ void IdealGraphPrinter::init_network_stream() { } else { // It would be nice if we could shut down cleanly but it should // be an error if we can't connect to the visualizer. - fatal("Couldn't connect to visualizer at %s:" INTX_FORMAT, + fatal("Couldn't connect to visualizer at %s:%zd", PrintIdealGraphAddress, PrintIdealGraphPort); } } diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index 042ac694843cc..aab35c7a9088d 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,7 +98,7 @@ class IdealGraphPrinter : public CHeapObj { outputStream *_output; ciMethod *_current_method; int _depth; - char buffer[512]; + char buffer[2048]; bool _should_send_method; PhaseChaitin* _chaitin; bool _traverse_outs; diff --git a/src/hotspot/share/opto/idealKit.cpp b/src/hotspot/share/opto/idealKit.cpp index baa055bc60aeb..528a0e294119e 100644 --- a/src/hotspot/share/opto/idealKit.cpp +++ b/src/hotspot/share/opto/idealKit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" #include "opto/cfgnode.hpp" diff --git a/src/hotspot/share/opto/ifg.cpp b/src/hotspot/share/opto/ifg.cpp index d12698121b939..3793983b62aaf 100644 --- a/src/hotspot/share/opto/ifg.cpp +++ b/src/hotspot/share/opto/ifg.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/oopMap.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index 3c50e7993c208..5660213556032 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciTypeFlow.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/opto/indexSet.cpp b/src/hotspot/share/opto/indexSet.cpp index e0c063145c6ef..7f02f01c83fbb 100644 --- a/src/hotspot/share/opto/indexSet.cpp +++ b/src/hotspot/share/opto/indexSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/chaitin.hpp" #include "opto/compile.hpp" @@ -229,6 +228,11 @@ IndexSet::IndexSet (IndexSet *set) { _count = set->_count; _current_block_limit = set->_current_block_limit; _max_blocks = set->_max_blocks; + if (set->_blocks == nullptr) { + _blocks = nullptr; + _arena = arena(); + return; + } if (_max_blocks <= preallocated_block_list_size) { _blocks = _preallocated_block_list; } else { @@ -259,15 +263,8 @@ void IndexSet::initialize(uint max_elements) { _count = 0; _current_block_limit = 0; _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block; - - if (_max_blocks <= preallocated_block_list_size) { - _blocks = _preallocated_block_list; - } else { - _blocks = (IndexSet::BitBlock**) arena()->AmallocWords(sizeof(IndexSet::BitBlock*) * _max_blocks); - } - for (uint i = 0; i < _max_blocks; i++) { - set_block(i, &_empty_block); - } + _arena = arena(); + _blocks = nullptr; } //---------------------------- IndexSet::initialize()------------------------------ @@ -284,15 +281,8 @@ void IndexSet::initialize(uint max_elements, Arena *arena) { _count = 0; _current_block_limit = 0; _max_blocks = (max_elements + bits_per_block - 1) / bits_per_block; - - if (_max_blocks <= preallocated_block_list_size) { - _blocks = _preallocated_block_list; - } else { - _blocks = (IndexSet::BitBlock**) arena->AmallocWords(sizeof(IndexSet::BitBlock*) * _max_blocks); - } - for (uint i = 0; i < _max_blocks; i++) { - set_block(i, &_empty_block); - } + _arena = arena; + _blocks = nullptr; } //---------------------------- IndexSet::swap() ----------------------------- @@ -305,6 +295,12 @@ void IndexSet::swap(IndexSet *set) { set->check_watch("swap", _serial_number); #endif + if (_blocks == nullptr && set->_blocks == nullptr) { + return; + } + initialize_if_needed(); + set->initialize_if_needed(); + uint max = MAX2(_current_block_limit, set->_current_block_limit); for (uint i = 0; i < max; i++) { BitBlock *temp = _blocks[i]; @@ -345,7 +341,7 @@ void IndexSet::tally_iteration_statistics() const { inc_stat_counter(&_total_bits, count()); for (uint i = 0; i < _max_blocks; i++) { - if (_blocks[i] != &_empty_block) { + if (_blocks != nullptr && _blocks[i] != &_empty_block) { inc_stat_counter(&_total_used_blocks, 1); } else { inc_stat_counter(&_total_unused_blocks, 1); diff --git a/src/hotspot/share/opto/indexSet.hpp b/src/hotspot/share/opto/indexSet.hpp index b4d4237b13dd0..f628bade3fa94 100644 --- a/src/hotspot/share/opto/indexSet.hpp +++ b/src/hotspot/share/opto/indexSet.hpp @@ -204,6 +204,8 @@ class IndexSet : public ResourceObj { // The number of top level array entries in use uint _max_blocks; + Arena* _arena; + // Our assertions need to know the maximum number allowed in the set #ifdef ASSERT uint _max_elements; @@ -252,10 +254,12 @@ class IndexSet : public ResourceObj { void clear() { _count = 0; - for (uint i = 0; i < _current_block_limit; i++) { - BitBlock *block = _blocks[i]; - if (block != &_empty_block) { - free_block(i); + if (_blocks != nullptr) { + for (uint i = 0; i < _current_block_limit; i++) { + BitBlock* block = _blocks[i]; + if (block != &_empty_block) { + free_block(i); + } } } _current_block_limit = 0; @@ -266,6 +270,9 @@ class IndexSet : public ResourceObj { bool is_empty() const { return _count == 0; } bool member(uint element) const { + if (_blocks == nullptr) { + return false; + } return get_block_containing(element)->member(element); } @@ -273,6 +280,7 @@ class IndexSet : public ResourceObj { if (element == 0) { return 0; } + initialize_if_needed(); BitBlock *block = get_block_containing(element); if (block == &_empty_block) { block = alloc_block_containing(element); @@ -285,6 +293,9 @@ class IndexSet : public ResourceObj { } bool remove(uint element) { + if (_blocks == nullptr) { + return false; + } BitBlock *block = get_block_containing(element); bool present = block->remove(element); if (present) { @@ -319,6 +330,21 @@ class IndexSet : public ResourceObj { // from the static Arena member. void initialize(uint max_element, Arena *arena); + // Top level array of pointers to BitBlocks is allocated on first element addition to avoid wasting memory. + void initialize_if_needed() { + if (_blocks != nullptr) { + return; + } + if (_max_blocks <= preallocated_block_list_size) { + _blocks = _preallocated_block_list; + } else { + _blocks = (IndexSet::BitBlock**) _arena->AmallocWords(sizeof(IndexSet::BitBlock*) * _max_blocks); + } + for (uint i = 0; i < _max_blocks; i++) { + set_block(i, &_empty_block); + } + } + // Exchange two sets void swap(IndexSet *set); diff --git a/src/hotspot/share/opto/intrinsicnode.cpp b/src/hotspot/share/opto/intrinsicnode.cpp index 010579722bb10..e67352d85bdcc 100644 --- a/src/hotspot/share/opto/intrinsicnode.cpp +++ b/src/hotspot/share/opto/intrinsicnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/intrinsicnode.hpp" #include "opto/addnode.hpp" #include "opto/mulnode.hpp" diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 0079f366640e8..8d2809f987ca0 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" #include "gc/shared/gc_globals.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 40b19eecd9f65..6f651db58ce63 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,9 @@ * */ -#include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "ci/ciUtilities.inline.hpp" +#include "ci/ciSymbols.hpp" #include "classfile/vmIntrinsics.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compileLog.hpp" @@ -120,9 +120,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { const char *inline_msg = is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"; CompileTask::print_inlining_ul(callee, jvms->depth() - 1, bci, InliningResult::SUCCESS, inline_msg); - if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining(callee, jvms->depth() - 1, bci, InliningResult::SUCCESS, inline_msg); - } + C->inline_printer()->record(callee, jvms, InliningResult::SUCCESS, inline_msg); C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); if (C->log()) { C->log()->elem("intrinsic id='%s'%s nodes='%d'", @@ -132,7 +130,6 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { } // Push the result from the inlined method onto the stack. kit.push_result(); - C->print_inlining_update(this); return kit.transfer_exceptions_into_jvms(); } @@ -148,9 +145,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { : "failed to inline (intrinsic), method not annotated"; } CompileTask::print_inlining_ul(callee, jvms->depth() - 1, bci, InliningResult::FAILURE, msg); - if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining(callee, jvms->depth() - 1, bci, InliningResult::FAILURE, msg); - } + C->inline_printer()->record(callee, jvms, InliningResult::FAILURE, msg); } else { // Root compile ResourceMark rm; @@ -165,7 +160,6 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { } } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); - C->print_inlining_update(this); return nullptr; } @@ -191,9 +185,8 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) { const char *inline_msg = is_virtual() ? "(intrinsic, virtual, predicate)" : "(intrinsic, predicate)"; CompileTask::print_inlining_ul(callee, jvms->depth() - 1, bci, InliningResult::SUCCESS, inline_msg); - if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining(callee, jvms->depth() - 1, bci, InliningResult::SUCCESS, inline_msg); - } + C->inline_printer()->record(callee, jvms, InliningResult::SUCCESS, inline_msg); + C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); if (C->log()) { C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'", @@ -209,9 +202,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) { // Not a root compile. const char* msg = "failed to generate predicate for intrinsic"; CompileTask::print_inlining_ul(kit.callee(), jvms->depth() - 1, bci, InliningResult::FAILURE, msg); - if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining(kit.callee(), jvms->depth() - 1, bci, InliningResult::FAILURE, msg); - } + C->inline_printer()->record(kit.callee(), jvms, InliningResult::FAILURE, msg); } else { // Root compile ResourceMark rm; @@ -221,9 +212,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) { is_virtual() ? " (virtual)" : "", bci); const char *msg = msg_stream.freeze(); log_debug(jit, inlining)("%s", msg); - if (C->print_intrinsics() || C->print_inlining()) { - C->print_inlining_stream()->print("%s", msg); - } + C->inline_printer()->record(kit.callee(), jvms, InliningResult::FAILURE, msg); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); return nullptr; @@ -527,10 +516,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_isAssignableFrom: return inline_native_subtype_check(); case vmIntrinsics::_isInstance: - case vmIntrinsics::_getModifiers: - case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: return inline_native_Class_query(intrinsic_id()); @@ -543,7 +528,8 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_longBitsToDouble: case vmIntrinsics::_floatToFloat16: case vmIntrinsics::_float16ToFloat: return inline_fp_conversions(intrinsic_id()); - + case vmIntrinsics::_sqrt_float16: return inline_fp16_operations(intrinsic_id(), 1); + case vmIntrinsics::_fma_float16: return inline_fp16_operations(intrinsic_id(), 3); case vmIntrinsics::_floatIsFinite: case vmIntrinsics::_floatIsInfinite: case vmIntrinsics::_doubleIsFinite: @@ -2140,18 +2126,18 @@ bool LibraryCallKit::inline_number_methods(vmIntrinsics::ID id) { Node* arg = argument(0); Node* n = nullptr; switch (id) { - case vmIntrinsics::_numberOfLeadingZeros_i: n = new CountLeadingZerosINode( arg); break; - case vmIntrinsics::_numberOfLeadingZeros_l: n = new CountLeadingZerosLNode( arg); break; - case vmIntrinsics::_numberOfTrailingZeros_i: n = new CountTrailingZerosINode(arg); break; - case vmIntrinsics::_numberOfTrailingZeros_l: n = new CountTrailingZerosLNode(arg); break; - case vmIntrinsics::_bitCount_i: n = new PopCountINode( arg); break; - case vmIntrinsics::_bitCount_l: n = new PopCountLNode( arg); break; - case vmIntrinsics::_reverseBytes_c: n = new ReverseBytesUSNode(nullptr, arg); break; - case vmIntrinsics::_reverseBytes_s: n = new ReverseBytesSNode( nullptr, arg); break; - case vmIntrinsics::_reverseBytes_i: n = new ReverseBytesINode( nullptr, arg); break; - case vmIntrinsics::_reverseBytes_l: n = new ReverseBytesLNode( nullptr, arg); break; - case vmIntrinsics::_reverse_i: n = new ReverseINode(nullptr, arg); break; - case vmIntrinsics::_reverse_l: n = new ReverseLNode(nullptr, arg); break; + case vmIntrinsics::_numberOfLeadingZeros_i: n = new CountLeadingZerosINode( arg); break; + case vmIntrinsics::_numberOfLeadingZeros_l: n = new CountLeadingZerosLNode( arg); break; + case vmIntrinsics::_numberOfTrailingZeros_i: n = new CountTrailingZerosINode(arg); break; + case vmIntrinsics::_numberOfTrailingZeros_l: n = new CountTrailingZerosLNode(arg); break; + case vmIntrinsics::_bitCount_i: n = new PopCountINode( arg); break; + case vmIntrinsics::_bitCount_l: n = new PopCountLNode( arg); break; + case vmIntrinsics::_reverseBytes_c: n = new ReverseBytesUSNode( arg); break; + case vmIntrinsics::_reverseBytes_s: n = new ReverseBytesSNode( arg); break; + case vmIntrinsics::_reverseBytes_i: n = new ReverseBytesINode( arg); break; + case vmIntrinsics::_reverseBytes_l: n = new ReverseBytesLNode( arg); break; + case vmIntrinsics::_reverse_i: n = new ReverseINode( arg); break; + case vmIntrinsics::_reverse_l: n = new ReverseLNode( arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); @@ -3018,7 +3004,7 @@ bool LibraryCallKit::inline_native_classID() { IdealKit ideal(this); #define __ ideal. IdealVariable result(ideal); __ declarations_done(); - Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), + Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), basic_plus_adr(cls, java_lang_Class::klass_offset()), TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); @@ -3048,7 +3034,7 @@ bool LibraryCallKit::inline_native_classID() { ideal.set(result, _gvn.transform(new URShiftLNode(kls_trace_id_raw, ideal.ConI(TRACE_ID_SHIFT)))); } __ else_(); { - Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), + Node* array_kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), basic_plus_adr(cls, java_lang_Class::array_klass_offset()), TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); __ if_then(array_kls, BoolTest::ne, null()); { @@ -3773,6 +3759,20 @@ bool LibraryCallKit::inline_native_Continuation_pinning(bool unpin) { Node* test_pin_count_over_underflow = _gvn.transform(new BoolNode(pin_count_cmp, BoolTest::eq)); IfNode* iff_pin_count_over_underflow = create_and_map_if(control(), test_pin_count_over_underflow, PROB_MIN, COUNT_UNKNOWN); + // True branch, pin count over/underflow. + Node* pin_count_over_underflow = _gvn.transform(new IfTrueNode(iff_pin_count_over_underflow)); + { + // Trap (but not deoptimize (Action_none)) and continue in the interpreter + // which will throw IllegalStateException for pin count over/underflow. + // No memory changed so far - we can use memory create by reset_memory() + // at the beginning of this intrinsic. No need to call reset_memory() again. + PreserveJVMState pjvms(this); + set_control(pin_count_over_underflow); + uncommon_trap(Deoptimization::Reason_intrinsic, + Deoptimization::Action_none); + assert(stopped(), "invariant"); + } + // False branch, no pin count over/underflow. Increment or decrement pin count and store back. Node* valid_pin_count = _gvn.transform(new IfFalseNode(iff_pin_count_over_underflow)); set_control(valid_pin_count); @@ -3784,20 +3784,7 @@ bool LibraryCallKit::inline_native_Continuation_pinning(bool unpin) { next_pin_count = _gvn.transform(new AddINode(pin_count, _gvn.intcon(1))); } - Node* updated_pin_count_memory = store_to_memory(control(), pin_count_offset, next_pin_count, T_INT, MemNode::unordered); - - // True branch, pin count over/underflow. - Node* pin_count_over_underflow = _gvn.transform(new IfTrueNode(iff_pin_count_over_underflow)); - { - // Trap (but not deoptimize (Action_none)) and continue in the interpreter - // which will throw IllegalStateException for pin count over/underflow. - PreserveJVMState pjvms(this); - set_control(pin_count_over_underflow); - set_all_memory(input_memory_state); - uncommon_trap_exact(Deoptimization::Reason_intrinsic, - Deoptimization::Action_none); - assert(stopped(), "invariant"); - } + store_to_memory(control(), pin_count_offset, next_pin_count, T_INT, MemNode::unordered); // Result of top level CFG and Memory. RegionNode* result_rgn = new RegionNode(PATH_LIMIT); @@ -3807,7 +3794,7 @@ bool LibraryCallKit::inline_native_Continuation_pinning(bool unpin) { result_rgn->init_req(_true_path, _gvn.transform(valid_pin_count)); result_rgn->init_req(_false_path, _gvn.transform(continuation_is_null)); - result_mem->init_req(_true_path, _gvn.transform(updated_pin_count_memory)); + result_mem->init_req(_true_path, _gvn.transform(reset_memory())); result_mem->init_req(_false_path, _gvn.transform(input_memory_state)); // Set output state. @@ -3841,7 +3828,7 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror, if (region == nullptr) never_see_null = true; Node* p = basic_plus_adr(mirror, offset); const TypeKlassPtr* kls_type = TypeInstKlassPtr::OBJECT_OR_NULL; - Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type)); + Node* kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type)); Node* null_ctl = top(); kls = null_check_oop(kls, &null_ctl, never_see_null); if (region != nullptr) { @@ -3871,7 +3858,7 @@ Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, i } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, - Klass::access_flags_offset(), TypeInt::INT, T_INT); + Klass::access_flags_offset(), TypeInt::CHAR, T_CHAR); } // Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. @@ -3902,22 +3889,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { prim_return_value = intcon(0); obj = argument(1); break; - case vmIntrinsics::_getModifiers: - prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - assert(is_power_of_2((int)JVM_ACC_WRITTEN_FLAGS+1), "change next line"); - return_type = TypeInt::make(0, JVM_ACC_WRITTEN_FLAGS, Type::WidenMin); - break; - case vmIntrinsics::_isInterface: - prim_return_value = intcon(0); - break; - case vmIntrinsics::_isArray: - prim_return_value = intcon(0); - expect_prim = true; // cf. ObjectStreamClass.getClassSignature - break; - case vmIntrinsics::_isPrimitive: - prim_return_value = intcon(1); - expect_prim = true; // obviously - break; case vmIntrinsics::_isHidden: prim_return_value = intcon(0); break; @@ -3927,7 +3898,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { break; case vmIntrinsics::_getClassAccessFlags: prim_return_value = intcon(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); - return_type = TypeInt::INT; // not bool! 6297094 + return_type = TypeInt::CHAR; break; default: fatal_unexpected_iid(id); @@ -3986,33 +3957,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { query_value = gen_instanceof(obj, kls, safe_for_replace); break; - case vmIntrinsics::_getModifiers: - p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); - break; - - case vmIntrinsics::_isInterface: - // (To verify this code sequence, check the asserts in JVM_IsInterface.) - if (generate_interface_guard(kls, region) != nullptr) - // A guard was added. If the guard is taken, it was an interface. - phi->add_req(intcon(1)); - // If we fall through, it's a plain class. - query_value = intcon(0); - break; - - case vmIntrinsics::_isArray: - // (To verify this code sequence, check the asserts in JVM_IsArrayClass.) - if (generate_array_guard(kls, region) != nullptr) - // A guard was added. If the guard is taken, it was an array. - phi->add_req(intcon(1)); - // If we fall through, it's a plain class. - query_value = intcon(0); - break; - - case vmIntrinsics::_isPrimitive: - query_value = intcon(0); // "normal" path produces false - break; - case vmIntrinsics::_isHidden: // (To verify this code sequence, check the asserts in JVM_IsHiddenClass.) if (generate_hidden_class_guard(kls, region) != nullptr) @@ -4038,7 +3982,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror()))); // If we fall through, it's a plain class. Get its _super. p = basic_plus_adr(kls, in_bytes(Klass::super_offset())); - kls = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); + kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); null_ctl = top(); kls = null_check_oop(kls, &null_ctl); if (null_ctl != top()) { @@ -4053,7 +3997,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_getClassAccessFlags: p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); - query_value = make_load(nullptr, p, TypeInt::INT, T_INT, MemNode::unordered); + query_value = make_load(nullptr, p, TypeInt::CHAR, T_CHAR, MemNode::unordered); break; default: @@ -4192,7 +4136,7 @@ bool LibraryCallKit::inline_native_subtype_check() { args[which_arg] = arg; Node* p = basic_plus_adr(arg, class_klass_offset); - Node* kls = LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, adr_type, kls_type); + Node* kls = LoadKlassNode::make(_gvn, immutable_memory(), p, adr_type, kls_type); klasses[which_arg] = _gvn.transform(kls); } @@ -4257,7 +4201,7 @@ bool LibraryCallKit::inline_native_subtype_check() { //---------------------generate_array_guard_common------------------------ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, - bool obj_array, bool not_array) { + bool obj_array, bool not_array, Node** obj) { if (stopped()) { return nullptr; @@ -4299,7 +4243,19 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, // invert the test if we are looking for a non-array if (not_array) btest = BoolTest(btest).negate(); Node* bol = _gvn.transform(new BoolNode(cmp, btest)); - return generate_fair_guard(bol, region); + Node* ctrl = generate_fair_guard(bol, region); + Node* is_array_ctrl = not_array ? control() : ctrl; + if (obj != nullptr && is_array_ctrl != nullptr && is_array_ctrl != top()) { + // Keep track of the fact that 'obj' is an array to prevent + // array specific accesses from floating above the guard. + Node* cast = _gvn.transform(new CastPPNode(is_array_ctrl, *obj, TypeAryPtr::BOTTOM)); + // Check for top because in rare cases, the type system can determine that + // the object can't be an array but the layout helper check is not folded. + if (!cast->is_top()) { + *obj = cast; + } + } + return ctrl; } @@ -4394,7 +4350,7 @@ bool LibraryCallKit::inline_native_getLength() { if (stopped()) return true; // Deoptimize if it is a non-array. - Node* non_array = generate_non_array_guard(load_object_klass(array), nullptr); + Node* non_array = generate_non_array_guard(load_object_klass(array), nullptr, &array); if (non_array != nullptr) { PreserveJVMState pjvms(this); @@ -5131,7 +5087,7 @@ bool LibraryCallKit::inline_unsafe_setMemory() { // Call it. Note that the length argument is not scaled. make_runtime_call(flags, - OptoRuntime::make_setmemory_Type(), + OptoRuntime::unsafe_setmemory_Type(), StubRoutines::unsafe_setmemory(), "unsafe_setmemory", dst_type, @@ -5254,12 +5210,13 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { record_for_igvn(result_reg); Node* obj_klass = load_object_klass(obj); - Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)nullptr); + Node* array_obj = obj; + Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)nullptr, &array_obj); if (array_ctl != nullptr) { // It's an array. PreserveJVMState pjvms(this); set_control(array_ctl); - Node* obj_length = load_array_length(obj); + Node* obj_length = load_array_length(array_obj); Node* array_size = nullptr; // Size of the array without object alignment padding. Node* alloc_obj = new_array(obj_klass, obj_length, 0, &array_size, /*deoptimize_on_exception=*/true); @@ -5273,7 +5230,7 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { set_control(is_obja); // Generate a direct call to the right arraycopy function(s). // Clones are always tightly coupled. - ArrayCopyNode* ac = ArrayCopyNode::make(this, true, obj, intcon(0), alloc_obj, intcon(0), obj_length, true, false); + ArrayCopyNode* ac = ArrayCopyNode::make(this, true, array_obj, intcon(0), alloc_obj, intcon(0), obj_length, true, false); ac->set_clone_oop_array(); Node* n = _gvn.transform(ac); assert(n == ac, "cannot disappear"); @@ -5294,7 +5251,7 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { // the object.) if (!stopped()) { - copy_to_clone(obj, alloc_obj, array_size, true); + copy_to_clone(array_obj, alloc_obj, array_size, true); // Present the results of the copy. result_reg->init_req(_array_path, control()); @@ -5915,8 +5872,8 @@ bool LibraryCallKit::inline_arraycopy() { record_for_igvn(slow_region); // (1) src and dest are arrays. - generate_non_array_guard(load_object_klass(src), slow_region); - generate_non_array_guard(load_object_klass(dest), slow_region); + generate_non_array_guard(load_object_klass(src), slow_region, &src); + generate_non_array_guard(load_object_klass(dest), slow_region, &dest); // (2) src and dest arrays must have elements of the same BasicType // done at macro expansion or at Ideal transformation time @@ -8264,14 +8221,14 @@ bool LibraryCallKit::inline_fma(vmIntrinsics::ID id) { a = round_double_node(argument(0)); b = round_double_node(argument(2)); c = round_double_node(argument(4)); - result = _gvn.transform(new FmaDNode(control(), a, b, c)); + result = _gvn.transform(new FmaDNode(a, b, c)); break; case vmIntrinsics::_fmaF: assert(callee()->signature()->size() == 3, "fma has 3 parameters of size 1 each."); a = argument(0); b = argument(1); c = argument(2); - result = _gvn.transform(new FmaFNode(control(), a, b, c)); + result = _gvn.transform(new FmaFNode(a, b, c)); break; default: fatal_unexpected_iid(id); break; @@ -8532,7 +8489,7 @@ bool LibraryCallKit::inline_getObjectSize() { PhiNode* result_val = new PhiNode(result_reg, TypeLong::LONG); record_for_igvn(result_reg); - Node* array_ctl = generate_array_guard(klass_node, nullptr); + Node* array_ctl = generate_array_guard(klass_node, nullptr, &obj); if (array_ctl != nullptr) { // Array case: size is round(header + element_size*arraylength). // Since arraylength is different for every array instance, we have to @@ -8615,3 +8572,112 @@ bool LibraryCallKit::inline_blackhole() { return true; } + +Node* LibraryCallKit::unbox_fp16_value(const TypeInstPtr* float16_box_type, ciField* field, Node* box) { + const TypeInstPtr* box_type = _gvn.type(box)->isa_instptr(); + if (box_type == nullptr || box_type->instance_klass() != float16_box_type->instance_klass()) { + return nullptr; // box klass is not Float16 + } + + // Null check; get notnull casted pointer + Node* null_ctl = top(); + Node* not_null_box = null_check_oop(box, &null_ctl, true); + // If not_null_box is dead, only null-path is taken + if (stopped()) { + set_control(null_ctl); + return nullptr; + } + assert(not_null_box->bottom_type()->is_instptr()->maybe_null() == false, ""); + const TypePtr* adr_type = C->alias_type(field)->adr_type(); + Node* adr = basic_plus_adr(not_null_box, field->offset_in_bytes()); + return access_load_at(not_null_box, adr, adr_type, TypeInt::SHORT, T_SHORT, IN_HEAP); +} + +Node* LibraryCallKit::box_fp16_value(const TypeInstPtr* float16_box_type, ciField* field, Node* value) { + PreserveReexecuteState preexecs(this); + jvms()->set_should_reexecute(true); + + const TypeKlassPtr* klass_type = float16_box_type->as_klass_type(); + Node* klass_node = makecon(klass_type); + Node* box = new_instance(klass_node); + + Node* value_field = basic_plus_adr(box, field->offset_in_bytes()); + const TypePtr* value_adr_type = value_field->bottom_type()->is_ptr(); + + Node* field_store = _gvn.transform(access_store_at(box, + value_field, + value_adr_type, + value, + TypeInt::SHORT, + T_SHORT, + IN_HEAP)); + set_memory(field_store, value_adr_type); + return box; +} + +bool LibraryCallKit::inline_fp16_operations(vmIntrinsics::ID id, int num_args) { + if (!Matcher::match_rule_supported(Op_ReinterpretS2HF) || + !Matcher::match_rule_supported(Op_ReinterpretHF2S)) { + return false; + } + + const TypeInstPtr* box_type = _gvn.type(argument(0))->isa_instptr(); + if (box_type == nullptr || box_type->const_oop() == nullptr) { + return false; + } + + ciInstanceKlass* float16_klass = box_type->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); + const TypeInstPtr* float16_box_type = TypeInstPtr::make_exact(TypePtr::NotNull, float16_klass); + ciField* field = float16_klass->get_field_by_name(ciSymbols::value_name(), + ciSymbols::short_signature(), + false); + assert(field != nullptr, ""); + + // Transformed nodes + Node* fld1 = nullptr; + Node* fld2 = nullptr; + Node* fld3 = nullptr; + switch(num_args) { + case 3: + fld3 = unbox_fp16_value(float16_box_type, field, argument(3)); + if (fld3 == nullptr) { + return false; + } + fld3 = _gvn.transform(new ReinterpretS2HFNode(fld3)); + // fall-through + case 2: + fld2 = unbox_fp16_value(float16_box_type, field, argument(2)); + if (fld2 == nullptr) { + return false; + } + fld2 = _gvn.transform(new ReinterpretS2HFNode(fld2)); + // fall-through + case 1: + fld1 = unbox_fp16_value(float16_box_type, field, argument(1)); + if (fld1 == nullptr) { + return false; + } + fld1 = _gvn.transform(new ReinterpretS2HFNode(fld1)); + break; + default: fatal("Unsupported number of arguments %d", num_args); + } + + Node* result = nullptr; + switch (id) { + // Unary operations + case vmIntrinsics::_sqrt_float16: + result = _gvn.transform(new SqrtHFNode(C, control(), fld1)); + break; + // Ternary operations + case vmIntrinsics::_fma_float16: + result = _gvn.transform(new FmaHFNode(fld1, fld2, fld3)); + break; + default: + fatal_unexpected_iid(id); + break; + } + result = _gvn.transform(new ReinterpretHF2SNode(result)); + set_result(box_fp16_value(float16_box_type, field, result)); + return true; +} + diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index f629f757df2bf..51dda136bc117 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -106,6 +106,10 @@ class LibraryCallKit : public GraphKit { void push_result() { // Push the result onto the stack. if (!stopped() && result() != nullptr) { + if (result()->is_top()) { + assert(false, "Can't determine return value."); + C->record_method_not_compilable("Can't determine return value."); + } BasicType bt = result()->bottom_type()->basic_type(); push_node(bt, result()); } @@ -163,20 +167,20 @@ class LibraryCallKit : public GraphKit { RegionNode* region); Node* generate_interface_guard(Node* kls, RegionNode* region); Node* generate_hidden_class_guard(Node* kls, RegionNode* region); - Node* generate_array_guard(Node* kls, RegionNode* region) { - return generate_array_guard_common(kls, region, false, false); + Node* generate_array_guard(Node* kls, RegionNode* region, Node** obj = nullptr) { + return generate_array_guard_common(kls, region, false, false, obj); } - Node* generate_non_array_guard(Node* kls, RegionNode* region) { - return generate_array_guard_common(kls, region, false, true); + Node* generate_non_array_guard(Node* kls, RegionNode* region, Node** obj = nullptr) { + return generate_array_guard_common(kls, region, false, true, obj); } - Node* generate_objArray_guard(Node* kls, RegionNode* region) { - return generate_array_guard_common(kls, region, true, false); + Node* generate_objArray_guard(Node* kls, RegionNode* region, Node** obj = nullptr) { + return generate_array_guard_common(kls, region, true, false, obj); } - Node* generate_non_objArray_guard(Node* kls, RegionNode* region) { - return generate_array_guard_common(kls, region, true, true); + Node* generate_non_objArray_guard(Node* kls, RegionNode* region, Node** obj = nullptr) { + return generate_array_guard_common(kls, region, true, true, obj); } Node* generate_array_guard_common(Node* kls, RegionNode* region, - bool obj_array, bool not_array); + bool obj_array, bool not_array, Node** obj = nullptr); Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region); CallJavaNode* generate_method_call(vmIntrinsicID method_id, bool is_virtual, bool is_static, bool res_not_null); CallJavaNode* generate_method_call_static(vmIntrinsicID method_id, bool res_not_null) { @@ -291,6 +295,9 @@ class LibraryCallKit : public GraphKit { bool inline_onspinwait(); bool inline_fp_conversions(vmIntrinsics::ID id); bool inline_fp_range_check(vmIntrinsics::ID id); + bool inline_fp16_operations(vmIntrinsics::ID id, int num_args); + Node* unbox_fp16_value(const TypeInstPtr* box_class, ciField* field, Node* box); + Node* box_fp16_value(const TypeInstPtr* box_class, ciField* field, Node* value); bool inline_number_methods(vmIntrinsics::ID id); bool inline_bitshuffle_methods(vmIntrinsics::ID id); bool inline_compare_unsigned(vmIntrinsics::ID id); diff --git a/src/hotspot/share/opto/live.cpp b/src/hotspot/share/opto/live.cpp index 7112d7aaaf0ee..cd202f5e35f29 100644 --- a/src/hotspot/share/opto/live.cpp +++ b/src/hotspot/share/opto/live.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "opto/callnode.hpp" diff --git a/src/hotspot/share/opto/locknode.cpp b/src/hotspot/share/opto/locknode.cpp index 917d9d2bada12..4587bfd4fd6ec 100644 --- a/src/hotspot/share/opto/locknode.cpp +++ b/src/hotspot/share/opto/locknode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/locknode.hpp" #include "opto/parse.hpp" #include "opto/rootnode.hpp" diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 02649d3711a99..96e0fd26d0d7d 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" @@ -97,11 +96,13 @@ void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred, // // We will create a region to guard the uct call if there is no one there. // The continuation projection (if_cont) of the new_iff is returned which -// is an IfTrue projection. This code is also used to clone predicates to cloned loops. -IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_success_proj, +// is an IfTrue projection. This code is also used to clone predicates to +// cloned loops. 'rewire_uncommon_proj_phi_inputs' should be set to the +// non-default value 'true' when called for a false-path loop during +// Loop Unswitching. +IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(const ParsePredicateSuccessProj* parse_predicate_success_proj, Node* new_entry, const Deoptimization::DeoptReason reason, - const int opcode, const bool rewire_uncommon_proj_phi_inputs, - AssertionPredicateType assertion_predicate_type) { + const int opcode, const bool rewire_uncommon_proj_phi_inputs) { assert(parse_predicate_success_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!"); ParsePredicateNode* parse_predicate = parse_predicate_success_proj->in(0)->as_ParsePredicate(); ParsePredicateUncommonProj* uncommon_proj = parse_predicate->uncommon_proj(); @@ -143,12 +144,10 @@ IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessPro IfNode* new_iff = nullptr; switch (opcode) { case Op_If: - new_iff = new IfNode(entry, parse_predicate->in(1), parse_predicate->_prob, parse_predicate->_fcnt - NOT_PRODUCT(COMMA assertion_predicate_type)); + new_iff = new IfNode(entry, parse_predicate->in(1), parse_predicate->_prob, parse_predicate->_fcnt); break; case Op_RangeCheck: - new_iff = new RangeCheckNode(entry, parse_predicate->in(1), parse_predicate->_prob, parse_predicate->_fcnt - NOT_PRODUCT(COMMA assertion_predicate_type)); + new_iff = new RangeCheckNode(entry, parse_predicate->in(1), parse_predicate->_prob, parse_predicate->_fcnt); break; case Op_ParsePredicate: new_iff = new ParsePredicateNode(entry, reason, &_igvn); @@ -272,150 +271,15 @@ void PhaseIdealLoop::fix_cloned_data_node_controls(const ProjNode* old_uncommon_ orig_to_clone.iterate_all(orig_clone_action); } -IfProjNode* PhaseIdealLoop::clone_parse_predicate_to_unswitched_loop(ParsePredicateSuccessProj* parse_predicate_proj, - Node* new_entry, Deoptimization::DeoptReason reason, - const bool slow_loop) { - - IfProjNode* new_predicate_proj = create_new_if_for_predicate(parse_predicate_proj, new_entry, reason, Op_ParsePredicate, - slow_loop); - assert(new_predicate_proj->is_IfTrue(), "the success projection of a Parse Predicate is a true projection"); - ParsePredicateNode* parse_predicate = new_predicate_proj->in(0)->as_ParsePredicate(); - return new_predicate_proj; -} - -// Clones Template Assertion Predicates to both unswitched loops starting at 'old_predicate_proj' by following its -// control inputs. It also rewires the control edges of data nodes with dependencies in the loop from the old predicates -// to the new cloned predicates. -void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new, - ParsePredicateSuccessProj* old_parse_predicate_proj, - ParsePredicateNode* true_path_loop_parse_predicate, - ParsePredicateNode* false_path_loop_parse_predicate) { - // Push the original Template Assertion Predicates on a list to later process them in reverse order to keep the - // original predicate order. - Unique_Node_List list; - get_template_assertion_predicates(old_parse_predicate_proj, list); - - Node_List to_process; - for (int i = list.size() - 1; i >= 0; i--) { - IfTrueNode* template_assertion_predicate_success_proj = list.at(i)->as_IfTrue(); - assert(template_assertion_predicate_success_proj->in(0)->is_If(), "must be If node"); - - IfTrueNode* true_path_loop_proj = - clone_assertion_predicate_for_unswitched_loops(template_assertion_predicate_success_proj, - true_path_loop_parse_predicate); - IfTrueNode* false_path_loop_proj = - clone_assertion_predicate_for_unswitched_loops(template_assertion_predicate_success_proj, - false_path_loop_parse_predicate); - - // Update control dependent data nodes. - for (DUIterator j = template_assertion_predicate_success_proj->outs(); - template_assertion_predicate_success_proj->has_out(j); - j++) { - Node* true_path_loop_node = template_assertion_predicate_success_proj->out(j); - if (loop->is_member(get_loop(ctrl_or_self(true_path_loop_node)))) { - assert(true_path_loop_node->in(0) == template_assertion_predicate_success_proj, "only control edge"); - Node* false_path_loop_node = old_new[true_path_loop_node->_idx]; - assert(false_path_loop_node->in(0) == template_assertion_predicate_success_proj, "only control edge"); - _igvn.replace_input_of(true_path_loop_node, 0, true_path_loop_proj); - to_process.push(false_path_loop_node); - --j; - } - } - // Have to delay updates to the false path loop so uses of predicate are not modified while we iterate on them. - while (to_process.size() > 0) { - Node* slow_node = to_process.pop(); - _igvn.replace_input_of(slow_node, 0, false_path_loop_proj); - } - } -} - -// Put all Template Assertion Predicate projections on a list, starting at 'predicate' and going up in the tree. If 'get_opaque' -// is set, then the OpaqueTemplateAssertionPredicateNode nodes of the Assertion Predicates are put on the list instead -// of the projections. -void PhaseIdealLoop::get_template_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list, - const bool get_opaque) { +// Put all OpaqueTemplateAssertionPredicate nodes on a list, starting at 'predicate' and going up in the tree. +void PhaseIdealLoop::get_opaque_template_assertion_predicate_nodes(ParsePredicateSuccessProj* parse_predicate_proj, + Unique_Node_List& list) { Deoptimization::DeoptReason deopt_reason = parse_predicate_proj->in(0)->as_ParsePredicate()->deopt_reason(); PredicateBlockIterator predicate_iterator(parse_predicate_proj, deopt_reason); - TemplateAssertionPredicateCollector template_assertion_predicate_collector(list, get_opaque); - predicate_iterator.for_each(template_assertion_predicate_collector); -} - -// Clone an Assertion Predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon -// traps are kept for the predicate (a Halt node is used later when creating pre/main/post loops and copying this cloned -// predicate again). -IfTrueNode* -PhaseIdealLoop::clone_assertion_predicate_for_unswitched_loops(IfTrueNode* template_assertion_predicate_success_proj, - ParsePredicateNode* unswitched_loop_parse_predicate) { - TemplateAssertionPredicate template_assertion_predicate(template_assertion_predicate_success_proj); - IfTrueNode* template_success_proj = template_assertion_predicate.clone(unswitched_loop_parse_predicate->in(0), this); - _igvn.replace_input_of(unswitched_loop_parse_predicate, 0, template_success_proj); - set_idom(unswitched_loop_parse_predicate, template_success_proj, dom_depth(template_success_proj)); - return template_success_proj; + OpaqueTemplateAssertionPredicateCollector opaque_template_assertion_predicate_collector(list); + predicate_iterator.for_each(opaque_template_assertion_predicate_collector); } -// Clone the old Parse Predicates and Assertion Predicates before the unswitch If to the unswitched loops after the -// unswitch If. -void PhaseIdealLoop::clone_parse_and_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, Node_List& old_new, - IfProjNode*& true_path_loop_entry, - IfProjNode*& false_path_loop_entry) { - LoopNode* head = loop->_head->as_Loop(); - Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl); - - const Predicates predicates(entry); - clone_loop_predication_predicates_to_unswitched_loop(loop, old_new, predicates.loop_predicate_block(), - Deoptimization::Reason_predicate, true_path_loop_entry, false_path_loop_entry); - clone_loop_predication_predicates_to_unswitched_loop(loop, old_new, predicates.profiled_loop_predicate_block(), - Deoptimization::Reason_profile_predicate, true_path_loop_entry, false_path_loop_entry); - - const PredicateBlock* loop_limit_check_predicate_block = predicates.loop_limit_check_predicate_block(); - if (loop_limit_check_predicate_block->has_parse_predicate() && !head->is_CountedLoop()) { - // Don't clone the Loop Limit Check Parse Predicate if we already have a counted loop (a Loop Limit Check Predicate - // is only created when converting a LoopNode to a CountedLoopNode). - clone_parse_predicate_to_unswitched_loops(loop_limit_check_predicate_block, Deoptimization::Reason_loop_limit_check, - true_path_loop_entry, false_path_loop_entry); - } -} - -// Clone the Parse Predicate and Template Assertion Predicates of a Loop Predication related Predicate Block. -void PhaseIdealLoop::clone_loop_predication_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new, - const PredicateBlock* predicate_block, - Deoptimization::DeoptReason reason, - IfProjNode*& true_path_loop_entry, - IfProjNode*& false_path_loop_entry) { - if (predicate_block->has_parse_predicate()) { - // We currently only clone Assertion Predicates if there are Parse Predicates. This is not entirely correct and will - // be changed with the complete fix for Assertion Predicates. - clone_parse_predicate_to_unswitched_loops(predicate_block, reason, true_path_loop_entry, false_path_loop_entry); - assert(true_path_loop_entry->in(0)->is_ParsePredicate() && false_path_loop_entry->in(0)->is_ParsePredicate(), - "must be success projections of the cloned Parse Predicates"); - clone_assertion_predicates_to_unswitched_loop(loop, old_new, predicate_block->parse_predicate_success_proj(), - true_path_loop_entry->in(0)->as_ParsePredicate(), - false_path_loop_entry->in(0)->as_ParsePredicate()); - } -} - -void PhaseIdealLoop::clone_parse_predicate_to_unswitched_loops(const PredicateBlock* predicate_block, - Deoptimization::DeoptReason reason, - IfProjNode*& iffast_pred, IfProjNode*& ifslow_pred) { - assert(predicate_block->has_parse_predicate(), "must have parse predicate"); - ParsePredicateSuccessProj* parse_predicate_proj = predicate_block->parse_predicate_success_proj(); - iffast_pred = clone_parse_predicate_to_unswitched_loop(parse_predicate_proj, iffast_pred, reason, false); - check_cloned_parse_predicate_for_unswitching(iffast_pred, true); - - ifslow_pred = clone_parse_predicate_to_unswitched_loop(parse_predicate_proj, ifslow_pred, reason, true); - check_cloned_parse_predicate_for_unswitching(ifslow_pred, false); -} - -#ifndef PRODUCT -void PhaseIdealLoop::check_cloned_parse_predicate_for_unswitching(const Node* new_entry, const bool is_fast_loop) { - assert(new_entry != nullptr, "IfTrue or IfFalse after clone predicate"); - if (TraceLoopPredicate) { - tty->print("Parse Predicate cloned to %s loop: ", is_fast_loop ? "fast" : "slow"); - new_entry->in(0)->dump(); - } -} -#endif - //------------------------------Invariance----------------------------------- // Helper class for loop_predication_impl to compute invariance on the fly and // clone invariants. @@ -469,7 +333,7 @@ class Invariance : public StackObj { // loop, it was marked invariant but n is only invariant if // it depends only on that test. Otherwise, unless that test // is out of the loop, it's not invariant. - if (n->is_CFG() || n->depends_only_on_test() || n->in(0) == nullptr || !_phase->is_member(_lpt, n->in(0))) { + if (n->is_CFG() || (n->depends_only_on_test() && _phase->igvn().no_dependent_zero_check(n)) || n->in(0) == nullptr || !_phase->is_member(_lpt, n->in(0))) { _invariant.set(n->_idx); // I am a invariant too } } diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index d8d7be5c89c1e..03a7bf50e70b6 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" @@ -1424,11 +1423,13 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n _igvn.hash_delete(outer_main_head); outer_main_head->set_req(LoopNode::EntryControl, min_taken); set_idom(outer_main_head, min_taken, dd_main_head); + assert(post_head->in(1)->is_IfProj(), "must be zero-trip guard If node projection of the post loop"); VectorSet visited; Node_Stack clones(main_head->back_control()->outcnt()); // Step B3: Make the fall-in values to the main-loop come from the // fall-out values of the pre-loop. + const uint last_node_index_in_pre_loop_body = Compile::current()->unique() - 1; for (DUIterator i2 = main_head->outs(); main_head->has_out(i2); i2++) { Node* main_phi = main_head->out(i2); if (main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() > 0) { @@ -1441,21 +1442,13 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n main_phi->set_req(LoopNode::EntryControl, fallpre); } } + DEBUG_ONLY(const uint last_node_index_from_backedge_goo = Compile::current()->unique() - 1); - // Nodes inside the loop may be control dependent on a predicate - // that was moved before the preloop. If the back branch of the main - // or post loops becomes dead, those nodes won't be dependent on the - // test that guards that loop nest anymore which could lead to an - // incorrect array access because it executes independently of the - // test that was guarding the loop nest. We add a special CastII on - // the if branch that enters the loop, between the input induction - // variable value and the induction variable Phi to preserve correct - // dependencies. - - assert(post_head->in(1)->is_IfProj(), "must be zero-trip guard If node projection of the post loop"); DEBUG_ONLY(ensure_zero_trip_guard_proj(outer_main_head->in(LoopNode::EntryControl), true);) if (UseLoopPredicate) { - initialize_assertion_predicates_for_main_loop(pre_head, main_head, first_node_index_in_pre_loop_body, old_new); + initialize_assertion_predicates_for_main_loop(pre_head, main_head, first_node_index_in_pre_loop_body, + last_node_index_in_pre_loop_body, + DEBUG_ONLY(last_node_index_from_backedge_goo COMMA) old_new); } // Step B4: Shorten the pre-loop to run only 1 iteration (for now). @@ -1729,10 +1722,15 @@ void PhaseIdealLoop::initialize_assertion_predicates_for_peeled_loop(CountedLoop // Target Loop: Original - main_loop_head void PhaseIdealLoop::initialize_assertion_predicates_for_main_loop(CountedLoopNode* pre_loop_head, CountedLoopNode* main_loop_head, - const uint first_node_index_in_cloned_loop_body, + const uint first_node_index_in_pre_loop_body, + const uint last_node_index_in_pre_loop_body, + DEBUG_ONLY(const uint last_node_index_from_backedge_goo COMMA) const Node_List& old_new) { - const NodeInOriginalLoopBody node_in_original_loop_body(first_node_index_in_cloned_loop_body, old_new); - create_assertion_predicates_at_loop(pre_loop_head, main_loop_head, node_in_original_loop_body, true); + assert(first_node_index_in_pre_loop_body < last_node_index_in_pre_loop_body, "cloned some nodes"); + const NodeInMainLoopBody node_in_main_loop_body(first_node_index_in_pre_loop_body, + last_node_index_in_pre_loop_body, + DEBUG_ONLY(last_node_index_from_backedge_goo COMMA) old_new); + create_assertion_predicates_at_main_or_post_loop(pre_loop_head, main_loop_head, node_in_main_loop_body, true); } // Source Loop: Original - main_loop_head @@ -1741,7 +1739,7 @@ void PhaseIdealLoop::initialize_assertion_predicates_for_post_loop(CountedLoopNo CountedLoopNode* post_loop_head, const uint first_node_index_in_cloned_loop_body) { const NodeInClonedLoopBody node_in_cloned_loop_body(first_node_index_in_cloned_loop_body); - create_assertion_predicates_at_loop(main_loop_head, post_loop_head, node_in_cloned_loop_body, false); + create_assertion_predicates_at_main_or_post_loop(main_loop_head, post_loop_head, node_in_cloned_loop_body, false); } void PhaseIdealLoop::create_assertion_predicates_at_loop(CountedLoopNode* source_loop_head, @@ -1754,6 +1752,47 @@ void PhaseIdealLoop::create_assertion_predicates_at_loop(CountedLoopNode* source PredicateIterator predicate_iterator(source_loop_entry); predicate_iterator.for_each(create_assertion_predicates_visitor); } + +void PhaseIdealLoop::create_assertion_predicates_at_main_or_post_loop(CountedLoopNode* source_loop_head, + CountedLoopNode* target_loop_head, + const NodeInLoopBody& _node_in_loop_body, + bool clone_template) { + Node* old_target_loop_head_entry = target_loop_head->skip_strip_mined()->in(LoopNode::EntryControl); + const uint node_index_before_new_assertion_predicate_nodes = C->unique(); + const bool need_to_rewire_old_target_loop_entry_dependencies = old_target_loop_head_entry->outcnt() > 1; + create_assertion_predicates_at_loop(source_loop_head, target_loop_head, _node_in_loop_body, clone_template); + if (need_to_rewire_old_target_loop_entry_dependencies) { + rewire_old_target_loop_entry_dependency_to_new_entry(target_loop_head, old_target_loop_head_entry, + node_index_before_new_assertion_predicate_nodes); + } +} + +// Rewire any control dependent nodes on the old target loop entry before adding Assertion Predicate related nodes. +// These have been added by PhaseIdealLoop::clone_up_backedge_goo() and assume to be ending up at the target loop entry +// which is no longer the case when adding additional Assertion Predicates. Fix this by rewiring these nodes to the new +// target loop entry which corresponds to the tail of the last Assertion Predicate before the target loop. This is safe +// to do because these control dependent nodes on the old target loop entry created by clone_up_backedge_goo() were +// pinned on the loop backedge before. The Assertion Predicates are not control dependent on these nodes in any way. +void PhaseIdealLoop::rewire_old_target_loop_entry_dependency_to_new_entry( + LoopNode* target_loop_head, const Node* old_target_loop_entry, + const uint node_index_before_new_assertion_predicate_nodes) { + Node* new_main_loop_entry = target_loop_head->skip_strip_mined()->in(LoopNode::EntryControl); + if (new_main_loop_entry == old_target_loop_entry) { + // No Assertion Predicates added. + return; + } + + for (DUIterator_Fast imax, i = old_target_loop_entry->fast_outs(imax); i < imax; i++) { + Node* out = old_target_loop_entry->fast_out(i); + if (!out->is_CFG() && out->_idx < node_index_before_new_assertion_predicate_nodes) { + _igvn.replace_input_of(out, 0, new_main_loop_entry); + set_ctrl(out, new_main_loop_entry); + --i; + --imax; + } + } +} + //------------------------------do_unroll-------------------------------------- // Unroll the loop body one step - make each trip do 2 iterations. void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip) { diff --git a/src/hotspot/share/opto/loopUnswitch.cpp b/src/hotspot/share/opto/loopUnswitch.cpp index a5a90b7e481e4..05e24e2271e5c 100644 --- a/src/hotspot/share/opto/loopUnswitch.cpp +++ b/src/hotspot/share/opto/loopUnswitch.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/castnode.hpp" #include "opto/cfgnode.hpp" @@ -236,15 +235,47 @@ class OriginalLoop : public StackObj { _phase(loop->_phase) {} NONCOPYABLE(OriginalLoop); + // Unswitch the original loop on the invariant loop selector by creating a true-path-loop and a false-path-loop. + // Remove the unswitch candidate If from both unswitched loop versions which are now covered by the loop selector If. + void unswitch(const UnswitchedLoopSelector& unswitched_loop_selector) { + const uint first_false_path_loop_node_index = _phase->C->unique(); + clone_loop(unswitched_loop_selector); + + move_parse_and_template_assertion_predicates_to_unswitched_loops(unswitched_loop_selector, + first_false_path_loop_node_index); + DEBUG_ONLY(verify_unswitched_loop_versions(_loop->_head->as_Loop(), unswitched_loop_selector);) + + _phase->recompute_dom_depth(); + remove_unswitch_candidate_from_loops(unswitched_loop_selector); + } + private: - void fix_loop_entries(IfProjNode* true_path_loop_entry, IfProjNode* false_path_loop_entry) { - _phase->replace_loop_entry(_loop_head, true_path_loop_entry); + void clone_loop(const UnswitchedLoopSelector& unswitched_loop_selector) { + _phase->clone_loop(_loop, _old_new, _phase->dom_depth(_loop_head), + PhaseIdealLoop::CloneIncludesStripMined, unswitched_loop_selector.selector()); + fix_loop_entries(unswitched_loop_selector); + } + + void fix_loop_entries(const UnswitchedLoopSelector& unswitched_loop_selector) { + _phase->replace_loop_entry(_loop_head, unswitched_loop_selector.true_path_loop_proj()); LoopNode* false_path_loop_strip_mined_head = old_to_new(_loop_head)->as_Loop(); - _phase->replace_loop_entry(false_path_loop_strip_mined_head, false_path_loop_entry); + _phase->replace_loop_entry(false_path_loop_strip_mined_head, + unswitched_loop_selector.false_path_loop_proj()); } - Node* old_to_new(const Node* old) const { - return _old_new[old->_idx]; + // Moves the Parse And Template Assertion Predicates to the true and false path loop. They are inserted between the + // loop heads and the loop selector If projections. The old Parse and Template Assertion Predicates before + // the unswitched loop selector are killed. + void move_parse_and_template_assertion_predicates_to_unswitched_loops( + const UnswitchedLoopSelector& unswitched_loop_selector, const uint first_false_path_loop_node_index) const { + const NodeInOriginalLoopBody node_in_true_path_loop_body(first_false_path_loop_node_index, _old_new); + const NodeInClonedLoopBody node_in_false_path_loop_body(first_false_path_loop_node_index); + CloneUnswitchedLoopPredicatesVisitor + clone_unswitched_loop_predicates_visitor(_loop_head, old_to_new(_loop_head)->as_Loop(), node_in_true_path_loop_body, + node_in_false_path_loop_body, _phase); + Node* source_loop_entry = unswitched_loop_selector.selector()->in(0); + PredicateIterator predicate_iterator(source_loop_entry); + predicate_iterator.for_each(clone_unswitched_loop_predicates_visitor); } #ifdef ASSERT @@ -263,6 +294,10 @@ class OriginalLoop : public StackObj { } #endif // ASSERT + Node* old_to_new(const Node* old) const { + return _old_new[old->_idx]; + } + // Remove the unswitch candidate If nodes in both unswitched loop versions which are now dominated by the loop selector // If node. Keep the true-path-path in the true-path-loop and the false-path-path in the false-path-loop by setting // the bool input accordingly. The unswitch candidate If nodes are folded in the next IGVN round. @@ -276,28 +311,6 @@ class OriginalLoop : public StackObj { _phase->dominated_by(unswitched_loop_selector.false_path_loop_proj(), unswitching_candidate_clone); } - public: - // Unswitch the original loop on the invariant loop selector by creating a true-path-loop and a false-path-loop. - // Remove the unswitch candidate If from both unswitched loop versions which are now covered by the loop selector If. - void unswitch(const UnswitchedLoopSelector& unswitched_loop_selector) { - _phase->clone_loop(_loop, _old_new, _phase->dom_depth(_loop_head), - PhaseIdealLoop::CloneIncludesStripMined, unswitched_loop_selector.selector()); - - // At this point, the selector If projections are the corresponding loop entries. - // clone_parse_and_assertion_predicates_to_unswitched_loop() could clone additional predicates after the selector - // If projections. The loop entries are updated accordingly. - IfProjNode* true_path_loop_entry = unswitched_loop_selector.true_path_loop_proj(); - IfProjNode* false_path_loop_entry = unswitched_loop_selector.false_path_loop_proj(); - _phase->clone_parse_and_assertion_predicates_to_unswitched_loop(_loop, _old_new, - true_path_loop_entry, false_path_loop_entry); - - fix_loop_entries(true_path_loop_entry, false_path_loop_entry); - - DEBUG_ONLY(verify_unswitched_loop_versions(_loop->_head->as_Loop(), unswitched_loop_selector);) - - _phase->recompute_dom_depth(); - remove_unswitch_candidate_from_loops(unswitched_loop_selector); - } }; // See comments below file header for more information about Loop Unswitching. diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index 72870613cb0fb..ed2db13421fc6 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/barrierSet.hpp" @@ -2552,11 +2551,15 @@ const Type* LoopLimitNode::Value(PhaseGVN* phase) const { jlong trip_count = (limit_con - init_con + stride_m)/stride_con; jlong final_con = init_con + stride_con*trip_count; int final_int = (int)final_con; - // The final value should be in integer range since the loop - // is counted and the limit was checked for overflow. - // Assert checks for overflow only if all input nodes are ConINodes, as during CCP - // there might be a temporary overflow from PhiNodes see JDK-8309266 - assert((in(Init)->is_ConI() && in(Limit)->is_ConI() && in(Stride)->is_ConI()) ? final_con == (jlong)final_int : true, "final value should be integer"); + // The final value should be in integer range in almost all cases, + // since the loop is counted and the limit was checked for overflow. + // There some exceptions, for example: + // - During CCP, there might be a temporary overflow from PhiNodes, see JDK-8309266. + // - During PhaseIdealLoop::split_thru_phi, the LoopLimitNode floats possibly far above + // the loop and its predicates, and we might get constants on one side of the phi that + // would lead to overflows. Such a code path would never lead us to enter the loop + // because of the loop limit overflow check that happens after the LoopLimitNode + // computation with overflow, but before we enter the loop, see JDK-8335747. if (final_con == (jlong)final_int) { return TypeInt::make(final_int); } else { @@ -2579,12 +2582,10 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (stride_con == 1) return nullptr; // Identity - if (in(Init)->is_Con() && in(Limit)->is_Con()) - return nullptr; // Value - // Delay following optimizations until all loop optimizations // done to keep Ideal graph simple. if (!can_reshape || !phase->C->post_loop_opts_phase()) { + phase->C->record_for_post_loop_opts_igvn(this); return nullptr; } @@ -4458,7 +4459,7 @@ void PhaseIdealLoop::collect_useful_template_assertion_predicates_for_loop(Ideal const PredicateBlock* profiled_loop_predicate_block = predicates.profiled_loop_predicate_block(); if (profiled_loop_predicate_block->has_parse_predicate()) { ParsePredicateSuccessProj* parse_predicate_proj = profiled_loop_predicate_block->parse_predicate_success_proj(); - get_template_assertion_predicates(parse_predicate_proj, useful_predicates, true); + get_opaque_template_assertion_predicate_nodes(parse_predicate_proj, useful_predicates); } } @@ -4466,7 +4467,7 @@ void PhaseIdealLoop::collect_useful_template_assertion_predicates_for_loop(Ideal const PredicateBlock* loop_predicate_block = predicates.loop_predicate_block(); if (loop_predicate_block->has_parse_predicate()) { ParsePredicateSuccessProj* parse_predicate_proj = loop_predicate_block->parse_predicate_success_proj(); - get_template_assertion_predicates(parse_predicate_proj, useful_predicates, true); + get_opaque_template_assertion_predicate_nodes(parse_predicate_proj, useful_predicates); } } } @@ -5630,14 +5631,23 @@ int PhaseIdealLoop::build_loop_tree_impl(Node* n, int pre_order) { // l is irreducible: we just found a second entry m. _has_irreducible_loops = true; RegionNode* secondary_entry = m->as_Region(); - DEBUG_ONLY(secondary_entry->verify_can_be_irreducible_entry();) + + if (!secondary_entry->can_be_irreducible_entry()) { + assert(!VerifyNoNewIrreducibleLoops, "A new irreducible loop was created after parsing."); + C->record_method_not_compilable("A new irreducible loop was created after parsing."); + return pre_order; + } // Walk up the loop-tree, mark all loops that are already post-visited as irreducible // Since m is a secondary entry to them all. while( is_postvisited(l->_head) ) { l->_irreducible = 1; // = true RegionNode* head = l->_head->as_Region(); - DEBUG_ONLY(head->verify_can_be_irreducible_entry();) + if (!head->can_be_irreducible_entry()) { + assert(!VerifyNoNewIrreducibleLoops, "A new irreducible loop was created after parsing."); + C->record_method_not_compilable("A new irreducible loop was created after parsing."); + return pre_order; + } l = l->_parent; // Check for bad CFG here to prevent crash, and bailout of compile if (l == nullptr) { @@ -6431,8 +6441,6 @@ void PhaseIdealLoop::build_loop_late_post_work(Node *n, bool pinned) { case Op_DivF: case Op_DivD: case Op_ModI: - case Op_ModF: - case Op_ModD: case Op_LoadB: // Same with Loads; they can sink case Op_LoadUB: // during loop optimizations. case Op_LoadUS: @@ -6823,7 +6831,7 @@ void PhaseIdealLoop::get_idoms(Node* n, const uint count, Unique_Node_List& idom void PhaseIdealLoop::dump_idoms_in_reverse(const Node* n, const Node_List& idom_list) const { Node* next; uint padding = 3; - uint node_index_padding_width = static_cast(log10(static_cast(C->unique()))) + 1; + uint node_index_padding_width = (C->unique() == 0 ? 0 : static_cast(log10(static_cast(C->unique())))) + 1; for (int i = idom_list.size() - 1; i >= 0; i--) { if (i == 9 || i == 99) { padding++; diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index acafea3fce86e..4e5a60ee3cd0e 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -942,7 +942,8 @@ class PhaseIdealLoop : public PhaseTransform { static void ensure_zero_trip_guard_proj(Node* node, bool is_main_loop); #endif private: - static void get_template_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list, bool get_opaque = false); + static void get_opaque_template_assertion_predicate_nodes(ParsePredicateSuccessProj* parse_predicate_proj, + Unique_Node_List& list); void update_main_loop_assertion_predicates(CountedLoopNode* main_loop_head); void initialize_assertion_predicates_for_peeled_loop(CountedLoopNode* peeled_loop_head, CountedLoopNode* remaining_loop_head, @@ -950,12 +951,20 @@ class PhaseIdealLoop : public PhaseTransform { const Node_List& old_new); void initialize_assertion_predicates_for_main_loop(CountedLoopNode* pre_loop_head, CountedLoopNode* main_loop_head, - uint first_node_index_in_cloned_loop_body, + uint first_node_index_in_pre_loop_body, + uint last_node_index_in_pre_loop_body, + DEBUG_ONLY(uint last_node_index_from_backedge_goo COMMA) const Node_List& old_new); void initialize_assertion_predicates_for_post_loop(CountedLoopNode* main_loop_head, CountedLoopNode* post_loop_head, uint first_node_index_in_cloned_loop_body); void create_assertion_predicates_at_loop(CountedLoopNode* source_loop_head, CountedLoopNode* target_loop_head, const NodeInLoopBody& _node_in_loop_body, bool clone_template); + void create_assertion_predicates_at_main_or_post_loop(CountedLoopNode* source_loop_head, + CountedLoopNode* target_loop_head, + const NodeInLoopBody& _node_in_loop_body, bool clone_template); + void rewire_old_target_loop_entry_dependency_to_new_entry(LoopNode* target_loop_head, + const Node* old_target_loop_entry, + uint node_index_before_new_assertion_predicate_nodes); void insert_loop_limit_check_predicate(ParsePredicateSuccessProj* loop_limit_check_parse_proj, Node* cmp_limit, Node* bol); void log_loop_tree(); @@ -1349,10 +1358,9 @@ class PhaseIdealLoop : public PhaseTransform { bool* p_short_scale, int depth); // Create a new if above the uncommon_trap_if_pattern for the predicate to be promoted - IfTrueNode* create_new_if_for_predicate( - ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason, int opcode, - bool rewire_uncommon_proj_phi_inputs = false, - AssertionPredicateType assertion_predicate_type = AssertionPredicateType::None); + IfTrueNode* create_new_if_for_predicate(const ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry, + Deoptimization::DeoptReason reason, int opcode, + bool rewire_uncommon_proj_phi_inputs = false); private: // Helper functions for create_new_if_for_predicate() @@ -1661,28 +1669,7 @@ class PhaseIdealLoop : public PhaseTransform { _nodes_required = UINT_MAX; } - public: - // Clone Parse Predicates to slow and fast loop when unswitching a loop - void clone_parse_and_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, Node_List& old_new, - IfProjNode*& true_path_loop_entry, - IfProjNode*& false_path_loop_entry); private: - void clone_loop_predication_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new, - const PredicateBlock* predicate_block, - Deoptimization::DeoptReason reason, - IfProjNode*& true_path_loop_entry, - IfProjNode*& false_path_loop_entry); - void clone_parse_predicate_to_unswitched_loops(const PredicateBlock* predicate_block, Deoptimization::DeoptReason reason, - IfProjNode*& iffast_pred, IfProjNode*& ifslow_pred); - IfProjNode* clone_parse_predicate_to_unswitched_loop(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry, - Deoptimization::DeoptReason reason, bool slow_loop); - void clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new, - ParsePredicateSuccessProj* old_parse_predicate_proj, - ParsePredicateNode* true_path_loop_parse_predicate, - ParsePredicateNode* false_path_loop_parse_predicate); - IfTrueNode* clone_assertion_predicate_for_unswitched_loops(IfTrueNode* template_assertion_predicate_success_proj, - ParsePredicateNode* unswitched_loop_parse_predicate); - static void check_cloned_parse_predicate_for_unswitching(const Node* new_entry, bool is_fast_loop) PRODUCT_RETURN; bool _created_loop_node; DEBUG_ONLY(void dump_idoms(Node* early, Node* wrong_lca);) diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 90b9bc84def14..8afce3e86ae0f 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "memory/allocation.inline.hpp" @@ -857,9 +856,9 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { } } } - Node *cmov = CMoveNode::make(cmov_ctrl, iff->in(1), phi->in(1+flip), phi->in(2-flip), _igvn.type(phi)); - register_new_node( cmov, cmov_ctrl ); - _igvn.replace_node( phi, cmov ); + Node* cmov = CMoveNode::make(iff->in(1), phi->in(1+flip), phi->in(2-flip), _igvn.type(phi)); + register_new_node(cmov, cmov_ctrl); + _igvn.replace_node(phi, cmov); #ifndef PRODUCT if (TraceLoopOpts) { tty->print("CMOV "); diff --git a/src/hotspot/share/opto/machnode.cpp b/src/hotspot/share/opto/machnode.cpp index e271637893b28..2ae2c5de3811d 100644 --- a/src/hotspot/share/opto/machnode.cpp +++ b/src/hotspot/share/opto/machnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "gc/shared/collectedHeap.hpp" @@ -47,6 +46,7 @@ intptr_t MachOper::constant() const { return 0x00; } relocInfo::relocType MachOper::constant_reloc() const { return relocInfo::none; } jdouble MachOper::constantD() const { ShouldNotReachHere(); } jfloat MachOper::constantF() const { ShouldNotReachHere(); } +jshort MachOper::constantH() const { ShouldNotReachHere(); } jlong MachOper::constantL() const { ShouldNotReachHere(); } TypeOopPtr *MachOper::oop() const { return nullptr; } int MachOper::ccode() const { return 0x00; } diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 4ac91175f78ed..ac60e7b73125b 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -156,6 +156,7 @@ class MachOper : public ResourceObj { virtual jdouble constantD() const; virtual jfloat constantF() const; virtual jlong constantL() const; + virtual jshort constantH() const; virtual TypeOopPtr *oop() const; virtual int ccode() const; // A zero, default, indicates this value is not needed. diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index 289ea30a633e3..1bd35f9dcc980 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/tlab_globals.hpp" @@ -430,6 +429,10 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type * return nullptr; } values.at_put(j, res); + } else if (val->is_top()) { + // This indicates that this path into the phi is dead. Top will eventually also propagate into the Region. + // IGVN will clean this up later. + values.at_put(j, val); } else { DEBUG_ONLY( val->dump(); ) assert(false, "unknown node on this path"); @@ -2221,7 +2224,7 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { mem_phi->init_req(2, mem); // Make slow path call - CallNode *call = make_slow_call((CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), + CallNode* call = make_slow_call(lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), nullptr, slow_path, obj, box, nullptr); @@ -2335,7 +2338,7 @@ void PhaseMacroExpand::expand_subtypecheck_node(SubTypeCheckNode *check) { subklass = obj_or_subklass; } else { Node* k_adr = basic_plus_adr(obj_or_subklass, oopDesc::klass_offset_in_bytes()); - subklass = _igvn.transform(LoadKlassNode::make(_igvn, nullptr, C->immutable_memory(), k_adr, TypeInstPtr::KLASS)); + subklass = _igvn.transform(LoadKlassNode::make(_igvn, C->immutable_memory(), k_adr, TypeInstPtr::KLASS)); } Node* not_subtype_ctrl = Phase::gen_subtype_check(subklass, superklass, &ctrl, nullptr, _igvn, check->method(), check->bci()); @@ -2430,6 +2433,8 @@ void PhaseMacroExpand::eliminate_macro_nodes() { break; default: assert(n->Opcode() == Op_LoopLimit || + n->Opcode() == Op_ModD || + n->Opcode() == Op_ModF || n->is_OpaqueNotNull() || n->is_OpaqueInitializedAssertionPredicate() || n->Opcode() == Op_MaxL || @@ -2581,7 +2586,30 @@ bool PhaseMacroExpand::expand_macro_nodes() { expand_subtypecheck_node(n->as_SubTypeCheck()); break; default: - assert(false, "unknown node type in macro list"); + switch (n->Opcode()) { + case Op_ModD: + case Op_ModF: { + bool is_drem = n->Opcode() == Op_ModD; + CallNode* mod_macro = n->as_Call(); + CallNode* call = new CallLeafNode(mod_macro->tf(), + is_drem ? CAST_FROM_FN_PTR(address, SharedRuntime::drem) + : CAST_FROM_FN_PTR(address, SharedRuntime::frem), + is_drem ? "drem" : "frem", TypeRawPtr::BOTTOM); + call->init_req(TypeFunc::Control, mod_macro->in(TypeFunc::Control)); + call->init_req(TypeFunc::I_O, mod_macro->in(TypeFunc::I_O)); + call->init_req(TypeFunc::Memory, mod_macro->in(TypeFunc::Memory)); + call->init_req(TypeFunc::ReturnAdr, mod_macro->in(TypeFunc::ReturnAdr)); + call->init_req(TypeFunc::FramePtr, mod_macro->in(TypeFunc::FramePtr)); + for (unsigned int i = 0; i < mod_macro->tf()->domain()->cnt() - TypeFunc::Parms; i++) { + call->init_req(TypeFunc::Parms + i, mod_macro->in(TypeFunc::Parms + i)); + } + _igvn.replace_node(mod_macro, call); + transform_later(call); + break; + } + default: + assert(false, "unknown node type in macro list"); + } } assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list"); if (C->failing()) return true; diff --git a/src/hotspot/share/opto/macroArrayCopy.cpp b/src/hotspot/share/opto/macroArrayCopy.cpp index 9600a3c6c2501..e37c961e88d66 100644 --- a/src/hotspot/share/opto/macroArrayCopy.cpp +++ b/src/hotspot/share/opto/macroArrayCopy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/tlab_globals.hpp" #include "opto/arraycopynode.hpp" @@ -643,7 +642,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode* // (At this point we can assume disjoint_bases, since types differ.) int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset()); Node* p1 = basic_plus_adr(dest_klass, ek_offset); - Node* n1 = LoadKlassNode::make(_igvn, nullptr, C->immutable_memory(), p1, TypeRawPtr::BOTTOM); + Node* n1 = LoadKlassNode::make(_igvn, C->immutable_memory(), p1, TypeRawPtr::BOTTOM); Node* dest_elem_klass = transform_later(n1); Node* cv = generate_checkcast_arraycopy(&local_ctrl, &local_mem, adr_type, diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index b94fb7101430e..1c9afae651017 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "memory/allocation.inline.hpp" @@ -2305,6 +2304,7 @@ bool Matcher::find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_ case Op_EncodeISOArray: case Op_FmaD: case Op_FmaF: + case Op_FmaHF: case Op_FmaVD: case Op_FmaVF: case Op_MacroLogicV: @@ -2477,6 +2477,7 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) { } case Op_FmaD: case Op_FmaF: + case Op_FmaHF: case Op_FmaVD: case Op_FmaVF: { // Restructure into a binary tree for Matching. diff --git a/src/hotspot/share/opto/mathexactnode.cpp b/src/hotspot/share/opto/mathexactnode.cpp index ff4edd2518989..326ebefd4eadc 100644 --- a/src/hotspot/share/opto/mathexactnode.cpp +++ b/src/hotspot/share/opto/mathexactnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/cfgnode.hpp" diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index ad351fb81add7..a7cf598cb3d8f 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/barrierSet.hpp" @@ -1973,27 +1972,21 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, ciKlass* klass) const { assert(!UseCompactObjectHeaders || tkls->offset() != in_bytes(Klass::prototype_header_offset()), "must not happen"); - if (tkls->offset() == in_bytes(Klass::modifier_flags_offset())) { - // The field is Klass::_modifier_flags. Return its (constant) value. - // (Folds up the 2nd indirection in aClassConstant.getModifiers().) - assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); - return TypeInt::make(klass->modifier_flags()); - } if (tkls->offset() == in_bytes(Klass::access_flags_offset())) { // The field is Klass::_access_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); + assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); return TypeInt::make(klass->access_flags()); } if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { // The field is Klass::_misc_flags. Return its (constant) value. // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) - assert(this->Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); + assert(Opcode() == Op_LoadUB, "must load an unsigned byte from _misc_flags"); return TypeInt::make(klass->misc_flags()); } if (tkls->offset() == in_bytes(Klass::layout_helper_offset())) { // The field is Klass::_layout_helper. Return its constant value if known. - assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); + assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); return TypeInt::make(klass->layout_helper()); } @@ -2014,6 +2007,17 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { assert(off != Type::OffsetTop, "case covered by TypePtr::empty"); Compile* C = phase->C; + // If we are loading from a freshly-allocated object, produce a zero, + // if the load is provably beyond the header of the object. + // (Also allow a variable load from a fresh array to produce zero.) + const TypeOopPtr* tinst = tp->isa_oopptr(); + bool is_instance = (tinst != nullptr) && tinst->is_known_instance_field(); + Node* value = can_see_stored_value(mem, phase); + if (value != nullptr && value->is_Con()) { + assert(value->bottom_type()->higher_equal(_type), "sanity"); + return value->bottom_type(); + } + // Try to guess loaded type from pointer type if (tp->isa_aryptr()) { const TypeAryPtr* ary = tp->is_aryptr(); @@ -2220,20 +2224,6 @@ const Type* LoadNode::Value(PhaseGVN* phase) const { } } - // If we are loading from a freshly-allocated object, produce a zero, - // if the load is provably beyond the header of the object. - // (Also allow a variable load from a fresh array to produce zero.) - const TypeOopPtr *tinst = tp->isa_oopptr(); - bool is_instance = (tinst != nullptr) && tinst->is_known_instance_field(); - bool is_boxed_value = (tinst != nullptr) && tinst->is_ptr_to_boxed_value(); - if (ReduceFieldZeroing || is_instance || is_boxed_value) { - Node* value = can_see_stored_value(mem,phase); - if (value != nullptr && value->is_Con()) { - assert(value->bottom_type()->higher_equal(_type),"sanity"); - return value->bottom_type(); - } - } - bool is_vect = (_type->isa_vect() != nullptr); if (is_instance && !is_vect) { // If we have an instance type and our memory input is the @@ -2402,19 +2392,19 @@ const Type* LoadSNode::Value(PhaseGVN* phase) const { //============================================================================= //----------------------------LoadKlassNode::make------------------------------ // Polymorphic factory method: -Node* LoadKlassNode::make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk) { +Node* LoadKlassNode::make(PhaseGVN& gvn, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk) { // sanity check the alias category against the created node type - const TypePtr *adr_type = adr->bottom_type()->isa_ptr(); + const TypePtr* adr_type = adr->bottom_type()->isa_ptr(); assert(adr_type != nullptr, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { assert(UseCompressedClassPointers, "no compressed klasses"); - Node* load_klass = gvn.transform(new LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); + Node* load_klass = gvn.transform(new LoadNKlassNode(mem, adr, at, tk->make_narrowklass(), MemNode::unordered)); return new DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } #endif assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); - return new LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered); + return new LoadKlassNode(mem, adr, at, tk, MemNode::unordered); } //------------------------------Value------------------------------------------ @@ -2422,12 +2412,6 @@ const Type* LoadKlassNode::Value(PhaseGVN* phase) const { return klass_value_common(phase); } -// In most cases, LoadKlassNode does not have the control input set. If the control -// input is set, it must not be removed (by LoadNode::Ideal()). -bool LoadKlassNode::can_remove_control() const { - return false; -} - const Type* LoadNode::klass_value_common(PhaseGVN* phase) const { // Either input is TOP ==> the result is TOP const Type *t1 = phase->type( in(MemNode::Memory) ); @@ -2465,7 +2449,7 @@ const Type* LoadNode::klass_value_common(PhaseGVN* phase) const { // a primitive Class (e.g., int.class) has null for a klass field return TypePtr::NULL_PTR; } - // (Folds up the 1st indirection in aClassConstant.getModifiers().) + // Fold up the load of the hidden field return TypeKlassPtr::make(t->as_klass(), Type::trust_interfaces); } // non-constant mirror, so we can't tell what's going on @@ -2862,16 +2846,16 @@ class MergePrimitiveStores : public StackObj { return is_trace(TraceMergeStores::Tag::BASIC); } - bool is_trace_pointer() const { - return is_trace(TraceMergeStores::Tag::POINTER); + bool is_trace_pointer_parsing() const { + return is_trace(TraceMergeStores::Tag::POINTER_PARSING); } - bool is_trace_aliasing() const { - return is_trace(TraceMergeStores::Tag::ALIASING); + bool is_trace_pointer_aliasing() const { + return is_trace(TraceMergeStores::Tag::POINTER_ALIASING); } - bool is_trace_adjacency() const { - return is_trace(TraceMergeStores::Tag::ADJACENCY); + bool is_trace_pointer_adjacency() const { + return is_trace(TraceMergeStores::Tag::POINTER_ADJACENCY); } bool is_trace_success() const { @@ -2942,12 +2926,13 @@ bool MergePrimitiveStores::is_adjacent_pair(const StoreNode* use_store, const St ResourceMark rm; #ifndef PRODUCT - const TraceMemPointer trace(is_trace_pointer(), - is_trace_aliasing(), - is_trace_adjacency()); + const TraceMemPointer trace(is_trace_pointer_parsing(), + is_trace_pointer_aliasing(), + is_trace_pointer_adjacency(), + true); #endif - const MemPointer pointer_use(use_store NOT_PRODUCT( COMMA trace )); - const MemPointer pointer_def(def_store NOT_PRODUCT( COMMA trace )); + const MemPointer pointer_use(use_store NOT_PRODUCT(COMMA trace)); + const MemPointer pointer_def(def_store NOT_PRODUCT(COMMA trace)); return pointer_def.is_adjacent_to_and_before(pointer_use); } @@ -5194,7 +5179,7 @@ bool InitializeNode::stores_are_sane(PhaseValues* phase) { intptr_t st_off = get_store_offset(st, phase); if (st_off < 0) continue; // ignore dead garbage if (last_off > st_off) { - tty->print_cr("*** bad store offset at %d: " INTX_FORMAT " > " INTX_FORMAT, i, last_off, st_off); + tty->print_cr("*** bad store offset at %d: %zd > %zd", i, last_off, st_off); this->dump(2); assert(false, "ascending store offsets"); return false; diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp index ee9db7d1cac1c..b19f7dda98976 100644 --- a/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -522,20 +522,18 @@ class LoadNNode : public LoadNode { //------------------------------LoadKlassNode---------------------------------- // Load a Klass from an object class LoadKlassNode : public LoadPNode { -protected: - // In most cases, LoadKlassNode does not have the control input set. If the control - // input is set, it must not be removed (by LoadNode::Ideal()). - virtual bool can_remove_control() const; +private: + LoadKlassNode(Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk, MemOrd mo) + : LoadPNode(nullptr, mem, adr, at, tk, mo) {} + public: - LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo) - : LoadPNode(c, mem, adr, at, tk, mo) {} virtual int Opcode() const; virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); virtual bool depends_only_on_test() const { return true; } // Polymorphic factory method: - static Node* make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* at, + static Node* make(PhaseGVN& gvn, Node* mem, Node* adr, const TypePtr* at, const TypeKlassPtr* tk = TypeInstKlassPtr::OBJECT); }; @@ -548,9 +546,12 @@ class LoadKlassNode : public LoadPNode { // extract the actual class pointer. C2's type system is agnostic on whether the // input address directly points into the class pointer. class LoadNKlassNode : public LoadNNode { +private: + friend Node* LoadKlassNode::make(PhaseGVN&, Node*, Node*, const TypePtr*, const TypeKlassPtr*); + LoadNKlassNode(Node* mem, Node* adr, const TypePtr* at, const TypeNarrowKlass* tk, MemOrd mo) + : LoadNNode(nullptr, mem, adr, at, tk, mo) {} + public: - LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo) - : LoadNNode(c, mem, adr, at, tk, mo) {} virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegN; } virtual int store_Opcode() const { return Op_StoreNKlass; } diff --git a/src/hotspot/share/opto/mempointer.cpp b/src/hotspot/share/opto/mempointer.cpp index df443c69449cb..bede753ff07cf 100644 --- a/src/hotspot/share/opto/mempointer.cpp +++ b/src/hotspot/share/opto/mempointer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,17 +22,29 @@ * */ -#include "precompiled.hpp" #include "opto/mempointer.hpp" +#include "opto/addnode.hpp" #include "utilities/resourceHash.hpp" +#include "classfile/vmSymbols.hpp" + +MemPointerParserCallback MemPointerParserCallback::_empty; + +MemPointer::MemPointer(const MemNode* mem, + MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) : + MemPointer(MemPointerParser::parse(mem, + callback + NOT_PRODUCT(COMMA trace))) {} // Recursively parse the pointer expression with a DFS all-path traversal // (i.e. with node repetitions), starting at the pointer. -MemPointerDecomposedForm MemPointerDecomposedFormParser::parse_decomposed_form() { +MemPointer MemPointerParser::parse(MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) { assert(_worklist.is_empty(), "no prior parsing"); assert(_summands.is_empty(), "no prior parsing"); Node* pointer = _mem->in(MemNode::Address); + const jint size = _mem->memory_size(); // Start with the trivial summand. _worklist.push(MemPointerSummand(pointer, NoOverflowInt(1))); @@ -42,12 +54,16 @@ MemPointerDecomposedForm MemPointerDecomposedFormParser::parse_decomposed_form() int traversal_count = 0; while (_worklist.is_nonempty()) { // Bail out if the graph is too complex. - if (traversal_count++ > 1000) { return MemPointerDecomposedForm::make_trivial(pointer); } - parse_sub_expression(_worklist.pop()); + if (traversal_count++ > 1000) { + return MemPointer::make_trivial(pointer, size NOT_PRODUCT(COMMA trace)); + } + parse_sub_expression(_worklist.pop(), callback); } // Bail out if there is a constant overflow. - if (_con.is_NaN()) { return MemPointerDecomposedForm::make_trivial(pointer); } + if (_con.is_NaN()) { + return MemPointer::make_trivial(pointer, size NOT_PRODUCT(COMMA trace)); + } // Sorting by variable idx means that all summands with the same variable are consecutive. // This simplifies the combining of summands with the same variable below. @@ -67,7 +83,7 @@ MemPointerDecomposedForm MemPointerDecomposedFormParser::parse_decomposed_form() } // Bail out if scale is NaN. if (scale.is_NaN()) { - return MemPointerDecomposedForm::make_trivial(pointer); + return MemPointer::make_trivial(pointer, size NOT_PRODUCT(COMMA trace)); } // Keep summands with non-zero scale. if (!scale.is_zero()) { @@ -76,13 +92,13 @@ MemPointerDecomposedForm MemPointerDecomposedFormParser::parse_decomposed_form() } _summands.trunc_to(pos_put); - return MemPointerDecomposedForm::make(pointer, _summands, _con); + return MemPointer::make(pointer, _summands, _con, size NOT_PRODUCT(COMMA trace)); } // Parse a sub-expression of the pointer, starting at the current summand. We parse the // current node, and see if it can be decomposed into further summands, or if the current // summand is terminal. -void MemPointerDecomposedFormParser::parse_sub_expression(const MemPointerSummand& summand) { +void MemPointerParser::parse_sub_expression(const MemPointerSummand& summand, MemPointerParserCallback& callback) { Node* n = summand.variable(); const NoOverflowInt scale = summand.scale(); const NoOverflowInt one(1); @@ -108,6 +124,7 @@ void MemPointerDecomposedFormParser::parse_sub_expression(const MemPointerSumman Node* b = n->in((opc == Op_AddP) ? 3 : 2); _worklist.push(MemPointerSummand(a, scale)); _worklist.push(MemPointerSummand(b, scale)); + callback.callback(n); return; } case Op_SubL: @@ -121,6 +138,7 @@ void MemPointerDecomposedFormParser::parse_sub_expression(const MemPointerSumman _worklist.push(MemPointerSummand(a, scale)); _worklist.push(MemPointerSummand(b, sub_scale)); + callback.callback(n); return; } case Op_MulL: @@ -155,26 +173,37 @@ void MemPointerDecomposedFormParser::parse_sub_expression(const MemPointerSumman NoOverflowInt new_scale = scale * factor; _worklist.push(MemPointerSummand(variable, new_scale)); + callback.callback(n); return; } + case Op_CastX2P: + // A CastX2P indicates that we are pointing to native memory, where some long is cast to + // a pointer. In general, we have no guarantees about this long, and just take it as a + // terminal summand. A CastX2P can also be a good candidate for a native-memory "base". + if (!sub_expression_has_native_base_candidate(n->in(1))) { + // General case: take CastX2P as a terminal summand, it is a candidate for the "base". + break; + } + // Fall-through: we can find a more precise native-memory "base". We further decompose + // the CastX2P to find this "base" and any other offsets from it. case Op_CastII: case Op_CastLL: - case Op_CastX2P: case Op_ConvI2L: - // On 32bit systems we can also look through ConvL2I, since the final result will always - // be truncated back with ConvL2I. On 64bit systems we cannot decompose ConvL2I because - // such int values will eventually be expanded to long with a ConvI2L: - // - // valL = max_jint + 1 - // ConvI2L(ConvL2I(valL)) = ConvI2L(min_jint) = min_jint != max_jint + 1 = valL - // - NOT_LP64( case Op_ConvL2I: ) - { - // Decompose: look through. - Node* a = n->in(1); - _worklist.push(MemPointerSummand(a, scale)); - return; - } + // On 32bit systems we can also look through ConvL2I, since the final result will always + // be truncated back with ConvL2I. On 64bit systems we cannot decompose ConvL2I because + // such int values will eventually be expanded to long with a ConvI2L: + // + // valL = max_jint + 1 + // ConvI2L(ConvL2I(valL)) = ConvI2L(min_jint) = min_jint != max_jint + 1 = valL + // + NOT_LP64( case Op_ConvL2I: ) + { + // Decompose: look through. + Node* a = n->in(1); + _worklist.push(MemPointerSummand(a, scale)); + callback.callback(n); + return; + } default: // All other operations cannot be further decomposed. We just add them to the // terminal summands below. @@ -186,9 +215,67 @@ void MemPointerDecomposedFormParser::parse_sub_expression(const MemPointerSumman _summands.push(summand); } +bool MemPointerParser::sub_expression_has_native_base_candidate(Node* start) { + // BFS over the expression. + // Allocate sufficient space in worklist for 100 limit below. + ResourceMark rm; + GrowableArray worklist(102); + worklist.append(start); + for (int i = 0; i < worklist.length(); i++) { + Node* n = worklist.at(i); + switch (n->Opcode()) { + case Op_AddL: + // Traverse to both inputs. + worklist.append(n->in(1)); + worklist.append(n->in(2)); + break; + case Op_SubL: + case Op_CastLL: + // Traverse to the first input. The base cannot be on the rhs of a sub. + worklist.append(n->in(1)); + break; + default: + if (is_native_memory_base_candidate(n)) { return true; } + break; + } + // This is a heuristic, so we are allowed to bail out early if the graph + // is too deep. The constant is chosen arbitrarily, not too large but big + // enough for all normal cases. + if (worklist.length() > 100) { return false; } + } + // Parsed over the whole expression, nothing found. + return false; +} + +// Check if the node is a candidate to be a memory segment "base". +// (1) CastX2P: some arbitrary long that is cast to a pointer. +// (2) LoadL from field jdk.internal.foreign.NativeMemorySegmentImpl.min +// Holds the address() of a native memory segment. +bool MemPointerParser::is_native_memory_base_candidate(Node* n) { + // (1) CastX2P + if (n->Opcode() == Op_CastX2P) { return true; } + + // (2) LoadL from field jdk.internal.foreign.NativeMemorySegmentImpl.min + if (n->Opcode() != Op_LoadL) { return false; } + LoadNode* load = n->as_Load(); + + const TypeInstPtr* inst_ptr = load->adr_type()->isa_instptr(); + if (inst_ptr == nullptr) { return false; } + + ciInstanceKlass* klass = inst_ptr->instance_klass(); + int offset = inst_ptr->offset(); + ciField* field = klass->get_field_by_offset(offset, false); + if (field == nullptr) { return false; } + + Symbol* field_symbol = field->name()->get_symbol(); + Symbol* holder_symbol = field->holder()->name()->get_symbol(); + return holder_symbol == vmSymbols::jdk_internal_foreign_NativeMemorySegmentImpl() && + field_symbol == vmSymbols::min_name(); +} + // Check if the decomposition of operation opc is guaranteed to be safe. // Please refer to the definition of "safe decomposition" in mempointer.hpp -bool MemPointerDecomposedFormParser::is_safe_to_decompose_op(const int opc, const NoOverflowInt& scale) const { +bool MemPointerParser::is_safe_to_decompose_op(const int opc, const NoOverflowInt& scale) const { #ifndef _LP64 // On 32-bit platforms, the pointer has 32bits, and thus any higher bits will always // be truncated. Thus, it does not matter if we have int or long overflows. @@ -298,37 +385,81 @@ bool MemPointerDecomposedFormParser::is_safe_to_decompose_op(const int opc, cons #endif } -// Compute the aliasing between two MemPointerDecomposedForm. We use the "MemPointer Lemma" to -// prove that the computed aliasing also applies for the underlying pointers. Note that the -// condition (S0) is already given, because the MemPointerDecomposedForm is always constructed -// using only safe decompositions. +MemPointer::Base MemPointer::Base::make(Node* pointer, const GrowableArray& summands) { + // Bad form -> unknown. + AddPNode* adr = pointer->isa_AddP(); + if (adr == nullptr) { return Base(); } + + // Non-TOP base -> object. + Node* maybe_object_base = adr->in(AddPNode::Base); + bool is_object_base = !maybe_object_base->is_top(); + + Node* base = find_base(is_object_base ? maybe_object_base : nullptr, summands); + + if (base == nullptr) { + // Not found -> unknown. + return Base(); + } else if (is_object_base) { + assert(base == maybe_object_base, "we confirmed that it is in summands"); + return Base(Object, base); + } else { + return Base(Native, base); + } +} + +Node* MemPointer::Base::find_base(Node* object_base, const GrowableArray& summands) { + for (int i = 0; i < summands.length(); i++) { + const MemPointerSummand& s = summands.at(i); + assert(s.variable() != nullptr, "no empty summands"); + // Object base. + if (object_base != nullptr && s.variable() == object_base && s.scale().is_one()) { + return object_base; + } + // Native base. + if (object_base == nullptr && + s.scale().is_one() && + MemPointerParser::is_native_memory_base_candidate(s.variable())) { + return s.variable(); + } + } + return nullptr; +} + +// Compute the aliasing between two MemPointer. We use the "MemPointer Lemma" to prove that the +// computed aliasing also applies for the underlying pointers. Note that the condition (S0) is +// already given, because the MemPointer is always constructed using only safe decompositions. // // Pre-Condition: // We assume that both pointers are in-bounds of their respective memory object. If this does // not hold, for example, with the use of Unsafe, then we would already have undefined behavior, // and we are allowed to do anything. -MemPointerAliasing MemPointerDecomposedForm::get_aliasing_with(const MemPointerDecomposedForm& other - NOT_PRODUCT( COMMA const TraceMemPointer& trace) ) const { +MemPointerAliasing MemPointer::get_aliasing_with(const MemPointer& other + NOT_PRODUCT( COMMA const TraceMemPointer& trace) ) const { #ifndef PRODUCT if (trace.is_trace_aliasing()) { - tty->print_cr("MemPointerDecomposedForm::get_aliasing_with:"); + tty->print_cr("MemPointer::get_aliasing_with:"); print_on(tty); other.print_on(tty); } #endif // "MemPointer Lemma" condition (S2): check if all summands are the same: - for (uint i = 0; i < SUMMANDS_SIZE; i++) { - const MemPointerSummand s1 = summands_at(i); - const MemPointerSummand s2 = other.summands_at(i); - if (s1 != s2) { + bool has_same_base = false; + if (has_different_object_base_but_otherwise_same_summands_as(other)) { + // At runtime, the two object bases can be: + // (1) different: we have no aliasing, pointers point to different memory objects. + // (2) the same: implies that all summands are the same, (S2) holds. + has_same_base = false; + } else if (has_same_summands_as(other)) { + // (S2) holds. If all summands are the same, also the base must be the same. + has_same_base = true; + } else { #ifndef PRODUCT - if (trace.is_trace_aliasing()) { - tty->print_cr(" -> Aliasing unknown, differ on summand %d.", i); - } -#endif - return MemPointerAliasing::make_unknown(); + if (trace.is_trace_aliasing()) { + tty->print_cr(" -> Aliasing unknown, summands are not the same."); } +#endif + return MemPointerAliasing::make_unknown(); } // "MemPointer Lemma" condition (S3): check that the constants do not differ too much: @@ -346,34 +477,86 @@ MemPointerAliasing MemPointerDecomposedForm::get_aliasing_with(const MemPointerD return MemPointerAliasing::make_unknown(); } - // "MemPointer Lemma" condition (S1): - // Given that all summands are the same, we know that both pointers point into the - // same memory object. With the Pre-Condition, we know that both pointers are in - // bounds of that same memory object. - - // Hence, all 4 conditions of the "MemoryPointer Lemma" are established, and hence - // we know that the distance between the underlying pointers is equal to the distance - // we computed for the MemPointers: - // p_other - p_this = distance = other.con - this.con + if (has_same_base) { + // "MemPointer Lemma" condition (S1): + // Given that all summands are the same, we know that both pointers point into the + // same memory object. With the Pre-Condition, we know that both pointers are in + // bounds of that same memory object. + // + // Hence, all 4 conditions of the "MemPointer Lemma" are established, and hence + // we know that the distance between the underlying pointers is equal to the distance + // we computed for the MemPointers: + // p_other - p_this = distance = other.con - this.con +#ifndef PRODUCT + if (trace.is_trace_aliasing()) { + tty->print_cr(" -> Aliasing always at distance = %d.", distance.value()); + } +#endif + return MemPointerAliasing::make_always_at_distance(distance.value()); + } else { + // At runtime, the two object bases can be: + // (1) different: pointers do not alias. + // (2) the same: implies that (S2) holds. The summands are all the same, and with + // the Pre-Condition, we know that both pointers are in bounds of the + // same memory object, i.e. (S1) holds. We have already proven (S0) + // and (S3), so all 4 conditions for "MemPointer Lemma" are given. #ifndef PRODUCT if (trace.is_trace_aliasing()) { - tty->print_cr(" -> Aliasing always, distance = %d.", distance.value()); + tty->print_cr(" -> Aliasing not or at distance = %d.", distance.value()); } #endif - return MemPointerAliasing::make_always(distance.value()); + return MemPointerAliasing::make_not_or_at_distance(distance.value()); + } +} + +bool MemPointer::has_same_summands_as(const MemPointer& other, uint start) const { + for (uint i = start; i < SUMMANDS_SIZE; i++) { + if (summands_at(i) != other.summands_at(i)) { return false; } + } + return true; +} + +bool MemPointer::has_different_object_base_but_otherwise_same_summands_as(const MemPointer& other) const { + if (!base().is_object() || + !other.base().is_object() || + base().object() == other.base().object()) { + // The base is the same, or we do not know if the base is different. + return false; + } + +#ifdef ASSERT + const MemPointerSummand base1(base().object(), NoOverflowInt(1)); + const MemPointerSummand base2(other.base().object(), NoOverflowInt(1)); + assert(summands_at(0) == base1 && other.summands_at(0) == base2, "bases in 0th element"); +#endif + + // Check if all other summands are the same. + return has_same_summands_as(other, 1); } +// Examples: +// p1 = MemPointer[size=1, base + i + 16] +// p2 = MemPointer[size=1, base + i + 17] +// -> Always at distance 1 +// -> p1 always adjacent and before p2 -> return true +// +// p1 = MemPointer[size=4, x + y + z + 4L * i + 16] +// p2 = MemPointer[size=4, x + y + z + 4L * i + 20] +// -> Always at distance 4 +// -> p1 always adjacent and before p2 -> return true +// +// p1 = MemPointer[size=4, base1 + 4L * i1 + 16] +// p2 = MemPointer[size=4, base2 + 4L * i2 + 20] +// -> Have differing summands, distance is unknown +// -> Unknown if adjacent at runtime -> return false bool MemPointer::is_adjacent_to_and_before(const MemPointer& other) const { - const MemPointerDecomposedForm& s1 = decomposed_form(); - const MemPointerDecomposedForm& s2 = other.decomposed_form(); - const MemPointerAliasing aliasing = s1.get_aliasing_with(s2 NOT_PRODUCT( COMMA _trace )); - const jint size = mem()->memory_size(); - const bool is_adjacent = aliasing.is_always_at_distance(size); + const MemPointerAliasing aliasing = get_aliasing_with(other NOT_PRODUCT( COMMA _trace )); + const bool is_adjacent = aliasing.is_always_at_distance(_size); #ifndef PRODUCT if (_trace.is_trace_adjacency()) { tty->print("Adjacent: %s, because size = %d and aliasing = ", - is_adjacent ? "true" : "false", size); + is_adjacent ? "true" : "false", _size); aliasing.print_on(tty); tty->cr(); } @@ -381,3 +564,57 @@ bool MemPointer::is_adjacent_to_and_before(const MemPointer& other) const { return is_adjacent; } + +// Examples: +// p1 = MemPointer[size=1, base + i + 16] +// p2 = MemPointer[size=1, base + i + 17] +// -> Always at distance 1 +// -> Can never overlap -> return true +// +// p1 = MemPointer[size=1, base + i + 16] +// p2 = MemPointer[size=1, base + i + 16] +// -> Always at distance 0 +// -> Always have exact overlap -> return false +// +// p1 = MemPointer[size=4, x + y + z + 4L * i + 16] +// p2 = MemPointer[size=4, x + y + z + 4L * i + 56] +// -> Always at distance 40 +// -> Can never overlap -> return true +// +// p1 = MemPointer[size=8, x + y + z + 4L * i + 16] +// p2 = MemPointer[size=8, x + y + z + 4L * i + 20] +// -> Always at distance 4 +// -> Always have partial overlap -> return false +// +// p1 = MemPointer[size=4, base1 + 4L * i1 + 16] +// p2 = MemPointer[size=4, base2 + 4L * i2 + 20] +// -> Have differing summands, distance is unknown +// -> Unknown if overlap at runtime -> return false +bool MemPointer::never_overlaps_with(const MemPointer& other) const { + const MemPointerAliasing aliasing = get_aliasing_with(other NOT_PRODUCT( COMMA _trace )); + + // The aliasing tries to compute: + // distance = other - this + // + // We know that we have no overlap if we can prove: + // this >= other + other.size || this + this.size <= other + // + // Which we can restate as: + // distance <= -other.size || this.size <= distance + // + const jint distance_lo = -other.size(); + const jint distance_hi = size(); + bool is_never_overlap = aliasing.is_never_in_distance_range(distance_lo, distance_hi); + +#ifndef PRODUCT + if (_trace.is_trace_overlap()) { + tty->print("Never Overlap: %s, distance_lo: %d, distance_hi: %d, aliasing: ", + is_never_overlap ? "true" : "false", distance_lo, distance_hi); + aliasing.print_on(tty); + tty->cr(); + } +#endif + + return is_never_overlap; +} + diff --git a/src/hotspot/share/opto/mempointer.hpp b/src/hotspot/share/opto/mempointer.hpp index 100fbfc71bd6c..f1d29f2453f52 100644 --- a/src/hotspot/share/opto/mempointer.hpp +++ b/src/hotspot/share/opto/mempointer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,18 @@ #include "opto/memnode.hpp" #include "opto/noOverflowInt.hpp" -// The MemPointer is a shared facility to parse pointers and check the aliasing of pointers, -// e.g. checking if two stores are adjacent. +// The MemPointer is a shared facility to parse pointers and check the aliasing of pointers. +// +// A MemPointer points to a region in memory, starting at a "pointer", and extending for "size" bytes: +// [pointer, pointer + size) +// +// We can check if two loads / two stores: +// - are adjacent -> pack multiple memops into a single memop +// - never overlap -> independent, can swap order +// +// Other use-cases: +// - alignment -> find an alignment solution for all memops in a vectorized loop +// - detect partial overlap -> indicates store-to-load-forwarding failures // // ----------------------------------------------------------------------------------------- // @@ -143,7 +153,7 @@ // // ----------------------------------------------------------------------------------------- // -// MemPointerDecomposedForm: +// MemPointer: // When the pointer is parsed, it is decomposed into a SUM of summands plus a constant: // // pointer = SUM(summands) + con @@ -161,17 +171,6 @@ // On 64-bit systems, this decomposed form is computed with long-add/mul, on 32-bit systems // it is computed with int-add/mul. // -// MemPointerAliasing: -// The decomposed form allows us to determine the aliasing between two pointers easily. For -// example, if two pointers are identical, except for their constant: -// -// pointer1 = SUM(summands) + con1 -// pointer2 = SUM(summands) + con2 -// -// then we can easily compute the distance between the pointers (distance = con2 - con1), -// and determine if they are adjacent. -// -// MemPointerDecomposedFormParser: // Any pointer can be parsed into this (default / trivial) decomposed form: // // pointer = 1 * pointer + 0 @@ -194,11 +193,55 @@ // // This allows us to easily see that these two pointers are adjacent (distance = 4). // -// Hence, in MemPointerDecomposedFormParser::parse_decomposed_form, we start with the pointer as -// a trivial summand. A summand can either be decomposed further or it is terminal (cannot -// be decomposed further). We decompose the summands recursively until all remaining summands -// are terminal, see MemPointerDecomposedFormParser::parse_sub_expression. This effectively parses -// the pointer expression recursively. +// Hence, in MemPointerParser::parse, we start with the pointer as a trivial summand. A summand can either +// be decomposed further or it is terminal (cannot be decomposed further). We decompose the summands +// recursively until all remaining summands are terminal, see MemPointerParser::parse_sub_expression. +// This effectively parses the pointer expression recursively. +// +// MemPointerAliasing: +// The decomposed form allows us to determine the aliasing between two pointers easily. For +// example, if two pointers are identical, except for their constant: +// +// pointer1 = SUM(summands) + con1 +// pointer2 = SUM(summands) + con2 +// +// then we can easily compute the distance between the pointers (distance = con2 - con1), +// and determine if they are adjacent. +// +// MemPointer::Base +// The MemPointer is decomposed like this: +// pointer = SUM(summands) + con +// +// This is sufficient for simple adjacency checks and we do not need to know if the pointer references +// native (off-heap) or object (heap) memory. However, in some cases it is necessary or useful to know +// the object base, or the native pointer's base. +// +// - Object (heap) base (MemPointer::base().is_object()): +// Is the base of the Java object, which resides on the Java heap. +// Guarantees: +// - Always has an alignment of ObjectAlignmentInBytes. +// - A MemPointer with a given object base always must point into the memory of that object. Thus, +// if we have two pointers with two different bases at runtime, we know the two pointers do not +// alias. +// +// - Native (off-heap) base (MemPointer::base().is_native()): +// When we decompose a pointer to native memory, it is at first not clear that there is a base address. +// Even if we could know that there is some base address to which we add index offsets, we cannot know +// if this reference address points to the beginning of a native memory allocation or into the middle, +// or outside it. We also have no guarantee for alignment with such a base address. +// Still: we would like to find such a base if possible, and if two pointers are similar (i.e. have the +// same summands), we would like to find the same base. Further, it is reasonable to speculatively +// assume that such base addresses are aligned (TODO: need to add this speculative check in JDK-8323582). +// A base pointer must have scale = 1, and be accepted byMemPointer::is_native_memory_base_candidate. +// It can thus be one of these: +// (1) CastX2P +// This is simply some arbitrary long cast to a pointer. It may be computed as an addition of +// multiple long and even int values. In some cases this means that we could have further +// decomposed the CastX2P, but at that point it is even harder to tell what should be a good +// candidate for a native memory base. +// (2) LoadL from field jdk.internal.foreign.NativeMemorySegmentImpl.min +// This would be preferable over CastX2P, because it holds the address() of a native +// MemorySegment, i.e. we know it points to the beginning of that MemorySegment. // // ----------------------------------------------------------------------------------------- // @@ -259,12 +302,11 @@ // mp1 and mp2: // p1 - p2 = mp1 - mp2 // -// Note: MemPointerDecomposedForm::get_aliasing_with relies on this MemPointer Lemma to -// prove the correctness of its aliasing computation between two MemPointers. +// Note: MemPointer::get_aliasing_with relies on this MemPointer Lemma to prove the correctness of its +// aliasing computation between two MemPointers. // // -// Note: MemPointerDecomposedFormParser::is_safe_to_decompose_op checks that all -// decompositions we apply are safe. +// Note: MemPointerParser::is_safe_to_decompose_op checks that all decompositions we apply are safe. // // // Proof of the "MemPointer Lemma": @@ -341,41 +383,51 @@ // This shows that p1 and p2 have a distance greater than the array size, and hence at least one of the two // pointers must be out of bounds. This contradicts our assumption (S1) and we are done. - #ifndef PRODUCT class TraceMemPointer : public StackObj { private: - const bool _is_trace_pointer; + const bool _is_trace_parsing; const bool _is_trace_aliasing; const bool _is_trace_adjacency; + const bool _is_trace_overlap; public: - TraceMemPointer(const bool is_trace_pointer, + TraceMemPointer(const bool is_trace_parsing, const bool is_trace_aliasing, - const bool is_trace_adjacency) : - _is_trace_pointer( is_trace_pointer), + const bool is_trace_adjacency, + const bool is_trace_overlap) : + _is_trace_parsing( is_trace_parsing), _is_trace_aliasing( is_trace_aliasing), - _is_trace_adjacency(is_trace_adjacency) + _is_trace_adjacency(is_trace_adjacency), + _is_trace_overlap(is_trace_overlap) {} - bool is_trace_pointer() const { return _is_trace_pointer; } + bool is_trace_parsing() const { return _is_trace_parsing; } bool is_trace_aliasing() const { return _is_trace_aliasing; } bool is_trace_adjacency() const { return _is_trace_adjacency; } + bool is_trace_overlap() const { return _is_trace_overlap; } }; #endif // Class to represent aliasing between two MemPointer. class MemPointerAliasing { -public: - enum Aliasing { - Unknown, // Distance unknown. - // Example: two "int[]" with different variable index offsets. - // e.g. "array[i] vs array[j]". - // e.g. "array1[i] vs array2[j]". - Always}; // Constant distance = p1 - p2. - // Example: The same address expression, except for a constant offset - // e.g. "array[i] vs array[i+1]". private: + enum Aliasing { + Unknown, // Distance unknown. + // Example: two "int[]" (unknown if the same) with different variable index offsets: + // e.g. "array[i] vs array[j]". + // e.g. "array1[i] vs array2[j]". + AlwaysAtDistance, // Constant distance = p2 - p1. + // Example: The same address expression, except for a constant offset: + // e.g. "array[i] vs array[i+1]". + NotOrAtDistance}; // At compile-time, we know that at run-time it is either of these: + // (1) Not: The pointers belong to different memory objects. Distance unknown. + // (2) AtConstDistance: distance = p2 - p1. + // Example: two "int[]" (unknown if the same) with indices that only differ by a + // constant offset: + // e.g. "array1[i] vs array2[i+4]": + // if "array1 == array2": distance = 4. + // if "array1 != array2": different memory objects. const Aliasing _aliasing; const jint _distance; @@ -391,27 +443,39 @@ class MemPointerAliasing { return MemPointerAliasing(Unknown, 0); } - static MemPointerAliasing make_always(const jint distance) { - return MemPointerAliasing(Always, distance); + static MemPointerAliasing make_always_at_distance(const jint distance) { + return MemPointerAliasing(AlwaysAtDistance, distance); + } + + static MemPointerAliasing make_not_or_at_distance(const jint distance) { + return MemPointerAliasing(NotOrAtDistance, distance); } // Use case: exact aliasing and adjacency. bool is_always_at_distance(const jint distance) const { - return _aliasing == Always && _distance == distance; + return _aliasing == AlwaysAtDistance && _distance == distance; + } + + // Use case: overlap. + // Note: the bounds are exclusive: lo < element < hi + bool is_never_in_distance_range(const jint distance_lo, const jint distance_hi) const { + return (_aliasing == AlwaysAtDistance || _aliasing == NotOrAtDistance) && + (_distance <= distance_lo || distance_hi <= _distance); } #ifndef PRODUCT void print_on(outputStream* st) const { switch(_aliasing) { - case Unknown: st->print("Unknown"); break; - case Always: st->print("Always(%d)", _distance); break; + case Unknown: st->print("Unknown"); break; + case AlwaysAtDistance: st->print("AlwaysAtDistance(%d)", _distance); break; + case NotOrAtDistance: st->print("NotOrAtDistance(%d)", _distance); break; default: ShouldNotReachHere(); } } #endif }; -// Summand of a MemPointerDecomposedForm: +// Summand of a MemPointer: // // summand = scale * variable // @@ -437,13 +501,24 @@ class MemPointerSummand : public StackObj { NoOverflowInt scale() const { return _scale; } static int cmp_by_variable_idx(MemPointerSummand* p1, MemPointerSummand* p2) { - if (p1->variable() == nullptr) { - return (p2->variable() == nullptr) ? 0 : 1; - } else if (p2->variable() == nullptr) { + return cmp_by_variable_idx(*p1, *p2); + } + + static int cmp_by_variable_idx(const MemPointerSummand& p1, const MemPointerSummand& p2) { + if (p1.variable() == nullptr) { + return (p2.variable() == nullptr) ? 0 : 1; + } + if (p2.variable() == nullptr) { return -1; } + return p1.variable()->_idx - p2.variable()->_idx; + } - return p1->variable()->_idx - p2->variable()->_idx; + static int cmp(const MemPointerSummand& p1, const MemPointerSummand& p2) { + int cmp = cmp_by_variable_idx(p1, p2); + if (cmp != 0) { return cmp; } + + return NoOverflowInt::cmp(p1.scale(), p2.scale()); } friend bool operator==(const MemPointerSummand a, const MemPointerSummand b) { @@ -461,97 +536,302 @@ class MemPointerSummand : public StackObj { #ifndef PRODUCT void print_on(outputStream* st) const { - st->print("Summand["); _scale.print_on(st); - tty->print(" * [%d %s]]", _variable->_idx, _variable->Name()); + tty->print(" * [%d %s]", _variable->_idx, _variable->Name()); } #endif }; -// Decomposed form of the pointer sub-expression of "pointer". +// Parsing calls the callback on every decomposed node. These are all the +// nodes on the paths from the pointer to the summand variables, i.e. the +// "inner" nodes of the pointer expression. This callback is for example +// used in SuperWord::unrolling_analysis to collect all inner nodes of a +// pointer expression. +class MemPointerParserCallback : public StackObj { +private: + static MemPointerParserCallback _empty; + +public: + virtual void callback(Node* n) { /* do nothing by default */ } + + // Singleton for default arguments. + static MemPointerParserCallback& empty() { return _empty; } +}; + +// A MemPointer points to a region in memory, starting at a "pointer", and extending +// for "size" bytes: +// +// [pointer, pointer + size) +// +// Where the "pointer" is decomposed into the following form: // // pointer = SUM(summands) + con +// pointer = SUM(scale_i * variable_i) + con // -class MemPointerDecomposedForm : public StackObj { -private: +// Where SUM() adds all "scale_i * variable_i" for each i together. +// +// Note: if the base is known, then it is in the 0th summand. A base can be: +// - on-heap / object: base().object() +// - off-heap / native: base().native() +// +// pointer = scale_0 * variable_0 + scale_1 * scale_1 + ... + con +// pointer = 1 * base + scale_1 * scale_1 + ... + con +// +class MemPointer : public StackObj { +public: // We limit the number of summands to 10. This is just a best guess, and not at this // point supported by evidence. But I think it is reasonable: usually, a pointer // contains a base pointer (e.g. array pointer or null for native memory) and a few // variables. It should be rare that we have more than 9 variables. static const int SUMMANDS_SIZE = 10; - Node* _pointer; // pointer node associated with this (sub)pointer + // A base can be: + // - Known: + // - On-heap: Object + // - Off-heap: Native + // - Unknown + class Base : public StackObj { + private: + enum Kind { Unknown, Object, Native }; + Kind _kind; + Node* _base; + + Base(Kind kind, Node* base) : _kind(kind), _base(base) { + assert((kind == Unknown) == (base == nullptr), "known base"); + } - MemPointerSummand _summands[SUMMANDS_SIZE]; - NoOverflowInt _con; + public: + Base() : Base(Unknown, nullptr) {} + static Base make(Node* pointer, const GrowableArray& summands); -public: - // Empty - MemPointerDecomposedForm() : _pointer(nullptr), _con(NoOverflowInt::make_NaN()) {} + bool is_known() const { return _kind != Unknown; } + bool is_object() const { return _kind == Object; } + bool is_native() const { return _kind == Native; } + Node* object() const { assert(is_object(), "unexpected kind"); return _base; } + Node* native() const { assert(is_native(), "unexpected kind"); return _base; } + Node* object_or_native() const { assert(is_known(), "unexpected kind"); return _base; } + Node* object_or_native_or_null() const { return _base; } + +#ifndef PRODUCT + void print_on(outputStream* st) const { + switch (_kind) { + case Object: + st->print("object "); + st->print("%d %s", _base->_idx, _base->Name()); + break; + case Native: + st->print("native "); + st->print("%d %s", _base->_idx, _base->Name()); + break; + default: + st->print("unknown "); + }; + } +#endif + + private: + static Node* find_base(Node* object_base, const GrowableArray& summands); + }; private: + MemPointerSummand _summands[SUMMANDS_SIZE]; + const NoOverflowInt _con; + const Base _base; + const jint _size; + NOT_PRODUCT( const TraceMemPointer& _trace; ) + // Default / trivial: pointer = 0 + 1 * pointer - MemPointerDecomposedForm(Node* pointer) : _pointer(pointer), _con(NoOverflowInt(0)) { + MemPointer(Node* pointer, + const jint size + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) : + _con(NoOverflowInt(0)), + _base(Base()), + _size(size) + NOT_PRODUCT(COMMA _trace(trace)) + { assert(pointer != nullptr, "pointer must be non-null"); _summands[0] = MemPointerSummand(pointer, NoOverflowInt(1)); + assert(1 <= _size && _size <= 2048 && is_power_of_2(_size), "sanity: no vector is expected to be larger"); } - MemPointerDecomposedForm(Node* pointer, const GrowableArray& summands, const NoOverflowInt& con) - : _pointer(pointer), _con(con) { + // pointer = SUM(SUMMANDS) + con + MemPointer(Node* pointer, + const GrowableArray& summands, + const NoOverflowInt& con, + const jint size + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) : + _con(con), + _base(Base::make(pointer, summands)), + _size(size) + NOT_PRODUCT(COMMA _trace(trace)) + { assert(!_con.is_NaN(), "non-NaN constant"); assert(summands.length() <= SUMMANDS_SIZE, "summands must fit"); +#ifdef ASSERT for (int i = 0; i < summands.length(); i++) { - MemPointerSummand s = summands.at(i); + const MemPointerSummand& s = summands.at(i); assert(s.variable() != nullptr, "variable cannot be null"); assert(!s.scale().is_NaN(), "non-NaN scale"); - _summands[i] = s; + } +#endif + + // Put the base in the 0th summand. + Node* base = _base.object_or_native_or_null(); + int pos = 0; + if (base != nullptr) { + MemPointerSummand b(base, NoOverflowInt(1)); + _summands[0] = b; + pos++; + } + // Put all other summands afterward. + for (int i = 0; i < summands.length(); i++) { + const MemPointerSummand& s = summands.at(i); + if (s.variable() == base && s.scale().is_one()) { continue; } + _summands[pos++] = summands.at(i); + } + assert(pos == summands.length(), "copied all summands"); + + assert(1 <= _size && _size <= 2048 && is_power_of_2(_size), "sanity: no vector is expected to be larger"); + } + + // Mutated copy. + // The new MemPointer is identical, except it has a different size and con. + MemPointer(const MemPointer& old, + const NoOverflowInt new_con, + const jint new_size) : + _con(new_con), + _base(old.base()), + _size(new_size) + NOT_PRODUCT(COMMA _trace(old._trace)) + { + assert(!_con.is_NaN(), "non-NaN constant"); + for (int i = 0; i < SUMMANDS_SIZE; i++) { + _summands[i] = old.summands_at(i); } } public: - static MemPointerDecomposedForm make_trivial(Node* pointer) { - return MemPointerDecomposedForm(pointer); + // Parse pointer of MemNode. Delegates to MemPointerParser::parse. + // callback: receives a callback for every decomposed (inner) node + // of the pointer expression. + MemPointer(const MemNode* mem, + MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)); + + // Parse pointer of MemNode. Delegates to MemPointerParser::parse. + MemPointer(const MemNode* mem + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) : + MemPointer(mem, MemPointerParserCallback::empty() NOT_PRODUCT(COMMA trace)) {} + + static MemPointer make_trivial(Node* pointer, + const jint size + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) { + return MemPointer(pointer, size NOT_PRODUCT(COMMA trace)); } - static MemPointerDecomposedForm make(Node* pointer, const GrowableArray& summands, const NoOverflowInt& con) { + static MemPointer make(Node* pointer, + const GrowableArray& summands, + const NoOverflowInt& con, + const jint size + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) { if (summands.length() <= SUMMANDS_SIZE) { - return MemPointerDecomposedForm(pointer, summands, con); + return MemPointer(pointer, summands, con, size NOT_PRODUCT(COMMA trace)); } else { - return MemPointerDecomposedForm::make_trivial(pointer); + return MemPointer::make_trivial(pointer, size NOT_PRODUCT(COMMA trace)); } } - MemPointerAliasing get_aliasing_with(const MemPointerDecomposedForm& other - NOT_PRODUCT( COMMA const TraceMemPointer& trace) ) const; + MemPointer make_with_size(const jint new_size) const { + return MemPointer(*this, this->con(), new_size); + }; + + MemPointer make_with_con(const NoOverflowInt new_con) const { + return MemPointer(*this, new_con, this->size()); + }; - const MemPointerSummand summands_at(const uint i) const { +private: + MemPointerAliasing get_aliasing_with(const MemPointer& other + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) const; + + bool has_same_summands_as(const MemPointer& other, uint start) const; + bool has_same_summands_as(const MemPointer& other) const { return has_same_summands_as(other, 0); } + bool has_different_object_base_but_otherwise_same_summands_as(const MemPointer& other) const; + +public: + bool has_same_non_base_summands_as(const MemPointer& other) const { + if (!base().is_known() || !other.base().is_known()) { + assert(false, "unknown base case is not answered optimally"); + return false; + } + // Known base at 0th summand: all other summands are non-base summands. + return has_same_summands_as(other, 1); + } + + const MemPointerSummand& summands_at(const uint i) const { assert(i < SUMMANDS_SIZE, "in bounds"); return _summands[i]; } const NoOverflowInt con() const { return _con; } + const Base& base() const { return _base; } + jint size() const { return _size; } + + static int cmp_summands(const MemPointer& a, const MemPointer& b) { + for (int i = 0; i < SUMMANDS_SIZE; i++) { + const MemPointerSummand& s_a = a.summands_at(i); + const MemPointerSummand& s_b = b.summands_at(i); + int cmp = MemPointerSummand::cmp(s_a, s_b); + if (cmp != 0) { return cmp;} + } + return 0; + } + + template + void for_each_non_empty_summand(Callback callback) const { + for (int i = 0; i < SUMMANDS_SIZE; i++) { + const MemPointerSummand& s = summands_at(i); + if (s.variable() != nullptr) { + callback(s); + } + } + } + + bool is_adjacent_to_and_before(const MemPointer& other) const; + bool never_overlaps_with(const MemPointer& other) const; #ifndef PRODUCT - void print_on(outputStream* st) const { - if (_pointer == nullptr) { - st->print_cr("MemPointerDecomposedForm empty."); + void print_form_on(outputStream* st) const { + if (_con.is_NaN()) { + st->print_cr("empty"); return; } - st->print("MemPointerDecomposedForm[%d %s: con = ", _pointer->_idx, _pointer->Name()); _con.print_on(st); for (int i = 0; i < SUMMANDS_SIZE; i++) { const MemPointerSummand& summand = _summands[i]; if (summand.variable() != nullptr) { - st->print(", "); + st->print(" + "); summand.print_on(st); } } - st->print_cr("]"); + } + + void print_on(outputStream* st, bool end_with_cr = true) const { + st->print("MemPointer[size: %2d, base: ", size()); + _base.print_on(st); + st->print(", form: "); + print_form_on(st); + st->print("]"); + if (end_with_cr) { st->cr(); } } #endif }; -class MemPointerDecomposedFormParser : public StackObj { +// Utility class. +// MemPointerParser::parse takes a MemNode (load or store) and computes its MemPointer. +// It temporarily allocates dynamic data structures (GrowableArray) in the resource +// area. This way, the computed MemPointer does not have to have any dynamic data +// structures and can be copied freely by value. +class MemPointerParser : public StackObj { private: const MemNode* _mem; @@ -561,58 +841,47 @@ class MemPointerDecomposedFormParser : public StackObj { GrowableArray _summands; // Resulting decomposed-form. - MemPointerDecomposedForm _decomposed_form; - -public: - MemPointerDecomposedFormParser(const MemNode* mem) : _mem(mem), _con(NoOverflowInt(0)) { - _decomposed_form = parse_decomposed_form(); - } - - const MemPointerDecomposedForm decomposed_form() const { return _decomposed_form; } - -private: - MemPointerDecomposedForm parse_decomposed_form(); - void parse_sub_expression(const MemPointerSummand& summand); - - bool is_safe_to_decompose_op(const int opc, const NoOverflowInt& scale) const; -}; - -// Facility to parse the pointer of a Load or Store, so that aliasing between two such -// memory operations can be determined (e.g. adjacency). -class MemPointer : public StackObj { -private: - const MemNode* _mem; - const MemPointerDecomposedForm _decomposed_form; + MemPointer _mem_pointer; - NOT_PRODUCT( const TraceMemPointer& _trace; ) + MemPointerParser(const MemNode* mem, + MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) : + _mem(mem), + _con(NoOverflowInt(0)), + _mem_pointer(parse(callback NOT_PRODUCT(COMMA trace))) {} public: - MemPointer(const MemNode* mem NOT_PRODUCT( COMMA const TraceMemPointer& trace)) : - _mem(mem), - _decomposed_form(init_decomposed_form(_mem)) - NOT_PRODUCT( COMMA _trace(trace) ) - { + static MemPointer parse(const MemNode* mem, + MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)) { + assert(mem->is_Store() || mem->is_Load(), "only stores and loads are allowed"); + ResourceMark rm; + MemPointerParser parser(mem, callback NOT_PRODUCT(COMMA trace)); + #ifndef PRODUCT - if (_trace.is_trace_pointer()) { - tty->print_cr("MemPointer::MemPointer:"); - tty->print("mem: "); mem->dump(); - _mem->in(MemNode::Address)->dump_bfs(5, nullptr, "d"); - _decomposed_form.print_on(tty); + if (trace.is_trace_parsing()) { + tty->print_cr("\nMemPointerParser::parse:"); + tty->print(" mem: "); mem->dump(); + parser.mem_pointer().print_on(tty); + mem->in(MemNode::Address)->dump_bfs(7, nullptr, "d"); } #endif + + return parser.mem_pointer(); } - const MemNode* mem() const { return _mem; } - const MemPointerDecomposedForm decomposed_form() const { return _decomposed_form; } - bool is_adjacent_to_and_before(const MemPointer& other) const; + static bool is_native_memory_base_candidate(Node* n); private: - static const MemPointerDecomposedForm init_decomposed_form(const MemNode* mem) { - assert(mem->is_Store(), "only stores are supported"); - ResourceMark rm; - MemPointerDecomposedFormParser parser(mem); - return parser.decomposed_form(); - } + const MemPointer& mem_pointer() const { return _mem_pointer; } + + MemPointer parse(MemPointerParserCallback& callback + NOT_PRODUCT(COMMA const TraceMemPointer& trace)); + + void parse_sub_expression(const MemPointerSummand& summand, MemPointerParserCallback& callback); + static bool sub_expression_has_native_base_candidate(Node* n); + + bool is_safe_to_decompose_op(const int opc, const NoOverflowInt& scale) const; }; #endif // SHARE_OPTO_MEMPOINTER_HPP diff --git a/src/hotspot/share/opto/movenode.cpp b/src/hotspot/share/opto/movenode.cpp index dc65afff26f0f..4b3b8547bec22 100644 --- a/src/hotspot/share/opto/movenode.cpp +++ b/src/hotspot/share/opto/movenode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/connode.hpp" #include "opto/convertnode.hpp" @@ -102,7 +101,7 @@ Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Canonicalize the node by moving constants to the right input. if (in(Condition)->is_Bool() && phase->type(in(IfFalse))->singleton() && !phase->type(in(IfTrue))->singleton()) { BoolNode* b = in(Condition)->as_Bool()->negate(phase); - return make(in(Control), phase->transform(b), in(IfTrue), in(IfFalse), _type); + return make(phase->transform(b), in(IfTrue), in(IfFalse), _type); } return nullptr; @@ -186,15 +185,15 @@ const Type* CMoveNode::Value(PhaseGVN* phase) const { //------------------------------make------------------------------------------- // Make a correctly-flavored CMove. Since _type is directly determined // from the inputs we do not need to specify it here. -CMoveNode *CMoveNode::make(Node *c, Node *bol, Node *left, Node *right, const Type *t) { +CMoveNode* CMoveNode::make(Node* bol, Node* left, Node* right, const Type* t) { switch( t->basic_type() ) { - case T_INT: return new CMoveINode( bol, left, right, t->is_int() ); - case T_FLOAT: return new CMoveFNode( bol, left, right, t ); - case T_DOUBLE: return new CMoveDNode( bol, left, right, t ); - case T_LONG: return new CMoveLNode( bol, left, right, t->is_long() ); - case T_OBJECT: return new CMovePNode( c, bol, left, right, t->is_oopptr() ); - case T_ADDRESS: return new CMovePNode( c, bol, left, right, t->is_ptr() ); - case T_NARROWOOP: return new CMoveNNode( c, bol, left, right, t ); + case T_INT: return new CMoveINode(bol, left, right, t->is_int()); + case T_FLOAT: return new CMoveFNode(bol, left, right, t); + case T_DOUBLE: return new CMoveDNode(bol, left, right, t); + case T_LONG: return new CMoveLNode(bol, left, right, t->is_long()); + case T_OBJECT: return new CMovePNode(bol, left, right, t->is_oopptr()); + case T_ADDRESS: return new CMovePNode(bol, left, right, t->is_ptr()); + case T_NARROWOOP: return new CMoveNNode(bol, left, right, t); default: ShouldNotReachHere(); return nullptr; @@ -278,7 +277,7 @@ Node *CMoveINode::Ideal(PhaseGVN *phase, bool can_reshape) { if( in(Condition)->is_Bool() ) { BoolNode* b = in(Condition)->as_Bool(); BoolNode* b2 = b->negate(phase); - return make(in(Control), phase->transform(b2), in(IfTrue), in(IfFalse), _type); + return make(phase->transform(b2), in(IfTrue), in(IfFalse), _type); } } diff --git a/src/hotspot/share/opto/movenode.hpp b/src/hotspot/share/opto/movenode.hpp index 02db0c73079f8..59974f797029a 100644 --- a/src/hotspot/share/opto/movenode.hpp +++ b/src/hotspot/share/opto/movenode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ class CMoveNode : public TypeNode { virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type* Value(PhaseGVN* phase) const; virtual Node* Identity(PhaseGVN* phase); - static CMoveNode *make(Node *c, Node *bol, Node *left, Node *right, const Type *t); + static CMoveNode* make(Node* bol, Node* left, Node* right, const Type* t); // Helper function to spot cmove graph shapes static Node* is_cmove_id(PhaseTransform* phase, Node* cmp, Node* t, Node* f, BoolNode* b); static Node* Ideal_minmax(PhaseGVN* phase, CMoveNode* cmov); @@ -87,14 +87,14 @@ class CMoveLNode : public CMoveNode { //------------------------------CMovePNode------------------------------------- class CMovePNode : public CMoveNode { public: - CMovePNode( Node *c, Node *bol, Node *left, Node *right, const TypePtr* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); } + CMovePNode(Node* bol, Node* left, Node* right, const TypePtr* t) : CMoveNode(bol, left, right, t) {} virtual int Opcode() const; }; //------------------------------CMoveNNode------------------------------------- class CMoveNNode : public CMoveNode { public: - CMoveNNode( Node *c, Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) { init_req(Control,c); } + CMoveNNode(Node* bol, Node* left, Node* right, const Type* t ) : CMoveNode(bol, left, right, t) {} virtual int Opcode() const; }; diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index ad98fda025f07..b1a9219e11384 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/connode.hpp" @@ -67,7 +66,8 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { // only valid for the actual Mul nodes. uint op = Opcode(); bool real_mul = (op == Op_MulI) || (op == Op_MulL) || - (op == Op_MulF) || (op == Op_MulD); + (op == Op_MulF) || (op == Op_MulD) || + (op == Op_MulHF); // Convert "(-a)*(-b)" into "a*b". if (real_mul && in1->is_Sub() && in2->is_Sub()) { @@ -122,7 +122,8 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { // constant, flatten the expression tree. if( t2->singleton() && // Right input is a constant? op != Op_MulF && // Float & double cannot reassociate - op != Op_MulD ) { + op != Op_MulD && + op != Op_MulHF) { if( t2 == Type::TOP ) return nullptr; Node *mul1 = in(1); #ifdef ASSERT @@ -536,10 +537,31 @@ Node* MulFNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* base = in(1); return new AddFNode(base, base); } + return MulNode::Ideal(phase, can_reshape); +} +//============================================================================= +//------------------------------Ideal------------------------------------------ +// Check to see if we are multiplying by a constant 2 and convert to add, then try the regular MulNode::Ideal +Node* MulHFNode::Ideal(PhaseGVN* phase, bool can_reshape) { + const TypeH* t2 = phase->type(in(2))->isa_half_float_constant(); + + // x * 2 -> x + x + if (t2 != nullptr && t2->getf() == 2) { + Node* base = in(1); + return new AddHFNode(base, base); + } return MulNode::Ideal(phase, can_reshape); } +// Compute the product type of two half float ranges into this node. +const Type* MulHFNode::mul_ring(const Type* t0, const Type* t1) const { + if (t0 == Type::HALF_FLOAT || t1 == Type::HALF_FLOAT) { + return Type::HALF_FLOAT; + } + return TypeH::make(t0->getf() * t1->getf()); +} + //============================================================================= //------------------------------mul_ring--------------------------------------- // Compute the product type of two double ranges into this node. @@ -670,9 +692,11 @@ const Type *AndINode::mul_ring( const Type *t0, const Type *t1 ) const { return and_value(r0, r1); } +static bool AndIL_is_zero_element_under_mask(const PhaseGVN* phase, const Node* expr, const Node* mask, BasicType bt); + const Type* AndINode::Value(PhaseGVN* phase) const { - // patterns similar to (v << 2) & 3 - if (AndIL_shift_and_mask_is_always_zero(phase, in(1), in(2), T_INT, true)) { + if (AndIL_is_zero_element_under_mask(phase, in(1), in(2), T_INT) || + AndIL_is_zero_element_under_mask(phase, in(2), in(1), T_INT)) { return TypeInt::ZERO; } @@ -718,8 +742,8 @@ Node* AndINode::Identity(PhaseGVN* phase) { //------------------------------Ideal------------------------------------------ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) { - // pattern similar to (v1 + (v2 << 2)) & 3 transformed to v1 & 3 - Node* progress = AndIL_add_shift_and_mask(phase, T_INT); + // Simplify (v1 + v2) & mask to v1 & mask or v2 & mask when possible. + Node* progress = AndIL_sum_and_mask(phase, T_INT); if (progress != nullptr) { return progress; } @@ -802,8 +826,8 @@ const Type *AndLNode::mul_ring( const Type *t0, const Type *t1 ) const { } const Type* AndLNode::Value(PhaseGVN* phase) const { - // patterns similar to (v << 2) & 3 - if (AndIL_shift_and_mask_is_always_zero(phase, in(1), in(2), T_LONG, true)) { + if (AndIL_is_zero_element_under_mask(phase, in(1), in(2), T_LONG) || + AndIL_is_zero_element_under_mask(phase, in(2), in(1), T_LONG)) { return TypeLong::ZERO; } @@ -850,8 +874,8 @@ Node* AndLNode::Identity(PhaseGVN* phase) { //------------------------------Ideal------------------------------------------ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) { - // pattern similar to (v1 + (v2 << 2)) & 3 transformed to v1 & 3 - Node* progress = AndIL_add_shift_and_mask(phase, T_LONG); + // Simplify (v1 + v2) & mask to v1 & mask or v2 & mask when possible. + Node* progress = AndIL_sum_and_mask(phase, T_LONG); if (progress != nullptr) { return progress; } @@ -1901,6 +1925,28 @@ const Type* FmaFNode::Value(PhaseGVN* phase) const { #endif } +//============================================================================= +//------------------------------Value------------------------------------------ +const Type* FmaHFNode::Value(PhaseGVN* phase) const { + const Type* t1 = phase->type(in(1)); + if (t1 == Type::TOP) { return Type::TOP; } + if (t1->base() != Type::HalfFloatCon) { return Type::HALF_FLOAT; } + const Type* t2 = phase->type(in(2)); + if (t2 == Type::TOP) { return Type::TOP; } + if (t2->base() != Type::HalfFloatCon) { return Type::HALF_FLOAT; } + const Type* t3 = phase->type(in(3)); + if (t3 == Type::TOP) { return Type::TOP; } + if (t3->base() != Type::HalfFloatCon) { return Type::HALF_FLOAT; } +#ifndef __STDC_IEC_559__ + return Type::HALF_FLOAT; +#else + float f1 = t1->getf(); + float f2 = t2->getf(); + float f3 = t3->getf(); + return TypeH::make(fma(f1, f2, f3)); +#endif +} + //============================================================================= //------------------------------hash------------------------------------------- // Hash function for MulAddS2INode. Operation is commutative with commutative pairs. @@ -2052,99 +2098,109 @@ const Type* RotateRightNode::Value(PhaseGVN* phase) const { } } -// Given an expression (AndX shift mask) or (AndX mask shift), -// determine if the AndX must always produce zero, because the -// the shift (x< #0 -// (AndL (LShiftL _ #N) #M) => #0 -// (AndL (ConvI2L (LShiftI _ #N)) #M) => #0 -// The M and N values must satisfy ((-1 << N) & M) == 0. -// Because the optimization might work for a non-constant -// mask M, we check the AndX for both operand orders. -bool MulNode::AndIL_shift_and_mask_is_always_zero(PhaseGVN* phase, Node* shift, Node* mask, BasicType bt, bool check_reverse) { - if (mask == nullptr || shift == nullptr) { - return false; - } - const TypeInteger* mask_t = phase->type(mask)->isa_integer(bt); - if (mask_t == nullptr || phase->type(shift)->isa_integer(bt) == nullptr) { - return false; - } - shift = shift->uncast(); - if (shift == nullptr) { - return false; +//------------------------------ Sum & Mask ------------------------------ + +// Returns a lower bound on the number of trailing zeros in expr. +static jint AndIL_min_trailing_zeros(const PhaseGVN* phase, const Node* expr, BasicType bt) { + expr = expr->uncast(); + const TypeInteger* type = phase->type(expr)->isa_integer(bt); + if (type == nullptr) { + return 0; } - if (phase->type(shift)->isa_integer(bt) == nullptr) { - return false; + + if (type->is_con()) { + jlong con = type->get_con_as_long(bt); + return con == 0L ? (type2aelembytes(bt) * BitsPerByte) : count_trailing_zeros(con); } - BasicType shift_bt = bt; - if (bt == T_LONG && shift->Opcode() == Op_ConvI2L) { + + if (expr->Opcode() == Op_ConvI2L) { + expr = expr->in(1)->uncast(); bt = T_INT; - Node* val = shift->in(1); - if (val == nullptr) { - return false; - } - val = val->uncast(); - if (val == nullptr) { - return false; - } - if (val->Opcode() == Op_LShiftI) { - shift_bt = T_INT; - shift = val; - if (phase->type(shift)->isa_integer(bt) == nullptr) { - return false; - } - } + type = phase->type(expr)->isa_int(); } - if (shift->Opcode() != Op_LShift(shift_bt)) { - if (check_reverse && - (mask->Opcode() == Op_LShift(bt) || - (bt == T_LONG && mask->Opcode() == Op_ConvI2L))) { - // try it the other way around - return AndIL_shift_and_mask_is_always_zero(phase, mask, shift, bt, false); + + // Pattern: expr = (x << shift) + if (expr->Opcode() == Op_LShift(bt)) { + const TypeInt* shift_t = phase->type(expr->in(2))->isa_int(); + if (shift_t == nullptr || !shift_t->is_con()) { + return 0; } - return false; + // We need to truncate the shift, as it may not have been canonicalized yet. + // T_INT: 0..31 -> shift_mask = 4 * 8 - 1 = 31 + // T_LONG: 0..63 -> shift_mask = 8 * 8 - 1 = 63 + // (JLS: "Shift Operators") + jint shift_mask = type2aelembytes(bt) * BitsPerByte - 1; + return shift_t->get_con() & shift_mask; } - Node* shift2 = shift->in(2); - if (shift2 == nullptr) { - return false; - } - const Type* shift2_t = phase->type(shift2); - if (!shift2_t->isa_int() || !shift2_t->is_int()->is_con()) { + + return 0; +} + +// Checks whether expr is neutral additive element (zero) under mask, +// i.e. whether an expression of the form: +// (AndX (AddX (expr addend) mask) +// (expr + addend) & mask +// is equivalent to +// (AndX addend mask) +// addend & mask +// for any addend. +// (The X in AndX must be I or L, depending on bt). +// +// We check for the sufficient condition when the lowest set bit in expr is higher than +// the highest set bit in mask, i.e.: +// expr: eeeeee0000000000000 +// mask: 000000mmmmmmmmmmmmm +// <--w bits---> +// We do not test for other cases. +// +// Correctness: +// Given "expr" with at least "w" trailing zeros, +// let "mod = 2^w", "suffix_mask = mod - 1" +// +// Since "mask" only has bits set where "suffix_mask" does, we have: +// mask = suffix_mask & mask (SUFFIX_MASK) +// +// And since expr only has bits set above w, and suffix_mask only below: +// expr & suffix_mask == 0 (NO_BIT_OVERLAP) +// +// From unsigned modular arithmetic (with unsigned modulo %), and since mod is +// a power of 2, and we are computing in a ring of powers of 2, we know that +// (x + y) % mod = (x % mod + y) % mod +// (x + y) & suffix_mask = (x & suffix_mask + y) & suffix_mask (MOD_ARITH) +// +// We can now prove the equality: +// (expr + addend) & mask +// = (expr + addend) & suffix_mask & mask (SUFFIX_MASK) +// = (expr & suffix_mask + addend) & suffix_mask & mask (MOD_ARITH) +// = (0 + addend) & suffix_mask & mask (NO_BIT_OVERLAP) +// = addend & mask (SUFFIX_MASK) +// +// Hence, an expr with at least w trailing zeros is a neutral additive element under any mask with bit width w. +static bool AndIL_is_zero_element_under_mask(const PhaseGVN* phase, const Node* expr, const Node* mask, BasicType bt) { + // When the mask is negative, it has the most significant bit set. + const TypeInteger* mask_t = phase->type(mask)->isa_integer(bt); + if (mask_t == nullptr || mask_t->lo_as_long() < 0) { return false; } - jint shift_con = shift2_t->is_int()->get_con() & ((shift_bt == T_INT ? BitsPerJavaInteger : BitsPerJavaLong) - 1); - if ((((jlong)1) << shift_con) > mask_t->hi_as_long() && mask_t->lo_as_long() >= 0) { - return true; + // When the mask is constant zero, we defer to MulNode::Value to eliminate the entire AndX operation. + if (mask_t->hi_as_long() == 0) { + assert(mask_t->lo_as_long() == 0, "checked earlier"); + return false; } - return false; + jint mask_bit_width = BitsPerLong - count_leading_zeros(mask_t->hi_as_long()); + jint expr_trailing_zeros = AndIL_min_trailing_zeros(phase, expr, bt); + return expr_trailing_zeros >= mask_bit_width; } -// Given an expression (AndX (AddX v1 (LShiftX v2 #N)) #M) -// determine if the AndX must always produce (AndX v1 #M), -// because the shift (v2< (AndI v1 #M) -// (AndL (AddI v1 (LShiftL _ #N)) #M) => (AndL v1 #M) -// (AndL (AddL v1 (ConvI2L (LShiftI _ #N))) #M) => (AndL v1 #M) -// The M and N values must satisfy ((-1 << N) & M) == 0. -// Because the optimization might work for a non-constant -// mask M, and because the AddX operands can come in either -// order, we check for every operand order. -Node* MulNode::AndIL_add_shift_and_mask(PhaseGVN* phase, BasicType bt) { +// Reduces the pattern: +// (AndX (AddX add1 add2) mask) +// to +// (AndX add1 mask), if add2 is neutral wrt mask (see above), and vice versa. +Node* MulNode::AndIL_sum_and_mask(PhaseGVN* phase, BasicType bt) { Node* add = in(1); Node* mask = in(2); - if (add == nullptr || mask == nullptr) { - return nullptr; - } int addidx = 0; if (add->Opcode() == Op_Add(bt)) { addidx = 1; @@ -2156,14 +2212,12 @@ Node* MulNode::AndIL_add_shift_and_mask(PhaseGVN* phase, BasicType bt) { if (addidx > 0) { Node* add1 = add->in(1); Node* add2 = add->in(2); - if (add1 != nullptr && add2 != nullptr) { - if (AndIL_shift_and_mask_is_always_zero(phase, add1, mask, bt, false)) { - set_req_X(addidx, add2, phase); - return this; - } else if (AndIL_shift_and_mask_is_always_zero(phase, add2, mask, bt, false)) { - set_req_X(addidx, add1, phase); - return this; - } + if (AndIL_is_zero_element_under_mask(phase, add1, mask, bt)) { + set_req_X(addidx, add2, phase); + return this; + } else if (AndIL_is_zero_element_under_mask(phase, add2, mask, bt)) { + set_req_X(addidx, add1, phase); + return this; } } return nullptr; diff --git a/src/hotspot/share/opto/mulnode.hpp b/src/hotspot/share/opto/mulnode.hpp index c8d168685d9e5..65a2cd112ec23 100644 --- a/src/hotspot/share/opto/mulnode.hpp +++ b/src/hotspot/share/opto/mulnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,8 +83,8 @@ class MulNode : public Node { static MulNode* make(Node* in1, Node* in2, BasicType bt); - static bool AndIL_shift_and_mask_is_always_zero(PhaseGVN* phase, Node* shift, Node* mask, BasicType bt, bool check_reverse); - Node* AndIL_add_shift_and_mask(PhaseGVN* phase, BasicType bt); +protected: + Node* AndIL_sum_and_mask(PhaseGVN* phase, BasicType bt); }; //------------------------------MulINode--------------------------------------- @@ -143,6 +143,24 @@ class MulFNode : public MulNode { virtual uint ideal_reg() const { return Op_RegF; } }; +//------------------------------MulHFNode--------------------------------------- +// Multiply 2 half floats +class MulHFNode : public MulNode { +public: + MulHFNode(Node* in1, Node* in2) : MulNode(in1, in2) {} + virtual int Opcode() const; + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); + virtual const Type* mul_ring(const Type*, const Type*) const; + const Type* mul_id() const { return TypeH::ONE; } + const Type* add_id() const { return TypeH::ZERO; } + int add_opcode() const { return Op_AddHF; } + int mul_opcode() const { return Op_MulHF; } + int max_opcode() const { return Op_MaxHF; } + int min_opcode() const { return Op_MinHF; } + const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } +}; + //------------------------------MulDNode--------------------------------------- // Multiply 2 doubles class MulDNode : public MulNode { @@ -388,7 +406,7 @@ inline Node* make_urshift(Node* a, Node* b) { // fused-multiply-add class FmaNode : public Node { public: - FmaNode(Node* c, Node* in1, Node* in2, Node* in3) : Node(c, in1, in2, in3) { + FmaNode(Node* in1, Node* in2, Node* in3) : Node(nullptr, in1, in2, in3) { assert(UseFMA, "Needs FMA instructions support."); } virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); @@ -398,7 +416,7 @@ class FmaNode : public Node { // fused-multiply-add double class FmaDNode : public FmaNode { public: - FmaDNode(Node* c, Node* in1, Node* in2, Node* in3) : FmaNode(c, in1, in2, in3) {} + FmaDNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {} virtual int Opcode() const; const Type* bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -409,13 +427,24 @@ class FmaDNode : public FmaNode { // fused-multiply-add float class FmaFNode : public FmaNode { public: - FmaFNode(Node* c, Node* in1, Node* in2, Node* in3) : FmaNode(c, in1, in2, in3) {} + FmaFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {} virtual int Opcode() const; const Type* bottom_type() const { return Type::FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } virtual const Type* Value(PhaseGVN* phase) const; }; +//------------------------------FmaHFNode------------------------------------- +// fused-multiply-add half-precision float +class FmaHFNode : public FmaNode { +public: + FmaHFNode(Node* in1, Node* in2, Node* in3) : FmaNode(in1, in2, in3) {} + virtual int Opcode() const; + const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + virtual const Type* Value(PhaseGVN* phase) const; +}; + //------------------------------MulAddS2INode---------------------------------- // Multiply shorts into integers and add them. // Semantics: I_OUT = S1 * S2 + S3 * S4 diff --git a/src/hotspot/share/opto/multnode.cpp b/src/hotspot/share/opto/multnode.cpp index 904c9470b6d18..736e84315eee1 100644 --- a/src/hotspot/share/opto/multnode.cpp +++ b/src/hotspot/share/opto/multnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/callnode.hpp" #include "opto/cfgnode.hpp" #include "opto/matcher.hpp" diff --git a/src/hotspot/share/opto/narrowptrnode.cpp b/src/hotspot/share/opto/narrowptrnode.cpp index 412ecae69c5f0..7f86b8caecf9f 100644 --- a/src/hotspot/share/opto/narrowptrnode.cpp +++ b/src/hotspot/share/opto/narrowptrnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/narrowptrnode.hpp" #include "opto/phaseX.hpp" diff --git a/src/hotspot/share/opto/noOverflowInt.hpp b/src/hotspot/share/opto/noOverflowInt.hpp index 9da24645b4117..96473407cca11 100644 --- a/src/hotspot/share/opto/noOverflowInt.hpp +++ b/src/hotspot/share/opto/noOverflowInt.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,7 @@ class NoOverflowInt { bool is_NaN() const { return _is_NaN; } jint value() const { assert(!is_NaN(), "NaN not allowed"); return _value; } bool is_zero() const { return !is_NaN() && value() == 0; } + bool is_one() const { return !is_NaN() && value() == 1; } friend NoOverflowInt operator+(const NoOverflowInt& a, const NoOverflowInt& b) { if (a.is_NaN()) { return a; } @@ -100,6 +101,23 @@ class NoOverflowInt { return a.value() % b.value() == 0; } + // This "cmp" is used for sort only. + // Note: the NaN semantics are different from floating arithmetic NaNs! + // - Smaller non-NaN are before larger non-NaN. + // - Any non-NaN are before NaN. + // - NaN is equal to NaN. + // Note: NaN indicate overflow, uninitialized, etc. + static int cmp(const NoOverflowInt& a, const NoOverflowInt& b) { + if (a.is_NaN()) { + return b.is_NaN() ? 0 : 1; + } else if (b.is_NaN()) { + return -1; + } + if (a.value() < b.value()) { return -1; } + if (a.value() > b.value()) { return 1; } + return 0; + } + #ifndef PRODUCT void print_on(outputStream* st) const { if (is_NaN()) { diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index cf371bb3fff36..0e2957ac66e88 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "libadt/vectset.hpp" @@ -548,10 +547,6 @@ Node *Node::clone() const { if (cg != nullptr) { CallGenerator* cloned_cg = cg->with_call_node(n->as_Call()); n->as_Call()->set_generator(cloned_cg); - - C->print_inlining_assert_ready(); - C->print_inlining_move_to(cg); - C->print_inlining_update(cloned_cg); } } if (n->is_SafePoint()) { @@ -1596,6 +1591,13 @@ jfloat Node::getf() const { return ((ConFNode*)this)->type()->is_float_constant()->getf(); } +// Get a half float constant from a ConstNode. +// Returns the constant if it is a float ConstNode +jshort Node::geth() const { + assert( Opcode() == Op_ConH, "" ); + return ((ConHNode*)this)->type()->is_half_float_constant()->geth(); +} + #ifndef PRODUCT // Call this from debugger: @@ -2423,9 +2425,9 @@ void Node::dump_idx(bool align, outputStream* st, DumpConfig* dc) const { bool is_new = C->node_arena()->contains(this); if (align) { // print prefix empty spaces$ // +1 for leading digit, +1 for "o" - uint max_width = static_cast(log10(static_cast(C->unique()))) + 2; + uint max_width = (C->unique() == 0 ? 0 : static_cast(log10(static_cast(C->unique())))) + 2; // +1 for leading digit, maybe +1 for "o" - uint width = static_cast(log10(static_cast(_idx))) + 1 + (is_new ? 0 : 1); + uint width = (_idx == 0 ? 0 : static_cast(log10(static_cast(_idx)))) + 1 + (is_new ? 0 : 1); while (max_width > width) { st->print(" "); width++; @@ -2894,6 +2896,15 @@ void Node::ensure_control_or_add_prec(Node* c) { } } +void Node::add_prec_from(Node* n) { + for (uint i = n->req(); i < n->len(); i++) { + Node* prec = n->in(i); + if (prec != nullptr) { + add_prec(prec); + } + } +} + bool Node::is_dead_loop_safe() const { if (is_Phi()) { return true; @@ -2917,6 +2928,9 @@ bool Node::is_dead_loop_safe() const { return false; } +bool Node::is_div_or_mod(BasicType bt) const { return Opcode() == Op_Div(bt) || Opcode() == Op_Mod(bt) || + Opcode() == Op_UDiv(bt) || Opcode() == Op_UMod(bt); } + //============================================================================= //------------------------------yank------------------------------------------- // Find and remove diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 8ff778ed49300..2e52c12e4e829 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2024, Alibaba Group Holding Limited. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Alibaba Group Holding Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,7 @@ class CallNode; class CallRuntimeNode; class CallStaticJavaNode; class CastFFNode; +class CastHHNode; class CastDDNode; class CastVVNode; class CastIINode; @@ -336,16 +337,14 @@ class Node { void out_grow( uint len ); public: - // Each Node is assigned a unique small/dense number. This number is used + // Each Node is assigned a unique small/dense number. This number is used // to index into auxiliary arrays of data and bit vectors. - // The field _idx is declared constant to defend against inadvertent assignments, - // since it is used by clients as a naked field. However, the field's value can be - // changed using the set_idx() method. + // The value of _idx can be changed using the set_idx() method. // // The PhaseRenumberLive phase renumbers nodes based on liveness information. // Therefore, it updates the value of the _idx field. The parse-time _idx is // preserved in _parse_idx. - const node_idx_t _idx; + node_idx_t _idx; DEBUG_ONLY(const node_idx_t _parse_idx;) // IGV node identifier. Two nodes, possibly in different compilation phases, // have the same IGV identifier if (and only if) they are the very same node @@ -586,8 +585,7 @@ class Node { // Set this node's index, used by cisc_version to replace current node void set_idx(uint new_idx) { - const node_idx_t* ref = &_idx; - *(node_idx_t*)ref = new_idx; + _idx = new_idx; } // Swap input edge order. (Edge indexes i1 and i2 are usually 1 and 2.) void swap_edges(uint i1, uint i2) { @@ -725,6 +723,7 @@ class Node { DEFINE_CLASS_ID(CastDD, ConstraintCast, 4) DEFINE_CLASS_ID(CastVV, ConstraintCast, 5) DEFINE_CLASS_ID(CastPP, ConstraintCast, 6) + DEFINE_CLASS_ID(CastHH, ConstraintCast, 7) DEFINE_CLASS_ID(CMove, Type, 3) DEFINE_CLASS_ID(SafePointScalarObject, Type, 4) DEFINE_CLASS_ID(DecodeNarrowPtr, Type, 5) @@ -909,6 +908,7 @@ class Node { DEFINE_CLASS_QUERY(CheckCastPP) DEFINE_CLASS_QUERY(CastII) DEFINE_CLASS_QUERY(CastLL) + DEFINE_CLASS_QUERY(CastFF) DEFINE_CLASS_QUERY(ConI) DEFINE_CLASS_QUERY(CastPP) DEFINE_CLASS_QUERY(ConstraintCast) @@ -1166,6 +1166,7 @@ class Node { // Set control or add control as precedence edge void ensure_control_or_add_prec(Node* c); + void add_prec_from(Node* n); // Visit boundary uses of the node and apply a callback function for each. // Recursively traverse uses, stopping and applying the callback when @@ -1256,6 +1257,7 @@ class Node { intptr_t get_narrowcon() const; jdouble getd() const; jfloat getf() const; + jshort geth() const; // Nodes which are pinned into basic blocks virtual bool pinned() const { return false; } @@ -1277,6 +1279,8 @@ class Node { // Whether this is a memory phi node bool is_memory_phi() const { return is_Phi() && bottom_type() == Type::MEMORY; } + bool is_div_or_mod(BasicType bt) const; + //----------------- Printing, etc #ifndef PRODUCT public: @@ -2060,6 +2064,10 @@ Op_IL(URShift) Op_IL(LShift) Op_IL(Xor) Op_IL(Cmp) +Op_IL(Div) +Op_IL(Mod) +Op_IL(UDiv) +Op_IL(UMod) inline int Op_ConIL(BasicType bt) { assert(bt == T_INT || bt == T_LONG, "only for int or longs"); diff --git a/src/hotspot/share/opto/opaquenode.cpp b/src/hotspot/share/opto/opaquenode.cpp index 8a8eea51db6d0..672ea13e507df 100644 --- a/src/hotspot/share/opto/opaquenode.cpp +++ b/src/hotspot/share/opto/opaquenode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ * */ -#include "precompiled.hpp" +#include "opto/connode.hpp" #include "opto/loopnode.hpp" #include "opto/opaquenode.hpp" #include "opto/phaseX.hpp" diff --git a/src/hotspot/share/opto/opcodes.cpp b/src/hotspot/share/opto/opcodes.cpp index 3298ec9770322..b8dff8d93aae2 100644 --- a/src/hotspot/share/opto/opcodes.cpp +++ b/src/hotspot/share/opto/opcodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -// no precompiled headers // ---------------------------------------------------------------------------- // Build a table of class names as strings. Used both for debugging printouts diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index eb91ff7ea64aa..da58f33367663 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "asm/assembler.inline.hpp" #include "code/compiledIC.hpp" #include "code/debugInfo.hpp" diff --git a/src/hotspot/share/opto/parse.hpp b/src/hotspot/share/opto/parse.hpp index 039283bc863d1..83b211828ce5c 100644 --- a/src/hotspot/share/opto/parse.hpp +++ b/src/hotspot/share/opto/parse.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ class InlineTree : public AnyObj { bool& should_delay); bool should_inline(ciMethod* callee_method, ciMethod* caller_method, - int caller_bci, + JVMState* caller_jvms, bool& should_delay, ciCallProfile& profile); bool should_not_inline(ciMethod* callee_method, @@ -87,8 +87,7 @@ class InlineTree : public AnyObj { ciMethod* caller_method, int caller_bci, ciCallProfile& profile); - void print_inlining(ciMethod* callee_method, int caller_bci, - ciMethod* caller_method, bool success) const; + void print_inlining(ciMethod* callee_method, JVMState* jvm, bool success) const; InlineTree* caller_tree() const { return _caller_tree; } InlineTree* callee_at(int bci, ciMethod* m) const; @@ -530,8 +529,7 @@ class Parse : public GraphKit { void do_instanceof(); // Helper functions for shifting & arithmetic - void modf(); - void modd(); + Node* floating_point_mod(Node* a, Node* b, BasicType type); void l2f(); // implementation of _get* and _put* bytecodes diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp index 68b87d858a5bc..f7330d10df3a7 100644 --- a/src/hotspot/share/opto/parse1.cpp +++ b/src/hotspot/share/opto/parse1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "interpreter/linkResolver.hpp" #include "memory/resourceArea.hpp" @@ -642,7 +641,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses) // for exiting control flow still refers to the inlined method. C->set_default_node_notes(caller_nn); - if (log) log->done("parse nodes='%d' live='%d' memory='" SIZE_FORMAT "'", + if (log) log->done("parse nodes='%d' live='%d' memory='%zu'", C->unique(), C->live_nodes(), C->node_arena()->used()); } @@ -2121,7 +2120,7 @@ void Parse::call_register_finalizer() { // finalization. In general this will fold up since the concrete // class is often visible so the access flags are constant. Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() ); - Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), klass_addr, TypeInstPtr::KLASS)); + Node* klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS)); Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::misc_flags_offset())); Node* access_flags = make_load(nullptr, access_flags_addr, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered); diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 73cf923480822..6257a6b872d42 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileLog.hpp" @@ -1096,33 +1095,16 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, #endif } -void Parse::modf() { - Node *f2 = pop(); - Node *f1 = pop(); - Node* c = make_runtime_call(RC_LEAF, OptoRuntime::modf_Type(), - CAST_FROM_FN_PTR(address, SharedRuntime::frem), - "frem", nullptr, //no memory effects - f1, f2); - Node* res = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 0)); - - push(res); -} +Node* Parse::floating_point_mod(Node* a, Node* b, BasicType type) { + assert(type == BasicType::T_FLOAT || type == BasicType::T_DOUBLE, "only float and double are floating points"); + CallNode* mod = type == BasicType::T_DOUBLE ? static_cast(new ModDNode(C, a, b)) : new ModFNode(C, a, b); -void Parse::modd() { - Node *d2 = pop_pair(); - Node *d1 = pop_pair(); - Node* c = make_runtime_call(RC_LEAF, OptoRuntime::Math_DD_D_Type(), - CAST_FROM_FN_PTR(address, SharedRuntime::drem), - "drem", nullptr, //no memory effects - d1, top(), d2, top()); - Node* res_d = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 0)); - -#ifdef ASSERT - Node* res_top = _gvn.transform(new ProjNode(c, TypeFunc::Parms + 1)); - assert(res_top == top(), "second value must be top"); -#endif - - push_pair(res_d); + Node* prev_mem = set_predefined_input_for_runtime_call(mod); + mod = _gvn.transform(mod)->as_Call(); + set_predefined_output_for_runtime_call(mod, prev_mem, TypeRawPtr::BOTTOM); + Node* result = _gvn.transform(new ProjNode(mod, TypeFunc::Parms + 0)); + record_for_igvn(mod); + return result; } void Parse::l2f() { @@ -2303,18 +2285,10 @@ void Parse::do_one_bytecode() { break; case Bytecodes::_frem: - if (Matcher::has_match_rule(Op_ModF)) { - // Generate a ModF node. - b = pop(); - a = pop(); - c = _gvn.transform( new ModFNode(nullptr,a,b) ); - d = precision_rounding(c); - push( d ); - } - else { - // Generate a call. - modf(); - } + // Generate a ModF node. + b = pop(); + a = pop(); + push(floating_point_mod(a, b, BasicType::T_FLOAT)); break; case Bytecodes::_fcmpl: @@ -2436,20 +2410,10 @@ void Parse::do_one_bytecode() { break; case Bytecodes::_drem: - if (Matcher::has_match_rule(Op_ModD)) { - // Generate a ModD node. - b = pop_pair(); - a = pop_pair(); - // a % b - - c = _gvn.transform( new ModDNode(nullptr,a,b) ); - d = dprecision_rounding(c); - push_pair( d ); - } - else { - // Generate a call. - modd(); - } + // Generate a ModD node. + b = pop_pair(); + a = pop_pair(); + push_pair(floating_point_mod(a, b, BasicType::T_DOUBLE)); break; case Bytecodes::_dcmpl: diff --git a/src/hotspot/share/opto/parse3.cpp b/src/hotspot/share/opto/parse3.cpp index 93f5bd6c0d52b..d0e2e90ec6bd7 100644 --- a/src/hotspot/share/opto/parse3.cpp +++ b/src/hotspot/share/opto/parse3.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "interpreter/linkResolver.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/opto/parseHelper.cpp b/src/hotspot/share/opto/parseHelper.cpp index ba4cc612cc31d..1a1cea05454f6 100644 --- a/src/hotspot/share/opto/parseHelper.cpp +++ b/src/hotspot/share/opto/parseHelper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciSymbols.hpp" #include "compiler/compileLog.hpp" #include "oops/objArrayKlass.hpp" @@ -157,7 +156,7 @@ void Parse::array_store_check() { int klass_offset = oopDesc::klass_offset_in_bytes(); Node* p = basic_plus_adr( ary, ary, klass_offset ); // p's type is array-of-OOPS plus klass_offset - Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, nullptr, immutable_memory(), p, TypeInstPtr::KLASS)); + Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS)); // Get the array klass const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr(); @@ -165,11 +164,10 @@ void Parse::array_store_check() { // cast array_klass to EXACT array and uncommon-trap if the cast fails. // Make constant out of the inexact array klass, but use it only if the cast // succeeds. - bool always_see_exact_class = false; - if (MonomorphicArrayCheck - && !too_many_traps(Deoptimization::Reason_array_check) - && !tak->klass_is_exact() - && tak != TypeInstKlassPtr::OBJECT) { + if (MonomorphicArrayCheck && + !too_many_traps(Deoptimization::Reason_array_check) && + !tak->klass_is_exact() && + tak->isa_aryklassptr()) { // Regarding the fourth condition in the if-statement from above: // // If the compiler has determined that the type of array 'ary' (represented @@ -191,16 +189,12 @@ void Parse::array_store_check() { // // See issue JDK-8057622 for details. - always_see_exact_class = true; - // (If no MDO at all, hope for the best, until a trap actually occurs.) - - // Make a constant out of the inexact array klass - const TypeKlassPtr *extak = tak->cast_to_exactness(true); - + // Make a constant out of the exact array klass + const TypeAryKlassPtr* extak = tak->cast_to_exactness(true)->is_aryklassptr(); if (extak->exact_klass(true) != nullptr) { Node* con = makecon(extak); - Node* cmp = _gvn.transform(new CmpPNode( array_klass, con )); - Node* bol = _gvn.transform(new BoolNode( cmp, BoolTest::eq )); + Node* cmp = _gvn.transform(new CmpPNode(array_klass, con)); + Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq)); Node* ctrl= control(); { BuildCutout unless(this, bol, PROB_MAX); uncommon_trap(Deoptimization::Reason_array_check, @@ -211,7 +205,7 @@ void Parse::array_store_check() { set_control(ctrl); // Then Don't Do It, just fall into the normal checking } else { // Cast array klass to exactness: // Use the exact constant value we know it is. - replace_in_map(array_klass,con); + replace_in_map(array_klass, con); CompileLog* log = C->log(); if (log != nullptr) { log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'", @@ -226,12 +220,9 @@ void Parse::array_store_check() { // Extract the array element class int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset()); - Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); - // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true, - // we must set a control edge from the IfTrue node created by the uncommon_trap above to the - // LoadKlassNode. - Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : nullptr, - immutable_memory(), p2, tak)); + Node* p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); + Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p2, tak)); + assert(array_klass->is_Con() == a_e_klass->is_Con() || StressReflectiveCode, "a constant array type must come with a constant element type"); // Check (the hard way) and throw if not a subklass. // Result is ignored, we just need the CFG effects. diff --git a/src/hotspot/share/opto/phase.cpp b/src/hotspot/share/opto/phase.cpp index 3684918cea579..5603033ce69d8 100644 --- a/src/hotspot/share/opto/phase.cpp +++ b/src/hotspot/share/opto/phase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/nmethod.hpp" #include "compiler/compileBroker.hpp" #include "opto/compile.hpp" diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index dc4a27d8351fb..0dd2acd866477 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" #include "memory/allocation.inline.hpp" diff --git a/src/hotspot/share/opto/postaloc.cpp b/src/hotspot/share/opto/postaloc.cpp index c22d23bc1fcd1..7f4d2845792c9 100644 --- a/src/hotspot/share/opto/postaloc.cpp +++ b/src/hotspot/share/opto/postaloc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "opto/chaitin.hpp" diff --git a/src/hotspot/share/opto/predicates.cpp b/src/hotspot/share/opto/predicates.cpp index a9cd1e638c180..6badaa654877f 100644 --- a/src/hotspot/share/opto/predicates.cpp +++ b/src/hotspot/share/opto/predicates.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" #include "opto/castnode.hpp" @@ -70,7 +69,7 @@ bool AssertionPredicate::has_halt(const Node* success_proj) { } // Returns the Parse Predicate node if the provided node is a Parse Predicate success proj. Otherwise, return null. -ParsePredicateNode* ParsePredicate::init_parse_predicate(Node* parse_predicate_proj, +ParsePredicateNode* ParsePredicate::init_parse_predicate(const Node* parse_predicate_proj, Deoptimization::DeoptReason deopt_reason) { assert(parse_predicate_proj != nullptr, "must not be null"); if (parse_predicate_proj->is_IfTrue() && parse_predicate_proj->in(0)->is_ParsePredicate()) { @@ -82,7 +81,26 @@ ParsePredicateNode* ParsePredicate::init_parse_predicate(Node* parse_predicate_p return nullptr; } -Deoptimization::DeoptReason RuntimePredicate::uncommon_trap_reason(IfProjNode* if_proj) { +ParsePredicate ParsePredicate::clone_to_unswitched_loop(Node* new_control, const bool is_false_path_loop, + PhaseIdealLoop* phase) const { + ParsePredicateSuccessProj* success_proj = phase->create_new_if_for_predicate(_success_proj, new_control, + _parse_predicate_node->deopt_reason(), + Op_ParsePredicate, is_false_path_loop); + NOT_PRODUCT(trace_cloned_parse_predicate(is_false_path_loop, success_proj)); + return ParsePredicate(success_proj, _parse_predicate_node->deopt_reason()); +} + +#ifndef PRODUCT +void ParsePredicate::trace_cloned_parse_predicate(const bool is_false_path_loop, + const ParsePredicateSuccessProj* success_proj) { + if (TraceLoopPredicate) { + tty->print("Parse Predicate cloned to %s path loop: ", is_false_path_loop ? "false" : "true"); + success_proj->in(0)->dump(); + } +} +#endif // NOT PRODUCT + +Deoptimization::DeoptReason RuntimePredicate::uncommon_trap_reason(const IfProjNode* if_proj) { CallStaticJavaNode* uct_call = if_proj->is_uncommon_trap_if_pattern(); if (uct_call == nullptr) { return Deoptimization::Reason_none; @@ -90,7 +108,7 @@ Deoptimization::DeoptReason RuntimePredicate::uncommon_trap_reason(IfProjNode* i return Deoptimization::trap_request_reason(uct_call->uncommon_trap_request()); } -bool RuntimePredicate::is_predicate(Node* maybe_success_proj) { +bool RuntimePredicate::is_predicate(const Node* maybe_success_proj) { if (RegularPredicate::may_be_predicate_if(maybe_success_proj)) { return has_valid_uncommon_trap(maybe_success_proj); } else { @@ -132,10 +150,10 @@ bool RegularPredicate::may_be_predicate_if(const Node* node) { // Template Assertion Predicate) to the 'target_predicate' based on the 'data_in_loop_body' check. void TemplateAssertionPredicate::rewire_loop_data_dependencies(IfTrueNode* target_predicate, const NodeInLoopBody& data_in_loop_body, - PhaseIdealLoop* phase) const { + const PhaseIdealLoop* phase) const { for (DUIterator i = _success_proj->outs(); _success_proj->has_out(i); i++) { Node* output = _success_proj->out(i); - if (!output->is_CFG() && data_in_loop_body.check(output)) { + if (!output->is_CFG() && data_in_loop_body.check_node_in_loop_body(output)) { phase->igvn().replace_input_of(output, 0, target_predicate); --i; // account for the just deleted output } @@ -143,7 +161,7 @@ void TemplateAssertionPredicate::rewire_loop_data_dependencies(IfTrueNode* targe } // Template Assertion Predicates always have the dedicated OpaqueTemplateAssertionPredicate to identify them. -bool TemplateAssertionPredicate::is_predicate(Node* node) { +bool TemplateAssertionPredicate::is_predicate(const Node* node) { if (!may_be_assertion_predicate_if(node)) { return false; } @@ -151,8 +169,8 @@ bool TemplateAssertionPredicate::is_predicate(Node* node) { return if_node->in(1)->is_OpaqueTemplateAssertionPredicate(); } -// Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. -IfTrueNode* TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* phase) const { +// Clone this Template Assertion Predicate without modifying any OpaqueLoop*Node inputs. +TemplateAssertionPredicate TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* phase) const { DEBUG_ONLY(verify();) TemplateAssertionExpression template_assertion_expression(opaque_node()); OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone(new_control, phase); @@ -160,14 +178,18 @@ IfTrueNode* TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), new_opaque_node, _if_node->assertion_predicate_type()); - DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) - return success_proj; + TemplateAssertionPredicate cloned_template_assertion_predicate(success_proj); + DEBUG_ONLY(cloned_template_assertion_predicate.verify();) + return cloned_template_assertion_predicate; } -// Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. -IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, - PhaseIdealLoop* phase) const { +// Clone this Template Assertion Predicate and use a newly created OpaqueLoopInitNode with 'new_opaque_input' as input. +TemplateAssertionPredicate TemplateAssertionPredicate::clone_and_replace_opaque_input(Node* new_control, + Node* new_opaque_input, + PhaseIdealLoop* phase) const { DEBUG_ONLY(verify();) + OpaqueLoopInitNode* new_opaque_init = new OpaqueLoopInitNode(phase->C, new_opaque_input); + phase->register_new_node(new_opaque_init, new_control); TemplateAssertionExpression template_assertion_expression(opaque_node()); OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone_and_replace_init(new_control, new_opaque_init, phase); @@ -175,8 +197,9 @@ IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), new_opaque_node, _if_node->assertion_predicate_type()); - DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) - return success_proj; + TemplateAssertionPredicate cloned_template_assertion_predicate(success_proj); + DEBUG_ONLY(cloned_template_assertion_predicate.verify();) + return cloned_template_assertion_predicate; } // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. @@ -186,14 +209,20 @@ void TemplateAssertionPredicate::replace_opaque_stride_input(Node* new_stride, P expression.replace_opaque_stride_input(new_stride, igvn); } -// Create a new Initialized Assertion Predicate from this template at 'new_control' and return the success projection -// of the newly created Initialized Assertion Predicate. -IfTrueNode* TemplateAssertionPredicate::initialize(PhaseIdealLoop* phase, Node* new_control) const { +// Create a new Initialized Assertion Predicate from this template at the template success projection. +InitializedAssertionPredicate TemplateAssertionPredicate::initialize(PhaseIdealLoop* phase) const { DEBUG_ONLY(verify();) InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(phase); - IfTrueNode* success_proj = initialized_assertion_predicate_creator.create_from_template(head(), new_control); - DEBUG_ONLY(InitializedAssertionPredicate::verify(success_proj);) - return success_proj; + InitializedAssertionPredicate initialized_assertion_predicate = + initialized_assertion_predicate_creator.create_from_template_and_insert_below(*this); + DEBUG_ONLY(initialized_assertion_predicate.verify();) + return initialized_assertion_predicate; +} + +// Kills the Template Assertion Predicate by setting the condition to true. Will be folded away in the next IGVN round. +void TemplateAssertionPredicate::kill(PhaseIdealLoop* phase) const { + ConINode* true_con = phase->intcon(1); + phase->igvn().replace_input_of(_if_node, 1, true_con); } #ifdef ASSERT @@ -265,7 +294,7 @@ void InitializedAssertionPredicate::verify() const { // Initialized Assertion Predicates always have the dedicated OpaqueInitiailizedAssertionPredicate node to identify // them. -bool InitializedAssertionPredicate::is_predicate(Node* node) { +bool InitializedAssertionPredicate::is_predicate(const Node* node) { if (!may_be_assertion_predicate_if(node)) { return false; } @@ -281,7 +310,7 @@ void InitializedAssertionPredicate::kill(PhaseIdealLoop* phase) const { #ifdef ASSERT // Check that the block has at most one Parse Predicate and that we only find Regular Predicate nodes (i.e. IfProj, // If, or RangeCheck nodes). -void RegularPredicateBlock::verify_block(Node* tail) { +void RegularPredicateBlock::verify_block(Node* tail) const { Node* next = tail; while (next != _entry) { assert(!next->is_ParsePredicate(), "can only have one Parse Predicate in a block"); @@ -297,33 +326,33 @@ void RegularPredicateBlock::verify_block(Node* tail) { // This strategy clones the OpaqueLoopInit and OpaqueLoopStride nodes. class CloneStrategy : public TransformStrategyForOpaqueLoopNodes { PhaseIdealLoop* const _phase; - Node* const _new_ctrl; + Node* const _new_control; public: - CloneStrategy(PhaseIdealLoop* phase, Node* new_ctrl) + CloneStrategy(PhaseIdealLoop* phase, Node* new_control) : _phase(phase), - _new_ctrl(new_ctrl) {} + _new_control(new_control) {} NONCOPYABLE(CloneStrategy); Node* transform_opaque_init(OpaqueLoopInitNode* opaque_init) const override { - return _phase->clone_and_register(opaque_init, _new_ctrl)->as_OpaqueLoopInit(); + return _phase->clone_and_register(opaque_init, _new_control)->as_OpaqueLoopInit(); } Node* transform_opaque_stride(OpaqueLoopStrideNode* opaque_stride) const override { - return _phase->clone_and_register(opaque_stride, _new_ctrl)->as_OpaqueLoopStride(); + return _phase->clone_and_register(opaque_stride, _new_control)->as_OpaqueLoopStride(); } }; // This strategy replaces the OpaqueLoopInitNode with the provided init node and clones the OpaqueLoopStrideNode. class ReplaceInitAndCloneStrideStrategy : public TransformStrategyForOpaqueLoopNodes { Node* const _new_init; - Node* const _new_ctrl; + Node* const _new_control; PhaseIdealLoop* const _phase; public: - ReplaceInitAndCloneStrideStrategy(Node* new_init, Node* new_ctrl, PhaseIdealLoop* phase) + ReplaceInitAndCloneStrideStrategy(Node* new_control, Node* new_init, PhaseIdealLoop* phase) : _new_init(new_init), - _new_ctrl(new_ctrl), + _new_control(new_control), _phase(phase) {} NONCOPYABLE(ReplaceInitAndCloneStrideStrategy); @@ -332,7 +361,7 @@ class ReplaceInitAndCloneStrideStrategy : public TransformStrategyForOpaqueLoopN } Node* transform_opaque_stride(OpaqueLoopStrideNode* opaque_stride) const override { - return _phase->clone_and_register(opaque_stride, _new_ctrl)->as_OpaqueLoopStride(); + return _phase->clone_and_register(opaque_stride, _new_control)->as_OpaqueLoopStride(); } }; @@ -359,17 +388,17 @@ class ReplaceInitAndStrideStrategy : public TransformStrategyForOpaqueLoopNodes // Creates an identical clone of this Template Assertion Expression (i.e.cloning all nodes from the // OpaqueTemplateAssertionPredicate to and including the OpaqueLoop* nodes). The cloned nodes are rewired to reflect the -// same graph structure as found for this Template Assertion Expression. The cloned nodes get 'new_ctrl' as ctrl. There -// is no other update done for the cloned nodes. Return the newly cloned OpaqueTemplateAssertionPredicate. -OpaqueTemplateAssertionPredicateNode* TemplateAssertionExpression::clone(Node* new_control, PhaseIdealLoop* phase) { +// same graph structure as found for this Template Assertion Expression. The cloned nodes get 'new_control' as control. +// There is no other update done for the cloned nodes. Return the newly cloned OpaqueTemplateAssertionPredicate. +OpaqueTemplateAssertionPredicateNode* TemplateAssertionExpression::clone(Node* new_control, PhaseIdealLoop* phase) const { CloneStrategy clone_init_and_stride_strategy(phase, new_control); return clone(clone_init_and_stride_strategy, new_control, phase); } // Same as clone() but instead of cloning the OpaqueLoopInitNode, we replace it with the provided 'new_init' node. OpaqueTemplateAssertionPredicateNode* -TemplateAssertionExpression::clone_and_replace_init(Node* new_control, Node* new_init, PhaseIdealLoop* phase) { - ReplaceInitAndCloneStrideStrategy replace_init_and_clone_stride_strategy(new_init, new_control, phase); +TemplateAssertionExpression::clone_and_replace_init(Node* new_control, Node* new_init, PhaseIdealLoop* phase) const { + ReplaceInitAndCloneStrideStrategy replace_init_and_clone_stride_strategy(new_control, new_init, phase); return clone(replace_init_and_clone_stride_strategy, new_control, phase); } @@ -377,7 +406,7 @@ TemplateAssertionExpression::clone_and_replace_init(Node* new_control, Node* new // 'new_init' and 'new_stride' nodes, respectively. OpaqueTemplateAssertionPredicateNode* TemplateAssertionExpression::clone_and_replace_init_and_stride(Node* new_control, Node* new_init, Node* new_stride, - PhaseIdealLoop* phase) { + PhaseIdealLoop* phase) const { ReplaceInitAndStrideStrategy replace_init_and_stride_strategy(new_init, new_stride); return clone(replace_init_and_stride_strategy, new_control, phase); } @@ -461,8 +490,8 @@ class DataNodesOnPathsToTargets : public StackObj { // Clones this Template Assertion Expression and applies the given strategy to transform the OpaqueLoop* nodes. OpaqueTemplateAssertionPredicateNode* -TemplateAssertionExpression::clone(const TransformStrategyForOpaqueLoopNodes& transform_strategy, Node* new_ctrl, - PhaseIdealLoop* phase) { +TemplateAssertionExpression::clone(const TransformStrategyForOpaqueLoopNodes& transform_strategy, Node* new_control, + PhaseIdealLoop* phase) const { ResourceMark rm; auto is_opaque_loop_node = [](const Node* node) { return node->is_Opaque1(); @@ -471,7 +500,8 @@ TemplateAssertionExpression::clone(const TransformStrategyForOpaqueLoopNodes& tr is_opaque_loop_node); const Unique_Node_List& collected_nodes = data_nodes_on_path_to_targets.collect(_opaque_node); DataNodeGraph data_node_graph(collected_nodes, phase); - const OrigToNewHashtable& orig_to_new = data_node_graph.clone_with_opaque_loop_transform_strategy(transform_strategy, new_ctrl); + const OrigToNewHashtable& orig_to_new = data_node_graph.clone_with_opaque_loop_transform_strategy(transform_strategy, + new_control); assert(orig_to_new.contains(_opaque_node), "must exist"); Node* opaque_node_clone = *orig_to_new.get(_opaque_node); return opaque_node_clone->as_OpaqueTemplateAssertionPredicate(); @@ -508,7 +538,7 @@ class ReplaceOpaqueStrideInput : public BFSActions { }; // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. -void TemplateAssertionExpression::replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) { +void TemplateAssertionExpression::replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const { ReplaceOpaqueStrideInput replace_opaque_stride_input(new_stride, igvn); replace_opaque_stride_input.replace_for(_opaque_node); } @@ -526,7 +556,7 @@ class RemoveOpaqueLoopNodesStrategy : public TransformStrategyForOpaqueLoopNodes }; OpaqueInitializedAssertionPredicateNode* -TemplateAssertionExpression::clone_and_fold_opaque_loop_nodes(Node* new_control, PhaseIdealLoop* phase) { +TemplateAssertionExpression::clone_and_fold_opaque_loop_nodes(Node* new_control, PhaseIdealLoop* phase) const { RemoveOpaqueLoopNodesStrategy remove_opaque_loop_nodes_strategy; OpaqueTemplateAssertionPredicateNode* cloned_template_opaque = clone(remove_opaque_loop_nodes_strategy, new_control, phase); @@ -554,7 +584,7 @@ bool TemplateAssertionExpressionNode::is_in_expression(Node* node) { return false; } -bool TemplateAssertionExpressionNode::is_template_assertion_predicate(Node* node) { +bool TemplateAssertionExpressionNode::is_template_assertion_predicate(const Node* node) { return node->is_If() && node->in(1)->is_OpaqueTemplateAssertionPredicate(); } @@ -615,7 +645,7 @@ class AssertionPredicateExpressionCreator : public StackObj { // create_for_initialized() is that we use a template specific Halt message on the fail path. IfTrueNode* AssertionPredicateIfCreator::create_for_template(Node* new_control, const int if_opcode, Node* assertion_expression, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { const char* halt_message = "Template Assertion Predicates are always removed before code generation"; return create(new_control, if_opcode, assertion_expression, halt_message, assertion_predicate_type); } @@ -624,7 +654,7 @@ IfTrueNode* AssertionPredicateIfCreator::create_for_template(Node* new_control, // create_for_template() is that we use a initialized specific Halt message on the fail path. IfTrueNode* AssertionPredicateIfCreator::create_for_initialized(Node* new_control, const int if_opcode, Node* assertion_expression, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { const char* halt_message = "Initialized Assertion Predicate cannot fail"; return create(new_control, if_opcode, assertion_expression, halt_message, assertion_predicate_type); } @@ -640,7 +670,7 @@ IfTrueNode* AssertionPredicateIfCreator::create_for_initialized(Node* new_contro // IfTrueNode* AssertionPredicateIfCreator::create(Node* new_control, const int if_opcode, Node* assertion_expression, const char* halt_message, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { assert(assertion_expression->is_OpaqueTemplateAssertionPredicate() || assertion_expression->is_OpaqueInitializedAssertionPredicate(), "not a valid assertion expression"); IdealLoopTree* loop = _phase->get_loop(new_control); @@ -651,7 +681,7 @@ IfTrueNode* AssertionPredicateIfCreator::create(Node* new_control, const int if_ IfNode* AssertionPredicateIfCreator::create_if_node(Node* new_control, const int if_opcode, Node* assertion_expression, IdealLoopTree* loop, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { IfNode* if_node; if (if_opcode == Op_If) { if_node = new IfNode(new_control, assertion_expression, PROB_MAX, COUNT_UNKNOWN, assertion_predicate_type); @@ -663,20 +693,20 @@ IfNode* AssertionPredicateIfCreator::create_if_node(Node* new_control, const int return if_node; } -IfTrueNode* AssertionPredicateIfCreator::create_success_path(IfNode* if_node, IdealLoopTree* loop) { +IfTrueNode* AssertionPredicateIfCreator::create_success_path(IfNode* if_node, IdealLoopTree* loop) const { IfTrueNode* success_proj = new IfTrueNode(if_node); _phase->register_control(success_proj, loop, if_node); return success_proj; } -void AssertionPredicateIfCreator::create_fail_path(IfNode* if_node, IdealLoopTree* loop, const char* halt_message) { +void AssertionPredicateIfCreator::create_fail_path(IfNode* if_node, IdealLoopTree* loop, const char* halt_message) const { IfFalseNode* fail_proj = new IfFalseNode(if_node); _phase->register_control(fail_proj, loop, if_node); create_halt_node(fail_proj, loop, halt_message); } void AssertionPredicateIfCreator::create_halt_node(IfFalseNode* fail_proj, IdealLoopTree* loop, - const char* halt_message) { + const char* halt_message) const { StartNode* start_node = _phase->C->start(); Node* frame = new ParmNode(start_node, TypeFunc::FramePtr); _phase->register_new_node(frame, start_node); @@ -685,7 +715,7 @@ void AssertionPredicateIfCreator::create_halt_node(IfFalseNode* fail_proj, Ideal _phase->register_control(halt, loop, fail_proj); } -OpaqueLoopInitNode* TemplateAssertionPredicateCreator::create_opaque_init(Node* new_control) { +OpaqueLoopInitNode* TemplateAssertionPredicateCreator::create_opaque_init(Node* new_control) const { OpaqueLoopInitNode* opaque_init = new OpaqueLoopInitNode(_phase->C, _loop_head->init_trip()); _phase->register_new_node(opaque_init, new_control); return opaque_init; @@ -722,7 +752,7 @@ Node* TemplateAssertionPredicateCreator::create_last_value(Node* new_control, Op IfTrueNode* TemplateAssertionPredicateCreator::create_if_node( Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression, - const bool does_overflow, const AssertionPredicateType assertion_predicate_type) { + const bool does_overflow, const AssertionPredicateType assertion_predicate_type) const { AssertionPredicateIfCreator assertion_predicate_if_creator(_phase); return assertion_predicate_if_creator.create_for_template(new_control, does_overflow ? Op_If : Op_RangeCheck, template_assertion_predicate_expression, @@ -731,7 +761,7 @@ IfTrueNode* TemplateAssertionPredicateCreator::create_if_node( // Creates an init and last value Template Assertion Predicate connected together with a Halt node on the failing path. // Returns the success projection of the last value Template Assertion Predicate latter. -IfTrueNode* TemplateAssertionPredicateCreator::create(Node* new_control) { +IfTrueNode* TemplateAssertionPredicateCreator::create(Node* new_control) const { OpaqueLoopInitNode* opaque_init = create_opaque_init(new_control); bool does_overflow; OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression = @@ -756,7 +786,7 @@ InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(Phase // Create an Initialized Assertion Predicate from the provided template_assertion_predicate at 'new_control'. // We clone the Template Assertion Expression and replace: // - OpaqueTemplateAssertionPredicateNode with OpaqueInitializedAssertionPredicate -// - OpaqueLoop*Nodes with new_init and _ew_stride, respectively. +// - OpaqueLoop*Nodes with new_init and new_stride, respectively. // // / init stride // | | | @@ -773,32 +803,38 @@ InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(Phase // success fail path new success new Halt // proj (Halt or UCT) proj // -IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* template_assertion_predicate, - Node* new_control, Node* new_init, - Node* new_stride) { +InitializedAssertionPredicate InitializedAssertionPredicateCreator::create_from_template( + const IfNode* template_assertion_predicate, Node* new_control, Node* new_init, Node* new_stride) const { OpaqueInitializedAssertionPredicateNode* assertion_expression = create_assertion_expression_from_template(template_assertion_predicate, new_control, new_init, new_stride); - return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression, - template_assertion_predicate->assertion_predicate_type()); + IfTrueNode* success_proj = create_control_nodes(new_control, + template_assertion_predicate->Opcode(), + assertion_expression, + template_assertion_predicate->assertion_predicate_type()); + return InitializedAssertionPredicate(success_proj); } -// Create a new Initialized Assertion Predicate from 'template_assertion_predicate' by cloning it but omitting the -// OpaqueLoop*Notes (i.e. taking their inputs instead). -IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* template_assertion_predicate, - Node* new_control) { - OpaqueTemplateAssertionPredicateNode* template_opaque = - template_assertion_predicate->in(1)->as_OpaqueTemplateAssertionPredicate(); - TemplateAssertionExpression template_assertion_expression(template_opaque); +// Create a new Initialized Assertion Predicate from the provided Template Assertion Predicate at the template success +// projection by cloning it but omitting the OpaqueLoop*Notes (i.e. taking their inputs instead). +InitializedAssertionPredicate InitializedAssertionPredicateCreator::create_from_template_and_insert_below( + const TemplateAssertionPredicate& template_assertion_predicate) const { + TemplateAssertionExpression template_assertion_expression(template_assertion_predicate.opaque_node()); + IfTrueNode* template_assertion_predicate_success_proj = template_assertion_predicate.tail(); OpaqueInitializedAssertionPredicateNode* assertion_expression = - template_assertion_expression.clone_and_fold_opaque_loop_nodes(new_control, _phase); - return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression, - template_assertion_predicate->assertion_predicate_type()); + template_assertion_expression.clone_and_fold_opaque_loop_nodes(template_assertion_predicate_success_proj, _phase); + + IfNode* template_assertion_predicate_if = template_assertion_predicate.head(); + AssertionPredicateType assertion_predicate_type = template_assertion_predicate_if->assertion_predicate_type(); + int if_opcode = template_assertion_predicate_if->Opcode(); + IfTrueNode* success_proj = create_control_nodes(template_assertion_predicate_success_proj, if_opcode, + assertion_expression, assertion_predicate_type); + return InitializedAssertionPredicate(success_proj); } // Create a new Initialized Assertion Predicate directly without a template. IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* new_control, const jint stride, const int scale, Node* offset, Node* range, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { AssertionPredicateExpressionCreator expression_creator(stride, scale, offset, range, _phase); bool does_overflow; OpaqueInitializedAssertionPredicateNode* assertion_expression = @@ -812,7 +848,7 @@ IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* ne // Creates the CFG nodes for the Initialized Assertion Predicate. IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes( Node* new_control, const int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression, - const AssertionPredicateType assertion_predicate_type) { + const AssertionPredicateType assertion_predicate_type) const { AssertionPredicateIfCreator assertion_predicate_if_creator(_phase); return assertion_predicate_if_creator.create_for_initialized(new_control, if_opcode, assertion_expression, assertion_predicate_type); @@ -821,9 +857,9 @@ IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes( // Create a new Assertion Expression based from the given template to be used as bool input for the Initialized // Assertion Predicate IfNode. OpaqueInitializedAssertionPredicateNode* -InitializedAssertionPredicateCreator::create_assertion_expression_from_template(IfNode* template_assertion_predicate, +InitializedAssertionPredicateCreator::create_assertion_expression_from_template(const IfNode* template_assertion_predicate, Node* new_control, Node* new_init, - Node* new_stride) { + Node* new_stride) const { OpaqueTemplateAssertionPredicateNode* template_opaque = template_assertion_predicate->in(1)->as_OpaqueTemplateAssertionPredicate(); TemplateAssertionExpression template_assertion_expression(template_opaque); @@ -907,36 +943,39 @@ void CreateAssertionPredicatesVisitor::visit(const TemplateAssertionPredicate& t return; } if (_clone_template) { - IfTrueNode* cloned_template_success_proj = clone_template_and_replace_init_input(template_assertion_predicate); - initialize_from_template(template_assertion_predicate, cloned_template_success_proj); - _current_predicate_chain_head = cloned_template_success_proj->in(0); + TemplateAssertionPredicate cloned_template_assertion_predicate = + clone_template_and_replace_init_input(template_assertion_predicate); + initialize_from_template(template_assertion_predicate, cloned_template_assertion_predicate.tail()); + _current_predicate_chain_head = cloned_template_assertion_predicate.head(); } else { - IfTrueNode* initialized_success_proj = initialize_from_template(template_assertion_predicate, _old_target_loop_entry); - _current_predicate_chain_head = initialized_success_proj->in(0); + InitializedAssertionPredicate initialized_assertion_predicate = + initialize_from_template(template_assertion_predicate, _old_target_loop_entry); + _current_predicate_chain_head = initialized_assertion_predicate.head(); } } // Create an Initialized Assertion Predicate from the provided Template Assertion Predicate. -IfTrueNode* CreateAssertionPredicatesVisitor::initialize_from_template( +InitializedAssertionPredicate CreateAssertionPredicatesVisitor::initialize_from_template( const TemplateAssertionPredicate& template_assertion_predicate, Node* new_control) const { DEBUG_ONLY(template_assertion_predicate.verify();) IfNode* template_head = template_assertion_predicate.head(); InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(_phase); - IfTrueNode* initialized_predicate = initialized_assertion_predicate_creator.create_from_template(template_head, - new_control, - _init, _stride); - DEBUG_ONLY(InitializedAssertionPredicate::verify(initialized_predicate);) - template_assertion_predicate.rewire_loop_data_dependencies(initialized_predicate, _node_in_loop_body, _phase); - rewire_to_old_predicate_chain_head(initialized_predicate); - return initialized_predicate; + InitializedAssertionPredicate initialized_assertion_predicate = + initialized_assertion_predicate_creator.create_from_template(template_head, new_control, _init, _stride); + + DEBUG_ONLY(initialized_assertion_predicate.verify();) + template_assertion_predicate.rewire_loop_data_dependencies(initialized_assertion_predicate.tail(), + _node_in_loop_body, _phase); + rewire_to_old_predicate_chain_head(initialized_assertion_predicate.tail()); + return initialized_assertion_predicate; } -// Clone the provided 'template_assertion_predicate' and set '_init' as new input for the OpaqueLoopInitNode. -IfTrueNode* CreateAssertionPredicatesVisitor::clone_template_and_replace_init_input( - const TemplateAssertionPredicate& template_assertion_predicate) { - OpaqueLoopInitNode* opaque_init = new OpaqueLoopInitNode(_phase->C, _init); - _phase->register_new_node(opaque_init, _old_target_loop_entry); - return template_assertion_predicate.clone_and_replace_init(_old_target_loop_entry, opaque_init, _phase); +// Clone the provided Template Assertion Predicate and set '_init' as new input for the OpaqueLoopInitNode. +TemplateAssertionPredicate CreateAssertionPredicatesVisitor::clone_template_and_replace_init_input( + const TemplateAssertionPredicate& template_assertion_predicate) const { + TemplateAssertionPredicate new_template = + template_assertion_predicate.clone_and_replace_opaque_input(_old_target_loop_entry, _init, _phase); + return new_template; } // Rewire the newly created predicates to the old predicate chain head (i.e. '_current_predicate_chain_head') by @@ -947,8 +986,8 @@ IfTrueNode* CreateAssertionPredicatesVisitor::clone_template_and_replace_init_in // x // | old target // Template Assertion loop entry -// Predicate 1 old target clone | \ -// | loop entry TAP 2 | cloned Template Assertion +// Predicate 1 old target clone | \ +// | loop entry TAP 2 | cloned Template Assertion // Template Assertion | ======> | Predicate 2 // Predicate 2 target loop | // | target loop #_current_predicate_chain_head @@ -977,7 +1016,76 @@ void CreateAssertionPredicatesVisitor::rewire_to_old_predicate_chain_head( } } -// Clone the Template Assertion Predicate and set a new input for the OpaqueLoopStrideNode. +TargetLoopPredicateChain::TargetLoopPredicateChain(LoopNode* loop_head, PhaseIdealLoop* phase) + : DEBUG_ONLY(_old_target_loop_entry(loop_head->in(LoopNode::EntryControl)) COMMA) + DEBUG_ONLY(_node_index_before_cloning(phase->C->unique()) COMMA) + _current_predicate_chain_head(loop_head), + _phase(phase) {} + +// Inserts the provided newly cloned predicate to the head of the target loop predicate chain. +void TargetLoopPredicateChain::insert_predicate(const Predicate& predicate) { + rewire_to_target_chain_head(predicate.tail()->as_IfTrue()); + _current_predicate_chain_head = predicate.head(); + assert(predicate.head()->_idx >= _node_index_before_cloning, "must be a newly cloned predicate"); + assert(predicate.tail()->_idx >= _node_index_before_cloning, "must be a newly cloned predicate"); + assert(_current_predicate_chain_head->in(0) == _old_target_loop_entry && + _old_target_loop_entry->unique_ctrl_out() == _current_predicate_chain_head , "must be connected now"); +} + +void TargetLoopPredicateChain::rewire_to_target_chain_head(IfTrueNode* template_assertion_predicate_success_proj) const { + if (_current_predicate_chain_head->is_Loop()) { + _phase->replace_loop_entry(_current_predicate_chain_head->as_Loop(), template_assertion_predicate_success_proj); + } else { + _phase->replace_control(_current_predicate_chain_head, template_assertion_predicate_success_proj); + } +} + +ClonePredicateToTargetLoop::ClonePredicateToTargetLoop(LoopNode* target_loop_head, const NodeInLoopBody& node_in_loop_body, + PhaseIdealLoop* phase) + : _old_target_loop_entry(target_loop_head->in(LoopNode::EntryControl)), + _target_loop_predicate_chain(target_loop_head, phase), + _node_in_loop_body(node_in_loop_body), + _phase(phase) {} + + +CloneUnswitchedLoopPredicatesVisitor::CloneUnswitchedLoopPredicatesVisitor( + LoopNode* true_path_loop_head, LoopNode* false_path_loop_head, + const NodeInOriginalLoopBody& node_in_true_path_loop_body, const NodeInClonedLoopBody& node_in_false_path_loop_body, + PhaseIdealLoop* phase) + : _clone_predicate_to_true_path_loop(true_path_loop_head, node_in_true_path_loop_body, phase), + _clone_predicate_to_false_path_loop(false_path_loop_head, node_in_false_path_loop_body, phase), + _phase(phase), + _has_hoisted_check_parse_predicates(false) {} + +// Keep track of whether we are in the correct Predicate Block where Template Assertion Predicates can be found. +// The PredicateIterator will always start at the loop entry and first visits the Loop Limit Check Predicate Block. +void CloneUnswitchedLoopPredicatesVisitor::visit(const ParsePredicate& parse_predicate) { + Deoptimization::DeoptReason deopt_reason = parse_predicate.head()->deopt_reason(); + if (deopt_reason == Deoptimization::Reason_predicate || + deopt_reason == Deoptimization::Reason_profile_predicate) { + _has_hoisted_check_parse_predicates = true; + } + + _clone_predicate_to_true_path_loop.clone_parse_predicate(parse_predicate, false); + _clone_predicate_to_false_path_loop.clone_parse_predicate(parse_predicate, true); + parse_predicate.kill(_phase->igvn()); +} + +// Clone the Template Assertion Predicate, which is currently found before the newly added unswitched loop selector, +// to the true path and false path loop. +void CloneUnswitchedLoopPredicatesVisitor::visit(const TemplateAssertionPredicate& template_assertion_predicate) { + if (!_has_hoisted_check_parse_predicates) { + // Only process if we are in the correct Predicate Block. + return; + } + + _clone_predicate_to_true_path_loop.clone_template_assertion_predicate(template_assertion_predicate); + _clone_predicate_to_false_path_loop.clone_template_assertion_predicate(template_assertion_predicate); + template_assertion_predicate.kill(_phase); +} + +// Update the Template Assertion Predicate by setting a new input for the OpaqueLoopStrideNode. Create a new +// Initialized Assertion Predicate from the updated Template Assertion Predicate. void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate& template_assertion_predicate) { if (!template_assertion_predicate.is_last_value()) { // Only Last Value Assertion Predicates have an OpaqueLoopStrideNode. @@ -985,8 +1093,9 @@ void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate& } replace_opaque_stride_input(template_assertion_predicate); Node* template_tail_control_out = template_assertion_predicate.tail()->unique_ctrl_out(); - IfTrueNode* initialized_success_proj = initialize_from_updated_template(template_assertion_predicate); - connect_initialized_assertion_predicate(template_tail_control_out, initialized_success_proj); + InitializedAssertionPredicate initialized_assertion_predicate = + initialize_from_updated_template(template_assertion_predicate); + connect_initialized_assertion_predicate(template_tail_control_out, initialized_assertion_predicate); } // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. @@ -995,20 +1104,20 @@ void UpdateStrideForAssertionPredicates::replace_opaque_stride_input( template_assertion_predicate.replace_opaque_stride_input(_new_stride, _phase->igvn()); } -IfTrueNode* UpdateStrideForAssertionPredicates::initialize_from_updated_template( +InitializedAssertionPredicate UpdateStrideForAssertionPredicates::initialize_from_updated_template( const TemplateAssertionPredicate& template_assertion_predicate) const { - IfTrueNode* initialized_success_proj = template_assertion_predicate.initialize(_phase, template_assertion_predicate.tail()); - return initialized_success_proj; + return template_assertion_predicate.initialize(_phase); } // The newly created Initialized Assertion Predicate can safely be inserted because this visitor is already visiting // the Template Assertion Predicate above this. So, we will not accidentally visit this again and kill it with the // visit() method for Initialized Assertion Predicates. void UpdateStrideForAssertionPredicates::connect_initialized_assertion_predicate( - Node* new_control_out, IfTrueNode* initialized_success_proj) const { + Node* new_control_out, const InitializedAssertionPredicate& initialized_assertion_predicate) const { + Node* initialized_assertion_predicate_success_proj = initialized_assertion_predicate.tail(); if (new_control_out->is_Loop()) { - _phase->replace_loop_entry(new_control_out->as_Loop(), initialized_success_proj); + _phase->replace_loop_entry(new_control_out->as_Loop(), initialized_assertion_predicate_success_proj); } else { - _phase->replace_control(new_control_out, initialized_success_proj); + _phase->replace_control(new_control_out, initialized_assertion_predicate_success_proj); } } diff --git a/src/hotspot/share/opto/predicates.hpp b/src/hotspot/share/opto/predicates.hpp index bc8c1a8ebdce8..bfc1b23115e65 100644 --- a/src/hotspot/share/opto/predicates.hpp +++ b/src/hotspot/share/opto/predicates.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ #define SHARE_OPTO_PREDICATES_HPP #include "opto/cfgnode.hpp" -#include "opto/connode.hpp" #include "opto/opaquenode.hpp" class IdealLoopTree; @@ -232,7 +231,7 @@ class Predicate : public StackObj { // Generic predicate visitor that does nothing. Subclass this visitor to add customized actions for each predicate. // The visit methods of this visitor are called from the predicate iterator classes which walk the predicate chain. // Use the UnifiedPredicateVisitor if the type of the predicate does not matter. -class PredicateVisitor : StackObj { +class PredicateVisitor : public StackObj { public: virtual void visit(const ParsePredicate& parse_predicate) {} virtual void visit(const RuntimePredicate& runtime_predicate) {} @@ -249,7 +248,7 @@ class PredicateVisitor : StackObj { // Interface to check whether a node is in a loop body or not. class NodeInLoopBody : public StackObj { public: - virtual bool check(Node* node) const = 0; + virtual bool check_node_in_loop_body(Node* node) const = 0; }; // Class to represent Assertion Predicates (i.e. either Initialized and/or Template Assertion Predicates). @@ -296,7 +295,9 @@ class ParsePredicate : public Predicate { return parse_predicate_proj->isa_IfTrue(); } - static ParsePredicateNode* init_parse_predicate(Node* parse_predicate_proj, Deoptimization::DeoptReason deopt_reason); + static ParsePredicateNode* init_parse_predicate(const Node* parse_predicate_proj, Deoptimization::DeoptReason deopt_reason); + NOT_PRODUCT(static void trace_cloned_parse_predicate(bool is_false_path_loop, + const ParsePredicateSuccessProj* success_proj);) public: ParsePredicate(Node* parse_predicate_proj, Deoptimization::DeoptReason deopt_reason) @@ -325,6 +326,15 @@ class ParsePredicate : public Predicate { assert(is_valid(), "must be valid"); return _success_proj; } + + ParsePredicate clone_to_unswitched_loop(Node* new_control, bool is_false_path_loop, + PhaseIdealLoop* phase) const; + + // Kills this Parse Predicate by marking it useless. Will be folded away in the next IGVN round. + void kill(const PhaseIterGVN& igvn) const { + _parse_predicate_node->mark_useless(); + igvn._worklist.push(_parse_predicate_node); + } }; // Class to represent a Runtime Predicate which always has an associated UCT on the failing path. @@ -341,9 +351,9 @@ class RuntimePredicate : public Predicate { NONCOPYABLE(RuntimePredicate); private: - static bool is_predicate(Node* maybe_success_proj); + static bool is_predicate(const Node* maybe_success_proj); static bool has_valid_uncommon_trap(const Node* success_proj); - static Deoptimization::DeoptReason uncommon_trap_reason(IfProjNode* if_proj); + static Deoptimization::DeoptReason uncommon_trap_reason(const IfProjNode* if_proj); public: Node* entry() const override { @@ -393,13 +403,15 @@ class TemplateAssertionPredicate : public Predicate { return _if_node->assertion_predicate_type() == AssertionPredicateType::LastValue; } - IfTrueNode* clone(Node* new_control, PhaseIdealLoop* phase) const; - IfTrueNode* clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, PhaseIdealLoop* phase) const; + TemplateAssertionPredicate clone(Node* new_control, PhaseIdealLoop* phase) const; + TemplateAssertionPredicate clone_and_replace_opaque_input(Node* new_control, Node* new_opaque_input, + PhaseIdealLoop* phase) const; void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const; - IfTrueNode* initialize(PhaseIdealLoop* phase, Node* new_control) const; + InitializedAssertionPredicate initialize(PhaseIdealLoop* phase) const; void rewire_loop_data_dependencies(IfTrueNode* target_predicate, const NodeInLoopBody& data_in_loop_body, - PhaseIdealLoop* phase) const; - static bool is_predicate(Node* node); + const PhaseIdealLoop* phase) const; + void kill(PhaseIdealLoop* phase) const; + static bool is_predicate(const Node* node); #ifdef ASSERT static void verify(IfTrueNode* template_assertion_predicate_success_proj) { @@ -445,7 +457,7 @@ class InitializedAssertionPredicate : public Predicate { } void kill(PhaseIdealLoop* phase) const; - static bool is_predicate(Node* node); + static bool is_predicate(const Node* node); #ifdef ASSERT static void verify(IfTrueNode* initialized_assertion_predicate_success_proj) { @@ -474,16 +486,16 @@ class TemplateAssertionExpression : public StackObj { private: OpaqueTemplateAssertionPredicateNode* clone(const TransformStrategyForOpaqueLoopNodes& transform_strategy, - Node* new_ctrl, PhaseIdealLoop* phase); + Node* new_control, PhaseIdealLoop* phase) const; public: - OpaqueTemplateAssertionPredicateNode* clone(Node* new_control, PhaseIdealLoop* phase); + OpaqueTemplateAssertionPredicateNode* clone(Node* new_control, PhaseIdealLoop* phase) const; OpaqueTemplateAssertionPredicateNode* clone_and_replace_init(Node* new_control, Node* new_init, - PhaseIdealLoop* phase); + PhaseIdealLoop* phase) const; OpaqueTemplateAssertionPredicateNode* clone_and_replace_init_and_stride(Node* new_control, Node* new_init, - Node* new_stride, PhaseIdealLoop* phase); - void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn); - OpaqueInitializedAssertionPredicateNode* clone_and_fold_opaque_loop_nodes(Node* new_ctrl, PhaseIdealLoop* phase); + Node* new_stride, PhaseIdealLoop* phase) const; + void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const; + OpaqueInitializedAssertionPredicateNode* clone_and_fold_opaque_loop_nodes(Node* new_control, PhaseIdealLoop* phase) const; }; // Class to represent a node being part of a Template Assertion Expression. Note that this is not an IR node. @@ -502,7 +514,7 @@ class TemplateAssertionExpressionNode : public StackObj { NONCOPYABLE(TemplateAssertionExpressionNode); private: - static bool is_template_assertion_predicate(Node* node); + static bool is_template_assertion_predicate(const Node* node); public: // Check whether the provided node is part of a Template Assertion Expression or not. @@ -569,17 +581,17 @@ class AssertionPredicateIfCreator : public StackObj { NONCOPYABLE(AssertionPredicateIfCreator); IfTrueNode* create_for_initialized(Node* new_control, int if_opcode, Node* assertion_expression, - AssertionPredicateType assertion_predicate_type); + AssertionPredicateType assertion_predicate_type) const; IfTrueNode* create_for_template(Node* new_control, int if_opcode, Node* assertion_expression, - AssertionPredicateType assertion_predicate_type); + AssertionPredicateType assertion_predicate_type) const; private: IfTrueNode* create(Node* new_control, int if_opcode, Node* assertion_expression, const char* halt_message, - AssertionPredicateType assertion_predicate_type); + AssertionPredicateType assertion_predicate_type) const; IfNode* create_if_node(Node* new_control, int if_opcode, Node* assertion_expression, IdealLoopTree* loop, - AssertionPredicateType assertion_predicate_type); - IfTrueNode* create_success_path(IfNode* if_node, IdealLoopTree* loop); - void create_fail_path(IfNode* if_node, IdealLoopTree* loop, const char* halt_message); - void create_halt_node(IfFalseNode* fail_proj, IdealLoopTree* loop, const char* halt_message); + AssertionPredicateType assertion_predicate_type) const; + IfTrueNode* create_success_path(IfNode* if_node, IdealLoopTree* loop) const; + void create_fail_path(IfNode* if_node, IdealLoopTree* loop, const char* halt_message) const; + void create_halt_node(IfFalseNode* fail_proj, IdealLoopTree* loop, const char* halt_message) const; }; // This class is used to create a Template Assertion Predicate either with a Halt Node from scratch. @@ -590,7 +602,7 @@ class TemplateAssertionPredicateCreator : public StackObj { Node* const _range; PhaseIdealLoop* const _phase; - OpaqueLoopInitNode* create_opaque_init(Node* new_control); + OpaqueLoopInitNode* create_opaque_init(Node* new_control) const; OpaqueTemplateAssertionPredicateNode* create_for_init_value(Node* new_control, OpaqueLoopInitNode* opaque_init, bool& does_overflow) const; OpaqueTemplateAssertionPredicateNode* create_for_last_value(Node* new_control, OpaqueLoopInitNode* opaque_init, @@ -598,7 +610,7 @@ class TemplateAssertionPredicateCreator : public StackObj { Node* create_last_value(Node* new_control, OpaqueLoopInitNode* opaque_init) const; IfTrueNode* create_if_node(Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression, - bool does_overflow, AssertionPredicateType assertion_predicate_type); + bool does_overflow, AssertionPredicateType assertion_predicate_type) const; public: TemplateAssertionPredicateCreator(CountedLoopNode* loop_head, int scale, Node* offset, Node* range, @@ -610,7 +622,7 @@ class TemplateAssertionPredicateCreator : public StackObj { _phase(phase) {} NONCOPYABLE(TemplateAssertionPredicateCreator); - IfTrueNode* create(Node* new_control); + IfTrueNode* create(Node* new_control) const; }; // This class creates a new Initialized Assertion Predicate either from a template or from scratch. @@ -621,19 +633,21 @@ class InitializedAssertionPredicateCreator : public StackObj { explicit InitializedAssertionPredicateCreator(PhaseIdealLoop* phase); NONCOPYABLE(InitializedAssertionPredicateCreator); - IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control, Node* new_init, - Node* new_stride); - IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control); + InitializedAssertionPredicate create_from_template(const IfNode* template_assertion_predicate, Node* new_control, + Node* new_init, Node* new_stride) const; + + InitializedAssertionPredicate + create_from_template_and_insert_below(const TemplateAssertionPredicate& template_assertion_predicate) const; IfTrueNode* create(Node* operand, Node* new_control, jint stride, int scale, Node* offset, Node* range, - AssertionPredicateType assertion_predicate_type); + AssertionPredicateType assertion_predicate_type) const; private: - OpaqueInitializedAssertionPredicateNode* create_assertion_expression_from_template(IfNode* template_assertion_predicate, + OpaqueInitializedAssertionPredicateNode* create_assertion_expression_from_template(const IfNode* template_assertion_predicate, Node* new_control, Node* new_init, - Node* new_stride); + Node* new_stride) const; IfTrueNode* create_control_nodes(Node* new_control, int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression, - AssertionPredicateType assertion_predicate_type); + AssertionPredicateType assertion_predicate_type) const; }; // This class iterates through all predicates of a Regular Predicate Block and applies the given visitor to each. @@ -778,7 +792,7 @@ class RegularPredicateBlock : public StackObj { return iterator.skip_all(); } - DEBUG_ONLY(void verify_block(Node* tail);) + DEBUG_ONLY(void verify_block(Node* tail) const;) public: Node* entry() const { @@ -952,13 +966,52 @@ class NodeInOriginalLoopBody : public NodeInLoopBody { // Check if 'node' is not a cloned node (i.e. "< _first_node_index_in_cloned_loop_body") and if we've created a // clone from 'node' (i.e. _old_new entry is non-null). Then we know that 'node' belongs to the original loop body. - bool check(Node* node) const override { + bool check_node_in_loop_body(Node* node) const override { if (node->_idx < _first_node_index_in_cloned_loop_body) { Node* cloned_node = _old_new[node->_idx]; + // Check that the clone is actually part of the cloned loop body and not from some earlier cloning. return cloned_node != nullptr && cloned_node->_idx >= _first_node_index_in_cloned_loop_body; - } else { - return false; } + return false; + } +}; + +// This class checks whether a node is in the main loop body and not the pre loop body. We cannot use the +// NodeInOriginalLoopBody class because PhaseIdealLoop::clone_up_backedge_goo() could clone additional nodes that +// should be pinned at the main loop body entry. The check in NodeInOriginalLoopBody will ignore these. +class NodeInMainLoopBody : public NodeInLoopBody { + const uint _first_node_index_in_pre_loop_body; + const uint _last_node_index_in_pre_loop_body; + DEBUG_ONLY(const uint _last_node_index_from_backedge_goo;) + const Node_List& _old_new; + + public: + NodeInMainLoopBody(const uint first_node_index_in_pre_loop_body, const uint last_node_index_in_pre_loop_body, + DEBUG_ONLY(const uint last_node_index_from_backedge_goo COMMA) const Node_List& old_new) + : _first_node_index_in_pre_loop_body(first_node_index_in_pre_loop_body), + _last_node_index_in_pre_loop_body(last_node_index_in_pre_loop_body), + DEBUG_ONLY(_last_node_index_from_backedge_goo(last_node_index_from_backedge_goo) COMMA) + _old_new(old_new) {} + NONCOPYABLE(NodeInMainLoopBody); + + // Check if 'node' is not a cloned node (i.e. "< _first_node_index_in_cloned_loop_body") and if we've created a + // clone from 'node' (i.e. _old_new entry is non-null). Then we know that 'node' belongs to the original loop body. + // Additionally check if a node was cloned after the pre loop was created. This indicates that it was created by + // PhaseIdealLoop::clone_up_backedge_goo(). These nodes should also be pinned at the main loop entry. + bool check_node_in_loop_body(Node* node) const override { + if (node->_idx < _first_node_index_in_pre_loop_body) { + Node* cloned_node = _old_new[node->_idx]; + // Check that the clone is actually part of the cloned loop body and not from some earlier cloning. + bool cloned_node_in_pre_loop_body = cloned_node != nullptr && cloned_node->_idx >= _first_node_index_in_pre_loop_body; + assert(!cloned_node_in_pre_loop_body || cloned_node->_idx <= _last_node_index_in_pre_loop_body, + "clone must be part of pre loop body"); + return cloned_node_in_pre_loop_body; + } + // Created in PhaseIdealLoop::clone_up_backedge_goo()? + bool node_created_by_backedge_goo = node->_idx > _last_node_index_in_pre_loop_body; + assert(!node_created_by_backedge_goo || node->_idx <= _last_node_index_from_backedge_goo, + "cloned node must have been created in PhaseIdealLoop::clone_up_backedge_goo()"); + return node_created_by_backedge_goo; } }; @@ -973,7 +1026,7 @@ class NodeInClonedLoopBody : public NodeInLoopBody { // Check if 'node' is a clone. This can easily be achieved by comparing its node index to the first node index // inside the cloned loop body (all of them are clones). - bool check(Node* node) const override { + bool check_node_in_loop_body(Node* node) const override { return node->_idx >= _first_node_index_in_cloned_loop_body; } }; @@ -990,9 +1043,11 @@ class CreateAssertionPredicatesVisitor : public PredicateVisitor { const NodeInLoopBody& _node_in_loop_body; const bool _clone_template; - IfTrueNode* clone_template_and_replace_init_input(const TemplateAssertionPredicate& template_assertion_predicate); - IfTrueNode* initialize_from_template(const TemplateAssertionPredicate& template_assertion_predicate, - Node* new_control) const; + TemplateAssertionPredicate + clone_template_and_replace_init_input(const TemplateAssertionPredicate& template_assertion_predicate) const; + + InitializedAssertionPredicate initialize_from_template(const TemplateAssertionPredicate& template_assertion_predicate, + Node* new_control) const; void rewire_to_old_predicate_chain_head(Node* initialized_assertion_predicate_success_proj) const; public: @@ -1006,25 +1061,104 @@ class CreateAssertionPredicatesVisitor : public PredicateVisitor { void visit(const TemplateAssertionPredicate& template_assertion_predicate) override; }; -// This visitor collects all Template Assertion Predicates If nodes or the corresponding Opaque nodes, depending on the -// provided 'get_opaque' flag, to the provided list. -class TemplateAssertionPredicateCollector : public PredicateVisitor { +// This class establishes a predicate chain at the target loop by rewiring newly cloned predicates to the current head +// of the predicate chain. +class TargetLoopPredicateChain : public StackObj { + DEBUG_ONLY(const Node* const _old_target_loop_entry;) + DEBUG_ONLY(const node_idx_t _node_index_before_cloning;) + Node* _current_predicate_chain_head; + PhaseIdealLoop* const _phase; + + void rewire_to_target_chain_head(IfTrueNode* template_assertion_predicate_success_proj) const; + +public: + TargetLoopPredicateChain(LoopNode* loop_head, PhaseIdealLoop* phase); + NONCOPYABLE(TargetLoopPredicateChain); + + void insert_predicate(const Predicate& predicate); +}; + +// This class clones Parse and Template Assertion Predicates to the provided target loop. This also involves rewiring +// of any data pinned to Template Assertion Predicates. The Template Assertion Predicate Expressions are cloned +// without applying any changes to them. +// +// Each time a predicate is cloned, it is inserted at the top of previously cloned predicates. This ensures that the +// target loop predicate chain order of the newly cloned predicates is the same as in the source loop from which the +// predicates were cloned from. +// +// Template Assertion Predicate Example: +// +// x _old_target_loop_entry _old_target_loop_entry +// | | | | +// Template Assertion | Cloned Template 2. rewire data Cloned Template +// Predicate 1. clone | Assertion Predicate and predicate Assertion Predicate +// | \ =======> | ===============> | \ +// | data | | data +// | | | +// source loop head target loop head target loop head +class ClonePredicateToTargetLoop : public StackObj { + Node* const _old_target_loop_entry; // Used as control for each newly cloned predicate. + TargetLoopPredicateChain _target_loop_predicate_chain; + const NodeInLoopBody& _node_in_loop_body; + PhaseIdealLoop* const _phase; + +public: + ClonePredicateToTargetLoop(LoopNode* target_loop_head, const NodeInLoopBody& node_in_loop_body, PhaseIdealLoop* phase); + + // Clones the provided Parse Predicate to the head of the current predicate chain at the target loop. + void clone_parse_predicate(const ParsePredicate& parse_predicate, bool is_false_path_loop) { + ParsePredicate cloned_parse_predicate = parse_predicate.clone_to_unswitched_loop(_old_target_loop_entry, + is_false_path_loop, _phase); + _target_loop_predicate_chain.insert_predicate(cloned_parse_predicate); + } + + // Clones the provided Template Assertion Predicate to the head of the current predicate chain at the target loop. + void clone_template_assertion_predicate(const TemplateAssertionPredicate& template_assertion_predicate) { + TemplateAssertionPredicate cloned_template_assertion_predicate = + template_assertion_predicate.clone(_old_target_loop_entry, _phase); + template_assertion_predicate.rewire_loop_data_dependencies(cloned_template_assertion_predicate.tail(), + _node_in_loop_body, _phase); + _target_loop_predicate_chain.insert_predicate(cloned_template_assertion_predicate); + } +}; + +// Visitor to clone Parse and Template Assertion Predicates from a loop to its unswitched true and false path loop. +// The cloned predicates are not updated in any way. Thus, an Initialized Assertion Predicate is also not required to +// be created. Note that the data dependencies from the Template Assertion Predicates are also updated to the newly +// cloned Template Assertion Predicates, depending on whether they belong to the true or false path loop. +class CloneUnswitchedLoopPredicatesVisitor : public PredicateVisitor { + ClonePredicateToTargetLoop _clone_predicate_to_true_path_loop; + ClonePredicateToTargetLoop _clone_predicate_to_false_path_loop; + + PhaseIdealLoop* const _phase; + bool _has_hoisted_check_parse_predicates; + + public: + CloneUnswitchedLoopPredicatesVisitor(LoopNode* true_path_loop_head, + LoopNode* false_path_loop_head, + const NodeInOriginalLoopBody& node_in_true_path_loop_body, + const NodeInClonedLoopBody& node_in_false_path_loop_body, + PhaseIdealLoop* phase); + NONCOPYABLE(CloneUnswitchedLoopPredicatesVisitor); + + using PredicateVisitor::visit; + + void visit(const ParsePredicate& parse_predicate) override; + void visit(const TemplateAssertionPredicate& template_assertion_predicate) override; +}; + +// This visitor collects all OpaqueTemplateAssertionNodes of Template Assertion Predicates. This is used for cleaning +// up unused Template Assertion Predicates. +class OpaqueTemplateAssertionPredicateCollector : public PredicateVisitor { Unique_Node_List& _list; - const bool _get_opaque; public: - TemplateAssertionPredicateCollector(Unique_Node_List& list, const bool get_opaque) - : _list(list), - _get_opaque(get_opaque) {} + explicit OpaqueTemplateAssertionPredicateCollector(Unique_Node_List& list) : _list(list) {} using PredicateVisitor::visit; void visit(const TemplateAssertionPredicate& template_assertion_predicate) override { - if (_get_opaque) { - _list.push(template_assertion_predicate.opaque_node()); - } else { - _list.push(template_assertion_predicate.tail()); - } + _list.push(template_assertion_predicate.opaque_node()); } }; @@ -1036,8 +1170,10 @@ class UpdateStrideForAssertionPredicates : public PredicateVisitor { PhaseIdealLoop* const _phase; void replace_opaque_stride_input(const TemplateAssertionPredicate& template_assertion_predicate) const; - IfTrueNode* initialize_from_updated_template(const TemplateAssertionPredicate& template_assertion_predicate) const; - void connect_initialized_assertion_predicate(Node* new_control_out, IfTrueNode* initialized_success_proj) const; + + InitializedAssertionPredicate + initialize_from_updated_template(const TemplateAssertionPredicate& template_assertion_predicate) const; + void connect_initialized_assertion_predicate(Node* new_control_out, const InitializedAssertionPredicate& initialized_assertion_predicate) const; public: UpdateStrideForAssertionPredicates(Node* const new_stride, PhaseIdealLoop* phase) diff --git a/src/hotspot/share/opto/printinlining.cpp b/src/hotspot/share/opto/printinlining.cpp new file mode 100644 index 0000000000000..accc3dcc63769 --- /dev/null +++ b/src/hotspot/share/opto/printinlining.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "opto/printinlining.hpp" +#include "opto/callnode.hpp" +#include "memory/allocation.hpp" +#include "memory/resourceArea.hpp" + +bool InlinePrinter::is_enabled() const { + return C->print_intrinsics() || C->print_inlining(); +} + +outputStream* InlinePrinter::record(ciMethod* callee, JVMState* state, InliningResult result, const char* msg) { + if (!is_enabled()) { + return &_nullStream; + } + outputStream* stream = locate(state, callee)->add(result); + if (msg != nullptr) { + stream->print("%s", msg); + } + return stream; // Pointer stays valid, see IPInlineSite::add() +} + +void InlinePrinter::print_on(outputStream* tty) const { + if (!is_enabled()) { + return; + } + _root.dump(tty, -1); +} + +InlinePrinter::IPInlineSite* InlinePrinter::locate(JVMState* state, ciMethod* callee) { + auto growableArray = new GrowableArrayCHeap(2); + + while (state != nullptr) { + growableArray->push(state); + state = state->caller(); + } + + IPInlineSite* site = &_root; + for (int i = growableArray->length() - 1; i >= 0; i--) { + site = &site->at_bci(growableArray->at(i)->bci(), i == 0 ? callee : nullptr); + } + + delete growableArray; + + return site; +} + +InlinePrinter::IPInlineSite& InlinePrinter::IPInlineSite::at_bci(int bci, ciMethod* callee) { + auto find_result = _children.find(bci); + IPInlineSite& child = find_result.node->val(); + + if (find_result.new_node) { + assert(callee != nullptr, "an inline call is missing in the chain up to the root"); + child.set_source(callee, bci); + } else { // We already saw a call at this site before + if (callee != nullptr && callee != child._method) { + outputStream* stream = child.add(InliningResult::SUCCESS); + stream->print("callee changed to "); + CompileTask::print_inline_inner_method_info(stream, callee); + } + } + + return child; +} + +outputStream* InlinePrinter::IPInlineSite::add(InliningResult result) { + _attempts.push(IPInlineAttempt(result)); + return _attempts.last().make_stream(); +} + +void InlinePrinter::IPInlineSite::dump(outputStream* tty, int level) const { + assert(_bci != -999, "trying to dump site without source"); + + if (_attempts.is_nonempty()) { + CompileTask::print_inlining_header(tty, _method, level, _bci); + } + for (int i = 0; i < _attempts.length(); i++) { + CompileTask::print_inlining_inner_message(tty, _attempts.at(i).result(), _attempts.at(i).stream()->base()); + } + if (_attempts.is_nonempty()) { + tty->cr(); + } + + _children.visit_in_order([=](auto* node) { + node->val().dump(tty, level + 1); + }); +} diff --git a/src/hotspot/share/opto/printinlining.hpp b/src/hotspot/share/opto/printinlining.hpp new file mode 100644 index 0000000000000..ae79648319b43 --- /dev/null +++ b/src/hotspot/share/opto/printinlining.hpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef PRINTINLINING_HPP +#define PRINTINLINING_HPP + +#include "memory/allocation.hpp" +#include "utilities/ostream.hpp" +#include "utilities/growableArray.hpp" +#include "nmt/nmtTreap.hpp" + +class JVMState; +class ciMethod; +class Compile; +enum class InliningResult; + +// If not enabled, all method calls are no-ops. +class InlinePrinter { +private: + class IPInlineAttempt { + InliningResult _result; + stringStream* _stream; + + public: + IPInlineAttempt() : _stream(nullptr) {} + + IPInlineAttempt(InliningResult result) : _result(result), _stream(nullptr) {} + + InliningResult result() const { return _result; } + + stringStream* make_stream() { + assert(_stream == nullptr, "stream already exists"); + _stream = new (mtCompiler) stringStream; + return _stream; + } + + stringStream* stream() const { + assert(_stream != nullptr, "stream was not created yet!"); + return _stream; + } + + void deallocate_stream() { + delete _stream; + _stream = nullptr; + } + }; + + struct Cmp { + static int cmp(int a, int b) { + return a - b; + } + }; + + class IPInlineSite : public CHeapObj { + private: + ciMethod* _method; + int _bci; + GrowableArrayCHeap _attempts; + TreapCHeap _children; + + public: + IPInlineSite(ciMethod* method, int bci) : _method(method), _bci(bci) {} + + IPInlineSite() : _method(nullptr), _bci(-999) {} + + ~IPInlineSite() { + // Since GrowableArrayCHeap uses copy semantics to resize itself we + // cannot free the stream inside IPInlineAttempt's destructor unfortunately + // and have to take care of this here instead. + for (int i = 0; i < _attempts.length(); i++) { + _attempts.at(i).deallocate_stream(); + } + } + + void set_source(ciMethod* method, int bci) { + _method = method; + _bci = bci; + } + + // Finds the node for an inline attempt that occurred inside this inline. + // If this is a new site, provide the callee otherwise null. + // Returned reference is valid until any at_bci is called with non-null callee. + IPInlineSite& at_bci(int bci, ciMethod* callee); + // The returned pointer stays valid until InlinePrinter is destructed. + outputStream* add(InliningResult result); + + void dump(outputStream* tty, int level) const; + }; + + bool is_enabled() const; + + Compile* C; + + // In case print inline is disabled, this null stream is returned from ::record() + nullStream _nullStream; + + // Locates the IPInlineSite node that corresponds to this JVM state. + // state may be null. In this case, the root node is returned. + // If this is a new site, provide the callee otherwise null. + // Returned pointer is valid until InlinePrinter is destructed. + IPInlineSite* locate(JVMState* state, ciMethod* callee); + + IPInlineSite _root{nullptr, 0}; + +public: + InlinePrinter(Compile* compile) : C(compile) {} + + // Saves the result of an inline attempt of method at state. + // An optional string message with more details that is copied to the stream for this attempt. Pointer is not captured. + // Returns an output stream which stores the message associated with this attempt. The buffer stays valid until InlinePrinter is destructed. + // You can print arbitrary information to this stream but do not add line breaks, as this will break formatting. + outputStream* record(ciMethod* callee, JVMState* state, InliningResult result, const char* msg = nullptr); + + // Prints all collected inlining information to the given output stream. + void print_on(outputStream* tty) const; +}; + +#endif // PRINTINLINING_HPP diff --git a/src/hotspot/share/opto/reg_split.cpp b/src/hotspot/share/opto/reg_split.cpp index 9e41c39764333..42ae79feba7c7 100644 --- a/src/hotspot/share/opto/reg_split.cpp +++ b/src/hotspot/share/opto/reg_split.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "libadt/vectset.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.inline.hpp" diff --git a/src/hotspot/share/opto/regalloc.cpp b/src/hotspot/share/opto/regalloc.cpp index d06619976f368..644296715f575 100644 --- a/src/hotspot/share/opto/regalloc.cpp +++ b/src/hotspot/share/opto/regalloc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/regalloc.hpp" static const int NodeRegsOverflowSize = 200; diff --git a/src/hotspot/share/opto/regmask.cpp b/src/hotspot/share/opto/regmask.cpp index 4b3fe291b5cd6..33f73262b16e6 100644 --- a/src/hotspot/share/opto/regmask.cpp +++ b/src/hotspot/share/opto/regmask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/ad.hpp" #include "opto/chaitin.hpp" #include "opto/compile.hpp" diff --git a/src/hotspot/share/opto/replacednodes.cpp b/src/hotspot/share/opto/replacednodes.cpp index d530de5a356b2..96216f9d7778e 100644 --- a/src/hotspot/share/opto/replacednodes.cpp +++ b/src/hotspot/share/opto/replacednodes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/resourceArea.hpp" #include "opto/cfgnode.hpp" #include "opto/phaseX.hpp" diff --git a/src/hotspot/share/opto/rootnode.cpp b/src/hotspot/share/opto/rootnode.cpp index 87bb053967896..4ced13abdb1f6 100644 --- a/src/hotspot/share/opto/rootnode.cpp +++ b/src/hotspot/share/opto/rootnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/callnode.hpp" #include "opto/cfgnode.hpp" diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp index 3dd94f619fd1a..30cfbddc1966a 100644 --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -192,6 +191,72 @@ bool OptoRuntime::generate(ciEnv* env) { #undef GEN_C2_JVMTI_STUB // #undef gen +const TypeFunc* OptoRuntime::_new_instance_Type = nullptr; +const TypeFunc* OptoRuntime::_new_array_Type = nullptr; +const TypeFunc* OptoRuntime::_multianewarray2_Type = nullptr; +const TypeFunc* OptoRuntime::_multianewarray3_Type = nullptr; +const TypeFunc* OptoRuntime::_multianewarray4_Type = nullptr; +const TypeFunc* OptoRuntime::_multianewarray5_Type = nullptr; +const TypeFunc* OptoRuntime::_multianewarrayN_Type = nullptr; +const TypeFunc* OptoRuntime::_complete_monitor_enter_Type = nullptr; +const TypeFunc* OptoRuntime::_complete_monitor_exit_Type = nullptr; +const TypeFunc* OptoRuntime::_monitor_notify_Type = nullptr; +const TypeFunc* OptoRuntime::_uncommon_trap_Type = nullptr; +const TypeFunc* OptoRuntime::_athrow_Type = nullptr; +const TypeFunc* OptoRuntime::_rethrow_Type = nullptr; +const TypeFunc* OptoRuntime::_Math_D_D_Type = nullptr; +const TypeFunc* OptoRuntime::_Math_DD_D_Type = nullptr; +const TypeFunc* OptoRuntime::_modf_Type = nullptr; +const TypeFunc* OptoRuntime::_l2f_Type = nullptr; +const TypeFunc* OptoRuntime::_void_long_Type = nullptr; +const TypeFunc* OptoRuntime::_void_void_Type = nullptr; +const TypeFunc* OptoRuntime::_jfr_write_checkpoint_Type = nullptr; +const TypeFunc* OptoRuntime::_flush_windows_Type = nullptr; +const TypeFunc* OptoRuntime::_fast_arraycopy_Type = nullptr; +const TypeFunc* OptoRuntime::_checkcast_arraycopy_Type = nullptr; +const TypeFunc* OptoRuntime::_generic_arraycopy_Type = nullptr; +const TypeFunc* OptoRuntime::_slow_arraycopy_Type = nullptr; +const TypeFunc* OptoRuntime::_unsafe_setmemory_Type = nullptr; +const TypeFunc* OptoRuntime::_array_fill_Type = nullptr; +const TypeFunc* OptoRuntime::_array_sort_Type = nullptr; +const TypeFunc* OptoRuntime::_array_partition_Type = nullptr; +const TypeFunc* OptoRuntime::_aescrypt_block_Type = nullptr; +const TypeFunc* OptoRuntime::_cipherBlockChaining_aescrypt_Type = nullptr; +const TypeFunc* OptoRuntime::_electronicCodeBook_aescrypt_Type = nullptr; +const TypeFunc* OptoRuntime::_counterMode_aescrypt_Type = nullptr; +const TypeFunc* OptoRuntime::_galoisCounterMode_aescrypt_Type = nullptr; +const TypeFunc* OptoRuntime::_digestBase_implCompress_with_sha3_Type = nullptr; +const TypeFunc* OptoRuntime::_digestBase_implCompress_without_sha3_Type = nullptr; +const TypeFunc* OptoRuntime::_digestBase_implCompressMB_with_sha3_Type = nullptr; +const TypeFunc* OptoRuntime::_digestBase_implCompressMB_without_sha3_Type = nullptr; +const TypeFunc* OptoRuntime::_multiplyToLen_Type = nullptr; +const TypeFunc* OptoRuntime::_montgomeryMultiply_Type = nullptr; +const TypeFunc* OptoRuntime::_montgomerySquare_Type = nullptr; +const TypeFunc* OptoRuntime::_squareToLen_Type = nullptr; +const TypeFunc* OptoRuntime::_mulAdd_Type = nullptr; +const TypeFunc* OptoRuntime::_bigIntegerShift_Type = nullptr; +const TypeFunc* OptoRuntime::_vectorizedMismatch_Type = nullptr; +const TypeFunc* OptoRuntime::_ghash_processBlocks_Type = nullptr; +const TypeFunc* OptoRuntime::_chacha20Block_Type = nullptr; +const TypeFunc* OptoRuntime::_base64_encodeBlock_Type = nullptr; +const TypeFunc* OptoRuntime::_base64_decodeBlock_Type = nullptr; +const TypeFunc* OptoRuntime::_string_IndexOf_Type = nullptr; +const TypeFunc* OptoRuntime::_poly1305_processBlocks_Type = nullptr; +const TypeFunc* OptoRuntime::_intpoly_montgomeryMult_P256_Type = nullptr; +const TypeFunc* OptoRuntime::_intpoly_assign_Type = nullptr; +const TypeFunc* OptoRuntime::_updateBytesCRC32_Type = nullptr; +const TypeFunc* OptoRuntime::_updateBytesCRC32C_Type = nullptr; +const TypeFunc* OptoRuntime::_updateBytesAdler32_Type = nullptr; +const TypeFunc* OptoRuntime::_osr_end_Type = nullptr; +const TypeFunc* OptoRuntime::_register_finalizer_Type = nullptr; +#if INCLUDE_JFR +const TypeFunc* OptoRuntime::_class_id_load_barrier_Type = nullptr; +#endif // INCLUDE_JFR +#if INCLUDE_JVMTI +const TypeFunc* OptoRuntime::_notify_jvmti_vthread_Type = nullptr; +#endif // INCLUDE_JVMTI +const TypeFunc* OptoRuntime::_dtrace_method_entry_exit_Type = nullptr; +const TypeFunc* OptoRuntime::_dtrace_object_alloc_Type = nullptr; // Helper method to do generation of RunTimeStub's address OptoRuntime::generate_stub(ciEnv* env, @@ -498,7 +563,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* JRT_BLOCK_END; JRT_END -const TypeFunc *OptoRuntime::new_instance_Type() { +static const TypeFunc* make_new_instance_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated @@ -514,7 +579,7 @@ const TypeFunc *OptoRuntime::new_instance_Type() { } #if INCLUDE_JVMTI -const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() { +static const TypeFunc* make_notify_jvmti_vthread_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop @@ -530,7 +595,7 @@ const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() { } #endif -const TypeFunc *OptoRuntime::athrow_Type() { +static const TypeFunc* make_athrow_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated @@ -544,8 +609,7 @@ const TypeFunc *OptoRuntime::athrow_Type() { return TypeFunc::make(domain, range); } - -const TypeFunc *OptoRuntime::new_array_Type() { +static const TypeFunc* make_new_array_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass @@ -561,11 +625,7 @@ const TypeFunc *OptoRuntime::new_array_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::new_array_nozero_Type() { - return new_array_Type(); -} - -const TypeFunc *OptoRuntime::multianewarray_Type(int ndim) { +const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) { // create input type (domain) const int nargs = ndim + 1; const Type **fields = TypeTuple::fields(nargs); @@ -582,23 +642,7 @@ const TypeFunc *OptoRuntime::multianewarray_Type(int ndim) { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::multianewarray2_Type() { - return multianewarray_Type(2); -} - -const TypeFunc *OptoRuntime::multianewarray3_Type() { - return multianewarray_Type(3); -} - -const TypeFunc *OptoRuntime::multianewarray4_Type() { - return multianewarray_Type(4); -} - -const TypeFunc *OptoRuntime::multianewarray5_Type() { - return multianewarray_Type(5); -} - -const TypeFunc *OptoRuntime::multianewarrayN_Type() { +static const TypeFunc* make_multianewarrayN_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass @@ -613,7 +657,7 @@ const TypeFunc *OptoRuntime::multianewarrayN_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::uncommon_trap_Type() { +static const TypeFunc* make_uncommon_trap_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInt::INT; // trap_reason (deopt reason and action) @@ -628,7 +672,8 @@ const TypeFunc *OptoRuntime::uncommon_trap_Type() { //----------------------------------------------------------------------------- // Monitor Handling -const TypeFunc *OptoRuntime::complete_monitor_enter_Type() { + +static const TypeFunc* make_complete_monitor_enter_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked @@ -643,12 +688,9 @@ const TypeFunc *OptoRuntime::complete_monitor_enter_Type() { return TypeFunc::make(domain,range); } -const TypeFunc *OptoRuntime::complete_monitor_locking_Type() { - return complete_monitor_enter_Type(); -} - //----------------------------------------------------------------------------- -const TypeFunc *OptoRuntime::complete_monitor_exit_Type() { + +static const TypeFunc* make_complete_monitor_exit_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(3); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked @@ -664,7 +706,7 @@ const TypeFunc *OptoRuntime::complete_monitor_exit_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::monitor_notify_Type() { +static const TypeFunc* make_monitor_notify_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked @@ -676,11 +718,7 @@ const TypeFunc *OptoRuntime::monitor_notify_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::monitor_notifyAll_Type() { - return monitor_notify_Type(); -} - -const TypeFunc* OptoRuntime::flush_windows_Type() { +static const TypeFunc* make_flush_windows_Type() { // create input type (domain) const Type** fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = nullptr; // void @@ -694,7 +732,7 @@ const TypeFunc* OptoRuntime::flush_windows_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::l2f_Type() { +static const TypeFunc* make_l2f_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeLong::LONG; @@ -709,7 +747,7 @@ const TypeFunc* OptoRuntime::l2f_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::modf_Type() { +static const TypeFunc* make_modf_Type() { const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = Type::FLOAT; fields[TypeFunc::Parms+1] = Type::FLOAT; @@ -724,7 +762,7 @@ const TypeFunc* OptoRuntime::modf_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::Math_D_D_Type() { +static const TypeFunc* make_Math_D_D_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); // Symbol* name of class to be loaded @@ -741,7 +779,7 @@ const TypeFunc *OptoRuntime::Math_D_D_Type() { return TypeFunc::make(domain, range); } -const TypeFunc *OptoRuntime::Math_Vector_Vector_Type(uint num_arg, const TypeVect* in_type, const TypeVect* out_type) { +const TypeFunc* OptoRuntime::Math_Vector_Vector_Type(uint num_arg, const TypeVect* in_type, const TypeVect* out_type) { // create input type (domain) const Type **fields = TypeTuple::fields(num_arg); // Symbol* name of class to be loaded @@ -760,7 +798,7 @@ const TypeFunc *OptoRuntime::Math_Vector_Vector_Type(uint num_arg, const TypeVec return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::Math_DD_D_Type() { +static const TypeFunc* make_Math_DD_D_Type() { const Type **fields = TypeTuple::fields(4); fields[TypeFunc::Parms+0] = Type::DOUBLE; fields[TypeFunc::Parms+1] = Type::HALF; @@ -779,7 +817,7 @@ const TypeFunc* OptoRuntime::Math_DD_D_Type() { //-------------- currentTimeMillis, currentTimeNanos, etc -const TypeFunc* OptoRuntime::void_long_Type() { +static const TypeFunc* make_void_long_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(0); const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); @@ -793,34 +831,35 @@ const TypeFunc* OptoRuntime::void_long_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::void_void_Type() { - // create input type (domain) - const Type **fields = TypeTuple::fields(0); - const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); +static const TypeFunc* make_void_void_Type() { + // create input type (domain) + const Type **fields = TypeTuple::fields(0); + const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); - // create result type (range) - fields = TypeTuple::fields(0); - const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); - return TypeFunc::make(domain, range); - } + // create result type (range) + fields = TypeTuple::fields(0); + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); + return TypeFunc::make(domain, range); +} - const TypeFunc* OptoRuntime::jfr_write_checkpoint_Type() { - // create input type (domain) - const Type **fields = TypeTuple::fields(0); - const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields); +static const TypeFunc* make_jfr_write_checkpoint_Type() { + // create input type (domain) + const Type **fields = TypeTuple::fields(0); + const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields); - // create result type (range) - fields = TypeTuple::fields(0); - const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); - return TypeFunc::make(domain, range); - } + // create result type (range) + fields = TypeTuple::fields(0); + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); +} // Takes as parameters: // void *dest // long size // uchar byte -const TypeFunc* OptoRuntime::make_setmemory_Type() { + +static const TypeFunc* make_setmemory_Type() { // create input type (domain) int argcnt = NOT_LP64(3) LP64_ONLY(4); const Type** fields = TypeTuple::fields(argcnt); @@ -885,29 +924,7 @@ static const TypeFunc* make_arraycopy_Type(ArrayCopyType act) { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::fast_arraycopy_Type() { - // This signature is simple: Two base pointers and a size_t. - return make_arraycopy_Type(ac_fast); -} - -const TypeFunc* OptoRuntime::checkcast_arraycopy_Type() { - // An extension of fast_arraycopy_Type which adds type checking. - return make_arraycopy_Type(ac_checkcast); -} - -const TypeFunc* OptoRuntime::slow_arraycopy_Type() { - // This signature is exactly the same as System.arraycopy. - // There are no intptr_t (int/long) arguments. - return make_arraycopy_Type(ac_slow); -} - -const TypeFunc* OptoRuntime::generic_arraycopy_Type() { - // This signature is like System.arraycopy, except that it returns status. - return make_arraycopy_Type(ac_generic); -} - - -const TypeFunc* OptoRuntime::array_fill_Type() { +static const TypeFunc* make_array_fill_Type() { const Type** fields; int argp = TypeFunc::Parms; // create input type (domain): pointer, int, size_t @@ -926,7 +943,7 @@ const TypeFunc* OptoRuntime::array_fill_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::array_partition_Type() { +static const TypeFunc* make_array_partition_Type() { // create input type (domain) int num_args = 7; int argcnt = num_args; @@ -949,7 +966,7 @@ const TypeFunc* OptoRuntime::array_partition_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::array_sort_Type() { +static const TypeFunc* make_array_sort_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; @@ -969,8 +986,7 @@ const TypeFunc* OptoRuntime::array_sort_Type() { return TypeFunc::make(domain, range); } -// for aescrypt encrypt/decrypt operations, just three pointers returning void (length is constant) -const TypeFunc* OptoRuntime::aescrypt_block_Type() { +static const TypeFunc* make_aescrypt_block_Type() { // create input type (domain) int num_args = 3; int argcnt = num_args; @@ -989,10 +1005,7 @@ const TypeFunc* OptoRuntime::aescrypt_block_Type() { return TypeFunc::make(domain, range); } -/** - * int updateBytesCRC32(int crc, byte* b, int len) - */ -const TypeFunc* OptoRuntime::updateBytesCRC32_Type() { +static const TypeFunc* make_updateBytesCRC32_Type() { // create input type (domain) int num_args = 3; int argcnt = num_args; @@ -1011,10 +1024,7 @@ const TypeFunc* OptoRuntime::updateBytesCRC32_Type() { return TypeFunc::make(domain, range); } -/** - * int updateBytesCRC32C(int crc, byte* buf, int len, int* table) - */ -const TypeFunc* OptoRuntime::updateBytesCRC32C_Type() { +static const TypeFunc* make_updateBytesCRC32C_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; @@ -1034,10 +1044,7 @@ const TypeFunc* OptoRuntime::updateBytesCRC32C_Type() { return TypeFunc::make(domain, range); } -/** -* int updateBytesAdler32(int adler, bytes* b, int off, int len) -*/ -const TypeFunc* OptoRuntime::updateBytesAdler32_Type() { +static const TypeFunc* make_updateBytesAdler32_Type() { // create input type (domain) int num_args = 3; int argcnt = num_args; @@ -1056,8 +1063,7 @@ const TypeFunc* OptoRuntime::updateBytesAdler32_Type() { return TypeFunc::make(domain, range); } -// for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning int -const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() { +static const TypeFunc* make_cipherBlockChaining_aescrypt_Type() { // create input type (domain) int num_args = 5; int argcnt = num_args; @@ -1078,8 +1084,7 @@ const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() { return TypeFunc::make(domain, range); } -// for electronicCodeBook calls of aescrypt encrypt/decrypt, three pointers and a length, returning int -const TypeFunc* OptoRuntime::electronicCodeBook_aescrypt_Type() { +static const TypeFunc* make_electronicCodeBook_aescrypt_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; @@ -1099,8 +1104,7 @@ const TypeFunc* OptoRuntime::electronicCodeBook_aescrypt_Type() { return TypeFunc::make(domain, range); } -//for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int -const TypeFunc* OptoRuntime::counterMode_aescrypt_Type() { +static const TypeFunc* make_counterMode_aescrypt_Type() { // create input type (domain) int num_args = 7; int argcnt = num_args; @@ -1122,8 +1126,7 @@ const TypeFunc* OptoRuntime::counterMode_aescrypt_Type() { return TypeFunc::make(domain, range); } -//for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int -const TypeFunc* OptoRuntime::galoisCounterMode_aescrypt_Type() { +static const TypeFunc* make_galoisCounterMode_aescrypt_Type() { // create input type (domain) int num_args = 8; int argcnt = num_args; @@ -1147,10 +1150,7 @@ const TypeFunc* OptoRuntime::galoisCounterMode_aescrypt_Type() { return TypeFunc::make(domain, range); } -/* - * void implCompress(byte[] buf, int ofs) - */ -const TypeFunc* OptoRuntime::digestBase_implCompress_Type(bool is_sha3) { +static const TypeFunc* make_digestBase_implCompress_Type(bool is_sha3) { // create input type (domain) int num_args = is_sha3 ? 3 : 2; int argcnt = num_args; @@ -1169,10 +1169,7 @@ const TypeFunc* OptoRuntime::digestBase_implCompress_Type(bool is_sha3) { return TypeFunc::make(domain, range); } -/* - * int implCompressMultiBlock(byte[] b, int ofs, int limit) - */ -const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type(bool is_sha3) { +static const TypeFunc* make_digestBase_implCompressMB_Type(bool is_sha3) { // create input type (domain) int num_args = is_sha3 ? 5 : 4; int argcnt = num_args; @@ -1193,7 +1190,7 @@ const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type(bool is_sha3) { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::multiplyToLen_Type() { +static const TypeFunc* make_multiplyToLen_Type() { // create input type (domain) int num_args = 5; int argcnt = num_args; @@ -1214,7 +1211,7 @@ const TypeFunc* OptoRuntime::multiplyToLen_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::squareToLen_Type() { +static const TypeFunc* make_squareToLen_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; @@ -1234,8 +1231,7 @@ const TypeFunc* OptoRuntime::squareToLen_Type() { return TypeFunc::make(domain, range); } -// for mulAdd calls, 2 pointers and 3 ints, returning int -const TypeFunc* OptoRuntime::mulAdd_Type() { +static const TypeFunc* make_mulAdd_Type() { // create input type (domain) int num_args = 5; int argcnt = num_args; @@ -1256,7 +1252,7 @@ const TypeFunc* OptoRuntime::mulAdd_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::montgomeryMultiply_Type() { +static const TypeFunc* make_montgomeryMultiply_Type() { // create input type (domain) int num_args = 7; int argcnt = num_args; @@ -1280,7 +1276,7 @@ const TypeFunc* OptoRuntime::montgomeryMultiply_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::montgomerySquare_Type() { +static const TypeFunc* make_montgomerySquare_Type() { // create input type (domain) int num_args = 6; int argcnt = num_args; @@ -1303,7 +1299,7 @@ const TypeFunc* OptoRuntime::montgomerySquare_Type() { return TypeFunc::make(domain, range); } -const TypeFunc * OptoRuntime::bigIntegerShift_Type() { +static const TypeFunc* make_bigIntegerShift_Type() { int argcnt = 5; const Type** fields = TypeTuple::fields(argcnt); int argp = TypeFunc::Parms; @@ -1322,7 +1318,7 @@ const TypeFunc * OptoRuntime::bigIntegerShift_Type() { return TypeFunc::make(domain, range); } -const TypeFunc* OptoRuntime::vectorizedMismatch_Type() { +static const TypeFunc* make_vectorizedMismatch_Type() { // create input type (domain) int num_args = 4; int argcnt = num_args; @@ -1342,47 +1338,44 @@ const TypeFunc* OptoRuntime::vectorizedMismatch_Type() { return TypeFunc::make(domain, range); } -// GHASH block processing -const TypeFunc* OptoRuntime::ghash_processBlocks_Type() { - int argcnt = 4; +static const TypeFunc* make_ghash_processBlocks_Type() { + int argcnt = 4; - const Type** fields = TypeTuple::fields(argcnt); - int argp = TypeFunc::Parms; - fields[argp++] = TypePtr::NOTNULL; // state - fields[argp++] = TypePtr::NOTNULL; // subkeyH - fields[argp++] = TypePtr::NOTNULL; // data - fields[argp++] = TypeInt::INT; // blocks - assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); - const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypePtr::NOTNULL; // subkeyH + fields[argp++] = TypePtr::NOTNULL; // data + fields[argp++] = TypeInt::INT; // blocks + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); - // result type needed - fields = TypeTuple::fields(1); - fields[TypeFunc::Parms+0] = nullptr; // void - const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); - return TypeFunc::make(domain, range); + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = nullptr; // void + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); + return TypeFunc::make(domain, range); } -// ChaCha20 Block function -const TypeFunc* OptoRuntime::chacha20Block_Type() { - int argcnt = 2; +static const TypeFunc* make_chacha20Block_Type() { + int argcnt = 2; - const Type** fields = TypeTuple::fields(argcnt); - int argp = TypeFunc::Parms; - fields[argp++] = TypePtr::NOTNULL; // state - fields[argp++] = TypePtr::NOTNULL; // result + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypePtr::NOTNULL; // state + fields[argp++] = TypePtr::NOTNULL; // result - assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); - const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); + assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); - // result type needed - fields = TypeTuple::fields(1); - fields[TypeFunc::Parms + 0] = TypeInt::INT; // key stream outlen as int - const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); - return TypeFunc::make(domain, range); + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms + 0] = TypeInt::INT; // key stream outlen as int + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); + return TypeFunc::make(domain, range); } -// Base64 encode function -const TypeFunc* OptoRuntime::base64_encodeBlock_Type() { +static const TypeFunc* make_base64_encodeBlock_Type() { int argcnt = 6; const Type** fields = TypeTuple::fields(argcnt); @@ -1403,8 +1396,7 @@ const TypeFunc* OptoRuntime::base64_encodeBlock_Type() { return TypeFunc::make(domain, range); } -// String IndexOf function -const TypeFunc* OptoRuntime::string_IndexOf_Type() { +static const TypeFunc* make_string_IndexOf_Type() { int argcnt = 4; const Type** fields = TypeTuple::fields(argcnt); @@ -1423,8 +1415,7 @@ const TypeFunc* OptoRuntime::string_IndexOf_Type() { return TypeFunc::make(domain, range); } -// Base64 decode function -const TypeFunc* OptoRuntime::base64_decodeBlock_Type() { +static const TypeFunc* make_base64_decodeBlock_Type() { int argcnt = 7; const Type** fields = TypeTuple::fields(argcnt); @@ -1446,8 +1437,7 @@ const TypeFunc* OptoRuntime::base64_decodeBlock_Type() { return TypeFunc::make(domain, range); } -// Poly1305 processMultipleBlocks function -const TypeFunc* OptoRuntime::poly1305_processBlocks_Type() { +static const TypeFunc* make_poly1305_processBlocks_Type() { int argcnt = 4; const Type** fields = TypeTuple::fields(argcnt); @@ -1466,8 +1456,7 @@ const TypeFunc* OptoRuntime::poly1305_processBlocks_Type() { return TypeFunc::make(domain, range); } -// MontgomeryIntegerPolynomialP256 multiply function -const TypeFunc* OptoRuntime::intpoly_montgomeryMult_P256_Type() { +static const TypeFunc* make_intpoly_montgomeryMult_P256_Type() { int argcnt = 3; const Type** fields = TypeTuple::fields(argcnt); @@ -1485,8 +1474,7 @@ const TypeFunc* OptoRuntime::intpoly_montgomeryMult_P256_Type() { return TypeFunc::make(domain, range); } -// IntegerPolynomial constant time assignment function -const TypeFunc* OptoRuntime::intpoly_assign_Type() { +static const TypeFunc* make_intpoly_assign_Type() { int argcnt = 4; const Type** fields = TypeTuple::fields(argcnt); @@ -1505,8 +1493,8 @@ const TypeFunc* OptoRuntime::intpoly_assign_Type() { return TypeFunc::make(domain, range); } -//------------- Interpreter state access for on stack replacement -const TypeFunc* OptoRuntime::osr_end_Type() { +//------------- Interpreter state for on stack replacement +static const TypeFunc* make_osr_end_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // OSR temp buf @@ -1752,8 +1740,7 @@ address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address r return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc); } - -const TypeFunc *OptoRuntime::rethrow_Type() { +static const TypeFunc* make_rethrow_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop @@ -1803,8 +1790,7 @@ bool OptoRuntime::is_deoptimized_caller_frame(JavaThread *thread) { return caller_frame.is_deoptimized_frame(); } - -const TypeFunc *OptoRuntime::register_finalizer_Type() { +static const TypeFunc* make_register_finalizer_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver @@ -1821,7 +1807,7 @@ const TypeFunc *OptoRuntime::register_finalizer_Type() { } #if INCLUDE_JFR -const TypeFunc *OptoRuntime::class_id_load_barrier_Type() { +static const TypeFunc* make_class_id_load_barrier_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS; @@ -1834,11 +1820,10 @@ const TypeFunc *OptoRuntime::class_id_load_barrier_Type() { return TypeFunc::make(domain,range); } -#endif +#endif // INCLUDE_JFR //----------------------------------------------------------------------------- -// Dtrace support. entry and exit probes have the same signature -const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { +static const TypeFunc* make_dtrace_method_entry_exit_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage @@ -1853,7 +1838,7 @@ const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { return TypeFunc::make(domain,range); } -const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { +static const TypeFunc* make_dtrace_object_alloc_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage @@ -1869,7 +1854,6 @@ const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { return TypeFunc::make(domain,range); } - JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current)) assert(oopDesc::is_oop(obj), "must be a valid oop"); assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); @@ -1955,6 +1939,75 @@ NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCount return c; } +void OptoRuntime::initialize_types() { + _new_instance_Type = make_new_instance_Type(); + _new_array_Type = make_new_array_Type(); + _multianewarray2_Type = multianewarray_Type(2); + _multianewarray3_Type = multianewarray_Type(3); + _multianewarray4_Type = multianewarray_Type(4); + _multianewarray5_Type = multianewarray_Type(5); + _multianewarrayN_Type = make_multianewarrayN_Type(); + _complete_monitor_enter_Type = make_complete_monitor_enter_Type(); + _complete_monitor_exit_Type = make_complete_monitor_exit_Type(); + _monitor_notify_Type = make_monitor_notify_Type(); + _uncommon_trap_Type = make_uncommon_trap_Type(); + _athrow_Type = make_athrow_Type(); + _rethrow_Type = make_rethrow_Type(); + _Math_D_D_Type = make_Math_D_D_Type(); + _Math_DD_D_Type = make_Math_DD_D_Type(); + _modf_Type = make_modf_Type(); + _l2f_Type = make_l2f_Type(); + _void_long_Type = make_void_long_Type(); + _void_void_Type = make_void_void_Type(); + _jfr_write_checkpoint_Type = make_jfr_write_checkpoint_Type(); + _flush_windows_Type = make_flush_windows_Type(); + _fast_arraycopy_Type = make_arraycopy_Type(ac_fast); + _checkcast_arraycopy_Type = make_arraycopy_Type(ac_checkcast); + _generic_arraycopy_Type = make_arraycopy_Type(ac_generic); + _slow_arraycopy_Type = make_arraycopy_Type(ac_slow); + _unsafe_setmemory_Type = make_setmemory_Type(); + _array_fill_Type = make_array_fill_Type(); + _array_sort_Type = make_array_sort_Type(); + _array_partition_Type = make_array_partition_Type(); + _aescrypt_block_Type = make_aescrypt_block_Type(); + _cipherBlockChaining_aescrypt_Type = make_cipherBlockChaining_aescrypt_Type(); + _electronicCodeBook_aescrypt_Type = make_electronicCodeBook_aescrypt_Type(); + _counterMode_aescrypt_Type = make_counterMode_aescrypt_Type(); + _galoisCounterMode_aescrypt_Type = make_galoisCounterMode_aescrypt_Type(); + _digestBase_implCompress_with_sha3_Type = make_digestBase_implCompress_Type( /* is_sha3= */ true); + _digestBase_implCompress_without_sha3_Type = make_digestBase_implCompress_Type( /* is_sha3= */ false);; + _digestBase_implCompressMB_with_sha3_Type = make_digestBase_implCompressMB_Type(/* is_sha3= */ true); + _digestBase_implCompressMB_without_sha3_Type = make_digestBase_implCompressMB_Type(/* is_sha3= */ false); + _multiplyToLen_Type = make_multiplyToLen_Type(); + _montgomeryMultiply_Type = make_montgomeryMultiply_Type(); + _montgomerySquare_Type = make_montgomerySquare_Type(); + _squareToLen_Type = make_squareToLen_Type(); + _mulAdd_Type = make_mulAdd_Type(); + _bigIntegerShift_Type = make_bigIntegerShift_Type(); + _vectorizedMismatch_Type = make_vectorizedMismatch_Type(); + _ghash_processBlocks_Type = make_ghash_processBlocks_Type(); + _chacha20Block_Type = make_chacha20Block_Type(); + _base64_encodeBlock_Type = make_base64_encodeBlock_Type(); + _base64_decodeBlock_Type = make_base64_decodeBlock_Type(); + _string_IndexOf_Type = make_string_IndexOf_Type(); + _poly1305_processBlocks_Type = make_poly1305_processBlocks_Type(); + _intpoly_montgomeryMult_P256_Type = make_intpoly_montgomeryMult_P256_Type(); + _intpoly_assign_Type = make_intpoly_assign_Type(); + _updateBytesCRC32_Type = make_updateBytesCRC32_Type(); + _updateBytesCRC32C_Type = make_updateBytesCRC32C_Type(); + _updateBytesAdler32_Type = make_updateBytesAdler32_Type(); + _osr_end_Type = make_osr_end_Type(); + _register_finalizer_Type = make_register_finalizer_Type(); + JFR_ONLY( + _class_id_load_barrier_Type = make_class_id_load_barrier_Type(); + ) +#if INCLUDE_JVMTI + _notify_jvmti_vthread_Type = make_notify_jvmti_vthread_Type(); +#endif // INCLUDE_JVMTI + _dtrace_method_entry_exit_Type = make_dtrace_method_entry_exit_Type(); + _dtrace_object_alloc_Type = make_dtrace_object_alloc_Type(); +} + int trace_exception_counter = 0; static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) { trace_exception_counter++; diff --git a/src/hotspot/share/opto/runtime.hpp b/src/hotspot/share/opto/runtime.hpp index dc608cf746a73..fceece73f6603 100644 --- a/src/hotspot/share/opto/runtime.hpp +++ b/src/hotspot/share/opto/runtime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,6 +131,74 @@ class OptoRuntime : public AllStatic { #undef C2_STUB_FIELD_DECLARE #undef C2_JVMTI_STUB_FIELD_DECLARE + // static TypeFunc* data members + static const TypeFunc* _new_instance_Type; + static const TypeFunc* _new_array_Type; + static const TypeFunc* _multianewarray2_Type; + static const TypeFunc* _multianewarray3_Type; + static const TypeFunc* _multianewarray4_Type; + static const TypeFunc* _multianewarray5_Type; + static const TypeFunc* _multianewarrayN_Type; + static const TypeFunc* _complete_monitor_enter_Type; + static const TypeFunc* _complete_monitor_exit_Type; + static const TypeFunc* _monitor_notify_Type; + static const TypeFunc* _uncommon_trap_Type; + static const TypeFunc* _athrow_Type; + static const TypeFunc* _rethrow_Type; + static const TypeFunc* _Math_D_D_Type; + static const TypeFunc* _Math_DD_D_Type; + static const TypeFunc* _modf_Type; + static const TypeFunc* _l2f_Type; + static const TypeFunc* _void_long_Type; + static const TypeFunc* _void_void_Type; + static const TypeFunc* _jfr_write_checkpoint_Type; + static const TypeFunc* _flush_windows_Type; + static const TypeFunc* _fast_arraycopy_Type; + static const TypeFunc* _checkcast_arraycopy_Type; + static const TypeFunc* _generic_arraycopy_Type; + static const TypeFunc* _slow_arraycopy_Type; + static const TypeFunc* _unsafe_setmemory_Type; + static const TypeFunc* _array_fill_Type; + static const TypeFunc* _array_sort_Type; + static const TypeFunc* _array_partition_Type; + static const TypeFunc* _aescrypt_block_Type; + static const TypeFunc* _cipherBlockChaining_aescrypt_Type; + static const TypeFunc* _electronicCodeBook_aescrypt_Type; + static const TypeFunc* _counterMode_aescrypt_Type; + static const TypeFunc* _galoisCounterMode_aescrypt_Type; + static const TypeFunc* _digestBase_implCompress_with_sha3_Type; + static const TypeFunc* _digestBase_implCompress_without_sha3_Type; + static const TypeFunc* _digestBase_implCompressMB_with_sha3_Type; + static const TypeFunc* _digestBase_implCompressMB_without_sha3_Type; + static const TypeFunc* _multiplyToLen_Type; + static const TypeFunc* _montgomeryMultiply_Type; + static const TypeFunc* _montgomerySquare_Type; + static const TypeFunc* _squareToLen_Type; + static const TypeFunc* _mulAdd_Type; + static const TypeFunc* _bigIntegerShift_Type; + static const TypeFunc* _vectorizedMismatch_Type; + static const TypeFunc* _ghash_processBlocks_Type; + static const TypeFunc* _chacha20Block_Type; + static const TypeFunc* _base64_encodeBlock_Type; + static const TypeFunc* _base64_decodeBlock_Type; + static const TypeFunc* _string_IndexOf_Type; + static const TypeFunc* _poly1305_processBlocks_Type; + static const TypeFunc* _intpoly_montgomeryMult_P256_Type; + static const TypeFunc* _intpoly_assign_Type; + static const TypeFunc* _updateBytesCRC32_Type; + static const TypeFunc* _updateBytesCRC32C_Type; + static const TypeFunc* _updateBytesAdler32_Type; + static const TypeFunc* _osr_end_Type; + static const TypeFunc* _register_finalizer_Type; +#if INCLUDE_JFR + static const TypeFunc* _class_id_load_barrier_Type; +#endif // INCLUDE_JFR +#if INCLUDE_JVMTI + static const TypeFunc* _notify_jvmti_vthread_Type; +#endif // INCLUDE_JVMTI + static const TypeFunc* _dtrace_method_entry_exit_Type; + static const TypeFunc* _dtrace_object_alloc_Type; + // Stub names indexed by sharedStubId static const char *_stub_names[]; @@ -242,95 +310,365 @@ class OptoRuntime : public AllStatic { // Type functions // ====================================================== - static const TypeFunc* new_instance_Type(); // object allocation (slow case) - static const TypeFunc* new_array_Type (); // [a]newarray (slow case) - static const TypeFunc* new_array_nozero_Type (); // [a]newarray (slow case) + static inline const TypeFunc* new_instance_Type() { + assert(_new_instance_Type != nullptr, "should be initialized"); + return _new_instance_Type; + } + + static inline const TypeFunc* new_array_Type() { + assert(_new_array_Type != nullptr, "should be initialized"); + return _new_array_Type; + } + + static inline const TypeFunc* new_array_nozero_Type() { + return new_array_Type(); + } + static const TypeFunc* multianewarray_Type(int ndim); // multianewarray - static const TypeFunc* multianewarray2_Type(); // multianewarray - static const TypeFunc* multianewarray3_Type(); // multianewarray - static const TypeFunc* multianewarray4_Type(); // multianewarray - static const TypeFunc* multianewarray5_Type(); // multianewarray - static const TypeFunc* multianewarrayN_Type(); // multianewarray - static const TypeFunc* complete_monitor_enter_Type(); - static const TypeFunc* complete_monitor_locking_Type(); - static const TypeFunc* complete_monitor_exit_Type(); - static const TypeFunc* monitor_notify_Type(); - static const TypeFunc* monitor_notifyAll_Type(); - static const TypeFunc* uncommon_trap_Type(); - static const TypeFunc* athrow_Type(); - static const TypeFunc* rethrow_Type(); - static const TypeFunc* Math_D_D_Type(); // sin,cos & friends - static const TypeFunc* Math_DD_D_Type(); // mod,pow & friends + + static inline const TypeFunc* multianewarray2_Type() { + assert(_multianewarray2_Type != nullptr, "should be initialized"); + return _multianewarray2_Type; + } + + static inline const TypeFunc* multianewarray3_Type() { + assert(_multianewarray3_Type != nullptr, "should be initialized"); + return _multianewarray3_Type; + } + + static inline const TypeFunc* multianewarray4_Type() { + assert(_multianewarray4_Type != nullptr, "should be initialized"); + return _multianewarray4_Type; + } + + static inline const TypeFunc* multianewarray5_Type() { + assert(_multianewarray5_Type != nullptr, "should be initialized"); + return _multianewarray5_Type; + } + + static inline const TypeFunc* multianewarrayN_Type() { + assert(_multianewarrayN_Type != nullptr, "should be initialized"); + return _multianewarrayN_Type; + } + + static inline const TypeFunc* complete_monitor_enter_Type() { + assert(_complete_monitor_enter_Type != nullptr, "should be initialized"); + return _complete_monitor_enter_Type; + } + + static inline const TypeFunc* complete_monitor_locking_Type() { + return complete_monitor_enter_Type(); + } + + static inline const TypeFunc* complete_monitor_exit_Type() { + assert(_complete_monitor_exit_Type != nullptr, "should be initialized"); + return _complete_monitor_exit_Type; + } + + static inline const TypeFunc* monitor_notify_Type() { + assert(_monitor_notify_Type != nullptr, "should be initialized"); + return _monitor_notify_Type; + } + + static inline const TypeFunc* monitor_notifyAll_Type() { + return monitor_notify_Type(); + } + + static inline const TypeFunc* uncommon_trap_Type() { + assert(_uncommon_trap_Type != nullptr, "should be initialized"); + return _uncommon_trap_Type; + } + + static inline const TypeFunc* athrow_Type() { + assert(_athrow_Type != nullptr, "should be initialized"); + return _athrow_Type; + } + + static inline const TypeFunc* rethrow_Type() { + assert(_rethrow_Type != nullptr, "should be initialized"); + return _rethrow_Type; + } + + static inline const TypeFunc* Math_D_D_Type() { + assert(_Math_D_D_Type != nullptr, "should be initialized"); + return _Math_D_D_Type; + } + + static inline const TypeFunc* Math_DD_D_Type() { + assert(_Math_DD_D_Type != nullptr, "should be initialized"); + return _Math_DD_D_Type; + } + static const TypeFunc* Math_Vector_Vector_Type(uint num_arg, const TypeVect* in_type, const TypeVect* out_type); - static const TypeFunc* modf_Type(); - static const TypeFunc* l2f_Type(); - static const TypeFunc* void_long_Type(); - static const TypeFunc* void_void_Type(); - static const TypeFunc* jfr_write_checkpoint_Type(); + static inline const TypeFunc* modf_Type() { + assert(_modf_Type != nullptr, "should be initialized"); + return _modf_Type; + } - static const TypeFunc* flush_windows_Type(); + static inline const TypeFunc* l2f_Type() { + assert(_l2f_Type != nullptr, "should be initialized"); + return _l2f_Type; + } + + static inline const TypeFunc* void_long_Type() { + assert(_void_long_Type != nullptr, "should be initialized"); + return _void_long_Type; + } + + static inline const TypeFunc* void_void_Type() { + assert(_void_void_Type != nullptr, "should be initialized"); + return _void_void_Type; + } + + static const TypeFunc* jfr_write_checkpoint_Type() { + assert(_jfr_write_checkpoint_Type != nullptr, "should be initialized"); + return _jfr_write_checkpoint_Type; + } + + static const TypeFunc* flush_windows_Type() { + assert(_flush_windows_Type != nullptr, "should be initialized"); + return _flush_windows_Type; + } // arraycopy routine types - static const TypeFunc* fast_arraycopy_Type(); // bit-blasters - static const TypeFunc* checkcast_arraycopy_Type(); - static const TypeFunc* generic_arraycopy_Type(); - static const TypeFunc* slow_arraycopy_Type(); // the full routine + static inline const TypeFunc* fast_arraycopy_Type() { + assert(_fast_arraycopy_Type != nullptr, "should be initialized"); + // This signature is simple: Two base pointers and a size_t. + return _fast_arraycopy_Type; + } + + static inline const TypeFunc* checkcast_arraycopy_Type() { + assert(_checkcast_arraycopy_Type != nullptr, "should be initialized"); + // An extension of fast_arraycopy_Type which adds type checking. + return _checkcast_arraycopy_Type; + } + + static inline const TypeFunc* generic_arraycopy_Type() { + assert(_generic_arraycopy_Type != nullptr, "should be initialized"); + // This signature is like System.arraycopy, except that it returns status. + return _generic_arraycopy_Type; + } + + static inline const TypeFunc* slow_arraycopy_Type() { + assert(_slow_arraycopy_Type != nullptr, "should be initialized"); + // This signature is exactly the same as System.arraycopy. + // There are no intptr_t (int/long) arguments. + return _slow_arraycopy_Type; + } // the full routine - static const TypeFunc* make_setmemory_Type(); + static inline const TypeFunc* unsafe_setmemory_Type() { + assert(_unsafe_setmemory_Type != nullptr, "should be initialized"); + return _unsafe_setmemory_Type; + } + + static inline const TypeFunc* array_fill_Type() { + assert(_array_fill_Type != nullptr, "should be initialized"); + return _array_fill_Type; + } + + static inline const TypeFunc* array_sort_Type() { + assert(_array_sort_Type != nullptr, "should be initialized"); + return _array_sort_Type; + } + + static inline const TypeFunc* array_partition_Type() { + assert(_array_partition_Type != nullptr, "should be initialized"); + return _array_partition_Type; + } + + // for aescrypt encrypt/decrypt operations, just three pointers returning void (length is constant) + static inline const TypeFunc* aescrypt_block_Type() { + assert(_aescrypt_block_Type != nullptr, "should be initialized"); + return _aescrypt_block_Type; + } + + // for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning int + static inline const TypeFunc* cipherBlockChaining_aescrypt_Type() { + assert(_cipherBlockChaining_aescrypt_Type != nullptr, "should be initialized"); + return _cipherBlockChaining_aescrypt_Type; + } + + // for electronicCodeBook calls of aescrypt encrypt/decrypt, three pointers and a length, returning int + static inline const TypeFunc* electronicCodeBook_aescrypt_Type() { + assert(_electronicCodeBook_aescrypt_Type != nullptr, "should be initialized"); + return _electronicCodeBook_aescrypt_Type; + } + + //for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int + static inline const TypeFunc* counterMode_aescrypt_Type() { + assert(_counterMode_aescrypt_Type != nullptr, "should be initialized"); + return _counterMode_aescrypt_Type; + } - static const TypeFunc* array_fill_Type(); + //for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int + static inline const TypeFunc* galoisCounterMode_aescrypt_Type() { + assert(_galoisCounterMode_aescrypt_Type != nullptr, "should be initialized"); + return _galoisCounterMode_aescrypt_Type; + } - static const TypeFunc* array_sort_Type(); - static const TypeFunc* array_partition_Type(); - static const TypeFunc* aescrypt_block_Type(); - static const TypeFunc* cipherBlockChaining_aescrypt_Type(); - static const TypeFunc* electronicCodeBook_aescrypt_Type(); - static const TypeFunc* counterMode_aescrypt_Type(); - static const TypeFunc* galoisCounterMode_aescrypt_Type(); + /* + * void implCompress(byte[] buf, int ofs) + */ + static inline const TypeFunc* digestBase_implCompress_Type(bool is_sha3) { + assert((_digestBase_implCompress_with_sha3_Type != nullptr) && + (_digestBase_implCompress_without_sha3_Type != nullptr), "should be initialized"); + return is_sha3 ? _digestBase_implCompress_with_sha3_Type : _digestBase_implCompress_without_sha3_Type; + } - static const TypeFunc* digestBase_implCompress_Type(bool is_sha3); - static const TypeFunc* digestBase_implCompressMB_Type(bool is_sha3); + /* + * int implCompressMultiBlock(byte[] b, int ofs, int limit) + */ + static inline const TypeFunc* digestBase_implCompressMB_Type(bool is_sha3) { + assert((_digestBase_implCompressMB_with_sha3_Type != nullptr) && + (_digestBase_implCompressMB_without_sha3_Type != nullptr), "should be initialized"); + return is_sha3 ? _digestBase_implCompressMB_with_sha3_Type : _digestBase_implCompressMB_without_sha3_Type; + } - static const TypeFunc* multiplyToLen_Type(); - static const TypeFunc* montgomeryMultiply_Type(); - static const TypeFunc* montgomerySquare_Type(); + static inline const TypeFunc* multiplyToLen_Type() { + assert(_multiplyToLen_Type != nullptr, "should be initialized"); + return _multiplyToLen_Type; + } + + static inline const TypeFunc* montgomeryMultiply_Type() { + assert(_montgomeryMultiply_Type != nullptr, "should be initialized"); + return _montgomeryMultiply_Type; + } - static const TypeFunc* squareToLen_Type(); + static inline const TypeFunc* montgomerySquare_Type() { + assert(_montgomerySquare_Type != nullptr, "should be initialized"); + return _montgomerySquare_Type; + } - static const TypeFunc* mulAdd_Type(); + static inline const TypeFunc* squareToLen_Type() { + assert(_squareToLen_Type != nullptr, "should be initialized"); + return _squareToLen_Type; + } - static const TypeFunc* bigIntegerShift_Type(); + // for mulAdd calls, 2 pointers and 3 ints, returning int + static inline const TypeFunc* mulAdd_Type() { + assert(_mulAdd_Type != nullptr, "should be initialized"); + return _mulAdd_Type; + } - static const TypeFunc* vectorizedMismatch_Type(); + static inline const TypeFunc* bigIntegerShift_Type() { + assert(_bigIntegerShift_Type != nullptr, "should be initialized"); + return _bigIntegerShift_Type; + } - static const TypeFunc* ghash_processBlocks_Type(); - static const TypeFunc* chacha20Block_Type(); - static const TypeFunc* base64_encodeBlock_Type(); - static const TypeFunc* base64_decodeBlock_Type(); - static const TypeFunc* string_IndexOf_Type(); - static const TypeFunc* poly1305_processBlocks_Type(); - static const TypeFunc* intpoly_montgomeryMult_P256_Type(); - static const TypeFunc* intpoly_assign_Type(); + static inline const TypeFunc* vectorizedMismatch_Type() { + assert(_vectorizedMismatch_Type != nullptr, "should be initialized"); + return _vectorizedMismatch_Type; + } - static const TypeFunc* updateBytesCRC32_Type(); - static const TypeFunc* updateBytesCRC32C_Type(); + // GHASH block processing + static inline const TypeFunc* ghash_processBlocks_Type() { + assert(_ghash_processBlocks_Type != nullptr, "should be initialized"); + return _ghash_processBlocks_Type; + } + + // ChaCha20 Block function + static inline const TypeFunc* chacha20Block_Type() { + assert(_chacha20Block_Type != nullptr, "should be initialized"); + return _chacha20Block_Type; + } + + // Base64 encode function + static inline const TypeFunc* base64_encodeBlock_Type() { + assert(_base64_encodeBlock_Type != nullptr, "should be initialized"); + return _base64_encodeBlock_Type; + } + + // Base64 decode function + static inline const TypeFunc* base64_decodeBlock_Type() { + assert(_base64_decodeBlock_Type != nullptr, "should be initialized"); + return _base64_decodeBlock_Type; + } + + // String IndexOf function + static inline const TypeFunc* string_IndexOf_Type() { + assert(_string_IndexOf_Type != nullptr, "should be initialized"); + return _string_IndexOf_Type; + } + + // Poly1305 processMultipleBlocks function + static inline const TypeFunc* poly1305_processBlocks_Type() { + assert(_poly1305_processBlocks_Type != nullptr, "should be initialized"); + return _poly1305_processBlocks_Type; + } + + // MontgomeryIntegerPolynomialP256 multiply function + static inline const TypeFunc* intpoly_montgomeryMult_P256_Type() { + assert(_intpoly_montgomeryMult_P256_Type != nullptr, "should be initialized"); + return _intpoly_montgomeryMult_P256_Type; + } + + // IntegerPolynomial constant time assignment function + static inline const TypeFunc* intpoly_assign_Type() { + assert(_intpoly_assign_Type != nullptr, "should be initialized"); + return _intpoly_assign_Type; + } + + /** + * int updateBytesCRC32(int crc, byte* b, int len) + */ + static inline const TypeFunc* updateBytesCRC32_Type() { + assert(_updateBytesCRC32_Type != nullptr, "should be initialized"); + return _updateBytesCRC32_Type; + } + + /** + * int updateBytesCRC32C(int crc, byte* buf, int len, int* table) + */ + static inline const TypeFunc* updateBytesCRC32C_Type() { + assert(_updateBytesCRC32C_Type != nullptr, "should be initialized"); + return _updateBytesCRC32C_Type; + } + + /** + * int updateBytesAdler32(int adler, bytes* b, int off, int len) + */ + static inline const TypeFunc* updateBytesAdler32_Type() { + assert(_updateBytesAdler32_Type != nullptr, "should be initialized"); + return _updateBytesAdler32_Type; + } - static const TypeFunc* updateBytesAdler32_Type(); // leaf on stack replacement interpreter accessor types - static const TypeFunc* osr_end_Type(); + static inline const TypeFunc* osr_end_Type() { + assert(_osr_end_Type != nullptr, "should be initialized"); + return _osr_end_Type; + } - static const TypeFunc* register_finalizer_Type(); + static inline const TypeFunc* register_finalizer_Type() { + assert(_register_finalizer_Type != nullptr, "should be initialized"); + return _register_finalizer_Type; + } + +#if INCLUDE_JFR + static inline const TypeFunc* class_id_load_barrier_Type() { + assert(_class_id_load_barrier_Type != nullptr, "should be initialized"); + return _class_id_load_barrier_Type; + } +#endif // INCLUDE_JFR - JFR_ONLY(static const TypeFunc* class_id_load_barrier_Type();) #if INCLUDE_JVMTI - static const TypeFunc* notify_jvmti_vthread_Type(); + static inline const TypeFunc* notify_jvmti_vthread_Type() { + assert(_notify_jvmti_vthread_Type != nullptr, "should be initialized"); + return _notify_jvmti_vthread_Type; + } #endif - // Dtrace support - static const TypeFunc* dtrace_method_entry_exit_Type(); - static const TypeFunc* dtrace_object_alloc_Type(); + // Dtrace support. entry and exit probes have the same signature + static inline const TypeFunc* dtrace_method_entry_exit_Type() { + assert(_dtrace_method_entry_exit_Type != nullptr, "should be initialized"); + return _dtrace_method_entry_exit_Type; + } + + static inline const TypeFunc* dtrace_object_alloc_Type() { + assert(_dtrace_object_alloc_Type != nullptr, "should be initialized"); + return _dtrace_object_alloc_Type; + } private: static NamedCounter * volatile _named_counters; @@ -343,6 +681,7 @@ class OptoRuntime : public AllStatic { // dumps all the named counters static void print_named_counters(); + static void initialize_types(); }; #endif // SHARE_OPTO_RUNTIME_HPP diff --git a/src/hotspot/share/opto/split_if.cpp b/src/hotspot/share/opto/split_if.cpp index a46fa5c5d86c6..d94d47591739c 100644 --- a/src/hotspot/share/opto/split_if.cpp +++ b/src/hotspot/share/opto/split_if.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" diff --git a/src/hotspot/share/opto/stringopts.cpp b/src/hotspot/share/opto/stringopts.cpp index 34267666c2a8a..793145e078d6d 100644 --- a/src/hotspot/share/opto/stringopts.cpp +++ b/src/hotspot/share/opto/stringopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciSymbols.hpp" #include "classfile/javaClasses.hpp" #include "compiler/compileLog.hpp" diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 445eb16821443..de0d2f7c8d0ee 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "compiler/compileLog.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/c2/barrierSetC2.hpp" @@ -553,6 +552,24 @@ const Type* SubFPNode::Value(PhaseGVN* phase) const { //============================================================================= +//------------------------------sub-------------------------------------------- +// A subtract node differences its two inputs. +const Type* SubHFNode::sub(const Type* t1, const Type* t2) const { + // no folding if one of operands is infinity or NaN, do not do constant folding + if(g_isfinite(t1->getf()) && g_isfinite(t2->getf())) { + return TypeH::make(t1->getf() - t2->getf()); + } + else if(g_isnan(t1->getf())) { + return t1; + } + else if(g_isnan(t2->getf())) { + return t2; + } + else { + return Type::HALF_FLOAT; + } +} + //------------------------------Ideal------------------------------------------ Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) { const Type *t2 = phase->type( in(2) ); @@ -1416,9 +1433,7 @@ Node* BoolNode::make_predicate(Node* test_value, PhaseGVN* phase) { //--------------------------------as_int_value--------------------------------- Node* BoolNode::as_int_value(PhaseGVN* phase) { // Inverse to make_predicate. The CMove probably boils down to a Conv2B. - Node* cmov = CMoveNode::make(nullptr, this, - phase->intcon(0), phase->intcon(1), - TypeInt::BOOL); + Node* cmov = CMoveNode::make(this, phase->intcon(0), phase->intcon(1), TypeInt::BOOL); return phase->transform(cmov); } @@ -1623,27 +1638,17 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { return new BoolNode( ncmp, _test.negate() ); } - // Change ((x & (m - 1)) u< m) into (m > 0) - // This is the off-by-one variant of ((x & m) u<= m) - if (cop == Op_CmpU && - _test._test == BoolTest::lt && - cmp1_op == Op_AndI) { - Node* l = cmp1->in(1); - Node* r = cmp1->in(2); - for (int repeat = 0; repeat < 2; repeat++) { - bool match = r->Opcode() == Op_AddI && r->in(2)->find_int_con(0) == -1 && - r->in(1) == cmp2; - if (match) { - // arraylength known to be non-negative, so a (arraylength != 0) is sufficient, - // but to be compatible with the array range check pattern, use (arraylength u> 0) - Node* ncmp = cmp2->Opcode() == Op_LoadRange - ? phase->transform(new CmpUNode(cmp2, phase->intcon(0))) - : phase->transform(new CmpINode(cmp2, phase->intcon(0))); - return new BoolNode(ncmp, BoolTest::gt); - } else { - // commute and try again - l = cmp1->in(2); - r = cmp1->in(1); + // Transform: "((x & (m - 1)) u 0)" + // This is case [CMPU_MASK] which is further described at the method comment of BoolNode::Value_cmpu_and_mask(). + if (cop == Op_CmpU && _test._test == BoolTest::lt && cmp1_op == Op_AndI) { + Node* m = cmp2; // RHS: m + for (int add_idx = 1; add_idx <= 2; add_idx++) { // LHS: "(m + (-1)) & x" or "x & (m + (-1))"? + Node* maybe_m_minus_1 = cmp1->in(add_idx); + if (maybe_m_minus_1->Opcode() == Op_AddI && + maybe_m_minus_1->in(2)->find_int_con(0) == -1 && + maybe_m_minus_1->in(1) == m) { + Node* m_cmpu_0 = phase->transform(new CmpUNode(m, phase->intcon(0))); + return new BoolNode(m_cmpu_0, BoolTest::gt); } } } @@ -1809,9 +1814,57 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { // } } -//------------------------------Value------------------------------------------ -// Change ((x & m) u<= m) or ((m & x) u<= m) to always true -// Same with ((x & m) u< m+1) and ((m & x) u< m+1) +// We use the following Lemmas/insights for the following two transformations (1) and (2): +// x & y <=u y, for any x and y (Lemma 1, masking always results in a smaller unsigned number) +// y u 0) +// This is the off-by-one variant of the above. +// +// We now prove that this replacement is correct. This is the same as proving +// "m >u 0" if and only if "x & (m - 1) u 0 <=> x & (m - 1) m >u 0": +// We prove this by contradiction: +// Assume m <=u 0 which is equivalent to m == 0: +// and thus +// x & (m - 1) u 0 => x & (m - 1) u 0, no underflow of "m - 1" +// +// +// Note that the signed version of "m > 0": +// m > 0 <=> x & (m - 1) 0 +// is false which is a contradiction. +// +// (1a) and (1b) is covered by this method since we can directly return a true value as type while (2) is covered +// in BoolNode::Ideal since we create a new non-constant node (see [CMPU_MASK]). const Type* BoolNode::Value_cmpu_and_mask(PhaseValues* phase) const { Node* cmp = in(1); if (cmp != nullptr && cmp->Opcode() == Op_CmpU) { @@ -1819,14 +1872,21 @@ const Type* BoolNode::Value_cmpu_and_mask(PhaseValues* phase) const { Node* cmp2 = cmp->in(2); if (cmp1->Opcode() == Op_AndI) { - Node* bound = nullptr; + Node* m = nullptr; if (_test._test == BoolTest::le) { - bound = cmp2; + // (1a) "((x & m) <=u m)", cmp2 = m + m = cmp2; } else if (_test._test == BoolTest::lt && cmp2->Opcode() == Op_AddI && cmp2->in(2)->find_int_con(0) == 1) { - bound = cmp2->in(1); + // (1b) "(x & m) in(1); + const TypeInt* rhs_m_type = phase->type(rhs_m)->isa_int(); + if (rhs_m_type->_lo > -1 || rhs_m_type->_hi < -1) { + // Exclude any case where m == -1 is possible. + m = rhs_m; + } } - if (cmp1->in(2) == bound || cmp1->in(1) == bound) { + if (cmp1->in(2) == m || cmp1->in(1) == m) { return TypeInt::ONE; } } @@ -1947,6 +2007,15 @@ const Type* SqrtFNode::Value(PhaseGVN* phase) const { return TypeF::make( (float)sqrt( (double)f ) ); } +const Type* SqrtHFNode::Value(PhaseGVN* phase) const { + const Type* t1 = phase->type(in(1)); + if (t1 == Type::TOP) { return Type::TOP; } + if (t1->base() != Type::HalfFloatCon) { return Type::HALF_FLOAT; } + float f = t1->getf(); + if (f < 0.0f) return Type::HALF_FLOAT; + return TypeH::make((float)sqrt((double)f)); +} + const Type* ReverseINode::Value(PhaseGVN* phase) const { const Type *t1 = phase->type( in(1) ); if (t1 == Type::TOP) { diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index 6ceaa851739d8..1d8aa0584240b 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,6 +130,18 @@ class SubDNode : public SubFPNode { virtual uint ideal_reg() const { return Op_RegD; } }; +//------------------------------SubHFNode-------------------------------------- +// Subtract 2 half floats +class SubHFNode : public SubFPNode { +public: + SubHFNode(Node* in1, Node* in2) : SubFPNode(in1, in2) {} + virtual int Opcode() const; + virtual const Type* sub(const Type*, const Type*) const; + const Type* add_id() const { return TypeH::ZERO; } + const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } +}; + //------------------------------CmpNode--------------------------------------- // Compare 2 values, returning condition codes (-1, 0 or 1). class CmpNode : public SubNode { @@ -528,13 +540,27 @@ class SqrtFNode : public Node { virtual const Type* Value(PhaseGVN* phase) const; }; +//------------------------------SqrtHFNode------------------------------------- +// square root of a half-precision float +class SqrtHFNode : public Node { +public: + SqrtHFNode(Compile* C, Node* c, Node* in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } + virtual int Opcode() const; + const Type* bottom_type() const { return Type::HALF_FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + virtual const Type* Value(PhaseGVN* phase) const; +}; + //-------------------------------ReverseBytesINode-------------------------------- // reverse bytes of an integer class ReverseBytesINode : public Node { public: - ReverseBytesINode(Node *c, Node *in1) : Node(c, in1) {} + ReverseBytesINode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeInt::INT; } + const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -542,9 +568,9 @@ class ReverseBytesINode : public Node { // reverse bytes of a long class ReverseBytesLNode : public Node { public: - ReverseBytesLNode(Node *c, Node *in1) : Node(c, in1) {} + ReverseBytesLNode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeLong::LONG; } + const Type* bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } }; @@ -552,9 +578,9 @@ class ReverseBytesLNode : public Node { // reverse bytes of an unsigned short / char class ReverseBytesUSNode : public Node { public: - ReverseBytesUSNode(Node *c, Node *in1) : Node(c, in1) {} + ReverseBytesUSNode(Node* in1) : Node(nullptr, in1) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeInt::CHAR; } + const Type* bottom_type() const { return TypeInt::CHAR; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -562,9 +588,9 @@ class ReverseBytesUSNode : public Node { // reverse bytes of a short class ReverseBytesSNode : public Node { public: - ReverseBytesSNode(Node *c, Node *in1) : Node(c, in1) {} + ReverseBytesSNode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeInt::SHORT; } + const Type* bottom_type() const { return TypeInt::SHORT; } virtual uint ideal_reg() const { return Op_RegI; } }; @@ -572,9 +598,9 @@ class ReverseBytesSNode : public Node { // reverse bits of an int class ReverseINode : public Node { public: - ReverseINode(Node *c, Node *in1) : Node(c, in1) {} + ReverseINode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeInt::INT; } + const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } virtual Node* Identity(PhaseGVN* phase); virtual const Type* Value(PhaseGVN* phase) const; @@ -584,9 +610,9 @@ class ReverseINode : public Node { // reverse bits of a long class ReverseLNode : public Node { public: - ReverseLNode(Node *c, Node *in1) : Node(c, in1) {} + ReverseLNode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; - const Type *bottom_type() const { return TypeLong::LONG; } + const Type* bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } virtual Node* Identity(PhaseGVN* phase); virtual const Type* Value(PhaseGVN* phase) const; diff --git a/src/hotspot/share/opto/subtypenode.cpp b/src/hotspot/share/opto/subtypenode.cpp index 3fbe06f310b9f..b58194b87d24b 100644 --- a/src/hotspot/share/opto/subtypenode.cpp +++ b/src/hotspot/share/opto/subtypenode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" #include "opto/connode.hpp" @@ -196,7 +195,7 @@ bool SubTypeCheckNode::verify(PhaseGVN* phase) { chk_off_X = phase->transform(new ConvI2LNode(chk_off_X)); #endif Node* p2 = phase->transform(new AddPNode(subklass, subklass, chk_off_X)); - Node* nkls = phase->transform(LoadKlassNode::make(*phase, nullptr, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL)); + Node* nkls = phase->transform(LoadKlassNode::make(*phase, C->immutable_memory(), p2, phase->type(p2)->is_ptr(), TypeInstKlassPtr::OBJECT_OR_NULL)); return verify_helper(phase, nkls, cached_t); } @@ -219,7 +218,7 @@ Node* SubTypeCheckNode::load_klass(PhaseGVN* phase) const { Node* subklass = nullptr; if (sub_t->isa_oopptr()) { Node* adr = phase->transform(new AddPNode(obj_or_subklass, obj_or_subklass, phase->MakeConX(oopDesc::klass_offset_in_bytes()))); - subklass = phase->transform(LoadKlassNode::make(*phase, nullptr, phase->C->immutable_memory(), adr, TypeInstPtr::KLASS)); + subklass = phase->transform(LoadKlassNode::make(*phase, phase->C->immutable_memory(), adr, TypeInstPtr::KLASS)); record_for_cleanup(subklass, phase); } else { subklass = obj_or_subklass; diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 8000e4fd39ed0..31aa1507d2303 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ * questions. */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/castnode.hpp" #include "opto/convertnode.hpp" +#include "opto/memnode.hpp" #include "opto/superword.hpp" #include "opto/superwordVTransformBuilder.hpp" #include "opto/vectornode.hpp" @@ -48,21 +48,63 @@ SuperWord::SuperWord(const VLoopAnalyzer &vloop_analyzer) : { } +// Collect ignored loop nodes during VPointer parsing. +class SuperWordUnrollingAnalysisIgnoredNodes : public MemPointerParserCallback { +private: + const VLoop& _vloop; + const Node_List& _body; + bool* _ignored; + +public: + SuperWordUnrollingAnalysisIgnoredNodes(const VLoop& vloop) : + _vloop(vloop), + _body(_vloop.lpt()->_body), + _ignored(NEW_RESOURCE_ARRAY(bool, _body.size())) + { + for (uint i = 0; i < _body.size(); i++) { + _ignored[i] = false; + } + } + + virtual void callback(Node* n) override { set_ignored(n); } + + void set_ignored(uint i) { + assert(i < _body.size(), "must be in bounds"); + _ignored[i] = true; + } + + void set_ignored(Node* n) { + // Only consider nodes in the loop. + Node* ctrl = _vloop.phase()->get_ctrl(n); + if (_vloop.lpt()->is_member(_vloop.phase()->get_loop(ctrl))) { + // Find the index in the loop. + for (uint j = 0; j < _body.size(); j++) { + if (n == _body.at(j)) { + set_ignored(j); + return; + } + } + assert(false, "must find"); + } + } + + bool is_ignored(uint i) const { + assert(i < _vloop.lpt()->_body.size(), "must be in bounds"); + return _ignored[i]; + } +}; + +// SuperWord unrolling analysis does: +// - Determine if the loop is a candidate for auto vectorization (SuperWord). +// - Find a good unrolling factor, to ensure full vector width utilization once we vectorize. void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_factor) { IdealLoopTree* lpt = vloop.lpt(); CountedLoopNode* cl = vloop.cl(); Node* cl_exit = vloop.cl_exit(); PhaseIdealLoop* phase = vloop.phase(); + SuperWordUnrollingAnalysisIgnoredNodes ignored_nodes(vloop); bool is_slp = true; - size_t ignored_size = lpt->_body.size(); - int *ignored_loop_nodes = NEW_RESOURCE_ARRAY(int, ignored_size); - Node_Stack nstack((int)ignored_size); - - // First clear the entries - for (uint i = 0; i < lpt->_body.size(); i++) { - ignored_loop_nodes[i] = -1; - } int max_vector = Matcher::max_vector_size_auto_vectorization(T_BYTE); @@ -77,7 +119,7 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa n->is_IfTrue() || n->is_CountedLoop() || (n == cl_exit)) { - ignored_loop_nodes[i] = n->_idx; + ignored_nodes.set_ignored(i); continue; } @@ -85,7 +127,7 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa IfNode *iff = n->as_If(); if (iff->_fcnt != COUNT_UNKNOWN && iff->_prob != PROB_UNKNOWN) { if (lpt->is_loop_exit(iff)) { - ignored_loop_nodes[i] = n->_idx; + ignored_nodes.set_ignored(i); continue; } } @@ -103,7 +145,7 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa // This must happen after check of phi/if if (n->is_Phi() || n->is_If()) { - ignored_loop_nodes[i] = n->_idx; + ignored_nodes.set_ignored(i); continue; } @@ -121,7 +163,7 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa bt = n->bottom_type()->basic_type(); } if (is_java_primitive(bt) == false) { - ignored_loop_nodes[i] = n->_idx; + ignored_nodes.set_ignored(i); continue; } @@ -132,30 +174,9 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa // save a queue of post process nodes if (n_ctrl != nullptr && lpt->is_member(phase->get_loop(n_ctrl))) { - // Process the memory expression - int stack_idx = 0; - bool have_side_effects = true; - if (adr->is_AddP() == false) { - nstack.push(adr, stack_idx++); - } else { - // Mark the components of the memory operation in nstack - VPointer p1(current, vloop, &nstack); - have_side_effects = p1.node_stack()->is_nonempty(); - } - - // Process the pointer stack - while (have_side_effects) { - Node* pointer_node = nstack.node(); - for (uint j = 0; j < lpt->_body.size(); j++) { - Node* cur_node = lpt->_body.at(j); - if (cur_node == pointer_node) { - ignored_loop_nodes[j] = cur_node->_idx; - break; - } - } - nstack.pop(); - have_side_effects = nstack.is_nonempty(); - } + // Parse the address expression with VPointer, and mark the internal + // nodes of the address expression in ignore_nodes. + VPointer p(current, vloop, ignored_nodes); } } } @@ -165,7 +186,7 @@ void SuperWord::unrolling_analysis(const VLoop &vloop, int &local_loop_unroll_fa // description can use bool flag_small_bt = false; for (uint i = 0; i < lpt->_body.size(); i++) { - if (ignored_loop_nodes[i] != -1) continue; + if (ignored_nodes.is_ignored(i)) continue; BasicType bt; Node* n = lpt->_body.at(i); @@ -477,21 +498,48 @@ bool SuperWord::SLP_extract() { return schedule_and_apply(); } +int SuperWord::MemOp::cmp_by_group(MemOp* a, MemOp* b) { + // Opcode + int c_Opcode = cmp_code(a->mem()->Opcode(), b->mem()->Opcode()); + if (c_Opcode != 0) { return c_Opcode; } + + // VPointer summands + return MemPointer::cmp_summands(a->vpointer().mem_pointer(), + b->vpointer().mem_pointer()); +} + +int SuperWord::MemOp::cmp_by_group_and_con_and_original_index(MemOp* a, MemOp* b) { + // Group + int cmp_group = cmp_by_group(a, b); + if (cmp_group != 0) { return cmp_group; } + + // VPointer con + jint a_con = a->vpointer().mem_pointer().con().value(); + jint b_con = b->vpointer().mem_pointer().con().value(); + int c_con = cmp_code(a_con, b_con); + if (c_con != 0) { return c_con; } + + return cmp_code(a->original_index(), b->original_index()); +} + // Find the "seed" memops pairs. These are pairs that we strongly suspect would lead to vectorization. void SuperWord::create_adjacent_memop_pairs() { ResourceMark rm; - GrowableArray vpointers; - - collect_valid_vpointers(vpointers); - - // Sort the VPointers. This does 2 things: - // - Separate the VPointer into groups: all memops that have the same opcode and the same - // VPointer, except for the offset. Adjacent memops must have the same opcode and the - // same VPointer, except for a shift in the offset. Thus, two memops can only be adjacent - // if they are in the same group. This decreases the work. - // - Sort by offset inside the groups. This decreases the work needed to determine adjacent - // memops inside a group. - vpointers.sort(VPointer::cmp_for_sort); + GrowableArray memops; + + collect_valid_memops(memops); + + // Sort the MemOps by group, and inside a group by VPointer con: + // - Group: all memops with the same opcode, and the same VPointer summands. Adjacent memops + // have the same opcode and the same VPointer summands, only the VPointer con is + // different. Thus, two memops can only be adjacent if they are in the same group. + // This decreases the work. + // - VPointer con: Sorting by VPointer con inside the group allows us to perform a sliding + // window algorithm, to determine adjacent memops efficiently. + // Since GrowableArray::sort relies on qsort, the sort is not stable on its own. This can lead + // to worse packing in some cases. To make the sort stable, our last cmp criterion is the + // original index, i.e. the position in the memops array before sorting. + memops.sort(MemOp::cmp_by_group_and_con_and_original_index); #ifndef PRODUCT if (is_trace_superword_adjacent_memops()) { @@ -499,7 +547,7 @@ void SuperWord::create_adjacent_memop_pairs() { } #endif - create_adjacent_memop_pairs_in_all_groups(vpointers); + create_adjacent_memop_pairs_in_all_groups(memops); #ifndef PRODUCT if (is_trace_superword_packset()) { @@ -509,35 +557,36 @@ void SuperWord::create_adjacent_memop_pairs() { #endif } -// Collect all memops vpointers that could potentially be vectorized. -void SuperWord::collect_valid_vpointers(GrowableArray& vpointers) { - for_each_mem([&] (const MemNode* mem, int bb_idx) { +// Collect all memops that could potentially be vectorized. +void SuperWord::collect_valid_memops(GrowableArray& memops) const { + int original_index = 0; + for_each_mem([&] (MemNode* mem, int bb_idx) { const VPointer& p = vpointer(mem); - if (p.valid() && + if (p.is_valid() && !mem->is_LoadStore() && is_java_primitive(mem->memory_type())) { - vpointers.append(&p); + memops.append(MemOp(mem, &p, original_index++)); } }); } // For each group, find the adjacent memops. -void SuperWord::create_adjacent_memop_pairs_in_all_groups(const GrowableArray &vpointers) { +void SuperWord::create_adjacent_memop_pairs_in_all_groups(const GrowableArray& memops) { int group_start = 0; - while (group_start < vpointers.length()) { - int group_end = find_group_end(vpointers, group_start); - create_adjacent_memop_pairs_in_one_group(vpointers, group_start, group_end); + while (group_start < memops.length()) { + int group_end = find_group_end(memops, group_start); + create_adjacent_memop_pairs_in_one_group(memops, group_start, group_end); group_start = group_end; } } -// Step forward until we find a VPointer of another group, or we reach the end of the array. -int SuperWord::find_group_end(const GrowableArray& vpointers, int group_start) { +// Step forward until we find a MemOp of another group, or we reach the end of the array. +int SuperWord::find_group_end(const GrowableArray& memops, int group_start) { int group_end = group_start + 1; - while (group_end < vpointers.length() && - VPointer::cmp_for_sort_by_group( - vpointers.adr_at(group_start), - vpointers.adr_at(group_end) + while (group_end < memops.length() && + MemOp::cmp_by_group( + memops.adr_at(group_start), + memops.adr_at(group_end) ) == 0) { group_end++; } @@ -546,39 +595,41 @@ int SuperWord::find_group_end(const GrowableArray& vpointers, i // Find adjacent memops for a single group, e.g. for all LoadI of the same base, invar, etc. // Create pairs and add them to the pairset. -void SuperWord::create_adjacent_memop_pairs_in_one_group(const GrowableArray& vpointers, const int group_start, const int group_end) { +void SuperWord::create_adjacent_memop_pairs_in_one_group(const GrowableArray& memops, const int group_start, const int group_end) { #ifndef PRODUCT if (is_trace_superword_adjacent_memops()) { tty->print_cr(" group:"); for (int i = group_start; i < group_end; i++) { - const VPointer* p = vpointers.at(i); + const MemOp& memop = memops.at(i); + tty->print(" "); + memop.mem()->dump(); tty->print(" "); - p->print(); + memop.vpointer().print_on(tty); } } #endif - MemNode* first = vpointers.at(group_start)->mem(); - int element_size = data_size(first); + MemNode* first = memops.at(group_start).mem(); + const int element_size = data_size(first); // For each ref in group: find others that can be paired: for (int i = group_start; i < group_end; i++) { - const VPointer* p1 = vpointers.at(i); - MemNode* mem1 = p1->mem(); + const VPointer& p1 = memops.at(i).vpointer(); + MemNode* mem1 = memops.at(i).mem(); bool found = false; // For each ref in group with larger or equal offset: for (int j = i + 1; j < group_end; j++) { - const VPointer* p2 = vpointers.at(j); - MemNode* mem2 = p2->mem(); + const VPointer& p2 = memops.at(j).vpointer(); + MemNode* mem2 = memops.at(j).mem(); assert(mem1 != mem2, "look only at pair of different memops"); // Check for correct distance. assert(data_size(mem1) == element_size, "all nodes in group must have the same element size"); assert(data_size(mem2) == element_size, "all nodes in group must have the same element size"); - assert(p1->offset_in_bytes() <= p2->offset_in_bytes(), "must be sorted by offset"); - if (p1->offset_in_bytes() + element_size > p2->offset_in_bytes()) { continue; } - if (p1->offset_in_bytes() + element_size < p2->offset_in_bytes()) { break; } + assert(p1.con() <= p2.con(), "must be sorted by offset"); + if (p1.con() + element_size > p2.con()) { continue; } + if (p1.con() + element_size < p2.con()) { break; } // Only allow nodes from same origin idx to be packed (see CompileCommand Option Vectorize) if (_do_vector_loop && !same_origin_idx(mem1, mem2)) { continue; } @@ -593,9 +644,9 @@ void SuperWord::create_adjacent_memop_pairs_in_one_group(const GrowableArrayprint_cr(" pair:"); } tty->print(" "); - p1->print(); + p1.print_on(tty); tty->print(" "); - p2->print(); + p2.print_on(tty); } #endif @@ -723,13 +774,9 @@ bool SuperWord::are_adjacent_refs(Node* s1, Node* s2) const { return false; } - // Adjacent memory references must have the same base, be comparable - // and have the correct distance between them. const VPointer& p1 = vpointer(s1->as_Mem()); const VPointer& p2 = vpointer(s2->as_Mem()); - if (p1.base() != p2.base() || !p1.comparable(p2)) return false; - int diff = p2.offset_in_bytes() - p1.offset_in_bytes(); - return diff == data_size(s1); + return p1.is_adjacent_to_and_before(p2); } //------------------------------isomorphic--------------------------- @@ -1432,13 +1479,9 @@ const AlignmentSolution* SuperWord::pack_alignment_solution(const Node_List* pac const CountedLoopEndNode* pre_end = _vloop.pre_loop_end(); assert(pre_end->stride_is_con(), "pre loop stride is constant"); - AlignmentSolver solver(pack->at(0)->as_Mem(), + AlignmentSolver solver(mem_ref_p, + pack->at(0)->as_Mem(), pack->size(), - mem_ref_p.base(), - mem_ref_p.offset_in_bytes(), - mem_ref_p.invar(), - mem_ref_p.invar_factor(), - mem_ref_p.scale_in_bytes(), pre_end->init_trip(), pre_end->stride_con(), iv_stride() @@ -2564,7 +2607,7 @@ const Type* VLoopTypes::container_type(Node* n) const { // Float to half float conversion may be succeeded by a conversion from // half float to float, in such a case back propagation of narrow type (SHORT) // may not be possible. - if (n->Opcode() == Op_ConvF2HF) { + if (n->Opcode() == Op_ConvF2HF || n->Opcode() == Op_ReinterpretHF2S) { return TypeInt::SHORT; } // A narrow type of arithmetic operations will be determined by @@ -2611,10 +2654,9 @@ void VTransform::determine_mem_ref_and_aw_for_main_loop_alignment() { const GrowableArray& vtnodes = _graph.vtnodes(); for (int i = 0; i < vtnodes.length(); i++) { - VTransformVectorNode* vtn = vtnodes.at(i)->isa_Vector(); + VTransformMemVectorNode* vtn = vtnodes.at(i)->isa_MemVector(); if (vtn == nullptr) { continue; } - MemNode* p0 = vtn->nodes().at(0)->isa_Mem(); - if (p0 == nullptr) { continue; } + MemNode* p0 = vtn->nodes().at(0)->as_Mem(); int vw = p0->memory_size() * vtn->nodes().length(); if (vw > max_aw) { @@ -2660,8 +2702,8 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { Node* orig_limit = pre_opaq->original_loop_limit(); assert(orig_limit != nullptr && igvn().type(orig_limit) != Type::TOP, ""); - const VPointer& align_to_ref_p = vpointer(align_to_ref); - assert(align_to_ref_p.valid(), "sanity"); + const VPointer& p = vpointer(align_to_ref); + assert(p.is_valid(), "sanity"); // For the main-loop, we want the address of align_to_ref to be memory aligned // with some alignment width (aw, a power of 2). When we enter the main-loop, @@ -2669,7 +2711,7 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // limit by executing adjust_pre_iter many extra iterations, we can change the // alignment of the address. // - // adr = base + offset + invar + scale * iv (1) + // adr = base + invar + iv_scale * iv + con (1) // adr % aw = 0 (2) // // Note, that we are defining the modulo operator "%" such that the remainder is @@ -2686,55 +2728,55 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // We want to find adjust_pre_iter, such that the address is aligned when entering // the main-loop: // - // iv = new_limit = old_limit + adjust_pre_iter (3a, stride > 0) - // iv = new_limit = old_limit - adjust_pre_iter (3b, stride < 0) + // iv = new_limit = old_limit + adjust_pre_iter (3a, iv_stride > 0) + // iv = new_limit = old_limit - adjust_pre_iter (3b, iv_stride < 0) // - // We define boi as: + // We define bic as: // - // boi = base + offset + invar (4) + // bic = base + invar + con (4) // // And now we can simplify the address using (1), (3), and (4): // - // adr = boi + scale * new_limit - // adr = boi + scale * (old_limit + adjust_pre_iter) (5a, stride > 0) - // adr = boi + scale * (old_limit - adjust_pre_iter) (5b, stride < 0) + // adr = bic + iv_scale * new_limit + // adr = bic + iv_scale * (old_limit + adjust_pre_iter) (5a, iv_stride > 0) + // adr = bic + iv_scale * (old_limit - adjust_pre_iter) (5b, iv_stride < 0) // // And hence we can restate (2) with (5), and solve the equation for adjust_pre_iter: // - // (boi + scale * (old_limit + adjust_pre_iter) % aw = 0 (6a, stride > 0) - // (boi + scale * (old_limit - adjust_pre_iter) % aw = 0 (6b, stride < 0) + // (bic + iv_scale * (old_limit + adjust_pre_iter) % aw = 0 (6a, iv_stride > 0) + // (bic + iv_scale * (old_limit - adjust_pre_iter) % aw = 0 (6b, iv_stride < 0) // - // In most cases, scale is the element size, for example: + // In most cases, iv_scale is the element size, for example: // // for (i = 0; i < a.length; i++) { a[i] = ...; } // - // It is thus reasonable to assume that both abs(scale) and abs(stride) are + // It is thus reasonable to assume that both abs(iv_scale) and abs(iv_stride) are // strictly positive powers of 2. Further, they can be assumed to be non-zero, // otherwise the address does not depend on iv, and the alignment cannot be // affected by adjusting the pre-loop limit. // - // Further, if abs(scale) >= aw, then adjust_pre_iter has no effect on alignment, and - // we are not able to affect the alignment at all. Hence, we require abs(scale) < aw. + // Further, if abs(iv_scale) >= aw, then adjust_pre_iter has no effect on alignment, and + // we are not able to affect the alignment at all. Hence, we require abs(iv_scale) < aw. // - // Moreover, for alignment to be achievable, boi must be a multiple of scale. If strict + // Moreover, for alignment to be achievable, bic must be a multiple of iv_scale. If strict // alignment is required (i.e. -XX:+AlignVector), this is guaranteed by the filtering // done with the AlignmentSolver / AlignmentSolution. If strict alignment is not // required, then alignment is still preferable for performance, but not necessary. - // In many cases boi will be a multiple of scale, but if it is not, then the adjustment + // In many cases bic will be a multiple of iv_scale, but if it is not, then the adjustment // does not guarantee alignment, but the code is still correct. // - // Hence, in what follows we assume that boi is a multiple of scale, and in fact all - // terms in (6) are multiples of scale. Therefore we divide all terms by scale: + // Hence, in what follows we assume that bic is a multiple of iv_scale, and in fact all + // terms in (6) are multiples of iv_scale. Therefore we divide all terms by iv_scale: // - // AW = aw / abs(scale) (power of 2) (7) - // BOI = boi / abs(scale) (8) + // AW = aw / abs(iv_scale) (power of 2) (7) + // BIC = bic / abs(iv_scale) (8) // - // and restate (6), using (7) and (8), i.e. we divide (6) by abs(scale): + // and restate (6), using (7) and (8), i.e. we divide (6) by abs(iv_scale): // - // (BOI + sign(scale) * (old_limit + adjust_pre_iter) % AW = 0 (9a, stride > 0) - // (BOI + sign(scale) * (old_limit - adjust_pre_iter) % AW = 0 (9b, stride < 0) + // (BIC + sign(iv_scale) * (old_limit + adjust_pre_iter) % AW = 0 (9a, iv_stride > 0) + // (BIC + sign(iv_scale) * (old_limit - adjust_pre_iter) % AW = 0 (9b, iv_stride < 0) // - // where: sign(scale) = scale / abs(scale) = (scale > 0 ? 1 : -1) + // where: sign(iv_scale) = iv_scale / abs(iv_scale) = (iv_scale > 0 ? 1 : -1) // // Note, (9) allows for periodic solutions of adjust_pre_iter, with periodicity AW. // But we would like to spend as few iterations in the pre-loop as possible, @@ -2744,40 +2786,40 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // // We solve (9) for adjust_pre_iter, in the following 4 cases: // - // Case A: scale > 0 && stride > 0 (i.e. sign(scale) = 1) - // (BOI + old_limit + adjust_pre_iter) % AW = 0 - // adjust_pre_iter = (-BOI - old_limit) % AW (11a) + // Case A: iv_scale > 0 && iv_stride > 0 (i.e. sign(iv_scale) = 1) + // (BIC + old_limit + adjust_pre_iter) % AW = 0 + // adjust_pre_iter = (-BIC - old_limit) % AW (11a) // - // Case B: scale < 0 && stride > 0 (i.e. sign(scale) = -1) - // (BOI - old_limit - adjust_pre_iter) % AW = 0 - // adjust_pre_iter = (BOI - old_limit) % AW (11b) + // Case B: iv_scale < 0 && iv_stride > 0 (i.e. sign(iv_scale) = -1) + // (BIC - old_limit - adjust_pre_iter) % AW = 0 + // adjust_pre_iter = (BIC - old_limit) % AW (11b) // - // Case C: scale > 0 && stride < 0 (i.e. sign(scale) = 1) - // (BOI + old_limit - adjust_pre_iter) % AW = 0 - // adjust_pre_iter = (BOI + old_limit) % AW (11c) + // Case C: iv_scale > 0 && iv_stride < 0 (i.e. sign(iv_scale) = 1) + // (BIC + old_limit - adjust_pre_iter) % AW = 0 + // adjust_pre_iter = (BIC + old_limit) % AW (11c) // - // Case D: scale < 0 && stride < 0 (i.e. sign(scale) = -1) - // (BOI - old_limit + adjust_pre_iter) % AW = 0 - // adjust_pre_iter = (-BOI + old_limit) % AW (11d) + // Case D: iv_scale < 0 && iv_stride < 0 (i.e. sign(iv_scale) = -1) + // (BIC - old_limit + adjust_pre_iter) % AW = 0 + // adjust_pre_iter = (-BIC + old_limit) % AW (11d) // // We now generalize the equations (11*) by using: // - // OP: (stride > 0) ? SUB : ADD - // XBOI: (stride * scale > 0) ? -BOI : BOI + // OP: (iv_stride > 0) ? SUB : ADD + // XBIC: (iv_stride * iv_scale > 0) ? -BIC : BIC // // which gives us the final pre-loop limit adjustment: // - // adjust_pre_iter = (XBOI OP old_limit) % AW (12) + // adjust_pre_iter = (XBIC OP old_limit) % AW (12) // - // We can construct XBOI by additionally defining: + // We can construct XBIC by additionally defining: // - // xboi = (stride * scale > 0) ? -boi : boi (13) + // xbic = (iv_stride * iv_scale > 0) ? -bic : bic (13) // // which gives us: // - // XBOI = (stride * scale > 0) ? -BOI : BOI - // = (stride * scale > 0) ? -boi / abs(scale) : boi / abs(scale) - // = xboi / abs(scale) (14) + // XBIC = (iv_stride * iv_scale > 0) ? -BIC : BIC + // = (iv_stride * iv_scale > 0) ? -bic / abs(iv_scale) : bic / abs(iv_scale) + // = xbic / abs(iv_scale) (14) // // When we have computed adjust_pre_iter, we update the pre-loop limit // with (3a, b). However, we have to make sure that the adjust_pre_iter @@ -2786,32 +2828,37 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // the loop. Hence, we must constrain the updated limit as follows: // // constrained_limit = MIN(old_limit + adjust_pre_iter, orig_limit) - // = MIN(new_limit, orig_limit) (15a, stride > 0) + // = MIN(new_limit, orig_limit) (15a, iv_stride > 0) // constrained_limit = MAX(old_limit - adjust_pre_iter, orig_limit) - // = MAX(new_limit, orig_limit) (15a, stride < 0) + // = MAX(new_limit, orig_limit) (15a, iv_stride < 0) // - const int stride = iv_stride(); - const int scale = align_to_ref_p.scale_in_bytes(); - const int offset = align_to_ref_p.offset_in_bytes(); - Node* base = align_to_ref_p.adr(); - Node* invar = align_to_ref_p.invar(); + const int iv_stride = this->iv_stride(); + const int iv_scale = p.iv_scale(); + const int con = p.con(); + Node* base = p.mem_pointer().base().object_or_native(); #ifdef ASSERT if (_trace._align_vector) { tty->print_cr("\nVTransform::adjust_pre_loop_limit_to_align_main_loop_vectors:"); tty->print(" align_to_ref:"); align_to_ref->dump(); - tty->print_cr(" aw: %d", aw); - tty->print_cr(" stride: %d", stride); - tty->print_cr(" scale: %d", scale); - tty->print_cr(" offset: %d", offset); + tty->print(" "); + p.print_on(tty); + tty->print_cr(" aw: %d", aw); + tty->print_cr(" iv_stride: %d", iv_stride); + tty->print_cr(" iv_scale: %d", iv_scale); + tty->print_cr(" con: %d", con); tty->print(" base:"); base->dump(); - if (invar == nullptr) { - tty->print_cr(" invar: null"); + if (!p.has_invar_summands()) { + tty->print_cr(" invar: none"); } else { - tty->print(" invar:"); - invar->dump(); + tty->print_cr(" invar_summands:"); + p.for_each_invar_summand([&] (const MemPointerSummand& s) { + tty->print(" -> "); + s.print_on(tty); + }); + tty->cr(); } tty->print(" old_limit: "); old_limit->dump(); @@ -2820,111 +2867,131 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { } #endif - if (stride == 0 || !is_power_of_2(abs(stride)) || - scale == 0 || !is_power_of_2(abs(scale)) || - abs(scale) >= aw) { + if (iv_stride == 0 || !is_power_of_2(abs(iv_stride)) || + iv_scale == 0 || !is_power_of_2(abs(iv_scale)) || + abs(iv_scale) >= aw) { #ifdef ASSERT if (_trace._align_vector) { tty->print_cr(" Alignment cannot be affected by changing pre-loop limit because"); - tty->print_cr(" stride or scale are not power of 2, or abs(scale) >= aw."); + tty->print_cr(" iv_stride or iv_scale are not power of 2, or abs(iv_scale) >= aw."); } #endif // Cannot affect alignment, abort. return; } - assert(stride != 0 && is_power_of_2(abs(stride)) && - scale != 0 && is_power_of_2(abs(scale)) && - abs(scale) < aw, "otherwise we cannot affect alignment with pre-loop"); + assert(iv_stride != 0 && is_power_of_2(abs(iv_stride)) && + iv_scale != 0 && is_power_of_2(abs(iv_scale)) && + abs(iv_scale) < aw, "otherwise we cannot affect alignment with pre-loop"); - const int AW = aw / abs(scale); + const int AW = aw / abs(iv_scale); #ifdef ASSERT if (_trace._align_vector) { - tty->print_cr(" AW = aw(%d) / abs(scale(%d)) = %d", aw, scale, AW); + tty->print_cr(" AW = aw(%d) / abs(iv_scale(%d)) = %d", aw, iv_scale, AW); } #endif // 1: Compute (13a, b): - // xboi = -boi = (-base - offset - invar) (stride * scale > 0) - // xboi = +boi = (+base + offset + invar) (stride * scale < 0) - const bool is_sub = scale * stride > 0; - - // 1.1: offset - Node* xboi = igvn().intcon(is_sub ? -offset : offset); - TRACE_ALIGN_VECTOR_NODE(xboi); - - // 1.2: invar (if it exists) - if (invar != nullptr) { - if (igvn().type(invar)->isa_long()) { + // xbic = -bic = (-base - invar - con) (iv_stride * iv_scale > 0) + // xbic = +bic = (+base + invar + con) (iv_stride * iv_scale < 0) + const bool is_sub = iv_scale * iv_stride > 0; + + // 1.1: con + Node* xbic = igvn().intcon(is_sub ? -con : con); + TRACE_ALIGN_VECTOR_NODE(xbic); + + // 1.2: invar = SUM(invar_summands) + // We iteratively add / subtract all invar_summands, if there are any. + p.for_each_invar_summand([&] (const MemPointerSummand& s) { + Node* invar_variable = s.variable(); + jint invar_scale = s.scale().value(); + if (igvn().type(invar_variable)->isa_long()) { // Computations are done % (vector width/element size) so it's // safe to simply convert invar to an int and loose the upper 32 // bit half. - invar = new ConvL2INode(invar); - phase()->register_new_node(invar, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(invar); - } + invar_variable = new ConvL2INode(invar_variable); + phase()->register_new_node(invar_variable, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(invar_variable); + } + Node* invar_scale_con = igvn().intcon(invar_scale); + Node* invar_summand = new MulINode(invar_variable, invar_scale_con); + phase()->register_new_node(invar_summand, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(invar_summand); if (is_sub) { - xboi = new SubINode(xboi, invar); + xbic = new SubINode(xbic, invar_summand); } else { - xboi = new AddINode(xboi, invar); + xbic = new AddINode(xbic, invar_summand); } - phase()->register_new_node(xboi, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(xboi); - } + phase()->register_new_node(xbic, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(xbic); + }); // 1.3: base (unless base is guaranteed aw aligned) - if (aw > ObjectAlignmentInBytes || align_to_ref_p.base()->is_top()) { - // The base is only aligned with ObjectAlignmentInBytes with arrays. - // When the base() is top, we have no alignment guarantee at all. - // Hence, we must now take the base into account for the calculation. - Node* xbase = new CastP2XNode(nullptr, base); - phase()->register_new_node(xbase, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(xbase); -#ifdef _LP64 - xbase = new ConvL2INode(xbase); - phase()->register_new_node(xbase, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(xbase); -#endif + bool is_base_native = p.mem_pointer().base().is_native(); + if (aw > ObjectAlignmentInBytes || is_base_native) { + // For objects, the base is ObjectAlignmentInBytes aligned. + // For native memory, we simply have a long that was cast to + // a pointer via CastX2P, or if we parsed through the CastX2P + // we only have a long. There is no alignment guarantee, and + // we must always take the base into account for the calculation. + // + // Computations are done % (vector width/element size) so it's + // safe to simply convert invar to an int and loose the upper 32 + // bit half. The base could be ptr, long or int. We cast all + // to int. + Node* xbase = base; + if (igvn().type(xbase)->isa_ptr()) { + // ptr -> int/long + xbase = new CastP2XNode(nullptr, xbase); + phase()->register_new_node(xbase, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(xbase); + } + if (igvn().type(xbase)->isa_long()) { + // long -> int + xbase = new ConvL2INode(xbase); + phase()->register_new_node(xbase, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(xbase); + } if (is_sub) { - xboi = new SubINode(xboi, xbase); + xbic = new SubINode(xbic, xbase); } else { - xboi = new AddINode(xboi, xbase); + xbic = new AddINode(xbic, xbase); } - phase()->register_new_node(xboi, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(xboi); + phase()->register_new_node(xbic, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(xbic); } // 2: Compute (14): - // XBOI = xboi / abs(scale) + // XBIC = xbic / abs(iv_scale) // The division is executed as shift - Node* log2_abs_scale = igvn().intcon(exact_log2(abs(scale))); - Node* XBOI = new URShiftINode(xboi, log2_abs_scale); - phase()->register_new_node(XBOI, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(log2_abs_scale); - TRACE_ALIGN_VECTOR_NODE(XBOI); + Node* log2_abs_iv_scale = igvn().intcon(exact_log2(abs(iv_scale))); + Node* XBIC = new URShiftINode(xbic, log2_abs_iv_scale); + phase()->register_new_node(XBIC, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(log2_abs_iv_scale); + TRACE_ALIGN_VECTOR_NODE(XBIC); // 3: Compute (12): - // adjust_pre_iter = (XBOI OP old_limit) % AW + // adjust_pre_iter = (XBIC OP old_limit) % AW // - // 3.1: XBOI_OP_old_limit = XBOI OP old_limit - Node* XBOI_OP_old_limit = nullptr; - if (stride > 0) { - XBOI_OP_old_limit = new SubINode(XBOI, old_limit); + // 3.1: XBIC_OP_old_limit = XBIC OP old_limit + Node* XBIC_OP_old_limit = nullptr; + if (iv_stride > 0) { + XBIC_OP_old_limit = new SubINode(XBIC, old_limit); } else { - XBOI_OP_old_limit = new AddINode(XBOI, old_limit); + XBIC_OP_old_limit = new AddINode(XBIC, old_limit); } - phase()->register_new_node(XBOI_OP_old_limit, pre_ctrl); - TRACE_ALIGN_VECTOR_NODE(XBOI_OP_old_limit); + phase()->register_new_node(XBIC_OP_old_limit, pre_ctrl); + TRACE_ALIGN_VECTOR_NODE(XBIC_OP_old_limit); // 3.2: Compute: - // adjust_pre_iter = (XBOI OP old_limit) % AW - // = XBOI_OP_old_limit % AW - // = XBOI_OP_old_limit AND (AW - 1) + // adjust_pre_iter = (XBIC OP old_limit) % AW + // = XBIC_OP_old_limit % AW + // = XBIC_OP_old_limit AND (AW - 1) // Since AW is a power of 2, the modulo operation can be replaced with // a bitmask operation. Node* mask_AW = igvn().intcon(AW-1); - Node* adjust_pre_iter = new AndINode(XBOI_OP_old_limit, mask_AW); + Node* adjust_pre_iter = new AndINode(XBIC_OP_old_limit, mask_AW); phase()->register_new_node(adjust_pre_iter, pre_ctrl); TRACE_ALIGN_VECTOR_NODE(mask_AW); TRACE_ALIGN_VECTOR_NODE(adjust_pre_iter); @@ -2937,8 +3004,8 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // range, and adjusts the main-loop limit so that we exit the main-loop // before we leave the "safe" range. After RCE, the range of the main-loop // can only be safely narrowed, and should never be widened. Hence, the - // pre-loop limit can only be increased (for stride > 0), but an add - // overflow might decrease it, or decreased (for stride < 0), but a sub + // pre-loop limit can only be increased (for iv_stride > 0), but an add + // overflow might decrease it, or decreased (for iv_stride < 0), but a sub // underflow might increase it. To prevent that, we perform the Sub / Add // and Max / Min with long operations. old_limit = new ConvI2LNode(old_limit); @@ -2952,11 +3019,11 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { TRACE_ALIGN_VECTOR_NODE(adjust_pre_iter); // 5: Compute (3a, b): - // new_limit = old_limit + adjust_pre_iter (stride > 0) - // new_limit = old_limit - adjust_pre_iter (stride < 0) + // new_limit = old_limit + adjust_pre_iter (iv_stride > 0) + // new_limit = old_limit - adjust_pre_iter (iv_stride < 0) // Node* new_limit = nullptr; - if (stride < 0) { + if (iv_stride < 0) { new_limit = new SubLNode(old_limit, adjust_pre_iter); } else { new_limit = new AddLNode(old_limit, adjust_pre_iter); @@ -2967,8 +3034,8 @@ void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { // 6: Compute (15a, b): // Prevent pre-loop from going past the original limit of the loop. Node* constrained_limit = - (stride > 0) ? (Node*) new MinLNode(phase()->C, new_limit, orig_limit) - : (Node*) new MaxLNode(phase()->C, new_limit, orig_limit); + (iv_stride > 0) ? (Node*) new MinLNode(phase()->C, new_limit, orig_limit) + : (Node*) new MaxLNode(phase()->C, new_limit, orig_limit); phase()->register_new_node(constrained_limit, pre_ctrl); TRACE_ALIGN_VECTOR_NODE(constrained_limit); diff --git a/src/hotspot/share/opto/superword.hpp b/src/hotspot/share/opto/superword.hpp index 8b24e0cf3a11a..57a403b449843 100644 --- a/src/hotspot/share/opto/superword.hpp +++ b/src/hotspot/share/opto/superword.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,8 +56,6 @@ // first statement is considered the left element, and the // second statement is considered the right element. -class VPointer; - // The PairSet is a set of pairs. These are later combined to packs, // and stored in the PackSet. class PairSet : public StackObj { @@ -474,7 +472,7 @@ class SuperWord : public ResourceObj { return _vloop_analyzer.types().same_velt_type(n1, n2); } - int data_size(Node* n) const { + int data_size(const Node* n) const { return _vloop_analyzer.types().data_size(n); } @@ -563,11 +561,43 @@ class SuperWord : public ResourceObj { bool SLP_extract(); // Find the "seed" memops pairs. These are pairs that we strongly suspect would lead to vectorization. + class MemOp : public StackObj { + private: + MemNode* _mem; + const VPointer* _vpointer; + int _original_index; + + public: + // Empty, for GrowableArray + MemOp() : + _mem(nullptr), + _vpointer(nullptr), + _original_index(-1) {} + MemOp(MemNode* mem, const VPointer* vpointer, int original_index) : + _mem(mem), + _vpointer(vpointer), + _original_index(original_index) {} + + MemNode* mem() const { return _mem; } + const VPointer& vpointer() const { return *_vpointer; } + int original_index() const { return _original_index; } + + static int cmp_by_group(MemOp* a, MemOp* b); + static int cmp_by_group_and_con_and_original_index(MemOp* a, MemOp* b); + + // We use two comparisons, because a subtraction could underflow. + template + static int cmp_code(T a, T b) { + if (a < b) { return -1; } + if (a > b) { return 1; } + return 0; + } + }; void create_adjacent_memop_pairs(); - void collect_valid_vpointers(GrowableArray& vpointers); - void create_adjacent_memop_pairs_in_all_groups(const GrowableArray& vpointers); - static int find_group_end(const GrowableArray& vpointers, int group_start); - void create_adjacent_memop_pairs_in_one_group(const GrowableArray& vpointers, const int group_start, int group_end); + void collect_valid_memops(GrowableArray& memops) const; + void create_adjacent_memop_pairs_in_all_groups(const GrowableArray& memops); + static int find_group_end(const GrowableArray& memops, int group_start); + void create_adjacent_memop_pairs_in_one_group(const GrowableArray& memops, const int group_start, int group_end); // Various methods to check if we can pack two nodes. bool can_pack_into_pair(Node* s1, Node* s2); diff --git a/src/hotspot/share/opto/superwordVTransformBuilder.cpp b/src/hotspot/share/opto/superwordVTransformBuilder.cpp index 2e32ce28d3ccb..aee6add2a98ef 100644 --- a/src/hotspot/share/opto/superwordVTransformBuilder.cpp +++ b/src/hotspot/share/opto/superwordVTransformBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "opto/superwordVTransformBuilder.hpp" #include "opto/vectornode.hpp" @@ -139,9 +138,13 @@ VTransformVectorNode* SuperWordVTransformBuilder::make_vector_vtnode_for_pack(co VTransformVectorNode* vtn = nullptr; if (p0->is_Load()) { - vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, pack_size); + const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Load()); + const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size)); + vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, pack_size, vector_p); } else if (p0->is_Store()) { - vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, pack_size); + const VPointer& scalar_p = _vloop_analyzer.vpointers().vpointer(p0->as_Store()); + const VPointer vector_p(scalar_p.make_with_size(scalar_p.size() * pack_size)); + vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, pack_size, vector_p); } else if (p0->is_Bool()) { VTransformBoolTest kind = _packset.get_bool_test(pack); vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, pack_size, kind); @@ -311,4 +314,3 @@ void SuperWordVTransformBuilder::add_dependencies_of_node_to_vtnode(Node*n, VTra vtn->add_dependency(dependency); // Add every dependency only once per vtn. } } - diff --git a/src/hotspot/share/opto/traceAutoVectorizationTag.hpp b/src/hotspot/share/opto/traceAutoVectorizationTag.hpp index 038e04fe0c50b..0c08777c90c4b 100644 --- a/src/hotspot/share/opto/traceAutoVectorizationTag.hpp +++ b/src/hotspot/share/opto/traceAutoVectorizationTag.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,10 @@ #include "utilities/stringUtils.hpp" #define COMPILER_TRACE_AUTO_VECTORIZATION_TAG(flags) \ - flags(POINTER_ANALYSIS, "Trace VPointer (verbose)") \ + flags(POINTER_PARSING, "Trace VPointer/MemPointer parsing") \ + flags(POINTER_ALIASING, "Trace VPointer/MemPointer aliasing") \ + flags(POINTER_ADJACENCY, "Trace VPointer/MemPointer adjacency") \ + flags(POINTER_OVERLAP, "Trace VPointer/MemPointer overlap") \ flags(PRECONDITIONS, "Trace VLoop::check_preconditions") \ flags(LOOP_ANALYZER, "Trace VLoopAnalyzer::setup_submodules") \ flags(MEMORY_SLICES, "Trace VLoopMemorySlices") \ diff --git a/src/hotspot/share/opto/traceMergeStoresTag.hpp b/src/hotspot/share/opto/traceMergeStoresTag.hpp index 9f33c9efa0525..214173c02f7dd 100644 --- a/src/hotspot/share/opto/traceMergeStoresTag.hpp +++ b/src/hotspot/share/opto/traceMergeStoresTag.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,9 +31,9 @@ namespace TraceMergeStores { #define COMPILER_TAG(flags) \ flags(BASIC, "Trace basic analysis steps") \ - flags(POINTER, "Trace pointer IR") \ - flags(ALIASING, "Trace MemPointerSimpleForm::get_aliasing_with") \ - flags(ADJACENCY, "Trace adjacency") \ + flags(POINTER_PARSING, "Trace pointer IR") \ + flags(POINTER_ALIASING, "Trace MemPointerSimpleForm::get_aliasing_with") \ + flags(POINTER_ADJACENCY, "Trace adjacency") \ flags(SUCCESS, "Trace successful merges") \ #define table_entry(name, description) name, diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index 407a4a20a9bda..b56e3739a9d2a 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,11 @@ * */ -#include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "ci/ciTypeFlow.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" +#include "classfile/vmSymbols.hpp" #include "compiler/compileLog.hpp" #include "libadt/dict.hpp" #include "memory/oopFactory.hpp" @@ -35,13 +35,17 @@ #include "oops/instanceMirrorKlass.hpp" #include "oops/objArrayKlass.hpp" #include "oops/typeArrayKlass.hpp" +#include "opto/callnode.hpp" +#include "opto/arraycopynode.hpp" #include "opto/matcher.hpp" #include "opto/node.hpp" #include "opto/opcodes.hpp" +#include "opto/runtime.hpp" #include "opto/type.hpp" #include "utilities/checkedCast.hpp" #include "utilities/powerOfTwo.hpp" #include "utilities/stringUtils.hpp" +#include "runtime/stubRoutines.hpp" // Portions of code courtesy of Clifford Click @@ -102,6 +106,9 @@ const Type::TypeInfo Type::_type_info[Type::lastype] = { { Abio, T_ILLEGAL, "abIO", false, 0, relocInfo::none }, // Abio { Return_Address, T_ADDRESS, "return_address",false, Op_RegP, relocInfo::none }, // Return_Address { Memory, T_ILLEGAL, "memory", false, 0, relocInfo::none }, // Memory + { HalfFloatBot, T_SHORT, "halffloat_top", false, Op_RegF, relocInfo::none }, // HalfFloatTop + { HalfFloatCon, T_SHORT, "hfcon:", false, Op_RegF, relocInfo::none }, // HalfFloatCon + { HalfFloatTop, T_SHORT, "short", false, Op_RegF, relocInfo::none }, // HalfFloatBot { FloatBot, T_FLOAT, "float_top", false, Op_RegF, relocInfo::none }, // FloatTop { FloatCon, T_FLOAT, "ftcon:", false, Op_RegF, relocInfo::none }, // FloatCon { FloatTop, T_FLOAT, "float", false, Op_RegF, relocInfo::none }, // FloatBot @@ -131,6 +138,7 @@ const Type *Type::ABIO; // State-of-machine only const Type *Type::BOTTOM; // All values const Type *Type::CONTROL; // Control only const Type *Type::DOUBLE; // All doubles +const Type *Type::HALF_FLOAT; // All half floats const Type *Type::FLOAT; // All floats const Type *Type::HALF; // Placeholder half of doublewide type const Type *Type::MEMORY; // Abstract store only @@ -451,6 +459,7 @@ void Type::Initialize_shared(Compile* current) { ABIO = make(Abio); // State-of-machine only RETURN_ADDRESS=make(Return_Address); FLOAT = make(FloatBot); // All floats + HALF_FLOAT = make(HalfFloatBot); // All half floats DOUBLE = make(DoubleBot); // All doubles BOTTOM = make(Bottom); // Everything HALF = make(Half); // Placeholder half of doublewide type @@ -462,6 +471,13 @@ void Type::Initialize_shared(Compile* current) { TypeF::POS_INF = TypeF::make(jfloat_cast(POSITIVE_INFINITE_F)); TypeF::NEG_INF = TypeF::make(-jfloat_cast(POSITIVE_INFINITE_F)); + TypeH::MAX = TypeH::make(max_jfloat16); // HalfFloat MAX + TypeH::MIN = TypeH::make(min_jfloat16); // HalfFloat MIN + TypeH::ZERO = TypeH::make((jshort)0); // HalfFloat 0 (positive zero) + TypeH::ONE = TypeH::make(one_jfloat16); // HalfFloat 1 + TypeH::POS_INF = TypeH::make(pos_inf_jfloat16); + TypeH::NEG_INF = TypeH::make(neg_inf_jfloat16); + TypeD::MAX = TypeD::make(max_jdouble); // Double MAX TypeD::MIN = TypeD::make(min_jdouble); // Double MIN TypeD::ZERO = TypeD::make(0.0); // Double 0 (positive zero) @@ -582,6 +598,7 @@ void Type::Initialize_shared(Compile* current) { TypeAryPtr::_array_interfaces = TypeInterfaces::make(&array_interfaces); TypeAryKlassPtr::_array_interfaces = TypeAryPtr::_array_interfaces; + TypeAryPtr::BOTTOM = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::BOTTOM, TypeInt::POS), nullptr, false, Type::OffsetBot); TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), nullptr /* current->env()->Object_klass() */, false, arrayOopDesc::length_offset_in_bytes()); TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), nullptr /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); @@ -710,6 +727,10 @@ void Type::Initialize_shared(Compile* current) { mreg2type[Op_VecY] = TypeVect::VECTY; mreg2type[Op_VecZ] = TypeVect::VECTZ; + LockNode::initialize_lock_Type(); + ArrayCopyNode::initialize_arraycopy_Type(); + OptoRuntime::initialize_types(); + // Restore working type arena. current->set_type_arena(save); current->set_type_dict(nullptr); @@ -1032,6 +1053,7 @@ const Type *Type::xmeet( const Type *t ) const { // Cut in half the number of cases I must handle. Only need cases for when // the given enum "t->type" is less than or equal to the local enum "type". + case HalfFloatCon: case FloatCon: case DoubleCon: case Int: @@ -1067,19 +1089,30 @@ const Type *Type::xmeet( const Type *t ) const { case Bottom: // Ye Olde Default return t; + case HalfFloatTop: + if (_base == HalfFloatTop) { return this; } + case HalfFloatBot: // Half Float + if (_base == HalfFloatBot || _base == HalfFloatTop) { return HALF_FLOAT; } + if (_base == FloatBot || _base == FloatTop) { return Type::BOTTOM; } + if (_base == DoubleTop || _base == DoubleBot) { return Type::BOTTOM; } + typerr(t); + return Type::BOTTOM; + case FloatTop: - if( _base == FloatTop ) return this; + if (_base == FloatTop ) { return this; } case FloatBot: // Float - if( _base == FloatBot || _base == FloatTop ) return FLOAT; - if( _base == DoubleTop || _base == DoubleBot ) return Type::BOTTOM; + if (_base == FloatBot || _base == FloatTop) { return FLOAT; } + if (_base == HalfFloatTop || _base == HalfFloatBot) { return Type::BOTTOM; } + if (_base == DoubleTop || _base == DoubleBot) { return Type::BOTTOM; } typerr(t); return Type::BOTTOM; case DoubleTop: - if( _base == DoubleTop ) return this; + if (_base == DoubleTop) { return this; } case DoubleBot: // Double - if( _base == DoubleBot || _base == DoubleTop ) return DOUBLE; - if( _base == FloatTop || _base == FloatBot ) return Type::BOTTOM; + if (_base == DoubleBot || _base == DoubleTop) { return DOUBLE; } + if (_base == HalfFloatTop || _base == HalfFloatBot) { return Type::BOTTOM; } + if (_base == FloatTop || _base == FloatBot) { return Type::BOTTOM; } typerr(t); return Type::BOTTOM; @@ -1087,7 +1120,7 @@ const Type *Type::xmeet( const Type *t ) const { case Control: // Control of code case Abio: // State of world outside of program case Memory: - if( _base == t->_base ) return this; + if (_base == t->_base) { return this; } typerr(t); return Type::BOTTOM; @@ -1167,6 +1200,7 @@ bool Type::empty(void) const { switch (_base) { case DoubleTop: case FloatTop: + case HalfFloatTop: case Top: return true; @@ -1175,6 +1209,7 @@ bool Type::empty(void) const { case Return_Address: case Memory: case Bottom: + case HalfFloatBot: case FloatBot: case DoubleBot: return false; // never a singleton, therefore never empty @@ -1222,6 +1257,9 @@ Type::Category Type::category() const { case Type::AryKlassPtr: case Type::Function: case Type::Return_Address: + case Type::HalfFloatTop: + case Type::HalfFloatCon: + case Type::HalfFloatBot: case Type::FloatTop: case Type::FloatCon: case Type::FloatBot: @@ -1327,6 +1365,9 @@ const Type *TypeF::xmeet( const Type *t ) const { case NarrowKlass: case Int: case Long: + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case DoubleTop: case DoubleCon: case DoubleBot: @@ -1405,6 +1446,138 @@ bool TypeF::empty(void) const { return false; // always exactly a singleton } +//============================================================================= +// Convenience common pre-built types. +const TypeH* TypeH::MAX; // Half float max +const TypeH* TypeH::MIN; // Half float min +const TypeH* TypeH::ZERO; // Half float zero +const TypeH* TypeH::ONE; // Half float one +const TypeH* TypeH::POS_INF; // Half float positive infinity +const TypeH* TypeH::NEG_INF; // Half float negative infinity + +//------------------------------make------------------------------------------- +// Create a halffloat constant +const TypeH* TypeH::make(short f) { + return (TypeH*)(new TypeH(f))->hashcons(); +} + +const TypeH* TypeH::make(float f) { + assert(StubRoutines::f2hf_adr() != nullptr, ""); + short hf = StubRoutines::f2hf(f); + return (TypeH*)(new TypeH(hf))->hashcons(); +} + +//------------------------------xmeet------------------------------------------- +// Compute the MEET of two types. It returns a new Type object. +const Type* TypeH::xmeet(const Type* t) const { + // Perform a fast test for common case; meeting the same types together. + if (this == t) return this; // Meeting same type-rep? + + // Current "this->_base" is FloatCon + switch (t->base()) { // Switch on original type + case AnyPtr: // Mixing with oops happens when javac + case RawPtr: // reuses local variables + case OopPtr: + case InstPtr: + case AryPtr: + case MetadataPtr: + case KlassPtr: + case InstKlassPtr: + case AryKlassPtr: + case NarrowOop: + case NarrowKlass: + case Int: + case Long: + case FloatTop: + case FloatCon: + case FloatBot: + case DoubleTop: + case DoubleCon: + case DoubleBot: + case Bottom: // Ye Olde Default + return Type::BOTTOM; + + case HalfFloatBot: + return t; + + default: // All else is a mistake + typerr(t); + + case HalfFloatCon: // Half float-constant vs Half float-constant? + if (_f != t->geth()) { // unequal constants? + // must compare bitwise as positive zero, negative zero and NaN have + // all the same representation in C++ + return HALF_FLOAT; // Return generic float + } // Equal constants + case Top: + case HalfFloatTop: + break; // Return the Half float constant + } + return this; // Return the Half float constant +} + +//------------------------------xdual------------------------------------------ +// Dual: symmetric +const Type* TypeH::xdual() const { + return this; +} + +//------------------------------eq--------------------------------------------- +// Structural equality check for Type representations +bool TypeH::eq(const Type* t) const { + // Bitwise comparison to distinguish between +/-0. These values must be treated + // as different to be consistent with C1 and the interpreter. + return (_f == t->geth()); +} + +//------------------------------hash------------------------------------------- +// Type-specific hashing function. +uint TypeH::hash(void) const { + return *(jshort*)(&_f); +} + +//------------------------------is_finite-------------------------------------- +// Has a finite value +bool TypeH::is_finite() const { + assert(StubRoutines::hf2f_adr() != nullptr, ""); + float f = StubRoutines::hf2f(geth()); + return g_isfinite(f) != 0; +} + +float TypeH::getf() const { + assert(StubRoutines::hf2f_adr() != nullptr, ""); + return StubRoutines::hf2f(geth()); +} + +//------------------------------is_nan----------------------------------------- +// Is not a number (NaN) +bool TypeH::is_nan() const { + assert(StubRoutines::hf2f_adr() != nullptr, ""); + float f = StubRoutines::hf2f(geth()); + return g_isnan(f) != 0; +} + +//------------------------------dump2------------------------------------------ +// Dump float constant Type +#ifndef PRODUCT +void TypeH::dump2(Dict &d, uint depth, outputStream* st) const { + Type::dump2(d,depth, st); + st->print("%f", getf()); +} +#endif + +//------------------------------singleton-------------------------------------- +// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple +// constants (Ldi nodes). Singletons are integer, half float, float or double constants +// or a single symbol. +bool TypeH::singleton(void) const { + return true; // Always a singleton +} + +bool TypeH::empty(void) const { + return false; // always exactly a singleton +} + //============================================================================= // Convenience common pre-built types. const TypeD *TypeD::MAX; // Floating point max @@ -1440,6 +1613,9 @@ const Type *TypeD::xmeet( const Type *t ) const { case NarrowKlass: case Int: case Long: + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -1636,6 +1812,9 @@ const Type *TypeInt::xmeet( const Type *t ) const { case NarrowOop: case NarrowKlass: case Long: + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -1899,6 +2078,9 @@ const Type *TypeLong::xmeet( const Type *t ) const { case NarrowOop: case NarrowKlass: case Int: + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -2693,6 +2875,9 @@ const Type *TypePtr::xmeet_helper(const Type *t) const { switch (t->base()) { // switch on original type case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -3632,6 +3817,9 @@ const Type *TypeOopPtr::xmeet_helper(const Type *t) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -3831,8 +4019,6 @@ intptr_t TypeOopPtr::get_con() const { const Type *TypeOopPtr::filter_helper(const Type *kills, bool include_speculative) const { const Type* ft = join_helper(kills, include_speculative); - const TypeInstPtr* ftip = ft->isa_instptr(); - const TypeInstPtr* ktip = kills->isa_instptr(); if (ft->empty()) { return Type::TOP; // Canonical empty value @@ -4200,6 +4386,9 @@ const Type *TypeInstPtr::xmeet_helper(const Type *t) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -4682,16 +4871,17 @@ bool TypeAryKlassPtr::is_meet_subtype_of_helper(const TypeKlassPtr *other, bool //============================================================================= // Convenience common pre-built types. -const TypeAryPtr *TypeAryPtr::RANGE; -const TypeAryPtr *TypeAryPtr::OOPS; -const TypeAryPtr *TypeAryPtr::NARROWOOPS; -const TypeAryPtr *TypeAryPtr::BYTES; -const TypeAryPtr *TypeAryPtr::SHORTS; -const TypeAryPtr *TypeAryPtr::CHARS; -const TypeAryPtr *TypeAryPtr::INTS; -const TypeAryPtr *TypeAryPtr::LONGS; -const TypeAryPtr *TypeAryPtr::FLOATS; -const TypeAryPtr *TypeAryPtr::DOUBLES; +const TypeAryPtr* TypeAryPtr::BOTTOM; +const TypeAryPtr* TypeAryPtr::RANGE; +const TypeAryPtr* TypeAryPtr::OOPS; +const TypeAryPtr* TypeAryPtr::NARROWOOPS; +const TypeAryPtr* TypeAryPtr::BYTES; +const TypeAryPtr* TypeAryPtr::SHORTS; +const TypeAryPtr* TypeAryPtr::CHARS; +const TypeAryPtr* TypeAryPtr::INTS; +const TypeAryPtr* TypeAryPtr::LONGS; +const TypeAryPtr* TypeAryPtr::FLOATS; +const TypeAryPtr* TypeAryPtr::DOUBLES; //------------------------------make------------------------------------------- const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, @@ -4876,6 +5066,9 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const { // Mixing ints & oops happens when javac reuses local variables case Int: case Long: + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -5305,6 +5498,9 @@ const Type *TypeNarrowPtr::xmeet( const Type *t ) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -5460,6 +5656,9 @@ const Type *TypeMetadataPtr::xmeet( const Type *t ) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -5652,8 +5851,6 @@ const Type *TypeKlassPtr::filter_helper(const Type *kills, bool include_speculat // logic here mirrors the one from TypeOopPtr::filter. See comments // there. const Type* ft = join_helper(kills, include_speculative); - const TypeKlassPtr* ftkp = ft->isa_instklassptr(); - const TypeKlassPtr* ktkp = kills->isa_instklassptr(); if (ft->empty()) { return Type::TOP; // Canonical empty value @@ -5834,6 +6031,9 @@ const Type *TypeInstKlassPtr::xmeet( const Type *t ) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: @@ -6258,6 +6458,9 @@ const Type *TypeAryKlassPtr::xmeet( const Type *t ) const { case Int: // Mixing ints & oops happens when javac case Long: // reuses local variables + case HalfFloatTop: + case HalfFloatCon: + case HalfFloatBot: case FloatTop: case FloatCon: case FloatBot: diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index 2dd702b686b0a..67e339d3d2ead 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ class Dict; class Type; class TypeD; class TypeF; +class TypeH; class TypeInteger; class TypeInt; class TypeLong; @@ -120,6 +121,9 @@ class Type { Abio, // Abstract I/O Return_Address, // Subroutine return address Memory, // Abstract store + HalfFloatTop, // No float value + HalfFloatCon, // Floating point constant + HalfFloatBot, // Any float value FloatTop, // No float value FloatCon, // Floating point constant FloatBot, // Any float value @@ -277,7 +281,8 @@ class Type { bool is_ptr_to_narrowklass() const; // Convenience access - float getf() const; + short geth() const; + virtual float getf() const; double getd() const; const TypeInt *is_int() const; @@ -289,6 +294,9 @@ class Type { const TypeD *isa_double() const; // Returns null if not a Double{Top,Con,Bot} const TypeD *is_double_constant() const; // Asserts it is a DoubleCon const TypeD *isa_double_constant() const; // Returns null if not a DoubleCon + const TypeH *isa_half_float() const; // Returns null if not a Float{Top,Con,Bot} + const TypeH *is_half_float_constant() const; // Asserts it is a FloatCon + const TypeH *isa_half_float_constant() const; // Returns null if not a FloatCon const TypeF *isa_float() const; // Returns null if not a Float{Top,Con,Bot} const TypeF *is_float_constant() const; // Asserts it is a FloatCon const TypeF *isa_float_constant() const; // Returns null if not a FloatCon @@ -431,6 +439,7 @@ class Type { static const Type *CONTROL; static const Type *DOUBLE; static const Type *FLOAT; + static const Type *HALF_FLOAT; static const Type *HALF; static const Type *MEMORY; static const Type *MULTI; @@ -521,6 +530,38 @@ class TypeF : public Type { #endif }; +// Class of Half Float-Constant Types. +class TypeH : public Type { + TypeH(short f) : Type(HalfFloatCon), _f(f) {}; +public: + virtual bool eq(const Type* t) const; + virtual uint hash() const; // Type specific hashing + virtual bool singleton(void) const; // TRUE if type is a singleton + virtual bool empty(void) const; // TRUE if type is vacuous +public: + const short _f; // Half Float constant + + static const TypeH* make(float f); + static const TypeH* make(short f); + + virtual bool is_finite() const; // Has a finite value + virtual bool is_nan() const; // Is not a number (NaN) + + virtual float getf() const; + virtual const Type* xmeet(const Type* t) const; + virtual const Type* xdual() const; // Compute dual right now. + // Convenience common pre-built types. + static const TypeH* MAX; + static const TypeH* MIN; + static const TypeH* ZERO; // positive zero only + static const TypeH* ONE; + static const TypeH* POS_INF; + static const TypeH* NEG_INF; +#ifndef PRODUCT + virtual void dump2(Dict &d, uint depth, outputStream* st) const; +#endif +}; + //------------------------------TypeD------------------------------------------ // Class of Double-Constant Types. class TypeD : public Type { @@ -1473,16 +1514,17 @@ class TypeAryPtr : public TypeOopPtr { virtual const TypeKlassPtr* as_klass_type(bool try_for_exact = false) const; // Convenience common pre-built types. - static const TypeAryPtr *RANGE; - static const TypeAryPtr *OOPS; - static const TypeAryPtr *NARROWOOPS; - static const TypeAryPtr *BYTES; - static const TypeAryPtr *SHORTS; - static const TypeAryPtr *CHARS; - static const TypeAryPtr *INTS; - static const TypeAryPtr *LONGS; - static const TypeAryPtr *FLOATS; - static const TypeAryPtr *DOUBLES; + static const TypeAryPtr* BOTTOM; + static const TypeAryPtr* RANGE; + static const TypeAryPtr* OOPS; + static const TypeAryPtr* NARROWOOPS; + static const TypeAryPtr* BYTES; + static const TypeAryPtr* SHORTS; + static const TypeAryPtr* CHARS; + static const TypeAryPtr* INTS; + static const TypeAryPtr* LONGS; + static const TypeAryPtr* FLOATS; + static const TypeAryPtr* DOUBLES; // selects one of the above: static const TypeAryPtr *get_array_body_type(BasicType elem) { assert((uint)elem <= T_CONFLICT && _array_body_type[elem] != nullptr, "bad elem type"); @@ -1942,6 +1984,11 @@ inline float Type::getf() const { return ((TypeF*)this)->_f; } +inline short Type::geth() const { + assert(_base == HalfFloatCon, "Not a HalfFloatCon"); + return ((TypeH*)this)->_f; +} + inline double Type::getd() const { assert( _base == DoubleCon, "Not a DoubleCon" ); return ((TypeD*)this)->_d; @@ -1974,6 +2021,21 @@ inline const TypeLong *Type::isa_long() const { return ( _base == Long ? (TypeLong*)this : nullptr); } +inline const TypeH* Type::isa_half_float() const { + return ((_base == HalfFloatTop || + _base == HalfFloatCon || + _base == HalfFloatBot) ? (TypeH*)this : nullptr); +} + +inline const TypeH* Type::is_half_float_constant() const { + assert( _base == HalfFloatCon, "Not a HalfFloat" ); + return (TypeH*)this; +} + +inline const TypeH* Type::isa_half_float_constant() const { + return (_base == HalfFloatCon ? (TypeH*)this : nullptr); +} + inline const TypeF *Type::isa_float() const { return ((_base == FloatTop || _base == FloatCon || @@ -2163,7 +2225,8 @@ inline const TypeNarrowKlass* Type::make_narrowklass() const { } inline bool Type::is_floatingpoint() const { - if( (_base == FloatCon) || (_base == FloatBot) || + if( (_base == HalfFloatCon) || (_base == HalfFloatBot) || + (_base == FloatCon) || (_base == FloatBot) || (_base == DoubleCon) || (_base == DoubleBot) ) return true; return false; diff --git a/src/hotspot/share/opto/vector.cpp b/src/hotspot/share/opto/vector.cpp index 73f9b9e74ba78..a0121819978be 100644 --- a/src/hotspot/share/opto/vector.cpp +++ b/src/hotspot/share/opto/vector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciSymbols.hpp" #include "gc/shared/barrierSet.hpp" #include "opto/castnode.hpp" diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 51b320c8047e7..e33d7b1968682 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciSymbols.hpp" #include "classfile/vmSymbols.hpp" #include "opto/library_call.hpp" diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp index e7b0a149cd81c..ffc2314a59b1d 100644 --- a/src/hotspot/share/opto/vectorization.cpp +++ b/src/hotspot/share/opto/vectorization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,6 @@ * questions. */ -#include "precompiled.hpp" #include "opto/addnode.hpp" #include "opto/connode.hpp" #include "opto/convertnode.hpp" @@ -30,19 +29,6 @@ #include "opto/rootnode.hpp" #include "opto/vectorization.hpp" -#ifndef PRODUCT -void VPointer::print_con_or_idx(const Node* n) { - if (n == nullptr) { - tty->print("( 0)"); - } else if (n->is_ConI()) { - jint val = n->as_ConI()->get_int(); - tty->print("(%4d)", val); - } else { - tty->print("[%4d]", n->_idx); - } -} -#endif - bool VLoop::check_preconditions() { #ifndef PRODUCT if (is_trace_preconditions()) { @@ -224,7 +210,7 @@ void VLoopVPointers::print() const { _body.for_each_mem([&] (const MemNode* mem, int bb_idx) { const VPointer& p = vpointer(mem); tty->print(" "); - p.print(); + p.print_on(tty); }); } #endif @@ -265,7 +251,7 @@ void VLoopDependencyGraph::construct() { if (n1->is_Load() && n2->is_Load()) { continue; } const VPointer& p2 = _vpointers.vpointer(n2); - if (!VPointer::not_equal(p1.cmp(p2))) { + if (!p1.never_overlaps_with(p2)) { // Possibly overlapping memory memory_pred_edges.append(_body.bb_idx(n2)); } @@ -406,1257 +392,39 @@ void VLoopDependencyGraph::PredsIterator::next() { } #ifndef PRODUCT -int VPointer::Tracer::_depth = 0; -#endif - -VPointer::VPointer(MemNode* const mem, const VLoop& vloop, - Node_Stack* nstack, bool analyze_only) : - _mem(mem), _vloop(vloop), - _base(nullptr), _adr(nullptr), _scale(0), _offset(0), _invar(nullptr), -#ifdef ASSERT - _debug_invar(nullptr), _debug_negate_invar(false), _debug_invar_scale(nullptr), -#endif - _has_int_index_after_convI2L(false), - _int_index_after_convI2L_offset(0), - _int_index_after_convI2L_invar(nullptr), - _int_index_after_convI2L_scale(0), - _nstack(nstack), _analyze_only(analyze_only), _stack_idx(0) -#ifndef PRODUCT - , _tracer(vloop.is_trace_pointer_analysis()) -#endif -{ - NOT_PRODUCT(_tracer.ctor_1(mem);) - - Node* adr = mem->in(MemNode::Address); - if (!adr->is_AddP()) { - assert(!valid(), "too complex"); - return; - } - // Match AddP(base, AddP(ptr, k*iv [+ invariant]), constant) - Node* base = adr->in(AddPNode::Base); - // The base address should be loop invariant - if (is_loop_member(base)) { - assert(!valid(), "base address is loop variant"); - return; - } - // unsafe references require misaligned vector access support - if (base->is_top() && !Matcher::misaligned_vectors_ok()) { - assert(!valid(), "unsafe access"); - return; - } - - NOT_PRODUCT(if(_tracer._is_trace_alignment) _tracer.store_depth();) - NOT_PRODUCT(_tracer.ctor_2(adr);) - - int i; - for (i = 0; ; i++) { - NOT_PRODUCT(_tracer.ctor_3(adr, i);) - - if (!scaled_iv_plus_offset(adr->in(AddPNode::Offset))) { - assert(!valid(), "too complex"); - return; - } - adr = adr->in(AddPNode::Address); - NOT_PRODUCT(_tracer.ctor_4(adr, i);) - - if (base == adr || !adr->is_AddP()) { - NOT_PRODUCT(_tracer.ctor_5(adr, base, i);) - break; // stop looking at addp's - } - } - if (!invariant(adr)) { - // The address must be invariant for the current loop. But if we are in a main-loop, - // it must also be invariant of the pre-loop, otherwise we cannot use this address - // for the pre-loop limit adjustment required for main-loop alignment. - assert(!valid(), "adr is loop variant"); - return; - } - - if (!base->is_top() && adr != base) { - assert(!valid(), "adr and base differ"); - return; - } - - NOT_PRODUCT(if(_tracer._is_trace_alignment) _tracer.restore_depth();) - NOT_PRODUCT(_tracer.ctor_6(mem);) - - // In the pointer analysis, and especially the AlignVector, analysis we assume that - // stride and scale are not too large. For example, we multiply "scale * stride", - // and assume that this does not overflow the int range. We also take "abs(scale)" - // and "abs(stride)", which would overflow for min_int = -(2^31). Still, we want - // to at least allow small and moderately large stride and scale. Therefore, we - // allow values up to 2^30, which is only a factor 2 smaller than the max/min int. - // Normal performance relevant code will have much lower values. And the restriction - // allows us to keep the rest of the autovectorization code much simpler, since we - // do not have to deal with overflows. - jlong long_scale = _scale; - jlong long_stride = _vloop.iv_stride(); - jlong max_val = 1 << 30; - if (abs(long_scale) >= max_val || - abs(long_stride) >= max_val || - abs(long_scale * long_stride) >= max_val) { - assert(!valid(), "adr stride*scale is too large"); - return; - } - - if (!is_safe_to_use_as_simple_form(base, adr)) { - assert(!valid(), "does not have simple form"); - return; - } - - _base = base; - _adr = adr; - assert(valid(), "Usable"); -} - -// Following is used to create a temporary object during -// the pattern match of an address expression. -VPointer::VPointer(VPointer* p) : - _mem(p->_mem), _vloop(p->_vloop), - _base(nullptr), _adr(nullptr), _scale(0), _offset(0), _invar(nullptr), -#ifdef ASSERT - _debug_invar(nullptr), _debug_negate_invar(false), _debug_invar_scale(nullptr), -#endif - _has_int_index_after_convI2L(false), - _int_index_after_convI2L_offset(0), - _int_index_after_convI2L_invar(nullptr), - _int_index_after_convI2L_scale(0), - _nstack(p->_nstack), _analyze_only(p->_analyze_only), _stack_idx(p->_stack_idx) -#ifndef PRODUCT - , _tracer(p->_tracer._is_trace_alignment) -#endif -{} - -// Biggest detectable factor of the invariant. -int VPointer::invar_factor() const { - Node* n = invar(); - if (n == nullptr) { - return 0; - } - int opc = n->Opcode(); - if (opc == Op_LShiftI && n->in(2)->is_Con()) { - return 1 << n->in(2)->get_int(); - } else if (opc == Op_LShiftL && n->in(2)->is_Con()) { - return 1 << n->in(2)->get_int(); - } - // All our best-effort has failed. - return 1; -} - -// We would like to make decisions about aliasing (i.e. removing memory edges) and adjacency -// (i.e. which loads/stores can be packed) based on the simple form: -// -// s_pointer = adr + offset + invar + scale * ConvI2L(iv) -// -// However, we parse the compound-long-int form: -// -// c_pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index) -// int_index = int_offset + int_invar + int_scale * iv -// -// In general, the simple and the compound-long-int form do not always compute the same pointer -// at runtime. For example, the simple form would give a different result due to an overflow -// in the int_index. -// -// Example: -// For both forms, we have: -// iv = 0 -// scale = 1 -// -// We now account the offset and invar once to the long part and once to the int part: -// Pointer 1 (long offset and long invar): -// long_offset = min_int -// long_invar = min_int -// int_offset = 0 -// int_invar = 0 -// -// Pointer 2 (int offset and int invar): -// long_offset = 0 -// long_invar = 0 -// int_offset = min_int -// int_invar = min_int -// -// This gives us the following pointers: -// Compound-long-int form pointers: -// Form: -// c_pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + int_invar + int_scale * iv) -// -// Pointers: -// c_pointer1 = adr + min_int + min_int + 1 * ConvI2L(0 + 0 + 1 * 0) -// = adr + min_int + min_int -// = adr - 2^32 -// -// c_pointer2 = adr + 0 + 0 + 1 * ConvI2L(min_int + min_int + 1 * 0) -// = adr + ConvI2L(min_int + min_int) -// = adr + 0 -// = adr -// -// Simple form pointers: -// Form: -// s_pointer = adr + offset + invar + scale * ConvI2L(iv) -// s_pointer = adr + (long_offset + int_offset) + (long_invar + int_invar) + (long_scale * int_scale) * ConvI2L(iv) -// -// Pointers: -// s_pointer1 = adr + (min_int + 0 ) + (min_int + 0 ) + 1 * 0 -// = adr + min_int + min_int -// = adr - 2^32 -// s_pointer2 = adr + (0 + min_int ) + (0 + min_int ) + 1 * 0 -// = adr + min_int + min_int -// = adr - 2^32 -// -// We see that the two addresses are actually 2^32 bytes apart (derived from the c_pointers), but their simple form look identical. -// -// Hence, we need to determine in which cases it is safe to make decisions based on the simple -// form, rather than the compound-long-int form. If we cannot prove that using the simple form -// is safe (i.e. equivalent to the compound-long-int form), then we do not get a valid VPointer, -// and the associated memop cannot be vectorized. -bool VPointer::is_safe_to_use_as_simple_form(Node* base, Node* adr) const { -#ifndef _LP64 - // On 32-bit platforms, there is never an explicit int_index with ConvI2L for the iv. Thus, the - // parsed pointer form is always the simple form, with int operations: - // - // pointer = adr + offset + invar + scale * iv - // - assert(!_has_int_index_after_convI2L, "32-bit never has an int_index with ConvI2L for the iv"); - return true; -#else - - // Array accesses that are not Unsafe always have a RangeCheck which ensures that there is no - // int_index overflow. This implies that the conversion to long can be done separately: - // - // ConvI2L(int_index) = ConvI2L(int_offset) + ConvI2L(int_invar) + ConvI2L(scale) * ConvI2L(iv) - // - // And hence, the simple form is guaranteed to be identical to the compound-long-int form at - // runtime and the VPointer is safe/valid to be used. - const TypeAryPtr* ary_ptr_t = _mem->adr_type()->isa_aryptr(); - if (ary_ptr_t != nullptr) { - if (!_mem->is_unsafe_access()) { - return true; - } - } - - // We did not find the int_index. Just to be safe, reject this VPointer. - if (!_has_int_index_after_convI2L) { - return false; - } - - int int_offset = _int_index_after_convI2L_offset; - Node* int_invar = _int_index_after_convI2L_invar; - int int_scale = _int_index_after_convI2L_scale; - int long_scale = _scale / int_scale; - - // If "int_index = iv", then the simple form is identical to the compound-long-int form. - // - // int_index = int_offset + int_invar + int_scale * iv - // = 0 0 1 * iv - // = iv - if (int_offset == 0 && int_invar == nullptr && int_scale == 1) { - return true; - } - - // Intuition: What happens if the int_index overflows? Let us look at two pointers on the "overflow edge": - // - // pointer1 = adr + ConvI2L(int_index1) - // pointer2 = adr + ConvI2L(int_index2) - // - // int_index1 = max_int + 0 = max_int -> very close to but before the overflow - // int_index2 = max_int + 1 = min_int -> just enough to get the overflow - // - // When looking at the difference of pointer1 and pointer2, we notice that it is very large - // (almost 2^32). Since arrays have at most 2^31 elements, chances are high that pointer2 is - // an actual out-of-bounds access at runtime. These would normally be prevented by range checks - // at runtime. However, if the access was done by using Unsafe, where range checks are omitted, - // then an out-of-bounds access constitutes undefined behavior. This means that we are allowed to - // do anything, including changing the behavior. - // - // If we can set the right conditions, we have a guarantee that an overflow is either impossible - // (no overflow or range checks preventing that) or undefined behavior. In both cases, we are - // safe to do a vectorization. - // - // Approach: We want to prove a lower bound for the distance between these two pointers, and an - // upper bound for the size of a memory object. We can derive such an upper bound for - // arrays. We know they have at most 2^31 elements. If we know the size of the elements - // in bytes, we have: - // - // array_element_size_in_bytes * 2^31 >= max_possible_array_size_in_bytes - // >= array_size_in_bytes (ARR) - // - // If some small difference "delta" leads to an int_index overflow, we know that the - // int_index1 before overflow must have been close to max_int, and the int_index2 after - // the overflow must be close to min_int: - // - // pointer1 = adr + long_offset + long_invar + long_scale * ConvI2L(int_index1) - // =approx adr + long_offset + long_invar + long_scale * max_int - // - // pointer2 = adr + long_offset + long_invar + long_scale * ConvI2L(int_index2) - // =approx adr + long_offset + long_invar + long_scale * min_int - // - // We realize that the pointer difference is very large: - // - // difference =approx long_scale * 2^32 - // - // Hence, if we set the right condition for long_scale and array_element_size_in_bytes, - // we can prove that an overflow is impossible (or would imply undefined behaviour). - // - // We must now take this intuition, and develop a rigorous proof. We start by stating the problem - // more precisely, with the help of some definitions and the Statement we are going to prove. - // - // Definition: - // Two VPointers are "comparable" (i.e. VPointer::comparable is true, set with VPointer::cmp()), - // iff all of these conditions apply for the simple form: - // 1) Both VPointers are valid. - // 2) The adr are identical, or both are array bases of different arrays. - // 3) They have identical scale. - // 4) They have identical invar. - // 5) The difference in offsets is limited: abs(offset1 - offset2) < 2^31. (DIFF) - // - // For the Vectorization Optimization, we pair-wise compare VPointers and determine if they are: - // 1) "not comparable": - // We do not optimize them (assume they alias, not assume adjacency). - // - // Whenever we chose this option based on the simple form, it is also correct based on the - // compound-long-int form, since we make no optimizations based on it. - // - // 2) "comparable" with different array bases at runtime: - // We assume they do not alias (remove memory edges), but not assume adjacency. - // - // Whenever we have two different array bases for the simple form, we also have different - // array bases for the compound-long-form. Since VPointers provably point to different - // memory objects, they can never alias. - // - // 3) "comparable" with the same base address: - // We compute the relative pointer difference, and based on the load/store size we can - // compute aliasing and adjacency. - // - // We must find a condition under which the pointer difference of the simple form is - // identical to the pointer difference of the compound-long-form. We do this with the - // Statement below, which we then proceed to prove. - // - // Statement: - // If two VPointers satisfy these 3 conditions: - // 1) They are "comparable". - // 2) They have the same base address. - // 3) Their long_scale is a multiple of the array element size in bytes: - // - // abs(long_scale) % array_element_size_in_bytes = 0 (A) - // - // Then their pointer difference of the simple form is identical to the pointer difference - // of the compound-long-int form. - // - // More precisely: - // Such two VPointers by definition have identical adr, invar, and scale. - // Their simple form is: - // - // s_pointer1 = adr + offset1 + invar + scale * ConvI2L(iv) (B1) - // s_pointer2 = adr + offset2 + invar + scale * ConvI2L(iv) (B2) - // - // Thus, the pointer difference of the simple forms collapses to the difference in offsets: - // - // s_difference = s_pointer1 - s_pointer2 = offset1 - offset2 (C) - // - // Their compound-long-int form for these VPointer is: - // - // c_pointer1 = adr + long_offset1 + long_invar1 + long_scale1 * ConvI2L(int_index1) (D1) - // int_index1 = int_offset1 + int_invar1 + int_scale1 * iv (D2) - // - // c_pointer2 = adr + long_offset2 + long_invar2 + long_scale2 * ConvI2L(int_index2) (D3) - // int_index2 = int_offset2 + int_invar2 + int_scale2 * iv (D4) - // - // And these are the offset1, offset2, invar and scale from the simple form (B1) and (B2): - // - // offset1 = long_offset1 + long_scale1 * ConvI2L(int_offset1) (D5) - // offset2 = long_offset2 + long_scale2 * ConvI2L(int_offset2) (D6) - // - // invar = long_invar1 + long_scale1 * ConvI2L(int_invar1) - // = long_invar2 + long_scale2 * ConvI2L(int_invar2) (D7) - // - // scale = long_scale1 * ConvI2L(int_scale1) - // = long_scale2 * ConvI2L(int_scale2) (D8) - // - // The pointer difference of the compound-long-int form is defined as: - // - // c_difference = c_pointer1 - c_pointer2 - // - // Thus, the statement claims that for the two VPointer we have: - // - // s_difference = c_difference (Statement) - // - // We prove the Statement with the help of a Lemma: - // - // Lemma: - // There is some integer x, such that: - // - // c_difference = s_difference + array_element_size_in_bytes * x * 2^32 (Lemma) - // - // From condition (DIFF), we can derive: - // - // abs(s_difference) < 2^31 (E) - // - // Assuming the Lemma, we prove the Statement: - // If "x = 0" (intuitively: the int_index does not overflow), then: - // c_difference = s_difference - // and hence the simple form computes the same pointer difference as the compound-long-int form. - // If "x != 0" (intuitively: the int_index overflows), then: - // abs(c_difference) >= abs(s_difference + array_element_size_in_bytes * x * 2^32) - // >= array_element_size_in_bytes * 2^32 - abs(s_difference) - // -- apply (E) -- - // > array_element_size_in_bytes * 2^32 - 2^31 - // >= array_element_size_in_bytes * 2^31 - // -- apply (ARR) -- - // >= max_possible_array_size_in_bytes - // >= array_size_in_bytes - // - // This shows that c_pointer1 and c_pointer2 have a distance that exceeds the maximum array size. - // Thus, at least one of the two pointers must be outside of the array bounds. But we can assume - // that out-of-bounds accesses do not happen. If they still do, it is undefined behavior. Hence, - // we are allowed to do anything. We can also "safely" use the simple form in this case even though - // it might not match the compound-long-int form at runtime. - // QED Statement. - // - // We must now prove the Lemma. - // - // ConvI2L always truncates by some power of 2^32, i.e. there is some integer y such that: - // - // ConvI2L(y1 + y2) = ConvI2L(y1) + ConvI2L(y2) + 2^32 * y (F) - // - // It follows, that there is an integer y1 such that: - // - // ConvI2L(int_index1) = ConvI2L(int_offset1 + int_invar1 + int_scale1 * iv) - // -- apply (F) -- - // = ConvI2L(int_offset1) - // + ConvI2L(int_invar1) - // + ConvI2L(int_scale1) * ConvI2L(iv) - // + y1 * 2^32 (G) - // - // Thus, we can write the compound-long-int form (D1) as: - // - // c_pointer1 = adr + long_offset1 + long_invar1 + long_scale1 * ConvI2L(int_index1) - // -- apply (G) -- - // = adr - // + long_offset1 - // + long_invar1 - // + long_scale1 * ConvI2L(int_offset1) - // + long_scale1 * ConvI2L(int_invar1) - // + long_scale1 * ConvI2L(int_scale1) * ConvI2L(iv) - // + long_scale1 * y1 * 2^32 (H) - // - // And we can write the simple form as: - // - // s_pointer1 = adr + offset1 + invar + scale * ConvI2L(iv) - // -- apply (D5, D7, D8) -- - // = adr - // + long_offset1 - // + long_scale1 * ConvI2L(int_offset1) - // + long_invar1 - // + long_scale1 * ConvI2L(int_invar1) - // + long_scale1 * ConvI2L(int_scale1) * ConvI2L(iv) (K) - // - // We now compute the pointer difference between the simple (K) and compound-long-int form (H). - // Most terms cancel out immediately: - // - // sc_difference1 = c_pointer1 - s_pointer1 = long_scale1 * y1 * 2^32 (L) - // - // Rearranging the equation (L), we get: - // - // c_pointer1 = s_pointer1 + long_scale1 * y1 * 2^32 (M) - // - // And since long_scale1 is a multiple of array_element_size_in_bytes, there is some integer - // x1, such that (M) implies: - // - // c_pointer1 = s_pointer1 + array_element_size_in_bytes * x1 * 2^32 (N) - // - // With an analogue equation for c_pointer2, we can now compute the pointer difference for - // the compound-long-int form: - // - // c_difference = c_pointer1 - c_pointer2 - // -- apply (N) -- - // = s_pointer1 + array_element_size_in_bytes * x1 * 2^32 - // -(s_pointer2 + array_element_size_in_bytes * x2 * 2^32) - // -- where "x = x1 - x2" -- - // = s_pointer1 - s_pointer2 + array_element_size_in_bytes * x * 2^32 - // -- apply (C) -- - // = s_difference + array_element_size_in_bytes * x * 2^32 - // QED Lemma. - if (ary_ptr_t != nullptr) { - BasicType array_element_bt = ary_ptr_t->elem()->array_element_basic_type(); - if (is_java_primitive(array_element_bt)) { - int array_element_size_in_bytes = type2aelembytes(array_element_bt); - if (abs(long_scale) % array_element_size_in_bytes == 0) { - return true; - } - } - } - - // General case: we do not know if it is safe to use the simple form. - return false; -#endif -} - -bool VPointer::is_loop_member(Node* n) const { - Node* n_c = phase()->get_ctrl(n); - return lpt()->is_member(phase()->get_loop(n_c)); -} - -bool VPointer::invariant(Node* n) const { - NOT_PRODUCT(Tracer::Depth dd;) - bool is_not_member = !is_loop_member(n); - if (is_not_member) { - CountedLoopNode* cl = lpt()->_head->as_CountedLoop(); - if (cl->is_main_loop()) { - // Check that n_c dominates the pre loop head node. If it does not, then - // we cannot use n as invariant for the pre loop CountedLoopEndNode check - // because n_c is either part of the pre loop or between the pre and the - // main loop (Illegal invariant happens when n_c is a CastII node that - // prevents data nodes to flow above the main loop). - Node* n_c = phase()->get_ctrl(n); - return phase()->is_dominator(n_c, _vloop.pre_loop_head()); - } - } - return is_not_member; -} - -// Match: k*iv + offset -// where: k is a constant that maybe zero, and -// offset is (k2 [+/- invariant]) where k2 maybe zero and invariant is optional -bool VPointer::scaled_iv_plus_offset(Node* n) { - NOT_PRODUCT(Tracer::Depth ddd;) - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_1(n);) - - if (scaled_iv(n)) { - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_2(n);) - return true; - } - - if (offset_plus_k(n)) { - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_3(n);) - return true; - } - - int opc = n->Opcode(); - if (opc == Op_AddI) { - if (offset_plus_k(n->in(2)) && scaled_iv_plus_offset(n->in(1))) { - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_4(n);) - return true; - } - if (offset_plus_k(n->in(1)) && scaled_iv_plus_offset(n->in(2))) { - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_5(n);) - return true; - } - } else if (opc == Op_SubI || opc == Op_SubL) { - if (offset_plus_k(n->in(2), true) && scaled_iv_plus_offset(n->in(1))) { - // (offset1 + invar1 + scale * iv) - (offset2 + invar2) - // Subtraction handled via "negate" flag of "offset_plus_k". - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_6(n);) - return true; - } - VPointer tmp(this); - if (offset_plus_k(n->in(1)) && tmp.scaled_iv_plus_offset(n->in(2))) { - // (offset1 + invar1) - (offset2 + invar2 + scale * iv) - // Subtraction handled explicitly below. - assert(_scale == 0, "shouldn't be set yet"); - // _scale = -tmp._scale - if (!try_MulI_no_overflow(-1, tmp._scale, _scale)) { - return false; // mul overflow. - } - // _offset -= tmp._offset - if (!try_SubI_no_overflow(_offset, tmp._offset, _offset)) { - return false; // sub overflow. - } - // _invar -= tmp._invar - if (tmp._invar != nullptr) { - maybe_add_to_invar(tmp._invar, true); -#ifdef ASSERT - _debug_invar_scale = tmp._debug_invar_scale; - _debug_negate_invar = !tmp._debug_negate_invar; -#endif - } - - // Forward info about the int_index: - assert(!_has_int_index_after_convI2L, "no previous int_index discovered"); - _has_int_index_after_convI2L = tmp._has_int_index_after_convI2L; - _int_index_after_convI2L_offset = tmp._int_index_after_convI2L_offset; - _int_index_after_convI2L_invar = tmp._int_index_after_convI2L_invar; - _int_index_after_convI2L_scale = tmp._int_index_after_convI2L_scale; - - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_7(n);) - return true; - } - } - - NOT_PRODUCT(_tracer.scaled_iv_plus_offset_8(n);) - return false; -} - -// Match: k*iv where k is a constant that's not zero -bool VPointer::scaled_iv(Node* n) { - NOT_PRODUCT(Tracer::Depth ddd;) - NOT_PRODUCT(_tracer.scaled_iv_1(n);) - - if (_scale != 0) { // already found a scale - NOT_PRODUCT(_tracer.scaled_iv_2(n, _scale);) - return false; - } - - if (n == iv()) { - _scale = 1; - NOT_PRODUCT(_tracer.scaled_iv_3(n, _scale);) - return true; - } - if (_analyze_only && (is_loop_member(n))) { - _nstack->push(n, _stack_idx++); - } - - int opc = n->Opcode(); - if (opc == Op_MulI) { - if (n->in(1) == iv() && n->in(2)->is_Con()) { - _scale = n->in(2)->get_int(); - NOT_PRODUCT(_tracer.scaled_iv_4(n, _scale);) - return true; - } else if (n->in(2) == iv() && n->in(1)->is_Con()) { - _scale = n->in(1)->get_int(); - NOT_PRODUCT(_tracer.scaled_iv_5(n, _scale);) - return true; - } - } else if (opc == Op_LShiftI) { - if (n->in(1) == iv() && n->in(2)->is_Con()) { - if (!try_LShiftI_no_overflow(1, n->in(2)->get_int(), _scale)) { - return false; // shift overflow. - } - NOT_PRODUCT(_tracer.scaled_iv_6(n, _scale);) - return true; - } - } else if (opc == Op_ConvI2L && !has_iv()) { - // So far we have not found the iv yet, and are about to enter a ConvI2L subgraph, - // which may be the int index (that might overflow) for the memory access, of the form: - // - // int_index = int_offset + int_invar + int_scale * iv - // - // If we simply continue parsing with the current VPointer, then the int_offset and - // int_invar simply get added to the long offset and invar. But for the checks in - // VPointer::is_safe_to_use_as_simple_form() we need to have explicit access to the - // int_index. Thus, we must parse it explicitly here. For this, we use a temporary - // VPointer, to pattern match the int_index sub-expression of the address. - - NOT_PRODUCT(Tracer::Depth dddd;) - VPointer tmp(this); - NOT_PRODUCT(_tracer.scaled_iv_8(n, &tmp);) - - if (tmp.scaled_iv_plus_offset(n->in(1)) && tmp.has_iv()) { - // We successfully matched an integer index, of the form: - // int_index = int_offset + int_invar + int_scale * iv - // Forward scale. - assert(_scale == 0 && tmp._scale != 0, "iv only found just now"); - _scale = tmp._scale; - // Accumulate offset. - if (!try_AddI_no_overflow(_offset, tmp._offset, _offset)) { - return false; // add overflow. - } - // Accumulate invar. - if (tmp._invar != nullptr) { - maybe_add_to_invar(tmp._invar, false); - } - // Set info about the int_index: - assert(!_has_int_index_after_convI2L, "no previous int_index discovered"); - _has_int_index_after_convI2L = true; - _int_index_after_convI2L_offset = tmp._offset; - _int_index_after_convI2L_invar = tmp._invar; - _int_index_after_convI2L_scale = tmp._scale; - - NOT_PRODUCT(_tracer.scaled_iv_7(n);) - return true; - } - } else if (opc == Op_ConvI2L || opc == Op_CastII) { - if (scaled_iv_plus_offset(n->in(1))) { - NOT_PRODUCT(_tracer.scaled_iv_7(n);) - return true; - } - } else if (opc == Op_LShiftL && n->in(2)->is_Con()) { - if (!has_iv()) { - // Need to preserve the current _offset value, so - // create a temporary object for this expression subtree. - // Hacky, so should re-engineer the address pattern match. - NOT_PRODUCT(Tracer::Depth dddd;) - VPointer tmp(this); - NOT_PRODUCT(_tracer.scaled_iv_8(n, &tmp);) - - if (tmp.scaled_iv_plus_offset(n->in(1))) { - int shift = n->in(2)->get_int(); - // Accumulate scale. - if (!try_LShiftI_no_overflow(tmp._scale, shift, _scale)) { - return false; // shift overflow. - } - // Accumulate offset. - int shifted_offset = 0; - if (!try_LShiftI_no_overflow(tmp._offset, shift, shifted_offset)) { - return false; // shift overflow. - } - if (!try_AddI_no_overflow(_offset, shifted_offset, _offset)) { - return false; // add overflow. - } - // Accumulate invar. - if (tmp._invar != nullptr) { - BasicType bt = tmp._invar->bottom_type()->basic_type(); - assert(bt == T_INT || bt == T_LONG, ""); - maybe_add_to_invar(register_if_new(LShiftNode::make(tmp._invar, n->in(2), bt)), false); -#ifdef ASSERT - _debug_invar_scale = n->in(2); -#endif - } - - // Forward info about the int_index: - assert(!_has_int_index_after_convI2L, "no previous int_index discovered"); - _has_int_index_after_convI2L = tmp._has_int_index_after_convI2L; - _int_index_after_convI2L_offset = tmp._int_index_after_convI2L_offset; - _int_index_after_convI2L_invar = tmp._int_index_after_convI2L_invar; - _int_index_after_convI2L_scale = tmp._int_index_after_convI2L_scale; - - NOT_PRODUCT(_tracer.scaled_iv_9(n, _scale, _offset, _invar);) - return true; - } - } - } - NOT_PRODUCT(_tracer.scaled_iv_10(n);) - return false; -} - -// Match: offset is (k [+/- invariant]) -// where k maybe zero and invariant is optional, but not both. -bool VPointer::offset_plus_k(Node* n, bool negate) { - NOT_PRODUCT(Tracer::Depth ddd;) - NOT_PRODUCT(_tracer.offset_plus_k_1(n);) - - int opc = n->Opcode(); - if (opc == Op_ConI) { - if (!try_AddSubI_no_overflow(_offset, n->get_int(), negate, _offset)) { - return false; // add/sub overflow. - } - NOT_PRODUCT(_tracer.offset_plus_k_2(n, _offset);) - return true; - } else if (opc == Op_ConL) { - // Okay if value fits into an int - const TypeLong* t = n->find_long_type(); - if (t->higher_equal(TypeLong::INT)) { - jlong loff = n->get_long(); - jint off = (jint)loff; - if (!try_AddSubI_no_overflow(_offset, off, negate, _offset)) { - return false; // add/sub overflow. - } - NOT_PRODUCT(_tracer.offset_plus_k_3(n, _offset);) - return true; - } - NOT_PRODUCT(_tracer.offset_plus_k_4(n);) - return false; - } - assert((_debug_invar == nullptr) == (_invar == nullptr), ""); - - if (_analyze_only && is_loop_member(n)) { - _nstack->push(n, _stack_idx++); - } - if (opc == Op_AddI) { - if (n->in(2)->is_Con() && invariant(n->in(1))) { - maybe_add_to_invar(n->in(1), negate); - if (!try_AddSubI_no_overflow(_offset, n->in(2)->get_int(), negate, _offset)) { - return false; // add/sub overflow. - } - NOT_PRODUCT(_tracer.offset_plus_k_6(n, _invar, negate, _offset);) - return true; - } else if (n->in(1)->is_Con() && invariant(n->in(2))) { - if (!try_AddSubI_no_overflow(_offset, n->in(1)->get_int(), negate, _offset)) { - return false; // add/sub overflow. - } - maybe_add_to_invar(n->in(2), negate); - NOT_PRODUCT(_tracer.offset_plus_k_7(n, _invar, negate, _offset);) - return true; - } - } - if (opc == Op_SubI) { - if (n->in(2)->is_Con() && invariant(n->in(1))) { - maybe_add_to_invar(n->in(1), negate); - if (!try_AddSubI_no_overflow(_offset, n->in(2)->get_int(), !negate, _offset)) { - return false; // add/sub overflow. - } - NOT_PRODUCT(_tracer.offset_plus_k_8(n, _invar, negate, _offset);) - return true; - } else if (n->in(1)->is_Con() && invariant(n->in(2))) { - if (!try_AddSubI_no_overflow(_offset, n->in(1)->get_int(), negate, _offset)) { - return false; // add/sub overflow. - } - maybe_add_to_invar(n->in(2), !negate); - NOT_PRODUCT(_tracer.offset_plus_k_9(n, _invar, !negate, _offset);) - return true; - } - } - - if (!is_loop_member(n)) { - // 'n' is loop invariant. Skip ConvI2L and CastII nodes before checking if 'n' is dominating the pre loop. - if (opc == Op_ConvI2L) { - n = n->in(1); - } - if (n->Opcode() == Op_CastII) { - // Skip CastII nodes - assert(!is_loop_member(n), "sanity"); - n = n->in(1); - } - // Check if 'n' can really be used as invariant (not in main loop and dominating the pre loop). - if (invariant(n)) { - maybe_add_to_invar(n, negate); - NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, negate, _offset);) - return true; - } - } - - NOT_PRODUCT(_tracer.offset_plus_k_11(n);) - return false; -} - -Node* VPointer::maybe_negate_invar(bool negate, Node* invar) { -#ifdef ASSERT - _debug_negate_invar = negate; -#endif - if (negate) { - BasicType bt = invar->bottom_type()->basic_type(); - assert(bt == T_INT || bt == T_LONG, ""); - Node* zero = phase()->zerocon(bt); - Node* sub = SubNode::make(zero, invar, bt); - invar = register_if_new(sub); - } - return invar; -} - -Node* VPointer::register_if_new(Node* n) const { - PhaseIterGVN& igvn = phase()->igvn(); - Node* prev = igvn.hash_find_insert(n); - if (prev != nullptr) { - n->destruct(&igvn); - n = prev; - } else { - Node* c = phase()->get_early_ctrl(n); - phase()->register_new_node(n, c); - } - return n; -} - -void VPointer::maybe_add_to_invar(Node* new_invar, bool negate) { - new_invar = maybe_negate_invar(negate, new_invar); - if (_invar == nullptr) { - _invar = new_invar; -#ifdef ASSERT - _debug_invar = new_invar; -#endif - return; - } -#ifdef ASSERT - _debug_invar = NodeSentinel; -#endif - BasicType new_invar_bt = new_invar->bottom_type()->basic_type(); - assert(new_invar_bt == T_INT || new_invar_bt == T_LONG, ""); - BasicType invar_bt = _invar->bottom_type()->basic_type(); - assert(invar_bt == T_INT || invar_bt == T_LONG, ""); - - BasicType bt = (new_invar_bt == T_LONG || invar_bt == T_LONG) ? T_LONG : T_INT; - Node* current_invar = _invar; - if (invar_bt != bt) { - assert(bt == T_LONG && invar_bt == T_INT, ""); - assert(new_invar_bt == bt, ""); - current_invar = register_if_new(new ConvI2LNode(current_invar)); - } else if (new_invar_bt != bt) { - assert(bt == T_LONG && new_invar_bt == T_INT, ""); - assert(invar_bt == bt, ""); - new_invar = register_if_new(new ConvI2LNode(new_invar)); - } - Node* add = AddNode::make(current_invar, new_invar, bt); - _invar = register_if_new(add); -} - -bool VPointer::try_AddI_no_overflow(int offset1, int offset2, int& result) { - jlong long_offset = java_add((jlong)(offset1), (jlong)(offset2)); - jint int_offset = java_add( offset1, offset2); - if (long_offset != int_offset) { - return false; - } - result = int_offset; - return true; -} - -bool VPointer::try_SubI_no_overflow(int offset1, int offset2, int& result) { - jlong long_offset = java_subtract((jlong)(offset1), (jlong)(offset2)); - jint int_offset = java_subtract( offset1, offset2); - if (long_offset != int_offset) { - return false; - } - result = int_offset; - return true; -} - -bool VPointer::try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result) { - if (is_sub) { - return try_SubI_no_overflow(offset1, offset2, result); - } else { - return try_AddI_no_overflow(offset1, offset2, result); - } -} - -bool VPointer::try_LShiftI_no_overflow(int offset, int shift, int& result) { - if (shift < 0 || shift > 31) { - return false; - } - jlong long_offset = java_shift_left((jlong)(offset), shift); - jint int_offset = java_shift_left( offset, shift); - if (long_offset != int_offset) { - return false; - } - result = int_offset; - return true; -} - -bool VPointer::try_MulI_no_overflow(int offset1, int offset2, int& result) { - jlong long_offset = java_multiply((jlong)(offset1), (jlong)(offset2)); - jint int_offset = java_multiply( offset1, offset2); - if (long_offset != int_offset) { - return false; - } - result = int_offset; - return true; -} - -// We use two comparisons, because a subtraction could underflow. -#define RETURN_CMP_VALUE_IF_NOT_EQUAL(a, b) \ - if (a < b) { return -1; } \ - if (a > b) { return 1; } - -// To be in the same group, two VPointers must be the same, -// except for the offset. -int VPointer::cmp_for_sort_by_group(const VPointer** p1, const VPointer** p2) { - const VPointer* a = *p1; - const VPointer* b = *p2; - - RETURN_CMP_VALUE_IF_NOT_EQUAL(a->base()->_idx, b->base()->_idx); - RETURN_CMP_VALUE_IF_NOT_EQUAL(a->mem()->Opcode(), b->mem()->Opcode()); - RETURN_CMP_VALUE_IF_NOT_EQUAL(a->scale_in_bytes(), b->scale_in_bytes()); - - int a_inva_idx = a->invar() == nullptr ? 0 : a->invar()->_idx; - int b_inva_idx = b->invar() == nullptr ? 0 : b->invar()->_idx; - RETURN_CMP_VALUE_IF_NOT_EQUAL(a_inva_idx, b_inva_idx); - - return 0; // equal -} - -// We compare by group, then by offset, and finally by node idx. -int VPointer::cmp_for_sort(const VPointer** p1, const VPointer** p2) { - int cmp_group = cmp_for_sort_by_group(p1, p2); - if (cmp_group != 0) { return cmp_group; } - - const VPointer* a = *p1; - const VPointer* b = *p2; - - RETURN_CMP_VALUE_IF_NOT_EQUAL(a->offset_in_bytes(), b->offset_in_bytes()); - RETURN_CMP_VALUE_IF_NOT_EQUAL(a->mem()->_idx, b->mem()->_idx); - return 0; // equal -} - -#ifndef PRODUCT -// Function for printing the fields of a VPointer -void VPointer::print() const { - tty->print("VPointer[mem: %4d %10s, ", _mem->_idx, _mem->Name()); +void VPointer::print_on(outputStream* st, bool end_with_cr) const { + st->print("VPointer["); - if (!valid()) { - tty->print_cr("invalid]"); + if (!is_valid()) { + st->print_cr("invalid]"); return; } - tty->print("base: %4d, ", _base != nullptr ? _base->_idx : 0); - tty->print("adr: %4d, ", _adr != nullptr ? _adr->_idx : 0); - - tty->print(" base"); - VPointer::print_con_or_idx(_base); - - tty->print(" + offset(%4d)", _offset); - - tty->print(" + invar"); - VPointer::print_con_or_idx(_invar); - - tty->print_cr(" + scale(%4d) * iv]", _scale); -} -#endif - -// Following are functions for tracing VPointer match -#ifndef PRODUCT -void VPointer::Tracer::print_depth() const { - for (int ii = 0; ii < _depth; ++ii) { - tty->print(" "); - } -} - -void VPointer::Tracer::ctor_1(const Node* mem) { - if (_is_trace_alignment) { - print_depth(); tty->print(" %d VPointer::VPointer: start alignment analysis", mem->_idx); mem->dump(); - } -} + st->print("size: %2d, %s, ", size(), + _mem_pointer.base().is_object() ? "object" : "native"); -void VPointer::Tracer::ctor_2(Node* adr) { - if (_is_trace_alignment) { - //store_depth(); - inc_depth(); - print_depth(); tty->print(" %d (adr) VPointer::VPointer: ", adr->_idx); adr->dump(); - inc_depth(); - print_depth(); tty->print(" %d (base) VPointer::VPointer: ", adr->in(AddPNode::Base)->_idx); adr->in(AddPNode::Base)->dump(); - } -} + Node* base = _mem_pointer.base().object_or_native(); + tty->print("base(%d %s) + con(%3d) + iv_scale(%3d) * iv + invar(", + base->_idx, base->Name(), + _mem_pointer.con().value(), + _iv_scale); -void VPointer::Tracer::ctor_3(Node* adr, int i) { - if (_is_trace_alignment) { - inc_depth(); - Node* offset = adr->in(AddPNode::Offset); - print_depth(); tty->print(" %d (offset) VPointer::VPointer: i = %d: ", offset->_idx, i); offset->dump(); - } -} - -void VPointer::Tracer::ctor_4(Node* adr, int i) { - if (_is_trace_alignment) { - inc_depth(); - print_depth(); tty->print(" %d (adr) VPointer::VPointer: i = %d: ", adr->_idx, i); adr->dump(); - } -} - -void VPointer::Tracer::ctor_5(Node* adr, Node* base, int i) { - if (_is_trace_alignment) { - inc_depth(); - if (base == adr) { - print_depth(); tty->print_cr(" \\ %d (adr) == %d (base) VPointer::VPointer: breaking analysis at i = %d", adr->_idx, base->_idx, i); - } else if (!adr->is_AddP()) { - print_depth(); tty->print_cr(" \\ %d (adr) is NOT Addp VPointer::VPointer: breaking analysis at i = %d", adr->_idx, i); + int count = 0; + for_each_invar_summand([&] (const MemPointerSummand& s) { + if (count > 0) { + st->print(" + "); } + s.print_on(tty); + count++; + }); + if (count == 0) { + st->print("0"); } -} - -void VPointer::Tracer::ctor_6(const Node* mem) { - if (_is_trace_alignment) { - //restore_depth(); - print_depth(); tty->print_cr(" %d (adr) VPointer::VPointer: stop analysis", mem->_idx); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_1(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print(" %d VPointer::scaled_iv_plus_offset testing node: ", n->_idx); - n->dump(); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_2(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: PASSED", n->_idx); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_3(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: PASSED", n->_idx); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_4(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: Op_AddI PASSED", n->_idx); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(1) is scaled_iv: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(2) is offset_plus_k: ", n->in(2)->_idx); n->in(2)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_5(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: Op_AddI PASSED", n->_idx); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(2) is scaled_iv: ", n->in(2)->_idx); n->in(2)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(1) is offset_plus_k: ", n->in(1)->_idx); n->in(1)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_6(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: Op_%s PASSED", n->_idx, n->Name()); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(1) is scaled_iv: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(2) is offset_plus_k: ", n->in(2)->_idx); n->in(2)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_7(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: Op_%s PASSED", n->_idx, n->Name()); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(2) is scaled_iv: ", n->in(2)->_idx); n->in(2)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv_plus_offset: in(1) is offset_plus_k: ", n->in(1)->_idx); n->in(1)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_plus_offset_8(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv_plus_offset: FAILED", n->_idx); - } -} - -void VPointer::Tracer::scaled_iv_1(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print(" %d VPointer::scaled_iv: testing node: ", n->_idx); n->dump(); - } -} - -void VPointer::Tracer::scaled_iv_2(Node* n, int scale) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: FAILED since another _scale has been detected before", n->_idx); - print_depth(); tty->print_cr(" \\ VPointer::scaled_iv: _scale (%d) != 0", scale); - } -} - -void VPointer::Tracer::scaled_iv_3(Node* n, int scale) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: is iv, setting _scale = %d", n->_idx, scale); - } -} - -void VPointer::Tracer::scaled_iv_4(Node* n, int scale) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: Op_MulI PASSED, setting _scale = %d", n->_idx, scale); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(1) is iv: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(2) is Con: ", n->in(2)->_idx); n->in(2)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_5(Node* n, int scale) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: Op_MulI PASSED, setting _scale = %d", n->_idx, scale); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(2) is iv: ", n->in(2)->_idx); n->in(2)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(1) is Con: ", n->in(1)->_idx); n->in(1)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_6(Node* n, int scale) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: Op_LShiftI PASSED, setting _scale = %d", n->_idx, scale); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(1) is iv: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::scaled_iv: in(2) is Con: ", n->in(2)->_idx); n->in(2)->dump(); - } -} - -void VPointer::Tracer::scaled_iv_7(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: Op_ConvI2L PASSED", n->_idx); - print_depth(); tty->print_cr(" \\ VPointer::scaled_iv: in(1) %d is scaled_iv_plus_offset: ", n->in(1)->_idx); - inc_depth(); inc_depth(); - print_depth(); n->in(1)->dump(); - dec_depth(); dec_depth(); - } -} - -void VPointer::Tracer::scaled_iv_8(Node* n, VPointer* tmp) { - if (_is_trace_alignment) { - print_depth(); tty->print(" %d VPointer::scaled_iv: Op_LShiftL, creating tmp VPointer: ", n->_idx); tmp->print(); - } -} - -void VPointer::Tracer::scaled_iv_9(Node* n, int scale, int offset, Node* invar) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: Op_LShiftL PASSED, setting _scale = %d, _offset = %d", n->_idx, scale, offset); - print_depth(); tty->print_cr(" \\ VPointer::scaled_iv: in(1) [%d] is scaled_iv_plus_offset, in(2) [%d] used to scale: _scale = %d, _offset = %d", - n->in(1)->_idx, n->in(2)->_idx, scale, offset); - if (invar != nullptr) { - print_depth(); tty->print_cr(" \\ VPointer::scaled_iv: scaled invariant: [%d]", invar->_idx); - } - inc_depth(); inc_depth(); - print_depth(); n->in(1)->dump(); - print_depth(); n->in(2)->dump(); - if (invar != nullptr) { - print_depth(); invar->dump(); - } - dec_depth(); dec_depth(); - } -} - -void VPointer::Tracer::scaled_iv_10(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::scaled_iv: FAILED", n->_idx); - } -} - -void VPointer::Tracer::offset_plus_k_1(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print(" %d VPointer::offset_plus_k: testing node: ", n->_idx); n->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_2(Node* n, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_ConI PASSED, setting _offset = %d", n->_idx, _offset); - } -} - -void VPointer::Tracer::offset_plus_k_3(Node* n, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_ConL PASSED, setting _offset = %d", n->_idx, _offset); - } -} - -void VPointer::Tracer::offset_plus_k_4(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: FAILED", n->_idx); - print_depth(); tty->print_cr(" \\ " JLONG_FORMAT " VPointer::offset_plus_k: Op_ConL FAILED, k is too big", n->get_long()); - } -} - -void VPointer::Tracer::offset_plus_k_5(Node* n, Node* _invar) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: FAILED since another invariant has been detected before", n->_idx); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: _invar is not null: ", _invar->_idx); _invar->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_6(Node* n, Node* _invar, bool _negate_invar, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_AddI PASSED, setting _debug_negate_invar = %d, _invar = %d, _offset = %d", - n->_idx, _negate_invar, _invar->_idx, _offset); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(2) is Con: ", n->in(2)->_idx); n->in(2)->dump(); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(1) is invariant: ", _invar->_idx); _invar->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_7(Node* n, Node* _invar, bool _negate_invar, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_AddI PASSED, setting _debug_negate_invar = %d, _invar = %d, _offset = %d", - n->_idx, _negate_invar, _invar->_idx, _offset); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(1) is Con: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(2) is invariant: ", _invar->_idx); _invar->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_8(Node* n, Node* _invar, bool _negate_invar, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_SubI is PASSED, setting _debug_negate_invar = %d, _invar = %d, _offset = %d", - n->_idx, _negate_invar, _invar->_idx, _offset); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(2) is Con: ", n->in(2)->_idx); n->in(2)->dump(); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(1) is invariant: ", _invar->_idx); _invar->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_9(Node* n, Node* _invar, bool _negate_invar, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: Op_SubI PASSED, setting _debug_negate_invar = %d, _invar = %d, _offset = %d", n->_idx, _negate_invar, _invar->_idx, _offset); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(1) is Con: ", n->in(1)->_idx); n->in(1)->dump(); - print_depth(); tty->print(" \\ %d VPointer::offset_plus_k: in(2) is invariant: ", _invar->_idx); _invar->dump(); - } -} - -void VPointer::Tracer::offset_plus_k_10(Node* n, Node* _invar, bool _negate_invar, int _offset) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: PASSED, setting _debug_negate_invar = %d, _invar = %d, _offset = %d", n->_idx, _negate_invar, _invar->_idx, _offset); - print_depth(); tty->print_cr(" \\ %d VPointer::offset_plus_k: is invariant", n->_idx); - } -} - -void VPointer::Tracer::offset_plus_k_11(Node* n) { - if (_is_trace_alignment) { - print_depth(); tty->print_cr(" %d VPointer::offset_plus_k: FAILED", n->_idx); - } + st->print(")]"); + if (end_with_cr) { st->cr(); } } #endif - AlignmentSolution* AlignmentSolver::solve() const { DEBUG_ONLY( trace_start_solve(); ) @@ -1667,9 +435,9 @@ AlignmentSolution* AlignmentSolver::solve() const { assert(is_power_of_2(abs(_main_stride)), "main_stride is power of 2"); assert(_aw > 0 && is_power_of_2(_aw), "aw must be power of 2"); - // Out of simplicity: non power-of-2 scale not supported. - if (abs(_scale) == 0 || !is_power_of_2(abs(_scale))) { - return new EmptyAlignmentSolution("non power-of-2 scale not supported"); + // Out of simplicity: non power-of-2 iv_scale not supported. + if (abs(iv_scale()) == 0 || !is_power_of_2(abs(iv_scale()))) { + return new EmptyAlignmentSolution("non power-of-2 iv_scale not supported"); } // We analyze the address of mem_ref. The idea is to disassemble it into a linear @@ -1678,7 +446,7 @@ AlignmentSolution* AlignmentSolver::solve() const { // // The Simple form of the address is disassembled by VPointer into: // - // adr = base + offset + invar + scale * iv + // adr = base + invar + iv_scale * iv + con // // Where the iv can be written as: // @@ -1694,14 +462,14 @@ AlignmentSolution* AlignmentSolver::solve() const { // expanding the iv variable. In a second step, we reshape the expression again, and // state it as a linear expression, consisting of 6 terms. // - // Simple form Expansion of iv variable Reshaped with constants Comments for terms - // ----------- ------------------------ ----------------------- ------------------ - // adr = base = base = base (base % aw = 0) - // + offset + offset + C_const (sum of constant terms) - // + invar + invar_factor * var_invar + C_invar * var_invar (term for invariant) - // / + scale * init + C_init * var_init (term for variable init) - // + scale * iv -> | + scale * pre_stride * pre_iter + C_pre * pre_iter (adjustable pre-loop term) - // \ + scale * main_stride * main_iter + C_main * main_iter (main-loop term) + // Simple form Expansion of iv variable Reshaped with constants Comments for terms + // ----------- ------------------------ ----------------------- ------------------ + // adr = base = base = base (assume: base % aw = 0) + // + invar + invar_factor * var_invar + C_invar * var_invar (term for invariant) + // / + iv_scale * init + C_init * var_init (term for variable init) + // + iv_scale * iv -> | + iv_scale * pre_stride * pre_iter + C_pre * pre_iter (adjustable pre-loop term) + // \ + iv_scale * main_stride * main_iter + C_main * main_iter (main-loop term) + // + con + con + C_const (sum of constant terms) // // We describe the 6 terms: // 1) The "base" of the address is the address of a Java object (e.g. array), @@ -1711,19 +479,22 @@ AlignmentSolution* AlignmentSolver::solve() const { // // base % ObjectAlignmentInBytes = 0 ==> base % aw = 0 // - // 2) The "C_const" term is the sum of all constant terms. This is "offset", - // plus "scale * init" if it is constant. + // TODO: Note: we have been assuming that this also holds for native memory base + // addresses. This is incorrect, see JDK-8323582. + // + // 2) The "C_const" term is the sum of all constant terms. This is "con", + // plus "iv_scale * init" if it is constant. // 3) The "C_invar * var_invar" is the factorization of "invar" into a constant // and variable term. If there is no invariant, then "C_invar" is zero. // // invar = C_invar * var_invar (FAC_INVAR) // - // 4) The "C_init * var_init" is the factorization of "scale * init" into a + // 4) The "C_init * var_init" is the factorization of "iv_scale * init" into a // constant and a variable term. If "init" is constant, then "C_init" is // zero, and "C_const" accounts for "init" instead. // - // scale * init = C_init * var_init + scale * C_const_init (FAC_INIT) - // C_init = (init is constant) ? 0 : scale + // iv_scale * init = C_init * var_init + iv_scale * C_const_init (FAC_INIT) + // C_init = (init is constant) ? 0 : iv_scale // C_const_init = (init is constant) ? init : 0 // // 5) The "C_pre * pre_iter" term represents how much the iv is incremented @@ -1736,20 +507,21 @@ AlignmentSolution* AlignmentSolver::solve() const { // Attribute init (i.e. _init_node) either to C_const or to C_init term. const int C_const_init = _init_node->is_ConI() ? _init_node->as_ConI()->get_int() : 0; - const int C_const = _offset + C_const_init * _scale; + const int C_const = _vpointer.con() + C_const_init * iv_scale(); // Set C_invar depending on if invar is present - const int C_invar = (_invar == nullptr) ? 0 : abs(_invar_factor); + const int C_invar = _vpointer.compute_invar_factor(); - const int C_init = _init_node->is_ConI() ? 0 : _scale; - const int C_pre = _scale * _pre_stride; - const int C_main = _scale * _main_stride; + const int C_init = _init_node->is_ConI() ? 0 : iv_scale(); + const int C_pre = iv_scale() * _pre_stride; + const int C_main = iv_scale() * _main_stride; DEBUG_ONLY( trace_reshaped_form(C_const, C_const_init, C_invar, C_init, C_pre, C_main); ) // We must find a pre_iter, such that adr is aw aligned: adr % aw = 0. Note, that we are defining the // modulo operator "%" such that the remainder is always positive, see AlignmentSolution::mod(i, q). // + // TODO: Note: the following assumption is incorrect for native memory bases, see JDK-8323582. // Since "base % aw = 0", we only need to ensure alignment of the other 5 terms: // // (C_const + C_invar * var_invar + C_init * var_init + C_pre * pre_iter + C_main * main_iter) % aw = 0 (1) @@ -2028,7 +800,7 @@ AlignmentSolution* AlignmentSolver::solve() const { // pre_iter_C_const = mx2 * q - sign(C_pre) * X // = mx2 * q - sign(C_pre) * C_const / abs(C_pre) // = mx2 * q - C_const / C_pre - // = mx2 * q - C_const / (scale * pre_stride) (11a) + // = mx2 * q - C_const / (iv_scale * pre_stride) (11a) // // If there is an invariant: // @@ -2036,19 +808,19 @@ AlignmentSolution* AlignmentSolver::solve() const { // = my2 * q - sign(C_pre) * C_invar * var_invar / abs(C_pre) // = my2 * q - sign(C_pre) * invar / abs(C_pre) // = my2 * q - invar / C_pre - // = my2 * q - invar / (scale * pre_stride) (11b, with invar) + // = my2 * q - invar / (iv_scale * pre_stride) (11b, with invar) // // If there is no invariant (i.e. C_invar = 0 ==> Y = 0): // // pre_iter_C_invar = my2 * q (11b, no invar) // - // If init is variable (i.e. C_init = scale, init = var_init): + // If init is variable (i.e. C_init = iv_scale, init = var_init): // - // pre_iter_C_init = mz2 * q - sign(C_pre) * Z * var_init - // = mz2 * q - sign(C_pre) * C_init * var_init / abs(C_pre) - // = mz2 * q - sign(C_pre) * scale * init / abs(C_pre) - // = mz2 * q - scale * init / C_pre - // = mz2 * q - scale * init / (scale * pre_stride) + // pre_iter_C_init = mz2 * q - sign(C_pre) * Z * var_init + // = mz2 * q - sign(C_pre) * C_init * var_init / abs(C_pre) + // = mz2 * q - sign(C_pre) * iv_scale * init / abs(C_pre) + // = mz2 * q - iv_scale * init / C_pre + // = mz2 * q - iv_scale * init / (iv_scale * pre_stride) // = mz2 * q - init / pre_stride (11c, variable init) // // If init is constant (i.e. C_init = 0 ==> Z = 0): @@ -2059,35 +831,35 @@ AlignmentSolution* AlignmentSolver::solve() const { // with m = mx2 + my2 + mz2: // // pre_iter = pre_iter_C_const + pre_iter_C_invar + pre_iter_C_init - // = mx2 * q - C_const / (scale * pre_stride) - // + my2 * q [- invar / (scale * pre_stride) ] - // + mz2 * q [- init / pre_stride ] + // = mx2 * q - C_const / (iv_scale * pre_stride) + // + my2 * q [- invar / (iv_scale * pre_stride) ] + // + mz2 * q [- init / pre_stride ] // // = m * q (periodic part) - // - C_const / (scale * pre_stride) (align constant term) - // [- invar / (scale * pre_stride) ] (align invariant term, if present) - // [- init / pre_stride ] (align variable init term, if present) (12) + // - C_const / (iv_scale * pre_stride) (align constant term) + // [- invar / (iv_scale * pre_stride) ] (align invariant term, if present) + // [- init / pre_stride ] (align variable init term, if present) (12) // // We can further simplify this solution by introducing integer 0 <= r < q: // - // r = (-C_const / (scale * pre_stride)) % q (13) + // r = (-C_const / (iv_scale * pre_stride)) % q (13) // - const int r = AlignmentSolution::mod(-C_const / (_scale * _pre_stride), q); + const int r = AlignmentSolution::mod(-C_const / (iv_scale() * _pre_stride), q); // // pre_iter = m * q + r - // [- invar / (scale * pre_stride) ] - // [- init / pre_stride ] (14) + // [- invar / (iv_scale * pre_stride) ] + // [- init / pre_stride ] (14) // // We thus get a solution that can be stated in terms of: // - // q (periodicity), r (constant alignment), invar, scale, pre_stride, init + // q (periodicity), r (constant alignment), invar, iv_scale, pre_stride, init // // However, pre_stride and init are shared by all mem_ref in the loop, hence we do not need to provide // them in the solution description. DEBUG_ONLY( trace_constrained_solution(C_const, C_invar, C_init, C_pre, q, r); ) - return new ConstrainedAlignmentSolution(_mem_ref, q, r, _invar, _scale); + return new ConstrainedAlignmentSolution(_mem_ref, q, r, _vpointer /* holds invar and iv_scale */); // APPENDIX: // We can now verify the success of the solution given by (12): @@ -2095,48 +867,49 @@ AlignmentSolution* AlignmentSolver::solve() const { // adr % aw = // // -> Simple form - // (base + offset + invar + scale * iv) % aw = + // (base + invar + iv_scale * iv + con) % aw = // // -> Expand iv - // (base + offset + invar + scale * (init + pre_stride * pre_iter + main_stride * main_iter)) % aw = + // (base + con + invar + iv_scale * (init + pre_stride * pre_iter + main_stride * main_iter)) % aw = // // -> Reshape - // (base + offset + invar - // + scale * init - // + scale * pre_stride * pre_iter - // + scale * main_stride * main_iter)) % aw = + // (base + con + invar + // + iv_scale * init + // + iv_scale * pre_stride * pre_iter + // + iv_scale * main_stride * main_iter)) % aw = // // -> base aligned: base % aw = 0 - // -> main-loop iterations aligned (2): C_main % aw = (scale * main_stride) % aw = 0 - // (offset + invar + scale * init + scale * pre_stride * pre_iter) % aw = + // TODO: Note: this assumption is incorrect for native memory bases, see JDK-8323582. + // -> main-loop iterations aligned (2): C_main % aw = (iv_scale * main_stride) % aw = 0 + // (con + invar + iv_scale * init + iv_scale * pre_stride * pre_iter) % aw = // // -> apply (12) - // (offset + invar + scale * init - // + scale * pre_stride * (m * q - C_const / (scale * pre_stride) - // [- invar / (scale * pre_stride) ] - // [- init / pre_stride ] + // (con + invar + iv_scale * init + // + iv_scale * pre_stride * (m * q - C_const / (iv_scale * pre_stride) + // [- invar / (iv_scale * pre_stride) ] + // [- init / pre_stride ] // ) // ) % aw = // - // -> expand C_const = offset [+ init * scale] (if init const) - // (offset + invar + scale * init - // + scale * pre_stride * (m * q - offset / (scale * pre_stride) - // [- init / pre_stride ] (if init constant) - // [- invar / (scale * pre_stride) ] (if invar present) - // [- init / pre_stride ] (if init variable) + // -> expand C_const = con [+ init * iv_scale] (if init const) + // (con + invar + iv_scale * init + // + iv_scale * pre_stride * (m * q - con / (iv_scale * pre_stride) + // [- init / pre_stride ] (if init constant) + // [- invar / (iv_scale * pre_stride) ] (if invar present) + // [- init / pre_stride ] (if init variable) // ) // ) % aw = // // -> assuming invar = 0 if it is not present // -> merge the two init terms (variable or constant) - // -> apply (8): q = aw / (abs(C_pre)) = aw / abs(scale * pre_stride) - // -> and hence: (scale * pre_stride * q) % aw = 0 + // -> apply (8): q = aw / (abs(C_pre)) = aw / abs(iv_scale * pre_stride) + // -> and hence: (iv_scale * pre_stride * q) % aw = 0 // -> all terms are canceled out - // (offset + invar + scale * init - // + scale * pre_stride * m * q -> aw aligned - // - scale * pre_stride * offset / (scale * pre_stride) -> = offset - // - scale * pre_stride * init / pre_stride -> = scale * init - // - scale * pre_stride * invar / (scale * pre_stride) -> = invar + // (con + invar + iv_scale * init + // + iv_scale * pre_stride * m * q -> aw aligned + // - iv_scale * pre_stride * con / (iv_scale * pre_stride) -> = con + // - iv_scale * pre_stride * init / pre_stride -> = iv_scale * init + // - iv_scale * pre_stride * invar / (iv_scale * pre_stride) -> = invar // ) % aw = 0 // // The solution given by (12) does indeed guarantee alignment. @@ -2147,8 +920,9 @@ void AlignmentSolver::trace_start_solve() const { if (is_trace()) { tty->print(" vector mem_ref:"); _mem_ref->dump(); - tty->print_cr(" vector_width = vector_length(%d) * element_size(%d) = %d", - _vector_length, _element_size, _vector_width); + tty->print(" VPointer: "); + _vpointer.print_on(tty); + tty->print_cr(" vector_width = %d", _vector_width); tty->print_cr(" aw = alignment_width = min(vector_width(%d), ObjectAlignmentInBytes(%d)) = %d", _vector_width, ObjectAlignmentInBytes, _aw); @@ -2157,25 +931,34 @@ void AlignmentSolver::trace_start_solve() const { _init_node->dump(); } - if (_invar != nullptr) { - tty->print(" invar:"); - _invar->dump(); + tty->print_cr(" invar = SUM(invar_summands), invar_summands:"); + int invar_count = 0; + _vpointer.for_each_invar_summand([&] (const MemPointerSummand& s) { + tty->print(" "); + s.print_on(tty); + tty->print(" -> "); + s.variable()->dump(); + invar_count++; + }); + if (invar_count == 0) { + tty->print_cr(" No invar_summands."); } - tty->print_cr(" invar_factor = %d", _invar_factor); + const jint invar_factor = _vpointer.compute_invar_factor(); + tty->print_cr(" invar_factor = %d", invar_factor); // iv = init + pre_iter * pre_stride + main_iter * main_stride tty->print(" iv = init"); - VPointer::print_con_or_idx(_init_node); + if (_init_node->is_ConI()) { + tty->print("(%4d)", _init_node->as_ConI()->get_int()); + } else { + tty->print("[%4d]", _init_node->_idx); + } tty->print_cr(" + pre_iter * pre_stride(%d) + main_iter * main_stride(%d)", _pre_stride, _main_stride); - - // adr = base + offset + invar + scale * iv - tty->print(" adr = base"); - VPointer::print_con_or_idx(_base); - tty->print(" + offset(%d) + invar", _offset); - VPointer::print_con_or_idx(_invar); - tty->print_cr(" + scale(%d) * iv", _scale); + // adr = base + con + invar + iv_scale * iv + tty->print(" adr = base[%d]", base().object_or_native()->_idx); + tty->print(" + invar + iv_scale(%d) * iv + con(%d)", iv_scale(), _vpointer.con()); } } @@ -2187,7 +970,7 @@ void AlignmentSolver::trace_reshaped_form(const int C_const, const int C_main) const { if (is_trace()) { - tty->print(" = base[%d] + ", _base->_idx); + tty->print(" = base[%d] + ", base().object_or_native()->_idx); tty->print_cr("C_const(%d) + C_invar(%d) * var_invar + C_init(%d) * var_init + C_pre(%d) * pre_iter + C_main(%d) * main_iter", C_const, C_invar, C_init, C_pre, C_main); if (_init_node->is_ConI()) { @@ -2197,21 +980,21 @@ void AlignmentSolver::trace_reshaped_form(const int C_const, } else { tty->print_cr(" init is variable:"); tty->print_cr(" C_const_init = %d", C_const_init); - tty->print_cr(" C_init = abs(scale)= %d", C_init); + tty->print_cr(" C_init = abs(iv_scale)= %d", C_init); } - if (_invar != nullptr) { + if (C_invar != 0) { tty->print_cr(" invariant present:"); - tty->print_cr(" C_invar = abs(invar_factor) = %d", C_invar); + tty->print_cr(" C_invar = invar_factor = %d", C_invar); } else { tty->print_cr(" no invariant:"); tty->print_cr(" C_invar = %d", C_invar); } - tty->print_cr(" C_const = offset(%d) + scale(%d) * C_const_init(%d) = %d", - _offset, _scale, C_const_init, C_const); - tty->print_cr(" C_pre = scale(%d) * pre_stride(%d) = %d", - _scale, _pre_stride, C_pre); - tty->print_cr(" C_main = scale(%d) * main_stride(%d) = %d", - _scale, _main_stride, C_main); + tty->print_cr(" C_const = con(%d) + iv_scale(%d) * C_const_init(%d) = %d", + _vpointer.con(), iv_scale(), C_const_init, C_const); + tty->print_cr(" C_pre = iv_scale(%d) * pre_stride(%d) = %d", + iv_scale(), _pre_stride, C_pre); + tty->print_cr(" C_main = iv_scale(%d) * main_stride(%d) = %d", + iv_scale(), _main_stride, C_main); } } @@ -2280,13 +1063,13 @@ void AlignmentSolver::trace_constrained_solution(const int C_const, tty->print_cr(" EQ(10b): pre_iter_C_invar = my2 * q(%d) - sign(C_pre) * Y(%d) * var_invar", q, Y); tty->print_cr(" EQ(10c): pre_iter_C_init = mz2 * q(%d) - sign(C_pre) * Z(%d) * var_init ", q, Z); - tty->print_cr(" r = (-C_const(%d) / (scale(%d) * pre_stride(%d)) %% q(%d) = %d", - C_const, _scale, _pre_stride, q, r); + tty->print_cr(" r = (-C_const(%d) / (iv_scale(%d) * pre_stride(%d)) %% q(%d) = %d", + C_const, iv_scale(), _pre_stride, q, r); tty->print_cr(" EQ(14): pre_iter = m * q(%3d) - r(%d)", q, r); - if (_invar != nullptr) { - tty->print_cr(" - invar / (scale(%d) * pre_stride(%d))", - _scale, _pre_stride); + if (C_invar != 0) { + tty->print_cr(" - invar / (iv_scale(%d) * pre_stride(%d))", + iv_scale(), _pre_stride); } if (!_init_node->is_ConI()) { tty->print_cr(" - init / pre_stride(%d)", diff --git a/src/hotspot/share/opto/vectorization.hpp b/src/hotspot/share/opto/vectorization.hpp index 98aa3336dedf2..cb1e8c4585675 100644 --- a/src/hotspot/share/opto/vectorization.hpp +++ b/src/hotspot/share/opto/vectorization.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,7 @@ #include "opto/matcher.hpp" #include "opto/loopnode.hpp" #include "opto/traceAutoVectorizationTag.hpp" +#include "opto/mempointer.hpp" #include "utilities/pair.hpp" // Code in this file and the vectorization.cpp contains shared logics and @@ -85,6 +86,7 @@ class VLoop : public StackObj { CountedLoopEndNode* _pre_loop_end; // cache access to pre-loop for main loops only NOT_PRODUCT(VTrace _vtrace;) + NOT_PRODUCT(TraceMemPointer _mptrace;) static constexpr char const* FAILURE_ALREADY_VECTORIZED = "loop already vectorized"; static constexpr char const* FAILURE_UNROLL_ONLY = "loop only wants to be unrolled"; @@ -102,7 +104,18 @@ class VLoop : public StackObj { _cl (nullptr), _cl_exit (nullptr), _iv (nullptr), - _pre_loop_end (nullptr) {} + _pre_loop_end (nullptr) +#ifndef PRODUCT + COMMA + _mptrace(TraceMemPointer( + _vtrace.is_trace(TraceAutoVectorizationTag::POINTER_PARSING), + _vtrace.is_trace(TraceAutoVectorizationTag::POINTER_ALIASING), + _vtrace.is_trace(TraceAutoVectorizationTag::POINTER_ADJACENCY), + _vtrace.is_trace(TraceAutoVectorizationTag::POINTER_OVERLAP) + )) +#endif + {} + NONCOPYABLE(VLoop); IdealLoopTree* lpt() const { return _lpt; }; @@ -133,7 +146,8 @@ class VLoop : public StackObj { static bool vectors_should_be_aligned() { return !Matcher::misaligned_vectors_ok() || AlignVector; } #ifndef PRODUCT - const VTrace& vtrace() const { return _vtrace; } + const VTrace& vtrace() const { return _vtrace; } + const TraceMemPointer& mptrace() const { return _mptrace; } bool is_trace_preconditions() const { return _vtrace.is_trace(TraceAutoVectorizationTag::PRECONDITIONS); @@ -162,10 +176,6 @@ class VLoop : public StackObj { bool is_trace_vpointers() const { return _vtrace.is_trace(TraceAutoVectorizationTag::POINTERS); } - - bool is_trace_pointer_analysis() const { - return _vtrace.is_trace(TraceAutoVectorizationTag::POINTER_ANALYSIS); - } #endif // Is the node in the basic block of the loop? @@ -175,6 +185,27 @@ class VLoop : public StackObj { return n != nullptr && n->outcnt() > 0 && ctrl == _cl; } + // Some nodes must be pre-loop invariant, so that they can be used for conditions + // before or inside the pre-loop. For example, alignment of main-loop vector + // memops must be achieved in the pre-loop, via the exit check in the pre-loop. + bool is_pre_loop_invariant(Node* n) const { + // Must be in the main-loop, otherwise we can't access the pre-loop. + // This fails during SuperWord::unrolling_analysis, but that is ok. + if (!cl()->is_main_loop()) { + return false; + } + + Node* ctrl = phase()->get_ctrl(n); + + // Quick test: is it in the main-loop? + if (lpt()->is_member(phase()->get_loop(ctrl))) { + return false; + } + + // Is it before the pre-loop? + return phase()->is_dominator(ctrl, pre_loop_head()); + } + // Check if the loop passes some basic preconditions for vectorization. // Return indicates if analysis succeeded. bool check_preconditions(); @@ -427,7 +458,7 @@ class VLoopTypes : public StackObj { return velt_type(n)->array_element_basic_type(); } - int data_size(Node* s) const { + int data_size(const Node* s) const { int bsize = type2aelembytes(velt_basic_type(s)); assert(bsize != 0, "valid size"); return bsize; @@ -667,340 +698,300 @@ class VLoopAnalyzer : StackObj { VStatus setup_submodules_helper(); }; -// A vectorization pointer (VPointer) has information about an address for -// dependence checking and vector alignment. It's usually bound to a memory -// operation in a counted loop for vectorizable analysis. +// Reminder: MemPointer have the form: // -// We parse and represent pointers of the simple form: +// pointer = SUM(summands) + con // -// pointer = adr + offset + invar + scale * ConvI2L(iv) +// Where every summand in summands has the form: // -// Where: -// -// adr: the base address of an array (base = adr) -// OR -// some address to off-heap memory (base = TOP) -// -// offset: a constant offset -// invar: a runtime variable, which is invariant during the loop -// scale: scaling factor -// iv: loop induction variable +// summand = scale * variable // -// But more precisely, we parse the composite-long-int form: +// The VPointer wraps a MemPointer for the use in loops. A "valid" VPointer has +// the form: // -// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv) +// pointer = base + invar + iv_summand + con +// with +// invar = SUM(invar_summands) +// iv_summand = iv_scale * iv // -// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index) -// int_index = int_offset + int_invar + int_scale * iv -// -// However, for aliasing and adjacency checks (e.g. VPointer::cmp()) we always use the simple form to make -// decisions. Hence, we must make sure to only create a "valid" VPointer if the optimisations based on the -// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on -// if the int_index overflows, but the precise conditions are given in VPointer::is_safe_to_use_as_simple_form(). -// -// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv) -// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv) +// Where: +// - base: is the known base of the MemPointer. +// on-heap (object base) or off-heap (native base address) +// - iv and iv_scale: i.e. the iv_summand = iv * iv_scale. +// If we find a summand where the variable is the iv, we set iv_scale to the +// corresponding scale. If there is no such summand, then we know that the +// pointer does not depend on the iv, since otherwise there would have to be +// a summand where its variable is main-loop variant. Note: MemPointer already +// ensures that there is at most one summand per variable, so there is at +// most one summand with iv. +// - invar_summands: all other summands except base and iv_summand. +// All variables must be pre-loop invariant. This is important when we need +// to memory align a pointer using the pre-loop limit. // -// scale = long_scale * ConvI2L(int_scale) -// offset = long_offset + long_scale * ConvI2L(int_offset) -// invar = long_invar + long_scale * ConvI2L(int_invar) +// These are examples where a VPointer becomes "invalid": +// - If the MemPointer does not have the required form for VPointer, +// i.e. if one of these conditions is not met (see init_is_valid): +// - Base must be known. +// - All summands except the iv-summand must be pre-loop invariant. +// - Some restrictions on iv_scale and iv_stride, to avoid overflow in +// alignment computations. +// - If the new con computed in make_with_iv_offset overflows. // -// pointer = adr + offset + invar + scale * ConvI2L(iv) +// If a VPointer is marked "invalid", it always returns conservative answers to +// aliasing queries, which means that we do not optimize in these cases. +// For example: +// - is_adjacent_to_and_before: returning true would allow optimizations such as +// packing into vectors. So for "invalid" VPointers, +// we always return false (i.e. unknown). +// - never_overlaps_with: returning true would allow optimizations such as +// swapping the order of memops. So for "invalid" VPointers, +// we always return false (i.e. unknown). // class VPointer : public ArenaObj { - protected: - MemNode* const _mem; // My memory reference node - const VLoop& _vloop; +private: + const VLoop& _vloop; + const MemPointer _mem_pointer; - // Components of the simple form: - Node* _base; // Base address of an array OR null if some off-heap memory. - Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer. - int _scale; // multiplier for iv (in bytes), 0 if no loop iv - int _offset; // constant offset (in bytes) + // Derived, for quicker use. + const jint _iv_scale; - Node* _invar; // invariant offset (in bytes), null if none -#ifdef ASSERT - Node* _debug_invar; - bool _debug_negate_invar; // if true then use: (0 - _invar) - Node* _debug_invar_scale; // multiplier for invariant -#endif + const bool _is_valid; - // The int_index components of the compound-long-int form. Used to decide if it is safe to use the - // simple form rather than the compound-long-int form that was parsed. - bool _has_int_index_after_convI2L; - int _int_index_after_convI2L_offset; - Node* _int_index_after_convI2L_invar; - int _int_index_after_convI2L_scale; - - Node_Stack* _nstack; // stack used to record a vpointer trace of variants - bool _analyze_only; // Used in loop unrolling only for vpointer trace - uint _stack_idx; // Used in loop unrolling only for vpointer trace - - PhaseIdealLoop* phase() const { return _vloop.phase(); } - IdealLoopTree* lpt() const { return _vloop.lpt(); } - PhiNode* iv() const { return _vloop.iv(); } - - bool is_loop_member(Node* n) const; - bool invariant(Node* n) const; - - // Match: k*iv + offset - bool scaled_iv_plus_offset(Node* n); - // Match: k*iv where k is a constant that's not zero - bool scaled_iv(Node* n); - // Match: offset is (k [+/- invariant]) - bool offset_plus_k(Node* n, bool negate = false); - - public: - enum CMP { - Less = 1, - Greater = 2, - Equal = 4, - NotEqual = (Less | Greater), - NotComparable = (Less | Greater | Equal) - }; + VPointer(const VLoop& vloop, + const MemPointer& mem_pointer, + const bool must_be_invalid = false) : + _vloop(vloop), + _mem_pointer(mem_pointer), + _iv_scale(init_iv_scale()), + _is_valid(!must_be_invalid && init_is_valid()) {} - VPointer(MemNode* const mem, const VLoop& vloop) : - VPointer(mem, vloop, nullptr, false) {} - VPointer(MemNode* const mem, const VLoop& vloop, Node_Stack* nstack) : - VPointer(mem, vloop, nstack, true) {} - private: - VPointer(MemNode* const mem, const VLoop& vloop, - Node_Stack* nstack, bool analyze_only); - // Following is used to create a temporary object during - // the pattern match of an address expression. - VPointer(VPointer* p); - NONCOPYABLE(VPointer); - - bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const; - - public: - bool valid() const { return _adr != nullptr; } - bool has_iv() const { return _scale != 0; } - - Node* base() const { return _base; } - Node* adr() const { return _adr; } - MemNode* mem() const { return _mem; } - int scale_in_bytes() const { return _scale; } - Node* invar() const { return _invar; } - int offset_in_bytes() const { return _offset; } - int memory_size() const { return _mem->memory_size(); } - Node_Stack* node_stack() const { return _nstack; } - - // Biggest detectable factor of the invariant. - int invar_factor() const; - - // Comparable? - bool invar_equals(const VPointer& q) const { - assert(_debug_invar == NodeSentinel || q._debug_invar == NodeSentinel || - (_invar == q._invar) == (_debug_invar == q._debug_invar && - _debug_invar_scale == q._debug_invar_scale && - _debug_negate_invar == q._debug_negate_invar), ""); - return _invar == q._invar; + VPointer make_invalid() const { + return VPointer(_vloop, mem_pointer(), true /* must be invalid*/); } - // We compute if and how two VPointers can alias at runtime, i.e. if the two addressed regions of memory can - // ever overlap. There are essentially 3 relevant return states: - // - NotComparable: Synonymous to "unknown aliasing". - // We have no information about how the two VPointers can alias. They could overlap, refer - // to another location in the same memory object, or point to a completely different object. - // -> Memory edge required. Aliasing unlikely but possible. - // - // - Less / Greater: Synonymous to "never aliasing". - // The two VPointers may point into the same memory object, but be non-aliasing (i.e. we - // know both address regions inside the same memory object, but these regions are non- - // overlapping), or the VPointers point to entirely different objects. - // -> No memory edge required. Aliasing impossible. - // - // - Equal: Synonymous to "overlap, or point to different memory objects". - // The two VPointers either overlap on the same memory object, or point to two different - // memory objects. - // -> Memory edge required. Aliasing likely. - // - // In a future refactoring, we can simplify to two states: - // - NeverAlias: instead of Less / Greater - // - MayAlias: instead of Equal / NotComparable - // - // Two VPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply: - // 1) Both are valid, i.e. expressible in the compound-long-int or simple form. - // 2) The adr are identical, or both are array bases of different arrays. - // 3) They have identical scale. - // 4) They have identical invar. - // 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31. - int cmp(const VPointer& q) const { - if (valid() && q.valid() && - (_adr == q._adr || (_base == _adr && q._base == q._adr)) && - _scale == q._scale && invar_equals(q)) { - jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset)); - jlong max_diff = (jlong)1 << 31; - if (difference >= max_diff) { - return NotComparable; - } - bool overlap = q._offset < _offset + memory_size() && - _offset < q._offset + q.memory_size(); - return overlap ? Equal : (_offset < q._offset ? Less : Greater); - } else { - return NotComparable; +public: + VPointer(const MemNode* mem, + const VLoop& vloop, + MemPointerParserCallback& callback = MemPointerParserCallback::empty()) : + VPointer(vloop, + MemPointer(mem, + callback + NOT_PRODUCT(COMMA vloop.mptrace()))) + { +#ifndef PRODUCT + if (vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::VPointer:"); + tty->print("mem: "); mem->dump(); + print_on(tty); } +#endif } - bool overlap_possible_with_any_in(const GrowableArray& nodes) const { - for (int i = 0; i < nodes.length(); i++) { - MemNode* mem = nodes.at(i)->as_Mem(); - VPointer p_mem(mem, _vloop); - // Only if we know that we have Less or Greater can we - // be sure that there can never be an overlap between - // the two memory regions. - if (!not_equal(p_mem)) { - return true; - } + VPointer make_with_size(const jint new_size) const { + const VPointer p(_vloop, mem_pointer().make_with_size(new_size)); +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::make_with_size:"); + tty->print(" old: "); print_on(tty); + tty->print(" new: "); p.print_on(tty); } - return false; +#endif + return p; } - bool not_equal(const VPointer& q) const { return not_equal(cmp(q)); } - bool equal(const VPointer& q) const { return equal(cmp(q)); } - bool comparable(const VPointer& q) const { return comparable(cmp(q)); } - static bool not_equal(int cmp) { return cmp <= NotEqual; } - static bool equal(int cmp) { return cmp == Equal; } - static bool comparable(int cmp) { return cmp < NotComparable; } - - // We need to be able to sort the VPointer to efficiently group the - // memops into groups, and to find adjacent memops. - static int cmp_for_sort_by_group(const VPointer** p1, const VPointer** p2); - static int cmp_for_sort(const VPointer** p1, const VPointer** p2); - - NOT_PRODUCT( void print() const; ) - NOT_PRODUCT( static void print_con_or_idx(const Node* n); ) - + // old_pointer = base + invar + iv_scale * iv + con + // new_pointer = base + invar + iv_scale * (iv + iv_offset) + con + // = base + invar + iv_scale * iv + (con + iv_scale * iv_offset) + VPointer make_with_iv_offset(const jint iv_offset) const { + NoOverflowInt new_con = NoOverflowInt(con()) + NoOverflowInt(iv_scale()) * NoOverflowInt(iv_offset); + if (new_con.is_NaN()) { #ifndef PRODUCT - class Tracer { - friend class VPointer; - bool _is_trace_alignment; - static int _depth; - int _depth_save; - void print_depth() const; - int depth() const { return _depth; } - void set_depth(int d) { _depth = d; } - void inc_depth() { _depth++; } - void dec_depth() { if (_depth > 0) _depth--; } - void store_depth() { _depth_save = _depth; } - void restore_depth() { _depth = _depth_save; } - - class Depth { - friend class VPointer; - Depth() { ++_depth; } - Depth(int x) { _depth = 0; } - ~Depth() { if (_depth > 0) --_depth; } - }; - Tracer(bool is_trace_alignment) : _is_trace_alignment(is_trace_alignment) {} - - // tracing functions - void ctor_1(const Node* mem); - void ctor_2(Node* adr); - void ctor_3(Node* adr, int i); - void ctor_4(Node* adr, int i); - void ctor_5(Node* adr, Node* base, int i); - void ctor_6(const Node* mem); - - void scaled_iv_plus_offset_1(Node* n); - void scaled_iv_plus_offset_2(Node* n); - void scaled_iv_plus_offset_3(Node* n); - void scaled_iv_plus_offset_4(Node* n); - void scaled_iv_plus_offset_5(Node* n); - void scaled_iv_plus_offset_6(Node* n); - void scaled_iv_plus_offset_7(Node* n); - void scaled_iv_plus_offset_8(Node* n); - - void scaled_iv_1(Node* n); - void scaled_iv_2(Node* n, int scale); - void scaled_iv_3(Node* n, int scale); - void scaled_iv_4(Node* n, int scale); - void scaled_iv_5(Node* n, int scale); - void scaled_iv_6(Node* n, int scale); - void scaled_iv_7(Node* n); - void scaled_iv_8(Node* n, VPointer* tmp); - void scaled_iv_9(Node* n, int _scale, int _offset, Node* _invar); - void scaled_iv_10(Node* n); - - void offset_plus_k_1(Node* n); - void offset_plus_k_2(Node* n, int _offset); - void offset_plus_k_3(Node* n, int _offset); - void offset_plus_k_4(Node* n); - void offset_plus_k_5(Node* n, Node* _invar); - void offset_plus_k_6(Node* n, Node* _invar, bool _negate_invar, int _offset); - void offset_plus_k_7(Node* n, Node* _invar, bool _negate_invar, int _offset); - void offset_plus_k_8(Node* n, Node* _invar, bool _negate_invar, int _offset); - void offset_plus_k_9(Node* n, Node* _invar, bool _negate_invar, int _offset); - void offset_plus_k_10(Node* n, Node* _invar, bool _negate_invar, int _offset); - void offset_plus_k_11(Node* n); - } _tracer; // Tracer + if (_vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::make_with_iv_offset:"); + tty->print(" old: "); print_on(tty); + tty->print_cr(" new con overflow (iv_offset: %d) -> invalid VPointer.", iv_offset); + } #endif + return make_invalid(); + } + const VPointer p(_vloop, mem_pointer().make_with_con(new_con)); +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::make_with_iv_offset:"); + tty->print(" old: "); print_on(tty); + tty->print(" new: "); p.print_on(tty); + } +#endif + return p; + } - Node* maybe_negate_invar(bool negate, Node* invar); + // Accessors + bool is_valid() const { return _is_valid; } + const MemPointer& mem_pointer() const { assert(_is_valid, "must be valid"); return _mem_pointer; } + jint size() const { assert(_is_valid, "must be valid"); return mem_pointer().size(); } + jint iv_scale() const { assert(_is_valid, "must be valid"); return _iv_scale; } + jint con() const { return mem_pointer().con().value(); } - void maybe_add_to_invar(Node* new_invar, bool negate); + template + void for_each_invar_summand(Callback callback) const { + mem_pointer().for_each_non_empty_summand([&] (const MemPointerSummand& s) { + Node* variable = s.variable(); + if (variable != mem_pointer().base().object_or_native() && + _vloop.is_pre_loop_invariant(variable)) { + callback(s); + } + }); + } - static bool try_AddI_no_overflow(int offset1, int offset2, int& result); - static bool try_SubI_no_overflow(int offset1, int offset2, int& result); - static bool try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result); - static bool try_LShiftI_no_overflow(int offset1, int offset2, int& result); - static bool try_MulI_no_overflow(int offset1, int offset2, int& result); + // Greatest common factor among the scales of the invar_summands. + // Out of simplicity, we only factor out positive powers-of-2, + // between (inclusive) 1 and ObjectAlignmentInBytes. If the invar + // is empty, i.e. there is no summand in invar_summands, we return 0. + jint compute_invar_factor() const { + jint factor = ObjectAlignmentInBytes; + int invar_count = 0; + for_each_invar_summand([&] (const MemPointerSummand& s) { + invar_count++; + while (!s.scale().is_multiple_of(NoOverflowInt(factor))) { + factor = factor / 2; + } + }); + return invar_count > 0 ? factor : 0; + } - Node* register_if_new(Node* n) const; -}; + bool has_invar_summands() const { + int invar_count = 0; + for_each_invar_summand([&] (const MemPointerSummand& s) { + invar_count++; + }); + return invar_count > 0; + } + + // If we have the same invar_summands, and the same iv summand with the same iv_scale, + // then all summands except the base must be the same. + bool has_same_invar_summands_and_iv_scale_as(const VPointer& other) const { + return mem_pointer().has_same_non_base_summands_as(other.mem_pointer()); + } -// Vector element size statistics for loop vectorization with vector masks -class VectorElementSizeStats { - private: - static const int NO_SIZE = -1; - static const int MIXED_SIZE = -2; - int* _stats; + // Delegate to MemPointer::is_adjacent_to_and_before, but guard for invalid cases + // where we must return a conservative answer: unknown adjacency, return false. + bool is_adjacent_to_and_before(const VPointer& other) const { + if (!is_valid() || !other.is_valid()) { +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_overlap()) { + tty->print_cr("VPointer::is_adjacent_to_and_before: invalid VPointer, adjacency unknown."); + } +#endif + return false; + } + return mem_pointer().is_adjacent_to_and_before(other.mem_pointer()); + } - public: - VectorElementSizeStats(Arena* a) : _stats(NEW_ARENA_ARRAY(a, int, 4)) { - clear(); + // Delegate to MemPointer::never_overlaps_with, but guard for invalid cases + // where we must return a conservative answer: unknown overlap, return false. + bool never_overlaps_with(const VPointer& other) const { + if (!is_valid() || !other.is_valid()) { +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_overlap()) { + tty->print_cr("VPointer::never_overlaps_with: invalid VPointer, overlap unknown."); + } +#endif + return false; + } + return mem_pointer().never_overlaps_with(other.mem_pointer()); } - void clear() { memset(_stats, 0, sizeof(int) * 4); } + NOT_PRODUCT( void print_on(outputStream* st, bool end_with_cr = true) const; ) - void record_size(int size) { - assert(1 <= size && size <= 8 && is_power_of_2(size), "Illegal size"); - _stats[exact_log2(size)]++; +private: + jint init_iv_scale() const { + for (uint i = 0; i < MemPointer::SUMMANDS_SIZE; i++) { + const MemPointerSummand& summand = _mem_pointer.summands_at(i); + Node* variable = summand.variable(); + if (variable == _vloop.iv()) { + return summand.scale().value(); + } + } + // No summand with variable == iv. + return 0; } - int count_size(int size) { - assert(1 <= size && size <= 8 && is_power_of_2(size), "Illegal size"); - return _stats[exact_log2(size)]; + // Check the conditions for a "valid" VPointer. + bool init_is_valid() const { + return init_is_base_known() && + init_are_non_iv_summands_pre_loop_invariant() && + init_are_scale_and_stride_not_too_large(); } - int smallest_size() { - for (int i = 0; i <= 3; i++) { - if (_stats[i] > 0) return (1 << i); + // VPointer needs to know if it is native (off-heap) or object (on-heap). + // We may, for example, have failed to fully decompose the MemPointer, + // possibly because such a decomposition is not considered safe. + bool init_is_base_known() const { + if (_mem_pointer.base().is_known()) { return true; } + +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::init_is_valid: base not known."); } - return NO_SIZE; +#endif + return false; } - int largest_size() { - for (int i = 3; i >= 0; i--) { - if (_stats[i] > 0) return (1 << i); + // All summands, except the iv-summand, must be pre-loop invariant. This is necessary + // so that we can use the variables in checks inside or before the pre-loop, e.g. for + // alignment. + bool init_are_non_iv_summands_pre_loop_invariant() const { + for (uint i = 0; i < MemPointer::SUMMANDS_SIZE; i++) { + const MemPointerSummand& summand = _mem_pointer.summands_at(i); + Node* variable = summand.variable(); + if (variable != nullptr && variable != _vloop.iv() && !_vloop.is_pre_loop_invariant(variable)) { +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_parsing()) { + tty->print("VPointer::init_is_valid: summand is not pre-loop invariant: "); + summand.print_on(tty); + tty->cr(); + } +#endif + return false; + } } - return NO_SIZE; + return true; } - int unique_size() { - int small = smallest_size(); - int large = largest_size(); - return (small == large) ? small : MIXED_SIZE; + // In the pointer analysis, and especially the AlignVector analysis, we assume that + // stride and scale are not too large. For example, we multiply "iv_scale * iv_stride", + // and assume that this does not overflow the int range. We also take "abs(iv_scale)" + // and "abs(iv_stride)", which would overflow for min_int = -(2^31). Still, we want + // to at least allow small and moderately large stride and scale. Therefore, we + // allow values up to 2^30, which is only a factor 2 smaller than the max/min int. + // Normal performance relevant code will have much lower values. And the restriction + // allows us to keep the rest of the autovectorization code much simpler, since we + // do not have to deal with overflows. + bool init_are_scale_and_stride_not_too_large() const { + jlong long_iv_scale = _iv_scale; + jlong long_iv_stride = _vloop.iv_stride(); + jlong max_val = 1 << 30; + if (abs(long_iv_scale) >= max_val || + abs(long_iv_stride) >= max_val || + abs(long_iv_scale * long_iv_stride) >= max_val) { +#ifndef PRODUCT + if (_vloop.mptrace().is_trace_parsing()) { + tty->print_cr("VPointer::init_is_valid: scale or stride too large."); + } +#endif + return false; + } + return true; } }; // When alignment is required, we must adjust the pre-loop iteration count pre_iter, // such that the address is aligned for any main_iter >= 0: // -// adr = base + offset + invar + scale * init -// + scale * pre_stride * pre_iter -// + scale * main_stride * main_iter +// adr = base + invar + iv_scale * init + con +// + iv_scale * pre_stride * pre_iter +// + iv_scale * main_stride * main_iter // // The AlignmentSolver generates solutions of the following forms: // 1. Empty: No pre_iter guarantees alignment. @@ -1009,9 +1000,9 @@ class VectorElementSizeStats { // // The Constrained solution is of the following form: // -// pre_iter = m * q + r (for any integer m) -// [- invar / (scale * pre_stride) ] (if there is an invariant) -// [- init / pre_stride ] (if init is variable) +// pre_iter = m * q + r (for any integer m) +// [- invar / (iv_scale * pre_stride) ] (if there is an invariant) +// [- init / pre_stride ] (if init is variable) // // The solution is periodic with periodicity q, which is guaranteed to be a power of 2. // This periodic solution is "rotated" by three alignment terms: one for constants (r), @@ -1037,7 +1028,7 @@ class AlignmentSolution : public ResourceObj { // Implemented by each subclass virtual const AlignmentSolution* filter(const AlignmentSolution* other) const = 0; - virtual void print() const = 0; + NOT_PRODUCT( virtual void print() const = 0; ) // Compute modulo and ensure that we get a positive remainder static int mod(int i, int q) { @@ -1071,9 +1062,11 @@ class EmptyAlignmentSolution : public AlignmentSolution { return new EmptyAlignmentSolution("empty solution input to filter"); } +#ifndef PRODUCT virtual void print() const override final { tty->print_cr("empty solution: %s", reason()); }; +#endif }; class TrivialAlignmentSolution : public AlignmentSolution { @@ -1094,9 +1087,11 @@ class TrivialAlignmentSolution : public AlignmentSolution { return other; } +#ifndef PRODUCT virtual void print() const override final { tty->print_cr("pre_iter >= 0 (trivial)"); }; +#endif }; class ConstrainedAlignmentSolution : public AlignmentSolution { @@ -1104,19 +1099,18 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { const MemNode* _mem_ref; const int _q; const int _r; - const Node* _invar; - const int _scale; + // Use VPointer for invar and iv_scale + const VPointer& _vpointer; public: ConstrainedAlignmentSolution(const MemNode* mem_ref, const int q, const int r, - const Node* invar, - int scale) : + const VPointer& vpointer) : _mem_ref(mem_ref), _q(q), _r(r), - _invar(invar), - _scale(scale) { + _vpointer(vpointer) + { assert(q > 1 && is_power_of_2(q), "q must be power of 2"); assert(0 <= r && r < q, "r must be in modulo space of q"); assert(_mem_ref != nullptr, "must have mem_ref"); @@ -1127,6 +1121,7 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { virtual bool is_constrained() const override final { return true; } const MemNode* mem_ref() const { return _mem_ref; } + const VPointer& vpointer() const { return _vpointer; } virtual const ConstrainedAlignmentSolution* as_constrained() const override final { return this; } @@ -1150,12 +1145,12 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { // for any integers m1 and m2: // // pre_iter = m1 * q1 + r1 - // [- invar1 / (scale1 * pre_stride) ] - // [- init / pre_stride ] + // [- invar1 / (iv_scale1 * pre_stride) ] + // [- init / pre_stride ] // // pre_iter = m2 * q2 + r2 - // [- invar2 / (scale2 * pre_stride) ] - // [- init / pre_stride ] + // [- invar2 / (iv_scale2 * pre_stride) ] + // [- init / pre_stride ] // // Note: pre_stride and init are identical for all mem_refs in the loop. // @@ -1164,13 +1159,15 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { // // The invar alignment term is identical if either: // - both mem_refs have no invariant. - // - both mem_refs have the same invariant and the same scale. + // - both mem_refs have the same invariant and the same iv_scale. // - if (s1->_invar != s2->_invar) { - return new EmptyAlignmentSolution("invar not identical"); - } - if (s1->_invar != nullptr && s1->_scale != s2->_scale) { - return new EmptyAlignmentSolution("has invar with different scale"); + // Use VPointer to do checks on invar and iv_scale: + const VPointer& p1 = s1->vpointer(); + const VPointer& p2 = s2->vpointer(); + bool both_no_invar = !p1.has_invar_summands() && + !p2.has_invar_summands(); + if(!both_no_invar && !p1.has_same_invar_summands_and_iv_scale_as(p2)) { + return new EmptyAlignmentSolution("invar alignment term not identical"); } // Now, we have reduced the problem to: @@ -1209,13 +1206,24 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { return s2; // return the subset } +#ifndef PRODUCT virtual void print() const override final { tty->print("m * q(%d) + r(%d)", _q, _r); - if (_invar != nullptr) { - tty->print(" - invar[%d] / (scale(%d) * pre_stride)", _invar->_idx, _scale); + if (_vpointer.has_invar_summands()) { + tty->print(" - invar("); + int count = 0; + _vpointer.for_each_invar_summand([&] (const MemPointerSummand& s) { + if (count > 0) { + tty->print(" + "); + } + s.print_on(tty); + count++; + }); + tty->print(") / (iv_scale(%d) * pre_stride)", _vpointer.iv_scale()); } tty->print_cr(" [- init / pre_stride], mem_ref[%d]", mem_ref()->_idx); }; +#endif }; // When strict alignment is required (e.g. -XX:+AlignVector), then we must ensure @@ -1230,8 +1238,8 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { // // pre-loop: // iv = init + i * pre_stride -// adr = base + offset + invar + scale * iv -// adr = base + offset + invar + scale * (init + i * pre_stride) +// adr = base + invar + iv_scale * iv + con +// adr = base + invar + iv_scale * (init + i * pre_stride) + con // iv += pre_stride // i++ // @@ -1245,7 +1253,7 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { // i = pre_iter + main_iter * unroll_factor // iv = init + i * pre_stride = init + pre_iter * pre_stride + main_iter * unroll_factor * pre_stride // = init + pre_iter * pre_stride + main_iter * main_stride -// adr = base + offset + invar + scale * iv // must be aligned +// adr = base + invar + iv_scale * iv + con // must be aligned // iv += main_stride // i += unroll_factor // main_iter++ @@ -1257,15 +1265,15 @@ class ConstrainedAlignmentSolution : public AlignmentSolution { // a compatible solutions. class AlignmentSolver { private: + const VPointer& _vpointer; + const MemNode* _mem_ref; // first element - const uint _vector_length; // number of elements in vector - const int _element_size; const int _vector_width; // in bytes // All vector loads and stores need to be memory aligned. The alignment width (aw) in // principle is the vector_width. But when vector_width > ObjectAlignmentInBytes this is // too strict, since any memory object is only guaranteed to be ObjectAlignmentInBytes - // aligned. For example, the relative offset between two arrays is only guaranteed to + // aligned. For example, the relative distance between two arrays is only guaranteed to // be divisible by ObjectAlignmentInBytes. const int _aw; @@ -1275,7 +1283,7 @@ class AlignmentSolver { // // The Simple form of the address is disassembled by VPointer into: // - // adr = base + offset + invar + scale * iv + // adr = base + invar + iv_scale * iv + con // // Where the iv can be written as: // @@ -1284,11 +1292,6 @@ class AlignmentSolver { // pre_iter: number of pre-loop iterations (adjustable via pre-loop limit) // main_iter: number of main-loop iterations (main_iter >= 0) // - const Node* _base; // base of address (e.g. Java array object, aw-aligned) - const int _offset; - const Node* _invar; - const int _invar_factor; // known constant factor of invar - const int _scale; const Node* _init_node; // value of iv before pre-loop const int _pre_stride; // address increment per pre-loop iteration const int _main_stride; // address increment per main-loop iteration @@ -1301,28 +1304,18 @@ class AlignmentSolver { } public: - AlignmentSolver(const MemNode* mem_ref, + AlignmentSolver(const VPointer& vpointer, + const MemNode* mem_ref, const uint vector_length, - const Node* base, - const int offset, - const Node* invar, - const int invar_factor, - const int scale, const Node* init_node, const int pre_stride, const int main_stride DEBUG_ONLY( COMMA const bool is_trace) ) : + _vpointer( vpointer), _mem_ref( mem_ref_not_null(mem_ref)), - _vector_length( vector_length), - _element_size( _mem_ref->memory_size()), - _vector_width( _vector_length * _element_size), + _vector_width( vector_length * vpointer.size()), _aw( MIN2(_vector_width, ObjectAlignmentInBytes)), - _base( base), - _offset( offset), - _invar( invar), - _invar_factor( invar_factor), - _scale( scale), _init_node( init_node), _pre_stride( pre_stride), _main_stride( main_stride) @@ -1336,6 +1329,9 @@ class AlignmentSolver { AlignmentSolution* solve() const; private: + MemPointer::Base base() const { return _vpointer.mem_pointer().base();} + jint iv_scale() const { return _vpointer.iv_scale(); } + class EQ4 { private: const int _C_const; diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 33429dfacad0c..dc7fd18a8d07c 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "opto/connode.hpp" #include "opto/mulnode.hpp" @@ -666,7 +665,7 @@ VectorNode* VectorNode::make_mask_node(int vopc, Node* n1, Node* n2, uint vlen, } } -// Make a vector node for binary operation +// Make a vector node for unary or binary operation VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, bool is_mask, bool is_var_shift, bool is_unsigned) { // This method should not be called for unimplemented vectors. guarantee(vopc > 0, "vopc must be > 0"); @@ -747,6 +746,9 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b case Op_URShiftVI: return new URShiftVINode(n1, n2, vt, is_var_shift); case Op_URShiftVL: return new URShiftVLNode(n1, n2, vt, is_var_shift); + case Op_LShiftCntV: return new LShiftCntVNode(n1, vt); + case Op_RShiftCntV: return new RShiftCntVNode(n1, vt); + case Op_AndV: return new AndVNode(n1, n2, vt); case Op_OrV: return new OrVNode (n1, n2, vt); case Op_XorV: return new XorVNode(n1, n2, vt); @@ -766,6 +768,18 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b case Op_SaturatingAddV: return new SaturatingAddVNode(n1, n2, vt, is_unsigned); case Op_SaturatingSubV: return new SaturatingSubVNode(n1, n2, vt, is_unsigned); + case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt); + case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt); + case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt); + case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt); + case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt); + case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt); + case Op_VectorUCastB2X: return new VectorUCastB2XNode(n1, vt); + case Op_VectorUCastS2X: return new VectorUCastS2XNode(n1, vt); + case Op_VectorUCastI2X: return new VectorUCastI2XNode(n1, vt); + case Op_VectorCastHF2F: return new VectorCastHF2FNode(n1, vt); + case Op_VectorCastF2HF: return new VectorCastF2HFNode(n1, vt); + default: fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); return nullptr; @@ -791,6 +805,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeV case Op_SelectFromTwoVector: return new SelectFromTwoVectorNode(n1, n2, n3, vt); case Op_SignumVD: return new SignumVDNode(n1, n2, n3, vt); case Op_SignumVF: return new SignumVFNode(n1, n2, n3, vt); + case Op_VectorBlend: return new VectorBlendNode(n1, n2, n3); default: fatal("Missed vector creation for '%s'", NodeClassNames[vopc]); return nullptr; @@ -818,22 +833,26 @@ VectorNode* VectorNode::scalar2vector(Node* s, uint vlen, BasicType bt, bool is_ } VectorNode* VectorNode::shift_count(int opc, Node* cnt, uint vlen, BasicType bt) { - // Match shift count type with shift vector type. + int vopc = VectorNode::shift_count_opcode(opc); const TypeVect* vt = TypeVect::make(bt, vlen); + return VectorNode::make(vopc, cnt, nullptr, vt); +} + +int VectorNode::shift_count_opcode(int opc) { switch (opc) { case Op_LShiftI: case Op_LShiftL: - return new LShiftCntVNode(cnt, vt); + return Op_LShiftCntV; case Op_RShiftI: case Op_RShiftL: case Op_URShiftB: case Op_URShiftS: case Op_URShiftI: case Op_URShiftL: - return new RShiftCntVNode(cnt, vt); + return Op_RShiftCntV; default: - fatal("Missed vector creation for '%s'", NodeClassNames[opc]); - return nullptr; + fatal("Node class '%s' is not supported for shift count", NodeClassNames[opc]); + return -1; } } @@ -1023,10 +1042,65 @@ Node* VectorNode::try_to_gen_masked_vector(PhaseGVN* gvn, Node* node, const Type } } +bool VectorNode::should_swap_inputs_to_help_global_value_numbering() { + // Predicated vector operations are sensitive to ordering of inputs. + // When the mask corresponding to a vector lane is false then + // the result of the operation is corresponding lane of its first operand. + // i.e. RES = VEC1.lanewise(OPER, VEC2, MASK) is semantically equivalent to + // RES = BLEND(VEC1, VEC1.lanewise(OPER, VEC2), MASK) + if (is_predicated_vector()) { + return false; + } + + switch(Opcode()) { + case Op_AddVB: + case Op_AddVS: + case Op_AddVI: + case Op_AddVL: + case Op_AddVF: + case Op_AddVD: + + case Op_MulVB: + case Op_MulVS: + case Op_MulVI: + case Op_MulVL: + case Op_MulVF: + case Op_MulVD: + + case Op_MaxV: + case Op_MinV: + case Op_XorV: + case Op_OrV: + case Op_AndV: + case Op_UMinV: + case Op_UMaxV: + + case Op_AndVMask: + case Op_OrVMask: + case Op_XorVMask: + + case Op_SaturatingAddV: + assert(req() == 3, "Must be a binary operation"); + // For non-predicated commutative operations, sort the inputs in + // increasing order of node indices. + if (in(1)->_idx > in(2)->_idx) { + return true; + } + // fallthrough + default: + return false; + } +} + Node* VectorNode::Ideal(PhaseGVN* phase, bool can_reshape) { if (Matcher::vector_needs_partial_operations(this, vect_type())) { return try_to_gen_masked_vector(phase, this, vect_type()); } + + // Sort inputs of commutative non-predicated vector operations to help value numbering. + if (should_swap_inputs_to_help_global_value_numbering()) { + swap_edges(1, 2); + } return nullptr; } @@ -1412,24 +1486,9 @@ VectorStoreMaskNode* VectorStoreMaskNode::make(PhaseGVN& gvn, Node* in, BasicTyp return new VectorStoreMaskNode(in, gvn.intcon(elem_size), vt); } -VectorCastNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) { +VectorNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) { const TypeVect* vt = TypeVect::make(bt, vlen); - switch (vopc) { - case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt); - case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt); - case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt); - case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt); - case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt); - case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt); - case Op_VectorUCastB2X: return new VectorUCastB2XNode(n1, vt); - case Op_VectorUCastS2X: return new VectorUCastS2XNode(n1, vt); - case Op_VectorUCastI2X: return new VectorUCastI2XNode(n1, vt); - case Op_VectorCastHF2F: return new VectorCastHF2FNode(n1, vt); - case Op_VectorCastF2HF: return new VectorCastF2HFNode(n1, vt); - default: - assert(false, "unknown node: %s", NodeClassNames[vopc]); - return nullptr; - } + return VectorNode::make(vopc, n1, nullptr, vt); } int VectorCastNode::opcode(int sopc, BasicType bt, bool is_signed) { @@ -2072,7 +2131,7 @@ Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* zero = phase->transform(phase->zerocon(bt)); return VectorNode::scalar2vector(zero, length(), bt, bottom_type()->isa_vectmask() != nullptr); } - return nullptr; + return VectorNode::Ideal(phase, can_reshape); } Node* VectorBlendNode::Identity(PhaseGVN* phase) { diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index f5574ba79e3c5..50220c9362b7b 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,8 @@ class VectorNode : public TypeNode { static bool is_convert_opcode(int opc); static bool is_minmax_opcode(int opc); + bool should_swap_inputs_to_help_global_value_numbering(); + static bool is_vshift_cnt_opcode(int opc); static bool is_rotate_opcode(int opc); @@ -95,6 +97,8 @@ class VectorNode : public TypeNode { static int opcode(int sopc, BasicType bt); // scalar_opc -> vector_opc static int scalar_opcode(int vopc, BasicType bt); // vector_opc -> scalar_opc + static int shift_count_opcode(int opc); + // Limits on vector size (number of elements) for auto-vectorization. static bool vector_size_supported_auto_vectorization(const BasicType bt, int size); static bool implemented(int opc, uint vlen, BasicType bt); @@ -1764,7 +1768,7 @@ class VectorCastNode : public VectorNode { VectorCastNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {} virtual int Opcode() const; - static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen); + static VectorNode* make(int vopc, Node* n1, BasicType bt, uint vlen); static int opcode(int opc, BasicType bt, bool is_signed = true); static bool implemented(int opc, uint vlen, BasicType src_type, BasicType dst_type); diff --git a/src/hotspot/share/opto/vtransform.cpp b/src/hotspot/share/opto/vtransform.cpp index d09a4c899f685..4730f3ac1343b 100644 --- a/src/hotspot/share/opto/vtransform.cpp +++ b/src/hotspot/share/opto/vtransform.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "opto/vtransform.hpp" #include "opto/vectornode.hpp" #include "opto/convertnode.hpp" @@ -144,57 +143,47 @@ void VTransformApplyResult::trace(VTransformNode* vtnode) const { } #endif -// We use two comparisons, because a subtraction could underflow. -#define RETURN_CMP_VALUE_IF_NOT_EQUAL(a, b) \ - if (a < b) { return -1; } \ - if (a > b) { return 1; } - // Helper-class for VTransformGraph::has_store_to_load_forwarding_failure. -// It represents a memory region: [ptr, ptr + memory_size) -class VMemoryRegion : public StackObj { +// It wraps a VPointer. The VPointer has an iv_offset applied, which +// simulates a virtual unrolling. They represent the memory region: +// [adr, adr + size) +// adr = base + invar + iv_scale * (iv + iv_offset) + con +class VMemoryRegion : public ResourceObj { private: - Node* _base; // ptr = base + offset + invar + scale * iv - int _scale; - Node* _invar; - int _offset; - uint _memory_size; + // Note: VPointer has no default constructor, so we cannot use VMemoryRegion + // in-place in a GrowableArray. Hence, we make VMemoryRegion a resource + // allocated object, so the GrowableArray of VMemoryRegion* has a default + // nullptr element. + const VPointer _vpointer; bool _is_load; // load or store? uint _schedule_order; public: - VMemoryRegion() {} // empty constructor for GrowableArray - VMemoryRegion(const VPointer& vpointer, int iv_offset, int vector_length, uint schedule_order) : - _base(vpointer.base()), - _scale(vpointer.scale_in_bytes()), - _invar(vpointer.invar()), - _offset(vpointer.offset_in_bytes() + _scale * iv_offset), - _memory_size(vpointer.memory_size() * vector_length), - _is_load(vpointer.mem()->is_Load()), + VMemoryRegion(const VPointer& vpointer, bool is_load, uint schedule_order) : + _vpointer(vpointer), + _is_load(is_load), _schedule_order(schedule_order) {} - Node* base() const { return _base; } - int scale() const { return _scale; } - Node* invar() const { return _invar; } - int offset() const { return _offset; } - uint memory_size() const { return _memory_size; } + const VPointer& vpointer() const { return _vpointer; } bool is_load() const { return _is_load; } uint schedule_order() const { return _schedule_order; } static int cmp_for_sort_by_group(VMemoryRegion* r1, VMemoryRegion* r2) { - RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->base()->_idx, r2->base()->_idx); - RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->scale(), r2->scale()); - int r1_invar_idx = r1->invar() == nullptr ? 0 : r1->invar()->_idx; - int r2_invar_idx = r2->invar() == nullptr ? 0 : r2->invar()->_idx; - RETURN_CMP_VALUE_IF_NOT_EQUAL(r1_invar_idx, r2_invar_idx); - return 0; // equal + // Sort by mem_pointer (base, invar, iv_scale), except for the con. + return MemPointer::cmp_summands(r1->vpointer().mem_pointer(), + r2->vpointer().mem_pointer()); } - static int cmp_for_sort(VMemoryRegion* r1, VMemoryRegion* r2) { - int cmp_group = cmp_for_sort_by_group(r1, r2); + static int cmp_for_sort(VMemoryRegion** r1, VMemoryRegion** r2) { + int cmp_group = cmp_for_sort_by_group(*r1, *r2); if (cmp_group != 0) { return cmp_group; } - RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->offset(), r2->offset()); - return 0; // equal + // We use two comparisons, because a subtraction could underflow. + jint con1 = (*r1)->vpointer().con(); + jint con2 = (*r2)->vpointer().con(); + if (con1 < con2) { return -1; } + if (con1 > con2) { return 1; } + return 0; } enum Aliasing { DIFFERENT_GROUP, BEFORE, EXACT_OVERLAP, PARTIAL_OVERLAP, AFTER }; @@ -204,26 +193,23 @@ class VMemoryRegion : public StackObj { VMemoryRegion* p2 = &other; if (cmp_for_sort_by_group(p1, p2) != 0) { return DIFFERENT_GROUP; } - jlong offset1 = p1->offset(); - jlong offset2 = p2->offset(); - jlong memory_size1 = p1->memory_size(); - jlong memory_size2 = p2->memory_size(); + jlong con1 = p1->vpointer().con(); + jlong con2 = p2->vpointer().con(); + jlong size1 = p1->vpointer().size(); + jlong size2 = p2->vpointer().size(); - if (offset1 >= offset2 + memory_size2) { return AFTER; } - if (offset2 >= offset1 + memory_size1) { return BEFORE; } - if (offset1 == offset2 && memory_size1 == memory_size2) { return EXACT_OVERLAP; } + if (con1 >= con2 + size2) { return AFTER; } + if (con2 >= con1 + size1) { return BEFORE; } + if (con1 == con2 && size1 == size2) { return EXACT_OVERLAP; } return PARTIAL_OVERLAP; } #ifndef PRODUCT void print() const { - tty->print("VMemoryRegion[%s %dbytes, schedule_order(%4d), base", - _is_load ? "load " : "store", _memory_size, _schedule_order); - VPointer::print_con_or_idx(_base); - tty->print(" + offset(%4d)", _offset); - tty->print(" + invar"); - VPointer::print_con_or_idx(_invar); - tty->print_cr(" + scale(%4d) * iv]", _scale); + tty->print("VMemoryRegion[%s schedule_order(%4d), ", + _is_load ? "load, " : "store,", _schedule_order); + vpointer().print_on(tty, false); + tty->print_cr("]"); } #endif }; @@ -329,7 +315,8 @@ bool VTransformGraph::has_store_to_load_forwarding_failure(const VLoopAnalyzer& // Collect all pointers for scalar and vector loads/stores. ResourceMark rm; - GrowableArray memory_regions; + // Use pointers because no default constructor for elements available. + GrowableArray memory_regions; // To detect store-to-load-forwarding failures at the iteration threshold or below, we // simulate a super-unrolling to reach SuperWordStoreToLoadForwardingFailureDetection @@ -351,10 +338,15 @@ bool VTransformGraph::has_store_to_load_forwarding_failure(const VLoopAnalyzer& VTransformNode* vtn = _schedule.at(i); if (vtn->is_load_or_store_in_loop()) { const VPointer& p = vtn->vpointer(vloop_analyzer); - if (p.valid()) { + if (p.is_valid()) { VTransformVectorNode* vector = vtn->isa_Vector(); - uint vector_length = vector != nullptr ? vector->nodes().length() : 1; - memory_regions.push(VMemoryRegion(p, iv_offset, vector_length, schedule_order++)); + bool is_load = vtn->is_load_in_loop(); + const VPointer iv_offset_p(p.make_with_iv_offset(iv_offset)); + if (iv_offset_p.is_valid()) { + // The iv_offset may lead to overflows. This is a heuristic, so we do not + // care too much about those edge cases. + memory_regions.push(new VMemoryRegion(iv_offset_p, is_load, schedule_order++)); + } } } } @@ -369,7 +361,7 @@ bool VTransformGraph::has_store_to_load_forwarding_failure(const VLoopAnalyzer& tty->print_cr(" simulated_unrolling_count = %d", simulated_unrolling_count); tty->print_cr(" simulated_super_unrolling_count = %d", simulated_super_unrolling_count); for (int i = 0; i < memory_regions.length(); i++) { - VMemoryRegion& region = memory_regions.at(i); + VMemoryRegion& region = *memory_regions.at(i); region.print(); } } @@ -377,10 +369,10 @@ bool VTransformGraph::has_store_to_load_forwarding_failure(const VLoopAnalyzer& // For all pairs of pointers in the same group, check if they have a partial overlap. for (int i = 0; i < memory_regions.length(); i++) { - VMemoryRegion& region1 = memory_regions.at(i); + VMemoryRegion& region1 = *memory_regions.at(i); for (int j = i + 1; j < memory_regions.length(); j++) { - VMemoryRegion& region2 = memory_regions.at(j); + VMemoryRegion& region2 = *memory_regions.at(j); const VMemoryRegion::Aliasing aliasing = region1.aliasing(region2); if (aliasing == VMemoryRegion::Aliasing::DIFFERENT_GROUP || @@ -575,12 +567,13 @@ VTransformApplyResult VTransformLoadVectorNode::apply(const VLoopAnalyzer& vloop // Set the memory dependency of the LoadVector as early as possible. // Walk up the memory chain, and ignore any StoreVector that provably // does not have any memory dependency. + const VPointer& load_p = vpointer(vloop_analyzer); while (mem->is_StoreVector()) { - VPointer p_store(mem->as_Mem(), vloop_analyzer.vloop()); - if (p_store.overlap_possible_with_any_in(nodes())) { - break; - } else { + VPointer store_p(mem->as_Mem(), vloop_analyzer.vloop()); + if (store_p.never_overlaps_with(load_p)) { mem = mem->in(MemNode::Memory); + } else { + break; } } diff --git a/src/hotspot/share/opto/vtransform.hpp b/src/hotspot/share/opto/vtransform.hpp index 8ceca318f4ae1..4fc68c7b4dfc2 100644 --- a/src/hotspot/share/opto/vtransform.hpp +++ b/src/hotspot/share/opto/vtransform.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,6 +66,7 @@ class VTransformVectorNode; class VTransformElementWiseVectorNode; class VTransformBoolVectorNode; class VTransformReductionVectorNode; +class VTransformMemVectorNode; class VTransformLoadVectorNode; class VTransformStoreVectorNode; @@ -314,9 +315,11 @@ class VTransformNode : public ArenaObj { virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() { return nullptr; } virtual VTransformBoolVectorNode* isa_BoolVector() { return nullptr; } virtual VTransformReductionVectorNode* isa_ReductionVector() { return nullptr; } + virtual VTransformMemVectorNode* isa_MemVector() { return nullptr; } virtual VTransformLoadVectorNode* isa_LoadVector() { return nullptr; } virtual VTransformStoreVectorNode* isa_StoreVector() { return nullptr; } + virtual bool is_load_in_loop() const { return false; } virtual bool is_load_or_store_in_loop() const { return false; } virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const { ShouldNotReachHere(); } @@ -342,6 +345,7 @@ class VTransformScalarNode : public VTransformNode { VTransformNode(vtransform, n->req()), _node(n) {} Node* node() const { return _node; } virtual VTransformScalarNode* isa_Scalar() override { return this; } + virtual bool is_load_in_loop() const override { return _node->is_Load(); } virtual bool is_load_or_store_in_loop() const override { return _node->is_Load() || _node->is_Store(); } virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(node()->as_Mem()); } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, @@ -358,6 +362,7 @@ class VTransformInputScalarNode : public VTransformScalarNode { VTransformInputScalarNode(VTransform& vtransform, Node* n) : VTransformScalarNode(vtransform, n) {} virtual VTransformInputScalarNode* isa_InputScalar() override { return this; } + virtual bool is_load_in_loop() const override { return false; } virtual bool is_load_or_store_in_loop() const override { return false; } NOT_PRODUCT(virtual const char* name() const override { return "InputScalar"; };) }; @@ -478,28 +483,40 @@ class VTransformReductionVectorNode : public VTransformVectorNode { NOT_PRODUCT(virtual const char* name() const override { return "ReductionVector"; };) }; -class VTransformLoadVectorNode : public VTransformVectorNode { +class VTransformMemVectorNode : public VTransformVectorNode { +private: + const VPointer _vpointer; // with size of the vector + +public: + VTransformMemVectorNode(VTransform& vtransform, const uint req, uint number_of_nodes, const VPointer& vpointer) : + VTransformVectorNode(vtransform, req, number_of_nodes), + _vpointer(vpointer) {} + + virtual VTransformMemVectorNode* isa_MemVector() override { return this; } + virtual bool is_load_or_store_in_loop() const override { return true; } + virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return _vpointer; } +}; + +class VTransformLoadVectorNode : public VTransformMemVectorNode { public: // req = 3 -> [ctrl, mem, adr] - VTransformLoadVectorNode(VTransform& vtransform, uint number_of_nodes) : - VTransformVectorNode(vtransform, 3, number_of_nodes) {} + VTransformLoadVectorNode(VTransform& vtransform, uint number_of_nodes, const VPointer& vpointer) : + VTransformMemVectorNode(vtransform, 3, number_of_nodes, vpointer) {} LoadNode::ControlDependency control_dependency() const; virtual VTransformLoadVectorNode* isa_LoadVector() override { return this; } - virtual bool is_load_or_store_in_loop() const override { return true; } - virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(nodes().at(0)->as_Mem()); } + virtual bool is_load_in_loop() const override { return true; } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray& vnode_idx_to_transformed_node) const override; NOT_PRODUCT(virtual const char* name() const override { return "LoadVector"; };) }; -class VTransformStoreVectorNode : public VTransformVectorNode { +class VTransformStoreVectorNode : public VTransformMemVectorNode { public: // req = 4 -> [ctrl, mem, adr, val] - VTransformStoreVectorNode(VTransform& vtransform, uint number_of_nodes) : - VTransformVectorNode(vtransform, 4, number_of_nodes) {} + VTransformStoreVectorNode(VTransform& vtransform, uint number_of_nodes, const VPointer& vpointer) : + VTransformMemVectorNode(vtransform, 4, number_of_nodes, vpointer) {} virtual VTransformStoreVectorNode* isa_StoreVector() override { return this; } - virtual bool is_load_or_store_in_loop() const override { return true; } - virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(nodes().at(0)->as_Mem()); } + virtual bool is_load_in_loop() const override { return false; } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray& vnode_idx_to_transformed_node) const override; NOT_PRODUCT(virtual const char* name() const override { return "StoreVector"; };) diff --git a/src/hotspot/share/precompiled/precompiled.hpp b/src/hotspot/share/precompiled/precompiled.hpp index 07922d129697e..a5f42a0fe8688 100644 --- a/src/hotspot/share/precompiled/precompiled.hpp +++ b/src/hotspot/share/precompiled/precompiled.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ // Precompiled headers are turned off if the user passes // --disable-precompiled-headers to configure. -#ifndef DONT_USE_PRECOMPILED_HEADER - // These header files are included in at least 130 C++ files, as of // measurements made in November 2018. This list excludes files named // *.inline.hpp, since including them decreased build performance. @@ -77,5 +75,3 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #endif // TARGET_COMPILER_visCPP - -#endif // !DONT_USE_PRECOMPILED_HEADER diff --git a/src/hotspot/share/prims/downcallLinker.cpp b/src/hotspot/share/prims/downcallLinker.cpp index 76a239a1017e4..6486143981774 100644 --- a/src/hotspot/share/prims/downcallLinker.cpp +++ b/src/hotspot/share/prims/downcallLinker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,7 @@ * questions. */ -#include "precompiled.hpp" #include "downcallLinker.hpp" -#include "gc/shared/gcLocker.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" #include diff --git a/src/hotspot/share/prims/foreignGlobals.cpp b/src/hotspot/share/prims/foreignGlobals.cpp index 9e74936a43168..d3d0c2cefae0c 100644 --- a/src/hotspot/share/prims/foreignGlobals.cpp +++ b/src/hotspot/share/prims/foreignGlobals.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -#include "precompiled.hpp" #include "foreignGlobals.hpp" #include "classfile/javaClasses.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/prims/forte.cpp b/src/hotspot/share/prims/forte.cpp index a7f48faba137c..10e8b45dc75a2 100644 --- a/src/hotspot/share/prims/forte.cpp +++ b/src/hotspot/share/prims/forte.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "code/debugInfoRec.hpp" #include "code/pcDesc.hpp" #include "gc/shared/collectedHeap.inline.hpp" diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 40d3b5062580a..517808a115f0e 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024 Red Hat, Inc. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,7 +24,6 @@ * */ -#include "precompiled.hpp" #include "ci/ciReplay.hpp" #include "classfile/altHashing.hpp" #include "classfile/classFileStream.hpp" @@ -41,7 +40,6 @@ #include "classfile/vmSymbols.hpp" #include "compiler/compiler_globals.hpp" #include "gc/shared/collectedHeap.hpp" -#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" #include "interpreter/linkResolver.hpp" #include "jni.h" @@ -2413,7 +2411,7 @@ static char* get_bad_address() { -#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \ +#define DEFINE_GETSCALARARRAYELEMENTS(ElementType,Result \ , EntryProbe, ReturnProbe) \ \ JNI_ENTRY_NO_PRESERVE(ElementType*, \ @@ -2447,35 +2445,35 @@ JNI_ENTRY_NO_PRESERVE(ElementType*, \ return result; \ JNI_END -DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool +DEFINE_GETSCALARARRAYELEMENTS(jboolean, Boolean , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result)) -DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte +DEFINE_GETSCALARARRAYELEMENTS(jbyte, Byte , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result)) -DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short +DEFINE_GETSCALARARRAYELEMENTS(jshort, Short , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result)) -DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char +DEFINE_GETSCALARARRAYELEMENTS(jchar, Char , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result)) -DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int +DEFINE_GETSCALARARRAYELEMENTS(jint, Int , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result)) -DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long +DEFINE_GETSCALARARRAYELEMENTS(jlong, Long , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result))) // Float and double probes don't return value because dtrace doesn't currently support it -DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float +DEFINE_GETSCALARARRAYELEMENTS(jfloat, Float , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result)) -DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double +DEFINE_GETSCALARARRAYELEMENTS(jdouble, Double , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy), HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result)) -#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \ - , EntryProbe, ReturnProbe);\ +#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementType,Result \ + , EntryProbe, ReturnProbe) \ \ JNI_ENTRY_NO_PRESERVE(void, \ jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \ @@ -2494,28 +2492,28 @@ JNI_ENTRY_NO_PRESERVE(void, \ ReturnProbe; \ JNI_END -DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool +DEFINE_RELEASESCALARARRAYELEMENTS(jboolean, Boolean , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode), HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte +DEFINE_RELEASESCALARARRAYELEMENTS(jbyte, Byte , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode), HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short +DEFINE_RELEASESCALARARRAYELEMENTS(jshort, Short , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode), HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char +DEFINE_RELEASESCALARARRAYELEMENTS(jchar, Char , HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode), HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int +DEFINE_RELEASESCALARARRAYELEMENTS(jint, Int , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode), HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long +DEFINE_RELEASESCALARARRAYELEMENTS(jlong, Long , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode), HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float +DEFINE_RELEASESCALARARRAYELEMENTS(jfloat, Float , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode), HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN()) -DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double +DEFINE_RELEASESCALARARRAYELEMENTS(jdouble, Double , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode), HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN()) @@ -2533,8 +2531,8 @@ static void check_bounds(jsize start, jsize copy_len, jsize array_len, TRAPS) { } } -#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \ - , EntryProbe, ReturnProbe); \ +#define DEFINE_GETSCALARARRAYREGION(ElementType,Result \ + , EntryProbe, ReturnProbe) \ DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \ , ReturnProbe); \ \ @@ -2550,34 +2548,34 @@ jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, } \ JNI_END -DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool +DEFINE_GETSCALARARRAYREGION(jboolean,Boolean , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte +DEFINE_GETSCALARARRAYREGION(jbyte, Byte , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf), HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short +DEFINE_GETSCALARARRAYREGION(jshort, Short , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char +DEFINE_GETSCALARARRAYREGION(jchar, Char , HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf), HOTSPOT_JNI_GETCHARARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int +DEFINE_GETSCALARARRAYREGION(jint, Int , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf), HOTSPOT_JNI_GETINTARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long +DEFINE_GETSCALARARRAYREGION(jlong, Long , HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), HOTSPOT_JNI_GETLONGARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float +DEFINE_GETSCALARARRAYREGION(jfloat, Float , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf), HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN()); -DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double +DEFINE_GETSCALARARRAYREGION(jdouble, Double , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf), HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN()); -#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \ - , EntryProbe, ReturnProbe); \ +#define DEFINE_SETSCALARARRAYREGION(ElementType,Result \ + , EntryProbe, ReturnProbe) \ DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \ ,ReturnProbe); \ \ @@ -2593,28 +2591,28 @@ jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, } \ JNI_END -DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool +DEFINE_SETSCALARARRAYREGION(jboolean, Boolean , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf), HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte +DEFINE_SETSCALARARRAYREGION(jbyte, Byte , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf), HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short +DEFINE_SETSCALARARRAYREGION(jshort, Short , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char +DEFINE_SETSCALARARRAYREGION(jchar, Char , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf), HOTSPOT_JNI_SETCHARARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int +DEFINE_SETSCALARARRAYREGION(jint, Int , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf), HOTSPOT_JNI_SETINTARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long +DEFINE_SETSCALARARRAYREGION(jlong, Long , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf), HOTSPOT_JNI_SETLONGARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float +DEFINE_SETSCALARARRAYREGION(jfloat, Float , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf), HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN()) -DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double +DEFINE_SETSCALARARRAYREGION(jdouble, Double , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf), HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN()) @@ -3790,11 +3788,12 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae // be set in order for the Safepoint code to deal with it correctly. thread->set_thread_state(_thread_in_vm); thread->record_stack_base_and_size(); - thread->register_thread_stack_with_NMT(); thread->initialize_thread_current(); + thread->register_thread_stack_with_NMT(); MACOS_AARCH64_ONLY(thread->init_wx()); if (!os::create_attached_thread(thread)) { + thread->unregister_thread_stack_with_NMT(); thread->smr_delete(); return JNI_ERR; } @@ -3839,6 +3838,8 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae if (attach_failed) { // Added missing cleanup thread->cleanup_failed_attach_current_thread(daemon); + thread->unregister_thread_stack_with_NMT(); + thread->smr_delete(); return JNI_ERR; } @@ -3935,6 +3936,7 @@ jint JNICALL jni_DetachCurrentThread(JavaVM *vm) { // (platform-dependent) methods where we do alternate stack // maintenance work?) thread->exit(false, JavaThread::jni_detach); + thread->unregister_thread_stack_with_NMT(); thread->smr_delete(); // Go to the execute mode, the initial state of the thread on creation. diff --git a/src/hotspot/share/prims/jniCheck.cpp b/src/hotspot/share/prims/jniCheck.cpp index 8c1f9f53b343d..aa158490eabdd 100644 --- a/src/hotspot/share/prims/jniCheck.cpp +++ b/src/hotspot/share/prims/jniCheck.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/prims/jniFastGetField.cpp b/src/hotspot/share/prims/jniFastGetField.cpp index 7418458e3488d..59ff8a3216e96 100644 --- a/src/hotspot/share/prims/jniFastGetField.cpp +++ b/src/hotspot/share/prims/jniFastGetField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "prims/jniFastGetField.hpp" address JNI_FastGetField::speculative_load_pclist [LIST_CAPACITY]; diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index ebe0c0ca5d981..ccb15485b07e5 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ * */ -#include "precompiled.hpp" #include "cds/cdsConfig.hpp" #include "cds/classListParser.hpp" #include "cds/classListWriter.hpp" @@ -627,16 +626,6 @@ JVM_END JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)) Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); - JavaThreadInObjectWaitState jtiows(thread, ms != 0); - if (JvmtiExport::should_post_monitor_wait()) { - JvmtiExport::post_monitor_wait(thread, obj(), ms); - - // The current thread already owns the monitor and it has not yet - // been added to the wait queue so the current thread cannot be - // made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT - // event handler cannot accidentally consume an unpark() meant for - // the ParkEvent associated with this ObjectMonitor. - } ObjectSynchronizer::wait(obj, ms, CHECK); JVM_END @@ -1198,20 +1187,6 @@ JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls)) JVM_END -JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - if (java_lang_Class::is_primitive(mirror)) { - return JNI_FALSE; - } - Klass* k = java_lang_Class::as_Klass(mirror); - jboolean result = k->is_interface(); - assert(!result || k->is_instance_klass(), - "all interfaces are instance types"); - // The compiler intrinsic for isInterface tests the - // Klass::_access_flags bits in the same way. - return result; -JVM_END - JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls)) oop mirror = JNIHandles::resolve_non_null(cls); if (java_lang_Class::is_primitive(mirror)) { @@ -1222,22 +1197,6 @@ JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls)) JVM_END -JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - if (mirror == nullptr) { - THROW_(vmSymbols::java_lang_NullPointerException(), nullptr); - } - - if (java_lang_Class::is_primitive(mirror)) { - // Primitive types does not have a protection domain. - return nullptr; - } - - oop pd = java_lang_Class::protection_domain(mirror); - return (jobject) JNIHandles::make_local(THREAD, pd); -JVM_END - - class ScopedValueBindingsResolver { public: InstanceKlass* Carrier_klass; @@ -1286,34 +1245,6 @@ JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls)) return nullptr; JVM_END -JVM_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls)) - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); - return (k != nullptr) && k->is_array_klass() ? true : false; -JVM_END - - -JVM_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - return (jboolean) java_lang_Class::is_primitive(mirror); -JVM_END - - -JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - if (java_lang_Class::is_primitive(mirror)) { - // Primitive type - return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; - } - - Klass* k = java_lang_Class::as_Klass(mirror); - debug_only(int computed_modifiers = k->compute_modifier_flags()); - assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); - return k->modifier_flags(); -JVM_END - - -// Inner class reflection /////////////////////////////////////////////////////////////////////////////// - JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)) JvmtiVMObjectAllocEventCollector oam; // ofClass is a reference to a java_lang_Class object. The mirror object @@ -1817,7 +1748,7 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) } Klass* k = java_lang_Class::as_Klass(mirror); - return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; + return k->access_flags().as_class_flags(); } JVM_END @@ -2348,7 +2279,23 @@ JVM_END // The function returns a Klass* of the _scratch_class if the verifier // was invoked in the middle of the class redefinition. // Otherwise it returns its argument value which is the _the_class Klass*. -// Please, refer to the description in the jvmtiThreadSate.hpp. +// Please, refer to the description in the jvmtiThreadState.hpp. + +JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) + oop mirror = JNIHandles::resolve_non_null(cls); + if (java_lang_Class::is_primitive(mirror)) { + return JNI_FALSE; + } + Klass* k = java_lang_Class::as_Klass(mirror); + // This isn't necessary since answer is the same since redefinition + // has already checked this matches for the scratch class. + // k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); + jboolean result = k->is_interface(); + assert(!result || k->is_instance_klass(), + "all interfaces are instance types"); + return result; +JVM_END + JVM_ENTRY(const char*, JVM_GetClassNameUTF(JNIEnv *env, jclass cls)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); @@ -2460,14 +2407,14 @@ JVM_ENTRY(jint, JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_ind Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); Method* method = InstanceKlass::cast(k)->methods()->at(method_index); - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); JVM_END JVM_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); - return InstanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS; + return InstanceKlass::cast(k)->field_access_flags(field_index); JVM_END @@ -2657,7 +2604,7 @@ JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, j InstanceKlass* ik = InstanceKlass::cast(k_called); for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { if (fs.name() == name && fs.signature() == signature) { - return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS; + return fs.access_flags().as_field_flags(); } } return -1; @@ -2686,7 +2633,7 @@ JVM_ENTRY(jint, JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, for (int i = 0; i < methods_count; i++) { Method* method = methods->at(i); if (method->name() == name && method->signature() == signature) { - return method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; + return method->access_flags().as_method_flags(); } } return -1; @@ -3319,8 +3266,9 @@ JVM_END // VM Raw monitors (not to be confused with JvmtiRawMonitors) are a simple mutual exclusion // lock (not actually monitors: no wait/notify) that is exported by the VM for use by JDK // library code. They may be used by JavaThreads and non-JavaThreads and do not participate -// in the safepoint protocol, thread suspension, thread interruption, or anything of that -// nature. JavaThreads will be "in native" when using this API from JDK code. +// in the safepoint protocol, thread suspension, thread interruption, or most things of that +// nature, except JavaThreads will be blocked by VM_Exit::block_if_vm_exited if the VM has +// shutdown. JavaThreads will be "in native" when using this API from JDK code. JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) { diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml index 0afbf56b3fc97..4bff3230c9ee3 100644 --- a/src/hotspot/share/prims/jvmti.xml +++ b/src/hotspot/share/prims/jvmti.xml @@ -1,7 +1,7 @@ -package jdk.jfr.internal.settings; - -import jdk.jfr.SettingControl; - -/** - * SettingControls that derive from this class avoids executing settings - * modifications in a AccessController.doPrivilege(...) block. - */ -public abstract class JDKSettingControl extends SettingControl { -} + + + + = $(var.JpExecutableOSVersion))]]> + + + + + diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/wix3-to-wix4-conv.xsl b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/wix3-to-wix4-conv.xsl index 382ed731b5a6f..1122989d062bc 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/wix3-to-wix4-conv.xsl +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/wix3-to-wix4-conv.xsl @@ -1,7 +1,7 @@ + + + + + + + + + + m3 cycle - resolveAndBind(finder, "m1"); + assertThrows(ResolutionException.class, () -> resolveAndBind(finder, "m1")); } @@ -1554,8 +1573,8 @@ public void testCycleInProvider() { * - Configuration cf1: m1, m2 requires transitive m1 * - Configuration cf2: m1 requires m2 */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testReadModuleWithSameNameAsSelf() { + @Test + void testReadModuleWithSameNameAsSelf() { ModuleDescriptor descriptor1_v1 = newBuilder("m1") .build(); @@ -1573,7 +1592,7 @@ public void testReadModuleWithSameNameAsSelf() { // resolve should throw ResolutionException ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1_v2); - resolve(cf1, finder2, "m1"); + assertThrows(ResolutionException.class, () -> resolve(cf1, finder2, "m1")); } @@ -1585,8 +1604,8 @@ public void testReadModuleWithSameNameAsSelf() { * - Configuration cf2: m1, m3 requires transitive m1 * - Configuration cf3(cf1,cf2): m4 requires m2, m3 */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testReadTwoModuleWithSameName() { + @Test + void testReadTwoModuleWithSameName() { ModuleDescriptor descriptor1 = newBuilder("m1") .build(); @@ -1613,16 +1632,19 @@ public void testReadTwoModuleWithSameName() { // should throw ResolutionException as m4 will read modules named "m1". ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4); - Configuration.resolve(finder3, List.of(cf1, cf2), ModuleFinder.of(), Set.of("m4")); + assertThrows(ResolutionException.class, + () -> Configuration.resolve(finder3, + List.of(cf1, cf2), + ModuleFinder.of(), + Set.of("m4"))); } /** * Test two modules exporting package p to a module that reads both. */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testPackageSuppliedByTwoOthers() { - + @Test + void testPackageSuppliedByTwoOthers() { ModuleDescriptor descriptor1 = newBuilder("m1") .requires("m2") .requires("m3") @@ -1640,7 +1662,7 @@ public void testPackageSuppliedByTwoOthers() { = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); // m2 and m3 export package p to module m1 - resolve(finder, "m1"); + assertThrows(ResolutionException.class, () -> resolve(finder, "m1")); } @@ -1648,9 +1670,8 @@ public void testPackageSuppliedByTwoOthers() { * Test the scenario where a module contains a package p and reads * a module that exports package p. */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testPackageSuppliedBySelfAndOther() { - + @Test + void testPackageSuppliedBySelfAndOther() { ModuleDescriptor descriptor1 = newBuilder("m1") .requires("m2") .packages(Set.of("p")) @@ -1663,7 +1684,7 @@ public void testPackageSuppliedBySelfAndOther() { ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); // m1 contains package p, module m2 exports package p to m1 - resolve(finder, "m1"); + assertThrows(ResolutionException.class, () -> resolve(finder, "m1")); } @@ -1671,7 +1692,8 @@ public void testPackageSuppliedBySelfAndOther() { * Test the scenario where a module contains a package p and reads * a module that also contains a package p. */ - public void testContainsPackageInSelfAndOther() { + @Test + void testContainsPackageInSelfAndOther() { ModuleDescriptor descriptor1 = newBuilder("m1") .requires("m2") .packages(Set.of("p")) @@ -1702,8 +1724,8 @@ public void testContainsPackageInSelfAndOther() { * Test the scenario where a module that exports a package that is also * exported by a module that it reads in a parent layer. */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testExportSamePackageAsBootLayer() { + @Test + void testExportSamePackageAsBootLayer() { ModuleDescriptor descriptor = newBuilder("m1") .requires("java.base") .exports("java.lang") @@ -1714,14 +1736,15 @@ public void testExportSamePackageAsBootLayer() { Configuration bootConfiguration = ModuleLayer.boot().configuration(); // m1 contains package java.lang, java.base exports package java.lang to m1 - resolve(bootConfiguration, finder, "m1"); + assertThrows(ResolutionException.class, () -> resolve(bootConfiguration, finder, "m1")); } /** * Test "uses p.S" where p is contained in the same module. */ - public void testContainsService1() { + @Test + void testContainsService1() { ModuleDescriptor descriptor1 = newBuilder("m1") .packages(Set.of("p")) .uses("p.S") @@ -1739,8 +1762,8 @@ public void testContainsService1() { /** * Test "uses p.S" where p is contained in a different module. */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testContainsService2() { + @Test + void testContainsService2() { ModuleDescriptor descriptor1 = newBuilder("m1") .packages(Set.of("p")) .build(); @@ -1753,14 +1776,15 @@ public void testContainsService2() { ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); // m2 does not read a module that exports p - resolve(finder, "m2"); + assertThrows(ResolutionException.class, () -> resolve(finder, "m2")); } /** * Test "provides p.S" where p is contained in the same module. */ - public void testContainsService3() { + @Test + void testContainsService3() { ModuleDescriptor descriptor1 = newBuilder("m1") .packages(Set.of("p", "q")) .provides("p.S", List.of("q.S1")) @@ -1778,8 +1802,8 @@ public void testContainsService3() { /** * Test "provides p.S" where p is contained in a different module. */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testContainsService4() { + @Test + void testContainsService4() { ModuleDescriptor descriptor1 = newBuilder("m1") .packages(Set.of("p")) .build(); @@ -1792,46 +1816,182 @@ public void testContainsService4() { ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); // m2 does not read a module that exports p - resolve(finder, "m2"); + assertThrows(ResolutionException.class, () -> resolve(finder, "m2")); } + /** + * Test uses optional service. + * + * module m1 { requires static m2; uses p.S; } + */ + @Test + void testUsesOptionalService1() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .requires(Set.of(Requires.Modifier.STATIC), "m2") + .uses("p.S") + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 1); + assertTrue(cf.findModule("m1").isPresent()); + } /** - * Test "uses p.S" where p is not exported to the module. + * Test uses optional service. + * + * module m1 { requires m2; uses p.S; } + * module m2 { requires static transitive m3; } + */ + @Test + void testUsesOptionalService2() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .requires("m2") + .uses("p.S") + .build(); + ModuleDescriptor descriptor2 = newBuilder("m2") + .requires(Set.of(Requires.Modifier.STATIC, Requires.Modifier.TRANSITIVE), "m3") + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 2); + assertTrue(cf.findModule("m1").isPresent()); + assertTrue(cf.findModule("m2").isPresent()); + } + + /** + * Test uses optional service. + * + * module m1 { requires m2; uses p.S; } + * module m2 { requires transitive m3; } + * module m3 { requires static transitive m4; } */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testServiceTypePackageNotExported1() { + @Test + void testUsesOptionalService3() { ModuleDescriptor descriptor1 = newBuilder("m1") + .requires("m2") .uses("p.S") .build(); + ModuleDescriptor descriptor2 = newBuilder("m2") + .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3") + .build(); + ModuleDescriptor descriptor3 = newBuilder("m3") + .requires(Set.of(Requires.Modifier.STATIC, Requires.Modifier.TRANSITIVE), "m4") + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 3); + assertTrue(cf.findModule("m1").isPresent()); + assertTrue(cf.findModule("m2").isPresent()); + assertTrue(cf.findModule("m3").isPresent()); + } + /** + * Test provides optional service. + * + * module m1 { requires static m2; provides p.S with q.P; } + */ + @Test + void testProvidesOptionalService1() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .requires(Set.of(Requires.Modifier.STATIC), "m2") + .provides("p.S", List.of("q.P")) + .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1); - - // m1 does not read a module that exports p - resolve(finder, "m1"); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 1); + assertTrue(cf.findModule("m1").isPresent()); } + /** + * Test provides optional service. + * + * module m1 { requires m2; provides p.S with q.P; } + * module m2 { requires static transitive m3; } + */ + @Test + void testProvidesOptionalService2() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .requires("m2") + .provides("p.S", List.of("q.P")) + .build(); + ModuleDescriptor descriptor2 = newBuilder("m2") + .requires(Set.of(Requires.Modifier.STATIC, Requires.Modifier.TRANSITIVE), "m3") + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 2); + assertTrue(cf.findModule("m1").isPresent()); + assertTrue(cf.findModule("m2").isPresent()); + } /** - * Test "provides p.S" where p is not exported to the module. + * Test provides optional service. + * + * module m1 { requires m2; provides p.S with q.P; } + * module m2 { requires transitive m3; } + * module m3 { requires static transitive m4; } */ - @Test(expectedExceptions = { ResolutionException.class }) - public void testServiceTypePackageNotExported2() { + @Test + void testProvidesOptionalService3() { ModuleDescriptor descriptor1 = newBuilder("m1") - .provides("p.S", List.of("q.T")) + .requires("m2") + .provides("p.S", List.of("q.P")) + .build(); + ModuleDescriptor descriptor2 = newBuilder("m2") + .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3") .build(); + ModuleDescriptor descriptor3 = newBuilder("m3") + .requires(Set.of(Requires.Modifier.STATIC, Requires.Modifier.TRANSITIVE), "m4") + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); + Configuration cf = resolve(finder, "m1"); + assertTrue(cf.modules().size() == 3); + assertTrue(cf.findModule("m1").isPresent()); + assertTrue(cf.findModule("m2").isPresent()); + assertTrue(cf.findModule("m3").isPresent()); + } + /** + * Test "uses p.S" where p is not exported to the module. + */ + @Test + void testServiceTypePackageNotExported1() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .uses("p.S") + .build(); ModuleFinder finder = ModuleUtils.finderOf(descriptor1); - // m1 does not read a module that exports p - resolve(finder, "m1"); + // m1 does not read a module that exports p to m1 + assertThrows(ResolutionException.class, () -> resolve(finder, "m1")); + } + + /** + * Test "uses p.S" where p is not exported to the module. + * + * module m1 { requires m2; uses p.S; } + * module m2 { contains p; } + */ + @Test + void testServiceTypePackageNotExported2() { + ModuleDescriptor descriptor1 = newBuilder("m1") + .requires("m2") + .uses("p.S") + .build(); + ModuleDescriptor descriptor2 = newBuilder("m2") + .packages(Set.of("p")) + .build(); + ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); + + // m1 does not read a module that exports p to m1 + assertThrows(ResolutionException.class, () -> resolve(finder, "m1")); } /** * Test the empty configuration. */ - public void testEmptyConfiguration() { + @Test + void testEmptyConfiguration() { Configuration cf = Configuration.empty(); assertTrue(cf.parents().isEmpty()); @@ -1840,47 +2000,22 @@ public void testEmptyConfiguration() { assertFalse(cf.findModule("java.base").isPresent()); } - - // platform specific modules - - @DataProvider(name = "platformmatch") - public Object[][] createPlatformMatches() { - return new Object[][]{ - - { "", "" }, - { "linux-arm", "" }, - { "linux-arm", "linux-arm" }, - - }; - - }; - - @DataProvider(name = "platformmismatch") - public Object[][] createBad() { - return new Object[][] { - - { "linux-x64", "linux-arm" }, - { "linux-x64", "windows-x64" }, - - }; - } - /** * Test creating a configuration containing platform specific modules. */ - @Test(dataProvider = "platformmatch") - public void testPlatformMatch(String s1, String s2) throws IOException { - + @ParameterizedTest + @CsvSource({",", "linux-aarch64,", "linux-aarch64,linux-aarch64"}) + void testPlatformMatch(String targetPlatform1, String targetPlatform2) throws IOException { ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build(); Path system = writeModule(base, null); ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") .requires("m2") .build(); - Path dir1 = writeModule(descriptor1, s1); + Path dir1 = writeModule(descriptor1, targetPlatform1); ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build(); - Path dir2 = writeModule(descriptor2, s2); + Path dir2 = writeModule(descriptor2, targetPlatform2); ModuleFinder finder = ModuleFinder.of(system, dir1, dir2); @@ -1893,43 +2028,45 @@ public void testPlatformMatch(String s1, String s2) throws IOException { } /** - * Test attempting to create a configuration with modules for different - * platforms. + * Test attempting to create a configuration with modules for different platforms. */ - @Test(dataProvider = "platformmismatch", - expectedExceptions = FindException.class ) - public void testPlatformMisMatch(String s1, String s2) throws IOException { - testPlatformMatch(s1, s2); + @ParameterizedTest + @CsvSource({"linux-x64,linux-aarch64", "linux-x64,windows-x64"}) + void testPlatformMisMatch(String targetPlatform1, String targetPlatform2) throws IOException { + assertThrows(FindException.class, + () -> testPlatformMatch(targetPlatform1, targetPlatform2)); } // no parents - @Test(expectedExceptions = { IllegalArgumentException.class }) - public void testResolveRequiresWithNoParents() { + @Test + void testResolveRequiresWithNoParents() { ModuleFinder empty = ModuleFinder.of(); - Configuration.resolve(empty, List.of(), empty, Set.of()); + assertThrows(IllegalArgumentException.class, + () -> Configuration.resolve(empty, List.of(), empty, Set.of())); } - @Test(expectedExceptions = { IllegalArgumentException.class }) - public void testResolveRequiresAndUsesWithNoParents() { + @Test + void testResolveRequiresAndUsesWithNoParents() { ModuleFinder empty = ModuleFinder.of(); - Configuration.resolveAndBind(empty, List.of(), empty, Set.of()); + assertThrows(IllegalArgumentException.class, + () -> Configuration.resolveAndBind(empty, List.of(), empty, Set.of())); } // parents with modules for specific platforms - @Test(dataProvider = "platformmatch") - public void testResolveRequiresWithCompatibleParents(String s1, String s2) - throws IOException - { - ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build(); + @ParameterizedTest + @CsvSource({",", "linux-aarch64,", "linux-aarch64,linux-aarch64"}) + void testResolveRequiresWithCompatibleParents(String targetPlatform1, + String targetPlatform2) throws IOException { + ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build(); Path system = writeModule(base, null); ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1").build(); - Path dir1 = writeModule(descriptor1, s1); + Path dir1 = writeModule(descriptor1, targetPlatform1); ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build(); - Path dir2 = writeModule(descriptor2, s2); + Path dir2 = writeModule(descriptor2, targetPlatform2); ModuleFinder finder1 = ModuleFinder.of(system, dir1); Configuration cf1 = resolve(finder1, "m1"); @@ -1945,163 +2082,160 @@ public void testResolveRequiresWithCompatibleParents(String s1, String s2) } - @Test(dataProvider = "platformmismatch", - expectedExceptions = IllegalArgumentException.class ) - public void testResolveRequiresWithConflictingParents(String s1, String s2) - throws IOException - { - testResolveRequiresWithCompatibleParents(s1, s2); + @ParameterizedTest + @CsvSource({"linux-x64,linux-aarch64", "linux-x64,windows-x64"}) + void testResolveRequiresWithConflictingParents(String targetPlatform1, + String targetPlatform2) throws IOException { + assertThrows(IllegalArgumentException.class, + () -> testResolveRequiresWithCompatibleParents(targetPlatform1, targetPlatform2)); } // null handling - // finder1, finder2, roots - - - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull1() { - resolve((ModuleFinder)null, ModuleFinder.of()); + @Test + void testResolveRequiresWithNull1() { + assertThrows(NullPointerException.class, + () -> resolve((ModuleFinder) null, ModuleFinder.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull2() { - resolve(ModuleFinder.of(), (ModuleFinder)null); + @Test + void testResolveRequiresWithNull2() { + assertThrows(NullPointerException.class, + () -> resolve(ModuleFinder.of(), (ModuleFinder) null)); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull3() { + @Test + void testResolveRequiresWithNull3() { Configuration empty = Configuration.empty(); - Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull4() { + @Test + void testResolveRequiresWithNull4() { ModuleFinder empty = ModuleFinder.of(); - Configuration.resolve(empty, null, empty, Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolve(empty, null, empty, Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull5() { + @Test + void testResolveRequiresWithNull5() { Configuration cf = ModuleLayer.boot().configuration(); - Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresWithNull6() { + @Test + void testResolveRequiresWithNull6() { ModuleFinder empty = ModuleFinder.of(); Configuration cf = ModuleLayer.boot().configuration(); - Configuration.resolve(empty, List.of(cf), empty, null); + assertThrows(NullPointerException.class, + () -> Configuration.resolve(empty, List.of(cf), empty, null)); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull1() { - resolveAndBind((ModuleFinder) null, ModuleFinder.of()); + @Test + void testResolveRequiresAndUsesWithNull1() { + assertThrows(NullPointerException.class, + () -> resolveAndBind((ModuleFinder) null, ModuleFinder.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull2() { - resolveAndBind(ModuleFinder.of(), (ModuleFinder) null); + @Test + void testResolveRequiresAndUsesWithNull2() { + assertThrows(NullPointerException.class, + () -> resolveAndBind(ModuleFinder.of(), (ModuleFinder) null)); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull3() { + @Test + void testResolveRequiresAndUsesWithNull3() { Configuration empty = Configuration.empty(); - Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull4() { + @Test + void testResolveRequiresAndUsesWithNull4() { ModuleFinder empty = ModuleFinder.of(); - Configuration.resolveAndBind(empty, null, empty, Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolveAndBind(empty, null, empty, Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull5() { + @Test + void testResolveRequiresAndUsesWithNull5() { Configuration cf = ModuleLayer.boot().configuration(); - Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of()); + assertThrows(NullPointerException.class, + () -> Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of())); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testResolveRequiresAndUsesWithNull6() { + @Test + void testResolveRequiresAndUsesWithNull6() { ModuleFinder empty = ModuleFinder.of(); Configuration cf = ModuleLayer.boot().configuration(); - Configuration.resolveAndBind(empty, List.of(cf), empty, null); + assertThrows(NullPointerException.class, + () -> Configuration.resolveAndBind(empty, List.of(cf), empty, null)); } - @Test(expectedExceptions = { NullPointerException.class }) - public void testFindModuleWithNull() { - Configuration.empty().findModule(null); + @Test + void testFindModuleWithNull() { + assertThrows(NullPointerException.class, () -> Configuration.empty().findModule(null)); } // unmodifiable collections - @DataProvider(name = "configurations") - public Object[][] configurations() { - // empty, boot, and custom configurations - return new Object[][] { - { Configuration.empty(), null }, - { ModuleLayer.boot().configuration(), null }, - { resolve(ModuleFinder.of()), null }, - }; - } - - @Test(dataProvider = "configurations", - expectedExceptions = { UnsupportedOperationException.class }) - public void testUnmodifiableParents1(Configuration cf, Object ignore) { - cf.parents().add(Configuration.empty()); - } - - @Test(dataProvider = "configurations", - expectedExceptions = { UnsupportedOperationException.class }) - public void testUnmodifiableParents2(Configuration cf, Object ignore) { - cf.parents().remove(Configuration.empty()); + static Stream configurations() { + return Stream.of( + Configuration.empty(), + ModuleLayer.boot().configuration(), + resolve(ModuleFinder.of()) + ); } - @Test(dataProvider = "configurations", - expectedExceptions = { UnsupportedOperationException.class }) - public void testUnmodifiableModules1(Configuration cf, Object ignore) { - ResolvedModule module = ModuleLayer.boot() - .configuration() - .findModule("java.base") - .orElseThrow(); - cf.modules().add(module); + @ParameterizedTest + @MethodSource("configurations") + void testUnmodifiableParents(Configuration cf) { + assertThrows(UnsupportedOperationException.class, + () -> cf.parents().add(Configuration.empty())); + assertThrows(UnsupportedOperationException.class, + () -> cf.parents().remove(Configuration.empty())); } - @Test(dataProvider = "configurations", - expectedExceptions = { UnsupportedOperationException.class }) - public void testUnmodifiableModules2(Configuration cf, Object ignore) { + @ParameterizedTest + @MethodSource("configurations") + void testUnmodifiableModules(Configuration cf) { ResolvedModule module = ModuleLayer.boot() .configuration() .findModule("java.base") .orElseThrow(); - cf.modules().remove(module); + assertThrows(UnsupportedOperationException.class, + () -> cf.modules().add(module)); + assertThrows(UnsupportedOperationException.class, + () -> cf.modules().remove(module)); } /** * Invokes parent.resolve(...) */ - private Configuration resolve(Configuration parent, - ModuleFinder before, - ModuleFinder after, - String... roots) { + private static Configuration resolve(Configuration parent, + ModuleFinder before, + ModuleFinder after, + String... roots) { return parent.resolve(before, after, Set.of(roots)); } - private Configuration resolve(Configuration parent, - ModuleFinder before, - String... roots) { + private static Configuration resolve(Configuration parent, + ModuleFinder before, + String... roots) { return resolve(parent, before, ModuleFinder.of(), roots); } - private Configuration resolve(ModuleFinder before, - ModuleFinder after, - String... roots) { + private static Configuration resolve(ModuleFinder before, + ModuleFinder after, + String... roots) { return resolve(Configuration.empty(), before, after, roots); } - private Configuration resolve(ModuleFinder before, - String... roots) { + private static Configuration resolve(ModuleFinder before, + String... roots) { return resolve(Configuration.empty(), before, roots); } @@ -2109,27 +2243,27 @@ private Configuration resolve(ModuleFinder before, /** * Invokes parent.resolveAndBind(...) */ - private Configuration resolveAndBind(Configuration parent, - ModuleFinder before, - ModuleFinder after, - String... roots) { + private static Configuration resolveAndBind(Configuration parent, + ModuleFinder before, + ModuleFinder after, + String... roots) { return parent.resolveAndBind(before, after, Set.of(roots)); } - private Configuration resolveAndBind(Configuration parent, - ModuleFinder before, - String... roots) { + private static Configuration resolveAndBind(Configuration parent, + ModuleFinder before, + String... roots) { return resolveAndBind(parent, before, ModuleFinder.of(), roots); } - private Configuration resolveAndBind(ModuleFinder before, - ModuleFinder after, - String... roots) { + private static Configuration resolveAndBind(ModuleFinder before, + ModuleFinder after, + String... roots) { return resolveAndBind(Configuration.empty(), before, after, roots); } - private Configuration resolveAndBind(ModuleFinder before, - String... roots) { + private static Configuration resolveAndBind(ModuleFinder before, + String... roots) { return resolveAndBind(Configuration.empty(), before, roots); } @@ -2138,7 +2272,7 @@ private Configuration resolveAndBind(ModuleFinder before, * Writes a module-info.class. If {@code targetPlatform} is not null then * it includes the ModuleTarget class file attribute with the target platform. */ - static Path writeModule(ModuleDescriptor descriptor, String targetPlatform) + private static Path writeModule(ModuleDescriptor descriptor, String targetPlatform) throws IOException { ModuleTarget target; diff --git a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java index c7c57d2371cb9..8ee5179ea818e 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.lang.reflect.InaccessibleObjectException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.security.ProtectionDomain; import jdk.internal.misc.Unsafe; @@ -147,7 +148,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; try { diff --git a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java index 22fcb2e01fa79..9574afee40729 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ import jdk.internal.misc.Unsafe; import jdk.internal.module.ModulePath; import jdk.internal.perf.Perf; +import java.security.ProtectionDomain; import org.testng.annotations.Test; import static org.testng.Assert.*; @@ -193,7 +194,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; assertFalse(ctor.trySetAccessible()); diff --git a/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java b/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java index dbe10f9646c80..aca88bb95901a 100644 --- a/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java +++ b/test/jdk/java/net/DatagramSocket/InterruptibleDatagramSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ * @test * @summary Check interrupt mechanism for DatagramSocket, * MulticastSocket, and DatagramSocketAdaptor + * @library /test/lib * @run main InterruptibleDatagramSocket */ @@ -97,6 +98,10 @@ else if (!s.isClosed() && interruptible) } public static void main(String[] args) throws Exception { + if (Thread.currentThread().isVirtual()) { + throw new jtreg.SkippedException( + "skipping test execution - main thread is a virtual thread"); + } try (DatagramSocket s = new DatagramSocket()) { System.out.println("Testing interrupt of DatagramSocket receive " + "on endpoint " + s.getLocalSocketAddress()); diff --git a/test/jdk/java/net/Socket/ConnectFailTest.java b/test/jdk/java/net/Socket/ConnectFailTest.java index 7cc46ce4a4dd6..f21ed7d132df1 100644 --- a/test/jdk/java/net/Socket/ConnectFailTest.java +++ b/test/jdk/java/net/Socket/ConnectFailTest.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.Proxy; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; @@ -36,6 +37,7 @@ import java.nio.channels.SocketChannel; import java.util.List; +import static java.net.InetAddress.getLoopbackAddress; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -50,6 +52,8 @@ */ class ConnectFailTest { + // Implementation Note: Explicitly binding on the loopback address to avoid potential unstabilities. + private static final int DEAD_SERVER_PORT = 0xDEAD; private static final InetSocketAddress REFUSING_SOCKET_ADDRESS = Utils.refusingEndpoint(); @@ -83,7 +87,7 @@ void testUnboundSocket(Socket socket) throws IOException { @MethodSource("sockets") void testBoundSocket(Socket socket) throws IOException { try (socket) { - socket.bind(new InetSocketAddress(0)); + socket.bind(new InetSocketAddress(getLoopbackAddress(), 0)); assertTrue(socket.isBound()); assertFalse(socket.isConnected()); assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS)); @@ -132,7 +136,7 @@ void testUnboundSocketWithUnresolvedAddress(Socket socket) throws IOException { @MethodSource("sockets") void testBoundSocketWithUnresolvedAddress(Socket socket) throws IOException { try (socket) { - socket.bind(new InetSocketAddress(0)); + socket.bind(new InetSocketAddress(getLoopbackAddress(), 0)); assertTrue(socket.isBound()); assertFalse(socket.isConnected()); assertThrows(UnknownHostException.class, () -> socket.connect(UNRESOLVED_ADDRESS)); @@ -161,7 +165,8 @@ static List sockets() throws Exception { Socket socket = new Socket(); @SuppressWarnings("resource") Socket channelSocket = SocketChannel.open().socket(); - return List.of(socket, channelSocket); + Socket noProxySocket = new Socket(Proxy.NO_PROXY); + return List.of(socket, channelSocket, noProxySocket); } private static ServerSocket createEphemeralServerSocket() throws IOException { diff --git a/test/jdk/java/net/Socket/ConnectSocksProxyTest.java b/test/jdk/java/net/Socket/ConnectSocksProxyTest.java new file mode 100644 index 0000000000000..8bea5ff816eec --- /dev/null +++ b/test/jdk/java/net/Socket/ConnectSocksProxyTest.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Utils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.Authenticator; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.Proxy; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; + +import static java.net.InetAddress.getLoopbackAddress; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8346017 + * @summary Verifies the `connect()` behaviour of a SOCKS proxy socket. In particular, that passing a resolvable + * unresolved address doesn't throw an exception. + * @library /test/lib /java/net/Socks + * @build SocksServer + * @run junit ConnectSocksProxyTest + */ +class ConnectSocksProxyTest { + + // Implementation Note: Explicitly binding on the loopback address to avoid potential unstabilities. + + private static final int DEAD_SERVER_PORT = 0xDEAD; + + private static final InetSocketAddress REFUSING_SOCKET_ADDRESS = Utils.refusingEndpoint(); + + private static final InetSocketAddress UNRESOLVED_ADDRESS = + InetSocketAddress.createUnresolved("no.such.host", DEAD_SERVER_PORT); + + private static final String PROXY_AUTH_USERNAME = "foo"; + + private static final String PROXY_AUTH_PASSWORD = "bar"; + + private static SocksServer PROXY_SERVER; + + private static Proxy PROXY; + + @BeforeAll + static void initAuthenticator() { + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(PROXY_AUTH_USERNAME, PROXY_AUTH_PASSWORD.toCharArray()); + } + }); + } + + @BeforeAll + static void initProxyServer() throws IOException { + PROXY_SERVER = new SocksServer(getLoopbackAddress(), 0, false); + PROXY_SERVER.addUser(PROXY_AUTH_USERNAME, PROXY_AUTH_PASSWORD); + PROXY_SERVER.start(); + InetSocketAddress proxyAddress = new InetSocketAddress(getLoopbackAddress(), PROXY_SERVER.getPort()); + PROXY = new Proxy(Proxy.Type.SOCKS, proxyAddress); + } + + @AfterAll + static void stopProxyServer() { + PROXY_SERVER.close(); + } + + @Test + void testUnresolvedAddress() { + assertTrue(UNRESOLVED_ADDRESS.isUnresolved()); + } + + /** + * Verifies that an unbound socket is closed when {@code connect()} fails. + */ + @Test + void testUnboundSocket() throws IOException { + try (Socket socket = createProxiedSocket()) { + assertFalse(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a bound socket is closed when {@code connect()} fails. + */ + @Test + void testBoundSocket() throws IOException { + try (Socket socket = createProxiedSocket()) { + socket.bind(new InetSocketAddress(getLoopbackAddress(), 0)); + assertTrue(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a connected socket is not closed when {@code connect()} fails. + */ + @Test + void testConnectedSocket() throws Throwable { + try (Socket socket = createProxiedSocket(); + ServerSocket serverSocket = createEphemeralServerSocket()) { + socket.connect(serverSocket.getLocalSocketAddress()); + try (Socket _ = serverSocket.accept()) { + assertTrue(socket.isBound()); + assertTrue(socket.isConnected()); + SocketException exception = assertThrows( + SocketException.class, + () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertEquals("Already connected", exception.getMessage()); + assertFalse(socket.isClosed()); + } + } + } + + /** + * Delegates to {@link #testUnconnectedSocketWithUnresolvedAddress(boolean, Socket)} using an unbound socket. + */ + @Test + void testUnboundSocketWithUnresolvedAddress() throws IOException { + try (Socket socket = createProxiedSocket()) { + assertFalse(socket.isBound()); + assertFalse(socket.isConnected()); + testUnconnectedSocketWithUnresolvedAddress(false, socket); + } + } + + /** + * Delegates to {@link #testUnconnectedSocketWithUnresolvedAddress(boolean, Socket)} using a bound socket. + */ + @Test + void testBoundSocketWithUnresolvedAddress() throws IOException { + try (Socket socket = createProxiedSocket()) { + socket.bind(new InetSocketAddress(getLoopbackAddress(), 0)); + testUnconnectedSocketWithUnresolvedAddress(true, socket); + } + } + + /** + * Verifies the behaviour of an unconnected socket when {@code connect()} is invoked using an unresolved address. + */ + private static void testUnconnectedSocketWithUnresolvedAddress(boolean bound, Socket socket) throws IOException { + assertEquals(bound, socket.isBound()); + assertFalse(socket.isConnected()); + try (ServerSocket serverSocket = createEphemeralServerSocket()) { + InetSocketAddress unresolvedAddress = InetSocketAddress.createUnresolved( + getLoopbackAddress().getHostAddress(), + serverSocket.getLocalPort()); + socket.connect(unresolvedAddress); + try (Socket _ = serverSocket.accept()) { + assertTrue(socket.isBound()); + assertTrue(socket.isConnected()); + assertFalse(socket.isClosed()); + } + } + } + + /** + * Verifies that a connected socket is not closed when {@code connect()} is invoked using an unresolved address. + */ + @Test + void testConnectedSocketWithUnresolvedAddress() throws Throwable { + try (Socket socket = createProxiedSocket(); + ServerSocket serverSocket = createEphemeralServerSocket()) { + socket.connect(serverSocket.getLocalSocketAddress()); + try (Socket _ = serverSocket.accept()) { + assertTrue(socket.isBound()); + assertTrue(socket.isConnected()); + SocketException exception = assertThrows( + SocketException.class, + () -> socket.connect(UNRESOLVED_ADDRESS)); + assertEquals("Already connected", exception.getMessage()); + assertFalse(socket.isClosed()); + } + } + } + + private static Socket createProxiedSocket() { + return new Socket(PROXY); + } + + private static ServerSocket createEphemeralServerSocket() throws IOException { + return new ServerSocket(0, 0, getLoopbackAddress()); + } + +} diff --git a/test/jdk/java/net/UnixDomainSocketAddress/AddressTest.java b/test/jdk/java/net/UnixDomainSocketAddress/AddressTest.java index 80bc3ae10333e..ba55eac46df2a 100644 --- a/test/jdk/java/net/UnixDomainSocketAddress/AddressTest.java +++ b/test/jdk/java/net/UnixDomainSocketAddress/AddressTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 8231358 - * @compile ../../nio/file/spi/TestProvider.java AddressTest.java + * @compile ../../nio/file/spi/testfsp/testfsp/TestProvider.java AddressTest.java * @run testng/othervm AddressTest */ @@ -51,8 +51,8 @@ public class AddressTest { @Test public static void runTest() throws Exception { - TestProvider prov = new TestProvider(FileSystems.getDefault().provider()); - Path path = prov.getPath(URI.create("file:/")); + var fsp = new testfsp.TestProvider(FileSystems.getDefault().provider()); + Path path = fsp.getPath(URI.create("file:/")); assertThrows(IAE, () -> UnixDomainSocketAddress.of(path)); } } diff --git a/test/jdk/java/net/httpclient/AbstractConnectTimeoutHandshake.java b/test/jdk/java/net/httpclient/AbstractConnectTimeoutHandshake.java index b80ec09747a93..3febe7145b42e 100644 --- a/test/jdk/java/net/httpclient/AbstractConnectTimeoutHandshake.java +++ b/test/jdk/java/net/httpclient/AbstractConnectTimeoutHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,10 +44,11 @@ import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; + +import jdk.test.lib.net.URIBuilder; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; -import static java.lang.String.format; import static java.lang.System.out; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.net.http.HttpClient.Version.HTTP_1_1; @@ -56,7 +57,7 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; import static org.testng.Assert.fail; -public abstract class AbstractConnectTimeoutHandshake { +abstract class AbstractConnectTimeoutHandshake { // The number of iterations each testXXXClient performs. static final int TIMES = 2; @@ -197,15 +198,15 @@ static void printResponse(HttpResponse response) { // -- Infrastructure - static String serverAuthority(Server server) { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + server.getPort(); - } - @BeforeTest public void setup() throws Exception { server = new Server(); - httpsURI = URI.create("https://" + serverAuthority(server) + "/foo"); + httpsURI = URIBuilder.newBuilder() + .scheme("https") + .loopback() + .port(server.getPort()) + .path("/foo") + .build(); out.println("HTTPS URI: " + httpsURI); } diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java index 4079bd81e3e19..859169dcaae83 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,6 @@ * questions. */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.ITestContext; import org.testng.ITestResult; @@ -40,8 +37,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UncheckedIOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -73,7 +68,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.String.format; import static java.lang.System.out; @@ -479,10 +473,12 @@ private void testThrowing(String uri, boolean sameClient, // synchronous send will rethrow exceptions Throwable throwable = t.getCause(); assert throwable != null; - - if (thrower.test(where, throwable)) { - System.out.println(now() + "Got expected exception: " + throwable); - } else throw causeNotFound(where, t); + Throwable cause = findCause(where, throwable, thrower); + if (cause == null) { + throw causeNotFound(where, t); + } else { + System.out.println(now() + "Got expected exception: " + cause); + } } } if (response != null) { diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java index dc7ca3fe9d542..7362ada977214 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -413,7 +413,7 @@ protected void testThrowingAsInputStreamAsyncImpl(String uri, excludes(SubscriberType.OFFLINE)); } - private void testThrowing(String name, String uri, boolean sameClient, + void testThrowing(String name, String uri, boolean sameClient, Supplier> handlers, Finisher finisher, Thrower thrower, boolean async, EnumSet excludes) @@ -585,8 +585,7 @@ final List checkAsInputStream(Where w, HttpResponse resp, return shouldHaveThrown(w, resp, thrower); } - private static Throwable findCause(Throwable x, - Predicate filter) { + static Throwable findCause(Throwable x, Predicate filter) { while (x != null && !filter.test(x)) x = x.getCause(); return x; } diff --git a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java index d2bbd2635af31..a879525b4b4b9 100644 --- a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java +++ b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ * @summary Tests HttpRequest.BodyPublishers::concat */ -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -57,6 +55,7 @@ import java.util.concurrent.Flow; import java.util.concurrent.Flow.Subscriber; import java.util.concurrent.Flow.Subscription; +import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; @@ -67,12 +66,8 @@ import java.util.stream.LongStream; import java.util.stream.Stream; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import javax.net.ssl.SSLContext; -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.Assert; import org.testng.ITestContext; @@ -419,9 +414,11 @@ public void cancel() { } static class RequestSubscriber implements Flow.Subscriber { - CompletableFuture subscriptionCF = new CompletableFuture<>(); - ConcurrentLinkedDeque items = new ConcurrentLinkedDeque<>(); - CompletableFuture> resultCF = new CompletableFuture<>(); + final CompletableFuture subscriptionCF = new CompletableFuture<>(); + final ConcurrentLinkedDeque items = new ConcurrentLinkedDeque<>(); + final CompletableFuture> resultCF = new CompletableFuture<>(); + + final Semaphore semaphore = new Semaphore(0); @Override public void onSubscribe(Subscription subscription) { @@ -431,6 +428,11 @@ public void onSubscribe(Subscription subscription) { @Override public void onNext(ByteBuffer item) { items.addLast(item); + int available = semaphore.availablePermits(); + if (available > Integer.MAX_VALUE - 8) { + onError(new IllegalStateException("too many buffers in queue: " + available)); + } + semaphore.release(); } @Override @@ -443,6 +445,18 @@ public void onComplete() { resultCF.complete(items.stream().collect(Collectors.toUnmodifiableList())); } + public ByteBuffer take() { + // it is not guaranteed that the buffer will be added to + // the queue in the same thread that calls request(1). + try { + semaphore.acquire(); + } catch (InterruptedException x) { + Thread.currentThread().interrupt(); + throw new CompletionException(x); + } + return items.pop(); + } + CompletableFuture> resultCF() { return resultCF; } } @@ -628,8 +642,9 @@ public void testPositiveRequests() { publisher.subscribe(requestSubscriber1); Subscription subscription1 = requestSubscriber1.subscriptionCF.join(); subscription1.request(16); - assertTrue(requestSubscriber1.resultCF().isDone()); + // onNext() may not be called in the same thread than request() List list1 = requestSubscriber1.resultCF().join(); + assertTrue(requestSubscriber1.resultCF().isDone()); String result1 = stringFromBytes(list1.stream()); assertEquals(result1, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); System.out.println("Got expected sentence with one request: \"%s\"".formatted(result1)); @@ -646,8 +661,8 @@ public void testPositiveRequests() { subscription2.request(4); assertFalse(requestSubscriber2.resultCF().isDone()); subscription2.request(1); - assertTrue(requestSubscriber2.resultCF().isDone()); List list2 = requestSubscriber2.resultCF().join(); + assertTrue(requestSubscriber2.resultCF().isDone()); String result2 = stringFromBytes(list2.stream()); assertEquals(result2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); System.out.println("Got expected sentence with 4 requests: \"%s\"".formatted(result1)); @@ -689,7 +704,7 @@ public void testCancel() { // receive half the data for (int i = 0; i < n; i++) { subscription.request(1); - ByteBuffer buffer = subscriber.items.pop(); + ByteBuffer buffer = subscriber.take(); } // cancel subscription @@ -789,7 +804,8 @@ public void testCancelSubscription() { @Test(dataProvider = "variants") public void test(String uri, boolean sameClient) throws Exception { checkSkip(); - System.out.println("Request to " + uri); + System.out.printf("Request to %s (sameClient: %s)%n", uri, sameClient); + System.err.printf("Request to %s (sameClient: %s)%n", uri, sameClient); HttpClient client = newHttpClient(sameClient); @@ -802,7 +818,8 @@ public void test(String uri, boolean sameClient) throws Exception { .POST(publisher) .build(); for (int i = 0; i < ITERATION_COUNT; i++) { - System.out.println("Iteration: " + i); + System.out.println(uri + ": Iteration: " + i); + System.err.println(uri + ": Iteration: " + i); HttpResponse response = client.send(request, BodyHandlers.ofString()); int expectedResponse = RESPONSE_CODE; if (response.statusCode() != expectedResponse) diff --git a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java index b0fb8bcb5ed8d..7e7709c033cfd 100644 --- a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java +++ b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8277969 8299338 + * @bug 8277969 8299338 8349702 * @summary Test for edge case where the executor is not accepting * new tasks while the client is still running * @library /test/lib /test/jdk/java/net/httpclient/lib diff --git a/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeAsync.java b/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeAsync.java index a5fa9e75d0952..6cdaf594b1d58 100644 --- a/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeAsync.java +++ b/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ * @test * @summary Tests connection timeouts during SSL handshake * @bug 8208391 + * @library /test/lib + * @build AbstractConnectTimeoutHandshake * @run testng/othervm ConnectTimeoutHandshakeAsync */ diff --git a/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeSync.java b/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeSync.java index b6a301dac28e4..17ea3041c5bd1 100644 --- a/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeSync.java +++ b/test/jdk/java/net/httpclient/ConnectTimeoutHandshakeSync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ * @test * @summary Tests connection timeouts during SSL handshake * @bug 8208391 + * @library /test/lib + * @build AbstractConnectTimeoutHandshake * @run testng/othervm ConnectTimeoutHandshakeSync */ diff --git a/test/jdk/java/net/httpclient/CookieHeaderTest.java b/test/jdk/java/net/httpclient/CookieHeaderTest.java index d5eca06c0f0ed..b39a23371abf8 100644 --- a/test/jdk/java/net/httpclient/CookieHeaderTest.java +++ b/test/jdk/java/net/httpclient/CookieHeaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,9 +33,6 @@ * CookieHeaderTest */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -51,7 +48,6 @@ import java.io.PrintWriter; import java.io.Writer; import java.net.CookieHandler; -import java.net.CookieManager; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; @@ -65,7 +61,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -76,7 +71,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import static java.lang.System.out; import static java.net.http.HttpClient.Version.HTTP_1_1; diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java index 7038d82d91fdc..7b4f7fd34620c 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClient.java +++ b/test/jdk/java/net/httpclient/DigestEchoClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,7 @@ import sun.net.www.HeaderParser; import static java.lang.System.out; +import static java.lang.System.err; import static java.lang.String.format; /** @@ -304,6 +305,9 @@ public static void main(String[] args) throws Exception { } catch(Throwable t) { out.println(DigestEchoServer.now() + ": Unexpected exception: " + t); + t.printStackTrace(System.out); + err.println(DigestEchoServer.now() + + ": Unexpected exception: " + t); t.printStackTrace(); failed = t; throw t; @@ -393,15 +397,21 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, HttpResponse r; CompletableFuture> cf1; String auth = null; + Throwable failed = null; + URI reqURI = null; try { - for (int i=0; i lines = List.of(Arrays.copyOfRange(data, 0, i+1)); + List lines = List.of(Arrays.copyOfRange(data, 0, i + 1)); assert lines.size() == i + 1; String body = lines.stream().collect(Collectors.joining("\r\n")); BodyPublisher reqBody = BodyPublishers.ofString(body); - HttpRequest.Builder builder = HttpRequest.newBuilder(uri).version(clientVersion) + URI baseReq = URI.create(uri + "?iteration=" + i + ",async=" + async + + ",addHeaders=" + addHeaders + ",preemptive=" + preemptive + + ",expectContinue=" + expectContinue + ",version=" + clientVersion); + reqURI = URI.create(baseReq + ",basicCount=" + basicCount.get()); + HttpRequest.Builder builder = HttpRequest.newBuilder(reqURI).version(clientVersion) .POST(reqBody).expectContinue(expectContinue); boolean isTunnel = isProxy(authType) && useSSL; if (addHeaders) { @@ -433,8 +443,10 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, HttpResponse> resp; try { if (async) { + out.printf("%s client.sendAsync(%s)%n", DigestEchoServer.now(), request); resp = client.sendAsync(request, BodyHandlers.ofLines()).join(); } else { + out.printf("%s client.send(%s)%n", DigestEchoServer.now(), request); resp = client.send(request, BodyHandlers.ofLines()); } } catch (Throwable t) { @@ -443,17 +455,10 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, long n = basicCount.getAndIncrement(); basics.set((basics.get() * n + (stop - start)) / (n + 1)); } - // unwrap CompletionException - if (t instanceof CompletionException) { - assert t.getCause() != null; - t = t.getCause(); - } - out.println(DigestEchoServer.now() - + ": Unexpected exception: " + t); - throw new RuntimeException("Unexpected exception: " + t, t); + throw t; } - if (addHeaders && !preemptive && (i==0 || isSchemeDisabled())) { + if (addHeaders && !preemptive && (i == 0 || isSchemeDisabled())) { assert resp.statusCode() == 401 || resp.statusCode() == 407; Stream respBody = resp.body(); if (respBody != null) { @@ -462,11 +467,15 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, } System.out.println(String.format("%s received: adding header %s: %s", resp.statusCode(), authorizationKey(authType), auth)); - request = HttpRequest.newBuilder(uri).version(clientVersion) + reqURI = URI.create(baseReq + ",withAuthorization=" + + authType + ",basicCount=" + basicCount.get()); + request = HttpRequest.newBuilder(reqURI).version(clientVersion) .POST(reqBody).header(authorizationKey(authType), auth).build(); if (async) { + out.printf("%s client.sendAsync(%s)%n", DigestEchoServer.now(), request); resp = client.sendAsync(request, BodyHandlers.ofLines()).join(); } else { + out.printf("%s client.send(%s)%n", DigestEchoServer.now(), request); resp = client.send(request, BodyHandlers.ofLines()); } } @@ -500,6 +509,15 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, throw new RuntimeException("Unexpected response: " + respLines); } } + } catch (Throwable t) { + if (reqURI == null) { + failed = t; + throw t; + } + String decoration = "%s Unexpected exception %s for %s".formatted(DigestEchoServer.now(), t, reqURI); + RuntimeException decorated = new RuntimeException(decoration, t); + failed = decorated; + throw decorated; } finally { client = null; System.gc(); @@ -508,7 +526,10 @@ void testBasic(Version clientVersion, Version serverVersion, boolean async, if (queue.remove(100) == ref) break; } var error = TRACKER.checkShutdown(900); - if (error != null) throw error; + if (error != null) { + if (failed != null) error.addSuppressed(failed); + throw error; + } } System.out.println("OK"); } @@ -546,16 +567,22 @@ void testDigest(Version clientVersion, Version serverVersion, byte[] cnonce = new byte[16]; String cnonceStr = null; DigestEchoServer.DigestResponse challenge = null; - + ReferenceQueue queue = new ReferenceQueue<>(); + WeakReference ref = new WeakReference<>(client, queue); + URI reqURI = null; + Throwable failed = null; try { - for (int i=0; i lines = List.of(Arrays.copyOfRange(data, 0, i+1)); + List lines = List.of(Arrays.copyOfRange(data, 0, i + 1)); assert lines.size() == i + 1; String body = lines.stream().collect(Collectors.joining("\r\n")); HttpRequest.BodyPublisher reqBody = HttpRequest.BodyPublishers.ofString(body); + URI baseReq = URI.create(uri + "?iteration=" + i + ",async=" + async + + ",expectContinue=" + expectContinue + ",version=" + clientVersion); + reqURI = URI.create(baseReq + ",digestCount=" + digestCount.get()); HttpRequest.Builder reqBuilder = HttpRequest - .newBuilder(uri).version(clientVersion).POST(reqBody) + .newBuilder(reqURI).version(clientVersion).POST(reqBody) .expectContinue(expectContinue); boolean isTunnel = isProxy(authType) && useSSL; @@ -578,8 +605,10 @@ void testDigest(Version clientVersion, Version serverVersion, HttpRequest request = reqBuilder.build(); HttpResponse> resp; if (async) { + out.printf("%s client.sendAsync(%s)%n", DigestEchoServer.now(), request); resp = client.sendAsync(request, BodyHandlers.ofLines()).join(); } else { + out.printf("%s client.send(%s)%n", DigestEchoServer.now(), request); resp = client.send(request, BodyHandlers.ofLines()); } System.out.println(resp); @@ -609,16 +638,18 @@ void testDigest(Version clientVersion, Version serverVersion, challenge = DigestEchoServer.DigestResponse .create(authenticate.substring("Digest ".length())); String auth = digestResponse(uri, digestMethod, challenge, cnonceStr); + reqURI = URI.create(baseReq + ",withAuth=" + authType + ",digestCount=" + digestCount.get()); try { - request = HttpRequest.newBuilder(uri).version(clientVersion) - .POST(reqBody).header(authorizationKey(authType), auth).build(); + request = HttpRequest.newBuilder(reqURI).version(clientVersion) + .POST(reqBody).header(authorizationKey(authType), auth).build(); } catch (IllegalArgumentException x) { throw x; } - if (async) { + out.printf("%s client.sendAsync(%s)%n", DigestEchoServer.now(), request); resp = client.sendAsync(request, BodyHandlers.ofLines()).join(); } else { + out.printf("%s client.send(%s)%n", DigestEchoServer.now(), request); resp = client.send(request, BodyHandlers.ofLines()); } System.out.println(resp); @@ -649,7 +680,29 @@ void testDigest(Version clientVersion, Version serverVersion, throw new RuntimeException("Unexpected response: " + respLines); } } + } catch (Throwable t) { + if (reqURI == null) { + failed = t; + throw t; + } + String decoration = "%s Unexpected exception %s for %s".formatted(DigestEchoServer.now(), t, reqURI); + RuntimeException decorated = new RuntimeException(decoration, t); + failed = decorated; + throw decorated; } finally { + client = null; + System.gc(); + while (!ref.refersTo(null)) { + System.gc(); + if (queue.remove(100) == ref) break; + } + var error = TRACKER.checkShutdown(900); + if (error != null) { + if (failed != null) { + error.addSuppressed(failed); + } + throw error; + } } System.out.println("OK"); } diff --git a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java index 3676eb7236be3..5d0935d721631 100644 --- a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java +++ b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,8 +233,12 @@ void testPublishTooMany(String uri) throws InterruptedException { } private void assertMessage(Throwable t, String contains) { - if (!t.getMessage().contains(contains)) { - String error = "Exception message:[" + t.toString() + "] doesn't contain [" + contains + "]"; + Throwable cause = t; + do { + if (cause.getMessage().contains(contains)) break; + } while ((cause = cause.getCause()) != null); + if (cause == null) { + String error = "Exception message:[" + t + "] doesn't contain [" + contains + "]"; throw new AssertionError(error, t); } } diff --git a/test/jdk/java/net/httpclient/HttpClientSNITest.java b/test/jdk/java/net/httpclient/HttpClientSNITest.java new file mode 100644 index 0000000000000..095508fd849f0 --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpClientSNITest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.List; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.httpclient.test.lib.common.ServerNameMatcher; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8346705 + * @summary verify the behaviour of java.net.http.HttpClient + * when sending a Server Name Indication in the TLS + * connections that it establishes for the requests + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.net.URIBuilder + * @run junit HttpClientSNITest + */ +public class HttpClientSNITest { + private static final String RESP_BODY_TEXT = "hello world"; + + private static final class Handler implements HttpTestHandler { + + @Override + public void handle(final HttpTestExchange exch) throws IOException { + System.out.println("handling request " + exch.getRequestURI()); + final byte[] respBody = RESP_BODY_TEXT.getBytes(US_ASCII); + exch.sendResponseHeaders(200, respBody.length); + try (final OutputStream os = exch.getResponseBody()) { + os.write(respBody); + } + } + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a IP address literal as the host. For one of the request, the HttpClient + * is configured with specific ServerName(s) through HttpClient.sslParameters() + * and for the other request, it isn't. + * The test then verifies that for such requests with a IP address literal as the host, + * the HttpClient sends across the ServerName(s) if any has been configured on the client. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exception { + final SSLContext sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "could not create a SSLContext"); + final String expectedSNI = "non-dns-resolvable.foo.bar.localhost"; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher, sslContext); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName(expectedSNI))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final String ipLiteral = InetAddress.getLoopbackAddress().getHostAddress(); + final URI reqURI = URIBuilder.newBuilder() + .host(ipLiteral) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + if (sniConfiguredOnClient) { + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } else { + assertFalse(matcher.wasInvoked(), "SNIMatcher was unexpectedly invoked" + + " on the server"); + } + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a hostname (i.e. not a IP address literal) as the host. For one of the request, + * the HttpClient is configured with specific ServerName(s) through + * HttpClient.sslParameters() and for the other request, it isn't. + * The test then verifies that for such requests with a hostname + * (i.e. not a IP address literal) in the request URI, + * the HttpClient never sends ServerName(s) that may have been configured on the + * client and instead it sends the hostname (from the request URI) as the ServerName + * for each of the request. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestResolvedHostName(final boolean sniConfiguredOnClient) throws Exception { + final SSLContext sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "could not create a SSLContext"); + final String resolvedHostName = InetAddress.getLoopbackAddress().getHostName(); + final String expectedSNI = resolvedHostName; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher, sslContext); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName("does-not-matter"))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final URI reqURI = URIBuilder.newBuilder() + .host(resolvedHostName) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates a HttpsServer configured to use the given SNIMatcher + */ + private static HttpTestServer createServer(final SNIMatcher matcher, + final SSLContext sslContext) throws Exception { + final InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + final int backlog = 0; + final HttpsServer httpsServer = HttpsServer.create(addr, backlog); + final HttpsConfigurator configurator = new HttpsConfigurator(sslContext) { + @Override + public void configure(final HttpsParameters params) { + final SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + // add the SNIMatcher + sslParameters.setSNIMatchers(List.of(matcher)); + params.setSSLParameters(sslParameters); + System.out.println("configured HttpsServer with SNIMatcher: " + matcher); + } + }; + httpsServer.setHttpsConfigurator(configurator); + final HttpTestServer server = HttpTestServer.of(httpsServer); + server.addHandler(new Handler(), "/"); + server.start(); + System.out.println("server started at " + server.getAddress()); + return server; + } +} diff --git a/test/jdk/java/net/httpclient/HttpRequestBuilderTest.java b/test/jdk/java/net/httpclient/HttpRequestBuilderTest.java index 1bb26def17d88..9401c10cdf21f 100644 --- a/test/jdk/java/net/httpclient/HttpRequestBuilderTest.java +++ b/test/jdk/java/net/httpclient/HttpRequestBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ import java.net.http.HttpClient; import java.time.Duration; import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -34,11 +37,12 @@ import static java.net.http.HttpRequest.BodyPublishers.ofString; import static java.net.http.HttpRequest.BodyPublishers.noBody; -/** +/* * @test * @bug 8170064 8276559 - * @summary HttpRequest[.Builder] API and behaviour checks + * @summary HttpRequest[.Builder] API and behaviour checks */ + public class HttpRequestBuilderTest { static final URI TEST_URI = URI.create("http://www.foo.com/"); @@ -262,13 +266,11 @@ public static void main(String[] args) throws Exception { // verify that the default HEAD() method implementation in HttpRequest.Builder // interface works as expected HttpRequest defaultHeadReq = new NotOverriddenHEADImpl().HEAD().uri(TEST_URI).build(); - String actualMethod = defaultHeadReq.method(); - if (!actualMethod.equals("HEAD")) { - throw new AssertionError("failed: expected HEAD method but got method: " + actualMethod); - } - if (defaultHeadReq.bodyPublisher().isEmpty()) { - throw new AssertionError("failed: missing bodyPublisher on HEAD request"); - } + assertEquals("HEAD", defaultHeadReq.method(), "Method"); + assertEquals(false, defaultHeadReq.bodyPublisher().isEmpty(), "Body publisher absence"); + + verifyCopy(); + } private static boolean shouldFail(Class ...exceptions) { @@ -295,13 +297,7 @@ static void method(String name, throw new AssertionError("failed: " + name + ". Unexpected body processor for GET: " + request.bodyPublisher().get()); - - if (expectedMethod.equals(method)) { - System.out.println("success: " + name); - } else { - throw new AssertionError("failed: " + name - + ". Expected " + expectedMethod + ", got " + method); - } + assertEquals(expectedMethod, method, "Method"); } static void test0(String name, @@ -378,6 +374,45 @@ public static R test2(String name, R receiver, BiFunction } } + private static void verifyCopy() { + + // Create the request builder + HttpRequest.Builder requestBuilder = HttpRequest + .newBuilder(TEST_URI) + .header("X-Foo", "1") + .method("GET", noBody()) + .expectContinue(true) + .timeout(Duration.ofSeconds(0xBEEF)) + .version(HttpClient.Version.HTTP_2); + + // Create the original and the _copy_ requests + HttpRequest request = requestBuilder.build(); + HttpRequest copiedRequest = requestBuilder + .copy() + .header("X-Foo", "2") + .header("X-Bar", "3") + .build(); + + // Verify copied _references_ + assertEquals(request.uri(), copiedRequest.uri(), "URI"); + assertEquals(request.method(), copiedRequest.method(), "Method"); + assertEquals(request.expectContinue(), copiedRequest.expectContinue(), "Expect continue setting"); + assertEquals(request.timeout(), copiedRequest.timeout(), "Timeout"); + assertEquals(request.version(), copiedRequest.version(), "Version"); + + // Verify headers + assertEquals(request.headers().map(), Map.of("X-Foo", List.of("1")), "Request headers"); + assertEquals(copiedRequest.headers().map(), Map.of("X-Foo", List.of("1", "2"), "X-Bar", List.of("3")), "Copied request headers"); + + } + + private static void assertEquals(Object expected, Object actual, Object name) { + if (!Objects.equals(expected, actual)) { + String message = String.format("%s mismatch!%nExpected: %s%nActual: %s", name, expected, actual); + throw new AssertionError(message); + } + } + // doesn't override the default HEAD() method private static final class NotOverriddenHEADImpl implements HttpRequest.Builder { private final HttpRequest.Builder underlying = HttpRequest.newBuilder(); diff --git a/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java b/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java new file mode 100644 index 0000000000000..b87e7ea8e49dd --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8328919 + * @summary tests `limiting()` in `HttpResponse.Body{Handlers,Subscribers}` + * @key randomness + * @library /test/lib + * /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.RandomFactory + * jdk.test.lib.net.SimpleSSLContext + * @run junit HttpResponseLimitingTest + */ + +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.test.lib.RandomFactory; +import jdk.test.lib.net.SimpleSSLContext; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandler; +import java.net.http.HttpResponse.BodyHandlers; +import java.net.http.HttpResponse.BodySubscriber; +import java.net.http.HttpResponse.BodySubscribers; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow.Subscription; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Arrays.copyOfRange; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class HttpResponseLimitingTest { + + private static final Random RANDOM = RandomFactory.getRandom(); + + private static final byte[] RESPONSE_BODY = "random non-empty body".getBytes(UTF_8); + + private static final String RESPONSE_HEADER_NAME = "X-Excessive-Data"; + + /** + * A header value larger than {@link #RESPONSE_BODY} to verify that {@code limiting()} doesn't affect header parsing. + */ + private static final String RESPONSE_HEADER_VALUE = "!".repeat(RESPONSE_BODY.length + 1); + + private static final ServerClientPair HTTP1 = ServerClientPair.of(HttpClient.Version.HTTP_1_1, false); + + private static final ServerClientPair HTTPS1 = ServerClientPair.of(HttpClient.Version.HTTP_1_1, true); + + private static final ServerClientPair HTTP2 = ServerClientPair.of(HttpClient.Version.HTTP_2, false); + + private static final ServerClientPair HTTPS2 = ServerClientPair.of(HttpClient.Version.HTTP_2, true); + + private record ServerClientPair(HttpTestServer server, HttpClient client, HttpRequest request) { + + private static final SSLContext SSL_CONTEXT = createSslContext(); + + private static SSLContext createSslContext() { + try { + return new SimpleSSLContext().get(); + } catch (IOException exception) { + throw new UncheckedIOException(exception); + } + } + + private ServerClientPair { + try { + server.start(); + } catch (Exception serverException) { + try { + client.close(); + } catch (Exception clientException) { + Exception localClientException = new RuntimeException("failed closing client", clientException); + serverException.addSuppressed(localClientException); + } + throw new RuntimeException("failed closing server", serverException); + } + } + + private static ServerClientPair of(HttpClient.Version version, boolean secure) { + + // Create the server and the request URI + SSLContext sslContext = secure ? SSL_CONTEXT : null; + HttpTestServer server = createServer(version, sslContext); + String handlerPath = "/"; + String requestUriScheme = secure ? "https" : "http"; + URI requestUri = URI.create(requestUriScheme + "://" + server.serverAuthority() + handlerPath); + + // Register the request handler + server.addHandler( + (exchange) -> { + exchange.getResponseHeaders().addHeader(RESPONSE_HEADER_NAME, RESPONSE_HEADER_VALUE); + exchange.sendResponseHeaders(200, RESPONSE_BODY.length); + try (var outputStream = exchange.getResponseBody()) { + outputStream.write(RESPONSE_BODY); + } + exchange.close(); + }, + handlerPath); + + // Create the client and the request + HttpClient client = createClient(version, sslContext); + HttpRequest request = HttpRequest.newBuilder(requestUri).version(version).build(); + + // Create the pair + return new ServerClientPair(server, client, request); + + } + + private static HttpTestServer createServer(HttpClient.Version version, SSLContext sslContext) { + try { + return HttpTestServer.create(version, sslContext); + } catch (IOException exception) { + throw new UncheckedIOException(exception); + } + } + + private static HttpClient createClient(HttpClient.Version version, SSLContext sslContext) { + HttpClient.Builder builder = HttpClient.newBuilder().version(version).proxy(NO_PROXY); + if (sslContext != null) { + builder.sslContext(sslContext); + } + return builder.build(); + } + + private HttpResponse request(BodyHandler downstreamHandler, long capacity) throws Exception { + var handler = BodyHandlers.limiting(downstreamHandler, capacity); + return client.send(request, handler); + } + + @Override + public String toString() { + String version = client.version().toString(); + return client.sslContext() != null ? version.replaceFirst("_", "S_") : version; + } + + } + + @AfterAll + static void closeServerClientPairs() { + Exception[] exceptionRef = {null}; + Stream + .of(HTTP1, HTTPS1, HTTP2, HTTPS2) + .flatMap(pair -> Stream.of( + pair.client::close, + pair.server::stop)) + .forEach(closer -> { + try { + closer.run(); + } catch (Exception exception) { + if (exceptionRef[0] == null) { + exceptionRef[0] = exception; + } else { + exceptionRef[0].addSuppressed(exception); + } + } + }); + if (exceptionRef[0] != null) { + throw new RuntimeException("failed closing one or more server-client pairs", exceptionRef[0]); + } + } + + @ParameterizedTest + @MethodSource("sufficientCapacities") + void testSuccessOnSufficientCapacityForByteArray(ServerClientPair pair, long sufficientCapacity) throws Exception { + HttpResponse response = pair.request(BodyHandlers.ofByteArray(), sufficientCapacity); + verifyHeaders(response.headers()); + assertArrayEquals(RESPONSE_BODY, response.body()); + } + + @ParameterizedTest + @MethodSource("sufficientCapacities") + void testSuccessOnSufficientCapacityForInputStream(ServerClientPair pair, long sufficientCapacity) throws Exception { + HttpResponse response = pair.request(BodyHandlers.ofInputStream(), sufficientCapacity); + verifyHeaders(response.headers()); + try (InputStream responseBodyStream = response.body()) { + byte[] responseBodyBuffer = responseBodyStream.readAllBytes(); + assertArrayEquals(RESPONSE_BODY, responseBodyBuffer); + } + } + + static Arguments[] sufficientCapacities() { + long minExtremeCapacity = RESPONSE_BODY.length; + long maxExtremeCapacity = Long.MAX_VALUE; + long nonExtremeCapacity = RANDOM.nextLong(minExtremeCapacity + 1, maxExtremeCapacity); + return capacityArgs(minExtremeCapacity, nonExtremeCapacity, maxExtremeCapacity); + } + + @ParameterizedTest + @MethodSource("insufficientCapacities") + void testFailureOnInsufficientCapacityForByteArray(ServerClientPair pair, long insufficientCapacity) { + BodyHandler handler = responseInfo -> { + verifyHeaders(responseInfo.headers()); + return BodySubscribers.limiting(BodySubscribers.ofByteArray(), insufficientCapacity); + }; + var exception = assertThrows(IOException.class, () -> pair.request(handler, insufficientCapacity)); + assertEquals(exception.getMessage(), "body exceeds capacity: " + insufficientCapacity); + } + + @ParameterizedTest + @MethodSource("insufficientCapacities") + void testFailureOnInsufficientCapacityForInputStream(ServerClientPair pair, long insufficientCapacity) throws Exception { + HttpResponse response = pair.request(BodyHandlers.ofInputStream(), insufficientCapacity); + verifyHeaders(response.headers()); + try (InputStream responseBodyStream = response.body()) { + var exception = assertThrows(IOException.class, responseBodyStream::readAllBytes); + assertNotNull(exception.getCause()); + assertEquals(exception.getCause().getMessage(), "body exceeds capacity: " + insufficientCapacity); + } + } + + static Arguments[] insufficientCapacities() { + long minExtremeCapacity = 0; + long maxExtremeCapacity = RESPONSE_BODY.length - 1; + long nonExtremeCapacity = RANDOM.nextLong(minExtremeCapacity + 1, maxExtremeCapacity); + return capacityArgs(minExtremeCapacity, nonExtremeCapacity, maxExtremeCapacity); + } + + private static void verifyHeaders(HttpHeaders responseHeaders) { + List responseHeaderValues = responseHeaders.allValues(RESPONSE_HEADER_NAME); + assertEquals(List.of(RESPONSE_HEADER_VALUE), responseHeaderValues); + } + + @ParameterizedTest + @MethodSource("invalidCapacities") + void testFailureOnInvalidCapacityForHandler(long invalidCapacity) { + var exception = assertThrows( + IllegalArgumentException.class, + () -> BodyHandlers.limiting(BodyHandlers.ofByteArray(), invalidCapacity)); + assertEquals(exception.getMessage(), "capacity must not be negative: " + invalidCapacity); + } + + @ParameterizedTest + @MethodSource("invalidCapacities") + void testFailureOnInvalidCapacityForSubscriber(long invalidCapacity) { + var exception = assertThrows( + IllegalArgumentException.class, + () -> BodySubscribers.limiting(BodySubscribers.ofByteArray(), invalidCapacity)); + assertEquals(exception.getMessage(), "capacity must not be negative: " + invalidCapacity); + } + + static long[] invalidCapacities() { + long minExtremeCapacity = Long.MIN_VALUE; + long maxExtremeCapacity = -1; + long nonExtremeCapacity = RANDOM.nextLong(minExtremeCapacity + 1, maxExtremeCapacity); + return new long[]{minExtremeCapacity, nonExtremeCapacity, maxExtremeCapacity}; + } + + @Test + void testFailureOnNullDownstreamHandler() { + var exception = assertThrows(NullPointerException.class, () -> BodyHandlers.limiting(null, 0)); + assertEquals(exception.getMessage(), "downstreamHandler"); + } + + @Test + void testFailureOnNullDownstreamSubscriber() { + var exception = assertThrows(NullPointerException.class, () -> BodySubscribers.limiting(null, 0)); + assertEquals(exception.getMessage(), "downstreamSubscriber"); + } + + private static Arguments[] capacityArgs(long... capacities) { + return Stream + .of(HTTP1, HTTPS1, HTTP2, HTTPS2) + .flatMap(pair -> Arrays + .stream(capacities) + .mapToObj(capacity -> Arguments.of(pair, capacity))) + .toArray(Arguments[]::new); + } + + @Test + void testSubscriberForCompleteConsumption() { + + // Create the subscriber (with sufficient capacity) + ObserverSubscriber downstreamSubscriber = new ObserverSubscriber(); + int sufficientCapacity = RESPONSE_BODY.length; + BodySubscriber subscriber = BodySubscribers.limiting(downstreamSubscriber, sufficientCapacity); + + // Emit values + subscriber.onSubscribe(DummySubscription.INSTANCE); + byte[] responseBodyPart1 = {RESPONSE_BODY[0]}; + byte[] responseBodyPart2 = copyOfRange(RESPONSE_BODY, 1, RESPONSE_BODY.length); + List buffers = toByteBuffers(responseBodyPart1, responseBodyPart2); + subscriber.onNext(buffers); + + // Verify the downstream propagation + assertSame(buffers, downstreamSubscriber.lastBuffers); + assertNull(downstreamSubscriber.lastThrowable); + assertFalse(downstreamSubscriber.completed); + + } + + @Test + void testSubscriberForFailureOnExcess() { + + // Create the subscriber (with insufficient capacity) + ObserverSubscriber downstreamSubscriber = new ObserverSubscriber(); + int insufficientCapacity = 2; + BodySubscriber subscriber = BodySubscribers.limiting(downstreamSubscriber, insufficientCapacity); + + // Emit values + subscriber.onSubscribe(DummySubscription.INSTANCE); + byte[] responseBodyPart1 = {RESPONSE_BODY[0]}; + byte[] responseBodyPart2 = copyOfRange(RESPONSE_BODY, 1, RESPONSE_BODY.length); + List buffers = toByteBuffers(responseBodyPart1, responseBodyPart2); + subscriber.onNext(buffers); + + // Verify the downstream propagation + assertNull(downstreamSubscriber.lastBuffers); + assertNotNull(downstreamSubscriber.lastThrowable); + assertEquals( + "body exceeds capacity: " + insufficientCapacity, + downstreamSubscriber.lastThrowable.getMessage()); + assertFalse(downstreamSubscriber.completed); + + } + + private static List toByteBuffers(byte[]... buffers) { + return Arrays.stream(buffers).map(ByteBuffer::wrap).collect(Collectors.toList()); + } + + private static final class ObserverSubscriber implements BodySubscriber { + + private List lastBuffers; + + private Throwable lastThrowable; + + private boolean completed; + + @Override + public CompletionStage getBody() { + throw new UnsupportedOperationException(); + } + + @Override + public void onSubscribe(Subscription subscription) { + subscription.request(Long.MAX_VALUE); + } + + @Override + public void onNext(List buffers) { + lastBuffers = buffers; + } + + @Override + public void onError(Throwable throwable) { + lastThrowable = throwable; + } + + @Override + public void onComplete() { + completed = true; + } + + } + + private enum DummySubscription implements Subscription { + + INSTANCE; + + @Override + public void request(long n) { + // Do nothing + } + + @Override + public void cancel() { + // Do nothing + } + + } + +} diff --git a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java index f83118adea3f6..83961453f05f1 100644 --- a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java +++ b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,6 +108,7 @@ public class HttpsTunnelAuthTest implements HttpServerAdapters, AutoCloseable { } void setUp() throws IOException { + HttpServerAdapters.enableServerLogging(); // Creates an HTTP/1.1 Server that will authenticate for // arthur with password dent http1Server = DigestEchoServer.createServer(Version.HTTP_1_1, @@ -143,10 +144,8 @@ void setUp() throws IOException { // Creates a proxy selector that unconditionally select the // above proxy. - var ps = proxySelector = ProxySelector.of(proxy.getProxyAddress()); + proxySelector = ProxySelector.of(proxy.getProxyAddress()); - // Creates a client that uses the above proxy selector - client = newHttpClient(ps); } @Override @@ -177,23 +176,26 @@ public static void main(String[] args) throws Exception { try (HttpsTunnelAuthTest test = new HttpsTunnelAuthTest()) { test.setUp(); - // tests proxy and server authentication through: - // - plain proxy connection to plain HTTP/1.1 server, - test.test(Version.HTTP_1_1, "http", "/foo/http1"); + try (HttpClient client = test.newHttpClient(test.proxySelector)) { + // tests proxy and server authentication through: + // - plain proxy connection to plain HTTP/1.1 server, + test.test(client, Version.HTTP_1_1, "http", "/foo/http1"); + } // can't really test plain proxy connection to plain HTTP/2 server: // this is not supported: we downgrade to HTTP/1.1 in that case // so that is actually somewhat equivalent to the first case: // therefore we will use a new client to force re-authentication // of the proxy connection. - test.client = test.newHttpClient(test.proxySelector); - test.test(Version.HTTP_2, "http", "/foo/http2"); + try (HttpClient client = test.newHttpClient(test.proxySelector)) { + test.test(client, Version.HTTP_2, "http", "/foo/http2"); - // - proxy tunnel SSL connection to HTTP/1.1 server - test.test(Version.HTTP_1_1, "https", "/foo/https1"); + // - proxy tunnel SSL connection to HTTP/1.1 server + test.test(client, Version.HTTP_1_1, "https", "/foo/https1"); - // - proxy tunnel SSl connection to HTTP/2 server - test.test(Version.HTTP_2, "https", "/foo/https2"); + // - proxy tunnel SSl connection to HTTP/2 server + test.test(client, Version.HTTP_2, "https", "/foo/https2"); + } } } @@ -227,14 +229,14 @@ Version expectedVersion(String scheme, Version version) { return "http".equals(scheme) ? Version.HTTP_1_1 : version; } - public void test(Version version, String scheme, String path) throws Exception { + public void test(HttpClient client, Version version, String scheme, String path) throws Exception { System.out.printf("%nTesting %s, %s, %s%n", version, scheme, path); DigestEchoServer server = server(scheme, version); try { URI uri = jdk.test.lib.net.URIBuilder.newBuilder() .scheme(scheme) - .host("localhost") + .loopback() .port(server.getServerAddress().getPort()) .path(path).build(); diff --git a/test/jdk/java/net/httpclient/RedirectMethodChange.java b/test/jdk/java/net/httpclient/RedirectMethodChange.java index 7e5971c40022e..ed1afb384e10b 100644 --- a/test/jdk/java/net/httpclient/RedirectMethodChange.java +++ b/test/jdk/java/net/httpclient/RedirectMethodChange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -220,6 +220,7 @@ public void setup() throws Exception { @AfterTest public void teardown() throws Exception { + client.close(); httpTestServer.stop(); httpsTestServer.stop(); http2TestServer.stop(); @@ -240,8 +241,8 @@ public void teardown() throws Exception { */ static class RedirMethodChgeHandler implements HttpTestHandler { - boolean inTest; - String expectedMethod; + volatile boolean inTest; + volatile String expectedMethod; final String targetURL; RedirMethodChgeHandler(String targetURL) { @@ -272,11 +273,14 @@ public synchronized void handle(HttpTestExchange he) throws IOException { Throwable ex = new RuntimeException("Unexpected newtest:" + newtest + ", inTest:" + inTest + ", for " + he.getRequestURI()); ex.printStackTrace(); + inTest = false; // next request should be new test he.sendResponseHeaders(500, 0); return; } if (newtest) { + // set inTest before sending responses + inTest = true; HttpTestRequestHeaders hdrs = he.getRequestHeaders(); String value = hdrs.firstValue("X-Redirect-Code").get(); int redirectCode = Integer.parseInt(value); @@ -286,8 +290,9 @@ public synchronized void handle(HttpTestExchange he) throws IOException { HttpTestResponseHeaders headersbuilder = he.getResponseHeaders(); headersbuilder.addHeader("Location", targetURL); he.sendResponseHeaders(redirectCode, 0); - inTest = true; } else { + // set inTest before sending responses + inTest = false; // should be the redirect if (!he.getRequestURI().getPath().endsWith("/redirect/rmt")) { Throwable ex = new RuntimeException("Unexpected redirected request, got:" @@ -307,7 +312,6 @@ public synchronized void handle(HttpTestExchange he) throws IOException { os.write(RESPONSE.getBytes(US_ASCII)); } } - inTest = false; } } } diff --git a/test/jdk/java/net/httpclient/ShortRequestBody.java b/test/jdk/java/net/httpclient/ShortRequestBody.java index 0bdb395003958..ffebdeec5ce01 100644 --- a/test/jdk/java/net/httpclient/ShortRequestBody.java +++ b/test/jdk/java/net/httpclient/ShortRequestBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,6 +176,23 @@ static void success(Supplier clientSupplier, "Expected 200, got ", resp.statusCode()); } + static void checkCause(Throwable cause) { + Throwable t = cause; + boolean found = false; + while (t != null && !found) { + check(t instanceof IOException, t, + "Expected cause IOException, but got: ", t); + String msg = t.getMessage(); + found = (msg != null && (msg.contains("Too many") || msg.contains("Too few"))); + t = t.getCause(); + } + if (!found) { + String msg = cause.getMessage(); + check(msg.contains("Too many") || msg.contains("Too few"), + cause, "Expected Too many|Too few, got: ", cause); + } + } + static void failureNonBlocking(Supplier clientSupplier, URI uri, HttpRequest.BodyPublisher publisher) @@ -194,12 +211,7 @@ static void failureNonBlocking(Supplier clientSupplier, throw new RuntimeException("Unexpected timeout", x); } catch (ExecutionException expected) { err.println("Caught expected: " + expected); - Throwable t = expected.getCause(); - check(t instanceof IOException, t, - "Expected cause IOException, but got: ", t); - String msg = t.getMessage(); - check(msg.contains("Too many") || msg.contains("Too few"), - t, "Expected Too many|Too few, got: ", t); + checkCause(expected.getCause()); } } @@ -219,9 +231,7 @@ static void failureBlocking(Supplier clientSupplier, throw new RuntimeException("Unexpected timeout", x); } catch (IOException expected) { err.println("Caught expected: " + expected); - String msg = expected.getMessage(); - check(msg.contains("Too many") || msg.contains("Too few"), - expected,"Expected Too many|Too few, got: ", expected); + checkCause(expected); } } diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimiting.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimiting.java new file mode 100644 index 0000000000000..11ced214ece99 --- /dev/null +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimiting.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verifies the behavior of `limiting()` on unexpected exceptions + * thrown at various places (`onSubscriber()`, `onNext()`, etc.) when + * the request is performed _synchronously_ using `HttpClient::send`. + * Even though throwing exceptions at such points is against the + * Reactive Streams contract, we make sure that `HttpClient` gets its + * resources released on such misbehaving user code. + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build AbstractThrowingSubscribers + * ReferenceTracker + * jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsLimiting + */ + +import org.testng.annotations.Test; + +import java.net.http.HttpResponse; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class ThrowingSubscribersAsLimiting extends AbstractThrowingSubscribers { + + @Test(dataProvider = "variants") + public void test(String uri, boolean sameClient, Thrower thrower) throws Exception { + test(uri, sameClient, thrower, false); + } + + void test(String uri, boolean sameClient, Thrower thrower, boolean async) throws Exception { + uri = uri + "-" + URICOUNT.incrementAndGet(); + String name = String.format( + "testThrowingAsLimiting%s(%s, %b, %s)", + (async ? "Async" : ""), uri, sameClient, thrower); + Supplier>> handlerSupplier = + () -> HttpResponse.BodyHandlers.limiting( + HttpResponse.BodyHandlers.ofLines(), + Long.MAX_VALUE); + testThrowing( + name, + uri, + sameClient, + handlerSupplier, + this::finish, + thrower, + async, + excludes(SubscriberType.OFFLINE)); + } + + private Void finish(Where where, HttpResponse> response, Thrower thrower) { + switch (where) { + case BODY_HANDLER: + case GET_BODY: + case BODY_CF: + return shouldHaveThrown(where, response, thrower); + } + try { + // noinspection ResultOfMethodCallIgnored + response.body().toList(); + } catch (Error | Exception throwable) { + Throwable cause = findCause(throwable, thrower); + if (cause != null) { + System.out.println(now() + "Got expected exception in " + where + ": " + cause); + return null; + } + throw causeNotFound(where, throwable); + } + return shouldHaveThrown(where, response, thrower); + } + +} diff --git a/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimitingAsync.java b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimitingAsync.java new file mode 100644 index 0000000000000..00e00c12db53d --- /dev/null +++ b/test/jdk/java/net/httpclient/ThrowingSubscribersAsLimitingAsync.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verifies the behavior of `limiting()` on unexpected exceptions + * thrown at various places (`onSubscriber()`, `onNext()`, etc.) when + * the request is performed _asynchronously_ using `HttpClient::sendAsync`. + * Even though throwing exceptions at such points is against the + * Reactive Streams contract, we make sure that `HttpClient` gets its + * resources released on such misbehaving user code. + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build AbstractThrowingSubscribers + * ReferenceTracker + * jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingSubscribersAsLimitingAsync + */ + +import org.testng.annotations.Test; + +public class ThrowingSubscribersAsLimitingAsync extends ThrowingSubscribersAsLimiting { + + @Override + @Test(dataProvider = "variants") + public void test(String uri, boolean sameClient, Thrower thrower) throws Exception { + test(uri, sameClient, thrower, true); + } + +} diff --git a/test/jdk/java/net/httpclient/http2/BasicTest.java b/test/jdk/java/net/httpclient/http2/BasicTest.java index 39cad481749d0..9d54c8c39e0ba 100644 --- a/test/jdk/java/net/httpclient/http2/BasicTest.java +++ b/test/jdk/java/net/httpclient/http2/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,14 @@ /* * @test * @bug 8087112 - * @library /test/lib /test/jdk/java/net/httpclient/lib - * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestUtil - * jdk.httpclient.test.lib.http2.Http2TestServer + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2TestExchange + * jdk.httpclient.test.lib.http2.Http2EchoHandler + * jdk.test.lib.Asserts + * jdk.test.lib.Utils + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors BasicTest */ @@ -44,17 +49,23 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import jdk.httpclient.test.lib.common.TestUtil; import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.httpclient.test.lib.http2.Http2TestExchange; -import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.httpclient.test.lib.http2.Http2EchoHandler; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.Test; + import static java.net.http.HttpClient.Version.HTTP_2; +import static jdk.test.lib.Asserts.assertFileContentsEqual; +import static jdk.test.lib.Utils.createTempFile; +import static jdk.test.lib.Utils.createTempFileOfSize; @Test public class BasicTest { + + private static final String TEMP_FILE_PREFIX = + HttpClient.class.getPackageName() + '-' + BasicTest.class.getSimpleName() + '-'; + static int httpPort, httpsPort; static Http2TestServer httpServer, httpsServer; static HttpClient client = null; @@ -184,14 +195,6 @@ static void checkStrings(String expected, String found) throws Exception { } } - static Void compareFiles(Path path1, Path path2) { - return TestUtil.compareFiles(path1, path2); - } - - static Path tempFile() { - return TestUtil.tempFile(); - } - static final String SIMPLE_STRING = "Hello world Goodbye world"; static final int LOOPS = 13; @@ -202,7 +205,7 @@ static void streamTest(boolean secure) throws Exception { System.err.printf("streamTest %b to %s\n" , secure, uri); HttpClient client = getClient(); - Path src = TestUtil.getAFile(FILESIZE * 4); + Path src = createTempFileOfSize(TEMP_FILE_PREFIX, null, FILESIZE * 4); HttpRequest req = HttpRequest.newBuilder(uri) .POST(BodyPublishers.ofFile(src)) .build(); @@ -216,7 +219,7 @@ static void streamTest(boolean secure) throws Exception { return resp.body(); }); response.join(); - compareFiles(src, dest); + assertFileContentsEqual(src, dest); System.err.println("streamTest: DONE"); } @@ -269,17 +272,19 @@ static void simpleTest(boolean secure, boolean ping) throws Exception { // Do loops asynchronously CompletableFuture[] responses = new CompletableFuture[LOOPS]; - final Path source = TestUtil.getAFile(FILESIZE); + final Path source = createTempFileOfSize(TEMP_FILE_PREFIX, null, FILESIZE); HttpRequest request = HttpRequest.newBuilder(uri) .POST(BodyPublishers.ofFile(source)) .build(); for (int i = 0; i < LOOPS; i++) { - responses[i] = client.sendAsync(request, BodyHandlers.ofFile(tempFile())) + responses[i] = client.sendAsync(request, BodyHandlers.ofFile(createTempFile(TEMP_FILE_PREFIX, null))) //.thenApply(resp -> compareFiles(resp.body(), source)); .thenApply(resp -> { + Path body = resp.body(); System.out.printf("Resp status %d body size %d\n", - resp.statusCode(), resp.body().toFile().length()); - return compareFiles(resp.body(), source); + resp.statusCode(), body.toFile().length()); + assertFileContentsEqual(body, source); + return null; }); Thread.sleep(100); } diff --git a/test/jdk/java/net/httpclient/http2/ExpectContinueResetTest.java b/test/jdk/java/net/httpclient/http2/ExpectContinueResetTest.java index 68012208281da..5d09c01b96fc8 100644 --- a/test/jdk/java/net/httpclient/http2/ExpectContinueResetTest.java +++ b/test/jdk/java/net/httpclient/http2/ExpectContinueResetTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,6 +73,7 @@ public class ExpectContinueResetTest { URI warmup, partialResponseResetNoError, partialResponseResetError, fullResponseResetNoError, fullResponseResetError; static PrintStream err = new PrintStream(System.err); + static PrintStream out = System.out; @DataProvider(name = "testData") public Object[][] testData() { @@ -88,17 +89,24 @@ public Object[][] testData() { @Test(dataProvider = "testData") public void test(URI uri) { + out.printf("\nTesting with Version: %s, URI: %s\n", HTTP_2, uri.toASCIIString()); err.printf("\nTesting with Version: %s, URI: %s\n", HTTP_2, uri.toASCIIString()); Iterable iterable = EndlessDataChunks::new; HttpRequest.BodyPublisher testPub = HttpRequest.BodyPublishers.ofByteArrays(iterable); - Throwable testThrowable = null; + Exception expectedException = null; try { performRequest(testPub, uri); + throw new AssertionError("Expected exception not raised for " + uri); } catch (Exception e) { - testThrowable = e.getCause(); + expectedException = e; } - assertNotNull(testThrowable, "Request should have completed exceptionally but testThrowable is null"); - assertEquals(testThrowable.getClass(), IOException.class, "Test should have closed with an IOException"); + Throwable testThrowable = expectedException.getCause(); + if (testThrowable == null) { + throw new AssertionError("Unexpected null cause for " + expectedException, + expectedException); + } + assertEquals(testThrowable.getClass(), IOException.class, + "Test should have closed with an IOException"); testThrowable.printStackTrace(); } @@ -177,7 +185,7 @@ static class NoEndStreamOnPartialResponse implements Http2Handler { @Override public void handle(Http2TestExchange exchange) throws IOException { err.println("Sending 100"); - exchange.sendResponseHeaders(100, 0); + exchange.sendResponseHeaders(100, -1); if (exchange instanceof ExpectContinueResetTestExchangeImpl testExchange) { err.println("Sending Reset"); err.println(exchange.getRequestURI().getPath()); @@ -197,8 +205,9 @@ static class NoEndStreamOnFullResponse implements Http2Handler { @Override public void handle(Http2TestExchange exchange) throws IOException { err.println("Sending 100"); - exchange.sendResponseHeaders(100, 0); + exchange.sendResponseHeaders(100, -1); err.println("Sending 200"); + exchange.sendResponseHeaders(200, 0); if (exchange instanceof ExpectContinueResetTestExchangeImpl testExchange) { err.println("Sending Reset"); diff --git a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java index cef7bf7df65d4..68cfe826a0ecb 100644 --- a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java +++ b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,13 @@ /* * @test * @bug 8087112 8177935 - * @library /test/lib /test/jdk/java/net/httpclient/lib - * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.TestUtil - * jdk.httpclient.test.lib.http2.Http2TestServer + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.Http2EchoHandler + * jdk.test.lib.Asserts + * jdk.test.lib.Utils + * jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -Djdk.httpclient.HttpClient.log=ssl,requests,responses,errors FixedThreadPoolTest */ @@ -37,16 +41,23 @@ import javax.net.ssl.*; import java.nio.file.*; import java.util.concurrent.*; -import jdk.httpclient.test.lib.common.TestUtil; import jdk.httpclient.test.lib.http2.Http2TestServer; -import jdk.httpclient.test.lib.http2.Http2TestExchange; import jdk.httpclient.test.lib.http2.Http2EchoHandler; import jdk.test.lib.net.SimpleSSLContext; + import static java.net.http.HttpClient.Version.HTTP_2; +import static jdk.test.lib.Asserts.assertFileContentsEqual; +import static jdk.test.lib.Utils.createTempFile; +import static jdk.test.lib.Utils.createTempFileOfSize; + import org.testng.annotations.Test; @Test public class FixedThreadPoolTest { + + private static final String TEMP_FILE_PREFIX = + HttpClient.class.getPackageName() + '-' + FixedThreadPoolTest.class.getSimpleName() + '-'; + static int httpPort, httpsPort; static Http2TestServer httpServer, httpsServer; static HttpClient client = null; @@ -142,14 +153,6 @@ static void checkStrings(String expected, String found) throws Exception { } } - static Void compareFiles(Path path1, Path path2) { - return TestUtil.compareFiles(path1, path2); - } - - static Path tempFile() { - return TestUtil.tempFile(); - } - static final String SIMPLE_STRING = "Hello world Goodbye world"; static final int LOOPS = 32; @@ -160,7 +163,7 @@ static void streamTest(boolean secure) throws Exception { System.err.printf("streamTest %b to %s\n" , secure, uri); HttpClient client = getClient(); - Path src = TestUtil.getAFile(FILESIZE * 4); + Path src = createTempFileOfSize(TEMP_FILE_PREFIX, null, FILESIZE * 4); HttpRequest req = HttpRequest.newBuilder(uri) .POST(BodyPublishers.ofFile(src)) .build(); @@ -174,7 +177,7 @@ static void streamTest(boolean secure) throws Exception { return resp.body(); }); response.join(); - compareFiles(src, dest); + assertFileContentsEqual(src, dest); System.err.println("DONE"); } @@ -239,17 +242,19 @@ static void simpleTest(boolean secure) throws Exception { // Do loops asynchronously CompletableFuture[] responses = new CompletableFuture[LOOPS]; - final Path source = TestUtil.getAFile(FILESIZE); + final Path source = createTempFileOfSize(TEMP_FILE_PREFIX, null, FILESIZE); HttpRequest request = HttpRequest.newBuilder(uri) .POST(BodyPublishers.ofFile(source)) .build(); for (int i = 0; i < LOOPS; i++) { - responses[i] = client.sendAsync(request, BodyHandlers.ofFile(tempFile())) + responses[i] = client.sendAsync(request, BodyHandlers.ofFile(createTempFile(TEMP_FILE_PREFIX, null))) //.thenApply(resp -> compareFiles(resp.body(), source)); .thenApply(resp -> { + Path body = resp.body(); System.out.printf("Resp status %d body size %d\n", - resp.statusCode(), resp.body().toFile().length()); - return compareFiles(resp.body(), source); + resp.statusCode(), body.toFile().length()); + assertFileContentsEqual(body, source); + return null; }); } CompletableFuture.allOf(responses).join(); diff --git a/test/jdk/java/net/httpclient/http2/ServerPush.java b/test/jdk/java/net/httpclient/http2/ServerPush.java index 60958dce6967b..7f9c82fb28b22 100644 --- a/test/jdk/java/net/httpclient/http2/ServerPush.java +++ b/test/jdk/java/net/httpclient/http2/ServerPush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,11 @@ /* * @test * @bug 8087112 8159814 - * @library /test/lib /test/jdk/java/net/httpclient/lib - * @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.http2.Http2TestServer - * jdk.httpclient.test.lib.common.TestUtil jdk.httpclient.test.lib.http2.PushHandler + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build jdk.httpclient.test.lib.http2.Http2TestServer + * jdk.httpclient.test.lib.http2.PushHandler + * jdk.test.lib.Utils * @run testng/othervm * -Djdk.httpclient.HttpClient.log=errors,requests,responses * ServerPush @@ -44,19 +46,21 @@ import java.util.*; import java.util.concurrent.*; import java.util.function.Consumer; -import jdk.httpclient.test.lib.common.TestUtil; import jdk.httpclient.test.lib.http2.Http2TestServer; -import jdk.httpclient.test.lib.http2.Http2TestExchange; -import jdk.httpclient.test.lib.http2.Http2Handler; import jdk.httpclient.test.lib.http2.PushHandler; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; + import static java.nio.charset.StandardCharsets.UTF_8; +import static jdk.test.lib.Utils.createTempFileOfSize; import static org.testng.Assert.*; public class ServerPush { + private static final String TEMP_FILE_PREFIX = + HttpClient.class.getPackageName() + '-' + ServerPush.class.getSimpleName() + '-'; + static final int LOOPS = 13; static final int FILE_SIZE = 512 * 1024 + 343; @@ -67,7 +71,7 @@ public class ServerPush { @BeforeTest public void setup() throws Exception { - tempFile = TestUtil.getAFile(FILE_SIZE); + tempFile = createTempFileOfSize(TEMP_FILE_PREFIX, null, FILE_SIZE); server = new Http2TestServer(false, 0); server.addHandler(new PushHandler(tempFile, LOOPS), "/"); System.out.println("Using temp file:" + tempFile); diff --git a/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java b/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java index 39768b68dc564..31cc58df2a8e3 100644 --- a/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java +++ b/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.ProtocolException; import java.net.URI; @@ -335,7 +336,9 @@ public void handle(Http2TestExchange t) throws IOException { // to wait for the connection window fct.conn.obtainConnectionWindow(resp.length); } catch (InterruptedException ie) { - // ignore and continue... + var ioe = new InterruptedIOException(ie.toString()); + ioe.initCause(ie); + throw ioe; } } try { @@ -344,6 +347,7 @@ public void handle(Http2TestExchange t) throws IOException { if (t instanceof FCHttp2TestExchange fct) { fct.conn.updateConnectionWindow(resp.length); } + throw x; } } } finally { diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java index 4b00c0eea7bfd..6dc945231abb7 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/HttpServerAdapters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -239,7 +239,7 @@ public static abstract class HttpTestExchange implements AutoCloseable { public abstract OutputStream getResponseBody(); public abstract HttpTestRequestHeaders getRequestHeaders(); public abstract HttpTestResponseHeaders getResponseHeaders(); - public abstract void sendResponseHeaders(int code, int contentLength) throws IOException; + public abstract void sendResponseHeaders(int code, long contentLength) throws IOException; public abstract URI getRequestURI(); public abstract String getRequestMethod(); public abstract void close(); @@ -292,7 +292,7 @@ public HttpTestResponseHeaders getResponseHeaders() { return HttpTestResponseHeaders.of(exchange.getResponseHeaders()); } @Override - public void sendResponseHeaders(int code, int contentLength) throws IOException { + public void sendResponseHeaders(int code, long contentLength) throws IOException { if (contentLength == 0) contentLength = -1; else if (contentLength < 0) contentLength = 0; exchange.sendResponseHeaders(code, contentLength); @@ -355,7 +355,7 @@ public HttpTestResponseHeaders getResponseHeaders() { return HttpTestResponseHeaders.of(exchange.getResponseHeaders()); } @Override - public void sendResponseHeaders(int code, int contentLength) throws IOException { + public void sendResponseHeaders(int code, long contentLength) throws IOException { if (contentLength == 0) contentLength = -1; else if (contentLength < 0) contentLength = 0; exchange.sendResponseHeaders(code, contentLength); diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java index 5e7a5790807ae..47353927e9cf2 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java @@ -58,6 +58,7 @@ public class ServerNameMatcher extends SNIMatcher { private final Logger debug; private final boolean attemptDNSResolution; private final Set recognizedSNINames; + private volatile boolean invoked; /** * Creates a ServerNameMatcher which recognizes the passed {@code recognizedSNIName} @@ -97,6 +98,7 @@ public ServerNameMatcher(final boolean attemptDNSResolution, */ @Override public boolean matches(final SNIServerName clientRequestedSNI) { + this.invoked = true; Objects.requireNonNull(clientRequestedSNI); if (!SNIHostName.class.isInstance(clientRequestedSNI)) { if (debug.on()) { @@ -128,6 +130,14 @@ public boolean matches(final SNIServerName clientRequestedSNI) { return false; } + /** + * @return true if the {@link #matches(SNIServerName)} method of this SNIMatcher instance + * was invoked at least once, false otherwise. + */ + public boolean wasInvoked() { + return this.invoked; + } + private boolean matchesAfterDNSResolution(final String clientRequestedSNI) { final InetAddress clientRequestedAddr; try { diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java deleted file mode 100644 index 2b2dacff57b29..0000000000000 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestUtil.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.httpclient.test.lib.common; - -import java.io.*; -import java.nio.file.*; -import java.util.Arrays; - -public class TestUtil { - - static final Path CWD = Paths.get("."); - final static String fileContent = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // repeated - - public static Path getAFile(int size) throws IOException { - Path p = tempFile(); - BufferedWriter writer = Files.newBufferedWriter(p); - int len = fileContent.length(); - int iterations = size / len; - int remainder = size - (iterations * len); - for (int i=0; i 0) { - int n = Math.min(demand, window); - demand -= n; - window -= n; - if (demand > 0) { - wait(); + public void waitForStreamWindow(int amount) throws InterruptedException { + int demand = amount; + try { + synchronized (this) { + while (amount > 0) { + int n = Math.min(amount, window); + amount -= n; + window -= n; + if (amount > 0) { + wait(); + } } } + } catch (Throwable t) { + window += (demand - amount); + throw t; } } diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java index fb0ce92cd1da3..deec3ec2c24de 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/http2/Http2TestServerConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -171,7 +171,7 @@ void fail(Throwable t) { Properties properties) throws IOException { - System.err.println("TestServer: New connection from " + socket); + System.err.println(server.name + ": New connection from " + socket); if (socket instanceof SSLSocket) { SSLSocket sslSocket = (SSLSocket)socket; @@ -218,10 +218,10 @@ private SettingsFrame getServerSettingProperties() { String prop = properties.getProperty(propPrefix + key); if (prop != null) { try { - System.err.println("TestServer: setting " + key + " property to: " + + System.err.println(server.name + ": setting " + key + " property to: " + prop); int num = Integer.parseInt(numS); - System.err.println("TestServer: num = " + num); + System.err.println(server.name + ": num = " + num); s.setParameter(num, Integer.parseInt(prop)); } catch (NumberFormatException e) {/* ignore errors */} } @@ -269,7 +269,7 @@ private void sendGoAway(final int error) throws IOException { } final GoAwayFrame frame = new GoAwayFrame(maxProcessedStreamId, error); outputQ.put(frame); - System.err.println("Sending GOAWAY frame " + frame + " from server connection " + this); + System.err.println(server.name + ": Sending GOAWAY frame " + frame + " from server connection " + this); } /** @@ -285,7 +285,7 @@ private PingRequest getNextRequest() { */ void handlePing(PingFrame ping) throws IOException { if (ping.streamid() != 0) { - System.err.println("Invalid ping received"); + System.err.println(server.name + ": Invalid ping received"); close(ErrorFrame.PROTOCOL_ERROR); return; } @@ -293,7 +293,7 @@ void handlePing(PingFrame ping) throws IOException { // did we send a Ping? PingRequest request = getNextRequest(); if (request == null) { - System.err.println("Invalid ping ACK received"); + System.err.println(server.name + ": Invalid ping ACK received"); close(ErrorFrame.PROTOCOL_ERROR); return; } else if (!Arrays.equals(request.pingData, ping.getData())) { @@ -356,7 +356,7 @@ void close(int error) { if (stopping) return; stopping = true; - System.err.printf("Server connection to %s stopping. %d streams\n", + System.err.printf(server.name + ": Server connection to %s stopping. %d streams\n", socket.getRemoteSocketAddress().toString(), streams.size()); streams.forEach((i, q) -> { q.orderlyClose(); @@ -376,16 +376,20 @@ private void readPreface() throws IOException { byte[] bytes = new byte[len]; int n = is.readNBytes(bytes, 0, len); if (Arrays.compare(clientPreface, bytes) != 0) { - System.err.printf("Invalid preface: read %d/%d bytes%n", n, len); - throw new IOException("Invalid preface: " + - new String(bytes, 0, len, ISO_8859_1)); + String msg = String.format("Invalid preface: read %s/%s bytes", n, len); + System.err.println(server.name + ": " + msg); + throw new IOException(msg +": \"" + + new String(bytes, 0, n, ISO_8859_1) + .replace("\r", "\\r") + .replace("\n", "\\n") + + "\""); } } Http1InitialRequest doUpgrade(Http1InitialRequest upgrade) throws IOException { String h2c = getHeader(upgrade.headers, "Upgrade"); if (h2c == null || !h2c.equals("h2c")) { - System.err.println("Server:HEADERS: " + upgrade); + System.err.println(server.name + ":HEADERS: " + upgrade); throw new IOException("Bad upgrade 1 " + h2c); } @@ -457,7 +461,7 @@ void run() throws Exception { socket.close(); return; } else { - System.err.println("Server:HEADERS: " + upgrade); + System.err.println(server.name + ":HEADERS: " + upgrade); throw new IOException("Bad upgrade 1 " + h2c); } } @@ -556,7 +560,7 @@ private void handleCommonFrame(Http2Frame f) throws IOException { outputQ.put(frame); return; } else if (f instanceof GoAwayFrame) { - System.err.println("Closing: "+ f.toString()); + System.err.println(server.name + ": Closing connection: "+ f.toString()); close(ErrorFrame.NO_ERROR); } else if (f instanceof PingFrame) { handlePing((PingFrame)f); @@ -649,7 +653,7 @@ void createPrimordialStream(Http1InitialRequest request) throws IOException { // skip processing the request if configured to do so final String connKey = connectionKey(); if (!shouldProcessNewHTTPRequest(connKey)) { - System.err.println("Rejecting primordial stream 1 and sending GOAWAY" + + System.err.println(server.name + ": Rejecting primordial stream 1 and sending GOAWAY" + " on server connection " + connKey + ", for request: " + path); sendGoAway(ErrorFrame.NO_ERROR); return; @@ -726,7 +730,7 @@ void createStream(HeaderFrame frame) throws IOException { final String connKey = connectionKey(); final String path = headers.firstValue(":path").orElse(""); if (!shouldProcessNewHTTPRequest(connKey)) { - System.err.println("Rejecting stream " + streamid + System.err.println(server.name + ": Rejecting stream " + streamid + " and sending GOAWAY on server connection " + connKey + ", for request: " + path); sendGoAway(ErrorFrame.NO_ERROR); @@ -764,17 +768,17 @@ void handleRequest(HttpHeaders headers, //System.out.println("scheme = " + scheme); String authority = headers.firstValue(":authority").orElse(""); //System.out.println("authority = " + authority); - System.err.printf("TestServer: %s %s\n", method, path); + System.err.printf(server.name + ": %s %s\n", method, path); int winsize = clientSettings.getParameter( SettingsFrame.INITIAL_WINDOW_SIZE); //System.err.println ("Stream window size = " + winsize); final InputStream bis; if (endStreamReceived && queue.size() == 0) { - System.err.println("Server: got END_STREAM for stream " + streamid); + System.err.println(server.name + ": got END_STREAM for stream " + streamid); bis = NullInputStream.INSTANCE; } else { - System.err.println("Server: creating input stream for stream " + streamid); + System.err.println(server.name + ": creating input stream for stream " + streamid); bis = new BodyInputStream(queue, streamid, this); } try (bis; @@ -802,7 +806,7 @@ headers, rspheadersBuilder, uri, bis, getSSLSession(), if (bos.closed) { Queue q = streams.get(streamid); if (q != null && (q.isClosed() || q.isClosing())) { - System.err.println("TestServer: Stream " + streamid + " closed: " + closed); + System.err.println(server.name + ": Stream " + streamid + " closed: " + closed); return; } } @@ -812,7 +816,7 @@ headers, rspheadersBuilder, uri, bis, getSSLSession(), // everything happens in the exchange from here. Hopefully will // return though. } catch (Throwable e) { - System.err.println("TestServer: handleRequest exception: " + e); + System.err.println(server.name + ": handleRequest exception: " + e); e.printStackTrace(); close(-1); } @@ -844,7 +848,7 @@ void readLoop() { while (!stopping) { Http2Frame frame = readFrameImpl(); if (frame == null) { - System.err.println("EOF reached on connection " + connectionKey() + System.err.println(server.name + ": EOF reached on connection " + connectionKey() + ", will no longer accept incoming frames"); closeIncoming(); return; @@ -865,7 +869,7 @@ void readLoop() { Queue q = streams.get(stream); if (frame.type() == HeadersFrame.TYPE) { if (q != null) { - System.err.println("HEADERS frame for existing stream! Error."); + System.err.println(server.name + ": HEADERS frame for existing stream! Error."); // TODO: close connection continue; } else { @@ -874,7 +878,8 @@ void readLoop() { // if we already sent a goaway, then don't create new streams with // higher stream ids. if (finalProcessedStreamId != -1 && streamId > finalProcessedStreamId) { - System.err.println(connectionKey() + " resetting stream " + streamId + System.err.println(server.name + ": " + connectionKey() + + " resetting stream " + streamId + " as REFUSED_STREAM"); final ResetFrame rst = new ResetFrame(streamId, REFUSED_STREAM); outputQ.put(rst); @@ -884,7 +889,7 @@ void readLoop() { } } else { if (q == null && !pushStreams.contains(stream)) { - System.err.printf("Non Headers frame received with"+ + System.err.printf(server.name + ": Non Headers frame received with"+ " non existing stream (%d) ", frame.streamid()); System.err.println(frame); continue; @@ -914,21 +919,21 @@ void readLoop() { } else if (isClientStreamId(stream) && stream < next) { // We may receive a reset on a client stream that has already // been closed. Just ignore it. - System.err.println("TestServer: received ResetFrame on closed stream: " + stream); + System.err.println(server.name + ": received ResetFrame on closed stream: " + stream); System.err.println(frame); } else if (isServerStreamId(stream) && stream < nextPush) { // We may receive a reset on a push stream that has already // been closed. Just ignore it. - System.err.println("TestServer: received ResetFrame on closed push stream: " + stream); + System.err.println(server.name + ": received ResetFrame on closed push stream: " + stream); System.err.println(frame); } else { - System.err.println("TestServer: Unexpected frame on: " + stream); + System.err.println(server.name + ": Unexpected frame on: " + stream); System.err.println(frame); throw new IOException("Unexpected frame"); } } else { if (!q.putIfOpen(frame)) { - System.err.printf("Stream %s is closed: dropping %s%n", + System.err.printf(server.name + ": Stream %s is closed: dropping %s%n", stream, frame); } } @@ -937,7 +942,7 @@ void readLoop() { } } catch (Throwable e) { if (!stopping) { - System.err.println("Http server reader thread shutdown"); + System.err.println(server.name + ": Http server reader thread shutdown"); e.printStackTrace(); } close(ErrorFrame.PROTOCOL_ERROR); @@ -1078,7 +1083,7 @@ void writeLoop() { : new ContinuationFrame(rh.streamid(), flags, list); if (Log.headers()) { // avoid too much chatter: log only if Log.headers() is enabled - System.err.println("TestServer writing " + hf); + System.err.println(server.name + ": writing " + hf); } writeFrame(hf); cont++; @@ -1088,7 +1093,7 @@ void writeLoop() { } else writeFrame(frame); } - System.err.println("TestServer: Connection writer stopping"); + System.err.println(server.name + ": Connection writer stopping " + connectionKey()); } catch (Throwable e) { e.printStackTrace(); /*close(); @@ -1140,7 +1145,7 @@ public void sendEndStream() throws IOException { ii.transferTo(oo); } catch (Throwable ex) { - System.err.printf("TestServer: pushing response error: %s\n", + System.err.printf(server.name + ": pushing response error: %s\n", ex.toString()); } finally { closeIgnore(ii); @@ -1303,7 +1308,7 @@ Http1InitialRequest readHttp1Request() throws IOException { } return new Http1InitialRequest(headers, buf); } catch (IOException e) { - System.err.println("TestServer: headers read: [ " + headers + " ]"); + System.err.println(server.name + ": headers read: [ " + headers + " ]"); throw e; } } @@ -1335,7 +1340,7 @@ void sendHttp1Response(int code, String msg, String... headers) throws IOExcepti } private void unexpectedFrame(Http2Frame frame) { - System.err.println("OOPS. Unexpected"); + System.err.println(server.name + ": OOPS. Unexpected"); assert false; } @@ -1375,19 +1380,41 @@ void registerStreamWindowUpdater(int streamid, Consumer r) { * @param amount */ public synchronized void obtainConnectionWindow(int amount) throws InterruptedException { - while (amount > 0) { - int n = Math.min(amount, sendWindow); - amount -= n; - sendWindow -= n; - if (amount > 0) - wait(); + int demand = amount; + try { + int waited = 0; + while (amount > 0) { + int n = Math.min(amount, sendWindow); + amount -= n; + sendWindow -= n; + if (amount > 0) { + // Do not include this print line on a version that does not have + // JDK-8337395 + System.err.printf("%s: blocked waiting for %s connection window, obtained %s%n", + server.name, amount, demand - amount); + waited++; + wait(); + } + } + if (waited > 0) { + // Do not backport this print line on a version that does not have + // JDK-8337395 + System.err.printf("%s: obtained %s connection window, remaining %s%n", + server.name, demand, sendWindow); + } + assert amount == 0; + } catch (Throwable t) { + sendWindow += (demand - amount); + throw t; } } public void updateConnectionWindow(int amount) { - System.out.printf("sendWindow (window=%s, amount=%s) is now: %s%n", - sendWindow, amount, sendWindow + amount); synchronized (this) { + // Do not backport this print line on a version that does not have + // JDK-8337395 + System.err.printf(server.name + ": update sendWindow (window=%s, amount=%s) is now: %s%n", + sendWindow, amount, sendWindow + amount); sendWindow += amount; notifyAll(); } diff --git a/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java b/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java index 76e32f04186a0..255f99a2e1c5e 100644 --- a/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java +++ b/test/jdk/java/net/httpclient/offline/FixedResponseHttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,8 +209,11 @@ public HttpClient.Version version() { if (obp.isPresent()) { ConsumingSubscriber subscriber = new ConsumingSubscriber(); obp.get().subscribe(subscriber); + // wait for our subscriber to be completed and get the + // list of ByteBuffers it received. + var buffers = subscriber.getBuffers().join(); if (responseBodyBytes == ECHO_SENTINAL) { - responseBody = subscriber.buffers; + responseBody = buffers; } } @@ -246,6 +249,13 @@ public HttpClient.Version version() { */ private static class ConsumingSubscriber implements Flow.Subscriber { final List buffers = Collections.synchronizedList(new ArrayList<>()); + // A CompletableFuture that will be completed with a list of ByteBuffers that the + // ConsumingSubscriber has consumed. + final CompletableFuture> consumed = new CompletableFuture<>(); + + public final CompletableFuture> getBuffers() { + return consumed; + } @Override public void onSubscribe(Flow.Subscription subscription) { @@ -256,9 +266,9 @@ public void onSubscribe(Flow.Subscription subscription) { buffers.add(item.duplicate()); } - @Override public void onError(Throwable throwable) { assert false : "Unexpected"; } + @Override public void onError(Throwable throwable) { consumed.completeExceptionally(throwable); } - @Override public void onComplete() { /* do nothing */ } + @Override public void onComplete() { consumed.complete(buffers.stream().toList()); } } @Override diff --git a/test/jdk/java/net/httpclient/whitebox/DelegatingExecutorTestDriver.java b/test/jdk/java/net/httpclient/whitebox/DelegatingExecutorTestDriver.java new file mode 100644 index 0000000000000..4b1b783b1b664 --- /dev/null +++ b/test/jdk/java/net/httpclient/whitebox/DelegatingExecutorTestDriver.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8350019 + * @summary Verifies `HttpClientImpl.DelegatingExecutor` behavior + * @modules java.net.http/jdk.internal.net.http + * @run junit java.net.http/jdk.internal.net.http.DelegatingExecutorTest + */ diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/DelegatingExecutorTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/DelegatingExecutorTest.java new file mode 100644 index 0000000000000..5b96ce4125dc7 --- /dev/null +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/DelegatingExecutorTest.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.net.http; + +import jdk.internal.net.http.HttpClientImpl.DelegatingExecutor; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class DelegatingExecutorTest { + + @Test + public void testInlineExecution() { + Thread callSiteThread = Thread.currentThread(); + Thread[] runSiteThreadRef = {null}; + new DelegatingExecutor(() -> false, null, null) + .execute(() -> runSiteThreadRef[0] = Thread.currentThread()); + assertSame(callSiteThread, runSiteThreadRef[0]); + } + + @Test + public void testDelegateDeferral() { + ImmediateExecutor delegate = new ImmediateExecutor(); + Runnable task = () -> {}; + new DelegatingExecutor(() -> true, delegate, null).execute(task); + delegate.assertReception(task); + } + + @Test + public void testRejectedExecutionException() throws InterruptedException { + + // Create a deterministically throwing task + RuntimeException error = new RejectedExecutionException(); + FirstThrowingAndThenCompletingRunnable task = new FirstThrowingAndThenCompletingRunnable(error); + + // Create a recording delegate + ImmediateExecutor delegate = new ImmediateExecutor(); + + // Create a recording error handler + List reportedTasks = new ArrayList<>(); + List reportedErrors = new ArrayList<>(); + BiConsumer errorHandler = (task_, error_) -> { + synchronized (this) { + reportedTasks.add(task_); + reportedErrors.add(error_); + } + }; + + // Verify the initial failing execution + new DelegatingExecutor(() -> true, delegate, errorHandler).execute(task); + delegate.assertReception(task); + + // Verify fallback to the async. pool + assertEquals(1, reportedTasks.size()); + assertSame(task, reportedTasks.getFirst()); + assertEquals(1, reportedErrors.size()); + assertSame(error, reportedErrors.getFirst()); + boolean completed = task.completionLatch.await(5, TimeUnit.SECONDS); + assertTrue(completed); + + } + + @Test + public void testNotRejectedExecutionException() { + + // Create a deterministically throwing task + RuntimeException error = new RuntimeException(); + FirstThrowingAndThenCompletingRunnable task = new FirstThrowingAndThenCompletingRunnable(error); + + // Create a recording delegate + ImmediateExecutor delegate = new ImmediateExecutor(); + + // Verify the immediate exception propagation + Throwable thrownError = assertThrows( + Throwable.class, + () -> new DelegatingExecutor(() -> true, delegate, null).execute(task)); + delegate.assertReception(task); + assertSame(error, thrownError); + + } + + private static final class ImmediateExecutor implements Executor { + + private final List receivedTasks = new ArrayList<>(); + + @Override + public synchronized void execute(Runnable task) { + receivedTasks.add(task); + task.run(); + } + + private synchronized void assertReception(Runnable... tasks) { + assertSame(tasks.length, receivedTasks.size()); + for (int taskIndex = 0; taskIndex < tasks.length; taskIndex++) { + assertSame(tasks[taskIndex], receivedTasks.get(taskIndex)); + } + } + + } + + private static final class FirstThrowingAndThenCompletingRunnable implements Runnable { + + private final AtomicInteger invocationCounter = new AtomicInteger(0); + + private final CountDownLatch completionLatch = new CountDownLatch(1); + + private final RuntimeException exception; + + private FirstThrowingAndThenCompletingRunnable(RuntimeException exception) { + this.exception = exception; + } + + @Override + public void run() { + switch (invocationCounter.getAndIncrement()) { + case 0: throw exception; + case 1: { completionLatch.countDown(); break; } + default: fail(); + } + } + + } + + @Test + public void testDelegateShutdown() { + AtomicInteger invocationCounter = new AtomicInteger(); + try (ExecutorService delegate = new ThreadPoolExecutor(1, 1, 1, TimeUnit.DAYS, new LinkedBlockingQueue<>()) { + @Override + public void shutdown() { + invocationCounter.incrementAndGet(); + super.shutdown(); + } + }) { + new DelegatingExecutor(() -> true, delegate, null).shutdown(); + assertEquals(1, invocationCounter.get()); + } + } + +} diff --git a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java index 794ede84a924a..e6fde147bd9ba 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java +++ b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.function.Executable; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; public class InterruptibleOrNot { // DatagramChannel implementation class @@ -98,6 +99,7 @@ public void testInterruptDuringInterruptibleReceive() throws Exception { */ @Test public void testInterruptBeforeUninterruptibleReceive() throws Exception { + assumeFalse(Thread.currentThread().isVirtual()); try (DatagramChannel dc = boundDatagramChannel(false)) { ByteBuffer buf = ByteBuffer.allocate(100); onReceive(() -> { diff --git a/test/jdk/java/nio/channels/FileChannel/LoopingTruncate.java b/test/jdk/java/nio/channels/FileChannel/LoopingTruncate.java index 203ba47d6fb37..d3bca2d8f8e20 100644 --- a/test/jdk/java/nio/channels/FileChannel/LoopingTruncate.java +++ b/test/jdk/java/nio/channels/FileChannel/LoopingTruncate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -/** +/* * @test * @bug 8137121 8137230 * @summary (fc) Infinite loop FileChannel.truncate @@ -31,12 +31,12 @@ */ import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; -import static java.nio.file.StandardOpenOption.*; import java.util.concurrent.TimeUnit; +import static java.nio.file.StandardOpenOption.*; import static jdk.test.lib.Utils.adjustTimeout; public class LoopingTruncate { @@ -48,7 +48,10 @@ public class LoopingTruncate { static long TIMEOUT = adjustTimeout(20_000); public static void main(String[] args) throws Throwable { - Path path = Files.createTempFile("LoopingTruncate.tmp", null); + // Intentionally opting out from the default `java.io.tmpdir`. + // It occasionally lacks the sufficient disk space this test needs. + Path pathDir = Path.of(System.getProperty("user.dir")); + Path path = Files.createTempFile(pathDir, "LoopingTruncate.tmp", null); try (FileChannel fc = FileChannel.open(path, CREATE, WRITE)) { fc.position(FATEFUL_SIZE + 1L); System.out.println(" Writing large file..."); diff --git a/test/jdk/java/nio/channels/vthread/SelectorOps.java b/test/jdk/java/nio/channels/vthread/SelectorOps.java index 1abb5c8bc5f60..0c86cae61850e 100644 --- a/test/jdk/java/nio/channels/vthread/SelectorOps.java +++ b/test/jdk/java/nio/channels/vthread/SelectorOps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,22 +25,22 @@ * @test id=default * @summary Test virtual threads doing selection operations * @library /test/lib - * @run junit/othervm --enable-native-access=ALL-UNNAMED SelectorOps + * @run junit/othervm/native --enable-native-access=ALL-UNNAMED SelectorOps */ /* * @test id=poller-modes * @requires (os.family == "linux") | (os.family == "mac") * @library /test/lib - * @run junit/othervm -Djdk.pollerMode=1 --enable-native-access=ALL-UNNAMED SelectorOps - * @run junit/othervm -Djdk.pollerMode=2 --enable-native-access=ALL-UNNAMED SelectorOps + * @run junit/othervm/native -Djdk.pollerMode=1 --enable-native-access=ALL-UNNAMED SelectorOps + * @run junit/othervm/native -Djdk.pollerMode=2 --enable-native-access=ALL-UNNAMED SelectorOps */ /* * @test id=no-vmcontinuations * @requires vm.continuations * @library /test/lib - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations + * @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations * --enable-native-access=ALL-UNNAMED SelectorOps */ diff --git a/test/jdk/java/nio/file/Files/SBC.java b/test/jdk/java/nio/file/Files/SBC.java index 7aa04b184627a..1e7d463644b46 100644 --- a/test/jdk/java/nio/file/Files/SBC.java +++ b/test/jdk/java/nio/file/Files/SBC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 + * @bug 4313887 8349812 * @summary Unit test for java.nio.file.Files.newByteChannel * @library .. * @modules jdk.unsupported @@ -63,6 +63,7 @@ public static void main(String[] args) throws Exception { badCombinations(dir); unsupportedOptions(dir); nullTests(dir); + emptyPathTest(); } finally { TestUtil.removeAll(dir); @@ -424,6 +425,29 @@ static void nullTests(Path dir) throws Exception { } catch (NullPointerException x) { } } + static void emptyPathTest() throws Exception { + try { + Files.newByteChannel(Path.of(""), WRITE, CREATE_NEW); + throw new RuntimeException("FileAlreadyExistsException expected"); + } catch (FileAlreadyExistsException x) { + } catch (AccessDeniedException x) { + /* Thrown on Windows only */ + } + + try { + Files.newByteChannel(Path.of(""), WRITE, CREATE, DELETE_ON_CLOSE); + throw new RuntimeException("FileSystemException expected"); + } catch (FileSystemException x) { } + + try { + Files.newByteChannel(Path.of(""), WRITE, LinkOption.NOFOLLOW_LINKS); + throw new RuntimeException("FileSystemException expected"); + } catch (FileSystemException x) { } + + try (var channel = Files.newByteChannel(Path.of(""), READ, LinkOption.NOFOLLOW_LINKS)) { + } catch(AccessDeniedException x) { /* Thrown on Windows only */ } + } + static void write(WritableByteChannel wbc, String msg) throws IOException { ByteBuffer buf = ByteBuffer.wrap(msg.getBytes()); while (buf.hasRemaining()) diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 8add9e76104b0..a82269c6c5661 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; -import jdk.internal.util.OSVersion; +import jdk.internal.util.StaticProperty; /** * Uses Files.probeContentType to probe html file, custom file type, and minimal @@ -83,7 +83,7 @@ private static int checkContentTypes(String expected, String actual) { if (!expected.equals(actual)) { if (!OperatingSystem.isWindows()) { Path userMimeTypes = - Path.of(System.getProperty("user.home"), ".mime.types"); + Path.of(StaticProperty.userHome(), ".mime.types"); checkMimeTypesFile(userMimeTypes); Path etcMimeTypes = Path.of("/etc/mime.types"); @@ -188,17 +188,8 @@ public static void main(String[] args) throws IOException { exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); exTypes.add(new ExType("wasm", List.of("application/wasm"))); - // extensions with content type that differs on Windows 11+ - if (OperatingSystem.isWindows() && - (System.getProperty("os.name").endsWith("11") || - new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { - System.out.println("Windows 11+ detected: using different types"); - exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); - exTypes.add(new ExType("csv", List.of("text/csv", "application/vnd.ms-excel"))); - exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed", "application/x-compressed"))); - exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf", "application/msword"))); - exTypes.add(new ExType("7z", List.of("application/x-7z-compressed", "application/x-compressed"))); - } else { + // extensions with consistent content type on Unix (but not on Windows) + if (!OperatingSystem.isWindows()) { exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip"))); exTypes.add(new ExType("csv", List.of("text/csv"))); exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed"))); diff --git a/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java new file mode 100644 index 0000000000000..8ad9a41c5fd32 --- /dev/null +++ b/test/jdk/java/nio/file/spi/CustomSystemClassLoader.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; + +/** + * Use by tests in SetDefaultProvider to test startup with a custom default file system + * provider and a custom system class loader. + */ + +public class CustomSystemClassLoader extends ClassLoader { + public CustomSystemClassLoader(ClassLoader parent) { + super(parent); + + // use default file system + FileSystem fs = FileSystems.getDefault(); + var path = fs.getPath("foo"); + } +} \ No newline at end of file diff --git a/test/jdk/java/nio/file/spi/SetDefaultProvider.java b/test/jdk/java/nio/file/spi/SetDefaultProvider.java index 034d6ed6ebd57..4d74c8fee934e 100644 --- a/test/jdk/java/nio/file/spi/SetDefaultProvider.java +++ b/test/jdk/java/nio/file/spi/SetDefaultProvider.java @@ -21,13 +21,14 @@ * questions. */ -/** +/* * @test - * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 - * @modules jdk.jartool + * @bug 4313887 7006126 8142968 8178380 8183320 8210112 8266345 8263940 8331467 + * 8346573 8346722 + * @modules jdk.jartool jdk.jlink * @library /test/lib - * @build SetDefaultProvider TestProvider m/* jdk.test.lib.process.ProcessTools - * @run testng/othervm SetDefaultProvider + * @build testfsp/* testapp/* CustomSystemClassLoader + * @run junit SetDefaultProvider * @summary Runs tests with -Djava.nio.file.spi.DefaultFileSystemProvider set on * the command line to override the default file system provider */ @@ -37,173 +38,235 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.spi.ToolProvider; import java.util.stream.Stream; import jdk.test.lib.process.ProcessTools; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; +import static org.junit.jupiter.api.Assertions.*; -import org.testng.annotations.Test; -import static org.testng.Assert.*; - -@Test -public class SetDefaultProvider { +class SetDefaultProvider { private static final String SET_DEFAULT_FSP = - "-Djava.nio.file.spi.DefaultFileSystemProvider=TestProvider"; + "-Djava.nio.file.spi.DefaultFileSystemProvider=testfsp.TestProvider"; private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") .orElseThrow(() -> new RuntimeException("jar tool not found") ); - private static Path createTempDirectory(String prefix) throws IOException { - Path testDir = Paths.get(System.getProperty("test.dir", ".")); - return Files.createTempDirectory(testDir, prefix); + private static final String TESTFSP = "testfsp"; + private static final String TESTAPP = "testapp"; + private static final String TESTAPP_MAIN = TESTAPP + ".Main"; + + // directory containing testfsp class files + private static String TESTFSP_CLASSES; + + // directory containing testapp class files + private static String TESTAPP_CLASSES; + + @BeforeAll + static void setup() { + TESTFSP_CLASSES = classes(TESTFSP); + TESTAPP_CLASSES = classes(TESTAPP); } /** - * Test override of default FileSystemProvider with the main application - * on the class path. + * Test file system provider exploded on the class path. */ - public void testClassPath() throws Exception { - String moduleClasses = moduleClasses(); - String testClasses = System.getProperty("test.classes"); - String classpath = moduleClasses + File.pathSeparator + testClasses; - int exitValue = exec(SET_DEFAULT_FSP, "-cp", classpath, "p.Main"); - assertEquals(exitValue, 0); + @Test + void testFspOnClassPath1() throws Exception { + exec(SET_DEFAULT_FSP, + "-cp", ofClasspath(TESTFSP_CLASSES, TESTAPP_CLASSES), + TESTAPP_MAIN); } /** - * Test override of default FileSystemProvider with a - * FileSystemProvider jar and the main application on the class path. + * Test file system provider in JAR file on the class path. */ - public void testClassPathWithFileSystemProviderJar() throws Exception { - String testClasses = System.getProperty("test.classes"); - Path jar = Path.of("testFileSystemProvider.jar"); - Files.deleteIfExists(jar); - createFileSystemProviderJar(jar, Path.of(testClasses)); - String classpath = jar + File.pathSeparator + testClasses - + File.separator + "modules" + File.separator + "m"; - int exitValue = exec(SET_DEFAULT_FSP, "-cp", classpath, "p.Main"); - assertEquals(exitValue, 0); + @Test + void testFspOnClassPath2() throws Exception { + String jarFile = createJar("fsp.jar", TESTFSP_CLASSES); + exec(SET_DEFAULT_FSP, + "-cp", ofClasspath(jarFile, TESTAPP_CLASSES), + TESTAPP_MAIN); } /** - * Creates a JAR containing the FileSystemProvider used to override the - * default FileSystemProvider + * Test file system provider in exploded module on the module path. */ - private void createFileSystemProviderJar(Path jar, Path dir) throws IOException { + @Test + void testFspOnModulePath1() throws Exception { + exec(SET_DEFAULT_FSP, + "-p", TESTFSP_CLASSES, + "--add-modules", TESTFSP, + "-cp", TESTAPP_CLASSES, + TESTAPP_MAIN); + } - List args = new ArrayList<>(); - args.add("--create"); - args.add("--file=" + jar); - try (Stream stream = Files.list(dir)) { - List paths = stream - .map(path -> path.getFileName().toString()) - .filter(f -> f.startsWith("TestProvider")) - .toList(); - for(var p : paths) { - args.add("-C"); - args.add(dir.toString()); - args.add(p); - } - } - int ret = JAR_TOOL.run(System.out, System.out, args.toArray(new String[0])); - assertEquals(ret, 0); + /** + * Test file system provider in modular JAR on the module path. + */ + @Test + void testFspOnModulePath2() throws Exception { + String jarFile = createJar("fsp.jar", TESTFSP_CLASSES); + exec(SET_DEFAULT_FSP, + "-p", jarFile, + "--add-modules", TESTFSP, + "-cp", TESTAPP_CLASSES, + TESTAPP_MAIN); + } + + /** + * Test file system provider linked into run-time image. + */ + @Test + void testFspInRuntimeImage() throws Exception { + String image = "image"; + + ToolProvider jlink = ToolProvider.findFirst("jlink").orElseThrow(); + String[] jlinkCmd = { + "--module-path", TESTFSP_CLASSES, + "--add-modules", TESTFSP, + "--output", image + }; + int exitCode = jlink.run(System.out, System.err, jlinkCmd); + assertEquals(0, exitCode); + + String[] javaCmd = { + Path.of(image, "bin", "java").toString(), + SET_DEFAULT_FSP, + "--add-modules", TESTFSP, + "-cp", TESTAPP_CLASSES, + TESTAPP_MAIN + }; + var pb = new ProcessBuilder(javaCmd); + ProcessTools.executeProcess(pb) + .outputTo(System.out) + .errorTo(System.err) + .shouldHaveExitValue(0); } /** - * Test override of default FileSystemProvider with the main application - * on the module path as an exploded module. + * Test file system provider on class path, application in exploded module on module path. */ - public void testExplodedModule() throws Exception { - String modulePath = System.getProperty("jdk.module.path"); - int exitValue = exec(SET_DEFAULT_FSP, "-p", modulePath, "-m", "m/p.Main"); - assertEquals(exitValue, 0); + @Test + void testAppOnModulePath1() throws Exception { + exec(SET_DEFAULT_FSP, + "-p", TESTAPP_CLASSES, + "-cp", TESTFSP_CLASSES, + "-m", TESTAPP + "/" + TESTAPP_MAIN); } /** - * Test override of default FileSystemProvider with the main application - * on the module path as a modular JAR. + * Test file system provider on class path, application in modular JAR on module path. */ - public void testModularJar() throws Exception { - String jarFile = createModularJar(); - int exitValue = exec(SET_DEFAULT_FSP, "-p", jarFile, "-m", "m/p.Main"); - assertEquals(exitValue, 0); + @Test + void testAppOnModulePath2() throws Exception { + String jarFile = createJar("testapp.jar", TESTAPP_CLASSES); + exec(SET_DEFAULT_FSP, + "-cp", TESTFSP_CLASSES, + "-p", jarFile, + "-m", TESTAPP + "/" + TESTAPP_MAIN); } /** - * Test override of default FileSystemProvider where the main application - * is a module that is patched by an exploded patch. + * Test file system provider on class path, application in modular JAR on module path + * that is patched with exploded patch. */ - public void testExplodedModuleWithExplodedPatch() throws Exception { + @Test + void testPatchedAppOnModulePath1() throws Exception { Path patchdir = createTempDirectory("patch"); - String modulePath = System.getProperty("jdk.module.path"); - int exitValue = exec(SET_DEFAULT_FSP, - "--patch-module", "m=" + patchdir, - "-p", modulePath, - "-m", "m/p.Main"); - assertEquals(exitValue, 0); + Files.createFile(patchdir.resolve("aoo.properties")); + exec(SET_DEFAULT_FSP, + "--patch-module", TESTAPP + "=" + patchdir, + "-p", TESTAPP_CLASSES, + "-cp", TESTFSP_CLASSES, + "-m", TESTAPP + "/" + TESTAPP_MAIN); } /** - * Test override of default FileSystemProvider where the main application - * is a module that is patched by an exploded patch. + * Test file system provider on class path, application in modular JAR on module path + * that is patched with patch in JAR file. */ - public void testExplodedModuleWithJarPatch() throws Exception { + @Test + void testPatchedAppOnModulePath2() throws Exception { Path patchdir = createTempDirectory("patch"); - Files.createDirectory(patchdir.resolve("m.properties")); - Path patch = createJarFile(patchdir); - String modulePath = System.getProperty("jdk.module.path"); - int exitValue = exec(SET_DEFAULT_FSP, - "--patch-module", "m=" + patch, - "-p", modulePath, - "-m", "m/p.Main"); - assertEquals(exitValue, 0); + Files.createFile(patchdir.resolve("app.properties")); + String jarFile = createJar("patch.jar", patchdir.toString()); + exec(SET_DEFAULT_FSP, + "--patch-module", TESTAPP + "=" + jarFile, + "-p", TESTAPP_CLASSES, + "-cp", TESTFSP_CLASSES, + "-m", TESTAPP + "/" + TESTAPP_MAIN); + } + + /** + * Test file system provider on class path in conjunction with a custom system + * class loader that uses the file system API during its initialization. + */ + @Test + void testCustomSystemClassLoader() throws Exception { + String testClasses = System.getProperty("test.classes"); + exec(SET_DEFAULT_FSP, + "-Djava.system.class.loader=CustomSystemClassLoader", + "-cp", ofClasspath(testClasses, TESTFSP_CLASSES, TESTAPP_CLASSES), + TESTAPP_MAIN); } /** - * Returns the directory containing the classes for module "m". + * Returns the directory containing the classes for the given module. */ - private String moduleClasses() { + private static String classes(String mn) { String mp = System.getProperty("jdk.module.path"); - for (String dir : mp.split(File.pathSeparator)) { - Path m = Paths.get(dir, "m"); - if (Files.exists(m)) return m.toString(); - } - fail(); - return null; + return Arrays.stream(mp.split(File.pathSeparator)) + .map(e -> Path.of(e, mn)) + .filter(Files::isDirectory) + .findAny() + .map(Path::toString) + .orElseThrow(); } /** - * Creates a modular JAR containing module "m". + * Returns a class path from the given paths. */ - private String createModularJar() throws Exception { - Path dir = Paths.get(moduleClasses()); - Path jar = createJarFile(dir); - return jar.toString(); + private String ofClasspath(String... paths) { + return String.join(File.pathSeparator, paths); } /** - * Creates a JAR file containing the entries in the given file tree. + * Creates a JAR file from the contains of the given directory. */ - private Path createJarFile(Path dir) throws Exception { - Path jar = createTempDirectory("tmp").resolve("m.jar"); - String[] args = { "--create", "--file=" + jar, "-C", dir.toString(), "." }; - int ret = JAR_TOOL.run(System.out, System.out, args); + private String createJar(String jar, String dir) throws IOException { + List args = new ArrayList<>(); + args.add("--create"); + args.add("--file=" + jar); + args.add("-C"); + args.add(dir); + args.add("."); + int ret = JAR_TOOL.run(System.err, System.err, args.toArray(new String[0])); assertEquals(ret, 0); return jar; } /** - * Invokes the java launcher with the given arguments, returning the exit code. + * Create a temporary directory with the given prefix in the current directory. */ - private int exec(String... args) throws Exception { - return ProcessTools.executeTestJava(args) - .outputTo(System.out) - .errorTo(System.out) - .getExitValue(); + private static Path createTempDirectory(String prefix) throws IOException { + return Files.createTempDirectory(Path.of("."), prefix); + } + + /** + * Invokes the java launcher with the given arguments, throws if the non-0 is returned. + */ + private void exec(String... args) throws Exception { + ProcessTools.executeTestJava(args) + .outputTo(System.err) + .errorTo(System.err) + .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/nio/file/spi/TestDelegation.java b/test/jdk/java/nio/file/spi/TestDelegation.java index 348318a246217..0b9bc9de7f70c 100644 --- a/test/jdk/java/nio/file/spi/TestDelegation.java +++ b/test/jdk/java/nio/file/spi/TestDelegation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,8 +41,8 @@ * @test * @summary Verifies that a FileSystemProvider's implementation of the exists * and readAttributesIfExists methods are invoked - * @build TestDelegation TestProvider - * @run testng/othervm TestDelegation + * @compile testfsp/testfsp/TestProvider.java + * @run testng TestDelegation */ public class TestDelegation { @@ -55,7 +55,6 @@ public class TestDelegation { // The FileSystemProvider used by the test private MyProvider myProvider; - /** * Create the FileSystemProvider, the FileSystem and * Path's used by the test. @@ -182,7 +181,7 @@ public void testIsRegularFile(Path p, boolean isFile) { /** * The FileSystemProvider implementation used by the test */ - static class MyProvider extends TestProvider { + static class MyProvider extends testfsp.TestProvider { private final Map> calls = new HashMap<>(); private MyProvider() { diff --git a/test/jdk/java/nio/file/spi/m/module-info.java b/test/jdk/java/nio/file/spi/testapp/module-info.java similarity index 90% rename from test/jdk/java/nio/file/spi/m/module-info.java rename to test/jdk/java/nio/file/spi/testapp/module-info.java index 844804707118c..9b8e30c73a6df 100644 --- a/test/jdk/java/nio/file/spi/m/module-info.java +++ b/test/jdk/java/nio/file/spi/testapp/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,5 +20,5 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -module m { +module testapp { } diff --git a/test/jdk/java/nio/file/spi/m/p/Main.java b/test/jdk/java/nio/file/spi/testapp/testapp/Main.java similarity index 91% rename from test/jdk/java/nio/file/spi/m/p/Main.java rename to test/jdk/java/nio/file/spi/testapp/testapp/Main.java index 4704c67902169..6f61d431707e1 100644 --- a/test/jdk/java/nio/file/spi/m/p/Main.java +++ b/test/jdk/java/nio/file/spi/testapp/testapp/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -package p; +package testapp; import java.io.File; import java.nio.file.FileSystem; @@ -58,5 +58,8 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("'path' not in default file system"); if (!path.equals(foo)) throw new RuntimeException(path + " not equal to " + foo); + + // exercise the file type detector + String fileType = Files.probeContentType(Path.of(".")); } } diff --git a/test/jdk/java/nio/file/spi/testfsp/module-info.java b/test/jdk/java/nio/file/spi/testfsp/module-info.java new file mode 100644 index 0000000000000..d15cf8dfb883a --- /dev/null +++ b/test/jdk/java/nio/file/spi/testfsp/module-info.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module testfsp { + exports testfsp to java.base; +} diff --git a/test/jdk/java/nio/file/spi/TestProvider.java b/test/jdk/java/nio/file/spi/testfsp/testfsp/TestProvider.java similarity index 99% rename from test/jdk/java/nio/file/spi/TestProvider.java rename to test/jdk/java/nio/file/spi/testfsp/testfsp/TestProvider.java index 27340e46543f3..54d6a58c4f941 100644 --- a/test/jdk/java/nio/file/spi/TestProvider.java +++ b/test/jdk/java/nio/file/spi/testfsp/testfsp/TestProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,8 @@ * questions. */ +package testfsp; + import java.io.File; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; diff --git a/test/jdk/java/security/KeyAgreement/Generic.java b/test/jdk/java/security/KeyAgreement/Generic.java new file mode 100644 index 0000000000000..dcf212dbffe7c --- /dev/null +++ b/test/jdk/java/security/KeyAgreement/Generic.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8189441 + * @library /test/lib /test/jdk/sun/security/pkcs11 + * @summary make sure Generic is accepted by all KeyAgreement implementations + * @run main Generic builtin + * @run main/othervm Generic nss + * @run main/othervm -DCUSTOM_P11_CONFIG_NAME=p11-nss-sensitive.txt Generic nss + */ +import jdk.test.lib.Asserts; + +import javax.crypto.KeyAgreement; +import java.security.KeyPairGenerator; +import java.security.Provider; +import java.security.Security; +import java.util.List; + +public class Generic { + + public static void main(String[] args) throws Exception { + if (args[0].equals("nss")) { + test(PKCS11Test.getSunPKCS11(PKCS11Test.getNssConfig())); + } else { + for (var p : Security.getProviders()) { + test(p); + } + } + } + + static void test(Provider p) throws Exception { + for (var s : p.getServices()) { + if (s.getType().equalsIgnoreCase("KeyAgreement")) { + try { + System.out.println(s.getProvider().getName() + "." + s.getAlgorithm()); + var g = KeyPairGenerator.getInstance(ka2kpg(s.getAlgorithm()), p); + var kp1 = g.generateKeyPair(); + var kp2 = g.generateKeyPair(); + var ka = KeyAgreement.getInstance(s.getAlgorithm(), s.getProvider()); + for (var alg : List.of("TlsPremasterSecret", "Generic")) { + ka.init(kp1.getPrivate()); + ka.doPhase(kp2.getPublic(), true); + Asserts.assertEquals( + ka.generateSecret(alg).getAlgorithm(), alg); + } + } catch (Exception e) { + throw e; + } + } + } + } + + // Find key algorithm from KeyAgreement algorithm + private static String ka2kpg(String ka) { + return ka.equals("ECDH") ? "EC" : ka; + } +} diff --git a/test/jdk/java/security/KeyFactory/Failover.java b/test/jdk/java/security/KeyFactory/Failover.java index 7107ef1ad0281..3fd69a3cbc323 100644 --- a/test/jdk/java/security/KeyFactory/Failover.java +++ b/test/jdk/java/security/KeyFactory/Failover.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 4894125 7054918 8130181 - * @library ../testlibrary /test/lib + * @library /test/lib * @summary test that failover for KeyFactory works * @author Andreas Sterbenz */ @@ -32,8 +32,8 @@ import java.util.*; import java.security.*; -import java.security.interfaces.*; import java.security.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; import jdk.test.lib.security.SecurityUtils; public class Failover { diff --git a/test/jdk/java/security/KeyPairGenerator/Failover.java b/test/jdk/java/security/KeyPairGenerator/Failover.java index 7fc8da8ccfc34..1bc2bfee2c8de 100644 --- a/test/jdk/java/security/KeyPairGenerator/Failover.java +++ b/test/jdk/java/security/KeyPairGenerator/Failover.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 4894125 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary test that failover for KeyPairGenerator works * @author Andreas Sterbenz */ @@ -32,8 +32,8 @@ import java.util.*; import java.security.*; -import java.security.interfaces.*; import java.security.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; public class Failover { diff --git a/test/jdk/java/security/Provider/ChangeProviders.java b/test/jdk/java/security/Provider/ChangeProviders.java index 4b8b2cb48c9eb..798756e523acd 100644 --- a/test/jdk/java/security/Provider/ChangeProviders.java +++ b/test/jdk/java/security/Provider/ChangeProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,14 +24,13 @@ /* * @test * @bug 4856968 7054918 8130181 8175874 - * @library ../testlibrary + * @library /test/lib * @summary make sure add/insert/removeProvider() work correctly * @author Andreas Sterbenz */ -import java.util.*; - import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class ChangeProviders extends Provider { diff --git a/test/jdk/java/security/Provider/GetInstance.java b/test/jdk/java/security/Provider/GetInstance.java index d0d6417f02b08..f0e1a149f5cb6 100644 --- a/test/jdk/java/security/Provider/GetInstance.java +++ b/test/jdk/java/security/Provider/GetInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 4856968 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary make sure getInstance() works correctly, including failover * and delayed provider selection for Signatures * @author Andreas Sterbenz @@ -34,6 +34,7 @@ import java.security.*; import java.security.cert.*; +import jdk.test.lib.security.ProvidersSnapshot; public class GetInstance { diff --git a/test/jdk/java/security/Provider/GetServiceRace.java b/test/jdk/java/security/Provider/GetServiceRace.java index 7f3f6b56ff722..427d555d37567 100644 --- a/test/jdk/java/security/Provider/GetServiceRace.java +++ b/test/jdk/java/security/Provider/GetServiceRace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ /* * @test * @bug 8231387 - * @library ../testlibrary * @summary make sure getService() avoids a race * @author Tianmin Shi */ diff --git a/test/jdk/java/security/Provider/InvalidServiceTest.java b/test/jdk/java/security/Provider/InvalidServiceTest.java new file mode 100644 index 0000000000000..fd56e6b3286da --- /dev/null +++ b/test/jdk/java/security/Provider/InvalidServiceTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344361 + * @summary Restore null return for invalid services + */ + +import java.security.Provider; + +public class InvalidServiceTest { + + public static void main(String[] args) throws Exception { + Provider p1 = new LProvider("LegacyFormat"); + // this returns a service with null class name. Helps exercise the code path + Provider.Service s1 = p1.getService("MessageDigest", "SHA-1"); + if (s1 != null) + throw new RuntimeException("expecting null service"); + } + + private static class LProvider extends Provider { + LProvider(String name) { + super(name, "1.0", null); + put("Signature.MD5withRSA", "com.foo.Sig"); + put("MessageDigest.SHA-1 ImplementedIn", "Software"); + } + } +} diff --git a/test/jdk/java/security/Provider/RemoveProvider.java b/test/jdk/java/security/Provider/RemoveProvider.java index 05ab5eb0549c1..9983aa59b2a8f 100644 --- a/test/jdk/java/security/Provider/RemoveProvider.java +++ b/test/jdk/java/security/Provider/RemoveProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,13 +24,14 @@ /* * @test * @bug 4190873 7054918 8130181 - * @library ../testlibrary + * @library /test/lib * @summary Make sure provider instance can be removed from list of registered * providers, and "entrySet", "keySet", and "values" methods don't loop * indefinitely. */ import java.security.*; import java.util.*; +import jdk.test.lib.security.ProvidersSnapshot; public class RemoveProvider { diff --git a/test/jdk/java/security/Security/NoInstalledProviders.java b/test/jdk/java/security/Security/NoInstalledProviders.java index 551f1896ecbe5..1e701f9a6e1f6 100644 --- a/test/jdk/java/security/Security/NoInstalledProviders.java +++ b/test/jdk/java/security/Security/NoInstalledProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,13 @@ /* * @test * @bug 4273454 7054918 7052537 - * @library ../testlibrary + * @library /test/lib * @summary Make sure getProviders(filter) doesn't throw NPE * @run main/othervm NoInstalledProviders */ import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class NoInstalledProviders { diff --git a/test/jdk/java/security/Security/SynchronizedAccess.java b/test/jdk/java/security/Security/SynchronizedAccess.java index 28019213b3c24..c1443529fe79c 100644 --- a/test/jdk/java/security/Security/SynchronizedAccess.java +++ b/test/jdk/java/security/Security/SynchronizedAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,13 +24,14 @@ /* * @test * @bug 4162583 7054918 8130181 8028127 - * @library /test/lib ../testlibrary + * @library /test/lib * @summary Make sure Provider api implementations are synchronized properly */ import java.security.*; import jdk.test.lib.Asserts; +import jdk.test.lib.security.ProvidersSnapshot; public class SynchronizedAccess { diff --git a/test/jdk/java/security/Security/removing/RemoveProviders.java b/test/jdk/java/security/Security/removing/RemoveProviders.java index 0d9f6b207c595..38edf983fb020 100644 --- a/test/jdk/java/security/Security/removing/RemoveProviders.java +++ b/test/jdk/java/security/Security/removing/RemoveProviders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test * @bug 4963416 7054918 - * @library ../../testlibrary + * @library /test/lib * @summary make sure removeProvider() always works correctly * @author Andreas Sterbenz */ @@ -32,6 +32,7 @@ import java.util.*; import java.security.*; +import jdk.test.lib.security.ProvidersSnapshot; public class RemoveProviders { diff --git a/test/jdk/java/security/cert/CertPathBuilder/GetInstance.java b/test/jdk/java/security/cert/CertPathBuilder/GetInstance.java index 5ec4d6caa5a79..4289fcfaeced7 100644 --- a/test/jdk/java/security/cert/CertPathBuilder/GetInstance.java +++ b/test/jdk/java/security/cert/CertPathBuilder/GetInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,7 @@ * The test passes if it returns. * The test fails if an exception is thrown. */ -import java.security.cert.CertPathParameters; -import java.security.cert.CertPathBuilderResult; -import java.security.cert.CertPathBuilderSpi; import java.security.Provider; -import java.security.AccessController; import java.security.cert.CertPathBuilder; import java.security.NoSuchAlgorithmException; diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java index 478e94572bc73..d29ca878cd34d 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,7 @@ * @test * @bug 8179503 8328638 * @summary Java should support GET OCSP calls - * @library /javax/net/ssl/templates /java/security/testlibrary - * @build SimpleOCSPServer + * @library /javax/net/ssl/templates /test/lib * @modules java.base/sun.security.util * java.base/sun.security.provider.certpath * java.base/sun.security.x509 @@ -64,7 +63,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; +import jdk.test.lib.security.SimpleOCSPServer; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.ObjectIdentifier; diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java index dfd7dcdc81efe..342617a5fa93d 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/OCSPTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,7 @@ * @modules java.base/sun.security.x509 * java.base/sun.security.provider.certpath * java.base/sun.security.util - * @library ../../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm -Djava.security.debug=certpath OCSPTimeout 1000 true * @run main/othervm -Djava.security.debug=certpath * -Dcom.sun.security.ocsp.readtimeout=5 OCSPTimeout 1000 true @@ -59,8 +58,8 @@ import java.security.cert.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; import static java.security.cert.PKIXRevocationChecker.Option.*; @@ -84,7 +83,7 @@ public class OCSPTimeout { public static void main(String[] args) throws Exception { int ocspTimeout = 15000; - boolean expected = false; + boolean expected; createPKI(); @@ -195,7 +194,6 @@ private static void createPKI() throws Exception { rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null); rootOcsp.enableLog(debug); rootOcsp.setNextUpdateInterval(3600); - rootOcsp.setDisableContentLength(true); rootOcsp.start(); // Wait 60 seconds for server ready diff --git a/test/jdk/java/security/cert/CertPathValidator/crlDP/CheckAllCRLs.java b/test/jdk/java/security/cert/CertPathValidator/crlDP/CheckAllCRLs.java index 71627dbc64f4d..88ef85fe6ca9c 100644 --- a/test/jdk/java/security/cert/CertPathValidator/crlDP/CheckAllCRLs.java +++ b/test/jdk/java/security/cert/CertPathValidator/crlDP/CheckAllCRLs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.PublicKey; import java.security.cert.CertificateFactory; import java.security.cert.CertPath; import java.security.cert.CertPathValidator; @@ -54,7 +53,7 @@ import sun.security.x509.X509CRLEntryImpl; import sun.security.x509.X509CRLImpl; import static sun.security.x509.X509CRLImpl.TBSCertList; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.CertificateBuilder; /* * @test @@ -65,8 +64,7 @@ * fresh or stale. * @modules java.base/sun.security.x509 * java.base/sun.security.util - * @library ../../../../../java/security/testlibrary - * @build CertificateBuilder CheckAllCRLs + * @library /test/lib * @run main/othervm -Dcom.sun.security.enableCRLDP=true CheckAllCRLs */ public class CheckAllCRLs { diff --git a/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java b/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java index 29abfb9f551d4..c57abdf243d31 100644 --- a/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java +++ b/test/jdk/java/security/cert/CertPathValidator/trustAnchor/ValWithAnchorByName.java @@ -52,8 +52,8 @@ public class ValWithAnchorByName { // The following certificates and OCSP responses were captured from // a test run that used certificates and responses generated by - // sun.security.testlibrary.CertificateBuilder and - // sun.security.testlibrary.SimpleOCSPServer. + // jdk.test.lib.security.CertificateBuilder and + // jdk.test.lib.security.SimpleOCSPServer. // Subject: CN=SSLCertificate, O=SomeCompany // Issuer: CN=Intermediate CA Cert, O=SomeCompany diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java index cda264b628153..dbd12e66f60b2 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @bug 4029195 4052408 4056591 4059917 4060212 4061287 4065240 4071441 4073003 * 4089106 4100302 4101483 4103340 4103341 4104136 4104522 4106807 4108407 * 4134203 4138203 4148168 4151631 4151706 4153860 4162071 4182066 4209272 4210209 - * 4213086 4250359 4253490 4266432 4406615 4413980 8008577 8305853 8174269 + * 4213086 4250359 4253490 4266432 4406615 4413980 8008577 8305853 8174269 8347841 * @library /java/text/testlib * @run junit DateFormatRegression */ @@ -274,7 +274,7 @@ public void Test4065240() { try { Locale curLocale = Locale.GERMANY; Locale.setDefault(curLocale); - TimeZone.setDefault(TimeZone.getTimeZone("EST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Panama")); curDate = new Date(98, 0, 1); shortdate = DateFormat.getDateInstance(DateFormat.SHORT); fulldate = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG @@ -453,7 +453,7 @@ public void Test4413980() { TimeZone savedTimeZone = TimeZone.getDefault(); try { boolean pass = true; - String[] IDs = new String[] {"Undefined", "PST", "US/Pacific", + String[] IDs = new String[] {"Undefined", "America/Los_Angeles", "US/Pacific", "GMT+3:00", "GMT-01:30"}; for (int i = 0; i < IDs.length; i++) { TimeZone tz = TimeZone.getTimeZone(IDs[i]); @@ -543,7 +543,7 @@ public void Test4103340() { public void Test4103341() { TimeZone saveZone =TimeZone.getDefault(); try { - TimeZone.setDefault(TimeZone.getTimeZone("CST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")); SimpleDateFormat simple = new SimpleDateFormat("MM/dd/yyyy HH:mm"); if (!simple.getTimeZone().equals(TimeZone.getDefault())) fail("Fail: SimpleDateFormat not using default zone"); @@ -794,7 +794,7 @@ public void Test4406615() { Locale savedLocale = Locale.getDefault(); TimeZone savedTimeZone = TimeZone.getDefault(); Locale.setDefault(Locale.US); - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); Date d1, d2; String dt = "Mon, 1 Jan 2001 00:00:00"; @@ -1096,7 +1096,7 @@ public void Test4261506() { // XXX: Test assumes "PST" is not TimeZoneNames_ja. Need to // pick up another time zone when L10N is done to that file. - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); SimpleDateFormat fmt = new SimpleDateFormat("yy/MM/dd hh:ss zzz", Locale.JAPAN); @SuppressWarnings("deprecation") String result = fmt.format(new Date(1999 - 1900, 0, 1)); diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatTest.java b/test/jdk/java/text/Format/DateFormat/DateFormatTest.java index 20490f43a38a6..f0b30fa1065dd 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatTest.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,14 +24,16 @@ /** * @test * @bug 4052223 4089987 4469904 4326988 4486735 8008577 8045998 8140571 - * 8190748 8216969 8174269 + * 8190748 8216969 8174269 8347841 8347955 * @summary test DateFormat and SimpleDateFormat. * @modules jdk.localedata * @run junit DateFormatTest */ -import java.util.*; +import java.time.ZoneId; import java.text.*; +import java.util.*; +import java.util.function.Predicate; import static java.util.GregorianCalendar.*; import org.junit.jupiter.api.Test; @@ -89,7 +91,9 @@ public void TestWallyWedel() /* * A String array for the time zone ids. */ - String[] ids = TimeZone.getAvailableIDs(); + String[] ids = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); /* * How many ids do we have? */ @@ -183,7 +187,7 @@ public void TestTwoDigitYearDSTParse() //logln(fmt.format(date)); // This shows what the current locale format is //logln(((SimpleDateFormat)fmt).toPattern()); TimeZone save = TimeZone.getDefault(); - TimeZone PST = TimeZone.getTimeZone("PST"); + TimeZone PST = TimeZone.getTimeZone("America/Los_Angeles"); String s = "03-Apr-04 2:20:47 o'clock AM PST"; int hour = 2; try { @@ -275,7 +279,7 @@ public void TestFieldPosition() "0034", "0012", "0513", "Pacific Daylight Time", }; Date someDate = new Date(871508052513L); - TimeZone PST = TimeZone.getTimeZone("PST"); + TimeZone PST = TimeZone.getTimeZone("America/Los_Angeles"); for (int j = 0, exp = 0; j < dateFormats.length; ++j) { DateFormat df = dateFormats[j]; if (!(df instanceof SimpleDateFormat)) { diff --git a/test/jdk/java/text/Format/DateFormat/SDFTCKZoneNamesTest.java b/test/jdk/java/text/Format/DateFormat/SDFTCKZoneNamesTest.java index a9f2e30a4d05b..aea3706f70efe 100644 --- a/test/jdk/java/text/Format/DateFormat/SDFTCKZoneNamesTest.java +++ b/test/jdk/java/text/Format/DateFormat/SDFTCKZoneNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,13 @@ /** * @test - * @bug 8218948 + * @bug 8218948 8347841 * @summary TCK tests that check the time zone names between DFS.getZoneStrings() * and SDF.format("z*") * @run main SDFTCKZoneNamesTest */ import java.text.*; +import java.time.ZoneId; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -325,6 +326,9 @@ public void SimpleDateFormat0062() { SimpleDateFormat sdf = new SimpleDateFormat(); Date date = new Date(1234567890); for (String[] tz : sdf.getDateFormatSymbols().getZoneStrings()) { + if (ZoneId.SHORT_IDS.containsKey(tz[0])) { + continue; + } sdf.setTimeZone(TimeZone.getTimeZone(tz[0])); for (int i = 0; i < patterns.length && passed; i++) { StringBuffer result = new StringBuffer("qwerty"); diff --git a/test/jdk/java/text/Format/DateFormat/bug4358730.java b/test/jdk/java/text/Format/DateFormat/bug4358730.java index 445a6c23fcfc3..9b37f9f56be05 100644 --- a/test/jdk/java/text/Format/DateFormat/bug4358730.java +++ b/test/jdk/java/text/Format/DateFormat/bug4358730.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @bug 4358730 + * @bug 4358730 8347841 * @summary test that confirms Zero-Padding on year. * @run junit bug4358730 */ @@ -56,7 +56,7 @@ public void Test4358730() { Locale saveLocale = Locale.getDefault(); try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); Locale.setDefault(Locale.US); SimpleDateFormat sdf = new SimpleDateFormat(); diff --git a/test/jdk/java/time/tck/java/time/TCKZoneId.java b/test/jdk/java/time/tck/java/time/TCKZoneId.java index a1d0065d39e68..1e2d387245159 100644 --- a/test/jdk/java/time/tck/java/time/TCKZoneId.java +++ b/test/jdk/java/time/tck/java/time/TCKZoneId.java @@ -96,6 +96,7 @@ public class TCKZoneId extends AbstractTCKTest { //----------------------------------------------------------------------- // SHORT_IDS //----------------------------------------------------------------------- + @Test public void test_constant_OLD_IDS_POST_2024b() { Map ids = ZoneId.SHORT_IDS; assertEquals(ids.get("EST"), "America/Panama"); diff --git a/test/jdk/java/time/test/java/time/TestZoneOffset.java b/test/jdk/java/time/test/java/time/TestZoneOffset.java index a69eedfcd6c25..b85a629aefce7 100644 --- a/test/jdk/java/time/test/java/time/TestZoneOffset.java +++ b/test/jdk/java/time/test/java/time/TestZoneOffset.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,4 +83,19 @@ public void test_factory_ofTotalSecondsSame() { assertSame(ZoneOffset.ofTotalSeconds(0), ZoneOffset.UTC); } + @Test + public void test_quarter_cache() throws Exception { + // [-18:00, +18:00] + int quarter = 15 * 60; + int start = -18 * 3600, + end = 18 * 3600; + for (int totalSeconds = start; totalSeconds <= end; totalSeconds += quarter) { + var offset0 = ZoneOffset.ofTotalSeconds(totalSeconds); + var offset1 = ZoneOffset.ofTotalSeconds(totalSeconds); + var offset2 = ZoneOffset.ofTotalSeconds(totalSeconds); + assertSame(offset0, offset1); + assertSame(offset1, offset2); + } + } + } diff --git a/test/jdk/java/util/Calendar/CalendarRegression.java b/test/jdk/java/util/Calendar/CalendarRegression.java index 24d34533bde58..7b0f2025005b8 100644 --- a/test/jdk/java/util/Calendar/CalendarRegression.java +++ b/test/jdk/java/util/Calendar/CalendarRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ * 4174361 4177484 4197699 4209071 4288792 4328747 4413980 4546637 4623997 * 4685354 4655637 4683492 4080631 4080631 4167995 4340146 4639407 * 4652815 4652830 4740554 4936355 4738710 4633646 4846659 4822110 4960642 - * 4973919 4980088 4965624 5013094 5006864 8152077 + * 4973919 4980088 4965624 5013094 5006864 8152077 8347841 8347955 * @library /java/text/testlib * @run junit CalendarRegression */ @@ -42,6 +42,7 @@ import java.text.DateFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; +import java.time.ZoneId; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -50,6 +51,7 @@ import java.util.Map; import java.util.SimpleTimeZone; import java.util.TimeZone; +import java.util.function.Predicate; import static java.util.Calendar.*; @@ -75,7 +77,9 @@ public class CalendarRegression { public void Test4031502() { // This bug actually occurs on Windows NT as well, and doesn't // require the host zone to be set; it can be set in Java. - String[] ids = TimeZone.getAvailableIDs(); + String[] ids = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); boolean bad = false; for (int i = 0; i < ids.length; ++i) { TimeZone zone = TimeZone.getTimeZone(ids[i]); @@ -489,7 +493,7 @@ public void Test4095407() { @Test public void Test4096231() { TimeZone GMT = TimeZone.getTimeZone("GMT"); - TimeZone PST = TimeZone.getTimeZone("PST"); + TimeZone PST = TimeZone.getTimeZone("America/Los_Angeles"); int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997; Calendar cal1 = new GregorianCalendar(PST); @@ -838,7 +842,7 @@ public void Test4114578() { TimeZone saveZone = TimeZone.getDefault(); boolean fail = false; try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); Calendar cal = Calendar.getInstance(); long onset = new Date(98, APRIL, 5, 1, 0).getTime() + ONE_HOUR; long cease = new Date(98, OCTOBER, 25, 0, 0).getTime() + 2 * ONE_HOUR; @@ -1163,8 +1167,8 @@ public void Test4147269() { @Test public void Test4149677() { TimeZone[] zones = {TimeZone.getTimeZone("GMT"), - TimeZone.getTimeZone("PST"), - TimeZone.getTimeZone("EAT")}; + TimeZone.getTimeZone("America/Los_Angeles"), + TimeZone.getTimeZone("Africa/Addis_Ababa")}; for (int i = 0; i < zones.length; ++i) { GregorianCalendar calendar = new GregorianCalendar(zones[i]); @@ -1197,7 +1201,7 @@ public void Test4149677() { @Test public void Test4162587() { TimeZone savedTz = TimeZone.getDefault(); - TimeZone tz = TimeZone.getTimeZone("PST"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); TimeZone.setDefault(tz); GregorianCalendar cal = new GregorianCalendar(tz); Date d; @@ -1511,8 +1515,8 @@ public void Test4174361() { */ @Test public void Test4177484() { - TimeZone PST = TimeZone.getTimeZone("PST"); - TimeZone EST = TimeZone.getTimeZone("EST"); + TimeZone PST = TimeZone.getTimeZone("America/Los_Angeles"); + TimeZone EST = TimeZone.getTimeZone("America/Panama"); Calendar cal = Calendar.getInstance(PST, Locale.US); cal.clear(); @@ -1770,7 +1774,7 @@ public void Test4413980() { TimeZone savedTimeZone = TimeZone.getDefault(); try { boolean pass = true; - String[] IDs = new String[]{"Undefined", "PST", "US/Pacific", + String[] IDs = new String[]{"Undefined", "America/Los_Angeles", "US/Pacific", "GMT+3:00", "GMT-01:30"}; for (int i = 0; i < IDs.length; i++) { TimeZone tz = TimeZone.getTimeZone(IDs[i]); diff --git a/test/jdk/java/util/Calendar/JavatimeTest.java b/test/jdk/java/util/Calendar/JavatimeTest.java index 8f32801a307d0..115b1e4e8b876 100644 --- a/test/jdk/java/util/Calendar/JavatimeTest.java +++ b/test/jdk/java/util/Calendar/JavatimeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* *@test - *@bug 8007520 8008254 + *@bug 8007520 8008254 8347841 *@summary Test those bridge methods to/from java.time date/time classes * @key randomness */ @@ -107,23 +107,22 @@ public static void main(String[] args) throws Throwable { ///////////// java.util.TimeZone ///////////////////////// for (String zidStr : TimeZone.getAvailableIDs()) { - // TBD: tzdt intergration + if (ZoneId.SHORT_IDS.containsKey(zidStr)) { + continue; + } + // TBD: tzdt integration if (zidStr.startsWith("SystemV") || zidStr.contains("Riyadh8") - || zidStr.equals("US/Pacific-New") - || zidStr.equals("EST") - || zidStr.equals("HST") - || zidStr.equals("MST")) { + || zidStr.equals("US/Pacific-New")) { continue; } - ZoneId zid = ZoneId.of(zidStr, ZoneId.SHORT_IDS); + ZoneId zid = ZoneId.of(zidStr); if (!zid.equals(TimeZone.getTimeZone(zid).toZoneId())) { throw new RuntimeException("FAILED: zid -> tz -> zid :" + zidStr); } TimeZone tz = TimeZone.getTimeZone(zidStr); // no round-trip for alias and "GMT" if (!tz.equals(TimeZone.getTimeZone(tz.toZoneId())) - && !ZoneId.SHORT_IDS.containsKey(zidStr) && !zidStr.startsWith("GMT")) { throw new RuntimeException("FAILED: tz -> zid -> tz :" + zidStr); } diff --git a/test/jdk/java/util/Calendar/bug4316678.java b/test/jdk/java/util/Calendar/bug4316678.java index f6bd4b87cae4f..b1c24a6a0c4a1 100644 --- a/test/jdk/java/util/Calendar/bug4316678.java +++ b/test/jdk/java/util/Calendar/bug4316678.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4316678 + * @bug 4316678 8347841 * @summary test that Calendar's Serialization works correctly. * @run junit bug4316678 */ @@ -53,7 +53,7 @@ public class bug4316678 { // Set custom JVM default TimeZone @BeforeAll static void initAll() { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); } // Restore JVM default Locale and TimeZone diff --git a/test/jdk/java/util/Calendar/bug4372743.java b/test/jdk/java/util/Calendar/bug4372743.java index 193ad53d813b5..d3d2b39b5fc63 100644 --- a/test/jdk/java/util/Calendar/bug4372743.java +++ b/test/jdk/java/util/Calendar/bug4372743.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4372743 + * @bug 4372743 8347841 * @summary test that checks transitions of ERA and YEAR which are caused by add(MONTH). * @run junit bug4372743 */ @@ -67,7 +67,7 @@ public class bug4372743 { // Set custom JVM default timezone @BeforeAll static void initAll() { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); } // Restore JVM default timezone diff --git a/test/jdk/java/util/Currency/AvailableCurrenciesTest.java b/test/jdk/java/util/Currency/AvailableCurrenciesTest.java new file mode 100644 index 0000000000000..2886e4b41f82d --- /dev/null +++ b/test/jdk/java/util/Currency/AvailableCurrenciesTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347949 + * @summary Ensure underlying element equality of available currency methods + * @run junit AvailableCurrenciesTest + */ + +import java.util.Currency; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class AvailableCurrenciesTest { + + // Validate the equality of the set and stream of available currencies + @Test + public void streamEqualsSetTest() { + var currencies = Currency.getAvailableCurrencies(); + assertEquals(currencies, Currency.availableCurrencies().collect(Collectors.toSet()), + "availableCurrencies() and getAvailableCurrencies() do not have the same elements"); + } + + // Ensure there are no duplicates in the available currencies + @Test + public void noDuplicatesTest() { + assertEquals(Currency.getAvailableCurrencies().size(), + Currency.availableCurrencies().distinct().count(), + "Duplicate currencies returned by availableCurrencies()"); + } +} diff --git a/test/jdk/java/util/Currency/CheckDataVersion.java b/test/jdk/java/util/Currency/CheckDataVersion.java index 303603c5b85e2..d7e76be62389e 100644 --- a/test/jdk/java/util/Currency/CheckDataVersion.java +++ b/test/jdk/java/util/Currency/CheckDataVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Currency; class CheckDataVersion { @@ -63,33 +61,23 @@ static void check() { break; } } + InputStream JREdata = Currency.class.getModule().getResourceAsStream("java/util/currency.data"); + DataInputStream dis = new DataInputStream(JREdata); + int magic = dis.readInt(); + if (magic != 0x43757244) { + throw new RuntimeException("The magic number in the JRE's currency data is incorrect. Expected: 0x43757244, Got: 0x"+magic); + } + int fileVerNumber = dis.readInt(); + int dataVerNumber = dis.readInt(); + if (Integer.parseInt(fileVersion) != fileVerNumber || + Integer.parseInt(dataVersion) != dataVerNumber) { + throw new RuntimeException("Test data and JRE's currency data are inconsistent. test: (file: "+fileVersion+" data: "+dataVersion+"), JRE: (file: "+fileVerNumber+" data: "+dataVerNumber+")"); + } + System.out.println("test: (file: "+fileVersion+" data: "+dataVersion+"), JRE: (file: "+fileVerNumber+" data: "+dataVerNumber+")"); } catch (IOException ioe) { - throw new RuntimeException(ioe); + throw new RuntimeException( + "currency.data was not retrieved properly", ioe); } - - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - try { - InputStream in = Currency.class.getModule().getResourceAsStream("java/util/currency.data"); - String sep = File.separator; - DataInputStream dis = new DataInputStream(in); - int magic = dis.readInt(); - if (magic != 0x43757244) { - throw new RuntimeException("The magic number in the JRE's currency data is incorrect. Expected: 0x43757244, Got: 0x"+magic); - } - int fileVerNumber = dis.readInt(); - int dataVerNumber = dis.readInt(); - if (Integer.parseInt(fileVersion) != fileVerNumber || - Integer.parseInt(dataVersion) != dataVerNumber) { - throw new RuntimeException("Test data and JRE's currency data are inconsistent. test: (file: "+fileVersion+" data: "+dataVersion+"), JRE: (file: "+fileVerNumber+" data: "+dataVerNumber+")"); - } -System.out.println("test: (file: "+fileVersion+" data: "+dataVersion+"), JRE: (file: "+fileVerNumber+" data: "+dataVerNumber+")"); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - return null; - } - }); checked = true; } } diff --git a/test/jdk/java/util/Date/Bug4955000.java b/test/jdk/java/util/Date/Bug4955000.java index 4339f848f580a..f05e6ccd3f80a 100644 --- a/test/jdk/java/util/Date/Bug4955000.java +++ b/test/jdk/java/util/Date/Bug4955000.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4955000 + * @bug 4955000 8347841 * @summary Make sure that a Date and a GregorianCalendar produce the * same date/time. Both are new implementations in 1.5. */ @@ -42,7 +42,7 @@ public class Bug4955000 { public static void main(String[] args) { TimeZone defaultTZ = TimeZone.getDefault(); try { - TimeZone.setDefault(TimeZone.getTimeZone("NST")); + TimeZone.setDefault(TimeZone.getTimeZone("Pacific/Auckland")); GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("UTC")); // Date1025 int[] years1 = { diff --git a/test/jdk/java/util/Date/DateRegression.java b/test/jdk/java/util/Date/DateRegression.java index 8fe89d9d59bdf..eda575743e326 100644 --- a/test/jdk/java/util/Date/DateRegression.java +++ b/test/jdk/java/util/Date/DateRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,8 @@ /* * @test - * @bug 4023247 4027685 4032037 4072029 4073003 4118010 4120606 4133833 4136916 6274757 6314387 + * @bug 4023247 4027685 4032037 4072029 4073003 4118010 4120606 4133833 + * 4136916 6274757 6314387 8347841 * @run junit DateRegression */ @@ -106,7 +107,7 @@ public void Test4072029() { TimeZone saveZone = TimeZone.getDefault(); try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); Date now = new Date(); String s = now.toString(); Date now2 = new Date(now.toString()); diff --git a/test/jdk/java/util/Date/DateTest.java b/test/jdk/java/util/Date/DateTest.java index 6740cb16faa3f..7dbb19409d37a 100644 --- a/test/jdk/java/util/Date/DateTest.java +++ b/test/jdk/java/util/Date/DateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4143459 + * @bug 4143459 8347841 * @summary test Date * @run junit DateTest */ @@ -56,7 +56,7 @@ public void TestDefaultZoneLite() { d.setMonth(Calendar.JANUARY); d.setDate(1); d.setHours(6); - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); if (d.getHours() != 22) { fail("Fail: Date.setHours()/getHours() ignoring default zone"); } @@ -79,7 +79,7 @@ public void TestDefaultZone() { Date ref = new Date(883634400000L); // This is Thu Jan 1 1998 6:00 am GMT String refstr = "Jan 1 1998 6:00"; TimeZone GMT = TimeZone.getTimeZone("GMT"); - TimeZone PST = TimeZone.getTimeZone("PST"); + TimeZone PST = TimeZone.getTimeZone("America/Los_Angeles"); String[] names = { "year", "month", "date", "day of week", "hour", "offset" }; int[] GMT_EXP = { 98, Calendar.JANUARY, 1, Calendar.THURSDAY - Calendar.SUNDAY, 6, 0 }; @@ -207,7 +207,7 @@ public void TestDate480() { TimeZone save = TimeZone.getDefault(); try { - TimeZone.setDefault(TimeZone.getTimeZone("PST")); + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); Date d1=new java.util.Date(97,8,13,10,8,13); System.out.println("d = "+d1); Date d2=new java.util.Date(97,8,13,30,8,13); // 20 hours later diff --git a/test/jdk/java/util/Locale/LRToString.java b/test/jdk/java/util/Locale/LRToString.java deleted file mode 100644 index 229507b71b30f..0000000000000 --- a/test/jdk/java/util/Locale/LRToString.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8026766 - * @summary Confirm that LanguageRange.toString() returns an expected result. - * @run junit LRToString - */ - -import java.util.Locale.LanguageRange; -import java.util.stream.Stream; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class LRToString { - - /** - * This test ensures that the output of LanguageRange.toString() - * returns an expected result, that is, the weight is hidden if it is - * equal to 1.0. - */ - @ParameterizedTest - @MethodSource("ranges") - public void toStringTest(String range, double weight) { - LanguageRange lr = new LanguageRange(range, weight); - String expected = weight == 1.0 - ? range - : range+";q="+weight; - assertEquals(lr.toString(), expected); - } - - private static Stream ranges() { - return Stream.of( - Arguments.of("ja", 1.0), - Arguments.of("de", 0.5), - Arguments.of("fr", 0.0) - ); - } -} diff --git a/test/jdk/java/util/Locale/LanguageRangeTest.java b/test/jdk/java/util/Locale/LanguageRangeTest.java index cb0dd9fda66db..d269cb9dc1576 100644 --- a/test/jdk/java/util/Locale/LanguageRangeTest.java +++ b/test/jdk/java/util/Locale/LanguageRangeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,21 +20,62 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/** + +/* * @test - * @bug 8253321 - * @summary test LanguageRange class - * @run testng LanguageRangeTest + * @bug 8026766 8253321 8349883 + * @summary LanguageRange tests: toString(), hashCode()/equals(), checking + * for IAE on ill-formed ranges + * @run junit LanguageRangeTest */ import static java.util.Locale.LanguageRange; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.HashMap; +import java.util.Locale; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; -@Test public class LanguageRangeTest { + // 8349883: Test endpoints w/ ill-formed language range fail with IAE + @ParameterizedTest + @MethodSource("illegalRanges") + public void illformedRangeTest(String range) { + // static parses + assertThrows(IllegalArgumentException.class, + () -> Locale.LanguageRange.parse(range)); + assertThrows(IllegalArgumentException.class, + () -> Locale.LanguageRange.parse(range, new HashMap<>())); + // ctors + assertThrows(IllegalArgumentException.class, + () -> new Locale.LanguageRange(range)); + assertThrows(IllegalArgumentException.class, + () -> new Locale.LanguageRange(range, Locale.LanguageRange.MIN_WEIGHT)); + } + + private static Stream illegalRanges() { + return Stream.of( + // 8349883 offending range + "-", + // Other general ill-formed test cases + "-foo", + "foo-", + "foo1", + "foo-123456789", + "*-*-", + "" + ); + } + + // 8253321: Ensure invoking hashCode does not affect equals result @Test public void hashCodeTest() { var range1 = new LanguageRange("en-GB", 0); @@ -45,4 +86,23 @@ public void hashCodeTest() { range2.hashCode(); assertEquals(range1, range2); } + + // 8026766: toString() should hide weight if equal to MAX_WEIGHT (1.0) + @ParameterizedTest + @MethodSource("ranges") + public void toStringTest(String range, double weight) { + LanguageRange lr = new LanguageRange(range, weight); + String expected = weight == 1.0 + ? range + : range+";q="+weight; + assertEquals(lr.toString(), expected); + } + + private static Stream ranges() { + return Stream.of( + Arguments.of("ja", 1.0), + Arguments.of("de", 0.5), + Arguments.of("fr", 0.0) + ); + } } diff --git a/test/jdk/java/util/PluggableLocale/TimeZoneNameProviderTest.java b/test/jdk/java/util/PluggableLocale/TimeZoneNameProviderTest.java index 5a8463cbfdeb7..288034729e1c5 100644 --- a/test/jdk/java/util/PluggableLocale/TimeZoneNameProviderTest.java +++ b/test/jdk/java/util/PluggableLocale/TimeZoneNameProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4052440 8003267 8062588 8210406 8174269 8327434 + * @bug 4052440 8003267 8062588 8210406 8174269 8327434 8347841 8347955 * @summary TimeZoneNameProvider tests * @library providersrc/foobarutils * providersrc/barprovider @@ -37,6 +37,7 @@ import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.ZoneId; import java.time.format.TextStyle; import java.util.Arrays; import java.util.Calendar; @@ -45,6 +46,7 @@ import java.util.Locale; import java.util.MissingResourceException; import java.util.TimeZone; +import java.util.function.Predicate; import java.util.stream.Stream; import com.bar.TimeZoneNameProviderImpl; @@ -72,7 +74,9 @@ public static void main(String[] s) { void test1() { List jreimplloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getTimeZoneNameProvider().getAvailableLocales()); List providerLocales = Arrays.asList(tznp.getAvailableLocales()); - String[] ids = TimeZone.getAvailableIDs(); + String[] ids = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); // Sampling relevant locales Stream.concat(Stream.of(Locale.ROOT, Locale.US, Locale.JAPAN), providerLocales.stream()).forEach(target -> { @@ -176,7 +180,7 @@ void test2() { df.parse(DISPLAY_NAMES_KYOTO[i]); } } catch (ParseException pe) { - throw new RuntimeException("parse error occured" + pe); + throw new RuntimeException("parse error occurred" + pe); } finally { // restore the reserved locale and time zone Locale.setDefault(defaultLocale); @@ -186,8 +190,8 @@ void test2() { void test3() { final String[] TZNAMES = { - LATIME, PST, PST8PDT, US_PACIFIC, - TOKYOTIME, JST, JAPAN, + LATIME, PST8PDT, US_PACIFIC, + TOKYOTIME, JAPAN, }; for (String tzname : TZNAMES) { TimeZone tz = TimeZone.getTimeZone(tzname); @@ -208,17 +212,13 @@ void test3() { } final String LATIME = "America/Los_Angeles"; - final String PST = "PST"; final String PST8PDT = "PST8PDT"; final String US_PACIFIC = "US/Pacific"; final String LATIME_IN_OSAKA = tznp.getDisplayName(LATIME, false, TimeZone.LONG, OSAKA); final String TOKYOTIME = "Asia/Tokyo"; - final String JST = "JST"; final String JAPAN = "Japan"; - final String JST_IN_OSAKA = - tznp.getDisplayName(JST, false, TimeZone.LONG, OSAKA); void aliasTest() { // Check that provider's name for a standard id (America/Los_Angeles) is @@ -228,32 +228,10 @@ void aliasTest() { throw new RuntimeException("Could not get provider's localized name. result: "+latime+" expected: "+LATIME_IN_OSAKA); } - String pst = TimeZone.getTimeZone(PST).getDisplayName(OSAKA); - if (!LATIME_IN_OSAKA.equals(pst)) { - throw new RuntimeException("Provider's localized name is not available for an alias ID: "+PST+". result: "+pst+" expected: "+LATIME_IN_OSAKA); - } - String us_pacific = TimeZone.getTimeZone(US_PACIFIC).getDisplayName(OSAKA); if (!LATIME_IN_OSAKA.equals(us_pacific)) { throw new RuntimeException("Provider's localized name is not available for an alias ID: "+US_PACIFIC+". result: "+us_pacific+" expected: "+LATIME_IN_OSAKA); } - - // Check that provider's name for an alias id (JST) is - // propagated to its standard id and alias ids. - String jstime = TimeZone.getTimeZone(JST).getDisplayName(OSAKA); - if (!JST_IN_OSAKA.equals(jstime)) { - throw new RuntimeException("Could not get provider's localized name. result: "+jstime+" expected: "+JST_IN_OSAKA); - } - - String tokyotime = TimeZone.getTimeZone(TOKYOTIME).getDisplayName(OSAKA); - if (!JST_IN_OSAKA.equals(tokyotime)) { - throw new RuntimeException("Provider's localized name is not available for a standard ID: "+TOKYOTIME+". result: "+tokyotime+" expected: "+JST_IN_OSAKA); - } - - String japan = TimeZone.getTimeZone(JAPAN).getDisplayName(OSAKA); - if (!JST_IN_OSAKA.equals(japan)) { - throw new RuntimeException("Provider's localized name is not available for an alias ID: "+JAPAN+". result: "+japan+" expected: "+JST_IN_OSAKA); - } } /* diff --git a/test/jdk/java/util/Properties/StoreDeadlock.java b/test/jdk/java/util/Properties/StoreDeadlock.java index d59a444525187..0eb3e930a81c3 100644 --- a/test/jdk/java/util/Properties/StoreDeadlock.java +++ b/test/jdk/java/util/Properties/StoreDeadlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6199320 + * @bug 6199320 8347841 * @summary Properties.store() causes deadlock when concurrently calling TimeZone apis * @run main/timeout=20 StoreDeadlock * @author Xueming Shen @@ -59,7 +59,7 @@ public void run() { } class Thread2 extends Thread { public void run() { - System.out.println("tz=" + TimeZone.getTimeZone("PST")); + System.out.println("tz=" + TimeZone.getTimeZone("America/Los_Angeles")); } } } diff --git a/test/jdk/java/util/TimeZone/AvailableIDsTest.java b/test/jdk/java/util/TimeZone/AvailableIDsTest.java new file mode 100644 index 0000000000000..3992e5be7bcf0 --- /dev/null +++ b/test/jdk/java/util/TimeZone/AvailableIDsTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347955 + * @summary Ensure underlying element equality of available tz ID methods + * @run junit AvailableIDsTest + */ + +import org.junit.jupiter.api.Test; + +import java.util.TimeZone; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +public class AvailableIDsTest { + + // Validate the equality of the array and stream of available IDs + @Test + public void streamEqualsArrayTest() { + String[] tzs = TimeZone.getAvailableIDs(); + assertArrayEquals(tzs, TimeZone.availableIDs().toArray(String[]::new), + "availableIDs() and getAvailableIDs() do not have the same elements"); + } + + // Validate the equality of the array and stream of available IDs + // when passed an offset. Tests various offsets. + @ParameterizedTest + @ValueSource(ints = {21600000, 25200000, 28800000}) // 6:00, 7:00, 8:00 + public void streamEqualsArrayWithOffsetTest(int offset) { + String[] tzs = TimeZone.getAvailableIDs(offset); + assertArrayEquals(tzs, TimeZone.availableIDs(offset).toArray(String[]::new), + "availableIDs(int) and getAvailableIDs(int) do not have the same elements"); + } +} diff --git a/test/jdk/java/util/TimeZone/Bug5097350.java b/test/jdk/java/util/TimeZone/Bug5097350.java index ff0894bf3d740..3c1083bbaa9b4 100644 --- a/test/jdk/java/util/TimeZone/Bug5097350.java +++ b/test/jdk/java/util/TimeZone/Bug5097350.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,19 @@ /* * @test - * @bug 5097350 + * @bug 5097350 8347841 8347955 * @summary Make sure that TimeZone.getTimeZone returns a clone of a cached TimeZone instance. */ +import java.time.ZoneId; import java.util.*; -import java.text.*; +import java.util.function.Predicate; public class Bug5097350 { public static void main(String[] args) { - String[] tzids = TimeZone.getAvailableIDs(); + String[] tzids = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); List ids = new ArrayList<>(tzids.length + 10); ids.addAll(Arrays.asList(tzids)); // add some custom ids diff --git a/test/jdk/java/util/TimeZone/Bug6329116.java b/test/jdk/java/util/TimeZone/Bug6329116.java index a79400990b253..4f6f5f27eac1b 100644 --- a/test/jdk/java/util/TimeZone/Bug6329116.java +++ b/test/jdk/java/util/TimeZone/Bug6329116.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,15 @@ * @test * @bug 6329116 6756569 6757131 6758988 6764308 6796489 6834474 6609737 6507067 * 7039469 7090843 7103108 7103405 7158483 8008577 8059206 8064560 8072042 - * 8077685 8151876 8166875 8169191 8170316 8176044 8174269 + * 8077685 8151876 8166875 8169191 8170316 8176044 8174269 8347841 8347955 * @summary Make sure that timezone short display names are identical to Olson's data. * @run junit Bug6329116 */ import java.io.*; +import java.time.ZoneId; import java.util.*; +import java.util.function.Predicate; import org.junit.jupiter.api.Test; @@ -44,7 +46,9 @@ public class Bug6329116 { // static Locale[] locales = Locale.getAvailableLocales(); static Locale[] locales = {Locale.US}; - static String[] timezones = TimeZone.getAvailableIDs(); + static String[] timezones = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); @Test public void bug6329116() throws IOException { @@ -101,6 +105,9 @@ public void bug6329116() throws IOException { tzs[0] = timezoneID; for (int j = 0; j < tzs.length; j++) { + if (ZoneId.SHORT_IDS.containsKey(tzs[j])) { + continue; + } tz = TimeZone.getTimeZone(tzs[j]); if (!tzs[j].equals(tz.getID())) { diff --git a/test/jdk/java/util/TimeZone/Bug6772689.java b/test/jdk/java/util/TimeZone/Bug6772689.java index f730567013d35..a69dfd9256387 100644 --- a/test/jdk/java/util/TimeZone/Bug6772689.java +++ b/test/jdk/java/util/TimeZone/Bug6772689.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,17 @@ /* * @test - * @bug 6772689 + * @bug 6772689 8347841 8347955 * @summary Test for standard-to-daylight transitions at midnight: * date stays on the given day. */ +import java.time.ZoneId; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; +import java.util.function.Predicate; import static java.util.GregorianCalendar.*; public class Bug6772689 { @@ -43,7 +45,9 @@ public static void main(String[] args) { int errors = 0; Calendar cal = new GregorianCalendar(BEGIN_YEAR, MARCH, 1); - String[] tzids = TimeZone.getAvailableIDs(); + String[] tzids = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); try { for (String id : tzids) { TimeZone tz = TimeZone.getTimeZone(id); diff --git a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java index 2ff278a583c33..c12004454076b 100644 --- a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java +++ b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ public static void main(String[] args) { String displayName = zi.getDisplayName(false, TimeZone.SHORT, Locale.US); Locale.setDefault(originalLocale); if (!displayName.equals("GMT+05:00")) { - System.err.printf("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName); + System.err.println("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName); errors++; } diff --git a/test/jdk/java/util/TimeZone/DaylightTimeTest.java b/test/jdk/java/util/TimeZone/DaylightTimeTest.java index 4b637136f96b2..1b8c1c221bd89 100644 --- a/test/jdk/java/util/TimeZone/DaylightTimeTest.java +++ b/test/jdk/java/util/TimeZone/DaylightTimeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,21 @@ /* * @test - * @bug 6936350 + * @bug 6936350 8347841 8347955 * @summary Test case for TimeZone.observesDaylightTime() */ +import java.time.ZoneId; import java.util.*; +import java.util.function.Predicate; import static java.util.GregorianCalendar.*; public class DaylightTimeTest { private static final int ONE_HOUR = 60 * 60 * 1000; // one hour private static final int INTERVAL = 24 * ONE_HOUR; // one day - private static final String[] ZONES = TimeZone.getAvailableIDs(); + private static final String[] ZONES = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); private static int errors = 0; public static void main(String[] args) { diff --git a/test/jdk/java/util/TimeZone/IDTest.java b/test/jdk/java/util/TimeZone/IDTest.java index d5396b619b8ea..aaa7c7f65c1eb 100644 --- a/test/jdk/java/util/TimeZone/IDTest.java +++ b/test/jdk/java/util/TimeZone/IDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,24 +23,30 @@ /* * @test - * @bug 4509255 5055567 6176318 7090844 + * @bug 4509255 5055567 6176318 7090844 8347841 8347955 * @summary Tests consistencies of time zone IDs. */ +import java.time.ZoneId; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.TreeMap; +import java.util.function.Predicate; public class IDTest { public static void main(String[] args) { Set ids = new HashSet<>(); Map> tree = new TreeMap<>(); - String[] tzs = TimeZone.getAvailableIDs(); - String[] tzs2 = TimeZone.getAvailableIDs(); + String[] tzs = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); + String[] tzs2 = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); if (tzs.length != tzs2.length) { throw new RuntimeException("tzs.length(" + tzs.length + ") != tzs2.length(" + tzs2.length + ")"); @@ -83,8 +89,12 @@ public static void main(String[] args) { // Check the getAvailableIDs(int) call to return the same // set of IDs int offset = key.intValue(); - tzs = TimeZone.getAvailableIDs(offset); - tzs2 = TimeZone.getAvailableIDs(offset); + tzs = TimeZone.availableIDs(offset) + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); + tzs2 = TimeZone.availableIDs(offset) + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); if (!Arrays.equals(tzs, tzs2)) { throw new RuntimeException("inconsistent tzs from getAvailableIDs("+offset+")"); } diff --git a/test/jdk/java/util/TimeZone/ListTimeZones.java b/test/jdk/java/util/TimeZone/ListTimeZones.java index 7dd309473e641..01d3bc771c58d 100644 --- a/test/jdk/java/util/TimeZone/ListTimeZones.java +++ b/test/jdk/java/util/TimeZone/ListTimeZones.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,21 @@ /** * @test - * @bug 6851214 + * @bug 6851214 8347841 8347955 * @summary Allow 24:00 as a valid end/start DST time stamp * @run main ListTimeZones */ +import java.time.ZoneId; import java.util.*; +import java.util.function.Predicate; public class ListTimeZones{ public static void main(String[] args){ Date date = new Date(); - String TimeZoneIds[] = TimeZone.getAvailableIDs(); + String[] TimeZoneIds = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); for(int i = 0; i < TimeZoneIds.length; i++){ TimeZone tz = TimeZone.getTimeZone(TimeZoneIds[i]); Calendar calendar = new GregorianCalendar(tz); diff --git a/test/jdk/java/util/TimeZone/ThreeLetterZoneID.java b/test/jdk/java/util/TimeZone/ThreeLetterZoneID.java new file mode 100644 index 0000000000000..02b4d89ce2b2e --- /dev/null +++ b/test/jdk/java/util/TimeZone/ThreeLetterZoneID.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8342550 8349873 + * @summary Three-letter time zone IDs should output a deprecated warning + * message. + * @library /test/lib + * @build jdk.test.lib.process.ProcessTools + * @run junit ThreeLetterZoneID + */ +import java.util.TimeZone; +import jdk.test.lib.process.ProcessTools; + +import org.junit.jupiter.api.Test; + +public class ThreeLetterZoneID { + private static final String WARNING = + "WARNING: Use of the three-letter time zone ID \"PST\" is deprecated and it will be removed in a future release"; + + public static void main(String... args) { + if (args.length > 0) { + TimeZone.getTimeZone("PST"); + } else { + TimeZone.getDefault(); + } + } + + @Test + public void testExplicitGetTimeZone() throws Exception { + ProcessTools.executeTestJava("ThreeLetterZoneID", "dummy").stderrShouldMatch(WARNING); + } + + @Test + public void testSysProp() throws Exception { + ProcessTools.executeTestJava("-Duser.timezone=PST", "ThreeLetterZoneID").stderrShouldMatch(WARNING); + } +} diff --git a/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java b/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java index c70ccc204de55..9e4ca02731d3b 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java +++ b/test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @bug 8347841 * @summary test Time Zone Boundary * @run junit TimeZoneBoundaryTest */ @@ -251,7 +252,7 @@ void verifyDST(Date d, TimeZone time_zone, @Test public void TestBoundaries() { - TimeZone pst = TimeZone.getTimeZone("PST"); + TimeZone pst = TimeZone.getTimeZone("America/Los_Angeles"); TimeZone save = TimeZone.getDefault(); try { TimeZone.setDefault(pst); @@ -410,11 +411,8 @@ else if (!z.useDaylightTime()) @Test public void TestStepwise() { - findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0); - // "EST" is disabled because its behavior depends on the mapping property. (6466476). - //findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("EST"), 2); - findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("HST"), 0); - findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST"), 2); + findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Australia/Darwin"), 0); + findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Pacific/Honolulu"), 0); findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST8PDT"), 2); findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST"), 0); findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST8PDT"), 2); diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION index f40be22e9abc1..5159b3786e385 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION +++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION @@ -1 +1 @@ -tzdata2024b +tzdata2025a diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt index 3217f68b82578..c8d855453c27f 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt +++ b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt @@ -1,6 +1,3 @@ -Link Asia/Riyadh87 Mideast/Riyadh87 -Link Asia/Riyadh88 Mideast/Riyadh88 -Link Asia/Riyadh89 Mideast/Riyadh89 Link Australia/Sydney Australia/ACT #= Australia/Canberra Link Australia/Lord_Howe Australia/LHI Link Australia/Sydney Australia/NSW diff --git a/test/jdk/java/util/TimeZone/TimeZoneRegression.java b/test/jdk/java/util/TimeZone/TimeZoneRegression.java index ca539336dae64..241afd3f7cf71 100644 --- a/test/jdk/java/util/TimeZone/TimeZoneRegression.java +++ b/test/jdk/java/util/TimeZone/TimeZoneRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429 * 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960 - * 4966229 6433179 6851214 8007520 8008577 8174269 + * 4966229 6433179 6851214 8007520 8008577 8174269 8347841 * @library /java/text/testlib * @run junit TimeZoneRegression */ @@ -42,8 +42,8 @@ public class TimeZoneRegression { @Test public void Test4073209() { - TimeZone z1 = TimeZone.getTimeZone("PST"); - TimeZone z2 = TimeZone.getTimeZone("PST"); + TimeZone z1 = TimeZone.getTimeZone("America/Los_Angeles"); + TimeZone z2 = TimeZone.getTimeZone("America/Los_Angeles"); if (z1 == z2) { fail("Fail: TimeZone should return clones"); } @@ -81,7 +81,7 @@ public void Test4084933() { // test both SimpleTimeZone and ZoneInfo objects. // @since 1.4 sub4084933(getPST()); - sub4084933(TimeZone.getTimeZone("PST")); + sub4084933(TimeZone.getTimeZone("America/Los_Angeles")); } private void sub4084933(TimeZone tz) { @@ -122,7 +122,7 @@ private void sub4084933(TimeZone tz) { @Test public void Test4096952() { - String[] ZONES = { "GMT", "MET", "IST" }; + String[] ZONES = { "GMT", "MET", "Asia/Kolkata" }; boolean pass = true; try { for (int i=0; i future = executor.submit(barrier::arriveAndAwaitAdvance); + var started = new CountDownLatch(1); + var stop = new CountDownLatch(1); + Future future = executor.submit(() -> { + started.countDown(); + stop.await(); + return null; + }); + started.await(); + try { + executor.shutdown(); + assertFalse(executor.awaitTermination(1, TimeUnit.SECONDS)); + assertFalse(future.isDone()); + } finally { + stop.countDown(); + } + assertTrue(executor.awaitTermination(1, TimeUnit.MINUTES)); + assertTrue(future.isDone()); + } + + /** + * Test awaitTermination with cancelled task still running. + */ + @ParameterizedTest + @MethodSource("executors") + void testAwaitTermination3(ExecutorService executor) throws Exception { + var started = new CountDownLatch(1); + var stop = new CountDownLatch(1); + Future future = executor.submit(() -> { + started.countDown(); + stop.await(); + return null; + }); + started.await(); try { + future.cancel(false); executor.shutdown(); - assertFalse(executor.awaitTermination(100, TimeUnit.MILLISECONDS)); - barrier.arriveAndAwaitAdvance(); - assertTrue(executor.awaitTermination(10, TimeUnit.SECONDS)); + assertFalse(executor.awaitTermination(1, TimeUnit.SECONDS)); } finally { - future.cancel(true); + stop.countDown(); } + assertTrue(executor.awaitTermination(1, TimeUnit.MINUTES)); + } + + /** + * Test awaitTermination with cancelled task that may not have started execution. + */ + @ParameterizedTest + @MethodSource("executors") + void testAwaitTermination4(ExecutorService executor) throws Exception { + Future future = executor.submit(() -> { + Thread.sleep(Duration.ofMillis(50)); + return null; + }); + future.cancel(false); + executor.shutdown(); + assertTrue(executor.awaitTermination(1, TimeUnit.MINUTES)); } /** diff --git a/test/jdk/java/util/concurrent/locks/Lock/OOMEInAQS.java b/test/jdk/java/util/concurrent/locks/Lock/OOMEInAQS.java index 5a78d2791fe6d..aee6c3617c896 100644 --- a/test/jdk/java/util/concurrent/locks/Lock/OOMEInAQS.java +++ b/test/jdk/java/util/concurrent/locks/Lock/OOMEInAQS.java @@ -39,6 +39,7 @@ * @bug 8066859 * @summary Check that AQS-based locks, conditions, and CountDownLatches do not fail when encountering OOME * @requires vm.gc.G1 + * @requires !(vm.graal.enabled & vm.compMode == "Xcomp") * @run main/othervm -XX:+UseG1GC -XX:-UseGCOverheadLimit -Xmx48M -XX:-UseTLAB OOMEInAQS */ diff --git a/test/jdk/java/util/concurrent/locks/StampedLock/OOMEInStampedLock.java b/test/jdk/java/util/concurrent/locks/StampedLock/OOMEInStampedLock.java index 2346ad39fc465..32b77205163c9 100644 --- a/test/jdk/java/util/concurrent/locks/StampedLock/OOMEInStampedLock.java +++ b/test/jdk/java/util/concurrent/locks/StampedLock/OOMEInStampedLock.java @@ -38,6 +38,7 @@ * @bug 8066859 * @summary An adaptation of OOMEInAQS test for StampedLocks * @requires vm.gc.G1 + * @requires !(vm.graal.enabled & vm.compMode == "Xcomp") * @run main/othervm -XX:+UseG1GC -XX:-UseGCOverheadLimit -Xmx48M -XX:-UseTLAB OOMEInStampedLock */ diff --git a/test/jdk/java/util/stream/GatherersMapConcurrentTest.java b/test/jdk/java/util/stream/GatherersMapConcurrentTest.java index 557598de3eece..970a550400aa6 100644 --- a/test/jdk/java/util/stream/GatherersMapConcurrentTest.java +++ b/test/jdk/java/util/stream/GatherersMapConcurrentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,9 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.LockSupport; +import java.util.function.Function; import java.util.stream.Gatherer; import java.util.stream.Gatherers; import java.util.stream.Stream; @@ -298,7 +301,7 @@ public void behavesAsExpected(ConcurrencyConfig cc) { @ParameterizedTest @MethodSource("concurrencyConfigurations") - public void behavesAsExpectedWhenShortCircuited(ConcurrencyConfig cc) { + public void shortCircuits(ConcurrencyConfig cc) { final var limitTo = Math.max(cc.config().streamSize() / 2, 1); final var expectedResult = cc.config().stream() @@ -313,4 +316,60 @@ public void behavesAsExpectedWhenShortCircuited(ConcurrencyConfig cc) { assertEquals(expectedResult, result); } + + @ParameterizedTest + @MethodSource("concurrencyConfigurations") + public void ignoresAndRestoresCallingThreadInterruption(ConcurrencyConfig cc) { + final var limitTo = Math.max(cc.config().streamSize() / 2, 1); + + final var expectedResult = cc.config().stream() + .map(x -> x * x) + .limit(limitTo) + .toList(); + + // Ensure calling thread is interrupted + Thread.currentThread().interrupt(); + + final var result = cc.config().stream() + .gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> { + LockSupport.parkNanos(10000); // 10 us + return x * x; + })) + .limit(limitTo) + .toList(); + + // Ensure calling thread remains interrupted + assertEquals(true, Thread.interrupted()); + + assertEquals(expectedResult, result); + } + + @ParameterizedTest + @MethodSource("concurrencyConfigurations") + public void limitsWorkInProgressToMaxConcurrency(ConcurrencyConfig cc) { + final var elementNum = new AtomicLong(0); + final var wipCount = new AtomicLong(0); + final var limitTo = Math.max(cc.config().streamSize() / 2, 1); + + final var expectedResult = cc.config().stream() + .map(x -> x * x) + .limit(limitTo) + .toList(); + + Function fun = x -> { + if (wipCount.incrementAndGet() > cc.concurrencyLevel) + throw new IllegalStateException("Too much wip!"); + if (elementNum.getAndIncrement() == 0) + LockSupport.parkNanos(500_000_000); // 500 ms + return x * x; + }; + + final var result = cc.config().stream() + .gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), fun)) + .gather(Gatherer.of((v, e, d) -> wipCount.decrementAndGet() >= 0 && d.push(e))) + .limit(limitTo) + .toList(); + + assertEquals(expectedResult, result); + } } diff --git a/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java b/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java index b8f91971060a5..5c6732503f53a 100644 --- a/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java +++ b/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,8 +127,8 @@ public void testGZip(boolean useCloseMethod) throws IOException { gzip.finish(); } }); - // Write on a closed GZIPOutputStream, closed Deflater IOException expected - assertThrows(NullPointerException.class , () -> gzip.write(inputBytes, 0, INPUT_LENGTH)); + // Write on a closed GZIPOutputStream, closed Deflater IllegalStateException expected + assertThrows(IllegalStateException.class , () -> gzip.write(inputBytes, 0, INPUT_LENGTH)); } /** @@ -149,8 +149,8 @@ public void testDeflaterOutputStream(boolean useCloseMethod) throws IOException def.finish(); } }); - // Write on a closed DeflaterOutputStream, 'Deflater has been closed' NPE is expected - assertThrows(NullPointerException.class , () -> def.write(inputBytes, 0, INPUT_LENGTH)); + // Write on a closed DeflaterOutputStream, IllegalStateException is expected + assertThrows(IllegalStateException.class , () -> def.write(inputBytes, 0, INPUT_LENGTH)); } /** @@ -202,8 +202,8 @@ public void testZipCloseEntry(ZipOutputStream zip) throws IOException { assertThrows(IOException.class , () -> zip.putNextEntry(new ZipEntry(""))); zip.write(inputBytes, 0, INPUT_LENGTH); assertThrows(IOException.class , () -> zip.closeEntry()); - // Write on a closed ZipOutputStream , 'Deflater has been closed' NPE is expected - assertThrows(NullPointerException.class , () -> zip.write(inputBytes, 0, INPUT_LENGTH)); + // Write on a closed ZipOutputStream , IllegalStateException is expected + assertThrows(IllegalStateException.class , () -> zip.write(inputBytes, 0, INPUT_LENGTH)); } } diff --git a/test/jdk/java/util/zip/DeflaterClose.java b/test/jdk/java/util/zip/DeflaterClose.java new file mode 100644 index 0000000000000..a4c4b233b4ec5 --- /dev/null +++ b/test/jdk/java/util/zip/DeflaterClose.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.zip.Deflater; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/* + * @test + * @bug 8225763 + * @summary Test that the close() and end() methods on java.util.zip.Deflater + * @run junit DeflaterClose + */ +public class DeflaterClose { + + private static final String data = "foobarhelloworld!!!!"; + + /** + * Closes the Deflater multiple times and then expects close() and end() each + * to be called that many times. + */ + @Test + public void testCloseMultipleTimes() throws Exception { + final int numTimes = 3; + final Deflater simpleDeflater = new Deflater(); + closeMultipleTimesAfterCompressing(numTimes, simpleDeflater); + + final OverrideClose overriddenClose = new OverrideClose(); + closeMultipleTimesAfterCompressing(numTimes, overriddenClose); + // make sure close was called numTimes + assertEquals(numTimes, overriddenClose.numTimesCloseCalled, "close() was expected to be" + + " called " + numTimes + ", but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + closeMultipleTimesAfterCompressing(numTimes, overriddenEnd); + // make sure end was called called numTimes + assertEquals(numTimes, overriddenEnd.numTimesEndCalled, "end() was expected to be called " + + numTimes + ", but was called " + overriddenEnd.numTimesEndCalled + " time(s) on " + + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + closeMultipleTimesAfterCompressing(numTimes, overriddenCloseAndEnd); + // make sure end was called called numTimes + assertEquals(numTimes, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected to be called " + + numTimes + ", but was called" + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(numTimes, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected" + + " to be called " + numTimes + ", but was called " + + overriddenClose.numTimesCloseCalled + " time(s) on " + + overriddenCloseAndEnd.getClass().getName()); + } + + /** + * Closes the Deflater first and then calls end(). Verifies that close() was called + * just once but end() was called twice (once internally through close() and once + * explicitly) + */ + @Test + public void testCloseThenEnd() throws Exception { + final Deflater simpleDeflater = new Deflater(); + compressCloseThenEnd(simpleDeflater); + + final OverrideClose overriddenClose = new OverrideClose(); + compressCloseThenEnd(overriddenClose); + // make sure close was called once + assertEquals(1, overriddenClose.numTimesCloseCalled, "close() was expected to be called" + + " once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + compressCloseThenEnd(overriddenEnd); + // make sure end was called twice (once through close() and then explicitly) + assertEquals(2, overriddenEnd.numTimesEndCalled, "end() was expected to be called" + + " twice, but was called " + overriddenEnd.numTimesEndCalled + + " time(s) on " + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + compressCloseThenEnd(overriddenCloseAndEnd); + // make sure end was called twice (once through close and once explicitly) + // and close was called once + assertEquals(2, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected to" + + " be called twice, but was called " + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(1, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected to be" + + " called once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + } + + /** + * Calls end() on the Deflater first and then calls close(). Verifies that close() was called + * just once and end() twice. + */ + @Test + public void testEndThenClose() throws Exception { + final Deflater simpleDeflater = new Deflater(); + compressEndThenClose(simpleDeflater); + + final OverrideClose overriddenClose = new OverrideClose(); + compressEndThenClose(overriddenClose); + // make sure close was called once + assertEquals(1, overriddenClose.numTimesCloseCalled, "close() was expected to be called" + + " once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + compressEndThenClose(overriddenEnd); + // make sure end was called twice (once through the explicit end call and + // once through close()) + assertEquals(2, overriddenEnd.numTimesEndCalled, "end() was expected to be called twice," + + " but was called " + overriddenEnd.numTimesEndCalled + + " time(s) on " + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + compressEndThenClose(overriddenCloseAndEnd); + // make sure end was called twice (once through the explicit end call and + // once through close()) + assertEquals(2, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected to be called" + + " twice, but was called " + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(1, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected to be " + + "called once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + } + + private void closeMultipleTimesAfterCompressing(final int numTimes, final Deflater deflater) { + compress(deflater); + // call close() multiple times + for (int i = 0; i < numTimes; i++) { + deflater.close(); + } + } + + private void compressCloseThenEnd(final Deflater deflater) { + // compress the data then close() and then end() + try (final Deflater compressor = deflater) { + compress(compressor); + } + deflater.end(); + } + + private void compressEndThenClose(final Deflater deflater) { + // compress the data then end() and then close() + try (final Deflater compressor = deflater) { + compress(compressor); + // end() it first before it's (auto)closed by the try-with-resources + compressor.end(); + } + } + + private static byte[] compress(final Deflater deflater) { + deflater.setInput(data.getBytes(StandardCharsets.UTF_8)); + deflater.finish(); + final ByteArrayOutputStream compressedBaos = new ByteArrayOutputStream(); + while (!deflater.finished()) { + final byte[] tmpBuffer = new byte[100]; + final int numCompressed = deflater.deflate(tmpBuffer); + compressedBaos.write(tmpBuffer, 0, numCompressed); + } + return compressedBaos.toByteArray(); + } + + private static final class OverrideEnd extends Deflater { + private int numTimesEndCalled = 0; + + @Override + public void end() { + this.numTimesEndCalled++; + super.end(); + } + } + + private static final class OverrideClose extends Deflater { + private int numTimesCloseCalled = 0; + + @Override + public void close() { + this.numTimesCloseCalled++; + super.close(); + } + } + + private static final class OverrideCloseAndEnd extends Deflater { + private int numTimesEndCalled = 0; + private int numTimesCloseCalled = 0; + + @Override + public void end() { + this.numTimesEndCalled++; + super.end(); + } + + @Override + public void close() { + this.numTimesCloseCalled++; + super.close(); + } + } +} \ No newline at end of file diff --git a/test/jdk/java/util/zip/EntryCount64k.java b/test/jdk/java/util/zip/EntryCount64k.java index d8c46d2236433..8830a87ea647b 100644 --- a/test/jdk/java/util/zip/EntryCount64k.java +++ b/test/jdk/java/util/zip/EntryCount64k.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2013 Google Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,9 +48,12 @@ import jdk.test.lib.process.ProcessTools; public class EntryCount64k { + + private static final String MAIN_CLASS_MSG = "foo bar hello world Main"; + public static class Main { public static void main(String[] args) { - System.out.print("Main"); + System.out.println(MAIN_CLASS_MSG); } } @@ -162,7 +166,10 @@ static void checkCanRead(File zipFile, int entryCount) throws Throwable { // Check java -jar OutputAnalyzer a = ProcessTools.executeTestJava("-jar", zipFile.getName()); a.shouldHaveExitValue(0); - a.stdoutShouldMatch("\\AMain\\Z"); + // expect the message from the application on stdout + a.stdoutContains(MAIN_CLASS_MSG); + // nothing is expected on stderr (apart from any probable deprecation + // warnings from the launcher/JVM) a.stderrShouldMatchIgnoreDeprecatedWarnings("\\A\\Z"); } } diff --git a/test/jdk/java/util/zip/InflaterClose.java b/test/jdk/java/util/zip/InflaterClose.java new file mode 100644 index 0000000000000..7c0e1606aded0 --- /dev/null +++ b/test/jdk/java/util/zip/InflaterClose.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +import org.junit.jupiter.api.Test; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/* + * @test + * @bug 8225763 + * @summary Test that the close() and end() methods on java.util.zip.Inflater + * @run junit InflaterClose + */ +public class InflaterClose { + + private static final String originalStr = "foobarhelloworld!!!!"; + private static final byte[] originalBytes = originalStr.getBytes(US_ASCII); + private static final byte[] compressedData = compress(); + + /** + * Closes the Inflater multiple times and then expects close() and end() to be called that + * many times. + */ + @Test + public void testCloseMultipleTimes() throws Exception { + final int numTimes = 3; + final Inflater simpleInflater = new Inflater(); + final String inflatedData = closeMultipleTimesAfterInflating(numTimes, simpleInflater); + assertValidInflatedData(inflatedData, simpleInflater.getClass()); + + final OverrideClose overriddenClose = new OverrideClose(); + final String ocInflatedData = closeMultipleTimesAfterInflating(numTimes, overriddenClose); + assertValidInflatedData(ocInflatedData, overriddenClose.getClass()); + // make sure close was called numTimes + assertEquals(numTimes, overriddenClose.numTimesCloseCalled, "close() was expected to be" + + " called " + numTimes + ", but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + final String oeInflatedData = closeMultipleTimesAfterInflating(numTimes, overriddenEnd); + assertValidInflatedData(oeInflatedData, overriddenEnd.getClass()); + // make sure end was called called numTimes + assertEquals(numTimes, overriddenEnd.numTimesEndCalled, "end() was expected to be called " + + numTimes + ", but was called " + overriddenEnd.numTimesEndCalled + " time(s) on " + + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + final String oceInflatedData = closeMultipleTimesAfterInflating(numTimes, + overriddenCloseAndEnd); + assertValidInflatedData(oceInflatedData, overriddenCloseAndEnd.getClass()); + // make sure end was called called numTimes + assertEquals(numTimes, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected" + + " to be called " + numTimes + ", but was called " + + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(numTimes, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected" + + " to be called " + numTimes + ", but was called " + + overriddenCloseAndEnd.numTimesCloseCalled + " time(s) on " + + overriddenCloseAndEnd.getClass().getName()); + } + + /** + * Closes the Inflater first and then calls end(). Verifies that close() was called + * just once but end() was called twice (once internally through close() and once + * explicitly) + */ + @Test + public void testCloseThenEnd() throws Exception { + final Inflater simpleInflater = new Inflater(); + final String inflatedData = inflateCloseThenEnd(simpleInflater); + assertValidInflatedData(inflatedData, simpleInflater.getClass()); + + final OverrideClose overriddenClose = new OverrideClose(); + final String ocInflatedData = inflateCloseThenEnd(overriddenClose); + assertValidInflatedData(ocInflatedData, overriddenClose.getClass()); + // make sure close was called once + assertEquals(1, overriddenClose.numTimesCloseCalled, "close() was expected to be called" + + " once, but was called " + overriddenClose.numTimesCloseCalled + " time(s) on " + + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + final String oeInflatedData = inflateCloseThenEnd(overriddenEnd); + assertValidInflatedData(oeInflatedData, overriddenEnd.getClass()); + // make sure end was called twice (once through close() and then explicitly) + assertEquals(2, overriddenEnd.numTimesEndCalled, "end() was expected to be called twice," + + " but was called " + overriddenEnd.numTimesEndCalled + " time(s) on " + + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + final String oceInflatedData = inflateCloseThenEnd(overriddenCloseAndEnd); + assertValidInflatedData(oceInflatedData, overriddenCloseAndEnd.getClass()); + // make sure end was called twice (once through close and once explicitly) + // and close was called once + assertEquals(2, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected to be called" + + " twice, but was called " + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(1, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected to be" + + " called once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + } + + /** + * Calls end() on the Inflater first and then calls close(). Verifies that close() was called + * just once and end() twice. + */ + @Test + public void testEndThenClose() throws Exception { + final Inflater simpleInflater = new Inflater(); + final String inflatedData = inflateThenEndThenClose(simpleInflater); + assertValidInflatedData(inflatedData, simpleInflater.getClass()); + + final OverrideClose overriddenClose = new OverrideClose(); + final String ocInflatedData = inflateThenEndThenClose(overriddenClose); + assertValidInflatedData(ocInflatedData, overriddenClose.getClass()); + // make sure close was called once + assertEquals(1, overriddenClose.numTimesCloseCalled, "close() was expected to be" + + " called once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenClose.getClass().getName()); + + final OverrideEnd overriddenEnd = new OverrideEnd(); + final String oeInflatedData = inflateThenEndThenClose(overriddenEnd); + assertValidInflatedData(oeInflatedData, overriddenEnd.getClass()); + // make sure end was called twice (once through the explicit end call and + // once through close()) + assertEquals(2, overriddenEnd.numTimesEndCalled, "end() was expected to be called twice," + + " but was called " + overriddenEnd.numTimesEndCalled + " time(s) on " + + overriddenEnd.getClass().getName()); + + final OverrideCloseAndEnd overriddenCloseAndEnd = new OverrideCloseAndEnd(); + final String oceInflatedData = inflateThenEndThenClose(overriddenCloseAndEnd); + assertValidInflatedData(oceInflatedData, overriddenCloseAndEnd.getClass()); + // make sure end was called twice (once through the explicit end call and + // once through close()) + assertEquals(2, overriddenCloseAndEnd.numTimesEndCalled, "end() was expected to be called" + + " twice, but was called " + overriddenCloseAndEnd.numTimesEndCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + assertEquals(1, overriddenCloseAndEnd.numTimesCloseCalled, "close() was expected to be" + + " called once, but was called " + overriddenClose.numTimesCloseCalled + + " time(s) on " + overriddenCloseAndEnd.getClass().getName()); + } + + + private String closeMultipleTimesAfterInflating(final int numTimes, final Inflater inflater) + throws DataFormatException { + // inflate() then call close() multiple times + final byte[] inflatedData = inflate(inflater, compressedData); + // call close() + for (int i = 0; i < numTimes; i++) { + inflater.close(); + } + return new String(inflatedData, StandardCharsets.UTF_8); + } + + private String inflateCloseThenEnd(final Inflater inflater) throws Exception { + final byte[] inflatedData; + // inflate then close() and then end() + try (final Inflater inflt = inflater) { + inflatedData = inflate(inflt, compressedData); + } + // end() the already closed inflater + inflater.end(); + return new String(inflatedData, StandardCharsets.UTF_8); + } + + private String inflateThenEndThenClose(final Inflater inflater) throws Exception { + final byte[] inflatedData; + // inflate then end() and then close() + try (final Inflater inflt = inflater) { + inflatedData = inflate(inflt, compressedData); + // end() it first before it's (auto)closed by the try-with-resources + inflt.end(); + } + return new String(inflatedData, StandardCharsets.UTF_8); + } + + private static byte[] inflate(final Inflater inflater, final byte[] compressedData) + throws DataFormatException { + final ByteArrayOutputStream inflatedData = new ByteArrayOutputStream(); + inflater.setInput(compressedData); + while (!inflater.finished()) { + byte[] tmpBuffer = new byte[100]; + final int numDecompressed = inflater.inflate(tmpBuffer); + inflatedData.write(tmpBuffer, 0, numDecompressed); + } + return inflatedData.toByteArray(); + } + + private static byte[] compress() { + final ByteArrayOutputStream compressedBaos = new ByteArrayOutputStream(); + try (final Deflater deflater = new Deflater()) { + deflater.setInput(originalBytes); + deflater.finish(); + while (!deflater.finished()) { + final byte[] tmpBuffer = new byte[100]; + final int numCompressed = deflater.deflate(tmpBuffer); + compressedBaos.write(tmpBuffer, 0, numCompressed); + } + } + return compressedBaos.toByteArray(); + } + + private static void assertValidInflatedData(final String inflatedData, + final Class inflaterType) { + assertEquals(originalStr, inflatedData, "Unexpected inflated data " + inflatedData + + " generated by " + inflaterType.getName() + ", expected " + originalStr); + } + + private static final class OverrideEnd extends Inflater { + private int numTimesEndCalled = 0; + + @Override + public void end() { + this.numTimesEndCalled++; + super.end(); + } + } + + private static final class OverrideClose extends Inflater { + private int numTimesCloseCalled = 0; + + @Override + public void close() { + this.numTimesCloseCalled++; + super.close(); + } + } + + private static final class OverrideCloseAndEnd extends Inflater { + private int numTimesEndCalled = 0; + private int numTimesCloseCalled = 0; + + @Override + public void end() { + this.numTimesEndCalled++; + super.end(); + } + + @Override + public void close() { + this.numTimesCloseCalled++; + super.close(); + } + } +} \ No newline at end of file diff --git a/test/jdk/java/util/zip/TotalInOut.java b/test/jdk/java/util/zip/TotalInOut.java index c7f22a63b31aa..92ab981def851 100644 --- a/test/jdk/java/util/zip/TotalInOut.java +++ b/test/jdk/java/util/zip/TotalInOut.java @@ -27,7 +27,7 @@ * @key randomness */ -import java.io.*; + import java.util.*; import java.util.zip.*; @@ -40,39 +40,40 @@ static void realMain (String[] args) throws Throwable { if (args.length > 0 && "large".equals(args[0])) dataSize = 5L * 1024L * 1024L * 1024L; // 5GB - Deflater deflater = new Deflater(); - Inflater inflater = new Inflater(); + try (final Deflater deflater = new Deflater(); + final Inflater inflater = new Inflater()) { - byte[] dataIn = new byte[BUF_SIZE]; - byte[] dataOut = new byte[BUF_SIZE]; - byte[] tmp = new byte[BUF_SIZE]; + byte[] dataIn = new byte[BUF_SIZE]; + byte[] dataOut = new byte[BUF_SIZE]; + byte[] tmp = new byte[BUF_SIZE]; - Random r = new Random(); - r.nextBytes(dataIn); - long bytesReadDef = 0; - long bytesWrittenDef = 0; - long bytesReadInf = 0; - long bytesWrittenInf = 0; + Random r = new Random(); + r.nextBytes(dataIn); + long bytesReadDef = 0; + long bytesWrittenDef = 0; + long bytesReadInf = 0; + long bytesWrittenInf = 0; - deflater.setInput(dataIn, 0, dataIn.length); - while (bytesReadDef < dataSize || bytesWrittenInf < dataSize) { - int len = r.nextInt(BUF_SIZE/2) + BUF_SIZE / 2; - if (deflater.needsInput()) { - bytesReadDef += dataIn.length; - check(bytesReadDef == deflater.getBytesRead()); - deflater.setInput(dataIn, 0, dataIn.length); - } - int n = deflater.deflate(tmp, 0, len); - bytesWrittenDef += n; - check(bytesWrittenDef == deflater.getBytesWritten()); + deflater.setInput(dataIn, 0, dataIn.length); + while (bytesReadDef < dataSize || bytesWrittenInf < dataSize) { + int len = r.nextInt(BUF_SIZE / 2) + BUF_SIZE / 2; + if (deflater.needsInput()) { + bytesReadDef += dataIn.length; + check(bytesReadDef == deflater.getBytesRead()); + deflater.setInput(dataIn, 0, dataIn.length); + } + int n = deflater.deflate(tmp, 0, len); + bytesWrittenDef += n; + check(bytesWrittenDef == deflater.getBytesWritten()); - inflater.setInput(tmp, 0, n); - bytesReadInf += n; - while (!inflater.needsInput()) { - bytesWrittenInf += inflater.inflate(dataOut, 0, dataOut.length); - check(bytesWrittenInf == inflater.getBytesWritten()); + inflater.setInput(tmp, 0, n); + bytesReadInf += n; + while (!inflater.needsInput()) { + bytesWrittenInf += inflater.inflate(dataOut, 0, dataOut.length); + check(bytesWrittenInf == inflater.getBytesWritten()); + } + check(bytesReadInf == inflater.getBytesRead()); } - check(bytesReadInf == inflater.getBytesRead()); } } diff --git a/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java b/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java new file mode 100644 index 0000000000000..2a1d03117b738 --- /dev/null +++ b/test/jdk/javax/accessibility/TestJCheckBoxToggleAccessibility.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.GridLayout; + +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JToggleButton; + +/* + * @test + * @bug 8348936 8345728 + * @summary Verifies that VoiceOver announces the untick state of CheckBox and + * ToggleButton when space key is pressed. Also verifies that CheckBox + * and ToggleButton untick state is magnified with Screen Magnifier. + * @requires os.family == "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJCheckBoxToggleAccessibility + */ + +public class TestJCheckBoxToggleAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + +

    Testing with VoiceOver

    + +
      +
    1. Start the VoiceOver application + (Press Command + F5) +
    2. Click on the Frame with CheckBox and ToggleButton + window to move focus +
    3. Press Spacebar +
    4. VO should announce the checked state +
    5. Press Spacebar again +
    6. VO should announce the unchecked state +
    7. Press Tab to move focus to ToggleButton +
    8. Repeat steps 3 to 6 and listen the announcement +
    9. If announcements are incorrect, press Fail +
    10. Stop the VoiceOver application + (Press Command + F5 again) +
    + +

    Testing with Screen Magnifier

    +
      +
    1. Enable Screen magnifier on the Mac: + System Settings -> Accessibility -> + Hover Text -> Enable Hover Text
      + Default Hover Text Activation Modifier is Command key +
    2. Move focus back to the test application and perform the following tests + +
        +
      • Test CheckBox states with Screen Magnifier +
          +
        1. Click on CheckBox to select it +
        2. Press the Command key and + hover mouse over CheckBox +
        3. CheckBox ticked state along with its label should be magnified +
        4. Keep the Command key pressed and + click CheckBox to deselect it +
        5. CheckBox unticked state along with its label should be magnified +
        6. Release the Command key +
        7. If Screen Magnifier behaviour is incorrect, press Fail +
        +
      • Test ToggleButton states with Screen Magnifier +
          +
        1. Click on ToggleButton to select it +
        2. Press the Command key and + hover mouse over ToggleButton +
        3. Ticked state along with label should be magnified +
        4. Keep the Command button pressed and + click ToggleButton to deselect it +
        5. Unticked state along with its label should be magnified +
        6. Release the Command key +
        7. If Screen Magnifier behaviour is incorrect, press Fail +
        +
      +
    3. Disable Hover Text (optionally) in the Settings +
    + +

    Press Pass if you are able to hear correct VoiceOver announcements and + able to see the correct screen magnifier behaviour.

    """; + + PassFailJFrame.builder() + .title("TestJCheckBoxToggleAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(40) + .rows(25) + .testUI(TestJCheckBoxToggleAccessibility::createUI) + .testTimeOut(8) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with CheckBox and ToggleButton"); + JCheckBox cb = new JCheckBox("CheckBox", false); + JToggleButton tb = new JToggleButton("ToggleButton"); + + JPanel p = new JPanel(new GridLayout(2, 1)); + p.add(cb); + p.add(tb); + frame.getContentPane().add(p, BorderLayout.CENTER); + frame.setSize(400, 400); + return frame; + } +} diff --git a/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java new file mode 100644 index 0000000000000..acd7ec3c64a12 --- /dev/null +++ b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; + +/* + * @test + * @bug 8339728 + * @summary Tests that JAWS announce the shortcuts for JMenuItems. + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJMenuItemShortcutAccessibility + */ + +public class TestJMenuItemShortcutAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Start the JAWS application + 2. Press Alt + M to open application Menu + 3. Navigate the Menu Items by using UP / DOWN arrow key + 4. Press Pass if you are able to hear correct JAWS announcements + (JAWS should read full shortcut text and not only the 1st + character of shortcut text for each menu item) else Fail + """; + + PassFailJFrame.builder() + .title("TestJMenuItemShortcutAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(TestJMenuItemShortcutAccessibility::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with Menu"); + + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Menu with shortcuts"); + menu.setMnemonic(KeyEvent.VK_M); + menuBar.add(menu); + + KeyStroke keyStroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_F, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_2, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_F1, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke4 = KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke5 = KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, + InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK); + KeyStroke keyStroke6 = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke7 = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + JMenuItem menuItem1 = new JMenuItem("First Menu Item"); + menuItem1.setAccelerator(keyStroke1); + JMenuItem menuItem2 = new JMenuItem("Second Menu Item"); + menuItem2.setAccelerator(keyStroke2); + JMenuItem menuItem3 = new JMenuItem("Third Menu Item"); + menuItem3.setAccelerator(keyStroke3); + JMenuItem menuItem4 = new JMenuItem("Fourth Menu Item"); + menuItem4.setAccelerator(keyStroke4); + JMenuItem menuItem5 = new JMenuItem("Fifth Menu Item"); + menuItem5.setAccelerator(keyStroke5); + JMenuItem menuItem6 = new JMenuItem("Sixth Menu Item"); + menuItem6.setAccelerator(keyStroke6); + JMenuItem menuItem7 = new JMenuItem("Seventh Menu Item"); + menuItem7.setAccelerator(keyStroke7); + + menu.add(menuItem1); + menu.add(menuItem2); + menu.add(menuItem3); + menu.add(menuItem4); + menu.add(menuItem5); + menu.add(menuItem6); + menu.add(menuItem7); + + frame.setJMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } +} diff --git a/test/jdk/javax/crypto/CryptoPermissions/InconsistentEntries.java b/test/jdk/javax/crypto/CryptoPermissions/InconsistentEntries.java index 9c06cbaf613fe..1e84316867ecd 100644 --- a/test/jdk/javax/crypto/CryptoPermissions/InconsistentEntries.java +++ b/test/jdk/javax/crypto/CryptoPermissions/InconsistentEntries.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,14 +29,16 @@ * @run testng/othervm InconsistentEntries */ +import java.util.List; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.FileUtils; import org.testng.Assert; -import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import javax.crypto.*; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -45,42 +47,35 @@ public class InconsistentEntries { - private static final String JDK_HOME = System.getProperty("test.jdk"); - private static final String TEST_SRC = System.getProperty("test.src"); - private static final Path POLICY_DIR = Paths.get(JDK_HOME, "conf", "security", - "policy", "testlimited"); - private static final Path POLICY_FILE = Paths.get(TEST_SRC, "default_local.policy"); - - Path targetFile = null; + private static final String JDK_HOME = System.getProperty("test.jdk", "."); + private static final String TEST_SRC = System.getProperty("test.src", "."); + private static final Path TEMP_JDK_HOME = Path.of("java"); + private static final Path POLICY_DIR = TEMP_JDK_HOME.resolve(Path.of("conf", "security", + "policy", "testlimited")); + private static final Path POLICY_FILE_SRC = Paths.get(TEST_SRC, "default_local.policy"); + private static final Path POLICY_FILE_TARGET = POLICY_DIR + .resolve(POLICY_FILE_SRC.getFileName()); @BeforeTest - public void setUp() throws IOException { + public void setUp() throws Exception { + // Clone the tested JDK to the scratch directory + FileUtils.copyDirectory(Path.of(JDK_HOME), TEMP_JDK_HOME); + + // create policy directory in the cloned JDK if (!POLICY_DIR.toFile().exists()) { Files.createDirectory(POLICY_DIR); } - targetFile = POLICY_DIR.resolve(POLICY_FILE.getFileName()); - Files.copy(POLICY_FILE, targetFile, StandardCopyOption.REPLACE_EXISTING); - } - - @AfterTest - public void cleanUp() throws IOException { - Files.delete(targetFile); + // copy policy file into policy directory + Files.copy(POLICY_FILE_SRC, POLICY_FILE_TARGET, StandardCopyOption.REPLACE_EXISTING); } - @Test - public void test() throws Exception { - String JAVA_HOME = System.getProperty("java.home"); - String FS = System.getProperty("file.separator"); - Path testlimited = Path.of(JAVA_HOME + FS + "conf" + FS + "security" + - FS + "policy" + FS + "testlimited"); - if (!Files.exists(testlimited)) { + public static void main(String[] args) throws Throwable { + if (!Files.exists(POLICY_DIR)) { throw new RuntimeException( "custom policy subdirectory: testlimited does not exist"); } - - File testpolicy = new File(JAVA_HOME + FS + "conf" + FS + "security" + - FS + "policy" + FS + "testlimited" + FS + "default_local.policy"); + File testpolicy = new File(POLICY_FILE_TARGET.toString()); if (testpolicy.length() == 0) { throw new RuntimeException( "policy: default_local.policy does not exist or is empty"); @@ -91,4 +86,16 @@ public void test() throws Exception { Assert.assertThrows(ExceptionInInitializerError.class, () -> Cipher.getMaxAllowedKeyLength("AES")); } + + @Test + public void test() throws Exception { + String tmpJava = TEMP_JDK_HOME.resolve("bin").resolve("java").toString(); + String[] args = Utils.prependTestJavaOpts(InconsistentEntries.class.getName()); + ProcessBuilder pb = new ProcessBuilder(tmpJava); + pb.command().addAll(List.of(args)); + + ProcessTools + .executeProcess(pb) + .shouldHaveExitValue(0); + } } diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java index f55f1eea42ce6..5385beb9999fd 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,19 +24,20 @@ /** * @test * @bug 4508341 7055362 - * @library ../../../java/security/testlibrary + * @library /test/lib * @summary Test the error conditions of * EncryptedPrivateKeyInfo.getKeySpec(...) methods. * @author Valerie Peng * @run main/othervm -DcipherAlg=PBEWithMD5AndDES GetKeySpecException * @run main/othervm -DcipherAlg=PBEWithSHA1AndDESede GetKeySpecException */ + import java.security.*; -import java.util.Arrays; import java.util.Vector; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; +import jdk.test.lib.security.ProvidersSnapshot; public class GetKeySpecException { private static String cipherAlg; diff --git a/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java b/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java index 50a1c188d0fa5..82ac4e70899f7 100644 --- a/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java +++ b/test/jdk/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 6377058 7055362 - * @library ../../../java/security/testlibrary + * @library /test/lib * @summary SunJCE depends on sun.security.provider.SignatureImpl * behaviour, BC can't load into 1st slot. * @author Brad R. Wetmore @@ -33,7 +33,7 @@ import java.security.*; import javax.crypto.*; -import java.io.*; +import jdk.test.lib.security.ProvidersSnapshot; public class SunJCE_BC_LoadOrdering { diff --git a/test/jdk/javax/management/Introspector/InvokeGettersTest.java b/test/jdk/javax/management/Introspector/InvokeGettersTest.java index 6036069a6f5b2..71e22ca3d711f 100644 --- a/test/jdk/javax/management/Introspector/InvokeGettersTest.java +++ b/test/jdk/javax/management/Introspector/InvokeGettersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /* * @test - * @bug 6317101 - * @summary Test that the jmx.invoke.getters system property works + * @bug 6317101 8344976 + * @summary Test invocation after removal of the jmx.invoke.getters system property * @author Eamonn McManus * * @run clean InvokeGettersTest @@ -63,10 +63,7 @@ public static void main(String[] args) throws Exception { ObjectName on = new ObjectName("a:b=c"); mbs.registerMBean(new Thing(), on); if (test(mbs, on, false)) - System.out.println("OK: invoke without jmx.invoke.getters"); - System.setProperty("jmx.invoke.getters", "true"); - if (test(mbs, on, true)) - System.out.println("OK: invoke with jmx.invoke.getters"); + System.out.println("OK"); if (failure == null) System.out.println("TEST PASSED"); else @@ -117,7 +114,7 @@ private static boolean test(MBeanServer mbs, ObjectName on, System.out.println("isTrue got expected exception: " + e); } - // Following cases should fail whether or not jmx.invoke.getters is set + // Following cases should fail final Object[][] badInvokes = { {"isWhatsit", null, null}, {"getWhatsit", new Object[] {5}, new String[] {"int"}}, diff --git a/test/jdk/javax/management/MBeanServer/ExceptionFactory.java b/test/jdk/javax/management/MBeanServer/ExceptionFactory.java index 2315edff3fc79..a615c5252da7a 100644 --- a/test/jdk/javax/management/MBeanServer/ExceptionFactory.java +++ b/test/jdk/javax/management/MBeanServer/ExceptionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,12 +67,8 @@ import javax.management.remote.JMXServerErrorException; /** - * |----- Original Description Coming From Tonga Original Source Code -------| - * | | - * | That class creates an ArrayList and fill it with an instance of each of | - * | the Exception class of the JMX API. | - * | It's dedicated to use by ExceptionTest. | - * |-------------------------------------------------------------------------| + * This class creates an ArrayList and fills it with an instance of each + * Exception class in the JMX API. Used by ExceptionTest. */ public class ExceptionFactory { diff --git a/test/jdk/javax/management/MBeanServer/ExceptionTest.java b/test/jdk/javax/management/MBeanServer/ExceptionTest.java index bb58e941242aa..d3550780f0bdd 100644 --- a/test/jdk/javax/management/MBeanServer/ExceptionTest.java +++ b/test/jdk/javax/management/MBeanServer/ExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -188,7 +188,6 @@ private boolean matches(Exception ex, Exception refex) { return true; } - // Utility inner class coming from JMX Tonga test suite. // Also used by ExceptionFactory. static class Utils { @@ -222,9 +221,6 @@ static void parseDebugProperties() { } /** - * Reproduces the original parsing and collection of test parameters - * from the DTonga JMX test suite. - * * Collects passed args and returns them in a map(argname, value) structure, * which will be then propagated as necessary to various called methods. */ diff --git a/test/jdk/javax/management/MBeanServer/MBeanFallbackTest.java b/test/jdk/javax/management/MBeanServer/MBeanFallbackTest.java deleted file mode 100644 index 6cf508598de96..0000000000000 --- a/test/jdk/javax/management/MBeanServer/MBeanFallbackTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - -/* - * @test - * @bug 8010285 - * @summary Test fallback for private MBean interfaces. - * It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic" - * system property must be set before c.s.j.m.MBeanAnalyzer has been loaded. - * @author Jaroslav Bachorik - * - * @run clean MBeanFallbackTest - * @run build MBeanFallbackTest - * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true MBeanFallbackTest - */ -public class MBeanFallbackTest { - private static interface PrivateMBean { - public int[] getInts(); - } - - public static class Private implements PrivateMBean { - public int[] getInts() { - return new int[]{1,2,3}; - } - } - - private static int failures = 0; - - public static void main(String[] args) throws Exception { - testPrivate(PrivateMBean.class, new Private()); - - if (failures == 0) - System.out.println("Test passed"); - else - throw new Exception("TEST FAILURES: " + failures); - } - - private static void fail(String msg) { - failures++; - System.out.println("FAIL: " + msg); - } - - private static void success(String msg) { - System.out.println("OK: " + msg); - } - - private static void testPrivate(Class iface, Object bean) throws Exception { - try { - System.out.println("Registering a private MBean " + - iface.getName() + " ..."); - - MBeanServer mbs = MBeanServerFactory.newMBeanServer(); - ObjectName on = new ObjectName("test:type=Compliant"); - - mbs.registerMBean(bean, on); - success("Registered a private MBean - " + iface.getName()); - } catch (Exception e) { - Throwable t = e; - while (t != null && !(t instanceof NotCompliantMBeanException)) { - t = t.getCause(); - } - if (t != null) { - fail("MBean not registered"); - } else { - throw e; - } - } - } -} diff --git a/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy b/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy deleted file mode 100644 index ac5336ce882d9..0000000000000 --- a/test/jdk/javax/management/modelmbean/ModelMBeanInfoSupport/policy +++ /dev/null @@ -1,14 +0,0 @@ -grant { - permission javax.management.MBeanServerPermission "createMBeanServer"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#-[-]", "instantiate"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#-[*:*]", "registerMBean"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "getAttribute"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "setAttribute"; - permission javax.management.MBeanPermission "javax.management.modelmbean.RequiredModelMBean#*[*:*]", "invoke"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#-[*:*]", "registerMBean"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "invoke"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "getAttribute"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "setAttribute"; - permission javax.management.MBeanPermission "GetAllDescriptorsTest$Resource#*[*:*]", "getMBeanInfo"; - -}; diff --git a/test/jdk/javax/management/mxbean/MXBeanFallbackTest.java b/test/jdk/javax/management/mxbean/MXBeanFallbackTest.java deleted file mode 100644 index 00fd1c454c2e5..0000000000000 --- a/test/jdk/javax/management/mxbean/MXBeanFallbackTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8010285 - * @summary Test for the private MXBean interface fallback. - * It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic" - * system property must be set before c.s.j.m.MBeanAnalyzer has been loaded. - * @author Jaroslav Bachorik - * - * @run clean MXBeanFallbackTest - * @run build MXBeanFallbackTest - * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true MXBeanFallbackTest - */ - -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - -public class MXBeanFallbackTest { - public static void main(String[] args) throws Exception { - testPrivateMXBean("Private", new Private()); - - if (failures == 0) - System.out.println("Test passed"); - else - throw new Exception("TEST FAILURES: " + failures); - } - - private static int failures = 0; - - private static interface PrivateMXBean { - public int[] getInts(); - } - - public static class Private implements PrivateMXBean { - public int[] getInts() { - return new int[]{1,2,3}; - } - } - - private static void testPrivateMXBean(String type, Object bean) throws Exception { - System.out.println(type + " MXBean test..."); - MBeanServer mbs = MBeanServerFactory.newMBeanServer(); - ObjectName on = new ObjectName("test:type=" + type); - try { - mbs.registerMBean(bean, on); - success("Private MXBean registered"); - } catch (NotCompliantMBeanException e) { - failure("Failed to register the private MXBean - " + - bean.getClass().getInterfaces()[0].getName()); - } - } - - private static void success(String what) { - System.out.println("OK: " + what); - } - - private static void failure(String what) { - System.out.println("FAILED: " + what); - failures++; - } -} diff --git a/test/jdk/javax/management/mxbean/SameObjectTwoNamesTest.java b/test/jdk/javax/management/mxbean/SameObjectTwoNamesTest.java index 10022c592f708..130289e10da38 100644 --- a/test/jdk/javax/management/mxbean/SameObjectTwoNamesTest.java +++ b/test/jdk/javax/management/mxbean/SameObjectTwoNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ * @author Eamonn McManus * * @run main SameObjectTwoNamesTest - * @run main/othervm -Djmx.mxbean.multiname=true SameObjectTwoNamesTest */ import javax.management.InstanceAlreadyExistsException; @@ -41,8 +40,6 @@ public class SameObjectTwoNamesTest { public static void main(String[] args) throws Exception { - boolean expectException = - (System.getProperty("jmx.mxbean.multiname") == null); try { ObjectName objectName1 = new ObjectName("test:index=1"); ObjectName objectName2 = new ObjectName("test:index=2"); @@ -53,19 +50,10 @@ public static void main(String[] args) throws Exception { mbs.registerMBean(mxBeanObject, objectName2); - if (expectException) { - throw new Exception("TEST FAILED: " + - "InstanceAlreadyExistsException was not thrown"); - } else - System.out.println("Correctly got no exception with compat property"); + throw new Exception("TEST FAILED: InstanceAlreadyExistsException was not thrown"); } catch (InstanceAlreadyExistsException e) { - if (expectException) { - System.out.println("Got expected InstanceAlreadyExistsException:"); - e.printStackTrace(System.out); - } else { - throw new Exception( - "TEST FAILED: Got exception even though compat property set", e); - } + System.out.println("Got expected InstanceAlreadyExistsException:"); + e.printStackTrace(System.out); } System.out.println("TEST PASSED"); } diff --git a/test/jdk/javax/management/mxbean/Utils.java b/test/jdk/javax/management/mxbean/Utils.java index f77196baa2c23..550f11736a13c 100644 --- a/test/jdk/javax/management/mxbean/Utils.java +++ b/test/jdk/javax/management/mxbean/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.lang.reflect.Method; import javax.management.remote.JMXConnectorServerMBean; -// utility class for MXBean* tests coming from JMX Tonga test suite class Utils { // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property @@ -60,9 +59,6 @@ static void parseDebugProperties() { } /** - * Reproduces the original parsing and collection of test parameters - * from the DTonga JMX test suite. - * * Collects passed args and returns them in a map(argname, value) structure, * which will be then propagated as necessary to various called methods. */ diff --git a/test/jdk/javax/management/openmbean/TabularDataOrderTest.java b/test/jdk/javax/management/openmbean/TabularDataOrderTest.java index 68e9fefdc7cd8..0a1a02c949ffa 100644 --- a/test/jdk/javax/management/openmbean/TabularDataOrderTest.java +++ b/test/jdk/javax/management/openmbean/TabularDataOrderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,6 @@ public class TabularDataOrderTest { private static String failure; - private static final String COMPAT_PROP_NAME = "jmx.tabular.data.hash.map"; - private static final String[] intNames = { "unus", "duo", "tres", "quatuor", "quinque", "sex", "septem", "octo", "novem", "decim", @@ -129,44 +127,6 @@ public static void main(String[] args) throws Exception { if (!ordered) fail("Order not preserved"); - // Now test the undocumented property that causes HashMap to be used - // instead of LinkedHashMap, in case serializing to a 1.3 client. - // We serialize and deserialize in case the implementation handles - // this at serialization time. Then we look at object fields; that's - // not guaranteed to work but at worst it will fail spuriously and - // we'll have to update the test. - System.out.println("Testing compatible behaviour"); - System.setProperty(COMPAT_PROP_NAME, "true"); - td = makeTable(); - System.out.println(td); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - ObjectOutputStream oout = new ObjectOutputStream(bout); - oout.writeObject(td); - oout.close(); - byte[] bytes = bout.toByteArray(); - ByteArrayInputStream bin = new ByteArrayInputStream(bytes); - ObjectInputStream oin = new ObjectInputStream(bin); - td = (TabularData) oin.readObject(); - boolean found = false; - for (Field f : td.getClass().getDeclaredFields()) { - if (Modifier.isStatic(f.getModifiers())) - continue; - f.setAccessible(true); - Object x = f.get(td); - if (x != null && x.getClass() == HashMap.class) { - found = true; - System.out.println( - x.getClass().getName() + " TabularDataSupport." + - f.getName() + " = " + x); - break; - } - } - if (!found) { - fail("TabularDataSupport does not contain HashMap though " + - COMPAT_PROP_NAME + "=true"); - } - System.clearProperty(COMPAT_PROP_NAME); - System.out.println("Testing MXBean behaviour"); MBeanServer mbs = MBeanServerFactory.newMBeanServer(); ObjectName name = new ObjectName("a:b=c"); diff --git a/test/jdk/javax/management/proxy/JMXProxyFallbackTest.java b/test/jdk/javax/management/proxy/JMXProxyFallbackTest.java deleted file mode 100644 index c68a93654afca..0000000000000 --- a/test/jdk/javax/management/proxy/JMXProxyFallbackTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import javax.management.JMX; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - -/* - * @test - * @bug 8010285 - * @summary Tests the fallback for creating JMX proxies for private interfaces - * It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic" - * system property must be set before c.s.j.m.MBeanAnalyzer has been loaded. - * @author Jaroslav Bachorik - * - * @run clean JMXProxyFallbackTest - * @run build JMXProxyFallbackTest - * @run main/othervm -Djdk.jmx.mbeans.allowNonPublic=true JMXProxyFallbackTest - */ -public class JMXProxyFallbackTest { - private static interface PrivateMBean { - public int[] getInts(); - } - - private static interface PrivateMXBean { - public int[] getInts(); - } - - public static class Private implements PrivateMXBean, PrivateMBean { - public int[] getInts() { - return new int[]{1,2,3}; - } - } - - private static int failures = 0; - - public static void main(String[] args) throws Exception { - testPrivate(PrivateMBean.class); - testPrivate(PrivateMXBean.class); - - if (failures == 0) - System.out.println("Test passed"); - else - throw new Exception("TEST FAILURES: " + failures); - } - - private static void fail(String msg) { - failures++; - System.out.println("FAIL: " + msg); - } - - private static void success(String msg) { - System.out.println("OK: " + msg); - } - - private static void testPrivate(Class iface) throws Exception { - try { - System.out.println("Creating a proxy for private M(X)Bean " + - iface.getName() + " ..."); - - MBeanServer mbs = MBeanServerFactory.newMBeanServer(); - ObjectName on = new ObjectName("test:type=Proxy"); - - JMX.newMBeanProxy(mbs, on, iface); - success("Created a proxy for private M(X)Bean - " + iface.getName()); - } catch (Exception e) { - Throwable t = e; - while (t != null && !(t instanceof NotCompliantMBeanException)) { - t = t.getCause(); - } - if (t != null) { - fail("Proxy not created"); - } else { - throw e; - } - } - } -} diff --git a/test/jdk/javax/management/query/SupportedQueryTypesTest.java b/test/jdk/javax/management/query/SupportedQueryTypesTest.java index 8c254329915bf..17c720d499e3b 100644 --- a/test/jdk/javax/management/query/SupportedQueryTypesTest.java +++ b/test/jdk/javax/management/query/SupportedQueryTypesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -287,7 +287,6 @@ private int checkSet(Set remoteSet, Set referenceSet) { } } - // Utility inner class coming from JMX Tonga test suite. private static class Utils { // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property @@ -320,9 +319,6 @@ static void parseDebugProperties() { } /** - * Reproduces the original parsing and collection of test parameters - * from the DTonga JMX test suite. - * * Collects passed args and returns them in a map(argname, value) structure, * which will be then propagated as necessary to various called methods. */ diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java index 94a0690428239..8f4fe0a24f0da 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotifBufferSizePropertyNameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test NotifBufferSizePropertyNameTest - * @bug 6174229 + * @bug 6174229 8345045 * @summary Verify the property name specifying server notification buffer size. * @author Shanliang JIANG * @@ -52,35 +52,25 @@ public void handleNotification(Notification n, Object hb) { }; public static void main(String[] args) throws Exception { - System.out.println( - "Verify the property name specifying the server notification buffer size."); + System.out.println("Verify the property name specifying the server notification buffer size."); oname = new ObjectName ("Default:name=NotificationEmitter"); url = new JMXServiceURL("rmi", null, 0); Map env = new HashMap(2); - System.out.println("Test the new property name."); + System.out.println("Test the property name."); env.put("jmx.remote.x.notification.buffer.size", String.valueOf(bufferSize)); test(env); - System.out.println("Test the old property name."); - env.remove("jmx.remote.x.notification.buffer.size"); - env.put("jmx.remote.x.buffer.size", String.valueOf(bufferSize)); - test(env); - + // Recognition of the old, incorrect property "jmx.remote.x.buffer.size" has been dropped. + // Do not test old name is recognised, but do test it does not interfere with correct name: System.out.println("Test that the new property name overwrite the old one."); env.put("jmx.remote.x.notification.buffer.size", String.valueOf(bufferSize)); env.put("jmx.remote.x.buffer.size", String.valueOf(bufferSize*6)); test(env); - System.out.println("Test the old property name on system."); - System.setProperty("jmx.remote.x.buffer.size", String.valueOf(bufferSize)); - test(null); - - System.out.println( - "Test that the new property name overwrite the old one on system."); - System.setProperty("jmx.remote.x.notification.buffer.size", - String.valueOf(bufferSize)); + System.out.println("Test that the new property name overwrite the old one on system."); + System.setProperty("jmx.remote.x.notification.buffer.size", String.valueOf(bufferSize)); System.setProperty("jmx.remote.x.buffer.size", String.valueOf(bufferSize*6)); test(null); } diff --git a/test/jdk/javax/management/security/Utils.java b/test/jdk/javax/management/security/Utils.java index c0af037a4d62b..afb1a8b184245 100644 --- a/test/jdk/javax/management/security/Utils.java +++ b/test/jdk/javax/management/security/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.lang.reflect.Method; import javax.management.remote.JMXConnectorServerMBean; -// utility class for MXBean* tests coming from JMX Tonga test suite class Utils { private static final String SERVER_SIDE_NAME = "-server"; @@ -64,9 +63,6 @@ static void parseDebugProperties() { } /** - * Reproduces the original parsing and collection of test parameters - * from the DTonga JMX test suite. - * * Collects passed args and returns them in a map(argname, value) structure, * which will be then propagated as necessary to various called methods. */ diff --git a/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java b/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java index b8e2410643b31..0e34f4865ab87 100644 --- a/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java +++ b/test/jdk/javax/net/ssl/SSLSocket/Tls13PacketSize.java @@ -72,6 +72,10 @@ protected void runServerApplication(SSLSocket socket) throws Exception { sslOS.write(appData); sslOS.flush(); + int drained = 1; + while (drained < appData.length) { + drained += sslIS.read(appData, drained, appData.length - drained); + } } /* diff --git a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java index 72a68cdddb06d..b9829621d686b 100644 --- a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java +++ b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm HttpsUrlConnClient RSA SHA256withRSA * @run main/othervm HttpsUrlConnClient RSASSA-PSS RSASSA-PSS */ @@ -59,8 +58,8 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class HttpsUrlConnClient { diff --git a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java index ec869f8343118..506e7b00e6d28 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm SSLEngineWithStapling */ @@ -87,8 +86,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class SSLEngineWithStapling { diff --git a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java index 7e1473c2828ad..30f5e5898899e 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ * @test * @bug 8046321 8153829 * @summary OCSP Stapling for TLS - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm SSLSocketWithStapling */ @@ -63,8 +62,8 @@ import java.util.HashMap; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class SSLSocketWithStapling { diff --git a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java index 14651cf3db926..90b01d19c03b6 100644 --- a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java +++ b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java @@ -28,8 +28,7 @@ * @test * @bug 8145854 8153829 * @summary SSLContextImpl.statusResponseManager should be generated if required - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm StapleEnableProps */ @@ -49,8 +48,8 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class StapleEnableProps { diff --git a/test/jdk/javax/print/CUPSPrinterImageableAreaTest.java b/test/jdk/javax/print/CUPSPrinterImageableAreaTest.java new file mode 100644 index 0000000000000..b07cc39c6ff2e --- /dev/null +++ b/test/jdk/javax/print/CUPSPrinterImageableAreaTest.java @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, BELLSOFT. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.print.PageFormat; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.ArrayList; +import java.util.List; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.Size2DSyntax; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaSizeName; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicComboBoxRenderer; + +/* + * @test + * @bug 8344119 + * @key printer + * @requires (os.family == "linux" | os.family == "mac") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary CUPSPrinter imageable area + * @run main/manual CUPSPrinterImageableAreaTest + */ + +public class CUPSPrinterImageableAreaTest { + + private static final List ALLOWED_MEDIA_LIST = List.of(MediaSizeName.ISO_A4, MediaSizeName.NA_LETTER); + private static final double DPI = 72.0; + private static final double MM_PER_INCH = 2.54; + private static final String INSTRUCTIONS = """ + +
    + The test checks that the media margins fetched from the printer's PPD file are correct.
    + Press the 'Print sample' button to print a test page.
    + Required paper size and expected margins will be shown on the print dialog. + A passing test will print the page with a black rectangle along the printable area. + Ensure that all sides of the rectangle are printed.
    + Click 'Pass' button, or click 'Fail' button if the test failed. +
    + + """; + private static final String PAPER_INSTRUCTIONS_FORMAT = """ + + Required paper size:
    • %s
    + Expected margins:
    • left: %.1f
    • +
    • bottom: %.1f
    • +
    • right: %.1f
    • +
    • top: %.1f
    • +
    + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .testUI(createTestUI()) + .columns(55) + .build() + .awaitAndCheck(); + } + + private static JFrame createTestUI() { + final TestServiceData[] testServiceList = getTestServiceList(); + if (testServiceList.length == 0) { + throw new RuntimeException("Print services support borderless print only"); + } + + final JFrame frame = new JFrame("CUPS Printer imageable area test"); + JPanel pnlRoot = new JPanel(); + JLabel lblPrintServices = new JLabel("Select a print service for the test"); + JComboBox cbPrintServices = new JComboBox<>(); + JPanel pnlInstruction = new JPanel(); + JLabel lblInstruction = new JLabel(); + JButton btnPrint = new JButton("Print sample"); + + lblPrintServices.setLabelFor(cbPrintServices); + lblPrintServices.setAlignmentX(SwingConstants.LEFT); + + lblInstruction.setPreferredSize(new Dimension(250, 150)); + pnlInstruction.setBackground(Color.white); + pnlInstruction.add(lblInstruction); + + cbPrintServices.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + int selectedIndex = cbPrintServices.getSelectedIndex(); + if (selectedIndex < 0) { + lblInstruction.setText(""); + btnPrint.setEnabled(false); + return; + } + + TestServiceData testServiceData = testServiceList[selectedIndex]; + PageFormat pageFormat = testServiceData.pageFormat; + // margins: left, bottom, right, top + double[] margins = new double[]{ + pageFormat.getImageableX(), + pageFormat.getHeight() - pageFormat.getImageableHeight() - pageFormat.getImageableY(), + pageFormat.getWidth() - pageFormat.getImageableWidth() - pageFormat.getImageableX(), + pageFormat.getImageableY() + }; + String printServiceInstructions = PAPER_INSTRUCTIONS_FORMAT.formatted( + testServiceData.mediaSizeName.toString(), inchesToMM(margins[0]), + inchesToMM(margins[1]), inchesToMM(margins[2]), inchesToMM(margins[3])); + lblInstruction.setText(printServiceInstructions); + btnPrint.setEnabled(true); + } + }); + + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); + for(TestServiceData tsd : testServiceList) { + model.addElement(tsd.printService.getName()); + } + cbPrintServices.setModel(model); + cbPrintServices.setSelectedIndex(-1); + PrintService defaultPrintService = PrintServiceLookup.lookupDefaultPrintService(); + if (defaultPrintService != null && model.getIndexOf(defaultPrintService.getName()) >= 0) { + cbPrintServices.setSelectedItem(defaultPrintService.getName()); + } else { + cbPrintServices.setSelectedIndex(0); + } + + btnPrint.setPreferredSize(new Dimension(200, 80)); + btnPrint.addActionListener((e) -> { + int selectedIndex = cbPrintServices.getSelectedIndex(); + if (selectedIndex < 0) { + return; + } + btnPrint.setEnabled(false); + cbPrintServices.setEnabled(false); + TestServiceData testServiceData = testServiceList[selectedIndex]; + PrinterJob job = PrinterJob.getPrinterJob(); + try { + job.setPrintService(testServiceData.printService); + job.setPrintable(new RectPrintable(), testServiceData.pageFormat); + job.print(); + } catch (PrinterException ex) { + throw new RuntimeException(ex); + } + }); + + LayoutManager layout = new GridBagLayout(); + pnlRoot.setLayout(layout); + + addGridBagComponent(pnlRoot, lblPrintServices, 0); + addGridBagComponent(pnlRoot, cbPrintServices, 1); + addGridBagComponent(pnlRoot, pnlInstruction, 2); + addGridBagComponent(pnlRoot, btnPrint, 3); + + frame.add(pnlRoot); + frame.pack(); + frame.setResizable(false); + return frame; + } + + private static TestServiceData[] getTestServiceList() { + PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null); + if (printServices == null || printServices.length == 0) { + throw new RuntimeException("Print services not found"); + } + + List testServiceList = new ArrayList<>(); + for (PrintService ps : printServices) { + try { + MediaSizeName msn = getTestMediaSizeName(ps); + PageFormat pf = createTestPageFormat(msn, ps); + testServiceList.add(new TestServiceData(ps, msn, pf)); + } catch (Exception ignore) { //in case if can't create required PageFormat + } + } + return testServiceList.toArray(TestServiceData[]::new); + } + + private static MediaSizeName getTestMediaSizeName(PrintService printService) { + //Use printer's default media or one of the alloed medias + Media testMedia = (Media) printService.getDefaultAttributeValue(Media.class); + if (testMedia == null) { + Media[] medias = (Media[]) printService + .getSupportedAttributeValues(Media.class, null, null); + if (medias == null || medias.length == 0) { + throw new RuntimeException("Medias not found"); + } + for (Media media : medias) { + if (ALLOWED_MEDIA_LIST.contains(media)) { + testMedia = media; + break; + } + } + } + if (!(testMedia instanceof MediaSizeName)) { + throw new RuntimeException("Test media not found"); + } + return (MediaSizeName) testMedia; + } + + private static PageFormat createTestPageFormat(MediaSizeName testMedia, PrintService printService) { + MediaSize ms = MediaSize.getMediaSizeForName(testMedia); + if (ms == null) { + throw new RuntimeException("Media size not defined"); + } + + MediaPrintableArea mpa = getMaximumMediaPrintableArea(testMedia, ms, printService); + if (mpa == null) { + throw new RuntimeException("Media printable area not defined"); + } + + PageFormat pageFormat = new PageFormat(); + pageFormat.setOrientation(PageFormat.PORTRAIT); + Paper paper = new Paper(); + paper.setSize(ms.getX(MediaSize.INCH) * DPI, ms.getY(MediaSize.INCH) * DPI); + paper.setImageableArea(mpa.getX(MediaPrintableArea.INCH) * DPI, + mpa.getY(MediaPrintableArea.INCH) * DPI, + mpa.getWidth(MediaPrintableArea.INCH) * DPI, + mpa.getHeight(MediaPrintableArea.INCH) * DPI); + pageFormat.setPaper(paper); + return pageFormat; + } + + private static MediaPrintableArea getMaximumMediaPrintableArea(MediaSizeName msn, MediaSize ms, + PrintService printService) { + final float paperSizeX = ms.getX(Size2DSyntax.MM); + final float paperSizeY = ms.getY(Size2DSyntax.MM); + final float sizeDev = 0.2f; + + PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet(); + attrs.add(msn); + MediaPrintableArea[] mpas = (MediaPrintableArea[]) printService + .getSupportedAttributeValues(MediaPrintableArea.class, null, attrs); + if (mpas == null || mpas.length == 0) { + throw new RuntimeException("Printable area not found"); + } + + MediaPrintableArea mpa = null; + for (MediaPrintableArea area : mpas) { + float mpaSize = area.getWidth(MediaPrintableArea.MM) * area.getHeight(MediaPrintableArea.MM); + //do not use borderless printable area + if (sizeDev >= Math.abs(paperSizeX - area.getWidth(MediaPrintableArea.MM)) && + sizeDev >= Math.abs(paperSizeY - area.getHeight(MediaPrintableArea.MM))) { + continue; + } + if (mpa == null) { + mpa = area; + } else if (mpaSize > (area.getWidth(MediaPrintableArea.MM) * area.getHeight(MediaPrintableArea.MM))) { + mpa = area; + } + } + return mpa; + } + + private static double inchesToMM(double inches) { + return inches / MM_PER_INCH; + } + + private static void addGridBagComponent(JPanel p, Component c, int y) { + GridBagConstraints constraints = new GridBagConstraints(); + constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.insets = new Insets(4, 4, 4, 4); + constraints.gridx = 0; + constraints.gridy = y; + p.add(c, constraints); + } + + private static class RectPrintable implements Printable { + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + if (pageIndex == 0) { + Graphics2D g = (Graphics2D) graphics; + g.setStroke(new BasicStroke(3)); + g.drawRect((int) pageFormat.getImageableX(), (int) pageFormat.getImageableY(), + (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableHeight()); + return PAGE_EXISTS; + } + return NO_SUCH_PAGE; + } + } + + private static class TestServiceData { + + final PrintService printService; + final MediaSizeName mediaSizeName; + final PageFormat pageFormat; + + private TestServiceData(PrintService printService, MediaSizeName mediaSizeName, PageFormat pageFormat) { + this.printService = printService; + this.mediaSizeName = mediaSizeName; + this.pageFormat = pageFormat; + } + } +} diff --git a/test/jdk/javax/print/attribute/PageRangesException.java b/test/jdk/javax/print/attribute/PageRangesException.java new file mode 100644 index 0000000000000..81f9eb1a59289 --- /dev/null +++ b/test/jdk/javax/print/attribute/PageRangesException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.print.attribute.standard.PageRanges; + +/* + * @test + * @bug 4433126 4433096 + * @key printer + * @summary The line "ERROR: " should NOT appear. + * @run main PageRangesException + */ + +public class PageRangesException { + public static void main(String[] args) throws Exception { + // test 4433126 + try { + PageRanges pr = new PageRanges("0:22"); + throw new RuntimeException("ERROR: no exceptions"); + } catch (IllegalArgumentException ie) { + System.out.println("OKAY: IllegalArgumentException " + ie); + } + + // test 4433096 + try { + int[][] m = null; + PageRanges pr = new PageRanges(m); + throw new RuntimeException("ERROR: NullPointerException expected"); + } catch (IllegalArgumentException ie) { + throw new RuntimeException("ERROR: IllegalArgumentException", ie); + } catch (NullPointerException e) { + System.out.println("OKAY: NullPointerException"); + } + } +} diff --git a/test/jdk/javax/swing/AbstractButton/bug6298940.java b/test/jdk/javax/swing/AbstractButton/bug6298940.java new file mode 100644 index 0000000000000..c2857c68ae305 --- /dev/null +++ b/test/jdk/javax/swing/AbstractButton/bug6298940.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6298940 + * @key headful + * @summary Tests that mnemonic keystroke fires an action + * @library /javax/swing/regtesthelpers + * @build Util + * @run main bug6298940 + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; + +import javax.swing.ButtonModel; +import javax.swing.DefaultButtonModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import static java.util.concurrent.TimeUnit.SECONDS; + +public final class bug6298940 { + private static JFrame frame; + + private static final CountDownLatch actionEvent = new CountDownLatch(1); + + private static void createAndShowGUI() { + ButtonModel model = new DefaultButtonModel(); + model.addActionListener(event -> { + System.out.println("ActionEvent"); + actionEvent.countDown(); + }); + model.setMnemonic('T'); + + JButton button = new JButton("Test"); + button.setModel(model); + + frame = new JFrame("bug6298940"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(button); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + } + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + + SwingUtilities.invokeAndWait(bug6298940::createAndShowGUI); + + robot.waitForIdle(); + robot.delay(500); + + Util.hitMnemonics(robot, KeyEvent.VK_T); + + try { + if (!actionEvent.await(1, SECONDS)) { + throw new RuntimeException("Mnemonic didn't fire an action"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JButton/4796987/bug4796987.java b/test/jdk/javax/swing/JButton/4796987/bug4796987.java index 62d11fc18c08b..bfa6ef8d129ef 100644 --- a/test/jdk/javax/swing/JButton/4796987/bug4796987.java +++ b/test/jdk/javax/swing/JButton/4796987/bug4796987.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,67 +26,91 @@ * @bug 4796987 * @key headful * @requires (os.family == "windows") - * @summary XP Only: JButton.setBorderPainted() does not work with XP L&F - * @author Alexander Scherbatiy + * @summary Verify JButton.setBorderPainted(false) removes border + * for Windows visual styles (Windows XP and later) * @library ../../regtesthelpers - * @library /test/lib - * @modules java.desktop/com.sun.java.swing.plaf.windows - * java.desktop/sun.awt - * @build jdk.test.lib.OSVersion jdk.test.lib.Platform * @build Util * @run main bug4796987 */ -import jdk.test.lib.Platform; -import jdk.test.lib.OSVersion; -import java.awt.*; -import javax.swing.*; -import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; public class bug4796987 { private static JButton button1; private static JButton button2; private static JFrame frame; + private static JPanel panel; public static void main(String[] args) throws Exception { try { - if (Platform.isWindows() - && OSVersion.current().equals(OSVersion.WINDOWS_XP)) { - UIManager.setLookAndFeel(new WindowsLookAndFeel()); - testButtonBorder(); - } + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + testButtonBorder(); } finally { - if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose()); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } } private static void testButtonBorder() throws Exception { Robot robot = new Robot(); - robot.setAutoDelay(50); - SwingUtilities.invokeAndWait(new Runnable() { - - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(bug4796987::createAndShowGUI); + robot.waitForIdle(); + robot.delay(500); + // Hover over button1 + Point b1Center = Util.getCenterPoint(button1); + robot.mouseMove(b1Center.x, b1Center.y); robot.waitForIdle(); - Thread.sleep(500); - Point p1 = Util.getCenterPoint(button1); - Point p2 = Util.getCenterPoint(button2); + Rectangle panelBounds = Util.invokeOnEDT(() -> + new Rectangle(panel.getLocationOnScreen(), + panel.getSize())); + BufferedImage image = robot.createScreenCapture(panelBounds); + + final Point p1 = Util.invokeOnEDT(() -> getCenterPoint(button1)); + final Point p2 = Util.invokeOnEDT(() -> getCenterPoint(button2)); - Color color = robot.getPixelColor(p1.x, p2.x); - for (int dx = p1.x; dx < p2.x - p1.x; dx++) { - robot.mouseMove(p1.x + dx, p1.y); - if (!color.equals(robot.getPixelColor(p1.x + dx, p1.y))) { + final int color = image.getRGB(p1.x, p1.y); + for (int dx = 0; p1.x + dx < p2.x; dx++) { + if (color != image.getRGB(p1.x + dx, p1.y)) { + System.err.println("Wrong color at " + (p1.x + dx) + ", " + p1.y + + " - expected " + Integer.toHexString(color)); + saveImage(image); throw new RuntimeException("Button has border and background!"); } } } + /** + * {@return the center point of a button relative to its parent} + * @param button the button to calculate the center point + */ + private static Point getCenterPoint(JButton button) { + Point location = button.getLocation(); + Dimension size = button.getSize(); + location.translate(size.width / 2, size.height / 2); + return location; + } + private static JButton getButton() { JButton button = new JButton(); button.setBorderPainted(false); @@ -95,18 +119,24 @@ private static JButton getButton() { } private static void createAndShowGUI() { - frame = new JFrame("Test"); + frame = new JFrame("bug4796987"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); - JButton button = new JButton(); - button.setBorder(null); - - JPanel panel = new JPanel(new BorderLayout(50, 50)); + panel = new JPanel(new BorderLayout(50, 50)); panel.add(getButton(), BorderLayout.CENTER); panel.add(button1 = getButton(), BorderLayout.WEST); panel.add(button2 = getButton(), BorderLayout.EAST); frame.getContentPane().add(panel); + frame.setLocationRelativeTo(null); frame.setVisible(true); } + + private static void saveImage(BufferedImage image) { + try { + ImageIO.write(image, "png", + new File("frame.png")); + } catch (IOException ignored) { + } + } } diff --git a/test/jdk/javax/swing/JColorChooser/Test8152419.java b/test/jdk/javax/swing/JColorChooser/Test8152419.java index 65615acbdee37..48067a4d2bad1 100644 --- a/test/jdk/javax/swing/JColorChooser/Test8152419.java +++ b/test/jdk/javax/swing/JColorChooser/Test8152419.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,11 +21,12 @@ * questions. */ - /* -* @test -* @bug 8152419 -* @summary To Verify JColorChooser tab selection -* @run main/manual Test8152419 +/* + * @test + * @bug 8152419 + * @library /test/lib + * @summary To Verify JColorChooser tab selection + * @run main/manual Test8152419 */ import java.awt.Color; @@ -43,9 +44,17 @@ import javax.swing.UIManager; import javax.swing.border.EmptyBorder; +import jtreg.SkippedException; + public class Test8152419 { public static void main(String args[]) throws Exception { + // ColorChooser UI design is different for GTK L&F. + // There are no tabs available for GTK L&F, skip the testing. + if (UIManager.getLookAndFeel().getName().contains("GTK")) { + throw new SkippedException("Test not applicable for GTK L&F"); + } + final CountDownLatch latch = new CountDownLatch(1); JColorChooserTest test = new JColorChooserTest(latch); diff --git a/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java b/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java new file mode 100644 index 0000000000000..c7c3ba2f12e4c --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicComboPopup; + +/* + * @test + * @key headful + * @bug 6672644 + * @summary Tests JComboBox scrollbar behavior when alt-tabbing + * @run main JComboBoxScrollFocusTest + */ + +public class JComboBoxScrollFocusTest { + private static Robot robot; + private static JFrame comboboxFrame; + private static JComboBox combobox; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + try { + SwingUtilities.invokeAndWait(JComboBoxScrollFocusTest::createAndShowGUI); + doTest(); + } finally { + SwingUtilities.invokeAndWait(comboboxFrame::dispose); + } + } + + private static void createAndShowGUI() { + comboboxFrame = new JFrame("JComboBoxScrollFocusTest Test Frame"); + combobox = new JComboBox<>(); + for (int i = 0; i < 100; i++) { + combobox.addItem(String.valueOf(i)); + } + comboboxFrame.add(combobox); + comboboxFrame.setSize(400, 200); + comboboxFrame.setLocationRelativeTo(null); + comboboxFrame.setVisible(true); + } + + static Rectangle getOnScreenBoundsOnEDT(Component component) throws Exception { + robot.waitForIdle(); + FutureTask task = new FutureTask<>(() + -> new Rectangle(component.getLocationOnScreen(), + component.getSize())); + SwingUtilities.invokeLater(task); + return task.get(500, TimeUnit.MILLISECONDS); + } + + private static JScrollBar getScrollBar() { + BasicComboPopup popup = (BasicComboPopup) combobox + .getAccessibleContext().getAccessibleChild(0); + JScrollPane scrollPane = (JScrollPane) popup + .getAccessibleContext().getAccessibleChild(0); + return scrollPane.getVerticalScrollBar(); + } + + private static int getScrollbarValue() throws Exception { + FutureTask task = new FutureTask<>(() -> { + JScrollBar scrollBar = getScrollBar(); + return scrollBar.getValue(); + }); + SwingUtilities.invokeAndWait(task); + + return task.get(500, TimeUnit.MILLISECONDS); + } + + private static void doTest() throws Exception { + robot.waitForIdle(); + robot.delay(500); + + Rectangle rectangle = getOnScreenBoundsOnEDT(combobox); + + Point ptOpenComboboxPopup = new Point(rectangle.x + rectangle.width - 5, + rectangle.y + rectangle.height / 2); + + robot.mouseMove(ptOpenComboboxPopup.x, ptOpenComboboxPopup.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); + + JScrollBar scrollBar = getScrollBar(); + + // Start scrolling + Rectangle scrollbarBounds = getOnScreenBoundsOnEDT(scrollBar); + robot.mouseMove(scrollbarBounds.x + scrollbarBounds.width / 2, + scrollbarBounds.y + scrollbarBounds.height - 5); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(1000); + + if (getScrollbarValue() == 0) { + throw new RuntimeException("The scrollbar is not scrolling"); + } + + // closing popup by moving focus to the main window + comboboxFrame.requestFocus(); + robot.waitForIdle(); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + robot.delay(500); + + // open popup again + robot.mouseMove(ptOpenComboboxPopup.x, ptOpenComboboxPopup.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); + + if (getScrollbarValue() != 0) { + throw new RuntimeException("The scroll bar is scrolling"); + } + } +} diff --git a/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java index 0e176a911a39c..da914314670ad 100644 --- a/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java +++ b/test/jdk/javax/swing/JComboBox/TestComboBoxComponentRendering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.image.BufferedImage; +import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; @@ -137,6 +138,7 @@ class ComboBoxCustomRenderer extends JLabel implements ListCellRenderer { public ComboBoxCustomRenderer() { + setFont(new Font("SansSerif", Font.BOLD, 32)); setOpaque(true); setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); diff --git a/test/jdk/javax/swing/JOptionPane/bug4174551.java b/test/jdk/javax/swing/JOptionPane/bug4174551.java index f65f95192b7e2..dbe6cdffe1a7d 100644 --- a/test/jdk/javax/swing/JOptionPane/bug4174551.java +++ b/test/jdk/javax/swing/JOptionPane/bug4174551.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4174551 + * @bug 4174551 8346260 * @summary JOptionPane should allow custom buttons * @library /java/awt/regtesthelpers * @build PassFailJFrame diff --git a/test/jdk/javax/swing/JPopupMenu/FocusablePopupDismissTest.java b/test/jdk/javax/swing/JPopupMenu/FocusablePopupDismissTest.java index 2704c9789e309..cb3811265dc12 100644 --- a/test/jdk/javax/swing/JPopupMenu/FocusablePopupDismissTest.java +++ b/test/jdk/javax/swing/JPopupMenu/FocusablePopupDismissTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,22 +24,28 @@ /* * @test * @key headful - * @bug 8319103 + * @bug 8319103 8342096 * @requires (os.family == "linux") - * @library /java/awt/regtesthelpers - * @build PassFailJFrame + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame jtreg.SkippedException * @summary Tests if the focusable popup can be dismissed when the parent * window or the popup itself loses focus in Wayland. * @run main/manual FocusablePopupDismissTest */ +import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTextField; import java.awt.Window; import java.util.List; +import jtreg.SkippedException; + public class FocusablePopupDismissTest { private static final String INSTRUCTIONS = """ A frame with a "Click me" button should appear next to the window @@ -47,44 +53,72 @@ public class FocusablePopupDismissTest { Click on the "Click me" button. - If the JTextField popup with "Some text" is not showing on the screen, - click Fail. + A menu should appear next to the window. If you move the cursor over + the first menu, the JTextField popup should appear on the screen. + If it doesn't, click Fail. The following steps require some focusable system window to be displayed on the screen. This could be a system settings window, file manager, etc. Click on the "Click me" button if the popup is not displayed - on the screen. + on the screen, move the mouse pointer over the menu. While the popup is displayed, click on some other window on the desktop. - If the popup has disappeared, click Pass, otherwise click Fail. + If the popup does not disappear, click Fail. + + Open the menu again, move the mouse cursor over the following: + "Focusable 1" -> "Focusable 2" -> "Editor Focusable 2" + Move the mouse to the focusable system window + (keeping the "Editor Focusable 2" JTextField open) and click on it. + + If the popup does not disappear, click Fail, otherwise click Pass. """; public static void main(String[] args) throws Exception { if (System.getenv("WAYLAND_DISPLAY") == null) { - //test is valid only when running on Wayland. - return; + throw new SkippedException("XWayland only test"); } PassFailJFrame.builder() .title("FocusablePopupDismissTest") .instructions(INSTRUCTIONS) - .rows(20) .columns(45) .testUI(FocusablePopupDismissTest::createTestUI) .build() .awaitAndCheck(); } + static JMenu getMenuWithMenuItem(boolean isSubmenuItemFocusable, String text) { + JMenu menu = new JMenu(text); + menu.add(isSubmenuItemFocusable + ? new JTextField("Editor " + text, 11) + : new JMenuItem("Menu item" + text) + ); + return menu; + } + static List createTestUI() { JFrame frame = new JFrame("FocusablePopupDismissTest"); JButton button = new JButton("Click me"); - frame.add(button); + + JPanel wrapper = new JPanel(); + wrapper.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16)); + wrapper.add(button); + + frame.add(wrapper); button.addActionListener(e -> { JPopupMenu popupMenu = new JPopupMenu(); - JTextField textField = new JTextField("Some text", 10); - popupMenu.add(textField); + + JMenu menu1 = new JMenu("Menu 1"); + menu1.add(new JTextField("Some text", 10)); + JMenu menu2 = new JMenu("Menu 2"); + menu2.add(new JTextField("Some text", 10)); + + popupMenu.add(getMenuWithMenuItem(true, "Focusable 1")); + popupMenu.add(getMenuWithMenuItem(true, "Focusable 2")); + popupMenu.add(getMenuWithMenuItem(false, "Non-Focusable 1")); + popupMenu.add(getMenuWithMenuItem(false, "Non-Focusable 2")); popupMenu.show(button, 0, button.getHeight()); }); frame.pack(); diff --git a/test/jdk/javax/swing/JPopupMenu/NestedFocusablePopupTest.java b/test/jdk/javax/swing/JPopupMenu/NestedFocusablePopupTest.java new file mode 100644 index 0000000000000..55963b081a558 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/NestedFocusablePopupTest.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary tests if nested menu is displayed on Wayland + * @requires (os.family == "linux") + * @key headful + * @bug 8342096 + * @library /test/lib + * @build jtreg.SkippedException + * @run main NestedFocusablePopupTest + */ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.IllegalComponentStateException; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import jtreg.SkippedException; + +public class NestedFocusablePopupTest { + + static volatile JMenu menuWithFocusableItem; + static volatile JMenu menuWithNonFocusableItem; + static volatile JPopupMenu popupMenu; + static volatile JFrame frame; + static volatile Robot robot; + + public static void main(String[] args) throws Exception { + if (System.getenv("WAYLAND_DISPLAY") == null) { + throw new SkippedException("XWayland only test"); + } + + robot = new Robot(); + robot.setAutoDelay(50); + + try { + SwingUtilities.invokeAndWait(NestedFocusablePopupTest::initAndShowGui); + test0(); + test1(); + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + + public static void waitTillShown(final Component component, long msTimeout) + throws InterruptedException, TimeoutException { + long startTime = System.currentTimeMillis(); + + while (true) { + try { + Thread.sleep(50); + component.getLocationOnScreen(); + break; + } catch (IllegalComponentStateException e) { + if (System.currentTimeMillis() - startTime > msTimeout) { + throw new TimeoutException("Component not shown within the specified timeout"); + } + } + } + } + + static Rectangle waitAndGetOnScreenBoundsOnEDT(Component component) + throws InterruptedException, TimeoutException, ExecutionException { + waitTillShown(component, 500); + robot.waitForIdle(); + + FutureTask task = new FutureTask<>(() + -> new Rectangle(component.getLocationOnScreen(), component.getSize())); + SwingUtilities.invokeLater(task); + return task.get(500, TimeUnit.MILLISECONDS); + } + + static void test0() throws Exception { + Rectangle frameBounds = waitAndGetOnScreenBoundsOnEDT(frame); + robot.mouseMove(frameBounds.x + frameBounds.width / 2, + frameBounds.y + frameBounds.height / 2); + + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + Rectangle menuBounds = waitAndGetOnScreenBoundsOnEDT(menuWithFocusableItem); + robot.mouseMove(menuBounds.x + 5, menuBounds.y + 5); + + // Give popup some time to disappear (in case of failure) + robot.waitForIdle(); + robot.delay(200); + + try { + waitTillShown(popupMenu, 500); + } catch (TimeoutException e) { + throw new RuntimeException("The popupMenu disappeared when it shouldn't have."); + } + } + + static void test1() throws Exception { + Rectangle frameBounds = waitAndGetOnScreenBoundsOnEDT(frame); + robot.mouseMove(frameBounds.x + frameBounds.width / 2, + frameBounds.y + frameBounds.height / 2); + + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + Rectangle menuBounds = waitAndGetOnScreenBoundsOnEDT(menuWithFocusableItem); + robot.mouseMove(menuBounds.x + 5, menuBounds.y + 5); + robot.waitForIdle(); + robot.delay(200); + + menuBounds = waitAndGetOnScreenBoundsOnEDT(menuWithNonFocusableItem); + robot.mouseMove(menuBounds.x + 5, menuBounds.y + 5); + + // Give popup some time to disappear (in case of failure) + robot.waitForIdle(); + robot.delay(200); + + try { + waitTillShown(popupMenu, 500); + } catch (TimeoutException e) { + throw new RuntimeException("The popupMenu disappeared when it shouldn't have."); + } + } + + static JMenu getMenuWithMenuItem(boolean isSubmenuItemFocusable, String text) { + JMenu menu = new JMenu(text); + menu.add(isSubmenuItemFocusable + ? new JButton(text) + : new JMenuItem(text) + ); + return menu; + } + + private static void initAndShowGui() { + frame = new JFrame("NestedFocusablePopupTest"); + JPanel panel = new JPanel(); + panel.setPreferredSize(new Dimension(200, 180)); + + + popupMenu = new JPopupMenu(); + menuWithFocusableItem = + getMenuWithMenuItem(true, "focusable subitem"); + menuWithNonFocusableItem = + getMenuWithMenuItem(false, "non-focusable subitem"); + + popupMenu.add(menuWithFocusableItem); + popupMenu.add(menuWithNonFocusableItem); + + panel.setComponentPopupMenu(popupMenu); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/JProgressBar/TestProgressBarUI.java b/test/jdk/javax/swing/JProgressBar/TestProgressBarUI.java new file mode 100644 index 0000000000000..0091fe625c9bd --- /dev/null +++ b/test/jdk/javax/swing/JProgressBar/TestProgressBarUI.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8318577 + * @summary Tests JProgressBarUI renders correctly in Windows L&F + * @requires (os.family == "windows") + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestProgressBarUI + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class TestProgressBarUI { + + private static final String instructionsText = """ + Two progressbar "Good" and "Bad" + will be shown with different preferred size, + If the "Bad" progressbar is rendered at the same + height as "Good" progressbar, + without any difference in padding internally + the test passes, otherwise fails. """; + + public static void main(String[] args) throws Exception { + System.setProperty("sun.java2d.uiScale", "2.0"); + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + PassFailJFrame.builder() + .title("ProgressBar Instructions") + .instructions(instructionsText) + .rows(9) + .columns(36) + .testUI(TestProgressBarUI::doTest) + .build() + .awaitAndCheck(); + } + + public static JFrame doTest() { + JFrame frame = new JFrame("JProgressBar"); + + JPanel panel = new JPanel(new FlowLayout(20, 20, FlowLayout.LEADING)); + panel.setBackground(Color.white); + + JProgressBar p1 = new JProgressBar(0, 100); + p1.setValue(50); + p1.setStringPainted(true); + p1.setString("GOOD"); + p1.setPreferredSize(new Dimension(100, 21)); + panel.add(p1); + + JProgressBar p2 = new JProgressBar(0, 100); + p2.setValue(50); + p2.setStringPainted(true); + p2.setString("BAD"); + + p2.setPreferredSize(new Dimension(100, 22)); + panel.add(p2); + + JComponent c = (JComponent) frame.getContentPane(); + c.add(panel, BorderLayout.CENTER); + + frame.pack(); + frame.setLocationByPlatform(true); + return frame; + } +} diff --git a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java index 699338c4b30f5..30d83a0538eb7 100644 --- a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,6 @@ public static void main(String[] args) throws Throwable { }); robot = new Robot(); - robot.setAutoDelay(100); robot.waitForIdle(); robot.delay(1000); diff --git a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java index c696b166dd085..633b0356f85df 100644 --- a/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java +++ b/test/jdk/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,26 +28,53 @@ * @run main ButtonGroupFocusTest */ -import javax.swing.*; -import java.awt.*; +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.concurrent.CountDownLatch; -public class ButtonGroupFocusTest { +import javax.imageio.ImageIO; +import javax.swing.ButtonGroup; +import javax.swing.JFrame; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; + +import static java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +public final class ButtonGroupFocusTest { private static JRadioButton button1; private static JRadioButton button2; private static JRadioButton button3; private static JRadioButton button4; private static JRadioButton button5; - private static Robot robot; + + private static final CountDownLatch button2FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button3FocusLatch = new CountDownLatch(1); + private static final CountDownLatch button4FocusLatch = new CountDownLatch(1); + + private static final CountDownLatch button2FocusLatch2 = new CountDownLatch(2); + + private static final long FOCUS_TIMEOUT = 4; + private static JFrame frame; public static void main(String[] args) throws Exception { - robot = new Robot(); - robot.setAutoDelay(100); + final Robot robot = new Robot(); SwingUtilities.invokeAndWait(() -> { - frame = new JFrame(); + frame = new JFrame("ButtonGroupFocusTest"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); button1 = new JRadioButton("Button 1"); @@ -60,6 +87,7 @@ public static void main(String[] args) throws Exception { contentPane.add(button4); button5 = new JRadioButton("Button 5"); contentPane.add(button5); + ButtonGroup group = new ButtonGroup(); group.add(button1); group.add(button2); @@ -69,52 +97,96 @@ public static void main(String[] args) throws Exception { group.add(button4); group.add(button5); + button2.addFocusListener(new LatchFocusListener(button2FocusLatch)); + button3.addFocusListener(new LatchFocusListener(button3FocusLatch)); + button4.addFocusListener(new LatchFocusListener(button4FocusLatch)); + + button2.addFocusListener(new LatchFocusListener(button2FocusLatch2)); + button2.setSelected(true); + // Debugging aid: log focus owner changes... + KeyboardFocusManager focusManager = getCurrentKeyboardFocusManager(); + focusManager.addPropertyChangeListener("focusOwner", + e -> System.out.println(e.getPropertyName() + + "\n\t" + e.getOldValue() + + "\n\t" + e.getNewValue())); + + // ...and dispatched key events + Toolkit.getDefaultToolkit().addAWTEventListener( + e -> System.out.println("Dispatched " + e), + AWTEvent.KEY_EVENT_MASK); + frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); }); - robot.waitForIdle(); - robot.delay(200); - - SwingUtilities.invokeAndWait(() -> { - if( !button2.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 2 should get focus after activation"); + try { + if (!button2FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 2 should get focus " + + "after activation"); } - }); + robot.waitForIdle(); + robot.delay(200); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + System.out.println("\n\n*** Tab 1st"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - robot.waitForIdle(); - robot.delay(200); + if (!button4FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Button 4 should get focus"); + } + robot.waitForIdle(); + robot.delay(200); - SwingUtilities.invokeAndWait(() -> { - if( !button4.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "Button 4 should get focus"); + if (button2FocusLatch2.await(1, MILLISECONDS)) { + throw new RuntimeException("Focus moved back to Button 2"); } - button3.setSelected(true); - }); - robot.keyPress(KeyEvent.VK_TAB); - robot.keyRelease(KeyEvent.VK_TAB); + SwingUtilities.invokeAndWait(() -> button3.setSelected(true)); + robot.waitForIdle(); + robot.delay(200); - robot.waitForIdle(); - robot.delay(200); + System.out.println("\n\n*** Tab 2nd"); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); - SwingUtilities.invokeAndWait(() -> { - if( !button3.hasFocus() ) { - frame.dispose(); - throw new RuntimeException( - "selected Button 3 should get focus"); + if (!button3FocusLatch.await(FOCUS_TIMEOUT, SECONDS)) { + throw new RuntimeException("Selected Button 3 should get focus"); } - }); + } catch (Exception e) { + BufferedImage image = robot.createScreenCapture(getFrameBounds()); + ImageIO.write(image, "png", + new File("image.png")); + + SwingUtilities.invokeAndWait(() -> + System.err.println("Current focus owner: " + + getCurrentKeyboardFocusManager() + .getFocusOwner())); + + throw e; + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + + private static Rectangle getFrameBounds() throws Exception { + Rectangle[] bounds = new Rectangle[1]; + SwingUtilities.invokeAndWait(() -> bounds[0] = frame.getBounds()); + return bounds[0]; + } + + private static final class LatchFocusListener extends FocusAdapter { + private final CountDownLatch focusGainedLatch; + + private LatchFocusListener(CountDownLatch focusGainedLatch) { + this.focusGainedLatch = focusGainedLatch; + } - SwingUtilities.invokeLater(frame::dispose); + @Override + public void focusGained(FocusEvent e) { + focusGainedLatch.countDown(); + } } } diff --git a/test/jdk/javax/swing/JScrollBar/4865918/bug4865918.java b/test/jdk/javax/swing/JScrollBar/4865918/bug4865918.java index ea20840d8623a..96b1034c943de 100644 --- a/test/jdk/javax/swing/JScrollBar/4865918/bug4865918.java +++ b/test/jdk/javax/swing/JScrollBar/4865918/bug4865918.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,44 +23,42 @@ /* * @test - * @key headful * @bug 4865918 + * @requires (os.family != "mac") * @summary REGRESSION:JCK1.4a-runtime api/javax_swing/interactive/JScrollBarTests.html#JScrollBar * @run main bug4865918 */ import java.awt.Dimension; -import java.awt.Robot; -import javax.swing.JFrame; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import javax.swing.JScrollBar; import javax.swing.SwingUtilities; -import java.awt.event.MouseEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.Date; public class bug4865918 { private static TestScrollBar sbar; - private static JFrame frame; + private static final CountDownLatch mousePressLatch = new CountDownLatch(1); public static void main(String[] argv) throws Exception { - try { - Robot robot = new Robot(); - SwingUtilities.invokeAndWait(() -> createAndShowGUI()); - - robot.waitForIdle(); - robot.delay(1000); - - SwingUtilities.invokeAndWait(() -> sbar.pressMouse()); + String osName = System.getProperty("os.name"); + if (osName.toLowerCase().contains("os x")) { + System.out.println("This test is not for MacOS, considered passed."); + return; + } + SwingUtilities.invokeAndWait(() -> setupTest()); - robot.waitForIdle(); - robot.delay(200); + SwingUtilities.invokeAndWait(() -> sbar.pressMouse()); + if (!mousePressLatch.await(2, TimeUnit.SECONDS)) { + throw new RuntimeException("Timed out waiting for mouse press"); + } - if (getValue() != 9) { - throw new RuntimeException("The scrollbar block increment is incorrect"); - } - } finally { - if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose()); + if (getValue() != 9) { + throw new RuntimeException("The scrollbar block increment is incorrect"); } } @@ -71,22 +69,21 @@ private static int getValue() throws Exception { result[0] = sbar.getValue(); }); + System.out.println("value " + result[0]); return result[0]; } - private static void createAndShowGUI() { - frame = new JFrame("bug4865918"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + private static void setupTest() { sbar = new TestScrollBar(JScrollBar.HORIZONTAL, -1, 10, -100, 100); sbar.setPreferredSize(new Dimension(200, 20)); sbar.setBlockIncrement(10); + sbar.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + mousePressLatch.countDown(); + } + }); - frame.getContentPane().add(sbar); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - frame.toFront(); } static class TestScrollBar extends JScrollBar { diff --git a/test/jdk/javax/swing/JTabbedPane/8134116/Bug8134116.java b/test/jdk/javax/swing/JTabbedPane/8134116/Bug8134116.java index 97164c253ddae..6a39d7b96fab7 100644 --- a/test/jdk/javax/swing/JTabbedPane/8134116/Bug8134116.java +++ b/test/jdk/javax/swing/JTabbedPane/8134116/Bug8134116.java @@ -1,13 +1,43 @@ +/* + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ -import java.awt.*; +import java.awt.Component; +import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; + import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; -import javax.swing.*; +import javax.swing.Icon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.plaf.nimbus.NimbusLookAndFeel; /* @@ -22,7 +52,7 @@ public class Bug8134116 { private static volatile Exception exception = null; private static JFrame frame; - public static void main(String args[]) throws Exception { + public static void main(String[] args) throws Exception { try { UIManager.setLookAndFeel(new NimbusLookAndFeel()); diff --git a/test/jdk/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java b/test/jdk/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java index 19d6d6a86079d..c02fcfcfb9073 100644 --- a/test/jdk/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java +++ b/test/jdk/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -222,11 +222,11 @@ public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.draw(new Line2D.Float(c, cy, c, cy + ch)); - g2d.draw(new Line2D.Float(cx, cy, cx + cw, cy)); - g2d.draw(new Line2D.Float(cx, cy + ch, cx + cw, cy + ch)); } void repaint(Rectangle r) { + r.width += 1; + r.height += 1; component.repaint(r); } @@ -424,6 +424,8 @@ protected void adjustVisibility(Rectangle nloc) { protected synchronized void damage(Rectangle r) { if (r != null && component != null) { + r.width += 1; + r.height += 1; component.repaint(r); } } diff --git a/test/jdk/javax/xml/jaxp/common/8323740/InitializerTest.java b/test/jdk/javax/xml/jaxp/common/8323740/InitializerTest.java new file mode 100644 index 0000000000000..3cf685331b1b9 --- /dev/null +++ b/test/jdk/javax/xml/jaxp/common/8323740/InitializerTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Google LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.Test; + +import java.util.Objects; + +/** + * @test + * + * @bug 8323740 + * @summary test that class initializers don't crash + * @run testng/othervm InitializerTest + */ +public class InitializerTest { + + @Test + public void testXMLOutputFactory() throws Exception { + String name = "com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl"; + Objects.requireNonNull(Class.forName(name)); + } +} diff --git a/test/jdk/jdk/classfile/InstructionValidationTest.java b/test/jdk/jdk/classfile/InstructionValidationTest.java index 17210e1173b3a..3e065260abff1 100644 --- a/test/jdk/jdk/classfile/InstructionValidationTest.java +++ b/test/jdk/jdk/classfile/InstructionValidationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,13 +32,17 @@ import java.lang.classfile.constantpool.ClassEntry; import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.instruction.*; +import java.lang.constant.ClassDesc; +import java.lang.reflect.Parameter; import java.util.List; +import java.util.function.Consumer; import java.util.function.ObjIntConsumer; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; +import static java.lang.classfile.ClassFile.ACC_STATIC; import static java.lang.constant.ConstantDescs.*; import static org.junit.jupiter.api.Assertions.*; import static java.lang.classfile.Opcode.*; @@ -110,17 +114,23 @@ record Result(boolean shouldFail, int slot) { var fails = r.shouldFail; var i = r.slot; for (var fac : cbFactories) { - //check(fails, () -> execute(cob -> fac.accept(cob, i))); + if (fails) { + ensureFailFast(i, cob -> fac.accept(cob, i)); + } } for (TypeKind tk : TypeKind.values()) { if (tk == TypeKind.VOID) continue; - //check(fails, () -> execute(cob -> cob.loadLocal(tk, i))); - //check(fails, () -> execute(cob -> cob.storeLocal(tk, i))); + if (fails) { + ensureFailFast(i, cob -> cob.loadLocal(tk, i)); + ensureFailFast(i, cob -> cob.storeLocal(tk, i)); + } check(fails, () -> LoadInstruction.of(tk, i)); check(fails, () -> StoreInstruction.of(tk, i)); } - //check(fails, () -> execute(cob -> cob.iinc(i, 1))); + if (fails) { + ensureFailFast(i, cob -> cob.iinc(i, 1)); + } check(fails, () -> IncrementInstruction.of(i, 1)); check(fails, () -> DiscontinuedInstruction.RetInstruction.of(i)); check(fails, () -> DiscontinuedInstruction.RetInstruction.of(RET_W, i)); @@ -150,6 +160,31 @@ record Result(boolean shouldFail, int slot) { } } + // CodeBuilder can fail with IAE due to other reasons, so we cannot check + // "success" but can ensure things fail fast + static void ensureFailFast(int value, Consumer action) { + // Can fail with AssertionError instead of IAE + Consumer checkedAction = cob -> { + action.accept(cob); + fail("Bad slot access did not fail fast: " + value); + }; + var cf = ClassFile.of(); + CodeTransform noopCodeTransform = CodeBuilder::with; + // Direct builders + assertThrows(IllegalArgumentException.class, () -> cf.build(ClassDesc.of("Test"), clb -> clb + .withMethodBody("test", MTD_void, ACC_STATIC, checkedAction))); + // Chained builders + assertThrows(IllegalArgumentException.class, () -> cf.build(ClassDesc.of("Test"), clb -> clb + .withMethodBody("test", MTD_void, ACC_STATIC, cob -> cob + .transforming(CodeTransform.ACCEPT_ALL, checkedAction)))); + var classTemplate = cf.build(ClassDesc.of("Test"), clb -> clb + .withMethodBody("test", MTD_void, ACC_STATIC, CodeBuilder::return_)); + // Indirect builders + assertThrows(IllegalArgumentException.class, () -> cf.transformClass(cf.parse(classTemplate), + ClassTransform.transformingMethodBodies(CodeTransform.endHandler(checkedAction) + .andThen(noopCodeTransform)))); + } + static void check(boolean fails, Executable exec) { if (fails) { assertThrows(IllegalArgumentException.class, exec); @@ -163,8 +198,10 @@ void testIincConstant() { IncrementInstruction.of(0, 2); IncrementInstruction.of(0, Short.MAX_VALUE); IncrementInstruction.of(0, Short.MIN_VALUE); - assertThrows(IllegalArgumentException.class, () -> IncrementInstruction.of(0, Short.MAX_VALUE + 1)); - assertThrows(IllegalArgumentException.class, () -> IncrementInstruction.of(0, Short.MIN_VALUE - 1)); + for (int i : new int[] {Short.MIN_VALUE - 1, Short.MAX_VALUE + 1}) { + assertThrows(IllegalArgumentException.class, () -> IncrementInstruction.of(0, i)); + ensureFailFast(i, cob -> cob.iinc(0, i)); + } } @Test diff --git a/test/jdk/jdk/classfile/SnippetsTest.java b/test/jdk/jdk/classfile/SnippetsTest.java index f6fa2281e14ee..d15dbc0ca3d64 100644 --- a/test/jdk/jdk/classfile/SnippetsTest.java +++ b/test/jdk/jdk/classfile/SnippetsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,10 @@ public class SnippetsTest { @ParameterizedTest @ValueSource(strings = { "src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java", - "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java"}) + "src/java.base/share/classes/java/lang/classfile/attribute/snippet-files/PackageSnippets.java", + "src/java.base/share/classes/java/lang/classfile/constantpool/snippet-files/PackageSnippets.java", + "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java" + }) void testSnippet(String source) throws Exception { var p = Paths.get(System.getProperty("test.src", ".")).toAbsolutePath(); while ((p = p.getParent()) != null) { diff --git a/test/jdk/jdk/classfile/TEST.properties b/test/jdk/jdk/classfile/TEST.properties index 62414b36eae48..2d8d20cf1f4c0 100644 --- a/test/jdk/jdk/classfile/TEST.properties +++ b/test/jdk/jdk/classfile/TEST.properties @@ -2,6 +2,4 @@ maxOutputSize = 2500000 modules = \ java.base/jdk.internal.classfile.components \ java.base/jdk.internal.classfile.impl \ - java.base/jdk.internal.classfile.impl.verifier \ - java.base/jdk.internal.org.objectweb.asm \ - java.base/jdk.internal.org.objectweb.asm.tree \ No newline at end of file + java.base/jdk.internal.classfile.impl.verifier \ No newline at end of file diff --git a/test/jdk/jdk/classfile/helpers/Transforms.java b/test/jdk/jdk/classfile/helpers/Transforms.java index b0e88bd8212b5..dba3f21cbd83d 100644 --- a/test/jdk/jdk/classfile/helpers/Transforms.java +++ b/test/jdk/jdk/classfile/helpers/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,27 +43,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -128,42 +113,10 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); - // Need ASM, LOW_UNSHARED + // Need LOW_UNSHARED public final UnaryOperator transform; public final boolean shared; @@ -202,12 +155,6 @@ public Optional classRecord(byte[] bytes) throws IOException { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -242,13 +189,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -273,20 +213,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -319,277 +245,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } diff --git a/test/jdk/jdk/incubator/vector/ScalarFloat16OperationsTest.java b/test/jdk/jdk/incubator/vector/ScalarFloat16OperationsTest.java new file mode 100644 index 0000000000000..e28ba401197ea --- /dev/null +++ b/test/jdk/jdk/incubator/vector/ScalarFloat16OperationsTest.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8342103 + * @summary C2 compiler support for Float16 type and associated operations + * @modules jdk.incubator.vector + * @library /test/lib + * @compile ScalarFloat16OperationsTest.java + * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation -XX:-UseSuperWord ScalarFloat16OperationsTest + * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation -XX:+UseSuperWord ScalarFloat16OperationsTest + */ + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Random; +import java.util.stream.IntStream; +import jdk.incubator.vector.Float16; +import static jdk.incubator.vector.Float16.*; + +public class ScalarFloat16OperationsTest { + static final int SIZE = 65504; + static Random r = jdk.test.lib.Utils.getRandomInstance(); + static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); + + @DataProvider + public static Object[][] unaryOpProvider() { + Float16 [] input = new Float16[SIZE]; + Float16 [] special_input = { + Float16.MAX_VALUE, Float16.MIN_VALUE, Float16.MIN_NORMAL, Float16.POSITIVE_INFINITY, + Float16.NEGATIVE_INFINITY, Float16.valueOf(0.0f), Float16.valueOf(-0.0f), Float16.NaN + }; + + // Input array covers entire Float16 value range + IntStream.range(0, input.length).forEach(i -> {input[i] = valueOf(i);}); + + return new Object[][] { + {input}, + {special_input} + }; + } + + @DataProvider + public static Object[][] binaryOpProvider() { + Float16 [] input1 = new Float16[SIZE]; + Float16 [] input2 = new Float16[SIZE]; + Float16 [] special_input = { + Float16.MAX_VALUE, Float16.MIN_VALUE, Float16.MIN_NORMAL, Float16.POSITIVE_INFINITY, + Float16.NEGATIVE_INFINITY, Float16.valueOf(0.0f), Float16.valueOf(-0.0f), Float16.NaN + }; + + // Input arrays covers entire Float16 value range interspersed with special values. + IntStream.range(0, input1.length).forEach(i -> {input1[i] = valueOf(i);}); + IntStream.range(0, input2.length).forEach(i -> {input2[i] = valueOf(i);}); + + for (int i = 0; i < special_input.length; i += 256) { + input1[r.nextInt(input1.length)] = special_input[i]; + input2[r.nextInt(input2.length)] = special_input[i]; + } + + return new Object[][] { + {input1, input2}, + {special_input, special_input}, + }; + } + + @DataProvider + public static Object[][] ternaryOpProvider() { + Float16 [] input1 = new Float16[SIZE]; + Float16 [] input2 = new Float16[SIZE]; + Float16 [] input3 = new Float16[SIZE]; + Float16 [] special_input = { + Float16.MAX_VALUE, Float16.MIN_VALUE, Float16.MIN_NORMAL, Float16.POSITIVE_INFINITY, + Float16.NEGATIVE_INFINITY, Float16.valueOf(0.0f), Float16.valueOf(-0.0f), Float16.NaN + }; + + // Input arrays covers entire Float16 value range interspersed with special values. + IntStream.range(0, input1.length).forEach(i -> {input1[i] = valueOf(i);}); + IntStream.range(0, input2.length).forEach(i -> {input2[i] = valueOf(i);}); + IntStream.range(0, input3.length).forEach(i -> {input3[i] = valueOf(i);}); + for (int i = 0; i < special_input.length; i += 256) { + input1[r.nextInt(input1.length)] = special_input[i]; + input2[r.nextInt(input2.length)] = special_input[i]; + input3[r.nextInt(input3.length)] = special_input[i]; + } + + return new Object[][] { + {input1, input2, input3}, + {special_input, special_input, special_input}, + }; + } + + interface FUnOp1 { + Float16 apply(Float16 a); + } + + interface FUnOp2 { + boolean apply(Float16 a); + } + + static void assertArraysEquals(Float16[] r, Float16[] a, FUnOp1 f) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], f.apply(a[i])); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]); + } + } + + static void assertArraysEquals(boolean[] r, Float16[] a, FUnOp2 f) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], f.apply(a[i])); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]); + } + } + + interface FBinOp { + Float16 apply(Float16 a, Float16 b); + } + + static void assertArraysEquals(Float16[] r, Float16[] a, Float16[] b, FBinOp f) { + int i = 0; + try { + for (; i < r.length; i++) { + Assert.assertEquals(r[i], f.apply(a[i], b[i])); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], f.apply(a[i], b[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i]); + } + } + + interface FTernOp { + Float16 apply(Float16 a, Float16 b, Float16 c); + } + + static void assertArraysEquals(Float16[] r, Float16[] a, Float16[] b, Float16[] c, FTernOp f) { + int i = 0; + try { + for (; i < r.length; i++) { + Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i])); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + } + } + + + @Test(dataProvider = "unaryOpProvider") + public static void absTest(Object input) { + Float16 [] farr = (Float16[])input; + Float16 [] res = new Float16[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = abs(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> valueOf(Math.abs(fp16.floatValue()))); + } + + @Test(dataProvider = "unaryOpProvider") + public static void negTest(Object input) { + Float16 [] farr = (Float16[])input; + Float16 [] res = new Float16[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = negate(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> shortBitsToFloat16((short)(float16ToRawShortBits(fp16) ^ (short)0x0000_8000))); + } + + @Test(dataProvider = "unaryOpProvider") + public static void sqrtTest(Object input) { + Float16 [] farr = (Float16[])input; + Float16 [] res = new Float16[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = sqrt(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> valueOf(Math.sqrt(fp16.floatValue()))); + } + + @Test(dataProvider = "unaryOpProvider") + public static void isInfiniteTest(Object input) { + Float16 [] farr = (Float16[])input; + boolean [] res = new boolean[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = isInfinite(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> Float.isInfinite(fp16.floatValue())); + } + + @Test(dataProvider = "unaryOpProvider") + public static void isFiniteTest(Object input) { + Float16 [] farr = (Float16[])input; + boolean [] res = new boolean[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = isFinite(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> Float.isFinite(fp16.floatValue())); + } + + @Test(dataProvider = "unaryOpProvider") + public static void isNaNTest(Object input) { + Float16 [] farr = (Float16[])input; + boolean [] res = new boolean[farr.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = isNaN(farr[i]); + } + } + assertArraysEquals(res, farr, (fp16) -> Float.isNaN(fp16.floatValue())); + } + + @Test(dataProvider = "binaryOpProvider") + public static void addTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = add(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(fp16_val1.floatValue() + fp16_val2.floatValue())); + } + + @Test(dataProvider = "binaryOpProvider") + public static void subtractTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = subtract(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(fp16_val1.floatValue() - fp16_val2.floatValue())); + } + + @Test(dataProvider = "binaryOpProvider") + public static void multiplyTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = multiply(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(fp16_val1.floatValue() * fp16_val2.floatValue())); + } + + @Test(dataProvider = "binaryOpProvider") + public static void divideTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = divide(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(fp16_val1.floatValue() / fp16_val2.floatValue())); + } + + @Test(dataProvider = "binaryOpProvider") + public static void maxTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = max(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(Float.max(fp16_val1.floatValue(), fp16_val2.floatValue()))); + } + + @Test(dataProvider = "binaryOpProvider") + public static void minTest(Object input1, Object input2) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = min(farr1[i], farr2[i]); + } + } + assertArraysEquals(res, farr1, farr2, (fp16_val1, fp16_val2) -> valueOf(Float.min(fp16_val1.floatValue(), fp16_val2.floatValue()))); + } + + @Test(dataProvider = "ternaryOpProvider") + public static void fmaTest(Object input1, Object input2, Object input3) { + Float16 [] farr1 = (Float16[])input1; + Float16 [] farr2 = (Float16[])input2; + Float16 [] farr3 = (Float16[])input2; + + Float16 [] res = new Float16[farr1.length]; + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < res.length; i++) { + res[i] = fma(farr1[i], farr2[i], farr3[i]); + } + } + assertArraysEquals(res, farr1, farr2, farr3, (fp16_val1, fp16_val2, fp16_val3) -> valueOf(Math.fma(fp16_val1.floatValue(), fp16_val2.floatValue(), fp16_val3.floatValue()))); + } +} diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java index e1790e6e17456..48886db87c666 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,14 +68,11 @@ public class CheckCSMs { // The goal is to remove this list of Non-final instance @CS methods // over time. Do not add any new one to this list. - private static final Set KNOWN_NON_FINAL_CSMS = - Set.of("java/lang/Runtime#load (Ljava/lang/String;)V", - "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V" - ); + private static final Set KNOWN_NON_FINAL_CSMS = Set.of(); // These non-static non-final methods must not have @CallerSensitiveAdapter // methods that takes an additional caller class parameter. - private static Set UNSUPPORTED_VIRTUAL_METHODS = Set.of(); + private static final Set UNSUPPORTED_VIRTUAL_METHODS = Set.of(); public static void main(String[] args) throws Exception { if (args.length > 0 && args[0].equals("--list")) { diff --git a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java index 97c7cf4c4928f..88d7e23ba5962 100644 --- a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java +++ b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8210496 + * @bug 8210496 8349145 8346567 * @modules java.base/jdk.internal.reflect * @run testng Filtering * @summary Test that security sensitive fields that filtered by core reflection @@ -55,6 +55,9 @@ private Object[][] sensitiveFields() { { AccessibleObject.class, "override" }, { Class.class, "classLoader" }, { Class.class, "classData" }, + { Class.class, "modifiers" }, + { Class.class, "protectionDomain" }, + { Class.class, "primitive" }, { ClassLoader.class, "parent" }, { Field.class, "clazz" }, { Field.class, "modifiers" }, diff --git a/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamAvailable.java b/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamAvailable.java index 07f796d47d329..e4eaccc0057c3 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamAvailable.java +++ b/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamAvailable.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +24,7 @@ /** * @test TestChunkInputStreamAvailable - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestChunkInputStreamAvailable diff --git a/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamBulkRead.java b/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamBulkRead.java index 15bf1b7707c6d..5733f2f0cf654 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamBulkRead.java +++ b/test/jdk/jdk/jfr/api/consumer/TestChunkInputStreamBulkRead.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Palantir Technologies, Inc. and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +24,7 @@ /** * @test TestChunkInputStreamBulkRead - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestChunkInputStreamBulkRead diff --git a/test/jdk/jdk/jfr/api/consumer/TestFieldAccess.java b/test/jdk/jdk/jfr/api/consumer/TestFieldAccess.java index 3a35ca6d7512b..bb2e145467ce7 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestFieldAccess.java +++ b/test/jdk/jdk/jfr/api/consumer/TestFieldAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestFieldAccess diff --git a/test/jdk/jdk/jfr/api/consumer/TestGetStackTrace.java b/test/jdk/jdk/jfr/api/consumer/TestGetStackTrace.java index fa26270ccebb2..9dcdfaf84e0dd 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestGetStackTrace.java +++ b/test/jdk/jdk/jfr/api/consumer/TestGetStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test * @summary Verifies that a recorded JFR event has the correct stack trace info - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestGetStackTrace diff --git a/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java b/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java index ad68e016a1a10..969016ebf35ea 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java +++ b/test/jdk/jdk/jfr/api/consumer/TestHiddenMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/consumer/TestMethodGetModifiers.java b/test/jdk/jdk/jfr/api/consumer/TestMethodGetModifiers.java index 9b5505c55deb9..d98fbdfcfd542 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestMethodGetModifiers.java +++ b/test/jdk/jdk/jfr/api/consumer/TestMethodGetModifiers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Verifies that a recorded method has the correct modifier - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xint jdk.jfr.api.consumer.TestMethodGetModifiers diff --git a/test/jdk/jdk/jfr/api/consumer/TestReadTwice.java b/test/jdk/jdk/jfr/api/consumer/TestReadTwice.java index 97ef76ece85b5..8990ffaa03d2b 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestReadTwice.java +++ b/test/jdk/jdk/jfr/api/consumer/TestReadTwice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Reads the recorded file two times and verifies that both reads are the same - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestReadTwice diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java index 19c637049197c..003e8c91edd00 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java @@ -35,7 +35,7 @@ /** * @test * @summary Verifies methods of RecordedClass - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedClass diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedClassLoader.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedClassLoader.java index a7b03149ce92e..f58c4051d3c27 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedClassLoader.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Verifies the methods of the RecordedClassLoader - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedClassLoader diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedEvent.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedEvent.java index 9223d2ef5ad0f..1bfeb8accec1e 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedEvent.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Verifies the methods of the RecordedEvent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedEvent diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThread.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThread.java index d3d581bc374ba..f05846b7284d4 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThread.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Tests that the RecordedEvent.getThread() returns th expected info - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedEventGetThread diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThreadOther.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThreadOther.java index daaec8c05576b..2e5e767b0e10e 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThreadOther.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedEventGetThreadOther.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Tests that the RecordedEvent.getThread() returns th expected info - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedEventGetThreadOther diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java index 611ed0e688f47..2e6abd960a826 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Simple test for RecordedFrame APIs - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedFrame diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrameType.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrameType.java index a44bdd371f073..c988f37bd0b4d 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedFrameType.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedFrameType.java @@ -39,7 +39,7 @@ /** * @test * @summary Test jdk.jfr.consumer.RecordedFrame::getType() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.compiler1.enabled * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java index 18fcb30038205..7506932981137 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedFullStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedFullStackTrace diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedInstantEventTimestamp.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedInstantEventTimestamp.java index 8c37fe8743b2f..c4f2966d40a5b 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedInstantEventTimestamp.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedInstantEventTimestamp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Tests that an instant event gets recorded with its start time equal to its end time - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedInstantEventTimestamp diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedMethodDescriptor.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedMethodDescriptor.java index 884697c26a531..a80203543960c 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedMethodDescriptor.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedMethodDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary Verifies that the method descriptor is correct - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedMethodDescriptor diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedObject.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedObject.java index 17878ff7e6ce6..772a0ca641954 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedObject.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ /** * @test * @summary Verifies the methods of the RecordedObject - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedObject diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedThreadGroupParent.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedThreadGroupParent.java index dae9b8fc11a8d..e5b40a34d1ef3 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordedThreadGroupParent.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedThreadGroupParent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Tests getParent method in RecordedThreadGroup - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordedThreadGroupParent diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordingFile.java b/test/jdk/jdk/jfr/api/consumer/TestRecordingFile.java index a81262f9405c8..5aeee69cadc2e 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordingFile.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordingFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ /** * @test * @summary Verifies that all methods in RecordingFIle are working - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr*=info jdk.jfr.api.consumer.TestRecordingFile diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileReadEventEof.java b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileReadEventEof.java index 1c98f293c243d..c92b2362ce4b3 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileReadEventEof.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileReadEventEof.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Verifies that RecordingFile.readEvent() throws EOF when past the last record - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordingFileReadEventEof diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileSanitization.java b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileSanitization.java index 75e01f82cd403..dfa39b4ad8595 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileSanitization.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileSanitization.java @@ -35,7 +35,7 @@ /** * @test * @summary Verifies that all traces of sensitive data is removed - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordingFileSanitization diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileWrite.java b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileWrite.java index f4cf5a20805fd..5fc0dab0d30aa 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordingFileWrite.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordingFileWrite.java @@ -39,7 +39,7 @@ /** * @test * @summary Tests RecordingFile::write(Path, Predicate) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordingFileWrite diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordingInternals.java b/test/jdk/jdk/jfr/api/consumer/TestRecordingInternals.java index 75513f5b7b44f..efa36c799878b 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestRecordingInternals.java +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordingInternals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Tests that chunks are read in order and constant pools from multiple chunks can be read - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestRecordingInternals diff --git a/test/jdk/jdk/jfr/api/consumer/TestSingleRecordedEvent.java b/test/jdk/jdk/jfr/api/consumer/TestSingleRecordedEvent.java index f8bd63b915a68..1580647b43c72 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestSingleRecordedEvent.java +++ b/test/jdk/jdk/jfr/api/consumer/TestSingleRecordedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Verifies that a single JFR event is recorded as expected - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestSingleRecordedEvent diff --git a/test/jdk/jdk/jfr/api/consumer/TestToString.java b/test/jdk/jdk/jfr/api/consumer/TestToString.java index 3c36317662471..7f75a55e0f1ba 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestToString.java +++ b/test/jdk/jdk/jfr/api/consumer/TestToString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Sanity checks that RecordedEvent#toString returns something valid - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestToString diff --git a/test/jdk/jdk/jfr/api/consumer/TestValueDescriptorRecorded.java b/test/jdk/jdk/jfr/api/consumer/TestValueDescriptorRecorded.java index 4fc90c10cf1e5..aa6ac255ba0c0 100644 --- a/test/jdk/jdk/jfr/api/consumer/TestValueDescriptorRecorded.java +++ b/test/jdk/jdk/jfr/api/consumer/TestValueDescriptorRecorded.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Verifies that the recorded value descriptors are correct - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.TestValueDescriptorRecorded diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestMultipleChunk.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestMultipleChunk.java index d0fed7477ebc1..5efe203161405 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestMultipleChunk.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestMultipleChunk.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Verifies that it is possible to stream contents from a multichunked file - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.filestream.TestMultipleChunk diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java index 58f23350dd07e..a2c127afdce13 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Test EventStream::setOrdered(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.filestream.TestOrdered diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java index ff26fd7269d67..7d34f00c891bc 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestReuse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Test EventStream::setReuse(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.filestream.TestReuse diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestContent.java b/test/jdk/jdk/jfr/api/consumer/log/TestContent.java index c6ef6f960f54e..75a2b98ac96f6 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestContent.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestContent.java @@ -32,7 +32,7 @@ * @test * @summary Tests that the event payload is printed when using * -Xlog:jfr+event=trace - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestDiskOnOff.java b/test/jdk/jdk/jfr/api/consumer/log/TestDiskOnOff.java index 0f8f0cf3ba7b0..220820e3c9955 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestDiskOnOff.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestDiskOnOff.java @@ -27,7 +27,7 @@ /** * @test * @summary Tests that event logging can't be turned on and off - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestDynamicStart.java b/test/jdk/jdk/jfr/api/consumer/log/TestDynamicStart.java index b24e96c53bb56..e598d4302a1c7 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestDynamicStart.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestDynamicStart.java @@ -35,7 +35,7 @@ * @test * @summary Tests that log responds to log level changes after JVM has * started - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestMemoryDiskTransition.java b/test/jdk/jdk/jfr/api/consumer/log/TestMemoryDiskTransition.java index 133318e837df2..6ffb22a38ebe8 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestMemoryDiskTransition.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestMemoryDiskTransition.java @@ -27,7 +27,7 @@ /** * @test * @summary Tests that transition between disk=true/false works - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestMemoryOnly.java b/test/jdk/jdk/jfr/api/consumer/log/TestMemoryOnly.java index d9faa0805ffae..618dbaffad893 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestMemoryOnly.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestMemoryOnly.java @@ -27,7 +27,7 @@ /** * @test * @summary Tests that a stream is not started if disk=false - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestSystemEvents.java b/test/jdk/jdk/jfr/api/consumer/log/TestSystemEvents.java index 01b57ed32757b..8d90684e5235a 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestSystemEvents.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestSystemEvents.java @@ -30,7 +30,7 @@ /** * @test * @summary Tests that only system events are emitted - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestTruncation.java b/test/jdk/jdk/jfr/api/consumer/log/TestTruncation.java index 84075053793c2..d2f6bf5b051cc 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestTruncation.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestTruncation.java @@ -31,7 +31,7 @@ /** * @test * @summary Tests that large output is truncated - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestUserEvents.java b/test/jdk/jdk/jfr/api/consumer/log/TestUserEvents.java index a6d2074645bad..62feb2b9dbd44 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestUserEvents.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestUserEvents.java @@ -30,7 +30,7 @@ /** * @test * @summary Tests that only user events are emitted - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java b/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java index 0533a0177f343..841f990a8d396 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestVerbosity.java @@ -32,7 +32,7 @@ /** * @test * @summary Tests output from various tag sets and levels - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/log/TestWithStreaming.java b/test/jdk/jdk/jfr/api/consumer/log/TestWithStreaming.java index fc5cd7b4fe042..78b4e959182c4 100644 --- a/test/jdk/jdk/jfr/api/consumer/log/TestWithStreaming.java +++ b/test/jdk/jdk/jfr/api/consumer/log/TestWithStreaming.java @@ -35,7 +35,7 @@ /** * @test * @summary Checks that it is possible to stream together with log stream - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.log.LogAnalyzer diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestAwaitTermination.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestAwaitTermination.java index 6d99f9dbb69f5..4477dc4f90190 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestAwaitTermination.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestAwaitTermination.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test RecordingStream::awaitTermination(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestAwaitTermination diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestBasics.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestBasics.java index 1dbfeefa968c8..3adbbd1af43a6 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestBasics.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestBasics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Basic/sanity test for JFR event streaming - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestBasics diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestClose.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestClose.java index 8b3fbe88b90d0..c7e6c6e592284 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestClose.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Tests RecordingStream::close() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -Xlog:jfr+streaming+system=trace jdk.jfr.api.consumer.recordingstream.TestClose diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestConstructor.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestConstructor.java index 5cfc21d698c22..0597300d83f7f 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestConstructor.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Tests RecordingStream::RecordingStream() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestConstructor diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDisable.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDisable.java index e0eccf9198ecc..73345f346e30f 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDisable.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDisable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Tests RecordingStream::disable(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestDisable diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDump.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDump.java index 86c131aa246b9..cf4dad5477e24 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDump.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestDump.java @@ -41,7 +41,7 @@ /** * @test * @summary Tests RecordingStream::dump(Path) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestDump diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestEnable.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestEnable.java index 27ca64b790701..cde7d74ae0846 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestEnable.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestEnable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Tests RecordingStream::enable(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestEnable diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestMaxAge.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestMaxAge.java index 8803272e919de..64dbfa4173b28 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestMaxAge.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestMaxAge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Tests RecordingStream::setMaxAge(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestMaxAge diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnClose.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnClose.java index 9840511823269..3da0c62b8c8ad 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnClose.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnClose.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Tests RecordingStream::onClose(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestOnClose diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorAsync.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorAsync.java index 7939a634d4d54..4e7effae9a2a7 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorAsync.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @summary Tests RecordingStream::onError(...) when using * RecordingStream:startAsync - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestOnErrorAsync diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorSync.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorSync.java index 2936070c3bf2f..4bf0ed0f6f696 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorSync.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnErrorSync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Tests RecordingStream::onError(...) when using RecordingStream:start - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestOnErrorSync diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnEvent.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnEvent.java index 390df2a2f562c..fa65553939901 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnEvent.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Tests RecordingStream::onEvent(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -Xlog:jfr+system+streaming=debug jdk.jfr.api.consumer.recordingstream.TestOnEvent diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnFlush.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnFlush.java index d895110274983..5f623f7ae5c81 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnFlush.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnFlush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Tests RecordingStream::onFlush(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestOnFlush diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnMetadata.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnMetadata.java index 79ca66344549d..e8085736613e7 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnMetadata.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestOnMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ /** * @test * @summary Tests RecordingStream::onMetadata(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestOnMetadata diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecordingName.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecordingName.java index 813150e0d19db..18f2337547836 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecordingName.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecordingName.java @@ -31,7 +31,7 @@ * @test * @bug 8257424 * @summary Tests recording name for RecordingStrream -* @key jfr +* @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestRecordingName diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecursive.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecursive.java index fb62d62b6c965..49cc9fc644f34 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecursive.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRecursive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Tests that events are not emitted in handlers - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @build jdk.jfr.api.consumer.recordingstream.EventProducer diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRemove.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRemove.java index fc4ca6e272ee2..d8d0aeacfa085 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRemove.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestRemove.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Tests RecordingStrream::remove(...) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestRemove diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java index 478e7a7f77edb..1e7a630e08459 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary Tests EventStream::setEndTime - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.api.consumer.recordingstream.TestSetEndTime diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxAge.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxAge.java index b8c2674e5c19c..80e05a6995c89 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxAge.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxAge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Tests RecordingStrream::setMaxAge - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetMaxAge diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxSize.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxSize.java index 8b350084e485c..764082b2f9ed7 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxSize.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetMaxSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test * @summary Tests RecordingStrream::setMaxSize -* @key jfr +* @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetMaxSize diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetSettings.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetSettings.java index 9f55c26540bca..e9cc19734e3b0 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetSettings.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Tests RecordingStream::setSettings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr+system+parser jdk.jfr.api.consumer.recordingstream.TestSetSettings diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetStartTime.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetStartTime.java index 06b28aaa79c36..95807cb2deba8 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetStartTime.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetStartTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Tests EventStream::setStartTime - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetStartTime diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStart.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStart.java index 719411b2fa0ae..f14d2cdceec64 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStart.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Tests RecordingStream::start() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @build jdk.jfr.api.consumer.recordingstream.EventProducer diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStartAsync.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStartAsync.java index 362fd1301150d..087b55801cdd8 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStartAsync.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStartAsync.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Tests RecordingStream::startAsync() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestStartAsync diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java index 36bbaa3c557db..5f23943e6cb00 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Tests RecordingStream::stop() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @build jdk.jfr.api.consumer.recordingstream.EventProducer diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStoppedRecording.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStoppedRecording.java index c0593f4d97bbf..a8bcb7f33687e 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStoppedRecording.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStoppedRecording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ * @test * @summary Tests that a RecordingStream is closed if the underlying Recording * is stopped. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestStoppedRecording diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryAfterStart.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryAfterStart.java index 6c4e5b8061559..2e0aceb3825dc 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryAfterStart.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryAfterStart.java @@ -32,7 +32,7 @@ * @test * @summary Test that it is possible to start a stream against a directory, * specified on command, line before the application starts - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.streaming.Application diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryBeforeStart.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryBeforeStart.java index 10f87402778d7..180a00988436d 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryBeforeStart.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryBeforeStart.java @@ -32,7 +32,7 @@ * @test * @summary Test that it is possible to start a stream against a directory, * specified on command line, after the application starts - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.streaming.Application diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryLastModified.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryLastModified.java index 2ca1c474acc83..6a9e8376ed2ba 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryLastModified.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryLastModified.java @@ -31,7 +31,7 @@ /** * @test * @summary Test that a stream starts against the latest created repository - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.streaming.Application diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryMultipleProcesses.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryMultipleProcesses.java index 6bda427b38734..95f6c5d4e5955 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryMultipleProcesses.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestBaseRepositoryMultipleProcesses.java @@ -33,7 +33,7 @@ * @summary Test that it is possible to start a stream against a directory, * specified on command line, where multiple processes starts * simultaneously - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.jfr.api.consumer.streaming.Application diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestChunkGap.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestChunkGap.java index 052914f08db21..bf5507815d6d1 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestChunkGap.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestChunkGap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * @test * @summary Tests that a stream can gracefully handle chunk being removed in the * middle - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestChunkGap diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestCrossProcessStreaming.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestCrossProcessStreaming.java index 313b5f026e1e2..b4bc1fec8f834 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestCrossProcessStreaming.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestCrossProcessStreaming.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ * @test * @summary Test scenario where JFR event producer is in a different process * with respect to the JFR event stream consumer. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.attach diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestEmptyChunks.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestEmptyChunks.java index 15de9597d637a..76940a99775c8 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestEmptyChunks.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestEmptyChunks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test that it is possible to iterate over chunk without normal events - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestEmptyChunks diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestEnableEvents.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestEnableEvents.java index 6e68872c464eb..99df63105a248 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestEnableEvents.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestEnableEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * @test * @summary Verifies that it is possible to stream contents from specified event * settings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestEventRegistration.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestEventRegistration.java index 1934f4802afe9..d61fb197f75a7 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestEventRegistration.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestEventRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Test that it is possible to register new metadata in a chunk - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestEventRegistration diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestFilledChunks.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestFilledChunks.java index 18bfa57a4b18c..423e3969af8e3 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestFilledChunks.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestFilledChunks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test that it is possible to iterate over chunk with normal events - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestFilledChunks diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestFiltering.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestFiltering.java index a591faf34440a..d493a4475be79 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestFiltering.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestFiltering.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Verifies that it is possible to filter a stream for an event - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestFiltering diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java index 955226ec3fb24..5b9aeb50fa281 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestInProcessMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @test * @summary Verifies that is possible to stream from an in-process repository * that is being moved. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.consumer.streaming.TestInProcessMigration diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java index e1a95380477ea..3586421d41eab 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMCrash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test that a stream ends/closes when an application crashes. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java index 27dfb0224c1ac..9485919c8e354 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test * @summary Test that a stream ends/closes when an application exists. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java index 4515ae9832a01..43c0559d47322 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary Verifies that EventStream::openRepository() read from the latest flush - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestLatestEvent diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java index a21d5a3fda44a..0067467cf1bb0 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestOutOfProcessMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @summary Verifies that a out-of-process stream is closed when the repository * is changed. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestRecordingBefore.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestRecordingBefore.java index e79b6de6738e3..c5eca13cef46f 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestRecordingBefore.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestRecordingBefore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @test * @summary Verifies that it is possible to start a stream when there are * already chunk in the repository - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestRecordingBefore diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestRemovedChunks.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestRemovedChunks.java index 05a8d8c5e51a0..f279f3acdfd2a 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestRemovedChunks.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestRemovedChunks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Tests that a stream can gracefully handle chunk being removed - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr*=info jdk.jfr.api.consumer.streaming.TestRemovedChunks diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestRepositoryProperty.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestRepositoryProperty.java index e1fa206477f5a..e5151e8a496b3 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestRepositoryProperty.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestRepositoryProperty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @test * @summary Verifies that it is possible to access JFR repository from a system * property - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.attach diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestStartMultiChunk.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestStartMultiChunk.java index baae06b8ec713..fbc27b051b0b8 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestStartMultiChunk.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestStartMultiChunk.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @summary Verifies that it is possible to stream contents of ongoing * recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr+system+streaming=trace diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestStartSingleChunk.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestStartSingleChunk.java index b97c8a7645318..92eeb5282c46a 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestStartSingleChunk.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestStartSingleChunk.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @test * @summary Verifies that it is possible to stream contents of ongoing * recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr+system+streaming=trace diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestUnstarted.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestUnstarted.java index 998a8681519e5..1e947c092edc5 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestUnstarted.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestUnstarted.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ * @test * @summary Verifies that it is possible to open a stream when a repository doesn't * exists - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.consumer.streaming.TestUnstarted diff --git a/test/jdk/jdk/jfr/api/event/TestAbstractEvent.java b/test/jdk/jdk/jfr/api/event/TestAbstractEvent.java index 1d6ac835be9a4..d1b320b94bffb 100644 --- a/test/jdk/jdk/jfr/api/event/TestAbstractEvent.java +++ b/test/jdk/jdk/jfr/api/event/TestAbstractEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Tests that abstract events are not part of metadata - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestAbstractEvent diff --git a/test/jdk/jdk/jfr/api/event/TestBeginEnd.java b/test/jdk/jdk/jfr/api/event/TestBeginEnd.java index 698b4f94ca286..4dfafa321ef93 100644 --- a/test/jdk/jdk/jfr/api/event/TestBeginEnd.java +++ b/test/jdk/jdk/jfr/api/event/TestBeginEnd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Test for RecordedEvent.getDuration() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestBeginEnd diff --git a/test/jdk/jdk/jfr/api/event/TestClinitRegistration.java b/test/jdk/jdk/jfr/api/event/TestClinitRegistration.java index 99a851eba7f5e..099fb8e721606 100644 --- a/test/jdk/jdk/jfr/api/event/TestClinitRegistration.java +++ b/test/jdk/jdk/jfr/api/event/TestClinitRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test enable/disable event and verify recording has expected events. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestClinitRegistration diff --git a/test/jdk/jdk/jfr/api/event/TestClonedEvent.java b/test/jdk/jdk/jfr/api/event/TestClonedEvent.java index adad7269bbd1f..336dee9609932 100644 --- a/test/jdk/jdk/jfr/api/event/TestClonedEvent.java +++ b/test/jdk/jdk/jfr/api/event/TestClonedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Tests that a cloned event can be successfully committed. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestClonedEvent diff --git a/test/jdk/jdk/jfr/api/event/TestEnableDisable.java b/test/jdk/jdk/jfr/api/event/TestEnableDisable.java index a953feafabe06..6b7576d74b95c 100644 --- a/test/jdk/jdk/jfr/api/event/TestEnableDisable.java +++ b/test/jdk/jdk/jfr/api/event/TestEnableDisable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test enable/disable event and verify recording has expected events. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestEnableDisable diff --git a/test/jdk/jdk/jfr/api/event/TestEventDuration.java b/test/jdk/jdk/jfr/api/event/TestEventDuration.java index f043ee26c53f8..d8b30f4af8e40 100644 --- a/test/jdk/jdk/jfr/api/event/TestEventDuration.java +++ b/test/jdk/jdk/jfr/api/event/TestEventDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Tests that a duration is recorded. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestEventDuration diff --git a/test/jdk/jdk/jfr/api/event/TestEventFactory.java b/test/jdk/jdk/jfr/api/event/TestEventFactory.java index 43c89f490b437..4aaf2e749babf 100644 --- a/test/jdk/jdk/jfr/api/event/TestEventFactory.java +++ b/test/jdk/jdk/jfr/api/event/TestEventFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary EventFactory simple test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestEventFactory diff --git a/test/jdk/jdk/jfr/api/event/TestEventFactoryRegisterTwice.java b/test/jdk/jdk/jfr/api/event/TestEventFactoryRegisterTwice.java index ed32b3586c2f8..479de103353f7 100644 --- a/test/jdk/jdk/jfr/api/event/TestEventFactoryRegisterTwice.java +++ b/test/jdk/jdk/jfr/api/event/TestEventFactoryRegisterTwice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Verifies that EventFactory can register the same event twice - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestEventFactoryRegisterTwice diff --git a/test/jdk/jdk/jfr/api/event/TestEventFactoryRegistration.java b/test/jdk/jdk/jfr/api/event/TestEventFactoryRegistration.java index 313c8060972e3..15640f56b68db 100644 --- a/test/jdk/jdk/jfr/api/event/TestEventFactoryRegistration.java +++ b/test/jdk/jdk/jfr/api/event/TestEventFactoryRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary EventFactory register/unregister API test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestEventFactoryRegistration diff --git a/test/jdk/jdk/jfr/api/event/TestExtends.java b/test/jdk/jdk/jfr/api/event/TestExtends.java index eae47911ba091..0121f2ce0911a 100644 --- a/test/jdk/jdk/jfr/api/event/TestExtends.java +++ b/test/jdk/jdk/jfr/api/event/TestExtends.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Test with event class inheritance - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestExtends diff --git a/test/jdk/jdk/jfr/api/event/TestGetDuration.java b/test/jdk/jdk/jfr/api/event/TestGetDuration.java index b25969198edad..c4f6377f2194a 100644 --- a/test/jdk/jdk/jfr/api/event/TestGetDuration.java +++ b/test/jdk/jdk/jfr/api/event/TestGetDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test for RecordedEvent.getDuration() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestGetDuration diff --git a/test/jdk/jdk/jfr/api/event/TestIsEnabled.java b/test/jdk/jdk/jfr/api/event/TestIsEnabled.java index a94bea9ba62af..8474646608c5e 100644 --- a/test/jdk/jdk/jfr/api/event/TestIsEnabled.java +++ b/test/jdk/jdk/jfr/api/event/TestIsEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test Event.isEnabled() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestIsEnabled diff --git a/test/jdk/jdk/jfr/api/event/TestIsEnabledMultiple.java b/test/jdk/jdk/jfr/api/event/TestIsEnabledMultiple.java index 66256c69e4b6f..69db35cbf4973 100644 --- a/test/jdk/jdk/jfr/api/event/TestIsEnabledMultiple.java +++ b/test/jdk/jdk/jfr/api/event/TestIsEnabledMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test Event.isEnabled() with multiple recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestIsEnabledMultiple diff --git a/test/jdk/jdk/jfr/api/event/TestOwnCommit.java b/test/jdk/jdk/jfr/api/event/TestOwnCommit.java index 6ca058cfcc4b8..0186d86d82dca 100644 --- a/test/jdk/jdk/jfr/api/event/TestOwnCommit.java +++ b/test/jdk/jdk/jfr/api/event/TestOwnCommit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Use custom event that reuse method names begin, end and commit. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestOwnCommit diff --git a/test/jdk/jdk/jfr/api/event/TestShouldCommit.java b/test/jdk/jdk/jfr/api/event/TestShouldCommit.java index f28884b77a2d3..f26bb6c67fcf3 100644 --- a/test/jdk/jdk/jfr/api/event/TestShouldCommit.java +++ b/test/jdk/jdk/jfr/api/event/TestShouldCommit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Test jdk.jfr.Event::shouldCommit() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestShouldCommit diff --git a/test/jdk/jdk/jfr/api/event/TestStaticEnable.java b/test/jdk/jdk/jfr/api/event/TestStaticEnable.java index b1bc9bdab97f1..e7d116917b1b8 100644 --- a/test/jdk/jdk/jfr/api/event/TestStaticEnable.java +++ b/test/jdk/jdk/jfr/api/event/TestStaticEnable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Enable an event from a static function in the event. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.TestStaticEnable diff --git a/test/jdk/jdk/jfr/api/event/dynamic/TestDynamicAnnotations.java b/test/jdk/jdk/jfr/api/event/dynamic/TestDynamicAnnotations.java index 18fb3cc586533..c98be5bdbe3a2 100644 --- a/test/jdk/jdk/jfr/api/event/dynamic/TestDynamicAnnotations.java +++ b/test/jdk/jdk/jfr/api/event/dynamic/TestDynamicAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.dynamic.TestDynamicAnnotations diff --git a/test/jdk/jdk/jfr/api/event/dynamic/TestEventFactory.java b/test/jdk/jdk/jfr/api/event/dynamic/TestEventFactory.java index f61c81bb9ebdf..06e59fafe4c3e 100644 --- a/test/jdk/jdk/jfr/api/event/dynamic/TestEventFactory.java +++ b/test/jdk/jdk/jfr/api/event/dynamic/TestEventFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,6 @@ /** * @test - * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.event.dynamic.TestEventFactory diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestAddListenerTwice.java b/test/jdk/jdk/jfr/api/flightrecorder/TestAddListenerTwice.java index 8b273e9b905cd..3a6d566fb1d1a 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestAddListenerTwice.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestAddListenerTwice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.flightrecorder.TestAddListenerTwice diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestAddPeriodicEvent.java b/test/jdk/jdk/jfr/api/flightrecorder/TestAddPeriodicEvent.java index 78950a723da75..d838f31b8d9d9 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestAddPeriodicEvent.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestAddPeriodicEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestAddPeriodicEvent diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestFlightRecorderListenerRecorderInitialized.java b/test/jdk/jdk/jfr/api/flightrecorder/TestFlightRecorderListenerRecorderInitialized.java index 9f9315ea1c407..72e2e3cc92935 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestFlightRecorderListenerRecorderInitialized.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestFlightRecorderListenerRecorderInitialized.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestFlightRecorderListenerRecorderInitialized diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestGetEventTypes.java b/test/jdk/jdk/jfr/api/flightrecorder/TestGetEventTypes.java index 8a3abdb3046c2..248a4f385cfcf 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestGetEventTypes.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestGetEventTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm/timeout=600 jdk.jfr.api.flightrecorder.TestGetEventTypes diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestGetPlatformRecorder.java b/test/jdk/jdk/jfr/api/flightrecorder/TestGetPlatformRecorder.java index bdbf0c53fa26e..52597f81b0d8c 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestGetPlatformRecorder.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestGetPlatformRecorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestGetPlatformRecorder diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestGetRecordings.java b/test/jdk/jdk/jfr/api/flightrecorder/TestGetRecordings.java index d4318134c580e..e0c8f9f0432fd 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestGetRecordings.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestGetRecordings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestGetRecordings diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestGetSettings.java b/test/jdk/jdk/jfr/api/flightrecorder/TestGetSettings.java index 68472f04bc418..85aaa177cf4bf 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestGetSettings.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestGetSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestGetSettings diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestIsAvailable.java b/test/jdk/jdk/jfr/api/flightrecorder/TestIsAvailable.java index 6e2cf4cf94202..9665319e64300 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestIsAvailable.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestIsAvailable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -XX:+FlightRecorder jdk.jfr.api.flightrecorder.TestIsAvailable true diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestIsInitialized.java b/test/jdk/jdk/jfr/api/flightrecorder/TestIsInitialized.java index 8d8dda1eaac3a..ebb6be410458b 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestIsInitialized.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestIsInitialized.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestIsInitialized diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestListener.java b/test/jdk/jdk/jfr/api/flightrecorder/TestListener.java index f039a60a2457c..90ceadfaf826c 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestListener.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.flightrecorder.TestListener diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestListenerNull.java b/test/jdk/jdk/jfr/api/flightrecorder/TestListenerNull.java index dab7f551af4d4..cab7346fa60ef 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestListenerNull.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestListenerNull.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestListenerNull diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestPeriodicEventsSameHook.java b/test/jdk/jdk/jfr/api/flightrecorder/TestPeriodicEventsSameHook.java index f6e7f6a234037..5556020dc0f0d 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestPeriodicEventsSameHook.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestPeriodicEventsSameHook.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test * @summary Check that an IllegalArgumentException is thrown if event is added twice - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestPeriodicEventsSameHook diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestRecorderInitializationCallback.java b/test/jdk/jdk/jfr/api/flightrecorder/TestRecorderInitializationCallback.java index ccb2245551bcc..a97b7b865bfd7 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestRecorderInitializationCallback.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestRecorderInitializationCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Test Flight Recorder initialization callback is only called once - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestRecorderInitializationCallback diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestRegisterUnregisterEvent.java b/test/jdk/jdk/jfr/api/flightrecorder/TestRegisterUnregisterEvent.java index 2a0088ec52a37..1481750c74c20 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestRegisterUnregisterEvent.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestRegisterUnregisterEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestRegisterUnregisterEvent diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestSettingsControl.java b/test/jdk/jdk/jfr/api/flightrecorder/TestSettingsControl.java index 0b54f218c43c3..e186db41bc2de 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestSettingsControl.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestSettingsControl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestSettingsControl diff --git a/test/jdk/jdk/jfr/api/flightrecorder/TestSnapshot.java b/test/jdk/jdk/jfr/api/flightrecorder/TestSnapshot.java index fbb41b7f15798..6070c68236dbd 100644 --- a/test/jdk/jdk/jfr/api/flightrecorder/TestSnapshot.java +++ b/test/jdk/jdk/jfr/api/flightrecorder/TestSnapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.flightrecorder.TestSnapshot diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestCategory.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestCategory.java index 4bb0083a0f35d..dbd33d013ae02 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestCategory.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestCategory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestCategory diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestContentType.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestContentType.java index 0c72ae8057159..1c38c21c3ae7e 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestContentType.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestContentType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestContentType diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestDescription.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestDescription.java index 57d86e85fdec1..6232346b871f6 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestDescription.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestDescription diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestDynamicAnnotation.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestDynamicAnnotation.java index 5b2cae9278191..726ac9070d6ed 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestDynamicAnnotation.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestDynamicAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestDynamicAnnotation diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestEnabled.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestEnabled.java index b5e60cedb8a23..3aafd264ff5da 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestEnabled.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestEnabled.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestEnabled diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestExperimental.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestExperimental.java index 3420debafa02d..5f044d34e24ab 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestExperimental.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestExperimental.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestExperimental diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestFieldAnnotations.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestFieldAnnotations.java index 088639b674874..879ba0727f2a8 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestFieldAnnotations.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestFieldAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestFieldAnnotations diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestFormatMissingValue.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestFormatMissingValue.java index b7b61d09abac2..90ecb9fa7d8c1 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestFormatMissingValue.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestFormatMissingValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Check that event values are properly formatted and sanity check * that extreme values don't throws exceptions * @requires vm.hasJFR diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestHasValue.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestHasValue.java index c5194f1381c59..a2367cc3fe258 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestHasValue.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestHasValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestHasValue diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestInheritedAnnotations.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestInheritedAnnotations.java index 16c7f20a9b57c..7434f51ca02cd 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestInheritedAnnotations.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestInheritedAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestInheritedAnnotations diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestLabel.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestLabel.java index ca1b74e10f2e1..0f8f853107286 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestLabel.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestLabel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestLabel diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestMetadata.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestMetadata.java index 1287aa5e20d49..8939272b0f7b4 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestMetadata.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestMetadata diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestName.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestName.java index 411f5da67e140..269ddbecc20ee 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestName.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestName diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java index 893b1ab4720d9..bf679b05bbf24 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestLabel diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestRegistered.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestRegistered.java index 1c1177ac040cc..f9e89c2c12d05 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestRegistered.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestRegistered.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestRegistered diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestRegisteredFalseAndRunning.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestRegisteredFalseAndRunning.java index 95bfbf527e1d8..2f2246ac3364d 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestRegisteredFalseAndRunning.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestRegisteredFalseAndRunning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test Tests that commit doesn't throw exception when an event has not been registered. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestRegisteredFalseAndRunning diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestRelational.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestRelational.java index 7b2d6e896896e..d52364091752b 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestRelational.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestRelational.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestRelational diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestSimpleMetadataEvent.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestSimpleMetadataEvent.java index 720da6da9ba00..cbb9cc54af664 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestSimpleMetadataEvent.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestSimpleMetadataEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestSimpleMetadataEvent diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestStackFilter.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestStackFilter.java index 2acd369b6cd8f..b7c3a67ae681c 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestStackFilter.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestStackFilter.java @@ -47,7 +47,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.events * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestStackTrace.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestStackTrace.java index 8223d313a08c2..11e651d40cd04 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestStackTrace.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestStackTrace diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestThreshold.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestThreshold.java index 2ff1c3410a017..8cbb276c14598 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestThreshold.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestThreshold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestThreshold diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestTypesIdentical.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestTypesIdentical.java index 9faae6ba564cd..7983828152538 100644 --- a/test/jdk/jdk/jfr/api/metadata/annotations/TestTypesIdentical.java +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestTypesIdentical.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.annotations.TestTypesIdentical diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotation.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotation.java index 2af6870af5b53..b4a8e87735f74 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotation.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetAnnotation diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotationElements.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotationElements.java index 34b84779d3e6c..0ce8767f8c1d7 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotationElements.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotationElements.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ /** * @test * @summary Test for AnnotationElement.getAnnotationElements() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetAnnotationElements diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotations.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotations.java index 895f9f4050fec..b86ef6dafaca3 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotations.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetAnnotations diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetCategory.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetCategory.java index ec92be1eb4e50..d4b70ff18b0bd 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetCategory.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetCategory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Test setName(). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetCategory diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDefaultValues.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDefaultValues.java index be7264966c3e9..a5664af148407 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDefaultValues.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDefaultValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test getDefaultValues() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetDefaultValues diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDescription.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDescription.java index 19eb83fcf6ec0..91732ed9a9b02 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDescription.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test descriptive annotations for EventType - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetDescription diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetEventType.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetEventType.java index 4dbd2e7cc6f0c..9e7571577a9ef 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetEventType.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetEventType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test * @summary Test getEventType() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetEventType diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetField.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetField.java index 28a39d649f7d9..aec07fdd136a8 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetField.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test getField() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetField diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetFields.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetFields.java index 237239b603532..1c8d98132f561 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetFields.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test getFields() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetFields diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetSettings.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetSettings.java index f47d451edfb9b..ab5cccf8bd8bc 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetSettings.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestGetSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test getSettings() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.eventtype.TestGetSettings diff --git a/test/jdk/jdk/jfr/api/metadata/eventtype/TestUnloadingEventClass.java b/test/jdk/jdk/jfr/api/metadata/eventtype/TestUnloadingEventClass.java index d86a9d10452a5..07daab8fa4559 100644 --- a/test/jdk/jdk/jfr/api/metadata/eventtype/TestUnloadingEventClass.java +++ b/test/jdk/jdk/jfr/api/metadata/eventtype/TestUnloadingEventClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test that verifies event metadata is removed when an event class is unloaded. * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestDefaultValue.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestDefaultValue.java index 8ded0a5830d34..c88b21013484b 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestDefaultValue.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestDefaultValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test * @summary Test SettingDescriptor.getName() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestDefaultValue diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotation.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotation.java index 70d58074fcb21..8c45e82c3cb42 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotation.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test SettingDescriptor.getAnnotation(); - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetAnnotation diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotationElement.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotationElement.java index 74ffad14b727f..91a490e24c94c 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotationElement.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetAnnotationElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test SettingDescriptor.getAnnotationElements() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetAnnotationElement diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetContentType.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetContentType.java index 2af0bb3af11b8..ba8e25dd44939 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetContentType.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetContentType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Test SettingDescriptor.getContentType() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetDescription diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetDescription.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetDescription.java index 2e23b17962ad4..1b91361771425 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetDescription.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test SettingDescriptor.getDescription() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetDescription diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetLabel.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetLabel.java index 961261bae196f..19b9f72c1d5c0 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetLabel.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetLabel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test SettingDescriptor.getLabel() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetLabel diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetName.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetName.java index 38b1fcb8085a2..f9ddc217bb73a 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetName.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test * @summary Test SettingDescriptor.getName() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetName diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeId.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeId.java index b1d123855bf1d..16d35f8d5c73f 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeId.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test * @summary Test SettingDescriptor.getTypeId() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetTypeId diff --git a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeName.java b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeName.java index 20d1ea957ecc3..98c7a3c0d0b5b 100644 --- a/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeName.java +++ b/test/jdk/jdk/jfr/api/metadata/settingdescriptor/TestGetTypeName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test * @summary Test SettingDescriptor.getTypeName(); - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.metadata.settingdescriptor.TestGetTypeName diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestClasses.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestClasses.java index 477beeab3b5d9..851ed0da7afaf 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestClasses.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test ValueDescriptor.getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestClasses diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestConstructor.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestConstructor.java index 056f216d677f5..c8d33bc000430 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestConstructor.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test ValueDescriptor.getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestConstructor diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetAnnotations.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetAnnotations.java index bc2a227a8f5ee..eefbb876c8b18 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetAnnotations.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test ValueDescriptor.getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestGetAnnotations diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetFields.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetFields.java index 0576615ba225a..a965e046643e3 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetFields.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestGetFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test * @summary Test ValueDescriptor.getAnnotations() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestGetFields diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestIsArray.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestIsArray.java index 983d7e29d5ca2..d3a002ea0161d 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestIsArray.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestIsArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test ValueDescriptor.isArray(). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestIsArray diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestSimpleTypes.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestSimpleTypes.java index cf506197a1836..c75737426a39c 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestSimpleTypes.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestSimpleTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Test all basic types in ValueDescriptor. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestSimpleTypes diff --git a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestValueDescriptorContentType.java b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestValueDescriptorContentType.java index 73acc71db68f9..cc5f8e8256447 100644 --- a/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestValueDescriptorContentType.java +++ b/test/jdk/jdk/jfr/api/metadata/valuedescriptor/TestValueDescriptorContentType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test ValueDescriptor.getContentType() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.metadata.valuedescriptor.TestValueDescriptorContentType diff --git a/test/jdk/jdk/jfr/api/recorder/TestRecorderInitialized.java b/test/jdk/jdk/jfr/api/recorder/TestRecorderInitialized.java index c4f48b9ce7987..bc791e6cb3305 100644 --- a/test/jdk/jdk/jfr/api/recorder/TestRecorderInitialized.java +++ b/test/jdk/jdk/jfr/api/recorder/TestRecorderInitialized.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test TestRecorderListener - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/api/recorder/TestRecorderListener.java b/test/jdk/jdk/jfr/api/recorder/TestRecorderListener.java index c6a1e853771ac..87790b57392bc 100644 --- a/test/jdk/jdk/jfr/api/recorder/TestRecorderListener.java +++ b/test/jdk/jdk/jfr/api/recorder/TestRecorderListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test TestRecorderListener * - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @run main/othervm jdk.jfr.api.recorder.TestRecorderListener */ diff --git a/test/jdk/jdk/jfr/api/recorder/TestRecorderListenerWithDump.java b/test/jdk/jdk/jfr/api/recorder/TestRecorderListenerWithDump.java index 0053c71019551..74d1f632ac541 100644 --- a/test/jdk/jdk/jfr/api/recorder/TestRecorderListenerWithDump.java +++ b/test/jdk/jdk/jfr/api/recorder/TestRecorderListenerWithDump.java @@ -9,7 +9,7 @@ /** * @test TestRecorderListenerWithDump * - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @run main/othervm jdk.jfr.api.recorder.TestRecorderListenerWithDump */ diff --git a/test/jdk/jdk/jfr/api/recorder/TestStartStopRecording.java b/test/jdk/jdk/jfr/api/recorder/TestStartStopRecording.java index 4f78f6888e29c..425b2b49df461 100644 --- a/test/jdk/jdk/jfr/api/recorder/TestStartStopRecording.java +++ b/test/jdk/jdk/jfr/api/recorder/TestStartStopRecording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ /** * @test TestStartStopRecording * - * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recorder.TestStartStopRecording diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestFileExist.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestFileExist.java index 42f5e277cedf3..22df06e164aad 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestFileExist.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestFileExist.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Set destination to an existing file. File should be overwritten. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestFileExist diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestFileReadOnly.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestFileReadOnly.java index d7fc0bdd0aac8..94289f9397803 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestFileReadOnly.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestFileReadOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Set destination to a read-only file. Expects exception. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestFileReadOnly diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestInvalid.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestInvalid.java index 93e2709c222f8..e3c099707f4c2 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestInvalid.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Test setDestination to invalid paths - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestInvalid diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestLongPath.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestLongPath.java index 9ab67cfc02e86..045362bea1443 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestLongPath.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestLongPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Set destination to a long path - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestLongPath diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestMultiple.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestMultiple.java index bf7d3f3b0fbf5..4e3eef91c8563 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestMultiple.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test setDestination with concurrent recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr=trace jdk.jfr.api.recording.destination.TestDestMultiple diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestReadOnly.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestReadOnly.java index 8c4a132cb7102..b6b2ddd8ce305 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestReadOnly.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestReadOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary Test setDestination to read-only dir - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestReadOnly diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestState.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestState.java index 99ded47f5ea9e..233d898be10b2 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestState.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Call setDestination() when recording in different states - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestState diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskFalse.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskFalse.java index 4930916a1d95b..1f264af21f80d 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskFalse.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskFalse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Basic test for setDestination with disk=false - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestToDiskFalse diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskTrue.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskTrue.java index 3684c6e65e8bb..b685c2c17bd2b 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskTrue.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestToDiskTrue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Basic test for setDestination with disk=true - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestToDiskTrue diff --git a/test/jdk/jdk/jfr/api/recording/destination/TestDestWithDuration.java b/test/jdk/jdk/jfr/api/recording/destination/TestDestWithDuration.java index ba305a18c2a56..eb9226fa2d8eb 100644 --- a/test/jdk/jdk/jfr/api/recording/destination/TestDestWithDuration.java +++ b/test/jdk/jdk/jfr/api/recording/destination/TestDestWithDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Test that recording is auto closed after duration - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.destination.TestDestWithDuration diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDump.java b/test/jdk/jdk/jfr/api/recording/dump/TestDump.java index 36706ecde3a31..47d26c16cf1c4 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDump.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ /** * @test * @summary Test copyTo and parse file - * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDump diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpDevNull.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpDevNull.java index d74dd7fede294..b83f96868686a 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpDevNull.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpDevNull.java @@ -29,7 +29,7 @@ /** * @test * @summary Tests that it's possible to dump to /dev/null without a livelock - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & (os.family != "windows") * @library /test/lib * @run main/othervm -Xlog:jfr jdk.jfr.api.recording.dump.TestDumpDevNull diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpInvalid.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpInvalid.java index 7b69f552afe7d..41250336d8998 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpInvalid.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test copyTo and parse file - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDumpInvalid diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpLongPath.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpLongPath.java index a1d2f714f4eee..d3b08cc8e048d 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpLongPath.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpLongPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test copyTo and parse file - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDumpLongPath diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpMultiple.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpMultiple.java index 3eab84cb44af3..2b14700e179b1 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpMultiple.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test copyTo and parse file - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDumpMultiple diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpReadOnly.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpReadOnly.java index 8ffbfa75952f8..9e05d8a2037ed 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpReadOnly.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpReadOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test copyTo and parse file - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDumpReadOnly diff --git a/test/jdk/jdk/jfr/api/recording/dump/TestDumpState.java b/test/jdk/jdk/jfr/api/recording/dump/TestDumpState.java index 7b464ff85b18b..b315117f726da 100644 --- a/test/jdk/jdk/jfr/api/recording/dump/TestDumpState.java +++ b/test/jdk/jdk/jfr/api/recording/dump/TestDumpState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test * @summary call copyTo() with recording in all states. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.dump.TestDumpState diff --git a/test/jdk/jdk/jfr/api/recording/event/TestChunkPeriod.java b/test/jdk/jdk/jfr/api/recording/event/TestChunkPeriod.java index 71ffa1f3a9f3b..9ce6af5861577 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestChunkPeriod.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestChunkPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test periodic setting that involves chunks. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestChunkPeriod diff --git a/test/jdk/jdk/jfr/api/recording/event/TestEnableClass.java b/test/jdk/jdk/jfr/api/recording/event/TestEnableClass.java index ea14efd1ce93f..cce06973d1c05 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestEnableClass.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestEnableClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test * @summary Simple enable Event class. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestEnableClass diff --git a/test/jdk/jdk/jfr/api/recording/event/TestEnableName.java b/test/jdk/jdk/jfr/api/recording/event/TestEnableName.java index c513fa64466ac..a1647918abb6e 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestEnableName.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestEnableName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Simple enable Event class. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestEnableName diff --git a/test/jdk/jdk/jfr/api/recording/event/TestEventTime.java b/test/jdk/jdk/jfr/api/recording/event/TestEventTime.java index 7ee9748520a79..54c735fff6963 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestEventTime.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestEventTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Test getStartTime() and getEndTime(). Verify startTime <= endTime - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestEventTime diff --git a/test/jdk/jdk/jfr/api/recording/event/TestLoadEventAfterStart.java b/test/jdk/jdk/jfr/api/recording/event/TestLoadEventAfterStart.java index 4bd96871b454e..0586389d86a15 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestLoadEventAfterStart.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestLoadEventAfterStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Load event class after recording started. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.lib.jfr.SimpleEvent diff --git a/test/jdk/jdk/jfr/api/recording/event/TestPeriod.java b/test/jdk/jdk/jfr/api/recording/event/TestPeriod.java index a3a76953fff08..e667fe010ef56 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestPeriod.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test periodic events. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestPeriod diff --git a/test/jdk/jdk/jfr/api/recording/event/TestReEnableClass.java b/test/jdk/jdk/jfr/api/recording/event/TestReEnableClass.java index 57d274abaa774..82631f5dcfefd 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestReEnableClass.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestReEnableClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Enable, disable, enable event during recording. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestReEnableClass diff --git a/test/jdk/jdk/jfr/api/recording/event/TestReEnableMultiple.java b/test/jdk/jdk/jfr/api/recording/event/TestReEnableMultiple.java index 4bbd0714c08f8..392450ee92ef0 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestReEnableMultiple.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestReEnableMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Enable, disable, enable event during recording. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestReEnableMultiple diff --git a/test/jdk/jdk/jfr/api/recording/event/TestReEnableName.java b/test/jdk/jdk/jfr/api/recording/event/TestReEnableName.java index 45f254956d6ab..3b6092f384cb0 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestReEnableName.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestReEnableName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Enable/disable event by name during recording. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestReEnableName diff --git a/test/jdk/jdk/jfr/api/recording/event/TestRecordingEnableDisable.java b/test/jdk/jdk/jfr/api/recording/event/TestRecordingEnableDisable.java index dd9d5089ae4d9..e0751c98aa9e1 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestRecordingEnableDisable.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestRecordingEnableDisable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Enable, disable, enable event during recording. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestRecordingEnableDisable diff --git a/test/jdk/jdk/jfr/api/recording/event/TestShortPeriod.java b/test/jdk/jdk/jfr/api/recording/event/TestShortPeriod.java index e53fd90a75cac..a7c6d995bfb39 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestShortPeriod.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestShortPeriod.java @@ -33,7 +33,7 @@ /** * @test Tests that periodic events are not disabled when using a very short * period - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.recording.event.TestShortPeriod diff --git a/test/jdk/jdk/jfr/api/recording/event/TestThreshold.java b/test/jdk/jdk/jfr/api/recording/event/TestThreshold.java index a0b42f66b892b..fdde42cdf5ad2 100644 --- a/test/jdk/jdk/jfr/api/recording/event/TestThreshold.java +++ b/test/jdk/jdk/jfr/api/recording/event/TestThreshold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Test event threshold. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.event.TestThreshold diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestGetId.java b/test/jdk/jdk/jfr/api/recording/misc/TestGetId.java index de4d17a741c45..979a59c7ca011 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestGetId.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestGetId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Verify that each recording get unique a id - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestGetId diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestGetSize.java b/test/jdk/jdk/jfr/api/recording/misc/TestGetSize.java index dc2176f59019d..ba540e6ae40c2 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestGetSize.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestGetSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test recording file size with Recording.getSize() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestGetSize diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestGetSizeToMem.java b/test/jdk/jdk/jfr/api/recording/misc/TestGetSizeToMem.java index 2b7ad3d4e6b2d..4529c9059c55f 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestGetSizeToMem.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestGetSizeToMem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Test recording file size with Recording.getSize() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestGetSizeToMem diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestGetStream.java b/test/jdk/jdk/jfr/api/recording/misc/TestGetStream.java index 3b353d0968be8..3db2549019974 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestGetStream.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestGetStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary A simple test for Recording.getStream() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestGetStream diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestRecordingBase.java b/test/jdk/jdk/jfr/api/recording/misc/TestRecordingBase.java index a17a7eb9959a0..4122a203db1f5 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestRecordingBase.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestRecordingBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary Basic tests for Recording - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestRecordingBase diff --git a/test/jdk/jdk/jfr/api/recording/misc/TestRecordingCopy.java b/test/jdk/jdk/jfr/api/recording/misc/TestRecordingCopy.java index 8d539ed68c4e1..1234655f31ac7 100644 --- a/test/jdk/jdk/jfr/api/recording/misc/TestRecordingCopy.java +++ b/test/jdk/jdk/jfr/api/recording/misc/TestRecordingCopy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary A simple test for Recording.copy() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.misc.TestRecordingCopy diff --git a/test/jdk/jdk/jfr/api/recording/options/TestDuration.java b/test/jdk/jdk/jfr/api/recording/options/TestDuration.java index 8f231ab77a038..d0bb1938f6b61 100644 --- a/test/jdk/jdk/jfr/api/recording/options/TestDuration.java +++ b/test/jdk/jdk/jfr/api/recording/options/TestDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test setDuration(). Verify recording is stopped automatically. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.options.TestDuration diff --git a/test/jdk/jdk/jfr/api/recording/options/TestName.java b/test/jdk/jdk/jfr/api/recording/options/TestName.java index c0042b4458ab1..a1b1747c70029 100644 --- a/test/jdk/jdk/jfr/api/recording/options/TestName.java +++ b/test/jdk/jdk/jfr/api/recording/options/TestName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test setName(). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.options.TestName diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestConfigurationGetContents.java b/test/jdk/jdk/jfr/api/recording/settings/TestConfigurationGetContents.java index 9365c7cf13ee7..ceea62bed2a71 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestConfigurationGetContents.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestConfigurationGetContents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Verifies Configuration.getContents() for every configuration - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.settings.TestConfigurationGetContents diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromPath.java b/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromPath.java index b64d0055dcb24..bd46c75c18be8 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromPath.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test setName(). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.settings.TestCreateConfigFromPath diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromReader.java b/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromReader.java index e96fab76899fc..219a100385291 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromReader.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestCreateConfigFromReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test setName(). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.settings.TestCreateConfigFromReader diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestGetConfigurations.java b/test/jdk/jdk/jfr/api/recording/settings/TestGetConfigurations.java index 465a07ab021bd..73b9557591a29 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestGetConfigurations.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestGetConfigurations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * @test * @summary Verifies that there is the default config and that it has * the expected parameters - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.settings.TestGetConfigurations diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java index e5d90e4b80bca..dc22644b4d034 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Verifies that event types has the correct type of settings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.settings.TestSettingsAvailability diff --git a/test/jdk/jdk/jfr/api/recording/state/TestOptionState.java b/test/jdk/jdk/jfr/api/recording/state/TestOptionState.java index 4e9dd4f2f7217..4b43f0fd5cbc2 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestOptionState.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestOptionState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test options in different states * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/recording/state/TestState.java b/test/jdk/jdk/jfr/api/recording/state/TestState.java index 5c548977ad79e..724b885d280d8 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestState.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test Recording state - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestState diff --git a/test/jdk/jdk/jfr/api/recording/state/TestStateDuration.java b/test/jdk/jdk/jfr/api/recording/state/TestStateDuration.java index 5e8ef60b36720..ac54d69e4abe8 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestStateDuration.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestStateDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Test Recording state - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestStateDuration diff --git a/test/jdk/jdk/jfr/api/recording/state/TestStateIdenticalListeners.java b/test/jdk/jdk/jfr/api/recording/state/TestStateIdenticalListeners.java index 216ac64c79c34..295f5b3c0c91b 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestStateIdenticalListeners.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestStateIdenticalListeners.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test Recording state with concurrent recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestStateIdenticalListeners diff --git a/test/jdk/jdk/jfr/api/recording/state/TestStateInvalid.java b/test/jdk/jdk/jfr/api/recording/state/TestStateInvalid.java index ba190c68d8538..5108fb0329104 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestStateInvalid.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestStateInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test start/stop/close recording from different recording states. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestStateInvalid diff --git a/test/jdk/jdk/jfr/api/recording/state/TestStateMultiple.java b/test/jdk/jdk/jfr/api/recording/state/TestStateMultiple.java index 21ccd7360742c..9745cab7351ec 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestStateMultiple.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestStateMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Test Recording state with concurrent recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestStateMultiple diff --git a/test/jdk/jdk/jfr/api/recording/state/TestStateScheduleStart.java b/test/jdk/jdk/jfr/api/recording/state/TestStateScheduleStart.java index 3708ded56f167..ba95407dad223 100644 --- a/test/jdk/jdk/jfr/api/recording/state/TestStateScheduleStart.java +++ b/test/jdk/jdk/jfr/api/recording/state/TestStateScheduleStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Test Recording state - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.api.recording.state.TestStateScheduleStart diff --git a/test/jdk/jdk/jfr/api/recording/time/TestTime.java b/test/jdk/jdk/jfr/api/recording/time/TestTime.java index 66e729f7568fa..3ece99b9e466d 100644 --- a/test/jdk/jdk/jfr/api/recording/time/TestTime.java +++ b/test/jdk/jdk/jfr/api/recording/time/TestTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test Recording.get*Time() * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/recording/time/TestTimeDuration.java b/test/jdk/jdk/jfr/api/recording/time/TestTimeDuration.java index 7f71c0c900471..12b5368db8842 100644 --- a/test/jdk/jdk/jfr/api/recording/time/TestTimeDuration.java +++ b/test/jdk/jdk/jfr/api/recording/time/TestTimeDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test Recording.setDuration() and Recording.get*Time() * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/recording/time/TestTimeMultiple.java b/test/jdk/jdk/jfr/api/recording/time/TestTimeMultiple.java index 057d9150b6a74..aab608267b571 100644 --- a/test/jdk/jdk/jfr/api/recording/time/TestTimeMultiple.java +++ b/test/jdk/jdk/jfr/api/recording/time/TestTimeMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test recording times with concurrent recordings * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/recording/time/TestTimeScheduleStart.java b/test/jdk/jdk/jfr/api/recording/time/TestTimeScheduleStart.java index 3698a683c50be..83d8399e41eda 100644 --- a/test/jdk/jdk/jfr/api/recording/time/TestTimeScheduleStart.java +++ b/test/jdk/jdk/jfr/api/recording/time/TestTimeScheduleStart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test Recording.scheduleStart() and Recording.get*Time() * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java b/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java index 67619fb10b4e9..ed20c44c688b8 100644 --- a/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java +++ b/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary The test uses SettingControl - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.settings.TestFilterEvents diff --git a/test/jdk/jdk/jfr/api/settings/TestSettingControl.java b/test/jdk/jdk/jfr/api/settings/TestSettingControl.java index 5543953482d63..ef38626eedb75 100644 --- a/test/jdk/jdk/jfr/api/settings/TestSettingControl.java +++ b/test/jdk/jdk/jfr/api/settings/TestSettingControl.java @@ -44,7 +44,7 @@ /** * @test * @summary Tests that methods on all SettingControls have expected behavior. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.api.settings.TestSettingControl diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java index 1fe3425372280..9112cfbc247e5 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test that event is triggered when an object is allocated in a new TLAB. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java index d2f2a3a1bc4da..a7695b7684947 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Test that when an object is allocated outside a TLAB an event will be triggered. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEvent.java index 2f7d3cc150303..e7effa0238289 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEvent.java @@ -33,7 +33,6 @@ /** * @test * @summary Tests ObjectAllocationSampleEvent - * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm -XX:+UseTLAB -XX:TLABSize=2k -XX:-ResizeTLAB jdk.jfr.event.allocation.TestObjectAllocationSampleEvent diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java index a38aae51c01ae..47f5b31f8816d 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary Test that when an object is allocated outside a TLAB an event will be triggered. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheConfig.java b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheConfig.java index cfc2115d68b6a..defc9cba1be0b 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheConfig.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test TestCodeCacheConfig - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheStats.java b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheStats.java index 2930b79883e01..2256e6a21fa8b 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCodeCacheStats.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCodeCacheStats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.compiler.TestCodeCacheStats diff --git a/test/jdk/jdk/jfr/event/compiler/TestCodeSweeper.java b/test/jdk/jdk/jfr/event/compiler/TestCodeSweeper.java index 62fb137b1cf03..dd227489a0c6e 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCodeSweeper.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCodeSweeper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ */ /** * @test TestCodeSweeper - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java index e13bcaa80b5cc..d39e006f5caa6 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerCompile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.compMode == "Xmixed" * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerConfig.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerConfig.java index 0e4834ccfa118..cc5455f98d9de 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerConfig.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.compiler.TestCompilerConfig diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerInlining.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerInlining.java index 2d0ce579dd810..9694c054f6a0c 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerInlining.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerInlining.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ /* * @test CompilerInliningTest * @bug 8073607 - * @key jfr + * @requires vm.flagless * @summary Verifies that corresponding JFR events are emitted in case of inlining. * @requires vm.hasJFR * @requires vm.compMode == "Xmixed" diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java index 02e235a23cadd..33884d448bff3 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.compMode!="Xint" & vm.flavor == "server" & (vm.opt.TieredStopAtLevel == 4 | vm.opt.TieredStopAtLevel == null) * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerQueueUtilization.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerQueueUtilization.java index 081cb5296d596..d4e4e12eaa3c7 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerQueueUtilization.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerQueueUtilization.java @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.compMode!="Xint" * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java index 389a7da25b4c5..053aedf94c8bf 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.compiler.TestCompilerStats diff --git a/test/jdk/jdk/jfr/event/compiler/TestDeoptimization.java b/test/jdk/jdk/jfr/event/compiler/TestDeoptimization.java index bd6d57b31762d..eb19965a64413 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestDeoptimization.java +++ b/test/jdk/jdk/jfr/event/compiler/TestDeoptimization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ public static void dummyMethod(boolean b) { /** * @test - * @key jfr + * @requires vm.flagless * @summary sanity test for Deoptimization event, depends on Compilation event * @requires vm.hasJFR * @requires vm.compMode == "Xmixed" diff --git a/test/jdk/jdk/jfr/event/diagnostics/TestHeapDump.java b/test/jdk/jdk/jfr/event/diagnostics/TestHeapDump.java index 20577d8257dee..14b0489505811 100644 --- a/test/jdk/jdk/jfr/event/diagnostics/TestHeapDump.java +++ b/test/jdk/jdk/jfr/event/diagnostics/TestHeapDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules java.management diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java index 86da3907e9d87..568104a7b50a2 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk /test/hotspot/jtreg diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java index e0ea218a07f0b..3cd8f6612bf44 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "G1" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java index 308a544adeb17..40c5129eb2303 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "G1" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java index 16217c0cbe1b7..0e27caf610d7d 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Parallel" | vm.gc == null @@ -39,8 +39,7 @@ public static void main(String[] args) throws Exception { String testID = "ParallelOld"; String[] vmFlags = {"-XX:+UseParallelGC"}; String[] gcNames = {GCHelper.gcParallelScavenge, GCHelper.gcParallelOld}; - String[] gcCauses = {"Allocation Failure", "System.gc()", "GCLocker Initiated GC", - "CodeCache GC Threshold"}; + String[] gcCauses = {"Allocation Failure", "System.gc()", "CodeCache GC Threshold"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java index 344c61043a2e1..7701fd36853b3 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Serial" | vm.gc == null @@ -39,8 +39,7 @@ public static void main(String[] args) throws Exception { String testID = "Serial"; String[] vmFlags = {"-XX:+UseSerialGC"}; String[] gcNames = {GCHelper.gcDefNew, GCHelper.gcSerialOld}; - String[] gcCauses = {"Allocation Failure", "System.gc()", "GCLocker Initiated GC", - "CodeCache GC Threshold"}; + String[] gcCauses = {"Allocation Failure", "System.gc()", "CodeCache GC Threshold"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1ConcurrentMark.java index 2282783ae1498..fcd33cbb1b50d 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1ConcurrentMark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires (vm.gc == "G1" | vm.gc == null) diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1FullCollection.java index 5c3da24fa1b9b..a698497cf956d 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithG1FullCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires (vm.gc == "G1" | vm.gc == null) diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithParallelOld.java index 9f95ca364f84f..c06b046f47325 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithParallelOld.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithParallelOld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Parallel" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithSerial.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithSerial.java index 6499f18c16425..6fc675a93e78e 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithSerial.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCEventMixedWithSerial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Serial" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCGarbageCollectionEvent.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCGarbageCollectionEvent.java index e228f7fd067ed..ff23291fa41fd 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCGarbageCollectionEvent.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCGarbageCollectionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:gc*=debug -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.event.gc.collection.TestGCGarbageCollectionEvent diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCWithFasttime.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCWithFasttime.java index edce5e76190c5..d6b271e4669c8 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCWithFasttime.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCWithFasttime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMajor.java b/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMajor.java index 5305cfd8d67b9..e2dd258818ba7 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMajor.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMajor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx50m -XX:+UseZGC -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -Xlog:gc* jdk.jfr.event.gc.collection.TestGarbageCollectionEventWithZMajor */ diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMinor.java b/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMinor.java index 65c177d3a6812..8e0d48682fccd 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMinor.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGarbageCollectionEventWithZMinor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,9 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java b/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java index c5614ad1cbe0c..c22670e4528fe 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestSystemGC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:+ExplicitGCInvokesConcurrent jdk.jfr.event.gc.collection.TestSystemGC true diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithDefNew.java b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithDefNew.java index 95c1a9c40ee9f..c6798c770a65e 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithDefNew.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithDefNew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithG1New.java b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithG1New.java index 931721011aa4a..5f026fc50e8e2 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithG1New.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithG1New.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithParallelScavenge.java b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithParallelScavenge.java index b731f1936bb92..f9adb6a45a6f5 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithParallelScavenge.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithParallelScavenge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestZOldGarbageCollectionEvent.java b/test/jdk/jdk/jfr/event/gc/collection/TestZOldGarbageCollectionEvent.java index 38e5ca49e608b..77abb19922bfe 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestZOldGarbageCollectionEvent.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestZOldGarbageCollectionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx50m -XX:+UseZGC -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -Xlog:gc* jdk.jfr.event.gc.collection.TestZOldGarbageCollectionEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestZYoungGarbageCollectionEvent.java b/test/jdk/jdk/jfr/event/gc/collection/TestZYoungGarbageCollectionEvent.java index 40c0a2adec32c..10c1407b96aaa 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestZYoungGarbageCollectionEvent.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestZYoungGarbageCollectionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx50m -XX:+UseZGC -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -Xlog:gc* jdk.jfr.event.gc.collection.TestZYoungGarbageCollectionEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEvent.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEvent.java index e459b0f2e7bae..7b7cc8a43766a 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "Parallel" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != true diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEventWithDefaultPauseTarget.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEventWithDefaultPauseTarget.java index c3a2803033810..6e411cf910553 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEventWithDefaultPauseTarget.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCConfigurationEventWithDefaultPauseTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.event.gc.configuration.TestGCConfigurationEventWithDefaultPauseTarget diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWith32BitOops.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWith32BitOops.java index 0a61a288cc218..9ef90afb06336 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWith32BitOops.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWith32BitOops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /* * @test TestGCHeapConfigurationEventWith32BitOops - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @requires os.family == "linux" | os.family == "windows" diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithHeapBasedOops.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithHeapBasedOops.java index a6fdcbde6b18e..5346c7a71038c 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithHeapBasedOops.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithHeapBasedOops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /* * @test TestGCHeapConfigurationEventWith32BitOops - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @requires os.family == "linux" | os.family == "windows" diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithZeroBasedOops.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithZeroBasedOops.java index d63ca856bc34a..62d858eef984f 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithZeroBasedOops.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCHeapConfigurationEventWithZeroBasedOops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /* * @test TestGCHeapConfigurationEventWithZeroBasedOops - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @requires os.family == "linux" | os.family == "windows" diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCSurvivorConfigurationEvent.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCSurvivorConfigurationEvent.java index fde69412a7af6..2a282660b03f4 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCSurvivorConfigurationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCSurvivorConfigurationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCTLABConfigurationEvent.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCTLABConfigurationEvent.java index b69e4fb8490c7..cabf6ac1fab8c 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCTLABConfigurationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCTLABConfigurationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithMinAndMaxSize.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithMinAndMaxSize.java index d347378b6063d..b58bb2ae7bf20 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithMinAndMaxSize.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithMinAndMaxSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run driver jdk.jfr.event.gc.configuration.TestGCYoungGenerationConfigurationEventWithMinAndMaxSize diff --git a/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithNewRatio.java b/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithNewRatio.java index 0c78f1e9541fb..c360ae3fa86d8 100644 --- a/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithNewRatio.java +++ b/test/jdk/jdk/jfr/event/gc/configuration/TestGCYoungGenerationConfigurationEventWithNewRatio.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:NewRatio=4 jdk.jfr.event.gc.configuration.TestGCYoungGenerationConfigurationEventWithNewRatio diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java index 584900620d4ec..41cfbf97b95e0 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @bug 8263461 * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationInfoEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationInfoEvent.java index 420f083758db0..0ec33a9d5eecd 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationInfoEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationInfoEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1AIHOPEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1AIHOPEvent.java index deed6b6462646..6570bbdd6afa4 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1AIHOPEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1AIHOPEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1ConcurrentModeFailureEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1ConcurrentModeFailureEvent.java index dade7aea8b68e..d178a429560a1 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1ConcurrentModeFailureEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1ConcurrentModeFailureEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "G1" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1EvacMemoryStatsEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1EvacMemoryStatsEvent.java index e32cfda41a9b4..56798b09db30d 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1EvacMemoryStatsEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1EvacMemoryStatsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1HeapRegionTypeChangeEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1HeapRegionTypeChangeEvent.java index b716295b507d7..399d82aa0f0c3 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1HeapRegionTypeChangeEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1HeapRegionTypeChangeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @bug 8149650 * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -XX:NewSize=2m -XX:MaxNewSize=2m -Xmx32m -XX:G1HeapRegionSize=1m -XX:+UseG1GC jdk.jfr.event.gc.detailed.TestG1HeapRegionTypeChangeEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1IHOPEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1IHOPEvent.java index 4a5bce6a69f49..20ec6fa76f479 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1IHOPEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1IHOPEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1InvalidHeapRegionTypeChangeEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1InvalidHeapRegionTypeChangeEvent.java index 023020f2a296b..7939a769ccb8c 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1InvalidHeapRegionTypeChangeEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1InvalidHeapRegionTypeChangeEvent.java @@ -39,7 +39,7 @@ * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @requires vm.debug - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @summary Make sure that there are no Old->Old and Free->Free events sent. * @run main/othervm -XX:+G1GCAllocationFailureALot -XX:NewSize=2m -XX:MaxNewSize=2m -XX:MaxTenuringThreshold=1 diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestG1MMUEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestG1MMUEvent.java index 967a3bc03d5b5..49b4a72147230 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestG1MMUEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestG1MMUEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java index 9e7d7ca54137e..cd9f0046cbbef 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCCPUTimeEvent.java @@ -32,7 +32,7 @@ /** * @test id=Serial - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.Serial * @library /test/lib /test/jdk @@ -43,7 +43,7 @@ /** * @test id=Parallel - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.Parallel * @library /test/lib /test/jdk @@ -54,7 +54,7 @@ /** * @test id=G1 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.G1 * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java index 6d5308408d622..1286c53d938ad 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryPoolUsageEvent.java @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:-ExplicitGCInvokesConcurrent jdk.jfr.event.gc.detailed.TestGCHeapMemoryPoolUsageEvent diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java index 7f1d96a3993b0..d54ca7a723d04 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCHeapMemoryUsageEvent.java @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:-ExplicitGCInvokesConcurrent jdk.jfr.event.gc.detailed.TestGCHeapMemoryUsageEvent diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java deleted file mode 100644 index 596af47de39bc..0000000000000 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -/** - * @test TestGCLockerEvent - * @key jfr - * @requires vm.hasJFR - * @requires vm.gc.Serial | vm.gc.Parallel - * @requires vm.gc != null - * @library /test/lib - * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx32m -Xms32m -Xmn12m jdk.jfr.event.gc.detailed.TestGCLockerEvent - */ - -package jdk.jfr.event.gc.detailed; - -import static jdk.test.lib.Asserts.assertTrue; - -import java.util.concurrent.CountDownLatch; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; -import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.Events; - -import jdk.test.whitebox.WhiteBox; - -public class TestGCLockerEvent { - - private static final String EVENT_NAME = EventNames.GCLocker; - - private static final int CRITICAL_THREAD_COUNT = 4; - - private static final CountDownLatch LOCK_COUNT_SIGNAL = new CountDownLatch(CRITICAL_THREAD_COUNT); - - private static final CountDownLatch UNLOCK_SIGNAL = new CountDownLatch(1); - - private static final CountDownLatch UNLOCK_COUNT_SIGNAL = new CountDownLatch(CRITICAL_THREAD_COUNT); - - private static final String CRITICAL_THREAD_NAME_PREFIX = "Critical Thread "; - - private static final int STALL_THREAD_COUNT = 8; - - private static final CountDownLatch STALL_COUNT_SIGNAL = new CountDownLatch(STALL_THREAD_COUNT); - - private static final int LOOP = 32; - - private static final int M = 1024 * 1024; - - public static void main(String[] args) throws Exception { - var recording = new Recording(); - recording.enable(EVENT_NAME); - recording.start(); - - startCriticalThreads(); - LOCK_COUNT_SIGNAL.await(); - startStallThreads(); - STALL_COUNT_SIGNAL.await(); - - // Wait threads to be stalled - Thread.sleep(1500); - - UNLOCK_SIGNAL.countDown(); - UNLOCK_COUNT_SIGNAL.await(); - recording.stop(); - - // Verify recording - var all = Events.fromRecording(recording); - Events.hasEvents(all); - var event = all.getFirst(); - - assertTrue(Events.isEventType(event, EVENT_NAME)); - Events.assertField(event, "lockCount").equal(CRITICAL_THREAD_COUNT); - Events.assertField(event, "stallCount").atLeast(STALL_THREAD_COUNT); - assertTrue(event.getThread().getJavaName().startsWith(CRITICAL_THREAD_NAME_PREFIX)); - - recording.close(); - } - - private static void startCriticalThreads() { - for (var i = 0; i < CRITICAL_THREAD_COUNT; i++) { - new Thread(() -> { - try { - WhiteBox.getWhiteBox().lockCritical(); - LOCK_COUNT_SIGNAL.countDown(); - - UNLOCK_SIGNAL.await(); - WhiteBox.getWhiteBox().unlockCritical(); - UNLOCK_COUNT_SIGNAL.countDown(); - } catch (InterruptedException ex) { - } - }, CRITICAL_THREAD_NAME_PREFIX + i).start(); - } - } - - private static void startStallThreads() { - var ts = new Thread[STALL_THREAD_COUNT]; - for (var i = 0; i < STALL_THREAD_COUNT; i++) { - ts[i] = new Thread(() -> { - STALL_COUNT_SIGNAL.countDown(); - for (int j = 0; j < LOOP; j++) { - byte[] bytes = new byte[M]; - } - }); - } - for (Thread t : ts) { - t.start(); - } - } -} - diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCPhaseConcurrent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCPhaseConcurrent.java index 66e3e026536af..fde4cd9c2d605 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCPhaseConcurrent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCPhaseConcurrent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test id=Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @requires vm.hasJFR & vm.gc.Z * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestGCPhaseConcurrent Z @@ -40,7 +40,7 @@ /** * @test TestGCPhaseConcurrent - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @requires vm.hasJFR & vm.gc.Shenandoah * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx32M jdk.jfr.event.gc.detailed.TestGCPhaseConcurrent Shenandoah diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithG1.java b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithG1.java index ac646e7c14a05..3e76369940232 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithG1.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithG1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test * @bug 8212766 - * @key jfr + * @requires vm.flagless * @summary Test that events are created when an object is aged or promoted during a GC and the copying of the object requires a new PLAB or direct heap allocation * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithParallelScavenge.java b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithParallelScavenge.java index 30b18a9df4a2a..13de75ff583d0 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithParallelScavenge.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionEventWithParallelScavenge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test that events are created when an object is aged or promoted during a GC and the copying of the object requires a new PLAB or direct heap allocation * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithDefNew.java b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithDefNew.java index 53382ea8ba269..b239f6f78ba77 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithDefNew.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithDefNew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Serial" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithParallelScavenge.java b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithParallelScavenge.java index 98abeabdacb4b..4880640b77265 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithParallelScavenge.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestPromotionFailedEventWithParallelScavenge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "Parallel" | vm.gc == null diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java index 33310ab721a5a..5730f4d9ff4b4 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahEvacuationInformationEvent.java @@ -39,7 +39,7 @@ * @test * @bug 8221507 * @requires vm.hasJFR & vm.gc.Shenandoah - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx64m -XX:+UnlockExperimentalVMOptions -XX:ShenandoahRegionSize=1m -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational jdk.jfr.event.gc.detailed.TestShenandoahEvacuationInformationEvent */ @@ -49,6 +49,7 @@ public class TestShenandoahEvacuationInformationEvent { public static void main(String[] args) throws Exception { final long shenandoahHeapRegionSize = 1024 * 1024; + final long shenandoahMaxHeapRegionCount = 64; Recording recording = new Recording(); recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(0)); recording.start(); @@ -63,16 +64,16 @@ public static void main(String[] args) throws Exception { } System.out.println("Event: " + event); - long setRegions = Events.assertField(event, "cSetRegions").atLeast(0L).getValue(); + long cSetRegions = Events.assertField(event, "cSetRegions").atLeast(0L).getValue(); long setUsedAfter = Events.assertField(event, "cSetUsedAfter").atLeast(0L).getValue(); long setUsedBefore = Events.assertField(event, "cSetUsedBefore").atLeast(setUsedAfter).getValue(); - long regionsFreed = Events.assertField(event, "regionsFreed").atLeast(0L).getValue(); + long freeRegions = Events.assertField(event, "freeRegions").atLeast(0L).getValue(); Events.assertField(event, "collectedOld").atLeast(0L).getValue(); Events.assertField(event, "collectedYoung").atLeast(0L).getValue(); - Asserts.assertGreaterThanOrEqual(setRegions, regionsFreed, "setRegions >= regionsFreed"); - Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * setRegions, setUsedAfter, "ShenandoahHeapRegionSize * setRegions >= setUsedAfter"); - Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * setRegions, setUsedBefore, "ShenandoahHeapRegionSize * setRegions >= setUsedBefore"); + Asserts.assertGreaterThanOrEqual(shenandoahMaxHeapRegionCount, freeRegions + cSetRegions, "numRegions >= freeRegions + cSetRegions"); + Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * cSetRegions, setUsedAfter, "ShenandoahHeapRegionSize * cSetRegions >= setUsedAfter"); + Asserts.assertGreaterThanOrEqual(shenandoahHeapRegionSize * cSetRegions, setUsedBefore, "ShenandoahHeapRegionSize * cSetRegions >= setUsedBefore"); int gcId = Events.assertField(event, "gcId").getValue(); } diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java index 2f220571b7d2d..88538928145e4 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java @@ -38,7 +38,7 @@ * @test * @bug 8221507 * @requires vm.hasJFR & vm.gc.Shenandoah - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionInformationEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java index 3162497f52c64..dfd0c0f86bcb6 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java @@ -38,7 +38,7 @@ * @test * @bug 8221507 * @requires vm.hasJFR & vm.gc.Shenandoah - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionStateChangeEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestTenuringDistributionEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestTenuringDistributionEvent.java index 9002373caef9e..843219d61d2b7 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestTenuringDistributionEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestTenuringDistributionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @bug 8009538 * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk * @run main/othervm -XX:NewSize=2m -XX:MaxNewSize=2m -Xmx32m -XX:+UseG1GC -XX:+NeverTenure jdk.jfr.event.gc.detailed.TestTenuringDistributionEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java index b17c678ec5533..b2f20450d0d86 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xmx32M -Xlog:gc*:gc.log::filecount=0 jdk.jfr.event.gc.detailed.TestZAllocationStallEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java index c17e19193db63..83caddbbaafbc 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestZPageAllocationEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetEvent.java index baae61d5cd81f..e64d6f83ab822 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestZRelocationSetEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java index 0e93aed8b8eb8..29e1de24224c3 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestZRelocationSetGroupEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZUncommitEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZUncommitEvent.java index 1aa2ba6af0b6d..f77ada9bf1bf4 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZUncommitEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZUncommitEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test id=Z * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xms32M -Xmx128M -Xlog:gc,gc+heap -XX:+ZUncommit -XX:ZUncommitDelay=1 jdk.jfr.event.gc.detailed.TestZUncommitEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZUnmapEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZUnmapEvent.java index fabbdce9c94ea..93ed6253de28b 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZUnmapEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZUnmapEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test id=Z * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestZUnmapEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryCommittedSize.java b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryCommittedSize.java index 2606757721f8a..33578d854b6c0 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryCommittedSize.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryCommittedSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventDefNewSerial.java b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventDefNewSerial.java index b46d52e46f18d..f70d7a85f168f 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventDefNewSerial.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventDefNewSerial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk @@ -36,7 +36,7 @@ /** * @test * @bug 8264008 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.bits == 64 * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java index fc30a8dec7345..edecfaf14065e 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != true diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventPSParOld.java b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventPSParOld.java index 475c0ff84fe7e..306b23f88b786 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventPSParOld.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventPSParOld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java index 3fe9e0f360d90..eb69289aa5e2d 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != false diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java index 54b8ebc33e4bc..6e91cf4c64452 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != true diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java index 8d88c8d6d8e66..2a17e540be86f 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithParallelOld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java index 6401a0002e2c5..888eb08902720 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithSerial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java index 2f7c7513b258e..a9034ba0eaad2 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/TestObjectCountEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithDefNew.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithDefNew.java index 5e3ce6928c9a1..bc26ad792d0a7 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithDefNew.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithDefNew.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Serial" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1ConcurrentMark.java index 7a635d4812e12..33547a1ca6766 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1ConcurrentMark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != false diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1FullCollection.java index b06d68c5cc313..2bf13facffcbf 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1FullCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != true diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1New.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1New.java index 16e87232a51a2..139e95980a50d 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1New.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithG1New.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelOld.java index a2810a8c8b225..5faae179fe0f2 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelOld.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelOld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelScavenge.java b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelScavenge.java index 21ae0a319a8ea..ce9dd0b936cdd 100644 --- a/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelScavenge.java +++ b/test/jdk/jdk/jfr/event/gc/refstat/TestRefStatEventWithParallelScavenge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestDefNewAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestDefNewAllocationPendingStackTrace.java index 4f83b37765d89..8741d433570ed 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestDefNewAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestDefNewAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Serial" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1HumongousAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1HumongousAllocationPendingStackTrace.java index 0cc00bb1e4b76..a61a87fd53958 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1HumongousAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1HumongousAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "G1" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1OldAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1OldAllocationPendingStackTrace.java index e74528c20e181..1346c36c04f36 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1OldAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1OldAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "G1" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1YoungAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1YoungAllocationPendingStackTrace.java index 0454d8fe77f00..8c951919feb2f 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1YoungAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestG1YoungAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "G1" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMarkSweepCompactAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMarkSweepCompactAllocationPendingStackTrace.java index 07a1c63fda1f4..8b3261e3a00ae 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMarkSweepCompactAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMarkSweepCompactAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Serial" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceG1GCAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceG1GCAllocationPendingStackTrace.java index 5a0cc9288b604..06c0d23788b42 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceG1GCAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceG1GCAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package jdk.jfr.event.gc.stacktrace; /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "G1" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceParallelGCAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceParallelGCAllocationPendingStackTrace.java index 8e71c8d55a83c..13bfc7c9ea6bb 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceParallelGCAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceParallelGCAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Parallel" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceSerialGCAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceSerialGCAllocationPendingStackTrace.java index 4d9a53e9afd32..36bf59741ee26 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceSerialGCAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestMetaspaceSerialGCAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Serial" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelMarkSweepAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelMarkSweepAllocationPendingStackTrace.java index 733b493548121..93e6b5b17e791 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelMarkSweepAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelMarkSweepAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Parallel" diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelScavengeAllocationPendingStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelScavengeAllocationPendingStackTrace.java index 341a3e53aa8c6..7771965dc97b9 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelScavengeAllocationPendingStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/TestParallelScavengeAllocationPendingStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @requires vm.gc == "null" | vm.gc == "Parallel" diff --git a/test/jdk/jdk/jfr/event/io/TestAsynchronousFileChannelEvents.java b/test/jdk/jdk/jfr/event/io/TestAsynchronousFileChannelEvents.java index f1ddba369eb41..e0752c6d319dd 100644 --- a/test/jdk/jdk/jfr/event/io/TestAsynchronousFileChannelEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestAsynchronousFileChannelEvents.java @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestAsynchronousFileChannelEvents diff --git a/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java b/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java index 28b26165e2f70..04e5126ca0055 100644 --- a/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java +++ b/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @test * @bug 8261160 * @summary Add a deserialization JFR event - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run testng/othervm jdk.jfr.event.io.TestDeserializationEvent diff --git a/test/jdk/jdk/jfr/event/io/TestDisabledEvents.java b/test/jdk/jdk/jfr/event/io/TestDisabledEvents.java index 0b523b80523b8..5a6835c4ce2fb 100644 --- a/test/jdk/jdk/jfr/event/io/TestDisabledEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestDisabledEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary Test with FlightRecorder enabled but with the events disabled. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestDisabledEvents diff --git a/test/jdk/jdk/jfr/event/io/TestFileChannelEvents.java b/test/jdk/jdk/jfr/event/io/TestFileChannelEvents.java index 11ae0a12e4fb5..490e16d3e52b4 100644 --- a/test/jdk/jdk/jfr/event/io/TestFileChannelEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestFileChannelEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestFileChannelEvents diff --git a/test/jdk/jdk/jfr/event/io/TestFileReadOnly.java b/test/jdk/jdk/jfr/event/io/TestFileReadOnly.java index 6986c43e3fe1b..f28c20d888173 100644 --- a/test/jdk/jdk/jfr/event/io/TestFileReadOnly.java +++ b/test/jdk/jdk/jfr/event/io/TestFileReadOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestFileReadOnly diff --git a/test/jdk/jdk/jfr/event/io/TestFileStreamEvents.java b/test/jdk/jdk/jfr/event/io/TestFileStreamEvents.java index d557a8dfd7de2..a710335e63d95 100644 --- a/test/jdk/jdk/jfr/event/io/TestFileStreamEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestFileStreamEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test TestFileStreamEvents - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestFileStreamEvents diff --git a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java index beef8437a3442..37a196237e810 100644 --- a/test/jdk/jdk/jfr/event/io/TestInstrumentation.java +++ b/test/jdk/jdk/jfr/event/io/TestInstrumentation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ /* * @test * @summary Test that will instrument the same classes that JFR will also instrument. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/io/TestRandomAccessFileEvents.java b/test/jdk/jdk/jfr/event/io/TestRandomAccessFileEvents.java index 47fbc62d08d20..4da995533f8b3 100644 --- a/test/jdk/jdk/jfr/event/io/TestRandomAccessFileEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestRandomAccessFileEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestRandomAccessFileEvents diff --git a/test/jdk/jdk/jfr/event/io/TestRandomAccessFileThread.java b/test/jdk/jdk/jfr/event/io/TestRandomAccessFileThread.java index a815a1231ce41..54b989cbf3c8b 100644 --- a/test/jdk/jdk/jfr/event/io/TestRandomAccessFileThread.java +++ b/test/jdk/jdk/jfr/event/io/TestRandomAccessFileThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary Verify the event time stamp and thread name - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.event.io.TestRandomAccessFileThread diff --git a/test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java b/test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java index 7c7b8366a0468..b746d50689e2e 100644 --- a/test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java +++ b/test/jdk/jdk/jfr/event/io/TestSerializationMisdeclarationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @bug 8275338 8324220 * @summary Check generation of JFR events for misdeclared fields and methods * relevant to serialization - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run junit/othervm jdk.jfr.event.io.TestSerializationMisdeclarationEvent diff --git a/test/jdk/jdk/jfr/event/io/TestSocketAdapterEvents.java b/test/jdk/jdk/jfr/event/io/TestSocketAdapterEvents.java index 9ac57b839fb2c..77a083ad8fe9d 100644 --- a/test/jdk/jdk/jfr/event/io/TestSocketAdapterEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestSocketAdapterEvents.java @@ -48,7 +48,7 @@ * @test * @bug 8310978 * @summary test socket read/write events on socket adaptors - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestSocketAdapterEvents diff --git a/test/jdk/jdk/jfr/event/io/TestSocketChannelEvents.java b/test/jdk/jdk/jfr/event/io/TestSocketChannelEvents.java index fc045e55caa6e..1a40edde0fd94 100644 --- a/test/jdk/jdk/jfr/event/io/TestSocketChannelEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestSocketChannelEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary test socket read/write events on SocketChannel - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestSocketChannelEvents diff --git a/test/jdk/jdk/jfr/event/io/TestSocketEvents.java b/test/jdk/jdk/jfr/event/io/TestSocketEvents.java index d73c5010cf7d0..144b9592b2206 100644 --- a/test/jdk/jdk/jfr/event/io/TestSocketEvents.java +++ b/test/jdk/jdk/jfr/event/io/TestSocketEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ /** * @test * @summary test socket read/write events on Socket - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.event.io.TestSocketEvents diff --git a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java index 3b8b0d975eb6f..3a14937e21d37 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java +++ b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java b/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java index afdb84952f429..e3255909fccb7 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java +++ b/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.metadata.TestEventMetadata diff --git a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java index 981579ba341e6..5b8aacfb1d228 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java +++ b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test Check for JFR events not covered by tests - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main jdk.jfr.event.metadata.TestLookForUntestedEvents diff --git a/test/jdk/jdk/jfr/event/oldobject/TestAllocationTime.java b/test/jdk/jdk/jfr/event/oldobject/TestAllocationTime.java index ce3e3057699a3..0ce109368a56f 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestAllocationTime.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestAllocationTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestArrayInformation.java b/test/jdk/jdk/jfr/event/oldobject/TestArrayInformation.java index 028024fdd284f..393a734aa26a1 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestArrayInformation.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestArrayInformation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestCircularReference.java b/test/jdk/jdk/jfr/event/oldobject/TestCircularReference.java index b3dbfef090c45..a601cefad40d5 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestCircularReference.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestCircularReference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java b/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java index 6f7337d37777d..b9aab92b9242e 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.flagless * @comment Marked as flagless until JDK-8322597 is fixed diff --git a/test/jdk/jdk/jfr/event/oldobject/TestFieldInformation.java b/test/jdk/jdk/jfr/event/oldobject/TestFieldInformation.java index fb0f5eebd7fb7..0d3e1dcc2e564 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestFieldInformation.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestFieldInformation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestG1.java b/test/jdk/jdk/jfr/event/oldobject/TestG1.java index 79df63953c557..4c3d65a3ecea4 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestG1.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestG1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.G1 * @summary Test leak profiler with G1 GC diff --git a/test/jdk/jdk/jfr/event/oldobject/TestHeapDeep.java b/test/jdk/jdk/jfr/event/oldobject/TestHeapDeep.java index b7cbb233f311e..7461a9f1503c2 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestHeapDeep.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestHeapDeep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestHeapShallow.java b/test/jdk/jdk/jfr/event/oldobject/TestHeapShallow.java index 8d8b7f3c97aa3..bca93871cd901 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestHeapShallow.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestHeapShallow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestLargeRootSet.java b/test/jdk/jdk/jfr/event/oldobject/TestLargeRootSet.java index 4fe432e649327..c2a4cc5264ce5 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestLargeRootSet.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestLargeRootSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestLastKnownHeapUsage.java b/test/jdk/jdk/jfr/event/oldobject/TestLastKnownHeapUsage.java index d51c52ab7e36c..36fdef6c86b93 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestLastKnownHeapUsage.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestLastKnownHeapUsage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java b/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java index 92610283525a6..fd895fae91b92 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java index b84160a0ac5a4..1747939390b2e 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @test * @summary The test verifies that an old object sample maintains references to "stale" metadata * @requires vm.hasJFR - * @key jfr + * @requires vm.flagless * @modules jdk.jfr/jdk.jfr.internal.test * @library /test/lib /test/jdk * @build jdk.jfr.event.oldobject.TestMetadataObject @@ -86,7 +86,7 @@ public static void main(String[] args) throws Throwable { // System.gc() will trigger class unloading if -XX:+ExplicitGCInvokesConcurrent // is NOT set. If this flag is set G1 will never unload classes on System.gc(). - // As far as the "jfr" key guarantees no VM flags are set from the + // As far as the vm.flagless guarantees no VM flags are set from the // outside it should be enough with System.gc(). System.gc(); diff --git a/test/jdk/jdk/jfr/event/oldobject/TestObjectAge.java b/test/jdk/jdk/jfr/event/oldobject/TestObjectAge.java index cd3ff53576250..6346326d620f0 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestObjectAge.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestObjectAge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestObjectDescription.java b/test/jdk/jdk/jfr/event/oldobject/TestObjectDescription.java index 447d2bb9cecf4..60f85e6ba7293 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestObjectDescription.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestObjectDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc != "Shenandoah" * @requires vm.flagless diff --git a/test/jdk/jdk/jfr/event/oldobject/TestObjectSize.java b/test/jdk/jdk/jfr/event/oldobject/TestObjectSize.java index 7b8a1003edd34..c10da3b498c3f 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestObjectSize.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestObjectSize.java @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestParallel.java b/test/jdk/jdk/jfr/event/oldobject/TestParallel.java index 547619c128356..e41b86e51d635 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestParallel.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestParallel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.Parallel * @summary Test leak profiler with Parallel GC diff --git a/test/jdk/jdk/jfr/event/oldobject/TestReferenceChainLimit.java b/test/jdk/jdk/jfr/event/oldobject/TestReferenceChainLimit.java index 640819e9bc69a..be8cb03fb39c5 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestReferenceChainLimit.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestReferenceChainLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestSanityDefault.java b/test/jdk/jdk/jfr/event/oldobject/TestSanityDefault.java index 30186db8def5b..c312fc1a8769f 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestSanityDefault.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestSanityDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ /** * @test - * @key jfr * @requires vm.hasJFR * @requires vm.flagless * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/oldobject/TestSerial.java b/test/jdk/jdk/jfr/event/oldobject/TestSerial.java index 8ed4d51c19d8c..4e6ee3c39d33e 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestSerial.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestSerial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.gc.Serial * @summary Test leak profiler with Serial GC diff --git a/test/jdk/jdk/jfr/event/oldobject/TestShenandoah.java b/test/jdk/jdk/jfr/event/oldobject/TestShenandoah.java index 6d3483910301b..14b3dec5eb374 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestShenandoah.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestShenandoah.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.gc.Shenandoah * @summary Test leak profiler with Shenandoah * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/event/oldobject/TestThreadLocalLeak.java b/test/jdk/jdk/jfr/event/oldobject/TestThreadLocalLeak.java index c82636e9146e9..3ccc6952cdc12 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestThreadLocalLeak.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestThreadLocalLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/oldobject/TestZ.java b/test/jdk/jdk/jfr/event/oldobject/TestZ.java index 8aff89ce7de64..9ae406c93697c 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestZ.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestZ.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @requires vm.hasJFR & vm.gc.Z - * @key jfr + * @requires vm.flagless * @summary Test leak profiler with ZGC * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/event/os/TestCPUInformation.java b/test/jdk/jdk/jfr/event/os/TestCPUInformation.java index c5166580010df..5a9e631141c1a 100644 --- a/test/jdk/jdk/jfr/event/os/TestCPUInformation.java +++ b/test/jdk/jdk/jfr/event/os/TestCPUInformation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestCPUInformation diff --git a/test/jdk/jdk/jfr/event/os/TestCPULoad.java b/test/jdk/jdk/jfr/event/os/TestCPULoad.java index efc9b39adf50e..09ceb0a79b786 100644 --- a/test/jdk/jdk/jfr/event/os/TestCPULoad.java +++ b/test/jdk/jdk/jfr/event/os/TestCPULoad.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,10 +30,9 @@ import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; - /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestCPULoad @@ -41,13 +40,32 @@ public class TestCPULoad { private final static String EVENT_NAME = EventNames.CPULoad; + public static boolean isPrime(int num) { + if (num <= 1) return false; + for (int i = 2; i <= Math.sqrt(num); i++) { + if (num % i == 0) return false; + } + return true; + } + + public static int burnCpuCycles(int limit) { + int primeCount = 0; + for (int i = 2; i < limit; i++) { + if (isPrime(i)) { + primeCount++; + } + } + return primeCount; + } + public static void main(String[] args) throws Throwable { Recording recording = new Recording(); recording.enable(EVENT_NAME); recording.start(); - // Need to sleep so a time delta can be calculated - Thread.sleep(100); + // burn some cycles to check increase of CPU related counters + int pn = burnCpuCycles(2500000); recording.stop(); + System.out.println("Found " + pn + " primes while burning cycles"); List events = Events.fromRecording(recording); if (events.isEmpty()) { diff --git a/test/jdk/jdk/jfr/event/os/TestCPUTimeStampCounter.java b/test/jdk/jdk/jfr/event/os/TestCPUTimeStampCounter.java index fd37ef195a54f..464de5557bedb 100644 --- a/test/jdk/jdk/jfr/event/os/TestCPUTimeStampCounter.java +++ b/test/jdk/jdk/jfr/event/os/TestCPUTimeStampCounter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestCPUTimeStampCounter diff --git a/test/jdk/jdk/jfr/event/os/TestInitialEnvironmentVariable.java b/test/jdk/jdk/jfr/event/os/TestInitialEnvironmentVariable.java index d8fd9a6e67344..e869a3da3c7db 100644 --- a/test/jdk/jdk/jfr/event/os/TestInitialEnvironmentVariable.java +++ b/test/jdk/jdk/jfr/event/os/TestInitialEnvironmentVariable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main jdk.jfr.event.os.TestInitialEnvironmentVariable diff --git a/test/jdk/jdk/jfr/event/os/TestOSInfo.java b/test/jdk/jdk/jfr/event/os/TestOSInfo.java index ce7565e3f5182..5dfce35683bef 100644 --- a/test/jdk/jdk/jfr/event/os/TestOSInfo.java +++ b/test/jdk/jdk/jfr/event/os/TestOSInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestOSInfo diff --git a/test/jdk/jdk/jfr/event/os/TestPhysicalMemoryEvent.java b/test/jdk/jdk/jfr/event/os/TestPhysicalMemoryEvent.java index 13e0522727842..79810a58b3a81 100644 --- a/test/jdk/jdk/jfr/event/os/TestPhysicalMemoryEvent.java +++ b/test/jdk/jdk/jfr/event/os/TestPhysicalMemoryEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestPhysicalMemoryEvent diff --git a/test/jdk/jdk/jfr/event/os/TestProcessStart.java b/test/jdk/jdk/jfr/event/os/TestProcessStart.java index bcf216857bb9b..2d1d80f59418d 100644 --- a/test/jdk/jdk/jfr/event/os/TestProcessStart.java +++ b/test/jdk/jdk/jfr/event/os/TestProcessStart.java @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestProcessStart diff --git a/test/jdk/jdk/jfr/event/os/TestSwapSpaceEvent.java b/test/jdk/jdk/jfr/event/os/TestSwapSpaceEvent.java index 5ea2ed139eafa..cf92db85ace79 100644 --- a/test/jdk/jdk/jfr/event/os/TestSwapSpaceEvent.java +++ b/test/jdk/jdk/jfr/event/os/TestSwapSpaceEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (os.family != "linux") * @library /test/lib @@ -41,7 +41,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (os.family == "linux") * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/os/TestSystemProcess.java b/test/jdk/jdk/jfr/event/os/TestSystemProcess.java index 0af7a7ff37949..a76060bac9d8d 100644 --- a/test/jdk/jdk/jfr/event/os/TestSystemProcess.java +++ b/test/jdk/jdk/jfr/event/os/TestSystemProcess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestSystemProcess diff --git a/test/jdk/jdk/jfr/event/os/TestThreadContextSwitches.java b/test/jdk/jdk/jfr/event/os/TestThreadContextSwitches.java index 00b846b87e2bb..7b3dfc79ce956 100644 --- a/test/jdk/jdk/jfr/event/os/TestThreadContextSwitches.java +++ b/test/jdk/jdk/jfr/event/os/TestThreadContextSwitches.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestThreadContextSwitches diff --git a/test/jdk/jdk/jfr/event/os/TestVirtualizationInfo.java b/test/jdk/jdk/jfr/event/os/TestVirtualizationInfo.java index 0c3c86d5829ec..2c30e102c73f8 100644 --- a/test/jdk/jdk/jfr/event/os/TestVirtualizationInfo.java +++ b/test/jdk/jdk/jfr/event/os/TestVirtualizationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.os.TestVirtualizationInfo diff --git a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java index b7abbc0a587f1..13cf709f0187e 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java +++ b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,6 @@ /** * @test - * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.profiling.TestFullStackTrace diff --git a/test/jdk/jdk/jfr/event/profiling/TestNative.java b/test/jdk/jdk/jfr/event/profiling/TestNative.java index 21949bcc31306..e7e076051f45f 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestNative.java +++ b/test/jdk/jdk/jfr/event/profiling/TestNative.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /* * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/event/profiling/TestSamplingLongPeriod.java b/test/jdk/jdk/jfr/event/profiling/TestSamplingLongPeriod.java index c2cd4cb7bd16a..2402a948ef988 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestSamplingLongPeriod.java +++ b/test/jdk/jdk/jfr/event/profiling/TestSamplingLongPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /* * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/event/runtime/TestActiveRecordingEvent.java b/test/jdk/jdk/jfr/event/runtime/TestActiveRecordingEvent.java index e786e8c933d0d..778acf48306e0 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestActiveRecordingEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestActiveRecordingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary Tests that the recording properties are properly reflected in the ActiveRecording event - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestActiveRecordingEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java index 2b55a012d44d8..92298eaece0ff 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ /** * @test * @summary Tests that active setting are available in the ActiveSettingevent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestActiveSettingEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestAgentEvent.java b/test/jdk/jdk/jfr/event/runtime/TestAgentEvent.java index 240868d567077..ca7b6dfc0f112 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestAgentEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestAgentEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests Agent Loaded event by starting native and Java agents * @requires vm.hasJFR & vm.jvmti * diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java b/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java index 3681e73b52707..b0522741a1e49 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java b/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java index ec72253bc0662..102ff92db719a 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java index 62b9ef1eccdb5..f73876e677c3a 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java index 8bbbdcbc447a7..6184a6f627e01 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassRedefinition.java b/test/jdk/jdk/jfr/event/runtime/TestClassRedefinition.java index 23c2f2cbc3a5b..5367d76dbf564 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassRedefinition.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassRedefinition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test * @summary Tests ClassRedefinition event by redefining classes in a Java agent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.instrument diff --git a/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java b/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java index 6507b7e53bfe3..f25b9a69650eb 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @summary The test verifies that a class unload event is created when class is unloaded - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java b/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java index 183d82bc5e201..e2ecea43a8802 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.internal.test * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/runtime/TestDirectBufferStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestDirectBufferStatisticsEvent.java index 777f2d5fca2be..b007083dde91f 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestDirectBufferStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestDirectBufferStatisticsEvent.java @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestDumpReason.java b/test/jdk/jdk/jfr/event/runtime/TestDumpReason.java index 83af0de239d3d..f801829d8eb3f 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestDumpReason.java +++ b/test/jdk/jdk/jfr/event/runtime/TestDumpReason.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules java.base/jdk.internal.misc jdk.jfr diff --git a/test/jdk/jdk/jfr/event/runtime/TestExceptionEvents.java b/test/jdk/jdk/jfr/event/runtime/TestExceptionEvents.java index 46488f0221a97..8c447ac44bf35 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestExceptionEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestExceptionEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestExceptionEvents diff --git a/test/jdk/jdk/jfr/event/runtime/TestExceptionSubclass.java b/test/jdk/jdk/jfr/event/runtime/TestExceptionSubclass.java index f6917faa8e2f9..0c55b27364eb9 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestExceptionSubclass.java +++ b/test/jdk/jdk/jfr/event/runtime/TestExceptionSubclass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @bug 8013122 * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java index 8256a62b5712b..ead77f467acb3 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestFinalizerStatisticsEvent.java @@ -36,7 +36,7 @@ * @test * @bug 8266936 8276422 * @summary The test verifies that classes overriding finalize() are represented as events. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -Xlog:class+unload,finalizer -Xmx16m jdk.jfr.event.runtime.TestFinalizerStatisticsEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestFlush.java b/test/jdk/jdk/jfr/event/runtime/TestFlush.java index ad8706a649379..5c450eab05f85 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestFlush.java +++ b/test/jdk/jdk/jfr/event/runtime/TestFlush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary Verifies at the metalevel that stream contents are written to ongoing recordings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xlog:jfr+system+streaming=trace jdk.jfr.event.runtime.TestFlush diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaBlockedEvent.java b/test/jdk/jdk/jfr/event/runtime/TestJavaBlockedEvent.java index 23fb1cd84332c..c29cebc3d1ddf 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaBlockedEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaBlockedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorInflateEvent.java b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorInflateEvent.java index 596b50f5b0cd2..5b7fb3e19cad2 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorInflateEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorInflateEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test TestJavaMonitorInflateEvent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestJavaMonitorInflateEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitEvent.java b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitEvent.java index a9cbd04019264..d16503f1fdc75 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestJavaMonitorWaitEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitTimeOut.java b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitTimeOut.java index 0e200f68f9ee6..379b9a97a298f 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitTimeOut.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaMonitorWaitTimeOut.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestJavaMonitorWaitTimeOut diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEvent.java index 4a6c991ec3cc9..92d86b1163cd1 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestJavaThreadStatisticsEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEventBean.java b/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEventBean.java index 1702d5cd2352b..dae73cb76b55d 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEventBean.java +++ b/test/jdk/jdk/jfr/event/runtime/TestJavaThreadStatisticsEventBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/event/runtime/TestModuleEvents.java b/test/jdk/jdk/jfr/event/runtime/TestModuleEvents.java index dc877e1cafc47..4998cb29d3dc2 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestModuleEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestModuleEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test * @summary Tests the JFR events related to modules - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires !vm.graal.enabled * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java b/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java index 571809ddab40c..132cc7e73b80d 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test * @bug 8216559 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestNativeLibrariesEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestNativeLibraryLoadEvent.java b/test/jdk/jdk/jfr/event/runtime/TestNativeLibraryLoadEvent.java index 240045c1d6089..e0931d7453f1a 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestNativeLibraryLoadEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestNativeLibraryLoadEvent.java @@ -39,7 +39,7 @@ /** * @test * @bug 8313251 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestNativeLibraryLoadEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java b/test/jdk/jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java index b1a564cb4a0cf..9373f7455913b 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.opt.NativeMemoryTracking == null * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java b/test/jdk/jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java index a1b5485a5bd7c..ac33c39a1a2d7 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/event/runtime/TestRedefineClasses.java b/test/jdk/jdk/jfr/event/runtime/TestRedefineClasses.java index 40fc583872f44..c4c73ec3d5787 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestRedefineClasses.java +++ b/test/jdk/jdk/jfr/event/runtime/TestRedefineClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @test * @summary Tests RedefinitionClasses event by redefining a class in a Java * agent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.instrument diff --git a/test/jdk/jdk/jfr/event/runtime/TestResidentSetSizeEvent.java b/test/jdk/jdk/jfr/event/runtime/TestResidentSetSizeEvent.java index facf222279c78..8b9bd99bf5ebe 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestResidentSetSizeEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestResidentSetSizeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/event/runtime/TestRetransformClasses.java b/test/jdk/jdk/jfr/event/runtime/TestRetransformClasses.java index a02f97366c3be..582422d8c8031 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestRetransformClasses.java +++ b/test/jdk/jdk/jfr/event/runtime/TestRetransformClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @test * @summary Tests the RetransformClasses event by redefining a class in a Java * agent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.instrument diff --git a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java index 8ea0181b0dd40..0dccbc4495a45 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test TestSafepointEvents - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @build jdk.test.whitebox.WhiteBox diff --git a/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java b/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java index d680dde023d7a..61d99fbec4f27 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestShutdownEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ /** * @test * @summary Test Shutdown event - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/event/runtime/TestSizeTFlags.java b/test/jdk/jdk/jfr/event/runtime/TestSizeTFlags.java index 3eaf4cccf6cc3..0c53d7c91a73a 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSizeTFlags.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSizeTFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @bug 8058552 * @requires vm.hasJFR * @requires vm.gc == "G1" | vm.gc == null - * @key jfr + * @requires vm.flagless * @summary Test checks that flags of type size_t are being sent to the jfr * @library /test/lib * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:+UseTLAB -XX:MinTLABSize=3k -XX:YoungPLABSize=3k -XX:MaxDirectMemorySize=5M jdk.jfr.event.runtime.TestSizeTFlags diff --git a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java index f20175da37fd9..7ad50c83399dd 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @bug 8242263 * @requires vm.hasJFR - * @key jfr + * @requires vm.flagless * @library /test/lib * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=2 jdk.jfr.event.runtime.TestSyncOnValueBasedClassEvent */ diff --git a/test/jdk/jdk/jfr/event/runtime/TestSystemPropertyEvent.java b/test/jdk/jdk/jfr/event/runtime/TestSystemPropertyEvent.java index 9cb506c45cb45..7adc1fabc2393 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSystemPropertyEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSystemPropertyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestSystemPropertyEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java b/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java index 1f5884c4b46e1..9652b5d501ce5 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules java.base/jdk.internal.misc diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadAllocationEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadAllocationEvent.java index 192559cd69b3d..69511a4b52159 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadAllocationEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadAllocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadCpuTimeEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadCpuTimeEvent.java index a6520614eab85..e6cd9d95d16a3 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadCpuTimeEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadCpuTimeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadDumpEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadDumpEvent.java index b583d48692668..302874880c29f 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadDumpEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadDumpEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestThreadDumpEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadEndEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadEndEvent.java index 160702de36098..0b70cd5bcbc20 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadEndEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadEndEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @compile TestThreadEndEvent.java LatchedThread.java diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadParkEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadParkEvent.java index d65a407430636..3887af38aeba7 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadParkEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadParkEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadSleepEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadSleepEvent.java index c084808ce79ae..e372766b95dab 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadSleepEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadSleepEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestThreadSleepEvent diff --git a/test/jdk/jdk/jfr/event/runtime/TestThreadStartEvent.java b/test/jdk/jdk/jfr/event/runtime/TestThreadStartEvent.java index 9e8f7b13e31f0..5b0a6ea68a39c 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestThreadStartEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestThreadStartEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @compile TestThreadStartEvent.java LatchedThread.java diff --git a/test/jdk/jdk/jfr/event/runtime/TestVMInfoEvent.java b/test/jdk/jdk/jfr/event/runtime/TestVMInfoEvent.java index 82a052739791b..2571530a47097 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVMInfoEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVMInfoEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.gc == "Serial" | vm.gc == null * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java index 31fb306c04d79..d9ed619ac3621 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @requires vm.hasJFR * @requires vm.gc == "Parallel" | vm.gc == null - * @key jfr + * @requires vm.flagless * @library /test/lib * @run main/othervm -XX:+UseParallelGC jdk.jfr.event.runtime.TestVMOperation */ diff --git a/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadEndEvent.java b/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadEndEvent.java index 355ef163e6fdd..7de0b321864db 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadEndEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadEndEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @compile TestVirtualThreadEndEvent.java LatchedThread.java diff --git a/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadStartEvent.java b/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadStartEvent.java index 7b4bdb4b28e7f..cc1f38b8a7272 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadStartEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVirtualThreadStartEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @compile TestVirtualThreadStartEvent.java LatchedThread.java diff --git a/test/jdk/jdk/jfr/event/runtime/TestVmFlagChangedEvent.java b/test/jdk/jdk/jfr/event/runtime/TestVmFlagChangedEvent.java index a386adc8ac2ff..a24996f0e5562 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVmFlagChangedEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVmFlagChangedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test TestVmFlagChangedEvent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/event/security/TestInitialSecurityPropertyEvent.java b/test/jdk/jdk/jfr/event/security/TestInitialSecurityPropertyEvent.java index bebd44782d21b..bed89be84c2ae 100644 --- a/test/jdk/jdk/jfr/event/security/TestInitialSecurityPropertyEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestInitialSecurityPropertyEvent.java @@ -38,7 +38,7 @@ * @test * @bug 8292177 * @summary InitialSecurityProperty JFR event - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules java.base/jdk.internal.access diff --git a/test/jdk/jdk/jfr/event/security/TestSecurityPropertyModificationEvent.java b/test/jdk/jdk/jfr/event/security/TestSecurityPropertyModificationEvent.java index ff5919b25909a..4ede92aee4166 100644 --- a/test/jdk/jdk/jfr/event/security/TestSecurityPropertyModificationEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestSecurityPropertyModificationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @test * @bug 8148188 * @summary Enhance the security libraries to record events of interest - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.security.TestSecurityPropertyModificationEvent diff --git a/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java b/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java index df801c5190742..70ed6f3d867d9 100644 --- a/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestSecurityProviderServiceEvent.java @@ -42,7 +42,7 @@ * @test * @bug 8254711 * @summary Add JFR events for security crypto algorithms - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.events diff --git a/test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java b/test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java index 7c5240a2a72e5..559290f50b47f 100644 --- a/test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestTLSHandshakeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * @test * @bug 8148188 * @summary Enhance the security libraries to record events of interest - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.security.TestTLSHandshakeEvent diff --git a/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java b/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java index e7e905830a44b..60b1406a0dc5f 100644 --- a/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @test * @bug 8148188 8292033 * @summary Enhance the security libraries to record events of interest - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules java.base/sun.security.x509 java.base/sun.security.tools.keytool * @library /test/lib diff --git a/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java b/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java index 651a6390f6857..92dc99ef8c713 100644 --- a/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java +++ b/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @test * @bug 8148188 * @summary Enhance the security libraries to record events of interest - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.events java.base/sun.security.x509 java.base/sun.security.tools.keytool diff --git a/test/jdk/jdk/jfr/javaagent/TestEventInstrumentation.java b/test/jdk/jdk/jfr/javaagent/TestEventInstrumentation.java index d5997f1ad4666..1a5ad27725b8c 100644 --- a/test/jdk/jdk/jfr/javaagent/TestEventInstrumentation.java +++ b/test/jdk/jdk/jfr/javaagent/TestEventInstrumentation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ * @test * @summary Verify that a subclass of the JFR Event class * can be successfully instrumented. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jartool/sun.tools.jar diff --git a/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java b/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java index deb38d5e8db86..92b88336b3e0d 100644 --- a/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java +++ b/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests emitting events in a dynamically loaded Java agent * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java b/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java index 19a39ff7ef07a..388779fcc7f84 100644 --- a/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java +++ b/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests emitting event before main using a Java agent * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/jcmd/TestFilenameExpansion.java b/test/jdk/jdk/jfr/jcmd/TestFilenameExpansion.java index 9b9f67ba0faa0..789d5cbe5bd36 100644 --- a/test/jdk/jdk/jfr/jcmd/TestFilenameExpansion.java +++ b/test/jdk/jdk/jfr/jcmd/TestFilenameExpansion.java @@ -34,7 +34,7 @@ /** * @test * @summary The test verifies JFR.start/dump/stop commands - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestFilenameExpansion diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java b/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java index dfb755a7f215f..c4ef5ecfa74fa 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdChangeLogLevel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test TestJcmdLogLevelChange - * @key jfr + * @requires vm.flagless * @summary Test changing log level * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java index 2780f396f0562..f64c99bedbcbf 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,12 @@ import java.io.File; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.Options; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; @@ -38,7 +38,7 @@ /** * @test * @summary The test verifies JFR.configure command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal @@ -131,17 +131,17 @@ private static void testRepository(){ try { JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_1); - SafePath initialPath = Repository.getRepository().getRepositoryPath(); + Path initialPath = Repository.getRepository().getRepositoryPath(); JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_1); - SafePath samePath = Repository.getRepository().getRepositoryPath(); + Path samePath = Repository.getRepository().getRepositoryPath(); Asserts.assertTrue(samePath.equals(initialPath)); List lines = Files.readAllLines(Paths.get(JFR_UNIFIED_LOG_FILE)); Asserts.assertTrue(lines.stream().anyMatch(l->l.contains(findWhat))); JcmdHelper.jcmd("JFR.configure", REPOSITORYPATH_SETTING_2); - SafePath changedPath = Repository.getRepository().getRepositoryPath(); + Path changedPath = Repository.getRepository().getRepositoryPath(); Asserts.assertFalse(changedPath.equals(initialPath)); diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java index 6ddf3a752342d..9eefbd183b2e4 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdConfigureReadOnly.java @@ -28,7 +28,7 @@ /** * @test * @summary The test verifies JFR.configure command can only set certain options before JFR is started. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdConfigureReadOnly diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDump.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDump.java index 6f4be44ff6377..2bc7aa857e3d5 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDump.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test * @summary The test verifies JFR.dump command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:FlightRecorderOptions:maxchunksize=1M jdk.jfr.jcmd.TestJcmdDump diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpGeneratedFilename.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpGeneratedFilename.java index 4612e7c7c8c9d..eca991eaab610 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpGeneratedFilename.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpGeneratedFilename.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary The test verifies JFR.dump command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdDumpGeneratedFilename diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpLimited.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpLimited.java index ce4b11937c611..8b8ba050245e8 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpLimited.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpLimited.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ /** * @test * @summary The test verifies JFR.dump command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdDumpLimited diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java index 5d469c698c190..499bf9452be68 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.internal.test * @library /test/lib /test/jdk - * @key jfr + * @requires vm.flagless * * @run main/othervm -XX:TLABSize=2k jdk.jfr.jcmd.TestJcmdDumpPathToGCRoots */ diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpWithFileName.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpWithFileName.java index 93265dc677cf5..268d250418da1 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpWithFileName.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpWithFileName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @bug 8220657 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdDumpWithFileName diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdLegacy.java b/test/jdk/jdk/jfr/jcmd/TestJcmdLegacy.java index a6aa2143f41dc..33e5d9542efe6 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdLegacy.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdLegacy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test TestClassId - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdOptionSpecifiedOnce.java b/test/jdk/jdk/jfr/jcmd/TestJcmdOptionSpecifiedOnce.java index bb057cce3867e..a9b9bcc58725f 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdOptionSpecifiedOnce.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdOptionSpecifiedOnce.java @@ -25,7 +25,7 @@ /** * @test * @summary The test verifies that options can only be specified once with jcmd JFR - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.dcmd diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java index 374c760ae9b47..9f42bef6e7e87 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdPreserveRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Test verifies that files are left after preserve-repository has been set using jcmd JFR.configure - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdPreserveRepository diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdSaveToFile.java b/test/jdk/jdk/jfr/jcmd/TestJcmdSaveToFile.java index b6542420bd5c0..b7ce317f9288b 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdSaveToFile.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdSaveToFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary The test verifies that recording can be written to a file both with JFR.start and JFR.stop - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdSaveToFile diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartDirNotExist.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartDirNotExist.java index 49035cff8f45c..e683880195b39 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartDirNotExist.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartDirNotExist.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Verify error when starting with a dir that does not exist. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartDirNotExist diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartFlushInterval.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartFlushInterval.java index 0d6e8fa076065..046ecd190f813 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartFlushInterval.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartFlushInterval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Start a recording with a flush interval - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr:open diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartGeneratedFilename.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartGeneratedFilename.java index d3e4dd7b2c2b6..bf365b9c248f1 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartGeneratedFilename.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartGeneratedFilename.java @@ -38,7 +38,7 @@ /** * @test * @summary Verify that a filename is generated - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartGeneratedFilename diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartInvaldFile.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartInvaldFile.java index 718ee55a839a7..e8e40557eab5e 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartInvaldFile.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartInvaldFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test * @summary Verify error when starting with invalid file. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartInvaldFile diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java index ff87d2b68a112..5e116480aa89f 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * @summary Start a recording with or without path-to-gc-roots * @requires vm.hasJFR * @library /test/lib /test/jdk - * @key jfr + * @requires vm.flagless * * @run main/othervm jdk.jfr.jcmd.TestJcmdStartPathToGCRoots */ diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartReadOnlyFile.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartReadOnlyFile.java index c1727c9ef974c..d74c29ae7bf03 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartReadOnlyFile.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartReadOnlyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Verify error when starting with read-only file. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartReadOnlyFile diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartStopDefault.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartStopDefault.java index 5985b85b167b3..374234fe07b06 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartStopDefault.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartStopDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test * @summary Start a recording without name. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartStopDefault diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithOptions.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithOptions.java index fe8db5f773aa0..41c144c16ee75 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithOptions.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary The test verifies that recording can be started with options delay|duration|maxage|maxsize - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:FlightRecorderOptions:maxchunksize=2097152 jdk.jfr.jcmd.TestJcmdStartWithOptions diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithSettings.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithSettings.java index d0e502c52a361..afe405ef29dfe 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithSettings.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStartWithSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary The test verifies that recording can be started with setting file(s) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStartWithSettings diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStopInvalidFile.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStopInvalidFile.java index 63f201c08bd31..dc74674ca9901 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStopInvalidFile.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStopInvalidFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test * @summary Verify error when stopping with invalid file. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStopInvalidFile diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStopReadOnlyFile.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStopReadOnlyFile.java index 10401bdf12f36..a91f11a55d682 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStopReadOnlyFile.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStopReadOnlyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Verify error when stopping with read-only file. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStopReadOnlyFile diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdStopWithoutFilename.java b/test/jdk/jdk/jfr/jcmd/TestJcmdStopWithoutFilename.java index 3cd7a572427fb..a4a8051937ffb 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdStopWithoutFilename.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdStopWithoutFilename.java @@ -28,7 +28,7 @@ /** * @test * @summary The test verifies JFR.stop - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdStopWithoutFilename diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdView.java b/test/jdk/jdk/jfr/jcmd/TestJcmdView.java index 44db54e785038..92e5c950f9bfb 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdView.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary The test verifies JFR.view command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != false diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdViewMissingData.java b/test/jdk/jdk/jfr/jcmd/TestJcmdViewMissingData.java index 9ba7e9119d923..b7a22b1adcca5 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdViewMissingData.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdViewMissingData.java @@ -30,7 +30,7 @@ /** * @test * @summary The test verifies JFR.view command - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jcmd.TestJcmdViewMissingData diff --git a/test/jdk/jdk/jfr/jmx/TestClone.java b/test/jdk/jdk/jfr/jmx/TestClone.java index 9e1c2d4e9a5fb..586a58a607c88 100644 --- a/test/jdk/jdk/jfr/jmx/TestClone.java +++ b/test/jdk/jdk/jfr/jmx/TestClone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestClone diff --git a/test/jdk/jdk/jfr/jmx/TestCloneRepeat.java b/test/jdk/jdk/jfr/jmx/TestCloneRepeat.java index 61458b676c93e..099aec3b4782f 100644 --- a/test/jdk/jdk/jfr/jmx/TestCloneRepeat.java +++ b/test/jdk/jdk/jfr/jmx/TestCloneRepeat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestCloneRepeat diff --git a/test/jdk/jdk/jfr/jmx/TestConfigurationInfo.java b/test/jdk/jdk/jfr/jmx/TestConfigurationInfo.java index 450caaa93edf7..4b6f786ee6108 100644 --- a/test/jdk/jdk/jfr/jmx/TestConfigurationInfo.java +++ b/test/jdk/jdk/jfr/jmx/TestConfigurationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestConfigurationInfo diff --git a/test/jdk/jdk/jfr/jmx/TestCopyTo.java b/test/jdk/jdk/jfr/jmx/TestCopyTo.java index 3da3e266fca08..6ed7f14547e63 100644 --- a/test/jdk/jdk/jfr/jmx/TestCopyTo.java +++ b/test/jdk/jdk/jfr/jmx/TestCopyTo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestCopyTo diff --git a/test/jdk/jdk/jfr/jmx/TestCopyToInvalidPath.java b/test/jdk/jdk/jfr/jmx/TestCopyToInvalidPath.java index 032e1c3dc9b2c..d868eb4c3dd8a 100644 --- a/test/jdk/jdk/jfr/jmx/TestCopyToInvalidPath.java +++ b/test/jdk/jdk/jfr/jmx/TestCopyToInvalidPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestCopyToInvalidPath diff --git a/test/jdk/jdk/jfr/jmx/TestCopyToReadOnlyDir.java b/test/jdk/jdk/jfr/jmx/TestCopyToReadOnlyDir.java index faaae63fbb27d..c9364f2b43c1b 100644 --- a/test/jdk/jdk/jfr/jmx/TestCopyToReadOnlyDir.java +++ b/test/jdk/jdk/jfr/jmx/TestCopyToReadOnlyDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestCopyToReadOnlyDir diff --git a/test/jdk/jdk/jfr/jmx/TestCopyToRunning.java b/test/jdk/jdk/jfr/jmx/TestCopyToRunning.java index a8afc2110f1f3..82e453057249c 100644 --- a/test/jdk/jdk/jfr/jmx/TestCopyToRunning.java +++ b/test/jdk/jdk/jfr/jmx/TestCopyToRunning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Copy a recording to file while it is running. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/TestEventTypes.java b/test/jdk/jdk/jfr/jmx/TestEventTypes.java index 4f284b399ce66..a7d0219661d95 100644 --- a/test/jdk/jdk/jfr/jmx/TestEventTypes.java +++ b/test/jdk/jdk/jfr/jmx/TestEventTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Verifies that EventTypes from jmx and FlightRecorder are the same. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/TestFlightRecorderMXBeanLeak.java b/test/jdk/jdk/jfr/jmx/TestFlightRecorderMXBeanLeak.java index d2096fde915d1..54f4fa141234f 100644 --- a/test/jdk/jdk/jfr/jmx/TestFlightRecorderMXBeanLeak.java +++ b/test/jdk/jdk/jfr/jmx/TestFlightRecorderMXBeanLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Verifies that attributes in FlightRecorderMXBean can be inspected * without causing a memory leak. * @requires vm.hasJFR diff --git a/test/jdk/jdk/jfr/jmx/TestGetRecordings.java b/test/jdk/jdk/jfr/jmx/TestGetRecordings.java index 339953fcbf451..af930be5f1776 100644 --- a/test/jdk/jdk/jfr/jmx/TestGetRecordings.java +++ b/test/jdk/jdk/jfr/jmx/TestGetRecordings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -Djdk.attach.allowAttachSelf=true -Dcom.sun.management.jmxremote jdk.jfr.jmx.TestGetRecordings diff --git a/test/jdk/jdk/jfr/jmx/TestGetRecordingsMultiple.java b/test/jdk/jdk/jfr/jmx/TestGetRecordingsMultiple.java index cbaaeda98a0a1..8788097228773 100644 --- a/test/jdk/jdk/jfr/jmx/TestGetRecordingsMultiple.java +++ b/test/jdk/jdk/jfr/jmx/TestGetRecordingsMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestGetRecordingsMultiple diff --git a/test/jdk/jdk/jfr/jmx/TestMultipleRecordings.java b/test/jdk/jdk/jfr/jmx/TestMultipleRecordings.java index 4d1619ed30d1f..316a4104db6d7 100644 --- a/test/jdk/jdk/jfr/jmx/TestMultipleRecordings.java +++ b/test/jdk/jdk/jfr/jmx/TestMultipleRecordings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestMultipleRecordings diff --git a/test/jdk/jdk/jfr/jmx/TestNotificationListener.java b/test/jdk/jdk/jfr/jmx/TestNotificationListener.java index 950e5fa6d59c3..a27059a2faee2 100644 --- a/test/jdk/jdk/jfr/jmx/TestNotificationListener.java +++ b/test/jdk/jdk/jfr/jmx/TestNotificationListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestNotificationListener diff --git a/test/jdk/jdk/jfr/jmx/TestPredefinedConfiguration.java b/test/jdk/jdk/jfr/jmx/TestPredefinedConfiguration.java index 6aa6d6bbbbd43..d329ceae73442 100644 --- a/test/jdk/jdk/jfr/jmx/TestPredefinedConfiguration.java +++ b/test/jdk/jdk/jfr/jmx/TestPredefinedConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestPredefinedConfiguration diff --git a/test/jdk/jdk/jfr/jmx/TestPredefinedConfigurationInvalid.java b/test/jdk/jdk/jfr/jmx/TestPredefinedConfigurationInvalid.java index d68bacbcbd07b..32d5f30540c15 100644 --- a/test/jdk/jdk/jfr/jmx/TestPredefinedConfigurationInvalid.java +++ b/test/jdk/jdk/jfr/jmx/TestPredefinedConfigurationInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestPredefinedConfigurationInvalid diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java b/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java index 6cab6b4a2ebcc..8f048ace3c3b7 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestRecordingOptions diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingSettings.java b/test/jdk/jdk/jfr/jmx/TestRecordingSettings.java index 026485e494249..d7c0387e8cf09 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingSettings.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestRecordingSettings diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingSettingsInvalid.java b/test/jdk/jdk/jfr/jmx/TestRecordingSettingsInvalid.java index 669b30cf36be1..a29bd3a61d1fd 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingSettingsInvalid.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingSettingsInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Verify exception when setting invalid settings. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingSettingsMultiple.java b/test/jdk/jdk/jfr/jmx/TestRecordingSettingsMultiple.java index c1ab3d80f380a..c383e1b2fd51f 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingSettingsMultiple.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingSettingsMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestRecordingSettingsMultiple diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingState.java b/test/jdk/jdk/jfr/jmx/TestRecordingState.java index de9b316ef2c4e..05d57f01b4417 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingState.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestRecordingState diff --git a/test/jdk/jdk/jfr/jmx/TestRecordingStateInvalid.java b/test/jdk/jdk/jfr/jmx/TestRecordingStateInvalid.java index 91e5384eb4b18..dbfc6783c5412 100644 --- a/test/jdk/jdk/jfr/jmx/TestRecordingStateInvalid.java +++ b/test/jdk/jdk/jfr/jmx/TestRecordingStateInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestRecordingStateInvalid diff --git a/test/jdk/jdk/jfr/jmx/TestSetConfiguration.java b/test/jdk/jdk/jfr/jmx/TestSetConfiguration.java index e3a6c9addf02a..168633d15208b 100644 --- a/test/jdk/jdk/jfr/jmx/TestSetConfiguration.java +++ b/test/jdk/jdk/jfr/jmx/TestSetConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestSetConfiguration diff --git a/test/jdk/jdk/jfr/jmx/TestSetConfigurationInvalid.java b/test/jdk/jdk/jfr/jmx/TestSetConfigurationInvalid.java index ec5bcffdc9a6c..82c3681b1bf84 100644 --- a/test/jdk/jdk/jfr/jmx/TestSetConfigurationInvalid.java +++ b/test/jdk/jdk/jfr/jmx/TestSetConfigurationInvalid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Verify Exception when setting invalid config. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/TestSnapshot.java b/test/jdk/jdk/jfr/jmx/TestSnapshot.java index b4eb13216b5cb..09cd515c4ae6f 100644 --- a/test/jdk/jdk/jfr/jmx/TestSnapshot.java +++ b/test/jdk/jdk/jfr/jmx/TestSnapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestSnapshot diff --git a/test/jdk/jdk/jfr/jmx/TestStartRecording.java b/test/jdk/jdk/jfr/jmx/TestStartRecording.java index 52a43b1f80eac..1ff3eab6d533e 100644 --- a/test/jdk/jdk/jfr/jmx/TestStartRecording.java +++ b/test/jdk/jdk/jfr/jmx/TestStartRecording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestStartRecording diff --git a/test/jdk/jdk/jfr/jmx/TestStream.java b/test/jdk/jdk/jfr/jmx/TestStream.java index 3763054ae3ba7..53d0ba473b368 100644 --- a/test/jdk/jdk/jfr/jmx/TestStream.java +++ b/test/jdk/jdk/jfr/jmx/TestStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestStream diff --git a/test/jdk/jdk/jfr/jmx/TestStreamClosed.java b/test/jdk/jdk/jfr/jmx/TestStreamClosed.java index 5f6c49544caf9..3533f7c94e75c 100644 --- a/test/jdk/jdk/jfr/jmx/TestStreamClosed.java +++ b/test/jdk/jdk/jfr/jmx/TestStreamClosed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Call readStream() after closeStream() * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/TestStreamMultiple.java b/test/jdk/jdk/jfr/jmx/TestStreamMultiple.java index f973376574abf..85518790b1ffb 100644 --- a/test/jdk/jdk/jfr/jmx/TestStreamMultiple.java +++ b/test/jdk/jdk/jfr/jmx/TestStreamMultiple.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.jmx.TestStreamMultiple diff --git a/test/jdk/jdk/jfr/jmx/TestWrongId.java b/test/jdk/jdk/jfr/jmx/TestWrongId.java index 8a88b970248f0..598a7f05a37f7 100644 --- a/test/jdk/jdk/jfr/jmx/TestWrongId.java +++ b/test/jdk/jdk/jfr/jmx/TestWrongId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Call functions with invalid argument id. Verify Exception. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/info/TestConfigurationInfo.java b/test/jdk/jdk/jfr/jmx/info/TestConfigurationInfo.java index c82f064ae4268..5158d2f7ce132 100644 --- a/test/jdk/jdk/jfr/jmx/info/TestConfigurationInfo.java +++ b/test/jdk/jdk/jfr/jmx/info/TestConfigurationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test for ConfigurationInfo. Compare infos from java API and jmx API. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/info/TestEventTypeInfo.java b/test/jdk/jdk/jfr/jmx/info/TestEventTypeInfo.java index 001147e8e5ccf..79421d6ef563f 100644 --- a/test/jdk/jdk/jfr/jmx/info/TestEventTypeInfo.java +++ b/test/jdk/jdk/jfr/jmx/info/TestEventTypeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test for EventTypeInfo * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/info/TestRecordingInfo.java b/test/jdk/jdk/jfr/jmx/info/TestRecordingInfo.java index a653af76dc0c7..7aaff146f2b02 100644 --- a/test/jdk/jdk/jfr/jmx/info/TestRecordingInfo.java +++ b/test/jdk/jdk/jfr/jmx/info/TestRecordingInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test for RecordingInfo * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/info/TestSettingDescriptorInfo.java b/test/jdk/jdk/jfr/jmx/info/TestSettingDescriptorInfo.java index 59d5aaa5fa99b..fbfaa250351f6 100644 --- a/test/jdk/jdk/jfr/jmx/info/TestSettingDescriptorInfo.java +++ b/test/jdk/jdk/jfr/jmx/info/TestSettingDescriptorInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test for SettingDescriptorInfo. Compare infos from java API and jmx API. * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestClose.java b/test/jdk/jdk/jfr/jmx/streaming/TestClose.java index d742422e69cb8..08c302d6d4b1c 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestClose.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestClose.java @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that a RemoteRecordingStream can be closed * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestDelegated.java b/test/jdk/jdk/jfr/jmx/streaming/TestDelegated.java index 04a9139b12272..e20f92c301415 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestDelegated.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestDelegated.java @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Sanity test methods that delegates to an ordinary stream * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestDumpOrder.java b/test/jdk/jdk/jfr/jmx/streaming/TestDumpOrder.java index 0c6d8fe313d68..7535960366cee 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestDumpOrder.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestDumpOrder.java @@ -42,7 +42,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that chunks arrive in the same order they were committed * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestEnableDisable.java b/test/jdk/jdk/jfr/jmx/streaming/TestEnableDisable.java index 6a07c57ff7879..06e9691cfa216 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestEnableDisable.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestEnableDisable.java @@ -35,7 +35,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that event settings for a RemoteRecordingStream can be changed * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java b/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java index 7bf389c75ad85..b79fbc2bcf04c 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestMaxSize.java @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that max size can be set for a RemoteRecordingStream * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestMetadataEvent.java b/test/jdk/jdk/jfr/jmx/streaming/TestMetadataEvent.java index 935ef292a5590..3e0e8773f0ad6 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestMetadataEvent.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestMetadataEvent.java @@ -36,7 +36,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Sanity tests RemoteRecordingStream::onMetadata * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestMultipleChunks.java b/test/jdk/jdk/jfr/jmx/streaming/TestMultipleChunks.java index e91a58da7b81e..942f64a5da4c3 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestMultipleChunks.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestMultipleChunks.java @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that a RemoteRecordingStream can stream over multiple chunks * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestNew.java b/test/jdk/jdk/jfr/jmx/streaming/TestNew.java index 9cf7a0cd16fc0..d2489730b032b 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestNew.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestNew.java @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Test constructors of RemoteRecordingStream * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestRemoteDump.java b/test/jdk/jdk/jfr/jmx/streaming/TestRemoteDump.java index 51e0c815dc0b7..9390857c09e5a 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestRemoteDump.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestRemoteDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ /** * @test * @summary Tests RecordingStream::dump(Path) - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.jmx.streaming.TestRemoteDump diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestRotate.java b/test/jdk/jdk/jfr/jmx/streaming/TestRotate.java index cf78ea399e760..8a7c7428a99bf 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestRotate.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestRotate.java @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that streaming can work over chunk rotations * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestSetSettings.java b/test/jdk/jdk/jfr/jmx/streaming/TestSetSettings.java index d0a9acab9cdff..2d1cb50dcfc42 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestSetSettings.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestSetSettings.java @@ -37,7 +37,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests that a RemoteRecordingStream can be configured using * setSettings * @requires vm.hasJFR diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestStart.java b/test/jdk/jdk/jfr/jmx/streaming/TestStart.java index 0755e99cb041b..6d4bfc10f81ae 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestStart.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestStart.java @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Sanity tests RemoteRecordingStream::start() * @requires vm.hasJFR * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/jmx/streaming/TestStop.java b/test/jdk/jdk/jfr/jmx/streaming/TestStop.java index 83656cba8a759..572577786a198 100644 --- a/test/jdk/jdk/jfr/jmx/streaming/TestStop.java +++ b/test/jdk/jdk/jfr/jmx/streaming/TestStop.java @@ -40,7 +40,7 @@ /** * @test * @summary Tests RemoteRecordingStream::stop() - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @build jdk.jfr.api.consumer.recordingstream.EventProducer diff --git a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java index d09d3067dafa8..5da979ad6450b 100644 --- a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java +++ b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredFalseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ @Registered(false) public class MyCommitRegisteredFalseEvent extends E implements Runnable { public void myCommit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java index 87014bcd72b48..0af8a8f41ccef 100644 --- a/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java +++ b/test/jdk/jdk/jfr/jvm/MyCommitRegisteredTrueEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ @Registered(true) public class MyCommitRegisteredTrueEvent extends E implements Runnable { public void myCommit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/NonEvent.java b/test/jdk/jdk/jfr/jvm/NonEvent.java index 9134d25c08c98..e98d995acdbff 100644 --- a/test/jdk/jdk/jfr/jvm/NonEvent.java +++ b/test/jdk/jdk/jfr/jvm/NonEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ // Class used by TestGetEventWriter public class NonEvent implements Runnable { public void commit() { - PlaceholderEventWriter ew = PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter ew = PlaceholderEventWriter.getEventWriter();; throw new RuntimeException("Should not reach here " + ew); } diff --git a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java index 8f0c543334757..87cffc5127592 100644 --- a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java +++ b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,4 +30,8 @@ // will be replaced with "jdk.jfr.internal.event.EventWriter" public class PlaceholderEventWriter { + public static PlaceholderEventWriter getEventWriter() { + return null; + } + } diff --git a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java b/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java deleted file mode 100644 index 8083bc16a53ba..0000000000000 --- a/test/jdk/jdk/jfr/jvm/PlaceholderEventWriterFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jfr.jvm; - -// Purpose of this class is to have something to -// statically link against for TestGetEventWriter. -// -// When the class is loaded "jdk.jfr.jvm.PlaceholderEventWriterFactory" -// will be replaced with "jdk.jfr.internal.event.EventWriterFactory" -public class PlaceholderEventWriterFactory { - - public static PlaceholderEventWriter getEventWriter(long value) { - throw new RuntimeException("Test error, PlaceholderEventWriterFactory class should have been replaced with EventWriterFactory"); - } -} diff --git a/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java b/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java index 6174bace86628..d20a045450036 100644 --- a/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java +++ b/test/jdk/jdk/jfr/jvm/RegisteredFalseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ @Registered(false) public class RegisteredFalseEvent extends E { public void commit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } } \ No newline at end of file diff --git a/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java b/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java index 3fe2ce8a1190f..fb2964e68e9f8 100644 --- a/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java +++ b/test/jdk/jdk/jfr/jvm/RegisteredTrueEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ @Registered(true) public class RegisteredTrueEvent extends E { public void commit() { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } } \ No newline at end of file diff --git a/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java b/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java index 6adeb6cb9c51e..8c07c5bf9b6ae 100644 --- a/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java +++ b/test/jdk/jdk/jfr/jvm/StaticCommitEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ public class StaticCommitEvent implements Runnable { int value; public static void commit(long start, long duration, String message, int value) { - PlaceholderEventWriterFactory.getEventWriter(4711L); + PlaceholderEventWriter.getEventWriter(); throw new RuntimeException("Should not reach here"); } diff --git a/test/jdk/jdk/jfr/jvm/TestBeginAndEnd.java b/test/jdk/jdk/jfr/jvm/TestBeginAndEnd.java index c85b0966b6e8f..e25d216ab5fd5 100644 --- a/test/jdk/jdk/jfr/jvm/TestBeginAndEnd.java +++ b/test/jdk/jdk/jfr/jvm/TestBeginAndEnd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test TestBeginAndEnd - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.internal * @run main/othervm jdk.jfr.jvm.TestBeginAndEnd diff --git a/test/jdk/jdk/jfr/jvm/TestChunkIntegrity.java b/test/jdk/jdk/jfr/jvm/TestChunkIntegrity.java index aba19bd37b707..dc66d2617afcd 100644 --- a/test/jdk/jdk/jfr/jvm/TestChunkIntegrity.java +++ b/test/jdk/jdk/jfr/jvm/TestChunkIntegrity.java @@ -56,7 +56,6 @@ /** * @test - * @key jfr * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm/timeout=300 jdk.jfr.jvm.TestChunkIntegrity diff --git a/test/jdk/jdk/jfr/jvm/TestClassId.java b/test/jdk/jdk/jfr/jvm/TestClassId.java index 058183472e846..b82abb64d5022 100644 --- a/test/jdk/jdk/jfr/jvm/TestClassId.java +++ b/test/jdk/jdk/jfr/jvm/TestClassId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test TestClassId - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestClearStaleConstants.java b/test/jdk/jdk/jfr/jvm/TestClearStaleConstants.java index 70e34bcd5140d..81f2a34a6b857 100644 --- a/test/jdk/jdk/jfr/jvm/TestClearStaleConstants.java +++ b/test/jdk/jdk/jfr/jvm/TestClearStaleConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @bug 8231081 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.internal * @library /test/lib /test/jdk @@ -49,7 +49,7 @@ /** * System.gc() will trigger class unloading if -XX:+ExplicitGCInvokesConcurrent is NOT set. * If this flag is set G1 will never unload classes on System.gc() and - * As far as the "jfr" key guarantees no VM flags are set from the outside + * As far as the vm.flagless guarantees no VM flags are set from the outside * it should be enough with System.gc(). */ public final class TestClearStaleConstants { diff --git a/test/jdk/jdk/jfr/jvm/TestCounterTime.java b/test/jdk/jdk/jfr/jvm/TestCounterTime.java index f06fdd0eed676..6cd60eae8945a 100644 --- a/test/jdk/jdk/jfr/jvm/TestCounterTime.java +++ b/test/jdk/jdk/jfr/jvm/TestCounterTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test TestCounterTime - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestCreateNative.java b/test/jdk/jdk/jfr/jvm/TestCreateNative.java index 1050856161d66..9ebbe7891b380 100644 --- a/test/jdk/jdk/jfr/jvm/TestCreateNative.java +++ b/test/jdk/jdk/jfr/jvm/TestCreateNative.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test * @summary Checks that the JVM can rollback on native initialization failures. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java b/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java index 29e21ddd89d7d..a7e620b203c15 100644 --- a/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java +++ b/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Verifies that data associated with a running recording can be evacuated to an hs_err_pidXXX.jfr when the VM crashes * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/jvm/TestEventDuration.java b/test/jdk/jdk/jfr/jvm/TestEventDuration.java index 53a7af9e323cf..1b0a44d843a30 100644 --- a/test/jdk/jdk/jfr/jvm/TestEventDuration.java +++ b/test/jdk/jdk/jfr/jvm/TestEventDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test Tests that the event duration is zero after a chunk rotation - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestEventWriterLog.java b/test/jdk/jdk/jfr/jvm/TestEventWriterLog.java index 9e68d0501dfd9..ca56a3feb416e 100644 --- a/test/jdk/jdk/jfr/jvm/TestEventWriterLog.java +++ b/test/jdk/jdk/jfr/jvm/TestEventWriterLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test TestEventWriterLog * @summary Test that log message of JFR when handle bytecodes - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm TestEventWriterLog diff --git a/test/jdk/jdk/jfr/jvm/TestFatEvent.java b/test/jdk/jdk/jfr/jvm/TestFatEvent.java index 93e8a838de12f..3e10074cce9c7 100644 --- a/test/jdk/jdk/jfr/jvm/TestFatEvent.java +++ b/test/jdk/jdk/jfr/jvm/TestFatEvent.java @@ -36,7 +36,7 @@ /** * @test TestFatEvent - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Dprop1=12345678901234567890123456789012345678901234567890 diff --git a/test/jdk/jdk/jfr/jvm/TestFormatDuration.java b/test/jdk/jdk/jfr/jvm/TestFormatDuration.java index 0fb1bbe07c557..a0d5b729fcfce 100644 --- a/test/jdk/jdk/jfr/jvm/TestFormatDuration.java +++ b/test/jdk/jdk/jfr/jvm/TestFormatDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal.util diff --git a/test/jdk/jdk/jfr/jvm/TestGetAllEventClasses.java b/test/jdk/jdk/jfr/jvm/TestGetAllEventClasses.java index b758520ac81b2..1eeaed48ad050 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetAllEventClasses.java +++ b/test/jdk/jdk/jfr/jvm/TestGetAllEventClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ /** * @test TestGetAllEventClasses - * @key jfr * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java b/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java index 298114b14e14a..a22e59a39fe8c 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java +++ b/test/jdk/jdk/jfr/jvm/TestGetEventWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,14 +39,13 @@ /** * @test id=default - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * * @compile PlaceholderEventWriter.java - * @compile PlaceholderEventWriterFactory.java * @compile E.java * @compile NonEvent.java * @compile RegisteredTrueEvent.java @@ -72,7 +71,7 @@ /** * @test id=jvmci - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.jvmci * @library /test/lib @@ -80,7 +79,6 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * * @compile PlaceholderEventWriter.java - * @compile PlaceholderEventWriterFactory.java * @compile E.java * @compile NonEvent.java * @compile RegisteredTrueEvent.java @@ -105,10 +103,10 @@ public static void main(String... args) throws Throwable { InitializationEvent e = new InitializationEvent(); e.commit(); } - // Make sure EventWriterFactory can be accessed. - Class clazz = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); + // Make sure EventWriter class can be accessed. + Class clazz = Class.forName("jdk.jfr.internal.event.EventWriter"); if (clazz == null) { - throw new Exception("Test error, not able to access jdk.jfr.internal.event.EventWriterFactory class"); + throw new Exception("Test error, not able to access jdk.jfr.internal.event.EventWriter class"); } testRegisteredTrueEvent(); testRegisteredFalseEvent(); @@ -122,7 +120,7 @@ public static void main(String... args) throws Throwable { // The class does not inherit jdk.jfr.Event and, as such, does not implement the // API. It has its own stand-alone "commit()V", which is not an override, that - // attempts to resolve and link against EventWriterFactory. This user implementation + // attempts to resolve and link against EventWriter. This user implementation // is not blessed for linkage. private static void testNonEvent() throws Throwable { Runnable e = newEventObject("NonEvent"); @@ -178,7 +176,7 @@ private static void testRegisteredFalseEvent() throws Throwable { } // The user has implemented another method, "myCommit()V", not an override nor - // overload. that attempts to resolve and link EventWriterFactory. This will fail, + // overload. that attempts to resolve and link EventWriter. This will fail, // because "myCommit()V" is not blessed for linkage. private static void testMyCommitRegisteredTrue() throws Throwable { Runnable e = newEventObject("MyCommitRegisteredTrueEvent"); @@ -230,10 +228,9 @@ static class MethodHandleEvent extends Event { public void myCommit() throws Throwable { try { Class ew = Class.forName("jdk.jfr.internal.event.EventWriter"); - MethodType t = MethodType.methodType(ew, List.of(long.class)); - Class factory = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); - MethodHandle mh = MethodHandles.lookup().findStatic(factory, "getEventWriter", t); - mh.invoke(Long.valueOf(4711)); // throws IllegalAccessException + MethodType t = MethodType.methodType(ew, List.of()); + MethodHandle mh = MethodHandles.lookup().findStatic(ew, "getEventWriter", t); + mh.invoke(); // throws IllegalAccessException } catch (ClassNotFoundException | SecurityException e) { throw new RuntimeException(e); } @@ -262,8 +259,8 @@ static class ReflectionEvent extends Event { public void myCommit() throws Throwable { Class c; try { - c = Class.forName("jdk.jfr.internal.event.EventWriterFactory"); - Method m = c.getMethod("getEventWriter", new Class[] {long.class}); + c = Class.forName("jdk.jfr.internal.event.EventWriter"); + Method m = c.getMethod("getEventWriter", new Class[0]); m.invoke(null, Long.valueOf(4711)); // throws InternalError } catch (ClassNotFoundException | SecurityException e) { throw new RuntimeException(e); @@ -283,7 +280,7 @@ private static void testReflectionEvent() throws Throwable { } catch (InternalError ie) { if (ie.getCause() instanceof IllegalAccessException iaex) { if (iaex.getCause() instanceof IllegalAccessError iae) { - if (iae.getMessage().contains("getEventWriter(long)")) { + if (iae.getMessage().contains("getEventWriter()")) { // OK, as expected return; } @@ -345,7 +342,6 @@ private static T newEventObject(String name) throws Throwable { byte[] bytes = is.readAllBytes(); is.close(); bytes = replace(bytes, "jdk/jfr/jvm/E", "jdk/jfr/Event"); - bytes = replace(bytes, "jdk/jfr/jvm/PlaceholderEventWriterFactory", "jdk/jfr/internal/event/EventWriterFactory"); bytes = replace(bytes, "jdk/jfr/jvm/PlaceholderEventWriter", "jdk/jfr/internal/event/EventWriter"); BytesClassLoader bc = new BytesClassLoader(bytes, fullName); Class clazz = bc.loadClass(fullName); @@ -372,7 +368,7 @@ private static void maybeCheckJVMCI(Class eventClass, String commitName) thro } /** - * Checks that JVMCI prevents unblessed access to {@code EventWriterFactory.getEventWriter(long)}. + * Checks that JVMCI prevents unblessed access to {@code EventWriter.getEventWriter()}. */ private static void checkJVMCI(Class eventClass, String commitName) throws Throwable { MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); @@ -380,7 +376,7 @@ private static void checkJVMCI(Class eventClass, String commitName) throws Th ConstantPool cp = commit.getConstantPool(); // Search for first INVOKESTATIC instruction in commit method which is expected - // to be the call to jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long). + // to be the call to jdk.jfr.internal.event.EventWriter.getEventWriter(). final int INVOKESTATIC = 184; byte[] code = commit.getCode(); for (int bci = 0; bci < code.length; bci++) { diff --git a/test/jdk/jdk/jfr/jvm/TestGetEventWriterPackage.java b/test/jdk/jdk/jfr/jvm/TestGetEventWriterPackage.java index 065458d4ac778..3d96330f6ac2f 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetEventWriterPackage.java +++ b/test/jdk/jdk/jfr/jvm/TestGetEventWriterPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ import jdk.jfr.Registered; /** * @test Tests that a module can't execute code in jdk.jfr.internal.event unless an event has been registered. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm diff --git a/test/jdk/jdk/jfr/jvm/TestGetEventWriterReflection.java b/test/jdk/jdk/jfr/jvm/TestGetEventWriterReflection.java index 2e0f87020e680..dae4e9a67b5a3 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetEventWriterReflection.java +++ b/test/jdk/jdk/jfr/jvm/TestGetEventWriterReflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ import jdk.jfr.Registered; /** * @test Tests that reflective access works as (normally) expected - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/jvm/TestGetStackTraceId.java b/test/jdk/jdk/jfr/jvm/TestGetStackTraceId.java index 8a23e55140886..637a5f3920d36 100644 --- a/test/jdk/jdk/jfr/jvm/TestGetStackTraceId.java +++ b/test/jdk/jdk/jfr/jvm/TestGetStackTraceId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test TestGetStackTraceId - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestHiddenWait.java b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java index b064285329c0f..aaefc60527ce2 100644 --- a/test/jdk/jdk/jfr/jvm/TestHiddenWait.java +++ b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java @@ -38,7 +38,7 @@ /** * @test TestHiddenWait - * @key jfr + * @requires vm.flagless * @summary Checks that JFR code don't emit noise in the form of ThreadSleep and JavaMonitorWait events. * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/jvm/TestJFRIntrinsic.java b/test/jdk/jdk/jfr/jvm/TestJFRIntrinsic.java index 6d3ea8d015a89..75ed0d14ca508 100644 --- a/test/jdk/jdk/jfr/jvm/TestJFRIntrinsic.java +++ b/test/jdk/jdk/jfr/jvm/TestJFRIntrinsic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ /** * @test * @summary Intrinsic for JFR - * @key jfr * @requires vm.hasJFR * @library /test/lib * diff --git a/test/jdk/jdk/jfr/jvm/TestJavaEvent.java b/test/jdk/jdk/jfr/jvm/TestJavaEvent.java index 0a2f2ecaf5b61..8a006dd9eafd9 100644 --- a/test/jdk/jdk/jfr/jvm/TestJavaEvent.java +++ b/test/jdk/jdk/jfr/jvm/TestJavaEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ /** * @test TestGetThreadId - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent512k.java b/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent512k.java index eacffb7a13b29..530004d3ebddc 100644 --- a/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent512k.java +++ b/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent512k.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test TestLargeJavaEvent512k - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent64k.java b/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent64k.java index 0de03efb35c59..b71ed0ec36130 100644 --- a/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent64k.java +++ b/test/jdk/jdk/jfr/jvm/TestLargeJavaEvent64k.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test TestLargeJavaEvent64k - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestLogImplementation.java b/test/jdk/jdk/jfr/jvm/TestLogImplementation.java index d9d42074b7b98..faa7bc18a3c8b 100644 --- a/test/jdk/jdk/jfr/jvm/TestLogImplementation.java +++ b/test/jdk/jdk/jfr/jvm/TestLogImplementation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test TestLogImplementation - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestLogOutput.java b/test/jdk/jdk/jfr/jvm/TestLogOutput.java index 18527abb90b01..5580270027a4d 100644 --- a/test/jdk/jdk/jfr/jvm/TestLogOutput.java +++ b/test/jdk/jdk/jfr/jvm/TestLogOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * @test TestLogOutput - * @key jfr + * @requires vm.flagless * @summary Sanity test jfr logging output * @requires vm.hasJFR * @library /test/lib diff --git a/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java b/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java index 8ce3fd3859fdb..45b66d508cda1 100644 --- a/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java +++ b/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java @@ -36,7 +36,7 @@ /** * @test * @summary Verify that duplicate longer strings doesn't take up unneccessary space - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.jvm.TestLongStringsInPool diff --git a/test/jdk/jdk/jfr/jvm/TestModularImage.java b/test/jdk/jdk/jfr/jvm/TestModularImage.java index 0f10150af601a..fe49b460f188e 100644 --- a/test/jdk/jdk/jfr/jvm/TestModularImage.java +++ b/test/jdk/jdk/jfr/jvm/TestModularImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,12 +38,18 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Checks that a JDK image with and without the jdk.jfr module behaves * as expected * @requires vm.hasJFR * @library /test/lib - * @run driver jdk.jfr.jvm.TestModularImage + * @modules jdk.compiler jdk.jlink + * @comment Test is being run in othervm to support JEP 493 enabled + * JDKs which don't allow patched modules. Note that jtreg patches + * module java.base to add java.lang.JTRegModuleHelper. If then a + * jlink run is attempted in-process - using the ToolProvider API - + * on a JEP 493 enabled JDK, the test fails. + * @run main/othervm jdk.jfr.jvm.TestModularImage */ public class TestModularImage { private static final String STARTED_RECORDING = "Started recording"; diff --git a/test/jdk/jdk/jfr/jvm/TestPid.java b/test/jdk/jdk/jfr/jvm/TestPid.java index 20a8b42f8a54c..f71042d1c847f 100644 --- a/test/jdk/jdk/jfr/jvm/TestPid.java +++ b/test/jdk/jdk/jfr/jvm/TestPid.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test TestPid - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestPrimitiveClasses.java b/test/jdk/jdk/jfr/jvm/TestPrimitiveClasses.java index bb0163bc925f0..548bb3fc19e44 100644 --- a/test/jdk/jdk/jfr/jvm/TestPrimitiveClasses.java +++ b/test/jdk/jdk/jfr/jvm/TestPrimitiveClasses.java @@ -34,7 +34,7 @@ /** * @test TestPrimitiveClasses - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.jvm.TestPrimitiveClasses diff --git a/test/jdk/jdk/jfr/jvm/TestThreadExclusion.java b/test/jdk/jdk/jfr/jvm/TestThreadExclusion.java index 411710881cad4..000923d26785b 100644 --- a/test/jdk/jdk/jfr/jvm/TestThreadExclusion.java +++ b/test/jdk/jdk/jfr/jvm/TestThreadExclusion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestUnloadEventClassCount.java b/test/jdk/jdk/jfr/jvm/TestUnloadEventClassCount.java index ddb7ec3c757a7..23b45f0b5f728 100644 --- a/test/jdk/jdk/jfr/jvm/TestUnloadEventClassCount.java +++ b/test/jdk/jdk/jfr/jvm/TestUnloadEventClassCount.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Unit test for JVM#getUnloadedEventClassCount * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/jvm/TestUnsupportedVM.java b/test/jdk/jdk/jfr/jvm/TestUnsupportedVM.java index 81a83222c75f9..a3dbeef6d5c9b 100644 --- a/test/jdk/jdk/jfr/jvm/TestUnsupportedVM.java +++ b/test/jdk/jdk/jfr/jvm/TestUnsupportedVM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ /** * @test TestUnsupportedVM - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @modules jdk.jfr diff --git a/test/jdk/jdk/jfr/jvm/TestVerifyInstrumentation.java b/test/jdk/jdk/jfr/jvm/TestVerifyInstrumentation.java index e003a4b3e4849..ec9e64972ec3c 100644 --- a/test/jdk/jdk/jfr/jvm/TestVerifyInstrumentation.java +++ b/test/jdk/jdk/jfr/jvm/TestVerifyInstrumentation.java @@ -29,7 +29,7 @@ /** * @test * @bug 8316271 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -Xverify:all jdk.jfr.jvm.TestVerifyInstrumentation diff --git a/test/jdk/jdk/jfr/jvm/TestVirtualThreadExclusion.java b/test/jdk/jdk/jfr/jvm/TestVirtualThreadExclusion.java index e7a4713c223fc..c2a820aaf9ad1 100644 --- a/test/jdk/jdk/jfr/jvm/TestVirtualThreadExclusion.java +++ b/test/jdk/jdk/jfr/jvm/TestVirtualThreadExclusion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/jvm/TestWaste.java b/test/jdk/jdk/jfr/jvm/TestWaste.java index afa2dda4ee12c..c755ca4c3d02d 100644 --- a/test/jdk/jdk/jfr/jvm/TestWaste.java +++ b/test/jdk/jdk/jfr/jvm/TestWaste.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test diff --git a/test/jdk/jdk/jfr/startupargs/TestBadOptionValues.java b/test/jdk/jdk/jfr/startupargs/TestBadOptionValues.java index 50514e0202441..bae1dcd08cbe6 100644 --- a/test/jdk/jdk/jfr/startupargs/TestBadOptionValues.java +++ b/test/jdk/jdk/jfr/startupargs/TestBadOptionValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @library /test/lib diff --git a/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java b/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java index bca93044fc906..66b27e5978d2f 100644 --- a/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java +++ b/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ /** * @test * @summary Start a FlightRecording with dumponexit. Verify dump exists. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.startupargs.TestDumpOnExit diff --git a/test/jdk/jdk/jfr/startupargs/TestEventSettings.java b/test/jdk/jdk/jfr/startupargs/TestEventSettings.java index 41e59523339c4..37af394affdfe 100644 --- a/test/jdk/jdk/jfr/startupargs/TestEventSettings.java +++ b/test/jdk/jdk/jfr/startupargs/TestEventSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Start a recording with custom settings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java b/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java index 83c4d07c23bb7..25beb590879f4 100644 --- a/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java +++ b/test/jdk/jdk/jfr/startupargs/TestFlushInterval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Start a recording with a flush interval - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/startupargs/TestJFCWarnings.java b/test/jdk/jdk/jfr/startupargs/TestJFCWarnings.java index cf0cb0212169b..092ec73546f21 100644 --- a/test/jdk/jdk/jfr/startupargs/TestJFCWarnings.java +++ b/test/jdk/jdk/jfr/startupargs/TestJFCWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test * @summary Start a recording with custom settings - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java b/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java index 9c90d04691ab1..6827c663ee37b 100644 --- a/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java +++ b/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java b/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java index 24be874a87f60..c70f98105689e 100644 --- a/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java +++ b/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * * @library /test/lib diff --git a/test/jdk/jdk/jfr/startupargs/TestOldObjectQueueSize.java b/test/jdk/jdk/jfr/startupargs/TestOldObjectQueueSize.java index 0613906aface7..f85baed6f9003 100644 --- a/test/jdk/jdk/jfr/startupargs/TestOldObjectQueueSize.java +++ b/test/jdk/jdk/jfr/startupargs/TestOldObjectQueueSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @requires vm.hasJFR * @modules jdk.jfr/jdk.jfr.internal.test * @library /test/lib - * @key jfr + * @requires vm.flagless * * @run main/othervm -XX:TLABSize=2k -XX:FlightRecorderOptions:old-object-queue-size=0 jdk.jfr.startupargs.TestOldObjectQueueSize off * @run main/othervm -XX:TLABSize=2k -Xlog:gc+tlab=trace -XX:FlightRecorderOptions:old-object-queue-size=10000 jdk.jfr.startupargs.TestOldObjectQueueSize many diff --git a/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java b/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java index 3a4d3f207326a..27c1533ca3b2c 100644 --- a/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java +++ b/test/jdk/jdk/jfr/startupargs/TestOptionsWithLocale.java @@ -12,7 +12,7 @@ * @test * @summary Checks that locale is respected when using -XX:FlightRecorderOptions * See JDK-8244508 - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr * @library /test/lib diff --git a/test/jdk/jdk/jfr/startupargs/TestPreserveRepository.java b/test/jdk/jdk/jfr/startupargs/TestPreserveRepository.java index 4f4ee195e1fae..74023639f47c8 100644 --- a/test/jdk/jdk/jfr/startupargs/TestPreserveRepository.java +++ b/test/jdk/jdk/jfr/startupargs/TestPreserveRepository.java @@ -31,7 +31,7 @@ /** * @test * @summary Tests that -XX:FlightRecorderOptions:preserve-repository works - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @modules jdk.jfr * @library /test/lib diff --git a/test/jdk/jdk/jfr/startupargs/TestRepositoryPath.java b/test/jdk/jdk/jfr/startupargs/TestRepositoryPath.java index a5052b42d6d93..fcddff8aca471 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRepositoryPath.java +++ b/test/jdk/jdk/jfr/startupargs/TestRepositoryPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Set repository path. Verify recording created in repo. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=TestStartRecording,settings=profile -XX:FlightRecorderOptions:repository=./repo jdk.jfr.startupargs.TestRepositoryPath diff --git a/test/jdk/jdk/jfr/startupargs/TestRepositoryPathLong.java b/test/jdk/jdk/jfr/startupargs/TestRepositoryPathLong.java index 4dda1ab23d2e1..73bc600d782b3 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRepositoryPathLong.java +++ b/test/jdk/jdk/jfr/startupargs/TestRepositoryPathLong.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Set repository path. Verify recording created in repo. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=myrec,settings=profile -XX:FlightRecorderOptions:repository=./subdirectory/subdirectory1/subdirectory2/subdirectory3/subdirectory4/subdirectory5/subdirectory6/subdirectory7/subdirectory8/subdirectory9/subdirectory10/subdirectory11/subdirectory12/subdirectory13/subdirectory14/subdirectory15 jdk.jfr.startupargs.TestRepositoryPathLong diff --git a/test/jdk/jdk/jfr/startupargs/TestRetransform.java b/test/jdk/jdk/jfr/startupargs/TestRetransform.java index 2e4067ae5441d..5d26a4bb0a98b 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRetransform.java +++ b/test/jdk/jdk/jfr/startupargs/TestRetransform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm -XX:FlightRecorderOptions:retransform=false jdk.jfr.startupargs.TestRetransform diff --git a/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java b/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java index 186a87a12c2d2..02636e4b715d1 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java +++ b/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.startupargs.TestRetransformUsingLog diff --git a/test/jdk/jdk/jfr/startupargs/TestStartDelay.java b/test/jdk/jdk/jfr/startupargs/TestStartDelay.java index 7036e373a416c..5470ae7936ee8 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartDelay.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartDelay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ /** * @test * @summary Start a recording with delay. Verify recording starts later. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=TestStartDelay,delay=5000s jdk.jfr.startupargs.TestStartDelay diff --git a/test/jdk/jdk/jfr/startupargs/TestStartDelayRunning.java b/test/jdk/jdk/jfr/startupargs/TestStartDelayRunning.java index b74714b9bdd6c..b7563c35c3670 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartDelayRunning.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartDelayRunning.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Verify that a recopding with a delay is started. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=TestStartDelay,delay=1s jdk.jfr.startupargs.TestStartDelayRunning diff --git a/test/jdk/jdk/jfr/startupargs/TestStartDuration.java b/test/jdk/jdk/jfr/startupargs/TestStartDuration.java index d9697492d94fb..fcc2f4abdd571 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartDuration.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartDuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ /** * @test * @summary Start a recording with duration. Verify recording stops. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires vm.flagless * @library /test/lib /test/jdk diff --git a/test/jdk/jdk/jfr/startupargs/TestStartHelp.java b/test/jdk/jdk/jfr/startupargs/TestStartHelp.java index 4d4edbf68dc36..0b3b5869cad5b 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartHelp.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartHelp.java @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main jdk.jfr.startupargs.TestStartHelp diff --git a/test/jdk/jdk/jfr/startupargs/TestStartMaxAgeSize.java b/test/jdk/jdk/jfr/startupargs/TestStartMaxAgeSize.java index 95a6b436ddb26..df9af580b401b 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartMaxAgeSize.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartMaxAgeSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Start a recording with delay. Verify recording starts later. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=TestStartMaxAgeSize,maxage=10s,maxsize=1000000 jdk.jfr.startupargs.TestStartMaxAgeSize diff --git a/test/jdk/jdk/jfr/startupargs/TestStartName.java b/test/jdk/jdk/jfr/startupargs/TestStartName.java index 7ab4a7d0f7e98..7dd11125f8f49 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartName.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main jdk.jfr.startupargs.TestStartName diff --git a/test/jdk/jdk/jfr/startupargs/TestStartNoSettings.java b/test/jdk/jdk/jfr/startupargs/TestStartNoSettings.java index ac5f5efa5c195..61188f224e0c0 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartNoSettings.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartNoSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Start a FlightRecording without any settings (not even default). - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.startupargs.TestStartNoSettings diff --git a/test/jdk/jdk/jfr/startupargs/TestStartRecording.java b/test/jdk/jdk/jfr/startupargs/TestStartRecording.java index 7eb24cc8fa69e..6b3239951c7f3 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartRecording.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartRecording.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Start a recording with -XX:StartFlightRecording. Dump recording with jcmd. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm -XX:StartFlightRecording:name=TestStartRecording,settings=profile jdk.jfr.startupargs.TestStartRecording diff --git a/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java b/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java index b919f80e9da0c..4a934ebb36da3 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartupMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main jdk.jfr.startupargs.TestStartupMessage diff --git a/test/jdk/jdk/jfr/startupargs/TestStartupOptionSpecifiedOnce.java b/test/jdk/jdk/jfr/startupargs/TestStartupOptionSpecifiedOnce.java index 756402b0c607f..11749504eba0c 100644 --- a/test/jdk/jdk/jfr/startupargs/TestStartupOptionSpecifiedOnce.java +++ b/test/jdk/jdk/jfr/startupargs/TestStartupOptionSpecifiedOnce.java @@ -26,7 +26,7 @@ /** * @test The test verifies that options can only be specified once with --XX:StartFlightRecording - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main jdk.jfr.startupargs.TestStartupOptionSpecifiedOnce diff --git a/test/jdk/jdk/jfr/threading/TestDeepVirtualStackTrace.java b/test/jdk/jdk/jfr/threading/TestDeepVirtualStackTrace.java index 3fecd91ea62c2..2be7262600639 100644 --- a/test/jdk/jdk/jfr/threading/TestDeepVirtualStackTrace.java +++ b/test/jdk/jdk/jfr/threading/TestDeepVirtualStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @test * @summary Tests emitting an event, both in Java and native, in a virtual * thread with the maximum number of allowed stack frames for JFR - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java b/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java index f0c3b52cf144c..de0b279eb4970 100644 --- a/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java +++ b/test/jdk/jdk/jfr/threading/TestManyVirtualThreads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,6 @@ /** * @test * @summary Tests starting virtual threads from a set of ordinary threads - * @key jfr * @requires vm.hasJFR & vm.continuations * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/threading/TestNestedVirtualThreads.java b/test/jdk/jdk/jfr/threading/TestNestedVirtualThreads.java index 26be901804a50..15901be949049 100644 --- a/test/jdk/jdk/jfr/threading/TestNestedVirtualThreads.java +++ b/test/jdk/jdk/jfr/threading/TestNestedVirtualThreads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @test * @summary Tests committing an event in a virtual thread created by a virtual * thread - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal diff --git a/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java b/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java index 0dc1ef8566139..ef2a3698edcac 100644 --- a/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java +++ b/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java @@ -41,7 +41,7 @@ * @test * @bug 8338417 * @summary Tests pinning of virtual threads when the JFR string pool monitor is contended. - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR & vm.continuations * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.threading.TestStringPoolVirtualThreadPinning diff --git a/test/jdk/jdk/jfr/tool/TestAssemble.java b/test/jdk/jdk/jfr/tool/TestAssemble.java index ccc95498de437..43c862d8999ae 100644 --- a/test/jdk/jdk/jfr/tool/TestAssemble.java +++ b/test/jdk/jdk/jfr/tool/TestAssemble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,13 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordingFile; import jdk.jfr.internal.Repository; -import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; /** * @test * @summary Test jfr reconstruct - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal @@ -80,7 +79,7 @@ public static void main(String[] args) throws Throwable { expectedCount += countEventInRecording(tmp); } - SafePath repository = Repository.getRepository().getRepositoryPath(); + Path repository = Repository.getRepository().getRepositoryPath(); Path destinationPath = Paths.get("reconstructed.jfr"); String directory = repository.toString(); diff --git a/test/jdk/jdk/jfr/tool/TestConfigure.java b/test/jdk/jdk/jfr/tool/TestConfigure.java index 90f6f39be00be..e200054319eaa 100644 --- a/test/jdk/jdk/jfr/tool/TestConfigure.java +++ b/test/jdk/jdk/jfr/tool/TestConfigure.java @@ -34,7 +34,7 @@ /** * @test * @summary Test jfr configure - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestConfigure diff --git a/test/jdk/jdk/jfr/tool/TestDisassemble.java b/test/jdk/jdk/jfr/tool/TestDisassemble.java index da7f9489665bf..68088fdc5bb90 100644 --- a/test/jdk/jdk/jfr/tool/TestDisassemble.java +++ b/test/jdk/jdk/jfr/tool/TestDisassemble.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @test * @bug 8253050 * @summary Test jfr split - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestDisassemble diff --git a/test/jdk/jdk/jfr/tool/TestHelp.java b/test/jdk/jdk/jfr/tool/TestHelp.java index 91bd7d82a2bed..b0113fca5bf91 100644 --- a/test/jdk/jdk/jfr/tool/TestHelp.java +++ b/test/jdk/jdk/jfr/tool/TestHelp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ /** * @test * @summary Test help - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestHelp diff --git a/test/jdk/jdk/jfr/tool/TestMetadata.java b/test/jdk/jdk/jfr/tool/TestMetadata.java index c321f4e3fe66a..76afc110f5d62 100644 --- a/test/jdk/jdk/jfr/tool/TestMetadata.java +++ b/test/jdk/jdk/jfr/tool/TestMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test * @summary Test jfr info - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestMetadata diff --git a/test/jdk/jdk/jfr/tool/TestPrint.java b/test/jdk/jdk/jfr/tool/TestPrint.java index 6f7e89f83552b..fcedca3bcb9de 100644 --- a/test/jdk/jdk/jfr/tool/TestPrint.java +++ b/test/jdk/jdk/jfr/tool/TestPrint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * @test * @summary Test jfr print - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestPrint diff --git a/test/jdk/jdk/jfr/tool/TestPrintDefault.java b/test/jdk/jdk/jfr/tool/TestPrintDefault.java index 215845e6c990c..8dd04c61e047d 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintDefault.java +++ b/test/jdk/jdk/jfr/tool/TestPrintDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests print --json * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/tool/TestPrintJSON.java b/test/jdk/jdk/jfr/tool/TestPrintJSON.java index 6a8977a672e66..3d79c75300f35 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintJSON.java +++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests print --json * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/tool/TestPrintXML.java b/test/jdk/jdk/jfr/tool/TestPrintXML.java index c8d60166d4c89..2c1c4a518e2b6 100644 --- a/test/jdk/jdk/jfr/tool/TestPrintXML.java +++ b/test/jdk/jdk/jfr/tool/TestPrintXML.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ /** * @test - * @key jfr + * @requires vm.flagless * @summary Tests print --xml * @requires vm.hasJFR * diff --git a/test/jdk/jdk/jfr/tool/TestScrub.java b/test/jdk/jdk/jfr/tool/TestScrub.java index ba02f7d31268c..43b9fca7ee4c0 100644 --- a/test/jdk/jdk/jfr/tool/TestScrub.java +++ b/test/jdk/jdk/jfr/tool/TestScrub.java @@ -40,7 +40,7 @@ /** * @test * @summary Test jfr scrub - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestScrub diff --git a/test/jdk/jdk/jfr/tool/TestSummary.java b/test/jdk/jdk/jfr/tool/TestSummary.java index 641d951f63ca2..550de0c081144 100644 --- a/test/jdk/jdk/jfr/tool/TestSummary.java +++ b/test/jdk/jdk/jfr/tool/TestSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * @test * @summary Test jfr info - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @library /test/lib /test/jdk * @run main/othervm jdk.jfr.tool.TestSummary diff --git a/test/jdk/jdk/jfr/tool/TestView.java b/test/jdk/jdk/jfr/tool/TestView.java index 89c74133286f9..89c45c3e06862 100644 --- a/test/jdk/jdk/jfr/tool/TestView.java +++ b/test/jdk/jdk/jfr/tool/TestView.java @@ -31,7 +31,7 @@ /** * @test * @summary Test jfr view - * @key jfr + * @requires vm.flagless * @requires vm.hasJFR * @requires (vm.gc == "G1" | vm.gc == null) * & vm.opt.ExplicitGCInvokesConcurrent != false diff --git a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java index 4718e10e8629d..551e3792fc236 100644 --- a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java +++ b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,8 @@ static void check(ModuleDescriptor md) { "jdk.internal.vm.ci/jdk.vm.ci.hotspot", "jdk.internal.vm.ci/jdk.vm.ci.meta", "jdk.internal.vm.ci/jdk.vm.ci.code", - "java.base/jdk.internal.javac"); + "java.base/jdk.internal.javac", + "java.base/jdk.internal.misc"); static void checkExports(ModuleDescriptor md) { // build a map of upgradeable module to Exports that are qualified to it diff --git a/test/jdk/sun/nio/cs/Test6392804.java b/test/jdk/sun/nio/cs/Test6392804.java index a89c2aa533321..a98428c3e7fb7 100644 --- a/test/jdk/sun/nio/cs/Test6392804.java +++ b/test/jdk/sun/nio/cs/Test6392804.java @@ -22,6 +22,7 @@ */ /* + @test @bug 6392804 @summary Decoder fails to detect decoding error */ diff --git a/test/jdk/sun/nio/cs/TestUTF_32.java b/test/jdk/sun/nio/cs/TestUTF_32.java index 3179768957e5d..ba042494fd2ae 100644 --- a/test/jdk/sun/nio/cs/TestUTF_32.java +++ b/test/jdk/sun/nio/cs/TestUTF_32.java @@ -22,6 +22,7 @@ */ /* + @test @bug 6346419 @summary Check correctness of the UTF-32 and its variant charsets */ diff --git a/test/jdk/sun/security/ec/ECDHPrimitive.java b/test/jdk/sun/security/ec/ECDHPrimitive.java index b41b93bc5ff7f..3ed0a9d34a301 100644 --- a/test/jdk/sun/security/ec/ECDHPrimitive.java +++ b/test/jdk/sun/security/ec/ECDHPrimitive.java @@ -118,7 +118,7 @@ private static void runTest(ECParameterSpec ecParams, byte[] secret = ka.generateSecret(); byte[] expectedSecret = values.get("ZIUT"); - Asserts.assertEqualsByteArray(secret, expectedSecret, "Incorrect secret value"); + Asserts.assertEqualsByteArray(expectedSecret, secret, "Incorrect secret value"); int testIndex = values.get("COUNT")[0]; System.out.println("Test " + testIndex + " passed."); } @@ -141,4 +141,4 @@ private static void addKeyValue(String line, Map values) { private static String lookupName(String name) { return NAME_MAP.get(name); } -} \ No newline at end of file +} diff --git a/test/jdk/sun/security/ec/TestEC.java b/test/jdk/sun/security/ec/TestEC.java index 8b7f4618d54d6..8e962812e2849 100644 --- a/test/jdk/sun/security/ec/TestEC.java +++ b/test/jdk/sun/security/ec/TestEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ * @library ../pkcs11 * @library ../pkcs11/ec * @library ../pkcs11/sslecc - * @library ../../../java/security/testlibrary * @library ../../../javax/net/ssl/TLSCommon * @modules jdk.crypto.cryptoki/sun.security.pkcs11.wrapper * @run main/othervm -Djdk.tls.namedGroups="secp256r1" TestEC @@ -43,6 +42,7 @@ import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; +import jdk.test.lib.security.ProvidersSnapshot; /* * Leverage the collection of EC tests used by PKCS11 diff --git a/test/jdk/sun/security/krb5/auto/SaslBasic.java b/test/jdk/sun/security/krb5/auto/SaslBasic.java index 0aebdefbe04af..89eb22383f272 100644 --- a/test/jdk/sun/security/krb5/auto/SaslBasic.java +++ b/test/jdk/sun/security/krb5/auto/SaslBasic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,11 @@ * @run main/othervm -Djdk.net.hosts.file=TestHosts SaslBasic unbound auth-conf * @run main/othervm -Djdk.net.hosts.file=TestHosts SaslBasic bound auth */ -import java.io.IOException; +import static jdk.test.lib.Asserts.assertEquals; + import java.util.Arrays; import java.util.HashMap; import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.*; // The basic krb5 test skeleton you can copy from @@ -61,15 +60,12 @@ public static void main(String[] args) throws Exception { srvprops.put(Sasl.QOP, "auth,auth-int,auth-conf"); SaslServer ss = Sasl.createSaslServer("GSSAPI", "server", bound? name: null, srvprops, - new CallbackHandler() { - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException { - for (Callback cb : callbacks) { - if (cb instanceof RealmCallback) { - ((RealmCallback) cb).setText(OneKDC.REALM); - } else if (cb instanceof AuthorizeCallback) { - ((AuthorizeCallback) cb).setAuthorized(true); - } + callbacks -> { + for (Callback cb : callbacks) { + if (cb instanceof RealmCallback) { + ((RealmCallback) cb).setText(OneKDC.REALM); + } else if (cb instanceof AuthorizeCallback) { + ((AuthorizeCallback) cb).setAuthorized(true); } } }); @@ -89,28 +85,85 @@ public void handle(Callback[] callbacks) String boundName = (String)ss.getNegotiatedProperty( Sasl.BOUND_SERVER_NAME); if (!boundName.equals(name)) { - throw new Exception("Wrong bound server name"); + throw new RuntimeException("Wrong bound server name"); } } Object key = ss.getNegotiatedProperty( "com.sun.security.jgss.inquiretype.krb5_get_session_key"); if (key == null) { - throw new Exception("Extended negotiated property not read"); + throw new RuntimeException("Extended negotiated property not read"); } if (args[1].equals("auth")) { // 8170732. These are the maximum size bytes after jgss/krb5 wrap. if (lastClientToken[17] != 0 || lastClientToken[18] != 0 || lastClientToken[19] != 0) { - throw new Exception("maximum size for auth must be 0"); + throw new RuntimeException("maximum size for auth must be 0"); } + testWrapUnwrapNoSecLayer(sc, ss); } else { - byte[] hello = "hello".getBytes(); - token = sc.wrap(hello, 0, hello.length); - token = ss.unwrap(token, 0, token.length); - if (!Arrays.equals(hello, token)) { - throw new Exception("Message altered"); - } + testWrapUnwrapWithSecLayer(sc, ss); + } + } + + private static void testWrapUnwrapWithSecLayer(SaslClient sc, SaslServer ss) + throws SaslException { + byte[] token; + byte[] hello = "hello".getBytes(); + + // test client wrap and server unwrap + token = sc.wrap(hello, 0, hello.length); + token = ss.unwrap(token, 0, token.length); + + if (!Arrays.equals(hello, token)) { + throw new RuntimeException("Client message altered"); + } + + // test server wrap and client unwrap + token = ss.wrap(hello, 0, hello.length); + token = sc.unwrap(token, 0, token.length); + + if (!Arrays.equals(hello, token)) { + throw new RuntimeException("Server message altered"); + } + } + + private static void testWrapUnwrapNoSecLayer(SaslClient sc, SaslServer ss) + throws SaslException { + byte[] clntBuf = new byte[]{0, 1, 2, 3}; + byte[] srvBuf = new byte[]{10, 11, 12, 13}; + String expectedError = "No security layer negotiated"; + + try { + sc.wrap(clntBuf, 0, clntBuf.length); + throw new RuntimeException( + "client wrap should not be allowed w/no security layer"); + } catch (IllegalStateException e) { + assertEquals(expectedError, e.getMessage()); + } + + try { + ss.wrap(srvBuf, 0, srvBuf.length); + throw new RuntimeException( + "server wrap should not be allowed w/no security layer"); + } catch (IllegalStateException e) { + assertEquals(expectedError, e.getMessage()); + } + + try { + sc.unwrap(clntBuf, 0, clntBuf.length); + throw new RuntimeException( + "client unwrap should not be allowed w/no security layer"); + } catch (IllegalStateException e) { + assertEquals(expectedError, e.getMessage()); + } + + try { + ss.unwrap(srvBuf, 0, srvBuf.length); + throw new RuntimeException( + "server unwrap should not be allowed w/no security layer"); + } catch (IllegalStateException e) { + assertEquals(expectedError, e.getMessage()); } } } diff --git a/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java b/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java index b78ade34eae3d..9384ac4b1311b 100644 --- a/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java +++ b/test/jdk/sun/security/mscapi/nonUniqueAliases/NonUniqueAliases.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,20 +27,32 @@ * @requires os.family == "windows" * @library /test/lib * @summary Test "keytool -list" displays correctly same named certificates - * @ignore Uses certutil.exe that isn't guaranteed to be installed */ import jdk.test.lib.process.ProcessTools; +import java.io.IOException; import java.security.KeyStore; import java.util.Collections; +import jtreg.SkippedException; public class NonUniqueAliases { public static void main(String[] args) throws Throwable { - try { - String testSrc = System.getProperty("test.src", "."); + runTest(); + } catch (IOException ex) { + // It uses certutil.exe that isn't guaranteed to be installed + String certutilMsg = "Cannot run program \"certutil\""; + if (ex.getMessage().contains(certutilMsg)) { + throw new SkippedException("certutil is not installed"); + } + throw ex; + } + } + private static void runTest() throws Exception { + String testSrc = System.getProperty("test.src", "."); + try { // removing the alias NonUniqueName if it already exists ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY", "NonUniqueName"); diff --git a/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java b/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java new file mode 100644 index 0000000000000..5a3e816360058 --- /dev/null +++ b/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2025, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.crypto.*; +import javax.crypto.spec.*; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.security.*; +import java.security.spec.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.HexFormat; +import java.util.List; + +/* + * @test + * @bug 8328119 + * @summary test HKDF key derivation in SunPKCS11 + * @library /test/lib .. + * @enablePreview + * @run main/othervm/timeout=30 TestHKDF + */ + +public final class TestHKDF extends PKCS11Test { + + private static final boolean DEBUG = false; + private static final HexFormat hex = HexFormat.of().withLowerCase(); + private static final byte[] knownBytes = hex.parseHex( + "000102030405060708090a0b0c0d0e0f10111213141516"); + private static final OutputStream debugOut = new ByteArrayOutputStream(); + private static final PrintWriter debugPrinter = new PrintWriter(debugOut); + private static boolean testFailed = false; + private static Provider p11Provider; + private static SecretKeyFactory p11GenericSkf; + + private record TestContext(String hkdfAlg, String derivedKeyAlg, + Supplier baseKey, byte[] salt, byte[] info, + byte[] expectedPRK, byte[] expectedOKM, byte[] expectedOpOut) { + // expectedOpOut value: + // - If derivedKeyAlg is AES, expectedOpOut is the result of encrypting + // knownBytes with derivedKey, using AES/CBC/PKCS5Padding and an IV + // of 16 zero bytes. + // - If derivedKeyAlg is Generic, expectedOpOut is the result of + // calculating the HmacSHA256 of knownBytes with derivedKey. + } + + private static class HkdfTestAssertionException extends Exception { + HkdfTestAssertionException(String msg) { + super(msg); + } + } + + private enum KdfParamSpecType { + EXTRACT, + EXPAND, + EXTRACT_EXPAND + } + + private enum KeyMaterialType { + KEY, + DATA + } + + private static final List> keyMaterialCombinations = + List.of( + List.of(KeyMaterialType.KEY), + List.of(KeyMaterialType.DATA), + List.of(KeyMaterialType.KEY, KeyMaterialType.KEY), + List.of(KeyMaterialType.KEY, KeyMaterialType.DATA), + List.of(KeyMaterialType.DATA, KeyMaterialType.KEY), + List.of(KeyMaterialType.DATA, KeyMaterialType.DATA) + ); + + private static void addKeyMaterial( + List keyMaterialCombination, byte[] keyMaterial, + Consumer addKeyCb, Consumer addDataCb) + throws Exception { + if (keyMaterial.length < keyMaterialCombination.size()) { + throw new Exception("Key material is not enough to fulfill the " + + "combination requirement."); + } + int dataStart = 0, dataEnd; + for (int i = 0; i < keyMaterialCombination.size(); i++) { + dataEnd = + keyMaterial.length - keyMaterialCombination.size() + i + 1; + byte[] chunk = Arrays.copyOfRange(keyMaterial, dataStart, dataEnd); + if (keyMaterialCombination.get(i) == KeyMaterialType.KEY) { + addKeyCb.accept(p11GenericSkf.generateSecret( + new SecretKeySpec(chunk, "Generic"))); + } else { + addDataCb.accept(chunk); + } + dataStart = dataEnd; + } + } + + private static List generateKdfParamSpecs( + TestContext ctx, KdfParamSpecType type) throws Exception { + List kdfParamSpecs = new ArrayList<>(); + if (type == KdfParamSpecType.EXTRACT || + type == KdfParamSpecType.EXTRACT_EXPAND) { + for (List keyMaterialCombination : + keyMaterialCombinations) { + final HKDFParameterSpec.Builder b = + HKDFParameterSpec.ofExtract(); + SecretKey baseKey = ctx.baseKey.get(); + if (baseKey instanceof SecretKeySpec) { + addKeyMaterial(keyMaterialCombination, baseKey.getEncoded(), + b::addIKM, b::addIKM); + } else if (baseKey != null) { + b.addIKM(baseKey); + } + if (ctx.salt != null) { + addKeyMaterial(keyMaterialCombination, ctx.salt, b::addSalt, + b::addSalt); + } + if (type == KdfParamSpecType.EXTRACT) { + kdfParamSpecs.add(b.extractOnly()); + } else { + kdfParamSpecs.add(b.thenExpand(ctx.info, + ctx.expectedOKM.length)); + } + if (ctx.salt == null && !(baseKey instanceof SecretKeySpec)) { + // If the salt is null and the IKM is a non-SecretKeySpec + // (i.e. is a P11Key.P11SecretKey), the key material + // cannot be split and there will be a single + // HKDFParameterSpec to test. + break; + } + } + } else { + assert type == KdfParamSpecType.EXPAND : "Unexpected type."; + kdfParamSpecs.add(HKDFParameterSpec.expandOnly( + new SecretKeySpec(ctx.expectedPRK, "Generic"), ctx.info, + ctx.expectedOKM.length)); + } + return kdfParamSpecs; + } + + private static void checkOpWithDerivedKey(TestContext ctx, + SecretKey derivedKey, Provider p) throws Exception { + byte[] opOut; + switch (ctx.derivedKeyAlg) { + case "AES" -> { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", p); + cipher.init(Cipher.ENCRYPT_MODE, derivedKey, + new IvParameterSpec(new byte[16])); + opOut = cipher.doFinal(knownBytes); + } + case "Generic" -> { + Mac hmac = Mac.getInstance("HmacSHA256", p); + hmac.init(derivedKey); + opOut = hmac.doFinal(knownBytes); + } + default -> throw new RuntimeException( + "Unexpected derived key algorithm."); + } + printByteArrayAssertion("Operation output", opOut, ctx.expectedOpOut); + if (!Arrays.equals(opOut, ctx.expectedOpOut)) { + throw new HkdfTestAssertionException( + "Operation with derived key failure."); + } + } + + private static void checkDerivationData(String derivationType, + byte[] derivedKey, byte[] derivedData, byte[] expectedData) + throws Exception { + printByteArrayAssertion(derivationType + " key derivation", derivedKey, + expectedData); + printByteArrayAssertion(derivationType + " data derivation", + derivedData, expectedData); + if (!Arrays.equals(derivedKey, expectedData) || + !Arrays.equals(derivedData, expectedData)) { + throw new HkdfTestAssertionException( + derivationType + " derivation failure."); + } + } + + private static void executeDerivationForKdfParamSpec(TestContext ctx, + KdfParamSpecType type, KDF kdf, AlgorithmParameterSpec kdfParamSpec, + Provider p) throws Exception { + printDerivationInfo(ctx, type, kdfParamSpec, p); + printHeader("HKDF derivation: output", '-', 10); + String derivedKeyAlg = type == KdfParamSpecType.EXTRACT ? + "Generic" : ctx.derivedKeyAlg; + SecretKey derivedKey = kdf.deriveKey(derivedKeyAlg, kdfParamSpec); + byte[] derivedData = kdf.deriveData(kdfParamSpec); + if (type == KdfParamSpecType.EXPAND || + type == KdfParamSpecType.EXTRACT_EXPAND) { + checkDerivationData("Extract", derivedKey.getEncoded(), + derivedData, ctx.expectedOKM); + checkOpWithDerivedKey(ctx, derivedKey, p); + } else { + assert type == KdfParamSpecType.EXTRACT : "Unexpected type."; + checkDerivationData("Expand", derivedKey.getEncoded(), + derivedData, ctx.expectedPRK); + } + } + + private static void crossCheckTestExpectedData(TestContext ctx, + KdfParamSpecType type, AlgorithmParameterSpec kdfParamSpec) + throws Exception { + try { + Provider sunJCE = Security.getProvider("SunJCE"); + KDF kdf = KDF.getInstance(ctx.hkdfAlg, sunJCE); + executeDerivationForKdfParamSpec(ctx, type, kdf, kdfParamSpec, + sunJCE); + } catch (HkdfTestAssertionException e) { + // Fail if derivation was possible and the assertion data in this + // test is inconsistent with SunJCE. This should never happen. + throw e; + } catch (Exception e) { + // Cross-checking of the expected data in this test is a + // best-effort. If derivation was not possible (e.g. SunJCE does + // not support the HKDF algorithm), do not fail. + } + } + + private static void reportTestFailure(Exception e) { + testFailed = true; + printHeader("TEST FAILED", 'x', 10); + e.printStackTrace(debugPrinter); + } + + private static void executeDerivation(TestContext ctx, + KdfParamSpecType type) { + try { + KDF kdf = KDF.getInstance(ctx.hkdfAlg, p11Provider); + List kdfParamSpecs = + generateKdfParamSpecs(ctx, type); + crossCheckTestExpectedData(ctx, type, kdfParamSpecs.get(0)); + for (AlgorithmParameterSpec kdfParamSpec : kdfParamSpecs) { + executeDerivationForKdfParamSpec(ctx, type, kdf, kdfParamSpec, + p11Provider); + } + } catch (Exception e) { + reportTestFailure(e); + } + } + + private static byte[] hexStringToByteArray(String hexString) { + return hexString != null ? hex.parseHex(hexString) : null; + } + + private static void executeTest(String testHeader, String hkdfAlg, + String derivedKeyAlg, SecretKey baseKey, String saltHex, + String infoHex, String expectedPRKHex, String expectedOKMHex, + String expectedOpOutHex) { + executeTest(testHeader, hkdfAlg, derivedKeyAlg, ()-> baseKey, saltHex, + infoHex, expectedPRKHex, expectedOKMHex, expectedOpOutHex); + } + + private static void executeTest(String testHeader, String hkdfAlg, + String derivedKeyAlg, String baseKeyHex, String saltHex, + String infoHex, String expectedPRKHex, String expectedOKMHex, + String expectedOpOutHex) { + executeTest(testHeader, hkdfAlg, derivedKeyAlg, + ()-> new SecretKeySpec(hexStringToByteArray(baseKeyHex), + "Generic"), saltHex, infoHex, expectedPRKHex, + expectedOKMHex, expectedOpOutHex); + } + + private static void executeTest(String testHeader, String hkdfAlg, + String derivedKeyAlg, Supplier baseKey, String saltHex, + String infoHex, String expectedPRKHex, String expectedOKMHex, + String expectedOpOutHex) { + printTestHeader(testHeader); + TestContext ctx = new TestContext(hkdfAlg, derivedKeyAlg, baseKey, + hexStringToByteArray(saltHex), + hexStringToByteArray(infoHex), + hexStringToByteArray(expectedPRKHex), + hexStringToByteArray(expectedOKMHex), + hexStringToByteArray(expectedOpOutHex)); + executeDerivation(ctx, KdfParamSpecType.EXTRACT_EXPAND); + executeDerivation(ctx, KdfParamSpecType.EXTRACT); + executeDerivation(ctx, KdfParamSpecType.EXPAND); + } + + private static void printTestHeader(String testHeader) { + debugPrinter.println(); + debugPrinter.println("=".repeat(testHeader.length())); + debugPrinter.println(testHeader); + debugPrinter.println("=".repeat(testHeader.length())); + } + + private static void printHeader(String header, char sepChar, int sepCount) { + String sepBlock = String.valueOf(sepChar).repeat(sepCount); + debugPrinter.println(sepBlock + " " + header + " " + sepBlock); + } + + private static void printDerivationKeyMaterial(String header, + List keyMaterial, KdfParamSpecType type) { + if (keyMaterial != null && !keyMaterial.isEmpty()) { + debugPrinter.println(header + ":"); + for (SecretKey km : keyMaterial) { + debugPrinter.print(" ".repeat(2)); + if (km instanceof SecretKeySpec) { + debugPrinter.println(hex.formatHex(km.getEncoded())); + } else { + debugPrinter.println(km); + } + } + } else if (type == KdfParamSpecType.EXTRACT || + type == KdfParamSpecType.EXTRACT_EXPAND) { + debugPrinter.println(header + ": NULL"); + } + } + + private static void printDerivationInfo(TestContext ctx, + KdfParamSpecType type, AlgorithmParameterSpec kdfParamSpec, + Provider p) { + debugPrinter.println(); + printHeader("HKDF derivation: input", '-', 10); + debugPrinter.println("Algorithm: " + ctx.hkdfAlg); + debugPrinter.println("Provider: " + p.getName()); + debugPrinter.println("Derivation type: " + type); + List ikms = null; + List salts = null; + byte[] info = null; + Integer length = null; + switch (kdfParamSpec) { + case HKDFParameterSpec.Extract asExtract -> { + debugPrinter.println("Derived key type: PRK (Generic)"); + salts = asExtract.salts(); + ikms = asExtract.ikms(); + } + case HKDFParameterSpec.ExtractThenExpand asExtractExpand -> { + debugPrinter.println("Derived key type: " + ctx.derivedKeyAlg); + salts = asExtractExpand.salts(); + ikms = asExtractExpand.ikms(); + info = asExtractExpand.info(); + length = asExtractExpand.length(); + } + case HKDFParameterSpec.Expand asExpand -> { + debugPrinter.println("Derived key type: " + ctx.derivedKeyAlg); + info = asExpand.info(); + length = asExpand.length(); + } + case null, default -> throw new RuntimeException( + "Unrecognized AlgorithmParameterSpec class."); + } + printDerivationKeyMaterial("Salts", salts, type); + printDerivationKeyMaterial("IKMs", ikms, type); + if (info != null) { + debugPrinter.println("Info: " + hex.formatHex(info)); + } else if (type == KdfParamSpecType.EXPAND || + type == KdfParamSpecType.EXTRACT_EXPAND) { + debugPrinter.println("Info: NULL"); + } + if (length != null) { + debugPrinter.println("Length: " + length); + } + } + + private static void printByteArrayAssertion(String desc, byte[] actual, + byte[] expected) { + debugPrinter.println(desc + " (actual):"); + debugPrinter.println(actual != null ? hex.formatHex(actual) : "null"); + debugPrinter.println(desc + " (expected):"); + debugPrinter.println(expected != null ? hex.formatHex(expected) : + "null"); + } + + private static SecretKey doKeyAgreement(String algorithm, PrivateKey privK, + PublicKey pubK) throws Exception { + KeyAgreement ka = KeyAgreement.getInstance(algorithm, p11Provider); + ka.init(privK); + ka.doPhase(pubK, true); + return ka.generateSecret("TlsPremasterSecret"); + } + + private static SecretKey getTlsPremasterSecretWithDHExchange(String xHex, + String yHex, String pHex, String gHex) throws Exception { + KeyFactory kf = KeyFactory.getInstance("DH", p11Provider); + BigInteger p = new BigInteger(pHex, 16); + BigInteger g = new BigInteger(gHex, 16); + PrivateKey privK = kf.generatePrivate(new DHPrivateKeySpec( + new BigInteger(xHex, 16), p, g)); + PublicKey pubK = kf.generatePublic(new DHPublicKeySpec( + new BigInteger(yHex, 16), p, g)); + return doKeyAgreement("DH", privK, pubK); + } + + private static SecretKey getTlsPremasterSecretWithECDHExchange(String s, + String wx, String wy) throws Exception { + AlgorithmParameters p = + AlgorithmParameters.getInstance("EC", p11Provider); + p.init(new ECGenParameterSpec("secp256r1")); + ECParameterSpec params = p.getParameterSpec(ECParameterSpec.class); + KeyFactory kf = KeyFactory.getInstance("EC", p11Provider); + PrivateKey privK = kf.generatePrivate(new ECPrivateKeySpec( + new BigInteger(s), params)); + ECPoint publicPoint = new ECPoint(new BigInteger(wx), + new BigInteger(wy)); + PublicKey pubK = kf.generatePublic(new ECPublicKeySpec( + publicPoint, params)); + return doKeyAgreement("ECDH", privK, pubK); + } + + private static void test_RFC_5869_case_1() { + executeTest("RFC 5869 - Test Case 1", + "HKDF-SHA256", + "Generic", + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "000102030405060708090a0b0c", + "f0f1f2f3f4f5f6f7f8f9", + "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2" + + "b3e5", + "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4" + + "c5bf34007208d5b887185865", + "ad9e90d0c59d47539899647a3baf0fd364c54eeb5f4d0b80e1f39579e434" + + "e801"); + } + + private static void test_RFC_5869_case_2() { + executeTest("RFC 5869 - Test Case 2", + "HKDF-SHA256", + "Generic", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d" + + "1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b" + + "3c3d3e3f404142434445464748494a4b4c4d4e4f", + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d" + + "7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b" + + "9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccd" + + "cecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaeb" + + "ecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15f" + + "c244", + "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19af" + + "a97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9" + + "aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87", + "eabe8bc548bf430aedc423e9d7df94125eacff3dbb3b95b50379246c2546" + + "01da"); + } + + private static void test_RFC_5869_case_3() { + executeTest("RFC 5869 - Test Case 3", + "HKDF-SHA256", + "Generic", + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + null, + null, + "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293c" + + "cb04", + "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c73" + + "8d2d9d201395faa4b61a96c8", + "06828b5679679681be59aa2822869cb1a174319e53a545e3301bd832ae3e" + + "513f"); + } + + private static void test_AES_HKDFWithHmacSHA256() { + executeTest("AES - HKDF-SHA256", + "HKDF-SHA256", + "AES", + "000102030405060708090a0b0c0d0e0f", + "101112131415161718191a1b1c1d1e1f", + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "0ecd9f09ddfc6b7bcad2646fa6bc10f922e5489a4ea755ec87ec1b7df379" + + "85ca", + "b97b1b4ce098f8e22f2f38b60d9f7a0e5902a1193602a876c010d73009dd" + + "0701", + "646e0175bcef43b9ebd2a3884699ad40b34d4b011e91679c5f25f0721d36" + + "7f6a"); + } + + private static void test_AES_HKDFWithHmacSHA384() { + executeTest("AES - HKDF-SHA384", + "HKDF-SHA384", + "AES", + "000102030405060708090a0b0c0d0e0f", + "101112131415161718191a1b1c1d1e1f", + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "31ca88a527220f8271d78df4ce6c4d973f135ad37973b96644b4d52d499d" + + "0a2b03d53c875b1176b089e1e6161ab6d92b", + "ba91a67e4d7640495194916ef1252418a651103fbddb0f2ec8b9d1f44f7a" + + "7a0d", + "f3cfcb44d7b36dce96f584c74118b434e714a13448321063241fd24ace11" + + "f2a0"); + } + + private static void test_AES_HKDFWithHmacSHA512() { + executeTest("AES - HKDF-SHA512", + "HKDF-SHA512", + "AES", + "000102030405060708090a0b0c0d0e0f", + "101112131415161718191a1b1c1d1e1f", + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "f6e6b1ddb24ea0f0ede0f533d1f350c86bf78966b0e5fd2af34dd00dae39" + + "01d6279fe8111d6572e3cd05f2f0eeabb9144dc0da9437cdf37b0c6d7f3b" + + "1064ab2b", + "302212eb57ae758874e0e52fbdfa4eee29d7c694f181b21d8a8b571a43ce" + + "aad5", + "94459a6593f9c2cfea2ad32970efb8506f3a927927ba283fb6bfd7111aa8" + + "63fc"); + } + + private static void test_AES_HKDFWithHmacSHA256_EmptyBaseKey() { + executeTest("AES - HKDF-SHA256 (empty base key)", + "HKDF-SHA256", + "AES", + (SecretKey) null, + "101112131415161718191a1b1c1d1e1f", + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "cc267bd9515c1eba2cf6aaa1fc8380677f4351fcbea6d70873df5a334efc" + + "ee0d", + "cf353a33460b146c0eae3f0788ee281e5a0be15280fbeba107472aa1cd58" + + "d111", + "326e9028f51c05c1919215bad6e35668c94c88040c3777e8e6f8b6acdece" + + "85fa"); + } + + private static void test_AES_HKDFWithHmacSHA256_EmptyBaseKeySaltInfo() { + executeTest("AES - HKDF-SHA256 (empty base key, salt, and info)", + "HKDF-SHA256", + "AES", + (SecretKey) null, + null, + null, + "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292" + + "c5ad", + "eb70f01dede9afafa449eee1b1286504e1f62388b3f7dd4f956697b0e828" + + "fe18", + "3fdcf83994f6e0a6f6f482d097e242355e255a8ed17e661a71ca2d592c7a" + + "884e"); + } + + private static void test_HKDF_after_DH_HkdfSHA256() throws Exception { + SecretKey tlsPremasterSecret = getTlsPremasterSecretWithDHExchange( + "00bcb8fa0a6b569961782a394599a1a02a05532a836819908a9a9000ed", + "58ceab52f470026eaea24eb250e08d7cc23f21dda57ad628d14eab788633" + + "cebc78c565f9292e6cfe9910d51c4878f590c46cbf380e19acf55cd468ab" + + "672afb29c09b7edfd522d034019eadae75ea99bacf1e166548f092a5d371" + + "930a275cbcb4bb02cb1d1b7a8bf3751dc85e61fb674059deef54e8ebbd36" + + "3bdac4f85c5e49cb7dc8720a8088f047f319a63c2722a720e187f827578b" + + "2545041bb5e640454e791f683622bb5aba4ab9bc51001c59bba5cd6cc0e2" + + "aec00b0a5313a27454a93d3bd3f2ae5ab1c13165d1564e3b2d60629302b3" + + "6bf44c1991bad279d3bd51b142294007f0c8828c9060d8b9b4cc6d335bcc" + + "ce31d4e6aa18fd3ce99cb92aec09de2d", + "00ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a" + + "67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a" + + "6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0b" + + "ff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b" + + "3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dc" + + "a3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c" + + "08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5" + + "c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa05" + + "1015728e5a8aacaa68ffffffffffffffff", + "02" + ); + executeTest("Test HKDF-SHA256 after DH exchange (TLS)", + "HKDF-SHA256", + "Generic", + tlsPremasterSecret, + null, + null, + "e3cf8e5e0892ad251a5863c7f6ddc4fb988b1a723a30d3fe1ac235799caf" + + "86e1", + "86e508974080cdad9fa4407e253d35ae48f40e0e266c91dd04c775538c17" + + "0eacd71bb4d54ba0c5065091", + "2e94c8c852d318887fa94dac544c369bc25879efd39683a9dc5eda55f565" + + "88c0"); + } + + private static void test_HKDF_after_ECDH_HkdfSHA256() throws Exception { + SecretKey tlsPremasterSecret = getTlsPremasterSecretWithECDHExchange( + "312092587041182431404764856027482553256569653405119712868911" + + "21589605635583946", + "851398477998049170325388348439523125186814652510003800309225" + + "34333070929362623", + "531080873930420952237875954830357399317339863932672261700603" + + "26242234504331049"); + executeTest("Test HKDF-SHA256 after ECDH exchange (TLS)", + "HKDF-SHA256", + "Generic", + tlsPremasterSecret, + null, + null, + "638d8874237f12e42b366090ee8a0207d28a1ac8fd12b6a753ecb58c31cd" + + "6a5e", + "348a1afabe9560d3a0a6577e8bd66f0e8dc43b4ad52037f692ea5d28fbb2" + + "bc963ef59eba65a83befc465", + "bab55b2106b4fee07b7afc905ed7c1e84889e941fbc12f132c706addcfc0" + + "6e09"); + } + + public void main(Provider p) throws Exception { + p11Provider = p; + p11GenericSkf = SecretKeyFactory.getInstance("Generic", p11Provider); + for (Method m : TestHKDF.class.getDeclaredMethods()) { + if (m.getName().startsWith("test")) { + m.invoke(null); + } + } + if (DEBUG || testFailed) { + debugPrinter.flush(); + System.out.println(debugOut); + } + if (testFailed) { + throw new Exception("TEST FAILED"); + } + System.out.println("TEST PASS - OK"); + } + + public static void main(String[] args) throws Exception { + main(new TestHKDF(), args); + } +} diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java index 237436094ac6e..b624afd69fb3c 100644 --- a/test/jdk/sun/security/pkcs11/PKCS11Test.java +++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ import java.security.InvalidAlgorithmParameterException; import java.security.KeyPairGenerator; import java.security.NoSuchProviderException; -import java.security.Policy; import java.security.Provider; import java.security.ProviderException; import java.security.SecureRandom; diff --git a/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java b/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java index 7884aa2ffedd9..e2bfa3dc048e7 100644 --- a/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java +++ b/test/jdk/sun/security/pkcs11/ec/ReadCertificates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * and verify their signatures * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm ReadCertificates */ @@ -55,6 +54,7 @@ import java.util.List; import java.util.Map; import javax.security.auth.x500.X500Principal; +import jdk.test.lib.security.Providers; public class ReadCertificates extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java b/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java index 7bf45feeac008..15a5b14ec40a8 100644 --- a/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java +++ b/test/jdk/sun/security/pkcs11/ec/ReadPKCS12.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary Verify that we can parse ECPrivateKeys from PKCS#12 and use them * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @key randomness * @modules jdk.crypto.cryptoki java.base/sun.security.ec * @run main/othervm ReadPKCS12 @@ -54,6 +53,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import jdk.test.lib.security.Providers; public class ReadPKCS12 extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDH.java b/test/jdk/sun/security/pkcs11/ec/TestECDH.java index 46146b4252488..b6821b8837212 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDH.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDH.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary Basic known answer test for ECDH * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm TestECDH */ @@ -43,6 +42,8 @@ import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import javax.crypto.KeyAgreement; +import jdk.test.lib.security.Providers; + public class TestECDH extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDH2.java b/test/jdk/sun/security/pkcs11/ec/TestECDH2.java index ac745fbb68bcc..5a7e2a0047444 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDH2.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDH2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary basic test of ECDSA signatures for P-256 and P-384 from the * example data in "Suite B Implementer's Guide to FIPS 186-3". * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules java.base/sun.security.util * jdk.crypto.cryptoki * @compile -XDignore.symbol.file TestECDH2.java diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDSA.java b/test/jdk/sun/security/pkcs11/ec/TestECDSA.java index b9362bc0c01cc..00fc73a140d41 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDSA.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary basic test of SHA1withECDSA and NONEwithECDSA signing/verifying * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @key randomness * @modules jdk.crypto.cryptoki * @run main/othervm TestECDSA @@ -45,6 +44,7 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Random; +import jdk.test.lib.security.Providers; public class TestECDSA extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java b/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java index daf24f4db96ef..4489232d1c8cd 100644 --- a/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java +++ b/test/jdk/sun/security/pkcs11/ec/TestECDSA2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary basic test of ECDSA signatures for P-256 and P-384 from the * example data in "Suite B Implementer's Guide to FIPS 186-3". * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules java.base/sun.security.util * jdk.crypto.cryptoki * @compile -XDignore.symbol.file TestECDSA2.java diff --git a/test/jdk/sun/security/pkcs11/nss/p11-nss-sensitive.txt b/test/jdk/sun/security/pkcs11/nss/p11-nss-sensitive.txt index 4579dd593982d..df891c7097a0f 100644 --- a/test/jdk/sun/security/pkcs11/nss/p11-nss-sensitive.txt +++ b/test/jdk/sun/security/pkcs11/nss/p11-nss-sensitive.txt @@ -49,10 +49,12 @@ attributes(*,CKO_PRIVATE_KEY,CKK_DH) = { # Make all private keys sensitive attributes(*,CKO_PRIVATE_KEY,*) = { CKA_SENSITIVE = true + CKA_EXTRACTABLE = false } # Make all secret keys sensitive attributes(*,CKO_SECRET_KEY,*) = { CKA_SENSITIVE = true + CKA_EXTRACTABLE = false } diff --git a/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java b/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java index 7652d32c70ad3..cf832dec86ab8 100644 --- a/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java +++ b/test/jdk/sun/security/pkcs11/rsa/TestCACerts.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ * @summary Test the new RSA provider can verify all the RSA certs in the cacerts file * @author Andreas Sterbenz * @library /test/lib .. - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm TestCACerts */ @@ -42,6 +41,7 @@ import java.security.Security; import java.security.cert.X509Certificate; import java.util.Enumeration; +import jdk.test.lib.security.Providers; public class TestCACerts extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java b/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java index 4d263e0442933..c125464659b53 100644 --- a/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java +++ b/test/jdk/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ * @summary Verify that all ciphersuites work (incl. ECC using NSS crypto) * @author Andreas Sterbenz * @library /test/lib .. ../../../../javax/net/ssl/TLSCommon - * @library ../../../../java/security/testlibrary * @modules jdk.crypto.cryptoki * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" * ClientJSSEServerJSSE @@ -40,6 +39,7 @@ import java.security.Provider; import java.security.Security; +import jdk.test.lib.security.Providers; public class ClientJSSEServerJSSE extends PKCS11Test { diff --git a/test/jdk/sun/security/pkcs12/GetSetEntryTest.java b/test/jdk/sun/security/pkcs12/GetSetEntryTest.java index 2bfb92aae2f56..00e6e2b69e787 100644 --- a/test/jdk/sun/security/pkcs12/GetSetEntryTest.java +++ b/test/jdk/sun/security/pkcs12/GetSetEntryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,9 @@ * @test * @bug 8327461 * @summary engineGetEntry in PKCS12KeyStore should be thread-safe - * @library /test/lib ../../../java/security/testlibrary + * @library /test/lib * @modules java.base/sun.security.x509 * java.base/sun.security.util - * @build CertificateBuilder * @run main GetSetEntryTest */ @@ -42,7 +41,7 @@ import java.util.concurrent.TimeUnit; import java.util.Date; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.CertificateBuilder; public class GetSetEntryTest { diff --git a/test/jdk/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java b/test/jdk/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java index 860b2d99910ac..32bdea4e153c2 100644 --- a/test/jdk/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java +++ b/test/jdk/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java @@ -25,7 +25,6 @@ * @test * @bug 8047769 * @modules java.base/java.io:open - * java.base/java.lang.ref:open * java.base/sun.security.provider:open * @summary SecureRandom should be more frugal with file descriptors */ @@ -133,11 +132,9 @@ public static void main(String[] args) throws Exception { /** * A proxy for (package)private static methods: * sun.security.provider.FileInputStreamPool.getInputStream - * java.lang.ref.Reference.waitForReferenceProcessing */ static class TestProxy { private static final Method getInputStreamMethod; - private static final Method waitForReferenceProcessingMethod; private static final Field inField; static { @@ -149,10 +146,6 @@ static class TestProxy { "getInputStream", File.class); getInputStreamMethod.setAccessible(true); - waitForReferenceProcessingMethod = - Reference.class.getDeclaredMethod("waitForReferenceProcessing"); - waitForReferenceProcessingMethod.setAccessible(true); - inField = FilterInputStream.class.getDeclaredField("in"); inField.setAccessible(true); } catch (Exception e) { @@ -180,25 +173,6 @@ static InputStream FileInputStreamPool_getInputStream(File file) } } - static boolean Reference_waitForReferenceProcessing() { - try { - return (boolean) waitForReferenceProcessingMethod.invoke(null); - } catch (InvocationTargetException e) { - Throwable te = e.getTargetException(); - if (te instanceof InterruptedException) { - return true; - } else if (te instanceof RuntimeException) { - throw (RuntimeException) te; - } else if (te instanceof Error) { - throw (Error) te; - } else { - throw new UndeclaredThrowableException(te); - } - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - static FileInputStream FilterInputStream_getInField(FilterInputStream fis) { try { return (FileInputStream) inField.get(fis); diff --git a/test/jdk/sun/security/provider/acvp/Launcher.java b/test/jdk/sun/security/provider/acvp/Launcher.java index 356453292c1a0..1405847de5d14 100644 --- a/test/jdk/sun/security/provider/acvp/Launcher.java +++ b/test/jdk/sun/security/provider/acvp/Launcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +import jdk.test.lib.artifacts.Artifact; +import jdk.test.lib.artifacts.ArtifactResolver; +import jdk.test.lib.artifacts.ArtifactResolverException; import jdk.test.lib.json.JSONValue; import jtreg.SkippedException; -import java.nio.file.Files; +import java.io.InputStream; import java.nio.file.Path; import java.security.Provider; import java.security.Security; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /* * @test @@ -35,19 +41,17 @@ * @modules java.base/sun.security.provider */ -/// This test runs on `internalProjection.json`-style files generated -/// by NIST's ACVP Server. See [https://github.com/usnistgov/ACVP-Server]. -/// -/// The files are either put into the `data` directory or another -/// directory specified by the `test.acvp.data` test property. -/// The test walks through the directory recursively and looks for -/// file names equal to or ending with `internalProjection.json` and -/// runs tests on them. +/// This test runs on `internalProjection.json`-style files generated by NIST's +/// ACVP Server ([GitHub repository](https://github.com/usnistgov/ACVP-Server)). +/// These files are included in ZIP archives available under the +/// [tags section](https://github.com/usnistgov/ACVP-Server/tags) +/// of the repository. /// -/// Set the `test.acvp.alg` test property to only test the specified algorithm. +/// The zip archive is either hosted on artifactory server or +/// specified with local path to the test. +/// The test looks for test data files in the archive listed with `TEST_FILES`. /// -/// Sample files can be downloaded from -/// [https://github.com/usnistgov/ACVP-Server/tree/master/gen-val/json-files]. +/// These tests are currently compatible with ACVP version 1.1.0.38. /// /// By default, the test uses system-preferred implementations. /// If you want to test a specific provider, set the @@ -58,19 +62,30 @@ /// [https://github.com/usnistgov/ACVP?tab=readme-ov-file#supported-algorithms]. /// /// Example: +/// +/// Run locally with ArtifactResolver /// ``` -/// jtreg -Dtest.acvp.provider=SunJCE \ -/// -Dtest.acvp.alg=ML-KEM \ -/// -Dtest.acvp.data=/path/to/json-files/ \ -/// -jdk:/path/to/jdk Launcher.java +/// jtreg -Djdk.test.lib.artifacts.ACVP-Server= /// ``` -public class Launcher { +/// OR host the zip archive on artifactory server. +/// - private static final String ONLY_ALG - = System.getProperty("test.acvp.alg"); +public class Launcher { private static final Provider PROVIDER; + private static final String ACVP_BUNDLE_LOC = "jpg.tests.jdk"; + private static final String ACVP_BUNDLE_NAME = "ACVP-Server"; + private static final String ACVP_BUNDLE_VERSION = "1.1.0.38"; + // Zip archive entry name, do not update to use File.separator + private static final String[] TEST_FILES = { + "gen-val/json-files/ML-DSA-keyGen-FIPS204/internalProjection.json", + "gen-val/json-files/ML-DSA-sigGen-FIPS204/internalProjection.json", + "gen-val/json-files/ML-DSA-sigVer-FIPS204/internalProjection.json", + "gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json", + "gen-val/json-files/ML-KEM-keyGen-FIPS203/internalProjection.json" + }; + private static int count = 0; private static int invalidTest = 0; private static int unsupportedTest = 0; @@ -91,24 +106,26 @@ public class Launcher { public static void main(String[] args) throws Exception { - var testDataProp = System.getProperty("test.acvp.data"); - Path dataPath = testDataProp != null - ? Path.of(testDataProp) - : Path.of(System.getProperty("test.src"), "data"); - System.out.println("Data path: " + dataPath); + Path archivePath = fetchACVPServerTests(ACVP_SERVER_TESTS.class); + System.out.println("Data path: " + archivePath); if (PROVIDER != null) { System.out.println("Provider: " + PROVIDER.getName()); } - if (ONLY_ALG != null) { - System.out.println("Algorithm: " + ONLY_ALG); - } - try (var stream = Files.walk(dataPath)) { - stream.filter(Files::isRegularFile) - .filter(p -> p.getFileName().toString() - .endsWith("internalProjection.json")) - .forEach(Launcher::run); + // Read test data files from zip archive + try (ZipFile zf = new ZipFile(archivePath.toFile())) { + for (String testFile : TEST_FILES) { + // Zip archive entry name, do not update to use File.separator + String fullEntryName = ACVP_BUNDLE_NAME + "-" + ACVP_BUNDLE_VERSION + "/" + testFile; + System.out.println("Find and test with: " + fullEntryName); + ZipEntry ze = zf.getEntry(fullEntryName); + if (ze != null) { + run(zf.getInputStream(ze)); + } else { + throw new RuntimeException("Entry not found: " + fullEntryName); + } + } } if (count > 0) { @@ -117,25 +134,25 @@ public static void main(String[] args) throws Exception { System.out.println("Invalid tests: " + invalidTest); System.out.println("Unsupported tests: " + unsupportedTest); } else { - throw new SkippedException("No supported test found"); + throw new RuntimeException("No supported test found"); + } + + if (invalidTest != 0 || unsupportedTest != 0){ + throw new RuntimeException("Invalid or Unsupported tests found"); } } - static void run(Path test) { + static void run(InputStream test) { try { JSONValue kat; - try { - kat = JSONValue.parse(Files.readString(test)); + try (test) { + kat = JSONValue.parse(new String(test.readAllBytes())); } catch (Exception e) { System.out.println("Warning: cannot parse " + test + ". Skipped"); invalidTest++; return; } var alg = kat.get("algorithm").asString(); - if (ONLY_ALG != null && !alg.equals(ONLY_ALG)) { - return; - } - System.out.println(">>> Testing " + test + "..."); switch (alg) { case "ML-DSA" -> { ML_DSA_Test.run(kat, PROVIDER); @@ -160,4 +177,28 @@ static void run(Path test) { throw new RuntimeException(e); } } + + private static Path fetchACVPServerTests(Class clazz) { + try { + return ArtifactResolver.resolve(clazz).entrySet().stream() + .findAny().get().getValue(); + } catch (ArtifactResolverException e) { + Throwable cause = e.getCause(); + if (cause == null) { + throw new SkippedException("Cannot resolve artifact, " + + "please check if JIB jar is present in classpath.", e); + } + + throw new SkippedException("Fetch artifact failed: " + clazz, e); + } + } + + @Artifact( + organization = ACVP_BUNDLE_LOC, + name = ACVP_BUNDLE_NAME, + revision = ACVP_BUNDLE_VERSION, + extension = "zip", + unpack = false) + private static class ACVP_SERVER_TESTS { + } } diff --git a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java index 657c01e4aa89b..281bb415305b0 100644 --- a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,10 +36,6 @@ public class ML_DSA_Test { public static void run(JSONValue kat, Provider provider) throws Exception { - // We only have ML-DSA test for internal functions, which - // is equivalent to the FIP 204 draft. - ML_DSA_Impls.version = ML_DSA_Impls.Version.DRAFT; - var mode = kat.get("mode").asString(); switch (mode) { case "keyGen" -> keyGenTest(kat, provider); @@ -50,7 +46,7 @@ public static void run(JSONValue kat, Provider provider) throws Exception { } static NamedParameterSpec genParams(String pname) { - return switch (pname) { + return switch (pname) { case "ML-DSA-44" -> NamedParameterSpec.ML_DSA_44; case "ML-DSA-65" -> NamedParameterSpec.ML_DSA_65; case "ML-DSA-87" -> NamedParameterSpec.ML_DSA_87; @@ -76,8 +72,8 @@ static void keyGenTest(JSONValue kat, Provider p) throws Exception { var kp = g.generateKeyPair(); var pk = f.getKeySpec(kp.getPublic(), EncodedKeySpec.class).getEncoded(); var sk = f.getKeySpec(kp.getPrivate(), EncodedKeySpec.class).getEncoded(); - Asserts.assertEqualsByteArray(pk, toByteArray(c.get("pk").asString())); - Asserts.assertEqualsByteArray(sk, toByteArray(c.get("sk").asString())); + Asserts.assertEqualsByteArray(toByteArray(c.get("pk").asString()), pk); + Asserts.assertEqualsByteArray(toByteArray(c.get("sk").asString()), sk); } System.out.println(); } @@ -89,9 +85,23 @@ static void sigGenTest(JSONValue kat, Provider p) throws Exception { : Signature.getInstance("ML-DSA", p); for (var t : kat.get("testGroups").asArray()) { var pname = t.get("parameterSet").asString(); - var det = Boolean.parseBoolean(t.get("deterministic").asString()); System.out.println(">> " + pname + " sign"); + var det = Boolean.parseBoolean(t.get("deterministic").asString()); + if (t.get("signatureInterface").asString().equals("internal")) { + ML_DSA_Impls.version = ML_DSA_Impls.Version.DRAFT; + } else { + ML_DSA_Impls.version = ML_DSA_Impls.Version.FINAL; + } + if (t.get("externalMu").asString().equals("true")) { + continue; // Not supported + } for (var c : t.get("tests").asArray()) { + var cstr = c.get("context"); + var ctxt = cstr == null ? new byte[0] : toByteArray(cstr.asString()); + var hashAlg = c.get("hashAlg").asString(); + if (!hashAlg.equals("none") || ctxt.length != 0) { + continue; // Not supported + } System.out.print(Integer.parseInt(c.get("tcId").asString()) + " "); var sk = new PrivateKey() { public String getAlgorithm() { return pname; } @@ -103,8 +113,7 @@ static void sigGenTest(JSONValue kat, Provider p) throws Exception { s.initSign(sk, sr); s.update(toByteArray(c.get("message").asString())); var sig = s.sign(); - Asserts.assertEqualsByteArray( - sig, toByteArray(c.get("signature").asString())); + Asserts.assertEqualsByteArray(toByteArray(c.get("signature").asString()), sig); } System.out.println(); } @@ -116,14 +125,31 @@ static void sigVerTest(JSONValue kat, Provider p) throws Exception { : Signature.getInstance("ML-DSA", p); for (var t : kat.get("testGroups").asArray()) { var pname = t.get("parameterSet").asString(); - var pk = new PublicKey() { - public String getAlgorithm() { return pname; } - public String getFormat() { return "RAW"; } - public byte[] getEncoded() { return toByteArray(t.get("pk").asString()); } - }; System.out.println(">> " + pname + " verify"); + + if (t.get("signatureInterface").asString().equals("internal")) { + ML_DSA_Impls.version = ML_DSA_Impls.Version.DRAFT; + } else { + ML_DSA_Impls.version = ML_DSA_Impls.Version.FINAL; + } + + if (t.get("externalMu").asString().equals("true")) { + continue; // Not supported + } + for (var c : t.get("tests").asArray()) { + var cstr = c.get("context"); + var ctxt = cstr == null ? new byte[0] : toByteArray(cstr.asString()); + var hashAlg = c.get("hashAlg").asString(); + if (!hashAlg.equals("none") || ctxt.length != 0) { + continue; // Not supported + } System.out.print(c.get("tcId").asString() + " "); + var pk = new PublicKey() { + public String getAlgorithm() { return pname; } + public String getFormat() { return "RAW"; } + public byte[] getEncoded() { return toByteArray(c.get("pk").asString()); } + }; // Only ML-DSA sigVer has negative tests var expected = Boolean.parseBoolean(c.get("testPassed").asString()); var actual = true; diff --git a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java index 46f394adbdfad..c46c6a99e6da1 100644 --- a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java @@ -70,8 +70,8 @@ static void keyGenTest(JSONValue kat, Provider p) throws Exception { var kp = g.generateKeyPair(); var pk = f.getKeySpec(kp.getPublic(), EncodedKeySpec.class).getEncoded(); var sk = f.getKeySpec(kp.getPrivate(), EncodedKeySpec.class).getEncoded(); - Asserts.assertEqualsByteArray(pk, toByteArray(c.get("ek").asString())); - Asserts.assertEqualsByteArray(sk, toByteArray(c.get("dk").asString())); + Asserts.assertEqualsByteArray(toByteArray(c.get("ek").asString()), pk); + Asserts.assertEqualsByteArray(toByteArray(c.get("dk").asString()), sk); } System.out.println(); } @@ -97,9 +97,9 @@ static void encapDecapTest(JSONValue kat, Provider p) throws Exception { ek, new FixedSecureRandom(toByteArray(c.get("m").asString()))); var enc = e.encapsulate(); Asserts.assertEqualsByteArray( - enc.encapsulation(), toByteArray(c.get("c").asString())); + toByteArray(c.get("c").asString()), enc.encapsulation()); Asserts.assertEqualsByteArray( - enc.key().getEncoded(), toByteArray(c.get("k").asString())); + toByteArray(c.get("k").asString()), enc.key().getEncoded()); } System.out.println(); } else if (function.equals("decapsulation")) { @@ -112,7 +112,7 @@ static void encapDecapTest(JSONValue kat, Provider p) throws Exception { System.out.print(c.get("tcId").asString() + " "); var d = g.newDecapsulator(dk); var k = d.decapsulate(toByteArray(c.get("c").asString())); - Asserts.assertEqualsByteArray(k.getEncoded(), toByteArray(c.get("k").asString())); + Asserts.assertEqualsByteArray(toByteArray(c.get("k").asString()), k.getEncoded()); } System.out.println(); } diff --git a/test/jdk/sun/security/provider/acvp/SHA_Test.java b/test/jdk/sun/security/provider/acvp/SHA_Test.java index 3e5d4bb252149..4a64fb00c8ce4 100644 --- a/test/jdk/sun/security/provider/acvp/SHA_Test.java +++ b/test/jdk/sun/security/provider/acvp/SHA_Test.java @@ -46,8 +46,8 @@ public static void run(JSONValue kat, Provider provider) throws Exception { var msg = toByteArray(c.get("msg").asString()); var len = Integer.parseInt(c.get("len").asString()); if (msg.length * 8 == len) { - Asserts.assertEqualsByteArray(md.digest(msg), - toByteArray(c.get("md").asString())); + Asserts.assertEqualsByteArray( + toByteArray(c.get("md").asString()), md.digest(msg)); } else { System.out.print("bits "); } @@ -70,8 +70,8 @@ public static void run(JSONValue kat, Provider provider) throws Exception { } MD = md.digest(MD); } - Asserts.assertEqualsByteArray(MD, - toByteArray(r.get("md").asString())); + Asserts.assertEqualsByteArray( + toByteArray(r.get("md").asString()), MD); SEED = MD; } else { var A = SEED; @@ -88,8 +88,8 @@ public static void run(JSONValue kat, Provider provider) throws Exception { B = C; C = MD; } - Asserts.assertEqualsByteArray(MD, - toByteArray(r.get("md").asString())); + Asserts.assertEqualsByteArray( + toByteArray(r.get("md").asString()), MD); SEED = MD; } } @@ -110,8 +110,8 @@ public static void run(JSONValue kat, Provider provider) throws Exception { md.update(ct); cc += clen; } - Asserts.assertEqualsByteArray(md.digest(), - toByteArray(c.get("md").asString())); + Asserts.assertEqualsByteArray( + toByteArray(c.get("md").asString()), md.digest()); } } default -> throw new UnsupportedOperationException( diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json deleted file mode 100644 index 1fcb409227f92..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json +++ /dev/null @@ -1,555 +0,0 @@ -{ - "vsId": 42, - "algorithm": "ML-DSA", - "mode": "keyGen", - "revision": "FIPS204", - "isSample": false, - "testGroups": [ - { - "tgId": 1, - "testType": "AFT", - "parameterSet": "ML-DSA-44", - "tests": [ - { - "tcId": 1, - "deferred": false, - "seed": "93EF2E6EF1FB08999D142ABE0295482370D3F43BDB254A78E2B0D5168ECA065F", - "pk": "BC5FF810EB089048B8AB3020A7BD3B16C0E0CA3D6B97E4646C2CCAE0BBF19EF7230A19D75ADBDED52DB855E252A719FCBD147BA67B2FAD14ED0E68FDFE8C65BADEACB0911193ADFA8794D78F8E3D662A1C49DA819FD959E7F078F203C456F8B6E7C9415898E541C73032DBD619EAF60F8D64F8683DA99ECA51220B0ACA28464099F547C02777BD37D84A59BD37ED7A8A92633C75D07C793FE7252B584ABF6A15EE14507E5E193F89864D09AC8727A6D0421F0C19F0E2FBFC213D3FBD70F4F9762CECFF231E9C8A7628D3F8B0857B032D32DE62FF8ECBF4008289BF34403665F81A081AD5A85A282F99BAB9E5385AFBCCCF44B74C0196C7545527EC3026DA1280C4EB37D09CFE3EC4B4910B62EB9815A425C6590FC4AD3FBB225752CC1FC5693F187E7DEC4EEFBEB6B91BD91C5E2EA6A91D14D097BE203FBA0BF937C97507DC007C4CAA9B0785892966FF15900924E579D4FBA02BDA87555F073DAE00513E70809ABBC711FBA2E7649577C42AFDC24BF7413E51268AD6DB6113B7D9191AF9D061DBDED5D630877650C124F11BC4BDC3FDC6A900F63126F921E838AD0C2275A3389A39BD99A134504550101CD3E95E6D1496BE7DE6627DF4FD6C28BBF40B30EFA9B5C3D5C85AB14A65C02D6D4781FF13D328608554B6D15ED91289A6D55AAC0C38E37706F7355E9A4FDA615B875926BFE5A59D9EF273BF94A07CFA573178F0E004B6E1EF0A8349E9BCC01981F2460F0A2743C28D1E138FFB765E7E3397B7913335D402FE91806AA8FC819253AF32692FA651E867F5907EF46F00625A030EC904EDAB21426D59119D2CAA43BD935DEC0A550C61EE4B279C1CA3A79C79A66E3F2D2FADB00F59A3A438AA44570106073017FA1C8757500109720D125BBA231A0C36350C78086DFDC8D613AECA88C4CCAEB4A44D13ADB3C717D65C82A351B9B6EABF6A10F4B4E9623E3A95B4D40A12A818AC6B3822DB82FB05DC4202648B4454689AEB69EA325F03E35DEFA54708481420C6D697BB912FCA0D3F192EF297DFE77FF36B2103F1AD1AEECED1C814C2CD7EF16BCE476AD04F941AFC79E3295474A41062518C0037860934F0E5E652F72749A698632A0991F613F5CB96CA1178F974F2C4AA0CE63DC24E364C92A643B90A5F85A62FD4D8D2B193D29B18BEDE2653FC5D3F24F5B2C018DBBCB6EF00F305BF93666BD47FEA9193BC233DB39121442E938DA5DD07EE6E879C5B9DFF41ECEE5E0589AE6175FF5EC6F6D2629F56B18B4DE66FCB13DF0400A797C92270F69BDEBDDCB88C4248919B56CDA70B8AC4F9429C292DA94D6478280764FE2386FC38CB0931458839EF4E7DE8F0689D99805988C7F96111852C8929E5A540D3B78D712DECC396FEF3EC34402184E4FD29F363EA80F6FC50BA9A11351ACEEA8FE68D541E1AA5848D9F6E61DFB62B2F23BC5081E82F76226E03284982EC48481209B1A7D4C8797E44BFA870B22004DB74BD7D478D5B3614D2B1DA7502B398EB9DA80D06461E90E03060446AB4A8238432BFAF752F391791214F1E6B63590D536060D1C245307BC5C1BAC4AAA099D36BB6DCBC973CF2E69F2734D0F29AEEC4567B99A16BC17C6CDDACEFE49927FB14E7D98DD4263519469CCA3DB4679A68CEEDA955592210FC49AA5FBE934CC73D84E4BA5478002D6890989068EF8FC98C2532B83BF3CB9EF02893C2152426B9D1A94734DFB4F91135143C9EED18FD51AE875D07A23775606A734FBA98C063B4A1622E7FF21AA7E652A3D6C19FE0DC6761B7D35302BF214D3079F76051082A875929920DC3B3CB43211A23A43A50332FAF1AC2191E717125F63E2586C4D86DCA6BCD3D038F9D3A7B66CBC7DF34", - "sk": "BC5FF810EB089048B8AB3020A7BD3B16C0E0CA3D6B97E4646C2CCAE0BBF19EF7BA2B57C446556EE2B72C78B96BB7A8503DE40AFB54184E3B5463C21AF7485323DF98F0160AE5D137512725F89D563BC9A189D31D20B3B3C8FFAAF5E486E79051F6F3605CCA2569FDB46B3318D23842CE40D6438613F68B455B0D3BCA0E050D4D119988A2C4801B9084E0B048C928092230902406499840655A268ADA3290DA4808228190C81461DC166A21478E08B221E308681A024414C665E1987190C6690C1544C9A011CC347183404500124D91080083368412854CCC0041099070189500A2B2859426410B00410AB980C0C6100C3329A3A6281C26101A374913358A0B292E82A2708B38499404809B2610A4803004370C48B26004172E194964C8C4641A966010836D2038224906081BB72001484DE110490838444C168E04B22C0991508336065C028C8A38051AB58182C00951127222100D04082AA4841058085208260A02B62D8A120E14221048440A1423915040900A2792A4B060088411C4402263462ADAA690C1B230501000A0B46C53B45013058D02310E08201091C84C22A750C2A67092464163168C8400110B81901383712185301B1846A310841443408098250C272C944241A2884502130544B644522292D080504BA60484367009B24D19A88424934994A28049B448912864A1C8654B82859330066312661037014A408018189044C40D4B2881A20640D4302C1B964CE1B260442841D8306524090464008963C224C0004992165223C129422691D038318328284C28611AB28880262D0C19525B22608A9228A21890D94252CB408E9B16064BC805E0066C49C225D422691411691C34900C858D1C8449631085083489581666A038680BA250E08461C1266EC9146AC0C03184182EDC16521418910A392C83A68D12296292A66008A510D9C84D2448248398241A4442080848C8962DA110206024519C3011DBC804112251180468E2244E10C40D18372911B78443848D54407064807021B04D0026620045251B838484807019B0040AC928CA80051B214ED4B0498C966CD0962548327254120509988C8A326DC0043163C861C8C2689BB48C5BC02DC3A88D1B166CD8964198340244142CD386440A188A1A46921AB7084C342421910D9A962DCB242292860898A050DA446A19B1058B206E24C481C99840221932110569D3949108A771DBC07002B82883B449A0448A0BB4106102481CA611E3206640B47003B6046048215B21833988DB674A61E7C208DEBE8DAE4119AFB02661A69ABC8BDD245B5D0FB1A26701C9B9C9A8F7D9FCD4C287FF3D608CF258282A1EB29F9304E89C14F3E1CE5612891C602934526006C99B4AA2399BF494BCF8DF61D6DF4C69BC93E02D4995E2F76E9FDA4EF67EB7256CA89A3F38FEB2E9DF6A010DC1C15002FBD456FAE884821A34166B0658A2412595718E149BBC6E220AEE268D4D8218C25F6A957DE5B26CEA7B14CB320D89E1699AD9F2B389C67EF93386A2C65F2C32233367D76AE4AB2ABBD422E98E493DCC3CC5DAF689B65CC4BC3FA51C9C59EEAF0755170C2495804D02A607C5BF887CD86A0389F28FC9725EF46003F13B0187684BEAB1F24A29F5319601F309C91D2A333D1B88DF205A5120C4CFDC2238124E4E2B47D0B5E66A654FE4CCCB078F07CBD455D15D3EEC7DA274D24A2E571884DE41C3A9A4FDB3F6098A172C30968039BD0E4EB3E2FB6D6EEED39E0B6362D54E7B88959869DDD5D873D9652401A29F27A28EA66D32CCB0EF3BF4600F7557EE8D54BF1DAD18F45DDCD4C9ED57B13E445BF122A43F53940389BF8714FFAC721E59317E4B70500AD0D1B9A627054D3193208C774E0B20ED041A8C055E75EECD3738F007158FADDFCA5F43562D636A5ACF3A3983D3CFEBCA10B813F9F6526519199A0313CD1DE13F06AD5386E1E120795FD267B7F42019D84DF6CD1BF91930FCA7AFD52E80700F4CF5CDC38A5F7A5749791C2FDFFC4A10753C24DB19E8EB651C5B363200F0B5D169947026E9F74F012DC7C5B339DD49D261CA1D37F8F28346E61978054F45AEE436DCCBE7BFAFE07CE9A8B83C90A2686FA95402850925C8582BC9B734E4ECA1F7B20B086F129F277A5CBDAA963C92717EF70EC19BF3DBC6DA203AD90F3B13BBC22FBD980BB1B9D3A34452B3357021CE3613584E0936BF1D09420937815E11CC5D5DDB4BF1D830C4F83F30E515921C784D87BB20C09E3C64BDCE9AB1C69FD307EFE359C7F938566C9F2517B063385167E247F31081119BAC6B55A0BDD71425510FFA2ABDFA888376A37F20C2480152BB361634520007C5B34BF22817CB2E67AC1A82670B71F196C89F23BA314B16A948499304EF5C03DCF58E52BE314863E723C56D3AEB340BFF18ABFA20DC03442030230533D9129B83ED22C351F2328172E363447444AE5C6902B792799F544450787119612E9BB4130A33A2A5962AC09D577D6DDC881FE6616126D8A0A7DF2B2253BC8EC4E35386EA5511F0F15887145B6C23AB3D403339E404073ED9C6A896A2F9EC70C44BD2AEC10FC4360E87636BE155B6A67B7EDF38CF73004813C9E7D2C654C2530A71E5F8C10942FB6D8841535AB1DA43E8CB0BB89E78EC91F8DE1531A03665CCD5A75BDA0ED0E59864EEEF51A83FA553AF662AEE00D1F8367B4D5DDDC345544C6BD514F888E6033C255DB650DA734AD33A3CF84BD3F06FA1A7CA02E4B8E993AE7AE63420A46BA8A3813D1E9D2966BB8560D71C62A044EA94179F4EB1B6ED60719D51E0EEF6CD079152F6BE488EC91911C6D3F1D1173C541F9D25BF342FCAA3FF46C18F2A0441D83BDE3546A9826C3496E06F2F2B0EEB9D5BE8739F83A42D3B300E70EE84DFFFB20764A060212F058C8A5FFA9A34E928D6A7E07708FE5393E3017CE470EB9658A74E4951E6FA4854C9E9C28988812E4418A2E832580B4A270372BC69676889D0CC43240EDABC1D3114D8F35AB2E9EA953082E9536279ACB3BE16D3A205F46CB67B221496935AC04292BBFB9A61C0A03EF4C9B6820495F3D80E4A6FB7E1C69903FA226E023E95BA416DF2E5E4541E15DCC000B5E65C9720DAF696012FA2A6CF758ED6D225A3E4FEE45AC5FB48707FAE133D592CFD2E8C43C2126F652BEE9BAB43A1A10BE2411A6794B26CB55CC217EB7B0B146D23F7922D3222AE5EE8C6D38E8399BA51C681B83816FCF74438825920F9CE8A202A8F6D942DA86238FB4C9F2198EA8DFF81C17286E018DF4B7FE3884D1759E4C59BB52617AED4E78E4E7C4E9A36E4E996D32391A34A0DAAAB6B540815A34D20407AEF81949BE67B906950D89BE9F085E99EB5872695173B3EFACAE9455D2B2CD4F710B872CF662B736216B1BBFB1F5F3D486C7B4B875612333F8E4BA933DC79F0EDFD7BAADE2C16F2146A496F79C42A4D6B5239A30DD3C48BEB092CA0750010F69ED4B92320147DBBE208F6E8EB1CF247D21A3A3B01DF58C0AA62944DA0EF0450E8CE48AA137E7E1516C1D5C86EEA17FDFAC1690746E7267045A3E90596BDB75D50B6DD5C34E5C8D89DC6F2F1D24440E57B4759B8625F72BC4A7B10D519D331F9C400AAE1E50D480CAAE5A1C0FA99D77924CF8DFE56CD7092E7B9" - }, - { - "tcId": 2, - "deferred": false, - "seed": "D6A5D2325B94CA1B993A0151E24AB95B396F415831DC14A08404820AE58A2AD1", - "pk": "EB7D0B421F280C78141464ED90C7CBF20D0E34F5DDCCB7464E7209C109B1F3A7C19946647A330D65E7C2A4626515306060BA6D293ABC2505D2FD8C2BEB94A5E3F410C45F997FCC70A48BDDAB67EBE3D4DFFC2884CA63B9E4061D1C5D0520464A0C4FA59544EC3230FFFA002349E4DF045D3C52F9ECB0B7F6ABDC52E8366FE6077C858C3E29B7CBB6AED2CB68279885964C5598D642B07DDE597A1404FF7F67F301B2C3BAC1C841926DA3B2A43493D399D0A85F868DDB1DF6802A3E487C0E4AF65E6DC82865EAC02DE8AEB7273D0A7A2472E6B59337AE95F824CA107734EF25B325CC123DD3945C706446E3C549045E3476670D8D673A9178D2A80F72F36FB01B513463A5E8EFC7985280140A43E2BCA8728B5F943A34553E12E2C29F4F04856BE5D6CE0DE8CF2A9560CE2B96AB3042AA8DFAFF5AEE292049A8AF15A2290968476A1F69DE8F32363DFA2F6E8CDDD6330881777C9F6C8AC41B549EEFAAC017BF60C3461F3FDEC8A2BBC971F8F7E3F57E82B66317DECCAE3F67641DEDAF0FE4F6144E6D6ACC8A4EAFDE1FC3046CCA680E1CF4A695E477AC91436866145E13C885488DF5E33363A9E3727390291F6E7678ADA974CAF1220621EF292FF7B62D6178E3EA43552478E1F2F626DBB0F893FA777DB7948F14AE60C418C12CC67B1CFEBC45A5752DF0E1420F69FCC4469D77942D484554F5EAC70E43229C2DD7363B46B58204ACB208B857735860CBD22270C787CA7072555FD8AA218BD258B976A529C9DE8DED6E24265F5D5DE9C43762A74E1810656058609766DDAD25FBD72B8E8C1ED058E1F124D8DD85F04A2437302CA6CF5250FA29849D54BB077ABD356D0769ED1AEED8A2535C3C6CD15FD8EF66F12DD381D62B1909235EEF975FEB1C40B7F8EB8D8A0B4A129918719993E813681D43AB52F8FEB68028DBEBEAD015AAC4EC989BF1563BAD3D7E2EDFF0D8BA6A5EF1BAE0D11BF5F1FDC2CEB4EA464A21D53E6287F56675B8E7FD881E4005CDDAC618B57423B6F6FE8CE8E57D6370A15ABF168B8A1EEB044C0D05D9DCCF1C9D6DAC6E8FD155C49CD1B509F450518A724D18AC502C869D6055CDCD280423FE8CAEAEFE572C0D12D31BC3A75BF4DA4A2A3753731CFF7216E2AF2E1DCEA6E2FDCDD9293B1E256B1A50B11F2E59B0CC701E433FDB7DA4A266746EBF395CA233A5A4C4F3C3782018DB5D1E338C7F92846953D24658D15F92B656F42A4A1C5CA46ABB6666E1B415798D33BB0930C6C3411FFA4E3ADD1C3289479913586F2C516E35426A76DDD5FC78332011F436D0B7D278E7082824EE4CACF42E13A84C39B2894FA8A2B97A579F22B35A601E49977AF381DC47231889532EFD3A890E207BD1F6A32CFD46546D33B0E80DF177D851A09D727A681969B97AC4D06EA17CA878E264ACA0A343F86444383D1DD18176AD6FF52B6172888F71CEC1F21F091581B0AF7A0AF7E84A4D24636BCF4D47BB53DC19E19FBD42468CA1B1AA85C48EB886F272836193F65A13A5002DBC6C37D74217B8DF0B0D02E4932C949EBEC293BF7AF4EE88A4C8A9509529353EE35EFD12B3B8B49EF6C70C71FC14DB7E716E72A5AFC550721DAA26F5201E6C7DB1DBA04CA89B0BCA48127D007982FE304780B8FC024681CFE373A879ADED69BFCF9BE8E0BF936DF636F74CC1B0722A61B2D9F1661245386B4CB7897084EF8D154E2AA05FC909FF699C4B1F563476DD93909B8EFEB20F875A90708B84E9373B39D34041179055752E31682714F30653DE5D9E0DE9D13738E00CE99B91DD2286FE3A675DBE7D4AB9F13124D5991097A5D2EED97DF2CB39F82909DADD36C72F734D0022D9301B42FC386DF483AA2443AEBA", - "sk": "EB7D0B421F280C78141464ED90C7CBF20D0E34F5DDCCB7464E7209C109B1F3A778BB75F600752B1F5E36CD984C52A42319B2C26D05FFC9906A5FAE6EA550CC712A1DE8F8854EB8E3DF5E36EA60369427D39CC2CE622FBA3654DBB125207AE448262E499F9C216575393AA8EAF8BC8B845F3510A492A8158460295046E7257531821684649489D04021194606032860D1A689DB100A50202611402C201744214981A11224C9882023B19180B048E3906D1A0144C31685249561C03052438631414470E34022A448098A2040028061A43041CA848421084E4084410BC35199340C90C0118BA8401CB78461244002B509402029C18604C424429B24720A0422C3C0700448501BA200D2168E12148E6490098A18428A466924483222996043284804C11198463151A408A4A861D31605DB8851A2040288B80C50B605202188502882043688421424DC800501A96C19336CE0426C02194EC3C6294B8885900665D84688C2123018B43013166D5300720A4968E0C22424411014856C8A3428984064CBB868989611C2A0088A288A89960548440D0A908D02328E9C14926410400348102311815B36688A9060594464228230C01470D208840BA160C3344E8A16640AB420D006121325802344505A24410015880A030E80988D60C60824C50DA20828142969034848CA984503B5040BC66904278EC8A6415C0084A1106D21134D2493854A46494B02658BA409C44221E2B20561443113481290148CC1284249C43091104122032AA3802CA2386C819484829431133045583649444086092706D8382183144A14298988842D1AA2714CC005E0B26C60204041A07008C2648132729914001A368D12C82052A42980242C9C1825C4C820C28801C3342CE3263010B604C4200952401109295049A22CCB0064C0C680CB189041B269E20420A1486AC4126E61226100392C1B371004030902056C0CC391111289543641D2A48812A92C82A00C4CA46819202652068C802688DCC485D9B28C931865C086851A072663A4240B176920128450C04408B80D1B198490123023426242B808140001512250D3280619140AA044641C418A92300914065109012013125298382CE3A44808300D4426426210010423320B2501CB9630591660804621844402DB9480C1A26448C690A0260123B900A3A0881A82210A424A1C377012A281DC8048502464989401CC020901B848C23022C3B44D60246AD3182A1430321905308A32321017521B492E00C0889A043F9965001E620A4774CEA00A5ED582E80D386F8C90D481B5B078A1C88F4AD8D1530BAB2BA08EF807674CF1680898E5A9B675B606D20634492E3F89C547C80A98D461CCB8A141189017166846778A62C4B55EED13D7E4DF1DA69413D4D24761B1438D94ABE3D86EC049B8877E5A85DC47D95478345D3ECB6093FF46D1061A6B054DC2AA2770878C236ECE4067B2BE4EEA132CB66ACE9BC3B07824B450A80104E644C57006A6ABE36B31E3BBD99BFBA8DC4487FBBD5161DB7E6F425F17E9E48290414E9989C174AB03864F53E18CF3034A62E2DF49AEC61AD291F0266F66D2E47DD89597F1354B0628D71A376A91C80C2A58AF83D9D96DB8430DE3474EF2490CD9D9EDC43EDBAF8E4B2486A4BDF207A026465ABF2E801972028ABFB891383538DE67E49871AF6BDDBDB3414833D3D556377D57F673387C496EDA35A6FB932657EDD54CE4A6A208750036E3EE66B2CC5ADA490B272E6108CEE4D55DF40EDCBC551D399A6399D7FB4386ADF1A026B32F5D0999206077A29AF7AA363FD28753E0A251002E7D130E2A311B4F2EB87F9B4D3507A06AB5203C4A5DCA9778ADD29FF0DDAFC0B6666CC7DE112436AADAF6E23A5BDE29C4D967400EE165E162F4508B1B9B348A8E39A776D4C17571E746C14210C100246F6E88DCB0335121786F63C9398241F164715C262565E5E83B762401659C03236FCE692C49BC021851B299ADF0A5569AC4B37AD08BF37222188E9E0214DD882D8D4E20E99F4F37C1B8BD71B853FBADA6F79F144FB8213D3070B5674821DA6C0F6AD69C40D37DFAACADDBB79DB5EAAF11FB5E1CC59843DE671CAA2573D918FF146E9EC3A0317E8E81DC341439A516B0D43D6B1424B520E40B7E0706DA7F41CC4E4FA78698C83B3994F63507162533E4FA95F2E3305A78662D2519FE4DCA125A466868ED723BE984FC9007F523E3B57FE4DDD0D90D7B62314BAAAE78CB758C58B13CC1E137895A1460A5B7C2BAB639F58378166F7AD95C83729E320CF8968EEFF4DDD2ED2805DCD2C0245C0EA55B45DC0F50A275DF3A04619ACD5FE15758EDFAAA0C404C102E06AC0B99F5FC623D8A8E90EAFB305FAF0FBFE9B111CCFDFF028EBE871217F2DA0560BEB4DF17D42844B998F9B729B2CFFC340805C00C8329BEA4C59AC517575ED579F6A658594C8E74F0697D9DBE65CAB408C8F9F8DD50A202BB7F1F43B711AE59D8467793231929225EA4CB0A0AECC44D1C83DCE4CD3AD8C82B2E5CBBBE3C9ED9623F099F719FBB9D183D97FCF74C37ED6C1D3C9582E9030DC758D6EEEEE85228DB8BCE9F5EEA677391D124F404DD3231EC24B94AF9F62ED98B9DC912AB28BC4B9A76422F325D34D022668E48EF35F5EAA6F41EA9F0DF5B0D65442E8EB747D38BCC7F611766B3C770AD55192BAC8AE72F64B10F0FFFF026A89EE6657EC2857FBAABE2A6B76ECDEA53E069346869E800E43FC80FE915D070FA21234F50E92561538DD98086AE91515334BE5C0222B584060251316F75AFC064248A40E340DE80DF4C51FBE87CA18A6EDD34A45326CED1731BF44214FDD6D3EE1D257743A2E8738CAA8FEF6754F872B85EECD6519C101BD1ADBF1D84519FF4FEA87B5E6575E395F87A7DF7C45B8C1E854D712C3D73F2314D014BCC5DA3C703A058BFDC6A6D5E04B290C280328E93C40A3F27F167C5E0AEF523105066D38DDB4E7D6644AC801714FA2DD38B26D94D43BA606AFFADB0013ED5979150BE632D8C0BB2DBBB33022B095CD47EBA3BC0C152F8F9D6D8B800CDC424D6E9F9970329866D6B8A527C866C10CC8DC838A4360FE7E3243BCCFE16871A9129D8CA6FAEC779984F704335DFA1EA06BA330BB6178BFC835E63B41EF86D2866779DBC0D09922B4CDCC4489F9964E6114C094C70A92037020D56DB6D76477C5F74AD45C7FEB713BBF4AF218AED20D2FDE1B237005A97B2AC8BFDB0E4795005197932AFC0F93A7404928BD61F9989C27D9AE6EB67CC47CEF3F69883557115DA47DCAF63A76BE3353583D96DDE5982D91D5C15517B43D2EDCF63F7E7B6C8339B11CA09083B4A7EBB949F69ECEDD4A9E2258C44304AD1EC0996D1916893BFF788E97F3BC5E6640E1273A34DC0CBD0D71CDE2C793AE4813E096C0E1396004C0D5658E321153E5D27255ADD883F5849CF9F3F05833D387E813AC1D9B1B29249BA046136C2A3F3D00A1E8BF1626AE3760A5EABF781394DE154315043F7109A995C10F2C0A486CF81C84132C3D5CC02F87D3BC50965E4B088B4AAFA52B3386AE7F6CB5CD967B40F2B54177FF9AE38CC9AC4F8E6478E94F8697382FBF22D0BA389D24A0FD13EC48613409C7AA6E14FFAEEC9C7302175E73E559910" - }, - { - "tcId": 3, - "deferred": false, - "seed": "8A5E79B82DC81553BBE821EE367F0ADFA54F59A3E8A71CA626F873F638636DD7", - "pk": "B8DA2BE5527FE7006B0B4B5B4D90FAF13696C1140701F142E38A7798CCE6B3BB49A293AF090BD3D65EAABA535E8F7F1B73F93FF9B6B651CD42ECDE51904BFD1FCA2E301CCD8D171968E656FB3EEE14F7E2F2EEC4C8D6D66A073DD3E7E56D34B31A07D73F8A5A2002DFD412391F8E5008A96325365BAD17E7F48780F5C500D0E84B6658BA53E70BF7046FDE7515123EBA61E6207380D1296337EF8392CEE6C423F63AB79935F709104B966477A5E73298DBCFABB746F48B8462EECE2E5282C548F49A43DF33BFD5EB150B79732F26B5A9396E5A83092939272EF4C965E293DEFD1B595F1526EC9C276CA444D823CF9D7D154BAABBE5E9BE7BD3FD7E5E406D6585DD6C57D52911AD52B855A3B85F7BA070CAC6AA2673991A86A866B3CA0C2DAC40D59A986D9BB06B3900456EE931B528610805C568B889F815F91AE0420981F6A3620DE77341487B8C9358261ED5218473DC2D14421B8964C2C6A8D84E72BB60FD8AD658B9F8A4AF9651F44E5D11F22155D80D8CDA88E33AF0E2E4E7EC12CD9DF71C1DBA6B275A8F897BF184CA1C0016B6B41E62E5F551E90ACA7A4075187B856C7B01393917F695BC033EB35A91F2E6DB877966D85CD0ED99C8CD96CABADEF069977F3B08C0DE647F458FA032C6FAEC523FEB5B5D6A0EAA34A541D8CC015AB698B6C0B5A6D312B45CE5F1868BBB8F9E54B2ED1DC039B72CCCBB828B3299FE381453C4DEDD63CB800AA9E2484EE34C6A97F636E2A3D33EF0F8FCB13704CCA940D4D1B1BA4201C74A4D4694381E0C8827F2683296DC8A194AD8DD58FF4059BE3D50637DD20026E38222900E4F09A2E3291E0651EF1A405BC88B46BBFFA0C367879D7711B661D6AA0ADD9A23B45442BB83D68E4AF3F77AAFDD2CED9BC2E571DA147F8104AFC933A661A6AD6F4CF53AB687158FA1231BB151B163FCB79EC996506EC5E0D7112ABF3F30E2CA7249006D9878E1B44D93030DA9B90567FBEA8036E5A81AD541F9DD65EC39CDCD81DAB7AF9706A0D68B4C22DC73797F4A5B5483FFCC7CAED4A7B60225833786115748B20B0D7C99FEAB95C5A222D6EE59D7FE44960DB17A0E64460D11B3538284827C8FC1538186FB32A2EFBAA005D052D3226CEE46BDD1A2EE3E8BCCE9711349FD17549ABC566263D232D229FEF5D75389B4892AE4A43AD933F4C51B2A1975794903477048D18BB4B95FD8F5A085579BCF79BAD56323D72C3E426F1C006E9723B27D738C2A36F458153801FBA831DFF85CD1F28E9ADD4A47F019E4C8AEEE5ADFAFC545F7330C6E63ED73584EB63657E6E721A981DC293B68DCA16D43640F3C27ABA5F65E78816A8EB840BC07F12CF5E349CFA21455E7CBCEE6CF58A06C63ED5FE33C8537C9F358114E75A5F2059896F4A3A6923373F76DAED2170B63EFC59EF772E509A61D939864F2FE61817D5F0E48170DFC62BBDAFA50F21CC54E68A3AB1B3D8F5F043EB40FA27DD59447728D07AA38766824CD44E4249A75A609DCFE1B5A1482AFBB54C6ED69027261E4B405D801E06F5C8E51E0B28E67925EF919EB960A63E47417C5427001365470CFCAF2EB2DC52383B3025B36F53FD8996C89507D08338953D52F335888609D2AB7E6ABB402EF6CA91D41FEF1681AD90ECDFCCD67635B104E8EEBD8DE18BFBD45007F6F902CC581EE42C4ADECDAFE9EA46ECF29D764F7AB9778FB08F8CB737DF9BEEDC33CA27C40E41580D9F602A7C9C21F5FA1D2CF048FAA99EDED4E45C431BF302F6398E878730F9A1FEF92D65D15615B42D52935F8EFDC88DB2F468AAB03D2A4B2EF1729B755D5E47EA318DFB99F136F173B465B665B3D16CAC577A0E09B1B604CEE0FD3FE72720F01FD5B", - "sk": "B8DA2BE5527FE7006B0B4B5B4D90FAF13696C1140701F142E38A7798CCE6B3BB96BBBA1E6D12FFFD30F9A9C2589D5FD180D8DD5E08E5202C7C11BC2FE76A1B208E092FCD18D1F821048509579B8C6846CA5E79E7C37C316C63680E49971CC591F379D2F2C23BD456BDDDEF5DE5BF759679C028894EA834B7A4586D6F942306F7E3102DD210400A138E88C4691CA4292403110C356522892C4820010B446AD9422C23C469614430138411CA466112B32C4C1882C2B80D0A9808CCA60180904D8BA03010C364181972DA362113396240068500080C1A328920316CA0B22851B68008330920C74DE00251583225493270D3868C191550C0320411094424C148222282A4940888280041C88804B96951A42554088D19A28058287060084E1B142E18070142480103028DC04652C3B84D110689CA163024002999426900C8451A252DE2082881826090C2655C44329B46665C180411240AA2A029E3068591A225138984E3001059A02D90128C90A828188910141744D426692330602399200238449014659244104C80708C908563329282086698386C214612030351922465539861A3464923374C40A024CB302011A06191900959C08C98426082428908204C1BB865D8987054844922C9409892040A832D2497254CA48D9A149164A40111864D9A2420482200A3363221C2300C178600B40411344E14A0111CA0414A8628212570420229D040291AC824501208602265CB0445D8B2111923621226694A48459B200DE3860182B004D0A0881BC20949306522403190388EE14028114102093465C41000DA182140A825238484133329140540248281E4B0091A43005402421A3986D04244D8B66154249011A1510936500C150C5880645B1669E3226A141782C3C631A41208A2060850988861986DC828665A322250C061203144042624DB364DD42421429631C08469100205DCB06C8A926981024140A0418B08886330409AB6498B0871E14890D9126A81344122479113024509044EE0968D0012859C380164024099C24540340E12C90910B441219825048581232430118829D9B228A3405244402EDAB6899AB408C9C890628480DB988803B488000865C992280342629CC231A1086C0BB82482189064B82118148803172540B430642811A1306610A70DC4828C8AC4491A322414042291B2011A4446C3987148246911246688908D58302C51B00DDA0261644049DAC201908240CA284D14434D41C82D6338309B866063C22C4F95BD47990D818D83D34D9E2413EEA5D4CE2063803CD299EC3DB1940FA7C362AEEE74D070A0CE30B49DA164FB45FA28C20B5BE74843D2F0BBABEEA745C6C2A88D78850C9DE6BEACE80BC467F82A79D189F7B01A7C602F719BE9FB3AABE740B4F8D070B7EF8D43201AFF4EF853A8D47A172C7E49809CEA38C9A66564F86EF038C8B249047E62F1850A9606AF632FF357F9E23F427DE017978EE1C1C1FB8B0CF5B1DCEC63CD8491F7377C77FA3F39BD882451241D172540CA7CB4E68D7662D381EA574ADC69F817865B094CE2D363F1E20B3EEDA731E25761EB3E4586A1B1610FDE20596C289657D9E0D5294CAD3058C7FEE81DC7D7E0E4475A6013312179B4937C4DD42D443C00B0F4B5B8D08548463A9E1E6ECC55127504E22C97FCDE23B06CAB37A1641FE7418AF904A6FFC432DE4631AC47EF61B57993F928C0F37414BDA2D9148B92B187260D482D9E6F22D367814E604BDA54582E67A47216DE32780D53AC49FF9418F4DE6306CBAA77E27E8FBA6FBFAF434F2A5046747F4DA99EC4CAC04957760EFCC3E2D0C8177437EDB18A02446497CB3984986E0596ABA332BB9ED7066477C7F72F205243E27A4F2BA03D35A813087D544003CB044B66B8FED49E4AAD43FE1C485EE402B288016632349997B7918AC7B5ADC35D8B37E73DAE39C4FEA2AB1C272208730CA52508D5FCD1ACADD0CF6ACC9DB0A52887ECED72BAA737C104F0F113D579EEC6D30F7BCA85348A6E5CD188346B65775C17F7AB26B8DC98A04CCB70EC4ADEE998C183B28664EE588DC56D0E979EB9DD0FC924543442E420FF82A89BC9AB5F4746326D930ABA8B255D14218F3DBD6E73BD175E4DF17419EAA96AEC8AED6E177E7DE0872930FB6C6676F3AA1428496A8166E932A8E5652BA5DA33ECDE76A06E850FFD7732C26D1255C21B96E0C7753200D4B3BADA9B44947CC80365F5FEA14C27D150258D0092E433B806B6F113B6C99AE58D1D1A810E4D0C1053C2F7064D7188DCE620B2CD2E237959FB0C535DAF42077E792EEED6FA140A8C7B94CC263624AA42640439792DA2F9EDD6E7F0D3A8CE9A1B27E788B8CE7F766FA078EC5170564CD7030C51C5DF95E98575881F48BAAE04348DCE9C226DAE0DFBC65CD3A966A2468D588C26EEA83AC20DA0180B6973D1E93A58BA1D52B59F86872D41353D5A02830C48D93757DCEECEC1C3CBD493B8298EDB5EDF0E0BA8EDB3740337A7BBB29E4E0BA3217B650211A93DD6DEEDCDA76AFE119817D3A1244C01CE8C5F5DC3E093CCDB0092F2C61DAC20D62E0E2B178950C09B3DE26B9FE54A4A8C3CC8CD5DB06E2BBEDF305BE910132CC11668591BBD93F4DB3EB142FA655DB1DD175208D39F200BF07006D50C84333FE0A0958C472A391F65003CE642FD282A592EC1FD02870A90C2A3D1A4409B818DAA8059FED19A6FC3DEE29D3CD7AF8A14050967202CF6F19A82384645BF182315A5544361BE84D477A36AF3448885BC09AD975CBD1094DAA8AEAF9E315563ED5B2A24C551C771E0C3399EF9B94A08EC4C55A1D9CC6DCDD01D7D00C7D44B7B7C8840263D6C85AC5D632ACDA4B919EEA53929CE86D7538772DE028408E555C2417180869A061F6137F6E8B95127A25ABEE16FE1484E6C139CABC5553DA4FC024E89B259359656B2F29EE21A0CF159DE30EF7690E27716167292CA76509A48B3A19639B30647778A6262760BB276EEE3BBA8F4CC4EA47F705B85A7EF0936FA8CD6329D223B60F32EA7CAAA5F271E65C1E04D884983D57A271E39F907CC5162A48CEBFCF0DB08399A6EF2A39CBBFACD2A266EB88FA699530572EB06002A0A42AD05608B592B83BECB526D650ACCE51B1862DBB5B4F62D489C02FAA95F6EFD55BB3C8D522317EF28ABCEF7A418824B9BE8AAA28533F93FF075E512E0460156B4F6EFF87CE7C021C18D4C7307CA35F6BBAE5D5C0EC7D2BE496FA3B1E523EEA57BF97F15549F541CE042631BE5162CB27DF5E82D892A7AB96AD48304D4893D8C6B0C2ACE3216F026C9F25EC16166207C1A3166C4A3B1BA89B62A8456EC4F7886D2C7CF6A262F2DBD3C6F82337142D4EC52DD419EE9FDFC42BB9BDD99CA169AEBD68A38E0F6A32D47FA94CEBA5DF11D0218EAD68D40AD2BF597FD2FA7E01428246170DCDE96215E27B4598B53EF6C51A7A7418E47FE378AEDA2CB16A42F663432C23C514AE25B52FECCAF7516715269FA5831FAE49E935643F552521D1579DB8F066F929485D1451CEB659306F7E0BAA1FB1ED36B00D180E838FAFCD42A1697A70C849E3E9B81F5864EF290F27A5C9C4064854B9CDC30119A028A5A631A3FCDC5BCF30DA8EBDEDFBCD9D9A52207C8B3F5109EA0479F" - }, - { - "tcId": 4, - "deferred": false, - "seed": "6137CAB1DBF57A5CFCD0079BA87FAF2C7141EBB92DABBD45FD8B478D24AB8946", - "pk": "0A8EF5018588CFB167C4B2E537A7B1E27B7E45391678942515986E2344D0101D116A9201D6CCCB5360C8C603D8ADB7F0141C25FE7253A77913E3AED199FF230ADC79187E9ABFCD5E08BB7C66BCC1BC310A3607F1736520C26C0630226C1AB0227EE8B9C9F657FA1EA090DAF837C91BB0C4BC3DAFFE1ADE030F1138605613C2BEE98A945DBF68AEBE54577D9C33AB99FB8151246585C4A3221CA1EB9717E8B685CE184D6820AAABB578AD384AEBF528E9E3D82D624E5ACDCBC3C68365CCC5D1499DD939E70ADBCE17B65C9B81A13428C1D8D20BDB1082103516186AB6922CD12D2C6686055AA97489A50CCD1F7351116FE06E6FC4F4C1B8A89F5D4E9B17C16351B6AEEE0A23E87F9CB009A1078C192659C49B7C99B1C7C74EE61BC4A80AE2FD5203AD0CEE5B54AD9C46411EC466CAE10BBDEDF6C2937E33D2E548EB6AF9DE3B0E427EDDCA94EBB0263A7273E37F53610062CFF9B3D079966F0C0BEC254CBC946DB18B91E7DA2A9DD0551A1D68FEB9A29D7A3233A51D5734262294E65C5BF32E2CEF75C26D693DE0A5A3BBB5DBC6DBF861E05E17962889D57A3AD0E21C1733FB0D01CD102F38337DADA0E6F612BC1C686D19B89FAD583D580F088248A672670E8948FE00794C17A47BAAA69B8142F7BD5F8823DDF05FD2A8F113FEAD12483C3CAF1D5217529450047AF883C1F63EF9DE56C41B7BB135FF040DAA9DE92905FA33AB2A18DBB01ACD22D862EFF06CD30DA86447578FE01CCE6BDD79F4AC7F0B0F0A7F1559D1CDF558BFC1124E77BF3358D8DBC465BCFDF67C5198A374E14CAED306489E6AB16AFB37BCF477C0A4E256AE502B25A28659ED776B55581440C466C586C3C3F95EA97852B6E334036986487BAA1B470228D817A64BDE3C1FEFFFA1BBB24E6A4216E7B06A2AF20D3F5AA3392DAC5D3D69C75D110706C90279FD2ECD68A2E5F9E7F20601D176CA30CDB09D982B239C55798BFE7F3DC9DEAFC2C5A7BAC89F25876BCCBA09C0E74D63F63819B2E5D3DADD7AE806B1B4A498348124D1BD6AE50CB6F32F12CE1667FF49D84ED9C7204D710984778E675664565C6A0613AFAA47A8E5925934C0D834BAF464E65F209AB782B87E2018D33BC686528337D180B7AE8BC95BAD170FEC9BCB878CA1D87E1B7980D0EE3F293AF7E4FBFC3FC6A46E7E69F879B396F41102B4546808389F22D20A472D5CB7C5E42FE6A6A4C0ACE61FB01BB6E85BD11CDA18381BA81684ED73D9491DF1B7EFE73A95CD8637AB28953CD0AB07BAA3770A372D664E60BB9765D8FAD605D7FFF0445AF8D4A9107324BC4DCBB8C4428CE7EA3DDE72B3F6E0FE3DD70EDEA33D8B794FF5EA1AE63633DD55626BBFF79978544CD15330F391985E02168D0D9031568484B724B313A1494EE3727E6AB0711F8AF74A1882737AE9873AC1F2A7C8F9A79876C2B49FCC217D6F1585B26C85843D1C7F4C295B7377EEFF1EC814ADC3F9067B2D3892E5CBEEE5D704BB5EF70A5561A751DBBD6C8B1C5169A9FC72819484D6F40533181F2853BF1696B080708940C936B1327EAA593FC27CE0ECB8936443920F818C393F7A27913EB9B5F8E1EC722D159ABCBFB04E6650C9D8E2A91FFFBEE965167D829F598EF1CE3D48AED0F5EF6AA70BDCC775CF00A901AFAEB2E0CF1AE0A6E41E8ECCE9D64722DA713135C193A8A91D2514B1C542BC0D86DD7D1623A1CCCA548142D5F93AA2B5BD35E0D3322D126E245C802E9E508AE531F7828B55ED6FA81F8236F3D97F7AD05ABA04C6FDFD98CF974E7A738090B2875742E84202F803316DC71B8364655062D67C62980E17396FAFA25E95BE5BB611D5DADC3E418AC4B2D471F3A0F8FF7DE57D1154A56D", - "sk": "0A8EF5018588CFB167C4B2E537A7B1E27B7E45391678942515986E2344D0101DB66137ECD5C61F7FEE7356B01237421B366F4E40ABC87E91E8A99B0C90858E55000F395D2BE88DDE694C04D10B5407A5754993ED3C59D8E530754D66108BCCBCBF3C3BF6E965DB72595249B482547BE56E8D79DC375851EB3F6A18544585146E0C42720BB55163800DA33851213264CC94118A104003150453880D034431244150D9C4710BB12599B244C928288248304B0628C0086D19254E0149310A0341222225999604D3004490362C21915001176511442D6032460CB000D4A8288B822CA29648402806CC3832E236011B230E040272C2B4691AB291132605E1A80093A048DC220604140C49460D002226DB1060C342498A3266CC36201834018B461262A8709B288C942652E4080C838884C220419B38290B147023C84D4318880AC9051434801CA200A2C82D89B64D0C488589828419C761C044510381054320329006109BA88C8084314124310CA04823A2305C988D21474C59040588A004D2388ACA420D0AA368D32092E38201E43811542271924666C4A441022181D3028D0C366609B590894409D04802591249D2B884081644C9283092266A9392285204440C234649C221E2C04190C8105AA62800438813C8011803894B30726240116124682226325880258102928AC6854C4811E1980523C868E3480024026180B27112414548028CE4100CE186281A85050B498083B4890383652445611BB880148491CA1485638249CAC48C9A46268A14884C3645E2984501384499164C13224D831092C9B0700B0101A1184E8B326C1C49865A328221441293A40D02056609B44DD2A245E4C62C501841131011D0A22154000A0C880509448C0432720142682448209A26824A42024C144421C848142766CCB02D04C065441265CA882D23B880810464092831D3962D64220C00C9851CA561D4420544983114862892340801498D21B128A4368448B48C18900450B6490939490497894AA25101464A91B20C0C232E93440A9B804548886153B830044831DBC469A4C4519004504CA86920108D60286CCBB045DA3688C82029A384292211060BC244D4248562082A49A221D1184413B109E2C6108B0408138001E44471103000CC120A00234E90322661A028D216710A498543884063486DD0000C8990690C9248D284008204611B4649644050D9286818091151A66C80264608144DD44088049220E2C611492868D48210DB042124C0404C1723C8FB9AE08581D3EB7AB76CF8C3E81B6A07B3CB9122962BD278FF1ADFC7B64A9BE0F847C2567BAED7F0E9CC8C847F81131152B065E571B57300917845264B0F74A4F1307445A0CC7D959DC701556841916A686F6B018BA13DC71B024FC78BDBF7A3C7A8AED43147B4E2848D0A3EEF92BA31543C805D0A1A7856E0CDCDC5E16C5520FCF39811A473D687A129158533BFF01C2E0D224E074AC452F292BE137715CDB8E2642797146DA5454E04D61D24113D658FCB42309E181B33D57ACAF78D9B56FA9C33A77DE2BDAA227B2FB815EB39FFF8B5EF175E786E94F2A6F66C0D3B68BB4B8A28998E1150BE49FD46773D7C067751BDD27EB7294CD5F746D8251DA046F325062218EDEF9AB1B0B15730B97584D096A09175801088DB9C258FCF490399C5A7B61D3B61E94BB41059C543C904A3112CC158DC3EE7DBA410038CB92D02CB13B55E21CE176E9F7CCBACF60B37C633A5C29C049442050DDD4029A1FCCDD30CB21A740D134536E350ADA4CC4684EA4C0A5C2E141A7A377190F817AF1F88C7DC2A068CC86C4B58415DC621CCD4B7EAACCFCDEFBAC22CAD45592356505A80283B86E8A92BD2307F7F854A5291D3DB4DDF4A4F367B819CB21102B6E310231BBFD1FBCD5BFEAF30EFAB540C5C37F0D5528A21E09526F9BC1AE6D1EAE4E24B8A7F79480943DFD794623AEA0393BB227FAB291DB470DDD0798B223E60B5D712B1842699EA167ED89CD62C091DE95D95BCF4CAE6C066C538F280CA8ECF7F4B38C8A44E90A25CB0A0E463E28B7B26682F1F2E1573E2E829F00086F75E4F53396127A60ABE16AF1679DE3099FEFE542889C4293E6E915CC2595049E438DB70ADA6587F041A9AE4B23E4D63605B56FB835C219DCBD2D76FD92AB4B123F997B8A790986C24A80A797F998D2BD663C167104DCD4CF0FAE750813C371F35F1CD138FE57EDABCC63C044300699D4506A28962FF0A6A66FEDB79E3F841AD58CE1C3B085162BC500C3E11FAB50AB0D1B02A98FC032E46AFE3DC20BF8A27D44E5FCD177123AAF3730A414699CC9D405B216D4CC6987100F2619946254F23D4E8E6417B32D0622C6BCEF586A44856EA72BB10035ED9BC8F54FA0BF6E6B7B56EE903D123D764674690CF92083B0265F0B71D6552F4130D8C086B079FDB62E9A390BA6824E611418592B51A5114BCA7601A9EB7302B35889533F2DDF8AE6EE315446C33DCD79CDF102285164DDBF3DC1DC14407D4CA7D594D397716D1A421AD444837A891D45FE2BDD58DF86B24724AE9C06070DEA7B13B6108154306BEA4810DC59719BEF6D189DFA4974AC39E64C6B37D3F2DC7621CB64DA44E514097B1F81DB5876C22C8B8917047EB32DFCE40DA9E45C67B50BB40B48665AE46FC306093EADCF46D6DFCA58A3026341F22BED8218E4EF3567844F2E100608F78A7BEF7780DE849B5BB6BE654AF024FC3566EF46CDDE83535C2CC539930BBD71F10163A7D9BE0DFD5712F93298E7F4377F749A847F2661EE8C34D18C59EB96DC49915907CDD4C691DB88D5E4CA3955B37AD6ABE539F17FFC0F7F306EE1EA809CCFFEDE766D756B6BE6B9CFC9B8549B0A385DF1F84D4661BD1E3028CF47C55E80F0CC33D316DFFA893B5D23B8DEB75A2232B124606FFB6E955608CDCE69E9B6EEEE660AD9AB3FB5F246342AD634848922716CC8DA15CCA183D7B17A76FC2F4F4B27102134F16AD98BEF6D13E2EF43C0E76ABDC5B5C57F23919FD3A2648C3315D0B6496EBD5715E7EA516803035D47C6998CBD102B28829AC2E9EAC2B739B71EAD831790E8E94555C5C05D34F9004C48A9AE1C48853F6ED1F659FA34EC6BFC116A37789198B64B063EA07D45DAB701FBEDEA33197143FD94D6B994002AE87D68836F7F4366DF3F10467514C36AD8D447B65FBB42715920ABC5C92C1CF329D245EDCE007E8F682A6EB30558FF3E03E6A5882900AAA3BB53899DE10E190299450E3187662074402CA9B5E8CB0F975E2B7A617C8C913C516F90A72DC5C3229783E1D4D6CB371976C52D4C998FE8FE8F376AFD83D7DBC2DD34E6603C9331452C4DC61EC8187082422E18C5B92F6B31E9F6F6F6991FF48BA8199BDEB3BF03379A5C5AC609A9111405C9E30AF475458F7F1F949E3002DC40287BE3BA70F5F9BBB2F0308F462DDA59E3D083BDF28446ED29EEB760C75494DFEA1E4241E76E60B4861503E281C898C0F44C7CE9ECB45BA41DEF7EAC785A6CA9073F639D7435A8EFDC6744CBA2F3772CE3E3383AB8EED5D0000698C002B269C9268C459B53DE9128A70A5549628A026FB80576F5FD99665A400A693AB05531177EF58FF962B961CF6ABA2C53782DDECD67ADF29142B3D6F34" - }, - { - "tcId": 5, - "deferred": false, - "seed": "B9E2F48349350D30A5342783C915A608C905E0DA4BEBE2067FB62C714207C62B", - "pk": "F9D6A3AF1217A15071BE92BE929BC3E6997BB8A2B75E7EBFF3E7E27735D8625ADBC63933DF6244EE6272759636370731F21C2892D94695A7DEF28F5C17CAC25FB09B253E2AE787630CBCB8EB255EC2F3E4F8C5BD48B75C50C829CEA6C289535DD500843CBFED5600D1764CF8E624E9CBFB4731FADD11C063E521610BBC656B4E19678611C32FE3F583D8FEC7D7A9155DCB999FD4DCDCC47CF45C35ABBE829795C31194662EC28EC54DA469188EE1A8520FDB60A2CCAE5460E0BF5FD999764C21FA1C501AAB111666118F356DFE4F92C05DD73F143225389DF6839E11F7FF7112B22F4B5A04913280B4B151B532A4CA71981F79E1134C353760A8CB4605018C6B69741E5431296213544F26D3951D3AA1299550C0AC23DDD5422DAD7A0C43CEBACF6750FE211C3F10958ED0BC70E50425D40BF9F4436147ABA3B8304199AA01ACDBBBF026E3312991F06D9B151A4321A46426D1349861F31B0223015E676CEF53EA4174BAB7C210D5F9E9B51E7FEC4F7D66D1F2BE83F5F6CC69D34CE995C6F8441D93674A1EE1CDF38D0B8242AB68BA53E44F9CED5B93177CC2EF428CC767B5F647AB314E7BD575D73DE09C428EB7AFA05F6EA8BA44C10D41FCBC8B404ECFE6395732E151568621657230013B8DD20279E87DC0F76CE8E3783E25699544D134F95B0EBC40B90B566724521D564AC5783BB9654F5CC699D0E05AD90A43792778D6D6E302CC1F6129BB83D2AC12A7824D70A55A9978657AD734ADE602C72730E0074A329172C8D0A8EE6B727650763BD48F6D03BD6ED5004360143DB51B3E32A35E27BD7DA81EC6446365379DD9076865908A413A05674F185465629917775EE1F113225CA8E3F09249C3A9E6C9E8C011D4F760EA6678B0E64FE0FE8CEFDB0294C538D684167A972AFF40B83105296D6454A86DBFBE4A4552E6E13730ABEC31A9888107429CD697B452BC87D3A16BE14CCAA682FEFECB57206748C8DA23B98198462749F10A57F4D0F3F417FF37F0A67190298B617DAAFE94A9DEB28606618421151FB5580EC58BD373879A254E28FD91E68C7C0FC20985A2C25BF169FBA1B8CD8EF48ABC8E18D322E666B39387652CFF9440DB5D29EA56A5F869E83D46FAC6D98FE196CEFA584BA6C82C0FCF6FE22A091B4D5E8E6AECAE31D75135DCD51F48DE296680CE2744325EB13ED7C2F27E3147DB37270A5566E9B95735E9CB267B46A9ECA3F64A0A04C1B0CC6AAE181E9A912797F2CA9E50396F33C84A5BCF10C8F36DFE6CE95DC6FF5E0C61A8C7219CD30FF27DE15E19DC6CB41B925FB31F41059B0B4A07A9B71ABA88C03A43E0680C782D0694A1E0E9C07D3451638172886997AF4BC2A3154D50D5A46719147BDD6E5E08CF1AC858BE26C5BADB66DFAF6DF09338EFD2713BB87820CCDB97C20539C5598CFB50FB0CD44630B6C92DDBE9A5B4DF85ADB25324A8CB1D589787FD1AB835DF3C3D5210DFD80241A547ADFDD53C212E9D2A58AEDEC473F9D75B47501829591D11E45BDE89646FC45C790F475BA5EADA393B45546B254460A9ACC0114B062A19CC693A4154B9855B1BBF01B0CB6179AFABA581AC3703365B1FBC47432218105221F2341014ADA6753A1B2C6B3C0B05B8B1418B2C1F7E130B0F71946D9079A6F50270453AEB750F64AA2C1DBE913C477E9262AC59A4D28A20DAFE13F14653E85C1DD0BE510468E05EE55836883FE4DA3FE7B7196EF5395C9522721204F033CD465667F918C0C067845946C0F6612721D201D809D01A394F4060D8F3CB0D2E68CCFC657EEDB4F1ED6774EE61B8FAF95F0813BAD1D4E84FFA49EA487F05925C7FC987877F389FBF2A048B67DD74C5021C9246AD0D", - "sk": "F9D6A3AF1217A15071BE92BE929BC3E6997BB8A2B75E7EBFF3E7E27735D8625AA49409355DF15BF003E59EC02A3CB3DDE25B5007618DD08E4199EDE29C2C8646931655E354CEA10B194F599F289A0D28799861F4E03270C94385C7DD3703382A5877CA5FA612C6B24A535A0A68AECC7DF043F29093D735229B8BD8E4E0A5669512A6001BB60C9B2249E23006E0280CD1940D13B5404A444813090C9CB48898C02CD2C020A0C6412002024A04454120602188514A8061C08424509091D90630D3A00DE2C26DCC249264126180188A413400E0C40D48824D41006210082940B8041435009B120162320ACB1468521805499471E3304992C844D20466040241D0C224D3440464A8916438825348094B444423000D18C72503A65189B68CC096891AC1084104211A060CC9464C4C90689C0482E2163212424CD41600DA34025B16260AB6892021048A36084944041AB3805BB29013476009C0814B440212C364D8486403810991008810C985DCA444C1342C589228D48649A3464A4C406D6234500C312104C160230370A4B42914116123872D4CB48888282511200D0A36115308204024215098400B312288B0648208821A4592504865D1364520B91089280AD3264289A64048B42C0B3301A3304CDB1828E3846990B8092240319A38318CA06D89C64923258892C28DA2484603176158904998120462C08D00931062C48C09390C524681022602D2345111120D4B4065200110D22629981245A3B22012910912A92D12868DA02651DA1081012690E2B80D18C64D1B8071023240DB982D540232A0987010394D9BC60CD846515C86255A324E1CC4216138684A8049E0380653B0519996300CB64CD3C6489814900BB04D50942113C30022306590B041181046C1C62182A0081BB721229044A03612441624CB30490B331051B261A2189150B60410489098806C241990C8864889104E10008D64462CA4107113358CCBB82C0CC52450400A58266902C48401018CD4100C50C28023146409369123C50D1C882042A62521A6044B3270609868E1442A0AB540CB20869C160A0B492009C86DA4B6051B3206DC06920BB32CC38608E1B04CE424848B38620A4869CB226492266623853082800118384C0CB34124900CD9C0801926201B174090880564406C98B4905182312137292430802397251931029B869103A32C5322124B188620474C89C48C10C32882A64D81486003A74118450493304601C72DA2900019352A092611649460D5116559D1F22734D48A42369CCD69DD533D31681CDDC2475DB9D6C47B5A0C69120726BF99B8CB301F13DB214C3AC2CFF521D8C4B5C0220723939D88460BC4CCD8F0AE19AC77AB0A53159119BAD1437E6523ADB59D2A4A607E365CAC070AB0A58BCA1B82C5C479A82CB9FCB3FB8FE40630F4E3258F32A0958340BB77F75B166C634E8B2A09154A03101EAE9FF029B676B6096D7B92410CAC845376A57B359C98A29674D662506EB5E59AB09D190A9E1B14B93CE758333F9768AD3149D0A8FBFF84612FE01026E4A9A73BEDB3F0679E65C0E41492AE7622A5BF3947F2B97FD7D9A04821A1C5A09B3FCC921B4790156DA8A7E1D6C6C1C7DD18C02EF391C12852294280C516A722F53544ACD24FACAD98975144548F47C0B1DFA82126B27CED004EF36DB69C3EC7E7AEEECA198925DB3CEA49A1FFAD0C9CADADFC88BCD1769B72C267A332F2EADE532572B9DDA5C877EC67AB18F4AF4F43F5A1C9943F30FED7D3DC818CD3DE31A67B1087CD5B090D7A6F9385F00B031528A529F151064212E943A985D87DA39AA8E34E91AE1BE6755BEE1F5289E01CA4729A7A93D4733AB91384AD738722D64EB1D3BE3E72CB069C68970A1E9268A58BA9ECC7C578514DEBDC4C8F25F6B092FF6207FCEEA8F21727A226FC45A089B30A7FF459732ECFB7D16300363ABAF4622DA67393465D31D1C83E4118024332AEC43A13C4FD64C2FA2F3A031C5C63B371BD1DC6079D1D0CDEB832F4B10FF5D449AEBFF92E1222277854A53636F688A6B93A22B2B311BD16D62741C56D6962F591AC01DFD2AF9FA59F24B4713745E326F3E593702852E69F0849199B821AF8806FE6A9E545FF011C7064A8CF7C234E1652262C3E7EAA0EB8A79AB0D25792C1EE706E157CFC07D1E6CC612506CFD5CF49B9EAC7DE770F9A1AD98784E2F097DE07F9E7A44AD1E0045962CB7FFF6CED8265A69177726652BAD9A7DDC78F807875D4FD0A88B6233157D715F3EB77BF275473D85E0639C9A5B78C987009DD8620E7A4E3C0C59BAE9FDAA7F5F04A657FBDEF7DE2E7FDF614CE60F7B67B8FD21D4F76C30DC41E828169EDD09B345E0ED441AA61F5808EA458CA111D930A9E9FD7A5A3FD5B977F951EDC959682FC1B0B93F1D3188D6469E128DD3DB283605D34E6D79AD2BB4A689CDDAB9965355B08B19A8046AA369C3DBF53B48BF0A41A9ECE797B31DDA1F4C3A54245D5D99173132C90064078D240B85C9CDBC6BC864254448844564BC09552162E4A5DE16D6515DB34535FB35F3ADAD71D9C95FB9CE07D194E902D596EF91520A0DBB692D7D495ECD1B3761AD973A361CA0F15D08B98F0606A876CEBA87BC0D09433DA0F839CB4B1FB48796B35622874A5F187EAD7E9169F03817B1C013E4F1AAC968B01E20AF86504FE1589368F606A05BAEBE5009FB5296737FE40F026C92C04B995A6F299FB7503ED49FF2C6E94C650F08BA76A3FF198432500F72622E41E5B6C5F6795787849FC480EF7B54698B0878B808E083B2042903DD9AAE12C7418AEE22798AC2E115721FE76DD7C8187AA18FE3895965F306B98D015AFBDA6DECFB3F90F3A4B2FECD757E0671C2D9879B1CF9A6193DD9467A5E32B716C68B4F54F8ED5B8A775EB826CA3B0C98DC0862E59540F922EA94D9DE3F1772D92554C6AD3F4D137E102EA6DC8C42D1A79FC7E15F03E92ADEDA5FE928F50DB5EB8DA04F54BF632531148A9B6D313A088A79CB107FFD0351AD24BF504ED12F6313B0CD00ED0652829DB691FBE106EE2DB3AA529855D429E3971E1E55DFBF6D73A0DEEEFCE501E51671B928FECB31600C3A9546BCB93ABBEC43303B565B6012B664D339DDFEA016A00E3855CBD9915A51A85EA82FF553C4B1409DF26D6E2958509F0B1B03667B78AEE5E2E5C3EAC20DB7771129F7F31D69EEA42631C3B5099839BDC6A6FD821396D975643A0FF68187AECB2E50022CAB078A3C0FDAE79C5328A674B76272DBDD1D2AC6A3A739EFA7093100ADB89BBE855724B1101E864C47849A25058DACAC3D2CDB42C107663FB03B93DF2BE908FF1796C82F0DF4139E9090ACB41D85FA7D209F24F41C5B89435D601904E1220B60CF96736A94B18CF168D6518E1D2BCEB5ECCE7E96BE14436716E0B273E2FBBC73BBD33B45C65468AE78F7C8DCD40870604FB0C49418A60FF8ECCE446B522CA3B623A9C239A746309F11EA3D5D569A92033572B68BDE7E6648BFF09235746585DA2A72BD7D24FF26FC70A1D0382C834E3C31BEDCA94D9ECB3A8FAC4F3DA824F5BF1D07B36B6E18EE3A0891FA64DC6B1B2967B2D0B6B0D756DFF9BC18410E88C2BF091938E23EE6D56FE9E273469B6418C3FC0FA709AACCEA48B63" - }, - { - "tcId": 6, - "deferred": false, - "seed": "2241FB7005D1B26A1735FFEA5186D08950B4B12CD4FF51BD263C6B8A2A2A18D0", - "pk": "B3218E745B2E6108AFBD6D915A1F2EAF1EE899E7E3E64BAE049F71C032C724A6F7050C48F25EF529F216D10C77EA74CD7A153FC1A1F4157D064A6681936D288DCB085C310B8B9134C8FCBCF9D7F6CB0D92DC58F4CE7B0BFB61E6D9FB12D395A83D0A457721BE62555E27F87E8084FC9D2B8F460AE51FDA5B49664439312290CEFAA906A0B9D253509E6C3437947C03AB2356668F4CA59AC7C78DC0ECFBED0C226E335DF8E4EB87548E8A775BB1E5AC92A30978F136B4D67FB71DD4C005CB4BF42B8CB7CBD5FCF475887959C131498EF72B1A52A80112BF6FD13AE2F2D6A657D25C3DC4D58431B8F8499C40CE89F528551337DF05C102DB12512657F48462F4A9D009AEDCF8A1F0EDAD1C0BD32BBCE18DD569FE04BF8E132B7301CC84CA4D0879DBDBACD03E524D147C2176158193FB98A4D4386D2B17963DF59B341D04491621D191214CFA2CCA6E0781FD70D37150693C4C1EB70DEDBE56DDC7CFEF279F0B54627FDB2756025C91691446A2AE336F0AF3F4B845D82A643C3901839074F5C48FFCB159F775CB26AEA03E0ECC8101A8E46563A56A75B797386BAC8E7B8507DFA201BEDFDDC3AAC6BAE10DD1D969A3EC65B4E26E6BDFAC613B4D634559A85E9CA7EB3FDB1BD3AF683D31E4BCE8AECCF5513C28526A2D1543311504B21DD8350BC3C349C5DB7CAF4627B9F41F656723012876D8E2C5D033771A9FC0E95E26F4C53326D527D2CCE21E05E4798885B569C48C1F815523A1E221F61242600A05EB86BCA6950A37965EE4D5C969825326098BF4E004B9EF89BAB0F72D4C93693DADDEA95374E64AAAF06A695234AB99C87FB8C0916CFAB816BC31ABF22AB0905E5DCF4FF4FB5A3294B1ABAD63B5B72B339E571C9DC2660DC462F01409848B4BB30A186F0A7A51BFE1153E98870D0FCE9ABD9F7931E39E7C16681CB6E1D42E444723D40BC8F461FE7599173BEAF23EBFB8FFF04C127CB6512398E440F9664BE694D84D2889C3C3EDFB6ED0C806026D80E4069F6BE6A59D66C165C9C19BD4D2B9424B7E513EBFF9A9FF282B94C5DEF162929147FD42AEA605A9370FF3DF01504A8E49D11D31F5918C970197CBB6C65019B7501296E69DA02129255B5F33A8CA4697D0D08FEEC2822672CA3DC5C04F803CCD5D38A838E1FE3BF211011F8E23F7FEFDC931A5E615C2D8F16732C04C82561809C0F52C83339C12A097666C13169FBC6CDF36D583364922DF573D4C6F57ACAE8C09A40767C6BB3762A577B111F8976620410EAEA204159E50F8AC96FDBA17002FB30F68A6BF8748C4BD4D67321109C79EC911A3E9639376207C77132348F558CD69E98FF998B6B71760F01F754A4601968D236A4AFD4927F1C07D4555758335769A614411D97E829C62F6A366D77BC562EE64ECC96BE33FCD1E75B5C61EA2AECE89B217D4302F76056803B69574590E8EB51B64E6B2EFC20631AE62E92AF25511DEB499D1748DDAC3D7DA5CBDD039D8114CBA4F4EC9E93F4119209792D8A815AB308E3BA61D0547A4296FE796E3A4F48D1CB564140AA23B71A51CC7EF2B13AE57C744F08D2599B78627DE15CB87174415EC2F64B70C4DE11868B534F66F688F4C2B34CD552947F86B4DB152AD5F4AD60229B60595C14D0A64D7A573079F825E85071298660AD63FCE58430D4C928DA012926ABF7C61382DBF19EA7FF36D2F085275877EFCEB6D7FD4B0A6AFA1CA72F7D18AE564FB7E23AFB99548DAE13F8D9B16FB320213D43FB1DD9C43AE437C992E84A0B977DA3FBECBD27E14F6DDF291AA0513E2644E943B702C901CD1CDD10AE281E0B2781C44932A661AF243DDFD644075ACEE5773A9C9ACCA5DBC86CBB964B63D3194FA", - "sk": "B3218E745B2E6108AFBD6D915A1F2EAF1EE899E7E3E64BAE049F71C032C724A6A9DED371058E6A75D33E78EF116E27C74FB9BEA75F06E750109E9CADAE7199F0EF40C4ECC6AB8F422FFE18683D84668DC2FB3FBCC7D8FAC3D787167A31D81F25F057DF0EC2460F082D61E6CC2ED687A257809952EB1EA939B9355A1C952952EECB9805E31250113208C0909010048111345192268D203781A4B00151446AD2A48960A410CCA6842131112288305A182AA014804C2465241085C2902858164823154218058610B220402282C2166222891003140008282E54C29164442E9930049C08489A262698140C508028D990849B2410211686221444DC42898A14288BC491C2B65018A545884806D4B684A38049430072011430012411C1B43053420ED41821483631DBA200C23626E41406222369C306811AA82918980DE2406DA12664D8B4855C226220096ACA44651294891836420C92691CA2444894491B83904B302D91020A0AB9118AB80061C84D89460A2441481891419104312128925B88319A164C121251CCB00044064024396689402418473243048DE1C468E1188401A16D8C08810B0046E0480A64A290C14832C3B2080A1626A09869233204C39225221662480629800482109564D998302203450416801203312417315418111BC16D0800485A2670DC38701B183293B868C9A64C444090882400A492501B991082082D24422993420608255223022A59A84019B550D9441051886DC994410283045CA6890A414501C58004848090A4300A28865C448C0B29510347105A1886D4846C02C38812062C934452101192019624131250230524C408692031705242445438220A14312021045B26481B116E80469251C24521364CA100320B36801CB100C0340AD4B2299188718838710AB0501C23522182408A8611C3A2305A064484148A1CA210D228329CA46910480212136CD3A26119B32DE1985012448018B9811A8629A30464C43085C3B01152222D23A180A3B029D38229A0488044824514C46D802031034329CA1226D120309A1266CB188059200210466A221544998084448240C12000504044C8945088466918A20400436963046601A608CB229283486D5B366908C64960C061C8B8244238409A84100B301208944080184AA22071DBB66558B44402992919B62C61080C418649C03224D13812E192894C188498C031DA3065C32044841286A3420C0B293063408CC422001234019B206C019300D1224E90240D5A0D7FE8388ACE498B62BE6C71353A86AADD7988649F6B1DD161073E1DA402F798D8BD1B4676D4C444730BC8F020B8B2FB0D6FBF0C68014A70B38B565E4C98C941906B82996EEDFC8EE174BD0FFC4150CC6E4B8C9DD41FB85D4F824143DAD23611FADAC021B266BCCBA588FE5D7C7F593DBCF0C9B33864D52847E3EF978A6A297B936C0FB17A899B2CFD82A3677B542D35997F6AE3FBDC25AE3727BFBBBE81A4617391E1FC1D25172DAC3484B0E9381A522070CDE8F340F0E34566A48319E0C090847A2C5057A200C01DB41E52151E0C999394C74B17F9C9548D51176DE003B849561ACE743273BB7C96196074D522F27D518F63F1EE2B09479050B01B95A6CFB2539BF4A640FB559943E5763978D74D0832C1E1C6F2A4E4A800DE10D392F1B86D0C77B62FB09CAA4039080D135F1EC200F8D03C9AB26A67F6CD6BDA3E94CCF61332E7033E30440289E251F081089FF46162C6D37913FC1B17A0C8E775B2D321DC685603E25804C86B78F0215C43A0D9A3B287A22811203D4B4BA5D692AFD54BC3215328C2E08B0E76B4C4D9517474F9F6826EBB41800DECECE108E1E340E2CD127F24F00DDDEA5257E03166AFAF71073A532EA529A0F20ABDF40002B0B02FE9C1DB7BEF600D0362B7EE7EE121D4E0E9C7322F3BA6C97DBD8A2E9203CA6CF6029B586CBF73A9A9850ECDC45D7EF6CF512473841E9E1409777CA1199E2D704A3173B62A444F89538AAFF46296303ACA38B3EFDED76E13D6893BA213C393E9C977893799988AF637BCC365ABA22587A4079210E5BAEE023C6CB000080AE2F6A0562AE5DF3A8A0606151A3E8F5F343F5D2E9C6EB15630E26F486D352F6EEE4D8FD0E9CAB28C7DFD67156F1093FC573D1A23C23F8FD5DF923EF519AA204F67B43E3C33139A62584A01B40FAA8BC4BFA2D2C177FDB295E6EC3FB7CBA29BD104F086A7CED1360ABB6717F417C4F612604B6FA730E61958E8B0B738821D1DDE6EEC9934CE165D115F474268D8950F6F661BBFBF4DD28CFE0658E39855DE27421917AFC1BF24701C0AA42B05E824B32CE9F19AA161CF14331F1C515229A8EF742FBB27BB5AADA0DA92BAB57F3FCA6016896AC9609183AA9C61D2FF6A53EE48AABD331A7DD50C2E5874391EB5F2FA6DD239C0177E08AB652059AE0525B82CF6C2F6F6F79870C9ED72778A3777F10BFE0A295BF8721A1EB3701865615CD5157F750E7723EE402B96DB5C5F3A1AA053BFC1E09246401C8D571F4B3BF7A44243DD62EA2B2079C2EF81041C0A97D698DFAD638F1B6E424F87CEE1262BDB0DC922F4CEA2445C380D7DDFBFAA4149C1A00839479FF8A1F88C9D86EDB40E67DFDBF0314E9C778EEBA7BF2CEE97FECF2455E0BCCB80052D24CD741ADF2DF7FA46DFD36A25682F0FAA0377502CF6AEB9688C9EFE8C34D571F6ABF439A4BD5BB8AC268FDBAA8A1833A35211339245D80B3E224D86917764238A6D693E444AB427FBEB474DE84F6CDDC8758E5EAEF44C351C813AEF15EF1ED7E5C67EFE376AF86B00448C07B69FA4805B77F17D00CEB33F5DFC0934FD5B63347B901B750727B020B6EB095091D4DF0E746571DF50BD4CCA89BA02E73C23B1520DC7383ECF7C6B46A38782F8A91FD52FDD3A91FCB341BD4998A9F71613C3ABC3EA4496CCF4177050E7A6DE906D7527EC728898378A2FE9C34B80059933AB2220657B6AA279DA0F819A8FAAB2A9F3C1C2C79A0808DB819DCFB01DD870491941DF819F543CF8FD5192919663C562158B4F764B7F683BE7C6CF6504F90697EDFBDBDE35D31BC037AB25CAF0B599D0630E5C185BFF748B6B4A807499908A926F8F7D85CFEBE0BACA91D3E306909FA608D5674E6DFD1ECDC709D5D5BF3AAAA59E99C4A1EE4214C0D086DCB7F1C820894EF90D3D9F5EBB5C4A394646DA1D79EAD22A2DB539E58C6A07E120C9000F0FF5BB4EAF5CA692EAA9D35BB1F5FBF3C5007E0A87084CF9EA23A2EFE439CB466FBD83582921DD1962E53E1DBBFB3BD1A7895805CAE1ABEDE64FFD844DBDCFA5094B96722FF4E76C9674D6CBFA3FDF35F0E54E2C9C81AFBC54B6A36CCD53605DC56F2A8E952F006170BCDADDC99BD8176EE78F083A4B545F70C956F233A102E8D09B5A6A910B893C0954996E126644CF2212E61809CD6028D868238CFBDF8180EFB2F12C20A754A557C63E2D76B4DB1070F1C29C9CBC7CA61FDD7E9EC7C7E606F3418E6C41D717BB31291CEA44BFB1AD5620C1A19AD5C81208CEE9F30B82A8E1B93D58FF39A0FA6BDDE894959DEB217D73E27AB1349AB22A3FF0255684EF4E2B63309AEE5C8EA3F97F50FCBBE5440C1B0A90588248B12392B1B4FC6444A568F9F2726CAF95ED" - }, - { - "tcId": 7, - "deferred": false, - "seed": "32BA0BCE82AC978E5932BD14B1AC1A9319BA20412538191E2C7B1E0BD1D01CBE", - "pk": "88D5035BAB5978F65EBFB276B69D110BC0036C20481FF9CFD52CC4686715BFD36EF295B8A90B4BC5FE763C981FC81C99AD256ED42638119125131C214BA262D158D0CC33D6687EF24BE355F2AD25D7BCD89ACDD766E4AC27F8358ABE5679A87E729B12950C17054E46CA9C0F43DA38D1156730EEE32DA5A3B7C1994DA41EBD8ADCD9C22BF4133B0A27CED066D13B62EAE06739EE48400FA4445FE768686074F4E61D05C9F9909027EF0B2ADED325F160C27A621A9124C2D526A1F73055399D27FD732024325044E2CE25E1BFF188A6B0343ECC709A18153EC3E06A4E33285D19843FCC32B4FBDC6024DF3EEDB880F468F6FB54B1B0128F2B85B1421B2361AFB59C6D548B307ED2CB2E9E00FF319AE6EC325371CB842EDD92407296049434E391DB770FA2660EA8691A67E400FB9C1EF402A220454F24CCDD28798C17EA2ED65CD76F7828687F535D960301456A7E937DEEF64E3FCD86DEE79BA27CBA562995E0984F96C8B64A5354DF6D7FDF71B70EBCDA7EC8EBECC26072F9C14EC748620C2493450A8A705FD9E8A7E747717EF48B80C119878CDF646434D193F25F12AA6BA94AC20BE5FAE1AB45EB7A169C2428A9D6364BC36F532B769DCEE7AC6A89EA6134D374CFAE436E9229D48136FF69B70FE1B061299B85E7EB3F527AAC6F8F8377A1568645D6BD76CD1EEB493BDEB404E9304B0D51332241E4C5E53E269DD7DCDE8D7F044DDFB7F5B4BD34BFFE05AACF68BD1C618E9F7982439521230DD97CEB4E10879DA82C93BABD0CF1084EC50C0025A918250D3E2FE026A06EAEC446D234C9DA1FF6A61685436FAB70D10D18C10D2FE03126362606CA49C6D4A4449B4AFE615FF4245C6E7CB1B5FF3E3CE6B1C8899292E1BC56686A5AB29475F4BBA57F1583D310C24B20305B7F367D93672052120E19D40630563212009602DDD18BAC6F747D1EC665B3EC3780005D3D41BCC4FB10AE0D2F71DABD94C220F7BDE1716CBFC26CEA2D874B80A36554BE6ADC5EB434959F55046FDABB5C57BA9A4E1EC5D1A1A7542165DF85FDD7D2B555C56C688829EFEB94248141F7620FC43D1F58B0297E0A68022BD731AA2F2DCB582897492364820077139CD6EB7964233B17CAE6369EDAAEF313C18BE59E847D238BEE14332A47826989F3E762EA3AE5905831AB0AFD435C552DBD4E72C7A3A3585F65EBE033A276C2A8B80DB69735BB5128127631C212BD58972341DD2E7346097DFCA3B51AC12ED994065CD9B97E26F1E32C97E7857971168AFC67844FC86DFA1EE3C38881FEE38A62D532D4A64C7018BFB613892D2D8EB799485BFE89E9B27E6CCAD6E1A21DB2D7EDD9EE2D34B9358FF3E60685218EADCDB2D70870843B11D99897F51F4B6E363229E5A10D093FCA34BA31300DB3C6BD8758D35306F05A9C4D8DDF78261A9A13468BA20EB9A24DB2BC51DB3CA5D382606958835C7E3984401F12D85EB00D1A6696AC2FCC96D4D4CABF6D644BB856CFACEE277325B9900AD611B5710D1607FE59E7B543148E6D28B1920464271865C07731B29354C2BFCA83485B020EE120448F79369692C4AE00FD7D80D663E8E5DF22D85ABB1F89DE27B8CEC5396CEB4BBFBDA56B65481FDFAB69CC0AA7FC3BB2CE8E2823481FBE8AA17FD80E5BA38C2637B1EDFD7046F5A578AC8BCD629E80F428EA736D551BB7D9E5767B215E8BBD562DD0D480E385E3767B91751D22061CA10B9BE65405FDAE73BBA685DFC4EF3803C1F8A63C8BCD9D41FFC2DC5B3FADC7FF866F08611D4E5CFAC7F1ADAF12ED1A41C6E486795E7632AAAECC5CA694D89476BAD99F43724017E2F6D7DF30A586FD377EBEE64261500A204083EAFDA04BCF2079C4", - "sk": "88D5035BAB5978F65EBFB276B69D110BC0036C20481FF9CFD52CC4686715BFD3FB2117E09D4FDECFED8D98CD3B8193C2DF09EC7592716C83CDA0FCAC143D92A8FEF25AA1F31D861D633143A027DD118B77C76806168F2DF713ED0F7B252D24BD3BFD17F352AA63CDEF541C389A0AC8DD94A6EBE2BADB5128D8A8B4BDDBD1DE511B218520C12840A05100B108E312308928411BA00003248AC140918A1069233172810672202521E3A85088224C240248E0A68100B56CA44401C83280D33085E334128044525126010B8050029284DA200511B2515106624AC6105CC2601CA469A4B62911950409276089426D010564614205D9A80C8C462258B02911426644000048A2480339011BA48D61002D5C342A8490701CA785089090A0C2608022819BB48C91A84D1331489B38611B8931110089129861043751E444628C48425A46421B87014228081040120AC02C1BA0089210284A22124BC069111584D34886109960CB360CC8322880C4715B482212372A143551C410500CA04C5B122A9AA42CD8062509C0409B164012B9110812045B446D0A986C622462C29020901001CB208A1A38885A24620C29915A022DD184458A0830629888DB906019B18410114084C20419A44844C4604446454AA4641119601A262E88127061826D5B069013314D19C4012203214C848409826458388E48A68062844544044011846D88442E14226C0B056D01142CA4360554160C12264DD100260CA58402454023152022278851C60CDA8061203749C40848D1A421011461E4428910132E53422ED9C22953124DA2A63100A0494CA46059140D09B38D4C1011931828E200446220020A38511C419064A82512848CD2A60483B045DC845003200DD2A86C0BA94009A32004238E0A0702CA3228140449DA060A23218661328193C60408A76CC8102508C87092200A49A2891A902058120580C20CC1942823915083C4110AB80CD940811BB22D03A26C910611D2425224090A21C62510984524458E13384E52964183121199144E60164A02A05121A52520A90824498503C640C942028402924430215300521B264A1448859324520B1831D3B689A0A42804332E23098011380E143944CA36114386041B076E14294421336561308E0C034D1432920385891A478A0206804B128D5A26700BC00854B80893B0615120082413862393481A070CDC3602800008D9429011C0640AA58403338910179288004119406D0A238D0445101CB28453142CE014266B9AB221D7004AEB423FE90019F0B877A77C97038E602E5F27588CC5E8F4E291EA281621AE6D5FD8B69DCF726EFE8A8D4EB70ABA722F29BA62DD2B95178D3F085965C951ACA56A8A2721151E6193CB347215F6636F85F8A58E50C88783369E0EE6A2C9396BBA3B68EE376A16F7669B94556195146917ECF64408E3B75208BACCCF2E9CA220934E4C3E94F212C78F61959D3F4AA3D97FE5F3A193124F03EC3C772DE668E57B834236BA3F1B3FB4189B92BB61B1D2BC98AA6DA3F9042A9EB270C2BC1CE1E79A3FD41BCA404D3023C6F595E564BF9CE85C4A919BCA776A94B5E30CAD0549FD2585CCCE139B20AC082704453279C2701CF275E967E6C81B57A071C09F5FDF3CEA16ED0DCA1F5983B79312E670B2F1EF546C24C42A67DB45160632A94C3D68E477260D02717E77DDA29CB4FA599FECB9B8A39504A12349F96C0A91434A7F5D507BDC893732D1957179C258E898847D44AF121235E5A01D8A9A2EF8A98DFF59E89905CF0E71BB59672254F351B85EF9FA5907AA688B7A260E09AC81199B14EA55A9D759482983EA94C5CACAD0B5BDB4D94367E3E6623AD7DA0441E9B695C1EF05A8D23466985CB88AB02E775280D954F49797DB6406C614E87C0E4DB0C932311451670898DECA67193EC2F9EE61E03234D3B06E27CD431965250DF402F85E9D3A5F5FA6ABF021B503173172D4FAF32A6C3B0A0610CC4E23B5D51E1A5F1ED2DC8750B50C6356C973777A74E062259BA12A55FA9A27533A79428BCF9A4026CC240B6F114CA92F345B8F55AB2B47933C0D8C2E77268319465576A217DDF9EBC3734DC7B5AD17DE4F64C99AA7D2BD308B28BA898B873DCD964D83682CF78D63D4DE1EA86F7ABBFD2194E1F43D58742A6B2698D286E4EFC0A06E8A11B65ABE781F7FB7D81A9612814C30F56895C1FB7C0C3E5C86046473114CC199C88C1017E3715E833CA40AC0D82216C29F7C2EF1BBEC2FBB9BC919E9E1DECAA0F1405CECCDB4DD2A52317B5588F2B23A799DF80952248B266A6E64C763A59B582B95ADCCEDDF942F7FB2918D002F5F67B598D6CE559A683E9367276D6ACE12467D83558C1FEE296C96B06329FC2812292F54E5A02BA47CDA2D845DFD0AA8D23D88A44B369E84D4EC0B1F7574B75A0DB17F358FB838880B3F4F3F1E3039707E3A1E3FFABD65E8E0AD7C8BCC035255E6A5FB19811DAB9217C4A52EC5B7D1F16EF52352EA13C68BF02944E1D12FFE662FD76A0340EB972854DA8FB6C2D1F742C39FE5937D01F8683895C01784A73DFB1AA14F4638079374E4A73F9E232AA123E89F86A71370F381D502BD496E656626805DF278FF5C5F2C77C2606E9A86D88923673F8A8BC1998410B4C4BFF2C2AE689C62547C101354B69B992D47020A82CB8DA28C8AA4BBE6C8047BF6877E61B6CF185D3A1D8686CBC42F7B81D3B4B7B160D2F25CE82EBE0D532A4FA55E42D84ADECD88B52A3442C0EE00F4BC8AEFF861C085FE1583D47E28F9C57DCFBBE640CEDF33EB3145553E5FAB89FBA6620A12020350C88BBAE49392D14ADB29CE430A2E42050590C2630DCA206876B8060CAD150968F10A482D9620B2C3FCEFCB08CCE9298240FD657CF1C11AF6758714AA332165E1C7898C77A0D865A6D0956916551E184F40A25F53AD56F40150D077D8FE162392A4CAB6C44B9334592709BFCBBE739E9B42557348B4C33F7CEA34B2C118FADD5C39A89A21CDF074A7F4B3E697476E38BBAA9068094D218149605C2B71E3BA2F92F03E429748E92F7A95AAAEAF4921CFDFE6ED2D5AFA4E10207E9DCAB695C7218A1D318048570EB68103E645C98541345451C2A333417C268B9F5A83B634E28A77CA7B4E6227115E49832C75C90284919AE2062CD3DF2C5CA0902651F28CA05E2FF21409B7AC1A46062FC76B9C933AACCCFAA53E7384D4FC4918B74A0E2CBEC7E06AB530EAE9D7988B72C737E71262E393AAC3586B86E81D33FEB1B2EF57752BEC6CB314ADFB95FBED5AFE23234D32DC53B315629D426B0F9EC740E29E85C691A709C033C3AC2B6ED6D0D0A3E0EBD15A3306841AF0BA50FF06BA5BA2648F707242325BF13B80477B3D9EC1628EB760BF95AF66F86C42CA50845F8CD54AA4ED1A8CA41F925A4D5F40BE63D39A48B7FFD47F858D91FBAA41A320D7505906CA613FD36810E99389310EED132E8D79A5E735A63CD4622BEC3E654FD7242DF1CDF3B55F9CD593B581DDAE4FC4F85463268428C1CBD6D4E451F0E6B1FC136375436D6226EB900C4E581DF8EEBF1026D0F451EA8D31545DA04E6B91B9D6FF5D69881E44321FBF7B71F90079BDAB93C456FA3812AA3819518EA589F9B59CA8347C197A64FE21CE29F9E5" - }, - { - "tcId": 8, - "deferred": false, - "seed": "0BE86B084CD4B31D855EBDED6DE39326516D4BA6770B76B1D4398FB2C9C75196", - "pk": "12BF77F8CC6192D2F75C2BFB9E76EF8D9E4E47ACAB1A8086CFCF213A8E38A4C3EF2650674118F16577B118BA4D6C68451309F3AEBAB28689A9B150411915DFA25339A76C2F78DA91E3CF11DB3D0B1BA7954E48B73B3C79B8943DD8A8AECCA0C2FD7210E4607B5CB442CDD4A5CF0502C5281253866572F5C031B8C7B664D024AFC1F4275139047F77705AD356F1F0B1518DB009668E777F982F12A2E2CBF94818C5666DFE39C86281681EDFAFFC427E1F94276356BE021FF111CDDCC1A9760E2C63EFF65D71AC360484ABF6296982CA325F5D3DE84389C579DD3679E3570E327E5F371EFBB2E4344107C4A020C3417E93B61ADB58328B8C3300FEBC5370ABF679887FAA00B2972E4CAC37FCA8091B5A4D82DEE628CB077E198C2D310F5AEC2B8BEFAAC088EA450B268C7975B97876F2506A736911F48A569CBA650245224EDA137930E333394A3E1765C9E44CEBA54328A1BCEC797021596F3825193CF09A75E20162081EFD2AF3E138EF0006C0FC7FFD30FF871F835E29F5BE766ABDE9279C63C66BDEB9305EA464B079921DDDDCA6499F24135AA1590566EC44BF2A4FE58E0F8B6924B5FA1538464758C84951DE0055DCC6BA47B6AA3A7AE762DA8513FF86C111F4A322BB9070F8F4325D81750B96E2932326792216C3EF4646E65219E3FFE6A94712615155D935C584032C73048022D620861BE26DCF836608EDA0B41EF3E5E36CB3E2C6E70FD18C36FC2F7CCACEC8A811FEAE3210E34E2A50DB516D652AA6242D29AE0E6F8211C031D0AB827DF1AFF74AAE842497C8A70F7980D447B7C2199EEF6E316A5F21FAAB102B01C2021B79D36578F5EA3854E499EA8C09EB7AB853E94C182E1859A2C9A4C4AAA306B3C4BF8FF4A51DFBDF86099D446F007DB6693241B7B4AB274A23D60343D508F8C3D2BFA3E21ADE4DF9DB242055D544858CD9EB01E2FC3712CD64A7553D0219970B449187BEA4578A0F4FEFF662A732A378BC64D725C862EDC3A48B7F8D54EAF6365A59FA9D48B92B126399693E610E768B97E9A79C7B27FC2F7C36C88FA5A96FDEDFD09EA5C69081EF50180FA987262132D76A9EBB6CB7281EA3BEF56BB5EF32608880FC58270033380A48A8481264D89094BD551D9A426B9E05B1484B9D1E0774534227A5B7A7A0540834FD43C6CC631531EC2BA5FC5F47FEE839157DF4DB54EBF42EAC44B6DEE1B2F5DCC679C94050D7D4ECA9E823195A7051CEF88CB93F574259F35E4EEFFBC0D6FCB9BED07CE09BBE62718D7D835EF761B2DD703AFF3EA55CE8FEDA4968FE17E13BBD4F273F585B62AB54D926B82E6F68C724BF6BCD657D519A072A1FD5F902B97643D7CE941438469E1629A62131C95F557F8EBE6EC0C5705F40157BA2D1A939D767AF2C0BBCB94FFE7AAF0C6E03E0EAF2F1F16044E00B071508ADFA77D9F7448C0C34B807575C07DC5FA58C9C9662E1129538D7269A52232E30FE645EC20B6B096FBA3B8A98DCBCF009D1E49F2B890CF40B8CB976155BFE06B41F6B2DEEE2DA860969509F49E248D7B2A3854A3E62A4D01A09B655B960F5C768DCF597CD553FA5F1B708EDB92C608827F16C56C7454DC9AA6DA7C5894010E777B43E17E402AA54287EAC468EC6546DB1E12D126BE971B968F7D6A4D2E301AA88208BB9162B1165AC9CD95482A5D2778068D44803C6B7EC58BD3A43F1DA720125747B83EA9E7DD1C416E56DFF82B36E034CC9D4263D80F8226C57B1FF6A869131376863277111F283751FCAFFD4F81F13936FC90D3CE1AE7018B54FFAD0A153B1581E96D0FFEE35E3482B464CF3949D08066FE404C883E8E984CDBA58ED30B81D907112DE004E5AF5876D2625E53DC256", - "sk": "12BF77F8CC6192D2F75C2BFB9E76EF8D9E4E47ACAB1A8086CFCF213A8E38A4C31A184EB1DFFE79685CF26FBF0DD4D9A75670F64F0DD28E678BF346FD275B33849B1636AB26002B46002131E8A4358E8514C57DA7CDB74E81A0E129120BCF89EB39287AED75BAD79BEE2285BCB67F2C75D3CD6785C840073138041A822408FB4F222784224412A18071013451D3262A21944D83B4480CA46D243802C8A83099C8248024920A96400CA0911C034E4A021218A370D40612944466D33288CA9044811206E04460118071192448D0426C10287219476910066552928963246000157211998D033146D1306810930DE240044A80419B844D21922492B028812441231545E1906491282158048C832861E3C68413952D14122909200E50020C0BA8902204300C890D229111C9224801190E5B409212466A00873049905199242D983850030988D21489C2A621CAA62C0C146D00B63012A93102B329CA922900A22414450E249164C9A00C82181020C245D486414A1040D4C4511C392A08838D193368D4080E53424908A72DD092094A042409B371C8A06C0C28501045825A28054136289B26421438810C070961164E49008D81C090A1A240C116464A802DCC244A942001E2260922B544A0200DD90824530442C102921B178D1331884012290A9541C4B01099401109092021B1100C800D9934299818710B19091A098D0CB2018B4422CB4228D82410CAA430D4A42D1449415AA405D44426A33066D90640033728C81252C8C88104050098148C1CC2899C02909208221883511A176418C4205C48051CA208822221E3008913802DCB2231933040CB000D9A460C03C371213121D18604538450403471C2822958926944C0059392310CC50919236C1425062012711392711136200A35901211129C024040107083A2284C96810B1900A148821B452C19346DD8061220B948091540019048A2222D8B488910B981DA42301B9241223932C9164163A810011761C98445539200DBB071944042D42260E1904C08216D5A105018046A618625CAA444223692C3B6000A108A4B047053C49044225289947010336A1421011317909BB485933290003286004325C9868819C47150C24D12492208265012308D8924880AC6600C0811DCB0908046228C464D04B8108A9070892011902030D2B44CC146200B232019450E51227214915114B58D81344D523092490012821010D9226A1C8610014100A0366CA0066500930C0939288910705C268A734B52C1E7258FBC0280557B30182A565D0606DEE96C8629D801C6C7638C89EBF8D6EE3FDF2E097A3CE63B844690FDCD74537E7970594405976CF07227702CA1E498A824D80A3B7D417DA4638004D8356BB6F4E83D130AC217DF4D5A8C3F1DCD0714AE049CC853A232166B18EE9EDF939AB6388469C7CEF34F36A41201E168A1B3685A4FE758E19E11B6B900C5E9ACE8EDED8C69A7A1394D4289819221F43D28988255442D833EDBEBFD92ADA840A4998DFCE7551605B68B0D5AB0E42869ED71433451F9613A4E9817CD706DBA1D43F8B09F67681C16667DB0CE1FEA42EE0055EBD1495772E68A00EFB36A82E29A0865E88837CA4857053B25725FAE7E2A145FEB5818F257042573F3D838C7DB4B9A9F7BD50EDCA258EE1D9ABE0370908CDFA843895361F93DB3EF2D4531FA3EC9E6CE49F78648CCE2B0204795EFEA3B14F4469CEC7E1F34FE69B2F746378C7F79ACAD7757918A784D18B7C4D44176D4C890C44B072D4BFD8E0BD4CA23352AA4247007C9D31BE4CCBCD29ED22E5BD42C13F9DC8F2813746108DF4B5FE1062F8F81A79B0972FC0AB95990AF9BD2419FC37D21CEF6785C90FA5F9E13A5F929015AB6E81BD5AAFCC93E06D7CC8F5FC08341CD6219955524C2DB93409346C6D51E3575D48A54807E292F574743A0683FCF58AE003B547EBCEF9E0D46B96121F258CD8AA4C942146C2159A13190327D3C7CD163366A18F2A2448D52EDE4E29EEE9EC6422554F7C04DB7D2228493EBAF971F7F33B4BE8A532B54FC30229071B05E8CF2EB08A67E41C1827155C74A2F3C71391C86A339F3541D2918B6A9129A95AD093661A2A2DC2A438AEB9B68A51AE2133A538639AA8505CEE801EA0F0F29776857F05B9C8908B0A257110C4FA63089AF8773C886AAFF9002FF0C81D1BCA7B86A354E9B8F5AF6A8515FD1DDD26DA450D6209990DA99394C29BF3E7EDD96AFDF4D8FC931DAA2E20E908F4F0325D11696B7759DC58F1208D04E0F01CC2EBF394CF97429784A7C399B00A7EDBC9E9FE47D6752C622F3404A986F40D73B7C4A7195905453E20540AD3EA3F340F9F4673F313A8FB886922E88FF6A53815DEE2BC26EA39DDE3692C343E26421FA220D052980051C67659686C53220F6C83330802575E5DA2D8620A1E9A4F9DAC0968B9DCBF8D5B9E9D4FF34889F43141AD7E0FE512C0C772944134EAC745B85BF14449AEE250169DF5FB73D7D3D48E815A68C8D7F8C3044D30A950A6DA8DB44BECF3CE73019BB7EB137252459CCA91B1EF3F21E30B42309FBA2B9807E475B9B31A4BFEB6500D3008E8EB5B7F9C7FDEFF5D43A9A1182C0FDB5E35DC627AB39649EC04A74DF65FAC7150411F3580BAD2329E07FA113EEEC08E830E6D7F6B30B561AA4461AE7AF8D09C3D34A4CB4275A57D63F18A6F2E89BBEEDA4A8880863B6270A62D188079013D2021EBDD2794502ED834A54E2A1D23D025E394F4A93B45A812AC4130DE5DAC831D7FE556399A490A1A855805B366163131539FD8AC79BBE593E40B4856BD311FCDD7100E1A60B4DF68B2C186E0B2969E68FD52070B4369E5BB43AFBCDBD55E729FD092380E365799B714748BD0CE18BEE4E702AA9AA6632C23238304F108C7657BB373305896E741F34C5AD15E7E599482F62A83556FF503ABA90721AE746F6F7737569DE661CDC6EC6E3E165187CC20866B6F749069A1C47B72A9ECFDBDDDECEBAB977CB766015449D5940B5F49150F74B43F0D14A1BF6A06EE22EFAE98009D232FB7C4EF0A1A7C8B9F14BE723D709AA66822333EBAE458D534CC3F65FD879E60C7EC24F3B320AA395BB2C3C5DE32558E60889316420F866D58D0E0AD6BC81B4FB6A54D1F04351F0AF1899D788BDC43F69DCF8189DE2CE0DA497D561662E25805C15B1FD36774AE9296513B3C04CF2825AD26D5117A024F15F25C3EA0A53979AA02BDF42FC4A2CD1BE6F76E9CDAB8AE1320FAD6418A03F6BA2E9BF7B7A78DB14B0A3A08803383A7A41151893F95E77BC007EA51AB7B10B218F3FA533EEC43D978636826A7C1EC7485B038FB628706EB53E212775E759FCE34A03049A2DD1830EADEF1DFC5AB36EB6CD164D487A865D99D56C057566FB643FA5EED6AEF2F6733C94262748CB0F3FF5565789374CC7E415D1B9843242F1F41E6F8A3E55C4BE0921C28AF977214AB05FC208E06B8A3993723BF17E32D46764E51D3E275B6A5876F8BB2BEE1B0EF512698DCE7D3E2264BA02B6825B174F08B43C1FCFD75DFF1C1029B8D1148838CAF0BA097E927C7E36A36734F7C8839B22A11DEB58A760EB761DBD0EF4CC5BFEBFE23149256F504ECC70AD6D47B11834AF0F38A0E4DEC01E354DC53F678EF2" - }, - { - "tcId": 9, - "deferred": false, - "seed": "68E203AD881ECE7B354F6A760C87CE3C2F7A62EF1E12C71DC2A965517F0E196D", - "pk": "19770BB1D4A3BF4A824BDC06B70430A7DB2618559FC20B03A973B5ACB24D06A1BE8EFA3847139CA8A01B00619D72F5047468678CCAC0B440DF18D256F267EDF378932591D561112D96C3C3F558E589807A6E3186896E47FCA7852DB1588DCCB3A8A48C22AB259F8F293D8DA8F5C5585E6619805CE93F409D894E75E232D7F59665A17DE0647A613B25EFE1437B8B917913997AFEEC8C02214F63331CE248FB4E09347098AEAD4ABFE52612625B5A7D4AFA110D00BE29DFE1ED4628383DF24C7D70F938B694A83EBF42C837A3BA38A16149820F569BA1A9050B3FFE8668A1DFDF9955986A33B5A6C04602A5E5E8F4052AC0359EDC3AD9E60B085F89F7ED0FDF8011A36F98C244F08D1EFFBE51F0FD11B9E5E121C7573E6E051940633B5C3DD3FFC5C585686AE52699503EB318DDECEBB2F77A9CA4925696CAD99A3E01E7E73BC44135DDC658451AF96695FBE67595A38FF0D552FCE0A2AB2C83DE74908A140E5BEE8F44AEF13DF065D5B7E49EC0335F0FA627A60DCD217991B60D96841DEF80F16E5387629DEAD646B7D107BD919B061B0BDA78EFF04A1D8DD73D17A68869959EE42EC6FF7C2B4A079767CF79BD14CE7664CBA0105D02E7E4A281F47E5462B4679980009B0CC12D6F19EEB806D433EA7125E63599D0D952D8689A8AE31D17335588D5EBC4B66B8847FC20838FC019E06BD2D87183BF21FC6AB3028BE3A715D6F4740F941804E5C62734724986FC63ECC307AE6D1737B1B7F5B83220882CEF048CBD6C74A5683B96F3B435C55AB722CFA2D74CAE584495F3C407D7F2C6051AB8736B56AA134B1D84A45A61342A05DBFED3F1FD11C25CEE2A141E1732FC1E4F7BE0AFFE6FAF8139E1A410706CCACCE20029DB74D1FA5656724E27DDA80D822DC1C14102D2F85D90553F6E86F7FA8B3509CF27C49DA58732113514EB8B4E76028DB8AC0A515646282E610FB3917B44EE07128338536A59305AFF30C9A20C9B97679091E1AD527AE99DC7942914FEE882D274451AF2EA3A41320CB369EA4381E93ACA63C6A53E1F1CB89EE6F2923BBAA9497775E3CAF9598FC2957B31E9655C7D371ACC677AF69929F7A573F27AF7CEBB688D58C1F96995A5835AF956D65C9B39E919BBA88EF4CE75A739A0C5232C9BF8D3AAA416349EF8D276BCEE375579AC841895B8B8DD4ECF41B9829333B04F6A6BE7ED6C96F718FDC7F4BA5EB1EAD2493443F4710B9A68DB0B173FE18071FC0D99A9495074849F38F350F3C7D2D11499064006AF1D33B07A120817F24D2197BD8654DB9F28FFE7942C56D4F06C0C77789A7E9604D61948ADA160FF1D493B506504EBAABF2304A2C200297FC3E8EDBE807A3DDAFCFE89BE4D138ADB49630F05A08D3164631D642F38AEC2CD0DD4488129A1565B1465B121298D24EE8024C1510B60750564014FC781C83FF37B107D00B4D5EB92647063AB48A45469AD7D3F58ABA499E851B95D36AF945335B0D7712A09C15B21D7D64708C21C34B9406E00F3FB841558E617C83A700CB89397620CBE61DC8925E5D0A9DCFA433594503B29AEC67C90FDF907BAA581E75D3FA508C4901324185109820228447B364DA78AC8A8B29CEC23151CB7B85014A816E216C52AA07BDA3880045BE280C61F2D94756B4697B9A1701BA76BA044BB86D1CDB74D31243F05C266795628DFB9FCA60E5F33D16D4FF1E3D75AAE2AA3BA273B8F609B1CE2440027313C84AE90A72F1B150FB0ECBBC00FC440DD3A8BAF0942C1B7E28D24B25905EA0A710E8EE4A9C4C2CF85A9A6A599A3E1729C0F62220E435F9662804C3E59A47D05E74C604AD37846CA58F30E542F2DDF75F42D199D0129C7074F8E88451ADDF0", - "sk": "19770BB1D4A3BF4A824BDC06B70430A7DB2618559FC20B03A973B5ACB24D06A127667D52E65FFDC8360D8716E35BF950772BCE4204481B0A2361EC96ED49D5F7F62C1FDF0128C858FE0FB20A40A0808A96D7801A790D7CB775CEDB703A417CB2E5BAC05DF0B07001CE4D6EFBD725CD60149AEA7BE5DF023915B21A2ACFFDBB6200230DC112885B340A51B24102C44988000E64028D59847081308C19212603B48C9A8420C4382004B20910254D12C64111291211246641A4891A2644A3B22C99404C84308522394C082446E2148EA4100D42062A5310261C4409130591C9C665044769A4006964846C0311204A84900B168824078423018DD1C0040A924D0213501C066E11B150CC886950C42823876D212068C4140620A8251205281BA61192124CC22212C8328DA34070C0A08412A92520159150302198920D2448608C22248B8448482240A2200C5A104E83262553468202814C211681910066D9068182B85018025119804901B664A39020D9308410428809A30CDB306A8C842118264E02368522042209254A4B8000D236010014125BB4111CA5295C860C040881D88008924028D11406E004699A2665CA06619A440E91022519134A21B789DC364A5AC0048AC2881BB02921078208899153B8611B921001A4280A40048C120C89B480C2C0714A8880803088949449511244648884CB3002DB344514039110434424C001C0A46DD44448E32846991031D98841C4169153142C02222A1AA1445B804D4A30481B1441644611CCB66823033011922D01A90848142C41308D23A70964465099A231CC824C43821120C649081600093581E3184ED3487058A62CC238225C002E21804804966990048992C26164222214C590A0C2240A15229280809B2206542852611492DC081221257209042DD3920D00158193C685C38868890004921670D0806D41201211246E04B160DB042081022690C84500A33051184CCBA86002B7200231100C94710C1162D38869C92670C0488243263002022A0C022210067101336004452203421214A76541142E801262D184815C480A532492C92071212109183889D9004A20210510390958108A91363049266E02A48D093260D2062448204C609290D944325924518B366622056489C2911B1489DB8051C2424910072019A89021265040062D44120A4B144951C205C81060128665101880A0827064C240CA028153B03020137024A1858910041C4031081752D2C48513292CCB406214C19199DB455C6DD1078A85E13A1C3F8D6F923ADBC92D29E31C2D12EDBF1FEE6C5674BC7239629893B477E559B1E31465C866DFC9DA4DAA756C91CE68626D2FE671A1D6FCE2984AC74230EA4B4C8A65DB0EDEDC29D522DC8B22D9768D0999C3729B21DBB2C7F914A581D0AB3C2E3DF2B9E199C43E2643962571735D2D193BCCD5C0D7FDA8CF045AF9C841845E548DDC3C610726C8F5370101039F46B7784878CD80C0173CA7408BA2783FE1657A48777201EF3F2A5876F32A9CC518961F02720E8233D98204219CD28681EB74CE793550F765F0D6A6599086C6C5C8D0B6F65119C071CE3C90DA97CA6E9DFC07A9E37F6EA3F5229DF74A52779E806E128D3CE8506C3F6EB4D6954D11220887A7BB0D306B49D3250CC719943BA1CABAAEC9D48F1DDB5812CEC8FF2315762D31DAFA2948423CCCE5DA6D504A37D1188C7B82144EC11DBCCA06027E8C1090FE59B7C822C59D1091AE4D9F19F93968B7B24662FB45646C81AEE953526283EB2937059D8213CCDFDB0DBE0828C890EC0F8A6909F2FAA64FD3781A56590CA0B19969ED93A6BC1889C07459888D73A8398F2635EFCF0B2FDE1189019DEB47E75D5B592B9ECFF329B09F03E898FA157C6A99CE2657F8BE6F6FBDAE5076EEA6223ECFACA2C7204C5A7C7FFB06885B78DAC63AFAEC102B20AD0E0617D0DB10165886B1F423F07696CDBBDBF384A6780863EEACD3099241B0C30F1155C5618F5824A51F860DF97CB16F19A0B478408A9ED61A7A38F67822C3992EFB46F72702604DECBBB516FE63D9E2C356F8A4C782F1B860737B2C98FB6389D34E72189FF0F93BBB068ACE2F90725A11ECFA791480B1E4D8CE931684F3936CB1CBBF5C47F454AD012C46B02A823DCE7BA163FCBB96E1CA355DBCC53EDC897470356BA487CB3F4C6AF9B2AE41BB9269A1F3CD4C08A74723E352528A19D3AEDE6AA193B41CAE219698221BDD08EF25761328F317D31A379EFB59EEB725069F014E07F5ABE1E4630A8FE051E323BAA38BFE984A99651659D352785003D2464CA48BC6511E5F9696879AEFE26C6F67E014FE291EDBDD84CB61C1DAE67F7DECFF30C2900672D142A527C41D5BA5BABF296C657351FC0517DB415E420D0A93F3B3ACE798840D4327D68BF6DBF459E2D16A789E8D77E64876F511EDF5EA330A75BDAA8F82EC33BA25AD4B64F097D1F16588D5CEB4163B8790AD4BCBB2AFB3B504CDBE936993651D95BACA39C8C64D96549B47547F1DB7EA53EA2DB1EBA552B2A5BCEFA82F0EAB20F95E452CEE39C96A089F793A2510DBB6359C99277F90484C47FCEE8C331DAC2640F593C0F8EB07E373ABAC3832828701D99B722982E7BCB4FCB40B78D9681A8266C2719C4103B39CB18037ED7026580C8143EE9E311A9428D680A0E0E3670BBD25CEBDFD6177516087D0673D73A436E5033B30ADB5874EE1DE38E017E158F6745D7447745E55D18CD653C834D629D7644F3DCDCBD8C85E18511D5ADA4AB9EBC764FB078AEE56C4895483B1A0A6D597BFE89E1CFFCD456F0CD994156E8A8933D577843C714CBCC6713D13FB9C4DB8E91EC971C5BA4E90112C105D7F8C3E9C4F1EEB2CC529D0A564A41426B13E89CDAB85965B86E0E9EA45EC9428536A4446B349AAE57ACC10CF1FB4B8A9E7092D6EB0E41D357629A9220CB9B970D5932E82023D83FB716DDB7CF7EEBE5D2CC88E1ECA2B4F278E8F7C670DC7ECD03B7168D20DE000290A83D97E9CE8B36BD6176089D6E47B00384378040FC70882BAF995B0A34160AE8255877E00A395017EACF408CAFC6FEAC79130C102B9F2EBFA357048E182AD11355A1A5CBA8EA7D7ED46481081778C423910F4510DA794508CE5BCBCE545F141C935CE696B547F4D262544EA0528B5327D7AAB12FF4C323D343E9A9790A4EB638F3FD06B53534CE8CCE022C7F848BB000D51295491495C4475A95CC10E7AAD59BE8BD0BD3F3CED728880245EDA454B4EF1B3B47C7058609549AE35D206C0E2323E18325B43486DF7AED112A2DBD17C2C1FDBAB64FE8CD5DAB4D31119EF146A0E4032E795D63734B3F90DFD86AA60661C0437DDAAE70CFBE37A74A4640747537C2DA404821E36626B62FAFBF875289E04E3A05A46461F60C574F0573F0E4810F43B486B06EA79A4E361ACABE0924677FE7F92E9279E7D4534DE32681BD605CB7E05AF40067C8323570D2AC4CFBCC7EE4C60B8CC2C96AD5C64605770EECC5A31506C106A97ECCF39D51B21AD772D64AED697A9A4F1C58E80A0A9C1C46A937CE2E3A504DD1672035D6546A896461376302D825CD115E7CF062D3DD4B5A25CCD25123FAE3D3EC59B8E0E1E453031CCA69320C00EE9A7817A01E4220BBE" - }, - { - "tcId": 10, - "deferred": false, - "seed": "F09E23ABE72DF75EE36DC1C952F56564FA4213A987A0656FF758F3991BF4E1B3", - "pk": "A7DFDEA74451C4CF87EA6233AE41C923055CDD85ED442FA912340D2F874F25ACC6AF867D21A200FEF83B993B4467B1F0B85F78505E04252E6BE367EEBA96AA5A383F3B82064954EC279714389DF85D2EB0B045D86D683B112A2A2BA0EFE003BAE26E42C6A7B3850E120E2C21F20DF331CDC18ACB55ED13D3437715F5515AECA0C9BE309EF6B5C2C76C83DAD4CCBA7171FCFC4ACE6F99DBF1CCB16080974157870646E27F3308BB2B6CAAB100C45A2B91E503F4AA74B82DD986C6B74F3B05E0DAF1E56AFFE17A253327F0BCFD4F3E8218C0E4F214B3603F93B1334F6B7F38FC6BCD7B9EAC364EA5ED73E7AE79781AB759991D0314CC2885D6E3DB3E4732B6317C5B6340A74639C53979B8F1CAE222A2F011520B13BD212241D0A7DF191D281D9B4D7DCD67A0B7F7BCC88B35C13119D67788DA711BFEB79B786BD77D3BF0A4631156EDAC812A77DC5FD0AE5B9F7BF8468FFFF04FD7256072C667A75C5BC983DEE7A208009E36CBD338AC5F7203BB6ACE2950ED17B1D2C5BB4449B1DA397E77BBC849893AE1340F3ED4DFC4CDF8CC37E5ED9D1FEE4F784E5040E5D4D5384ADEBE45EDDB64F4BDD0BBBE1CB19491CAEDC92F39EBE1691FCBBF6CA42F8918F6F55509BDBBDE603B4E39DE4D2A577C895F6FC09347B8C7635AD6A08B9F537104771AB1848230A72B5EB8875E7A2F5B1B83E3D3428B879D872002B5BF59E8EF1E3FDA75B2DE1B5D72AF6466731C4892F3D129E9FF1D3A6C5BE6DEF1A24C50B432981EC213DA5BFA8370A13C0BD06707126B4D08B6D945D818EB437BD29523A8ED95172FB9D644C4FE4E82CFA9DED35C26A0050262D679BEC360D3C995E11E0EEBC91E2D0F8EC05E6C01749245A04B2AF93A12D1CFC51E6B44CE15D71463CAABF53085E94263ADC3E8F631BD916A2773017B9CCAEA46ABC65F112670658E3A4A27F2DA0FD44E6E0CCD8ACC967C5A8216A0DF9B390189E3FBC3AA7C7D7BDBF994E93A901AC07DC912853269246420CDD9E42C453D46373C52E96ABAE9A00935B8FA935324D039299821576B5ABFF44C8409798AE18CB74000DE3DC19BC76E97F94BD212DB980A7E991C835E39DD3E262F14B6724DB0E05783EEA7B0E671EF233AFB7634D94D0FE721540EFCEEE3FC8CCA0F22B9B968056F99268BC58168F35698014144EC4C4C97E79B6C46AD8F8610159261595E7DB5348057DDBEA726AECC05859CF1962D0260594A00F2FD5E7DEBE7B5EFFDC6D71E8366FE17E9D0E845B8E98A8A4CB1DB51205CA28444D0E2D9EE86ED0F0F236A7A17026463A4E4B154B07E3AA32E4793C028F069C35A019E7A95C079260BC354CD2A2DDD5B75A1D09F96A335DF72E4FF986032E50B7924448EDE8895EFE636B65E2FDB1646831993C521DE019DE51788AEA4E65AD058DED635F94286B198095B5CCAB33B4C7C63093CB24FB705B6475F2C30E8F1A3AE5C445A500CD4467C95E2FF52F793E76E2C4704A4FFD0909181CFCEE87140ACE05338654483EE2D275874190765187B592EE9CE95D46DB4F3A4B86AD0ADC9A851B6A0E32A16C2B3BB206864CED0919596CBFFE2BA045D749936D14F0B5C57894A4271BDA0C9D4966D9D7B82C65397B425DE86781A78C8EB2ACD4299520835AF46AFA76CABB251A9CDD3D70705A28A33187B73F9AF84DB5E46D0C158CE57DF198C990F271597F51AC056008FB226891D66A66769500C16CE71227960F05CE4110E9A3DC397E727ECED0F37A291012B7AF59749700352F5D9368D4A055EDC9D1204DEE266E7103DEFA0F24EB3C3AE05A5B640A88DC5C71B790A8DBC97167A35EEA719536854142C09793D9112560050F67B457F6EF16AD550905A", - "sk": "A7DFDEA74451C4CF87EA6233AE41C923055CDD85ED442FA912340D2F874F25ACF5988CCB4FDCDF38F0C3612FD8EC68184A108B98D6AF0DCF04BA253D531DF1E5DC51829A30A5D0C78F58D2B9CCE6D4448A8788A68262984F2FB5D67739ED70D932F4FA61194B2ED7C2579E33CA3E4D5CA2F9B34C960ED4F53900CAA7D6198C211A06890AA424944042494271CA96310B4864110512E1000A092646A0387240C22D44868D8A2811233009C3C46409836584369114C9905C2285E1240420B991041165031600D922881389088988314AB87181400100442ED0884419470260A68509B78143A68118B645142529012304E1A42C48362A89406919A98013410AD4884D20270A89A00100412C09370421B088224584CCC62CDA9890589429D8442DE38429004502DC8284614260A0A449629250000564CB965192162C1437816496645246291B17100193654A06689A16308B044C1A98640C1949C9A60120C029D34248239809D4140010017103938023350E0CC91110A311CC948013206ED914459A04648A029212A72948262C228461DBB08802A00523A804E11684223591131931449209DCA68903120254A64841100008B261CA0630822446940641111681C1280DC4A284CA3472C4A08DA0284818A36C41A48C23B940DCA0490AB58C0C195188462264182810040E09826D13434AD0126A83C828D0462A229310E2304ACC108AC9C269213725083906CC0632DBC625C84404E2B06C80A688A026511344805C48600AA3292009851486502414111A948111A8308A8600C9468621263021A96C14032AE1C6809C20829C0291A4B0615822299332051AC1052180699C020E9B042C4B224CA4128182A03004C451991211E2A644D3B46D010992E3800C02054824B44001310154C0888CC0444214854024615134022037225A26450B318DD4360164067260B625220928621864D2382081064AC03090649820C8009113110A13A47020B064E3A40C0CC9855384005C4271942860CC062C0C1622E082854424494CB00104186ECB46651220455404024A3680A1284AC0166C183212024189D3026E504044243348211272C2888C119481E242859A8030D0184D403492A13030090130408870409288201705D9C09120A009238324DA04254BC671D8484801916519046613200219268A599289928870203670E1C64444428D02096212398500432624C1119C16411926054920269CC6008892690C102A0A846449B42C0131061B81908775E23EA2126EBB71325D654C031F1FFBDDA43F012EB01708059BA2B7A5F6F039D05142CCF73D20D925F73138CE91B8DD34AAC7F033135CE1465D2B386BB1BF4576645C728244A87663E1B33542C8EB560835C65E6FE833E4C14DE4F2CDD738C29D42332CBA5FCDC6BB23417F5EDB77AB6951122A5D68AC3E6D8B6267ED26B73D45E82C720D382025D176CAEE9FB343BC98E8A44378F92A687B99DB7061627DFA3E226E2940F5A83A8575E6C644828E5504C042932357F3AFA1F850551465D8F5A3D582434AFA13038699EEF6684001F0B736CB48A1DB1DE5998974D5B8B1478687D432822AF8C3B0F6CB2369BAC2D6796524A8E87214A93C9C952B36D21D3EAA283FD4E56421AD0E94762CD8FAF6010E63108CE2656C2F3BBDBDF21F3C39BB0EE4392F4F72D8C7F864BB054CF787EB0E9EAA54EAB1CE7306590904B78090D61778B27B7E45BA078B49474A017441D4E4FF9C4B722B423D35778B97187C505B1CB8DF644F5220023645F06AF755787B20ABACE3C8E89E8A47AFBA5431CAB8AB282F23020FE82C6CE569A1064BBD981BA71C309B6004CF79B2B5506D3428735DF01DF5FA01E36603D9941A9D1B41C85F20F9C341D7BED9CBC798FCFA4599D7126DBA60861CDFFBAA2BB41F7A93805A6833DB711100726DEB65DBC1807769B6CD056848FDE5506F4DD1F7875814B5C1710FB52EAEBE4485F5D9F04CE8E45CAFB4A5A57EA141702DC161A26B93E29FBB8F851670847CC9652B71EE58B6F15538BE0E2711F47B2F090550F2BBB225CFC24439904D70451044EE0A43A464F1B7D8585C07D8C23446727CE490E8F00E6905F734637146ADFB0C0D7521EF49CFCEFE26C9E5BCD52994FC2ADD14E1FF5EB35613EF09754DCD7C442C3D8CE94B1B54542250C37A9CD1BC4923AD391922E728E41C2918A5C3FD3CE863EE93E653219438E9A3CC4FF6AE3A143A01C315A02D0A48BD370EB4F8D4135BE517CEEFA3B170B18BDD3493612F548EE98B570560ECE0ADC80A38A91E552EB94FD4A10ABA93E70C1A89B71508D013B3E998D26C9E10A3868AAF56ECCF41C67AE7384C0D65BBFBC1BABCBB66BD28B66F1788E9EDEE262224CBBFA1A1A37CEF8367C120EAEF2C15BF7671F08AA6A7602470905FB16A76E4C6A8973F9052FB9C64B099E30B196DC961F0338CB3CE2C6A6950996D0029C2B10069D27A9B5A0CC04AAC59E4A34F3D80F9A1DAB54823429A5BB43EBF7A987EAD9E4B4C0BD0BAA8774E3662E5C3F4136ECA28C062986EEB4C81263347BFA13CD4CDB9BDCFD718635C57E29D4CB9D3F236B91885B6BD5F2EE49C4652CAC647C07FB4AA54E650EC235A5D34EAD7B3F7A7233B0976E5D5A22FD583D0903BB7AE10F9B1DFEA26A0B8DF10E0CF1EECDA99A4C91D31356975F8E51C0CA16EC56883BED25DA08FB6637A71DAA297E827427E29AB8996D9C7FD1ECB3810D6F860C634A2063890C0B8859004E253E7932726CDF16EE2091379D01F9990012FD22E95589CB2F88272BBA855D7F76677EE52FD12E6F5157359DF06E6AF3EF28D2B2AB897892536C7B14D56AF49D02FBF16A02CE1E56294691EFD6B5A59C9295771854560D6A7DB4A4425F1E3EC07293BB94366A9701001FBD5B46DE69F6BB0782D5CB5C7AFD4B6E5402C704AB7ED7EF1D2C7EE1E3E09970733C1CD8C086AE3AF2835101F5FC25885B6FD00F8AAB08679A2F33CC591AB96984A1809467E2393AE6DA4FE5D93E9CA77E5847FBB81F779691442BECBF6D0B9A2E33CD70870617385C3A6580D6E14C3ED7B800C12B8403689DE0DF6A242EB198969D7B943E5B94867389D96904EED0A973F7BFCA95A83D6C8E372BB1F6FC17B5B833DC81FC175452CA55AE33564664096D6C553C1BF3692A5A018117A3413A13F71ADCB490116BF83B4F16E23055E68270B6E5C03F9F2055C6BB0373934A16C45695C76DE7C741500D25F590D0C46B24AA0948D7DD57B4C5D50B5C720737366D6D491DBD18C5939A45E1A9382E7111A467BD89AB60E011AFDEC391B297D82C1C6BB1055AC7F9B4BB4D9D326352AF799B2F798F04DB9A8D2EECC3FCD578A20C6966E83D2A0601E29A172DF3B125F1F9112B5F378253C38C032DFEBE100569984ECDB80CC31DC7A310CCC80CA9257F39B315584F79D63F0000023D2BD47A807CCDFAD45470A6495D5BE3E5F4DC800D4F429225301B0DB5C24400C72BBFC81219B57E18DAEE6793D414E9058C9972E43E6FE823ADBB8CA86957E5DC17B6331792879AC0DB171AC5D6937E9CE8A5C1CB62E9B97CCB2072B622E61F20112C13C2E4AC0A5687EA974F621DC8D7BA3C0E6321BAEF498BE626ED7FF5D0AE541903AD9B204" - }, - { - "tcId": 11, - "deferred": false, - "seed": "F4476E8F0B3DD9319238639F50C78B3FE1BF404EF184AEA2D9E60D3028FFADF7", - "pk": "6C395EAF8BED18645113C013B8B55899A2DC27E31E4A246CEF8098E76F55E02F7F194F429456244129C03AB673F90EC9BE818AC236E107D7833E8499FF3532B9590731A3922F4EFC47BC9E14F7E2C09FE74C79FC775F2C577A59FDBAB4E94416F073E6B40DE447543AD64C3588690AB0A7CDD6D482084C6330EFDF6F9F64CDE8A7A501E555BC64FE08AC7E1AA0ECB9660EE9FB5CC3054644B02FAEC869098BAE6D524946620F0670EC876949BE7F35632431DE473BE80BDB81A8938C8B7EF396A60E42CA5C2861DB5D787334EF4BB00C9E72645AD1F372D9EA3CDB2B66526C8239E6E2D2B6B908963E3AD436B65B45EF86DB50C86D12C71F9BFC44DECA4BDE71A0940BBCA89206B225A24F23EEE96831535CC0B0873E4CC04E5999227051744F1A6B709AD21DC4512C2FC7C52ECC7E765FF51B7A09C80ABEE5412D8D69BDFCB532CCD050B24C7CE50D8CA8F778EAFF3AF167FE836767D3997FA72B3F9B09B2097E21229CF33600D35950D6E7CE143BCD2BAB17BC64F009B43856A22498019FB688E132476B97A8B19B7F94A162617344775573D8FBA23CCF721AE457D643B924F1B73D0EEB1EA467B25739BA2BEDA963C97F63219F14F1709F54A257FC123036DF5502DD04F8B5F08B927701C5356200023EEB7C3806690B950980C0CFA308595415D296336F3876B435CD0C4A001E1BF09082C8F4A96B87F7DB0A744EE39927385C0BB846C249D4CFFE4AB61864328DA610FC856193E75C3715CB35BBBE9C23F0FF9695FB65523C9CD5F718E505B2AB991154648103DD70645A1EFE8972DD80B5F7D4522CBD4A0AA2BBAA45B328B693AF88F0AE2F6B2BCE6BF27AE95581FB00FEEE342709B34E6BD0E2E65E63A8520AA260D601984E9AF702CE338FCF6D7704D712202B6DA7EB96C1C9C848C40FCCB3ED55B9F4004D7D6C57CD301B0362C36FAF5F52AA7A0AA6B78232EAE801A67B567470647744CD4F8E26903FCB14D59DF6D3EF057518EBB0DA849B4A743D6146C14C4587AD5E7A393C658EC91EBE970D23305FE9A151FCDD8B7C332A26612D349301ED291E8DF0A01099A0121EAEEDA07FBBEDF015DAD5F5655542A59F1E0F2582C78F8372EAE3D22F8CED5EDF73207843AEEAFB34E3DB9409A000D2D5E5C3CE34983791B3ED407F85124E5625C88E2C74FAB18D53D18C3652B37721683DCFF834FBCFD6AD7158F6AF0BCF9E4F41C29929BD3917403A679EB04F24B8A759C9C16A7763557CD23EA3DCC409EAE49DE1E473544EFFF60425679EDD7094340750FF060F2C25CADE96F5091A080E634CA1FA414B7C7C06D1B35B28E2F7D2A8131E43A8BAFA16FB4EE1FB7AE762AAF69EDE9FD79EBC831F88AA59683A296C0C0645CF0783468C70903B9B9BED2164B6CE5E8B118893D45878D7085BC2F140B39588847C0BC24B280C206CB3F8B2E40C27A4947AC92EB97BEE5422A7EE96180EBD311F6D061014225F410F91048267FFA13FB2B40EFDA99D2C15CFD345966FEC37CC1744E32D99DF751847E07D69D890847F53BA3953601810DDA13102D98519E586410CAE7033F8A5D3077E045C186ED50C399C32C81744A921FC38AC49AA5D07E5F016AD3C48E5BA637A6755861CB75A4F6F6CD08EF3FC2F2A16FB5F73EBEE9B74DC7108463740CE3C5D043EB63A82590BDA9FB796B08E52F4056710DEDB65324B05461AE395E888BF81E16FBD44D9091EFC03D1D3793878597562EA59CBF4CB8E1BFF6212CF2FBAE2722ABF478516F64FC3D5EA10179645D2ADA0F668EDA3678B0E4EC1F80024FF2D962EE5747B84A42154DC07CC85219F16752F571FEF4386DBC60961E8B8D7EB723EE1F1E5F1E1EAFF185E", - "sk": "6C395EAF8BED18645113C013B8B55899A2DC27E31E4A246CEF8098E76F55E02F1C5509910FD8171187717DC7FB4F8DABD29CDBD28C23D7809EF6B58A4371C8D7E7007D0271B40F27F9E379D6B87D17F2402D64EF2CB877B44B67CC0DB31E60B617376DA349AFFC07B219D7B4BF9791AAF289E81F03CDB8020485AD0AD92993D8D0A6852403281100221A25625C400262188AC34662CA100D80A42464486A1CC184A4042A132150CC202252960C1CB84C1A2566A028325B206D0B87901A048C1AA07103429252264E12032991A24882360E223891C1946008B1284CA84D08314A5C84701BA50413B88D1C1008202466A11042118170111911C2242421432912B641539209239948C43868C0166920C64DA04645134390D2183210170DE0100401829012158883065062261190848924C26121270654320A1A090D00A2250B053018A210C410895BA6898022615A048600158C03180EC312600341851C174A0A42018198484B0409C40891A33411082952910626C29005D12232DC38602336245B1621C4302EC9988418140158C6900C872159B2895A062651228E19092D0CC04008408620448E14C269103840DC260860008553860982405289022AD4186900A305C11672023624CC404D01450698A0410B184923492D00320988A82864808D5C802DDC06051C86695C326CDB464459922C11378E1CA771C4926C94B441949240994401983228019620D8C6606116111B9049102986510008DBC069E380041B080EC4148ED4884D24990DE41488DC34850C32508C300D10B080D9C645C9C469222412D8A660233830101224DA4450C196491C227151A82001298622A7614C845013A42C6042058A924104A52C084831CA8061E3365111059052C88DDBA48CA0464221044D883481A0A200C3380E13986151C62C2348928C024561222511C24820160DD4205019856CC3208949B469C0188864383211165240849010B150A4386919A96563B020032009C8C62454009289A00583B66482A46442A09119B76C0AC28DE4948563329152482108178CE1067159144E92382D9BC24101B920608820DA067018C16484386A0C1460D4320111199218078A89802858C001D290111C070122468CD1084861266ED202219318664C428A9C942023B81013308801B32454245209152608B30D9A48080BB960024311A296281B476C483289042824D2C0481AA6105A826421269020902D09165019A1241A852418141102328882349221B800DCC5B10C552CE0DA12866C8FAF547502643B8A02A98FA05EC5CEA052F3BF14B035B89DADCF5CDE85716C2673374E6BE9E8C08DCF4190C5A6AFC0FC9F786F80ABDB5CC0D78DD48201566462C7ADB0AC4CA23DAE66014DF5417CFE62DD7F82DFB10E96A3A0686B115E2447639E43F153B6D05A38DA088A280FF10E7837636A57454D2BDDC54E877CD4B527AC664308C1699A614B6C6E4920026BE5469505A3E30491B8387F2802895F0EBAB983F8339632CA1EB603C2F54130A21D8568E72144FD764336570D719B0731FE709C2CDDFD06598F451EA2BCE3CF5A07F6FA4B508A69EBEA1C892E88557D6CDB0BA6BE9165016043AC6A376786741AC3DC33F73DF74DD62BAAA41BE09B18C1FA3C30478EE0A748F7EF4093BEC0ED3BB579B2634EE0BA6E4D31BF8EC0B7D400338B979A9862B8BA3EFC81155AEA703023372A686DDBF98E1707D63071E47578EF65930084995869106CAF96D3559D193EB6CCC7593596C2DBE3E428FC95965D4EFB7F26A5F8CE601EB2FD0B8AB722C748DC3A1F732E882D9ED645FFD1204EBD73320168209850E4719FEDA0F5E0EA1AC258CD49444D168928D2910DDD35AA376A417A579C0BE8E0E1BF3578CC7448BB0C277B0E147E6E579EFD21CA05C2C2A4DFCFC384D88157A80336F545AF1460F5B36EF41B98F4188226FBE2FE483A8E4CE1DDC10B16A4E93BC994883D3DD5A8EC5BB64D6CF68982EE40DED10611392154A961A4C7A961CAAFC1290324D6D53B3364EE6990D4B4ECEF7295C30B2A004F15C1AD3EE6DDDC8A3A5FF0D9B7A99A35198ED1FA480DF3FB2E136A368D67D24294D4BB4203D8606C0433B1956D38296A891555802BA4F6A518181FE1F9167479C3DF67CCFCDD574E631C874604B86B8A775802A247135A7C15F924BA3924E40BBF41912B1B24E08B499A666810945DEFB9FE33CE2449B17AF3C9276C732CF15C6EAF5A41E9B494EF366A7E7AC6FEEB4333D798748E8539DEF358FCEB1B4182924049C8B05BDB346CACC92E83E84A7BBEA97D4BCA0E9F237794FD150FD8F1A9B94D2A23DCFB207159BCCCF985B01A8F9D0EBF6C9AEAD77BA0433ECFF81FCEE4536CB54478B630676CF8EB7FC4C31B376220C5E6C49C782D7466BA5E7233364E59B92E3252FAA07C528FA507A4C204E79D9C4D8BA011B825961335A778C6B86909AF2F848CE290D07104FF340BF4AD6920CF89623CAE4AE4F53F21EAABA0BD91BA38563AC16BD8EAA42546524000C2DF03CF50AFE84ACB0F2705AD911F896F4E52E7C8F0D3699FD506EE24608A377C8332DA17F94C9473571EC00E48BF68E6AF36901C922D6C2D7E3CC48099056EF2B7015ACA61BBDC02E4E8B8C1F4CCC51DB1CE4BBBF23A097A45BD93E4968FEB79EDC4117B5A5E38E962C1DD737BFCE6BBF66760DA004A009558F73B5A0C6269CE6DA2EC3F49B350A3D0DE04B08E84DB4D2C1D9FA74240E9F0EBBF8027F69FDCB184045240FA2D212BACA4B15551C6C3F990A2D4AB05770CBD97DE23A0F0D625FDB623261E430989602245B0B7C6299751EA2FF5CC3642E11FE9D3D911F893189F7ABCA9C5837383DB16611C39A37D882EE24DE730435AC2123C96DAD7847A0176ADDF49BDFBA9725D0A3E50D5574772E1A9B131A299B4416D86C6D976DB45547F8C5F4404EB824EAC91C475354A2518B30D050081EBE8F86AEDAE639B0FB1854DA56B5859DCDAB0209E6ECA00A5405B14882B115FD8612CB39FF5C7F79DC3BBA02A62E1A1FA3F6F5C0B67EE0416B9C3C55777375CA6CA321E990308C01DEA20C966B148773487804324A916F14DA4BA3AC7DE2CC3CB88CE6FE7BF1408563EFF695A0A2C6F6CA392C3D3DAEEB45ADCAA6E7DBEAD25E9B5FC71D1EAE07B35E72FD32E569A3B783DC3DF1F957DA596EDAE1550D7559BE71E8AC1BB02AA7EDB0A44D3B0C0F796AABA6C009E793350E4A46F82AF02A58050909B27CA9F4D37E515193BD7E794A595018D52AAD56D03055124EBCD1DCE89EF6EC705D98AC7DED9C1611C580AE7247BEB0A8E0A23D888D517196410968F7A93DBFD36183B405A8FF26E8D04D90B22747A95BCA43554CE12B4D1E8B0AC6397B100762826EE25AFF2133A6B8612A82665E6C3B20A6AB65186949B4AF63FEBC9D09E83D2DF49102DE25571C1C453B03419F9AA06C59BCD12419493554A77DD57F8A2FD73CF8CE6B4E6CE056EBF6BEBFA867C303269C7A48386B3530F3D2982DB0983BC5208DBF1AF9047CC7C75D3A29B4904ECE54E52265A51EF0BF1DA09BC9DF56470ADD9F84AEE5DA5C2C0F6F73E545370FE919CBF13040FE562B564C84D43EFD09CD4A86D57A01645006058944E5CB4701E6DDEC2" - }, - { - "tcId": 12, - "deferred": false, - "seed": "130A45A87F380C72BA709CF5A432BF768E1D875A30C860FF8B74BC56A7C8A042", - "pk": "9F256B88122D75E988235D6AC427FE3D896EB08948FF95ACB7A50A3D892C2314A1C5BA8E04EA3D0F352049E24FD868C3E715385F6D4FB8F0ED9F42D6812B1ECB357BD6C5AD5115B87F6D41DF39922E7C98D58E5968A72BD420236D5B9AAD031B7433FFA6DC3CAFD5DE7F6FC2367CC8B9B9BB20FC1EA84B17AE79DB3C8C7F5A5618313DB8C3D42B45066E93B608A2D16F61E04F4216857E2C1FD237ABDAD2B027253F7BF372F4F692841AAB16D2FD320CE27781017B3B37C6BC242748B1B004309B3859445C8250C210FBF8DDD40549DD456A9612B4FED4D6A472A4CDA4514A1F10BDB366BED07C02C0CFD016DCAAFCA20F0D23D5735D431349E29DE31F2145FE90BB753B937823587C1E7CE62EE4F7D5E6D54D39AB3F8FF8E0EC72A49B5558CEA637C0E13CDFA4243A9F631EB3169FE395E7CE3D6EB20F38A9D72CD1120B920B551DF84063737A7787FB1A02B7D1C95BE34CEA9EB938BF6DB6155D8B5F6F5877214507561D41455FB91D431C49112C35E4F4AF5E320A3A1DC27350EDE5444A36C78788AD341B71BBB5DBEE67D7E3591759F96179235BC259640E796BF2B0BD1AC7B2A4342B1BCBFF0FC3443B113E72ED6D4C81285889F492E07755F181291526153CC0433648FDC99D296034C39C90D6401F60C4BF0FD75718CBBD8EA0DEC9810B7297F9B020411AFA0297F30C535542142769AFCACD7DF0C82B44223B2C07D9B8D01B6B8A0322CF26D4EDCAF9F0D1B4A39B41F831F1331BB9590074B4C3C457B196780577D673463FDD50B096DE197CF7E7C829C074B724B2BAD84D1A199269EAD5132FE1B0E995913513151A83CC6D7D9D9B3D0AAED432502D92579E70DC5B26C2DA124BB7730481AF4E4B0D03913CC48219A299DB782B0F149C54EEFB2E7029347F01B4061CDAEBDA4315352B466117945AC389F8CAE9F1ABDA7AF6D06C0DED532C450E50B1B8B7169A1EF9243C9A940714057C064A24C5E565750E8F95BCE35315C3AAA1DC00F34336EB5DE4FC191534CE624D6EE718537748A64CF893D0302BEC7F37CF50C6BBE2B4CA109E80DFA2B0160207407AEA0773C353D58EE7CD1149319D1254846C4235169D4173E2063470D58C363843AC28E2795D97FB5F684063ED2E35086F2691E60D82A0A98084FA90D2F8728FBF0FDA0575FA7F9233573E445030C4EAABDC055AD0AFC6DC4E490E86FE20EED7936FBB5C8EEFB33378D5D68AF4E03FEA06A759801F331FA357DC2C56BB498764940811C7A114EEA6783B181A87896DB9F5CE44F1779437A8F06F33040D1378CD5A6B4E155D95C1E866DB3FD48476C0C0E19A9AFF3DC131B8F8C89893295A0877FA7DCB186F00A4326DC0460F931819CED17E0EB0AEC37609A52C1FA290B00635DB18D22B1B6C909F2BEB231D22B75F7227DD37A8E8DAAB863765F643C1C568163114D338C409D775EDD3C1BE181C80A992B1D1872B874FBA52849B756DA852D391900F147EBAB5AB555A5E9BEDC3773C371717FA18C09651D9E88EE9422F2953BA56BF6DDC9A52BC286C84559CC39DE4DBEB6A2971504DBDF09BAF301BD9660A491BAE4B7019F20B40D73613F982DF356C584ED555FC6E79B75E8ED50475401B0B1F4FD2DA5851B32276D81ABD0C45C6ED1A44B1E57AA25E3B1D79219052BBCD5A990BF252CCF1AFEEF926F7BDC0105BDEAEDB5B3C9020142280E86D2388E323E7087689C0F831C3723DFEF7319647CC9AEDCB4059AE574DBDFB7ACCBA9144A73A039E23650668848A0BF3EB960DD89573C7A0107CC723A8237763AA18ECE34DD26CB77F1A5859CBEECB9E9A38E1265F611D7FD4F6985C9E29460486E0A2D05F3CB6651FE6D34AABCC13", - "sk": "9F256B88122D75E988235D6AC427FE3D896EB08948FF95ACB7A50A3D892C2314D7B62A6BFEA6D3859D52D9E096B609AAD8BB46BCADB81CB2598549651A77127529453228DF894FA3E83B2E00C70242514AD3DE776DCC3A52948E254FF5E80F5FBDD58FDB1AE63793E332F520D44333481F8CB0F70ADC8A8529DF06389BE84DC75C369104052E09274819322DD906404A92250C152412456EC91224042404D834805BC40559420409C69194322664C82441960D2002420AA631DC12840395494A1444A0480E0C10821A12024302411BB12D1B482498162C1C444E194521E1308464342623498061882D4B340088B0081C208A2113855318605A2070D9A6006314801A132461320103B265A3407218127194A86102108E8CB0110C1568630672E2C081241290E446685CB2692200254C4252891444123988C11684212348191284112730D4B88441C8655C1090D442465B207010327020132C24292A84424CD8866C99164A1A293209278D4284288236691C378EE0A88C11200C0320518B96302427611B946594080E02390061902059065164188D12B26C0B272E91962058304601264592B42554444A24114292C045E400320022521CA07192028A64B468D086601B326D14900062062E01B0690CA4650B31610A42124A866D9216410A903109370A888688611889C3366819B971CB940C0144251AC00D19390614B41042448621947102952542940980A049213425D208520BA651E00841C8A811E0041040088210434222972D832470C14210002542A4B24914270DD488680A37489294055CC46453304A09B345CC8640543222DC1890A2322603116C04B930C21206D2342CC340861A02881931442443698418815328691B084204B9441046894A4426C8301002B74D0307690CA32CE0B64002000AD2122242B48490480191262D824005D1464CD1946521998818C72D199865012070A0A28D0CB184D186494334891BB56863C46488306D108049A1224090180EA3444508A700D04851E3406290C648A2164D493689A1048C08046DA114314C308E1A272489842D9122041A3422D31884443805139485CB86688A220DCBC030888648000170E316410A39615A384908B96D0AC38D24B59150366CE20006C328514C344819394659B02460144E14B080E020901241091345041A484DE02686CB8620D838690AB124CA246A194080DB286901C9491997090A080A90A8240CC9401C496510A80492222ACC362024288D24994CEC6E9BD02A0EEC00AC1F6FAAA0A5E59B3AD6D721FD88F05CEAF09C770D8CD7D29CBD845E2DAC16FBC72415DF6FA055F335588659F9DFF7F1C6EDC444E08EC7B62A59695C392738349AAC209B855E84CD5BAB98811E4F728550190C5751C1E4CE70D4795F692ACB1460FAC5852BFB14A52DFE75ABFDFA0F444CA860C77CF84A324646298B19AD7C2B967203534C5976A10EF6947AA67AED44342D448ABED06D52F53A19D325D613BB765B2FEE469B4B7793F4AA47C50F9B737B875DF641164524583A5F656B671CA99034395A1AC133400DB425237A20C21088006701D21D3C0567C8470763A773125D518525F87A0F70A6A9A55B52D7D8EA539FE1DF29A297B83C354A7DE6A9BAC2060C4C72CD11FD2177D7DDF65F8CD7CED7A95EE85EFADAA3B236DD3FDCA5106F1CAD4C528AFEFB87EF14BE8E7092086BEAA44DD8F090D0FB4E21B3B7A23810D4ADA76188A2D8F55F37C2731FC5A4758332036540B2F866D85DC897F3B0000C0AA5E6368EACAF358C515C005C2D7F5E971F5EB538A7B9CE2D202D76724E4BE869A8F0E5B9D888951DF989BDB004D470526AD2B795653073E65070B28B5041C55AE12C7BB7C332ECDC8D05569E8F62E340D497B6EC687294D87FD871A338EE54A72265AA591FC3E55C34F1E0AB7668964C137EC4DE8CC3FD6753E431D748A30AA09C0670B8A467D5CDC689FAB400AE2E5513AE279E43A35B6F79F839AB1D5EE6F88740A794028FF0B6D3D866F3BFE611211F3423BBB28DF54E000042CA0A3EC2A0B5CAA2A570AE830800608E62BCE1D54C94CC2D7AB7718779CE09B8598753661AFC9851A1E08B2FCBBC729D2E8C598F5A145C8D4EF1AB73CCD13F8F220DCD63C06DE02171113278FE5A9B9B73A1B046BCC7AEC817664853A0AE57647F59794EB5A193F00F96FC4A3FCED0AF132F586626EC803F9BA5919BE3667801B0F7C6BC1F8679F2C32929CC013C59C9F9A1C04EF52A0F8B1E68F0D66C7EEA1C59F9521111BCF4CD6351AB7928488856AF77132495AB887F8F235FAB1E15860C2BA8354AA91C49096C262687C1EA866E0D1D23A298D97FA1A950C3A9A9DD5483321AD49E0A6797648361E7A37B16F71D95CE1FCED2F46B8946EA164875B2C42AA4AA529FE50301FCCC283B753A58A8AE65345B5010325AB9F5184EFF37C46737CA9062F108044966E981528B43847E368D52566D41BFF57982847511696B498CDDE34E663D0A0895AF4E52398706748DD8D433C51E8C2E2B03899931889E5080E1511EA78AE0891CE0E3509E3AAD5853E00D6FEE95951300CC7368E392CE4109A032F4F6DF555CB321F16DD7DDA5F80ED1C32C22CC53CA56DFF33B153F2A687C8DA2C5E5DC87D294E45C47F5ACFD713ACBAADC399D1C1563F516CBD5DD736B77C161548659E3A695E6CD85B05EAE9B5CABCED4A1FBCD551759EB0F5E022247EA9877CE88875D9F66FEC1292E05544F59C221053264F7BC209F1128952CF7D17ECFF7438CD2CF8AA27F5AFFCF8E8C198FF49256978AF48592C2D39E895B8DB728B4FB4D89D3C5CDC388B3D75075F9482B43C0A6F77205F17F03F1B76774C36B26E555A555EB7CE1E1C458E8BF8445C19F6911C581E8DB7D2B4F39EEB604295B4AA0A37816C815F42EB9284F536C3777EA4C2B7C3D3D44E8F7F222C8E9BCCCA6AB7A0050551510DE4B6470193C4B5CE91C0845233EA3A666BA39C8089257E7E6C6184C29E75C9A5C1F9F807DBB118D521FAC705F224CD40E5B2BCAFAB3E31BAAB7C4A3B5409049184CBCD20BFDC66F12AB4E40A316E5B4960F70DC105ECB99C6AB56D79906BD72CE119E4E31672D7F7025E4BA548D458BB8AB782158304FD5A95B4AFA5EE20377F137E320DCB333E7FE1F13E4971B8E99F2A3995101E9EEE3950AA1E0A898052376B0CDB28A7935820A082CF52CB4A6A5765A7AF9DCDB7E15B70F1310A467F34B0B5EAB49A54114CB446A7EE038B84015877A305DC97EC70086637F38679B94CDF4F52E93D20D1520182C20FABCB9B73341C0023615D59B18C857BE6206BD10ABEB2D9794E4806C6EFD39D2FBBC15047ADC873525837275B4B9EB0863F103858BCE9ABFE9FE950EC911BB685D768CE07C72E7D7BEFFECBB0EA219F13B0C5EEF74ADA957394AC961B7B365FCBBA9E53DC6F7DC4683052A6EDFB44BFE42A69C4C16E3E95B61BBADF9BB294DE9D8798AB62654EB0DDA5C1DD714EE69E483748BECC6329A6C9709429D7DC7EACDB21B2EF7B8FBEAB834AD755CAFE804DEA4729ED64F8B8DC0D5F76C4554362599ECA9759183E4B52635B09D33B871E1AF49B323E32A1C6C465C6AA9294A30BB6984E188051C148F90FD6948A0" - }, - { - "tcId": 13, - "deferred": false, - "seed": "3D00709DA8D78B889875F40AAAC1635D2BBAF0BB7F37F6C4ABCB7220A5808F67", - "pk": "C978D4F3B96E78540AFBACEC073B62B2C94FA53EC08D49663274298A806D704B1ED86941A4FD8C65EC64BCA35BD1254033AB9B9F83FD10406E77D73A6DD23DE5AAB469308E43BB96E205B65008BCFD9B6D83837F96CF8FD82C9E3D0D3FBEC2142D0FC75E6723583FFCC4B19CBEE9A6431001C892871858663F1F4F2FF3E3EC36F099448C153F4ADF4CAF6ADC24C7C5058B9B3092575A37390771657D3D471B9BE02EA2C0B50A6493B78D0361DCFB877FB026D59C136DE1E1DC14E65ED16C1726ED311DB5E02601AE6E03AAA8E008725A9364A9762B1D12B35B5772A9E001D76B3F0EA3D3D9A016844B1436B967FB0448CE481305DF3A50235852FF620FDBF0897172135B8C528C449E4C7E49D6F84AE71613F30FC75DE26C6869A5D0B98371B92A9755BF2752162028B25DE982AED49EF9D5E4050BC4B2633CF537AD76FDCE838091947B451D16512B6B370DB983F86837F93416AC87DDCCB2926358FE01FED867FAA2DF6BB7C001B367B56FD5C6925AD63F06696C78981DAECD4E90AAA51B2B2A809425E5EF1A884061AB0034689357D84BA0E6282B770B1ED5D5122B6C43B446355ED8350BC3B6183B4A96FAFD1994B0E1D52FB337679D4693779226C4B7AA79AF2882E58D74C906040DF08C36415F330F56BC8E35E9210ABAD998183C6F8A324B30BCB4499382EB96FD595ADC129C68FE0855E584FE716104F663AB2194F7683A62E217ADC22455408CFD0419D157EFF8AA816DBF6A0AC519391DB6FD2B95869B1A1D763EDEACFABC4F086750C26C781DDE6EF3B19424DAE49289C3F2FD7AD08698C05D0D121B6779D77CCA6A00AF1E37B6CAAF3663260EB06EA77CC4C775820724E8A4CE66BDBB446B61CE7C195AF164468B111016A8BF2B43247EE076CB7F27FDC3CE9A97E506C7AAC8F16F675969086F38AF49A165717C694612F3CA4BC9D3DCC5C7CA499CC92CD76CD535DAAEA822E532A9231BB965646E2FD080DE1346A132F4DBDD7C7201CA26735978F5685EF35B7441FBF37996C7059F56AC93E07BE51B66D270423C6F6577AF624A6BF257F2CDF558C0F6D488EFE24B9EBE7265D2ECCEF3034F9D26CDDCC2861AC97F156E814E44FB859EF4FE39CCB96DC25848E1CF9174E38CCB69492ED2E4F2313DC76B0E169C47246499C0B01252F6A00C7258ACBEF3351D131D5F6C83EAF2B51FFAFC2A0D274317F635FC159DC095898BF0BB95A6B32D6FE6A0C6DE158ACC5A6DEB222B94B74C3E4C0AF15266BB455A5F5BFB8E60533771267E0BAF8982226578667D80DD16253069F5CAC2335D80ECCFDDC1E37A79256AE37077F452AC28B8C4602C5C4DA09E0EBBCE8069800C597977B5A67A36DC00C3AD0B53D77F1D19B64752DB3866858D5B4084E99FF28D2A834A77863816F569E2C929947E92B354D1229B62604DBC83730E1AD9DAD41E7E6B8016B77742514855B75D2512B9C88C7E3348B5047D0B816503439BA38A0910B1A0E14E2D95CDC1EE0FE8FE2A80E5F6EF6BFD4409760FA8707C44832A1EB0061F6F43A615461E331275E1038E73D78FC141F87D5112BFA2A1A4452DE08A8ED6F6FEE57F99C7DB5D1E4AEF0DCF68CC28D0122B312720FD91B50B40655557D4D6908B43284C4390820457F4CE5D21C82224AF09D56D4ECF2BEFCD658AB0044DE320E609D826E57209955355F03C8F41F2A2B91CB50460CA398EF778B3B1A83760322A6E675065E80B72556A80B774E1CC11EAD767AF196B8F8A87B4D5482CE88BD218C0AC6614558E3E81FB1664AE4C99C680DA41423368395B9972B0819FC0B4639E6704E4C8241A500308B5319E971972D1952A54DAD62547FC263489E2E6D61F02C1", - "sk": "C978D4F3B96E78540AFBACEC073B62B2C94FA53EC08D49663274298A806D704B64D929D9BF74F1242AF230B6A21911E89084290C4CA9B72C13C5824A6324C9515F2D8EC8EF5521FEB0F6D63388FDB8F04865596B97351014A825D9074E0D1A411698EF5A6B19194A18F9DD2E61651F8AD2C2981627EFD486EA75220666F4EA53E0860044B2404B3885C3462E50A83108142C9AB049DC02852138480035710C290102236A89C2401CC928A0942824082618868053164AD3228D4C10461812050AC628933489A4B80151904DC0082613C0005BB26119260ADC383224052A028868A2841100150DD0328251A23002B68D9A826CDAB2090A4266DA26640CB10583C84993484890862D1C0611C0222D0B14889384710B262ED9A6411C0331A0C280611066130288E4326AE298658B926993928D59B07118164C1A404E0B192CD108682182441A036C4404881947324A14081481850B104C10904CC2A61188402C03B36D19366890364DC4382481C829D34225A0B08D14165221386DA448681A070644B8301BA125D3086A58C20409135221B60512A288A2063254C84D53402914C8691BB25008B66C9AA42052C231083425D30409D3101013446E2224294CA60118C410D040724C060019C56D9A08729CB228E2966DDC1062620284D4160E23B760A2B2208B400C52B61108382D1C04800BB88D49184A1A4009E3060A60209004C45002B62941425219276418C7400C34220017290C26015CA08953182D0B2948181428022186924070DA26101B468E12292E2294100CC44C20C96C543631220180042491A436099A046E61140AE4326A9CC82CE2248E8B884C9C264CA3024D1924820C30691A050102B26818168E12222D880488C0C22CDA00649412811CB32144489114380100A509210990C8B000A400421BA8881099718C462AE0B00802352183120DCAA088123850822489C3826118B185D9342A51A20451260218268ADC282DC0A6090A232683B449420491041689C3A42403820880460A481826D3B4519B905199480DA0A471DCB6910CA4649C02840838028A080E1A030281986DCC12882334669B342C1AA52808469212110D033764C0242CE126328B208803252EC4088D1A190811186E0BB1014128648A4040E018329A840102A70011A269E44261448489A2306EE11490E2B00D5A0666D0064AC01692DCA65109B948C89424640640CCC44153A6240C248D5822528314519A8680200306248145CC1462A34682D920326ECE3A61DED4ECEFCB1BDEC41B15E8656E2F2AFA8158B7E27DD27CB0FA892E3F773322A0AA29DF9434A5B04D92F1AD4D6F31E6A1D6B7BFE54E72552929C886518BD5F6B4C7F473807C1C2AC8AF14D75C3790D6308496A5A81318B386DC2CA818D1D74B11AEC0DCA16041AB31D61DB7E65146F35ADFEB0C0585E116A8BD65747C58E1578CD5D8D404AB666BFFCB57BC015D841A16A126B66034E1D44C8B1339EEC30B0122948E66E8DB060DFBBBCA8B12E8531967820A8C35BDA3C945D3954895F6E67724C88900A0F93F667947626FF19CE2CFBC956A8DFF62BC4DF97CD136341264BA2B181AA0F1EA4E3C520662085F77523D42A6C9395A06476A46E8E275C0331222C49F852FDC634EBF7AC24F077C7B0557F3DCE457C24E1CD981EC86C149A91950D716D596381C4719D63DC9DC5A775667665426EBAB1D5E7AB3643074818951C25D43F79E82D8BDC4940455920394B42F9E95871BBFE837AC878D9DB48AA976A609EC33A9B9512A81FB87F7C502B676076E2CD70FC9DA795E274F3D0CE12259EC555C3ABEACEF09AAC80F4F8C41E077E39AFF7B5D97AF8C5B61F701AFDA28101343C8ED11123221358507AAEEBB6025CCCBD49CF41D0BE26DB1A95A8C5CE60E625493ACD6C39F035B9A4A200604B94CBB827164B6CCA42CBEABF46B975F9B9D57849D46A986F645D2D530A6DC5611CF92D92AF4C93350ACDDE4785F6902416AF43305D65B949CD7D29AAD6C9B7A3DE28A8983BA4E7A9123287ABFA00F7CACB6FE0C868C4492B264FCB58CECE465A736BFBC1E0403A1CB4D2BC36FD0880234DA2F90C8FEF5F0E12E47DA3EF05A15BA5DE31F67DC929421499DF52DBF00D604238F8C179D578162C65AA4F980460165ECB8D08F53FC319C51A715E4D8EFEE21B8B37AC76ADB189837D8A0C090A847AF3B0E78F2D4F2AFA2714B64F75E076E95EAEFF03FAE2C9A7C319D754873D3A3EC115D9DD5625B25EADF0D00EA12DB8988CDC167AC480D62AFAA5A301478304CE6187B4CA7292C0D4743BB000E3057E1DC899506EFBBC25966BD04EAAB8B6116BE3348DF1D3D6C2948A2656AE5DAFDAB604E38872436C5605B280308F8F8746626272CC9712161E5CF095DB53862FF1F38B40FAB69B81821F911073D4A098A7C6EDFE8632C55A9008D50CC1595835304BFDCFB43F515A00DBD0FDC0ACD5138B5732C50EBACE2867278DF1482EF3FF77F6BE06924DCC636FD51D72F3ACA4677B2119A14FA2E3B2A08C528B9F0A191934DB195D92D9EC305222E79B976A577788DDCFB030D47820310AA23F4B37AFB03E2460F4E278CBFCB30C9AC95DF06D21EBA32FD11D52A1AE8ABA6CDA337172FC863818ADCBD25B0E64C96B38A5C706BAB2C25FA45A616114C0C896E09D0A9F8BD5B959AC4E16043720CD3966858BD7EE6CC29745F6592B63A06772DB2C98E9373A215C642AAE4FFD6E84CB47F7B8E19D6B355F35AAB5BBFCBF16DEB73C2679A1A1502F9F6116300D54BAF65948627EFE620803A4F2D895899F24ED5A5B5A0EF8901DE2725EAFCC41F0064363B249A6F405663F550CA82A6DC5C5D04C4EC425EA7F27BA9C3B5C135F1EBFBA4BC0FF8D7C5E7B429005E5494C83FAA5C63CB73BDA47928DB74917F5117DA9E2B939984677EE84B944E0346072357610B0F2374D12910C8BA428628D500A6A57F3E3AB4752FA5FC4221DE5C332C70E53E8C48ADAFEFFA66DE27176290FD0E553ABAB1733D8CE618106D5C80B37B8D3068A8B9420ED1DBFBF7AB681A4FD077A5CFF186A44BA908D268C627F1A16BFC2A89782BC2933A0894FCB09A6DAE2B99192CA6934317F79EE65E33808267306919EC2AE15D7F8D98DC1B0CB34DCF0EC6AD5A8E6F23372E24E1788B0411347685F0A4E552C5B906C9CE64C0489E0A6EC183620DD4F0207637952F89F2E6336AB38A357DD66D14EB984D8084AA389A41E0EA910043B139EDE4D6646C9FB57919CD1398D417BA48B7B91385D377AD145F547EEC67C535CEE758D8286E8B8000ADC600D1C037FA2F2ABDD6FBF614DD626A759C9C4CBDB87076A38F3895504C606BE4014D57D7F2BAAFBD7ED7378F338EA58B2BD638EEF8ECC136EC311FC34E2E1333792C410667561F96AD2702CD43EAB97E7A8F5E686FF12AF8DC264F8D0CF66AC0B1E9E0BB5C30FAA7532F18DE7F75E80BC04651ABEDE5F0AE0E6AB17546B34FA9850EBDC4932FEAE13C25460343DEA53C1A0AA5BECD55D9610C7B79AC4FDA3C05594C3E220E455B2EDDBCFD433546B50902A77DCB6577F07BC871D4DB3F909696452644236C72AECF1B7F8518D9BA7F8AA0EA7EAF020D0358770C0792B3A07838C58F4845E475C7D0" - }, - { - "tcId": 14, - "deferred": false, - "seed": "530D229A951CE81973289F186CF9CBB284D9A0A0888EB818D6B9D78648E074D5", - "pk": "0BE9F87E9D22D6F112A39CC531350A306340AD84F313CE18F456F135A5C0DBA3B853E2313ECD0BE07350AE8AAF22B5B7F10FE05CDC62C00F3DA4B71907F73315F8BC47526AB332F78AB20195ABCA73682E053F4E13F18036BE2EF3C8B01BDF1F21510169D447A9FE87E70BEF56CE60168DE1C9312002CC9E3B680ACC2E13F0D5FBDA44370DC9276EFF999890E7643B3B0BE8A24D7175753FDB1E31CEBDB69EDC8A9F2BF176365694FCC4DEEF0C8B0B1DA3020CAA1A767F20A9F36669CD82D471328AAD31B2FC325901371B36AE637C180871813AA481EDA4FC0C7E2C0598F93E96D907C72FFD87A62F79C02D6FE60837707AC7F52BD3A49770115084E958730F42CA8098B87171E8579511175FB616A73C86D723D5A7EA67F35F1F6088A2D7CE48FA57975328D238BCACB26BDB0CCCB372A79D96F9C09C8A5727C93B36C7C3A2B2476D01D5077190004AC89967AD1973614F337975FEFF7D7704E14B61265377D37432400359F5BB2EFAB22B4F65ACD86C4C4CCF94FCF73C9FBEF68BDBA59562BEED19871A849DF1DD7F4A6B910CD5AF39D4A9FE78A2ED6A93790A578D774475E52498FB175E3240D6C5F02AD7F3D527450AC5748E7CC5E8D3E28BB189BF59F2177BC05E939B81610DD8BB6E895351469F3BF0A6116D993F4107C93B7DFEFDC35D182ABDC6D22769B9A1C2191E99A72D595FE5D9A93F96E99D9A913A52B0BE91C6D4EBC74ECDCC92EE580D84FA62397236427F7C057E963D662CCA4025928EFC272B5850AB0C13BAB34591AFD81B407752CEBA1C3D7D49786004872C51BF73CC11A92C3905F5FB96046FF0D153D43DC1D3D9CDA6884DD2BB37EFB86D9DB6E58F2882A16E2A254BFF02A2624EAFCBA3488E1B5F5322D2FC54AC7767D418D2B5D7CBCF7F20D6F77F118C6D00D10D7349A57296488D16C4A5C19D2D4CBA1B9C89B3C76D647614D3F2242F6A2BA5F8C602CC63B69F22BB104FDB6F7EC567685A5BDC55A95F347E1E54223E32C4616AE47A6CCC3F4FBD2DF3A3A97417C0BA457228E0AD36E2FFD7F8AEF3F089DD2ECD4382467BE0A9D5A47D85CF7F8FA82CA75652D923D4FC73FB4D9D39DD9EFAE2453A4FF3750B07EB8C0E1DE2DB8EA85E6690D060C21DB933B2F2364E5282190906FE5515720B9A93E26B2B25C66C5BF8B2B3027E5DA94BEE09B5CB8FF7403F9A7A65AED0D8422440F704CA74E439B06A25236964C3072943B17F82BEB48770FCF31EB366F29900066F95BE6E285E5B79F375414B6282DDC91A2EBA913976E9897F90059317BE155110D44C0B5A986D98D866C2EEB767F18F5FE4BB4510895FE4483A4B6EC9DB706BB7DB77E544D9CA9545FEFFF39AA4519C55873873A9C438CB345A542F989C5C7DA8DF169CEE4C9396105FFD5C9126E128657F3DCFEE744BD24BE2E104B4F541E74B980C0CE198C0C49770B66D8C56590FC9D9480BC069F0D673EC3097ED1A383942EA1E995134924074A4A2C328751A93F9923BC22E2CFE15FA4601A9D268EB53B155E35F57365DAACE0450C7B3F26D397E9D05ECCCE3916953465871B494D3A6FF94C9479D5734327A698E5E743EF37A5CE4CC6EDA1D659F416B2CA2F002DEDF6EF3117CE6235AB3B419C130540DA42F110875B12AAA18427334CB9B6C5767701B365C688ABB7F9F6F70EA29F7A44DC9E4B74F1625FC4382B60859FCA7C54F210429DDD95033886AA1DBE4D44A9C58AF2572BFE9984E73B9841A3D306FCC5338BBBCA1248EB5441A1C0372920223AE484E96BCCE5A419CAE46A031B545FA29B3817C6C1962168CF0B102CDEBCCA79D2AA1841588D2D2C322E2A2870B8737A351EA147E25FD819C7287627A9A", - "sk": "0BE9F87E9D22D6F112A39CC531350A306340AD84F313CE18F456F135A5C0DBA303A61DF0BA0157FCBE4718531ED771978D263E0828E642D25C92F8C5CC96F7D6EC769BEDE7FB414B8BAFB3214D62DFBB2ACA9695256DBF80BCA6E85E94C9CCAE4FAD63FB4AB9CBDF660FC6003C794CFBF02F86536880C5BD68EB5F72C198B98F0B9200198328E2246002224D501412E1340C0290305C48625A20301094015B406258168009292D93466540286D5928445A382D8230119A0405238000D14688633472C4C00954164A9AA4454100251CA76C1C398A08368C1B1412CA120A4A260C1339511B4071D902309816269AC02003962591368D9A468D5A121021C35051448AA0B089C3062CC8000E24241102A6302224659A10724926218CB81159360848B268D844229396001028821CB1011A047114A884E0A430124928901226E3425121030901091209321113068819158E00970D640000D0126CD8B271D1380C1A8329C8484442023180042513B701194962DA40815244284A482E13306922158403A48913024213087209404A63248D04A069C8046D13330CDB9429618890592025C920404224090A3880DA006501C6900800828C9040C0C4219010490C496C22C30014152C08156688C68901A431C3C06141088E60C28C0AB841033061C0A2919BC48C1A074441280E181090CC322800005202A708D44431592212DB242452081019420164026D93A26C4844220B1289DCB25000458824148D8B044ADA16600114729B48041AC96114C56162262D13462D9110214A044008180C51A2099B002562B44481340888C06C9340510A308E1AC3311329219CB09008186289320E4B94285080811CA22519168E1A428C114321189205A2A08961242D1849848922110B108908276AD03248188804D0348908A088DC088E511089C2326962860D03982084265103B868D2062060402AE48890CAC25190B43189488DD42030E1248421A000CAC82099208214C67018B22948106E00385261C621042869E408621211461C40725292205444849A004063125198B2206112859AA0089B240C83A01024414299044D210484C80862411490CB0829590080DB080622392E9BB27184A050E1B080C2140E11C42803444294B4601B073123A1808A326A248160640032423489C132020A14844A10125A062E9486310B04209BB4491C268D4AA28418A78D0484911B18811A47245BB281411080C016080407910112108C4860D0A20102198C211330353C77F4FA51B59E01AD4CEBF0E0A3CB5817C8D3540E554BAA1905BE97C6DD0F8D109BCCED7F0B95B8292F64DC47031E73CD56B8EC0FB415F1C271CE3F21BFD27317ACC974185FA816DEC34A1135E5D86D0B44D83F33D41BA320AC9B1870E0D7C91FB8C88EA6AD1FCFC2334AB0B023B7E86A8D5CFA53021CF33A84D9766C3F8FAC0C3ABE0EF6329E2B809BE7EC6A801832052313EBB604BCB4C73913506AFFDFE7D248D057B66DDA6E00D986322FED8AA3434012AC2C56694A5D81767F307372D85D3349A32AD7A41D0CADA7ED4D1A5E2487865E94CCF97D27D2F1397E613B78E57DBA3A051FE026AA8BA16493B639227BA467F307826C9EBA07C9D63D2BCF652B063703BBE4899F7E620641C3462C3CD8ACCFE4EA59470882413E4B2A156D70FC7B963099506991700CFEDEA0E196670EFA1D268013D214D21EFAAADCE3545511CE827957B4717B23767D2383D47897A009B61BBECB9D9FDC8BE188C08CCC7A3E4A4780CEDFA1D22501715FC206C245514F742337F5312CC9696331CC0338644D03FAA23E18FD3581C5B9C1EAEC31471B74345999057AD35A74BC1745A196CEB5BAC9C49E64FEE7FC5755375A594DE9895B15FC1248625497E9C4A5C8DEE57E488FF682204B97CD750A5DDEB47CDE2581F5091B3E20AFD9C2D6FB85A454BE79054380FBEF569B7ABB08E8DD53EDA5AB1D878667770A35FD41F2532F92BC0022FD38359FCC4D21E3A492D045EBB2D0B00683369934F76CCB35485AE2788D5309EF24C87B8910E75120AA6AA9A76A75083AAF0CD64993F8B892984C6B26EAA78A772648918DB8EA4EB00357F9A87BFC500164B247A78ED13F7955588AA504EB3A81243C5AF252C2F0279F05166047B6B476C2AD0897A39052E6FE3E8A4A2FD3F6DF1C4DB335F432426590D28183FF469B9025D7E1E176FE63ECA2A5B18DA48A5007AFA11A04B88AEE65246961DC14F9BC3D821193A8FA0C7122303FECBBD6C1CD668CCF9B38EC2DD1098B53FCD43E68538FD9FBBEE399EB5B69B3EDE9FDE03D813E20DEE209AB044A79A09217C316C4A5298EA2255D8739D04EAB0F6714154B8E1035707285F1A9B9791A1D3B230F5A09B41C3E2059EDA5616C120403EA9EF0E15A728DE056EF00E8AFC261D083283B431285D945614E3B78436ACE4B103815CAD8FBD86750E7A021D978F639BE399DB7FCFA45D244BC469010CE0D67136A369EF5ED52AA6EDF7FA98345A9D9F28FFBF681D1496D349570970AA1BD4B3632010924F8AE0AA4A3ED5F6712CFC272C4E8AF8F6E77FC7C176863F488CDAF4A770DF7A248485FA731BB2E209C2CF6191C93EC9FCAB45D620116DC0B1BD6490B7B2E405A3ABC4312C5C8BC910DAE9A4C4FC70FFCAC5D9368F4F802785BAC0708ECAF3F8980E21A4D7C6574484364D28082F67AEC77BD36AC76303DC8DD0B7ADD0936BD528E04A0D480D735091EB361A5DB3F3F49D7CF5AF418B77DA7FB618CA12D67F1EA38956AF81E4350B0EAD041D3197092A99C2EA260CFD494D19410934B0CB9F47998E8A549A40406635917572B7B591F30CCB30F181C78217CA879414B95413FA38EF730A0A04DA02953B22E93A5F12DA6BEC17140C824A2F40EF8165C9E66B48DB26AE45642191774FE4753417F05F74983360B1797724DD201EF293D2BC04160B8FB638E47CE55BBD6EA2520407F2CB1175FF5DDE1205BDB0A75A0C4B7F1017AA2C032FD427DBA6CC4F448F8506EE48549BC23179AB4F8E53E86ED1BCC6F0A785D31059E79D581AA67E637AFC8781B0ECD69F3CCD225EFDBF0AEE458BF03D30DBCCFC77A06EE928EF5448AF78E9BDFEACEDD20850CCAA15EC3067AA48AB1338ED4F83705052DEF70E1FDFE8F23C3C2E1378A8F9DD3BF5F1D9B44E227E96D41FCF54AD0A7008AF31AAD2979ED7CAD2FA386473C77CE6779CCBE34D6137C1BD6375F1F2890816E43A4BF15B9CD968D4D774B5B0859C709494C171B48A8322E233682251E93A77E0C9A60215B53616C7F51CE9DEA0C58D8477334D055892F90DDE0516F61FE065BC25690435CA8F6CAFE850D1B0DD659FA01AF0A795A95BDE40030873B2AB78229DA43411F6BA8EA33C70D5B4BF5DE05285399194FB2AB4E95B6DB3A8A3DBC02F9F8C2550116670010958F69627DD6D0D76BBBBCA897F42962BFDAD0514AA053F45D4F3FA1088FF0B57D9F8587565740CE29A4E7C10960C8C21CEB9035DE1C4964495C6257191161AB4911AC49648DEE4FFBF30D5239A454667D139C7A8B4794774DD9410030FBF0A75D636834A39D41FDA3B39E025A247190B4B113A024C62F9B9A54E36459A050D6D7730047CEEB3E6CA74D45671D5E22ECC3" - }, - { - "tcId": 15, - "deferred": false, - "seed": "2FAD994FA583FCF6B858B58ABFD4B42FFA64D552ECDCA55878EB62A0BCC17280", - "pk": "EF4A349F3CA0CDAE99BFC29C75DCDEAC5C0543FB2D6A2E05AD41223713DE2DB80395B221099FBF9C1A8C17E4D01FF19D578A3D5DA2B1381546968198A34E64639ACC8DFF2B806E2D4784662802DF0292391A40B48CF382E7CCF55DF43FA06C2857EF61E82A4EC79B02D1A732BC6951445F74244EA7D9F14CB715C4C434D5083A228F734507A5D0C5C83E54FD711CEB0D124D37406D5B75DAD51AB6DDA66D8A1FA9F4EFA6E3B1C46C4070D514EA46E4D21D5C4F7D4AD3ADA7F069F2C71FAB92B2A9E88FAF219ED4FBB5CDBE82ED767D687168C6D7643E742C65AE62E0E93898F4EF6ED8D5D368AB5748EE940B397CA5A706949C6CB762993C96D726EE442C91EC8B89E38931BCBF4C294B8ECB222AE419C35B4E63587C35874316C941F20B549FB2E5B9F1E83C8FC19D14007F59221536422E116891AAF4F74785A70B8394113D497F77FCB2DFFD05931731C6B7B70CD2193F087B74D02F76FA52090B5464930791A3B2B01B4A6A756670101DBCD798E5C68D3AA00F5BDB7DAAB46B8871B6117541715F85554F76DEACC02178670967D2152F5500FF343FDC9E110193161DDE7553312115DECAC29E934D46C3D7E3BC4422863BD7F80ADFA4C601E328A04C6EB10D8BD3288FA0AACB67B475F7DCAE3B36F5C51A1987AF89EE82A9CD1F91DFE4197520DD7B1D7DFB4A0D73607EE20157AE2BD70E1E5916CA6A7CD5ED8E8A5864409C1D82C9A469E2370530EAC606AF7904573AACBA0242D34AF884CF4EBAF3ED6C3EC3BE274D5F9252D73ACAFF9A7900CB72FB0ECA12783FA6FB82DC8CA8BE2FF2315D537764A175EEEF1C521A5EEB857C0DEC2F8886F3A11D841EF72292AC18BA1372BD474FDC153A33A13A4F88E9F53F541B49FBC89618CAADCFED7B837B61DEB8CC2832189E966EFDA2CBC5B67C1BE0D1CBE2C5CC3AD6A0C0386F009FA37440C3C6B9A2E38FB38D8CD36C5898AF9650B609BB5C17F006F306A23D24C9487C423E9264D5F9BD592DC57A6B7F55394B8FBFC7B5554D091AEDA0C810E74640E81067437E5738F88917DAFAAA9764AE5DFE741CFE65AB6370F0FFFF4B41472F12B075205DC1879EB6719D69F43CB18A04E5E71E5776F1987BD5B6F8A09F9E34F08B95E75E406B6081B2D9D28C78E3C512F52C27228EC1DF21EE3DA5EB4556E892D6975C52D3D5C356B2DD3E7F3FA4A3FCA1959BA6D55A2F8599933B61B78A97B14CDDEB792483DFC32EC4D7C4E87F0258104A9CE53ABDBB4EB68B144B31D8AF2118B4BDC717DB70C30AE7CD1899AB621292CE06B10C7F8DA18C038AAF4EEA3391D4B979A2BFA82DAFB40DF9538C4ED406CC9259625606A7AC12E7114374358C2260282400EAD169F7C28949429C4972E9A550E1854A48EBA87269BAC149FB410980C77AE49B7ADBDBDEE36D014F19652FDBF3A8F80258F99D638E79D10C02F501E7A36E6EA03D4853336D188A744E403EB775235AB6E173373AF151E6D7D1026CB570F44303A4C65E2C5FFEA0E8DBA8073932120CF52AA92A913E8EF08E0652C99B9239782FE7332D108F461B16D2D8708C994EE15A2AB66F34249A67585B91EB27435C9850FE3C67C061F56B78458D37B2C77124EB9C174F3E845C67F6D483DF9E6690C26F172F586E31D1E2ED17A8DDBC500AE766369A15726C666C6437773A2C22F806FCCCD4392DC82DCEFA6452A0EEFC9CADF6D98E041C4C4410FD5E9CDE5740D291E254B1F1C80A39BD1B372A6CA71E315C4109F5B2F82D957B5BF806A6367E993A3558454768DEA69934F830D27477C3A44055A542F7CF0FD1113A9DCE618D22701C60AFFEF378CCA4EA6FF5C5242241F18C88BCDAD77856828175AC96E1", - "sk": "EF4A349F3CA0CDAE99BFC29C75DCDEAC5C0543FB2D6A2E05AD41223713DE2DB83344D92FA9003D0A2BB89C66DDE0A2D2643976E86F9DF03B88D6A3D86245243CEB0D6C13BB02421CED2306B68A2E3F38565BCA435BF88E2DF253A05F40518A7F14FBFB3A0E455668E852862AA54DDDCCC841A20DA649AC3DBDFB05BF9FDEAD6BCA882480041112349244B46013C67124C90059908C232470204824022926D02688C430044A3641491649E3963002230522154422C74C82A47051B48D03B47004C984C02262C9B08D1C21664C30492395600803658890490B39910A1461A1A42524148A01878844368DA2C2115A987009848461B248A3968514424604396A13381118270D932032C0A86152322E22343214C48D82B024DB304C02B40108837193B82C03992CD120628A3281C0A48924200AD8382E18206193906C421030DCA88004008D9AB68D83C04818164DC1C620C1286621B48401482890B42D92907121B670E1040C60322EE1B69114178E53A041A3163104C50549B2651B05464B28910A208681B28554204923B3891C14250895091AB48580822D6292880C37841C38101C26611BC160DCA630E4800912280A2235695AA849231966CB12515B0060192026CC142619066E22B20811387049948443A624C0A491084029D448611AB44981B881231850894088194546148848A2244003028A08280CE2B03019336E14270523322E1405645A4291C8946D03C328518081082564D4220952B20C63388E5B1621038120E0844520C6440242688C84000B24521BC5084494618BC44C43364A5800891CA250D8B4894A304409B988490426D9B00CCC846050921121C92C18C250C406622191441C405253204D0A2528A4800C8C040801096911B96DC3446E401031104084100850D822091A21614CA03000C88443B02443124942B6846004818840400496498B920010146019A2015C460A0AA52C9B8090DB820800951098B4301221688A14081485844422521C4680C9324941A470643831230840201031A1323224340201334E090910DBA648C816252417102009811AB180C8260104314CC3442663A84C211606A3042E10234618093114864CD42608D8A671D222088B344512A8318A36668A262C5246602343225A2466012649234861C9C6851B0530DBC2505B186851240493A80454B2245C08084844508C964DE4C80C4B22849C4849204790DB8831121069DBC444C238488942848C100D8238441C077192064A02227061FEC3F15580F6044A49D7F992DA568F3C4ED4997293CB8B6AEA2B83A1CEBACD46455754559FB4618F3E08D63316DB0569263D35968F0938EE15196F2AF8B2128443FB2254269695AD9D92686A4A2B3F93872145600C1765C0EC479267A24058FAC9F7E0DC0D810CD780E1047A54FC388C97F84230C277F775556A07161328D7993EE28E418F4C29EF0940EFEC7060FD6BB16F75E433A6F90CC3C4031D991854D54F906C21835AB673390745628F3099DDF6AB5C6D6D3D345BF0566B5A1ABDF15F9D1678817D2678594D56C14B9BBD745DFF9FC352610E8B7B6F58D6087583FDC40B6110291885CF2B01707D4737BF6BBD9216D8C04E314FC8CCC719DF819D6DE97E7CADE9F3830FB92C5D1B5CFDC2DFE96218D08968A3BECA9C8843B13BA3E921AA5DCD4547F5DCF9AD10DD2A2AEA30BF2436F95591DA07CA04876F5B0AD00567AE9EB65E0866F0952D9BF9D813772F46482C4354EF3F735286E79EB70A963FA511D45D8CE07D5CB83133B2C85DA7CCA0DDAAA056EA1BA1B94F3A866ABD801232D8408B2616D35E05DDAAB76C72CC08EAF0FB277DA53BE76C4A8D3A91E13DBE99A5F7D2598C2F15C76643F85091BE549D37F0DDC876754EEE50F2E20B6D0D7EB9A4B0294099216FCF0EEF9E7FF2076A5D8C3ED0977B2BCE37EDFB1CFAA7A250F238F65540A675C3564498F1DFBAB6E238DB07E888145FA4314DCF25DD070956FEE9E92EC13ACE4976F1614AE0EE5CB649D4BD91B0EA96A6D3B46D4184F240337D46CE3052B93E8AD8187D20FD11090C3584F2324343879C02FBCA34CCC36ED99D29791A7F89BF5C0C311F28E36FD8239FFAD0763546F4C09A2C085C6227CE4D06B33EB5A90B261CE90419199032DF0163E76795269C79202BCB0E6CB33F06B6BDADD48B54ED69CDCB1491D97106CE6C9AD47B7C82C2B8E82A6EBB9796C4A578F87CE5F574EA3F9E27222A816D50466550F5A87CBC499BB41BC7105D7324E4CE482FCC6A11A7CD8B10696808F1FE8D687BFC2C235840C6BC9BC306CAD75998F71016D3632F090ADB270587CE4301FE6813C63F2139352747577FD6B0A5CE15E0CC7B46392C16EF6FB39FE1F7EEAD1CD4E4FA930B60F676A5F2512E82E6BED63D5F4A3910B03E4C2CF55EA5DC42024FE460E2A5953B81EFE8BD8693445596E228DD4EFF7603E361DC7ED19FC81AAB6DEA4E50971D8BD011E6C13C2B3BBF6AC5733451954D1F044D640E535DC50E8E8F779B52A7180120A7107A989BCB77BB0BDA57CD638F84BE75DC9ED9C63D327F3131232D73A5BB5C3FE20BCB63305090D349E2A773B865FD11BCB3209F024B42E9B2ADC9AE36FAD88156CBF190538C947C6F4F571ED54655C47B4C47FFE5D8C6CA393E82223E48433C75E9061D016A42A62114C17739828A1FAB4AFE2E348F2494D952B74E9707FB0BB74EE3BAF621E7792916F9E5C3486DB188925C049035C711E193FA0090578AD5E47F0634ABBCEDC1CC7CC32B72D437D159A88FE76E66F900257F0E59D107CE9D79CCE91AF2B47CF061F96CD0C12F35985166FAB3E2F4A25FF3DBAB35FF7E30859A5390DB06B68E6F0EC3CFDD2286B356827E8E362D60F1F7687010A7F3188E8BC8A67C4B9BBCA16CDC3DCE5A269A252C6A149B58901DC16125E5982D78163D6799814E6694FD39E307CC42F43F81451EA8F13704C5F44ACDD2A11BA9288580A8698D75600193B33088165072E0EEC47E29A898BCFE9C03DA583C060BA5E7A4627307B24F4644EA18F42CB0EEF06212942BC497CA6B4B622FEA0C92A59C59B32FDD027EFD7988983D04B49F9BDBE96225CB09AF9BFEFC879686FB4B1CC2B99088325250945350D8BC98FC0C38651E15FAC03059FF843402DD836B6177C1D5DE74F5E67F8DFCAB03BD4512D141AE64B47EB2BF750E2F2C0A778F25F3B1B85EE2AB8693E1B8EFDBB9304D48291540EA31FE511BED3AE070D1A0D3F0AA9102DC476B8501DD273A0C234B1024EE3D09031F2F0C4741982693334647FFA5A9006EC4718AE7BC3B0C472284D435CC59C1E5A25780DD29169C83D95919ADE93E87535C9D5A7CAC1A011E7561CB8E05587860EF873A54DC65630A4DF344E384BAA1194634DB98B9837CE00A682D3827931BAB676AE17EEA73AC025DFA58D9526BF6711D231EFD593306C9D59B20BA97F9BF9D021116252AA312F1AC21383AA05F689111EC02773C27E97A4283A15EBA9A1D270A798D72D1E41C4539EC0D89BB3575F11374499ED04ED6666C99D68B03AF9FE0F79F841E719057FE1AB2F1988465A1A086B92BC4C2890A395C17A473ACB7DDDBF3EC1BA641FE41326F5A3AB47D31E5BD14CFF3DD3C901BB1CB71C0" - }, - { - "tcId": 16, - "deferred": false, - "seed": "64C00833C31B906FE4F7CABA5D0E2E26A81310F20EDDB3E1913F44B89771C783", - "pk": "03C5682D25BBB5C22AC191A5351E048846E52CB0E8E54AEF243C14AD0E69D7A57BA7654320DAF1B4B1A10E816BE13569212FAC21AB2D6E60C68CE7E41EE4CA5CF437519089AE7FCD879B4B9BF5A60C66BD09B74800363A04F0EDEE88BC9EB69F6C01AE3BC10D2CC6B625CDF34288372F01C031E506657EB519C31B0815961454E12DC426E486B7EC88F2FC90833F4416FAD525417DE49237F0A7EEC8F9AC9B0D0778078153E9FB3E7D95AA1C07732DB861474F4A34614747A282A8A875A713367221153EF0F77359172A5F07D47E71C8BE7168B854AA091EC8CF8DCB0EF888143FD78BD76777107070E36D157BDCE52CEBB89530682C50CFA74F0F3482DE20FD562420E55FB3F3896793D4CC68A23520734902030D1D1234C25D768083E82F3A75D29C63AFF7AE102EF4BC02115D0B370CA98C5167AF69E68EE2E71C0F6B8E680032C4ABF001755ACA26D92BF06BFF8F2678611DB13F283BCF4D74275692FF493A5FC639A4DBD8B47BEAE8585D27577ECD2705E0CBDFC9D778EACB3A200E6D72730AE6E6F9D3A53CF8A1794B979C8C8969778C6CA07B65A01D607613236C762F4C54AD222BEA5378CCFFE8DD95984814AA9517FD9D01E3356C265F740926E0DE6FFCFC50BCAF8307B243FE030B4BBEF4CD1816731B54F53B87CAF3580E43A762391F8652B650E981FD0ACDB32F8C10A9966935FA82B2AD99DEAA6FEC117AD15978B5C950BACFD1AE3AB68F36C4F983717D6FB4CBB5513DAD2F842EDB910576205F8A1851B097B4723B0A21315C7E16C2DE11A59626B651C49AEBFD198CF8FD9C81C781E93EE959D4A8EE3E4B4428121E29625B217D403FE70203791F835D6FAB8B32AB190B0A53075B17132E366AE270622B0D9CA492B23323538B39BA45A7BA47DF6009333B7C668C145C9CBECA0DFAD7BA07682AAE3068F79A2B3EDD897C5723F56B33EF04C9D06C5A7AE3518482698C69EA6E263C63281A0E723F955D39870222993C1717FD8574867320497E0E385FDDDAED6A32CFCFE356E133181007F8507BCB233F08EDB2ECE783765A7BBCA2676B3A4BEDC7140234215878BCABCE3263492C9E6D5F4A323B40344C077B38EBD282D326B54BBBD222B9AFCD2438EA594CB850FA4D97A5C14A9552ACAD740854ED288BEB288401A458152F2C1471C434BEAEB470230166306691AD6972B249D0AF06E131507BF8B9F798B55302D95CE98C2AB7A67DA55217F4F5530763BF50C3389EE6AFFA281414FD34B85A3F29E43322C8EC44BB26E664D71D5DF8B91859C4F174685899B3A9082574D03C2952BB65486F5D770235CA476E85F8F966FA67F3323DC10A66A9BC00D37FD2C93752FD49F4FC6BD8D45F371552ED38FC257C04F58825A086EB23B1017221DD0847AD0D552BB5B773903063825E541DD7395E160FA0A00288509B97EFF2E9F0C12B1B2C74643E2D08E67036A1683C77E83D3BAFF79D8D8DA4D2AF890E6D698FB18376B0720E1C5FEAA6EDD7441EA9D618BE89650858FF357EA575728EEFAB6E048EDBD54F4E5585AE0C322468C12DDDA309E0B8901ADE7E10164CE31898189F99F03B112C5761EB856B39C8DA6C22A4CBA38421889C4F874D27B98D8509082775E3E32E304EEE79E23A68608B2DC1208512CF1644E0DC3F5F4B6DDC83E971D0E4F23DD22BF15DF80F2337B9D344A157E97BDF504A5F128EFA7FA910C3B10D2D17D8C18C8FFBAFBB0F8F0ECB1B16B8C480766669C7D26F0D69BCAE6C448A27F85B6F797C096E04413026F9BB2BA647D5460FCE9607340A577526420B12DB4299AC409927A059EBBA3F9B27175513900174EF0C0D39E2DA96B96C46B1BFF2A46ABD682FE438", - "sk": "03C5682D25BBB5C22AC191A5351E048846E52CB0E8E54AEF243C14AD0E69D7A58DDA19A592F17A74AC79AE162AA423B4D6DCF620B92DE7EA28D7CAA414693CDBCCBE7693DB544164D7726E8BFEA3F7C321F2C03AB1D2553C59E6EE3615F9E6BB2EF8B5A71196FF404444F00C1957A9E8C873C917CE469FE85BA5AB43D679EB9B6410891330891AC164D3880019047104854021036E1848269B305248844C12B6918AC4901409319912921CC82C8C42688B9449C99221CAB02958B48C9A148C6332718810461C240613190DDAA06158A684DA48448214601B12120BA9699B466EA1986198B86019A0811800650C396D51B685C1828C012146E310605146465B485152928DA2207113B30501B42919118A089925E28604E40812480826004185D04241144924E4449120058223139288102E1B138690222C222708C4C248CB860DD30062D9208512A291C814041C000581A02101B33018456682B8302000499048709430720C4426DBA08043929009162EC486640AC211DB120808036E82042A19432C9C92259A9421640222D3929040808DA1A88582828049186519194E02B9206296251B45800249514C20700118204916048A3012098441041660DC382CA1084D203849444224A02885A4B4004C188D41A82153C08C22226510C07194A40112B12DCB980D84A44D61328C4A142492A0909994651837904928862309809092205B360A18A70420B800A0C6291035425CC06D824870D0141223284511A68063044608C5255A024EE1C651CC308E21C18C59B48DD9924D52262061360D539431DCB4901233710C908983306A5102915816081C85440CC2455016604900620310824B120A13823044380901B68C44049293A230623006A0C480014669CCA2041025859C806882B0115AB66910A3210A2732A32622184066E4B02589300C201440400004100881804206DC048911C24002A861C2B29121800920C02D202972A4C230233785000531993021DAA6609AC06522906D20004D1A930C01B761E3349291C070E01600D21609C0428824085153429248046224024C50388A00C60C62C26803040961A664024811DB242282806411430D891211012770191746049105C2048D621691E09829E0909188467062484D89C280511284CB2605D0481220402C614466A108488936881C222220240ED1946D50980998C66804C34814292503B68C00904510498A82862C9CC28D20421209370913302C4A108A5C1011040482941044CC6AF62A29C0BB4C651C550568C2B7E30973A1EBFBED2BE867AAAE59FEEE532DBDE00A4D7E787507E2FFCEA98386A4F068FC0E5365AC4ADAD080BFF8D689CE2218B0FA34273D329AFFED0EA373D504C43A939E217E1AA6CB6488A2D2864FF4CE1401DE8A810EDD25E2F211118801D963B6114B2B7D53B60D3C4BC7B536D15881091540F2144D874A95BD1F0F04D3425308E3E0EB10382C1486C1FF829BDFB39D722A77BABEF4E9E26D9BE8113BE96EEDAB8B5BF7C59E71F6A801BF1564902D71574D66DC66E1EF857B082E574C52426F71EDB4CD16F14D812EAD67171D232D0DFA455DD732EDB1E4CCC7CFEE165250631E8657E315DE287EE92572431B4DC359CA109029B562152977B08C3A36FA205F151CA4B7FF65DCD94B53D17A1EEC5573707168B8CAE56AF54BF73A512501A130FFDED992C88860DDAC46052EEADCAF6304C361908209C1127C38453F8727CDD27D396150E5597378E6A7965433A08D777AB39E1237D77AA4EC0905744CD25BBA566C4562BC55AC98FDD04250B77644AD5A52519A066C156DA7A2B3A031EBE2A372771C5E615AE0F05B78A7F2C76756D40427B210D1B745E561EA01AE315271393E26EECF7314427AD500AEF0F4D122668B15E4263811EF7EE32D3AF2BEB92A9111079343DCCDA12F80F9B2A8E0DF681EBAFE963B811298F848F52DF1FCE28CB0BC588F2454E07FBC08C4EE76EFE3A37E0AEBE457517121FB09AB15B7E3884A236E783363B27007EAA3AC074D3C9A956ABBA45BA8F35E36483A0004DD57B89082D0C5478E785D8ACB40FB979809B289AC722509D231960456B74D8022F8DC8666EF3E5E6AD54561AA4EFFC29A8C3AD5FF4FC8DF2E23E795EE43AC324D9CE606608FAB471390BB65151B66A1FDF4E699A133F452D9286309B131F7592AB446CC5C4D6DA2DFF31174BCD6A987AF1C573E9C29F93619E4FBB4318F6112FA43AA2A2D69B46AA076F59515729701BFA4BD991B3EF479544170ABE0BDD7B8667452E40104C81977395DA7F1DE198658FCDE46AFEFF92FB2DD42B549B464B77699D55079F76DD04388C1792683D89B2BA5516FD7070E504D927B88742723A51B8A8D06173BC7F069C6C0057E887D0ED60EC9EC608703C75B5BBD0BCAD1D588B48630871B2F8134EE8D826EE7981A3CA96006A12D580E5CD3DFA0E03BF853EFD7F1B61E4A9B5D2F61237BF2645592B2AE7C78D218082E72145DF841160E91895D80D47DF474FAD501B55DA75E45A4E2ACEF6F94F944174800A117CCADBBE5C1EF8A7AA1D5E7F116C5D634F816C742AAAD7C346B91C8CC8110EE8AE2CF4C44D6629F0D00141CD58B94E46EAEC58BB86939814F4DBF63DF95F86C5FFF7BED383B75DC26C7FE7A20EA084959503B6DD11EBBEDB8FEAA8E0F486B6B390C343E2032D30E98D519EE372379CC28B62ECAED5F4AD3C60514D56C5C29E728BF99212FCA97E2ADBCAEA3B2BC4927B91C2CE5BF0634D0D14E7FA08C5F372B72B9EA9A8D2A7A913A25C9E0997076D4AD064EABF0574665C09BAB7177D9AE77E9D1854FCD3011AD78A9E13405188D9B91CB5914F5D6B0EAB170FEE77AE61C215E73666A2D52B32AEF97A1808E22F09D4AECA4D80CF4B0E901036ABBE5EA0964584B52DB4B0E0C5A6E71E461A2C8B2B24155961C1B4DFBF1EB42036CD70CB6C16B4F85C53BBE696BEF4CB3D21DBD5BA62B49A95FB33DE679725D4781D6E2B12DBFAD7CEDFEB971BD8F2211CB5FDF5B4FAD7F684E61BAEBC5C134AE3F56CCDE44183183160B57891C487C59A7F95577D035C442F95EF655794095AC49A3F92E4AE67F9F7CD0FC36986D288B22340FE7C7EBF7265C98F70136D21EDB2D95A054138168591473C510818D3872190A3EFE397400D11702FF8F38A7B0292FD043DBAF6332188516A36FD46529A049CB3B97C706C0CEB4419100E66D32FFB0212CEC721ADE99B95F8E873CEBF0E47DE58E26FD06846545B546836EF0C2AAB40254A50ED445F0A886777368158847AA30791467083D6575437ED85933C865163335B5F4FC610908F446984680B8B9F2512F73A8531ECF81F9F4B42AC6137ACA06249657510769A273C3A2F2C0A6A7F65BF7A0E9C3DE9660446CE0D930CD10C946966E0877BCCB014C89FD7759F513BE8B3B618DC4F933524F4AFEE166D74AEAA1453839D3BF4095F85253382B26DF060FE9C1737CA02B8D018BECA3CCFF06F72E373696DD5CABB97EE2D329B0CF0661ABB843ECF7D3248627D4BECD58C06A348396AF84455D6BF39340AAF12760235BB13AC3333D6A2F89E9940F1C0A6C23B5D94EE5644A3A1F9C953CC47E2F76373FBD27FF569795F2928C59DB86F5BE69" - }, - { - "tcId": 17, - "deferred": false, - "seed": "16CBFEFA6448D329CCC9A68DAE478FDFC02D73C0F1DED9F6A87423A52208296E", - "pk": "71BA1F2972BC412818D4C9B94D6E40EB98741BB33CED307707ED1627BBCF8CFE1330A73B6E9C56AE0D878B9982B3BD187C051C8CED3469EA0EA4F18E70DC9FFE3800B48575EE12B01B082A01B9871BFD8091889C00635FF810B6DDEB4505FA8ECFB32039A6A73B1612B7E3E02DAC00476B5C7AB32861529AAF3A8D7899BFF3CDE63C8AD082312EBD856CC2739D6736A39B13C971DA277980C73848FF99D72C8738E0D36E961D48C56F21F692CC72D5ABB690CE9440A078CBD2CD789F884CC45D0792C10D567649067812206AF64241915FB1EADE7A92668E636C34D0BA4B9746A2A5546FF85F9908B200B76A40DE0B53ABFC7EED5841DCC7AF41431FE59287F69F11C22E71A2E2D86E8062249A3774FA206445AEE3BDF33CAE5B9F28CEB78EF887D9178171E9B5ACF243CF2AD3E85E0143EE13CF9C20A4FCCA0AD53F8AE39FDDB58613164EE6D5C6C83D83738C06F327EAA2BC84553897F11622FB2FFF96ADB1CF3C154BEC26C42344B13834761EA5DAA6F7659DFB86C9B25725E8E9FAF6103709A415F3466DF43565B85A7211FA4495B808C4F1C5BBF7A789C20DF5890F2BBB3E0E4D959D24D864218B950DCEE4F56391566B57B794156DECEFA42140B82C4945267072B62E2CB494F872162F4D066D4DAA87BB15A114A38CBED20609201BC2733E1475CF09C189689B5EC2BF040BEF6F16851A9D3B058A4B0A1A98A25D74120725C7763C6BE74CC931E057143F4870C751B102387E403AA6E0B384B4E9151FB8FBBC1241FA0656E785F97D27A4258D015F301F41222207426F386CE4E7A919C4B4F29552FF323E9C85CDD11DDF3397F46AE8F66049DBD2C61B20603E3B77D898416FE0AFE87BB16FB39C17DCA8B3F69DCD223B35B807BAB02F039EDFDBF05ABD1D28BC54B33CE357BDB72B06F35D40D9EC9C81FCE5624CA7C13DD81985AB5DC422767B2FB3ED6EDFBB4CC76A35E1793C7ACDFC2B80FCD5D98D98E3298559046C776B130ACD7636A4D357D8766E58160491EA73ABC015857253403284126D09B770C557D8F9427205F16E7D4964BBCCCBFD2812649CAFDDB34823665C4635FC3D4BA0D9A070B195D8D3DEE77D2147E8B1FFFD155FB536018D08A63097960F1FA341FACA7CFD273FD8B13B4A967DD7340F3B1FD93DC5D1BA7E0BE530C263F6930BC3DE5EE4E6D2A7A14CD38D3D86FE63416715B825C5682EA7C8E227630BFFCDD18D8B84048D385F54A657DA77C520BC24B0A40D3D0EFAA5BD6E31D699B8CC0AC97D3DF3D30CF0794FCC470FF96B43D5DDF282ACE2ED4201356B492C74E09F3908B5A5A5D42E7F4630BA516FF29C6A5D968F215D017097A246CC85D6A5B008BE68BB049DB543B8CD9BFF7E3A160C37DFA3AEF8C2C702DD9EB0FAF580040024392758C004A5DBCA829A071956ACB219EBC33E50109F6F0A2D582C89D74B0A2B929D569DD8EAA9881DBA877C45C6186A98293D9CE56CED0E4E1013CC293917A1851123677E1206D1D051B3790396B6A5BED83B359078A9D58B576422544279D3B93F4016051F6D7A62BD3C3693E10D1207AF92B72C348EEF81502D308E34059CA3548012021B684C13A734953B9ECFAC69874550B79EB388CE5236DC28FAFE05F548958C6BC1E4DCFE4F87C8CA3BB468AA28389C72003BFD5822755F28B75B4C9B097CF98D61C0CA959C775375BDDC31CDC5E9AF7633DC3CEC431E5FD8A7CFDF20401DB1906FF7BE9654F1D5040BA50B7D955953FDAC1AECB3AC2CEEC8065723C232F5C3BBD96F55C4DEB9B84812BBEFE549D5DC450198BD20D90782F0C6F3153AD6272DDFED0AEA91FE43A7A78AACAA0736A29892ED01950BC0A2FA17D19539A5", - "sk": "71BA1F2972BC412818D4C9B94D6E40EB98741BB33CED307707ED1627BBCF8CFE063F07E542AC493E2086888356684C25B2437F7AB2271751BB0310B2CC46723C06469293E5C9AD9B7899530B9F9489708943B5892821A46E186DB790F95CD769ACD9A0387EC1045DF0C4D254F1CFA3C69CE31FB553523C1018D6DF6C75322CAB9A28306292004C380002C385D4448A908629944249611612CC320A1B8368A02051C0828C93B460A00052A0C68813926561A20113446E1B9304D8B2088396609B42455A4265A0328920066ACC447098080503B13101942143400612842114196408C09022C7710B35901C47849AB68D53A66C20488E1B952D80344E8B38824B360E19A3481139281BB3011CB8514C826C5CC40D212469C3C24510A6881040241CB31084C081D4808140848090266D4C328260C42504C985E1080589B865E31692C80461D3105211028C5C166C24A24059A0488C9424889831DBA660E2160608062ED0828500A511098964E3206D91428DA0143180224C60B8049142111930480B144D52068A213769041586E1C04D9948050198885822015A0085D1B881A4C291DCC40D00112954806D94100623B8811A3800C0144E5C188612A06180A2089A366948B2840C46500449720C1744D2148951484D04870D11123242C83140186AC1B8840B920919330D1A0652633081934060601271DB140EC44850DB884D60286C14028608050503836910041283006CD01884A0320D41884964148083B02DD012885B3871DA364D54006603B601DA040E90487102C72C02B64C034325A3186EDA202408C410200440D1A06DC1402C0182482144044A066EC8108842188EE4B2401A09250C016824188EE2A6050A90241A344C0907301AA98008352DDB102C23B970421425A4C64CD00229CAB8881401318906724C346523A840A08611602801E016050CC125A12011A28445C22610C2088623A729D02425C482095CB6219BA0506148280C2765C84601008564DB824D5980891C884D24C60D9B308C93B2248BC868C3800C12478D8C340182422DDB001004B008E1124C0B828513B78D1C41006236281A2772E2B881499409D2924D10434A0B386C09952509382ACCA62C41B0651881098CA03090446D4B06901B150081A62484840819306C00C2918B4486C94288631652D8A44C1A81246328404A328C48C46051282EDA0809A1C48DE1022692B82113245213490E0321480B3169D326405282005A1885810228984080DB2000D82E82D2713294679D8DBF3EEFC4DE8D7C6B6898759DAA0ECBF083FACE0BD58B98F855C4F1A8EC9D79B22BAECA6BBA2D2C863732A12115AA2CDB06F43D2F5D59D4B477B15FBF0374333C4D5D4942AF2180AA5D651A8CE9F3568A24D9B78D2E02A14F85E7A112A2D4D1DDE95F08E4293FA2A32524CC7E1754DC23406DE33FE808A31A8E60880FB8973F38C8642A02879C34E90300E86A91F7E803F92178D7C5676AF246C89B09A59566D91F6EBD4F2CE86C5E2F18230D44C6FD3FA358F68D21BB01C88362756B13742BEDD36D077F0D0839450C9C3398CB04B26C54CD61553E8A253B9F94E9B16AC4A79CC931743181D364BD999716F0328924187153E9F5E25E8F7E05666D6F70F012E8A5A8534A406363D297E768AA84221792002A4E2D04A46D1FEE446134AA4CC06DC7E2CD7605C660291E24859F123B332D41803843E059007FEE960B19224190F27111BBE3C411CC0885B4D5EEB369973ABB511C8584DC4F5E811CAD7745D9DC88707891ED2E8A597A493C8CC1A964BBAFF9FC808CBB0FAF6079D29832EC18888926497C52DFDA34C83A2D1178A3CA27C7F1CF04913BED288B2DB7581A8C4EE24784747488F6BE84FB24F595F82FC0E7B05CB01241BBA23B19EDB5162EE2645B29AD48CF2F64D813F0303CECB0C94CD7EF8ABB6BF64838F949749F15A0EB899678A5671B2925E4005AD0644AE486234B720A0752284122D1CB8839D279FB571D9973482B67DCAB15EDDB6DF57E36998ECE43C4C067314CDAD1834CC70A209BAD00518C549E9C03B4D76FCB0F235EBFB694EC90D5123B8F025BBD1A323C6097AB0FAD3476742C0531A5F66ED13DBBADE8AD4888FEB8896E37FBC01149D40CE6811D8E386EE419580C20BF1544FA524C2DB22C9DD116B752F42887752FDF863A860420D029C309AFFD0FC9163375E48E8EE7D69B64098F932B205D63E86FFC3048DCD3375798CEB11A2821A92B6405E32D0C9C692C0C51FA1757B4EF12E8931E26B77CC7893B0385BBDB637C1649B696DBD5CC7D6D62B3BF19A7AC858E12DCA1FD34D8AD98C95BB203C4DCBD20D5A1AE7DD6D96CEB23E3F0484532040C74486A2C4C69C65949D970846D315D4D5295C674DA72679269A6234BE374E3826DC11DB198007848245DFAA3C939A89D34F6E1EF688164ECD9D9B7D5909239D46677E18DF479C9FC825E8D3876D05FAB6CF70125460D524A5F3A45525241FD610B53D8BCF110687B9AFABA47AAA61934DA03C272659BF7EAE1716F3CE5D7F6BC6B72B0C4E8A8E9C5A3EA6B104D94DBA6B06D029253106A3F2771604002A8EF7998C785B23845579B1F22060E1114C1331D88F172EF11ED81C1DFDA7F27B7DA86AC5967A459B2DFAC327D11EBB1FCC29E503A5F0EB16E368267862EDBBC2E060287E672E1CF718B31A439BAF4FFFE9FEA3A0AC759D6593D19EEAEFEB6A2B4B715CD4FB7D04BA8BEACDEC78BA158F46200EE31BF9E93EDC79C1937B20235C9222C6C73614569F6EA24ECE185A1ED3AD12291BF20FBB42C64E39C854F0D3B72F27EF6C560BBADC074AFAC043D32486E9761E81F2EBE147C224DA94B8F5F5E8096E4CBD95B892531F4C4924A30831224C7AFF3092DB1104FB247FD18D6F1795C961F43C325290F734179DC7A98296E5A3AF11E0607DD086E04F61D20BC661762D39526BC3AD16257E1B100DC7E97D3992AB446FF18F7C6658C6107E5656533FB9E1D74C53E1217A06511874317D2C46808B6422B183A9A110B40AAA5D43212DD760C912A2A2EC804926BEEF9F474A70E484B2C97E1F6E2E47D40A32ACB802D14B56583516B4C4BFE58FDEEE47AD7435E98556FAD15A65D34338C0F28E7039258E00BAE42C8FECD35B3FB261B5384C2C4384A2190397AC362F378542F82A8600573EB73928081C7C6E99E59939E3BACC2153D3B4E979F7D47A5B6919B644AED9C0D8528947AC8A7FC442AD49BE14574B12AEB461AE4B28E45724E97506ADD725BAB31E94A37920F40A55198DBB56C407A9B7772235CA1C8A14F41E6F63F62C006D1BD34C42AFC675DA85E12C0F9989B7FCD4627C5ABD6834EA6C5B6F0069ECB352C303DA403FF48853FA999CBEB2190FC6472654095410F89FA9D7D41AD6327C0F509365864F0E7C6329A1C87222D603924228C2857C456643C27443AEB7D7E30D3FC9C9C0668C243D5B292ADCCF8C871751E7440D896C82583F1F0B1A701499A2F7EF685B00E98C3CCBC54472B6D7C89A59B6BDC2CECDDCFEA3B43E192494F6334B1CE6D173F909761C2F4DCFF0E31D17B164B032F12560578B64DBE3F4B919E5899C9EA6F21FB3C4EA445C0667190A6A900926EF15ABA288356ED8742" - }, - { - "tcId": 18, - "deferred": false, - "seed": "EA945C93BA680770398A958B46DB716AC3D58C0AC3AB49DA134DF31504FA510B", - "pk": "CA6D125A791A8607FF94FAF838CC140B7F163C3D5219BDB9BA4CB5DC8DFC3D2F11EC2A045BC422458C32E131434082E0C05B9FA0B5F1E0C52D1FC0899D5BB32D020491041844972B680109CAABA456B8C4744FF7BA2E2239FB5C4C231A30D194ABB3EDB34F769ABADE12EEBE1CF4086ADA3859263C4BEC5D21952F659BD2D717A2D39ACE454795A0DA6B91D6DE7948027F698A38332520E4D88CD74891D342B977CEF86AD063B6C53346EF4669526DE5DA27B71F54E58F54FB9CD9CF9DC86522D46A13C6CB4D7774969F249D1EEF6791150EE05D2404341BC066631052D0A92839F77C07E4FFC447E110D2A3649B4BF7E8588F24DC509922D4CC5467142BB2A3D350B56BB00A23B28C6769BD09F8F6C77BFBA63639D0D9678D94DE66F8A14C22FDC1B9B33D14769AE034203C1F98E94A403D18BB22ABDD84959D63407B87C73E721985DB756E00C3E8305F9C0E23E9D7D8003D010589A283156AF7DC48F05C8A5A814E484D95C5B53006E86F009A6D36720781D79BF460C6461918B417601A9D88DD84D5A26B71C1DF418184D2017C88D1AB6931A49215988B65838207C2111A3BE980C5809C2CFF100D3D8495A7F8D3CDC0D1DF183A56DA568460EDE3631258559B010B2208C8F134924A3CA02FE42463F8D352D0EC3797332442D85D30BD5989FACF7A2E8CD0018E5AA4ADBD902AAFA223C9FD5E4BFC647E806C96F0AEC74578A74DAAEC99E9C3748F388E3A99DD30608E3C5B7382021BC6926D3317240538DF1198BE444D67DE7DFD26EAB0312EBB8F24FAFD464E09CC2F28E08D792FE9E422663B4CA3726194D881A9929246FF957C858D58CA2B2381F5DC275969E907088EC047F6CB1EC8DA1B76DB6396A9C197FC7A8017F233DD0ADF884188FC127BD74BAFA5E138F5B6DD8A1354BCB82DB68890CCBF6F4400A96D7EFA3AFBE7CCD034377532B084B4CE473E0F8F12A5F1E9031984CD109A81FA2BC1C04932D0360FCC0F1293617A6AA9AA6142C8AA8A9EC7E872F0C15250E36A5830C63A0BB8921D3599A7352A6E38E77715FCD2F2C6167A0DF4FF33CC32AB96F2422DC33F83C45E2CC815124CD36B5ED28F142FE79299AB930CB6210C4A1F7754FC98FC3233EA0C92CAFFAFD36E58A4E64475573FA9057BE3EA35DA188FDFCDDC26628DE6C8059739C145BE59119782E93BE98F3E42704A827D3536E28ABE4DF62758E4674ECAC17594F079B1CD653257842F02D5DD70A62B0F84759BB0CF06A19CC2B0FD177C06FB2A020242FCE4DC8242DABE161BC5C1D95F5748BBCE96F07D4B2D8A80C1144ADD0F057A9E3CFD5947D2F1E8C29E1C206BF049788A52D9DBB6F72A344944A12CC80909EBE2CC00BFEF5273036EAE707CEBD6F57249CF40E2EF698393395FCE381094D042026989E2598969FCB343C05227B914CEC73021833701C8AD8937C77AD611E265582E6CF59819C56B0F29174B9080BD8E3B57B7C2D594CE1B432C2AA010C3B55A9D0EDF6A364CB629FC0E4AFF80439F15184E987128242DDA1425C7E18FABAFCF458259192C7CEFADBDB723E63E704719BDDCA69BABA98DB8187583E841025A900E53B35F2B2AD2CB260014A886A84760CA74828F56FD044E300DD273D95DC2B654C3E0437E30134DCE1FF9F02D6D8191955AEFAFFF588357573CC17279778BA6DE661721C02639D0810F416D2A284986029D11C54D225980FF3ED3B6603F4B73264328357568D72C8875F34A4194A7B556662A2820144EF89E38DB837D5B539F87765F98D0E902AB12594B076852A0EC716184EB8F1A589B06C374CC8C6715DA7AC6823F0670C78D9D3F7D921AEA718BC8B3894116B2404E623975C0ED", - "sk": "CA6D125A791A8607FF94FAF838CC140B7F163C3D5219BDB9BA4CB5DC8DFC3D2F7CF3CE2F74A2AD14A279908CBAD4D566CE574785BEA782A9A838666FD20D0CC66F55DA7573AE47774CF62F0FFF40BB0A9FF42767685B979C2BC3987046E74E7854A9D4BFC9E7ABA2E749FE766C8BA10BB7A21D46C27C0E0CAEE22A599B914D79CBA2698C446684402C58344C022230C4A0094A406222A04882062912B98D22390E53A0691A3425819889D9146D5AC871192251C34406A084055C428E9BB44C51B6259940710B00314C086A5C008814890858342664227009062E04318A483809E3286D4A342C18364C540031D4A09120B2601A31700BA52D21A98518C14C90809063346654225021028DE0B66D43C600084361DC14610C1302528609823252109284C81206C8464289B81122B70918472D93386211292000C3440C37040C344123178512433114856C00A404C1264883C470D84812E2906544023222076824A05164C6895BA0084C203091300E134310200341D0486200472DE2028210056ECC408802292DD0467108424C02926550147054C6458488510B384C438681CB180C1C8345D9942D6240898C80401CC82D19B30012C100D94850103044CA26700B242CE3A6881C27712186688A3409CB482552402E49286D5382852187490B402D03444543A66913C58DDC92881384218A0230D8A00D63146C02207104A76DE23431DA346993246D20936C930251141720A228061047711B27111A475111354C1036688B869113A960211220C10088090970A3A64999024A92124861C670181208D9004193A2054988645044610B95100B982C0A9650914261C4104A981471532692D13864400020D04688CC0882194902D9182E23309114B7905182645CC061218289A4482009402542C06D1C4582D0168294B861040610891026E1A2611C040048063123870184961164A860C420529C0660208108D220201A054D98480C59286A40B481C10451D1B60C14990824206E94B67058A080DB1661D3902C41160DD4A08C9A302500B02D1C398E49104A129364880032103064894624141951A3A02C40A2690909458936015C220C12325211214653404984380990C864C9360A84B84CC3424AD0300AD016040A21821B28808A2269811000D2B08461C44CE006315B328DD21640C38645C3B42821B9205C322524362DDA144901A54893106AD9902D11044E520886221368C9B26581168E0A18481B128A2433255B8268E4103111A985FE04042BE50A23E0F03008ADE937C006A04241C5464002866C62DD202B2B7B299400A245D4E1E6E4A9482C432DFB3E3D28E36ED1A3A354B420757A22BFD2AC8848630E24F775BFDF16932E0B1D9CE8743FAA82126D0E28FDC52EBB345CED07B2DC0E36D672A81E3B909FE06D5ABD9AC08FEFC23D7AE91AAE6524B3B032941E35F6DF6BD9661049E4F7648CC64351B0781CAB885000E34F1A1B84EB001CA87766C8C8E403D7F3724F0163EB46E1ACEBD9764637A814D67A61888436C3FE080DEAC3CB020CF15DF367358D1A51F0E0657F6C1434568B4F49BE12982651B92BB2B68CE4A97B9B9F48E40092F8E4B5ADD32A760D98B47C063E050644426FC8C3A6D967FAA9F718180237849D5114C09EBD481764F18B31564ABFB66C3A2BF567DD4C4CE98D226C374AFCE873BD0E7A0D98BEF4837628C5FD978729F1A5A1DB98FC40272005A324F16007276885947994837C3832B18BA4D70AA15AE39786346C177DE5C09F4D7C0F572799F9630B071D95BFBB8734911E1BC44385D09F35B51264C2E71F220D96C86DA0C38B43D91FE511D983124AE39F59B78EEE058B75027794963102107C9E50F193B60DD11690DB8EC84ED9A78E1B13AE8DCAFD878EE0AFCA6096290A0465C9371C1D9C9134E6EE476B5D3E44706DB11D2AF07DDEF54AE381455A452DD746AE86783944D2886F59100BE51B7ABE4F503A402F25F21FFFAD63C7344D7FFC40CDCB38AA27046943945DD773E2288DB5FE4FB0F0682C423AF0837CF66F896BA6E72469B3222DCC117ACB9F345AA0F903D11C8F574DD3DC324F5C74BE0E155A4B856DB8CA5499E064F6EE21088FA2FC56C4C14FA15C3464CC5A129FB8B6B4A0B0D9A60F29D35928F35695D33919B91853D2FB8EAFC5E36789B8079115140F151FF55886D315E53B094C12898A4E1C97F39914930AD96A107A95702DB6546746C8E661C24B289E53057AF78F5D7941C145B9E38C64563ADDC80E95E27362A3AB93B85EB9EE8880467D6EE72440E114976001BAC4032BB9323EC6AF70B77F03764BDAE26FE824B402BE79290EE99E81F9DE4419A4DE016D925D9835DBDD9467F731C9E54F604FE9A101836137F7E2E786BB5A46A7494B75F5225024860770552C59446B021BB6968D6B6F9DD9F15C50E22BFEC54976C94980D4E21B19DAA740F35A6D13A42878833171F7B9F33ABDBE78CEF9B8F92A92A7D9B96A4284FBE923BE691090D185BF42B5D1CCFE707ABD2C9F14A55E8AA5E69BD4A0BA8F6249BE11B65D712BF61B98BEE99D1D3F190C76F7B7C448C133ADD6D8FBAE27E0239255F6047167E84C54F9753EC2DA7C53E089974DD49868B6A2F467216E01C29DC2BAB531C8158AAAB9137C55520C1223A1F804C1A9AB1E3CA5A9C380646C8F48DDC70578125E5502BC7F441A416866696332CAE434FB78349509E592F7A799A22C0604942D469BDB65951B09B94CA50989C172672161E77A1BCECE09930E485C1BDEA9CC435AC84CEE3CEE4EE6E47046E1068FAF8F2EEA2562AEC2118FBE748CEF8BFA43799BECB81C514AA4E1115750400EFB12CF1A7F47D25B3DC1AC5F3FDD9DE82FE0054716086E7788FD83153FAF1D9241BFCBC46A8B200C2F35B5B13453F8F73D52025C62FC7BE837C291B6BDB73584D4D704D6A742B9EC772C36AD7263278ABAD4F4F17AB801378E7DC7E5DE8E852B1F07D00B7A47D1527313753A2695A88980F5870C1D54934D0D7588350B180012DF40C57DB2AEED587929EFA6C1CF8AA82F1C51581B89A87226DDEFB73BD581210DFE3CBCB6AA1117C018920C809C0B7F70D034B8AA0BCACFD689C247027B5CC166109EE063557AF7B70FAE195350836137828B060A82568269336D2890D9F7C6200FD1D7E6EDF87DE48DB19A942B2F15119C01EF58951CFFC15DFC40C16C695FBF14B9AB602EB8F7799320BBBCE2FDA218BED11C4D102ACC0B29782917DF52430E95D07C859977C1DC0763B13305AAEB4169FE4D57962A55295904A12E7D169E0AC5B0FC7048546A6F1E0D2D0FF2CAEA2878F41445AAE5EA4BC0921DD8FCEEB400A25277FF127AE7FD57F23FDB465108DF387E20DD628D565BEEF6C34BD8DE36C33F7944120E08871BABE9A96589D69409C66BD4BE9EFC9359650BB0AD6773D5EF9C91910C7846C4F3D45153F68059E9FCAEFD86A3195417016841231EFAF86DC68E26CF7C3B34C4026C78FD146E8582B36F5F458ED59FD4EFD5ACD0D861AC54E81E49285140E511F24F8B3753EDB2C1FCED62AE755369919713C556178131B84F857EE1B8F37DA67DB958358FD628FA396410D1865B9DA8C9AC772A5D6172E7CF225AA5CCF60B6EFBF0A1BEAAAF" - }, - { - "tcId": 19, - "deferred": false, - "seed": "F7AD0FDBD2F83B60C726521BCC0923122D1257181BF03C25516FDE98C709F781", - "pk": "08C583FE51538CD926528D3F9E09CB7D0F90FCFF247002D162983C5C34B92C17E4EB81467C60AD40730626E412DC0A7FD215E75945BB223F17311A5B72BD0AC75F487512B45D9673E7F659D6D31867FED1C258C51EC7CE9BAEA7E6716BD33967CFA0A8538A96FC37A1515F726CA4CB1124A110ED9AD4C7380963739AADEB3C62832211FFCCF84EDC129E068C9BE4001A29A4ADED360936E858E4A401ACF4A55F087891BE2B64A8DB64C19323FB527EBBF61C577419301B7AC70DFF901169DE9EF367326E83EF4E13706499A56EA10443DF02FA4C55441FDCBD946DA8A81C5CBD320069F24EB931716C57FD0AF6DCCF49BA437297192D6149954CC1DB661C874C5C81F2FF5842A89D094CD4E18899EAC122DE246DEE7728282005AB3019EEE47B3AC0066CC136458AB5E89458500C1937C56FECA6D52D7C626519FFC40DE49D89A7655E7D6612FE7CD6D72C36B93AC7C7D75DA5FDE8D80E339F96BD6895B07B87DCC5C15377381B8AC3304AE7CB51DA169982A297450499955E816C557857F2D4891960C4ED5C54F931B9E9462680DAB045CA2ED5BE81427326DBF390BA5B9CCDD147470C1319707495212D791D2535ACAFD4BF78D4550A2BAE409E10DFA388227BCEC4CA3837B46266BAA53CB19DE9A3D7EC1F354B648C57D0877290D09F92CA61BD3811C2CDF9EE870918EFBCC5750DBA2510B601AF593245FA4DAC6F89502E6DCCA5D4BFB36628D88975938CF1C3658E4F72DE501917428D62994715C83FEFF5A714878555EA5FA7547F5061BD6DD148041AAEF04334463910D3E82090D2EE6BF80781C3C3E2049424C9D1D3F9CB98CDF1DB9168734CC4CEDD241F5C1F26AD69BD979E69D2825370E36C1BA31E1DE8B150B16201967528F5BC096B1A43A06F716A2862D107391222EC9C4A546F1DF3FCAF3F5A0B8B40B0726E80E4CDFBE174899BDD50BEE334DBDF77F0A91A9DF6900BAD7CC26E7AA8E362A6385AE373C44B0945F5C0B2E60BB55991C14D22F5518D200ED43815525CA42F8331913C9C8F532ECEC1F1A2A8DC1A7B38AE15B8BC99BCB542B866333B234CCB125612CA99E285A447E7DAEEAFE79812F3E3B372CE0855B9969428EFC911E2A332336FF43CE8F661B1FD4BAC83F56842E716B7F149BB39B4D22EF5D54592D551AE15F98DFB9EE27DF3192874DFCF8A42D5795A636C83C4B0EB828894EF8C783FDF28FFBA780ED18601DECAFDE64C824FFDFF2E40DC5590E7098FB74B226A5C556F0B2BB68C3628587154F42A7E80A80A430532129D642316CB975E9501B0E2933377D04FF576C922E1CC06B3A5CE6EA7E1B611DEA65FEB2B092B81C86F00B99FE676FF7DDFC549789901B87CF2BC775CD5A226C3724D7FC14CCECE36131BB53CFBD4B1606C8F57A5DFE39C4B946C40CE3B36F6CA43FA043DDBABDF56B03CB12ED1D3E929E7F15FDA92615277421BC0E7DDC4392B2CF5AF79193B3C26FCA0EE4CA7E34D89CD99AF85D053346D4247ED68226A1C82B32344C1DE2BA4B71AAD24FDB3A4004820F450DB8766815554774A3372C1CB97B5C365C0E78CA06B143022FD54C7BEE72CFA7FC2F4EBE218BE84CA503DA9067F36D76839F5E4386A95CDB65221A5FC5D39A4AFC65325C8E17E1FC22FB73E97B5B0E341ED24AFA1A50629E7C5829F8ED47EE13D25EB6472B6A4C795716688AAC6097215E423F8D8C7A017E10257E96237D2BF97EECBE02F68F95999AB255B5FE8A7399A294183DBC38B69139F1612943E88146CA41231E80F5598757650C7C64F5F686851DC64D8E073523DEBFB4AEAC5B9CFFD6F92FDB356E178749397E08235A99C52958A3D99FCAA18FDEE9F5C49AA3D3C9F", - "sk": "08C583FE51538CD926528D3F9E09CB7D0F90FCFF247002D162983C5C34B92C174E00263334CA00EEF5603917486011A91A03BECD6D1218C9AACA13A58D65024247646E4A2289A28C38896950E8278F9EB1E8E3AE1E8C07C748AAB114333B716E7E95843F237086C307225C1177CC0D2928EB2B4F1F81B6479CEBCD693B92FB6E19106000434083248C62404C12022C89024EC38604502204C8444EC1883004256E12352084342550246DE3B880D8824C4A16051B89448080052400680A25602337848A448083C4681A4888CA263211A0208C268923246E5C3682604482A1B22001016CDC128CA0C26CD2A67012262D9C084114024018376454140910306CC2464EC2426A91922813382422996C633844199681182512DB1672A4088E489490A0C429CC46212146655312510411915442211B032E10142EA0108502B324940826C24251013911C822701A1249D230642409608AC66DA2A86012027124934D011760029605C43821C1048E42320D803081A29688028870D38009E186489A426D0BA62D120566122152D9380C40140A62063204965000B985131025C2102D18A07098308099160214B425CB340A62C88080046D5110048C228A00934C48044A8B48219C02280438006440520C41268926694C3664C1A46C5A22460AA54C520032C89051C1A064224430228344D938800184288922881AA7910AC930E4149009C409D3826520C81002A4319146240CA400C3246EC1962C820490143850113549E49069CC106A04052283B28942C86C1CC151980244C4442E14066052B429C8A09081060C9CA80D8C422042200D0A9188810069CB243260361104326491068220220CCB3441DBC06CCC92505AB271E22212D428301C3390C99481CB06721A0266D48471414802191072611610003682402222DA00520C914D89328E4102094A380453000CA1006123A14D11C03121339054C64C4A269264366213C661E0946111B88D88802D82C66103106EC0400143482C20A4900B011049462D0AC9705904004924248C2622913092D332826320669BC62054C211A3B4401129055244320890211CC54524C485030971CBC62554A240D4A005D838260213804180115B2849612011C9402DC8B851D1304008368D20A02582A421DB342E14181102462E23126510C9091C804999248C61820D54C44D59C08403160DCA10420B140ACA400E4112419C22885A1689C01202A3264219A40D0348044804690025662322929232690C4069D792697207DC3A6B716F6F82572DFE0FF9F05C53FE3215DAFB1CDED3575DBB95839694837C86E2056F91C27C7D15F7337E89B7ECDCDCEC4B3D982CE8C1780E8C9F9BE11FA9A5F51440775D8120A60ECC8C0B5F6F683E02AECA449F98418F39DB4399E1EDB2C4475706B2B79F270E3BCA18725BA3D8BC834651D29C1B2CD688FE7AF80818C4D9106ABF2E82C3B1C3F09C30C8314559FF0B368950D50FA2D3069D31062263F61D9B934D0C9098F0F66923ECA1D20F5E06DA4DC4B7CFBF74D035CEC73466D1596BA89254579DD536CAFF93EB4C0549AA55364F586395408E8723DE82962B8C802266A0643D9D50D8AFAC6708814AC67F24790904CC71E728B030CA43B39EABF450D6232ABB7217E6193093A95AB2F5EB4223C319ADBA0BAEC5D1501E702DA6FF2B0729C06B24D98E268A22EB28A3258C6EC03190132D7012696B81BF0B1C921C6F1889801458C343B2786A3797D9913A67CC171D89B93B521A18452F7299B97D10399E02A91BA56FE1AFAA92F5C418996C1A29EE8A1B5B6F664B6D41DD69939EFE31DD082D4DF59D428C95266683061B26BDE28198AD135662DF0BF5BB401B51D17E576C1A1960942B74CA70AA5D332BD238FEF557D39CB4B7EAB02631314DBB91367ABF476D2E3BC2DEED1A05654338F889FB7F1C4D08320638A6B1FC61C25B95FBA474ED1B2758F69521C602C123AF1C9D331657696D1AA5C55FE671C069CB2CA18683C2F7A5A35DDA52E3E71C0BF77EED74CA7398E52876673162B88D63690754DAF9BE8DB9220AB35A72397CC60276870E7DE8853ED89BCC0E555247AAE1BB22236EEDD9E5C8A973E46767CB3AFE20884A554E7C522A45B599FBB7F1C4F84609F5489C7A798A0FB79C4B8963A0C05B686DFBEB324AAC5BC97BD46D4149502C36D767F57CAEAB2DBACCCDD7F31F0ABB0EFF7978EDA13EC1D0E2D1BFADF503984FBF23BB56C68E3C7C759136A12A1E62A4D11E3A08A76685D082CA5C9803CAF1AC032B9FA90E16FD55416F189C2B13C2414EA222CB5DEA142D41E7B2BC499B7891124D75F8DF559850C9368BFA41979892DA46F22ABD2916884915CF1856B4A5EB3CC00E4CFFC36A48D04C8F4BAD2118188F06F76D9E58A2313C513555C33D883FAEECFCA01330D740148E03B6E21A35AC08B85F788B5373E9E5727C6673DDBA5995D0A30D7863E435CD58BFDDF22C5BB2D270BBD74116A32849BC6C9AAFA7A26AA4F0B0D37801FDABE99320F0F33A025093692C76CF06242C41A189715C239E2F72FA59A46D9951ABF6B115A1ED0E517107B89F0EA49D7C70E69DE121E53347FA9B1F42480B99456DB5862315459921203D93EDBC5613FE2B7EDC756B67457917ED21EB46D8B7D35B0CEB9C9451D6E9BBA9290A96AE6D7AA14C3AF93EA28DF817DEF78007D1963FDD20737C1D503D47E94A0514E8D06BBB78D195F5C2376D3EF02E823465F94B07B09D3F67D1C89F38910777672C554A9ECB6F5B24179CF92A725DA4A80770E46C4D9BCE5855210996A3957E2CD2B25F5A13FAB9E87B8FF886355AC4EAAADD10F0CB5DD75C52A0E65563FB26F4E0E5CF52D2E07C666088090BF866A58B75D8DAE3772F47ED298B0CB49806783C6A057BCB5EDE6E27F84DE01ED80BC1469A07A9B314723F33E9D871CC294738DB9786F77DC4F0D8E23CB15448140B21AFB5C2E6D97C077FA45DC39CB281BBAA7D315B606E0AFA64E0B02D939904AF11534335C0FBB18D523B448F0B162F7CE993A3095C49AC63663F42705851FA5CC43D70D919EB4313B00C0D8B14958C02C674EF7F9FF48A164BD82984E784F3B3D65DDDE52206646B400037630F7A7C36EF61D3039BE92FB4EA9DFBF0040C307395ED490009E2EEE43FCC9BB05A648EC4551D1A44F901E0AF85F4E3731BB1CE60C4C374AE440C9E05E4818ACE6FB50E70ED1D413E6C89399487C06472AD15DD9D2BBD7B9E1961CA94A7E15DCF772BF9172CDF7B9E9A67164661B579BEB88DAC9FE577F24195B3AFA624DE80D021742CB6C91764BD9B7653CE2F7FD162F2DCE33792285FC554F2235273B0646CD8326090747D4F87B8D4E24872F44E8055B4E5E938086F04E1AF47937C4BB4A56F9DCFCE9ACC1803056DAEE856B24AE45BDD89189F08EB4C908F1C4A6E22B3C04FEF78442733BE2AA609297D8A15E42A2201EB18A87723B92514801A37FFD3B4D36481EC2550DC6A620186413EEE403505A66BB725E65838C6FBDA562F4AA3DE364E237B9FE50915D3056054D613039AD3208E700AD81A745D5480611206A8E45D5B13BC664C724ADB73C981E8788C07B2A9A822883EDCCCC179F376F113642354DD6F11B45A6E317DFB215B" - }, - { - "tcId": 20, - "deferred": false, - "seed": "B0C02139AEF99336D87001D936CF8DFE30459D268074B69720B15BB7939F3D4B", - "pk": "763FB831AFE969385A5E604268724FC10E9384AD30D00638C68CEA2D8C5DF9B9ABDCAF2AF8E16F7272A96A8A6EEB6C41EF400C05688A73129FE2DEC50ADC3C7763BF670381824A474E2EC5B06C5549530CA5C216E06A5D0BDBA341983705703E9AC306B796223991E8D35AA0856184D0EF5C44C6B3BAC268C0D952F571BBA2852BB93255459EFE2AAADF2B24D35407353E718528A331F8700BF722B6F51B833DB1F715D358455E916684593438071798E17EF48CE1FC777F5D2D308C22B2B3CD4805773494C863AC6D447C8361ECBA576F0348459946C7227FC8905A59700113827D88524BD68BFA2ECA81F9CCCD0EA759B2173FC6D1A6EEE3FAE3D9601411387B8C39DFB3BEBCE4D6A7FA5C08E61606B4B85F21067A6572EF6CE91D39F7F2D24157006B434361592EDEEBFF2277C4FBBBF11B30229009765B8D24F274D7DA88CB8E4A89D6F77F8901359E504EE2F04214F8D6B560705DFC9E7936D5FF1236B2D1C83459C0B5B6283E34BEECAFA84A80262F206D331231458F9E38EDF6D5AD5D2ED1ED84642A14265384CC302F72961D11A58C7DF22CBAE52A4ADA704EAE6FE9477CEEC185223D82673323A91385F5575B30A0BBBF6F24BEF7A62F737FB6B88BBC89B9D6429119671B74ECEA5B98BA0597510D3CCA0A853688425257F9017F0777C02E40D6F2DFAD9AF305049161283D90F183826C5FBAEB8586A2C766CE4FAD6D3D565B4CD459A76A2CF23D8565D493BB09035B2C44CB7D62AD772658DF463112E747221D6AA3846B207F839BE7EEE2E2B2FBC2A851D666943583E36B2565A6C80AECF1AE6F9A0999943BDD7DE253769E5C5195C24B1E88D67DB38C5378A10239A7DB6205BEA44847AB1CBD3954D0C6D70E26CA139FBB7AD7AEF6899CA7B57009B778DA2937EA4A3340B8C389C2B251A0EC3C9AA697AD5320F9FD41F799714E067EE46FA9534D531532D7D62A06106920751737A52D64610E181AF8DFC424541FEAD333BFFDA949CCA8D19BE372CC14DADB16EDF4E65B336ED1C7507DCCE4A1762B0CC2EC69AC3DC0E7AB12A837FC227A8911EDACDA112750C295026666A7EEFABDF8190B355928C328E3BFF06F10406915C358B579A19C55A07AE2FB071434B69BFA88A92C52CD795C97FFF514CAE1C4D0D244FEF3D26A2D2D62C931E8DE8698D7EBC93533C37F365B640B91C0B85CF55075DB6267F5A980806C39E096A39AB4D86C380CE94F5EFD7E1C44F1F77085CDFC0460062D4579999C9E395CD8338D6AFDF963E7DA6A097350A39FACA19BC824A614A84080373A27B550C4EB321CA88291201DD9B79FF69B89FD50FD34FA80FE7D6D3F5F9DA98CD2E8A151A5B35C7C6A132123FFFB76935AD5D6EE9DBD99C2D5E394E540FD3A7B76439CF442807FDC4FA8FB4A1F5FEF9EB09588807C80A9573E54E6678639B45EF7AE51F7311463E9F345F08D4594CA94DF334C29E69662558DA177F9D4329F25E191832C979FDCA310DF96AC66F922AFAFC38467FAEB7D6B57A2CE46FD272998C17B78C69F62E16F72B44500532E886F10ED712796F179DFEBB634CF88E7AE99BC4405E69D89AAEB42C9BD25FCFBC8E4E88189CDEE12A87EA48B204F7FA2615430F8F642683FCC22061560D241B1D1D3B746A487DD2E17A81AB89EBB01BA9AA3DB992CD0DD68392576E65E933A3C1C9E6B561575D073C3759BDF001B7C4B96A15E419F982CD8E846E383D3FC2DA80605731A0A65AE905D6D979A1931A174D2CA5CF073677C862AD63810F945ECA3551F63426E03CF049882DB09C067BC0A8AF25672FB30F0E79ED5A1A3FB0983AF62915752315159D10D3AB86C282A5DD123170783E00A15A939A4", - "sk": "763FB831AFE969385A5E604268724FC10E9384AD30D00638C68CEA2D8C5DF9B935D82EE28F88A1D59D0F78740D34116061454F7A1A4258B2EBA2AB3A8EE9AAC87EB6ABBFC89154E8249F601F6A3212EC53FE82DB06C9FE7777B725DD75D8EBA3FEA86EC5B270EB3C5DBEE5D4C5DF89E46F42A4482D8EB94176A47FFDB279D67EA2C00D1214604C142EC1082598045150284882C6649C3280E4B04D09C60511A49093286D93200460202C9B8441D2C865E026869816458292908BA4905046809C302E544642C3422A9C906C64362C1C070A1A1428A224680A030890B449A13481C8402118122888360C9096280BB3819B067163342010880911832598C40DA40090C1240081940DCA124A54120898284000860D140730D9489282B48C04C1508C0822C428461B338D23002490808019398460A240800005DB925002146211440610A628904632A09861DC303142924800072CD9368A992882C8863004095252A6301C92454C4072101320120060E28004A0C4601143109014051B164524326C6206321A035110382E10414C82B88451386A0843315C224E4210410A4991A0882C80428DE3344D0B030252286820477021C811D2426C59264C0BC54CD9309183082998368D08856921424200424040366282800019C6851287704A428604476959909151B408D9880421C930DA346948844C1AB54D0BC9000B05291BC250D8C44824296C12038C04100A84C010A0080A8926880C25051C390923C08C94182293240E1CA541DA027212C4452305025920525418480805820313724B888583322048106198465144B86183C050D0340200450258A6454BC26903B80D81104E001501204425E3340001064CC98220103941949884C21681D29829A1B26184324608C66158304204173122B12554B410E2348D8430121A010AD1169083220A0310264A8890434221532244D1C86122998D62306D61462022A40062360EDB380082A621D4267080C441C9B48143A244A2187091B86044448A51240A19C251191310D4128E62128E6288850AC48DDAC00C1011710B402482A4019C046E80485013400891000A0814054B02051A476E91A87080B024194448E0802521426888066CC82829E28208CA26308A041210845103A02C529611019245D4128491246A14B59009352C14350C132460144666D924225186844AB630C342484BB0651CA2610AC04023158E09402C23B2508C04261042666104492393044A3292A0844892442A032762B40570BBC2ED9CE35E4E6903960A5DFA7800993F5438ADD1671D7D3848B9743709A9774C85BC528B2F0F619998B7FC107A4D4AE40270E5F55C889A2A0AEC5AD97C118A6BE6336C1A93D545FDEAAA791D4DB90DCF2317D2E6F013C12B027E38AACDA013E4F1C660D25E43402E89CB69F72E47617C2BD4AAC1D0151930CEA563066C3261F767587E07AC68FF4485726AE42B210220452A9C399F684E1B9B228F6BA15DA5F02401CCD4858E2F502B367C5E79EEB28C6D63DCC2AEEE547FB67AC7D947125FB162133BC836C1B931A454BEE47242AA8BEB8A85AB41B4184BDEAD20458AE8734074798D86795C8AFF512927D22CEB52B86B8006B1706035116C4508B35FAA86DC4E6EC735AD9DFC4EF993A79AB8759974270EB82D78A0A80114F92A0A8A2806620FAEF97669C75ED51E5E0BA4E1753C6CCF75FBC0F7CB42F866EDDEF10AA07B85983B6E49F630501311A8FB986DC978C2DF9DB275FD67834FF915BBCF5B3E30A6942FA2C7F062EBFA5C4AF36E22D57251E8E79C9941E09803F98B4EA46D556BF7809D9AF4C86B8B3A7CA6BAB3A0E48AD77A5F01E7D20765417D3C6561E6693F061B58C137E95B977553549AE66A16EA02D87A906B993F9B8394E6AD3E7A4182B35A70345421858484BEC0813B6104CA50C09FBA0F291565B50E28766F91C44C1D989162A8DEB1E95BB0BA0912D6C506A6DEBAE47A4E939F0F47E88EDD14F8A35253D8337C2769325F81F1C73D1E22B54D8133E4223ECDC3FB4BBDC0450C8E007E7DE2ACF075E5D9332247B6BDE0058EF4E56EDF59AC3C8BBB88BF7F6CC48D85A04F796EDA1CC91D08F839339950E82BC5D04FBF27AF8D0F858B4356B728E56FCFE4F04C2F7672E0EC5E6237F73382E9E8004AB6680423729CC9C51366465B4C324C18ACB245382AF26F26E4430746E98328DCFB24148486452F284856920B162F932BDC25A86ACDDD3D5A1422A0EBB94FE948FB58F2BA856C945BB20BA07E0BCBDE5740631B3F6E9C72B14ED7F79DECA30AF6D55573157CA59907340392B6E62143E41FA3DE63EB14B61631AE846F80A9A7707B9C2CA22A741F8B9CB6A2FFFD432BF2BCAA059AD23D35B6BB47CAC39CAECEAA917370BB89D33814C31FECE827889A7D758C031DE16F58B4277A04455A7F515BCD34630AA0A4CC253B5741E99A27F251313177D52CDDA8182FAFE6B32F4B820C8EA34413937C9FCDAEA67D16A7C2EDA61BA1B8B7266D48C8E8408F299C3526B57198FAED1855C2645BE3F678846491C5C440654E705EC349BDFF04AE935196E97EE9946C3983A4822E0566724C24501CCDDD6D9D4BAF8EB9D065E5F280F8F04CBB7B3E8C76757FA760701F28776BB86EDC0E85903AB4CCEAC8DD89482903FE6137675742D4382C4C4CF66FF51A89787502E6F60E5E622063C71E7CF1EB365E6BF0C25DCBA8ED29561E325BDC64E528DC961242B4DF790C6C28BC7217B54ECC4915FB29873905ECB8E9E82D4349D4BD8813134F2930E0F3E79F3AA10613D535FE717EEE3DF66C1E829876E8EBD5BC624720A00F2EC10B369929A9E6F1EBE7C88C7D4AE413DB05BCEDDFD74D24E4DA4237B17703C6A48825521E75CC0F37EA656DCD1B10D2000B2B04A884C64620D607B1099D08A745738F90AF19C1635C5517674B317A609ACE877382A34F6604EA3EF08148280D1F78B1D2CC538671C71C6AAFC538FAB60D95977B1DBC2C4320BAE64E595403F7B54CC81C4483A69B6B515CBA264335531705AA70EEB88B49D14D3B8EE588C6E32F68F96B7B5219C39BBF1FB45E9617CDAFCC8380AB86E2669812A2C39E5C3001B0BA98847E8BF01B8203618CD92F45926DCB22D50E2751D5E3271D0E7F159505E4FB7AA9BE30A82DF405B4C0EA3778E1B75634FF4356E42409E36BA15425AB7ABD650D855340D203705D07C33250A4AF67B2DF4F2A41E48957C98362D6F55C202ECA584EF1511577EDE1368D6E79EB3DF014FEF9064C082E7709B06D23914A08EF375A2B63DBB0DA0FC780B66509AAB62B9B47156E479DD268989624389A098BC36E65E4E43DF5A804735A32FC3D91FBC5F29AD6869992BC02860BA35833D6782C39496404419350B54D8A176CA742CE6D4BE5440E94B00E16B2319321D3BE09D7A65D40C0940FBB789156AE56E41E686A0B31ECA83FD48BFCAE60BD670C262E454073C0F3E074566B5A9B7AA61F26FE7DB58755BD63FD821E7D282EA7779D548ACDE1EED0F2D4EB49DB8C23939E2C925DAC5180C3CEDB532EE049816C129697EDA8616C1ABBDFF14952F7968003C212C4848E5B91A19F1B8C41509B2A95E548FDF81AEEBD2BE401DE92E61A3A818AEB92690540903F" - }, - { - "tcId": 21, - "deferred": false, - "seed": "9E5E467662A57A5A45824B882101553E95DAF19EC097B6310ABE3935C24CF284", - "pk": "1FD64A86C2E0D9EE3093A00C0E6720BE47731447998DD55FC6A39553939B777FC7911DD947565A75C3287ABB7942631AD87C6FFF760DFEBCFCEE14E7BFD65B32E722CC3047FEF7A8F99C454195840788211DCC2030828BDB355CEE813D4A9D7125D00E35B676366E04A31A2643DAFCC1C25FA4CD8A898D9F47F14990AB4076DFBDA212051C8C480FFEAC099247EEAA1D84C5BC53CAD03C343FE912A6EE3D6BB0281178753EC6627CA8A28F2E1D2EB4FDEDED453ED83B15A26D1C88D9BF8A62B9AF8C62B5149EEB239369F1432457EF30D8F0A9151BD89AE270FAF53AE69DE47D90A76931164DC0242FB52ECA46D62E096BFA42FBFB2F6168F390917B31E750E2A20F7175E27D5D4BA25536CCE167473A68080110C11CBAF5BB0275003A552FD922E6A8F9B1D31AF1BC5F8D5A6CBDF6211FB48A936081AC3A155047EE28735668C61A3AA2F336914137D8646C2406D24EB9B825C1691611CD8AA3DB2C8D35D3069A002B39C5DB8906536F8AAB76A5794187E6319278262DE1115B7612E52387A1CD8D2BD7441897E4B91811BA486557E477ABC4B74D222A45D70B6CCE829111BA8FB994E148B1211BFFE473172F5A2EF1018139BD10B2627EA1F3A15518EDC7D53E46B6A9A731E523D7FE923BAE33604408AF9CE5A671509ECEE80F7E38E6BBA2001EF73F41397B9CAEC556050EC6FDC403C71FD690A9E043588542D0509917A6A4B2754994A3A42346D1F63762E72DB5DA042DB3477F2C11081220B4C257B413FF52AEECE4F418A0B9113ED6C5B28C734C5F174E2D8D7ADCD1061756AD3D77331691ECCDE82F0AA4E869C322DCA08CFA9F4763003F4DC3367FB7A1432C4B3AC127C84809045FACD6DBC8F5059C04D52FBD5BAB1C695AA5C61D1484DB572C88DB0AB41EE63850ADDC79359C9CCC6E211483C11208EA2D94CBAAA8AC1B3EF0FCE07ED0F9CA944CBE4D39F2D7460E12FF544B094D5939FB5ABE5E3096BC367F3C293DEC6CB1EEDB4C4C24121A3027D60AFB7C7A171C18E954BD2D5961CF7EB547888F9C3A4002AC82E09AB02E56CB7DB36673E74E77500C6A6D30DA50A1B054C3FD8BAA0C8180E1A50914DE26A7D4515DBD51E6C4C804D39E244B7D94705B7C1E210E1B651F17F87757DF7169616991C010E69D7204314890893CD9258E7672C2C5CE34464C188DD22E8E3B8B1A11DF40D32917D7CA89F6B254BB0BC6042D73AF18C92A1F6B02B68CF59A1E2EB4AA4F646DA63F29FF89DE07BC52C723AB61898A8B247CD51888688768695C2A0B25D89FFBB2E056DAF6F465215444E856C49E0849253DE4CC6B4C5D0CBE2D57D7CAA589892B9A228AE8157546997D4341742FC7E6CE226DEC98FC18F25A60D347331E29FE524D8EAE3219B739C84498A98AA7D5FCFCF3E8A9F6335FD242867CDEDE024EC7D0C662BA136FD317E6D06D197B2FE1DAB09E395758DA72EA4291CB5DECD4B68BB68EF7F910BE2879A43A8F3D48F61E6ED640E1614732125009EB226680AB0BAE65C282A5E56ED17729D53CB9BA17612CC68416A2B23C243967263AFE1C171381D82ABE28D2CC519F3FC52A140D3507EE92442232D488CC906BED2A399730DBD3E459480B79C3E4A5ABB98EFC72838A530AE82B80571A6C37482BA39DBA11201625485A16F48166F3CF61F719F6E67D4D29DFC769F88926E5133F8ECB1029BB8DC1B349398AFEECB8B893A01C152A75BB700D44ECED0A8C5A77983169ACE8B341C4AECD426891AB4240B246E4E7F5BA79B3736AC8037086492E038124D516A821C96F1609FCBE302FCB7BF897165F1CBBECB7CA1395790BBAEC1CBEB30B211933556DBF238C0FD7E24B6489477CE2CB05", - "sk": "1FD64A86C2E0D9EE3093A00C0E6720BE47731447998DD55FC6A39553939B777F56FFF5F2ADDDD78A3E2BB4C5A4DA9067271817DB907906D2554CCA567DB41268D22F13499DAD6DF046717288E48EF9D4C6D3BF5AF14F53E0531C57889404188EDE2ECD98974286206E0343314B528021B667436B73DDCFE8E87AC5F085A4941682B26853860563B86D0CA8400394418B088A9A803112C08501C701133902DB488A1BC731CB482552908994467082028D52B02C0BB86092020121C69153B04954188D8B46811C897199082C5A020684A4211246241A892022266810406D0805651412001B104C99A88C92C0305C1441DC0688A48069C3949042842823090AD1148862406654224421B109142910831851D9100698060A543022D3C06DA04411CC340413B05012413251B20D9B46860216490131811BA34D51B2519C98018B2848D3320523459083B07104C94811808020972CE41641003686938221599060A1A6048C886D244200E236114928494C308D1AC6806482690B96491AC30088188D19138DA4188D18344421918D8320714B04400B406824219059C830E14461E0080154A849029849C024115C1268232480C334244CB08DDA40518C0664131869433448C14000190145DB1026E3049091262413088DA01852E1401209A089903490D8284604B7110AA360198760E222804282852082309C046198327150103261000808C544C8B625434464E00008D8440E61980D889888D0286D6410304438510A1684CAB045DC322A21928D1C240840022402C42C9916724390710013291C8248D804265344218A44049A169010800424A60D022988D9824421360A998471A4368053160C203608C8B465194341094601D3268011340C1C40228906869A38681B338491842CC9426E04992D10074D22109149C229DCC600000889E24688E398058B38244B828DD91470DCB06081802119049110449111903118348D19486C0992311AC04461400C11144964428413866C21806CE2C004E0B44413836111370A1C114689168880306861288D54147180062C19096A50B40013447188C088CC38301AC940044029032621C4A42882186824A110C9346494966C08A245C9840442428C8C3405D32210DB200E9BC28DC1966818414C5A482E08040E4AC810118511149849DBC46D99B229181189199581CCA29053126E440826D8106DD4486AD908260A34814B904D88C05118184808459004B5091C4465D2B83090469091B0112399705DE3EB78E228DEE7F70D7299EEBD0AD40428FE8E4B14E5B573837033F825FC13CE5CB416F30FF882459FD3FA3EA6C4281C3C85C2E9FDCC7D0C31D39B8027EF4D2DD054B580684DB2E5EA26DF1C0BE11D9C531104AFCE61DB9B71EDF512B3EB8D2D36970503686682897D25369E1C663B0E0608A53B841FF1A6005DDDD3402D499990DB2EAC2D0FE1725D1437208391D84405C8C01C1DA8D50228FE96F4304680AA4B22453F67369AAF971FAE95A9B2F693F2283014F6C33B282420F8557D81DFB26E1CD9D15ACC9BC33224C015C4258041A108D6E14B64D97EF69EBE0C9763D44508F2849EF9FFDF043301BCA68F77E56BC1780B6B9CD58A2A550389261864E2854E3A78AED80938832A8AA14A68E8B59F53E6BA4569D39A63FB4256A50E4B5411E1AD2C5FA6DE66F87B8569697D9C1E4746FAB1DDCE6F152F2BE32FB8BBFAAF8BB1CCB14081E5415633E7294226623737B33528D66003AE0EBFFFA9E361B9828FAA39CF68744B442DDAA2976290755D7B7CC878446DCB11C59A5F66A38BA6B88697809E437BAACA2898CDA27BAEB33BA2D1930F859E2EFC28E82AD1A407177D35C3A8F76E4FECE7D8EB1C5D686D189EDE5BA8630EA309289F1B1E1CF294DBA76FF182D981D501E5DEB931CA103C3F56A9FAE857260FD8345994A0D2704BBDB5AD73385E3963F7A4C7694C35B1513FE8D4F001BB661D28996DACAFAEFF590C3A8A4478BD828105775CEA545062C14BE01FB52F4CF39F6EF90C7F6E3FF40ADA9FF4BCF325B74707A38AC8CCB3F4F3337B2F42380B8A111FDB72F8CAE96E373FEA8FD8B34A823FB5E2D6EEE425625504D985D873DDE7F7289BC6078E2A11E5E9A90D004412C44692B8827B8C1B9D6FBC37698CF2E6528C3BE794C2B343062E55D20DE220715A4859D0EFAAB0308ADEB3D6D0AADA3B9B83E790F36513BBE4CA857241BE78D98DBCF4FBC50AAF971650724781C50B993D24A8F4F9109D82FA7A208982FD6A924C6A1047A233C0BCC59038225BD872B63BF5B698347F7256047D7A0A0EC533F0EF8FBDEB67B909E00F120E1FC36E70685C99484AD1CC5816E63EA40467001485C52BE6B0B8FD38B5D5929DEFA9EDCA9ED6D699D40BA4B4D1818B71809E26E1D3BAD6A8FEC83D38E93D6584A45A5A3C74C7DB19F461C4D3A1C0ABE6C3E1953128508E8E4E1FC9A22AE185B557D8973C727095B1D90144F86ADD903C8293ED633E092B38E19F14A488EC1EA141FFD1F1E1F14328209A449E40AF2255447F173A6E39AF85902C029C33685D50E6EBDECC5BBAFBEB88D4B8D432832990D653FD63E4FA6E288CB94C8ABF06A96FABB2A6981ED1134CB5E20C65EAE52B0ECDB62B5A4C2DDB2535EB6522661CEFB5C510ABDDC11406B520C8B9D93703AC241A91078D9256631A9EE567AB7518D10C6CC5A651D7B762F4D607EFC780D121DF1441EE5C72C763F40086DA2C85778484F30167FFED8596C118E76A0FF1386113C5558DBFBD8DD79C898E6DE18537C0E026B2498478B13EFE1D521FCF982E18380C9CB2F684633457169F615CF9D9B0970F034B2FE0AFEC705499244B9ECB1052A48C0679C9D38A94851C0B3832894E833D712537EF9616F4AA245BDBCB7ED4B83FB02C34C4D28F267A2207FF9073EE2A76864154C8769BC2CC21E18452FE8953F5383F7D03B8A9BA9BB79CE31FD16F361254519B4FF065AAEA21A0C00EB9886BE1FAC0A9B11DC2BF6A7ABB94B75D884C9EA00F35FA1DFF62A3D8E50BF540D3C3FDD8C0EF8EEA531C28913A6AE19AFC4B1A8DE1EC52C939DAE8FBE784445465E8FAA1AC810665AE3AF82C82F18713E0EE56CB74AB2F4BFAD6ADBB2FFCFEAE2ABFC3A0BEE65C271C3C825DF01DE8DF618342D4F614FE005B98344E43AC02F9493FEDF6B4966BCF2B5907E4A71DE891D5C2256F08E79853986505E99ADFBACE9B60538F1C013E72E4946A18CFECFABE38AE16F05C5A4D22989F3C83C5FC66C6176D2B26D5EE1542A25E189A8954F24D6871A46301BB4896F614FA6B7AA536D30ED024D726C87F95EF9AD28F5B9FFBF08D9C2583A32A2146141B53185F70E34B9EEA5FDB967BE995AD54F8BF31DABC5AC06F7C6B523838BD49E69B5859FF6163F5C6F3D52ABF90533A38E2D7DCADEA0E05BC1484B720EB2534D6B3FD4EBC96937BA9211A9EF55BE30504544BE33A4FEB14843905C68F03A6A03C7B948AE195A951A5A63329BD691C73C613BB9CBFA1BD25341E91F8CC94B4D2B7C1DD4B8F6FBE5E00C91A068A453989D9EC3D144707DF6CAD210484DDA0F4FCB6AA1B3979248911469E9747D06877C9621218A383F81C8A1EC1D2601C9145273FD4F9737481CDE2F3E2" - }, - { - "tcId": 22, - "deferred": false, - "seed": "E13C0B6585FE12EB64086B34B49D5E074EBE3A3688EDEEBB26A737C0E5F73F44", - "pk": "34CF8D42A986CEB086B210D348C30F0DFE538760501F0FFDD2D235E615E5253DAC75D4E29691D11EDE6003ABB4D18FA0384B21DF71489ED36530A0EC48B33205C2F393713D6FB8261499CA51007823D6233B77CFD8713A096D4C468E6415017617E36CB55EDC838A58AB36D56B2D4CC0621980C4E0D4637B3A6E3EBA245EEBDBC29B99327232C279F5777A2EFB8A74D492812C6E9E620D725E6AE4961C20AA7C84F4784F6FED36FAF3696898668D3DB7BDE29D024B008236A58F5A9ADF320C3E5428D2482233A5E202A31450698FE8F4CA36604F0A026163313FAC89A925E85B09EEF12B2F2BA87197B3E8F5F6E46CA201CCE21B7DEFADADD13EF45B36683D9B6F8E0AB717A17A9082EAB98BF09EF8F71DF601A4BFBE04F84F7EC82A9BFD1F0DC4FBEF540D59B245364CD6566C5B5E6D735282DDAEA74F66B589A574EE3CE5B79AB6B5A6FBB434E685A724D41FB463C4323629AD788E842F38AA6AAC8A5218EE204D2602C410730A535484BE7B7667E3BA8168FC5C0D354D8B74B583545E73A59132C729607F73F1298B2FCD75B1DA1A29EABC19157566DEDBF4C46F33ECD31D10B403917D856781796FC83046E2F06C702B803014867D15323756350CDF06C4FA6E9247ABD204CBEB4830553363249FC79355E422D50EEC8E0E153EAD339181859E8FCF504CCDF3BE063A2D33898A5409173A86A4D20638063593D03E8746EF26EFCD4356EDE61BAA087157081C3A49A4A93A666A174C0D776D57F792D0908D4D36A46036FA0623D6D4F98389782D9AEFDD61CF23E044F62B73C124091862F2737232FED252A36B0005FE7129975C225957F3E576BA0FF70458C169F54A0BCAA3E0A797A3727DA6865F5C8AF06FB67F3DE4B8D004592B67575D304A328126D51FFF766D4660ED110E911F6FF56CB45D8A7BC187748FDDDB58772BE7F4666AF1A21188AAA0D8DD351FE52C8F98BB4800160884AD064F89062AC122BD3EBD03FB3C16C12F8DFAE0B0321752892061541B95275AFA789584728E39DF5510122D9DCC7F3B44C9F711579608BCC76A95F54AAF9C5B58B1854FA5332FED297961F65587BAF92BEB65404C85E78C077CEBC3488CA8A1B73BDD041CA3D546910DB7B2CF04FED3B3A5154F416EA7152B3D3AD0BE22A1270D9DCD13A87BF8E45726E2199B858A8D27EA1150D88F652220564DA7A88EE65D1B8994859AED54912D92BD1B3AB3269350A910854302E3AA5F22D5E1269731DE82BD3853F1F9716FB6495374A012693DE42AFE190BB1A5E5158FE6EA8855FC0C0CF839505002B070A0C3F21798F017A3B6E063EF7042841670A9DA96C3B30F47DD02D6F8907E19F72700B81306D088D0765DB3E75C2E21C6BC6C0D592EDB1CAE257BA989CC1D7EFD52D43EA0B2D4C6BA4FE3C1C88921916DB894C7D3CDDC0F5523EE399A06565074137B43705DC6D4E6B1A714921EBE241ECC8307734CC6BC902AD2FEC1144E1F009B64351E2486F9D144BEA0DFCE30A0AE2670A43A4311DE9A1AE77651E65107DDC22DD964E2CD86CDE6D93FD04F7A2245768B163FBA24554B2ED476A31D28864805C957E6AA4CB8E17A36EEAC614DD7DDBDE3E65F9F91072E459A6B6AFA60CC96C5E512F563B641297E5355F758EF0C8048231324CB9AA9315FE78EA1A9306907BBAEDBABCB1E6CF0C7054C2DA82F9B3DEA56A3F8550035FBE4618C01F7BECA085CCE8A0B61F4DB47E521B62C0C1A2E57D608B974A0597ED27FCBE7D97225B67DE6A6BBED4AB12E0FA5B23B0B445280FB4B1DAFCE2F7FBCAD405B58F73B1A6E7FCCA7A0B9ABB0622F136F5E1EB56ED541462D618ECD3CE6F94070E14A663ECDB68ADA26E482", - "sk": "34CF8D42A986CEB086B210D348C30F0DFE538760501F0FFDD2D235E615E5253DD1CF3728449166DE18D01AF13AB89C79E9FF693A38DF975F7817EEFDB3BDD311C6F76104B8BF45649DDF285DA5B0DD590A4F52C69DA871025C4845CBAD89317766C08E753AAB26E1596D77990656793263EBBE8303F0170C1DEA8D31BDF45173500685D2866052B60C5240621B9521888289504441D9202504948808356C22915083088423B0118482080AB42881B8011A4949244381824440D1241250A801D124425C040D5C0011C8260620B62140064E03C504019051D8C64D580024A022905C34210C148910336CD0306181C24023852CE4C05014956540024ACB8629A49005A20840E1A24553C85024992C01258C93C2209A02664324888C443299028E22256652124A0C894118C710E4364200852809453211404414A66999224220348E0A01869C440523094D8A92648BB60C649070E3024518314C1248814426001412715B362DC8B64580240820314AD9B26053B8289A442E9B44848CB049A3382C04498C5B40461BB9518884290136260880651C108A8C3651C032320216886224251CB8116186680B1461CA081259088A59420444222442A0600C39094C886D5C38504C30721C3081041891D4A8049AB08D8C3620E44442C8B4280C442C43A48DD81052CB14645820845CC021824649CA180A0025100AA32C1397014906041B296EC10226243605109429130388919671C006480004125398519C840DE21026209369A2005084164E41A608D1A649E3C469E1926C0C098911032E23924C84204203B15180B8019A80715A3252A2408011412D08C7719B108C581486088824A4886C1416601888459A988C5A30851A04461C3386580281440808D4303188240648428A1A102C933450E32801023406E24405A39650DB9424882006E2245120A1440C186DD1380120042C0A9749C906305218889226880BC78D6202090CA961CB4868D03480D0B03189868591026522953108053023038604859014266659828919420E144101893860E2102A0A288E10B4204C404259381011188AD11045CBA029DAA244003642138705038331E2280850420D94384C4C40894B12240C48818A320418820C21853109091104B1208CB60C8842891C1861C32840CB945060800C0C2810884209C11862192761991848E13848034886CB386E21B08DC2282119C564D9C4318326211A485249122E88422A0CB97091C42D90C00C81A66C9948029AC4101CC760D5A0943FC50ECC76C5E3BBE12B3777C398511FB8C3BBF1472B4A93003ACD253867C6B605316781DC6720DD064BD8FB864900F9FFE46E8570704B47E9D5A6E822DE39F2AFB7C401DDDF305F643F0F67D20E6D873CA22051F55E8F4B5D2CB58DE4866B7821761CB9B739715F2488FEE912A41455285D7BACD08A9F7C047975FB5321E50590A64A0F97741D19198E5702A119CD3A121369CA612ECFC6025BFF69D38DBD4DC73B17BD5E9B02F5592525FC32A0509D42BBE7C498408201B67117512C3C73E285C8006592A57DC7D231DD345C9868F76BE3C1F64E8B2B3A312441AC94CC805BE229BDD53A8FEC70D0958267C6524C4E21E27468B525BFF03F6EB31EFEC6320E266168717C46BD3FCA9D6130D99EEF3CEFA5036973346B514D2611E034CE7BE51D6B234731125BA27AE21E63F8F90DA49445431579397111B78528919BFE9512400F6372E76E2B741E60FE5D1DBDB05F088BA8702F15731988B451DD979E67531BAA49A0C3EFEF08BF8A90396C9F0649F88B37DEA5AF0EE488D703D8EBEAB262F367384CE63B02C5C98D6A541426754E6C1FB92C4E4092A23D31B2DB6194C4056B32AD88C886A8CB997529D32A2821D3AC8030531C02B82EC568F739FD817247407F06E222CEED6B53F1886D94FFA9BDDCA1714E649F4EE985D6B3B0E9DBDF8DFBF5D61CE9134F3F2F8C71DB0AFDF006ABDA46474F0E2DAED2D0631B107ED8F9BF7C9E7C1FB104306DBADFCF8EA3AE03AC6A4A6409839FC46EE6DEB7C23210583CE341CF5BD73F7F1EA61F24CCE3957C1C901F378C8E3C3E3555D8060176A268CA3CB8A9BC02CF0D2A09B963CE1A3B2CCE9C5D10DA86991D56097B8F5E0B5E1D4480C61CE329C67ACB4802CAE0D69053EBE30BAB6A56063E106EF136B535353DAA060FE5F54470CF33816B675C4DE6EF93034BAB55A295FE925C31EDC5547E7538A7FEF4624C4D763074B2E1EF55AF67994944125E69AB5D6149BA453F745BA4D9C5896FE3E09E1B89964F4F790611EBB47214AE0CF847F3F04EA2A7B827DACC4807E360F89AB09F5EFD39ADB63A608273262ACFE1509BC4F6D64291F1C55F0524BD9D103096A79282A92A5D9063E3A3429DEC83EBDAD180E9A766A2D5DCCF47E5CE633318BC491C9DC777128362669F221DE38A87893F3991239E5D634210060A85182E236B8C42E75A2E4F3CF86D3B4F4C1AF40834BF20FE30B708868DCCA8C91105A4A90652787A5CFD212ACA30E5D52433AFB523C9B9333BC834411A6B641616CEB4E63671894F02A7D8C806B45BDFC814FD59580FE0B903DAB7401EFC9F22A46B19210A21BBDEA61E36E59C664E5B13131A0F9158F4EA6C1D511C8807F4D84484CF5D42DF76916A17C95374EAA01BF78A617BB3BDCD5968AE10358726188D8B4956151270F38D9E8099F65F916844B1581D556D8CAD57BE3F4DB4E826CB0EA08091DE0A04EA6E22F581EF80B0AB2061015E4D076D55974BCDE373EC71D3C06B30443C45D7D8A20B27741669C45C2D50C78FDBE619CF4B73A1C39BF3E405360E52811558B92F5C967D7560E1885B52F5F9DFA8CDDB6CFEAE6C8877973DE446FBBFE92D3CF9EE72DF44D6F46F0D325F7B853AE1CF45A9D59FCCAC5CA51619CBA3BB43A9B37BFCACBA2502994C9B3CE6730C0B0780D41FB0CC0B1468E4151EFD0EF2F7B9777B1CF7334245D25F19AB27B2B403474BAF7ED21FA4989E5D11FC8983A5299039B0D539F1A16A935B1005C807CAF252FECCE675F413C1AA37620CC9A033416DC9EC88330B19EB3A2C72D8E10853742CC29560CCBD79DD0CD53899AACAFE61B0BAB975B2A41B4E94940089B7E56645D826D764A6D2EBC25741A96171CD82092369D5D883777F2DA6BE88B648F22E48EBBA07AF9A6CCBF5D12AB564F1BA87AF129BE62E9BDBC26560356D665B6BCFC0A4F0A3D526589331FF5E9319612288B1BC27101910F7DE014B4870153F2149712AC612B9F72419E4C11AF0BF32C8B72387BD81BEA4E797532B8C4940835C347295A160657717166CC57EABC188003D78B81FC81C22A1C04C386FA075927037B32C173F85B1B827C7012E291FF315BD9CA0E733510C49CA55F8B27B460074F3FB509713548A1A7FE238C39B710B4EC0D016962A74BD428F419184497B74F37910F060897201C072DFCE766DAC229F923CE33ABBAFCE57D1D5689A6E801903D75FC004A826280C10D7D5E12F0F15878E2FA82A442E3BCC527A3B9A3B7D11F2250D0EF7CEAD5A7DEED507975B555AB9E086036E1E1F5516B79763DD2F57585FEDBDE751C72BBB4BE09B653AA1D5C68B87BCA899EB3E160B66EB35CC19BF3D5229AD7122A0C9F231" - }, - { - "tcId": 23, - "deferred": false, - "seed": "CCA8DE2D58EDCB32ED7EA7F60926658AF64330AFC8398010232F9910DFBD85CC", - "pk": "F9D5C3CFFBAAE5CA0E0E3630C5C68025B3AB7B3ADFA544503FB8C5F64396FF244C128645896985C4B899BB730245354A7C77DB450EACC3DFA7D3BB3EB80401F2500382A95D400576F2EFC9339C2CE7F5635E04C764A9DC3FA214FF275A76015F03C3EC3C33B42F20180DFF8E1DCBFA2F9D1246E10C80D62C50F62F9903EC19D871CAA6087A76B091B6BC2AB8A7D7A68B37E535CB50C5CB90CC8FBECD6E943981566C4D619E3FA973E009144F085CBCED1074FE864D9CF562FBEAD83FB8367057D3C7AA17CDBF3DEE2E0191D904E0AFD850948054E60CA3371987239B1788C25349E37C6348A713FC0BEF6E28613704741B258B1102D33EBE513769E878999421F82A02BA0EAA98C64DFD35C7BA9E92203F58562E3A72FE2332F51681E927248E4DF1984D1919477B7206B2709BF67E3806C508838375C2ECCA7B59EC8D3FF0666BE56BE2C58F5CEC5530CE02F4C5A4302FBB48C87655DC717E8845C25D78C063E11FEA6ACBA8FB44E26AE15A002B072A8B9204F283A47BEC85629D2487ECBA65020B29095C2CD5A1CAD78157CB3390358D56BEA88417F2619A28F3BE37039E08D5AFE4AF5DF8035977D96240E86B7149FE275C1392FBCF336DC2859B40AF357C687447872E2B21890A629B59FF0B0324029C963FDAD39865A8D624F9796E3771F2562E85A193CF1C989FE42366B79B23FB14EA2B124F3A564C38406E126792C3D0E16C5B1A3F7908780513A2F41B1191950F7FF5CE0AC00ADF6B39FACD4C5C6DE7C3A7271CD3DE5FDFC1E7B1A87B14EC10E8C9E08D861340E8D32BD72575FA9AB69B6CB0945D60515282322DBE868C71C2F5AA797F13ED1E850EF671EC0E6812C3CC009556AE2E7940508B99C5A6423CE8B824C24C25A7BF9D7137935BE95401605EC60DDAC167187786C2088AEBE36A9563D33452266C074B418391EB1A61197C3D48D7C268CA58C7BDC2211BF3E4E783ABC76BAEB35B7B874908510748A85E6EEDE69E483C91CE2D3431A29133E5982EE3100094F7F8646A9182E58AA075F6565D2A3C52E8E95F1FC6B8472939C7EB26ED92C96A7213A3849E81D6CD90566DD3C74ED9A0CC5ABF67D6EF4C1D478A3CE21869D5CE44FE06552C014A9200553E4736250E3E35502CB8CADB7231F7D9D81A5A428B631C2272D0137DF177140B18C0658190C486344EE46A2B1D252736DA159C446A69652DEFAF455AA6AEF32760BCAE23E1DE86C16C77A3CA002CE938E45BD75921E69FFE60D4FBA80A65F50BE7A73670B2F0A050F6476BE5F166812B8183375FCBF3318C8D4C8097F21ECD1651ECECBEE56B4374E08A3D6EE94D244EC2FB685DA13C69F3CB961F0DC18BA1F1B5ADE394109A2D23757D2D704A3481185F30E7D193E463878BF21CF91460A82B4C5DCCAB6FB6491C1E77CC8713B1FB5E6B0F415913F984B717F00D7F5DE88EE310D5D3DAAFDF3BDA8F9C5B710CEEEA2ABA1E7DE3D923AFF883DEB41501A1FAEA0A3D47BE627600BA9D097688C98B8D6379083129B4E85C5475E924BC2D74E8BCC25CA57AF9BFA461302264584C470124AE33E73DFBC2AA1DA875D95458FC641792D0424ABF2CB76BD08CFDD55697331CFBFA16EFD5FD1F1D3F2CBB7A58BBAF23E5C715A637FBC0B6203C25A5516D074DB2C2CB89C9B3E7EE87294017D69CCF28B8CDC76425021C748DADF5953A93AAAD9429AA985C2D3A68455950B9E2542728D3272D25C7952DDE7024DBEAC49BA72760EE4252CBD40F1ECF48AD74CA320656351EF5C22831782BC260B042F9C0E103E501635DDE0CD8947459716658D34C4C8A09781B217EC2201057F9538D0235310209D26789F519FB5E605A21B97092B00B", - "sk": "F9D5C3CFFBAAE5CA0E0E3630C5C68025B3AB7B3ADFA544503FB8C5F64396FF2488BD265D6142AE32C61B844AE63FA741242CFD8502CE79547C31B6B17137F568CC17CE8EE384E104E052F66DE7A8A83C29A85FEE0639608AC3C3B54719460D311C92E32837508EE3DE3240CE74CB83D9C100A6402CF9BBA5B61F6FD4073654A0122990D80870D2B8801C4652898641A0963058346298928419220C600625C132441C0269D3306451226C03171142A465D4844141006DE1486823B3491C873163226A93347010A38121C725C83231A2C04514B72402B56054320244206DDAC44153382189806CD228468C8201D4A88DA1A265CC1848CB085221B485E28409D8A6300B476284340924C549A4062D130870090804C84821943460184204C0946D033232591886E38430C316114844724300664AC0240826250B19410423861CB02C0BC68CDA180609184C5C22455A240201214D402422D8C628E3C449033870D9066D6400301835840CA961112808D4B00564102C91286A60342A02374860A26C1A93089B406148C008E0428002B72401B00011C220A1480243B6405932468CC42061B88C82C610E32680039889D9308D5904010A932C1BC86823A90D24092103384DC8240E213008D92869A3348D9B06509AA004102265C3244C54140104170011050C890641230011C02464D2446E910402034086A116241B9410D242001C874542B824A032001B4626CC480ACA862D4BA68D0AA0500B446480302C1B824CCB882CDA426914B98C09010D5C0408E3268D08C6304994688CC49004306948B43080021002A18153800514354E21302ECBA88C11911004158490048189269092A26C21318D4CB64408B42558A061DC801189B23103A704241548A304480B1786C2C4698A248D1003848108050A054A03228224230DA02880212225034728990260443491C8120580307021372863C871C9082A9218128328610A858C08187181964C58406EA1242448403251326192A0504320900A20810B464DA09201D0247109136D24309009026A51C20508B220A4A66009A97162946519C664D998810CC60824902142100044985090C829124825C116694CC2290C042A9818489948840A41618C30418C921089C06D08326D09A75101224C1432469A9628D1089149284299224C1C452A9B364A14428A58206409A10C5C30460AA6241B032C12432683268051008892208C11C64140328500C99103C4314030091CA171DB080E182830C2A28001333AAE251458DABF79947B70FC6F01786875E7AAF7CD53625A4024C1F56989B53367E1D26C8737FF1BE2692B8EB4CDED688482DA39C89CD4446DA66065AEB1FF70BE9506322BCEDABCEE2939229D70228A665E666DAB61FBD49CF10F658889A910FBB35F9E36EE5A6180CEF522125C01BF577A0E07E15015BA420796791A53FF4FEB50550A562D32E383D05CCAC6CDB346A240EE00FD54236791A61D18AB3844E809C6F17CF7CC78F45E13A26C2A0FCDA30E77A131F02AEAF1A5D4D4A22BA808058A94A307E07D97CE5C627BBA7E10D52C4CE53C0866BBD224807D948676385F0A4717991185A37A4D4EB652B0B922B7B2A814036BAA7F60AC44A072687FD891FBDDE181BCCBAAB95642716347DF66928B37E291FE72BCCF43B6DC9248D51D461FEB43083C5E764FE12B31247F321307A3AE0C70376FA98A0FF6B4E046E28340B5FE9F9CAE7D87DB9634C97C0DB606522142E7FD42EBE2FD81638C84FF498C7C682DA4C49E723C39CD4AAC506A091319DD80C27934FDA672E7DF0370FB399ADF95C8371B05AEEF0835E0AB045845965E050C8CDB8D7A1A07D04E65ACB0EC08CD1C105D327CF2AE2872968456654481C1A9FA954217C6A318D72A43EA22ECE5E765E185BAFE650DD5F2B37CF6007AC9E7D3508D56EB969B9AA637164A6F9CCB02BDBD1F36A2D265A5E880871D5A1A1AC9A4A3ACF23C42495C5607475DD2E12855ADE46B2E82A94BA12CD4ED5F670926F47A4C91D033E58441DB64BD0338CBD623D03A6E95ADE4718A86815B7E078391237B0ADC075F200356A3CAF0A27F6954C6905547583875EEE63BC18E31A855B1338B991EAFC262DF85D6189B11CC44CD46422EDCD9FE939C5C7C67C47492C04A67B1E7BD790AE05AB0A23185616130F49FAC229DB1058DF1BC7E0D24057AA4FDD9CC75D7A1332D0C4ADAD6BB4C781508BA7A86E45B932FCDF39908DACCC208B649A74E110FA9E264856FA9C1458F29036B384A4C66602AB45DF54D630F3AAD3864F1DD1A93C0DEA21CDF6D18F41FB1F7AD7C5069F65ECA5531D0895BC9B336793794034E7F144ED23729F4E88150C3C79740133854D4C5BFD4DE141CCED820AD5E51A9C6A67B5484EC867C289F20ED3BF829CA39DE0E6BD876023625335803E88B02EE9ABE67FAAF4B7699DF3AB028A3B8208AC8603A9A4C915D40D9E968F9EA3EC5742F37AD4A22191B9AC9EBD0435CD571C9E3C9F389960A4225E5EF1B710840E86ECFCB754AA0E43DBAAAF713FCEB82E34C15F8BBAE1B3165FBE5EBB89C6DE51A78CD2D245A7B2120D9F3F399BAE67C601BCF45AB4EFE873F33A25B759EB1D9FE6BAEE9C64AAA65FEEF0931AC0A2BD6CB9C71A58E6DFD46760AA741E8BE8BE0CD00693319A9C8D515DBE5D6C2AF10DE65223D6481B56B8F29E5BB65DA25C6C7DE823700DF2634EE2B3FC862C461044524A64C3CDA3CAB95C06E289DA5A34C305B7469AE106CF6351DF49375814CC1FF5F782DD65B5AECCF0C3DB348F32293CA680912657AD2C4DDC4A68111DEB8CC62B1613A59D3D88B88E41E0FDA6741013C857BEAA61D9B4437D3B9FAD6F4FE3AB0C5EA4FF951C2EE9AC894565A07A27D97BCAAF451AA8D8A9B658850519B492FFC027FE3112B820EDBCF0EB337427A3E4C5D95A178E15BC704F21F5F5AA38A3057F55A7CE0E186A8F5F56009B5EB5753F33F5C7083158C98D797E5A0F907F10EEB2C9A22610538F6725FF158461716048ECECE1F73A098EE82DE3FBB05D17B4AD47C55FAD587880E01EB2C5EC42FB6070113F53AF383316AE2348BAEFC36C6A96BDB7CCF4FAC2B83A364A350C2687C6584886246F6C39C434889D28B694DB5182C353BD1442AE0148C18C9E35297D82E1782E9CF96F4A1CE8467C947B99C95E58A519FD005D7C0A937DEED2E54FCD95F9F56CD3206DDED6CA502F54BE7F27D8B3F192B1C1D1C5CCD7F4EC072C99DD43AE966CB7A192161797E5DB55FAD9555B65FFB9476782F834E3BC7B888841A4AB3A277064FF846B1E525E41F15F424D76907ABD8D69956E38B929DDB378A9A6144EB969745D9034DCB50B98325BA5EF3BEFE8CA06BF3993D80C1EDB8F109BFD30B599D41D74075722B766E8F63AC2B225CF07FDE46CF61031E0FE7699A4D0945D92D096169051BB61A125F37FAD5302D92AF00DED5A7DF80C6444A564F9C04514561C98C062E04A862FABC02772F9278138558E48E66F05A5A5A4FD5C6A08DB584F75C0915C60757E90F16FCD63A542C2BD0201CB71495869D1F01162049A661ECE29EAEB95E6484B430C7ED3301A87435A579F726A5514CE69DC346EDBA1376FB87CEBF0CCFD01504126438F37E29DBCC" - }, - { - "tcId": 24, - "deferred": false, - "seed": "7D80938B0E94C0C67513186B04F7E2A5CD3BBF9F3F47EE074B7FD6F74DB4F857", - "pk": "2A1414FF284FB46FCC0F38A48AE290BE1834688A53E4A841B23B3DCA32172A0CB1B1FA0FCF04EC7FE28F223C26CA4F1DC556B30FD7B206F69F50134AF7123BCA43000234EA3A7065E15880CCDEAA549CF2699E6C1492633AAAFFE4549B382B6C06FA08CBDE376F72C6257D17B0B57007FF5FDBC4012762ECF1E9667ACCA2EBC8DF142E7865861A5F653AB2EF87BA70A2B224A6FA780BCC8BCDC436F5768EB3557E8168445BB17E698B299ACCD8ED2EFBC6BBC83846FD4676CD6FED03593D16D1D482F6CF4D612A839B741873B1C595796A602A9C40A01316C89B5CA167D1CC587DC4772BD5026C5DFF68E8479594948ED931F774DC510C7AA218F2708AB4FFC46BB630C6AC267BAADEC685A6CAEDC27B5E42A4F3BEE7FFBE0DA3CA66B311761BD20BBBB15DB3F012AE57AEC6B2BEC1616FC897C4C22D124C69FF81BE4C275F45422EA12A137E475F1501102B5BE1C3D5F99D2A5730E2F98FCA507D3A91B8D56F3F3FBA7D19C66A7DC9EA93B43C29DA4071F1FFDA2DBDF74B2EF839F26A45F9A6B464DA3833DF5A823171B8809E220E76B96CB4E41DDC6BE7B645EF14A47B39E20D0896BD700BA4DC1411477C90E7C8D83C748022EC87590D946C4CC958B59494AA0D3C401F3DA28B0BEE31505E10B6AEC4C3E2C08AFD49236112F3827BD9BB37B1E94F408B8771525EB2621E04C25E7D26547FE00EBC1E0647FB465737F8776E92B378E2D486C8A3E222799F7017DD8052179E1C19853236D3FD69977C33BABB3A6E7ADC30DCEC686D323BC74E429C8780CFB35FDA7970297A2779C954C66DCF02B332010E90F6B91D1AFA2FBF55AA329CABFEC4141967D0B935A7AD132F845A1003C45855443A17B983B0254EDF514F82A0459AAD1AC5B5040EDBABB0632EC3A5E8EABA1BD7C06840CC63433B9AA5CCBD3293B6DDCAD1309A68D1AF613A59AB039BECDE97774FA0052915EC8689B5A090A6EF353104D9884BB4B7F74A4310D2FB66581E2C00480C6C0F1E923ADC96803FCC9E2C99B79663029573071456119AE65BACBB00EE99E079653BA5B3092DC7E4ACFF720FAAA5D6A9A7101454DCF755C2CC15AF4F256B5E8FEB26C698C29109678FF5A17F9FAF7414B6829C366545710F16E114C680FCE900B050F0F874EB29AD7F365ABF8ED0B1E4D31FAB1062A4787C65D4E0DBFADB04C78DA2F47BAFBA22C7E86B91E7D079BEA7FE69D26913F4742D8BCCBBEDCDDE93E93F5C15F9F260CD92FF8514AF36E111089A579207E0A86FFFC29BAC3B80E944D2054A91D32544636BF7F0110B400D5C13B94FEBEEB052DDA90C1CB8BE5095F1EC21A1DDCBBC5733EB89178DC5C3998C64BFE9E6CBC560CC76BF1783F6E0D018CCEA1B2ACF1D7FDADD44A8D3AC9673826FC168E2C099C144D33CB4A9804771FA8D5D5699AA4345AA6B56DF022D95D2F8A2768AE3EAABE346E0CF1BB1213BB4ABFF96614F524D1CFEA5C60872DCE1D4FDC80A30EAC2C72423DC781358037A9DA9696CDF5E7EA37C038BF44107EF2C22BEB958AE44F34C05A38D69B6CC345C80E743A2CE79805990A02939711E3BD20201EE06FFF039BC38E267AA9840ECDB121F4670AFF83033C1199FBDEA0DA08900C97FE05D0CEC1536EF05CB4C61A6C9ACDE3252F29FE04ABD05E1AE18666DBA373B3F0820C93162CFB209CFEC1362C0053C0964E622BF1F156E9189C54F69A0C5C8749FA9C703B4B7237E8FF5F72AFBC8ABF192B9FDF659E11039ABC816D18F15247820D9852CAEA70041D8DB16C564AEB78405C70E5A3BE4C30327E307B9AD99686F5E52D1834DF9C55529B99EE182D6CE91E7419D1345364FBCA7810EB0E6FCBFEBC10456B67E59DC", - "sk": "2A1414FF284FB46FCC0F38A48AE290BE1834688A53E4A841B23B3DCA32172A0CCBB81FCFC2235A32ED4CA1AEBD96C34D3CCC3A8A919D4E96AF879B3CBD48015CBF7B5C0FE804B106845AC34F7FC8B0FAAD1A6001601397893EC3A94B69A1F50FCCAEA41DB6543C8AA64AE5D312924024B3B826767F2B137E8F24CBBB69370C8311816008804D4C1610C19669624204C44480DA008E90226A8A0089E09231E046315432608C228082C20483280C1A244D8A886059106C1C4410D32652C4B2641C204C9A366523426E0143601A120E0A9588200822E2A49099C251E02450E2C888428888E20631092826498661DC184924428501889190488D0A256D50A641DC1425D4C6200A328E4408860B1965DC32681AC94143846D1395840C992193468A19B8415C3644D0284818A27001953014888509C60924484011308C1306229800110C037202954501A0410B392458269018A785DC4290210271CA1488610461C4882D00A31104B085E4220E9936469906010133305AB690C484510AC249983242E3C844A4028D0A174A998271181532118708D23664D0284A444691E1164502B069091106DC3481430030230485000304929080DB360AA2B63103886D2480640C4901221668A126488006219C30099148255BC26959484163066E8A162D9CC89122892D53C280429021422084DA008AC3324EC9162C1015715B92689444000C858CC996800C014161C00C5C841022B3496120092385059B949189462022C9048326318CC6290C99659A225101C66D420490D43460122382499449484610A1C22104824401114AC8068C5A948CD2B82CA1066012406959084D5C402E440425129665A42432990241D41820C4C62940342900036802126D91105260826DC84052D3400A59088852B0059AC060C226400A244920188008C40CCAC49163448218B5409B484951960C8C02901818325B024D9C4602D3B68014070ED1A86962408001274413362DE32650034046542290104364E21451443880CB266D1CA80421838C4B980959204C221921C4A268DB186501C85011279220B6200417418BC46C1A318D43A29108204021178612328A5AC8245180284B38719A408ACA30260819899A3666431664C34004C03070131788C2302DA3167282A6642238042013624C005049C88C62A4451146001C43825A9408A0C08111312891402C24092EC130910434214C286E8BB420041426114286C38889D4C82C4310022031655244454996690908423D4E7D0670BFAEB283C64B53E45D84F5A6AB4E596A7EFAB48F63982D92C41D5EB16136FB78EAF16E178A675BCF7366B38F61A0DE5488F28DC1628CE97F92474ED0A5220C092CAF7148574459269B09CF4DD51CEA4D47FC967934FF9E72046C247D3384BD0A1EDBDB2E9F500BD26DCC814EA2E662EBAC54276517FDAB8143E49DA25270791185F4C58D7930D56E24DE452EC09D2F702C4258C9D092B014C502009A5C9BA06047D4E1055BFEFD31CF8B48526C2415E9B7AAAE5C109448B1F3B9F778CD3E081864F885496C53D4BC9D89DC61C96AC0992B93F996E1E2B3CBD19BBBA7EE4C62D57EA8C67366D62671B8BACE3F8A5E5E0F6935B001DBFEC4C8395160F38FF99F19E5C73B10CD485A365E873B17987361AC9FA1A980A05E16780BA4CC72B031881A13AA3A2737465D17E28B7E7F78AF30E19D7C361755AE31F78B49478D24CA1220693D559380283D34F16C9003825E07A55EA050A72CE5576B9EA862507F556EEBB2F3C3EB6D37CA24411D8A0E041E1FEDF68B5A9F4754C42087A537C6ECC180D394EFBE4D68AE746B60F69C23E116AD1E53AA1402671ADDBE531D58F65C862659CCC7519160753E89FE0D8CD13965946AEB680ABC153EFC40786381202E7A2F9FD03A8FC83879C1DD11C7A36A40F9D887FE2EDEE83F345373C88EF751365C143AD427E517773CD69B035565B3BE7BE9C39192ACE33DACAD81A30B819C73E828D49CC025C7603A829F306405B87961AAB64AC270A027DD8C2AEE328B6C9B8343AC25BBEBFFE625ABDADFBEDD4693CE2B511D75AD5B67E02D9695C08F2E4473E1DB01D7B2FD3DD3E38E28AAAD3837C6DB3DE1D6D0C1A511B48A0FBCFE01F1739B7B54C50FE12D7860B1E6F12A30A126B6656625482C5395D682D087459DC1310A9E3830A22859E685B24A6F57E1DBC60C9E0B8C27AE92B39BE9ED4F4B6E6887ECE3116EB131AA7C5CEE57BD56C767AE88C78F921CB8424AC4F94762804E0E965B4A3512CB36524A3ABAF8C1AFF95B278A717AD31A85431C25DCECC6FF65E1F42816EFB5E773F5562082FFEA46C367527FC10B591C355AF9D9F29A41732B9206A2873BD551EA04E7EA00E36341EC942395A5FD7293C40A03C144250EEB20746D19BFCA7B2AA30283AC3BDF41ED84B3320B3E1B398F4FB669F6EC7E679B56FC7885E7D69D32D0FABEC6F24BEDFB9FD4A7FD90804ADD519FBE3771765F09D10E273D0FB43197A3215D8EDFDF6605FE0FC3597C7732B0A85AEC400CDF03D2919DAC7905BFCFB4294F682B28FD89921827ECC7FA0A3AAA2DBDBF7B447353329765C85F4FF169F7D661E05BBC151A50819C6A0A01BA09EE1D4580C0F5B06D352961F92D01D242CC33E0ABCC2958C6794A5A49B92AD4E0AC54F0C2CDAC09B8F06C2478F1DD506FD15A29779693F722A368F74A8880577A1470B7DAF91B8072097A8100B6A987F5C6C303810376B4382AAC2DBC29AA0E751F82DCBC88A71052B3E4A3C8DB44B7BAF2AAC864D801F5712F7E26B0BF07F7B8D4E76D4F43B113BEB5A7044BBDD6CA3D8900364E9A5848566A033355DC36C03A06731F58F3B1B5CAB7C80A31ED4730AE4607098092C21E4DEFA2F549988D45235738803DFAF6C58464DA5B6F951E4E28EB2C5CAC890393631A51872E1E741AE1B8E0B2B729A2A7B09BFBF38834A28CA33346A1C74A401A266CDB64BA1460BBF539AA37F3B49FFA35B796C3AFF079CD7533D92B4DF10331D9E37EB29B13134675BF4624D511FFAF336EE40192B8C181A221699E7DDD1E4E8751808831EA49D1FD827C85B2929D6CC8043D5ED9A3D51CD01DEBDEAD39CECF204EF7F946625250BC45C51DF7130598CDC501C3F96C44AFCF1CCD9A21FAF7EEEE6857D320064C64AB318BF2F652340CC5965D1FD19689E0FD5B973CA88A728F7F65876DE19EC5DA17B12D93567838ACDB25724EEA33464C16B164AF4ED4A7CCFBD5BDF2E2B09435553D85981790797AB8F28A250DA12094A3855D6F0582557D102EE5C12D26D78630EE9494815E1AB766E991C67BBBFBD8230F98E4D94828DE2B071E5CB3FD97950448B845C00821E8F7266B429E9CC28958452FED371B8A1BB86D873B54D8C4771F1C671D5BA0689C1F02E51830276A2010FA34BB12EAEC927ED01E815A83109F5E325C0B71A539835393CF8CDD3FB1E7544748F87A0266EA56D8EC96D2F08D7CB51C930600A9CA7550879EEBECAD44BE65FB99C550887C4D338B5E465C89DA83BE02052F151FEE499CCFDC313A98DBFCEDAA1D3843F3F54A29CCD57802032DAEF35FB318F592C08397FBC2F8C94E1616676FA17D3A544AFE1B5260C04BFEF15C8A22F8CFD77CC26A483E" - }, - { - "tcId": 25, - "deferred": false, - "seed": "CD52A8ED3FCAF1F0D0DFB7394D3ADF9DF810203199E62356E56B7217F786B29B", - "pk": "8F02456FA5266891FD000117992C1F8E6ED9A3415B7A48A478858302C379C4DE3A3B33F4715C1B228160A25FFFC7E5F451D166EE93D7AF6F3646B50E0E87196E352A22566DA11E9479B50B05343E202D4A8117AEAC5D7126A1E60D20EF0C3119562594EDB8B3AC853F995C64C84F965B415CC57E39310CFE8A2129BA5EA09765A5790F92B7AFF0B1BD92DCA72E224F034B5023787C183AF0947F33F57E4BD856B94B223136DB7F29104C39DDCBD3761414C9D7088301DC30080E68D02444C7D249545A2F2E89A01F7282B1885F658D3AC6D075ED83D43341B7921D3CFCB0F8BBDE671788451ED02E0147221637311AF653D9266BC8F653CEE8775711ABD0691978B298D2F972376A270E969B97538C379E4AE9B920876EFD22548F13917E524211F32AC670EEE163498D18A5CEE0373645F926321D8BF4BB75A05FCEC36613C15BD9BDB332561994492E5584A5050240665E5CB9E3F2E34D39047F30E15D63D99F084F7E04C0297C37C0C5FB93557298FEAD1F1D64AE73A4118DF853807BA43D94471BE77C8BAD8A08A1E4E206C5311CBD87FD763D07229137C961F6E05F3224686F1E468F124B74041CEF75D0818BE1B9C3E5EE11385225D2F4844A33F4E9388E477CB583E2745DAA1EE7FF4E4D32D8DAAAA90D8F6C37B293926B73FDA2B850DA5809B94E265572F5EBD38F0829A7A32D3A35AA7824AE0B513B25B27DF4311B09998816534C1C2131B90A7189A7A65EB50BBCC6DB352999C1785BB713D901F214C0B4DD6DF7867C7994FC7BD3BD71CC4BB64307B30A79B176C386EDD40C0DCA724CCF51B5042D0DC046DFA81205BF2AA6832E8CE56D6A8BB50078D04F234C3535DEF4E08ADAE1C35E25A8BB51A22509FE412662E3F28122FB7EC5AF8C400C4541CA8E532D8A83F295E3BFD12DD8D954EE47DEFBB5CF2ED53629D532A405D25F4E32F8678AEC96DA81ED79027CCDE34FA4514BEFA6E58F9498DC9FA7B7A091CA69587E4D250271D39013FD8F25CEA402C34E7FD5A2DA47B232D85455C12F7526E0B2B6CFDE7EE245BA9C402965D042C49807D5BCB2EE0E616CD66B7E189324532C2C4E1D3A9366C08F44EC8A63E7C535DE0D7AD5B1DF77E7028EFDCDF6EC2B5D2042F0BC62564F71BFEEF3FFCB21EDBCD64F6D3FE805002F0A4DEE90B7D81085C28D762B7DF72018C70E6C4E7E46C64AC984FB4A18D318BC275D3D145230C78C5DE27AE20A75678C184E051624C64765445016C8637D8E11A21E8062226AB9994F0036F5C658AFE744081EA051EEE6B3F25AF1ACE9F6461A3ED133213F341E58A2CAA3F3165872A961533F7906B967B85B79C24BA5152CE9AA1EE710B58B510E89BA860F6653BD307A2E169BC83C556C978DC420FD5A303D3939AD5C76B2311FB4D689AF7AF7704773CFEC0112462A44BA31BAACA36319C5092FD9262D36721846BD9E1C5F4F6540AF165843ADE58DB3498F65BE4C5849AF5867B8F60B54D8ED92176FE82AE83439C874C06A8DD487AF54673F1B97F44420821DE6761E02B6E2BA79DDE743722ADF634D7EFCDE5D5931C1E255293D64C4B3DAAFC420D28819E9ADF7617B6FCCC3AF3EE5F0BB765194A6E4E73182A8422E25C28458063A5E0625595C95D4DAEF94A98848E5042CF6EC7448D81956FB91FAF6EBE7C2040B9C509F6CB7AD5B573ECF184BA92C06D4DA0F68F564EC4DBCC029B08517F233FB6EADD7C0B06AC7E7E6C4287DD26837E65ADB668A30F69DFB15D50B4EB7324071EA9664954A23E94B6D0D2759B78941ADFA1786188A1D23104303199AF735F3508DB1A59070966F0694025C4F72306AB813E925C658CE8358609E119850B16390490EB1", - "sk": "8F02456FA5266891FD000117992C1F8E6ED9A3415B7A48A478858302C379C4DEDB8B14F36094926DAE586A7D31F7EBDAC45D7BA30C05C997B1C7F16E327E30FE4ACD9CB1F9621B83991AC2847F9BEE656DA1E6E2DE20E3E14BA58B032FF45A6B5DBF1C515C9A36F13638CC94C7F2B7850F2C95101CED9F0D267BCCF4469CC95EE12812C2C261D1324290B2280C341009204DE2281180922C8246040A148994324944C02D52A824E3A071201248DAA02801A14993968C0C460D591421632031E432480C15500CC34414C588DBA83053C411DBB600C3C82541128DD0362664385143A42580060A0045311AC90018080840B444823260CC84091204450B88651C4644D4180D20414CE3902180104C0AA88108868461B06918347219354112A948C2128159402D9B9841123430103984E1069018446AA22229CC2680A2106102420E81462A41189263248010A809140442D8802001A10942140462342240A891128209C488718C966C1188244A34851A38510BA104432429E01670801490CAA4455C440104318E98C0851B8305C0B848032491DBC44944148613444104B96423394C98146E1044291A0029C2205000B540D9866599460E93240DD8120E213250434460213030508229CB1609C30021813201CB446113A5889922725992600394500BA02890100ADC321081A2414CB6618226618B0241E32652C8265018308E0CC96C1B03041918495A183119B389D2066A99280E08264143C809A2344D002705DB088990884404372DA3B44D0C89419CA41063064513B07009342C53A28D81B2911A81284C181261387223C14CC034520A406092182014064E84220D0C142852B8850829898C3625A21881489449D23246D2006D19C88014498A1C4146A138251185859B424D12032999284923971154208223420A40B4608B8028141889E2088CC1B64523A1312038011399899C28204928701101481A49254A24810C8164D2983023016E49A61008A18C1BA3691009001C206A19313020B66110302D0C860D81429008058A24A40110C529E00251C386405B4461D0A40D02B288E3B88540C05159020EA4389009284C14998C83200102374800434D51B2241B022904C248118688082128611480002421C89068141126D8A44C114720A3328A4200920C1148CB40848A86708CC48114280953C26C04284CC9222E1C4044E4B81020064008364ACA4841C9029220428DA3306A22112A43A890C3B24C01426E1341690286642338086D493E042528BE94F6031DB0767E76297C47022819855114386CF4DB2FDE01D20A02BF72D6FD241E69D4E2CDC853ADEB7E3BE0579C7935A49799A2F470375C9C1032A5BAFBB23E6C3B578A0A0568185C073D1A786846C547F3D229BD6B6627A9D0937E8D5C16E661F0F57160AB89CEB89956E67938AF286EAD65B398D3184E41613F1FAAE14703ADA37E76FF5EFCA5BF5FD13564ED42E4FA6890B15D13CA9514CDF1AF816E63E28E4604E500CC55EFBC01512B9CD3D0529FCB80E17D3ADB8D61A2045B44EBD82B4EDFAD53281B3C43A22B2C2B48675AB94656ACB842EC18A45892B7E9E7C88A641218CA9D59633C451B45C561A838CED0BE3B683225C03BD1A8BF3E3551B2E1EC4F0E8CE6B019339A3F3F8FB8513F4AC9AFB2D09FF438160E786F28F6521AACDB1EEFF18303D711B9CD1BBDE1AB39FEEC90C97B39234A9A01F8D83DF69718AEA9C4BF308EA01ECA7175021919D1C9F9170EA25DF51C5175E0E3254E0722CDAEBC4C0A8D39A00497FFB2BA4EE08CD6C032657AFC914176D3C22B55EEDBDC83830522915D2F2F6D0C5067F25248623D8E359570E0410E071ED54E17E366DB5409B62B567BFD267669DDC532BB70A53D27F4FFAFF51A27F8836C744AC96CE0D0EA469DDFEDC360A8D53CDFA474B7B64A5691B245647B843190FF3CEEA9E8FCC8ADDB4DF38E45E0C1F6E1BE1479517E31FAAFF8AA745C90F75C3E36EC728EE82CECD125A05265D4DBA8EFF9CCABA4C38E8AE02F1B7C4F784A6360BBA4715408BB6B8B44964DBC692594395E386F23F717A1DF7F4CF9CF1B5B3992DBE21CEF3152BBE1DD77B60AD7AC235A1CF24132461E7AA1D72586881043501F52FA8CCC4F0D6A1814B789876185BE2FE5F067E62D93343F8EC977937D1E100E48C21FD60080A568E8F6D954B98D8E9D8754517C79DF0AF61BB09426FEC169F1C4A8418EF53E343EF9C410078A395AB98252BB5A3CDDB79AE26BF92B1AF47EDA3FADA7D422ACBCE2EB4A40BE6FD1A5BC2C1D90A0F0F9F09BD5358685FBB5ECF7189E4DD9B427EC152C4B1A2C0D4A33131CD0326EE8A1A884F910869BD60571EBFB7214546C015444998396EE4C216C99CB7E84278582D0029E499791DC03829AD2990132B24F8EDADEE09B38B4D3701EF228FBAABF19B5744E47AC933ECAD85BAC10B49F6BA0A1B16821CE8C5791978AB14B1B0C2FD3E44B43F3DB49A5B63DC1D16D74E94FF111088F3BEFABEAF1CB5D1BD86147CAB37B068F6D99C5E86D178D6A860586FF97ECAE105D1103C0FB6A860CD17D6DEDE0B02AA943536A5EAE551D5AAAEFB4FA950118998C8080121F4B411ED3C29ED90197643DAB10BC1BD51B2350ABD71132FD23A64158DF8F9E064E6642A2DD76313D477DF17F1923FD394F95199AFE19423091183DF668666BABA8334312B670D240D5EF0D1B3A8A197539A3C5FE7F16B88C7911ED0FB35F48FED2A8DE84F4E75F6116849362C05B2F03A885C1A3838C78714FD37E3A0625FDA5C0D5D77E4FDABF3EE38BA993326E3505657A160FE8287B8CEE808687FF15B897CFAE347584515E2D78932740C82FBF42214E34BFE29DDD842CE89E1E775769A302B84FD839D68F595BE46A30F7AB09F35A5B8AEB43428C1453F71DC01A0C202E092F125ECBD2E9BAB434675E7CC21073530FE1FB63FD48BCE72A017DCE1856E26F33B040B16CFC2ACA88E3D0EF89BC9CA83E1CE78431BD6FF547866A9DE18E12C5E82C3DB4603D43318CF9A0AF5C10983097CD7F5005576F5BDDCD9F3E828636CF898CF54916AFB4B787B199FBA2454D9B57BF7C92341D2690F799DD3DCA7E5A9DF3317B51C8D503007EC5A234748E8AB670E6D9A2D98A53FE26FA6A653CC373BFAFAD1015AEA7CB952692443BF04AFAE3CBF6FD9DA5190BBE02D3AAE57FA0D986FE596E0F72F4E04CA7D7C508778C7FE7F8E3D2117D1ACA8304D99D3C404692591BFB48519A8F7F74F583BC11400A1B40D8E7441CC7DA6669909A79760A1E381FB6838A81460F4493E0769779D38287AE5BCA0834FBD21D7C1AFC421901A05550D8524B37745FABFADEFF0B6B3E5B342E975077A4B8F11FA1F60A22C6A59A61443FEF3B17BACFDD29AD2E6D3A8563E6BD8F33B9B041BED520DA17844BB4AFE9EECA45464D931013ED46B428C0ED5E705DCA043345BEE4612E7E9EA1C82FA41D9732A40DE8630250FB578312B546366E64739CE06B9C7A56FE76620D3A295F66B5CA2C378B54D2F2FDC9D57A5AAB3EAF2EDE57A76033670BF5D96BCCA0A4D0D4EA27F1290A316039B57231570B3504D3C4381BF89C15E2E74005F6D643D7BCD9B9D8250D9DCFE470292B36F37DD077853B5266" - } - ] - }, - { - "tgId": 2, - "testType": "AFT", - "parameterSet": "ML-DSA-65", - "tests": [ - { - "tcId": 26, - "deferred": false, - "seed": "70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C", - "pk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CBB111923F194A7CC8A7BB2EBC5C0E71AA637CC800E6103B850A539B2A39E1B6D713E5DB8314C9AE1F8BF8A38F06AFB9D73B161B0FFE3A4891706AE26D54FFB496DF8DC0F1983509500C9ABBD28E59B3FCDABBDADABD45EC31499378BDE849E7C1F19B7044D67E05106D7136D95380D5605D4465D877557065DF0A75D3C28542F40FEED42EC7E280637B083D988BCA5F6394E02396C4676184FB63318DAFAF5BBDDE00E308FE84019C2340A3F3E1C0865624970711283356AE14BD6B94D1C9AE188DE1A8A2CA824A8EAE2FE6AFB38D83A2D99996AB21FE3E84C0BE6B6DA08879B677374FA7C691B13D40FA9D4CC26B2288D5A8C9A43724381004D61B0D57FF400314C8E30EE796AF10F7EE21BF13D08180465ABC72EDDB080C6A07184E3EEDC47C19AA7F09D1F3309E183A2BD9B0573DDE474A81BA4F78D0C523D0C04F90060FD571A35C037E079C5E210D7390DF568F2E2F03CE44420C82F3FE69EB9B48EE90962D6B0F24440648F71EDB241EE6566FC1A64CABF66BE6FECBCB1387C82A7BC202D9E367998E2A291AF0CD1570677FE8D63A3285A2EA6EB29AF9DC1AEC1C36C4706B12BAA20839692F286A6E0321468F7479345C4D52FBDB2F06725B554B89E2492612681ACEBC6C7BADA9225818DBC35D64C22C48BFF80A730D0716DFAC99DFD5B8992611D0C93EE90BDB260022AFE25D913E06EFFB59CB1F8A60CBFA5AB2F459A16F467E989525E0A37EBE56E833FDE55DB9D1530ADCF45846DF281E47CAA1E0A27EFDE2107D354CEA0F6A454692F04CD838EBDD46E191E5D9C11839A2C3F488A4FC7CD265A7B5D32B08CBDBFAB9D2CCD76222C8EE37DDCBD2AA063ED861473A6454CAEA377850B1A2B9DDBBCB374FAB5B12F351C8E5888872E5CD1F60A4FAE1FF837D192C22BEB41EE6FA392FCDF4550FF46B5CE906D017EF3077DF132300D8BBFA9BB03C75E79E2F04C284AD06A44399649C3E2A2A8D1EFE9B7A4E0C271047AB75908BFF7DF9E30ECA547745BAE23A86FF9A8B58C2538B88B866401076902DC5F0BD761687B49EAFE36D350CBEDFDD36C121CF23786BFCF7E47076496EAB6BBDA774049C2EBABE2DE99C4C24F2DB73684015B373977496760CF9AC23D8B623133DB2DE10D73FA6AD1C6DAC8434F28C6E251CE7293CFF3F3B61EFCB5A435123670F29846A13DF3EE712604461F1BAB8F4EBC836DE058978AE734396A98081B35CC98188A86949C99270D4709854C5B35B17F48A373134C814CC8A0F3E2FA807F2A918530907864778282D75E03A41B2504EED816A417A3AC6BA16080C39B7310192002A728F7F20395009A9E16767CE1971F5DE7D229A50613369E4382045A8E81901F4DBA8102F3D413FE35B326A874F233B719A7137600D35D33AEB6B7259624083AA968730C8F78292AD28F14EEABE660835984FE69EF23DEC8C327C0EB0B882D587E1EC433DA85C9FD1E0A34994DEA240C854452D18C30F496E49EC904B602E0F5062EDCDA03280A53B4313574CC2C0D5471BC9613BDFD6641F5BD127BAB5B5EB3D499A33114048220E819F8EE12CA922C8F17D9C9F51AD5BD6883B10E6AA2483BA49DC547DA7686151344F4E9099B38E430B5226B059832CF03DB48FB02DBA4E61593DC4576360491890E53EC0E6AC73CF32B25D823B38456E286505A541E5AEEE96B1914F5F76687CE2B0160227ABED77993594BCD831366206D75714082F1C46F1F4439AC81A57AF31C81C555307A070FFA94E0479B784BBD88A60CD4C7CFD94E6AFE02F6B21F72AF0DCD6609D40C965C14E5F2389183E53DE930F7DE1D44215CF49144844E8B87F78A7F132AEFE22BE80B4E3A05EE3A68CCF609EF44047402E4493046E6F9C767FF8A75E28B3CE077FDE7E7EED313B5BF7E460127CA8182E9BC794C0DFA730FB920080575A751B5CAEC85A109B4422BA266743F0D032BDA8F1CA6248CDB917530DF1302A5F8C18DC642D52478C98C12A3F16EF2B62B4F59EA1BB58DE7B65B3C7153CE6DA5E4950746F80E087A0E3586D097791BF36DEF865D68591D39D0903773EEA962147F34704138B54DF7924CDD8C333DB5E1A409CCB2B34E2C3C8C7FDD3FD8D012CBF382AAA85E83A12F235A2D147D035B7B28B34B6F57949F322482A7D4D3B15045C420D5ADDC7F0E69B4DC1CBA58B01D872480B06A260D827D891B13C4C5CA50C748DE3C771BE61E9AA170165CB01F4BF5DA27A7791D3AD3F6267B4CB4E61B28FA1708418D932DFC4161880C5D3B17A9663A9061FA8F1804315850FE4E7306C882B38227E867F80872CDC1944D472615EA4900EF7D270B881D4130F56C5CC980D92A47ADA6657EB6F37A385D2D8CC993E1442EB05281853636991E34AADC68954D04E7ADEF76BF880F059B0CBB55D915A4B123E2F1339A073CBFBC409BEFF6400AE096D5AE18EC42CFFAD5B4980FA35BF03413ADB5D7E6876AC355D1C9ED70CA2B973954D12B3CDD76AC6835DB96003ED8C4E288B71FD77DBAA7635720E12AE0A317DE808C664E317F55275791F3245CA4FE5D4D41077FC150A6E403D5A208E46EADBE8F2CFB8AF472F4A0CEAC015219478E6B86C958CF86525B7485C1734C7EF00E90683FFF5DBD0A7D413A855021026A1B32013A4616CBCD3700ACBC705BE3EFBA625C69A025267BCE9D135E3F5B5CC8C43956407E84B6663103E29C242035551AE797F56C6374BE0C798C0CF398F1ED", - "sk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CE38D1C14F6467C35A9F380D27DE61F7C75031569EA2EC8260EEE9105261B7FE160C91344B0C6764C204E5B8D424650BEC06B9E2E625AF07E23F4950CA24FB4D6EC2C8B3A717C9311EB87279FE25E311F48B8256501F6463412B50DBC89A869BA2241112648400738730212442544575483725033356258423201621183610245665648356120845260685045655512724747212125402221428117650306426152134325243382121135623332074786223150837084264345645148311486246686743371366726014707721161588558387183806701657870647785600288534846622583548804744012574371077544387121142208887223588746148553716773822822741403577328718380781434875207647401607561060861322146156542670820841073130361028650452612166833552584735354526517106000385777812426804146432667410603554128333725230677821516317300087526584634638808846451112405321011181864782241003855754210468343733880078343787413576232688065864853483551585074460588700772013100875488142084166115605685115808058863018286131417220168171786585310622852822615043142885431780580115045688233663636406515244767064536422686750635413347851217808387655142313887566205174085281417213812608124414575018287101002132557042172427861117005304772132030216744315771455710541665741524024371512055116783678252533566424613702232740007068187175780286801721004275522864253158176308640831143305382735303723568704541157314123164326663562151508210302338172127102314227577283771627506887214187313030150715862866288868603270146172271385381703388681378810486573016523140830756821032312850065081630675766511601417121255564811411328826207476424482324775326081758115637483551478685666681732021367522746683445700666477204722285687124702480702542301257137367536005268153335820613732408717615224260185343116457761761566876606554781033631421832160155580423842031312343625273082812547513544126735001001838574424013036127812626811887435120627127515610222281118141666638208675561240065461127440345858781007852572885722222550840041260836462878467805022820771360751443687864313877737355412700540708286880045383432281006435486766501775761275438162403343453887216614704841431466587845820225457315213203024880801371255432720568652468040616835054533737272220680825508472867422361680075518121784448115645071105815511010471621075861187800527264521743234076486730776364875131638468745363842354661048363385214842038251103357468016433402070353221275733465833387438517503660880258758088316360182132261568741110331413053416726535501334808710264868845271442358803557705484287055888683862521827261177885176773005771117851106563570287401340012653451205467518807033356622620070232687726311133333814170622861514731302546511761580741613737061400548877756777665316726666887643583104875706764700436358605203442736486123721610624208608323540355557300610365342714158662558016531018261135468246132583477050060156021168545303687336418886334252015833423288568177555148481201581385041471835707545554552827313602123268321382587028585344867273428418220883610214161712415748852510260736761266172132360325411011226660161632642605186351585131425384566627833354507646508025434157357825430282384745701567517747803152750000947BCA93C27D584E2C66EAC9C7640C1CA217EEF66DABBCB260B4C34300FA051357820F57392544982FD11057DE233E6D2DD84972A7E47D4DBA99BC30CF8F2AD5A2C0243195ED2730FFA92D227D153095972D4B3447FFAC45A23EB41CBC87CDD1250A8A478B0F7A1D5B39AA2206E48645584FE7BF7A13168F482765E57BB924AC6D9A11369F4A6AFFCD169B7D75129B35D5134A31761BB8355AEEED27E201A06313013E307A01A73AEA7955C0578C8C5E5A1A2D2FA4593FACD904C62040BDB9F329933536BF8D81C4256BAAE8723FD4DC66BB5E7F9CA49031A193ECECBB5DC390EC6D5513C79A052B3FD43612FB7375315D8091F79BAB1318F17854561BC93AE0E5CD6D131E562C8114810C939AE563AA10B47CE4484317F34ABD02D0CCAD58DD29BCF657BBD9254B01CA9726091938ED32054B37DD617240F4434C1A4A8711AA3A399A8A5388330B7059ECCBB6B1B9CF7187ADF10B0C9171D3C0F6E2D460A419247672E3B9FEA2C95910BF2FB6A5D61F257453B07AFB64B0BA2758BCD735751F2D53515E236FE8A5B4393B80BF06DF97BDC6380087E6AA8DDE6E098111A7343FCDD1E903708E637EBF28323CDA6B9405810EDCFB3691149ECF224C50F8DF92A94AA4770A0E91466194BB0E27BF1CABF16ADFD351220033F76F5925557BCF9634E9461359621D80B4BBAD7E2A6E432DC43B126CA42AB88AA88F0A84AF58029C99A0248F0C454071F35B831FED1254D6F4E2720485786215F7C7F0C4ED15FA853CD3AA07259B39240A82135C2923A72B876FABB3F0F2C09613DE39D459A07C14E7BA437D8041491FCEC1433404BAD1DA9EE9471E17CB691B2A353710C9FFA4E5178112027764EB7DE809C3E1F1FA4178A5D4DC9EE27857EFF26B91711FC144D5A775B8B50D5DB939BA3207680C242FC821947F934C8DAEE203563D28606BE624A32901932DAE85712AF6C8016026927E9B8129574BE3CB1E95332B052707AC8AA8F435E88B7E568D4987C6AC0E902B0609A02D91B3F5FD3FD901DDD0DB9873BD7C71ED921D4577A78C4FCC9BF075203D38F5E76E74F277484E057B6189004131B0C9B1A155294D1CD3D5208E266901D7D314FACCE7E2AA584583A11E4D7C21B94A32E508EDDBBD7A65AA86B4FDFA6BC285D4CFF53926C7173FBE1F89CC303234B878C6B8101F58AC8D3E5E1BF5AB6B26297CC97B95954AABDB25BE008A3F47E56487B00D3DEDA890D92C83957FEAC6B8291AF65959E1D1FCA3BD196E9FC9E67E0607094822E5B4191DB96824B9F03F2EF57F5238BA7E1E84ED55B7DFF3D6C2C1273692A9A19272166130DB89FC67DC94DB614E3E82BA3A3512B012D51FB486B5A3150B78E724E2A12DE07D8671FBA2DA7FD5D147208FC3AF653E6520FC40871AF2177E65CBD0EAF304217B367A665F224CAEDFE93006AC1E14BCD67A88D171F3D8F3E358A71926BA3E5C239A531263EC9437BF2A033B8B55B2C0CB6E7E97316E22DF77CAD910D20EECE1C50910A5CC32ADAB09377550F92D5BB1F4C07F4A2822338E2CFF5348DF77CF8EF8E6657DED1E0CE058E3CCFBF39B3F166E303D33C3556C9AC8ECB3DF7C74AB36D0F2794441BA9808827B578FB5C29E494E21539AD3AB2B41BF161D7F69589D4524C54C89B486F75D252F541CC63B9E706D64A1289A2306C595363CB6FBEF0A1B5B17AB5B1794BF27036F64EAF0BD430DD58D80010CCDADA4A5A3A1E41A6FBF129D73779A37AE5C8D6841A9993C51E364E04FAC8E25A4E6872F6C860FA265C1C4426AD9C21D26DA8C278546ADCD831F2B8B26D4E1F670623D95C8362DA662D1FF0AB687503F328DE095810EDE12B49EAD1533519558C1E940B46E4EDB027BE9DA2039B25DCF7357E19E5416AE268C14FB3A8BABCB3D23F70CC9D59681C5D833AC22E653D86E22CE822540755D8D243C15213D076C6B26436DDC07C7E001347B0CB8783DFEFEDF275FEC4792686734007F0FF8540811C2AFE6CA151420532FA5526A1074C3D789F2932DE42E3ACFBF94760F426D96CF033FA49E2F458F9A9C2E71DACFE009DD9C3F3C8AB3282D6F383B981C82D6364F0E4BDB2AF6A95BA61F474150CAD7233F8903DF972DBB0328C0CB9D0CCBEF883D2E6ADD180ECA1B662FC1D2DBBDDB3634219E1EFF38B1E52875356C03EADE942055F483504BBBCB4302A417CF6D328ED793B1A3C0969B7B3418F50AB39F83C5666C90E38356F7F9D494A6DCB63D67C34E3D14A4E15596497926C8568D8EC3DBD9C2E82C385BCFB8D9674863BD4FBF1757DB447BF804AE950147C91FBF9AA17891044CCAA73B45528597462CED751D015EBBA9E2B7CDCBE6DC05AA9EAE0C86848A3475BB1C5744F5903EE4A842A469CC181271F245AD70D02A4837863B296B4ADB4E8D03D82B64AA11DD31CDF21EDF1DFE3276C4DBC877E35B15FB2835EC3A1C453168A38CA8E563CF3E9A00736CD5CFBD2841D10F94AD55799C2927E5461B28BAC5174D0CE3F8F7CD7609FBC8DA0C38CC21695CEDAD12F8D2E64951A8996E510D6D52797C5BA0EB4AFA6BF2CC43DA09DE3179E899BD7188B32A98A499D372F3707CED479B0981CB50C0C0539CF7E3100B720E466652A4F499C2BA3A17F5232268730B962BC572C0DE96E8C9E28F7E3532C2224196AA9E27688DD050D7CB7854FB3C35F9C62EFB10DA84833F29BB1BE5EF3B533638EEF743D8119DDC290BDF08B6F0F9E4E1E13446C53ED69805DA26908A15DF1C48E009EC1253BD5A5898EBB5121CC24904C8B10E24E680E565985076FDA11D13FFDFA4DB28AC9F0AEA2F81FD7ED4DCA8D3B2E3848B4D6046F6E0DE3A4F683F25E0605E84B36F483C404EF899CB3FCCBE8CB2A6F0A7E10B1948CD4F93F181555F661D31D426808BBF9F66FD60D649269CA3FE991B22428C37AD2A08680F747CC0360CCD373DC6A9F43A66470E014E72B3D8C38E020442D8AAB974E6049374145B04CB7F3044AAC1EFDAB2A18BB464D4F2F2D8143974C95EEE856D59EC00288ED43FF5CC8803006C995514A2CC9CA622B61BCD75EC51C202A917105B4A4BED1B80146831DCED07EFD2ED25739F54096911B150D3077CCD731A0361682725D53803F8FCEAA83919291EDB4493EC84CCE1D0F82A679236EAD1002AE8018CAC9FDBD246FF093D803C0DE3326A57907B0DD6B01D081458C75728C600829928890A56AAAFEFCF7423B70A6D86B415B8358DD044ABEE00B9C9795FC8F61A64686DF5F876A8F33061599AE830F7EB4C4BFF875F4A936C403C5D160DE5D33CAEE40FB718DDA4478AC6F51C59C2155254BD77671118411E2609D000306FC9507004A31E8957EA40C2564B83C3ABB71A87C11BD18D7891C449DBBE79B4A4FB048307CE0E812B2C68ECAB77FD1111526AB0817306CEBCB0497C552431CE15E4AB52283F679480D69DDDE1F2579CFDBE0BCA95FC5B2DB0C5CC76A31950F5116AAE5F02D46710E4257A75FDEDF2F47CE37C203E7F24D3C9179713C5D807C296149A75CCB444F0C6F6ABDD2DBB2985FE267482858A1E" - }, - { - "tcId": 27, - "deferred": false, - "seed": "4B4B71C5A1BC1074F2167A1D68729CDB9E16ABA3651FF02A0A0F4C883CAAC827", - "pk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B270474C81AA0D8F45C0E8B5D02751E797D101904586782EA09F4E3A567C2BF5146DFBE766BCF8D0E4EF46016C6ED7B167490FD2F8E9C53CB42660331B1B62810D21477F5C9301D6D054FB076E77F35C1942AAE874669E0957A031223861EB563AD723781105567445B5422B179E4828A4306079C4D42B793A1358B05D02D4565E4AFA2D1CD32B6E7A4224D3A86E8AB79E1DC33A11D99411636F939C3AD0D39351CD057FC6BDB32ECA7427CA0842F70B416DB14518796F68C66E3CD04720DA02B32A3430E0E027F48974602EBAAED0F1FB5763A914CD6DB7C4ECDFBE076B0348DA1AE1F67C63EACA5DD8C27AD54900779952239539DFEA22BE70D54661BFD973D1342F71F6A97CE798EFFF852FD789DA56C867C1FD2317C8174CA0E0787DE99F77D264655A36B1D8589B4C4C1743E742C31AD19539CBF8366EC188DD606392D727A53C3BC4111CE2CD330FA0E484F19324AA5FD577DBB055A3BA6F2E964371C0D4B9150E4EB9155DB871B6A3F321DB2B3EB9E679ADCA62EA6F7DB5C4471F470D42D6C161CC1A43870E7BF845CFA696D71629C21D53A4DE22AE73C39837222077ABD8A1AFDFAB6B4DC5A2D68BAF6EC95621BAFE7257071A62F07848180FE4BDC29CE7CAF2911564BE1DB7DA45EE58852D0457456D19979CE66F3821C30539965E4C3A1691DCBB4AD0E7AA133185D2486860D4A5FBD260585241772B5976EB449A72494637DB59CEF54567F7FED5B0ED618C9527C28C38BA362621CCEDA11A00DEBB824D31C7D5B3599077B9FF736C3245F1F3DCCA6D8D74BA96B195B51CDC1C68E29E5EAD59CDADF5A05B924B2A790F80CFD8B8B17AE1FAD36ADFD77B078C5A535A5293696C7259AB0305C589B2986B6A841F21CF8686D6B186EA538C29C7654A6AD74DAEDCE943627BF5D497CD7611DDD900EFEBE11F9E611F416B0694B621D4EE741CF21759C92BA8BFAC90ED9D274A9EED59774CABDE532D7644D048B83CA97BFDAEF30F0B2400A1BB647C7BC9E60F57451915A0B531E29D21C2007AAEC522F4129A7C251D7FFFAB20BCD5B0563ED78814A3B2047A375DD9A919A3E8FAA0EDFF63E0307EC9CD14FAB372E965324CBF541D99EB498CD093B188B1CB79DD6ADACC1C9E306483BE70C1BDDD1F67B0B86DAF8FD905F7BB6239138A73300C58EE30B6D48244803A5FFA9936B0A06B16EEB2A880FF2FBDDA1A0813006C96ED0B6A30B5D10528CF5AFD45BEAA82369BD8254A1A7250048252EEEA523DCEC9FFF069006B2F9A8653103D47ECF79BDAD2572A11871C018646505164837DCF91C2E22CC55B344990BDFF2D50363FE34A19C5CB46CF0C193175248EC50978F2CEE4E83ED2B7BBFDE4471859017D3418CF3D3822BCCEA6B8D30CF11FF008569D9F0BF462CE6D73F8C119E3D3AB30A68D467CC60A907661FA1DD47FF3977847BE38ABADD7D4B4E1B127EAA131BF3B0B1FAFC57165B69A48500753B9DC141B9819CCD9B4CACFBDFE4E05CA5CDFEA912602CFF1EE04FD2914780E713176AB4383F3CEDAF2C0B5E6B640D3B5905EC8EA9630BD3672A18135701E4140627E98F1BDC78B05D9F2224C59AB3951A0653E6729B7B4BB0035FC964C15086FCE0C6AD85155B940C1AA13428F1E6C20FF95661D283F2ABE3D43C072B169D68C740E67E3CD9D44D80BBF1D455204D3B56F06D9CD266A2A928C918F737A9E475BE20F26D97A3C0B7194D6043CABCB8BD14BB4BFA94D13C0D9BDD4E6B062D4685D22F3DD7A2EA64FAB53A0E06E0E425FD487E333AC6669017492AC45FBB9E2313F6BCBC6E484A5965E9412FABAD6A6FD03675CE1C70158B33E17CD18FB44392F06753D565FBAB2D4CB09A85EDC20C9C12276557B03DC41B7042A0D7FCB5D236BEC4B907F6FCFAC62C3A07BD92EA85740F1A501591FB8D930A527FCACA427A61256F6591DC1F3CBAF19CF3F9B5AB5AAEC97A95BD5D9056F5E463BD86EE03D1CD5A14312DCCC3345958DE85488D1DB2C54D3393B8BBF90C1411A9A8B3BCF9A13305FC5AF52818FCC4039D5C8C6ED87D8C01A089982ECB6FEB7AD09A79603ACEED01CF453B4620CD36E73B76B91924D9BE973C8BA8B5B360998A182F9A4FEF5563A0C5505B18110723A268CA4543039979231FB082A639658B9F5468E1BD16F96A158E0F39A160109A7CF244CAD177B2B1F41806279296E7D6622425B75A1320E7E3CEB2DEBD1F739B29A8A3BEF23D5DD2712A82E320450AACD8E9EEE78A7D019AA09E42CD9923702086829308ADF09C0D0A88B58B2F7C4534F75631AF1A5B0B68552F402481F9A96B6A6A0A14E93E2772EC72D286AAF2CC9EC6450E80F42673A2DFD25C0E0D5831DA8ABD631966DC0688C38D602AAFE8BBAB8FF5FB9003BFE2E45A74A1261598AF634F896CD8F4C04C5FAA6442A788121CE8163A085B4E66308FF572CF005E960C8A21A82552AE6DD1ADDFE08CA37B82DFFF782609F03DC16E0B862398C9FA09DFA4D35510F4BA7E77C0233CF923E4792FAD9C5D7A05FA174438537740EC822B2670BF1F244280A5A7080B21CED5646F5077CB39F23555A112FA1E1458BC45C491D5092B763AB7D291B8C07BBEA2E39982CA19DFF6E4EEF17557E8EF101D808FFB6ED73DAECEB77C4CFA2E391CEA50F1A75801C2D34407AAAC4B5138B4632A710A40F39BA7ED36454E0B054E00BAFC027D01303273DD2289E7666D98C3B602CFAD31B7680E6B1572", - "sk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B27B870452948D3FD91DFABBA184B7778E2223C610196918C5AC471FFE27C45C216906A32E421BA0C8EB43BDE774C8151020BB33E6DD3CCB67E07FF1508A591C40F29C4F4E03C0761DAFAA6C4E4D7515D3D044F7E5D9B6F76C3523F07B86B966BC2050273654131572050232540265501410321121824027783508650550741845227675205140764772006807238701150672363522380823186775485346122741232101846044762034061346508846856004508217531847506553422270003465001318843366570722341256676412710345762503442766148802031700065838665810155802123526425443477780225517686668627385732838374183830578328430875075738806006057215372237255330206645686206532007402436187730431525465867647825811554786647043104375540063472868467521138444506855840850622072745156652883730438734305732524737387063014705036441133615604518408815122131125202504810267182170514218811002085201254838156820201088584847214346753735887361787368723385680274880675716073083468858754024781441460451718621650764072470876430018540463314037653043260254403334013420554376741651526887384367232437772872571236432846113158844048402448026234443446356631655624571084504437148135030305335563616217056075630605830233420552628432373442580105268442188606664005688153573261574404273251112701374300315715427425557365723036707713333154501238558575528577180345582234204444027511078611230842318434676756513328416871728302630727767221615188778420705148760282006015420340813653580172668162025543061257714607056886527838253463775286557467874302385541175163873125403136883123024782644056005776454050450463856458231030266773238561883245373725805362358236861886558048054373517006153723263352805784612747766872528551515675467320836133213785558662842164780507124010780705382731865322261671658563251820625605486727154222632331845371780377110620406316868745534211605053684662067164782272500355338031585232841457166288521403104854878437265654262373837268281560786012704588254043617732675622047062353066104016602755704578677260376636082632526506057173816361868253348168171755151062823522066020418818632307513542804243556317063765822868038468506613448543036820231730106212347485234367884828616827033357121850832050360848747865116708334325478114764064545882530235517784101378158280387668200424153038757453662564868561401622005841426338428326845853813752150205647048731768316114171432031210530176405308626212315625877622410617144857321075301351544462610553051243543667566675865335022131344837646363774338358017020828322812301042686502414653278867536671246033825211786357550517555870412326345585188457210000315518722276643085112001162624655523063655320741885067301234547663482785273242871867433610317833314257358238168035870421442233173234774652833582072540045143452135211450447284405865524301678168533008608553068110010402510031273465112253237686727627477608688360860655175382170833104267041778753258183846702848155552758183213003518102058824468267721170670211086383333614167717873621734000234476376137205763060645015200727731656541667312526120835206388554240354487387761200858280506664805026810157822733523020574251831872646604616365770712618804337567105781AA2BBE68AEE92FFD1BE88D01DD90EBC8D1A9F5DA65FB482FA23E92A0BFFAB2416637956B1A4F7D0E392B910710069FD0E18EB26E6CA741ED0915FC9FCE0C0EBCCA45C7BE24649829B0AC3A43C4CC2E4CCECC827FD3191515DF2A120359341577BAF0BC05F8358D518A57ED3033A73B8230E8B23F627F6145AFB0ED0742146C61A21AA6CE40AC75928F007F39E2696383FA48C75694F106E623B6F41E070D0E985E9D542BA2B5F53A47B00CB6472F9D03C3DBDD1C113B08128105F6FCB281C302C0410C32234E0E9F279AE96F3CEB0B0A490443A8CD46BDE80AEF7B1BF7DF48F98215B2F556D0EB916695417DD643C93AD1D703CB238418C6199F7FB4936CAB6490072A245577FECAFA7507A2ABBF3E2D185D9DCA22CEAA93662168F43ECE8421B7A9A5A2226227F22BB497615426881EB9BAFAEB7E14A177AC6102425791A1511FA9BCF2B3E453CA701D0C8AC45714541A0478353173A6EE57078F1059517910BCCCF0C9842483CC8E5D35166AC13BDD7D9C760819752AC40CC61528F4A93749BF5711216101CB0EC79B6E0BB92D4F9042DA176E6C175EA1B2738B7A6355551AF4C11AEB5BA92ECDF28E521E1730598E480A6EC130C65388FAFAF5BD3F43F566D0206A6CEFFDC01AEFBF52B46BCCABCE80AF453D1CE840B3157D4B1D15DDBF0E864939A5C411B471A9077E5785ED9928EE1C05E0BAE9D4FB8C9B0B7A814A23784B04F63BB5A533AEF4C186217A24302E706AF88D4F9E85B71CE427D19C149E01AC698EBBE6B5CEA2E3A43DF2976CEBEA3C96424D2FDA27DC3DCD7A36990CE7B9547F247039E83194E34B3DCD90D65D3641AD5B90C4114D0441FA46FAC16A9F0691B36B39012F2361EE0B87C23FC454B21205AE0D7E6D9C162061924C2513C369CA744DD2DDCF9C0C314413D4898311080757309D5AAD1A3761A3223B60F66B0E392F821597A011188BF35B25002C298F01D6A5463D3176E1C7FD0FF1A70E112ADF9230E9FCC9C423E310E67C35860A09CC4D3DFC4EC0B16AF467373FAA59D0E326D82B6054382476A1D47CEFD2709EC829E3B29AE0C09E6B41DD540CEC37F0032C949B9298ADE79306E376C6184FBF7440C14D217B1A557886CA79AF8625DCB9142126A70FAD6F813F3A5625F2E138E625D38B399E20AD05D682552180FEEE5C1E370F2B6E6D5720AD313B98BFD466468C727DC1F2F1CD141DC7CCE3592A46FB3C63302932B832F309AE30E6714AB952AB84D76A59306D05E1251171F8C7F8B7B2ABED123D47428741A8583EE5B8E973950B4F5C754DA4679F3A06EB18115C3049DE8E232AFB65747C0AEEAF5716FE5B89AD6ACE90F8CC4E137A8D9C65CC3A98C7FBAED0E7451A8F623890538DA9A7B821D8CD9F49A1AAC810EDDD7EE00AA8CF342F0491A50E617DCD535242D54F0EE8392D1B8BF7D69C81FA335FDF4AE163A1BB7024EE883DBFF9A1CE154F4316D6063DC7283F151C4ECF5A9E8D1C25D0238CAB9A925788FFF6BD68519713694B231A07E826CFB6F3910428E3219116782E07E132228B558CD380591866C028E1F3BD2327BF7C61FCACAC8485EB43213C20922252B2931861E077712CBB5701876BCF66FAF1CF6582D4F4EB87CF82C1B7807A255E73DED3A7FEF23139DE96AE800C2922246A54F3F3A6EBA2C8E8388DBDB41A4131A69280924F6D7C13952ADF9F6131C1D6AE6A3A085F8FD5E4A45C2951A8D65C345CC067B13CA32B1A6C28A6359C48DFC119FF7AE92054169DAC29119508F17FFB0BC925E357AF70B85C214DB0368E1425AC878978C346485CFEEB9935BD94D203E271C2EE9EFFC63C54B6D05C15EAFE0D0D562C458B0C7EB0D84CC123FBC30EAAB78B47F9CB11AD7ACB54221F56998177D85EBC62DEEA042E411707FA78C545445372461BF5D4C9E4B5778BDE3C9DB02F697965D2CD2A10BE66AA9DBEE728B52A9117C53A5A2D90D59F86D8A601436CA41D4A99E3C2E66261E37A3A5B7D4DD21CDD46EB4C62268520FFBBCAA8BF3DE714652CBF83E7E2CD57FEF6ABF8946392A33D984FE1CB1A08FE5DD088F974499B704D94F0646C7977DCD7A75E8012CA35E39CA7EE7AE1C0C27013A32DEE29CD141379DA504CFF6ED8853959840E829170D2D15A265CD9A8BA48718848473090F40C1BF3DD4159267324BF9858400091FCE515D541F6608D395DEE9C5F673375E443F104339F444C4819A630232EA7D413CD8A3556E60D7D20ED42E45CBE335AA1EC684CEBE7B32C5BF4F68F969932961930247E2A9F279F5C587120879F3F61025D6B6DC617C9FCA4AE8034B00C8DFD6797061A36C12979E85F4AA7C9F7E57FAE4AA44DB1AF6306E982A723B6F58E9008B4BCF4A948FB131D08AFEA9B4BD093CE76F8F6366ADF4EBA4E31FC5EE6DF22E1FF1370C81937D29007A9138904F569B95A38C5DE1BF03711C9D41FC0E72744426EC510E600D1231C99C7FCBD91EEAAAAD1EE8A27544D0AE7871B4B881D80DEFE22F3188C250AB8760277BE2295157BE5F33201233B53E2348661384134E6A9BD89E8F85B2F4E217368FC86161F491413C8959DB67AA5D51DED0854FA779AD305E3A6895542CD84DA2E8F4739585F7AF91DFDDCB35F7E8C6F90D1EB810D8ABD36334AA02E84A4CB0DF03961F5AADC0CFD45A7F59678B06204CE0613F040F3DAFCFF3D59C56B655A3D3A0359340A0F91AB9AB1A17621A1A57AF588C31385D44667E9258E5870756AEF7AD2E2B3E3364BAEC218E0D6BE14EA5139FD672755F7942F4BF9E023ACF94B1E15C58298E29B958276F0C4F04631D41D99559E7A7483AA39252647D8600D33A4C8624D9A663AFA8C927808072A4C6A63B92A76F76A79176261D9050E890D52CA68279AF0B09B443C001A4092531BB8E251F7ADCABF4E49DD1616F42528CD67283F2C52479D7DFF2F383AD7EED58C1621E4DAD50AC9C9FA5096ADB9EAE77B19122ACA00D48E967050303C93D90976A3DDD5B3BA4A816CF0019B508DB2E65CC47B187C78432E41DC9BAE328EC529DC3F6C6BE048CA843832EC04348421113A02B60B35CA66132059D4D5EC297E9B92E8AA3130E30DAAD74EE7E021541F0B3FFA72DF618969D18B7C6936242555FFF1161D85C033BBB934894825BE9271EAC5A445363743F81C46315F547995D6925FE76BE6B7145D022AD1A015C0B8101FE30A81D363B2BCD627BF178FF12023F1BD82665393A49BFCC5AA1F1C4FA318736A301D00DD5D015A14640B91E104C814056892DE7C624240C06A3C5AC14E565FE5FC6170BF315913CA6F5BCBABEB9C110803E12D81CCBEF3C48B0DBBEC02F8616227CCEDCE48437D801861964934B149CCF34FDF7D60D29FFB46854CE5F3929AE9B6C051C6825399B9EC10A9BAD1586D2E75DAAC68BA2527B021E3153F419B0AC23A961799F016A37572C91EF790635A1D7B7E7968AA570B5897C6CF03395B5FD2022114BA84DF417F8F105810384BAA41EEF2A5B0C7C3E320237BC67DC36809CEE73AC388FC9A0873B2AB63B638AD364F28B1B7D002EF2CF5C" - }, - { - "tcId": 28, - "deferred": false, - "seed": "FB27DBBB4ED8F4F7D2700283C2B092866694246932EEACEE72DB730EFD172576", - "pk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F0533A0BE6A3BEF98F0A550CFCD43CB1CB9ECC3F4F7DB656C9FAE8122A0A88DFA6262F3B11454457167C1DA30042867A37B26AD62D594591BDFDB36B833DC83E4B8109CC2EC0D4126D24B2BEA48781FBFDAD7659F1D8E60987B9722DA54627EB895226B360C61FE3F2A10A69CEFABA3219AFACAFF22FF5BC7B564B01A65BD698AED8A7AB78812EA6960C2B766783ABFB85613B069A7CC173425F701B62238FEA489407ED3F2ABBF538B1184996CC7B9AF15FB5754928F552AF73696B18FEE24038A1E9A11DF0C78ED6814CEF3671D60DC38D483DAA6A6822FB4381FC036C805C8D2B7151BC6A6B12466211C0E1EE663BF4EE737F4D942881E9675FD7D87709B5F473054834599DFA499306B3E727EA6FCB7990E0ADF348321DCBFF6FA886C5846B1D05F5E08C6C4BAE416FBC7ABC1867082834616E3B4757616E9B7E04E2013B534258015E06A114192F48E3C5F0E6A48775EC05F554D69843684FFDA6A2FAB8F2138817596115832AF77A10E43A4FFE98DDE79A9F80C0710E5450B681D620BCE626FD0932B4D9D87BE222B7D0D8FD010172F3C5BC2353F44C08470871E38EB3DCAA19C92D3D028D61662C54EAF7ECA32C0D48F4AE0B2FCB0F517000A8BC96A76648347687815254ED5905A1B4A2ED4E43364B48886FDD5B86F90659AA03B2AD85B54D3E85E3380FA2E050120F555FBE241B86E481E020BD0AC3445CCE71D9F8FF56A7475B073F1F388454B3605EA18A5E183831C948241DA34EA3E1112BC706102854423A4DC16D9D3A79BACE600F8098AA60744E1C7FE18A047BC7646DA4A569E0A8C41D0587053A22209371E4BDF5A7CE8241D97670BD81E7FC61069292BBAE13D8F729B7F5C2ED3E90BCAF55DCDE5B20EF92E1E7A159B6205E7ABF72571F02505526928DB09F65562D628443925E7DED9586393DDEB4E59874077CDD4F7FD4CE68D2CD311DE78B245872AD56078CF3DE1D88FDCF541AF7D6CC69A1C96C2E5763BE310BF77283A820359CDEE43B53B2F004F2FA2F1725BFA6116AB9A8F37FF4011106D1E65C6A3828AF1E92671953C26ACAACBC48031D7E9919DA915B9E5D89556FA82E9498A0BA980892B9B9427B848D095A0BAF3857B6D6969E99CCC337EC6E166B1E1F55237BECDA10256C8D97A38B21986AE06DA7C80A17F84BC448F9539BF3630D7D01E12E80B616F5F98C47170DF5E16450D393CC4542FCA66359D48B1C29D4C997C6FEC087540AB588663F5824A4F09E5871A78E06C18D3A708CBCD7B4A957BB69818D38BE03888BBD62738DEBA58E3A6DB3FFE477A5EE262297F96C26ACF7CC419CB7F3EE8D09E47AC1B134B6AAC3191F7F586B507F58FF9AFD67FCA0C10E7676ECEEC78132EAAD0F8B91588C62658ABDBA03C9FBB0630B2E9603E5A93F9A04A3E07A09FA0B3AC4861D368ADB53E8FCA932F997952AFC5DA4058C48AE6F9B634B624E50D2DB8E3CFA23FE41C2B88C3C588FB22066A0894893D4FCD55FFEA4352F8A27D7714A18309B7997CE71EF16ADA021FC52F3652561A1D6518559C250CF1E35D109B04408C998E457F06F73349CB8BECA963EA4DD65826141A59FE60F1DE7F8D8A67F5873A7696E206E4EEA9FAD9FE00C97A07F7D7DAFF316CF85BC1A465F61A381B2EDB3EB4053B8F134B75DF5C6D133E7CF38AE416D24D4AC66AE61DB1F682A6B42B26A421E7497FADA9A97717D2A9D7B028FACF01CE14F3F834D84264E688BB7C0305EF9EF28D5A0A491B0C4AC763FADC1E260790E0EF2A70E6BC78A6D3A136E0EFA5D86C9C0993F3E91F5AE6DA55BEC8425F1838298F63601B4E9E71AA12C07D2FB6C0CC5661BEC9A0D929FAFD8AEB545B729C7BFF035E67EA7377D2162622018F54F780289FA8BF24F9FC2E85D06DDACEB91D064D4DDD3969FC213AF6292EF7FCBADA5CB3D5D1B5833CAEF100EC657056B69324F2E5C3ADB519120193157505F5A0C1044C0034C03A664CEDC465C79BC2B915B749AD0DC2E88DEB3FD6BFA8EE42631F22938D735186CAF7F273D9C8361851028362F54A9CD50536E31BF835D13DD4435911CF01B1A8E27339033690C35C311760DAB34E391FDDB690156FA47B169043E6D5E1AB721619CA3B8095194B7802A7FDEA8DCAB9F43BCFD1F5893EB4F58EDF1C0B9DDD0BD4615FC1EAEA46C68BB84697DF3787775E4DF560B1A43FBC7A33A3E084ED97E59C000529CDC1F97EB92E9DB331EB207BA478E3457D1648084D267C0603135B8DACAF2C15B42299DA433C0E5225C934DADA9B701751ABACF9FC47D90CEE43A2FA47F6D05D169623B369A7133D0F73922B2EB869E91B5737FC3A2DE03A3A92DA98A253C022B4466DC591772D39E04CB1E4F176C1A282BA15E912E2E5C8D81E00F92A2FB8BBB16D6B7733A785F620BF52557B3C3E87EBF625B4FB0B7B65101053532EA099A1B0264DB218EFC19BA207203089CDA1FC2B32BC416C454A4BB977FC3528E423A3553ABE4C48DCF662BA7F5B7E1B2A4E2DB9A388EBB0E39BC229AF71ECBF2F40727D6CD39C2FCE2464AAADEAECD47BD08FB1FA5B6627D274E3D31C078FFA3C3ED29980941CEEF8853704262B23DFE88780FD9CF259EFEEAB01255F0CD354A473848798CC5C1CDE63AEC6AF2EF078777CB67A4BADE7C3D5F345111FC73261B55E8E257EC5824CC829B5F5EE31D4ED03A16590396E2FC381A7923E81E3F582252EB19A7D61ECFBD72F0C3C16FC79", - "sk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F05E8F6C5312F27292980146AED5BD4CDCCCF105C59DC052E9A5604839CFBE13920A93E9DAD0A618E59915ED8D751E04CD99BC661E5EC654FB33C82AD84ECA806453B9145C9335E1A95D987D85954A8DB9BDA8280BA76402E489AFC07D90DF7567C36560273017280466156464484345270285178305711250242618355037451272805831334710075688556205675635811344085746515547468075008004432316642077378448408234860066117021246184447148263433760087826350221845428303755534425555717783464144721524485283480133537526651561143130746043842062162336620037333860708821510700458474260707108783552112553517880140325080003741440347208756274083066034241155117413308076178401187304037688762030146873725228304172627873352187338032728273353058572467830523107526832557771072150587632044015331378888724574122703235400051288424471463017425114740686283126323770788487586151073237435056574117185656340627503508855871406032154132457173517406070365623071357215822006317662446377112741371334240268625017522547202654825346782030134741711776706347452824240741863480127103262631840235133582166006304237018151562258370018144006703338563061314556680178581266374583457127838148005138183311168871835130403368588740370785287432187408630065074371213480444706406001571542517601870046628537585864013505382654286745611688562826411460181216012170130671033666664050228621047288450184107351840765645803278162817607642382073553002556568788426586683475530285773666151835665516303380616363227666858618761871385373345822418160086702271023726638411777186012145217307263853282062146678035810787254502315346844448377284120122775352576074324353408540721484446660113184477760757722801866776724528834717535547588852626733700730625755854828563408352458634703417047181611758852002888110270451664011082677250413015718850326577835815683880356606382152683807252371042722116282841206422056134168747282480661425448572771268256417857244404004266015646767320855751075500451662804257710454343255256810735615778555006233143718626653125262772466865157188155020522535172225206165001848253325225481217513861451643867711572822836715814443656054847322127382261373454384541346144146522301347070057540552088832373200502381445727625633138630426301227580101874474535184582276070136541128502418006160228766041816107568722737402742376833648820075260766071780446008477251682432221347088684304624471851307716637632473404150070457208081263267878825854610503616057514005155454106025132382716413517273075776773481460567806534468274677273732307402176400528254003850741282758634420707000148538120762573172316826678588360778452648825333124015705775726667545085706211188383356315880631315705723620874123576711420723155615800885213201562654580242880636273014718214588481101167063874558732715713124774232421012565602130506631727226611188335482535363622858870107022383508628013502852406025771446035382361661005267412153785415157213823542604756172745743260401151135822128877563768657521545878000334705788040273517532403014046181623871830487143472731360310027464080371511476477842670552846448716276586070267871218265501785588404888023122544554862135404377441518C06B6969446A99968141308658E13180DBDD324D01DF12295072B0689AD24B8D909F5B912FD4484F8715495095E72DA498D11E17C8FA5179C034D020D13333D45F044FE079EBB5CAAB5AE07027DFE0B451C647A7CEF0F2D7A516278D0146904E6BC5F9A019946F64F3A69C8739B47FBF768BDC2D10AE0DFB3EE486115C3D29D0390E9A6F0C66F32D20EC247C23A95324346E87E5064A651255FCC49092B4C7E7C1FF85C6BD646F40ED3A8C0BEC3EEEC4357DD01EA975523E50A5E1F1357B0BF59087F056A70AA4757348F5FAFFF7BC3388DA206D92ABC9A373472E188B55F03A2F5B2243A3C2FF86A3934AD1C63EE4D31EC38B980F22141FE77B29CEDB621B6E7689343BB29699FEBEF26346177BE01999A5A1A916987138E7B84EFD5A8EAB3B995C6E4202354B659A391EE0305DCC82347C50CAFE8C3D25D5BCB25648CC4CCAAAE062FFB75041874FD14302B3189C8EF04500EB3B9E6AB7E021647C79E1FA19BE67D1826D3B96F3E6D49C6EB5859F8EFB241B8E583005536A8235C5358A64E894847194A3EC4CB7BB6D445C66C08AD99D4BE4243FECBB6F340E175CC9373FB62ABF024CD913F03BEC9E8D28F7C8587E1C3A7620A83C3D4C31DDDAEEE9E1C965823A2F143F1F295B4A9665715EB2FC4A82AE0E16ADD7F58986E68A720783D14D0C48E92467B3DECED57A169CE42E9281B180F791C3A9A84D936BB4CBEA671510899F35A4AC0EE2F8547C2685913069FFD11CA7DDA5349D545BD5705BB5FB3E233F11A6A6B21DC638A4410FFB2420B123CF8503FF4FB53A19DD70974D90231B90914F92E52A38B13800C194427204D3AF3DF2436AD50F85DC6EED13BE12870FCB051023505363E848BAF4D01594BC35A9C35DD23A4986ECE378A425EFCE6CC49C65F5D829D4A7AC4AC54C3C4766928315F23400836DA42717ACCF7061CF91BBBE8C47127F5A8DBE151B37FABF6477718B11C3FF2CAE39246CF44520C92411A2D9B365570462F2545364A6CEE318330123FA3389E732BBD135E74C6CDDE764AD713A40F19EEB1315492378130247187C9444D7E5AB0E56BEDD59ECBA7D27AC32618E1DD23D1452664D465B968D86E53DD0D9B50ABCF572BC1A2B072C1FB6A6B2B4DFE7A8261E5D074897EE0ABD4E82C53624CBC3F94879323A4A7DEF36E80E579F824129D379515BD42F67F68D2A0D0D212D102B19D2D1BB4365C0F5DD6F6FA2F32010A9CA755599992C68FC61E4528A68A38F6ED6E70B45E1604221C27060F6336062F6F85A846E9586D8D9950C0517905C23BB99384092E333985D1E8F51F9A1AA6ED855B4288674D02A04E15E8485C086F952B746351755F31BAFD9BB9D0BA02D7D23E0915B8A1C5C2E8372FD6965EDFE496ED5A2859440B1851F2822F1C199C041E863A9D23AC3E03D510507BA8B4FB7ADB6F85D421B0ADE9B3B6606C9571E49EDE3ED93CC85A23E4EDA6D014B9F93E6B38FF145C8B10BCF6D019E8BDAD78B8FC0C70FDA4B21CE9652CAD055EE62C195CB2031847490633F9BB81D1F2B81E9FDE6F8101CC0E633676D5CC8B0431B917AE43248BB2749CF38561F409EA1D509BCEDC177601ACEBD99DDA198F4E4F215AB890CE8CD9AE75384D27EE7C3460DAEB72BD2BA90FDF270FC05C52DA014BF09F1C30DEF071E1750E5F9218F57DEBA0C90192D582B25A63B18F84E4E06C741AE8E125753F5FBF4E5CF08D64F6BC8A155B1BF4A6CF1A252A8F6167833D3895468B438EC98548A3AEDFCF0A3A31CF1E0D4E442B6FC59C86C10287631B134CDC1832D83AC335F04D10306C75C1A45AF63B48BF8EB03F89CA6E0DA78BE299F98891922A977E6EA182A5AE7B544D2666CD0F3CF2387FF3C5E4FAC94C220BF532394269304FC8A57FF17FDDE31B6D233A0EEAFA3614DFCAAC06BD6CBEF6EE74248DFE9C6B7A5A0F284A0CD4EDECAF3DE0B4589D2408F851C2036812C7D46B15F67E8C9713ADCDC1F1B2B82ED7DA48AEF24DF9B400BB32FE89AE95608D7164C377279F779CC1E8FA6D6DDF67A264D112CF7E0733FC450AA97B286EEDB959A57BB82AFA333D1F0CF965087815023B51B1E41D035E29AA99C90CAE7E16B0E7C03E52700CFE574A165460732537C413C701E69700BA941A9386FE8F71FCCEE6D3C10F832439B754B8BDFD49E3052C0AB1DFA70111A4558B86CB6054A4DCE74F81990850ACF6FC778DDF25D395527577D9D0CC34C72029AA9627D3649565F9013F6DD2E586824BA63C18D778F6E9D8AB85682DBDD723315AC9DCC02DE0E8789F64F1DB1A7F011CE71B028BD8DD3D1DB7C2496E67838649DF2CC4E4DDD1F5F3308DFE57DD1A5074C45F0346043BFA4D949AA2CAC83221D27ADA31EBD5A4F458A54D128BC7B20F410BB6C19F1652B84D05D5C173261D701D5EB7053769BA9C62362CFC52FFBBB536B1C21C497732C6894F8FECCF35C513A14EAD53C3A067585C1E021ECC3F023DF543F624DEFED6168C92C43B0858AF64DA72240C0BAED28C53C59340AE604DCE4E4E2B316FAA0B04A39800DEFB5DC91611754B00FC9D028BEB2732568EA481FEBBC3324E21D2C9A3F8990DD20E39806D90FD50F1D19D34CFB18ACEB5B7D8810B57F79753D372D0E7F4E14A6BFD4882A351083FF53DF1505A5973CF63CB015A38CC8F595AC862EC9FBCF3A3F7CAC508E6A48535AE97A56468B874AF26711CF989756757F8D3F31CB1A22E5A06B86AC8CA86D4ACDF5815F52B6E3F34CF728F1C735ECB35DBBF9B0FB14932D3B1816BBA6FB3DE65C1F537C0A36579EEB49F34A82881FCA14C2D6D8F2C7F9D9DAA879C8BC0CD3169489F44303A90434E8FAA1387885286B5F837769DCAD8F8B654C85C6FFFE02ACBB7C2881A7E3A3B2466E3F12EC79138A3FFB47C7758DC2F7A6AD0C76A7BE44604CC264F8CCD1027812AE9B47C94B70C27DF3F208231879B72947F61F98AED252698ABFF431C37170BCDB9D5894FC0F580F7260720C389CEC04D82F5CF60A6D3501554065DA790BEEF3F18A2F05625D0FA18FA51F0FE8D1C0583933FC814006EA9D3C8D94465E5EF36C65F9333B08C63CD0220B98313A465F5B25F406CE4906E74BC44D3F7A98211A0440A8BFF2ACC2F6FDD48DA95A02F110D809A0304A756BF23EEB96E2E72FDCB5DFCEBD2FBBB293736064C39C45209001FA2E4576ECBE80BB7B69B99BBB8DAB7BC45A1D39F8C52EEBDACBAA68650C20424B6D77FB03B39698DDE6B33860A485CD2DFA29EE384B7318E8DB0A8A1BE5BD032F75DAE98C5F3993DA601BC00FD13BDB70460635D4DAB8C59E1A1B74CD5564501214893C915081957EF886A68198AA776C29BE1EB747CAA6F68DA72543A5AB3107F46D6259F932F616F3ABF7414516D59418B14E95BCDB1D5703131CA20BDC8C429532212068437A90E8F992DEBF36CD1412EC24E9029D83C0DD6C6C049F9134F45968BB94C9F8004EED39378FA089241DC3084E253D42A0B9B91C5367E6BE1F1B35C37699ADC1DDF545A1DCAE0F0D002F21A32279DFC1DBE455CF17A7FFFD3EF781E727AC" - }, - { - "tcId": 29, - "deferred": false, - "seed": "334ADAD056F76D74941FD87E5263E449D97C06D748A82018D0C794154C20A870", - "pk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A228E9CFF23DC094B0D3690EE5B3DC55F243F2FEC1DB1046CEB35578AC48F680F9F9F8E20B4C96C67FEEBA4918C4D7AE555CB82338D92A2F2A97B722F09107FF5DDD88C86007FD3187E8EF195B678F1765644D5FAA99773F0188DAAFD9DA6BA2598D440F2639BF2C0A3729078CA78907C54E332EC2AA6D9E79698BC72D082787D7FF28929CCF6FAC633B2EFDC7DD0B82078DC8CBEE7709512583EB2BDD9177C4691D4AFAB887A739B396B308B7004BE2C7E9D83404D185DAC00168869F5882FF81C9C65FA6AB987C0B356C56F3E8ADC931E780F2255C39E2D40C0D741D4266B1460344737457D5DD07889B30B640BE49615EA8FF6CEFB05A17AB44DB8DEBB3E883E8682158F566561FD4FA8027A04A0153ACC065EEEBDFF09138F621025527079E7FFA9010FD95C8791CA36377B60E2F92383841E15C8A8BA07F2BD34F78D9D2E6825DC476687AA780B642B26A08C33CAB33860DDD1858DF04A94C2405F94EAC54A005AE53B7573CE87860FDF4A59F0E96FD87B451A2A897D8E9EFE4294949E8D663669D8474DD5FD5580A366CE9A282A5357DD7B96A66DF961484072EF21552CBAE892BEE96330FD3A2C55008D71D23A4F0579BCBEBA343C65C3D565B77474C178DF9A97B451A4EEB90041DB4B50BAA022037E1E60D98F4109B9FA51275A7662BABBD7C6F791F54EA56752E20284B56CBB853368A2F54C02778BDFC742E8FD566ECBC97596388F9F823CA2EED4CFCB83084749165B17425A8719F4822CFEB3040EB3C8611E1322799D5247FD27D403C74A80FA0A672FB1CBC62443A222DC7A1E783E5BCBFDEEE18A8D880C65B9E827493C318478A6573533C4C36A6387CE1CB01CA70985B39088AA76F4C13A774DA5B86599DCE9FE1A87D2A48AADE42DC5F1849AB42C8877B5936FF2E53D860B54918B02617FC78CBD03765EA6D9F554C8A6DE18D7AEDCED60BEC084BF93419B7B5FF489457CE976625236CB16C26686C3BBC5BBF2E1D37C69D70976A7A3B332DEA756B3B84FEF984BCE70637FC376A8F4A02EC317D4E67A3F259141AFC2B061D48015294497C276D87459894A80B2C7B9C46D988E6550567EC4F3035E23E1921818D2A4D060552AB0088A27C9A022DB688BE947C231A99F22D6D0B225FFE5CEE23A5E89789F5AE58F4C50603B37A0624A96270B849E867366D8D82E02445773DF5648A15C857C6B04AEB21AB4A04A0552E9F30CC253B2FE7CE0071D3335976BB702B11716420B43AB11639589E5D5A3E7477B95E598208AA46DD30E1606F30DA0C616DE7A3CC31653545894FA958E8DDC026EA1A8A8B807EA45297A04AD11EC7FB3EF4DA1377BC6C36CD3E0BA08FC90B4B80C541BA6A5B7D2D91E299D4AA9D854EA59F45E0D76F8090127E8E834F3A652AF71F18935A58DBDD18E9384EAB5E2E10D78CD57BD4EBCDD45BD2125F2E0896BCE153B5F84437E076145B61C050F3A45C1C311FD8D880F38D65E89C4302FB3DC58C6DC1F58B0C52B73C00A421261AB5B9EB317C79E2F885ED5734F638C8EED36081404A048C26219B04E526FBC1D1A5058685AF88028247D6ACB43FEE3F546CE2BBE4BA456E6868CACC2557C07ACA318E1C8F70AF0C9F55AED0515905E775F5921B3AC8EEB5137182F487ACA7DFEE88E77954A94DE3AD78C518B438915FCED9160A4CACE1D7A005FD60BD34E1B328321C22F58E70741117ABC5F819722742187C9D3DD19BC3B7726DC3E81DA040CEEE823157A14470E9C0A04DFEA594A05DFBD1E256BB1524FCB591786379FCECC7545A875483D4B2E58383DA1807F5222CEE95E21BC52316A886590F55BECB6F2D5F8184330C82BB50427BD6DEC0C5E164ABDCA44F77E80231FABFE8BF02012FD377536BABF6C7638FAD14870C97F1AB0D4273DC9C4BA426169B659278A5BAC8B63E4318A0E85C4B22403F13C9E74B03633FFADD939FBA9EA3D746B37E4BCA503370DC6ECB7EAB6537E16EC64DAA24C1ACDD2F98531C594CE745C70CF3ACAFEFFA1D36CC062D4FAAA76AFE291B8FF281FFD546F500786DA4E05E7ADE2D37CD519BD78819F27ED9B9A950ED2D0129253DA2B7F3F660281C9B0183E5F753FE96D123DBC27FF6F56FA5465B8BC9F48CE4AA4963D17FCFB50FE546164F901B04ABD909B78108ED8C5DDC8BCAEAE0669B740E0F7DCC833FDD91A789603FA9A2EE551A387F944C3A032F231EF0E7CA775905CC5ABC8755886BA211E698211ECD3B04B959BDBF431A454A08558D4CBFF01D177901671831E2A0E9838E7D9D0CDF1C6C8827E97CD341DEDCC53097C9BFBCF0B4347E398E1132C5CD5A505D45F6F5D944073716672A2B0BB6C41C8AD65F843B1738FADC6018B4C8D6D5B2E2E331B8FC41E98A91A0F43DA608F49AC0126561625D21147BB3D5A9120BA264A703D5E37494FD4AB883DCA023A73DF9AFFB4A3930B5ACA133CE57920207D3D1642365EE718C430B51AD7D4FCAA294B1F42D8BDD7F08C5B8FEF631EE7F18904EB84F867B7407F93DA884128EA3E4E1E9144ED351F40FB460FD511AAEF20ECBF20398C701717409289AB22C2518BD464D28D76D9420AF9C9E91734E36F355544A80E50BE0D3A36556620D9D217946CEE219C990807EC0D1F2AC904CF661F6906D58D8A8F500C3D54F1966A8557F8224415F17279FF93489AAC8E8C09BABE490C6F34688EF162133B19B55FABA9E3AE1E2573E51966CA827E3DAD50FF9", - "sk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A2B3B647FE6B2D597C0BB64BF8EC612AFE415BF8C6EE9C1C89BCC07825BB4E0635E279D6F8DC3E90FDE70867F7176F78C7375112D6738CCFA4081C0A267427E6456A9CC1B62D301B2E61490266CFDE8BFA6105E0A538AB1C1D0AB74430B33713623581386483755445243753473438078511606051368073160115738012354521300214633143005060458451614181317625600850828658142078641844516326445870256686653680383537701272643265207087826247876408370160122140768874166087151412676620180320686408856302667266662275523315434588681761074568070028312208584121154004344663581510807865182675883813108000025672850572778605381322036260037871137460676071517771314675682566577436544573460506504832281442435167233455724534277207215216360738167150836460874031736450610842824275257455405400364275587451282130682375546268016543663485208367258707108220164027637784307552716318515481724518532741014070576523654860028123444648726543434463586358076328861862385412143118625642628126672617763635717788356608737358238865854478487075717624743613147755325577155202642662650113374865061032648163018768724404227837151260534245414730837040272670625518524816844173752604713612421427581014835327884216357004103827372624624825607613685321838718783121783201546220877332618523484033418836504550354845557501255723257746365364533724770053004852604007145007653484371135700033413050162143608712741065021721558584332535787122020613285457067071122166270825871245825500252511451404363724313586561623662725341448326850605637645520652710734061103603553721504585707324281583008610265170617622430557127532416631412258328838374307302264678282601782132034871337644843401462742842107215876302171452753735780621218157840378626106652400582488562616865716354530113688531563273150642540215680704544160562010462168227847102043537372863606227863485764564280612335786655251320053243774704426146103767351675004061227771882487418563217101228257228474177206416048740843757752314642706176054186108442840481072688807888245121437337668018848605137653166518641703180318156612602033260572357615555665686231008127660607683820542312302436523202472348222103574847503136060448373050426708734310818546100012558051246608155643310633872255780650310786552541215201745381263325165137452788463576343674204721826037356042184745266584825467165112106006355167510788781105623465658773756883868012110284321513014454716525175616611768137427681534886023486205351442728858581666752868236430175106745042638321062083108321702340453041130612457481178582752050626158025384055005352376672458346427221748425807137606753806442562318172647335860725474830371583802351251766113664310376562367167407343086650862744558342510760512033105786441765808007204600605264376872847174351175438301566013163416683413510128707207468874177221405114514851318225231514632664730885425005816216567873025118726014288180357621523872378502177300555886517581515484033478831137167558052224442144782845268072021678508733840333135173515826820635274207417088856814547057513727206644577603710446785322314856685424538803253760515563520538716116405141054573465220348762101770782046356737660564646108A71710BB56C4A58168EDB0C30F9ABA6528629B1651EC7F3D4FE010447640C0C2463FC2632093713C10EF12918F6716BEC6AC202B2DD43B2637A4BB8EECF09091A92FC1B9F1081128E4DA97706698A51AEC985B77FA207BBE267EA379FCC692A53EFBD31773E886C3637A229EDE8DA0CDD2AE15AE92D780700C84AB8B6EC9C0B337C52BCE50FA59D420FB4246E1E62264C0EAE5D22AAEC278FE76F27EE4F43165E6F28678B613BB2B482E36470569AAEDF12B0F6A1E8D63761668120810A035FD8AF1BEC04BCECE6CDB44A97176F4E1F5A8AFBEA4F4C08B6C42CDC167F933777F012D11BBDC6A6BF83E1C7CAECE6069181B7CD884F482FD02FEA80CC499ECCAA88B46847020E6154B30DD124FCB9ACDCFC1B458B21F2DFBBB4192ACE07E445DBC9024401ECAAA68BBC1FBB615BE93CFBD2CC1C395FDC0F31E7054324F37E00506DFBEAFCADA9EEF08E082F130396A22F0A1B82854B097FA713126BA0309BBDEC3BEEE33042044D9FE6A20D72948E54421739E3B5DF5F07DCDD343EB4947873E77E1D092357781F35E8771714A168897FE3C458D16621462F3D2130D661E83CA346BDE9B68F238B264B5EDBE0EDFCE0FE7AC1F6D51DAFAE7C15FDCE3CF6ABFF710CE4CF52D7340C6C6C5FCBFE3ADEB72987B53CAF3C8462DF45649028E57BD96FD918156A42DF582F2D404004E4B4C589C2214937200B4E8AFEE6FB4A00EB88E4827D39ABB8741FA6B2A65632F76BF3F242FD2455FB6FF3CD06D09B4548BBC0FDF4E3399D5926C62C2C962C708FA6A58A546A1C27D5A4F067F7CD0D6BBD4032493A68C6CFC5D050D779E9F389F8DB5A522FB052D2967DCFC2F99A911AB8F7BABF73944696B334A3F3DFEB250BBF6E79E95ADDA9F8A1678712D752F4A0F2028C6871BEF429D9C6784C7739FA8CFEC41ACDB06496D8F7D013693DCB1000E8B8269A3AD0685D7E611F9D0E268D5C0BEE1DB5E0C103AF2B416C6207E498A4B15A3F6FEF22E1691BA30E296790414C4CD257501DD5AC4236D338E092B32170120ECE4A9699FAB32BA0447B32DD4957684793A77B53B7088545BCE9D2351391C6F68D4F5B7AFE553ABE675C716B66B3733D20C87EB5E334829B0BA1EFAAA6B909F9FC2D24517B38FCA6F0EA0093583C0925B0627C5536CCB9891C801C2B5CBA522A8F8F036D45B4022DF9763186D34D2D137BD4D1D865BB5C49D7F5A73B2DAAC7299723A36C723367083E76D2AFB0B74CF90EB9DBEE3B39D756A69299AE2042F37B087BCEED9CE935FFC25344E5D9EB9337A9EF17637A200567FE6C3E6BAA5A69E8E340726D60AE730CF963CDFD0AD05745A145E9FE92D80546D7AB67602A09B777581A1C8C7DE45A6ABD1DF2AE9F5489059C40EF605661C75B5D526BA9A928B41FFC93C36ACBAFEF9EE13DE5660790E44BE35D8C797EB9831724C86A069BC4153E44CEEA0746B04B9821B24CDA4A98FC7A42C8BA35E7A191B937D4752619CEDCB00D21CFB9AC21F2C933669AB073CF8F3B51B6D5791BC979C7B7BEC9D49CFE66CECC937C5045B21CB6FC234C29FA963328B174C8537D204D79CCF2250CBAA5AF3A8BB1014105178A8B98A4EF49E09BF837452D6D2AEABF589674C893BEE8BBD01EC13417CCC95B7A07C6139B5EA1F069EB7FCA0BF92F3744DBF1E24D469FA24767D2C0E7028CCD6AEE3807A2D3459AE84E9E5516F50CA3C42669F70A61CA3427919E3D3C4F865176FC08C68FDD7A48EFAAF92828C29AF85F050B45F03511BC0BBAF555627A12C53550BBCA665884239D3B68F419214FCE906A47B036F3C5DDB300B1E58A545B71C74733AF367D6DE5519FD56775B84DBC99ABBF3F135FDE98052CAB7B42825C3D76B5D3E0F6BB0C04FF8CF2FB3888F3350C4BA6027254E124D1E9871DE84AC5289A465688C4BD68A2D187D461BBC4535F824CCBA09DBA5B7FE5EBF9F7F97A85E31D5898D13D770DCFD92FA3B7872EC42853760416AAEF34C0CA96763D8B38694827248B062948A42821B841E623089709B55A9A26E7C985CE42B5F1DB99136D057069D582E2AF5AD2A18827C6EE2B5342D2A1DAEAF1FB1E0220B95E850CC04F5806FFC11B304F842683CA1B65A02E76FD0A2320819B27E43E50D7F75F4CC3988C087FCF409DCC6BD92DC9B8C72A67890FDF4919A2A0E4BBF932C7806D25B5E728DE08B26AF413F0D74BC7CAC88FDA1B54B6C4FB584FDA5D7D6A9E2F24C4548BF3F7A3F173845AAD914A3A78BAEA5877841329694A3402600C5183A1E773010F7351FB0E57062D715DAFF483EF5E85965ABD16973DFFA3558ED9B50ADF802C495A223A3A19B82C1CC1AF654C2690E46FB629FB5E13A8DBA83A176338A298057EB7FD674B43446D0BC50070A420AB426A1DDA272148CC2D1253AA827298D6D402CFB1D89652E3993E42D52DDA92F7A171EAE4B652CB65D0F6D55B54D7CC5E2108E6D5C85DAC4D5FD8E05E3CA6A060AA0AF6BBE310F61CD874C16AF5992609909543AED87019D72D07781CC8A42DA9F0D680035A7703309E191A044031480D19B8A6A6CCCFF7AE2AD1804651FAE4A2971C28D03863F5960F31DFE57831653F09A7BBA185FD036DFE22C594D63342588422F1836F965150750C94F27B77085E49DC02E750275F6EE30EDA4A0CC30725884F8B563B9F7DC7F6B3C27F46298F8AED120F634755D1CE1CD2E2E5E3EBAE4BB5BC3527C6DD97DEED0FFB644053EDE8454BD55C3307A12DA90AC6940361C310C081F13BEDCF3EDDE165162E4E20B6E33201E3EB4E7D9307D5AE918F0015158A500E4E3EF914999EF073E34CAE6A1C483B84372E29E600ECD1CB69115119BCED399ACFBD65DC3049BE0377CB27A1670A76B8C162F7167B8ED59EFAE205BDB393374B8AA7D23010D475DA30331F5D63AC67D2E1AF8161CFEA4260ADAF702464837CEA071AED36A217A029F59E7F38BA9E1C1DDCEF91DC436F5F685AA0C2A1BF3F30EAB6B6E2F7D2E4E43ED72FB8782AB5B7DD91657613081D04959FD045AF83330EE67DE3D388B7B20787A5768D1BDD982F5B7615986172387CBB65DC3D6EBB1F08F9E05EA69415383F51BDB25A21ED4F8DABCF3BA769630FE0A421DD644B1971F56709BA1BEC4F69BDF336977122129EA64310792F7A48BBB12CDDAE504A179E3094964A8835B360ECAEEB01A834C383A1E726290BB2031242952FEB5A4C3A02C9106A66905DD6BC931DC245DCC48995BC1BE9F0264148D13A92C16FADEA763BB62DC71454FDF1170DBD696C34C3AED4D20DA0983C7ACFBEC2A87E0C45C2A1CD2445564B400105CCF9964EAA5B64CEE57412B70C0EEE991DC9E868F1BE1C254DD006E814ED5412B5BC7EB5F60D3881A4D36D5DEE5216DB93F2258F42F96E21B58B547FF72F93DD3D5228C2C17771ED77FABCBBAC14D2775C098A1CD66028A0E448BD33DF3189B10D9D7520B0E3ACA333B5F8551A3554CF140D2EEFD6E30CC1E900B5A2906D11CB8CCB35FBCEB3776573E86B9DCCC6B8DAC94959BF1969804CBD7990F664B517995093886D4606BB0" - }, - { - "tcId": 30, - "deferred": false, - "seed": "06C016CB8566F5B81F8457F56175AE77DD05C35EB37B687EAE89147DD7ED008D", - "pk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC3AF64CA232E59C2E1F4EC56A8C2AA886F2D5266B72B1717E9F83EB353089EBD02636BE7E2629D9128819E0E3B47C28F05AB0F06805BCCA20FE0BF1CA4DD2DABA5B9012D0D828A9F752074C5C40BA640237BF00E137DAB33468B4073B7DFDB9BB3F512E092916F137C77FA23152B1C1C6C0E7204DB7B0D0263401BE8474A54F00B6E8BBC5E596ADDD254FAA848224FA50551433BC786D063368ACD6D412D94B34C5E6067651F0356A30CAECAC274FF0C1A87117F589C41E6C7D62822F0DF036DA4A646406CD44780C0CE6A6C960D7523241861A9AFB5434F3C6A36F8C317FA267D0F1A25C1E4E5B62318D19C7DF5F2AF5A269205B638119D3479C692C611DF51D2D4CA3E68306FA2C8564532AEAB82F5AD8EBB33668028AB8CD97E8859EFAC229199B507995B1F96B3AC5683D00F3B44729A9710084B1069663552F64BCBC1EFF043F53FB1A689C6EC82FF5A0FE1C91978C52140B048B4A656FD535143D9E970172B28AD4B2D41E28EF62618D7C6E7B9504DE18F3F845A3FF291EFFC26564B2FA62E8D73788004E47899925B63712F211E707048BA59A9FBDB2079BA8C0E35CCDCE7009BB57E425C734A9A2430B32647603293D6E769E6BEB0448AF3AD30B6309AFAC2AC80E1BB5285B233A87BEEE427A02D983AA02D6261E92C7771DD297CE29C1597481E4D8B2BEFE04915DCF2A2F2391424BA449BC7F741B2AA0E8653F92B8A03310EE8D79E060212DFBDDE4D17BAD0F78C84F21DDE401B94318748994771D60C0C572C51FCCF8BC6F45F5D5556A827E8AE043127D7F2C948B45CCB5D9BE71AA6B02AF82DC2702BCBA3C8B970B0C6BDE654CEBC291EED77E1691852555E3C01E8F6F28537F1F20A9A175FDF01C333806011955B4DAE11D9EC8DFA9277C77F03172754EED071BE138D240785580F653CA8A21CE95C10152D9F82C1F50FDE555496EF081CA858BF719AB9BD245847EC23B6CD76175F94D26A72BFD150EF152D7D5C975EADC946472F2DD7A8EA557F9A197CD420928593F1A971A95C99FAF383B2786C3453892573F936FD4E58344E3577B062DDE2F58413787759A861AF09E94AD4EA06B37F818893093C76290FF0C96183412F0ABD94217D830BC21827D0F6B18747A8A31812364A8FB9988CD10CAC3BBB2A649C4D5614ABC022143716BA5351ACD138B2A06957F5CE978FEB935933119E2FB0A8965D0EC3C14ADBC82D37904E4AFEEC034CEE4031A3BA4EB3B1FD6033B45B4C35A5D309AC256DD9DDA40963C69BE485653EA7EDEBB8CFA20B422AA14DF1D5D91194490D8905740C8165F911D6A311C5CCD3B6E07CF46F0A9C57DBF4DC4A5382AD40460CEAC5F6EA9CE7C79F8B7064239123A5563D2C33C1C122F5B221CCDACF9D577576213267D6AF351F601B7D4C22B7956F363A42910D90A99CC77D4C858918007FE70865A6256C0A2C82821883627F2FE31798EB532D24317AF4818BDE315B82AE5ACD3E9B468F2AFB40EABEE4E05891D4A09709A409B0DB9A5A80F30906D99E9B67AECCFC8862B3E499B7CF7B77A2E79734B93724FDB0C35983DDDEF4B7476BA43EF8CCDD6E1E09B538E777E71BCF9ECFB6D26ED0846D58D2552BF2525242839D8DB26F82D9C6404695E1AAAD195D3D0F4E6F9795CCA693554DA5EFA82B3C773A04A526D4086CD1AEBBE609D55DD4A0CD49C2D5DBE590EB66B9B061639C524F01CCEAFB110361AE8C9D819220337F38B6512C68DA333CC2325EBD47C0BBACC9BA651D7F60B6E7AF1B8A04D3F64F4FA011EC5A15493A08F823AB7878684D9D6C1B23CCFD136EEE2203F6E7585F97E36E4DBBE652B4184BF6E761475C0AFFFA4A92E0FB139BD8D736AEBC10448FCD535598188B2DDB4D4DBF6D2662F769A9F55412B50D5ABE76339FE3E162FDCF3501AD9182C250AB14AB6ED95666D757BAE8486FC0633193CE3D3A3EC9BC8F29259BA6E8AC0F699037A172CBD5034DF788C3B9114C9A605A1F19D63ABE13DB3F4255BD1C7205E9A352825FF340D794C70FE5A641BDB47573C5C884A575D768F6AC5049083387B348C77BA6D11F506CED5FB296D23899DC35E3C13EB984B1B8874C8A5C333720162E4EEC1A43C77535A885C43DB98BAF15F0F07BF2C74858E3BED6EBEB210EEAFBCB2D771F8815B567DB720ECB17A1C675C1B014C365197D4ED8AD420D10F103D5069C83D0D2E39852AC777E0EDF6681EF4A048B3AD6F4B6134B7150E8B29D1B1B0FB69112E99185E513A7A05E470A5384956E6196B2D8B1018F7C2F876ACDC83763C390DC4A057073EBB972B89FFEF171459652B00DB20F0058FD0CCB8161FB0EDBC881B84ADBA66EC0FC5826A4128F45BB1ED48B5F6D7CC8D8418C43B444F60E7C9D8C2C1F04A3D86516AFFA6E418A4660ACB13390B44E7B17B7C63DAF2460F4C00E9EFCC531F2C1FD31E63336BCE51B89BD1E6B867ABEA8EDDB837D23B3B16FCCA05CDD2924E2A35802F55BD8AFBC8B96C50E55FAC219FBA35DD618F31C81ACFEDA2EEC25350898046106815713BAB9210D2A05A1B478170AFE4B3778E051375D021831371B16402F9BF9E137D55E4FEA29AA18C3AF0760F6C9C647D472EEA663B41FDF52F3832C8CE454E451B6E4DA179DD5DE087ADCE8DE05F2A5D5961ECCD6E362F76329A27AE77210D2330EC2AF69E5898805C8402CC41F2EDD9A2DF411FB8FC7EF0C7B590A1D751223C6D770B8E180635C3A7EE8", - "sk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC396F5787D5293F0AA21C1EF4982D6D92B03578807EE3B173529E67CDBC4592C01FE4C422355C1791E28132FFE128EE7400A82DDE9DC6C4A9A4446552457FC67014618934EC838799C91EC12872C9A7B41B56AE1B4F2D84E0A1C45E63613CF23B8143058026560631877225541240870755028612211601113257620730333171113133326014734054530822257254625481781338656606531637062386428216843125583177381435215743200728750178828264283858572338340174666155423803410245053881552033512106268217163576701115100151420758458254007203647278565678136022872018662578473315183258324430858168453864072542224242317055776525374818573571728183430228822052531150150563757546718458310706857665406856725636865568642212311532331480501803576035710033308324482566338724804414110081242517212343043345322274804530744840017770682328836674404578040172026160252354482574075878623707433412042010420315324686631430437621117246135145667012805637822015676733372011026256612787756404678851224687705061484330880505326284055581054124668286658020382004078761776361161527740048635207170416215413243527764483287008340567823406070005843544321560087377528537112747351413323761711545608265808303065815242428578631040654613162778428574137416806766647656885762514121044168162303486044752838523570078420858537671500835356333734424688301521706686448255386087425664222682810214243348461332478264228721251287155070578654184140476811887216103058536107683826460515064853244078875520430770825153374152041800752886860880705277852311445620558643661375387135831547560175412405304476660057527456133616354524282235243658540065376850627062681617338104541451788220635858838672766573864142370366455786746353087604586187606056712725063187712712448173850448611574436042456606878057101783345634527487132824126777640311332086444211084406665723663416404615362244124732217810466715618067505057624817681836341825188410360207772465666127650130242187521306645231253000028638486005737424660746138014572216528038511631376771854823406270830132667674806184712737536564845562848003181411682763004664515632264310472672641657307765353303431853146262328068560152456358001505514157483485470687546573587047517328521130710682881183360163073041784613833175275612544847536060656800117884142016825672787262425284372054865151236484576661230323038363486585601502573856284167732206132578258425346636431584100337878378274840833177664013564252244411184708104348334304276470112213147701405086214104113215886548778307185000683785205742088186133061432162674560501614305005453476872274532448663370472187828212621133266066680423603181222832354734806782474407505641561545776848377668885033003456617755578432240766407055388340333658406402462202510811201771475150833626185035600871018847510308042575856566110553231327801543061080331388054232227503550601672838252561463072541831582337012688050512015154818313653303778611543867346215811512217107581100031233816616052755553316276881007300046414722210544405685155425152663633145137786125875381612221375311321043307001662685838057425460185646272147556360106708043553528546214161058211015442016678886740618868527873410028761B9B238BADA333C6E82897B4A54AB928D97C4A87932DAEB797FA5D677E173B5BDDB92434B1676FF7B965AB309CA58ACCBF0A6CFAA4B0C0C917677C9414FA1E9230BE5F75CF5C63129C70C2046214904DA3C43B4DFDEC7562261C2856D1F86724673F89D790BB11B55623F5426106D2D5625CEA933459A75DC1A8DAA87D6000330112EEB17537734ADB71B349190A2A70FACB2F42CEDA5681691B6CA9DBA1B48A4AA72C1C7235BECF0170B8CBEA2833B25C064F320D8912FD8B5B30E4ADF2CB9AB32BD6D2A63DF5118B12C37460FF7E8F9D9830C51E36C7E725B1A8E1F52A94985BF1E5BE49DF468D46249F5C9B664A1BE2CA6444F8873A76813078E4DB1F05DFF8A8A66759F94FC117EA2B6415ADE0982B73C9BB8EC1116DAB7670F46518CBB729CC8EDFDF8DDE4E7DCC960F15E4B417F655A5FE1B69A1AF0DAE73EFF122A5E52907932CBA3930322622B00E35766E0D5C55F1B7995F5729C857EB80F2F109C3393F7251D45AF89D038A0F303A4C273A4FC38CAD50D3BADF909C4B8748C760D6688FCBDDEA1A1836FC133EE714874628E4611959291DCD686FB40693D398214B2C5CE4A0C88A2D9E6C1521F4FE425ADC889B8E237E90DB6D4DE8899CFB85EF1B61A31EE0C68F6D59E1CBC52EA02B4FB66C05FAE0B4E78A492B883A15806EC911F58ED3FE072E779DF0251771FCA6354B4972B21F5BEA540875EE1A72D2D8A3A9A1707D6B0F562CE6D045C9D925F88A709BE8C1933AE1EC9603F497A5013B4BA550C024C1DB116783FF1053A6BECA7393E4313F407316571C113004572F4A39346F2A67279218DFBF61BC7C7BD1052A3E38014F926496E5CC895C6412CBAA59771A01B5480027FE3431C6A09BD2DB91F62C35B19F0A92451167516E041F49DB672D99D71E1EC63B59A0BD8414EAFF6C351C4F7FC9B73DFB508C1A3C198F9DBE0155F57E89CA8546845BFD8D4BA6953BD5AC46C7C652911583D2ACD204B24B2A9850D6944A5B89A4FECAEF23387BB845E5ED9630F72E3A54B2DB5E6FB991AA77A4C2714AD041F6B88E5E013651488ACB4F74E327FCC55CA05491E8919701D597D1510C5B47460B9163B736713DF60DB65EFEF3E022C326ABA7D3A48ABF958F630F15EC8ED234BC829D7BB4F1E7F4FF512627713205B6451804E3167FE01B99BA0BADFB77C203046C750216852A4E7EAF44F97E24A5DC16245E738B5BC153B39F040488EDB47609FA698AE5F8F86BAA6B051BE56063C9EC478ACB41FB247A7349B9E8B1AA1B1E8F3351D2849AB1080E75BEB8C68E4CDA3F482C6F8FAB0AB67A916DFD2A98F5F22473D55FE31508A73A14A1035161714FB6D813EF94E25D1AC9F8FBFA3641C45F5AA2083AF05E31A458F8ADBA3A23E9C260D9EB3DD99FF4E6A5AC63A529D0F09BF70C9FC9E4092510655AAC4F6C07BDDB7B6BB4113E66F843C0826BCEADE05C0F06CF3E93959B9F0256E3EC12CD2B5D45527F1A99C2D51AEB9FF19E9B0C4B33EBC7F689127C5074A39D5CF78E7F5433279DC235749EB8A1242CF4534643137796DEE5B74647087282241FD91F01613606517F852ACB9B6E7FFD2B64DB930F7459A47A4FB74EF9280768E7C427129BC6C488459C023B06CCC997FCAB04BFC0A012BBA03FCF13A38C225366B948C8874E5E958AC64E68DF8EF055D071AE59ADF52ED94E2F83EEB207D9630FE28FEE8E78B41B1B46A1673E6EEE92FFD61C9ABF92C5507B183DCC30A239D3998D7BC2ED70E6A2024D18D26191F47EBFFD7B5535A871A9071481725EDA4312C59207B90188146F6F22D0C25DED8F0FBEEC69C2F7438891451C366F1014F4410EA91491B77569EEBB61C9BB500150F42C3586B37C39836D7CAA54CE6CADD9880EDEF79EAAB352131AB1A9A9E61732F74B20B5B438411EC812EBCF717A07CBE0FCC2C5D70BB46A741E0DD7E2B97297310AD0281CFD683565B40D7DB04C47D34ECEF6FF88965B4D858564533E3A6E6744E84BA84B250880FEB8E88E748ADB8B545AA0255FFC70574CE9ACACE6FA948D4307EEA22F4B21711DA0276A64365F00F23A15827D16DD172B33CD1500D59F6A093E787FB38ED23E3AD1F2CC5D2FA18043FBDEE30108D1E9D2BCF53488BCBE02E7979DB238B079E88D90175E922127A7C6CD6B72B87AF752522CE2C0D6E766416CFB97930AAAD9FCE7F6BE37B3BBD1E6D4F6759265974B5AB9F6BCC1BAFE0F3D9810067E2F1ABBDDF421A21A22CDA9AC3123BC479FF33DABFDD5C6F49E139FB05B0B7A5DD024B2725996FB0AF19DB7FB1462B7C551CC2A7DEBE3CFEB95170381A407849D0E0CC9E11089EC05E2E898EB2456044BEF899F24629B311363521208B1EBA36F8A619DE49FC20AC474FACB7AB2318491F72E26C7FB9E0C387DA35DD7869D82134A9C61919C16790ED81F07FDE26C56E5ADC9E0803B260CD0B85391293DEBDA809F61B781C79C252E03EA43026521BC435E47842D24B711CB5F75C6E12E2B10BE53E09EBDB5759291F4887350FF986A16862DEBD9F262C8FBE71E2F106781F8DC94BD7E3F89DE77893B3853146F1FC5265870F713557CE2E514B92AB652BAE9E758F4ADCB8399EF0BACD87231BE1A84FFD58F4B6CCA555EFCE7F70C6E18D1CE8380EEC6DC8D34A41383B97A7B2694E8FBB09AE1EA9976CB1423418A9C13603AA67D167C7DE85481CE58EF553D9C3781A795B6022C1C00B119256547091F4B5A334016DDEA662540AB95882C608BF370513E1D041463AFBA71AA2086EA700061474FDEB1229A50E89BC1294CAA0F892E93C2257925AF7F18F9D28EA8D8419AD1121A6D8097E048C82FBD885EC3EB14E90DC59FB365C30C12C427CC9205E56CC1FE60CB6758E351440F4EDEEFCC35BDF6BCEDF4A4E2C1C68A70ED0FFEAF5A03D4DB22DEDCEE8DA1F7B6B37046EC3279DC9573E128F51BFE42285D8E64CE98836D6C80F470C64048CBDE71C10DA83556803DA4671323739FC4BA80278F2959D1C43E59105C3A398B8DC626FD58377373CEBB033FE1211F05583EE5F4AE3283780C682056BC77C7855AC186C1703B8F5CA6BD50735C1C5369EC4E180BD5430A5E33108E1547914D3C0B7EDB6AD734EB3022355F9327A23BFD535124AEDD1CC9A36BA514E91785B36695795462F5C4BA58660313B1023B075812239A12320787C5C6721304651BA9F269F1E5656A875C8EEA9E782EB912D52EB43F622A6D770F3201CDF2A5C20CE6A1D1945C5A93CC6C65A2A7627E42622B7954625D0CF8EC441C16B04DF7602F52CAD75BEE96403BBBAEA1B102A60D4AA3FCF4D5F8208A30E821EA585A130EA928E74BFCDC435BDE8AE646841BFA7A535FEA5FE89510B96B33C7A3002C442E311A45A1147F705E1E73962DA730CACF5C94A10286EFBD3A7CAB12AC574ACEBB4DF64253F387FBE4036F9330DC3670AF3D5C5E5D39E9D527859CA6CB8CC47833BAC8A07F80CAF9DB40D927CF6B2F88D4F8FE74E0DC4200854045B4E7BEAA849D23A7FAC82CC7DE0FDDABF825B720777A4FC2B4FD7BD65549F156A8AE" - }, - { - "tcId": 31, - "deferred": false, - "seed": "AF5A2ECF442AF8C0371F89C499ABC337021992F221C1D3A66B551DEC917F1B1A", - "pk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA13802B4AAFE16A2BC444D2F77A328CF9839DA78E4138842050AF64AD2D071B941A5C525C66A5CB33C4061626386EB5BD8586A4A7D3598BCFA9367D58BF650006F07754F6820D7B43B312E6A4B7A3C19E870D34D80372F54BC43EB93BF58AB87ADE1ADDB21F3DBB7CE2C3A6A39A89D3E1EA741A6C74D8ACE6BF37E97578DA064195161D174602AE8EAB65C8DE1D33896F3FA4A3181A5D6E75B5B718D3D8E36F39C54361FDE078E2286759A322BA97AFD217B72517B3F1397CE10960726700173783865AC596B47B6B8BBDB8D6B64D4CF8CB7ACD5C58DA9AD194D15E849D96CC51268C288EAA6133B8567607215778012FE046BAFCD663D2FDB47101C02326A475C2DC8DFBAB87790A11CE0B672F41E102980E7039E07B52267DC7B7F46AA07CDB42B65BF9E7580C16C05E50AD305CB0E4D68EBD4B92980EBC978E67CC115422391489E1C067BDF627F78F512C77DA348BF38BCFB89CA9053317D3C7B3CD1FBFC2793A367D367EF412454863B00C6782EB813A59B0E46F4D653F2711E225807D59D5398A12D57653193B951B25AED9811A983734C5521F068C1DBE1E008088A81C88A7FDE81D8A44A219C987CECF76E1A1849443E17F07C2B56A6CDC36FF4D9F30F4AEA525853532710E21EC5DC16C24D1276C11B36C328A5D4AF570D6C9DC7820258A71E1D5EE4B0548B49AEC9C21CCB5C2FADC7C9BAD23D8DC8B746FFB82CD78E327BEA707968C82FFF2DB878AC9810015A9D88493DD6FEE55A5FB18A35B595D7A4833EDC7114ED47DD87D5CD236533B60D732CF6A24D27ED0B68DC9136B276CEB4FC918A87C1B410CEF13D062763C54735C267694D07E6BA17D66F88CA7A3B082492BA8F4AFFAA66945F7B5AB62BC5777C443DB0E7F84F2E6756087A5634EA81DB361A78409386F569F898FD257C9307C9FCABC5BA0E391A012DA3E65101492A7FA9D5CADA36F0D613C1CA3C1BB57E9F6165C06934EC1859D13A1C3888178087106C6F4F1FC46A10FD4A9F1E5D83165C97B7D1D71A9E09B1D8101058739499342FA5291112409B93953B989FA7E68B733AACF0927EFD4302572052CF508D3FD9AA1EFFE53B4D57B22CA8E9ED9F0C06102F47BA853AD5E4E01501B6E77E31F2010F7813F339F01BD0F43C3F300B15D36AD32CFD7AFE8C786185AC8773E0F30A8CEA310D24B7CD068872FAB88120A24448637182F477AE10473BD3653FE453002CBAE148AF0C6C4DD1034AD15843AD2A83795090B1C738DF100BA32199D0CC01D3FF7844C524973B652156257BEDC07A533C0F1083827B24C3D77DF19F07249C8523F7DD350E75EF3509B99B77ADFF5CDDBBA4FDFF0BC89A3F2AD2C2EE8137B0EF847B4B879EDD39E299CC205E5E79995D80DC8D67EFB93AE3D6318C2FF67F8C31EB39818ABD6B3FA0F2C6D6646E9795D5727458EA5918FFA9A62E7528028403EE1F34213588411E691672DC1989EE929F69FFC1A87EB72219577E24D3F31E8013CACF03F8600490C84CF2348E10D4B1DA72573A9F4AD9156B3FFAF41B104FED8204E64A51353F47904B42DBC4311520E3951A45E2C1373F206D558E0AA127C400CDED08D087734E52FAD8366D786622A62A617A3A6CE792618837C635F60C45608110F191912D3584FF51D84C35340B9B5B3B9C94D6234E17E7B3A0FC76B48B34DB6409B0353B4245E21A15253D03EE89FC1C25DA0AB260ECF9994FA14EE59EE88048C12CEAF3E28D1E0208BC09F4E173FDCF0CB4D985913D093B6A37A3B1AF4989948B979446E89D24B121F4EE30A3BD9611D698B1B4B9F652724BC80B2AAB623727574485377C20E9621F3F5BEABA3943B61D4938238509A327EC910C4C91DDBF0B4A648B1F621DEA766217BD65AD8A628A39F28071B741CB1276620A2C55D975B1C2C56F6E81BB57B284AD1D6985A204478FF3A4E849F5B0FEE7B428C058D1D393C90F436D772FC7B8F9B9DCF2052E275F917E888FCB7E2916D48FC51E93AF143CCF0BE2ABBC05BF10577D769AC2706177D5919F5AF6DE12E99B3D9F09952230B036E3BEF89B20B235B9E250A02D4CDB9D14551ECDD5C5B0669EE409EE6654A9223F24C8A1FC4BE88C993F8BF25D783C79087BC66C00EC0664F33051B18BC2873B997B15A38A2C7E8B904C00170B5E9874DA8F50B76490D0F1649134107BD2ACD3717B5D5474B49BDE361DED36EB52A0132BCF5EDAFC82AD33618B77F3A382BC32624D39A6732522E4CCC05BFEC4B8A0AF5AC143C3A403BD5F14BFA86A71A85EDF5EEFFBD081C99C221355D5A1657A45370C5815ED7799BE3308A774746878309180DA20792943ACD1D30137DB52DC46E39563E1370C4EB09577FF3D58D1DB81DE0C7241DD1AB6254362FDE4850719D5B57B237882CAEFDA260CE190536AEED81503F2D7713D62C8E6DCC668EF5E8EF6DA38BD71C2E0E2B93D66E1406A8930D36376832A1621B1BA35A7CD1F572AE2A795FAB0787ABC98EA6BD6089D9F02EC071205B603F988BCA2E327D70259F08C6D57DB635B740BDEE9DB47658426ACA91A2A40EC65FE7171B1D8053F05883EC08C8484E599B2EF851C330471F78C0A8819154BE4770401B7A309ACEC2C412F3DAB3C89EAE5DB44B9D4AFF661D47AAEF05E63DDC8C4AD2BCD6A7F32C6685D69D97D28DB01EDA78B988B974D275CA566ED69ADDF84F34E5A7CD4E57A95E19E73ACBDCE88C33242A932F2945F2096ED0688D31", - "sk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA138013C48B3CEC2477128AA4F1138D64C065E4AE6F90825B8883A318E3C0E57D79608872D8B10C822DAA41CFF163BD1BDBF8F00E9422BAB08E519A346A00559FE33C1937B0006E751D8E89206D6BC60CF86C989CEDC6A650A9D8CDD7A885A5D5959750448826460188004101125111186074620576284254126602486514650254327504054426658404637850147516850678005764401755744635128034716451535421171000447534622142286762007017285656210134675821180311780513280388413616213558436053280311820410525136513060540160781021887535516157262345448444784701867043127643363865707424667300015652134858161472800247384008538765723005036486454028675180110070100585227018422187630788540325626225188813123884672141516606825703365081484622675274186476437010486026151361553084613341471802783747425386776481227074016862284216366468674776440845680570115565427708841053204705545428355530152603721866522350763826432546480520011000217246455705043270634768453003815312660206530127032003278361545060180436455308127725487262482742654007210440273753502818225888755041314584755808333558051776484568406766162183053205233717482617042441680463342553134108652603646478047082474478071810434283471763142724425102083470712525401031116854048436637142716444771867644085821750556353854203622388308758477100636263240477537720385175337344211355475034614513544055425640506651668811324364614815740531827808364780478544043850587041437810503082400163542252323515405157863646838612144458502587220415731546766633753238104428464045120204231781335071761541014428403711427277077374826708330641275013578628428874500743644104623670603744818368054481625408140001614207775166058635432827321472400672317435015252346535680281888151477005612260638815080663703827487130616081186003343810854681567106141615804734621383114175553858354054073406806336125653830065280187374320341007765836446711861021424842660758755784704122132480132102238862510143518701447661211335031546207621450714706100313847443215510114355878185523877811720703570726544284774414545134241257007847220580113313158613736252646822524660278672558356438724635513883380417860673588850524465417657131258443717224832306011153434405086734832734238855846814657087130365072151474425107710001447436647300443625157617824024324281003277361345864124855547568664642638575406011371083735120870107051813268152180133151542028272641804564120630702784343172240455064040414206576102854172281178857284212558163858228783344551685467747877225614622512371447002823523287806683488140720812213887102060221860281611143315388888484862187875060500504384547208612234821708336400356848478172006063423822373324570772060541305847652773286164648028265165301157086073527525123782386608802465083320180637434353766062137470236812473248565115246843013483416800782261353501433487770254236463403451508568564101825531344410267156466015063128101007831428421211188415154723111285433565758007356644774022346717041065367152658860424264228021125381712078461548403462250318848437146704741046774408631383441511034835475844544150855632038827538235253151753601010467407471214815105021732547307206305612530887784636307521185FEF35B7E37D1212C06AD85C4AB401622C11D1DCB7BA0A9F7552B03D3F263D4A66A0986F2EEC297734A9D60561FB3C8129C37A3BA600C75F4365911F47D8DE507165F9C6C79DB19992779F091115BE1569F4237446174C11B193532C716BFD2AB84BAE3852ACEC911DDD3C0895040BFD0587F898B70E09E71E1C8CF9BBE4580F17AB55CCEF554ED6745F46455862B00EAC4F3CA7EB66FBCAE117D94003C1DF2A43CB4BD00A4CBBFD252B0B6956A61893F022F0709000ABF488D366A1FF501C32E1F3EB787728672ACE02A5F6D2A40D734592A8BBCF5EC8111DB6DF677A6D0E01006EB862FF074377799C7560E983FEB4C382F89DEDAF21D5B2A39EAFABDEA4C3693B63D0D1B121886E5C3EDBC109FC0D412A548567CF467EF10830098EFD8A010038236B05DEB89D1D36664FDA3476C5EB93D71BE938250D307E5D9B42DD6EF72188A2FE5B408518DCE4A36EC95C4C1E23E73827DBF9AEFCB93C8B5DF3D281EEB9BBFEC3B29C29AF773433F3DD11ECD5CC94C0E9B58F96315BB12DC9C7F43FD1A148F1F95BF7F10ECDCA26EC30515249869E2C73B976499E14628090203FCDEEBF7ED6B91F6BC99A8B346421E991BC5B2E938D73D04B93413B870DFD517E6DA6EB8A94EAC931B83A68BB40482AD982ABD87DDF0F32EEE6699FBF7679205006B6D103432C9AC032FB18AC75A1AED57F37E28F3188D143340666677A1F9F6F5F7FFBF777D593BBBE243999F24172D2F74305F082DE10517528C0DE33F4DF1D4CE360EBBDC1FE3EFBAAC2E2E573D2AAE42F0535DF07B6A2808A5960A911D6F04B87B15731BF08A394DF18A7E2A9F9738305DAC46C5C0B8054F8B06E9C4F846A0E49B8D194DDACFE9478D0D08074B7C27E5FB13E9A8B6A7AC3C85717E39870825AAA1853DE322A904455A9C42DA9D8D6C0254C943E5978899C6CD910E7FFA2F666DF2864CF0CF668AE1CA8B062ABE1DA95132721921ABE689DA865DD04EBC092BF2AA2FFF57DA38DDE2FD9DF29E48D2049C61D7E506D9E5B0026900B80A9559FC6745A794F5264794EAA738A56829350EA9ADE450C2786CC6D51D74A8F8C8FA724B4458CBD35C71D02FF49E09997D6CF57E3E0B3EA3EDBAD9AA594D69355A501B09873B433997FB9FB03EDF9ACEF14486C491D4543B6D22C20F5B82DCB757AA7CE5A58B6644F45DB334622FAE70D4BB957CF1365BF1DF8457AC1A6116D50179B9F4DE05367B0313463982AA2177F9E66986EC007A6EFBBCBF6A7DBBDA21536246EE27A125C40F42399A56935AB1D52CD64B66D79DBF26AF291EEE29FB7D2FE6B07DFC2768B62756671AFF32BF43AC85A36E62BDE7F8364FFAC0BB74E43B4620C18E308C6694EE8F6656ECF25157BE214C498DD7EEC3CE6C8CDEC15F90DA71BFDAF7E35FF79C10CF28BD2B4E6CC5B006D8892BB49F3A1AF40ED845AF81F7EE9D26D6199DD628F0A1A0965760FE30E6C3B00C3ADD14C6484664D640933ABEEDF8AFD38E4BAC598353ED16CF66ABE9A27156A16743036D0FDADA91563013CB4577F691075FD5827796531D3C3B4219E904C08418F3B05D699550F9B6A42A2274A07D3BB00A1C127869BA20DA27B494904737EA8D06C75C26C74E745680BBF20713CF7DF7F800CB9393A6EA984AB452D8472AA18FB9B77E1EA98E2B949E78E7DD5B136DB996FE57493669A063275131A7C1207E7110E4620569C51B5DA00E6ABFC839F3A301B65F6EE92EA148F631FECCDABB60E6C64A3D1A03AD1FF48F540D0212E6F49C283E19B805040FF74EF6982FAE0FB8BC3B4BC123405EC37DF7A76A7F90522017702DC629A4D4CDC38EEC96B786B7E1C7A8BD559D28CA2782618F771A02D6AE77C64B0340F1205F2AD0AB202AEF7BA2908DEF8FBE78848AAF2A7FF551FA952D0BC58581A9C95C7A2BFAB8DA745DE41A694425BEB6DF3652DEB5325D0A42E5F2795BAEEF5B76261A1DD5C836843B50BFF75F53CBE0094AF351990E3B3AEC21A7EB5341EB652EF5EA8D8E6DB9EA862E1807531ECD0C0BE38A51282B8FC579D8FCBAC82E49691FAD4B45364F280D7BAD3902E745A16A94929870DE881207DBF076691A7AE81A66BA6CED9FB349A466935BB34028EF6C30A03C0E68AB4C39C129FFA85379152013245388984808C56185C779510ED716006F4B014778A5706D4B8D02496EF7C47D3CAF14C980BDD48BE3D37AFE25BE1B6D18E131D88FC1043AECB1CAC973707F61CA8610A107793C796F87F40F67AD15A6B2E84CE6C8E6C58EA2113FFBA3EE77D357322AEEEA80BE8E6B2FD7F52C8689AAEBEC7203C56F6DDDE1B2E29AA4CC6034A9F2DD07DA138B21285F075FE2FFC8329F5E8BE9D82F4762CBB746CC7F327FD21720B74FD3DAC57B8786299F49C6C602C7956ADF6BF661594CC5E90F4DA73AD1305FB1B554DD4DA00AED39BF0EE6FFADB87F427095E10EBB336B7036FA99FFC21CDA513AC77DB20998DCC3156AB73991A158E9136A688B70C85048F09EC38B6691FC708B53B9B6E520AC55A48F7D50F3C863EEEE841D984C75444105937FFD6B3ADB67B48E7342323856C636DE826209FA66411AC5605EC7F7F255FBF88B236AB77B2763F25155265411C74271B5B8A5B835A019CFF0BC55233EF268AAB76B4E9859538E90E818E6F660CDC4AE93906DA2A5E80DF4B1D5E0FF92243BE91418D5E3FDCE6B50D2727948D2559994C2C40A5FC27CDDC97D1EA18194DD3974325E8650DE63DB2977B824D7354F5C90E91A2950E69F4F628535D2C7BC994FA6F175B31B7EDB3CAE4D259BF6477EECEEAD8178D6C67D44D6C4DE1EC3E5C09AE82B40C65E181F0A70F10199322A7CB53FF2BADF4FD53733E5760B2770AC53EC62E25A9B82C3B14DA51F746D6AE4CF7713AE33ADD9ADC97DDE11552AE2D9A75455F97CEEF197DAF5F83DAD6B96E22773E4B0A1EE2C4916E9C07C0931DDBDBB251F3135C979AC8B81BC76AA46BF932EBBEAE2303E35E723B7C90C48B61811B210001564D4B9A58D18C46E58B33D70251699500854BDA27C1F58DF5FF692B138C1E8A42504D83369BEEF19CF466DC78A9FB69FDD283BED6E70E89693A083E577F628C099AE38065D38FC2FA9CE5AF0289AD653A3C4658CD7A65784F9935CA396451990CC56064933D7A52A5A047BF87C551A842F5BFC0D29F21DA27C40771B86C310B7345B5A9E29F99960E795500947958ABC2A22A166AFCF6F60A4564E5B00E3955318AF13E10F79268992D58A73C3C17D739B2B1F3ABEEB1EDC560C2E25C846C31BB644D4E3F24A07E7FB23506DB4D8FBDBFCFF61FEB010A02C004F33B39D99EB602035B190950E5F0AFF31DB5B603B1D578E054AF0CDC324E2D4AC1753EE363AC120BB50B70FCA0E7A9A30569A701C7723CEE90B3E25299D35EC97EE34A8794D730BA79F249D7366BEA5B6AFEC2B3071343198B3077A3290957F89DA865C1013D80A3B1CE9A09B282F989218DF94F15F675A65DAB79840EFE887AC9A15CC16F1C075E6C7941812A77CC8938BC46FD8621DCF20310FEE350EBF4C07DFE758" - }, - { - "tcId": 32, - "deferred": false, - "seed": "D85D7C2928288CD0B90D7269619F8D8B4EB3541F7E084CDE0E39CEFFECE9AF80", - "pk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18AF77A88253C8892F6EBFECE56F0433C3E0D5500CB944BDCF554EEFFFCDF172CE264916F22B21D87FF3ECB966F0BA2D34A36C726537ABFBE2EAF279D740B4AFC1D4AF798EE5212C7B6AD63E0B14A10AD15C405F2C159CD98FB38DF453448473CB86634080F983B1309134427B95C48CE4D80933A4E8C20969AE50D31B087C3AF9E2E5F189B5E92221C7A699B2874BA12319FD27F1A96BFCB603752C24B89E02EA863C80E5D5B906F5AD17F8812FC928BFB27C168D87348287C6112BF1C48569C719C20586BD825FC4C8CC214C8B8ACEBE8C305255B078035919D22683A3CFCA6CC1B02EA3327DA2483791EBCAC9F1884CA45F16FC2086169856819AC7F73EE4BF3D1FB334AB587942021FACE990AC71EC9C938AD8F9DA7873BB98C195FA477E6D66815264068B2267800E7036E955DFCA260102D9DD90849A603F2504CC142E3C0FE2744BBF908674370FEF10374554D090C039E78558F178412F65C59336E8D5351AD74D4BEB2E82C1423AB672B58E9D27B3DB4A39CA733BC6F556AD171B5302A9D93A194296AE78F4B3591D85CCFA3E75BDC7D59A080CC9C42004C3DFAA70492F2019213B72837234783A11F1CB88D6A0E35C1CE3D4B8AAD793FB0E16F10B32DB641DF8452583C8059270FAA562A0A94D250304FA03F6C445EC45F6F5EE7E1CA89881108503FE71182466833FD09E6229AC09CF285E86D2F755DDD58E6E0B4250898ABDE89C802B7F1D8960D74FB9912D156B81A4E9C9D3DC052DCA9045E0B666A85AD6F334E4EE090014C3B2D23E902757DBF78FC382AEDC9F2EA122A582CA90907C1BB3987AC70E353FD45A3F819931E53FA1ABB705F2D143065CE7BE38AB8144DFE1248B9B69C2367D377BE5588DACBE8B572540A0E6585EFC801E4B03786AAD9592064459DFCCC3583132DB9A8A500A87684981B121B6635D5DF056539DFB063BAF1B3486A4CF80AF43E828B8C1A1B41C9822475048C91281D206E056BDC06B1B8865ED92FA5286F6BBC00014A4F3F28A2C47A609AA667174BD0EC308876F0043193F68E3067279AE809CAE4DF6029CE44F836AD611B27DC35DA4295F1126903E681F5A97239F08A2594768A91D01374C403243283EA763F4D23C530CC383A6E532D70F9B02C64847394C44285C20591DDC84EA24581DA5D98FB248BFAE3E66E20233893F89D50320E74473A1045E0C2A540F0797456C6C121B3D2F5BB94809C0FEBE8FFAB8D9FEC020ED5979685B9191BF509592F1C1D98D3EAAFB0FC551AEBCD53DAAEF10B997A46C593C0BCB3605F58B8847AA9DCA8A04F3CD980825F8B61055253C4DE89D225F7907D9D0D3E9D5BA1E3AB13C3E3AD89BA579B28F7D11FF0C757DBB8C1653C1C28F39649CB19AD2CAD524FFBC21FBBE58A4CFC367BCA0863175567BFA73A681948C462AA0D7146307988E3903C9971A81BEABBEF66AD382B69EA297B80422B480F0872CC00BAB0FACCBA788941D4374FDFDD56419B6031A1DB23A5A4A7BB0B363366AC5DF5A75A72BD9DD57069074E3AADE3D154ADD4743225564BABE2E68B1E0028392E23A3A4B8E1ADEBF4661F64191DC9F46DA8FCD5B769C06B8349C1C25090A29EA254D9CB9537662D339108D5B8C7D5D2B81524ABDCA3B2C5F18EB38F2751062CB30FAD5886D287E968CE885AC1631380DB84A304C5ABD351F78261E2A4F42A9A175B87752485C984936831A7B8012746FBDDCFBFA2BDC0DB4FCD0B79F7E652E5D402AA7B640EEAF8D607AB02021DBD0920EE6188ACE856EB0298F6C2DDEFC46B4D5A38D4B8AB9EF29065499A0A83D5F319C634E281F54C7519235AEF1DB1963D436E0173CA7A7FAE1B54303067D95D33EA9A25A94A490C55634CF4628061A864FA25E6E22E2E6FD7D733B0D1996C4E47190BBAF6E4578A81B7A1704CFA07951F61D8023AB3F1C5E173785F974D53ACF35B3C66A99634D2DC3A8C404247A51134D41A2161C4A3D0E4251B0579A9FDF7B3A7FED59637BD9F8A68AC98BD5B1009BAF290EF5117D6FAF7C8DD87BFC21FA226A9B0126F35BE6694D507695FDDBC48528C104DFB00662DE32E79E0C132FF9C08FB5EE336C98A93F7115171B6C2B3269E3AF5690241A66645E96799ABB45BA96CA3F558E293681A28066504F3B70943C99A465925906FA7CF3B820988DB0356AEEC8C9132BA78D212A33576524812CE85DCA2817B3364D68670EE07329980CDA3E39D88A8ED2199D55F5558CF7B817739E618D9405BE4B8427A3793D8DDF359F19A9FF09B2E2BEC22CA7DB34F2B22D88DF8CC728F5DFD167294CD22B144788C97CCB5D93361E6B74B072191BDFF77A6FA78F3220A47924A3D04948FFEB146838006F58239496E4EAF29C66ADFCE9724090FACBDE3951C053F42F34F764EC61A1D3A8A113CE2D5209A071BEA934101A571797F5C1C0194B9C1FC3B6599AC9C4790D83F55BC1875347F3607BAFAFC4DF2701DC07B68030A693BE88DF3C0372707318402801BB20CE414795D7F250053D0AC39C75FB68EF64EB419FF859D89A3C86C879CFECE9BAE38941F2307C920F1AE48C3DF72487AAE2BC63FBC20F165DD1C22091392D43EABAE0A6C4FDB3824E48548310526AD7A74E4EE6D73BEEBF13EDB38A59D7232E14A3778DF9DE871596C32F0546A16FBA37C16295B69EE997641791C7F3D5777F09AF55EA3F65314D27785810371470FA5617CF2AE06818318A0277474984", - "sk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18EF9BC3E4CA859E29C9AE87D9F6ABCAA84A84B20DE0894F37538E4133F557BE79C5075909BBDE7F5D579760FC0E58AB046E437DE6407CFED9CE5DD4D5E29AB04DAA70EB9EBB4D9F8AF32E0F7827F8D21BF738584C05D72BF4849F86A939718E8758445758814405066377236336162422838141762541276638856732360636423606651537874070450512230825442745831855684586351301333083575603024146601761737864228634768611208800655885828450737877205363001110217403351766632673281486707612045613182023667776367266083085712334830625737734852167672546845358411430645183583205065515383430563752021515024067500252010305132523852061423631568837802262668835487215855713274656266553465801348565243281764238745587354847434233833785336228853521530475450885388486887835421722800658106572655224626170632788231534531055663633012723460285353506035756252730815271414513036013604238484541566535734773380388840006280582113173886805271424366177715072681663764401431567346132851240273782202733172167802164088384310178216148840587511022757608251252064470305511284744230376254058476377274278086212488134263172827505611528825772601057638282760062084248067366371506358270582646651731160837361726605566053122200085235782558202084671262280830376814326676177807216075382173587246317674115285874745625236467814027788077336464042438520155042207346565724471747218387263118251375556767004053380182005875423780068363181661642242542646383023783342543587832154174778867365514222838388050642140134550860437148533084783344668707368431437015074670186306765104170870588047846213541524414736145150241215537864250374007845472700883417116237873657100750277242403235832704882353311545437405684075044150771571660005121055388384687305874147352600277663431646864700661301872840663534130204184605151861678802848543043027112104621511332255801120370470314425616558471472110733484223773623516535806637808681554467580118184582804154876801541184062762533732181015884585322680581165844687268617606655544276240638067611886232388527868508066182130307666322465628720528384531681113858304217150642806020144620080026852272610816183175145551704480131107232330465767126775852210875576883641346622737681600741174706303221251408630641587163003138713755442054141327080413822046600263640713611635310468722133311135012064031401143771510032260820885658416866680820730365314128654311255766615845301470057467310803472744450477206372254274621747370402131043815278774511034112778031445315048801015187323248127122555821044371482802710874843188101116516365815731456515676384256760350158471615247286366525363544813275860301445876074135438836883327838320860533654243487313251171802278742026065607171267878685588702652134688634745721733478005842454053488684540346456381110877324404284677613573082782065301706732632677347535583500558363725728148105342685468251370277036362661674818553152823343661441735136803538852043417412770322111347850373120404206488162576682561408525683855506861223536747512321018852123356208573123754682321451266335483743432708612575374514747037003725505244127842514108713422352781075135017606254307364886354437140385584416227381884E738DF38784D80AFE74520CBE851F26E4100D19105EB33B399D0F6165349133CE404E2030F5CAC75974179AFABD7E4D86FDE3830B6B1BE3E413814A2A06DE211380DC4FCA05B008125D64A4443FF3663725BC63345E388CFEDC27F2EE4C8F8085870C29E360B3A695C984A30C63511E479ABA406A782A2EEFFB4B6D787F867C45D1F6EBED522C852AE8FA4A561906B019A62E654DEA793EA955C6DA7ECF03261947EEF8FBA2C47BFD27A3314B46FA227D0D2798CDC22BEFAC39CD11BF0DB030A68A9CB8C33E7890BCA2AF77CFED475871FA7617E98C86A5FF711B1A4F6A68D2D29423AB4A9C7C9844F93E90F3118DD81198708A1AF8017B7B8178EE2117AFE34A2847A97592B9BA517A1A54FE7CF4BA360B62A1DAEA0FA6ACCCC1E588C46129F8F0BE8123C8215DCA2091E8227746F62C7FBD2E0C4EEF88497C185CC912436F45A64724175EEE4FEC4605B792E336E3D457BF1891C79C9737153C9339544D59BE170FC0508D96002A7C70E2A2E826F59EB661EE644F1FDC88469D851A9A5114787EA6C29A3C583A3F15D32FC93E0FD8D725D2257B8151CC001E681A51E05E26BD4FB60E39E2EDC1F6CA39E7E55F8FE1B24CB959B44A55268932E7DC18B5D80E97182AE3E1042BCC32CB57FA5648DD6C8053AF7FB0CD6FBA70BEE596D9141AC92D626FE36186772D75537BD37FF20BF97881DDB831E9B3D1CCFE9BFA5B8E5A52DD3703E5E11459C17DB76DC12BFA716458E1F0245C9B177E341E3FC113AE2B827544BAABBA5DDEFE017CB3098BA6448AD135FB0AF73B42090FBC3968E9802BBBE9C6162BCE1F76CD5516FD323B415ECF937E97CA231A64B7E587E33402947A9D51CFF658FB63B529FAFCE3A6A5CCCD13DBC3A24C08F6ED0D2B218571340C716C4130925D9D0307645633CFC52E6C38FC41215D367F414C5C123B1AA87DEE2D91E5980BE6B2D1FC9F46AABDECD0A7C189803E287CDEED22C683ABF3D4A9E1925B2561BD880CDB1B92E2A1C6AA4C33EA39A06FE4F358B73A87E935713745FB8632CB52DA1E46DC009BED11FBADB6B917026134529A72340B2BFFEC7184B0EE9E5CE7558AF7EED869C884448DC3F7FE694F1529EC766EA9B5E212FA217AB0D6CA1F6F99B4DBC7F62DECACE5FF9F9197EA29CB99D3ACD62AD709ADB2399CAB425AD994DA40CA7BE048BBA952E7E0C9E41EEBED32E0A4DE84DEECFCDCCAC70F270FEA91BD399D24A9E0EA318888C3D059C7230F5E8BCB616EF8D372F34345F478250512E313A828143B4596892F19818DAD08BA3CE4F8A57FB343EE0B7A750FB19F7C598609B6EB01EC54C571A907411D72D5E04EBE8FA14574622764D7B1C087FEC221F1ABA307F8E9316DB1D5E843526657639E60FBB7A8A1707656F1E6FFD50D0A2B6C900462A2A93235151B6D3EB32F75798147D69CB2D55D48C48F68DA83B578A8DCAE89C480520DF326CDE6C92367D373E473FBFFDC81054E8BDC470690B1DF0935A77F004231476FF2D6A47DB802593AF5CD584ECA26AEF41E6D8C94C552481790F6EBD50D48C142F575E3B5CB5B3B9C01EE818BBABDC9324E5E88A842AD90743771E4B542D468F7623EF77BC0F330A71CE2F5F093E3EE3B4F0DFAA56088DDF128AE9953B0A5AA1264DFCAF098E43C77D5A2C4BAEA68CB34507BAB46C516B06F7DD0E9FAEC5BAEF6000FF918E53D15E4D8FE7828720F8608BF2DD2BDDE7062F4ED9DA5C547EE0DC2B1F4B9035E1643D5A9868ED871DF630A007E1AB95B8A2D42ECB35C6059E162B7E2A04CAE5BF1911C1D01508B96413E4DCBA4CA62BEF8AE8613434621EAD3A9C5EA09F170EC59F7E276B669E4E133DB5A3E49EE89C98D3223DDC2FD36C2F14C03D51300991D3EB9AE3E432C6119AE978302BE54052BC4871EEBF247A79EF131E39ADE8020C61BB07D065672FC3CD14F91DF7B3D48340456EA9FC42C3D5C0AAFDD3F04AF870629698E9AD9F5CD9EC8F3086B937A6DEC7619AE58B32295037DA9DEA0DAF9EFD6867DC2E045BB8C38CEA5A9E2F32E1129D29FA3C44590F0D25D84B851760EDBE3EBDF02263B5B1AB4A3556CA3A66483A2D415F261E03CE40620BADA221305CB7E811EAF8FEAB983EF9463F41D23DA60B7D737677F7AAD8831C81BEFAE0088322C9481B841E0268FE919397B2C48BC6D4828B375675EEB0BD41CBE839C9225D92DA70958DF89269316F263100671FCA80218EC06BA6BE4DF202AE0AB204C2E3C06CBD25F160EC690FAAE53D977752713DE3C6140F828AE24E1157BC6F5552E306B08CE3B3445694A7CDFFD491AC58A2DE5C0544369B9BF6FEFD1010633BD19691935BA21E31A2BDE9E11EC2ABD52EE99EF84E792CE7D5756925A58ADCD522932E8C3DF4A7BDC1E6D45F0D32907082DDBBF5FA15D1AB759F6B1E5622592D6F867F0E680672434341A653C9B435551AB55A1990061A8E4FF56700E76FC3FD715FA2CDA54D5DCE687CA17ED530B13F8E100306AB9A5DFD3655C3359BA4C20933632CA2A00004D0B8A6C4167B46949355C1379FA6C34F5D7A2AC4D3C3357C3B1C14D7D7D66B520C80A39CA5494F2B32F9F94063B1F6BB20CBDDDA4BC56F6599C343035492299D28D0889D3D794424C224DFE4BF48D414151662942D8269879DCAEE5E924819985CC88F49F1D9BBA5829579E823F0B95BA75BEE15A828EF9B77AC2D08352477AD23D8EDD2A0BF64F2EE58083B2EBCDEF0DFF4ADC99C2A809786DC4E1E12E6CB6A6BA15589CC627A11C784A944D255B8EA82D48089451FA1DE1E8FDCE437E97F8EBE4D3418CD830705D1B134038D95B8AF89E0B851364C8A75874FB98E1914783556D1A81D767E5A346A7EFF827392A0CA0680A48BAFE20394FE98AB290374776D1CD314127164338C2DC78FF219EF6DB244BB73CFDB3A2272DABA26016A6A82BE03A50E970CAF008326A51976D717C121B22D2196582DDE1CE8F226D53BC95572DE85B5590806AF84589B7D608E6485AE2DF98538074A56D5B15406DC95C08DBBC27FBF6534668D77386EDF9A079F79A6BEA49791E55E53391B2D6A21A394BA1FA6FA9955A500D702624C8A26992CC1454C5118814F959A3BCE54E308353C2252106A4679635A1692E160EB5C5C028EF93538D082D77946DB74C0175FB07CC7D2E98C77E674562DCF316C7FE27DB9B95CDD3AA13857CCD3107CE654EC46B39143A411D4A30AC43CC3203E8C1702CF30FC879D1647C565A0E3F204D87CBD8A3DD7EAE4D3339023B995B85204E8EEE81106B8A51F00C8D8178DAFA786BAF1F4D236784A9C9B3C02976605A820B9615D1BE26E8F43421E49AB558B07B4A05353571CD088B8CDF1F7077209486B9A3176F5C934A5A3EB79D2E60FCB687DF8BE0325681BC48ABA956D006BC0022D6DF92B14456087DB752C4FA8DC5D3A7ED18EC9A5678F43AC498D1BA6C68F1E4BEECAAA3DAD0B6D5BD678474A21CC8CD4E188FD229243D08D7F853F79E4EC4DD73599F826DF9BE380A60A896DC2490918792D76B7A7761452A8C839DEB25B09BB87CA360E" - }, - { - "tcId": 33, - "deferred": false, - "seed": "62E511A6731C2FA10DFB5F68A538CCDC1BC578C16E7EFFF458A82627438E78F2", - "pk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D810D2C97E964D54DA11C0B0E1525D2AA06A90B4FCD30ED22106FDC449A3405398F7F7D3C48D5B8CE2BC01AE8080D7530F7B37BDDC656F530C58EF169451340B9E77F1D6524CACF35436605D4BBE69DF7041209DFB7EC91250D5F81E8E18D1668C46163191F96C81A82989633577880AF1E16A4F46A7EDE15AFC9CE8123F8881351422F69B3EB258897CEFF699742871F2C2A9680CF8E9ECF81AF1B5350203C7C6893D02808208092E2976ADB732C9D4F48B919D61580F19EA0DD6BB86DDD200CEE38D631BE40936D869C50D9F2D44537B1C4A6E42407C427B41FA05B65A12386C67C0589E2741D580EEFC484B46AA6C5F7A588722F6F6A61509E92BE36992DA24182D50A4344FDCB8214A1DCE582C1763FE83605B3C05AA678868CBAE21F168E10D585B83A0D815ED9C4E82AF259DE6C0334C6BA3613B4D909FE6425204CB344EEC4370F171173BF4280D817BD3A60D8C6787A0567A28E08B931CEDB65E236AF33EEC1F40D8F5626649A9F7D94AA3A92A735B33BA79F755B7F0D5E85242F71BCBAC7BF03EDC47A7170C62E007F2C0FBF62738A4C2B4D4DA2A3EA1D297EA7F0C2035ED2D73689389C8E2A8016BF17838144983FA4DBDF402380E2DBB34DCEFE65FC0FD8A66439794ECEDFAAA71D767AFFE9D9B5DE20B5F6EBD276B474547537861F4B09BF224CC0244EFFC27F77380E90D9ADCC9F51554566F9C40096E4F922EE4AD9E0AA1E3DB8B1F1067B68CAC4B5BE9EC9B055194D9223F2CDD7C1CF244CF6DAFB0BA08505D009B0D9878B555681E32D47D056139D415366AA5B7DAB20333AECD22E661204F6AC710FD8489E24CF4E665ED1CC4CB6B38A690EB5B44EBA1F664C7F3EF4058A07B903CAF36EB5D53FFECC16D217623984F3AB54696AF2F68B3780260EEBA27FBA1C968B8AF0CDD8E3D53FA9D307CFE3B7885972BB129876CB12FAB77918EAA6D4DE61E4038C3791B9D56FD46C7EC08F2CA37AFE5E88B95A55FAAA3A0A014BA87CAE8ED39BE46D9E3D59D25C48A08AA1120167B6D03E7B829DBE1F53B3C626ABD9D971CB096424D66053DF2252E01A53D6DCE5670A0BDBB79CCE9982EC044E8F2EFDDC47E90AA819FC6D53C63BE6231278F15BF5BB295C775C72E77F26D4E24D8EBC88988C08AB1E4A89D62EA91A1C3C66C102736854B2A04DC4CABB39330960A34122C9620DF3FA99A1326A2B6E56EEE28708E6C1E51DD1B442AC0B78EAB11A887348EE2ABE3F1541FED4B7663FA46B6C17FBE2DEB0D2F0EDBEFED39C07D16495FEAB5FEA1B07ED6FF827BD0D34F2063745755CB0009660A2099D9CEA2DB9AE6B59DB696CFB7082FC585046C03A4861F798638CE6761DE09F4112C52B4DF752A34507469FAF20C302E33AE7E9CCCAC61123AC80E2B7368D68E21B14AC237AE3705A4E039EF57D6A93220C644C74EA59B565BEC30777AC494CA92887B1D460F1D6B0CC153201948076C94847453F9AFB845E56E6D8D5D6D4C80A1D90032246989F06FD556D4FD8268A1221E1825EFF23049724A686C50F9322A2778D85CC368E80402464A578C98810A3BB7C73FD347ACCC742AA20C096CCA8A9AA971225D78F3A5031B828AE7E537BC77B3F956648F29D4198CCEC25D05F2CEB0FF38792B727BC0567FD1820C8FA0D4C15B3935597090E91B961BC2DC4898F184581CDEE606A0A8F23BECCE52192DE1CC9F2047B5D28BBD8082DCD7679C923344697B737BF564A2AA5372BA50D245E80B3CAEB8B615767B7B395240D844711B025398A4C2E35837B5805BC97E4C36E8D8ED45F57FB4CA404F484446304E5A548309FF4F024CDCC27E89D38E1E4E131928DB431D0150FABFB2ED4A928B167D1E296E68AA860EEE76104718B00340872994B369C368410B30D427175184F5242107CE1B8DE0AB862796D637ABAB7BF5E62A4730C8810E3CBE109A6ED835D66F9D5C192632CC1F2CA69F675DEBF82B3F464DE1E5A22EF221A87B6D8412296AABFFC87E86C1EC25BEA15F0B193D5B8D5EE58FDE46EE76DB19F6EFACECDED8DBABB62DC0D7C1B7B4CCCCFC5D6BAEF0369C16959C7EE04AE41283A187D8BB83255CC0081EC18AFFD608002610B168EC1FEA21806835C183BB37853B3F19C5121AE3670648E162048F248BD669EC2E9F90869264B7629DA97F8A48985D59B5E317B5D41DF7BA781564ACE32673E4ED2C267429BFC26C03DAE87BF1AD04E600B8EF12881D00AB2BEBB88BE9B80DB3A59AD91BAF9567D3F02D38A84F01AC9DF8A6E6733499448CE8891A7DE203660F064CC3C3BD9505FA9B0D4471693A72AE18E35F52E218629BD7A92A3811EABC1B3CBC78F36F1209CE73D536E9BA3539AB3D6070F493DEA35C9921BAD86CF5CFF9283CA21260D01B5293A85982CC7B257B007DCB366AB842BB2F827AE1ADDE271A3FB87B801C47F3B350E46F15AA15D76C12637286BE088EADB07A66139FBBF4ED10FE023D758E55C2C8D890097125F4608EAF88B33AB5D72EDD4479059A2813CD074A0E34CDD75D13084BED9E7A006371EA1E797BD57DCC737710DB399FF2D7C40B05577EF13B8FA0A04496276BF54E1E6D1C3F9868DB83F854D22B4CA511348C1C138BB095AF9D9295FA9ACF1E34FC3E153E0DC5E3FE6C26732B91BECE623D0C0A75EE15F3EE55725B544B88BE6D7D29FD77C18E063696AB7DB9C7D9C7728FE418E0CE81BE10AEC7F2650E270B60557CB36A88D18F4", - "sk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D8543967E2BB6AD85E15A3179E43AB6210B92C397EF2A36304015F31F60DC83520B3E2E2C7B7E3A652EC0B51BBD31658BFAA01BEB6CE0DD16703E8306F1421CABBC2EEFD701D60E5F2072A86796AC63A284748DE25B6786D7576C9591BED5250D1121664437027712683823110134744782325716701825326106281417512402562610760774070343722070662367530147028781502758603157256305388552722426744506877140170222115755788830108151370532112385248757273210600417046550866454217847036112165217026334580616264266850007412410034322610722874412460415117243752444301602835170505851723667537487687808834221236561731042711113664647265734388234256740808277021024657346336844647180827423804866772028353351361670188658044347366350218124262267334435473855537211130380776088281881551766412145021645553875408724137851647668330658315135038267670382522043487733486060561457458043303027081056283277024535724768402670634777386227288035465267040734338784170132363651088253345304861706644881714370321243303456008237433072503686580630655646152582141715035716673665747140801705080317547517185862266481747431722632188065665210410582248202410334706237247575063208513068542270135344480624807537048480257675722323868828523667548614484014178247848124228773143444620546765572057224808221064011331533864761613330733788818550157340764213234637215043534188225246248281740085824730061387131717516063000018352515166156772488565363385310845267712035500857213573868153280775421661767877171368115267572412817754047622165670213137627105670022861852722630553286872248723225586151310467404677764356827417400515120767731720865132638665281483360808157072283037470672371102636515325400318878128348651077203370773663621888364417646737251134728117508742145812273038200087512187114012422063043160048858500181257281883384253120871138472364018411544174868763812527841472624285482785457751546051004821681781406613433481252758641876587085482852562232237523732553411565212412604250652414531618530613526624881737841718756787780272121431872321183822088511353210454732244658312661582133328744116472840474843221621543832313310685346707326357765544520442308307863180375243803077277353233600485441327804771085561221300415863220114516267846385655746223526784608523021285328004700858523753543662754344646814246060073571775452627175168743175130112638655838615286783432204861821730783716411812363468715234157311333307828807358242827006155513883707261038435330521613355045286071466437258168088086533315463186611606788828853586717026080606737676270286022426073737051117462454068011642116863107044530477611414484156003044801451425172355417510241275561626552532775433703464354358238878657601860456477867740546616006031482073282787538313203724131644133801723168488715667283314218312128313170507635704084481126205514816851386454877547178307011008511063001268188821288520661657308875484062782067558134202582486678183064415640006521703113811861612754566427581001647120348066328787758180026152053480046235012435117513720852020136141848740456316226257681303354467224068344155288562637885645005055251476280088665121557083876761876614184437734187175A705DE4CE30DD419A30FBF87F172F493F6346DD3FA5C18C5F5506F4DA575F7E76A12F54D1483FBB94D05AFA2EAB6115DEA5AD6C86943D11B5F914174530AD081E5B99D3630652BC23534C4DCB5774AFD15445075AFF50D97A93C7C83D80AE7DFA051EF731E3DA1960CABCAB92596054E42B6D3AB9D4324F147F3737792EA623A4047091F692A02F11B46C992509087B4BCAF1A3A5B961E52FB08C28331A26A7933BE9F5285A6F49F617B504F31D822F8A7716CDC23B1D3742DCB3C5E039A9DC0C049EDFBB1A615DE470B035A0CC7E15B6F1EB7A92F031541358234E70495C375152ECFFB86F158172A0C63C490CCCE17318386A5EE54319281EE85E53B6FB44DB01412AE8E8172FA3A09A4907B7D8AF2202801CAA448330E8CB0FD28048BF01201ACD838C30FBFDF7D01626574287D93078A0CD752800B761DC4FFD79E997BB1179C67624A0BF3B2441C9E266C78C07E99F788C55A4694005F8505191EA20B3A6C41D2E6AF4ED78B9B48141F498425257E015805244D88AD9F7E7803EEFF88EB2C74D940C7F4F93BB99CB6B582C0940D412787081003CB9BE3F3D2974FB0C5211B8C7746F8C66D0F5DB018BC8B5DBB4C5863C10247083B3701904FD7A498EA1011EC87A31D3F22E3637965DD63F564717C737CB9EAE48B00EF49F3EE4D875712DEAD9634078FCF28FF19C3DCFBCE7CEA5744DBB1BEFC10CD4B01A3E818C244EB1330F7BD35C2F18AF7789A2040C09F040505CB5036630A7F3EDA0962B2D5DC590AFF47D6F1B39C4073F5CBF139D865D531828C8FBF5C0D5A2366AED1610974BA8651D152E2DB71D5FA7BCAEB56B9C0A73C1ADDCD35DA6828FDF652F6E92A1A0307A3F274A9DD3639402774BB62AF2CDA387854450E34589F1DE919852DE1E7FF90C58743E29EA4402E64E30F75C8329A5EF95F66960904B245AAD166BA02D685589930C4128A95612826BD06999A967F9147B18D3E966C3A9071F709671B9CB6847EDE93AE225C70DFBB4623CDC0066DD7D13788CA2EE4ACDCD857B8803C01CB90DBB650B324AB2BDEA62304BEDE414B4422F7610F113EBF9B7E137681F209AD1774EC5D6389EB46C736D1503DFA228B7FDF5E69BEDA7901F61F2024D9699A28E3B3AF085EFF26C17B962D6B340CAA2EA1FA927F273D676667A1A873B60607E7CE4EE1739D334321FFDEA839B9B9DF69D621BF1DBDA580777084614623500E3315A570ABC6722CFBB1E20B32FD410680D87A789648E00A129FAB4BA628C060DA271877425034A52E2DBDE5720A333C3CBAE2AFF7638D3005553CE6C69456E835E23B98EDF88D5037BECAD644EBC0413B77D942A73B47C87A399E18144323CDD51ED50038485D144344F56089ABA4ED70B8DA96A630D71EB80CA91D410764A030AC66BF04CE2A837A345747B1BC355B751A591B95974D2C7065D14C8DB475ABD6061A9FF3FFA4701119DE5075CDFF32DE15150222DD9F6EEEF8197E73FD6EA63C778DC9341FA9F312945DC20E8E24C607512C501921B7740179F2ED8DE976AE0D6F8EE5D821A3668CC9ADA6ABFAE60816BAB6E67DD74AB8D3C271F0BE15C583A561ACA92A7CB63F2BF60C0DEE6DC87ECB3C0C1BD5F16956C8A937646595822DAB1CE09B1E194C77735A50F8AF265C630D20D8612A3080B2FB41EAD3977D177AEF12C2498DF63EDBC91A1BC2929283F7C66ACA5CC4B03D9A410043B8003419E1CC5D09293D526D79304ED589AD6EC522D10CEF80FE742CABC90A82A209EC4B0BDC1E202928BE4A6DEFD6EB37CABF3574DCDF357CAB6AF07B22416E82722C5023E96CB6B518754ABD8DFEF198474A37AFAD1900755BB1DE56249D3C5BE147954670C91C4BD940FEEAF275D87C04D2934BC71214A96BC3502448156F5B4F3DED83ED55149DEF3CF1B39F43BECFA1ECECE545111A996C8B6F46066F759C8F307C7ACAA31A1823F27CFB8A0FBC4E5A11D6AB0A180E78AE4FA0DE073200DF8717D08021B72F1ED67089000F5694E518FE3C286610E0C18CA312883F5BD806CB6EA30F4BAF513FE183FE3109C43BD5BCB42EFA5FA0A5D6FF7EDE6CFF61DA65BCC6EC78BA9A35FC2B05BC4D3255A19C79332F80AB35177352A6DBA730C6071099F3DD56D510A129E6DE2D38AD6895C5B917E22CC6763CEA81E8B2A88172AAADAE3600A911D34A0AAB6DDA0374DC776FF50CAF62801E2DAEFFD58453B27E2A367F24106E35D1625936D31E3C26AEFB9354D70417CF264BD5B394D5DDCDE1F90C20CBEAF24323BDE3078395CFA5D9AA74F1E97BD4628B190F480D717823786C3EA5B6C0F54ADBB0B2DAC9CE7B1CDC6EE67B036F16CAFA4D25F6C74592E535302F8F3FFE3B91476BF588CAB45580CD0EB2C421183805DF21D51BAA4D6607E40469A5509AACC29605F64C1E48D4FF1E91674E52CE9A6D5043380580EE746CECFFA49B6DED160B70B3C62C43A233D6F584E554EA5D791EFDFF310A7F5225E7873B26BC5283495CB1C3C2BF64D868B85D463ECFDD28B6682F2DF7E57840F535D95153F6AFC2BD713228D1E9FE546B9C65D665CB01603C9FA03BCC4F8292C81F7195FB9453BA15980BF464CE57999547175981ADA808847786ED93460A43627BFE051F15F871B38D02C9CA224AF4F90E0EECCD4B2DE7E7AFC950C2F770AC94ECED9C18B05DA5B7067D6A984624F800982F89E6E0385DB626203F958392B16E9A86FEBCBE65231E8F3EF03AC7DEECD07543C8F8BFE409C3CD0EB88CC39223366CBAEB968EADACEEF97C5C7FD24C3BA4D97C898734C767029BDAFB3B11419CEA7E2E4F913B85333990B5B0F794E86342797D8ABF0F4742895A0D93D03E43DC03722FE38858E00976981C555DB0B708B3089D344851CA1CC42C7F9DB437E6F2750F21FB4243557F70A591354621E43712A047CE2F8951483719CE639A50C951E1E7326A7F089D47E0EE2BA28BEA4204D8478237CE7DE9482FFC1A8B7D3A56D4022D159C5099A69DBA88C71DE62275BE5B1707B4567930C6C3AB019585998F5A1F167737265DF9F1677B9AC771AD5A1E3F460394FDC249918C1911668D7464786293AE2D81D41C27EB0242984F922AD5596BE51C31BEBA3B9C474ECA02A440A2B4E9F4767719A92632285D176FACA6D06DAB7EF77B8FA4BA88168A9802912B3B2B3326FD1CE0A1C960CB5A197143F547B657038140C79B7CCF828D81A9C1D4FBC7F03FBDD2F6EDBB163FE0DB9BB9B68ED9389372F0D767FA985C573461A5F246AD3BA30BB6C90BC205C763677CA8871BA4682939F64180AFA9CACADF68EC838B56E6A71A952C8769299C4CF572B205BAE167DF5FC183553C152085B54FD5173BBBEEB615BE96E737C5C1A52FE068C71C433B512C5FFFF769DC2132F94FD7E1F1ED296A061C63F8BDD401B76E602247A109179EBE7F47E7755A21BAAA0F3E5118A3440CFE071B1A3D998423BEF4BBC48E2C172F1BFF8A5FE505016C9270BA787604D29DB56EC0B953DA5AC54FAF7505FA30516A3F060E3894DEB7C5ED8175493DB7E246D87467C2021C" - }, - { - "tcId": 34, - "deferred": false, - "seed": "BC4EF6C46CB18061966CD872D2CB9826B0220173E42F11B451DFF93C0577CDF5", - "pk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572CA7CF41D9BC636574F8629CED228AE8F626FEF7328FF39DF8079AB8C24840B1241920B4849E57981DDB978AB5B4437EF87198E91E20AAC7278EF115FEADC43E58F9C0F135E7833D289A4F33738FEE0DCEA8B50DB3F0521C1C3C76987A7C82C0AF3C38C59AE1A888B9397258CC71340AD2886D98207ACA566A30605C4E2E545161A9BCE5488870FE6C48C13B0F47E5661A7409A6C5A568988C9814FD2862FC5B1A690841478F579BA587598558C2C07E988614B7D8628FF00798F57CC1440A0C5163156D490F3A3390D4498881BB67A58964B73826446965AA930537B55A701F4F635A67FE975838B59962DCE9E020C77352929FD327D0106CC0160B3AC5F63252F85C151C889D096C942939ED146A04A44C9F2395CAB0F4399E1F603FD0E3E5D4E7FC1DB51343425D8CAD80076FAB19E3DD33A007903D12CAAC1673FCC06C401E8315D9603CEC9D3C7F0FBDB3D00CC2B23E10DF63A9E4B2D3E0CCFEDDC5DA1C2207A7EA9A0B81D4878A7CABA63E494A67466A401D1988270F6DE08608C304EF6316B74B39BA6EF4D5BF3B66E297B275B81DA2DF24FA1129D88785D558C3F79C235C8243F0FEA80018DC6AB8F375EB17A778E349A87C7B5DE5666D17E41154BAD3C5B00E5B07CBF9F46CCF1759FCA574BE7257F1160F65E9695EFF1FF32F92C386489AC19B3322F30214AE8B008E342E21ED559A035299CB6733CC34B2C2732BC3A3A5B5C5E4370CD940FAB60D9110071DFFC23831D984A446FAB028907A71A423E5D22A073F069A2539195F1CFDDAB21E3B163D2A1A3B16C749C181E3E68EA90E1C2E98D64661E0830BE2E2C967C0EDF86FE3E0021C6B217367C8D0F3CD28B8BDADB49329DE289EB3746BA459AD8B783155FF8C151ED791DBB33BC6EBE60E6985D98AB003F613674890E1FB72CF2FBB11EE24C2C3CE6148A152A4B0F44DD890AE262D53B0A5FB18C748BE880B432CBEC5616FC0AB592B9732B69E6A7C4EC149AE75CD286D133E812D94C262E273D7D6053007DE2609A40109EF7759045C601774DF800222897974438D6CE98884FA79C99B205F00C743452710BFF448AE9CF00401C99BB75DA90E7D99877282D1CD6C9165F372ABACFFB6474E94E7C9DFADC925B7D7F14F2AE043A0B8A75124C2152DC45310FE37036874F466E088FD22384C798A486E1878E784DA4C4BD790C972CF118A64F176FE8A8F6E565EE26A293A4593FC80B685AB615CA5BBA86BC046C413D9937D544E9AF7F23C717796416C56401A0E68043F0ADA7F4C6C9E2C257F36580B2A63F9A6D8961EA4DB955739DAA153152B8D6C2DBACC52B24BE9692DEC785509A23C01E1969C1A6E2225CD3B28F93439174C104A24A6258C813E74C46FD95947D8AF64D93461B6AA50136C799C140097C7D8B24EAEB87BA50E73FCC8DFE9447C228DC6438574E21A23BD082146A0E617A439BF81A9118FF3094B8D794C72EC7ACEE9E60C24E151BFCA9D51CE368904AEE0C608DF45FCA8C2C536A4F0F1038F280D06A15CA43FA836DD54F2A2235C1AB14621F8F57F10ED45814249653F1DE0FDADBDAB1E95FB502DBE85D05047E7CAA8C4C6892B421F2678C8868F852A51F0E5BDF82F776DD1FD40DCC4404DB2CF4625597FD5FB69F10806866334853F0B40FCDCF64A02641226BB7BF4F33CF8449CA1921380091F5255DA7968333EBABC8F9A84F6F8C84041AD2FA7EB9C80F95D874A860ED43980D7597E4789F8A69424DA042351EA9D5B19E5C128F8C5DC505AFAE0956D913193D1453EA24FB0D8AB64584718A61B447EFCE208312C475D2074928DB96FEE1BB910D06DD6CC3F474F4335EEE418BECCA71138A3B435787B4CDF209325865676EE3DAE6AADE50AB8A075C4EC28DAFD308F53028A5944272A9D2A6F199F08FAB81689786F08312EE0AF4AF1FCB0AE0B693627C1254AF89BA8C1F2613B1D5D46C0FA308AF2372248797CF2B3AF9CCDFEE69DC21B09BB390D4B2AFA00EE51B83065ED83E4BF1E60C9CD0B79E5C7EEE4390B28144FD2FFBF03FDC97A4AA39361B9EC50A2AE3BF8C931947DE3675849361608E171BAC9772296BB218DE9505544B50D8BADBE77959219A611325A3F6093549362F07C40FEAEF71B25A9A7F928A001B1180BAD6B4C57BEC8822888EF44BE1EEEC17600FFB00305C877379815BFB09CFD4744B4CAF48DB5E4859A476C198B4118B48AFE8176948E837BB8E54289F995C4900B0E8CEC41A6550876BFD950E5E3F346791C4AD110F6D6C728E5E58EE33E47E57848C7DB6CAC53DE450CBB9E1A679D2C74E0FC8A01E0D2D9AAE47855BD6C1864AF95EC834D229809ED6D3096113C199C156A80D10EEFC8FA3B41BBD23E5BE9E618A379160FFD6578D158B9E04790248737A43FC8999D25D549F67E194D992E63E51DE388654C3B5956626443BEACD55F433AA07B010FAFE318B5763BCBA9FDCC17C88945FA5358FB0DB345EDE62FCAC8D70E59E3E326C41944F26E6E9414AE356F7011AF46C21CF051982F56E1269BA3286BA4AB4142253E75FE6F38EF6E43A708D7F12E18CCBFB88B31B2DC2E3604AE8067A29ECC47BA2A7EAEC61C20A286FF7C2ECFBAFB722120992FFD8DE17DDCF8120A77F5AB9BF66E0ADD0AD97444EC43322950FA02D746D4182D649A6407D5ADEE07D215566860364DF3F554F784F30390B1B4D942148525F7F5B253BBEBF71EFC2DA6944BDDE76BFFF42B", - "sk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572C29C756D826F40EBE63389844B3856FD107649DDC3AB99121F9B5F658A25B2BE42D2B0D0AF78FE1A314C90B3A426395967DD3BAE3D5D1029DBDE410038E39BBFAA7E20FE03217656BFA7930D08F4BC65E22EA8FD2054D1CCAEB3071650956921C8818383516546652345845348341062226750117678070784570688375188710570177501547154781433305500441388730375103588405375867617654308866302441600407576855334525682615663181476154841163774257413648636855878347220644304842024115888285246226138068538618624402515488050667520351648113356388605656772231715728008745145588726836117405018742345584424117700018427422172663251250586644286578757304668042003246205338202634818086486123301785675071012243767856118835760130687363568514152268258478147501550424740841243831124168575576778672513600028474115545671848450525620062025268211708511303805861272607274170036384165863223506451565485030532523838221603121287121258746072176713758303632550312407040655188220360357083342722457032075015106782627515768051832500124057822141806717818130204348522116668168451131021286034235335052683755014564880081527078434626244324244510065258144513486042326238540065740028287018174303318278605860268612373017402063473525711430312023244056812545442844100520001864131458455054357850851616055356500742453276075824111777566866705768584830046800321427826811111278128707133771780512815062885416415722083566437861458372806671084678275584322766418754517617566503460016327270648231052836222025133383052468854188306714172464176800512243177780687715053575280724703280270467263745336412286256741502851718788040761600037416853226678306578787264856847665327562026070278647542104163834357747751682268186422832211685401007454675858764182640437071260473443336570828403305146626232784033300107168103446217346137550463081382500454211446123826604371182686275337146882401545335814524011776880487111118424037210424342370242086353287448665040282354413775244701060055434041608100180153521065422144718432411453616532145776130503005125174035851250505745133537151673466754538347058334505557141046336117404485764114821312541582861414507838063640842508474877435530016238621821578103225262201873646007042385113361266433360344375647126042186828638601077581056113382282548525480625002560854472737373661454043588228486646342684336122607353740480842165545624654407006382410124026814128213476402880362710601084361726087002868561358056824863415583231157101337220888846877801156782588770147556680432713113728653328533633450458645337136485473234337704500632556522004715764426011055020800404283451041078541112463436778348678102033630286016710360132806074553635343634681186558240305064843460704424377205042621258166181681515748037366075414103086201016510622332567241352646460736353614088313652185275227160484630482480168165272140537778813161341883025552377040525524854466625216273363852012381002677764353275847134654001617637546856066738302850036854362132481856731425248733072822146707717830226726020857302425511116774864817318644468555074138657504402057020263158005116668616551570538040051435731622821807634486281403783750583701308338531138562104F2255924EC380D004EA05A4303E25E0C1778839405DCF83B74FD2754CF15FDAA6DFA98B2637DCA46E9DADFA726EA4AC153EC7DC0CA42E86F26D03494E5206BD4408DF6E7C499B5919869C447963748E4446F2F0C38AC7DF52BCD04070490846041583216B2D157DE1051B4E55FF75DC6A03BC20895978E3D6FA56F43CC5C7CB645D97C028894A25FD2BA8592BBE355E903162615150CD05416835570F12F5A5C9229AA1A9D7DA3E4D2DA4B3F80979B944A30004EAD2A590228A828C878F5176AC162892F11369811C7A5877771A00C47EDF2473A4C01B760FC2598F505B942C92CE8483CA8A3050D63522B7D669B3BE2C3CB85A3BC7E618935E6B72290E2570F719EFF0FCDA400DB8A7BBCB6BD66BE529B200FFDACA580C0CDE827AE11F2D920D2AB1A55900067A4E3C0464C80F12A7BA1A0F7E8C796BB391995A439EDA1F11ACA434A24BED01DC28CCF448791190EFB864A094D564B3D23005A492D0D2F1D6845472984C8C0822822C9E978F85F9E36E38BCE8FF48E3B485C7D6888BFAD21A453DF01BE666A4BA5AF49A1922BB368EDE947E12D4AE08237912699731F33AAF445C8482DFE2AB567F7B3B256956A800CEA10765BA7F10D5168AE9053C2A341DBB59290437DE92C05A93036857A19207821AD6693DB7552F22229CA392566E4A019BCC21F76AD18EFA19150681B4EEE85D1292AABA0A6792D1514D4A550FAAADE32DA084DBC9AD9384B11D482B10F8FA1858A9E558383D5ECFFD75238DEF0C09C9CBEA14871A310FB813E6792897B5054FA56371DA801EDF8AB1EB122BF4A2F01A1511490A48B8339BA9C6DE477750F5FEB46ABC9E3DADC5C667847030D4A8CB532B89ADABE7F2809AC03C4C88B09313901B6F358B3F9EE0E48428469884974A726EA63B675E51AF76D4ED98F2108CCDE6C639473BB9979AB51DF674D1A65F889B41D9B18DABFB776BCCF4791DBC901A24FD9EBC2FB2C9452589CBB629E681393C019E35F5D6BDCBBCACAC054BA8656DB830F1881FFBCA556B0C6AC73CA5416ABD5AA4816F5BD277DF79D984A06CBE50E4E0AF9B9B150099AFDDBBC907580B09745FD335E006CA7F61934B890BEAF2B94F52F99BEFE94811B2827006042254CD2D8075A0B34FDA4B31E7420DF4D96DB803C0A62FD802952CFD8E1BD3048540D1918E52666E185A21564BFC9CB42AFBA374979B139555A8909DC7BF49C4B4BE6842C3D692C67188C169E10AC30D5C988165C33DFD7DC21269D276F1D3FA22C10C9012A5C8A0C8423C4838A62302094CF3A213C5721087AA6C43E589C3B0FFF04FDF91CAEFD1498FDCEC993ACB4659935D5D90BB5A709704774181FE001EE1E05A9DBA1251115A79173B1C33895EA761F0C5B6DD42BB06E96765D8C242D457A986118FAF8CE1F089EF1CF293518E066410EB04AD8EAFFBD0A59209E2053B7FF0C2E221A6F27CF8F05022BD91B0AAE3C01ED28B41732A4D89CD55F7D491F4E431C40A83752D470AEBB54EF96A630576E8DA05EAF5218F8C09A8D1F3C80A90DC77F15B3B44CCCED6149ECEB7569EB5ADD3873D2A23133BD723F71A2AA7B0D3E2EE1CC75493DC0361477AFD5E6658E9787CF117243CE7C17DD8B4FCAF65B3107AE60CA15A8C5FE7A9745E27EB4674A6B55539B445843A2870AB67BF2AC6F80FDC5B53929447C6C0A4B42DE8BC3CD22783A17B5AB083B4649452913DE9E9B5321E86544BD771ADAD0BBB5417213E3FA62D80E92548A4AA7518E2462B08EB141B98FF44D6B4D7CCB1CEA4552B75AC71C1F4D10CEFB20A6C703559F26899DC2693FB287574455EF767BDAD3D668EA8477B4E5FF4E263C3C7F50151487480D7A6C271412ABB763748E342CAAE563A2B2B421E067B275F709CC452D011B2AF96985275C1CB1945172CD2019388894D7C450D5A1DB83A80771456D9D0CF16FE983086090DDFCECD8BE9F6AE66CA936FBBC0FEEF1F73DD2C19F4ED1F1F2855906A2EE18A100B79F1C3FAC6FBF990982B0139664C08BFCA09277370F2639C5260862AC4C7D03B7F4E48EAB9DF4E9050F67A50FC665B1022B00B0E7635D9462EDF1D602E04808DE10A0C123DC21C4F8BA28A94DC1B1EF5F070F70AD18B6BECC8F9A529903502AA982E974A6D17FA57A52BA878508713E7BBDF882C2FA50FCD0EA27F54E1A5FAC2D4101AB0D6F3FC3251D922AB2E3F90F8D61598EB15C77869B32F96D364B70B609D9630E8EE18D71A4A05A0767DD2632ACE2342F037BCC0D85ABCA48F10E3839A8D727BA55A7ADAAC526F63A60775743E06D61AF9B9C20A3F10DE2B8BCD545C3296274751AEAB66B7A0883CAB9B07D48A24CC567AD135BDFCA30B61C47AE969509F34126EAC2FFA5F2DD08984A23430B7ABE4FB7DCD8A6EDFF1BEC22E7801ACAA855FA5F3DEE21EB1FCBF9204DD2586F6F78F775B26856ECAE89C80EC645372C7B21036591CC20CCC96F92E16E1C36D4A0D80F8ADF3D8BA6D2536FA67A5F9FCFFCF291C29200F9592D3EA56F85ADB431D481F4297085FFDB8F669E523EB96BEF366DE05D2DC8FC0485977FFBD719DC5CBF4BFCB3CD191AF4BAE90696DBF52BB25D164DE472A64C57002D434A1C29BD379D72A4CD86C1380BB8132BAE06620DC219C8E35D0B042CAE54B32358F68554E34D55275CBE89E9526D5285818D5D9907B52AA21F34ADA8C74576C46CF25794CDFE19AB419AC44F3B05D0A40068945F7564B17012499D0602B4A1774002D18E4F7DFCAF3E6CB035776704457632913826B64C71018C4949E7B97C4A31E042CAD3D25AC3B47E540D3D0DC6491BC021FC56328E6300462D8820EF3D9BF7A40FE779218A0CEE30390A183F571CC592FEF2ABDBD47B3A72F1E779815C0787FAD9A4D5F817C20E1CFC2799783F09DCBABC4A4692538F5B8A8F71172A738F947B899FD431B6C82673F78FB88D528649E8FC794A1D3A89E7C3DB3075C2C3AD5CA00539BEB10C4FD6169A05836A3FD524405BACE465D0AAAE4CE9DF3836701CD7914382C27E73CAA08F1B252A4B7EAEC1C861CFB443B28ACC5FFD0058E0E9BA4864979C7EE56A42E0070CD18B74340D92A83DB40276B1AB57F84B6ABFCDCAFE227C08415700B6163B7D57EF45FFD23BC0DCE56F1CA8FB58E52BA415A58B87A46078F44EC0EEC9482E4E032D61512BA21ACEFA846B408856D64A1D868EA98CF4C518EF6D0F9CADF76F13FF1A90EF4B42B49ACC0FB61EBA9D88A51D6F9143C3713C91D623D173EC0BE6DCD11B02B2B7EF08ADCC1C7A78E262441D6D919E3E3AAB0B61C7ACD6C5EF95908FB789D44EB01E505F9709CA1D47C9AFBCD88806038DA554B6CD3CDBF274A8E0292D9B451ABE590D7F7B8B32EBC60848AA5C0528A8DD435498EE46AA7E89F72AEE8D96A590B5FA434FA4159E190C4A668912C80803CADBA8970D57EBB2FA73828F955754F81F2A3B5144F891F886E74D3F2604B0E6A2537F491B786A50EDBC03CC756C89D59C7A29E372AAB728FCD082A872CFF573D0E8D0C6C60BCA9B21627651BFEF05975499BBC05B2" - }, - { - "tcId": 35, - "deferred": false, - "seed": "135DF872744277E90019BD1E904DCBED63741D863E82388B61A2B069E509B25A", - "pk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C590596037B30546386F06E9FDAB6AE2E88BD93633E9C27EE046CF437994D9FCEA1BCBED601082DA3973209A408440CDEC12AF383AA23DB274E7393884CB7AA4672AFCE26A95511BA62CF43EBFC7945800D79CFEBE0C41FCFB7A7F1B11DBD5D530BA969A56399E76EF1E8244DD225204AA140C71C90400D0E6A99593B346BBE05EAF414AE396F169911754E3A631D9C28644319BD4BA952B7E935AEBBF0AC81326A8FD03EED551623BECFA9637898091FCF12FFDA8CC2636C1699909804FBC6050617F4E0454A45DBEDF647FCFC47F678730DE0FC9B7793B88125DD22DA136105A23FCD1E7B581CC9C8D62204472BC2A8F8690543812A157AB1D3F7C3A8380BF7724ED623B938318CC45D1D8B907C460E1516192BE22678A7B508477EC3FFE1C2F085146CB921012010F82AF16ED8E8A4185D4C77A21C1A6DD6B56E0721CA1F701B92B04C9429C460E04C02E07345D6305205E21DAD975783669E4EC89521FAB64BDB3A31EB76B18C33F81CF39D5AA9BF1B19F819EFCD38AA04EA3DE374A6E155F8457768DCC6B7E14D2700AC4248710D527A60CDA5A2DC3CBD0E74EB82625A1642CB80B7310A230392148A4812CA7A64EC7DC9ACAB74C592A1CEBD7E4DE2B05953B3500AE2586B4357A511340821EAB6C8F2DFE6576487C93C47B4B2B76EE0C96552EB31A5C4415EC909F74C5BA9513A10EA8B54ED292D8D76AA92CC131BE5F3FB10DE22D5480D88499EDF7C3B265B96DD9CD13A8964C6D642A10371D69F6F1948C203AF1E321CE53C48AE77A06E2DE4B4CC942E9563E94B75BF4284E7EBA1BB3850CFC2F1E9AC42D7AFD4BF6D7F99E621EF640AD2BEBA85DB0721CF550AB3E2BB3346B36C9D13E34D7C9FF5FAC1EC257DC2B38122855C5A762CDB08FC3DE4D546F2FAD9B51A3F6D5D11AEC965BF60B834175DC3DE02431B2A82C528689BA90C735DDAD72BD930939EA04E750E33BD3F94F47D4F39A60E0EC2B30BE74CF49CA04B100F470B8AC60BC47522064F540F9A5D0F57D19452C02F0BD526D17E86942DBFEF921D82F343835288974D4DAFF657D0D53A08D1530ED85A50F8683A98D98B402C67FE58879687A39F05192A082C830365D577EF0545D4D1BC183A2EF070D817CA4CB941562B4487B4BDCCABE417567C6C5DFBD09F512E34CF996A3C73A5D2E1ADF8EE94B255ED8EAB9FFC7CC5B1CD8D213474BB1213E47F6F7B040C77517C58CBB8E77F5165C590691971EB4587FA441410BBDA483AE2E92000D2C96869EA239131039B672D125034926D0B31CC481EF36CDECEC45E3258791C520A185249ADC4E1C946A9214FA6D29F264A07FC039737DC0A4B0FAECB74A8B539AD875C9BB2D6EED2DEE6B69CE2E12E1E92F3F0EADA8A64AF5933BEF893C0D9AB0E4A19B18A9EB56F7079D7D730C1695BEAE4821CBB97E3D5752BBEBF6666194695BE5E1FAD0ABFCC280FDFA1FE2BB45F371F642C93EBA3A0D7FA69FCD30AF866B1360A8FF6707C54504EAF05AF44D2F41670033460009A8C7156B24EAFDB2BEF3A2FBA97AB039518EB8950BB8E9D07D5138AF47F43058EFD57AC450E7CAF54C275121BDAC4C2AA70CF6422F7910B01D058CB4806D28C55C69FA3FE7801DBB2C62BFB86D7A0925136C4055FFDEA8F47FE22332F09A580CE44DA4311CF51EA68495D69079A5C9C8FB442E7681A021A32EB88AE12EBD16F91753C54A56435E5F244F0C2CA4103DFF9AEE7E780FB423BF148C9026EC9E649AA80CFC411310C3440B5AB6FA3605867751790EA9A54E053C81970B3CC5CFF5FC000261616524768F7E06034B55053EF0B7B24C52ABA0F4A40C56E7BB72857C893AA25BF97761819A2EC8B9319C8B8F55A8042879795D06971EDB9A63D85D2E5839CB704D66497508A8628AD4A7B8C862F965DACC4D9BE011EEB5C46CDB6A2AC03C6AB7C72DA20889E6EE48B9D6E84E2ECDBCABA5BBB7CEF9DDB7B97286185283809E6D6AEE4189AC17BA586A274E5DA9FDF56C0C86ABBEE67525D27B15E08CB949F8F38FCA263271B5BCF92121269EF692AD7DD182B917E50DEDAB1B8C5A42621DBFC682B2767A4C91E1DE942A660D3D1F4E998FAF32F652C68C09D4C6D278FA8DE215F6EDF6E254AC8E9A8A09DC43E93ADBBF8D9A6D5BDFF52A0F9A57CBF07B2F1C2690B2D4D1B92012A0062CB0D39C5F51E1357A3A9F2B3F063A194BD68D09412DFBEBB39A19E0B6994392F9925D1C7554456D0D633549616D56536B4F6AE1F0C6F2991899DA65BC1B8F2913F05B88ACBBAE77F7BE27302EB04789E605724884525219327477E4BFBC964207408DF867A12C8554216DC7F0EDE2A74F3450F09719965593AB620804F6160D493437BF2647B17AD8E9087FB9ECAC796362B20C47AA45F5F0EE2A3320D844E78AE6DF61597E05B25B4EB804161678C180C70978B5DB16F0532C524FE4644507A178A31D84BC823241390F2906E2A5007D9364CCD5E332E65595488F65CE00C15C33B5A7E0D2AEB23BF53C953858130287B021AF19FD83ACEC0160129166B7CD39305B32029423C9EB7C1C86FBAEB08302E8E98783DDC23DC2C88A916F061A17A436208D565B2F29D31F38881CA031EE00FFDBA53D5F27B1CFBF8959138D3935AA2340CF37F8F1519849A087DA12C3D0E025E33EDC19022911C7F78F49B1D3FEE3F87250E38EAB61B2E607173F880B9534B370ADEB83BF9AFF3CAFD9BEA06878E66DABF", - "sk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C59059776BF0982F58C5BF8760131D784CBC59C83506E9C37073A735B862A90A1351FFDF2CBF21F6C592F36C142E7372741317808CED0E64E75242A8CA167DDA0931C12067EE31EC05CB5D76762ACCB588D97F885DA913EDB932FD9EFC597E31C8FE7483732182417476267842312383478154743246465608704018564385702145640032387477480015217732076670716666467833626011865105780352472546415744556138516780087816437287418113876478510168466361118214334241670114075453510780284573135100347550388577701188017176163033247283666855118737431883475501656605683610738528276807102471644770484440320781171351481611644187385155343613247758636820584746160088566426010428203244046441730233448316034754248183573334761217257455360176028465830788381643240768766280464653231063260878410470574307373316874208716171123303817623837725475353711451040420210541882572050248682047242423200011856287765407446474167417575752066354152702022122578670844232737845641088335275415401011387716361864551521567112453813325131754308472287050122011151372646414852012325538044287833806555000572835360174353656765502258874142856141381211338024426087777686324317468856134168305145721077050524706654710068461234873625832256211720256300534682510444126505380610114274108128652105757116102101610027146353055681174423780414631814766604742016505380053811753008368165204378032838721314303164347700288275788623102537480584471452714476335173848668614437618187610552480265653710132536135642551212270583780386871528154403781704407403277421066170314475687213210526636380221070102627478732365161434256612014823302523866118448752603774022243324574346365536516014470447434451828251230234262820774158573160724435457606050617288264125822135802242853578238058441418124730762135158784477176721846631804675433384776456172658806162800784657603315350128042358401711706737852082571514521858816256047683653501611414232632543716484572216533733465564646410787800711631308540481036537622137273362580821460630373846686536351643184220531260100470718632847612280013042337373536221652732260400271713866033384882613587553853154040621820351770001324430483350066467206672766355051513856777165413015284625031416666867715458402036710374272215323506650536575663454041153038824213555822740826103470534308818637830853622438247348816776304148463123075133283488484062036787547713120366474014578455581134567708113412242521388135757240176263555784173124460318616660500408413380503574433416272072522707577581862022240481421307758281540872888122804243684675014071523047532418622155330485380820231333301134246558278003026512810705606767804263084124781578616637246768362221215416245532858754872782888871325412358451314080488111481442478110611135071715543656513067667176448838086323467381317537420507301435855664835265066015501051842518277816662454485756187478822648427083443138015222802362876282417008521324004255156877406860744830428285413554573067703281106187011234434728360065728454415716563261413046158800686358771553030874538582228413307033286145140814246244015884017253404030718260532684216764132301055016015132773621625305843836355723257172476645626154671D230BFB6EDE64D1F4CE65CDFCBA4F8B6167127DAA9CD1A3251479BF6BFD0CBEA010D6D3EECD927DD933C6784BE30834AD1DB0AD5B2E416D86836615051F434DB116D8388EA6DD7F7BCBF7D28A72489CA067DBD3F478010F9E1CE759D5B1AF7A5FAF197533023B7C05E835256D849C1CEBEBF17844F39E36D0ECAC807874050C8456855F01EC40AEAB3884D384E2A12F0EDA8AA841E8E0B1C5BF11E2BB6A29E8444BD802C1F460405AA21E7717EF90739E3F7661BC8F0EF1C66208E66DA244292995889158F64819551F4174038EF3C2D60B98EEB43C53BA96056542A215055432FAFBE0E7A812F0F685E24E66ADD8CF09DAEB92445DC2FBB144176866DDFD663238E81F668AD55B4411AACDC07811BA48163C49056F7B442BE8533D9E3A2B83A057F6A996B6267CBB9433FC85A4DDDA41806DD8E067765C29721E6D5A1BB34A80333C199E00C2E3563F9F77185CD100B4A2FF5F1F97ADE70F1928CF198E1298E35161CDCCA9B9A832F4413B732FCD271FAAFBACBBC9664C43FB4C24206365E7FE7C5E30D12FFFF90A3064BCCD44BC8C59735CB95CE2A91D88C0A635E419FD0BAC0270800109644EEA88C36FD78393B42384CA9B58EF61B3BA9EA7EBE3FCEE044054FC1BD24FA70C71243DA12B338AC7461C39661CA4F2C7E9529AE53937800BEA814BBB2324AD2C05785920AF96834B994FFA29F8674F30E2DC5E502E74296E8B5B731B53DB9AFC4497C2A7856D23E28AE1E78D957BC73E8EFA29AB3664A3FC27F5D9BAD4317EE47EF6CD1B6077236600C2767F7BE560AB260D07C6FE184F7B9D928242D269C655D7B896B859CF410C2C61BD5E6E5C34531EFC22ABD9B02E21887BF37AEC7B4B7B1C7AC9BAFD050CE93E6586916BA766F4AE1EA035B0CEEE4BC362CF87AAF83577427C8F76BF36D631B72ACA5575F48D293F451F66F11FCE6F725C6D2DAD3C7045C2CD74875E122F14B3D988E207FAFC198CEC59FBBCE70C6AB11E686B5775CF08673DDBBD296AC617326D3BD9B1DAEE12896671CB0546A7F6A74ED11456EFF0A74391136A5866F61A5D3FC6498CAA1ABADEB900A0C9C36931A4A25987F25E31E2A72388D84CA70102409168C348AEB13833BAD91281CFF1D4C76A4D2F0747448E8F5525763543E2731C97D506F826232C55C1B85C661F5FC726EF9C2E8667D9FCE4D3386081657629CC1658D3BA4559CC0F0290215BCBA010CFA280B87D23BC79FA094B3CB4A08157A69E3BB41B009DD5354D2EF5C0C617A72853533A24322AC5C85BE8C31C3C8BE7A71065978006D5867A3968DB01AF0165B12A557D3B0BF8B44321F948F367A5E3A5BFC9F190F26FB35527DE4C06EC155607E377789E2203FF48A04F837BBAE45E2E4A4F049E181E2249F59F38B151C3F66765130DCEAD1436BDAAB9A4B813E6B2D418CCEDC699F126321E429CE9837B9D00FD9413AE3EFD9649AD2F58D0BE9A1682D9105769C111886B68EB0DBB6B16AB16C9578D3952D24C03C8E6E43347121FC1510952228FE16CF87EFC1B0E6CD47A01752DF9AC81479C7434EAADB137433256ECD2D9DFF8C49A68E758AC3594A0C06B84A19393935C4F6A894B0E90D7166F2F65734568CB3F837A406A8CAEBF9922E5327D5FA2D2BB98D63EB7359E75FB836F5D392B25D32997DADF301F8154F320DCF941D309C78D09722E17AF06055EC65F2F9DD341BE705134C83BA04DD32064CAA6ED894EDE02B81CB33FD86056B40F303CC4B236EED3BE34D4555C8F51E8BC20866EC97BBD57FB754956A1E52F371E4287886AF8152347589BCE15267BC603E9E707A83D14B0AEBA6E94205BFD62F743CC4D6C401FE1E1CA130872083A039F7D3B52CAC89A56EECF96BB3244C4CAEAB615E2A45814ED80A153EBE5BE67DE0F87EC8D48A404120D2DFE26395AB2FAD1A1194C89A0AAFE42EA15B64AC806AF8BAE70E770E73491E55122303D0F0A258086033E6716E58F18519C13B13E07B4567B8057C06F68C6650BD7225DE1F8AFC79C0159CE5161652A10BED61895AC2495777CB165912C0E24331A21B6F4604E8D6F689E06A1EE856968E419FD01E8E36BD3A071F21F9B4B778859C0C524DEA1E1F8EFF0D92DE8EC7BF8FC5DA396046CE9966C198B0B1968EF2776C43278A0416DC2904167CE9DABDE13D82676A8AA9579564356774AE62F4A7D86B43AEE8EC84B3FD55445F1C84DFFBE038C0D5899AC1BFA5CC258AFA4FEC802737F6CAA0BCDA4143729F233E4AFCA6B243CD21B44906A5EF8F2A45698E91C23B0F3BD7BB03548BBDEFE24900B400F5DF27822C2434471F460DF2118108AC3AD2D7CF5D5D824014546D29D4FC258088B2EE8601729BE1F2C8509446FA37FEA4BA7D057216A14758C88E75D7D72B625C50B18BAED848BC23B28B775007963C010B1710243A455CF3F4F2D90363D4E50339B990C449ED1A26E95F997CEEEAEF283FC98D59C172F0CC9127B564AA488E3B18330EB1F945EE48475FF1968E0C2DAEF0F582EB5D0184A983159A894687674ACCCA811C570B5452492E8C79C21F8373E379C5B189948ADA6099A3465003F8A1A3F8D89565A09189E8A9F86186EB786C4491C728542ACB5B333B0FE345FFBCD9E0069619B04502A06ECBA06D6C3D9BE70025346A4E879C55BF000B9FB374716DD20F41B91BE43059AC0EE454D11BE599FDE39386EB72B6E195365D061DCB06AFF60543117F7742EC0B0402F398FF1E3AA7777400108C2230F266F27D3BC29C547FCD0C57EC098CECBBD10E12CBC26BF290909A62E6D359A823EDFB728E714ED8EA40ED58FEBFE6CE2316D8F294CE3C9EA68F08091659A99B3C12F4249D931ABD465F8BA18205F57C46BEBB5F245D1F9F29C64F3791292A8F9DF9C6473418AE055351962795185DD60555BC277C8A7155172408F0B99B78D43896CF17755FF5200A7DAF16112A93BDAED173A2BD934021C22F25AC6B761FEC2B992BD8E28F1246670472AC2A2A76B2E15F336F211E99912520728FA86C130951A26D456C47D5C51B8322208A0944704A815975DE32074DDEADF567B9346DF1FB066F687354828D5BD41A0E3FD2C38EBBA74010BE647EB75E866CAC2C8289B3A097832EF0B2FED44F6AF239A7556027C41E7CD42B18DDF709E75E94360C0B404060CE057FBCF1B6100E2D9516A91B7F7546305A447C2647F76F588ABD7EF3CD823CB6042B59160B8BB1F14BE18AF1134C8959A84E25C1B5C22D1BAA419D547107791E1CFEFDD112C9488A9A57DDA15FBF312DB3A122F70BCC5BEAEEFC35732070465309D2888B65848DC47464AD50ACBF88DA25384240BF2E3D4FF2EE4B59E85FC47F7127814EA1C014B127B1F09BF09FFAFE7E748EA504B6EFD20180329582ABE04EBE4E20C7C508C32B2DCA0BE8E01E80F21693EBF250E1FE7237BF04C58E5EC60116BE1E6BE90655D5EECDA10D59858A678A7B137F82618A913096D3C479145D361FAF0E926F2D9C87CADF302A950DAA88B4F9CDFA66B1D111C3C9B80259187E78B2C0DC3ED3D6DAADAEDBD1865" - }, - { - "tcId": 36, - "deferred": false, - "seed": "AEF72BA72607B5D3E49C579752BE9CB9FA67A01B2E8B654EE92177BBA596066E", - "pk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F5CF4217CB02FC3BBE5E08E9A257D0B22F3CE939D6E809C88560A0847C8A51AD8C6FF596A8708CDA9CE65190FFE3D24B457FB29C88F670803DBDF7042F8A07A2CECF2E8711F639E561B84AA9357A6C403174E942A05919B4533E28BA1F4A9724C1455A82FAD68762CA8EA8EE25A024961D1991B2E4A5587D2F48A61B00B348B059A44A41E44498DBCB2026AB577083A10EC5A527E27047C3ADABDE815555D16CD092ED86C26863145C296C9523DE0286328BCC16FFC27D7A2E5BED590D20B77B51FC2D5646DDCD385F79D03E63AC83B7522F01FD1A9B5A7307B5D6783006E935465DA875DF5D53CE648B0F570F5646E607CA5D226E2FE06451CEF35E687056AABFA25834F69275634D2E223B2814848EBA21EDDD175C895F66EDEB9A59F4D303C873236FDB5C5551DAC07F5693117C93827201B56109C398A490136D67501EEFE48BA2DCC0E0DCA3E7BB099182AEB71A5833A258985035D8B19AFC76B622DAF4F5A441387F069A6CA00F4077D22E666E32A9953B34384B950FF2A9F4759AAFFC066BAB54D6988CFB35636F2568E76ECD41BC6823054C733DCEE6AB65870DE742A4D61AF0FCD5ABD5210C40463FAA984A27C9E731DD994657274E3FCF55C436B8A956FE21203CBCE1EC1BA965A8E43F5580F9AA4DBBDAB65564DBCD86B1B28FE0033CE376049223B08BBBAC9857B5104CECC681A8003C40295B69E0EA73ACD0252DFF155AD4340BB95B9DDB0AFC97F2CCA3FC70052B2FF327CB4FE8AA6BDA893BA30D2BE86B2430F7A99DFE1634B98AB67327D50C366369AFACB1C842FFD41273DB7510E07CCF8C062AEE290095B3ED299EEEBC585C2BF2DCCC9FC3FED5CB80BCF8A6576E67EE732979D3D82D0619AA0F0280CDF50601AB7A6E3E3A0F62F24A704E6252293D0F2C343B2CBB4F3E988B6309A287EB4A3943290B9C82F6EA93768DFE50A8D51313443CE3444E4B99790964B7282C49CB98CE2C28C254B0D508677DC2E2F44DE41EA0428A5EBC125E7CFB3034247BFFEB234DF2910B7DBA0F4DF808C1EDB42E9234A1BE15735F0928F05880EF8FF25E7C03393A2EDEE2828B374AE0BAF1A63D266FEE71DB913FE4B404DE35E28E1584AE938F9578C5B06799DA2EC43803980F77850F4A557892DAFA4708EB4D933510770C40DB4DCB7BA4F8D9138D78A2799662990FBD6142CEE38B7CFE9F7D39ED50B4327FF111ECA523714A06C642AFB2406299362D16472CC49B9D01A6E0A38880B447F3903AEEFBF5A920145143D559E623CCD860432121B5B0161A43D8FB8280AC4E7320A412E36053F78FEB287EF0AF32E1FE5A1C1E9BDB6497E7A4EF9FB4F0A2A9983F40F66C5DB8AD972E422E2098CDA4955812C09E649842636B6CBEB0E29A50260078E3505B1235471DF74E2E737588078D8641AF48C1AC39CF05632F80C99836B0935CC15FD80F3FE9E941E68C3FDDC8DF1CD641722288A20EFCBB09620F0376414F34E380E13CB09B43B105B3A22A4F54518CF28CD644830BCB267D18793542026A1258F8E3EC4920FF798152E054444183CA5621222006AA18DD9E42619BFE90F35634967CBED9DE93722D38D8011A5EFCA178C6314A43F12798F150FA2AA9BC9C2BAEA30008BD61E1BF257144B67A704BD43823B3E06F6E251819CEEB264383CAEB49B1D7180AEB56DCC735A09C0EACB926BB4407F4AD016346BB9F68624087A22F50D5EF91521F3CA8A68906E56761C37A5F001B0B2120CE86D1FDD86A2F795086C1E63300EF953DC5F94264350762780F703F89100653A83F9E80E3327D6886F85A6FB4A68C22C114DD54DA899008347F08C7ED6064DA26DFC8F9250DB0D33263BB5ABC997A949D845AF963F3CD51CF4240B6C2EF3AF3D0BFA3938BB5F48F0562A06CA59B662D726317A8C02AB28395C3EF958E06816CA972792C6FBC051123C1564E65C9FE5E13A8E91621773694FCCFD4692D4D35A27F6E2412B49804CE472672692C636F3DC22A2A6FC050CF9895AF34A33851AC37AC2E7A2E42D401088F119BE6D66BF6AD4B7C9BE4B65937C34137924B5F9B789D93F598C5162C500C09E8EC2E4CCB47CFD919FEE8671239A3159534FFD44711F515286F4C5F043C02B94727832F41862ABAD03EB0A2DAFD8CA9B766AE254B1568B75CB65D8491B488DFFBC6E5DAAB4F6B2910A18B0139AF77F10137026116DB1C75BB206CEA39C2EEE4A760A37187DCFC9A3BFB67A7688190D5B408B8F93404F22BCE4DCB1EB2443EA95A12495F9881E303AB7491056C1BEF4EE4DE242FB2ABA8FFC4210D9290A291549804F308D1F1E79453B8EEF08B7E94F306C9350263C2C3FDF9288E6B77B74308548BCDCAACD999B72998E6F43B037AA19746C92964EC170D8F4C45C9E276CFB38090287A1FEA8C2A3DE69F246F66BD1EE6D99BEF25D817136AFF0518584C04103EB4BAA1B0C13A09F53A5470CA0D3BF811F78524F8BB1059A6AE908959015917EE1D6C458067B0238125ECCC3870465FC8DD6FCE667DAC35C3395F2F99D9412478F69286176F842C12480AC3C1F10E17327FF41A9C9F3CA25B1DF71746E38D495AA39278EDF66784200E41939ACA3A5C6B30133FD34648CBE9E05D7F8203C4ED349F61B06898DFB59472A50C5065FFA3EBDCEA251B37FDDBBB1638B7B7ABC392DEFD6D8C2A623B5F8C6B2AF21837E4DBFA31049262A89C6DFB0DF74D4236C231CAB14926955BD861", - "sk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F586D92ED7533389C0202DF540751374583C97B825C4370216AF4AB36DDE304D43D0DACA16C3F5087918EB0AC74D767F421FE3D1FBC7EAA3AACCBD5CB5D09F333CF4B78F53C71C613696DCF9DCAEF19B3C1EE2EFAF0D828521A6CE01FFA7F61A9348527342744071064226038054116606320141710221271257486326667037121338804027786413333762444565247120260711112481538554528818355348570835703121724850217680085831247330511727221071532777537181252433162511266101870334182868555603545033287523215207404240325534605842331807636112112578123748213488427847140378435253062845364733136513038331863665164167881816537665065848863257260565026575136330876105673463618643727206285030703671806436818322112274163527184354571804314504110461483305276281527585556577604221866560252247227633024375431035511576001826578516576032642038878266403868054841663872067833221181722456668288121320355140013335216064378035186542241363324612723361344715333431546685723672037350475440828822807350518723244126165140441743684004218174044766245273324152220377505024108077250427538553813160114380427476282474087652860170448374247256182540047212386666433380053013860147850648461451277375447570165767818683367627182818503143056367684131733603212447465727282433537555073853150367373683784851317615160568487055012186553755658442635833444503161210303854541265435850086145313831714057147057120854520605228538737665130427538038232223511606506354232283180315487066067657113311376130525682787352874263703354678684763224515801735756766354734254556702053117703010838153428847256422882168222781354461343605223116617002218761072342227774472342364510245075075620557536146654153377441306448752117273127761641170377382766582167256065853886542021656228353632167205880115560215680560306250271500428858201477207883872516256244502862366650053734802237606638246801357641266043847685428523576470862427772605087355417711178011230254130776185056386880131707363610348377857813822161177008735870862408816363434033522876874245827032130687514032517084000404550331071880041411855515353347350748833163660475436163376714460516374334807032470377016148566161642212524742565118144158720586251383718220750427038855211255848338323237278850416582248665388024224073714504355652603153613411853445800308877122483607514485078628638685574852023328770115826675755280543602581333212557321868322175661562521048051805784217422803480451341517247206525267651220578854840124507450130330783180120225057375467878261257470561528834570641813282421264533224140164101541355026886165283383701241282521170736675535341222832655883108544384278163414862621416360817830726530353375153418874861316345662582058367316632462543274165056545780126454850320726117724140462523727278438211532634765078536860488641558502057617183425565211328306367418664731407825108631866633714182740052163310713218483574715351876351327521183865501355706182848758085863563015436623450348571177625576370888877313167468486714351112267202247833152524060633413850751063367135630834183838550563386607380546701865460634035501871746162676710175335260356668310562162041187655378322137251758003287138288249A1A4563679824EA12950B80F31653B5EF7BEBC201E938EAE950102A93B46E11F5123313957EBACE11D440BDC9459D1B9CDD345863D81F2FED1C4B534D0F17E0908F1FDE10C037FAFAC1E0FC865B74D15D41E1211EC7AA0EF69F87FD0F8F9CC42B0E0E827570776232D4ED86A84D1F7A2201B2F29B6BEC81A3238DA71A1AC6667AF0A3F35124133C5F3F10D7F5FAEB27DDFE82B59C85D4EE7340F84787D4EA738D16861E4E66238C4873957D0EDDCA68F884B726E10AF47E431DC904EE034F9F491208466EB6168FE6B399E5ED34E118A77DEA15BFD11DE8A531C8C25F4F73F8A35282E32094F291308B6EF60DBF7B54CA3B0F5386AD179DA593BB9C2B7A2461C2B7C1713231A1769F03FC1B2C7C152AF80809453EB6E97C8B4149A04626C93E150EF3DCC298C13A439CDB871893CF3456B9A59FDCDD6E5A873BAE7E5C778C99605EC7B01339D8882DEE88B7DE879BF3AC89910C00F99EF2E8DCFA2EB7D8FA6B5555685EA2B5350BF55633C0AEB1F244C1026E62C82A5685757D3446B756D9ACF6C049A18EC4C9359B4DB246D9B455016821EF4C598BBF834DD6FF82A494531BB5E0A533F225D068A1AC496AE8D28F08DA00DCB8209BD40CBB0CFED32241FFA1C33275A2565D1CC24D3A6BAAB228C2D8764680A105A834B36C18A9D522D0A25EB34FE00B32193DC9F976B0A23CB220A6799E4D596EFD98A71EBE0454E25E93E233191D14A78B5DB29D4CFA2435CE41B13404A2324517F0EFD5B59F714889C66DB5327045DA45C38E3DC4D8AA433E1962F9313AECA58B3122B437F0CA17B09414EFD52EEC5E2F94DE8CA5079CC79F1A11E7F968844F8DA1CCA85D9AF2759A3FD75A9EC44BE6857B403C88E69F1A9A66764CE7F92E622D963E8ADE4BD4973D739FB946ECEDD9BD829D5BCF02FB87E25DECD98C8EC507EB5FCEE4A0AAF62970A6C4F4D66FB4BF7FF735391A27DF24B848E93B4E1CEDC8B77497A8EDB73A3C9AA8B4EBD9443235261C2DCBDF5606DE190C35AD76494DDA71E9DD8EB70DEB2649CB944A60F50F38C4B6EC1E64E12F029D1E0A2D619E4E783BE3AE5A06FC4A355511F177411CBE64395AF69F744773572B5073FC1BEB8797D0508204B3658EF87C62D94EB85E991D2C7A4CD02DF7D64B6587102D4FA321D961AF7116CB37E62CF3B1AD0C3FFD9D9401F175A359D69DB9E86EE9A4255F1574BFBE38A18E94BF0536125045C20921D10CEFF864A3A583C5CFAEDC1151CDBC4C31043A8763AB3714F942DA758D352CB03AD534EBC81764D21285B10E0E0AFC28CFE72A84103444A2D1DD6CE6D7964FCB66242F08B36623800E34510DA71F518C941EB8452C1BD29D0F6A575C7551D2A208CB579F05E9F94AAB26AFE4C7484E86CD05B41BC669B7A1EA0DB9E9F581528D5C29B0A684766E7881E46625AF5D0A37BA1D50BF3F90FE08697B20C7A205362943282350E1747A7B91CD9D0358F2101F5759D81533FF5B83190BFF33443F6C73A0D3CA0BABCB4A7DE4832DD9DCF2A144690F6DAF40431C7F9FE41944E4D168474700C8AF6EE39668FE2ADA2F8B9F015314EB7C230EC3C21229EB886D37F17F9457233C055A7F4504999521EF38CC8B4183088B52CD9A8246107C46108586D8AC5EBACA4072D8639AEA5743086B46553E10A6803BD86B494CE06D7FE6AEA812946D6B939A315F7E200A7DFE2571CAAF009C909FCB75938E421CD542507F50DE26F813B41D10E67E4B5756E8412E272715764C1C097D27434E2D2CCCE49E6A4477CE65008EBB1365865ABD4F709129E7E045368E8DDB80ECB4180EBF5705F53551E2250978C21874FCE6069D4A5A51C2DD54A2D61E189AAC9247DDD58DFAE54EDB816A5895959E1BDE574B0316363658B71CA5A3B859212799DC9D1B1EE75A8163D16263D7024D03F76FFAA106E7CABDA18B5F943F39B420486E45FEA2714914421C79D4315BDADC6FC2A77DA76D2099C28D59D865850152588F33837A06E33323263ADFC75705C1EF5E0E6703999E3DAFB419BA86ED5CE3486D6655D6E320C3D43D98E4FCCD31E28CC2F51B524414562AE41647F16EF6AA763E354952B44AD5E5576BAC79C2DDA9BC2361A08BC24697F6A129CE30999A3453B3ADDA3410DEC30CA11EDF278B47A6E6F92B0C6670E118EF97138C2D6BFAC34B20B11175260994BD93D41FD44B7BBD5EED310B3C13880D095B1A73887288BABA953ED922A46A42450D377DC23495707A35510EA3D0AB741BE55E1107A439F136BC7E1D03B75E733FD6AA3236F379C7825FD5401D1217003C11C422CA7DB8A8AE40CDFFA642F76544CFF87385E7E45FAE6E68347D45A2E32FE15A25DB579642B488C05D3BBF597DE46CE67DB5EED0EC59641ED85281D5E2CAFB15A43744B3B60DBBCEE50990DA608DA0652AAE2EB1CABABB36FE42C414DB0689112A37DF8CBE831B236967497F4FA17AC452B2BD8935211FB423D415FA916058E45CF7AD447F3F19660EA9A069C447D14603B23BE2C6722A581661798A1D9348EE1CBE235243645B20A6F0584621F460D3BAB447520372F041684942C76C7CB510DE9258BCAEFEF8FF3B7C3AAB4D9C4F3FDC9952F1E4B3A232EBBA94FEA8DFE75500FD89221B7339A3C61CF0B44CC36CC17E5339137A5FC7265438D76ADBA37465E9E30E858B5C9B4B162B4769EE7EC9A2D2090B1D5CF77A86FDF7F7AB76B15988703454FF678AFF7E7D221F2A3A5E984739C214BED903A842B4DA9F29E26E820A2D70EF0217C544A930A8C2150FF41D6F1450DF4BA0C81AD2F6AEB54BD5F82612B11DD9717112F424DF4C3F27006B37A51407B133110D0C827640468B287B8D41ABB6693D7A041892DDE1D494CE08ED493C59C68E207A281F953EDD91B978D31F459DDD6BB9AC2CE212C5BF3B15457287E4B95347A1AFB976733BC848A709900A08FCAA732F6558BD818920509933E915EC76CFAB7EE55821C56804FF8322C246CD2D14B66241D0D88F1670124B5E48FC5744E4DF74F5EA51CE9FEE5C5ABD4523D88B98B12E0BEF3EC7CA3AAE48B7C3C311A8840D593F74134CC0D4D6244051AE18C44E5308B3A997711735B438AA4D2409481DA436A84664D64BE7F941DCA6C4DB2724E7F1FED95D4FCAB4960ECCF7A478B6F6AB5C7674E01867D6DCD3BBA6D51747C19B94A4F0039226B658BEE299F23388FB5E7A71493EF7C2016754D020825616B2F4810FC765A67876F979E73DFF831F0ABE6569AFEB611CA67997253730B44979FFBF105F0A06D6FB360BE8877C111D6D0FDB5D2578BD95B34F4408D7D894B8B211FF1F753FF3290E54A9D05C6A5CFBFCBA0C9501FB4441A4B9362B1537C589BB27A17113EF54B068B28FB6F74474D6FC5AE8AA7B66B156FAF6AE9954F52518EBC897172971BCEEFAEADA9B43E4DE8B074EF0D7B47800930D076C6592E859C722960D32355A63DB0ED8138BAF10DB3C235293944153C60F09739DF20B96F76A0171C11B8A704AD44B035EB9366567F9B429AA2DE76FA9C12D285B53EDD61AAA85459EB7951D" - }, - { - "tcId": 37, - "deferred": false, - "seed": "16759CE55C6741D02EFAFEF5D7521BC0D2B3ADB55088F61F0028656AC970C70E", - "pk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309168B20B154BAF03E312224727FFD0F08E7775B2B9FBFDAA283E0D6DD20B3F8F0EFC52B971F2203B8973D0AFEF578DAD5875142780C13728B3E658F87C1FE077B39C9CD7B7F84F28948250D51D5C3875E58A74DFA7F795C2B0957C6F699127DBD0C2265EC4F9CF0DC6C3D725936B3078ACD64B7C6835D5D21FCB9CADAB91A3DB704958FF70D33C1FF00396FA561A1BC4B4B0D069A71D287FCB1CB90B369C96D88987FD3147ED2838C7C15BE066768C48955F3E1166C62A5E3BD3B66151B0291E3E6438A682606E15C04BA8F56BEBAAB1E7008391765BF0D55C4C9C7E535AE9E01FB3EBC261FAC00B483A77537231C532F453E6B6F1F4D0313612B907005C3DCA1B733CFE377D4D9AB990DABD1B85C3EC423992CF77667D685C318912CDD91BF31350708FE8F401031E57E06878CBD155BF260AB5910757335E98026B22141460CD14CEC795EB5389D025B48C0F2D9C1B19A41D730B508F0C23DF59A93C64A7A2EB32658080F546479955C410399390E2273AB80F87F28AC0892D059E46C338177ADDED57900EB14D554A0F807284CA2B1495E6DAFB461054B0E6E14E7FF9313D1EE9FF83A32DDED566836CCD22B72D6DC6E52A58C7E56ECFAF68133A8B6CFA5F754653EA2F0C5AE9D26C10631B747BB4A452A54BA96F59D339EA45DCBBC0ED32028BF612753AABEE62D59A59D1660F88E6D9E2F1679C7E4196075260D45C9C3058961F0BE3BE6F61D26C30AB6517BECBC07FCC4B06B98E7B5FD9D14EC59E7CF89A4C7E1014BD3D157F0EF8DC37139683F21AB04E9AC8C3525554957294009796B80F0E1C05FBD63B3B1ACEE497DFA493F2559379B3F9A5D94D739BA9AD4214F746F4103F64B0DA83F779D2C404CCDBE4672177956F6600DE124F820E799F69EF86EA372F49780EDEDBD17604606971E8A41BEE1770A85B7DFEA6E6B8B2810E41D8ABB894A506E0880079E093978F11F9FEDEF1CDB4CFC370CA5BA9CE0DE73811CDDB1E7B2BE7840C3378A84ED126CBFC75C209984ABE1360DE2139ACC0363979EE99449B50BEFF8B48AFBAFB27C9458C9A914F3A7607A8E8707B3D2B1615097BB80F07D83BAB83BD863D46020F49BF08F343DAEE8F320AC9424D36BBB91F3D7A8D00579B07BB7C53BC700CF771A420ABF7C656F9CDD5134B2B0C6FB53C8F93BC5C4A475C11AB043C1B0A50FA5B9FA29D5A1E684F50FE9E2E48B8BE54D7DDA7B94EF28274EF5B88C3433D60E027383ABDA44DBD1E0CA737B48AAABE9F98984D30F2DFD50B678741993B8A5B483A2C56E038046B64705E23621BB23870514AF33B36911F97D45DF2D47DB94A4CBFCDA78240C77E9F7B99710E5A59A9EC2F5C89DA2E9C927CB40C58E562CB0AC1971F92A5BC1EB371DA6BD1541662EC4F0F78FF3702CCD723D1B4FC3AFDD757B75BB44A5F4DEDB9A63A15FE399B6E59928CDFB3342AB4AEE2F4DB0DFD48C5969F7409A69DE1CA6939D9121D119AB00B16F934707D83728916086E22F1E09B80A30E3DDA76D1F76DCBF9706B3CD4A3554671D9092E891D14FFD74DF0CB8835951D0233BC1068D6D1BD766E487144DB791DD5A72CDFB5A39F0C5DB47141706925FFF615A2605CE1B63792D35197CB9CA7E518F27E65CB32617BF91A07D5D14C186A4CFB7E36ABDC8C71D4245B2D70F20B6412D478B36E72CBC2E1D44B23AB09C5B89C4725CFA3CE27C79FC2F7451DDF529183FE7C1E230097DD5AEC1F23D3A817ECE30F843BE07FE76DB36FA3447362197E69575719E80588E93E4A57C11FF8AA1D8657E54B1425B6150FFE3BFBEF5BDDD58B867CEBD10DB74B4249A0B650E3AC3A65F828582FFC7332F945E82241CFA3D25D731C01FC7601E2F5874983F2D9E9D5AA781287AE5FB25F8D9BCF73EF5576CC46AFB1076B95382D89875CC30BECC32719098B5BB95FCBD22601930D5A76660B67870F269965F6115E1771D558631002E7388C4761AD4C18DFC07C3B93E7D11257099900A9B6ECA8086970B9CD7F0EA9C1FDF0E37ED7F18F79A81EFC726780F544F4E4F6C49956EF2A70F56152F030BC73C0EE7C57AE991F7E3362115A029FB411CDE0308F2B1ADD50590D7B6110F161BCEC333C5F70A52F6EC186FDE7331A5C2EA232F91C7CAA5308E79E85993FE7FBC06930FF98AA4356170AE3BB262B22C24F3971B3092AE0C4EF033B752B17DB8AF26F660C775EEC805880E12F0F87D5E1965AABFB1D235D5DE332B177427650E0162C7599217184FAADED2CA7946F3033BD6DBD59D9B2758386F463D187D97F2CD436E789415EB50D4A567B623A45B3ED8E1E8E03242E7B85CB501C04BA6244AC3010F7FC8047DF6F46D2B86662CE0C3C6F3AEEAA5D8AB02FBDA8039EE7385C4F139D47F70C5623B2D434A138BD4DCB5B7C40965512CE283CD83B63DD9B1739B19172537C6C50CA6B212117EB2B9F26A94151D473C865E5D860B272872E9113C8399A5A150376CE51EE643918EB0357EB4E785E8BA5FF3259831D63195BF1E21FA81F36D213D7C8BB52B4D9DC17D1C592518B6B97D0BFDC160CCB1C44CC624BECC28B49E294F206073185EB1414A4B80B18B376BC1CA498A9873E76A225DD2E8F8535FC267E40BD627F6ACC8F94B8A70563E55823775C4C58EE180E3AB69E42164E3778E389DC4A4689132CF41BC3816437B97AF05C126D658386DD57159CF61124448FD580F539DDF48FC22B46B103790705A63E0", - "sk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309D14E7CEDDC2A30311AA8FA8F33273747D84A4F0D8EE7E194564633AA61E52915D5D8E2DBAFDE6D3F5D79C3B28AD634EF193197738F18E4A676CFC57CD89CD0AA6F0E234E1EF9628DAA5784D6E88DD9BD172917508BD299439586A2C69EC9EE37516408456805453875186164354434762851144032503062044733174535345336243074007370072077081545713763660866431727740068416380203118388213565687636452870788087330528072715111223815614114023416424628572273654761365202371732860200885645176752622184560057533370811066568577508011873252658610003344817466632285818231285557473165208431105636756216358276868345764816338628113787615730106550304583831526218881611205302483650721835183030737847070762778474055733402548878760487075428407073405005144801723170186433372802720438860108856746505547118015547131122453566773381342522407281545850801183484018184666083467106168381252845568124004675454602314541338432622742687024545623154163133642142284145826740831864111748641572426058870067085812666034786330234235402238130001884155852477742051765281745785073343582078116414130602308708382046610771844771422553017257116530515834771623210643083653453123174273203072120652165461603377577853268801105230325786774860038401255212558785474148811005612536620386306604704351810446347070743027613512061524183212465467663737220484528055077682744477361738537607035114778361715572673801101334710201843154010635705268423258373218118673778880168467346108724815012616873216832455740487844547741518240111500865103473675713041381803575311157872410255701424078321127582473648431113027582351430662278746751035665641182434584325772861215525770615370625335026857551177161702753358126622760777226647078220754285585438101185067104306615265684566031171156370644844601446724773223546111143485217226474815348070603068162168730827730621315400104575240651321414881564033855112770221780800225157528348444266604837745836675662685500716522842326213800620274755378763818201620041432256675142301443166263778606832838270748825315058517802584084457456813426874047456608883514726678781223637518532315712014762086217806235541401078781766415284331567726815303634475775271858640741021524306284275220610644874785084105424161267563884428838216142316446781311233544824647208842466574102173038377413542118331143367050032021043212425764087110600105282382455268312103048345414288052540078876487667764823025775566311214818185543787576556256857315236518510021215252482803706248475668860228066666672561867742220301027605488000438235713416236536151436128508016780048467212168013085034575086368465731676561760082315388865064664006463851448257676647715152480874332803114601541422802066821101585027654741377572383658717163467081225212357315441278864346071400588203756538864216143433263515106785455401547748303686407408160384157550870668870806518373802647386257117430103643478524250667688677831215028557767150786248416665782857323615017621284673503646038567228556675312835873622053521367101744308644383425387466430243221642874703241566431377885506752554645704356662457447386007618112165350121803204124113324380005611435572303115406311786186209CE53C40AFB0F90429725B870E47031CEA4209326358FDAE2531B5CE92A42C724AD1D1CFF79DB6D07F0215E6ABF1DB5F9303B27CFFC420580A0A8612C08E1F54005EF429BC8378F59DBF6A3FAFEAFA03D9C41EDBBC0DAD976D8E103CBB49A9DD674BAE19E45D44D87BCC9D83E8B6C9D99E4EC4406B744718F49DFBB12932775C82161C63ED883BE33FDC9F724B44F2CC2544CF1851237D53303B82A6C8E2381A7B92345530A7740A6A456DF5245388726AC8C568C075D849EA225C42187D25F435DA2543E3842D46F747400AC1D566CB1763133EAA110B66A72E025082B70845813A7AD6D4D39F017C9E8CB006C11A73C369DA6E1E20B6282ECD8D0553CFDC39621890EE0110F0A0CEC2FD1220C7DFACB8DDE955E336C9536DBDFF7600A64E59B113C28C86CE93B035C75E204F0FDEB7362F598475DA64251CEBD14B95600B39269C6C5FE67462ABF76B26363946B3DE38F6A3A53C261990A5E147CB12D093016342E57CA38E28736ED4F331EE1A75129386DC2A2D8C49FE616BFC5A321B5650FE51B38EA51776D1EEBC454AAA446B1C2EE18C10690AAA7889EF9C2C25FDE8E988EDFB39273A0D180653488C1C541308305ABB2E8C430EB68AFABF503DD082D8EAE81E196781A735D990CC89E024DD22901C5A3C382960D25B076BD38E01FBFE7173997760ADFD97D94C49BBB4848DD24666AFE02AE5D592CFD8354ECDC74C1C3BD713355D733E7BF531031491F869D01037AE0336E979F263D7D1217EE11554B90BFE16A103CECE88C19FC1D9B5987BD0557AC9D09F07B0CE6C01D2FBDBEC726FA5C7712E60F70F1AD4C566733CCCFD650DF6ED846727D7C3D6C8412843ABEC36750D8296776123A10A1FAAD44EE0F19DEACF8C7233C8E456D3964E0DF8603FE8BC04F73A261E1F37EBD5DB516645F4C800186A10FEE9D9271B68A0B27EA99BD19ED87E91519F795C6A1A5F7FE26D0B07D9B618CD7153E8B302FBDD7010A03A58817D00F4B9BB5BF8D9F9FBFC5FFB3FADA79F1FFDA8A028F85FEC0A6B74019EE18CB7AFD4EFCFBB259AA3104545A64B1B6F226A72065E053FDDD950096E8A7FAFF0125B4AA880B78C84D02F00421A72942C7D7E36F3D346B4434703FE26D063DC65BA0A9F15CD05021AEFDB4A5FF916FF20BFEB723F90BE1517D49C16DF4C919E9F46C54A508A9D564CC781C2271DC08086ED0265F60AE93D8BDD7D1A6AAB191F3A91A13D7F513A136385D94C83E770972FF7D4602BFB1A95DFC204CC0024CD5AD7EAD3B5D464EFDEE19A01D57AD19EF3E47BE36CDF2913C145B77A144C9457841F5A855FAEB9470BDC69641EDF4A800F20BF88BC5307DE87C5A0CDB7114ED6F18D7638ECF577A406110B2C343C6404C5A4A1E235C50E48C81F60AE78A351080122107DEB5B3E296919881EF977A12F3D5DB6ADDEC4A89E31DC7FCD81F217E31674072C5E199C43A7BACA72D697A3093766BAB7C2DADC817BB26257D032AF358DFBE2CBCFA8C2B87A530323D9EFF5709C2AC3358657A51C13C0F8B55BF17CCB04A29359380208CE79F80DC384EDE6B501CA27E290E51B02321AC77DABA35F297A552E21AD4231298F58C91E56FEFCA7C66D27BBA45ACDBF7B63DC48BFA63A0753C47822B39D11D60F4734B81E7FC8895E1ADF2B7C4A4574EE9C0F4A829806A4A99841E6F836DBB8D6CB007014005140D2C39DA195E9429A23B889ACC8223104125C68DE0E79CE6886BC06ACE7479CC99B3CDA6F568FD8A02329055EC10DAFA1AE57E09EB6D54A9EE3444B73F38D2E6B8224F7D7B2C80C490C28FAFDB2E22A83BAD4D75658DF39F4372C0B9F1C50D284642C303E5D7F54DFD50B5D097E2F1DF300D7B8706461445438FDF83CE2BE35E17CE5DA9E86A843AA24072F2B20C5377841DCA8A45DEB6ACED51B9C95FBB93B2E4D80274142DD1A20139B7E1DA43748F1DECAB315FECD77F74ABC890E6443917052F428FD8A41FC938343A3DB5D89338F2AF43B84E83D7AF389156F88D06FC97658B37B9A6BFB6238108BAA40E9C6ED8A348E2ED58FAF6EE3D3833E4F0AA517CEC9F7D83F5DDF46F88DBDEA230F761544E1A10E0E69517E47F94D7230C0C60371E2A99897EB97D7BA3D8B6931FBE0B3849265C65F1E2B8BD120645BB724A0EA60C2CBB6FE46287387610F139CF5FCB6B0BBB32A44BA4C3B705903DD54CF0EE1933F4D7257FDC4331D7ADA07FBA0B9179FAF1FE3C8F4F9B654BC6719AB70F9B36799476EF0C4449F1CAEBBAB550F52041F88F0F4F32A0697FCD0A28B73E26A4D8FBDA826A680C37B3006B059363062AA7B04D561D38170B831C47D656AF0EB7BC00E25CC423FE75DD89BF7527BFF04CA793CFAD973706D5ACB8C4362B4ECB3DEAA59E9ACD999137131A1A324FB43D88D9A9670067507FB95FCD80B29E675093145442BB9499428CE0CD635D997924AC4C38C5A21C452E5A399AA1BA6CA0050A0E13CD6C612E9E7282BA21C4DBA82F4C65D6A6E0A5D616AE2608C804D463BE286F73526E70719EA9DCB16790B31A6AB7087DC60DBC370078BD1C56219CD548BFF20163B8568056EC6DDB1EACAC12C873DCEA792BE7B6CFC7D792FD57808FCACC0C32684DE298E6EB382C0CC03D6E6AEFF28EAA92F028757D27C4809614AE4372293CE517CFAFB94D6C49EE963D2B887CE13EE6994E56BF47C7927058D1FF0DE5C7DDE04F6148F8B0694FB6D99DCC4F84417EF371F76638B4BAF8B83CD7810116DA648B202DDD928C91B0DF5E9D4D1D830AFDA050397AC882E315F809374C7FCF31D9D011F367F0AFE7B0D05FD0330C3EBBF0B5003635D007461B155911D26F93CFE7822B509B7149771979FABC066E73B5B959187FD903C4E0960A5C748358F7CD0A86D44F58B53CB53B37C47558E1253440250D0CEDF6E19F9EB8C341DCA787E05E1E7BE7FE2DC244E2B5F915BE5EF2CC789DD77F8816D1D29CDFF437F4D6C76BB0F99D395B66EBAC0F8BC4414260B5AB7AA5C430B330A4B325A725B709DE25BAD74D3A08F6F7F76C76001AA207C54A83EDDC4368A0585EFA3C5439CCF0BDF11F8874FF7A196A1703004714015D28DB1BF8A626CEA8E9439A0919FE802B5CA19F3A4C1BE83F0ED3EBEE4A03A3A438DE157EED40FBD96C379CCFDAB89FA5FBFE123F10D552CBCB3CDC055AC854E52D5198BE1C745A79ACC57660C22105A786C8E1349CCBD5A7A76F115A7DD98F16308661E2AB3842AB455D11BC3D16658CFF8C4E128E36BC8912461F883B29164E984F8808DE92AC0AAB4CC3C8D966B365312A6B525E421780FE0434FACD08E09FC65CC84B8B21E42FA7115BB5A1FE4CF3FF75133BFF1A437BF2087F7E31C7D7C3782BB75419DB512DFFA88297B50C4BB234435A301489A066FBF12A6581F634EA9E219C3805CBB63F9ECF1A47BD4A1E5731CDDB28CF8C0C40F8FFC2CF7290503A22F4B118A7ABDF6E5FC44C6DFAAB37C8E3304A10D601AADA7228029397B58DF0443C155AA2AFCD634E505BE5B1CBA8EAE7373C5A933E429CE58F8C520897A98D6FB3D4A" - }, - { - "tcId": 38, - "deferred": false, - "seed": "1A1520478204D8CA028FB48EFD49367A562F66452E43B305118C85B4444675A8", - "pk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E1836BE3233AF866B20CC02AAA8D87FCD7FEE1326D80FF94E2DE3A72AE84AF0FD92016765BF45634B405DECC316B73502E31674F8FEE147801679DBE2FAC60774795788B5125266762E8BCB71AB672119CCBED4EE4C5DC5429D98A6A6AA102A79F245752044F2C74992B08329D30A6B51A12A9B5B36CD00DDDFDB5DAEE56EEF87CF31CFB0BFBF4C51F1150DF8209A85231B9F3A22E12F64F27AFACBAA0141207D452C53E0CCDBC6CC09F3B4A2F1264500668971383AE96441FE2C4ED0DCAA91ED7C2452F1826EFEB2421BB1B336C7707B6BF68F8BC603CA56883E437B5075DEDE9B50C094A51C6E47B3D06FB25F5369480AE7BEE9C3D9635D684E563C50329E1D32A6CAB3AA491B53E6D48BEA9C140C14BE3AC917475ED7FDA2593883B6EB71C950651F2A82D16F446B58CAE9709C700C2AB622D824A425785DA8799FBF875CFFBB5F55AF583378D624DF7B21A97A241130C0F18EA8B4921FC70542CE3DB20E6730FDF6629566E2656F84B4C96E6F021270A248E31E9B718B08B47D2C42558793E148FF4548A09A091592F6A57D8D0242A8C2B0EB3EFA26E477D9B530D091EB884B2B720D9DE025D9C0D0E4CE5961CF59C550BF62FCD7BD659A3631159C2F0FF4DB34E64A2C3E13B6D48EF5E420444B95655A0EECCF6A8E898305D6C9C117F4EDB5772415C0A005A1CA40BE58FBA18059BB10E25E2F483E3B58B2C59EA4794A07B493555AD4A555FC253C8019AF81DB432AB4624A59C4004A9BDEE75C91CC41A20401965BABC0C55992F87F538F9ABB80EA4C91CCC954A3E2BFCDFFBE8D22B9754C8535F0F642810B2DD2ED3ECBB2BDEC3243E6D1CE1B489BF6C0BE50B8316D0045FFF424F49961157BF6853E1F902A3B118DD650C529C603E9438463204F7DA7F489CE50F7A77157346AFFE9BE973DCA0AE076B2DF85AADB46DDDB57302F92C28BB77890A0F50B9D74E12AFBE40FB386D08B394AF62AD94C0538AA7A77A7422167604E9AA9CC7C08B443A25F850B093AAE707D883FCCAD208B7D991A9C0465BEFEA4865B6A267427A7F2D02861EDD8BD6E72962EAA6D2578FD45A27036F5E9EB6631EF5ABE2084AAC7AFE8930DF7834F4B13DCCEFAF45A632E7783852CFE5FFFF87ED126155D3EE0D40CA5F2E76E1BF47FA91BC450602584301A7E8B20E78DA1290AA8700BC6F0863053D0558A35DA679286CC974BAD7337FF1B8BD169CDD3C15A17ACC02201D536869C6FB56AD8D3CC0E3BC86816E94A7C07F220D03A12C86B77C13FE2F03F455A5EB3339FC709DB02F89DED1D43967495C75DE8FB8A4F37F458159842FD69C3E1AFF691C3FDBA87027603D5B99B2ECAF26752A115B0AD623CB527A82F6AEEA016F75FA381B2325C7BC4370357C2D53FC27BD2DBB6B81FE1522533016861F1DEB34B78F3F76E12D30F4C674FFD86EF1607309ABB3F015A9E81E4E292F41EF0FDD97E81565C546E4A8A2336408A1E6F7A7BF878F352338E18A428FAC3CFC7DF4F9013678CDBCEB12FDBDA4FAC1144DFD42CFEC6EBD951555698732835B701B6895C0383CE71B07ADF320893C7CF3A50F3D067EB9BFE93F4994388DDD99928EFF959C6C1A78B3474F8311938F6D8E488BB45CC72FECAA84224E5A9D9693FCD8486F78385B81DC192B2126E8729DFA640CEFF389CBD01304801B56B23E3CD64F32982EC8AEAF6D1BF875B97A07CE44F342FD351188E9798E59EAF1BB3F80B710D732992323780EDEF912CD529391ADB9C4C7900A3B5D34CAD48C14C49AC3CE951EA8DB4E944E8DDD5E83BB2EE3444B165C56FB6DA01F5CA9BE7A7D2FF84B085D8939B3B17C6DDB32D117E1B0AFF70C9B6C7FC29264A709A92B216B8C62C29434C876A12F7F44F1D27D58F7A5F7707B6CE80A538D05C40FD23572B9AA2DF9C6C271296E0A6D9078F42BAEF55C62809E8FD044C898873EDD2299216571F832DDB7C5DF718C4270ADBACF6D5EB3C5390418F561A2ECB4CF28E24A082387CC373C3A59CE2FB294E1E547BE587E65D8045A1AD8F58936FB2BB7776CDC4794E40A11DBB22B9EE9FB06AEF118FB9A72A7B710C1AEB4761034BF4AF7042989B600B4EC8D6DCE81184B2D6FC27FD97BA2ECA40EA85FE3006566BE60CE8674CEEB9493323AB6561FEABE98373FD7B45674C8161B16F147001B1A2FF74DC51A0A15AC87F3CE086BA134BC3579FEB31625C07F698533BADD414E9A8CD0DBD21E0678E2ECD7356609FFD4E96ED65C3BB6E917C6911477986665BC9D3BC2FFD480B5624C143E09FFCF5EA8433411DE214990BB6A452391C1586C37D6AFF7941B686D564AEBBAEC3F704E4EF03968999EFE95493368853458A40266CB1B1F1C3E0249D816CFF02C42980A73CAFCD929AA9536D8AF31B5F9AFD0E323C3E174AEBA0EA50F9DB0FC04E270EDC19249D65AF12A09F133A02913388B386AA897A7D4F4BDCD3F90B3282FB48DB6EBBFB21257644DF17C58E57A150E36F78F802CB0F05FCA557D5A77821CC74A0B5D9F76E0D5A9B63AEAFFA3869EF79CF2F2A139CB07E245E9A5AE90037FBCE24CE4B076D4795224C2AA886E423785E0E9B014D4A7FFB688BDA6219DE7CCE223762EBC9A48830A4B935D0F4D9768F84F7247E896015063AAAFC1A613F575458043420E2E5650043D230F06B6A78D093B660A26573A645C1BDC900A01B8CFF95BCF5A2DB23A69A69179681F550E04C324A48BC52E92DA43EE0", - "sk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E71C7A10C110A218599985787FF89F74BC94F14CEED203C92F76B5D67C5B8B6796B86718BE88A979951E9AF1ECC344FB99232411F87888F3FBE77FEFB6626DCF784DB0C7EC04A3261153E64729255E5CE6B894CBB1085A600E4BB0B03317F8886231702201058730723376188778513655812720172542417247143646428467073443314821558505445472081234686830274636170123228128315700625348670708056866251602156687542664438717868470378622443800377346336674542226381071034445030257183710411707658015133175365315628308222508432565388880836567878400317604235388313286765740235347182434457158814480762440746180380258134310686500677042318457626156280488882282674122811574762127248672012054076701118281460302420147013883802514645737522146600613056240136251846755266808132084387728784208687387732824316004177161457846583175562587327431712865534241213236603884536300716533078315626426655820641212230038185751644338668423426326635871105864138063716425330034814786417767388845064650681757471566615121140773133884856204744373720784387445647085255465817762845160020133010878367040062383084562467661733017263525738783274220670582858510453422721212564255311404704722055575627231518700445822334550788684185480667112556485545130470664356488815156248663062318887582478736241505814413368843465478500161842054157741700704620375746677448687646640465602446038662064506232040688488545875504681671327453411777175183001230743263842058632518307126387382745311055143874741412652558685470007145300836667478266765746720400414877053756562543853638554022055767416327752773186204257730441432226483061516523786268418417712485468645471672265731856455178786356443681803602068235327538110083351515556343615860803101225335447663035673464647078555401071381357720555132331165637465300650732644127750530363550200566217756741351568334658823132266106657664531167085175005811475037652261325817387606338288620565380266463665550880676743051820742216586384231472841757814014150130847064753035562530164461378674013218167481421451275114210804288236311323672003873724375163251155154108303660515386682522367768687520216231844201453516302058387034720361772125260457738774237645072531304857314868085873347454730385585338757726430656643873504153136638132646508716410685703137771500478115462036447706678642871630833317150172751226273671655845870784214880067160103258382278756008163457685251154205335015838270738631741007511261313311742713137207824551084847527852768414008530840523524707832357752407838621837744764534808245473201313077736628712454463573282036047606177628356273553851122846857773665077638871445056113471408877065460343677241566065401740402885336200350816455438826025210267242615477370212156817586755010774300244226438052721318725583862702644650137844613448618726312407205277538504854674606264472087585650666470602431007157683533714105566221537353610384157440670683218006615808544110058801184806484305030012037257405731613708843171027163255001108804531421323638770136218052673025686322362266664828487564412206143775215655602403825841434121722386033731087561201120571426628221551541811228681254526288715703202548412644DDC673FE876BF31B6D62AA38B221921675EBFCA9AA50D8C0717D3FF935281266A40B58D839659D70D618AF9961C2F09DFEF7FFFD9DC74FABDCBA2BECC333FEB52599A3F8B570E6DDA5FD6FE6502B04C560A1CD59AE5C67EFED02291FE2A2B190C226EFB19D5871371D5DE58883D163437507226F54E01AA46AD228F395AB023F66A866AE5DA63D9DF0B66314B5223802B27DF610449449A29851565467C348740D53D1ED8E4E0C36A4F422079704C39702CA65AB322A370379733AC070C30BADB277E629CAE8175504EC40F52C12D6C6B2B0CD641158CFF4526973827AD68D7729E26A56DFAFF82831D8EECC3DC1B296E2956C7F7848CD3C70FD67F4AC16405AAAB4D4C78A1FCF2646D7F763D6F295F0D35095C4A3A2E83A86CA83D9E24EA38EE2C8667804AA73D369C5FA0EB148ABD763D5E04E16D7179343FDE380715F87B2F5C1D96CA406D412E0371B9C5662BFAC94821D3FB1246FCB77A7FA9232C9F3972B0484DAF748CE475AC1FB2339686348B6BC674FB7ED3E4E6A6C92A480C839D153BE71AA61B23DC004E22D7D1C6E1BB696565DEA94CD434E458D3580E1847DA39BB228D13822695850C73464EE3E88C9209ACB603F2097504FFE662B0B20B8B27138DD27E0B338A37045A93DA327D7EC4F28BBEC8415CD0A5BE2D0A95C67DE588A539521C11FE14346FD714F4B51F07CB6E7CF466F8B1D979A2362E08F1F49F5621D6AC52917151E61ABADB7E2BFC10A6CC96664CC0335BDAE35DF198CC44ED61B282B69C7A1B3FB71DEE7B3E053B7193170A768601978DD4A8DB92805E3C8778AD770CB7D94098E4EB999C16F4FE59552A3073C194251179A81BF3BDFB6547DA36D70F46FAF467BB216DA5074E8FE7AB595D495A20FC5A0210D6D0D660DA3F716EA06BE4C56CFF576CCC2328EDAA460E37103A7B03ED2A867B1A454A9C667C1D01F132F2348ACD9B8A7C4B18FB1A2C64C2EB54E3EC265C864B922AC2B1AAB30E7125E5F6EC16F37D63C720BB320C40B12A39E4259C9FDA98C37ECEB212714055E0BE07F85E39FC4679B9F7DD1FF402E7E6F97CACB1D2548E8C469C0EB5C25A98693AA70813BBA53B351463FFFD5801AF39E58F8490665D4133EF03FE83ED3B6AAB0E2BECF0BA18A66B6401308FDF1720D03005A94B4C2E319BD76AC95ABABACF9B26EA783A231B444CECBC8C55CE98A038983BE9439158FEACC518CD113C27DE1F901E43BC060D7A32AF33224639DC2A2A0CCC60B31721F44961DD64B81E1EC48852D0CC0A784B23179EF02BFE135790AB578B473F95EBA1679E48679C0EF848DAEEFFDA4C1310F0BC23E4AB154DE62FA80727341622E0E77062F52D4586BDF4AF660D067727EBB7B050FECB835F2C6AB3D2C8D758AA6EC45AC79845C62F92759306FD1D9B97411A1907BE21EF244651A9B22F196E59F21567F9988C8021B85B7C981E60105F725AF1089719F039F6EB31FDE133E783F085CD5683C22EE3E70A5C0593C500CEF37888797874DF0A3DF2440F1F8898253D477CB53431DD42DDD25DB96CD6193AF62C6E3B69EB0C73BC449BD7CED979451937249C05502BD32CE73818794484190D3570D3C3495A46144884E1D0683266EEE8857ABA5853BBB5A0F222815EEF93B2F471D2054727238F19383D29827FF65A093E1EFB0B14141CE90391E8A6CB166F200B6C763DC6FE3E5A1BEEA03DE341277465F89D78FC1399BC92D4EA0D5D62CEBCF1876BF37A137B8229CF0183C835FE9DFA73B7239E6342D0078A247908EAF1252A1065A60CFCEB37492E9F524CC408607EA865B361DA0AD206E2C9D4D4CCDFF50F9F63D3706C9163B1055693EF2D9BDE961BA85994C304047EECA80646FD81F8FD46CC44863457DAA860EFDE929A491989C80E6ADFC794850EEF0A0C01D343974C407DD514CC66050BD439F9053F663C4B4CC486F3F11973C161E532E5D8E9AEE1CEFDE8E5CBE1A80D1D8C436544AEED490A664FD8F91B6FBA3077334637FEA2E549E64281F306178F9E1A8F56ECD758F95F94DC952E38D78F92837B99472A13F677E6B5AF3EF6A6CE2E9AA54C622941CF98F938D79B78355F3AC80CFCD0647C0C1E1DBB4B04F5688E1D5E0F4D30655C85515DFCB1C49EA1DD2D7FD441B7845E60369A9D73FF79DB6C183CE9AF44265B450F076E73D089D8AC083D237CDBA4A715D33F03E8EAD25B4120148B36C63F2296D9DB09D017C946A265CDCAD3263E72DEB0473ECED20E9E3FDE02CD2DEFC2A166978EE2B01E4EC75F1A32E96B24958F1DA8F0A3193F6E0200F4AFD59ED941909EF3D5D041B1D1AA1B1ED79280A82604AAC11F8EA04EB14EB8B0D4A06FAF2FC99D2A5CCBC5A759500CF648A1A67A60F10CC7CD0B6B5A4BCCBC7622D9ECD7FF83E1599343A22085BB4A11DA0446B22C668078D5211F5DE6EAD9272165A631BBA60FCABFEDE47AAEC562970DC24F7946C279BC0E9312DC6B74BFD311E24C18FBD011D59853967DB754B17FF0AF52F6F1B602EB0DF2C2880E47EC87DCA35AA46F7E6604D2BFCBF71166EF6160ED38C70AC14AEB97E39FB97692B118A6E18B692FF6AB91D196A4E718C60C2558CB5CB658AD4E5FFBD90278B3169512B5EB12FCBF21563249699C8F2DF7BEE98264901605C1820E1DAC4D6D626F4C5CC06A05CD6DFCB538B06C0634F5E147F555CC54BA7AF371F70978FA3501F069C481F43933A979822D2A79104C1DEAAA9363A520475E2CCF6321F0F123E3AFCFFEE327A0F59883C17FC1D3EB5FE330AF9E981A3B895A78FB31FABC1091575E189705B0B27B04E05EB9EA6D05A6AA7C6D32436AD27AD9F4096DFC6EBB2E85D4449E308835A4B49349EF96B0AC82CCC6730E1429AF80DD8D5E0B84BF3F841ED609E898F906E1B09753FA0E0A5AF43952C84B400D6EF09F7CFB78C430D6BAB17FFCECCA98DEBC078236FB65944AE95B34CA33D7AB27DBAABF52ECB3123A8278C2142FF7DC357FB491D7BDDCD3CA4284D949D1EFE905F02A01DD44620A9A0112CB78214057F6F0711755814EE3C596EFD7230824BDBAB540445010AD16DDF5FA0EFC4B5D90F2AC2F57CB1F88515A9977724C643737B472619278BC747BCE1877C041FA8BD3027B56D7F4C826B75681BB146E2D42C4E8F205EE779929D74C419B1A309B9B53A2F7100355894CBE365561FF62FE3F0F0E9079B37BFC52E1198DD26471B7A6450AF9FA64DC9A070612C1650C9805D3F7336BEEF26FBE686A9A5314E0EBBE82E5F80C6D596D145B9B3840063A7FBC04D3A2945B483CA721B90CA75DBC79191A1FCDEDDDB499A96A0737556A2B6EF536653632A92FAE2C6106F069FF829F2CCF8FCE667AE7D617C9F245AAA18B60A57103F6AEB0E225971AEBF3D9A5D63866502DB16CCE4326C5B544B604145EE44522988614A6F92AC10FDA5D064413EED3B14CD9D410BA73FD59599C59475201044982DC6617AF7A00010F99614272B18CACF644BE0126C1840ADD2ABC4D20CBF39212379BE93C6AF8B1978E69C41C514FF528B6E3BAEDE9E8817C479EAD" - }, - { - "tcId": 39, - "deferred": false, - "seed": "C2B63699D7C013E2D0C3A6A5D79CB60122B8C8574694975F4D703D75035DDD6D", - "pk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCD170667CD085153D0943CD38A3D1DBF3D912FF53FBE702635789C4DAE8F6BC6750483D1554E30AB38AC6C796B7E838B39CEE22570048BA090BDAD7A851C95BBE48A564FEF34D9F72C88BD7223ADD4FFB1577F0A24FD5DE75289710830695932FC0F619A7E0E41B26436E26F277C8C1A6320460444EE13363A353C003B8D4DEC547FB6B5D054382927984E791C9A718566AA78C04C744FC587AD18F55157D269554A5EBC1FE0A876FA2B1ED8BAA686625A99DE374B93B300EA39571116A9F7C82AA6B96CFD98F8891CCD2B7B8854C3EC1145D9A069F0BCF0D34F9DBCDE3DB51B2E87AAFED50E92F8D4DED20C5F7986BC99C0A0780ACA994D56D867A10890BE4A89548BE3E790FE52951AF0860FE66B8665802D9DA9AAF1F32B2E37CB3CA788A11F842C851AD20DBA6EBCD90CD27377FE75D3972A07FBB99CAB3ED4EF317B6A43DF763A70A5F6C23B5C5EE6E0F104EFB6C57B338FACAE6C0C437EFC90D5BA12C0146CA119284686D863B5B35470E620025AD064673C0CEE9839D9E047B78450C4882BBD36FA17E4DDE53AFCCA9527EE9F3B1A5A99C65128EC41F3ECE1B3782C20AB53F2860F472C31D04206AE73E8C9A43AE565DF540CDFAC9B7B267723D324678D11BC421F3D724CD2439762CA45E0E66E06DF3FD2D218CB2B35848806881266E3AF9685FB1487D81B39EA53A90F449693F7D4C942255B3621AF43B46E928E0CCC4052432D1066AFB4D03C6BC118740A2056044896A2C6460D0FEFD7E5C9E19B2426BC4423DE45F9F698BD5A803178AADE9AABF9D3E9A01377C299820C4F61A2341FA1BC5321FF5E80F9D1A99D7475C8B78B851DA80167AB21B815D4EE09FD51A2C7FE400914D2FCB2455AA43B96154B27D6164D0A48AE97F5AF447444A15F0228D31C2655241C98AAC48719EEED2DFE0A766C6E199699DB26CA099BF1943359D8AE608576D33937992A268CF6490755D79C1B6A14F494C2CAD7FA3908F9222C786E4776AB984BB7F77B0C892D806C867EFBDA69FF21BF473223067FF55913BC844C2CA71790428BC00EEE3D60F1ADD02ED9E27C631D3FFC6AB6A0D381DB59A82BD9C0FB751AA0AA3E12399C0B04195A852EA5294C27A31D9080B0565812F829A8E9F4D112E29ACC735152FBE32DB5A47A9B519B01D392BB1DA7C9A856E3CD9B1F9F462F8990C7668F289F7B03FA92F443BF11A4494E18582B0A778548D193810EFFCB0DDBCBE9DD02683B9A9BB231187D5955E04AF986A3448DE0A377887E987F7BAEB025EB273739EB77E88DB7B7855444C6CCF9F6343F30AD4D53D7B2A4923265292DB0D1D0BF85AB199D7A6FE544541B66544CBEBA4518BA5F47A7264FF66CFA2BA8874135B4EB23E094A61A1D3AFC3CE418CA9CF97A4B08C512C6C1B6B50FD6B393C278405AA5091B54F12B576FE0499369E90BA685EA7D5AF915485F5A93A721A342D999C985FC32C6E2D1E43D4CE319A8C907874B807182B5E0F0794338E851B21543ECDE72080FA348FF7CB9855819F905880C9DE0081B149B9D74169D0881C37E89E4874E6D8D665BAC4DEC61D3200F4C7B88CAD336449E0B2FF4E46961685645347280BE9EC144ECFB60441A3249CE8C9444ED17BDA3803F075660AD88296DB499C54C17934DFB76E1B1557D03BB14106960A0F2357832B314478F694EAE1829D53CF696A7200AA667D488C85D4CD25A4669ABB2F69B3CAA7382F99A1A73E75C48994D00CE8A9E844E4A9D74301F8138A765B48980BA5605221C3646867A19A02D3060AED73858BBB4DB5B21FD9C03BC670A61774CD447F55DA763001D56B5121FA9AF4AB04E7CABA5A34FA17A40A696E11C40FCD4C9091A61006D7A0790F0384ABCB8EC3A00C882BFA11058CFF423E43E0645D20F5603D116BB3DDEAC4FC27165D7D5387EA0EAA963BA3FCD28BBDA753053607C9D76BB2977E7E15695A4E922F348522C3DF49D789281BD70A39DB9718AA259997A3A5C9C7BDD7FBDE7078792CE4909CA2EFB7ED0FCBAAE72C48AE021C0952E5EF7E569A2E12DF64974A2C0AF1DCCD4DD9CC1576E1F630CD8F8E60BD5566DE711BC40EEA8358C025984DAFCDE3838FD0348AC1D5D7F4513F20AC862EF322AC22C2E1D6D238631C5048522C1C5464BA55F9FF4C1DC8132CA7C3245D540374ED191CA00CC43BAE8FC824E18D83E481374E43FB19C9EB861F9CCAFB005C009525D5024C47100580D5EC7919DDB28972B0988B4B0B408A75537B424318C0E706BA8A4EDB0A13730D6232FB1A5555AE54760CDDE6E1344476774507E414690DA8443FCCEA1C1EBD5C47A96FE2C1FCB69E7D377E359C43F2571256E7ADB761483F3D814D96C1AE16B242E91BF78AF86F8EC9485B5A1762ACE803C64305C57D0897F4A059778A1E9D6CF18352BACFC47C57ACBB1AE6E04E27E83C0FE3875F5E245F04E983DB085A3710FCA645533B87F8E3ECF3A1A01B8FB88FDA78F4F20CBAC99F71CE4C50A829112DD9A5C27F4191145A514FA8894467704CF58CE847D5212E5A0ABC0C2A54C8CA4416C3B99FD5DDE80FE85276F166E017BA7B73DBC33CA68D681694C93A495FE42A5C463C7F0F920AEA1209A5CBFBE2D1CA7F5C2A00DD79E5C4F511031B5F4503565D5F3A7FA9BE4FE244CAB01E9A3F0D432A58A8FF902C7EC52D6D5956D57DE83642E4CB86299406C408A69EDEFB75C73526CB5DA5DC9C726CAF4A67841E2EE89EE84B2", - "sk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCDD6098D72264E7D6D4D2526269ECD818BFAD40D6E450F1CAED968E46DD015BF860C64F11F1C8B68B0A93E3A587B4A7B668405275BA0E02F7A9B9ED5C2A3A07D58638B2F079D879E4A963A71E48AA6A1AD48A53FB6975BE80A87EDA3DC2C45E3E2535347252511162373444883864234312171761112443113274541262551337205657337562142564641810327758354632066283246026032660562804546204201032100470857008704485318757233871080537100440075887712430860310035716105637805207148726226407183117674134077685281072455240143304525435254517217271628230002881303005708644321451536774560055002568231011653601844825336871747306308225147337254564776486761652475071243277768387525351423682277653676710247471164822022210263745461742764530838303826607831325346722787012407686084857676626567311027633317684127048724810304183188573153261558525367337033801513347178210115184560288328727438522687047476323872420601657314862574234236007814048147752447545347484058034681872780107524724278612143027328675538021258766156243708623415106424264857207356713470438274025516222771841842254336038556352053512561056210538731218660581146781731417410102603685057454531087820334516527768741004147848406586028810822338421580355365452504827026415403608881208676827215416335512862313241750784333244556575172312606561322356524231667412531172858170544156587437378562074674811724802217158383553162701447171412448374380216533350052350232168585430430038546666427434215210776566432862887475236726102445460355684288760664335323010118554183206073738163224141810160528738375535763352866840268340018558752747872223772826467564754525856800736608302314355680585125466035281342871425278510600680607610868737872577318456358351064687712720078162564728847764466144165122526208337786674382106466856735504105256432573426072255878810568204077874201326268870137766250031860247320056725710627478252872153077206662734770617680505174037136271378240535272306826168630171048300027443113217376461110152053250267224762485262338638447582146463383730585507550657233653638216033427160072055538301436882311630532018878501457673434108006610310811853163472486135380248156020871742778818010634356287622737627032567085008145130063600135307373066250323073525614304006334526265375820448468046114113141828615350121800562146785177371376766480605223276434131846634530460107814758043353551835534481112537700631102252224444448644311222281052385284857636008820160843864850064545034076558382755214271046680842130583103778217641677217787005862414285106751001024270630427040075517615787225164836210742813206221343126760806276705656662837772503318234073411728338565231372213525857540671013027723486135138826824336244204230151581264235632588644223333771521856662577177028188663150465003874131033684300235477368611231125344672380206712007222430300558053788063326274337621554730280578778138875722058258442357632740701132645843862338815650446440677274306103004233323287706324404276838811203068132048447336288350384168670840521354057564146760626677354826831558367781860451050315725567188201475818213440704580241507306186380161351432371542176271552136705726572162781943A096ADF0AF810187F7FFBE7E1889300AA1174F9E6D0A86989C07D14BEBA934B88A1C1BF040A0F417BFC476AB1F88F58608609DE882E23EAA30B70720422BB19F8FA49F47AAB5FFAEBC8943FF6D379F0FE8B6F8D3501621A2C550BCCAB4DFDA85773097690AA34B1D5629CC72BAF11DAFC173B3EF79BF07E7F227876BEE79911241664D127C56B89E0CF0F0CE2682616BA0E0712FB4BD025C744812CB0EFCCA37BD57B0CA6E732B2E507921F6B763F398E0418AED1257A75DA7BBA0BC52D3179CC3D35079702DC9E4A96A384D7D6C0056F0EB8B0C5974EDD43EA0ACFBE53C5F7198C4F7DDB2B5D07544BAAED6E8DC14FD14CD723B4E90EE80649EDDB402375DF04111BDACC8BA98775E2806773B311BC4D104801590C17AA20046CDD6F28A44536E6174EED2D0AD4041B5617AA9395712031F1227646AFEABE17C43EEC78154EF0D5E890EC372CF314079E80C6C680529422C82E4E74C8BB35BE3AD04C4FF6045067E3C2E4FC1055E68C8BA0FC55F21DE15F50E46EE5A455865B48A41B44205A01ED6509994BD7FC9A0237323EE302ACEA0152355BD7EBA6350FE80314C9B6D30FEB4B5AF6AC0DF133733C5345A5B2EB5DB77A401F4135EC523F95F13D109B42C4FC3B8C824BD0D11BE7A6B5A74B70E24605914E4AE44FBFF0F14AC56E75A8347DFCED9B1CC22E2F6CFC1A72F444653AF7ABD1170774DE8BCA0F7D8B80390CB8ACA45EF671CC467A674B3C1B212F41F029E492FAEED1749AF0E57F3F513DA2A43DDD5A39DE2396C3EE779507A3E7C99BB1B101260B60354553C8142225AC393F633E1880EF686D3DE4AB903BABCAAA27109949BE89045D4FE4341EF15B833FB0C1DF7B49BDC3C949687305952B4BA446059D168C4218DA3748D88713A49A14467D38C668987B461EAD58934B0FB8ED1B92019E10E511A1A2B302A880570DF72B3903780B281C17DFBA7B9D1448A81219A5212E228B58B9EE6B73A28ABA81006AB7C31BCC56D3E7C9C5E8F1E1FE1D62FB61E1B26121456A909B9516D01230F4B841189FBE50DF83937057F038E4CBE75D347EF024CDBE00BD73F9680A36B7BB26640C49570F6DB11AA917145D14C56091D0585FD6D42DB68B8BB5EBCA9B555364737C8AD68DD72BE29608324E651766B1A6936F8C8B42D902ED712E3EDC6F6B5E5A07D4C2B65033958C4102A0B5A6251C27E2CB6DB3A0F246E0D7AE6EF8BC1027E91B705A674F9690A73CC2D5396726C977E15DAE96859A01F1CF0133138F043403CBBFDF079FEE2C0E345C598258BB03BC9D77DB0C5743D56F702D9031FB3254BEF6A141FC529F09F1FFCE797A5D343FAAB8854DB3B88EA42DFD2AF8F463CBD6F7733A221C528634FF3BCEAC7DADA963FE6BFC671527AE0D117ACF1127580B55E5C4B9FD980528242341283D20BFC220FB3F89B5710AACC60F9353FD31FFCDCFCA6F5B1CC594E9F8FD0F3E9349CEAE2B25955A7B5EFF5606D0E54ABA830B29BB257AD63C94962F167F32C174B3FF9BCD0DB1B97ED070A3C81519F65DA57E526DED042488C0DDC4B4746754564A0022592DA6F25023F086BEA4A9ABF5023BBD53F193C949A455F1EA061A8DA38D93FCF0A41781E46E91CEEB1287A7A9CFBCEB62C38792FBB967268365E9D6469FC18FE2D2E0CA4C5DA62A0FE4B8E58A7AD31F2617E5377EA66768AC3AF8AA6973F36747320CEDDD50B687B314E4345105248F2B9B1B9451C909B7197556225A56030833FEA15F1B9A088450D8DDFDBBF073481F50795F5CB9CA2B8E1BA02A02657718D823EB37499824CB0830FC6368AD6793EA27D171E7F1351AA04D86652E738140B707B17C7548F9800EF75B2640DA5DDDB88D34E9AB788239F37E6E4D5F7BDEDA86A1A35514C022C24107248D15C2B07E1CFCC7C2F239BE83C585F7485DF3D893E99A7D6A8A6C4E58F5F8D049571BD45506C6B64B02BCD3F778A652DBD5745CDF4415C524E29BE7E00AD3AF934366C3E90B7C7E987F6DF87498525206027AB905ED56CAC425C3F89F676B1CDD1E1E44ECA7E0E2868B58A81ED88AF0673DE18E22C2C58B4540D03A51D5740A5AC058DB3BD115A45AD77EB66AAD1AFD01BDF61E7A81946F0B52AE30ACF0FF545A4574F6B8383C041BCDF1B358C2E40AF9A98B31996D5EB214F047355C59DDF6CDC74E1ECC931BA3814E2854AEC822EF6B9F7B22FBA347E340A629CF0E49AD22513BB390F88BEB7993F240D8A0B6DAB823ED3F13A05B392B22712B20332E876D14C51FD09F2158833F9A7DC653605CF7E77AF15BAC2D1FE6455DDC105AB28FEC90B142297984F0398D5D5C6678977850A87CA0977B94D0E8DD2FE094EC00CA615A13E7CA73EE2632EF460BC06F3480E214263F8C3D22AC12153BF2D5670C87DF4548521F1FF527CBF044C01156B3FED897059D5EC24659F50210BA483D0828CE8E4BBF64E06739B04AE712E89439EE16EF5056082C45DCDCFDF008A4CB806749036A05209101FACD435E456A0339862485335B7C0AD0EE13312E18EC8E9FEEEA48B8C2F1BC07FF9911255C0B1A9836DF57B14A8AE166B3624CBC71C4B9F5BA0652C4029CE365AA6EA990B032957B26D02932C2325A3A956051D5BCEF413B0DE3FB94E89797855270D27A2381BA1039942F59A2675E4E645B672FEC30AB3B73F2495C27A47EE3EBC400ABB1CB54FF15F934FE8B791FE3F3A228424222B88D8E676F8158A5F39034417249EF1CF70CB94B7FCCAC8303DC229E6187B2E1B0B04701D9DFBD4ADA26F766EF6A89AD54906A608A973D5F72C189A2BAB4993862FDD7B54E24E8E249E6F0336207B754396D1E508943DA1329BA186A366376F653A0CA2D4092228E1D82B094F7D96CABB71673533F51CECA70263744D54E945FA027F2577343DCDE29ED6B1820AC47BB5BE66A9018A5BA9277598267390B5B63423C6C8D6211F037E841AFFB719B35275826B98DC9A06EB64195376161AAF7E34E1767367F42E25457CF6843A6D5263F62124A7C76B8898A90578FA477883776E799B822D5F595F2F7169B76FA211C48B7A8169AD4C7EBCA7D967A7B48E77DB51D3FAA346753970D50E5DF88A65AD8E319666A553A68F4CB529BE3585400211BBC4496DBE5B0BC75A7C5079FBB3DBB6946D911361D69679AF4BCFC8296928A4D5FE3FE21BF0D0EE246259331BC7C1558FBCFD53741B4680D80AA34F67E1011BCD4B27A7B9C6FA6A90FBD916EECAAA000AB00FFF4A933273EEBBC587AEF3C7B2E172EF16087F6ADEF740FD12C30FF23D2E78D9FD36C74739C86AB3F1258C8C04D66DC611092EB653A7661B28B2785AA6A9A9EEED2E33D857926DE535FF13A6A8750E6013AFEC7A25CB85D35CFE4C39B79E767CB6A0406ED3DB06B5942B9BF364E1A1BB13E69DEB759A0D0FB49830886D5DFAF405741C073FE3D6DD3AFD4D4F8282B6C04C89ABD1BAB8A2E67E1BA0005861A5D06AB2BFC4B674A0985C4145075FA34A69036EB7C23333E986963590BDDC8A849606A173AB3002DFEB4268D26391D55ACB0FD16191AD78" - }, - { - "tcId": 40, - "deferred": false, - "seed": "821ACBFE29F941CD0F02D6BDC0112688B212D5C925AC08FAACC248E7510CF88F", - "pk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B17B5A84B76C1B3E7ED0C4C857A0C27F3DDABA85382A3B84768185346EDB47C3DEF01B18C78A91BF46B2D8BE7DDBEA67AA746CA879FD71BAF265AE6F3A9C977C055C678365FC92BF8AA042D197A5F9BED4FCB58AEA2B65FECDBDD93E2AB456510A65332E08233C0672E9213B7124820567264C5D12A5A996A595440AB364F4AED75B98A77838C8E4E98CB0F53BB9D44115BB69F02957725BC11050CFDF0930F82E45EAC8F709FC805683CD81DAB07A6B6FD3E44EA3251BB67D0EDBC895CC9A3794D240815B8618EE49EAA29D7FBC6013DADBFF2A48837B4084BD6E8A7D522058F5BDC77F378B3F76D483FB4C9D99856843C639B3ED99AE06537630E7ADFCEE1A7D3D9E44E4464F79F9ACFE32C384744DEED50057FE32028C9B2A7B84086EBE6545E619521DFCB6FC02B90F00ED8769497531AA39477C3AF9DC8E2BF9C51FD329ADEDC1725F760FF5E28B5400D917AC413EDA735B58B26FA7E0C6E07749B1A5D087325EDC2F08ED9F9ED5A98E388AF03B44860930904A907A66E00D09CBF98C0921248036F48323EC5A42166BCAF893195DBEAABE232AF704BC64BFB10E43FAB2874602D8641CC997FE3C074924B6CAC536D6536C87AC0F8F658FC3F99DC98CBD835520BB3441B55CCF3CE7F263451CA1B3CBCF45D12C3B889728EB7E401C1C2458528DAF2C40E90101A3B423A4E1B8609E74C60C9B7595CEB8F35FE51AF78122D9C487BD89A03DF414746D0F2009E852A3360AA422D035715E5713F7CE28D7D8DB37C40BD86EF6CD55C0589B6E52CF9C7643ABE4096EE53CD1C1EF65E1F9C7286452191ADDA05F133BFB18378B5D898201F7EF9FD77CF76A4A81B8A732B316CA1C2682BF25C4FF2F500F55FBD60EC6DCB48282984FCA4054E8A3DBF5E0834B312B2C867ECD962F27846FBD1B5FAAD67FB4B17C20BFB0211D96039515F9B0BA6691E8493F122236F9F52325AD5B1E30C3301C0D3F60DA86B77BD81B4823CB636ACB3DD28052A278737D2E5B07B5E9363B2395B51F1210AA53F627F58109B695516E2A8CF756E5FF531DCC0C51F3FC5BB95B28B2EF1676F15C6827A4CB2520C719A90BA2AB409B31E74B99771CEBF87AFF0BFE549BBED6B678ED0B331C154D42FD7F6A7F07B99AB0460FAF7803FCFE336CAD1D3FD5760025DE4C2727D386306EED3B3D5D17D9851A5744EC70B3A0F29A76A180C46D2D49F50E9D8D1046F2BBECA53543A0C3646FD736E39175A2D66E142B0A94927F2A937846A1C44CF00F55CC9B9D62D4F25AF4F87A25B8BC932259823F3CD59F3F09ADAFD033F1802293EE5CDD49E70D8DDE9FDA65C0EA4063D4F5F0810671635885B49C16601F531C7FABDDE3A63611DED6ECF67D621F2CFD48488DA31D0FD102001D44AB947AD5296635C45D853624BAF09A5BA447CFB8C874ED98EAC7B867BA6CC10A4675E6C2F5F54EEDCD52D500DA4E15C338B1E12CAC96B0E52D483A17F9D1F90C4DD385CF00DC0AC12DB97EA1FF33C3DF6DE8BCC81E70C6C153C2BCBFC6001A815D17ECC8C61C24DE9933BECC9C9F18A790564174BAE2599F93E5BB1216FC2674FB34CF153FFA690962BEE4E9080EDD9B49E3EADE139075AAF1A187531F51D05F7BAD888C1E717BC4B368FCB12ABAFEE6B29FE72132ED8173C4FE6F711405381D3E2049A627F4DE50353CE804CE5EEA3F3C94008156E7042BB252CFB13F512B1A5F28A10CC70686B22E9759C4C8A62E021F8366A4173A0D3BCDF8B550EEB9EE396BBE86D0A851B77B2B404658AB1A8B3D69DBAAF61CC7D539FA05193A6F70C2956B0D2B3757157F54AEF2D70DBD8B0D48D70FAD4D88B11465375B7CB6178F3DA79268079DF5110F668168C6E9BD362525EDB99B80F87FFBAD11E8D88935162251F7B4DF2578DE0532551FCC2AA0A23993C6BC289AC0215CF664FEE314BB4C21354F8B69BC920FBF0B8BB2DC499D3E4BF583B9F2EB574A5AB25205FDA5FE123B09A777B10E945F508A22BEF885746B6F4CA38CE73D2B4E843A3CAC214146C71925EFD237E09707B138A252D6396D8E9188BB08ACC33720C7DD7A87613E55C903C436BAB24C9D5B74B7948EEC3C44B337201643E4CAF2FEFF9B6AA4A553D1A6678592C630D11D357348E14A8DA3B6C274464F96AE6554AC76BD4340361E7A599207CB88B7517679CFBA163AEDA592CA982AA4E3E37DB705ED5E26592CF91DC803C4BF9A8B6058CCD426BA80B4BE2FFE8D0B2B5A9BBD1CF149F4EF6BCDAB30F7A4A9FD2F6D0C2C9887EC40B41A33E4AA0FA37FB61E9A1736A78E75B0E5B668F648420FB37885BBDCBBCF7898B77159083BA58918F7F190A7AD04F6F941FD99A09338920E9522D9F41F9C8807FF02C0350D0A91CEB260CC8F4690B2E9D5A6FD3A4032AA09AB96A7B4C02B3AFB62407546B0C584E142C93BF127405A17548FFAA23832887ADEE53B90117163D8D5CCAA96FAB1FAD4DB883688D376B3D582363D9816CC85E16A5BE1167F25883184FC078EAB9A0C09A5172C0F557BC314686F961FAAA93BE14B8C239AD5925B2B9CE7C2D507141C4705671E7105190B54AC4008D8D845435A9F68164E7DEAD5893406DD21898E4F6AB7CC23EDA1D768E427F2349F329FE8A838A03DD7DED95657D82D05F6753B6E3800C2CE345B1D33AC488534171FDD124360ED5EB4B62061D61B89D95EE2D3D9D5F8792FE679ABD0ADDC5B1100A5D56FF8C8393F6698CA302", - "sk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B37F4413E6607D0819662237E4F7746006787833B1F0BE10734308C1E564C8FED69592AABE7289459A5882BECBEA41861C798A02A0F36DA0AA1D00BEDE17B87FDE6DE5DB5083B879955B99177B83F46383E2E5048700863247F8B00DDA1432F9475845411106010802403124423006207171123637626358064004744217668563237888426103620752544733884730188200687105834153425720865281708118271854426277451381137237063130331623234106723431860347548763207658577260187146861448155686826455003173682641840333567008330412485633328752625476441625800267213531873672382311441364125312140451047067036187188453426367824516587741606322451571174808077083645343475863427745255815618608637822668140778022078564357408860015574881153222705772820283282645138703666837082845457545642483327554486635104572840030702644546883155868854848727734687116530122331273316185560038723621705252685722207460533380311867184216400552714105740853578622762727822013200126021044283211375323117003650187002088603640345838844504335503120832113026778216041020078002871175114780338718740318457762655342324868368435104511507781314186715333714808404824660120450275541327480357767864878521734380425386623801541346774823118010158808603360723632020412452027121234068688716164441521887108240101786315371520841447607250516005315365686168717574678054651203116875838316668026521024171872707164174688353341467360173172577764432418112331306083318608605402151567381436862124117738672361158226325887710338805385437741854660070530741053300731051058032536663754782277723523405535684511367423724838044746436665367216702401504057760861543160842185113378015224425623321268204241475232123052525186526436170475223506404246556168704551444551388733525384672264531670007310781725425740047878568634613747664237017616081148818153324800302322626514831370370752655505652444514474570366145827603375858080460822137114012511117868251538483208262330710570084046510350650067607452046145226203135104263664202836618344162630317470784727848257402470148421118752145271066152161743850236604061501516023741745433718841304847033226752765102660665216844000747725857377655737286628628855470800115846468544603448604421136682275115820474718124475360816350707076840045427737648741006206344653466760485601222162728263052643450841137207405423267533600508015253620825076388520610231453565801282615681627051432685018612236467086817638250582501884472046848272635753014406331123268541531386173156646817565463500686735817646042771537270561435557563865543005755720030384235037845153625183357188765067524510541785723483746082513261716357675385520117254805854813722260257761547732624410547504153484802545113081035450188274886618452447827427357657813402550236060754048666817727427460350022175101303701227746503115654701150825304136500402467436180731888868347168086754418454456816581305381780810850606827744730528684184014655603763554220413703356318438650383817117084323856267162872086718276068621466341542271674584731366742432452022720723523885440383735736758540137861645710336031513401537787442784487630878114247615133473366832843613332177588724308575184307203156767071BD4D1A723FECDFDE655FF7613698836154D8F6C5B46E3CC037A90876BAFEC493D244CB2B771BCE1BC5AAF7D9F8A75D94A2E9C6746DAA9058ED347D992A707C5D654D696521403D04BFC933DDD819C17A97BB4685A827F2FA843ACB0DE979BD88FF69CE5E62BC74BB3B0917EEF8C603269990CDC67E4AC99A6645412A1C2326FC2D13CB588740F71E9012AC9A07EF086670BD981722F8A7103CB68C33933F6132E78803316C85F6AB3AA8BBEF2A33A19000031CBD73C643E226C156E5CEA88BD3743B3B0FE16452FD7BC84380CAA4DEFD3AC5D38DB01F74B9AEC1E3C368A77B9FC8DF87A1C909A7E10B9369DF94460B8567C38B75267EBE99CB7E07EE626772BF70E721B00050D350BAA16B0AE07FAAAE61716FAE72B10922673534E83950769A5AAAFD95D3DBE428E66C7148508D2CA2914AB6DC20F0BF7AE92FF51577093AA98FD383A5E62791AF20206690BB1231736CD5449ACE93061E2A71FCFB4CE9752188A4A86302C6799B882E44545FE4667023FDEF2C13939B373E2A85030D23DE62FC85F3AB765699E898D3F06794193695BB0495684A4AFAA4C9D63843CED531BC122EBBC3D9983319968FE57D037699C3722545D5AA32FC648CCE93EC746C020607513559820FD9F4178FEAE2620BA278613A0832A3068BB65A445ED00D0623DC6B668983A5FCED6D8BDA41164E8ACCA99DE3CCFF3C4A6D5CBD019F53F6B70C97FDCED46ECB1D6D969B16191DA7FB093A0200AB28055A045AA9B544A543C96AF75EF9950E36B9D661999929DCBC2D697CFC6A3540B56EA3E4F4187B8D892447B63D80B75035D8E594BC8D7D8FB55694DADE5463804985B3718FCB59A946BB3B66D6BB38257D0430E18605399C6F460CD33FD9E4353CE5F7DABAB57EAF388310B828BB008F1F8850626680D2BDF2D1D7FE348B18CCDCB1430A689954CFD60A683438000C1295711F7196F9CD524243813388702248346794DE6AA4CEAE1CAE5E1AE474F4CCA0CE754B8021464522E4A845C1FAD51F775EF7375DB6A21004DDFC8FBCE0DB93DC275494E937424C4C3EE97063650930794917F57BFDA70D2CA74B1BA7235BA947C587B1C9D86AC4CB9C8DDBEF333DC988894FCB2615B3562FE939A5D171257726B6C789ADBA53DDE401D5168418FA6C1CBB65DA20308DF78EF6A719C059EF43A5E01CF6B2EE5259EAC541CBA7B6321E5B592ACC42F6E5278785AACA977E2658145258EAFE96A544A648E709B48EE39646F1B1F1040CAC64ABA7B6A69DE4866832FA041C36252843F20FB4679744D6DBC09C8260A3CEC898ED2D8C33CC790D2D7798824F0A05A1299C4D7F2A4EBE7496956A5C7A033340DE8A044619D48013BE1E4B43213B3689C2267D4541853314E807EA6A1C69485CF57B80A106246F10242E3C96093C960EC0F9C0159A45B9007B7A8141A1834B8B328F44BA0A1FCFF7208B476988686BE639362CB120465D1AA9A6054F596270E5A3088329A91A070A6A9B8D86489DA8AB6FD21F21B163D0DBE579C2DD5F102DFE9FDCBD9EEA6EB32A236360EC67CC685495DF8ECD4E0DA5AD27E9F313E3123828A3A7F54D793B1227214759A72AEB0D64FD2E9A134BAF89ADE482ED7CC5DB0C9593C63219CF38CAADEE0C0D297C9201F7F25680F0EDEAF516A4914B2A4606234528FDB99E5F5C0CD2A881CC1B670EBD170360877E7FA4D884A67EC0E3D6A4D3CDD304C4633A1E6DE168AF86FE586895EA49E390C0A9A92662EAD24E05EFC92C048372EFBD3AF11B87809C0D7EFA38C24C7E082DB4B542468EFCA41F88CC7C999FFE3C6568586C39F3750745F0D3F551620C227109DF9155437A87A04E08A4FEAA648E9288299E47C351E34AA509EB4F772C78E33ED4E36858E4055E7E3AF5A958E96E69E93BD86DFE5DA8D1A3AAF0769DD87558024F2B26C6C6C42224760D12B52832326B7A1F70CCD530B9951CB3B7A499C35043789E79EC68CD8EE1FD56CA5F22A5D54FAB7F0689F1B9584FAB8AAB9842A3A30C8780132F14AAB121CB09F0B4941A882FA8BF4935BCC7F2F698D93FE10F2393FA96B9F957296B24669DDE4B600927BF5A469C0001F0B1D8F1DF0E6B208EAF552D52F15FD1A80B1B4831E65057641FF84E9CB6811980DD38C4B26B11265B4E71CC306DED99E3D48209545DDEA12328A1A99972AE9C849718A2E1D4E356BA7E93409F9BA01BFEB6AE78DA17DF50924E428926A844580DBADB3439D98C6B89818907EBD7B7EB11DCE48478CABE0A49DBE5918BC45DB4B88FC045D1985B918789F9ECC59DB72F2256382841AD1317805DC32E60CE2096562BEEF9482EDB130FED0B00335AF2A8EC79380349E1564C3A382418550623E7A87A7CAAC056EA6B44FBFEE65C93890FA3AECCDCDDD24469D418FEABC03543BEE545F9FD977D77FD44352553D32A365AAB23E0916F18775E3DC4D41163794884596AAE4251F7527725C98483C72786D46EB2A11992B40DD0C69AC7092067B3EB63A179A5C61446FBDCA3B21BB919032B97962B7E218C2DC34409EBBD5BB360F2B212669CD16F45F5AF4EFA777627DA59B6E2AA0EEBCF2DF02D1954B16BC0B5A718BB95C1A905400C5E0EC0F326C8ACAB20DDB69525FEBCDD32067CC74DAEF2E79511F10CABEBB69F11AB14612B38190F8C02C4526ED189793D059CE759D56B00505774AAEA728C79CD8D2588919500EFDCB2CF7F870C999EE2B5CA16CAD7CD92C50DA46274A1946A0D8B3EF4FB6D498339F2C7793267C92B0AA4A73CF40C362416B487A83A9CAF3F7C6772AD70DDCC5A9D1FFF56B5E37B821FC398DCB15E60E1FC0D8E6DD569E315C5B12187FF345D749D66967F3E7EC97117330894138DA444597DF7B5F7A014431C253C8D19F9E8E6D143F406B6E9518F18EB3E3A3B72CEF48F2AA245CFBC1F1219B4508BCA6EFE40F80357A1CF1C9D061955A746318A75969EA691C83B5219A9354E0FD92ED1302314944BF62EB3E75EC9640E2CD6E0A7C955EFCF41DC0F90D25C855FC9F54ECDC4CDB40AA95E7E53F8DD2DD6CC33F2703E8DC4C09C6781DF792E6DD945FE0EA4FA760FE35380236138F6B49C99DD5D6FDED1151D5C461DAF39717916CDE27834BAB0A5E3D5C0C5FDCDAFFC3E372F5335DF494288D5176786CA73DBB2B58FD519B10531A2C9D6D390F7D4EF4D9C4F8D0C6F36B68E3B502E2D0F4C97D027CF8629E2239B3ECCA9547EA8D9E8A357602319CE01B0B76D2F5CC5B4A3A906762554A37F0B8FE5B4DF29D434D98822C9D3CA495A103D1096DD042D6BAD442BE6D7A5882AC7B79C9B588F10CEA4EDA495ADDF22A8A52F49D21ECFE6FEDC77A459368C18819BCB9380A0C115A5280CFEA7136EA7359A78392C27049A55FFF75FD69F70D08E2FDAE617DDF1E43749D9BD0DCE026FC0B8722DB70AD47FB3ADF73C1BDAC24A27A596739F7AB09B92A6005226FF18ABD52AA5131BC9F86C786D87576BD3D8291A471D4F40EF51B214069D7B0096744BD9856C499641140EFEA44192F40ED4CBDF2C562E30881532543471258282" - }, - { - "tcId": 41, - "deferred": false, - "seed": "19B20AEC7AED1C129B55D7A5143192A3CF43BB55069017D695581B74006788C5", - "pk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B741612FD62C3049C2B665EE8EF14D040867275020733F0E2673A1AFF38F32C07C4F0792A7BA4777256077FDC933F991ADAE12D5C0C79299769DC28F2445FF043D563DCBCDB9E8F3B238C441CC329E13925A779F9A3B65552EA2793F99A95577745BD8CF86DAD4373B22A7FDCDC1BA31543C649C4B6B7C8E60795AAA4C4A9627D97B5C8A04BE0EECAB50E02F59139751DEE11A401FD23F3A0B47837EA00CC146D668992DD97AFEF17751A01449B0850E3AB1838A512015737199483769E060CFF8B66793CCE1FB3E4EA781C6D09D12231775AD1D98CAA9B1EAFB9390D67D76EA3026113396B8DD311516577ADB15A77CF47C2082B7982B07687C2C88A6BDA5F9E5FD7F2AF932D947DA6FD42A219E297E65486B5187330E4C465DDA55DDBCD1823D7349D9305691C3EDCA07DD547E46AF919C780BB03C670359EBE80CD4FC98DDAF6449677FA7C045CBED1C04BE230690177AC880286407E301219D305DBB3FBEB56B0AE253AF69ECEB2FB19FB66302C828D375328CE26B8EF9FB97BC95B35D9F0294E157A98F50AF78A451AC533529E98196987D2D0E63C6F9857750AB8CE1503814C87FDAA84B0D345C477BD8E87A09DBB0C176573B5369A083C852EF8B49D4F30E6082E619CD0E10A141B161832E94B14D6B0150CF32A8054DFEC80C2500F230D4FCF86236D72C02EDBA3CDFD83B28EB7A282D4CCDFA1E1E5438F54D15704E76C92352FF2F28BB112372E5B532AEE918DCEF2585E3163520A08182CDFE1A3D35F8F4039105AD2BD4400C6F8EBFBCA9FE312F7D95019912E2945890AB754881AD378AD92D00498EEB82113897D555DFB6EA7A49B8D7115DAE705C2C7BE0D5BD7C79A19636884686B9173AC7EC14310D08361BE6ACFC6FDA240A73722B6704CC3D2BC0F0C0C040E44D11E185A21FF149F8AF17D2E056A3C3B5A06FFFB6E8BD3650E538AF954024C4E0B55B23941FF945513A64453A0BA9A4D3DF118C31263A06A3DFA7E258862FB8BD066179117F878662746872C7AB66F2264E4765EBB0DD19CB31F55163D8BD964D3B359A0A79D4695D4E0A1D6106CFF71ACA80FA61841BE0783D3CBDF843C65EF755A7891C0C40C98E6DAD9F565E51FFCDD4E982173903ABFE03BA08BF60E5F14D3C88E00A2D882253D88CE6860EEA90A9E4C2AA2EDC6AB0424493C1A79B5B6A3F73089F4A64D0B2E55B7BA0415A53960B870BBA5799323DD2D00199E2FCBA9547A9C2B823F753408FF143BDDB72B3C1E6696EB3C6C3CA2984453B1916FF4DFD6B3B43477C42CBF433C752D0749FA7D13E53363E6A22D085EBB93AAF260D610EA9694AC2DF8BD0E7DD543FEF57685E381630EE414FFD89269CE6F0D9D1B1E32EB744120325F092596DDF8CCCD53FCA530440EE9000EDC1D9708D0359A2B8C20008639F164A7DEEF0E1F83FAE0C6D06AB8A4E82CA74ED9AB0144A93F681BBB54356567E24D8F8A8C013D1E879F666EC62B94F2617C85CD57323A72FF71AB92E322C339AAE371AE06BB79AAA775C3E52B9480619D6D32335C8BB45EBFD11F8A5C5CA339B69E0F3FCED6A857EF3435732919568F1212DD9D02CE7F3FC1B22ADEEB3BE460D19235DD54C85AD0DB8165F30AA209F34D043A9D9DD186003EB29BA7DFF1ECAFEDD36767A7A389C685C4D3ADA09626C652C7985F237D69C31DB93A8CC116BBAE071DFAF8466908A9975C29D8CDDC236BA5EB447EF045AD83CCFC8FF9663D027A8138C6133A20D9AF2F89B2C183811B8A6868D5701C9466C54C78DEBF571A18DB524A7AE18C935B624446A8B94F25060D695949D7AC47DE11475C427B3BC987CFF890932E8BD341E51D0DD8B178D5C4F40C35B9B2E2F2AE493029C6C63867EFE1D7CB4B02C53C5646A9EEAE87E6FDE7C073BCC7F0A79B4F7E25383185292D735F0DE85B4F3FE9FBFDD21268CCB903640CC081E19BEE7184D3C2338C83E2259E59D8606357F325D5867265A2DE3FC8BD88AD8EB2D4AEA4E89CD08283DBF1E7C5A7E97E3AB43D9A385F162CE3AB3CCAC6F86AF9C45FCF60D997C3A6DCF610DD4C6978A3BD071BE03C0495DB413D5D2ECDFCAB95865F0CF0C732AAA3ED403DD9901B1DBFB603FE933F994F6C0B5A7FA6788AF95F676F20AFA37D7590C31D10AE2B0FA71239499737C004E7436B1539ECD7E442AFC74EE027398AE51D87128BEDC2C2F1E8DA5FC017A748D6D51428853B71B4F8D07A593AB61FDA4C401CEF4AD4A202E957DC207B20E15F5923CABD23E5FDFB19C66EBB92E1A8226F546A3637CF69054CD173614E5B69462BBD53FE82386BBD5AF6B807DB21B6FEC62AC9B6FE7F6D1BD777B2940B43516CDBFBAE26722F6A88552544C656CAC0C1726A3E5EE30BFC1E140D40EBF234BFBF07AE5B3FAD3ACEE3F8A134CAC9B9EC925E8763F21E85A113C6E59F5CCA70EEDDC2540BED7C92817B22D464CF0B13CB824684728E1FD84E497E4D8B1968F9103E5B820D97BDCE02BBE71CE0D6A8C26769ABFE48ED47BFAD693EB992632B6B934B54EC903A5C35CD8845F0E43A0E856BB8ECD9CEB4EB70010BEF602C7EC170BDDEB6A1CE2474E3323EB133BE60E1A23C0AA0A88DAFDB69B4C492981A53EE45F006F687951F13E6399C0D3953F134B5015A62817F8F631F22F029EE3167D9CBDF890CC68818FD12DFFE4BE01B4BB04325C36770E85ACEAB462A919B5A2CBE9F6198F9E3C8D8F253818C5C1B6B3472DF05C8", - "sk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B74160D9539D135C3137993C93CB7E9DB32D97BED2F47CD513927BEAEA3EA4DE8DB3BB6F69EFBE8BC30B741160501F042738BE204496408E7B322B4F8810CE5F0A1B4F5853BD042BDC71BD3F713995F90D2997BE98853A3E0B05ECA0C2CD529C62D1D31142720430162555220261408757487051805486321463505328548138872674635348656038584807581556616567024781108748714006466586518105002840004152155071684402283301625468608582682871478285880112418701887856542813261486851086715532015038018055506582001004343174024123728627110402632383478155035530668058030807805254735026344715438314074570828778555510310503127760081644038768664440013167025735144760220153688771326556654136677416836236681275767825505783518026507108541306761822164356817775213250763580875702357583307542021077861788684686144273011537008501712324033761721553654884040484566604226000214651473588064077132555143158421687651533365271426802716634284747711533266322568582853708027003861221727624188548224553846320154218535004558846614210714725845776845035032840301165860462661558567062356487726862640113066862340546354378052445185333237853473826544553735144445868050241350888774173617075453531720267316818175415433376853422836031112605825812128668124221221813720163332878132662740616835058334581511783268088514555323113603245767313468456805542257754161745144715584644762635222801770257403571224173224101775575421637641653561651523472523353220007246647685422882100323788035807815471744883353670332227331383575023847310756871261578822337587022523242818335102643211010036128440207207414604308060212184302087706651107415366331635141330688886357276684550512668846326170485080755401433066163136305042535141770172143571578534537566273505072131666672802302137400258356111170004050122176802185713363384107338013714068046336638073677671825887712654440634342104756450234366074785063373770138355536602834482336117841811656443744500552574381774725612554820152456181136173480528377444617573837506101566008482616254362626412148541878576272451278865273175261065121480628166312811217332443874218160274773587204140232054516151580731416010517360222140016312345165580552765116138228663835802871501003418662168472077781187768025576001388352286135461575165005568123188068230433318746647171256317558746767878042633203465265747801218226257524465703521066601441767437260017503655584555626781625645828607216813374401208635875826640523026864485803177516421032408802243351517420170357837500517573422583060107563784043772507424567258253886871303426754383234648741138366371401462647365832748247554435886122467742424232347324855363843371303526333082723501448384560734138412613126277377455378767072466561765062756763081555387882428742444264545182347872215788716415115613725675021506301847681043752187440344541180617014583366082216418784124548587567538635417676816656583151701337688684365852214350536148165082118684731162728603020045865388212864485217252720226467655245757761056558883368818036647577235233732437782724674158151572615477036118545377305340788610187136740007740123076210307123022813564872374047362802876653816510510783134134880883380826444C8103AAD8657AA9B63770DC7A193DBFA1E0118E192420247B0444A7F836CA9CDC3A0980662EBFD520D15D923C37ABC4C3FC417AE01F017B157B85CA4AC48B3A5FBF10BD5E1F3BD2CE7E7477F4D47CB502DA2BF1D75FC48CBA9CC78781E33A3076A96F7D482609820FB1A1EA91EA2C423DA8C5E9ECC59F34BB5D58CA360DFCB4E4A10ACB046AC8A0C2F093FEF48DAB309A7645EE2FF18D88CB14737400C44B2EFD12D8C03579A5E0FE1B260F691B9A9D001FAE92D5C04A46D0232751D51B4945B86609AB60D80A9B04F573318062929CDB4EA895013B78D88B6379C1FBA2E729C7BE337DDDC9ED90FDB05595D48E12CC38732E00FB97735476D423EBFCD8B91D7D17D9C9F23FC65EDAE2281BC482EFAC37B48B23B9D1FBE8B8AEC1533844536F1B61BC8AD5C0DB80DF89B3DB99EBAF8014A8050F721123B45A913DD533C8C9A5789F2D6BEBD95CBA04555E36779C2F1D0F562E5C8597970C009A815FBA3F86D76BA778365365BB5D897B67076C9B826EA46578DE54285A6DC36BD9EB85F0B282376CAC0EC1ED7E22B05CF123792CCD02EBA13BC9079C62528075652685B70E291A659B578CFF8EC7858CBF990929A639F20455F3CF14A6E9FC8DAFADC9415B3B20C8B26B5775F66DD90851653B30C382D3FCBF8C823EB5F6FCF70C0357F71EBC54BDE2055615A1A1CFDF3A92888C5831A3AD66B5CB128397210804C3DED05CBEBC4B9F982CD5AC73154EB629E8EAEA4F5239E7A4F6A4628469169FFB74FDD8CD475F395E95C8F6CC451E46AFC3977BBE7EE3D2ACFC1C29C197752863C0ECD61060C90F3837A276DA89A7496435923C2B89786724FAE94EB1F585E8EA4CD6B0B8127B241A889BA2FD60CB8AE279F77BA7EABEC33EDB596D6EDDEDF252800F448C2FE0DEB52C00B2C59DFECDF7761ADAE9FF8B7908A5B441A70B451E136473FAA2310C59733200D238C75AA10FFBF9189580C53EA961A72FCD49EF3F7A7834FB0E0FB5101F0DC77819319223D1BE54CE05321D70BEB5347227EB13C2EF4BCB75DAE62B80BBC3F89FB40D83A0BA7DB94AFC86C469EF7EAF8843C508C465D90F850F85203A978134C4240479EA0E241F805161E7C0B28B2E960EB281270A26FD00B0FCC8942125B0E73474B186BBF1B2A22BA5CA4EE34BDABC5CC9729B25F02AEB9BC4FB18F11053DE96BBE76611B1AA5D3C8D1E256481BE19B03CD3FDFC9BE306F35ADF8B229CA3E2470D65DDC3F3774C453AC9F049D4E81AC955283B8C85B5F52F13A5B9AE74B08BBEEEB7FF9C7DB6F0DC10A8E18B5DE83725FA5B1A6E5A009753C694078CB88E8A2E95DBA4C5AEF8C041B8AADB984F533CEA6B560807CA8FAC3E16000DE18C94D0346BB6B6E01A739685207BADC4C641201C159BB256E56216CCA2DD471F34E97891785CF7E6BEDD14C92FE0160EF1B25DA80FF86739568F006E778AEAC09EBF4FB56D2DC914D549FC91CAE30C1F044AF84F2F814C3BD9EEA0FD43E04FB7C5ADAEEE456414DED08A0270B1C418AA964C31C0D9326618DB93BB2885A7F734DB1CFBD903D5A2ACA03185B3406E015DE23AEF3DF47F4394C6C406D63EDE57EFD3D00555592FF3454608E00D5B04B276D8D52E8533FA59D8DF4DA27AEB1A4D6E54FF340C9AB6F79DF17057517B7E50CAC46E99C2433A3F14CCF5A398AD94C433826D0497DE022529C0731FC5D567A2B63CB8473B1DD8EB40EE86143562E6A549CB58A94FBEC6E75E71ECDB0321D4E5FD2CFB9E8BE3E7B6A9CFB42FC42CF3D8A8FFF70E2E31A9D4DF35D6AA73AAF44A0E9FA0C49F1AD3A624B88DBBB2CE5754850914FE76938D2FA56298E56DBF447BC1DA818B2CBE6DBA78A240A070FC43A9C776562864A6846A4929C94B4F1138ABCD75DA0945C9AE6F1EA9468249DFF202F2E338B9BE3CE4CA099315346ADA893A49B969D26ECB3A05913DA9FFC13327CEB3DF6F0D1CD855282CB64CFBD0F695ECA2D4C24AB18FE07A79F2A129CFCDCEF608835AD2F56001E7B73DB415A132EB72D0E752E08849CF5F663A841D25792E3073A4A2634D9B41C3F9C73464F4694D116EC073C67C507C05FF3EF5FF1441D2396FC4583C8709C89E2EC6CB688B3713934E76B95E8C10CD2F3B9D0F298D2B66380C547D992894DA2554CE583743490A6792FF5490CA64868DFCD95C4D3AE21130DF4B00FC50CEA9AAA2277B76CE9F7CBF8778C30591A81F2FDB4F16C614FAD89600135B8084BC2494A119470C6D622B4B6DD534D086074874202F9772C190C301987A0BADD318C2152697E8397D4EEF55547C672F35985E3F298881BE917043C8B3E9679AEF3A65EA7E641F3805ACDB18E716493B597DADC3021293C234B5F3B548E82250FA5A2872357D961486CB95081829BB567AA3B352B64C0FB4F7072055FD8AAE50F855C9AE69A1850BEEF309A41D1B91A5E181E5020FC73DD5A90AE7271186F470E20D2093F44E128E044E5F7B516D746818B18A8D4E155B0CC322DEC548324B0241F4038C29E6CBA77C80228AC9291D1E5046F7AA321548AECD85847EAB71996E3AAF47738D06010DD373DC12FE362B599EC7B060120AF6435301B6324B7B99771300C7DFD369F7983D1054C1C45D37C8063C73765CC399CDF2C7ACCFF7A3B6F80C0110748BCA149DB1C7503E47CFBA8C4D44A9466D1DC0F3758932BB4F960AD5A67CA4EFE34F5D946220BEB96C787D88F87587D3C09DC4F6DE6CF1A91E463BD48398AECD75ABFDDB9DA29839D78260DB74FCD26D6918600C74C4218096D1BCF7054D7DB853379B88235AC069EEBA3BE170D9D5742E085B468D3ACB79FBA3972E46AD34CF645A979D3AB0E93E1B69F16B4C1225C048F5E5CB06AE5E9D84C59DDD9AFA1BA1291F3E02CB46DEE9B22EE622393E58AD1CD6EC3A9EF39BC5CB2252C17EFEE60F2A139EB84BD7E9131D70CDF35983D81252927FCD3CEAA9A6256CDBD0BB4A310945E7A6EBE10EE50AE002B281797313E621013D1F9E9537A51A9C32D89FD4C830D47E6F87F84B9C600861FB7191A73EBF28F9CCB83D031CCAFAB2EBAF1F4B67B651128CF35F70F8315D03E9AC420B730C7C7EB1C16623B89B89015E59A57EE9E4AA835436725459AB6EC1C3509384E1E44C50B86251EFA538C3050032DC9BED5245CF7708DC6C07382CA7B5664ECE3AA5C357492A1CFB76D49D4CAA23D237BDF1EA3F8EF35D2C893BC45329027AE33D9F63E9845BA7DE22DFE6A7222D1329060C4C8181D92C6B399E71ABA66FFBD4C29CED409B8E083012ABF3A8A1A9CD64F97E972CAFA4CA3861F5F73D891155F7DC9B49FDFCEA857981590E424752F9D80BACB50CE48AC3B8C8F25062DD793AD88B89E94A93A4A38753DCD1EE3FCAE78D680638C0B181A99F08EBA730BC90805E56C9C89BBCD093E1C8D9737FCFA8B1958D1C5E022072A04CEBF6CD3552CB1805A598EE9FF199144A5C4CEE2DFC1D318965DDEEFE9D2668281263143D9C38F4681A72096CD7DA420305ED6D5AC10B021D8CEFA981B0015099F5E5725B8D735455EC2FF2B8ADAF" - }, - { - "tcId": 42, - "deferred": false, - "seed": "12FB6DF663126191038F413001776E0791E024B1129DB3084A1CDB809404B555", - "pk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BB3E4B6E7AC1320C295DD121AE504385663CDEE9BBDC461D9AF9B74A36F30E52598E024FDC912F1D51924E3BA090D5E131218F69A80C44D920AA8B3569B36505F4D50F161A5DEB45E736CF04E61D6AC17948F496BDFCE3E9968861D267CE87D3233D12E0FC6A4DB86895F7D1F436483AC051DEF1E5A4738342B95890C90176FB8EF27029026E333E944A88D08DEE0340580A08DCC4A6ECAB4761279D76CA4DED5AA147D656DAA41EDE66F4C838F0A04E2A7B8E18E4413BECF01CE5415A17B6F39A5B7996A84D4158CB664AC36EB09980FDDD8323B2207384F60A63BAA446C0CA5A8982EDF24DD4DED8F07181000A22F9FED786FD3252749DFE193301414174CA01BDFD362D25985A6CBDB315026F813E3220FE8DC1E35EFE3F07772BA54861933B9CA9F8F68BCECE60F9F28148395C1605890D5F2B3E859EB7EAA3CDC66C58C9782AB8D67BA6EC271F454DD8EF82854D2CE61B5A513AB8FAE77A081D4A5B34CCE0100D31DAAED0852B9E77C904EED16AEA439B46BB2BCF42FD3ADDF320B4F1CA1737B8D7D3F7496C7C77107F2BFF1C907BB145CC2FC7F92CC3A3A4289CFD836AA2B7490393563E2848F0783EE4814BEB9F1FE75B5371BC9944029FF463361F65EB6654B588F9816FAE2083A4614DE3AF064D65A1254B4252C8B02F1919CFA11F7E523F51C99EF17CEFB5EB1F692FCDA240C3A0C504F2527A477A41BB2894AE3F3117E96FE3880D3447E1110FEBEE17CE73F1BA7956F397023E6CE4CFD8D3E1E84868C94C0737ED138FD7EF28A7D6E0A047215A3490A031C2E7085EA975FB16D129B7A70521AA45E9300355B930916D40FAB7E197244CAFDAB36C55CACCDD9EB203F48CBAB6DA41A29D686AA198576BA05F4575145DEBC8322DFBCE5A1D0899913DBE93F96033DDD73E8CFA20D92CC1E9869C217586E78FE30351EB421CCAC154089EDA5E4716E1BB022F264E76385AF044FB2EDD00D351B0FDC49B10ED29510FADEC7D7BCB72EDBE46650198C7B221335B354A7F6623842FAE558380FB0EFEDEAA161D0AC5CEDF64CD3FB1C709DB76C8C046CB5337438A72F283476687D26987B2C6C205F9B39BC2DB90EF13CD5440993F802BFC120F6062F8B62344231A268128B4AA66EB6A30EF98CB94CBD50667D9BE107A04C54631570584FD0132EC1F3AE8F115C54CA0849C05258CE87E6343BECC597087369594D1B847CDE8AB9D7D3EE1911953FEC22A2473064AE8BC3F406D81AED4C546C8E0DEC5327F2CF883DB613D5353837C823C005420E2114468B6B29B862FC6D0946964DE31D2490A14D5022ED160288F1C1B08DC9852FA66FD00138FDFBF6A1297B90152580AB8EB3E7374B627F32233E513FC9329A5062B3B376C5A3BD11E82979A0310E6BAB7A66E6A8CBF829E46C69BA03A9827EE64E0077DA863E7B046EE8521020166108EFE63D089A598E1930748A6446E4E817EC5450A07A01D49C767EBDC711F89B07C63B2140052C42AC2EB6243A4386E4E8FBE98F17F28C3C452AD376A2BF51C5E305904A1357D1F1B12EEE2D782F91DBE7891C7255872F43C697E8FD6CDC923FC866223812C568EEC14530BFFB2987E45F44E0F792B234718307275546DDA727789F918EF4897A6B586F9A614187FA19CB3AA3EAE11FDCF108F69581082882AAF9A85744BBC451263AE2E71A2E9EE1413403444FBC4CF5ED48E73211835DD7F2EB21545F4749CDD8FD83EF61A836AFB24FE46DA4A70E8241E81080D6AFA07CD3BEF47DD96A17E079EBCD81231D0D6496BD46438CB6342B7B7934A42F375A47B64B9CE0C08E21C5050204E576E552002FC90C86E92CD46A8E038A647B3635639DFDECDE6CC2628BAF8680529E9669EB28D02F1DD514943A034374C14A603327DA8F83A196FF531DEB4D642513977742745222F18DE817FE9BD55C4DC0810B56F516B673498F7EBEBC49BFF7C73305932E8F86DD79512EB52767154734816624DA121A925DE9A2CFD9104CD2C67F1CC2ED5413ED2C56AB5634DCA211DDBB333C8EBAFAE42771D9F4BFFED56D4C0B1C6683BFF51D0CC804E1E2F6B288C78CF292E0840D60462130DE3224AE058533B510D70CD9D5ECA048AA7472C5DF3CD8CA66FEE21194798237CFB506EE058319764FBC09F21B46850459CB581AE2417992351339F5F253895CC4251670192824A76F8FB63D926EFB1A070E0CDCFCA3B6D91E4564E085AEE5034A10FA2DF175E0B4EF2AC9BB6CE88DC16BEAB87A5A73350D5B7C964D005FABC58BA0C6CA62A7C127A49B8F01B6EB8AA51D3C102591E7A96029A248E4C65529613F177DF501C88DE3938C378EB4C71BAFB61624C15B8A14AB6C5B0840E0BEF1F6BE9FE4D469AD7189B3FD79B2AF4E9FB2D019F98E57E56D33EE4F32F2D21D8C11FB3190E3DE9DBBE9B5C96044D92E684B16C8A2AC216CBAEF735B2C72690F7692392904CEDE6BF8591833D4007C7732E7C0D70FAB6179D13CA6F77ECF27E689F7A6D4702D9BB293F3DCF7761DC6405CE43E32E73D8BBBC46C9EE7DF606BB4DECA8B197BCFC79D6494793C6DB02BDB2F14C3B81AB1D5F7E5F9E07AFF50B64CF2D82254D8E7658D3909BBC27522AB2B6A31394E925C84B665A4A030D5B1399902C0E31E27733E1761E460095FEE4E811C98A8FF6CBB37A27329B9DF33DF55A22E52DD17DFF78643675E913640FB6EBF88430487D1DA2CDB6148076F0EE6C84393D5", - "sk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BBDB2D29E491867090B9E965A697B5E5AE1CF087CE91425ABBE0CE0A5AF62653F1AC1EF5C1FEE6B7F332FF0876353BF37596D0FD0BD5144B2D28DF122762C53B0E688BBABC6FF40CA6B59885C172D7B8B03DF7E9EB847FC64437129BE6491FC9F17844745181084765356218212331443581827422547478716583235137304142402455774301672220067702281740345182635367206821152585408456654052728583200823033372154310824870472281817357366180438076076674475812436718415054614482424484278483046206360807771787771054735117481860335283427845150441828024348673056854648847118566408478657304738565734805614324307071342515464763053856836203744407720261127508640865603645571763504615240651218232156110531767574417578488131402811708672300570030415207614860486716278605250054542784421203140032858080104483743443502057255687503365145364325545780515742727205012463332228222545378481253257774532743251224012706856360000657410838731676482345513625233382538338360685487381801863581234163171801118480454512304805870580353572172486653225874875432158856321508853750572842660701771844633807757246836606614711553870048011642387468317806408144712357547215517244347457800162502560134340120227860884181180845236075730547174351241070547148484732728430350804426817052716534122672621650022564668418360272021232568277144644726668188641422271467488778515871817362810073182218026675237214022420675082370102767463268407376823612174601552176822253665808322107310413688206233547728348046326336582588831571550353146288604673611722768507738570106650282730540010814825386303560441675734048647887803531221650516815166201144723144731234257121763440850075481006600576245770066430232611184655640121061423732475158340280276165264230773851076665813040613203748418653067610885602255487480571513758574384651854415626417420543166747785171622576046385374026360446536560323364081514531124255163224126611340585256771327070023233175712863557000643568748470265527880027314325564436741673163013613563057262677350520653061006868115275687721800851442668541753630261381875745384251303754538638404618280501713206120252623514460810823423805714323631500120804284855515134331476516481847486650288541442660882611657005023631346640283306348184686066537312548854776538144604140728572838456414638133171874875422240152881130760145071162647006611762068256704854336802543356764210411586424602276003305764112061322443824572765215233587274448602602032341352101470571466720431168327107605723515030588630603022537525532211385730001520137417308382054521477265701811070771684871876723563513581351236548745640701728104731485470714068785004725608360521461771588538108418144581302136103731866083078237762606701124574620400076086186400026430204242416313181665824713128874033465213378736357151255754782458148571410206886244328708502561842137167528742821045110640483861757763044035404758481557643071506274125252625457522422851864812233285804123447364523664267670644684325263185521744116250655620038007410050478715435430444716138012661608280614268743443256531360686636133112133285152162217110212444684675883403052787004876652088607383057786732820085417285882C942ADDEFD289558DF68F84C5D3EEABC4272F5977AD513D3A8539D23950C631FB6FEC0A49A32EA5EE0B732A751FFA8281CF1C1D4A278E6F9C87F64D6D7DF0AF6DE3521AF8623512F6E27D4EFE4A716FB72F483FC9811832A56BC22612C7DAA2779EC83276AC46D188158D448FFC8316E526CE5194A2F2AFE14DC009EC89C712C705017E68EA63E9FD3FF5EDDF24AFC4533190A999F2E3909B93B0144CECCE997B32EEF929D73635EEC938BDA1660F58D15E5D9241C6061FA2DC43BC8E282081E324975DDE1B84C32C1031987B8252E1B2D3047EBAF0206691348A5FEDCB7988BA0D967D7FA8610CF7DE3B08A8BB536D2A80C75D74DBDC6DC1383A74B936E5E342E3F425E64660D230779C1BA1AAE18001BFD14EE3EFD849FDD81A561CA83F31531DCD1777AF16A8A7E37280D2C9D7989198AA342F845BE6F3FDC99FF6E4A2CD7E5DEF8D44CF72CFE0FE7A659ECA1816919613B8BF2255B77565CA0E332E18959EF7C4E3912F98BCC325AA4341C079A04C0B62050C9405F4E87C52C829C84AD60CB904B99B45653D5BC9B7CC96B4A8EB2BD62282F2B58A2FCDD4F48031B355B2C5D4D940B3E5EF791277D27E4D9E91EE5C1DD53C5F2C0F77D0CD693B80A97D7AAA4CA942D34879430BB0A5B354B51B3D61B47CB9C53339BA44BA39F617E28BAD34125090052479A275F9C9F787FE355C4B8E965EFA9EC3122CE4ABEF743361422AFB61D4136D5D83EC2476A17682B3E16FBFC14348B2A3618713F78BB39F23843A5FD50906920185AD1692597DF722B6C8EAE0324C615FB051474185ED261C1FEAD15086C88FD18A99226AB93DCE1A11C289B91B6DF0D7466B1AA26880FAD838B520EE9EB1753479FB5E9D17440336302A2E3B12A5602EAE3D561ECF7580B4308852BE844FBD025E598D3E4501DA5F0E4E8059AB05388505374F5EF6BF6D587AD79EDCE255211F91878B4CA75465884C75801995B4F21A2AC32E38DE736FD4D1C9C165F4C5FCC8F9392B768206084F4508ADE4AF5AB87DEA58B42F82AA64B03E32CBB5DEF948A14B6D93881EDFA5890291018F7BA6CC7148398823CD8840075A3335B5E0B1C164750CBC43D852C4D1778F258BCF6898E363E368B4DCB4863DF4667FA505557C35EF6150E74862FFEEF1C42779E870FEF08C55C1B7DFD433CAD4A6AD2DF25A90E840C07D5695AF96120BB6A41D48D4121E05FE703B1F5C8343BE403BF30868B215A36B9E79141409A0AD19E087E39AFAC1102A7D7A2411B4D435E4D731E6CB826F727508B0E7B360BD2AB2A778087FC0D6C2FBBB171EBF7A0CC40DA389836E895A6E0AEBD0BC0101D1E10BD7FF82DFA214631B38688BCF620F7188F33BBDF17CA3FDE11C60D4A68F62C2FAEB9082514944C93E31C69BA1446F4DA0390C250DBD21336667657326246A4CEEAB541803F7810FCC2A9136A186319E8A164D25EFE0CF08D98EEDEDE98BC226826F3AEDF19F5837818514E15960757F5B705FDD106E061BD6777A000169961D5800E5CFB63F81AFE396861CF87271C767DB3F023EA090270D46E4566533590CC29553316C3BA34655CBA17EAF8227C14A87019324D843641D3AA9E08BEFA9CBDFE9E43693E10E3CE2989AD595B1C279B971CB03B02644C8D205AD9AC00E52C9D66042875ED8A8340CE37CE026AF25B8ED1EB503AB1F29EEDCEC95C1053AE4CDEC7987E1AECF5FBB61ABCCD1AB81C38A674067B1D3D1DBB587BE58F0ED4F390F329ECF85EECF686FE7FAF7B065D14AE1AC5805611EBB4E24C609ADD608864FB88339A7C50135BF3B9FD149AABC7B812D9DD9902884ADA215039D1CC6DD687207BA91A9EC8FC2C18C15F2A841E2C7539AFC58C2F998B8D6F683B786F8A0859808150129BE0E57F7FCB39D102BA7346527F6C24DDD21B021835B32E094591087D20E0CA859159E033BD06C7ED6B76D56E49BB8DB788FEF5C3649197DFA25572301076AE65F3CFE0F135B8784614B65C458FF7EC6D386F10B673B5D17E5A2CE710835E5504902484DBF2D4C99B66821F94329F6159DC50B5F9611356F47FF4CA62C0BA7EA6CFF3953F68B3A2C4161D63C74AD4BED2EC2B7B57C81166016141F8684C26B7F7B7A6D136F1DC6669DB16215AEB0664B322E339AD8ADEAEB2631A18E423BD66ADB9DA0D7E29210A82F41EF96654032378DE32083A9DF91D237A69F7895D2AD7EE5695E498D7DA5FCB33ED831361A3AB049D36D605E3FBD7F019651467D06E9D8F14975EAB9E1D30296FAADEFDFC435BE54A23774D2D34284DDE0632AE5BC3EC76CE59675494522AEB4242F296B32D1E8F71B9255D7424CABF83377F94417CB6BE226FE2E42B020EC0132BE43E0D0F0A346A8451AC76122A44A15DD801573C704E0FEB63E9E5C2A7242A1BE0D3BAF8C887C05E032A4E5CF49C462DE9FADF951085420FD67A5E31AD9AB33B8FCE6C22C5E3CFE8B87BD3A13CB921CA861315C7714F96CEBAE615B179A62AEF869E81A3A5A16AA6C5A7EB6A7025BD47D1E734818A539AB8AABB6FD1D14F2D92A22A9977C9DAEA678DAD360EC2B7E8BF72A5EF72556251356937F6F515329887914D81B66FA071C538152D75208B58BD381139F5626F5373A6A319EEC4C79A37F759F27CB2CB76D18CCF5185370D3058C9B9571845554BD64D87D5999CDA335E3F93AEA99588F2BAFBFC9DBA476B06ED3A57D8D913C46FB9734A4B5FF97ACADDF5F6E08C9273F712639633A04C7E7B7CEF00876AD865F2895680A808EBBE6E8AF85EB2FACA81C33E4AE8097A9A003DF4161640CC96506F42227DE85E93177100AC01F05A6E5701FB8841DFA529B35507442480B00088C5C60026AA77DEF2B81EA411C88EA6770C5F849528EAE68F1D83E2462AFCFA372241A988E0738514AEE3F32723EC78EFD8C04ADE28291C309B2217D251C19BDF9E051394414E49AF076CF8A5DF9BE6A4C7825839F1805D3DA89EB2071B9E2486FBEEBF1A5967F1AC58A072901B82DBA4D6090E4A40020590351837EEF6CF6E4CC678F3FAA67BE1E16740E7FDA873BE73C71ADD485001D002CB3DF4FEF3ED277D130BF66D8C4106491448C10B8C402DD50C95CFA53CD8EB375D64E5E7500C66932B33E0A1A1433B8FC80D0EDB37004A2F64A3207512CA591123313DBD5C0C5D99475595F2CAFEE7E9BB138E518E679264D977E2320CFC59F467D889B5B4D3756D532C61BEAE3199EE83D905A440BA311D8F8B7529CC0350BEAFB908BFD7BDD542F6FFA460D2116008F16F0471157C117982506D82E13A703EB53544A8783484526D8251628E1020DADD2F502A5E70FA9E90BDF1CB9899F79B2F24BD5D09DFB876B1845515D947F8DCA2EAA40820556D16BD93382DD3283D98BC11CCE2418C43A35E07AB307766206C0F137254FE736F15821E3AA07EAE299A33C31C896C2569BD39D2A0736ECB396FA4AF9799180C693B342A56D7255659F75022E37D301041297377C228A367A8672D0FAFF459A0DA9C40BFF60ECE85782E991F0682DFA73099A87AE293860B143EC788148" - }, - { - "tcId": 43, - "deferred": false, - "seed": "2D6ECBAAE0E5A784B543BE58A0650680AE813A01C7E0C9FE65ECB32A304DD218", - "pk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503BFCA2420ACE9FBA45D4F39487658C0AF41E5C876C107B772C7366B70DF124C15DE0029FA1F002EA566AF04441D7C7E33DFAB7936F19F34A73AEAF42026E4A7245D6FBA3C21F26EDD80652442522019A72E586BEF8C655AF4B3E6C6AE8B8678A81AE39E3A4D756AF595E15AA8C4ADEDCC4E5BA4F8EB4AB5BCEFAAAEF15A629FBECF7BDC657910A62E5E02E3FA3F1D7FC4D94EE56F252B53020E325C25129C5C4501FDED83D071C59FE6454AEB1271161DD062D0308D1C515360E3DE60C383074944762EA6464C175F7A9D317CBEB83A8238FBC383F02E299EA185C37F259EB4BBE3A9B26353BCA9A1D877007A48B1BE4ACF21AF2B6D1B27EDD5C3DC2A77A17C6EC0A9988F2DF6EF5087FB15D482439D26CF63256ECEC16BEBC92A65A112C2A277DAB80A0FC49A18873F9F62E48E44BE451C161D5DF260EB14EC62083485CF28AE98FABB0008FEB12B0387AA1BA88E70CA703F8E2DA0F7DE8F08419FCBD0A5C120081E0F57A91857D476DAB4BBF70B3BFB7695B48486F3E8ED074B258B930C092F73D749E2671A9163F631B9EAD06D631BD8325B4DCB40BEDD67D9CCE14963C5D4B2EAD21EBEEBB441936039F99BB12E5629D5959DFA5627335757A6FA6A2482DEF787BFB173BABC595DF3D03477F8CA89B82923799BD5A94329CF9B1B950260CAF3152441B51B576C5CA9213E8AE2B34858BD4BFCC5642FD4A65C1F38F5444BD0FAC0C24E6D9AB20791FD3AE3298CFFA4B1F2C113CCACE75ECF9A83015C83ED7C6B20FA037E83529D8182A16070C6AF08652AC7F4190BCB569A7BA00BAEE9FCA16D9B0485FAFB55F048EACCB80D72B34299C9820C0D3E06EA8B08F844D296C180D7F86AFEA7355BC0B48C58A65C55F7582EBFE9D23FEA305B645F31EB1BC7C158F3D14D74101973FA0975202CCC83CC962B2852A409E6C757427E9309746BEA177FA23FF5DAC5ABCC5F85A8D87861104B41B04AEF79C31C907F9774C06C2A4CF36C2E17829149743455E419E672F744C3A75DF01D6239E4492E643CCCEF324FFDC0E42E531E28D98E9EB41A5906BC6EC0C4B41ED82CA86262F768D89A3C8860C18F1B42356ADC9C1DEC2A311DBA00F7E24688642E75C1325D4F72619535302B520660EB56BBF4E7CC7F35EE8261D3AD2174EF0F5B5AAAF9F664B61AE18C5368F080A9238B6D4F4047836C9D784B95B84BDE8AA165B3FA5E582A2F24AEFC50F1DAB9FBF666E4ECC858599568FBD3CF90EF6F23365951A00F808AD1B8B6EC09084C97268330A5E24F4F8F5C73D5C365A5F88D1287C5E37076BF79D3CA40EED1FAD9DFAC8B7A954CD58BFB24C200704E19844BB47F5CEDB184AF2939341D28229F63EAE74D1AA2D14550474247FA3922D2C24E40A5F3A765B3E41F0126DF8A494F8C8EEF43F05E8AEBB1FC899013BC21B764C33CF4EDE643055DE39AE5394C570646828AD265FCDF37E0CD152DD07ACBA5C28E57BC8D82D871C49C457DC3CECE1758EA883E0E13166E4B82262492136FC221A15B9725647B10663ABF3A3B589A73226D8CDC97B7CA86CEAB4AD973D83F85190CF0F50938C1E11D3796FF3BC839308C3E8D96AE71239CE9C189F7F00DB181A95A5F59D371B3F238F456D736AF7A948D9CDEC9AD6DAAED77E47AAA925D9EA0B0B4007E6FE9078CF127729AD03FA43789F38D7277262502D17580A2586453B1C38A24C7F5C59D96500FF01BF04224A9A868264189DA9CF4F3508B145EF402D217CE991419B68E5A82E00BC46DA3149E392D042E785817A41E33C823F4C6D2551D5EB03E9EA862CD175D58FFD1B5D7BFD1C7AC8C6A505D937A36C89A60702B7F64345D13D82BD29C86302AACD1B1835186C5F3F56B9E44E085106CC96907A332F0FDBEA742A6715BFED95D606C9F05B5F37F8F51BB049BA47DBD5EBB80739817EAF3F09810B00D9702A91077D60A09E7E70562EA84492B9DADFE4B8DC957727FA2296A97D24CA5F065F17DEB081395DCF58033AFC2F424A0CCC3220C477CCD627AB4E1D7104477D799833E2AC49AAE6D055C97D32391F7C138DAA8CA142D33CC035E4FABC57F3D1B0D8F93468D08BA33BE80C820EA5B3445B4E07E584B42DC27DD24FE42DA51B410ADC3D8AD3B8FE21C573858EFC0B6E709F91D86F6360C5B7F1F98A4B7D0F606DB60BE93CEAEE79A2112A93D0D6581A58ABE136FC6A87A6FF3D993020A6E5BBC682BB2175C5E6AC38708BE21A501E515CDF4D87B0D1C57ECF232936A78C525FE54557695ECBFD0B8751BC299F0B8A98979960939A1C88F3553A98A30021D27C72C9B25D274D642D50E0B438A65A68C6A2FFCB3D0E7CEFE9F0F5722E033F7358D7710D18A1BCDB12E4D01E3E8A580EF1A830DA29207ACBC45FD589270A9A82D7E090406C60DF24886E62F3055CF4E9E2D03400475D226228DCFCBF396868B1E79F91ADAAD9542CAFF5FE3483D51FFEF8CB247F2E90F489D0066E40BAD3D00222047BCC934FCBB4084D5D6B0397C93DECFBDD0D22CCB2A04ABA3DDCF8E6BDC4BF271EF1B55F808AB58CFBE7B8D27D334F0CFB0E2A8E3926AF6B584BF746DD8E7106EB4D0272B234A48707A9731159BA9F772D1BB885A8BE43CC527EA6F304D1CC25A41F876D393838C13D3FE8E7B1232DD59C553977D86D2F0634C9061CCCEC779862398D13753F046CBC1C6BBCB2184D3B93EF6307D094600520A13C9A61CF8F24B966F33A4E1D4A63129B", - "sk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503B2A3D818FA1632E882FB4B102891F36847D725EFB265104C96C6249D614CE2DA2FD15B9A2915A14F0F18067A2EBC07177869430C6A3900FFDAD11EEA8256258954C53CDC5092E082B959CAD36E830534AE598CB9A40805DA6AFE3A33C781B67682304811862666262674883630257466336654176127111610188405651882248835621772103713057301461408544446057187771006674605835060402676635418131476413436003120645277455515485670383644331501872624770716378003605043343662173545134662807012482221028367326430336535664448056113574018581120523841166041143840318651156482606328312581566713531544126481316674737206548863641151137443513805664368650232741372866237083842038500867032145440548358704527308541843850274876810732814453828163568433334252171168355156128245552322375020411688726150257732451832171850113208171275024208763087043620431368784852342633345325381082054768367221670638442265455241150542031786524420340504232434554630307202834160338843770683236510173416158055663006632524311202770074186756864725651225115207874172102767108723215410126544502265753858458031284223785244845208708477813813164616574044334063467141642437824662515130780320530524304615455323331052410022757028285822155463465307887721528548442757207157143662703603322523164328585723017213078884661343736471304300711110210007661410452167826762283616602211111814737670478671581647376618273266215607470650400468274107273140772805621181485466005826678168630861123665356648222147531357331816374484742736281012353528830064601303473326670343601815332320656614136537004121661334847127484167341210426215347444665228633775855605113481362562501604066143748138675085214380117534354518528803214733100542576016451870144542343240477121026665084103270221073287781215258026275727484778353836573535212634148130745855242442608642460711873814258078850618877672413774513172426032072356862074508810306014067080867427757824824028824108174406026218102520624880108734712762825145441131055432206348270026562148550718452404551485343104823587357361075363067777608700730787068538524620734084330357617168267260432467052780270082138751130213247302351083133755083746701327633651771612817385522241687365428627888010160240244451556860642616888021741676615122361567710825223512105410650126041326541401456171026106665284806160355012356447348246653058504148285820087475110160353520303780551734644523605167821608646410237607101761118786078003148446280063422132668120564163088754007557568310505200680472867527162330302442631523115778167707572822871262554364140832017606753138334338852737720140605628627473251125862002613337020675245162661260861007155034720455157108418561023828220700355382181424101273721445815451858423724440784253713785183511880022873741854405034651712631638575532026648282103088505253625664346403781263188161174460770820772032382661577887440223154505470856385852111666161268622021383012686823504876281517266854274311810301526324508130485562286633448201880388745815358336710062432506786440757406072140568841501477456514813456204417571574122527482775515235688833535654757407187843821823872746421510747450775537360482055485647333021465B68C4EC5CBD1447A46D08AAE37528E592C1BABBCC9F5FE65F159E1C54AD88B07A7C424748C63C42101D44A8CBC87510BE76B9F61F3314BEA466B2F7AD9C7831DD8F077ECF863AD498AEC0735DBD6D0A86F2DBE80487C08E0E15D4F7CA9DC09822E3A541D65A07BB3BF9C39AB410EF2C0A2F707985F8DC2A72C9269912A3282D6D0480D37927959BAE33003B5A03A2F82850BD15266F977EDEDFFAABC2B0BC9BA8C550B5D7519806A574BB1402812D52D6133845DF5EC6172352C2FF5D258D3D5858A2EA5EE606A40CB2D76F461980816BF6A536A79D1667AE5422346BDADBE2F6C70FC143AA30F4C154E22E5DCFCD641CE01EEEE50F42AD9BA102FE9D8A186190A495FA807A5CA7552B8827D90FF2FE48F8F195391E358754A3B032D155286A324CA507F16A815706A3A5A1F127E134BC5B5143659E4601212A46651A4C7F8823AF02BE5E3E04F41F47259C66B131850A7D9B0DBD3A415E078625127DE9F1D602DBA207C0720F3F96A44D86D60802ED16271AFEEC041FA8AABF92209A4D9E53B311956E46550E4326A5C50CCA7AEAEB692176DBBA39C51272036B38FF92182A22C4758D1B865C1BBFB342C1F9407BABEE19DBFE046E122E18CF7A25FEC6A28CE4C33C121ECD9316E9AF0016A16BCCC46CF6329D878F48990351829BE43228F200656D57813FFAC51DC487A86F6858FCDC46910024AEACBBA199DDC66963D914E970EBD38F18EFE709BA2691DDC8CC272095302BB2D25657C32BC64915575B173085D920AEDDFC37177B5FE4F38ABCE426EC46E0723E00982FBE5C7E8E5A4F26540E37DC39E022DE7A08F13B3E9F88D05C30C8970899E2C3FB898CFBBA00AB8DF919FA51CDA3E8193F52B8390D7C274C7F5A344EE42312B823DB36BCCAD37C4B213011F0310DC9BA72B851658DDD5741731F21A6CE7F9059872CCB9ED69F732B7410033D8B5ACBD66B33928E3A7D7D5A28E3245E883A2AD84F7C2409AFF0402E982BC95719C10BD187A454DEFC7D3693AC537ADA62BE47D6681667CE11F9AFCBD8031F92085400BC086CB4B61FA363096DF205CAD59F6859667A9BF44888A0BEE5D4B63C4E95AA59F02C2AA9BDD02519E1758ACE89AEF92F32789656E071BCB10767F2727C309107847DE2A0C06360DAABB356C35086E4C95AC668F0F4760F636754879CED6A1D569FB11E5EFA2802E8B1C8C3935F6C5C097B96EA478143C2D2EA5C1E64FE19E03F180B70F4EA91FA327AE0BA6F4C3179570C62C10A7AF043BE2419959F53A31EDBFA1E091029F96EA203BF98E6798D96727DB60909C09A9339FE71CE9E4DA0BE641F0E8E53B43277EBFBD0682459DC028C6F7C042C1CDEAE9DAC9511E6EDE9B4927454EF9BD651B233606B644BC2DA0B29500B0890D64CEA0EEC968146C5E5FE395087BB4884F0206455290BA892B0D929632D098C33C8D6E27022578249C9DC0C207409799801ECABD7CE84729884E8714A19A05B9C7C8E6D203400ADEAFB0CA2669C8241914F85186EA0B50AB4FF646C5D386FCC3F4178EE18BF5AACAF6B1ECF1F5F894ADE5FB8F5EA336BF88548102EB3C897AF6CBDFC7A6F6667E075475359840328BD9131D2D17FEC3A9034D3C7766110EA3118161A42D3B61AB5AADC71352BCD0B5A1DA9CB741F70A6ED9EFB8ABD5229697852AC27C189CCE811A9025BDDDA939167BA717F1C3EADED18D9FA05C2828673AF274488F154B63FFBD853AFA274E182D83D37C97C7090BB9F2DAF9B37862F846C46E55BE02AC19D23AC0760E2B657C0B1B134FFF3C6753F96EE8B2CFF394B0F5B50CB77E8F7614664FB3F0EA8BA85D45582A71F3CAC0DFBEEF6848C63A270DE0D2696AC4FE1EEAA781349B02614DB517807CF4D2B0AC80FFBF0160CACB94F2C700D57E156774D85B52F5245DA4DD8E4FBD2B9DD1B9256FB65D538582CA08C20C289C5AF404349B12E5B3A431F53194E894A45F7AC68FE4A0BA8FECEFF0749ADA4A9B87D52563572F1B0594C62586BF28A821DE955696AC76565861F6F44A167534232C3EDDCD921F5D939284DA288A8233193B231905C76CA822B72FB04C21B4D7011D4DFF88544C1408FFB8159A597E7C4184BF2AB570C9CD7C0B8682EE942B864A52F4B71C6A79121E16C40DA0AB4718FD859598A4F52790835A5D87018339C221DCCB8011796CA373C9DB8EE2926046B0BC01C4CC6BD84E824CAF382EBB9D2BE3F8366100116F0234CB3C53CB418BED8B8A530CFB64832C78E6FCDC31D830E894DA330737C0D14EADA335E7BBA9E270751BBC0D72A137F3496D3F4057428F00C5E8A6782ECAE0E48C3B0D1220F2738AC092793C18FD30478B57BDBD2C4C9462A37B1639163BDAD2D9A11C36467AE1906DFF0F3C5A7134D09168DF7811FB2418C43D576CCC191F0343373CE73432735B178BB122A9A65AE84B27EE42707895C6412A4970628DF736082D11D2022C08C2759BB086547148C885128882C0D716DB047A5821BC1BBEE85E4AB3C5B8B40A5D673CE74357A475D47E96EC40337FA16C6B2FC3F09EE71E7FD4458712112412F6549775D0F66DA948E34BDC30FAA8BE5241D57C48DAE353CA3191AEE310A055850A266E04BB78982D0432D84531B0B20A2B3D238C2EE1556468A193A9A032657226AC726D9757641829615989251393CE0171AB29F94C1D583ADFE35EF8B9859B67364DFD3EDE5DA27CF277680C65C0589CD7F715727017F02F14CD9622468DF17D5697AC895AE8D46CCB1FB0DA103AE57A97F316BD0179B297061F6286C07294C55458144C6AA2E1932388362559F28289B0361EC79A8D81E6C77E7EF0D3327A85ACCAA082862BF5D99DFE89243125A9BD7BB2FBA35DB442E41E1DB8563F54AE40D444974307F410CDE68CA0BA9B923F82D5F181C141F3160A0450F57454FE6DE530F8661D49E1A87883003C5D1B83E0F21004E2648970E3807DF2B865BB961242943733938ADDD5D219B7FBDBAC5ACF5EF250A67A0923E8908C265876E56907F71FF287A6C16F21F61424D72F58CC468D399045F32083A17736A99A263E976E14492A6791E1EAD4D568AC062168A7E85F115CDC302B567E66A6FA7BE6FC6D6F7D4E8751603079A64EF9E46B9EB1DD50D94D0D85CEF2F7BFC58B5BCC193555D4B83D454CFBC2F910FF7D6E22E9A27BAE8A95A229D79C64BBCA7F563DA32246BD8C7B1D5022E0EDCFF163B03E4A3CBF2ED74409FA652D82311A753CFAFF4D9EA50BF7D91212E60B23424C90EDBAE25F0202D71CB566D6C4E5106C6D618B8E49ADD7156561D11963D2A1DD17A7C2C00145FB0AC9673788D8AC7886470719E405BFCE819A7083DE2D841FE616078208EF2AF75B38A20C61573A4094A6826DC2AE481A2E3391260BB9F01075258B7EAE81E2CBE387FFC018EA827BCFBC92CD49ED433DAFCF00CE55812FF8FDB0F566DDA8C6F7942CF7A9E07E2BCEDF02D2AAF40A66D0A55912F32A1F1D5C5071DCB5EB86CFC576791FBB66B5F0D38C9D2F2E31F86965ACFE661A9954F3FA8E9652988D0D2BF72" - }, - { - "tcId": 44, - "deferred": false, - "seed": "3199830796190C3968520DAD86A85B677558A22257E43459AC684B68CE336DA7", - "pk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A473CF3EA6AEBDEE745DFF2CBE7A31EDC4221052D97347909F0567ABF97ACA00EC5FB1D9044A346866B1D7F99084C55E01687D6482390FF78468628D011FF6435C1A0FA157A895AE77B1745E49EC365F051A461980C4A22715FBDEA55972D41FB6549BC5085E175042CF5554C03D4179095625449D7EA256949E94469DC1E1BC3D5D91F2DCEF107EB8F17EFDA721EC1D1B0F6BDD2DA9F4B628B4D467584A1DC37F33D4BA326A6E783C562548EED4891DDB715072A7105CD1F65D4E5CF147896E3D16AFC221CBE3ABBB3633709A91293DA31A0C351C9974731FC48D72BB69BA69A76F06EF17E3DE3818570809848DA31EDE05D9BA734F898F38058C8726B8E08A22CB0F07482E4E96CD9AF73C9A04A16E3DCAF2DF45DD49EB0AA4B0F263D071141C0AA08CFC61CAFF95AB9AA4D66C20FCEF62F2E4D7A85EC0E4996AB14DB4130BCFED9C9465BC93D8C424D1904A732E5A198D183B7184E0BE2123A135139DBFE7721B5863B30F8A99FBC5221F1863CD22BCC710632B300C8A667C702E091807A3BA8DF2A96A072C991673851B0F30E0570A68BE0D1AAD7910E68C40C240A6F151B559A970A1F10A81A91FEAA8226389C9378B178BDC69A4DE7AEB439007741EEBB06F2C57BBD01D80114659939715C42E7CBABBEC944E40129E4C626A53CB1AEEA0D4C1EF556A9CDD6411010227CCCD4BBFCF634B2B59FC7F51E42AF50339ED2BD88F7D7840CF2A26CB5F64B1CDD1D7671687400219F4291FA480134E3BA5CBC8DDBC463E552F8F92268962D97154BFFD77C061EF9C14D343F49EA0BA241124DD41211E1B75F6C0623CB0822E5FAF8CE10BC07E9AE9441BD50F4AC7D79846FADA78C9793A55BBCDECDD98CE0A669665E33E0A8A142CB338D05CCC9F776A04DF80A95AA00775D52803EF71A57732657EAB19493C212F9EC961EFB24302F32A489624CEBF07F23DD09412045A413C67FA16592C8BAC0C98A5D5476EFCA9B6BFBB38E87D301579F8D8AD6DAF8B2C6B9DD026C19C931C42FF9155DE9D0959F30E04463F264FFC1589A9DBAE3D96E247925892C230A6200D446FDD0010BABC17BE23EB98183ED8E333EE2837B43895E5378D3BE60136696C2CD55DEC42AB817844E77E430964BA68E700B766BF046655954BCB9685929C018B0B3C7747B8CC37F1141AA9A3B190E46578FE93DA3B44BB48F339C861FD4F97BA0B0B4852F839785C542E4151D9944E26A131D5C248EA31C9F41B158F8DA5E025F3AEF3D2A15386BC095FEFB360E4818BD76446D5F0A72FD4954E5329523202D7C05EFAB170D185B2BF0D32BDB32F33A7460DFBC4ABDD929FFA5FA21340A5EA68DFE1DB724E0E9FF2E734FA6A11E5FFD61F086C90ACC6EDADFE8DF68946901C5CCFB5A74CB6B9CE8C490709B0834605FBD161839568FA1413571BC7B350F78F48D23F67122FB629DE30A85C594620B92284766F9F2664C7DD414F2933E0E62C0DA5E48A8C82E34D66C559D9BCA52A06E55E42817F4B5AC06ADBFD3B06433442216E47FBDEDA317C50E2107E8D6592C0BDB963DD4DF016102C8BD78C5134E9E120D0462606EB5E3822D00D235AD9C7A8CF169610C65AAD5480C45E2D9D95C80ADCACBAF5857F86FE4CB5DE389ED1803B05FFE13F724B02FEAD70E900F3AED263624AF0EEF24DDAEF803AABB07EA37366323B6C306E77B81B00B3A5823611C803A62C9287A09035834BEE86ACFDA3EE3A3FC69AE707A74C37CC597AFAFEDDC3490E4F19CF0195217DF1BCD3E24D1BE5787C6A08369EC6867593388E2CC5677A10CE6D9AF6C0FDD970F0D484F041C5A4C2697F92E52DEF895ADB8194A11711F055FB06C5B9137D446AFB847E562A1F5DDFC6F17DB54DC8FCB33C600EC7BD5045F8EED910D2D19D14B422EA6C1F31D3AA272C2D6E4635F38AB155FAB5C8595F5A1ABD240150C1D20DA320A7702A499BB3F51AE6DC74240BFED48D152FD628E7B2854F894718D3B5A94A887B12BFAF7456C418A83356F5D0ECD7EF4955CE1079D4781BA21044E64E71CE375B5AB6977D09957DAAB44CB2B349670B11C3F740E85518124332EB859718719E4C3A7EC3EF474C0F4EAFD0C104C1753396E8DF1090E4E42A4900665BA62434D8F1D3E3DF25569950E401205A3A8649853EB34DD026D35CCA312C5D05842D2744B643728053A93EAA878AF045632C4DA0986AEC5F4E5E0F93DAD38911A8307622A2EE9FBB93EE62B7F2D90B222AB0D23211E71227A2152D6DC2E536EA0F8118464A9C8F9B1D85D6C10BABEA6FDB2262595687ADD404C4C15C4C2189BFB7660C5CBA279EB6FD85A4C5276005C7EC5B3765D299783E926124597132D7EB623D665CEA1DB454578985E785022F680BD1439AAFA60E90694CB720EEDEB301B9E948E424B5D5B4E6D976B6E3BF31029F346024DE71AC2C2B42105FFB6054226FEE8A80C2471C052C3C07D6A4CF749135E03A0B263576F9F19BF7FAD0FA16F39A3A8C4335B0039A197C12465C9C9D6E5D5964186FB6FD7E7EC615F1DA758F207ACAF8B219B256CDC6B5200B64FCB9CAEF6540E2B4D5F382C9D8682B72F3D359650D74E69038527A215221980B30AC3C066F2198F781D1D318B53F0B0EF5A8FDCA5D1B1D6D978CFA7D8681E2BDCE2B0D494A30D7092DF7536B1EAF0ADC98E00D9FC718CE797240CF4E3AE2B8AAA87AF2FAB32922E4A87CD267FA2B6F1CA38F4F5ECBDFF0C879E12", - "sk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A47AB123CECA94687F65EC4FD6FC892101A78F01026F29E0135AF71EE700E7C2CBC73CF903B7B4888927C0F819C0CA2EDCBD907067803377984AA4FF3E17734478A57E2B35B766399418F75C7975ACD04F60063F2F0BFCA26E50F070B0A1A195353724566837267013523843061217340448208603377516427785068105543815455713385838378638182068387137202878174761230078700864648646024855062224860686668854027226160574716084705654107343266361631364842553385601555588856047580535034530370012175508353073724842155863748067168114848882320522407062271240544578230102367855236538671440435531266463107672883753384543572436706682450834316033375243560363701823084801423101304218866444185862300771604518682156827233004524227545010242832663758743810826325221807752832476605018480872813137847777000653666127557527716638486160042404864166636102870313548832240045178714184303667865718102217306530807425665255147226317774324026116685410151810861754650667058078686427182806416042711402016888435813707675336867138675385874877012367321122252527373105272488877008643087733704347456662422460586083063645404228215715050611018103186084667757203763065215143246526035450665527055616815808787430678265678120245012578311308256263333860323880466256476062110526427163351471203052665006541664736828465247818142306281443835837182183652107651602852387576021550653670563332605536365174537158126383246523487401623134168384464856206204768217870623261824124585771546525528033177675181171075524844712203858364348868366630338263454740137745641040281333252087128027252246866743284811231073882131764045468851375840422556572064517855348352776346620056667224700385762102065606267611202427345130114347574537103157673262766574536203507836868203424662260332464514814176307376835282323336537583824722072737215563716516622534570868515740510531360567302685310330081808880645123531722346410845162360657713551527237544415554545544676603556376177653716885147033372853404163258617884540527813328211514033674414257460047837602245324068143272035585220146643616441718725600482680403063464864523457642605402244220645225704532847633875702715808568343465273572577521166715627587343885578373673372766332716633554116600462443030006236252146783520750515425417144815346847112732253776133677705301441278410464448741113474825577724608565567664387072414188665482012132181145627744672156457615822101260650685316686216446276142280271565741485500215068572175027842512176043780617184765347663010028034833058116425222513618208124855666167843357777361347708737016118061814685808301052444558752468101207730047385746728811752708526513738756226634713860484428284725564228166015837222131614501433104081222168277767128212721462486143511455718342443083388355003610147772667647654723627762544342374672085384358876058841431863634132804448410306706760647544551074056854262848837436080043515363533205588831716267387132602472322688526176687873184770211636173375004366841185377208728801202224543227412038046055442545283515488671645386881814722167054187675850246200624520546261410308840183184005181485267722758628353566744521701762386445637465210013676767755BF422E848963E128A6250E1EA8CD6994A61AC9A0145EDF10B3F305466E0ED49A068336C98B0567F9FB23C5A87F7ACAF7F22A9CDECE4215215B168AFAB7821266C858A92579D96BA48BC94A120657B5C60BA282A2BCA3349C13C2E56D7BBDA2D0DBB6072FDEA7A1D8FBC9B9D965E9C8DAFB3DD8EBF78BBC57AE218800125A80765173C6C95FB23FFF90C87F7F090758A1DAC96DA7537B8CE57B1E313312CB26799A65E9AAF0387D2CA3DD5E348918B7CA888E0BCCF9136E55EE70903A2DBBCE3476AEF4CF338E7CAC5FE067E23699FAE85A9EFD9E68242949786AB2A2EA82EAF8053E20953A1EF07BB9E22D7847D9BDB6A06A09948038BA5448337264179180AAC89158B68A6CC91507E552AC1DAE3619FD2FA2E0CFA0C2489B3C9AB4FACF1EC5BDFD188BEC71782AA4C3C6B0C6097AE93C7EA5920A832F6536CF5E81D1A222B9B936D5B57BF539014AFB8ED19B076D5C3EC355D06A7B56523273AB4231A4DAC8942D5DDFD58A73F968CCE3A8BDDC5D4F703CAAEBBB910C264EC2079FF75F9417A97502C91DDC2FF5625A3C535C04C8F95FB0B557B6335299DAD717D21A9973433C5B11AF908BF9B88E4B1941EC12E9BCB9F2B2331B7F08B2EB04FC30CD0A99ED2CBBD3DB18E32CB5C160FA885EDF8188FA8716C0FA9232FECFD3EA34330A61465D4E10C25497BBDBEE15070C3EA66E172EADD1DC7686CC32418CC26AF4B2D61259672B51D6E86DEAF4208F6822FDF28D4F3706D92FC66EBFF9E6AFD36D2D18F25292E8175ECACB7465FC04E674ECCE3A62ABECF9C2D1A52171FB411FDCC893C43C6CFA94B1731F21278378EB94ECD9774054F2D6DC682A07980C87F6C37D3C0822FA30334B90DA764856BC84CFE131172E75639935E9FDC42027907FA20363B0A32C7A29588C003DF13DB2AE9C7BD6682B743B7919DE78F8E819376C1D9E64FD1EA0750C335F56E9326E94107DF6E441EC38507755D3C48301B616782A1F4ABDC98BC8585A18C29E80A32DB88EBC3959DDEEB53638F6D58B58888EE0FE37AC86148BE1DEFBBF3E5FF194F9538044036B95639DD219592F0433D695C074CE6E9710FF9C0B1D6891ABF1396B5CF34BDECE6B3F559B1D813CDAA5DF038A949AED51DFF2C2E821C643032FE6DD6A74803E2E2DED13D446BC969AF4A0BB2B973D5CC54E2AEF9896EE166D807B0E41353D6DA28D8F5FC2F3D991CE68AAC6DC75663323080D5688FC6C6DBA56C033896F0581BB8E9F0E9E3AD561490FE9B8702D9FD32B652C7E7B74B74A489B981DCB598B6DC38A7CD69C8F429D1B2B0C827D8AA31860842758AA1720D87B23074DD0B70601FE0C2AB6B72BC4FC836C81EFD49B94AAF378AA828CB90242448101732633D0E68DB2573588809CB76A80066109F6805445F3880A4CF143D02384A5198E84796EB9E3EDEE3C64DE761DAC094B05A4D8981CB54B72C317E4ED791C49159A4E4E8C21F869FCF320F90C0E67B0BC2BA193E29E5018213C1AE8E9D256D8740C5103DCBA8EAB450A6E259B334E3448CEFEFF100D03104F810A7CC5D085FA80F054E4AE67AB242545A818E4EA1F3586945C3A4D242EE5ABE14DB6EA38F50407A88DA116D6D3BAD935A32817B4A24119E9A103FD7E6FD5D5E020EEBBA1390E5151FF456669E4C14EA8E7F343769E7510AA68D624553ABFC6EF2F839AEB4D6D5E1FB57510D3D7A7F0EE969CCB11FB023EF279FAEAEC6CF377B524D206C5BF4E529C315E6F23D9AA4D8229F3AC1A0D77B26F3530C80EB77A55F45AB9FFB9FFA8B8EC28F733BC500BD684D49DA1FF31EDCD20C24231086BEC40E937C2AC1F2D4C9EF4D4274E9F15A6F961820699B40D0DBF4D11149E5696652A75D571C61E8ACB9EA96B5EE185ACFB344C9DE2EAF7F956F0569766EEA44AB42F0A2982F0957F5C70DEB7248F6EE23D322669E2FB3520CE9FC98BF79636F5156D9678BEF7B19F916A8ED1F7EF9D34FF853923CBA360B10086A64BE6BD6B52A90EC48D763C5E00A9BC0822836E594AAD9BF91D0945638B6C6A961DF953F69C4DD75799C7B73CA6864746EC3402BD341CB14EACB6343FBBD244BDFE1EC43BD6A5A0B1D3FE2D896A04FE8419DF95A691020BF61D214E4736EEAF25EC01304E6CC167D8EF969B8E2ED2BA6F5328EF83903C73ADD97CC6CE4BCA6DB63615932D3D0865EF837E335BF54AB3CADFD6EB4A7AB5FB441644AE5748CCE75157F669863CC89930393083D8BBAA83735DE31812E471B9858E267C7E646C3F204250F8D4280494ACB87D82052B0BE33002806912DBF10597CF46D78E8C64E648A0BC8A756D8F09D1927B73385E8E8E960CA2F3679ED81B0461706F4864043D5DF4E5CA59CEF9A484513C86E2FF44C496498EC88C0CC8BBFEC45C9A9E233730C4336A8D4DA876BE797B57635A6CC532DDC701A688AB712C8380CD169FEB3CBCC1004637BCC616B7D300400B6C55B0134FA2D6B96A8AEE0A54FF88895E9A16FFE4EBCD308C7E112E0FD81E64C08239BB95D52EF32266668E4F0F39EFD341B159DE7C8EE179A223D398BA70A07B774C04FF711EC50B94631BE472232731808291AEBFCF6894632B1C1AB119243043AC5D0C054B60883D2083564133FA82F3A46FB59F86334BE0C6E79E201DB85D35432BD1793ED3B28DA8F65C7970DCB9FC6EA0902E9B83C4C8AE86BEFE01D3D5DFBCAB946F017CB2CF63AAF8B65BB26C8D6A5A73C9DAEFF2FD482839916D9D60D3919607CB99A7434574F05FCF15F4F4F03293F3EF2F5C493CF867A4114F134043C5A5CC26F8875B6170C787FDE2247DE3AD7E80610F6CC09F58B66F6DAD4354795D49F994535B4424244F18FC65881F9DDA7900F7066B3CEE542575F13C9B0E3E236E0813F2D7580AAF8F9E564A3AED65DC17F0A6EAF79F4015ACC811F5D2145E51F72A1680957A97D36050028DA3D3FFE4FCFBC223CA4907BDCED64101577E2418821D77EFB9D868FC824D7BE13A28CF1EBA4418BDBBBAEADB54B3E162DEDA47FE29C993488D2B5E41B390BB4895A49717BABDFC798474E852CD8B573E960B44E85A2174FDA806F97A991BF9CFA8260D0EA441A032DD91A24C2AD52F3B8064226B22C73DCCAAD5DAAE55E5FD30FC31A43B022D997E14E71D3DE8A8E1F4027324E22E2A7616FEC4E0ACDEDDC12C04A56B65F0C00A95B8C1DE9B61F7C589D0D8F158E5C9C65439376E5E935CD7B149DC883FC602370D38676571CA764E6E5A2467EF5E775336BCEE1450E0F978BFA4A0B4CF5A72C259FDFB18E54425ED83E6DE7086C5A175729E38DDE3B46E751AF79BDAF0325EDD7CA791F4F760FA7279A7C17CACA8DC172E47362F90097EB36A8CF14DA378670639D239BCDA3A8BAF29B12803CB26891E4B0B24BC61066A490078046F000324E5186C39EFABA39C5EC4AA8E9BE23BBAD6D7ECAF24A5BC0EA0DCDCD90E17EB7B90AE56D12420786F07C8F2EF7944442AD36E2ABCD1E66E694D6B949EC2C5DBE99832271F3A70782CE889A55D93F78BD4F5FD19C580F456E684644DDE65A045D6D64BD99" - }, - { - "tcId": 45, - "deferred": false, - "seed": "E788F93DB12EB4DB91993C6636C009D06D503D5331125A2AD635354AF49ED3A5", - "pk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAAC29339D545F3F03DB0EFCC2AD356020BF1DB8178B123AB7222FF4041955E4E9338DE146932623EB6517BD73687A51A67623F79A36735AD64D63641D2AD2A040E8CE85DABF03D47DC9A3E98CB8098FB22F84C370D240AE0DDD46369D02ABA059E31DDFD5F56FCFB2CB7066B488C73AF6958DCDEFE66FE5CEB0FCBF298CF576C48F3A1DF542B5343EBC8F2E80CFE4A2D31DE6913EE5962A889DBB22067FB377606CC1AC663787C04BA8C2BBD0273D38D71D18BB7AB435544535A60271B3B2045636DEC30B0727C3C527F00DED0F08D372BC985F3C8FC12E1A46FCE031D8A2B5FC93EDADD15EE8431435A7C6797AA343D33B57AFDAFD870A643D927EA85C01CB43AD709B72F1909DF60499B75B0A29445CDBD1211EDA6666695052E4A80BA3A4B22C33B40BEB3CAB8100017807E5FE4EA49E3FE419EC2A86A39631638C0122728897254A58A4571E31B46583A8E37AEDC5C437E27728B1F14CB7493E5698959B6909FFE54A0293A754E34B335703DA5D99D6B146F4C7118A27AB8E1F9DDA161F03DCA0C6408DA273D5517683E5E1F7B3C2F29AEF73F75F5E60CCEB99AC5327F168A283E590E637D33D6535001492DA965AE977212056569F2456C8F9596DA43989D9162DB32D8B2B989000ED4B3B9F87D1251F5FC9EA71780740761711E74D7EFAB8D007B81E848CD2493117D3DCFC2BEDE8F85592D8265AC04B95282A06EC534E056ED8CBE73DBC07522E1E03E160227CA1AB5CB3F08D7BAA56D03F9B7C12DDC71B69EDE3F6181FE721A75DC0931C11F75D08754BB461F4A2C6CD584AB8419B7BFCB7EF2E39D8A4C1292AE9528FEF05C1F5D6C7F57AD50EF626B32EB916501E6FBB5F9A854095D28F8F6CCDC3C8B0D56D6BEABCF8578FA38FD947445C8A486A8AA17CC5012C64B21709EEDDB0C4D5955FCCC688A9838DEDBB005B7D73FB63480B296F23282D32C01601758632EF62045E9DB865BCBBD026F5E560A8B3A7784EF75B37F03D2A588B53B76DE01553F78477731FC4FA2759CA49D03004A722825118A931E9E0B360B2AD76293F52CB80A0311790CEB79EB2ADEB151052A4B8C220140BDB45699C12824D1416EBD2A1A18A16EA70035E69D2902873423AF69E7A7385F1245BF06D1683CE862441914D77DA427C210311EF8A703CC2BFFDC70FF7BBF310ED56EF30EC8D9125755AF03D2809557C89B32CCBBECB40110E0B786567D8531216EAB5CCB8C96DDCF03A3CD7E0E5D6104239D38B8DEA3131716238B2429CC6E02CE3DC8AF757D852AF7CE141E70A0BE92AE640ACC586FE960A440C4089A515A6979345D087C9A31B7F6594782EB57FACF3ABC51FE40D5CD0328CD90A4C840C058313B97E3C330BE1273C27F4F96BCFC066A3476F7D89B5B1609718A1CB91C3580CD215DD9EAA4A95564F42D6D6909C52759B030BFE18EB47A7B9FD72E1AC05C946C372B01CFA06682B48358F48E0D76F9DA3CDF60BDD53B9A09A641E12CD593B6593A62702A1FC7925447B1D7AADA5C8EA884E1D2A9510BC2337728EF44D66411E112B71B2C203C1F7746F918CF4F29033293BE45AD2B4A7518C3055778FBFBEF015E57777BE7A8F6AD535C0985E174AB4BD96CB78F322C2EADDBAB2CAA52C8989C1F3F03F230EEC98B52AC6A0A2DE8C7EB09D0E1B81834B686DD3D9AC1920EF6D817F429B3C314240487B0C527D4FE754A3E0D42D8167AF4B05283437A76D164731B51894F4C3879CE88645F389DCCF109BAE5ECE09193EA6C35DE193F6C68BE0827E38F4FE434A06E761B8B669B22896B9BF891F2F0A339FA0938CC231C37A223D44FC2E44EA78398F452D32BE8314802971ADCACFA737B2B90CF1B8FD3387D4D774C7BCA754BBE8A06C6425B24A0F08152FCBBD0044063BD419F6286B26CC3104416CD3D34FB06A7494D1FEC445589E56E2FD976E96912F72D377E4BBBFC482803694045EC116F4D5CE28AE3D453100F2F2ECB8057F47D41DA549FEDD18C27D79499CCC62A503F4B91E44EE4471D13B89A3630A4B622151EA3AFE335F19ED80FFF32267A32A2FEF8B49E60C9437B7405A35412292B74D3C38C825DA7D27EFC433167AD46AF0E341E8309CE6A95881DE1C8A67A9373E712E95B1EF948AFE624E66588060CA6A4197335E6BA537520DB6869B6BB114E718519BB72FF3F913074EF5FC9CF8C115104E514B22E37A871C48AED07FF93656FC99C3F1F1BEAF5EE12CD9D86A8FC6EAB7CAE5CDF5BE07699B0E801B9B83947C6D78254DA8E77B82330585EA02B42F87329A76CD09703DD0A24E01B1B63ED00926B4F4E9DF2277256A06EEFB77BB04DE09DD8B19237D40F141304BA7DE9F9EBACEBA0A86B0A73310E138E02F0FA284AD4F47B2F7A4F18F0A166E24025201F5449F1BCBEAB76A18832F27CC5650F9B3AF19C9FBB8EDE9C5561E43FA39503155C865BB9FA2D97FB64E8675CB8540E10480A85AD854AB01C94909C07A4A8DC2122ACFEE00450E5455B7BE692DB87A94CE0F367B3E6E40687E50D427116A9DE98B1FEB0AD0042FED0482CC695EE6ABAF5EBA5FB10DC46820643F4C40226197096714135716F74A10888B2CABBC27EF3D4C4A51E18EFF63771B43C5833B3C7577340D9E729CF730702F2AFF7BA8C0C3812028AA36A112686DAFCDE36D5132D4EE31203623224127DF3E69372C45D7B9E0370A3EFCB9577BE0952AF2E4C2856C0C156858A12AD1E6C54E51E4", - "sk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAACB6D6FB5A7F5B3C55D1B7B4D99FF4A4E464226FEDA9E8C986B4E5F41A37EDB84F87FBD62731259FE7266BF78C8C1622425EF797EFA30EC80432808B12AC45919A2C30DFA9968D2FA70B94C03CE2FE4CB15E52A9B0AFEC74FAA276A5A6C3913558165301232343767500140645258743061342542321447425681352486528374628548377702443573345023511515432272262636387653371116077564331128261673582164376865470573778011771888324265183248748526461364218768355482805103865333082167526282242560783314370341456383857383578161652306885528655175662755151047138555553146534343846644604080124474864542472815033627744112223432243010282717120330873340070542331872402377068660004410221333432814123760781816702355556354318770785856176381340622240247180674627437023487887142122356311528327715685414266201482028121764321760138877428245535571814667284614438305271345087160060677013335670831368663514625548365687250184502508737813417187476721462666327610566282504268562450465824881154630675748446771056374112326181781302812218455007821574286647628015822857841575474420251404400700360143301022535255431143253062813825455084682005502132778411085234725034175400186665763287222312538538408377111638782350433570758668635031106555035670557521681012082802587051366781137117633440736821514153673831736211187582851663268227614710433747764655121055850228627771006367547345372746630418234207825131867834621675040540865400710271240446255678587535712646677663862756162648235733574803251637433612543243468478708540037560522713432554677321560753633540782667588111844775721082267830084100184201347637783057758451023428802706114581247815517568146814871862414358208702618046381513554368158677108340188165884412034464317538338522232138722036733523471141710411066612126271743047838718830351623801480688837684510742872845350422860251052626017351858365885606700612771843631480036820157031348205867520520487765402767737510616772508510833486814641587451664151854305857511507587221816184780048357254801883803628823755313454274573606336453016746307562240318134330413451401315522363547183446584200387332666582654003115726104061523538637014810542557514371810386337213708847727654658851037453520630457682353101720774353267248527376013051436822206685057775611555457025261832548641805611352714453114181682076074007865877368448848734003148417023366531156644485347310062806883886101206088240403774741141888061787233830058632806617875630436082502522148484676107601474733117287574076826454801581084362107263126264670065123516671432478772264052013128365223266326033557830542056876118774244531751804203463628628086531048064586012217077568726234013258648566632205661202682265777756507302764142182572022616275154047553442287404117336235135884581014567433756542883011752430774456756024433362318460726861231472815238026480165521125855780525541506454870715826252784875538606765743657652331856072572662706465271157248031452273677063333062566472476428010820161672272014834502781064534320058730853758777214125800834724680368831480488687653825566260382261818011441503256800555554122412786818455524643670578000882636824433184045576563440255AFA30ABB273C678163F2E011A3AC11D88762AE6242B03E2CFBD09C41F274AFED4E7B529A15CD5D36CECB76A7296FD7EBD5B56C185AEC70357C401FEAE5F89AF063AC7333ECF31BE378348FE5A5022A54F3A202BC48676BB6EA1B284E85D76EA61CF1C09A97584756145D383D3495A2EF5718D2A4DEFC2C8F46AF896B41D399BD324987CFEB50CEFE71170D668EBD607969325C3C342411B647BE4CD2D77653EE3F5F9C0685BE270ED0299EF45E119CE37FAF027EA64B0D54603C59566CA9708087A67B2D43CD438848C4A3A0485FE9F9DB87522F3E552A2C91A18BFE6685D335D48FC9A633301C126D4098310B4B24E1B142377FDFF5B9E55404FE682E8743A36BDE3AE2DF8698E8BA14EA9CB895BE64D9AA061E2ADF95692AE3C28E90A30F65662A33DDDBA2598CF925C5EB9A76D7388BB43108FAA4208565D77EC00ACDF271FF2A3D017CEC9DC5893A655EB6E438714AA9B05AEE119FBF4E18147C2D21357BB68686165ED35550862CDA47A9B374B7F7AA5913A4B502DD3113A85B5A125CED5E88F384A4862A9BFCC42B74F52DD34871C27C03C90F288A43BE6AB6EDB01CAA1E99B311330950E28893D355978FDE12BCC2261CCA37078D4C74ABB70E46F82D5062BCCC4DA6176183B4DCCEBB601D2C8BE0953754652CCE06E599DDC35C3C717BA398882922333D52F70D9021C57EFFAAFC163474707749105460B9061320CF20E7E53686B306C2963FB84DEA297D2B4C4192F1497F369D52460705F25A1C9D1CF428A59020261B100A444FD057F2CA21A5401B178F3795C6D95260673EEC3216A93C128E7B50A6E7C70D2FDAB027D4E192FE36BC45D738CF0A08BA7922FABB19EC4A755C8B22B57C66215C6CCAE9421E93719EDF47929E4999538241D144C68947B5D9CE9D382F797D0C993760F0E42DA8051E8C1709DCD8BCA4534EBAD89C67187E704E22636893E910D10C125A873224BFA48ABA7D753DB4677F2AB120BFA18F8F0493A396128F6426D2A4265FF5B14D0A287834CF4581F6B978C66F306688BA4FCF67FCBA53FF05A6E98F7E288DDCA4A1DFC43A1492F3587D450099693ECD43BAA35DD7AA59513E515C1EAD179C6004D9FBAF3787EED000374BDFF6B72789ED74191B821B595DFAA5D359DA953E26E9B572A040E4CE2172C4B73AD0FD3CC21F2B099B7DC203472BFD8DFD40C8AD841D81A1AE0A7677A666CA8BE53681152E682A18EB6C804F4605630A1429A58C0293B880F455C4342EED532E240D27861D084C14D32469CBC8C62F997C24C8E43D675673C8713CE03F460DE306DD194AF165E021F049541793C97343B1716CA0BF9B5AE4D330985B3EAA44C60F706326208C8BFC2889351656DE62F647AD6B40D6ADDEB7345BFBDCCC14099F34A77D09DBDFD65E2D9CB09F24EF14CAB57AFFA9C5FE48C483F63212821CD2C8C9FA1046594646881D40A66656AD9E0534E3EBDAEBE1DC3FE5A6F96BF5FADA52A7F730411635B3F696448A96EE1C5ED717D13978D6EE381065AA9D3C8A2E3508BA76001427ADEB8E9C706E030AE2C41E64AAB319C767546AFC2DDB7E1E5AC0F51EF6D235C6FCF2401F9DE246C80261E2469F26B8F77973F22460398DACA28FB963AD5FC4715999DA55FB88864E72BEE8415B441521930A00C08577B609CC1240723E565B06541522075446BDFDFA6E21A45CCA5297032F0DB06024B59F347BA50F2787112131ACC9A67F41E81A8F4562BBBDE74381F3142F43759600BA69887F5E80E0488BB1DE61E1169088DDBB188D2464722469C9D9339019FDF3D1421390A156B33F73E23CF9C2E1E8139CDC12172433D7E5B62AB55A88E34BE956CC62AC6E469C4DADDC4A3BEFA5B3D7EF2B061C541A6C8ECCF2137CFD0EF24D0052646492014BF6A604BD3B8E3491497EBC008C68033A48EB54673DD28ABF05137C408EC9051853BCDC392F6AEC82F8EC5CF285B7F8EB7EDA1DD96EDF0B264880232EF5F659EABB78ED48DE3BF7FB439D3B1BC92DCDC1F53EDE8957C8FB244483FEF72CA1F18F458CC5F1B8A15DA992AE5E69C364B59D69E2BDF82B25DD56AF4E34546DD732882E83530952AA7ADD397BB69FB4A5091DE23E60EE3F2FABD5D81370AD1A16DCE0D4660A5488925BBDE4E7F3C989026D8788659EAA0CEAAA8EC16261F255DF7298906D9418B92DBCB4D1471A4BC7C6842321794E3CCF1DD5EB2E3D13A47E5489223BC1A9630AE2B881A160650CBC38E7198494A58FF65F2099B81B44251DEB1D4DA99EC3658366FDCF918919741A4C2A0A91844F4B97F3C135392A9E0D41AE6C189D0D93D4E0F6826D142D2160B9CFE60B7EEB0AA148BBBAA4DA7669C72990F8BEAFBC6ABA9AB11D3083E2C337D3BA6778BF7009F444C122AEF14F6C8C1D800619D22045C88E80FE1E80C505FEBB6670A79802E85E96CBC73E15982DA42BF530FA5500DD321D8BF5EEA7E02B578A16C099ECFB47ACDCBA485436FF5D13009F51E53BE19F457187CE214C7E4D1C4BA0AC68CB54D3471F5B1CA714B5ED52BAA5EF9FE75E9758D1C92BE75B821692BEB24B8025D2BCC2D54F46CE8F0EF4BD81D35BBEE670592184F63C6D87E458F442718C7D5E85BE6F0C1EB0D9EA0238A33040D4D8CB0CB0DEA36931D1D932840893743AA426DF8B9222E80338C15883DF42DE0AA6B837A9BB7ED65F570ECD05DDE4294A4AD23D39588B218ACF34419F3FA581E22B4879093E4B35DD2ED116690A96AF422F10C511C49393FA25B61FAD39A14AA33564EACC82C8F65A5D0227657118527D66F942CBECE1C776E252644B8A97E5A564038E3670C31F3BFE93366BCEB27648A904152FC907E6BE8B6A91103CD55C8000BEBB60545276D595CC738B4A2B1F9E30693FE9D6796DCEE7709FD2458A38856E579347C560F8DE440F2888F38FEE3C905BE51303807F2957932F96A3ADE5CA77E5616A44B510B9686500CD8E97950AFA67680E236A0B5258A13DBF0E096ECD086C74FB5476E2EC7BA929DEFE11DC8F4BFA2DBF21158EF72ABCF0675B29709AB9FCBD2755633BD274AA3D5426EEF9B1F712308E7CAD98CCF4704F1D49CF5E189FFE80B4E17F950A1A4D14FB6CB6B0C0D910BD527F35498A1379C9D034A15AE852BD20395D4302358B3E09ED64724432ACE05DF83C3573D71BC5C168C4CE160ED2B7A79684AE20662651F988AADAE591159A1400FF9B91E13279764CE8C14F293A0346FBD8EC833BB9D6A4DA4260DC221401A4AF80CD8B71420551BA188AD8DE6D9723F49433A7AFB855747530246A4D1128B28A85A6F16B7584D4AED3809F9A2BC0064B5237823FCD1EDDC92C5F24A168AD3CECDA772D8A9740FFA20FF91612B1E13F905B2A81EC4A2C69D088DF89F2F20E59523667109F3664056BDA4A5D70718302E509DA989106B1AD7370C4A9527AA79D2BF8226ED487FB44A5B872DE95581E491B241667C01C4AF5B639BA1B496A2191A23DE453C15F9EEE2EBFC4FCC3D6098E31C9C33BF8908D4A21CBD14302E0F0AEA458DF776D75E929487A623A2FEC1" - }, - { - "tcId": 46, - "deferred": false, - "seed": "03D86B249CF84472E3B78B12110E2C09C7428FAB65D362760D0800914696D411", - "pk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63AD301F719FE8E5784BBC4F7952B43182748481EF5F9AC848D277C819E86827DE234CE3D1D90CBCBEF2725971CF3A559CA903896566ED66E4B452A1080B7E825179882563CD73AAB0FE07452DCCAFC27FBDE1A94D750E27C2A67F1B47397C50BF0B53E1C2CDC2DC13B333E9BE0399F271287E4C9BA16FA122C418B7AC8DBD5769CE792A66475ACB94CC55D70BD7CD91A62FAC1E59139EE46072A7F76766AE4A1AC3C52A0C689ECC001849F5F6CE436B29FB5552FA5F3BDBD662A85EF86228EFF2EE4C9B0CC0FE78F8DA5A70231D6594430A70C878DF82AF33F1EC8C979FCC8777E00E77C457300461CB93E9D33ACA87102F0B217D36556D9BA2C2A23A736628357831128B5BA6B649109972B42B15C563B51CADEDE4CF3D9FDE08B456F7A9F2EF28F3A7F18D5F3CF4BBB6BDCCC98F801391D78FF0511A09DC07CCA1A81E63B08C0EB738E1F942387946D3B3BC7A0F658AE2FF83310988BFD4ADEE4129C68DD665D12211211C2D9582F80AC92CE3F943B61C6C45B935D38B27D3C1C2ED6DDA42FE43D5DF6E5F6BBBDA654C35DC259114D288C9359FD41AE8C2233AF33D991BD283310BFC261CA0C45288DACF1319A70E93A221ECA835A6CB1FEA3EF0CD1837C0C20C51C3C8A6E81A2FA638355EE80B61354F50A061EF5DC9E3F3D41B37BB08CD9BDBFE42A0BB909BC24EDC022CA57FDFA2AC70ABBFA851E2A2FC73E72E06DBD0A73CCAA91F399C72879DFB993F17408C9D8E5B60A6E74C61DDE19893512E63DB8CB69AF370A8D0A91EB39334900EBAA892BC6DAE48D97073553B4A479475EC1AFA797345C6743BD395D95A16B2E8D494BFB306B83D67222B09CA917334406EE4A021D318F364405D74AC23859899B6C758762369A63EA6EC3C9236FC91578C6601ED2ED93F0873026E792C010E187C54FA1CFC58BF88939D295539566DC50600B4182D5013C262889AA964FD15ECC00DCFDF57B2F7513A623A405E31811481937FA6D4DEADD7402CF84D050E4FEA37F5B86DFAE2370B1BFC8B9E6DFAB3859A6AD8712558E782E5D5C41206A007D19D20071E925EE25E8F10A9F04B09F03A4E1AA017A7779CB13AC5D67AD0E45F32C216F60897DE2B77B2741920EA73DA07ADA1CB1E3AB5C7FF0841C8B4D3B369DBCD7E5E705DB112D0BBAA7549ABA02AD762460BF2A80D39918B99B5A0D8CF7BEC174C94490C3FA100C19595786AB729C05E0E02538983A145E4DE6CC10936CDF2ADF465401A15492A9C0834D5A61F41099BDD7E92E27CAE2377D44F61E52C5FCC46F58981A1FEBA332B1F19118362EF2D12D12CE80BF017A1AE2753C20A9AE0E8BF4ECC5568D741BC64C3F783CD1397400DDB3DA525A3338F1A725EA5759A4A2B0B4D3B0895EE07D534154FA16D77A3AA3B205A8CF06274957C4190D47FB9108EBDE24ED0CD544086C3ECABCEC0DEBFBC368C0AB67D065ECEE9CD671784DCB4DD769A944E44D9B951AB3F4A890C215C1B9C9B962687A576A0BB15357CB5F250EDBAF7AD5EDC3FCDA793425AD3516AAB5AD9A01F5EB036C1B6DF02EF51516BBA767E1071178CE25D8591BCB5276D59233F91EDEF0E217F39AEEB605F6422EA5D0F47CA2034C4AD449C87DB3C42A5F2DEE9F111455DDD988A7EB4C285711AF467CF8BE4832DEEC585F2CDF7F68DCB3CD25339451283E618A6A3FD8095DB07B8F5B5DF79E8055CC8EC3C2B55E0B23E18CAA12A991086C7C6B87A0713B4268A72A9C3A2DB6B07514C6B7EB0449F20B096F88A754638E55E9ABAD72343C92DCA03FD2C4DF16BB2CBB1963C8B9F48704CAEAA22359468BA67D58FF29E38D783999218888650D6B414A41417D239E6FDFF8E382F107BF4FEB81744E074A51531C38B6DACEE427547E17BFD2C2E4F4596071CAAB4ECB31CE7769F5EDBA651F6CC4380A8A1711E3BB12A3D8A061A11F669246713D29442F0AD39629722ABC838CCB51BF80E9C440C2E2EC88D93076253F56C61816FB725739B4E44427FA7ECBB415B6E5675B6AAF736D592C28308CE432D117F388536C83F90CA8FB66F1DD543AFD147289DA0C8DBA45FBEC3499DB3EE000B26B49B0FEEE4044F231D5AA9C71405FBD754BB43659E3B59980FFAA3E0D78B8E067CDA206D7809D76650E4672EF4DB8C74E6244E82EFA9AC02502E3734FC188F434D3ACD65CB7F9B988B1D69B1FFFB69D88EF2EB1F2B70A2D165B0EC78CAE92447EE5376B0AC4363B98689076123F2DE26DE1928ED2C4182C3180056694CD6C8949A85FF3B1E24EF12614151EFC76D8652F04017ACE8E91D57D059D826CFFB93F3EE6A0405D9A4CDA1BAC97D906A14537F3F4E62DF70739B94442884C0C0694B438083B5009646BFD58B73FDEA8E9C97B18ACBC3693C07CB6C750353F8E8B704B2D01346619ADAC4A9B05FA4A478C7B8F2F6FCDCD6F9766E059E9545BC566E2ACF6961B29BA91BE7C425B1EFCCFD2F8ABB9E3B9FEFBA2A4371F8F9BB20448E9F2BDC6B5B0DD4CBBF04B30A6F819FA271635FA5CCB6F5FC1C3A70E40E31E2FA23A640AAC6B4C56BC07B948710E66284E483A2AC418313126D8E79CE9D31A2B657BC5E5D7260019E101F04CCD200B29DFEC7CF888CCE69C11E70115E36E62D94BFEBF99C2B37427AE66E576A9A7D66CE0BACDAB0836343FFE0C5AD719E503A07952FAA8A08BA3380AAD12C1B16918719B8035109B932C17129B881015F976CB27854279888BB5A7", - "sk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63A8B9205612461E15A894899F582B63CE137E1A2F6449844C6E1AB07FFA975AF9257EEF1899B521DC105390DBE918F8858644D8B4BE502F657606AB402E005A1E646FAB4CCE2A201FACA5D3F8073585D77E8DAEEBBF03327BE684DA62F446FB8BF11333781374634823864042432083342054315306250442250826183726662656836707207736660161824455431866318670240311553240312347115152581385651705245784026155414134588730150508327407213452331305655400268516817024258565182057835868833071380163376245221257278005855363453284531033783707576026861505718742866514771740874438446244726810142022470677257603785402032470565871511738035371647503025642426405205382454702086852403683351111368612567430634780474174484634822170721682005744765345483340267364815826771864626134365402244150866005531353283300630053128674405643208648637486012828554178631542254248251856301082170407214768471150867840383624825684364366438030362238282104043061255215621210686101367563532532562306760522550345502415700162084747110886865313326700027831108836087336210727177214467302222658180777371060148146602645888401352857182336671315855802221313438166008560261203061705863553051286285235608241467031187205708420581371001823637854571517586144832155022232600160485088873722360483602837746658646860177715055875558150641212362263864175584814328466146518265263274857302328063567642227558860841183338043285138556553222668166416277534867861727330746664576480024537803586435081208274002737517430415402722305805887888006778232512782523462685012826525455106007263311385032752711256051815357843176702263215670485563168666680358667680544184345338385515177482431554648487165220470888673712742761144130066376423527701312468340042581563652578411642814866606020050483618642353848611076208376042661087664224038705704184504657206570044150271443252440031002705772661801304248550017226385876682044215363807531016374814725644264133280774048845453460315230256666151016313714182805604006003275203431342570007274782878487383272346602306120123182336428852143161760614620647282877803338426417217267534810317714120637715587447884238722162264175700647268123018833033454700328881216065721525378787614880383841413262040530202264523768288244748401630013064582441506825281343376027562685201588256074212735338587526201851804705483838426483651360202665338765886456254245744670566111870525780254234553032810841267361136718675661103883076155035127073645528165635100567720655217755421301357108034726505744587147310040141010805646522087147007255714057158741217277422625282364731745870783664616160434555775443743502840544863386473378018153247320635606807438754156737641371466713704031817403002217663388070881274501471075834867805472376776326800354057684821603313825840027201144475741126230724105836354806407505613633022136647710632508145086447881758420157178754808160145254472146725788070481561266847405464138405113446032102601304210208730306401431145205104734535487474140772264560342348655301266821517162211403658702262776371234537788132058858823145524452147323040308527184140733703820531813674657553835474053654050304073176263545064447138716350737634B643A171F66CDF58DDC280697C53B4E42A4BEAA9754E6BE2BA3A38995D758B1139FD3553664E16C952BAF99035D4E2D089E48D5AD9CC29E4D2B41B6A413D7807F5321F52B06C51480F368B2EDA86074AEB9E30427BE5CF548FE5042AA154DD0DEE531E37AAF546BDBAED6F7BF1226FD5395449897E9935770991B81D23C884DFB0834B1493781662514C3F1D666185ED811847CF1C0042EAA330F42139C94928BCFD81914E52F29BF32E9EF9276B381D6D17FB6E487CF8CAFC1FA8988394161595DF71D66D504B4AA20B17EC08848D59BC328EDDD2CE0B618790CBC344AE2721DA47092A438AB33B41A490475323593968858B61EF2C0E9FEA7D67243AE69EA6561ED8F586C3EF625B0E560A7F908AC491F6F76D68E73DB4718346F5A3DCE4C3BDEC93C1CE41C1A86DE45AFDF43E73B5A3226367DB267C39D75D80F831033C0932E537A8A8B27B1C82190990B9A949AF6A2B9CF6595D35862BE8BFD084C117494B56CB00C671AA902A6A7179577C0B9C4D615F7E1E2058820A12B131BCB96BE297F14407FCC7F99AEA65F1E4F2557F6B946A55754B594C1DE5758D76B541B568FDAC78F3C6ABC68EDFFF0BE8CCD2DF86E536F1ECFEFF0160459EE05F55BE0BF6CCCEF37DF0AA22A2C01A28A0FBAFC4ABC22A07A2B60907C6523E891F18C264EB0A0589762622F664B7B6B65D9ADA3DE8B1D3A417F88B9A821CE7D5D321FA2A64D4B2017CBA63FD177D5A866D537BA28E1D0A22DA42B471A5D4CA50C9CCF42494FA002A35D4B9B3931DB7B4D30D1C6FAF0FDF7F3980A20D1D5861207FE143222415FDB586A410FED5B40DDD57B5208B804261880E25DE41A4880A19F7F6D49589CE530961FE2E28827621F561515133DC1FB9E2BB61DD7183EF2CBE906E292C0C7D61E04A0D61623C897258F4BBD645B30D2DB836C75481AA3313C12660F8DC1ACC7EE159D6799B587C85992BBBD1A7794068D7980BE486426156A19B9096EA4ABF36E4E8B524D474CA60AE27B9DFF771C64F0AB2844372E6DAA50DF760E5A56F6A0BDFDAF7224B48692CFC811ACE083F19CECFBB9A72C309CAB467DF8B79D2F34860C7C056E8C55514A53975D407B4000119EEF0D0C8EB05524EF006886764580F697C849B8B2D2E4E1DB15992EE072BF4B5252AA1542ED4CC9E714C0EE6A447B838D233355228BF4E427790D8A46132C50D3E340018A9A3999CE187777DB336FAED69D7259AF20E104E9D13F4F89AFE3D60E449C8075001365EA6A5B150706B94828106776831D8335078F1D590F6EABFE3A01C351DA0C8AABF324AEC14BFB0729AF86EEB4C646D293C3F5F3520554540451573A93BB05BB3D70771240652751356A52429A866AEC7396BBA9D71AA078221902DC1ABFF960DA9583C58D4806D65D509BE5743C9D42AC7C8F7611226368A49D60F8E24DE73FC614EEF55D705DBFEC254B6579E207322426687E3B1C5C0A05A869CAFDDE8C4F06E799010DB17FDE4815008E9DDBF7DD9A3C63ED11866DCC739C6C97B2EC58B94900657F3D881BB9761D8F64469C68A5791311ECF13AC0D22877D4D2E6629E5C4D4640DDC30CE904C5FACA5356C72FAC8ABFC421E18642A1A7CEA716D9A4A93E115D749E16C79F29CF637A5A6A17577DA4FA5184FE7AF22A88203B77818B24FB77715DC2B44A59FC2B4EBB58289BC308F8C0B8718C8E40A87A6E6B5133CCFD2D846AC98E02EF3B210FD2E6E1CE8306BCCCB4BD9C345F4BE59E931B8A30E3F9F82549C0084F72CB13D6C645FBE61C81319BF98474B386B7799D561E53771AED22AE04FA425D3F61027FD710D897CC4E6894973146A6FB2E485EA3C127EC6794554B4282F399DE9897E1C70F2886D4A3F487220B00E85572A4E291B99691AEF60E10D4DC1515D3259F8E74144087D4C5EC5B0CCA2812C27E3DF2746C1A015644FC5B21008227B29328109922DC95128E9B646ECB9468374594C748DE019C492BB0B6444743ABD20A08EFAF84892B578FCD389DFE25F0F6BC20AA8993759AC87A0920D7A43B34CC43CD7FCA8A2CE25BC8FA3D246869E3D965D98CEF0F3FC39A5A62239D803B7E311BCFCB9D9C6C484516AC3E65038DAA2806D4D0D4073EA623A60F7F68B66C97511C1E15AD5F72ADBAB64F772C4A3F4E161E0BE0386D7EFC60D497F664400DF69924028764A92A26959F3FCAA30923D3F3D219C91F0831A1F6F02B24931D57D5CA427D8E2C02D4E4E6D4EA3EFEC061CFC72941DEDDCF09FEE339E3A208E286D9E0B8E4F9CB900D9F36C013ADC673DB1F69D6CE170197FBE60EE4E28E9DC66BD1423E80B78A10BD0119BD59C1C2D4EEE1CDBF028BD9D0C459CA885D83ED2BA145CF9CA5917F6F276B4DD4C9DD4E1A0D4545D2C66492B75A42DA066BE5D5B40A28F023F49AC263A45FB430DDE7C55CB78882BD689DE65C36AF223925EB14F26CFFB6CD082CF6AEDA6371DE32C5276D3070F89EC7342E94ADA62DFC11BA4A0B05FB6537F36BBB02630643332F121C93089F26DE6EAA4886E4C1BBE25E2D0660A1DB2582A6F586C1EF875A406143194E2783BA9BCBA4BE28E643887D14A13652CB8ECDBE9E7DA4A73D05C926486AC2518DEC9C82409F20679EF33E48AA0A44BA2FA9FA2B26A8922D5EB846C96B32392C46AB9F7930ED7A0B0D121FF874DDDC303DFC57D278760180B9692579BBE0A079B8AD5A41FAFEF9A8DB95BEC8C5BB0512479D2E810096C729AEE88741F85A308ABA9D5D1AEE42564C1EA76D41BA78AC1B05D5C604D3860EF722D0EBD73FF6DC894F54FDB8E4205BCFD05D199544BFE6AC3136DB83FE2794C5376BDFB6EB1C886A03CB2939F31761B0EF1ED877FF28E5C9F2FBCF7D1DC24079B4790825410F3319C76425CB9E8C385DCC2917AB8A9A743B8BCAED7DCA410563565B553A4D89EC927DCA4A4B8C1085EEEC5C53F5D43F99C1737587276012E5DE24C8C012600907737C487C472117BD48F726CA8D4E876AE35DE494E63D0D844C53CEE75AF13111251E338D057D5A88DC3132126F597DEEC69C149220CACB942B07746200CC72758412FAF7A22C0F73389615BD5FB87590C4F42BB451E48A21BBAAAEB12B427748F4FB02382D105FA962B180D1901307B1F03DB38C8A0AD97A8CF615C0A9C18FA3A6C10E1B7E0A83777A9BA648D25B0051BE791A05BD7CCF713942F17EEE24042B0FF47AAAEC674D0C9876BCD3AC11580DB1245691DBD8DFE791AD40A1860F485933C477ADAFC3EDD030624DB77DA7E01E7F81417E394B3629C687A464DEECB42C1ABE5EF245A717FDA612A85663CD9684A58B3124CEBD1CC5CBA3A2A8A48B168FAC6760375B8A62BA4CD7BB4F177CEC05ADFC9CE35908D78DEBE63E3BAF803F2A0079528BB4B2F782128C0AD576092140C94A980045F998D89350278BB6867806228F8B0A8617A6CAAF54ED3C70337963B986C68EEBDE477790BD316E572D823D2032D065891EF8560BACD14F910D3279501F97342A6120EC2FD8A4F130DF18C0880304697662F66877BD07AD2E79ACB4CFE4F039" - }, - { - "tcId": 47, - "deferred": false, - "seed": "B9446E8F78C8B7B2ACD335B10F0B8FE1B34007A1D827EB5517710569E060AFC7", - "pk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F203EAEFC937D6D289CDDFBE4D5B104ABAE3BD76989357408C69922BF39217134DF5C806D34574A1AB61ACC99A82F51852F173E0BD61E50552CBF5A8AACF06588470F649ADC715E3C7CBC646E168B4BF0468043679AA7363144CD6F751578BE3EE5F74C96107189ED1759929DC3107C1CA5F14FD14F3CB31503FF08C8E79875FD529AE80A1421C0643DEFAA35D6889FA5B6E018ECAC896447BA6F5095929B4A5CB636B4C9E0875D5B02DE68CE6DD54B24156952E081ADF436F064795C4D099A9C17F5CEFE19B8EE8406F1BF40AEC03A15D243F870E2FA2B0AA54EDFF17D2189D240725354C2A680F3E3F7F937D2190A2076B6437F5DD6983699F2F87CFE04AEEBB22A88132611FE673EAE978F01BBE3959AA3F4E9891EE9CF6D6031436C8CAF9FAAAC52E037BB69BA454C6D1A7F1472D85C66F978A2784C79E792D1B8B0155D85A7FE1F9B049F012690A2362A82F4CD9E913DCB0EBD67D68595B0D17D085AF96BC64F84E069C9CB9572A7864CA1DCAD25AE60F37889D416A8867D4DEBC7D1AF997AD04EEEAB9BEEB027ADED41D0ED3B46FDDA94584C0F787802B7A9192D8AB1547A15BBDA48E7EC65AF00152E4A385F755D6C156B4A5443A145F84268A55437EDE5A732CD7C3B2A6A728EC698E975758A1B65906307991AD8CEDCAF9ECA859DE2A7635EFAE365647B4AED61B28C24BF4662F7FEA3F14B8E373E4F3E4ED51FEDD1D39A2B70460BE3E7D213FC51357C80E292B9649AAF7B464332FAB8595BC1F87BAF2056574AC9C73168E13DB1FBFBF29820EFB08E5CC9465BF31431A96C91364CDEF8A7A53AC440FC40BD990F327DB60E980499B7314CF5A63D95FE20BAF80D001BE16ADE597188CAB8CD217877521E9815F274D8FEDFBF8AE11D36BC42B8F1D2F1C7F4397FF4087B73E00AAF4E9FDA6F9499AA469220B153DAB01512ABCC6F5DAC0C54356ED2ED0A1A260F3F8BA1F67D047CCD333A26C5137BA76DF6A45BDD731366A04BCA2F80F7B011BAEF941E91835EE218AF34357F47A48C6D5B47DCC282BC53B1465D5775FAF773807634A647701BDAF3455E1536FE96CEC471A090D5FA7B737AFB670CB0E2CDB5EFDF5757CB52669AE1907D991A187E87F19DD5F2751CAE3205FDF832B312FB44225B7D9285328011B5E081CD0261E255B4C74A1AA551305CEC1703CFC5CA1E55A3D1E4002410A5935DEA3B3F33EA0B9E17793CE6D171E70D954634DDC50D6B06A499F25AC5959F282E12D8B9C28A00C58371A56A4500B2C507F57BFE85FDE137F82929FB9B813B205F72FEAF23B9457B746E8C70EBA61C80772FA8DCC94AFC0AEB59426043CBFDD6CF69F97DA634D884BEEEAD96F24963E9DCCC71FEAD90938956140AE0C486AD185FED8266C515037A1FDCFA2E211FE52E0E45436215F123D8137DE4A679B19922C9A6C1860BB7430D0950BEEB635C0937EDFC5966D1AEB418C2E52AC41D134B43CB9A4A3305C4C669892F65978006FB56EE2F8A7566F2841BA1FECCBABDC49BB92BA7E06842F6C7B24427923802EABDF84CAF5B3E77DA7F1207F8B0497D17EC1B5E3527AF0539C64277918EAF8FBA7457833CA80AE2A8E001CA9BF08DBDBDC19CDF82F4230B494B07594B8AB32710E794605F93ADB877FCBA8B4BD3A89D907A92F1FA309727754A42EE1DA7EBACFCE46D07181D4B7F7D20028646AB680CF108BFC3A43834BF955483866759C7A34105B4A34F92DF2190BE8E5272D0DAF80E8C5DFE361B66D75A7D8783DB9BDB92DEAB2BC703D13950EC2ACFA686F97AC0E04B1E69E5DF49E54AAFE615A493E96BFBCB008385116FEED54A2B984930886A514521EFECE22F449EBD0F18BFED1970A86E7F4D96EAFD11F135A9BD8320A12AEF389BBA46B0DEFC101C3A90A99F00E6D5CB28298BC35DDB62A1629374353EAA79830BA5B051DBA82FEB251444B3044B432E675792DCC8E464BC40958C2BAB862208486647AA879B8AD7A71F48D63C3BD0B38BAD9EDFFFD1A28FC3221F67B26A2A36A40BDEB3D01E0F4AD90B26C5CC9AD0D80E24D5D354D5AACAFAE1000AD21E4F60D994891621B19214F92657006E01EB4B28B94F804A7BAD9A120226CC03CD634731CCD5D7610218FF40735F7964C6E2E4C119A590786E693820DD75F6BDD58CD6A1B8857645C3C23B52C96694462832ECBFD27FFEEEC6284C4C27B1FD95B7252857BFAAF2E5C34F51A4055DA5C9A2C8E941FDEAFABF87074713DDFD9443AAB31270CEE2801588E7B89F3329F3B9E9F398738FB0EB0F50E337BE42000B5876E84F623C258C4BAD7D1E536528E8BEF4AC6F6869AE9738AD76BCF8FDDDBEE023A5A836020DE542CD56877DC97CD33586A637FC6C1406ED18333A32995E14D79DEFF1E258B7FBE76461680C9F5D7CD79165944EA50C29087F46AC6392C1CB8C3FF9DA336D4787E81C3662C384A603EC6BDE0089A5D48136D08DFAC460ACAA0BFB0770D85ED2F859CF3D2F1E4C82D5C5E8D6F9BD5F1538E21FA15ED28407AECD7E78633734118CC4C5EEEC2E2D01FE75E1B7D9BD0D149B13B57FF5246655ED2259544BEC5D06639BF6180BB8DAADCB49ECF1C0732D530D0817337C4FDEEC4DBB99F0DF41ACCFA48ECA5C5B8E48CEC321C8A1187B3E2018211CAFA625209296D77F6EF6F14DA8388FEB69C11A912619F514DD8BCD5CF0AC64E7FF3C97FDF06B6620D18A0F95FFFF5DA533BFB61DED91BE2DF2B", - "sk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F24A60ECA34FC68FC31F37093DD96AA4B9F3D5830C6F16E5218B03461992816F1E6C46ED2183EC938F9BACE6D938995AB55B79D7718E0A65ED1CE086775CC7EC0B9D8ED16CA18D454DFD93287074F1753CF1A106D43832069924E934B69A056D6D176426004013076575326430863137681154388472321482327058660264144318587126616777245665846085207077377620134715340864342265500652186150467601565650873175644064416834227733720173774587668873453654245237887584735816803431317252007518455862453438544280565558788488641766433715102273116838853016286781356764553350815576130623142120288320447330858634146116010314662770062074375774867186530144058337264066324211032656066333521814241564325222500443323140011323440703778825861335111403817102184704327185386633608142215442067221665320752283741503126550045540138523388552553756710758782221066048054785368634370510608715285855830261461583231884206487168348502251624181358250452363431358088283280220684850274887682136732878487628835676427436605335002250861670280661746364663333746081501851137351028871688754020075563164387882072231828620163852404354634175131783368268806428070410450722647813676878073455762434565702154475408122163541077486410856021580604143745384424577785383320062585216722084220844048307024134432474888345716725321201005120225816884018256740445853733442120313688418144003171551700522688612013631552624366072347843226703122460417203012430812021833811420720661868774436374256462732481621436813002757624755522350808162680011825038722214273025248005052317717234810061288158327831563165021287226153061841412807135642600053623232871172234266585054154037728672161210616458710643372418828532614851034330455673523587742236477452251870078026584337870552270745526756623860278447626062284834315340427146171232766872568061730756050724247027148476041120506552842756071205358731326167423273744026237525138835086634357501537604145556133481414804060470432652463216123837200443812665470481367442016456162841127017802443686606775850025538847122687372785518286573566563606242666874533554403325385363656115174748320261462840552772623674410481265030724763256241631486648346756261368748180167401048541280737780881841151540185080052416176233736633170701131856087368601514425225057047273141367358256783768616620301431740016335013544305727222457250283187257250743134642552508353067725664027065305156731547334833675272822335860257083672157731427677103643242465216121111244014577786563871520155270585467046042052457113044834347701052060663740758787647888206363867766446811488063441365214110100556377588423480631304107844013871142521788152386654530207028734623080264311677371668465072078164640706288825415386285222822305247408773601071322560410302142821481811133677651772473201332288815205035613301832085104746827523346476715450002575314316042733172642714440446820038280042757635636678707806871714311068015364432431546245667366443671858840683530203154356038363103684425222575835848370481228786854711047404557132636566284507601070068815183715138065502835833765443038333301854266005471082640210720634670243202468375243858240881712734844607240223EE143A505C81AE49370E4B4215ECC3A31B3D08AB2504AAAD76952654536312F6B2298A20A48791A9236B32BB68004CE49F169A4A91C189FA677AD10A25604A4BCAA38BAA0E572421A79CB1F82E3543A285C5BC6BF25EAB82287027C386D543242119C74576C1126E284DCF1E25717306223CD0AA9F6AD025842709572D1A1A2D656AE4388B6F3F491A0EA231798A70A3A0FE3A7F0C97E74251068D009CD0088B8B9026EC8FB19F181F0838BC4FB5C7196127D97D91108D5C7AE2893C85C32023175DC204D0C000261B382FA078DBB3F0745902A445FD5A32A7CD12AD7AB014F5DF7B9D504FDA8EB8A00DFE5DD832348FDF7A6298AF21A8D9730DDE60964EC8FA10B3140D409278C238A78DEBEAC947E740547530AF8A98C24E6A2474F1BEE79E762D710CE68ADF282FC8110FC099041B5A0CFC307176FB9FA214C3D42A7F2BBBBB27FEDE0EB37C71D84811DC34C83ACE1A41D078B936205CF5B726230109A099B75ABF9152824E04C352A9085BED558C7C894D886DAFB46C3BBCFC2A74AB8B4407E514767D90692F94862B2F7100FE76CB36F52C3BB2C7920A76F642799C213B80A6561A6980D611D2887A0531CBB412DEA4BE23D41F515BB8AE38C77D93BD603F9AE2E55B5F0DC6F4B2E217C98F6F2F03F9952F43BE49E6A7EF8129A265EB342AF271D2B3CEABC86729E962200FAAE9EAA62D04C64ED91E0B3D8F8300A7C24719A9F64AA35804D2B5FAF7F3F617963BB8199B2B842FF5317D43F32B04052CE5F3B7DF5DE8E2FCCD0B183FA767A3779307D8DC95ACD2E36F4A99945E12C0098B2FFBAAB97B08AAAF9B30D2531906506EB5194564C74468385A83D0D4291EFBDBCEE7A3E781DBB81C3F876957DC169C19E376D76F7E4AA0663FB3E332410ACECCB0457E076F25CBB2436A89D5BF25C376392E719B2B49AD2EF20FE5F51595217239E0E3C7D40BA0EA3F3BDAAFE29E283B9A2B93BBEF4977E2574082E8BEA041DE33244DC52D71376FD051BB790DD94899C80466C2216879166FA46766B7D23899916FB8100ABF1A1ADEF0FDBE68DE44774E13E1104432503C0CCF39BE4444E3564A4740A101DD654F76DDEB32C510077186709684EF6EA61B325B8FAB6E039C95D6C19BF09CBCF7F6014E1FE85920AAF974C164D8079E3CA16707BCD5DA704F0A66A48EAB2853225A795DEB51D45632AB38A07F093308545A7EE29FC0309B48A177DCADE869484814652B70073AD0CBDA32D2965E26E2BD2AE66FBD91FC11E9B5D71969953981D020AB89EF3CFC3D902CE078ABF948260035F9583C34F1650E647992A7FC4B3814EBC58723349901171EFC1629C0C2DDD338891C48A19810779C2941ACBEF58361B3A84DFA71D80373DA5358990B65922E17ED7066E4153CB637FB56605684A94284A907C92A2D717243B731FA6F3895E8BE09B7EA23A023C6692E8F2DB4872213EBA4B402D764D2DCA50A3F2AD278F33493E9AB83777F971476A1CBE9F7A448E3E9D9E47D55D8A7F04B1A380ACE616DDEF3625EFDBA9A625B19715D38EAA295185B7199D81700A9BA454A07C912187BC269C7BD8D499E14557BF206A33381996038E27A28D19EA9672574B017799A27582421CAB69B6F187CDE5AF2526266EC10EBAC90E4554143ABA9FA448ABB8CBD380903EB2249E124F2FBD230E6A91342972B3C01F81D7993A5A1BD25C4E0F564CD4597A18E828F536CCEDBF66DC85F343949B1DC2A50D58FFEB67949E596AF43E1E00E13C3BFA84FEC72E364E88509B8F95E0E9C0341F3A3DA99C947BE21DA56DE9ACF630DDBB190CCA9312142640556962599A52FFAE981E3FB372C0A2B99EF2CB3B86CA9AF186939CF277F32D503A5E6554ECD0259C52B348A7E107DE4ECFAA35D86A62F98AA403F911491C1B393F4CE1333D517A731E106E191C66C7ACFC13EDAC66E9E2C5C3AA261FFFC6CE688BD711BC748376E25286923E55322E6483D96DAB4765AE5D91DFB477EF5A5B61FBF78F248A92D03B18A7FC247615405701C08E5147700F41A35CABE1D1A592582A2BF2067653D7C925146776C0BFC84A4EAD67619C0196A0293B94AB5FC30900C25D341E819F443C2BFC9CF7D4C3960C6C7E6C33F656B3B512752A55FEE1DB2B4FD799DF192FEB8B775E141A0B263A24710AA98FD860C18D490C55D9A44A92E1ED5FB9BCA06562F2D1611E35559C2DFEE0AE1DDB8D724A36CD16CF728B2652C92CD8619B96AE1EF21B2D2C692CF02F9BB43FA0E4C87E001A3D6F1B7177EB43028F88FC024005FB095958BB35DBA11E72D800A971B1FEC05548BDEEFA046947449209964328C1B95607AABA6DCCEBAA3B9A4A175760F65990E36F0299604545311179B3A0FA7A3695053EA99B5164A22E1DA59DA3964D76DBF5D46193055CFE1408BA943B86C0B7CDD2CE95EEFFA95EED74EA018D42D891D7ECBE5C8DAA52C04510253F8CCBEFF351274CDA464F51D4762B68E36C783041063128878D9820AADABB2BEC4FFDEAF61685D9C0FD2CA6626F8E3BA66678BBB3B46ED7FD3A9B4EBF623E37D90BB6FBBA31C9823E8D7379EE6A42C4AF6C15D183666195F509F3A23D14ECC4FAA4A35B55D122D4F0BAD9E0DB8DCA918CB2D13E96B5E2EB2AAEEA1788614BEDEB39691B072A094EE22A6DFEE43BA77A46A9F341C9A95640C26E7596CB6F0D0889F75789FC54E31FEDE42BE11D09F6EC514BB5570568D395751CE5D4764AC64F4709C919967AA7E04FEB19CABF739E1B240CFCB302321E3D012A2231D0DC0D1038F84BED48ED94BC06F65A3F437C9D8FB2961E49B292698618F55D06360C8661DDCB990C68D1F47BE15640BF059B7D7EC8317548E20C83961418C38B4EB278C9D86671AF17D2A2E22A2BE605FCE1E496B5B1DC08A0D4E7B956CA5A28116CF83FCE69190B1559DA0C19A40ABF85D5030E0E979C3B8E174B42D0F2709E28EA9579332E47045733C15A63DD2026C6540654C5B481DF921B2C4FA9729B817A3282AEB9568A6AF7DE57D73ABF0A04347A96263C97B575EDA6E1E17B2CAF8B1374FEF9BE11042813B4D64DBED1DCE9D452CC0E17F67D51022B8AF47D32494188868933BF44B956B9660A9103E2AC233F907CDF2ADCA9CA51318148B325BD29AA508D9A6F121CFD6BF37835F9EF9E3D9523F53BE11687A2F19DA1580BB868038A1CB0119585AD8A2AEDF39C8B3B7130FC5FB02EEE22279EC7ED7192B4FB87FE60CD64700CD4CFFDC4ADC518C216DB78C77D8E78E2A8509636B9790AF99616BFC5CF3394EE1E044F4DA0E22D50495B887C6B2A07102828E8CA08323B3071972286022AB78A794E3CE3A31897A2DD60D26C952F51AF92DFED277FB671CDEDA5667887CDCFCE78103037742274A82DC620B37DF769EB2332D95E3AD6E2B38EDA6E9530FA7803BF52A32A1907A880E18E7B5CF7FA751751D24A59CED3C08CF90305FD55F19C6C902BA7AF6F02464C1F84A67FD85F81183866C544F080425FEC22CB6304296E00F41B69F2ADDB5AE7F286D39EDF19DFB02161BD6D5AF66D2D" - }, - { - "tcId": 48, - "deferred": false, - "seed": "910E96CAE3F7DF10E0686DCAD2D6CF8E0DD9ED69F3661F0799DF91CD6C494986", - "pk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28DB7EFFE2546EAB9785D75DA10F4FABF8BC5A3BA57B8510AD8825E296F6D1ACBD0350B05DFB4E58A120B6D001DD51732740BFFE855ADF7B48AE537BB790DEE364A702310323EBE2883609D8219E85AC252EE56FF58C5D6579323EBEF4D3EA265D1E65B446AF2436C3164B0B984DF75B63DAD2D3CECC1F41BB23560ED67842CB76723DFF07717DD3D9516580F94514B1FB3450D88F507F1BF07A3766A6E52C93F972F052BA165BC8D7A06A7C96A0FEF43EBCA6FE4BBB0D236832B70DD54F4BCFD007A09D4E1024817EC0AA397E9A88E4BD740D6588B30B6A994701DD970AAC571E66CD86B3C9B9A524F144D80A96565EA9BF9096721787D5E484A7CFC24FD04D7384455905DF6BC6E3F526481A38648F0EE49335EC0B9C067AA8071E0BD4DF9F23960754CA894342673CEE8A3F5A6C26DBC476C42715E23D222F3F8365F69F2571E777B4AA51126303A1E90AB3F9A445DF08FD853F64ED4A737BDEF71AEE8E54454F8AF5680C0B996F7EB4E3D3F01B95CF449E1301FDD80B4D3D238E7DA61F7BE64E26623EDAFED874581CE54C35C4FC6B302B565A8A1EAB844D086001B74DBCDD14424721BC36828EBF3C3B70A8FA289C11F0B1559988D4993B696E1C6FE6E62C97F4239E305524157540E9F472E979F9640B26FC6F79E69DB22928E76813E46A1B056A938730C1F4C0D5D5C763ED3B78FA56073D2A41C639F4AEEC923FD761844882615AC1EBF3DEC850E33B7D00EBDC62E2BBB0729CC465ACE1C8A50B4B35B4CB6C51CA9016EA38A79B65EBA47A955D41DA2F23460D822BAF79E08658253C019F1E393C0392389E527FA0C446CAA5B93EAF129C5EE2E0FA36D08D763042AF0A9CFB0FCFE6A36DAB0A78EEEE90AD2D5F63F3EEA6357EB073F9F912AF9BE8E04D86F4A34B9D7A351FBDA890AA01EB34DFE519195043B116AF01D47A45E5FFDD73D799CE1B9A5E584DF247B5B4F1128861F43A322AD193D94EE12741817A6324E0E8F747D20B20BD5922B1A1B3BCA25C7F910275DC3A93932CA5B6257E7476EB35DF4DA8B5545A6073D308CA77822A72CD72E2C3E82CF108DCB05F50AB61DFB879BF731AA258877628DF11ECE67758390946519D566AF6BBD45D621E53BFED5D874CF1D22AB489AC8DEB3F8943F9927AEAA68CC4381CC919D25CC10C2F4938496D9C787FE032F956419D8463ED1385A0D1C96D3510CED99AB14E14CA9AAE0FFB645AA8AA0D09C19A4CC4A6F83468148403AA88C2655ACC1C95F93FBC192DEEDD77A7046F97824B1E412FD8E70A71514892FE27B53118E4D3362878DC31EC6343D3595CD0BEE06D9BCCB6E96E8F5DB7CE8A8F31B24F989C4CEA43E55B3D2AB85ADD1907C5543551FDA44AAB69DA22483C2BE0000D3C49D00AB453F30F5E2453F8C02B20A398BCD082B6254FD6B923F1EBE56AF4195A336246EEAE1E92B8AA72FC6E355A0A1FA1A982363BB4C73C6102CA1393267A0A9DDC14CF5AA12F3A070FAA3C1865ADD1080836C2BAEAA598FA3F522133E7213B9BD4CDA65F0B98C377432A28F6FF093B6FB769B4E9777ECCB333A9977BC3C1C2B8D95D2A44CBECD962981948F1667EE8D64DA1989A8266056B632F5F7DA9018F290C98D6B546F98DD220DF299901AF1C0C8A2155230D7D46061BE46795A5982963FF1A6D507E256EDB08DF304E8F9358A32ED22B8BAE3B06154FB5DA7C4C0E448509A0B61CBD6E4E585823890BB1E2B44DDA6A8822C762F6E8BF07529C4F5A7690C24DF96C5586FE5131CE825937A5E5C8D90AD3848919D937EAC19FF862E5E4ED51C7EEEEE626D601CCBBD055F68C03BED53D67EB8B1668E06CF7ACBBBAAFB7855964B6C7BE342E63C9DF5B935338BA29FC651F8E029499B6F8E12971326AB7A0B836ACB9B0C67EC72900AF728C55755596894C8C9E0923799A5B7D0F37372CA168044292A1263CAB005323DB3747CBB1F6C08341320DE056418B32C9BBDD9DCDA8842251ABA76DA423D40DBB390A62F696FD3F1E063BB0ADC562326F2884C0CE745740C1CA4C3824349C175F75BE9C3DDF418894FCA12C0121D428DC9DF635A7DE5D6C1DB6D359A07F02456B01DABCBF49B505243A0E295F3BD03CD70209C2323131D9A300E7C626E8A30013716EE6564E11E349D53404C2001F1B77744839154D52CBF3D1045D71446B4B0E7C4E3ECFF88385C35A0764AAE46296B9EA80197D74DA2BBEB8A430E90AE1C341059663F51B58D756290858B054AD60D0CAD93AEF729824F81B9809D6C0F3E8C15CDB5C79F5361C33CEC09FF86195888F214B7CF69A19E9B3D3A91C09FE6EB43C970A1C6262180B9A0D599629F12A61702F03C0CA5A45F8518DB4481C721155791368CDBF786D1A7CCA77BEFD436F836B5BBD548F079FC87A3509D12179EB3DFF109EB6EEF56D21F70A3982B24C3661DB64310412DEDD44F6AAFC252A2CD4F8DB9BBEF12E0FABA2381C18B5A43C9A16EBDFA9F9C2A4FF5912E46FA2599FD16A318EB62A971A03890C8DA8B9360065D11FD848857568D08E8E5813B159CE3FF0FEA253593625F82B5BA5794C015BE84AABB34409E937C51DD3F6565932561571AECFAE711B61A9AE5CC1D12AEDA3659669A481A433137BD5EC3DB59AAC18004DB0F96E708E06990C35856DC612B24BA27D4D837B3E8196A2536D5E388D8E51C6FB25D54043D0D2DD5FB1F827B451B7846511E5F51B6F48C3EC08FE39A677E2C8E", - "sk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28D24492CAB5EE1A838CCB870B738CD2BF15845081EC92FE655EDDC3DAABBD70463345E717BF4E9B77E4E42C41EE081FB7609E529306FAD0D010253818BED6F5C36E80F0CF2E1CDFC3644B0FBAAA332C91B8E9BAC48542587DDCE3B89B85AC95B67205358448251106374330761616370840427403060131555776484032685263315404265627140818478237330461730266886678220206757852370307812313186670777525377243410283855032620382282420030862325482173385126618006425080660754150507021155510527010400031730580268480057432412702246646585006018341365521716483413675564656536487671660142316774020375316380713786272377283742823337111220565020523286660270378010320780454435727328225012270684854752384080330327232568564232334624785300247078327824557671535222210477505366750273350760622046230230260051216004274018134720587804852011513328437632380487348538761062461618530322680868132352785267226346453636340478012526081750131434530007670441442545000101046220634032432113214835787158680732862056026304846838602761436702478386234638586703304407840415284465247473208178635703585423748148856167002814048306441188623612783876688861220036258078151885032812826481381533241417755607323112011074124487501132778203584733520654651330088421647830628846050045765114501255050401362864274111122784215666102828748217571715050331524203557710257341457213042182483316853151265470516218556873288758186361667570271538733143722872641133534773365442068318176733601261602087128454576104402730785325228074080124728136803212012176421321531125876743834555426446750774328825708846140833734063225565260787734461625334052344861774220588771408021810607471156332580632280701173562858681586364176474502351131460358610510860814212667307781071767853607451544703521337335512585050362481526644627232206577243115336803784153432761563147764470542241266534771730877768307535531184023433563146435118336554118553322683875347873514134711335415277733516356657622323524047003022507454625047621173572485725784623060878303721555357201478557707263311371545530238434748271222817073038030533437284816784301801712411264351214303745068324677180701387874004318531672172357360350653266358643677401786781602256310774310423523102138875113656455771583275031265507486382852658323110101755161235083527248117325406547684577540263666157667871418616544150267046727347840767160533104681104207400671472835332830774825088686527066365754634711824660710703543823161528234747317210601368642418361673115730670838723373875628051373556788162537260577837888028732672353482401052021665413247585302187633005427258870173180733401656355241728775560065687277881464582763237044678011865760682717142166374624528785211470160157277740506621763080770285055044428134504455441747414021514780758088166611667254100231637072441607706077511335806828544374880608121171511770560080601164106110827266126106183135415882627445120836107122852801612426738230306530455072677400205525856874676132831248508378511646237882435637476882748587424351284047403241180001573406464365334575336777303464222072838174364367877848211517701774258316522054107175211473552828834313110583621807140335000560AA86F8697754821BB4793B67A97B27699FC1124FD3CC779CCE56FD068D0A004D91A5A8BBC7C8517437AD5FA4114658257B24FD6CF7D1E7D4D0394DBCE171425087C232DEC09410FFE82C67427A4D97845CF0922C29BF38D3E6E31E8758A43839569925EB3D9834C352C2D2124EE24F5CF61207FD6BEDCC70E1D665D12BEBC188F3A1E6AE462464BCBF05587BD0B5E960A9D20DB52C7326DD7BEEC6D2B20BF82B9D551475B32A77AA5540D2C15D44C948A2F0EA266F6EF1F619659B0C4ECFE94D45045941FB3E3D4940A0B7412B2152AFD4796104D0CEFE9B5EEDB94ECF11B0F31956E2EC3AA935BEDBBA75AE3878667DF71006587AE20D9310A2E4D32A9ADF94C7995EBB2D72E1EAA238EEF912458918099AC43D157EF4B4480F8C87EF8F8A14B083F85CF46F795EB40EDF4CEF2661566D605CC62AB1BD197CF13596777429D7E7AB5835D736AB302CCFD90E5A0A56342F27496F7FD30064B1CCFAB8C3A052353339DF7D25C05601B8B7BB86D0B43BB4E1851636FF4471C26478460FD4F90230F3882AD8D5770B366B8A2055ABA7045DF54915850B48C4C191DDEBB20F0178B950F711757599C73B31024344EE04EC84E57B818F3C77C939698E895FE92BCFA7B2A8E6F271C39718C9CD91A278EC554A3746ED04063964FF384DE5D9E53D8D018D99F974F022A8820B1AB4F2155FA7CA8D8D454058AA179FE01CF8808B33EA1CE9FA5F57F59EAD79E60F374A5AC959F35A22A336F505061D75497E374DDF66889B6D72D5AD04E73A7BE7DC43EFCEBD248140B0A57E31152EF1AF3E6EB4A203B6292A867ECCDC211DC0D42B67D7FACC9156D159CDDD0CA254D338AD67093232D10E94B5D6DA4492704D9A35501FE279B2B6836978C0520B643323D9E0FE1830B2EEAD1BA1ACBD76DE53C8F4539EA793415E2059582406601BA40A2981EC3B5CC4EC5328F6F636FEC2751870923788D0F8331313B0566C859E01FFE88335DBD0BA67F5A6F73B41BC9E501272C7D2B6DC0047E3C7796B0E716C1D5E2D9601E84876B9A94E91FA7A48883FD3829786162BBAE86B4F6E0B97EC079BEF8C57FD43444D2602D3A9C5DF317C870C34D8B530C92B905A8B192F0CF1CB31F67CFE717775652D3EB6BFD7F3736CC3B956BAC5EEB82B73A29D6BC8FC64375F4CE18A066DD7E8AD4DE9B051DFCD749232AF775A24597BAFB20CF25BD08EDC60D9A5030BDC28E600EFA01701C9F19EB20755F17FF66A3BBCE48CC727F7D0B51FA1652EE2A9B8CCFCBBCFFF80EA6F6CF977A757A1F079CDD91094E4BDE475DF195DDFAC60D47101E459EA750A9B6668F66B7832B1F96EDA29FFEEFBB4F4B988CAB6E0000377B19820B0A12D0650A60DF4606D92372376134D184E5E7F94688AE41C3E7067F191BA295C1CB0F283BDC5BB02D6B77DBDD22B36D7028AB787EC423F026C5615F4BDF04859EB68BB550797756F148ABB10AABFA479271B202AB399A3D5B6B269C3B04B6E6B8282F38155AABF1B5DB61513DE96993C82F7F4528894EFBD76F99ADDCE4CF7C6BE8F73C341EE5BE2E9F6298BE4E1A00D9751D65A5414B760CA2BA96D26A7B2E77884280647BDD9E6ABA0DDDF1E84AB104C34D0FC10DE4D634C18BA991932DD0BAF307BAD274EAE729CE4E642A070A9C0F5B5343816D3DFD78EAC59A8A36CFD5CCFBE250F5F6294FD58587BECE6C9255C2A419B7614A08097AEA3851324C533003874849CAE7606F190090299C473D3C367E2A11D61363C7BE70A0A9E8553E572B926BA73ABA9E149890E61A07088406EFF8A352189F6D68FABDE060E3F3592B9F729D83272D62A02C933A2D425B71D9EC5839E53AEA96CC7761064DC37DD434B6AA283FACF03A5230F54AB0A6FBF7858E1434EB58D989318FC7270E0C76ACF28EA8B6697408668B1F556DE9A53ABDB587E7F8D7816418EFB92AF93E8EFDE2F0843208B604E483E7BA28565E4ECE92A54501639CC754F0D5BF5BCEA727AD2AD5030FCCBADC4BF27A16057B3F948C45924968D9F69F0FC150944E4D541416CC46AAC433325AD2788A944A607E001CCD824C3A1BDB3F5E0F5FA93A864A7C7B0C2F95B99A5E64944F07C4AE95F9EAB462E90487EA2FD02218BED373536E1E92EB7B9F48F6027941A289E2A63CC9CE55083D93514D5EB734F9CDD5045E4A910B824BC105858E6B4B2A964A5303A9593E26824D5956C18B5E7CD5E926DF580043C54B3862DA98CB9D84A68954E96026EB0B9C9CB21C6F04E783E759E49B7FF5E33CBA7B10DBDB4DBD84ADB01D725625B86B60B8819B23ABFB84F8540A953A53E9002896F00636D96928F5D6462DF2F1E5E3BADDD3E7EE5F9BED9ED8E29499AA327083CF6E3C6759F34F61B3BE3EBF6629646B6D7370667A36BC53056B1C045A5D460AA6603DDE5C0E80B864EA6550D2529F9DE9202A8731D21518E489D90B16F89D1C31734CBD18DE5F1F31872593AB9037F3DD87EF3E91877961D075532305BAB20FF22ECFF44DE46CD7E4CC5E19DD5C101AB28487DDC6EC920DB72A30EF983E8F4D009569F2864B35B113D050032CDFBAB343086BA92D2BF00D7CAC698BB5D436070566604D793E945C98420354077FFF14D5D4B7366AE9FFB7B3F6E8B240A82E85853C73FA6165975A4C11108678E1E30B82B5F6346B283C41964FEA6D525D66B46C2BD259137CC02B4EE78532A1B76409F95498655F6A28C4EB4CB280E6F78019D2D5C70BEBF9BE1943FDA6897EC6B56ECF64622B520AC230BF261F60C2E66CCB7BE18A0B16BA0A08B6F8468F2A0797AFC66BE782A6F6684760CB189A287F74996DC6A2EBB0B17FED11641D89819761D3C0E4E13F165BB6AFC6706FB4C9D27AD6ECA1F8F8FB4C919D88ACED483DFF586203904EFC7741ED28771317645FA2FB2507391A663F6E58ADA8E219C9B379F4DF03DC578CD0AFBE62B65BD18943C81B9B7276F47E81351BCA38770A57894B2F54AFC746155111E928A7A65E7B4620C976BAB3BD48401327300680153C2664D303B5365C0F967D39BD92DFB53583ABD16838110DCCA3FA0BAD45F485F686D1003D62C3F7E86D87E908F3CFD77223AF4D4F6EFC817F14EE85617ADD35C630879FD6EA0E20645316C26FB4B9E66AB6FCAF5CEAA95302E3258EEBA216082A033843D592F9D9B655A5509390C63B02E904DC2EFD9C1A4F9B782BC6AF1F7AE315C0E7E25A5A8DFE3FF2745504BEAE8D41EF908C45F3FA6F2E40262C88278E89B02B3C8415C2C8CAA76F687EF30014C2C9ADEE89E46B06383F4FA33E66FC80B7C505972D8164F6B651A4D037A5FB2ADAE708F4FDCEDD202F9D114F4F78BD2507274E87FA4701BAB73390650D02E254729C33DC1378E9C97BFCDB32D2755046E1FD63CC0504B8117F82E7C1CC796DE16126AA3F50A9AF0373A819B01EB63FF834EDB711DE4E877EF2F1D46AA1B7E0EB0DF171AD0FC1F2CD0B6B029CA782FB259C5F860428478DD9E2270A0B9A05260DB661CFBD0E80E75F06020221115BA18B0D6B455040050B23BB87D9DB5F87877E7ED688" - }, - { - "tcId": 49, - "deferred": false, - "seed": "D0632A6EDAFFE0A71E94E62A5135066E6F7ABF8065774A2596B6BA2F7F138BB8", - "pk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A74348698A5CDE30D2256E33639E45307470DFB674E427A6A441012D80ADE3CF8133B307E29842FFBA09E7D04C123ABDB4CD41F27291E5A6ED55827769503EE1112AC884873EA789644C70B424A6056038E2A0D785EE036DA2DA53B724CC1FEF74831897636ACC26947129B21ABDADAE0D105B07FA4C1CA63651D23355419307E8C44EE19373AFD8CB061F1B1E8406627482A1BA2E2DABE2E5A0CABDAC7D2A7025A8BFDDA46D9ACB02AD4C9466FA203059CD5673C2018923A9304890E3A92DFFE7ED3592CB07E0B23181B20927F96F0E85E4FD59EFFBD51FEF48909E36F153DD128C001B59F164EC759C9D8D07B1DF6252F1B8DA19B9E9019FC5B2164A88A4B4C34DA7A8DB6B96E653750BA8039A34D5699ADD2B5DCF3C191F4C10F4F3F772074B4B726E65E783AA34E3B09079CBE2E68F0F52C647EAC333FDEEC274DC4E123E078D47FD52D01961E2BBBE62A1472311BA4AF5481D92659594812A4A1D841CC35A3CEED21F5D69C7F1C4603CD4E1E94B9FDB5FBE2EBF720D5481FC0A095FB987D2F2B0C5E54E9509B87EFE228A21E547A28AD9784477D275A8959AB2013BD8C8702153FD2B1870F02BEB1D1B25B2CA038AEE8E93A6BC6E5154624C6A734736124C3DF027D3259F5F89C51B18F4C3772795B1E31C7C566FF6F2D8BE4BDBF75F6FA4FB5EE4D9243A73F6D7C6DEC8D4E0E5189D50D0E419FDCFA07F03246B00C9D866E87DDFF61BA2B7FF863B7B120520C67BC5EB4690249EF688065D94AEA220EB3E3A11AD5BA7A29D9F262CC28A2E24668834DD679A87C1A0A3F36F905DCD7829A772B1308FFD56D021E58A81B60BF95276EBF04B1C1D6308559FAD1E80F39627D82DA5B0D23CA64BAEDEE87EFDD8C34BBA8CCEC047843C84AF46C435AEC0B23F9471C73A78456734A715ACE1AF64BD69FF7ACB6129B1C78608D5C64BF7CCCA2F9696ED1C64369007541D7D76DCFFCEB8D2E4F911DEFADBDF740A4048B0006EFDE5A73B73D553505B7286211B85F64C7B9CBBA721652B8473B4086C95FA7D0743EC2F9CC5C887A727DC2C7321BDCCDB028644ED73EAB821BE8F951A26A516779FCD5F68EC495C9EF78660683F08A85A610CFDECFC58CF49A79A3B9E3B5FF9E403BE51C274DAFCDD07E2051B44849C2ACEB79CCBF64BD6741B58FC4B6BCFD23B4496918E9BAC4FD4FEA6EEC1ABAC8757C6A972D3909BD94169DB5EDB540225550B600BD347EB3EFA51A5F6171321A6F1AFD6FA0A7AAEC65A612DBFC300AA4A1921CAC1D77EEAC226CA0F8993D1929F4E0F0E85FA38D436C035F49D85D1A802F4DDA9E4DA98BAC92A0FA7D5C2BCB1EB89F3394226766E4AA513928DC910311B086B19611A58F6A9A2B494E67E22BD10DDB62E6DBD775E7269270E2A0270D60191C8B2C8FC511D6CEEEBEC5ABA95375412E14BDE0906F2007EE4A61EF0E535FB22E6DA4FEB9BABDDF775E0394997574AF4750ACC98DB4C7979B90D9DAA0F35EA877D4D868F828340D1E38C767F413E89DE0645E1E2241A79FAB882DBDF87A04B279703435E3528CED89479D163917C1F990DDBA9B625509EE7B8AC53C38060BDA1EE697A6F237C5AD3E3347A7C6F4450A363F171901165C2DA96393FA31A057B1C1964607D923E5E4C658177D5BC0B05A6CC0DE1BDFFF0F1D0DA1F1C8752D3AFEDA44129507ECB0A8FB52114F5ED6F0CD1BB486AF44A3D74C8F88A2AD42A1B72FDBA3D6BBD2943153B55A9C8A4DFFFBE8E0B0794E60C9B64D7D716C58634F7AEC6D33CF50E604048A2FC28E9C03C7A77511D7EF20482FD11F815852906B0B9F4A40D45FBB972CA67149CADB90F9BD3EA69E42291BB1562464BFE78AA39240CB24B0BBB8D76BCC8057A3697A2B5DC71C8E9AAFCE7EA04A0498B365520621B1CD4B38C5BC3B2CEE7FD7599FB79D67269BDC4E5E2ED33F9C90D6EE42C9829845D7E6D6E861EE870119E99095777327297927A552D2D3D8D850D3E4B63C8934FF69ABAF1A69B408DD2C630B3B7AF05C1F0E22DC7E90C4A31F585FB9D9E4DEB4E9607CB49C47E6D8DCEC439AEBD1EDF4CB0075B1164A3F29C33DC9D0D59ED5763AD8B1646D0F655A00B6918A90A417989F9AA44B5CDD08CF1BE46874218E1247A263E64DC1228B540E70CE9F0FA70EDC4B5D02CDC450AF18F6B586FB850848E09682C5B6ADFB680A6262F90856FEAE11843B277EA039786313A1AE260DB0062AFAE786B61D4A4C3B30B8194379BD44436879EDFD61FFACAA894498CC26E2F7D823F0AE7687ECC67930799DC402BF4F95DB72001F508D7DA37EAAAB0C2C553A53E7587ACC342167F62EA39C37B3E61A5D7AB113CC38F8B7525768A67BEC285F0ABE9BA6A9957C77A45602BF82F1059E55AE9B9FB126D24E3003D4B21C9CEE851527A324A6F48FAF80387D09B59CAB3643925EC74FEC4374EC3E63853E741638EE27D829CE5DC11B8120279EA9605061513C6A69796FE9CB8DCFA0EC70EEEDDD70927703FA4C64BC723B94D358371310ABB486F086ABAADA7B78B1C0C55D88EF497EF7B10071D8AE72E2E28078D04ABF04581FC9D4FEE6AAAC4637E6F9F6F65AAB1BEC7526CC1BE743A0EA8481AA9E069A9CCB7DC1575345305FBBE7338C1D82BC10A1B64E69EEF7EAE67C5819A3B49BA603F7477F19B217AFEC4BC32DADD26255E2F917806ADF9E64F769AF70AE5691B26070A6C65732530D93AE6D1CCBDC77AE37C494B51775", - "sk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A7482939DE8E5383E4A4D7CCA79A9B7B5F621A461B2A1894E53315103F03C391E0A38F615C6BA1E541A423565FC34907D84917BEB652AA4C7C89B35EA83F793FB3869705E5DEDC1D7D34ECBB4D95C1D35DD6B40DE0CECA740A4E31A27A3B9B98B004167782002506841243131365280841862554703104113155456536303543617108241084365386764253004844717327286064008824375547612437003687713635685066644742221774873358808665720400037071175028268662180577204401046247407058352323335075052670824212300407483106303227830177854464331616047542826861670237417840476056071515848278403033816884841214314076440461221508580035331828782618221062670850105785181770543082612856215036712840812726467805080064220170772536041034233473660817847175128245640505226614302508264364233558221033502567126054184687247511388085075262104876576227676324033577673623810188261171678788152746506166666437714701318570634332258550030740802413325435742263763045437462580115223212302255580103400865160557838787133716521241880267285308440147661876354467437784576735016345306611633062308811754584122563375147088373865225564243753521041540308730534446822385070861372114166326555121551770304536258008600364651176054363425836546104588565084542687503166017467336054565181617671174833865845685463658560857723333778762132475402167621010761623608348147038670132886240342442203328236027687753446546143324435782630665465553071476465625052657022353521572181631224342003132015665731086200251034727642342042768724157205803313336582551523358281602585074476178580187227145207635537012102513281730837422237248644518856730446206270316046650705818616665454358454738580353684110371157587563500822416111325582357584873627108128414201573148520755163811133056706316481086737445764287175387115416137177806484511265720218435445723261765302547621018234141462250030101638825222058372031833322338705318630036282520683874156368725686845163013242685832845523211553403620674105511622738815740862134023810117557426767760474585642644381655073854814045378307374382347381682033386078518685732885231765713423524881768718425148633644633286058714086311531058034818681263601377352475382525127272081155327226706655400072010405570087661815758158316283675713547420087156758728037757338135282288202782248501716018427204542088117607023584376282157782581470415233186584826507805762724272460033571412651326634402130004312645872667823075287652008020443487546340027782053437118628753610138356363183678428866266814623572045615003787625306877435726552077775273853857342148168433307612655423471126126802170023576688573236778627018467128804074385508720177344051461510855273367027750453251260135356145844210610652605165255220226672777165242368018647605284032071386241066412541114087584161112462346880726742547517663078120246705222743787525124154100750480507431087464341512207843441744722418777548374068250520572687713551245737701746245167380432348183857040811300514238606167175033186851181631382615450327661753468814784210764752450808523060630255288500182478823571263715802420751310703278612077507052483158216127060610280280340534522742587786314172781347215116342513C16B0A1B5B614ED286BE55E5CC1777A2680709F20FB7C0BE8326186386A4F081761EA493C531A8A89B64AC384C313F63EF47D643A8E614A9D8D00EC276D1FC7D84034EA545B2FD2BDADF7F90D0BF68EC519E47A35F14510BFC78314E51AE02001C503E723A4B6CBDF23A73D7E0150A27CD344520027639033E28C34E7E6413827C4F8213F09BABD184118676D5E1361B056F3CF3D5E0CBDAE14AB817EB1C8C4F9A94B65900259F62B3E099DA04A73CB7A671DD3814FD163472983BC8656C8BCBF2DC6EC110827656B37ADD2B79E3B7FBCA07D40DA224F67A06EED7E57B0226434017DC436754C5A9464C687BDFD74E5EF2ADFA208F44F18A40E36EFFB2271C634F1FEB5DDE90C929EF2106368C73A7672217BD86489E0F17B5EE32A61AF1950DF50E15E3E0DB1293E0D02F9DAA92999AB5BD13EC2AE956BA90C226FD88CBC6BF31FA87B403AD68D166F60B25E539B769ADC1A80918218DF163062A8671F090CF07686490C4AEEB58D396CD41C2111316444FB56200FC8B902A2EDE74F410C30153B8EF03552470F1C00852C564EAF18CA6D5DE6386F2077837388D3EC51894D90C2F86601E4CE8D6A974962189C43AF8C9F682573C794669379FE22EFAD679E4CC797DAAD13E7F41EA7990D62074DF58E69F0F33AD8A1C77EB95FD8253C692E3009239B5664FD4B86ACAF7403591C3FC2AC97FD750F09786A430351079FC257DC7884A45F9B418EEECCAE1D5F63759E3C9D61443EFCCFD751AC19A9959455AF7A49433032F8CC4F5678F65E9D6FA74761B9B9A1252928D760113DBED52CAA13DBD0B1B9D63D7F97C4A71A417BB8C823853236ED58721F903D8F3B8BA4142D9E4D3D95B59756B9A7D5FD0484AE286CCDAF3BD033F9B743F5DB8592253848FDC1E2DAE0FC717D056D8D36FE91B3B15C1165E018BEEFD0A28C43BBBB5D95A82CFC1FA2782F2593DCD3F982143E7AE80F70363AEDF228A7D847B185CDA5AA435BEF32D2E4033C34D3C164F0CDCB98DC36BB52A2C8E12E3E3B3D08DDB265528C7F4743E34CB72CB663EF69E086E6D46002138E35B2130FF2CD40D9854D674F98805B0041123CA280589EB45F066E7048A2A6E612E81AB1FA93BEB0FE673A9092C6F72856B696CCBFB6558A39209C92C800FA0ECE324091B88E67FF414AAADF439322E4DD3D6EA72924E4960FB7A4D9357BE2EC4C3279BB9BBF39AF61F0E390C6DE1F94A4786689C0CBC2E9ABBF3DC6D0D3538BD872B882284231CB76C5AD72560CA2FF6B7BF99639459E2861500A34384862856D6AAA944737ACB263294264209E02501D97FDE1307C45D733C4D35B4EA5EBF63A6CD16A8D0D3294CD4C678AC133BC2B6315E53F4E823F3FC259FA2696AF74E1EDE6C36A5452BC5A339068320123A24D097A379EAB362619070A62033949204024915836AE207E0855C28512DAEC08E70A931C69D96AA565C55B4917CEFA3D16F6505A77CD6DA985B4D2276658A0DC6055F5BB0463C6B8A521AA8F7DF7D9CC08BBA26D85670C888FC2B2DBDBB0D42A1B15067865E0991FB0CFEF9CFB7531769B5B3311845ADF229DD808243927BE8604495F7FEFC90021D1B5CE27D372DD9ACE488C83D99EDA25A84C794FBF626BECFEA5E3B1B360D520264910496C4922A59EFAA779CC9F5491000AB2A5043E18718FBFAC21BD187CCCA87199F63C29BD1F402DC1115F07CF993C9C46AC89F394D96A58F68D9682384AE586BA5E6F575837270B8F00062EE4A072AF52C5915B770C30C372BA591120DC8B0EB63CA29660AB16FC95D8F5F804479786B68D0BE9DC758775921EAA7B1A4DB99DD6FFEF29AF98DCD566210EFB33CF062C2555F0495BC654FC4952AA72E4B5C9793917440D63D5F5C4ECB0F901BCFA5F3309D57ACB366396B88EA9DDF1B9A07F649D5C0ED5B945FA4BEAA1F01A900F5B3FB64FCFA7D087A41CA397895EC045BF595C2B4DCF5488506A3C7EE9C4B588AB0E49FCBC7547EA2A8F867813321658A6240F12A1C2E47B1960BF1BA97FEE40A82B0AA13146BA443A891EAF7E885E82089A5EC21D75760BA5B0197DF5306B3438D3FA2B799C6E171B6D9BE22377704AC307B54A6EC6FD1FC98C57BD4A8B2E5CD5777799E3B86FA8F0D0A683EEE2167BF15C064DB860794D93ED601C425598F5A4D5B354CF0B8367AD742144B1CE70DB908A466F4312FFD7FD55FDF8F820398BAEA18ADF3B14710325B93877EBF94A8F68BD5A57D899D12FFBCD261373D2940D78A940D936F9B2F88599491928A9D54735F676516330E6D3E9F284FE32001BD5A72C0C0B29E2471D77FB31351CBA2D41AB5EC5513C568EE993457BCD6950D259E41E0682763F057D3C2234075C6380D65221E6E475AEEE13CB9DAC1D789B0BE04941985146149F3BAEA4F49053CF915721D53E4969B9E5EDC83342A2328FA0FC758E806C8B9507464E9BEB51379B650F6548F26930B7AEC18FB76FC3CC6E74C21A01D3CB206E2381EB61D9203C3BDA62B8BC2AE048FF6B3484E0EBE49D3689F51061A02D31AE18D0F3090598E4E0DA7079914B8BF4D9826B2ED5CD4FE1DEF48D63ADC7D66FDE0215A74A333F13F743EEF7CF61F6403CF927EEAE489A978F0EF1FE039E1AA74EBDE3434412474F4C9EF6F5A0F1D765624E7C7F5ADCE07434F8744D966B685139258006DB7107F7B0995C923E19A1A778639DA3B596F4ED950B4FDC87057DDD5BE1D59A6E52BB6BB5E3FCEF06ED76171DE35D7342E1143A7FF257CDDB98194934ECF249468FA77339BCE39223C299840D7F9A584A3C9E791399874235B3F1C0551486FAC4BD434A4AE8F04F011A849F2C8343900F0F9BDD9F9F8B80A7E6D9D1B127ACF0A37170415A2146B03BFCFAB50AA890EA64BE874D4A67AF2799FCFBD7772B5FED6CC2E6646845B007545EB24B12F7C5EF5F9B2AB7B4AC774B30E8FFDEBBDA4CD07CEF7023F20EEBEFC5D32D138F7DA6AC5C55D9896F618E274CC0BA43F058917667894F99BD0CA6E25912D6848AB545449D1A86BFDEB77929CC9E21FEFA8315AF65FEC0A4596F95BC3011A9F461A67E65464D36A7F7FAA07C487CFD2FCCEB9DA28745B4A7543C5EF49835914B25493A43DE0DDF4ECADB68EB4DBEB7EFA3DCEE7765D07DF439BB632F9723877DF94BFA7EF26936610F41B07D56026C91933F019C923CF98C255AA95748E99475B77F21F787D3606A3676A215785728734A7446B0A54EAADF962EDFD0C11F31187F84F2629069CDC97F99885A5F0B8A52FAF7B9171B40AC47B14E00D6C708A109F03C7E7130B1747BB5243C73D18BED9F97FB2F2D0449A0A9F4D4348B0291C47F2CE493209A7EFD0487D19A41383FC7C6CC8989F641918078ED90D2154E3CC3D4D0627FC86DEE37196EE9469D5446AC97A1A491E3FECFB656A4A3FB198FEA6D3CAF6C9FC09F79935589FDA995C90AE9D78BFD33954D0F78D322EDCA54E3C4F78F9B99B9C60CEF18C611ABEEBE7892D3CEAF5D6954F7C599BE6F283E9C1F60EA8509D8EA192EFE792E389D2E2F0180B92631226" - }, - { - "tcId": 50, - "deferred": false, - "seed": "74C0714236873EE53E7F8F65B1159ACCB1994B4E9D3E8FF194CC87D7116BC0B4", - "pk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406ACC5943341CC53C189A843AEA7399002EEFA251842F86CE14D00D974B4208734A416A048806AA9BE9D7B5B9EAC0C6CD7A3C163801253DCC0CCDD9AC2B4A663992B9E2B7EF3E2E8B1D93E4B677D1B36E8388A919E5B3A2F90E4EE69CE88735B8B105E98299ED5A9AC192479052030E6C56CF1FB2E5A822B3300950EB73A8FA59918C5468E3EFFA4A410E44FF78750D7B209F0BF48EC6E3062B76690489E1AE93A278D4FF6EF799079A8B42863688BC71154A32818CD76131FC400F2EC7AC3DE5C2954DF90AA3324756C8F31404A9094CFDFE98FF12D1F052C94C68026A214D0825A9E009A53AC5B8AC30777E05254E0C966160397FFFB0436A2CDF4FBE10B373349524AA455BF3A1A90AE05D9EF25843C8E9AEADB5FF113ED03BDAFC1EF32E3EE3F073C0FE0906D4331E2F18EDCD335F094CB3AB30214E3AD3A919BC1470685E514F86AE2008172226495349F4A9E55C3303072497571C1F4A2A28328E7D83E2B392943A5ED46095F55CB28A38BCEA6B801C1328031889A252851093FDF0B888E2E35C0CA28B5D204955BB6A41DF6AB0256B985D59FAA55880379B080DC7C1B856642985198F4B693AFB943B6C9463EC255013265C586371774AEC9E3251817ABAF21580D50A849328A828E5CAB4C9DF78C177FBA51527791437AFBB01B2D7E88824BB7A138AC8741606270EA33EA27AFFF8B3EB0F0732F60A8D179B95A513CDC9A8072C202CF4A5DC2DDFA51BA3BD186F6299C3F7AF805993808F3AF31E43BAFCD1A53A494E0D6B2B230FD9EA2E647614E50694B9FB19A810A83DE294C6BE35D3053CF2B16591E57A76B0D67C97B1BD8AED950BFC5F8526F571C72E6646F2B9FC09C9070E4A761FD82D723FDC96110A3D50D2B58CAF753DE0C8E55F32C80932662A8C17AC9B219456AA9649629CDB604322676C3E3BDA5EABA95F4F0DA031DAB5ADF92D8AD4190EEF2742CF42B26EF53A310C15D792DDB795114505222D05C21AA2567BB52E0C20A7251A672267D3B1F6728F5A0C00E957A534BA80D996379BF00BE4A725F2822643803F1F6780785B0583E0D41A67831E9B664C4E843C8BBBBE525C10FA7A7D5D3F082BC9CE72046EFE9C40EABDDE491C1346395412845B3E94EB9AA0E54381BFAFDB8186D59CF00E9EEECA5C369FF92930B569215FD7733BEA2B7BD8DD511C12EDE27ED5BF1A28080737C73557007890FB77BC5942433E8AF06234BFDCE21FC132C27A754709AA5B8640EB2C24D5F2D3E6DA9B9584317F27FE2BB5F74F95F512CB81BCCB2A0D70333B52415A39129759D6FC97954D0CF9DB5DE9F091784BA15D360B2FCB7F0F43F07FFEC2C3161C5C80C9586BA6323714391FD388A5DAFD74B436CA9455A5A025DD79D8F35632536C1E4B1BF67A3AD009878D1C067635AA9AB6989EAA3B8D788887ED3A968155CABF5BAECC99BA50F5257E9F712DCAD05EA58412B05ED7B484F54C04FE9F235E5E65AEBF23A55F60953F165C0820A9B2FFBFCF3FC6DE3DD30C1A82731705146E8F9D32B61E4AA16279AAEAC2E04957025C3C8D8AF4064924DEFCE4CA07E6F76BC56833A83B3CA4B9AC61527577C1BEF69312FE3C61A09954B0CB6261BB1272A736E66577F3DC268C026898961886EE7822056149C35CF6F96FED8885342D12A22AEC7B669A4700D19DBA1C275FDDA86EECF0393840EA0510F6BB5033C05914CE4B1F44615C12347A45405CD323738C2BE21385DEA60ADE73CA54D52F14203616471E0D0B3C1895BB7013FB7E549347D4F8AD066E20F8AC282B8EA89B83014303D2D9FEDFF90E3FDCE51124F167C9D32235E8126679D8033567FA1E5E41985CC108E5AAAF363BC677F961C30C1C34E7A866243E0FCF79271571BFB713D86F28F61C5AD2999FE7259F15EBC0622607553AF79AF73F01E8CB369CF6716B91F46444E6E5392AAFB8DEDAE015A50DB6C032EE026BB1C33C5D26B7B6656F6EEAF7C099172BDCD632F03BFAFC76F8C2A81EA19BD8981901B4C4304912B0D4CB25A27B3562956FE094422570B08089F1E28D87F46057D4F4ADE163E9045159D0967AD8377792C4FEF17A25F11E36B21DC0347A70D7BC79DAF4BAD4A6A153FD403F601AE7BB3E78B597521633500532B75A046CB78183C5E1EB84E3AA84D09EDEEEA0354B9DB64E9B5634E2AFA4FD66D08028538D1756826CD9D467DF890AE16A9AF40E4399BED757EB5D47B21B16D271E58DBAFDF8A98B669EE8FCD42108C746AA70A050E950828E4FEA76F3ECC3CECECB99CDA5CAB069A66E216CF977C623035346574198B607CD9E4582FD7F4FBE32DA87F7681451252D9440A33BC7021E41280DBF732DD2EF73CE59131F972903EE6E46D61B1E7CED204CB149D8429BF4B05E25E28685B021ACA8BD5F70D8FC737EC696DCF647577CD3ECD2CAD3116D9EBF7177F6AAB6EE5980822E57AFCA971D4057D141F1F55B82BB8F420A064B6E7C71077BBB137C0DED97B2AFA2A4988CD3951D2447DBD3D5079920CF75E569191EE46AB04393617B188EE9F2FE6F0E256C8C95266732007A1CF3F2A388CAEFD375BA4B78FC8CE538FC3E70151E94706A111B8A26F5076C4832D8B6691012081EA71AC204F3E318DFB7590A873E0E70362807693A30B7F251E9F363E494428BCAAD217FB9D035E4195C2D0DAA0B598B426B7EAF237F88965B4A4D674056AE40F5EE78ECE6A862144AB77F48F5B37486075D2", - "sk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406B9EF82C67AD72D44F22E10F89E426CCFB2811A8E07750EC2935A1F9444FF4131CB48A42D748BF952B8690AD6524023F73316D90AD774123DCC5319ED02F202FBFA1F1D197EFDD905014C177FDAEE49DCBC747225D2FB3CEA3ADB8E2F10F5755F31436765238773811321733542255302236533175246241780115462104128007273467573581348025535202227888706643664845147473688287871520557661451418514328878413038641373366831185718407742631304024076022441684115028005630816212057231680771587242263888473502112263046460617144852151674704418681846542541312625882506057864440533060357780443856681154777055701564087151872280855644718015658280312863677851147420664002785211407513254877075818406464328248013813154001322331624050147360555283035458016011331203524038706005326522546840872070671102851110243378174102083335884817020806875402760403831201100510876353316634888227144764415084733285837346265644801676051255766352818487278123042115281377854803730378374471578305031582424347547435583025488480537442240264682550287888171205276633203648543708665200471783114087658344004102353745875558615862028665386814251361853842784661712201842436134335654038651468851708818528563106713814084732620424444237602114074526706512504115573852618086623748284154003702757757885036608640844880578740408271280183246214564565328110404504021103016366323280028504148533853428165340303521887433431373146283407730451035150720684600438720240345177513074482742355148418025323238586232103826864137218026215613418453320312007670683531321512305778830220658672678877563067006255872600208024500124245128464104281008478520046576600633618564710588403104531170654438824562483140304830274223077451374414444447124376042865584403545752862327612288316107336565543304420625625012177810618312506023087408115701507637225608287258644060687666174638270058500353333121758648835266567510606053434880354021738386588676806063236654101672728166185228385412582015006285747468822340712803265176441520244078283446424774241033356353475612312701617237258760886425214443261704054342328120028688506282815074881887174845040542014534164721023455783006371746652275687272147487705001375251724275752155608832577703522335257124614767107557731356735056633724055282726761568051586048862533873550710632478825084814164307166347670722803851310738410137755085005608733655557485423453372808253002062253267038441144230483053567613201418323534713125770348632334075865343351277534834615026336638362833351283363448556373502072322478778438815815664723328454262752274860247747123500500630273565256443614682104088854483626725222523065686710162472081316104233804041537588555546274842073138881460052176546281423571573185338586307437833408755217507062427213105610460654803111545817106235831580136240252415456220148378568237665852106565412111146242167358174564532174715154103728681582144676477318056841602550434801435838750170373643147742013068813731813005134634107011047674042315218355460415773452841407821547664873708810126218821246161302682282412113460675813240713848158403046611047337524175380380808012270778466665852652317643364873677411852533564414508451220153F0E1707371B65F20CAB5D5EBD4E8E11B4E4F5D822E845589D4DEF994F5257DD296A7A8B7A99B416B8A67923C9C493A9E4D235D76686F0A80C3B1D922147A744D5094C44F262C209CAE25B9424FFC972DC73F836FB02178023FA1C32F80C9738BE0B43A1D592EC849D675B7294D2F44CFE4C1075D945B06C11A2DC643477A1E4AF420C3599D3500CCF5CD9BE91602F3A3DA09678E49E076642697D5AF3BEADB383BF51FF2CB2E2C2B64175524E1F55113A4920AF070BDA6AC714CC7F10DBAA72879B73234B693B2A929FD8637A13A93A8CCDE2C5B3E5003BC9224FE8F0A0480C8BD9D12FF50B4DFBDC0EE6EB93038017377F024B2439A5E1F4C918818F3A775C63B8BD67F4D532C0EFB323CEA9B2F4860619000DF98E5092ED4E55B5D56D658A7F92FE58CA2751A17C91B82043A9167E891015CB90B1AEC900BF74770D7F442D102119F26DB95E31E70E8B3D31604F8D3F3E74E6B0936F5AD20AACCDDD7A70396F0167419BCBA7CE8B32334D2EB0688755838A03713A9C47798E4B1757734021FC6288E516492B37BF2A046E56419A1910564A564D642F14DEF38D81C4B963DAC9D23B3960E549DAD867F4280567033314CDEA6092AFC9D9A42AEA5E551EDFC4AFFD3542671EDC7740CBCAFA2299C3111287115CA755C7F9F14BAD648427A5D8DC9F687262EEA0E594D29B0B9AA6405219400C0FA2B6B8AECABFF90B0906CBC77A22926EDFB96AE021E20F930D307479D1831956EEBB08F4444A63597B3B3B2788C8D05CD519CB40BA1F74D6B8A8F6E71B809393A47522A8AA8220D0B1042CE95A744E81B65BB048B6ABF484F1747923D394BE5DA2C34F0BD81A28A2B0DCD1589EAA9F88F2451EB22B5A4C7906E818E0D8ED383749A87740F9261FB122F3E89DDE0D1CADF056D40D293574C0D8BEF6C7AE7FF2155B5098A2C83960F77E778CA8602F0EB6C019529D01B73EFEBD4F97FC855E4D11B2B8F0C791772A72931A4617535DFBF99F5FDC39CE1964D7D6F42192EE5A2F58685D18062E50AE46DC5C65D3561D4D09615111EEBE6D3ACD0B7E197255CA4BDE22464DA1C05C1601D72954E7AA5412541EEC3F43C3DA5956FB65C3CC0128AEB685C00D8B6C0A4155C1AA505D0C93AACE11BD702CA0E7FFA2B21E840DD71165D5E734738419D8A01549B4D1EC3194C6CC3243D67054C4AE559BE3039ED73BF7E9594051C30E32B31FE7B83577384336BA458201CE23414CB2DDA8E99F660B287B391F023DE4BA97F6FA87F7C2E98DF43DBF31A852EA4AC420DA3597EBECAE663A35949241C987AE63F2E0EE3A051C1F03C402FE17101680E21163886860B9763066EB9E2708865C97D9D2E06C938153BDEAC0C4BD252C5A9EAD82A5B2E757405E2538774E4E17C403C0FA87D92275C995B09345E288179C36815EE2FECCB138F5647275E4F87540A913DC6EF4C280F09549CF05A6FE2040F402C81BCA531D51A3BDCCB5552B48D4162B64F59C65E12B5B2DB7A6ACA488E5BEA8637ED36D5D1A774F8820274FEE0899CDF9BB802BF37311E398F2516DE4D4129B2A7043B39D10E0ABABD0EC17EA263F174CED22937C3DCD184531A79CD1A96F3CDEE3D1156E65623B1723F666FCB1B0DE4C0FE5303C99BCFFB31E583434E09BDD74932C1C77B1BA299087F584CF2C58C573413F84D98E499F89B50CBE9B261B0FE913F2B4C9C79C8177B749617F91ABDB62F1A7EE394FBB5CF355BAFBC6CE1E0CBC2D536C56CA0C72CC618132679DF48CF13C5C769487825F8755F616D62261B68B3BCC9837C5ECD952109FE184FD8AFD3DAAFA61C873E460C4362CBDA2D1A240BB919FD44914DF357D4BFA3943077B3FC3D052C98F325A1D0428E528A4BD88BC1E2B453AB657D514C0C38DAE4E628830881E73CE0FF6EE2D1112692D26DBEC1E66A7ADC56010BD25F9F6A7DEB15C2D9D8EE5CD0AE8FFC88F1175F5FA7380B8D1B81F0A70FCAF97B0DDE29257FA9729F5C423D8B532B3EBCAC59974DC03F487BF29CCC5D7ACD904D656DBCBB79989767A198E0EBEDA8F96840A7AB61ED3DB3C863B742B6A7EF8FE2D3F01530D554578C18E174F8A8C49F0A2B66D246346BD9D8122087714AD87FC884C42714BE251D28FB2CA0AE72AE94B340BB6EE71364F9E6D4A56F302DDF19D068E4ED6ED57D2BC913852902026E41B8AD643899FC77FC4ECF764F66EA6280D71C4B3A4BC8CD08BB218A22F5254B819626E5F809D9334A2F84AF3960B52849B7534705EC80075859CA6565EFBAA5594869242801B602B3A0D25E749439035D8EF7CAF3E24B40C7D4A666F83B0945232C192F60FA1341122C772FF83A9F41CE6EDBDBB4880C2A67F340A3163A28F1450499381B211458CB711723EB29C6470AFABAAD2B0BE532291A17CC537CCB4F8ECB9263A2AE4850C6C51C9F0195A284A90A22BBAA60C111B561D00FC0D3A9E82FD49A932E516DEA0C20E3F48F2D02DCFCDBDBE046384CE410BD650EAF21252484FC22A8E5DC4157AE37C91380F74ADE3170F70515AFD3143394BAA087532C523A2F33DB97AF8DCA20DEDF113633371974E23FD5E16B5FC5CD6A9FBB5201D0B5C55E2FAAC5AF3DF589C1A8F3F30CB4566CCAFC4E1E29618E03E936A1AB09AF052D0ED3D382DA96DDF004D59201AABA01A9809BDF5BEFC65C18FED60F885003827EC4B285C108FC5EC86CC54F400AB14B8424163857C8BDE700BB1351E1C8D9F4CA2CDF4071E5AF5623895C5E027C71B69CD0F50DE48ADE15E59F3FB5159B588F8D707BB6F78E178013D04E0B57F4601D7E473AD99C19A1077D6220AB78EC6A29F79B6F7A100A5B722343246C0F5998D77EB22DB6FDA2C14A143BEAD0BB9153F5B46E02E7527AC77B712B31785EF66DA524BD680097D1E4BF448951968D83817BA6AC22E08F337032944B070E0DE17D58E0CE99A55BC758F43BF743B1E978BBACFFFD698D85C356481CBD10C272DD6EE2DFCA53913AFB41E0B5EACB693ABEB5F10F6D9F4475A73184D208698E7D89D7623466EF4AB8332B753A4419FB459E29B67F392D008A2B64B97FDC17EBD81AF4B54F5ABA6E9B66583267472DDE96F20E5767D25FE0954A2EE9DF8F6D71FE8D31EFC6D0321EFB677C2BCC9EFAC39F517C66660B0D616FF28BED9CEEFFFB72C6222EAB8F8B85788422E0D450C1F8FC81478A6AE1523AB9C5002E0D46D83480D7885C43C990AAEE60B1697CA9153FA1EA89FD1655C5BB7EFBC097F1323B3D9373BE36842BAE4DFD30A215CA0386520B6FE10C18DCACA30E22048775434D95436D37D58BD521F7AB1CA8179744F236AF8DB5C49EFE51E54BAD9D254533D086B31C2752D1BA51AC37478728E22051A70AB190B860049D379A2A605F36BDFEFCDD7349FB8A84A1DDB132AF28F87F17A01D32CA508C1384537C79A6DC538E1C412BFDAC18A556F630DE3858D292A89A0BBFBF179AD4403F746A62D02707AE7F4570CB3A40B065B987A3D92D3D8327B1230DFC0B1263D66EE896A58FEB52E96CB87565C9A1D5185F907FF852BFFAD7ADFAC" - } - ] - }, - { - "tgId": 3, - "testType": "AFT", - "parameterSet": "ML-DSA-87", - "tests": [ - { - "tcId": 51, - "deferred": false, - "seed": "38359FBCD79582CFFE609E137EE2EFE8A8DBCBAD18BA92BB433AB4F09B49299D", - "pk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE008301E666F59D3EC5044DE456788FDE19EB39677B5F9FE14150DA463A706F3BAF715B95336B2D685A7CD7880713E4587BF7D857BF7E315696B8D0D9D49E142918BF0974E7F43237D4BE3AD394599E3D39BB7649932553447E5D5ACC3499930176ECD3A844A425F50D0511C9226C4B9A24F2A011CD88D32308E0312A0C87CC34A995823C65F4F0F98E50C37788CE38DC28FB8B9BFAAFA904B541EE712F6A041E0611374F6BF17EAC0BD56F3B6BF336DA9242070C2469A20C4D1616149A6159252011D299F93F986D875DD30B38A22549174570138C2BB3AA9CBEA91974F3D89BF5AE32BE9E58B854A2F8E86FF76780C03490F467DB0651C20B1DF60EB97A3C99D9BD664BE6A5E4C8A8AD4CC36390D7004E4BB421DAED654C357DA4D68498933EC71777AD64C2AE013C73EB457C68EF9A745ADEEB4FDFC879E774D03FAF6B14AAB10752E24B52D0F2D94D540A1EBE10F597E514442D6C13C2E2498E8AF3017C52DB233A90717DF25B4D072B7D88EE8731D16824C95D1FB983C449DEB466276060FEE4C7EE381451F232C29C7C3220850C61D1C3C00DB1CD9726A02A56609F3A65D3D164604588CD9B431412F1ADD914C5C2DABBC90467C0C4EA5F76E24AA618765F8B0636D7B065E1F4E6F622EAE17152458C766586772D363FA99214F472B0DB8A1E49D82D0278F2958B0AAA1586DB134BDFD2438742495007E2FE5B60E246399226947A12EA17631CAA534687CB75C060B4797EAB8277CC4F8A7A20387606EFE2DBD3E736249277D90FCAB992A8C99E85AB03EB4CAC5D88553958528AF92974718135F1D0C793EB000EA0AEC3EC1858FDD18688D1DA27278DEBF2CA8110BA4A204F7930E1C8CEECAFB73F75DDB34C5C55968A7933058426B55D039F7292AC43F64584F6DF187A1D6B003F514CC13B26C2F348195AA321DE6A27EC11348DE50D825A2964C631992E4B0B425B1BEB4F9600E3ADC4431CF2E88B4223D2DB663C3CE70EF85DDD56A9BAF138A9D7EDD894131C3A8F41A04EF9F86752B72181FABB37C86B877E61D60EED95EEFFABE6376E14ACA817C5F41961AF8A7849BAC094917B2D132276B6B3486AFF950D23D4AADC24CE98A5269E1C69917960A31EE09A527C358175CAA0CB1B018E9526D93534EADBACB52B273D735E22DD0D5C28FA3E47CFE90B5215AE24F146C3464BFEAF01D28DAA553C1E94428A104A9D78AEC762591E8879F76851CFB4648566721B0CAC1F14FE16149A9D8210CC8F2F50DEF7B46C843BE93BD8D55602493350AB560EA5BA17716423BE0EB8360AB109D8FB18BFEA040847B7335145D4F200D19CF6FE7BAC917F426C9B3D39A9CA4329818F240E7DA382761072F4A6505EA8E76C1E446FEB6625E38DDBCD3CDA81E83BF768F3E01D9D263B367303AE156C0B7183364A1E7941A09298A3ADF7BD231E6114B9DCE7952B113F78163138B9266F843F1ED97D9C2B163A6E8BD4C1AB4E179367C5AC96CECF5050FE821FDFA44E9E680B61C6018932DF717811459AF2542E2CDE77178C2E9880F011E405EAFA59C8CBBED76E5A1941104B1B9D3A60491C954755E02E894103F1F4977475E9EA36609FD67C9DE318EDA2370DCCDBB9CEF7AE6360905EC220838C9769823441CDD0DA8EF0ABE5F2D1D76E2FE08FEF53DE1D6166AB1A92B1AC093E5ABF7658C4B57287F2D1FD7B82DEDAF8D5A4FBAC4B35D58231694E162497578ABD7AA7C8FE7B3541A7F18E54E8B7F08764C5E68449DF655901549832D628FA63D2B2C5A150933994A9863317AD40D778D9D2C05C7898850B90173223C7A0AF890FD7E66221B6F06318B2ED5E199CB424885AB841E7A4726FABA2F9BB53BC3236434C35FBBE4B1A0F93F50C37896C29F8E302AD31ED3331D620E3B629455101A1F1CC7BA5E46E68ED4A8CCC87B4DC75BC0162B6330F833FBA2575DFAF5B5F28BC54FF2BA81E7A47313C15482B605E66BB38C6198F1392104080FBE78B86B1BC9A6FB881F5C7820147E6BA14B81ACCF20CAE96641094C216902EA5C125F6C935A150D7C9ACC5D9E2E5D90E38C0503AA9426017C76AAFCD5261B506274EC13A9679FB09796027A4BB759D928279B94D841A097393BF7E5BD69A496CC3DECD2B0F07F83392AADE33DC51B2A84F6A07635DC0EF57A9AD5959B6A50B7BA509AD5B11FAD26B419F9F1E3F9C7329B5A953D7CC87B2DE210611CF52A639EF2B3908012CB88E1D6F57625079CB103D6C98101A11BD2233B65602CA3049BD320520419F76B061E3598DE38152C88767D1A24FBD02BB10C38EACAE317DE6BB287B4D2CAE5DA0214965D8773778626E9B972859D8482B8D0547E4F56DFF87681D5BC5120F613FBBD91E1F14E6DEFE672E2A7EABCBBB9B11082C5E700AA0B1F7C1785FCED19A93AFE7C59FA2519BCDEB494C3D13B2125F385323B816C68F8F5628C7C2ABFD0278A337073DA74D16099698C4B114E8A8CE344E0A15D0FC7ED497B001D53D4C96DC3954D3B4B956CB9D2A272C51F1559B22904B40CC8531E40CC412C68CB6EEA4A4090B38E2797329985467E818A524D3228EACAE7825D3DAD2EAA422FDC77AED71A205DA7838D945E7FEC37E4DCA67E504CE35E5B045F56F1E8D7529EBD6F1AF7B6E939E2B7AB4027D37A5135D172DA1AF9CA2F728A6F37DE60DD23D97D11E75AB1FD51F8E9A1397E5822159DB583802B32EEBB4567ECE3746D1AE33314785643DD2A0741E7F1BF2D261F22124E8DDD08C640A48B54717517C21CD325328BC239CA028B2630D063C8CC20BE9BDB48502DADDE73FFED5963816533E020AED1208536255B1CCE985433127FF4F04D5B1E2F2108704B8B966588C0156AFC2AE192986FBEC443BAEF6CB85A6F29C7792405A24114710AE1C746444FDF5FB659E5E346826207B8C54463A0617CE17FF33E40F931FE576715C932EF29FD76B04A69B58E0303D8EF25678C8B70AF12E9045591C04E8B77106940415177E868593A09C7E14619A4B332F9ADC3A658B86017F32656C5429C115E110037A8CC7E544677D2DD239A59D54D0F3C7460EC15208346BA56DF5086C5DBCC41E0C95FCB6861C2C0C32AAF3454EFEE2FFBA214B430EF248A59B32444D8D0D3DB87C9D4B1536D157728EE7585EF532776A003A023C0AB0E9FF557108C390684D565A665063266AE6670ED53B0FAF8FF67829BB737825B153A9338CBE3DF1A462849B93A81F84ED07BE6D6240003274737F618DCB26E48252CE4204DD3139FF6876F43B305D835620FEDF79AA67433DC25287320E9917967B70B2D866D17B698BFFF2B3AB9514949E58B57C68A45412C1FC421C768BF5EE8A10C8AEF56926F51EC62C11569F31AA517868E5CAD89E958066EB9EDD7271B31CB4B1D6CE211225AEB5B57F749719DA07ECBEFE03881DDE3D81E4135F2DC81AF779776C1B8057162A6C982FBB4DA6A9AD284AB10C70022044F46D400BF6AD7182D197789983BE99227979A1334BA149D869BA1C4088123435BF978541356DAF171F33ADB1C97907A0FB5845074A85D26F546135AED0F91BE4539C12BF9411E4B556F687D069DB6B21FE2B7F321887448CEA55DB19FBB8B0482A55AEC16738D74CD265093836BE99D4FB53E9B014B037CDBFE9", - "sk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE003B9AC2C1422A1AE802DDD7464D3F32729A3C7DE894D506ACAD25CEB372EA3149C98780DCD1314BAA29B9B807754C47DE5DCA954064F28528B815FE27B79AC506B3AD7629D2C971AB8F282E0C6E7E5548EE0E113242B7A0E064A6DBCE30C5619B19800889A04404B50013C088C1302962124CD3B4910A352C43123119996522185202C38523440D90244A1A30224428618106291897680A200908326A44A44C4490218A16689AA8511AA52C62468D04C340D3862860A46013187084948C63C04404A92820082043162A23292D1AB12948B60921883100C53000C48CD98268E1304C6332450C328618083191980D10B8709B302264040893A48C21C9700C35715B000D143122CC98102104809B28641C308021307118335024254408178CC00848844490489830CA440009195119230C52200E4906321C154E194885132549A3000408156D20410CDA4252C1348C00316943822464946D1C81110196214B0200CA2884CC466451186A181000A4982160B06803946C94485180404692222C23446998264D1C01085202208AA6080A316193400E9CC81181322E21158484C24100227254226258069248484411270404C011928245A1C68CE33266C138725A86010CC99084340858A86080C070D026629B302A04296904108D0BB904504628504824D04805A24802C3208CA014004138214B240104B5494200000C2428124084A220449B069063C0888C14214912105416242087445010850CB564DB2441D042299A168A21B44C13B77010C085190269CC40611C4846980625601446E4226224272262242944C62D08318420322104B4610A3812D92844A40820CCA8290B21310A3429032140C1A26C8A161252A664A3B251042951C4049163B02D1444308C40660C400C01A52C09942D62C61103985019104D19A828D38640C0306554A671E0B4859B8610043669D0462918A371402249004385CB4028893666412269A42851D98029140721DA80911B26505BA0609942715088491023095A902122278E43B2700CC94CA402709240100A397002360E113041D8402D1B246DC392614C868D21B800D3242212C82112998509160C5AA22409344210A22403428CC0B28D12B66963340DCCB065A112114A3869CC148158440954A6800CA805C4388A8406019B322D831290090260A1288858104124400219344818A04D001062132250E338219A962153088051260199C4281BB97104978404052CA0C210D3428181424D61846C5A30491BC224C02028CA922D4A90100427864C962109194514822C11A69113B80403187001A2515214495A0230CB302C94102C00498609A025C2124C1B026940A444411662022528DCA22D0016425830665B8624D42448DB260C4C088501904921244154068402434A244205401448CA4484C0420C9826049CA205D1C2511301861CA150D902500C39868C0031220548D31081124805D1086962382C0A23709B4472E3486E22967014336CD8902903004963208A039125088921C0820C994032C2344E4B9869098044E4046994200999246D09A96001292DC842288A3402E408700C236E0A054964442A82C800024831CB90501C056812122CD0800C594861CBA6099CC08142B80024418A94204042144D19466218050924336AD400611248328A047293B46962C27141A68944963162304683426C00192209464D8B0649E1B070424431C180659C002411A83113212C4B46281B180D884270D1B00D90C845DAC248591426224400C2944150C804180000CBA62419021010890C18222162A881C89248D3942082067209A8900C498A41862819C5809A184D14102E2212520008120C334563C63010934C60C631DC400E98825060022AD22240E4062DDB320ECA324ED4182408C3284AC268E28040A1C86451C265CB166023094C820468D9222E1C499242242100370EC812726408250A202A58240459164C08173000460512904003072152C0641C836D9C322E11158A1035885AA08DD9804803B64C0110651086401101420AC164DB224D64B25102360D93463114B668638429C8102494300819370214824588284054A8299014126136120B098CA49828C292454C006063C481C03625CA882D244030D3A82DC9C825D2844800329250A271D3440D223460121312868C5F8620794A050E20D0E1011786240EA664F2F69BB1B7E30EC66B1A4A0BE59B79F2198AD9804483E475E53B3C49CB0CE5EF92912AF440F23B995813D11B59F798E93C9D13539817C7AC68CAD1AA1AC27656BD0C4797E9C8EC17784C1A327A9DFEAF4D6191EECDAFE049B733FE39D5EB4000936FEEFCF82928E9F94CFD5CF4C1E3DEB1433A47F6D328B5E83DD156D0182DC692347591AA6F732CFBE982935FD1846CACF4CB8515C55AB85EE5AD44CB09D3269E2E6D11780961FD131D5E6FBF89849F47F2B71D8283FF25385E52B07DBB266C674CEE3D0B5DF5A56D8BDCDCFAAEE6A248E71DB1345AFC597CA830A1A35B4396EF4C1ADF9ED01BCE9B6EB637FA24AA160B9076BAE30559F8B29DEDB3D25B79064AB0CF8B8D70ADDDEB8B174248D5AEA4D18DE43B8938CDD2ACBA5477BD4AACC3CE595E5D269FE675210D23152B04710F368428794A75F49B683ED20DD647515777955A8CB38A36AFCD2CE0ACEC4F0DFE807702D1EB3BDE72E9E085AA4E09EB1B0947413852EC3C0AC52F06CB959C85394EB3748119EDBE6C80D2D8F792CE0D915E4F4B151EFB135E7F4DC97D858141C57F70417B43A6A126956978D78EFB9F037243B4CB41DF968B7EE5B52087F05AA9FE487BD16C0347CF1335760BD2398AD54DDA00A5AAC446D80B1C7998C602192ADAFCB809D14EE328641BA3AA00F8D29C3A848ACBDC1946BC0D35E0BE0F8F7E3DA3F68D9FA9768F5CF275534A0ECA9E60FCEA38F1E042C316143A767B33ACCAD8C8D66C70C75FD1F0B2586B653AD4AF54E56EF06933EAD31DE365D110B9C4A2A98BCBA165CAFE386F887C72156EB14FF0DAD665616CE3CE65C1904F2C1747B2EC2B5C9D6776BCD79E5AC64B7933BDDEDEDDBBC725BFDBCCDE2FB375AE2BE3537BDF89BF4C25F83A49D6A6A8D0761CF39D620C53ED837D198255CF5B910A6DB57877DF92D8BB6E9C526B8C4EC93100DEE0500A210C984583E1538160EDAC2C6F866E7F5D99D7B1B81582F5D0EBBF2786E3F556013BA9B6F656EB798838EA0579201A95D56BBC3BCDB9511AFBD4D81288896F87108C077F1A81A3BD297BB124A80086890242995E03CF42A0C21E272A9AFA1DC103463D2AB494F7D017686D31894DD2F6EBB0C3CB6223EC79C65D45C1B0D4EF1961F16D653FCF25977B651EC51A13AE8D4A3472EE71969A7A936F5DBBB9396A46D97642358CAF4894C9A6DF84A59C5962A6990A76F0614890169F001870D49CF2E75008CC4A5D85E72DE2D6CF3FA71852253522FE8B0E423CB417A38EB78C8763C3720C04E67FF88979EBA09E34538BB523B99B8E34167412F77AEA894D83ACF946FC054D0AF47295E51ED83F7486940A4D41C04AD7EBEE610BF1D03FA54071D51A1509E4F49163A25081BE8790D087F5F4F05C88550FCA9BF99C9BE5953D51DD0845C93E41EEEF62E0794B2927C4F5ED9BD3E34EA9200A79DDEB4B2D8F305FE05F827C7E2ED186341CB5D1152FC80104E0E13683D941294C778417164B684A976E56E78DA4D17C3C73229314870B85C455C23B830B9A28A3D8C0B566426DC169F326ABCE2EFFF39E9B199AE5C1292B6F2EF37AF1DEA9272C8D5423DF8A5632F991E14DCA2514788B62BE164828E9ACB893DDA602A5E2FB9EFCBEFD95ABFB82D2B02D49CC53084A49AB1BEC23E5B4C8E714CB03405F1BCF7E11BB59729DDC0B7BEFB291276DCEDACAAD39A2F01C7DC98B9E065EAFED1CC8CE3E848080A2FC5B98C9F6BF5040273342F0312F8B9844594A503DD3E6AF1C9E35C1032A4A8A5E7BF33A82F35E16EDF8C60C90021D8C0BA4C386245DFEF09448431D8C00D1E26EE4D8C77DAA1A705ED4792ACB4EA27C1566FB56683C43BF67842E67534CB3F9677C8AB9D0EEE7827CDEFC223AC948B880B5F1CE9537272932002C1A4DD218F527166EBFB2B2FA2BF37246ECDFDFA72B6DA11C30D1C7D248AD64818F691D59B755DAF71BED9AB5FB52E03622A900D66B4C6384169BDF9EB61C02DF45FB76B1A26F34E938B190861745C021FA876200C7FC8E222DDBFAD8BE781B185424AAAFC65862DB132BEC6D18837A1F58A876C99E63F51420B83F459675612F7ACF80B4EB1DD0721CAA1B4970DA608679C6383E817FE16B66B19181EDFC39270C7E917B1F10EB7A011997E967853B78E00CFD58D224D933CC5A995532DCD4E532E4030515F4A05B331D575DDAC29BAB069F09AF0D173373DB1EC2B6366BB371008A2386FD88BE77F5ED5E198CBE88DF24BC6E393FEBC10C470A72D47C0F834653C9AE800E893C6BA68EA28A838FCBB69C3E964A5FAFC2067DD406B257C98DD3979EC7C7ECBE96A33D85515DA2CB6AA5E1FFF204AF62DD4119A0E48C04A3F2B38660F52964D8D4AEE146A9C53C31906DAD0FD90B5D83B3E31B690A4C4935249981BE1F1A85EC6E0FEE4C88F2D89E2969AB8CBBEB501916558D29EA7C3ECF1C9EF1A04350633B4CDA737DFB151CB5E7361173F3AEDDDF527D73F2F9D5B6213AA68F883E9A2633785EC6BE642A9FD0F21A42F6B9DAABDCD1E6ADBEF64841B59686EAE3EC88EEF0A9CBC12BC012622DF2DD93A86229044AF2F260D2183F51E833EE92D98F0251E3F85FAB74CE367B8B7AA63D3CF8C8BF4D78358BAE0A0241E210AC69353087CC7331357EB4450F9509CFE595F54032EE057754A8EDD746CB9282E768DC6B830C5B4A219343AD124EDB3BBC42505566A7038C959BC35585B6055F1968DA243F778F4E46DB462ABEB93B81243C31EB59622EDF81F06CCC61D2A6EA73E109C387915F277BCF1FC11105BBA70293C0FAB5C065F23BAA19290A302F08091107A4B1D568852622098383427760EF8F2928625BDDA5F514C5ADE959891EF2959F248A3532BF9D30E714059EBDEC958708F8A83C268BEF2682D603CA886347E198FD68233999C77D30D7455DE6BCFD0144277062B304BEF0E34C5A9D8D780D29EC2321E07340771C46360483ADCAF12D5B79FDBFE2856ACE8859F6B12414B3F7E8BB5813498960F34FDC64FC848579CAF9DCCF19B4FB825ED5716DCCCD6872CBDE3831D67384942CD8A9EC4BBFEF5706B8F9F05FE1E8FE69D3EA6A8621C22144177B1C1259E1A79DFDF89728887BEF1A70482556831B672440E13FE3E3FC8204A02EA1EFF19D95253887285BFBEA16A0F219EFBCEC30A8AE86589A5703103A8A393FA6F6B657704AC677C14CD10D3D62D13FBD378C2DDA325B61B85952D51293871E1FCDC948C77BEAE9A6F0E87CE1A8051C8F8087685C12624BDF58380ED66F55B43DDD6D362173A5BD389859C17D95ECE3AB732639FFE451CD103EE4854DB2F39614F658BAA384BC9948D0714EB48A887143E7A1FA4B690C22B492A70C612B59FFD2D6B3B5E99C2003E2C359B1E62DCB620C7A246A7B9B3246131556F2F3D513A23C6A9FD2280ED686D767CCD01754EB4C99692F2B380C36081344C1D35EE1949736B6976F4852CFBE64FABCF11B9AFB828576B4F9787AA7D03E84598A7143EF7311FAF2970E23ED4C173F985D6450165AE3E241A18234E74FF3DDB921A5300B1C4FB6E432E698F53F66E38C07BCD6E77605DF4624D579076292DE1CE6FC6F0081A38BD92D39B24B73BAC1C52BD68E9181D3DCD0AC7534DB48901E5984F9902557BFA231B2EA28C3183262A1B2221F7426EA88A5816093A5CAE2CD5D59A9390FC93A2956944B064CF013BCDB67FB423D1328D2C6D7BA329013FA2D30EFD69FDCA1A95EA6D06C7363534B2F3F7DAAFA296EAA09B3668E9CF82D9BA959B32F3CAD3C10C6EA48611554539C37DF6BCA3385EAD3FCFF96D372B42393B73C8DAAAA31506EE0527B7FB3E593DCCCA57C8FBBD4A3C7F8A53899869132FBC3E4050607BBFE29C675E3945E74A31CD531BA7AEB2E2F0CD990B8F983A90DFEA0568F0677EA9563F7C479DE968940CF242992692865CFDA89FA078BBEF49CE4575BDFB380366011C8435F12B42D9AB99AB6A31912C4354149D723101D1365A65E7CC68D82E30517773902FB38DDA2B324E7208E987ED287D092E7662A430241BFCA552D314127E38C8597A89519D4F1E62A79465AD5F4EAA3FA77CD98326D2F92CE9852055CECCF62D63CB9D7F198AE085E4D45C8E48FCFFE593AD652D9154167BF3E6195810A445AE158F1F9A6793363AFC1F22CA882FEED3A5F5727CA76477C5F23F0FC8700CDC6A5BCB2B20B4F9266351D304A96A82BF5F314AF685C1C707C92E3E847B7047D689C70B25E5501CAEC9919626F4A0FC81586AF1EC88889B423387D5D95482618A650E80B53B07CACE3228940602E3DB47466CE9BCCB6E4D8AA61C8912583E810B3B2E7E9CB48BD403ECF08D28C70AE0B620859C1F09B61131404C3D5BFFCD860E0F42AB299006230B2876D77DDA91C8C62BD93A844E4B344E3255EEA531C6C458D04ABDB0FAEF2D1C0B4C55F570A5A51023F4D4EFFF59F9ABE17922FE732CA71BCD434AD7710B84CD4AC9F2507A06826562AD7F647826F9DBBE4EDD23F124369DB8526FC2B4D52F0741415F972BEF6A935BD812A56C8221B7DEF0F5106BC01E913E3D43DB86C2BB4C7E0762663C6DE788721C2AA07F8954887E2142F2E914A099EFC0AEE1339210D3E53DA3ECF88624B1119BE34010B886C80F51D1850838F2150E72B042AF32899C0D3D7B02A57F8CF263A369562E4E945A31282A502A95EE9BB0316C6861006DAC17F936F54C4C7" - }, - { - "tcId": 52, - "deferred": false, - "seed": "29B4987C62218C19C77D695EB904AFFAA1BFEF6A52F138604CDAB1534E66DC10", - "pk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB459F1B080DCCA1E39FA04CC66B9DCD4A6CDD2FDC25B96E87D778C068A41D7D4AB8FFA0E156AEF370568021A0F56EC60853AA4579F7C7151A31A7A8E5257D791D06ED11CB264B658467E82EC5EFEEB6FA224577EEB84D4453C82D821B87771FE57B10526B6B003E94F9CC812731C08A4B9FFCE90A06AD3134BDA3CF4E7E46DA7BC775B95116E96B53817CDA3FD3BC4D6F612C52BC2EEEE4153159B6D223E7A7B20EAF926C822DD064375FD26CEE2DA8DBA4665409D5A4F38BA2464D393FA00258379038331E4FCE0115988C634A95656888EB26E95049435440F42006C3515C7BCF4EBD138792B163ED11ECB45719D9B7821D6F7768B631D67DC614CF595C42FD2255252152C38190A5E41BC5868839EFD2E12DD73AFB61E8719C0ABC10679249DA931B4BBA405A46C3C112A4004A8E3A273965DB3AEBD8CA5D2BD12584160CB21369B1C5163D111DDBFC040CECDAE8B580B038B0D476211B05414A04B72AEA2FF2BE302422CA22F77CC5E4B576BDB838FBCDE65606F841030C2EBEB821619EE7C3C60C82BCBC3D55B0150A72A95EB2363121B925414138674A0619E128EC73EE4A9868D257F79F27658657CB72D9987FD03826C38DE6509F97B25144E4D0FAB4F40A3C152CCEDD908C50F8EB12E775CF512337BE1DB1AE9B320541EFC0DBC70ADC7C50494295C11D5770D6AECEAE9EEDDA468AE90800474D80B5BAA4CFDFA0A56F3C120C8A2397F31C429F915D1E748539C2A60BF05FA043E93D503FFFFD538D5B22BC0FE8498DCF20EDEBFB9FB973CB00EFFB3B65DE718292D783A16BF01301AD2EE546D48C0F44A05323EB15137C0527CB1A55775A6BE5B0F3862BD8EDDB3CD54F9AFABC42916DB1473DCDF9FB115A64F8EE011F2CA6D11528384B3757711ACA40979C23E65DF41F8D4B2D593C1351B713AF8421970D9ACD3F7E7ABFC764B8CD985159A78205F20C7A478CD987A18325F20D30C33B172E94A7C8F3B097A0627EFB6DDF787973F4B410EBF38E3215B59A4C218FCB5973A378D9A2CEE29986A61B841069BAC816147D0D8DB1BFC8E7E0FE811B589484F19FFD03890861703A27A0C9D451048C925C40C888410044F7420FC25B6B79F99E1055BE964968C354C917F3F981F7B67D1AB451E127CB50E5A1B8C3F179C3FF2175DE548D1137297555BE12489E6F3CF2831DD0E45F2E4151011DBCFB8D55AB280C0F0B5A81B492A33C674BE15221A990B800D9CD5DA9048FDB938633A3BA965398D8FF1AB77F301ADF74FB7AF818E4ECF587416D1CF1BD0F50A65D5EE7EE34E1B6388A3FFF8063B12551BE96AD882EA8D4DEBD9E7DEB05990221114784E7D1092FC01F7BEE9EABD72D3F49E572BF79C771F3E912935C2C71F61BF53EEED86D4FE1D85D702E0CD0D322A92C39935C9ECDC838242C3C97B708A40CC8311F72127FA66F6B63F640C1499F1C70AF48179629E404ABDD56518268BDF1B55F3A6A61E4836B881CFE7B64A9663402FF2DDA2997BE6A557580477ADDC419D5932324306F4BBD3E014CDD8D8FC9102D1431BD895B0809F8BF9214932E915FA0CD1A67A00DFBAC207189D9DCC0A5E1842B92233B8336F19868F29EBD31064EA8227E157942ECBB4C05D40926B4497F277394A7625DE21518C1CF3880F6E23A0A18918BC441A8E7A2E63DE4A37EC35E559FC5FB0CC0E016CC7FE06752866DFB1117B07B635663F39974FD138700545F6B64B2AE401EF894DE97FBCCD34ACBD5CA3AB9A63864E2B0B5B12306065268BF0427478CA944BCF25B2AD50BA6D6481AD0D40EADF2977F12D028421AFF4556B7C450BD8BEEBC697005FC656051E8EBEB7F288361DA5F91AED8F578DF23BB964C68107E0FD6B4C022779F84D78B31F2D152B07D1DA564D425484A0A5F223C4EDE705CAA2652179FBC9A65BA065039E2D531B80645FF9F54FB131F697FA80277B743F33588636A771CD9DDBD0511FAB5F1642A02E043AAC57618887534FBE5EFD1441028BA58D68A390A3DF8EBCBAE896170BAF3E352DB8C2857DD5EFA25E2695C157234115D136631CA96CACF71D6DAD9138B86366FF62C30064EF467ED753D8560E47EBAB157E5EFE8115907092BFC06DA6F33FF14AD29573D61EFB73651AB2B515E67E9215DDF86BC52D2DBF2A4206AEFC55411784D8A44291AC7EE56E9D124E1E69B0C5DC4E418D88D3AEEC568DC2CAB4D812B124C7CD91FA8613AB0A5CFCD6F668075DC4069AAA37DC3C7EA67C184E02B5BB33D604C983CCB9ECEE5D4B6AF74E6F44932937425B18438F3D5F358BDCA002F8E0596EF63BB934A91B0DBB69D9B3830A5CF6E1DFEC05629AEBF50F31D2EBBD9ED0894617878F1B9ED88F0F718D765CEF17A06DC288484062533681506E440A3C0E84C90119859C0978D612F0C062BE8FC5FEF3A4759C9E6193C66B56FCCFFBB6D44C713B748BD4C4A4FABB9DA38468CB4300437E5258C383EF438323F23CFC1D6C77304EAB8629A8910CDBB91C3B5C6EB81DABD2240B62E0D3C60C25554150F33387461C514A258DD2FBC1EE8E39DA5BAA6AB3E26AAD009EB78906B488E41ED03EFEDE7D7F8E67605D3C3131F4FE41C79F9C146B6BF51C56734BBE8961421DED7C16A44730093AE312563B6D98305DF2EA0527E797DCB46330690ADACA60C4A240CC42F770375EC7A49800FC573D94E168B053DE9B5B485A530BE485EE5291301D8A70F1FAAE35B49274BF0739E0E5DE495FFD791B6A3C5DB7D81BD7EBA6DD2D9E326DF27F2DC957943B5BCCCF7A616B41B2DCF2269B9AAC96CC06337FECCAD0A870F0DF3F1F1E99E45869ABD22282EE80603DACADC28288B4D3BCD5FDB39C176EE3E92592310B3A7D42B58AA477D832E113D696BDC4E2A5946410803F24203EE93C13BF380F4C84E2C62722F75851E54B0718FF23DFFC937BD3D1D2D787673E60BD218C102B572C874EE3F5971EF7F24EA5EF2A093B6813718E526806F270F7712117AD6BA1A91D1A3CA817F66B0F354BE66DA05A2EF3B9D05685C107C74E09EA8BBFDD182A1C7A6AB9191224E4BA13AF29076652B79419E11060A0BCC68EF8F97598888C12BA214AB25FFE68298A959B0CC755F00D6FF2688E20451728C51AC2FC96F53115591845AC9E330AED88A7387B5F73A136E598041F7E81BA18321A0E620F088A8A882C691E9D8F99E4C00AC849B3057069F9A5A0024E3015D613B773AEA1E1581AA57FFC246E5EAC3DA2A84A4E48B60BCFA9EC42686ED217469CDEC1912ECD07A5BAB69FE67BE98515D200022B408ACB03E2E927E3A77E4DFF29AAAE0D1DE55779FBE73FFD37FDCE0A3FEACB64DF225FA31324C3E276BCD4753A2594032FCD27256ED4F34DD2BA992C3AAEFCC89F89D9B46635321368F2DB71A3F9612BEFDB641A6B33DC3D8AA317476BC805959261426F7331DEAA84B8C6BD2142B3077BA40A9284B6DBE7D6C92DE0A99D0C1BA619946BFE2537BC7AA29BA4347AD4FF2F5EBB554E740E49744E3200B7562CAEBB9FF565990B6C79E917884F162973DA858811C0A8D2799F65AA7B3CC8AFEAB97204EAEB83EBFBC6A688E48E7FCCDFF21987AD436DF23C16E27F9715F7660884E553421292862B5CDB5A246B13E75F5677DB14EB5802441A3F01F", - "sk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB45F5A174EAF47F9C8BB723ECAE888081EF19773FD058691588480FE23247C9886F403733B8A4D5923E737E3EC5A5BC019D015672BF421BDB6A830CE2F9D229B6D2275C41BB2F14A0B5632D21945070EE1653E97CC251C8CDFCF4068211CB6A24D68A1290123730C4B87141040164442E24B4251B05251A248C94166EE33450844251234085591286DC08915CB870C2326A2497109186095CB2101BB2485C445261344C591012D9286023950DC0266220C70100108413A869C2322942C62520202182948908153153166CCBA0000944501AA90412318851427254B66002222A209130182344931629C80689E1B82101426D52242C1C13855322229B22916290909244308A2861E0A4518B222813111218098100076A1921419302908824621832280C898CD434000A800C22238CC8981181046D13899048024E0386204342699C44650CC2895A882559A06812316C1127680A394648B651DC384882102DC2364A02A12C5BC02C24A50118912160A64D20219100164620400150321011A2808A360E94124C1A1525C2C88C43248CD0266109076498B401C1484E04A010620201DCB0818C066624170222151251327291800024272E2009450AB9101400668410260CA25000828198348854060E9B36321C87040093444A300DDB84899A484A1B474513805053B840A38431412429CBC248CB3646A1340E18A269C9926D48128E04183049C8448C92800A46450CA05102184D19150108B8315A060813446A5B48655494411001689A448800305012070152442CD83080C0A22581226A194500489250CB82851394484A1051C3046D89124D02922C2313400AB14CA3B4241B228AA012204C0401A144898C4271641226C8028A884600E10445C808699A00804A3001DB102618B40D0C3204DC8665D898499B140964844161862D10808510016C22000DE0A830C418044CC049923485C03671A3022103A16DE0207112A7640815208AA4044C164EA12066D98001233730C3182220460410346890B42454424444B89042C888DCC29090106D13464C98C66443048582362D620009D0962812C02C88B00C5BA805A2C8619A84694008321B87644228011BA74D081761D4228E82006A5A420E5CB86101B6055B32668800318010901BA631C0401101443010450111A728843426DC90648C306481300A1289681CB92122472E21482A242705E312401B994114808C4B40104C1681584488A24672D3021121444552425108172C4A902188120221A02841822D58224420C500E00030129844E04231D31226CA960D0B4909CC480181262613248D98182C18448CD39200A3C46888102223136423238081A22C582009DC90445A148EC93291E1463122C981A02462181384DBC285E100905A10655B262982B09180C600E0986059306D18190614276D0C24851110200429894B2288C01080A2160A48B08C62304EC0446D4114211C3392A102891C23260B1209D8340422C224D4368D041451539021E1C2608A841114132920B90D984292C4361203909093C84493009221156523257092106E14C3701AA470E146209096280B342D18078D1A373110831083102DA20470822010430860501610D1447288906DDA94245226281025000C334143A04993386624A75182082844C2300BC47121356D0A300EC24240D4024A80302591B860A3042291A08113940C883800D4B670801268620648D848064806602423509A346222433183A6210C04484130844994805838049324286300020CA485C9C05162B28499166D98108183B681C0340961B28541348044064AD8320941022D0A352C983664C288695208850AA01000A22D1C137001A50081928509838891347111222D43862CDB24728CC4645A288A1C826854B04191024003486824346D24336C5C266A8104280BA4501347911122280C4301192124503840CA20315A488A04B8509BC26421450DA1340C634072DA288224C28404006620B729E2A6258094250C4265521040C32882DA1286022586884690D9288C02403123A861C930711828688C0866C90206582088A4A445201560521832C092600A09519404042302219B0620D1C02801122D2089600AB604642051CCA42C51164C21110563C23188C20544444563144A6130888B3860A118904C3852EBFE4A5235C8D8FDACBF1F0546D7E244B119225B648A9D6F84949F1097FF2A302FFD636B8ADCA5B833657227F6432C2409C7BB078696CBF666B7BFA550E7DD1EDF40119D51EBEFA2862A773F05427480464D6279581BC7E8829DEF05EDAFEDBA3894960E2F9C2700C52EC53BA72C8467097E08805A4C23106F3559C1CCE2AA70C23DF45DEAAFA26500E17E93C2A9FA71062E3DD628EC4065F78E192CEE47AF2C01FDC3A495EF01FAAB25C9AEFE9431154CEDBCABA4D2E9793291F52F8AB834129044E3C69DA4F726CB6909DF7FFFD4B7B48C1DE143CCB63E84276CC00595C1DFDA1FF6B134DA457C2B66E893EB6561DE33F96F8426E0E2791A278286A6C5B5155AC2E3B90821828C3546E451945863C0E9E2853F7B44C296C454F991D091B65221C1324809A8F683DA113DE0FF641C9141D68B888E816602F165B46777F1157C4D6C4656A5E99BD0EE46F89047B0C4A509AB2C3BED7A175E45815C16F9065F49C7261959FA0F9CF4B6A5A5742AD6C4D768F7B7AF02E453DABE24AE382DD50458A1D20E4D9F30E98404061F927F26A5B6A677B2957FE4C973B42F2A1A9F61A7C4DBFC4FA590130EBE23E0921760EF05F25D6C7A61E2B0D636FB21537298EEB279D38FD4B85744CEE35D168590C53AC9AF082A1B0C7A46EBE5828C6B98BD89F562C1145DC5A54B4ED8F7997D0E48CF90D56B9569D3A4C4847769BA3D1ED526724ADFAB7229E5CECAB2D08E7FA9B096669D063CA3FD42D2153FEA0E703E23178233435AB81E7588C9BAE343FBFDBE77AEF158DBDCE8E1A4C3A69CDC67F3EA1D4C923118310930CD2B83BF534EBA764635D12E5FC86EBF2560D12DB4B24E4434C9135E4CB7631E0B8AD570C54584BA92B27B54A502FDF57896EEF6054D55E2B15769B53784C8D024EF9B10CF583D99CB4155BB4E3E9B2C28D382952C062F6319D26D7DCB0E946767D13B11CB870265BF829A93DE55E17AE7AC5D706CD0484E62DDE8DC2B16CFE5063EB8327460C516921C312F2C47BE9E71AF239EDC87FB8EB3F2D712609B615FA634CF9991DD10C1897654D5534A537A193741AEE36EA98D768349BE367F63E21EEC6D6A5086C7490E6F6AB0D7776CBA761A28FB5C3FB1DCBB4A5A90F6A8147C80D5254C8870725FEC69C93285A5A974917A7F3E6C7EA58416B814FDFED39AE3AB71A62B0CBB0427EA697DF596784EFD9D650990DFBFD2B5AED08AE76A243497ABAEC5591150616BBA7D7DDAE4D522067062D98FCDDEB0360C2099F13CFC66D001B18C4D1A8CAF7AB4C8F12D9E931F641AECD1F894BBBD3A62E7EC18CDC02C2580625B5334E32E565D4FD9CB7EDC25E9ED12D0DEFFE81E94F62AD696BD3F2BD17585E9E3D87AF16C9EECF24CF61F53669918666F8585A4E2BC34F6205F5DE856BFC767C4D0E2B67622416CCF8CB89A619B65D9B0D002D457C5388314DA854C4CA94EC466B97C8A55DC08C73F7FF0DA6D898B7A77062F9150E322FBE3339C62AA192DEAB57816A27EEA7C9BCA609E79AB10C88B0137811BCE51E17298487C287074A0D1FDB59813BB535AC57FA6DE8178C6CEBA4E6130063DCA5D7E256D173C11E31BC072BA6A70582B3146113DF433F93D74A2A72CF55482A1030DFA0C2C6A0AFDF5E9837D22F7CE89C9A4D81FAF4EEAC6262701B011CAABAD823B5CED6918627F66B1A07C3E5944D53E161AF56478F7598530BFAC4317BB363D4B2B04BC3D0CD938527437C2F88DAE1D447033A315EA49B2ECF62EC6BF95711A57B7B6C0AB04FD6706FC3553A7B726F30C06347F4CF35D989F57AD779DB038280BE50125B9A8AC1A2C84F9B8C7A650A3EA1533F575CA029709E943DD9E1F2ACE7757143A8CB9FBA11025D49CA9CECE240D1B63140C30CE7D0EB2311E5BD9CD7EAA3FE81E93607D14D5D329FD28FDB0E62FB87D448C3C1F85B42FAEE0DC60993EBCFA8D848903E55E2E987D34467400B8F50741EB573BB9FD41A0A5BA61EC07EBDB2675912DE28FECB52A40494245EA078A754C1B9641F4F2B6D7512944A83E8D1A70B7F3E62A13E9C456152F163BA359752A91A8F833373D6CA24EE0901657636FB2DA1E9E0C16A789ED447036002098B7D9D66EF633047792E9CB8C8CD45DA05EB5ED49377F060CB67CC33AD0D609741D0B3DF408F584D83910FDBCED95724714F4334E8C6AAFF680D5AD60C5A1402A97641DC8FA7B1531DEAFD369EFEA623F475694B04E8E5F52FAC99D8BA2D928E60C4D8AF2A68683FE7EE6D82021E35B895D57BF7F4BED6E2DE8B0D1DD0D0662068D4A9674AA65121489ABF8DEF5F2A9F1E2D36A8AAFF54C56E2E6217C7C9DB4B750207C5AA367A25401C7A3C7ADA45E1BF4E3D777D1306755FC0D69830F3BF262B83E727E5415992D6BDECD7EBC6DCE31FCB1EE0B54DDFAF20B522608870C9A0B1C9DA746DAA1E13A451FDD6192EE7E4514B8B99BAE4FA2107CEE404A7BA585FA7E1F1529E66DFC6435A1C26D3CF0CA13836F0B44E8947833F8DCD0DC2FA60C9E6303BB78E1C6E72A3615F9B3719E9F6A0D2F043DBC9AD7BFA803DA6FF03BA5B366B50EA314E42AEFAB8D2861462982115C2C7D6248EC74F7289A3151EEBD3DA0F43B89E9B5C50FBD0955DD803A3109EE451F96F5DBF1F9B42CA04724779F0FBE9D1C672F6BC478E919A07A486732817EC3741F231E9ED25715FB86EA804DC1B23BBF148E20DA21E6301EDAFF8813F5A97BD9F196E40BCCC824281F7C7F0F4A5D396BD2D3AC94A99B0BF24BD7888276A52543B0435091B4E94328164576AE7A572D2C4693DEED54F583D85C783BCD540A1240C40B68AD8DEEAA7255387029653228EC60AF145C2ECDD26A1D0B267695ACDDD490495CCC87BC1013C065357569790FC44001EFCAC9DD18BDF6EF505BF5C4FC555DCFB2A098108A1C06A3400C10248480C8B3836B26CE19BA22EE4C087C687559B6B6EFCBDA275926CF10F151DA7B2A0EC4DC214EAAAB6F93043437B32E0CE139EA665E2CBAFEBE56D6F1B98BC82FB299C381076BD1E1B0564F39FF03795794374269B3321C8E2E9BC6EE8D03084C3BF949E26B759E5A71CCBCE856FD0CE5FE7F0531178B2C80E2F913D777CDF265CA351FD1EEAF2650A2C8A52ADEFE7EFDA688556AC442D9D4EF43AFB177987831AD7ECA98C3042581F2389EBB972BB11C8D6845C8159FFFF7B2B7AD2E77F6FD4FE21E00A528F1C243D84B4793ECD4BE3F94E59B2B0435518B9BE6BD0633E310F254B822A66EAA384D7AC066C4F273254F3A2C00CFCC43C3A52FEFFB2B51CE1564A0CE3682727BBE58D9455533269FCE603C7F6872A6C07BB290C0B8AA95134D55B8D551AD77F071985EDE813578564EADA5632B9AE931EEB24D6966DC6863DD2DEAB2E3D0F4CB3AE862AFEF5B6D4C9288B1B3079C395924C67B03C415E7A8070A6839996C5BAC53E427A61A7EA100CC10F3ABF7D311845DCA174FFD06C3F05B88CD2FF32E9E44659D7E80F40EC56172C68BC5293820886BC47E8339CBBAD03383D099888E668AD95A905373D30CDDF91756C9C7C89F6DCD6E0BC9E9C4ED9A876F1568B49B6CCE9C520110BB205E307ABF68A8FEA783D1FF4BDE01F57A6B1224E9C83FBEA507BF14F77BC27BA0806D48F8A0FA1CC1DC0EEED7FEE5FCBEA5FB609D76413329F54685CEE7E4FDD309114F71F864A26F05A672315150823110947291991437C60902AE0767BBD42C57D6C97F5CCEC62207C8123E750945BA0BB444C894A98DB610ACC5703121CF8A93C7CA9CCDA90EA0938304651EB84D2534F2E67960064F81A41ACFE3560066DEDC1D7F954C01CEC3A8083975829149FFD8A54E3EAB95A076361EB7561EFAA8E678987F381F662B59A49579D9A2453AE756C133EB4460E72218696DF703DCE965AC32CD144C83819076D6D82D8B5451E0FBC384EA3A2C5675F2042F48D1D1A914B384DD0727CCFDF0A07218B3BA7BD10A55A550679C12244059D2DE9F76A4B1855733725EDB2981CF956D22223833FD43B9669BA21B38FE2C6BF49484BB4FE9E5CCD5F883E856DF05525D9E3BC452B73E6CB6DB583E3641D215019D0C48EAAC8C03D646CE537800AE96457CF187D3CD456D13AE4B657FACC6D9F78581F209E94CBD19B6768FBE0F558AB7E2D4938A0D2D92C6C8BCA7A01D7500286756E87C9A55F10BF60E23F7D6039E17CC6340445E297FBB213730455D0A7B33B852E4829D31BFE5DC6AF3CB5916176E4D125863A49592A306B9ED9CDBA4E2F40A4C8F3C85943C10BA10B688DDF847FA2212E374C64148BF6D1D856768696C6C8F04D213065A453530CA6964377687CCB2AF180ECA47260A493C8427CD418E91D38C50FA9ABF904E419A612881CD595821657C95729FDF8D1D965E80D8F8F82C6009A8BFEBA81ACF69503B873F92E557DCA50F87187BFDAE231D0164CA86E58025F51B0BCC8051D9A88313A619B87BAAF7B16EC52808CA8CF9856CB09A58B71FD67FDB4B3A0B88536DC3EE689101CC39F7F0418E3CEA104C62E83DA5631998DE88562499C4D18A98A1DEAB254C74334C325C11EDA989F98548674C19CA942AA95CEBBAC2A593BE1A1595B702B701DD42E89C8E65DFF6E104053815FE2D7D0908CC2698D2B6C26FE981025691A1680727A0D65C37B0D87EAE23CDA4E6EE98F7A981B9CF44B6B2752AD2337E02CEE156BF8968174FBF7EB0574BB62434D69EDE82D49BE6DADB3510026559B7" - }, - { - "tcId": 53, - "deferred": false, - "seed": "9B54B9C91E0201251489E07D1442A42D0BF32189D0C0CA8A2D4871DB25F531FF", - "pk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3BE947BB391590EBCFB93BC00F569874F69780502C80C4EDC87DC9378294EC3D62F584E70AA18C0F1139DAE97590D0C89CF57803A26FD82F264F2CF2A184B2DA47F44E22306B95879CB3A036C918B6166E1408E59D35E2177F6CBD05EBE6F1230FED71A3CA9CA73F3333070A1DF3FFCBBFF32F82EE2ED47285D8F05809240ED1F91873D3D817AF74CAA85BF78EF02EE9B36FF3BEADFEFC436001A219770927C1756A8FCD265721CC8CCD367C7B19A40DBA1C9DEE9611863BED506F42203AEA72EF21026307AF0602437BD5A8E7B1B1F1DED44C4A009E785BD170BC98C839753F076BF7ACFCF3DB89FACDDBE5F5CDDFF76931C0966CD935102FA75A967C67222D5F8DDF2412F0CEDFA4C9FD94C6C58F26BA4954D872229BEA543107613C71994652F9268EBF81862CE4DA0D172233D358823229618803AE54608871866DCE80B988BC82F702A8C16C9A6E58B465C39197432152297524CCB00338067CC08DA6E2AAC288AA9B3AC40493A454ACC7786D6A2F261E86F4FC6A341896C2E1B7EB46AD1E4F35D970B5B4FF1AE8F514F6C78BF27A40EC941DEC16C95D9D91F869B578BF37E5164EE77DB6D38F7E65D9E703C6323750C24C6B41BCA787AD02208421D3DB8D7090FD3D154D9561B9638BC20BD55EABDFBD0F772D590EADA34FADD191F4FCD80C4B0A9EBE8A069270B89FDC2F0C54C5E9D835951E76E4255B9AD8DEA2092E806D7C62BCD7800E175C93420D7D8E3806F2B6F325171A80C34F0EC7AE7C48CF4664BF07675B8C617FB7944795070E7B47EA9BE7509BEC0514439E9DE57E4C6A2A64303176D1BC37632DE696CA7A3785943E299A1B152AC93D1FC8EBD3A451FE780098A13A72F4EFB4A41131549038C38815687150DA19FB3DD1CB611B9196135606169090D426B33C0B267CCB630172BBBAA67ED2817227DBE6FCDE76CFEA14A17A36B034977559C9E8AA525052CBCDCB66E3410DF8D321F3992B02C3CA8FEF477F2E22ACD2B31A89D194CCFCB4C41F8FAB34128EDFF327C80022CB9E15FD41ADEEE69F227CFFD706312AEE2C824FD281D62C31C98B2306D08A39DEE41BFD1CC702E55EA718A0C265E116BE6B87678927373592B6438B7FD490B2810132579BDDCA4FBBCC0764DD245F6D4DDB97943F52A0FCD190C71744C2E6352F4D0D2121ABAB3870994E21D617A96D77C195436B291ECD15E9CD29C6E05617526FCD8F853C8CEF29CEC0549073D4AFF72CB975D3B6F4EC0BB0CEBA04E35E69E702D5E1C671424EDD6A6835E0E9FC9FCD7FF16B90B039BC1B1295F88F724AFC6DF5F70C22A6E7CD16315F5B7DBABEE28B7651EB16293E2F4998A4F4640EA6EFB4C0E8F51B7DF809CD8F53A4C18F4F4EEBDB18F3CE2DD37F12E0931A46B296158A82D6F4980ED9FC9316BFD7C519688C0C4BD22DDE4EED750EA96898481D7790B95907F3D7E9323EC42B59342A52616E288717B8DE4D5550DE95560EF33FAEB2E2A4D9641FD0630F487DB670B9490D8F91F4E2E9DDB7B6B2ED9DABAE448622DC60A5F869C96E12F1B26A77B42FD6F513E9F8C0D53BCB5610EFBAE271B754C735787E9FFC5FE8778E967D713C2C3CFBBAF59B2262F1C4B8C0499EA77CD587A5296A819955781AC371C20E66471CAE28C6B098A6D25216F5CC3F52A258EFD3E22B010DFB5971B5EB004ADEB9D34375B157EBDFD3331B6A9D56D8DADA55AC152C3AE497A36269F44F3180C47EB8C315BC3F3A0C8AA1CC062C487BD917FC3988AA468C63856277620F576CD6B70BA66D3F9377CF20452DD3E7A8890FFCF309D7E5FDE1B2ADB2BB6E96ED3E8F2CD1F075D82599B92F74602A87FE5506E25E2307FA48D0C171E61BE15E10C3EE42398D078EB42049D44B0A343915F3A99547E2E27DA86B6D0B88F9529613412FF6D6AD459F30C1BBAD521E99869F1F01EE7540407D645A7B6ABF590DBF180A85076CF838D89F0BD53CA96759CCD3F11726257FF862A565217B82068BEA4BE94215F0DB4775558FC6D97B7D4F3254A4D733E6604A003C804BD380D6046469E310AB9B07CFBB605A32DF6E1B15734F8C2580D792AE5AD45C13C37D90D893218FB7BC6A449161C0B91B2FE8197C81929EC8823942A2EA8F7C04A307249CD3295B6B529CC87041B6866E9F358B5EF30486D7CE9BB297FE73B2A0BF7FE5D4F7C56281DFF8CA46B5F1DA6A14A15EBE6F6D7DFC4327834E655CE52C310B6DD6D72A9D948A930A11FAA6E57A08A6FB873341A3F1211D0396884C07F785BF4531839AA77EEE2D5BD8D1B767602C01F6CA35FDB0F6A3967C367F88762FFF45A67A4E75C16F744B6E6FBECEDB03B346EBB18B1A35D0F2CF387277CE01F8068DC250E19F0E37FE36783C0D4FF4A1292577DE8F3E81CD769B2D22EAE286E75756ECF31E56B00A57DB2C17750909ED9959946C86E25112ACFAC5F526A331B5E49DECEDAF38EEFD5D5368A8539E49A0766C22CF5F713E6EE058E9BE157805A521FECC934987809B9C5190EBD0E709D1B2EBDB06F925F3203131171ABFE76684849C0A82EC8D66ACD60A24794BD39C18782506BC7F9F7DC6B1BC7EB2D70A3FD7AEF3DB81568C5F6513161D8DCF0B9383DD97207C186572449F7B55806FB564723729394C85291E01C5EC803D8FD2D702BD9F84BAC47E6E659A3FD90D04B4F53A01DEF302898D4EC430BEB2936C70B976355DC2A68D798EDE02F534872E369582E8B4DF771AA3FB15C2602F2487A21EE9DCA0C2ABA12ECBAB2C8B49939180C3E305336EACFDC339F502EC730B55E0FE4227415EDD151811D018FB34839DCDB684C9C8453F681916316DADB8BBB025A6B66DB0C6315C73D0654113CE37FAE29DA59A893C4C7F001DE15F0AE4B59C211EE59808021DC7CCFC2BC8B2C15214B783FC55E8C50A19ABEEC8093D82C3E12058B7023AE561384D9B28307EC60D004BE81512B0D03F02388FCC2878832C1F881251BBD73D3245336E12653445B6CD704A796A284A7A7F1F7F37DD9D22C2B2BE0D3C497E2F25CB95933D154199A32D4971965BE442C914ED7C42F28D33BBB61684AC719EA5F4D7FF7202E3D476519B3CA236A143B1DD22B34F479C0519531BBFF5E1E1D8330B231D588AEFB2BABEE0A1BED4A1D775C5BD5177A8CFDAF83E5B4CE662418D4A13FE34D3875E9EA15BAA45033CFD746673AB16FDE39F31BEF02051CFF7DC335C6B9DD8CBD17CA9B652F01AF2E3044FC3B1F15378A967F023DAB2AFC2CFA577B82DA875E1FAB014728BD7A8948859EE9619EE02DFC85859D28DAD6B8B2AA72F7973D6709D1DCB0C625084771F3EAA12D4B6D091E6E5026845F0C30FEED6BBACD4A9B5D623CA247CD6622D1E18590E5EF3FE9A094263E886E567BD1AFE24D7E263C5B2CDCF03D1FFE2DE85D7C81A7634066B30E0FF49B71234DB9441017954CB05B8BB72C11710A55041C737AD29A58B9EC6E2CD871B56976C389133F45EA4A6C39545AD15BAFD9863A333637F7AAD613BB82E61652A00BF90DB3FA1B4205198A42151DE6A3500F0A770AF589AB63C01299A28F94B9395D652866BDE7505BAD85DBB2B9D56E43D02F679F94B4F0DCDCAEC1487E18B89F96BA1F1890BCEA47E60FB0165092BA684F8381625F83C86FA90F006", - "sk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3B0AC8866103C621D3464AF8A7E67C30C8FA7F66580CDABDB9E6848E611578D0E85F99D936F0B17CDDAD87C4107D0642F26EABDDE9732CE11AE78FACD7532C2868A1A29A6B5A0CDD35F4EA2F536DEB14A7146F4E94F723B69B976F4688FE8B5D22A0B281D1426D18144D1A066403A98808390E010241D32428233764A3C220190322C8C0405A9265C8B82813B789C9089211082AE4B464D018300031644A928812A52DC2280108C58559A86111270912080D4B384621B144994268C0062999228D01A511A2C46882928C24B70D81168ECA0465D920289442329CA00924356059348EC4C46D23C52123A425CA10921441240B424E02C94C6094318C082908260440046249304A21154002180DD282294CB051211406DB2480DA08012125661B96641819125B9649C9406C180004090380CA1210D0444EC2A271D822694B2091DB8251E0A00D0C9788D044091BB020C3C04024C7251849450AC84001164D1BA96960A691C2B2288284818BB44404B90C9C4206D8063198926098846589240800098209B349A0286CA3C428C1145198222919266109A208081152E082895CC06423A641C408721126321431122231700B15868A16426480311B156E023702DB4491A130804114200A119098142519A1519814264B422C0A878DD9386402B33080B25104B785D2120D11C44864A88DE2868D1C2090CA940D0C15500A188011870513988D94A265CB164D1486418B168C88002D14C680A39069989431514866C44286A304302449048C962C0312806124456312806182098B300699A65002942D08C44124C96C000546C2B6098C0025531872CC108C13A0458482080A972554C2886342859C3049CC18929AA82013220AC0282694367049A60850C850A0B22C60B220A4388D1A128008346190366C0094700A0912C8302C41B66859B669D4C2814226699A2404542442A3245203115123234801B2001AB24843B0615806890AB66811B5641230841AB88DDB280A2437645A262164340508075200B7689B988DCA164810B9440B8490E0A41011880494184013B500440060181469540050030864C40062512030C42200C9828900496CDC96404126051B87245036495006029116449A105213A62C528224214690D4364D24014044B628D8264AD0A26C82288AD4C66920A36C49A40440068E63B405141168E0264008884419158C19C62994966110868041C43108458949B030A102851990041A166A8AB631C33085DA1672E2028E119711E128810C8388D21200CA164419C52544468D1134615C946DC0485154808C9C045153040E09380D110248D814880B88719CC60C64142812854801938DD894890284258312698BA828C2A690D4264504B57120468D21462E410241A3C0082030028B442C02264849024D530065CA24465904460A290E11A460D0A020D1140D130185D4B829494684989081DB2290D9B011C4460209182C63484E4314001CA24450B20CE0C48C09C98C8AA28011B06058C20914B9208C384CA0A49124271223112C63807102B31048866DE0882D03488C61A4895C241143282541409118286D54261191B82CD82069A4A229E4304153A20D08C1400182694A440948222D6304066434212490648006418AA40DD094690043819216649408486094715CA24D61248018B8814194200AC650E1468A4CA65192822844140D4B2006CCC84D1C3460D04069208641C4C66DDA904880A2111BB44CC4926DA1B0080C11724C204C93406111494258948920388C89982504A68813412699B6458C148060288A032402A442658AA82C1AC5412288705C882114A78C0A447241402C88180012B48C4BA8640A934CE184400A984DE13070E08404230900CA326249846400378492B08141A629C20621DB162409B74DD9A28D1A8208A3388483B60C8A824D20B48C4BC82C8100640BC4850A054E84B04CC1204C503851131305CBA210040002CCB660DAA8084AA091121121612401D016920CC950849804DC803081A465C986301803321BA1681AC904D9062C042149CB480EA11088D00802E01086D9346C22850C9B420A122948DB0089CB3088D9940891343294C8051B940420226010849114A58CD9341101355020C361A31682630231CC3881DBA809149349038948134210A304094A2688956D861BEC7549AE8CB7B5AACD88780F7B1D1597FA1BE27973CE28C4C0E9F35194AD0E2DF62E622B75E06E7E21AF5FDF3E4908FBA7D0B657FCE0A512FBF13D3C83F16CD3BE385BA075CEE26E68A28502C3C097539430E8F19916B44E53AA7742910B719CF4969D5EE2D246F5CA207AEFEB037E7CCD592094DDB72621C5937813A5B324ED4544200460F4EA7744DECC6D182A604C142D6212EB6F9F90B1AEA0F89EC07D9C083EBE1FD78D3C4C2282E1D5BA47064E8DFE71ED9A7FD7C0F95481F3CF0610CEA3FAD5C4E73789C70AF963A1DFA6DA9DF610BB98630EB4419399AFD1412E0693E33BD24381050FF62883D65150AB1DD0C67F443E5FD247412DB729D2E58453C770F934C475B89B458111DC6268F1CA0E9D143E7F0570D22AB5B7BD9446BFC7DEA9F06383FE1A0BD9E644CAF2B91AC44BFD37DEDAB4237990A3AD448715940001EA30E7219172B64D86E85C1FCA8DFA922B61819BB4BB68FFD44970FFD9CBD6BD2F09FB12E5265A5B0F919F6D4D6D06534FFE792CDF6882DA5D4557B51AAAF3A80A8CEA69E8678E66D1F47592BFF128EAAEBF38C70E8FF7AD31035DA28AF239FE245D2FDD4F853029A65399D5E6B6F4F4CA2D862B62AAEC8EFCC4B05DDCB351DFAAF1F7E7ADD9AF9FF44D2E2A384368200217F48DA0DF5013BECD2462D4BED2359FE44D9612EC6505A76071E116AB5F0F1DE88288DBE97A8B0EA32B9A6FC53695972A8F6B33542457C30C553DE91B118B15A6DB2D3F56FB0CCA91DF79741AF737E88A88A69424F7192EAFB981DF8256989189D75E0C7183E3ADA99CED3913ED35DF5AB82C8FD07D7B67DAB7EF443DF51D82FE87F8CAE103713F88E9B73F649B1D3C8589B71F06517B18502CB230EC27150C072D985A98790DBE1F83BD59421D19CC9E23D845C50CEA8515690944950809CF95FA636AB3509AFA1A7ACD2F6C346CD76362D15907764749F3E16C8BC84186E1FC9FA120F49859F7E4E6C75F7CE19C9C129C72A7CA129D10AD8EB9650DDB304F5F02FD7257DD8D71B97BD9ED47B9111236E3B706AE4800401B77E1E5A541E44DC1D686234884A5F910AAF16C8D23E593A307DA8F1180095D7A707566E9CBB125751499D748A7E1A78108B93DCFC165D2906A1DD9AAE8C5BCFCFD1D5879A8E30B6FC3EE38F470428E8455162261E7FB6F8D5BE329C0FD494492C296DC8A78128478F88BD6E1B2CBBD731ADB947300A82DE410B27C87180032AFBADEFF276BFDC0072179E36053A3F4C031FC2F94116938EF7B2A02CDED2C4C101AC0CBF0F0404BF9246F1E4B71EE2EA0569BA6478C4929DE40C56B075432203D8CD2C0EFAE663001CCB0947CA073C0301A3896793F7FDD0248F7CB4CDB184408FFA24AC8016716A7C40572731CC95DF6954A94BD2E507FCF71A8E250124E29313ACD6AED2EBBCB36ED59F102F706D5E1B79DC3D956F46997B4172C7FE20F550CFA0F1508312CAD73AAE7AC30BADFDE7D2A8B2ACEEA2FC564354276AB61A8F2D6A3CE5D43A5E6496894B66E72DA30370692421D267F04430397C3B9293F7EB11C107C2D2BB007EAB932BF25CA65D050CD061D3653BC1B25B5AFDAD7A9EA9352718CB9584615D8670CC61D7C165D778EB2766930470AC115F488C3767A6B80D987EBEA29839642720275E20602ADD280FFEF51005BE2AFFA3F69BCDC69C7C40FBDB9F8AB2C57E8745A9CA2124FFC3E088B5564C088B71847A2AA574A4251C1F5ED3F02E22A85BFB1AD2B137477439D4BAA4DAB63644A44C0CB121478A2D91E2B7B9D6CD02968EEADCB51BC5450ACAAA81EF9C1A05B475DF46C4D6603C371D6AE3A1E777A789E7205EF7AC574753F60493B81F8E0AD527A6A561F5C1723EB7E9AC1D82658C00F1CC538DD8E5552366FC9A34D0EEE1EEB9C4228C58D2D7132E3599686930BE56B9A59097B2238AC49FF4F6A9F893FBA76F511C6A6126686C0BB6CB946B0D3CF7DAFAC886BEC911564332E773C10ADFFAD490B94EC6545DF90CD12695E79936A7CE77E66C3F2781F6606874BD2E1379A8610B0BEEEF465334A455DC2887D8B35066B496856A5500AE079178EDD320A7AD2F0D350B0B3E78EA658787AD5F4CDD224340E93A06996904F9D5EA21219B871E21DD3BF7BD3BAD750048702059C86584B0E8B4EFB144503609D021C1DBD98F04C84BCE4304C834BB502CBA56A6AAFEAE643F76FBE439033D13F5FC93D8D852710C3CCA4E2507CAE51BB8779C622AE8197CAB5E51C9D11BD38BE4145CE12BFDA8F8B9ADAD8D8033D38143C92ACA69D5F72ADACB8D6BD10D427726D0F51AB7114A174E5187B8F9D114C2F4FB768EA80F74A49CCC642F5DBB7CEF2DAC669E250451CB9AD8EB2A7631E6884934E2A25FD710F3E47726D7709BC89800C6376158917026C299CDF76976624AB877136A19ECEBBBC1C36DE60EBB3CCBD43508EE6CCA750960543C16A0EA3676CAD076DC3464517FBB3B2D929AB2FA80FC0B31BF2026E4FFDBD2C20D2DBB8FA09BD88CB4B3CC124CE260BEDA345EE0232B2034AAE1E1918365878D4A0BA98CD4D7011014FF7569CDE130389A7D59E860AEF59BEB4F4D3259C1B092E68FF8AF679327F4181F6476D54D933B7EA376B1D4C0564D204CBE631C4AD3DB45F3A7CB894AB139BDEEFBAFB6EDDEF0DF6F7FD5EF140882E21CE59AC45417686DF7CA38AC90A7B44DDBE0F085CC397B3B65E6D2524CB2A6D4AE4BC69911CFE84465C9D6B697D28D84C8C28EF60ED5BC34B0EABDAE529CFF3C00F0C706584C48B565CC060A80F6DDB0DAD0799B8907E94B0C29A4E7A8D6CF0C5750DA5EB717B30341352E6046420C7A226A1935BB7F0D25E4067E30B527A55BF410B4335063ABC9BC76A5D885882AF728AD934BC7E55553B9ECA69D97311EB3CFB1DBC28891D3DBD954084E911DCBEEC1056C502385C8EDA9B4ABB93E623132084C5950FCD44725BDB70C9B9187A30DF477E128F143D870A7F02E5D2F20A3F1B034FA05475F58D98A6D8C22FFC0ED3792A1A2DDF00F62CC03CA04060BCA60EBB9CC27C2BB6636BBA116CFD03BB196D85DEEFFE0C2D6359129FE1877F723EA225FEB1E995A34B9A3A75D1E6C0786590E159CDD62B39D084AA5BD2EBC4456E694054922D4FBCBD5335F7F8448ACA08E650D296D45F3511365B5304F1359EEC32E4616C166F938F2F36C790BD577402C4A605149A4B4F8E1A101E97E22AEACFA89273B3C1824B42B0019AFE8C4ED8B7F6A265573E11AF026464BFB2C78532C0AC303EB5D36D88CC33F528E56310300D52481BBB27B7F8C523DC036B2D1A36C002B98BF5F58B4254D097DF7912D4189287A14D7AC1A30691BCB53FB9E86056852075B7278E4A50F76EBABC11761BFC5D2A86B5995B1CAAFCCE5F5B3BA2C195B692743B637E424AD4072C4B5DC6BE4A3DE4E041E72C64FFB9AF9C66353C5BB2A3967830B9CFC9AE5C632A14BB32797BCEC4A595D8761524026F13D237B165CA4240D4972287ABE72AC7F419F37E99047F17D5D9DB57C508AA0730D6D9D2049E19B1EB3C7EFEF2EE719047A777FD281A0960C09BD79443C5891AD8BCB1ED643B9A9F1E66FB5C7EC6DB926CD73DDFF4D39B15E386AD92170C4F678A7BD7FD6EFD600FE082A64AD91E2EDC675DF911B531074660096E85C66005318A3B85CF7E1C5D269C5BAE4096C9E05145C01C9A6294A50B3D4707A93254B0CDAFAB7B0ED1CA6CCB3DDC1FAA5304055C41095C503DD79F86A499F292C473C3B975DBBE53216C85D42E3E5A819E1A947639131CA18CA7831091D64FECA2713B8BA5577BB6B7FFAB6D376856A4D38856651EBF90929784436EE1F09EC9C99A2BE601294AC1C7ADBBC0EB050BC3F728D5D0F3D4831BA4DEE0E4674EBA6C2D26944029B8BBF90891C37A69DE342EC829625544A82C3FD8F61DBC40ECCC6527E06C26868B33BA362FE4E85FD8F76132E9065F6FA1DE7FC0CBB92A3306534AE9FA01256B24ECC2C63854D3F46284D0EFFEE19CE5B7998DD8DCEB38FEFEF074EF35A3748A9E44AB4F75F656FD08866DDC4F58252B25A0232180E8DB2CE8D346A558B03DD71B19D81E5B23BA688099DDAE1D10BF52932FD2EBD360E653BD4C3A254FA4B71F2859757FB024B14356BC00DD2877AF29BB57ACD812C22119F8CB62BA81C946C36B0D4CBE3A1B4810FFB27A47096108AAD74A5A0413D2A1B85286569853AC230BE9E34C78C84FE0F6269685878AA1246A55F37842584EE302301941B9A6CFB8BB4ABFBF3DAE55AD8ABF6CD6CD7B2C881DF7D5DC264A5F61584A990A8D1CCCE1C0CC05881B4358494283964EEFA16E9A47586FB9ECE3B39777DC6C1DE6931C5448C0AE2D6C51924D7F6BFBCBAF485F0F22FA2228A162C13240EB64C050F2EC800E937FA97C77E2854693A4CC83E1773EBA74CAD800F4AC6CE461C9693005BE0B3C288EF1898900466318B96AD247139E5E8D8CCCAEDD20719275E102F50F1CA019692642092CBCB21210EAE0DB708D96E50FF249E6918A628B7834BE30349EDBA515A46B0229E6E7AB1A88C25A7F6A3BDFA84EAAFCB52AA1A143FB09DF7CBF6E39FE1B813AD64FA786155C298D9483C2F9B39CF46F936AF6B95E3BA82356D7C99EDEE47CA00C3DF9A80E8DE0F246C5DE4FEB6C55B457A59CD82AFF7A60E3100D409E3EEBF2E695DD3D047CE2B35D3820AA8D4D7692C299C00B78EE7BA40DE61560CDE3FA77BE3AE68E" - }, - { - "tcId": 54, - "deferred": false, - "seed": "A5B67695D7DBBD6A7B25146E30DC3F577240AED2E4E20158D1E24143698D1178", - "pk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF01B627A36252963C5562CE2AEDC3FC4916914049A29F8C76CD6C52BAAF00A7A4EC403786746B5B4496F0288F9E3F8C6A9927FCB787B53860FD3C5604CB0C0BDC8E62FDDF2B331260AE7F949B77769407A49DC31B2DC7301A39092E0D33C511B7A51AF129C482989ADD0097F5A66E9D5AE2E477A0BADB20105E1629E8AB6730D5BC3E889C7802AFE8439DE26DBE2D7F4A58ED8C9566202690719E286E92CBE0C7CF65749EE602B6E31DE6E6CED9A84AF50790611D383202CE6D01A83032842084163182FFD6B6E901EC74D36AAAC5896BE92833EBB7E3EB266D11A342E0297CC492833DC8B850123AD4C33C60924C402FADF0D392166B3620F906189187BA9D761EEC3226C43F698F2D5F6310357355166FCBDB45EECF917D0E3D0766C5EBC748B58DB09B515529DD320957374CEEB807A2BB38C9511C2CD0AE6462162E2CD28E1513B87973561D5BB9E3FF260F64F9EB2E1B9A1FDBCBE4C9134E3745000ED804C2A3A55D769C6FCBE947D9557E5EC2EB08E9D416FD7345EA46547649E936A51CE643D9518B595AF4E2BD75ECE8D2E04D4A0840C8E8516E25A797C0E9A93FE8B8D31DD314BD271410C85A0CB6755C1FAF225D0CB4B8672CFD6459E65B4F071A9C5A802646F1660F8FC24BA57199DE9257AFEE8C8BA7D6256BDE7E6EF090B5DF3A549856D95C0FAF20CAAA31D07A980A76E638B122BCA0EBDA0820B9779C5524F8A6D2048B4285DEE77A755DF9142E03BD78D2DD07F62894D169F21BFD8798F5F5FB0CF73D7D14BE1536749C0EFB447C253F1ACF93081DBD309BDF7C3DE11A1414A00914A82C0EA649232470B3714E39378FAF4C7178384BF7EBD5E793645EB4D11DDCF00454E62F95C7C6338C8AEE320754DA40AA48F8FA227C5C22775F0D665DB438B7950F7E5CB69743888C5A41331D78605BC5069E273DA0083603578D43D696F54EC21BB61394C5DE4115F1D3531105C5D3047BB102452871CBAC4D78DFB3AFEC545999EBC8BEE5F818DFE0AC009FC62D4B752CCA004EAF4B07FDA82B3DBD3AFA9C65E43EC7AD116BB3BA07F14B2074E34DAB889FF6B9A48541ABBF8B556BD5E16F0AE9BD303AB1224234A0938EFF04D524F146DB003A684C781569C3014D7714A124AB667CEB521A3F6AC60FBA8F5CB620311F4899D922596423EEEB10E8BF9D8CD3CA609469CED630436DF478D959368D0F175E88E5A563556B3628DC43A2D0AE9BDE3431DCD968C1F2A5C7BBA792F86CEC0E3BCC0DF797C128AA551B1383505DD6ECDBE11B086F11DA4A933D9AD88DDBC444DAD18DE114AB44D5512A5341C089A496DE50157232F67438F8B99650436DDC8C4837E2FBA469180C84F2B36D0B4C85BB9E38862306719DB53DE9F30689BA76B42BBD0881084E0C8732023E1C83B41AB9132A7D64332618B7E6E4B084AC61AF78035CACE0FD16D1E586F79FF97810111CD7C73215655ACE992EF34EA6EEBB64F2A392612DFFA868E8430905DCDDE0A3C16B33DAA6A75DBC5FD6421EA72DE15325E05C07FA81E6D71C49CC41489F1BA0B9B95CBCB8A8A8C7A84F47F8823C6C3D3A57FAC5565B805E6E61B1F5E46CADCCBF8F2A33A3C1535FAC6862E996592CB6DED121F5CED4DC2FD06079BCF23747991DCA6ABE74519F59A39DDEF6E3802411FAEA858FC6C7CF7D90351A17C7CE3DFDB3F870C21CAE3149E04B0BD138233DA4EF3FCC1714683181300A01EF5AF0BEC3AD30160F11BD031F950DAC48DC43618A08D3BAB7E36190951F0E4F2892AC5FADCD872C4D1E2E878D65051138AEA899108E16199F9B3D134271B52E316AF09B7578C5ED66BE73DB9D0E68A0553CAE44F68E3E13DC3497680E742204B8F44996C916522C86B44F313DDB26B73B8B049D6FA8EB13784B2E4062FF47FB3CE7CC046C3BE30BE98E242960D7C81B68ACB705A2714DC73916F41156E43015B69C0687C336963DEFD66F56DB93C58F3CB2F075579FEDD47E1185AC5A7586A038C2135EAE0F2F86C6F8F6AFB6650A351ACB622ADFBF2B1D991A12EB7EE3C2DACA56AB6B200E64E0D1F81CC98D0181102477B87D4BF3CDE84EB42C2BA59BBDFDE06C9BE229FE207D9865C941D9D3FD239EDD161FCD62FE98C096435A01F56A5FB73A703778044480B706AA6D0B70CA8DDA70FAA87E63B718CC92A00765AF46BF3983D6D0B4A6B134F4E4D7BE7AE06792429DEF01D28D61B17207956786C0B008262DD4C6A759F497A8DDBCD821DDE864458EF445B4A9E836200525149982BF2A76CC10B8D571187A9E63C36221AF169F6B61E561783F90DBC461D53A05F54E4F0BA20C5F25B85170E680843E484494497F65001722DAF1083C96D7689CE83BC727B27A9E162D32872D1732F64816FA45AAABA864A47D46492A5BEBD45D4E7D5EE5AF5163CFED4B439A03AE80FED99D5977745B56AF125DB2FCED60CB48C4F3FA1B8C7ADB43229BF9CFABD05BCEA82B4B0CC543C45310D2E11ECA9998FD2250C1430F6AA44824484F857FF95BD99550259A8D680D471131ACE5E8C56F5DF7150B2A25144387CEE08FE6237F72618076554BF662504B565204BABA2698EB4F2F7FAF673057FDBDFF119F8BB6B1D394B28A4D87148C1AC976C842E563CFA16C0B7900B162B084A23775F7E961C25A7C50990BB10EC2C46A986B991758DC28EBE9572C1795CBAE8BDB623C7314EF4BE3DFC62E827E3A1E61DD4F9B245D1916AE9A2802311685189DBDBA7ADA866BD2F81B4B5FA49FF8D16C3BCBA223B94D3C52832BED1BBD87753944B3AAF1108FBF3DBAF9367F5FE18E958AE66F1EFDC9A71E7CFBB81F4E88AD8E37E97A407967B3EA89ADFD6FD9D2CD95A6500B39777EF946904A15241399D596BEAF23E41BCCEFCAC92795CDC8B7F6E5E2657BDEFB3FA24349D0E10B03B6AB6C24A5D8260E227755713C3E57D1B5AFCE8F1067D1EF1D93232D59A545EDA53C1FF692668985FABEA4192A6C4B11AB02CF89B64B564958AC4D237C1B739217008201897F93352AAC793A7A1C7511B5ABFA83B0C040922069D71CB1071516333112730AAC7210F3C74B2D45D80B6530147C24E2D9893D5CA662405D70F5D91D5CEF7AE93BA7025B2FD907A86125E68E50A01F34458F318444C643D0DD307CE5B59F12E4B54382D9EED313DC725CA4C553F56A1CC943A5FEE6A5EFEADAFC2ADE956C6FA6FDC0468BB0513DD7301B87F8276029C677FBF38D0A7AEEE19B8423A7DD9A2FF85AD6FEE2978044EB0A31CAC6B74F20F8F379E1E46BC1414837AE5780F31D21AF710914A559D5744457D2F831EFB1ACB39DB7B3E4B126357266DBA8776BCBC8AD39C8E7D7EC6574541CC669DD38AA5C8F61D90DED5F84D662CE2E7292305304D139E65997020579D6CC60C24356223DA1E1AB33C51BDD14A619F8AF8F646DBCD319AECA9AD9C0292FCAB1BD5393122D2C9E23DF817C9971BB81E3887D25D9652BC0BC34D3E11B87226F08C997052D2A3E96FE7BD4C70EDB0837049C51A50C77EDBAEBB842847EA248B1356B1647C7E1ABE36E992B5757723F1116848C52EDC61E21A274A27A94E25037BB0E949C7BF6E01757E283CFB9DDB647989BB473631D7D2B6A421E0BA8F24CE4CFDDC175D69846535879872D99FCB91DF3", - "sk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF014AF666446690104A56370BD7F6719BF71E367577A2A1848656792C8BFB5AE2E1CAAF65980284F4E23A19D6DC9A160480283E3072E9FDA05C6B1F920D405C7C96F4D0D1E111C9CF5715903931D93ADD0A029C126C3EA29CC48B1BE330CD6866568CC43142162101C46D6444860189451CA730C2186C83162511290DC3242858B4400C9030D4904913440688402DD9860501142462061082108E94A0651A374D0C1801A3167051248062C6451B332419C3684B4069121804C4283161223240202D90226C9A2608DB4421E2280A23B98C22472521A124D2A850E48665A1402860944D60382298348622816CD2882120226DDA048490442E8CA01198B00C03B901CA282258968011056948347011468C1911008B204293280861A465C24011C49861A3342058184119A1504B28698A360EA09230D9C0911CB12549226198928D84A288123612948468992212E4364941A40812C26194142162222E4B202D44344013312E420425A2A0805C82684A100CD9C2891A452D8C04691A436520144513C85102A0100B076042B26CE10484C9020260385053342D0C428853B86404486691820DA1302E58186261322D13C44992B0499A442CC3202E53B4890AB14CE19050DB400CE4922423C58901934413C389432620C2A2309A1849218909220541093989DA968409498A4C2471E4260A6432261323201B016602243261366402323000C6890018481CB60DC2480A2206068A10451A2441D0240EC104281A892D83907049084E1997058046921CA8611389290A20322180610A022D5902062311612417709C926DDA06516022000A098553168220274DC2C689C822280C152C1086011385510B996804029262000180C0841A0024D408710999281C902DD2062E00B68CE010921A050201826D52388C232829A148728BA24021859000030422C009144244CAA0441A030993186EC8226CCA106600160E522890E04812A3282EDB9484D0B21013B56D19325210474501327111142102068018C288D1189251268DC2464ED002524A98258940920A280400A00C8A465109B041D02066D40805100208D0B85091386D24418D0840040A448994444C8318318188898946284806414A484C93864CA11489041664C430229A4061D814865C4681211749D1800403956141426D23456ACA203012944D8C480058A28D23C404C8360C2384294C80681A2400A2C81103070518B0205410328B246819C625D4168A92C4601A32218318049B382841B611A3A00148402C19B284020306128529A198090CC78D98C45181882848169141B48CE4160514874D649281D1B804E432020CB201C086009B045053301181B641A2A24C22B40101455082168DC884706046660AB1015C2090DB1872C4347122902962180C89A65043881104386C50148A02828480104183B28402317154B6304AA43118890011404E23476023182E94426683A6481C0670522082E4A82D54A2419422720B1562121086DCC62912114CE3A070D01260A4B62D23114AD8B24D032668D14649642610DC8280DA286882244922048113934D998408CA268A90106C50880100B82522904943006E10298182B641481460901605E0B86D92B04101949102C460A39070E2B291A384209318640A8700C4948590268214C749A1086C110924A12041E0202E43124CA4008092960C139930C33664894281191880530444082949DA92298A088980B021DA126A88C44C22808521A1250C103213026190260D0B29405B488852B22C0080400025846384415A908D1B314D93380A10B1301B398241120D0B0650E2420ED88689C8A0858142841C382412328203C261DC406822910D9A424E94108988082823936512C8916020220126259B84200C05845A344D1C316203946101908192324694462DE0125041320021C970D40065124522608670A4280A4BB02D82C8299B122919B14184A82922C02464C00124060A89148A01C80820C620E4184282B68DC0A86D61A461A3240090826110203042266521444EC2B610C1B48D838411E4266E5002884040491935320BB24CDAA011E1A64522B251C3868164B82CA0B0504092499C80819B348859925183C28D14B48021B5506032410AA16C004209C0062CC2A290E430011C090A214968D4162C0A1085123244C7F415C457066B406B020246804A5CFB387AF746CDE5026AA81A7110CAC17CD438C4054028B3EA5C703646EF389AE1D9A81D6BA2E708F058E4A7A5BDE33563F88B33A72941DCB16794220455B1DA8169E387D521C0A8D2F2D08B030B500193A27E2140EB59D11B2C9115379B45FA7630DEB827E6B0850626819DEF3A85E9479C2B1434E3C39ABA253E56BD1C500772D90A2402BD89A525CBCE62E45F7D213A59E0C61BC98DB7283E3711E449AC5DA6CBDA9E140FE91112EF9728DB78535269F77F38028BF65B9CEF282EBB8ED0D6D16C23F78C2FE6A1B9D6BE06A7D42D003991536BDBA3C9F28221A993D487678DB5747DD4ECA2EF7D0CA9D8CC235192A3666DA395EB597E37B16C5F32F68E2F557DB7C77F0101DE84843A12925D6C3D76F0412B9DA765967D4B2917013CEA751F38EAB0FAC3D8ACFFCC272AC82ABFA37DC339FA4A6D3D36560196B1F3DD59BFC5E078B998C2BDAAE167C4C80FEB38ECD4D7CB9ED838ABBD6D7A093D9B3EA10AE51B6C1C54F84082D1EF05AC2E0841784AAF4F6FC997E43E3FECD50BB333703382048F5C415886AAF3C95A5C1351938B496E8FE0B10F1808BEB61921B0916097BF09BF64D1B263FFA7031AAAA99269C0C5CCBDA0ABCB9D341E87BCE1F3FB0FE594AB152CBEFC3EF60925F95D1112B8078EB30E616C22E05BA9CD77CD5A67301AAAB35157232E7C9DE936FA6D43722CAC883EE29E52EC8D7F4B95CC17E2EE860FA4591550C1E01CC78577B337BD1D8BFE84DD8B95982EED0E023703F242602645672886BC03C4AD2FF64815C916EBE6A33A282E440D9012E70A630DCA4CEE5C65AF2A880B54CBDB44923FBC20B2F5FEAF1C2D9092308E930C3B044F2784902D8AB7A3F65536226180C75B33B236BE642C00F00C94108FAAC067D4E1DE83203CFCF316849EED95DB2ED332A645BCCBF648FC93C895FDBDD4368E4089A5C07BA22B17EC08548925F53B73D021C5CD2A5D0656AA67762C16CB6D5413A6F7168C527E85688FFB064659C7A048D7D7EA0263C275E0E1B3260789A58060895A8B907B2FC200EE8F559443FBF7434D42C35D6E2208FCED553FA75EB4029B95E2C0B3BA401240F2050E3888D9738A5C9F3557243C39D1C133FEBBCB9E08B2D8E7247A2EB1065F4415170D74E74817AED0E26303D38890A8F733D4627ABF548834F74DAFE9468AA3A31045B540449549C617CD8E674E608169EA321B6BA7925DA5CC3AF9FBA32B3C6F73E41C8DC1A8F2F59FC7A266E0009EA2A478C9015FD7DCC160AC6E25A36502F0575A28B6FB60ACB4AEE2B4DD8BD6B058CE9F230E541D6E0EF35A403252736012AB28AD15FD5034D3D388E627EF590840B486FC7665E4360CFDB03FBB01C9C65F2E6788D7E0145598DDA606A24E69C6A6542702FBD214085961532211713D71CFF0AC5BA3AAA2E97B11C7A9929BFE7E050393E126E94E8746ABEE2FC812356A4A442D3B9B18FAC0AC475A3F10A0E614866B113A457293BBDAAF7A5E69D438C411660A99672BBB8D8C1EC1C25138F5003F3CDCA247C34D56E6B6A3A36F9DDA05E64961D4893B51537D61C78044B3C29691F907EAD4E24508F75FA50162B00F0C599E461FA88BC622D6F1DB60163C19B4D1CFBD773D29DF49BEEFCE2E13748AEA33DD426C2EDEBC38F7E3DD6F1140FC79D5B42A96262E8028F8515D2C2B698B5670E658D9D7A1807507DA6F55902CA9745631E0FA7A85842A7D834A236708E09B390A4EB06E43B2978120A8D8EB31351EE66085D11990780E2641A8825C9D55684E1DCB887AF400F70C2006CD6760D5154DC0F3071750B3E547889D4B9A8617A94345BD754082726C381EA0494409A12CB1B1F38DAFDD05C2AB37505C3AA2584CE613866F3540931E341F5CD65A25ACE0B3B0204A09B1B094A8A502A92B7D4006657309611D601CDFEFAC3D748B27030351E5841E4E4C26D7EE937322BA7B33CE13960C3ABB665D14D7329AEBA2F5793AC65CE83D3CEAED892E402178B448654E367823E62F858F2AFE39795CB33DE23688F97793D94D45DF6868CB401E8278CF88149505D9439C9D9102DB9FA43205DC9C9EE056ACCFF52E240E00144C4B39987BE1F7C1D4BD1EC8CC0548D55121CED6ECF8F3E8AEC28762AEDCA7AF154806950ABC2E62C2FB91EE9518F847E4E4923A92EC23A5D67930DB82BCC8AC9F75028E071A226AA2E04A384698FA19A7E05CB1D1F96BD2EE8E3D2DF43BBB071BFB916C22E2A7874372BEF00898B5A49E1BFE2F670259AE8531DB29A717D26E45C3E70CDC7EAC1FD9B4B299ACA741AFBE1E9FED276AFA2BE5A26F7915EAD4160DB608E4927D7EF20B27ED2EA11D0778A784C16771BCB8DA8309162BF023B0F1084ECE6E1F9B54C7FB02534A721F9790392B3CC1BC4A45D55AE8BF40D041451C97CB68B0CD5AC0F99FE8C5B29B8067A0B831A4C1F01CD36B3736C3DBB36EF1375DBDEA234AF41C697C9B1DB05896EE7F7C5DFCFCE2D50236972A57DCA809796D911A174E2D3E9919DA93A324AC4BC87C0A6E9E7E67068D9908BA87DD5C501F46A712F8DF069451C6CB0202BFA81BE9C7EB139BBAE81BC34A057FB48BA38D0A17BE7D41E5DCC429C89543EE5E907B18BC6BC605EDE5061CE12D98D8C1C7675851D3DA2304A2C9666BFEC43C52BB16921DA67DB8D6BFE253FF14921588B596D470FE7B0FADA80C495B54B134A22F88B3E2928C82D63A06CEFC4FBA8205DD726C5F6F69212BCABC83DD0E30B15A20F3958ADD691BA2587A54D5927339786309A7E547F3173DCB861FC697E7904158BF9EEF3F9326B39562670E73F59FA2B9D851FDF775580CD2A0613F07C837095E71BD65EF43290DC39F202B16993E0A78DDBEE6C2D18C561729354E0B820E7375284CAF9B684B252415CECD9F472B3E57A552CBBD9544048DD45781BCE46C3438837AE9648F76CD428854A52FDC237B4CE44D9DCA477A91514932D2634E8E7888D3AEF0440952674632F1ECA2A51D0E7412A25EF12DA34AB2A3C00C0EE546B34450CBEF5B5B420E3D9D27DD8C17FF907CBF57042BA694BC8259395787857AB435F5813102D862E2BA6F653F01776BC2E0F0FD7060FB36C1AFCC21A64624360D19BA9EBB8E3E780CAD1785ABBD8843D472BB30D91173422360336FF44195765B755790280D8D29FEE9729F5444A3BF960B487F0B351E0A3D340FA4EC6E6900F91BB980144273757662CDB2F21C976D1607095848323C9AA30F6AEC830F9B4E568CE46F2B56147DBE0C676A81A8C5BF36AC0A8A21FCCC19E3C44F1AB7D73B2901FD68B1D475D9F492B540F7BF903B643BB536BD26C858EE493502B01DED2AA4C2564C561C0E87049631919E5BBA3CDD2A805A0F79BA9F40B2C8DEE61DCAA4975935052EACC9663DD1E4FB3A9B62C84922016F791EA8CE13789BE56DEB2AB36D187427C860A4E7507D0A8ABB54D52EAD11BF3835578D52C775DAA5112D2392D0C991ED55913139AA026CAB18472458EF7BE5C29992F6A6727D5800980439AD002C1D5D78FDBAB8D7C10B3F9F370D7B152013B128AB2A9E896A1C7E91292B78D3EA1C5E74CF23638EFA30251A5335AACD939B2A562192165AB3CD509FA7855318A52F9A312DC17A52BFF12CE382D878725C5742AEE4B7B34C80E587A05E4D19EDBD180C661CC89953D32B18F19DD0608DD65D415AA9B51B08687F61E73A8F204E55BF61FFDD5EF25C5EFD9A5332E9D81D70383FDF6A137E5B0F816E003079E266A89E40CE0BC721470142DC86E23646F9C14233332369CF3AD37C879C64C905DCB3430A2921FD9421560F2CF8FF0A819F5299938660432BB60CADB0A626761236294FD3E6BBE5D75265E20821BA874679417D92A17078F8A869733AD88F15329982FE21EA39FF935F1E458A8874EBCF16B79CF400E2A252E5D05F61B1C1B1238BD48E256D65F1786B4E2969816C0FBD38A1269AD423D33EEF3E46093555129F4F1E8B79631270F562E1B8C396B5E8CFE71096A174237C8DCEFB2A577495E777FF7BDF8177B4C2397ED36113769A39BB41EB7710DE471FD2D36324D3A3F8320E4F1BF34DF5108520C4D61B0FE7DD7CF5E396757B1FEB791043A6188BC5DCFF3522D80A5AE3D7C1E65B7B419B86A3853F7089F93B7C42976F252C23F0262A681C8C3BDD6FF91E36DCBAD1BF28416F4B7A458538B778F645C22EE027998E09B5824F3057453F2BCA68066615286D430589EAC58BA8F0BFA78263B37E0C3EAB69BC8E8C1E5DACAA84FADC7FADB2D23BC8A24B949FC23CB65668A8D562F03C7DC70BD3C5BA42D83907199B026A2A09758268122CAB97E4C892344F4AAFD0E46356D6FA535C8A89A90ACA4A72E24E27998D16EE58716BC7BACCFD99BC293D029BC976C54230A321184B529D588EE131274102C74A22FAF4AFD3453BF40FC475970D4D6C0AEBD9D219EF8E57FB0B5F9C82B09838D8E24B7B30943027BDE7FB5C9CAAB2C8B1939CC7870F4EBF0B6B68261027B282FD7E6A200601D3E039E6771B8F2CD009A466145AB437A6243F73B1036C786F9F6038D0190C29570830A3B67D418A78311487795E5B47ADDA457D89626D03EF3150A20C6AAD1761E3DD47B51F5BAC74134454EDE11F443CCCB5F8161EB366D4DD6ED93F78D92FFC147F9F793510D799C927630939DD0C2BC565737BC1DEFCBDE3DBD246955B1BE65319673C2745C88618C78D6BBFDE1D4D400D" - }, - { - "tcId": 55, - "deferred": false, - "seed": "1B87631F6ECC4BC8FFD14B2792F3D1691A46C22A26BBC98DEB2554D7FD2522AB", - "pk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F05DBC4579BA8280C83DD2D58FF98104B3FCF0996EFFDD337220B411A7AE227E0938991890F8E7495057295E2D7FB7B8CF1F39C6C59AEC37FE6FB87311D39BAC27EAC5351B11BF84EF91FB0BBEE3E35B26578AB0E38FFDCE479A2972A4DF2D001778C393E64CEA03373328EEF17AA3D0FE7A9C366CD3440501358229177701B96E7B669CC1EE3B4CE04DF63281FAD18FF66EE0DCFA087EE942408064235E4FDDD7D97D8D83E3EE430EE24A11ED96B2AECB9069D9CAC9D2530780499A99F16721E4DAA25F96FD0DC511C597BD071576A5E6E7F911AE6EC7F18FDC9048720E629C419B3B86B09352B4515CE915FF36C997342BF2A194785BAFFC4001C248566050BEF62D089EFE99AC5C6F0DAA2BFEE64070B5E9C04F2312CA8E89C5C04D34A9562BADCE42432A88C27799F297FCC0DE87AC67D62E95668FF38D6E533CAF5B5B54278B5646BCE6D0A82ACEA726E017C42032F8B09AB7DFAF0897E77EB1BF671721F21EE487F5F1BFE267DD47DE4FE32EAB7BF5B2E0E0D20D8570C3A079AC3AEC06E686EA22F3FB5474CDC726517D8A85E42862E0F607B9F0977D4153C90BB7C29A29B8A0552E6D3B8C0EED949945BD4816A73CFD89D59FCB1D2B41050812065E4D7302BB78865439B9EB9B43ACB92E435027A151492AFD484E0D726B01E967854D24C5A889013513C614126E3EC8B6955E32EE4040A467FFDA26C349E0DB3A9D5A0B2AED925E7E8387B0A387FE1C5307200E254236B90D7202655FC3C06C3B4B7BE97CF96EC48A247F550CFF02EB276A841D013DE1315BB2AE74B8B7D05EBEE272895651D99747E437ADA14D73AC327A311F1AEAB23B04F9391D662BF71B04A3D943A90DD88C4926EBF16E4A3D11C9B7CA61F82F5A6EED8BB27EF576558B336599E6A7C4D4E9CF57B8222F82E370258E356BF4CE670B1F8F3EC6226A4A9B66827A75750B58E8C9E5088733CDE9B578AD555C2C9BD5348A285147368EAAA71A8B31FF7E70FFE682683B4E471E54988D242B76CDE527012C7B0B07A83428B40087E297068C60A07C66C49E447D06BB9A669C331570418A4AE6E80A3606B5CFD9097091E5518C3CB835B72A81362A2665864162BD4A72DDF1668515873FCF144D3FFB8D5F0BAA4B66F7FD69F74DE0712458A8F393AF2AC74C6D6F3CAF95593AACD1ACB4367A196E455B94D45E2C411433CFDFA0DF743F709B9CBC27EA3617E288D598F3B56831B3EBB23A93A539FB4112CD03A2FED70A8FC10236F4B716E0BD41465FA958A149184328531F255D9C67474C87D547829385899C3AD7E832C5E6C659E402D2E06F2587C5497E2FCBE8A8E26186F2697CA30183811E39FD5D15B8CF0EED21171B1284740B2D5B8D32D0FFA061D16536ECCA222BBA35C1E7509867F240F72F1784CEB2CF15D0E38D4B9F30058A2EF721F65C303999A614B12766126D78FBF0A69CAAACC462CAD5082273B89B2A72067047253ED7818C0D4B72AFB1D256C37CD4BC2B6172BC68C96DC2C068D9533F97B86BEF6DA7317C217D27B2175491718D08078621CFAC83EA62C9599795E156BE08B5F03D0735C2B8048F777AF9154F534A2890C07F83CFDD9CF8468B79940C0077D39B7D8AC914BA4B561C848147471C0A60A93A29B4DC10ED4FCA90C2832BB159FB02D27B340A0FE663B1472A04CFF2939763034A19EA164180586FC4EB65FB5269324591474ECDDC7949EFC8CE1AD9BC748E5818404E63E44866EEC341E26B0A2B9AFC20ABA61744BD0306A8F9929622CBD81B73C81A8736B49528CE0977005FE82D640EC6034FF3C48B5FED6AE260B99A4A57EBE358172D82A90EADB4D1C316C3E01AD35EFC26F0391FD349990B333C347B27378F78DACB57788D264564E022D732D8632E174B66F91E4147F534F3B5485FDCA75E97F91E2D2C7FB11270000AC0605C947A300E2D3D30F5B35B51712CD369E6E6EB0B8893764E635CA8E65886746150C3AA300CF1F69800DE062DE2E64648533FAA6623ED0D59285AEE2E5518EBE278260A6D3B4DADB9543721E89D7722440BC7549C396DF1A56EEFEE0689D710090A84FE0AB06EFD61DEAF590F5E78D6810097DA74E2FB0852759D03D6023004CC6B5DDE3767FA7695D4E3F1DFACA0904557585C11D6198C2ED3CFDAB074C6D20A622722366ADDCFEAEE60CA40238182E92AB4EC629171216203885F307E1A5EBA8021EDF344D1298064D6992632871F33405C1E3C1067C47DE6EE1E5047FF7D2E03A803B2228FF640E1510D250A7AAF25F4B865697EABC300041370350C2E919F8014DB1B7162718AC693CC0ADE07691C2D967787C816670BA35F9753FB1D30954AC64CAAF4308B56DB027B75FEAEA74CF0B410CE18585685CEDE880ED4180AD470B0BA03F81C62F896BCC1CD19B7D0C506F9517A5A891AD03D062FF5F5CCFED5A6E96F20769692FD5C53C466091F2422A89110BBFB5C26993AE1A5B9506AB0C5349307D05CB3296D66ECED8B478A81BC6FDC6840F62615D6CA202B09731F5712C0D68216F1BBBC569405F349044E05012AA45618B41FE9304D3ABC6E28D1F680835AD46120B7A642116FD7CC91AB87A5F7585365C0FD25BF729494BFE12A9C5BF0E885067CF4B5CDFFF2F52C8F0A39F376E33067BDB64E34608ACF07E16673DAD6D5D33E7265FB88D4F0070388D92DC012C1E51C53638C5DCF7E5A254608987A25333CC8B9B7214843F88179769ACB4B544A744DD69297CD2D8095882D835A4FB3026FB6F821C664E544B37D543B3CA16F49418765897974F0F90F4DD909486684E0CB7F18A55FC8CEA86C5083CC5463F803DEFAFE52218F00478034A9CD4B83746026DF96BA4ED018F9827763359A1D200EDB0730546911A97B60D481C099C0A85EB039BC63F94E271CE865978446E5A5E5FE681F1A7079FCF3D3CAE2583535FDBFDA03BF965D928F0914D3E80A1F53879D3B1AF6381CE65B74F0D43433D0A99E4EA8B8A6E9A78BDD50FDA1A40BD4D10967F4748732AB7532A7D155CC6AA9479832924677096D8FED679462E5FB2B3B70673181409FB79A155BFF1B02EE64B6E68ABE957EB842F7525BD6CA82839BFB365FF23E8F42F37C12071F4A97691AFAB9696A2CFFA97956BCA8E514A4165C00A6AADC7AB61249C5DA346BDD2173974568756D99AE3B9A30ACB15A52B98F71E17B58DF2F9FD2D8D8C11BB83C402DDC816209000865571148430EE351DBBA27C19090BEEF78148CCD9E3A3F5783395EE6ED8EBD1489DDC8570DD798E92336F104D61BA205EAE82E190C9E899CF338B8C45A12C8958E4B53B47496F6118351E348A892E14B9FA1E54467239970497D7F208DB6E112F5E4E57194F9DB93E39AF2E9F35514817A4C4AFA2A543E7F25D759151C5EB3F56EA2A5C2BB352538B45984B06B239E053A0A6598BEEDEB1ABD97BDB21F4BDCE8627CFA0522D78581304D30DC5781CBA5A913EC0F5B4EC9E53FEFAE2F739807911E422193A492B479F100CD9829CAA7E62BD53A997F6533C04328284B2A16B269FE758E8EDDEEF76E1F4ABA2E9ED27C3D630CA83F3792DDBFCE6A41517B8494BD449F602037B67A1B742CBC09C3C13CD441337F0D20E6957BA4A3E64993661ED46573792DC663B62A6", - "sk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F965B3B86DDCC8A3BD84B23A843FFA28A75C1EFC4C51BD35E9C5AA8C6C6533FAB87ED5E5E7FB72A5297E5A8D2C6B87FE1A07A4613F21BE746F8D357FE8B60DC395576CD911592CBEBF452C434EE7B7F9EEF354B0355CAD920C35D9DAF50085136D28640DA401050140CC9162619900C59C63110A34DC1120E09808148180E1C123154248493188A040670CAA43140C64DDC140811428582402D49460EDA2486829460009431A340881C224108B03022B58852322C9446445C140053160DA492814BA62521066A90360564480E1A2950C218614904490A87215384046228519040284A2431CB06416422881347711B024854B84D4804410AB005C1320082084C4B244A1926251C302ADB10328C00856040208CA0098C3210C3A48593C280A3900048808522864051B02419411220488CC4448DDB022DC4964C1B30122193440CC125D106209C2491C4328544B8884AC8100B986920C6658148010A208A92069180406D23C84022023204174D22B271D904241BC3900CA104D2046922840419254A80224C02996002459082444880182022474558B650C3866492445144B62402B00DC8C89051320D4336714BA82408347118110C992002E0048C1041259426054C466453A030D2003119192554840CA0846C8C12464A904920B70860322642142899340EE3326DD2A440519284612289949844DCA44C0C971092A4008B40664B2231D184601AC58CDB406A52B88819B9851CC92449426600B869C4404AD81409831449D3A424842265003100C1043014356C24C9010C176CE4120AE0046684B05152802D5846295482505316911340621B466E10484AE1308CD1982153B860A3C2000018601908888C4804CB1860133286E1A02508332D43308554443058168C1BC5241CB26D18C1892396699CC00153144AE2B0509CA66561C610E4840C44342259146422052241240E04940050B28809A021C0C88C2347724C486D0C054E8B220C08483180C4081B91080A81811BB52CDB326C8B82680C318E60128A00938C20A96862A849223930D9B2488B844DDB1882C41001938401CBB850CC146A03398604B4680B828C99101184288008842DC3A065C49860C3080020164E10410DC8A2841BB14900410A1BC5881430414A886D8426710C1500CB466480382D53B62CA0C024A08284E0C208A00642DB100A14C39192B009A4927180340A03886C2141098A166548122EC326665108068C1266E1B2009032728118658194859B20040B81456242821C82100BA549DA306E44C6111BA548541071D4C0089A402DE0C42183C66023B68181248E98824010388D54426260C089139588CA120284422D8A1812CB14251B4126C1820D9AB8459AA4688A90018BC80D99A2888014305BC00422450610C011C2148D1019260B240159386410319008C380A2388222C708C82032CC406510192160462E22A9248A849100B510D8362524353184848D84A40C1CA6400AC22CA0188D92A42D123709D9322DD33025480250842805A448000B318C1B9228C8100A19315289A84823C90C1C1164940024D90802D99221920468A240892322109446689022110320700A055214B560003970213806CA8040C0B2844C3231D1466901264E9AC28CC3108CD842898CC8415190214402890B93249C264C03A70D21C08CD3C0810CB68D4C3450918488A3C86022447282868911984DD1380C1301910B372013848112A2414A007024326E10416991B86424064C41382893B8641A3165203171DA14291AB905CC060A180960C2C4510924708096040AC82C0B23400B8741C02425D11648D2001124093003412D4A8420D09644DB424D52422809942C10A82DE2A031A2328CA33252231302222026C42400502685519080DC46890A0446241046D9240822426981C28589306C0AC37193848D013092D4B26D10A92100085083364918C10DE3942919B3500B132813046823016C18144121948D90C68501B8844C904DD91864D9228AC9A604181441C4362A13917023174A6400885084051B162A14332D93200C90468D12B19182447199248408188058C86D5CC68463B6050C816D1BC93023A189DB0481DCC648493265834064C11048190629143904CA068DC132018418308296250301508AB64998A628241606C3484D9044482664C6C6B124A2857AE26A5B0547C8D17FD20BDDA77BBA851BFF1E2A3D6F2449A3D7661C42E5F7FE82D17697172DDF3CFB1E3BF29831D5483B46825D43539C4F159D3EA9CA18BAC04196CCFE47BAB835111D405BF52F5CAF365F6E1FC3E6B5AC52CA6F9D04A2DD1B2A9E0A5268790AD507254B22E62F3952282041954DE4CE98460CB4CE67E8CEC031CD430D1E825D39389BE8E1288382C1C1475EFB6EA7A3773B9A25D3A99794B1D073D121B65F5AF9D0733620B5A30DADB57985AAB262E87CC6B1D54EC13213F78791760C9413E273B7215A654A9BB4C0482C291433BD76AFFC47A2AA962B7DE542DE840B99CE6428BFED4B95205E72C0021527E1C5D3E810D91CAFD3C86AA4BD0A40EA7DDC80E1AFDB978EEDEAFF5307AAB7E6FAF6FA25CE431CB75D08099D83D4763B6214E48371AA9AA59E1CB39049CB8665AFE3FA792C5356F9D757019DEE92E18A6CBC33B0407D18427794C8752CABA14C54613AD42B7F17A7C2D6F76FE7891B138B047E8004FBF4DE4EFEAB8CF2148CBF623B41EB4EFEC749236C52138AD9150CA2160A24F9672059E6C50BB1E282722B2A46668638A37601E3291C59C97940D15F916B59871339FB26DE864C6451FA615EEE6FC615BC0FC0BBE440DD431FB61C4A89C381DB8C65C2FC41D3483CC89E16E34BA6EA4D564B053D834504F9BCC93EEF3C6E84F046029BB639BD681D66F58B30EF1CAF54B46F87B9029472B297277774DB9E491A29953E356AF1DDFD874418B04D649B64BBFD74A8723B451ADFF707F95F6EF897A563DFA14673B2870FA588DEA8FF1A66480686B24D918E7D24A70F48C061AEF8E546E71119FBC46838B3F58A908C247A06FBC8F54553700934C6C6189E27319975328E092AA66C228464D21D3AD3DFE4533B7539FBD05D26B245D21DF4401EE265F9300CBA6614A670D8D07D2BDD9B58EEAB9314BD0D8B669DB1736EC4B15714C11EFC6CDBA9022CFEE95F88DCB1C9B94CB9286D4CAC2265BD8AF5067E86190F3CBB14CB37766363C205F5BF5EAE9C53C7F3C8471FE7C8F2ED4E54B2B46530232D4879E8B151D0900B37BD78DC9E3E6E82BCF874B131A4CCA2FA669745EE1875CA3036CE3388102E975BAED3DE91FF7ECD36DBE1A1B9F6E8F015222F173D14758616BE86C322B45C79F7937210199B30FCBA68A92F6715D078DFA45CFE6908AE66611B7854E468C837715907C4C67942F729DFC9DD8ECD36CCCFC80C08483D8B045BB23279696C6279A1AA9A1954BA3C2EB4078368C5CF38E735D6F2233258DEE2DED0DF254E4D29F8E62709F9842349D2C9F5C0FAE386A8007F76BE0E6289C2E44742D80855B198290888C82123141ED6DC69CD9883E932E0473BCB64E83BA3F0DC1E093A64F912FB71154911539775FE594BF9BCA2331D4651EAA5DEC5651EFF2D96758138100768BAA50BB969D4F8BEA490DE88325BCF7EE32960FB59ED0CDDC5E2759404E18EB0D3B5DBDEB0DB7F3F83F5EB30C385083B60AFE529E9934F5BE43DD962FFFCD48D2FB362D8B2FFC91BE657ABE6F4D26CE63B7C10025BC3F22CA472D34E410093C388238C901482960C74D9C616ADD05ECA6DBE268875C59F6C086EBA2E1DBD9A7FCF6288A423719EABEA8CA57C83F2DC11CA0927E2F294EE55D4E61DB87377682130D88C9F30F8863BA646AFDE045168D16BA07EFD56BC30D51F3D53E99200F86C2A9EBD506DD7CB43612119F56E546AFE24306A406483BADD2ACA212918F42847E58191DA91889AB58256DD3A482248917E144CDCDF37F5DDD84D365CF048B7165536791E2EB0FED48DF9F3407C79CC7E9FD5CB2498D1E9332C9FF687FF9F0099F78553CCA3F02DC9BDD3520118DC7026248CB69C70D13A48B04AFA134CA4B1F1AB074D5ED7B36AFF20EE54683D593F6C06F6D643AEA6084BBB0AE9008502502CF8A6CE986A48CB82E20FC64E5C81351E217653162F62BCEF020DE2F3D5596D7E3C1750A3BDDBB7353EACF11B27FCB566A404A8EAE3FA66B1E5A8DBF95A69FF822ED5CBCEC9604070650A72F69F8AAA81213F6F9BDA507DB2032620E2C587DB8DA486FF4680284423046814E030C62EBFEE80DEEB1D760D838AA963C3321DAF041DF16CC206E43BAF0CC1095115233707567D6C905E01BE0074657F0AA9C9697FD9D8E87BEF5C9BCFC77BD2D4A4476AD3497E359EA9BD2BDE4614D9CD03085F7C473E3698F98CA9DD4127DC2BB41C547D5ADB304F38EC348767C7605F0F01DC475D4D4D00A4337C0795B1EC50282282EA3C30BC2F9288B79FB7F5F433122BF2B2B1935C8B747CC2FF3F41A85AF9FC3E7CED7DC8AB0F3D9482890A09E990B7B57443EE62EC587CE3A6EBDC78D9AA327C35E1FBE16959D031176B522B5BED9A18FEF91A0690832CF87CB560FEC9EF1163F34EF7A0A96B6C48904F15BC28F8D753D125BF55955C5D4B52EA7A35171C812A135C5A0AEBF21B53CE9371DE75A77EB5F8EDDE3C900DECCFECB184D78461460C192233E66C50A46FB89BBA14AA02C434445239CBCF8A92914EF5A9ED12C7706615CC8B0DF0C596830B1C40C7C8364CD0B803C20737C779F9D25F35514AFD207BEECFC82F10B0C8F22E1B3D86C91F2A5DAC2E63CF6DF5003DEF1DD74439B2A0349904FFB4B05A4AFDA774578C70F409B3CC6328B1D87AF729A60F2455349D48420368C22692DB5D0D9BD313142AD2FBAC6FEE29EAF2974E66EFA51BA6A52349C3B451AC2FCF38E3B5073213426724F2238AF8932297B6900E5F1C62F518122792813E5FA5ECEEF796AF07F8DC316FF3D81461B1CD352DDD9F962A3B46DCEA26FA83D0D1AFC09B7468A194BED369EEFF11DB12237F0E9A69EF7E5F1DAD3DAA42335ABC804CC18291E1128CC6111E605922CC7B136DA254D674B1D717C642194E7E41827AB76CDA5B9881FA9115DFADEC0FD0ABCA1F00C8D93496F8EA2FEEE3E9677F0CB05608C4F3A6A42BA2A694ACA9AA045E88734FC818965D95812B613A24638757AD8E9037A4A5AF89B2ABFF94C500DFB98E5CF43DC41C9A988194EC689D8972F74F65064BB9CD20B16B8AEBE6C258EF9F128281F6DFE1F0A6453D5D16DC11949E7049AF3F55B22620DE1E75A5AF95030E4F2386AF4697490FFAECDCE76BA131D61FF45BEF33DF3AAC63FC355EBB1B24AAEBB0E31FF057ED0CDC9ABB146D99A7276FBF686B9B1DBE51533F12436CF3CFF995BDCDEE6D5660B3E4D5D37FCF633D6FB28318D2A847ACFB4F8AFBDC8396B7172D2F21D17A666C08A66F37A79CE711AE936FF9BF807C3DA758D416030D5BCC38633129C4DE4EF4C763B2D9FACAB758942B827BDDC9DBECA273269B330E5BD41CE84566A1B2D39DF36EB89780EBCAF7A7BEF02DAF9A343F7FFAD821FAAF0138E6D73F7621BB699FF0809AE312D168A449E8748B455B01F2EED9F894A4F47C4D84C7E7FFB382FE90B7BD13737A01FDC8F3A8C1C692961267E9E0238CD70887739B28774882064812EC9C431B59572BD177B3B0C21D352782FCEB70255650ED77FCB9C4D8C65808558852BB57ECB9093C835491028BA284C6B97D9A4D2F1C0530E3169C2628C16AFDF0826EBC9E4405FCBA358134CBC596C89017E76351BB213D2677575E6820019CB6EDE7852FA932151D7A72BD7232EDB1F019F45254D2C49258895DD6EECEBC1C1406FA927BBCD8FB1F03A016505F63A5CAEA9E301ED9101B10C72F27247442FEFC7576FE89E218B9D5D9CE59A54F562A4BA435A35873177CCECFC477B782870C4E34D95759315FEDF52B9364E9FB4B9757AD1F777EB55DA8A3F5FDF2363F795981364D028C3C3A39A41B13EFD20C4E0D776FA1D4B5A3AF641E5C4C5CB5C4B807CDC39B8C246D9182445EA95F8552DFD97D5EE22221C155998856E33E4EB5A438A7A62213276DF3830DA45A0F5C7ECE630290C8BED32F6CB5B899FD85B36BC3F60670993F6428A445B330B81092144A7167BD9B7929991176D4EE46FBC683546D268E1006120738E5933228131FA464C9A415D15F79A1C184BCDE8C9B766B0822A5951E3EC815B5ACE734535277CBA2BAE71EDDB24E58DDF971B6D757B77EA1B97793F501226D02CA95A8FE15D4B31897654CC0F934B5F8DBD37AD33A05170CAFF4CB31B1CA19B3C3C6C14E9B4211CB64C75D42C4A538FF1CB982178B7A9BF8E073886312086896AC4C0DCDB345418BEC5D1AA64B29CCEE1984536E27F50D62997FF9E46F0EB0D1FB74F456E8553228DF4CCD20E6760C79F88FA9EC924D0D04F13500EA3B99F3DDD1BEE0BA0EB4207EC4C8628419A434ECF5BA680CFF2750AEDDDDC2D1DBE375E77E5D133C833848CD35AAF2987898C0A03B93EBE86ECA1AC8568613288485C8BD9F49251527369B066152F34A4B6AE4FB46B0240F48A2ACEDFFB5553620BFA82C83AB61179014D224C57063375077E3770ED0C34478108D619D8E297E1EB29D48BE286A74980154C488BE7960D56F22BCC1D5FDFD992D5FF1F44D97534DD9C5A3D4A9F8D9359716815996BDADA33637AC3DCA3460FF446E51CD05CDE9671EA6BA24378CB83EF1F4EA2AB8CEF6D50767C79B8E1199CC823E20AD3AFACFC8DE12AA149FCA7D0912C719444BE6F68187BB166A46BBF7E953ED1ECBB3B607E8F8F851F27FA4CD603705BCA0C6532574AEB3B5CC61636D468E785AAAD1520004D408FF1BF1FDB5361F6E8D1C91B6F6B42C4362E50A0474E1452380" - }, - { - "tcId": 56, - "deferred": false, - "seed": "5C3E3EF0278EA9197F30C4DD9C4C06425C05401253E77DFB3E1D5315CB00915B", - "pk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED36093A4B1D6FC48D27FE2A3AF6FF6845B999A74A457349428C7F042ED012B9AE0C11733E6F8BA8CED9D41BE522BBAEA8C37BF24DE1C2D025E3B148213D573FCAE27A8E14BC4758430F9CAA5D1B808A88BE38761C0D2C4FE040210783A147F2BD6D81565E72D7E1C1E7451F550AD6880B5BFC38940FEE73ABC4E0B8A68065F0B8B9DD4F4AA9E171E50626277ECA42E71DE8A2D364572F7D37A498F451702992703A86DF74F1417BD5CC752E6D4DB90B11C6786A85EF82BDC80C3B53AEC20DC571A2EC1C36C242FDB30D527F6D483072A0700B57BD31728F7365522D6A288FB78160723AC2F89C6AE609EE194CCB75C49AA533FF6FF6D070383CF326C42D400A70D31FD15D835FE9B278F53BA6E4FAC9710D1D03D32FDC47A3203EC23A34420714BA70D683BFE891118350D91B56CF9FB95533FD4F8024BCAD4E2AAEB0BFD729BF5746BE9BE6FDD6025A209AD606F49F8987998600BDDFA807C3DADCED192F1767B58C1C037579C9AD0D8148CB7B125DC66697A0C9690F86DAFA2478AAE0D2F9BD9069F77B2EBB4C372C1116BEA7488337B5372960C0192715FFEA7051DFAEA0E86E43F534EFE805E16BA45469370C50C15CD48CACBF0565514550167E7FBBB86D777B006F1E13CD1025E4A7327FF7F999A26DF2718D5551C30ED776EE9BB36F497B4B845D40F411BF7DD622EFCFFC6D0E581B05AD660417F3C5709261AECC043B2BB10AD07A605228225B647141D06294F246ABA4B66CAEAE4B97E72290FEA8AF0E3888694AE54BF29A9F587F0817201BABEAEE17B32A8E1057B48AF5D9A29D4AB9E479F105E95DEE4C855BF4410E5FB7D2AB55EA4E55331B7B3DC1B31A9AA99813FE42CB602ED0A979BA9F684E545C44E9185A176F25CF89AD2303088F80B726CA30D326F46E37ADFD11B10037655D4B84F10B7618AE37C3494D29B0BFE308183E652EEF324BFBBA27FA0EAEFE1DC21B8709A51B1E253E597D6FEF829DDB5B1DE50BEA95E862C7B61991975AD3AA56DB6BF405742D0EFECCE68F9D304AC4A162E031DAA216854845BD8ACE7917385C8C6BDD8B91577BEA5BA5527821F8294E631DC5F6EC6FF91804FC9B9C48334FFBBF667438563E0EB92CB6DDADF2AE8834194CA5600F7297CA00F0EF247065E02D991543E58C4FA424D20484FF85C0EF98A881E96F327DF5662ABB6462B4A5E1AED2D87244A1030C80A5145B6DEEA9B5F6539DA2237C7CB913AF4F24701B4DE514C6BC9D82DF6BB0EA9727D2BF8CAF3F79FB45B89B9F9EE6C7822957C650EADD34DE288A3BA14CF632510314F8304706EBC27214E37B5E9356408FD8F30C1B7E9AA7699D4ABF460D82A6AE6BA3AE6997C596C368A5FAB46BA4D106120560B5E7F87007A3EAC7CF822C414C4F480F3ADA0721C979BED1D39451C9845C23FDBA4809A35D23512750760493BF1E9C0FAB92E09D4DC3C2B757EAD5C3C039610427267B0B60B3B7F258E110332F88EBC474C7750E4531F8C19C8F2DCECBDD9CAC2645C18AC7A8B7AEAA1D79BFC79BF73CDF5BA09AA0762EE739B503384F3C8194AE739AD48076174D3193CAADAA9A5B1F4ECA6E948B3CE0B46AAA6138689796089137C70DAD610C88605068EF8FA29AA47B8F680FC2B663443913233BCF5263BC9081A50A39B8A31D7C5905D281A10B40550B3D38DA910C731200DC6146D44BE24FEC8A09AA2EFD512D1E417DDCBEEA76F83371DDE60F6F5324C38E9E4A9D26636C5C3AB5E2441EDCA559ADDFF294EB07C77DFD26104C67BD4F73CE2F068F72578DCB83D5B5BECC01CFC4A4A424C24DAE233AD0B48B8277083EF5FAE224D372E52C5628BE386F647A811CA7C564C8EE4CADD91C1A63DEF5553542D1DA7B9557C4407481F4150D381515F560FC2AD136D9276B1AC7B4AB9C08D911347BAFB5561A6F6B55E8509462425B37A8E96D122B5FC5718ADBAEDD87DFAEC689EDB28AF8A0CCD2CB5A97300DD6716579C9B9A15436BCB3DC4A917144FB0285804A8BEA421D9C39C4653196190FC5B45F2CCC55401744EB7A2525042120C900CF3EB6D7A8E685F44749D47A704C47F96B49E95C216A0C5E4E4CE5A0E15E798FFAE9CF8912FD985734E3910E82CACA9494EA7D6AE4904CBB3ABDB02B3D51C18178A308FC058D28F0AFCCD14D0F488B82CB3B0DF13CBA10B1F6A5FB93F557281815275BA3969AB0F685BE6CDFF611B08F14FE31D3A569C25A4A92FC946FF8C803F9A7D3249C7AC9BD08D06C631C79DD06BFAC714E4CF8D0096A985A80F3AFB7271AB976E2E1E3494F03203C7234DB5552BE5A58B46BE553FFB6DE465E01E6C66B019073666CE1D9BBB9952CBD44E93CFF7E2CA83C5C12CFB63B0198116581EE8BB3F9ED569B5BF2BBE7BD0B3A6A71A5616144C8EBD7C8D56FCEA92E4732811ECFE8BD075FB5490D46F30FD381D2574710CDFCCD62733406F788A29D32DB7A63E4F7735035D49BDD302596A2DA212886ED1F394FD70E4AF7E94CB50A43301827382F6DC651F895BBA5C6583A5704737954736F54CF7D3AB3FE8CBDF64AD8705F7553F672FF47B4E9E47784D65E97011B4630101317D55BC680BE0C687E1005892861AAE665274A78EBE97BE2524C94FA37715F3755831B49BF2BBBB1589D5859C34C663751CE53BEF8ED43C551879BA0EF952B94AECAE204AA097EB577644CBBA015F00A40136C7B819A0348270A89EA4A9428BEDE241B67DDF0332CF32182B20F551C82E366C95C42891353219147A1FE908AD18835B69CFEE9B8913D30E9A651E15AF091A2FF4316465B410A41597C8FBC32ADA0A6925714D68C9E72561DD67DC8793B15E7776BC92F3E545215BC3104BDC06D8F2FBDF4A4E79E74522EA0EAF37C3B716D592E50C97FDC2FABE637738272B633CAE325D9474EC4232FB8DD3777BC687D55A81CA8DE116674615534C3B1B6F79BF472C64EA729FCCECB8C30EA3937D1EA8412C5CEA57B5CD2D8621A5AD4CCA52C24339F4110517D287AD4DD6A9B2C77A60F2BEEC6502B1347C021E4221ED89CBC77A02B76764C7800BABB59B6AF7A5285F60BA88DC08D10317711C93E677403676170E05574409C79EB948C3F80F7B613E4D6C29E6FD81D8CC8BE62C6DE83FEBB801F7FA7E557F9CBC99C2BA8E33E8CD9A75F82E4DC604FD765230520E66FE375D22F732864BA892CDD4F76948DB7341407F0DA5B122654F955A1E5A65D43CA269FF3499374F5DE5692B425628948B91EB42DD35306666E6677581EC6F6683962F959273DE0C963A5BCF89679FBCBE517E5DF25868097820A2F0E52B78A27ECA47429985DC3962D99749F0C9AAA1458FEEBE8AB691EE7A3D68727CAEFA85E935057A1FD37B5A8A2D32C86227E85D2D385BA4D01B4C51911D7B98118E5634D3F2B41EF296B978FAB20880C7A165A534A38218BA366AD83893E1045E1EB03155612FB9ABDEB6FEED1B7A5AC81F26783491F0A89C71638853E22D0B0C26BE7B0909EA33D2AB9D47EF4CC6B4B4C6EF0E61CF108162C0B250FEA52ED6174F81AC2BCADFE444C60906334A7787F68DC2FE1DEDDFE0E9DD32C5EF156063132F130EDDA0C6F6FC7ACC1ACB9128F6EA3951CAA132F68F3CF69C42DC4604B359F40AC8D7FC6152C33E2DE529BB3E29", - "sk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED360937FD1E64E1BD8E8E9ACA63A1587322108D5FD639C9693E7AE0C24729A3792C655C3306686F2684A6AAF99F90F3A79D38DF3BB3C6956B38F223E1DE0C628B87AE5093A25DA52B4BFEE1B33A931CA2477EC2AC3BBD94A97055E1A453FDAC9BEBC19C126094C100C9BB49120386513C66D13A54D0491484924100AB52801459012B0010AC22192B625D0A00DA4983122A34563080CD2864D1AA44CD140325300888C262952922C21234D10044D5026122494458484645A38012341214B104E4BB06112908C4B90501C26120901291C141263322D44269010A268DB226E20A690A0124611C2041407620331211A470A50068813A6081106614C988548C24C11000119362C0C969114192151A88C8A804520166811B0610B4120C4B84410368C22C66403A1800C35800B366D98340412328E49226211B0441B21001A190149224249123001488462B6040C0280211712934624A2109201144583C44520073220A851522628E1080A5C264514B184DB480AC0088EC04850A0922180820191022004468C88B2890B36919C48619C4005042350C804050B196119270E5A4085D4B851CC94248936659342201CC34010900182B640D1B4290402291A948D92848988969009392A91B869C890701B334AD02450C1A29048B26123490E0B200A812289491665E42425E19051993290D4824D09B731E03692CBB8908A90251216724BA285020022A4006013837119032E4A1622D0444E62268D0B370208C485D9B02123C240112024882840C8B02984988181386221C644E3A648C8123201312D5AA6441A434EA33090C9266288B2850A12040890400A862D0A03129A4062A3C2694BA425A1040199268E21C46412344400C68148A81163268251A21123930589208EE1328E0C1246649260202281134161548881DCA28043460820C3301C39010C46665312060A046909004002015004426524493218A94410162464246C19392241A40D0A261014C00CCA068080A489938000C1468210354A82462210026C131729A0B2501C278A4BC2650A39080228281338424126061A2725E4483019228E0B02429C400102988181088C92008AC3306E40366E04B4718B280E58282689960959202924869003404199126242C6440A359123B20C91B285C8168D622631634881C9A2440C4330E2A844C02248591024840265A0302A02182E9100711020718B1631E4964980C420C02866D8C6811B06050A98819826308C14668CA4280A24091C876524014954B28891C8109BA861E2306414C7291B2726124125648849029169E29871592681D8C48450480C41368D1A44421C142DC43292CCB28563080C99205244B431249688DB3642A4C800DA30042207811A1889C03824C1B48D2321245A126059208DDA240514392662807103370C40C091C3488610112DE1B2100A3384E4822010324D11084E20A52D50A871E1C471E1184621A84C408224023580CA180D8CA46511A71004358211974D61008108308042265289A6910B2781C2A8651A27410C44649224515188651C20805A0229994042A2108A022708D01670580620A3B231A2182C1002650BA12C01387162848140202889386521872D5A86500A066A03A58551C8488A8465E49411548249192749E2A208DB066120178ECB3020DA4082233981191948E1C48404B40D108710D1864088208D8984915A3441E4C668023681E1A02981C489C0B6700A2988DA226D5A180400C25022044A88980D9CB048113228C9966110A12590C65119A821D9B4601AB98118A52D239445C00832C24865433408112631D916861903501C31515C36424BB405A4240423244612474C408088E280010AB210421249993668E04261629481E20250012669E34085C1364894B0888A1642D03669DA047263144C09224C92862D91900961C44013148122004588464022A7051C146AC4400C4436698CA468D4087149A8300408320838701C98641A880403854D84B8010C208E1B342ADB324D42B621A3B629D0268E21A725242060D1C891C40262CB268D1C89318BB60C09450220900120A8110122651BA880198744E0086CDA484592B80953B850D8A68CDC2885A0A449E12869523221D304824C164594A04C203522DA80611B81801015241BA821A2C2285BB2456094280A1706F4F0365F55F2BE8949D5203EF1028AD89E2DA16C4168B028F367D8FCCF890C765E5C2EB32FCB2929D16755C766B50BCACDCC1827555BFDDF1BACE70F6C8B1AF5D462B60394554125321CF87626152CF5F8485F3F0EE9F6B3D931438FF408C3152304E84E6520ED35381404A49B64C293DE829FF71F275F86820E20E978EB0AAB289A1EDA6B775F95476B15BFB7EACD51017EC4525B36798E9C4CE58B1B495C035F961A00F14DC562F704B76CCE278DAF1E0E52BF4EB9164BEFA385C17DC4274320C7448A4002537925C7C4A3A6F21D8DAB362858FA41870C6B9960CC295571476FCB24F2AE5054DA00DD41009577D61F11622F92F9F5F1C6F02FEA6E973B254A202DEE4AD4FE676E0F1B590EEE5E4D5CBD9A2FC2C1D6528840854D8617600F184C0AB59D5EFEECFC8584C101B66C84C3F87836BF7BBE88EC92FB051800FCC93B105B41D60D7BC3FC322FEB2789F1BA946F20865ABB4A1BB506282A69666075BB813D254839CA5545F6345B24FB87255FBC6952444F836D4FC69D0F5C1851445B9F0C473E67DD7D237FE167D7C9B74341D851E92E3AD9CB9FF33F9157B79152B5AA5922F4EA93540C8B798DCCAFACD157F5DF97113957205F3F96FD74F4D7B0CDAF9A8BB933C37322BAE53F46607B29BEAF09635E572CB6D9F6353DAA787B8C4D593A2941D45A6004B9CD4C8769911A13525B64E8C5978C198C8808F15236F0E8B1B2DBDE6647E8B0D9FD48A4E36E1E5D9B02DA044C47BE711FC4717B850105F9E73B334FCD2071ECC2DC2C1DFF3B5E0668860EB25CEFC8F9285462DB6671CA572DAB0B9C8CCC1C30D0226582511F0D8E3E6943276014091272C9F87D62F8A688659A50E929E0C3A8F6A0037ED12ACA7A6656E4C8F0C77562795BD4CAA8FA2CB9D4ABAFE7A8F07BCBF3B31F3350BCDE58BCE638994508E5C8BEB7E25FB42DE3EEAE234FD12B7E2B388F10C604D36737EFE96DBFA4ED1406C4626998CAE8BE592058EB09B58662B366CF6B079CC14D8700F5EB1850952AB6A1F33A1DBB02B7799D535FC21193ABBECE2AB3C1542F4091C5D45E7272DD11FBD6F3F836D90B1153CC0CC1241B75A373FEDEC25E826E3C9CD4725A8B9BF07792D5640F16F1F0EA0341374AD6CED8D0A4309CBD6A8C41E8704F7812ED3441F8AEC9AA3509BA788F98E04F5DA6EBAEF3F0F21C15E2D6AAAE85028C8B46D4D91718413EF4D2FA536EB32CC22626DA5F2B47FFEC60D021AF9D5AA4240D0F585F2B3E84540EF4AC604917DEE3D871A1BF91C71803A4FCB102C1508B82FAA8762FC3A302B03FD941F575DA3140C793C84B715E4157AB305D33580D463C1759D61BA72CDDF830662D37AE61BB401CA7F67F838522434C53D70A30785690593489B7AD6DE0B07AB116F72AA115A1289F3CF2375839FDB8D0B0A6B97C5BA7F8B427F398DB15FB4E2CE60F7D4F854BEC87D7BE03E133EFC3F2EF7A41C0789114451BA731170409074C8FFB5215418C4C1F53A6DFBD73765143A9880D5B6EDAC970A57C294BFAB08903F337329934160DD8E0964B51C7AE278817B43AFC5642CBD4BB2F78FBCD3A22976A1756805497B5DA22C288CB6810E772A61208DD2846DA977E25BE46AED080354DF881106885AE297977E4840D557248C1CF73B8C637693C3B42A2F9F54566AD851B9BEA3626C7FFDA65401D731DFABE20543305F70176A3AC14B724682BD1787E930181FC3F13AC48FAF7563C26272E7AAE34B5CF530482BA36E9BB5ADA0FC5104E6F94AF5E496F9D38099D89D2589C83E5B2BEFF5C638B86A15359B48A41548B848AAFF320779AF8AC3B88B3ED71F7934323CB6E90D5BE36310E8291AAF090FBD93E154D43CCE896E669985D8DF91EED305409E292D9622DC28C0E3DCC6D2886E6D938D4A6877BE7403E0CC855A45218532B25B335469C20C47A5D25810DED94FA0FF238160EC4E271CD746E9D2C70E5632B2DA1290F8BA2A10E2680BA001228584326814C7C338770F483BF4A2DBE3101A52ECB16927252C2A391B32A24574B4B630F6550CE1690807D7383B24378EFB03386259E666AB0AFA71C53D3DD2CA5B0952F7695D1B66B091BC23CE1115DECE076DED2D12AB0110876C27670CAC62195285DDD229E41165706CEBCC41A5E6BAE4C7DBA625575965198B6661B3E5BF5AEEB7531B1EEAE07798E1BC65B53CEC5F01566A0042BF943E9C79AA6B55AF98732E5C84DC8631155E23B5FC5409BDD46B91FE3541F375314E4C0A0FC172BB3A7418911BEF933C5136E90574BFEBFEB839F0631781205918F5E942F9F26EF336302E1D2703A86F900449075B0C50C21CCB144CE02CA278BD0179ECD9F3BA61EA97ADE4A1E338EB905FB45CCBCAC4A6235CAAD8EBE97ECBF6B7D90A05EA10376DDE8FF931781B239038A1C026557BD50BE562626A5F1877236E8618D7505CD73BD32AE6447EE3D058231C3C5B60E703C9AF21353631345A7D401B74EC894F1DBEA23ED32B1FBDDFA1E12226719C58FEB4E7790F7B4D329F72CBEB1AF9149100355EF3FE317F3262D53D1D50971B53574040390DBDDA3FB3A8FCA81D833454D3025CABB2729B84D1358003DCA4FD88EEBC8317DD4F73666271B9F74763B2530FF7948451FA1A3BCD67D8798DBACEE3FE4C7FD017F523263D2C0A4ADE6BE9901489C4C230687E89FB079C52DA5EE5FF6224DEF88DBC52655BFF36D00ED2EF944BABA692CC95935ACD610B5F5D178D202778B7FA7F7D1E93810879FF10018EA10EDAA6435C1CB44E8DEEF08C095CB456183E262585D9DB2691FFD801F78C293A378EF8B818793701F8282469CCD8AF52C7849ACE0DD55B6117E93AF8CB7D385D618A3880095F3AA75837775ACC7E580031F5DF23CD3FEED158DDDAC8D1927F3F583BB56E37E60198DA73133AF222D346B6C1832BA8E78A1EFFE22CFB7B26E069E197D72A88F1D2EB3A6BE7D965054D74033CCB7BB7A1C7886B10B7F21C7205938172444529DEA76585D79C8CC779BE23884A206DA8BB54792C7133D5A7FB82991B4C912B0469DA9D7A4DA41F745939C237229D3D8EE31E1CF642734AB95D2906728B8404A9E8D7CC7EA7064BC2DBB35E7B3BC85BB54118765FDB66CC543776FD6D36C1192FB351BC177AC038C6573918F46FB6642D9DEB08EDA8D8AB84D963FA4274BF6B2D2E6ACC216FE379056BC5BFE68C217FED4678D711A8B16275EDE204D0C9E7B50875EF31A75880908C466F46B870E5022E015B71E16290A2CAE99761DCEDAC9A485D224D711261F32B35BEE7A76F5DBEEBAA6804AD6E27F1E214FA839C6AFFBE6AB73907D2472CB5F6A1A12AC28A6F2A37D6EA2E6FCDA312B5EEA3F830F1BA742CBFA517B28EB7336D96B208E72819AF82E9D6E3B00C4B6F2E7CDAC5AA3B5E2509B8E963CDCDBE118D71577D810F5ED946AFAC62257BCAC3F6043AB5D6A022D9E161363575C17DE278353B4F891F74C92D1261304D9594C4ACDD9C516A80685300A23864B9065C42C388F91E43941D7242E61F5924D069CC065B53652D13C3CC37362B93982DA0C954F57CF00A287DA54A28D347B2E3E0B30E555E14CCFAE6871CF9AAE3A9E18DAC84CB59EBC4AE3056017B6E70D000A756EEEAE8A44AA706DD8A1E14FEDCDAC101AC8AE90E0DB8B640ADEABA76E8B45EAAF648DE53C63B323D67FE5BD9BF979405229327B364073957EF733EAD46A0BACE00CCBDEFFDA62E50CFAF19648279CC04BD9EED6877B0BE78542DE7073C86372CBE407C05CAF3D264E8BAE22B74A3B9E59FB0269512D481DD3F44F08ABD0129FF336E7C1E464BC2A11EC50685F3AFD0E00E6CA0C99FD1646EC59E313835C929FD4BA95F6B0CD1CD737F22047355F61582B508A8EEB2F3466E37A04856FCB46B289D461274DA1764F1B4165DF1CA0F74C42FE780A96350133C502744F566BA027A5E7D40EB37CE5E810C80AF2329A410317CCAC602910FF51CE61A37CFA056DF2D89514ED3DBEDE62625E4B25DB654FBDF1851674D7DE0CA3549B9B1DBE6F46448BB4011AC09E27B80E3A225B2020F2D6144449AE0B832A6B5D44DC64A495E66BBC6D837298F0C9DF6E8EB0BD4DE699CE17C8112E4EBE988CB6609F21DC4CC71AB5F41CD95BB5AB56970F4BB663C0DD47621F2B0F22DB700ECFB029F24E1C879570F7BB42BFE66470D13F283C591B172DA62B4ED80E1508C1FE545651DD9D3942C26EC580CD2E59F298345C150A88AFFC87645DD0272ABEEC35C244CC981E489A93655F1EBD125F7273E2DC2990C0050FDCAD84DF8D8983BD68E5BF237DAECC5ED9D182B9886D70F602FBB6F6CA966C952EF4C386E2EFE91AFF326EB056E05F17F7A08FC8E93135F41C7D69E463F0519E0FB89B86136CB557D321B25E73034AFAB218F8D5B04465A3421EB91C88790A0107BD39DE71CBA1F9F2BEFFF0E3F64D146C52BB9AAB4279CDC2AFA34A376161F335B7D283F163108AD93A2E3FF2215126BDA53C05A0F0CACED1D6D5338FCF5ED6017153B458F126EE7D7B3D47B33EBE84A56B0755C0A5B12D9C822336C35906A95049D106C71A4067BD78DBE14EAA94925FEA88CC0693F35358CC3F4C52C98C8DF7F01F120D2FBDDDF6ACBCCB7EE08B8D334E00D9FB725538AD6747A7C6D62B0DDAA19A29EBF40381FB20B8D06E76703CD97905EEBADEC69F4FFF29D34D7AFC51FBE040B75860FF10A15FD30ADFC0781DF7626828B08BDED220EFFB" - }, - { - "tcId": 57, - "deferred": false, - "seed": "E3B2350AF8A1817D936FB7435C4C0CC758F79FF4696C46E4642670C5A78B30EE", - "pk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D457101C42488C6F1A2D1C64EB30539F25231207BF67714530E1CA918716CA2DA13641617C283E30673144B5BC85202152F70A41ED9C72BB49F4BA7292715D446CB040CA1A1152A8E77E24865855234131483440E272DC217F789AF13AD77DBE65DEB2300568EF26C729F7A2862C5BA15E58471414A3DCB37A7C39E64A33328AEC25EC03B62F7F5583760161A2109A93CB4F76CB0A9C19C42AAC905028AEC29E8287493F88FDCAEA9F46F6FCD36BEAA4DBA41933747D10640A0F4B129CE215D6CA1E041DE8B7A1E791B7FD19D0FB8F975580E828ECB0052F11E2D2800B0EF8AEADF8605F04F8CE1E1AAB8A817403D45C554D03B56E7711C5A10A8353C0D7249620A4C2454515B4A61D10603494FF26521B93177460FF497B98F170A7E7F12EEC8831052D0852580D3227257827749E9BCA234EAAD2E13589132997A410FD9B4B5753E5E6A48FDCAA4DC1EC7D7679767160D90B7842A17B01084303203C257D4DB439944AD0CBA4F916EBCE4428EC5E8EF6A06B30B162CEB539F9EA80DE510996BB857D169F9705B362E097DCB529BD20EA815D55E0DE2A117084C29FDD27E6C48796C162E2EFC4FAE9E53ACDCB235B795C671B2D72B34A5CBB7493D02FB84BE4229BFB4F668E5DCA4F65F7370B9AD2D19B89E2EB2D33DCFD904EEFDFCCFE640942799677156A3072D5BDE13A927C34B4509924C78AB56661B37D9A269DA60A4941E0BD9930915B4EFC5D7783C0D111B172632AE105C8B79EC3C540CAB50BDD214E9EDA38058463E10EC3DA5D2553B3F823D12515DE2321247E570B9A4769E90451F16527C5EFA6EDEDB8CCD23A7EE53ADC0D6CA0E289486BE0A1E1246FBECF67968FB50F93C5C018F21AF32EFF9A34EDC42F2CFDDD60CE0D41214999903304470798BE4D2AA0E4579374E97CE363427AC8FE4B40BC2DF55DF1089DE653FDE138D1B9549CF0D4B9CB5C53C74769D7524B0E9695045E3A4484C7817EF4A653DCEAF454F035E7E424EFDB45ABD91B78028E53A1B6DB3A8DA27F60BD5E0504899A955A0501D581FC471FD5560DB991774A39E202103041993A7274AF5B7FD0084E8D87F6351DF5626AF931D9644C544D134FBE29BB49F23BCC552596056AC4D260D52676D8352A17575130C245E43443EECC0109D29B1FDC3EA1F42C4DE1C603D4C1C67E871F706BDBC388648D416BC38699E6CD89BB0794FEA545A5150D2B4960B6CA483EBF71083295FC9F104BF804E700E3CC855F1F379701BE232ED6DAA4642D9FE83901D8B76388ECAE976F08B80CE021744CA29603923E1E6EC4A907BFEF119B9979D282D3D989509C91F254FFDE6F3339B0A69136FCB45CDD650889981547CCE33DB5A12D6702F9D88C16496C9D623C460EDC58666ECB3014ABB54CCCB326F7A6C405E5DA27E06FC2D02EE8F785B968AE2F05836D74ACB9086EDC3414D192ED69341F8249E8AA300EF050B8370B8ADBC5353F6C90E7726B41367E0954B3B409A644FF8D04E56539928C8C676DCE1810EB9B17F209C0A1E02F8D27BEC5BA5C516644DFB80DF016EA59245F730EAC356F37393A2A014FB6E1369384BE9A7CA34AD85348021BD9B2BB488DD6966052DC377676B7906AA7640B9A7E0B246BD0D6A49BD9CD8C6DB4628C5EC1CAF0D154A702D3CD838FA69163102E4A41605D847751404C0F6A75BA3A4E88612140AFEECFC4835BA4B8972B3BEE3CC22A52877FE08AD7A4ED7001144F2D5E4D27F59D310BB4C77EE606F5F4A5918408C64DF84ACE033668E43FFF6CC05A994B1A8F68CED63CAEBF95F3C30E71AF35CFEA31B9A36834698EAFB54F4B9EF83D8C597491F858BC89218CBBE22E7720FE2DC057276028BAAEF3E260560E0ADEA89C59E67E7A5B6860EE069A50CD10081C87C9FFC5B1012E9F79B15C924B7FCF1CB17FDAE8B79C4E176478173429B92C916F34C0D139F11010AE39D34B5116D9CD02E232597C3CF8FC740B8EA0F8243FB2923DE5ED7131F028435424DFDDAD4A46FCBB33A2ED42FBAC77FA36F2816678F2787F5AE11C64431410E63861B972C87599C1815368CB1C6AE9B956766F78621FA0D0B6214FEFE093C6DB2554C70AA472F6B332E1A5DB4068AA73ACDF50588C0B95DA328A862388F6E3C4191406F38FF5F526ABE35396CBF57BF6254218671472FF46BB4AF7905CFDCC948D61E4D72FE8D09418EA27C67095D608315EFABFED54B95B3CFED9BBCD55A13DC2ED0AF7C014BBA0B2239D511257B28975640CAF13C1AEBC2EC7F77AEEEB9617D6E5DA22AFA50CC6092F1D1DB34EBC2B873621B4DB9EA05FC497B799B0FC136D107ADCA22502F7BA903B3486DF8ACB9FEFD436A30D6E5488E6819167719D22ECCC383C146B72E6C6BDA12A6B7879BC9DAA5DCC85E78CD072B87B13C7914A249BA9C0F0DA96518B7BE227E5BF5789401C32C9FE5801206352B3FBF4E684549076AD1F10D4ABB782FE2DC75EAAE70D7B1F0FF1691BFEB248019FB45DEF28DCE655F1F4D9BDB083C8A7FF9C820D0C95F6480BF9F134AD7E7322E5E5D9CD8E77D02B106312189424E7E33BF8FE5EAC286E38F38D3C2DFF15A2CCA7A2EF382CC7180A39EA0962EDDAF7831EE8D91642D847108CCC7683E293B181E504293EF9738AE06A54A97E2CAD6DA5B2F1323D4B988CB92DEAE70B0027C58C31CE520C88C6E162AC21BDF5F30F8E2CF40881544FD7E4BE982E471E70D19AA51A0E564C49BB8B216993D6BE1C148FCF1AE1763FE1EAF4D05202425007FBD68F7FA81541FC8EA87CC13B93D404BADA2CC10DBE8996E9A694465BC91613C1E4F49FB61E8A7B75B954264537A935409AFD7FBFA00EA14798B8C2CCD0748801F5DCE2A61EDD9496E7508DB5C321D88D18979AA281C64202F945EF1F9855D0C867320B5E2913EBB84761338E7D990FB77B3351B1C433AC5A7C03E58B68842533D36DF772ABC7B9C20C9893951DF56821EF1C49C240F00AF16B5A9D1041E96AD648C5FEA9FE4CCE57A058858191153F181D9634E2969BDE6D86BECE6E1BA52A3D9BB29FCF5F85312EF2C28C9100E8BA0CEB4063DF7B54D3B4D52F90B055A1D6CADC626DDAF48F4E0B647C0DBD5A07C8F197F13C69D05158E134A6893E01ECB1D1AD019B5172CA938AF7699F5E459F65F807CFC9B2B21F4151CDF0FFE2FE786BADA75CFEFDE1A17D3B2C56B5A16DE8267E163045D71F540AB7508B8E89A6B825C416E54BE002984743DE2CF344A0E8292F18A533A9588A05102F40534F34A030B9E6BBF8A01695D9BD60153AF79CCE2CBA83167A256D56BCB87A088069EEFD87098F162DF64318A33D4618554C49E7F23EB4BEB0DDAA3F03D1FEE20A2C6E95CFECD06BDF650755725870048578CA2440194B8E1084E7BF06141D1F522E080308CB9B84C09AD7E5CF72A059E4AF8761425EB74D0C8EB536C7465678416E9E94F0C2093E9EB693D5BCB78836272486793BB4BCCEC65B45186EDF4A6743F1D2726533A8ACC0132DD55DA3031834FDF5B9E18B6F5F24020FEB4D77BBAB0C0695E0FABD4909E5DC525CCCBB455B3FBDA6AA900F062CD64730C27BCD5935E6C3A5191BB50D5EA974D366A14DBABDA87CC826B6BE346388A488777696E52860E6AA85383DFA8D354061AF381EB1", - "sk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D45710588C61A2D2102D4454B6B8E789B753FEEA928AFAEC16993C07F775DD0C20127B45D6F35DC9989A44EFA13013F86054BC0A09A307B909F7052AD59029C184D87AD0189BA7ACE7A66BAAAECB99361E393F00770F54A5ED4BA262B231C1DC79F67008846904046918106E14476109A52DE4488053346291022502212883348C11290DC3C84558B42991A6201036808AB4209384044236821AC41042004812162891A24860C685A09448DAC071D22050C8449140364ED4A804812088D2A4891CC450E1B86C9A3080C838324A000599B8649C12441800326420415B1868004728C292402101621341300016224046025480311B158C11838090348940344C0829864BB80C599444DB060E42C8709B122EC80252DA242610192E59A23103138E23C03052B46C08132208042D5C402D194046980481114790982682C49091A09804E042300C8824D308684938841A0104D1302EA1122C4C008989281204B7511AA76818372E2012802315840A87691B1085D99020D0B22DDC04490349292141269AB66044968512A34D013769CB2080D0B66DC434698B246EDC440EC23801922485E412008A122D1A497104174A61C64419286264080AA3B64C0045111296804B363014806102871002312588388542000D8C906501050A89A68C8406851448811B0562198608D902606018009906420381096240115440068A0210C92884D830420436219BB22C8A4452A09805D8428E58C40D54183110042D1947200131321A335088268AD2804919C8214BC04DA11405A0300A919629A04051DB925110C748504860C09650048205480265DB2424992226DA966C09B98C09174551424000060A1C2109D12628591410E3B4904B1809642029CAC849E4168ACC424E03456A22180513822C813261CC922C21254923B39101B349E236851AC650CA2840A0348DD21045D3C241DC886803928D6008266398201195700884481C1646DC48218AB22D43164663420C58423108A58962946C1C016DD4422A10336113A86C224210E0021212B00D0B358610A421C23631CCB0614922524A1685539001014669821265E0A869A124122122814A486A91406D1312445A466A080046139008C322889CA04863966814892DCA08042141614C2844A482440445120417458948705C08501B062000204CC1C86552B83119372124402281280148A68C94C42C2404300429012348899092051324625400709A108E21944D408029841282A2884150248484820D214109D2B80594266094C670C4806DE4962D9A240C18B9315094700134496298495C164203C92112014C9014469A342D61404EA4C28DA3B648D2984DC91620D9B0801009869C90410B8825C31832D2388DE0222151B068849400D214089CB21124086641A83182A224E4A04412B4689A04801410889B980CA3C4815AC0115B86685C444E23C5640CB231D4C80004C98521432108344458440100068D133411A2C81154062511C9281AA8885B1282583402CAC68D1A838941260089A41084A48902088421B30118C68813116A44022688028D1B409010846C12284C414252420881231624D8C8501900110144508406481291081102211B878DD2184192C4019180681CA004402024911468932024234062A24464121004E3946C19A931E4468640C4059BC2504C404A01A8089A321102A94491380D0026640412111A2212890212122325A4348A23B321C8A424512821D806681008084BC865C12692DA00609B34061836060B809111A94C13092504420219261012290122228EC91400143989C4048453928D11268252045052309094245012147222350C18B22D228430044281920452144052133789C8228E0C204504B344D3C83101A131002466A490041A494610296A610212C896494906700833868CA6514200624C424E932089139865DA140A501245014711C308648BC20043404C0B49325922462291014426240B264A90422121110A10840DC23482014249982640212171114045134610919620182310CB340123952013C511C38230A0144488209201233258C831113184E4106501940059061193080222A78922A42CC124711048214CC605C3284E1B471104998901C04CC3926CCB2068D890859AC44DA29089884892D2B46C0B180620C571238490FDE05088FB395717595EA65C813DF854DFA8AEDE97C0F8DC701BE92C6C79873B0FF5BE6B0CFAF8464A45D2BA5F1D2110B599D7F81608ADB80FB5A2CC5CD7092C5FE4EF02F6AD15902E03A5FD6D39BB6B4E3D79E52C23AE1A3CF269E1F501FAFCEE6AF25C5CA0C47043C67D79C421E081CC89C6B28602174B27E86C5D1A3E1876C2F53F7C3FC53A2405D6035ABBDA69AC32174D18746907E86DCC25B949C998FBB6759163EF9D4AF56539A86E21A8BA90D7A36A92043ACB02A205A23F40B7BBF7A00D6E6EB96CABCCDE88992F1EA76DD79900BB0BA99A562AA8BB9BA85A5F9B43FCA8F5E9C98B93D1A69DA7C2056FDD455B45E4DCF2E4BD359AB127424933ADE5EC8578F4E7262D2BBA50BB96CB5F8C00DF7DD90297E696AEB1BB7E8F3F16260CEBE3C1D61A16E1C92B286AFFFBA544AB264B8140BF77F720AED373F4C730D66E6F03D18CC26F1319F489FDC69F9993ACD0E4B0DF6E8B60EB06039880622A21E407449F30CB25CA14D4A409F1AE4419D87FF5927F932BDA8CDF972D7E6851BCA99444BF90E604877B865D9BDB9DE70D66219DBF4E9D5328B411D801F75C655DAB68B00A573FFD1C7E3D6F60EA042120242BC737B9684F3B9575324C72EF5CDBF236E6ED6E36464757396349CDB9ECD7F2827624687F6657071DAE514A27E6386837DFD290172F6F0EB41F237E19662293ABD847CDA90D1F83B231A1F10229A05F11CC6CE6A26712A5DD5042CB4E87394FD46D09225A4BC2BE61302461C432D3CC5A8726000A1A5618747DEA42D2261CD7B0659E05E1BFB90B7B796A31503EB4D73703A4DB8EBB852C270AE75C9CC8828B36C9172E6AA87C25116CDA489854D478C1D635D18E678CA822EA5B9C84EF2647F83705BB39584FB28C0074F805D6AFA08FEAE60D3C503F3124579D3B4E6DA94DD8AB0246416F036A99D7D5E4D042D3F5CF1E1852154B7D54B2B44018FB2515E6A78B09D7BE1CA294348D43348CF84666E99B8AB0A157D96B3618ACC41DCD53631966A2C86C4312447C66F71CA4B43142D46F6F45CF255731665A130D659B11A18173EEEDF4FF7546391AA8EF0E88033365FE8203E45B4A1F9DE544CC1DD6FFF4C467F2E78DCCF966FC3A7D9C37441D870C01B5A0D395C06395D15861B09396C1A523066AE76A2141652ED9E4594F8B4755135D9AAF4EF0B3A3256B18A78CB726DCE49E98AFA5DFCDD7C424007A1E1E66708B82B5AFFDC8F49CDAEED382FCD8056CDC4FF2DB11D5188C2C17B8286BA12F02E46D11346D2E31E2665D2B75872ADEA0A57731226B3962F152AAECD13526F8DFB912C63FAF7750E3C764F03A1011BCD546A6EB4E27E7C1B002B3044E50F3806317C9B8B610B91135E00C6E3A5937A0A6E964DBB3EC9332256D19553125A4A698E03E6ACC934B004C9926C0D6FDC79AA333534989300A5F207FF439ACE49F7E81E4A4BBA2924602FBAF3B335217BE6422C45C3B8EC631A88A9F71D20CC650E068C50F3046D88AFFD7CF983BA68EFDAB1762D0E32EC722142D5BB6347CE84F2E05DCBA3C6772CCB887F7F90AC4B070DC92D52C6BC717BA95EFE12BCEE3232250770FCD7488A2E75962B6F8A21D4BB83C03A59A3869285387013D4B8D7198E8889A108A42FB2EF83529D934D1D47B4EADDF9A87F45FF75C0560BDB637BE1D10129886964D2E127C7F204E8840390D89C6616FF17DA2D681B5C6C3A58BC8E741416F4A38764BF1DEDDCC392BFD82B7F50137F8D6898901A2E1B9A2BB9FE3BBC66F464B9A48A3DFC2D78A0DB91B57DFA09920664642B6FF95AFBBB3D75FA02DE3AA35703DDE0F9ED297B82E8533139A82CE6915926B704C4674ABD62318909456A4A2C9144FDE0427372B5AB67A1A2629D4365F57CFCB295BCB077B91EEB7955C6A0F5484D2D7D023BC51DEEA0B506D453C58DB34C59D883E7FC6114D38BCF367CEB384B23EB9E0DFCA82072B2A6552F8CF045D49F4F1647359FCDD137AE02F00135E5E44949E6B44A8745CE5AA7B3F06DBC894A67548550B68EE4DECC21AE41A9E06D980734920AD3B5CDD4AB69F8615663A9FC0E4597061471B234B0D04EFB5D74CA1957C1F6F59348AB738C737F38E7423F6283DFC1E9892052C09DBCADDDE2EB0D3C3996A737346CB09FEBB61EF3D3D3D0DCA6D33866E0CABC54FECFBE3EBE661205AB52DFF8C3386B19B1A4A69E8423FF31919764B4FFA08FD66DBF7BF5303B1C9F01A95895DBFC8B561E57702B07DC9C32E582FEBB3F4E258D3466301E7EA0B0E08D6ECBB5A9C3CD50B42A07C5A89C828179FE709AF72ACF0D40C90F05CA7D1215CD5A644B684F34EA37F8D6784A2224546833003DA12535B62DF56B2CF5192B271BDB5FA888FBE73DA5FE30F216E834034E8E718FF4843BD74AE1E97A09234D3B7E4762B3879BB3538F8FDDD921C8BFC3C1DC9820A375BD4782D89B443E621F165C23B0D49ECB82B32E1D569A525487BA9F91E2EEFF3C24E98D3DE8E36F0D48CDA2DDBFD15CD9A9572151FC66C9244FE994F52A832A5A30AEE67D0296455A3AB6273A1CF434C830CA4058EB440352596F81476D60D28F4CC9DB7146903990BE339D8CC169768BE36F8DC43B65A0E9C50B1A79FC131B794FB8D6910BAB8B92D5644A934DFFC58FBE8DC24F2B2BE897B2CB5E2FD75C01ECCD920A21E8B7F83BF778C1DB56DED43A74D6B8C0FD1ED4F4C897C82968EDD13C31EDC86AF48A5BFCBCC30E97298EB782047625E2B125164B795017B8EB2F992BC20D39577A6F3EDEC96671906FD94DCF62518A18B4832F52BAE51342E300ECEEC4DEB7DBE314F2FE65A238DFC0D140A702DF93C3EC4FCF2B2F357ABBD78686CC650D934E8EA18011FA7BEB993AE2223FC75F64898C4C32FB487A827E5B19F818BA0190107F2DCEBF3B56D5DFB9352A04DF74F2E652D1E11BC45E419E9AC5CB55E876F5235229DE599A509C49B28BEE7F353F6AFEEAB9662D1473B6D7F3374E7A6B13A8D0C88BBDF32D2B065296ABD3A757D0022DD4CA53FC9DC8C8FC0A8A63749603BBD46190C72F9BA7A4F326C61A532706360E555D275F996F021144EEBF7EC044BF95C134073F927C0F6575B85939DEEED3370F1B123E230245E69CB6A7F16E139ABC2ECB98AE42EC1F61FD081CED3E9E1F8280735CC7BD81C73C3D66C21CE5C3592EF8391060B41EDC80FB107DF455041082ADD0DBBF5BA6E61E533AB60304D6C36AA9DEFAEB1D5F5853E119D853A0237FFD212E45F5EC95634B6580253A7924AFD59F3309B6F6E010CCA0919E7D2DB088316226D0D9171574A4476AFDAA129C442AAA16E35D5AF3E4738C4015EF996F999843BBAC69175AC26BEB89FC27DF75256F35DE4F661CF2D53A3DFC55423D162C199A7C1D9F51062E39793E74DCC9B471EDBC70EEBE20E644F5E0BE39730A3CB1086C72F9A1C2A2268E3BA67E71ACABE15188120FBD0B7EF2C1038B3D3B39BFD648B27B06F966D5B2D46FA6E867446B8E8B32BE5C585333E36CA7694F70E345B5EEC2A9C1867FA5B0B95B14DC811AD8951CF82A6D80D7CF9E62AFE36DB9694128C578D561131BBC3B3C4379CF2ED7FEA106B2C7F4EDE9F2E80E68F92C93769D36A1D1BDE344E69F6F42304BD78A2DB3AAF3F768471E75731947278394BE15015B424A44BF5B734A63441A9FD07E74BF057E5049077CEB07C3AE573AD9CED8B1AEE7E9DFC3357396BCD32E520690D9DF368E2EA4CAB79328F827882EB0DC864C8319A63A6B3170549DD11AB5521516953A1B66E07FF37E038433BD044279D1427934085171CD641D9F8049DDE8D0FFA459377C43B71A9D578D1EC458205F42058EFBAAB03CF9445384983ABBFDC4BD358ECC5EDC56CF8584D5D495D75D2ACA74073C9218F5264DCCF6E08C49DD4652327EAECD35C08A918A572A6C54481AB765F820AB0C46169BAA3017D2096FA420B6A03F81C4C759B53E80E792C438DF5EA6D147708113F36E911B56334E36268B57C3E0700123BEFC78FA5C73192EE03EAC66B225DEE28752AD43ED299AD73606B2E62BDB589E8B95E7A066D250B128FC0649363D7304D8B140D41A85618919F1B0C547B23E9762368E95FF305B16944F3AD25142D035C20EE3264B1D859F8B8CB675FDD1F343CAB8D832812A0313AEC6A1C35E24BDD700CFFE45C7C498A867B5E24CE67AA977559AE5149EA4CBB7A421958439D0134020D2FD4DA4893AA7A1095B194B71EC7603E5CC28160C5A9A808DC337AB6006288CD5570474BA78C7C9736898BF531A9AFED78617181F1EA6E33FC3F4DAFC049CF13C2F9CFB71686A7038DD43AD235E894633944EE722DF168BAF9A5D167932F4E8B2FC556D62E58407A39EE3E666CC112A38AE7F3DA55C930F3DB2CAAF599D2AD19A5F903D8CB614AD31BDCEDFAB67BC6CBB67492B9267C59AC05E4295A8CC2570FEA32ED8901ED9424FCA18D3A7E9D60CE7F0C49D0DA9671985F53822BF517CB408F061247418DFC9DCCAB5FAFEF0DF0A196477BC9713D745C3A8276E6EE5373FCAD8A13F9D410DE705F504A6FF232C0641934161D0441CD33260C77396324B644384AD560DBE219E684AB60E610F98E48EC4DD5F473388E6C7F1C6DE2A53445C117650967496749CDB013F9581FE384A893C259CD05F015C6643871402EFC6B0DF5C1DD7CE912037006330259191F50546301E992918CB4DC22C36538FDA1B3B369BFFEEF8DEC7FDEFBC498E001D18A" - }, - { - "tcId": 58, - "deferred": false, - "seed": "75E70362235CC7CC4A08053BD887CDCC4E3D88F77E1C7DACAC972A9AF83C0CB2", - "pk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96603A9F1803E43FFFD3748DF1F1CD131490C539CBD0E9DB5F23BBE7B8C6C33E4678F4CA674374D7605F33F122C314638D11F21A0C810011A87F0E1D04D259A6079BC86571F5E9ED491AF727BE0659A15D9B028D4FAEB61EE093BCAA0DB72374978A6AF78E04D2D3C15B9432DFF6F3359744517D05F5BAB7070A11310DAFAB230F91E7E8B0F8AD23CC722B4E5A5E546A7D3251E4CEAF11395F15F50CFBD6BD0F5D637B1451B5386572C3B1C2E978D0005A30DC34E0CA8588E078E9E5EA8DF2AABAD9ED35782904939D14976F624D5195310F842F252C5F7A26440FA9F2C54A4D03180A514D2C215AEBD528B760D4938A0D85D6D8AA300F7D294E7C325F92FDFBA5CB5FA4320A48BCCB8616216C53470670EC8424F47149D853BDEC6F108CFC6E537ED942FE437C3D47EF70436C97A4341840AC4D6B3177A9D88333AD0B3AFC336695D8D6BEE13D0F97E87A66E5DE08C918A6D553F8F49C1E71BE5C9831308E9ADF503807606F2DC14BF46C377C6C98E780808BE91096C8B67A6D97A2555B6194BA9594D3E415CB96302A602D20B328FEB424C12ADE11626C27CC7A19BFB8308CAE0425C9340D5679BD2A7B9E7874E4DC03A323C395F204C2D1FFA0441C62E42494A13D2B59E59F8CABCA87A139989C2E38EB5C36B0CA169E4AE719ED92523E30DCD272B992C8B859ED4059029E8851C607C606673334D6CFBA44E501D596E8823A2E637D3E75EFEDB8CE122462D94075C4A0479695BB7AB98A2815A115226D93ECB20D92484EEA686A3F580225DA87780B2314CBD7B90F38589EB04706BAC8FC90824420802C87E612719DB951CCCEAA4BCA5BD77BC781FFEB29CADFDD9E91202A7CCCFD7B25DBBB91BAFB361597A3C560CE89F2E1AA884897328D2ABD7C41871197841A29F69A86316CED244125AFCB946BC968C191D91FEAB8498D58A5E5617B32BFC82C53D2E3BAB3ED5410F10F188CDDB8FCB9ED9FA20E598432482103A7583A86CAF8572F295F712CA91C0F453FE77B0175AF20DE1492EFA7289E07FA4CF907FDBD91B9AF460C6DF8F70E1B48439030CFFAB1E5D19913AC756157EE709BB9BA9EF982A679872BC077B1E61D9F08A9E7B6900DCCD71C6F0ED71A86FC6937FAF47CEA0B65E94DC215532487E634411B8870C418339B063345948BE07D3A3DEDCAAACC9C65EFE292AF924E08A78B93870CF0DE7F87FAC477F54382D597CBEC10CE7D86E68C7C7BA61CD9258A3104729CB1180AB988EA39A1C0DE6BBAEC8D544226C738693EA743E1B677F44C3322592EB0CA8350152C385F48FF8B2BB747B9EB2AB710527ECC053DB826630FEC5BCF6F42BB8AEF9611D532CD073BE341565458E47FBDF214C3006457B0D1A18187124047160D7B87BDB1790786A4A53767BC440C5DAF372854CF8C55C03CD556B98FA4E50AA37B038F32A1B76BC70E17E1BB065A03BD33C3B22AB1E4C353526B1D4B01A1F15C33DFD9DD1D30CCC638306A81E395E7F74C5CB8E47229E6E601DC19DECE6E7B366568E28AB8271EB4CEF5B81F651AD0D9D1C8D12BD5F043AB584183827144E47F64B44B5C32D154427BCFBD25F52D797B218FD44F0F41A0EB1091213FD77771E2DAE9A4413FA499212D0A2C24C39EDA4960A46B9999BD5DB0E59615C16683AE8D92934F81C4E3B1B5E3651CD088A2FA008D632A8735651ED452F882032E9AF465F5B7E339B0145B34D0CD011BD7ACE3F5CEDAFC60D14F028EC9931FDB033C1F5F38E3E9BC8160D30B5DBB61B423850DEB38139162CC2E98010F486E0B78E5AB525DD13A1155F5653BE40AB16BF2EC096E962D40F52AC47F283612E8ABF3D747F597250CD511795C784B5DD52E521EAD85792FA1FCF03A6B2D1BD256A1E1DCB832A96F2A5B3830AB8CDEA95E8F0EAA3427C443DC99511EDF971E7AD0C0B629F480BB6A4273F66FE617C63657353BCDB5E2DFD533B6FBBAE9A35828019355E3E09C44930B172C7CE28AEF9C72865086443A0C1C235C6954705BF0E5CBE6F45F7DD02C4DC2A6EF9DB288C7C325C962A27EAF3A8B3677C0207FE66D75C1E58E847569E2FBACC6A1EFCB92D728CB6EF42EC66AA447C458BFD75F3790F46D044067AECA98BBE26472EBA5660171EF4C40F18F56D1CD42C9ACB36E342E78EFD65CA3D2E7E1047701456BD9599644F7B334AA7A64B5C44318661D328270D29F7B16994A1E1139A2B52925DA5C07ADA48489AC79E8630D5E72D03B33637EF0B81A54472F634E3494844D25D8B63F5BC0A32E7296E408E55B68E283432922D82426F3EEB0B1B35681A254A2E803BF6A7D140C8B4CB5A6919960BC0E787593D34BD7E5774D9B4321B61FD2A2DF794FEAE88950CF7BBE223C0117B8C369BA854D02645C9489AE8EF9A7504CE29DC5C45939AD19C9168A5561ECA1131D52443A4457FC203854618727EA00B52DE2F7B19AFCFFA01716951A5EF5140D53E88C84C707D6CD2B1F71270C940946499FA8E7FAE15F5BCB6CFFAF3CADA3F3BD908BF5E1B73694771F65BDAB6D4EB429E83769A1A727A6C7003DA53F747B4BEA711026381CFEF0D9CA7DEAB34192952CDA3DD0B49229105B7AD22C09C75BA2B42ACE26A0877793CE2369BBF5A72BFA44384373B73C88EAC04024DDFD96D98BCAD23FFAF41EB009FC8F0210F2B3C9A95C384B1645F3BF1F6ACF5EDAE1F3AE5E68E5FF4062F6934758F0C60C6F78B8839ACC5EE0A0FF31A4A57979184BB651D62C2F77083682049D55C3C75B01AF4D29E43BB8A14ACB5E843B75ED0BE125E7DDD092DAD5ED09343695474BFA32488FEB31DEEE31AF6B6528C6D34FEDB52239FA5D834A2E5823DA2F024A7547D21E88A94DF8381EFB72C0550F1DCC9141CE1D4947A7CB0AEC57C10B4E995377E96AACC0CF03D720175A92B0D1C222D4E0652E86063A5F31EB9CD9049AC0A94982EC0AC281F34768D1AB5943F27AB87AF8FB8192BBA4E540467016F1E821C433F80D7A320EBCA0425F11F2166512CE5A4B68311305710C8AA3F1B9F18E7F3B49347F8009318F92017CD47478E73DE4C1D7666729F969CE9E401EFDEE454EDDF217C791BCABE7B1674A3FF1191D93FEE46A27AE116F08F1AC575E88A76D115D8C966ACD63BED57DCCDAE0AFBAB7C63B47277AFB200FC4693815D53F529B85819966A92AA9CBBA95397F57265F2132DC6156F2FC64F3E7E5D47F579AA01EEAFFBCB30A25E6BA8B01F0E375847252C95B33E0D1983C0161B5836A6B0F21E9452F4E0E1972098643CCAACA2CBD7430D3FA6543EC473AF5E911F0A5562F7DDEFD57FE4C22B8E742718E1F0E4C84845743F502D5A837882DC3C581EF315E16B4F46B0F3900839FB5F773E4F01BD504DDA48C110C8BB2765CA294CCFA39EFEC4005649B44B169472A5F7E27DC345D3A6457A35EC012F0DEB86381686FC294F7F57F1689E3B8F7CE1542BB3277E07954B7FCA5C5F903852E053D5D2A3BAF7E728545C8E63F6A773A694A5A12AAE8C30B99C706B84C51304508AA149EE74B659829BD7A11DF53239D6729DFDAD18F77006D282E3726208324C779E0F27BBB97465A56FE09F7134306F0F627A71918DFD4B17F0CC72684AE843A498A00BC259827AAA8A15079459D20C517D92FF1F78638", - "sk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96DB67272B3329CF77EB15BF675572262FB945B85E6463A8B20CC8C2685A461A728E66AD389C34337138FBA18110FC95592D207D224F2B617C765B22BA604DBCFEDD53E9C98E5C450860FD37B00B3C2D4FC66072B312A89FBE4F1BE957C22337735430314C306C83C221928048549269E132621A87708C386D080029648610CBC068584801091300E200725300929BB488D4421004A669E08890E22290021631881842D4302E03105201B92C122045D326011A936C4A10010043022338659B365153882510C68108198522B90410120CA2C8205A142484822C12284024450EE3062D08B78082866889402A1BB821E1400099424141406109252480B690D912850B368A24A92C11C3056244819CA62861484A53B00019A67103A68901382DCB066E88B02020B7311BB3659BC20C9B1205D0324A48A049D9A27123122CE28224D9B490633648C41060D2824054108223A5510044514000110149850A21129C482C042512108784092442CA8081D9488E1B13021A098298040D90269052202D11B728DB36891C044C03226C81C26124C011C3084A1A120DC342125AB045C9C6291B30114CA60111B32C2307819B0612E31841140229C83230929841DA060D93184160C891A0200D513069E0A409DA98416346701C4261C2C604E3081118C0456146100127716336101B914402B00D144488D8944D121228234270544072114524103105CB28504A9684192368E0360892C628D0A271D204009B2220A32620418890D0128612279023A76049920184B62884407191B60561182584A2101A069264845114A104231268D2C4292205129248051C042C1A286480B4241AC8719A1209C9861189168D53A80D14148413A08461180EA012251388080A9350599228D2A2201BA008221509433492924412CA82441C144DC0008849120A52C86510A65159800860004A23B940518408E2906DE2989124249181A80023824963482A412065A3040503906C9338920C37050A058924450E13494DCB4221E1104A59A650CC420CDCA88DA4269112334660180A0422648C189080069004368513044494881021916804A645C40448E2C030102946823246142081D32601D238684AC640189740C3122C4C0441018584C2446CC400100C25712243901C4486221610CB468D1B2008E29250E4B864E3C6814000300CC151D3A4101AC04CA31486CAB8018B909198C44D82B800C9C20D88063099246D1B356D49B00804064D4A3686994228E12280C2C4681A244D180328CCA06CC4288AD83804144951599670C01645E1906C9432252416411C30111CA14894048E9BA208C1980409C649CCB620232652D93460CB08044A1624E04668E3C20C23258C50282E54326AE146045B245002176E13300093362D9A064ECC44080B44310BA3501B430D53168943240A018525A3362A20318012874893C265D29221E42466D3008A1931129028680B2444C49828C1046C92B86DC9A889080831D016480B322A88823011490562200989066891B24020A048D4046C981646C9B64D23A429CC0490D08200A382841A450859148ACB805009C645493061CB126C41286A024980D8262054B64CC13086E2100D648021148524642646D0448889306A11426119C47051A445440001C2B86CCC388058126C928031080202CC340A62C8691CC73143B681113062DAC40580300118844188288D611064108680198421C82050102592144568C8802110C4100A039224412422A94102240684443262100DD3B84881988CA020805A46651893919A108081A02D01076298124E21B161143070400830044891D1C221C2060A60A6658B84800901255C24850B396058A4884B961062B01111247009078411844962A2454C844D81302E80142D00133043C01018866850320DD0284AD9824554A6240B94258C302C004849D134868918008B847122470A5888800BC884141640C3144E13336422448A9A8651A0A4648BC04DA2120894C0441C918C8A042ED8064D5B1800940822C2C40DD8A4900398694A86901C440212470C122950A0940414203181288444486E82884920B22D139371101188DB080E0C328A10A8300B274D88940843886899A281C82012C9482C0B154A4A1689E29864A0382CC4203124A4009A068622B405D20809C304417D180ED93D26C5171687CD43FBF6BA795D1C7C15936B549B680CF2EBE9FB44C51D62DD547CD205659A2CF3BFF3D9AFE85044DA2EFC2BE70E056EC313F7B7FBA589265226BC8A24B7B112CF7B967AF99CB71A120B479F611BC3D000E4B38D802E2533F9886A6AFE8DD383581DF8FF83DA2F308D687EA7982DEE7F81DAC574B1F7E3DD2CB010ECF084CAF4E3AD55744CF59A7BC4F380DE877837974EE1489900865C33DC3CAA99E08A6FFC03ECD8EBA4356CB5D23D9612F0A4992FF216A006ABCAED535B5DB40445F5AAFC3680EA522D260B86BC75ECF87346421243D63B889B08E52E0C1C9C1C783E4DF09E61CADC7ECE41D317BFD4F2F6FEF777E681E4E6690B08830E5F1F4EE92959C1981E4CB746D1632C00096EBA57C8D0C9C77FA74BACA4AF7C1C117E7918286BF2D4CFBB387385D928180176B3BD05E2768247F586B4E817C6783B4EB7AE95AC792BA57C707A61B47506D99C36FDC5618BD8D2C718F278A3E9D52E14C224F779BFA8AF2B0F596E93A76D2A21DF4F766753FB34F2594ABCEE60AF2D8B08DC387A8BC1A36C6D0A08316780848457F4792A1A93FD50FB1902E94EB7AD5DABFB0B5C2EAF0C778799E72E6E13BB8EC2A117E90D0A5C9E09BF3A5AE930DA3998FD3E1247955F0502D316EDEE0E957E9DBE71E9DC1372185E89782FD984C4BB9DE1962B9CAC63D8EEB6708C69964C9EF5AAF7C3D4BB6D993977A760F29D46217FB7FEEE11443C561DD4480D48C3F4FF1987772C108A2178BA9E0756FBA4FCF0FEFAD74D93D1B40A04B82C922EDB9BA2A2EE3C3B0C81184B7C29709E6887084F3DECDF2CE555200947E9C5904949EF41A30576B8A387E2B82748DB73EB7852929E6A8BADB3F446EF4947C099638B213E55F39AA3587C5C8EEC9B2CD26F9048CFE58CA82EF70A96B8C81143E57C2E822BE4FB35EE6AC3C37A1FE6ED44CBC6A753E379832E1D912775743B62C6C96BC97D41C2F8714DD2E970687AFC42BE03557CBA071289B81F46A3AB7FF15A207960D83174DB95911DCEA1AF71F2063939D1E1AB0A9006BF623DA4AC74EBD66906D50BAA1F09D96203EC2872EB6FF36B5C8E8A3256FDACF66EB73361AFD4B4BBCF7110DD81A7075D78D6F1A4F92B4FFAAE9C32CEBC29679BB276447790C9F4A3172503475B241C5E02CC9C4DE0C44F802637829A61BEE95F587223A406B37EB60D7FDDB4B86EFBFD88159E28251F56BB37CB440F7ACC87F5324B5202B0029BEA90D6B1EA5FD25FB271A8D8133C95EEAE95BBAFDE9F2EB4BD1A0C659CA2988359708ED9235DEBE98734C867E2D120DEB050D1F2A3FD2EE73649116218BFCA6A135EC3A62F8211C77372388820D4EBDD2B77608FBDED173FC49FDEAAC54E91E5CC0BC5D809A1CBB6572F2C1F2F81D78A270BEE14E6090005AA59B897100AE1F9BC36AE83D369AB66313850D3D8A99EC8A93E7315BC90CA19C502E69A2D982642D85C5C8F80854CB1D04B74A9FD4EA1E9D1FC43733B2FA5C0C4E8A093E97D228DD5F89EAD0DF4B44E5E6B4629043427537A87BF19003736260D26BB4ABF49D703AA372E997A7F82EF15526CE44AAC8AF9CC079E8B13CCE250BF5D081EFE74C212D9F84C6FFBF7353BB91947029AB9872A5243CE69E42EBA244840C2F593AFC47AF3DD28160DD5676081F3FB67958E0C5453685748DE3CD3D20F4EB48E50F62B917D6E1DAFB4F803D0D4FAD19B844498CA838846FB1320E4B2CB7A1E3961ACC126B0D0224EFA0F871C760371A1E0FAD6B90461A8FD3F32836BCA0EAFA91219154ECAA950DF2B895C263B27B0C0F8DC45C172B1EB6459586E2F8D3F0E17C176130E94033B43808E0B7E7DBD771732E96A6CAB939BF50B955FC44F27568A065CEAB2B0FE06CF4BA6C4E2ECDD097492724FAE6EA18209EDEB8AD419D3DF0757C493E3A6E2758C118A42D823D29A04E7A2A700DB1D71A3C86ACFBB95B917B7715E393C9E4FF8C0C9924E55E944B565819FF7080AAC7BD5F87890950C02B6ECAD7E3DDCE2AF9FB4DDCC101B16B934DE4917315EA1B4F8F6BDF01C8948109EBDE1EC8165DB27AB305B8599D0F7A29961AC85E0C6F330E02B8FD037CB33A1361BE467E7C028778B8B373CAB5D9C8E0C2D55ABCCF6B39C92CCB3AE854317A9E8E91057D68087CA7D3B68F2D62353E923B87506F59C412E8CB90EACC7F6B9A3D1A1CC8D13ED4A5B35B7D6C2A4DC7FD630194119E61439A33FDF0B196FAAEEFA671AA935653181711E21A6A3B6AF02B809CF4E445CF9E5C8F9009066219E0CA4CD808669ED204BB3D1C7F69BF95400431535A0DA03FAD81253FA9B24FAD1C6FB553A8781A2C01F42846B9B25897EBD90870DA0068CDC86B0A56CE04498A6D4A3AA4C00AAD5A4FAD8A2CA3C50632DF3B43168A1A5FD6367208D751EFF65D5FA552AF4E5171BA74B1F83945F28096E1C5E997993118AD44296E740083580360DF0ADED3AE265A269A76457B6FC0F7A677200E123D8DCBC4724481F63E6EB7C8FC375D9E726ED2313E82F9C24C79F9901FC4FA87E366C67CF7CC0C1C058E37F12DFDEFBA637046EA26D86CBA5FA7B0A31DBAA3FBBE71EFD20F14AAC9CC24854BA24AA1F3BFDE1B4D9793CFAEA5D0B16AB624F0FE6A2E190EA517C5ADF6F61206E6170ECA282471AD375D0695F986D2C923346C2CA3E9DD95DA2257227FD0CC0AFB29E8E94571A2906708D45CBFC61F7B050137AB738259C34478C733E54B9AD2C6FD0B4E8A84B19EEBB8C22C4BA69AD028B1E06FAF8454AC0D20AFC3683F20B798223DDFF36606DA5CB70F82C7C8615515E982E1375DBA9B69334EA175F82F5DFB6F3F5E48BD5CB097A6DD0B93E4D438D28085C4AA54EDC4D3B365AE1E486661091CF1080A1DC3B7BCC44A56461622BD489D8BC7BD386265876EA9A8D44810B39595DFA3B5368640976F813AB802E3502357954E9FD38F7A01AF24B4901EA68368EBCD72367F8909E52779D13733EB343D9FC6E87D7757C662D7B41094CD882BB81D850D4919F26AC15BAE31F29853B8EE18F035ADD3A78DF5218C7D7F21BCE4AB2A7AC948E9828FAB018AA8D3221391ADC9A11C846ACA90F755391F8BF64370DE4355244DBB9B2B25135C75782F8106BA0FD0A1E5369D0CF473794257D4A5C2C31E65590CAC03F1501CC0F333C0D07358E08CC6C26477CD83AD3B3850447CDE75A9CE082E414AB1970CAC756F85DE6C4FF9B3EF977A7FAD9598F492B2CE4F7A4381EE6C090282BAFACCBC2D1C3EF987C0BD3E5900330F384E6C79A63628E8AE0424C605ED96A623080D6669483C77C04622DA1B86BFE2AAEA01F63F67E6868B4B1296B7A619050CA400B025BE282D415EFF74097C2B5933ABD9D0CCA6DAC48D2A0DE10A0A73F0885A978C5D1ECF61BB4132B8BD836B6063CD8362ECF2F078A50540EF38D7773F821D0947AF56A457349E59996DF23ADA9638108F297AC2F3D4E5E6ACB13B5BC0DC14CAC6BF06449A265F8681ACCFDD8C117F22A33A59CF29B4E746522EF91CC31A8B14BEBB980951AAF7B5CDF6B991D40486E9CB98F84FE7233518DED040561737C35E14ED5A7820243A3E828C6656DADCFCEEA3B96CCB0F4C791BED1269C6297CC6FD334102A37577C960E97C5AEC11E5B2C5772EACF3782D1F3EBBA987668D822406D9D22FA542918E76BA5D7FDB471077C924D0830F56D9A0A777B8FBA8E273EA670AAE201D7BC2285C78A7DD8AB1620F3488620C95F09316FA13AD0306A47740D25A9BF457A48DA5B504ADBD4C8EDE1396ABA8D8C915E3A55723BD64027EFB6B81787099F06E25AAA1A034F4F0535B6378A205C238DA6CBAC1AC7A672AE2570F37337A0FC8036A4D21F05D00CDE03E5758F57895939A4B7FF96FDA5B2A2B339BA109D0BB44F23E0A786A8664486C5FC5FC159BB988683DDF03879FEBD137AE92802CFFEE0262382350D9A745CA7C56E607D3980948AAB2AE8CDF0B560DD2E8B24DB149FCB63869710FFF439B9827B0D2D3A3D5B41C5F2ACF9B3437FCFD162FFCD26CD6FC6C0ED7EE53D27C61664AABE706E49D8D6DF790B5D43E9080AC62ED1025BFC5F205CE1FF6513F57D491C6AD0407F55C20B00F130DBDF49709785DBF1EFDE8B68B8340662048391E8C9D9A0244B62564481DE0E55FBD863076C051DB3D7D9C80560D8AFABF6E539A07A0D524F2E85F4130EDCB91F98EE4D286C38AE7DB6AC285A0CDF3C242F8A135CDA62DDF3FA2E5EA7BE1892FE9A0573C438B130966CE9B9EA94BBF73DE63760A45DA17FE69B913D736594EBA6ECE11259749E36D00A1429D6E09FAD4FB4DD3C5D1969013FF128CA3F235FEA0F43FCC8FBF1A7F48AD7C606A2A147D49BC1D8888F97DB44960C80F32B46024E05F4D346CCDDE189058F9F167E8EEDA366804DF647965C5535E24F1DA228A6D51CB73BF2D6BEC546A3C0B58EC2D5B9EAA034168485D144B8BAC206648EBBE89A235E8EAAB34DC0907896FD6A9D7469680FDCFAB4BF00840D58D3DDF91CD7C10A4183D097EAAED94D693B6911AAC624BE14863C23F0BCAD72FD3869AC4E14DDABC3ABBCAD1D7EEE9DB9E383C6DCD1FD0A2EEB4DAB2FEB2959C879AF1570271222DD74F57A9494895E01EBC38D557D7C9B67F485D5F4125ACF9A1ECDD9E22BFF830DD869AB3064609953A9665A33FC53C37ECA61B1B72364C80207DB9245FA75BBD460890CFAF3452850B61528B23276F6258AE93C641A1B" - }, - { - "tcId": 59, - "deferred": false, - "seed": "45CCECBAFEAC42F2D9166A879175A6D6263C3F7F9B5F39F27A1578C859CECF89", - "pk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA756809063B7ED14F8401B21255D6A7B6872DD473407966AF226EFB110054B3EC01F7DCEEA3DAF2E71CDA93F08E6BEF1729455A1943A85360E3641502C97168F621304573F7E87333E7BDEFB3426C4205DF894D2E57F9FE7CCDBFEC5F34E18B7A12E8D3F5B0634780E06E9F60266C680C658F5A4D36AA27AF28438B53D15F277BACC9C8086EDCE8C30712C33D9E1D0226F7B618EC50DEC58DC44C6C1D58B95761666BF8D3CEA00CB4F0FB89866B244AF1C442FBF74872AAADBCAA326929D26CC57BDAFDD8E096ED1683D196323C38CB8A778C10E786FBFD42FFF507527EAAE2C4E002485C00F9CF1C564D11E6D703CC7ABC9FDE9B356A78EA11AE47FFCE443739CD396708F2E356265E9937EA88CCC72D11B5B163CC8376D3D9CB276185C2E54995686B858FE51C1F77D4F19BC7B6CD6748840632B5D402F2B483FFBC38A2E13623128018E6EE4C69C8104F24E2E0328AE686E1CC16BE4086F8E5BA323D242693E4D6BC86BE3E70F25D54D1DEC44400C181F6796D6A6B373ED37E684FA97B59908A4D4DCE9FCF77DE11F13A674B38C9757B458F43A69CBAD899EC4BA0C25281FFD1CB07497BA154AF58B8A8FA6F63DEFC4B8CB3980158A108E744A93109C6E54F69B38BCD851BEFDD4D3DE6B3EF1FBCE494F6FFDB5752608099DBFC9C17B09BC7443D15ED8750E3BEC0080D8ED4CCFA609D61CFC85717AF1C117FC4C0A6899DB99B5BD5293F6AB51D15A0323EE6049F21D4EE8B601B3D28A95F4E3A42E868480219795B11B7C3054F16E3C7F7457817791BD9AB310E6FA876E747BA3F6AF9E80AD06014A6D2F6B8D4529A0633B4D4C2C8664FB7A8F873DBD6B49D481D813B71D6FF5ACEAF851DBBF0E7BBEB23C276A58BB56826FAB8A74C3F7CC37DA538C5E698624C15A5E4CFB27CC3B57258CC86A5D54FE6903CE22178BF84A005A9B36AC5CF79AE5020E3D5A7E509A2B733B859FC21425746C39A36F696B752D7B7D65B32392E5B2C9636B2C2FA8C1D01E75278F687F122C294D9052A1C7F35AFE484AD5DC503B71F247B819EE60957770244D1E3654C600C79EC7CA4DA2A8D01469DE4822FDB1192A354D093782ED30D54004E624B51109B575090408177C1711AC17E779AABD1878FF6AB812BA7B616192A76FE6E310E3714643202753C780B1F83FEE484E8FFF7C8ED7CD6AA424C8C8ECEF1B1149CE636A13E9C2CDF78DCA062BB11AE3559FD627C5C78DB450D62E1C990560AC5A699985A9F0BCBF47328B68463FE60C32F1B5FC613F2E964DC1C803C1B057659F62F7A1081DF280BFB4CB7C15E2E5FE51EF46777DF704D619C01838A45A0B3A87905FBB909054A86390BA48578E42A49FDB247EBB239691FCDDD1A517B932C43C80785986CEEA1254FFC3782E9CBF427C1371858A7DD5A181398746B924FE26D85587BB2A9F6AA4485CFF37319B53D87AE34775FD2A9E3C2144870BC6DA316757A7B91B9750CF6FD370CD01F21681913117A04A7984A0A2699F586BA2D14909EA7D65EB3B2FCE05B5D53A482FCED56CBEBC3C967D88A9C9364EE93A9719E78F941DA9C91CE2B53BF861D1BF75BA002D28D7DA218AEF50D6E457A8C366A301275E5A4D8059977233417E1BD6A0921FED5DEB24417F1CD384AF00B3AAB654C61D353B4F01AACD13F47AC18164894649E261742B71F6D8222F24E7CECBCDA74B6A0E38F85BA6CA8305BCF27331295D27A4C6A005EAA38C23D29370AA37C053D71D03B58F7D7DD73AB04E19B6D0EB217C066CB675CAC07EBBAC2C3736E1FB379E5EB175C9361AD9478ADF2D5EC5C92026FA31B00540DA61DCF8C5283FE58704BA7C3D4D60F055C155A1A82C6FAE19AD4E95738B461A6D11A49D21E94A101AA40F8D4D90583EC98D2B41DAF1AD18BD3A6E41514E313CA810B8523A256E59817665A0C489D1555D382A2E5BA182802759DF12A56DB7B9451479E5A197D7CD7F61F5AF735622B4A7A3A633B16700B97208FAC2CE6EC8156500D40B28631F77621C00EA6DDA7580E4CE8E0E36D581AFCA211B369ACCA07C814C32D89054C70853189AEF7EB9AEC25F5928C70EB0FB4B7266EF39847C13CEC1615615AB6D4333A8C0274BE5B517528E68AA31F7AC2A8C312FD8A97CD52A01428AEF3C871838641164E5BBB83F9A7DB2A93B4CBB20C0E8C79291EC7A443463CD288DBDB559292FCCDA4C8CB21465EB50D1708999876D03F10368DC38EAEE4B3D544D905AC614EB7395C05DF986284BEBEF6106AE92A0969B49B645F6D859E0C22BAB4F0418D4481EF5FD272D700077C029B22DF3A2656883EB8321D3FA8EF586EF5A4C7553B990CE2BE6E8085776F87132AF4A2837A467CBF0FD52B726EDD8EB3CD3732F0A5478071FC98985375CC392B9007B88EF91D0EEE47D958ECDDBD3EE6D247335F651DB7052B06089ABDF1C7C53C467865DC009EA908CDFA799F8B6FC90CA6FBB7C57CD71DAABB94BB896AC501597298DD91E6DE37123819BF60F51704BAD0E53EE91EE8605502DCBCE921666D349029AEE37E4A351EDECA78D62F2C9F24720C2EF3B6CCD7A71EDCA01CCC0499A1BE59B69895DB80CC97CCC7E18D5534858EB33F6C9AF4E097FBDFC2D1CB8A8594508FB2F4CE77C0F7659166DBED42C4EA1C509BD565FE73D480C107AA937DA52EFF47632EA8CF47B8010DE6CADE97619A4B4E9DABA5D58AA126000BDA1CF9D201F6DCC49FB9EBC480EDAE5A9E18FD6375438D0AB21B90BCB8B37F4315BCFA34077BDE114447224D23C8D38BE4FC49AD43D9F4A8780198A1C39F767E199A7A6D808761CAA04274BDDB3CED0C56994AB555886F8B04E7A86D8E0329EFE153C2467C86D8C1AF6A8B968517FA59A197F840F642F94E282CD29ADEFC892710E23A26342DA5671FE3186D6E2A23A08BD7FC8207C490544D3ABF54B28B828D17B587DADB2F184AF2DFECA9BF5938ED222B48A44F0D22E8BFB3CC790FF04739AC85F830F9DCB538848B98A272682DD7B843C732380CD02CE32819DFD9C1499D7504E84E96F18EE41F41BD15CAF1D43F34FCEA37D1D801F4C9FD07C45FF9002ABF824B2C3C1AA33839304CBCBF2DC972186D9DE1D2AE73FDFBC0343379473632D3EB29DA537A918027A340CC7EE214B60FEBC384183FD988F2A2ABD79F01AE72898DCD3E43F7BD4656FCBD0E37FB8E055C3C481E666AC0D6E604E985564C79457195F3D12480D7F0AAF89DD4CF0A1922B4716F044AADFC79D44441AC0D23EB6B576EAF5AECC6478AD82B3E05398A06B4222F5416E153766EEBAD5013F54188823CCA0CDB128ECC2BBCD982856FF80C81BD0E2D980B57A7CDF5E3E42B713D5A6ABC45C9E24DE97B65015D1803832C412E3250B1BB9D581D19C8D3E42C992AF8AAC4CC48C7951048B701C815C78F56C33DC8A52D11F6D66642C9E29EADF97217606F3CA209F9C9550EB5F0C81276E455DE699D7EEE328089B7C2394A3F014394FBA7C9A02DF915921D33264A2F0C436DDDA7D84499B2871B53C653098B64FE8C4AF9602ECCF194A0D125C6DB6B6F171E2100DADB638EE2DE4233F56BB9BA88537CDD4E015D9DBEB2BB1B30D69912517A61C817165B8EDC34B5F03F3C9CF03EC6F4EFE0BC2B73788202675144D4D97EA292", - "sk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA75B72D6E6F95CD49032D373F9BECA5810CAFA20CB56FC17B18BA507904403D2CF5CFAC3C3FD6A484D144B1F5DECB41B23AAF9744D52FCD9F8E51AD2CE89629609168C1376CCBFEB0EF1A9489F451A239EFB729A02244C3D7C4EB0DA857CCC7BDE880348D0882618A0649A22249DA104622A401D41864E2B20C4C16204926244B202C9900426216461B9588D1B6049414110B80908A04422428420B4491804440DC4420C2462220B051E386450930428292018BC02C9C106824246844068A02B98D4CC684493070E3164A04312992B88C1C158E08C3489C308A9C1028C0B64508888C61802C0B93494B923044A489083022DB948D5A002924077209332922495094B86863482643C00D52240953006E1C329044842D9C10521985452044259AC40154422221384459922980002218270A200208D2C68C6008601B024C0C9329C1385110B429428441D8B26093A244E4420A18B78C8006888824820C1612094742D3A860C3180143B04DC9260618A30801982C19040C0B4964D2340819364A132961E3268C0CC3200AA01050445013046DCB4491DC42701398812421284190500A956D22808DC2120C0213904040020391889A82881006321BC168D8004E08C34509B4514CC411CCC0881C1944498651404211430004E3328612A069E41211D826115C1005443249C986010A258C98104E24A7250C09009B2211019080A30811C9C84C804600A014668A308C4C360AA1A28409A501402862202984C04851618409E1B8858B168012390E1A812CE02832193121440248541891A1025099244488942101A2255B286611108C843205913684008511A294690AB080DBC23193C24553A6899896299898091B381191A26408912D0B29009BB2509024095B3869E19400C40602DAC02CA2960DD3448048460C84A66121092181B631A4864C82326182B2100992849C101054482DDA964963A820C42424E23004A1328A5C124D8B0826DB126923904101828598068812077204B864D8002983940490B464CC086D1108440947705A32852221899498215B388C4420105A0482839025C9361100840CC1428E84C628E2808450404D08467009A200E0B66958806C248510042246001264A0320804A785A246608B260E5C1830E39631C1B2812082805C38602319289A146801A3019338091C0392C11011D9A601109020DB224491445080A22D248910C1B67018B08419B1299416899A828821354C13C93050448540982CA11029E1942D582288C932804338085904301A238418466844121123078C8440814AB2916232101C475219C48C11042E0425855B80291A1542C2866D410225903670C8264809252648426582C84113394A23258D620031E40208CA8805D048018A30910A3921DC426909116C0B0380210741DB286A118130DA12891A978C1326020C2171602292A1341211158480240C0938851B062E9C846D492408924291A4468C9C4851893806DCB6290A046012447158C668031040581466E1A87063840C08A381228925E00648A01641140912D3006DC116055B46801C450463424010004AD2262C0315729B424D48868019342E04198D98A26D18083193A64101304C01268D502822E1264D1A8771D1361203392A9C428DC2000D00A941E0140124A821111172C8040D8C96600A440884068218428EA42212628248109664E0382DCA1881A180641B429088122610438CC10681222762D3B02913086193B08D2016265880440318119A3012623830029065A182846012805388901C143203256984181222A98D03298C00246D0AA96D63800C0CA5311AC868CC18124A162A52264C000892C304420BA40812184403156ED1984113904CC2A8081C38800C826C58B04904312000B87103344649382C48C050CC440122949189B40C18326EA4306E422092198601924085D9944D94B2695C328959800008C18821B3649C421019448D1A0882D0344C40040AA00204A1840D983652D4004E4C228EE32620243089A3C4610A26320935810114281B45601845086142491CC748A0184D432285E2388499469204962991C62514992923A761601022E32489D2862921A805C004715A402D2044881B21610825710C464E604400A2184923476E19C80C0A449021300054C205042868CAB290CA00317DEB52658BE9EA23E8D1D8AE6C5AB563D01DA20C5577A3695168A3DBC27E610B3529921FF3EEB2A866379379BA3689271BBBB1261CAF2736BD9BAE1F12A5E9F344E853B71C6119628427B790C8C7A1113B896B75A9A7B539E92D8D29156DF366BEFE74DE978BE2670CB07EDBDB6BA156AF6C26C5CAD55A4B44B61517511FA3B74A42FCD70207E532C68C8124E0665CB221AC3EFF05213ADE3C37B8F5A59AD00C46A5E8B11614008FA57AACC54B07E886B7CE9A4813DF22B5C1C64BD933BB76A95ACCE5787DD24816BC7AE25764FA2C83144D6FB8585F5E8895E86EE5650031AB9674F65CC012CE26B950A221795DE8F46B5DC78B9D9CDB4472C257204F32379A823B00C20F92243962FF94E5C4AEC8ED84D442F1F23ACE5D5C5850D0ACFCF7B1F56AF108E6483DCD1334338C5514D2808FF1BC34204C1740FA434BA8A4EE20C2D2A27589FBBF68D889A616FD6DA0C32FA36D666FD79E426BC54E1BDF06FA0470DEFFC93D75973D6A925FA4E5002AB614FFE1E9D5110A2DC3EA5E6096CFF0D46CB5B3B444CF67D3213BF7A139C41F70DFCB57E3490B84CFC51FEE7132FC86C3C44C193AA9ACA24A96A860D5D273DB96F35DB99491CD23227BB51105B3672BA3044457642CF680BAEE402784D2A73682BC28239BFDA08B24E4B542D5B5931F4B8CF4CA0A15A3F4012D9C0BD5FBD893543A4271DFE87E77C706186645783DC23A5BA180559C66DCD151F518B05A98EF3C64804869A46CBF41702A3E403C94B948D2E41510871FE7A159290BA88692473223266D462856CBC9280B12777CE80C8013655F6760F5715865986C688A336EFCB92E20D40F7BAC3BAEAE5DBD417627E3E2EB7D0D8E7D413BF703BC30D4E3D594C6FAB695F93B2CFECF0EFFE92D646083B6BD124141CDE5236E89579E8C76BBDF9681D80D19061147432075B4C755E1102BBD53A2E9E2136C2B02BFBA33F26CE1D39A3385BAAD5A5F8AD0F9647DC9B2E78434AE8663C7E9E14797472B4A646C8FF18470272BA12E7FEA3AD96E4E1F486569F26C60FDF7C2B4D3AA0756381AC8346636021322184D6B0B2DF793917041D152C025317A6E52134C955E21B623FC15AE57BB77B5A1824448AD18C30212390E68AF28E06A287141751C708F8F2CD6BD46FDB940EAE5F4376D8F946B9FBC8D31D1689C0EE560A8CCC84205173307B5EA39A502A9DBAA861B2CF90EFC3BEF7E3A74159ED7E5993CEC4F565626FB84059C358F2110AB4928454C4692195ACDA560267CB505B69E5F53844DCCEFA5D64CEDA4DCFC3F92A63D163184592641C2BE726FBB32E8754A83315039422681D2F902080D02EFB2D3D2A5A79822132126B1FC849641B6D2D0E56A42B32BE25C4F3CC52C7C17B18B039E51E889214A86FF898C94956327BC3A265FAAD1E1068C7C16A3C870FA03CF3FEDA3FDD9131DF340350F80E7F0CDF4B7210E971879E3E2928B57DCD40CFBFE85B147275EBD6924511EB293966BA6E42B67DD97F0F761E2C0F1B58081E0F040C5B832967B6508DB8B7786B238C598CABB104441B52D270F1F5FF333C3441337E925F259F2347A53D50CEC83065760A4E5AE4DAB5AC16A402D80C8E429FF2A90F7B5D3DA698D82DE8BD76616345B53967FFA2BC2882E4EE25C881382A4D619614F6870532EEDDB8FEFCA9A19FC809F5C6758AF8902D1E60092637AF30237A66C92FD30627AA51AFDE86B581E14D86E79B50162B7443AAEF8E4A2B3872E26FF579B09740E25CA0D674B229D96A8EF0A3FB87E8CD75AEF7706750A67C6F5A7639CDE9178CF37885FE9774191CE41A22F57660D335BA8D1AD5928103827C7FDB74655B0B7B3D3CC859A26FFF60AF0DB79F3EAE481A0472E803D59EBF3BA2C85A5B995C2CE3F0C04A7E2676A7C01C10EA1BA0A351383FDAFACD11F3F5403831704196974A4643AA6B0B57DF54B8ECCD1B1814BE540A063C7187B573D0DD528B6596224D0A9BCF5701EB056A345112A7C393A797D1C1590280EE7C6764258C4B151559FD0719094AE037C4B62350D949FDF23B7B294990033EB17C9F70E0FB465DD2F78279B7C1C313D3FCE7BBEA597CE11C5A47ADCF5865CBAD0400D0CCF8F7E0FF59F5389799D08FAE155083C2DEAE21EE6E5E72521A09C5BA7149F188F46E20ECBA23E982B7E0D28C92908B2213C6882DACC7F056D3C285FB8D6BF6EEE57AAC0E36F8EE51AF5653FBB1D358E06BD804115C0DFC572ACEE647B223A2FEED76BE581E439EDFBDF324356F7401841B3E1E192D7D3D8E19D83F757A20FA7DD4AFECD1867AF33340FA43537F7BC0F80235C1CF9A9837C94D7BBBC0E820AFFA4EA36BF685A82EEE6BCC662F94E5EFEA083802B9A24D3E9422DE0DCE4CCC298E4329B02A3956363C88E555816510E7B642A421AB4F768D347DBD05A5B1A903860078F105A7F0AD52DFE7FAB396FBFF271BCB5F7ECF387263CD0114299ECB39559066B78958B130CE25F1B9A75887F188C43E746FAF865B4DF3EBDA1304C70815AD16FE0DBC96F6BB61D659C7E80D7A46F6B1F070409829F69DEF6C1D87CAA1DC71273034D8C3C22A4694D2992D9D1B83A71DBAD8CF0A6C2B4ECA9DCD53A827A5D879B8279DC3A52E0B879293C07FF2E1DF21043E919E2449B58D75A3634E008F6D10624A3CF532F73BD41FA73571771A8278FAF79A85EFF2A2936D31BF878D304F1736F6851EE824B87B23FE9D2FAE453BFFC27757ECB335BFCB8B0B79C349DE2726AC7D3AD77C509A87BB58ED8D49CFDCF27CB80F2F9A6284BD43602568A095245C787F63BE998315F6FA0D2F7ED4F138F07706F4C9D41D9A5CBC83E649BD140BAAA55D15B87D40769A96C5E9BD9B21B786D37BB9A4D6897F80C8B89C3F3AB69D419C7DE651643CA76AD5342FED2864F3DCDAEDD6374DB3E8D044E10FF48BFEA1D5247D2E1FC075255901710801EA98404B2E0A009EB8639D1D2BF09FAC2E7163CDDBBA6C277380E786C076B762A3DEDFAB38497248BE093FD03C1259C7B770CA5532B9F0A44B6AAD5176B8D0B04993B5B76699891ED7328D340D2EAA4659D0C4A3D90505836FE0C7B7D424D2037F04DA135B91C6291FEB6B4CC190D21465863223D9CDD4D11FD8CA128377399D093768FBEB45E3228167F457E28C88886D4A5DE85E0509C0E18DF91BD71051605A51C218DB2DDCF7616FE7E61B94137D59ED68414C3012C67E0007110DA0DB233DCC71336FBF40FE2A73DF2A51639EE5546BA7EFBC8242C3093A6B6D5D96194501B72FB66B2E47806F666B1F6CECD83B8C3ED04FE14A36F218CA8B67FE20FA0C113C33328FF34EB87403E705257281543797F2EE63C7E23985F5D1147302A4316A5337650ED4F5AD31552490E1EA77A361A0E4017C51297F0883DA971E34AA452D05A44D3AB141D652D25DF3711D40A61167D8034C40E638EBA994F62769FA890D38B624076AB1260E718CCF228A338D255D24890A5701D6A80F8F944AC6AB6289D1E7D10196A173CFEA4D4FB6ED1249C11B1E7E6FEAA15544350520858314D3E0341FCD1612D6388E0079B385B2ACDD20A227A18985C27061217E2CEBE13D70F849F2512EA1F71E987BC4040002A54021B311DBB4A0F326355933A8B51E43A1B51906AA48D02B379154A47B9081F5652F418D39F4C8D8E055CE0AA5A5FFC9F6B9217D4F11D96B3859A28CCB7A4A9A4AA5D84185130C56FEFD6CE70B8F28182ED42244F8DDDD036CA93E81B31C82FD8567B2B927BD1FFC413CA02A58133475025C0D5113DCE589A0C159B0CA4475011B45C849D4D62ED00F1F81FF207C04F9CA3B8EE0308A498DBC81215A819BED2049AF1915023E72256209C924D99486BE97F6070D11CEEBF425951AC1025A885D96719D92D821C451CAA37B8FC816FDF716214AF207839FD0386E332DEBA3A94D1C583805003729872B5A9E9F1E1129C26408484BA267B48AC341DA546512E790BE48C05450F7462518BE0EF47A8D876072D4235BD7B6A4CA27A4343E6F0CBE6D5A39C9F460E1AA92F8A7097B60AD4BAE9B98DFC435ADBA536DCC0D413109644DD9D9F4AAC0A64FF68E820C36B0D151C3E51D9D98BBEF1A5740699E508205530C49FF5AABB0E0A99B8DB59E036E251F1966F86751F5A8735BA1A796DB720989ACA697FD883377DB331BBAC2736DCADD0F582F5323E3634785D777E6D41D73810934B78039D60259FCCA4B51BA231B8DD07824D5B3964EBC618618492A3E97D060FA4E2564180A1A91975C35F82E251B39650983441C7EBB4EC326B0C2958BF1DEAB2EFF0C959B9963A4F54DF3879C0683DE30C36E86C910A60CA95908434A45B5F76C5DB263BF5DF46F6D408BCCEB3A9F402FA12DFA99D756749F8CA0EA717F0F9233BAA282077BF46E93C81F4F66CA456E7B40E671848B0FDD01DD3390648870FB0AD807023B70A4626EA005771DD1095E306CC3A133D6FF7D645D2E71771FDC98A65281F0ECAEC106B9E6CA4CA473958CD65CC3875759D0222634E341008556409F022D0842A99E556B818EB631B99890FF37047F2ED2D3FC2E07B5DC6B72DB6C2F4E19636AD4C81E857F22FE40383DEC6BBA6D9118B78BA911498427CA29EA4F3E14C6E41205F1A89364CA6BDD12BEE4EF87DD7CA83890223C034B082EB6B2CB91E5ED225F6AF0D75D6BDF3DE95B55FDF6F0242B140EF5D45194A8FA13813DFE7BDEF8208939C90F71D1D68C080221748A28E" - }, - { - "tcId": 60, - "deferred": false, - "seed": "4A74BED90EF52CF135555B622A50D1A4F5C53D97D3176A1B184CE55380DE6FDA", - "pk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF6125285BCED3A9A3EE9B63F6A6732A555ECFDAA74437C0FAED714CFBF9690AD19A5D9B9E51A87B897CB2CA597AC944B1BB3657FD93DD44224A276E14C32AE838EC55213490B2F9F53B7412107A1D05D6758D487FA15F6DBF7F549F8103349D89B5872520245520879B0717984ED29684D4DA55E84E7280C297B4C7F3DBB90A7FBE7316ED6B1E075490A227095C4D18F50063781BB8A123B6407D41DDD071EC1D18607E6B5D7913289289146566F94A7C0FED3EB2B712B8DEA3DCC4CA3BD088ECD2B78971D823D661D8A1102BC9AE5164A56543FD4E2EE9C2F1ACE76A2B7285E2F23C0E6E66E5EF400E5C2DE9A6C1FCF6E4D60C714F5AD92F28D2A3209D4685C14C83380E69DA9DDFF1892D2F9BB9C9E0EB98E8E7E3E33BBE3D8A7999DF481F4B7D4857A016048D7B7BE2D44FDDE58DF6139FC8A1D0349407853D45D18630A3C3F7033961C06E5A0DFE4C449ADD2D4F66BE3BB19F39120535C9761353C5F5E695001B081CA27E1A862415C19323060BD436863669F6C1C75AE0CF896DD76D3CA157C070BE86D5B80BCB3CE5023B810F69BA4E3D54EBF2E53B92741E0E1E3086958FA66172112635A60EF6734D8BFF84A2782333586D66429437622F5CE059B210256BA414A887EF5E90CCECE0D6E9E2B294ABE6EA63BD9C26D20E4AAC170E5594A2E83A96A24BAD2F69E706E15E7B1BEE6AC92C7CF1B9AF28BF06E1EDCC572740374F4DE8DE26C06DA968F0D79C4454B12D28F2109FACDF8E1E0F8802026AC78B599929040984297F41DDA28AEFF18C3DB837E01F3D12E3752427A9068812D75C2A97263146D60DCB8333BCE02552126D5BEAE37F50BAA8FB23DE4BAC3C7BAB3C21415C1EFFA6E62E9A3DBA18F8302939A02E82B8284D104367F02FD4F484F98A0C8A2CC95D108E9EDDBDAFBD53F5D7D65C6CCA72163EBE58EC15BBEE65B9B65E3A5D240898C866960DDFB7A381DE17FDDB9226129060B5951CC83430F806A960D14F5935FA4371959B04E77EC978B09D08449D6DC2C3FD8DA655F4709198BAC7F2F42C4CF6C8EFC6B8C4EE37ADBC51F56C36D719CECABD5C3A1D63D08E6EEC48EA920D5A3FF93C2C716A76E89A4EB7946D935D859DBC99CFBD4DD7E2A36E8624B83384F7707467E336C10CB05D407A2D97EAC3E1A632C7348E8DED1EFB9DF72B4697C44F10B11111728E4304BD417FC174E85A69E8A1800FDE4FDE40071E2E06F725F11FDA67D67E682DBC3EE5DC866A0F7553F9E386AB08D2C67CBD4A6F33183F7C6631EB9818CE4620CF08BA747C61082AC71D5F1D055D91BD0C2FA96707CAE162614688E37B40CC707FE6C9EEC8CC415DDEA6E68B6F49C137B6EEC2F51B4E9D0E6A2AB2B92F7530E146F8BDE6D4CB559AAE7F8FAE27468E04ECBE4F85ADE29CCF20FFDE24F04C4DDD8C2A1E164769AA0B5A6A98498266A1BEFAE8073EB9C4EBA183AA71D6C98AB4F9D74614D259853E029710C5BA64D74C866EAFAA2AEEE577BACEA272FB76C40741853FE0552A79C6191BC40CB6CCF914E0B85AF88DF9553EDF1DF6DF7EB72275DCE3A568C4EE85E9731E44F470F00B2B95630357011C5084381B1FA5D0A55EE8D4299D17394083BA42E33778274F171A3CBDF9E0537031A272F04B283BC8F1B99CE201D9AF085A2CADA6078C7DEB922CF313065BE6FB3ED204F603ADB18395292680ACB6492DDD602EAD772FA22250FCA54542E3D68ACB4263DE0D2D442359321C200B798505E809E6B219FB2698871AA2A698544BC1C79BD6E18F8A8AF0B64AE7196D5640D0A1ABAEDA9B00CDBAA4BA177BE7FF03B0719BD489AFDBCEDD091AB69AD1BB66EDDBE03AB71179AAC1B766F14EC1B7F27B4FE46F2273E4D5EAA63DC3B83427423CA032D2BE29F057A9FCBCE8A747E59D6A5E20982B91D63C85A460E82AD028D93DAAB42DE00DA48CC0D4BE3AE85602C6CEF78BE9C238C368438144691A40D6A5A4A6E1DD19931B4D21FB779A03E86792BC63451352604BC177A8BD0DF71404DE42F5E35E6FCF96503277D09A552ECCC611A2A053887475EAA290ACD2B1F84878651552A796491E0A6E5C8270049F45D3DB482D4ABE5F91D89D5E97D985EE27BACE55AD9FFFC4DB7696567E86E8BDD799C5ABEDA6705561320EBEE7D0D3FC4203E30376406EBBE0297FEDA3E1BBCA5CB6CE1D1021CAF67BB9EEA84DF563D82B012CBC8D24D1FBF9BA366DFC1758B98AF3A3F68D0C0BFEDF4E76EC3C8D1D56B94CEA7E24991A44D094CE30A4B724A29645046196DD122727C26C96920131CCAEC02D3B45E513DA8BBD993DE91CFC10EA98A3362123FCDFFE536179F7063CD83F42D7047228C0CFCDEE216CD560BC5913D734A10286E05BBEA15CB293956F72BBA3A268303B43B6ACF89C20695A4786B01A5B8392BB975A25A6BDEC91BAA13F812567184AC8F3C0B7057A6409C0350BA92D75AE3030E2324F2BD82F09B32B7A38EE611A7B583052CE2C967192D7980F8FF7C8D826CC004CCE8ACB1AADC7E141BD2095330B7CDCFE6E3B0A7ED0A66DA4B00592B3BBCEC6414E293587E970ED78986461958EFF17F33C5B0D7A87437CFFFFC0EAC405499F12F6F4C54642325EA2FAA4E1FDF03FC9C8F26496F003289E4ACB9770DB201C92E5E437E4C0255C302648C38175C553ADC0F77AD76379D046B11E839772095805C6948FB219B9C26EE0D70EFA301F8096DDCFDFD0651FDB69F55D75F2C236EE5EAACEB2E5AE020C41B51F6329094F7B5A42C41197A574E4656B7E0D7B7108E6B3EE10BF44AE7D27E846F14EED09EC3576226098E1F4CF4FD5101334731411A1E3F438C9EA9350318331F917E0276521AD2C584D4F9AE1378512068AF29F497E4EA609B1FE0506432BEE5DCE18F7E7B83D0E5A9127F6071AB16196973AFE681FF9311D23B1CEB000E3E74D7FC7AE3B9F849A1052A87D3B6B28873337EE3A2094D42A27509E206C5DA5DF4FABED451F444C6E9699C6D4381445423928589CE9380FA8BA0EA486A8C97C5112086A4F7E5A19988CD01DE1702CC0C23ABEDD443BFBFAE11BD6BDE59D81B7A5749F4D246C7690A2656198A3371096C0AD58BB9011E1DFBB234453507EA439C5E967999DAFB04D3F030FBAA6005600BF39316A356F2C2A1FCF3365E2CD543C6F79CAED18EB04FC3BF02D2A43E69ABB3D58305C430E8482DF659994DED02814DA9FA99633979F281E218386CA9647B633672CA3232766D671779991E43BA9E8841302BDD269AEE2A6D99D658EAD444F1AE5D0BCE4BF4EEE91E03F1C2E29AD5B9F859A36EAD0BB8CB4D01A49AF7AB54CC9941DE0FB5DFA1EBDEE2C1EDEA77CB83606D77560A41BCBE9C2D43D0282D850164C4B6F2AF3F9F9AFBD7B53805D7BFBD8FAF8331864F805BF7B1ECFB72EBEEED31FD1877DC4682314730F86671A39275BC094CAFF3E9CBE4661B7400F3090AB9B638A9FF77B9DC7A5E43F4D03F2C322DAE8F44CB5CDFE794F385DA446C62AD9CB0833A7878A89968C01F9E67B3914D543B65FEF59290D107B5EDF2BAC0E8635B0BAB6A9D3FDB9A267E8C4A735EB1EAD8328030A77B497EB19787034FA2FB26CC80C9BC6AD0E63A83156BE42BD0A658F693D4D1BF4F85A3EECB4843CC7D58FA3CFEFA7C8DE", - "sk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF0DEA5466C45F3BB6D76E10FDE27C71282CC6E74D56AFA21CDB31A104662DA91A615553612DB8AD8F6D8CF8DC8246BD5970A2E14DA5EFBCD145FA638CA1945F5657B4CBFA716DA133C1D582C9562302A69C19C0DDF2925111FDEB189762B5259590B82141362452462ED9448821203110C0914C3632609010CA408210372260C209D822488C2042A13031E410684A460923C10CC0346590346218334D103462C8384C840272C832721C2372C0C4289B109298449019A631D146840BA9651AB284C14466C946069BB869E406445434106420658BA220A00081D418901886448AB82C40382903C5216334858C848848168E188451C1000159144551101040064520984544066019B98518292ACB185122089224C22D1CB16D44346EE1C66DC2022DDAB2080C894902374C11428042902C09314D0C212610930C8288041C3525E29084D1004890203221332218180058128D1BA56D222106242106CB46608CA068D0902DC2486EDCA6305B10405298410C178CD1A20991284C0BC8691BC14800A4848222298246840C4952D1448008442644028990A64C0C096D9A0481224471DC807150164400420620070840464A22244C82845109258EE1880D54265223324050242A5A4621122940A3A249D8A44C13C44103232A59924D61206A23362812A6440495211210865420406418491032411C082C03051118498018A76C9B220D03230C242820C4A81048206520426000074A0A150C22B14509430DDB008C60367081884013110618820801174A1185448C2840E3443193B060DCB4904486658C9291E1862952100A0CC248021560E1348522C6914C184D642281E0006C11212109424003234451408102A44041288E60262A01022E50C460E3406C124042D2488C8A00888B182EE19820E3481158A6600B464850B045981291D0882C0A4668C3208AA1384514286C18486D0A090D0C2765DC322D14A51122A644194845A00085DC908DA4202E18B7501BB481DCB6414A2282119085DCA64940A884444422E4326940802503C1600A008A4BA205A2262E1440600248645340825184208A14020929080049268442320B3131C10652CA981090462018A8444C4280022552DC462009325182C41091064C502031594881022904C4884148241114B60C08C568E38885D1B829D9C8601146129A0806514280E018200B2424410821C316400AC3681B235084B4840B014123B468083722DC928108129288327123862C180986CC22059B1480A4A830014624DA30080B33044148221BA148A148111C12118A068482C268242410E03682032765928224C2164201B160019968990268A2C028D1488E13422E03085263188422263289C48CDC428A03033119416512A5910205840882848438601A010E22A4281B254142A09192866419384D99C06C8032020BB780521652609881DBA8311825010A858008860C012708041148034620028111944410894200A1202464A009E00424101330E2303092A8640A460513202604B6480A962842C40960308A8C382602A408D23020CA06861B420C51B8288B100D62A830A2280143C4289C842819038D5432442385500A10901105614448519832820AB42C10490E5B360413498ED3482C8024699A3831A34468D4300464C4088AC4609436641BA70454A005A1C264D9126A5382281C062C0C226D18C36054C271898210DB808489204024A48962C03199367200B97193068110A08008A4281AA1249186119B40909814920B8571044485120685628420A2209194964D90324511A80C11C02490926900A8442023610B85858BA6004C142A14476604032460B24558380D0AC91144C80410834522387201374012460E031720C148321044051B364C8AB40D59064C82042ADC424CD1324E18287023162E832246E1A0241A3632A1182E50168263C06953B2511838800A8545C21269E3847124154563322E91020DD10469CC180523218203042D041865D20492840851DB026918462E0AA48C0C100A5CC688003311020422D4004603104EA12828DB028614110114242500C951214232E2384C14214EA446024830108A024E9940250921912489659A400613822C40C2096148420BB524E4A468E4A42812C860D32629E2464E2336900397011B80500A0165D4004C79598BA1392FFDC71C568B23C0F83C7E8B9B0A0A1FDD95163EE61894F5A05160F60DD59B40B17610366DBA74DE90016F765146B645EB2066870201C7123382F81B63D9C0700AD3FE71C0C920A8BB05E1A518B64F2F14801839ACAEC7D93FEB0019DD04E20562228D27B2807DE75432BD152AB4A8BF948AEEDCACBF55DB2BD53712ED63F99ED7DFD3D964E73687598D3E8F3874FA2D96C4C78067F6561580B5C725165EA7C6639D1041AEE5DF55BA3F8A78644DE76FF75854B5B1A3D087BA2DAAB0473AD6B3470CE0A411E4D2D804DA6B3A1DE69A87709A8312D56D74F8ECB01300E87BE085DE012148CD4FAB16765D7597890C3418034F43FA86325E2B8A883E84A315C68F6A849B863B7DF98F12D2C1C3142A7D5E425B25CBB9D761536AB1F0B149609D00A676DA927B96FB535E7F4BAC62243E29F97451FD7B04DD77DF10205EADDA73759BE70C2BB6A77778BF87A498C19A90B984BD0BEF97BA41CC4B12B915EEBB0494639B778F6AFED1857ECDECC70744EBDBB713E27AA8E87C67A0C45335B9DD700CF964A0316BC86AC91136BEF4530502A514F5D09AA73B2D94401412AB868BFA9FC7DA00D0F14245D952EA61838A7E47FD508BACC077F33C5D63EE1EBAEF84F3DEA9B7178C658FD5D30836C6AFC26234D68902716325280ACDD60FE4CE7E2B0CFB7A977A446D33EDACB8D799FEE0B71F7AF5E857DAE2373E903FCF846CB701DEAFC0E2CADEB666C13B77FDAE6807741E8AA2525D84722D07371F5CBC62574479780DFAC890ADDB7992A6930164DE9ECD36A5324D10100CB949CC20AD8092BE87315F5ECD9F1FDB1510ED1E2D073EF11A46CE93BDA2EEECA21BF2E273D2DA6E0605B2B29226982E62559E41B97A79EC72E3F35C5F847D13969AFD932C9056FD9CD9D75FE2122AC2DFA155264B8351A53868E097DEEC787B7C9DA89ED0A5F7CFF484565347954885535BC5461DC99EF622A8E261FEEB199FC4DA9D5CACD40D10015F1121D41AE315FF43407991256A74AC34FD25AF729AEBA375FCE2B8C6D92DE71240469DAEBCB0F258AC84292A3C6A3746841C5D498C5C0D490A29D4C1A29AE7A58BF9EE38DD76F91DFB357F06D9E56ED9E6F489C3E18A10785349A92126C236F5795EC6D755F6F0B36AE0FBA1B9548219ED544DF5CFDE3094B222063E416C8EA42B1DF7A1747627AE479E026205FBA28247904FCEBF44D8C06D276C163368ED2A289DE6751E3868A8BADBE0A0ECC38A85148CB0D4085B14D8760C4F928DC5802D02D55681CAA1BD468404D925B6EEF482F760C5B46FCB8F01F5114766F591E813D69FE0D51F58950B84FC2BACF7CC12B07703DD927D322F62CE7A8D903B3EF1785895F9D8643CAEFDD7449CA5B3EBD05713A202B403BA684BB7E3AC3CCE1DF7CC50819E97467827DBADA606B284D9EF2075666EB6D5E4E0315E8FCA999A12B9F1168913D34EC21FF7CFE51D161A4803371BF3F22D1983091B29B4B25D5D57D4B0045E35259B4281798D365D82F678D8A2CB8B59FA0578D183C6EEEF5426B831B89560E6F580BC2535BD184F301965EC3180156388E4729AAB4219F4782C94627FFCDEDEDD99DEB0B2CEBC9183A1A9181552BCDE74879C22A74710DBEF84CA97E1E7AB3F55C107A869662C14549B411D2E3FC3801AD44A2D4C372BAEE122462E87A1AE73C2DCF94771619F1BE13609998B9DCFA4BE1A0B5A587EFAEF65343DA0E6F0C9AC6A92D5C07EFC32806816894540DA7B75AEC207E415F350BE6D9F9D33FEF566CDD6C3F79A9071DCC18FD5F7E75CC978AB838499A7E6DC3B774261A38C01713C167893AEED2CD2A35DAEA944F497BD35722953C8CD1C82C1687AAF59C8130BFE0B2D4E7F4975DB8C0F73B17A067E4D51AEFA87A3760F91D4B468A68D7FEC98A17D0CAA58C2B30FE28F7D3DE71ACCE60024C19A1D64E97519BF5ADB6D90143FD404DF6CCD0204D05FD8AD074BF4DC841CD9D9B9C02B59E273E8BF2BA451648AB8AAEDB8A4A9E5EE5B4027804169205085F59526019DC7F1D375D40AAB078C007D674E27079A3E41EFDE7FC9CCBE11E5BCC8A3F541E20F1B2C32C4344B4580D995FB46FF8EE92E552D706EFA3E39144E48625619F0A37C39510437A1397664899216472F49D11626DA0A8B9571E330BD55DD7DA37D44ABD03328E6DBC06A7B79AC2F6A70243013E83321D0FBA0428173508D1BDCF9D2303E46D507501121844314D1B33A899A85FC8DCD0E4DADF4ECEE61C3F3AE97A2BAD70DF14B5461B091D3847A63A9236CF0E0F8026ED02C45333B314C421A2ED66E1699D844B9682145AB4FFE0A2C7F49BDBC3116513900A665B230A0A39C42078F7932AE0BDA22B58AA96E27B7F5F608497823FB58319EF4B2ACF7E3676ACE2CD1D7A1D6C9DA161320AD8B2BA1507C3B19F226E7E8496817B3DD84953B6AD645161F6585E5F8B866B12AD6B60C25FE0E653BC5E5FC4F925286668373E5D22521CDB20FD6D76CAA1C52BF1590C55D7FC0D7AD3199238D8DE9FE93857779B3C719648F9A27FA461F61200A0796036B43AF9ACA5242DBD7858AF7394F09D3B2D71EC7174DA5AF7361876416E222527B09F723F5BA70AF96123853E6EE151511202B6DE6C88847478D059C5EDF6261C2A2689890DB128603F0CE1B1929A968AFC747F52F62B5A1DDBC458AA366871197A94BC84FD22E26506B94BCAF8E229960B4A058B90927AC0D749BDD733E6D37D1BB83FF1799588A9031995A03396883FBE7788549C8F9D3F92BC4A50881FE6345FDA1C71F281BD70BD6B12ECA40828C34283C34AC72EBFC77A496E214878F29BC314121C2005E42D5277DCFB69F35C6D3C1F7BA065CFB2A18B32C00042A5F9B8E997202C8B35669BBD0ACB761939FEED5D4D323DF7FB9545BFE5321E38FAEB18C0DD2ED061BAAA890C992F3D0CC505F656488C2DBD4933169B9B57924AA5C334B58E7AB232B556C58DEDE837685D394DC404337B693D8520D41C2F277717E38190A20DD13F520AB64965EFD8A10040855798E97B9CF0BAB8B93FCFE1AE5B22582CED7858AE9159863EFC6A868C9F4D828B3FB5BF1A581F2282609D2796E771EAF96F48A2E42DE7EE66EA7A19E19886768444A10541909E296D6A7F5D1F025205DAF70979BF58F5197DC4B9F2E1FAF62175F14828259FCC16DEF9536AB559DFD7E61A4411C0EE1BC926CF41433BA6C008FEFD258D9DF032C476C7BF4A739810FDAC69847DDDFACFB46D3478F9AB34D92B7B3EDB6C7F009F8B71E99EEE78723B89CEF33F6521CE6F48B87EA2CF147EFB309C2BE1072A0392798789EEDC1F4E4A176DD68047ADC0D162C3FF71513E7FD5B2E38218705F0F00C7CE2CFCFF2B7E6D4A2DBE506E5F935099DF85E5695F0377F32D1DE93247C6D4AAAFF294B34374D527D492B5D9A30328010232913AF86739E9314874F4BAF10EAD6D5972B7C3855800EF2F10EFF5E56E4F9200B0CD7048D5B8BB69E90C3890CBEBA8E1A3C1AF9A8307308A5A10F305024FD422751B09910266C9A0FB0D81913337C2DC465B602B66572AA82C9FFBDBF34244C2A0C6D5BA00D9C4355221E0D5203AA28E5B494434EF45759815168CCB81016735F0B94DC6D8FDFA434900DFB80A8C2AADEF9AA73D47FD68E8B90B01CF2C2FAC9FF5ECE3D9CA6C70CE3771FCEFBB0A337F09790181F2122E8C5FA5B4FBF3C3559007FF5690987485E10EBEF40F252C4D9857D6E0DB2547BF0406557FD917B58D4A71A1EA69417F5E328863775F2B8692B11B68157891F84E0445E16AB94CEF77276D48CEB70A1AC4AEF4C7098733470563F1A1039D49B2B9DFC18364ECBD665809BE39B11B9E12762195C11B738D1CB69F09BF48C6F703E76A1FCB0B11D99ED4E319007C1C66ABC7AC664C9BA3CA8D4C9A20CC53A0173B6C740A70630ECB972F8952B48BF199E132A7648A25E27C00D7B9220F961ABCFF6F3A77B68E503A1AFC043DED5AF9F19B3FC8177CFC28E31902BDA123D1EDE5C892738751145B4D94767A2181FE4DB7F24C86C13CAB82420CD08BB5BADE24D5278F80A4DD7807D8C50B8B1601DD384CA1F46895D55B69516EFFF67061837D33A27675AD7A50CB89064506841FEB35EB363192256784F21598B3D883646D22D6A95AC355C8397C97350011BBD81DCE7DCBF5FE5C3231597643E3FFEDC213AEEFBA6D11B525A7AD49896919EF497757457D19729F41B74ECFCCDFB8694C0000CCD5A91239A67984C73279CF9D82D220BCEFB796E9E0A5D6008F75E5D03EEBA99A6B935BE749C2EE00B84A01258AF84585989F80B1F10D99053CA685181EF33B879148E23ACAAF5C41644D3E964C0C429488112C2133BA871D9A57E330CC7FEEDC46EFBF7413C52651717253B48EE6D91D8F24888DDB3008FE90F38D66CE819BAF939768206B04CE53DF2E7895C8D391786762DEEA768A4FABD4B49CD2858E0E7BABEA35724056049DB8225EDDCDF51149AEBDB714ED8CAA43C3EFE989625F732267E8BA56C1B16EDE1F9763B1E33307E96C3D7642DC4F666077A634E15A1314582EA6DE272EB28EA6ABCA7B57E84CB7FE6CB11672E52B8EFC875C0BEBE2181D216E09F2F9487B0A9E6A2F1D0F9DACB5CC2E6C1E19009ECA080879D5A7864E472B34B686DB7340953B607947CCC5E97EC686B747A9D19A29C3CDE7FBE56B78CCE04FF027C97EC85208DC2AEF53BFCD4EDF3EE1067CE9AEDC8" - }, - { - "tcId": 61, - "deferred": false, - "seed": "779C11F3F4D148FC911E188946C09E67EAA04DF670B6E0B6A96B661FD84E8994", - "pk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F57EE66EF9F649D16EE8747A2D91CF0C6ECBCD7CE3B1559F864189045E2F251064D890F431855DBED63AC0C74EFF29C88D8CCBF3E8AA3ED7A3FD574D5A0AD7B7C59769B0F67BE603EBF37342C7540AED84809F4792FA42C865ADCC4FC51349E8A5FE54681B3EE84B7BA7D29C1A5D16364C30E966CD307B2AF7B2CCF6E5CD817BE45E2AFEC0E6AAD11433B59EF2A1E292DEFF179255F784EF841F6AA6B69B733C1D1C79A33953AE6119D7F63C1AEDB95D7E359493FFF919EC41B76C615192EF1161C4C8D936F7269ADC4512FF0191FCC6B9ED142D70BD7B411D1401CE1D2CBA37CCFCB465166512FB5292F434E2846D9164C2E903036284D0C27345D4E220908A7980318204162F00AD9B9F3E32A2F679CD83A561732F7601CCECD030462888E13FDE4A6E4890F277F6F949A13592DAA87C9A411C222AFB38DD901B87D2FCABF9E21AC6182ADAB425685AA9728350F608D890A0137047311C5E81932D5925FA21C0701D4ED3156AF0C88341434010DAA0C544EB8151322044DDB2AFB31613E817583B3E68D6F7F97C63D6566A2C6BF7A9C55CED36903E9CF8087A2D43D495340A880F9C009FDBB66EB831154FCB39C81DBA120E0F97D312696493B0A61A495A77052EB20CFD65309E96E802318FE469E37DDC6B321D7613F60BFC6B7F668C6E13D0AF585B870D27480835AF9D70AFC0F1915431987130DEA79D1AD60DD1D7180CD7B42634847CF782C2C8E9C9069559C5B5BC6734078BD6485444657965C68D2B453039E7F928BECEC1852079917EE1B1B268ABBF29218A9035DF83CE5002CB2B7E0A63CEBD08F488B40C9013C0F1291E12F20747F326472A60F6494E7E1D8369A4B43C3C1F66816395205F1566593AA8491F3202E79CD633688F81D3EB2D299A97FC8F8C392B0D9493C2CB4A49B1453F4390089B08A9B13E45035BD7A2ABC486F7FAC3B66EF963FBCBB21F514B1AF3D239F4D8ED7978BC89C73377495B3EB21B374887E29C915B8E24F93536B194B5145691F55962993D4A4849D8D3102E18DFE4C14882408813B623461F8501B29901CE4457EE2E5809DAC8F44BD8AFB435017E9A9135479263D3F3175DFD8852CBDFD4CD5B83A752787E212AABB691880BB3549C9D67B0748111BE8E87DED3B77CEBEC42480FDE9C8EE9063A06AB2A221B9D750511C74F7C634A40D0EC5A8173DEED4BCD836F77C6D2A7C813032D26CAA346955C5885D1E867878CBF8C08BD20DF9B0A5ACEA83EE438A7869ED52C16F3157D7C8C74FD3B6587F220A0B4E03BBC497E9AF5E9EFFB76AC7726991DA18E8189B3692EA97120161E7F6F7367B565985CDD992E6F378901272FD74C516A4E6A416FA872CDF76F18FEA2E07A614B364BDDA76514F2C6087A5A2F066909365591ABAB3999A2CE216F54FB84EE5410C6E4A35B946B8A4714D052E036BF69D8B17B63E30E1F9CEBBA5A169DAB785CA0E5A5F3CD22EF42C78803F87AF3A8B3F94E86302FCD170AE49F7CF56C2EC86873038717D2762D12F15CBFFD37889FDA773D5929D2E0D9EBD5BBFC48FC18CAA1FBA3710416790FF52AEA2266AB40D451B419504B125656EB5E3873A424F5CD46A0A11933DA8D71256FA9C6B05C7B8C8B16D869F07553AF33495ABD2B6C752AAC5CD3C9367CEEFB9C2CCDD81F6E5D68A23213DDD8D63E21E2DA9FD77C621A500451C6E5467275B2F68D9EDDC54E50A85D2CC0D4EAE55FA61C7D2C76E0641B230EC4437AD5BE19D6C9D23C6C9F854225894EF6F8DB7D4F0EDE60D239873B85153C938A4A6E9D187027C46B7E0AF04BC0E5FC91A92DFFEDF4C898883C7C2D3E6CCD467EFB826CC5094D0145B436380302566CE1FD2AFEBFA76696F25A4E579DB4D1C78DBDF6333077D687D74034672045CD9F192375F75D3B09C117BCA028FC45875A9F00078E9CDC8C54FD5DE2260DA41F500E31559AE42286E7364993EABB5AEC1D95AA03ECFE51269303E08DE7FBA7AD0D22247AE591CC7F02D234B68E290E5347BCF5BFE705CAAADD17C46F3AEF8F7300B52EA533C833CE5F878135EE57EAE7092022B9F5E07B245C24936CFD7D0AE6DE720F050FD8BE70DD460C4605FD9EF7A13BFC39A20345986B1B902F8C769A303E40D386398809C1FD139FA70503BE765DC9DCA0F9A55CAEAA9F414BEFD2E431F016EFDE2B358DDBDB9F194D9D9E306750C3416136110221C2931DD42BB93746362934A180A2DF308C7D2A6E0FD575942DAD441B862DBC9510B6916AA3DA181CB649BDBD335E43B35947E63503E13C85F33A6303C081E072CBC6B94CF8A99D6CE500ECA92B6118AE6B1787D44A6D15BEC81D0443FF56A48CB99BBAE77771CA27446BD0E2386E0750E2B506A6036DB1EC3ACCD62BEBF489ABFA41B48D160850DBA0762DC59C50CB12E987AD0CAB87D98D14796A93EC2AB551988257493C2B4DD2F9EE2EEF9C379883A81941DB034979671E0643AC03D3E787B90780C80CE271D8846BAA0C74C62B9A66B9967111A9194168BBE31169D9143CDCD2101CA8CE136BD80920ABAE16E0E9FFCBFBF50BB8F797827F17C8EC861D4426CEB4BA499E19AD2979D62E57FF43FEDC52240DDA68A7DBF10DD2A561A5CA1930128609353BC556E9208FEBFA49C5522843B2C4CB45BCCA91543BFEDFB1B9122304D86126074E0E5CA4410A291A62594D6C963D84A526BF6BA283EC7B2F2CC84FD678F77BF6425C4C05A63F8C5E254262ED597ED4188608CC9B94560E708976A4C55D4B6C7FCD9D6C81126C1FF08EB87A0CEEF192CCCE37F828894C125AB9BE842EC70CBDCC032F020DB1E7A4F174807DC874100C4CACBF898825AEB954D0F9A41351B652BD3BB25A15E4FAA2A5ACBBF82A037D6AA3D841016E2DA7C4ADD3DC90020F644297209D7EB4C97DB0860ED5878DB8A54AFDFDAAB380D93174C09A5E6D1503E8253D10A4C3D10E1F9D0A161DBF9C17C11CE861549499ED93D3BC7680708062F64520F285B7FA460008BC25465666E1DA2C4BA092DFE329BE01D13E490F13D6B6D0373168BBB49A18E4C1E72EA64B6BCB79DD36F4BDF825F990CC4D4DD78051224945FBEB810C6526FEC4D3CD1D9DF883187ABF1523852C3FB9F9196A4C0A4D94B77F1C49EBFA35576D4E5FE3612ECA937F69122651024BEF58A8646716D83E5C0213B76657D72305BF58A312CA327B9C5E630B6602013D045EDD86E9D029BB35B03D96F89F30A10B32563CCFA19D691C9A9850899D923D527ACF2F5F4FA9349A23CC4AF3E3AB52501DF3591C193B7899169E495ED5E0A60F9E59BDF3CDBB2278351DBE8B9C511C67E2CA5FCADBE5F20148B32AF131E5D9EE2827206327E80AE9A873D9C618470231274357085A74FA9BBF966BFAED80FD230BE766705232BB099EA35D7CB619D2F5558F1B8FFDCE7BEBE733003BF055CE1AD5F4C6CD84C45F537CCFFCE2DEF26AED060F0F2B23E291E2F700BFB52061BAEE5045A6E71114D73084315CA5B848F6D9B38E30C854D0E6848601E166336F937E3B6DFB568B488B4C4A0CAFCCB27C56ED305E045B24BCC32309221B1FFA9FC70EB5280DE841B642B128118B93E90281C4A2287C4894C56131452EE812AA3EFBDE1EF3643A8706FE7364190FB2597A852F9A10E", - "sk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F578BB2B26CD59B63A1775D194E504D4D1B294977AB824677238BBA02A1533E887B983852ABDB4444A3E036E00EF0F61EB834C9DBE6E824E4A96D0971E372230667D1AABF891050A9F30FB7AC5279E270A4BE0FA7EB6F2C357968524BCB3A4236B08196491C348D1A2709E1C04C0C2505E0960503A22C88004E80C685942429532048CAC424A32012589871A002861B27210BB42C09892110168E4B260A20362511462154880818204A08099042A064E4B84C1B864041340A22200E0CC34DA0C8511BA92D10294550A6858BB46921990404150520154A2137884CB8110A420203B1881BA69190B8819900655A822519A245A136201C36050C173104424C51144963844C24B30C1125000829688C302A48106CD1C86C0AB12D8C260C00B9482103611A818112474D1B33241440821C373184246EC48630C030321134895B468988A60523471012130AD20232133420CC9860DB3650E2C241D98284D8160103C18D0A9305224024D8322D19900C60428E83926419082600A34809086E540429222102C838009AC0500B1864DBB2700B36295B08620A246484060A203066D294411A490CDAB420A39000D226461C208513C88519C441CA486918B24412934C0CA08118972CD8388A1B421110C01149242D0817864C440222A70424264D89208151400A1113855C14910081652004311CC240C98264E4A42CD4488024A84C22126D61883042C648D94420118521A33286441688E2068A941008811025D0A07064A4858B26018A964D80B80CCA1250C1C280E0046ADB2452001448141064C498601A030581442D53822909B131524808C1C4405A9450DB266A01184551A08CD322521A46015B100E9142110C2485D0B68C82166C192149C0204A89408803413202A91089B621A43262449441242788C0384441C85141A62142B04562968914086D0B128E10086162A2640C433040208D1A150203B8200982694416889236711BA791DA086E14A08D02881101234E030262613084E1966018A3109C062188846DD024209A008684B68C5B224C90C80108008840142903B63019106001354A13886D10402A58A220A1C02C130122D8288A0396109832461CB808C9A00CD82640D188241882808AB470218251C8000E8B0485E2A22590A6694C384411914041246CD138904CA66C9892298034320C1284412850229541E2A829093111E2862011A0101998692414918A362ADA860D0B370A1A104AC310481C22295B48668C3021D390104AB82D0A2012003245913241DA4412CBA4301C062AC08691C1B410E408411090688BB6088B281120150ED09605DC120ED8062C64A881DAC0018030611BC88CC93070D3424524398ECB84301B252010865089C84C61A84DD2B26D08066E221425C1B2811C904019905101278523038813278651C26402094DE0B46CD334222413501B102844360E4CB8859148800B277049004AD1B4450A310A8A04311A487121860C90444888146C2492510232914B486D22091289C88D5C204CA4862D00932140A82C20162519088D10388458224EE4C869C8C29120A528D3247109234824B541E284609A208C8818621C122C1838601B310C21A224C2443109A7011B461223A26122B76021865022C50580122C0A16650138114A3472CB206502C924110132820046C90649E1B87149446583C60C20178EC9B845CB44014B802C0C31601049801A1460C0186684A42509162950A42C21214E03040ED340248B080D9B944804A68124094862300A1CC185123424C33804A30688E4964112A70901836411230DD2A800A33660DC082A1A21290B242D834268D9084E13B645CC88248128060CB72C10B9685C1821C200818BB009E096254BA05108C5814236600104041996311409124B148C1B85452200922128284CC04D5B2684E34030910421E0C46C622612C442065B9621E3202E033446DA246DA0B05181923121A70199342A8CB6411C2951A1B8094B162C01134CE4440998B260D298241A11511845621A26064C4840182511E4A06D09170C23806448084CD3224292140280A60541242890122603836548369240486514056893C8108BA6910A909001132082140A1A200DCAA201214772149668A1266003364C1B340213C32D988420A0A824A2C8451B014A5A1622D80204AB1CB8E3E604B577A19923EAF947A1C22E67A7819853ADDABD3BCB54881E30AFE6815B99D88335631B7BAB8CC301B3150BF509F4971976DB4011FDCAA8B597F01F430AEA64761C3CB0EB40A42DDC87700A9A09E0069B6D6521813AF0A753B3D7C213E270B518FCA4C264E1BCEB736723765A8E31055FABF358131BE0827E125766DE4710F315629D514678F425F6FA9FFD962AC6B11104A068B1B370C1A367C16733B7B44BCE22B58F10F103A9AB05401D7E34CC04ACF6A12563F273D03E9F994B4E692DFF11FA1CEC32B4798DB0EDC43BD389FA10BD580409AC1D1A7CFD1F377382C5AB8BE2D6BAFD61D9A0C8B726D30756E25960B78014E64CEA31C5D050F92EDB367B7D67C459BAB1178ED64F263184AEA6BD69B712C6C9C056250BCDD8EBEB3F87A51A6B68744D0FE4869CC1381BF3CAB5E772B21893F239C248D76C56D58EE3C10FC49B24234608BBF929A24B185F850EB9E2E83D31DD614B80A35300562B29EFFD92587CC5CD9C52DF658B16260491F99B2CE74D8F19930E00685FF4EFF28E86039827BDC6E22F92742CC6C4D38AB574C6AD4E46018AC99355C6027FA721EFAB7549FADCFEDB5FC7AE3D0A1B86E65A2863E72A414533CFAA47F2225BD2901D48FBEC15420D408DEA83CDA7748AD3669D60194774109A4094C206C0F259A9FC5CC399CA32DB346D0ECF3BD5572A66521564EBDC5406AF642C8F746659D2070D7D333135A915AC586A1E017B5015AB43BE34CB26E520E9E74D6CC8F1D4F28DE97A7E26AE1442DF637AB256A24648A48AA7A5C9376042AB53C3FE776DE659D86594A343C2FB7C5747AEFE7E1CB0257BED195252F1D99D3CD9C4C9908348B93F875CFC4FB28F865CA2AF8BC595E3F57FDFD1D3DD5055D148888EC7ECA58373D40D7531F621EDFD857776A370ACD540970B64BAF4F30E2CEA3CBCB058A525AED3B9177EEEE490F007A6DA0B977411FD4DE96A891EDDABFC7DDABBB32EEF587326DEA9DCEF5EF9B4878AD0B326C465CADC5D822F207B748879DEA3BE7E949721EDF58E301118BD1EF215C24729082B29537AD23A5FB8AF20AD8F44F7619D99D6FB97EBF6D859DF8A48F76190A71582E0F927BCF4126BA09A56D9869963704939174392D88498027813DBA518E3A2A9E0177EE919C65A0233D7D5EE910B883832253846E7324C1FA3EBD375F005F286FE024EEBE9FD6ED6D30AF0A12D12936839CB9C06A39A2C92B1E7368F042F136EEA4BC8DBE85C9174269F44CDCDD890775BC9060ADA08149B7BF7B908CCBB8C463D6B6010792662F9518B65C666C9BC10BCD7E2157BD7D1F79358F4AA3F680A1E5BF243463FEF1D8DCA0D2A2414BA77B83A0AF696C9614999A9CCEB11A816701248ACFB268816388BD9525F2EFB96B0FB39547CF773A2CEB8FFE43F3F5BC26C6AF86A43314C4BADFE000CCA62EFD2FF28EADDB6C351F81C9AE719B4798091C3DAD70E8CEFB6074694381399E39817FF8D6586BFBDCEC4FD0EE57D4CDD1886344CED1877CE042C29C8BC318F28C11A9F785567695B3511A43A3500A4BFB596C4ECF42EF5052E52731271BCBFC2BADA445F77E932BB438377075AFC2462B58DDD9AE5EECC3F1C5D40B3DA1E212AD06643D7F4348407ACEF56441A66E03AC1F2828AF1A33A632D313ABDD0A7023A692579DBD9F308F604756C902DC340969EB395ECDDCEBD2455422CB099BDADA927A32F47FB1C3CD15B05434EB069A944BDA9FCC7076CCA52D91C2B54B9C5B453D18B9319746CF263DF160A9C19DF0E9B4FFC9DA665351E13EEB1CC3F8E9AA1F7BEA9B660A4A2B3E12424EBC68DBBB9D258599AAA00CC307A798DDED3437D6E02534319B2A40BFF442DA21E3A348423C90AAAF605EA626582412D088129FEAB971A287BE84FCF238410194D980B6F1FCAF520775FC39A38DCF4AE42CBC22BAB92D071D5F95DD3FDC641A508497D2C85400420368FDE2AC466B949F4F83BF7C3F2F6B6928F0DAD2C646B14E1EFBFAC24FB12A566981DA4B61FB1A20C52CBF7DB65156A898E096256AD638E7BA4D5D8810556EBAD83212A0CCC2B6499F769E5725FE1A9843002BCB84136218DA86EEA319992C806AF2D434C9192D31DEBD9E3FB8BA5F0823BD7E6C162A76DF7DC9927F651BA5AE9A6A3171464949C286EC060662FC3E8243FE5E3FD679C9DA1F0C6D7DA8FB8284392C0D947DD9541A36655385DEB72B836482291AE46A0D2E0C4F072549602186FE67EFA0F8FDBC25ECA5FCE9ED067AF4A56C60B758D4252ECDF09A2A125DB91CB8B66E7F7C124BABAAD2718732B36BB3D58AAFD1A890B2834B864D864F1073903052EA8BA2B9F3BD43DA456831919AB474EEFD0198FEF6D156B81E780DA803E9DAE22DE8BDCEF44810CDC4B071922B3D6A994A4925D7B0883F8A3CFE36AADA3A42496BFC9B9B2FDFDA2CF081A4890FA1D2B694518A675FDB38197E0409798E0F4A1F677C51C8E443E8559B366FE6C52F2254047539157C3638B691C58AC057121DDEA73F4361FAC7C62DE745DF555F4F46C15DAC3F77B8BEF4DD51A6F845667BEFF02D8E80B8C1CC97BDCD870A640C81C02618B9D167C1C48F1D235B8B4CC6F851CDC4C786E2031BAB1189C498A3410BED4C18405ACD863B92E2462FA3B6D56CA4CE4CCBA3275CAED86DF80396D52A6784A14297AAE4A5A6BCF4F55B12D64E1129A3297ACAEDE6B8991045543255F7B71917A798E81822AFAF294DE2D7F31CA0DBC3664194B3EFE7AFE2F97F5CF63D2DC7D5974D6C7C3634947054C36423D6C720EB7D2BCDFB9B020694D133F8E1E8C5C7177BD235CCF8D9CCBD9D172B76CEE1682B548A438B3E3F82DB42018D5152E0C3064275ADF5E4B14949B8DA9762B87A8BE6F1542C6BD5300C940268DF6BAE1B5B0C780B87DF291EBB582CD76AF544C71E15B299745DE59AE228FFC4C4F00B0C56BD74DA6404BE10639369C778A2FCD5E908E9E6866DD7FCDC37DA28CDEE66777BA6CDAB1AD38DF12C5A0044308837106C3E96BFA336A2EA633C88D270BB1C0610BA11A742AEF1C8B4649A5A4EF83EF7341A4BE76240B099AEBECF601C021EFA19C34CDF55159E33D0252FBF657C680BB810B51AB191B83E6446A5CB4EDB960C931112A539A7D5F6E64ACB438D98C7C1EA1914A82272F617442B80E9B37B0769BF6D7603EB5864D01B8DB6A8CED4B5DFA0EEF5F76E994662D4654DE3434CDE020B9B2CDE38B289C36263452B8C87197EDA09E2D5CC7567EF7D89253153631F384A300944261300317226F4F1E3120F3D721AA8C1E7C023316EEF66BD3B565FF54253D098896DF69B224BB1F276EF5A518A83CB6AA341C23022B5EFEFA05F5378620D0F088DDAFB9686868904D83A219FB12E6DDD1F65283A653FB9F5EEF7BF9A7AC7E39671D129E70363962752CDEAA6D05370DB9C622C4F6E7B22F44E25251F2A739C1644F2A9B1AF280BF235C2B6894F0485893ECD449C41A1788096574F773671D72FA5DD3DAB0E61EFAD5F536642B892D506A8AAEFFACE924D5008E985B3A84A781110EECEC8EB950B1E6BC8FD77F7A41E244E9BF48DFFC86178BB3B3FF62056E3E8AFD168D2907AE21944D35DD6DEA1F6CADED78C3FB4326DA30D51891E1D8C6C8F1047FCB21BBD141AB5A010D1ED5D3F0BA21A7DD39B4098C2FDA2E00A1C2B5F2B04962458DB855A310382DD4FEC536F1651D1C8752C138108368914F78398C3D185A49CD741A495815DAD06F29CD650B22FBADA0687C47414E72DF4EF0958E56FEE546D02E9B86200035253C02E22E2FE581B22D9273DECB45A33297C77819801FE7F3CA86C00CBCB6D75E1D7C97A527B56F345E0B919DD4C60E3F27DE490DF7FEE4F1C7A5CDDFEBBE24C8FC94EC9DF0644C3CABD184C112192D8165405AF437459CCA354DEF38A4E3B7D32C1246FA2B3DDF544A38F7FEBB3E28F325F00E2214C3494A26560C2F3C6D259A55EDA0D3ED8DCAFAB71CC001C676EAE836637BFE635FF4E5089F3171BEA34C21714CC1F52E18AAFD5F1E5C624E4B395826FD27AA950485CC6A4CE05CAFD975B2BF28D19FFF3930C5BE6A3BFE6166F37B63FBDAC712CE89B8182AC33DACE19E1B3F5C406B2A16411405AA4065014F49452904B54FCF4DC1F9FDE55F6932D8C8C69745F7A93592372E85266E6CCA7D2C3D01F6171451D8F39174235BA81C999793B34580C7FBB7F65ADF8F925F1B6FD6B00BF67602246FDE6F56E00FA177FFBA87EC072ED48569DC2E891EEB9D83C4882D53168FB0EB46DE6B062F9A483E4D0D883CB396D1BB2A95CE845FD33BC0ADD48F5231D73F8217205D14ED7F56F91ABE9E955A0664B957E1522A98E8ABFFB21BF293BFC7BC798025D8B380B3196E394D952ABD9FBECEDF1B24D21CFD135F7EC4F94545E69A574F62CC39F722ABFC08B4794B8B58D4653C58F76700B8DC741A3C2B37775EF52916C1AB6081309E2786269A96D1DB34F6FB31F71E40451756005A494E9658E3324AB05B4D21E6C38DE8FE99B38F46D7F5B7D9F2696BB433053C0F0A3DDB2F8240A35D708C3AA813F9CF92C090BA34A4C3BC16F039479DDA7726989CEE74B0E318B2BE904874E99A186FC2C7D74B9F5B2813941EFFADE242B1AFDA573FA2BFAA4484BB8B76858576BBEE52E49283A21EDEB92CED51071BE899FA1FA9F8ECE8A9EC2074832EE0900C2C431C101986403188AE9578DB5B26426CF2D23BF451507B" - }, - { - "tcId": 62, - "deferred": false, - "seed": "A94A73CDD32CF203AC75E89A6BE1AA55AEE0F2E45C8923F6D4954C611ACEC3F5", - "pk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225DF7C1680CEF51A4E68B41F0ADA6AA79E229C0D8EFAD838209E2A39B824A6C19C180785B8B793952431A4BCC45C36B37A9A7AF8BB92D0994933A7F5D6E733EB1DA94DF2E33A6B03D8DB42DC83EC95603DD9BCEC090B170C410D06F8A7AF8EABA00CCCA7A042CAA7F7085380A402F72CB26657CB9C3CAF878699CE620719A5B0A0CCF78255E4BEB0A30BB82872F0AFFB5625E165FC9D7A88B67759CCB8A72B6546DDD1DADFFE168AD985773ACBACA465180A0EE002B49C507571990941F9F57E366F0B8D2C6E72A40F5C100A23D8D6D887216A5620AADA2B82A1FA996862C4FB7383AEC9D8BB8BE0905232E9BE89291341B7ACA12B9364DA8B8D5FB50DC937750BDB1581F8B83C3E19278A00620465FF893346B20EB0EC8F1CB335E65ED0E152B08F8AFB1790775E069B251B1E88C63A8979722CD50AA16B883AF0BBD8B361334D263BB0C5D9582273D79B3CCA93FF2022FE1CDACA9C6AAA2C6355730FBFD657B0E82DB02E50A5EB9D830FBB9F706D2B2061B4733025C7C94B1ED50655848F0F58EFB9DD023F8C871B26F2C3C098FED8D60BEC5995B87DAF867D5549F27D2C62EA13B894176B11FEE4A0BD96B5B18262496D7F0055F9F3551C5A91FD728B08ED5757B00504BB0C10D3C776835983B8F406F066863900D8001F6D37BA6626F95AA8874712ED06E22D2DC0354B395353789AD700F9ACE628DD2E53A7E98FF3ED8DB4B625AB45AE9AB07E827A524D8B458BDA8CD3004A5D56391050B2C8E22B2993CE57592A7FA9E93F891C3DC1EC6DA769548F03175B7ECF6E3D50EA48920645D9C766138643BB8C73B2399610727FBE42F02D43B397FA07CEA23C5CA1D8D81E6FBB64E5E69A6433F37C493599DC0C96B6AB82623710A5C90BEFB870888C2197286A5014A0B38343517769412930973DFED9A5975ECB36E3642392B423124CABD33425CAF4B2F4E8BA75956CD30B4DB8CF2F378B946DDF455471E55A86E1D5643298F963CC6E2352292D281405BFD188217F4D0974393921605D94D27BDBE78FF93CE3DC0C21B212E741AA540D3639E36DA03D2C3711F2735C439D0FC5B1EB3FC920387A043EAFF4FE1C632F27D6D0E62C1987CAA6DAF11F2197F31F67B8F0EF625C700562D711586AB764E7C600EA9F8C06397683493C0FBEAAC512E41B478A30532D8D16ED092AA928608449548980FBC9AA50AE734C0E2759D9183E762DDFDD249EE6E8B4E392836FD49BDD46908667E62B367E221FAFCB297692DED3545C3AD530B2F0D6345C1D4AA87460F9CF38E05EC751364B7AA21FEF507198234C2FA189D22E5F9397628EC7FB67714912657964E6249D3FDFC24F7E0D63E2D45B1663D7C23E5B08395540CA9CC0261126B03BEE0EAE396424D774D978048CEDCEED475DF2A5DA43586AD7F0935EFC144B23C429C7F01EDF72BF4E8D1E45D19BE12B999C7F980691E23D70A5A4A0F517B8B324B125CD0071D815129A4929738882B8B5813433FEF88C58F0AEFA1AB98C1C9A29E2FD2596C9F8D2C9C7C2EA83F0CEB1DB39F914E47CA6E6D56CBD5745CF478B9B66BA527D2E36AC5DA0DF93B19818917827CF4E92E300B4ADDE59A5601BEE7CA34A189D54898576D9235DB2D5C73A083C735E87C202F2F5B7BAE6B82AF1D41561398EE17F11BBB4DA28C944011573A4E6E43C16E9550F8EA2BA407C79AF3B0E4F115625B3D822A1730361E9323F8FBE76313BA4941BE9E937D9A193E5A3BC5F1A240C60651E30FA7E0A45E557D95CC4912A6707B557F5351B6366E0C114D3FFF7385C3E90015B55D3112D7525ABBF3D773B04ED3C48995439E3A15CEB7CE577AFFFD5857CEB6EED8FFA2AE9D957F902065647E85C9AD65F54D7D88C4D3BD6107FBA1FF01139F5990625582F92CAFDA90C258990E1F40B123B798DEE01CB5BDD8E74DB0C724C93E4E65E41972E13D0D358EEB86FFCE72FCC3FC93B699F9190E222FFDE951879E3AFF4EC95552054813E8328C28C40778A3BDE116EB931747E0FB0906E2C73F9C96FD963AD300C79FBB542CB31CD8B66C6E63BA290B075CBB6E1E4EBC5AD67CB74BB07F6BABE718F00F010E8BED75F9B98E75ACF081F5DE101D233B002D37A9730FB2FF808C24D7F25A97E4B2FC73E7874DDB2EA3B573A7F7561D7DDBF1F3184457D79E8F94655A90FCE94F661C4DB9D1F14B9FA336F4DF3129E3C76AA6BE419BBF15414870CDFB257A4E2D8233CF8921DD1F69BF6F0A40803CC6E679F0C9BDC4957AE758C8669AB33F2D80E661CB66E36A9AA294AE55A450078A2A5B0EB44C8E03420F241D377F32DD22A65C86191DA857972F68D70C46394500D23AE922D13B2F7B4BFEB5EE21FE28503848422E43F1610261F42FDEEED6F7D67D80754881D755FA81E83D503703259F6CDEA6E1DC5B2FD951702ABADB305A51CC37227038F71F853A53C180BBE28CCBFD5919161826C3DFA0556685B36D7BF451E6AEF92A15F1176C040EC22B469E11AE7E3A1F371C71F49B33A583B9B9082DED6B6CE1B9983B557A458CB9E5B81A7682CC19921E7F297DE94FB9A6CDCFA40A134A1B3E282C3FE9E78982A9006FF4D49964352519B782FDC0DCD4116B8EE67E024021B8C556E2727F25C74E37B92E9540D81F6243DE033D8DB8DFEB0561A7BE63485D05661EFBD17C5C222077FEA20801271164B2DA8943593A4B65D79145DA0A9FA18229564D9F331CACC42295B09FD366F378F48A248B90FD3AC940024705252416C6498527546280CBD6B29BF073E2F458F6A1A57953DCF815C8B2EFC9A34700C9D82BE140176008950E22D814A0576C7A23F4D1EC0CB7E32CDCED7DBEF19C167C7CFBAEBE341B3889A7E90BE6B39708D7EA31E7916829D90C6EE0522EA36D7F892C14E089062C9EA8AFC3361B965FCFC27DC8525BB96B7D51428FD8F493A0A0D8E2B30E6DDCBCCAC1E927E6CF939C1B913CAECD4048D9D21B067A100F0BBD5C0BEE8E08A5462AD325041DA1DB8A4B7D7B6943227D970D8EFEB9ED5DBCFF08F93E16AC81CB544ABE1E97D7DD3E61F4F2761BE9ECDA5E6FC10DD0A9C89E9CBBBD88B25A51BAE63ACE11BEAA575D4E1BE03E084581E880E082A62FC7D48A3569FC17DE7AC1271C3E624A00B3FE59A06803B2869EAF89076463063B56384E3676C8D998B8A337FEAB096479B3AB8455248599EBB7D7B4A48AAA941F42957ACAEC111F987A68EDFDC3018857BFDDF6259ACF4582227ED9385B4BF57A15CFD9FA6F2FECE6C2755353EF4380B59D6B04597EEF66C42B829429C00A4D9283EE0AEFDDFC53DBE21383C42008CDDA8615B0D70C35FF8EE905925E201E1F7A1C4ADC176A49FDD119832634DB677C9C389722EA64C290E6B6D34529E1CFAEBFF34BC7660C9B94A35A30BF7CDC52F05CAA78B6B7F2854BFB0988F5DF23BD9CC6EF86602A371525326631C54CF73A9FB78D750B223C8AEEE95B072B021D761082E7C14418163C80EFFE990F18A63C3FB6ED7116971A488BE3E3A2BD9B81A6F48F7D0E13E218B4FDD8B66FBDFCAF2AF84ABAAAF6764506243F83C3E0963A170BE980987F8CD15157453D856D3C200EC2E520959AD657BBEF60A1EBDFE7709269CC44546F39664C98299983BA3190DE946FED23EA32A5EC", - "sk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225D480D800452AD18AA0D1D9CFECD4042C822A6D44C7DBF8A48E407403131619B7C3D984C3FD15A93E61F09726EC8D3354B81BBEA86FF3F4487CCB772392210C6D501D69726A9EEE9D235BCCD637B449DB415B0CD254B61D9EC523C8C90D1CBFD6CD0382CC44246C3A40599A66512B82084A06D1CC01020206DC910640A400C00408D12A64C90C2450A964D0345709036001C36000AA34D2340291A17458A3049A0B000CC0045D4366D2399408CB0315BC84848B885C0A64043C245E0140C5832819B824C63405053462699A20C033648600086D2004E509810A1104EDB462A242749C908445C44011B9244E4383192C2281BA348A4C48150160A819264639491D3C285121212030226E314282122091A197199262911C64980027198480112968C2233010C19841390044A22911A8988183184D006521C348E1B36044316490285458C02121A446062020A1A97444B4212DBA20018040D01B18DCC1681A0142C0B4192224964190012A1B46009B70CC3120083B220A126521BB9114846864B80218B06655990109B02018B121008879188300A6122415A00085848515034640A99484C446CD828894C082DD4980D0B10514082010B2400A49681C9902481308C1B37528A3892A0048851B85112322CCA162A0B386121456D0BA8458936459000241C87299C804C833040914085638440E1128C1C07505C20649336240833710C1866C9082808268D13B3519A026DD29668C9B864E2A24C8C364D8B00850C1224C0324D1C25302445044C14824C463010100819226C530208000852C9840514404E5428811805011B865004197050A44093442E1AA48902B90901277053044202C2711A146A50A42553202489284100080990B650640490A2B081E0B60193822024B76D01944D80A85162382D000328C04671DC1064501831D9160D21066A19474622B46121B670DB806D9424600CB73044B0711946690BC324DC220548484483308E8BA2816192085A008C582632DB1482C02611122085DC400108108CE1921052325188445248A68C19444411A22D24A96D00B06009A98022B60C1C2405E4480E5AC44458200D832628D304211322608AB42C609800180446E1922920344621B36522884D9B046AD9106D920049CBC42DC4B8818A9650C4200619284142204424104A98164508B66501B6619C1629CBC82511B08C9A9068640446110291444091DAC06004B92082C62D48327162A641A3444120422D04420C8A9209E0A00C8A041152820823051118372C1C0609A23082228870A3C24C5C1651CC242D644246A198510A4586DBA008119485D1464851344C50B21123A34C4C122913480D09176103480E1B334952062880200049C281C1248624382A04414CA1B02400C3418208490230114A364290220852C285C430911C388A99C289214340A30029819425DCB28092A03091B821DB244C22A20811C449C1186C0B1090DB162508C64000C20CA0B48921B271200488E330318804064132090216899A08112349256290248C928DC1B630A29211213641643804143491088804E4A42D92C460CC126D409030820690838424C2406D90A00451B2010BB584DA02280C22045CC889D4309203B6910AB148DB340883280119C6104A824CCBA00C12280A89982C1229491427061927020A9661C3B82154462190180550866D63148620B80908070D52364A6428290A11010A9304230585A3088493386418344D1A464ED2006140028A21B79088320D1B2581224246E3C68DE00092034928A3362C603289C14821C406881388895BA24944024110954560404613128A81404AC2266D59425192A60C21144AA0364AC328660B838D5C98251B464A5B2242144224A2200858040211B32C981488A3404C41964C0014044C286623902441068C21156AA1B07019B38C5A242D98962DD90004D4462E1C1431C11021122609411602D30446212164038801CB88609BA849A0042299C26898B6491110721AA84514470580184E111725D490701C376A1B04510445840B1106248721222549C4C26CDBA465C048801213210A04860C396A00B885180932501604C008054C364821C4119A16640B10001A858C491205CCC64C4CB2091C037103A94DA0A66CD23086029128448644CC28209A28418B282601396967AC06D55A323D137EC2E28C52F87921D3A6471C639B5056B58AD10D8961F464CB2BDF687FFA2E57C9A5323D2AF8990FDEA1DBABC7D0AA56F1BD9904D707A86A9A92C93B081C7EF23EC6EE3723EA6A53D183B3DC49B36B965DB4D62D88D88AD2A3F7E5509D23B0389E86A4E1F4B970D0E04C0E997EBB3B708967FECD1AE6E0EF71555E4EF519613B00AB50F08F90D36FB3766FC166C948415EDE215C2E8E8D596B0F5FE6018ED5EFB2D9DB07A564B30A556859B5839F0EA495AC41D497FB4F25C0ED4D8B426A89E137E7B9256E5A87708070786A89885B9E029F2BCD382E2E319CFCFB08A78F2D3C6DF07BB586F5F2F925DB887C7C2529AB8EE9969D436557BB1489C41FB119CA34A15E77F89259EB7C7D3C0DC8764DF2FED95F40749A7EF900A33B214FD5A92F9A175AA263BD002D7144BE306E4548B05076CD73CF0C22713735A2FE9CDFE7FF48115CFB6C64D9CCDA0981EAEEDDDE51372C7D49D4E5FEF4C41749228591182FDD67F9F0A416B0E9CA2B7F44455330360F8881FBA353DCF3412E832FD094025314149144B1CA88EEE470CF3B66570B0D9785470521B707C8A61577717ADC490B5FB13537AD02588E56041CFA17E086EAB73BC7C36D8EF488FAF357C118AC99E0AAA862F33773F140643D7B1E92B8BC0900E8C1E28E03E810E8F3CDF47977A5C147C434EF371FE83A11556D7D3C24CE5D90370821176073F3EB25EA4205E96E698EEA65ABB0110CAE96DA29560C62E8CFE713AA5D7B7A98586246DCBAD86A420D1C28B97AE1E9C4D1E8C6439885AD906DE2474BDA0B629D01E12C4045D343521F983909871F90073B7E2146A3A86945BB83F6693BD0A38BA209BE3FB4B193CE4A5BBEDB38A5F3C7A21F259C594952F25BEEB1A992348A94A07B579A32D167CC4C4F788A74AE9214E6910FDDC79892C97FA6A00FEA091A463F13E45707C19DAC54C67EFDFF9DE2687DEBD02462308E50F1F3AF266FF82D279F8975DF99FADA5AEA5514243B942BFE05A7AAB1579B469CA92BD222EAA2B547B7099A0218F5F43FBB0D54B11D7E8B5373306B2FC6469F694F3EECA3912BAC0026A40F2A3D9A76D76A9F3B06380C687EBD7980F901D2F5CDAD534C0D2745231155D6D51E8AB7D822EB0AF875716A0C63DA747BAD741DF19474372D7239EE17AC7A5AE3C92B5EA98DE85508065DA483D4D4FDB90329124A2BD27D77F1FCA072A83C85D31C75ACA462F39A4B82B13D49963B518C843CE2B2EEF0AF96ED23898040C9FFB7273FE3A02C5858163700E1423BF5DFCF27F0FAE92081D2E6A642F49102E60FD45C5A2BE668868820DF66F6D3E5DA79B40EEE9F1F7959AE72364EF382901D8AFA5BEC757ED80522DE6CF70E0EA970C54D044F1B16495CDF6B38D70751ACE52F9976D6EA2E47AD672310B7B71A75C1C78546FDE138F4533D8DB9A7DBE2E08F7E745A52B3913F12359DE7F7E37A6172C97F612EC3C0FFA2BA55DF61EC06243BC499AC5C7F7CA63727705C43D356C79B67497646AA7C8672AD3CB8B241A16DE6FE53C6E723475DB2A5230EEC5C233DAE829811293D1820A0B827CCE1960DC978F72B2DE4B58802DD15F396555EE4CEDD9932CFDCEA3F113E86BAC39945E996830651595017B5069DB589013DAF4916498C98042D0B807B490BEF1783C4A5A4AB135EA2D2C0DADD7B6121785201004A38D94C73B3EBED2FB3F0A26BCFB33951F89C968521D58A307DC13CE40D1188ABB84C93942580BBD8D821748915257DE1D7381321E6BE8567F0AD583DB4FF40095D45F2F09C6FB0574C198E8DC6695AC75FC1D96102D43BCB32B8D95937B7A0EFFB573A00C26B68FC52A5958E0A00D23CBAC22352929BC5488A29D974743FBCE01C2EF7169B58D23C5ADBB8CCD424686BC1D42B653CE8F149C48455F97245FA41CC97FCB39D812FD61CEBAC99B8087CA86A99008B644F262517F42712D9DAB06B0EE8C069397A80AD678E72B7766C29A3407D2406F22DAC4CDD02F83ED60EA03AA6FF891F6F06514E2D321CA475EE4025FF331F6B12F09BEEF84AA9B1E5D822CD9501310B85588798296B14BBDBE2DD65140343D20C6F6B385922EC47EBD8293B41E0B22F08201B81AC4E05C7D1F09EB994B1EAFF70F731FE66A5A49BFC6F69A9B054BD7CB410B893894192EFE02E9D0CBCD75B751D95139B6754FB856AEFE7C65305D8277E986C89C90EEF6845416E8A6BB8DD5D2CAE4EB6DFE3FCA1A0143E0AA10E247DA7233905983094C4FA6E924452FF3D8C1C074EFA187597160C864F7366169A892CBA66215707AB59917C9B2395A052CFE64EF65BB10DF9E44B4E5994C46CB8453420E232FE7CBF1CC5CDEEBB6B7C56803AC8A97AE5B7C1EF5007A09ABCED41387EA53102C85B3421D5BBAD46FE31C8F8942877BDF3430A7B9A41FAD7ADA3B2071D4D0FF83E8FAC35C26A20ED01486C8F4EA46673FB9456EF5281689BBDEEEA2411AA12380033045831417F6DAE4DD21329D73F7330B13DC60A9B970E60D7673FC65C93664B0A625F93A8350DFFEED09C8E601335363000CF31E7F41953B696141B7EFC19C0BFE1BF0873CF394984CDA52535A1E544D5D814C0399199CBDC6F8033DE07A413100F3A76B0C45D9C972C0D554AC7C404BBDF94A85A40A3AFD60DC6DE689A3B23BFF358615E940C8D243077291968035A19C576F6B3EE2A6F615A97C2B54693A586594D218DB114D7CF90665283F67B01E12D61E516781C1930BB669B53CA20D248E84F23096684FBD9733B7C0CC48A9BFFA93B4393FF5D9D2B4CC7DAEE10D8D4101D73506A6538099537A58E0C08D94AE83749271B54D27C72C889FBE32126D6EF46BFE19DF20026E1B9757000059578D33ED7B5DEF0B95D193405843C91D417FC377DEED6A60BDFA2FC20CAC04B0FB1E3CA4794D36E56FE48B363CDF2D65C891BCF8087D511936E9255FB51E0CA64D4D034CDEFF97FE7C0D4E2DD4456435BE3B50834BB3D15EA0216CD4DF2C6032FB9A83E077C5F1C912B3F5363CE67DFB373D1821F4958B89C9B268EA05AFB3AC7E9E150C5B7F0CA030130A5F03C7BBB7FE10B03721F8688B4735255A7D72B8C8A90C25F2DB9158A18A01E13AC040458DC671EBC19EE75C6D5903BA569A0DF90B986799C546947E9B94648424B742389550CA2B2F803DFCBEEB664E3AA5523BE7E14147515CC1BBBC24610A7284A6128EAC0CBF1F4472A46E4ADD7D9F4A7CF7EEC0C03578AE620DBD121F774AD46F4B5DF2155CB4BDACB1BE64A674AA7F066308468800788E4D5F4E84AE1FE5784D92883D1EAE3E66E5297554DE94B3FCB6EA3C273FDFFF08D770048BBE5D4AE753468CE61F7ACF85450C7FA93C2F828F1A888BAAEA301F5A8D3BC84D5CB3122812304226FF83F1F358DE1F73F22C48B76EEBD4B01EC34B51FC09277A70AF10CB58BA9243A3EDB5946CFCAD46E2926C717EB13AED5B90DDFE0C3DE6BEBE9511E925FED1D38CAD55826E30CED1CFBB2A652043EAB1653FC1CDF32CF5FFA2F8A4CA591B3C70517530B08ED7D663EA064AD65EFDC9947291958D5C778C29E80CD3EDEC15EBAC272993014B00A20363720F0B4241EBEEE394C3F35FF5E9C7FEA8B004DC9E53E2207B526644873D3D88CB91FECECDE2CF5809F78AB54583FD62ADFFD83FC406E40F6047D8DE85AAC6743FE2F7461D52B88FC647FB1D82150256BBB32E9DE4FC271D98C1EB5E1E3E660234FF2C182C4FD2AA64325AB09DDD1035B055B5886BB953EAECBB75826543A911E1D2D9B1674F4286ED25A5BA05D27BD50DE219A0C6E029E4DBF691471571AD689284CF9DC1E2EA170326A1B949D73392FDE52D3D7D3CC56518F652CC93F75FA4CB4DFCD52CCAF7A64505D1D8D0E83593A2AB7F083CB09AD48257F21885A9FCD2719C95701583839D6765E6CEF7428F9A0362A6D77191F6921E1E09E69F7CB8AD9E277A31FAF37B21407DDEC4B0F67872D15353AB9466B1A927EA0DC814D4A3E0649BB0813CB817EB80F2D6EB85E49CC14F9AA8A37513DA248CDA02A0A77F340DE1B939798CDC6D7C7069EEE4E2A8A8120EB1EE55AD3823D3AEB93FE55BA2126DDABDDFCA8B6A6DFF07562080166D257BEFEDF864A917DC3A875BA2B673C0E4BB33122E28A03955337082CA6350165FC16F23B404C57B971737361D6D91AE847050A18D4E70E452C9ADBD816426101A6D3DFB1EB8CF2105869B42F5718D1B8F27CDF7B42007D4942BDBAB9EBF1DFF9D92456F610F0F18A43823B2481EA8313DAC3703F342C3CC17B68AE8719B8DFD80FC544522D973EDD78D5E2EB4589665E8863103EBC554446F5054F634B01DB6C735103BF85706F45A41809C97D0C1EC449D000509B0B6C9ACE95F91E2D1FF102FC54DEEEA476726C06E198C4EB2E5E8A342C75A53C4FE727BDD039352B6E3F0139FCFCAF4F3F44B3B4751A76993F1F3C9DCCF74934FCDCDED4CD7305652ED1DB6DD60277D17EDD982B73161B144B224B6406ADE4975CC0539BAF45B3394538F0E4C368B9598E0530B4D8F5120215F64BBF2BEB922BF9F7A1422B8D5B642E6A217BD65FD68C444375BC4DD5E7471E8540C79ED21BD42E9885FB54C2FB49DB1683548B60EF7EA8D2DEE9A91506E49C51FC31121A33AA06699BDEE221634819AE6F8155B8A1F1D93E1D1F1064E5C158973C657886A115B83D2B3CD348C2813F667859046E322065FB634AA1C8185130354A137A" - }, - { - "tcId": 63, - "deferred": false, - "seed": "86CB0744A2F973D562DB3B2C47E234F02C0ED60D2EC27326407492F6A6913BAB", - "pk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D979DE7A021924CB86D8AB86B1D64859F825CBBC99BF298B6B87E02872C489AF9B032DBE33210DF467ED148AB524A89C77A8AFA461FC57F3BD206D6BA67DD825022D12CBA8CAA79400ECC22D8D347C8CF58F0630C3C84DD051999E51944E040AD9262A60436941C3A0DDE60EFE0AABBE4AD77F8BA18366772755FC672B4E4B022E4B7E64CD3F7426890FA203FF42B439F3DB0CC90EB3146FEA0C3B5F1D4F1CECEFDF87871B04F40FCA90F3FA1C9133000C254FDE2343FB85623B75B100CD435C5BFF5E7E8490E00BE7717898DBA816BD0F3E8A7A439AD2948C9E5C829D3B1F1AEB4763FA27C90C9ED7E1EF1722CE12B1783AA64DA0384B1EDC211DB94BFB75DC689E71FCAF7878BFE16D6D867771054C080C70BA5A7EB6FE2BF34BBCB1BC26C64240A9976355336BFE99FBBB471C8DDFE0D204EB81F7B2956C8073DFB5F8A5C41DA87086F071D7C0E8490EA0AD194127B2A1E28C7BD8661DC0514BEA6861DD3B3C24CBB625128D2DCAA737EF012B4088D8BDD7D98E3F548E4445D7E753C9D3AAB45A217F0832C0EA598DC22EE9A0503BE209D020E3877724B3277EA9906957DC07E1E834DB4A4B6A335D48863D411560C5D2B54C81347B96780FB0EFE9FA6A1D5B88EB9016763EFCDF929F027B7A12C3963B07F01E87762272F958E066DD1ADB38FED33710FD6E5E75DF098ACB3D18923F710D1AADF8906D1602E3928A2197925B971E1F6469090B932E2BA6A3A2D7D73B513042D1247770BD516E7537238E12FDC86BEE336ACC7DB555DF40B80BB59CE44DE6F5F45594F91F9A8A91146F9F30BEEC6DCDD98623E145CD3DB94E3017E73B0B77803D8D2401527CE2830EE2CD7C577601676965C9113912E554710D8EBBD66E5C9F66236F10FC068E5469DD4316AC852D2B7E7E74198F8490A299F9945D19FD66947E00BCC27D18182B556183B92DC42965DF100E1DEFA542178AB65BEDABE24E668E9E354FD616A2962E89AE02951AA8F7CE98BDBE19FB9E346D02A4353AC6102A5D2DBB8600FB25FE08830CF28BC7A18113C98BD151B8FF4882C0FB6EC1C03E7AD142424F65B7A1526A907DE28DE378A2AAE7378E9B5B5D3AAC8312AB8D9A7D13DD96064C59727335EC0946B770F28C3DD4D80C46A014552F0EA2886311FD4B2B66B37D3D7D1587552BC52B11D57E78070E306D5AE16C73B8B574E90CC8B3793B68C8B2614043035A19BBAE46C338D14991C344BEC13F64C29DCB9F942BB36393C5E6642EE1F6AC97A530374EC7646AB23292FB0BF817078892BC4B14426B73213CDB2CAF3B8B33413C92D09D343A53A0FD29DFE241BB0AF15E1CEAAD5B6FC6E89FD4C0CB7D720178531D48D2B3D9397A7C1EB5BECF8566DACA5D7828F10CB9E9ADB6580FE49C574855E287805983CEFC751A2ED29DE334AA5DD15A73A6561EE82F39F5EF3479DBF324AD94317F2B363E53B2B1A4C5C4BBE954EF7C5A5550F0770B056EF847AC587B56D074033CDA9CFBDB9B3C482AD69BC46E2FDFB8392F801486BF80BB58CEAF972437E237EE4D2D40381920F3AAAEA382AA6CBEF990EE1111DF2381773057B5F48E38417DA2D67456B4A9C414A245463F9C9C25DE136CCE83E0E5157ABA9C4864F02230966F3B3D66D21289E41ECBB0BD9E27FE6C42E540FFA552ECDFF62F6434FA3D4A76ABEA34DBF780E597505B86FD6EB4FC71D6E3E880483A7D8A148172D159BBCDB13B4DD613414DC366D6E68BBC2DF8ECF874965666BDC8064696401C0BA1F5394B0BCD4C15644CF2339CC7DC02123C9947998CE4106E0E3F95895DF08BB4E343587CDE72C07CAB0EF6C45E7759CDC2102248F56205E4F9E09A6552FD4A3351D6DE431B4A5825DDE7F102E82B379429162EF057FA564F24CFDDE233E9AA94A93E67CD4E716D667CAA1E98BE971E7F46267A81DF798FA537C1470BBF40C6F0F14B4E2EB5378DC68406AD9C5A40F8E8100E141AC728B2AC51654898F8E3A7B91513FBAF32C6670C294C3F45B45F88BD8AC8B3B031AABB5E8B127B5C7FE6B136F0D61BDCDDF36DFB72C8BF60026FC137D0DE670084D4F9E99A7482791D5EC0D9FFF4BD381B66062B15BB0176EEE004EC7EC97FDB5B712F8694226CE1D60E7D79E1394046A1252EE30DD15F223505F1360C7ADC789E4DD225F4E11D72B5791BC622C43163F3FC669BDA7A7A680D58D88FCB49D05177AD1103C65C1CDDCDC2DAEB29D8834CBC6A89F04AB592FD79DA9E377192CB88EB7151DC554270E4B401CFB3F38EDFCB04C23D12A96302FCF04B2B7751E1637E146DFB116C7DC5DC7A7CCFE56E0202CADBCA4065596BFAE3A2431C6485D3AF3B727C921B5800CE77873E3E72A1C4A03D54AD3B51ABA5B1284FAC0DC80AB5889A9878B1981DF24938944B6C2D570AF90AA661B7F06342BDA8B6E67B70503D12D462F0783C900F5500FE2F8167F27977C742B29A96BF82DDA9728F173F572422625285848ED21FED7A77B89B88286639907E58D28DE09A44B989EA8883B2A492367B1DBC2925465D8EA2B3338B5FAEDACFA0E17EA560496E10EF78828765BAA8B97106D155BE46CE0535B81FED4504AA9DBCE8C01DD09943E6552B4A9A21C870AA4F0CBAD2C3A049F9ACC37915DF05CE5D3DF0665C2C79CBA877F814B8CFB49CAA89D1FD415100B8491DEE50DA1E26D13DA1EA3B886E8FCB44238536A41B4A48FBEC56CFB38E3A2E17056D63D3EB1CD3CA53F32FCD7FDE8182024F66F57B14F8FAB506A6CBC56FBF9A5E58843ACA387F1C2C50BBED57E3110B85B3D2A688B02609D7655DC6AE40EC94DEBD77434DA62E1184519F53DF6639ACC67E61D326DF1820095C03186B100EB387D77D81BBCDBCB83070A9ADA3B3BD5105D1C2C3D9B667741A7A3E126B34C3C90555ED867A3A53C61575A51EDF66CE3EC527509343ED637AC719637EC68C6D7C2FB9D4BDF58A3E16E74608957F553C193AE7A1077879361DF738DB9DC997028942D4AC711B0A14C6BAB05E5C07170E1D0393810EC9F3044A38629E65BC179866692A221B5A651937B3475EFED417DDA8FD06AF7F2555427697077A20D50F4283E31C70BDA469300A76D8A8F5756AB47D46030485BC553FB69B12CB6EA71E69C88910A86D91A039A3C5D1D29C9A1D728B508395ED7C3ED98218097DF7A65CB3E19D136620BC2A933C3C951E81C707E2DED2490451380EB0370A41E46A043467DFD7EC6B37748626ABB9A61356C95816BB24C29A4C64D6A7B4EA3997F635DEA05E400396E8B50DCFBF47859B842E1215D398F8339D8CF09DA11F9B93FB480690930EE204B18FA572AD409A16D69DA195C4BED44BB790E4BAF2A0CA406198A4E9C176D6A8A85F479E2250E0E623CED7EC8DE37E99716F2BED4F1E25A1F5C49FD6A4CC84B956EC82468777E08564E15DDE40548488ACBEBEFEECF8D6501A392FA0E126924063EF9D0285C5571D09E294959A5F1153B44EE45FFCBA5378AF7F2CC40AD35EE2EC6FBB31E3FC8EE7C89A6E07FC1B1A7FD602ECE50D139CB0BBEA22F95396C52352D0BADA3278305F1AEDE214C9C8CD9E0D8CFC81D9FA5ED48118D7A4D34F8DA18ABAAAF51D1B9A01A1FF5DC3D7E4294D3534AA3D121E938E3E8371014DD11379E88839720", - "sk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D73B1B651557BB7138A45C55436FA0CB57DF632FC44F7E6947B2262A553675388D926CE1CF7D3C24A6125124973E6B13743F9D8337CD50156BB82556E328CA6E8D007D9A8AA09D94A21CFF8A1A2EE4EC48F31E967819633C9AA7AA697482ECFB453C48451146A1B420443C028932621DC988C4B3665D83431593886A4406D014872D1C66D40260D14278C5184848A9291904464CA1089C9304A1C432A10822D49447252420D1A322420224058160D0AC26008950C12A171883070220052DA200800398851388994360A11269221B72DC1342AD41446810606DAA4691316094BA44424262A08C110D812240C4500CC424250A60119918D53027119462961C68159A42DE33230D4360EDA0632222550143981D10405941040C20046002984D24050220746C42240023730E3A425D1C2040C3166C02430E01620440040C0C681C12825233209E3C00C50124CA42086C28211C8268884082914B16DDAB00CC0B28410846499981090224424802501A589194291E228290C05049A948990422224060EA3148DE4A2609C924D4B885102834C8C28025336022315111CB84591164164129118226E90B44921980DCAB6219BA43062366A044740D32005091486209925DBB00053428112A711DB1432C1240222936584347111172E53188924A7090A210C1BC32CA2224413C6059CA485990891C13229D8380441004924989052868851C88C2029201C252C4B440912B350A03404933280584682C49689A300095CC01010288AD4360C5BA050A2204CD3C641A04682E2267220058800084E032412230702233080D1860020834D0949115C4445D09881C236088482855BA628123650CBC88D0AA150940051E4B44004C62DD290095C880588A62918377003078D1C826D4AA67080804D63B66903A5918B0864501652D024464114682180690C17629A1021D4321014980814A37018C4659146660113015BC04023A26950008C08A18DC8140504A024091928E1960D032744891662C044324C442A8106265B08844B4208D84829DBA46C1C3160582029D1468DD2121013976D243332D4B6291845648A940090C4081C330A4B2011802885E1464C4CB688081861D8B88184846CE20226D1306440C86009416191122E649831200350E2C42C0A40214C3412E1202024022C41366E04202620414509C50582400DCB3851109550133491211022D240311217440A49909CA08014116D10082002408011920D23178601846C401292028591D9862984C8691B8650C1488C0930090B846150380E9C06229B4692DAA24000A36419404200056CDA104991C289111604908830804290CAC2059C2029220171630485C1145059347203C7009398450A0902E3064E22172614336541042550364518A150602628DBC00D53326A12272923854C9CA00CD44460E1B808CCB440E2A44948160009172DA3246A0C95300415100043424B8810D8368412436A63B4651BB32D14B14188C65110A08D1C2970D2B2115026499194691B128CD898604038680C09710C42480C078D4902008B100C02A351C8400480222A24422E8246888C26248B2832CC380400042C894449C9C20C02082E13C53153326A0B484942488D1903712386041335484C028101C4298B90016230094A00854834320003920CA201C108846144414C20201B1505D0B6045AA28018898494088084040E52280242140E40304583A400492280A1824C02B30D1028018A4652D8C690D22842A12226534410083362032672D300821992319BB24D19A60CE434704C128119067013422A4B06929232865AA424A1B02D02B66D4C06651C00100A026E902680CA286698C09010A9651A0390E3488148B4601B058CCC482C0B256692162401C66023016D1B46510A360484944123148EC4922C12084541463099067080A8108334219A0042889221D4244293B67002342420190C601805DAA431E498641131915B44418C886101A62001045190B461CAB68851C428211772503222D1B251C922059BB488833286001522A03809020466511451200672099464D808328C28869488659006488BA22D132650CC8205C944680C3590434002098850021770082771C23802A4468952360A231302501805E4084C21B14C2195501B4866128590890850D242621C002D170F4C880BEE2D7949D532833B199A8F1AABD2EBAB8DC6ED79D3CE9791B5FCC90E1440B2FCA080974B7F46CF160E36997EFA2879798E2B9763936D73CD08214CEAB7BEC430C10E250703613D29BF5D54903F114E5C9EEB0CA35CF0EA999D0FEDC7DDBDEF4076DCB97F8E4DF850BC4453F5934CB47B1951EACC8065CDFC3A02C137B0EFE379FB104EC91B4667A13C0D49043F14C02B1F493412EC2820DDE3DD9F77F62A2F73BAFAD1978706551B9908AF53751BC8B8979B3AA02BAA9BB37A9EB42DAF7FD7AD5D02295B9FF04A2A80DA3071FCDF2BF58A2B8083799DF87118689F7A34751D5039729F87DEF79E20D649665CEED960D2CA982A29FFD7A5D430AC8B1BBAB0982CEB99BF2A24038F67F4D224A794DC1DADB0D958544FEBBC073A30FF627F06259A093EE35F1E184C6CCCC51CC86E0B1933447BBBB13F1275963AFBEF220E5BF134C8062E10AD74CBE5CF5C22D4B61C7B7FFD66D959742E0CEBE90C74AC7ACB8B47CE737F6C44FB06D6BA5B7AF82D3C0031CA35C31876BF7376BC8FC59E8E74C76DDE4EAD1B648BF5E2CE28603FA017F8F0FA7F7070BAB8AA3486963B56724418F805D13E24D3B3898FEF6D4974CBB316CD41AC7B66E7377C1282FB01764F148B8E1E715B519970F842415B9FA682621D0A9A918459A480D863886B005CEC83AD809AB5909E433326BD19C92D15048A67F654C8B5DAA2015ADF5EA08704B4A20ACAD70B472005124087EBBA4C264055A2817EFD0A2CFD4CD446CD873A9BA85D9361532DDC0C1CC422C67CA3DA904C001D5254D9B2830FC1A2C54D8A9FF470D98E14EF47D51E74B1F633B9F52706DA39D6FA0EB8D8CC52375A9DEE93FABBA13BF4B808D6F27B5EADB29ABDE6E3CEE6D4703BAD39F5BF4833A3CB98B0D8D99C1B2CD4D5DA4F6C5A7C6AE64E75512471B8AE4D8E266C55854CCC37EDFCB6B361EBDD6492037252325FC694594F3031ECBFABAC41694F91178FBB7A1D93594EF83BBC94CD3E5EC1348335397BE29D7950B00424A79E47F8678CE690522E45AD670350E41439C62C4E6E722BD354804E178C5B4F226CA42D8C8E81B32C1948051AB5326AA03E72EEE8114C88372FF05CB7E5CC1D1D6829C520AA6D4462367247879C7107D619D66F9F3D01BE81BDE3ED85E87EE8710D2CCE5CC4F9E4C52758A3C819EB7D0672781EDB86AF310CDC4789C79659F9424380F42918DC60528F1EAE3DE5AD34E69D06414B5CC50B311E3C07AFDCE85BA3CA993843A18550D42FC6C39DDB61B9872226D5CE2D5CE57E427953FF303606A38CC4AE3B5B6A0886C27AF4AEB630F9BBED6A0E0688F532BFD0D727FB1357F2C8DF4FE36E3E33255BC6E74E4FEAEA7D6F99E249F9D2082C595C961438A53A8138EC8F4C7DE974208278467CB58240F4E48274C702EF2C6EEB718447F61F91E4AD08FA0C1E435A01F3E3D6EC6D7FEF96996B6ACF37632E4BDD02AD3230B6FDF302E8F93442A4693525DDDD43EA90E03DA3FDC054916614DB8CE66435DF03A2B3CDC14415143C53F387BDD0BE8150CC06C323D67480F56BF519308A7FFB993135100679C512B6D23CF99FCBCD9D998604E061D242CD7459FF389371FEE1236FCF1E85204F30B2DA3EB220CC19A2455568DC7F6637DEA11139CEC3C1D595B24B456F1261F27608008CE3B1F9E8905BF445CF3FDC68DDDAB5664394328113169EC75EAAF0B739E7F3ED08C9CFF6D5FA167ED85AEF78FF13743AAA84921DE09302DDD8D1A99705E809FB13B26F8D90652EB7A0C70623132FFD32614A7E268A5FE1CF298D8D1406FEEF6056BD42718F8256AC663FEB926F61393E12944A1644A9804513D38EDC72072A8FDFE3E0ABCD45A4681891CDACCA1EF58EFC8BF58D182B3FC7A8D61A103CE517E5ABB983E1B58DE0F07EB24ACA29725A5278CC7C06AB253A55E14C6AEC438FE8B9F5606EF06FD44A098ECBFB76355FE8D2932F72ACD219AB56F50364620B381A9AE940F7A3F6E416706278EDC9526B8783E9B9D75C523BACEBF472FC1C1741D7801ACBB3793ED9E8A7308018BAE285C2B36A3830C98F312349286F713247B4E3AAB8B089DFDE8DD3D5DF17CF3E58B06A6838EB37E5F10D6D6CA986CEEA61A73D5BB7950460774572E71BCE0DF3B5A4DBFEA69AB598FFD56E20A8318645AC33C9E53430D54A542430634B2ECD0D9343DFACEC4F2C84EC9241D1E92ACA6CCA673465AE958EEB1BD55A9B6B927F8E97CB1516E7783185E0F36A6B8AABD9653777A80DB0A8EE56875A77CC4D77D647DDE9367B0BAD8D6153E475BCE3ED8AE97C8C58F60EAA37E01BC298243BE90DE8DC8612678F3B821EB6A866276D5041172BFA9A20C2E562C1E3B3BD21A3D22BC6F276EC19E4AC85A8CD731181A3EEDC1EA692917F8DE7608F6E0DDDEC449A9C16892D27288A1710CC5142CFFD329C4CD1A4506E0706699954D0E7A8C310567900FDB0AA1012AB331AC52F46B81CDEF42B5D494309E588F775ECECCCB96925A504C9EE4D7655720C0FB1EAA63DD14A0E2EE2E37DA3D3FDE0BAFAE83C1303BBAD5991BF21CC6FEB6DA598CCA5BE15773B85A50A0BCF9502EE2B9202CA541F03371C94E1A645FFAF98BF4841CE59E1CD806E7151D9F3D568083385C2FF041D656E328EE76FA41B8DB0D60DD8A067AD012940C85A843DEC6888397258F1D4A75EC8ED9BC9D60D121E69A9AAD8F334C8ABF6942F89DC2DC8826D2904BF5B331155A9E3BBAEDD4F1A2EF1143C7651351FD7D8F473155B85B2B21BB05DE74CDAED6EBEBB8BCC2A3BF8FC30F6B89E50F160C7FC11B099C3B6DEBE53E2C6A5C0D96F3CDBC8AE448119F5D1B27E3083C82190CE1C1967B27A207634FC93986A5D9A18018991BB18CBE679FB9868E0138C4CDEC51DAF819DFD579D8726808B4A1FA6436FBEF11B4BF81FF2C1A80C8302FE90B564F87651E1F42E30C4A32A1F5546680A8FC6B3C18CFE217A86ADD3E96D0B84A9811932996C30127BD5BEAEC298966FC87ED2D280EBFB55055ACD4FB781ED3480DDF6402292D0DC41F5CF5552C35393EFD69015980494F11A9F63FAC77362555F8BDA8E9319E72B35CC0F13CB9A87D3F850FE89499B649AC97AFC97D0B1412F651895F19610245A5F9691FF5FB4E0E192BF59FBFAC4EBC77DFA81BC0BB32921C25F45E07BAB1924A5B0D7E41108C89B964C7C19EAD8D6C90E5FD77F206DB344CAE717F14C5FB8ACA5293C5C6718E1F3F9C92146DEFAB65EF3310DEC708707B2B2BA0F4670C10FB653F2F8C54A9B906DE06D2A93E36F0CE6DEC71FAEAD4C7663F160194DC2DF78D6E042FCEA0F100180A5DFB19205AF4CB8E88B22F2771806C222CB88F3C92B72CCF36D331DD803AD7080FE334CEEE9B04B9DEE66E3BE9AFB17475F8EBF168986CCD9BF4E1EC2C06998F9A26CAE3FE52B12F0331EC3C4CF85C91176228BCB56D0CC52C8C1D60AD6EF34ECD6DBA58B85F1AD69CB2F9484AC7D4446DA446487249BBC646832C57085622E25925017CF725C55F2BCC3DC155BC8064A1A6A9581584B883D3CEDCEE272728980888880CF6A23181F00E2E4182C5A191DB684518E1728E6FC9EF5FCE1523B8CE68DD790411CFBB8E58F4052727FF6CCF640DB939DBF955C84C95774449D4EBCABCA9A6637A807181F1CEE17C621CD5C29C59C155DB17DB49E838547CFE72171CE48FB1AE3B1DA964A95D5BD62F74A0C46528A4DB898854A064B7FA8E29AADF19233C3851AD0EC0074FEC5BA61AE34FF7C474E402622CBDAD9B70AD96559EE37C89163C271DBAED2D721A42F33965E70DBE0E6BF55E9A24D5F675874EEC48F417778838A0DF29BA2CA927F478063F667C7CCF1A449C48F7B14E23B54D16C3B0A284EEEC1AABC7D9A7E6DD880A980F8F73D47E4705FF2BF775D86C4578C77738D36F4E7E0885F16AC7E7384284D78CA36708B50943F0866E7438CA56134E286417E94B36234CBCD2E279BF974198EA375833C6AD770D6CAA76D10C7AC0E07886584A89BBD6E0E2F9801C1A429F7B48A3996B34D9192551A0AEF46CE8CF84BE877946DD751CCE1716E47A7A88B88B8F77BA7280B7DCAB62DF14BE6BE4B90EFFEBDBD3555CDA85AD90185C68F0C38BA2E036C685231C6CFA1B3BDF42426A2AF8F5CFAE4C998B330D4F7D4EA0D2F9F21D27BC13BC2127DFF9ACCF107B2A04CCB1FF1C85D26ECF8B897366C213B8C796454BAEE61CCF0CFFD49047A10C6E6F417764327F37A2756F6BD70E856CF3A16800D47EDE41CF7FBCFA107AA61F5CB95BC555F5ABC9839EB4DC6A6EFBF44D6727BBB6C5644EF183264082DFAA31E554E4EE9B7D3CB4B96A817430AA90257CBBD2A2AEC5202BC83CE146F2FDD7FBB0073D872BC8C9B6E52AC946EF26E20021147DCFA2550DD9FA380F854DE101795D1D05DF8A9C247318F3FA5F726A36697F1843F1F44B57D70ECD52D86ED3C5AFB7B2616925608263230B0DBADFFF5B661C8952CA48653101244F940F2C17D9E155B26E3075EA9F3D06A75A4254A628B2A15B269A1D1455B02D44BD064B5EE90ED4BA37E9A92FCE4C26D96615C726C6B604A964C9D0E498ED8D18BD3EDAE8194246F25BD618C2A53C6C88F7744CBCCCF4966BEF5BB4D2E5C03089C561F823605B2072C620F85A0E8907DCE2DD78451DD343406BB23B6AB74573C1E6F040B67940FBAFB3A4D1BB59E8E698570E0B4BFA523AA269C6C7A3908369078996189D29B9D" - }, - { - "tcId": 64, - "deferred": false, - "seed": "23BB289CC934CEB1993640DF1015693EA499786882A987414FD320489FB549DB", - "pk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA38AA9AC55571BFCC03E47C9D28AECF1C995AB14E20718C5913DB899939D5E05196AE807A2E01356A5BCD39DAA2B6097DB0A1E59BE749F147675B8E483116CE553F964C7676B6BF4876472FB095308B3F19C585DFC11C4755898BF2D2860A50B96DB8731D7A0BA1A9B9926EFFD6D351DBD3DF4E9593861DA889B4DE05F1BC908891AEE2CF827D2BFFE673237364FB80DAC1FF57EFA9C64953D04010F331C50A3A7304669D7C1FE09A45ED7822E7B16C0FA25BF50B5F45088DF18BB925E7F81228C00707AF7CE831C4303CB207AEF57A8117202EB2054199CB940522C51F10C0EDC37F7CAF4811C1D2191DE97CBF9A588B5AC18D44FA75C18978CF2A992C64D645D015204A54F62F080F2B3725C3C5B41383667BB11DAA5F58010778D875CDE5BF1DA1C7801E3DA73C9C586677D520392421621B3EB73D5673BD677A695FE158BC9B055F8F0DBCF0D6DA00FE4AB482ECED484D3B2F9BA25A7B75777E3B8E8F0AC5BE1916E144817CE53344691129AC8C1BB358D2B3FD648E879C2373EB7A945E887FC7A68D4A6A8BE8D1213590F696CD7F07A46F75304AB6F9653C6B8C3E7A4644C7183F43FE594AEAF139ED97FE8F578D752BE0A2AEC39D6FA474E8BE9C536289664E97879C2046965F2B35C5C3EE5F50E0EC537DC92F4622F8FC845AD4AAE6F3F1C1CD0F079B3C1B918ABF9DCAB771157C19445CC35149884748E9E7F5653DB0A3FEB4B6A22F7EDD4C091073B4DFA96C5567AD040DCFD03D8F8C06F7C8ADB09224B28ECF2965729DB669DAF4ACC6DA9BB53EC28F3BC40FE690FE61747D7194D878B5326C320E53E9DB8E5E31250BA43AA7B0FD09B2C88D5522527778B1AD9706551CBE64E95D005E23E3B4189412FC048CBA553D186D9C9BD52E04301E5B399140922690BABD55A89E91A89CCF125499F97509475847938601781DFF91E2C5728F63117AB5E46B0058CF23CD4DF0F850F8CBD50F9EC40351703AEDD1EE23A49285CB9040CCD83DFCC7CA64B3602D0EC606D765D73EAA65AF7483AF174EC680CF99172C60E449CB1B109D2A732910900507797237A38B14AC61AFF346E262E1F7BF5C290694C22082ACD5E21EEB0BA17D2E6DCE5B5144566C3C5D185437FF9150AF8356D22DC4CC368A66C1CD8D11609C50C28B82754EB07C6559723204E65553C93D5AD6F628B0EA65B97186A69419281F7C4E648ABFFAE38193ADA329082F0698CA091CEE2CA63DE821B5F33CB2AC74C85045FB5F7EC6B86409C705CBCA2594E4B5D1F6E9E295DC72D5BFE6CCD9590B069047346200B7E18B6F254794EDB8069FF880ACFB3FB970F4DF373D27FE784E34513C2DD0E6C700277B03D35A20167D346E247EF756E17F2997F8E8DDD86581917A78C0407C80A9AEF504069B24F52CC929B15DBCA631944F3E16C1DA45F3C55EEB697C00CCF24660B05B6DAF33E00F6EC513E2065E0090B8B16CF12E461432E6A3B21754C7F96CE7E4930C86114E2A7D7A809DAFF959BC73EFFEF4242484FFCFDC4E8A45447507BC639021BBD2B02426928BE4A37CB22D8FAB32E55B97EF5EACA5F3BB9E03C6B2E0DD9220731B6124E71773ABB62985074E1288AA955E86E7C4A9394C8E7744A5EC19B0FA9400E3C6C8F07F006034B44C31BA2FCB2C0B774B7DB59857CB2F9F82222D64055A2A2CA653CEA909B97C010BA0FFC434B4775FAA02F626EB0887CAD810C6081572AF088454D09FF2AFD96EF89DD8D466C4E3CD28972A652BD1034B65BE0E6628CCA3D9FC4518BBD8D03740AFCDBF46F4266572972666F7F5B12D4D2E379ED2DD5E1F95316AB0A7C7C807AD6904119B4168DFA2FBF3B9BBCEC239F72A1F5FB44340111C9824A1DD907722A75AC04B2ACFDD3D37BA1FDE4819F0D0FBAB61D0A72B664C8D8B0981B16E2AD0C64C2431930230F47D03C04501C29707B5FF66F8BE9819FDACD64E3ECA6BF66535E5D39998EB47B5AC726EB6EE4FE7414CC5BED56CF0C9D2F15CCE8898E5BBD9D6D9340C0C0365B76DFAB83470B22F94B53DDD079B1658801B21D14C9A2CA1632119ACFA93F741DEF70F6FE8B5ACF456AE19FD603B7D5A4609E34F9ECA9C3019B8D44C0C8A68CB7A2C9D06A9EF7314ECE97EAEC6441ECC1D4269737DB6F1870ECACCB822DF0F8FF694D8557DE50ADD38F8DD46E45035396C6306F32C665B6FF31ACB5B2A3736275C8371EAB26D221BD49F878FE270292540B7331C89D9BB0E9867A3B71AE6A7E532029EB6BB3A1702BC9E2D6F99C6D822B3DD079EF0D74F903848AA4948BAEFE05F575B606BF5C80156916C0AF0BF00D74D357A0876DABB37D2D9F5BFDE94FC9B91E65C29C1884D30573B14598AA23D969539E5DFF0A8F5F8B9D37D2EB6B07985660B0C4AFE72D94DF2B8CE9C91DF195CB13730478E4ACD65B65CF31BC6AC75545DBBDA223FABFFD0206CBBFCEE5DFDE78D2113CF2D7A823DF4D94BC6AB7853434F36F39628348A4F7EDA5B18307E6CBD69F3A5B4C0D10AB16B470A7E7D558CBD6C63C6495FAC0FF8166BF9A058EC0917F3F0B0A629AF76207D2DAD92B57CC3E559F572E5C5EA9529CC4F33FA61D4C9D027F4B862ED7E128D27C6AFA6F86C98E3A515917136087495FD441B5D54C3A7A1480F91125A2C0A71CA5E5C8AA3F015CBA22D3558C1A996B00FF50A58CE99E61E281C086082C9C8CE06704BB686AFD8F1DD5EC0AE94D93E273ECA098CC65E3664DF09E0BE3AD8A577CA5ACF31285C26EA0DC6B07D113E761D321EDB5EEB426D883E94467633D8B1E7EAC425423F2C86461D9C7635263EA5877F12BD8173DF6AAFE2E8E659BB39B17C999BC651062D7C14DE96C24EA46DC15C708B122CF079DDF3C85AA7F8116B9A59E77A5B1D16CD50DB43DE5C19DAA22F9C58796C1C60CE186405F277C3B3A32BB47EBEF753B6DE1C1DA31DF20DBD5D125A1C253D6A708243B50BEA40F5EC6A43D71F4BA01C80015B6AFC6396A3A5C9A30B555660700A92EA0476A52E6B15EE1E444264055F64F84719D42A5D854D91082117112C8840E6DAB690DA578AC625F845BF87047EB5CC21296E1F54E79B9A87B3F0440C2B277DBE20B2C5D4CAF803AC926F82A780BB5509073C3854296FA62101D444A6386E338CE310DBCF85171D8C243D71F993D21CCB7753F5CE23CCBA53DD589236F8947ED0A26E6CEF3536C75F10AFCF687E9FD0EF121AEE911062756379ABD985C2E99DEC3C204D98C58AA69DEF3FA1382DE4AC87F7E28308E872ED7826F01A365584E59A0D345F81E0EBDC45178C00BD18BDA8D5B905BE17DDB8AEC470BC1205B1DF09F21F39D9A9DAF1E04FD1FB62810B173B85FC5134AE99E44FF43B244FF07A15BE0CD15078800D60B1FDEC8964B10F9B56C4A14FDF7FE531CD2BBDD4BF17AB7B4353D00D7BE9194A13D0A313C0A166CD387134910A1707A642A229FFA05023DB92429ED54766D20FAC4DFC07C6DCE8EE38D9A7189F4364A8932E3BEA62F8A8F22473A066A1904108291541FA0F716E586BEE112EB37ECF7DB06246395A581EBC30A2E54BCBC8B097FBD50F1004337878814E932F7C8296EB90DC265B8519A3D420BE636472BA55B8E099C2C1AA6DFDA96C32A44717D52C9AE852DBD0E8E684AB00ED7C744CB881", - "sk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA382A55F39CC1DD6472202739B17FD8F6119F6EE2416E3751DEA7ACA6511201476F3A9CEAFDA8CEAF174A63524979B737ABEC12554BD7DF8E35D8141310EA89D9667F769E56FC0E0F92C9D656BFAAA28856C11339DAB43DB3057CEEDF836365F0F0C8124E8BB880DA00880C304EA0445120B10C83908D5B282A40B6511A33061C023283488C58106E1C058D03C22DDAA661C1883083C291C13420183622620011E1A20103C228084425C1A80D51182A8C24060BA54400B504C4124699088422063159921153B68918060298C26090080C8CB871A416429A102613C6450349824CA22003A3455346841C45448A24098B80211209248032669B4200C242061496804AC0906402460C246103422064066002460EA2B830DA06410892858B228800C70823239022088511276AA2486D1B1506811432122591E416515AB010C8B065111122D480915280508C92204818115884040210490006691B026659C8492011315C446E00B110D3124A51C66422210ACAC64C5B320504B72152B428D32260C4084253B431E3B60C49088C44481052221194220124A22D009085D9C625E2A84C21915053264920A3881C040599824D4C3030898865541424544422A4005111C16C09474C1936621C262E1BA64C0A1409202821A2A689CA340A234762CB04881C07058194505B2022C286508822916080480A1984228888A4466411916C248330A0280C62A24DDC82515A446621B32908C6499926482312124CA41113464851282C5B400591384021A36CA4A20990926462C04D48322C9918811244851101610CB910538225E3328ECB282E63344ADBA86124B349DB242A1B1185DBB049C0C28859B0054B20108A444890182C00B70C0138020013812200109200859B9048D1189123A005D49430D9C824D2280E2086304398000BA8301AA78DE2902098884DCB9401D04690202688DC066141388C02B18CA2040CA4964059C0710AA65004B38450422680189001904C6280845B826114B39109474A9A062ADA044CD9062CC2A80DA320008BB46D58087111360490242002220DC34664D9A22012012C83A60C01806152448204054ECAA00D23A86D2227011344094B2444E0262D99B045239570909451C44429D4062A09A72C50B84DD88660103330A314419CA825E2404CD808488C16099220894C48119C9009813692A4B68C214961431468D480201985485B160000C1656386688B302214054C80484E92C48922A72580B051D2366A921680023450512689893441D32891C328720C3025D3A2411B23828398310CB10120822CD3067152088A64A268E21250E230281BC111500011CA046E24A84849B041C3165199B06C44A00580C88002378E04A649930860CB0825A2986CC4C68CD8324153C03160B40C49266D50086920B680C0908DE21201C9126ECB4825A04892849828DCA810A3120652B64188104209236CD924294928011A32814A26200C08644A809122202A02008D84987144348C201144C8B8902240321C311103C0011A248010B08084186CD83890E2142D59066862220C63222503834198A080D0186122136943264802C0899898054A4226190206CA164C0A12604AB86D43404E0315229332054C0486E000658C987022857163081080160824C74512904D128505CA4884CB88716432101B4212E3B83098B60C94B45008050C08386420487288420063A0601322420B144019B6708AA08CA0348AD48608E00692C1A8850A92885A4426CB447260423221A091A3B471CC388C43A608C43460A3B44949C62C80B8711002904AC088A042321B872402070A99C041A4C4840CB5680C8588D0B46818104960A24CD4448858824108155193C88C09124260A251D420291A0810202810E3085123174D91A8319CC028C3A0900B1650142406E4380458082A83040813401082403119B62052A69014A364C120694000104C806C00A4085A90880C218152167000897019264D63342E0A470522994418C4401B8725CB168199B8211B964D91142D0A440483C4449BB08842426222B2010BA444613069A3186514B52101B26D11146591388AD134105B364C011891A386012110621935208BC27122A22851222404172408C32851289204952400B36D22B12919165221254AD3068A4882041C200019A650D7C1BEF09D1A5AB2F21E912D5DDEBEFFEDAF5E953791304B0D2B2BDA83AC05A83C57F672EEE2E73BE9022E63C64697BE5638B79142BFB576C0E7C4035365354E5D394A8AD64B33A9435619CEE98991E8B1E97D508E295A394FB4EE32CA9A0DE12ADADEEF508F07F2B48A5ABA6453604CDEFD5425D6303616B847D00B5D3910466F3DC420E0F4F6D5FD1E0AEF8F5848DF0FA693C3DA60383235807EC330665AC6DDCBE3918B8A46EE5A59A387B5015BEF1299FC869E7D1D30AC835B3C1F2E727F21DDBAD92650A8121538AA8A4FCADE6A13E3CECF4363C2754B3DA76DFBD4CC95917A1B1D1363329E8F11A2902640EC318144205C7758A984C596A40BA5C8DCDBCCBD717464ED2B69A65EC8D5D8EFADBA48AF762802DC0A36F89EAAC39B2E31EA348524B956A5DA78DB04E281E14AADA9B89714F8FF2E781321C8C4620A165EC37FB157208B256672DE198635BEF161FDF89B607F1727C75D9D45D70A8FF94413A93405D06C6D0D822E4FAC5137596803032A06A15BE32CAF1DDB14A7751EC712825DF6019289222D2BFF84FE8771D4680291E7BBFBD3F31242CF086504D015313914D6E6E9489648C08D7AD621DAA70237DC32C11C959BCBA0547B67F77FFF0590F7231A8026434CEB71159A31DAB3B9836CDF74C499343F9695D79D33557C13BB07A0E889D668121BEA0F0794B5319ED4B1DB298ED191C69160B339B66DEA5545BFAB625255636E5BF492E67DE4D33AADB56F924AFA84D91E8A1E6DE385714779F632F031DDD60569C5D035260EB1A0A995D3346CEB0B511DC87B13A1D73FFFF1169942E3D788C759CB3668A32013B95C5D498F4E05F26EBA9A444797458244CCF499427D4B0B457C7E7A5CB2F27ED58698E0C16F89DEA4903C7CC7419BA70AFBA2914F4ACE876A81D29BEAA27DF75E82F941D1538A631397CC9593ED423AC62D147BDFBD50E305CB3A03B4A8A0010A1CEAE0A4813F6BDF59F3EDF3364229C8F524553717D5AED1F9282B73FC37216B591C7F762FE3423C5D363F3AE6D32C06E192B135D7EE100714F5682CDB123B6EA8AE5D03642A435B6F2483D67ED91A58A3F1EDD98F342F819BF373E77BA3C5CEF082A7D58DD103B0BEFCD2F102BDC2738F6471FAA24E4DA7AEB86CD0A64E227482BC864A7D2CB9976CCC38BF1EFBBA872244EE2C9C366BF161CD5EA83E652C85C007A29ACC0D8783507256E9EA53C513612DF7A1857C12BFE64B106848688C70C05A06148B41E16B240AB2222A770BBAF3643564D5C10055AD40460A4028D03369982524D6DC3C3A0FBAEA763528EB3CAD5022F37126B72F1C239D801D4B002FABB90AE9804888F42ABC2601F18AF8BF9D319D0A8576ADFADB7E47DBB837FCFDBDAFF6AB5D16B55DA2EB56201F66BBE9E0BD78EEEB2037EB708BDE7999E2A3529DFCE57A7DA0DF50913C06A425CB665467280D2442473018214698E73FAD8C94C4CDFD01F20516B9D4C644DB04AFE2806E1767AEC74FCBCFDBDDDA474808AF96B92A2814AFB46307A06E15FB5C0254579776AFE8C7A86B3DEAFD5EE14D42E44A2A89C53BDBBF6A85F97B4DE490D1B3612F4BDAC78FC40C97AE572C5E333C202556B682D106C5E7FD814CEB696CD94E7D2F75C5DBE95D5F30672FECCACF629504C8D7B2E15505A241189A687D715686D5EF6F48B00C139D6346BC8FFDA65AD6EA7F2DEA62C91B87FF00A94DBAF52808B51F1D3E4646997D3FA2A1BDFA49ED5119B7FD5E6A3C2BAE019D5C2D52B8F4DD733B3D452D71B5D6E13019F8DC0832228B836A34517E29EEDFFA7E440B87B0A1D1A85773ED178EDF20614733F846644D9D87B2929AFC75AAADC84A8EE46CFA64117265B7CCB4987F3B9218D47DC9586D47AFBFAA700CFEA59AB29C6253A2C85D8B03DB1610761D3827B79AFA0ED64F6E4258622B717D06FBAD64589D00213FF42629368871618A1A76CBA764ED9AC529E790F6F19937478D0AD8B00F47191F5D3228922AB1CEA8F89E713E9BFF2F0A2999E765AA79F01CF93CB519929DA9A9F52534396D8BED4F997BB73ECCE290FBB34EF73EE344D7674FE7CCA81B9C3E59C087C68D0B5AA7B30D7204A8E5DFDE41FE6810B8AA73C8D3B589832C0AC61A8B5B6DCA3636C19CA8D0361BE98EDF9868AB622F504860F98EBD2AEDB1C4C21BD5E082BA30C0CF2887F2D3C379B4F1B19588EDF9881D1A01A6448D9740EE5A13782BBAA843522E82199B84FA92E12A58E440E03C17098C327DE35F91466CBD7DC9643130D91548038EC7AAAA490E25F88F2B4A50A9F32BD29AF4735D3DCE745016FA1F75A3BA7AE337DC25B5162D8EFA78CC119C57E065292C84D5A54908C14803011D82AA40678FAABA0C79D4B3981C20E0F0A7D890612A9BD8FCDDB59BE33549A6FF8E00DA5786EE8E94CD12B2163BBFAF8994B98FB8B10F96E17DF10FB24E55CA7F9E24873AB7D6A3442391B6E24B67E40E3DA4B63D558D9D79E1068473D97BBB3B842BD76EB96A3260C1F537D2E9CB6F0FFEFE3DF8677763ECDF4026159A407EA96A6DD8CC7662E3D773BA23C67E93CCF73710792A8B8E715B6F2DDF783C7F9E8F70F5D588311C37DB02B6E4BCC2D63013540ADA9C053A27E2165C872B21F867C64BAE5592C9D1601F7635A99258A2A41B94A6A1461FC2FFB1C9708387C89664E218429A1B2BC3449FF4B8BB04EE22F92383B9214C6DABC3BE103A4220E0BC93189C9672C006568C2A02C424974323EAD572A5DEE85DCF8EC343DA23071651380E5ED3F0CD03EFF650D789CB339ADC67AFDBFE0BCE8E4584A8FDB9A4D24C1137EEB55E53361C3910073DFDBFBEA44002E44B5EAE15B147B4A90EF0CD1D886DF73803AA55A6F37E9FB32F7ECEEEE495CB44A2965F0108052D1762819D04E1CA28E0A5240AE5D77B0EA36D42E49C741B09A5D9C74860A9AE013CE42C55B5BCF9988CF9A7E231F6784AF6805E5B79271402857F2D18CF59D69921AB8DF6C936F98A737CE7B1839521272477EE3F54164FDCB3BF4B6CCFAD5DF9ACE602809AF8D096BAEB9EA02A901EA7C9DACB20FDDBA38AE3898A0CB277A7170F6CEFA70864EB6571F96E5DEADCBD03BEDE4F3053F66C2BBFC01B99F05156EF302A29028C57479219E18CC73C29D4C12D70C9B99F0FD9F1C9CC7CE8B1FD4F9D0FF82B703A2C93EBB3E3E3D13A28A4D0722EF63E8BC6D67938621544140E7CA6345F88548607D737CCA54E308ADA3D17E8AD01E27159312035E0254682588F4073F829A262A1C37F8E9AD94F30C1079CCFDBF9655110D689887575A783E0FB5D3E1807F62CA14D7383C56A37695115ECC8A18D3E6E197C714AF1F0784900F8025A37867F7042E3533571FFB13FBF132F90BBE6EEB31F759E8C6B03396B5771191E415BF3EBB8F9E55F2514DDFFA7758B4842BD76E5DAC567BC7D440ADCBFB356FE1280D51351F9B12B3281F47592B4327EF74873C70483243FC12952BEDD44C4D5ACC10A7F513024B4D9811E91C1D6E0A5A015A719944AC8734EBAECA8EA22FF55C9B5FF8199DF6163F9D3955A96E9C5097311E197F4CA413B5909DE94AA2A59F681808CFD75E887747F7D539086DD980C34330515D50BAF6F7D234B99F18AB0EE6A427FB956BD747DF06B3D7078915BBAA02410EAF0EC06BE06E8BD8E39F5C0BFD43DBA1E0D8736C0E27439B43757BFDB16B46428FB3C06F7C949EE7C418815A4BDDE5688830745ED66F25C0658BE197CB157FB49DD9F490ECCC0A8D1B395435E9477767F00FB257C73B5225BDD008464F5F8B63E0760988C05E1B6BDE4B407357E3B269FFA93A75BE609F16E12130FEF601BE2B5BA2A0F34724D9B62786F1ECCE5948DE70DA662DB9DEEB037E398B19525775FFE9E07AD70507DCE5E1A0A732BDD1BD3CBE810E10E6FB46E5624BEF6AC2B4B98D4D711EAE84EB0AAAB0584A413088622CD9BA87468244C4248FC50127CE87B2016DA3C883993A16BE50E4F1639F0669EAA9DBD5B396465FA174EDC3795AB341CC27DC61E21BD724564E6AE371619F8684499E02AB62F81A5379877EDE16267C974CEB7359E4F0D951FF9FD551279899E3D88113E5F9E7CE9B3090B1AAD78C59964D9CCF80AA77E2B31BA06C8987639DC79BD927DD45DD883315696D5C67304B48C71FC7B4CF39F22F5CD3B36605111109057A1E040FE401920A237DC12EEC2B3DF5A906865F4A74A8581FC4C1CA0CA38E4C6242E5B07ED99DC57C47719F6427ED8B2AA53327D49F7E54D1155D9623053CC638A2526803EE6CE115309130DEE2A8C18925976C956AE5878B7EB82C5FC9B802A43F82E4E9019FBC644EB80209767D6D13D4AA3A6F4CF95142830B8A483E2CF474BF63421FCF9BF44F7D9FAD4F0C2C0A78B4B45AB3735D1EE0BDAE8201F2C3E40088942C20426057B4711E3A4E0CF672D52524BF283AACA49649B1F2501A155592C7FE39CE1912A1085D5709B38DFEE74EB7A8A48C1EC7D21FF37B8C6EA209D6534B6328F1A99A1AD3198894C807E4AC30F6F85E4D472EC7D58111F71037248CD833B929DF928B6A0C645578621E262A8535B4D6232E30F6A591577AFBC2CA4AFF9C6E9AEA99527E285777763D7DE120C62C37A605B02A45CC96FDD211C2E5D00719BC8061D295F060E7D85E5D09E11B959B13EC3049EEF03B479A21C4A5984EB75780A26ACD84405C1DD3ACB9CE822E7822836802B4CBF68918C213A513F41E5BFEDF1" - }, - { - "tcId": 65, - "deferred": false, - "seed": "F53C24BA9D2E6C4C35249377D1F653B2E8F7ED655292EAAA86A5720F46A9FAF6", - "pk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753E55B13A23955D57A3FA27210CEAA2089B6B046CACD2F629C3A5B63E705F8FCFBA3D06DCEC47E3F643BD5FC5CB09E1630B5B00E28F84A8FC47D224F0F1A70FE496B0B75C234FAF16A386600CBFFB3177664915A7D1F5CE3FB7EA7A6771563CB00ACD2304AFD0B6E479CB3E054E794D8A32D35AF3E0D7AF2151ACBB8D4259E756B60EE1950F18E0FB40A914E42C1C62845949ADA186A3210429B8C38CB97002FB160676A72DB53E333D32423ABBFD6476D0885D9773E8A910DF792C50272B609DB4F8352F5C8FAA0D9C5628134A068ACEFBFF1ABF7CD5BDDBEABFEF7961B62B82380F1B8DC0C5A35B31D46E99ED6D95802349E4A7D1421A5D1E92A7EED88BEA564D5C1F2BEF62549FAE3A0FD128A2D097BE3A0C07165AA67CF0BE37DD21F9A8E0CAAA03A5232DF6E989DCC85783C1018D40E2FF19FF47298E10EC513F6D3061EDA08E182C1F322FFDE8F177A8F8A9BC5CA7917443A971C0B1E2A1BC975383B70277E132D6A5790510DAE885CC68D1B663DF26DD885187CB87142B1FB39A3E772E7C3EE3469AA9287C0EF2D1D4E4E009926A7BC7AE64779A7B30B9DEDA83230E28D196650DFB24BA8B876438E1A3034407C3AA88118EF17BC9B429A737FF98A9F8F2FC7EE49921A298EC8AA9E53E68489E75AD9AE6C478883C163EB62C002EE44E255D229FFB8C8CF64226D5E63EE312BE2635BCC35E725D5DD9D89533ED5FEB70E9FD05D23A4180785003E8E10D1A1A2B4BC347BB38F5657C96F822CC87DD803AFBA9FB1573F769D6F22706447C3EC0417C4E4F965952712DDA63945DFCB36C9BE20FD17B03939473AA8AB3EFAF165777DA74FA4B43031C1E2C3AB64B58EAFFD7BBFAD33FD09AD64B7B1338B87E4DA87375A32F1CC0C8F6C47C4BD303DDB75ACC74854861B920DE39897C2F7006C88FB2A67DF694899D0B035F8FDB04D5F8F26C901679172BE20BE761BD6BBC48D0611B9CEBD5C678F03366BCCBA33C272280B0293ACD0AAE04D86922D4016F011D0A9E9E7CB9CE0C254A6AB7CDFD644DA87BC8D868F4974CE5F404D896DD823CD44C60AE112CE6049757F0FC1BB427298D5C5183ECBBF4933A6DA01E1439B23729FAC858D12CBF2488BFB206B5169A0CC5869E18A2A4F00109643DC1898BE04DFD97A2C3B03B72925230FC5C56DEB6B1B9427ADC8F35F76CA0442BE4990803FBF2CB7277AAA475CC781F5B55B582F8AA5EF20C35D678FADE39B266D490B88481E9B7DC2400C33A4078A57B0E64A177E8275FD1ABCCBC7A7737644335B70A92EBB7126D1621143753C62473F19AC1F6C2E3EFCC90DD8353A61C1A459EBA92888100327D7D15CA5014BEE26E1899102052E39FA36E0397751859AF2742D2092D8547CFAA72A855208844C1CFF732DB881EBD9DA1A3BA485FD88C7756BD6C60A318B3B307BC6CF86BA321C67575D9521DFFF1334C630CD0FF87E9A317E0DFF3608680A16B35A67630ABE437F808E9F3D495DAEB8561F98F6E24A27C32DE6F3908A8BE72DB5BDEDD48E4C4B66F59FECB678689CB30BBD139C76EDEC7AB02FE746DD3D7F1FB180A5AA401B4E5291DC41DDB07F3035B9206AFFE0154081F22C8B9B1D33005C31C4070ABA946B4E85B2CE3D0ABA48E3B1F0944BE97080A6B0FD28B24686535E5F38FD90F11B7B6432E8DCF0C9F2728A8257E47A357CC24B4CD19F5570EC45BFD58FBB078382EE8824C181C8ABE78F1F16B39425600C5253F46A07B9D14F7D4E8B3C762AE9A38923DD422482733D25EC63B07880C51B602849B75D8C2C6DFDB81ADE1360C3A977419FF87B6249AFD11CD6FBF4C6EE7CEB3F82FEE038D313BFD07ADDA2888E7FCE44E7D382FE484DD1FCDB3247C9548D06043A0050B6370382FA972B80984B7E0DD2D096AE1D7C50307091E7A2B647E1136ADD0F75DE7596A7BD3DED6DD24E0A5017B5E875983AF1764D046DA4241CC678FABB2457C271212194F970434D893924FF3F4C41A4E58EF2BEFAABC1C264AE028197EFE52CFED818515A380D52C68EDDC680AC71D0855C024CDF4995E30B90DC161F28627694A0E010AC5480CEBFD281403AEA84C8286ED36315412924E1DBCBF220EABED8C0740F15588F072560E68B282644A023C817CC329EA436CB1257B7667C1AF8BE26B467DFE45CF68DCE933379928C6FC832E731D25B9D66AF5659FE701DC66B4EADE812F3C907E140EC23C5C06A707377749C0E448B7E4A6BE686EF9E07D7B313505A5E5235F4857E085583500C1CD83AD311668DF5D969703CF866875B74621279F5E1A9D940EDAD8063E6ACF290CF6418C3544ED1C1E9CBEA386FCE8D93690499FCD13D8FC53A6522BDE20B1E87BBF9FCA5E2B56D9E5B6D0AAC167BA43FCAFBCB5C65D3992526596ADFC708F9AE5D37F7567F60F7DB56BF23A0C3246C8E00C856D4912A0C9FE2314AACEC37EFBA21B4BF6CF684B1E06DC447C1D1C86B14DE72EF7EBA190F5D3B957A8666BE27712867443E78C194557D2BFABF475498C9AF9D5892BD7AC30E8A08660DF8203CE47E59A083ABA27C1635146D376472F663F2552FEF0F8BC36D7E63524AF82C985AB73AD44B269D3C19A12440578E55B3A10BA641CF1B9D6136540DB65B0A6CFC6D0466CF3C3736226845BB8A5788DF4AB4A96CBCE8F407D5D22D9F74C2F31644EC31498929E119D33316FE73EAC7B1441048A950F3E2B41334D79707D55114B4F5A6DF9FA6D2C699C3F6654EBB518CA8004F1DAB63CB356270ECD50BE3BC2F8452D91E3E241145EBD6F0D14E7BF95CE3B3DBB397877BEB356683BCC22F51767A1CA35436EAA5B8BF5B2BC14D5460AE1B9B6C8D9020D07C683AEE4AFBAD19E7340592AEEF4D61D17CB79288B958F2BC5FCF03C25E0FD2E5D0689F9F7D60E7D86779FD0EDC0F832F6009DC47910EFF56829C49264766854A33B10E3D5C18792D93529FA952B140EC72A876892031E1F927B30010E57FB56E2705ACC3EDEA9F98352F618B1E0E1F87CCD544FC76032B9740A1731E85E7B2348E688F8F548277B43B3A1F2071109A8FDD5B763C4110F2ED8734525D0151D6BA64C13AAB2192DBA00A1A26BF1AACF18AE3B1937EEAFBB50D7E3B730FFBC6F416DB7E47C6542891333652024A9B624F4765E7606B01A23210399D118EFF5E4EBF8DCA44CFC6CE37F83CA8F1EB2B22231DE01428C0F1CC73FBBC55A56F29C44CFC0E496481E2B2A0F5552CFFB4A275819769FBA6F1E3C15201DF78E58F993052B9831B71B70B9C2AE265B68B8FE8BDA95C0048DC0D3523A45CD5EB90463C0A2CEDC2CB20EEA3D84B814B5E5C7C5CD9ADA8B4DA4C07511A339323C30BFFD7DE9E0AE0D596B638F41DD47DFCFCF9424C41EF2D11A7A86293F0285BA6E9BE442D1C38BE1DEB2260F6457FDFC57B5EA8EE0A215A954D8D366C04818AC1DCCD367BBCEEA01553092711E9B6C2423513E4E5A15F497685FD22F02E40EEFDB890298ADC4F1A4137415F8DC0D7036CA2A8A9EBE2C1193C8DAFB209EAABF8E9B479E4F8487465450C4423665C51BBD51BA8E38F3DFB144D59A7D2339CB5E5E837695AAD09081F80524D77947982FDD5F9B3CB2605F3BAD6E9C1B4F21DDCBF9895BE62F46E8B3415786CEA7D7DADB9E48BDDA35C459A5E1", - "sk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753ED54505441C3C70B3B7D89DAB317BA68655A52A93FAD9A042184C3ADA17DD2F4AAA36AB503D0F81ADC4DE1DE655304A8F14F5EB687DAC6325539D906C83FEA1EB81F82D91C3387AE16815E04696C47BDC3CA909F33C18723AD614C12A206C10D31C350E8B8805C912721C8504012184090552441210A092112412309C1066E4C6400B234CA2C2841A2191D142244396848016095CA65021946823217109410A1C49854348909818488CA021A44882CCC86504284621A4052383519A062E02364919112A988290A1240C420610E43651CC366EE3862C21B18419230E09398848942D54242CD1A04581A8248B448C0B950408354C0142104800409B12521947241420281A134D4414525BB06412207249102559368A500412020205814608D9C8288AB2649CB20449948D482691593252C0A6841A468618997010224A9AC429E1866C22170D14A844CB06625C466D1A054043360E0A278891409111862D4C44005CC268C2228D49460D181970604431D0C84D62B8900940061BA42500922504B100024291A420521319449C0200E3824808060081268EA0C828C2301049126224A5902192249180518104301B025144800801264219C94440B6049B269220A0611B139000222988B8300308021947301085410CA9301C24062490500B2769C9203163466C5000288B0452DA28411AC2051A9744D28660A3326982328EE3B6288C828060B22190326263408803424202882082B684A0C050138040A2A6806242200434468C2841119808D428709A469004426E01900D92B08083320A0A3240D3106221C360A43202D01232039521182206D3362463A229083420242486210084D9880D4AC601232045D3323210C210242362532062A4324C8BA0681448465248416098480B10854C882808854101224E49C421CA086A12B67002B265A0A88C5B202D01048ED8A28403460400C10941A66083C4501B200418460420276A5036111A956162888CD9A08523C70090C48D59864109220E11868C14824450A8248C220A60B09012244D53C01140B650A0A24D0BA28192106C00311042A65143026211150DA4B689248944A02084A1980DCA4648D8482509B9089A466DC8428DC89608D0886CC0104D9B466DD1B0240CB80D821486C1047243A46853840453C8608292009910284A120DC4028CCC321108899113B30542006AA0C2208330629A864CA446501C4232E22025C3242548922D91360688A86C60484AD8246919946902B1614B8205590268C1B22C1B931023150481C68D5A260DDA2244821086E41400A3B80553346562B62111C90888A2481A364EC44410D210825318128B2829A0340609424E8B164949920C9A92449A06284A180A980045E1C450A4384891C63024B96C91207049248C61802D23A331D3326113244948344D4C261021A124CA14280C1012103066948004C11848A1868109926D93469021156AA3A4100038851A99901A089219008923C1912430518CB600131921E3906D4322624BC04C51466A1A014A2034894942641839121CB291E4306A5A08861A05611A82414BA48D0A0281CB86904A2686D83841CA080A1B09059A9631E022829C308D08054A832685CCA6045338891BB06021B00418001223A921CA204EC0000890028C8B063140A8459136080C23840AC691CAB64412134500A42D21945111422519445053C425C20260D83001C99084C2224A0401011CA20CE00244DA0629E18469532086A4886D0382502288018A1200C9B07194040558B60D19442C4C9689E13865533602C4A24824122D19888850460C1819881036480A001193286408968082A04013372A20220282B26DDA3866E4442604B800D230620B0649C948728CB251E2406E03B58D0A02044184011A9980202571DA9291A0B67098B08C99C24DC8925009457011C444644026513880D48011D2B061E128660024915A00896086450B431102C084C3288102252911B24D842005A49669C0B4250AB56821904024156611C40964C0845C308913458143145013406D61C885D1A06490462DE010881C9824441010194221D802711AA65053084AC1966C8C228910236862086A13C43051B06C99104D022601183781D8109023868420272EA3B424C0340940048E40B685A486640C3344D0228D0CC10915C8D6BA68F9FD41BCC8679EC985AB5D74557F6F6D035539B339C408F2C24981BD5C4FD018955077A79C3FD94EEB1220DE199AB168B00F2EE837275D9CC54ACEBEB0613C81004681574F9943AE9850AEC08A1EDB44859E22D383A7DCDF3811ADBE6FCB0C896483F61AFBE41EE57E253EB9A42EDD4740192CF21B0708E94054CB14392E4157A5A88EB7930C7B104A6C348B028CDA9ACB2E2EF34BF66240D4B21F57E759A45EF39B60B19F7C1F9851251A46C13B973AD63EA39117CB223BC943A56D12E792233DAF0729AE2A58C56917359D2A6712A0063E87A8D424D28E2C0E3E4593A0A8DE46580DE0F74FF9B05453A34871581784160949C9AC9ACA19E18EB3143889EBFE0A2379194F8CA251AA26BF3750BB69703BF138A7FB44D4A19251FA9EA697927EB8621513E1753B10A1EC869EB486036EA73B0978FCA3017F933F027AE44461324D989F47E64B7AF616C89EDB7DBE101EB6EDB517B4F342A6FA89C3813DF0F51DF5522667425C694E6B2B872CF884B31706AA8C2B24FD6BEBDB2022C86660C7300EFDD92BCC2AF803B5D77A257000957217486444E016379DFDE75DA83DEE46B84B1F86F43B02BB0B22F46F1540F10B8C465C4412618EB64AC8235DFC7F695D22B0B7B3AB557DBAE7D5AF0DF012E595215E2A1418E7145F357BF57413DF34FD078E639B52963258113A3C560C90BBFF7BBE70E3B5589220E211A6CA8045C9571437CC9B3C24DFB14B48695E2053B88B1FF2B7ACFE1880B4D336BBFA6734747C2A6B7C460D24C3E6219A2B0AF769F794B7F239A4CA0936162903CB0DA57072466E610480BF09CC57D8ACA4A1CE8AF298D2E42AF44E380D94190E20A61BDA4CDB1E123A03DAC37A73F89B843FEDA27EE7EACBD49EE30E74A25A49D93A1972A237C95E1D8F4243BFBDBB0F9C50E03C16B37B01FAB3D0DD3BFBE2CF3CFAAEF7295BE80B120958946E02461EFCBBE668AE52DB638A7ED808B6778AD7D11EE66A705F32E232D39A0B9D73AD33AEC4799C791B7033C5949295A3AE385F7075943136685BFD59F9F1F1DC61026ACC54E65661DE4DC996B53CB612370833037A15D746880FB78CBE5BF2519280E7308C15009E0D6313D43A8DE343B51BE5C5D736CCD71C536FFF1B2BE1CBB8F4F873B580A9165A78B617C845FEB074F86A2C666CFBCA2C5582F99B7E5B2E11B7FF253D33151D02DBD056A06CAB4B43345A0CFFC2B8852D837216C36B6E9BD5307EC23DAE29719A896FEDC2A2196B426AC19667F562C3D2D97497FCC78FD50449AB975A8D65CF3F143963D4DD7B296F06113CF2E91A9054AEE8BE010E76B33B8864FF0748931577F53640207C6D335BC928080A3FDD2C0F8823FE89C53F7BD5C468DB531260D9DAED51091A5B8070B884C1DFDDAD50AB49ED6E6EA101339FC9A528D95D5AD49D8975756A3A4518D7DA8E3262CB1BE9B8533FB9FE16CA796AB247405727FB32182FA127A659CB40C810861CB048E6EE8442D6D3E9D8767B559C9180533FE3E86813707139DA97CE17457851BEA7DDAA2A32836922D29FAD031E7C9B1F9CF42621D2FC6FC785ED1585A13BB5AB8F2D119BC0A6381E29241E8B54F28479F17CC84E778AF97DC779BFB14DCF22CEB3FF7992BA5CAA89A3171A7D766178B75F66F12B6107E046F5FCC977BAEA650D6FF52DF4B2BAB3EA66BC560075A09CD8FE7081039D97F63C3FF478771747879CB4A4EC68807B4A7B70A21811C59CFA0332349F1A490BC727C4319B8004D40864C82BA3CD5C0788DBD9D7918C9309A70121B7854A4401FF8F283809C6647FE5E1C125569D537B50232E29E13BD97ABC77C083627813983F0CD96C3E79523298C872B19AD6FBA2A7754F89B8B64864FB798C80263B9138F1508157C37344137B87F3B996649D954A8BBE42A7D161E1474BEC1BEBB09AA11955D3447DA3101924DB9D0A2C499A579B140F5346C45F9BB621D78C95450FC70F245A65BA12D42AF7DAC59DB5C637D0DC8FD262D1D07BBEF45289552FC3BC2E9454BB5B3094AA778DEF3ED14175A8AAF783C115760B36D1F7AFF8FE083EDEB2495CFD65E1E363532215779DA1DED3996365B76E183E824E46DEA3D8D5CDBEEFEF60588EBB7B9E16E3B2D36EC34B463639C96200A34B5A8D31FF36661CF5E1D5E5F940EBE6012466A1842DADD06E1CD2987E0EBC10CBB7EB0AEDC00E93CA0DA7EB1E856C11BE2D6213113E3B5D52B7D5573BB8510EF41A71869A3B63A419492557EEA47E33FD67EEF605D0A77C05801B453D7765EBE207CE58FEDA0ACB4F7EF1E55E2A30C5560B1E22313B8ACEFB9BB15700CE1F60F99C87AB22269746B11EE963123E98071FEA8E5F0D28A5B960C62BC86B6A34DB2D21C82FE86473D2CF319C385B30283443486EB78CC6F6FCB70AA31988A4F6F328F83E862E1FC9DECE5D674689222C8B180CDF1D87A454C92F3DCAD346BA6FFCF56C70182EB2094BA136E4557920051AB41638277EDB2010AC169CC7AD6C326B8E73176A2D2904AE9F480A3FEC9A44F1A6552E78501F2B29D078D52F82EB54E2862D0CDFA0C5D13F166472EF24303899048911FFC3A736D45EB9202A18868999C0DB5653765A5E13801932753C3ACBA638C700B53FCB4CD1097D7D60C243F60232626F8FAB697ACF0E14158DA4C622DB29D52AE0E67F2EC9D1934C09DA91AC92205FAA39C08AB2CA18D5DD411B4451BEAB2A0A7433B7216C443904C157DA05B360265CC1DD8DD396DF03D47AEBC3CCE621CE5C0A55D128362719B1451B1246AFE01F548CC041F233A7E048AFE518C6BB90368FDF0562BCCB228A3E7315BBD1052BB42526DC233B9683955A13EFDEF5C16F18ABA2F6E073E9B1C77A60614CD39319E70D0F15F677D21AA806A68127BDFEBC6054CD6A46E12EF046DACA347E3B490DDB5F905AB786321CB587C771AD65BD4DF0C763E0E5950BB45F494D131F0F9F713E7DE8A1A38C6B0A41196CB8A5A2194E54284E295827485F79FF3D6AD5175373F09B1C9149B202FB0F4698672BA956A9342793C201B16E5BBED7B9FB67548335EBF045CB6A7D0C1CDBE524B79B6CC94EF46191FB43031AA212210EAD6184BA77883AB9DE9816D133D39D9E78CCC4927F647C703681961E26AC75293328C8C309ED3C4E1736FE30255944427E84979708D58432ECA8E6A4AFB1A2B6E49B5FDFBB03B4892909CD5272783330EDFD4FA333CD931925BBE58D2BD91DAFD8F78CC458BD2F4DEAACFD08E1B3B2BDDB6BB2AA1838BC18088E860473FD3DBB337FEB1E4B473ADC1CF470CF3E6C37B80814A1250A3A49E27B4E8BF39DE69DE5B15460347963C6ED8777BD9FF2D10CB4B5AB5C359165D8D5D32B98956C0B357BC4AD66D44F6F806EAD2C983FF682605EC53137CF7EB4F9962B2CD012025C25F7E1DDCA033237AF3F00B773130458BCF37541B140E6E61AB7EABB9596758DE62C089326AD8DC30A3BBA2DA22AB72DE3220934E10AA0DC70E7EE1F2876BB8A368ADC58F820839982BDBC1BFDF8C1DEF02F1602918D6DF4360FD8D2F3FEC610373271924296D666BAA4C90811D85E8BF06DF9583B42D77AF82BE9ADC7C6326A95E4B865A1586BC5C6BAB186F3C9247F5E8D9FE965A80D50EEC366D10059E0C1D8D6CAD7C4843263B3337A75748A9CE4595C433B3021DFFDF31E45D87AF5025A9D1084943A74F2E3794F0FF83729EE840ABA02D0EDF2E79F5897D177607EA587DB4F24A6E0C4751C8316809EEBE26527B94F25DFC7F6B8B54F4E9F5F296915BF2A8ACB20D8DB55C7B2F852019202EABE8EFFF3BD09F303A321F6C77F784637B82CC850C41028BF4D016020EDFC4F2038AF41C8EF4A22684C38338386B1B8F825A6038033AAC64D17D1EFCC3C739056E4DC66744F883616A5A24BB18AB58990617B9362F2D06CBAC7D4DFA2A728EF2388815782FDCCBA7D3AC321FE53E52B7DDFB3034C4FAC11824D823508793424A610A5462844818C928E8899F0A33E3A5C2C0E666E02E04B4FF1F7481F7BF2977072AEF7A3CD28706898007F7E3F65844128BD753873FFA555BAC0B0D04DB052BFC7825BBBE7E17EC92DDB203AE71BF85349F26194506D95F2EF54E1C6B007ED5D784BAE91B4B3AB4AEEF1933BC3E799D02F09944D20A066739B91C3018BF9BE763195BF5D934567D1F2CD6A4F639296574B06E0FD867D93DD1D7BE642A8E3A06187619240DE0AFD0681AA84E517EC1C74CFD9B3603BF8EE427D0E0B67D365C2E8E20717FD02F4ADFF1E4AE5DB91BF73D691AE1C3C4379C08B58172CAD372FA57D7BEE1CD37330B602744A793158EB421EC88B574B5AA3A64FC21B482D562648603E2067D136DBE20993A2B21F2F163A53EFCF19DDA105D9A24AFA4C916565DB7D5B462F0B48025A4FF8A7851555DA65DE6CB4D57C4AE1E786EA621870E9A6A2B37E09BDFB7CD29104D4BE15D71251E2A2032CFDFB67DA87EF99C23D4699D9804852B5F0793043AB691085A35CF4C8E93CA53E59CA4898B2005FDE559B7F5E7DAF6ACA3FFA45369373ECB89E3678AAC8E7F49F23A0EF032570D93BD21ED5F09F6CE77C21D5FE74796DEBC64CBCD156F27AB394BDED0F330757B4225A4A3074B65D4DC89027BC441EB6BB08D3C299D58CECDB15992D849C583EE935E34711833D35C8B57CEFFF60D84A8977415DCFE05D66D982529B95D5B13B18AE6FCAA86C75CB1CBB207A3210E683F1F50BFF5D" - }, - { - "tcId": 66, - "deferred": false, - "seed": "C8D0778FC6359E5FA663FC32E9DD1E53F26671B46C7750DC50CE69617A36D2E1", - "pk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B964397B289F9D4641D75BED239638D5292DD04BB9A264A8A9DDA6C256589EA35BBFD41C3E4DCDDBA3963BDD7DAD6E7D7701A6EF8D79A12239CC77EF52BA01D236C9ED0A09E26729988F7AA137FABD14EB0B24BA5D900628830115913FD55EBEBB1D4BB3286D9D0C9141481D3700959D415E3F1DBB222F968BF66DF0DD0239FCF22DF99D4A90F4464CD25D31A5A34DFC5B7BD06A2A7EB7A6317EBD6275003DBCC5803C13C461D98C7E2F8032051ABB67FAD382429F050E7C7662FD2287CC5C90AC807B1E3CB48B40FDBF2A2849F72887FA28F8890890B93D9F8747BB3D12A5EA03ED29CEBB36C49560626112A6F91A7451F13DB5B3F199043C9EE3CC29F2A359C87D457E87EADA7C16ED28A38ECD7A9B3E8DCA5222828A5BA5ACE01D80D416DDA5A86A6C6D765A3F699FC403583B89BA0D246C63B059C8F438EC00F6832B977A6E6075BD147E11FCA34026D6BA629D6848E80740B9972C695B183C836AC198AC8242DD6E1C2AFFA7414ED108768F210EDD47CA00CB37F77B725E53A0AE784145CBB4EFD62C92B69CA844B577DA4C4191EDCA87433C8A58169EE98CCF5BECD03106AB77B161D8D2D57D2953E6DB40172C52634C6BE81BFC10F10F0756D2D5879C25425644AC52B9C3C2B6760A635E45BC8D7853597451B113123F61F15D2CC28E5435BCC2DCF4307D1CF8641F344AB3FE26AABA75D93719A061F86D62827E648213DA604CDED56F9112FA02BEF09A700D5BD96AD48A2E76C8F4E23B23AA103C878BD2EA6DDDFB99C9CDD359A0BDF3DC5867025B97573F9236F5ACBECC1781035B4D4BE20B8DB36200D988C4F8D25A9F12F103FAA96214D1BED02733867FC2660340E145FBAE0D7F1DA8F96B82379ED215EA99C27DD25BEFD851A8A24DBD1FAD992CB6DECB0D79BEB70AE4CCA034BF3AAB421534FA7EDD20F850187F58C7E74A6A9479F224DFD152DD7CD0E3FF8E0394F1C2162B7BBFC1884BF1ED6B30988525EEF1BA9B7F0DEB42F1FE9F8529BF4CDF8EAA0A8A7F73FD682195646C89B47409A164D16F18DD5020E1039ED264B25C3950F38E2185E387F1FCD736B34F8394900FE90FC706F89FE9066CE511A2ADA019C9CC96486B3F648DA4C162C4FC6573E01B4B5452AC528657B2CA570E7719AC5D22B461CB6722C8BF8D9AC15640AE7187873ADCDB5C529359C32FE3A0CEEE27243386AE644A18A14ACC3E583561A51393898147CA7BCB0B5A1BDD624888981BEDA682791D422A5B0408F7CFDA10849124A56C3831B12219D979D2945A6299756C14C019E04A27E88CCE860B55688161364A1D4C4AFBD8F2C68FB1E7E5E55E5BE50A47E3D5B9B3A034B9338B2B571184333518A19DFCF5958E5486BD2834D9055CEC1A1981637BDA2460E6F2737CD752B20D4AFD4C10A55B4C80C330F8A5B88A298C235A046CCBA61A276966D848AF1DF48F8DF3F732BA52980BC5E496CB0E61A92C20FE7BCD9E3F3D39478FE9FFEC11C970EDD761A4B704780B7A437854C318192FC4BF602DD384BDFF3DAD78CA56F32246B5183D267F21E5594398854CA3CF56C472FAD2B33DD4D303BF14B0034466CD46AFA4C91636BBFF29BDAB9E6FA6DE92A5EBA2B53DCE92EC6CD55175756AD9DF520884439BED4D6DE233DEBE6DEEA790CC51AFB20AD228A6FE7105C534AF48BF943532316EBD8C7E3880B785614111A2129BB63DCAAC40A2E9F5F5196D56EFD7C977E3A3FE938F9F812BB5A404BF9CA0ED121E92A3AD145480C31FC408A363B1C8A578F0CC03896A298BA5A2A2BC1CB04B9B6402301346AED5D431CDECF7D3D1B6749A63468767AA5A463955BF04717DC35DD63EFAF6D6F5212A744E21F4E68D807910A8B2F4EBE90399CC91B85914E8C4FB95FBDC3FDD3E448C2A9E6664BB2A1EB9D5006F4CF8EA5C8A1785EEEFC46B7C18687A36BE0B8044989EA24D034FAF9FAC8AD1903DADB16AFB6E695802825F40125E87A51DE61E63E123B838D512A821BC6534B7D6D8EE300ED51D051B2F3E5B564973B92F961D296510BC9FCB907C024191CD652B22CABE1E6EACE1E38E5C9A4B88548B1D3187F4B3C9E2504F828E10ABFC2468727B90F018FC3EEC69B11AB8752CD7B79A233CAE01E5DF47D4E696FF2C6019A754CCB5821EB0B2071D8C09A15C7539159A46CE7424F7B32D37D24697382124DE0489C891C27B0EB27BEE7CEB43577B0B19637BB1C21837936C7E721BA0718A2F855473A8626B61722B1A254731269B906A67CE68228E9DD38F8EA09733914F8D748E909999F2E38C50308DB6217B5178B51B0786C8FAF468FA9973770984200DF7F7C798DEFD00D207FD646EEB833D1F58697ACE409D5F238B2EF191F4E4D307BBC7D563E26EEFFEAFF72EC348624D4BEF5ECAEBB72166FCD28C66A78127DBC5FCC0953F402C88BC18213D50CC5A39C309445ADD6420D9048EB7897B061570DC94C10D985568A427BA55CE067BF120328EF29C2D07C21D1D14E2D26690A55F52805C561F48AB496EF194FFD957D4F1247D73D47DD839B4C58E87966589B88ED55136B43489E038FB0466B812F810426722D3F27B3636F17EB97601A4090F9A6ABA3C771FCC8273749DB6FD1CBB34BB0526417EDF0D0532DAD39A4D42B974A1D6683C1DEBD68CA87074257DF68BFD763CFE0324B6DF92B7A9E6984776C4994B8E0B9485C869B2BF65C7CF35427A929F7A9309BDB64655A5F03B69090296F172530DF9E9E3B40FFD133138901FB70B446BD868CC97104C63A08BBDECDAE86FFB6A5FAE67AD1C9CD907D99F1D64F74B117699AEACF58B191D1B882911A0AEE60EAE4AD5DAFA80D7E69D470A69961544573339665D0309C1B6320633CE6B8B9C7470E7B7299EF8C30082BFE9D917F44978E366A6C69C67021E1C77DFCABA356F322689A73A5F18EBBFDC484F1A319854915D1B4BB34841411760B925BE2255F6CB2EF607BCE343E8BF8CE32BFFB7C6501A8CB2E300FBC7821A67C8869416BDBBA57EA4CC34C246ED9CC7BA00C929C53D830E23B6AE78C63FD01FE88897B68FCEE0EA0F43997C5937DFB070970FA8BEE130DE98E4746656EE7108D414C7380B7B16BE6B14128D5FABD602F58C308BBAEB3CAF0CC0A32304F95BA0716B9B86FE2FE8CA47019D187157290D2BC7EB024354EA3085CC9AA3CD5093474A03122E224FA85563A7A0311D6F6D52997388E582C92872A02F8236D3E3B7AD23886EBA538A9D6F4C044EEE43342CDD983537E1EE4AA695FEB706D00C267DC96BD0B58380B88F72950C006ADD3DF8E6AF886334128B8F36DCBB214151FD44C5E9093C0FEBF90E2150CB14ED76AB66E39CFF756248D57B8273070D0AB53A53E812910B5F4AE28CB7B0EC687878F0338177C472C387FDB5A5434DC97417108494C192C5A2B9C81795AB648C8C5301A356A721F3C8394441C24E415809C5C913CE55654CE957C5EDB311F386C09813042DEA14CC634886603B34B9F5C88A6F6B22F2047A29FEC04355BCB8DF6375598F0654D35F18A07426FA7FBE1BDEE98CE84B977F1915BD48F79C50296A88AC76D8DE9D8848495773D8F2C5356F053EE297E649AEE43B01F684E6131D0DDA5F016D7115D0625F4E26CFBDD0EEE09810976FC3B3BC93E0DAD1F", - "sk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B9643407C924EAB89568C8759675DCA08CC7B483734454E675D5624D163386CF511D6866D58601579DFBC2962D0DB3061381D276F0C11231DC2F231A8EC570699F8AD3305A0C0311D4AAB7EC90E8A9760235B08673DCCDA8A2DFAA85B4B7B14C8038F0C00841B4942D026466334910CC94191488A80003081346892820008432E081288C4122D0B423099064CCC1210C14211D022261B97601A8028C0086D20B16464161204232E18834122B3048A840102276149820812A76CE4C025D0144E8C38218A168A48C841018964CC283101C529A1968159220D20887124385023B14DE0828019A0850A924DA10828122586D8826019824CC2842801C86811092C08438453106C14198A01C9640036464C280ADA466AC320855846051322610A00729C306482B451D3264D43140D8C3444142041CCB649D420298116118806251C2849C09421DBA240C482810C492CC9A685210444D2869160C66412866C00164D10C608531884441631DA280C53202023C22CC0984010826D9324089B368E044042A1C884D41665CB482804178D11120163A2519C488E9C408C63209008446062207149380A2384118B34491412411A091098C22CDCA6310342219B465263240C110190D0885099C20112B82CCC3009CA948D22C18C61240C090171D8344694B62D63860D13B789D9369218128264C40843249160282C98B04984066122A23192408D22B22D18C624622091130290A1A200480470A1868008109022363111C84CE0B60509458E83282E60482E0C403102A1645B4049240921C49031C2466490B86C92A861D922516430911C37920AC944641264E32888602485532844A3280103C00863184CD34090121229983070124888DC424E5B8620A3A84C40280D10058899A268A0B06513B904D3C68911335009026D4AC8300C429144106002B32164B230E2A2450B259010A911A494091442604AC80D0C22710B3191E0322013B86D4AC40C04C57154969161949108B82014213204004D0A4126E1068541A0709B1091A31032C8146859B248530290D89824082646D2144C42A005A3B2501C806C80B828CCA825D1C42C113044CA02490228100A484D91B670D33869214710DAB8489AA83018428804C965644872111582184188A4206110412C00821020226A23C5841A336A10A0419A148110484E013980C3862D91468480108D41262A52B40881000ACC38518CA8210982709AB251C1C241D0A2890BB06824A04919B865A02622CA34900C392E0C496E54142181C04C183129624442093032121384DB946D80148911414454C0009A482194947041488413B66443B2605248265CB03058282DC83444044400E3960CD38000C4B804E13026411865CC282AD4B288182040D4A8408B449143C285024191C9908593209123A28C40146801472DCC986541989194B6705044005110621B328E1021321225459302815300511C374810A5010032258C448C23B28954A6800A2941CB82450A23259322110AA151A4841014C2491882840B272E0B2992E4A428DCA06C5C186CA2484414C38041022014C46499966508026EE106304C984810326292482064162C10308610946C22484D21056A8B382A5C80880AC990C3222C09028E8B9230E200264842801C291210123209A02019204C190280204322E12086CB128A58120598264A08278C1C25818A281109894DE430250B4011E1C46C404860584251C3B42CD81622513806244904C23811D3282DE12400014801D0100603962451B8614C886D03A844D1B26C2420519BA641A214921419820B27858342520C804599082E40827062C42113A020882631244621C82848190268D048496382849B90045B08211430664488245C103080420963126612252D43B08C519641D12884A49671894820D4A010431402140805A0960D13B98004A68D1CA5408C48425A98490B494DC426308C864C9B8884C3002250066A43A2849A0892C2226D02384C02C03019A9251BB26541C001DBB810E284240A17200190904B9204082945901222D9366559A2818CB42119B7284A06411C133004128EDC2671D03842DB384D0836660AC210CA402A4204041A202CDA404282B46DA23042A0480293488012137061B265D33041DAB4644CB681CA0201D4223283A871C1862909337172F739B7890830723B9ADBC0CD918254BC4E2C6DDD7B63BE13F32F5DEDEA0CA7D38F05DFABBCBFA3924BFA10E921255B06FA33050F311A3A12B3107CCF4CC7A9F12B62F93B668B3E7AD97B456C993CA037D5B71E8DA18B406C5DAC22E5A1678834B647276EC041C68BB17D997C729D27D049896211CCCC79EAF8A0E47C7CFCB081FA414A3645C0279EF465738A3CAC519FC72C918298B2F9005B740F89D7142AD3437C54C67A379B7BC9BCC513B3BC99B1F358089E711CA4F988BC5332BD98B1FDC95F44D124A5AEC8AAF99700B67BAF5F76B33859EB52F4B474E8991BAFAA566070F2B5329BFD634E718E5F99522493F43D61093D86F0A0EEFA2141549146196F9D05C778C8BA7DE2E27E9ED31AD1CCD1C6FAB2FE999D22A51BAC9E3FFD876D76540E421EF893FD4207B55D7CE9B4E67B930F02B972918886039688BB9790A5AA82112E86D4F5E6C5E50147938723914FE7D5D57327990B53655CAEBEBA41C849ADD5E6C08A6E0BCB03BB4001FD71244F8DFD440D6A2E39F32C9CC41A0A9DE17BCB4FA90E9D038E3036FE1BDD38B83477C581D32F017C4AC0182186D1391138423EEE405B7E263A62E793B09B78EEAB7723CBE9B16006F87432AF2684612E79D045A03E5E2EA748E03D09E9D14DFDDB182B175E10F8072019928B37A05B2BFE9E041BDF35D4A8EBE5D14272F928FB458A6A6360090BC3503EBCAD26F2E513CB751AA3726719DFEB146458C0ABE1CE896F27DCD6788BAB2B8EC39FEC0E24AA4B87FAD919125B1B90F1A247C7841B101B9D8532FDBCB3B4CAC0FC30403083FA67754E2E53F204A37E6E59A03FAC21EEF88930D36C3A88005E30BD2150EB22D90A46F6F1F17738243F26C893ECC437876B20AC447702BEF884CE00A916811A0B690E65124C4A90E8BE4FC064A2A7363F51F0D497F6F48D2BDAEFD43DA3E8BBE1FEE6B81482FC121475642580A6BE74D274EEB1010C1021D3CB9F887A0F9163292D80067FFC3EA45DF606AD2734D4FBD2A7BC94577584A000C144C5D7095A261A4A5743701F284271EFC1B836EBAA9020A315B941F70B8F8BA8DB2F7E326A9FBB60089B739EDB09637153AB4168DC958FA1FEA52DF8FCA1DEF7DBB2383CF402D2C535460EB45FF67BE55981BFD7D24691A2FC98B68E5450A610526A1EC6B5B65C7C7FA99999DC09B5A96A5DE21C1BC917D949D39B5682C4012057DAA773E2D5F0ACD9D2767A05D75300A83A55D8596E9B32EB372FADC58202003A1EC2EB483D41D4E48BDEB31BE9953D6A4323346A8F4A93E4045EE4D958C1CD1C4D81A77700A9822661E6FFE3FD2BFFA2AB8680176425F93BF2D6218F739A043287DAA557743078039D735EEAA2A664E30B1962A338437C24174719FC599A975417C54649548BCBC7E5BAB1F9E85F1C4D188E2E55C8A2C49EE24B6836402074ECFD06EB5E0BEF8E56DF71C2E916189B8CA9EB037B75CC193A11C37D94A22797D37056B2CFBDA7D9C6868A0C1880CCEC923B2408C122B567CD8CF49312382FC6B20DFD1A382BB624BDBCB8311E1CFE4BDCD93F148B81AED26D1A4C121551F1C3C6DA706235546CC019CA9DBFE4AB857EA45797DAD8F41BFD753402D43172B7AFC4E39A500CE7D927301B30A0317046F44111AA38CCC9A0E331202B896CD70AE69E289893642FC318990D738EDBD0240E648D5F470C81E3F6CF6664A8DD271242FDA885502C78A38CF3C7DC2FF99B658D57C8E840FEACCE406FBA15C21DE8BA1BFD9F8E50CCFC2225562ECB7CD5F4735136D2BF4CF2122C3F395B4458FC82661927D911F7D91B4CAF2A7D9B772E8AB7FD499E11551082E604F9D90E46E242FFFC5814F164E83307ABADF982BF97BF8504902D78C0FCAA889CF85B15B4E973636CDD92CE8E9FF5E7C6AD98DBF171ED629506B851B9915EC32019E8FD1AD6D7E1B31882761309EB5D44CDD89BD7BED85777AA4BA1DAB9021EDD72B6C7E428A80AD736F3EBC2494F6E3B3222A0BB32982234154BE0DC90FBE1CC576704803D9B8E91AB3E6A7E74CB94F2BF6A708E7D1BCBB24EE4F654A49FA6BA0DFB473E6594991D71942CED454B0E456147CB713EA500788EBB4D1B64F408D508617160B0ACC39FE2693D3CF16DD6BB88FC99D2A0BA06D70A9D66FB50862E768B42182BCC8F770510278CD7037BC26C5C9F04C560C004C0735718AEECDD15C1609D2BDADC6B57AAB41D573FEE8AA42E6D47F0CB63E86E276AC802D1C04FCA01A7D3B0E6C338C80FECD79B7D09910DCEA7CC993AB80EBA57DC66BD8946EDD4FA70BB4454E0938724FB2721EFF9C29F65B83B87AC0B3356E5F1BC96464A20A841B89235CCA15503FE324877A3658F00AF4BED8BD6A30149741D1580361A1460ADF64B576DE7700B2658F79462D1A0D83C2D74D5406B98F672AB9EC349AEE128FE8C3D7C7B95594FF538B4F1AC31634233BA2F319D9685D09F740C3B39B53C9ECC8F1440A66FA8DBC2BF47FC6FD4FA1BF49B157B234CC62275DCBD35A2518E752618A0E8FCF01E35C9914EA77497AEE217BE8D5560371015436304971AF556E0372616FFEEBA76F5816D33532773A67FBFAC503DC8D4BACCF893B035EC84FF7E57E2091B39817C4DC8FF77EA9207D6962A893BF36B28BE6B40C6F9DC4092535947F8CD4E0A39113E6331378CEA0C5B2A684349FBCCEB4010F9CA25360FE555B576B919DC2E50E6EFEAA97197FCCB491138B0EE6AD3A03570D3B22BD6C849969683D05BEBB536F91E6FA6519129E47A5D4DD32ECF8E33C78ACB6E2DFC8EC749641D21420CAEC7F173F8DE363A359BD30EB99518BF4190BDB75F6D7A736ED3A37264AEE6D3B44F01D9858E5DE5B38249A84E1E97FE9FF19D1717ECBFB05D75A427C1A05FF3C25E7DE9D41ECDF4A20BC63FF578C1C2803FD9914EB08F8D401BFB67CFFC1BA97AAD168E014D3280336075A1EB18086223DAFC81C45E1F8AFC071908317660348376C7E73445A165F601801B854109C648146439DF89ED4D50178E1E540779DC1F09E5446DF5E63C4B6506DF371772F055EEE761E20984F8E4C2336F82EFDC17BAF6D65450A695C9E35E3001B6620AE8B599FD276B2A6E72DBBD0F1656D97316D95A5230568208F85E11862DBE03D057F36915B797C04219F3B69E323509C34B8F8CD08003E4D79FF2CBCFBF356D1BAA8145297EAA7E3649AC3B4FB2E8141D0A120618748C2A9DD5E7C00B35508C470CCDBF167AEA475EAEC0C23D215F229A61898BA0C283B01079AEBA4967CB611CBA95E1F573101857A17DA2348C16B6E85AFF162F6D2AB893A6ACFB625CF5BDDD53D4170938E19AC93B217D0B2B81E647CC7D1DC3D67EEF85028887F6C7006FAAC2871B05983B0BA5581B744A6D3712CD39081B93530AB7CFC7176DB8C00ABFA0A758CD8307A99F110ACEDA66FD2924DF4241291FF0EE923DC36B87F2F319EFB0E1E7428D8FF2214265B7C299F73BCBC6F5991651D39A5ED54701B2A4BA1347331EC839BB5B7718DA95A8192CFF78EBDB359FECE727DFD4A8086390ADFE800BD6F128D3CD69C7A7FA9844F6CD47DFF423F98732A5EB303EF0F91B49F8F778891CF0D75BFEA4548E7C0D49CC12E68EA199667B821534FFE1646A14D904A42F3FDE71E64A19D2E008722DF6104E98A0EC766B71AD7F5A601C3C2F1C46BC8C6CA8702ABD3C54ACBC43A1B245CED4B761A0C10DD94EC0179E484FEF0A952B7FFBDD797BBF864675C55743B89BA50D671ED8A3CB0EF9FD30412BC1CA9E5399E42BD6EDBB9EAD74109BB4BFB6DF7BACA771A258E34AD80C3284047A88B69881F01F16C8FF3B819C39784C1501191F5797C37B011C12D195EBC0AF9AF97E2F712772779CBEC502FA1AA9EF66CB29574FEF386935977A4F905A1340A2BD2E57780411D35F4B39B332CFE1510EE7F4EEED19A8C405B719C5FCA2F662B137F4F95CF94DE58E77129131429304829F551A7125433B16EC0119FEA0C51C856B7D15FB2DA4468FC156E6254ABFA113904A35F31A4BA58B5968A658E3DD5C5A71155C6E16C805830DB8D2BE6B428F522E886BFE0939D404C0DB26CF80633CEEA58C42DC087C7378E30AD1C1B02CA74C06525579A548380D960F96A5D02EC88527CC7213F87171C0522D7A4876B42F3AE3319EC030FAB20FA2B84D3792895B62F8A3E7D7ADB2D997AEDB5E84F8E6ADD7DB64A3970A125E6227D70A2B006C768AB5CBA0B2812736654B50511CD477226DBD990CF68C9BF3FDAC5193D06EBF3FAFB6CD64CF56EA80C8A19258D8C02989C614595498B99A271BF0D9AD7991D0BD9BA50D8565BFD9C2FC0F524A8FB95798B0D4AF2D9BF51AF1B3B2E40AE2F126A7E34A3BF4FF0D228EE33C822DCBA41FF43060A034733F57FFBA9B95526BDB5B9BE4FD502415E8C1C521E81EB29B3F4352C1F1CEDBD5F8F6C7F8EFB52D1F8379938C4453227D9F588C41B5694B4F2ABF010B94EB6D77FFEC56A789A5790EB263BB459A84C2D015491F22011E48C1440E3C793406835144585433885947299714CDFEB915F1BFF37CEDB75C4B55F166CFB6DC7EF1E69BA5E2E03AC9A10F0F700A660AFF7440FEAB669E95B1874969901E007B39BC1D65C1746AE3A2BECF3C10E00BAC5C8B4BAE07AD4EA55EAC579FCA4C3D194264BF4C660368C75057168401A1EEF2B52ABCB9B11E53143D645FD4360A0FCAF7D0D30C22EF231347158EF56205CFE44F58304352DB" - }, - { - "tcId": 67, - "deferred": false, - "seed": "B401635BE8E33FA0D248F6F5E6E599741501A0F077AB827926E7DEA4E8A672C3", - "pk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A9989F10AD3B8E4BB17FD9FF154B01A9E41501DCE6797720D2CDDBFDE8E0BA6CEF823FC5E62849ADE35BD996504D3220A24FEAE1EAF3D9BDA425DF010D11649D98B93FBC7513B8C782C0DB9D7E897440FC3C3B5B8186D57AB54290F1BB8FF3CE929CA5681849B51D6F1CC7E4136340DBDB90BC10D787DC7AFC342FCB93F8D332F779C41838A7A4E1D1AD3E5CA921BAD38B35D98B5A3AB78B0633657916CDAAAD41B63D783D98A0A0370839CE9914138A63B8F9B53871CCCFD73D0DFFB6473A6D73FA9B48035DB8AD4C96765BC014F460C84A29350EB8C1D43D43EC70B4D507B0E2F2EAAD653E81FA8077B5147A20D1DC828A90D8CEEEDF13EBCC64C74D51745D059295B532BB43E3E910188D1D57A6947EB94EB4F330C3AC8EE5C78E8BB1FE98406DC8346BE031FE55FB7AD2D37242A8290AA2F38A08E4B16B6688C6B341EF1DA0D8166B704DB0F363F254A4B113063E73372FAE0939A354B79AC67593E9325FD6C2451510244899B35A473751C5AE00AA919C937291B10744696ECB71BC34CF25C40DF84BF66D4D80CBC292005C5BBDEF16FBDFC329E7C7124CB759B8444053F69BE74B16C2345120D3D407993842807B1831AC96679FDEE72593C8C7BE3DEA2B5456F135CB536F3105101812492BC5CD9C8AD7ED2470C16F36CF46BB985429EB04B7288C2C468BD2FBCACE2CB73D660124B09AACE9F521CB97654871C89C169803FE8E62CD61FA35373F2ECE922D5D688E34A1D2F4A55E89E57BCCD0CEACCBCFF07BB663219DFA695C9B53632D6B0B9F0545AA8190584E11A2011991217CD46F798075EC26D3A0E6429A5E6BA022C191AC882CBCB57492031F85F22E2BAA0A5032E377354107BA33B70BFF808BA93730C42BE10D29C877F439243E0231C8DEA5066080547E5BC45A2D2B5FFD4B702A69835E8D86573712B6F518062DA75ECF6857BDE01E27C6198F79C68516B9226B91FB3DD7F6FA604667D9A5CBC9EF5E5AAFFFBBA7611203119EC994201AA9DA9FCD94865EEEAC6D65927E4DB04D7A4D115B119DE1F77BD8525A61605E21B3CFB4287182A429E14370615A2CEF9A2AC23784FDC58E929EAC095A421881B7413C78FF20E7BBDE5C2B0802F2DE80BAA8A78372FAF4E2FF881EE7903584073F6895C28B4B8DA913EFC0A9BC9EFCF113EA6C3710FEC2308F93440D5A9478431E82F3AE9527DA3500E7E44937A637F70F70BD4AA8E3C6B662CA326579C6167E3452EAED83A7AE98592120431C8C568F5723E8BC924FC0E9CF48617B29216FD15E0531E52FC36B4642F2EA7B50C307081139D4ADE79449DE300E20CE01B3CE1F115C8AC6EAD4CECF5DFBC6F34BF30EC76133894326C248DC33EB904D58BE3ED563640CACC4D03BCB72FCAED20BF63EEF0D2C48F6C4C39AADCDA8565B6F9F6E88A822214EC63C7D0425869F524EFD9B2AF0683E9D642410E797D8D929D3810F91804EDAA7DB074D1E06BA6A8608331AED4335C42B92AB16BAA9C5AA5366375EE302636C77B5B0628DB56DEAD05A76F35BCFD4F6566A156754A72F3ACF3EF0187476E00A2723A6105836C08675C9F896AC6353D15BE1EF3959036205E27A61BA4C072DF5E4FADDCAABFA950373060F8ECBB1223E9B1FA22F440BD423148E9940D8C43372120BEC7FEA4C8F0A9A7767E59B136BB458BE963E32951D87C9B31EDAFE66A2F6BB2E7FBA140939664D300C0380FCD15205C888DB991B7AD4CEA8DDA0283037443A5B166F0DACE0B9C5C4E935C10AE408D2F4250C15DAF3B2351CAD4D37A49B56DF652B501114BA06A3F88514A8BE2E450DB895A1A59127ADA2E3DCC7C061EF9CDB4B426EA13AD00FFCCB120C45B144FC86BEB397B390AE86FFD007B20FCD271EC56E010EC34EF2E916AC5D3F2EE8438AE34CFB53264F8BB4B060A4B5661FB707FFF2730D356A6A7344488DA60610FEF59DF33CBFDBCA271349826481049A77D9FEA09BB8D59136A918ADDAEC78AD7E673AEB7D5912B15241B7E886829F95DE8B391BA11F245FA1B106594500CAC933E438B78B0C7DE70ACA34B8F37A25CC40C419A1E626F1E0FE2BFBB62EC6717502FC5E469A6D5FC9FD866C17BFEAA175183F582CD5F6ECE90C0BCABD52C726B2BFA29D6651B5E7770FD12E1D12B9B99AE76DA076EA418F55F34F961C433CE7F1F35D954D04CADCD5AA2AB3C22A782892E5B2DC274FD009C3F59F157C3033358C2306C9822D6CBE8DD36E8D1D8FA228CD11BAC928575AE2EB50504BCBBEA36E383C1AE31A83510D344A1213AD37543F38E5009788671F4CFDB0659ACB773E470050BDCFA86035CEF439C68CCC8268938584066111BBE9DC495F694BBF77EB465903BA6EAA5B6D35FE009D4D5D268A4375820D18F19C5B0AAB94FDBCDA6DEAADA71CB09C2B6BE67B124F100BBC120B3FD20AEDB07DA8DBBDB8B2D0867D860C82BBD97F31F1EC668A55B8FA925994406AAEA47942650F0C5EA7623A46BFF43EFC24334EAC6441F240E6285839019B8FD8B0EF77A548534C6EA2676EEFA0521C58FC906C73AD1AA9B1626F136A6F19B8D4DBFA964BE0D717EF21AEAE8DF1D0882ED1FE087F4600916B2C37C9EDD2C088D7867C472D03B955FD575BC640F9C793AC3784A59CAFE0BF802AE9A618671B4BBC5606C2A2CA70F2129AA05A3CD81F11132ECA59D5026024ED99164D65439869647996A65127BB78B46C38F8112D883F08FD2D62A5A80DF9E099835836EAE4068C282E422209290DBFCF7CACF1BB029E92E5E8B5C7FA1734088E72634A6C9302A1E50EB7B13F66414E539DAA46FD15C4F494AF9BDC78DF2887CFFBBB5D9DAAD21690B02CDFF0D08C46F15A1A40C4A53BBECAB3E5914A6D5B5FFC1231183D5F05794C6A9BB8DFE2A75ADCE776BAFAA5C6EFA15E77D0296A7B12293562FCD6B78456EFF224E3B14CD69B5A92411D9B31C3B385FD660793776A622B04F8B034D864381278942C55AFB18F7A4C181620F6837EC8D240F25A0DFF45D873107E2A005715E84EC11DF91DD11E99DB729C62F424EA39F27775404E2BB0E4EF42A1053FAD6D12C531304201D0017C08CC906266D07319B3EC91DE81FB9480D3BEE6C168628E5B8D817B91A7216D46DDEC6AABA84F9474249D5927B1B5D3F4C6A91AB147F820A58CD0202A8CD6AFF75F51F9995268CC2CB3DD55A210008B667EEDB1057B067B26F4D4F11AD58C82F1DB8D4981093955C5E6C3274495AA80E9410369DA8503354F23E783CAF4E5C0D66CC2D6B632E8C45FC8EF4C5D64B6B3FAD03EB35A07D1A06593ED51CCF07FCFCD29EE195CDCC55548B8B125CF00F76167E9941FE06C57A022869425F6F5C4BE87B8DAA3C73926BF52C47B6FC324A7C69CCF9C3550167DD3309E8CB90C4E1070F9375128BD9D94B3781F5103034980017CDFE3622952EB3F303A8D233FD68F7CE52875DF1D2D35C62F96C487DB09C93F36DD86DB4618F62F6511A942B0BE2819DC2411BD0A50069E3DEDBFAEF8204F711BCAB3252650F6E97C1F347ADC1FD54DCF4B54B5D4E495C451A069B83CBE84084CB7B26C2254AC5560B712C7490192B418C21C1AC73CF45B6037E3816568709E83C8BDE8DD5C25C5C6CEB7C4C3458053A3514ADC5B9796D1C8BB0788A", - "sk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A7834E890B7C74613013A6F22A3FB4FD211718E21EE7F2599640977E85E317B9A1BFC39D0774A06F948BC46B114979737FC2BF0A69E043BD9A59E1BCBA7D22FA4FF93970C8D0918561C28B8B12445158AFBDE2CC362AF25A6197519DFA2E4991D901011D2A02993320C4CA06520326A22348D0095644B364A54822489002C22162940C2902495644C3026CC982C0215665B964D48A04104804813152DA21431509601E28290C0C004C3806C091772D4C82C1098280823711A45721C0590549840DB96800C878010A86108104C02A30102B064D1321211C0911985510313810B108DD0444810995163302A4C344C102692E212601910514C480902200A1A46301C9781CB967058443123138010400C894648803886242230D4264811082944480A10A86421852C50B225212751E140054C1642D4388ED1340D13447013B86C19250E2126615BA664C386040C999024042D64B025C3C0651C319220C84503A19048B088118444C32069D9409002950CD844624320920B142C10442CA2188103A60D09B37058C26C22933024950923A5511C3225C414621A08650C016488944804C84861484A8B144041B04918444E9C96605A004013374213362CC830000A35914AA44C24834C1C17665418894CB84D0A440A0217500A478ECC046012288C1320051317429202000AC26008A801C9442C191949C4221059B82148442220B8681B144A101390C9C26C20293201912D04374C2489884A864900C86DC2924008074862286912364ECC8624C324250444204802486344325A06659BC4641C274212424651B26C243684E12068C1B224193001A2C08C03C370C3468E432064CCC20802872523292A0B999108184CC2882403190043000650C44C54004820268ACA204608460C12822119353040B02091164AE0065184800C90925043C270C9926454B8859B88000A2101121400090608628604CB1602C3C82508398EC0C24400498411885013136294928C61B8600C022ACA4020DB4069DA08864A3469A088250B0240CC96040CB10D0A9825A18400523442400060D4C8708B04101C350D42A2451B30009C140284C66C0CA064833850D848208A162A81A260C190894A020550B861810225111052923688A0B8311207425B929104146E5C266204A52D89921080228188828088040581026688840019338CE0340A4C0202240140D3308CA20266C8348120B968189425091410CC922058961159B42D51C08183306003928DC9261282964C8BA08189488D1B44704818051936821B010693046E22450082C80549347148323089926154348E24C44423B640518471A39811504446E210261BA92059A229010781E2286CA18204D00070E4182D0048614028528B80700A094A48C640C89891DA06248C221124846C412846A386914B1052D932420BB691431669C098881C3992CC44698A8831482046D98689134770DC9648984805E2188A02226A5330861B8791D3C4610233908802505A34518B248480B64D01454D82A0000B3591E4366D943624A0249201380E8484680A9441034688E1B2498B920C89045008093260444112C40D1882698AA46C8BA22C112091919244C1206D9AA4215BA47053108502070C5B164CA4A66D11366108328A02B869232602C11680D0822D083522D93684184424D93402D3A6459428495B2480081881E034498C4232C21810001664939270C8468A0381711425121CA4019BC288A240849A88642097041804000A4061A28890801092D3825112208A0B2432C8B42D81143222492802048161864D83064C21472E22408A0B3072E4860018A70C0AA90D1385699988308C2048E41472E3942809497104B56114A72099C870542825D9126249C861CC3482C2B6614B18449B2488D4104EE414484C0082093921D82660A4B80DCCA2840C239151384D0235722025511490015182214B066920234CDB3692C0964C14C0410335819C406684C4909A44600BA80803C86864140623A42824471013208D201549403890E2B289D4A0215B82650AA025599684999441CA208403373223B77058A89008158D9392041C280011C89001851001254D8A368EE4A65164B06C8B488960A24D43404622C601C9A860C000220A2140130706C2340E6034248414918B0480182109194341027756188942B1D56A02D7BA54F49175E97242D7C7D88F8B76362F6E00626D5C43CA00F79BB798C716CACE203B87156417A1FB7C8329A79265384F842A03C67B6033CE4569AAF56CE5ED620C311C8747966BDB91381BB3612E14CD3BDA295F0F60629B22CEEA9902AC68C12303F7F6C6515540176509404B164CB26B20FEA5DC505E79EE5E340A9001E58BF1CF1895D64554BA65A5AE5B6854D0E3FB55F882E8F4E0F19CD4FE65BE4950FD1B469C285F3A8EC333E386D5E0E4EF77BADC6A7D708D43BA1DB88D6A65EE2AAFED1FBCAF25DA02E1BC70762EE598140F8D5707CD4617424B3BD7EA31BF8905E5CFCEC6DC9CD5A304E160A2F572674B8CEC6643319D8C8CB5D0AF800B88C39F58AE0EB98C422BC56DEBC63E21489C8B08E5BDE780D935E5CFF895991ECE3B1E3ED0A7C73023063F620DFDC19AF60CDD2AC586A77FF592ED2213E18A00591ACABD334D159112221B4937CFEFB52F6E629CE8BF43A0E68F5A6FC04D91249F4866BCE3D7552EAFD5D4A670F5646065CB63D6DD0CD169549070E7067DFE219291097F9A80013896E8CE9A98C8FDCC57952081469E7D6176447CBBA056EA5F7AE02D4F2EB01C344777CAC8179C65650FED7D69BCB3157DD3C374BFA535DAA86C546F7011E24F9706FC7C1BD2696C38426C7EB8B60FA37EB067C7F779ED8AE09BA85EFD5D6CF15CDACCBEB2D3576A9119B69272A369A0944627BF1ED78C9BD1FD755A0CD1C3A35A0844F5E838EFDA89A69D3142D98B493B9FA013BEAEE7711E51CBDD7D6BCEABAC57DF965C87D204B4AB7166CE5E0A223670A6E1A0F2C004A830B0458A92006FAD8CD67B5587B7158527F6A8E3910CBDC864E3BE2434BA8F57D992EF33FA37464F51AFAD86DD8E9BAFBF6D515069CDEAE1A7E2E8E74AA3E9A6781F23652EB966C13DC55ACECC623B2D2DD6D0E5B4F4008AADDA7FBF552BF631AEE4811705981ADB520C7409876BC7C6967939557AB479C75220C035EE4B1C7FE1A799D1407A2FB00CDA0FADD3939182426BC85BFE28FD6B14DCF74680D356E2D405DE7203B6620FC5CB75BF3466B6B121CB10755544895491911F4246EC926B4CBC41E6E32E0FD77C375AD6880CDE407B5D598EF1E100C859076038DFAC70AD8327B36EC9AE1BA43339FFCECEC16922CB2B8A68A6D65B62F3A2D8B549EF3E7B1937FCB779863D520AC99E09DE7DB053C91923ECA1C24272991573E2252CB5448E07A55A59207F7A6134B25032933723CD9DA9066D937DE127809EBC609AE0C0F24C6FA8DED0F1D828AFB99B99FB392C247C2611356CBEE8803D93E315B5A51E3075DBED3E19A239A695C5E5AB5390F8FF93043E07EC86A40D5536014644FF07B8615BE29B3E05687AC45561D942DFBED128B23C0CDFA00C2CD5A31C2380247695B8E54E851B0701FA343F264AF65570AAA31D649EACD650634E96B7DE543F412B44B5C50B8A6876CDE9DAF9F8489DD40196F28812E73F984200102B883452EF326CB15C30560404309EB5BBDAD0F597ECA72E315A0D68172C28F0CAED2CD9395E0526B009CF272CF44F5B0225E5C031267A1D21127C793F5FE43C1F21088D6821BA3629D9ABF69862A58329BB4734520C5CFFCEF5CEACA0AB27129CC6C38EB476DC689AC55E70A73448FA082B520D60E1AC4ED624DA8DC0C4DC388221C77E5BED4C4EC6CEA078276FC7A0C896B825F87B5ECE931A06E313AFD6837FDDE0A1EE4FB20E19E31F83E6DEAF585E4145C007B70BFB1F349353D3C4682CDE4AA15F74CA68DEFAAB2F73390FEF3701286B3D6098577C2796D53F0A72BCEB07767561B8CD74394015E0557DD0A08832E56E294236D70C984DA72618AF1C4168A43C29DA42EE5FF22D194139754C14BFC9E3DB998C8ADAEE2BA207881BB3988DBE11FE2F66A243ACAE8E4EAF497969426D92FA8A4345F01E2590620EB5D66F65B1A2602F7DCF30173A3BEA40E52528DB7D4415517BD3F21AF15DA3AE1E4D14C12BD9FAA1C290A4C6ED54D2EA7109F44D4ED6A1DDA63A1B98B7EABEAC083EA3FFE1818F03F5E5647FDF858E16A72107F46F85219EF35F831AEE7A27A4731A1D24976CEB930A0F8A325C23EA3F3333490E8F68157C6B731DEFED42F82811A50967E2779B5065F988C391D0AFF5C690DC89C73FC193AB994A80BD9373FFEF654F49517B81536F92C7C811935F3D34EF94D61C1F28477C3B89420D5EB1FD39DF402982FB267190E0118E612D384C7690052477E255BC83D604AB9B4B43C716E8533AF82F942CF273C9823AABB3BF1281601FEB7C86FDAC680DFFB8A7B1318E72F4BE9FA0CBFDD83BF073006C7A9A80181202C924C79505E9D9C82C81F52C7526AFBF982877D7F7DFB2576E1D330538DE0236E24A73739E8FAB92303FA99628E463DCD0D8CF300A234EAF7D00F3325AE876D27DE643E708213FA83C4E845D8B622DEB03C344084E3623DD3B7AFC424FB46BA1C81E4BC297B6EFBDC0AD025A727354DE74609ECB22EC5E92A8364469EE3B3E8D9630DB1F0C053B96CF2D38D72B798E769A56E003DC1B9217D912861E986AD4CFD2E25F0E25A59A60BC19130B45E3E5600D483D9A8B1C9C0836C4ADE168D30B8A590A22178A755496C1BB4D439786BC813CCF5402C2DA9D0649BFCE8CED93B8C15A3A9C4B34EB22B8C244AA39E5ADC3EC51E9218699F195231B698F46FFA11C6022B76EEB5FB6CEBEE1EF2D55B780969629674251A2E401F7071C948CA1541E2A8E1CB8949A9C610565E345D98A28819A8D8C1A6E950FDAF2B41C1D798A6EFDDC807BA931F2804EC61231B09EC32D9E752D3AEA3F8DE889F17C8E4698EBB7C491DC74721A0C52A4C821994334F7D97E31546BF7612C2B6FA368231A98DC64E9D4E491E241B8B5FA6E4FA8D9A30D4729AAE430C6D1AE358374ECEA58E07E697F0B8E0D093FE9E1D036ABA07F2D55FE9D030238C0DB6EEAC21DE6E03028E1AB991F74A754C2149630FB402C025C1840412ED11BD53BDEF26FAC36B0F03F48B55CF15773F8B083436BACF90B1F3587A782D4E4C50C7324C2BF2173016892C4D17B4E9A4BB8DE1146BFA8F6E9810B3C1DF090FC61C242E097A631B5CC6D468A9DACDFFDC660D32CE702DE2A87C8ED1613D8AF09A028B2B4A716388B0533A41F6322622115C1E751581F06F1A71CADCAD7337C8881455E3C2B3725C8A82805E6EFFC0BD89A0ED3C73A05E5EAE505D5BE604330CE88B17FE43F17262F3EEB06F7E62879E94A861614400A4675A18D08C02F888F397E90C5CCA7A5BFF3957970864E68B611EC6C957FB78D799DAAC8A0B917DD94B4BCDF3152E2B739A24816A08013D7B263CC85FE4AA35393C54E85CF5F2E98F557CAC073A381019D288201A7E8C93CBB5A3CF605C80C4FBCE566371A3239B691EBC0C67584B934AA243303D1A0AAF7648CB00E75E3CD8DA7D8AA71E41C0F8CBEC1ADDF27326A9D5C4A0A4E851F8552EA8EC9C9949363C56B33A745E94B48522748250B498D447D3E1ED82193B48AC2ACAB3F87655FC3FE6DA0A6C4D9E75278A21938DA66A09053492BD4FC29E3743DE3056AD202F3455E9BA37F43EE0B74BE2642A537F3B4CDCFD2682949F6A2F869DD4562268B50766C676D01D1CC425B206753FE2EAFD9C45E54A37BCA002D2D2599ADF13B43740F6C0F912BDC68B087EC427CE4FD7CC87B4C0064FC7BDB59CD9F17CAB3289131219A0CCB59851264FB44CE4D6DCDD4C85C9015499BCB74F68929D6E6191A196900B9B662A80811E613C405241A73C98B84E2853709A508CFD5B954527CAA7AD15B3EE77DD79E581F19EC284B54E56F45EC62EE6E997FE8F6C2501F12B544DAC253771FA65531A48BDC4671F3FA8FEF9C06B0A964832802778205E8A24D6FF3498703D737A49FC3A945B5C84F9810D354385E03BEB38269AF76A9C57501D2FD3BB5AE83E6CAEB143C44AC46B3129FD3DE7935B73F6EBCD42212143F3CDA752E5453EF3BA8E13F08D6E881094B86C8269FC2257E2CFB06C82E4CFE65A91FCD70273FF08F461D4B2ADB79279443C885F209301C4693A74EA1E1E13C4EDDA1230160134276B0B0740CF8E75CCD61FF4C2948DEF15763CD2EE5FFC79B12115EEEE71DEBFF1A028AFFAB0DDE512D8C540E9F3326A86C7057A0A59B800010919A8171500EA71ABE779B7452E40FD8D31194F7D9044DF97B2AB6629A13328686358698B5A04D1CC3B38A46BF63C10A08D924D93B8EC49E1936E2C8CE86AA65AE2275B05AA57BCD6A8B641739A9FB5D941CD53033F4168FF830D04A6197378880092B6827DF9B1C8D5C397C00FB6E7F151DD93778BFDCFB1CD4BBC797A4D3E7BE4401BBE012D102AC8D8540E874D44C641834F66CA534BE7A5747CAC2ADDF4DA703FAA6BD79712E8B7C501D88F4076B2020E8E99CF95A0EA0D0B92E8A779B9AF6F00F306D78E397AA2DCFF603CE47C4AE7758731B20CE5E424EDF63C6DC99BD3C86037E46D64025A8D6CA7535E3D202B60E335F38E62FC4A041760254FB88E9E9FECC2C9F7EF7B2B9896FCADED7E614EE57D3D0E5E4A64BD649B614BE554838E38170E0748E5FC5850E6D9C805AE59928A732B01595DEF14C7B80A7D371CE80238F0448D7E43E37BB7CEC15304950E778CAE35D946317F796B5A8FDB5D85FF17E4D29042D934EC51C37CCEB4045077D212AF9E039F0E9399F75FA5407726FE2168F50CF6380566AA47B6CDE62" - }, - { - "tcId": 68, - "deferred": false, - "seed": "BF2846DEA3C6081ACAF75BF64AFAFEDDF8BD15F91767993B2512551457A429ED", - "pk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273E9D304793916EF99F55AA44E7393B5B29F8C8F3208162C338DEE1D78EC15A6B53567C948686D7E6C9ADF72D7FCFD252C0B0BAE33FF0CD980E10F65D91520BBDE49B41BE7F40F250DB70CEA064E0D553E3878E10DDE3A4FA97374A3717C5CF1CC691182D6B6030A6C7CCBE9A06B26937D07A83190768BCA23EE0D53FDCE3C6B8074ECE6B7AE0DAE5FFEA2DA18A34F7683B5099A50C32B53A7F564FF33E961153B915AB9FABC9E99DCE6B9D9EEFAB3801E4FA1C0C65335F18D45E9E947C1D95C41ACD02E3E64427FF751959A430A59CD8FF7D3540DAAACD99A668FB4FE3DC6194E52BE226FD2258DD487E8B3DA7326A1E56F0E33BCC84666BDFD9BDDE4CD9B3A2713DAD664188C811C6381126D4C4449EFE45D071818D63F7E2B61ACEF9AB8E70C643BB14B223CE465E9F06308CA83C49B69924E555F5AA6F2DC0A919B86A69B7DAEB2E4F1E1985E15790A09D8D34A81CD5135BEFA07606C17DE9E53A1B66AEBD2542D5DB491DDC8702C85781933A07C7C5E27FE9D7AE6767289D9F98B1F525448B47933C114B7873DC989093F7256389EE428E7F704C3A254842F51DBBC882967DB8AFB3582BBE75DDC260C52C0EE7E46A6B407164FBB09048DE13183A787D99E7ABCF6E485708E5263A4F568A2C4CE1AA7AE0613A50B87C5EBCBCAD91D2D5ED44E1575E8C71C55042DD445AEEAF81957DA823C175A331D41D57548A9ACD0872AEA3AF4EC7262C4E14597CBFACB123614170D8C9ACEB4A93581ABEFD24CFF5AB03844E2E95FA48F265D58EE0076EA9F44579C5D440D07A77B0F94B117B9217311ECF2DFB8BC3EEE5686EAC9F8E4150148BB5A824C379EE7E5FC383CB5D964E564826BB4DF824954D350ADC37CBFCD4CB3AF4061E778885BDDC7C77CD52E2FCF9C76656E96D432A57149DF48EC694ED04B45BD58B2616099E7997C3B7FEFA18A88E6EAD6020D959E1427B796DC14AC603F8B49AA90E1FA56A6097C97F21F327431B1590063B7C10635BAD500EDB5E6EF985F1B321203E5CBE358F8A4549CF16793091436DF517F308CEC8A80DF728DD32D8A76F7C586479AE7437B4374073C0D76C60E111EC28BAB200453BB85DA6DBE5776EFDBFD22F4F7D165314C269EA33CC0A6A14891974220B2531238B896ADC75E5AE33658AEEB3BC4F4954B44B585EBD1DF92302458FBADD906F4A69E0F0013C385935BECFD97C8BB21A127E34843BBE4D7C82C9EF7F91456C0451828620A151F4CA0260879280C14A27B0DAF873E6F9D27CE1EF9B8E50F5BF896027B415427E633C4F2D04B2B921E1F0B85E34AF2F6D1CA6063AB1F4098941330A1E2A960C885EC1B1E36876C725561CBB991B37CABE41442F439EAC01CC76153C98AB1D927C53BA0869C6244A48D2A235F325932BE12A804756346285E2591FC0EA0C5A923EB22DCD3769C22EEE39F01C211F7FA67FB1B042D21B895B54D07997E72E24DF13C35219B79CBFF013A9DAC527B230A66C50FDEAC820CD1BF82307B7E364A2DEC1360D9C4DEE5EE3330530D501D35833208F8CFC2C7966347FD4B145F7A457DEC7B07EBB60EB8116DD848BC10FE8654ADC7F0BE98642379363AD172B8A472243350BF2C5AC80208143A21768DC4CF30AD65AE2A1B887BBFE47B225B3194138A079430C1106A5D5FAD56F10CBF0945E681BA31335B40A424E1FD7DF2405628FD133BA601A9A8BEC494969865E391D18A3F2C93AF707B9D3FA2C1D909C75C0C109F4166CA1D5EDF1210A5F3A426DE8C328C6089B40E21292688B546A5017B9AB038A153B311330C7054E0BA34652353F99FC5E0C4F196F34D10EFDB967F3B08E01AB74C2A1FEC819FAB8A5EB71DA9AAB90A0C1F35EE13B1FA41EC0F8850E127E8D3A02B25FA68D5ADE727C23C02BBA161FEB29F7C6B12C887EAB6EE13B96921A1838091D7BE76394E7B00FB61F93C29D3D8E108F2A510784BD2FFB788060475F09B96736E2802D9C0FF4BA636C7AA1402B4061C9B7CE8B8017A17DFCC571BB4122583D7164FD93D58B4E204B7938D8A29D923CF59AD96483D4EB15D8272D9A5049A6464BEAD51881E27982313A4EAD2B59CE76CA107279E1406459F966F548C401273ED78E0D7A39603CE8833DFFE05CCDD7F8BD077938BDF1EFA0E9C04581AE267904C0E071F14CB7C03C47C123EAC045D023867D5417A2D79AE49D967A13B645644BDA1CB4C27475D20E0ECB22AE89A6F742FAECB1E46543B7723C782E5093A5E905924AAA37D9469C0E06A64AB77AC655E7BFC7C6D91BC4CB9A7333640827288DE99D6F0C903B4BCCC0B3B095874D7A435759F7244E08C5387B349DAFCFF6F855595660E81F691F073C33C9D9B21DD9EBCB6DCB86333540B6DBAD58AFA0DB6BC25E396FC1D54F74B57C5CB127468F655DC8FA27BE4C5F0B47DAC99DA66454CBB3D2E76796A4199370B63CAD67F8F4620610CF6B31C8C4E05FA696C3670799D7141A1CF67BBB1BBE3BF8EDE42D0C76125B7DDE298CA1413EBA6A767B3AEDAF89666A882C5D255EE76FCC79CD41021DAFF368BA3A20FF217B76E4E3A7CF9D487820AD6AC4A2A9B9599CA6F5223DD4016DEEA12E08E48E877199B281E453C4F4B6933A5B2F86461AF01A59EB1E38704C95C46A5D9C54AC66348EE19BA3BC8858F000E18B58F350DBC1414928B3F7475497EB7015AF29CBB257899615D73DE8AC220E424846F54665635DFC4BE1A8EB017870BBA1464D799B89E268A8A26861A6B038B7748CEE50BF093CB832E97E40BB978E93D8085457376BF43D1B299BD9E34DDEEC0B6DE0FCE5E0A8DA14C1E22EF0EF0F677651505E2C4E4555D04CE7FBAB8BE12FF143244E58D8BECFFBBD84F1CE3F55B521A2DE728C86B2DC3E30A9400EF325FC6526AC56C81E09093BD9BB93CBDAC6D1309A777EFCA27EF9D33B144EECC641BBDE8A4CB63B3411571BB023663E893F2020B28C98A33027D976C82A2578EF9D684C88C7ABFF2CC4C3E19817E3E8CE37478F32CFE2ED494BF0DE24E051823F8842C86D5EC5A0C9EB87C961935CB63DC5B8A4CB62B726F3C3F8416B67A638D4D7EC476305C9FAA38B1D2D89A61C68011878797A5C5E1A52205719D1327C9F26CF632F0365C586B6DD76282EB1223ACA24D41907543A17AC4B17674493039CD2E5B3C8BC15B2CB2A0F4F79EFE3575764F166CDC5351AEB71C328138D8824E558B87033B0E15B2A14566084FD1D72F375D38712EFA9238F6A3B799B5F6D92034CA1C298BE6CF526CEBB371B2240A13D0D8D6515360CD88E2AEA4DA1DE424DFC7EF79247A526E3D52C09464BE70731D2D7D409E64E4F1C45037AC85B8B3A40B53AE7A5CA4F3527ADAF66D509BE5714C94F49C205763577675452952D34992D4AC89426128C73F46108A3425BAB0E55291FA05DEAC792E91B5983BF1374F99E27946B676A5D7422579910C6EFDDFE80199B86578B40875BF7562BDACC7A9601F55D22206AD785A73F00E8EAEB70E53A5643805B1E173ECACF8FD1A70F3CF38504B4B021EEC915D8B1B2A835EDD6F6A22F06CF33C2C96529FBB54A3BA47FCC8C2E7EE9089DE5DA246A143661488DFEBBFB63CC8D2857462F55F009FFA917A63FA87D046C3F922CA3F9C1B650EB9657763DD91F4", - "sk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273A8F45A2EC134BF040EF6F32ECA6ABE19C0E70D5AB5AF5D284AD01EE26877180F80C71A31A5F3CD8B5AD5039D4CC8F5EB6C313B5E2D5236E04F2D67DB709263EDF3F7168AAD880C3EB854DBBA92BEB2B1F841BE9047F3DFB0D1DC975F36CA9CE1DB169101180E002369C93685921824E33246C346201A26511AA56DA49069003402119224A4082E04C7480BA66C61100EE1A04104C58460822102854C8B226D9426714A0824C8422112B26582284023873000947049460C2397090391708822621C41111212444C008019A205D1B44D842471A21825CC386C1342100117840B446A042006911042C2406682C845412625092560DC20254804511AC1919C2060582431DBB03011400A80347218878498024D19B38C1C388E92984991281019996D19399019B448DA986C08916113886420196A42C46DA2404889C03083C210E23408624484531061A2A68D81A48D99C88818B40D0A27428C1626E2A62800475108C309883885E112311CC39109910C59383110338E6432904346821A10924CB844244740CA3825010891A3B8819AA2499C90401C12310AA0480025605B1464DC34091C21810A116293104EE2986DE430868228625232059236881B017112071241A0109488204AC81002A128249820643850804622E2B28018B7442222665C303288986D818241CC904983C690A0980544A6281AA688140012138488E2A03163B8251184701B142604B13109A25013188402C38DDB24255AA64519338ED89628034665631420C3A050510429D414098C302ACBB4845C225289824C94C2691B268821458014B21162B00853C42410112500A8285B384181900CD0008E89184C1CA085DA244603170C81426491B0400C93685C90454BC081C08691019020501625C4244004437144062D2211324C34229B06666386610245621B4252D8128102478C903211DC3086113502C93025D2B42C1CC38413A12C01B84901238DCBC84D02B048D20449C43604D2C6254AC28C91280EC3364C00018862A49154444CC84289CB840D941804083788A1404A1C058D1B47845BA48524188D102011589880211441C3421153B0101BC92180866C0B300D12C94449406CA0A691DA14820B0532D4B08103913054404E504882519604842270839409C996490416668B88405BC240A22692C2882DCC808964B24D00180553380AC288319BB844E09684C3488E0A480CCA1692E042311A138042A86543360521B1001B2891E4422AA318855A804D5C268264221010450D21B88018A1445B864C03300A5282841927248A048D91848819A48D0C1140129981D0248964C63189068152044A5028252327309AA88523347080B48983300E88160080A66D0A9590C3481062940D49A289E0B270010260902801D8906092A86D50B04CA2B40C9B90611BC6089A4084200391D8C61009328619230D13C15050246E59189019B2481AC090E300818B944554907058B6008A26214C3264D9008184A611A0B28022104E64962D9BA86851B28051B46850382D23C27012B14449024A84A491A3C089882241CB8440A006711B38250CB83110A540CC4632C4180DA4004601316402280823B54540B0899292711C178D58A010129225D3B26D01948523336113012001058A4A8445D236315A44802124414B428210998954406E1029411CC90949B4701C1384184992E2924C090489800026CC28229B882CCA0289D0824401498AE1C8080A92045C240680020A81368E91088A1CB7601B856902092C1923518002642194888BC0711294308914100018684AB66463220D5236285C384D1C85641345900B492964204219170D9B3032D0A25104209219222848A2841C2304CCB2311C941021403089A485401269D0064E0B485080024421244D0208704922498A828D1CC810130144149371113746988605D91840C28664C1986889202CE01640048730224024220188CAA08422090E81088659B4700B212188B46800301124882D0206722125250A196510122A089501E1900420100851362A092345A4882183A46DA004909B380E42900C11C40CDB365152006A49A8911C964D214130130092E0B665DA960DA0080614282D9830650A23510B3801924001CC080E90264E23469283964193848052C845593244C984682028421449615F92CAE0C5784CCC5560F4488F89C5A8234F2D32A8E68C5D1380EFFEF6C6C3F320328F0E3955484A42BFEBFEF943FD69D962F5F6A78A253EAFC70495F96743FC5E93F127C180F1EF7E7A7DE4221F637EF2325328DFC314C96A98F66FEF266E5E3C126258B88352A244D3ABDE3844D006C32CF335FC8C2FA63F90885DA39F57B54E96D6C7D002B08427C7543F84C415CD0B9C35BAC084A84EA5667905AD532B9B96DF94972DC41F50D05211D49522F3205CF7BD9B9F43BC24320464B22B6A7590D2B494BF8C9679B36CB3817F2AA0F14070712F4D69E2A878F32EA8417200B15861014B686B2838FAA7EDA182CA8FA5352C8A9D86217C1E64ED566169925A64D0F9FFA46F681FFEEC859618FAF0217A4150D762F4297240EDB382EF9AC482642EB18CFAE0C2B6C63FAC6B13A0CC2EF187AFBCA2DE9499D8F03B7808CD4CBA3C01871CD18C770DD07E18EC4087CF88FCC75F57D5A7B48488CDF11D05BA4FB5B990EBEFF7D0FE336F6A09B47BBC587223CBE9C0C289D4D822CB6603D9D72585D9BC1B26690D773921442AE98437F669EC1E5D163F8755F01B79B64C49A4749CB92AD35CEE90AAFDA8D4D98C56F2B2C5C23DBE4008ADE3C2CE2B58936C991C1EA0ED68192024A3070B23BF1912BF125C7EAA82DB74BF70443CBAB50313237702F004AC5C9097534E7809025205F52427B5D943BCEE4B5372AB0EC4A7D5F56225FB2945E5FEE0670CD4701D4E83F876B4E35DAEDEC6010EE8050704D4F652DF7AFD0F76CA4C8AE495598CED4DA6F831D25304B0C3F8DAE68EE4587315ABA35F0AB0C57E5F8B1FC28861B94EFFD86A4138874F8859990003A7CD06C78B658F98D4C527A51449064A18EA036AD3F12A12232B279DFAA066A2A6BB855A9BF1719223E98AE78CB16B0C2BB6F01BA01A5EACBD180A5F55486D97C7C004327F70F053211BD2AE5FE5624600E6BEA4A7C3091F7D55BD0A08707D00A48BC4FBD1F5E0186B28FD8BEFABAAA378C500F0F7AAFF5AE10D7CACB3881DB61E0F25D06D4521AEAD68E0123B06C8EB36F1E1F4DAA89FE87FCDC965EE3A3914ADF98AEE505652881A23005B15D4495DECEE29FEA75E8416A73070157DA6CD4F8A112122A342AF5C1CD7175FF9878A328BB94897A79BD38161242B939B8677A161289A6501C7E404F2D26569B5203AD21D2E41E515A2B44719A7C51AF3CFC2DD19E939A6E820093A88E675FB08AFC3D681F7862F3C7E04FF3EBC47C6A8937FD5318F21E393794EB650ADEA8721869F12FC2C36BD031DA7A0F3602E143227696B6944B882A1D7F24BE6C92A8CED148002EB07A89BD4ACBC7CCCD61D79389D8959108B5FD4FC6EB6335F320D796537C4AF1D2653889757762F2FC640B546D58F30CDF6CF19849478FAA2A4CC9497B08B4198545924CD469A92DEDF4617FCE963A12F7E8DC470751A350A700B6388D07ED6968D73C92789C859BF8F5B636D62C047953774C68577E0202E526B75CD4B8C040C7ED79CD71746B644BDFBA2A3D97059D4C10F4305EE36EB5EC0FB2D4395B3AD76F267737E494AD99B0BE9D04864C08B2F59643A3887F08BA8D1262CAE59AC5EC8BD6699FF8CDEE37B62DAACC40953C1B11F11801B46598C5465FD466B48E5259F39308C1C0CC6E03570BD73C167418C10E4776AC7A88BDC0DF6CFC0A4374DBD8C46255D21760A05F2424DC7B1C5289498E434AEE87CB819E7CC121AEEECA145DD5F296AE3E9C4BEC1CA869247DA963A32D892808D5E21C5AEBE225FB47BDC71668C7671D7AD3E97F3C2C7D9F6922B723BB4A1C192F2574E4AAA172935BC5CC8D3B8FE9DE0FD6495EA954A572BF8F99A773899BC4D0860C6EE0F7124D2E8BD80552196A972B92EF0DD02C1B7B93ACE16CC072B3459CCFE7AEB8EEED6B6189A5F6FA2801C529DE277BD70C0A74A256473A24B9BCC9F70C50247A8BCCE4FD65E6CD3B0AA3EF08748075B6F5CAE090DBB0455A95C1A01F0C4132EDCC96943F6A055FFBBF014139B44E775378C8306779AD387BB578D0F6C87A17E50211241945C07BC688A4DAD2F1C67727A8318B4312AF75829DAE2642A199E2519427C0C589128F82A873318ABAF65840240881943A09D04CA3775A5491D8602D631F4A8202C5C58EBD478F54104378328630B2DBB94FAF7346F023DC13BC99E0098474BE922C50A0C373412A3C0C5CC33448560A35E98A8BA8CB9AD6555A96F9E5FE5634DBD12C6EBA9609598262C87361775A4F89EC1876DBC29B382CC3F114E1DD2193FDF18D63E8CC187F5EA984F6B7BB02E8FB6C56B8EB0F27A0E7416F68E8CB2D102D1548126EC80220DA3FF32131BFB793325301DB1BA905B64F3878FC7FF8C6880012FA168C59D901AAF36F15621DA4355E1FE9CE11EF061393CD78BF04BE8BB124A11093E5A7E083A62FF826971DFAC64E455C4AD8AF54D156C34F09DF10EDBA38F9418D6502F781421E8F5D6768C958D1FE86F3FFAFE7A338E69BEEF52E7A12A301384F98BF0F399C4A2CDF1DBC73A24F849FE3039F1021D30266D9AE86A5199D3A27971BA33AA0E1068D1198E76B410E9C5E2C360E07EFD930906C859BA5672E40F80830B555C44350AE5EABBB93CC4A9BA2CD46419AE8FDEFF49E145B403356E5614F988A96031DB41CCEF5061FC616B31E44C08965CFCE685B1F8395EDBB32991CD550700A569475224F173F180EFFE1067B3640E27E9B95529407171769C4B13A502D8FD1380F7C2451ED37724A9746EA2E6ABE1BA232D3C50CD85F5E65CE03CFCD63A1030EEBBECB0D37F98C54B3400EA4075535F56CAE74F9ADB282E54FEF53AE317DCD4C14C1018D16C5EC858888536654D22FB3FEAD4EF8BA3A766C037D950663646367099231211953627C838CE4468AAEF91595879188CEC0B5CAB9E642A74FB4BC9423A265016F8159455BAEC314CBA926F8D4BA27113E5DFC32B0188241EACD32EE8271E146E3D820A44565702982F7FE378682903C2934EA5607D03823A13DD441C76BF385053F044F8FB46C53B3B4DC84F8AE503BD085BC8A04A3881710728CF95862C3F587F5C36E5A938F935188A3E6E6435DB64FB3ABBD6521255A77DECA3131090866969FD379E88D188852430EF637B0C92EE924D632C4BFBE21125B5083009F32771209A146CA19D7AF7345F4A40641E1E1313D348B48137A9A292D6DDEA5FF827F1D5E9C30DCD09A22A03E61A18613FC55C428454BC0EE898D1B81077DD99EE00B9C24DCE5B800B434673E826169EF0B13E11E01551E4BADE5F8C23A37F69A7E66EA174F2716F5C2D8DE74067E1C72984663C2B9A85B34C2D266CFB0700DDBA3C3C33B8BD6348CC3422BB0066DFA0DD49C0A2529A095004C06C58C1512A0E303A29751B759507DB6B768BE9E0C812CCCDA432185042E6D293086A0F6CF1990C7ED3B70C0BECA4A583892272ED984DE09EF53F0BB7415EE51B1C78B69E85F317E47CDA68C558BD3303DAF307DC50F86EB29B8A1FF022EFB9BCA38D7F886766D1AF006389A31C633395DE0B16A45B02BFEF191DD0BCB72B4C3E334E7CB3CFACDE61D61BF58F8BB68D0DC480030FB0A2A5B4462CC21AC937499C3E9584B8684FE30A1B46ADAA1DC1D1747299FC67CF7F8BA46D622EC599123BB470404044A6FDF12208FF47518B13A08529817EAC984BA850E0C797BD360F8F8194600B6F61E270B588546000486FEF61F7C1BA4EE4B61E11385E200E67B2D8D3B6368A01ACCF917A530388F463CCEFFE2CE19A50573B6E5FE1CE2DE99C5FE23E78CE56127889951658DBF3C9B1CE3E9491C24ED4E6FC49B40CB0827A42CFA9DB9AB43837CFBF4189731F978CAEC3E9378C9FCD6E820B969DB94FC81C494772E41C7CADECEB5774D9CA07AF3747137A8C38706979EF7989679D72157D7E933F873B8A5788E75B47AA85DB93F4493B6335347921E492A7A008DEFDE2A8AEABC44536A68D3FD8370B7F7A7BB81F9B1237CE8E4B04EA49C8DF6F68377DE8B7A8D84D2C34B33255BA1994420A7ADDD191A8650E7F63B797B1E8CFAC5EEAA687F7F3776DE10297BEE34C884211AC44390EDAEAD160E4B47E49CE6D40D4DBF38FAD09F32179D7C88C66375777740375D790B1EC716456FB1FBA1D5CE5652AD54A2B7AD5E9D62D01739052D29973808EAAFBAE24A190716437210B3957EDA9C6946EAA9C322B371D30DFA5567D3D374310ACBCAE642EBAC96112F820C4A82C6D59158BDB81AF44C648DBA1AC84DBFA3AAAB9BB64D7B264B13CF3232FB1271C421F590FF449648ECB56325AD339DA594E0795882A95DE0A942A639D3A466D715C0EFC1B81ACA240039BD7BE62C19A924CCB07130467BF4505E1D2495A54B2EDA7A064A989D9145EA9242FC885A9706EA11C880EA099D3EB563099960D045D78100CD6A9B888E22DA1FC29A3FB4AE0A67C3AA8D6B88268D232867E2B6BC940A0B908C413B4A0B85508F5DCCFFB05AB383EA69521DD0F9543F78789F1E35F4A4B7648C735DF12AE6664FDC7F8B99E5F66E913A26622BB0F6BF658796AD22653A23EE8AD8C3ADB7B07D244827EEE2445156116E503258C47EEAE8701C4BA4313406D62FBCA964DA4D2A4B130F7433A8CC1BCCC0B8C4D37F2176E31DC885A07339A103BCBB26EE30F2D7BA66CBD6B8C675F04109965D08E6B0DBC6D9F5E4F77882D2D66C5B7536F313BEB188AD0B6748012180BA65B07A733FAC0858EC5C32BB8" - }, - { - "tcId": 69, - "deferred": false, - "seed": "12B78D9B1A0645B5744CA179DC53994C83B561F77E63C32BFA617CA75AEEA7E6", - "pk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE648FFE9D9C06DE86AAF547C8EEF2A52B7BF95AADE081C03F75E7E072CF6B22845C52139A10FA2ADE1B394284A21B19FB930EE6BF8DF7F5E8A3E2D3A631205E7CF8D0F8CA673E8376515B77DE4E876E5D45EC152335693BE63ADF11759BD686AE75ABA00295539174B9FC74B69FB7DD1DCFE6A989EEC66AFC30562C8E2ED0418B11356A91231BDA058A18DF1F11DF076CDD5B3D56C96A260FE22AE77C674CD34329F1FB4BE1D9EE13C1B0BB5BACA1DF12BC15AE1A5B9B939C26F08C5FAB9B72EC9E43C3C48E12C7F317F4AD712DF76D31873CAAE61C1358BE84443AA8F74CE06F67371AD4105A0F78E907113ECD4D823C6AA18857D7F5650B030A5E5580D6E37BF97AFA96D797809BB538AFCAA5C1DD6E5DC3F015BB2D7BCD5EF24B62DC34A76FD591309458B1B883CBB48477A9D58F00256C6B285849B4A59ED11BDB568142A06E44FAD490E970757E02505E8255CD0D11161F2CC467C4707F1D4CC7193BF081EBA912064AB1C37026E6C9760DA69D545A89A6F47DDA8DD68174D18AE9947DD9A2EBCB0A785CA3D7ED4087F27400F374DFA167A35E75E529D4E7C4D06B882A114561D26E83A7A000223BBD184CD3D0CA98195568C5788B3B95C246F24A28878244265E7F94EC43BE4C3B81ADD6557EF609BF2761EC1B9F14F87208883A25CE2E80809A17BFFA93D894CA65A22CD85600EE6D9C00D4D07A99BD0A219A4677B689FE953449915AD1F3788A682004DC51470A1D25214496EBAC6DEF10663C616608A3077EC9722B6089B22A6C725D118F80180614CFEE11263ADCA8867C07EB210E64243357F8C41DF170368E8E1718D782CE4FB109D7E7872FA3B242C560FD723B36315D715CE96300F450819455A0003835239F2ED79E02B4B9630BA24798159126271506F3EF3550AB035FFB963749077C537FF6420A4CBB3E09BABF7B020931D9AB34E10E42306E40DB39C1D5927BE05DF34D707E3D953DC333D01B06836B4A543867BCC216F32C3C4663F7AFF2C06FC1DA5BEB90DDC4AA33C4868B920D59512B1181C9C45341CB6F76F66A867841A4073D0FB2E0E1CF5D9725258BFF96EC3F673ECDD216BA10F8DFBE52529C8E8AC80DA471D5468DF34E211A68B3A6FCCED3FB756F59B155552828D2F4988220292C53CB3BC1277075FEE413A8F35E349054EE31389703DEBC6153A61939419FB03A347D7A20E72E742BF878A71C1E6690CABD9BD80ABD79588B9814A5C3D43FC5D6225F124EC25EAB48DAC33825050A6EF0AA9FF3A958CD71792D2D93F5C72D85CE79FECCA5FF77E72CE9093472B6478786888C39B22B5A8FD6578774E5BAE085ADCEC6B0FD7E65479A95BD9FBC5C10DAB4718F2CCB3179FB8FB4C3412BA3F123ADC9EE98DC5C4D64550FE00780F3F0775899587C1BC8C3543B8D3478D307A18A5C90C6B7FF46ADC031152B6E1547168C2C598663EB233F52B28439EAE306DF3BEEF57F4C0DB45894AF4F2BC1FDAB69A2D46B75148DA829EFAB49A07030775FED3085ADA7F3D56B6AA9A732C9F5604905ABF9A45D244B10C2C11383CB6F09A5E576E992526FF3CC0BD73941350B31DE9C8FEA826DD980504BBAC2077BD7B11AEC2DCB9CE3094F95E716CD6C6D0B541083B7F28317A65BA7F2C3FEA438F22E61A1325DD8A736E8C45098D6EE00B97789766C233387F43F43185080F51A55D20D3F07AAE1BF460C577EEDA3B27275060EDBD06019B9122D017AF5E69F4118B6AE2D8FE342D654874A46DEF2413EBF1FE4490E56612C8DB050BBA92F520C620DAF77506EBD5718F9C7D16816F4949288A9CB33F6C5268F9F4F9EC77631EEFF1F67316CBA59A0060E6B3AD6DCA2234F17ECF9CDEA719B5CF0E71EC06B16C6BEEDC0DC6EC4FC855F0D6F6B415E97640F0B6220FBCF6A2AE9215215DE029BAEAA3CC272AA37B89077BC7E7F79213B6E6ECEB4839438E410D3013B4382093CCB74C02ADE6278DD3AAEAADC8583DC7CF1DE0E46D01D6FA3C4CC2871D8C447DB6D6ED19E54F21619147B5F4F1572B4EEEFC439E63F55788C8FDFD65BB517F3EA69D368B2ACFC89A2C8AD317EDD58132B167F28CC05DB2D4BB959208B3FA284129E831CC98FEFC8CFFE3B0A93E3B23C7D164CF17B8375AD27052214C0C4BE98A8A5EAD5B58E169717938AD889E207418959B86734C31757628794220FE487B3222711EB859A17175D9F89264B52E2200489206C47CC96EE85127C93DB91EDAFCD71DE5F6D00031A685B5375C3C4AD0BD2C7DC43C338371AF943502DC9DDEFD080C798BCA7A4FA680505677CC38F2B3CD703196F224FBDD0CB5DE7CFEFDA481DDE2C6B42EF0A0C2765579A185681C88B4A8533E18B2AEB47E727101F6DCF58457F7BFEA5BA4D5FDEAB4B8D7CFD5AC619FDD94360E9960C5AFEF4B21F5449F5F974D2DFF521D2ADC721F8431E2C944C44ED8B66ED3BFFB679DF0866D20CFECCECC4B1AA6F6247D833EA7DDE92A857AB2A179A14AD8D296CE145073980C9C204EB1A8C235CE08E421517D3722FEEE717048014129E2F793B3BFF60EC8D5E413553564925140284C5779B8B30213F282D3A50ED3702C55DF71DC7800232DBFACA8EC126A0202510CDC6289327714071D8B30557F62DC7AC9E1CBBFBE4E300049079D298D44BD8A391AB033512360760A2A045C35B43EAC71DA9761C5BB4D3808FF35FA00C8A538AECF6B84BAA7ABADC51049F7F6390AC2FFD8C40DAA73600F8C243B1F2B497DA29F623235B88412DBCD721F6F8A598E31F8700D6C40590B9E191ECE668BD4C304AB4A8B21A7967CA80C01BA542FF455BA3771BF0766E1A86DE16CB03081718581E0705CCDBF01C12E4C1AAD8B0B25B5558F9A182B6981D4B32B13BDA26ED8EF813906EB171DEE95B27CC6DBBDD776F19826A0A32195CE7F54FD04B5E7DFA7BAD009DAEDF7DA531A1C85E37FDBF65C633A10FC7671D5CA85BCEEC6E17FE57E7DACFFC8663D3952C41238BB0ED95A77F7981BF23CF2B816DEF8A75B3344955C452B416E5A0C087DC913920BDFBEBBA499BEB547C7D1C06029F31C959A1EE1B16C9AADFC7CDCD41C5B8CE23C5E2FA99C78E6BB6D615BEE75B7453ABCCD5BD961E776196D7D5A07431DF4C0926A514388A8BDFA2DF581EF16A7B575357433CA0A09D28E9158802FF21B6C86CDF65697678EB72E809D3706BF37DBA403345FD7DCE699E9A9243181305E615BA50ED867B5401C12E6277D24FF7C167B317699292EDFD4E95EF132E34972D9E55BA4E84CA3761221800D0532A1A38278A079DACB541C1CC56E00C1A7CCCF0BB1B746251B649954766C2A980DEC096BC570B6A4BE8B78D17C1EDBF3CA372B4FBB610FDABA25901A38B577CEB2F627650C80DDC5C255AEC4A5AE07D361CD88717079A883A67ADA8F2B00CA7F9546EBA4279513F66DC7312117B6A80BC01F0C268205AB6FFA8D90A75BE3463D77B98D183A113D382BED583A88642FBCB2CB0211141E64F992679392122F4AC5F80CD8A5DFB86DB5A7EAC05796EED172F666903E909819FEB2AE99550D2F32B5649C9F18E09CD3BC8E8CD08F2C35BE7FBF37F8684E89F0DD02C60EC8A4B271956EF1AFA0CF20BD8CECEF167E42545E062A73D8D94DC8E34D816980681567", - "sk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE67F3C35F1FCC838A55E60B917C1D420F5D6D41D601A05A3E98F46FD2530A8D929CE70C2D4B69E48CF1755A2C9786E88125B5D1378361DEBD87E61513BFEEBAD447208E14897188019D65B9A54D8BD72F07B0C7A7C855ED506BC1B6FC033BDD3770148045098444C22101AC860E416290AC008932271440209E3982962026643080961C4058A4089031322C1262EE1C248102949CC4226D4B488042251CA466100092D13154522C43003132592A4200B01610C328D22C1681905860897682340210A1572910008CC066C211881224384102941C420280A324D93B08CDBB44DC92208C83269C3B8004BC2440911494CB209E4A221A3482103A6480131604934894C126A18178A1C2045448084D9342002286610B050632090C9164E80B848A14049223804D9A48C0C228A633661094410E0B08CA1A0601002868B104603192AE0904C0AC08804A2090A299023390E19B90451C071E0C4901B0152C2442A83B88591267098101124B46851220011B88D011226C3A4841948209B3072603268D8C2201B43891C97200B3109882264C2C22D9B06691C1828820045602049E4082514820848B261D20461DA8664401824A222858A9625A116496216889148800CB664494842DC2690CA9030D8064E5C820008194E24856104072862026D4C8061C91644CA864D1100904CB00CA1A290A324300C462A004406E2B645888821A2061224A484D336880C208A822868D9162192861102130201114549286A04268DE34432CC984123482C80209201336A189248E100258B2065E000601AC304C1884C083966C3982D04C66D1B1202E3B2518448651C00801CA62D19B70994248AE046120BA9701C240A5C204944189204B16C81344808A0301821929B840D020791CBB8295C323221B04803064994208562086408C5640B182521854CC820010818020093519990016140052223008838515348424414501C078CCAB8311C260E21C48124338E5C087012054D8C962459B06D4148118484849BC42D13B77144C668E3C421D882655404044B486CE3C22400338640C49012C5408A28214B364EE20002A14491A10008A1C671D0202201296A881021D3987088A8604B2491D1126A512411D10644D39284C0220914498AD3C8001007640C327109914D119984413645D8144D9BC211CAC870223382DAB491538270C9248219422A83C82C8C964C9C006540102218B0489C00600C4448023830E212100014618BC0695BC828A21029C2884582964C13147009C411D9B29020A781D4020824026991A20810C660993824C28871C0088D589685C2C848D8A481CC1089C196215C4230E3B841DC40504C48460949284A4689C83206D93485580012D3144008472024341292308EC1A631CBA82144B65081884C63046AE4B6810B20661C490E9B3611E0308021131202220490A800DA86690B020018C788521872442292A21628002845C2222C19306560A0409A40641324492303911C069213464A0A09128A082E81960C8AA06DDA304D0C854D5C222423330508932CC036311BC12852286C1B1751D3226AE2A2298A36285412311CA44804B484233989D1209060282ED092700B0321843482180331532888018120E1142C90B08C5AA09100B02504344ED93005CB12094822889B22044B4468003761944604904410E0B8012331850A2624601644201911210230CA2845A2B068D3466482884C1A888CA44865E31641DC12044444081AC080049104D222894C164209130C22072183366463B8084BB84051B46423964D4A122E1BB98442A665A4B22892248E9B048193C29098148952B090D818045BC870A1280C240404DCA231C28248CA488501B34C62120D8A3429132530E39064A3226E64C49122456C524611C0368264B20C80C091CBA8080C4480D4385282A609C80425C1082C0AA15142B2701BC381CB026DE02232081032E0264463000024C88C02A46C6226609A048D52B800018701C194411993508248500B48296232858B104C1AC57198484C03404264044920C8411940909AC22510A79100B3094C00728092240208515996085B362A228651E392318326481B382D23092E8126008A463241A82CA1462060A60988362E11348008B42D1CA324C8904C1BA54C20280821C684A11042D912881A282A1A405C88893D0D875D4B138F7D713B73367EEE0B0BA8973A1F3755C4AC11764B147CD19B397DC47BD99B7E2DE1455B607362610ED43F2532AC40377F3A637778DE4ED4ECF200E6DB54F07A761527A7EBCD2CFE22051E07CBA0DF8B953DFBEA83054AE29CBB6F6E8A85CD4303E2186CCF0C4F2B979EACCC437DBDAC0ECD89B9D97A548D40B699FCBDF8F03565303C88D23F63D4E79AA5AD78BDE673E5655309F6D57A485860FF4D9F9724AED4B0DD4A2F41257CC8ED3B28B4C232B346343BA371ECD712757CB516B1DF171D22682D77F71A5024DC31209EBF41DA1C408DACB133F9B8256B9022F59B439EDD5209F5735307865CBE687E0392C705C80CF7D31FD4E817B12488110A675233FE76105C040F720324AE3DA7E18719BB171981F3209CD7DECFAF201ABFD28D7E8D6533CD66E3B3B54C7B6854E5056057117A99D413B3C419E3C2A22DA0FBAF3FA0C87C2BBD849D9971DEA51A6A022DC4BBF16F8E08C7F2FB5EC892B18838CCF4416A38E3BBB39DEADC270C338BA467B45B531C98AF14B920E46CE50AC0C15F08C70DAD4A79E7322D76451F82F9A4C4F2D42846C5282D08A0A74E4B1E2F6F31848F1D47BABCE24EB0A435F4F4344C8C44EA295E62C909EB39773BCCFE1196E85191F34B414451F99180645B1ACAC43E8DCE346F574873187A84814108CEE348A0217780D89DA03FA80A9808B97455944B3F80765F6E74B8302308F18BA36587188A3C24D39C928DB1AC883E7D260E50B7F8B36C2D1FCEB0D581BCB57087BF5C1FE018917B09DA8F04C99A371BCC80514FD78E262A0C7C70B212D714730380B108732693FA8F80332798485AF1A988BD430B05AF2B82CFA761CC34F00AEB64CA3279EFAB0CDE1BBF50B6D6431497E7417797A1A7E58459D30073A5163ABB6504FE960733D6789D469D0A344BB719FB7454F60FD7648AA6BA34014545DA6F386CC4915279D549ABC4EF263B68DCBB9BF1A4FEFF5E729834394F2B82B95DA66A352752F20367836D01FD2D0F12D29195DACFC0151D5D5796357741A8EB32299964F9FB7077299A6343B69752E8C9B7D07DBAC9C88C91BD64D0DD16A8435F5FD9F6D809DA47C4C73F47E1A1DC203D4B134D8620C8C4784D216C7E0F650874978EA4A781B054FD3BB383DADCECEC7FFE4F83677A38A8B351520898F29EFB26E64F63113C68C97814E140A7183C5875AE4339A6CD08988E44B9746B6445D6A9112F26DD834E0E26808CB1BF7DE16FEE63C95AC8B57BA335F34AC183C12DF9F02AFF1D785309A40CE9E103BC996237DE8100D1B9904E358D56451D72F5EAD3035CD315261AC8D6B3733515656CF02123155BAC2C9C5F22AD411D5339D7D027D9B3A040E3F7E5FD0B6D9FA119D19F172C2109E43858B609F975B8BBDB64BD2DF89EC26A1FF793BBAF8AD331587A23F3C91D1EF1D4D3859BD31F48888AA2E2821E00567C12B4F3AE880E3A5D36D64811681D8D5F2A64CD9E7B0C82F2FDFCFF190D323DCC96C76816675BB9683485755BF92F1B4E58165779D583D5DE05A172EE3EA77CD632F4F96A5ACA618A4215806AC625822A67870EF4ADDFDF7953EBDE41D7C092A3FA3840AF0678578CA1CFBD570A93EC1AD52DDD876B7D45DB23414143398D14A534FB6D3EBB2EB66A67B9402EC31DE21FD064BCF30187531169BEC5641BD6D5AB835B62146A36CAE06B4CC0A2CB9740497981A915A0F4C47DC39D5E3D15C6EF289EBB5A1A8B5F151AD3AC441DD2638117692F42561DD19E89528A915FD8380980E69F46B1700CFDA67CA516B5A480BC617973603441B6CEFD8806F03D90046703259669500BC8D3FA1CA07E4A68A6A63593627DB52462C16C340CF4D5DC365CD30E616B887BC1CFEC39B6D14F84B89766F41A9EDA5E5BC73557E27365067A59D3E971B93430749896EDD778A81BACB6C60ACC0B9F892AED912718D51B06426E2F2EB8474C9476815081AE71DDCE4234E2021B56337A3A8A0F2F5C02A9024A6E94D2362F17FADEDCBC7AC6F7623DCCC3D971CBC1FBFF347C86052E3DB823055A73769834D360030A059EAA0A24531BACBCF681FD29AB2EE5572F0DBDE188374306E9C13684B7363DF8F8CD26D1600143424C06BC9A5423EBA825BA610BFA0476F94336DE1BD92CCCAB73407D6C2257ECC9A62ED558CE08F73D46CD7D6D69DB8FB0B31D0CACBA5188F87052A0A832AAB76E9FBF360DB1534F4D43860A80007738870F6250B2ED025C6F1E3C0FF5A574CC789BA63C4B6F952ECF2332A74D9F1E585AF38F73F7ECFF37CE90B8562D50F42608734430F370763DD631E7078ED2016FE17E9968D43C409044B86008852E284FF5D262D05A960976A790F9223FFBF78C4A2F347689222CF4C30CBD83138BEFB46075EE28EF109C9CBBD1A5E9F83FEF060DD98415428E0137CD302F7DD9DE430D031BBA25A641667691CF8E64DC471D5A2E2095E7BB2CA6589CEDC60F2C72E5D7C310D4FA63F3DEF1981245B308CEA4EABAF747D4DC37F77B1E532145DB7451C64B877875E8297BABD554E6F14C17B80E68336BA24ABB7D0FA5D02DBAFB105711429654EA1D31BE03165E7DF097B91D55A0A4DE087231405EB9713A225E3AFD7A607939AF07E17A804FB034183D7A2F68BF203B46D3EFE7EDD0527F698F8B5E31E736DDBF68288CB9F71F1A649448D960178105DE170AA141EB6BB24F33A93FA3DE87E0B7B3ED1C21F309BA7E7FCAF181D1FA278575E3B464C9A8F235ADD708F47DC6981BCED1A5FCDE85F5BE97233B8B08D794F34EC4E7656640B86F12396B05D9A3E73138D9F9401413584275BDD2FEF2794B63BA90F5AFEA42FF703266C19827550A162270979270A57824378A0B6A7D33973CD6A7C973AAD16112A9B65C110920F91022D9D1863D81CFBA5261BBB88491BB6A30DC5C1AF54E280EF97B718961A707494B52BB01626E9AEEA4514B3F3D4CF39956861BC7D566198909A6C7B4B673683974919BCCD022F8B69602C066FF1F400AC4B1477B860052DA996ED38A5EA25B6394F8C966D312048139D7795E0A02327C51FB9332E12AAA170B8FD9E812698F73EB22497857A6D6C91923A934F90FB05ADF11808951D8533E27EB57A734FEDBDA1DCE135E937B3081F6944DF3CED2238158C24EA96CD547ED5DF59FBDAB0DC99F9EC67BA1B29A7FB949D79BF2D40CB375A1511FF9935436373CE4CB6AF1721E824DDAFB17C233B254CFDE6979500F69A746E5ABAB4E9893A51A34675F422827CD23D8F47FBF1BF760326E44B53049059628E7406ACA5FB7E036C7CBEF9D536EBD13B6B5FF0084B16D98A88ECA76299196CF51C305EDA8AAB1C656EB18FBC6949EEF6E177BF53BE1371543E3B969A14AFFA7352179AF4686AE78936615ABDFC59BAFE63785D9B707C31CB863B8EC41F6846A19068C6BCBFE53C231DA97EB9E93D014DC7AC91E57F89B2AD96C2EDBC41DA01ABC1850B762740CF0D41E32D1865B9B240210F5B66767882170F4B70D890D3D26243D3FF816D564FD30A052FA9F81C221BC314733FDEA7E443B8659442CBF240F7AB1B8DCE657DC283659990B0511B4C45AF9275AE5AF97E3B0F29C7F9D5BF4695C06C017F6624E39E0FF68E857810CAA85C7D867E6CA49D34FC3564BAFB5CBCD33A8631701AC896E59BFFBF5FB12E877B81E7C019A409DDDD132019B3DA666AEF32CC6E900DD5C1EC750BA1F935274D1B99210CCC50F1424B42C159BFCD68B8F38D12CCD2C096FDE4970A12C251644FA891876C7E56010BFBD29022648F4F0287C1A50113DB285CD99B921876868F5674E9A00D1E6F8C63AD88D1295EE57DE3095050AE2B922F9A04E961C7A0F8D43AA957A00DD2AF966DB68F3DF14CC0FE573D0DB5B1ACA3EE7E95955F3D5892F9E20F9C16E9BDE2EA60F9E8A95964FD1472CD6118F55F5E31D765A89A79F52D89C7720058793DC269F0E93B9105CA4969C83B567C57A911CA26BB73CEE638E359F020B891EF2CB39350714717240B7ADA74B41FFCAD3DE206CB48BCC3D4AD693A6D9A8970EA2F9E2B22800840DEDBF5F7A58F9160FCD4F1444C28E74BF6798565D60470E1DDF64E48678FA187B92CA62E9AD6EB234A398B686041CB907E135D9D8AD429DB298B77CD0139AB42FE38D94EA1A26663238D351564129127D34AB7964C107F28E593AD4FFDA0A095B5614EF9C6E19BFE1B5437B6CB370E17D10E6D34343921553D672D2E6D614C56B45907CE9743E6472CE6BD959FF2AAEFE2AFFF082EECC211FFFC125E7142504EB398B8D34BB0F849CCAD124274D0F8ACDCB1D54D99DB85468CD19C96BB1B383C8079D5FB0267CFD7BCF0916F586F2554706F6F547961FA9B897721C8B6FFBD63F2E1FEE53A8DCDA34208D859D3A00B197D90CCFB6C9B7DD0CB419AA37D7DF9034074BF56256F899637389FEB731F67004C1861A8294D3EB2D8485BD9299A544D25A6841BE00C9F0E01ABC2F224A8F9282B97D948AFA3145FD063BD4B0AD7AD6C691569F19D053A85CE7BC604495BA5183992B97D9D52FA9A4E9949D3C4440404B1970FED773C298E5E198480418ED96F34D944416A7C89BB6AE2B8705E73F1EB098502EAE317916BBAC6FEE466A26077B662DE8C49FE740D3369B976E7F3AB087A3C36874E2DEF2C048DB247DDA6A2A0FEAF2BDDD7D064149280CD18D81866C2E31B9C04EADBC7D086AFA9ED63127CFA5EC4E1F2035A2ED03" - }, - { - "tcId": 70, - "deferred": false, - "seed": "BE8D7347BCA4E0611DEA6C735700DD86180C4B95CBE7FB27491F00C9445D8A3E", - "pk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF4400BFDFD81A7683D69E63112A0C53BBF404C0AFFFD0401EFA99346A90900A50025B74DBBDFCA7D6D3D3158732A2F7123241D3078B6529A6E170EC0EA0EA99A12FE37D209DE360D5F6D985D0F3A64D4B6BE15D17E1F7171D3569CD4CC271F8A4B8630F0954854D18D36B347D2EF4DA30729383BB5C89AFF73CB5AFA6557143C4233C4F5F178B4D118215BCE7FA19C6CE32F1B73C9DC6E20C7B2E49198BBF5A0DE3F6F4773EA9825F8F5EA1E80744ECF76F831D5A3CDB8292E7D5B6042F5B86ECB6388FAF6E706EF81745158CCF6E8A84A417D6AEF91DA5942ADB6EB8EADFA8EBA0E21A4CBC05DD9FAD44847B518A6F1560E30E6926E45E852A43A3A8275665EE0BDB0216B77AF4086281459FB912F3B692EDBAF4AD46E336E5ADBF9EE98214BFD1596F18D71B9EC1B394FAD799014D0014D340F67989CE35C574BD8DCDAD3C8C932B69A207BE31C074B84C6BA95B4667E07FF002930F32FECAB85B1CEC07B0E5017E93536E65E71223BBDD3174DBDFD3649BDA2A850966A4D5407DD6B5CC2B6EE5C0266CA77F3FC750B3191CA67A049A127644784652ED02EA37BBAE4530B00FFC20F7538ABD09157B986B4619539E99C0775CFF5FC22D4D2A605A68816D8CC7C214111B0EDB53A0F1913F609C78B8294968FC47782BB0B5CF60E82BAB42D5EC98F18F3DACB954ADA096E12FAF74F68624A1B656065175B420CAA238579102F5454EBBBA8391FCB059C1AC64B7466A69AF6A2C3B3479939F22B774CDD41950F1872874F874C83D6129C3DEBF1746A35BDC51A3086331596C242A05A34860C07426E97D5ED9FA43B7E0B2AAF7546323517795326A84BBC3DFD7B2AF2A60ECD55F0C17214C76B68120BA3CACF063DCA7286174228D2C6D918BD1B69D5FF80422E9C7BBE2C53B9C4C6BDDE5A484C7AD19EEE4E04E5C5331B33C350A84D96E60A317DBF9D9EB9FBA32BC1F1074CF4E55C6ED35993A005675C1ECDA984A06FA93F16CC4BDB6FDE74E936DF0AA09934BA66E1A096ED6DB1B0438073FDC59E3C5033381D8268A9125766CBC7864D6583362727D11324A1E4C103DE210873D5FD1216FD72C443201C6B179DA770DF8BB6C8D65E517CDF2F23732F52659EB45A711DEDF5A0E67B9F20A28EBBA2C0E4F3EA21EAD329C6B2888E93E6C3A2A630B8AEB40F31D7250D5367D3C74C36D1C68F3A537AC3351820BDA795F112EA80BAA1D2217B65405957C52434262C10CB556C0B1DEEC1059A6EA4266DE19C05C07DCCD06DB1150D24690355D6B2AB11BF4872768C339A4445AF61DF7DEBAD342A617A8C3DAD91172EC87D12D14BF2FBCEFEB7914C5806E0403874EF87C2C3C31B71A419134AEB3B57315B19EE5CB661C7DF9370E476789B493BF8B0187481A34D8EEABB828D2CF0C014E8877C050D288324ED8ADDD7B888CE3F6795F4526646ED176A7252C58C61449B7B339D96225BB5ED2B78ED0646B0A6AAB394FD8A199150763699809BF58D5FCFEAD0199C8D6C68C3800474D4871EFD1D4CA94D4890D2D1181AB759CB914925AE6EC91A6ECF11D237BFFBC352C280AB2A7184798C0BD4579149DDF67DD1A242AA2B1D3111CF32C23D64DF2BD617CDD003427C11F968628DA45D912E4B7468D6EEB3B99702F2991E6BAB9528DB72C13179383D41CB6A89D06B6FE014400668E6FCD7FAD91AA8B1D1ED618892C1C490BCEF17AFB653FB5CAE9FB09942E14ADF650824CC83E34A43982AF55908C20445391CBD8EA1BFB96F87E518908209C1D173E80B71E7417DF0DD98849D907C99FFD83FBA09C113138A51133D3C246A11169B149820CB37EB619F5D37983B6C6B6DCBC48CBFC8B728AD9934B29E9669D2CD5F427E22AE1168557F80782F7F01E4E5C2295D3A04E771DF0031B4F6974A63F9F709566A01CF9428F791AE2277DBD58213B13B91AC09330729F9B3F2F74391AE2A42B3C85D1713B6BA7DFF0677C7AE4168FC2B4C09F3253CFBBE2F6B044818A650026EA3D9CC6702DE4DEADB688F52C8774E91F31D7466D4FD5669366C1CF7D5686FAF6BDBBB03B5BA479AAB69BF6E5FF369CEA5765AB55C84B4F96D8993A6E913FD9B7CCDBE4830BEF447F66EE983A6305B03F6014E4DD0BCDE87C30EC7DDD3E0CBEB22996736E97E7AD0C94B825CCC7C489DB3C271D84B118FF68F59254604F12D22141E333AF6BE5621C5FF8A7C1D8AAD98E6EE69EC17A520F6370B070B48A804EA4DA8FDB492ACD53979A61266F93E296E89C4E3C6D7109B83E3BE77F81631B1E9A07B14C9D5CA2C511D640D2DF07E9E66D022D2A71E2371C9F0BB9379476AAD6A76A61E9282BCCE1F13322420F85EB96D29846A172D916181357683612A39C94D9FBAE611DED9E8AC2EA4CB91E2EB37494B58E33A9A661F5CDB89E7286320EE03D46138D5C62EA17382C3FAD1FDE6A3249F235FE65D4F1F62BA26510726E2E1ECDE0A156A01BF88142C4651A0CAE7D01E9987CE9BDD691EBD2B90877B29A10824AED9FA751753378204E866C755B665B17F9C8CA44A1B1D482C7B9D7533C1C96891C9F1D98FE727A286C722F3CC0737E90AFB95BB75B8A4BE465C61AD94A8D11E5969EE5C594057452EC61ED6C5B21E4CABFE07CC00DF5F734F69C747E79970DC20726F7C845E68B4C4C4F38743D716933772714C600740A9D7528030C4E7DEAAC03EA018A2304ABE5881F10C6D54A53F5203E7B65FC15FFBD40FDBABCF4F0C6FDE7E1A69E8659657FDE45E633A9E9837BE399CBDB6F06E531D62F5B5F9047D88B2C93E0603754B7D2A2CD6C51975A205F80C5FB0AFA7FC745D7F09FDB010963FB077A1DBCD1304A98256FB8C55FD86CA2CB9FB5321881D723A11CA9043C3ED48909274820127DD7DAC77B0BA8C29048962C77E10D9544159E0E9CB80CACE205AFACD6F38A680411AE55D55BE0AAE59F1A355ACB60CCE7E37BC3D8EB96FD8A8BE3E41CE80BC561A16957F7BAC93BE401F896EA0A76B56D8F34998C051AD8440950C3DE11583D7751BC29F1C5C5EF72D1244CCE46932077BE58F56BE3885618BD33265CDB2FE482AAD6FFB1F1E709ECEB145E05EC3092951C2C9C8DDAD869AF09DACB5DC161E4836147CE63ED46CCCD5E453084BA229066202073F1D2A275D4689A187F1271CF31096A1BE5B5138D45F88D385D0B0EF2B43B18ACEDCCF8890FFEA8E00DB74F0BF5E11EC8DA5C4D293A3BC5D957C5495D12B1F8CC2D131DC9E74679BC3C969CB50B06E9FB4979A81A02BA1F2CAECC2F5452BC37EC370FD00516E71A949B3D39D9E36381E061E7694F467290726E35DF4A7D86FBF5DC59F29255C0C2174A8AA5DE8189AA00C3F00B173438CCF7D19002162B608F79BD3CD68C345732B914EFE4EEE05C6951867BCF3E0663BD9EEB8B543D9548E8DA9643D3A691A1599409850528DAD2955E6A2BD84A7615FA3E4A58DAE63F35DAEC6B6A0000714ACF78C3939D97836E623CAABCD5ECFC71B8C20AF2ACA289160765C9AC91BF9C64B624337107A9B890738AB3CC92A1A5FE53C5F9741CADB323A310A7376070E941D35E0D7FBCCDC1C45D5BD65ADA152CB38FC786F230A71C47EB5E47D6E25AE74D0615F6F3CC0A27154F43300F6B6993B6613AF45C36C302C2327B7F496AB0", - "sk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF44FD2ACD1FF283A37368D3B17D6A7B80562452A6D0EC2BD04D0FB88621954FDFD96735F21331D6E77E8B6C8B93F7FB809353C07FFD5C703C7051EAF4EF1BA870BC6E0AA204BCAEAA3E31FB6C1AB0BB8C91FCBF6F63FD3473AA2A9C5E53D03D36C20B328091420E21954124350C83302102B96054B065092930118085041790C22080A3186592142844B26C42B6090133265BA44C4A106243266A44863040A45020B56501486013B52D14436AE120059316625A32494324641B3949601284D93268098024189705632280D39864DA482091C82CC8A620039581E3A62DA3126DA1207103B230184470934264900650902490E2964D23C8105B36305B304C003190221571C4B26943064A18155153040D58240444404ACB0642E4928DE2368121030E09162284468509070594466A2409661A412AA1208244308DC240649A4432549040212084D88601C4888883045061A02914095248C0119B106A882851CC086421358E14A661DCB42DC0B824134092A404060438091122698882042182481187101A1444090730CC8245A444100C022508152EE40820C0144512294D040649E1443101A704C116211B424A09B4481CB66114A145038791113331023331D338308B12329B000292428414B94C4B426D0805060239681A83501406488A262DA3C8001B036C0B94098C344C440832D2386ECA384A18426D09458E19468619A98C04105003312921002ED4401283069148B28911A56CA0084E49324D9040691210261BC36823302C084742A214802023881C3526C1128D98A6509C96311A9484644486E2A064C9160E94888004226849202A1CA11114820093368CC1C66D5A848C49228922C830DA18450A006E52B4215A848822B48409966554444ED432694CB02CDA362144246EA3C440624031841880E11012C3366580A4111C25020344620A164509470C22328C9BB02144288D89B00840024C50442A12C44002C48880344C11016E1130480AA2815CC84D92188E20252A5A344091343099A22100192018C58C1441218C824918208A1988299AC4490402284A025004064514B505DC18849CC40043282564262D0AC3085C1646A0B02508189212220D9C16200C33620B818C8C480110A50D0C336E4C88291A948521410164920D9486240C4808DBA44198A6844C106A0C984D21A98C82260AC3269212C550CCB48144022A00062049A861890611CAB6700B326411345203802961326A1429081A3090DA302513238C83380553320403172D8806514B86901BA6484A242153986CC098300CC4700226919BC411C4484E1C0960020361818230A2082D80048C01B500C138651BB5280B116288961192422652C88510411014C86109320C19486A1A21240418081C096918466D032168D4962D0AC08100B631C90848CA1069C2C608D94281CC208160203160442060A4000B326824318603410AD88469CC082004C685C4C68D92240960484219408C01324C64B489D9C26809890C1A224A1134601206694B2692044889E416629286910B838814422E244970092169DAA840220584D148011C220A12B4480A217220416AA1C86912044C0446704AA69150140491C0690890655B380141904408C7044004460A47868B480159406164207223312C59B4308CB2480C0971D08228582421C41825DC1462D0C085E3360E11B36802170A1C0529A4181261206098B84504456D0AB460210572C4C860A2920001942903A691E13261E004918416890BC24D61C62922426D13454E833412CC444E0B344841024DD4920451306E5B006C20016210322D48288418355104492C60004ACBB48022A864923620233892482409228445E2B660CCB2518BC68813C1442193089B828C53248C49362C1B854DD3B26923822C4A220CC8B60D13C9095A4831199009C944305AA84949022504B72810068662201044924480A6411108295A164D18068CD1448CD4A46521014203A00C1014041AA7659088284A006DA38425091346003930A4B66964446662324942468421494A5B00846224450236810989480298709A903199A02C40369019B380C2B2610A300C02454010378419256E41946D010488E3B64808848C0A1042180665D93405C1441014132C11C04D5C4268D4104C403690DC860964184691228D1C3468D20170A507FDB4E85D7F3A939B1F58FA6E23A8E76C8D110E2CE9D794F066C0ECA93CEC62369E8AE09D91EEC5237B52090045BD6A9B9D90D7C4D9709E43C83302885194AF378EEAAD715716F44A31BFE4694EED6581FBB187165E925114196CFE661ECE9F29B0F3FE4F591776A072C4908768773E8FDDAF33D7628C00490B2E42751BCB3D0CE4F94BA23D889C022CC94E7CF002AE28FD037BD0EA5B52BC24A8E781A37E7E3C656ACC219E429E504792A9DDA870FD4E410A83CCF7B58B8C98834CCEFFF71FB9B744948AF5A67F25C1D61B823585E6CE1A80D7827DBF142CD11771BE47EC2C625575D1841220B579C307C59D5C94AC4C83CF5FB060E473F13C4DC8AF10B795B2C0F96EEAF8EC24992BD40CB166EE55EBE75DACD55CF7EAFB3295AB88B3E92E499460929B728AE6C2CE9335124D34A2181E5E3CE485807F0D82845DD8B8097E63B3AAEEA170A9A33AB83D710D4B8D761CFAB70ACD863DD82E6C6E882C1CBA9FD25AEF905F3E4FE2F90A34D970284BE657D93090481B541B2E5844BF13A491239AC03FFE9628BEC0D29A31B6F4A7186BED829D85C15A4510D80D3BE6E21913221CE6E4B556B0EDDE23DE1573563DF9262373C2713D4A9553C6752F37E7F31AB495AF86B86B4F3B58075DCB2B0DE5E90455CA7608678D102BCBA5067AEB49A0F6F149A14F0F69B6E47CE388F5FF2526C714CC698CE76E4CE6661B6AF65725208DC2C03677D4D96267F440122FB85EE1E6365A03C81AE161FA6393F4B3D8617A5654F56CA5F679AA8AC433E7C1B753908AB22BB2831FC00AA9BF9F98AC985BE604A155DEA2CEC22EF7A6F152ECD49BEF30300BFD4DFF5BF834131229B4263C3E8E37277365B3078994330BF6951B2ECF80815FF69F2507946D3B22809B1C7FF75D48FA911CD6A13F8763C69D72585A01F4C3ACBC4E0CD4C067B262780475F886B9505033B219BC5D06EC5F6AA4FDD610BAEF4A313300BAE8A58A6CE7723C84942582688081A7051E5522C539DE8DE21F910BA8409A84A079117D9B85D856455B752C9125055605B4F45197B88B92F95C36844E0487F1EE7CE2FB57CF0B7CBB07930440DE8117BED892CCB06818201AE6959F9A1258DA6FB32538F6D4C7C68636039EEBFEF06D8FC56B71764807B928333AFD5232B2E3D699F9B1436E3A1E086986D3759446D8CEABB56FABB4399C9CA347D3A2DDF5BE3F13F8F388B47608C01AD4E1335F5231E3BE21A57455B6169928D9B55FC3D0802781126A9E4CC183A4BC9DE0AECEDBE90CFF67301A7CD6DAC07DAEDECF4F639A4E71EF0C35FAF29B1090BE4BDE8C2C60632D62440BEB8368F03A6576DB06E2931273F355F94F2649A35306BB1981351085D38AA9CB1723D8C535BB9267FDE6C526B69C00D89D1CE44AE51125872E612A418975403BBFA35C0D4FC507F3E810EBB1B3710A670CB27D749F1445C310C353E59244C5BDD89D7D8B9F5EFED87DE0E331E687117C439EB4249034ED6CC1F0F8C1DD1DF36977BDBFC1068C850B85DFA7F960C626CE0BD34E6B37AEBE1B267C44CDE42EB2C86957135E3BE09E8865F42ECC25BEFB39396A7782723F42F211CBE18A37E5443256B3A3DEE4C6E436B7995832D62A450B15ECF775848C6B7DD8295F8BE723A885232C9F784A99DCF65035CAA2A143528B96D94FE9347A84FEEC81017080AF833965F716F08C5B834A95A0EBD96315FBFDA08F84F42A53392F40E4B4EE85B4C0782CD74E489D0C2B398BA43CD2EB1F202C4DF1D923428DFD9816D01B51D4DC0D93E7E4AC0336F058F1D122B500A4D2647F99A373816DE2E82DFC9D1AC7C50CE69ED1C0CA96E5B158635EA75232A1210C78A83E6201CB07EAAFE48A64CDB8E62AB122F9FAB90EE073CF65C8E977F67D9B5422F8847D8B53E917915963B4FD595F920BDE01A4DC6A990ACBB5FD6D539A35C8D1A9885CC227D175C7148C166D9BC428E64EA2E8024C02D3A1C41DA20056A3177C5FE2EF228A8BC89FAF9307F6830DEE32FF753620199B990129F2CACE1841439504BA08C46FD49BC52355C0DE4F52160DFF1CAE29404A9633ACF497634D47ABC680CD24FF360B32FC7EA3B49FAEE6BE85A9C983E8490D75561C3A12436BEA48D07A1E44DFDA08B4D11AD497A8B0176766A8E596715646E44995DDB5BFE8CDB0540CA9E79D50FB78D2BB403401D7AFF234A35D820333C0C114A6F3598BA35A894EDFD495722A233D00F9879DA4DCD9BB22766E8A31A017F2BA4F50D65C70D6FD25EBAC7A79C60C41E132A833C0A46F17ED241CBB80B2E2568959B707ACE990174EB94ACEA580B1EB7A4F4FB379AD58EE1AED4A3557382EA56B77DAEE6B7E82620E08EAE12DF1EEE4F32AB402E759D5544241E541B8C8EFD16323BE507747C80311BD92383E91E0C50BD6BB663D3CFFF1F65EE004C7093DF7CBF18A3D8CA1539716EC3892086BF9F07F1D1165564E19A53B3CEAA42AA703B5A65DC6D56C781F4D6E1FF5C7C183C268677415D8ADF29461C7D64083B8897365C90CB6FB0663877A1F74972E56FB2D1EE8E4E639963AD4661EE0DC9B96A39211326B2AA31D2A5601820780D3FBF98C0AA9B7BF9AC628934F27BBACE9F207C855D23F4D70D2D5ACA4B811E8162B1CE8E88CDB6E2A90131E7A147D30B79A2C753C3D01CAC80185B20DA14E23AC7802DA5A4F9950B4AF1E346E0E021777FBC7784309E18D2260516CD018B8FD66B042B1EDE8C9D6B8526CC0BF6150BB8F6C3C85905DEC69A971B7442479FC06AA17F417D12BFAAA674817469BF682918B51F2D5B7503F5B356624FEC0EA777FA7DAF55B343A0267BE6BF4FC58615B52E8A23370B2B6DB1722130F6E1316A2D1804E401CB1D62F2AEB5C3EF08EBD4F535DEDC1585AB2C7F9861B65B30FCDF25AD1DB9DD0F1FEA0B073288D5FAFA0BA4473A5C57004B3AF12FEE605BF2AAA44E19C13D3E05D8513797C0FCCC7C71A56DD232C4CD1CEFEE6D26A17ADFDEB206FDB9E450359D3AA61BB8B98059C6D8EFB18430B048F1F0353F5DD41F5DC4C91267D7C9E24CAA329C3A314544B044DFA5E8ECFBFBA48F3B115ED6F1D6B6E4CAB9E31EEB452ECAC61624A0B6982AFECEEE7EF4E17BEF17EC35BDDAF762D3C563D42E39BE18B1305632E46E87BEF197E1CA9A39D09944D8C93FB1B4D9F739AD3B967F0F16EC63FB35E582FEF7A1E3B2E225E2137BC6F2651797AFB60D01AE4D0EF1457C25C5596788F15AE5EDB62020795F9B24A3022DD9489ACEE2C3E393119CDCA6FE0A3052A1005690EC207C31C19741F7661898DC47B1F7D77157474A2C00D5C47E603CE59C5846272277C7D4C31A2046BCB2ABBA6C0E10DEAB577CF71D9F0C96CDF553EE1EC8230ED7B200946DCBF6151DE73F0A2B811C35B00BB24C7173BA4C9125A440C6193665D855415BCA4007CC33CD00767CA96846DF15A8F485DEED0A21D011259AED3E1623DE0EDAD0E4BC516AF208EA242560627F8C36178FBEC5B05DCF2B5FD3BB72A4D993996A03B6CADD20DC3CDB8EC4219CF454020C4B8EF1B8BDD401ADD90FBC229D1BD3AE5728AA2BF7CA5E3630E63D8A14FA42B20E9B0F412623C371C6B7CCD60DF4B979A541FD21CABEF1C9D56975848126795BA1CFA451448762550C6423A114EEC6151198ADF1D5DA22C8C43EFD81DF965F8463569899068FD168598D168199737786B8C70F4BF4062AEC00FFBDB3FE78CC056FF1F0E6F0E6EA6E7DED51105485A39F60B697BF8C0DDCE72F754C5584F31153FDCEC4AA664F535F7926A89A5F1EF06EF9DA943A2C6DA79D4DC1753C42E032CCAE7510E37DA6AD20E3BE46CBF901834C78482D539B531218F83669565451443ADF15EE2B98A90A344DDE8D373964E69785139A5A7A285C3964DF177C823A67B2601938AEA360231A2A368B2A238E3D15A265249591B7D64BE7AF7598FB92202177C3CADECD5244F3C2DC503B6C63E74C27A3F6CEF73D216C4789B7DFF9962140313330157C5C90B0F62665A7B386988CC6924397807E1F2E28CA147C2028EF79D55889162686D8BC9C0391C1169515024FC5E1825E60EDAD1DDCD6E52684F79D25BC15249E01605EBB68DF71935B643ABF034FAB9202111D23813686AA284AB1276C089056E29534660FA2401EC2CF950E90BD84A742E83DB963DCD83868C98CFCBCA330E7D3AE30FC5FFEBB2A986EA6DBFD0E11E938DD3A3E19A6D6FF277B9D2CE0F556EF725560A0BE782D3F4F6DDBDE8C1EBA97F1ABDD9790DBBD40FFBCAABCD2065C0B25788EBB3C9C6D0C467C6D18455D3DD36B90B0EF0A0A3784C658E6377E93E27ABF4220426C90530E7FC078EA863A507F2D35FD10495819490BC4456FC6EF09F74A6FDB590D00EEE79C2B28268CE62822D73B94FA35B15E2419EDE1DCC6370FF6A43EE2CD3DDE1FEFE9C79B4E6324070F6539D395238B6E74F0E45303F526C1E0C21D1C60D5FE89C722E973C9228C8396322D77D9D5CFACD112D3036F8D6C9C36B4D163131E9A0DC2AC69E33000669704B6EF7B53F035398BE08AB7308B77E1590160CB2236DF3A14C59B3554F460C56B83BF1A2C6DB094F01A42E371F2DB19034358C6B62D3B028D415325315181D6FC7AD306103FC2E9CF9E1DC3587FEF8FE45606099155B0C23739DBDD123CB0EA801962AF5745ECD047717CA8922EF9FEAB11A45397B70C4149DD64BE94B75F0772AB38D623A6DE8D26D5209DA6F683A" - }, - { - "tcId": 71, - "deferred": false, - "seed": "E4CA0A81DB7A44E5F3DAE5B9770DC89F15F02126C3077642B67B361B7A75A9E4", - "pk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AFAF5C7E1BD67EAD28E19515D528596C1BF06C666294A896F79C09F1D21EBC70114085BDCF824D71D95EE4947E1E3EA0997FFCB4463CE552D31F0359555242B134B4455F3DCC906C4316DF185DDF332D24F7984B531C8977CD997BB0DE517AF11DE8AFE89150839AFD4A927F3CB5722E8C01F3DC10A558901689E7D7976580BAAD1FBDD9E390F40B045CD83BAEA0B8D8E254499E1BDAF0B69F9FE108819CA35DF692BBA250A2E381F795E25E244A2B6B47EBFAD304365E692B58BA89C187006C68CDE179621A43E5E54628C080F15591B0C1F312DA3300C4B760552CA99AA294BA7CB0923294CB53C22909876E568D125214936DD978D0E846C4DCAF5E014232672E0C5FC33985D32B9785D754D797AD9D5A5C45730F5244BBB470F765E194EF081FBA4470BD80F8CE9698F0D4BAF0B4AFEB8BC20E90A7E4F7E4EBF8B9DF483A3FA7C723B982493C7288D47CB4752285C8EE1766EFAA450A5F7EEE1347BC2302815989A7F218A08163776876177D584121E2A47F778B516CCE9418A9F55E26C8C02E4A063B5B08CC7E65DA00AED0DE22361925FE57A06AA3AF9C9C380A1699947279CAD5616CC515C677CCAB310547653797D2CD344FB5E4A1500BDA741CB36174B17618088AAF50867066203DD4B5C4488767950D9DB333D38482C31C0ED75080AB4381429E4F22996BD79C16DA38B473B677BAC22A0543BFFEA798AACF9792D879654CD01F4471D447D31B5B65F98FA56C113E19AF22861E557A1431E6963BAA47237F618DDD85A295BBC1D21AFB59404333119F816C787D0AF0A1D72E461D1376812D02C5951AD7C5656A1A6E163ECF6A80461C5636FF561BFFD0FFBD2EF0A3E7121885F474CC04D34BDC5C677C031932EA22D64306B5DC4D7E09B3E6F1034CA50E3ECB3C8D18B07B2954E7648DEEE772AA689630EBE0DF871B4DBC69BA812B9F9B7E7990FAC1EC61A85189A01EC81A0FA6431153EFFB49FE7A6403A63FCA28F9AE70E50D02109E9176DC51ECB0ADF4E85C55EC558F6F81C3588A21DB82F26FAB0C2A3F4193F41C2B31401019A491332331A37F2E4CC465A3B92D23CFA7D7087C548508884B53C191E5E6C31927F3F87FE67BF100850C036ED5C3D0608B4C31B6549353672A1DF0F45F68EAA6B4151264C7E6D8CC2A6259DA6847BAF0C3D8132001B094137701AB4D24DF93E3A0DFDBD9D6F276146AD21DCA259F23B4ECBBAE815A850EA004B8C692B77EFAA3346D5AA55E960E9BB23A270A4651058425811AAA77702A74BC60A8BCFB1808E15A022203AA2337D5A3A4815DF05CBD4C2D7C49949D750D745E5180FE7B3B5734445E8D9CA7B3BBA4AB3EE400D2CAF1E51AE5068DA38C7368CB2F99807B02E61766BBBD9A923CB75BEDCC7406B5C97ECB6CEC70D1E92BB949B9CDBCE4D94E4D63950ED163AF96CB8761DCEDB8199150BB3B8D9A28C2EA3C0A13B55BAAFA4DC2B4BF9A697C5769215394EFDADD3CD91387AD25819E6C673B9E2421F8B22465B91E62539706579AECA5F61EFD0442BD8D230BF28A45E133A3A84E670F645CB9EC726E84798DE434E3BD79743970070BE5D96BC7C59050050E51BDEDEB74204C546722C62180BE677BE5F348ECE3F1CA8754E56B4866362B3F85DA70039ECD2713279ECCC903F8912492A320265922AE7154782904DBB5CEAA41BF42A612FBC7778BEA414B72D304C0F9AB839AC3F9844002EC0936A5AB70B5598C7A2335E6B0827B4DB3FC9434AB37CD12DDF8B45B0742155D1278B823F95712C9F437DFEB37977C96A61FF58BCBAB7DDBB45591D7CDCE17FDFB4793543163DAE9EA3560860DDC797FD3A9F9FFE1089485DDF004A2E5D3420A10AC4D6332022C18BFC0B4B762555BDA20020AFA3CBB33179E6ECCF71864C200466A28D39DE24FEE24DFBF05C931B215490621DE320F5A5F8221EF5F4F085BC873C0FCF60E0DA9C30D29CF2375A98046FE90262C881961855E7945428CD255E9B3266D34844365A10F04E533C489978D055CC749082BB49B92A574F5BD93DF9751CBB7CE3B065819E0E46ABEB2BC1E01BF31F69D4D04C752D57A4AE5FD2548042383C2B3BF4D9951F575FEE99205B52215F4FD67285A47F13E27C0FF48D924E3E24061983CBB94CE39EE6FB94DE8E8FEC2CDB43D7B88592B9C1DF4C1FDDE728322E27C99BACEE3C2B40F4996F27565A454735EF4977FB116921393E964FE2F06913ABED35849782282688B2D4A05EA0B068BB24EAA04D31B0DF024CC845FF9EF6AA358957170000BEEE474BA05C98DE6A3A7B25C3AE90FF347E231841773B20C81013A6CCE8BA8B0C048CC24CDEAB59BA03776C151756C9F7D7F26801C5DE1D0A89ECF3730A7C0B960B8D458B7724B0B6C9BBE5ADE5232FFDA9BFE770E3A44F25A030D6E7437A43645C32B3715A72C44A5691DAB8A22D8F3743E5B286DD8463ABF24FAEF72D69AC2A13662BCA8BB70DC801327E5E6BB0A491564B03A33E1EF4BD468B8645338A3B0963DAF439637E4F703B6C753A5CFF812D74C909FC5A5C3C74D128EC21134AD835DA5071662846DE039D0125EB8DB4F5756B70144AA660EF354F60207ECBF4E71F78159F303DB891D0B553C8410260C8EFE95A5253CA0E6DA8F8E242BE336C15B3DBB784CCEB89410FEC3DA3E11F3D08F32556D64CF9908EE93A7CFB4A2464B8A91A845BF17E40DB9C4AD057D900FEEA19BAB0001C62203922108091940FA46CA09DFAE5AE61C49737A1A927914830261F214C97AD1BC95D3D7ACF2CC18504A768A6CA528049CF80D15D1F75A14542403BC1842B944628FB145F86CC2287E2CA2C474E9FE18DE39730C2CD48AF092A28A8E10EBFE68E0D339087BD81E3A6A13209BC84BED40CE38C3E8DD9ADA8E7AE603BC0FFF18224C2623BF1553070B6B8D247ADC9E3DBCE2059F9483656BD0C7BA2073CBAD822D8210DF3CDECD4C8CFD0E31E4AB8DAABD954C2563236917BC3B69D7FD0233A6727662D74B1DACC59902A4422DB75D49BC542C5BA53639591ED5E08A74AA80A52969C7D3B0DB9E974642734A22050887265CA80FB9D04FE6D67C8C009443386EC676C9DC3A0C6A3DE7F5068E0BB21255AC5B56CB0BAA51EF66BEE9BE3D55E836B4CE8AD55137934A65B53CE2C4D9877D31BABA7BAF9DEF94E13BCFFF1D419867F2CACF758A72C96F02F6CDF0D9E392A331ED4A712CB0904EB9E3D6E2F71740EA439F50E7E53AF0CF650680F9DFD52F6E013BAEBBC7601E1322656B0FBF8857B68BE154C3ECFA043491D3893F78CB9737A45FAE9083B99A650037108C8790B4F5C37AEEC831B1552519942DE4ABD523850D32B55F4ACAB3CD9E589067875BE6ACA634348C361281B48C59A37909C23CFBB11868169306B775ADB7A9952CBA481E0AF03181F6C0479C433DDB38DCF3F76A1F57BD79CD1DDC5345C0BC9E4B9322D0A65E9CA2ABC2CF988AEB047843E65C46B94570440B66F0272F182D2203DB65B3A62710AEFD4C1FF9D540DF3F83B04EFDDCAE5F66DD9B6E1137D6E0A6B3BBF44A995AFC1BB78D66E9CB70198D4EF8D43A35D2281CEB56712327F5CDC8A105D7C3A54172C5EA0627390785B7C47C0378B7B102EBC78356A64AADEE13048F0CA0E83359D1A5D94", - "sk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AB2A9D6678985CF8786F69F522175BD04F4CD743E00045D3D4946EE206845D21DA867F2611FF3003BAFB007C16E69CFB635423A3A162E27876374ABF58E3E14D326F06FAD2505E77263BFA84A72031CC9AC22D96945D266C21CE1C43E993EB953042722C398881B106153423299A8480846525828211A150024B46C14A130C2A66024A62453004412172D02B2080C16628806311C42099434801318862106515B226182A605D43489232705194668413229D4A82D102852520260D2324083C02981C4301AC509032724E3A4314A0245131345DA8270CAC671DC4265C9822019972160004161186820841013994D63208C124592D988640BC06420186E54B68940B651E0203089C6001823100915415A404D443231E20026E44072CBB2098016700317681CA924540491CA804512288AA1368943080AC4A2909494481AC7640B144D180906501005D2A2081401218B184401481020840C02A25114C63014359013010961B46C03C97081428823861103998CCA346904827111C921C444251C312503432D042665C2142E59442E8A848508B909D10880943866991808A4020E5404464302219A2621038421A0842D10B040A2A4050AB700C49410D9344964B42403C08484246043306648B2492401895C0470C8B061190680E2084C00466860108CDBC04102041010A4048142519930415C068160089143866C49A031E4A4610C264409C628C8C40CCCC66CE3A29002898818C98182C0491B276A0B832C03A22C64306A010272CA428E18048AA3980108A26D8C98285AC208A1C691A33026A3928CA4304164C89122B96C8802489BC680C4060654404051A0080145051A396A1106311A46420B08054BA088CA88480800049912306198710328246194609234719C288D18334A014704841211A4C82DE4282589A68042462D18028ECAA8454C82211A28881C900008449200306024C53122A1850BA97090C02C4B344E8A80640134128324858A086863024022467040945114234D52308103381008B30DD3400D999465E1246D2438901932001B08401B433251C80CA0864C901862A2301151122918874D19266C03C88824022011122CA1A42809A4305AC60492244520986D12C50884262EC2324124134AD3002D60322224181261188112242C0A3168E4088D4012841B016E88C40014A00C04032C08018D58400203B24D0C93048CC8288A866508108114235100B6901B347014C204A1C62D5B10250A4071841671E0128EE3308E138128E4846091364A1922119C966401944420954C61C4911383108904642231220498690401280A9384C9422E0413721B1420819220E42832D8B0014B444623B2640AB88518046662444CDC2670D3328208B66D1319440CC1100A183011171100092584164C82A60823C6610213610A992022858521072C244465C0B81111829119B36549A649D4A83122392024348544384CDAC29108A788A438311813001B070AC9188D23B700D1881183A60C93346188420C52126CCC866553826D22104124A820D1204D0C9870C8442210C110A1246D940480E19881D320490C48444B26681444620C060080326888304D14C9701A198C81384A52C09111236D129621A23072DAB04C0CB825242826D4348C8320905C32925C1882C1C48CDAA6290813800A0410D12425A40822CB926C024302D1027291382421314654182E11996D24118408878060B40C02152C1B2331D2A0501B080D002929DB16000040109942624B88701287615A368E0BA0718C080A61380522346564264004242DD3424911154E11A84C03923040C030C42049CC902D0947011A0349109080124910110948194260C2C24121A50D20858089A4891B3402194930CC902951B88100B640E1104012B36821116ED4366890A421A04651042001C18665C040802116610280409C0821E02044193311842081D3288823438A14B90144C640D8A82122858C94B66913444A1911721B232EC042464336490881695B4050DB164AA28850CCB48812072D09B731A3B084E0C22914B82C59488E0A3801DBB82C19166D08A28D08B668532252122632D1B4800A408CC43251024760A08010910028499845491486D4B050008544DB8888C8420C83B46C22C16014413100C90424296DA0020218384D5A2250304FAA14081992194671A66FA05EFB40A6AE3511B1B259FC17FD2F928978BE51A64EB05E5DDB644C47F9CBEB76168F5CB9E54DD51F898D296E6AF042D12F59BF6FED3069EA304F979C28AF642EDF92518D765FCB5F34FC8354803FCCAE0651AF15779E7CC672DA376509430F14C659ADE2BC8075B0056DC26A74B3C90F9E772447E134269210EA86D1387FA10CA354C03437F9DF2A77962709CBE8770CE88279C88EBCF0349C0BFB121E018D1F46AAABBDF2DF379171F7526A295C65FED8A1280FDA9EA8F5D4998EE93AADBBD76FB16F5CE48E7CAEF9C41C19CBEB3880CF6EEACC849E46A752A23C646BA788554BCD3D218A76D88A01B991AD57178B24D724D0CE12F3A70ECBEBB531206D81CC2DD8265D673DC6C5B492AA576E1027F7AA88FFE6420651CC96536103CDA90607B38B8A840A963C5FAAAC63A8CC58CA57EBF204E80A6770A39F7A8E094ED5BC4DDB86A31120F7A968F23C1E151D2479631E6A9D011671F664A59D9BB1A0192115DFD813B0CDD61BAB1B6F7660F680971C4B55DA6EB791774C64DCBC8B8F0FBB3C57618E29DF5DE4023A7D9B6CF678CBD0107B62F5A05C131F5672B5693C23CC4DB4054B92DB2B3CFB59AE81328A6F265C49A302D92A8A4BDD8C8A832758FBCD76940E85566531A946D2027EE7865F23B06A51E80EAB7777DEEF62B1CCF6E7FA3ECA6CA495C88357FB45894578D6BAFEDBE6B0F6A8AB672CD13AADD9006101C9E98738819073393C11A383DEF2A4884B8136253D3383E4FC13A9D90483DE15D4DD12D85F3A03769FB77F23CBEA1DFE0AA49843578C032D881320C6DD3091D82D106FD26C54EF7D21F539EFD3BFA928FA8D6C74351BAB5FD6DE02CB02EF09848BBEBE76D2F4FDB2A484A7CF0C6A2484BE8F56EA052A1E02F4D7D19B0020BBF3958455E2960D4A7EC5B7C3BD93AE5F716D7976CA10E4E442762E7070920C9CA2E767FA613FDE222A1C42E135165BE4852EFFA36EC20DEA6609ECBA9D57EB47DC8738A24753AB72657F4B61A2317D7FFFB55F395094C12CDE5786E13F565AEF078B62A1B19BC4DB01FD4C4806CAFF88B4FBA065230A6028F03507B99611B5A9888D64EA6EC5EA6757FFDADC5F3F0538D7C34E5A69DD305B96CD03A1904E9320E28BD71FAD85C99ACBB30527DAA2926E88ADE20CC255EFA7F4597746DBF433EBCCB94C7A27552B7075D7574EF0B9C3F7CC932AE97F827CA09E8F4F109D9D48D70D39F10F1334CD583EF43012FAB8D325BBACA1AC63D0672E41D300CEFBE29C30DFFD952F5C70CF9FA0E2FB1F954499A7412A0ED2E5F3C9373C2EF3C2774A72A3D649356979EAB8E70483305F1CDDF9B5ABC0FE0739EF3487D3FDBCF3CCCC0FE4D6E30001278973577EA567227CF6E86116E796120DD561C56CEE924F330BCBFE336793D45B310B4ECF4D59B7BD35BDF0EBC9693BE646D6E6FF663E87F32CAC11E2BCA4DE5915EFC42FB1B390B1092F703894A795A2982999F0FFC55F1958FDBCDEF309DB3869307A72434CBBF0F8EAE903301B9B62A7785754E10C7F352D886DDD1AD381B1D7C4194A413B887688A6E800B36A75CE4E2ECDB587C99CC7C1D62D69D82E0569D5ACB77F8EE771C170C1377C56EB297BB7B8511C15ECFAD5E30EF7BA659B7EF754FC9A82CE1EC7186E251D7B2CD49909DE53CC4032270B2E8B8779E6392949F83D9FF8B9F76F80F5C85C8D1D9B5D88BB4F1107AAD0E6AD1BF75AAAE13E666691FBE698CEEFBDBA8888EDFB6E918CD3AA718C6A40316C8BEE208DA05C16920182618C0431237E7BC6AEFFF8A003DF6254290488D91FCF027DBB45FC2C6EC752C9DDD9435D8C343C1052A5DCA889C8B7B5705DCFFB21A421ECC2346798883D4A38594228184B85231113B94476472E972D8E1E41B224BB1BC50DC9ADE64CA386D2E2E86EA39F164519EF36558AB08E12CE2100020E325F6EFEB62D6154C2D95EE780254C8B4FA85D02DDDD85572A9E498363C4B59AF5F65D307B6E85A91ED3F1319F5E36FDAA20B31B6DD07A7E32FA65FDCBA46BC573AE8720E728BD15B1046BAAE89FA243208F51EEA38A627DB10D086E69F4D41522C42AEB53E5C71CD10D683A362D155193D998CF296D404DFEE6BE9315D329980FD414293292F9CE857321EC51DC255F47D55594C378B7D200CCB47DC13A21962C51799806AFA87988FBAB95B1CD2DB023B6B3FE148F600D927A7F4F3701632A784532661DDB474C682C670844CB96EC569BF96187B62A869644E17393B5F52998689F41D562FD4F1DD4847566C9683D5B1E6EAD5495B94709F11E393B758D63CF05DF6A041168D153044E4F24D49210D1092C3914C4B61E410359F7311E80D79DC9169209B7201A759B50C956534E5147873ECF46812032CC5EC50D58218E92C2B4466DDB89EF5FC7795D2B6A85D159E3F5BD1A2758DA5D4F9046F50FA96A43FDF09A6883C29821DBD5BE66FBFEFEF1D667996DB4594967A1C786C03CF85B130C89946F85CD156CFF490883120A9CBA6E64C2F9279EFB006FDFFAE654D6C289364184DE60B6F2424F3D473597D2987BED78FE47220BB72A8D81D8BCC850C4DF510CABCC0CF1937D1D39768E9E21D645C356FA2D16D16987FB18C14B8D24D5D5EAC9068719B38D418CBF64774FB15F32C473BADAB5218159F6BDA323A209C699B8EF093F34B60F022009F09B2E8AEFA824178C5F8DA0E49125170D47AEFCC010837623394B396356B053405784F232DB4A6ABA2B94D821D2CE665DBE354C8F69F632551F6DC897607398A32A5B9120A044B79F7FE2776C8EB3D3CE28A13D654E58F45E5508995576F3EE3896859DB85ECFA2E1AFA06B7B455BE1048D4214F87D82C0758484230A76C27241661C08F024C2D9EE1168A8D4AE74F297DA8EA70B21A0CB8CE6CF0441A937B2F844F4E61F1AA566929972DA86FAAC9986E08578BC29C4DEAF9327BE415DB29926300C1FF3D63A4AE745275BE7F3857C2C83CFD209C4ADE1EA3215FFF40BA37E9DD31E919CF1988A5028FDFB0BB42A4C0E5CE1AE608C92E2049954DF006182932415BD872F067930FDF8ECC7AFAAB7F96429A0B516AC86B6624FFA59FB11000E804DFE0803BC3C33E77CEAD6E4C87A7BC9A9DBED7ADBC60D14A17E6369E391585EC51297D1BA15A3521B7A84E09268EF44FD7072778963E6AFEB58C07843A63514F43FA56DD7B130A991DB5412B32BC3950EF4B4BFD99D72D119B5C75C1BD676D3BE15D3AF8CED24B0401D25CDE43C259B93A4298D556FD5896971595C6139960F94DCE6B0CDC00AD70DE34EBC6CBCFAF97FEA0692F8FD154E69C3D84E0D41F4D834602AF91033F7995B599A33B1142C81C71D4C2D27407A353B91AF878303B4779F38F9E679EDF5F8FA13318B899E443B398BAB9DBC14922CAD6633CE263C5AED77848359D60E8D1B96E605BBF8164488F9071268D69FE47C0B6C26963CB56541B8F15709D49EEC66B44D638B5628D075F2385ECEA51C9FA43D1D9A51A4FD9DE4E6A8A2B2F68A09293CD1D7F52FAAE9D6D0BC87034ACF0014CE0543A2C2003F07130BFA9C0B29C7974D6C9BBC45A7995BAA62A780F7A1A168720A12509F1876F641612E70688A6E4B4C87666EAC6C838528FB409D808B36AADFC5999563B5D3AD57DC12504C0EDA94DD2F043D6E33E21D7478B298554239A9FE8361F445C2515930C1D896EE0381FC14127BB072F9FD50EAD1C6CAB24E7F8A493D92B63D30E5048BD8878A27598A51E294244BFC8C33D5C0CBC2507311438546A8D001408EBD119001D6553DBB7E78F03DAB8FC785BCD199564512A47B6F020A5E57C494F7EB73F76498ECE66C799DF38ABD4DB146C988E1C0A3FD6055AD305CFAC490E18AA791243B7A92AD3B1D8CC314871094E9111583157BF9F02BB1823B0EF0341F4A11EF810CDC887FED3705F9DC0DC24FBADB842B5509D6324D468EB9255BB0015CEF339FD2C649684F8CFCEFB90FA3E8212331E22D976FDDB86359077684DC3398D81C139A8FEFA2808FC74B7C0A56439FC9DD2567D9FDC273781C9CAD88ADC6CBD707E97DB4B989CAA4E3DB3A2CD7E419E2939041410DAB36621DCF04FA9DE5D8AA38450C44ED40CCCDE3358D770ED5C358523CB2B667986D11CCBF1F6975C8BD7BEFA496BC9670C205E725DFB4F3F28A54790740D7D56CF20282795AC1FB768E9937547306334B37CCCDA4CF158B5CA0DE2EBD75D9E40D6B664B9EFF37E943BE1E7215A70C0EB3BEE3DC576C8196EB71D97DD62F58AD25C02FFA64270F63EF90581A736BB9FE4AF4334090E471B2FBCC38ED35D8F430764A4113B736E22AF6B7AD1489F1EF2C8BC52F8D4F0A2D06CFB9412DBDF67715CCA91B3877E9681B7209178D06FCF3130067B02ABC7F9DD59A65668E259B1DB1BF68C2CBACF5B36B3645D83B4A76743C33181D93C93926CD6AE28EB4A09B1DB597BC4A9E394650104F7974AC21147900E038EA8B41BB2ABF78290B0475FD8BC6948B24B5803B0F35BB76CDC9F432D5B82A251CB185653FCF87DC68FD9EB9D1C7F84338766D8230B0CB50061702D057E308D00C3A31EBD9561BEDECF00288E3B5CF7A01CEB999F3AAEB33FFA551F3917AD20AD24BC3E54C728EEC590F8EA355D00E1A54FAE5FABF85311915644469FB3ACC0AC1DC843F6F84FB0BEC6FF513F3F1D286996AD82ED9AD86BD51A28E447196BC9B05CDFB004BF2AA19425FFF47" - }, - { - "tcId": 72, - "deferred": false, - "seed": "7B4BB05212C7AEB83E3C04F8C9FFDE0526EC4E22E29EA84260A89292AF1E4DE4", - "pk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333644454CCF3B324CB3CB63B33BB9993989DECCC7E365DC5BA6BFB2CA61B49BE2AE657A20053EECE5F192374812B2DFB718D6DC45B46336AA5A230D6D30ADD86039FFA5B1E84AC2C0448E6BE453992287DD29E478EB0256552CDF84AEEEFDDB281138DE2047CCDA934FA337A9EB9D2F257D554C9E8163593302DFF2B21ABF8B7FBC319D3DB37B8A2E372235EB43A865661858A61B679F3FF11E6A03DDB1DF3FAECA1C4098686298E1070A1A5944D7BE4663312C7459DAD3F214370DD2B56F12FFE8AEEC8EE26E6E993D8341ADD70313D5E6010A771684CC81CCAF37D7A7A5FBA2CEEBD6B0F80D2A4AF55164B4188A5273CACC9053555413D8741B405D21D0601805E69300546AA837F968802C2CC2AA8CF4F0340B82001FA5BA71958FA5BEEC7A94AE095F02FC54758D2AB1401B78DC1E10910C97C5DD6F0D3076B5A09AF8A9724240A263DD2D54C16C4733551D9C70D89948B58E99C8BCCB03BB0C3CB5422169608FC8ED9FFF0E66D2109A024218D168D0952723699D3A42C082A2DDA76DDD835818C627B57A972AA51B1DC268F7181BD112AC73E436EFFEA1616794815CB1A37D6EADB92A1009F84A508E16EF9080D76DB153B6852F874EAA47DE5C338ABC83CFF5F2A99648A82C44CDFA1A50B11B3C9FBFC1CE38EB770A3531ECAF373C0F437C9941E7D0EB0D042F1EFC0B55F8EC97C785EA3B153505BAE1B52D97DB48F2D2E7D7E70E934F2C0F9943E3F9869DCCEEBFF0CEE6D1DEF7E4DD610A0835728BAC3C827B8FB92208F5B9DE25E43D93A6EAC1887F032AF66CBB5ACF6142C11DAC310F2EEEBD7FA25CB0C0F8F940E19D43AD7F5270A26365A01FF200027E173D566B5E77D98FFC1134F0628D241EF306EF8364120FBEC93F92E06058B2BD70ADECBDB9AC63EE0BF8A45F52CD80D753620D7089D6CC313FA5A759EA6BAF840271374BA5230487A928535F47843D3BAFCF39424E62693BE9712332D312B831019F8AF6F68FE5D0088DC979C9B3995ADD0B607C399CF0B8F651A057A96ED323A7EB597B51AF3AFCB9B99420456244D436E81A01B4F2ECE5B87D63EC7FE6B505FC34CA5D7373B204124AB9ADE3B290EAFE5AA73704902A2E3A404F71BCBA92F0675AFD825F10A10B4D51DA642ED0A9667C2A16CAA2BC77CAB7AE9E20D114DA7FFAF501D3D1783A58029877A86C8EECABD2E18D6CA58AD5F0961A1CBFD8A51BDB49EC3FE4EE5E796132E5671701305A650F75B4A8BABE4803C5727332D1B123508A60FD6D1961B267B4E4A418F4D1F2D95581280693AD13882433DC685B8D60C78414EDBD6A5946D571FE2D897B094C77FB5FCA27A9FEE9B6215886776F3843F681BA3A69453835BD4919D870AD573E19808C55A77642681189BAB4B2652F52FD6894F70FE1B63F31EDF0A1D3E805FF4AD806DD627504870EF04C1365B1CAEEA148A3193252927C8011A3976E5254815035132D7EEE8F3010C8DB2486336365CB7850D4E608E68974ECCA90000EA4EA4D146571D2720F79BE23C538161E5B558FF5FA40E63728B2279B1EE255D8EE65E2CC373285043CBAD5BD7A9BE42F6C282FDECE15C6CC49BBFD29E38F40993F8A17456DD3145FB717AB10353DEC3236F3F44FC80F853943B57AA08E8C543C35276D637D07F59CF67CD4453828542CBD0CCC0CA7A2CCFBD0276E70C119C37F9118962F0298AEB4663C9A1106234B4C55FF6517E775B275788263E24FE6AAEEE46E5D082C5336EED7A75ED3293BB670B49E705AB5E9EA0EE336EC8882E7FB1376B18EA60400BC9F66C112802859C8AC80C33B1309B829DA0D4C558D4D44449C02537593B456E842CAE22D546CA071A1E7D141D7808C1984E9FE431C62F259957469DADA36DF63D0E5C9BAE0620F09B2A3181CB08BB0E0BF4E6CCD34E8DB992DD8499A2AF80027FC34ADBA843F7AECC46D4D4FFC025A55B6188CD8E24496AB28F94896BD8049DB9EB991AAFCAB2EEFB31151724A19C7587773E3BA238137AF041139F0428892D255E361D375BD5FB318C4A39F524CBAE368033CB88B616DDC4B2C61A5BCBCE68F7719FDAD95655E759513CA1E6AF4D92AA96EB15E9080DBFB4CBC50399717B5EAE40E6927D574A8144B24D721CD2D1633BB276335846E2E86B2E6C843EC53A779B7A1E9CF5D94B710E824B321BA89C502D03BFA73B6B76BE8E330BF90EBC6059004F9BC8F2656F0CDA2B3B2018319B70E0024AB7E1095C22DB13F49E42DD3D9AC800D7307CEB9517567E0A4668BF4A0CACFBF1DD9C1C86D13721A026E2F4B290173B05F60093042A1B081A94A830E028B2AF8A31BB7FF432758F54B63B34E49BA2F15A7DA3638BA0F5BDBB2527BF49B2284D51DEEE54FAD5244CB85DE2AB6FD689339E6F89A20F803093E0D4D186EB60B5D8E92DED4A8A095066997943A3A419589965EA3661191FD10DD3F6F068459AC38C44598C09B4BE609174EFA39768439EB72773CEDEE9C433DF521CD530C26C08075A13FECB913A70C658AA12E065565EB15B6BE0BB52A57C5E4996BEFB524845147F836A492C46D95A8041FB6197BCD33FA9CD1C70EA3CE12ACFA92F31876DFE3CA83BF500A47CB4CD9DAF60F411603BC7A218BD0B8502D25B66039737C3B82C7F5B4FFD12FE8DFBEA60559A0317CD489FC63086A8DEC42CE55F282C264CCE3F52EA88C6DC173D8507AFD1B99350F89BC59FCAC65AB8EB136F67CDCDD0559A8E8F6E919F827C393C70A6D010F19362A3EB88FF30BC48EE9791386B5833018703C36886D0A943E8699CF2072037507DCD197E072F356C2839ABE1DB04DF7CAE9ACF98029231BCF574CAECCB78F65BB8FBC7F3C88CDC1F3E256850BBC89722CE402E424D7D0D3268B4628E93220129B715A962F3D72B08FA532EC208FDA8273BA045820B3DE9E76EE42968E8A386DE4082AC71E5F18724D7EEF285EBE1A39F6FBBD923C589840B20C07FC2E0C56DB3B521471588F8F499A71DA654ECACA5289901E02337F0E93E230621340D1F86F1DE12883C356AAC5E68131763413886DC46C754E163F53DF1164F3C266B6D468179FCC130AC5331D997CF82277AE746A9276788520073F7DB46F13877215B7DC9423452CE9E815D836C6CC0F04DE3DDB088ABA39F8F2CED319111DDED7FFFD95CB1A1081E25CA2ACF3FBB7E80BAA8B12148E1E6911351BDEB116D0AD319670ADB8E51C7D533E1CC899C47A809368B94A841D0B21A5FBFB5868654658CF6C0AB08D7069320E864DBB8DCB9057BCA35DB465E21E474CDB26833C8BC10B0B2279B8F73DE7449ABD2A7EB34DC01D30D5DFFCB9B3FE320F500734534A3BB22B4FFA1A309462ACA7F4DEA20E112A50F5FCF222B85139D908AC13F0E8C66353269344A344043ADDD5B78D25172B02E11673457547DFD6D4FCE567E52D2341D837B384087357950914441AB621C7F1865D26DAFBC209C90FD4390B87D9046FDF5BB44E98414383306504F0FF35687B2CBB29DE04E7E191AE48FDD50E74B83C7590ED2270BDDD7FA9A6E12E28F4A5286AE07D7AE1DFBADFA9127C7665902098BC3CBF12AC9F3F826EC48C9A22AE3E76D8596A1E98BB6342211B4EA25DBB92F274B542B01DFD20A6E96A69ADC103D951C72AD75A32DFCC55", - "sk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333601E8A88ECD7C376304233D07CB229E18A0F8F5242BAD485115B0D4FE59F52EC045E19C137A08767D4F88F17884897464E9BA4CAEEBB414FB0761690875C322A3E134C4E894BBFDF177CA6C3B36A364B9FDF0AD02C9775A612EE58D32CEADA1E31C036440A83119042A89B0644A180C203069C046840892092148124C1009111608512266E3B88C00C5096014044C328989021291440104B2210B040E0B9390D0B64521888908A72D110821D2B448A214696446469A222154300C59A04400B64550126A004446DCA42C08A825CA40821B0869A30484C0363118998823C308A43206D104115A2420A1B840D48680544406E4462213B584641230CAB244C9301098929100860801267294904CD1923001896083445049842DCCA62CC02649E0106D62A200D490651C9471CC980C08155044A68C08B38D98C4295B208A1C9060DCA2251219621AB851E3C29114B90052A0255A4291A0423061A62400B96958A000209224E4008811886C12366C1C411203822421C98549C06864B004631826D2062C53C668D84000D2484492A46912970861128A5200055AA2001390811B036959486E5B940DE0044A94487112369123A4449AC465C8228E50008D8A440C514625D2262EC384255910329AA8110099890B073141186DDC002AC4C0901120321184804C382152160D10954942400E52B4400B290A60C60113028DC81692D8B624414830D9040D80982CE1981010B46D104800532800E1148209100692104C4204290B401114B628CCA28591A6295C424003436901B3605C404698C401D1489082B248018545013802C4C0304AB2045B386104292541426221356160B84904338921400880148421020A8B220199C64D08936D5A9668C1241104170A03C404E132811B2842C1B24C20350900428812B9115802299320711A469291140C1940459B060C4BC61109B38111B22942324111322C4C288903130A01C10C12C72141A06D22112A4C94906396505196700C12410CC06548A60C9C164053C45004110DD0881161280A113702D9A06C20C22C90C290612028591040943842604432083292023585D202020C4271E00642A01284E2946040040998480A09B36914094100278D02164D4A42908006884A220A22228D441250594484030382A2364E43247119988104834D11C19064306C8A8451D44030C24470209069C0382DC1304C60207193320E24848101388D92244AC2108E94B42580A82C543860E31204DCB644A48605643489CBA021D1226CA0202644127019A900903432DC4866DC224C492666D0060414384CA04040543805D9B090A21862221984E2300541149224222ED8128E0B304D1C816C999221898601CB48891A934CE0964162C645033484242891520806E3301001850108A064138911991251D1363019094610B8710B4465CAC04818C2301CB4702407898AB608A0126080408A49860418228E1C1001E2124CC8B40C1A8509E23628983809C0C47152968123940C10484E8C060A01222250486422476DCBB40D8A460D5B400200952960482560A6010CA56041406053284E8018651C496851948852C268A2B281228411D2C07011114D1C153004C141C8302C01B629232231CB283291324A13A9504AA4218A068D839064123528D8346522024648109000407298841194847042028DC2C8200C006DC3288D4C4062484601A3B06D08B5881829261AC1848C362660244208062024C3215A366CD2220C2229220918728940288B0891E4282ED1268D99A6718196691B986952128C4438208124294386815CA84C112824D93629CA802183C06C21004A20174613830050A608023026E2344800A48901388201A96C0B1409C3281101236E19312C5A46058A2068DB98901BC489DAA4005C2206889441A206659806901C10629A26481C2820D2228819400C19086C639664DBB05114426AD3248DA0462941382D829690A23661A3002DE40672DB082E410885D408691C26220B2342D81489A222869BC8289BA470043129A0B829E4947052966D0299654422291249510BC824E3A881C84492D996815096308C164CC116421AA61198A2444BA000A0C6904BC02DC23405A0108D20206521424EDB14440100481CA70461062623B1845B866110816188B228113484020671A426690CB7CE0406096708570A60CA36F9EC4F06EE56DC910BC6A50F8396656C7E0E92BA130C46B7C0A0E6C93545004D161412A9C88AE285DA2D9C60803900F24C95368B9456608065D9742A1BF2AA1A55A4DA1395A8FA4A17CA371A289AD8D096ABB7C376193D5BF84D5F88B131EE9377B11A77996BF37B8914DDB60AFE56846D386903026BCF2E196094B3D1856888CAFB2971FBA819C13D9FE079F9F2E02865B99F95BE311CD9DC448E51BB106C263725CA163F92A4CE0293CBDC12DEA0E49FF5244432A2D0996C2C35DA3355CFB2C6EB81E346D78DF235C64FA911F1157B6C4F0FF2EBA91D047E7FDB9908D7846E17FD1330CA271C0EBBDA6897B6A49E13DC9BE2E9115C8F3AA1802C5A6EE67CAAE5ECD8FFADFB9D126BD16AC7FA6AE5E9E2757177C1FCAD8B98EACAD20C5D7C7D9760F1624F227F35FE8B0EA0ABCC09A27BD0C98DEF908EA7EA19215E99DEE4BB71F94C1DD9EEE76137B88B2B9B331BE4ADFC417B57124DADC6BB25FDF6DA925C0B1E38A54D06AA317F9FE9C9475F79CE2293FB6AD9A1FB5DE2A0DE7F83A82657321A85DEFF62D533C05268EE059DFF288D9A2F600242D5C54D154646C005EF65D927D2B76BE7A8413CE0B818EF5558B204C18B734C6ECB75CC164B2E3787487FC1BE72CE3D6C5161B769EF8245131612B735F1FD87CDF915E365D56FF3F124AF6A565FCF3CA82B64C25AAFE3864AFE380E9FD2245331C1B59A4D62D3820BB441CDEE09E938FBED8CEEB13D2B54AD7C4FF1C9889A18BDF8842535F2837B011F9CF7253919A64F153AA00B44B343949FC8829E855E76980A357993A73EFC718A04DD59B5E062DDB30013868CA4AD30CE8F24912A7DCD2D6CA69394C229C6E09A2279F2329CEA517C1575CA61BBBCA6CFC3C4F926DC9A0923DC859A8C01FA4B1BB60C5C6BF384ACCBF366A877E91EC85A20967586FADFA542BBF0AFDBC65BD34B84E3D65DAF38B3DF497E8FBD03369EEC861575C2E4144B36CD77E23F1BDA693D45FE1C201EA08A3CB4C3517F85D24170D7AE3D2172B9175BA3A38194AAD0A82C32426B6A306906CED1BAA59C48F26F5C1D1979C47A5B495DA33FA4A359657DF97052EF48E39095FB59D7040833D67A0DF9EBC02872E905D6A6277224426D47B409674819181993C7207DA14A11DD151E4855D3C8F310D13019C60B6A1F1DAF1DC3D2E60E0BEA448D2A2C9A6E7BAECA8CAFAFC7484246C036238BF6FE2C5F817DEBA88DF00D10CCEED9EB4898A2C61616C073D5812C3C0ABC9BF0BFB9C7B7D4C8C1D13CB2224EA32071DDABBFFDE25117EF6058826CCEE53BBF25AE65FA181E60A8F9E41D0BCD99F21B5F3384A9644A6DF25BED6DA8087A29FF72C84D25B674BE4BF291DDE146DEE6AB46329CE70D2EDC8A39DE7C6263BCA03D8E09C3F7393D7ED7F4DCE3D44E867CA09E18ADE556047F72527AAE88FC99E2E02C0225075C88BEBB810210BE7CFE43921F1A509FDD72F7933F30B42607CCD44DA422863B77CB5049E466D49476644F0A26B8BEE0C30CA43AD756CC00EFB6A1A151C383C8213096A5F4695857F14777F9CFE6F4E425ED61CA6453A21CB0C9C4C3CFBE235703F6BFD3690437FDA24C030E0B0819836C08693E3FD605A2C1E1DBDA347B6CF30223C8499B5FF08793F7646610E7B683E4A9CC010AE1AD954DFEDF9FA0EEEE26BA0F24C2B88AA18A89C1441833AAD4FC205CC5D8410CDDC6D8E518E6FAB1CABEF217023E90F5383CA8F6C6EF373C907285553D4E39E268829E609D9324B393C7957CB832063863C9AB5BCF950C50B97A54CA45752126809DC9D65B889D1E0CD4CD5EDDC694EDE7BAE2374E9C695774CBB58167D870948D5F5EC047447852C44D21F66C1D289E9AA2AE3C06CAA69F35A5D5786BCC97F2934B88430F3D5E8B5091AE0EBAF0D3CF80BC4CCD15481D5C6B1FD0F3818E48525E2F9522B4163109B34C69F09860510875BAC0ED9CD0F38183CA9127CF3F5FBAF8913A2F0A4362B87896461686E43CA2DA5D58F12D44A964EF6DB0EAC5045448CF01923E30A49526439416E6471FBEB884B2B4A02F351CD6C5D9169DA9A19D7C08DF49F797F0BF8942B0DE603A72461B9A67F96F62C5024F644CEC1AE847AD75D6291F4B1B5272A38F89DA7B9B2FB44D77598CF959AD4E77FCAB290F2EC7E62A075850E1723BC1F78AF44F4F5F540419302924D27B20882A46010655C20EA9986375203E85BE0B7BDFBA844CF99448AEA3CCE916F3A8E77AA9DE340099AD924DFEC0F38F1AE9973F82CE58258AB7770BF850ACDC66F71B5F32FB159DDA18C31AE388339A74F59220069F4471C9FD55DFE359E2A6FF3EB874AE2E10288964914CA12179A4950AF63B7316DDA6C695C7050E0AA024D8074AB01C94CF663C45B69DCA8C469F0CE7764444008CBF0E8B6A0EFFC44DE1B6EDDB9E765F4E63DB6148E17A5D196F9B373ABE858D05E14BB282052B4EC190171D5220FC27DF1442BCD7F2AE89C06A9D2071297B42ACEEB9C29F386018009BBEAE7494254013DC1A7454D40720ADF575E2A4EC7719DEC804323818AFE5D24C76FEB187135BD4724E6F18A7474B873B4B4C2CF9593C0F2E27DCC68E4A993FD0ABBDF518F5B97BF1139CAEF1043BD3C7D9179EC1B6DE98DAA2BA247F2AE49D24CA571B6ED66B22CD07C126ECB37B24FF8CD5FA4CE282E482947E0A2988FEE08DD0EB3580DD21FD3D88D1D259C8CFE6F52AF9A1119662CCC750E21FA393A6BE619BB537D216F8448A473136303FB5007551A20273CDC07E058E02A643AB374538CDD5D62E86D7262AF04C2063C7836790910BD7752D4CA7A848B9AC4422D04A4A3F018785EA171A637BB55E7F63B9A4AB7B1FA038F09862D073CDF9DE0C1F1DC6CD644577F5DCCB31D160157BAD4BE7A0410966E98E845F1D8A8D36006C24056E076C2F46169DADA9E928C84277EAFF6CEE3B438E84427C4C95EEB264DE7E2E6C3BFCD5566C5F396FDFDA3E9E2405FBE3ADDCA4B4B4380150355AD3B42BDCE65FA1EE23C576BB4A4BAD816D54184C78F7273CF0227C79FE21CD4FA43E59F3BA5B73DB40E9568C852DDB9A431F788B7C402E7FDDF503858623B0E24024DE4A9D44852B16BA3F4008532E0030ADD805C896AED954858F4496418F60DDD790F4C486BA722FC0772D033678F9E8B6830FF6AEB194C102D8E81FBF4E5FC562EF8226371F384C51C6ACEB930C5F1DB967E394094E9CD59AC1332F6E93714DB498DA10804CF0F549D46050E9B1BEE7DC30F1DFC135CFCF6E9BB55A00EC42587CFE32B22C865388E2015B585F77EAD9CF1CA48E9432E46353C0DFD66271760099778CA61AE954561F76EA4EF58F11287C402A08D6E47289120606E5AEC3FBF24735E9E93647D967E61460858CFE2FD3EB7B7ACE18A5E9718AA8AA412C3D04FBACC721AE4F850BABDFED7F3DF60262C91EE63783811AE302367A5F10CC08DDDB58B7FE6A8D9F5A63F0B61D1D6D8F457222D8FCB61414551224242D82F56A95C6485993258496C43D5EDE518DC9D7D055A42C10BAB46F1B626953DE1472E52AB2A891251CBA71646A342DCF1CBC51C37F0D71F81FA4824AF714E8F2900CEF663525C82ED3720CA215AD8E6F01E6E56F4A25BC969BB455245809789ABF105B536EB2723F064446C0FFCD7F537EA1EF11B4F5FB55562B1CB57860F1F2EB5AD95BCB965635E7804045CCF4668CCF3AEC958F06CB1471B78E979A5351EE9B1379404E7A51CC4F2F3DF703027FB0C0ADBF85FF977DF5F992433C14244E4928324FBF9E527E83775A34635A2D673432588EB69D35773BEF5C6683A54D6338CBA404977F6D5EAB9D2A73FB4B93ED82D04AE0BD9F8CB820363B52CEFF4AB309ED8677130339435C565059588212D81066EB6AC462E0D0F8F11872C9E25460B45AAF5191FE0657999C54021032EE672DBEDAB378039BD67D22CBEB714B6DBAE11D3794CB44931585BC5FA02A72C5C6FB3E9A4BDABD16C24F7D314BF8DDE13BC838CA81FD964F8813149F700B0BC16C41492A8C7B1EC967327DB0AD6147CF64202B9291F1BB8DB6E31736B455E75F117F531CE39CC23043906C98B8684072BEE3350A54BB899E506EBC6FA310022A52C9FA6A0B3EA7068D01AB3B805A917B4E7146C7F6AE89DCD07C4FB4E618D564C25B6D7F272731174BD541A0AA7738FF167008B781577BCD98A3E84CC81B856CFF987AD3E9D843C14D72DC8320445031045CF9D25993C1F179764FC7102208BEE6ABB9F9A332A7A7DE13379A81D030FCAD6EFD94801FA480E5524EDE34524899FD40A4C02AD85F3DF4C7F68E6B7A66E1FD77C1B9AE0842AC3AFAA9430C57A3372072D6EBEF890CCB4987278E3AB9FA11D5EF0914B949CBA37D3F55735C550F56D1D3BF96B1C590137A91AAF14CB520794B63FF597A311790C9A0E704F836A5F89BECE8CE2B895C0E2647D5D4D2665F2AC7C95622F8B3B3E2143E81278070F18ADAF9B1ACB86A42DFFB6989856178B58CF65044905F57D58D21F1E282EDAA5F6472E62952AEE2E9E6A7526C26AF1D2E1CD05F5CB8AD57D9A2662A91F97BCEE97E43464A28B5359F66FF6880FEBC1512C66B289B318804899D517B4D2C6F224618324C940DFAB6601394141E4F66D5994FF5A5F71EDE3D6914FE8E435CAA500E809F258ED7A7029867DB1A364A8649346CC3D9CEC31B2A1CB3A2918FE6349856E037DE1EC177C168655D" - }, - { - "tcId": 73, - "deferred": false, - "seed": "31F5D7AB44ACD0072423A8E486EFF6D8E2EC8D9D25040D6209BE64FDD03A7664", - "pk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E77543D2FF7D1B317F28D621ED31ADAAB6CF0443BCD8A32406E82FB4FEF87F8977878C27B6812FBAEB5D135333C20C8EA95BE99F8BE1153AAFDEA8578534DEA61D60644B8B94CAD58C78D4036581A2C3B64172B0F8D22F56EF6A7B8682B062D3D98299342781880AE568EEC5D0F30B9959FF26947FC040EB8A3C6688E33EAA162954422477DF6405361B3FC8A7B39A120972F78859B879F2C80EA81C97D048F8FED5A64114855FA72BCE11D1DADA55BC65DE976316A39B399581C5D55CC06A178ECC954F4D9D723668A9EF6416BCC88A9A215487F17A48BDF6A6763A7FF8B447E87C22D009FCB5F935D66B3F5BC2C1DFB4BF32906F12D3F82C7325CF3F53CB0E73BEF4F8919181C532E75BAEDCCD929B59119451564AA0EDD61C373D4C41AC14E739CAFD09F3AFDB8B50A8F9E4E27EAB64915725B199A32D94E573E6C9E85E1A05B06102C852564906376B1F9732D059FEB25F7A3DB4A0CA596FD49BD6F75B45AEC689207374AF4CEB82C3EF86A4F797661AB631857A902ADD3847C222D6F1B3D49B0043F0F34BEDF97F2E1984237DD115F34215FF1786941BBC42A5A80BD506D4392649C790A0FE68DF5FA9047501731BC408349D6459DA55BFAF10031D71B535D1A385BAC31B7033E315A7B4BA614A27F16FC375EB1A63A96E1C584D0710693C1442AD503C63062918F736FB8A32C68B475E46B4D27449B074150BD0B98F76A87F313F5A9F329DF1CDD180B28F5D94B100A438AA7EE4E46061C02F3B427F4D30ACE7BFB6CE65977F56F30154F2A2E489FE19F866F2BF70FC6CA1D54211398690BF62EC4C21B39C8BF13C654F596778514108D9D0EC8C90111C1A771288BE97D8099E893611B3F8820B5E169C4584246F7878288DF4FA658401ED2696CB1B69F69F3DA8C4CEACD56D33F405497CF9BA898E734F4FCF5CE5165847149E3963145859A9F9E49572A9227526921074737D444C9D56939BC22C00DDFF53007275BE52B4D3053AAA5E2B702ADB635BCAF0187C9143CD88DDC3F684E6313F840DFD666110D63B49BF1E56301C65E6DD242FC66C1FB8CE3F7C7D102FED86D50753D16D382900E6EF46EAE83A5C37C4B1B966777C6536E97EC39D74B4A1F66FE0063D41374498B1910E288C711C037306DEC815C1B3D33B28A6A151D9E7B04E08EA7DB2F829265B952CF705755CF56E9C0E38CF41DA796A621CD50048E05B2EA9903C3DBBB450CEC0EF28CD2C11831F09098001AC2AA565EDD47FAE33E3FB9456A0E5A1CA83D236B6E135C18A61BF0F90C632156B9E1579C56EEFDC8215B95052E10FA03A7DA37C2FAEB811C1003C3F475040A377C738EF8CD80E9BD2800067ACD32FBBCF14AF95EE119939BE55B9F6EF6239C173480EFA5E2BA4E10EAD1F7047EC2F342D853AAEFAA3DEA9FA6625ACF6BDE1AE1CF72421F44661083707D056298FE9399132EF319E76B2FE7D0307AB499E3CD42C472CB427B734D736C20C231DDB7F80F7232B42D72603B137B849A994BB1117AFEECEA2DF31C53B3AC7D7E060051DB3D92FC7D9C1DC173BBD1E7082D8F81BAAB54C6F96443926ADA027F9404ECF8FEDC79C214C766E441162C67BE2F15988B2B7E809B5D68173BF3CBC70E8E1959BCF3B876BBA0A7207A519C484AB07F4570F2491AE1B7E3C5E7D195887E977697FBE4807478CD5A0D181BEFC4DB81CC63FE2F1C5FC89A14F5FD48318A00EFFDB68F7779237440DCA768FCA85FEF5EF463B34AD1F7FD1363FD79CD0D1D6432D2EBAE0629D8B815D8DACA9118A12736E552BA8454F7FAEC4695AE475E5A31368E8417CC498C90FA7F23F5C230A43392A524CA5085ABFCA331553DEC1B311EF3D2F1D29D663260B06644496E1E47424EDB6E9F889DD58822131E2EC79DC037833F0DF0E65F1238B60347F9162DA336770567F4C7DC2DD06AFFA10678267A1EA2991E4506B7BF37D854480BEC70ED1D4997B351A56538632920A99D42FF569E1F474DD178E850F15D20E2BDF33355901B27354CD95D826BF2C21A624193B41D9FEEDCABC16514C4BA02B7E3A393D5AF73C8E012CE98FE6DA264976671A7B42E7A44D56F60AA010750BCD571442E02212A10E2CBF9A65AC8867D67C2382C474014D43A816E89148C8F43292F42D9BF36D5ABCDB4A33B70ED528F533E3296C2E8C2EC244D3BF7CACC8386672D32F81BDFC6F3DBE83530FF464160EB77B9F9FC0AE346BF5654D6495FCA822BFA30C5449F377B2B2F63B44CB8579EAEF0493EBFDF1C8E5E80AA530DCC1B998223371919E3FACC34FCF95022AC900E5F033082D7AAE215785D6A9DF921C63593F43C63E5C81DFC7CF42CCE0D805AC586375ADBDEC1064D16B1348D261C8F902BF4F0FF6C525D2AC37F384B3AB17B6159FBDA15899A2EB14C2E299B8145B2A52EB918CE77A29716CC168EA9B122607993AAFC496B28C456C64DD750A47186862DD36D8AF7F722B9E8565C5365C1F46F065861C6853D7C0CA82FA04A85B6A70C5197487509AB0904296B5E07149F33F663027DB06F7ADABDAB3994BB8A68F7BC943EF87846BF8CA68FFADD1BD50E51EE64CACA906C0BF0B39190E7ECC4745FAD9A27B06CD64F18DE7CD97DC12525ED54466C99E76E206DBD9C0B4D22F5F08F4FE0957FCC7915EDDE8F5E47EE620758977B49535FF4560F0DCE0EB0D992EE0C0DB587FB1E0CBC032C41CA5D2DF6A35CCA6D49CEF7FFF59D390F0A5EF2DC059ACD78AE65E1AF5ED672309C8AFCE6FE2F08B11F28076EB87ECACED71A6C65356AD2B6996402A69FF20713099088DB1504A43AE9725AF07A9F126433B755737B74CEB4D71EB610E5BA5C029676581B36F0C981C0D8D06C2F6B05205B29F9AF32AFBD23E00495D5FEF6E44050B01905EF2AF34B6EEFE5E17483450BAF54EF84590427FBD223A43E3CC3FD47C2AB86A4A1DCFFEE5A51B443B8C7395D31BFFF12697D1FC3B887D2CE4E2CE79C29002F11CCCD98E86501AE57B252675B1F88B8038CBAE8BF1D50EF5293FEF0B4AA790BBC92BD5D995BA7CE384236A59DC88962DB6364D9F27A20C969E6BC8AB636022E340E4C37BFC9105334DE64E745A9E606BD1B5D86277E0A4416B981BE9A77F2889F8AF7244FB8F973465858C4BF9244B306E610DB421F14971C3299C3C57D3F8B09212FA094485B6AC420DEF2E3A34AC7377CE18E03ED00CE575ED85B767D8787E098B7333F425E2336DA4FB1C78F3D4D4DE5BD4464B02488805FBC64907A45E37D0C596B88F989B5F9E5C307AB050526020003679BE079CF953CE9B7519D8C780BAC4EE8A44172BB74900E06F571ED9147C4D7F6C562A155AC6EDC157D62F4480E588250F49B7DD8B1C04A97AABE87486A0852DECD387EEB3E9837BF2035BD9F763507C9DF4DAED511A4ACB51DD47EF283DC43C64433090B89096539F5A506FB4FA53FF96E3ADBC74F582459ACDE4C9325589CC73330116B33FDFFE677B970844BD891E1B194F1F2F51F457D3E944430EFDA332A1E18DBA2C83F58989A3C491439BF5227C7EC2788663BC733FD5FE173AE87941687060D217AB5AF9FC10F119A177FBEAE000349FEF237DEF84C52FA1CAE6CF0F89639787BDEEB7528FD6514FAE29A06D347B2496AAD01CA951BA1B423C", - "sk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E775A965DF6F74D379106E6393F7400957F1D5753F6C9EB1E8420D8F9AAE113830A0A153844DC529D49CFDB506F7A3E4A92A6F7B77271C17FB2942B1144CD5D82DB4B9BE60A655BDF10FA3F5ECA7F774E3B11F9676F5DEDB01B15423EE8E63BD9B1C61940551926C09477184942DA3B46999462A41C86144388E14C6115236600A366A42120A1CC8904C946142004A49204A23412019C869223028A296700C376403B911128528DC267222260E18466910B8519244850240280321020C146123258E1996209036201BA620400472DCB6654C44061B493122338E48A26558223024B88442C65063288203404650025263148209948412822551140CE31004D2B43118A40D0C0061C106011B3250D0202C58166509236AD3300C432289C38001D016080927480C83111B472520086A928820003751A4C484A09020CC4404D34232229771883849D3244042028022240848802D11A3699C284010854D04118D01C76DC0005013070554C40890064921A25120B6445188008B280DDA484DD0B2450C4190C896292145669B060651082A44A60DCAC06064883008226E5334120196518C8611213482838825D0B89121068C142205991282A42268CCA26D01130059284AE4A0041A818C143041E49669A4986C20B441CBA028CA80850B36529C001080040A94182DDC146108213100B550480292D318706302461019858B268E1B0386CB4482DA848D20249102B92C22902D9A90850B90655BC22C88C62D533861DC946C88368D208710884260A3246AE4C2289392889096211395440B0291C432060C13905924658B006C50C829012842031620A38090A22292D4148AE1C441E336620CA4088C922023A740D39284128710A106808BC8889B302ED498880B290A93820C22C1901B443190B205438891CC269244B48154A2209C82601C1480E31484211172090401C412621435216394000B2070D93226C4A24C61406221A2691C020022226ED1000812011221298EC1B80003804153364EC3C2814AA244590848DB42908020304B3681DB268113442850C224E2B84D5C104C449871E200661A877003364D102990D9184510A37194A8459A462E1C230D44304162004A62C841121169993426838449C32091DB026402302A5A148891204E5C0089C1862C1BB19004C1649B28080A985091942411939098A210D41889102766981492D8102220C20489446410148498324518C011A30629D9860188B28C60380D1A475004C0900092050084705304298C322159B8100A2045CC124E8C4831412401CC422CC03085D0C80109334CA3B08024462EA3486D59000E88440900134A58C2618CB88411B30921C72418135292164E49844C81166984C031C9C445A44420DC3641C49051233861228809C1102608094A8B14918A98290B160A82987049C83110462D93A808C28400583070E3C4292340320839800C078A14816DD3A66C41464012152E094828124609422065E4C800D32264C1986019906040488653064D00A741031022C3062C63008662920493C02C8830015C9869124161238624518028E3240EDA00250A9560208550604651830044C396510B024D4A984D89A08CD93232543208D012459B469112998C0808044CA8519436842033204C424161B461918809D9B8808A38448026449C8000092632E294000C2142C906015B986C13916849107058102E18438510190054288E54086089A23102334E21B485A4060E92320558100DDB962D2405704A0669A3B6618C32620CB7212009409CA430D2382514224E0CA1210444210C04485B108A2311641A178299002213A6651B88881931622005441AB34CCB2291D2006D202848C940899B82090AB03189828181086AE2042800262652860D9494891C22101200809830529C46800AA749E11291C808425B326C204424202980A2381118B829CB404ED2488981B2482409298390250047696244040C3929CC08001CB70C09450044906194900DC2B88CCA3628180545A4964021B961D3166D41984511066ACA144814222DE3882062222520976DDA304614006C5C828463482D24424448247022110282300DCA8280211701D230261BC2615B268424054414A84CA236441B819190B6411AB7311CA69124B5518CC40C09294914B870E348265A3024FCA93B3DA173B47E7A5AECA423DF1E771F6B210D4026CD835782F7C0502F779B4A30FF4732B447AAB972713634F2A5CCD9CAD1DACB157D0F8AD04A2FFFC043BFCF848458F964E1B8488300F2763F045F5774862315D314A8AC2DAF2A132421F0227734192BCD4AFE4756AB317CAE107B2891547B7F41C9523D5EF2CAA75ACB48A816EB7F371B5582FA1310F9A9EB6E77AC47A0B5182A5A9F8279599153D6E157D2602E65ACA3353D058AAD1FFD32B43AE51A11D309279F31AD00B6CCD1DCCF2D8B8A9C453F7DB22F9A11C45A42EB492AFDEA3E67382AB800F44BB853A26D5A15139D3B4D0F187AAA8FDDCABDFA5B53805A972788694EEC9CABC95683A97A7CABC1C724C738134B47A96BCE7202F0F319CA1D7A9D17D3695826BF15B3CA31E27047477E015C76FC99FB0182D955A04CF8F294E67431ACA9D168F4A32745A8F6BDFEE7EB35E2043048CBE1CB14632360AF375BCE61220FE6826D1903FB1AAA1E2B40E5810A74E85980A37046FF67A8EB28C7CD6B41CE833DB9373820869209603C81CCEEA03C3CD0836E3A65798B20E55949297FB2F2C613C9C584DBB783995BFEF772ED04604DFF8399FC81F1626306844026E0AC80FD6FAE2AFD470064383BD3C5C41DD6B4B8247A9DAE986979B651C927DC309B96BFE0B08B2CA1874E08E3231E55E619D68B7C7F86649B4CB6879938B8294C9FE3FFB1ED88885FAA3DFCCF3FEFBA69A804EC4B72A3E6CEF853B5CEA9014E9AFD963B18BEAD40DEF8EFA134659F4738E87BB2637AD40E9A8F330D01F4E6B34482065BFCADA0D8FEBD24ED280A65BF2B7C8D17241867DE8DF5D8A537658EDC0C568822CE6314AA61FDB322F1CD1720051ECFEE221922052D4B1329C8672C7178D00346E06AC0A192A805783DEEDA6EBA9852F071B544C9E11DA0D0C15A7DC4C14DA9CE3AF57FC20875DAC3EDE8418E8C59B935A4855D4E1B850FD2282704C35565C890FC3EC4968E0EC007DD5AC95912806804BA8F496E37F316E508A4F10842873EFB15CBC267D48830E3F22110AC751387FDB6FA2F097499AAACB155DFE928E17247F40BA4BFA362C80AB133F6DD1260A9D88A7B7284B5C9D4DB0B5792FDAB2E54400F7DEB0C40273D4FA1AE5D7D67D74ECA21BA9C463C7A7C96BADF827570B586D3592938F90C1A7BCB844B2D166651DBF7B4640C02DFF2B4FAB99741C694F0B4294CDA1035E70C46700CC9C359DB57F83635712B0D81EF964002CFF25F0DD2D57DB50D53120522D3D7969951BA053FC36FFE73BF28DF4A66D6316E5F82D97FA867635260778D797DC7AA6FC47D45ACA168F58BAEC6EA5E7D8B714D97F85C260528E4AF146478B2065F084B44A07D328BCC1C05C9475565AF74AC697E459D4B2CBF4ED533C79F04ED4ED43879F735E7D2B5EB2F9E095BDA1F12DF7A9A924B237C2DAB8B510C4D2F317C3DBF802ED7ADA23DCDEE73309D10BE5BF1AA397D1E9F3B8BCED866CAAAD95F12CB12C20590DBE96B2CFDB44F8F8FF240B2B18FC9AEC8921AA6344E08AF638F9EB8EDF4274747AD1D29041379C5D3B3695F6E4E76A747B1D8E1E4C1EB938830E35A0D7F0B9CB272DC43E0601E6A2E00BC4CCCBEA0DE00063E3493C8ED50616B00084476E1D144F7C3988D1E5DB81BDDF8474E591125E6156ADE0ADFC8E4C5D1E4061A044E419A5C4275B83E0203905B9F7FB95E979460BD478BAAAC8FA4F5F3EF043C67582C2F9FA959250B06DB851CD914A5BD3B3C89DCA914A24D694007E39E38C7BDC90798F0D2C86C6C9944095E094DF9A871190922F03ADBE4C8D2A0EB21FE4F7E461FF4CF3FE1C45779356E7E36877358136A1CB08A5CE83426DA7C8263A35ACA21E796C31AE64E6CB32A05008B55ACF66189F5A8AC673434363B45F475E336CD4947239DD9A127AC02436F67A5452FBFBCBA70700F52A01058CF5E300D9780F371415AEC2FF225F07A43F1F51A91FD615935EFD876BE31BE216714CB3B9C792982C29CB32F326D88746FB884B39EE76E60CD0FA83FE33CF14F83CE5F74E14F43B50D03C3E84FA81D9402E1F893A9FB85AADD403DD14C6035A0B5EE9BB98DD068E042F9619055FE80AF76500D38D7EA09249E78B020ECF83CB6E27BA6F409C40809285AF42944BB120002F98406392463EFBE072A99662C111B73C97EE1FBAEA1CA520B54F84FD2C501261C70B2E3C75DB6FF000C4562D16583473BFE99C250722EFEA75DD8DE29DC681D2AAB6DCC7BB865037B21A3179E0A5DC51E5702D48865F36FDA4E8A58DEFE7861251F1E50B6C95CDB4DBFD491A98BB918A5394D989DBCDFFBD34D722CDA9D8819D6CDEA4ADCC5D8E54B7E58B3FF316C1AD1B3BB7393590463F02FB7CDEFC5730253B6D1286A681A94C45025FF0BA2DAA47D2F7A22D97B7152A8B4B188ADACD0F657A4766E2B6A82FDD85582E11D27C0CFFDD271362BE6F07EECE5927EC20BB4B4B124FAFE95F65C0CDFFFD4606378D6A03485325F207727DF828AD10285A72CD009296D8921BC4F1F7749D105F769EABFA7A073C5C3293AA3781BF5D330A7B46D2E9F395645D996C5742CA24BAEA12B52884D354CC8A743CFB85D45029BB421FF8B06562F5F47465F1F39E6C4018C2432C82175F631C57E587012B2B35E2A61271B05D7891669C24CB02E186313A62EEAACC8ADC7B7BC08FA4EF773FBE95ECDA083F04046FDF4CEF88010CB45EAC2C4844B8246FA38AA30358DC0821D70BDA3CF5D32D17A37F708111A171744D65377017BEBF12ADA5A242DA8E602E21C7D5CE680E5BBB5EAFD621BC9D1C0CAA3534049EEF8EB9138369CB86ADBCD4AF9B5E3BFB62FC5C5EC09B54AB87D591A59106A230141085243D2922CDC2DAFB28A67E0D79BA46FF11CAA0D05D258880AE4F5A06C7609A61F70EBCDE82152E8F82F7100DEC3492A186B7C5AECA8F9156B1195A6D6D52F5B55A0A9A06B2796503DA41DF47DC49E2CA1319F212E72CF017BD5A36B7C8083D9B5A34546BB689C7119606779F3E720D6915E310B6282BF98FFB244035E5F2844FE0842498A019E7B8B5BA700B146BF36754D716E176E52C158E6C68EA09F973638D78E7223821F370D0D658885234A5833B3934A9DE8AB743777E0A77453D346066EEDC58D6FE6B13401A9A1D7B98FE7097841D48BB4448FE3D0F2E4272DD8A49C21B6521793BA492EC3A15FB51BD4891DD21AE69AE9F80E6BB6E2CF1BFDB6B74C8B0D45901DC5A63C3A71826CFFA19212F5416777D85FE9B1B815AC68B686B247815F43C3E0B094683A8750C9B51AFBC27816B6164ACA150176611C003C7D7953D03B2BDB77434EB2768CA4C212D1A9767DD5906AD1D6F5E4AB545AB0878619A538B6C317E2DC3770D24D3BC63ED31D53D5173F593B732F2BCBC08C92CCAF492AB76041EF3EE0FA77F5AE55ADC47B65911E00B3BDDD5EA3385483927A03764474224979399940E83A8A49C9B76AAC5C271ED87DFECAC18B4AFAA992B2CB1A04A6C4647C4828B4AC5E732BF7D56757EDCDC8D079883F4BC7B3F3A9AB775C8746DC376042B3AED720B913B007FA4C6E525C7EE033D9C9931769DCB844E8EFF509D3220C5240226707798C722C7B97F2C59FAFADDCD0ABD4C99335F4870D9A3D486A6D06D2A00C0FF61D9EC4085B71B90638EC2F4CF72B3B62CA92F4256A7320D848E43F7B8ACB62C04AE8E9CFC42D9C9B96442487461D71EFD90773562718988AE10E401D00199D35ECE065BC93257DBE1D38629C2CC35FE8342685E54503A75F15BB29E3283903C04B9F3CC1B02CB85F4DBC1B2BB30D08AEDC50F39ECF324AA74DBFDBD04BB87A36D31BD7BA9E70B9E7B90CA61FC5DEDD2CF1DE1868ED5E473E93E7E4557EF081C39628B13A1527D392306078C1189A0A1B6BCBE31B421C3588ADFA39E4EC6F6A16692E5BA669D3C4C67274D5206519D852A46998E492980206A01C6A1B533CBBE304DEF68FB87E423158956769016EDAA9C48AD9035958EC3AF95FC45981E329B7BEF0C5D11D7B80CB7C93465239FE69FB3A5A34EDD0BED53A93089D9E96A3AF7CC03E4F4B6690A843255202A72B93A1EFB195031947DD6A7B0FA9783731E690B513824754C7C685D7B8B61BBBFD800862D9129B72FB46BF7B310003C3D46C0F4B449C8B514A9D2DE61B0A8A9EF48BDC5AAABCB548636042C0D2D3F548332FED043A48F81BAFB4897B9C8BD16551D5908BFD185E9DEB2E66026959ADE4B9E0B3E9F04D38D011E77AE8F38C8AF8C845A05EB7D072933F3BEE00AD376962028674B7042651C91D4DC89290FEF1EB6AC780EDF600D23B8EF474045D14877607D74DFFDC2E9A7F661A5A94678CE458EF58CBE13DB5FDBE2F38CC6674A23F1DA4C7374D38D618B7E98B4B48909340DA000C0DB91FB691AF80CFE6B11944B72ED1442C142FCC6F412F258F6EC0B0B08A52BD097CA708B6A6A0A768B4AA802D50DB92ED6DF4E5ECB03B9E1F776BB4165BDB002F93AE34E8A8D28BC9F910903DF77E26D607F09891C4E7446EC76760C4B96FE3F72AD5BC0327AAAF4761A9A89C2C8E886CE9A74187FD55AB7C0E6948358BB7623849F35A4BBB487C17600235EC49B3BF86178127A3436F6580446A41A7BC4F1B352604539B90A444B603E98C20C75546D0D4F5715BE12610E44EF9AE6F600A7DB33FF2133F8695D12321D20285F4322984B0FA1819C4A0136035E134E81C43F9400736DCC8F3680E71E9FB90" - }, - { - "tcId": 74, - "deferred": false, - "seed": "2ACCB6888C3525515F10A2ABEA6D7A3B0CD43AE249F1F7CA93D1DDA58A6C825D", - "pk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7446001CE0A183DE5F05257D64D4495DDEBD5FC90DB67196FACA8155CE9EE2145A7A4F4CBB8E6F8B620649EE54D8BC9D680476C7165E32941B3648C86D916D8A1D738A678764AE76944DC953B8D94AF1B9535E14547F6BBB32882E43C7649638B65AF3D61995DD2D8753338E4551A5D3FDFDB7BB3AF3A251C4B05DF5ACD422FA56709A2EB698C80BEB9B83C2F7C0DBAB0639833C141A9338D03EDED1478C6F26052D3A07D6479D7D9D84C4CFF0B3E12720B766E7C805119FB5D31CE45590B52E7113F35E5EF11A5440B6567C97C81DA59A73A1040CD459B7689F6936687B964FC7886A9470711243E8338587DB7686B198AE9C7AAFE58FC0158514D6B2D51EF53C824D73DABDD5B30041EB914D4EC5EF290A3D8A55B628773C8F8B032B81A683D5850AF64753B142971B7E492153BBFB255187E54D98B887F08DE5AE72A89C55F13FE2D5A9B90B8020C5192C37CCDB325613BFAF29F44621CF82041BD335CD8DE84F2F9DF7BFB7241E7AA8579952F4FF6FDD9F7EC8EABC2F68F730CB648D00DDCB6D51ECE42409DCB3BE74DD78CCA1E392B6FC36B0675EA6549678DE83C2FDF4385C551625523CBDCAF7E13BF38B67EE2282EB27F827FB575F3C01A41ED95249452A58F5B3595A9CCEEFABC5591C873E7A726FC20FC3A34C1C665FAC9DB9445B34AD03CF4AA9F3F33BA8AC692B973AC8869D4CD25D4CB1AF9174305894AD3745046E1A536151AEFD1B2E8F6AAE6EE58756D7FAE3BDC18BBBFB750AE21C043A643310813D1C73C9D8BF31B9945C2AA43DDE3BFAB9EC891E2205DFE4CC7B375DCCA358CCA611ED274FB4DBAACD67DF7D2A7641EB04FDC5879E11B3FB7E7EB0A9324F665FBA610888CC8E471443CF83BFA95E06AF1F38A7F7A694E7D8B112DD215D34851022FD401D8551390DC00CA42557BD6C7643E6F1CFD137E2EE67FFEEA6867E2CB1956ABC5AB12E8DFCAD33FEBB318FDE62D8DDB0A5490CCCBE0A8728E74BC0891C94C0153AB15D06E93CFA99AAE2ECF7ABBB04BE51E613BB9B8E19AE454690A57276DBE1FCBFAF1052C05F0532C003A28132639BCD2EE8D453924D7A40E8CB23FD0D744ED49E1D402F4C05E739120EDAE70C937ECD9F2487B09FE332936104366025EA468F495776F17B58843766AE40D0BAF21306F4818F03329CC6414D65CD8BD1E360E61301FFEB702C571B7E35801AFFAD2DDC0CF7CE32A51B730223976E8DCBCC3DA88CCFB5BD7497263CD4BB742F2D46AEC17103E362AF1B86ADCAA662CCEDF940A009325CE2CC47E5B95B77FB23F35C188214AEC7B862569D4395B7E4CCA1F288EB7AB777E1AA7EBF0A9289BCF0F7FAD99D3529CCD6DA43FDEA0356CF1E9D0214FA068CCAA8762B6CC3DDB910ED8B1FD92702522CBD20CDF95C352624C2CA7C2DA5CB90FF964B5399BA9F0A67F4A7D062BEDA3DF4F7748058E104D97AE54BDB511A83DFC2A22934E782B3A695B2B7AC23A689021734936668BD8F752E638BA2877E35E99C3C3560EF6AC2BA8F3D8361E4DFF09EDA4196FC07D0949818B867A0721AA2E861E78CBF3BA63F52E72B9E75EB54F847CC8DF0BBAC4B1519881D6A9E3B0D3D609DC9B93CBC3569655DEAD9647732832BDBA23D7CDEF931A85B932C16FF7025E860199228E91AD9B7BEB70AECB0AFD677E0970E8C05612FF97BFAE7EBA53D6243B0EFFAF51C4EFDDB569441FED18018A90034B482416A3CB81E9CE8B7298BF8A2EAE1D58661360D2E89F3F91141F281618A9E0A598D51C4B16397D44C9E5C2DC5DC0457BC4749AC3E968EEABA9EC7876BC9E06E61764A200B2ACE50B0C4769B123A6468A8225ADFF3BB072BE044CF43E41A4D74E85E14F911BE15B950D09ADD90F01DEFC9E93F1ED782459635C0E857F77D11FA37BE582193EF0DBD16395487054854C2D3C5E9A3B30580E109873B1AA16EBE776425D33071BFC0F1BAD64DAC7EABF51C7EFCDB63C12C7B77E9BC78E8ED7F33A5E7462CE2EAA2249F0F3321B1C0EEC70C8C47D548200D531B68FA189DFF75E24174BA92BABF96919EBC584F0D35F5DDED81ADFFE82DC9803385CC3C645C3E871C9778145D45572E1DDF29BA88ADC365A2655F1C279A842317CDC42E284B213D366112966930EB6EAA58B555D43C7798853E84B6016F93EC8A0171E4BAA4E22D61491775E54E4A3EB24A618EC8C2AE256121AB12CC2BD08B2465B0F183F2E0645936B44B3D470E1D12F8872308A832F5419ABB76E78BE62B1BCAFA38867661957AB45CAA5C839BF949AF640DD0FBDF8A5F61AC689D21C4981E925DE139306092066977493B79670A5993DD3CD6BAA0E3EA035C1A53246EBEAD5A3F41AB2FC858198B84BE5304226F85D6A25DD002CDA5A06EB8193C377A905D180599C20BB3BB51FFEE1A459EC52203E81E495CE1259115205BFB9C528F929B0BE0885D8310F66933956A36A6D451E15D19EC52D5566B09F0B958651255B9E1F2AED5A71CFBE458C7D6A3723887CDA58A63DC0C768C1E6B63AF3CB8F1D0F2F22BF5FFE71111A42E0A0216E903958B5F6A02A6F6851B0E729F33628FC1D6829770D12823B17E57166F3FC6D803A138AA86CC1D10C9B704EDD7FFD328A88D1A1906C8451FDE1708D6F5E9766F026F38DB1E954A8B3FDC0C894BF4EA565F65A54A1F66B39ECDE5EC51FFF1210944A8D72DA94A9638A9ED895DF0AF096D9AFA8E98A234CACEEA1B370B5DCD46824DD6DD65FDDDE7E978659A52D9E236FF1E8196A145B31AFE40A01DE7272DB0FE2C84FD270CCE6D1E592CCC793C1446D5EC3F7620B9990381C8455AF18ABB60A8387B0BC84A2C8AE26AEB685DA301BFDAB4D41115E98A51CA921DFE3D551F778C37A8E308B02AB3684F4E91AF9B81AFA6691821FD2D36ADDA15FED1C4683AFA2140855C430985C1C41B272AD2D41570AB1043A7FA871350E27D90411AC43CEAF03631027522FA1C7F164E9A24789462C7BCA902ECB7462C4B1D5262F1184980D6AFF4BBE18A085693BB54AFCB2E95C1F24432CF4AD37BA682CCCA98C8447B698B14D06DB3F04BAC6BDFF61D9AEEA76BFB393BA5AD68AA5B5C784557EC67B51BBF3BD90E421528DDEBFCCDD52A9E0683803D89847E27E5BFF389F9E5A82BAD38C36EC56A73947631D2400C6102C9F764B81C06557B60922180754F9E728323AF15FFE62D74AC5E9E7D0F960E5ED4A66EDB2D38F775C6A41B08C43ABB3A9B561A61C908C1B2812736BFC9C6B4F60D1827E8DD66488AA1A0B570B2779AD3EABD0EAF112D06F8BEE241EA22D0FB770AE30431A3F1155D06715324281BEB83F8D6352BD11ABB05470984A91C09009AB0C4BB9AF268AA0CEEE8404D50EA18088BDB5B9D454FA747D48C843DA2268694AC4D858700707E2F01EE7895D550554441B83052969D9E6A8C7381932BA04AF70D277A0F90C7BBA0400ED0074448BE6012DAE3F2AEDAA20D0329B2B71D9F42694B69A5B77782532FDFC43F04E5850B7EB7C4421FA45C06AB0247A533FF8AA42A10AF60E01E19D1A0102EC6508DA62F044A05A27819BA6DD7E728FA7F57463E36DB3FCA730C15E08531FAD965B87B370533DD8200E3271BE939721F34B96FFC39D80765CE1FAD8949FD9460805B51C02310BB7E67A", - "sk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7D400BDB6C6487CF73211781219BDA2BB75DF877C94B708AD56A7838C6E8F93A03F4E076E48B75928B3477AC23A937794A4E46188574E1B75A34B3366C922159B403DC25FD105CC7D1BF6C121B4C9809AE0B7438C29E81CF41377958760C8E33D44463223246682C24CC13021D0A06CA2344AE1A8082307119CC6800B346D003791CC124008054A82202AE1004D42B600DBB828E1B8099AC4810A8209108769CA101018464AA4A40050C40502334822988501C04CA4204C04310114160A18822581C86C5AA01181342EA306455C209180828008872C1C4448033980E348689C260DE1004D92A22C42C061C426891407091C498402432A8B0061123668DCB8080A8964E03609908028018420810886C4446061144088302C8222050A3685489608200928801288230448931489624021A206101A4791E2C4450A0271409200C3968C03C44C51B804401844E1A28883822D90960DE0308610072251046502C4318C86901B338614C24114235144986543088A1A204018402D20401002C04060982818340093246004A6200A2462823090E4305251C2300205124848884C866D00233123A86D22232E11170E9A1044E32060521225191002D2C23141A06C19A910CC3040A0C04C21274642202450362921300C13B08922C405E41408448271D2322D6184800A255120A07150124CD810408A901159026120436411260DDA80258A828962921061B02C22A071809404990284C4466252868401C020219024A1868D04108A134152C2246998C48003250E4B066804367209813194445111002DA4069249B82101B32C52C66C103229CC366A11042E91B2810BC56564124AC9248858286C0346520AB6050917690B11820491214C2005D3A868133502912630C4086C081389D44642A3B84052100CD0969020188D8BA669210145C936682046458836306412050A484C54B2092238600A440821098603098AC9B230012601A21484A14046D0908DDA42114C86841B21890B1071D106891C2562D434029CA610D488400B300D440824080670A0C43043164010296418972C64B46460300E148131DC2284E4382C631892113829230024512664CA422A1306290A894450200C60A41020211121A5650C2311241065C4982100310144025000C549043100C1482453360A83406294106CE28891DC08255B0681123969E0B2311A030411C40D49388644B431831662E0062DD9A050A11241A3208480968D49340188888D110622A3200A0C990548286ACB3849D944660A81041C0766A2C28094942000862051A425E4180423116EA3946411016C04816D0C410EA234281B3692DA004D8B488C118331CC968410395003C224D2C020C2027210150ECC80484998651220218B300E63B448213690C9A4099CA22C13157001934C4B3472D0B06C5A3202C20882A40688249328CCA4500A2772C20472CC464062904D10C53163B4442397608BC44D22218C1BA54421042952A608A42402E4329164466C428228182684D036892236268B066D9912610A2206D0C0404818490BA28D121165512286D93868138768080411D8124A9318491C3381DB107041480D5A0404C82404022686C9A08482B4481928064C845009154218006518B231E4906119286D61B00050084511428494C4800C022989306ED1B4445CA66848A42424A584A298640CB90843C668102962E3368C5BB0500A4050433031A0269244202AA4122222A22404128E62346D93286153A84C9C42410A997149A24DD33831D3064D01906D9080645038511A377192126263322421244AA3026C12B2451AB96D183802132612223649D30410D9B628A1902022018C22262DDC224E1A82881A1106CCC65101195002B890DAC49020333193043190360A84066251A40101399008018E18218223022E4C942D01A6611C940921200649842D0C488E441085420448E1142063240809078223004901A900223941021992423648D3189224260152348E53022251C024598805C48291CA023241221210902018C5505BB24CA0820D239560E2A68D909669D31869A2C28D84442C13B961C390249B0885D93630E032721B424C11394C1B206043144E5A263009320A44022EC100658AA0651B176A1BC08D8C3425D9103252B401D9C24C52360ED4C645100692F07098AE41A05D93A1C684A6F85AE0C3005091536D975F58E54D87BDF53AA30AF6D208193913E3369AED4EF455E3B740B7078209EB3D94FD7326D66A8B0C93261D1AE17B84C1F92571C48CDF1197FBEF94DA93141A721132B8531F7BA05632C88D29260A3DD24FA18A3ADF458AD3ED969336F625CA4EF3AC10CFE394D8CF7AC01A42B9303F6B0EC1B6D921675C44C96E554DD6016EF83CBCA0D43F87F50F38E39B65EE5E2F371E1903E829D9B38D0465878A13774D98E98ADE50B44244C04C9AC0C99382B6CBEE6A5471D6051B1B507E12D8FA5AD2E75910CE1DF16EB223DEC48CAE8BEA1F6BCBC5CEA43B6F88F3220907D43430F3103A9DC71B99D372AE154B7F4E0D379CAEEB10E92FEC9C8B1759475A488183D3EDF3FF9B59D52A86ACC623E383D71DCB0C89151547E07F3D1B60022406D823FCD9C035F8CDD4B5D4577D31520404A1C4B1A0785B32FDAB02BDB35247031CA6EB0C1B8489689CDA38F2DD803E1B27D06D368D9F4886D33267D49DC5E5854A0BC0D76B8A152013681F24D774260A098E90C3476F59860F19A0CC0E88FEBFA673CF37E8E1D60928F014BD0BEF831C96C87ADFDDEB721CFF4926DADD97A967DEE812017D1C5ECF64B67E723C26878AEDA15711F06BDA9142F3E0B7BC5659331362BEFDB8861365154F5699B78ECF66108A9E7B689AE9177F0CCBED79051402B0666365E8BDAA3C781526AE71D00A6CF14B1AD10A3B369DBC67448476DE311EB5B66DA0520FDD4180F2FED7B5C8FC91999E09CDEB463E2CF65EDECD5255F5C9607706B9D0B066BA2D41008BF7447FF67787C3A35569A2D5E7D68DE2868F16923D61F8D0DA5C1BA5ED8AE24390D33857D4C2C08C91BF604525A0F677B0406A2D19CE949E0054F6B6EE0129E95561D62360758212316C09447F5AB159C1B327C7B90C5C32F09C4659DE7AD13702DEAA6DE5482F0EAB4FDB5B7BF570A4AD4D5726105C93560F6EE929FEA795ACDB4D3F1B98CEDCD2FC4053CBFFD8F5CF5F5A6DC1FC7BDAA5BE8C450E2EE64492A06450EFD221D228D0B824A564AB2D4FF899CE2C305B9CFAC7DF5E51C2EB65AA525B9BE9E430E607794022F0C027032E257007A576502C2920BA7A343CDAAE1B9E096D19959E80931B407CECD160DD330581590268CCA0CEDD1ACDEE0FA31B4080AC4DF0C5151383B3EB5B16C6000905F9FF28271FF7AD1AA6958CA868307DC40EF3C841F05A05E30EB923DA60BA5D8FD5ED3AB0DADEF52DD483407C96BA81C11A37E33B02FBC54EB54EE96BF1DAE0B2C8000E88C3AC653C722C93B35A983949E3C4A813831D54E9A08703B71993C13DE6A94D2E30129453E2E4D63CBDBA6744E1447481E76546EED9E83B0712CE3763CDEDD290E1F01BAE87BFDE6782B0800CA3E01683CD4D5F7926E8612C6FEC9A41B80D324E7EE054F8A56B29BDA0F9DE74E2C47C8D891B8D872E0936EEB5918CAD91EEE3D88DA6C1F1CBA76131C1538F6B0F9243331622F9A606B3EF3B3E034B77BC21ACB93063461FE91E83CEA487C6A21C2DBA19251E456F63615A41804CD99CE5CD363390827912CE79139762E72377EA7333BB81D4379956DCAF8806C7602365974448481E917FB5D453447B87E1BA456B6CB314ECB8815C918678DCBC1BE64E993C881802049A823131292E7695BBE6E743CBBAE9CF2BD1785AAEC2FE504DA418D90BB988FA6D3F1B6F9DD3B436AA466DF6B3CC0A9494B4EF308D8E3C017355AC0C4526845822B9ADFC2C2E15EA2C9BB3EE8B02B3E3CC327DDBF7BC98DEBCC2170ADAB1E9504307E7D7B777B46D8E6323F6B31C44A47DC6C25BDE2F6C4DA92A63CC4EB9B5881CEAAA535EF4531CCABC97D37933D401A09380DA609EB0D17C5857724192D01DA491E0E8E645DF8615C7285B7ADFE1959311CCF4AFB0E1187C3A83E6439F4007B689CF94A9AFD059E16B3521887FF6FB6F7162DB089D8729C128AFB65432985693F8F6F8FCCEF56FF9083C5E1843E1AFEFAA44892FFCD74A0B7DBC23321B3BCA93338961F95F4C700E5E4AE13FB45BC9458BCCA5B032C7C9884B3FB67CF59FD60CF1E9CA6563A52CC13C8D4C242BB8DB246635BA3A50624D50B1F54EC0E2F08FF9C725EFE752218F5BEBCA4C37BED12CFAD5B11601CF8BC57D5FCD3D44466BBBCF94D653512EE98F60965386A314B83957E8FBDB60123424A9F403BA489D0EEB202AF8FBD9D8D92C8F05880F60B6EE96369CE58CAE83827018E0ACB77C66755193525C80CCFFDE7DB5FF123FAB4CDA0DC97836B6712BCEAB0F4F7C4FA3F83425BD7528F51A4BDDCFAD5A66D1BF90D093FCD0EDE8FFF11DAD38BF851B2313F3100359785A0A77124C9A1E3F3992F16763881C4426BED570B96CCC534AFE4FE62C690C9CEEA653F737022A80B1E7C26CB3493AD4FA370AB6EA6A6A7B34B6494BC3A9A72739491684EAE5BFD22204939DB2D4C263C3692225327A9E00AEF5DE8F94AB7AFE69226E0DD7FE93E6331F2CD353FF55E06DA3AA647D0C1597EA2D31ED16B0200885824C3981AEB985A1D913212A48D6846BBE760631D3EC6238737E7A0A678CC3069917028D611664503E983AF9D2759DB89C298A638940486167111C39DA598782CBE48DD3EF3CB55A4BCB83C17C519666AE344F4010C80808247D6FE659643B9D12CD07C0282ED014147369D84F415B273D3A959836C01B4D7204FB7906B6271027E271B506ED489C8447B73B2FCE2019EBF11836D902027744CD0B5C3C2F1770EF816884281ABA2F758A740A2B1EDEF583B76C7DCAE57C46D09A45AF1D1D78CC4083C243BAFAF302DB0800E646EEFF1E63F0DBAAC2B4A7CACB018EB35CF8B06FB133129E6B8583ABD49B8A374B3654B0A5760B5103FB748D7723AD10066FDB16C35FF25DC0B37A1A8E650674644A38A17935272F8688CB9CCC6A2E7146E8895DE8BD18D018A5E4A70CE5A61172790A9B0C5817EBAF43078BB2FC26D202DFF4F61159E675F4F0089774BD22A5FA1BB66A83E762A7829A7D02E8A7918D786699A6681AF4D39F862F1D1731DF2214FC7D70F131F5A7412C6E00D7F63E2CDD5F3ACB0A828518CB55257EF7296F25E514D64841A4C27CD72B455F1CEA15F823A49627171B948EDB8BA8A7128CC9E1D9BE62A742CF4ED6CAD17AA5B3E31A61C5263ABFCF8714293379000BA4EC7D75D6363D4E08D1AA0E8976D319668C86366727F9FF004550AADD4AFD9E9F7000570AA12B72155FD303F073C06B550DCB7956E01C47620F72D6CD5D611C7FC252E7211E4AEE17F280CEE89B9F1FBB37279A85CE8FB3F9C81189D1589574014E0938E1E03979CB6071158BBEFA2755DB66FDE520BD38BB9256AA9EA8482AB1BA7BA2F723F26C2DDD7788A0C1B7E864D2329107DECD4F14C5C77077AB37A84461B85FE005BCCC49BBCD0659B5C193DA7E7EBF1EC4256A62472813E0F25A2B7BE0C7F305B6529BC4B0202C9535D38B99D27DA84E4B4BF4672819A44B79D7A22107AF80601B8814869D95E2B7F41C5C74ABEEFF67C3850162DE79F66CA805A0686976216A28DDD130871671A028F57BCC8CDCBDD44CC294200F980E8A1A3516D3E2FD7CEEAED42B585897CAB5967C53C5FB19541169FBEF9A6B748AD8087F215F3CC7D6336D0E70D1CA1732FD7F379DBB0785F33056D5463EBC13213A418014324C5583D2A79BD7C83B7F8CA752858DE7BC2BAEB315C8053499FBD4F1C76D862769AF953A3CA5B02A34CAB38D49A694CF7E7EEB1D14B13BE5F69D356F2FF5536C32E1B4EF7BEF1F8C70D62EB608811D4573A5787F5B31FB88728479398175AA14387623C973836A1791946B7C3B67DBF08E60E9E3A397549F3BDD095628E4E0B9601C795A925BA25C2DDAD9E92F4B114F2CDAD6377B674A991EDB6B17E9438AF7D3EAF61524E4CFD0D1CBFAF5DBB8E32BA2552CF016372273DD77C327B161F0D2BC9642007EBC98037A9BFA24C441E3E1CBB9E3A91AA3AC2FB19C0FD388472AF2C76FEDCF0879CC92BD1E75A3BF64BE4403801226E7F097B20BCAC08F580ACF09B9034B66807E9580A53D65FC2454AFC9FE6E52D39C29EB8E6E895AD2C5324DA8ACFCE100425783B3FAD39F62598D73B968605B098141D931228435622E2C3DF1B1A597AB163FB4BF480094ECAF884712E5E20226399369D4E5B5F612E6CF60489A48D4CEE551DECB1D91F100E7238DFB1F27ED04C1D2951384E96F1B7025DD0C1C3143830F8AFBA0CBCDA49118FC1A18FAE7E5BB3B0F0DF455366D3017F2548B2B7A1D20996408B194BA0F7A553B942B4AE572CCF76EF9B345547C1B2C5BD3377115E923157EC7DEE45CDE95F9B1895845D9B51494CBED188EF9AE6E6CF6275179D86F5077FA6A2E9F2BF5ABA69D9C1E937A75DE26C4C74525C8E64FF78062F508B6A2FA5FFFAFF9282953855D561724D1325F4C3A8BCFB2BFFA60EA0B0F7945CCAE9C3644E1FDD4896BBD03468268A2B8CBB5AC94AF36BFA7C1901CBBCF72F08BD9E3887215D37F0B7A89A7D07CFA92704915A104E5F179478CCDED737C1BCFB46E8D40F09919A9DEEA0858F4C2FB3613099773F6FCEEB9777393EFC9563FAF43C0410B9D66966B415A114A570F4255F6CBCAA3CE563B40E9E599C311D38A3429CE65A92283E03FA26525AAA3B71C7C897890075841717E708A2CCEC301D1D80F1062DEE01460C0A134944C33ED0AFB6048C3095FDC5FCA7F66A9B9B882" - }, - { - "tcId": 75, - "deferred": false, - "seed": "DFCC13CED6971EB1BF3243CB8EE883FEA9677D1E5DA8F3046CFA4305DFB79127", - "pk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D5C010151C22FC4A843F9EC4BD804908A705A154CF2A75A08DF94175AC8E1AF30AEF9AFDCBD3C4C6C265527FC557DBDF1E390F1B3112682AE1BC1AE0A45334FEAFED6D1A7FC508068CE2374188E40B4C03FE8C373551C5C1A8BD4C707AD00B6DF77808B06EE9F0464E75508C1DFDA68A543D6616B37F37FE2D1E43F94711F43A7CA806728B2C1B9DC5C3BF3FE86740CDE4BE46A95E99818CD277B12E75878FA1DA028A30040F643DDD97F5F7761056578FBA1C6AB256A803B5B73F4D1C35EDAF40370D4A82CA5AC8E7CA15C1CF77543D49292E4DDEB4CC67210839039C85FD09D9AA3B16707E91B02596240B26C9E835EDA8337DE7AAABE7D17F6CDCC29A5E1F896110265B7A4588683FE140371906917D32B2E7885DE8EAAD0035F4766D0D5433C86D8B909DAF5AFB02754AE3EC78C804B939D04FE775A777CC8BCC0AB91CE39724A2CB0449B3F2519EE086735694E2F266A3936FADF367A032C84808DD355F805DDCE286BAF7DD3BDC27DAB1714224016E1131C222187472E3F9B34637DFE6E5E5B2C9597A8C0AEB21532EEA8F9B1730A20FF975C7EE0FCE46513DF1C87C7A9ADF3B1525267F5FB9230A5E2DA4CAC0755C261AF59BE7F837550A1EF13F3927A1C19909D9A308438EEDCA0E01EBA5AC55B53A9E7DF7259A99D0F1DC5431CB9AB3EC47E0E70AD2EF0CFBA997647327A579E6A4DFC84DD4D49669F8431A401038A4C60FC5E6681F46F4CC13FF0264ADB54D1651050CCC13505E48314889F34F023B31F5AC55CF6DF0D6546486FEEB64542171DD2CE1B80A7BB0D21A1BD12B2E04106DC1D062D3A82BD92539E9AAB000B53CA1A9D22C8D3B28702CD9E0A0E4A6E1049EB64B08F47C409CAAEA917CFD656FDB1975E91B8D33168A3A3FE4F16D948677376129565C07FC961301A45B2120A6E05D0CF00FCD5EB40AFE2C45B4DFAA84CB428B1AC2379CE170A31C75F6C0E94CEE84AF08CF22EA3FD73CC31DB388F77D20764AC80E9D98F951E43443281F3922DBBD7667B436CEEE30311A9DD123A7596C46EE991C5367EACCBE4C0E0344147C065754F5B363020C9093BBDA21CEDD00B447E97C8FFE0616F976E5D9E2645633799E25419CAD1D5DBAEE26B160D3A7777C3CAAFD8993AE177C90D31FF8FAD80E92A6C0148623B3EB04F1CD67B15C0BD4C1A1838FAD512B9632D5A13503879D1E44093745B1574D236BEBC77D1AE82E02EA2924F83C942E7A11D83D77448B9939B0588D84F7E64727C73647AEC32776C2F867F49675F9807A68E4FA09B2268859F5B27AD89F7EA7F1C8FA1E62C3161D5A92C167D4B5A2E76CFFB8D74135EA212C51A4CCE21C909FA2F4B2CA63C6E193513D8C83D716307FD122E4A6482ABB12C25F57703D37D170C5DCA08D9D39498048D2BEE47DF26F64ACC6869D7705ECE719470C69B270BB2DCF12CC014DF399BB6818A1E8BCDD9769AAD420261F946B7B0E73CE859516B9342F0EC25808829E569895123AD2E98C8DAB005D8096B849497892A749A543601F846D87CD89BDF6710D5D564262DDBC5EFC069F33D9BDD8A0B04BCE9ED672038F1031937A97693B9A9933BD577935B00B3DD9249B369478F5561BAC68633577BF71C27895D0543B0BC67A068E0500F90DAF1F5F18011D04A506D3B9AFDE41F5988991A30A109DA4B2D4AAC5757A7429410A27CF63C1B5810074CFD5AFF6A4C4036DB6D4CD62CB75895291A3070D399C8F435CE0A2C266FB5285011172C444204F837C6992E2FF444EE28B22A2FB6B8193FE71D03843146099CAAA242CAC6F74ABD5FD87576A69EBAF3543C6774017B7A1FF5851660B62F54876EE54AF01FC9024BBEAE59A9283C1BBC3E92CDE19E73F34FA575803AAAB0DEE72B2088FB8E0920AED48DE6D5C12F8E9CC64E9E96F153243B997EACE87921188589167F43C660DDBA9DC067FD857AFFE6145C49EBB6FDBE9D4F6FCBE420BB5D4D315F5E2CA1D519FA65D71203ABABCD82A4167B9C8FED8A45141A2DAE15571A61E80169B234CFA1E29F352D0678A487B84BAC6DBA09EB8D66FBB7B3C1311C715192EAB0E5F51EE5C9E8FB30D102799C4E677942B957283EF9A6B5009C784975CF386318D7637AE8633752E8E54DCA2B83CA7E49CBC2FFD48AFDBC3D1098ADEFFD170E981DD89BC5996BF60DD58CFEE25C98B49C1CDADA7015406F001D8160F496131A7C7CEE245E969E44EBB91361F67F19A2F40A9414C401635A927A664B770F7BAEAAD8BC92F77C897CA3266CB1334F8F6BF07E327EF3BCDDF28552A3AF763CD526C7AAE3AE1AA021212FDD48A3FEDDD6044CAC2834C0B02015385C92CECF10DBEB46F85ECC09BAB13533E7AE1148CF63FE8CF943C563DCFB66A986B66C3A4D29D6CD59F8837B2FAF10AB55AE37C0BA03C82319C6517F1F21B2C1C9D28D328B8F8D1B2DBDD2F4E1D6106C1B96DF68818A0C16200C5A5112046197E8CCEF6987B49A9BD0D173CDFFF9B881134C572C781044F183E251EB3ACF77C98E2E09E5ABE94D560C6F240295F552192770D1E0CF08EF6573882C64DB14D4B7EC869F3505E764CA181B9898EE04CD824C93B36290B1AE286C2165B02D7A1C02CF6E3D4530317CC53164A34E675ED6FCAED968A67A975BDAF4717A8F934494235FF4BC29DD78E8610B3CBACF8776EB687D26482E7E54C4EEC6388F27BE203B582549A8AD3DE91396A613A061297CBEB572AB559E95F0CA078D9F0FE2C68983069C3722B771A7918CF81ADC6A4EB59220CF0FD2874EAEC19901940233ECE858767E85AB96C8CC5E2F671E1AD10BA56121683E92EEC5B394DA24E46DE8A0C8985DAC50ABFF991618E819A592CD3C6DBC29C433CC7A248D639CD3A172F2BD674E9D18818C78AD6E50CF09C56E7FEACEE93966BCB27AEA7D0E6D099452958EC60C5F0D1D227CA5B342004AF21B1B8C43A27CF11542A478BF3B5C87DE90E801E4C81C4EE131477B663196E03DA4A307C8E1D1716A36E1721A512748F01A595464C30FB90B1EE1F5394E8E31388BA5C7CC273A61A12ACCAA671DBFED51FC9E50EA536116C48E56FB8F8C2C28859D937A2248D4C1BEE872FF12A75A3E93A4A93840802B920ADF6AD2DBF1CDE092E2C8373FA22E6DE1E062E8D5C71413DA5DD48957BDEE89722DABC0B01464E22E3A5CDF0BFEAEA5879ED77CA5B34FB1925BB925A44C2D54BF9A00519DBC68E4591E08A7AF2547931D5403C42BD7A25C4A7C286D8D1A6D06608668E6890B222A8DF12DC7E06B891BF5B0AA145F1ADAEB9153A58F9FCF63154E18E08B6CC5FE09D7CCD659A12939A3F0986BE7AD5344D5306243F2E5E970A797A5B268A85FE721D5B9D447ADF725080E749B88F795BB2476D232BAE3B4539B5B9286DB664C547DD9A037F2DAF6034122F7F10AA8C72CA123F91909C4A1025B4F6DD88319D5BDACB85D3E1A9452668AFB8CA012B3BCC3DB180982951A287F8F376D59C573CD0262D598925E162365A79F05030D5C3C7854F19964CEF5B08BC0F1B542A8F87DCD29F6A07289F6F7138C31A6D70EAEB89BE30A63DFAAD20ED7366E0F71DBEA8B308E416321307D1B63FA54EDBB8691C2AD4B624D0781D5A6CF2118CB3C56A6D4C0F5544303DAA723AE181A787BD643E", - "sk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D56BEFF71C2EB5536183747EED21768A95B3CD546BAECDFD720956DF067C4F25B1B01B94DA624F662ECA6B0B7FB63829A85DC801976DCE9375ACBB16610E1F4C8410072775FCBEC4F0B34F7E9A81ADFFD2B8BC2B651CAE1D079D43DF246462AD649BA26DD10051C8242CC0B64C1C4064A326654198641317889C302AD11644241872238348C2B84C14080C892065C4204148044C10C88D0930901A25498C208154B60C1B26290BC59098028A493684DB060C4CA668C4C828CB08850C4451D2C62C0CA620E2804C62286CC2480C93880840368162964091020D23C348DC00525C466604B48C00C844C232449C366591002842960D20214C08080143A6710A9468C93892E00865609871A4C2905046720BB448E4B470232682DA466521229119415013490D19434A04B8050C020CC8108698060C4CC20C58422D533830A2C888E038711AB941DB242600892C000524C11411A3A870212224144290C9A83010046ED3C00C2237901C3169C9802481A0400A32700B25801A2548034068912820D9129102902CE2186ED2408908498899C4404A94202119082388459A4020C110649044609BA06192406560B22150324A91B48C02B210000448E0465210C344909401E21240019160C9208409C66503828882882C21475160068C99C200E0246C93B051A4229094082E92166D81A00810026411A64912315062364D604602194151188944C4282A400402801411D4B849C030495A00501C8004442812828460614045D8C424133806991686A0A42D033185500689C0A085204924194800183985D9C22512A710191704D82006D9408AC1928910170619B10150088E9AC8498036524B244D8A8221112140228269810251C92882992268C8804183942D0818894C068A040662DB3832DC346911C961E0120E40164522A08D829260042141A09051182500C1421053A664E1184C19A34000222D4822915AA0284B264012C111E0346D1B957010379023C9850C380DE4283011422614A6484A3452E142128206090C07820CB16513456224878C0993005B966CCB344818800003124A8002300302619890254C32902385001A3550083885930472C4288E10C900634204604409C80226D2442D60046243988422264422C49022B2600CA84D4B145104417061B61099A468A1440DE1368A994486401691D20281CA244420114899268190102812428D50165119404060B80C02434E0B3672A04461E0404912474211C024040592439464993282C1106D01144A002185142525224626A0B888E3C80DA02808DC848100912C0BB02902952119373041B68CC9280411195252146E64204213202DDBB40958340552C82003C80C5028281C928D0AA20510B345D438889284041A8649CA1689901808144712A2243104A611821468CC82209A04525C38501CC36DE1C46D11B161123209443890E112501C37705A4001D9444809C071D98088CC141203C92553404912C90084188E83A0219A902813394CCBB0001A296E8894718A1662223221E1B2852417412193711A86448118711CB40CA1A0310B038514154EE4168461100009B25012B94113C2290244842217411B440AD2923061002A20B390CA4204001582DB284D523224603891132801D3326C9B182DCCB450E4C024831211208384CA144D0C0741C8962D9BC631C01210CA20410C442A1C1126C92846E3B66C2021828BA29121016440142E1BA24C0148001BC38C0327261144260A010A033046DBC849E382810B0370DC208C0A9740D00028E0C06D61B28443180113B3690B394E001660249425A228251A81314B26850C32825A8260D0160D0982800B870821B94CA32460094348C2366248244C88821152044E2314040A353048C6840B976980381048088EC494646232808C34514A1220D2080C83384252262E13C211DA08648CC4890C4746D8C62512C56D64C870CB460011B4205398609294488BC809DA28848CA2681989044C443112B085E32680C234509C484A23258622472953B88444A468E11811032820D0080D8AC484138829E38410A498490C164291C8052285411A056118158ED4A430D04011224862A4868460144EA0004012B231A094802325125C164CCA8870043168C4A6851AB644D92808A4146213346A0381089234282241128192C6238102623B7DF4F576A60F0705211FF78F5BA73A020C3B5D126AE4D98FB954C361C73C0DFDB8B56A6666BEB0E11EDD0336DCA6E9A615259DCAD0FD54B00385AF5E6CF0835D2C8A20AC908793D65180777E45CD2C3397BF92CE8B121C94B3B4E410816938B434553F464F6A3F8EFCF1889553160A4E00BC90D7E0B455717633936C3EF7031EEC468053F036EF3F1B3156FBAED8E93B62132BC5C52D0478A12ACD5ED7FCD44B088588F21A416B76B3A1E05B4BD04A2EE2F210D812C67C4638587EB614E7956C3FEC3A128F41B03427624C98E2652CB37F6F6485B776C9587ECD1E24520DE64B2A9E925B950F89ED3FB37291F520B96D9AC760AB59B9933E48AA852106883D0683DCE40CBAA4EE8F04ED06C20E6F1EB8A71D843913BD8BA253524731ACB3761E94DC2C99AC1022F7713C45D85A46E7042B4699D2CCD9E6C3930EF9960BECC2C88259C89CBC9FBCA7279575D65341DE40CFB2DC3CD80590D46C5641E59DF726E68FEA6D145D0E385B4E03D98FED14E85A3ADC9A71A4C0F3852E160B1948D4FE1A2F77F417C7DAA829077B94BD8B9FE4695B063279E08445566A2E6C88716058A12D0DA5D0E619300C692B9F1622DB08385E745FDA142B21D73BA3FC12CD8D8E644B062DDCA01586597F2EAE88FB44F00C594987D12AD94A6FC54736C5FC582796F8F7E03621EE0A2C686F804BBA9C55A1AB856761683289AAAE5220FCE946F7C33F75898F01813DD1B96290B2A0D6E841A375A7CD816115147D729883731A9B84B55EE22F6D7CA10DA8CEB75C6D14C09C16C6C08E530FB5C02AE2872BD176FF90E7F7239836A74099737AC774C724ED445016827B6A7EF68CC805B0A6F42EBA2FF2D2B6A4FA44678D9D2187C394A479CA5B36011F434A2FD1A59B06EDA840F558943D90E727268448EAB601538E1D57BF18AE50A3A63D5105C4814FEA4F65C5A2BD5007B5A45995A762757B0B7EE043726881DBCA26CA06578B2E3DC06DE188153FEB80F0E798C34CF2E6230DB50072DBBE055EF4CB8F8E89F83FCC119138C531BB24F490C90DA49CF5CEBA383E5073502DA63E0EB6C07E611645EDD9BE7A8101C439A877AE8465445F17E0E665DC2E03A0459B67594DE4A2B4FB484616FD9DB0A5B593A50C4BDE3236E10D353D394C36811688BF41FA28226045B8CCC6E4D0F681B749FE0340D0AB52CF784383BE321A258048DE6971549B6549620E6A7B71D969E638ABF3A5E40CD19CCA7332B941D54661BF268C7799C37B32C639CD3C5B1CD2FE73B04282337945FEC5131FB8990B52EFEA62DC02E3408174B759E1DECF8A19398875E4DBC73BAD4369783FFED5B7CE954ADB3AED6D3DAA99746386EA51411EDE7D728CFF25BB33983950DD212D592C5C3E3FAE90E0115DB9351185065723CFA42EFE64242D105FAC50403DC35018E2E7BFABC7F868E4C7D34424BF42B14E42EE84CA911F5F3D466EC727D472BDC1D84BE1C7A4460A36966CCD8FEEC52AB551566AAD0F2C1B24AE259CD655B0AFBB2CC4BE38704499F9FEFFDE6AACFDC54F5FCD5123361C9C01C7BA5B52C128D6C3D596736CCC82E09CF7EB8FA06510E038ADB0F6C00234C3014C5D10DB6519EEC95DD9D19200930D9E5EC24F06D206399E492C10CA910A4A0CFAB970BD1BE66E2C1D9B705A1B7E3C01C443E54E0F10D9F890EF21C543138EA649759EAC899A32A3FAE1BCCA5F7522EB4D524C13AB36AE5EF2FAFE33545674CA0F70573FB0D674B14CA0CB873C33838558B7000692B288D70C09E3AD9E514D95B970911E2CC3C9A85179C2A39B8586640CF6F34D203DE9C10829DBE1BCCB34CF9C83D7344A73305DD9292CBF0160CA139FE5419CC012E69B741DCF35A3DE08822D27B9680C7E63F4FA0B824A7259E932BA573E172C81B46DC710B1F8161EC2D2B880D1748B5F08FF52FA8D6C94539A15EE5024E14712AE62B196675C7FB17C7802FB68F4C3C7888F9CE863EB82C3B9A840A9E1FE8BA0A440644A9262E7F924580F059EC0DD2CF948F4D77DC76FA360F6CBD022CE3502765AF333D79A4C2257AECB069116CE1DB6963A11401E93EEB8C54B03FECBFCC8C68B8E1C049B6D348FCBF52BA7FFB264C5EAD3D15D95EEE901DA2FB401FA0BFA8691B004A411D2925E479A05973B090AC060FCAC093AE9C42DB104420AAB012B55D5C67D26DBC5B8ABC65A189D4E7BB40DA12C121FC166BB1D73BC6625E87D42F8D633EF76F43E1F0BE4C6211C1922CED06685E895353FE67CD70219AC3BACD6EAD3C54B92985E5A12A805EB8FCDF31BDC1FED3C730D3D9D62C22E8F24A9D73D5895D92DB38D783F8EB736D809117B45C35EE8F40056D690637173785D1E14E0EA90FFA8C97864B63232D2AAED14C2415A00F84D954AF103014F676ADD1817AB83B851CC016311BF31333915ABBBD7EFD264CCF472FD99E86D535E1497885774D17F07D19E0CFDB00F7A6682E511052BE0BC1846D8DAB478977034D0CBC1DFC72FD7F68AB51C824FC88115DAAE9E203D5033294156FBFB6E0F400B7B8F0861DAF592D4936C483D5DBDC98B7A576CC9D26E54EAC4CF24FF91797D48AA1374772D7F0B9EC4AF5A76E231E2E847B7D91F8A6D89A78EB1F7A039C3F3E5C3714F2C62212382806D78424223B84615ED361C49AFDCBB92243555B0D777DFB8F00005232FA8C97916EDAD87AEB466EBCDA6150F0ACA969B2D21C2E5FE2D7C4177E622FEBCE6AACE0842386D29A17FAB242B3F926BD8700340CA7B4B5383200DE7C93A701CA22B9412AC2F1C2139B9D332FD585B8E6B1E0721090F64BF871A2D0C0B5E0A0391E2A0D1A9E9103BD08DE12749A6F6FF03D2597B1F3BF33819F9AB2EF83B0927445BD727F161279C6C2DD2B68C229BF233F8BCCDB4A61D866F2D4F705439F990A32A0BCE93360E798129D95F284B942ABD702081AB6D1813FBD52B58A421E96FC0A715EF134CB1297E2AB3C91E581E3CF97223481475D955DABF2D0B8BB5F134EC14D84F102C9C57CA4B90589C1C5250544C760EC6CE839AA85BC0681D744F716A0E08DA4C2201D3C7EC51492A0516C9CCA8F912B03CF60AEB07F4ADFCA22C43F234897A8F518271DA5AE07A8BC6CDA35A5A58FC991CCA18E59E4CDD1F15251823961E38A49815FE8C766B705DB01A92C7A13B7F68CE43F21F692EC29CD085E70CFF19C6CAE0D08B30A155855024BFC9D95C87A01666EAA44986ABCF2F9E146CE26D2C12BC816934D179D0FD0CC1E11B5BBCC03E56EB056B6196D4700C774752674861A402C1A94A0032C5642C68ABE913BDE12AAC92D335AC19326389CEC3C5BAD1735C0120B7EE10A0E34AF450A663856D5931F9195B5204CF22A426BD28A6E31234227F033F311BF0A826B7B4F6E216B63B3B184466AFFDE10DA3FD8EAAE99CF91BA078532A1ABD8680B50A5F4516E3DEF7CC3AD7BDAADF662EE3EEAF05F918A598F979A9512EB64BF3781DF8CD988403FF0570F21A6E09484950F6CEFA7AFAE4142058B39D715E0E4F620E026D187C5A3D8C05EA644F155AF31D6FDEB4313410AC7548C88B8CD9274D2B190F1B2ECCCBBD7DAC21C647038D2948DF2DC80AEA5E5923EBE72D9C726E6DE0A266A8E6B9AAC80E50C7D9AEF2E2E3919241A82739DDCD2CA4AFCF501E3500FD2EC421D9AEC0FB7A311ADAB51E213933791EA6F0557878056AE3AE35FC18428ADA90B518F7665F4E896EB78247B580DB4F2AA5FEF1483155E08683B90D8331EE8118FB4EC738A19243CFA72940FF692E736D0B5AE111350775F57A60CE87CBF19CC5677B1A3BE9E780D15E1D09160C4720713A4F74A362C99C85697586382BC54461B120D17977A09CE326803E055B1AA4FDD4BEE7CEC045BA9138A30E9B47DBED84040E983CA093159E1F3B58AD2E60E6664C801DD79A8C8E766F6FE79D72547BE2895C40A469C47E8AD31CF8F5BB5E79543830942289A5C099E89B2C723D8A72B2133C87A25F6257CA5E706EF1E46EA59EB42EEB9CD3D9AA7A20D0936F0EB8D4F8E51663434D8DAA10B5934638E49BF0B8208B7924BBF61A1AE8282AB13BFBC1A8F2DBC003B48F8A20EDEC06CE9914CE4EB1A5B916A36337E71C30AED4969987C3F56BF86F09E7353E194602161CC41705301E7CBC384EA3A15FAE91A17ED8E1B98AAA6669D3236885CC239F69DA39C2A7B358605FC2111E4B90C9674DDF9434832E0EE97171B78A2226C6099C0F5AE1F6E2A74B66F52EFA4C2CF3D0FF7B24DADA3A62790325C96B990DFADFD2AED3AB5535413C221D0C584A6D586BFDF0E13ACAB23EB2108D996EA4DD7E510C307040AF3110370D38CC72B91B72CAC1AE463F6BF174EE189CC125C9FABB1C59051DB1AD6443D93A8F83FD9E9C39A69C2D48A170BA0F2336C48D653A06BE3164636DDE839BBFD2AC9566F750B527CD911A17EAB10FAC460926DD0D49871E070BB84413A200C8EAD2E1C2F8642114EA9688540C57559DC1D3D325988E1C34E0D48F9E05F731C9104E83F39609293AA760A8D877856B68A08E99E6F5D31A4C19FB2C16B1415D1F6ED290C6C3889196ACB26018A68DE48316EDAD2FFDB783D87475EF0B3D23E91DC3CEB668BF71DC8616B32B7A308DAF553AC6C0B4BFAD25AB48166EA09D4BC36BDA8E34FF749A30278BF0479FBCCBC84DC6FF077D7776E4EB54F3A67D7CCAE3AA19C149B33658BB40751485229609E21E21BA6F0403E4AA5377" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json deleted file mode 100644 index 4088355c10ece..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json +++ /dev/null @@ -1,507 +0,0 @@ -{ - "vsId": 42, - "algorithm": "ML-DSA", - "mode": "sigGen", - "revision": "FIPS204", - "isSample": true, - "testGroups": [ - { - "tgId": 1, - "testType": "AFT", - "parameterSet": "ML-DSA-44", - "deterministic": true, - "tests": [ - { - "tcId": 1, - "deferred": false, - "sk": "C1623CC91C677078CAC1FE857F7DC40809F390BA0D51BE7BFBAD9B55306FB2E1C5B3DE04C3E7FE3E3B24A41F45F5FDD3E73A72EAED3B3F57356483D7CC102953873F519C79E445456157FDE4EA5F64D613E5ECB8C6258484AFA36AC4D31AF313FC17A5835184087F04CBCB7AE63D41AB1685FA02D1A64F5D0F844F6FB5213DB1C0444190B48DDC04111AB824DC342C19164CCB242803018284C2416206650A280D2020900A83314CC62DE1824C128489E0844518A22D141628D19290D01805490010E284500CB409E11429D2220118A30D10B561249449C2201213B525CBA020DB148DC3280853B0498B34262045919A424910098C89200553A00C12430060C060E33869C4428CD984648C8009C3C844E1886520478060264601140EC1046ACC4045E444921921921AA15023074A022444903470C33250C9384D824249444042809060842811021660C242251C102EC034060BA74D81224C5C286C50A861009388534062A32671524268D42225D9106C08314C231385994608CCA265E222685C804904080013236994864C23A03014184DC0063114488C5AB0850922080A396DD29045242588890286CC18858886700B474CD02461DC86511B932CA38031033764092446811802503671E44624A41632C9868CC236700CC489038910601670428811414042A0A224D92831E344451A2548A30281C024701348224BA06003C38DE1184C59A64954A46810348D4B34815A00215C24018442685B088E920002DB42508A3071A39881811871E4A069A0180603203022C68C8212824A180561A4311402301494691840619A482919868051308414A30C01350D94362DCC220820368624280E623200531045A2388C1039498004465AA86C892682E2C601CA14652340704A246502882520B56508025124248EA42408018270D036804940211834681C862490241018239023406841384D1028718C4226D1B04099249214219140362C0B216689A268A23280014545A0320C89806492466DDA0802D0326E9BC808D2A249E0006D5A226A93B42020364E413669A1124C10A2901CC66D99B26C92442600004A1AC36C9C4221E2B66C58120409850420884D19A930D3347159128D024271C0140603A790D1806C00296D58B8011A29441A308124A58C82B070D2B60021270E48A809248709192585593462A4460C13160E8B844C4AC07154946D22235003244AD0808D83B644CB066289C250C8486811407242C409138268D0B66980B46D52097202586725A9DD16DFD951EFB6F6FE3231A2C471231B53057FD316DB0876691543D51B66FE1CD1ADF7A9A73C97CB74056DEB19AAAE8DAEC4EE2D512F19B5521DF260609A5F1DD23CA4EEBFECAEBC9CB0DD9D612D0AF491655C6B22A2AB52C6BDF09B8C05784D2BE8832EE184F7D7EEC0C15F06052258A5DD658C74DE50D9F351979A1B0E5D4C94832DEB34A09F08422C53BE60568F81F379B76F5C1F85A0E74434942DC524D85C26A8489C273643CDBE8662EE0D7EBE56C7E4AC93D84016D99C0C180D24B6B3A9234E60A01A83DD64446DE5DBF8AA770BDC66097BAD4261AC8878450653F21EC34CD3E6F1303C44A4D29C9E801D6E87DEF63D4D35F7516A992B788913829191A09E9526F8CBC361D6530EDA7EC9013AAC629177CCB744CAAA8ADAC376F0222B97997F273BF7098FC39A63B899CF35D2E9D397F0D2A49D320B03A9FFF21D98D307DFA94A328E04BEE9D58B77C53303779973495E3EDEE49BAB18E3634E23E363E1F46F087D8CFBBBA8A210661C6E790A6A6449E0CC2738DE05A034BFEDD377C0AB454D4F39FA6F4E91FDFCBE621D0AF8F84197B4762CAF6D5992643A16BE5626E52CC0ED24895F629B02D3CFC92E98BEFDB1DC80475FC9EA7A40EFBEF650355B03B76E7887BDBC2D4EF8FBCDD6D95E260FE6561F17C44E1E01F6712DD0E5F7EB89766AF3FC9370A7C168F64746FB8F744D146CA781C6C708A963EB90858930875223CA379428A71D8008C70264C87E420ECF17DC963D3D7E3C8F280A8716EB636FFB857E8AB92847CEAE7C77FD2970DA98D08E001AC9605BDD6A07885B330F04AF2DDDA3EE6E9314C012E3FB14358D67070014A728B6ED5006622052EB43B77EA3E5DDAA0BB1C1C6A973C8A455786A76A673B5F4BDD339258A7218F4A210F0BFA65B4A07EDBB199EE755B8F60CC001026107163EFCEFA41DF85065D46FBA9471513268517F06B5914F0C625F3C40DCFE428853BB58B10FC19C2685007AE56F42CD6730CB4A6283BA4AC4B40AD9D9B2FEA1C2916111C39BAF1430612E569227E2C6AEB11E0451AF81E308F3BD59CBE29D940E2CA1653F6D6C70CB1D3358392F2A97A34FB9BF05203FF507DA2041AFD85E4643A77CFA441963E282B7B2A5A2B8D293D036CB5143F3E01722E589840DFF12186B7D9799A3D74E99288FBCDB6D2CBAD2E5FD4B449AABE16A12924AEBD33AE5F61856EC66F44C0B09FAF4D0C20CD0C59D760368B335CDA9422C695653E06C0E839EA7FE946237B222F61F9F02B3AC916D030560B8ACD07A41E7D54C402FA7CF6983F09D3E46EE6A7F786FA39DC369E0EC4A30BF734C636DAE26D756AA781E40BD1530A0BDD4040AC17329DD6B90534491CB2AE4D179C2215CEB1F466E7D871D42FB21106834D72BBD656D836F09FDFF875B0029D9F3B50BE25BF05D6A2B0EE322E969247609E16D321CC928C3C7F9CAC3C9F53358D066EE23B52837FFDA6CE77D6235DA4FC06869BFFF3FBA209E8255EB6DE7DC40D0C89969DE0D33B5E54151378BD3021C2A8879BBACEF98AC7F542CEF27F8C639FDD3BF0A0194BCA92E46D6AB5C44C7CD960B1409A088304D807AE67442712E3F72171E06FBA8CE1CE2A6A15562F6BD6968D15339233C5BDD9A5A9796C1DF657F08BD90D1EB5126314B16324A63ED2E8486716B38DFDEC3B14BFE21B2D710BC4DF2ED5A45993DFA197E5B190BC11275E5D9B2BBDAD69E819E4FB4EC859B8C6D32D6F21A7CB35E62ABAC2892E0C6C76D6A416FE3E5CE80361204CDD30C584344C3E61BF91A239B626D8C57750CE0FC4BEAB5743F93083BA01FCF2A9B4CE04BB80AD8B3652C28F4A81D96ABF4716E8EB090817710AB2D052366391F1897C7512F221221B2EEAE39D36C24B919CEA2EA7EFC42CA4FD6FEF946BC241106F12FB82B12D947527723E32BF5029EF8E6C6EEC47C54FFA329D8832F43811EF85FF1B2133FB6240849D7435EA99DFA76EC12ACD6E7AD590889441FBAF7278F019849872D9F4A281764005CC34951CA11C2CD1CE31E51CD2C9EA8E4185274188718D56780DA3F7D234FF14422697B3B4B3936BB1607BB9F048A69A293C7C9DF377E380C9EF8B39990E6D7FFCD4FEAD58C1E5249EA58F9ACE95BEFC1A904B6BDC284577D8FB618278D1F132DE15E55A09FA1A558999298A02B3787C5E53B34EE7D017599CEAEFEF80AAE2953E1CEC97E880349C2AEDF507B3AC853EDD5C0D8081500DAA684A20CE3462E1338917748A2869C9708C5A282FB7D66CA0AADA519FC56874D158D8951BC66EDF57EAF987044C7349CAB7C91BEC1655F22006182084F1A65C356CA2AE8AEACE36D3C5EA966C23F047EA10F1681B679", - "message": "430B1F46E87DDE9A3D055A7D4D6AB1277B2DA6EDA642896412126391AA2B29AFD81C246EC839929F5C06749491DC4D81D58CC989D8500B6879E8807B1C3AA0B199EB599AEB86B344B77E3DB1AA034C938D80CB4BDCC29B31B710F57C7E491D99B71E97DD6FDA01A0D8A54C7481C2786F64FFC53AD358CF31C9C875ED278CEA03F2BF732372B19252BB9FA4ABF465FA2CFD1C08684D10582B410A8E012DBD407C5140D97CEE768C6D68124B2C84113B58C9A2AA67093B44CC3B6199FF1EFA6506CC28BD30BEC4CEA88411A491DD948DDB09ADFB92C40CA50E709840BC1F107E0CA428C111EC4505C5346E74AE4AB5647C1EB80F9C07092F8D39A975C4890317F9C0EF474110AB941949029BF39ADFB8E65CCAC0360A3EFCEB69D2BD805E4FC8D0620F8E039BC046DFEF1ADB03F5995FF62AD41352D479084EF3E302578B83332506918CFAD6E3BA701C94B0138DF0CF6C2948049274CE61EE0A64E756306273A02D68F3C405883F2F668820356812B2DA3A32B9FF23608DFA559183151221F83DCA18253FCA099FE24728F302C8B7808D7AF978299F3EB853A8BECDA46B8657598BE9ECE8A02DD4B25C593DDCB436B82335EF9C6A7B8426B701C66C9EBBFB3C8405A73881DAB57D1664F3AEC6F5BA19155D89A0A80B5D01C46BC79E1D4338A50B203397CD4B16ACD597A7C77C49917E9FE4B0D761065CB89C758498868B14BE2B6FF758745AFDC535EAA605C3F97648034D2A320264150278A7F1CB114B977C9D6BC1F29295CCCA16B23B7709D5608E4095E41D08B22AEC6289ED402414787062B0DA2387B6DEE76B32E42C51788B65E815E089BCF92D778F49A9707D37FCFBDF8CEF953A48A4201FA0173529BA360BFA6A77200F57FD5245146C2CD7FE8882670EE6878386D06036F0E1BA4B728CFB75806F05BA6409C514731B0BA8DA11015A63A8B5B5AB8C69703185191D12C5611F1407E8FFE3E50FC39C3310EF4091BC09FECC11D3AC107C696EE89F74CD6147830B4B3A971A0027747B62C528F6D858D1F9E67F59496C6B4E9E03FF0A598B26625B06C79863B5F07E265A40175E1A6D6EF3F900F3C4A28AD3E49D4D0B7E4ECEBB79244264474CCBFADA43FCD33F4FEBEB0F7E5928479F869D6A0FE52EB0CAC1232D7F674A057DEC4C2248934A40F5E2C9CBFDD53F71FC3BE06E48E13398ED426D8D3CC82118B7E8E5BDCA248380F4E64C427D1BF2384F60F6A07F01EE62AA1746CB143F26412547E7EF0E8FD1F2DC606F3643DEAF330D81CD6309465F9ED7F34D9B175FE1641D90212D4FFFB91CC300E7DFA0C555F7B35D2AF6A343D1467436EEC7AB95F2C34010FC99D66391377770A7DB8CD4D5C6BBF931092322741929F790E037318D6ADB74B4768C11F0E4674D18185DFB3D051725F93800CD38F58688AAC747F885908804D6CADAEDECB43131D75B18FBA2D4BED8D9BCC2156FB23F8F6378C622153EA8301300D0FCDEF1E2BB4E6F807784EA0171E95C372EC19B05A6C7B8DECE7080A057D29CE5A445A83410EB83B174590647424736A3B6967BCDF8A416A51202CE3F00E4D97DCC2C48A78D12CDA98E94A9BD6CCBE09DAF8085304F6911ECED3547DE9512461E16721322E4E6233BC7CA360A9004DA5AE064514603EFF0DF4E2D8EB04E9574C59F3AC14726C10100C688203F4960197CE696730AD7E558D7B939E3E6E7EAC4E70A7F6AAA80C1F1546E282B5CC7AA193213769B137C7F450AE5410817166F29F2E4E7E962932DF282A9F08A1DEF3E19C251F95611DDA9CFF4E2FED873439B45F8451B9AE06C6B2C698778BC4C742708BDB54CB35B686F0E7FC856CDBF977AFB663DFE44F7FCCE0E0555BE81EB28984BAFBD6FED3F0182F78A1396AF7B7081280864E5E4BFD7C52DA28BB5DE5FFA211678D13D41BF825F4B21BE1CBD29719ABA341E7B0C3F101CEDFE2F709E4DA4B5A6D0C021152AB546837024F4DCC4C45C132A038315A0F1D69AE768F70606D070169AE0818685C4BDB7341BFE15AA0455F535766FBEBB50875246A6DAE86C7B9F6F3A9FE01AB9928A99C13E6628431D41C1506381A63FAAB57BFB3B180F5D7FF59A434233EBC5A659B71CAE6970CC838D5FB638676216E3B16E8BA6C01349A7482AAF32ABD17DF7FAB8C69789F0194022BC4E62B6A6AAA4CDEF13B1E3BF5E1F4FA69F82B1EE3FDCC16DDE1106E3D2C41F6E661E33984DE7AD6021EAAD3E64D8C9CD7B5CB538AF88DB82FA048E5705EFDAC0EF479827EDCA0255BA60771A5EBC716C690CD3AC840FB6FF462063503D68C199050BFBD64533D94E093A47658822A25D54CBBFC689DFCBEB1DDD5BC6190B8F02C6FF3D001AC63729D35C8C50FAD3DCA2E67C5CCC6A8799420B159C7C5CACAB958B423964C489DAB1982A4E2222D700BA5AB772C4A11A44FF64018AF477D054217EAE28FB8E37595941FEE7AF87FD44960A144DB0CE2A44B33DC79B1EE31CAF80DAD620666D0ACEA76841EEE6CE81C6FF1F6D1027502EF89F1595065CDEC19B30E4B5314EFD64031B3B9DDFC6C95A4943247ADF7E4C93350C241ECA71260A454707B84017C5EB7AFFEB5DBB863A1CBDE0062C662308A2E824CDF6397863EF78F62319E2873B506F8A9EE82135B803025D962E609E006961EA3F7B67347518E70D9273893D79530F67CB678D6A8D28A0342BAF904BFC0A69AD575CDA4AB73AF22B52AE5D58372E0C26795CA96A16B8461AC61E6F68433ABCEFCBC16B857A89C475D1A322D34266539A17D485B8FA356EC3E154D37BAFC4CE75829FBE8BC823FAFF15A49F847C286F999A1F2C12B03E8F8A4C34A97588D91971279FFCB100EDB943E636F78ABFBAF88BCA5C55C935F6147E51BF798267E1350D2F5E3F74B339F6EFE86208C5BDE149C5B71056BEE748D06614AFEAF6DDA2A6EFFBB56B0880AF9B201B3C12055D292E3BB556240DD031C29A67BF244F59112BFB6865EEEC1DFE1CDB1E27F0A9E3372638FE4407099D0E54E9A188079C8BB9470BE6F63C83612D80BD60C21B251B64236E5CAF09A11C12F1A5E94F199DBC7C9E394C0B0E07A583E707E5241B8FB33E39BB26C31929F39316F4FDE206493566E17B51CE635420493176D8FD353206EF87F0994F039DF8F008AF602F50D7F9C0051B56227F3A2ED20B29611219FC4376234EB900093A81389ED00991272B739389F1F978A92A3E41F0A28985D697C01240875AC46A82B2FE94004CBD7B1E7594AE38A9DA0E84FE7E122482BB391538EB8E85AF9DC022CB32CC08FDA7A95165725EC29A0F824F97F0251BE636B57E0791A7F50EE190D45749472B29A674239AF95B373A40A6E0E09C674071186B125EF5AF72CB434AC0AA990341F063EBFE30963451491474B603733959A23A6D5B8A378F15A5A5B9CE4BA44BAEF6AA531AF5097ADE73F64AED0A541784119665F548FAEB447DE108AB74A74893017F0A1AF84AEF0730B555767B0CF6AE502E7693374D2E01C54C64E411AA93C96DC5FA010267B387299D4376FBB190E1C51A560871B559FC800D82ABD119A5732B50270BEDBCC8A636E7499149AE0E47F736FDB71EBF1995D1E8BDCB0EE96E732E8C2509F98717C3D174C78A4A2BE43DD89195408CD300505A219305809A1BFE7294BC2EECE6D98C768A8A1E0F74B665EE3D652AE8E008EBBB11F0D2148E4E5C93D7FE0190D27B3EBB7D2194BFBB624AF3A894CEF7AED571954D006824950A981F4ADA72BEAA0D820C5DD9BD519D39BB7915681F266DA66D49BDAB9E55879B953A7332F877DC5F5CC7BB3C9E1C1F2E41EB55EFC02A450B5142514F1E06D43E48FBF5DC80DF241169D5936432BFE9BE99DCB17293CF968A17F3111C884635EF2BEDFC87DBB80BF25EE9BF57B55CFE635FD99554F5FF2B4482D1948BD282FA282C48C0302348982E30A772BF14195CAC7FE39F836E6238EB1E1FD074E63B9AD0A8D37111087E47FE5D04B62DEB496353457BC76C53A2FC9D5AC9AE6A47F632E6D45E08786DA128464FF2266BFF92B5CD89176A19226F2EB14CDEB331C497F1836FB6C0A117ED6BAF95E9DB8254487B0DFA7301397AA29D95FF2065D851BD302B747AB47BA0AF408B51E4BBBF042ED1B2B604EEF4C266FE243261515778BC9451A8DFB025FA3212E868C3A078C7CFF65077DE94E50ED90A259FAFAEB398A94FF15C838EFA7F49904BEAFCCECD8C9ED4E014EA00C7AEF1D437DA306E8B7DFCE536912C169BAF0A3B78A643D6E210E5550E3B2BAF7EDFE01E721E3D05BAC1378EC1DFDEB2E2AC0F0BC368E0A8CC64F375DFEA2FC20CBDC515440FC2ABBBCEA3584E103BD686C5403EFE376D44F5242D35C9F9D35E1A869FFCB6657823EA0D4331ADD5CCFA99BD6EB3494A48ABBA7B7ABC32ACB8FF00512E1B0AD493F579898847E328C06FE05FE282F8D4AF48A1AAD0495AF1AC7354275A6D45AD5A7B3F6787F893EA558BC5D4ADDE1F0D265ABF73C86550D25C00821C3138B385448E3E02901E2E6EBC6A0F211CB6F22F8F865F0DF3893B987DD086B6674F5464ACE18B9F0EAE948667B2FC04FECEA3E2B7EA6B869D5F66D02D4DB124A59621B96E0DEFBF99A91AFA0CFD6D5A5968E62EF42B4C8908C3719BA0254929A9A183D50C566CE4FC970E047474490FFB07F576765AC5286B2E0FDBF1EC56A8AE8E6F560C69614FDF5C89BA53B8B7189E6388F7CDF7B819F78F3E6EA54C40865262BD2C8CE87284FEC36E2E73BDB8AA9CB5283272A90A6BBBFC3F7FED5F124E8BFD770B6254CDC695FBA0D8627315370E2CCDB89BCC84C96E20805AAF087F9E9BD1A189F4C6D66A6DC3FEF773788B3B57EF876CFEAE1F2C876CD239BE3B8A94F21350EDAE6C269698CC66BAF90B3641593F96399C71B2ECBE50F61B5D6F37D47DF702A9B9E47BED2824DEB19ADE7D7D8830A8F610088CF4BD0AD22A5A4FBA767D01987688BE710235A74129666FF7917B506A18E6B5D6166E8B682BE6B1946A4D4420926FF8CDF2488EABE71EFA7F2536B9DBEFBA08BB9E94086F55B1B991E18E6023E6952D4A563F2420A1536A1EDDE119E5779223CB712AB5C0BA4F0C176830FE523DD8603F1B316E128579E65454C2BE62C922C1DFE09DFB47D4497CC552AA9987A8BFE19C44E207397204686C718A0936145FC102B8A7111F74A421226AE016EDE658DE5DF9D3C28A247A87F2BC6FECF66CE7A6699880E0871CDB6F066D2CB3F9F625DC5E80751DBBC85982982E2EFAE3AB8F4F1EDA0D13C3B65FD2178E8AE4A712B521B7539785BB058176AB4396E6EFF2FD9052D4C6AF17DC30F50630233C3F05C62E151EECE13CE124E58A25F0F3AB65033ACAC9EA6E41CB3FA435D367DFEB0B9C9B37414CF32DC85A3C43087A578165C86D100E47DBA1FE7061111AAA961E67ED057C715974D3144912A58B6DB22D51BEDF6A8646D810190D91B61F0776DA00C8B0BAA7A83F4433F357E758F5AE8F278119908497E717A7AD25B09EA7C76B306A9A3AFCD9AE6B4F64016D5E80BD3FBE2F5EE673A7459B03AD9356148EA83461B66716346DBE85678C37C932EBC53B033A3F46DC28219880CFA8BB5E15F8862D345923BBC179FD763A0F943FC56BAB69F26C0C15D668BAD923D7AE6B35C07621768F9D972E2D6F46551D45E3FBBB577D13F01E8C1AFDBDD2F052E931C0529380F290FA1DE8BF5A11F82612943BAA2C0D086EBEC84069B271AC8656883F686C67B1808E27C860ECD1B95FF6CC6E6A5846DA29992CBA450081B8C37DD4911470EFF281FE94F10636A29B790E41EA6A342A5BE79CAF575FE9B0147F2EFE02874BC8A0E136A395B42E77D9F18CA4F61501E6C1805CDCDC10D0292593481F7E0F93281D0456EB51F6ABB7C379C028890F445D9FAC0D96AF68CDF6CC879A406CF2F0991916B33A72A193CF170B45AA079DB1BFD4B4126FA9AD3ED13FC98CE4C6C3C30923C8C53BCE1812B21BB644ED3A0CC0596C60032FFB1462DF5182528553AE865BF87FB7C7F61D1FD8E40D830B8D8F54924EDF934D1EBB88DA90BC59EEF1F6BF9FC2D17D8E9E0E39FFAD22EB84EFF39BAA70447B124E492D760E55D6301DCDFBCF9173FE293AC4D6CAF2E1964B32973067EC76BBECC65113C1FAB85375D92CE1436E1D1B205A88202B304264620B282E62CAAF5CFE1169EDAD9459B15BF0060C5744A17460F9FB164974CC55B3FFA71AAC13437BE58325E5E27E151C71D195F886F5630925D441A54695DF23F64C6BC3B0CA83F0E88D01BA4DC748A29F42AC2997C2A21EC258E430032C09E73E73AC2B21B55E1DFB2DBA281426620A0545D2507D1E96A3778C780FE77F1DA3B615E1B0D14DE8729229472E6619AB3B67CCAF21CFBFFD1F237E780927F147425B2142BF62CAD6B467A10F7B3DB922F095A0012EC179C4F8D5437AA8024F13A2A485E8890940DB69FB719B94B7D2629D277B593B94ECC744AA4CFF3D33D2250236C74DA057496BEFDB961B89BD6F44D581AD7A28524A6AF2253FD27530B7FF16FB5804FCA7E44BA2A3AB85FEDEED837DC130F533E8215B3AC3F584A2EC0E9B6194F97741EC050576E16349AD852DE8AAE2BF83CB1894107299F101AD5A2C05EC590B2CC698663C44FC0DC7F893F42BC5A2DECFF2FAF46CC1C00FA7294A0184A85CDDA2B1F38A89B1B17EC08555D082411A4CAEDED562C9FBBC1F512118EEC3BC931CC91636461151BDA454C4F029E01231BF170EBE17C526F3D8F705DC46560642B1AF36E3B401325A6CF59B88BCD4B3242D676FF4066E4252ADCA37786CBDB340DD81C5DD0540992F0B142C5A18D3BD1070719AF996E3C3768C3B234D303E6E9850B35C7AE52496C76106D7CAE4CF8ED01767B6DB5603F339FBAA019B08FA35E3DE1129A6A4D578264CF1FC8A1DBF218DD72B4865214DAA795A00505D4AE2B85E90F589065D65FC60CDD828007D4D3A4C084C7EC159C5D86817860CA03545FF74F17AD8570B2ADA55ECA12BFAB5C10067A086A34A57AAD8694C953137BBE901F8D3DEC27DB5DAD2AC96D56C312E25FE48BDC889373ED252B4F88D32DED6702B58D35A1FB40ABE2F2ABDE21CAA5FD0F67E7407A8", - "signature": "8C94308B9CAEA02AAFC29AB18EC01929A029D49F06F3BB4EA3110B1A9A415C77DF646A68302FFB4D853F8B9AFDD4D46B30ADA30213D763551A2FB98F690296DA77F08B3A1C2363EABE33DB1A891C331932EA22902277F44D68A0001D339C1108C3815A68DD0F7396119FB1DC888E10E3A95182E5A185E9CFB0F76CE84ABC199F7D58C7DE375F74EBC6B3338E3F6C51070336A1D513B3BF6FF4250313A52282D32DC616EA4B2B83A1861024AF9ABA17FE0159544800AEE0534511D9359415A66A6D79C2B3173B6281BFC3C96F07F944CEA0841DDEC3BA1ED9B337ECCBA219C675A13A1466463C128FF79E5C8F1BCE22220E1EBD1A071AEAA32E5506B553176309E1EF15AE7C15BD361EF6676046996132716B5391E9C0350C248A70A3552540963858FDDD3456FDA6707B99C120AFD925A47E4DA492DE65DD041E58A881A8E4125C3CAB474ED7D172F05FFAD0655FB7729AAC1C951AB05892198D713657936808A2E9795488F3F6E3183D0AB6B69B3484AC7B9F3C2AD65AAB9901992FAE9DC1E585D9CF7C71B4C7CEBB47EA07D534F9C869B114E3B0BF29ACC2CA60B91055E98643E7F16D3B4FB0477E3AF62C9BC5535565BAE2B8B276B33DFC50C3A14A62891435DB43DA2861154C654A4429ED865A373C28FF41F0C0ED11A1AB963838FF975EC9754C5FCAE3BAACB9ECDD920E365964DC321147A39653FE4B2F2D1EFBAF8D82B2198376C814FBCAEE96411B9E2D958D64AA731BBC1D6174D6EC139FDC73C9F3AB2886A92E0E82C700DD5A83F5EF0912ABE4CD30E0E3E9C8639C4B329B639DE189D8AAED2250F3BA74C381D6A4D333EDBEC2D1511B20A8144B42F0B5F674F4004F39CE1091BD431ABA3719D994893F4CF798F3CDFAEA9ED0AD5A3BF7DF0BF7E9E716CF2D3C72B17870780C724A0A0A2EED8E5CB4E8D15597DA311A4923BC8F6FDB64B9CCEF2C95BC026994ABA7C743F2FE83D5E771ACC2B6F8AEFCF6E1C7360767B9BF995778F95390C303C88FB81447EE993DDA266F031B9E4907811E3868F883AE4175D95C0B4C61092FDAFD2A41514408811828B3FF30150239C28C1E3E65631B178FA56D019BA08822C038F718BAA7A12FEF65C08A84E2E9D6E292774859574686AB024E2DAA6DEF1BED248EEAA02E0D28C73ECF803A250123636E6B8C642A10C3B8B3DA55706E17ED5EA96B80AA9D99E450513E16ACFE6A587896BF17254B4F420EED062775BD74CBC09ED7F925D10D34FBFB9EEBBEF6DC29ED87BDF01DD57EE8909BC0889BDA2AE430D8CF80E211EEA8C41DFCCE7DCD197352F60CAB92363FE4681DAA0C8F62ADD5FB1874151E1EBD8BC025A8341C46D335DED5293F012E7E9C2A8CA2234E1E5970E6C51C6711ED16494472205878ACCEEFC98850E3AEB99F10B6A07CC3A31CA742F1F93B4104496EEE8DBF0480AB395310ED09D8C7A117AD8A9F5C4A3050807A600613723555189F22ECB98F01ED8E69D113A03923B9C0C8889F094B30BC16792565F3CCF427EE9F0BF24AD436DB5C40E6FB66BC416009DF2F4D422A9C719585D47B95BF274063B64540B672A373073FF87291A62C7B9838446321B71356E7BB5EB096E9EB13B51A50EE891A2412E2117A5275DB0265889D74D9AB9FEE8AD1B039A0EF471F1410AAC97323E30DA2F91FF22D33DC9C8379211A404E32EB01786EA0CBD618821F710F093DD276F52A10416648E52879ED2A7FF6821EC49768D687984397D532C20B7050ADCB4330037D1EA1108B3A98ADFBB5457B05C8027E1E9433BCD89ACA8A84B802634C0759BA1AC6C144097E0EEB0A8E1A3A64E3E66A09D443E49ED53FA8FA8A295AEECB459D4CC32109EB999A4BC3CDD4D744EE7D9A73F07D763B8F80F4BFC63002CA3EAB87319EB69DF4A25FF1A7CDB72A74CDCD2E49B5A9D780ADDF902B9FC31F90AE788AFC954074E010B495885153DA0CDD15B26C6436D077A040165B6454A24B2E2162F9FF31B9C4B9199934A7A1FC78C68704B9BB784B0FA15A84AEA9E70D51000D7F335E450A026AA935533DF695F471739D9924D452B3C3D84DC597442A92E9A5C950C72B80138BD6154214720D8F19EA7E99328770A48069506F22869FC67129656E26E8E85242FB6E93B466B5277E8FB8B235A221A86A1191801B6B2EF236DCF910CE2FA399F8CEF28F148E977B762C8A828D57ED48C95711A479090255308196CD168B3C6C49777FF0E4D2319B1C44954E9A20C07E23F79CF1096DAF01ECEF4D47BA517554FCC1C6D139CD2F9F5754B61963DED55FA7638FE20041D4E689E6256A305AE0BF096EE9ADB9A76EBA46F5183575E8CF70CC6F69E5AD1DE54159E5339D818EDD92A2B9345AD759DB829C6BAB42398922788DAE97AF3F12A4354014F147A27E267495208978D736C632A5F0270C561353B27BE23CEAB57AD68D02F9AA94F301D3FCEF3E6E234BACE92F5D8BB1F975400D0D6B22F1347DB350CDBC71DB4519BBA4FB5C243A91BD0DA06C1155514E45184581815C7229AB66C921F2BC95655CED4A32D128FBB6B8BAFF83708CB49F69502D90BCEB6BD55DBDE19732098D1D1C1A26C74FE56DB0470C5E76BC6F4927A34D6BD84E57233E37127146295E5F19AABB77F9A6F90D702A58CB0EC0648AA54753AFE9140A9A60EF9814E43A916F07043819F09BA02A7A84525C34D3492C67ACA7C5489B72084CA7D1D5CF2A061394FAC77DCA111DAEBB9CF6C1B270A027F8D2EE04E0BB68D6BFA136640D04366864213F9EB3406A747B81EAD497416880A0CFF50F95784C044E58BC0839E6D36FCA9A45374A4059C812EC2B47AF8FC3A99540A62EF1C4B6D75FED8AFE7DCAF37832A02B3BC0339CF41A6F42733A584DA80A8CB328A5E6E59848DC23A0C0332F529853B138ABD0D3F2A8D2FEBC1D71E249E1FFED726E4664FC3020566BB769D4F3CBC8A735FC7309AFF545C3F87560BBE3D5016FC99CCBA9F5410030A86858F320DA5058DB5A188E68164E2349EE036B6904E5229920A7580206D3B75E89A8EED7ABF650D69494A13E83F37F841A4FB2A7F1BA538D40F84F25DBC0EC78DEC1B5F29F1A27198291365257819922F1A42104C721ABC95B2D610B0DB4576401E70B1760184DBC285EDDDD0788DEB108E824A21B8E98F0CD8A60557D183D16162F32C3D7C7353C3DC402A8B96EE8C5408A4D525517F76EF11238DA98E8069402FAA2A9A64350C4AE80F033A52209E66FC36F1802552292F706BB6B703C8E1FD66DF7DE25B4167EBF2E6F8189D8AE114460A1B0C0398CEE7BCE10D022833BEEFCA70D5BD174446CEA2C23DA0426303D45535C5F7E81838F93979DA4BFE71729373C426366787E899CA1ADB1C8D1E5EBED05315F646A798795ADBDDDE5EAFC1A4D6F7884929ADFE4E8EC0000000000000000000000000000000000001225333E" - }, - { - "tcId": 2, - "deferred": false, - "sk": "D9C4374117AAD1691D8CF8789E3E9544C379C5021B04E4BAEDF25FB2BF7225CC5530437B7D76D449CF4749DDDD18BED539BE7661D0803A4D7F379DFA3FB293A0B1A5F48C7818986FB379E41A921DF4726396F2DF788606A8C8C5B4E973968545A66B1467245A5A9140C7ADD5083090B658C7654630272C9A25C1CDAB4DB6521DD49641491664C1A06192B68420970153A825DB263249429018088C13289121236A0C022912276604194109360D52948812C93004209092142E22B52C24900DA086248C940D01A62D1B948D84A8300B868541902C00316D8A306203C47003B4440BA6201382515CA42489884403204A00338403B72498142A5888681C12611B116A18C16D5C8248A316815C1630898464C4320403A731892289602424A1464A490868E2B64101146E8B884012270A4A242C020522C320411028124A868C04358902B6259A244A8C008D0820882202320A3442E2308E9094900CA730C44046911261191708D0126A81308DA2204CA2165221134498063264046E23B461A1162A1383710323421C042A1C840D840886921070C0160E03198AD4A2811A484C53200919079080C49009400198A885583682931882A4184C530805D8C648E12272C3C80944348ECBC650523610D3A481D2244121412C8C028D52B4210A244C44B8641109099C440AC2380E9036082016645C30314220725C48440B3306A2C24CC0B689CB26801CC388D3306E1C9261223108E282680A1852639224E3322A093260C8C2842085485B240603830511850903246E61880509A851011500120592DAC8419B826D4832660C2121C3166882084221359059389020C20801824951808D101406010431938201CAA8858C44504B4680A3265022470ED028500CA60520928113232A409449103865DA808DE1208E40B401C844261B808501294651922403490452124090B48914294E21858500A565DC2012193584C02668544608DA82451346055BA808894090A346708C4410DC349049A86D110742242288DA388094364181188C4C086C09150E0BC4290C070083422841342D122508C40865C8B004121631C43430A044900C4822D8086EC918815420214C8821A49088CA320E209361C8B8605C04529228900045501C0829CB0646C0180A03232542004C11276E0B448D02A7110489005CA021881071D9A201D0028CA3B08C01252064102652946401116E8A002E0C05465A186D1418405C464C1A0732CCB820D28420C224710000628A1088DDBE8BE20BD3D9163E7CD8E081F70C5EA00959FDAC57B0D8DC10873C27E22EE17981C4E689700036D682BDBA68454F9B7C394C50CAC4DE6A8CC734850F95764B228134B9AF1E0BCE16A593EB6CFBE451620DBBBE3666E3B248FEB4E5306609AEAFC331E92965C0479F86FA1AD47F1C4A793B2904949ADC0B4FE939DBBCF05066CD0E230A8E485C26F41533BD744AC8E442CD1358991B0C11A90CA17697CA7130FBF44DDF626B7F4D2FEB954FDC64B1D3EC0B72AE26B90B5100C649BCC89172FCCE6558F28EC5B764DB91EBE971C7E881D879956210BE220D6607BD9EAE2C72C4B413D8DCEB01F386C0EB8A1F8EBCB4053B6BCC383303DA64635B9CE7892662F8680905429617EAE18C58DE9380FB69F558FA1B706733A1B7B324B92FCDAB07438F020F0449A70B8F602B5A9702C771B2B3A4A906B2D27CBD824AC5A207A2FFFF1FF1FAC38EB85DC30F3F17C799A1B8E71D7A69D1D5046C73AFC04DA3D1F6487D1CD41C4075E7A6BAA11048273A416B86578047057C6027F89E695C66A6880AC8053D5FC6360353F336F282281C32484840B3D7779A2B59DF42467C42100D382530A74613E147EF863FAC5CEE1522871427739EDD9E089C1327E10F39ABA9F27E66E074200DDCBD31C7CAEE7D4967D8DAF612AA0B5123A1FFD4F8EB379CB8097C3A49E7F45ED5872AC1A579F41D1A8B9AB4F1D0946A9AD6C2FF429385DBFAAF002E96D85DCC93978115CF1BBD5F69A54B3AEC88FA74EBB175ED930A5E47EF09138C0986811946388D4452AF4A07A1E8983333340F9FAF033A87C56855C8975471DEA335CE0E0A57D36E43E1FF5DAF699A5258DD22FBEA92C7F7D7DA258D250717A6EDC2082DDA972A36CFA6552F4397F502BA040145207F874D4E5B07222581646132A5CF5D5DE59F347056F5A52BD89C75B7EB3D48E2326C02AFA1822716A4B4D109F0DA405380BCAE4C7C673ABEB898DD21936195D3F3ADB1B3F042016ABFAB2670A977D1729A605F201DB816606DB7D73B1906C9C4A49C1687460E2093B51ED68F7C548F84C01372CB97FA557B2D7514355E4D0F77D22C0F245B6DEE89982F7C2DF3EE89AECAD428C9C6CE962BCF6DC898EA7AF0A0065EB4477771E97DD30DECF8F41B1B0BCB5DD84C20F502D894710F97B8E93A6ED694AC69A43B6E20F7FA885997D23DB912F1C5336EE2050A96EF1F4CBE9BB50F977C9035FDA05E063928069394C18393E988F715E64F02CE6C3A70AFD2403E3606721EBCA72E9D4A63E3E11707604587301CFC4D461EE07D337A9A1C74870B67457C22D9E4EFB60A5F6D405A184F972BA07CA8D702160BB598104B35F0C0DBC4105E3714A32A789C3C19E3CE8D19AB71FF69514F2CD7C488D6F999625405E9702C38EB3C5B50F53766BF51BA14015FFA2EDAF83B13CAA06060A30C9D3D44BDA226905C357384D027E05B3C0837C246629A070AECBE608E743E330ED18BA3F8DEB7F09F61808C527C5695C4F3FB8DD5F376EF656EC4AADBB21234E85C39CBB37910ED7A9E12D04AF813D3D87A7FCA55CE6F86A53C6432F9C99DD23AC297B217DE1079EE21F467EF700965A326C82CDC548084EBC5F9D0C3B48F75771ACC1C3C45A70388A0C65764829274062989F7A209B71D4051F26897C8FEB6AC847763463A0858B0B2F9CEC93454C35ECD5CCB9AB987B1957849E1EB610D2636FA7BBD08193A69227A34FF2BBAE787DE0F9EC719A3DD04018D3F4DAA2047C569C6B5BA52785FB44F24DC548BEFF25B3E51C24880469BB9D0749121C039BD7FB831D098B8DDF213023476DABCBBC778393F02B4077B57D392AFFA2215587D934025D148F435C1B49998C937BA3D0E7463C526D08DA8C67A2C305934E82B648D4A8CC3EC162E56A42575E944CB711C3AB0474EBECD829CA8E678C10782A284485F3D96A1DB852FEB36BC1748EAD20A342436FE63124C161183DB1BF5CDDC1436999764010C2F57E55BAE6788A7D653ABD03989A6F515DB7A76A77CF3E282E83FEBAA8326B9ADFA176685FFA1C6F9ECFEEF97953685EF2DBE311BA25E2D76F3950E005E4117585709447FEF5F1ED198B98DBA256B4BD2A430D7CDE4052A36D87905A8124AD317ED4DF338CBD1CF26BD02680944226BFAB3DE9149CF19C2519F639F9068825C0BEC1A7572C70B948BBCC290B95B0BF5106A8B2CA8FBF9CE34599E633EBA37254C250438218AB1D2A3EAA0C148AF2CBA48DCEDB11FA3B5D873BD161D24C65CF7DA109D1B8CA296071FF706E5666D66ED10E5B1FD78D2F993F76DA41EE8A9299D33C2ADC8303EC322449EEDA11FF245D03048E5701C7763D545EBCF540CC2CB0E3A06265F380C622FECEE4E", - "message": "8F69A33C4CB9627BF27401D4A1BC131D28AD0E2E5A317CE983BA2CC7465861A414FB72745E4DA31C0E04576DFE0D0EE834A1EE323D5A0901DD0189EFD6718049E2FFE1AFA548BE16E04B8963325AEB0CA90238C7A243A3F6AA17BC1D63836898688AC8E919B8EB6D689075E050B4189A1FEC723E0AE8D4AAE9FB6790B527A7552CDA174BF40BF91C4142B076ED8CF112A871450AD994737FD5BCF513D42DB01906636D42C6C10B64F74BD37D68A966DE0F3BBE6541AEB9991DDD0C0070F16715C01820546A014E66D786B8922E905DE2BC65053C42703227B7D8431427E3EBB0DD010DC58C2343147700D673D5707160F234E35BA24516CEDEAC77AE15C667AEFA8E029FF14F169FC0A781593E11D42E8659DA8E91E53EE0A1FF15A3C203BBF9591584A99FF8BACDC37541E126B8CDF3503AB2D1BFC0C37F38A298AB1DDA150288A8110C052469382A9A4F5565778339AB327DD80644A26B218ACE0830E56813CAA658A9F17826CD12B815612BE40906ABC89185EDDFA8E05102842CF27BF040FC7B396E7E2E023CB86AB7AE25F36DA6B6C0842126658E0315D6D8F4B5DF38CA663B55998ABFC72FE9B7EB7CE3BEB72AF73A0B2A45577C5215C42E465EECF4A4E69B6DDC1E65E0C1EBCA", - "signature": "3639297077C2F61950A09D4AE55408D1822CBA6133C788347C1881F8E02400B683B012EF2D9EEBDB65029BCC9EECAD9881BDD4FFBCE8FB50242D9081E2C8C791577C800986BD7A03A3817A06E4D6609E288B3849AEFA840EB7B69C589AACF26B6332DF4210F3AB0E8DF14F918848B907FE9B09CFB91F32871B0ACDE0ECAB8915A0621CEDB4A591B1A6EC4B4B9F83F432A9B576D9E5D40AA57D24D408135E72C77281515A3783C8F3397C9E7D26B4543A528BFC1FE91965142D52FFFD2A26470EB821435914D346EC8765539D39083D743320FEDDBE31E08EA0E4ECCF74B231934B5757D460E5B79D16758F4A56E59C166C7F9F1BF6C1DEAF5478E97C8F55000475D523456724390D94AE9F5C4B3F96E86F1932412D740D04D1851560476D50D7B97B080BBDBDB7A347197F2ECE6603B0296C8833B5DDB95BDE239245F1BF27A7584F5B9243D906E4880CDAE82E5A7F1A71A7DF8AF9FC41C0FB4B63CD356CF5F36F94D20592BA58D1FCA9D354B358AE5423D7D5FCCEB05B831024EDC7DB64D6C9E45454790F8B4239BEA02983C5827E4D08E8DF3F795D46CBDE5D4955A6AF2A6E0D101CDF43F43D7F5DCB829A5A79881EC903C1B8522CCA5D8D4722FE29B36BA0C571DADDBAAABFD48DAC4D2603D768A92D8ECFAD5264A9081A74A2F7FD635220EC8A95695F2264075DCC05F69084EB8336588CDBD58CA028E02A2756C8A3081E720F281172F43194D8ACAD2F61F2DD4F01C235694FC20921EDCAFB9AFAC8FFB1A234FF35E68AD90086CDEF922C47C84ABB31112C6AD6CFFE0DA11C1999483609EA98573217C28B512ABDBA6F7A7E69FB8944D0B0C4B9CE7AAB52BB558A5411671385FE36903D148D11DE00A9007929094C54ADE5E9BA60AEE35D5014C7293FAD0158D69FA08E2CCFFBE2AD99C66A2FD2382E6D1C355481248F53A5130EB4743DF24EC048196CE056A7EB032FBF6FD07D12C153D06BFAC06C1AB23147F8139DDE1C00F9A9C6347456C148245E3C94F2C012284190CC3EB04ED006AAC3DD2F08D6D0AD54EF507D7E80671F12A3E4DE2136B6ECF02EDD28E75B985F73841F600EEB64F8E5CC101756AD7794DC14D187237BC82CF6531583DE7B0F60275E63976296A0A02E67298C20FC64A1A8B1CCECAD1DFEAD996A47E9B6DA0079AEB435FA40A53A4C0D565AF713DCDC8D4F16CAB00263058A9CA1F276A39172FABE34FD75422E64F23B2715B395C73F2335B6E4EE7E5BA8E2DE18EFA39FF1B0CD8C0C6F5618C971213E94BF2B9B18E05BDFDFD9DFD88CE24B392BE1ECAB51B95C0BBD9513F881DA789C57B1EEC8C53EE9CD4FAD5E7526B1F1462AD88F180243774B91A9CB219D4CF9730E682E2C6C8EB160131D3AED3D3B3E64EF6A1AD7ADE7048A0CCCB67852971330A62223A89733E06615508029823D397EFE221B35896C18E9BB08140C464F8466190CFD8B0F09E6EF46BC14753974AFA2CE926EB6B02F4EB25CFAE70C77A865CCAE8FF2415C0D81A82F3807A4BF61F6EFA9BA4A16D14E3169C2ED86B50059880D07897A67C882E9B10450DE3978ECD78EE2A3C2B2BD51544FE65ABB7909FE439355530D44244052F2154279B6395E77FF1B288103357C5F83177794D517B0D8A368C9B008838AA4139F1BD10E3ECAD45748804F45122F3384A1A2D541BB8B9FE3C478EC0AFD81EF69FB2A42CC9059CBBEF42633139C342627A604AD07D09AB962E7C1CD2E1F1FBAA633E00AC1EECD29B5324DDA5F273154E7E9D0AD3F78C6AA08E92C77BBA7CF202B94377872146C60E9384830DA573CD7E3BE362267CB74BCDE63FA708E15F5933E27117037F6C35F91D03DA285222FD3F29C440DE820C89F6F37C250F82F0B20E69D728A680095B59AF058A06E46CA75B6BB1E2B0E14D2C9C4705A080B9B826E2F1F96CAC70A902894B416C68171B7388F4FD6BFC4BCF7A6745F3AC83B8A31F869C64F67C5600F35202D3F45E697F46DB1991AEA695443C79810796CF0C0150A83E24B2DA00DC72364CD34C2BF6A9F1EC4C39BE42F8A7E9DCC3BB6D0BB6198FC08C9743335262D996C489C460DA87FF75D4B75367C17A466AE08D24D736EA63A6B0087041426C03BC94BA143264086C94B4C8A3F6B7914CE40EB7FEB876CF16A2F12C66AE3EC3B57A93866F63E56666AC7B59D3C78536D77F73E9E9BEF9899EF390E8BDA6E2AD5CAC671153C348C804F65408309A08B2E78FE79F014ACD99766B383E5869F3A3562B4A312CEFB3D8F5B90FE769365E1640520C817B6A3A26734F406D104CB7AC9B6DCE371AE3D7D10E265EA370C0C78D0685F9BE4B3E9E097A334F53E47C016215719A5A25EAFCA799BD13F5B23C63CF372972F5588B8A125AAC58A0ADF961A6D0A2646F9520DF6699B67293ACE799C784CFF813CD508317ECF90726D638A13AFE574BAF3D2E9F39103DC199510AE4B28FED016993FB16CBA627C820F4B76227044F39AF0B8222E1D387C7005080E5CC216E22AFB8F591074938A3510AEF62D18D8CBC9978A8284DDEC00F7BD3C75F724540174416CFEF71D5BE602FEAAC4EDABCB72F7252471F4A3D01A5D1BD82F98A7BAF66CD6193E17499741810B68B1B066C827FF18763CC557946FE1B60C706606F7CE607047F18D93593A7859BD669642FA74EF569C31F811AFEA327962E02FED620011AC0B96C6CA3AD9120EF1C3DB3C9EC43E7C4E1A255C822EBDBD71080C103EAFF847973B30AD88C40CDEA8E19750BAD8E298D8B0569CF6D3F99DCA585B418355ED039B585F9F829DFD4460A748083ED38C6DD9A93C34447AF47B339C5621D908838469326D318C41ECF288B16C62040EC628DEA4C29DE18F6BD3793BE057B52BD0AE44EC5AB575383FCF35EA91E74ED011792C415934B16CE8D4E9C2416C1C79C1C8B09DC94E005DE0D9B8BFDD07552140D3EAC45EBBBE9E164BFA885940702281DC14142E236AB3307EED9A2F4A88AF5FB61D771ACC92B2306B08F5D8F740C3F10BFD5368A744BB6590AC29295085EC4DA93C508AE62AB59E2390C1EB5B2D5976C55DB166B9D1FCA8A91FCD234EA2B5895DC5228CA981C630195FB832938ED7BD73353EA9771ADD724BAB7AAB17CA622F4B9FFFD6878E7759DC98C0F5F57A5F59132AC552FF4575104CDAF00FC6B73F460AB4F3E06861EFDF5DB48345F35A00F5DFDEE36A49C2150547036544F0DBCA21FC5B41D36D4823B2917432366F97BC0B0AE524715293C6FFF6DC57FCC9A7806C7ACEA749193CA1FD24266CCF42402C565F488CDD0794CA7BE9A78E9DCF4A2BC2C83024C0C58876B2921A1A5203152E4F73757A9AA4E4E9EEF103273C44454D5069737892B4C8D1111E313637445D7C8292A1B4B7D8EC060B3B444D646B6D85888A969BA0DAE1F20000000000000000000000000000000000000000000D1B2A3B" - }, - { - "tcId": 3, - "deferred": false, - "sk": "B7682E0C424BE42ED48F21AB5AB57FD47BED455A6853B3C166D2AECE055EAAD23EA1D186FD4F24BF1F8D910CFABA719AAF8714606159023E27B81BFDE79B4C21F2E28722215C01B06BE6835163253464EFAA9CDD2150EC59085A32C2BD5D840DE568E12A825CAB4E5CC6CA768D632BD6780CB532522953FA3D774AEE03E2D76748206C49384D81406A9B82201334601346214CB0419C228089C88C5C16690A10022006715A308510102210B44C0A042A8802425B202064042D1BB2850B3292C93461634488D900111C092ED42884CC484D5440440A318AC0B08D1B024D04164DD9B44CE1B01124A72004A671E3106514A74581062C193786E04291600242CAC40C93124E981010A3226262982990806099C88418398019018A2140828C066D13B929C384659B82451405910B114058484A00210663942911358AC1420DC8A484D8344404908921C408123160809000494010CBC4911C041223384E14364D633806032720A006524924850A410693A804E4968CA284510492609482242214640AB20D89A44821294A8C246D511666048949D02685D38688A2100E0CB028DC3889C3C88913B540401012E3C48992081241A608E43425E31645603022E312691A824011412684286DD1A6811239825028692200249908401B124908056D0AC58111352A04A1909224095B34281A2408DC984DD300300222724C145182C8241AB040D1B849CBC26DDB9411D8020E0B2708A4266490A624C28085140726C342819842068A0092D91600CC224A21B20C53067100A37121C14C98B42021818C99004242086E8C964C03086D23017100004CD0B61049385191A6040941261B2891C396704C0646E03421A398010C3784C31248D1C44DA22029E0366E54846D230862608404C3A88CC34021C9A8605C94518B16309BA0499310891B87856394854A24918C228CE4388802434424346910A948C80288E0A68D613081E00269E0440A2187919A082809A165DBB24852080E2180711B16250A338802368004138CC018415A020591B8699B3250989611D406525B820D50B46DDC884809102EA0284D0300242031640C382042180D91925103C5291145109C98315CC80D60108C10220511B12CDC366492383183444DD1802521055153185141328499444C2390505494201B830DC3168A48A29064880019A18CD42208520644992245E2360AE404851C4648C2B8814C2822CB38218124084188884802409CA624C184699B360E58B64181046501E3E9D13414F71537E2AB58DE666A17ECB001FF8EAAB0141BEBDA328E8C7EC44F552DC00A1261A83DAB59F8CC4392EF5F14BD88386694EF93223BBA9EC78A67D5FC9A01AAFB16F4E1C80BA31229514DC1637CD43ECBDF85BDE63F6A2A17E6A1BEBEFA27EAFF596624B30DDF797120E52ED396371C1B143C27EA83BE66C9C2BAB70EB1FFA60CB818B9D159C0C7B02734A91200C2282403D316F6136B0BD3E6FFD328DAD5F257B316BB76D6B3317FC3D7808CA0A8C3A7BDE19A2988B994CC13C13D1E3C9790BA3239FF91081CA6F21AC9684D4189BCD387B0E70EFBCF09B8924C5D9385E1006CA7E153B7CE207B920671065FF7A9AFAEA91DC64484A857563C9E90D74237DC453A554D7ED88CAD9EA30F0A49E0B835560B4D7741FD1B96EB6EDC6BB7201DAF2499623683B672956FDD51E14EA62504421AEDAA2C3527BF7AE8DB52D35D673F5E45918C833FAC8482DB27001C766DA36B3E8B0B24616E749E38807F3E646761E4C998E04D53FC98B7D636871D5719EEAA6BE67D20565D7C120E210A67C12B03571B9BB450A710CF6986D961BAA5A9F92FB33E61D605CF0E4FF4C689D535DF5FEECC5D5BABBC22975256B9834143A5DCB903308B18D7503A2EA8CB8B8ECAFA6BE70BE6779B9FCBF3984830B72C513CB150C5529ABE6EEF29E24291756BE46DE9796714A940BCF0AD21721247EA5449946D987DF5E70326B15CBE2C439388E64480CE84EB9063A4213B58C7223FC06A5B618C3BFCA18A4E46205DD963CA8E2C86712D75A4582668E955D821AC4A7C136D7F31C7CA4E7B8AF187B2C6F4366CD11996BE298D71B9E6C3D6C9DC47826F58935CC8EC353C27B3827C3065165B3645032D3013036690D9232FBEA4FDF57D035D99FA9CDD8697BEBE97D2B9DA476BCFA7BF167A1FC66BB1C5F2348E86F3F61432600D231A593AF2FA3CEEDF7F4417CC0E75023054E21841DD19D53D3547D3481D76401E66FE238D68A5381F98E0F6C455B852CF09A1B17343336FE25DF426A0FD29CDC00F207402C7F96668881EECBE43A4C1DA9B86AC50FC6B3E2C74D244848FABF414BD7B3BAECDC750BF2E58033010B8944991D6CBE7E5468C168FEA69B167B566078673BB06A035BFDE64F66C50616E9B3419394E71F8AAAA636634F51F588D3E012A40E1C9A787044596C51A82D77EBAE4FEB448C919601A183E6A847E605CE142B5D56A0417F20356E7E1A35FE18E94188155E3867BBDC7CD04069D1DC4B3EB8C9AA64F7F955C7251667441E77D7C818A8F49496F1141E829C51074D3D38AF41FAF4C77A56D05296B034913A253536702A21B77DCD3137BA26C413461CDCD413296C9291F1CA056EC0DF02FB888654DC54192EA30631F8F9C8B4921A1DC2AFF4CA8C350DAB4234D9151078DB0EB340CC3754E48012E8C21C84B410FBAB3134DBEC37805E723E5C08F1AB371624AEC29A1885AAA7915497220DA11EADDFC7D9FCFD51D0765515C16273F978BE26CD6D7F8627587F82F3BF4EC25C4263DE24B3D4A0839F7AFF0C4D16A3DA89D1F23678FBC23F475B18B523F115CEC9D59928ACDC7772FB39B0F44A77E15C7D786317CFF38DFA9222FD53470AA15061EC8A9D6CFEFA5C32A60B29FD1265B10C78625B2634158C3131727688D7837AC25BCD90FA8EB272B7B3B232E8259FDE162813ABE082BB0BA76B62DECB230310DE5AD36BF3F1AF145660FBAC027D58D86B03E2E1B5ACCF81B6252B90E1B9E85FF41FCAF60E308E5FD114B63CC26262B4A5031E654B673B23464318FB55785C5B707D901E2BE7A3C7E2CC4BE5EAD3CCEA165A577680183A1E05A2FBAC4EABA9022F9A43A53CFC61E3236652842ACE2C8B4249523BF57D6404EA8B247B0058FF1AE98CDD79164B6445A80F31C427EE1BA04256F0833E752DEE5B5224317919242A7E8CFD0791637D3D3873768FACBA6DA65BD8B4177E6F634CBAD83A94F2CC6500A0A5829C9BDB3849FBCFD517A80CE0D8411948791D0E5927BD13EEC09C4FA2B2453D9CE1BA10769B067D8D92547E8BA2F6103D066792655BE8C05AF1628099D2617BF2BBC2324DC6E3E36C9F32597A13FC45C1E974B00FC53009716EAC9FF0FAC4C6B87DC59B4908631A6A21FD5E156D476E438872D93FE112AABAF99A6952959FD9FFD7C3C25E11AA011333FAED86DA99A6BCEF75E4F341BBDC0E181B5A2A22E9CA06BD4F9EDB955CC44F11C6D2E23378B94BAF0509DF55E8D05C4F8DE0B4FDA82AFE7450A0A3E5D8DE82368F1390D5696FF19D1C4F265EF051CAA0E68E336DAF98698FCE2472A6B580E1F30BFA7B385D8F4DBF063FA79E412756ED83668D5C3EFB0FF4A59FE6189D1B70EC45C7B", - "message": "5DE75924D05BBEF6B34CEB195AE3349EB621187051B1EF95A779B99A3E0F729994BD19C7D1172418BBD3E015B20699DD09D8BFB0A343F477AE2A3BF5737AC994619D1FF3C13E7676D1BCB446289DBFE36E2D1508A3D437B4B0DA06478DF6D4701909B272E9070B1FE06385DBF8A552B471C8EB48EAE39D141009FBCC5D57D95697ACEB7B5231AB5976FFEC41E947BEACA7639F664C6C1D058505A49561811ECDA46E23B651F918112F38B407E82219B49E5C4E7C247DC4BA633C746B42DB912B07D56302FC5C08F5E0C3E311268041F970E670F3AD26A207701F1359EEF9D4134ADB882A1C899B0E4FFBA2C68535D97796636417EEDC0790FF808C976B57F0838A694700F8D75DD4FE5ECFB4B6A188FCB77FB1DF7C5F7C91DC81017A5E9A6D1EAF59680D3291F74743E1776A6DE31101FAEA31D876A0DDF3777A91EF1EA0B575C83C97C7A283E7E958287F5A52F30B6E70201A1410355B47210B911A7A4F6FC23BC95D7951822115FE410ED2E7FEFE08940B3F8E63F13F26B6E949C498E62A66FA675850FB9F7AAFAF7D054F5C12306ACF2900A5B66A29931A5919CB31D19304916AE41869CE3294B0F5F88D845A7FCFB57B952BEABCD1DF7FC11E2D342AA5A70A8AA9DBE1E6E66555EA618849A95439864DF6D7789D8E3B46C6FE4F33877F127D4136D993061DAB530EC979F818A57E1052B5B33D22E941643DE2FF9239741F6459A0EE28658C3C0033FA62DFF37928C59189A7A7E36B1E305F3E1F421EDF4D71A96C71406A0F9AFA5C96A9411AA1A35D241D7186E5C8D0CAE15938FF869897DC3B7D8196D64DE202108D6FB436FF89983EA6DBB5BC88EE2A02488E4D12AA87CC4BDF41A339E10300D32E0FD4F3D3136FA64BA90D64E2BC7C20BA77DA4DB5311F616288496F2FE3E7B3409879050FE57A23DB0344CAE82ED329B0D31DC9B7406CA715E3D84E364BA98F73F693B6E62DF4D741928D21D934453BD67FBBD9725BAAD34E5F3204BDBBB569251DFE2D69A9A96BAD90256213BB0747E7950AEBB4CEAC7224FD5F8F99A16866F5A1DCE07C2CD1E06B70A81FCECED0AEEECBA62521AA0A01FD7B5A3A8A14DB55AFF331E469F5138DBB2B96BFD0AAEE7F38EAA375F71759268546D590BA8C0C022F78CABC4E089992409D3D7BD19048D30B15C796170BCD7AAF7FED0387542BF8A6674F197EF994FF81BB80C59208A572495DE4E584B36A7E9149B5E2081A4DC162CF8376029231EFFB4B4981895FC36562F51DD5158DC82ADE52ABB0E98F4BCB3C0A24566D07686732FA734CDD48D03DF99F7253E589CB8725F17E6BF964E96F9827CA5A9DBD04D448025EE014EE1B5DBDA514D3FEE4F20664C11371DCB16991DA883BF9A68EE30D727137D7902F4839635B1C63F6C4F7D42070E880CA774680DAEF105D277EB8D9090A98F6B813774D42DEE922314480EBE562775F68ED180B67EFEB077D8B174C7D4DA877B0DD3698CF506EE382AE6FC6F68EE93ECA3627B28248D3EEAC469EB0C26BD1A10A7779CEA142958F9F9A533BDE974E1B3CD9B74FEEB2EE29ACD7DB65E00D7ED6E94E5E44A925188285166570727FC687AC7EBE4042BAEF68BC23F4B9C51BA5040BC6BBA41FFA9AFB1AFA09DE1BAA4DA091A08086128A9CA5F27D3F4420327C8FF4801BBF2057282D05D1CBDE60E1E6FB6715EC41AA9A852686DCFC47279FCCE5D86ABF02A6B5B57DE22B2097B12381EEC567E4ED1855F9B482C174D6D40A5825687C02E1D0AB634C020497A44E07E8FBB2D05280C53562DB4C90AE0901B88179D06F9F991E33BF17E7A9227A30454430CB768F56842995081520158FC34BF5257EC8EA9338B3714126D6A95A3D77FB61207154F6DD0041BB03D84D8F75E6EE910460F22CA765A2206D6C56C6E498E063B08B76B1DDF98571F492F9DBD3DEAE7D9C8EF21EDBABED962331F06371364DFCB3216E24638A20F77FCDD894FCC5525DD0C8FC329494841EAFD93CFDF0053FCC27F5A1263C7F4599C186B35FCA9C6F5F2FE169B00275F15447AAA3A823E27E322CA2316B25823F3A79FFA785E9CBC953815FE06F376B6F5860C6A87CB9BE98690C9C2A93EFF1BF1050A01C72CD521BEF265D66BC4B8ACE5736215DE59290DA957175D704BBEFB0E81C2CF906C3A579BEAC3A0C945409DEE4A1E683A0DADB3C4AA7E0174710C72A33F1BBC62A6E6F3EB9C138C0CEDA817688BCE8CCE523A2A4E2566775015F3BF66C09E716CA929BCC6DCBA7427EBD93B21CE276820734331B078558C63ADD096004B67E618D9E58FF3FEF00183EAA293A1DA2520BC03FADEB6A74B52292DBBC6EE4E5ECA8F8B0556FED36C2B41F9D8FBDA8EAA1F74BED46F05E7712E20E463502A420B6CE67D125BE999EF906300C627C57C468C8DD608F9AB354791E6FEF0EE63DF3C1821AE78111B27E57DA88FA44D89581D11C2C72F565A3D0B5E8E2D83DF178810075E5F8FD29E1953BD2C6326B693C5CF6ACE086673D69A67A181062A6ED511E0CF36381358C2DB2A394B05E0C1EE9C54B89C68E10857463F71A842BDB8429EB31D250542F88E6BD3BF10BDCA160C0FF44EBE7D0D982F15C4892091B4A69A3AE7051BECD1D2DB132599F1101E2BCF60136CE947F339A3DEF9F6D81E1BA3F5D4CF2ED989861F7CED86B1A6A167291CACA74C45BA7B5969C09EA20C4EB061D4CC4B68392AC866AC591764A16D0A42710645988FE070314D0859A1F022789442381EA0E3E83F5245272CB5FBB861C3729EC484D2F299F37D2F50688D1D8DD91F131D03207CD1459B289B19E3ED609D70D6BF8E0B97A75F4B4F1DB52DCA7AD03100A36C45D2AA221CD01C8A51D5328AE47E3307EDCEE9B27F62E5DA9EEE15B7A2FCFF1678551BB3DEAD4CE54A16C22119BCA343822DCD20271BB1518688CF69B566A123F65C4787C1C525BAFF00CE20C46C536E47DB1E4410E572BFECDD7904583BF61847868D7D1AEB1EA071EE15A9CB9E3EFF8D17A5BB7EE8BA83C95272E065979904AA99CF036BE085ED869D3CCB694C025FBDEE9BE140A0A21689F95D90D8A54DAEA98EE5DDFDFCEE2908E65C210F347D26F35B95B34642939067CCF04A098ED3E2CE3C0FE66305BB5391E223E43119D38A33672FBC980BEAB96558D3A940700B3CCA9D3AD2CEA08E23082DBF30FC08E94B6640CA04BBAE80091ECE96F128B37141131FED2A5549CAFD7BEB5B180509880C49FC6CB1C11E4CB7C7901C89ADFA0E5335C43A74053347D3028B23085647993B5844FB2716B7154D93E25DAD1CCD889EF3B16FAE34D04145237378D66BD09A254D395736990204A5627F5446787B467B619EE8F06CE664BF7B94392B5C77BCE828D6186348EA2DECA1CC84999FCCD95C9EC55E28C8C2FB559C9020C6EEB661F708E40351D7E530BFB7B1C3683BF15FAC5B17D1CE7EC5CC3C27E04889A9E59E6534C08AEF6934747083CCEE84FF2345D519CABC7D2BA6B783D36C864C65C47CA636B28B71D6797717950D652659AFA8BE3CAE4E269BD527C0425168D04C097DE8F34834A7D1728367F148524366F9E53C4CC255D3BD6FEE7B5A6CF459E1685FE740CC203EDBF58082820B967A40822D36BB4A489BF0CEB51387009D5205056387C292D584309076956E56926283657BF7CF096F54E0128A265050DF528AEED9247E19EFCC79EC301A9F38BE7AE5057456631840EE39E191B25F4F7070BB15CE2CC18777F7CBEF100FE7993681D4E965D0C19A68591BAAABE601BBAB89FC27B3C5BA83545AD645F0DB716C98D5C7A37E0AD97C986EDB88B025D25E3DCCCA816C707F0E2542E44F4D69F943E1DBD08E344F88661B68A822C3EFD648AA23AFFA2F533879540BE2F670F4D53091AF68867E7C71EDB6E9E494E9D30A1839653422AA8AE34A525EFAA62D3F5FF00D91F5DDF80FBDDE464A8502AD9AC85EB21025C0E4E2C2877D50962C5AB8283BFC823FB221CC285F3629056D1260AAF87B556E556B4C723D44279A106EE4075BB79773588333B42065811D671016AF177105106203EFC36FDAB2F5E5EC8DE043902583C1782BFD8BB772353EBC5CF03A0D869E5F3797713B58EB7480CF7B92AACFC9C41040BC9E1F5447F9852B2C5B5F33B5517F28A01D5435C47E063B41D3B0F7605B07AC33FF6F05C6FF44EBB70FD6E1AFC2A32C9A0B1AC17044401B93D6439CE53C3B033CFF06688E1933CAEEC48A04999A01956096339B5E44AB3A57FD1F0ACA23A03114708BB16803C2CDA679061B8E9808A2E11DB0957D4F73C8A06E6C50D6DA43E4D008ACA23CE2A3213BA0DAD20D5BA8B44DE5D50E188039C112B8A40B250E7E815B1367375C5698B61BD915A70096815479916F455B9EF837300908C5A8BEFA5157EB688EA02245AD3B309D10C769CA1B8E5CCA2F5FC66CC3920759A203C3F6B8E9ED10CAB20FA143B0BF0BC8529A4E89AB0C99AF77E43E68B61A9E4176066C4708FFAB05F3652817FC42039E2F22DE2058CFA8701AFFA894F3143FDA27AD85C45D3AEB30CA9759537CA4AF2079317CE5F4B5EEFBCAB981E42065AD5CB8A4CC9B628CCFAC18D2E637CB73399CE3D90A9060F88EF438E8511CE6F403A0CF14C6B641830983C1EDDE73BA27E41BD678E834167C718F5B1E2E6C109199F756905FAF9F0005CC1D110CE277DA02675461AE70EB6A412EC455B6575F16A4DEC0565DBC8F387D84F9D3AE67AB35E511657D82B5606A4DB45CEEE81C94FFAFCB88B8185CFB67E4D7171EEB391E9E1DAC625B56FED22D86E8A34924740F94A3D50CBD05B8E2476CBC7C54D2F742F0FD7162E7A138D4AC788E710AA45824513BEA162E2A1C1F709413942BAB5AABF7E347A148D53B8EBA0336D91539766AF0E827BF8EFF36389ECA38232FF2D7E341A3AA710F590C78EB69156462BAE9B8B73386F38EAC4FA26456FA555E26E7DF679983FEF23DAE87DBA66BCEA19A9F991F864A17C23F7CD592ACAEADE0E82F4737B70F0243F94F015B59330B71E25F1304DB3D8D7E2F96669BD7F8313EF9E10EB1EDB0F0BD94745D03C83768A618AD9ADDEDA7C1E6E134F8B7BC96B84652C982B1D9242F8D2CF0ACAD146EA3185E2332904E84088CA2D7D60D3E2DAE411171726B5FB6C95B3DE961E62474CEC73226E55AE7D9C7C534E278927F5D669EE6D111E325D54F338E2A6A06493D6F1B7A556A94CC9512235498409EEA477597EFAB239380491C9CCBA1F00A0D1C5D758162E9F4F5464A1A64A22C32721AE57E246722A6B2E07E544A5FEB06AF86C580DAB2B9DFB5AA0F0251E6840EAD66FCB6B89F80C2AD38383B329F9EF4589BF0E8A0C9996EC19E1DA539CFDEFB2BB0F3D9544392A06F765A74218B7DC34F38D230D1AFCF9130410A4B4FE038F7AC59B6B062EE2D2ACCD288606AD9AFDBE95D9572B78B54D26166C7817E6F72F7E6C55DD1576720E4AB99CC26722107F7C278BAC2D82FBD0A3B0E1793C2D8B498F90A9172D17244A4107D9274958FE078FA8A5A33087BF278383F439C0B41523E0E51A662A9F2822CBBB34EDA97F5398EAA12D52506C2EAAF6D4B75639EF0676F482A69DF0E8A9BDFBF6105E32B6FB3ADA2E29C62A0AA687820B4ED35C2418DB1A67A3A5B92DC61368585CF7F3B1B644A8137A52CA21DD982760CAB7FB111558ED0310E9FBA34E5480F4E707A2CEE74DC24AE5717C06DE2B509E4807824707505FFFC5DBFF798E8D85F758A94C2D3770674DFE03627457B2DF10628A31D44BD89D3435D93E4F9BC14D47E6D4B9BD3BB2287ADBCE1FA58495D9032A9A3ADCD56CCB116787E060EA431C1EA9E60A30B609AA9C66064017EA05BC16392992B7DFF62EF1046FC7E64F8F811CE50AAB40AC122CBD5119D3045ED0812F6E30EF6B6001285427B643E3C6FCB6390A9FE76B342A462994F2B9074B56A848538DE205C98BBBCC75DF6BF23CC1AF0B201E5A0618D4BC5035B9F71BCE9D3493A97FA47607D65865A5FF3FF17A7CE28C0E87A57FE951C8F804EADC21F161CCB5D1E66F1E4DBE92C69D4358E0CCC13A12DBE87C9B530579189EF2359A9DF5A8FDE00CB2B58EBD748B23F884626A66EA39847917995EADC1839BFEDCC24AB6BF22A5C247B6FABE8CF382DB48148915167BB47F505C184EC027C3AC741BB0F6676B0D0E7781E19FB8D4D630E71ED4843010198DB9B122CC301D432856B393632369FA1C99BA252F086E317229486C034F1960087ED4606288A7C89DB0EA0DE94700785322249E901897611913AA74F8BBF412639DDB639CBD1C41374A3EC66A87451D9E4127F7627DFDE4E1701D7FC9DE13DC7754952F659EBA7B1A861B8DFC78D1379274530B976C66F9CC4002563837C852D83B3F3BBFD892F14DBF64C976C924E3C656B69131EC17B7905507F78F073A7E509157215C988D490685F8AF23F64ED338915E72B518E4305C9CD44C219876456E87C0C59C5D7524C86CAA161C745364A12890064CA9061056F37ED1BD56B5B09B1423775BF0FCC898AB1BBC283B23DB6E91A3D749125992FF1BB598260DCFE428D2524050C1F545FFDA18A63B052C0C8CA4DF8C3BDE83EE5474395135FCA2B05157C25548B0804D1EDE", - "signature": "CDBC27DDFC61E219B3448514C2DDD3D8A8199E8F4B49C7E4E73178708F40D30FD66E7873D6BF716588C97559C6C4998B2E43A58575F4854C6637784055A0C147AB1CC54787C73A49FB8BED952D2679DCA79EABB65926DEBC4C7D25D441C56ADF09C409C9FF12D2C43468CA67E45AD07E58CEAAB0F35ABB7F3D236DB2849DC0EAC34448643D7183055623A7B9BC8A08033D3B5939958E90DDDF6C9A7602A44F8516C78386905270FB047C354303AFA6E2A387A8832DC8B436BB178F713C70ECC12E98FEC4D5B28A3E072116B9D2F0BB95BED447861C56E6160170DA93030C32E41288C1C06794F7E6341DC4D6031051E51A18B1D7A9FD1A84A5DB0A1F1FFC93E0976F7077A83FEDB7B085CD366B67820EA9FE232C77B54BB368FC6A530DA21605249B3CEAD87C3E8B4CCCDC776F0092069679FA63DD91C802A368C5158718BFC115BBF9D45B7A87D4B03040A1E4DE2CD0343A318A04092EBFC0CA2BA1B94552DB961D42B1E638234617DBD18B4EBDA761CD35D12C30683428C83754D8FCA43DBCFD3B3D486D234A21D3563C8396E8AADFA89D1D79F01E6A139504441BEF37209F8D5C5495146A8A1951EBF17F7317D3594A54FAA220E3A73DD7EA3D193801C0640D6BCE9FD57F16C2F749B3E96B2071F5A36ED9D038F97616EFE62C383E69C3D70AAFC5FE4890D827D26CECFC0AE1C8BC96841652628D318F424F50915EC65E9DC9DC43E19C08CB4011818C53301CE8A292165DD6249A8D796B257481089780C8895995F7672F1B2124AE77D38E825F72EA07E0B7515AD8DC615735268A417C25944B33513BACD93C3502688130862E2307BA77BB74986819A152A3DE627401B268587FE1FD45B373CDDAB5C4D6B593D07A8421394D97C564F7F373C2D90DB689500E67D9C7FD52B14F7F1B20F27CD97BDB06E04E13D702B92B640F6E20DB82F0455DDB9C2420E7A51E063A00962C29B4273030A01EB60690C48660F552D41D7EC955B70379EE13E390D421F032EDFBCFD3E958085EFAA573E60A55961C2E390B50F85992864EE654007CA0DC6B2CC7485A558F5909C58D701F91895DCE90FDAB1069B87BAF2DDD822DCB61ED44DDEBA48BD257827F0D1045FC7B482F462ED3ADC794C2974EACACBE3577353586955ABF65538C942CE46A3B5C9A3255BE71DD5C8A572A86095BF4A1FC36BBD3E65E7AA536FDE6A31069BFFB676158664B1BB87144D3E129156E8A22CD757BEB1495A5C9740B0F0B271C920EDBDABB208BD544AE20B1813198605042A38B40969B0D6D044D4804061561ECF8AF816B7EF6B4ECA3AC0EDFA4C8699C76080CE3EAA5E2CABACE5FAA150E5D233BB694BAFF02D6825FCE4412725DDE05DB5F521B9E17DE3C719FCCFF0CE174F369C2DC497062991B157FB2FF36772C084A226D577E9E451BCE364E0EA32FAF6B366CD5E02C74D8907ED3DC54925EE10B3E97CC96DCDA7067DA790409F2B422616C65CF3CB26A7C6C8E9240C9235BA9B7A67BD21ADC729B102FCDF7329ECDB2EFF495122E265D0F749EE7414312532EEACF600C62A15A18172FECFA2BFA62BCA47CE794835EBE25557A61B61F6977BB7ACD04BDE30C2425F68785B3E227106FAD9E5ACB26BAD47FE1AD461EB2445560904CD6DEC4DB091BDE4CC2ABD72CAE258BE07CA0A8634C72DDF75A06B4AA84DD16F9E9FA2D2DA81B5553C598E10E9FFA7E80AEA8131C16775C1DF3E45950AFD77E9045A419A7B52D3F3B1C1309EEFC00B53060FDA34B95FA6347305DC91F477F4D99BF4A1BC5418CBEDB316FC83B090B0015BB6D0EB1AF1EB32EC962D2AC089D92BA915A8F5693D04876D2ABCDBDF675B8A871B837FAB190CC47D93C2E00DBEC028A26860DC39678B188C27E8E776C7C8C72CA22FEE2861725C7340D4B5B6D8D0FF63A5C439A1CC12137DBD14AA540C10EF6993CDB9D5F6D1C6A8980F48818AF7FF6DC75A2AA1987E689EB10BA40F2255BA2BFD9A36C629F02A8CBD4A862D9D6B0E6D7C25327CB87F47799ABED84BD3B4BA60422B5491FE512B0A689E49FC2D037B8D7B9FD5895C13A40C14525A6A1AFB1DB0A6747A3FA1E7CE023F290757BE19309154477176011100160232AF0C5BC2CD425AC5AED3955CD7E1A700FEB09ADE5BF281EDA1DE0FD91B072F78AB77EDDF7C7E47343B5184FE540DBDF6BD617719550B8658C29A276A704E500C379D03F60A2A977676F04B0249AF27FF58F09275AB99C1201702EC1B5AB7CE4F08096C561CE2AF0A373B2C797DE10C017D1D65821312989519173A8F901E9832C210729A48A58DE10E7F4F09453A02E656B629366846C5AF57CE17C889C1CF30FAAAF091EC80A831991519580F80770037F1775B534612F5B7D1FE5D161BD3E38CF00726779792C17E51ABD013D7A9989EB9A136EC7059B8BBD5E3013D03110326299134B2CC96CADC3995FAE8EAF9466D7E502AD3755058612C083685F9355DAAC4B43AD138C6CFCD100E463D17ACF63C830A899C2187E85C2BAC006D9CAD1276C2154FE264EC6E607E178BACB3290DEB1FA077FB3843DDC0FD44707096CC54BBB17F1238A975A536BC00BE8BD625C930147EEF5F110D5B2B3B3E303D44B57289A00D1E047314BD3A206B55AB72AC676C4B26D004E23E590396B52AE35E3ABAFF7E5C965404714D1ABE9D69CB6F780EBBE4027B8AFBCE253EA7D7503887262673AC0132A0E4689DD45553AEB1660A72D3AF71D85E94EE92E478BE68253B48F2CB40F88C35828274F04676CD22996D6A7F92175C733C06E0B71F077F0B7E122314B771A28786DE8D2DABC94F720BDA3980F0C97BA6849919F469A3C6B0FC12263B5BA87B8BB5F01BEC53A68E5A1CDE4749223CE118CD17EA6F2743B9ECA60DB616BF30C4FC3B15F3F43352D72B8094C47064EC5E6869BB45EF803B51DB512DE5AE26A90C3EDD184751F9179B14D8363B7EA74A27463EB85846EDF89D38CED01BE910883239B51D20C60664A70156C89D7031DD2BB0E51E1A520DCBFE8F5099490F3C1477BE812D0EA2AF032F1E628067998A671AF4AA84B694EC2C6193359E8B43404597F4C3900979EDC4CD7435E95A66DDFC704CB918CDA3541FE63355C1CAFB19E9277C7B843AE4FBA7B7AD8873BD54E4324714D80D906E8BDEB17272B722681A2BF2467CAB68C5DA699CD1EE5F1DF3849F7AA1F2321F6D34DA719E2A93860EEFD441F25442B01081511401648C778F3E081ADAF247FF8BA3F2DD2E70294B094D8C4F73292F0A28936273710E6BFAD532ECF02EACFB6572C0EAE5B5A258E12A112E1A22AC086938857D189DE0912313E53757B80A3A8C2D3D4DFE4060E1D23263A3C63727C95BBC4CDD0ECED0B1D334349858A96AADBE00F1A3D3F6B849AC4C5D4D5DADDE100000000000000000000000000000000000000000000000F202B39" - }, - { - "tcId": 4, - "deferred": false, - "sk": "ABCEC4A46E695FC6EBE64A191389F0D0AE180F911D5B824F4ED9111728FF4F9493EF3A7512DACF766D576898D33C4C8F4001B777EE5EC2E2DC1A8E3E181B43418AF45100B92A3835D02B9892E609B2AA8C6AF7661CE0BC8362AE0DA172A79E84FF4CDAD8607E4924FF41DB6EC28DCCD09B8D1F5657BA17C848BABC71BB242A50C44069A0200101914D130822C114288436508B0422D83004E23848032532CA902509A0009A848440004CC3304D04C0601CC84889340950B68918C81103410D631870DB444AE4224D8B96491B0224C2802904365290222D424626E0060613B12DE1187203B18442228144027159186C22092C012751083160DC48061045089AC444601609240224DA006623945149C200182232CA462A0BA16D22B2215028700AC108D1828C00B24014083221B5810C4501240225E44291984622C90826532650DBA8495B226294B049603050242382DC0429D2260254262CC3A868001546089168CC067184B86C518285DA221110402494149044B8102220299AB40190824D523050229668101072913411CCC625D2880D1B1951C3888C222509DA20322003209106028C188000B02D92421111B92DA10890A228700B4464A1B01153966800B925423860884688630800C3C2910BA9511A1902C2B229532052D9906DD9C080192400249589E004914180600022440908012435624C48864BB46123C900588869C1001251248960B64844322513C5318B909118A8691A850449B800A3B02598A2052293455342701B3722590860911248939221D9024E2042601439410937318346851A836D192751C93686111749A0B4649BB285CCC049C0C4611A066203C304A032248CB861A34408CB4852484866244610A1068909280C01810C028531232102E4442C0A988C19C54192187223B168D844862295405824408C322222C27110170A910668D438529B025212086458185208078DD388240C1092C2C60D549640031989093530988425D104524C146E62A06C5AA004CC126AC3284490268A43468021454460B249A390681A4745D2965188220E6032249AA6280A034A9CB6888B180CC1021012B70D0340480CB3444C0010011549E2B23094064504378441B2401AA3884AA885112229D2402550B0048C2621180872912851481842499020C9126D1A1289A4404C4A82710301228920449C48624006920813819CA670D0C808D938721A118A1BB589111150C3C6695386851A0204D2426D19116419A38152C861403A93CB8575520D2A3A7317CAE1963E2705B7596C8E5DBF0DAEAF8755DF38A5DF16297CFC84097B480D9729E4CC62170739A1A8A2057EA7FEFB06275344ADB6934E1C2DA7E7F3E831FA35E6A4B8D8DEF435235CE957DF5FA1D842962711443BEADE91070833C84264B45E2380B094202E079A0A7C6058A54E6F552F202760230F6D95F5EA873709BE4D7603AC010CFBADAFE229CADA1F2BC717F877856D8B930D0E215C4BA2212D66E21A2D1F09B1F1A9BC8C298CFD65B318FE91847279F204201203E0922E82BD298D9BF18B8FBCF72070F7C7C51D5480E60674341CF263FD179862F37D5665FE35ED0B2A86B7115C90093F5785309CD56C48BBC50570A0C2D066BD0ECCD3C86E2A6C8B098AFD9C0E235CEB920D58F0B913BFB633BFE21BB1668D9C45638F5CE9650CAAA83DB2D9B4B24B1F518B19226ABDA06239698A90F30A50AF69AE1D20FA00E3D88FF6F2C2466E45A39A1C946FB695888383CB6A59A7C8395082134A82DEA3DA7FE6D9E6F76C7E86A50CA04990C70DD5F9AF062ED14CC661F453BF309DA08056E19F2F7B34A15235230C15EC6859D7DCF0ED892DDFF4E5096B36B406A10CB35AA81F72827C5982E3C5BFBB989E062CB4A7F0F76B008AB8CA5EC1CEBDABCAA1E97809B44C5F49281415337978184811ADB8131D2DFA2477D27532E92409493D46C597A6886250593FD58D305D0760CE8F772337D42B0F7DBFC483A941E8CDF32CE3E97309C3C404B6E4101678F123438853FC8A71C835D1AD0C7712460DBE83C1ABC6BB0834C0271A6627E7DCB93EFC25F78417BBC801488E5A051455343757F6BFAF923867C45ED5BF37304B11E012EE63A3B8D84DCE7A15D5AB940D87FE1181EABA3C97BCA702F5DE4DF74848A99D2B1F34FE2B03633D6AAC900A09C278556172DF5D9CDE361A8ACD779465CBAF50DE5C8F4CA0D15DF3F74347C6DDF7D9B3E3E5E197BFE0AA170949FB42B78364A72B1B106156EC09A6E4EC72F3F814781D3CE7B7AA2B02E49CAA25AC36DAADE0FD570A61589553A0CAE582BA2894C82C0380A713B0B74924E006A6B341F21AE2AAEC2016D2687F1AB696337F5A268B3B6F3730F507D6122DC92CAB36107E864BB3EDEEA6FC1C5309A9B51582CDFCC1A899929AD7CDBECBCBF9D38121D58C3B3E6D9BE001B117E4A7F762816174B761EFCF291A1CC5DA354029962EB8B0F6166A9C9EAF26921D1777E621C50C41614300605B1EE2A0CC41BC666CE90A15733C69A82451FD41F23EFAA73A2482C4E3D476CCBBFB59B25140FFA0C1CECEABD3B036F2611C83AA834E6CFE03963941BDAD4AEFB11D01EC43293BCD22ECB8784EF5CE2A6042F200F1B9D6C595EF920C3CACD1C1C3CB61B6B46454A3B28A472AE0203038A5602CB9B001620C98BC09BC2DB5621C8DB085D88561058AEA691AFD199C6D4BB1511137ED2800722A81670B44FAC51DFA6683675BF34C52F6EB7EBA35D22C907A207AE5CE6C3C40AB0A26B88DAE777E10B4FC33AB38C308CA2532032A7F306E9ECA723B58119C3BE662817A1EAB6069FA05C3B0ED31060D5794121A83FBB152C7FC05BB753C9D29BC329E745D7C7D493372C26C0336AAB37B884FB41741B344EE4D247D6B5D049E5E322CC97EC6647EC7551824C6AA9CD249F49FE1652ECFD01C3E7EB026FDCE7320D21EC9E4D460E50D6440C7364A15AE3C107CE8EE1E8A33EBC9D2B5585B8F69771F687EB6940C21F45750079D68D3DD6CE1CD7CA8D91A64D093A25A96628169B675CDA9F14FADA4AF3D11B6524465B89DD4EF93A9A159F8DF2A134FEA301110EB77E1ECA51166D26CB036BF92F1655167BD32D12BE04A91FF0B3C52C69DE376856FAB9B4E14524E5858717ECBD0865719BF1DDEDDF8CC141396F9F0B4ED38B0CAADA08B64451AD8BD38557660CFEF46EC0059B4AEA6A7534A3DB767C537E60210A1AF84EC939413FD7EBBF14FE96D6EE82A0C632EDC63715C0C6654AA4FE298F43ED5B47AF7350C32C8D7F696F9A96B81E9832F486A66D9B304A6531139561FE5A967061BDFFA4793EA986C3A2693C21DAD4428FE98F168EB928FCBEB8FE0A611049C1F430CCD80F9181D276AFEDAEA40261FE1B038F5677AD507EB48B9768964BAEC928197AC26ACB1A89CDDAF51C4336B6F49985C13926E76AA7D69F5F0844F23E7B2B977565587718903B39173F7F18AF84264370BD61020F2A76ED281687419E334443159BF6A21533F41E030654F6876AABB21025B6D2312304FF8BEFFB7AD2E225BF79F1B6F8C33AA90D9DC18B369846FA06548E72EFB2EC4FD6BD833F1872DF9659F62AF040345CB5B8399A4836F7F5A9F920F0484009C1F6871D2", - "message": "22AA98C685E1552B525B4302C943037F668279C224B6270DCAF2B06C4F4AB1254C48DE253829FE6DFFA9CB6BB294F054711BAE3FBACFB900CFD1F0844E55D51EC6F697B998759B14C13392DDB6F7DEBA77FFC22468781CE402", - "signature": "0313B5DD1E344BF95EB5D825837F570922337633494F8F2EE3618AEB906DF766F5ADDCCB8EC1C5CC51AAE0B9FAD876FCFF5D6814357E8C63FE59FD72DB3CE4D1650660A0CF64339D8B7C6DDB7A7A3C8EC6C88F2F0F70B377D9D5E21F0D40E17573F07C94CDF844CB6794CE2CB8E4A11254FF0012D562DCF4D9FBBD18348D13E1B69395C69DCCBF618D7A38EA6A51B9F1F8CC70CD36D087682A558A1EA9BF9DE6ACE5B350B6EB977F435CC46FD43F155B29822D68D1CA9603BA43F1DB28BF4D3CE284523BB440D1E2C124CF92DC74F19B74CBC177DE9B08377B0E363401D23E97AE967E13AB77E9B7C7488E49B45E835136EC2874A24CC79059DE5B0A67C842F2E09B37B3039DC186427F760CE60790A9FB58AA388880EC720A783EFEB4E11ABD817A7EA884E5EFC279AD9E8AC2C58A41020C7468A749933348EBF78A0F0597B29B00A126050FA40F532B0F4411B733BAA5C80CA1B52828CB236268989EA2641431A359E6595F49B4FEABFA85ED4BA85443E2D7B82DC7523FF627D336DA1551897438100C20F0184A963D0B9AF7F7CC9FD64A2878D8FC5ADE2D0D928445EEBED286F2B280AF573EE62E70F698BA0C14381A5B4E001C53C49A77E9F181EC65B49E6CD8BBE30B5F309686F7DC80176F654771DF17FDF136D6C05498CC00C476E71608A39CB29A19A986297CB9C1E3FFB4BA08ED42AD12908287F018D49A0E1AE89A9BB3F932DF98CA91E691AB5F3BFADEA9A233350A9EDE63CFC45427CAD109468FCE4ABF7FDB83C6EC83865134380D3FFCA4D94C5604DD9DAFFAC204C14009FE06311B81310940C43FBFCF049F99F5DEEA649A333F6A3AE6232EC7CDE62C95338C23085D776B9B8F4454E03BD0FB28046618C33A7CCB409BE7BCBC0906B5A9424B41998A3A1E65E5EC667A14339E3BB44354047A2868D64B78FE5FAEDDDFFDE497368C3CC130D0821C1DEB2C43119195C6C4CFF1D5A778965FF97685DD93775837EA0852284C670DD418DC9FDC9C44DB7EDA60E58030D8FBDF86D48B98230E6AD19E97D21D7358510E20EE374B8486341302EFA590B96C1DC253226A12CAFDB3B4A31EE2270F764B74F17BF9C5681B6578777739FF767D4E094CE80AD9804261767097BDB163430332C428CB3CCD9AA881316B51556C718A95816797CD5C8A2A640B85DFDA520D1A0129F0E9DE772724EE8B74B4DF6793EBC0A801B6F77A2647CA2A5F564D336BC23ECF591327A8DC4214953D99EA3A9ED9943F07809B4C36A8BFF093721949A2AEF2CDD9687934849CA35BA1F38743AC663E48B39A2A32122B6951CF6F1BE17FA96628D8DEE8760CF7F2699045DF30484722601E7A45DEB277CBEB749F5CB4383C8643241158EF13D8723B9B00C98F8BC68C5F42DFC4A1B8D95F4652AEF67798A8B3C0C2AD40CB7A2B88A23650147E32CB605324A99370BDB640EDAC9CE57EC22689DD45D1922811584B01685615520DBB0FFBB028E43B77B54AF4A3EBC6B9F857E9100FD9C64028867999BB9C7FF05D37704D41C94CD63DFD1A7673F817931A4F2C42CE572B24FB5E779897FA4E6E2191524783C710A099D1A6BB9EAE47E849187432A2039BBE1D37D0E7C797907F99BDB8E7FB33C3B2FC9E06708312BEEEF2935D443F29B646FB5AD52C99EB71559571781A4C86250D262329FF3DAACA18A5E7B77C3CE593CF3A92B12B9AE86CA3AF05EBBBD75B6BEFC368982D96F2E5FBC128B6A8D65FDB0B0F7859689F0B6F0A3D1EFCBF1915DC61C7FEEBD077F71122E77775B4279F4F57ABA521BE4682DAA5B836B5B4D44CDB726DFF3AC9CDDA9F0D1CF4E79BC9E90DFF7562CF206E756C38E708BD30820A14C595288730F42C8ED99A7C1F2FA6CA9759CD31B8F28FD35B9E0980ACC3432F462CD9CB4C594AB63FD250DDD4877269056677EA7E3B0AACD4757AEBA398688423015D952D0CF67E5027BA4B6B376F6380B5823717D64513EFB35015FBD20FB2284E1E340C9B94F87CFBA24310325D7597AB34BACA6753215AB994390C2E5A82EEB06F338293E72C5D0FF786666FF2EE2D429461F1112551AD0928844D7698D3AB0C4054881A623525D728E514E12550AAB227389E5F0C2341A6AA34BAB5472BC9E465DC24E9910175B2B968F2E7883CD22CC07B3D203CFDCDD877CBB28368DBE668F561E3FA1C5D3391D4A408A71E0BF0C32C1FD6494DEF7678E58B829AB428509C33F2491725959485928B2E7FA96EC7AFF12BA3196087D3C83DC242E5EC95BF95C8581693FC0B744E758E1E85959AB63E9B4B0A4547BE5ABD7D29BF9DA2D192B4BCA491D1DC856EC80AD6C3C738FB775F95A217D76093852AEE0CC203DB1316C6253BB75CE2D92906B47A5B733E4A8B0C28B1283419249B5A05F6302CE110F85790EB46DED7109B0DAC58A4D25255B6950F3B2C3421140E4825B6AC968091EA7AE9790BC8D03F3F8F4C1BF1006E821E5DA2C65C542183F4230CEC934ACB81FEA94D959FB6A21C7AB20652C9B247EDEF72674FE915858795A9A00564F602136C364A6D9638CB1BBD8A705B90429D13A19DE93520229282D5122EE112A32A68E23577E358FB28EC45478D05F64513A9E814A5F1FC7CDE4D03EC51ED41D29ABBC0F60292E2F7D0AA4490C38B583329E2D5A1E61C73D6033CB73A7A4F75ABBB29A31E52CD1EEDC3DC4F0B9152FAE6B29DD1F9739456AC5B1890B3BB00415027C634F1E6374F310C95E680086862B8BDEA0833997746814FC602F97999A2309D4CC05362303F72BBE2EEAD04D566579A00A8265E238FC578FDB2A63C57250B5714F2C6485BC6247752853F75ABF066637645A5A6AC0E85459EC2E24D704ED7DA4BA0FD23748D1D853BCF84D4D00EB4B6DA6D036B8F29797882EF5400F2F7D6EFCDA0418CBC5752AE5431B59D2D518FD752467B7EE13F699CEE1581AA1A305B2ADACA12647FA8FF00B427F28AA33FC094A374521437E3B4A109113E1AD8AD23E2AEBD69EDECEDDFEF0B5AA0A484AE32BFB2B05F8F7F65077F5B35C99B61EC28060437D9CB982AFA28FFE8AD4C02BFBFB071CA8E9EEA15CCEED97D47BE2313E3C344793D40B45F709C8A2C639C09662A81F117839AB62135B6715FD57F7B0368C6EE1E3234655EAE94213D24D92989A46CBD5C7EF116243A085462C5454949D41D2D570AC810B54C727FA5E187D0D9F7FA7DB3682D99460F5077AED0A90D513C0D833E5F5A91A5A26CF47AD134C074D658AC0164ACBAAE8FAE161E00C7F8B043FFF46FC5C900C9ED14C44C98ADDEDCD5F3BB7038868F8460EE12472DE2A24BCD0A611D9E039D60000D131D242E3C436E808FCDD3E2F55667698D91929DA3A4F0F72D4B58636C6D9CC9D9EFF0141C233B3F4A53595F696B6F848AC2F7FE00000000000000000000000000000000000000000000000000000F1A2536" - }, - { - "tcId": 5, - "deferred": false, - "sk": "3820A7CA1DDF6D374E8053628E628D142C4305EC1F3F05C66908FD5A1720C7F02EDD55DC8D2252C7E3FB5C91BBA1C615E23C16AD39B4FF5BF62EC0E22F081573D22DFC983A88CDB217F422AE9FEA6F82BF0E72EA8E6193E9DEFA584C29A9873CD76741016481CCB01ADA6063BC8BE27A5887FABA7F701DAD4114DBF31357508E54982900B391C1A42822330C82485114330A14A3601BA310D2344D63368904368293100840B42991C2405C22290C492C52084208A788CC266682148180300E10C330928021E214499C904812A169A13009A4908518882420926919A44D2448612217821A358019B2891245619A342A2132665B362994220E942812CAB6300A9251C910295B160848486E9A90641A238D0CC52022B9318A3266A2B82902440463380A0C373022B22C0B3152D40410DB100011265150C245424622103792882691D8207221088C8C246623044E1845698AB8886192004A244C0CA46518206C8A342C12498A1034455B200D02184E98420D09A30DD94028CCC821200150E4B02981466821434880C46DD0480E14884152829052C08CA4B26DA2C401540850A3828CA0A248A33240044032231041A3C680D3042DC9884DD1302A93202A0C250A991408E3160548464C64A2319818122308865A926814B7219A2071C214640028509C806413996D99002C1008909B925018266AD4020453026001950500953113A385829820C43651C30004E010269824660B920109362E500889E0326C14378C181589DCB864993271A00260C1A425A3C8718B8829CC946558243080C204583465D1B01088A82422120219244A02388D1A295244446E10320514488C13814544427052129182308A1BA14C1AA3119A163200B53049322AA14061801885D822520BA091D02422222112D94409D944215C84811416641BC40940088A61C40DE0162120842CE19000E024654110721B364A511085E398719A448223016C12A12121C4240A346520A850A332815A2051A288500319421B2831D4346C24A06082140C0211889BB009C424001034525A482AD91252CA96090101611892604016040B91214BB66910024840C40D00828D081161A142310BA424522612C3328820300D18C705243505D4320E94C8841C406253364811A061214669589611132001D8A430400431DB18120294281CB0291C374564A88811824810236C01C2500A24094A842D9936688086284330719A280E04A24C091312D124718298100C297123324843368E17AE9DBEF07C60FC5C871DAC487C6EEA46F0FB8B88470DE3D6C3F2B75C615689DFAA98540F2A9D1A3F8448947B6AC7D535DE9F3019C60901BECBADC594124FB4C677CF4341088FF2085957DF9F3837121DF75F92D40EB77D6F4B0AF61B2577E432316D09DECD949F1A31EBB1E4B51E3D412B5CC66BC65D4B399EE83AE52F558994F5C0C9D15617E43E9AB83A34C16D097A3690677B35119EB33D80A88F1A8A77C2343A29EDBC9B3D77E52CCCDC1977E09BD3EC6C8E05085D23C063F785B518E49EC3BA8AA156F16C760DA4787259398A9D343E5B37602A5318DCEB6F27BDAB8C143FF882993E80FAEE6707B26263EAC39E22980BFD23C61ABADE42C22549D493B23BFB6449FE242EB61986E5AB99832B161EF32CFDFEF5221C2710F1D316D12B170F4C9EC71DDE912EC7572DC0B25BE911DD536CFE6C6EFE9B7ECAE861E5D3DD28E68FFC7BFAF7CB38810DD8DE12B23DFCE3A69337FC423BD82764263669295023F3BBE4E48DC7A3F17337C7BFAABA2F7B57459C3572881EA0BD39DA3C2CF160B6C032F81A6AB8FCD5B94A7F2014F0AE904B4346994CD4C54EE678E23AF95BEB21A3BA062E1A9DECC2A983475641A66550FB2892F732437302F19F1B80F034208F6E4250822868ECC32F43446028DBAF1A910B923ACD44CDBEF856098EC10171A53B89DEB2488F6D4CC4EBBD024668EC570C00E335CA9AC4C031A3BDE783B093DEADCB5D6DEC107CC35591AEC160549D7263D1D3B6CADEC6D6DD874CE9C73E61804173F07E4F20F5B7A5C3698799C30E9489D1805F3A5DD6C36C70D38A573CD425FB89A928061ACE86F065F04D2C14AF0B8C9D8CB4F7640DC5AFBA3EA426FDA628B72A4CC276BE9DF0844ADC526BE701BED18843F001A88570BAD4181BB66E37C35230E2DCE7DE953D1C4C8F7CB7C46E1C57FB7F32BE90F65ED059ABB9250B8D8046AB35CD9098A49F81B5957B830FA47184DC5D10B5176142C956098C7410F3EF6B0CC092CF5B0FBF73060FFC9FC612767B95D1FDF018216F8CBC1FDFCB5A97B21019C0694231C34783D519346BE304BF1217BC6BEB5B2126CA975725328ED5CD6542B8E41AEED52FC50D1F99C35C755E207BE22A7C5904A10204BF0B583F486CE7BFB5D6CEC33370CC02654A6837F4A88E6CBE64C1930DCA4905DAD35DDEE0F8D4BEBC17A04BCB086D3C44BCFB68394384AEDF39D27471C422371FDD80BC72FBAD6C392285EDDA04A0EF4CE9742C020DA2F528E183E634ABEAE41785EF3C69FC8527F7334B6C7278960364AADFA66D58D8F7AF4183ACF3323EBB3505BDB84FB4A76B2CE0B768CC8BBAAE17FC2B637DE77E107ED1C6314F94677A4462DC03B60DE122E5AB843893944E6902724A8C4CA0C00D88C3D08D6314B4B07DB39C4EA413BE9E0DA58270EF6A949AEE60804A78EDFB0D4FC989C02CD7E48D116DDA1E91E72FBCBC9E90172501871A7E444449EF65F639BFBA5D4F297FDBD2A6295B67499FD853B4E26A82B62975B07945CCF29BFED8BAD16E67D95B8A485B9756CABCC8C99A11A577C50FB6D39C49B53B309907213D9E60983EB820276B2416C8CF8CA98D9A9FDC6CF3F122A81901988DE195DDF69D9CC38B36BF74BE8D4DA4C1345A5FDBEECAC4DF62B2146AA5BBA74AF45D2B736BE08593466E85AAF96FAF3FE9E5E6FCEDF7E3C80D1D16BF761B73B5C5EEB5F01AEA31153A5618404AFDCF85C2FE38E370B844FF850E1EFBE759779211CA7C219E2425B2510C00A653D32A1238CF423067A309E5839200F6C5AF42BF7EAB25A685D9965037C61047155A7B33BCA049ABB15DD4E869B7C9E525B607861EFBF250C83F95ECF3593484FEF1D49FCA407088A3B1B9CB6EC4FBD9CF8F2C1A5C98E667A8027C38F51299B6442B6188963262B14BB71F6824189FE8E372C6BE319147B719FE723C6861DE89A95FB61BD23A61BA04A6751033C5372E840B29C6F04951D3FF7FC559A3387DE0D582FB059E43FC5C230B8352A563E05CAA7DDCE8E068E5910F490706E8E6F58C6AEC45C6BE781AEEE0FB9AD868036E5314C44D2BE4DF0D4E47278BA9FF6418317088AF48347602D58B8F4CE43324CC9A053FA1AFB622664E8DD5020E4A6333EC1418E57C26CC3C45EA61600DEEAC5A93854D39F60315E99357BA88F58BD6136E96DA043825C7C17BD246054DCB99438E24DBAEA048666F15158D71C1543C2A550B9D24C5A24A9B78BFDBCBD3495D25449DCD76E8BEC2A65513C8EA9E729D7E1AF990D323A6ECF88E206C94A685DD3A4A9BBA3DDF153B7D98912B130C2A1C1DAA0262ECD8E43B5B1AEC483BE373EDEE376A866D51A3A6662C0AB3A062CF645FEF874E97CCD2D6C5", - "message": "0B0F604B53752973C4A72EF940C3FBA910AA9AF2916D673D69C4AE4DE92A237F271E84921C309B59B92E795BD26C5C015EC5176155DDAE8FA17D7BEFCEE3A23E0201669CC55A6F270CF0D03FFC09BBE4B47D318B6926808EBB49EC8B57A849896E76648D51117E8F518088D66B69D88E09D298186C10B5678EB8AE43E9C0A794C63CA9D597C4B74C959E9C1E8E0F46698CD64CFF3C0FC6174CFC51095E142DED9F16E5B2D3656555D2D42832280164E0C10C5817AE47ABACEE7C3BFD198A21BDD1C420F2EF0776E5EEFA46E8BCB49388FA6B937FD1FEB2BF09D5B9494A534F19BDE4E7BB8A5E4C558C2A166006B481A7C5865069A3DEA2B880AA503B5C020F045A4D9C3E5C590E4AD5375E74B732695A11164B5A57AA665922431498A9218CEB9ECD92700E92BD11E0A8140938C4FB9543FA5DE8EDADD1EDBDAAD11A6AEFF2EA409638B2C7AD546EFE390729982304F35D7F889C0CCC81D67F5A1D6201BC4BE8D1AD2D3CB85815CB9669B56F845148DA0DD2D6B5D7C4986DD3F10BDC78EAD8B4A88B7AE1FE11C634355F60A43A55C88B37954CDA71F4744C8E2B4D7F8D4A2BF60EF0C44CDC7F7059AC48A94B10279921709827A3E1E7A46DD857616E6B737CDFAB71CBD47639245E392DC116614CA3F099B8F2092AD667DAC43B8501DEA9876E5E0B98B41733DA63A2517A49C169A95E583F18F2E1DAEB4425E307509CC6B0B376827F0BAAFC2FB2ABD4E4151A8DBDCB8C22C78F5DFEF0DD1743B047E58537866795D67E35358020CF75F0D2B80287D62AECD6D34D18494D01B4412B1CFF279CA69C18A263E7B862F514A7A64BF192586ECD460D22DD2280373A66ED987635761C3CC34A5BF6A370F9F8B16F98808767A2D9A1517544D869E674980758B15BA7844027D3593432101FBC51FA4709F4D041BE9FF31DB9B7430F1D7F8E06C22C4BF3F8798D50C92641CDBF0B2C88E88666029FC985FD4E9FFDCD779C7F7600D02AE8D9E3CE6FF76F0B449C41BDB785BBAC9CF58ED7ED1525D7C7E885C0D46ADD0F7CC3B14394235B9176B69A222567E6533870EA540F4DED9A1D78F2CB89E6C1DEBE67249ED8F31C87499E24DAB0434FB9B40EA695499C76A1618A37B1AAA5309A914B6574209A61DE0633F086EE4F2455299C70B981532A23DC453939D223BA3A25122AD498795624C727E973C052E69AC40AD465DF55ADBB20FEEE76BF2906EFA7B0D9D5EAE860FE02500E2E0F4A21CABCF963D91262EAFEE814BDF9775874D656F8BDE11DA29327E3E7C7C95395D0DDF766CF34005CE86592F6787D1044E5CA1962C4DF2719308B2D6335FAC77DF46092CD3D5D228E381BD7E5FB4D2EC18B19E18E4748F662AB34C3F2C33877BF4A8D43A63F9B5DC75861AABB42D34EF37EF19CADBA110A3807D1699B247BEFE3D61AB84941ACB227C79CA05180FD3415D0E76EB31B4DD903D78553F2C22563F9B22BB876E81EDAECA4B8FB9415E2BD5AC32CC08775A20E8F90A1681C9957DFC330B6343E58F841906EE3562ADD6AA53FA1EC4AA2E894AFE769116E29AF49D0FBE2D8FEBA215E470ECEA81B258977A0FFCB17666953C29B2F70559DA00610398A08E0A17D69705707569D6484C4203C06B17439E9D4D9DB8456682A79659DAB332DDF45C67E527304013A422E46F2989BCF033DB143676A4EA720D0DD75584298CBAA765CBB0B09EF267D503F2782A427459FD2A83676DEA43C01D288429A82527A69B1EB19DD3BA1AB7428220BA74F79A81377F7ABBC027D96903AF6ADB4644E9F5CE676FC4D3ABD977D6438F4743476F77F3DA6E822AE61E0AD38549BD21E0FAC1C963F1D47F9E6BA6019591DE22BCEE5D5C9CBC4106A369C04BDF633F41EB1D6821B1F43194CC14B02B753584A659EA46C49B983F592C83BD959690845E872B471A38381CF3B2E8F4DC157D9A60FF56EC63B1C66D2227A069CEE7E48DB0E0D5991F96740D364DF89B08BA67098652958A14516534103ADD9E457E6AFC4DE1AF332EF3ECF6897B3DC8E5D6980FC5E5D829D4326F6023F48CFC9D0D787416EE61A0BA3CFF5E7C69BC83B18928AD277AABBDE271EABF8269701E526960460EEF521E83CF7A61A3CAABBEE1F1C99402EF55FD438753790CF56034AEA3292828AE858B2D3B9C8D77FF4545FAE7B4F2AE1EB17B8198F4846A8F4A105CE250F900969696E477B2C46AE786481BCDF85715BD270F9C29BECF4579F2DFFFF7750E375113E33ECABFC52E4DA5405849FE5D5F4A17C1F0984A1479D561943CD1120037EE821A2B57A12D7F1797E64E38A4B71E2FB10207ACECB96B3F3ADFF82EDCB633E388FCF11C8D105C1F6EDD41B553B4B559C3199745F3B0EB7326B867FD4CEDF4E9ABA1FD6A10E1494847FB5DC83C91F7A2DD351CD1AFDF95865701FDC658A41ACCA58E574B67929EEFEB371589374285148EB09157AA9A67F2FD54FCAFC1248F6D84951AB1A676637E9CB76C17C282DB53B1BEFAD8019F51B0400DC1CB012B97575ED81C129636C38998A2E6FC5AB7F0BF1FFDDB588BDE4590A7A0F879FFFC1183A3C6CFB341FB518D0786A6473FF9614877B1B722AF4B2E1E9B5E0DE7C3DB004EFA16F5CBF07870D7208A93A9FCE0EEB598CC54F04B1BAAA992C02BB2D27217AB20A3381EBEFA04CCB1F23E59E4B0DEC700E069DB7620E22235A4C5F54522D96ED4785ADBA7FF95F2A7DB212D3DD05E58C560E5ABD0EC238B7ED01E54ECACA7D32F7C2A3309A437E68C3AC7A9BC51025409A2A1ED05F8DB0EBB647FEFE6222D6F74DD8E4034580B675DEBA4BBFADEFFEECFF4771A0C1CB0ADCC6E9B050B85D230F6B288AC3FC24880CCBDF9C6A6976D46797B75B8532411FD89BE027CD8C81547B24B535825695A35BCDA4E2E0A3A6BCEDB73DD10DD847C4A0AAE059A07F56B0ADC0401026648BA469C534CDF6E2CAB8F581A7233D2F15BB35DC990EFBFE688F9B9AC5AA5C9B3E95DA7B0122947DA03AB9DB58090FF14B736B9CAC65F966206AE7C84B971D83944D8AB61589A28058E14193751B685058E632E32EF1E8C94BF005A3A2EC5EE2CE2FF6C05A67D87E56998E952E4557250E8AB5A979ECB28B0EE41DEE07F919E67670D9CC4077DB0D90ACCFE17CF6AE69DE0C9DBCD3D552A7FB37383574692A267B0A8BDCAF3532AB47887FCC94AEC3461A9257322095F1024C880273222295107864903F3DC8FB353FBE51C4D89F30FEAA5A570979A38B0B4AC9A4AB6B7169984C576BC4AD6DA1719CD0D5ABA03BCBF1336DE48CBBE167E4293DADDE3997061469F200A391646C8FE712EBE087B448F7A7DE437186D38A4CFBFC2919FC888487B15C60E93373D076DF6A60452E62E05256AA66BD1FB771CADB331661DB4BFA47581A4367069FA20E9C6229F79D6680125D0464F7CFDCA1F5C46688D5816CD90862FDABAE753E56BAA1369AC1AD3530630998CEB4545C4404C8B9A65D5A43443624D62DCEC989AA2CB8B85414E06AAE6BC4E219C5A3FDDF8FCC75381F6A0F73F54A7A2B5BA0F546235E71B233EC107900D8116CCD398FB14F32CEC310AC089D6BEC40255A6A877C30B05355544D115E8F85E428087A5F3670D596E31D25F676B3C6FF444AA0FFE5011AE62D6FFF86E615EBE80622BB646A318BC65950889616DEC254DB332649788C07E46CE590C2362EE66BB33BD43807A1336B94198BECE586CBBE3136B5CC809F24DB5BC3069E9C1FDFE53C6D1DE29DF48A9000A7E89D6862A773832DE2151423D9D11D722D923233137DB6F34F8DFA4EEC134BC9EF5A70424D895638D1B09D95D98CFA17308908D65AF00259DFB5ECFEAC55DD7FAAEEAFD4E94EFB36698D2315D795A93B8BA6A3CA93F6B79F2E599149BFBFC6F5C5742A83C886BDD4539BCC128F30B370FFABBE724AA3F3D571785AA6234FD2359FB3468A06A8E74918EE6E87CB29178900B49891F565A80BFF302BAFD0D5C2C123973BA7B9B425973CB3D7F2AFF3059D272A7CE611F5CDDB5AFF3E2B4024FDF0E01D7AD1C63FB47D9BA986C341030B3E5C6CD3CDC6A3DF9D6901E76D31C141C37619F5BB316209FAF8428AF19236DD426D70EC81E77309D5D9AC33CF3AACC0259A19F91E4579AE49EEBA41CF79B9499CD1211AF1E6DCDC70383A35E0ABF7B53A1203AADCD3AE638862D35EC4E441100E8CDEC7F0E6D22845F6CDCDA801111C4C7F261189C7D67B981101C40F21D33D05E336F1C7443560238C72B34E47758927E37F972247F4457EA60B2546F6B5B7A91B151E8B3800CC1748587E0D5421A43648BBC5D87C591B01C229C8104CA87C0B7F0770ECABD1E2A858147B62F607A86E1C71EF73C036B18C01CA5C1BA8242BC4BB7414FC90C0A8372F860F2EE51DCC1E457135776C377F940400AC5309112E6742617FC226EDDF51E95CAB40CAB58CAE1E662DD78C6E253B373BE970129193DAC7DAE372CBEA847248C2E69273B7CFEE70BEE59DECF64126D44BACAB5F2813CFEE1EF89AA3FD6D030319CDCE94FA86E4E64998266082F8BF74877038ED888C16907A8DF99BB53809E54520E4B5B6AD44849A33EC3FA44A7B179350DB07524823FE8384413F0A7E1936D8CAAAFE1052C462778B36AB8A9A14BCCC0319CF6EE2AFF01EF5077A10BC0FD0DF76D9B806481BAD1F49EA013942F38BFE52FB194EF8ACB283B1462BFFE4AC618D6FEE7E25130EC71D68C81A9532A16520075EBC1E9C3FCDF5FFCC150F3815E8647F34DAA814935D0E1AB68EC6A1B14FC7566415CC11E0C14A9693B8711DE2D3F78EBC468269BC851D2ACDFF5E8A6388B73E33F20C0C7621C6B644649AB088DC191418292A698EFA4871224232A7788EFA2D69F9F9FBE80FB8E6B0106405F6406D00A6D6185EB521372CEDF51C2E0876C7A86A90F1F5DCC0EB3187DF8BC62736663F713A1D403665BD5AEFD6BCD3413FC63CD68B3C5C7FDE3AC4164FC3737C2703AAC85E6ECEB29E34A6ED70D4178402814B5207ED2AE12E9DE009D0DE6A0BABCBC4ED41D5C28B1943C4B61D8B1DBF4395F5BACE1E47ECF0EB9E21F9E7F663EAC3788E935A1AF73B19714ED91BCCCDBEDAF1C74155CF235A58485BCDFEA58A929ED1E959DC99345C36109E42A14438466B1F9E728801BCADD16B2D8F762E4BB8B3F01E531339DE79634F43117DF5C585D7D2FB4A5D3E82BC25FD92BB1298AC79211B3866CA1019666AFCB10BBEE1AB63263F2823A86DD3EC57E8632C9F4975155A01F22859EBC400F5A3B8302ADAA5892A320487AD077B144392528F100F0A222DDCE5636AD5962AC6D62A2382167EA977743CAA6BA2F140655DFDEF168BD620C73A47A8831DFD66DC6F2A9F47E0724081681BE62FD15C74846980683B729AF1757203F457FF12925B6B7BC81775A9E5C53862B07D4B93CB2E9FA896AF58D258384115F1C63779E4189832C29C8B142DFF30C00DCAD2328A63C92CD1E42B2A8D2E18542BA3A81686452C83AFD5F6955A708CC1DAE500718C6DB89ADCBEBF119C4707B931E685BAC00AA60E3B5F9F42FDA6EA90F5C77295E84A3AB05D69212C5368E24F18F43B450181884D7AE8BBC61E1603FDEB13797F9620AD6C2B863C495821F7F726BD5801A3D5A36F4609B595B7653799B3794E4A60090D71F5DE1AA5F0CF562F7E722C55AFB676395ED988A491A34B462B2D18AF517569531308B8190F0148CFAD463802AC62C6CB289FC0C95C207AADF82AA7399E0476B774D9B876829ED91EA3E5C40B504370D266B7B3C72DDE2CCB7F3AB8E820ECB5715289451D352D83DB67EEA889EBF9E8B012C8265376C841BAF6EDA4067A400D4C6FB00539F3839A8D0B29906F9923B9244132282E38242257C339A0D0BA8F05F75D41ADA51E29E33BF65F78981F04F397BD5F9580376A8D1C552363D6BE90EC83C2AF748CBB7783D6B26098C641777A260F5F60A712C7A7D1CE681CA1FF969B8F25B90F9A2B03F71E06A848DF3C5C8571C5626D5A1F123DD14A9F90B3958A7EFB3FD522C7E83F897CBA80B95099F1705E1CB22C7E91DB644880F7DAB480B29FC0F8E1D0ADBAA123F1E1FE36835ABEC924531065354B77DC1082DD690B316A7BF104140F6316C46E81E777F56EECE625EA030C1FFBA3A4D40745E77129230A69D76C226A80A8CD31720B08D9207F22F8F3068C169B41E7136F94B73047377A8AC0987490E4DA2B7619A760E3B61369BF762FA9A3ADCB014CFD0644AB1FE6D8D3EFBFEC893E98289DA93AE19D8DE41AB33FD717200B6949AD21B3290C77D5B1FA44EEC7D0C6A9978D50B40DF77823FF2613BC80D0E11DC2B790B332D5267851B6315AC08D0A2D6FC0A8F93DCD20DA6054894F84C88CE254057CD2FE36693F868D812DD1D978897597840CB336223F8A8EEA9C15AC05D3E40333391680C4F4CD5C2F600CAA684BF09EFC8A9B71E6883E9353C22B379BB6ED8ED83A2468287121207D9ABF61D2DD5116D3B163F262BD3D57A23EF2E6154BF6EEC1DF88B961C4505F7CFD2E23E0E0D245A9418292A5AE6E60F3852D78D19E1EACBE9F42A522FA57554308A1D01E31DDCFB7C38534F7B48E0384AAB4B81A93681ECE4C55BEB089092E757A4633B2F30BA83E470B3ABDEDF9135DF22E2B29CCD0893C54C329DA1B16C2FE4221F1C7EBF6B3D6DE84EA1DA57392762FD9C64C0771966B0E1FA9A6E286C23128DF317F704237B97A339A623C985BFD6A0C60DE48EBDD73A0610A22B02D0978E626B50171FC8390B80F37E5E536CC184259D4ECFFA958DEE1A27CF3D2EFC9B218809909B19D573EF86087A1C9BE161C54DD1279E022F98030669FC93A7BF03FB101A3FB5321F654D2B40EF8298844806BB66EC32F7AB3BC7BED2AA7F22AF20759B12A0E3F82D3C3A141F393DE746D5A0D91F32D8249F0DB0FE37D27E49795C648EC6D96E352115FE4F10D1F56C39FF9140E3E87F13AF3C6480D6150E1B7B4AE614A577D6E81694C19E468761039E970335FDE9945F6119F6ADC184C9F2A434C681D593F34D258F2A8847E02DA5EA2605A007B25031DCCBA8A8C50C77411D197E742D4B3994471AE84E2B612B09B2BBAA38C5E71C22A8E3DD1F284A681DDD45E962F9D061846EDB9713D4F925A9DAC0E32D2A4496F68C68448EDFA87FDE3ECD47411AF5DA95D8C48D5CED988AFD72BCB7A81896EB1496F468D4664A58EC3874BC6FF6A85692790BB405592DFAF53CBAC93884A842EB2D3DE9619843919CD9D68AD89DC7A84BE54C406B8208428066011807D722C2B34D4A279EE43BDEB967360D9BAE50F654B2A06B576B803544DCDDAD670CF8D2D7723929842C6AFC4093BBFBB75D1F5E03682500AA0A34FC66CE4409D08C726552ED5ABB0C646E89B35A659C67F6F398D6BE39D9725BB0322D458DE2A62E46B62013F2BAE5E60C3D41975C6A4C6231F4B0EA2827329279459840911891B0111FB4B1FE99FBB482FED56C7BFBA15882CE5E2FA2C73E0B682EADEE6F68E4E1A9CD92FDC2CF30902453A16622AAB1273407B985FA4B7DB40D87812F2A10183464F8173D22D5603C44586B107B4B82E94DD80E87AD49E9C0FAB5C3330B74E89F742CA1A5940F0F329F56DFD40C6869D0BA8CA412AF9C5116ADBB3C22080F93142C7778D52C4D75F1EABE13FE50877C26D7DB429E991506ECF1DDF30A00F9E0B355306B889F41BBFD1B4D27B67952E4A0B53D1BF8B2E84497F00826D84A913F02649D5145383163F3C3F586EDAD06F518B64D9B300C4540A67593B9F3358FF2A22AC4BD7E7B9AEE507D184E039ECA3BBA0B5C584D3359D7121BCCE01691E11C120925A7D8B100751E8ADE99D3676C7355BA4BE451920BC7D2AD6E8EF0A9693F16FBB570122FE5F5FFBDFA490B3C84809ACD898FC0F807C77937C7CEB6F03308D3E9C657F80730EF3A1CEC6959850FAA6C158F23B23D28ED53BD77531F1012DC1753CE1AD6E0A629E14BCCE9D56B74E09AD6EEC9DC4A5C92049D48AE21222AF706B1C4DE65AA814AEF5B7E1EDF2D8A9C5B98853A17199DDC3233C5583B95756F5A9C175FF7D0891010F5D36A268ED5C9F58433A69185931E11BCBEEECAA240C2C5A4ADB4E770109F3F16CFAA37AF98E1228FFA7C584B13F850FED0187FB836E0A01B19CF700849EFF09BE1A57DE41CE1D52EA6F182E0DDDF741DBD2150113B10CC3D9E44917E0FD9717D6D361A88060E202039AAD8F31E4E6FBB4D7FD1BB5D6DC20C3D83F23D120EC98FF4912F3D9AB18D8EECBD7EFD1CF9B19081B38CD959660E8C63A539939D0CEDA897F5ECDFDEE16ECA492B216BEA35A167178F4A0FB76175D160FE2EF97BD6BA0E296922CE60D91FCBB3343ADF477F8A92AEB56A471B0711CAC45DA8EEBD21FE83FA68EB74C8502C81C65506C92C4A3F19ECDC2B7A5AB47704DDFB2E8D5AE620CA0D67197699677EDA3FC4FB821BFFB5F2DB03D4DDEC0BEB13EF84EC372A5C56C1E712C8D23D1A2DB1BA077645C85689CA2258E9B1B807DCC6394680B72938E1B61AC3E8A5B9E84BB4B58CE5C8C2246A604C05701C026185CFB872BA78CEE33EAFD0486A22C6D5CF9264EC134DD79548F3CF5FAA67D8B1FE74F6AF7B897AB0A0D8CABD5E1B2829CFE66D58CE00E68C6F23FC35397FBBF96D2E63825C96BC3CEB22FCF9CA46C93538F8DF566145D06207533627B665E39DD284F4275051229F3CCE9E9E62EDDFA55BB2AB1D1D8E8E6145B3E38F35F90B89C15FE799EC14F7E415FCE4EFA72615EAD26C10C1FFA4FDBA2EE04C4845489C21BE45C478D8B2116C84AAC21B48BD4181FC28C7C21AC9CF95D8B04C0D817C8ED8083D9CF8B81213AA2E3B8BBF4AD66A7AFDCDC4C420945F5B3E8C8AEC5C4F98005A0CE1B3283F5FC0FCF8567A150E12639CA85D298CE8E4F9E0C53817D3009284A5A0BD5D3A07234AF751AD059E301076946DECFED43DB1176A2BBA4B8A571299FDE4AA3574B6C189A721674E004F259B00B26EF5AA90794FD622040B80CA6C5E9FBD44B3DB21290353878F4D8D87496E374B05E6A5B25742A885569DBA2501367EF4C549BD5CE6169914A7F1D311D52CCFBE2091F0DB436506F210C137C2180B89626F52B4192C67ED06C1F9175E44B9468E6FC2208A98DE577962D9B4C31D5B0DCF4017DB1BBB2F80512C89B9AADE69DBD584452D25CAC97A4A7E6F48BCB909907B93F5B8108EDAD38CF7FB541328C5E8AB867DDCADD6A1B5083869E68EBC785C80ACD260C715624360F2F3D78FC1B2A464FE0525059A3D5E04BCCD72D23BC680CF7B25C5CD2AD6A0BB8366DB24B671D5BB3C12554D37C7A662AF9B9DB61DC6C7DE288DF1976DE08743426CDD30AFFDA05A8390A8F3A4A94D7CCD33BDB229E32850A77B2256CC595BE515F9E6854463966D4DB7A946276F594AD4BDF0B9C59D4D38E211A4465AEE023CE6C062FDF4123ACDED834F672C1A724BC17D44DE9632A588E7EAA77F3183E09D2ED55099BB1AC8198C96EC7B1635139980D5CA4B8B3102375A2E08BC3BC754D9FE659C3FA403218BC8C00FA87A0FA6F096E336865DDF02BB05049CDC9680E99C4F567ACD25AA7CC76C182A8DFC174BF6FAAF4D2553A4207922C1EA10CA8DA3E35DFBBFB5F6919FD4088A3A8E48358CEF25576A3A6447980F1C716EB58E755196A672C378F6615E54E9A16CEBA33CEA918768961C244A561164B61754F679856575DDCB32C70447BB738E84CA590CB523C6553F13EAC77461A58A7D4E1CC1E36E7BC5E85860B0E6B67C70D398AC0BABE1F42426D9E7F12B5E362BF3BDBAC42C572730C5F4EEA957FD3F17050625BA9D9938380249290AAF31BAC", - "signature": "7C6B47263ADC85F69B12955F66743C08E52EA89E18EEF82D6ADFCF8CC1B1A13D386305F13956EF20C02C65C64BA0AE526CE9EAFFDCD44DBA07600C4563EDE57CC7BE708C057BB3716AE33D09FAEEBA0E9B71A8E24D03DB2ED26C85754A25856F054410E286BD70A176095540559340F1CCABD50EC5E89B36F97783D35EEF716A910E6ED934332083F0B49B9B7995489BAD905E86D54576447BA6254C382732320D1ADEC8B75C85EFD00217DBE6F386C0C02CE4822AD52B72AAD0FD00F74BDFE62F2182FA1AEAD069074255883B08434E20886923086D3083864DD22EA3469D56A8A7F4384DCBB04B819274399346544F08A14E5E5E7DE0788854702775DCD8C6A32CCC85C1CFD78D5D27BC651FEE0E3EF0082DAD5ED0399F33C179AC987A2B933268A07BECB62CFBF4425609161E1AF5E706CED78857F3D1561A4615A058635C6D4F73E60ADC5E5567528A63B60D26AD8C8607BF09F4C8C96A6183AFA07C63CC19C25EF43AF3A21FF390185B5EE30904988DDD853F7F3DD4E09F145385FE52358CE2C69E3B14F7A2872AB7455EDC06A5C448298813D7E0A2605EA911A03D6670D08631BA4E11EC4CF9959C38071A959DF07610C3DE964D82FA9C5C37821E4A3FF7E0EA642370DCC4EDA58F2CF264A8A87E21260B4C0B84C5D5CB5633AB0AF0A40F9E4BB3D5A05DCC5FEE2D6C1BE45EF44099F740D35E5A515C6CA1D578E1A0C57BCCCADCEF80FA42089C055F13FFA1CFA8163B0C338244EAD2F473831640ECBFC4F7E244BA5A00FB366C87646A8453F44BE68BF5EB96DEC1B1428AE0C224F82A0CE6FCBD5225F1C0EDB502344066B191B81069ECF87088A81F8CC6710976C65C9C12CD4FDC0964B77A7D79A055A907AAD424F6D0B951086C3583963D823A2F2244741277B15171AEA99A691AC76EAD489F25FA84A1EE6DBFEB3E1827E828B8A04A87B8174F5AD43D0B59D39E88321D301B6506724042FC1229F60BC0D3CB2E923AD72D4F6F1B416D6E83106B042055C9F92C79C97FEDF1DDEE892C080521FA69AB735F91F369595F5DB09F03CC917F4AC29EC03E893D3EF6D536923B9DDA78C04489F020C4EA18A144E2BBE1B5686A1D8C8864AFCDC681632BCA685F5F391F07192F51FC9A18F0A05ACB47F818A12F3BF654A892D396D3BC54BCB09D877FD0D98ABC76BBB3F184BCC3BB294D7BF6F548720C6B8BDDE604476A876E7789D6584B2BB9EFF13FE32113250B6B15EED1C6BD48F54D2353E15766CF4AD88921E66BB2B17AFD3D8C0CC18A2DA69443F3F4CA9109BDACAB0CDC704B835F6992B96D088BB3C7D86F072675EA1C259A4A11DB96B9557F60461F33C06264E3EF6A405BE4640710A36835AD44CDA5BE55F0720313A5BD39CAD155F33261076C1211930D23D2202E8DA8130505E1B18032A743F293111DB0ABEE58CBE2D5FF413CEBCFAA1BC10EEF60477B2ABE50D598247D00917F0FD2C9122DD7EED52403364B14640EBD6525DBEF7AF9EF7051D85C7F80BFF2CDBCB61E0708AF53B2FBA4B6D5D3751D07115E693D68F4C6A0E41270EFCE43D9A888E83A6006703BED0622F5CADB57F6DE5F3E5DB74AF934CDC70B31ECA0751540F255EE3D29DA18069330CCAC2E49BD2E85BAD2B43CD6F39F6601FCCB84A5F47B94BFCBED53536FC7DB0666E0D50A9A567D78C2F6FCA01D94923A6373743C00BE3FA1A1A62C24CEDB2440AD7645475DD6D7D7D616D30EE0E35E5912ED4055A895848094895329F07AE1E201568061E27ECCCBD78D564C38F1681E7AEBE51C02F563DCF77FDC4F32819FEDA21F0812067FAF1FDBA95ADAC178B92A4762551C669057A483453B49209A20A52DCB6F5266E1A8012580B65707BE63DD5619413B56644BA6B5036C68E2E66245BFF8D6A84D55B37A497EB16D01724BF3790931AC164DEA3CE1952912A938924F5D4DFCD5FE398E0727A79C0EA11DA7CF1DD406AF37D91638ED36D8C03404359BA719889C8DAD452A98AF1538CF1316CE669AB2468BA3CBDFB76470525214D177DD0BFFDDCAB4C82E2B1D1764CE850209E37EA76E8CAA553BFC42CE5D2DD483A34502E73B0F04F497B8AF26A188FB68902A8B2F5DD8387D71350C77E7FA50F541E45EF0F68D623298A88DCE27547F83150C2E679A5F8A3D28EF96C229253BBD5B60F2BD7845E354B3D7329179C1DF91626E7549FFECEE116AB6A7EFB4C8B49424B68BE363AAA794BCC68E751B3A3F203E5A9495B440649F9E3DE6A8AE4817CFB738875FFA75CEEB6ECFEC6EB555B65493234EFC90C5203C6312B7EC954B444D706F4A572342059B765DF362FD07C3B48150476D5DC08D3409A79BEE44634D0AA92C6B70EE7DAFCB38252D91EEC63164EF7555786437A7F8A282E56BCC13511D71142FFFE35E6F3219555766A0A08207B2DA4C894CF35206485C2B0EE6B28662A64A37C5C1A9D4C0B366CC6D99E92ADA28792CC10E5AF605FBFC638C0A657054A0E8760118307EDCC7384C9DF458C3C64150925B22EC3E1A1720BFC967ECB4EC5BFBC314852CC17A2269479F1AACD60DFCB1E415EB40136B7A6A027C782FE7D7F7C6D19507D8C2D0F6C250106DC0A72E4448D0585225F9E735A8F126FDEB81192DA13BD806DE1482AD570BF016DAE36928EE49D735F91F059EDD2750D785BB14A44019916BB8BBA2B4F818637BA312D54AC37257FC9E2853C086E95EEC0066782713C98C82F582C0431C531FEAB552E1C1AF0B82D6034F04C85171FBE7BC0818E8BE09C5033DB552FDDBBDF5DA0A048F920B7FA61B7D5B38D1C85F3CDF837D90F64D31FC5EE79209C45A4670849C70C82BA98A7EE2030DDFA50E6952BC73C71A8CC49BDFCB0F10C1304B291221D56895D47C9FFC80FA25DCD12B40C96EE3177E9B6B78A2D9F59D2C2481143D3C70605830E3634931A3027A8FA3FF22EAFDEBBEE16AEDE4D8712EACFB58EADE2E5DB35CF01BE532C2631A1EABF4B5F373E230BC8765737D1F1DD529F10D2FBA8882E62C74937DDF93CF6B769F84872F779D974AC8ED13A55A076790C032D8367AAC64C944426D661A87BB24A5E4861D0EE60D07A600D4D15404EE920573F2F5A3AF5D31209548624B52D1001D2477097A25A0D480C1A1A04E7E1FAF0754E4DF5EDBC0E5BFBF152F23B54B90C55A8900F4091BC9C7CEAA1C7200C017D5F99DFD5FF5D7DC33168C4BB834AF29F3F651C9657D3E1653A7DB02D7E61BC48A13EC743F3107240F53FEF424B864577BC4E6D78E8634AF636333063B366F0AF833949B0770B3E545C563E3B3354D87993940A47128185D74EBE823EE752375264143555E6D7F8897A7C2CFDAE2013641586A91AAB6BAC1D2F3FE292A4C51595B6A7985999CC0E0ECFE0B181E2E3046477D8B9AA5A6D6000000000000000000000000000000000000000000000000000E1B2A37" - }, - { - "tcId": 6, - "deferred": false, - "sk": "0672A2BA2653D9EFAADFB90DFBAC95F77BE8540FFAA866671AF76F7CE585A21A5EE3BC98E969B2DF5F910F15A109DC09B91579F8761F4145771C80666362EAFE59CE336D877D8C724953C5738F65F3E1C551C1FFD9DC7E627DBE0BCA5174F200E8CDCBB1D8B0F84569DDB324562C66B5692C9069EFF52A7E4ACA9E293B26C1BAC3162A43808DDC4248A286401248649AB208E020462106815128900A984C94988C4CA82090926888B44D4924495A426E83B6050038500BA38D00B96902436E9BA484D1B88CD8A42D043208CB4089E12032613210D144491148258B08694BB00CDB280003C70C98883041A40CC20612982402DA06498C362C822209643089A34624129690818270A3108554206DC2B66001426A212222198204D1248660A065D0482214372662384C809808248040C1A44C1A4692133430C88808DAA650D812920230518B244CE302300A114CC4246A4CC44523B044D0B80C633800CB062EA4304E103051CA084D1BA349DB4828D1464D9BC484D0042CC9B60103A64443941080C66999100181142403050293264C9B028E53180D8A16411BC0290C47259C482553A405538401CC8868012882E1980C42440208A32008836D042292882800608408040289820812D0B609D992248C022C0C482A13920D1400244B380081188C0A9328220808E1460682386120196059441151A80D8C12321A07881144116338255C340050A064C0266DA232308CC684A224710CC72D5B323111246D944011C2B87108054C48184E49A6910B451014816CA0480A222588E2203050A80551366E234820242932D2C40C9008081A9750221345A1304D14A088CB06111104095B928891A001C48848E4264C0BA2499B022523160100924DA006908AA481A312481C9281121842040152892846D0840513374419B9911B010D19912C42386559466D802428E3068A24952411C38D0A1491498400C082655C448C23476889308253300224186E08414202248210846594288C1BC1210A246693A8011C041204308C9C486A0C47460AB50D8B288C58162100354E4C024E14B05112C80D80C40CD1484A1A36720B372419440962048D48424E91028103B405134082184520DB4288E338019B460299B860D8106D13240AD0B08818996503022A00372012079082B04559A485D0266290822D0B324E218291212006C90270803681544092D034640903011A90510CA2085120229BA009D8120452028820315184804C5492000403810A4809FB030EB7ADE0094AF6D6A78EF4A30D8A22BD35A79B413822D86A8ABF9BBC04D838EC1F2150FD86A245498E76DF32DE661DE605C76757DA5FFDA3082DA464400EFB1393D92A3A53270E0F144D255B5825B05BC72C287634A16EDAB6AB4422CE3AB84E45DB798151B1697FBB7CBBF0FA370D1F57D887E5026226CDCFABB2D502F7A82E983B03BA41D643DA93BFA387620265DFA80DF45E82C74C14963392199609CC59065A7D4C26646A87C04C31B34B2A70E029C24EF993B30EB53EDECBB4FBD6FAD614C581B3C04A15AC777006B0293183CA9DCD587960E736F780B1BE219928BEAB8EF5DE4B8A03449F33A65B2B08DB13F4B7DA0B756153A322282AD8F8D8F64EBCC6D322D519D6CF1A8F684CE469B9B9269759944CD1A863E236C856441F6C2198B73999AF6EF8140C9D23095847D3DB2518113BA8C96D6871C4BEA7067C0BF6947FE69B3FE12081BF58DE113C2B487759511CCE1FA48D814FAB7F0AB1B1323827A8DA71454578F1046CFD395E3683C332DAA81867B112E8865B6E2405D5AD2E57E8EDD695C3DEC48A52BB39E590ECC8F32B5F80382F1D444CBAC5FC7378C4D8EDB275CAE3DEB4C298EF20E6E4E25DFD2996769361ECB2C86AC0D28287685219F60213722CD172A2A2ADE055B515955E2D982FFBC13C2EB17CBC96371EB69C35BFBDA0DED49E6DD63021F38BA0C7E30A655401B6B8A9796A675FBD5044E64F6289C69248AFBFA217B68A5499E605E1487A07CCD60EC743F053731CAB8A2EA92C4BCEB56560FE3F55B21FDD604E6AED8F2511F0562B6F1AEB40B70C116BCD8DB842E26EA0B325246F4B6580559F26D6817D6BB4FBAFE4B144B26DFBC52D45C3DE758999834A642E871AF54DA2C86D7D4E3DC6BA54F5ACCC8B6D74EF7AE1BBD0C82D76A8E837F47BD53B8DA621FFD51A05F17FA88CC3D7143DD4B36F0674548FB886ED228BCC53B33998C3094258ADC3E05E24C5A8BEEBC588ECF45178D246D20757C287FF45149371931C75A7C59955F5BD1834B6738DA57D4FD28CBB11ADBCC6A11692021D5AEC5D36D6A992E7321C9FEBEB0A8544ABD8DB5CDBFB40889219F893FB4F543C22CA29ACA96B8E4C48E3FDDD763D5AF7C4A69AE763926F6F687130CCF2A2EE5EA746C3F1AC9772306A01E378845F568D3D885D4C267708B2C352C45905C7523A3C390B89F3E034D4EDAD9327785975D7286B755CCC9D9D4874B5A9DBDF90544421D7C6B2CD2876C4301FA891A2836E1C078EB7E4C31837DE4B8A38D270024F121DA31F48021CA533ED61FAB4B5C08CF3CE5DD5300722CBC6D1A11D068C604967D525394E88A0920EBC56AEF47FF4807DC5245345CC7CC13F5BD929EDDC183D10F83E5AF32DB1F7D87B2B27110B4A6D0B3AB5252079D4FA1E5FB3D667189ACC70193C1CFD4D7E3FA9BC93CBB834DD3C8854EEEF5FB471D73B3A35689C8E04A1367FD191DCEA35A661D0AF567DDDEECFA8AC62C34DDEF14BF848B35C9D97BE3978B055CF895477902B40CC35F3A7DEE7900F5717073486E8C995192619F7BAEE5EABCA9B314B4D0F3F602CDEDC8084CE573A6C7BB59E4E0048EE367D7FC40419199E0B104DEB93B9E36BB510B8E40A00AB9AECE27D5FEBCAC6134A303CA9B07F332DB85A8A03A56995876A74699A8170EB695F77395341355AA8AECFD30443824F7BA6A07034AC1638F4C6B602C48A0F11EFCF4CF765F886DDF128D16518F2E7EF3B4E6BF799D0FA82C152832FEFE7BDA434EBBD1C81128ADD704A749D46B8D5A4BECCEB7AD6E4959F8F4F191002A43FA609299667292332BED76228613EB5AA536F15BF7C2DBD73A002B133E7E780DE1F0A3F49FFA1E32DEC1DC496A0080CE85130FF9622882A61CB392D3233AB3AE81458517ED1A65AE45C6577308FC98B31D74B008056B666E70423816151EF5881812AADAF241B299222AB9F6F0C0178196846958E2C1B4536E2110029F1E2D7B8796B049EF697EBECD35E467704AE9248836634194BCB51E4F8474FA7699A1125CCE9FB62F16BF5CE11E422DDE6323CA490086F2F9D41B7659943D455C90BC978726707CBAF0224613828281276672CBA3FD13CF37609CCB8027FB026A8211DF8E13252AFB9DF7F13423BD9477A0518D581326181498DFE98D30248DA71F1DEC92E7453DAB2CAA2DEC15E1F73A249D9A8DB45D503780C94DF2985E339612AE8D9AF07E96E3B54F233636E180867619700CEB0DA7C2362496013D14F904C30594D6DCC3FC5424AAB9A4605B34808E22C697DE85453D4E9E55E0B7C04E5CBBD8F3530676B09ED3A0D5870042940C900514D9361CB3E3C5FDD687FA90F51C0A21A0E27CB420CA68356807DD24F", - "message": "0C39B65F4C2094AC626652CD33CFE44EDB2667CF722443514CAB443DC398A8EA009277BE397E1C1E7ADCD1B24376AF0F19EA50E56C90D683F8EFDE693F0F8834199544E2DEFE392B0BD46048A83C412A14834C4BCDC180457456BC72AA28F2DB247AEE84A1C49266361DA7EDD54BD9B562889131EAADAE071AE5A671646F49B2C1359382F1A3B2A6B437F87CC99A2A1BC821E1F3DBB311B8FCDF28546A479E2F9970870066A2D6447B6CE4FB65ABE7423910B9039EE3234836F924C8E82E1299335E27B0DD642B812480D6FEFC47B121A710827DE1D18DC12064649224FBC4526AE14317CC8E53BC8E9BD42BA444AD9B8B48C3AC807D7A7675F43E3021BA1DF9AC7A42A9E23D696BBD03FB5C4702B55F95854C41F470CDAD8A255436F910C089F71C2E59A44221D78AB81D4E2B059CC92A3841E1431415DAD4E6EB0315F423DA512661E4CCE098D6678F560A4BA19475296A2A1DEB12AF5900FA3A3C188867E0C268EFBF7AC53455552DF4F36E16D50E23048C7DD4E64341E6DCAA0036EE045B82C42121B0B779B5E7FF032F549536ABFB702B1CE4EAA5E389A077F47B1B55595D4888A4C1D17F4E21706779C9CDE25DD1261C8B4761A40B69E2F22F069A264E79CDFD36F307D117FC737D88F50EC67CD07D8FA269CF265A7E7CAC93E97BC29EF95C88904AB2DB61C8865A6EBB23871576DBABC83920AA015D47E8CE699A9E57E139AB7D233C577B46C9C314D084A1674A152D87D2A3D8A5D9ABCDA22E212B8C9A2BF25D8AD22AA3627E6C12C684AD2BE917F094263982D396364F4DE0BAFAB2DB89997DAF8B7E3AA953C055776FDC29F8AE5C28D4071534A9A2E9090CD3F723D3E381A2ADA6D9463FC49B3C6D2B76803F5C21D8DDCE965D2C472389D2BEFF448F2D81EDEF1C851A863AF66B64417BCC2CBBC70C18875055D171BE32C06081362FFF7DE8F8A23B076839602E2368CEEB79E4EA53F42F440D167A902A23ED53E6691AD3332DF5B0160EBC3B5C9567CF619BE2201447EA500332ABDEA9B849C3A395F596F2C96ACD9AF8313E453277B9F4234874E791E9DCFF0C9D9DFA8FA9474C026DD34E5CF3AA10CAB1FD23EA5DA0D0A66E520096C6116944F2E5747A974BF55428A3D2475F6276490AADA25220F2F2111892DB9E9C75A5401BADBF69F31B77535044DC50B1E93849F19C0B6C5184F1B14F68960F9F469805F3843198AC68E51619F3D712A34279AEA27BE4357A99C44C456BD2D9319147285680922B98DBC4D6D2860515D1371D2141C7A1E76EEF8586AFC973713EB89C1F09A84AC064BB7644625224FF1F7316B9DD1091CEB151D1A040F7E60F202728F7862589E7F1FA32D39653383F90C67D96D9949967AF234592903CBB968E0D979B92B5C69D09EF4E767741F1F6E361DCFC8D751CB8C3BAAC4CC393D63F71AA1488491CA06CC20B0BF54C5C225B6F0825677C2C40A395E1B7322288A815E59AD2999D61FE09C95828CE18B2997AEDCED56CA8BCDA4343B1E948256AC5EBDA23A8E6D7102A4474CE23567084547F2ADD9DE77483398D81A9A9C7A573D7EDAF99536D31C3588BB649EFE1495CEDED788EBBFD5775842D91DAAA2F9BE08D63B06DB35E72CD0EE5DBF45DF9B0CA682BD944A733D6875A62F8C53A3FA9337F13429FACB288C73220C29285B2D87DF2CB1A54631AF3D0035C1F3B26A5EDD07760A63576A395827F3D5F9B03D9E47A9E1E6A271021942648B8424234080492BBC56C692C769B5DF32A75F7403C88469E54432A37A895E3CAD3AB110089ACF534A0D78C2083CFE149A2D0A5055EF9F4C943CBE1FD393292518CECFC57E4FFC4D07A563A30528A6A3540636A3BE770B7CF03F5004D7C6F8ADA08DEAAED0422AC0C0C8D7515C9F8BF44195D6DC30D9B3036DA007A910BD05DF06B032812CE8393AE2777D717A691D07E860C1EDA60F6DE31F0787097D0D483E3A51CA7997646503738CDBAEBCC21AE4B984B668FB4020C139D9F581EBACB7BE263A33955DD68C9ED9BD2DD6C0A7BD049972B624CB7E787DE7184023F33EC0A1539C4679D6B4677FB971D763BE17D989FDF8C0AC4E0B5A6CB40A49B5464610A110EBEE9A21BB0D6A2F043015EB2C8820DD966A13EFD18D32367834D41E8673E997B2803638A710580CA08DDB4D90E4E8EE584BCA2FB853A122274142130A1ABCDF7DA6C0056689195099CC3382AF6987BA47EE294353674E7295ACC1C070F1D8E4107AA7189F20CC818F1D86F6D646CEE911B304E2FECD5A14CF5F36331AA86E10C319C96E52996D4CC12810AD7C1DD1DBDFDC78DF029BFDE9E8F9B1FC7D9DA99FBB0304A8129EC58A82177EECB7330E715BB3C0B4482923C7B1EC0D1823FF643014C7D08A8F2D9F9090B0F83663AFC5E601E5FBE1DDBE678B9D93C5A23F564B8A4DD29C8D19106747959E72AFA4B16B879E3C6E7F79A212A144F9AAF665253F1360ACF7DF37642270656583E06FAC85389A3AD76E69BC2735B1C3E13B80CCBD298EE25C29F9F5C275AAD83BA0E7C47526253BB3125EBDF5CCD6E1C4F9D9CD4891167BB4E4D2AA644D5D362C6F790E2776BDBAF8D96DC3A543C72ED46E431FABD737B4BF0F4B32E12E0520E60401CCEBBB40180985948045C58B0017C3D8797E433A2E2C64B9679EC7409D59B3992053EEF2ACD7B152E5F564196876EA0A31CB6ED47F2455BBEE6827D96C6B99E46F3DF1FA21F593E842B26E83D843118F6833BC273E12C7224E00E840B0041544893C6C8A06523DEDE2ACE7365693BCC6A8D7DD81B01310CBB8084C5FD3868539F8B5179519CA6745B56C4A5EEE8F2A8A60CBC7453E1E0990D176446D97F34A2D0BD5C5712E2D82601D0B9FC9A3F2420C65E4532DB3810FBE3635B2AC3A84415535FE41208B907EB3E97AD63DDC4FD694127EF1E948801B5CF651119CE17BEAE3396C098A86548B67DDABADCEEDF60F57D2941815778AC14F78C78516F84C5F9749B433DB97A9283A94697419CF94248B6819D9310324977D47A133AE9F1FC141B56D6302817761BBD52B4A1EF808E0AC761426C99E0504ACB6B552F9550D55DE787C12A0409A9F9EE3674617D15E229AAA98BBF4FE49CDC81DA3AD110645132B332B6D2AA38B35320925135BDD225053D6594E78389909E596C63B85DCA8B3F6C3233A31A1F8F3E900E49DF83F649E592979C9CA4BE65E7D6D1F23A7744626972D52B07B7B89CD90238A5E871666F4CA6DAFCBF34FE15983AEA5BB7F9917736F7BA46F342F0C08F56D19AB9569FD23288EBCBEE7B5924B8C86EF77748F3AA9CF2FB884398F83772C9771958B6DD063162A3AAA42E6A3280FEDEEB7A628A07702950975CD135D6338FF959ADDA2296B3E85A024F63D4ED8A5859786E2BC76C2325F37B4D91EE8B64F30E781BF48ADA774C1641CFAD2D63A59E294B5D99C94108154E38B499E3CA2A29AF7CC77A8BB3A3B712376CD081715EA715305C18B51470D5F3A6A82E9189848311511E8B0ABACF856312AE3916FBBCF6664523684D3C7ACE08D2345A3907C9C07183CB3E68C5EC3899A95430E278A72701E2355A4AF606DD8F8750F7F3682FB84290B2BE23BED99CA06D5E54190A5558C927C369C00C512342EFFC41618CA6F8FE6E3A38D1714FC44BF5679C1A49CD8BC8B28499602E277DC8832F738225920709799DE6961E0B4EC12397E7891AA772627F66F494AF719C55D056DCBF10E8E3DDF1B6C1BB2F0B2FA61949D1CA7D4E1F60EF836B086FF8C03A5916A14EB2670AF56264D7390761E6EB6F638D6FACF56B72A48F271ADE4541C8EFC91D15F69E0AA6B97EC0E9C0C3EF169E4A4DB1C1AF04762B98ECBD0DC374224D98FDF7788435BC154E1FB06C970A914C34DE52678F61ECC1969A2C5B1FF4D82E2C80CB543B4B7C9DB541229CC50CC6C448DC029CA24ECE635233C401D3715671BC75785DCFD929377AF5B65EC43EF45A9B00CC766695A4A5DE9A2E6582F7936B9FE7DBBA6762C41453683146F4ACFD809847F866DDF559972FE0C093EE7C9FAB3CAB0BC2BF8DA19466A96BBF2DD4859E2D1CE122A3CF16AAAA9A4708F72BBEBE285E1B794B2B9C7A699B36F39F033277E8B7BEAC3BC70A572556EE5C070A309D9D0BC35F4B6E55ECC91CE9AD273B0098F64E1327C85CCAEBBE67E8A118669653495D2FA09C29C6FCDF870905B2C8BE0DF806C29D5E7AFACDAC5F89116A3474D2229C76E649F99EB9EC71A2C229764A477853D68C39B8F0BF4378993AE2B26E814A337CFC103760CE92FB564E3A3E4546996CC4D8B6BE069E99861DA9C731B543BFDC006FBDE3B33D2C8C4A3F5789466122616C98F52E5E4BA239E0C3758C5BDD3BAED8809F67A70504BA061409A9D87A499236230EF0F1985DA0D765E9B7F733A154E8300490F458847A89E7C6BBEB7A9ECA7B6CBFFC3124DEDC1093C02C808DA1CDCFF5237745C5FFF51F3F15CF746D3397916A45990070490CA74A55F34EA4BA9EB73A281F123035C005BF6C7B30852665860ED13A2B5808F81435A77A8504B58CBA45559BD3BAA663A571F108685E414FC4DBF8033075E30CD6FCD9B893DA32F7C8D5D971D5EB417F1201B00F65DEF4EEED3B55B7FC7E6194B72A861439B865558157E65D4C2F8A1A93F48192099B375D111370F830B34EAF3225A16006D4749494B9AB9D3B05015E34866A4A2D94B9588A8DE8AD4CF90F2CF422634E8DBFA0FE3FAF27C3F3C2EAF9C1BDF23FDF43D196732E1FA6D2B343BB7D9F5F26FFC31B26C64A8EFE2B2D86AA34BB618FB58CCB54486211A8E66648CEAE52F07A6C1EB5234DA7CCAA971AF984D6050D1A81F10E6D19CC44B5E668CE92F4251924B25DAF41D5E381C3FAE4208D18F710B5F93CF3C776A3D81C608B06CE6BC68FB8A8117CE7BA065675B88510F2E8A440EC363A5983DDC1352E446A482C593A490AD6093258E447EF52BFD189ACD11C87A8B75F08B5D166C1DA69602EAA5916474131E20F704DF84C3FEF2AE99F9B9E8F7315A143A07C7AEDE5797F503086DF7DA971244A61909C4AFB00842FBF4C3A59B991B58AD6C0B8667C449F0D97F34CC41FE935D9F55821299F780359E2F631858617437D4AFE67DE4A1AA382B93CC3FF596726F0D1C071FD0E00883E9E03811FC659495AF2A62B45DA079A66552F2928B6A25C6416F8DECF723623764441E5E581F9B2E36479A1B6CB3DE9B090E3343277CD7F84E80219793CAED4945DF782C4B72B498A62A1F5362745662F711A7E47CB816EC7069D10CA8314845AB0C9FC326C5BCA0E2AFFB4E6948522F8CD9C8DC008855E592AEF1F8239748916878ABC493E33CCFFDB86CC2ADB99B6251F493F0D2A0BE56D133B66395AA695F6298F7F4BAB41420CA9B8CCEDF2719590287928CF6BB3A506D6678B814076B7A774BE9B7029DF9F4719AAC1D012BBD49EBCA6AF124D0AB5C5FFA92B4A895CB76B88DEA9C7105136D78B76D92079A5B001B214DDF7E140861D86ACC260B72ABEF2CB3A75C2BC87B39A9D9052D4283B71C10AE275474E82A5FEA1654EC3ECD468DE4A015CEB67BAE3275C2C79863E2883D46FAE351F0908F42825DC7D9FAE0FC7171791FCAB10E16F3F027E5043AACBDB1F05FCD2B3EC7F6F46AD6DCCD6F9E6A6AC702451194788D14261219F794EA195F2B3778654BB373C68AB4333E224D161A1F89FE440BD8E968B518EEA28E81B89E04FF1A85B879E4B54650FA8DD1322D14B4A87", - "signature": "947B02936A53FABF0009C0ED2E82970B33714BD4F15DDF7BC3A895DCEB96F9304811F783F8CC627B5B80868E23EE36CB98E6A5F9AF020BC5DA891E898BFF4A5AE003268A74BA6088E920511F5EEA54A5338D03356EE19C79E7BEA43AF809BD763EDED9D639DB0CDC790BACEF8983CB91F1087682A4E707E94B7D00EA8EDF04B57D5117F84589FA045A7B4A75C62FF9A344035E8B771D66D82156E28EED855DE1861023D5C1CD356C225AE03EA0A11BB1231B784CE9BE0D54DD6C4EF3128C7E14928CC0DB36DA5F81CCEE1924064403E964D375B071FD36CE9595509DA0BFFFA4E4C2DE1DAE201A55EA124C86F9B963221631AF131D2C4DA034A7798817D2734AE44282DA3BF2803D4DF90B718329F31317E5D585E323DB512D2036B74812C11B219729214B485D05917C913E742402ACA2127782534EB2DF176C5C25C484ABEF24A969EA2EB524FCB54A7CAFF7E6F464D8E716689810A2A02EC899685A1E28C2FA215572D188D3F39184D09EB93AB30D507DEDA6D6049E5345F989E071D26D909170D7AB1BD6CC35AC198EC7C0B48FA5679D24912E9EAB38FE594F1FFF5F2D97ECC84D8C81B81B2AD476CA93E050E550887D017E55B2B5D15700542E90A4639F55A63EACB727CF1F6C76D1DC7B6C0FFCDCC1086B7D8EE1C6624DDEF545082B4A4BA6637F8B77214914693DEDEFA7E62F5342548C0264206C30B631486CF5522D3BFEC6936AA961719984B84C43C49F2399EFAC02020613E97E16640EDFBA2D74ADFF5357A064FA43BEF8CC7D03AE781859942111E4C14CFEC01C47DD9FFF9D3D97EF92B4AB04C571A0C58DCE3BF45CDC01A7E09F7C89C81BFC06B5A4A46C88FF95B7FAAF3576D53346D18A0C179E73C4DE8501FF6B49963E2683951FA7E55B49056CCB0BB6759494AFC8A14A1D5823074E0C17DC279540D29C2329635189397DB8EC9F8327958BB00DDBDA507E1B54C226E7C02A680FA84E935588A435AA1CC029EC15CBFFF5B3AEC29034332C917882709A95266ECFA14D4459D5F7C60AB739AB428CD967CAE7D1D925BA66365A522F4F9D559D3268913CE7F0F228ABC49D4CA872878D7902F7A202A58FFC7D54FD7AEF88E31FA605840E510C639D0D568D7BCB1A72268162576717A238CD3416E89B3A77163529A816D613928C2CA18D2B2C6728FD622432E54A9085185042034D4DC8EA8E9F100BA7629201636CB87B2E5DF1F95FDEB407DC330716AD0D6ECC93BE38E497E1B38B94DB5DB6A5C067C6D0E1345AFBD7D2AB9646B16C531A96D4B3EAC2E540D479118F448780E15A3C17FC34051B4137C8E52C84495CAB2CD93420FE657743180C93337E39306874F8D54DCE702D5729F82710ECA144F040DB9A0907A3CC4DE9A12DD3958047C157F826F9C054CAC044567CB71A727CC9FD94DD0A388DF0A167DB6F9F16FB00DFE96968C463CAD7617587E5698DE7AC658E954D94AD94A1A3E6A5FFDF9B7E49429C00212839005E29803DC4CC4FF778CC331DC060E69279263005685494F686838DA7930805AD839437056C62510081D276EF676739C0D689B2415D3EC4C0BF67BF52C9A2845E7361BEA53111D6DE6F5EF65A22A62396BDE531886D71B925D91AB1F916AAC97201CFC477B694E898AA52AFDB46787BB85F01917B06E34342D2977E78A5A82CDA3C93F34BF9A99F7AE9ACA24D4BFB2C57485934EDFB7123BAC3DB085DB5B0F2FECD29AA6BBA2EF2C2B04F66605678BEAF90F448B19ACD4918A337FC9ABC098FCC804AA1E37E22C9EF010A9FC40CA42CD270ABD9E56D31B12663A984513AFE3917F3982F32E42FA9D67BA2E5C149FC2E6562E7EBC24DE2E1C475D05028E69AEE688EEA60155346843F71F1F99B3D4BA69DF71ECC4AD75FAAE1921EB47EAC6C4B73F31220F1993665ABA88F5C504CD7F6D0789B1166E4CDE2CDFEB140356CA5FF1B5074661A90958E940B8A7F80CF298B8366D81C4EA232DB4A8A4153028F9BC9B9758BF1BF27B7A4887D48A09C453E3F81A8D7D92ED7DA35B3828463C4F2AC5BFBDADB70FED3E73BEE26CF0B973FC6C00922C2BFAFF53842BC71294122CDF7E057931E46790356856930EE6D653A70F68E107D86CC521232ACB62F86626DD626E1D5745EB26B91917D11E68A6BAB09B6BB0BAAC327A37504E3B10037871BC8D92466D2EF236552C1F3E80102F8FEB03BBCFC4C51039F17D5490FD61A6E5BCB4BEDA507013CEA1C810E933CC805E67C1AAC6DBD9D9B7204FB5560D691148F7369996B48D370F32739ABD5E1DAB98BDE86FDCCEEE4459E3396C8ED7137BF5326322AA7A41B2AB74CA5D76ED91DFB678C66874E7C6B4C6367A5BF256DDBA53BBA20AAC90C4855CF1C608774896A974DF5B1840A83B2FEDC619D707AE30B186F9FB75BEA7531035207AB889B92FEFA6D9802E6D44598F534390178F14E1F629629F6E120C1DC8F5C14C392C117A239E539A602E521360CCE81F3E70D94FE371A13B7A42CCDB29709428D3EDD96CAC31BA34B91BB2A92C9208B7C81AD8300905BADFB91DE8632C7E62C4D4E4C32616F712BC4A50858FDB651AB486B6D0D16A0BA10D128D539E3729F364E628A93DF73DB954C5D8A1CB6935E1D5D3AC2F905DF189736539298F7A20B3C705453CBB0E991ACE069DE62A2C89CB956E8E0110083C344D971C61101DBB2978E1831885EE7C27A6CDEE29402552D701663E5579F450C4788D46AD794217926CAB7EB351E93CC7D3771975A969A3A06E789EFB410FC829123BC00776E6940D8C15CC8773992C0FAB5CDC59EC4AC6A8889EE8087C26AD7702A8672F711859A179CDEDE22D1A77D8693395575ED4E023B903C6F14FF4A2191E49D4C21398E484B3189F50853B0B20B2BBAD0EBFB75528B4B6FD5C7B7B71CA9D4DF36E67ADDBD7305839E7FB2A25AC53AA1622F13B3B4C4E8CC8198269065717451CBE58B8DBB1F448C96D5940EB94460618036398172A2F22CCFE2B31DB2DB562EEA7415AEDB81D65EBADD8D2CF04C69D870C898D05353D8C5CCB2E37A6EA9EB3E5E9DF32175888E07F4472A80DBEC699210A1E6B8F4BC7968C3FCD9666AC9D1CC81C3428A26A3A94C96292F3A8341FB90350FC79DA7E0D947751C6E1E17770B980EC325E0E87D8A283F0BD853F221873853DB22213BFD7A7D621F64BFFD73115B48C4B06DC11F307538CC86B351CB23E199E15733A2B5E3E2360B42A203F632A8243B1557C64773D72EE1D3E3E25AE943AE3E9F984D116938D39005D4556B76A793AEAF0A6397691AF7386F509668B435DCF7B10A8B810FA55190D56DB430E0061026292D3E494C707C85E1ECFF151D1F243063646C7D8D909CA2B2BFD3DFEDFC08173649595D667C8598C5CBF10A37456575839BA2A3A7BBC0C2F6F9000000000000000000000000000000000000000E212E3D" - }, - { - "tcId": 7, - "deferred": false, - "sk": "A7DFE40E0A335C3B287EB94E97BB6875F589EFCF7FD841EC88F9D03248BF26C9EC8E7F8DC376270F7112B52DB67CEBFB8A5FCBEB0A2273FC3CB8FF1CA1DEB5C581335B8F6C53E0F8513C42D5AE82B193BCB8BBE9298446ED79D278DFEA201D0B2667E3806972F34278B83138432AAA10065DE34B24303A4E5BF1A5E3DB90825684A0205948885094459C3840C916061A284A8AA40CE0A828123369E2208254C66C91A06C64426AA1B44508418220379218170803406C5B384ED3224A48A2519A840DDC420294A82C14C105118070592009D00405C8B08DD2222920B8880A39511086805084910A098AC3A84C5824080912698A486401182C489804CC14051912250832855A202942382252B8880A814119032D1BA5214A448492366A91B84C1AA528513669DA240E14820C08A0244A444E83B48C22224212C985D014690422824B882913298918A1201293306400201806451C8051D2A870D1444D13268A1C376D84186024C6081A262D011621C3048E02A06C832446C2C20599826418B86459B0618B240422B58CE3080A0231229C244DD4C88448202202868063B68543A68D1A132E51862911B929918868D9C828D4320C0149498844105842269CC265D1165064A27049A029C12641D1403100262A51828DDC2401C14670D3C0484C962909A18CA4A485889410D00030C9808C8814501C234E91287218490248828D890005D4222D0BB26C21020018A00098248960A88D8B921062B251224282D8B02853A090A24268CC0651048940102229140988D1322A12C95023C68401068889B62819180E10468D03A7500028051286248B9880D3242C0B172111176D5C048991888C183388D2268DDC42450208300B302253148CCA888D89B665111482D1A029E428315B462952B221DB126A01B90C0A3361A3420D1A3528A232498898802011285C200EC3284EDB283120264550C04903298021004A1C347098360E11A04914390CD9046408100D09202904A52D524400D01488E4084823B4110B907103440C20425021085212994CD1A8290B4229DB1229D3360513256162340814B24450068002C20C22C98D4B968520962480402C51B26C0922424B8041984809E3346E24829024930C0A1348533440843004223826A2042C1C9484001860DA864D14331204118E030144E3240263C029E288291291019AB22183B29153222051380400A244D4066E19160E08183120388C14B88420152C19A02C22192E448468D3B048D310612181EF7DB8F0B9A7828845B0CEDCBA94F60B86C183E48327BF5CDF316E9A8F55571B452EF600C2A1AFC57A159F501016FCA48627C1FA9D7C3DDA58BB4D41EBBB6B7F9DCBA591719CC4B9ECAC146BF8788B48C911600FEAA5683EF2D12C45A3C14A0A5A62839944B427439881DBCE4481DA951B10D81FC7711D64CEB088DB4A70B5804ED577C30356BFDA58D5426DFDEACC6F7CAD7C30E718E7FFF4AE006BD98232417ACA13359A05F8B389FCBB29E9B670B28CD8AC24F3ED55F70D8BACDE3F144E79312D8298FE6AF01996E00C5E8D940A408D532CFBA872B461F538E0C7583A73D8C93E9889E251EBB4C7B1DCE6FE013DAB5AE565DC3EF4F4F5429930F1A6DED98A66932BE3B985E4DEF769609E5EEFE6EBFCB6FC56E9542FE4ED8A121ADFE9E19B8F9EBC4B9C1F4AEFB351C2D3840499D0D2227B157DB138EE62860F2963D6F3D6458F457057E4A03A72ECC52589B74E12F4EA37D8E0D9797EEDB246B88744602332EE0886AC9630D876BE34D9FFF286B5CB06498C60CE53A558CAC63DC5626DAEF14F702CA476E4C08A569DBEC1763DB6C5910B8D2352C6A648B2A6F27F9E248FA4C42FD48E7E9CBF37F318A8D4362C1B53741B41E4231680A6F91122520306325C2621EB87A1736FB79098006E83E17E7E22637688CEE4BA8A399EB1583CB8EC9DF3B8C284A230AB6622D73F590D19331783CC2C921EBAE23DC5605F4707CCC96A18924BC17952916A97408B4715FF3F9ACEF8FC4943BFF6C9F7F5E7DE18B93E679D49D04366A658AB913EA5209D22D72B62992383C7EAE704259B5932FC09F76A12FFAC12605D8715366167DBE45B272EE7EE27817128EC94E1C1299DA8F58E4206D477AAEB8BAA8634107E14059E75C90926189D3FC06C9D38799F3E00BCB87637EE24705551A797899C9EF7FA41F61342E9B2480508D9D3401EFBFD12776EAD4CEBB815F505E1347609AE7527C81AE892C841F0D21C7F97003D5F9F3843DBDB89A4E55E52BF915B92F0F2CF0345FBEDA99C322FE7BE34E0E08034078FADADFBF0661AE573EE9B664C9F05A8AD3F02B1866D24B8230D20FDFCD358BDD88AAA4C3E458CEBFCCAE2D65C64F6066C7495B571814F714545E6423D322848459DCCCC2120D8BA7CF672F37C5343085045FE3037070310E851508A0D5605249AF5D911560D308C81C7E2F2538A0A7EDD6DE341424ADD8249D628599953F857913F5767584A7420A669AF08AD060281D536C170F383C450CE8C61DCCD534AE64B91AFAEBA4742808733AA718A13BF0A55B1BD4AD618A932F84F8039754E1E316C560AFE646D98E928C28D39F5BF2F0D0E079C6BBCDBC5843A5FE72E99642B0E297F11AB5B9C629BB4601230F33837975AA2C81664825216D8821B79802C0C3812D1C0140AC676860C565E7775ADCD2D41865B23DC61BC5BFD3A80F56561DCE6F2A79D37E85629FA6EA952289FA3AAE5DA7D4E9238942684EA932F89AC0AEB15263AB2D5FA4D3D181851E38BB2B3B5702E6E8DA5CA981D2DF3A0A7371A75EC897A46205D9F05594DC169333158F929E3421220EFF6204BDFA75E41481A3E70BD4EC1D4502D902698C4FF7FA6D69CAC4A8F67EDB414FE5EFBEE8A6B695B218AF6FCCA45CF900550681B124CE36D2D9CBE8B2F179B4A4009281A559A6C5B30D4B6DEE9BDABEFFCA70446166CD353D8905641EF072F00571CEFBEEF7A296E7F49F5B112F6F0A6F1576468C75942609484DAA448F4508EAFBF2E9DFD2F83860831D6EAB17B8FA73E493E3D8B71530719209FD2D24637D6323FB03E3CAD1FD601F1FBC7B408D3AA6B90C053BAEAEDDDAFCBEDEB3CE0C6A70FB83AA450A9968CC458C18CC9571F74FFE1ECA182ACA2C4EA57A60BAA4D922AB6B006EEA433CF69448AE44A807846361F5E09D565D89410C3CACBC284DA15BA53860450E28843A662BD38E89C0AFF23ECB50B85C7069E44E211DF89CB12E6CC211036B0ED7EC5C098027A8C11EEF0898B785DE421C8212EC9CFEBDE72463F3856831FA209B8C21E63CADDBCFCE247F0D831373B7AAF82B676FE9C7E3CE70752AD0C45FBC3C11B157834103B74597644E095C386C6FDD7C9DB072EF20AC511DB9D4CDCEF85330E1372512336D5CC951A7424A8EF7FA4CFE956B6926DB9E1969747B814EC682659DC28A088A37B62D9E84485FB3B33B6F69BDAE3DA0C7D734713632B9926421B7941BB44D141AE72819281CC405F667772D68837B58156BEB2E2EDA6A51D9B9A5DD972E70F3F2B9DFE660884250CBF8E539EA6E637A693AA3B7E34467ABB697AAC4FB376048621F2DEBBD94E1DA4C9A1D2AD21DEB16A94BE1B0DBF0B5DA2C38B618CB3323D9F", - "message": "214BC54C508E63F77B261DC59588A87CF95C233C22A339E7158C47931C1EFEF775EB3C91A32C56E888214F9F68D7CD2525B23F695871CF5EDC6979A677EC19CBC5859C63ADCE2E38C67CAEF20116508F33BE8035E9C47D124EEA5FD1651D64371451B6B96601E4A6E8292ED6841E483C3ADFC3DB242D1D7B3F036492741661F45232104A528B6FF79AA4630740BD16B37CD3E7C711B76A259C0845D6F87E4A4B306E939AD1C41022A7D5938E52B98485D95D11BE629263E6CDE20F63AE16CC2E32B6C1C442EF108D92495A759D3707AB6CF3ECC5AD7C02F133D689E252A26C014A31C65A65F079C622BE3B648496BC57C462051B17175FF81126B5BBB5324CCEAEDE0B5A8ECC0D710F04DC0C751318E8913F149E701AE0568B5426736288CAFECAB1779C7F4E96D9007635F76DEB4D379918447F30167F257B8BA825A50EE845FC4AF7C34AB200D5BF45B5F0405BE2347ACC814BCDC648C274C24F8024561FB66676534F1FC8041B63114679D9F4E8CB0BCD7BC4C54FBB4F9A178B4FCE64E705BF8FE42826EE01F691479A8815E2DA00111DE40B5CDE464A9F7A3D21BE9562FD9A5C5CB3F4F9E8F0D8D8A20B9A5AC9D7394AE4316181621B43D8220FDEDACE345234E3DFBA134BF54E458DBEF98923C1891CFB8DC9B5317E3B16C740EF373666969C95BD1C53F435D7ADE792FF9E310A191246154064D0E8F20032AF4823A335D88D5C2A943CD4CF313CF2999E237F6EC50F63936D0FF3F2C729FAF0232671C94785B67E0CF71A7CA5B32434579711EDF155D5BAEDEBBB8F0C6922AEB9798356714931AF1070C49BCA507E289F005BE9D8B46AA67CE2137935C7EFD192E4CC24DBC434B381E9A15CFC529D0064F057FC3AB592869E5F1AA5FCB299B2CCC0ED6750E318F6FC969E6A3A08059788102CCE79BC92804B1D08F3BA30492054DB6401EA251191BED1B8CD35DEA3A653D5D546D2EE8D31C2D88D6275D6C7B463D449DDAF586D5E57FFBC07ED5558D87F7DCA82E4ADF49EB9135A578468907BD8A6228EB723241D58BAF3C78C46451D2F11CA0552A05A85620001D376C6194AC6494E337388EA49821C233F32579FBAE6D11E9DB257C426D99516A16DA63A7BFA261F2B012CEE4EAF7C5C16C6331B79A26E79B1421371E574505F61D699C6DF33EA734ED14129608260B1233C387638F7ED3A34866D656D74F06C2B8D70AE60A0994F3D6C1267DCA2001EA781E5D6E17BECD284F967788227E060381ECC60A10832091319F225C972349BFEF08D4DD5298BF7EE11B693AAAC682F91DCDA113EFE0F35CFBAFF6C73DAE43B8C1124EB57713C122F0A5FB03D02C4128565FFAEADC0AC23DBE5BF123CBA024DC2F3956EBEEE95918B87D2EB22EB1A8ECC3B267528A62F2280E3DAEC02C89A01F5829B5891914DAC", - "signature": "7D337573A06A3698B8631704D2D6A1E529B45BBE47236936D0BC13A6DA8E09ADAC5E60E2D0D2D5100ACE99EA411D50C77CAE43BDCB50B330412EFD99959E562100822C5F2B932F7D43EB8015878C49D182EB968F3B12313F6EDF5056FD9518FE09EA1CEF89411D126346924C0B4EEC9D7447083482C12D6B98F0EF74913E66A018319143A5DFBCC3C21D1AE52FA19FCFF12E4730E4510B90EE9F9727C240A145CF34A01A5BA058CFCD26611D7F729F742610AC81B94E931A47039027F81377C84CF225763F68A446B63D64A3D375E1EDF67C1EB3E997A43BA77F108CA3D16BCCDB6CC451308146348C33C9485F4320E8A7ECF3758128B929D4E8CE07B3E84999515A0E5CD7D7D6C5B3EE0E712966D91666AE5C2FE8E30F22A83A1A7DA0FFAE83531C30B3A0B49029239409F36D384C888AA82F86B6D00C0D6D02FB75BC49831489161BE918EF91AF79D031DACC7CFCEC51467F5FE59095C1E8FFFDA2970D4D5EF2B72D519AB0F9919BF046A19BA279F64A084627315938EC50A5B1ADE46A4A2E3D382BE747D895E0AC6926EB6ADBA0E845FA49903B83BB56520B809B034DC7A4B7F292CC7167C51969C2C8E78CFA42BD342B78104512AA4003C48FD059AE0735F78F4837802E6711B35BE35DE93B86D9EC82C9303B732CBE1B16BFC3E718C65288810A5510410CA87DA489A71DEA594F993C7B45FC00CA68BEECCA107FF4723339E15C49F7839725AE5643BFCDB2B98C443DCB6CDD5169465740FB9959F2B17B4BF31D0704FA48ECAB5BD0F4CAB954AB132D4BB0014E558083F1ADCC81B9B5ACC2987F57A3CB069187325D5F5BF5128185608C464CF9534755EDAA7404E35F6182BC83D016C8892E63A7ECA6406EB369FFA55AC37963946038E3F74D9E18F3F40FD190DD510B07D2FDD244D74342A2DF22CBA0835B5A5183A4A9ADE24D82D7C988723031FE07BAB95F4BF96CA393BD58E74CFF56F916B8D3835F833EE658C788E9AC56E408A5A4E98F05C2379F75A82514AD1A42D9A90742C7F92D982B9C789A862259953D9D88F1BBFB1BDB345E966577226C87C6AD8DEA26F75F0C3715225B5297FA7C5D375C1BD8B5D6DEFBBBEA757E6A504E83B0F2FB3A80CBE2FE526CE76D799135497C498A721AF6EA8443934E0D76266ADB52ABE212AE58D7F52458901AB3CFB8A1EBE9AFAD9203EEDC9D1BA66ECCA41D8C268541A83CB49243FFC534C9EE8E0279139989FAA602B668669AEEE6E00EDE80F60CD41929A6BE3800E53677056C7D0ED1AC4D80AD357D96B7B2C2F1B35EA9B9CA397D23A2928245F7A9A0BB4AE0569F16C4445EA9CEA3094364A40E8CB5D06E1F624DF1929782CC33FC322201525CD181CFCD4A5D4201693D0EB249E9967095F73A35F4ADCAB9279C93E0F62E533E121F3396767D409CA80447A4208BB1D83BF7688A007B5402B5F0BCE4ED4EF51847B9F036C3BE81EEC6A6FBC6980D5505BBEDB99FEA87140EEB4B3AEC965108B48C6C808414512F04B5DB3D27FF450D54D6CF5CEF9F9B80D60C0C9A2F2E33129411013599A1ADC3B7CEB410CD007E413B463C1E08EFD1AD51B08B21A08163080450812D6B020A299BD8BF3C8B5E6AA69BD5ACA973C625D995EAC71A81B31E75B4BE92A773E9C10E7686EAA978791E0A68C0C5371D6FD12DE5A370B09F90CF140B7D1B63E381919EF326D0F58A21F04BC24B5623713C0F42E56F4727278C1AACBA51CA553CA46F7B4A3651584897B5EB99BDAAB90966D971AAB0768C96CBAA0D87EEE1DC0E8578B2A8416157BB7BE74F1D815EDFBC169D2D848AD00CED03966DA2E6BD5F98B230D26C3979EAFB099A07CD5495E623238EB46C62F62B748CD97491F0CA8C9A91FFCF617649951C6C61EFBA868E240A2B754C4C920B025BC51278E5239A7EE1F1223F4B8574AAA9E8EECA6B65356820F8290D336EF57A7E6F84280BB7179C6B919B2D89450DEE63BB4DB6AC77BEBC00D0D4407B8D6018C3D878DD74D27D3C01F555B7768859E499EF742251CE86E7ADDF7745C4C2931FC872DAE54060CB6B930F9483D0634613DF19F9AC589C39A666E00F8627B234B95BD77A88C93572FAA2CB38374414E56BFCB9FE30E55F85F476D08C6C6680468F6E23378795435E6B974BEAF4EC6FBFC49A3C0F23277C29EA4822D36A081EE3AF75438A99811AFBF54BF9DEF686F26FAB9A8618F6AD361486209CA84ECDFC3960F47C61BA603E09BC3AD5048AA4D52842C3B9A9C79B49AF43AA952A972B86C485CAFCF2DAA0D0D1050F66E4D8DE1F1732D9C88C0837A83EC78F033C762E950E25BACC1DD6B89C1D4C05728D6EB03E7435523CFDDA3AED8FBB4E131A494D11C951D88490625800E35E594924D84864DB441CF17C5A5E70E0A338D2F5774FA6DD8E3DA2478D6860D032C54A95990FDF5BEC5083552A386A45A81245EB75ADF99A1A6163DFA3729308F310C8C212322F96B08BBDA9ECB239CDE74E75D324F61CBAF7F1A40657B86E83E896706624E51B3730680C574872AF46BD84D5761105CEDCAF29ADB1DC24A1C8B74E6F762292BC03FA07CEBBAA430648BA27E9023ED7C7A2B61BBF1620514CEB508742328AEE012939543D69E0D705BC57903A4E8183286CAD8579734FE35811285CAAEC8BC0EC14F126B10022E0EEE54766B221B6682854EE9B16E53EACB6BCDC989E47190275BF19B3D894C8AF56A4D34D61CC6C078A04B70A69DB3019A5BB0D3E349DD21C101AE2B42EA29950FA164FBB86871597F2E64A84BDD281F1B3538F51F01C0E87ED962640F18DD3C429CEE89B017AD485F188A3A1803D053E7D8F22A47B6A04D558ED17BF0101EB7E1D7D0FB1A1B6082D12398F500B2F65363912B8D8D94FF8F73F1246FDD4C3E6F7C4E372842301583AE8CBD5EA185FFA685E21AF074E3C2883774534D8B449A5DCB07C46F36FFCE4F56222073806CE59EE5BFED172E5A252D214ED2642207DF742AE7A62F8D9A4EDBE70182DC277E09F6826C8DE5B103AB17A892DAC844EE7B2019881DA549200B76AAFE5B9E92711BBC36A3EEDE9B24E44AB42883E2BC7B9109B70EDA772642317B50A4D307592120485F6C1C7B29A0271D571C7DF5F0438C8B725FA98AE2147556D38A295C373B627B732333A0961A45A20EED30B4AF3A95890A12E932B1BF934754A0994154C814E114E9D671306FA257AA8D2FAC90C5920D2E20FB35C5AF0259F7F69607C29075B8DF9B7DE0C4059D62BAF1660E05EFAEED41091D3B6323E32538CAC3D88225B9C683B69C415003CBB0A770A0530F2738FB14ADFBF48459AF82D5D43C7ED0F1E2131535C6266757B9398A6CADDE9EA000621252D373C4352767A7B939EA0ABB1B20E17717E8098B5B8BCC3D3DF152A2D3855565F606682889DE2E7EB00000000000000000000000000000000000011232F3E" - }, - { - "tcId": 8, - "deferred": false, - "sk": "55FDD4E2E182AC68535720F7EE49C2C48266568EA967FEA7CD50AC62663043EA16FCBC7BECCCFD1E71594F6608124EA79CAADB039A303FD25C820B2186E801CBB5E715431F30363F908858E6927537FB74E7EF9D094790AFF50F5E88AF6139E20933274A7D4F3EEFEFBD08ECC4AB77DBCD0CCCCC17BCA0357DB699BC2424F1A99A08128B20486334062116120441525C3001E206460BA77082262A18314D63106E5AA669D12229083746129584DB30001132049CA45058046E144021982228510681C1C831A39244212162CB200CCC444A200529D23860D8288441024D44188D1B39460BB391088010091790C222491B378619384000126A5B828C24B600D1C4091C3750E39681A24031C1A28104344060C8691AB88D01150C24375260C44114274152462ED3B29124278198244920838198C250C1906D1B0788114885533890624871C01291024902D104729A26521B2012D124051B146C4C382D23465261442423C451C1388508480D14428E9B304D239330CA266A2385050192040A826819030824069061A469512845A2044841122819A9688B34664B8471A3808C844031D030460A31018B102D98A249440821018281009585D80430133288DBC04C6132820AC645CA240018384EC1048A0CC72911294940262941205202B430638090081685432689C324821A0850212149814031C8485212028404106522240810450D001830431081E4281048B850008545D188108286658C04252445044A204584863113460851260DD0260923A7911C4761103861DC226423C96492C03110B40C22B3012023648A0480A302601001509AA86050180C442270D1184DC49231DA464619438C84226293C685E2260420084E53240C5AB605CCC44110B951898628DB96216006011A4045C84448108601621461C2106904140050284AA2946123834801C64D981068118409C9C8446186445006100A26264182714138720C43091CA90851A40518418090B610CB429103B724E1800C63060022908953244D0A094962B80894208D54A46C09C09064B084002205A38689182905E12065138551214648191362989881C42428C330618C386CCC186A89A0891C246E5B489108262CD1242D6086645122855B1441DA105083006109088613868921B5480CA131A420319446408A060C480008D09029CB06255B1852C496109B442508260158B60C924229DB248504A840D4326C443080E44810C9A260DB060E91841009468C5B2249232425B4DEEA430C8E4E98CCD4D270BD4B96248155DF82B14BDADB0241D93D57742771D73368AC1C839621783F161524178734CABF900B0AFF404E4242826FF4FDA48FC5D09CF0C54110C688430DE63F1A16560D4A4F36363C00C8865616B178243B4282879D0E90576D18C4ABCFC821CCF87DD19DF99D8C341C3A7E6AD9B1D936D83EC1C2756616439D59688709FA7C6ABB3783963F1DA6A5BD3F3C391A3D50B65EAA6C1547B3C8CBD9F3D9BBF2D828E18756A35933D217682E527F68E0935BE2EA5CB8F74DBA51EB3A9BD4DE3294B962E74D76BE40ADA71B8B5D30DAFDC34490A91D1A7302097EB7C1A9B75FD018CCB0FA8FE4AA8C95261C837922A08FFCEB669D7A4C4D97F5C657080FEA40933DB7EEE691FA496D015799B72A2C6D48BFD8D43A5AC1D4035AC92860D3C58E52134179D459A9E7D34A069E99C702A7E3683AE83B6EC19C322C5D794DC1977C7F8C75C3B1477AA4553E7CCB49D17A6DC6418ABE9EBB80D1329E4471DE21D2944B4041A6DEC0B3A7C38EE411946B9FB552DEEEB4C1BA2F6279BD1DF088C3F5B24412AF02F8F28FA8BE2C5D8098C8BFE4008F53448C28420CFF19DD3B9CDE0AFFE43293EED189CFBF2CBF141EC1DF9AFB5C3678B36DFED40868C8C73D0BFA7BB6B6C6141A9226FBD5DF9D8CF485EAC66803932D2487BE19E5F48F8D34E175D0A24EEE880B4C6EAA0E093691E7A6BFC912F89AE07A4613D1A5136EDDF15A3DAB94626C36143FE16558867BD43E5EAE022011B0DFE75610CA7B6F220AEB7BA46BE1A6F1CDE340EE5C6D915AFB49223CC34D183142AB7E82A922D6669E15BA4A316B9282FB6FE5A1F310B294910B04174A955F40D82CD5517437642E91C41451051F2D063E492AF13EFB411454F90BFF85BBB8B0666233CB19C2DAD4A192AAE440344A9CA97F26D504886030BCACDFE72C87EA5785AF2BC55C54C641BFE7861ED3F5AF1F1B430B63C872FADB6C5FE4B446C4823B7AB7BCCFB20652358611DFA20466A176CEB3CE1D7336C34889A6EE4BEB96563801AE9DADAB2DA8AD03A256FF5BFCDD8BF0F65AB942678391862DF6B3EC81385DE7721B6B650C8A3B6C59CDA6B2A799383309D4176DBD7F9A91952298600349690A6FA57B02196BB2483E57907FB8C027849228B884BC33D0D0B3D49C6FFD11EE219D6379592AFF909862ABA39C0B0E4B2CE259C4C77F51E7C7833A6FAC2FF2AB30F34A54522EEB3EE52F0DD3FFC1FC3E0EB51311CA66D47C4160918BE13CE1946F27F56A0AE6B647A1AC04E1148608C4D35E60E95DD3FC887C812710920004B55027EDFD5D77396BCE2E43D696574DB561E4FF9F475609898E32650E9A18B7E22692ADEF2848E1A0B26F3990A5CE03305EB6D90228D4735F97D008AD96C019C79186B1994D8210052C432FC145D280C6F8AFA51B7D52E1F0151E266EB86CCF02144C4073FC01C32DC69234250953718CE1CAB03DD64E5AE07B3BE21BD208B5A76E2A990987AF5DF07DE6AA059DA7AD6FD1186B99223EAF0E8096EE716705D0033E8BD8172A732DB465284850B41A7C3303116AB487D03999615CF0B43AB8070364B7E0A50364947C92F48422C4EA043D33A31248D4ED643BA3314B9F42C380A1319E18BF300B3F247F334DCD78D1E917553318DCCEEC91D1CEC4A9AAA0685EAA32BE2F214F7CBEE8CD3CC60AF330187F7F688AA009D453E21FB0D1879D39C6444FBEFD02C6547BB6EF70E61F7D3F0A3337C157ABBC4CB598B8A750ECDD2DDBC1DF4CE5E1CF6F2A7657BCE25377F46CAFFB9FC0DAB2D42C590DBABD7147DBF56C619479598F62FB5DD0769AB4F915990BB524385AB946C3266C95870F199073A81B172F23F7DCA7B2A9A9B3B6EDCF5DF718340EB4C10CA61FF4FB969F736028372795EF6AF711FE9AE752231C3F9C6CC789B6DB5EF2086D91FE6A22027C83B5719DC6FC87FFB8F0113DB674F4E23B4EBC7F984136C79EF8881E0478B8EDD289237044D7FC11188C753AFE34664C680902A2066A2BF8BD48ECD2ADC23389288ACB70117EF8031D332CFEAD3ABA3B3A8C8115762AA9E8F8B46DFF5D97B6441489CD8A5F53E0FEC9A105FA7AABE36F1219469717C510F5090BAFE13506BF7E82BD30E5CAAD3D64537B047268CE62C325B89184D55B92A5788B2D09C1E7F9B7E1D5708A0C2D47FF9C79CDDB958F7AB25FADB4078B1E4C45093B8674E1E605DCAD367D2CB72D7009B9FCA95C55B91081F0A689D7CC3A7616BCEB070D49DC25AAB7F7F53C0CEE24E12F97327DD511B21DCFC004B123B2D8BE604D1F57A490D7B2A7A6E3CC3270D41DA5E2C02FC1920BCA7F1C2689D20C4F0310081E3B3D7BA8D67489E00A285561", - "message": "E742D452F392CD3CE405908EB380CB0225A4725065AFCB0C91C5E4823471376E6424AB24D57FC4265B24DEF6CA73E28FE20468B6E26BCC9267AAD2B7B82960C3FB5A01960FAE078D5A54BB324232B6647C9DAB943533C865BABBD3DC0D1E7A1756212980D75F2C8E999DE9ABD1874E3A86DFD53340B6E424DAD9F53C3CA02B44FF8DB9906D3D4352D0EC4B1A57A33FAFF7107D38637AA410B196BD1BB1FD7AE4B7414E1037454A031839AEE4C796BA98F4A739B785E3854E9EF0D5B7415C8B7ED012B0123C335730C7021CE8C94200874EFE783D7C4BF768538A448E76120635217727C81D08976CE4B5027D4BD9D9E27E4BCA4791ADF6F8DACD1BD3A03BE5CA7F68C2A2247FD3184609EB7243D2366E5EE4C95CDD869DE41A4B47F021DE76CF27464F814837C648A7A7CE2F91104322BE3CB1160A0D10CFE90ADAEBC87BBF14387C8387F4F5AA10FBD469ED5587EEF537106CE0F3AF4CABCD4476F248C21D119523B680067B332A1CA4C657B9DE1360FD23ADE58C5538EFFC8902281FC7B5C12C22CC69E7EB18E5F6F8352B9E4935D06C96BAFD834934618D9E6B1F60292352D064A0EEAE80F7B721312FC1B6C58D68A96351431A8626CC117BE9DFA33A1625BAECF12CB1DE33BEDAD584A91546DC767D0E59764FDE3FC29052CCE23ED28CA5DA4507933C0A7702D9A1225A48B71FDE5D27B12FDFF16AC2802E3629E10D5FFC2FCC6135243A9E2F3E3867BAA0C0F0C77BAEEF9DCFBC723C7A2BCEDA39B53B415BC21A397F9A8C4DC580EC512DE4EE4E0870DF1C4FBABF4906E0CFB08863AF2A89949F8E0FF9385ACA3F588E05781C49DC563EE9E0C5D6FA512932B7F5568C1E0FF1C9492ECAA5465ABFE125B511723998C4071481BF1C53DECD59B440931AAC640D9F78B1B40EE46AC0A8FD18B4C8AADD734B0F03F02CAF6A7BFE3DAF100703BDFADA7DBB50ACE3D40A05AE6E87CEDC0B08C44796D7A63E8B5BC95D97E3EF706E1684E791D3B3A2BAE1E7A92FB70A33D896219E80751A41E16B506FF266C4BCB4346578BAA7732CA745BCB01988AADBCBBCC45C9FA3A5D38F3F8E04005AE777910032D992D5EF9DF2C0422548A980707050CAD9DE56BCE60EF74EAA4465EDE96B055999F81A2C9596A2B35C8AB3CBDDE9D26AED44527DEB9A2AF3BF6A853FA51DCCD913876A43DA3E0E2C5B42571101B7B930840B0AB64419E1043CF56AA3C2FEF5B39CB582971A5776F8FA9696CD9F67E9290E483E9BD1698E961E849A513608C3F20FF678EBE0C778C2A6DC1FD3AFFF89D646A1AB85F005AA14A0635E92191CD41A6A46CC283D2FCABACD2FA07B7E2FF97D17B36E0B222D39DC1EB61BAB8146F147579D02A87DA08AB4ACCEB32AE1C8CBBB0EE0D90A642BB76DEF4AC8C7E477888159824349EB075DF0BED236DA9B2826E67EFF220AC84AC99BE6EEB0DA904887E3A84E5208AF49BB31EAA1552EC79E5BA02458106B5A31D0AC8AF392A63947911400FE78F6C94B3F8E6B7C3B98F6548E7894EA22215C87E121441C53EED726AE26394C825517EF8A477A6DF33B5315C8DEE16ACCE76ECA60835390E65392B9FC5EB88EADBF336FE361D190ECBD0B35B22A6FE6A8D48466B5E70BB6C5FA515CD8672BFE70054038C5893E514E23B16C39198B37B06B21275C2994EDF7F9F921B320B39E29444E3D621F52C9FCE19049D403AFBF1C047C8B065543BF43A25817533A33DE6C866FE9D8A73B2CF7277CA0E8D78F4F104C5CE6FE2025992E26E49D4C49F0798278216453C00C78EA7BAC2BEE71E5273FA46044B4B5578EEBC2A9E42025A8A3526B11CEFFCFF47191109C56AE105CD70A04C3F4EC43E49346203347319D8986D15B3C4A49F02C02994D8798499DAF1E0ADB81A9AC79FE8EB55ABE2BD18EBE18A9E5F35D2F66B38CAD6F6EEBD29AEE054C05D6F0B5326CC5B86BB0FC7CDA720838593238A2FB24E0CC36DB193FB7FA66573B064497F771DB1D965953477FC28989AEA2CC004640524A6DE8270E8A5B12BFF87B3F63FBB7DA25337EE34E6E4EB45DE9A39BC9B95ED37A6A404ED2970F9C79A7C2953420732C496B855F19BBBC8ABCBABE1D26D5BA828EB060D7280046AB93979E0BF90B6F1C07CA70833BEC83DB41684F1842A23417B3BBA0A33D7AF7BAEEC14C9C96FDF30BD201C05AEC6D3D2F539D511FBB356DDF333409EC16411DC7255DF0791BD67892880A4DB082684BBCA8B7E55B421C17DF3B68720E907C1620B142C3382AE6E738F8943CD214A847A6439A682D62CF0AE8961B5F020E7126C5DD6258CA0E8F5711E5472A4C05ADFA9A6B8180B741F382090CD1C781F7CC7F23E041800F42B228C351AA21E4D916BA5D9C56CF8E9507065D729B7C3653A8BB062C0463BF0B97F13A1016BE4851F5A489081A2AB3D2AC2744008BA734ED38DA10F372D97EA0C278C709A23ABD4B07E91ACF6A6F2DB9AF7806820381845FFBDC4BD30A503A0F74F37748E3624BB2AA478210072FCA83AD1A43ACE9F2943AC1AB6CEDED67938AF921FF34F2DAD4F224EF7498BC450A67CA383A9DDA333073286A22B85570A11FE03F55119794BBE8B81EDF1966BCA5E363C15E8E8673C94E3396C9AEC28D110408DA5561296E2928C6C111A4826309F119E5456675AAF935A17E80C0BD82A9CAC2627D6FAEBEC9A928D33980A86ACDB35686306B57D466864A0320F21751FB0041BA0F4F1660774A519D3ADB304438C1709711B982EA84D1B193D026081A4663AE69C5E12C3E4A683FB356DCA618191B29290C5DB4AA6A069C3B8D61C8B7FDA779E1F34A5F62EB7DF5C563ECF1200D3FF499DD06C2BF44A2B4254318BC402EA3A047FDB3570EB40630CF1DF84D1E2BDF5449A1F65A9DEF76954B5814691C4C12BEB10A1C006189968F37A4B236D9EE0D39AC340852EC54AA64FE15E1A4433ED48153D23B2B648C8852F3E3AE485474AB2DFD58A7F0CE6691ED36818DEADC8973E6ED06AB841B0A915425D7B87E41E1E68B00BE2EB725C287FE575736F6E1AD2AAC61F02A3A00ABEB2C0FCDB35564E8446C776E980636D5D61740AB2F0736A021D82C1D66864E5DFA98C4648CFBD9C7AA865F6C97038656C9C8767898FB43B0919BC98C1D0F6FA4D90F711E5D009D4C8FD8A773B7C73CEA654A2CD52A276C6CB62265294869A052FA1634D3EDEBA1F69DA09F0568F9D2F6C511F6BD6169BA0DE25F09FFF63AED2FDD0F6D89BD01FC5B088D3EE5344FCCC0215B6436987D6167A0F2D5EA47A984DC86D45534BAF35129488F3BC2D05BFFB84A51A87A1774033244277D0F2B45EA43500F4034081711CAD67BAA9CB0A58E1D01013032EDD5EBC7095D4BCCBD28A5F32BEB685F7901BA7A839650023B0C908FF33B37D038162FB96EBA35C2919560267EE5A94035825938D168481D8E59813E20DD611E4E23D8D42C9DE1D2398CE3CCB3DE5CBC4BB16D555985F411EB5B56508C6F4E75621304DBA2F4F1A2D8B2BEC5793478E5AA0DAE6F52C43253FE7BC91D3FBA84F8525D002CC307CAFA20BF198BD8F28CB579960A1168A1D26340C8E26CEF1261F23E97B806E9F27BB51F16102527721BE0E8B930A1ACC38F0A63EA1F3FBCEA1031E441FEF4D3746EAA37B7D4F8AB354D5F079E56FF4446333C8B8B7B589CB36DF40EBC5A75D2237F3FB874E7E0FF1B96DE43BCF229DE1FED3FB6D01752B3271E1F98D4134114911BFAC8351E3186E90DA3DE2E7FBBD305C822FE6F06ED1D4774D7A66DCA0CBF740DC277C62FA641ECAFBCBE359A28FEC48D62E1D3B6215392C0F8DB601E35A6CBD978567E806168A9F5B4915A80DE405038C4A370D898ED6441F727985037A040163F14DA78378931D3B96BA486958AE8902C98BE75BD0AED53CFB609923C63615917EF0BC6D07CD183192DE3854133F701B9D4B499F958064ADAABF4080C4A019DF1E5B98C8CA265E031B8CEC355C8FFC3BE16DC3D01533ED17C9769365D023CE7F0384D40F7B6179612B5EC382982E244E2510B4831F2D53F26B142A33877961EF1F845370CE115CA5F0D2FD6926482BF3BA1AEF3212DDF36705A210D8076A4428C7F9CAC411DE590452C761028469947BEC31ADCBA229D8EA58755F2715AF6D51E581D2CAC4182557E6815BFBB84BDC54C9368764CC29AA9AB49EEC37364F85AEB3295E60CE6DB2639669F55CC49D7934BC8566AB5E207B33F29128868BCBC1DBDE1089317088EA3FE1D595376DAD3BDD156802F82B63CF4C5ADEF9A89D94493BA152F9F07A9E9CBF8D821F1D6CD602EC49B61AC4F7633EC810F3D01D4867B1F0F3021D70897593303CFA6B5A3BD0303AEC32105F854C3DBED373760DDEC9B9E8EC4AFDAD00FF2E5A05A0113522024B86F1AEE6F250AE3BF0AF1E6FB7DFA8E04E3F9D5C876731D9C33460FDC13CDCDD433B45A6BF17E98638C264DEDAC262BB03714E020F4576DCA85DFEEBD6D70E557DF9321A8AAC519C419CA20E33DA37C22047D4CF925AD67545D04300A42B22DAC098A912848302D830E06CE5BACCACEB6E9316F9B1DEEE271BC6AD9D74927CAE725CCAD0C596653731869E8071E23BF", - "signature": "39F0B36E2780F8D81EE231CF85B28930B0876F344B4EA32F8CEF086931EE1E6B9382AA19FB650AC81A2BFF86453BEFB33BF8F0FD8E0FDA5737D7C56E4D9427BD1E802930F500594396F98A2C574073FD570D30666F5C067EAA3C88610A52FB0F6826CD12BCE739EB685B3800B3B4E3833DD2886CBF4587CF0704B2E72B128E43183F5A5613E8A5342C123AA38FEDD3AAC513432A96AEAA598AB9DA0789B440A4F4AE37EC090144670E8E876D83A39E0569A1F38159B8128317216ABAE8C5988A396F2964B6BAC4521E1E35B4C1BE3A4AD1745F718A1C74B260F462567146394C5190A3B6F724BE2804C3E8BB3FE3587B09F22F3227A2E69B651F52A32F62693E212B502A5F7917D17BEBF20BB261D554C966418273C6BDFC51C8947BE2704116BFB1D1657D5D82E676DDE05A580F048F7E111A3D632205FA52911721CB22F937E6241E1248F1A6E10A71C34932DB75A4878BEDF3EA3E6EF5508E5CD691114192DD4C44E6620EABF1DEE4D09448680D84C6117773D240DDACE06A2D925920F61A0AF12B6E64DB0FEEB2274EA1238E22BE017579792F2EF95BB55F6A23D18CCE1D3AD209B6463370CFF1F8278E779A9A943B5779A99C971F8A3794CDB3B04773C9875D82D9B72C39368B1FD4FB0A661BCD31821ABDCF4CAFEE9FD959285FF15B9FF8211619638EF4EFA138E44E4EA9F1FADB550C13EAEE9828A34BA911D4027F38FC0B9D0A1E788A6B8648C63A9E4D6AF974F87170333BF82233C199598D7A7CA1F90816CFC72621DC36FE881F25BB86C67B9B59DBB02D78A1ED003193ABB5470A89C8F958FAD2D6491ED121AB9A02EF470099D42FA37174052E231D4D988707567F319D964B4F0551EAC4CAB4EE069EB8FAD6BBC4A9F1D98DD8BD73A5647F64D4535E8FAE71B53902C917A9D286E014474E4B126AB17C29DE31ABBD58CEB1C12669FC2EE50042CF30BA29F08E97FBEBB6059A458A90EA6613C7F76A5AAA9DDA66D266CE0514B0B0442694252AEA4ECEA14CF5C90A8BB60FDC56F865447BF29769F49E79751E8AEDA70CD78E29154D688558D1F831096C660FAEF3EB1850DA01F2E929A6432CFE9DBD342D1CC234551D6301B6B61819CC487EACDDEA62C2CB8766E2C7066698305CA924419C8E83CB1D68527E923700EF7C5A05DDB511DF15AF11F5BCBA557C815B95001E0F57E6A7B8798133ED1AAC2819B10A8E2E4BA69606BB148881A2C23D3EE0E981551E02EB1ECE320B6BC15AD1EB0EB2FF3FEAE63DB0AB4C2F315E54F047734833CD380DCA1ED68FF1838B09495083457B07D93B8607217913D678D409C1ADCA9C7F496FCDCE029F2F4D254CDFFBA036CEB59D15BB40B4215397DA55B5480EC2DCAA221D4CED195DC440BD0B84EE2BA5108F46B7E24148EFAA6C2AA728F6CFF1391B46C36DE741C7C546A0EC22776B9830C3165D2ADA141F97C05D03D93557BDB24012C336CDACCF8CA3630064460C12251ABC89AAD06478610B8A2BAE5380E65A2C449632EF9A79CD9AD8857BECA18552DB913C0C79CAAC8AB166A1ADD7DE272A796E72EA53E23582DD8A00F554849B9EB9D77390CA41B04F6A0C9BE3C3D0E94F9E3DC39BF1AAEE34E910204DE1A2B3A92557A67089B912B676F93884D4A6411B89740953E1F79ACE3407B2252DFDDBAB75276C10EDD534A9F398E51CE9E36469C1DF0526ECDB84B07308A0D5D5C520D028A8E30A193DF746F0402D160A4E9515CEBA20655979124B1D6F5EAD8892D9F1F92A0E1A1DB0B4BB90892F569194E088E98C0C5FB93A108F05507B29A595CDA161BF4D97680D6B0D4428D6A74B016509CED3B635B02183222B79598B6342A20DF2269E881C7B121889C0751462D76C5ADB628D26359D56F8876CF14A71D330D03361F63E90C85CBB275AA78C15293EDA0356E9DE2474ECE7C49419E15ECC5EB8233DC8377D88316AE846BD464D292B91FA8B3319A28EEF4D678F0DBC04687C7C59CD98B694BB15DB7E18F4599D4F2806D0D78E80984C4136EF605FBC268221E7608ACD24004CAD8F533DC1BDE1D3CBE0605A69E828AA13210A07001D60B8EE2DF19D5AB8D792F3899C39C9AA1B82F1FDF9222264F7C3EC8B756DEF951F20D1622B23CAE013DE6CC95B0F39721FD46A64B7134A602E0D9B6B19299A5521148AB61ACBB878686C2020663EDF3652CDB93CF4E24C8FD2AF8D0167573333A7DAFA1CDE08C253D523AF9F944680B97BD7BE2196870A754894334A029A870F8FB342E53BD3F080657A4C5A2DB603C9F0F3BB341AE936A2B9356A73DA67AB54AFAE131C8FB0CB73EA10832D2094D014C01107FDC06177FC3884E7F788384E8AC89C689B2A2BCE8D6852C8B5BE520671DBD8447E4D78049E1EE50663A609DA79725A3822DC899CC87224C115D129702C7573B45ED58188D422C510381BA3C77DB099B87C028C895DDC6F60C148CB1CBC60CF56C15455048AEC096CE78B0E70F8C8F1694CEB365DB8FDA1F01897247E632B30FEA0F888EB49D5487482B367ECB413856E8630841F811BB1AF14CD26DF29DFE7238AFF1D169804445A74BA5F9F96D9EED27BA70AA516C1BE7DC46C015704E1BFB42F0CC44456CAD7FFE48B62BB8BBFFE5C97027BDDBA1E83C027DEBE20A908486A351F077E627464F6BBEA0AFE9230FACED923DD9DF215AF123D8089B467FBDEF42C4174156687ECE49D87C0F9711592D2469BA2100A5286B086C2FBF47A60B864FC9628CD1977D7D8D72B411D2494BFDBB77543DF4B39664F7B22451B8C7244008A3D24DEEED0C9CA67DAD2D56F1987313B4AD33A72CB4973B6125257BE3295682A3D0418A2251D71510F858F65840149C8335BD999C55E51181914DAF055DA97746FA5A80A7019D9424EF0087F38EF1491A3861A19C87452E05BCDAA61CF148A84507B043AE4A42FBAE9359842B0CFE70FC17DA78A754E3D7A768469C170DE3AAD692101422C00C0F8315BEF3BBDF887E75E5DF7101317CA4F8C4D365B56A63A1D833B5D79BBA1812F3659C377BF9CB4A913CFA504E0CFDD1FEA0B87BABC132F81E9A2C7FE0C6E6D8467BE84EC5E21E0A46E4759A5267E6EEE4266A4EA8718F8D40A1594CADC835306F88E2100AC444379E9EFA4B3FA0E690550CAC00EE4633687DD1FFA748DA3882ACC6CBBB2EFDC0513A25B31361DDBECF5ACB3C488AAB788E63A48D556ADD74B607CDB8DE11C7448DED000E8665EB75BE788AAB14C3E958CC969FE353C0137924941951BEE553FA392DDD5D7FBFB8A2A8DB5FB0EE58D08FB5ADF617EAC526044962C599523981AC06B60E1A6A34ED97B80949DABB6C9D6D8F1F4FB11222632456068798995B5B9E4E9F1F4F8FF10161D2B5D636E9395A1B2D0EBFB1419202A2B383A424B578592A0B4C2CCCFE9EBEE000000000000000000000000000000000C1E2C40" - }, - { - "tcId": 9, - "deferred": false, - "sk": "382FE71D7DCA3DA9138076E84FD5601E999042CBEF87ED4A8B5200087B61564E433A8E49F18104C7A7158AB1D83044AAA46F6511B361326218771C3F99094F9624AD27D16068D01BC7BBCD0B5448338C2A81FB3F83B2799A81EE2610C5534CFAF09100FEB0913F2DE35DD5C21DE040A2E8B6FD99848AF401BE6EAC45DCDAB38AE1442E88B24C2233621A187061C4606390801B272A133450042331A4300994204D11464404242051C48DA14649DB4428C0084C84304DCB8244CCA84C13B39018150DE3C04122160400A6252384511A28221B136E2049715A04222112724B4889993210E3A42C02147004B06920110918352EC8B681614400E320324124321CB47083C60D0B970451B8101A3268E2A84951C06C20926824B448C9902922122101252C13B70099B02519A6410AA049149069089751C8006A1A233142168A620428D3C6900BA544A234251484605C48324B384E19296661286450A409DA162A9C10100306019088410A0006C9283020A44808C04920B78DE2886809A64C1A030ADA180DC1088962384D61842C91180D61A649033672C2A24DC2B02449260540006948226512C50C08C36D54224D244368418230D3402114285050366C4A446D989604CA90605A162ED2422241129048827013A2815C8025DC12264396499292281A042D8C800100262C93025192A288C2B29183080E12382262406D14436923112E521480A4187280304961863182224C92486C60B84808C30104280152084A1041520939664A328A99960C14430E1AB46C44C00801C60C128024A390104C0046048069E2C260D2360EC9C82963962D53C870203311021568E3222453466C410891E0883008266E5B386510A991A1B88454888152444118A81093004581122C10224E1BC909C04406A4A00414C401DC0286CBC645CBB889800885244945100871990804CB382512359244067011406550483240A009E0C20020244D82A20C81360514460E21C1494A442D9B343120C85004256502B59084B445542489C4A224122225643862D8B02584A005024828E1C625E03462E19221E03452DAC2219B38311C113293C80D612466C4024DC8026E240582630248D1140A51342960A82C2093891B496C519010E102654CB0251C096C4B18860B35421829658028696080296012250A417081222990A00950C041C0884448804D1A182820A82C22806D099501088670C9120803272DDB208C1BC92C62128ED98681CB067010C7498B386D9C8005F34E25F7A1DA3F630CCC7317F25ECDDF9ED98A9E07707DED49B04D35168D0ACD1EC48A4A92EE0A9B2AB5B84F7F3FD38F399E54FE65FE2EA64CDB121AEEB6EBA1C0D52580543B76E82C799F8ECDCEA58DEE9CF8E24C1B08C271B805BB729C7060608B6564F93CF8DFA6FDAB6F7B6F483E81C9F35E07C061F88585B86F7DD9E62CB027AA2DAE58ACB5C095B23661FABE88C717A46223395B94A972E3CCA2FD131EF052F7C8C75EA9B93784893E354BE0E4DB252C36AD03285A7FCB33A3D53269D20EEE2C3E6C0D74C91A2F1B35510AB2E7C4D12F0C564FE96090081A76B9163DFF22815EEC4B7AF398DCAF4AC6A39D31EB3C4674F7D007D6C04C95AC37C4E62182B0448CF3D10CC25823463A9808F97640E378BDB17EC0A2972F5F70812625EABBF6F1F93B566E36D2CB3FCFDDF94B3DEFC1AB168DAC4371398DE157EFA4B1998D2E19B4E9536038DECFB279770CF87FEB7C0904DDDFCBEC1721AC33D837AC7689676033D6D556DC70CDFCE1940CE25D69A961C6BCFB4E16CF42636B5DCE6C0F736DB467C39D0E4BBD0577F3535E7A47D3A80010A5A96CCDBA9C89CDF7894C43B19EEEE86D7B248E6FE89F84D73F76DDEBEDF18BF3AB9F5D0E69BDFB35AC1AEFD64E64488711C95D132029440D3573F1DE86EA10B9CB85241735112D992319FE5C28EFD072D2808BEBB97A75607F2BD0D62CA3223819F2FF26F047A5E1283C39317C1244CB95CA3C91C752DA2B1B36D185FF6B6FA6E779860DF82DF8450A2B131459E5C437B0FC44E49A9C613F8CCFFA188850E520E166F73BE0F978C8E770E88312F8DEB9FC4F93962AE579B2371484A6A7E09C68DAF0E00DE46749AB332791745294C3AD193FBC533E56A723D230BA35DCD4308728014FA998C4036066238B50D5A4381A1E46BB6CC2EB3C4AE4A43BA3712462D7A842598A1E5A7076320194C57BADC732197DF4A8A1E9455201AF865FCCAA674E2B427F7B3D35F9E66D1FB56CC690D61C7EAB983D3F31EE3066D0CAF61455B185902DB44CD2A85D6BA2D4B97DB516AE75CAFC855829E24160ABA921528CE718E10023D84EDAB83D42CA84E4E3B078218C44BFBA356F1815F927D61F2EF8C46C4B5521D0F8971D54E81BEE1FBE150F3B303D8668C9328B61D68ADF26AE20B4A38C4A0DD62A5B432ED1A3DB945003FFFD37870B5A514FED603B5EC54668FFD29D6DCB5A593DE0852CBBE4376B161BD7FCD8CCB8F60D453B68510E5705549E25149A1271A8093F6084759F47AA3B5D32ADAE32173B7B0DB4DEFF645D172BB02F5D2BB776906E1118167F3DCF7CB8C0AE2866344A59A9F6C3687CA3ECF74884E632CD63B6AA193DC56E087A67782B69699525C53A35DAB992F9BAB1CB098723BA2F1027E72BD20076AECCCA2BCEF8EE76ACD195380A34B934B44E642BAE00DA4C1ABF7174CF0C0A353F96F27CCC2B6281B7CBB29222E9F7067646F0D915AF86F90ECB3E9AF2B1D7FA2A233A5EC015C6268981942E0DB8E1F3667DBCE020907148E61B353D505A3077626E56B8FB108D90A5922E5259387CDCC49D03D1D47E3CEBE87A752C7562C219C25F502A8716722EF7CC7B4AF8C33DB33EFCF2B31A076DEB28A410B8162A9D3F1042E1AFCD5A9DA472393CEE28810C853DCD94F5590F2F5D9888ACDDF1FC78DC26221CFEB3EBA97D0AC4B2B2CABE0BA52E6D7BC29738837B7DFE5A2236AE31CF61A449186080519DE388F1211F6BC81663D2AC7A4BFAE83E9E64BE6EA7DAFCFA7C1DEEF73DC6F9F9714626B9F67F292DA66D19B6A5CB4DEF0E870AD09CADEE4DF12C873722521D191EDAB644CE9EF6AD93CBC951B8AE64F741B6497645E92A916605137CF73C5E30CCBAE5DBDECAF908C16543310C592529819C926885DD3C8DE66480FAF7DB079BAFB47BB99341EB9091AB9E9A0CA721A8144882154C3D4DF29427042F41810DF2BB8D59C5FCE38468AA8328A740068843F7E2C911990C9B2CC9C8E3597F03502ED2813587980918E69D4C482F040A8B7A09733BAB73E581E7DE74899A5EC59369EC1C112EEE0073E1320B189058ECF06DA8E1B74A7F4FAB3C77E2CB93066DA683BF9C6DBDF4E673F11F446DB7AADDCABCCB6AD68BFE43F5AB8EAA5F8C737AB144E33ADA994E5F38E1184A4CF2EF21734DB0CE019F114D02316703CC86BC12550C1CFB863C1249D9624591ABC9661DA47E2972231378F57D27F5C1A6B0ED2303DBCF69A8E98C6317929C6B092E1C0973AE4DEC65C3F3B59EBF6AFAA60C5121500EE6B4027480BBDFABBAD8FBA8ACF4A23AFDF667EF95B6B60DCA6A39C688BADB1DE6F3795DB7D4D31E882D001087E81A0B7846C7D0B383D6E85DD516E37409", - "message": "7EBAAFA6D04129716131907EAD0832AD490D09E97D865B4AFC5D6B0FFF4EDE6A52E961ED88DB60A325AFF2675DFCD6A87984884AFB8680DFA7378130E44F205398ED7B83B1AC32D2580570FD6603827E8E4F5E20A27758CE6D1299BAADB8A895AD586BDF7B64F8D7A52BC15455EEF240F22FE98CE4CEAC03CDF7E8A983D7FD1A59C5EC594474AE77DC43EE4E7B25C556BC1D91ABD2015B99B1AF5329DCD41B93793D791A44AF5D83DABB8E40675EB32120C57D9E6B7757D3E03008A2F788336B8355AD2E47E61B39BBFC2229D53BC9BA514BB20F3F9EE9266BC0015FE81980FDE5637B3018046DD3D4BC3D549EC394E190F1BB788619CFFF86C532B4B9F0F6F951C0ED691C59AB0CC438290E9D6FEC9E75BA4FDF12D2BED2CD988AC411310BFECBDAC48A61099CE0D0CE4B44EC9C97108A44E5C5EEC1D3154B4E72B8397CDB0F7D15AA358076E25B7F3EA1E6E80A214051C440EC4189137610450144641B1E71B5334F0DDCE9D5CA30274E0237E45B4D92D7D458ED9142CC23871E56411382CE40D9CA4358B417261C2E7E845637FD2E9B4357E7EA5F4A8076A7C2F40FF1F8AFABA5393512F690EABEBFB73811B974E57C2D473AC22E747A0EDD39E99FD6E5D3668F3DCA1C795CE27D1A155ED9595EAF9061CAF5C55F3EE97056AF6ED90E05D41E90926F69044746230C990118E4D0BE4C12F7A4AA0464F8FFA7CF64C07FEF171B2E43A917AAC2880675F929583E9040BA6FEEC8262002613AA91A2B8D4DBC1D36F23FA9248A2D3ADB1DC5AD669EA219D35DB17C9C25095AD7673445E59DA6CB2260C8FA57639D6BEC8AEE307BD9C96EEF00C93318DF7DFEED970DC1F61AC5C94D4086300D91199C90C95C1A24F7F1E4292A60AB67F30BA990D58C71002D3548A412276DBEF3984FAB312723880ED479080EEE2B636ADC75AD4423A6E0C5CEB7EDE528F871FAF21855C3164469B9EEB47B6D37CFE4222DCD0B9867B00BEE12C27590DD77C24FE640DDD34E9138E70D15F52E94F3874447CA5CEB48573ACFECA3554E2B76CEE4E31060BF132CED8AB953F0A280F7916810A107AB5BA66047FFF0003B1CF13BFEB77526265B98E54E76B891A89F3AC0ECDF71406674865A0936BC57F87B64424BFC8FDC41E471D951077C32B5AF960457E97CA05F3C378D94B60A9735E9EDCAA96E413FA391AA687FD07D9D021B1014CDF241E5460DB08D3B336DEB4CF0AACEA57E4DC6C464F698CFC2AD10CA72C102A25787E0B89249F63406A39A2A792B2DE04710C41DB36B55D2FA789004E593DECE9865771D8B16B5436A792FBAC9934852B1F55D518F9A07CFA56BCF488D61AE355D63BDC27DDED6A56154B8BA3AFA3EC9C01D6593C83C315527F5FC61BB169723346AB4075D09701789268EC1F02EC4A1CD8A5F2584E29F126B1ACBEEF660CBEF16A8E9FF9C0B542042EA76684F9D70F2E3F3C18606ADCB1D695112B129B301008EDD5E6121A8948E1165D350FF09647DCCF4A1F8605ACC750A0AA8319A6685153A7672B31A3DE785EB22E1D223D6271282AC18AEC83C760190799F082D7FB0F238F627271BE62AE5A36A34D65B5DEEAA12D6B14B59BD0C619D8D9A44238AEF1FF83C30118039E834F7716CD59E138E2ABEC2921D9FA92F6808A760031B2157103FD2EAE988AD6CA4F350F488261409FE91B5667A9A2EF1E226B8BFEDDEDB84ECF993E9A71220E0253D2C4B918C5521C7953FDFA00D50A32879FC0A68D2AAD13EE181DD47DB9E3D715574CB3D566BDF30209297B01A666DD7DBC5464F913599086AA2FC6C8541592CEFFA067B287EEDBF4C9B9D6CB23CE1DEED628935CB2D6B5CEFF3BC442B2BCBBEFE4AECFC455A3A64FA117CFD9289FC27E6289750005877DBF64CD562E2E7D1C99830F5AE63C70685B3898D420862A8C4569F2CFDF564EEF4F94FC34CDFEDED8854855F3A4E52C612258DB5EE4D702BBA98B450D070264FF86A440129DA2C126978DAB3341C4079A66F9C23445C5938FA799E78F157656208BA7C7BC7F936AF49D11148856BA55910A6A736D32E0974E50BFA608975E37AC0601FDA7551204EA66F524DD03F44F5DA28EED5D126C32794F1CCE747DC1E9B1FE287CA607F81FE7C795C96569E66B2F3413DA810035D472B7F5AF74F9CC70306A8EC36F1383617D0FFD92F6DEFA7EFE91C840EDF24430B197802979752FD55A8CA85FD8D4FCE774F1CCC540F77C02E16F1494DF170CD8BA57A86BFB086349D53E8A62E1DBDE03369757EADB0E985A038B31DCBEF513D4FF9A3BA6E8338EDCECA7C3E9417F9E133BC399F2EC0C72E60E809F79D55FE1A917CBE28FEF19D6D08A43F74DF496EA9305072C90AE3BA0D21A1AC0BF040920D3F5B8703C12A32A6864382E9CEE8D00CF4F93830623E76197F7F52309824B08B8E0D5DAF5662A36981D50880FD3A8D73D24430A1CB201A9D0BDE656593B37B8EC47F235B5CA251249A04507DDB81F8E5E4E5E414B3750AB168BA51A8873E6ED153E302F61F7159B658E316D6D183575D87ECA30185CF72C67543CDB658AA07B1DB220032DF80D287E769E3253C80F43570AA538EEF49F45316E176F1F9411F3C085257C6B8C708DA7B924B792389A7EC34C7F778E6100333E8B9FAE75A4D1A32E306AEE36D29FC6823399FF37CDD0D11C8D03F14740342B736C4EFB5302C141A86C857309A70BD74DB6C7C29C839F8D86F2A136F67A0FB3A3749542A9DD8D4A062672C75B67D3BDC3FA6B56F3E79008AEF8D8E04CC7781B23D0DAED64CFD1A91DBBAA2C9C4E765FE2FDFE6E8533848E51FA027B86AB05A0530F15C1B7B6BBB268F09A7865E202B1645F8B4267CB1A49A2929410823AA9B834101E9EFFEAAF6E406639AF7D2710E60A84B6205339B0719E05BC6724FC2892A017AF86D80D361A7FEE8C284CB84F5F09B90CAADD49CFD396E6AC36052F5CCC8E7667CC762A9F173F837A231D57584A3BB19671B8B71907E415A1672475ADFA11998F94F28B00903AC551E651A3F9485DC0ABA3297E561E0B5A5786BAD9EC8169CBD706AFA60AE764BFE01EC514623BAC6C4100F707C5E8A02F4B0D6265502AE4170AC3EF95B49ED1A2BAEF56F63D5667C9FC0AF4C0A8648FB6AC5444EC8A1FAF4715027AC9F5987735D1AF7C55AF4C838FE9FC84FF71F929758DD52E2BD4A34237350642C0E641B6710A66C9C1EA1D9BDA80198FCC56D45D67C3511BAC0971AC9B6166633B1713A969B8DBC3CF60FCD6998137AD713EA3ADA84169D49FBB7F5CDE362ABEB0B71D022D9ACE7FF48C9EC1A7E0C72B564FD2C620272A482941443838D0506E2294B760AC9DED5404D3C4D2898315D3E3A82D2E944D537817B9901AFEC343B95F2844CDC4AAC3836E7713739F4201B95C42FB7C99AF8667628C1B60115BCB185754148B3C7226DF14B6DE1AB4C6043329B176C9DB9B1D73B3814FEB89E84A4C91C84993752B7AD30CC707A71339E8A277A5586BA85CD090F799A6B75523A62C6DF1549D787BD8722D1F26BC2C150D6A38951F3014B83DE665B21F5D9D97F2237333CC10A4114796D56D13D643364306E7445F475729602A11F8BEB002BDDF30E579E26F2BE4AE87DC666974E24FEF2462120B6CD8E79D65A2E80542A9240D4EE1F616326AA528E2A1282EF49F0312174B67D40FFCB1370BAC5D1444D75FBFFB6B0887F4573A8C4622082E1FE349B2C73CDC92592F684769FA7D7CE6FB5AEADF38023E51DA4EE3EDB10368442B218919341FAFB22EE80DA96A52434B184D499A4C49317C62F6D6DC9EC1413D01A1CC3DC8853444E52718798EA158A12B72AF023079E5E76F41AE685494E947618C4AB3036ECDC74F7A043230A0BE116F2B617818A2C94C54CFAC964C73BEF969591A3CB2B7DC9CFAC7B4F9B64AB70BD7FAEC138E42908BC90D6ADFFBC88EF473CA8CE7BC960C4B3EFFCAB92E8259CFAFA85EDB7832B3E630D6D2CF031B8CB570E38C101A56B426C654464228D152ABCC6DEB888DFFD7FFDA974E60CCC2AF7531F38A813E263D9B20DCCB50229E7D8F379F81A280CEB90B64BA3657F1E50381B468D0A6608A4B5E107C4736FB4CAA10FF3045C05453EE12A9FB0B79845E077803C69CDCBF7CCF7D6FE6067ED152F67023CAA6095D1748414580232007AB3426FB2889E1BCDDDBA539A2D79CA523A2CD1B1314C87502909DA849BA9B11F9104772BBA27410018348832B0BFDA4F09AF02B351927F2B6D29D9CA9F330266EC035908C9D4023CDF2343B177F57903D37AB89D0F9E23EB0C4100BC6421235CE5FF2729C2ADCAC24D1151757D8C6D6DE53DEBC38FE866142D1BB593974F4D3198C03DE4625F41BE3D488575B25007C2D5970BB152BC1C23E48A88036C070BD38604C5844E4205F1EF3D7FAC0B4B9FB51F229BA322D3355E458C27685130FCBDF591C0520626E5703A2E85871A62AF0CF2DA3468C401644656CCAB33B2402074C59A0EBB57928F548B5FA4871A8B2AF0BFD9A871A5C257044C17E4967B70D0DFB59F1345526FE59B4BD92A1C06B15E3A6226A4821FD614D8DF612A3D2DDB2DB67BAA3878C68C16645CC747BA9B366677541171A9264B89EE18D9D169D341629393C5526C28B24CD4CFCACEA9C42DB2B1CAFD7F906FC17CCE16612B1261E62E2A700CE74DE73174D3A1E06AA31AA05044EC324F026CD39F7B13399D9D86EEB53A6DE84914719EE31AFFEB630F3D8F08B4FFB10016209C13BA2158ECCB4B74BF04EFA73222554FF5EC49709F7F8DC1D40005E91245F3A5E2A00B9F64678B2D8A9E6BF1D011900D9D12F7F3BB023D1E5985BF78F8D6132AF5C0B9C330F361EDE00473DC9EE7469478FEC02670E8659B643B92C5546C32FE7B0AD816A5080B5E3867DC209EA15AEB4B14E42AD58F34CED65ECB3B519A54BC25117EF8D392A85C2895B5A4B73CF93077E360A828570FFA02ABA84D6534F3EE0C935D97D1D1CFABBC0D82E48937797FAB31704588605082A950CAA23D6569AB793FDC31BBA561E729E80979DAB84ACD4EE6B2CFE06D2EE8C4183D33B9F894C6865D9CD405C7665E0150B2B649159BE684839BD12CF0091614E1F821046238DC9F538F769FCE51E9B8DEC0E98442CABD3A4296F1D4331A16D33CA356B11E3DC13937F814D3D6281A746F054606DC52B737AA40422471139867624CC8E9C559BD25C7C6D7F902677A84BA63E8CB817820048C1C0ADB6288000EF2163B51ADD4D758D1C87FFD574354B41CA5AC72228A7E9E9E75BE9DB18FED47C32E3C561C972A67D50A560017BE794AB9BB6B50CFC43D2F6D57E8D73CAD6227C896BCD18E0D7087F57C365FB9EBF5864DFA4A13B6B5DD7FFFCB648C1E1FE40B6A10EC0C45C74504CF2105AD443DFAD1E306F720B9CC37B4A30198D3123FA9FB2A7A9DB3BDD98D441B03E0EE6A8180989E76CBC71B0E8607C3A9E5D20B6008B010702FC5D59847AFCE122F3FD4FB5D89D3A3331AEFB96B593F724C04885B574A43B5EAC70B543BD191BB818768C67A10AD6E2D62AA4C65FA373A19116AD86A4F9A97064E0C0BF80106DE6654B4A3945983B7DDF3AAF1E14A04F6D3035542B0F710352AFC20FEC78B61D8548B9669F10B3D6E531AD07A84C493264DD49759D95A6AFDBEA5AED1C7D7D2AE6D2FB6747151CB6A5C2F9C1AF5CEDBD9CDE8D5993ACF080A0008BABC759A9DF035C648609E610F226ED128E2656A057862246B65C70774B68F54D68073393B85110285FB463DFE394D9DA0AE85985FD6882EF5B11FAEF2BAC18F9D9D9B5CBF0F80AE7AC4418EA658D68B14BAC135452DF271DD3348BC338BC6C789ED95D5C5625762E4CAC6514866613E6D533AB9814B7C337260BF16716478401689F4079644DF4F734281C16164D19C4ABA20ACCCDC517EF42C19A5B1CAA4658C27B61902ABF88EFF0795D2C971608B0570E016CA0568CCA3F7B38FD3DF5608154A33C1F0D70C2AD0EBB134A8F475A8BBEC8408D3B9B0BFE8A6F10FD6C979B13C3EC73F191B788A79B4D07AC45172950689584C909247DC8A4CDD686186DEA16676851B8A7C311439149B1A963B0CC60E5395B56ADF27C25A51BB4A2FB19E14CE66B6D11781E89B3EC22CB854A12D46970D1A009AAD071C479D9C731770D666CDF0BCC381A3D328542F6371FC6F5FF7C4D3BB06186C048B2A3774EAAA3CCBA1342927B498F2195213326C9E393153BC8846AFE2120B8FF4A455B59AF6E65BC0CE9CA3502BE73D74B6CD12A760A9E0E0D26BD105FD993DD879539CD666CF2025DACD481A122627594CAD7C4FE30948412C1C6A160C358E16B6B67653418A22321DF5B1A9EA0DFC3C82DE3B8CB0F48EEFA7DD6188023D1B8B7632270E63AA38873A2C4472F9EF1E8DA56D5328C00548DDC4D9FD79115C5F6168AA98099BA1AAD606FB92F8D253C9A55773E5629E84350F3BC3B00D803E83CC2516C6C29476018ACFF2ACF61584A175E67EB8952885772E6C2D7F9C2B79C8B2F2A77C73C8B0230F080DE716B2A13DBA5FDC8648F17573A2898E72B8850997B6085F98523F00516DC7A90B9C2701BDDFE505A6C330D1118AFABC731A1DEAB813AA0E17708122C0069FB61A02FF6D5EFDA990A23E1D42C520CF1975FF06F123E1AC0B0A86FE666F8843C406F5F1E1A36FBB7A0B41CC641EB49416D6F0AB03CAA6AC0CE3A3DD1977B4D16EA33CF75A37A6092003D097D0ED8FAEE89F761B40F7E600FD502887AD90BE4BA311B9F4CD9D348DF230A2EACBA3FC356B506ED8C357E228970A948FC4983AC3ED9C3ACC22FBFF56783A73231F7E0B91DFED20E754ACE7DDDDDCEFCCF3ACC76554C269D634DC228B38C284AA35C00487D7873C8CFE8E8657726FA845863719FCE5A9E32406E2191B791F76DA035A4C862176040DA9AC0F37E66FB84DF89CAAAE9D8804824725FEDB95E5380DC66CC72BBCA1E131E6B785EA2B2B4A05BDAE01B22C3D47CA85092802A8EAC42E963A62307476FCF94ED7EBE5538A8C6F28A6C65914CF48299D3BA2B89B3008D29CD874B79A72AB840815827566E50627C2C332B1BC60060BF2FDA320FB040FD14D52CA59B24E325B5783BA1BDA3B27415C9DBDAA01562466322706CDCD0307C3305DB08D2663C57F6D3307E1C73832F8CA712402C7402EFEE0F1BD77CDA08F5F6582540D34F1B2809F84EB2F540558EF9ED46D5C636C45856AE57FD9E4650359635BE72028D1CD37CD876E0DC598E360CAA1DCD1F9F2BB4CA27CDE012980080E91B1C7376622907BA6674F1EB9E80148E6A959EC74950A2B934D42B84D739F1DA528F5C6E1C90A238E5167041D4E9AE5352B74C89DAE368778A90170461ECC0D6B6C6C53CE36745A72F79AAA1C82D494BD89D719800A89127BC3FD55247C1A29FB8387F1E3576E0C45F4D327C0B24A75FE25EC6147C890F25E50AB3C43B94F451E5B5D67F8D3BAAAEA1FE211FCE8622600400F73C1398459EA7FC59D02582C2806D01023D84BB50E99AE9ACC217B7223EDAD956FE155152E7F35B2AEE1535885EC048C6E0C50D395B0F1C9D767048E9D2DA7F15BDE192C923F1C74ACE06600628602D1B0189FCADE0873880EE8544AF3E29314E2B5DF87BEB5A50ED72FDC093800B12CB2F870304289A73A65D7E2384EF3A388EA9F0013B2B5C92149E2538542D95FF020A23E976A7DB3E2C9913D87D6EFF12BB51EE298F1D2CFF18FDBAEF56B70CBA35EB9273F1E58A6CD38F1E682A759FDF8D8BFF60E7CBEA948E25DF0114BEBD4AF13E4E0D4E7C9EAAC2C5F579A1AB14E7FECF9E13F20DF873F8D0E090905D32C8F8C0033F5D8E9F1B9FF17EE04FE3656EB66F5E4777B60B047DAB9BDD883EAC31A6455D1719CB475D1715CA0D12762F94AE78CF3C8EE90E55E71D0AA4EBA6216A0E81566F7813E7759BED30860BF22178407783B9A8AAC30CB4D53AF140E33A47ABD60F33EE700C323277E751E5B32B221E4B9815FDCD400DC544DF845619FD733F164937144FC3D89D8186F8B898418459811B3E66796DE51D1373B248A9B3B9609FEA374784A33989FE9F5BB26D2148F7282E09C35E13295D90BBC7795DD72CDD4955E9D148BC779AEE9C7992BB85D8EAFD102FD690F2C679CB7003FC4E182678320738361C361747F49AC6149CF4CDA4B80581844F5EE4818BF61750047C35A4B10697892A80F07E946F357574527FD2D0187873BCE78EC99062C70CB4ABB72A104A770CD7ADBD20894E7BCE2874E45302DC0BCB9645EF28136F36E7B179BD003D5DFA68A572BEEBD40EB9AC1F9228C74A788671BBF4781AA31C7F8699813F32EA8B60414C3ECB894DC7B01E50924482E5C068F0BCA79BAD9F469770FBFCB3942D1A3E54250E87B3693329479217514A8D7B734D256C5D28EF854FC3F234BC671F5225B1DCC20E590D8E5D09C07B22EF0A89A5B863C2E652CC0B1623579541C63CE9C2C4F66BC43323D7000BBF2923F5B8A76933FAF950D2172C1D90F522301D9A0C22F470EB8673CDA0A1B494FD7EE9AC1B4597B2DBC26FEE33A08CDF91E3C59BA4F93E02D010FE3F1C1FCD694F05B7A8FD32D8E7CBC2934A25C481D9C58FED7E0AF3AAB527D6DEF43D53756F0C95B2B58A426F7F61D09F4FBE55D9AF053B92818ED9FEF1CB41FB5CA23AC85B0241900F73971558116C5809F565F71333713EF5BE87B0AC95364C9FAA80DBB9EA84B5A5790D20343141093F86942817D195ED8DF4A2DFC7F7090CA3DB46A92AABEEAE2D7DD8B9110F23A89E4FA7B5A1DA27D643BB879888A2238E221E2F67D9DF58E73C46023FB7E999059D3B81FB753B2AD333207873831AE42FAD8092AA04C0E4103B1CE0DCBD6B06CC2F0AB37CD1D10EC4C83428CDEF84041D12BF9ABEA5C80050A853CC73FFF3076BEE68078737F6EF483F486215118C640790D0CFB4C6E5243691FB73B1294E0D3A494A4A538B94FDD2746193D9FEA24C1C04F5B20D2D40B638CB932C35D953A9D31260B76DA878FD52EDED058D1DEFD9CE214D14C3112FAB00B7F2DC88F7EBCF79EEB1C9C8607D6919B8D32CC8416E2B981C141198DD9884DC3927EB0192B6361AB556EB3977E5E242E5E26BA60BD42892F46F3F2DF684D0D9FB41BE42C04F0C248938AC79F110075B42181DAE62801DF76AAB50AEDABF4361C0EC597F31245B0390CE2629DB933E450E09DD39E6A1B644B0FF672B52ACE2AF52780D3F6505551F52045028C4DEE6D1C6A34BCD5E95E9DE1BCE849643BD07E0E6FAF8B27504F859D73BDFC07FD2034595AAD85A9DD9AA5B3A72346D6F3C4B21C4CFFAD8247C8CAF0DD9A708E11450502BF3C28EEEDCB0E1D32D3EF1A3F6237E34C0E4D0222F496839B7374EBB7D786973E85392AA8FF2A9901D076DD4C65635286276698DD4388F867D1ED18650FEDA9B03C80A3B5BD0AB3A62A45ABECFD55898BDAFBA58137D4BE29EEE8B3B3D1C4467B63DBA1EFEF2C81CDE7CFB101B1E65084A0E92955690C8CDE6F93E23FD79B76DB475CD24DD92A7504510F8DC3B22EBCD0288B4E479F8DD835297B196531D2DC759364306EB6780FEF31C9E34142B55988F81312B310093F77CB89C6E819A7CD3450D0790CB7B5E33A3E5E51DF05A3BFEF63320CFF072D450D71E7239AB24E4D83A8E8E501A5BDBB041219E15517B15EEE237836672A761D36D11EC973BAF65320B368906392E2689A9936752563172B3A5ADD90066E01EB394C77E40D57553B883F446C42EBB9CCB47FA56816B06AAEB62C21C8F57F926420AB7C1D5E97E73F024C259011CD585C23D30F99D22197B569D67BF5965887AECF553A9B48DCA0C418778AAD65D4843221B8217D2D61BA5A46C4F9FF5B00B78CFA8B6496007A1444503DFB8D7CDE7A63D5D7F54EE5823A33EB3A155C20F0011304068CE0385A09170606FF6895A6955C211AEF5D13BB93866C9CF00A911A4A50A59133113A9C7DC53409097808A6D0DC44A7776B41A7A43818C77CB51F3E20107F080F6682D90399853104B8F3AC4DE8521048B22BCA58B5F7B5EB3E3503F638C1FD24568F23EC8C59A3359A5C9CED0305B1B81677E20EA35F9E896E665D3CBBCB6155E1B0539A0B26BF95396DB8548124519B71BEC19A17DFD4AA2A2E134BEFDCA352B01E1255A12377D811FAED7809C9B881B24C185F1D1273F405F5BE82FED08F26E6C11D39A604E88A1EDFAC8AD3DA9FE8B1111C7E038A14CE58B9598AAE96B7BE84C153A9B26993CECB1CE931E0CBAD5F7F6C18B68E14E83A6BCFA33AD2B3A707118D56803A1E55CAC8AA93EBC47F9EFB", - "signature": "626A3DE2BEF13592E52829D91DD5CCE8E679AB2384C317DD721C3D90C9FAC0DA9E07F5F329FADB83A1C3C1A06A6351AF25496EC7FFC232D060982FE36AB460A905E7E5BA6FD1D12F17E4C4C8D34F531EF6AEFEDF5F29E4F6D24A8C9BCE0F803B47777C78840CCF9AA4BB798D7429EC8D9BC547F24A203D565A012BF17903D75F021E2FD41B8128320C274B95BE21F795F0D13F1096E59D92B85AB447ABF603DA95488C8CD4EA2DB181D9B66626168B765A6D7E922AA9F2F79631CE32A6DEFD4151C4F0EAFD26B50FE8007518280A647B8C4BBFC48B75AAE50C20E988BA863EBD36465487C72385C16DCDC5EF409911FDC9FD9F1F69236E18813D7688B64F8735805AD8FF8494DA36F42133FDE81539CFD1C430DE02ED8B88D5B0DC2F411E7192759971E4AA68E5546F14CA4E3F43ADB3070A8EAC4AD82383FCA3F8FFD6A80E1984653968EAC57BF55BC14765D91101302AEA86B3FC599C100549F80B75ACEBEA040AEB4FA0C2B4EB4803BA549E0D873D99DBFF0C8992CACD6A2300B46F5F4F61FBE05EC6B203F6386F57F49223550406F6F4CD9E31C889A9ACE17D9A846F7590F8EF0A3FBD6E4E4E3D940EF78A9B0B2975A5B442F141DB9569F993C6398AB98A4C5C5B3BFAE5D00C53AEDB5C6376A7C72387481D72AD84F96F7DC59DDEBC41D062455CE042B573F62C98C0B580AF3DCA8155841FD66736706FAD04D9A518E96C0A1C92BFCB82A78A696ADC70A518B25DDB30EC97E8DF355F87C322008ACA4151E57274C2E219EFC811A538B8BA26DD44DDE9C429C8566C30AD085C1569EB163DE705612951F8C022656A2462F92344329FC40D59EA66C07D44145F54A8CAC1939A01F359F54932A9E8B691E0FC3D01894198ABA75E851DAF35CA562DD5340DE311F091E2C65CC294558FC1326856924533A46F754F90F51569472C9FBCE63991D95B43ED76453707DAB30717A874D17535C94D880164FE89B014016F1BFCB971F651178351885034DE97FE94021EAE46FD5624E2C501C133D56D359904F9E0F8A1ED887D975CFB4461923FBA3AE566A27198BCF6938A4C80596396A2BE7755AEA803F4CB7075DF5A7D70788713DCE543AE2280989166EBAE4E7DBAF3DD6C92FC4792F0F11DFBB9B4A465FF9AB96701D5795131D71285A74FB93EF20C8DDDC705EA1992C1CDA769D2F43C5EDE7214823CD8F2C7219C482A6B07E88C6DC3186E04FDE3254DA0E9767FA69836FC509F5A9D9CBA41B12F948F163B2FE487CC83BAA5986CF84D07D171EF9F6944B5DC9FA7866FA72E7CACD7B4345164E4731971C8A75D96E9EB0C61B4F1F3F32CEFB9453615929408411F118A6DE1A9FCBE4FCC71AB730CAB4BC28B61DB6029A788437BCFE5AEAA41CD90418F49766E20D91E0E29714019CCF304371CA4C498EE48C5584FBBF146B888E2C3926FB5BB12CBD0D1736BE74EB533A7C34C06349A26C3ED86DE52A37E4B8EA2C1108BBF3E6773267C5B5C3E50EA16D56B24DDB32FC7F9BBEE75DF88181AE97FCFDAE2CDCD5CCC2E141A9379820CDE613E9FEC61212D23763825D94FA1102BD7F7EB1929A2538731A7E753A7F6E6BE57172C9B8349D8EDD698D1DC25C55D7F06775C4B9534BDDCDFF33DE2F1E9BABE78DC320A202ECF94037801F42ED1344091A132A24B875535322FCA82282D9AE2C0E1E926A2E9E1A4D2BEB6A58B85D65A7847A57E6336C367F8C0812C055B18E8A0AA987599531DB98B8ACC58F5DF9D8E7357888594A188ECF9A805FD767A1CC04847BE22833994784B545C4895B18D06F157F3B75BCD922A8894E2D8E3D174A3C3657B4D4A7B7318A4864D7EA59478E49B0C8319375DED55F93DDC5A51C6048D028195D4DF04206678644A2A6A488F605228E4120FA97E271758657FFE34F0AC5044F8718C3E184EEEDEB62D0C29670250D491E1FC3E59246EE06D3CA31C167BA3FB52A77E1624E34652EBB1FA92DEB762FEFA87AF0CA5872AC6E2B6429ABFFFFA10A5F346F032F753B7075B7CB32E9E899D371C7AD8FC070D25D6C919FA478FFEB91EFB62BC331D0A975157653D07E3202452A05303C9616CE9A647FD4C97E1E0DBD9D8470ACF5D5DB77780A5D515FC7BA795A071B67F7F63D8A4C6E05BA2A7B31AE16EA31D8252562F44DBB447935A3EE504DD135AD6DAC43BB01EB0C5CBA939AE446FC260BDC488E3991D1BFA5102E262C4E31A034B8BA12C1E0AC599474DD98CC014F387B719AC06327BC5F157AB80D424BBD10769BBBF97964DEA127FC52F418DEF5DADCC93724A725CA47300A31F5B1D2D93AADF5FCD59D5F30BECCCBDF34AE458C50A5B54FEB305EF1C3F42556C2E97DA0327629DB5AC8532D6E4AFB22DA1687F536C17D7153D8791805061FBB31ADC0AC2F15FFD764E46DE3AC541B07C55BD67C7A5A972E0370620FE67449C58769D269E160C772C1DE53C46E880D5DA7D58EC100C6810B1C6A051F73B42F8682F166069E6D0D06D2A5894E4B6F74C42B31DCE09281EAE9B1DB21B521D6F910CB8BEBE8F7C09B137C7C1B7B185CFDD91E2A0D9503C35C99EBEEF4B3011A1E5996393FC21E972AA0E6F576A426141699AAA0487C686C1E14E74CC697F4E21591A75F5DEFB98B5D649EE2AAA85391D25FD8E2A20ADBA6523C26713165ED207CA3EDC7F0CBFD5468F4346A209D7A8EB2F63DFB6255F54C062BBF2C90631B539BED1A557A16225FC3DFAF9B6EF2BE10C0CB279644AFA74A03E66FF4FD965184B9571D4A8EB2357A4EEDBAB71275E3D5DD8635C53D29516E98F74B51051752AB7D1954156A906144EA4E54A11826254529835A80B6A3599953E012D4953F4B610A85AB55860C305787D00BD61179F369579EE1277406A3F55DE431E3E7EA8DE07FD4484DB4FF458CFDA28A2307334A41DB55E31CEFB5EFCCD922E475D06979E690144F77780BE1DF0667F746FD0B2F72F87399AC11B9417568D3691AFE1671E08FB2FF508A68AF6A3E0CAC6A9ABA02A4E8AFEC4B7F41CA03EAFC31CEAE5C523703FE41C1CCB6D021678EA00B6AD24AC63ED1F6880C4585E4E85BD975EC84417E8C4D4C2A4B6C10E11853C9DAD6F07BDD25387B66AC3DEFE166D6F85576DBEC76943B87E7C91293D51CB2542B63828571408F893CB541C8A69AD3054FA9EC6759A173E82B55D78CE64920548856A664E21844E97CB264F42E11754FE5B17AB60FA85897D65881207164AF2307376728D738EADD4F486BE0E5CD0F1FF2B080C8D966C28579DF5592AF1E2FF39EE0E318596B26CA5F48F789CA0712A7573BB6ADF3706D53E644B70056FEA3C7EA90D0D1621314047545C738E93A0BBBCC8CED0DBDEE2EAEB0709142630353D434C50657D888A909AA4B4B5CBD9F000061D2C2E39464854575964747D859BA2A5BBC1C3E0ED18415379808394AAB4CEE3F500162C434F" - }, - { - "tcId": 10, - "deferred": false, - "sk": "2EEE200F329D7A51E31290AA8C6581EE83A0B6F215ECAB93D0F0E4D0350B4548999ADCD8E8E40E7BAD4ABDA6B7194C206595C2747C4CE24E6EB6BDF0101CEB17716EE0336E6730404E8B6F8F1022F66C791D166DFF04E6A18CBC05966306B34745F4E213CD668E079A0DB2762FEA5A1CA548A026120289781B847A96A070F43F10280A08252564A48818052C6042280A4989199005CA826940382891820149121204024EA4240512974CC092859A122048B82812B881C9360D4B001090B60C0A398600A5100099710BB5201A196ED10612D800251A418E1B3321DC404D20C3404492055B1248102500080468C1B611D4C2100C94046442204B361189885022A08561208A23B64C43286413027121488900300212A33109B32102A561C4A80154185203010A00108D2230801B1760CA406283484E00B949022622001765CB020213B90D9C368A83A2915220465C82898BA09182203118B30112B240DB026880200610112919948884222AD0808503324A583231511646A14445A0A64598B80CA49230C9828D138685644864813669080460E2422C60204900B50113496604C06C631285E1C8295348614BB828E0182A634881D28881C1984444867089369208434A19A920182088182940A132514432688BB87113226D132051A33031C118220A450C9840518234010903929A1226D28691E3828DD2B26810094E039728D8402598243208938492468543962192982563322102A291A494318C306CD4004009874521B284D1885124274C0C410D61402D8B146283A689618808D9808464862921994C0A990454207014B3608A168D09150C9C38305AA68C14118A4C120A9AB03109122018328AD240492294650B23121847060A321061980583B8300BA08D633426D14260D1886513C6685B082E09B9601CA48D519861481248501431E1B811C41082D344249B424D1B310D99105084468DD832851B14864B102C221211DC908183167008A770C2440253388112C68423184952828DDC408C8B4884A11060CA8000DB2089C2805199900C1B044D22874802378602C040591484C0B221220790C4804C48068EA22006109489CCB60CA04226CAA46552003050B608A146914A007221C711D9088483103143C009E3086961204E239200C390611A3529D808421A422DA4208120A351CB080208495161144164B044D0A6400C4081124025C9B631501870942850034868E0B22DE3B86062486C0C336D0899305AB845003991109040B90DB8DA1A76D8382906AC6480001D09B8B836B9724779F5333E5CB7EAFBC9BE79ECAEEF30716D5B8198957F201320D88030EF5C82C56EDAC3E6E7CDD8D272EB421CAE9BD5F07FD96EBD3F21C0171EFA28612807DBDE1BC11587A52AF2DD2A9AB7F24267DA67ECC77585BDB335DD29E7941DF37995A7680E71C4E688B840A19455E569B5A777BA3137384E0FB6F2CD937FF55A389758E95A4F145416EFB0EFB094BAADFEC3F91EA5B9AEBA8F461F4B2A451ECAE68B50EBB69D358C12227E8995FFE00D9A3C6AB4E00B58AD99C9240B4D2AE6722AA144E27B6F91732C06A86072B69001AF41F30CECE4869C334EA78126A47FE2587BC76B587E25E61B1EF8CE536C0AD109033B14DB41B9F2F3E18D4F812428E9E9AB88E6DD01E8C2474F6F5B1BB1FCC3BD905F1B16034D9EC562E65F06C14F5BF497930D02565EC9A458BEAEAA5CEE6C93207AFA1C934961D1A0F6D726A4395D4730575BFB09F41B21FC5A816FF6503A0ED308D693EF4FBEB88C09CEF42B1B1982218C3BEF1E81B63DD0D9B1BFFEC50A5782D00B9EAF42DE3561E47F2EF9B3882665328D17567282D1B1B91FBDDE4B64A5876BDC61777FBEADE3144444577D591CA0CB5A665251DF22E055E25AD7543A21566285FD3D3C85E7A4849DA65A28658FF631DE44ACAD7B066E2D88944BEDAC4B220006B19F5F15805DF64F320AE38D05F0DAB0E95E02D1707C23279F3CEE21FBC0D921B334E2A41E7D07EAD955FE5D530F3EEE696248568282A4CB03C3E017FD959560DB0B2F2149F2B01FA4ABE1FD17C0321F38E77460C29E93D88CE4301B58A493C1B29C1B81C0C6B720ECF408EC4AC8BB744A79418531BDA100236268C257049D84598BE897D804FA13076BF9E426D700101D10460E1A97FF32974E1B981893C0022C1BEA990AD92C2C52409C05330FBA5EFFE835A2D57025BC8F22796EB42E6C3CCA9240E3B5E098873F45D5F2B290C93DCC1485481D3689C835EC613A5EF5C6EEBB21AF65403023EFF15867EA26E400FA648AC02C7BF4FA9EEA4FDA649DA80AFEE18A660C6C8F09FC45CC6D0C1941829488249052FE94E9E782C49174B680D7362E41AEAB16B797A05FB55E66A2A0DF069106B3E28F1CB7E90B5C0AD18936208AFE951DE9BDBC1EC66259C9D80C9623C68E95102EB6C597C955B37C510BF421FF5B38590564960AE172DA8605E01396992FB918EE2C107D5A13AA1F8601B775BD5B9226AE66F28FC62FF06FC2ACEE4ACEFE64C3234E4FD53B76CF0232D5C9D7802A040D4E529616F0F43F118CB678FFEC23BD92CA08B18617B4454CDBFEEC86E9CDCD80A8E918B73C3C3311D258C6E2F7ED1890FF0D4F28E935B41FEBD17A41048A35B9AA2F15D1D32864DDE6D8A82E65C17615C71F04A2750F5D9C5D62C24694DFFDF1C900733365272ABEAD17DB695B5285DD16AB83751AE3F63742C5F87806950EAB68E35DF9DB0FB4ACC7409BB896AFEA9C49DCECFB9C933AF12DCB7723777D0059460A02309E9794B04E7CEAEC0AB433311BCF42AC636B71BF73AE439EFC3C4B793287E7F2C8FADD81B2C2A9A09FA1C956DE94423BFC76F791AC88E9BF0EE9493BE031603BAF103BAE535B9A366DCD45EFD324A5087FA6D214772FEE650488F83EF201E9EBB8F60B86B40B2415BDF5AEB0E20EEA5153534F93EC093431850241F7BCD4DB2B5ED441FD8013F14566F6B4ABF725B3F966E0C3BFEAFB5D0C2B6D819887985CFF7DCD647E0B5ADA53D895D14F0361A8E83A7945A99A833EB3AF65D6C9F2FF811F5245A629BC646F3E31DD9D7810BD4404A1301D11D30DBEC2DE0163953760A6C5C7F033BDE8763DEF5D396BB141788D239B720590A79D73BD46EC7C3280BF852A451FAB4392630E071ACBCF86236F7C07ABA6C90BCAE4C18338308A08C1760879A8C2E0D561981B39A4694DBAD9AAB1E4A752F87CBE6BCC9B1BFBB314EF3671E95C654B619394123376DBD4823F5498991DE817B82FDAD2C06AC74CD2F0FE13897527ED8056CCF315C9983031A10E226A2FCBAE1FA327EFCE9F7241218ABCFF7F3934D45B82DB6124897DDAC45DC241CBB42569F926A6740ECD74A9EC6DACEE48CE955F9B3B296E779625A6514AC5D586BC407300572B3693C1272609DCE114A1484F09BD7201C285C2E8CB5C394B88A1FC9A0B72F491A7CB445B3D7F6D9585FA0AA6FF2B71E32678C8B94625B69B1F008F248DA1FE9480C653974BAB0153B78AA642F191522535138C326864C4C9FC895C092C1D05659F01EC7AE7FD50C9E30C7C2E4785E2EE1A7042D6A1AD17A73996B8ADCACE9888DCFA120C8DC527860734EAD355C47136CCBF738B3594860B795ADC28", - "message": "3F1B179FA452CFFC1F4776B275BC9DC61A4448989A5C74AA4F6A42748E49DF12AA62C5DA238BAB9F4309D563EAFD739B54E8957C0E91DB05F63B2A50F11205F5AB60B0E857F1AEAFC0562A76626AE579BA3387943E8B735A4B1CCBD23A6CF56D7F38CDCF772ECFDB7CD40781EC2622C10D65BCE780852D7930281726CC2B83C8D8179D842CF3DE761B071A6B04A383624398FEBE34CD841CBDF9C256A5EAE3973F0C256F89665A0B23F0B505A2EA73F37EBC11AFC2C3D4FD8626EB86FF0267D00DBC567796011E5548C08208CB0B43A880C1590CBBF0549683BC71A8BBA2CCA5F98011E592F3B5D7C8CCA0165A58BAF8CEA629CBA860511EA2E86B4CD9E721E8D7DC608504114EA98D016C0C0EF67EEF084B8FDD8BA4825A0615F7E09C42D935D9AF0DD847C2435D84B4702ABA573499C9088EB21CFB97E5B5A847476FD25EFE2C2763429048F797FDACD8238937024E5D66B3FB40055C3DF19E213E5941095CD8FA62BCA591007D03CFB879388983D6E7A189782F36F88EE409D490C5FA66B62510AD0D0EE9EFE6DFE23139944046C62EE639C0F82E6D850770A69577DF6034084DB97E4FB2BD206281A79CBBFFFF8A9E4B70252F6F03DE8FFDBFCB0A5267877FED3893CBE5119F0C6930FC0DFD82C63CB1E7DE66DF2141E184646151CA8A927DB49A3EC63B3B862AD60551B0E562F35E109594E4E43B192BFECF066B3C7612BAE0E170F0E1D7D246CCC3A2F94D3FB08BCF9DC7DC44735E258B1F9D0D8152EE79FF9EF095EEC3FCD872D9584361A44B9BDC88BE2AEF1158D1765EB4DEAF441F2407039E98DB8D148DC8B7EE9C44D5833FFE4C52A077F57D9E36CB220251C58F61759D18E4E449E72F29351F6CB08F9D996005A33EA695C21FE883E1C3BC3DC3E8239F2BE16FE445A18AF83639156521188EDF3F15ADB300A17F88C829EB72275F6F35D2D1A72B79A01A50F1A63741A8B1ACCC35E49D331DF670D30DE8855FF27C9F6D7BBD16CDE4C4C4DD48CAA971758D714E89DDEEC7CCEBF2E89F8CF03D7E631B9A18ACCF19FF35AA24AB6A1E10DF105FFE2603C30E16B7194AD615038FE96F4767DB8882D48C97514CEC057EE636C9FEA31BDAADC5CAF6239A805BB05081962A2A5054D9DDB47AD9D3C98D053A5199A687668425139998BCB466364F656B1AD9F13FCF7FDC50652841EE475D86AB89D0CFC01C6B5B876AF9D0312A43DCBBC71B2714B0C3226967A3D1E0AD7E9368EDDEA9120B2C8641EEA203F2E943F43708EE6CDBC6748A33E3DBEDA2AC492A6DEBB9751E7AE4AA33F6ED893AF7054454467E29D7EB7F2163FD24F7B5607C2E77DDFAF72E983AB532C6585AE8D78757DA904D1FDBC10768E3E70D582F17708B51D561C24EE0D5A26559EADF5463097155540F26EBCE03D89F49D7033AA00E1DA5ACBDF148DDABEAB739EDDF99A6B2BBEB48F83E3516380FC7AA9FFACA8DDB53388485061EF5B94E92443C24DDCA823E44A29116F346A22BB3DCE7022C3E2EF35ECAA91CE5F65D7C5EEC85D741ECEBAEACCB39F881391EE2A06BFD7B72173B171B7D11C8792F0A7D9A125011294296B157591A675649716F92234BF074F78EAEFDAE1AD79E4208C6338F42F2A9B105EC5C717301C638C63555AF0A81F63D0CDD04F9C22E2FF223CA5AE1A01C7FC61E9DA4412E80D493A7C0DD49CAC10C62A7D3ABC1B9C74EAA2D8AF248946EF8A37F1F7017E49D11B89EBEC111D85D7C1512EF4F99BFFEE68FB588DF3F39735169D1B5A647D71F52F76C6BC09F5703320DC92BBBE6D7CA592566483636957D235F5D18150B6A4641CED6276319244CD8EBBF74BC5DD3AF82E6C1118D19ED291ECF84E4EC2FEFF28286898E9659B01A37F4612460B34DA8444A4805FDEDCCCA5D6D8013335B4139101F28090517FACAEBBEFE59E44A969FE3B8402D690012AB908EA590249BD9354D456EF65331608478B2050F985C5903FDA5AF0D918E7F7E167C3A669B727DF0CE96B63D4D944493C5D2BCE97F2827CAF54103A18CA8CC0483BC8B98C42657349B8438C0274E4401463CB55E93023BA114FF8CF3A718740756DD8C92958BD07A304FECBACA3CCA8135AAB901AF23E1104E202395A08784873E03FCF2D07AAB003E6581741389C238942D7A2B9FB30B53CF5D0C408C0EDFB1C4FF448D745FAFB0D659B4BB76B16D5B61B0A38039488682907151802A815AF220F82680E523E838ADB47425369CC421DD36C2E60100A9EA7F29B05D985D644A7FEA573BD24B922396A481E33306AC41CEE9DD8ECCD9DD7833F8CC77477EDC2E97A72CE2DD930BBBC58FBFDE78DDE34CA1F8DC758CFCF2ABCD35CEDE0657B35583F9C016524D3AAA5E698BBF85AAAD01D7D3CFFAD4602858BD7E2F173D6A24504E448926DEBA1F70F3B0D5B454B02AFC4D0C482BA8019A0C209ED071BD2D5B341EE06FAFA7FB0D1FFE77FC6F6C49F78EEFEC44999E4330BDF33021EBD91DE8EF2042FE4C3F19E992A5E66FD9BF8E3D428AAA8FA51C7C761C2CAEC8908DB3066D50BBFDA98B82387E92611514605D6CBCC0AF9FE08B39AA1DEC89CE77987BF3BBFBCF362B4AFDF12A8A1ADEC69962A6FB26610C816F023D87E648A77DACC3997127AF770658921DCD300EE2C8C0916593067B3B31ED1B6B73D68EBE68CB22386DE39E57FFF6AD766193F99CDA751316A5B0729FE5307C107FAF6DB4CEF4B1C6CDE957DCD6361606A6606BAEFD9A1AE08A5DB21991F022C4BF758D16FD53D6CD41F637F5569D7357CA048F07F53C850CC56A07A4C2F3BD04DEAE79498EE10B366861EA82A7E04B9202750D4FF4017239BF1BF7088A3F2E2C79DED5A12F75CDD754840868754428BD7392E4F01F36E3B450A9BE5BB95FBA71C960C7D09DBF24E6662C86D8B5C3E37D76B16845B0F88C40AE7360545B3304DA5CBD2B58C29F6EDBD794E9AC779227B0FD198EBE3A172FF4B8896F0C9BFB7A4FD9FE6ADC73E097046FA25CDFEC45CA1E7FFC4FD582DDD8C79A9F3959A4DD7E3473D6F242B0A6AD4DEF109C12DEC994F2E313EA1930ED25CB401B82212E86150BB53BA88138AE3269157FC2A7A919E21CC068E0B9E934701B572AF0E20FC2CDB2B7452CC1E5545AC4CDD34EA0097CF531FD92E3FC38CC50E1FC8ED59272FF3D631FCC239E4AE0AFA46419863A166DAA2CBC63E24C26ED7EDAE476A194F8BFDD540D640DB3A8B294E0DF0AEAB7A735589E23CE524F534AC82D80CC51DFC08EAE4FD02E6F6E0BCDFA0FB23697EE1AFFA735566223A70EAD827DD31881A3C2471677F905B64E6AAE00467561FDD6C79B45016F1326D705A854877DD91D0B147071B00C5F8A600116487D39284F6334FF56F124951333F723D68465B765B32B396FC4C432D51E8C6A9782461EFADC2CB93EE38D4945833435E2E27E17CA98998F9B33057B1C73E2E43B6A184868DA05559B3050FF42C76D7440E1A5B803C8D4B0CBAFF9FF31C7E98FE2D011B3F87416889A81DF9F48643E943336430602C5B44C1D11BC7F62A0D67BCF9964815CA0AB83E7A87DB714F2C1872E5B9F0843B82846516E54A3F7FE311839F4910AEC6CF0D23F86BF2B0B05BB71B5B47E93B80F7060A350EE4D73EA09A6D489BDD064763CACEF5818B319CC973FBBC78E01A505A2F6C4F6812819E02A573AD8F7A345763943B623995B0634562479072D9E42437FCB2D02479DBAF2D088B31EE870F11047E965D04524D0CFF90B943B1BE969DE752249E8B48C609F14FC48692BFF40EA6095F1967DB766C8B4E18FA73DCFEF18F2DE1D295B51A63880E288ACED85B188B3D10A0B025BBD934BA43A5AC5E1829DA836EFDC88F4BC6BA0F4F23A4AB16DEF3B5488BF6C974EE1BBA51D17BD472C731DD35D5B74EDDD3C9177A3503D783968BCF8A1F2549F70069164C965304DE2434530B3841A2AE7DD47DC5FDD9DE046840B4D65A08A71A3D15778865CCA2418F154403183FD44B622982C64F771C87E18C09489493E378476B3B1C8D14C8009ABD3D1A51CF806189496A4D70FE857822049D3DCD4CFECC2F95D2A8A16D94DC6703B4C4EF3E8C7EB9D6859350131E1A03EC8A21E13F045F822C48EE3E3A481EECCA508F189954AC267E6CD19C80F8688410E2E97C71A6C792DD6E33EAB2FD16B82214588B923AF6C6069387F6A72CE06033913B50F0310112DC2143802AA2CA066388C96158AC154C33E9BD72C993B410FE5E9D7CF37A30EB85A127A7773ABFB416419A5B4DDECEC10E2EDB312C86C3F3C8BACADA66D057FDD40740176D137B1F1ADA098D978CDBB938F45D4B7814F2C5B894CAE249CA8E1FDF31E81997F7C55B7A43461F5C7C9893AD0494F4F0272FBC20D80F327EE55250F9560A301078BDCDE94D72A7D113ADC7C739D7AC2B8775D961F89245C5AEA8ECEB1732FA345FCD84A0C07C65F091B4B32DC4E117D24D782C404E8FDDFD6E9E65B3633985D6DB8CA841B9F9A3B3C617F1D69FB454045C5024AD09C5C1080F3EAA64202C08838B42E218F56422722536160F97ED3C08F285EF7BCD1119BDA59DB5EC6BC8E9DC1789B3CBCD469A4BCBE1CE237366A5B51B062D0A08201D4F0EAF6F8FBFFE53F35999763DA2470F2F9FE79BDA60285D052D65DABFBC43659DC76602DC662A3357BC3E4BD07BC32AE5B5E94D7DBDE4B5117BD5A9E3461021A569E200CD3CC518ED6559BF2539D8DAD74920DFEDE8DF8FD8333FA17F0798A17B5385A9569A640685D7365D3DBCE8411D44B17BF79B852B1348AB31335AE013B2877C1D8AF62F88C5186B7313F2C8736472FC5F2B4B38F761009F7623292EF14A4A4006305CC419A3ECC73082F63BB2CECE6A624C2A6DF29DBC6A4F0FD3658C58EE694FA58741DED54889994DC6A3DB4FAF5998B577EFA399E58D822B99623D76050736C17B5218671FDA3BCDF7E81B3E85D87200DB9150253ACB07AFA8FEAF74578125E1E26128116A7446C804DE54FD2D2B1A48E684F73AE91932A37372DB66A230AC4CD54869A0115895D2CC494E6D6E8B12845551B4F3DE0B3A4C114979F0471311434BB3784FAF7F9A9B88D536235543ECED732289B383E8005D98192FBBF41EA8026CA3A14B6895A6EF0548EBEE58C25530F56E0EFF157DF6ED0ED0D5565E9FD474B38EF5BA74D24B82219F317AD51F3E7D6F8E4BD8836B91525E162DB417C87E36B3C0FD874FB4BF4136926AA6D045033C94FD1EDCD69835A116357F341372148C4601CFD84BC36A8E5B2260B90CA797CD5A41362C44B4488399394AAA431A63A74B774E68025D7DCB1963911F2BDEEA60DFB24E87196FF38479D235C98E83F1FC419C87F708677F98C84F9C4848B255DEF2D92E3506A533D36E56DF81F6461AB5BBE9D171ADDD39FDE7552C5D4351DB59543C0FA939ADD6130E25D4326566FDF49CDFAA240BBA0B027257D2ECB83209329944E8F44AB785560DED2BA8EFBC55CA31E48F4C94749E4D205A50BEF3E3F039DEB3EECB213FE92C1C3E98A9F72B6CC316D6C0B87BE7F688000A2433E3A184A68722D44C7F6C90F2AD0B248AFC9E57448E3450888A875CB3006E27C232963740B985484E7FEB07775F4B4FD89AF6F627CC56CA1AF23E3BDF61443786D3F04DECD3CF71E2C6139B584F52B6B656CE0737F50BB270830B102B781E621B3356CA16019696A23EEB238ED74D160269A3EDD35F7ADD9E065F836A61A0CDF99272956555106A349166B2C299B8D0066581DC3608048DD8BC2F267BDB2808E1ADCD37A7538B9435E9E5D7ED4389BD2CCB6E926A927BC6DA19E8E0E946442A6943F65C56E5AB7507FC6EA1DEDEA7C1AD087CC005914CE80A241D42C88380A49BC4B6850536C5A99B6423B77A75FAF76CB17479EADFEF1FC90B832C8F36D92BA3E927C9D60473117267AFE4B115E39D50AC7991BF248DB38E8C99784848013B48D4CD6E034B93E643239E78936DAC6283DB748062220071473B0579FAC64510D033525D786778C53CEBC3BF95C4FE9406943E9D68E17EAB3245C57C00D0C206E3343D8201A2F6C278DD61D0CD42B71CB7064ACCDD38551DC554007F29E1929EBC81025CD1A5AA41510BC5CDFF340F42C4FF6DA37F8E97F5911F37ABF457DE3EAB6114DC858C0C14B9BA5B652DF63D0CFFF4D6F8103E0FD15D87D8EDCA53FBBC70E3B42C410F379BF77DD17F6FF57D7A0D01FFE0044F226F8D65DBCD1803928B29CB6AAB703A0EFFE4EB47329D9D373954F0F15CEF2577EB8F34665FFF2C774EB07F0CA72ED27AFE6EDF158C3AA193F3B5CAF99F52430A3662997DEB386DCF0A6781E42180ECF44E9043AFE95BDA84FD1F9EBDCE26EEC0A4A08D8423111B320EB87156BFAEB3827389108E12E7AAB3F6CC8EF67A7C877BCE3192E503608D6F1E5697941FC1418C16093A55A2ACF2378590F4B0702998A65C8127F13AC98BADEEB32B152F3054EB7D0F200322E40CE632CDAE8F0E6C22497BB6D464ACBE9B461C5D39AF9334F5342FF31C9273146D20F5D4BFC61F980B1862BE4A147474DE89A1A3278004F2CAE293CE2709748507C5DB48D98B484CE933DD3E925E1788F2470C91177ADA3869DF6FF81308DBE846F50C51AD66CBEB2AC91DF1C86EC22ADAA6C702F1CB7A141778BF957663060725A5AD6478E22FC959FE5C918EF1A11964E66B1910018DF4698543CD3015E9876AACE37988370135BFD7047FBFD3996B45EFAB6FFA70A4191F259B8A27EFA05E7E1C75285CF70910465589B41A9D29F51F7BBCE06457A3DFC540608157479B499B2F0CD9D8A8D6F2C01FC79E5079597FB6E2D1C3394B8D8AF65DD133F9D9300DF3DA3D740CD0E7E13EF62BE1D29A3DA6745A5A87558F23D89319BAB09A15F8FC01AA388E1FDDCA117A27426D142094A11E6B49E2C541A82C685D41D6E2520881534012774B4C01CE3D2FD8FDAB8C25E4F0AD1292974C4C141173CA219C07314314FDF94A05955E210DE13F0165C990227EEDDE23A52D7F4C8A181C996D0FAF6C313EB74BBEA4C2CEC0B7B01698C63C2E1D37313B637271DC49A7EED8542EE8BDF7C7D791F7BD59A029419616F9C8F478F060B855CDA73418D0AF090844FC0066DEA9DF8D4F3C9ED58CFED2A78B427B42B033C46485B767D75526DE8682D6AF0BE91169650BA4ACC4D54E0D357E993FAF358BEEE3F7F988381EDB31FBF174239A345130BAE1B0DEAF27BC5E1DFF86B29712CFFAB670D35D19DC5B25DA43D481336C0CCC2120427F30326FC74503548344B585C082A78F96F072510D50E1110EEF01617282CB681CD352A23607C3CF7AD9AC06FB52B38294DE8F87894D25C1D278678B048E3E3F4BA0D884154C5E16780BAE2322C389667A15EFB0B21718F56767EE942E4BCB190CDECA74C92DA8848F41AEA2328D29B10C95C6DFA74B0E162591B1BDC0ED6826ADD0B04C7495FC30E586FBC03D4E871915AF71866278F9CD1B4F1AC56E8E1B7B11DBF0C9A64F608E1C3958910829654057103BEC687A02AE9A568BE514187A3E27F3F9928EEE29519BDA0065179423A7242EDDD8CC337F0B7E7FB7CF90FC682C9E60253BD0997F34F9081FD785712E52262CD17C3508AE4D2FDA3BFE232269ABB185E635E659D405AB12E17A80AEE5BA7DDAF1FAA819A284A60B85B49F1A57DA72A0866B2B9C2D28178995E79D4458B58EDB187B0CDC5C37F111D20371FB8F410A7EBED95474859645FED6F451A396781EF7A02E6B52593189EADFB1226316FE8DF79B23CC67BD2EF973CD561DD612D0C3047698EA0D3895A28B4111938F0A0354E4DA7484697C85908A3BA3E80BCCCAFC73303C767BD3587C1F9D48FD4DB93517A561DAA10F53F330ED14CD65B4A54FC43E5F5CB421B8B6CF7B83D86CBD72A55791588D4B81094BDFE45E3F32A2C3FFE809F66FF310D66032AD6BAA5B33E79F1C476029A49D49CAAE427D8A81EB642B15EF0C544C9EECB7CAFD2A854BA79E4D7EE01A96CDE9EEF45E430EEFD8A16D5D22B751F981667F36DE2E139391980DAD22462BFF4896D277D89DCACBD5CAE5EE90BC2D5954C083AADF632D9051B782190ED4AABE8FFE195000A6BA05115EAA0BCE755B23B10C81DCF4BBED61E6D31E9292DC1A7FD6B453EBEFDE55D6AD8866CCD50473705A24F519548172D3D9F92E668D679D782B7F1041E5A558A625D65E679FC75B15499BFA304435FEE6F6498138848BAD0BFFF6942029BD0C5465395F5368692D6B21B2E22A638D6EBFAF3A0EF1F9BDEF8529C6D0BD328CC82BC66DCDB2F5AE20F53B8AF66400D6C2C0A3C6BCE1E8D2B222FC54F1896E58F61816E301365E12866C1BE7C4BBE0DBDA2B504F0628A4DF1EC7942BC58C0A4CED0046D73FEAF2231FB9FF61C0F7AA564EC1E10BD65B693CFF56DDF3596DDC85CDECDF7F123F9DCB27269A7F65A435ECCAFD89A211C829BC7F5916DDA61959AA296505F6D46543D863F2D3F007D8960634841CB317F5EAC3D3A3E4561801CDFB269257FBAA6A60E7A0A1980C9BFD6053BF2EEF7414704C7160A051355CF48A0C0F6FFD683C453513F8212364775B7424D9315A920DCD5B140A8440EF7E5908D4061F580022399509C0ED416F945705A19FDF8E65C8802B67701FA1D15F06013990C7BB8D0D0404679713222924DB33BC659FE58F82A99BB1AC551426A13C2CF316664AC8037B41755F110F6441C7BC9446430D7BF917AFDB8FBEF84E895388A68763E0E16F89FF630BDE9732852B70A4A3AD8A29D2A4670757AA4202DE5D53E653848FB26C6031D07CD010501F0785D1B1D69BED49DC3B07265D51A15A7C432C3EA63A0B0D228B4F8AD4060DBB8D54B94BAC7F2179829C8D9F9CE4F7BFCCB472EDCBED73B0D18E3108156FE659CAA40B45016E0EFF20F81C29EADC8B638364FACA6FC85F98A9BAA9BB7E5261AEC6786C18487B14B77ED2B62B762D6B8B39AF5A870EACD236CC53C016158DD1E71382475657C512EDEC0977320F1BEC79D0CF39403975210DCEC3ED5B58F", - "signature": "0E27A9CBDF2D81A93D2B091B79F926B66598283ECDACC0D1F1FC71EEDF8A8CFF01741193BC4A5AD7E14CAE78A658DE7655C93D50F88FFC5E4FC993B7D936F7B7E3A7A0BC50C84190D300032369A74367D1E2165307DA61D4255CB55B12448838C0783F61210E9E8003814366A50DCF6F7F504AE587598FCD32D00A026723A34F040E5ED07F849A6884C1E96D6F15590BEC3E3134C48FEEC6AA56A746C218C7B40D5CBF994FE3DC3EDBCF546DC46907B64B3A438785544F9E33C78772F568B206B43DAF1315B0A6CFDB4797C127AF6F47F605763EB9FB0547976FC486ADDA2597CC86CB461A3B1A2C02D600039C2F50AF91BF47DD8FBD791155FBDBF4709825C2B5D302F5648CA842D6B9021938B6569DB7ACADE0E7A13661BE3C50C15AB3A4E82193BA5A342AC17A24263EC52B02857BB78C3B7122362C22FF1787DD9C3686DA382CD8BC5C70B2F16C8917AE820371D813D8367176DC993F72AEDD28181E57C8E0CFEEE2C81BA538655D888875E7F6831B1B5178F3C2D3FBEA81C12AB19E507F2F4ECDCD91D1CBA519816B87F16CC48D8132DB8F042057E21C635CC5FE3BB7D695CAAAE0A2D35591614E9FE2D1C47FBBFCA82EC92E05182D392011A48BBFA4788298AFA2F5ED2A4B2E933776AB1FDEB35C6EA224A69DF604A2979E826D00134AE1C13A7F2A17A0B3AC498804F0EA2D545CE3E37092D672277C4CD051B652332CFB8D1DD8ED703080032E4A7776A19828903A857C574A954A93EFEB26B0CA40A6780F331EE5AA78EA847EF4A624AA0B37D90BC47964B114E8F570BCEA25308CFC4E13F478861851E08E70F8188E147C1F17A769C868FB37A10638CE2D95F8490D2B4145C302993459474AF385794E4097D1E6B3B8BCF29480B25CDC9E8127C07F701A03452FC6953A16E864D6DF32B2D746E173EA181F2939AEE6354A940454F946E9450751864BC74DAE264FABAFD2449D7E51598BBA2D1816B3E912767C1DB51601DA9515DEAB9D34AD7E5F4072AE029613CD5975786FA16A7443F628AFD31B5570DAC44EEC0D41E9F2740502A2B2B6742472CE59E900DF6EB15A3B8D37D05EE0EB56F1558A2318D40C6B7AFDA5CE952344C8D27ED5E22FB57A5B6629D2B901BAB796ACCCE5CDA605B5B9D276F082F495D65EC4E96A962B4D373DE2799F5F4AFD748B9C2495440FFABD7C76AC29F0EF930FAC787873D0DC93158325649821D6F5BCE89C0F46EC9EB43406EF0F2F63F5A9CB90E542D0A3BBB219D2D174377D60D845677126DD80B62464ED3DEAEE110018B29D0354662E1BDB4BF07BCEB8DCCB73F631385617C9A9944B9E6BE8FFEC492847554B1DE4EF5514E5E8E968F69C98133AEF51A75E0FEF2C60A1CB5F1F8CA4855C5F6CCB4ECBB696189948973EAB694004BD998D0FFF5E0B5270C71244D57011835CA161E18928D1F03F515E5A271E46093F2D43052B9266373D06D040C3C735665941B9BA15C9ED03D0941894D521B3518C970C0ADDE281A863F1B09076C9E7B377CAA8D5A3813D7E9316B3E8DAA28268D53DB57D2A1E4A64758B548CDEEB8DABBBDB81740386412B2D3CDAAD98B0E90F98CF39860A11C3016FDCB87D8F83155EBB4623E3F57D1CE98B25FE024DA73449441416EBAE515FA4CB1139C6975BF953605FB1B5CF9FF952E674CEC3FBE66AEAFB1E5D3EF0E3AF3FF9FBBE2E9DF971E8D6AA5A79C0C3A4D8F4D18313EBE0E00DC7D5C913A879C448AE8D31CFF3901F14FA7D1C1C1517BBAADCFD2F6144B2FFFD3440620594CC5DE9B96B3F509BF13F98098187353094EC60D93A57EED58CD91701451C86A7D96ACF611A57F212E27D2EBE0335FE030E391DEDFC2CDE76AEA4643BAF0F4545BDFA7206E14D4146FD203F9E0ECEDEFFAC0363E210C4777017927A4871AC70725A3FA8F593BB9AEA1B048E07BB6BDD718B27F2D375B6690BBA1FA85FE48E8D85CA3B35ACD83B568B286D19CE7C5E0356FD18C203C91485E2B921ED491E59EA5A85796EEAB8208A75A57E0CBA190BD93721022C0303463DEB4D149044FA1E220CE7B253AD5564191E1CF998535050EEB66823EFC455AC058325F1AEBB3EF0FECEEEA8A9DF5022411E04FFA1AD7FC67692E76AB3E9474D461C815A77E0B08CA7FA5940C18BAAE2A7C93C7501138A7E071EC321B4BCC684AEC1546195261F2D07676E8E4F36AC2355D44C8412DCA71BB769AA2B459F285819CC9F19E53DCE686E24600344A32BAE91AB109F01DBDEE0A86AFBEDB1689900659388F2D57FE151AC876620A4B270DE0F9AF057A06FC9A746377F94FBAB3BEB63A96ECC1D26B055102BA7781F7EBC57F48D1221DFF5AB33F9B954F89B1EE348E4809219572CD379B833D690249F70C22D28036A82EEF543926922365643A92FCD478171AEF25B31CBB010164326E680CD247B85B1417992ADFB613BABC7B0B19707D9331BA1328C9677E4DEDD041D2259BB4A296C338130A397E003C34AABF3142DC4DAE8F862A9A9D7A5B8D39647AD00EFFCEDFA93C8831551A4C5FE1A6A32397F8ADE69557EF57C88D3A7EB14F4E43789148A31BD2E8A39F89BDC2E02DEB4DC2B337CA72AB3E00462A1ECC7D212EB18B25E88EB05897A3F29839F840909552229718B725F9FA2F23A4BB802BD9835CB4E765F422A10336BCB804EF6E5042ED3CB9F52EDEC95B0728B117736A0722AC389BEC0A0E593CA4196B857A7B89F23B219E48AD233481BAFD9691A35D929BED17CB12CCABC4BB101B8B413ACA50F2CAF472BEF9D3FABDE8DBDCC9531F8FE67FDDA1CA3E9B790CE4B0A0643A58B48862EA3D6FAE5972CFDB0EB6BDCC9EC1245BE418B2CFCDF3CCA609A132542E68805BB2987A7962E54D95F370F7AA9C869EEDF525E6DD9465A0A1B2B93C033CEE24C849FB41F0313A98FE766546E430AA5AC928741D19D39FFA404D070D401B5C26FF44DC9C7F928D51AE42E1FAC8AEDF8EB71BC96F05C5886E47F8970F071358B534D073380AA2037C42F69982E89B3B76755F7E5E1DF981370467B7E0ADDD97C69B21E37CA263F2BEE9CB46EBEAFE7C02629D31DC040187DC375C72040F5A43B35FBF0676417DFFA21F7BEEA23D0545D9C6FA337976F0E62E25647F7A377A965EF2C5B7EBB6D074308F93BABA96A9AAE838C16EE7DB31A64A4E3F6C416EB9925A3AB70757BACD418983A9D0E23FB8AD69083A98137D640B440A68594C65788968D3D3092B319DA8560E6748190D8A07B76F70D0E3F44F4557BC2B604A37059F0A544F184198C4C22108315DA78F45AA217AA485691CDC82AE5B06EB6D787EFD0A366DB7F1B2C2F404F50757E88A9ACB7C3CCD4DDE3ECF1F310121D2E304771727E9AA0A3B8D2D6F9051537396B7475808D95A1C00B233336383B5D5E65788082839CAFB7BACAEBF900000000000000000000000014243044" - } - ] - }, - { - "tgId": 2, - "testType": "AFT", - "parameterSet": "ML-DSA-44", - "deterministic": false, - "tests": [ - { - "tcId": 11, - "deferred": false, - "sk": "5DFB07A2044B931675C78943EAC3C4C57B07778AD9AF2E87C470B9CC2C8DA1E375BCB3BCD19E7BB983C96366CCEA141EAE2207755224C8C6C61F908989CFF2F62798A68645779515D474DDA61F3341424EDA24796027344E36941474819A58442B74BF5060B840944AEFDEA7A4CFFCB39DE207FD9E6AC62E6D0DB2B4512E202600B53001A92DE2420242127124B728943086DA2230008765CC22911B058203468AA0322640B484C3142D88148C94924923150ECA88091894688238002141288CB8800209495AB4119B2805E44230CA2480A4062AD392051C036A22364A924452E2482819836888C63141905000438E23876019438150326981C051120608020882C4A68103A5908CB60090146601B1081225481A881143386023262E14450D9C928CA2461294A60588B0110AB028A442099C82801A806159B08D40A66D12C90CD91868A3842C02B62501402CD8204D1B35301110496344318AB2704B2428A04608C9068108C5044AB23008150424A2659B884119362EE2B829D9126441A63022B78C93386993300AC8B68523B18D01380A59A00964126E880822DB00080C08129942441B006808132653A2405A342598908C00342D939448C8224CE24429E20028142240482824224906CAC80C4C12801BA5411106481B277220073124108E9C94911B378251282E11064201346E8C222524346A19472123B60951B2311834458CB8201C190A19B76D1897480982049C128A410846241331D04246C3168051102E5148045CC2641A108ED9866490246893B44594304AE3120C54049003314062924D5CC8108AB8615C046AC8B085930005C306691B348E03840C50002C8C96900832680B908C02862D1838091CB2211B48045C1086D8345143848843B26512B68D03014519B88D92264E12128852B26421092649380524110A2238322331204A2442C4A24420100DA1A85123868481388E02004A1CB7244C060A1C264ECC22484C922DC0202DA11689C3448219A76DC49010018289D84422D99820C0884588220C90369090A405D38221D0A628003325A2C26CD81071D19650C334088B942D6188041BC82DE230642028241A345010256A64368109C145E33080C3A68CE0B610C3348DD1061188200A0AC8212081309C14619BC25022158D80A04189244120934001A60908252EC1C685001762413032DC066D48880884C8305B968D42B44CD03488D004021815525226308C462820944C211800D0B2481B170A09304C44C204475EF23331FF6673E26E6A32F294BEFBD5964FED987A42A235FC5B16086145C0B8A823FBC14F1C8CD03FD6EEC495283E035C0DCAE52E68F329DE7ADFD64FEE0B116D4A14E15394B31DF88BCA10D1C906AA82287C117499E9D8C77D17A95CCC14AFF9C205D26480A570B5770B048199CF3F0E1B91AB394B1F65D47F9298D096CA25C099BC67F4334263E36BD9E66B998A07DC1E181E05386E968F1CB0AB1E9A67D5D3301120378224881F651759EC7DBF45781EF8A84DADAFE613D6016966BD8844B6A617ACA1EEF673B774CC807B36DD02DD45216686037F9AC0B12F5726F251C57243E2C188F5ECC097E0B989B58A5D804ABFD720255577668EE304D01C50FE8B6D906853CF7A494FB47991F181B7420E74199C82E71A824BF8C6131DF4D1856F11E7040770724DE72C815AC0443F2E77EC22A128DB18E1183EE79682C43024C907466C354B1C7B0E0EF09F16487BD8A99C3A0A9EDBF00F15A5EB1C50D42736DB0763BD56BDFA81099ADECEE84AEA069C065B670314B9E48C6675A3CC693957DA1D21BACED87002FFF56F253A3DFC79A3F03A3F2B10519ACBC91AF5F1985B5C87964EC8008A3A6E8502A5F169326EC19568CFA8E885554D6A681F00DD26B324F49DD24D8106DAE64D1173DFFE4FA6225E6C6D5EE359CFF435A080868949B2ED0CC73B4206688D90041ABD51F6B9292EB6F079401E6E5994FBF56B72824CB6C72B127177DD89CC2F98B0931C98CE5E890D957B98E1EADCB7FF22C531409E1C8059470149EC81EF16326BB04EE23BA3C103120DA665DE8DB0A0BB75EF5CDAF4EE476E550238CDC1ACDD71A634ABCEA55C90FFF8E0A787BD2136914F23D87558C5F6BAAC546C24B1410202B944310EC4C9C687853605C8AEC9F1EF6B6752D39A15BFA247EF89FC0699A11AE45A75E509D454E989F2606EAB10F842E4AD57C6E365489414054F62200F3A1EC762DC5C8EFA1988475DE8C3D58C2B71BA11987C0AC642083BAC76FB50788C268FEE7BE2599B3458092A8BCB1F31948FE482DF9A545B638594D67A4406915CCDC7555747C04E72A548AB8FEE876B2582613CCABDA96CF14AAAF6716B790BFE4D9232D90370D60BBC184BA33BCF778316E34B11838D8F71FEEAC042F035B076EAC1C262FA9C32BC8D69B138B351318ED1F3449595115236F4CA7CBA2BA9E103F0F509AB916E48B8AF039BDCD51CABFACADCEE8E4984F561F97D17CBF1DE9A7A7BDAF326E6D8AD90E95BAF1545D3E24669D1C5F428E07E2C7110FF43598093E6F928A034C686BAE75A567AE4F520B44DACB495E5B2C6439E2E678E7C054FF7601488C6AE4A053699735510F9DBC34CD76A1994C0FE7412C0CE9515BF603A8EB5FC8ABCAC9F1510447358605DA133FDDEBDF22269EE1D468E2EE821621D2784C46DA83002A62694FAB1EFEC3B8D6F1B2CCE2A4EC428354E39A4F45C9665C1B855A50915BC4D3BD01F7FBA9020CDBDC2C8E5C6B06F144E6BEA8A2444E10ACDB205F315717C86FCF1FD6BA6E3FC86E3BA566B8FBE029A030C8C69E57C15AE1312252B36FB51A1615E3746920C0B715C1DA4DB04C108ED5C448070C10E636D92C21E188E710E7C10211EC2CFD6387A9B5C9EE8823DDD400C9617EFB125BA84454F64A68E2BBAF1EDB34F925F1A732A2A2268194C8A87517578CF3CC597FD7743CBAE3D9CB6455445F41B92EEF49DC432106A48ABE947BF2B924984235205A1923BD7782D9A15B4D9D345D069F1384D39EA497EC0E77A07881D1FA3ACE9C3FD6B5DF6B2B9AA9ABEF406D95E81E568DFEA204CEEED42A4D37BA882980DB4C8C3432813E96B110E54E6CD110A01364178C57D00C68DE77B4CE635578F56A9735AEF93F0D816E3448AA0A9F19C2E02D13C66DDE535FE81778DC246640323CC37226068CC7F79E86BD0EE1C6AC33CEB5195FAE42817944922696498828B689F6935F9BF3322A4320F4C26E48DDFAEBDF44D01AFA1FA3ECED3B05D02DB3BB423B85597B51F2564A75D4A8C90D4B685203209372600D54D985ACF293B0EAF69887818ADD1E1B7C5D7B75FFEB564E0680B4F467BDE0B117A4210860960B5E0221728687AE9EBBC6BD5954CE0AE57B145FFC27EB6A0D38E4616CEBE76CE595BA4961E9F80F0067ECD6E27B87D26B660A3AB52C1379ADD46F5B93975AA19F3E4A8954B253F0B4413F582106803D50F99B5B28B85772E783EEE216EAD2DCF9562941C50ABC5FA8E24B61486468AAA20DF15D172F6AC03AFDFCD5381BADB078B8EBB70915704B988E58F45D3D63112A5C128C649900F1D6966E398567DE348ACC0DEE42B8801194E99BB1AAF025A91E32CE6564D0510B910F22A27DECF9D2E", - "message": "B1344915CCD693416B37FEBD8DC7C7DB9F253E9DF53CEC514923AAA2676FBFA4CC04FC68F9E32F9E864C6895DB37E9FFEB80F0F6B86CB6AD9C42F8FC75198DD3CCDAF577C7B35B8F1BF60AABEA899442201FBBF4428C7EC17BC31B54724B9590F7531E6F790A1FA7743283372D3171B8966B470AAA8526EB4A6E81E65AD0C29F2D37DD5B412BAE682A66796877C82FFDA9762434EAC2C7D4AF609B2772490DEE9BFB005D2F1A2EBBA032CD7159D54BE596F33068BE5D9A2D940C7670E64E9AF7D7D33EC3AEC6F1D9DEE39284F05CE025D181760D40E5C2D9BEAE2420F40D9F32B7BDCD3AFB1C660D01714D813758DBB82C6B7E858052B5A50E39E015D3F24A2C64C9DDCC150D904F07F65FF68AD0129EC3F8123F3A03FC958AE2478C6C6E036167D85149F79FB03FAAB9897CE73F8855C54C83D753B104B513D56BC64C3B08917347351326D8EB47CF66F13FB90F6AF5A894C7750077A89CEB7722E2E680A59BF8438C523531EA8CC2834FFC4EF02D35B85146F2D601D500996A441064ADCA1F623F2FE7452247EF869D76D578420730888690B1A008DA282AD1757D2171293859C73F5520B5BB4803E7FAB02900D20FE765818EE624E7A194509D016B4BD7814EA0D54A51EE950A1476D587AA6F78C8D2E0C8F8F278D82E119044B6BFD0BED86FA420A2C8A4EFB05D7306BE52F932D8065DD1292346256E429DEE419EF37D1B352881DC477F25A40AEB3E17E61BCC00D2E2A93DECF300F0816821ED49F99B9B8BEDD91EFA04BBB09ABD1D2436A7D6648A383A3A8F09080E467BE10330BF62271074BEBD7F56390D1D3947F402476B626B52ACAB21AC104AAB59753311D9E9E2B2206BA10942B637E45CE69F54B467BCAEF3DC1AA215477B15C800358E1D6904D89CA96A031A55486C4FC168272613AB8E03507BDDC27E5C8A6FBB5F8B2286A5C50EC56860F6BFFF6EBADC2171D2EBD1278C5814C32E139E040961C319C3034870333B12F73B38E71814A9F1608365EB32D5238F6BF7D80021BDA398DED71317AB3CA4D7BE1DA74A1BC40C9B2E345BA7A23F9B2DDBAF85140AF9309E8653AC24AFD825BC2A072BCD02FE3EF00BE3F9515C29EB8AFBC3EFD1F9CFDFE9EBA94959B5177E2886B8D18DCA97F0CB807EE3EAE31B48CFAC613C2E00AB74FB95F664F3CABF6EEFCDDD6DA5F898EC38F2F07D6DCB75E0509D131924074C05F45DCA25B7CFE2BCFEECAF5FC36CE6E3C585437B069FD2C6BBAD33D686BD5B9E2CA0D98BDC5E717B6DF71D4091308E84739AD67FA679A6CEE9A683284B4FB31B2C408F52F0597D9C04EAF4AC6DBB6C3FD67F2539D887DFBCF3CAE459FA766661A48BFCFD6F640399D3AF0786359998CEFF7E9EB1B057A6293DFFB7F3F2514B0B702946068A6BBD7530D6917FB11DBBAABED7AA4681D78AEA9186692DDA3470652EB8A3F14456A5AAC420883B4237B0A72D912763B67AC4131A8A5D2F168296B912D3B661C4E83CE63A61C045EBA575EEB67FB070ED8239E51A67D9803CE00B856674E0B7266626DD0215E5EF5FDE7BF40B99102108FC2DF28BDCC8EAC63EFB20501F2466998088C7A0B96D1B75C4C2E252A0BF38015CA58ADA7938AE2EC7966F305BB421C0CD95CAD2127DAD87086CC38BF6B15DAD2C7C0441E5342E4B5AD91E66F423E2884DD903FE6C647D61E6700EA8830807E6FD64543E3C6E9AD193373690DE94F716154794FE975B1180BA40AF7F05C1829169FDFBEC3AF7CFE1D79B597EE438A296EF146A059971E3F9508E350B50716DECB51BC8802AE62A7F4C2E6F7B54620EF04C00F072AE37AC327E26D365761C104617AEE0F328EE97E086183D46A3621F23F3AC2760B8859A960EF16FC1C6B1978A7412DD7385029C7361A8F749CEBA23EDE79A170EA68459F52166F5C561F8887E620C00C64F06BD0ABBCDE5117ABCFD03B6D1BA4F30FA9675D82D7A430D584146BA7206CBBDD9BEA1EA47083DF932239CAA021DA33E43F168D8BE9F0EA8A852C40ADE439D58A805D474F89321626E33783C23EB601C4C25FE0F5E73C3AD339A7D696BAB2CAA5FBF96623AF0634100C74C814D424325BC30B60BEEFC183E680E645CD4222ABAB5C67E67111C4C0330EC0C77B22BBC98F7528C9566E171DD26A77F87F3942E0D3EFEAD0ADA3B7749C51DED5FDA3FE6E79658F1023068B962D058A2896512201E4CE7B6981252F0E855BCFE1F444236C930E49A13B37AF4F597C05DCA23CC05C43C32A2110817CB306BA47D245E50222E23C6556BD75D50EEF8BEB0DE835C8DD2E15C706670598F865071710469ECB3479EE026B19FE621AC99126B979E1BA1DDA8E6111297C10E4A77F552F809E90163564EFA243936B9F26E07287FA4077CA2697BED6A4F0A95990560E758D990B4C1920F9E1ABE0B589650611C2D5A13AA5F4E2B88BEAB9372F468B83091CD0A538A3582934F66CACDF23998FEC2FEFE5135F1B5622D1AE943255E05E48BFE912F4F241B2BAC499C14B058A3A8EEB9D1FA4D442E23FC5977A5602EDCEB7B7B2695E187B794F84B966315B1BBA5C04A72024A805FB19473B706B8137642ADB1C66CFD64F260BB1B7AADF6C296B35F30B9D7708A9D41E723FAD4E872AF73F88C26AB651BD57A21E28CE8C247D58E479F7968876FCED35D2B87D2DF144347033DF4CB50DE52D89841463F5DFB6D6FF6D9E82BBAB3B1EC58778AB8F36DBC6822EAE32FB6CB6730CB331C395C274AE7E37B409B7C6632E76DAA97B80F1E0CB47AA366A8E350EA36746592EC9B1E97F02F99D60021370B8993C680A102DC965D20B757F4177A81BA7B61D288EFC5ADED4C9A94A57B2C6BD2977E23640A669847EE81B1490BE38AC43E522C8D09A207B62A8B079A2484DED10063D7A13FBF0CA8EEDC2BF67BD8785335B8295AFE6B356E206224170E87231A772D218437BF7D68AC2AF93F1127184FA21521479E56FF22E80F61BC28B8D2E71B3D1D94281B695600C8B0FD8E1D7E811F4CCFE16E3F5795C24AA0A0167E305C28875C8FA9389B72F79086F6ECC16C88B0783A5815FB6F77CDC7CCC38D60E787BE9CBFFAA62EF959A5E5DCDEB6255C8E0D2E01FE05EFF9E78102BEA2914057D36E3D1B48507AB6B17640470FE3F17A8B6A5E04E53456C5D9E50F745DE06F9AEDF4BFCF31B0C6ED12133654CBC8DEF7F6609E122C2E4C933E6FCB0F3D8CCAE8CA0B10EDDAE8DB297C8B3231C89434A5F54D0128C83AA6FDE29AB70CDA43784545FEE9FF6ED444F888664DD22B2E2DF57CA653B6D210E6B40B7FC21FE06390CA5D5E60F58AB14C4903D438AEEFB17CA4B998706A0ED6A4A6F474B1BA1D48CCC1143C84A8D2E78DEC11618C76B6DA28BC39DF68AD24A407E10733DD189D5DAA904BEF88186EB6832145940F15B8ACD9D18D4F17C8D917B09D54F25F5609D3802077442390ABB60B51A741C5D4425BD46789E6EC1E7D22D56E7F34CE7A072B630A6951718C1363B8796D94EAAF8630D2226C67826CDEEA71E8D136F3642F79E692F04B05147E40CE0C53CA08EF0AA6A57399FDF3EDBD54566E66EFCCE16F0C447684F5552BA36B2060543FC13558D8D89E18637073EF6A874677A97F9FA0234B140061C7E344BED60971E358449ACD17E58E6D05BB2144D74BD89AE97A759143AD845B0270BE670B1E1E92B8C7B65FE16023F530E4D0CF7003D1854A50DCF49C29AB0EA47B2E3BDBBF52D58A9147A9D123EBC56F11BBEEBB29D731AB99275EF3A923FF708783CC269206ECD38CF947347D1E71AFCF9DBF291B95274855CEE2AC256183D97B26EF949A950CD1E40A51501F867A7BD383552DFC7B97771767BB9FD7D1DDDD4967BBF79A453324CABCA5B20D3FB0106DB97D033FCD40371E8ADACDBAD78D89BD5E90CF97E835518794FA3DB2B501F2357577655B9A3CDA3652DFCF96BAB9C5F957670E32E586E51FD89D7BA87689FD597088739D87E1246DC2B51ECD54292510A3B43CB25A62BDE914EC3CBFA99DEC70AC23C0DFC969AD941A6994A370F90B155D254563FAAA7D30673C0634753FD657588EC6603F8235E917365DD89325251B21B2FF80F544FE7384FF62FE52C4CA774128C895152CC75CA63BA8F81E0130C93B59F940B718802124DB8D07DFDC24BF2F7BD9C4EF61741AF2B6987566224F110641DB7783FAF31BECB8F78947BA123FB00E1B6D13360B16D07C3AAA336DDA1B65D4C2F21BD5CD4BE9EDFAFA7845972D60CCE3403EB5E5C833F64C5145DC08E7B36FCFDEE8730B944F5A23F9FF3F0D1DCE80863B558D8A35B2AA6527691DA50CE6FA39856265ADE60838CEC9EA9873991DB56FEAE8EEE2ECF43244965A13CC1D230E9172D82AD23D6A6E2A377A7F67F640BF3A363BC81A786D12B035A3185533704848528FB45958EBAAB303674FFFA568E7AEAF463D666B6021263183BEE81E7292877924CFDEEF6F8173A1347B99944333F48B36C8C5F8C16D226DA3C9DA5F4CE77F00E442D85C73E5780C3628D9838FCAFA5D1D3405F1936CBCFD2C52D4E88DA9C90DFF285E3E9112C03CBA58647E6B4EC077B1670816F57E2942816A6F342132649AA644D14F41ABC5264AFA70BCAE3D679B86F51AF2447052D078A0EA56390B372A1513BCD2EA466DCB5A4D86474FA1E26BC0A83F585C79AD6217BC96AF771F74D142BF5E91A92844C54E766BF2D3698C0E4F6176ADDC79E974A466FB2E0CBB42C53F59B0DCB032CD37561BD246ED52C812EAA36BB9E5B32AF39B0FC3775F9AE120BC59449B7B77B1BA1A5B60066C858368DD5AC8EEDCFE1F83F52C5362EDE893B7223ECB70BAA66DB29147B80437201FEF71B05FF251035F88CAFF42E82A4302D36098268B74F4183D4D19F13B87E98337157DA5EFBBF34F48CA4065D3E3BACC83833FEEBA57346D169F1BE6A04C29C82FD225A3F7C685124F537EC0E10AB85834BA3E654F19555CB9746B74CE43A2C78B21708C3BEF87C1E88F0810B4EDE18114E92A4313B4EAA05F60937E876DA2576332AEC38CCD425EFD511A39B9B4BD4CF3F2E2709A05F939E5FC597D4E851202C9C2C5713AD573F75AC5490DEECF9DB8DEE20399706B1929A4E89900C49C24465E0809566D9C2EF78C52DBB42F9E227EFD1E1A72CB710BD219330E69CC0049367978AB114D9AD7F955CF0B7B3D325CB35165000ED29DBE0A1956F1459583C697CD19E78B5174E4FD2CEC108A7C24280A78A3EC9397164F6003FD85319804E5655A879F663DD4563EF9982521FEC2079E8889497BE9201F6D7F2460A8B2DD96510E0E4C83C3B193C11FD6B4B684CE8563A5380F2E55F474A60B6317D0967615AD4FA9F08325ADD797B79E6F5DC72AD197F5F61EC88BE5FBFF9272319A494B608F347CE155667A59C3009A1450F306193CFE611CF705492A30FF56FE7F71D732CCEF6364E166CFF812ED2311B516FA5690F2A2727B1850F2985D48255E8C47E711502A4B4A970BDF70DC3447F8E2887824B58AC758E883F73BADFCED4640D546351BF33E8F1E0B1BB9FB5AFF0F8BA0954A8E6533D37C03048EBA6A55B3C5DACBDC44D39877D3078AE95E445BED12B1A503AFB2200CB18B08B46A1196A9F57AFD564811C030A445FCAE72E55E85B76FA050134B2EC23113ED04043DBCD0B6FCCEBDC9135CB202B84FDD74511F9E8F0CF226E14CA5C438C76AA5C3C2E9F32271009183EE92A995819DB90F66899BB9B0C7ED31DF41B68E52AC5BBDF2339F715E43FEEDD94F57F9230523033417E4222797F7625B526670EE6BD3468CCD9BA4A1ED264AACC250A82A488346B2A5F926F2E78A8ED8405F858EABB029F78142A74BD5A82D3DD70AB126CFA3BAD7F51B9E95CBC8CE75E77A4A1B6321B7747778CD035B3BCD448EF1BBB6FF75528A7AE9AF6224A16F4F450387A3EDBC2E92C0B19C222E35C1A57EC3363B1814786E1D37D792B37826139AFB381DE04C07C42CD3CA78E470C2527C63DB4BB40A4B7D2067F0F4805B658B298092F0873D095A0EEA45639299D60D2B58EE19034F942DECBF5AE9A616AF72375C12BB7DEDAA6A7DDF9A4837373D7B51960B30CE9CE73B3C10DE32A78639A9337D9BCF1527A43688BDB6EB8BD03DCAF10270DFC0E2F0D22C27E32224332734CA261974022F7EC176CB12BE6F13621F320365CFBB03D04CF29EFE93E91B029B7B26FFEEF06FCE57D12BE3902EE2712ABACC3D27CEA35ACA1509E4D0864FEC5A5B41A0E03E1DEC6F2A337215CDE555D66F84E3D6755DDC1C073D0CDCDEF88A4440B17684B8E0AF9DA2B284AABF610821E5C2C911942D0BD1C659C1EEBA8E21AFDE3277D5073B9839957703802FA276C82CC66A00A86977B8877DC051194514A633B34D362934E850C2717A0BE5924E86AADA33CF3454632C68A10AEF8B5BAA1083E9137D2920A25F969F540B95DF59916C4CACC455988F46317756CC937EF0177C0FEB3F23BBD3569E8967C49B95A3BF6D9D6D7C7227206E283739FC7741E9FE64EFA0389FC72FDAC81FEB7507B87E6B73CE0E7C7C54061D488A0653959B758AFF6F7D1900178D7C1AEAD0794568F92F8ACE98EDCCE86DE108A0502C4349C4999831DE00E808390BBBDB65EA360FBE98B74A9C59340EBBDD6F6521392348577FD407890301B0792728CCFB88C5DD472ADA73759BC999A02134DFB1622F61D8B7632AC77E3A980B2CE566F3D530F0BC21C7519BFB00BBAA9C85C39B0CDC5F8D1BA12B7882FE0F7C756E7556743525E5D0EC8EC1BD7D7AE3DCADC68DB60D7AA13CDB29FA15C0A9AF890F1875E39758621279A9877D9C69449C41392CAD988B8DE458EECD98385F79730B5E26C1162415D97326419B5FF92AA8C13374391DBBE736D98C07AD32D638BB44E677C71105CFB572496880C167715F9BFF6E711ABE5A832538C7E6DA8822DCA60302D159C6A82FA48FF8773E0C6FA173E13555B2DFBF47B7D08DBA3574446BC0A78D3008E441D1552150D9061254B2F3FC5A1EF3E38433340BB59A97FD51F468FE8A92BF629DCD0029393712F3536D6B24B88668AD6A4B3A4C93A6B141FA8E5863CD5980BFD7AB83C3CC5D2FBE80C7B167DC928CA95736580A52960E2090CD8768F593BB04D448B64530C0E3C2568CE3A2C6420F81F74DF6885D55078EF1B383B020854A636A78A9EC1384F74EBEB65F5A25FFD4147DA7EE40F6257C7E34CAC9270EA278B6E608A19B568D29E58DECADDAD33C59BADB9252993B316B0B1300793D69853A6B903396", - "rnd": "083457D40E250488A60E7634A01D430A60E8572BA88AEDC5544918813713A0B1", - "signature": "63A82320D4CE09C47AD127C5BB7F6C2DFF1529CDAF9F7456FFC2C6ED905117DCAD8C087AC0D89E0CE961C094FA9C2EDE279C65E699D1D17EA695988FA1C4983F7E1F18862AFEB2EC9D0F5B0C11B2AA0BDE957C40A15BFF97D7CBCF4E59DAE9D5A3C9F87DDDA5B9069D82CC1810208092BCBA1C4373F2A83E1915809E81D8D206EA78103F68663DBEB179B02883CDD333EEFE6D023917C6F2A46E5A5C4514F57DCA7B624AF4E7717BD71B5126E6DE2DC96524302C0804D7BE3ADA64AF116FC6E738EFA6E65E8790B40EB1B48364D215EFD61F7A44753A95506E52C99CE9B456DC938592F135EC501B3BCF82DA69A1DD44E8B3C1CB8DD513D0F3142C80822C31BF752014399F8179760FB67DB6581CF3E6935A9BE18B92C2DBF189AA4667FA804572AAB4E25EE9D1A7A0D7055CC6C76D1D663D350CB71AFAB1DBD0CB3A8BB71B0360A0A4DAD0E23A1EB5E459686A02946605600864B4EE0F3ACEFD407B6FF58D1EFF0C75AFC141C6241DF37602486BBA58BCBBFED351C268214B204EAF8A0C747F5FB7AA43FC5A77A181CDBAE131871FA81F76306CE084CD144ADB67FD658C35C0916C2BCF5B892958429B65DB347DD831C9B80D07D194606365DCB370484637184D5DE0AC77D09EE1D9B22D09D6F894967B43D97636E624A44AFF12FE3095D7CBA9A03ACAFC5257B82080F2D8AE3E18FC0DE09D017B03AD6BEEA4EC3840AC8542F8CF93108F8CFEF82264FCDD2CDD86975B3F8FDF1F582208268A76E6C9FEDF42908D5278A2BFBD3FD5D5DBAFDD5E2C2B9F2EDCC1C452963849CB34EC51008D1BF6DA50A0D19D82345B788C0540E17B25FFDCE8D4453BBE751EDA96A44C75FDD90081857DC0F8262A307B34CBECD1565869A314D64C09DC9D4A8026522FDFE4CB5B8B1105DAE0DB66C85BB4321DBE7684EB6B6F8587D8320C6DB38DEDD61896ED51AB0C7F428F19D255C6B0FDF58951E5CDB1969CD9A7934EFDB9C82E1E8D2A59C9F79DF1AA93E5071E3FAC7319FF68878CF249DCBDCD104616CCC1C1FBD785569F558710441B31CAE3167A4CD7DDD18626C54362962032E6B7A276056196FC22967E907C320A7AF58CE3F501C4CD318A707504F1C259E507A0D47D258E2F38E26A5341347A06B58BB0BF21DEE65F556AD488A736D4C65C82C673C060D7A6A0775CF8C39AA131FD64DBB17B72704B7D1D24BC5F84083BF8A647EBEDCFDDA09114267D77CFBF399BD92F3B2AA72BBCF7DE9D69BF90A4DE2CF824927DE2B8BDF46B109ED60851C59C448ECB443F00263C9C25F46274D17C294CEBF2537D8FEABD78EEBCBA7264A5B94508E0BF62EFC21E06E1E2FB1444C5AB6F847F522F8ABEED046D6DDCFFBCB8C81FD05D4D7F2E1BC99BEAF8C1AFE3E05B3690FEE4AA375A3DCB77577CCC6E3EBE8A987C6D7E896073C0CC0C482546B539B4FDF04EED8E87F85B00BE43A60B217E96883B91D7881AA0DD3EBF5B0D08D0854ED4278FC902E060EA16FBC254A508C86F7AE75493B8DDA086E9C1B217F5C91197836688CD2D0BB8E552D1137AA7EBD5D560538E9BB6B41D0690B06C66D1575B861C8A7D3A884CC9881AC3001F300DF34762798589F9EE5C92436153D8C732559B333D698F3EC5820E8AA5F2E5A769C2B47AFA275FE474AF8137C7019AF2E60CA75EDBE48F81A651CE6BABD3374C0772A8AC3677B10F547717C96750DA448BD9C7938C66CD6FB75D732DAC831ADCE9176D94856E1BF60838D09E6323A27B1609F9C121F498D2BB685818A00DE7BA6B2847C516149F356ECEF04F34EA483546FEEB12EA4077620430C39DBF47C05EED5ED587FFF592217CA95A2C3D1E6F6FF9FF209F8B30A99D56A3977A3317490B2B001F43CD8DDD1D8FC16A3FA9B4315462845B995D2AB76EA539C7F04C316C71D600E1AC4FD5C8C6343BC8055F1700B40EA2F1ABE94BE006013AA261F0720AB799D0FC6DB5E9A4C3C5A7F82D70D28E410DD164E3E461A46E81FBDCB810848BCEE06F883325646E1E2A693FA5DA7C25EB21C4EAB87DC787A2677CEB6A26E106FE78E118FF54713E00597BFA528C2AED069A126DE3746F0665E17580630F702FABC0F1CD7F57AA71F638D8AF37D3D9E0A7E9055DA3DF86483F25DEBA18CEF699EB8770C78584798AD8028BADC59D2AF9AEAE37EC939116105F9F64EF8278C64DED3FD433A7B8820916BEDC6B7A75698ADED3FDE88675428303573070A5A3851F9F21EAC780FA8AA4023E3911487D852A5377435A5FFF9C604B5D95B0968AE0ECF4431B103FA6BA71C4DC8173A2DE1F79DDB60D2D0C8E5655D09444291692992D99FC48F2160EC0ACE4C49207BBB76D7F2A85E18102B95A514588F59F162D33CED6180703EDC36C8B339488810D2EAE9625CEE383271C7172EED6B5486960E8991874B01353593D7070BDEB7A9F9229AB770EEB46378D57D956DF7A8640040298F700F4415BDD3A9615A465DB01282212CF1AEC4B0B8CB3B17E5EFA286C6C045B439C749FE1D45075D8E7A00FBE8448FCACAA153D69709D9FF2B97CDB26C0C379287CE64861ADD789D0C8939A1421B085D6234CE1A749DE3DCBE8E0615CB3BCDC6A81A5C49D9285745F1CA8A0641E32688341933482183E245C1F9CD28028C38A23181A445AA6EACCE20606E6F7F1DF706883CDA52F3F2B68DE26DD3771E950032CC7200C2023C82496508282CD3BC47FECE5D97CA1CE35744D03D7A428B7AF12B0CB8E657C0130F8A3A254976EC8F7DCCF3ABF31F4B0B3F7126FFC4877F3D1A066D26A232FA9992161225411ED7DDB93C35C6A377F30CF22AA392D5C4FEE4F73C9EF6ED3A0279714523B1918651E9B0FFA550F161053EE7801397B4C1849987C179E763ECC60A4E4C536B7E2663E4C726714B02EC3169E8407BA592B0EB846F3692DD44651EE084721CAC0FE1CCC302707EFE24664E05BDC69C83904ACB8CF97121C7E5C6DB27EA28E77BCDA55D2BCC1C5FCC552AB83BCE4238CA18062C2D23A8B800C8209C3A4CDDAF11616578A845566FC289A8E3C88F554C4926071DA89326BEB259A0E1F6D844EBF7B281F9FC3743A65499E7394634818E133FAC664FA0C88F101CEC3FED8792950BF6E4974849E1EBD27691BF5519B702E1AA4B3DBADAB5DFA34FB0ED9D4A9DF4B6B63CA7165E2A90827408C482D9DBC972468584F42376004E78BE067009E43304BEDC107A4E2A89CAF185C9BB7E9FD2CB92AEF363BD796F3604EDC08A7C545B83702D3CF808852103E013BFEA161AF250BCC72771D0C484DD55541723A210D683B998CDBAF3D9A5E71786F1CF47B862251B5163360879AC0202D334951545C5F71767C8F96A9D6E4F21F28434D7E96BBC5E3EFF3FD020C17233E7F99B0E3E8F5000000000000000000000000000000000000000000000000000000000000000000000617232E" - }, - { - "tcId": 12, - "deferred": false, - "sk": "5C3F57C82F4018917A01B668F23208C4BEEE1FF17B97DDAE5BA686EDF4086F541B3E7A058D88470895EB66727B848E72C2FE05AE7A5D4338647A6E0A09AE61F28B5D75DA59AAEBA7CBCFB6A17103BC3EF40CFFC9A66D85F1AA21D5CE22EEADDBDBEC46D482F2683C4A44AFC1E5C6B0E046D9167FA67376811D1475DBB28780D41A16089C467221404AC106925A026C52348C9B942194404148984141308513290ADC0451C0C0285B4469E1B64812110D82260D21096D13030A11197218970503144953900548464408292EC23606CAC2309A00461B428091264D40020E1B986520374E6018609CA04C4B248198368EE1C4252017065CA801C0903050A62D03150C1C808DD84652CC022A1136490882254A486DE3B42D83102403297123222681264A1937020B212454304982302CD1206C12126D1AA085A482401A415183920423870860048003114952222D0189280C42814B460A143288623489A2264C0BB98D0124489B0802130752114662233151830612139390241864CB10819C48290B358D00A32124842C11164EC3266A44C04C0147704A3030109011592440E4426E11922CD31625404660E2B611C2C000E4A4510A39448AC865C39005C0A285D4804C2422490B106E18387261A23022228E233042DC1080184046A2180218B009CAB82C030129D12868D1B85080A4680C312C833080034190A026721316040B4042DC0646D43880C8320010446A21C244C190081AA72548B68109000622A870C498311C110013266941941042B081DC266D84C80952A62C0A29664B02224C124223154A1A284D1C0666A1445290B245C30871431489191070A14200128510E2244253226892C86424B46842320DD1084550326D84440A2341288B36060B28705082000914415126641AB46D9C800041C28981105111B26412804820384A99188C1BB8850847401024251AA651D1C02944406904850454C691CCB605810220DC98690AC791C4C26D13A2890A2905CA400122C551040542028008641620581866D8000619B60861A831090390191711A2A6501BB748E1886112805062B409503204E40262DC180D9920311B3370498430C8242D14880982B62CA2384C028010C492415CA800E1B665032132DA842994446619228A58B210234440910231198369D9940D94422023418D93380E9836669AA2911CA90910026A58046C014508530810192611910228CB28200AC004124100C22852439690A3A48988B0649CC86C4434852E62EDCB4AEBD86940B877BCCBC6FBF83AA99A4C6BF23931786EDFB2C9938387EFC6D4F381053F4D6461C83F85E8E349D4A2411BCD5ED5C0E571238ABF9F7AC812CD9BE92D7347A8F9DF636D512B1D92D90453800C67EAD0E95A26515873E392E3D88390A708ED9E85C103AE695585697764CDFAE7B0A3E428B35BB8BCD09897DC00EFF423AD004239252B2AD7F99F8D0668CB25614E8693DE853B58832F2CC1610B34A395B5132AF970CE61B1652A4AD4EC2D6F50B494BE61F9F69804BAF1EDD421082E45478C3EB519D64A36CED075C9ABC6284A1669EBAC62269EFC414CADC894EE3BC547918D9E09F5D975DC44FF1D424AEDD9A542BAF18F2314785877C0D77BFB8B8571BE1F32FD55419243AC32827956E148C93EA58FF3367946A8624767247518CFA8B91D8E51CAD3F3CA037FD871CEBC048729D068FB28EAA0F54BA39AC7BC048687FE90DF0AB0C46CBD86F324CB9389BAB145992D501BA22B5B52BACEA72F5540053EF4AD4FE66420923BF42D4494F91744864020301CA0A81D007AA41B0D4312D3EEE795235ED6170361688997A8C7BE6B14C6EA8573F01FE220B7A324E345D4C0FCF47C5FAD14C9A6B3D4CE035BC8388D67D7EA8E41D73484A5FE705FB740F8DBA473B3C3CC71FA1C7B7D3ABEBB953CDC85627BE0C65B9CE9E1AF14CB734CCA3D754ECA01D2AC793F440E3CB1A107B8BD5A79C7A62C9551EFA3824C2228BCF7F5AECAAAADFD492FD881077BE153887FAF77A9A599260375896CEEEE679FE57D6F2EFE84E5C6475B5B5E89B68585EF297CC9225DA3AC6749A285D5ECB08DB79F737111CF3E12314AC4B2F58588CF18393B69A70C877DA7B7F61D06E21A4FD4175D7C4EABC45DF964CC9A85134F44C420DFD22352518074200F726623E1A6355D42A8AA8A3055F2DA37675C1BF0F0DC723C46AFC92B0C709C87BE871AC6A77D69991C594E858289C1D07AAF2D3D9D2E26880BFA9BE0BAC7D2ADCEC92E6F6A0EDD0B207EAC4B50351FF8784E618D78C01A2E2EA07C0739411BDA0AD6E1E1138E6438E15A77F9B1EF3C1531A647FC2239519D235536003EC161C590E2AE8572A5FB0514A305DCF31D4981878D1E98491E4792B27F574168B1837DC65BB54F6EED043B0FD5BC9F2B88A2DC4994F7AB6B9D2B49CA9DA86B4219355A8F48357139CBCB0A49E7F7B52317C5B41C28EA6A19378D74328E7B707E1E28917D61B13A4B640B4A4595260B81BA7484BA4BD7908F98066F9A73E99D6A69E156F2781B0DE8C0034C42331ED63AA2089197F713D817DBCBE3303C3997210B71DFF9010E1756DFD058A0F8E6A8441898D7D2D0D5F6F29249CAF9A0238BF830F07FA7F7D2358A3B16F6F8802069E9AF743EC8155CDBFABBB87ECB09CFB2532E64BBC298926F658EB1BD96956062ACA01FEFAA0B3739952FE8C48DA6557ADD22197F0C75B5A1163BC4EF95647FAD212744366756F6ECA10BA522E593C2CC9A531AB0CD148569ACE95E4504BADD4D8F3B640499556E5859317018F8CAA0A1E018D2762498504F03A0AFFE5E86907F66D0618EB084A5B95AA165C80369EA445C58CF1918D2195052F549683B1E95DEFAC344ED5DB485305748861356A5C8DD25434D2C44808776B63A86E10C8D6F459FD05951649945A933A29A0B4ACACD4E42C75D8D86D7A4030DB5CFF889C21B0D5D170DB897E52F7C3328FF54EC3013E4FC76351E0A1189DAEBA1B34E1FA713C2F8FF2D6534F0F9E6D6CDB3A2DB4C53DC74FC0A9EEE1500148360E25F6AA0AAB245EFE013FE2B535F6584612DEE494940E6171D1EE563780F5A8A137B034B52FF2B0AF8EBA81D98E6ADB4403057BA7CFA0DFB8EED0004F2129218A28F0498047B4066A483A80CD12CF63DE39F654E423E991684BC8B21A27A7560DA41E36684A52A4C15CBFD9A4274A6085AF2FE3F300B6AE9D47E258B59A9C0D84CF0F8B9408D29336F5275416D5BF56762FCF43AA19F3D49CA0BEC7D13764E1927C81165FF418EFFD1BDC79F634357C9E1010BDA4C2FD9C00CB50D63DE59A5DB9300BFDC1750D93FAD1EFCFD80DEA1BFCF6E166BF1BB5EAAC18850BC0A87362816841E99F200CF3E1F148AD952D19EC6EAD27506EB29A30F1B293E72C854A36F5772660D7212EED5D3C03BC8E2AA210735514B939396DB79A920B2F3A15B1944FBCEFCAE7BCA0B448BBD0B78A5F9683F7E3E204C48709B55AE14F85C5B329F944705683D7398646572B9BD6FF9AE15F35472B1CEA6462AF95FFCBADF998BA83CC7A5B33FB7ACCBE87F7E5DE5D2DF2014B6969ED60CD18375D8118E19EF52265876286DD9F30280AF2802B5E9CAB9F57F6279013E030712551E1BD5E7", - "message": "C21140CE91893B598D56C376B32C1924F76C22CDBCA81116A4CC916BAF80503E35367E65A4BEBB05799E0FFFB3E1A73E0198AD5233B5A94076E48C4D8EB4F89C5677575A6A1ABCA4BF558265E988FB30192020A71DA7B68D91E98061627A5BFC04F888AF12C15E2140CBFAE9423A2AF746EFC8EAB0FC95DF266A1CC93CFD6FB93FC5A0137F411FE10BD1A4B386DDF7ADB3BC5ED2349BC1A40C08F031A369F3E47E80C63AE7DDB4A5C1FC8572A1A1E7179BBF332FE2EE3A060087F033E6E1DE904445556EF4936CE6EC41C16FA1C12CFC3CD71381FA372AD4EFBBCE53C3A0E6826B2634CD9E24EFAF402D660CC229C2CEDBB4D4CD644AB77812F492E443AC14524D8398649008B110A578CCB1AF3DC881A01100D8F23406048BC4D54F3494270DDF154A8BAB62DFDC8DC6016B4F423CE843C7786AB9F468970E43C66FE43ED6A7E31BF3EC250C49197CBACC5ACC15485133B98D0B3B0B28D3026F97F47B5B965921CE81979470A2D1D3B476E2C76A07A63842CB7A97F87564B2885DC7DD1CCDF29C94C5D3BB8094FF342503B170DA5B5F377510494E33EEE6A13C18286FD6F7D765E6BD23C93F1B498B19AD86DE17A1CAB0CD9ED5F333D959B78F13D7CA1F18E1ABE2C811A50B2CD54A047C278CA575B513E24888B7A3B92DF8632FF615654D08403A2C53CCB5ADF8555678AC61D1BCE685283C1828581CD73694C75304812BC3B1DEF9498CFADE50FB70E1D47BEFC2C0B633784128FFE73A83B84EAA06A868362AF49C24927319FD6965170F929F90843FCDFC6DB856B74D028BBCA6F847B6128073740B74018DB2A03097E04DE9C5405E46F2BCBBE9AA9EFF10251F26BA2E014564F958E0EFCB318AB75662F4B75E28ABE3602649FB777ACC54FB3F33176AF6928B97AB127023BF6D3BB8336376F3FB50593791B1C18CDC100CC904AF396D42EABAD9E7B2AF81E27412E7D6D888869559AA79A05A55B16C73495B945398D1551190BBE90C4CA5C9FA91E6622D00266BA01C9C808E7ED3A6A3E53457787C745B7415D6FFF426B2F52B081F2DFC5451A7A1D310C8F3466AE88FB010BE42D0D119BFE3B77EA7C73FB0E58FC7F9676356B4A376284A95343E2B937EC634D79785F20186905309F51DC91EA6FC3172FE6656E4E856C7C3D3A04F36C073C5905E57E1C139F7CEB93B9CFA3DEB1E368375EC074357922E79462CF9554A8EA6EF5AB43CDC80A65F05AAAD7717CF0DEFCDF59AC5666320459A33626898FD7967B2B4CA4BDAEB2C1E3A536A649C2D62DBAEC5F7CEB1415AB9A58F27099EE1B2700F4AA57AABBCB4C4C44B07C11CC6D4C23C004A4B6E88B1572E75078FAFF06A4215872A71F09FDCF81165566399882FAD1FD7F90823C7F839BB951988B5C6291AAFA04A4B73F49936096D1366C16DED48FDBC55D80A19E25FD39D658AD6E66624CB17D086D02D6A75B004220627CBD7211FF06E1CEAF5327F261B79DD69493B2B743A31988E0C386CD840CE3D99097A4C7BCFD31112DA5FFDB05F93089943B57E41BB0FA11852F0F30180F749F2E3DFB92412201EC77DE783DB49EB7F0039EDCF8AC02078C39E5F9BED9B8EF95E3A469CDE934286123F3E6233D23F77EEDE8F8F795584387FBD4D6699335E06DF1B561BC1DA5D8FC966250EF9A0361004F8CF4CA26E14B55608763C220CED384E37026AE34470BE2A31FE8D0BDA40F5FA7072876CAC3DE2853A60319888C1C7F431E93A953080777F3BF8DF5099F0B6390EC4E3D3E26A3771989B64BCF0F923114E27FC917A04BF544669D6E3AE7A209F1C2292ACD2161C2D7AB49AEFD5BDE912DC8ECBBA8FD35CA071B5EAFE97B126338B397AD90B009F1AE28B64D6A5300A30676E95D5AEABD896FB9EAC7130FEB9DE8B4020DFEE5080726379666769573E1D271BFC5190B273AB18682A8C72039448F3CE2EE44D314B64BF26872157F1FF252A1F74C446ACADBA246E103AB43F98EA9BBD59697D693C9CE043FD3D6C981929A3DECC0AED2F064C37AC4D8ACD2BA7BD64F3B9701AA204F62A62F44CF9E46772F9DE665CFDFCDE552E730B826067FED48FF621D30A1207093AC907CC8434C0422EADF1CC0037B385C7C48322AC3FC0312E7981B9269520EBAA6693B182A519B196B7C120982C4D11B048692AFDB270CE7A89719EE656FAF0CE8AF84E4864CE30EF80D51C0D3BBA9F1867102186EE75A3B4DC1551D609326BD3CF5B53CC6678C16AEF19725524AA90DA47A818C2CEC029DDC5B4C125392008F32B41B8CB95E7C080D3EF46185368689D3B8AF6112696158726E8B426F994593631C6BE8D47CB653EB93F59E34850C679DABABA935739B9E9CEFF96FA267ABF2DD38F6819E24358F51D4E4BE080E387BDE3DBA0B9C12DC69ADFA0D1A0C0828D051FDAC7CF0EAA557B747BC01DD3998A9FA0577DB47FDF079A5E77C337BECC70DD6C1F790A832715618F2098C8C82411A3D8906C3160FA2499E44BF7230BE59B0C448842E53C622F0C89DDAEA378EBE6559ACF1C5AD9B566AE04B66DB3349E3E3EC410B4AE7AAB72F5EA45E6C6A8284F52FF2BC14A235F1DF937BC90AF581A5270A457CCC83EE5815B1940BAF6AE9D6B9566C5CE870EE39590D9F394FB078B35A43C956414BEB618CDB2CF2DB9F0F6ECCBB8983B8DBF8F05096B8A7E56B3332B46F9AAED9A69242DA1538D1613EC011B5749482F33D22F4F2A2FCE38EB576B5BC9E31ABB0B4E3514E7CB0DBD0EB934D7A476D6C20FFC0F61B5B63CD07D0CF9AF109BD048C4A6912E0B572C4233E40566FF4B45E4077CF7992BDE619D7D416B130D41A213203423E95ADD3E06953A401653B911E92006F1B3AFF07CE790EC0C4A5DC27C73FB5920113565EBF82FA68AA7C6F18A898CC9D68AB59D6C4145584F46D66EAC20E10608DE439DB2F691A7501C32C240DF33E3B80AE25E7A033764AFE75B7CA080C2BC6907D1BD6C44D3B8E830A1A4A6F540AAC377EE6FDD4B0ED99CB0E285AE7AD8F2C0D8B78089F65AA77ABFAA89DDD315926D09F77872839520885BB4C7EB4D7793BA7F78BB87ADB4BAEF60F3726C96345077CED3260D927139943E2E3EB149076D32161F12248D604130040AE3BD2A5FB6996511F3BAAAA9D9929C48E8EEE4BFFA44B09DCB4DCEB589C28ED0B66C03D6DC261D2270444B1ECFE26DE1DA1623CF00BB76E7930786D3BCD5553FD9798B4773765E0BBEE57A702B44A452208A8BDE01674A42B3774D3B32DB08EAB4776274348D6C65F424374AFE295EE043B8AEC4C00AB73BEDBFD4DFDC5330F52F789A8A24E70ACF4F4BE8B8A338028856298F62D038634F02875B3E5DBBB0DDDDDA8200B2B50AD21B7FFC235AB9C249FE329B8D300DCFB2794C3F2FB9254F4C6F4272658101BAF2B6C070A0EBDC9C41B61564AD0820204F4004026CA7C1928B1FE800F6FB795F63DFA4AD515D0FB77BB9E7F04CB16F346F396DDFE0659A966411CEAFA2585629A662161C3D8F59BD1FE567073E25A459CF8A584D2420C179FBE13CAA1A2E9DE2C02515F00A3EBFC78691FFA2DE9677A1BCE8DE403A174EBC53205AFC57E04E1E87459DB5C66042ADCA926472DC149A56DD948B694D24285EDBDC514DEC8A5AEB03DCB679EC553547512B6462752999A46E4686B2CB52FA3EBF890AFCA894D92FF5D99C76B8089D644657BB4763E7E7E6D9F9E1C5BA50C4A0526F8289B97B9F0D73C84A5D0F729D4F0C400290F24DAD4113C47847A14CF74036ACE85658A9A549E8AD941029FBAA51408311B290FB4C3BC5DB325FC587BB07D87358BAC4DED31EF3938C3F88731C46233DCE5C54D0B38F66AD352BC798DC74ED1D844541CE8E0FE06682448BB3E8FB07FAF7A1FBA8255DB99A8952EEB38475D817F2716E23401BDFCA05792E6C29F0FF23DF4C0EB58CDF8EF36982EA6ED9E5E0B0B1B4A3E81FE64606578887B350221C74C1C898652689CC96598E0A862236528C2D7E8F4564C0EC77B1353F5875E88173090CA42C720E2F40F908A90B5EF73B96E0FD9CD295258065F40A7356CAC69E039A687E5DCC338AC950246AE526E182248B091E14EB1BDB876A705FFCD7806564EECFECE01BC7A0FF1287EE71ACEBD654074BD6302A8DD286489A256C329C503E9617D0FC35896F623A49A1BEA223218FDD919828BFFB7CBFCC226A8B2ADA48B3459095CE7BB3E6A074962CA64C9FA9B22550477A5096CF2BE54BB01B29E3F966F0ED5D4BD647DF240CE8BF8E27610B7D3D936E234138A1A2DC6B155BD8F38833255308571CE646947388B3F138AC97FBA7880EB2161EBAF8457A321DDB53ACBFDAF73ABE5DB2054C468541FC31E61C0F89F0AE84B2632A5F12650922338D19B584E4D855BB20EC550DC116417ECC5E4E9C66ABF40931A4B34DF6DF4907130E5CC6BFC88F35B97534E5B8B657167856F1AF113542EAE0754D730E0E3055D10EC4182CB9D4BD0D5FD1A895D57F7E17C15C26341B16D727898094869D958B1DC9BB37356ED8D47C26CA270C69736109D310A39A4E1F8D45F987048E50E4D787DE11083689522864F67454A85CD0AE8E0FE46A751C692FD2F2C087973CCBF17A7283DD180270EE3E85BF037DF27F06811F4159425E4A0ABB290BA77791AE24FAF246276251CED06827C9BF272559DD9938194661C5E4C19AE62EE6D2D9160845E729D6D0183E9A66A31F2620E4F0EA10DD808D99F40B23C9173FA1EC3473874DEAA4180F69BB19C6B33B6CE9ADD8D9871B1B456064F2EAFF39408B32054EA10F08D3F9BE78052B22E1F18CDE0A5C09A271A63AD5828F21E363901595DDFBB840197746B67B4B2E55F0C8F085D64D904ED5692DBD8EBA874E8A740AA75B1CEBD277622B9AABDE0C9F63C8900ADEAC586D3771B1C9CD2FA24512F29587EB921E81D2CF322EBAC7C08632FAED3100994020FCF5397A9DBDA1AA90E6626B653E9950FA90A31FCD546371EB4E876EDA332C745EFBC684E3181176EEFF821E38ABD5B969C7642C0D9E1BC27A1C93AF3390AA13059B173BF802185EBDB1BDE816DD8D7FFEBBFE844731107537BE87FB77CF27ACE899FBC62BD474684CAC5E1E14538101170B7E5B3C93AD0061430F6D6A640A1CCFD23C98DEA48A7C163A17F43271B9472BF26082EBF77E2431DA6BB5508BA264A09090CD9AACF3778E6952BAB7DEDBCDF860F80DC8ABAC5FA0D644D21C18E669F5CFD30D3EB1A723FF292E98561EFB76AC88CE36F49834739ECF7F41D0F3A1BC01A9D9B3558755C797EDA6FD1F4A2E1F1815C5BDD5E813CE83289594793E11A5264DE3853E138B7246A31F0867B79C3363F880E199C709E52F17C6E1FA9B6AB6F50DB4BB7E921898F75E85DECD42E549098F2FE3F506B3DA08611756AB83D0CB82EC4A4D00A5C292DC75E84CA11246476E7264CB66EDA33F5AB5604124F50EDFAA26F1148954BC6D5A95D198460D", - "rnd": "D6D63A082F55F3F97ABF83514C80C64EE2ABE267EE9D3DDBAC95E82C02F47F73", - "signature": "500FBD0C82A2ED239A7FB6001F7FF85D631CFCC95ADD7112D6798A8C9074AE1E30FC71287097F72838B3C9138D45E725F5441731ACC95FC089B6DC7344410CA9C9825E93E8B793A072CDDD51E44B6219B03F0EE4E6D4AEFE227E433F2598CCAC766A1375604FC70B7D0700CD7062CFFCF8968371019FCFA37989A3C82B988872CD9C0673BD30C6DB85CF086AA7078716D541ED528EB99E11D630B448488E38914875B016E49AAF947A76F1242CFBC0B340544724E8CA8B108E2564414C0BBE6CF4699049A160079FA29E149FDD514A10043AE2D81087FD14F6071FB4EEB8C28D7773F1B262892EC36C5CDF89FED6BCFD3BE3C837FEDA2EEC2FCEA6BF034E6C056C9B993874E72F70E2C02DBEDA64B373FDF447DB182B0E916C2D86B72C62264E19555873567CB432A03CD352D73B790380A204C210126070D98ADD3C47208F9C589B31697A225B627539BF30D04EAB58D73FC0E90EFA57AEA118E19EE1AAE8D30DBD50C7FB798689DEDD4805D984FB1EADE5C7C61B69DE7BFFB7EBA9AC92578E5782368AE47CC56D3D2BCEDCBFA8200D3A3A47F274BCC4F9E8E82AF3463CA573204386EB6515290F7C2FC620F411BAC62922FC5020937D15A8DC2B6F5AA9BAC4C1FD8AF71C945ABE6826B30530CD1EA5301D41C36602125C740029188DE6194E7B1F939A4127ECCAE14F43BCEC068C64195C698331BC1DA6763B8ACF0BF55CE6E0C24ADC214469D0881D5DA1871ACF2F13D5CC213EC4A966DD3126347ADC4353DF27F3AEEBCB622B015A53E1F48D7CC136DF6CE5C78C4C0395EC527F00DBEC163AA8285A5D61E162D45665B3EE418F48546028EC57EC1C7CDE3AE686C7F63EA9CC284C8BB88CC70340CF8416302A8A984A3DFD6B71E58CE70712A28FBEF9BA1C74068D009FB89B431891987F9607C8615350C162C68AA3FB6A0AF7F86CB99F1DE4B2604545A7568472A43AC43F7309784B7CE5EA6C6445FA8EBDB130D8F585640F7130C293B2D0717451FD6D9831B24F79FA736070F85150BFF683C44CB82932B4056FAB59BA8CB4815A475ABD582AEC3F453E8A2CDC6BAD7296E0AF633809410FF490EC324ED0476C9093B23C8E9516FCCAA4DD420431499E769058F0E6B4EBAEFB396504C4ADD6F13DBE0738D08C0E151BEF076EE5DBFFB3EAA900062C83681A0369E382EC491C8DCAA92BCCFF615DAEE43FAD2050E0395CAC5429D1F5861CC55DFD0A589039A00338B47BADD08C88B70267D5FF44DD3210E042E9245E0DE60E2E4F7E94D442AE79BEF0DCCBF001F5BC12E53364FE31E7289FCB0A8490BCBD48D7AE55A7E73D20913BFCCA3C6C0E80C4A5785C1B49969F066517D6912FD442FB6C08C979D66024AF717B00881968B645977E62123AF073955E87FFFEAB6184016883514C3D54C223047565616BD16964C620D8E81439CF007E0C4828592AC60AFE4A6111EA5C8F7B12559021B6E40DC80D1A491CC4CB5452B13D5B0AF67D5BA39DA6C39BEDE362F900F552D070A5225ADEE1C7AE51D562DA1C2B323812C0ADD419C66F1651F1F9155E98CA7B43FBD61B5A9946D2C567B6BB6AA3A3649C7977DFA9A08780C1CCACA5258120EE558BD724F46C1DEADFA97598CCD7615CFE7289A8EF1A1914F5FCD91D33DD28D301EE4B925B32AE836644BC922A5889BD21262CDB56C7D2FBE952A3BF887C6557590405CE03EAB83EB7DE7570BB1C21AB894D03CB9E1DCA4E9B2FE86C837928F28DF73DD0143D0D01A3A997D1CFF01055F13E7D9F2B06E4AE94C60EDA1EC07AE3EEA92B07CD2D12D27B99B7F604C613E5E718B24FC476063776FB0452863BF9A89AF3930E8E39EF5BFC22689741C71799C9F9105AAC66F7B2D87FF3189C16E9B5846D54F7901708B436F36103757AEFF20992F29A2D534460EFA5FAAD29533BC9AF9C545A3BB4007D704964DF30C2191293F011972921D150576C175D19694DE37282559EFC6C40697169E5365E0685A1E6D87627E645E4349D50266ED451A2B2157D82E34136EB6A1604C134680425A26F0E6A5D6F7A70CE42A5D7F92CC28B224C4E732FA7F72357DAB8CB3F9F7FF9C4D8BAB76C60E8FA9D5D6ECAB93191F9A1C55FB3C69701E190A735C1737AC0E1C898AEF75093E9CFCCEF08AB6A9A05D6D7D70CEAB428CBD0DF463919A9585EB5C057F09A9187781B93D9703B1FBF50EB04E77956226070817FCFEB54269B1DD0168F4623A1B5A470F4508070DF49BDFD2A09A58597994D44009E2F618F38789F4E2D810A67ABCD85D3291025D3D32F601A7F94AC374B180E557C566C5024E438B75FCB6FD030D82C0FF3BEC1A3EF43DC52226A24665AAF95F0215891B51A032A2FA19DA0BB7D5C352F5D30E0995EFF3892A24951ECD0D60E380A93154B1E65231C82640CDABC1F543D783FC2CAA774176C97E2D7C37F4B597C6E976FADFF330E174E9EDEC798DE6040FD9C33C5873E7EE467705447A2B7463F70D0A8E94D85B4588B76C8BDAE112E37763258D5614CF31FED87D3A60F64E3BC2AF4C32B520D7A3FB0E29B8FA728C1E7DB497BB8125D92C08576AD1414BAAA27FB77D359F7A9F2CC9796924BFE61006593ED211514557DE045F566B7958B695CED35F61BEC34517D1948D6FC43202BAE4E47D37927DAADB9CF404E4310444D13CC5BB2555300085305CA20F41D7CA34E7998AB018F8D0C0BA641B9748A8E5C28349D452C793063BE377259793BA06A591B7E9B22BAAFE6C5527E697F0FA1822B1F7EE6E3B78E03F934D4E230BCCB93251E7FA8DA673493BBDFE91F0701D0551A2DD23784B14C0DB20481CEACACE8FDB33A113CA797F285459B5B916D64153575BE5635404006BC2B4BDE00AA446EDE1472E441309BC47B6B12803DD1DFB9197FD476789CDFF7F895A1036A0A784E0656BA680E1904D577944B3BB170A411FC99897E8C7B3158074B78C85ED0A666E7B849856E4EECDE042ACFB59FD8F3EBB6EFE357492C67EC0807F34750E0D87C05F54B94898C2B44899343D8E231BEBA65D487906608729752E30CB519C159D09AD388AEA97B95C260DE5BC926996FE15D01EAF808278FF726D8CCF1014279C7E497D9D0A2323C4627008CAF02B58A1B4B98D5284F06960046E645DE11ABB122EB74D4BB6ECBCFD57B52F8344B20C0139F63E40D4928BEF00246A5073047356E0D82D942EFDD513C7C4C923E0FCCD96F4FB46310B2E679E20E5A8AECC1F1F7CBCC9EE6D50D4C5BD34B63C4ED6B501E07CFC861DEBE01203C9308A0EAAAEAC3323A7376BCF0FEA404EA5C7E3DB216AE5B0B50740FC708DDB46AF0232074011A31485D636A6B7190919AA9B2BEC7CACEDEE5FDFF01151F34363D3E4E73819C9EBABDD2DAECF820393A4C657A7E86A7B8CFD2DAE3020611172B33383945576279A7A9BAC4DEE9EAEFF800000000001628364B" - }, - { - "tcId": 13, - "deferred": false, - "sk": "89EAFDA81C10DB1C89321D386CF95B1D71AD02FE23B6957C03F87455FDF391E4D343E0617C8DC51797179C4E03C7A313E052EF59E92C4E3298FE763BD19FBDF67F711002E8A3C87BB5094532D7DFADD24B0F81D7AA0415A3741F074CC5DEB048280FAC463222D466F245307F90463C8F32F892C6ABDAF408F24E77D491EBDE3008264960260900B32413A18521C02854A40D142831C1889144A64D4A262650A8119AB2610C112ED2A27190488A24296820420424C46102B81008446923C74948242563962C0A3050DA886CCCB8281B03080AB34992A040CC182E84A251892890C1A4300A194641162E09162021152A140981C2127204B86449C244A4088222374693A6091C2731CC0431E0B620831421403630CA282608960C2382011B9021DB008ED0120A0C28505406322314701A308D03934D522065421886029908430289D918209A8245138344D9120E61C03021066A11146924800D1B130C0346865CA88810C42963248612428E58428842104522C06503A748044700E1902908A60818214102234691C8905B408020406EE1803011B5645C382A629044C2C688DA268E1139655CB831A0142D9BA271E23809CA92509B182E4206211942512317720A212CE316804BA820D28209093644DA86480C404A428861E43440813851CB2808004161E096514C8621A2420490280A8488115C90018CC60C08A24449460DA220481C4382232028883642D4482221383183820D20196009C76D531872E13046DAB8201203515A34600C218E48344D0A338193328E48448E23038D12C601E026424330701B920523B72D030184C0384800A96859A241E4460A62C2819480208AC4486090415C12205A22200B0342CA1849C3C24100156C54263194202001284E9B364E89485110A4095B36719A3829C9C22DC3B49184C4110B068900876999944563300518298E5806814392014C464D54064A54044DD2C02C511672DC2029A0B8648804814A880890B46824070C42004514240CA134110C94240324880018601A9440402642D42692A1082A002904E2022C02434A101825C93280548604C4B02404832C08C191113624D1142084A284DA926D549089593249E3A645D31229E0400CC384285BB8448AC20060367018044D6132505B108C98164101C1401C310422324E4BB46998244E92426AC3884020457162A47199102C0BB54123053052B429D42431CAA82194C08148A040C99681E2927009918D0930021928264B9204CCC69096E43EE739A97CC8DE08ACC93A37FB78A79FE7F312523D3D126A16D6534E8E30B959F7C2FA43358521C469E17281ECB277BF2D64765EF3C880981C7E6EB0324906B21B146BD8ABE45D266A00D0DA92A4108339DE4AFDE39902651EE4854243E40F851F1DF40527602CD4BC0569F60661F9D7AF6A91BF095AE3AAEE25FCA7F4FF4A8BE0A17450724C185AA491AD34F5F711975F5F015352635571C973CFB584CBC14C3AA4A2BFD99FDF2A5D21AA89243BE26E129CB27A7648ED31B223D84B26C445498CAA5FB7C32017A6851FC630D358F19417A547DD7F02CE18DFE123527E9568576C0335527A98233A231C8C22FD4877863945035DCB68352F5B600C4C77985FC2DA58D6633D4335BA0A3A821CBD30ABFC841997407F197EB409A506D94626485FE82B54456D0B90B5EA914B229128FB7139B35AC473639EB6923C5923E4AFF31E2DD8B03EB7C6C71BF52C2817D623054207F9D90CE42E2E133F7B3C3B9D22EC26144D53B548E6B00638858F729D24547F1C2880D5FE830686932CC7EBBDAD53EAA5FB004A2F56B0F1AFE9815C53EEB5E36A4D8F71B3454B48089CD2EADF1CD1388F26BD360693CA5522AE019C9458505EF370DD8C92C3679F99C42F47660CB92A5D59D60036C070DEF762C5FCE7C1D3FAB61D9033500ECF16CC40FC1755A3DF254B8CA2CC15D159BEC2C5E41725F5315C9C172120CEE0D10CAC83DAF7BF577F01904A5FA170FDDD25496AE392C984E377164D1963FE4A1F8DE2335F62FCF5CA8B99E195BD20FB0FEF35E603E8D54F294D8FB348C27EA30FEAF3C983CB1DAD3F0F01A2EF2C56AD970E566410A2774EC0B7C840BDCBEFB66AF88A4F6499DCB77348F140124F5828EBBADA7738BD82B11F5CF2F5EF2D5D9D7CA358696D8F617D0A0B2D0642CAE5BC51C1EE97CA82C5A7B7BA47C116C547B9D1534EB9A31F77237D3EE80B80FF4F25C1ADA4CCD4AFF1AA7F160FBCE089A74F808EAE95A0AB8F1BDE8D6A7D8E4A1B9018D1DD85502E9C067F930C56602325BF65806B6ABB80B661E6E2C4F42C505A0BFB1BF032F878CD95E8047F4F99ADF11890A30FFEB5177E05B3EDB20436D0E4A67971E5AD3E89C97327CE8D607399A7DB3AD096CE0FDB5960DFCF4AA1B7AF16CB53B0019A1D8B54D5A5E1280AE3DD40A82CC4921B174D9E7AAF2F2373386405930847DAB5F7D37916BD0FC30F7B99EEFDB53AB3896BCDA41425354D658C9E2D1D073261AE06129224F3C24AA70CDF8310866F251416FB25CDAF6A4595E8C0372F4E1B4C71FF849469AA22A46239DE72EA0EEE058F34EA26B37EFF47E196DE20AEB8D6CA6165293036E583A22EB2E0DB7417C7DD1F8791EC983B6373180C80506513BACA28BB91A86DAF3A3ECC66DFAA13B37175AA2EA94A62B657ED51FD067237BD42311CC455EA30C9C049AF6E653121D0A564145B83B486554B53334DE3FFBC857723905EEAE772DDC921077DE070C12BE180CAFFE5F6617F63A9BF6F0953753C263062F823292210D91B9945C1C07E8FEA1E918DFF5B36621BC4FCF72B862ADA232327D7EBE8BB3054B862B15785D46E4888E30D58E047ECA68DE71C23BFDA1763790ED89D4647677A774AB9E5E0E07D9D4F13767BD31760CE24AB718AC9B2E28D45E090A4F6C54148A8F92CFBB7EE44206048571065C6FDA9997F353471295862380872357582E0082070F7D1FDC8A451C4F8EDA08BF5CA6A981A790681DA0ECED57CA18F5F240CDC96592D7EC9FDDFC764418C28A23B2B42FB2F118DF262B63C522F279D1E29868F3BC39A008779CEBAF929D944B2C5AD09BD0D90F09DD71F90DBE88E3320657333DDC2ABFCE4C6208B5E444812404E6AF048B92E2C5B1ECAD70BFE5FC62A645DD153307154EFBF9638540E83F09F67D5AA23273F250519FA85BBC0616A47829C8D7DC5310AD5F421BA7EACDDCDF3C8371944B8CC33039DCE698473096EDEE78681F1D95A3C977359F8BB29BD40D0AEFAB12FC50B90EE1998C8E393EC0D9F1317CADDE2135C4805F517DA6E761DC617D93D053EFB702DB318AE7D8022876157B7E2C6BBA2AC83D580806526EE14B5BD57CEA1097D871DF6934EF8D7F925ACBAC4A34744001F1DD9C0E3607C34E00F9D74C39DEBE0E646F6523F3A12ACBC41B48B873844D5317DCC665FCB3C8A3C3AD6FDB835C3DF8F23C6F4B04C863AADF82DF4C5035A46B2776C2D87178B91816C664A68B7E9BC6B0FCC8FB7FEE5C025E00777D9724F5D83D0F6B9EBEE89779069B278BEC3FE347796A7328C408647E374697D23D0FFAF8280B528ABFC4F5508C04AF3C98B1C8A5C3868B1C385EBAA910DF00B3847D4285E4701FD1124C3A8170A6D", - "message": "50DC983A4F0739C1F9AA61D27AA4C66876FF3CEEF36C94041AE506AB1858ECF2F523FC093721D2817CDBF0310309BA54CF7BDB80C191534CE5CF5B2189B69DE9DC65DB35F896E35280FE7F47B97AD475078F61B542C857D159F59F1A73527FFC23A9ACD77FC2E331301D491862AD4185EACE7408B3C093883C5BF7DCC7146FCA17E2F4FBFFBE447C981476D551932C50D1672FE31C96DF18A4AB96C43E7C46A6F39BAC8FFD13EC19B2919F92D83734D21F36580EBB6265C471F20EEBD8F60E38A74F0D86664B872A75EB45825B510AB3976EBB4CB4EDF6002213DB843D6105F714FAE3E3EACC41DA820DFBB16287D74C774C4DDDEE22338A33F853A7250938709CA80A329E82FFE54CA96EE87729F875BB018E76D2A1A01E2D8166EAB28D83F1F573DA5BFD924D06C2207F8F40600C99E20535A9FB2DE4770407C5EC88C105CC38AF4883C2DA7BF0AA8AA4B619A426F26DEFABB85ABCA13EF79D367983F89166D79933675279898DBE8F669D6CDB143A8148E41A27DD656C179BFD4B683980112810922EDEA73B5209D395BF28B8D9F4E89FB2040AB97669C7120E8DCC9261534F8F5646D0FDD9344DEFD39E462D7E2629CADEC98DD0A07E56632CB8DB8841DD71DBECA7DE03BFC7683FD4AA38CCCCF3CAEA160E70D22F3B3635498FC54274219A0B6A132049103FD84E9CBC0BD7B39FF2F1FA4FA9DCE9DCEF0DF0EF42971505FCE082EC6CBFE5C53ABFEA59AE1E4827248B27DA4770011CF8D7D3060E4BFFC2A74ADB54FFD82B19CB41C0ABF8E1B3C313FF3A415ABD4FD73481C497D9B107FA6AE33A62E25C275FCD81979747369EBC6EADB715456AA6E2ADBDB02637F99B63D807E1979D2270CA157FAC009FFD95E5A8FC907514E0024C7BD88452273DDF79823794DD1B47B8FF22CCF547B621BB3210D86416721D9B6DE4FDDF562293960BC762225A2FA5BD0C120392AF4DE7495A2FA7E6BE48A6DCA492C382D954CB03B57C432FFF7CEAD9F696ACBD4FC22D3167D633222648124FF6629E45089C53B9D05354DD7E4E1F8D51CD2ED1979D3E42D7CC1E2D0D9B560A59C17D1F093CA62567445B8D0405FD860341BE7C526C107481A881AFC1BBFE2BE059E27BD523CF0F4A813DA812C0EB597BE0E80CC737633B3D5343D94CF0A6A4ED6D4DF05E7866EC4D85B4B6A74EC7C581CEA0685FEB982E4940F43B101D95FE37E5F7DA856C271B4848F86065AD7C328F53F6E2EFDE89E447D25C8694AF3446E61A632480571977B08F46E9D0E001A6C789EB45637B189B0977319EE4D8AB8F31C841665443BB7A99595E087A935C7971415E3F3E660E2780B8673BD1B2D10E97C17C2C5972E825C82AAB71A3995371B30350B6E64350ADF59AD93C6984A444CB01A2CE04107CC1F744828F1404C25AF4D1BF76F69D0F398F813CD633E06A4BBABF7665F3484273794753F67DE02E32710D1CD3CF5E04416695164683F6094B3A00704336336710A48FD5FBDE75CFA5C7C0CC3D2BA54B2A02AC985A59E7034F42316B4C86F6F23D4A47791B8907EDFFF06F2E87454B7CA64CF63A2970B1581DAB5E02CC74C015F6471189A74C98203DD6090CB104AFAD45FEE00D9BED3A4ED3EFC5B4AA44C408FC213236F2917B875A922764BF8447E2600847907DBD37287E041A22D4F3B3643AC890F9E70FB68C8E5ECAD215B853ED1299A75DA9FED18D1B1A45A91E09E625653D1C12725A7C0766F08E4E4A5243C3AD382CBA1818A157DB035364171C7D1DAC1525597C00263F53C0764A55AC906F7E5CC69B27923B8A9699139899D0C8DC3BE4FADBC1C12073D3544C53A337F0EE9BED34DFF9B801A7F1E61A9D74FA93A0131A82469B2C5CB23CBF5329392C71B13688922C70DBF6BE2A95081D745C33277D867F14E927772E19A4BAF0762C3DF9038FFAA8211027932E6B6D125B7557F7B0C955772674403030B33C976F252997A86392CB54E4F0D2FDA6892958A7E2553C2916A0C3E55C965B4E8D12E22539B895C5BA3DCB9321C66A195C820B9B7FBDC51EBDA8DDBF5D62A05E5F75AA5AEB5A2995C5D765A874F9D2F35F2148FDF5BAC3386DCD7F624D5B9C20E63F8DF3BACA3AA480005642F633EC3C0B2B1AFA82879EED68652525FFA9961B195BDB6036DD1F7A1BCA8493A82C9D92F27E0CE376B67CC1A0C3D0D944556F0594FE6F93C5DFBB170F91B0FF483EB1393E697B6EAF2A1A89EFA03FF1F42E0CCCCACDD25966DBFB6EEDBC0E913F6B62E0B5C507512139D36657D56FC14DA8D31D22F06AAB1F66FF46BB9DA88391725E5E618D99C84C2FBC3479F1C06522B70B953FA0039DC9C36D4F8E5480DE6E4C57173A9178583D12BD268E346F8CB68D9A3C7B16D0E98A98F0D9E5D7DB09554B69E87D76F2BDF386AC0F898D36BA9D5227695DD629D735D58E2D4E6BDFE92247B3C5EE0CDFDDF6F812A5ED05BE18C63F45C4C1FD51091057F55C53E9B5052C991448A5FCF9E217E866AFE0392F2A32E11604710B83368F59C1E7EFF7C55CA7F3DF1D2FF1F9DD43B6D04534E063D23FE55319465DF90BB744399FD93C99E82E9A8F430C6E0F86FA5D616A163A7BC9F89B2488DFF4F73737EB8C3F77F33AA520E780AFA95C6D646E330D3D9530F64383B19213E2BACFAE4A39A079D37DB9079AF69B0D7DFF7A8BAF0643AFA24171D7655FBD30FAD49CBBF4FEAE24E71D6BB1E2AF7F06075CA240E18DE87E75C4ADF95D87973E2E9BB71AFDA26920405B189885B8734F3ACF5EFC9EEBCCB2EF9A5E5E1EEE8000B6F16A55FFBAD66658402CAE3FD718D423CBE7DE874D2F98F1B7D4D309C2616C0A58709E8D961B22ADE64ACE84BD69C36E6821805B8A58268FF7EC1BDD834DA30EB16BA99B873D444C4368E074BF90DED2B1575766701E75010B25CBDB686615C7BE8D159C3B75C6C087F07A005A32B5C2C883439915629CC607E4104DFDCB3CBE683BA67453A656F5F16CC80CE57DE61C72C8A7A4247E0364026842926AB72C4FFC5F7E414E278B6F28681718C79E2F4A777B042A1B391EE67CF49CDE167E5D09848FAB14C85D9777F3C3DE42647F599E465810C8C0B1DFA874469FE69E7E3206AB7C98203D76A38743C5DBFBE1922C1CDA3B5C488508851CB0E88B6BE5DB3CCEBEC0D5919C34DAA3A195D146CE9090FFB284C1DB4DF1C6800D34541719441D150CAA8B7292DEA09C17A93A4C8992500500A4B003F048794A32686F3CD0F14DDBE25BD91F9591A46288B224C63BF9E97C7125086720FF70E5C920033741294F3B707546730FC12A090BD003602D426A36A0B066202DBD5128CEE8E1BF9AB0338B135209A630892DD746362572283ECDAAE09DE874B4638E791C76FD3D99703F30422B9FFBED4BD488251A83BB376E9ECB267A30D9E175B7B24EF7F2051252F1C9F15CE0C709F3251077C9EA6B15DC710E7C0F908A3A308D23F2A8EF135C4B520F869997A97D1ADAB6056B096F99A95B3D0A4E", - "rnd": "6CE096FE72575F419023A95742CEAAD2448EE8839CFEEFD44D24638294CF9B2F", - "signature": "B8FBFEE9FF5B04AC57EFB8A7E0F76BFD78981BEE1F0B8E31D6C3914D0CB4750D5AE1AC7F9D9DE24CAA2A39E35F9172C63928E450650415D7F58673E4313EE8C22FAE0DA969C76822C112372D659D77386A49FC828482AAF77F51D8AD86419753BC7CF6BD49C51A108F50044C67692C96D1068A9ACB274808381A51690B008E760878E0BF7DA4715BFFAADC5CE05E0680C068C9BA3125E2B5CD9A3028EAD6D612854E1312382E4914D2CABF1DAA02BD1F376195E0EFB2A2F469B85B9EE42EA30E8B9F64FF75188B5B2C5DB13E23D040E16BA75A8A265FBA0FD5EF34977F6F5F3F557467E2840D62B474437613915691D90845ED8B14D891B1737B702B468F57B2127AB52D0E30176EDE5E344BE133929F9A852E2B733519E4272C878AF9223517C6118623B13BC862D349CF9560A39B8C339B2CB1051D295DB1FB7C3380EA7397D6EFD9608993F31068704EFB574102289DCD61DC17BD01C6F35B09F786C73CC695C4EE8400E06A66B6927D7ABA40561E2DAB073F6C25E69A02495476C60955CFE3489D5989E51F2F9566FA9638148A6680A0B17B15B682E829B44CFC5EEED2F4AB5170D2C45B9A7DF1DFFBEC2F2E603FA18FFE9D896A3555FEFF0C76E9D1E38F4BDC5EACEA8676FB9AE1E9F179ADDCC9FADF89CC323DF4D79C75456D54993CE4FEEF09E9ACFC499B9427F94992156D194B98D1E94E23D6A1D7389937D877A94CB4F192BECC54F88C26CE04EAC8F95B2D6752542C1B9C256D1F9EAAB42804151A3C06E6346343B11937A0B4BBBFB456C91631E323AE40F95C622E29A6AAFFB1460F0B26DE0BD144390934B4F9351BF5752E09D43B3197F40CFBB0E6993461767CFC2A2011009F8F0215C09FA727E6259594FA7C2C81748493BF7A96754ADE5B4EA7D79C88E88268A626F205E29CF52BF9E5D00FD0B912A5BDE4E040C84AA54D02DB95DD0763AFF0BEF9C791C85007431631C641EB75FD142771E9B17C737E6DE73DD50BBA8400EC8D444ED7765437F9659F612D9FB65590F2577150D82DAC01DAEC110D29FEF6C91FAC37956496ACA5D675C865799ABE5B2E38FD9BEEF3AD238A9AB067A9F6F35E8BD00103F46D2881A356688E63E5D4577E9840E90E63150410EA8F6B6DC53D6B2BF9CC1C17C33C1F29C33D77F5D363E7CA6CBBF2F93993DDEC69499523FF375E5C2FFD220A209F111F41BB36C8C1B88E2D60815C2E76DB7138B9E98E675050D42BA4EBCA9CE4FB75921818B1A88674010B91B851E89BD6563993C3C739219D9A4ECBC8ACAAF924D558936BDA419C4A833638EC6FEA4AD5868966E02D55472B1ED53509F18D3BD0A48BF233A4A2F95FDBD60BD2BB848A8B33BE76E357B268E5459E872AD572A2639BAAE21B40477A8114BAFD4F64072ECE59867785A6BD203E0EFAC7ECC002FDB8CA9B00E99BD97D602184AF64CB31FF5C0CCE3088C2B31F5AF581F9DB66B00D5338393EC94A7BBA026CF1B3E62DBF15EF7AC27345E8C89F70F57954A1F63129CBA3E93AF6DB16110BD702BEBCD44E5871540F28CB61AF300B464D6EAC0E96B0DD5544CB4946C1A4ADEBE6635FC0075C554CAD9C5DF51DB0250FFD5738B0FC5A2DDD8473C947C6F309220AB2342B84AF9A143EDCD190DEC46D06B93A36E30862F0315BD793E35BD3817B7987A2F3F82CC033D3CB9C562059D2FA3A22F1CF2A2324EAF07EAF810097A0C5E179E2D427FAACFCDE12ED675433B99EE73132F8831F5B848BDE3B26B80D89A44454BFCBEED7AEBBF72F3C523966A5365E53131E6F0EF5650C5AAE29B1C830BA1695DBD8C84445D9FC7EBA466A4F27B0C341CC61BEE266A5EF78D463B7296187E68BDE84B1D7A2D9BA743631A7C00DC50F077D10BDAB7A5B3E6B39181C123D80027968910BCF0A7CA61A5EB9451741524F30527FB98FF8080DE3EEC8338C9AA93E27E8F0B66021F1569F3A50F4460C6E81172EB7A3DFDCF62427DDC0B2A027C50C34C864964FDB442F080AA78CE75C1128CD89F1B156009DBC9BD4C90CB3E610B7A288CE1F9F8C12EFD8972EC67A81A9E3AB0D27373C6CF037816B0C7B90298CB0A47438F6A24E414A46960C645B33ECC00B687CF210A9E174C1A0E4AA4B930F508078FE2D10C31C0F2865527F8DDBE298CC8B208EF44046CED7BCFD77877877CCFE7DD2E87AA3B59F1278981B32AC349B3C985748F843D0D35BC9B54C5FE65BEAD70694D9533DAB3C806989373AC7A04D53DDEDDF21DB1507AF2F6F3187CC3995B549B0E939F1DC1DF83CB9BFE0FF3F6E9B1CE9F20213A37B7C5619F86A7A584ED93DA99CB13EA11DAEA9159CC5F8D33BCFD8C6EB63339AA8A6A401A0798D89C6A267FA9B3B63A8FA0F1A5E8B780EC519DE08A2F0337DDB4E91261BD1DDFD8D46052CFEAF04A1689DF9E6CC0167C1153A1429827C91B4BF4A3E473836D571697F592DC9535E8C423D491FF27FA209CE589BED4599ABBB4F4DC2B2D29EEE6B969CB27A446CC031AE1FAE583E2BAAA01DDF395A89CCFAC421E57B1A7B161100B2399803B25454B1BAF195E1D99CBF4DEB6B55937D46D9239C427DEDC47D415A6192964C966125A13B697874F2858BC8EC8C1ABD088E7267EF2428DEE0DD7D18613D7A386A110A3FC92122AA06F060075984BC593192B12F65936C2418F9546D461113667505F329CB2E01D72E262E943816DEFEC1CCAFB8B826D384AD4A6C804BD2C419BABDE30288425E7FE75D0A03FC934A46C8E78B1C8BB7BB7853F043CB25A77F920C6DF59D96FCE7450C2F74C780ACD9E2A6BDF6B292F0833DED5CA69B44E49B12EE58753627057AE5197838DE8874F3EC043B9EA842469DA41AAB790C24EAFA44AB663E658FDA278705425F8AAAEA30392AA2B6CB03AD2DE65DC01F92AE94C47B8F340D141A89592B2F3CF206634F7E7EB5BA19A712FADAE3F303F603041C118B69B6BC28992E51DE03AC6ACBB0F67F50519BB9628589C69EE2066A9209E2A7906164055261FA1C4F6B88208ACD35719A87B1D9592704620A1CB44205369370B733E55B438718DE5D5C937D0D7C6BFD0B1EDE5EB412B72A602B65B65B52A9489A9C682EF46C13490577EE75D608E5687152D30E3FD8395AEEBBBD8F87BA2C3A5B97E14CEB8BE9E1C0245CC06693891D0D98CDA6650B31F76CC0EBA3DADF4C24BED3753EBFA5E903CA52C5910553B21538A7E88BD84BEEF4F1C8CF4FAE5318D3CBCE0C3661B566F141A2857C55680209EC10DB3E373F700AD79F5CE17C079507A9D2A41796D1EBE6372791FBD1A5D02A4443D6E3DA564F02EAEA47B68478C5BE3280D41C581F79064F525C7B8185ADC4CAD8DAE0010A1521333E5A7B7D8E9295AB273C495D5F747D8688A6B0C6CCD1FE040A0C0F131B235E797B81ACB8C5DFE1E4F3F8F9FD0000000000000000000000000000000000000D1A293E" - }, - { - "tcId": 14, - "deferred": false, - "sk": "8D075246821D7EA00B94C71D0F38EC9D10E3833618967B6A3F4106C1BCE11ADE01189A151DDAF927ABC50845AAD8BDCCB784ADAC0AE98ABF74334A8B84C4410EE3395EB3EDC7707579E9669BFBA8B94BF92A6F21F0B98301CAB813376916F4325D4E625A4BEB70061131E4C49B51308088B5183F907372CAE4505C8618A0A7CB9A2489594492A0C850E2024E53C8400CC14D59042C894010D492844CA6200BC1010C38704C062500342D03B960D0B829E1902D590420124532A2B6455300019132858A2041C4A411A0B670D2100E24C845E3024D884042C9222D0A2710238151194346A39484E2303209196E9480088AC24863B820E1480A021464C43009E2302A82444E013004D91230C948322311724910641A084401B84011038052048C0144700C19048A240C1CC228DAB84C9C2232DC125162926141440A8B080DC406004816910A08860B99080AA950218749C22212A4444CD326425B4802C4860909188D24234120B64198442C50206C83845159142AD1A88C939469A1064608472CE128719A962100030EA2C2844318625BB0045C96101A27020B41481920911811494CA6891381615B084A0214250CA8686422880A934108A84114318413302021A08C02C8501090311A880CD43246C2320063802CE184401044500022248C3846018184A1440958C42821A43183B6849490700BC104941400A086491B088621C165D1400AD402261CB20023B02CCB9031E1825024478518100582268991C2519AB66914B40C8490811C112052486159866424C809199971A2B0614C3042A32632C1225020C0315B966521400DD3C689142250DC048810448D21257144A871229341113112CC40486032085AA40004068889068E9A28720AC149D3B2701A290C89B45100A644E0A48C60C26462426418931024900508274E08328622958558046008184961384C902888C13032A2B208C2488421A98D4AA0448CA41001030ADBB430D4A0695C122ECA986141B46D21C1899C324ED3803020148818434D11334C10463144104412852514322C040560E1A4302281900A8840A318841C166522164DD38284A0406210270E09B54D1BA29182120883C24D22B94C20488162105040C66523C908580882D03480124471A42605CB924182160A121131E38681200248243380A2185010B9459A947188346864B04C89A005044571C23801D8C68163C8404C202858C86D58208C0A2692148085E2A69104319202805062C8308B0289E14284DF5B9D1200801F9330A9C52EAF589FDEBB3943D768B4A2A73F38455E941B04AD502BD93D98B8F074A5206F1E51950B711724A31B8A5D5F93D1A62A60E3F69B6D79EE6465CB1792B991788C0DAE36D7A3E40564FCA01B1236E46250AEB52C61BB1E32BF69760B8BF91E1220307F9B4BDA5D36E782B47EEA703A636387CCFAE3A8A3434678FEA1534ADACE2B944F7649D0E271F520BBF249D7EB5334F3350D918F031E3786D6D544C2D2FD8B624D2CA3DF07FDEDB9D99EB3FC0144512274396E7EAE35E821787047F7E1139D8E432EC39737CF09A103AE25536097088FED5D1F99C00BB59B221EC99CC8E94329C4B99300DB5FE098397510D39BA9CF9C2D7B44FED381A9EFFCF476B3D46F9E07AFAAAD20F0F4C447B7B5F7E98E00594286977F68B1F16B62E5F0677BBEBFA7F4CA31CDF786424423DF47CC0FCA816A5EA563DA39A91617F1485DA0B3B48B33076C7B690471F9E232C63B85F746617A94576D14D1AC7FA2B0F4EA8D21B69BEE7838D836846228CCEF7EE6E447120BDE1C85BD260298DC883ACFEF197EEA08322EDD0FB9ABEE7A99784A64C2BAB8963D606863295492691AEE0C3A30A409577289CEC7CDD534C81A0E85AF6D09DEE2C2448411F1362A7CA8AD22CD3BACE899186F4E1441F007EE71ED53A0346DF06AF83A51899AA2AF09012363336AC70192BEF60DB21D16598712687E34D35CEA41C1FAC4C6FD077684627574ACEE398207E6272CB3B3F4D30DA8ADE34BE6485421AB0ED2889386724D52D01D9B398489E367811652D38556A4F93221E7ADC8E91DE765D52D18A6C57E090D67ABD7B210877354AC77317FD2B5E9F3F9A8221B008AEB1605AE9F1533979C01B255D398C7BB88FDDE165D2259989AFC39FAC51FCA6144F6F184905598A5515282F4DC86877F20C0730357997209A49BDFC2D683C7F783E4BE4C5C8C0BF760D9F465886FB96726202A972B6DF71339D3571AA24327248A67FAE26ECE002FD83180B54BEB6EA27A3EBACC4E58F85B698E9657789FFAD02E52D064DADB24C4573DCBEBE160D2F5424BDFCDDA0F1371863A1811D7AF30636B6BE554EB094C591F1238DECECF80114DF69CE5690AE12A8ADB99E149C079124D2D22A2D04EBE4556D9C933C677B8E2E2F949784B68A6B6A6EDCE89D5B46F064C8930E4EA0C7BCF8A0493DCA3A1E2B98BF80959D6DCA1D95A10C785505D406B08E1D4C5AD69189E3CC1B9C1C01735B5E977CEF1798BA8E56D3C341BF122C842AD16487A3A14785F8125C3437AD2D88AFBD6EA26C354EB4FFA8D0EA9D2F39446F3726AA4140564DAA8A1131DC2B06BDD85C80DBE94FD1934201A4AE8C7D184DFF38B35D7F0DFFCF28AB234313B666E25720E22F2A4224E3BE58F049FA17AE14D402B5BF6CFEF6A5FD39BB27A02D5541A475F3D3463D6B1C9DD2683A44C254D4C2765326322C9648B07784DC19CE4ACF2502A832EF41C17FDBBA8343AB0CDB442E7CA78CF755EF07369A454D35486C1199B0BA084551C5C8A34BD11FB3F96F0B9C8AB006562D1D35BE72BE6D1482EB09809965FAAFFB52EF603B6F6E7C0A1B54817AC49FD1AC4DF9E12261DB2032C139422ED2698B604604EC1F60486DD3324242114154BCD6A2FB1618B83056DCADFCCA91924E8A1E0AF120E56702DCDF8DB5D33869DB890A1A5291485C8B75F00A1BB731FC818134E6EA28A5BC1EF2DFD456642C1148782C6AE9512770A78692F05E4BE7E18CB6B9F1B4BC8CDD286CF2D0800AFBAF0924FD9D99B667BAB46BAC3C2460EF6F76F3FB0E8CD72A1D80FBAF5462D6749659B5A5E2CC75EDDFF0568FF13177257E29D8FD811A247BB3F5B234BA144D87FD84DF7320F997D098F72806AB8DA468B2240D4FA42D8E4BF786E619310BB680C059C0F4E307B99073691686A209756564991F95D0E87FEB1990F46868170175CE36BF7E41211C9DB9752EA68C629D367415F3B93E1D1B98117CC667BEF39D5A2613E540E00BDBECA5A7C6AC47D37BF91CAD1C1B0D24670D058D6E092B5458CD69FF46311A03545E6E87B732FD0AA36DB4DDC31AE9F24D2B56CBAEF3531DD75319A1ADE1D35E919161A0C323041D558ED600476149B0D260AF7B69DF0EF8E1229B8BDFBC6E30E1B5ABB0ADDF47E9A429DA3F89334A6C534D028E9A03E43C5E50C7FC4BC7F9AB095A00C2A6C0595435EE9FE191F80ABCBCFB66215815500E8831E51D78BA483B3CCF504A2FC6FD2052B8E541D0F25810B750BEC85A407CC915CE622B7BAA1BC8C192F6EAF3882660962FFC7F0419EC9A9A05F734F5C11AA3CF563311FCE4733EF5B2675EF0EF8B98BF4294E671C5E644493E98A1DD51F226F9D77DE8C389E", - "message": "0C6E73105341AEBDB88635ECEE0505AC5F28B7521E78658BD77C7D9091EADA31483F8692B3CDC65E961A5D340510983D2BCC56762EC2B7930126DE1A9F44D816BA3AFC86433178B59EE614D50C67B1B6961CD46901956B45C6C9C42B836544ABF0699BB7C62E5A0036570B9A077D5DC5526280E4EFC88056F1C3B59E32AF0DAA801C53692C03181601C43281EB5D087C68F6DB9010C4C743D3C7BADE455BC468D8F7F710FAC5BB2DF390A9B70B541EACA1FBF9F717E6A1772C4D2FE7300CA7AA7B3DD50A09AA7762EDF277B13CF49003AFEBEAEC0640A5AE0101BA7127A81F6A42E5AB9B57CD988CE80037BD95A378E7BE57905076E99026D82DD8A1365F6224AF0C55B5DB4E5A403C61D696677EDCD9A3F1D18ACDCF76979B86EAB10ED4EEBE979E3B717D1BD88FE15E20ED802BADC3DFE676251DF9C3EB7DD2D0B3DE3B9E5D4F57C21441BBC01916EF8390BBF46A6B3AC9EDAD323D1559B37D2C3D35EE7F64EFDCE1EB97E88CCC93A86233537669A91006A25DA08D39304259FDCE8753C27922D607259D7A72DD278D3A6B6E57B3B04BB490F868A13BF6017F6509C5B35ACE14D18A0627B55DA0FE0BFFDC843AB0A863C281E221D74AADDC2EDAFB1B71E8266ABFA61EFF1673CD96B2CFB34E1825DB7A807AAED9C48EBAEF8A1C9A82F453CEBE4DF5AA162A29DE715BA7B0913A37F9C95DEF6E3FA7735F6ABC4929F4E4293D6261ED8612EF386AEFBA554D24F87738B3117FAC31B62FACD3079A4F941898C6A8CBA80973EB0A490921246E534666040BDE418DABD1080B6A60711D38428B1428A8948AFD8316F59E2B7E3AC1990C4524D391202DC06F3C56A68C8AE1A974875BE6075F8C8BD79DFE6E4E1B0E5EB1F6EA53C6ADCAE7FA30082016D4211564EC468C997390F798EB805B0727F1775D6C7BAD9F4695BB14F5599857247658F906963F936BCB2CA48A995C68DEDC53C860458D2D1A1BFB2BD9F8649F34823248E93AE47BBAD8A2F9A8C8BB41C1940D59F8CCD957BF4234EA11F96B0EC4D56C45DB1EFDEB364C95399C4C6F4F050D2544062974A0C70E66E7261AC84F123F451717C04FE7D914826D6DA16526295A04D9487D4D0AEC83062A06D700B9BA02DB027299A90AE76EC154336124CE396DBE26D38251ED42B8B1C1CB36569B68B6CF916F9F93E881D85C9A6A8FC29E44D2615C72686F89944BA205812BE343092CE4F6FF69A09AC9318F430BE638E4BE32ECAF795FC84CACCEFB0F395C1A101C6781A37381D03181DBBB3BB51B588F5ADB629C3BFFAB8AD05877D09A2175856D445F637693BF21CF28AF25EA98A4239F9531AFE187557BCBF73733A2A0593000A6D45A3FF7258C8B4423917A7682078B1970F452762B419F9E5B9B1F4B65F2B9299B6CA0303D108983250DC9F4192692567F0892135A9B12748A7D07AF10B051ED86949C145E0A220307AC113DB5291B624A2FFBB7E040BE3881FE3B5F139130374B7E1E3588DC867AC0735319D39472C6DD1B4040E89C6CA4CA25F1E485E2765BC6E5D228F0F87D8A70E3544CE5885D73E3C1428AECF61C1DA70E2E0667F75E14BF38A1310755871FA52C3704BA13B3F82C59DBE4F636936816D97D771823B7A7E80E5F988189CCBEA639C0805E33F72586462A1E9E47231FD123BBD4142D5866AD9638B1383A3F56787A2C1A55658BD1AD92A5708A643D21C098D3C0E04439D25316E5EA05A4B72CB7B483DC68E3B7A4E49B194E00AB7D92803D56EF66F70BFB5795FE0D096F6DC7E0A61C07F6BE5E168839B8EB3F91675124EF59726B97D2D4BC799BC7FA3FDE9C8658DF68FDA182D9B0C28739CBC775F25CF84DE80BF31FC00E1AA979970ED80F7383B2B584C44A71D765668B58E1EE65F333D6D24F521F390D642D4712593F164EDF1BB92D682632CB9C3A2B2C2D243B62BCD2D72426EF8F3DDF1DAAF7150D119192B97D1D5021C60AFAF93EE15D182B0F245D206BD0A9085C380A4F2E302DC5DA1B8945593460BFDC3EA8CD2F4CC7472E4BDB25DBE82D1AD813B17D10FE04B2C8298AA9A44776EA49380999EB811B0EB61A4D32E3F6EE65C42D8DCF1EAAF8E5D7934F4A5A7E617C7EBE1BC94DF24866E2CF2808E4DC461873E42706C4F4A86502568B33E7FDDDDF22320F290E614AEC3451C4C70FFA3C63C73748385D84AF8DE82A2B98DE7DB7A7963702213F0E4FBB1D858B738291902DEF6AB19FA5741724544E385E1D6772C0C447589F272CCD78D6EDAC75A903DC208948FF513D7CEEEFD72A4D0C8726A9C9FA34775EB11976EFBBEE1B9363EE4FA25BBF85C6316DF43CA50AB99E1B8867F2811063F8A637DF0E0F31BE32B894F991C86995EE192ADA5E2D1D96912886207A20D4275D80180BF1AE9EF10BCC22593C9BE1243B0288C7A96DE410B2298EAD003C8A5411D09572EDA59876E0D348433DCFBF1FD5865C0574E6F8F2F205B189257FC5530F5F28FCBBB7AB9807FDADA260D71563B2B32CC58F9AB43ACC502A983EA0738D75A81A533272D3024CEC9F2820C5431D9DEF29990D3BFB29B35A6E8EBAF885A725CD67A3F4B352DB4C3A018BC367943BDFE490C347995BDD4B0E07854E1F3C4D786290B50022012EB3703368184637BBE0BCAEF746FD0AB68268C5F5E2054C7FA219D2FB2375F78DDBD6C15150DE451004EA8A9A9FDF674A5EB32AF8B0DC0574C183465E573BA56B564DD6AD48686AAC6076D2E87A0D02E9782A37C9E04EDBB2840AB9BA8BA687D6D205A8A2C9DF75957D0A478C8F8A7F7B3DD104DE127870FFEFA08DBEFDE7B7A7026272F98940BB7C094941504DCB5212C8B7A1424D893845FE31E2845C7EDFBE5B9458E19C4732DF1451684BBD6F30D224EA3CDDA6123C5A440F41BB20CFCE7195FFBF7E9E77FC059447558AE47C543FED02542AF074BE1A13F659994CC72769DC4CC812AE1ED578142C52642D4F519DA98D834738AABE5D116E9C74EF1132E7AC82DA351AFDCD704A8DD5AED2D089B06A49AB7EAED3EBB681E2107C8E2005EADB2434B600BCE6540C321B2460404022EB2B94F5FB0D0BE039DAF10051DAA365B135EE12F274DCFF3EA68CBAB4259073E261573186B71FCA37262BDCBB25FB99ECCF4AF0B32283425D1AAD1BD7430765B6AD254C738F35FC26A23576B6391AECC264FDBC8A472008AECAC1BBB4466D6C9DE216D611BDFDEA8BD438D42A320D1FD6616144AFA447CC83360A717AC1D15E7760A8C459F14D24A8AD60D214A43EB83B3C7C85A5E4CC45A66FC75EE1A697ECA64C7969EB495B53E607297BEAEE3C4A95EB1712AD78AAF1C9940DB544342BD2284BC050EFD4A4534E2AFD50D596DAB3240B930D78C037679C693E909CAA7DE357FF12C4A2605628F990D3E4DF475A0824A95FC21882D23B0F62B046FD9DE3210FDC97309EFE5D84CDAB904AFB47C94CAF3B2E80CC8CC0EE2FB0C3FFE424D389DBCE2CA8930943532A2C4ED87101EBD361956AD127BFF03B852B3AE25287B11C83014CE71A2BE21A0C553FBDC745196A9315879541578B28B646D4752450A869EA161E8B6C7FE8E92BAC28B2E7A78159A15E33FAF19B33A18DB86603140DC635072664499FBAC8C710783074F918E11D4AE882EA86B0904E60BD463446F9615B2022CAC8C4CB422448BAAA81E9935ED3EDADFC7569E758D2EF2815E1DE1181BAF91A0858EBCECA465EECD1DF827F77759E2546C7B45B76297AB6978F12A1101A992C016109FDF83375B0D1DF10D28886B72783EE2C1BE7FB7C1256E4023FF730CBE2B10A062F9D221472E29B56F23BD09B99CE09D1DBFC4B370890A71F0DA6584C28D24BA32320863154CA29661F030CB975F2A89743589E2E552E27B6CF76DE9B49BA5AFFF4468D42664D29792BA0652F477696EC41A10782D240E9B163ED7F7E4454068433542F0CDEEA394ADA706E3EDF8AA34EF523EF503F8D5324536B2D9F9804EA9ADF45BAEBC58C0F31F1461025653C1D908D18832EEEE6CAED3FF599ED1C2A91EB95D47BFD1A31677952DE36097B9219EC5949CA2AF0806E5B42D41C2C05621027508BB87E2977D9574273AE5C410CC25B219E502C51E1764E52A574F488A9ED013B77163DEE3A8BA9751C0B67CEC000B6C9A5D5F2634B9E66C9A7B9B4204E734EDB7D1D41C38B01F791B377F04840F50B599443FCF7C87E58B8D9C9EF321C5DEC0D54A7C3CC594B0CA2CDBAE2A457409297EBD07E3B80A38241EA9B0F98A3C44C951B4889D28CF72A137E7D9A4ABF4354E96193F668F30855DE7950C4845E8B206805A2E7AB29F32AE2397143D681FC91AE1F6D23C32D523802F4B3C6B7D96484C2541C4651F17356845723BB2B0B4A9140079DE8E34D74844CF3D81F80788206F49C4E21123C984B07517138B19E2BDB13343F39DF592111762F83E93D7AA8F690D55956E65EC57F417D41055FEAB3CFDD169A286F13DB4EF3357FD8BBD9C94856D023646E08F1AD5DAE4CBAA71447F5073EC306C3FEC6B43AC75FD80C222D8E38E819A6E0BB0EA11C5D2735C71516520D8BFBE9680131707604207CA90E0B84E314D0BD67548103282C07F56F3DB85A4409E617A711A208A681FA62BE36CD24539672806F5A5CF3A3A3FB0A09D8F27166DEB377325F1B56944017C34825A623", - "rnd": "18C6283BE2D43153FB5B50808C066E9EA643FCE4CE79381BC09A3A6B9BFD7A77", - "signature": "354B6997A217A97653D2A70A82150F2E8D2450C52277C117FCBECF8AA39DF59E0E1152C6E70DA27137DC9D29E906EEFEB76193D1ED977B33C00F54180127AD6DEB19F9C45749071DDAF8CCE1376742E1E7193212BB30EC6144ABC486DD17E5DCB0C7BB3720B2AF2EE48016ECB15CF203B0C7DB1380241796B2C7B33F7C7D84459AC022E90FAD4606F06A31955882FF85803F8B6F72E738D92D579C54ED5B1DB825056B02A9BB936C6E355AB1915F1E9FA0B28DBAF09A398EA5BB0069F73662B982D8B69F921311EA9C43743BAC9C2166E3A3A4E8073C18A367D16F2B8858E0A3E04A77A0F24E74180D220B7B4B1736957283D0933F845D249C1DC8F966358594DD9B4866004F7E3AD57E86E1EFEB25FA427234B561995E13A8B974286775E8B8F7F1E71B2975648597ABB15021ADC016A5F58E3B8A84328936BB90C93BEB7F921A56A033029CD67CBB4E5C2484121F5651C486B311E356BA423C2DD613ADF25E8CD54D89FFFD068C3FBF853914C76A3A8B35FDC27F461F46E1D22757EBA8B8B23F050792360F7743F8762D0D0AFAD4FFED7181EA6B910243C3451519A7B8E90D6D124E23D4E7DF5D0430FABE663C642124FBCCDF9B294320711249D37FBCD44EC1CBA6F97DE385B8F5B57BE3615A098F36416755EDE788A61E0124614B7BFDE270B7D278296860B20E8D83E768350E00E06DDC6F91303A3D8201973FB10505E2023E0D0D2E9FF9F33CB0E080521C4B0AB8BE6BD9B0E393A6CC4D96172A340BB110E58C7E19B9BD1901C3D8B24E6C4F35CD71B6F30453BE6F8348EDA88641820D4B1CA22E9B7FC873E07F7552EFA3142B698D4D3D3D297F6D79DF1317F1847C264C139EBA1D3978305D6C5770E9CEE52E259A2B4D716AD60A438FC402F7B12777D23160E42422B743E08ACA6C486AB096D599CA1611A4D8C60C3D7A7E6E23BEEAD5A0FB6906883923AFF4313AEAA7E6A35123BE5DDEDE4813EB8BD880064C452073A673CC23A23A0EFEE6E328EE788E82C5F85C49C7372DFE710685BC00F8236781ACAFF3FFEAB89E2AB9D7691DC5D569DF75CEC7416ED407DF7224452019A3906DE08DE7F0886F2ADE2CB40720952888EBFE5B689EC341F3F238B64F3858A1D6068B61F6F4EAAC2F675EFED7C7530321B29BB4FC4ABD0C27919950E83975C723AE40D156FA177D50DF2706D8F826047670EE1AE769346AB9C0158CAE1894FA131F7F8966A7223BBB465FACA490AF9B20103735656588D1EEE485C7291D9AEF2E22AB1E947B7542F1410C40DAEF74465F65156BC7E8B7C195F7334D045823F6EE6BC69A007AF0F2153DF473E6EC29604180BFCC7A22C2C725083F9D5C77D0333C6575EA5C25253013A7445DEA9FFBB7A85355A3653A78F7EFC7396E6848ECCE8EA5B4FB19D0D2A4F46FC061B4DDDAE428CEE9BEA1A05768342D74B9D73F4A6C8B627D24D1E389E51A29D81785E49D153FCFE855A3F16D4C205AE4E796DD30A84FF2AAC4338DD7B569F5B183F6FD85D85E144FF3E5154CACC5F1BF569A626F9C88D979D9D8CB1E0A4315CDED3D4C0A39C9A34BDFDC64D89CBB0DD39A28D1C3ECE8A44078953DD62BD90E99D42B5807CCC7BBD6319367829917B199ECB748E4FE8856C978025CC4B941E50F24DDD47B227A31CDAC96D387DC873136F0ACD24459D61BF927132CAAA3AE85F48CE9FCB5B4A55F49BFBBB69E1406C06459BD560183706DC52B3C8AA74040A52BC12BBF75734DBAF5084D08F6E65E2D2946BE8527C958F8BD541922BBFC99F2BC118B0139350A7E5FE2FA235FFD72E07232EC76C9C959F15AC4D42AF6C42C9E73F78AE910C8B08670104DEF9115415A0A8F790F8DD471958AB30DBBDA2033BC5F1F9A54D8A614696DD408CD1972F7690AAA0ED9FBA564B07AA0526679E2AC1C09E666DFBA6206285AE8A5A9D093DF9C8A881C8FEDF9E55C7CE6A8C9E5469A7E0A4E52A12C514EC3D7E33A6EB5CCDC3470E1C1F434D69D0780AD6CB1BAFFBDCB9749EF0E85E17E913D0BCA91FD01E60F21D7E3B75E9C79B5E9CA05F03685DD12E9672BF9E3C1CD86896D5AC4EA95E80AB1C3924E364361B82424BAAA04A5024C22F3569AE14B59FB3E1A859EA119AEC1415E42547FCABB2DDE1FFD96876BFBA1C7F349967272EF02DB1A3ACC389C8A01DF90B6CE90566D513EB99060C6994A7377FB0A9E2DD4C3A606952340713631A2F1391BB13D45CC9F9BEFBFE0BA4D09EDE1A1217FCD42D14C62E2C1793941418EBD9CBDAC461B998DA2B0D7FC9B4143857BA429C2ECF2E8BAE57C01B697F7AF974633057DBC314D30FC1A983C21D0863B1ECB7B149C38BB453A0BCEE146EA8BCFE3409DB22FB0BD6195FDA87AA53344236AE48CF6083818FC104A9DA37AA21A3FC3A50372354FCF44762438C209F248D67390E65A78BC6946CED0626DFF83904EE6CC88419B0F055F978FCC05F471E07583A6499C590353BB21D9AAB1B3C0CFE91DA8D8FC8837AF49727829B60EF4106A8C8FD2392BF18C0075AF1E0411B6A094402901FCDF23D830F6D3D544A7A610A571E0364274A782EF8B1545607B164AE772160523F56182CD1DEE1709DD999616A8A10BA81752C00B881E00355F437A659710CA1C6D67764CC0582AF29E7572FEBD8B242EC7B091C9ADD89350A9C94F5E1B1C799C8E5C88EFCEBC8FCA25A2BABCE39EA39F75655A5C6D311A09E3D93AD02D10B162B88A07564B3CCFB72136B9F7E7FCE7764B9CE5F0EDF5829C0D48E026830EDB5B724AEA05ED4BB1E47EFD44E7FD1FE18D4135A608115467B9C0BB4CF5C0AC555D0109E7C56FB7D1505E1557944F847D8480AD7F245F929198E433D855D5ED3C28934D6F7508A2261E82AFFF1CB2831C7F4637AFD52166D32EFCB7FAE0C66285101916CB7C9FAABF8C3FB48E6830DBBD19A10B332A59C23E49FD1DE2C232047C277846D43A52D2848DDF9A078219BBEE538CB5637124E90BA7D09CDF7F631A4070A12A1B39B35B0C0E0C1EF5D9D12719315FAC2DC2056E23D1ACFB4B115E332BADF39D8588300E98D7EA6C5D2801238B5B86704E43D455E6B588635AD34304B226BC5D29874AA3671E2D1693FF811A25CF56543AF7698F2D25F3C25075B3AF3B60D92BF8C1AF3BB3416BAD3763D6CBE297816F51ABCFC7F783A59C1BC5AFDD8B7D76611FDB34C374226AA8232468DA0078CE2472FB02BA697E973E277A836606AA57DCEC8B790BB711F3DE664129D57A4D559E87C9E8F0CB6E14396397A57D626295D1A58E2F18BE0053E0A3F670458E29F0C8D63C5C8295F7475E527ED53B4B1F651AFB0621292A323D62696C6E7B818A9C9DAABECEDFE81C33555F778D99BAC3DFE104070A20323E455657727C838485A4AAB6CED1ECFB0A0C0F1D2431325D6293A4A6D7E1F0F8000000000000000000000000141F3444" - }, - { - "tcId": 15, - "deferred": false, - "sk": "5E181F59421C79C6FFEF9B953B6D30204B3E4DA3D6819092AEC045B41F80C4C9D9D1738FD1721CA9F62CBD0D5964842B17D95060169E19CF5AE4E0403D5534CEDFC2F9F939D3E0E48FD4DA0F400EA0D6457342A994C79B2AEF4697CC4B85342A455EE819EDBF32793C274CAE68B4FAD56395E72964CFBC85EDD729867BB310578B24108CC80583160441066ED946690A23281A0701C2A248C112415BC81149249023A82CC34048CC122E09390CD19241C0904811110DD1444C1B017124272ADC10429B1226500892510046C126814BA0704AA0801A03201B86000A126948082499368A5248680AB03002B230630892011710634229A1184C49A04CA33821E2B62421A7451A395119180893180C80322521044A03267122026020252219B3809180510A464E11062D439690E23008E0A20DD0140C182328CB027119A0495C886C12194DCB84010C1412E4468C5A9864C24832CC00050A442818B24CE182804812310AB384D89604C02404CB266549A209A34490A0A00C58B20483B8504C942921024682B6291A298440C08DC9040C0040021103221B140A42020910040C5284114AC268A2A200A2C82CCC323019B10C0C2532E3808914A46D824608E4486C59C86C89268C241048C30249C90882CC248C532662E0C2885B08660BA36180B8401482611A092121C68C4BC84C0BA8458146201B476062288D63C63088B290D2C464600666122286D3022E20B3400B088C92B86D8286898B220E44468613228DE3A4854CA24CA1A0205324081B85281C90400C3242C0B00D021162D9380DD8A425C9C06504080059A42151445142A29108846514122DD1C28C5C32208394086200921A192403268522969162162C1A87899944088240680C363258042D64344C9C444AE31441A2A8448A48019BC200E09065DB184400376CA22801D4367200C98809C8504A165143B868E4862100290CD1B84C5340815B96085C102C6214691C110C844886D4822D4AB82D80A66093066A5A90318C008A10B76411B40909256A1BB0241A124AE2062C1223080C27325C244D949889E2300C611800920409E342680C8290DCC06599382D64142E501424A400299A268DC992810C452D8BB821C3A63098182A53167250022C8C422DDA164E9A3662A3B62903227024416EC444410C3888D43086114665D2308E1909640B254DC2B05052A04124B0881442460A1469D2388E9318849198919A944980022184A04D14218AD0B04D21C55003482618250ACCE3AAFD236D2AF576B6B63071C8636756BE3E914360417EC01FE7A83D91BE70599633DFEA09BF4CDD8AE78935ADA69A47E7FD0AA7925E715868C9EC5829E575730DA04D35F998ED0A8B6EE5A810A6FC079FFFEED7595B68FF6D9750751BE64816A43883EB316A289790785FA8418AB2DEBD8CBE8DF388222275143AEF538F36D33BB6751B011EAF366F6BC564B860BEA66AC1E8281ADEA5B3D8DD2656A6FB35352ABB713A14FEFA311D6642875F79D58C05914B668A28D6F2828C9A3A54A733B44B34FBEFDB7E2491990D7680B263BCCE65AEF902BB4EB22C36FF388F8C3EF1F96CC97932D65EBD3C9E2E950C42B294823C40F3E3FF4749A697DC4F680F7E7B94A8217D6A676D6BF0A4EF67F51CCF9CE52276E664D05664735E442708191177D4448D746728D596646D9C8B1D0A64F1D62C4C89A960D4EDB68B7BC1D1569A93C7D8645FBD122CE6BC279731129C9F4448527201F01759B4ADD1ADD8A675B8C84E8CCBD95154FC5FD76CCDB1B46ED7327E9089D52A964914A07A158033D6755B1DEAE8A796B756F1E0FFC54F08BD5EC96FAF05360C8DE66830D970C0ED8FA082E1D9E2FF5AEF2EBD07136D860A48E276DDA8C60FC46ED97964D27F6B0C47506D6E11616B7AE1DB89B06874D602F16B3882373E3B9DAF8EFCAB8C210CA8B4A02564EECE03CA1CBE0ABA78B3D3E24915D0C4BBA388D49F2BF8EDCD36742B7A5056DCAD76962CA05C3872528F90A9738240483DC8B3F1A0E3EB68DB87ECE64322545B0141CB5C1CA018D4E6E9529F1248C837E69FBDCE08FFE6F863D6BC254665EB79A2A71A5165A969944A98B4C4D1EF46B767869AF5547DD64C686706E3E3060958F4628F8062340031720593301BD155F99B3ADFF7B4BACE580C4608610B348B26BEB84162CC0CD1B8B98FD00C8DF89E2777C914A84E8F7725B78509581096457B8C28EF72E818AC92577EE3C3A3833DD076B1B392890B895244A2DAED9139BD76D683DEC7CF4D6AD6C32E72222E95F213A09AF903A98B8313AC747702F00830C8665109537B700A2E9D3832FFF9C405D937B4A4877E47D09DC08F583F6F09D629CEB0E26CAB114BFF591671A4C2F5BA1035FEDFC7741ABF2369FA275B9CE55FAD8EF00DC9AE5AAB8AA2ADB8DC8AD1AD9AE6BEF77B82CBC27C36E7B84A60C7D5265AAD26B567B336CBCDA50D0F5564E5288345E9DE3BF141B022F02172641EF29142B46ED1B7725E9F36A52CFF3C362B6F61305C15822D0BE476A226FE8DFBF5083CE07EE0661ADB64B8DED8707AA5743AD2733745E1A4E69A2E0FF897E5F37C0E1F88ADC8D34D2CB9A1D6F35B4BCB89E783DDD1340F2A2748791A9372CDE4632F5DD82CE73F2D0D2EBBF202C9997D2BC1C523553909F1D21DCDFEC14B37277FC5AB9D40E3B7EDEA01C99F5E1CEBEEE8DEAFF9F448315A3C6EB357DF81AEF1612AC7FE4594A087BF5BD3F1A27CB71A4637F7722D97D36DD12A467292AFD95F0F3731437491850847C0B61E553C38D257A87D4F5B302A06E65B6ED439559B022A7AEDB666E36803599DE6A79ACCFE0A42C3E5874398F7CEE63D62E2037EBD77E30588AE71F434B8FDAA771B3C32174DDCD5702417E184474BAB7D8EAF7A8C7FCA6D53E5ABAB7B5351F30A1B14C0314366ED508BB0D2B7E5307EAED993CB72A619935644FA9F376F47BA8721A1A83BBE723D54970A46179E8483ED6724B3FEE6D03CAB17945924F082D9045140CA42B1CECD700DA1BCB45D0F2D971F70A9DAE27DA83F722053FB18A4ACD25CF242FE0E5733B65B751CA44DB1EBCD1EC0159E7BF29A6762D287CBB1F813D45F7839478EC1FE1929316FDC10C6E84389115FB1942A610F22950A7262EA2878603D418589674FBC0C46E4E6355CF8D25823654C9AE4F6E973BE09FC668D1A08522B9907755DC9B4FC0745E7088D56A519860EA109A207FE1A4678AED210BCD79F8BE48D3B29622A66A5334E5373C4AF3F89DF199F71923E23F964BB1ADB0D5C57591309FCFBD1CF8EAF9706DE8AC1907B137D78D19764785889607F19D290C9F231BD992C2D16177EA9F1B7C45A06941E47B441C2BED87BFA54477FDEE1D5FA1C2FBAAA2285BBC25DDFC0397332330C7158244424B3BF60DE15697F3354BEFC7BA81542FE94AF3359D9864E07729F2A583E0B28C99F09508DD07A81CB60F7C14FCD948FD3D61A5D23641C38CAED49FCADA0DB2F027B2185B55E65EC9ED32830F1F509FB95F3E89F63653E86A9152EE5A7FDBE479922E3EF5644745F7FAE3FCB991C47689C7C62493DDD17EE4F62F7768C85F9E2DA9D0070D92DE0F9CEDA09BA6456EDFB0B261C49F7829B58A771527C9D4B40772338", - "message": "D1E02BD099A08DCFE55386407746102C4998B74CB6D2FC3828DABE3DF057656963B2AA25886F9F5979060705D083E6CC60DC4C9CA6816A7B05B43F38FA07D5ED5856C35D12710995355DCE204E01EC6812B944C644BEC02710BC969105D4B748275607BCEBF985A5A3905A66A87B389B45450DB24FFD436013AF579717AC2690C4779C879D32AE1F6B94C4881ED4D76853AD3E2C657BBFC4DDA5EF9A19F03A6719793A80E38B498472722D0EC12105034A708751144009FEF78012E7B6219298A386A923D721D8DAFE536C6E7AB644F08CA6BBAB88DDEEC39D12A1BC6548D7DFE1A7C5061192A9051C0F2E0203A610983C782F8E007340688CBBB68127F4EA2D5670158B4F8068BB35BB1EC9467A7E5393C8B150762D4FF63315867A4EDEC13AD9757D81FAA461EDC8A5BC5069737E1335045FE92FC3A3D3F20F2FB16E3161F10B883CC48DB357F3B2E0131901410662C6F5ABAFD0CDC215390A35519713CDDCBEBD916FD54408E1B330B6F2D9DDDE2761C6C53C0D20AF9DF8120995950B2368D2ECF6DF6967288C31B9CF806BBA2843A0CA5CBA7CA0C9B49DFBD6FED1399A83B021AD02207EF2BD8042DCD7D44C99CF11DACE2F8ED48A80EF165D5C25A9CE0D90A4CD048A391D6FFAEB8E0720B8CBFA58FBA79F472B287E26373B3EEDEDA90F49FD8FA047F1CBB879165AB652B1B72A554B4ACEB8170B204415F555F2978555A2E1B8D7E32046A2CA60B6524B6C931C8C2ED673434BF001D572C18E9395193068A623E5CD43582BBE8D1AA919E09205A389EA0BC8EEFBC6C7851B3C4C052FE40ACF33DD7236A576399E613E12B886F0AE0D93C37A23009C83961C72BA92CA20CB2C619FD14113374C652EC88A7F5CE3F7D6CE1626FB116C6F041F866EF1DB6867ECBD6E9B7EC67D23B9BE8B8F70A0A31C8B6396FA310D899BFD1E98BE36F10AF0BE392B22796E5B6CC8473384AC6A8E9DDEBC5FFCCC26A117E0E80AD933456BED4338FAFE3E81D9EA5F6321D2256A8308F7CB04A2DE4D29B83869A45359BAD0EA1A58EF30728669E25F3D49F6DFD981853B64940330864532696C84A7643828A95900ACA6EFBF6D8CCF342824809225BD10088C82642AEAC6FEDEF0E01238178761CA890596928DC7E6F82D1A4C4411594C96DF7BC08A74E30542387D875384FD4F756891EB7254F0844C0CD80DF009375B7733973566FCCA5B7577EA821214F3D13A0B567C6CD0802E15E2BD55CF587D2CBB8F9B4656375BCBE4FEBCF38206660961A8656E36F3EB137AED6DC2C8AF5A316B6C89791D5479A07A8C6F58E4FB1B83A48504298AE8994408B99BCFD8D5575456A1EE9D890B8F66D1EF57CF37F3CD16BD46982003B0D3590A1284ACBB4B90D15CA64CB111D8C93CA608DA5D42A3578D66561B68A7B4FBA25300765348356EAC4D99738F81346DD8AE3FD4FE53265A8066CDE229F7DD6BCF35CDE67FB1777C7A062D839D24BD5B4880134512833070398027CBC5AF74D9D136974CDC7DEDECF452582FC35FDAA83192919DD1AEA26682AA636C9D6CCED236F1E377CCEFEEDA1DE5F4B5EAB31A9CECC5379382AACAB4AE633BCA570BD1E80742E3DDFCC76E692614489C6351CABE74BB786F55D61519CEDF3F3A5814EF66815706B5728F5765358C6A98C49994ED9E94DF477153400EF8556C532CA3F690AC0C36F73E68535402EAC396E50D6E3B326BDD4EA59B73B84F451DC5E3594FF8224FA632D5C7597BE285E2E50B8F53161A50AC7C9B19E0523F0BBE98E435DAE4CFCF263824888CDFE7796786EEB2C40DDD02FBBE3E1EC74988CABB61A741F54A0BD198D09D3118150EEB9A6362681DFB6D65D9D980E5B6679FC36A3C9E9ACB82DCC9EE0BAE3173B7DC7BA3F586660CF2065AFC72C3D214FADD460111E8F491B2E020C96E5B235569D79DAC94E094ADA0D453312F4DACA3A638492F039A4B54881083893407E145388A491E67794D430D499B5C3D7DA1366955D050A15CDFB2F60425E123A1F73C3090AFD18315F87789EA8BE34C4159AEF2A72A2B4312D6E75CCD345FF0D62E982CE89D972C94DE9481146377433B7F2A6416B852392424CE28DB6662AA798CEC62CF1ECC6CBEC4AAFA645068E1FEC3C22FDED97DC290684BB40956F03FD8F8D17C447606FEAE093E937AE3A170D9D87ECCA53AA24B0830D9D61D7B75FD5825DD06C041B97D8F6869812485F2693E682F7F534964B5FE92BEFEF39666188A63196D4CE0D90957D11509F0A1DDC62ECC6C8393FF60729229E6994B114EA5725A22024C2136AAECC37EB3BBF6DFE52C090F423BD872AD65668F838AC5CDD685D100CF8609D03E0EA75C06ACC5D821AD715F18E7D3767229A90B1D5F455249CA2B7993188C568B22F715B14B9C567183EFC8DC0E9801FE65195CDD95F2352459A8A303375B10764E6EB1E9D2DB8C8686A110956AABF16E2EB0EF2902A4FAD3E0E88DD823DD1293843388000630AF54435F818FC6160DE680C6E049EE95A9D66EB719812FD0E50831D6AC779271340FFADEBFAC7A698BFA6ABDA808E5436930AA1A723B3FAA32020BFCF9511077A328CFC58D58C654F1E0F3592C62D2F1042A27BDEF369A04D4883685006B4A7E53961F7BFAE96D91ED99510C3F143269880C6843CF640DC3A3C9AFFBE9B4EE42ED336D5ECB5BFD6C6DF721FCF93ECD84832039EEAD37B1C0F4EAD6F756DB880F964A4A0D98B589C2FA157A812502AD7AC005D672C3848C38400613541DF782E87846FFA7B88E8A5A93FD733A6FF2C7083FF4EFD8C3015695F2039C23101CBF6E50EA73EC0AED6EAFDE9A74191A7E3BDC292471DD65D2D2EC330994273E68F507168EB9ABCFF12CB1D155AA96EE899F862ADA8C0524D6FC099543DD379E4004893162A3BA0566B7B62996B362DB682F1041336743F22669B948BE1186A75647", - "rnd": "0C58411DB0217112E2223B64145B2606A22C503408975A0C0D23EBF5373C1EB7", - "signature": "E1FBBD4D3C6891FECCB9DEAE43F70E39EFCC59174D2E0C10B2487173D1A841B0B43AD7D2D69F56C89EDAC95D35DB4C3E9DD43517CA38BD4E7222730CC2EFD153A2F3B1EECD54C3B96259085527BA7D84491EE50F1B55126D88DD69516BCEA2B611441FDD32537F08E82FD8C9314E88C671B6DD8CCEE4C209D7BBA6AE12D03FF088C4B24CDCF148FD9525285D5E6D38DA573F31019A7C7E15F0BD238C5DD3484168C888759ADE653DE6E728166383AC94536F4BE9F2F82AAD2219C39B49C99BA3845EAE1DFAD5F85AF6584FD846F110CD88C8957C91ADC93802EE271BB530F2252C427EF3A99F6F903478640DDCBE6EF02788E4B154A8AA9BDD335C60465B7C95F992BABD92A806A4F7DB7E79BFF19D6B1BCE91A204E5FCC06DBCC880413C38B17C3AE25D997EA90183BD109CC0E091DFDDFF704BC4B2DE7FD34AD57A416ED4E97708E3CF753390752B2EE4B50B35441518BE9FBD085BCDAE84158D42E5D15027BD3D4CC2064A49F0A0131922E29127D1A70A326EB081FD0D3B31F2EF033D51AA8E25DD6C697ABE66853987E842C26E47A5E966D4E1E28C389D0CAD11C779E3C5A2226A3FEC122BC43E14A159A1E96D7C2CA4E5E490F35C7E28245EFD69BEF49EB96553FE5EA8974443F017167AFCEA1B937262008DC0566C68FA83187A8122A9DB77F7D48C3F4F74F6346007F88C1978ABACD2E3AF8201AD5D7DE36581B36B99DBADB7D292151AFDDA904596605FC394F15E77BF5D42EBA7A3018B551031099F2B865876B4EC9DEAF4128689761EBA75E68024AC789E3E6520195DFC32CB3865483C9755C18C8F32E0EA82538D7D397FCBA5710A90EF1FB69449E5E2C69B4F394FEBB9B11CC8C0658789EBBAC6E1665BA51E134B48FC4FF90DB5FC56EF46ABEEE80659972CE772E4585AAAC14B84E75FFC701443BA9B117DF936947D632592488F7D9B66A30C7869AA14998F1E0E74A055F7176DDA9832A80AAAAA4788C4D16D9EB3AB26C1E68A1F64C4774EA5FCF4C85F056A786056A4C23B6776CBB6D320333A285E98323397111EF7921B6839E07138D2167093B392EA673B55CA5F06967053E726AB723ED03C08B9F20BB83B7C1317C4B0AEFCB7901B7AB6AB84BBEA02152D4B521523F4FA00A6BC5D12D478A12DFB0029C3A3F6532E62E0E50F7D06A4B384C0EF01906E153F5E8D4999B660F51DCA1523C158E398DA9AB146D20E0FBDBFC4F815C4E850B2E3FEBC082A5837ACDDD6BA233A9B24ACA1FFA3D2E56D7107843442278046984AD9CC683486C8A0F16B63E4ED0FDA2AF1850541DBA2232564C6696BA18C4ECB73EB84A3016ED1E69D84EAD3502F4E68998EA9FC3C59AA31D7B1FF134FDCD2E7BCF1FB4B99F576C8EEDEB710391BA08362E0A2CDFDD9C633B9884B24710BE34C857DE17B744157A44F711E38F763D0DE548FBCE0CAAD61772C75021B3227BA00CDDF108B036C2F7AC584D76C1B2C5781F75B90F8646DD29C587555A41340B72A1EE4F66C72F0D2BBC9193925BA22CCD671552FD3CA1579F7658A133AC2B585E89DB54AC612FAD32BE9356B81ADABF2DE0BE6228440B445E9AAADF522D5B55A325ECD1F52E20B1622058BA88753075ACA64C2FD771DFF85DD579B41AB451295627173FC0E34DC54CEB925E83FAE2FAF51981701B97E6F01BB4A240A82541D0A2941D9FD4CF6F93A571C874E2F238D0291510DB947C35E4E0C7EA91B66B69E390C7C5286B410CA91E652F3BC5798EA47FD63DC22BAABB3FC6795BE99B3535BD7A590216C97F24E11666670C080044E4C78CE25A793C034F2D3BD9713F3038F56C251F61D2D73A33E3A964AEE65CC3C6614FE6CEE803047599BE721A0FD18BF41190339CBAF8D6FE016B8D0162099BDE0C24963FEAFA9756077F1EC61CCE0CF410CE4CDDFC83284075D68953BEC6162B03756202F943BDAFA0DCD303B92C704B73994367E471C47F16CEB8697D97E52021444FD0D4EC1236930AE0ECD758457664BC08B2110E8AF421C8FE40FE9FC71EA3876B02E5791245ACACD5A2A106C02F66E7A44DD0C5535B19ACFE3D1D0DB39168089C3AEA1BC57F84D0647F07C5EFB1A88588E067F92BD80E4FD914CA38E1F89E91D4F1BBCA217D32A2741BD3C120E26B2FB6CD5132EEA33469E684FF1C425C95154700D0DC2C0764F76DEDAD0BD79587848EE34D9374008A867209D4844A8D56A1DDC15531DE2B6F4B978BD350AC03EDD4E2812360ACF40DC3BBD06AAD03F6F48515E4D773705C64663897A056CA4C8D85399027CF37D76503421F9DC64FB5B4FF53C4D15DD625D09A6B2E5323D6D354079DB0B0CD75EB52CBBC640C4AAFC81C9DAE43F85856DF0964CD40EADAC97D420D30DEA230F72EF1646120686A4141E3E5E3DFE308CB55896626BE46DC04CA6F9BC5307357B85207239528A7CCA53E1F07DA6D21905E3041B4622B2C598BDDE031B01FDF12086A8C9AF1155E1D9B725C3AAD8D5FA9378C9C69CE38C06E815CAAFA73B02A7A0338232E98685EA9C4037A50EDF7721E5B4CEA55732DAEB31FCD9EDE620111C7F5DD4D3804F1768496DF4BECA3D2B0E387A9B9BDE4B09A08FC435F0BFB720F20404DD92CCF4EA7EEEF685D019F3B7B872DDE13E07FA7CE3150A1C887DD70337E409C9ACF8EDEBAABF29CFB9211E2AF2CA7F81017A513EB400F42BDFC6935E7258949A0A985F2174316C4036541A64EC656DCA3A547D99B4E6B2D226A811B9DC0547762FFF262238452107BFB27BBBA14A6C1C3D5CD893BE510161AFBC0A1CA294B2E44A4A4911F0E911B4B95DAEA17659CBCDBCA5832992DDE4F764714DF49D00D447456BFB95F4C8C0E3AC081A32B2AB5947F4D3FED59BE524FC265417D58EB95692B3F4B500D3FEA9247831E4E576318059B36E799AD9EBFC0AF32C420C53B506167360730CDFD4CEEBAF9A0BC3B2622CF16EEDD4980FE778666F8D8A7D99907C1372E3331744A995EE7AB0B81799DCA2E1EBB3D085F019907B163FFFC2D98371F80B981F86166BEA20ECFF693865BE7576220B9FBDA4AE96C9C6E45F2DC779683BEC6C049956E97250100BE96C6B6B80C5612607A82D8829E11DEA33853BCE0E2025C755EB95D1E4E8CA133C5773AB011BB002D9B3A315F49DB216316AEABB4ED866F6C32C0F12C65B6D952E13FCEF58C30A28412A6F9E231597651162CD7C75EFEAEC60074DEBDDA88CBCA5A6DA5CFB8E8E739E9AEEE5731205EB46B802F138FA5807C45467255BF859A9CDF7300219E18F827C5773EA5A173AF76E4E15F38D87DD000C64B9D1124C5DD5E1BD88EA86D82B0F22010C2542444C5758595A99A0A9ABB7D7F31C253F4CE7EFF108334D545F6A7A8594AAD6DC03131B404B6573767C9BABC7C9F700000000000000000000000000000000000000000000000000000000000011182432" - }, - { - "tcId": 16, - "deferred": false, - "sk": "51CC34A2EDD9C92FEC31021A0CE432BE3E2649B1B3A5617049F2A6F050838EF2F54A00E61DE283C55E912503EEF3E7C47021BB0581D3FF3D89B8BF50429DA880404665CBDE6EACFD0D1206354AD32B5E2E9C4F819667E251E49A10CE9084CF757B92A2E66E3F23558F9B6694179B5E4C0514F8A3AE3D41B65848F91DACA82340113312A3B6515B36288A8829181522E4344C6230015246650C3672D0108E4AA88088842114A945C2B0912034890B42316142720A0824C382499196301CB80553166D5A16511402829A329120A109DA000DA148012116126110921211469A10014036691C20895840241399119A92714012481B88081C10118B20864388699120024CB08C840221A1186D1294455082818880701C170A18270680060220920960008113076E8BC284C1864C0B9129E4026D80A21021020024168011398C1C4224C8148088A0005A1850D8A2901C34462148725A42499306309CC46C92006A9CC644C82822D4344492324662482E50046C1B9905A1A6514C96498BA008534071D1C08091080D1CB64922172410376C23026992A28D8A460143480AE416521417669982218CA2488C448C51C4250AC20904218A441432D926641142721C977181C68521B8110C37691980840B2432A034281306008438044C0090CC38911AC81193908C11932023392A63020460C48D50904D9CA8455B90111090505A487200172598880C93B45109006E0233920805520382889B020DA4044860002E51000600174E09B8718CA0248BA010012921623832E3926824238E98C20503C5491091491235451911309B88685B8691094231E1B04DE11261E4364E02062919422023126620A2685A308061306A1B87600B854D5BC8701004311BC00CA2C664E4220518A72063C0311419505206458C204E93A021A0226A59921042268CCCB6859296288B3022230861140240CA122121B468492251641844D0104ADC428D13A485CBC468D1100CE33809592066A3082E9C46646228419C882909228CDB982198040600B0699A002ED4468180B8680205702406520BC06C990282828084120272C93684940624D2460A0B284D98422A82300ED93004CC12880295890AB06C52824424C045812289D310464A1245920831D32621E48071A0983014168643A00DC8925194384C40400044180100966C1BC48110B28453C4089422605442851333922041058040810C172D40464EE2986111904514B164538068E12250C2C02C1903505B284EEC2A75F8BB622AE9EADC725DBE4D0C43619B9477A7CE27F600A734FC5DC96960F41D36115BD187A3E169453A76590807A1DA57C02FB173055942356E879B178626D137DF4D74381384703B96E913B37C5033B47910D3B1AA949379E8FD38028A01AE41450368ED4794271901D3A70504E5CCCE06F1063EDA51C768B6E6923A52C6A9CF468CADBD9BF5EDDE5BF3921EB14FCF97A8D69EDB09813705F7AFC8B823E28FC07B36CF8174ABC7F74AEE00981BB7C6444F872AD8A40A4D8B20399930632A9080DD80A4FA9EB87EF9DAE46E62A3E1105F4138E53B251A9703E3E4BE30AD2EC3711989F28C9D3EE98AF38A2AA431F31C41BF572A3AB62E1EC6F4B0FEA14BBFC99DBAF2E1E96FC406F17DA2F6D72F9E8E2C8F84D104278D897B3861CAB275D7C690B14EB299AFD8A9508EBA54A87B81BCDFE1BEE783962B5794573A3C842B85E3F87454062784D32E6B301D5DD43EB702F886C9537D45BE6ED13D7DEF5AE4D692551B2B9E6D83AF896661E80E756CC207747D7ABFEFB51AFA6C0DC4D0AEB2E92218AA51063DB7ECEC4A320B41C564CCB53EF5DEF9EE596D7C9F7140E0048139A3732A365FA842A823642C7502A989C7D56A5C9CB8F7B81668C638B13AC602171169C2BD25BC2999809CEAC16FD304ED03AB6954F86F5E179CADFB96B1D1F9ADEEADB29191FB99C039AF2219678CBD02F6062CC4C9A512E622AF383E22D80EB9FFBF16F2A2D428DD80E0D6491A62B46E6210E67C2BC87BC67A169A9F488240C1D5F432F4494D8CD02819369F023663844B8A3B90C87D2DC2F7354C0DFA3421BEAEDCFFD719FEEF693CFCF8A01BF14C100E73D7D9551527DBB9511A8AAB01617BD11AD042EB86AF7E3DCAE54CEE4EF4DD8A51B06A88D1577F7001B510A0D9B59981C762FCB354A4028D5900BFF4B941D962D589244EA5CADE2F400EF3825997E38DCB8C1A514A20D63EB7E186784A4D1E61EFF36CE161A441A59B72B581425CDD8BB303179B2139912E4A9ADE76C2868D35BB26EC7FAB223C2BF6D2361E76B81E3E7BF7232AE801C5455B8E8B88DC7E0AC906A222D283EAF51492B3DB2EFCEB96EAAE2D9495C26384AFAB002DF0E0AF74843C9E414CE03C150AFFFF3E7847A8947FC4FA93EB6DBD6C321677865B4D7557393D04F00BE1CD7C1C67E575E0C41B462A60830DF831810DAEBC557D294E28D0036A89B6D4BAF21F479A83CE7AC225F0190237E46D787F3C8F7972A1B310BB47156F7E96E55D9656679EEC53504802B08F1FD89970BEF2EEAB6C11E91E6E6D76C6A13EC9971EF71A08145FE34AA1DBDDA7F20849277C1B03220DA3091AA295434D3ADF076A2EBE7613C663557C360333EF2F9C08944DDE14234C029ADDBF5DA20B814FD8D0491B3986E13CC3F26D6A6A523138217B68C5C2914B9826C68052347C83FC50D4E0BE90B49A92470E6C75B636D68F2EABE0F358F1F286416D7F5344AF210DB73C30A96B9AFCB46592E9302C3B6F6536A2AF40C1C07F0F637D07CD99B6586AF0655DBD37831BBB920B07B0C5E28556C603A0D7AE4F3B3CD9EE087D384BEBEF14950B89D1D53788DD45011777D8844801AB18E5E002006147A1BA95D301F551A3A4BAD14C68B1046E86A40F66ACCC50D8DB8D1DA0E62E6BC44840B5B093B45823C9D0B8E6D44DB7D9ED7A770B1525B53E9561BA4E027068230C64993D0CBBFD6C8525A1CC1A007BD583CA362FD00927421929FBF483432D31B84649A672C96F052F212667D2113742EC4B95D11D73222B37F990C978692C71B51DBD7CE39690D7DFD8A32D10D0A33A26D296E8608440E03D2380818B02FF5AC5380F106741D74E6BC031C8F822A4EE861E9F3D1058A18CE144FBAC9C00EFE7E25C9D9CE7548A86001A57111E5F497F28FBFD50CCAF31A2586B7D4C97AA1C1BCB130CFD43EEF5467F8A26300828F9FD3223906407FEBBEE15389E25856A211136142F273C5D4D06B29E66C2366282B5F592AA65C61D65A46E9610EDD7A5E09F661651BC77860221FFA9C2B9D3748FC4373B4E8DC8843DF1EEE283D5D5D7AD63D0314A3DE519453E15DB093EDD89976A87DAD3DD5C6941689FAF3E148EBAEAA8E102618D39BE3AB6B27D66D004202125A901499EB1382467E31188AE455F9F86C4196B06E695B637BF383B12E76350A4F75FA83AA07A249B879190081805D2570B4BF6270F0BACC1DB9E30F0C18312423F6D7C56E197A76D39DB33EA43165D52A24C14589C59D95D7692AB492A1081BDA3CCE2A07ECAB3F3E07F284B5F94A99CD359C34369AEA92BE90AA59CB25423707F48CB40F40D8DBF8D3F9D6FB550FB2FAEE63C8E1A10F3552C295BAA5B2C945558FFBE", - "message": "959D7C2BBFCC7DD27F7157B95B10DAAD3E9CFC3E239F471D39A2B2BAA7B2FB4BE7947C392A140B936EDD3F9EC4F78A5972046D62BD687312D6A640CB5FECAFBF0F1CB1E5694DB1ABFFB9A796B21EC3796D12A656720B689879E686DBC00A4D1673F2BC8871F76B195BDF6D2501ECF95D8200D6AD0222B1CCA522DDD5660C8A6CDFA882AC7B467A44C0A97923D70EBA56BBECE84A772DBEF59E37CEEB3C2BC2D4034534BB42B54A6A4B4DDBC1184F03740D190029E18DB11364C561C5B0C5929B6A9273DB82C76FBC16C9D8294122BAFFFD7FB0CEC72D677620B683B172603324771DE3D34F01F3BEE7C8564804D1CAE776D326E3E909B84D65C2DC758656846D11DDFB0C0A31D323639AD77F7ACC39FC2C0908F6CE45017229ED0522255658BF47D1153DCEF6F17FCAF429EA7CE13B6AE501CCDE15CC3E271AC902FBB19D188C845361B6371EFEF8E81EC30C6C1B3C2CE9B6BF3DE2DD12A9884D5BCCEFD99D8D019506B80D2521A43EAFBB2875C7747696F2D44F2B19228B0C6FDB59C33DA7A34639D3E192D31EBE05EB5605681F1864A61E09967DE4C7D576988B2BE3268F95B424478E2B1B95A0885233F2EE9924989BBF8052D25BC78EC8FFFC2773A61039DD459E8CB7B4232671DCF245738FD473C0FFD2F4606DDB52B0FF434E41077D7B97A781C30CE4986EB3E0C0ADAD788D0B4E3E2EF122A7E05E08AA714F22D706318AA0BD019B22B1EFF0F49B40CCE4FC224E66264839071B55A91CE6BDD389634F218C91AA9ADC71748667F83DFC897BEF6744D8852627BE1C4A58DE0C973756E93298CA47D3646727EC4C70F72466AD87297DF52A7295E7EBD4650E02045DC1F75E1CA4AA11A56C5D6F4B1B0E139281595AE26A582FB506D743DBED3FC1D672075B8489A5C0086994D524E0796C2BC7C1A4D0D876651C7BE8C264B37A39428150C48839DB53262A3359D074AA9EC83BF756268143263790945FDCCBEA3CC26449CF7E41A8221EE82613FFADF5B0DBC58D4FF03D9E8B51CE06315CFA3B4C3D3306C6258663568BE794C50D94F53DC1F0591818286FC92A6F56E2983309B3AD33A7F5EBB6A135DDA5776007C9FBA7B19E6465ADE980E528F17CC6BC41FC03479B8F083BA6DB26560701980D98BBA73612239437514F3C3CE39BC6DCF83CDF3E85F8C27131B9D4329BB7FC26BCC9C4B859BFF8213A88405E0039F57B0EC20E032854D75C7401F50B44CEBF91AE3D76D917D49E064008935D54377226C419015B48AA6332A3DB8DF8C53929CDE594957360BA95101D56AE8C877A3801F9BB446E9CA52643B0D693ADE5BC5DEE941AD78C386CE209889E016EEE1409368872B42327BDE8BD21CEDF42C31DAE1FC59CA091B1C173AEDE6C2B84634812901956CA93DC228A35AC884EAC1AC075B32265B600A5228D53059145B2F294466F7AFA0338D1D1847C9D45B43E15793F241E1E19AAB78D8A1C8F9C64609F277B60C763265AE594D23C0F6E8D2F3F1DF06AF1E5DA6EF50ED3A054E8CCA30D93EB2A75F35C05E33109F98C0EB88B2EDF055C4071F48A52F0532468098CEF8D5F4AC7FABB0F447930DBE66F2D5E48323BAAE1D85A03585BE5E68537D536BF187926EB57EBC7D8C0DDB643CA507039768BF99EC9A469B44AA2B3C194D0222F74A637E067D5D42CDA7385410E4DFA0FA67B555A05AA654F5A8DC02B17A14C451FC491C45F16B5CCE6FF492FF3C3410BCECB63E11642F3056B96F61CA1BA2B24A378054F59C9DA095C6C9CF8B0D0E550A962E643C6EFBD2413EA8E3A20113882F8F9FFD814EB6EB40E29D0D46707F0F9D0172DD93D231EA250193BC77EE9332D400300A0C9B668D73C2467E4920E3E4FB20C23533F7886F89AC98F7CC3AAD9750E63E3A556A205F46A6D52C31CB8", - "rnd": "A00DE2E63DD5328AF32D386C5E7CD56F9730B99F57A7BDE7A6B85CBA667181DF", - "signature": "9640EE42ADE56FFCC49FAB13703BAC5B0D9C58B19AB0AE29B0B7E981B1E05C38676F3FC9AFE2D0724191BEA5D4A38B07882F27CD9C1B4638387BCB9FF74212DFCB6B861C1A62FDED3C9593EF0EA6C4A39316D375441A3DDC39A373888F14074AD837042C3D14569D50B2F81DA5A2A1A3BDD620ED1E4BA20C2EEA971642B85453F8674F59E461D017D92CF56C6FCC1C8DD9F25432AAAFD08729CAD63DA236AE7DC734312AA12EDD4B31A45464D4D476B98CB8B8A967A0E38A0E06C7EC22174B4243B38966E94E215DDF8C6FD028FC176F04462B212A47EF0DAE506A3D033AEFF702E17400EA76C993947372A42FFB0DEB58661BF781F22B56712325754ED2D69883DA7BD88A2890AAE3B536B7D1AD67EC28C459F9D59BAAA128F746F0430BEF8CA808D818F95AB4C445A7A163277D7B1F4FF35417B827D7E0EA6DF253FC82331D779E3E8F9C0CD30FC544D6C990BF104936F0043E5F51C82D1735F6ABBF55A4D72571AFAE1040747A4BE6CC479A55A42E4E69255D40E5583865CBDAFC55B94DBE323498EB87DD86B54A1ADDA452BB533212782989490A2AF4135F73CBB334505DD763530F86018D03CADD69B299B67550CDE643D1D444E291484372F192720B8649AFAE2FF1421776B01707113AC99D5EBA17D07B563C5C25CBA4EA0E3BE6770AF2510F36CE9D4472FC37D9B0A1FA706E901966EEFC40BFC00A916B77D10404843205877F289261A26E05170FC1C78E07B83367C1381289F72903779303534FE00CF363EA8AB1A6D1D906EF9BD3AC9E521D78D43748E12BA793D427E8E17E906CC03C732D5FEEF7934A9394371613F4CD1FA4A065A8D5B992307419D51B5BC6103A7DCE98C9ABBBE6A636EA28FBFA58B27361CED9C912DFE19A3FBF0AC9CCBF72A23E304FAD36C169478B9AB102ADE1907627A45D62A76570C2B1FEFD0CA09AEDE82634A42B621047532B3C42E0B27CC793D387F328AEC86CABBD9818FB2CCDF89C8B1A30D6B3C50E50BA2F87DE053C82CE711677DE39A85D56B7ECC2BA7134E1AA3C2A515FED9B521A4E3589F7EEAB110E6050A6464212EBE2F035F6D90F9F1E34597554E9BA1A4FFA15782C4526DFE5581431D2549FB1FFC158C584CF3A38EE2FEC3418289F2BF5027136B4CED48886B1F91ACDDF9D0BE8DC16A00EDC82EDD763455D286F0485F83CB2AC72DB2BB625A49820BAAAA704E3E84252A1B687EA197A564CD7AADEC4EAD3F9E2BD266AC4E9288DE31EEF4D94DAADC70AB9985BCA7EA686BEE9DEBC3B2FB078F5F8ADB7592046B03CB2423B9DDFCB16E35A36CCF169AE415A7103C46221DF0CBF32044E623D919597D98948FC50E3C3026F31B8BAE1D86EBBF2EEC24D396C8CB2029E0585747ED9E77E4B59C572F149DA2A6A5A4DF578978048219B7440FE1950452A6B7C941A9F2DF02320FA033B84F1EE67CCCE3D30773D7C4C311516DB432F16DE3A941DE2DEA329DF8914294D726A8B73F01DED4DB46187818F0B42F91D210C4CA542632013CF1255D25C2D97098D742A270A87EEB68154453B1F74CE850EE3B500E22A11B6BC13796D53716B395BFB8DA722176C8B2D770793629055B2FDF71469917989C71229443004CCE15893CA5D87D39FA37C7A60C74B61227DABACFAE8EE20A202ED5EF2FF5DB395C29144DFCF93F90EF73CDE70AFDD0218284B6740AB0657B5A969D53357652ED38B051762610A4B644D9231F9A37E02DD41B2DE3ACBA28EFE65CBEFCA6B080596EBB2E886BE2439BD71BCC586FAEB364D0D7EE163E76DD91CFA6395C349EEBA139A72DD967F1DCF4230ACF7EE117E89930711FDB6B57FD0E4B6440E193EB9B34037DB27F41FC1A3A8D35F6C8371266CA24BE9EE7067E8D2B8425C3FA8248FD4F6CED856C4219ACAF949A032E6988A733C1C5980E83934A7802FABFF32A7CD073DC9C3AC35B8916E2F96A3DE64DA645B45F31A9EFFEAC5F9C93C53CE092EAB03AEC82E053DAEC11A0A7A688D1769BFB1A90967885A5B3FFCEFCB00DBD2202D4C9DB5DC6BE52FB36C891654C1EC3D1348B120C66B37FCCBF0F6D68EC0EC45B6902604A4CB5BDF75A20F10DF080662C9000673596BD97FBB2EAA329CC632847F48D9E9EB64A3BA9AE0CCCAB8554013369E6C880372366A99C5FF7197982BBC669015C170AB0319D4C473138593452C2658743E3196E33AA499E213C634FD887C2E82F65624D9A7D189B0109A14740695657B8FC2C3C16CF227F26742C4C1295440985B4BE4F00FFDD35CEDFC36264F43625A3492457C849217E29CD080434A856166F15B8E9B1F7CEEFC429F290425F1D50E56AB48510986B80656475F28BBDA522A14405EA6DD251C53A7A60F68737E985D23704B05275CCB2095A2AAD858D84F21822BF63814190BBABED0F6831C6FFC8EE0B1D882F1786C26ADA57030872C53B4E37E532255A3AC269BB136679475415A128719E10C2BE430CC8FA3286BA38479E50EA22E5D3DA70B8C594EC74543401A07DC32C4314F866B478071AAA1CEB7EB8A1209E030A0A68E3BBF39939749B630DFA40472DA7BAB6DE9531EC630AA70568C7C1DEFDEBE6BE7075BFC8587390B8E0944D782C73E7E19B524CE7E5C9CE7C82068ECEFF5A4FFA6964B3D66FFA0CFA05DFC2BA8055849290EB733C737C0BCA93B21114B4513F14CC37ACE178D0EF2A5B741927FDEF1A09363280437D067DB1D1F24D4FA7A11EEC885D887B636C996AFF78B49A16473651364301D0229458428D6AE652173EA168D7B408A5A58319A4D0723BF5594BDD43AA9DF91DAEB1F539E0EB3A86C5204521789A5193F95F9553AB591878FB6230552AC4F5788EA7E2DDFF3FBEE08736B095FCF1F6208D4C143BF54F2A7008065E658DA4FDB8A21B881F69AE1AF35BF1D4172518165120B246497EE3F210FC6CFE91509079C51DC906A6908E768A4D3D0E25F9BC97E1B929D06DA05F730030972D2779E0B52040A13E7C4689B55955D588B924BCDA63A858DB6968DF67F80519F36D0EFBEF87A1A51A8593D76FF0E3AC37831514C8FDD874A7F04E2DD00A075B24A7B697F586FA517589489DC6F319252C30790099B291141AE6044855C35B96EDBC7DCA8F03D3A2EE3758CE5B468ECF20FC4E91236D1A3C049058DBE145D40E026915B12AD0868A8B3849A119C1457AB618465CF87FDB7E882CB8E75E131A75E89E15D5DAE52F0F99A899AF471727D7800B388E819FC556B9AC34E2B118C9DAE26889BBF9DEEC987F1F32AF3652671C5C769973FDE50D6E75B65D61DDF6FD79D7F143510EE70F5F0358A3E327F5E996910E4020C262A464E7D91A5A7A9B4C6C9D1D6E0F135485A60808B9BB8CFE64B4C70757C808AAAAFB1CFD2D7EFF7FE10333C3E516F8489A6C5DC00000000000000000000000000000000000000000000000000121C2C37" - }, - { - "tcId": 17, - "deferred": false, - "sk": "5A25C63FC5580D85BFC0D88CB914F155246792E611740E5432FB5D7FAEBA2383BF9E966E154813361659008F074FBC0390750CEE16B3080071C944904395194ED5FD3D6CDC07A52347D911C5718D621633ADE794C97DB2314CD896EF2A09F2060A974995C9A32E855FAA188B92FC3C95FD3285C5D632530C5F62BCC88B11215B5A208162B88519296AC81488E1A4119904699A80694836280C08040A1624811240A49084DBB020D9B650403449A1C684009331834830E496489B44440C312DC80065511472810491208785D0324C20105263045054347059120D09A705D39830E48849418224C0386E80884D8B024088166D1A0750E4B84C18C12159366D0A37228C8225433829D2322A04C150DB283118454A82866CE3B2110BC44890A40D64B881924685D810461A486189800112252802146A53A6508C32090C468953C801E3223251B62DE2A84C122884E0220CD89804DB188D83144800378D100700014931832032134990A3A401DB024AE320090B8249CA345114B684E038880AC2650A212021350260C840218630219668128560422669E4420804499244C828599450C8A4455B2246494404220360880010DB126A08B20013820CCB00910244821BA488509631E2263102389103900D1330885B362D13C550E1A288A4468598020554382CC9966913B14DA4804C809281E00465E38401842845C4B21191A0881A878823050004A00D8B3489C38228130582C112691B496088067012A9910AB609180132810408131926D1202458903192A22408428159C25150B08DA4002483146423446810C28D0342511A2389224630D1808844902908432840328D4CA24D53288AC38048208871093606C9168DD92029A3468563242981266DD020640B192201C22459A449A3284E8C4809088788C91431132868E39624CCC84D99B80180C66D21C74061384A0A344D63B6281246041A080112080E9AA03083067002160992904C43462A080660081842D4342E10A2510AA565CC344C6302225A04611A38251B2466122041C81848A322640314800B4182E21229034871C1C404DA126614272913376C541661E2B60D1B468120349223276E222585C83041CA9410DA380282A640D3940402C6441A9448DA242DC2422682949121202EE3166C24B40C11226D0AA52CD280006288505B483062C485A2A630A20008A1346E48B8450BA52DE000055B0080C8900902A04D24C944D0C0801337411B370423834520B60460A884603204DDC45821BB9A2765BCAD98CE10F383A48EAE6541BBA2B1672D1502BAAF8B5F785006050F81DE1B7172843B00336E67075A7406AD10BA50C1F2EA0A475464F3DAF7C8F9E86E08DF93B36D52EBCED4378C3CFC390D768F081335674C9DAAB1FDFB65C69A57D4ACD4983DD8EAB25E81CFE2B8247EDAF1EB401052FA7ED0D5C34CAFE2B1FD6D2321865005A8A84F78C7EC76ADEE9780E0E411CF50B4E51AB91F72BAB048CAF5D8C146A519411797C95A9991D7F64955EE52EFE7686357F6D753F8E1C72976B44CD859EAF472BB9A36F5412EE3B8B1788AB4700A3E6F80CAEAF94A86D95030EFFB8EAF8BC7AC0409E397805D812FD13C88595994C634C7E27F508523DD90069706496E23D86A465F7B1529BF0E8B25159E12865C974228DA1A86C0F6CE07AFD99165FC16974308E1E29DDE745F23D48C52938DDAAC9CDD8495652211425E3910395EB1E1EB265BA8891C37E65057D59FE084B7D10C7183BB3899DE5232651E334C57DE7BAD7A749D1C530BDCC4B98A2F5D177FA639FA63506DBF8EABC22F0EEBA3CFF0B72AABFCDD475797509C3ECB7785D6D46085C1A919906C724520B3AA543BB95C255F61D78A1598804D813B8894FD14DFDB3DC2F62DE391AA7A0CBED7A7194053E1A6CAD33DD13DD25C4335CA2E21CB21233EC2E7391C5902AA15DD1079EB2A79E1D3BE6AE8D52DF61201CC53EE870DC4CC803D95F82FC751DAC5E5501A2198445650B699045BA4277B165B31F690244FA09468FE8FB9A39FD8E51A1AA4439F3D252404298539A15B5177583047F6963BCD0C81F5017AD60FD996C4298C91A5F13FADA828C84509F1D75E6A8C0F410922C67FB84A09299C50C520A5232A1FB975A3B640B8C7A766FDDF88C93C1001AED6BCD93F59389548B7A2794E14C3E3BD90347B88F4F1E3B38E8217429A736A1445037858A837A68E1663EB9605DB08DE5A5A3292D80A1A228C187377082977C32C5BBA5F35B07FB0C1162609D34A45E179538FD8D59BBD55BAE6DAB5F934D30FD465185CC46CB809DD0D2B9904CFC95D75ACC73C752B01214172441C4207CE5D39A2D6468D41DEB9788420D7DB0EDC0E77ADBB78C25EF7C5F135446D706410A6D9182203134164CD4085EC0FD1E99388671473727D8D337FC6643FF18CC9E05636278839446523E0FB5386C38B313D9B3AB44B0902B16A586A7F354767A2D8147A78CC99A636054B3B871176A63B628BF1C7B7F7D5F012791EE9DE6FDD4881CAB41BDD1AB0AAE1E0DF18989E9CBA459FB2B1AAF01DDA54C0A6C1E4DAC83B4990E048C9D193F9B3120E343AB245C850168B633265697BB3D8B7E12231E0001C3D1C53BBA27E39405694FD4ED247D3474EDF6842F31E365D044C32562233A728FB766FCD922D69E79ADE6379D9EBDBACFE0CDF45E64ADFA3862A4A28BF06BCD4D0016938D306BA07614532078858B7709751F946F59D6CEC4FAF2B86AE738C81BF444E1FAFCF4EC4F0321B1EF3EFEFAB3F0EAD135DEAA6F58C89180FF6234917E6731C352FED71659DA1FABEFDD9ECA6D6941B2E270D5A8F74E1944C48124C6AE366410056E173E54888C510FC6FAF75C56F8C20A2F9426C14EF6985091452AE672962D1E7579C825B869FD1E227A5A37A5496B8CD8EA204B4CA385D81F39662E51227CD248839BC405691BF6E702A8EE2D71670792BA463D90F875A221F5D156C39DF3725939FA1CEE78C824A9A9712FE3059C3345B38060805B069EF3F64A64BD25B32D011BFA885B0A5C71F0A355BB747993C329C235AB0230E2B951200EC6A674D7ED0CF4156620C351511018D0E3A884309A93648AE8E3A084A3D11938B4F748607D25354A301522E5B69EBDFA69C219C34F82DB9EE008981DBAA8B489584AFD28F24E146508D89780C08F798C8DD7703FA3ED0AAB87717DA52084F5755A431E1E7DF115766161A6D5D0479D7346CB20330EBB4D9F36AF99A605D084B5F279C144E4170606C64148E641F0EBF64B163D72A845DD47DAD6F9EFCC8C91D5E8CC35298E206F0ED82A819134DAB693E8B2E795F0C16E1CECC0809887F38ED25318DA2A1FE47F277B692F83EC15F7E05711422D85CD7417FEF0F0EDBBD7BFA978C9D8E9602496C0FF1B97939BC53B190F0CE0D6DF1694493512CB8446B01F7281BC7AD70686E44CB6BEC56CCBB4004924AC13C3698C808E53AF411C4FA1F848249661E07F0D171E20B10F3399C4C0BFD0324DA855F121CD1B043EF279E9781A0B6848618652FB4DFC55C618AE0D6E0E07A4DA2CAE185C1822FAD1E9C6A9FE01DD3D4AF54E00C2CB32A7A53ADA8342ED6A583B3386D8550B144713C39B9884AC9F5A7E2891317C71811D0FE", - "message": "B875BCE01C914651B9A9702999024A53E490CE42A80E8880514414076445A67190EEAF51B28F4FD1E15B4F4858DC64FFF69B4653E30E7667C76E706C6228AD09F2C906FD0241EE2AE3B1501E754FEEC1B0762F124E983A96ECB293A0BA3382327AC598479E157625AD95EC1DA563195A0E2A9FE55A28CE8A10A41279679BC0D0CFF6818FAAFDEC505C893A1D234A3BFE2BFA3C7A035228FC5443448B65D2AFE7B20F68E06245554BA5A337822423CE542F784C168373E037D6E4D4004892F3930B5E41F19F6A777711BFEDE389FEE029438C1D5966BA45F401084BD9BC670A9386C180044C11E14DD1B3D1C967E23F21BD916753257A558C638E0381B7492AE38854C5C9209DBAABE043D4BC47A98205890322E74B93E84C8BA1A207BDC190A66F1872E9E7C925DF79B2E70DC7E02D0595C04348EF9AFCFB3EAD92457D335EC7509B9C74AF18C6CC4B1181478F26F91DE6203B1B89E0410C8D2102AE9570F1FBFA7634C1FE1326D0DCCC2930A6891D415B28B66E2E593D855D9B88D5E9A399744228D1AC6755469C8F6974C6659FA715F7EB512EE53323CC229C1645B0B53A51938FCF4D9F142CAC579BA25125602173E0398A23F42C03127570C194019E3731BB99278712874E810E455AE845993DE43018E3E8E6F5EBBA16E2D5EE963AF2B284E8EA6244528CC3217119E0E61AF54A5F57CFF450BC1AA6FC6CD99F4B70F3272641033BE49C3CFF0D34A4019CE726F082205E8A6218F38723CEFE815299F8C672B5C70C0A776BBDE2320D44433D75FAED2B39433666DDEE4D0DB24F5A1E311A79E83E11E2131CBB6495F03F064195D61E589F83B371AEB1C6AA1F2632D053D2711486D81493538CAFECB4E517A3986D34E51FADF0A32EFFC153A5359FCBA8197A07E39FAFC9BC3E058F27E2706F046BDFBFF2DBE9CDD955B336A2D0D2581CD7CF25541C0F782D27C0097ACAF9E1356323778EBBA3773FCF23F217DDF07D47805A21C4A6D328E26E7B9552289CFD48CB13934D19D876F893CC2844F2E6A9BC133117C841AC49F7709167329C0A0BF767E5FD86AD907997226271EFCA9974D5AD315C3494652DC89941DD9370985B04BCF3DD66BB56EE7065AB2D6F75E2384E24D7CAF70EC8EA454BB9DC9C00DF4250D2E6D203E798AC77296BFC7EAA788276DDDE72B3E82DEB8FF6C5FE68CE18DC622AD8E7F859162D968AB225FA57E10A4A22ABB5DC416D28BADF2C1A152F372A4F655360B5C3A42293BBB32011E7CABB10DA2EA0F96742B58A8DAB9C7BA9E94AABC40DC412F1E478C2A51C1EF7F8B6657CA8C3FE79E3EE5C2A6652993B67C7AFDAAA19C74D4663D4D9A784E8C46C1BDC27E6044359C3F5C58B5A0B76C6BE20478DE18B12D5DE4B80EB1DC26FA87AB735DC18585CAE559166BDEEA599C74FF19C172D637CA2F8F58042B298EA29B3B331F3D2C5B75A3774F05D2E0BCA5E8E338407EC225CABAB08A2D0B3932245EE94C9B80327FAD3F98839890E27AA9AC533D6D5DED9BD7C6B351BCC98B1E370FDFF85D8A58F91650862E0AA9EC7E0C7D43B8197041F45746C6E47958D0235DA33D850EFEF7FD547CADAF5234D2AEBB3CAA8CECE8B17484DEF74587BD65C3FFD862ED58A7AAB70A3090DAE4D6D34E8C5EA1EF1CCFFBB080862CB9B5F22DF547927625836F0D5D1BC75CE8A9420AB198AD47B5A2AD56760DE64C55F4C67E57194A1CEF886BFBD404549C733609A6CCEC11703459473F5471FE917F3301A1A84A92E2500EE6C308D1A0FCE201D874AF658F67A66EB8FA0B9A2BD65B74CD7501469E4BBAA91C5C43C7DEFD5352D970485A164CB802E846864D9B6C6B3A9AE7CEF45FCB8210CEB5A2376A9EA54F4797068700E65C9C695102106C795ECE83BE66843C9AF9D007493062D92153FA56F2C6FA2AEEE8F16C0B8F49AB896A0F188B58CE890C420E913175E9E7B897F89AADA9D6787749EC8CEF808E998B117D33282B6119FEA7F0C93F7174DB65E0FC8A18C4BCF6AD2743EC72CD310D1B3E02A6415FC8B512016F6A9073AFCB366F4A108D99D78DB7BE82F0D0832B5E02914CEF3CAB3AB0017A13E05274B52018247F9E1B339E582D3F518C0FDA3F35F1B1DF45A3C7EFA5FD65542BE1F4CD194A82CB0FB91D0FE1E6E0A72C51381555A605D51F8DFFB2E32438AB2B157548C45BA2B4153FD54BC6C15D3556AB13DEA88079A13AB928BBFEA7FAE4F4E3D14F1C3742303FD0A5DF47309E3849EE5ADE092D8F0C549170169BE294BB0F1C7C5509A723B1892D0C379CCE32BACFB4AE93630A017138EAE64FF8CB5D4C18329D89EB5DECE871BDE81AAEC7E73AE168E1E92EACFDACA667B2F68FA57F6137BB0F84091413A1ADCD3050A6A7E8FBD165F5683C94F717B6A6AE0F0F9AB5B21E8EB297C3C8A0D6D11E7E15C4B4434476C28135678DEFEA42D34CB9FAF4C02BE30504F9EC6FCE62AB6CE62C7F49EB036098F3DFB698B723789EF7922B5C33B73AFD6FAFB7B3ED7A9237DE2EB168894A6578163EAC0B1942B4CCADC9DA60AA898B97850884407B76D7AFDADFEB7BE01668D1F2C5D5CF5EC005F3F0233AB51A6D17B99A918EF21C583DFC0E0ACB2F46A4EFD88EF4CDB233263913FAA0A8A972E5BA95FF2210CFFEE7C6C08818F597D3F09498DCAD9AD50306EBBB617DD9E318B604F3929F2FDB4DBC7629C9D0B91EE1AA81D483B16F77D95D351F0D6E8C650190913137D73265D5285A3C1574223825E929EDE2EB73A9F74CCAD4F4F4F3A7F89B9DEC08EF080B8874BFF76B66C494223A0401167500AF8C9A203FD2CADA852FB5A2DA18446239EA3062E38AF044278CAD9FDF8A136D9B75A6307B18F24BEB684AF7AF8E4141B2099E2474107645BD0539221EB632D01765312B5A067BC80EB47369D0BD5950BEBC46125A3AC2CC90F046E6D0F0F05EC21BA4F8EEFFFE081BE85F46ED1745F3FC1A231F1504FBCC6E101B581E87A06DFB507126B1457AD1DB5B17460720ECAC58557E816EFBBF4332664E69C1D963332E5677C9B39E596AAB920AC4583E22AC89ED2171CADEC4631A34B50AB02663D61F6F7429DD668979C73950236ED987F760FE8035BF7292A28045304D1810A40BB5699DD025839B0A22D0F45D7144B85A81CD1B5422294FAD4FA9BD6870AC4ACB96D178172419C48C42A26F0F2FE24C4DBDA0F952DC3ADD2D80B1E9FA1FEDAC81D0244FBD82660B8B2FF78F0F56D06F3993CD562D3E2AEFD69F0A8D3F94F483D1A1B5DF9F1BE01B03CE377DCC117C380DE18EFE93BF5E47AFB35BADAD69D9B2ADB3A07B8EEE50B89261057B85CAA3223CA7F70957A237722D44BDFFC4727C0949BD486F43A8DFF4FAD690DB217B9C6DA310101973137FF622E4145ED34B9F233C36F7123846425CB16A2CC7986A5631A3913B5395A84040DF80B585F5916F17AE293587BD3FFEEE73B5C1B3644F76D86A19E042533D5C61BEB4422734C602832D81171F32C05B93D39E90F219FEF521A7EA5C08149C98C538784808C3D27D04A7DBB259612EC2C61204EEFBF294DA06BD1609A1DABA6EEFDA883DF5866D98C28A9386F405B237A19C26C2738C734D766DDE766C94F7983EDFB80BA8D05EECD4786B6F400B47D533729EA972E93EA7E6210E547342013DE9D3824BDAE5AA403599ABA224696E74C241C86DC2E17BB12B92F153209486802A9FC8BE801A26FBE0618AEEAA5A3AE7742EE909D23BCDA2820255F1E19AB1C088560C6F40E2A3AB5B9AA99093FDC37194D2EDD2551EE6270F099123B572968A021EDC7DDBCFCA62013E18B862CCBC23361B747824B3DF64D3E83F0B44A4D964530C6D4011098D095B02963473BA1F3E14E5D89EE6E9866F6EFD8768D91564A7629C72720AD1090EAA5B61BB234E525B410820B94C4C00C57E68212A183764CCBDC972C605603645AF24DAE7BF04D780179F903DE22260D55277D24116B833754310BFFADE69EAE13602EBBD21534D50A937D24BBCA7DD7DB4413FF0417C489AD1FC4AFC5570C7F9DB5CD5BFA02526927823BD6F4305718E1D157B9663C63E1BC29BD247E5B57466A725412E35FA933FE793B68F981B26A44430B1D9E76F1F2C8B1BBA33550E262EA3558A79B9C5BEDEFF530572F2B9377CCF27561BE427BC219EFAF3E4C98282ED16A948CF97F5DBAA4CA5F19390BE277F0073C5E7FB4CD7FC15126F85600B84E0F696311A3837F0951F4158CC13D1340E8053F04E73897357C370F7988AEAEBA5721574C4CCA7D2F0C239616E949B7D1CAAEA605BB0F7067B6B0DC20B28C2CE70BFFD6780FDEEF8F0BFA13589F4DE55858C205B596BABA2D9A672A3B59882A207B3564CFA20F94D0633CBF753C0BCEE0EC36A9DDADA81D70CF7988A3AE53CCCA7050636D2ED28F02A0B25DB32A89A6230BD88F25539A71DFA393A131123482C1F0EAFEE32ED9B97B5CFD781E87C10471AA9BD83114BCB56F349146E84EEBFF18D1E5742FFA51BEE30AA4E2080AA571EA7CF01D114C54A66519F935EDBCC41F3E0682C4F8AB8061C8AC2485BB22CE68697F03AC6E2A059A96DE20B05B196B088F5F04D7720FF0ED295E4717E7EB8485C9544E58C4537F43DEF5D4E999AABF0FC30C7040A798BCB8D7C800ED6DE38F6AC7B95A1A292F14009FAC702FC7C7B62A4BB5FB77554B3F236E7887D9541FEF4E249CB04FD40AC5BF84C68BE6BC2B305EA1550C5D32B40677082E25EEEE99C72B932C5BF826577F58132D2C5CC34752946675721C4B837B7F94D7A75363D8ECB0224F2E0EC096D4147158E0AD349B4FAF8288C6DA49EA7BC13B1B8FFA6CF0B0F4DA60F712F7D41C2D50BC06C644B69B23D2144413CCC6101A6226E3DCC424D1771E2564CFBE21C4C69C93A15A04DDE71FF8531F3D68CE193E30B634BB9BB9C0F1160AA32CD59377F151ACE2E60541D096E27E958416E782C2523A63351315737F7AA79BD473C99D8ED83525EA916C7894EB47D10E383A98B2DF17F673214F27779773527ED5BBDDB38DCEBFAF9961D948AD85843A8D0BF3CC257190517D2B5C97E5BF4C6AB4261970825F192B07BE236F69749E7DE60C37E4DE07A5EF2C5F13A7F9C66DBDD143BD4C036B47C4EFD1D4CB60BDB190D2555D537C1EAD72731DDBCA2309FDDB89832D1A0571D34460B3028C79190C082A36B0F6A2F740FE5DC2BED6AFA778F25E4EE46CC5DBC7824BFF4BBC1C0B3431F38B729BFB5B296DEFF3F6CCF41F44AB701F98AE4A00939CD2AB51CC6530F1538FB2F5F352E811F6FC2E6C59779A2E9DCCB0ED0E5FC3E3E97EC5840C51269C5C4C6D6722BC105B5D2EF7712EEA126157B8A3F2028C3EC1F6D4B203AE463FEE6E5D566CD8F2E741BEB3794D21BAB89C8273CB4C4094FAB2B946590AFDCE0FD77C182CE78694D52205E387FD3FF80850DFB0D2BE1DBB069A45DD01AD14ED2445B0B846290A984C5432E808462F4090BAF46EF72214C08FC241367FD2E9070B0E2AB63DCFB3FCBED7D2E67EAD7E48D1C5B0EAB51FFB4FFCEE88F925C86F1F3BB096868F000540A5A98EF37210AE18BB67FFEFF225B8A195BAB6430F59A64CCA44F72DC539B0D0B4A2106DC19109B3319752CB153A6333DE5BC03FD1BAE2B5164F857BC3E0AF0D331529555896FD55F987FDF20EBC9C4FC0BB0E7547E3E5DEF86803BEE7033B2F896188B18A24EEECD10723B698DA1E1A0E6C7FFE0F396EBBC6B37A4683CE5D1C3E96CC2CD7AABC3FBA1EAFB69FAC9172AE878D442079C5568E5F5C4664A80A80BDC2632A4DCDA19CB09F78D590FC1B23F9DEEF8D4F1ADFA2C019F979476CDF32F33FB3BBD08B519E14DD5FFF1B867087D9A3B343DBFEC0707D33B69E6BB6790F9E945C0184F4C7AC21CB8C108B5CD577B8652FC07C7DC7504137B097387269A1EDEA5BF1FE28ED08642FC0A24E01A82DCBEE11D55766FAFA865A2A72FD2BDCE26DDB12348AA166C93A872777774DAA6BAAADC31555D77CFF1FE69364F227908BA738F0F96D52DB8F0466ACD3661AE019BE1C998DB7841A5DD47F8765306A2FE65B8D9157676987443B7B997035507EA64BC4CE210EEB1939905763F497170A9ED6E124E5C02CDD8D3DA879D0BDAAB538731E7C3B0906C87F73528445F7C5ECB54B571AEA88F2C5C8FFD828D66B8C8C149C5AB983CC56F5F1CCADD786F5DD65667EE45D49BF51932DA14992FEF7942D4AD879225D2B6B99A9A1DA3C1C1F671192D71F6A98D7648DBFB8E5EE65FF96CB08C9F7ED076F3C85E97C34AE4D114B1290AF9195C39CF642C680929AB15416DD4F274D6732F7C1236CE3078F192A0E525296437CDDE6F3563129E4C893A968F10C4ED95C639EA8D32B6E7CB7F3286CAA4826441A45222B2983B106DBCBEC92E89AFAB786D5577996B0889F080F77073705B0B4269203EBC3D4AFB3DC35595CCA778B2EFA5F715AFD4DD61D31E600D8378D3B3427B70A74C9F516F73054C66DCDBA8508E7AE957239D76C3107CCE1DACCE008A3A22616508073DD90D1AA32697EDDEA12C0CCB83F31DE5A3E078AE7A785E8A263BE454BB7CD45D5A0EEC650941673BCEE7366C26E43C6E8EEDEE4955513CC56223E49DD3BCC5D79823BFB061ACC39239DE0FB73DC0BE1AC9C80171547C8109CF5E01DCD39119CEAE743CE50EF636906F42B5E66AFC137400C82EED7B644BC508BEB6983D22D4EFB46AB35134CED2E8B58CE5A03199C875E64F0FA870CE3951C571A3D1EEEC1D54E2F770237209B31060AFBBB4C61136BC90A5744A87B7D7249E255AF7DF43986131BBB17846592B6A99876057F2C78710697325874D5F00A47FB68C9D744CA7D0F7BE8C4D31A03FB62CC1A9885C46EB1AC2DF447714901FBDF8E328761F483C331FCCAEEDE249FFADFA3A176D1D0987983CABE5B08FB79D969C7E97215E29F0343EB691E3DF27C6B88FC43EB226BC2C901476901F8C7AE9A1B07E05B9027F7228FC4E2949999C0EDCBB722B69694E14A227A9A0C042EC7257F02B8FEDF4723AAB2D98004B5E5439B536E30C0EC2D9DD406BFA3B3D2A9FB0FC89779DD35135BFB780FE43369E709C52D6CB6FF3E90BCF8DFED123A439BBA970CE9ECBFAA7107096E6E50A9267DC118FAE64F8C4107F8B456244E3C1DC96AC9B80BB02AFF04AC7CF9F7073745131C2D2A2F04AD6472A2BC14ECC357ED010075A595BD43AAEC48FE94B3FFE3C40DA0197B3B3E1E3F0F5E754E5B1748024130F9DBCC44E52D9869694E43BDC3E8F1182C34C6981EFADC42E97BEADB145696425176E8D5DD39D5DF135939FA81F8DA602A706EDE4592A6E1B0A97DBB0DABC3A248C5B59E491B889A120B2BC4DC8CEB6637F887D8F8DF07071432F165D3E7EB3E1E15866D5F1258B14866BD4D9ABB13A10E50A3F8EAE2B7CF3215B0A2CDD000D058C580F02DFAB7DAF071BBB0AE3A1DC5D4BE36D4B743049F05B46717EC492203176C87B881E85F44255A3CEE82BD849A2D9CEBF0D4183CE07E01D88D3FDD352C5F3D6E33D54B61BFAE0AECF42382A1DE42A7F421758241859F5D03E2A70E4F114E5F71249CC74222BD6173159DDB3D81E4809C8EEE838CD0610AFA176D1F20211F89CF6104865EDE36E3A50253A28F99757001C8306F9B1EC175AAFAA578066263C6B82D74B3F2E648CCFD8AA24E460C04A090738284E8D7B74415F66CA6AB346E475099AE943905E4844C18475262D66B17A151AC74AAB36066C1AEB9D66A95E545DC0424B123A5F13CE82C38493E79F2CECDD73C91794B4C754BD23A2B42CCB0846286CB55A438EEDDE225BFF629AC38FCD9FBA31B1A47CBA85AC9EA1283D462A72361F57775CCC970F256D944F3A63F36E4BDFFA574D4E657FD41216EA9E134BC69B39D68E21CBAD9A018EF009FC8E97B3894F3B790CC5AC1C9D8942FA56A89E156780DDD2277CAD7759071CF95AF2F9270C7D932C38A347791C0DFADF42F6912E784B0CF5B5A4312C7B642C543EC81A985885F0E7C7066074868386689928DB755B4BB1759B51BD0D656A329927DDFC926693F82E7BEC7A29C0984762B19686AE0D44223B5A813C50B47CD44130210CDDE647FF2FD6E8C97D871BF6C7A2617A39AB72CA34ABE2EA65C3CF074569F145B76FF9D42BD03210D778CE1E34E6F01FCBB24E3275E87CC7BA73DF61F7B0424B9550EDC7C22D2C77EDE8A2A163AD5E3535B6C787A596969537CBF1585820097A2A31BB931C25D68339E3C91C7DA483BBCC2781F13A6C7D50E3F9FDA8A0666BA7052055F7591A5CB7B7F1E412E78A9F2564A1BEB3C71EAA702914AD78ED9E751E06B0971CD9F85D8AEB591FE4DCA6759172EB3725746267AC4D2FFFB6A53800D7D6B0C96D1C0200ABC733263ECAE79028DB52B0FE665BDEC01DB31EEA9424BE0187DADC6CCF50E423D9AD715332856F6C0A83EB634998B2A32D88BE0025EA49489658B42A43AAACC6B60A97190F0C48DBC344C4ED7D546A4C0520077C179A2E60C6806F7B6122A0DF7168B7B3E4B7C334F4C5AA545B0FC8F5D4155CF47A2E2F6DCE8BD0C2414DA16DA92FFD464A4E615214819A36F7ECFC9742A0B9028059FF6EAEF2025619E7C69F0C924147A71BA69D27DD5E699CCE5FC0D1EABA07DCAE0FEA679461E0DB993F72EB26F557ADCE720CB885B08044570300E2DDEF495AA1C601F9FF1619285F22E86D92C09FDF429EC12414B992BFF9E97DAD8A4FFE71AD05BBC6D4AA4C9F96117228608A2DD4B09B32DC60E6606D8CD6943BA5BF39C14B48F7C095406A757B321A75171F869E25136CC41149CA94C641173F1FB7C1B0868937F72842F81D5F44163B7B26BEA415B3F3676FC05A833010039D6DC9B9816D859BD5C39C52188ACC847BCD0AA4D9EE7508D9493F46225F0B837A6B72E9E3BFE34620009D291E8D4CA6A5F2B98EC39A7F0047BD7974B3B5AC62ECBAEF65317287254BDE3F58EECCC642BDE2FBDEC1E84E59C0B45C6AE53F146F598BE5E4D00A89A1C17B6701E44FB494285EA3C81505EED29FBF6FBB1448A0B2D02398A360EEA151BB10D4A0BADE19206F60B385E1F492F23F56C3815C44B2962C21EFFD602404DBE485CCA7F81E296330CC0FC6EECCE4C02108D775CA85E777C8CCBED43159EC6F379252C6B4B3FB16CC9E0743BC7B62EB0611575C934C6E375C716BE324E5F1480FBC4241A7EAE178557AB238CD43E924BFE3BA3291FC2B89E3FAB1963C50817EC6D497A5A022CEB053E948CEC652321E079833B664C81CA751F27476AB3561AE49888AFF51F0CCF3AA2EFABE937D7C58715CCB9DFECB0751C3F9967D2668DF5EA7EC3C42AAA36AD33632816C19E090F87F9AEF8A84199A75CB2592CCD403362B8B14AF2465EBE350D75FB79940C28756B67A805C946A635710A22E9DF43232FDCBD23E91474762FFF773E4F760AB27F9C386FF16F101FDB9B5E67BD8DBEAC4BC57184478CC4AEDB591716E8214193D9C8B0A78B8FE9A06004AFADC24FCF46155F5F9109E47B3043C4FFDA1071238A4821B78DD4D30BAB567B68C2BC0873DA3328870CAC8AB49055857B973B3F1CC9C76BB5352A036F9D6B0C1CBE75D1B5BF5C3A1A2C3AEBF6FE56E290437177B77239DD9372C7CF144E55C2F7A2890B72E6C9EC0FF2B256A65BDD7D053F51C45F63AEA5C9E7B77EAC6B2DCD83E046D47C5C21E208D0DB661803C54BF1733A411BD8A23E77066794C9D1BCEA59CB596BA6CFF140816D9C01A125AC317C805069568699DC4CEDA36E9CA24FA4D27D8CC53441CC41DD90C8B4B5EF2B1A74043618768F68E5908DAC7310CED1492151F1CD402035B299C6F8BE6B296AF960B43C6DEB71F6C34ACCE569F46608D54F34DE1FE88CCEB17122896D52B3B276F6A0D919A4207D0071D9590FD1A6D523344A711EA0619939CDE18D6971689CA4DBB710C9893C20C0527E8082C69C92FF8BFBD5EF578E2E066A6255C5E1CF7EF15B1FAB64A6601E0939C9ACCE67049C23A66F38F05AF8C4871CB629A8465A8AFE4DE88663BF396EC4EB2FE71C154ABD930B9C1F6BCECCDAE1826A9E15240A3921E5C1182598A8BFC6DA06BC34D947F2BACB4EB2807B6FBF660D1E0B7FFF49CBA864C063070588E2BD1C9BDA8D32E8008DEA9D5EEFB29EE248C81EAD7A65DC61B594EF1DD9D5DC58293E641E5DB78884BB98705B60FE5F97819A38E35DB220223BF89216B7A498FE45FE5C4F49207D81AC7B609A87175947ABA6C172D32157868DAE3EDA3935001C33F872BA460B3E420D0C05B439ADD079D3CB4BB7C0CBF7B7B9A25B88628A8DB2309A4858902C13F75E813ECAD91029E836A165C6E731B67B5103E759029CC44CD7DFC56296071B389133E8774748BBA0FC5E2427D76491F6FDDE60AC65A52A46F8861395B125465BC93C2A7827B35AB1AF4DFE2DE3BDD2EA747688DD62E474BCAC102AA2FA6AEEFA8B07E4A94E056D85BCC290DA61D65623280D009F20D262ADE5797E94391674402760043AE0FAF87416A8AFC5925A362AA463B86EAB155B9041C5A3477A832E6C8822349701FB87E07CABB47B63A47389C0F9186782FC635CF8063567DB741FCB24136905E4F623BCCB3B6B0E715397772D7FBB9A4F537FF228198E25B8521CE7B926CFFA1BA0087B9367BA02EE8B75872CEDBAF85BD9F1F40D85A6ED72B724863D5A99E6DAC365E877167340478D77CE0601DDDCD95A41530DAABE8088809207A8028F665A7B8809CA93529D2CFE9ECB062F6D05BECC88CDC0F36262CC2F7CC9B4A03FE5587EFD73069BA9612702476F0D8AB0044A46A8E7E7E8E457EF8EA573F57A9F746EAB56B733B74C66B470B5A54B52F172A371", - "rnd": "C4702883C0128CFD006755AC065EABBF039FB341C0D88B1FEBEF3600AC717D87", - "signature": "9B656484360D584EBBC561E4228CFE751D8981F330905498F4FEC740B86A68947B0F03B26369B2C6F1736F71665CD908D0A9382921B44997341F21AF9CBE25F5CA6ED5E803E13E61EFDAA5CDB97582D8BC47AD25027CB9950E7BEF9DA9F91DB83271761AD7588B187864E2BEA2ECC03C1B0BE45DAB362AF7F6536ED797FB28347C449F0A281B00ECEBE777EBFF66C5CD098F36ABA40D79EC58F3F7BAEF75A704B64C9FD61880EBB79B09E66A6A3B50C1AF84E8AE60B5E071BEAD1BF5B4218389FD6F46EE6EF96C81C44F7A801F3DCEAA832C02771C9A5091A867851B6784E2F978AF4A37D509138D152040A9CF72EFA9FDD08345773F5825CFDFB288BCB26AFF31C85AA6E824C106ED1ECBCDA37FC4103B57FB7D917A8B479A74F78A691F57482A29E2A5422418BE919DCFC6C58287590D6EB21BA4A60292C7077A619CB429BE30B52A5DFA485949279BA0ADB334488FCEDA56E09A9270E847EA1D11FAD6C84EB415235511A5B4EBC734D1E56262D248B930BC9499EAE946C8E63B3D4050FC44043FC45DD43EB5F0E321D6B2D1360EDD25EEA1DD06FA0471A81587AE39A67AB6EAE3253307559BF3C4EF17004B3FB4BB19962091DF15B87FE2C3CF2A9C9936F14D5D7C8278A26DDB767430544ADB3CFB8D91009166242D74DF15D25C6C95AB8C567B9811F661F69B7D3CCB41CA9D35A96F965152DF666EC38852A8E188242860948E807B05D32B7D88E2C11D240B4DA6BC3F41960A410B17D980CB4079EB163D0646768799663C0832A901BFECE8114C09887A36A13471CD50312B7825131EB66B212F680D3E8625EFA9CEF441B8AFDACE6DC43010782B75D4244ECA653E167BA324D67264CD521D31F95CBFEE107CA75976EA4FAD7156F8D2877D41435860D4216AC622242F768DB85DB6831A12FD4C5E911F9B4785771C4AE378AC0E4FE59A47F14810A045BED620EBE88BA19A926BC8E8EB88646C0ADE577E0236C3F565F7D00F2C66415D2A66606C091DACAFD6600AEA16FC802C9EF260A9E502A47ED1D6A433C4E6CE89A15F253573760612281C3D7C69F3F0B69CF3DBCAA2952F56B859D45E9A8D95EAF99A262D9BF69951199BB7CB067E1B2B0E26DC5B76B8CF958143F52ACC814E27D2220EDA58ED509DF9FE832E5AC3CEA7DA4A96B1E1BF396611A23887296194C359163908AB988B6CC71EEDF00D994F065EB75EA5BBB56441D976C2300786F1E232EFAA9E7140D2C7028C1D26AE7B6783C960C515B82D3DB4C74237CAEC8F31DF9104FCC4B5FAC9FA7E5092354658AFAB5C95FD80BCC921E16D803831945C3A860C6A60669DD9F0BCF6FA1B647CF357F4697CB5531BC09C8982C00415D84EFA66B572DB38A98003623C04ADC0F06DC9E34679EC1B0AD7B746F2C8CAF9719343EC0263EF8BD2511134E585E871EF3ADB08C2262A335CB7CC43DC506925EAE3B8DE9B6BA14F23D401E84B781D8A7AA7374AFABDAE863DC67BDBB8E5F91145E143A37E5D30C3EBC36C3B48BC94DB0232B7C3A4B3F27835F3F1858890D3813E37D2DF8143072C09D6CF0540EE6D2258B1C1D6A669C9CBC69BB31FE2E59FE4F42D0CF7A6D8058A7C4C488BCC58D854486E0A2F304E73D8E9C0BF04A4977E6254D398BB9EBDD06D7A2E840BA37915F05EE6C5DAAD484ACDD582849A08327E50838679A130F8F836BBA4AB3E53679ED4ECFA29474CAB9DCADFBA5CF5A6CDBB869FF8D305936C8744CF32B64F069F48FEF319E31C3DCB336B44486CCE2EE80F144A85F2A2BCC570649B128AB1EC1585AD72C96BCCA3A9B9CA5AAAB395095CEF6EC61CDE3133DD1C5E563CB7D04BDBCB117BCA2F2E2D724B559D38D09107040385C27813224D865D11076E11EF327381C0501BCE48E70E1D8188BFD5ECEC7A40356320EED2994277D3CC1210E7489A1E5380EB0B8106C2F068D0ACF1F38D9A02F470662B6658A20F4DFCF5C4D8AE8BD6F9B19E02C1F0B598CDA7C76D244FBA63754766A6AD1A0C4C240AC0FBAF6F817D29E159B9BB408E1C8853E3DBEDF24EB570327F509A35450EE26141184664C09D1A38C57145AA62648FEAD40FD2A0BA38D04A2E2F0A36E657D1EBBEA4ECBE43C5051A7625FC2CD0C2FDEF6C405A0A928CA0378F7616A79BCC6E526ADA5BC056AE6C51A1B9EBAF6803298681BBC0F87233E334A317583A48A53D9D6306149798DF59885B1D483EE84DF599F431C1BCEEB2EBB0850F61DAE0FBBA6662C425557DF09FADD85A8F0FBA7396A6546173CC1CE5BF871B54BDE32E8D5C70379C3C77C2ACF9750E99E8C89946B77C7FBDF149ED8ABAD75109EB0F0B061D69530ABA0862D29F4755CD7D6DC39AD5DD4DE322CCC26B20D1632D7A87DA5AACC10A4854E15918F79FE5D5B25F5BCA4D6CFBD6F308057A9C5DBBDCA4A8F2CC302404E1E0531523889A1C1441FC4CBD349A0EB9D65DB02C2493E3A83B305757F9B030854D769DEE03CBEB116929476330941D14C2C7A6A7E46C050438C90CE6C90339D4BEAD07D26D9B7CD212F523ACEEE20B5EED6EC7FC4EA7984AC3EFDB259CC18D421E7E694EFBE045C386E8648F4BBB0A387C0C8AC135B470EE484169C8E5BB69FAA4266274E34E28C0E7C2C371CC924BBC0DE5A5F33E61067F9108A7490FAA80F5247AA8451A6C3341A32F699A071502E5C9D703A98BDF6CBB1848664DD5374202B45BC518CE2619529764A12EA1787F12F7542A06CC9500E279B701EC8B5417B2581CD27A3554C56B0688360A82D12732F0443D1B6DB26C3A01A06851C5F5334DB0AA432B769FF096ACBB6F0CF9EBEBBF86BA1E6E08FF0072D209708FB437EC6B274E45427FEDDF805C56B0D8C3B9DF591CFD3DABFDF3D49CD39E805183E0F44E3E62EA41D512E01AED7D9B46A8CDE19C4D0E9B52D602882B5D3712898C21F833C5B48DC0261B6D82179AC64E04FAC063977313BE58B86BEBBC4769DEF6F961AF175D28D904DD0D7FD06BA5B9C8167A7959945BAFA3CA6FDCDCD030F6CC89C03B5EB533EAB2477F3932C3C7C9E9D50523B2814C915E6F4536B09BD4645B7FD2B5A628EBC9F37FD73634BEA5640B1F88B604DBFB60A1F6850717A7F034E38B459A5C111340AB3140F48E9A9A37353720CEA905814F92833B430B19C02C70C2631A74EBAEA4D7F319DC07B5562493685AD2ED5C918B8EBBAAEFB5A052AF6A524BEDC0B51EA2829EC1C1223EB10DB589AF71192B2FE73FDB097299B6E42BFBF08719578358545A53272159977F7D2256243DFE9A68D5DE17A860F4737145E0E1A1DEFF0B7472B4FDF68F994C8A573E296FFF1FA82F2B3E5C62648390ACB6B7C2E3E901212A547177797EABD6EE0C1653636C759BAFC9F707122227476A6D83888F93959EA5AFB6BADADEF7F8000000000000000000000000000000000000000000000000000D182237" - }, - { - "tcId": 18, - "deferred": false, - "sk": "A38FC76EC369291C0C3F2B03F1B8B301701E47B4E85FAC27C29223F71C0A2CC9C5DE18967E2617B512611C1B6F8BF42EDBEF11C78FD21EC9E474DDB52038ED850D6B9CD00B8095A7431DB26F236973F1C7F2A3B5EE61DF9A84DED3AD817358E76B1601C6EC9113A9BD1E6A47CCB422B89720FD47FB1496AB2E6BFA8F19D259B1884049C4A480DC888C0A0289E0248E124810CCA288112685530271D4382C21836C0B492403378163024592A8881C93059232108326501C2110E1A8710A0846D2202C01086A08481011817124932409886053C2415B188C61B02CD3022013A40084C42CDB06014B200160B4210331851BA88098481204456948422D4AA8108428648B40455B36825830826292015C948009C42D5C382A449861CA34045BA644E032301B140D19C4651BB4084426314032095B38929B404C60220892986C19C005C9B44458C0281BC20193008E64340A20C74DC212281391652400909A882819C480C834819C08300C429091A890C2C2891B2910C9928CDAC46C11168A24894822374043904101204C940652C290480C4169A1164E53220A1AA90423008C1A256A1A498204800D1116881C244618B669E046646146694A168812B30083460C892800A4842DD8408C04944909102A53A2610BC00D89088D9A162D0A3221CAC049E0A22002278A00289223133111274E48028D0CA67113162410458521A72DE22830E314720141400140294988250CA22DC9102D00C24CD92665004244C336720A36321C29700B0661E480651947241B41640B1824103469C1C671C3224E93868554A60D21A3514BA8204832409044915B4610131932DC864D1B286E24952C12492519800C1CA170511292239550C9C82410380223C98863C44DC3988581106552124A09322DA424109024000CA8015032208446221492812131200C998D1120611C388984A22884082D8420699C904CE3146DD1169202416002C56C4148681BC44C4C00064930618C3860A0280ED14670C48250494844100990133906E3A840240844A43641C9244DD3840591982C8B28325A140D019304DA04720893099B141281108552340161224E44140EC2928812C484E34048C8B02502156113B5705B1480C4961158A22C10280D1B1521A226810326409232129918800B0489C9064602C570D40440A206200183659BB8249910320C050651484160C44C049729182945C32245D036089A148A24050E51222511B0490935801A012024841040A65111956C06912550D9135EB2E4CE029E8040CAD3BE1AA494C9826CAB5C3CC5AE8BEE5F49DC41C872944A93012FA8721EECB46EC703C6FC1796C3D208B240A5E58A02A49CBE783ECE50DEE4F0A89C7DE37A420A5755547C09FAABEECA90C3F27662A4E5E5BD113690AEE27C720F055444000F1776CB94D82AE1BC676019DAA8241F7F68A291F25AA4CD3DAB2F98B1A3F2DD8126F9C9AE35DEEAAD341B0A353D95C8782A85E075D0C263AD22C3970DE74B5F54A603BDB71C5598F9F64B2B744EA948729690ED7BAB65F890B8EA1AD27B3E888F251B76EDFEDCB69F2429608BB05D9935A0B489B7EABEB77EDF8EEC529E1EE7C3DFA4188D1085BE937A4164EACAAD4014F299DB16DA14105C16EE7BBC431F48AD9264CB70CB26AEC7A87534733C0B6A6EFF359A99EA24AEDA08AA525129D5849A04F1E220B31A530C1754A660EA205DBD7AED093521DEBBD89EE62AE8E04B99968668B462EB4C4C1F24225FA22B86047F9179719B00EA82D1ED05582FFD74BDA4F0E6F25B9BEC8052F61775F512E305530BAABF71C043DAF1346B775B6929B8ECEB05EF3F4A31E495B0F08C9E85E0A083F75A7D6D5327514FD36CEF1BC693185E1B7D14DDAE8B476D18279DD0902410C8883DD5A31F98A7C2043247ABF058F7486E3BA19011C92217675497F41F29EEB555FE192B1F27F466EC445F0ADA9C6641DF81246A2E5CBC46A3760F8B59542BB13089FE2632E40DA23239B9FEE05D3273BF5731E28A7155EB3C0079D8C7F8C014E666CF559A9593B7A78F1E0883FF5E0BB8C8DA9DB09579907E2AFD3A144A9883C2C0A28FAF2BC3CF105F327A497956A13D3212A2F2F88FE30B899C883929F091F1050F9119BA8245CED94072AA14B840C15FE4B83F62AC1C6CAB8232B6720FB2DBEC9FC5DC62983F6CB2B9E035365C7E9034976B4FF954610FA3F70F4AECC364C78FC73008552FF92E83AD2CA67D9982E94E1F6C6B68E7DB4E138414219AA3F34AEDB09B932AB9D3A665662DE72C7BA6F007E48B3B4848C08BE2A548956E2B9563443F677104209EF51D01A74476C689C05037EA8D92DED7FED1073A5D8A6899C6F55416F709C1731AD81CE463C532C5BF0F150F6AECFE2F7B67CBD680388CCD1D819BD9980F6EE76D04E3AD13CC2E0A0DA86559E0268FB1653748C9CED7AB3E80FA1554D3EDDC8F8ED836A89BC8F5656457427EC920AB97BFA4B74E34F3516B38AB0A5CAE3A66C9E76A9C1FF73CE81AEF9A40A2DDD5383161C716EEA5C115FAE2E6C85EB15A69EFBEC343C019720D634FD351B2898F21FD257C52BCDC31FAB05226CB40E8FAEA38117584392EF9B60423249199CDE0127B98FEE1430BFAD5878FC5CEE87997B4EF20425633FEE2F63C13A0BD85DC02BDF9157CDCD50DDA1C2E8CE54068410F42804E4A06A4823341DF13B48579F83CF40C3027A33B4D80C891BC5AF9061C837EC83D3CAD0EEBC308EA43BD19E079001CE2F1B05AE16C8D82163F87E4AA6B3C1EAAB04B252F161CECA2470116CC10B50037B0336D3126964E31B4F1E1FFB55577F99288BFF7B74596C6A480F17596C7A0DF2CA17F58AA102607936292392CF46E538B6A5C8854CEB839473BAD879BD14845BA9C520F99AE772551B66033501C9D82F2B211A3E225267614B06B51DA3C229EC8180DB3EDE1C1EFFC7FC9C367244FA55F3CED6622324786DA01E448662CA18055116B2BB59AF35B93BB6636DD127AF3D06F0812F66F5278AE70A4E7D556378DE4068DB6E30FBFFDB3B9896BC17190F9B59E0811608700774846846D0CDCE09C36E8372808754A650956F8904A048CEC4A8A86CAA6276793473CEF322B9C6EE737F2C01ED1EF88156DEADE1520B3945C0EF0787A894D1C58F376A13BDB58E366563612FC717AE9A92F0189AA67EE8E8DD609DE2A21EE7D42ADDF520B80410D28D02BD4143DABC6E45AD3C2201185FA25FCE489799820872F794F7833E8CC03F086C171B052E3D9FDCBC7122D6FA89E7528FC6AD45D01CC3004387BA3926B99EF745BC00B608426A9754A1D0FEC97855652CA350BEDE5E8741F2CC1C0CB0E6410FCC14256A74082BE0F7CA43DD3FCD59716D7CCF06C665E5F8DCDEFA86A4AEE1844FBDCF2805685CDAFE578922D59AAEEF9A650ECAC307285562156596D49800ECAB42581ABE6D58BE2B5E394B0C1539BB13E60DEBA7A0A7465F34C521FFD77FA5C638BB8700718CC7478DC8959C5346DB7CA9BA8E1C8523C087D3C157E91F133FD31D764E8B8C94788176CD62884D09BDB452F5B5ED2103A5F1FF393FDEC8951F339A9E82E6D7F5A90769CBEB95891F93D20E39B7A2E685154E61B772BC9E4A92C7EADFB00C7D7B902C2", - "message": "590C53BD0219BBCDA80BB6259B17629CF4A0741168696D95AF63F375677A6014F5CE9A667793A578157C3E0C1490480EE28CA305E7B27EF472CA50A791D149E717CAB6E425452898A55BC3E65EDF60FF0B8447B06178DFACB3C0ABA02B4BD3D8629DEB749054932A3D057DC65E31B41D6A7BF365AAAB84033F4639B96F669D2322211812FDCA7BFFEAF15CE67B1EF2ED791A06C86FF6FA7AAFE93F0B547D1B99EBF9E5501E2E387044635BA42634EC7F528D378AFF891D07723741353BBF624595831A689E447BB1A406528DFD6CB2F01E7BCBB7C3B11D066283959ADFDD7696F05811D8240BFA1E45FA3B1D8F808A07D12012B256539EA75C3F749862C0ABE023E10D87748311312D220A62587945D71BF85A8BBD9A78FDE0855C363C28404F5C9496D457A6FF2BACD04CCE507F2CB875B1C1A3100874BAB6642E73AEBD017AF15BE18432BA88DC9B6A9432542F610FF90AF43EA231AB3E18C98FDF839B964003A0FEB28E25C369F064D5BB478D834643B10F45FE041BEF0D70A9F52478417126DBC0D775A5C00850F243BE21B8AFC2BEB357C40CBD1CC37873574F2E135B3322F674F64F41F99B761C021AC7936265C0D8097FAB63679BD20F196F403725530C0B51841E6F9AC73303287458EED391E298875467683E747A9266EA092D9F9E915B089A2445FD472C70E7EAD8E22E38FA229CE0D5B6AF15A676CA1BB7C7381BEE00568726CDB47F785C0A167DE5EB44AE1EB142488E9EE7E22F68D9C575A4378765CFC327DC56AC65E46E739E92440E508F915BFEBF80BEC37D637D7A1963E6D0A9A8C1F33BD33F7AB002C84C616546ADE3F2285C74E02F26C3FEFA1CD15D67ACBAD504D8F1F143B7EDD0DFEFA782C278804ED78110A1A5AE81B3E57E8B2D4A8FF26FCF23DEC7FBBA7439FD198EB1DAA97D864A1BEC591C8AF9E39FEDACB7F0EBE96DA1812C3FFFCA6AC4DB2C2B9E9121A092357C1833FD93F0FB63DD91667E4F6528B81FD27A3BB202624FEAED0C855CC031532B065613A28D73FB68F2012DB9AEC839B0FB5253F4BD3BD22CD58B07EC6356DFBE1F2D179ED9B471256EF9EED58E2475F4F9E9B3A0F072581DF5ED56FF996A61E0D7BBDE23BC329AAEF243661558C7192C8AA157C537B77AFD50D3D174626469D50E479CA850FF9550AEEA576A6FA8F1C661B8640240702874642E23528349984AAED6BE4A8E7BE4EEA397355F2BDE2C732654BDFBAF17ACCC912B2335EE39E8E44983499B1C171B1FB4131AEC3CB99F8864118B6B2DE2CDF872DA61AA9A9902BE847118CA679185B2C0EBDD7D0F1EA7F3D5BECFF1F76D56624DB02CA1C9DC0A9291290AE3AC7546340383D983441BA89E7B2B86A52B94E78F55C53FADC58835996E2199B8BD221E5C63FA85DFFCAB278D5EF229FF7679B32AE1C806CBD1AA2F8862D52F6BA90791A52BFC1EDFBEC9575C901158F410986F9D8D42C04EC8495982DA44A95407B89FB6E63A98E617416DA216CF142A2C09CC0B2A372448BE77E0C3E335212C6B6E2BA53C84FEDDA49AD5B28B7EC6A90C3CB7FB7014C3335DDB3BE4173D80ECF3F920DC782167E4053D20ED6A8124FA5CF800632215258C4BA4C6A368031AC5883F33B07922A10DA0D91096A10ED7247EA4E73202082C27A999FF1A2F07BE16D3C1FB42A6A29E442A036C4E3DCF264ABEF5AA2719EE878482DA521766CC100D284E65C758961A29CB0120898DAE02FCB166E63F14E664398954D8C0CC6A454B8DFAFD3FCBD8B0A535BF0D7D2711D85A9A1F81AC189D07258D31A0093B50E9D97E479B65099D1C3312FEDD1C0CF16A295E1310B643C393285F07DCE70BC3A413DC1A6E913A366EABD5C56FABC5672C6918ACCDDF63C5F3EDD9D59C7848F1F982AAA383395B83D52BF3737B37B06DFEFC7F25D905464EB65F53CA151061611F51FD2018C363AC8FF2B1132D192547B7EFE6FEDA6743F6A3C367E6E5EA75873E208DA07E685CE4FA598D1CFBE9111D4639B58B97A082ACF27B8975A85E051C0FADFD3F366B806C7A7E9F5C1436722C390F44EB0685343B60C30CFFD5D76299B6A1536D164B2D8B24BC10CBDCE370FE7A5E4C0BF8BCBD621A138A63F6A5298A4A7B408435ED8B851B3DA7C4E74F4FEB2702A4FE61AC15F626885AA1D048C8CC80F71B2BCE97011F5DAEB80DB2E4EA75B55BACBE71AA8265A60E1C360CE834D34A5AA8D2C40447D3C116A8E412BB0542BE678A051B122729CAE02F166BC3350592CAC8B826A9DD3F60C7D199D34C45D62588F942EEC69D1312CF7BA243A89B92AF7C3057922ACBB8A978CBB9253AF9468273BE0755E582C3215BE2F26287B82C81F7D3CD92C74AE38F4F287089BF6EF5C2DE29FCD41C898349C31EDC0E5B08D2E95579942FBB24AB709324DF69CB864037F04D6A59A182FA8B0388B672BA77B32F913B0F00A5E60F49829D57171587D1799196850E37642465793A16CA6D2D0DEA3BF5F09DFFD1CD755CA2BDC6E774C51953249FC761EE2482D90FD2735B6BEB3F633F8BDAA0259E315EE6FD5CE6FD754BAE7136596D7129C6CF91C29E022C5C5AFFA4C45DBF738B897E0D398BB5F4149BAED5A0B8C6EAE3289C4B4E2CAF1C3E9772B350FB9923204E2AFC445099C6111EBE71BA41C4CF0D4F9F5D80E0C1B686C25DD352C613D20C68166487D33A82851D2B10E235DF9B6BC47A63CEA68C37B2B2D07FD31FE33D2FA1A799DD2F9387B36D030D187468574231F235044273B402F3931B5BEEF0892A44844A8D21CD5EFA7EA5425A8F2A45CD2C6DC4A90E81B3EB34BBAA8D8E0659AF5E9C43B93583AFF59C4386F55FE8BE9D20AA6148A0E8C7873E8010D1C2FA3E049BA2434DC865778EB56492D508F16C458C6D87CC0BF551A2EA0B1FAD1165592E198FE7CC2E4A0BA7776D3DF18AB1925D2E22361C295793836E7298D30DEEFBF3561C869B4F9B68C38AB0249E78C01482DF2C9C0C59B04BA02A3768960D95589B0CB6B29E33728ACB2F8FCC74F8BEBAD609A568668A07A908BBBA0ED966975357251C5D33971D284892271402B8065A3810CE2E61EC7EB869E949BB5BBA1CF34392857A53F7CBA5370655E4437093517716C8F659DBE5DCA06F54FF3C552E9D776B84960A7D710106280946C81E28BEE986108A58935EC82890F8C4F9D2CE414D1D036C2F7CD888A12189B8A30E6C98344ED10B967CBB7AD7B412E205122290E1AD5535B75D0CBA91A707130D367C3B72FDD71B62AFEFA353BAC93B376A2FA83497EE204ADF960B6A34BB85200F34A1F0494C35BB5728CFCD9F154E6876EE4D2D272242D76C85BF3392738B7FBC43680832B225B75CD057DAC58DCF9FC99EDDBF3B4263773DD3A26F04928BAF02955A6FB4170654AE886F8B9A7FAA0FF5C4C51E228D1417B31D203806D340CC5BF259709CC5638FBC004C4F5A16955D0CA943455FE6A15B05F73518A6C254FBD8CAA12FDCB7B938092405C4E91A0EE835C7FB5BCE1997FD22362755FE6DB3C1C5366A69FFCA240805125EF6E3C4912D4D33855A841A314333A0FA01BFBE4B671AE8887B485C1BBA218076005CCA9D1C37E71449D4CDAA4EB1B3C51A8445887B12BAC081E0C914617C59272E68E2F6F8BB7E47483A5D21DA6A69445DBD971349AEDEE252C2599B7E2F4FA6F6A814B7F51083B2988E375AF50D83DB7B4844B1234FCF4320D8067B6E17D67F95532E5E46E48CA16FBA6318F1FEBB593EC7B255AEE4FA25065A9C82B1F26DFCA72859B066C1A32D9DF2951D75D69DBC5AB86DDB137EA7EE04951FE912299404D8D8EF8FBB1612ACA3C5D356D2FEBA2644AFAB45F645D597B814C6786E46F37048681B30FCE26B06FE6421E8156002CA0E8E2F069ADC6CF308EB71271C1010C4AEE8B6D5C9C9B473B646226338DD822A3BE3897F0AA159FF3DE4F9B055224C21C759C6988A3EAE980D3AA8F3DCA9D7029CC7496932D81E748141137761C1AE5E3AFF0D10E01FF1844CBC572916DA40505B5B7204808621D56AA6B77CC3FB556563BECE1CFA335D0FCBC9EF53AE881A39BDD672B626121C081C07443E2EBD4E3C1005B13014FD26CE1299169C8F3DDDAEE4E63A1137656A15EFE31A210270A8E2667F918B37FF1FF7E7AA1C91270BEB372946AED7A0B4BCA191E93034F50E792E2A3EA87B7406F493BDDAC6F406FCFF1F1710307B9ED3200EFB05912C92DDD1AD9E228D262B034759C14DAAC0C3B7A62315C311C7BC1751B865D47EBB5FB6E0679B89ABAD1F14E329D7EC93F08B85E379C1F1E273456C3749D0AC3B0F2C1E46543D3546A6306814F8365733F4612265A0E3ABDAA60B1D9DE130DC16340D19800BE1F512F126C6249C97EE90E24E6826E6E04928AC2A274950266C6D5504ACE7C739825D870846EA0C5704CD556DC44E9E321AE0F4E1BA8D3E7C1B3710D27CA16543FEA79C075801C13E0A66B765C66B5E7D40D2A5122AC6E11F64E00A082816BEBC321CD922CCDE04C0F31FA79BACA25D253F39E93B5D985FD8C969E55DC2B55EB102640824919DB7290D03AA8A9EAA884A3DCCBD86C8C0213B406AC0830812C49DAA454635EC9AF2FCC0B1FB7ED3A04289ECED6F865208F7489AF5BE849A77DB09827D2BE1347538AD530F8FBF09BB30FFEE5AFBE31C461AD5267AAB2447460C5071053A039F31E4E8D18CCD6DDE1EC3451906CAA6C74C0EBD81CA12185D0939217C6EDECC004A05B901C3302B039C9F3993082E816789BE50D13B4EA4EAE5AB02B8D1097E58574E48883230869DE0F8CF6FFDFE090BF2F286EC36234F928DEB3149CD0CFC6C0F36921239745A0FAA86F48AE032D617F5CFC4CD758D8EE96082FC8C3F3123D583B0A1D316FFDBB7C0FC7AC50DB0148A78707BF1E17F1CB10AA812152B1A0B254B023AF5BD4E8870C0A64C923E9992739728A74B566FD7BDA65F229E6F9C5D0D8EB85E9F23ACB21FBCD160B83DC2102D4782B188279ADDAAA15DA1706E4441215F8A554EC6D9F548B0CEE5341A791B48CF90E2B1BDBC97E307257918F463EEA1057B32580ADFBE2A346F44BE7DE5D01B7596D35CE5479D91E2602E850429B8F58D6319EA9591DEA2EDC8F95B4D794436AA7E41AD587B041F66C7EAE982ABF32DCA9238C21B7B99B7432BD7EA660358CC4AB130F7568287C52535662E4822CEC4B3605EA6468EE7DB75972FDF402954CCF6320C5070A68D28387F5003570F4F730B1814BBD04FFF5601A19EE4AABF447539BD3E9795D9DDC71B2EF546E4E97D137CDA9F859F8E8A34CAA2294E6EA9572DC535ECD422CB4DAA9EB4495A83CAF92BEF0C8D02ED0AAA26926063E3847C7C65897811DE146D2009DC8D904AB41D952E85ADCAEA0EE0A6D713014142D429382FFEFE7818F87FD9B9F79BE294E2BD28D4A3370DBCAB7A6301910A5DEE2617A5BE227208DCF23865936A756471E137E170F0685979E85AA206DA6A515E12442F5B0DC4CCC32E183DFDB1F5174D803D6CE2696F325672B382EE3636F43035178981C2E5AF4D1A4ADF22BFCC2D6B49D83CCF9A87769BC6F241BD12E60E0D3BFCCADE616026BD0C0669DF0AF848B47095D545442F2CFFF6EAE2E9A3BC54832AEA1B07819D001F1E80FEC7876C86A8DBE579666A38F756044B7C6280443E0BCEF04B90A1239AEAFB407E3B86314B724D632DE2C82274757ABD2A1B88FC609CBC85F8D2DED30C08C84289DFAE72132F67045EE0E1FB91C6C32A64AD2C622C841F2DAE9A60B277AC430EDE59E937A0DF6A577EB4817FC96B1F5985557F5017A69B72164F517E86E5B9DF60AB66B0204880E3FD4409C8F7367C0018E798308CA4BA450A098021C2689B877C78B6466B38401E860BF4D1EBA57C977014E7226D355817F1D2E9606706EFF215F56D73CEED14FF090665E4BBAB17F36AE728B25BB17CEAEC84347F384924EBF0AF7D0399E67F98C642D3EA20459B255221AA8CF2DFA293F8065A4D86DB42DCF0852957D1691414741A91FD4475F147D2BA5B7A2615711A074F6DADFBF3B3583F185F118C6EE0AD9BD1A164F9A9E266B45641393382F54F97B6C5B117B0E5157F8BA627DBA69D13F48EFC1B6509D0CC01845EE10932E3E6403AB72A81D43C98ED066DCA75E3EB12374A6C1768358A4FE046865348D31CED551C0BC6B9D55D60A56551EF58B11387D8A6B4251F39034B0170FFDE34E2FD3EF6C67B896BC3B9EC6F8C506C808CC0E025BA35461112B3D0A6768972C1CDECF6D1D27B189139420DECC538D309A9C28BE3C1AC21D8CF1072DF0CC2ADD0A6B2A85F5A154217A3A1D2DC0D15218593DD68235A1874754C50E71593BC330B1E1B02E7BE66E612E5E5FC35226D28B725059B3FCDCCECA89A66C6402828FD9FD7F44A36CC478B2F1C36F047C10EDC12910F3D905C0AFF6852CF2E49960348D62DBE44FE80BAC76396F84ACD353E78C8AF5C4471FE2A5E1BF2CBF193AA2127670425863AD78C6FD5813CBABA26F2334363D96ABD6A4DFBB3F81B8AF09048A051B271C06982DBA21A19AEBEF9DD56377DBB81DB4A72D9D8C48E081579A689843F3698115E6FEFC43F24DD96421289BB0E9531791487D7E9C3CF2F58461AC6F8B0F1D0839965CCAE359663215C9CA7F4E64F30409E3A7510B932762A1E245AA2463A33EA066F0B3FD5D0B48A97911C39F94E7DA1BD0D32E4DBD7F2A4A4A17EE920FBB378D6A14263F1EE4DD11E51E7ACD71ACC9C0E7B9EF9B30A8B49D3FC2D23A1D3DC7F3DF354C6EA8B1D5B06E5EE6620C6A0D2C420BCFD7AF06C2A672DEF0E4A53B60DB8077378EC91BCCB7818EA1F35F276C30A777658E09486B16B4057A7569674F00524599689AB493B789D9101A2D86BBFD446A5BF44BB31119EFC2436CD34680A1A8CF8A0B24A09B036BB1412A625AE907725DBBFA18F7DFDC50CE1925C80F78CAF37265068E3E4B005464EC1B8F61E808F80B7C4C1184241DC608496FB0EF6847DCC09C4A53D102EE99DD7E3D05A5D49A2DCA152057459B8FCCC8E7812CE4DDC291E1B1640C05D31D2BD391AD13E0E6BD9966448EB20A399E34985036FE2EB23B7A821DEC536DF07258D72A90E3C0281D0FD5BFEF104854BFCE14D1FC883BE45664756D3BFDE683594564D706BA07A30694E862E28516A0E7BE1BC2E6C745D73FEDD49886D6BCF562B844F5B13002CB90FB99426F6BD23AFD0C43E8F3594B9E4B1607197598AEAFD747CEB4B003AD2B970F2C225580FD46F75A212576844D316CF5096E5BA9CABD1DEEC36CA2D9951E21BA6D308AB883548462C34055BC9E9AB4718E4521DEE6043FB6DAE8D571B9CAAA86E2052EF1A2FB4A3B3D41BE0A63F8D7A8EE5C943FA513CF9C323DA3DD8FB1B4715AC9B5664392CE1284D6F2B59071E48EB665336E4BF540A77B6294710DCF122FF75E7C58778E1E11CAD034F5BB4AFEC6BEB19CA1E1BBDFC7123CE451B488F2B9CCADF09F3893305307251A1BCC62D45FB4490A0078DEDDF7EDB4FBB7D11536D4EBF1588FAAB31FB8B21570CFA3BD8C1DE4C576FB6DEEBB253D9B42585BE26887E4CDC95870B9153B4467EF34040B93301D479A49AD2BA2B559D938BFEE6420A15984DB46ED99557F0F141700A4050E765B30BC7C93B20CB004B6E1D628144F6B7883490271EE60D9B42DFBB9EBB77C4BAF60D43DCFA92492875D255E6319ACFACE02C81040BDD73F6E8C15B844940D3A0554EFD51F1D6E30A389B0592DCF55D9E6404DF8E171908F45F34B3DD9C81C47A6531DC8E3934B1BFBA991E13D2D32A9B9FF8060EBB38D231DC3785A2959EA357AFD7650790FC976B139AC7EA4BE52CE5D7487C40D97452CA396C8AD09FC45A828369F9FEB801E41B38DF820E030B9E66082567F02026C0A8D61D097418CF4A95A9CAF6E94B340A3E389D669A1C28E842E1A2A0E95A034C79534432C3401DB89F799F37EB4E8009A90FC1F36DA014ED08E04992D16FC434E0B6446955DD19FF2C0A07AE0A31C98B737310AE8FE403BEBD9A10DC3F49C3A628A968B4DAF37DB9BD50D7705FD18718BD89DB9415ECDE496B1E5DD296D750047B6680924A86144F08269A6E2D6EDD1B6DA7B4904E3E0DA83CB33BEE4385DF58BE05DE3CECF5C0711929D322941AFCA70DA158762F0F0A5AA26C870AF82E79DB492F882A15EABCC51DE3A05898AF15C3BE341DBC6128874730F426A9BADD55B9826BD2A9DEBADB2A5EB99EB7573A4EC91642E74EE8FB471BD867E5F1151A7FBB9AF792E6782B05A58305B8A84360AF16E53CC43A99F0B114524AD4E4605F301662E21706503305DA7C813E99109966AD4B46504630E19EB2FDE31A7D058227C29FC842AA0EFA5C3582F51C37A2AEF76CC8DA678821D0DEA48C2500AD6887CF99B8E14807062F88B2CE71160F862BD7FE908305D51BE0A3E7D048D996AD2BA79904A2637AAD88F0CDB08268C5B8AEED66BCAED81020D33C1B5CF590F6FC39353637CFBD749194AD689326A958FC00DD603FD6D0E362DE68C117F40E5AF183F359DB64C5950E2D3C8C913AEE899553106A4F8179F092109AFC64CCA1CD203FA381AF3FAB0C6A2CE1B9C763F4FCDACD8EB8C22F999404A399867030C2F0E603EF8637C856240BD39AE8157E942C970B2C27BC88D110C5DA4A0563B7DF0415F7385B8F8B0807F44A40943F5E6F4EA8FC3D5035D7E71E5E7E113FCF4A6E4C67D94685CD3C28D45B61FEA4A6308ED71A1950D10346DE5C7C0597B7606468F3EEE7C4CE358968F8CE409713336424F63672A4383E5D332CA87C0F3535F615F2753209CB27C449BE528E2F377386D88C3ACDAE7557DE26F8B2EC937E48BA87FD780A9A0CF05EC4E4E8FB166455E6183BFA57F0BDF48DFC0F3FFA29EBA931B968F3851E8BC2D3E32B8AA20354EE65F2DCD83CAF02237A8396955DDFD48A4E86EB4F04CA48C3F078AA5A14387724926D1FCEB43A301D096DBDCDE17C3A7E3E3FC21A27E65B84C191126CCD0B9138507712985E13CA10A113365F4E095403E57866A570C79BA4057DE27E4BD1303FCD0CD6357F20F6A4E533E2C38B6001A30F5D3DFE4B5E4526AD91B854B7AF4383D7C1C050AC63602376B103B5EE4936BDD2992D8F5408018E5D8399E0436C55E8E8D10DC21ED43C3DEC92064CECA2A94772FBC10D972C54E484DF24E9A14DB57DFEF0589890A9B993A6C5BBA9ED866D826C3A2DF8E954D841699D6BD867E302A83BF4D35A2416819FF4AB61706EBE82F0B88CCCA4F5F171D14A7DAF1248AD3F07362A676F76250F38DE22EA5B2522BE19AFB486A7EB39D2A364497F344F60C2DE0686932CD732A43E34B7DDC794D51ACAB1FE720B8C468ECA563FA21B6343F0BCEA7E3040ED701722BF12ED790329E20664E3783F1CAD5D37C6809DEF5464502230E1F177DB7FAD293D8FB8E97D554BF32EF67FB465219DDCF50CC09A9A55B178FB6BCE4E1D10FDE497DE60B9895243871B374406DC4B8DFF2F0E87D86445079E49423CC1DC662B72FD5CFFF320CDEA7DE524E0A1F3FBBA372CAAB54882FA4197D1818773D028ABFCD837019682BAAAE5560AD3A5DDD91FD0B50CEA886304A9FFF282AECAB24188B8CABD7B12CB70441732194C2CF934197F4B39B458E176BA544ACC06C6D1DCFEA237CCD9F6596B096A65CBFE1E58F4CCF9497FA7B1E4BF85A4B4D47ED5DAA9E23137A421C52D63FFF3EB9918661A6F28", - "rnd": "42F161D9B99AD1545DCF338304DA9E05030313D59E7EE1E41B6D2429A4D3BCAF", - "signature": "7D3F29D5E2354EC9D7DC8CC01DE6165F9B97EE1D180B55253CACE1BAC314B175850A6A1B0F4AB10A6DF798E4377422D6BB5B10E28A28E3E301F9FB04A08F1CF0FA7C0C0196EB81B53398FBEF6BB1ABDB96F1CEF6AFED32600890B00F065F82C08D51AFC6D7D501A5FF81903022E3808327EE3A3FAF0A51BB6BF5BA833477317FFC72D18BE52EF8C92EDF4D114650C2911CF691FE75D9DFF178D8BC90067AD74D427766C87F3E655A6A1E3E520D1A936C53032E8288AD2F17D1E9620AF478F1243FC398B418EDBFB75694254FE934CD16389C8E08E913F7C27C08DC6C3DAE0462BCCBAE9663C2241C36DC521E707686EDE3A49C3F76A1F30E53980A2CCF83548D778DFAA8609F520D82245403A5268C8DD34ED1E60E8EE9E5F264AE40F1834BADB50FC61EDA3CE55F2B8A485CB52FC340F0E900CD2F9A05FC1D1334D5C68D09955C52AD0D42E41F301BC66F267E9CD17EF15E8F317D38EA551DBD91B083C10E30ED5FEDF363792493421281780B09C0E1BF66ACA4B089CDD312997C4D20C2331B8E5D96C299578341897744201DD36559AA94691D900B03EEB8EA9228AF32A2E2039AC43F14558DBC5D586B80366C5439D29C48AA81FFE7BBA14D89812BDC112CD37BA1CD0AD289684AB7F893B8815580C55FEA63384BDFDF8D2D8CF65A08647669F26ADDC1B40A200136CD544BBBD247DA65E2CFEF468E2047BEF6709B091F6372873C29AC7D35839207EB3815ED8AF763C93E20B68DE3D2F5938FF3343942CC66BDFBEDC036ABB965AEA65A828AF7A24ECDBA05CEB7D7C7F6E539A48510D7E8E2204EA819D88A1CF6A419FE1652F7A05E4A017403934991AFB3022466C578D27AAF85739D8759FFB846D097758170A1E09DF6CF8A3C8DDFA1D47C3C530D914086F3D04B9D1D379AB671BB97B2D85E97E35A0C7C25473672A963D11B8377D42D16FF2DEED857BEA16D4DE80F815BC9AE2AD276309CB32590863DA2FFB4794E0D736E45793B3EB6F5C0128E76948DBD51AEE0EE00093CA100E51A18702ACD7212461436E505F5A269EFF59AB9568ABD83CBD40550DB1DAD3C7F6BD05A9A922BF76CBB2E62B65A9F39D66AD00A1849A7354A5DB1C6C5F6897B8D35A56D1C4761E248FAC7496F183385FE332976CF670A2FF9D9051615B95376BE741AD6648EDC13A1A877505E92300471BCEF86242CCDEEB677D35CF6A65FC0A9D8C2A580A6EBAAB89E16CCAE06DC40A53959D60492844431037C6B314947444A0211E39DF43130F8255965409A537F8FAE179C0E9406B6672355AA3065C1756CBCEBB52634DC5DF4C6E73A4F880A1037A0A9387C1036354015736D7668E6EFD81321214E6F4B30A82D0664EC0148BA1DBCC772B00345C6CC917C6CEF5092B5C90B8DA75C3D0FC0CE6288880F3D9077467F0A93CCF96AF31AD93491BD775ABD7740F096D2F938DA0BFE8A4C731176413401406F48802497D23F39ED71E2A618A5796748AAC28B8962E9ECA0247A8D922382C3EC809EA4E47683280E3DBBE35984206CD89CBBA9F0DF7786B053EAD6DAE5B33CA60528054836245848F9D57D9E0892FC511552BF9835357E1B0CFF94A351B515A460C4E00B33B205330F7E51B62BE0264C0B54AE91FB4DE78A3437D8F9F709648EE510D2D173970130B48D271A45F974451C2226BB4EABBB8FAD9C52C194CFEC68CC83279AAD1DD651F5A9DB5DE16441D810FD47ADDFBCF107D977F361C415B6B7993AA7C93358D1BA3C3246EA982195D7F0BDB423891FFD24FC67DF21A210803A7E1A9920BB7BDCA0453F8D657C621508A8DD76B4710E7F4E9D52D1244FB2BA336A8CDF1A84A8DDC92A012B64035000DA2B614AB559117AFFC799EFF47C374C486D1F848C78F636E5DE663A578023E41A62DD94BF19D18C877F8928FE31BBDA84593E97D05172F49D9DE9F6596D2D477F43BBD58BE209DA6E992C26416153FD50D1CB9976DBB381FBD8CD30BCA0ACE9B911A59CA3BEEDF7C11CD2C83E74EAB21161BDD5DB654036D9831AE1C569AF5736610F889CB55865BA821C9EA5E53545F82AD8D7B2731010C1B5A10A6CCB626C87ADE983CA21872C87CA7FAD8E8DECF72E53911592AE9E9E006F3080EC8EA6316192DF0F78F73D95EB671D7C00F74B2D0EDB0E8754D5B2070321430FD18628A690590371D6A025BD1B54F6BD151350265573693E166BC7FF88B2F7A8E8F4202FE4D17A51C21EDB3EB11F7C9536DAF86268428DE3F093E0FBFE93D031B3B6852CE63F67DADD15947B7A28EAB9DDB01C592517126217E070FD724A64F44CADCD05B37C191D4E7F225A87171DF8D1AF8B26948B0A2E0B02FED18F1617C1CFC0DDC62EB5040BCE74951FAF6D6FDAB7BAC67BAEB7112FF4A76C6F8DE6619414B890D40250393E547AC6A5904A07B47EFAF0213A8DCE341527B7F1B050D066C0179B274EAFB2969C20737F57AC06D07D92DA4FB1B23BAF60AD6F2C9E91B0E1AE238DD98F163FFBC812DC67947C3FDF29213A820F26697AE5433F14EA5143C6B10DCCAD3EC7EB45B9DA0754BA94B9ADBDD319B93E92EC1D0E1ED9117E82F62BD4EB72A24ABBA7058CDB11D7D9CC14439823FC81DAE5EE5197DE8D84700A96E09336837B5A3B8D0B8270E4E58D64E4BB36B2C91D2D903F8B312BAB49562A0CB25E26412647F309D54B31B0718C679096DD3245012B825C27BD072C2DC265E1A67B03C367FE6E7564ED6416B14DC371F8C2DF47FEBD81FE93EE5DFB67AC2721224F6AD72C5B34C19BFB9B5F5BC61E5AD5420D8C608B62BB52F48E76DD465E946EB9716CBE9E9D64BE433F63ED7DAECE873B47BE1DBFD7008C90BEA1D1647A03D58DA652D5FE0E5C3C1BEE770F8EC7AB46138051F65715175D15FFCEFE4796B309336C108F4FD0A8838505F4AC6E422138CA8141C5970031170C49720BF5D3356185A466AF1D915A9EBDC8EFD77FBB1104BB103D1F1871FDAA46942BBB18D700F986E34C7764C36AC192E2229EECAB49967ADBDB90CD45CFDE7BB5BA97FAA86FC6A163EB3B3552DBC092F28A107CD729ACC7D176314DB68D24EFE393A4363F118F1CD6FFC53B6AE1E262C15CD4065C3AB94EACA62261CDD8E83B89C2E7F7B23D809E56AA45AB9E8C89D7D1969BF923F63A801073DD2E0C0A1FB95749D7C7A15270C4E90A2868005E4A1149A0D2E67AABDBC9CA822595AA6FE9E97601BC421D9917ABA0D753075F116E17FADDF3A60DAA9BBEB633B19E593D86F73A8DC152EC98440BBCEEBCCE3DCA5FFF3A9D789011A37E50B91837D6FC6725F027C603ACA3D0D0DB19BDDB15FEC86AC4020B0D434569ACAEC3C4C8D6DEDFFC040F1A1B2433435C5F769297A5B7C1E8EF11213036383F424548497C878E9EA5BFE2EBFC0C161A3040424C4D565A71A3A6A8B7C5F5F700000000000000000000000F203345" - }, - { - "tcId": 19, - "deferred": false, - "sk": "07E588E4638FEFE3F4972E3CB7A27F03306DD4DEA7629C8ECC9D527F5C766E5F8016D12D714E8A95330ABBDAB2883FDCC6DC786C5E0775960F7AB95C1933558FEB8A8CD030ABB7E359BEF703C14671B80F005BECB0E3D84888CE0350A7FC17DA3BBFD862D2833A1FB07A077AB02875F2E2048899CEE2B461BDBEA7EA687E9B94E03808621412A0480919C48D1A89712310915C3622A20244A3C46D414089D4A81050846512940C50028E5CA0510AB22DC3B4642204860A89494B480D62A08CD4864053846D52067091060C03022ACA0626CB98109938290846005902008AB44CC91032C20860C434451B240E120961D090855B90480B232AC8246A4CC240649801C44400103669CB161241428854A884D848664094051A82650AB66511B5499AA66181140CA038429832021A351103246ED0464511496E82340EE248408A22091949685C864488A02903363161121242B04189B2210317061A054C99362021A30122A220D43870939825494471E49469D0964452085158A44920A30922278A5B144D0485088882280B22480B228651B884031184D2B661A2021180A06400386ADB842C1AB16D92066EC21052628821584021648885018904C2A809E384401036840A00911C104CDBC680148548420801DC068E53186E028989C2443282B4500B154C01824C19336E8B04900C2621531286E2002D10C245C3C420114730CA0220594630098901989481A2144C1A398EDA8449C24409089104D2300AC1C885C2B051D4B0818430084B4891224451C116315C24921914280CB60D1B204A14A87100B191E3C08009178C02C98161442051960D43340521A15150181002B0409342440A206E24A12864980981468D4A360222410D1AB770593270131082E1988159324E884069D3386D4B94285A268A23C2441204885C3008CBB44408372E64B404D2A8241AB38C80C0049CB27009382E03234E89B6908894519B461153C28051886C8C988053480EC30249C9126112276E02056DC19050A0262413019014104D209860A1964DCA0649DAA4880285894324429C120588464403440D0BB70DA2A6605B208410B970A4064223160E848405CA40128C8205D106844B002A4002291A2405DA046290B80891A8110921451B110412C101091985234608E42864A338005AB4458942211A852C12157159262A802640934226234784C3406158B4095C0092DA206523000DDCA240C0922118A54414824D12C84504284A19A168C24492198140EE6026A4DD266730D5E6DAE34216874D8125074CED14BBA9ADFB6B48A203B0C24CBABB4962249543446443414EF7D6513E95344872E6EEA4396C4D64C723E58701024DCE31F63B68F8F1A5F2FBBEC1814EB35FC1B73792BD6352974D18AEEDBA8C630D4308A6FF6445ABE1A0761CD94CDF79D12D86D4B2E09115CBD564AD610C4236A042755161EFF35628C38BA4A5F32F981D3B20896E054FCF9FB0E84492756DB96CEADF00B08D0D22629725FD41B13E88F306FFCA4E494A4ED5AEF63AC0E57BAA87F141350A4B37135E6AB987F6D82633AC889D949ABCDCEA18B5A66B5B4569D744F18DE5E47557E23E5740875F18128A0E6A59FEC550EC006A823AF3395CF325917139D2640A1F022CEAE100F4DE50D374A33953F39353DD36C8E1A6DD9F3A61569DD096726C06D3FE04C60EE10AAFDE52E540843DBBEF5CADAD54A303CAD53F89E6B90EBBD1F1EEABF169C38086915CEEC09F49767F739DD8447F69B150AE7DA2D9D5CA17CB8F8E5D06DEF50FDF360EB21E7684B238FA7557307BDA6BD654CEDBC0196169EF9717772CC69E1EEF6AD0D3B17A1844C0E2C19F948AED7B6C54A8F5AA18F1F768FC13F0CCD9B43E4269F374421CD209AA19012D5A890AB9F60B81AA90A85B8366011DAF7FFB16A27B6A71633AF71A98972304C1D05A65F855A257F527F013D73C3FA430F240C5C43706912BA04320C83B9AFC88E82472BB84485CE1CDB3EDD9B4CADCF4340BA66B431F26D9DFEFF3D6DF4E0436010E27A8895B8294021F45A0439480E10DEAC618443229F897F41CE033FCAD55804B286ACE17CCEE330863FD38F2F765E53D2D63F5FE43CDEE04C417164064DEFDC7B0EA9B05180E344C40027CEC5DDD0B548E0180F496FC52C0689D9B6499B10577EABB091438461AE2CCCC6CDFD42002FB25DA23A82E48622013844ECC9123178912791A8E752BF89089EA659BBBD5D56CBA7B3A90E6190FD0556832B7E60CAB577A9F4CA2D30D3F9CE425988540F11DD17E306268A1A98BDDA8A63ED9CFDA3D3B6360E7E45AC261E1499A3E952895AF2B2D60655AF609B63614727917F5EFA954C728F3943CCDCB88EC4A6F540682C0AEA9338E8C767D26A7F56B6943BDDB177CDCAED01956507C9FA31A91449A5581E7FA19D195839BBFB16AE094A3AA0EEC4BE45E81A3252C9BD00DBE38D0CA548569B213C45648AFEBF62C9054940EBBF7DDD1893392A187C8A153B8A838AD9A3F53CB276CA2E5FA07009D4F71B5AAF4C898397E8349788E69ABB6253FAF6E2F09067CA6D559652DD55F84087ACC6AE475C120D6B094E65EAE63773C1DCC6873B3529B9FAD9BA59D3A89F57E661147DEE109E25B418257CC7A9A66533964D98B92AB49709942D9298A6EF217F332D1E24E1F09B4921F8B9F43C4CED620B06E6BF58B94E4FB0620DB5D49A963A87E566769769B49CAF56DE726048A17684E81A82AD8F20E1960408F1347C0CA759746663535139AFAF53DB854AB54795DA2AF5646A08D61366CAEA401BECA71ED91D04B9765763AA609F5901FBC2CFB5003FE3D47FAEF8000894B0FB49B19401E62EEF3A0B0D3A55EAFF384C46EBB20F2F08FE0E54B813295F71D20F0089F2EACF912AC6F5BE281DE643C75436A8E78392C25BE7F15BBDE3A718D8ABD86E6E3A23C6D386CD22267C7796ACCCF3B2EDE77F1D71FB21FA3BDA9D8497188EF5FDC40D545C738953A62E4A1D4EF216C2A87F200A68BBAABD88868BBDDE0BB7FDB294DA43DACEC25FDAC9EDBEA763542F8FCA4DA1A4FA606915FA8CC0BF7B10E9803DFF9ED8818A93FFAF1EF9AEB10CE5D3677466FFAE32056A1DEB60CEF20283A763F09C753C1F63A9A55F58851625C5FB96D36A7A9CA74159C455BE80F810F7C3A0E9401F2E0B5529669D19F7BF2B7E1990A6FBB57E06A3BDDD9185EC8C83517C15D2D5218D9D244488C69A9EEB8595500FC1630055CF7BE445F9E7FC0D06859B76607BB52AA0753E5FD64CC2DF3FF0C6F95089C48DF5799735D9F05D9ED48B95D1D035DCAE96903628205F34EB369BA14586AD6534B6443A07ED8078B4E02764A8D341D417FEC7642037466FAA2B16D5C9811547CA167A21AFA271C52E5B2B2D9FB186E4A6B713C1F9A3F027EF0ECCB169171180D823C98D29950DECAB3186F4B5A1E00DF70C9C9969C914D3148A914C3A2AB35753EB2C7B276DB6050595AE99BE821442661104260114B53A303F5E3EEC18F5E2A246AAFD310643F8FD54EBB277265860207273841532A9EC06BA360FEA7CA191E9F91107E5555E4BE205E0B7082C34065C8A1F538F1263F138EA04567C1F55AB7E777B3881A462FE2F7C191F3568F3F7FA747674634", - "message": "2F09A83481E7F53782813589CB28FFF955E387AB4C0BB4964CC6E863AAD637F31C36DCC162164012105D6639695599BCB8E7A0F31A9A060BCA0B4BC2FA0694E8BA9FDF65E5B8E0F5D6A14552177FA19788E2693EBEF193FC9BC179430B16B355AF7DB90BED229F21265FE4AD96A1CD444E56D9AE5B446673ABCD8785DA0654BA4FDCF3E4C4F0EE6290C48325653EC9224654495FD10331A3617DFCDB8430E6A98449EC60C4139898B6AAB18DE7C8F1A7A80CB5C1AFD8043B3CB8F85D89A50C42526AED56E6722EFC15F938D63F6E5B5ADA86809172391371A0D3D2F310AE92EF80F0FB4222CB2D299D28FAC349A40F0FAB080B1C948D324EAD0F21149BCC2410BD827A4E7D0762E6A2151FA587C180C1E86EC034BE5071FB3E794A84B1D03EBDCD8284CA66F77D6B3DCA6C068971C7F794D3E5DA89F192424DE146FA729FB00F1BA8164FB81595CD4849255092BEDC8574BC2462DF5966E3D13DDFFCC5C6B5621BFFC466F63BB4B936C434EFD5647F2DDD0BC12802CB0EE00F0D8B6CCECB927D39FBB412EBBA9035E5272DED3975F15CA9AEC75743EF5ECF11B020877199E063B26E64C7C029DBA4620417609B1F902F95FC06AE2F44EB9EC2753BC75FF339FC88C90DCAA48759B05DF79B2F8D20454C777F7BAA96682DBF38094E1AD9389CFE33A481E16C08AE10A79C175C0324A8109015FFFBF16DA109AA79D25397004C74549E533530D561767A6D183772D8380B5DE61A26ACF09C86DAB2B7CE7E297EBFD389353B2F05F6AA3BACEB8EF47CBB6247517C16C020FE89DA823B27809D2365FC0CB32E3A7F5CD9FCDB46AB79770915D9386BA28E7ACC87B76FBB8CDFF28681576405FE92959AB2F30B908CA8B6F8950F1A1A071E7ACA010B46C3D43250E58C67EE61710C1930F43F891C597CD7CD7B43EDDCC47FED70B9D61217C289D93C10640C6476313C82ECDF99F48E34A01423084DAE6E604A98CC6493AE8E050F8D341851FA90FBD6C8F15B3D0F17BAD44C84A11DD1170D54615E9C5F4CFA2EDD29EEB1AF638025B540D964BBC2C2A9352CB08DDC6C2FFD3EE37BD11F453CAF2CAD1EFFB84DE685DA610D4DCE56F1D0337EE19BFC27DBFB29A6FE96E95B87C28DA8BAAC93F52716C8ADB4B86858A33D79642DA708C958E75AB1F5DF64AE328F1A76A572936A356025E965550E36AD1E8662441BEAA139331B4D17C8564D002D02C3EE157729A0BE80184841FD743571794B2D64DC3452098C1C9C3329B5796E2B63C943A82669B3C721503DAAC550B881417ECFBC2B90CB06973CE0DD67E0D155F3064E2CB6B3F71AE9906D0059A0C8FD799B0987CF6231B1F5FA5B1E839D588F51964B8D4E311D4A059E1F5D42C100F25A647AC06F22EC3F939C5ED4FDFCB809EDAFC159922262F45B79A9BBA2C54D54CE581B3CA6463F12F0DEAFB02679C3AF59C1229015CF4B75A12106AE35DD1D434D854DC1AC12CA1040D629DE9703166228DE98BF089BD91C1AC74F70567FE919BC47B43DDBEC8DF2802B2BEEEB663CF0925C2E1EF6D98B02C228AD39054A3C6BC51444D4F4A8BF56FD8F99949D9C45C80054BB92EBAF2E001BA9E69A428B821ABFC98A302E3D454DEF19CE25DAA7ABA8C3F0C58764FB355045721139F6AE70CBB4743B494408B8C6DC208E20FF73732DE3DC49B256378EFB12CF38E703216E7E3ACD984ED48F850CA21CBFF3F7481F7E59145B642DAA994DC20FD8CA145BE29B1386681FF1CD413E41765DF085510BEB994D42E5BD8204A3ED8A1C16CEC682000C44440234B9CB9CF918E6314D87D8DE26A790965BEEDF58899CD9BD693B5727A7AB775D2F319229E39DD49CDA8D40C748855125EE29AB84A17434C7E3AF3ACEB5C1BE8E4E206477CC7EC0067381CCBD64BC6CA3090DE86639C67E94A95FA8A4A4471EA74AA484B4295B33D690E44A2008DD278B53DE15D4680932D2D58ED3005550EABDA2D59B8B48C0821FE151706B9854237D60FDF48E04C17DE62FCC75AC7A1428004FE3752C5A8789486D1A95E5F0619F4A3A4E147D513AA01701F612D208EF39773660CD379F5DCB747B46C9A5D87EDC419F7D9BB38B5F611D1A148926FC048F36BF6E64CDA33EC8D602A0DCB357BB2B8B1C0ED79725F8E59B2D70766734CD1557FA2061040AF94F7615C1AC71FA8F8E917CBEF3115C895720726FC6F3B5DD97AE11D643E54CA749102033217C19570AF4642B45CC7C272E3D06ADAC540970A9363EC6C80484F2BCC18A6F398AC75DCE1EC3CF635E14D674DADBC7D80969D47F59BEE8DAE776CEC4C88A59A2F0010A05DEB6152889C9681F18AD3ED248BA461A2D603B95CC3C8434EC592DC733EE2219AE1093508401E09453B5166CAABA1DF5518C91131BB9157106992A695EBBD42E1AE98D66B098A7BE73564EE2AD8BCD16C38B82071D3C023C7643E82BBF53EBA297C4F878D1E081D494AF4F1DF58BB5EFC5EABD495D6BF212615F47316C3C6DC374446D637B930180D5E073104F639BBD7555682D165FE60527730BD26157B408BF9E8191492A442E17D3A944711A856C32A88821452D61F6D5B78EBFC118547F24E42BD4D0CD65FE76AE5A7855BCBCB533CCEBB5D6D9EDEA73525FAE29BADC714CFF002DD0B8391D5D5FFA3318D5483566B77A9E8AA07F2512FB8D0AEBC35D70E1724E9EF1226DAD6A765556FE00E6015D4A72872BBEE49A9EF24F3E66A493B3B5F833FED7A680D83EA55C6E3A1D186239F4AF7F7613691570254472FAAC53C7E49074176220F60CCAE89A94D355BFE3654AEAB96B78432910961FCDB24AC0D93A2FC3FA017DAD24AD1BF8B93D79AB90F2F7BDBB858DF6A88A75940F44A427C2A1D70D7FE5B2DA220670466221CE9FA4A66371DA0D62B148AEA9ADDC9FB394F47D1988DC1E51F364D2CA1D37D5A552385134C3D998A5DC29B42CD1D916ADEC23A71C087306F0D9693D0A80E98C65747F82C3898CD73C11868D8ECCF8BB316E52B3AA9C4A25D4FBDAC09A15AA2C69B880248C0A85FF9FCD44662D4802CA9A0353B4AC5244E6990C8D48882BA58077B4D5909792BF8522FF05EF82E332614463EC3F9622E03F4918B74C8FA7FEA4BDC64960AA462E8643E9D68C918EFE50581DF087D06247C1147FD7C619026FF98B977D81338A7E35EABCA1DDE3F4BE21DED04EFFA18A3C3A487CEB297C1943E4C7BA8150AFDD20A71C92110C9C8F3EFFA854DF5DE636B30CE72D5E53329BC7FCC93E6C22F36775BD2D353554972368A6D01DC443160D2234DC74B7259A4EDC51E7A82F05350F1C6D97F56A096B8F819E52F9A20EEDAEA5F943A23110D40CB3983FA0E418C2BA9F732BB1F1BB0666D60D858C324EE71BF2CBC1F2BFD482481E89B17170419D062B8447892AE07A67EB0377B458F3966409AFE2821FED3FE6FD56916C23F2694DC2DD7FC8B2F1CBD54EE1DFFFBB809FB0F5D463DA8F60E4AA4DFA7AF6B5C949CA023234F7A38C396D8972E304978CE0784D46356CBC6C80F7D52255EC5E554732E6778B9CF8ECF62B4120461057BACDA2E6D94BFCFB2F418ECF2CE49AB87B8ED0823BBF642EC7519843309BFEFB4F24BABC0D68EC25C96DA5DCBA6449843A5CDD1F41607C748AAF4EC670C668D41D49337668D41458AD12E2B734EFDE1617080999701C44839A229121C09A37AC24D9CB997A618D44F64D3C86E316971BD10F60A8728DAEE9E2AED8F6180AA6E998C5CECB0AAF2678B17C271E0527317219AA2C6783D071F2A5D648A1D93EC01D6C41AD1489B0C6FD77E478E38053BF2B4FB135D928132B46DA577CD1AD9D5C2960A772C45281244E83547BAF174B4A21A7F53F356820C4DF060095AEFE4952F2938F2FCA7566218FE79DF9EDF232476F067B1BFF90EFB98F71E72B73100CEB7D416DE15EBB509CC2F4CF2521AF36C63274A5BAEAC7936074EEEA1B1128165E0CBFA923B964BB15C065E292F064A77A8DF953896E18AA266527461AD01101A487C089C92AC3C085FE14D394EDF887BB08BB2C13CC9D1F9588D3E779EAB92993FACF8B781FAF35B90D20278EAE32FA4CA130D4FAA5FC741339A878607DCDA625A381C7E74529EBDCB6D10F41B0593E0033654790DFCD15C1B7D1A20B8CEC8B1D61D8E7ED332EB2E9C1B3C7BABD2BE4DBB4054C09EB08FD8A6EFB15F812AC907D8CCD6D9534F206806E3398DD5783BCCDC9B4B71C6918EACF6D1CDF39AE211C59901F3E7AF9AE906B21B621D6D76AA64E34C3192E06219DCA476643C45E273690097048FED2F191E2E3BE3D07E23235B0E03E61E4B125CAD91E106B8A91732A5FBD04080D1B878D95A8CB54D0FABBDBB3F1D4388886F395117D63865F8739AE378E38C2BEE5278519C7E8D74737473CA46FF2C43FABB99780C2EE34A0A1547E80128B18375F4BA6B613E4411E745800B20427B405B9C0C3A66F22098CDD98FE09064C9F37F941CB24F87EFF6F5F06A3CC7A12399F5E84CCB2C212792B6F9E341353A12517247AC43EC61289857285B9E84E782A11AC51AB2B63C4B2BE809236820472F518EFF144A524E6F109B02F7674D0F9BEA520388548BA14086920E924B81B3AB5E8FA89E10C1E4A4A329A66406C2DD2A7A44A52BCB95BEFA2D1FE63F06E188C6FF19BA347789D09F8DCF1E1385DE607CC10573C448B2B518C41027F1616273C13D3C32773FAE2FFE18FDEE70AE831A551157A17AA2C5F33180F9E29787F98D6C4FCC96A03371C47280268A3BF43602B6B7BFFAFEDEC39DD3DC75E90410A024A329D2B6B139D2150C46703E4099CFB77A0E0347BCACB74EF68DD072488E0AE2CE67240BABA000BA0F6C97A61DBA1BB44EBE771F036E9BD7358E66C1F3D18193EC8DF85C4E1E75E11D06B64873ECDD5D4FC443CA21F760B6C3721A21912DB0B5B50B92EB175B889288990674255F594FBFF7EFB48736AF8F790FB7C6A0FE7A137ADBA7CD3C8D552F78CB00C176E9C67B48CB201B413B816CD8CF786C8AF15D996A8D5DEBCA920AD00320E01893784EE17C42C80E97E4A0C8C7726F475D585068E3A449C5CB42BE10C9B7FFE1F458DF3816D5C4EB6A313DA443292E88B2D487F302E46172A055B7312E324FC588E3E1F5FB122BE55B634D4516FA2B8273DC43098D88D5E64EDA4A32BB104EA78654AE7EABA26505EE057BD8CAB04CFA9872516CD9D62A37629DA8602809FAD74C080563F4B3F4D5492CEFA7B03873E73A623CA5F78ABF8BC89322A087AE32CDBD3C114EA7876CD52848F79951E2DA853E200E5AD7A8135D56ACEB51891D2E30C6418A8ACDB20748CD145E0AD80638A3F4BBCDA5EEF90F37C6DEF0BEC029E97643CFAF9A96CF310BC5FD43E6EFDA2C575BBB8B6293720065DC1159FEBDDD4610FB3DD5046D846F802E6117FF6EDB5910DDBE8C063AD4B428D40D1EF65F6F6CDDFCB2B248FAFA05D7B1C647579AD472EB17A95E1ABB32C3AD86CFFE636C115665B8A2D3D1C670CA3BD937390E823AF8C2708B17A5C51580C09488B9B525EF1EFAD4C99283A6E3662F5F23303C035826308524528B1C2B2F4B367AC52C90195F19733C66B86B7DF6C30623C0E460C74B59A549CE84F882373B720DF1ADB66C532007A1034EB1DB7A43A94B0D5366914938288B98E33966BA768B2893E5B1A01E13773785B9FF63E54E3D07EBA308C26405F3B34DD47FCA579D5AF2B29729A75B94FE1615CAA73CEB665018BD80F405793DCFBD9D1D350C298CF23CF6EACA3566EA98DFB8720023C380D072D0A95759CA41ED8CDC8091E464A69815EE6ACDBBD920B204EACE5756CA9C4E2F01A9A2B192E097C4A6A36618EF73AE0FD8CAB001BFD21C836AFA3A6206842032A9716812A660D0AE7C8D9DE5B41CFF25206DEAEADEE7A069BC5922738F044234891A35EE98CE7DB3A58EF9604BC8EC8D6DC97658C8B95CEF6000D11414762D65EDD9BE90AA6CEEA6B6A3942BD7107A9D7D46E9BC7A201E47BAE04B8775245749BAC070B65659D45785E088E6F117CFBB9846487BBFE8265E9004FA7EB464873F8A853396CC02D3C5C2A994908EBE4CB56F0FFBFC63E1DEFE573CC93A2F96F11A8117953DCD2EBB8442BC6D8ED68D9B694F1A15A58F18572FC300C57797267220387B2E2A178BCF74A57B14BB01A1FF2CB46060A1C73985BF31BCC98CA3610F67777F20C5AA4FC9AFBBDCEF14C798DC9C8D68D8969DF99F6930D879E13B8B41849FEC53EE3E8C858CF6FE9B6692C687BB9DF517E4F59F43CB5D6F423FDCC0AE473371DB5F447A91A55DCE35E1B4FCD8830856A1D9D275066B3B9858D021E35B3CD040536B4990024FDEEA69FC0A8F63B63F741337FD7E9786ED24EF56BA608FB7CA306118A307F72B8EAF486A0BE3901AFF1330A19B256D4169067340BB90EF175475EF9AAA52D97025BE5D6AB0009D5075AAE7A987E42DB9DB0B7B8C881CE9EC0A087AA94405C5E6CCC895C8DF484CE4830B5D957CF92FDF1F33A060399648BB872CA30CE5206BC3406492B7B34CED7B6BA512C0C86108AD056FC9AFD9064B6F704915BCB3A889A5DC26068596353ED8E379668505B8F49CE966B57EC637F946FA38ECE225C0F4D22A1889CCFDE203BADE9FE7D25D35A85D2B3B7DA88AB3CE65F2F477A9F00D78CB4BC3BAAE162FD8670F3032849DFC4B61E2DCFF9E9C3095E4B69FFCC64912FB111485CE98A78B3A2ADA19E920A88505EFCAC0CCEB2E8D510A5C5229404AA270F850DB0993DC1622AFB81E2BED4AF246EFE03778CA1B5BFC2E299ABECA2AE238F6073412EF64E627438AD8371ABB7AA50B2C543283A8782C73CA7E89F359BD77FF28E767E00D633412CB114247CFB6ACA39E0887A2E161ED6F242052A908E254CD1006C1681E3313A3F713E585D750941D2782E5BE8A9805FA4F762311173B36B097199863D3C42673B7023AE75C2CE5474179D43F92FBE6A86A952C44B6DAB6320B31B2BC97D", - "rnd": "ED1744006D7253B6BE926AB3C169C15D8A65115A84D309D2D4553CCABB267DCF", - "signature": "8FCC3725A592546EF0EA4CFCB8E5FEF136F3BCA5C28C4365ECD48643BA3CBDA36CFDF15A79B6AB5CA52F025913E430B24B7448BCE8766A711AF62675E92BA9B03E4917A38B8E8A5C01E8FB6D6FF2F2FA134D564C8BAD5D033D15F4B64ACCBB53925519677112951AC7F9F8289F533D678985074032E14C70E8C8EBA76BAC12A59E215E98962198E31517CA5AD82A80719BD5144EE7F2950A07AC70F05C41F41C11D2F051CDA2253F2A6FB4E38BF8EF917E6D59F49E855FA98096BCE99C350F558E98648FFFE14D11722777E04401598CF078601520ACC741BEDA15F0C2C0584F9C46DD594B584A1B0E01DA9B0F3AE639268A8442E9389DC89F13C1F46351D4E8AF79A9D2E2EAE51060ECEA7B8EE93B7E083A1C95747E9EFD156C948520E7E95E833B89D1F559AA173DD3352DE9C7E5EDF81481AFB65ED6C30E5631BF352F87000B1098B0125947CF07F76977E2D08E30D6707C9563DEA3CE0B96985AA3C369E9FCC6F850853E5D838A8FC6F00341FED92AFF216F41EB9F4F3C998A5CA98845A5BEBFDC82DAA9C6ADBCD79C0E3C06E52FCF89587F8D6A694361E196758543C962AD0BBC1373CF1A5A3E213FED1BE534F7F0105CE61457978C91E8027402CDA17843FEB76512906AC6CBE6204309049B3752AEF878D30E4B976351D44858B4ED4A18155690396CBE9A01CD1D3835E326524B9ECACC08481F38EA670FDC6C2A947745DA065EC5954A7545F5F7C460A9C4E8B2AE6F45FCD0461E427B895EEBE216F8A939831E888C596D03C3AD7D44AD88F8E6053D60F92C7F4831ECD1C08418CCE497B51D4B34E2E1DC77D0C08933827462BC81880E6136003D75A17A1AA73635B3523C6BE7871E6478EA14C6D6CD94027C7C8D400853D6EF34F96C7B56B2D578BD61CD46C256581B43795FD7268450EA0FEB8482493696893E0D85508C8D1E24C8AFE9F5746B69F616C8C8074ECBFA9DABB631B1DC71E00726FACFBA1ED77BC7B1A89916F6C365C3C66602134853D749369EC0328680A6BD1BAE1940BAC57C0F38E04F08E90A70556E0010BAC7E51C61C8A273D76F4C8599F775E2AE712398E4624CF0DD00B90CCE0A972AAB19BA661BEE350F2315BB978D27C4F4AE8891669A0ABCACA55E746E757CE247B21C8417BCDD240922A7CC20429CC38611916EC282CCDF018871FEB4A519E75CA7C2DD583660E372CFB52D05F6D2E343DBD23154834BCA5629F6A4933BD0C844D4BC94DE037BFA128CE3DF0A665A43D90AECE383AC0B9F902D5B3292E200759266578E7E3CAB484E76698118C882599D665DFB284324334B45EE120B8B3F13D3553B769B94F1DCC14D36BDF6AAEF0B39B09183F0CAC4720232D378EBBECCAE3E57F00CDCF3C67FB0737C717D88624248C6D81EEF0EE50697A79104D6965D55125ED667EAC00902EA4452FFEE293E691DAD2F9D25DB3CFDD7E09283604A641F8EAA26825547A37F7A54DA1CB1E0EA24057716C9C00DAD3D1F2CF4C448864B054EFD792E20E354D2741FF59D7CBF980285141BCE17996A1C3B2E1EBA7A2F110A95A8703177A9CE17B43F33E57F56FAD2EE56823422E03103558F15F4FEE87AD4A450F35F71F3D8F57954EEA5372F635A916A40BF5F3A077A9EDA4F05CB17A53D10F8852520D75B72288746CAECA7A21530BC4A0DF00F722CE6DF1487FCC3F5E5DFCB1B75B54C4A798A57FD56E68A16788DBBB5FF84478833D2A9257E32BD1A562E9AD1E84DE2EFF6E69E99D9E6EB7C8D99A26AF4D4997A6B75D787FA8680A48B0B93E278DBBED17219C271598B01CFD9B20B26E6F9AEB9BAA18D217927756DA90B6097BAA62B4FD817EACD175032EF5ADF01F66E421485E9291AFCAC659600A49D859D2A85CE26CC4D439DF1BD7D082DD8FC9D314EC51E23F87750BBBA86E502443DE00853C78FE7E2F0D9D0C65AD86C2D853A21FF2EAF41D69BAD4A596564AA91DA8FDB8218BA0560A1CD713DB3207EF34E2B93E3509848D48D85CD44E367C20C6AC29F21A262D409ED302708805E11E588F1D9F84EB5968DD9237C6539BFEEE2E0556A8554339E02544952BF483D2D677D0E6C11B5F1C376975CBBB38EEF8316EDFC0EF2EC95A97B6ADA113EE1EF5E1D76059E9DD90DF14D4B3D46A0882C510EA17FDA8B50059C0A4E608B9603C1BF00FAAFBCA27532D6ED03A3A6D1A52111C79BED5E50A3F289468B632E4BB3ECE19B3E311C7938551BF5A5DD0B017638B016A4E17CCA10E1E858DB155B5998C4EF9769F1FB8A4F502765D9CC45DA68D2E1AEFFF7288F8979C12F01706662C7936D20B19217558090C025761533019E1A2DAF200F68CA8F46BBB5C8C1E10DC8B94B23BFC8317335DC049D9EB3C8FCDBEA0C04E46167B244F2044AE49AE24C060332C9B6CD25A3EF4D6114E67ED25978904426649A3C5DDEBF63E809646B77E1124A75F1890D082E2B9CD0E5C27D2DB46C1711B5D89D74F65E5DBD84E3FCAA0035C76801AB84A7D0ECC6006A28CFF2EDB9032DA3FF73E38B24241345344176E4E0FD185C8471332559CD47923A8BAF047F868EB0141563E5D80779EFCD90EE2D191415C854240717497AEB4A52A0DA1F2B8577C2200FBFA34B4D470EA08007BF451DC6E918E4F3F80C6E61A20FE8129CE6328FD56B5B91340FEC24ACA21C6CE6869907330B0F4E3DEBB53CE58DA051B5251E7F707B1B67711BC8CB46E5E8F13C00D66232C3FCD42533DD10D27018513888F2147476D7609D9791AC88608029406ACD700F2D8489DF68369BD885AFC2E7345F2706BC331C51CCCCF2C424F0327E7BB6FD1487D49AF8C36B21951B761495D90C14A024094D8B614BBEB8F58F3FC8E4B4AA14364E553C9E40D5691297269D33C3AB28DAF3025A35D8F9930EEAE76CA7DD104C037B3B7FA98586A7D8DA255CFBCFBBAC90D30C5D83E52599AA22DD95B05AA5B123EA281D06806C4A747703FE2504D8BF88392DDB8979B11E57ED73646F910D7E57D457DF483D176E4FCC808B51F3AD990844F4E45C1E34282D7847F59055A6128B65F2B8B22F0361619E55DACA5E4E26AFABFB032C82CF3D05829F0FACC822A96E515834DD57EF359F93226C22E1E801EBE16A3BCABD6D8F4B78F15F41E879DA5F9DEB44B2976226B4DF771216509B31F60908AF3DAE76411AEEBFCAE9A956AE3AE98E414802471A82EE5E8C5691DE938DA98D1E0DA9E8815041067214F8913D9FEFF5201F320F388E5129D318AC55A9B99D585599E3B254A2515288CA335B4CAB4775D4BC5BE0FBC417FEA855217969427A4AD55318A882EA56C59C4E6CCCBFFF260E3EEB001B2834525F6A888B99AEB4B8B9CAE9F110202829334D6274BBD2DDE6E8F3050A2F454B4C5A65B6C0C3D5F7010D3A4B626D898FA3ABC5C7CAD2D4D7DFE1E60000000000000000000000000000000000111F2C3F" - }, - { - "tcId": 20, - "deferred": false, - "sk": "D6D7BB2389C3B486EF060EDA3263843F3ADD561DB9E36B222E0FA21CBE60477BC41567EE2E688929334FB690F9B9691C37E91A786AA5A721A2D53446A042BEC66765FE239067701B83B448486D32B941E3F8CF7B09560A83EF561EDD5DEABB4CCD9F6F72AAF267C5A34C797D21E19FB17994336E148F7911B36D6619F0885C819B44211A3620CB82304026010C2228DC024043C844D8B648CBB0119A4805C03231D4106A4102891A2961D2120CDB962CC49665C84210242691CB808D1294611A48704340811C9601D4128904A00CD14025C4444211484EC2184800C2711022441C150AC1B229242626219960C0984080120AA0284CE2000008294ED40880949450890482110411C9260C53808C8CA66499B24583B41020234C5B180D54442414938C600806C3C4494C144A623604C2106CE2A4641CC888A4A63189020A19C98549806CD8026484364291969119282014912D20301088400688064E10000A130310039611628480D8889019382E10B52D1B266A1C20215C16608C106C99448442840D5A1069E33841913440042042512425D22661A4028A894491891029894449DA92411C12129C168518066419494810C47109C8441198049BB0892142488B282D5C840C11C551C31422D2222508C92C9A900C09174483C6911312501007325B960D19388C8C068842046590B089A1A229628020CC36092207044C28691244620C3002C1C47081A40C62328A1C4081A4486692B80D1B082820B64998385262B605194711C31288CAC28599284908B689E310500147890215529CA60D13184241A6514012440B188A5C2441084851C138669434001BA65041324459382A5BC02C001062C818011428048C46041B8910904681220641D3C861031986C9160041802D43964D4BC24C030601E4468981101062926860C881D904680B169003998844842CCA160890208904364041244E140582224732E1382C1A126280985140144D494242E0C26408828858A869C9124641C6215CA46808B56CCB226504C44C83120101272E614428404000122711A4B48401C96C83424254988C84B488D8400AC92885D92202204301C4402062285008C050039881C9486DE226014A42018B0442221285C3060C188110E0A4310C058693B4440843669A248412203103A2519C020A0AA42850B204442240543262E3C24C0013120898511A018D92946CCA426811A1892132705C42225C808421354404B35020A168DB9224CCC64D52A891201806E66FAF50875D34BFF31BA21D11127E7BC0F3734B15538D3FAD3B8C9BAF8BF81D73AF0143D3F71139DE0814545B31D8BC812095ACB3191882E0EDDB738E80FD41655CDE17145F76B0ED5F7827C392ACEBE65119890AAA65C248C0EF8F8931927A18B5E32B5C5980562EFEE0CE8525A79B8FFD94CFDBBCEC6B60A692649313AB767A2BF49C17E67C93F2068F0DC65D7FE0EC784A3F66D7D3EDFEA614771AF2A3BF91CAF0A02031E5581178E8FB2443ACB381B057A1EB30CF58C9CEBEECB0C6653DC628B6540476C4BFE14FE988FB48AD41E7CACBEF5FED11411674B3EDCB52BF128B1D932AA2D73565047BD08588C189239D4A9B7CB39C1DEC758CA97249BD1B6560A7891EA98937C39568651EB95C00B7C9ACAD4682DDDD532E5C4B5317EC1E42BD0D6D629F293005B168D985DF96E5EEFD7DE7EC41AF1163D41A7C694BA9E4BD2581AFFD2BBD76982C9723D001C537E6E71B12781C20D7B1692DAAAAD9AFF5509300F313E289745F3D74B533280AA38882EBB67C6BF70B80BF7D4D251919C134130F73FB0638D2C09CC7EECB1612217E136B9579D0BB2D16B88BAF9508C6A7CC7AA00D86FAF63B696D865F06D18C29C0229D70AF2C8F013753393696C07105595456DFFE299A254FEDFBB39AF3EB74BA12BAF5E5E027AFA3AAC9962E0D5D2F47DEBAA7631BEC88D6CF8253E4051AD23665F1218D2C9CB3D6B5ECC05B657E24BCEE2562B0EBB02FC7B347374AF4A82BD0519BE333B5718F5E619583EF9D8042BE77984E9CE4AD377839CFBCC0526CC557C6E5622A34B18EAC4307D3387DE7018814F4573FBFFE57ECC0FD5866EA2A4CBC20087E6CAB7D2322EF2507A2778AB8E4CB91DBCECE30777E88103ED452AC7AEAD64DF62B04FFF2DED225DE94CB0F1CE60EF463FC092AA5AEC38C0EF412071C7937B290FF8C7AC03DF900C3FC37119FA3D7B669ECB071B6C469358F4A0FBB78D728EFB36809B52C46EDA4A6C17C70AD26CD5155A278C7F4CC404F8655B9255A343EC463F2FDDA23CC6D3DFF04911A457F2F5A0939F20DDA49790C9285EDF39CA662A384BF4CAAC1C8605337039CC1E209DBA5A3EA1C2BF65AF1C4E599E626C91EF6DDE56032BC3D65352C4C8754DC06C3EA7E3942D9E34EAE10DFA9E35F6848EFE5034226FFEBE43123E05E5B00AB3BFC5F0B17742581F622E63A64E00CB2056DF3DE16B64CBFA4458AEE2FA83A27913E65DCFF5ECAEBF8C0A79F31C2EDCAB50AA47FD9CEFAD6DC35A326EDE7FC46330185B195D6F132738730D553CA91FE4B2DB2353655D9DFB29D78121FA72827D1F222E7BF58BC8F96A8AB0988D8A9FDAE0999512BFADC6205AB4DD3EC37F6D578E5B5B91F30AA2DC4F96B03EAFE2B354F9A6769432B3A4B916EA5629AA9E313E486090818E20D34C0350AD4662F177EB5010F47CC68D8D435EA47F72A5D8739222B5ABD5537016114764CB18DEDD82A701892AE115B00B675AF3038E33169E918D0EA82167C481DF35B95B6E79F72D356F6EA7326F7EBEE215F6DDE2818DF300B4AB96548E1BBE731C62D90F4ED53B1721FC2EDC30D22900ED6DD15F341D6F905401082393941615E8D0BC240F8B71F2BACA80DE7C18E76DAB633AD5BC34F865EA5C7481685C6272AB4FB882A613B39462C2E64743A47C14AE43B18786B7700A790E8600717F37F5CF3CA9A3D784ABE8F7E4F805D7676DCFCA8F78F7C65ACBC564CBE5734CC1B52DB0BE6BCAFC9EDB80118D7E379D946196548AE787F8928FEEE83618BA7D15836376E235D7213DBE23237F6590A1224A42436F84645BD9B5D0812E0092665EE8BF6E1EF145D89FD0DE71D8AFE69CAE8D94953A7C17289951252BCA1E055E31B013A650376E20E388284EB33D8F951EC7D80E2D1C5AB1A06E7AC3F7EEB0F639EB1A1E5B6C63EE21AF5BC16CED82F13AD0A57674FF448008BD213FBAF56DAB8233D64313B4167423D378699F4320147AB1ADC424B2452869E6646248186AA0682178BA12173A1A28DE962EFC591EE490E7F505715155518DF03416F03706E2C457B14C970BE86E5AE238A56A42679BCB114E6C6C20FD7042385DE15BE862D0D523F82190E028B78B01826595D3C05B2791F00DD58A9DF665C4F56B2A21DF9FE13373469FECFE05C3257F0E55285D74CB52F2FB230728CC08A6C3A9BD8825FFC69E188A132FFC9A6C8669B0535392A03CD777A49F0A7B1094328303CE1B67F0F92BEFAC8462561D8877E9C56DF6EDE9B87F3C1BA43D50D489CE7AFD4036CA0B5CD5536AF269429E1FF8CA5E793DB233B00FE2FA5ECE573AD9BEF553B987371221C79F61EEF5AA5519CD7607EF05D9C07726A62130C610D3E789A92AF", - "message": "D7D7964C12AFB6C20C1C21C7DB1781478482158DB275D289785004548B57F76355A31FB4A3FEE01D3C63F4992A050DC60A0A31E68D1ED6F68C394AF3CCF22501B64CCCE9DE8C52B668A2AC886C5EC3C343D146B159AEAF228DFD40F5B449C0E8EB61F8EEC8519751BB8B943C4163F4CD2FFF3C8CDA1162AF3A953A76DD0D41FDDFEDEC612CF3C2805D21C2BB5DE9B7C7741E03F6469FD6D8C324E18AD1F5727E46F226F82B69EB33F5832CB1E926D31C1F0C6C508C88EF05E617CB1726B80389D2ACE13106D7D4E06E907F36A5BDF08E3C0843D57F452B28232DD0FF4959C375B9D16EDAB40F2463E1EB95B7B11332B7171471E92DBD5B418696402B3AB6CC03473049D87407A3ADF27092DB86B2BF64580BB5155D0AA503A9E2E257BD16D474C61B6970778BC2CD2ACFF4D3C0052368EDFE420E2A921FB1A1C06336D5CD7CE64453E0A91AAD629A1AE0A87DBC47C40D19B7253AFD18C7A7C5841DD926DCAED34CB11B84133C2013383F27F139E436BF9A891283A1C9975FD7F3E63BC09BDA41D2E261F2065E972C3BC60395789F9AACC0DE75001D80B5AEA321E3AA695CDA3CD59F91D491F69D108A300356773B81BB9E4F979AD7AFE063B7F3E9A46E225C3F1D7AD0F95A39FC57794DB0FEE36CA18CC652CDC59BF7B6A598EB0E8D4D165D3B2FE7C318C8470D6C1533928E55794EC58137BBCC5E8C26E193984168A5128A0BDB0678323222C3821E2C52C2D8493EDA54B4A0D8223842A819F63B8CCA2C9868F56BD89454A37A210FDE04A0343FD7CE250B943E7A7F76B39ACCD5AC44D36023CC8701B01863E5E8F21B5798EBDC75EEA27F5F2A4F64EFF61BF0F73A8B6C3C6776F07DA92E7A4D8536E3A36A7691A392066019803AD7134931302A66E81CCC9585CE2A8F6E7B4FBC009A0162AE20274556E0565702C235A17FEB257D364E1F3846518B9DD7FA725DB81B427079933556AD61B4085412E7106C0289E1D907D7430B7BF5E477D5A70AE8AA69EAD2A2A409CDFE850E912AB33B3602727F045B07210515121E9C0355336F4532074D1E13DF818E3DE029DD591E9991E7CD0816501BB2B708E68126970BDFAFECEA484CCD1ED07B955577BAD90EFC9444330E35E25B307B541A3CE35A17E3B59B02EC55B2DDC5F602EA72809706D245CADB3E7AC07AB1D83FFA2A9214D26507D50FC0AB53C77082AECFB094346F767EAD51B6C01EB9C45CAE401C226073C5B37EA6F00D857F96819B5C3484D660185C1D8B06DA85E4ADC61C462BEA480CDFE25487F44DCC9309B42B3CA4CC7FE1A2D92A642E4056193A72F3BDA18F33C2BD4029B366793943C14CCB5CF3C057A183BED55EAD054C0996BA002D918EE0D5101FFCFC6E029F7737D86A7B49ECD33AA0844B816444E2BA3C97B605F0711C2CC71449C7FBF726CE4039A390C089A04CBFF19EADBAA7EA5AE7F7F394D1DFB1DB682B04EA39932C3E3205294E9FCAB2302C87E5A24C8457CCFF835B273658D36988435A72B9CDD4A593EA311174E9DE421F29EDA549391EC29EBEB70E38BF2964179D377E0DD15A192C2FDB6A47F58AB69193E65FBCEB07BFC1674414E600D46E557907FFA070D60589AA9050F9DF2AE2D29E0E0C2E7FDD1F9CD8EEE3D7E4C3BD7FD44A71D85D55A0A014DF990AA398AF4A1BF8AABE5443A0EADF5CF510771A69449BF4918F75FECA49CC617120C7FEF9CEFF5AF14D07587466D9E6D6289E6D0185FF61099D66AEA50D45B216C9A97AD0B685947E78A068A5A492F73D1A0B10FCE32A1A9A98B47E627DD392B6ADFC065D1700E1389A502BA09AF9BE1BC82B799FFB5F12CF0792D198BE2FCEA440039E62ADC06993AA0C5CF5F9212C694C3C914C78D2B94B5FB41E81948C45F64625C1C7620B585A77F172B5AB718425136524032515CA02CA016D051AE1851CC107677E4640CF7140B76143D4834DCCBA396319A907FEAEA40807327C9811D9344638F93E3E5F777FCE0A24C36F0AD133EA9E2CBAB963FA01A6BDA5B84F404ADB24B2DF5581B758651ED30D01FF5461AEBF81BDE2EDFDE6268D7AF697C49553DB0C2417D0B991B5A78019B8A08A887B9C546A4DA21C57003B8298E6365FD97FD674978A7BF0B5190D23D93AED3969BE74B15570446CC77396A00886D29FD981BB07F10A48FD2DF1C4AFBA6A8FEDA043096A850FE09486C87FE087A9E27AC8C78E69278D7C7229FAC03604CB3447541D49EA009A6767EAE2956E7D72F7EE28C97AEFB1E30BE92E0A05ED77CB761B36FC537E970A4443B73F4D3277AB7D2FE738027BE76B43A79CE0F545DE1EA737150C19FAA1DF262A45615AF58BA7CA234FE30B1E038C2850F7F45EBD348AA51234D8DA42CECC12F25605070FBC3B9BFB9D29CF8330DB0FEF4FE7C7B4D27C2F4D71173026A2684D1F673BFA137B7738BEA8303A64D8162965FE7CAA1BEC792E50188387F5F9442BD78EA79959410E6CF903B32E00CD48D1F80C296BCE40DBC701943B22E7713B71D73107ADA90F358F6A4BEAF7B37BC28C3B6AF8316B1B5CDF3B50A98FD079B7E4FA66A9C359833BF13D95872B1F1718AA240B9B9E5636D880F46130E4017324F1760A0ECB25E797D6094E67449C51416C35AA03F46B2DEF0832CEAAF15A4540A5D9247C60834D54270007CC453F0A4F9E538B294118FE16F26B92197A0E97DDD594A64FECEF94F75FEC1BF281205B9B4B49B989381AD54B28106CF57BAD4043F288ECA0DA569858DCC344166426265F600DC6BB518A66C23581A5854770BAA4028019A87FBBA912040B149EDD0ACDCE95B465365143C30C306C5C84699D63F061212132F5BC13C64418FE1597962E92060F22AB611CC623B20E649382ED2B0320AB350C9CD3DDB85FC6521767761B94FFDF7294A0839B962DBE06D274728D9730668BB22B2E7178A3C22FFDB2F3E2B8E1D9050F845B69AC5D603A0E4B807B8EC4050B492EFC6E05EEF6EF0A30F9F768CC5153EF01519C3BB0BAAE9933606E93CD5FF6AA5CAE0A35C90761219619660CFA6D6EBA1348EDBAAF67F73931370C4F1886239705F1D53A0C6738EF0B4CA3A7F4E0D140B08719F0F6FB9C31E8179C01F76C6E39C15BEDCBAE1E412D39E4B64C99E050CE3803BC86C0E5F2F2BD84594E9471D3C1983C8844AF09446C0DD9D6E8EE59B542653172CB2E06764AA09CD5F28B4F060FCDA4A64F23B600ABCFEA8D372F928F9376E49E9B80A1663E8CABFBAFB513579B10067B7EED2C2603CDF36C944503F69B4C8A05E2EB17154823937B49BACD9E3B7FD33A262DDC1E7CC689B296EA89D208F5B57D544ED76E4A2CA95A0BA8ED8D8089561E170BEC51C9DF54B9596141F17D9E2437474D28919EEB45127FA6FDD180E214D8DB07702D2CFDCA7DE075598F3E2800087A6E70946232258838184E945C352FB3F1801A7EA79FA5B7E28AC4C4737D2BCD3A5906B0960658F68517CCD1B5AD07A439CD0D69F53B62801E069BBA28AAA004EA034264DA6980FFEA0FB9091FC3BE7E45EC6E138215D07CBDE119170643053E21EC95732B4D91A8E1907FC6B81F61381DA1FE2EE9C1F080776DB26C11628F69D6712981FBDC1F441B58D5739548EA6F4D2B7996ADDCB04A6D914F4B92AD00B703150EA28FAE639737AB0A990C5E11C6B844191219937FE514B8305F7357EF26F1E2D2A70EA3B3663E92292CC1C4039EF0C3A381D3F299D6BC1D454315A12961D7CC5E0FFD028A5BC5EC05B2693C025AFC46009DB9C7F250F2CFA998FE795243459368C41FFFE4F1605C49C5438BA566B644BD68E56FF540907E0FE2F3EAB80FB1483E0FA2B99FB9AEE50CAF0882CF01B19C83B789048C84A30A7DBFB893D66D0C5148128D57023AFC466D71F3994B0D3DC875C958C561FA5BCC67A5F39BFF1B57004953900CCA2666DC7CEAFEE8500AB0705BB8AE2D6E55A5D81E577E691679306B5944A4FB7E988124F7C71B06D27A24E50E0A143087B045EE4E0FA44B4A5DA397F0D16275F0BE7B6FE936DEB343F3E8C3A3C9C7BA10213DBBB995BAFA086A5AD57A5FFABB3EC7AED5C52552C56CFE830809ADB5A5331EF6EA8CA03C9F9440953BFB4AB2C7FCF170596EFAD9070CCA5CF6344E3A9DA556202C26F6ACAF201DD09E2D5E90C9F4B756444B5BFB544B1CE1394F5DBC64DEC2998B14A67E5336BBB46A4F2424ED04AC53F0B219603FE234D3A44AE36BD5871FC2514C947548A8095EAB9BDD891FC12C1CBA324383A114E62089EF265D94674F47D843E61A2166863435BB752502BEC3CBA777D225CEF7063766B5DCCFDC3F1920C0E047E28DD4948D58127BA74C4CD665BE039CAD881028202673EEB5F4DE47B162C172D92381CF44255B35F7172CAB556BD0AD23F07BE133B96B645C18B9E88D0A93D3F7A141356C278C296A43E28B8AD0066FDC6C514436B8141B59EDF6D04EC579D9A3B67B5CDAAC1A7435B29A47D5C45153E908AD07E3368A73FE1CE2869CC1DB058BB750DC23F0778A73347BC02B12373C7492922ACA0491F3929E4C52378EA9B072C6590C01C6E67C32780B742A1C114A6E1A1546724ECBE5C351A2096CAA037FA9A5DD3D5CA6568AD8047896E9554535A8B8FC3A0E53554F04B6B25750BE81AB0EF5C96F51B9036B552399C79ED09B76A8F3C8ED56127573152EF75F11ABAD72CC166685CBED2870A6524C83C66A7EFC16C303FE314DC2757B955D7A2AA9BEA2A760321CCCB23AACF2F93B1887F10972A92109CF4D55D2FF333238059A1A69E16BD474CFDD271E1F925153034DF5A8B39BF795938A29761C301044EAD2CDFD46FD880E30A4A4693EB593F8C471020F771D0AD3976067697A0419744766D3B38B15C5065D6DC5BE6E8EF6FBF4A47B36A457ABBE8558120B03E57CF66313F835B0889D3FA7A76722DB902BA96C6B4FF7FA7D87409B843B29546DAEC490A14E9A386266449B76B32C974643C1826778B2AA0D97B1AD319717CC39B55BD4FF691F51AD10E41DFA04922E3571339B08620AC882C4FAC09F484947833F9F08E262097ADFC9E47140356E075851F67ADF9A0BD8BE3D3608E4FE1B92822552690BEB802BEC1336143BC805B9CCDEBFBBDACB6DD6A8ABF4628EF68D15DE1F3946EE3BE5180CD1464C70B484B3A0C4FE7214F9B1BB6C41A4F1048DFD335FA7C8BF7BA67ECB50D3B48C87D9174C9DF8EF8B29EDBCA6DEB5ED6C0736EBC15DCD25880021AB9050285FD1A0907159AEAC28EF4E5A01852FC9E12736CEF4B0A4551CF832C5F8C5E83EE52A73EC70BFDC233BFBE7901679C6584DF9E694CE3552D2BD104F4D7DE9A70F8065D3C7DD7DC3C7BB0503468361656C46AFAFA0D469A3B8F25069338798293E426AF27CE50D07FD9ABBFD72EE44232644D7E6A628E97A72E1B8D4E57A5D82B978F18BA687A9432C56D7894EDB8471C635E3900A51A130CD117A2628395DD5230AD9F75F0B590AD4E1374859B68BEC07E10E424F818C926F5197FF927E24649E3040DAC88C52D578331297E4118264110CA44D9EFB0664E4A183B2E1D13DE7781C59DB1B9DF8AC2EAD3E55E57133F30378D1CF669D80F80C5B78C1388182B688F808180485DCE2DB0AEA1FF412C05C62BB336487C5DF81345E61F880D4B619CC3267A6CE96AF37DC5895451EB4566D54F895EF9A4FE9F09ED7AEB3BDB93B705009D44A7F1455F7ABCEB371B67D58E2111FB1BB440723A17DE7BA238E5A0690CA4BC27797688C05B4D9F6BEF066D758FA3D0DC44905BB13816CB30C1909D1A18CA4D78ED6531F1FE3FBC1001AA40D30F3D42D5FFB9334A1D999CAB788700075DA1062FD96CB2C289C09587EA795AC4C233B7C1A7FABB2EFA26E59037CBC293C796895C6F0306B6FEEAD0BAD82D610339C4674B1AC7ADE70D7522E023B1BD5A8B7DB55B7C8489398EC29945E1B8941D070941F5165E017CE205E0F83C95799830B2737C4A781C7BB98D991C449FFCEE6D5F759D49FE1CFEFA0FC3890042B717EEDDE5DEA7017C8CA68BE3235CFB7CB59EF13AE3BD586626911A7DB704B307ACB0E617C1558BDFA84332F5A014AE1967C6D84C17EF780DF6AF3B6A86A9BFBFAC3C07D16663439DEB091A5BBB5F05520BA12776C46F43B4825C8B04E366E8C2AEEE54B576A9BA8F3DACBB5B940A5A71A41ED16F6C6EADF0F18E8B20F2713A9654BE6615D0B970DD0083E5726045331D7D7D862E0D4D7104F4257EE786CB13231F1B90C717D7FF3A3CDEACED63A216706601FC059449A1F5857DEDCFE3ADBBBD61591486B5991F79832A77BF32F672E1E562953288847C2392466037417254B48DEFE3E6840BD2FB44749A007D444BE5A53F32486249AD553FA882889463EE1D3AE4F38EEC281117AAF77C25D9ABCC14DEF49B3F9F8F99816EC01EA5138DE2B0AA63BC49692ADA306EC1D7FBCB0C155E5DA61677148880F73E6CA9B6688FE982F34731EEFA19BAE57BBFC81086D7FE08767734FD10E607DC52B663241045F026D25ED3C9148BC58293276D2C64E3AD9180B9FC58B6CBD1C700567ACFAC5E1CD8DC2CF434798EB272DFEBC8F2AD0822DD860F822D1EDC53D6834D47D70EA56E5C1A1A3497B133A112D71B250A926504482D79650ABA26E310C4A5681A91998E04E65B57B1505046FB1A4C53F1ED188BEB57D9709CAA54B761CB94E7F82EBB5F2B1D12231E506C219E161F6F7198BEA5ACAD86D5E0C4AB171979A82D81FE5D0A79BDFCB082C529722DCA3537B16E3119F916D65539250D27CD94E847D299EBD34DD0CDA2B2A7BC8302B00AFDEC68ABF1B18AC77DC1AADB3760AF584F583C3238C821A06D6FF2A4B084A800046C7DC715D4407414C2B3F4EE3E2D955758413B02C4676BB38E8042359F9A21C6991964F606B080833F06A033D52EFDA228344AA66E992DD163DDD664D3B31B62E7DA1D3BDFCD8BA2E7A9ABE248DF8154E515E8AAFD0990A64544B39253683CDAF8E9036683E2C810DF47A00F4F7316276029CD009E045BFB30912EA7DE6AEA97A8EB555F06F18EB22676BF58F4D13763EC920D4E0FE5C64E481A5802A4EE878E90A4D076E6F2B97D77DCE6545294059893C38665F98B3C89523C51C06EF69F1CDB01ECFA69DB3772F7F6C94C7F288AA9DAC6F9340B52907DAF4A521E75B1743119557CED3DD06F9D0781C899F8EBD3B45AC771D337B87247FF1ADAC9683F04B090C22842DCE5714CAA30EC7DAA9F987A03BA5D7A62050341A849C2AF2D09DDE40F63299155D76EA841E3E84AFA1A91B1C9F7C346230423BA637E1A4B8DB330827BD6883C416261D700807E95CF66BFB28550525D9C49CA87AF7AF3B7BE7F28B079A7A1B9DD27122C556F9FFD9BD3355735D8BAB663BA3A2D906563638EB736907E0A68F4CDF59B4016C607C6776AED12DE827EF50FA6BAE2AC6FAF686728E25D26075878E603D9A4DDBA6D2E9CD69D3FCDCA8C61146C97D6834F08A7AA68FA73E4A49D049ABADD6AE38351978D3E31A50749D1619CC701C30BF333C36ECD382F41EA6CDE8B9479AF2C2938262F93C9C7127764D2984C5E418318A9146A09842BB9712B4705441C7C2C79ADFB1884EBA507ADCCF2E8E1A07D316222A810A628DA2440BB0B38D164EF6A5DC448C99FA3A5C0B9BA82E3B86C648C64286A2386D9E0B2779ABC3AAC6EC230B0AB55463CE159CC462EEA86EB41BF0CE5A7A793959015B31A75AAF97FEBFFA4416E3567794A240BCBFFC3AC8CFB3822843C269C03039EF612DE9060FD15CC19DB7782136443490C43AAA734863881AAD6A80F3C05CB2BC381A9BAB24677B6633459D51EA61ECA93782C573ED7109FCD90E6D8B388F063A09628223ED6B1289AE98E5525F61281AF5B983C696BB1FBA3D891637F029FE1897FDB3127BE162BA485C2E0D2C4785EF455DB536A79D37BC75FE0550255AE6DCA51199E5516E78AAF02B63CE7795B942D93C92D706A32A30E30580F48C53E5AC2BA6A2E68A5F2CD735BBDAD1CE1BC1F6F291A30B07118247F823457D45AD66CBFC32E9398BACD47D4799E888EB22542883C6A2F21EE2DE14DF2D925FDC74701D44C6F4224344BC9584C1EDE52661758A8221F2B6CBAA91F0542D7D4841593E357F0FEA60ACD64A757C6D9DAFD332425C75D3B81BA9F02D2F26A0F98EB939022271C11869BEEB5E3B3D9BA6F8D9B8914DBB3781447CAFF69778A94B0A118710236677676580FE93F71834CB9F87A5D872AB0B16CA5D6999D826996752E27670083B2E9EB22A3D58D201DEAE16881C31DFFB2E8081904C51052992A2D9D094D6C64A53BCB885D3A12C8DA616AE6FC36AC87238E7B93CBA5BF7E72486CB69E578178D1DD9F3E4A318E2E8BD3CEC44382AAF5D0BBF49AC64E32446A05C9DB689E9C9925AE79973C8D33181931E1FDFA29843C23C5552AF0B7175B64DBBB8D5997606DC1C8EDC7CECECB35E6E541ED99A72025932372C90C6E5213764855F7B31A0D6B2F7B951A5F176F968E518952CA9D93CAD37E9756F28FE966D33CEF2E65499760481C7B2D6203A42A8A7548E5C535406566CB415A8A45779AA9071DF341EA1BD7475E981AF30A9624C921AC7A2A926DF13031087120DEBED0277E37F8287D5C26EF6378333680967F3C62294915AF08D10F46609E010B4ACF81CE9B9979D296F26AC22933636D3790DF197C6BAE40AEC307A1CABF6FB6F90896EBA07E117598B8CDD789C4621082D9F5D054FA13D1BB224CBD0F128B64D9E4868B43F6473D712413804D6962EB7006C4561439AB7F93EAE1E7BB82A9BC491B30ECBFE22757201A19F079A7BC9D09F84FB8DEC4700AD1366D6B4D67578B249D3809F66CE3BFBF932A94447CB601462F4F031DCE59711537599391D6FA4ABE5E7D3FA902CC590B5D77284585322ADA0F4237B205D991CCE10CC2B5FF1D36CB601986A790008866F118E760265211FA1F92BF1DB5BAC7D514CFB98B335A2444E74EA7973C4A6CBE6FFD6CDDBEB69CAA87F60013522E0A17B0B2E20CCEE8546DE6A626B30CA9F02FA6014BBFC2889806CC886397B81AFB1E01A4412C6A12CFABAD3F5656CD6922FB8DC82E4D4C0BCBF1EF5C1F9E8401AD4D0CF42C3F958DE7D45E87CB8E8A8762EC26F7996557F8022DD3D6AA51F72E3378CDD0EE304559F3272D86354E399FD899AE16BCC78A7B2DEB24718988A5156A93D5F52E532110F2D3BF13D085E3369F6D6F5F7761B2097DFC340F41483DB24B0E1C2874C90D37F925787EC0F86751FA65B9B73AE02376BC5ACE3B9B1A366B42801C47D7ED9C5914AA4F9AD87E544C27CF2977B380325745F406112221E238B040ED25349F2123ED7D377D47696AB26BE05D7D42F6BC3FB550D7090189C65C1787044320C03C854C7C7E7FBFF7B82CFD079AE87E09BFC4940DE561246D906BECE764FF9667CA06D8DB7702CB503DAAC1FB7691E5B3438C869AAAFAC70550B37F39CFFD927A2863A980ABC186466F3F08BC7675210F95BCD50779BEDB6387849D0D492A9F4667387097A17B7028940059766E5E99FDC0C8546F33F9B2990B5AFC2BEA2A46B8B5671B0072E1D7FA1C19012C57D6CE83A087279FD344BD7248F38979659C31952CA15D2CD23A84E85827A3E16BFB9C94C461B82BBF735A1293ED4AF7DA2011CFFA7D27E47B92F568B2E7032D57415F93EB53A9876C3C024485C8BFC79337CF5B550B22CB8F77F87DF91467C1C7EFDB43B4EE2F998B76DB2D38B75C6400EE7D1AA8CB1D328514720AFD250E37694B0BE22CB0B610426826724DB7D00182F5A3075BD10CC3D208047B0E7201A1E918E518B8DF59A3F5C8EBA58EEF4A998F708D0ED6F7504E53B4C18664ABE93E0DA55188515F820FF479FEAC2F5088A38E6916E7B01F574AA136784AEF4E2DE4650AF60782D902A6683D1E2E31F184CC0FB0C482905E4903BCE45153F5EA3D02A8209DA42C885452FBA735F913043EF28A7E252C50C61502BF128FE72BFE5DAE36313270E41F3A24DD2558A55108264CDB8D5243887343DAA181B356AD2188445C86F139510A8FDCC1BD9FA4A0B68472793D18B442AA35377A837B63FBFBE26CC9F95BD57A9F89E44194FDBDAABE6E1CE5AF528F9E524DB86C6BD8DAEEC171BF7B3A530ED36A11CBCCA706905291A3435E6A356DBB5DA72D082F4F9C6B568B4835404F4E01BC872B1D1DED357F55D7AC0834217A19B70FBA7854CB5A953EE9A9EC85E63A3DAB778FD44F14BB081F81C389D4CB450067DE2B8A8CE9894C6B6A31C8E55501296170C37921E1E7D28A4751EE07B5FF70B29F31870F9BBE6EF0A1C636E7455F716FDB3FD43BF7AFA9652B163B4889EE2191291E44C660F491450F70C18B5D0DA072AA67F5D79099C0E407F8042D036E71734183E4F5D22BC7C10764C5C883A16D3F433EB6FB6173151E1416E238C5A8B9D539553CBA3CF3B16153674AB5A7E4FAFA30C9D5BD43BAC88E3E21F9838D2B28521A7DAD7E9B9E0928FBFAA639F153301D9A7F53FDFAD442E6C3D848361CAD6C09914C08E7F2956984B7D08186A19C5686681630E924C99E1365A0040522C0F97D8157C647D9A823DB5888B798F7B896D7DD6B07062AED516783D2802660C21D7F69794F386433E16F2C6BD6863121F5F5C674C7303052F6C0803A8BCB0750372F1EE8BAEDAE6D4CA4AB376921BDE1A21FAD9776A7F12C682466EDA5A0D89CA6859D8477D331A38D4D1CB86CA8776DBE25EB5457ADD5D4B386BBFC812BAA596D07DFE08F6C178D73F5355C7CA4B32410F809400A359486761CF08F50A598C299996D1FCC9855C775E599EC245BE1B4161CA229EE33E2CA27AC88D5238D630DE169A86E68D930C311F783FD0FBC22FEF2241CB3B38A2C31F7D5F8FD6B77BEF9D2A9A8574AE3D832C065B41A75EAA010A9E45CE28745B799B0E352410C0128C611F9D7AFCCCCD34F06A3F96B13ED254A16F50E844DD0F3AA5975242E32EED6C9C0C807AB24B715A8789AB38AE0010EE511852FE2CAF", - "rnd": "F32C3D559DC84BDA418EC707335B795E07AEB17FC6A08CBDC2B67FD9EE29C832", - "signature": "0848F20580F7078EAABA079A9ECEFCE67860B27E11B76B2C16910B55CD7D3B9D63EDD5C18C9249D4892888ED3F96CA3F1C8D9714923A1AA95277749950668BFF9CD1A0EFA53C921A714876E9479F749BA8CB3F5E14BA1D09DB5DE9B0EB57F1D59E9E3C93327CC5B43F1FDCB3FDD951A3053CE55D4FC309E224F77F1621321FA2D68D2414EED078352DF42E534A4F17594B6C3FCBD1E524E7CE5CB1DE4DF88CB759238112D65A77CCFA3B970FCA4D22F5B708B15D20397FE55388A6334E6621CF5C586EF363045E548A69492327C8EC60D9D16847C72FBBA85A321DB6B6AFD6B6F5705B2FB4D32EE3D841E8EB18F98000FE72E0602CFC34064949BEA876FD58501B15157F67D0435D11D8C1D51E0B40B9A899F154318D6407509D2BB87C0B2D11A140FD35094078B6484B62758E0E76E2AFEC7B3EB341C754B1C9318454702C181F3DF6DF162673585576E1CCD91E7F8273E9DC719C03887AEE86FFC80D42F723903B496B21FBB10872804D5D0586E9D2D486C9128AD3D291914F73E701D93EBB6DCD9DE2A84ACBA885ED1ADF64369C784EAD94EBD7F3A99DDCDBE6BA33E1A3E38712140AE37BECBD673551827A7239A3C3DC8C11337847CAA66B73DC49EA98CEC66492DB39666971B865ACCA012F9AC55B35CB3E9D09FB3D5B2FBD89165C62F350A14CC6ABC7C5242C76DC41C0BC4D6E7475F97DD0FE50A669C61584C982CF87C66F0FA9BBD295765A0F32E244998FAE798001E6177161BD2F403FCDEA314523263C4D15E914FBFF6F4910861A770D6848E3647B7B71BA018CBB503A7185CDE0D4844E40247AF141D034119B0CE8BDBF86525E6ACBEB530C2966DD37DC2AB1A14BE22A1169C904E2C90D18A16C113661B9D2339B3BCC9BE50E3A69559DC847FA9BF0E67D377267E26D3AC94CCB47BEC06BED307138AC1D5C69B31D299FA4A238F5B78FD5219EE4CE5FA7E5945EDFE4DA917DDBF5CB3BD95AFA3A3ED242A7EC78A3B9ACFB51C9712E40488136148B364127E2272486E32D380D1497E7A845C40A03496215FC6BC7DEE48F748123F22F8A1F0E34CF1C5B44FBE3098AD291CC47848501168A02430E27558EB9F5A9E36B1245DB490B2DD103E7473CD4CEFAEF0E6B2A2F2E27CD2A26B21F2D7EA9710E80AD5B5F8EF39DB220C569A15082626A7D1CFA2CF35549AF242D8357D57C86878CEBA84DAC5D5E9087E9DD2540E695B36409AF2A7E7C17E9C89B9CE5101F5B8FE9C6E644C1E8F3CD6299FEA0978D729C826287662FFED24D4455A0C563908D5FF36984F232ADD262A48E8E03AD50E7BDD998A2EDF1B0B95792F7B163B6FA7FD6827DC407AA812CD2A6EF5562D36C83560EDF50C34470DD28C0F363159A80373AA3802A8BF246A521B5A7192B287A69E94A50243EE9F76009924B7A04EBD2609DB51FA23B1F1A852794E4C749D8391EA335C4356BC566BD756AA9750E653753FA25F197E3872A6D7A465ECB57B20DBA7DF70AA098DE0C68554C8A0E48B4021CABC6FA83BB80E6B024B819A22B6648370063B5F3389007465D3C394F64E60AB253F7279395FADEC592EA0D527BA7DC29A8DAB9578F5065F3D52A7C01AC521C4CF45AA39545D045D83EC793EFACE7FC0EFDB7B45985682D1639AF4F2B1F4363F7B43E47802A77E7A64C53B2D2E97BA71BF15C2F8497046B37799C146FD06CC91D97275EBFB9B089B9431D314A211A8A021468AD8E3E72AD2BB4BA572F5A7FB1FA84A69FE2307A419564D985DE57BE86912F93110CA9E1589FBBE1DDA13E56552C225745536DA897C774B6A2F040FBB37C716BE81000668B5E15A9F39B914B998F1A711DAF7174E121A2C6EA0B2E1D3417D895903577EBAFA98A7B904800690827AD520011DD40A89B58557B1CEFD6C33316DCF5F22C4BB3ED9564BA249B7C5C0DB11553C52D53115EF02D1A9E0B28AAF26BC2B14EE0654CC1CC4FD01CB5106FCB7A7FA0592A5A391433E5D14F7F33550B95F9C520155FD60CCA64B05E9B2C94307A4265416FBD464697A150297770D0766CCF09FD83058914355D149B4C363CA922417E0ABAD4D045C9D44E55CBD23204B2F1B98DC49855AB6055836B1ACBFC14000C24F4C1479D554C2B2EA8C70A6F87081BE76BCFEE0EEACBCDC7057ED11BB34EC43C5F073EE0341D216C2F0E2A5ABC7CE03AE878F9C8505AB2E8A8A4B37EC3930F6E584CED25C4F4021CE5FDFA850B22F80B593C456D691C7E8C0335DC5C279F7F85A167DFCE85CA4B8D504B739A495578C06F8B10366DC55E734DA62DEFFCAC0FD03D45E696B58CD5FEC9D4B35C94D4168DC05AB84E5C24C622054544A31110CF3692A8F4403179A88FCCFC8DC63CBCBB486DE9963B172BDEFFB0750F8396756617126D75B3E4136DF937BDD2B8DCB99804F97DC6C48BD6895A7C98B8EF60441D70B112BDDB6998974F93868D4BF6EAE0A466AA2F52AD4CE63C11A27A2ED1AB712E879F0CCB8D29C2E959563E45D640133786F7D8CF687D28A540F4D76E52EA7CF415B570D7500DBF99A7CC80B22CE728B598C9327C392ACC31C3FB6F1A74D6C5BD4F82BDBD0551DA22D42914040CF7086B1C6B30292E932B6631B99110FC5EFAAF3EA59E6BE473A29DDF4E5F6A657E2E562DE99733A6BDFD180F0FD6A3E78CCEAA8AA3421C957503A781E75D3AB2F4C9C7FB27E19B033508F38DBC4835FE388D2103960946703880E827F89F1C4AE0ADC53D4A33C097D94724A7B732ED93C5DB1E5258B1CA94B9FEFD11511DFCB7BA984012BF84032EB29CB7A8DC46C89250B3F04E6428D585A8C403F458372CFEA7386955533AA3285B48A5FBC7C6FFD643D70D048AF0EDE756C51F49A37FF22A9F1F1420EE0C6A059E8C281C1A168534F5B7ABF12D80A108E159495FBED116CFE386176DB59397F21887FE342A609EDD7C2007098CE8C1E60B7249D3733BAB5D4CC8AB2794FB7CC3DEA8A0EFEF06310405C66AA9EC921F1694FE35A6A0E1D361E8B4C88A973F8073085E47CAFA2D661CA0867E1F3DB97CF62BD0B9FC7560AAB3095EF2DADB7C2E25A83F0ACB7635ABEB2139CF6021471B7658F65CC80B04039FB4291B8B5CDF42E7B9F156F3C2DC2F8E71B82832D16327DD5277031C91E3C56756D38528764328A9A6A4009033B436D24CAA14ED52B6898D466C3DF1FD23621842D7693DFA35D89B2DC441D1BD4D1AADCAD8DCECCC42394CF2977E383736177CA84A379C0E632BC3277E287F0B72C09A04264AAAD14599E0F6516C5FF6A4DA84FC9BA39CD172F3F5EEBFBC0EC8E7FC78AEC8416D01E3EC17A9A934549ED515DF1B520F18272C35567086888E9AB0B7CAD7DFF3F8171E2037444C5561636C6E6F7D9BA5AAB7BDC9E4E5F8F9031A2A363B49535F7377919CB1C0E1E3F4F7FCFD0412242947597A86B0B3CACCD80000000000000011283C49" - } - ] - }, - { - "tgId": 3, - "testType": "AFT", - "parameterSet": "ML-DSA-65", - "deterministic": true, - "tests": [ - { - "tcId": 21, - "deferred": false, - "sk": "3E935D3B7DB7EE991CE774FA5B93D9BE0D108BE397EE176568296EE7F28786007CAF1156280D770245611B2D346A65FFC735A3A2E15BB20C05143D9256691B2AB41D75A90BC5E8F3B30B6F5CD05FD18992924A5B59A65AF06C0F000E74A219DD3E7604B58331DB0A0AE901C29391794417DD110BC8AAF7F62CFEFB34E00E1D1273224608140352203374007875256171864715361476150443076135107682417565754553623586606381220842166273341313626571127738336004603326033470801750142613464376064342020345044224040084303114570820783867267616511300688505780160364878830103711055618008111745151375375768600743812137557362365733331614323120366135554251746566185186844142405008812716203287601083143716200564576635047520177022180063752520164642714415327778151052008642808573380026883457436064234122618236025563058541674201723048788640112813150654403774841424453305303221148753008688031332254082078242584840286177301607176788017121684433040173755555750683651813041566084354588662418642250064747473031812374021673282486827605038055324710254455817626100000230664826103172488176531134306846024723448311740230680042148850536837730552571345643370461544610780183773451078171180104582147807556873670047488518654385284874451381580620113757112803083074314684320237100037477766105712118241161456212245656034186154017004464176334326740402832764308766445851504060640576124400281353647323214821033857545523610774625068106122683180221678260362521201302863406712350682475271635857220571525343258836275054827741877621326432020580784710353875772868341878363051856158443044548840053168838728704486521268772477031031715632770125821827468281545148686412467356360106478786427517182848466386616460707311675654327102528646248552175050554380133130605483627138568443074022187057484232375461550120577463002814013083534021237475850308467047435262471236266305063408115274535542164420053544842843632328232763503405306865145032688402018882073027571768370605424427643718688264801531460682254320658441480417081480173221048303526715882527870543270488733275488344414828021760801815571212201813874340356543310486026422086826301213865460574551547165833464571331342333324361541770188154256776002570452822671053622286151572588871378618203862708670032872331727751130056133838855585607876011010676275632625203121158641326875854128131672382381020353185780015705112326025800226563074580444604700207600183643031776082661220866111632103107372146823046820244455412421580875043257154231387817356100882747432501152565307267161430120118507744308574866233700326827552338466067211465546257660701674221148284153310844242634735382144183225241003471575543715561843716168715856042071108301012801652345045255016735805665612203238088225555235253071116306808173433031610572882372184860154863135212681745772538311183131358541040558574735410488454426065881446470864680188026246287815664520033268207530852644720764714770741540141065754171222385408035558637684376620487744584745736533387425473434280735546766515087150306388383873763030720286231050777658256536078013373573731543008080540837532054265732725301403185681580340556182751534152216780045272761136256556858461150186753280004488820172321265430428278876741152805304254EF2D2B2351896FA881A5F6022A2BD420A3D39B3B3C4A138A6F299A621979031111515B402D9040361D5C6E2DB187204FADC47A8AF07382C437E85536EABD12B61F0E50679A42EB886FDD3ABF04BB7C16FE949AEB66B30B685A0CBECBA90EC1340CBB5FE2382A534BA58AFE4A8A293079D51D7EC7C9EC515697726C23AAB9815DAC184696FF52AE3C02FF716081FD07AB10B653C3D4B47C32BFB5392D0CD22D5B99264C5B58F65A5E52C8D799C17A0473A962A6842CFD255CEBC0F20E9ACD7EFBC8A7226EA998F014C3E71535A6D8ABBEA5E8487EF2A4516A4B8354B19C03B971230BFADAE6C80DD3D234564553E2493153FD09AAFB5F06DB57B388E000D149C8AE52CB42886141316AA57FBDCEB78F815E31630C8A557FC5F54CCE95E1CB5F25AE1B62D2A1F390444FCD77EB745785F5B36CBE1433E55521165BAC3B2B0046224EBAFB4C9E74E6343AD94AA37AE932BFC770803786687392B26CA7C47124E88B8B99713453FB22C210EB6EFABBF4F07D47C01543564F6D3C6233B913EC4553E8075C97A6DEE1CF8CFEA5C167DDA8258CA69FEEDD8D46C52F3A51055E890B2351CC3A1898CF6FDF51F85F01453E64B1E6CC83E28A6C22C8BED80FB7B4D27D475BA41B9DF56EFDF8FC4EDDCB453F65D836F3BC96E43F0AC0B5645B4F8D306D7272D54F86C90FBBE4CA897DF1F56748AE6D0B0DB3277A7385EE7561B570D270C9ACE06D2A0044BE7C8BD01F3CE08EC36561911F0155922432E9045486A602AA4F06A02C300F8A71504A134EAFFFC051F1D4D42D881E30FDD5DFAAFBF9E9BF745AE0F70FC26FD404FA797D9EAA76D9065C649785F5FBC134690C7D8BD6392D4EE99C488B9EE15DEF9227868A199EF358BF08EF8DDC5E45365217A4ADE0D36AF7B0D3D744C3EA3BB26B56B9CEB374710F758BC7AA68BB346EC2DB5B5E7FFDD5F0B4CE9F25F03E72A9E2F5DB15E3B4E922CE09A57E2580CBC287903703E165BD7F42D4274AAB820EB71E8420CD47F87624727E79AC507B093D22C9E6E761DF4A3082AECE1095D3A5F101EC019F2B84ACD4BDD1F5379CAC8D7B8808485C6ED1ACD5B1A245595108B4836004D6A6D61294C1C8EBAD65A0E742B98CCC7D1D2760536B6EBD19A88D17C3598E86E5A22C0EA07BE671DE3AEF096AAE6D3B71AADB38839ACFA559818EB43A3418576F3B42DCD0E128AA022234218E616169F0BA3847F0EF62FFF4EF7D4DE803682D40A5C3B7D8F4D5FA1444470F1B66DE187B50FE42698128AA93350C20E7D37F619537C220D78C5EBEF89CA0F11C7C7A93D83F28D83A17216ADC450E25F3EB00D9F365C9F5ED69DD08B68E0BC9780F34D150329E4906D30A04E47B6B6D508DF9A945ED83E39DBFF9B0C136486D01A91D11D37B5ADB8A23D305B70609F126588C8F77B6D0614DB5364CF36EBBE9AC59D4AFA18DF530AC5ED8B58D68D0CB7BF91D65B0F392AD4B408992549F8A8FBECAF25652F0F6C4AB6F32D5B147E8D85286EBF96A5D57B17A9899E854EB4544BFCE30362F7BBA0D2FE40102EDE08EE9F43D0709CFC89B8E33FD5F3815A771C56DB8D7C788C49EEFF53AABC5E341F184F92ADAA225122D2D95E3BF03A27DA0C104C6F44A3E6EAC0CBC2F2066D17AA74A584644EAE6E2B69C32EA116C91D8D6D59C9744FC22D38EE5CFD0910DD305788BCA661463AF04090B57215E702850E85AA1C66075B15B9C9D6E9325A634CB04A6C7271CEFD9DEFDA2D4292EF1535998E5A6E65C4E51DB49E27FE2986AF02F4BEAFBE174BD75E8998651E610958188820845AAEB239D2D152B2C2597D04D7614A4439F6048D2B361FD9C558F40CE0D2D86D7F76846EB81DFB4E833127C87095DC2AAD0D7CA4FFD189C5E24A0F9CDAD4A5598F3273514703ADB5D12E7966E51A856A688CB6E25CF8C724BD9EDDCF555B90C65E28E07022BDB2D7569CC46DF613EA1E7FC1D88B02594A464387DAEBD0462A5F9C8BB46D525F9BF8B3AF7FC0D0B84DF55B2AF9E3E82A1305726B1C6D60396FD086B01BE69F91C752C5D0A587540C919FA8EAE2F5D3D72A14AE9D5E0B4DD4C8EE8084342033C93A86052ADE3A2A68E4C7B5DD599C568C9935BE59AB38ABE3556FE81306358D5F13C1C50C8E5D32F230242CF52E30C43D88C50FA030CA5FDFA88DA869F31B29A95299ECE1E4CE8575B6A633120EA76B43F30E9517728708DE1E73A27699D451C143DBF335684A643F544756B94C546593972C3543EC65EF687CA3F07302E675FE0065C1526D1353D027778E2BD04EEA31D4009701AE7B2241E32E1F9427BF820CF55A465248993114A7145615384CFB4A237C0C37F5C2C1B3AF7A62867F0DA8E4614DE7BFF6F00034AE628E64DB9FD96528A788D98FBE61211D1F22E37B978873EE78A6E871C52653D1EE0E0174699FF71B0788E7561931AA70939FE1D585D733509303507801B87189CA17BA3060A4BE85F9ABE6CCE142F8E16451EB3C51A4333827641A9361BF679E665F0E0E11F657AB9277D5E3A9EBB8DA33BCA8D37259166DC8C68A7A692B570883276450A56D984B774A10AF0BA766971DB3755AB5EDE5BB8CD6292555208B37872EFA2E7E42746576F725CA9E9FF5A6903945CB08E715D4BF468AB847210E30CD8B289D2FB745726D76A5802A4C74DF544E835D61DFEF680846EBC5F715F071FA0CF2BC3AD0B0F016C9A67162B4F926C32EA6DC7C548E859B72AB73C7A29C4F06D609C3284C784E40CD460EC149BDC17E614603F26BEB2E8AE8A0CE21E00EA3D18CE1865BE6EB0B9E9C79C170049492418CE009BAFBACD4B8AE55537D8CD8839EB42FA6921282B32EFD2A76B1A965DE1BE3CB0001069D4D80D6715F8E173BC8BB972F23020E0BA2DDF3A2D390F11F1F5BE9F6134F4276CF63C5DD6A154E133D9E1126FE55C5113F5E3485AD051B4C613E32AD3BC0793B0D955FEE79B1392AE2EDF048753BAF82EB4B739746C075CF84729A90EF60685C3F7833BB0D00895924E5A8BCBCB7BAF41C78C3705C48C28559968C947BC6FBA0E9640F8845A45C5AAA018842FCA46A25D68DCCBDE8BADEBA341F8969A3C83337EF3A6383CFA4CF9B093F7C81CD8947059CC6DB350BE20E8080A32C356BB813A714557AE66E6DF110AFFB7B11D95A82F4714D09C945554DCEE53B3A06F0860BE89E7B19459CD061154B9F86ED770AC271D7272A8D0F40BAC2BE0F95064DF20246FF3AAF3100DAA75F68CAA6C532E1181D670D94A68639A4557D5FA10AB8A016EBB94B3B367058AF40541FEF88F497EDA040B6D927A3C1F034D6C2472F8A90EACAFB61242E96FFA47D1598D6107C1B4B6703E83067A817EFA9640A6A1277E59FDAD28DEB29A70E31EC82BFDDF96DFBF7756FB6D8368F9E340065997B55B00B22057E7014CA555FBE5563EEEDD4B039835F60F753E9810B5410ADF699515080104AEC812C3EC299928C66C498B0E26B1719C690BF5A42415A6F63A9278DFA430380A821BAD0A2F8377235A260A0BC9B33E49FB980EFD770BA97FFE16183D6B1C24D0D1C3F437A1", - "message": "E3D54DBA675DE7530D3854C8CDBD581C6E392F69CF9793D8C0BBAFEE7334C5878BF13B3BDCF1D993A47A7E8EDD4B6C3EC915A5E8FBF2071F112AAC41F08CCD8CC731143AFC223213212A5BD6B6A4026CFC9F7A41C08CB99F2B375D0E04FBBE00503533DFB869DE43566574B49232566E38B13CAF8C1EC1FA11CCA3DB66887996DFEE090D133B1D394F075F8286CA6CCE13C3977D929DEF5943461BD5A22D4BB5E8FB7EFE016932D02ECF4D7B7705412CA14508B13E61925EEC0B77460C4C089C83D687C8F70D141C75D6DF24FCDB64BB8C2721AAC9CE8C6FC4750C1686A7A70DF34957DCC0CE53C3F0D280CBD056D4F921FDEDB35AFCE5DBB348964AD105EEF5A1B07BD0D586B87ADA7CA7AFA93FB75AC0DE1C749C48BD6F192D6279482D3F9781290B88B095D73E728AFC186BFF0816C1DE78119D701FAD382C65ACC42B04D69412AEB255793839EFB9E5BBF6F69B7FDA27A44C04D3AA2FDC6101E9CEC6F75745F20E077EE23D652B7DE547A0FB0E3A153473BC824AC8A31A2C9493DE64B6D40185B60431B1B34EE32797CC77C45C71F4E04E849BF8DDFCF640B83130208DC2495C0CFC6C031B63B80FB45F47BFE3D25EC5B36C2700300D8223074C156C5D9887DE8C5A97BA36A84D7585CC065F20FE8DCE9E8EB814A1D5B7A3B7A3AB68D93EDBBBBF67BD70A0FC536C81C8D6E8B139C6B3B5EEAA3953464549CB38B78A15CE3D5BB4B798E6B142BC48C70C5BE61F82DB6E2EC03616999073574E6FB35D441B78DCAFF56B8CA8F473EC0543C9C69E93B97F95FCA58DAAED511F4440DB252EC18C90D2F97AD901716AD34EE103EAB0B7982994E21ED1AC4BD62ACE6DFE12C8C2CD092E7A7E37BD4E61B4CD51D980171F8D4253A4E7FCCABA0A513038276325372527621B0A3DFAECCD7CDFE98CB79C0662F5D0234AEEE9302438B778238BCA409D5908768779155D659E92D12CEEF3C2C954C3F1A4C2912E9EE994209B608A604D0CD87F79665A25E774E6DC1D8819B85852D9ADEB174C75D982DCE29FFDD24B7AAF5946A74C14A301AE09F1386AB17ACC341D6DAC040FA6527FCB8E095CD4F1651E47CE02E6ED76C085B2FABE9FF5A510E63E73EE386AC17D5C2C94C2D528B3A9C8902D10C1610BA70BA616C58D037F148E6332107DB9F64C579064F19481669C7888C21F0A3374194FF1A72FB6180DC01D29443BC52C318AB03843357A5A98B3D5CDDE9BC49D3ED29EF73CAF44A7849AC6DF4B2D353B6A562386BD480512108CA0ECD63BB3D3A0695679762F8254116D8049488BE6389FAC08916E6407944B1526BF03551504E40E6A3266D4E773E892EAC4DD5128374BA341EB4097E20A9BBD4E5EA26BE6FC325D9B71C232DCE1974928516EA2519974C82AEA5247627F802C6442B67FBC10E359672EEB9DFF768E9333A2166336FF0004DE5E7BCA55998C860FC1A86B75CBEB3FB5A5A2519D5227A6B5A7E0EE058FEE0CAE2B4AA75099FF098089F0261C443B13911CF3250CAE2F2906CB6454A20D0FFFE8C5AFB1DE7C5BA8CAAE00CD7C2D7219FC83FB158FD6D15EDC2924AB41C9B881566C538F5E38978C3182FBDD0C0C532A77A61E5B8E666B3C540DE976098D2BC68C0CDACF57E9BF1BDE8A7BFB13256BC69F2E386D8F458D303BAB781E537517AD7D0F0378D2F258B013AEA01C97A7E8CD2C3DEB203AA8D59084ACC2B09AD3C97EA613A2FBF297038B4E721665D512DDFE5C13F11DF4BDC0200BF610D57EA7232914752F75A544E01D5AE0DEFBC9E18695824058BDFCDDF4D5884840D2B55D6C2D6EDF475CA75F3EB4D0EDFAE99349684BC9C533EAD591085BD1D6D4E4F9B00A54C97244322D505AB52B2D4E0438C6AC5D2C3983BFB2359FB21174AC02156AE11EF233AF40A695854C84E620754419CF7ED9EA4FDACEFC8879B2EBC7B29CDF9C4CA2921E084486477C1452BC3BAF529DD92748E2B1B684B1103CF4C6EE11999E4121CFC7E2F3F6C7BB9C055F800DC46D78D9D94C3B20BD1B697411FF0B41E38173D2C9FF1CCA77B27384026ED2EE25223B0007D2930D700A20EC9159A66A4BBE0BD84DA52F006D7FAC6D59AB2BDE08FBCEB76A57FFEF59C077F9008A4A231FCC302E4DDAE9F3DAA55707C1EDCDE8042176DC7DC6377BEC58B236990AA6C5876D5A27942FFF7FD74B7DA1D2EC470CF71103A64FD2917AF4C45D4C59C13F58472AF408F9C5F907C7C6AE0F402B404AA40CF8D962EDEF7B7654EC8E36C645855BBECC1337EC18F0EA65933F4D07CEE15294139F479A16133D2BF412B5E46D5B06FB170F0C93DFB8AC3F7478002CA76B67A272A3224C8172CDD8A616A4C52F5FDE946CF5733583C53835EBC90DE3ECE34299D7E5434BF072F08A44905818EE9708815CED10E9043E88B6EF12BE72FC1169FF2F925C38E03B827CDE77740C7C2848AA3B09F555E2712B341E248772EFCF01B99CD5403642448B5243F35A3073A6DA7685AD42FECB05D46FC99F7D6B8EC56F39A7E7B3579FCD587E07C05BB7E1F5D49B9015375E09A9A14F2CDF049AC392139EAA3C2547426B8CBC0C4BA76C55014FCD3940FEA2631A75CD2FF5C22B8A65C9AF2DB1B831C30EDC8EB79B797E76D045EF0B8EFF8D41404F626DE8551FFA445885CA1E3C9BF05B5C39CD40E3B37CE3B58514BC70E2EA94CD694CA88C1F47AACF9B4FF6622C555AAB7C71EA210FAA9C0BF9089DC9C9DFA77C2C4A92F59BD7CD24EF4F8D5088DDBE22DE854F8966C017FB414464ED6B991E289F7E3FEA783831CCFB51E227A6DD4F5EF50963E80847FA6B350A2DCDA3C875D176342ED73BB42B416E58D1612C4D066F1207B6E16A955DCD557A9EA37A9F24CCB20E74AC4D6166ACEBCD7D651450E5D4AEA86DC89528DFEBE07B39A160160FEBBEE5B11122B4177FD04B0A49803E498F1BFFBA898BE3B26320966165E136F7F517FEA35EDF01D36831F9AB478CFF8241E01AD7570C26EA62439013F61D48797B92964903802AAAF356C6AF7645F5F4338C7EAD5AB2898C600123888AF42A2FE06FF03D81320FC08E7589E19887EC86CC1B08204C29E86CCF187B1240B81F7D375F3762CBC10F3BADCAD7431E59A4DC136440AA72628E17D2BCFF916DBC8A66B8A83A3C6400EA0CC57A82DB41BB28CEA9E9CECA1ED826719B9B62B6CED5B52FA518FE47274DC6E22E5F8398D42AB23572CD6623EC307FB7EF61892AE3196C48125605F4F09B9C0F0DBBFB9D9015D325C546CF3B1DC886AB0DEFE2C35CD39E2AFD13AEA74F787B410883EB72DB8CA7D225E6FE8143695BC0FE556C6CDDA493F92ED62A38E8F90CC4C713A4798984007A5CBF68F0CDCC01274C96A15C3C4355ADFC75F7DB0603918ED6CB4E4491A8569FB1A9AF32528F6E26B2303C7987E39015573521E024B2230BF1BB803BF2B358880F2840CC58ACE31E551C8E2A0F8349570741F8E93066C8F17608DE35AEC342415A4BFDD13A9757501F5246ECA49913D0F02EFF35F4B3D40DF97A64B0FD02709C0832C423543A850776ED9C0574C26CDAB8DB371F5F4B731E6F510BC09FCE3DBB58BBAE1074CCAC284D5F8068D2435E053A037E3ABDC957B74339EF0063D367F7556E49D2C7A7DE3616F5E8B703B7585F526E9306C59329A18E76B85303C31E3616831F2AA2B173CD0A43CDE76AE52EFB8CF3C381097D7A7598EC833A75E97AE4DD539C31B3E45216EF9C844008C28D12B12D3C7EA7FB89B3B5D20EF5C7636A8E83D6A9F8F7DF29C9716B7D92313048A7E14B9EDF77FEBA874B9410DCAEC4816D2FB57050696F5D4F0DB47C6183D447C5AFBCB948D09944F4271368542E377DEECD006779F6F7649B946E79BBF2E19AB4E93F142BB24E6D962F6648CD0BF1BE876F6F431E883105C3E86B973E30735A6FE17346ECBEED5D101EF0AAFBBB4C072BADAA2F4D517C272F2BD2190F5F8C87D961041A121D6B319EBC959AB0603096017BF7CBB74DBC74FB866358EF8C1AA5B9A10B2C524E822278627C0AC577AE9383C2A529054528E58D56699540E4931BC65A125EF4B459A7A5FC10E0324ACB641BA33C83A7E100CB00FFE0ABF6281F8942AE5490DCCA37BF464D0B061028E46E025FBD5F6DD6CA1BEBEE282B749FF5B002210916B9CDC4D903A95972FCECB9292A554AEBD821AB4CC50D5EA0A33A699FBF07F2CA520FC44D4A9581182290294A8FCC66DE3FB5B7F5EC5B267D1A0E6F84C27C02253649F5903389A0901797A7EC8B78AF12BF2B1CC22D291347A0F8D6EB2698AFCA7CB4C23EDF250A5B77E51EFFA3C675F1FA951D72467EDAF987D5B63DE4177535974BB2006AA9A8DD9E624108229B1C5735BB039CCE47162EB52DE88703A8BDB8ED409BC01DABADFD31EBB95CAD9026705DBAE5A2D06376320BCFAC17A7DAC957BFEE98480C7A111B5ED300447A21FE62448F62CCFF7DA68689A73A2EC70BD13130337EABF26A00BF86E52077EA00DA46FE7323780CF98B3E998BB30C3998017F4BEA455568FCD567086EC68ABC40113DB474C6C88B1C1C7588E7A8C8D2082D4C70DCB8FC3D8FBAC53CAE95286F13254253861567E4715B03E682E422C111169D96359EE18265C3CADBAB3AE61F03F86D096ADAE9A6C4820EBE3B61015995707695B42B67802FAC2D6FBB2B67801A3E48843EB83288AB52C29C1F112F9233860612BA015D4B7CABC19C6294F8871E2ECF6AF334DF9C8330971277E32CF1488F04B4B285AEEAA83BB81D54B6B8426439804B027822373AB99868EC068735C816521BD75DC19F79D2E2166B1A551C998318FE19F5079BAADB12732528BC8B522438AAD252C57D3899400913CD124D2DBE90A891D95900C0256D9DDBF939BADCF6E37E6783DA2A2BAAD872F6C8C11878ED6D5EE2988135A39F2DAC7CF127100C36D2D4E58B3A9B1D7341120FFCA0EED2E98E020A46F1AECBC809A21EF79E6DBCE76F96B6930107F078A5D4464CFEAC414CA41A5EE4F87CCD8868E7922A14C247885F0DA9E23A7604EDE703C2BE3633AF9CCC32B9E5F51CF51978F10A06F5D77C67927D80AE480E7E5E005401ED95467972ED87029029DA05DFBCF2F0B9D50441E8F15804B0A59D23CFC2E3C0FBFCB10B69AADF0B37C06DBF972E264C6CDE4142C04FFD9FA0AF2451F8BEC3FDE9723306085ECEFB17C591E691F9B4D4F796E293C0CD322F02B96938A5F7D1C8A7FEB94C031DE24E71020FF37E00590AE7CA48CA876AFCA2BE3723EAAD40FD27B90FE6EA039C9F3F6069FDBC70F16626A41678A31E8AD88DE9BCE8A25D43B86EBF80E5E426FE21606E67545FF8E55FA7D9802D65AFBDA79EF40DE924FD0DA7B5C8F6A2CF993FA6D27B2861C629CC9BD2E1E6AF04F88065614F7E24CDD19C88CF2D7D2B93B7408D898525E5141FF71D18DABAC186DCD432F3895A1027C92CF8613C80BD46E4758CA26C8CD92B74EEBC5FA5EDF9C9FEC54FEAC40F0944E3FA165E515A03DB57C205D383C04B2CBFF703939EF321DF8A49BC3F5B1409EA491062B7B9982277825B52C6CC8313BA05ABFFCDFA525445B1CFF773D28536A989D257967B50D7BEC4FDE5F338D2AE81BC8EC592BE93BDA0A7DD089057E675674E8B997B05D049CA3DBD60B7F3FB23BA5F4E5A48ED8535234E5C66C41B157C25B5D9EF5C8C0ED016D6B217F4B60BFD0DA223A5D40C2A403DE8268AD5E6207C54B217C2F009C5DD052266722DC21D4AD8314DE498692E3C77C9F8226A14F27D49E0DA1101E32E5B86BC0F0348A20A360A919EC863695D2EC318A61F654C9A1526AF1538F928DB76F9B14EF598F2551EE85D6E0429192C5F18D339DD5A280DD5B1A8F59EC1F2947996C7E190C87502FDF5004772224BBD1C4DD62A8DA1723EDB41176A9AF04B1F30D09050E73579364360DB4F98034FEC1B43E6E9E0226409E6AF1609FEB862D845994BC20E67010237B74DF1AB59EDF14B1623FDC990B87B929FB7E837B1ED905286A886F59B023F40B07A989EF7A99E974EBAEC49B45FEE1F405D11A641B2B150EBE854F7853F06026CB1287FD8BCEFB15D2AEA623D7C3ADAA00B35A105ABF2D8F9715BE65AFCC1381D29C5EF398F2B76FE1651348BAAC147CFAFF34778242B32A1620E0332EEC7AF5E750DFEC30A899452ADC530DD933A07748DD522AC20AE2B2889FAC3237D23C4472FC8C6B236D4A4D19F67264F54BB9B25318156B30EDF273BBF3598AF5B34BAD41585982F6039F6E488308B47EAEA5D21A91E5838F7D9CCC8F726EB2DB82D022BAF103AB2DD444489B94E8DDBA71E62AB6251DD5D5F69E44F377674A5C2B032150C32664C96C072867BB7A2DC29033E6BCCAEDDEA430E5E155DD0724FCBC0415B2AB6DFE68A2E59403B206BBE7F421FAAC53F66040C5CCCEB19F17BF000AEA7E775211E48AE04AB32B2EA470FF97707D9C073FE72A7B77D49FF8DEA36610C2A83306435861BE01DC4B20DBB8AA6CB780328DCFC2A32D74CABA83929CBC85E406E74EEDB727A2FB5BD9D304AF46225832858B295A17B9E710BD7B0B5D19DBBF4FD021EAF29F4D1B6BD7E78C8A3E3235B5D0BC687BD5B428D2318CF4330EC343566D42D17BE838EEEDF70F1E409C189DB1AE0A205D222C92A1ADD33B8E3B126AF62818A2DBE3E3C001098A986865C6B57D0B2F5579B97B6F101EB56FA839F8789F6774074185A8E0F383E9D8813CA1670D8B7586A3A1C27A3F5A3874C4E743EAE21BC519DCC430E281D2F73C23BAB948938A46FC24DA94647150DB72783AB3FAC01D834A8544F144779A51480643CB1ACCA0BF88D203F865664A5ECE18A88CE31B0D8FEEC585F9531329002D4FFABED01EF42AF52DDF08400C58D07E98046D77C7A142B513DA0EE795DD57EA43F4CE36C8F6D2862044945DC293C8D47D9F207B0344220E3177D6E17A4B39B22CCAE3C53D4E0DC87F70CBE9BF743CEACB8932DF8F84A527C9FB84C6CF5206EC2E43D1FF8E846DA06EBFFFB87BEC09C63E9633713768060ECA6259AAFE7C787F3947D5B94A6B80FF0A7A4785836F9A1396833347C13034040D1C6B1F83782AA6458328160FA04971DE04A16B6C031B2571DD131912CDF2515DD56983ED6EF3BBE5B3989E951BF0B99C5605C38181E96690487E87240059DE21BD220059E5D7E3C832FD4569BB7DF06437197CAC141E8FE5B369B542CBEED2F9025A030C54F0B5D2B1E79011CF2A0A0DB14312E352D07BC03E654AABAA95AFD30F1483B57BB1A74A0CDF8C9FDEBE4B0E156FE86BB1E21D861F8EBE0C4AB2B23E776EC01A281F6DA9BEC4C560668B4EEC71856E6CC41741DF2EBBD4E95B661EC24FE31B1DAABC9373CCBC82F3C13C31E478097259850221928C7AC6BB933A5631C896ACA87FB6F5E3EEF36EF5B9CE59F5676813A1A7E768FC9B8AD4A0A072672BA23CC21B21A95C9BBB1A40FDFEBD2D611B773DFA55F87E9AB1CE51CC42B0FE2FE15DA2D73F656CA56279AA16722ABAED5727519EA258794503F1808E4EBF056530B318B99A74886D05D042DF4D829C425C908B58162EE30A073D4BB7D27275B548E7A90E6D178DD27F67CD955270825FB96300C4645E4CD9C175C1185707D4D365955FCFD245A55D64EFB66308A47FC85592BFB755EB4AA8B78B541274E2C225DAD649C248E7F2792A56BFBEF704551588460B192DAFB9BF6798B7D4CECFA424AEAD675DCA081E60BBED670F9AB2316F5012E2290770D3323403DA5748BE6681565A713873A5386A6F1299F0E1EDB341FFF08325510A7F2FE5EB0302727D7355EE48ED5DF4316FD34833238690B91D47165CD4CC0454DA33B87569D38880AD92A92ABA0F24D99ED4CC977A2B4E37954FBE9B9320101C80A858122793062C7AC26E71BE2608DBD2A97CF4E884FD3255D008700FF3531C045750B2EAF7730BC9A51C675D94179DCFCE9EE63C1473D15B4319AA9EDFD19739CC05C5C3C8AA618FA9096C6648756F8AA74FD18A8CD81A2D248B856902B4D30182BFC2F392450F902973043EA0F5E6C872AD43A2D319F99F095808D83A8B02BD380D6C3F3DD227EAE2B4A4867713853D63CFF405621B1EEEEF00D5BA2FF254CDF97B4226334A9866A2B5BDF1F8E8AFDF1238DA9F48FC388A339F79D648CAA0A0A69D6F16E297663E5F4CF1AA95427E68D71E74C0A2FB6B689224BD9978F7A3A4505334774176FD87097D8AB454CABEE138F2CDFC6EF0F3DB14B09DD02E7FABE9F156654433B75B951AE3C196D670192004DC1924D1950AC597682EAD1C087ACB1461247DFAB3CD42279F9169B69B33435DB9D8994AC04B15D45007F0F98334AC5D783219B376D9ED7553F52CBADF159F69282050A4C843467AE7E4C4A142A61CCC4C48DC3AAC6B8E0A8D618E06C60DC924A943AF9000F896446CB62EF4E47AD6D1FBE2B8984A48ACD7C0519D6E87A33106E9A91C298808BF04E1267349334E6C2AC015A9F704B2DDB56D27A8B00D876AD00F62434095A6F7A5E9CD4B27FE09FF69019AE5F27330792CF9A1C07FBE98D23C4E615332A77DB5B6182D277DDFD7572DA75748DFB3B9315294EABE4B6D0FC3114B2AFF5537A6B05A7AA9ABB4930E17B7FD3D8F81AA2D674DB69AD967C8306FC3E1CA8BF78F446B26D8F2FD1AF6F7FD7E52867BCCC3B4DBD7227EA992DD995D77C4A2BC808C7A3E68FA433675F489BC503DB70115A824669E4B1861CDBD557A1F78F1A4B3582B2553AC23F12A4326EF943C56F847B8C679695614BBB1DDEA9CFB7D799CE42DF8B735FEB9DC119DBCA306DA4FA84A50F79905E5C2AC1F61241D88359EE6F62DC9D3E4A1593F41CC5F3C02241CE5EB62C28A547FCAADF1DD688F3DFBA870D9BED723B02B0B1CDB4C08D093C48977E0621930A668A5CD517A0EFFBE248B4AACF3009BAC0D47F49378F30A3D2C2800CD16B3C9464563DA4A7321082FAE95DE5645FCCBC5569E942B5F860A32F04082723E9E53F2D18099BEC5E23A916354198325FA8DAEAA3F6B7AB6AAD6EF12A03CBDC27B83C818F44", - "signature": "80A3AA584B532C5098947755BF88B40612446DC7D4CCA500DF34D9A91804FED988A4EC0F7124A5C42B7298D1784A5F6D364F7445E5F9090C0CA2C84902722A800B930AC58C45A46066A0D613DA411DF5511A5401183E2EB6B6C63486D3E2976D77D3319CAD88F01EC4429BB8C69036CF1BD891DAA369DCB525D33E9803485F666532CA7CA8321F983525E52AD2A3E363E30C7D7AC7ACC1F9A7EAEB76B7290B2DEE7C681C125AC33E9EB2B8EE080EFF7E8D3751E3C35FDB2CF58C2C9BF83DA0756A75BD92FDADF3E9F3E1637503C923802D7843787A6D947BAEB26FE64D0FCB52C2C29DDDCFAF2BFB4968E5938155F652145D00B410CAD920BCF74059908DFC0916637EE248E63C3EA0CDFBFE1B28388357206C6DBB8C0D9A23942938EB523A51774245567BE82401E8877048243D343E0D1F3F4503F8A4BE59BAAD3E76B7E2D1C2CB4234B62BAAA10642B903F5A644DF2B37E740DE63C82617C405B563BEE0008F70A33A59BCF17A38B0170F736D3D617469D39CC99E3FE9A49B94DD5E1ACD03877081658F4D0300CBD5E50B0AB094E4502BEEBBE4840CD5DE6FCB891203117980FFB033474E88AA07ED44A306115FB08440212D943C6E8896370D8FF97DD4E29ED631F05CD72B343698B8078DBA5523E471F20F4EE58ECDC30E3D4E0F0E130378B42E5521AE16088C18874703CB8A38D382FC89957F592C051749FAE68C14EA0B6E11677D65D7AFEA3516AB9B75D5F464B8E119E97ADC22CFC48729DFD3881AC6422A11E0FD883F44FDA7A7370F85FB80EED1A4D35AFD4597C173186BE56C94F275E4F2AAEA096AE8FFB8E5499DFF2A00AFAD19B40A0EE428EDBB3B64F34C4ED401BA5772D647DD20E4BCB393D053DFC6CBABE37D7544727DCD40A42E83AECC1BD8718D7B2F0A8B5E3E98A568F055A6EFD74E8D81851D745634AD5F7FFF96A5C832859F92A92E70249F38052CBAC2BE7DDD217786D5FEB80152DB1210421D53569B07346AFF582129AF9E35DE9C3A4CF2FBA7B6EFC9552503EA94A722F6F9A84E190C422883C71D60F4059F912CC773AEA6C52B2C5CDB496B056697F38F4EA2BEE6D5150E92650631DC3C35B7DDC063643F65726964575D34E0FBDBC3B144A829674BC26A21C3D7D873F70BFD2BE1F71D5BA2593C221DBD6A245045256738EE39251B1F433F4C8E0C1AEAC740952A677F72D11A0437A64188A5A8CE69A4BD56D98021B3DB19481D606BAA7263EC0ED9529B242A366B76C5EAC589BE4A3EE50B0A49852641F9102E2F63D75FE2C295D2CFF1554C77C742979F1DB719FD14D1FDD0303F5FBD3C96763CE56563D05EFF726FC1BDCC4C71257A8920A8D5777DEF74D2E175A7A2541AFCDB51249EE6010F19C9D428C774ECC455D23F7EB770B8F2AA09EB278A55AF0BE2EEF172FA12365E0D539C60FD5A5EDA381620C1775EB2F47146F1E2C5B854023C8711DDA05FF78E393D1273641CE6DA638006650439C5F32A45BE179B4CA0C4DA02D908BFAC72E47CE4A2E277991EFBDCF86BF28456A6FE93E671884EE309DDF746194369B49F76476830B242DCABB07203AC83CFF067ED83B74D201DFC633F63BB2039C82785C3A80AA6E79D303F02D134B141156C5ADC941F477E955C83B2EC1938DD6E491C1D5EB0E262F62589DB9F9BBB14856AB4AD10D450923ABE90E53D64667D87046B81CA2674A266A4F43C35A5DD0C8CA7BF90D9B8E7700970FED98BFC65D22F1D1AE7DA37709E291EDEBCE413A636FFD8FBC55D921E2C043401D68E837049C4469CB7542A3A4E3CAD8272301CF07EA827C7FC18766D43D5DE67C32CD0710963188A744B70D3EAB6950687EE42A9FBAD7FB7F1ABF8A623E0846CB9D3BF8FFE2C5B1D650E3086C809B08A01E0AB08AAD8808320B2E43F4EC80D71C1B1A9935C6755349AA3E723324FF334BB9BD2D6DEED275A1F779227BE29CF8D6302DE79776B2B59BC42837EBF82CFE344AEB2CCDBBCE412258ED39C321BF78E4D7F1350AD7070892C47A656A9579015FBC1EE340502E6592D0078293C79BF17F189F8D46AABE90C54FCBF3651A43B99A004D1FA260D7758413015EC3406B8D7E5C8A3C0D110F79A883CC13C2FE40047095A1E5D0DBF136A2D33FC04D1D5F7ABAC0D43FC083F87CEF760B4A278D90E1D5FE74E999A1A58BCE582B22807502A3135700688F8628FD12AE152A506038462F6A8B45E5CCB4440577374CB6032B75E9B92B8A4FBD2D080E2DBE7EF640370AAEDC4C75829201E17797A25EA8ECF81057F3F3BF50227ACA6B4039378BA480A07085598F249C890831A4A44A5D24AA33009A0DBBBFA5CE269F345876C7FF4B55D5ACA860DA86FFDE4EE9966C44A18A5C3A1FDAEEBE3BD0B3B9C2D92041BEE72990348993491C73BB4A813295422B4129595B359B3194010DF21F4D3FAD2CFEF725BD089AD68A2001B29D6DE815B9519850C99C5F0C8FF573B2553A4330DAF4CA5D4E98804EFD6B0D4642FE94D5835CEE0987209218E37921DEE6828F29C730AD5338B2C8550FED699D266E99651ABACA63DEACA113EF34378654EEE36D53846E5BC40C189073E85DF689612AC27215C7FF655F23273FA860CFDB866B7A40AC33A28A261BFF4434C3490292DBFE7DD54F54950ED3BAE86FB6C7B05AC2DB2D26946D0285BC571F4BADBC7944B9DC667133CD308B034B24BB5177306B73DBD7D506225ADBC8B12427E691F63D4DE76EA4C54434A57FE92FDAF6249D355D5E6F303BE70BC850520314755BC500E9C1AF6186FAC1522CF527158C491371D7596C3743A94E8ACA236600D6682EC7ACB87BEF47078722D8B7AC7EA48EEE37007E766214C0C27E97DA933913D33A02C522B26800C113336312D86E0FF38A67B09B344205062FBBF576532D22F027B79FE5CFCC50C3CE52CB6632190AF1406AC18C21183D61569E14981312744C15207124F410E8B769AE628CAFACF5CFA53421AC5E0F426D62A9BBCB8E275573941F876522085775C8B03CDCD3D67CBB50F4EFEDEC473DF28D2D881AE8CE3C1BF09F2CE9188035948C4A3693A05AFD3374EE58EAEDEFD90CD8C4FF0AE325AD8E78C38EA6EBF95D61CF46203DB6455176647D1A12CB7D7423E3871F42A8B13B1BB9C2C2D10FEC92C3F9E0B792C837C07C10AB815A359679DD22584E4EF1BE4C1DCB918A9B130C9A5E6023E6763FB8938D511DE761B7A4236015422D30C64BE39079EB5C66FD3E0BA97FE1FBB0F9F61CE878052C90435307112A2F83790DDD3C2A420ACB56C8E0D76753E3FEE5D73DFE901935A2313DCAC424200606E704F305E124A28FBC0E30E38AAF3F2ED11E27532C15664376741F70F59830D1ADBB56042F8C87DC2C989FBA6CD94AB7543D0EA696F74D1421F489F070C9A2C793CF48DB7BA4FC951CB47272E450017E3849BFF1308D3CF74D9515C04E889E424CF87D0B368DE99D9C31AA1A217DE12292040ABDF61AD972729B6B1892F72AA71A1803905B75CC61C87775BC4C721D94AD74E9916BE5758BAD7CB947CC9E250B42C9525829F070B0B0DF812B89A88ECB874E0C81F7B1FA95FDACF77C916CF8E72ECF00C319BF4093EB114465B321FD086B79832AB16F83E7253B031531288F70D94BD5C9531DB6AFD125A736B66EA40EDF68D020B49D2763B016B328D8959B08370C37CBCAAC5B12297C1F3320DD9885718B4B00DD6B10E2652A69360FC719B55723DBFA38749CFAFB440265DB48F5DA31A056A59428D3284F600E9CD497B1378451569BA3F8F1D32091642E65BB229A0E676E3A80B1E18C3A36C4D17F9901909DB8E5E2203E7DF5E02F152B1D302C31C91D8ECC3E13FBF864FADBA37AA645338597001F55C638E668A6E36794E83247DA88C84441EE126E43DEE6F3F1F201738E25E859118050647BEF46D042E14DBE46E2B189CA03245A7848FE104B08468220278E230FA454EF065BCB26CFB93B19B3B35A2C1D69E301300F50DFA168C54BCBF8673B63A7DC6AD7F56D33CACA83C1C77678777BC6239632917ADB4000D229E0ACBE4A8A243E6C57ADD4C728527A7051DFA5FC4B995A3FE3F3A6E5BB9A9D6FBEEE21CB1DFAD333F6C958C675126667F0C1CED9739F2499E79AEAEDA15DBA5C8C31986564E962FCF789608949F7FF91AD70B3431CB86D7F1A3E129BCEEA58BF56C5815C9E44B60DBF7D104B8C5D85CF05BFFD603A2F20843987A1A5B34B1182A014C5AA7F5EEF615F677AE07FD093E77CA4DE721B67760306C7565D5C764D2673E02B266921647BB5D16AC34644183BA29F3DEB5D494D063A41E7615F8DE9D8F300FFBC156B69D375D8C3881F873A98EA7F8759D5B287927D5F3EEE9A242831B7342CD495FAC2E76F25426D24BEE831557B622A3F7DA57759CB2DC91D107053CF2C3D81BF1F85D75FA9B8E6ABEBF976F9ADD4BB7F788F8592300F36AFBF1800DEC01FD44BE822CD2071E328C1F0E23F460EDF2ED9A6E6B68CBBC011A86439D8D110F56C57EF270D25C5B588BAF25684BF68CC02827A927F9902283D3F76DBF53E864C7B9E44A193D119B563385A603C3E89A3ADCC9B7B9257EA51F697E14F708419E3CAF455385585E461FBDC32C921D47BB7DC8991D01062E833A41535A6978A3E016585FA9C6E248676A7BB5BAD5070D149BC3C9DD1A5C5DB200000000000000000000000000000000000000040C12192024" - }, - { - "tcId": 22, - "deferred": false, - "sk": "F392F98C9CDF8480C41F34A3BA6EECDAB55B7A7413B28B05B6D8DA29B455DA20C13C7ADADE697C19BD95F4181D9BB87ABC896C07446CC52B62F7C2883B3CCC61927D373DA98BB6B1463FCBDBC7C3A676D25788AB26706412FD08C05B130F826130DC142EBFDD884EB8FADE304455EE978A72A3A123A69246EA506F92140A8AAC301826517220457575500718444602606702737036246348057773753653026737530327720617356636110021487182406485883783500307652062837008037623504275143575413277805241337630721014485311207126464251365722038703047777860484650222507051720537247120624820142650776607686280727735633154433151782223422704163680716278603431812174820280568464342510822713206812416037802546378526410045560675630237304285416623454261283085572045668858060866837604282874804876254654326261578215675122020866578445072761231803362336526243078878567202715767743383861568417748622625301333140772280730350454860126812584207355072774075606603733422242068425724752175886643765751536756230433665412301147080035348337144751803325188375752442131056834846104747661738815140077787317821773203565820682216027654224806146185675613323671341833128465031767087642306567758113743515665083376682071584772645080206870431383757154651308356136765831320760126350481621267663254431456810768528220808107371083873767157585238851353083212225832367378252330145547815686824158782844746478735016774465466740401333310057727005121237645614476264226362084266800020031025007113888434744843115873163067161007831303825424463365517676765688324200684513347206713426521057202461184363017881817403710703264672680236531845142531570466384473731728758138705644753855655816742241364617142126084780008354140654801776325821685208137803465245450505341523100083408734674154335414845701708522128274506836754076625206872353746311412316312855531504102358752662137808638173521823133750654348485071110586741851463345337506614254157164306768776078885708514685148238201860867238133581485532340048788405422353860218008258548436878687253828241261050821015817420278763365687765514675058675166754736381757223055720684127776321362551252532374142887160764038838183424628018841887374712515033240300045651318782786054437184283851251186686603270668845482075874631015013706514675820635143655714764714156053721845140813850420508700657763114833577580426428065023467825688868337142277613856181714827028778062057570322170260362422631028183028112073851046204428683517685558417500601725657238741370857627730181360274563088823835144601056210101460602232722700431633184040618846384113624585660727717184113675546163610607728213513133205278237138625783833077538572741625110451321533127067244638480483667304517823113154663264021760688615102244052321747321612302751435786674345144462326132726376720328244761422741627313648020611868614763040681674853246228406044610051800751763205151834303188718047635724013221728118711424128888062074420703056187033803211250204407771300451054423223354033358307300448270140765437102400745208838204164114740002455888478168313785353187171180330311056851418840303151441514865342313468076524833442066721446046807704220124510652483242431018436830414063580815564337474054060760627544438122721145213236126348660A82C6DE4E1250965D63B99CEFF0EE2BF66C76EA5BD2275E36469F4F48A5C59613823B26EE15F377DD9AAED3625E4C402D971B2B83296DE5A8D861CB951ECE6BB06F787AA4275345917288245199B56E7F3093180FEB6D09F62FEF524E49F685082481B42648D09F71E623477F4D9E98E79386C060311CE9C063717B3F69C36391B555ECF819637BF03B370EB3B47B8F56EFDDAC66893EEA7DBA70BD28F35D1223829F0FE82FCBE7B0D47EDE3C72D9454CD323271ACD902A883811175068522C068B9C4CF6A819E6A141737177FA90149BCDE0E38221CE7508D32BDF4CD9605EDD630C5AB530DD0F36AF49EA3FC26BC6C0743EEB48581460BBC7836BF163E819671E821CEE4DA76177343369B9E48C73AEB48AD198E958303449D6FA0707BA74BCB777F8E9EEF95B782BF00AFF9114DC954AA6A943EBBABB85A486902222AA990E5CB09323BE672F4E96A1F0F97302300EF6B953425DFB55E8B12740E91C0684D38530B65B9D9D4A48795DD27F166860115831266455A4D29A2A928A11D17F42F56D5344C9F50BCD5066EC1B469984FE4F8B538825A016A029BC3FD608488C78805C3EC39954CB1B9EE1182D416E7658E038ED6D76099E8D9BC68E0149520AF9CBC6BE7B03F85A39726298195C58DD5DD70987ED894DA457339C0C9AEE5B1062C0F24A99DCC9D4FA5E426335449DEB5FF6FA03652EE49AB4091B79E83AD0B0F62D0392AECB0AC4C5FB3DB71E057588D4F777F4D21E3E5AA059543780A80294751338CBBC7566298EA8F067A919869BB321A09736E9DBF1EF1B825CFAE09CE2A0B0660D04B2BD78A69B48073CDDA437BD3F21B00CEE21D1B87BF3D731083CAEDA4D0835C5828B036E6471E5739DC2A7F874F8E5E2D0F66D5B01183A1AAD731B11414B304AADE217028C2D68644551BB1762D5400800709F13DB2B28A5203F0634ECFF934DF3FF920896D26FDF4D4EF9808F835DACD59BB5C44ECE1BD80034437786334910F23F208309943A3189EC42115A05CC2EC8C779F6FD9621AFD581423C2A6AD702A5A9AB15D632D9071D2E104A551218F65A44AA075B02DF27077A91C91FC1A19DDBBF4F793513AE1CFA323E72B6A01FD84FE50A27D2C3F02AED8AEBFF2D1FDCB1A16108D5655BB77C8B1D982CDCF19F82ACEC7EFD6921ECD285CBB2E45C0DE0D585A8C932943BC21160F34D7BFB6CA14CB0DBBBC9F2775ACD252E5B1279CAB1A4119B816F79BF0E46BC648D2E0FA569AB23B10C2D58DDE59C0494A9166EB882D66F6CBDB186A611F4C668F6C964453D5AA9567C48DEDEBAA84D295E46B1CB7C60462C1A9606521664F49E4DAEFAEE15BCCA53CF8FB9A16A38449F000D597072607466C4D7A2144DC520451DAAFB2CEFE1BEBE13B873409B1ED34E995E34BE5C345D408A421CBE8789D267504C923F8AD9EFABD6729FD28C0AAF9D34219C9E9E03D604335CC3224655CCB4E4DA0B60044C10E25584D6F1C434BBCDDDC2F98B2FD6D18640140972FB1D00C1F29929DFEF2822E000D6334E80CE73F453E05A13A80AECA16754A85AF59869635CC9C8805543557DD7D5081ED8C5DC0D71FB935CF8D2896915B406055B349811677F5370F1DD9B179E88DA3D6D43CC3D83220F3C79DE3817A070879A0BBBD5B0500E87EC15A2974C38997A4EAAC9967EE2DE66FDEF9CA9D340AFC5D12AA0A3287D8C9DEE1DFE957346EA23E40DB7625E8584F2F2FB610DBCCF1244646E31ED89EC62CE8FD792EA52DF83879925205F13D79CFD590C291659047811D3F97F9D1164F6087CF5A53EE97C1D7237885ACAFF30A657127F6480CF0980DA55B5FBD5E70F7F4C621F02025B1CDDAF1DCAE5BB6A60E046AEDBFD07F9B45C833039DF8F8E5FBAF5F8F1C1D7C9A3312298B557D49423C814F58D8759B53BDCCF4C34B72BD105302D23A1DC342FEC033871BB3C049826790373BA6DD72CF0EE7FACD730E801B47863D7744DC7E5EB38833134CE433611F333CB89C8392689A2CFA95792237FCE981F4C03AE35D6D8739091A0653521F3CC03B4CFAC824B6D2FF13C91C754758827ABBC642053F293F79FB04542A76DD0A65365B0AEC5B4D74D0E73E57A6CC8B4E29200A3115886185BCD42AB969D392CE9375BBBEA8FBA59AC8C4332682ED331F23BC1EAA9835318B9DD58CAD9C34A73B921EF8CEE4C33639490BDA62E12717D553745463124D5D8D71EFCE17F73E5C8F01374DBC88D5E54FEFB9D9D26070DFB675E01BE95C83D82313AFEB303F82E9AC49408D5D92B6B435570A809E0C286BFB7C18215C719D3E24406C067F90F3C20CEECFF1571781D6355A48A46235C31720631F9C8E30EB9DA0C82F7F9E9F4C58DECF6C5B3A0B1D940747F27AC0478A9B6C1360A5CAD9DBAFF568BF06C5084521EC5182CF156C57F85DF79D98AFA0F3385F01A5BD1863CF836D132DEAB0F1D0DE0BC55B66040CDF41866436C9C4459FC1921ED90D3D07965CF48AF319BAEB13F0900337D77624BF0EEF80BC93DA74599CB74AA4F921AA1AD522187AFBC3135B69866C26B7F197E791D2873C7C520CC3D8B9DD248BCCA4082FC1AA98F2E851A814D4C39FDADAF5F7FADEBC2E6CEBD684C86D82AEA07B6237E320B75E873B763E1D5D36DBEBDA522B361A2705B2CDF78BA8C5019D2DF67C41EF22A872D71CFD91F437FBA0D89FDDA36E0EBF588EBABDED491FCA8C5D0AC5F6E14FCD7D6B132CB831D1EFAE21B51BA867589AFADAE45D77054C0EED8025A4D53B04282FEC01E5D23B148C12EEDB3A5972381987BFBDCC44B0A00B35A33A546F9B05E6D77891C6FB299185017653D5673A9738666D596C83224BEE68DB80BD3519764FB0B3BA7117F17EAC1CF2F7DD9A145DA4EFC006A5779E7D66E69F9958B3D16E10671C1A9D2EF491F2544FCA21688308DFF9F5DF029CBC75ED44F0F8D2ECFAC218C498D4C0638B97F8D514B9FCC2F3ED943595F489F564C34C2AAE9072419983A15389612328648ECE830010293A281CDDF9AAD3688B75DF17B10D8836EEC5BABED4918C4E325322C91BDE46655630F45F33D88D224BC3B6C3040C86076E82C1915EDD39A00C8D38EB064D3A50E410E5A35A8415DDB0C7C942DE119059CC1ACF2A375AD3549F3C6453F1CDFB8F491512865EE8FB5A04AF38DB4F772136954FE156C98C81450396653980096676364F53617CF6740631C6D80724187EBDAFB593B48F9643A748DCAABB7E8E247CA1AB65540FEFAA6FADCB31AFEED56E7AC7B4CCA250174CA4C37F7A457171FF7BFDC2C0F4A76F159157D46DAF95C7792F5CDC668175F857121A405B595338FB04F8ECE42FE7BC5B0AFA27380AD56FA7E168B9179F560F08BE04E6F1B1F09C90FC8A94A1C6D70E7A37294D16D11D73F4BE278A99057D349D6E9F0438F037A06AE3956E3EC8B33C8CBB04CAD6DE4D8FAFBDC37F192A3EE01A10A4C499F7BC6ABDFC383EACDFA09C5451BD99A21A79E2041330C8936D17FBB8BE322DD81358AB56D858EFF712E3626319C25235CBC357050022CAC0A6968CF5FB29E9", - "message": "DBB70175E063054DDA24BCFCAF671F820D674F1D09CA173D4A1440AAF50F1FC8FADC1810F390286AC101D60507DD285275C6F97C0D2B2CF3C7F50609CEC64EB029C3DAD8B9954807E35D4836BEDF32501D0E7143BF488CD5B4D1A53C980BC70A3794E4392E4560E609B9C49900E1C56D319E1495D085440DFD081D1A7C52C0A8F64917834C64EF32A441C9045689DDD2EC218F58B3BD534F18309E1D780528D3BD1B23DDB3B18FC1F7C85324D45C3E9B25961FA5257EC31927CA35DB25E6FAF7669D60952502680BC7B5D777D77B194D0CC40372FC8F711EB048E01BBD5676CE3F2A9FEEAA4B5F29081C34969C746208E6F2329CB53A22058C0AE0852B7127FC4C74EB3A8300403F60B8AD1F95FD2991CE0C8CE452C2432B6422EFEA8AC0E1B53BC994C606301473D7855EF86687287BF56B450D2762C5E03AF26A987317C4BFB013A6BD791EFD141AB34718A37D1DCFBB63014F7F92C9E2870DE503452E271E9D02768357E3DEF6BAC5A0F0444DEE1FF5AFC79B3562C12696FEA15815B7D9BAA38C66919D137F82FE36B140B960E02966FABA1EE9CBAA04941396D665DD2C6B0559502577541AB0CEB066E066553A2DD407354123DF14F4B1DDE6B8C34E3264161796F48DB5319B3CDDFDFDBF5CE17BCB5924984143839B4EDDDAA8F0568ECCAD253C48D00687F9A07785A67B62D28B86D70E511AE08A525F66FB15AFD112C184785F91E76852DAAA3E78CB96E20249F38979031712440DB723B022E1323818431B897DACC51400DB25635EEE41761089DC47E8EA56DD0DF60B56FC682D000E9D660D0CF38C263B716359F41F3B190D201950E140D67F50287C09D2008664341A829A074F9629DABD88BE69A6058900DE5782CC621A91376E5CA31C66E3C430CD00FAA83BF765A2E6B2FCD20EEEACCB996FB5C4B63235142BD5FFB4390F8CB95BCD5853D0226F931C38FE972FBD0D6E10DC2CF29D1FFD2653CACBAB8B81DBE44A2B8F1C5DBDA7C56252E4B35888DFF7808B3514F4D7E5EAE9B51078E8D2E600EC57200FB48EF946F021CA8209E7DC6443B37D7281C73C6A3B43AA570398E62CD5ED9A34ED23AAFEFDB7DB3141202D940C1411CEFFBCED878C0D325E8CF7FDCC520CA3377BE97855827D2E6F4EC8786EA1374E006539387924161D65782C7B2C262AF9BA8FCFCB5B1477083836129DA973AB8B082324F74BC6320646448DCC8AB56582EC72EB192D3F72255D85FFAC2B5C62F245B73191A9176BA5A9FC0ACD3AD48D37E23EFA0C65F0423AB5CD0EB76BDC035112C7A118ED47C0E67E510A6F7A28F26C3D6A882EAE74BAE6CF1FD969FEEAF6B36C85F62D40CAA26B6CA98120D612598F360CA2628F6FD608F4E1E290B32C90FF71E181D4B72978DFCD189D857DAFC7B2AF8C958EEA6894ED59AD56B9AA6F83092EFECF9EC4091BCC9B8CCA245C30B54B9B8DFF3636BEFD417F46DDD2F6136B983CFAB532FB623FAFC3CC4CE8A91434377F4DCD1607BF04E431", - "signature": "B6662CABCD010DBE21D9C8E04A2857E7C78EF2AE1D5D583D2E292257F5CF7ADFDA5AE6574FC79E58F254DE8E41D988D2EB72FFD336856AE6A0FA1BB06CB2A8A1BB588F1201B31E9E62996097FC84D41DB9A57112F3F02B2EBB572602F054551D313172B84E90E907EA6E293F1FF7446C5814CDFE2425D61F3DAD02BCC6262F816C73B87F68D2D4BC0EF41D3C659D9FCA7AE921547E442B3D0BB2620208D12932CA6F3232E98BFC2896B8FBBAA7524FAB1236298C6F743146C758AE32109CA3A1F77F96D18D7A87B608DEA8D1C83F705989D50EFC5BC2228D61C6533663B1FCE85669D0A02334831DE3F2A770D2077D4C79A5928B21596B464D7EF0ADFD463491458B1F151B2EB5A6BF87D5CD39C5CA162CB8B111336417910448CD63E074282E51E3DFF91342FEF98BFF2E40C055B57FB2BAEF5ABD42085AFD65E14B3C60A00985F3B4758C0DA6B43A8D54DFFEDC07A298F4CE70BFFB27967EC5D59B91A3F8DC79B9846AA5255B3199FA422694B9C5E6F1A1C8B494D1B2D6F093E6CEE2768B1195615DD350E9072E736911B67FC83BD6ADFA60F2DC9BAB479CC0BEB914A0E9F064ADCE261909A25DF629CD56BD3CBF8AB8107AF1E3DE33D772A4BD8100F83C91934FAAB8776CAD460CE912EE635672D3CD3B14210250BC3E742D34448F8EC576F502276549BFE3D46763875F701BCB01975FEE50157F16A652524BFA5BF6F69EF32AADC43430C7711029C88EACD391423693513127C0411E08D7B4952AD5075A09D1F14287E94B885A43A88EB3D602FD122CC1507EA88ACCBEAA3E939305C0092834F30D486FFF47D373A68B55A01934B2254FC911D122343BDAB0F2AB2278EC4CDD7D19565CFC62CC3D5937C12D313D77A5BA20A6708A43BD11480FB1C7598A55EE706E9AC6BAD2641A640B3B0DB06171E3E9CF2E4FFF16AC1719DD97CE3C21564C2410E9B03CC9792661C39677FA20757F53B859655052B6DC8923A172E1801FD2A5B309CE97B3DF50031130AB05C9A0A7E6985471BA8A92698AAB7F4CD35976AB007B4A43B8D51042514621CE3B8AE764E997C18C9E62E68C4340B03DC4C63C0C7472BAD4EE36FF470E1DB5F2CB6F136B51692A1836AE0B5A00CCBB7B81450BC51605EF4AB1717438DDB7C5F1543A59BBDB7A1C13980C227DC0A412B486481A24BBEEDCB379B1979EA058ADE841258A372AD0A25E5C0D11B87585119282E9EB471D1E944A07859B43A65396A3252F9DBDA5C5C5E52C38529EC4B9ABDBB936CD7146AA90A6E1B35864516CE15123C030853FFFCAC8E65FB30696A0D64C170A6D60918DB28B8DC763A7F31BF7F55D31C6C42BA2187E07BF8B25595435BCFF169EA715F31EB11DA382D6D1D1C20B747EE14F69C8F9D27C353EC651BE930C05AD02502AA296F01B11DFA4EAB1AB6B9E99A59561E8FDAC25DDB432890F9E383F54CD7FC530AAB05BC61500C5738B058F2DF8D789F51922A66B015BDA4420051C1E537390FC4F6C3F790329C963D907B67229CD75641F8B00D2AADE441D47763682686928AB0AF9D94736DA210B4D74259442D623058D3E8DC3B61731A9A3662182A47848B8CC7A8127826AAC45D2C03BE0B1D2697D7B2F85A774F891EB45AD17C58F532074AE1B70C3689401575C33D57CC2EC0C00B643109834D5A57D1B546DE93EBDCEBAD143D5C6AD7498335B45AAFF1AE6EEB4EEA739642A8F68E703E827DDA7EAF6FB674CE8638F50DBE7E4F1B2AA8B3300BAD6F802E3F0358F0BA8C1881104EAA8B4C9887B065EA7B0CDA8EF2354E2EC5B111750827CEA337DBC55FC88C6470FF87A8B7B50BAC4BC7CC5BBAAEDDC6BD1E9F22663602811AF94F49021C86F383E1C9E64C465D78F1C42427894012FDFBCF90916A3D38AE0095EAE52FD539FF857515EA396280099CB36167520B1EEA47AB0B1EBE680506ACD029B4DE61C7389500A5906BC56C30919BD753BABF4E6F822885F13476F1DEF4BD444C39CDF1AFA28558BA48A6F99CD0F065A18DA8281D94656D94736809EC626BCFFDDD1A777A1FA67C642D08FC30461AD69C1332FAB84B400161C3802F19E89C1E962D698C1AB1C8D61AC99987E3E7AC28A8FD42696928712A9E367CE28F48CC9D17D69463A81670E2AE088E0BE21E0A89EA9ABF1D1986DEDA702919A2C9C1CD6851B3356908FA62EC2DAC2817D5C6C874B8F6D5F92FE7617C9CC2C3C221AA2434E156FBFFE8B7C27646B93C866E2FCC1A32D2BFD859B432CC0EB4745B1145F482D03A2B22BD026BC6B37BC802D8621906DDE752AD414615296A403F9F1931EA80BD8B3928F25396166562E62C06B946853C17E30C93F67577B35E81E456952A4086907BB6049906D9E2F9D1927D0055AB0CBE11C0D82D899269D145255EC8F2DDA1FE481E3B15DE0A719391088C1647F330DA8AC990FF06CE0C957F8482C88127B2B82F68D115FFE880BBBE9D4C6DD2D9C872DD4B91A4B52C217848E38805B92507C9899484973EAC5A47C78A53A58E4219B86818DD90F5483CBBDA8B56E3A12739B7B287F29DB9ED987CE4E93079B577AB4FC421885E7951098B1B036AB3A93CD7F2FD65B75EFCB7007E8378D2BD18C13AF5CD6F8B0E5443A87649C2463BEDE2951FB7A963497668993A9ADB3690B9969596DA62549F0E5B597D3BCADA83E66F565E44A0C0B88DB3EFD076DD011141D8FE0348889F0455E3E1AD8FA47F5C8F28005C63FA4562C88AE0405A95069BCF1085909198826EEE7C86D379AAF244A7BACCE44F93D1611142421DB3C82860736016C36C89A3B6FC87509696C708C0DD2A1161F6748EA33D1989ED65D1DDB8878EF158BF1C1973060C00BC132E2407D1A4696C6CE911DD9BB4B231C961B7FB427E8577CB28960FB519C9F977B627B8A59400E72FBC12B1A207CFEF4C2D34592E0D2267D30BCA0AEA3E22C8B7A308B02652E726B2CA97179AD96C8165FE64F230E87923086431D55D1FE4208A987C61E9EA8F38CB56B7DC086A192FEEFA7AA0FE2B3975296B1EBF6604DA709B8A7169A3C610061A4E85EB42AE122A162275256DE631A54E7EC4E55DCFC3FC58FD0273333CD29731AA0E18FE0CEED334427EA9220F5E6401C68ED8B0A0BA69033CF6B9F1960DEF6BF9E5978AA7C1FD480AB685E44227A4B64651DA47AE3B27EB6029D59B2DFD1118A64A218FF7DA3779A1C0227A9E26F92DF3A7EE73382A807B71ECE108E5E46075981A2FF5152BBAE895C9B0CC66D86850DA85FA737E2F1AB80F8C2741190000793DBDF6C54482514704D09055F65F1730B05925CD1773D57849EEA88DE4A3DB8BBAF341BCAC5CCD3B56FE163249334861DF702729EF012659B8AAEE1E8D4E785767C3CB64D1319E23533164D6E789DF1501EB9A6FD7F0F14DCAB73875D4F2848EBA3329D6FD40F60C626406BAABB2B81C95DDB127D20F0FCA2422F74DC6BC3AA5256F3F9F5C80B81D1CE07D62712CA54662205B58E56B3E1684D69323B4E73D6C4F29D9F70F68D5FCC3D89965E5A1702523CCCBC08B3F6427A616C6DDE12C374643F3C7E97CF9483036835D4F928D00A673C6C22F16BE20AEA0E4DFDF88DD4172D4DA21D4200E3DAF7B3D7FDAA5659180BBB6CDA4AD79A9FCA6D5D2881826B40030314EEA07CD45539BD0BA04525DC79326B5AD649B343C23F2887226706D66899881B7CCB4CD46BAEB41E9D047E87AB8EDBE95E02672AFBEA25976319BF35C13C2C1BD042D3DFA527E69DE13C84DBE8410DDA13F38B3FAEB479ECA09F876095E5761ACF0144DD946D2DEB7BB70534E85BD2E23E1863DF685C7E873E9CE29930F3C2A8F78D77F16D4D34A91F1060B6F275DC9C57BFB49A6E5C547B9CA023E418BCAF73D8BAF604E91F5AE69F8CE08B36EC91CC920296577A83C32B07B56776E5311523C346D9590D57F036187AC1CAAB62A4ACABF360D6C4E49517E30726F26126AB405381E02F4C7CF794F8979D54E87B6FB082A8B8A0B1D0A26090A16F09E94D0CDD02886C6545F917D905A7EBDDD1EFA8E5C7763A32DECAA87ED7229C774DC4287B065D04218695B3142DB41AE748912797DDF08A4F8495334E15094B51B21734CAED59D5D2E6635DE144897575B5DD00D51F98715C220CEF67CB08FFA84AE2EB8491303D41F5EE405560930F93EF7A5D3420D203629AE0FEA310855EE7908C1346672C669025E49BA520C471FF6DF9D34FE3960A5A3957E5A007A636A457688AFECB68572B0F55EB90435578E1C75A30A18A17018A7B753E479C677995AD162E7D04AF4D4743A186031B37D9FE4FE23D274DE278FA30BC2C9EF5A5F1DBB431DDD23D8D908722350C3136D26382087BC7399C1CAA1ED4A5508AA0CD3FCD89A45119EAADB689B1D94B5F58DA23A650D52E5C77B739125E660D9836647D7371BC635690D77CF63500085A2FAE7C15ADA7654208FC88629307A2DF3916262523A61C177A7E1F8FBA729B6BCD401F8033302F83DCEF604B4C3F9A5F389C354AA4B938DD145B54A00994FCE1ECEAD40F8D819F232EFCC05FB812A764486D21295E56C4627BCD1F3EEE644DA4E32A8EA4EC4FD405B74BF49A238411AC85E15E4B6755E2EA566F2C38E858641B3486927C6428CB030D1E394A4D4F5B6B79BBF42343A74383A5C3F8FD2373C3FB2D31626ED8DE1C2B31637386CA00000000000000000000000000000000000C0F15191F26" - }, - { - "tcId": 23, - "deferred": false, - "sk": "9BA12496D2759ABB2CE2C3FDB3FB71FCDD7C315B4C7C5AE5C6B4B4F6A97D2335B07CFC9C4B33D9147B6231C6B33CD876DD71889FEAE5C8875128BF0D75F72E380A1C51E6D56CCF1BB2FF2453BB7F09EC9E1FAD76A07CC6A4CD012726CF9309E9EBEC279BA77B159B515A954FEC69758F40EC0C3B3836B661E1FED121F712889B77512258675704133806066748826547111521115868474531585416005713338105507070205662844057632638535166351741357313537883572686500540128261085411603366201318374814306288785181752828400800470585613434710704510035385872517651333585207787188184062530114384673018530063727426246401400773237530844578751387817248277471125878621454431146683341406818333868760704701502761143473707860535758187372162868573323826480416420733630025672348726538053525024423653243546423514553071340770645158747722387267847757250586600731582661356526504140404107264574637750025462020601372686055328846034067308301012344312705314305867783080470360821015418216663460502701754763838654027628220553546644844707313784544085501508364158844217135802560352218345288786203528513537552882486255033112148517000583211241325641064030340235323380524631220275268447538464445758352140612704781828086872330585810217000036008674504425701420181180377803350424765338285178682720218181012520214517830318082227120513518322554881166140214761423438151247072168382748504452500004758363227304767704161305584642720280148873012060716368664714384685145586365736257431288024173772381536807648611435052307322366547752204377446868057638617731102741825234125865523273560843152782032533880776282206451272477621267326281383315581785515642825006261045510323376338070785444022023713881268480640885038174347552814543067652828245641383354501751610445443231755333835224563515134301511513821681374734335016003216522571455880410230421326311811338146248236660357671633348772574361832403770183010531215541634647651601211557845444264232368206771167634647778401370320484608854756652513571656277447284614256054125825545667871576431852286416638036374180758183634577548265761215082800487735370570835434878138206660513012214466631044531375060518448334384743777234256478821032557054374186280115238364375612238562440815877116541472770062087278326687024403300345343640711805831336621255213741538544438567453332843754315440442730654367534363248630360146213140072646271447800025357255281341257570554320245275102060221620818717848621585406508157876043725614243441752316510561605237486301154208628170146326444636374671281028428888054302763653254651680624433732312785052851001186422542016363135628821440082566635447837137437567738250604600438461732334063187876327123582736038000542537210170133043240437625172228545888471831032816233708717083020220534823336673537346268102842456807765246230548276186624233334504072552008188226324457005707040616360473678536233682028686415232708258156535400766767114686043413232745516072208330587043436465427087756584440822673872786114734048782500067420780002787748322508678107138016507217573854055248812267683351608427542745123578836475638204547465316772773558376364227627315732325112263147154784743851852416083411402663045461736077851483201053723540300740062572041704370051846EC468CE48A91039F26B5E7756BFD4A483E0805A91A1A5F54C7AB9507CC918DA35CE125C51BBB93614253ED63D269380A50B1804345C810218E0DF6EEF453AB0CD7BEBDC8AAA364E3C458E6AB8DD9E21BB72B0A499AF42763E3DAF541E0558E5E3A154C4F800CBFBB451CA73A620B3748B04C7D535088254D6267A28291CAA541EBAC426BAEB242E19EED2786BC26A40841229F2934DEF2A73A5C6F3670E681F111A3A1732CDC2813DF8772596A7D6FFD5F717F2EFAFB6BAA793C345FD4ECDA18B9202309C27D00BCCA6E51FDACDD9832A630340DA5CB703F2D68CB1C17EF8242B3F3D60579616E6102B08ED094C1D0E725E2985A0525CCBA21704364E9031E086EF875BEBD0D31A922B91E9B95F6E57985EF2948D9A7638A1C0C76145CDD9577C5585B434A790D6A87809FF6339388938E2283FE1552535DC30C3F073B7C8BC80EF42553D30FBE79BFDE391D9B7F87BD1F809FB671F49F159E4C653654239EB1E94B757E9D81E2809EFD283BD9BDE81A2D316F66BAFEDA9D4A524BB270EE43451434F5F61D33C6DCA6CE3194A3017B5DBA255E905302091D5F341293D20B89F1E5F81D5731014AB1A5EB022609FD6018662EB2EBCF6F3F823DDCB86A5C82B9BBA5741E1909CD60C1AF239FE3B930D0E8786F6ED24A6A8A26E03A05B0BA51AC54F87F845D680A1FA09291405E758712C00B9C0C8D4D698CA82641040521FCB063D5FBE2271965AFC1F4995EF47E4E307D8CF97D9D22A6BFDABCB726132FA7BBF5258226B384B7C06160AF1D0CD8CDAA4F16F68D618F417FD3E78DC8B5611052D2F9E770878D7351D52FA00847A426C9CF845711318FDE114934323D02F2C5F37B9FD93E22BC9433142095BE1D6DE07C7009162F4BBF057466E04DBF98C4DF770A2DB27A5735A4733604247E2C3AA1AF38B4D9D267EFAF31D2A3162391AF0284813D1184217F93221342D28CDF90F85F94D2F66024D1FDDFE6B95774128548611196000DEF8681CDA4555B626CF2D77A2A638AF6FFD0DF73787B955DDF5B9F0A6487C60D09A466D2F97C985CD58E4A8154CDA4CBA831ED2E386854B8EE5523DDE4D0018BD17BF03F02BE38328DE99F9424C01E6F2BCF9DA3C75CCE87558B977F5CE91C9CD3FE49A1DE4A45B162D7C4EBB4204FFDFA5A6AF4CC2DC14B7423DD9C819876E42A75709E72B18689427324ED0621AEFCE11CC766858D46ED7F1783949A8C5618AA1ECDDF332F2B6C92E5EEA5D5E7DC87908547656B65E26D9FB5B2068EA5C39CFC01021CC11C0845A3797541301E6B6C998BFFD7EB03F8B3CD7189635FB13A4E42AC5249F4398CF221C7DBE68863A8E05D3FEE54B905A64A4CB6AD5B9856081AA953D2F51C049E183C47EEAAE60F980B29680675867405F605B5FE8E13C0D3C5955F801F941CEF618F62AC6739A92A818A0F6F2B1D8E259040D190F371577AFB2289D13389579452FD1027E4CDD2BAD5F78A4E6ED722A5984665FEE58FC209AA232B38F45392970F89ECFBC0690785D87A7E54E5DF49EBD9175F530FE091624B281AB66535197122765DF0378ED4814A3A4FD60490C82517C98631C51BF9C4F0AF9F597BCFCC1C25866D2E9038D02CE583AF9D564EC7A7AC4AB7ABEA8F86269B6DA84050070CFCA06862E03039AFABEDE496FFF556031F083255CD1C46F3F94119FDB8414A6E80CFF99EAF2C5BDE4794C119D5F4A8DEB2936C2C4E249E3DBA13C0D938322A91E860D4C4D8C17AB6DE6271ABC5E4F99CE6ED0D728585A985068A0A388A51759CEA3B29CAA0FEEC27A2DB3A252AB4A18E8E477004F5522D308329197229382969DE75AA3BB3C775AB0F74FCE5E1051DCD2C2624A8EBF1F447F7417BA2B5E85EA0CE6678AE6FE0B113CAF257C7BB73D1A5D91AC0529CF7DE38792CA229D1CC519368CA4DB063FA95031F4EB0A5A647E092F59CF39C9A255957DE2EE92AE1FCC4D041DAE51BB04C6B8E5BC52CD73F31AC745DD79F27908E054A2E3906A84113FD7FD4E764AB0F21C97617A82197D1A4EF7E73408B667FF71138BA727CC26A400E5E5BBCA922B104D588640484EE4867EDBCCBC45AFEA42AFCF277A63CE6661B57B00ACC1C2F76D8C203FF2123F9079EAED0B0602BB1788595A9198568006166C61806B5D6ED03761C874E9788FBF180880F9853EEBFE2A933AFA6BE7CBE917C5919F9F17777F55A29E7CCA1455E38EBBBEDC83BB062E914F4A4A2CF1E7E32362FE97831FF33926F1CD9E99C80AAA205AC365173D5DD94B8D8F3922FB192F277A09BB7A92A5166C2CDF7F18E7DE7189ED838F7850B306576D10FF014774588865CB5EE3B161E54529B8E45B2FA435E36846E80D46CEE9BA5413BA950A448662FCC5A8BC8E42AD3A75326747A9C02A6A6C676266B580CA91AA4E9F892EC00EA64065D38063881024F5A898451623FEB3746B2108A24096F2290F98C9DAF9A4DF9746EFD5B5D9FADBC67C9C06F920E5042050CDD3A1B500764E7936124B4C742677300DAB0B2C56BA69B7CECA73A6F97C961AF46648381064764F48A5D16CFC82D9766A35171CCAE17F18C82B81BF91847766FA1C361312B0E532092F9CBEEC51A55E460B67E47E91C90013501CBE9C00E1D84985D6161691E0AB8FB540207991B3DC4A8B444F319235F3B22D03640A98C5DA08DCC417E0FC232316511447752044FDDEA962915109466284D94F7965C37F5E9518826C1BA1A94371B28DE026962AF755AA44035126E6CBDDA35A746728D6BE15618180C3EB460404696D59ED13BBB60BC71298659ECDE17F0264971C5158264D9E9006C627CCB58AC9B5AA5AEAC12105EA17AE78C1D9AA9C479917149E5CEB8C22910305F5CCFC2AA90012D2B6DFEADA3FDDE35EF41CDE929B88F7395CC6CEB401392DFAFDEE51B30A53B67969DF6AFFEACFCF455825675CC2A6F6CCE9BE60D23CC0D6ACD35E9C833A3C82CE16ABCF9E0C56A2C18D1C1F9C159867C933B6179856B9050D5AAB4A547594FCA0CFAE4969CD0B50875AD6476D9EB70674434F36935378BB00B4E50711BC0BC375449CA9FE75C0871063E5BC55567D4E082BD0B07043F9477EFC5F8DEFA13CDA03D3EEA1DEBC996B88E9F60B4909A7B3BD2DAFF53CE6B6046AC2F1463ABF3BCEF4C112AC1E625DEFDFB28BC0E0D67061492B0F64B7C66B89CD1039EFFF0546EDFFC69D14F7CE61FEA845CE360D8ECD01D1643AD4C9ECD76125CFB693DA425D877B7CA327261A0CE4AE49057C622DCFF48C6062E0AF24FF8280AAC3F21010C05B789D8FA371F48F18A2144FD1F8423112DED4DB1035B2F5E39329E680BDEEF5A37B3155BAD91DAF7B0CD8346917859D7CEEFDCA7E7C6983E09D789AD7EC35F9848B639EB1F3A1B44D78521CDAF980D6F52FF981C30605E8F5C0991A479EBFD92DBBD6CEF2FE4B0C70015943D2F1A072FFC126CFE6740DEC7DBD9DF059FA1C03A51ED2EBC7B892FF0F0D34C2DBC4C1561788CFD18F0B4A3E2C0B3EB57215C26CF7E28C544EE7372D7841D349F261660A3AD42968D98D0648975D488C2", - "message": "5F8F32FE68B556ED1D2EB8D2BC20AA36DEC7900F8E5D4BD3715419B28771E5B0A080DEB2F3EA6CF415D40EDA46FCF8A439954471B7308D3E4226E9D5A96BC22B08FECEB4C5E3CC2239473F1C9B8DFA5A29C31D499CEEAF6E34A396BF0DA53B54F1AA674056216756DFE15F669FC2E1D8E6F67BE5BFB3D5703F25D62D3AAB0398AEDEDF7C65E051A4A8DDFC725EEE940BD0D06B103EEA32D027CC20A8C61034DC54BD5533CDB1A85107B9CFF283FC3C5FCD9C3D6F8857560311AC2E0E31585E77D0806F9A4E61A70D3FF36895ED447C55DB52002488045CC358A39475BFE8456F4FBC36005218B2CEC1C573E41BAFA7A622EDF776C8AD340680C1B3002F69D3B3D8844494EA9F42D2C9C9D2BC0BDD850BA3C4DE929C1DF49351219F95EA7B9794827FC1A1BB4A6A00809393BC41852820569D7BC6FD55339925FFDF55A0C2655C85144234FDDCA91E8BDCE8CFB7199330763F5750D71CA8C4B3BF7E6469F5DD68624BD6D5B69E5FAEEE53E3A61AE659A364484B7D2BC8A85BE9F8D35C8B97716E8202B610BDF878C1BD83187F7892BD861C09FCDA64606A185B93CD2F601C3107D35B38D76D75AD6023AFDD95E103EEB7283379BD9E44CABAD923856A599B719A18FA836749E5BA95C79B1F2F1B443CE1FD26CBD2B74A0156C381BC270B74FC42DFF8D91DE4ECDDF3053007A09B8E3C964B90DE55DE5193F218685327D8C0C6CE3BBABD57DA8772DB7CA9234A3D19BE16A895E7D14337FD9D50B4A556C75A9D287B44BA5AA4E52C3262218DDCEEE3A7BDBE1B8175E84113F515623C07BAD4FC0985112DE4D77D31290BD013562D12FF8CBC5F2BC463223AA82991D7D60E38037578BBEEED70631CEADFE49823EA3D87EC384B3FBD4974C474FF9D47F467110EA4F3FD94B5FF38D8FC1C75392896394671853FE71DDCF7730C70ED26485F395F180D2F5C31AE0C2C20691CB4BC81356225E6A72DC72A1CD3502E42C22B594118D131BA5EF95F2C18B3061139B047A24E32197F89780B91D36B28BB5EC6C03232A3CDFC5ECF687BA5701F3958FD87FC0C8D09825E8BE4E5CE9089C674049C38EC5E0FC1AD542F57B4770B6E5DDA215D319DBFFBFEAD9141647A508E271CF3B0DE7C137A5AB999CC88082FF0CD495F1F1FB1E367B57BB400D8697B4620B75FE467D9B8BDF9400E14047576B3AD6AABE0C0714686015B8A963A0DBB68CE9E41FFBBDD5A792920916538E4C33F12EF0E93D249E562B71BC1C252E1DD8AA646F8C7B489A2BCFE7D29A6D3FDA2C21DDD78179861AFC766F6885E9959F753C66462DAA6E01C8B06A6F581104B583F7A5B1B4935A4EF08219FA8D114A963F3FF3AF22C3D1C1E3927AEBC886AD0670FC89C08FD4DF68EB990A0F7C51A4439C32F5F51785B20DC82586940C35D80A91865C3154D6C925250B24D4C1A9E76A267711A0813E8CCD2DDE9748FA0464006DDBA963BBDABAADD377239442DFEC6F7E8098604645D63AEA080C1F749CAC589F77B4AE0955FABED757E6576966D539FE1BE5965D03882279B2C9B6899205C9DE8D0B1819DA8B5426E573CE785FEDA3BE95A18A667AD5AA8FCE7894BA11A44B266EB7571A93CF9FA64C1132AE07F0F24773C83DED2C2885D415ABD96A21A0381811D66952252786C39EB68EF0B9B03BA7E2B66A49BC6CFCD8097C321A932E5CDB11EC6E43A8E50DDE01EA5A28F08F5047C67C988E8B4A04701A0237330598ADE8EF8F801A07F2148B44E593B0ED16DA30BF37A341073C6A92066645BD7042C3A59B374FDAC00F7F69BDAFCAE5EC0AE65FCFB785C93E49102F5A5029876BC23B0FDB7FBBC376A9E834F0D19A276BC4E22FEDA18FAB529F15570AB674B844703B47D726AADE3AD4015F52D86843A01AD5DF086E07A71A0236765DE6A777F94B1D69253A424193FA9DF54899AD9915634DA23E6DF351E9608219684EC8C8C949E900718DB6FDCD144D0BBFE1079C1BAEC516BF60C1E24B8EE6DC380F55E0F65DD64025C937EA89FD12F0404ED0C03CBA18CE2FCF169F9A1EC9B96830FAD0149D4A90B13446347CE4E5C6005BF115385F1D22EF6A7E40EE87847BFDA4CF7FC3135C4164091F49DD08389E1005271E9AC76E27B0CDF360EEBEA9C08E233CA58305CB276A8BEC9686CDE0E2DB5CFF9858029F3A5A42759E4AC6DD40AF9617CDEB03FB1F9D7F112A01B87A265C4E27BBFF596695F127A97E1558A68BB5EE4EF0F44D20F318FEE1CE988051F3C09AF6E142932EFE970C1B0C07040E7F3DB9BA53BC4AB1433F7A4F1E480D920C23A07223D7E43570320B3BA590507D580D29CC3A8C85A442BECED5880350F9D2B1AB5C746C1B9909E446D9508D701204F2427F41E043A78024EE3F60EE19B71B5BC925A2557FAA8C7BAC7E3405C920FE3FB3A1BA7C559BD75DB1E4169804B6627AEF19AE6E41B8A40CFB977C1AF53208F4D775A48C220A756783F41E13B7780328992947D215C5B5682DEC76CB035B41C007CE1017EEFBA426EBC423F710C1E962528F7636F200C2E79D8377D621513BA7EB3EE5A0DA55B81F6039D2E8BD42EBA5B2A82C3F033CFEED6EFA7D970B1460CEACD13A0C67AC0A7EBE7963F0FE21D20B2A82EA922FD889253B5D4CE4D47698D43AC11A8F4E1638AD3A4C179C522A3ABBDF420DA3E89B9FB7608822904944CAD615C62B28EDB15D3826D33DCF9FF9BD5DFD8639AF4CAEAA55F9F8409B4E5F70681BB7861F88283218E15A4282E199BFA12360FFB9BCD68D9BE5A3411FCA4E8279562F595FAAE0CEED4FE675DA4A8FF94B180AE9D0C8C687650730F05715820F67248D02EAD4C7BC0D41C880444B94CCD60A66A1C9B5B6F6690A2E1766EE10B5D03AC16F175603A1B9D49F97CF3F91932E97DE67CB523A38839468EE7681909CE997BFE5EEB364B472220403EE4A9AC1F8A4A8F78AFA4D9010A0127C0A75D3CDD87DD269F19A47C78F696218F25AE8A61073644A4F791ABBF1B180267AE41DD44AF65EC6E0AB356CFEE86095B64F4190D69D60284A1EB42744C31536F736AFFFFF186833EBBF43709BBE6903A06F7F06E8776D2AE41CFCA33A3A86342BD11B67EC10F525563A1843C8443546C1EE61DAF7310802AE9C00F44DBE7E04030BC4D0F53AE2023A7647F08A0BC6F5013A61A84E994FE0A20092DE133FABAE3AA24F8F3946812396B0643721AA13417A2423F96CA8A6529B0E17766E88B2AEBD79AA9D4D31193533CE50E4EBDAEEC976F156D5DE5917D54F9CC0527BB4F1F795401210739A42D10A0242748DE5FF6B50932B507057EECF8A1E37800223378642DEDADB464F5CA251D73DCD28A1E3772CC285A33B34C6701B585FC03C94A847CF7B16616D1C3DD646669546D80A27E9DE6424AA7AF6F1694037E774259308E71E15D7408BC1EB517CF0AA2C9E16B802CC8553458BB66D96CBA233487DAAD6E093235D901CF46F31B9A060D88DBD0B7380652EFC73AC1A6BB5E434EB0394F1EDC937E9A99A3867EB71D6E19622137B009D36ED7F9890187CCCE7D884DFE118AB3682EC08CDA8BA6DD4B79C9C18E7438E6914DC1C403870A540B74244964CA31E730A7D7591E42569532DA8094559241F2C7EC182FF8BB5A3F88DFCE3020D8B8CC0D1F54CF67FFD3A97CBA7F5EC79333D9A545221C963E0685763E59F1EBD34FB2394727896CE638E909AE6DFF41D17EE1D0BA036F8AF11335A8C1B5A0E9DC58EAB9C12F46740493A8B5AD0EAA73AF462BDF43CE44BD0973688D9C8DFF8FED961758E1AF88FD5D249FFEC179FE5AA1D135C0448D80F4B0CB68492CA399A3916A2EAB684B44E407706CC3C2F48972BC9531353091F91B427FA32693906DCAE862F34AEBBAEFD30666523EA9C27354F2FCD99A6E810685B51965571E4B4B5AAE158636497B6F952FA0B73617AE35A8D7C272DFEA1CE06E983CC65A501F73BE9D69EDDE6A4A1764DCC4B74EF09EC27C74B677920AE8C49CF4F18160E04B5AE7EFA8D5D92BAA5E4E547CC8AFB9D55F1A9DA7A6AA06626673431889C9996BE0A473702450B960231A617DF4705B07B47DBA1BCCC0EFCD5713F88F394EC4BFCC49EC24B76D531A356A6796785D755F027C664D8966B5CDC82ADE776BEECA8AB0D9DB6ACF5E841BCB4381828DB8F7358A637D04D97598A8B3BC823B891F5EB6ECF54E6F9200C380813FC3210E68894A656796C9A5B780FF486E6A93DE055B8F658FEA17035D9C212D23BB5974E1161E4F6041E5AEC446D70D52CD2F21F1A33C9938032487D9ABA74C448EEB8F8D51169E8B848242F5C769B471F0AF04E965BB0F4AE7C6F7B4AAD4E283DA762DFA49FD01D21887ADB28781FEFBD931AD8E2A26BBBBE5D88B52E8B7133134CA76C6648EA39E3D2F102177F4237219E06CBD05174D503C9288EC9C3E0128A824A7ABF418DC45EEB3A67777F74D6EC52891EAE0BB56DC756ADF40D39151E3A68719C563E99BABCA4C785BF4C2BB1BD25C7EEE22A8B0C1E90B948FC3A691670E9A3A331320CA4416B492907C3FE70AF9A2E765F9607EE1BB2CE52D2DB15F5DDCF59BDCCCB5BEBAC2784FA0896BEECF38C24022046E5DAA7607E8D2DB8CBC65541CFC6A0F20CC3AC5EBD4560BF5E9A3FFC0BAE917B479D960ABFC99EF84A696CE5A95720FED90F3AC58D77D48BD5573A0D85681238AC0EA8F0B58A01378929C691C146068897C5642DE74D79E08E5B94B101182200FB3E2BBFEFC8B44D2D1203075862D77A184B25A7790D76D7CE88C979D73E599C212F04A8B01EC3CD6CED3B5E25487957C56BEF6AB4433FFFE6DBDEA396212A6870284FD1BAACD5F7A5D9FAB90D5DA39D3C5F9AF196D9C46100BF45861679A7679638BBC8E5B5A7606D863478B430BF2C61F52D3D88B0913BF12597620D337DEA52BEE9CC8A1592698D23B23815C596981152C99453FA16800545EE781F24841FBE5A3E5AD8D08F2B898127AF40A681DF9DB68681533C349109C29D19311BEAB4C2F2DE97A5345EA7E41CC0988B2042925F1F9409D947128CE1D38F278863385A19B2CF8338D0FF31B06FD865B9167488EA157C7965F4679286077894660F17BC7289BEFFA93CB7DB990A0E40D998945A77E536902FBAD3C8A278CFE0AC883BBEA0B20E5D70EC6E10B59C2449CD1A0B55F8252C91CDC87E70E72FEC175D6D67BD43CB5AE4EE9C7F9476F4589E2BBAF89E801D5E14458F8A0B96ECF9F080E5150E2A5004C5A89B735639621157C4056DD1106CFC727B921D5890F37051E2B906885C1CA3999C18FB8C9FC9B652D82AFF074EECA9976D612ADDE990DEA418031FEFC4E972B31CBCBDCA0469E3966FF6F97F9788650298DB71CEDFC04659D30FE673602659C19A869FB3EF4262EF3FFA9E3FFAB1A3FE7670061EBB0D49BC60AD0C774913910E26E4213B76DB72AEFA3CCC197CB6F6DF773F86F12480B5BBC2068F61E16D1C0C141AE6F1811B2E0D713AAF60B90BB2F00EEDD4651FB5191DE5A246A4D8F3E9999D85253FA705CD4B94A6A64D9E9B6E18BB6855CAF6B991494A8DF75E56C2A427883E0C27246E5854B8DB2EB0FE639BDD00AD678D1B61D799AC59ADFF6A8616B357A4B12A786EB612E5613CDE533D92E87D51D47D860BCC39687485EA814DC5F5A971EE915C193ED52AED98D7AB301E32342F3D207BC03546460D33B733E1008E48D80E716FD717BA82403DBB520246AC3BC9CB91CC0ECDB7E35E6863C3C11558A8EAE9E1DC49FBFFC0F92F397828A4AE7107785939B96932B9EACB6BC6D8B3A189B5D3F6B0C7A3A413054B25318792AEBA3F4C77629F1E8CE1AAA98FFE1EF50C2E60C11AD76EDDCD8EEAF858364ADD637AB97ACBE4D2124AC0AB559E85229F1B5D81701EEB1D6834FB215984E9DF3847392EB29D2A428DAE7FAC283F93C8FED86FD2377E8216922D46A51E628091F6F8EAF967740B0EFD84F002358D3ABEDA0993DA16D0D8233090A2CD9C27D78DA0A53962FE7DD282B276A30F91C2B734EAD2CCE5E03137205BD97739F6CD75A08491D4ECB22591A6FF840B5DF123FCA7DAA98B11C85C1F8591EB988024C206CDC4A4239E7A91DE75F49541FFB6D91BE4699C0C0D8B4A44A8204F7E90AB863C3183C2270D185643D6A7165C1D043FC5108C340650F38A8FFBB13BE4BE68858C50A2463F7BE998286FFD0F981B45F5E414FDE71637D6EE77B33E10A530C630D63F21A212E844C2F7A26BED4F7B4DCE0C566CBAEF4EB4BDF2B53E743EE13A845D3C7AD5E9525C50CFED35DAF5D993B6377CF1DFC5236D51151B046F4904A02D7D51B6E331754B0E3621DE4CAFC9D8F7247788DF0EA7E6141FAC4B24608282AE29D594CEC0C82DB05C0087AB377D0D504F64F1CBB2D9F3121087AB6F35A70ECDDD15C9AD2A185C16333BB901CA069BBB0B80CB6F505FB3F382CED72CDE60FC050241B1D32818D11AC4421B66CD85D0F7B479C021AC111F8EE8F1C60B2320585EA276879AFE4034DBA277806FEEACE548CA0A5D36CFAE7B99ECB0236CF4838254A20A13A2DEAAF201B09FD027BAFC3F0C5ECA9EB5850A58C6196645F051E57B82AF4B6C2DA9441358BFD2412864950022A07542601631A00E27BCE6E203B1D3F1B844CCBB2EEF71A12AA4E725188073004849A225D733C77C068B0D2AE53E0DA6F759A8E7A5486C529B29A3EDADA69924E7DC200158DB4B612C62039B321CDACE8294DBB1A56ADC685B0B0122A4F3DE0A264F47B00C903BD30B5E4281B0C75DAC5C48E18BB0BF642F8C2CA194AE56CF7EF3B4529FB9271774108C61198A6894FC9FAF896472D1CE78DF00E714045C5F7C77DCEA45B3ED5BE5AD545D8F3833206340A5E10DD3375BDE0A068D050CB4C87E0BA95CBACBE59280BD5CABCEAFC88F5C05E3D8DCDA6B15C487B62B467E093259230D47B79F36572972BB78F90BD384255CFB1E4F1DFB7B5360EBE1230F154C3645A7A233FDDC472432F6C845CE86B078D93A5BBA3F8800C5313593D66A8A103B01377FBC5C6D5FB8A55DC71EB0BC9904B24BAD2F505D6DB5640E914D84FC71FA058902578B72C47659AC07AD4D64C3D28328D2DC8425C4039EFB2F20E3B954BD0B0483848F2C2D9528214514510CB0932F7506E9B98D0E891D8183A907FCA7AEC068B9FDF7F3479A128C6982BED19512A4271D8B682525B5028B77D6B6301181B403E5F62F64BA3CF06F0EDF321114855839E9198E5BA2A65ED952B2204809215B9BA3C366FD5C9D409BD71ACB748E653DA82EBF617D2D57C74CE37BF20AD8D789DA53C086423D86F94A96ABA379F3425554BCF92F82FBBF5C2A15947455D7D7478A84BEC6E3B9FAA14E425D2C8971DCD157C1D9E210620E891AA4304CDEC54BA7B3352556C49A172EAF19919184CA005A526349918F9A7CBFEB83510AD899BAEFD3D1F689DC3F449153597C8D21FA1C7BAF18E689B51F89B9BEF196193B7A781B96B38B9145AF7338FCFEA109542BB1719C9C8540B551A35F733C394F7831900452C0B8D36BB90824699BDB587EFCF5E8410E4ACB8ECAEC5F96E74A5DD3DCD4C85720064A14028FE768041BA1A13A46CD8A0D2C4D09E724591ADCD5EB907038853D8C92C5BA7FF57D5B54B2B324073C7CD2EACE0C521254E9E5C0CA197FDB3C1AC73FA8EDA729A858098E6F5EC11A19D4F655C6DC9AFFC4E67A49EF62D80EFBCAA383DD3DDC22C2A9B7590C16F8CF23D52392186B95EF9E947D851079C35FA11595682DF4EF4D770EB16CBC3994326B8AB3B2C279149122D178BC7B53318406738290596449D797F61B3D0CC8B11750F8D841FDD9D333A5FECC67CC7733824BBE257D40E53B43CCA19C95ACCA8FFF393533AED57D423BE0C38584A81689248BC7F78CB7FA4C94A7BDBF3015B4072B83748E55ABBF4A334AED679D89E2F18BE1B249B3F61363C79AEF6E1FB09D1948610F77A9927AD6D57BEDA02BB1E77415DD7FDD3EFC683AFB1E20C08284B620EB091974FDF8CEFBCEE1461C210E81E86B61F2D5D1882261D60D60689E39C81B981EAEBD9A42E608A34155516E4E385B86BF0A4AA05E3F99B6B3B7E401724D1442A45A696A189765BCA3240111E9259DE161DADB4E0ACFF27818C631A8A2ABD752773A83DC29CD619A58556040A7B27CF56086BD499F8B8D283683377A21BE120374B8D4561AFE781F246AD987E828FB40306366B4BF4C0B4B909ECA91DC85F521ED5869A2F2AD58C74B6C959AC71DB6F11503F026DFFF6BDE6BD70363B5B38BCA0590A5AF2A1054209A36B41B2A671293F2805568400AB282F783C356DDE30E0F87C001D9B1B9716A7C4021928253622F2DD156B3C3038A077A5768AB8AC070BBD9467E9C9630754934186BDA122CEA503F5E274EAED746065CA81A2702B582E82A33CF6CB3917D451FF59B0909E6BF847E6B610DA89AFF98B3323E1385954EDF1175C0C1B158CB905BCFD9AE7FF9389ABB9FBC5194A45DEB0570C58F31D914F9941B0242717B243ABCF5A20676051978C16FFCAA8ED2EA23B8323CD58388860DD64FA39971F9FAB83A4B248EC8161D32565917B7E6EB4937B4743C6C236E75E1747A1C83377FD1D927D385D81A9EA7F4AE5034097A0A77E2D2EB1943D3128BC0134F2D600ABB929A5281C26EDE1C12CDC80F8EAF2E893091EA274EDA1A246AEA3263E43D6C60043CFF6282AAAC620A21B523783E0CBE33F78C89D00EF8920CD53C6EC0E83DD7E1303D9B6D5280BD2BBA26376C17099758F34C22054DA031C86CC50367C81C3059114A71C565B1702981D77040B0FEC1E89436ED1896E93BA202F11ED2BA4EF33A76F86AE8E23B8FD064C8FE894244C97BA7BDA6BB56B7517C236400F591E4F28050C2958A7A79964AF233CFF8655F1603F6A0C7ACCF440D0C82D5528876721434C163D86858B02C6F6A660F53B3E45185FC7777A629C3E4392AEE4A96D900B0F19783DCB6E5028B6E56E160A37D37FACD7C3B992773ABC8AE1ACD6AD41E7340CB198C9BBEA1CDC185AEEB51E2620F0695C2691A29CBCA8E23328E84B6882A59A8C3C2A273CDBD26965564F1F1DF0B2CAF83F30E782C049DBC00596BD85426EA90ED30ED8EAE8A88C0D1363E69868E8CAE56E8DD62CB36D9A15150FE567DF7DC93CE78706BA983885155C9AF05B5FF1D0EBFD9D020BAA9196D9C871236DBEE8A703BE458938D3C882719881BD49476386387DA3508780878271C0DA821BAA1E9719E437BEE6294D8E4E2483932D0257B44B8CCD8C55028B3B7D2BB3866216A7F52CAEBFA0FBAE120609F95213BC05AE24473C98C29F4A46D985336DF8305787A0374098DB279EF0E34E6DD79BDB106EEA24E4DEEAB6DF35C58AE73FEC926174E0942D242AF0D30825274FA1D510D1C0C41FFF59A4381CCE5C6B89AF30C41733EF42E76C9CD58DEA7E881706843BA04E3A170304C551B6C801CAF9B8DA52913D2DD4DC755E0BD7C723C4AA5B001D9855236401C1014507CCB84577749DB1AF29E318241D91C4B23BD80549CD1D6E0D793E966A8A7B755552F16D3A1146B0CC6D92C8C90E97D7EC8EEE7C365697F93AF257BE24691E41F2AD26BCF47D52A1B80F5BE1C658616537630088CB6E227B0EE6EB8DB2FEC0284E58202A73CF3AEC16BAEB59D2A6E0257F0ABDE5926D9A13D89A8B2F69695BA3682E87A77DE06FF54892F56581FB16991654F60EA22856D6FF9E0BE2C4837F0C1F6C54E840F67A75185F0DE9439AB1E37D4FB3E9757B0FBD17C89DF8568755567C390032DE93E9C93E6C89B2E66E9E9D96616919D9FB461F9F33", - "signature": "E2B72659B75C1F48D3ECCE4E6543C8C79DBA860CFFCBBEFB69AF338A4816ADBA6E6673112627712B5370954A29F9C896AF05012B290C6171DA9E894EA53A94F6C87D096F6DFDC0D77ED5BBD368E4F0CA642DCF6C89462C1E694F8B9C67F641CC2859EC7289A85FA82CC1984B5FE045DA7814CA6F693D144DA720D33F1619E74E9435DAEC3B4D64888CE2525FDB063FF6C4578A3C783B364C80CF09B10D2868DA846858E742E7F5E5845C49B4694E812C39D021CFBDEC8172A6F489C8D0A5D57241A8F676CBD02446725B6B2C0A51AEC4EE63339477F0D7B7DA74B7D343AC283B6BC38D79DE45FC28E20D4BAE6D7E9DB775E4801ACD3FA93E05818031BFD882905962BBAF1A6CB0543C68A6A1232E6BFC1B820C53DDB53CBD62A849FA24BF289589C860F32F35C42F0C04C24750A47307B07BC610E1B6D7BA61FA2DF526DD836A656FCE196A8FB708DAD7F85CCDFE288E2DF71F3BBF9C0CC6F48ECAAD507AEA35FFAEE1E7DBB53FA9617583EE72DEB3DBADA8208E19C584F034D75B50F0927DA9CF2793A1218298434C32726351A48428F94A19A7A286CD99141F97301024B6CB6823A199B3EC759ACC3A7CC20D43072A5E8112ABCDDA6A17C1D9DA1FEB4552B07575FCA4B697EB8165BD0DE2403AE19DE5CBD60FB21059010C3C4D2B0DCD918321DBD7F94D59E0B08825872083FF50847A3457ABB30C5C32E4DF9735553FECC558412A22D46A165AF38A07CE0E2E1F888A5DAA2F9D39870F008E38291208F7D2FE2D75BB4E5B6DBB16662A1DEFBE0C4145CF91BD2E66A670DA776993F60A4757CA5BA0C55BADBDB1C0BE86D290D3F00EE241243CBB9CDF5B3A93DAF95840C55320B931C6E3EC9389B117E7BBF23EB6192965AF97DFC89EA6D2580A9CA0C699A66E22FB7354F203FEFFDC4934251A8488A15C3491C3C6E5DAE8C828EE56D97723C83164AD15437B62F4B06133402A3F1A261D08F6091CC5C46C517DA95717FE632FCE49C659D93BE9417AD1507315915F1C48F20A66F5F08352C83E75775D27F76B1DD73961D50F289391FE376977817D12D7C9591FA2832AC84EB00A8286841812F8C120EBEF5FA71F79AC3CE6C77862D2121B4B21A33459566998CDFF4A0E614CD6CB72F5AA2643A3A61D8104CCFB041E94D433AC6D10352049B4C104005191284CC9B23942D90F3C53D05DF898394EEE9E041B735BBC85F20D454ADBC84D3769412F5E6B06303C503BF1C29E43F93AC993BCFC20250A38BD862E7348AEE4E693B1F99FAAD7B7E8D3F5AC1CF8A192D894AA3BDC356106F4C212954B25D86EDF4FE97ABA3030EB20A9DD48CAAB2955F830523745B0208EA35AE42AE06383F8CDAD8E66D5A988D95D1DCD310C9A6AC53DC448AA80B21B78C2CCF3E46B447EE9E9E0E090BB6DBC1AA4D5A6444283CCD5E01438CD92226A4FEFA67EBE63480AA072FAB17BFC0FB0E0901B5DADB7C29631B3E3022574889681478E02D5C81B7C676122A1E7AE441D16E090D5EE64A17033D0D0C6953324C5E476C652922FF1F1E47F833C3FB1705E5CAEC5B57AB93D192CDAF9CA712AC0BA70F36D71A37D366BD80A7BB3E382EA87EC5A1F6B281C01F8667C4100906D713B83DB6A50C8C527846EB728B173CEB9B6791845C7749AFFB6C72F362CF602D70452512C76DDE9D1E76988F3C6EB14B43EF02D1081E6FD446576CE727DE20F6B25214DAB404B4D77ED2DA703DFC0E4219D44CDE16F596025C9E90BC0B52649AE81E95990EAA115368A9C6B16F64099C8B928EA42168CFC544445847EC42FCFDE6095FFAECFEA31515FA4970B27649C81B49B4AEC86D1329EB1F5B5AD04851651BAE0236C267728F1B0B8939B0849D9CDA009535E066990C664F160F5B8387D93CCA6DC94C8AC8E5A161F0D4E71417F43775F7AAB83550BA7DF60AB7D58DA72205F6F52F98A5B73C6608EE34ED7758D15AE7360832F929B73E8041B35D4D428FFCA023781B26EB65C8D3A5394B8EDB1A23EF228850F32C19E8C8638F6E3E8D64BA7346AA7BE8356CD61C0648F19FF1E959951A2B92B635588FA51CFEDCE28FE0EFF9B00EE81675223A8EADE3476EDF74D688C57C68E78FE3557D97198D74648CB71FB218A056165590A03E4AE830E8DAE1FBDE2B65964A2A9DFDD75E7FEF4C11842DDD8DE5B7ED553940AD6C74EB10802F5607668192FA7138E385CA14C99DE873F48837FF593F5EAAC30FC7AEE7FD0CBAAE64447EFFBA244AA0DB2CF145030EA2CB6738D95DF990E8B6B981675ACF4C4CA0DA779BEF86116AEB5CA18010CCC8F971151C5B61E2C106C5DD38CB9F7122AC17222163EBEEF8FC9DB9FBFE8F9631996537DFB7B7080A466CE52EF5459315ADA3C8E8D748CE5BBC02D326D676247D8F6207AFCFF6B9877B4ED1082C283A27B8612EE26C9EC76415C14393ABF8FF2F8E54C62CD56AFAE745FA698EFAB0AE19C4F1BABBAB440B71DE8510B7B664A9B9F8F80C4DD125549C0546D4D42CC39022D1BB599BCE77D24B4AB8EB1392C7B0160C9BD376B3FCF822B3DB1DD6E61A3EA2C5369C7C1DDBE7238015196154B94201F935CDB203D8D82C29DB4846ECD7F99E8A8FAFA204C5C800D7A6D0E15791E197E86AF298116E2E4BBAA7365A51CE82AB819B2343B05DE001EAD2E0939F8D21CE2482F65686E5B1DB274DBD223E97F0D094CD4E69A198751CA2AEFA95C937EAF7A52245D560F9126EB4B9F5EE30A119584AABF46AF32D0507E1F7D78175A919CE7678B8A120E169D502B02D9802C02FAFBBD5437EBC4EC674E21DEFA246A471ED242326B523917DFE2E41C1D77AD867D64C09E711CECDCEA9028BA620FD799209A93BFCB7E36EEA2971F977E99326F2F54387752BD19EA29C90CA3C09D9A02740551EDA36D7687CEF24A6D35878B44235E8147D1B752C2BC56BDC86B41588522881E7A9E290B0B2D2B2EA2F56A3C770C7BC2C144F0CAC497C181B0823BC6BE8387FA22A448A9EA92BC4DF5F6CFC946705F20D4C1091CD96C67206DC804969225C0CB11A4A1B476EB557AFEE3AF5A18E763080E723A60359325053C16BADEE646244148DBED40C598A8DE738F5546CDE8ECF09FB14ECD37E7F9A5B622701D92147C32D324FF9525BFB30E85305D0A4EE82DE52BAD8AD6A5D66BECE7002C115B954DEF31F9DDC7E87AF4C37552CE4027606044AE792882750C8ADD98B6ACFBCA0C087ED65276884642FED7AA393B7ABB5C35EB7F3A4922D97EE16AFC0043A21495D1D1D269327F9DFA44195E205F6603234B067C20D09229772354041771CD1AFB30F11981B6027DA1B3A6F465300AC5C0E41FBDEF7D0DDB432DE67C814B76A7733C5A84637E56D7D620AB3B37EEB81DF16093B5612D784873F84E6AB6E28827625F1981AE31E3F78BC4F68F215F4145FFD9530DDA56FB1F67BFC6ACE5C647F0D3CCB2A8255449638A65E3F070FC200B7CEC52C370A86C02188B3F8BD809227F08021C1CFF8583DC561EC62CAF8C2CF878A25C8C62004E4803C15837F2A8FB76A2FF611CDB597B793363F9F1A02D2026E2A87FF4BAAD424D44B24BAAF7472E36ECCEB0AB87359AB317F880E5E112EAB060D8B1A6EAB5C135D5458E628F43F054C8CF2D19966319A9894135FFBDC0E5035A1D2B4418E466C8556DC71348A34082B07C6725B8963F97D2003BCC9E4208F4B28EBA007973C582E9FB315BA0AE288332B94495E2436CB94CB705C8763FFC696894CD2825ADF31FAEA196F6C23176FA6D2499944131F09F07A6F86B1518092B51DCCFF01969F669F5FF0F8E16FFFD044C2D2DCC0E76E7762C0A0109F7C9EEF834F1584220FAD95FB4CA00D649683D15454CE7E797B6F28F195878F5F42900EAE1C1B339489141D39EC56411AC205AF6B4E0D00A58AEA1B43BE74B5B5930ACC43BA774032E7E3868F4208C9420FD59D3CCE11AF933F964AF0A703F7D73A568C89AD1AA9297D82A606E94350C13819607711659F1972611AA5EDB0B061BE6E1C0FE17BED2D0A3AC80963DBA3A28F0ACFB9DF8852573B35EE8975364A9DBF85A32952488CE99CAFDAE4584ED43E00668E531C5CE7D69DB910CEC52DBAF374A73CA22CB194984F1BED01224372675B892A8FA7426BD2EABC723ABF439C15C1421357BB3296C5B4027A4E2873D5CDEB60176B299AA06A37A9E86B96C91EA0F4CE7A32D1A13F453526C38163291B7D1EB78A7C7509FD4AD09EE2B73EED7B48BD6B8864DFF71861165F7141DD3032EF27312753EEF75AA1CD075FA76756D54F1049B3FC7E2B6CCC5A40D8A77E38D1576CD95F9CC7CCF8083CBD348CA2C50DEEFF4D6BE391E49C8704AFFF70B0FD6C978B1688E000A254EDA045A682B27166645B17803AFE2E794545A7877909C584D3D8E58BB6B0BAE76B4700B9747AAF426266A65891516A276485EE9E0A570DA8AA36C5879B0E23C9D3B3165F46648ABFEBD65F1F82C6D8891D1FE47D51E777AAD299BFF8F5A636C30CFBBACDBE423FEA9D93250C6207121B0D7D2122C6D5E8F6877A6C05DDB2401E997FD18DFEA68993ECC9522E1D9FA0B2F4CA779B6B11EDD658A6AEC05CEADBE69CEC2792669F180558B235C295082EA9E20E65AF03638A50C000C657B8E919FD7E3F1F8265E99A2ACB9CDF93F4D72A615454F6D8EBBCC1D5D5E6CCD447579B2EF000000000000000000000000000000000A12161D2227" - }, - { - "tcId": 24, - "deferred": false, - "sk": "C76D6626F120F0DC3DC1A840BFA94FFA317233CE5DA1323B24005FB7EE273AAB58D8935C11BA583F58DC10BF321EE6A9C86C1290EC27382858306C4DDC149661245F19CAC304C002479EBA3FBE8203B10F8EB866F84C4BA964C33BE17DEB9A3F70D0BEBB6D69931B7A5C8D7F4F453D4B7583D6648A2D9CCCF3BA555790EB3BD1367456382700517316272745263777343070578043772431812488504440335421634222648265848838121837353786020831856580712415333215302208147066378168632077260742828733501307547176277560372528436054511866171224212737853618516810286575524353052360560431827317050484274631523727443076623201205630176106647063024526654105775786876227221382811315183175187688715152251718801634644008352335346173270831466732388742751781744268285136885233676618075730644567376260056046801283118368127378730400864858860423178431432174024128156430042136886878305255512578456815567452271245453668030586055385062026711530033343383475108202713263083330656287828016636402607650813442327778368023726478448081481213123878572853738681808620411477010631062247480543800734826263723435866084563460834818022430110577037880375342662814256421633255877085434152814408536434148614146707002044162035858310133662324605536663662033473105060631775853077483602002225412581468165821865661211467268147103283132171232547477287443230241240757844153615762424741301722062267472747003826503885544682608118155735313865325848302455485634756018273820137345741727418745261488050677330138546833853508746107616788711375147727451830073522165114147383877083481400123163777662262788355285502510077451133068444362310516824714022346257785811584806148226560441060227752554564772478727583156451406704238688634583166663607688238257518812813555154445780176360300350404665741672685880004215010272888675646851148358423071453520360300388050250721351241676211305457044364015801141683044422561272606177463587455738363783408862388284722643833723114756406862376370330214001874826214622708084084002025636767831375160242480502832474732411157747428683178362313332364104274857216211278653233102730780172388640555127240368788380054832243460744682438112304407528808054840554628757808453602377264441116235321564084234171882453426885776378241812475187760357460162405285166613408735655768736813085162678146372876548208588416884845602213600238752455130070756438507443718730864058241676520223100778537466617861873171267335652236024385153037355153660707083178885813007345133271161552764051576616612614573437834476747524844652344312488386640172186252053064230424402062806207278026457241843213823223578630525753080343552186870662772512780561337726815780880748104546146704251635867710255085600275752004733518051655028507656643504277361001831655542464863821714055377458781574581878347750535822404730758788652635060486802627610003565431211741182688234752636126335334361107773262121051470658880873527267780287051622324420455244182713745723520882604160088777146578781102532430655862124224627601834385720032400151863686860466774444313130150443305816566373132477054681352205101436236160183731116027810540738716405756418031728372050026377227020873522458211520648153707830512024387354646073575114450322344315407165806830058732AE7BFDD687A48F0383438F5D34FA545227619047718BB592AAA4511C13CB8B554321352A460C2EFF5C24A42C8A397E0BFF652AF19AE7C99F1EACDA43AB86B4F77A6ADE00B473C7F268E999E76BF3B5355B2309CD95776C48D7E25EFE74BB83173C3B81BEBCB724E1315EEBE3D5DD2BCC834E74E411ABA98F9F0323AB583B41E42ACE6205B48BAD7CF266F639DD2C82208AF0EA64FF0C1EE76E13309140A42B755C21B8AEFB23C4FC79AED0B81DBB4031886982D1D9D218E6AA8C547D117B8B2C477318268AF238687527D4E30D7414E10922F58D7C71ABA68ADDC54F34DF14F7A405CAD7E407DC42113EC1B4161FFAC3CE571C1828B287D55A0FCAFC14C2CF1A0645DC8116B55E34BD9CA049CDB60C27D914D676D0869D33E0DDBDBEB7F31DDF7BEEB59AC7D6A62F7F42DCDAC5C0B20D1E7BB4DB4589E21089E541766C4BDCCCA807C3825AF0EE7AACC7390F7A8B689A825F9AAEC2F644E24920E95FBFB117866D67387C0A46A730423A80CEFAC3D164A3AF5EE17D84FF2E7B783D1AC74362D483EDB69EDDA4365CEC01271172A08BA2C88FE98D47F52684CD7351ABE2958AF5D3EF796AEA4A5B5EDFBC9BF3081E4DADB42BCEE2A6477B7C599BB40051532EC96D0FFA2930BCF1D6B077F619C4247FF89842BE8B3D72E62C0A1B6702ABCA1C1656F2BA66EF804207EE0DE06E1E4299198ECDA8E5A96A245EE9B717D5A79F5478AE5B5BCCF8B8D3629EBCA8258A2F00D88A12A34FD0B0AA5EAD5A74783617E9109C8596F605DF1038702966175AD2367B5B9B1AD40B4D49ADD943FFFC22717BB13AFEBB8CBEB3A7B769A5BBEE0891E03916507A0FF8297C4A91F73A9D03774BD41ECA62701B0A1D15A20CD5B4E9C156A004047A0D1E57F593E6C5C3DE54FFB17A60912AF5A5659339CF9D6969D3AD72EFFCC3160D8B4039DD6143D8C77F0EDB668E44991E2819FB01935BA4DFB5D48E1D8601C8D4D8A17F7A6007C92D95565369A88E1E1CCF781766CE012605607A7F75030E3829CA5F0774BA2F5F57C62FFB9A7522FC152F64C4862CC0C9E49A10B0013F19205E3DE1BFFB88CD76228B101180429B2CD679872E53C573BAACE27610F291FA2C021B0E5D1814A23ED34BD3190E3F6A2B6CCFFEF42EE2F0B5C669B6D23E7BC699D8E785A8436A852D6E8503C8165C27362F246BC26546D5CDEBD5E5C9C268ADA0A3ABAE1D7CD250BFC59CBA4B500D9118356AB49316D7C24AF1E1673E4970834132C5134F2F1B59C45ADD894935211F8026C714B0DD6B2C2DB08D3FFA5A347A3206BFA8D9F8F49A332912FA4DDA18B1301D004BBD6DFAB19DA9FB4F851E6622F99F62FD6008DAD1C03353B619646CC869A8396914D7B7D0065CC4A3539CCB833CCD62507DEAAE15A3A49D1ED997E53A86EBCF08C64FA9F724CDFA0F4D24DC8890F77793DC962BCC4EC48E1C2DB60C88CBB23E5E9D046AEF98341EBD2D30260CE8B318894C1E276EB7849FD777271B6471E716642DF70BDEAB121B03CBF901A171127E448F7E34C161D015BC661063156B702A5B08FE53A1899DC650C37ABB75F8BC4F0E2F03E84D6A7A2E882DE68BB78022F771EC6433D540912358E185AF67DBFC36713707B4DC0FDD6FD2EC615BEC33BE08C8C9E9E436BEB31FFF5EACA3F2661E64A0AB24D0D8B80271C5C658F5D224F98DA322FC68A21D3E547F0F4EC78566C172BE2683993EE8AE09920A412B04905D54AEDB5D92CB257E113AB3D4C4C1CD47DADDC09A00417D2E4A9923E5BD8EDAF73E4B89831ECDA7BF8299AA149383082CF1B0AE388063E115836AD8B1DFB9E6A1C9D254F02DB05D5099D6994EA253605DACC9A5AB52324324AB3B645CEC06C6F57514D2D03A4DB3474EF58EB37C86D27D2598DC58CFD2371A18D0D5EF241F1E5F5B100FEDC33B5677CED61B3DD091C5AA1252B1E681CBFC124CBBDBF5CAA841235296009AA08CD067EEFB12E403027DB735AC59231D6E1C068D180ACA2F3C8BC0D2ED552BC4F0AC5B5A401F52C7D66BA6D7E50EA96E66CFBFAE392840870720D14A4698E05E741605BFBE7EECD1B03657A10B180E253D23AA6750F1EAA6328F40A6864A30D2082C8CBB4AD86113C205CFCFBB93BB80108D63BF2CF7432EB1632D37441A92FB5953813CD740715C2D14EBB2B6D569CECD0AA2F3D4D681AF6EB9CCDFCA85E72A3B8DCAD00960154D350FAD1046F4A1C3893B0AD1B261BF669650C62A0EC134DA899B0136CABBCEFB31D9DF32D51B929148836200F9D51AE7EFCCB7C113B2DC8891F0593A464CC9906DCD18436366DEE53E87BE3153A241742FDF35EAEF168961400E150246DA42F8BF9804DEBFD51DEB5B4FE1681E44FFF181CE44D71A6204BFAD321B3ECFDDABC3DEE87D2C33C7AA2AD6B9C78E034A1E19F255400FC032AB7AFA02A002B9603EF7CA090117108183C49D5436FFBC7B471754915F5D9CC154FBAE4A9A9F0928A50C06020181DA8ADFCF371EF51903ACD6FD56EDFE624FEE35A63BDE5CBCA7DC3308176E599E3B95D7F137E9DE519B417661AF3DF7568FD76A1D34A8EB21038A23B9C62E5E46DA52DEC95EBF680CF8BE166CB674D65682BEE3FE368F082DC4F368738F83E2D333EA1DEE7B2A6F815403897F5AD6C1E710BD46EEFD5D743B79EDF135B0451A18FD60070278D852C302D0D026C2F2BEDE0EBB9D016F9B817D90914F1E3F875259B80D1DF60C28AC231155377D3A2341C4AC4A871857263B0C2DA6FAD157DB9F85CE3ABCD6F769F46249BAB9753339B2076C23549A68F5F29F8A74BA874DA2806D7E4EC1F61BCA6E11C2E15EA64E8728D9B9ED08246A31DF3087F8394A9D925551F4601AC957DA056FAD48919B10951E5CE56217B11C6DC89C25F2DD06095A820BF63E4B53CF80EA8C836062822A59BD726A19BE405854E232BC0D6DF7F9315793B89E9E10D00E9C48698328B170B9A7F95B2ED96CF0CE99E0D1F18D1C73E6545C8E9F717F722A07286025AC8DBD6C2567E21DB5968BB4D7F33A49079B2D4C3956508E58D812F687A7E4FF07065BA76846E70FB42733C56D948559E50CBAA00E1503D1EF447117994EB8FF0BCACA06F91FF312351632CD6755D0703A7E3B0DA03C37B98159078DC9B8F4CF17659B0773F0501E2BF177F882FD017FE74CF9C34A6F013D44C7D2986E9CD29D444B98E26584942747EAA79949EF3C6724A218DA9D820E68C62B64293EB1468E5CEF3A9BA007D5345EE1E5251E7075B84EE3B060B1E9AF2843AE46B4681753322D7906A6E849368EBE27A3C98F9BA0FC74D3CB472D511A78B50BACA9850C4E59620B35318B8978F697D79439E2E2A30BC41C67F41BFAFC6B9F8D8C2D8FFE8EBDC3910EAD15F01CD2B1A9571C02AE0FA9189A50CAF1D6864AF684FF0C9F05E0E8830A49BFA0872C92EA8F6D9445258EDB6FDCB437601B4EFA9CBE3AC1390995FE8BDC1D54073B16DF60018E904F2D23E029CEC4A4DE94A356CB99A44F2F314B9030683CA19AB7402701E8C4225BD284BA1166C3B181701F9A47B6C999D69AA5AB0", - "message": "320D1B2976A4A4673900C7B75B23EDBC25B9AE867FBB79B55B29B3780EAE8C159A3AFAA47CF1D9E452CAA8EDDA3304BBAC47EFDCF96CE92DB1981A5088F731E1EDA1EA5FDE9A031595A8F268E92B4D75793C6F408F79B78599D93E80066F8C4432911828A87EF71C877F55B1F18207F01820C0153B647205CA93DDD6B78B94EB59E3EAF01B66953951ABA4027F811877B0F60C9A5AE6281D82348E3EB749C82C81D53309F9B7E624BB1BFC6382F43A58D1951F7FB716C08DEDE4A8028B50544D0F26F7B9DAEA0CD075C3B11B7315022A37198F0C96D752798E0EF406875CE86C367079841F717261A2B6570A8F4F9BE1EA305E73BC8BBD88AB162B4D4BAE86CCCD406A0FF6ED5A968D4C985460FD8FBA5B3FB40E29B6ACA07F70717A0700AD3A0BB7081E09F7219F3F8829692C3DF91C90334DF9E89284D65F7406188C9A1EB7B5C491591A20EDA9399DA1AE8C0C158588FE1426B763FE9D11223FF7A05A3DE036B67541C2811AA459045CE73096F89E6BA672CA7A546D2B0554DB35C547AD9585D14485AA812BFBC88F7B248E03F2EC57043F4DEFC2B27A3B20C2EE7CE334D428EAEB228350A3ABF4628C2DCFA84BC7435818F91CD67F70F3C7D54E2C205E55BC4ACCDACB354470FD5C246F32A542106EEE0EDB38F01FF5C4B657C7C1A00718D2BFD311B8BAB6523351E93CCB44274B8F96EE343830148F5C8594818777C1E798EFB45AF1D2A75D22470B4D7F7C7A5938DF3F8288A0088719C4E36018D9993F9E69B8469E5F2ACF1977D441B82E5340E5AD5B21B66051513553BA1BA1C1D5F788C47CD3BC60079300F6E3D9F13EDAD4DF8521EDD022031A3D74A6A5F32AC6FC51C67F920233C5079A2B44BA7B8EC6DCF9AD4667BD26BD07567E078267A1BF44B15E68B71AD38226EDDF138D2A599944F70D47B26F775BB97D9966845AB3E6AEB96E1414D3BDE94160B6DF19E03BA1BD0361354E5078B3C5733B740314E2DCCCF8F4C9CB179DA62D5C982B223CCEF5F29D7B673680DFA2823A2BB279EA45D98CD91BE7D52E3E386B98B62DF3FAEDF025B55F49EE6FB5E8DFC9F70A4F093EE3898B25102CF3AA52E669D6EC69BF6C79457BBBB7CECF65B1E948DA808025A242841FEC6073326BE16C2D1953209F31BA4A772FF24BC30376EB994398D4177FFFBCF78C9A79B7F1746D077AD146514A2DE0AF9800255F3A11BA661765A7D8E8E7FE5FA46BCD1269E278555186D4BDDD03FEEB70BDFF7E5F616259ACE39969CABE8D4F8F23544918516C977F84C09D6A6749B1CE719676378E82F9B4E563D67AF7D911233F2527B5CC5D0733360CE15A173F10B91360A3CFB08EB44A09157559A0CE8B661AB4A97803C52F156627C642CD02CA5BBC7648833F2CD7E99D2A7AFB736E5AFC4FAE5DE19ACD2F5CE3E3FC887852758411E8C7FBCADB1578964445332113F963AF3E944286DC448471125E55A46D2DE35E9C0F6DD10A3BE4F1E4BDDE51A16F4239A1F6A535D3202055990606C0065C542297D490553204A6E3CA16A7FC9A1D77191E5C01C1507A332C659FD6B11FAE088BBA796F18886195A2B8F5B0064D85F56FB7256F0FE70E9C06ED18B7C8A75ED97A1DF482908D2E3E8D6BE8D0EC8020451C687D10F829257F3D09FC47C7EF008B89E2312792A25EEDC71E9835674CA50235E0A6C832E7BBAB458725EE7BF65D26A0501C91835625C330B0F8B4D46A0762F7773D2415A0DCA573B47EB8658F9EBFD26D9F6EAE9D7A7304BC690F8D2F60C33F8A7D19B52F9340BFCB2FFDC92A7F9ABF85E3352E46ED7591F354A9E19B70A3B247E3E4295E45B6A2CEB59B120B6758654BAAFED2120B226FA778FAE5350E756741093083E4E56A84B64739695C1C09EE39DEEF11D7E5BB7866C90FC9C96CEA071FF82F145592443BBCD6B7CE848839B641C4522016945F711E86152820275A6E16BDF296D34AB38CFF06A63756DAFF7BF230F024DA00C4128F025F091F4341620E0EA883042BE731E82D21DBA6EE737D90346B6189697CBF41F7C2BA7C9CBA20E14D26CA578FB05E92798D57C0060951BDDCA5D96322AF35D80013B48A79AB7684E1E1B040315A350DCF84389E54C054AC4C3428123E01C2FD66FBB2C5BE2D16B22BAB805AB59DF205B71764E4AC9BD4B2D872B8905DA230623C65DD235FEC253468E53928722D1F04C486B46E63FE63441F11B1E3617E9765D4F388D4A2B68B6C86C8E20FE0F3C48A561A0FF5070455C43A7FDAEB58ACFD4BF51A1C37B7751ED37BBC73B9C29DC4FAFD0A8F5FC98C7FF02B404AC08A0728FA82A5ADA4EDC195E679D88187F58004844065F281A67FF0A2BE0AF94D5C97ACFD43683AC721045FEF8C36DEBA2E3EFA248DA65837046B62BD6CCEA84CB1211C5893B0C5F0A5922A989CF7ED093D5D706657AA6E79EF3FAD0959DF594B9CFBE779", - "signature": "84D8CFC8120CB598A6A1CED91FEAD8FFC224C59781A421E85F7A3309F74877B526A3A2576A41A17D71229A5864953B5591878A53BA64C10E88A4F77811D5641E03E445B7BC3AAD9526EC4ED3604A371D1170618F672520C76B18148D3895386C1B9ED1746E0977C32DA44425B4737668BAB427F516B4552F5F11EC62A824FFF1EE50F0F03E01E7412CDE699F8A135D9845C7F1C4D33B806527574920AF2381C4AFA8F7E0673D1D76F6D03BBB5C3BC027ADC84B7D34DFB4DAF2D9BAAA9AAD4D443B195F350DD83A96CA96DCFD2673AF4B3425FEF1928085FAFC728DAB0374CCB14FA411A5FA2F77308BD43D44DF732E0984F7076CCDF6C2C42D0876166CC47050983FEF8800160933B87733C0B766F013947382A3593DE93F604A9A5DDA9BA4EF09954EFC9A8E6C0D90454B7F5C79140206204091D82923054A5D7BC76BA2D8BB3B17A7BCD027209965E125CC8DA21C4EBDBB4E84C342735F4C15705261CD9055FB4FA98309B45C91B92DBE2872D6F95B83243F6F92533C8E52EDB05147AD030A7ED059A3D6E6645EACFFBE84387C88AF178EBBA7ACE86F8BED1F18C04B1DB3F81721CB005D92DAD11E3D03418D3319CFDC4FC31E41917D3B34B3ACC7DB8E4B1D77884F97AAE2D71B202623F95308609A890942936E0740F53A48D036CF3991047F98CAC74E8B753779AA1EC926CF23886E0F7088EC0F1FB6B0D3F8FE587BF56B00116E84FC8D50D663B542B096186CCDEE2C04CFEC253EB84CAA2CFCE5104B667EAA7ACC31FB1D91C16DABF1A5D60704F46AC26B2E6EE4F93817824714D472FDB8407B32622562757F2F845731F5525FDD975472829D1D98C47B8B2A74BA72756B807A0DF17F4095508D4944F4F5CA1447B056E952B0A49AC3FBEDEDB06967A27E452966A6EC426EBE72BCE9D73FEF60C2B7BE7427DA1890A56F2D88F744DCE406BBDFE360D7C08F71016D2A84607F655A862C0C9020550E1FB87C45B85FC1501EF062DBEC20A7256904F9D5309191536A8814E4DBCCA28C40F34897A49A98AFB645F3EF246E2CDF4DF43070E8E61377B6D70B146F955A4EFCC98BAEBC3F1C621810D796D7B1BA0E9A441E56DCCA92AF85CA2834AE49207ED3B36E10178A7DA4921AD35DCFE3C4FA522D138E015D2447A3DCD35A25772C3B1439C871745844E05D5A266AC1C7253935FC43B6EE1DA7988C0D1BCB775ACCD20DACF4CBAA0671171337BB71E7D95A625F1BB66E3298BD5B8130BACE336B34C3756F62A0932FACA9AC3BAECE59D77D79F85AC4582E527D3AD47D230B1AF26833EDF2968DE208553B3167D7185CF60B4B4C08A0587496B56D9133BBF3513C20EB29A334290C46FB8C4461E81DCAA82D2413F8522DD889A4189306AE720736C875EB797E794839DE3619DCB6AD8A548CE43EF71AA16559350CDDE6218D044A059A8BB4D9826503539306469BE45FDAF3917B0A3A6450DD11BE8EF9F59DB8BFF8A337155A63CD20910EF598B208C14A2774D2FC55301F9CD3C8FB73DC5C1D30CB072D7E098B92D6ACE1BA78B3A10168CA4E8C1D44D95052AB5C1A7439A99D98C50A924ECEEECABD1437E4DEA5E7BB83AA5A3FDE2C98E019749EE0AFCA2681EC2C799C69F581859B28D2D346EF2FB97102A69F030B6F53F21FD655EC0F5CB34B3D363586148C443167C6CA47DE98835DBA80A092B9410B26BD023DA9E053981898215FFA735599AD0DEE853D374D6BCF0A0171FA56459C4536A7D2FF8DE6EA0C362C157D594101F9A860B800E5307DA8411E0E1468BF025092CBD1C607D9780CA3DCF070F5D949BFDE60E0BCF8267AFB9E04D5C2CC339CDCB1876C818CFE60F89F78681A8E82D36F26FE6260AE1A9E74355C0049C84C39A0333C01E77D1AE8E87F6BC96B0EF90B825188F784859F5390989C212E5CC5B829FA184E5BCA76B0B402195F4EC532931C788416811A029F492CF5B2D633F06ACD8104155D947E88AC08CAE86DF2F64F79E3AF8C82B9FF3834875DF69F1D381971003E0771F64FB343FFAE807C9C0D4A0273EFC11AF203EADE2D9F2682C918E2662EF2D6AE1B6E8A397B3FB62130BD629E315C59D1F0EADCA1BAC8CB6F067F10F6B13D70F70C3881E8382F20026746C6175F14A2331FAD83ABF256734FF7A970495B1F6B5B1CB2505B621D406B944BB5CDCE22BD9E88FBFD41F8B49C794B0022A456493D411B1B8F59D6A52E7B9CA786814F215C39F0A4D53285FA10097C151293054632C326E210110CE3CD03B7432CE2B1133FDEAC806CAEFB45A37CFC12F98AD0BF76ACE2C347ABA12A77D5DFDF6658C2228304FCD265653894C6696AB17E8103A8E23C397DB684BF632FAFEBE420B3EC111C08BE7DF73A7F763A82F01B120D326A98E92EE34144CB6C7ED15472F2C860D25A6739D925734C2CB6EE02198E96DA851860489A5F9C056C5AA2B5A90D31E7E115F32EB8285339D96124D3830F60E2E91715BA1C12856C1E25B8C59AFBE7B446F43F1B4154F8F786935E5402DC55E7BCAAE8ABADE43435DBD01F78BB882418BE11FF1893D54B5A83D6220F4E86D7CAF49E1B2EDFD6CEB82DCAD8A982BACD2DB15A66E7D0FB4652A920C339DA25B19D37715ECCF886D900D785E5E77E9AF53589DC5E785B2D5279AAE870F86E4701125FC316EFEC0D5CBC411D5ADAC374124521469ECD10832AA4257E2D8906358BF2788654DEB5D9E70798571B965376250C33706E78441465CC2563A9D2F70DA579FF7C4C715296F72562DFD9951120AEBD94D4F08212647F08B4871B6C4E31CB869A8CE1301DF60F88A517356E56189D61ED484C32718A9D37B6BD1FAB1FA39AA1147735BABEFD166712AAA617516D8CE2A984D90C73565ABF5DB9A46346FBE7AC465C81934F5D92735D30594C71AE239B2FF5C2DB72920E7A59B487DB9E363C594E34D9F250D7FA3E8DF4F8A07FEABF07D7BE68D6E03333B6947B1EC087F16C1DE3B0C5596043D4DD62770605DD89F11360A10F2320170084EFE8DA7E10E128D0E90D25623324F8B32839A96690CB33F6FF05E584C860251AA02CE00825B9F775F24E75AA788F98FA5BB7400E31362534EF1E8D310FDC0272F4E84C820E799007AA5351717BE6B06711BF9DED0CC7F96A0AFF9DC4BAF7F1F2D19BED2F24A7DD8DD1A171649F19B134C0F27CC458AEB79274DC155A9E3A267E200EBD328C16AC4892EEDC748BF522C0964E003793C0A6283528CD09456476677FB152B6DD0EBD86A410231191D86A0C4C19027F79F4615C665A75E7350CBA43D5A43A609F9C4155B7D2991250A6AA4912532B2081AE7ED0E72CA8982A5E16FAF25D622E060FF7C7639A1401B39BBADDEF2D1BC3E600ADE38A5540015C6D99769175DA7948C1636FF28B8D739E65B0E3DD43D5F25853309CF5DA4722DB29184EDC0294BB966D023093BBB10FE6A9A17F8A37608FD3FEB1878C02068BFE295FB809DBA10046D57C50D1A5515A3F4099F98F8262DA6DA7E64C0A2B662DE9F58C7F0CBF6B95AFBF75708F3B70A73A7D30EEC7B2C897ED420275B1D3DA2B0D94D689E21166E3B42B942DA7566966C9C78BFA7C64A7D0CC3CE47213B2C1D3D0E75EE00AB186CEBF88BE2C1C042253F48E2642DF054EBECCD82A02DACF3CA849335AE09789A705D23C1B49ABA88BB60ECC05F70BF02B067470802447159456D4DBC7451E41D034306F3A40AA9280C63DC86D5ABE401B64B48293B49C3A4119A966F652CD00B32342CF603A3D02E8F829E97ABA53B035C3C72D2EAF8F9DBFBB83D61B5E13F721C719B3D6E963E68CD0A6FB792DEABFD08ED01ED50A407B4C3EA558BAD59A9EB0CF8D5501A75A11053DE46D2899323B2AEF99A6308D64ACDD681A256DEF931C7E5F488D8878950F0637D478BD665B9C8AD85816E3B8F9C586034E1DD2381BB2F8130CCAABEC2F43D455F5150F83F160F9E43DDD4247424ED273F31F07EA12099B0E5FC35998A6811C8CD1825F8A1687AF77836165DE0BA2438275DE291B65C90DA0CD5880F95C8C8CC0F256FD0B1A9F9209C659A031AACC5D0FE8B0DF5A4E9D9EFEF76ED7624E9ABD6361F0772ABE1CBD5F78FE6F872CE769A817F4F3195E65CCBC3FB2F9BA021023585EB4F43F471EF4307AF047142D79BDADC744EEAB4CFCF8FDC682462985F828A5CB69483076EF94D6C6634000BAC9B75529594261E3893F832DA297FA448EEB8D098166732671773CE215F777ED8B16C6511D47216BA200CB3082540D6323F9726BC4CBDC1A89D9698A49EFFC5B3928461746597F24991A5212547888DF1AA6F6BE3D1AB887190F3EECC6DC4E9B0B4E4672CED38B5DDBD3C00DF9461FD62637B3D7FCD361C41EEC7641024382C378F15BA8A14C1BE3E47C4301624C354EF8D10CD26E354385B7C477F355FFB8998E9AB2E2C0C2FB2E3E466A1971ADD49B31C6A6F1E9C0ED9348A337D995A08C65C1E58C950558A4139D3274872FEDACBBBF77B4EE9D2C54F9A6142AC8A2058C2EAD0606BB37A6B141CFD97C9780DDA16D54A5ECD9EAFC53576A00CCF909F3484B64E37AD1F63334F39B94EF033B647B68E1FBF3A0BFED69FD8877FC22C048D4C15A8282FC2B602D3B1021CA6B9A7E844B065C62B0CBD7FE328F9FB5DC23BCF50A11558290A8B5C1F642586C7A859194A0A7C2FDFE0F4352555C60637A86A6B1D800000000000000070C0F182430" - }, - { - "tcId": 25, - "deferred": false, - "sk": "05F78DFB8DD95ECCB19A4E223909896CC6A32086977EF3ED299269E51878BE84D29086725EBC30BAACD7C10F04AC9B3037B7407C63D36864E577A8FFBE89D9174A2ACC4183D106E7F478109F5ECC2160C0583253D7287E39F2BE1E1FF6DBC0127A322CA8E2BD20BA4419405CD8950831BAE2E4F854DCE2828025369A1FB3F07E77878741641453852638027541273502161744187110423466885282676035866631880680212377455761475822537381311428256306028053075841275812862151082114225553333632208035118820600216464008332253350051356421018671288648082042327826524064231463461787457445340458144872151441075521254341210228484201564136088803605035560122810660262424606074018703052055371555875382226471026530180032600112827753232300073074181386480534164225448647716638448527736082708564276203618062484286666008357240756656266712700838805173838263510506272540177577752234807311255185168734122463815356405123855254518275503443802574060346470206813526234734131654288881363708638820352751020216175724418860014818114623484543247618186431467841145500584206376100245427354377078068051005766127458621211151260165633001348137530712602370312371232020175626206103837672301778747622163741706566121434014071278363537881306583436007681866270754208381518840617617808075330388482526180736260681245127862565373032388826478887465858427858051220613172202211345601088467637001415045874412557332067277484377551504066843600063121066341371643283786784761068601064575354243720165161606071462467454388636873636233778021648671534367133507427605374074416722337133601751734478484212371667138687221813155227282016661347012087060844717657163652206587018728132833730304737025362757761315052144646422630627111723456313173844406042412780701303413724368817117576255854668574228750452553070204351788025621430144242371001323737372064343217801782040275037004610781844438384742255584167536370662184616027251211143638677564508151383860530708048252122840866600333828445206788217648545821445206684478670700853248527254603327501006210154518503008755220176074648684464420077608424316613061505360032376774670110586687775170411382701487278646233746321110574082140788743715263036142246810378474651821327267878687767558532332766770770556676145510857677602768584841218228625328357130763700187376638323351202458842267224561707545685515711742787471041306204421583620103716561184185104727138066730485156405743817162476012062163020146660802807525251031404783027088628746507335166655450455814243664167181412115564530746315868643783184442146216216845873256853767015455878677678280687482518218081546136488640838635431565180552472320787367186616811775854673275284425445068256835580334212418571666556783641407770327517431140237301214478304666154718470055040784840142143820856651337364886780162504570540561687240205801871073843068104004486611083157177770070276412274284501525030180108545680011733761885871352405735268564864488888408546532680830132441854774703851551130551311212088487888340480334438028463403314317118862855268314010187431362037387131230675578024177157366237440614241826465088416751852758868580542326571477612173575680005143247771436458011248538443205703184858134812623530080474087351382103253482864316815ED9377443018FCEB94C82DAFD2C91A64AA5FA118DFEF2C915FB5C1C06E09A9915755FDE25B00C2D6A8382A8F9BD031F4F9CB0CD25CC035F5D38EDFF23E27941C7F38A6E958A5D7569D234DBD2A94B296446F553CA82466AE1F49CE4863D68462FE22DD7CA41E3B5223878FA372DAB34237763BCC0B9BEAED3FD27AF301D4BF779178571DDC3EFCA493D98DC24DFE77536701B08DBB76E3759B237EA3A0F9496E8C7587288EF7192DEC95A60FC480B9E1F533592962DA075833478222BE8B378E63506364B78ACE0D27A5017D15D58C018EC843375A5B07887FD25E1C30C0075F944A9762E59C94359728B04C38E9997448263150BA6E69FE461EC1AEB5FA47AEAD3AE1848CA696060462D29F331C02F80D22D8E3BA79E63924D2D4D3BD901BD79076852FC0B02FBF48BE9F772FC3332BA583228E55EBE8EDA94884CCDF80D17654E27FECDD237C0EE61E8DD35B1CCE3C388DE759B1FB7C3D143A153DBC41D2FD2E9D0F754273C21C19F5F13A63A7DFC479FD64D5F5FD008DEF079292629032111D2B16AD8D61566A73DCF219397939669A3B219F648DF45D541E47FA70833A785045B71A606DD4DE82902DB7C1899D44FE0D2413F886374FD1C19EAC8132F37A3AD31F8BC6F9582D58A494DEE3372DBE3C32E10B18B787D8E4D3B6E9679EC94CA86BFC2B23B9B4F92C1BADB21D5E5A58A9ED0FAAC419B51C1993983B5A7F6694FBFD5F1AF15A10057C6AC46E7034072A1A5D26D63B67ADBD3771B7E78DE3BFB9F6D5CE594B285991BA243BA22B3B54453E6F5413A2CA1D9AE75FC1FEF7E31A7A3B7CB087CBCF3F08FC9C34B1670E7F6D5C32F165D3796D1C369E7C50E9A122C116A8279997B0578625912829142D95C43DEA2165E0D3F9313592C8982FC1E107052DE326109433DCFC45A1BF14846D1F8F146D154CD5AAF417449788DD7E6D470E7C70C7DF7D8A1B62A503B1D4188AAA5C32BEA44C9D849D3F8B5C91D1BF97F47D83DC0D063639F79B9F08DB24A13A06C1ECDBCF73CDAF7510CABA36B890BBF7DC241AFAF317C24026A6F6CDC8426D99C0F90A2F1944B797DD68B792AF00B15D0C78F8528F0E055FF01E73E455BD5162389E0FF178312AF5DABCBFCB28AA2C0091862A010484C0930E7D9B6D703399D40B4D83C996E4CC415525CC895EB460EADBEAA104D6251FADABAD74DCE9FBBEC08F9D0899BECB3D6FCD573FA9FB94D9D18C59C724F39F0157AD6C8C01449DD56F37110F68BCDE8C3F66CAAE7968A2FEF4B0B20A7CF41AD9D40266EAEAA0C21951ADB946B78A3ADF6E81AF6DA0ED92749B119936AC4C7B798DFAE058A5F509D90ECC08EDDC2ED7234D3BF28ACBC7235AA971E4A3744AC9D47221EF2730A18A5411C85B6AC8DFB2396AE770A5D1D960D7EDD4CA6D0F9FFF6AB257B22FD5DBB3835D05D060369F01C65E58E2C143AA4FAAA554928531B9BE2D0E2B6D9F0D32AD9C9A12DF38F72A21D2906AB17AA5934F08EF87B42E40E46DC1C35DCE85B0501F256DC439C2B3A332E37F3A4E400304A6ADDB09153A7FF7EB8760AF870C252EB258EB658512BD8EF92A89FCBB50CF6F76BEBC46C97AC9DDBAA7450CAB49B4190A8B39767F36597F89027EB3C09DDCFAFDAB286863890EF528EDD073AEABD6A7C9C3D04EBD1A3CA3197249E7DADC74CE737CA5CB5A3C010FDE6267AE82BF9B8AC6210EBDB68BC5597E10D98F6B5DEA2777512710C58694785F544E4D886CD8CBC8E6875BB61DA19BC7FCCD76547C4ED44A935FEDCA88155AC0E428EE506B1BDAB6F00063EC1EB0D3D91B6D9EDFB85E8F90C42D9B058EE1FE208A54A5A14E4983E9C06A7F549647EB8EEE92B3C9A0B54912DA9185C7AC272C2DD4615C07140772CCA6CC3044FC59F7271259491BC9469BC1DD07868D6463740387DFA7D2ADD1346D6BDA59435B84F6AFEB3BEF20B007F8CBAB2DF46BD171362B7F7AD541A645EE4E62A520324617DD097622EADD7DA6939812673AB6D8E5A25FCF00EDB519ED4877B13EB0E57E9AEFC8B63F22C0816E70CBCE0383D689706FDB45EFB6474A7F194D6603B745F4D85577F79387733EB0975D783D7DD3864BC89111E1273D6CF9122B43EDF7F6757E2CBCB6C8AA3C9923E3E6870F9FA92AC02DB2B52491A1EDABC9600CDD515C665DC88889762A2012332035055C896145EA883A5D4EC485BB24B1F659804B8F10FAFB1B4C619742EF4BC5EB665C48BE5F5C5093ABF4E9E6E43D8E4D7E15F7D38DA74B567E4017FDF540BCB9492CD35C2A3ACE4CE579282837A8B55ADA428C1D190BC77764A4E44369BF90F24CA2CF566F7394978F28E24689323FB8C5B2D688578A9E5A34305D0EFB970490CB172D6FE786F5565CE921D92A2573C302DC9CD0431F8ACC8E0F1A44B586257080347F933387385429199F4A53851076447C6D2114CAFDFDD13C92D8C300F26CFEBAE984D7A021E9B462D30D19618AA72C58FAFA0FF74CA67699992B502BA0EDA7C6CD2FECCE6B51D6C704308ADB4B86F2ADF28FC43F03807C5B7391B3163FDB66C6EB76A78799682BE26C536059BC179E8F89D87469A57899C1E18E03F16DD6B5AEF7420990DF22CF4D3E905E1B5B1027DAF56DBAC8E9E3A54BAFB28A8FA5A51CCCC0872AB53884563C0B7876F68A48F1F51B1AA350C93A23FAE59B6BE2F8088F58FB9FDD432C10FEB6C79F9422F0AC6DA4F8288A23D16546715EB6104CB0499E5FEB2225C97287C19BEF3279B3871D6AD522B30DD96BDFE4BACD75CB108BD622605FBC0BC6F2212D76D8B50E22F98E34B6C53F53AD9E48F11FCB77769537756D20BFFD1D775B42625E6E7C4EF65D7FB3EC718B5FC0094273B29487759E8010FC317CB0F9AF34836426A4BD2B79A3F48E0F38447D96DF0FCC545FB51DDD3C6B849FF33BE3F9A9EBDEE04B422B6E032E134B7772C6D3D4430C67BB2B1B0FED7C801F5A58F23E08E1735DB1AB32D66A66A7F60E2F98B811950CEAEF309D6A2476105E165A673A4F9F49A94FF751DDCAF839D58CA66A78FB5BBBDD80C5B87A6817D329E5747EB580A7B1670B3B7F52CB5FCD6AB51D48E7F0D91434F6ECD742DB8286C2134713E6FD638891DAFAE78DFB0550E76A8A54DBB1AD4434786084BF17BABE7711BC40943A6BE4D6F9886802A078B00937170AE765CB3F5F71BB792FE3F0DE18085C3F402079F491B14CF2DF6AAA588DDA39B69A5DD267C95465350B261064AAB109D1D8781B399F0E0885BF2C646452D54504BBF5D5322C6F4A3C25F4AD945EBF079CB58A84B9309C32EB6FC35E92F526179DAAAB3526382B8F02EE2AB9D102AEC8F250348228437DBDECBAC81776D4F4A0CB88E1F19CF6A10F48F72BACE1D21BB213014280B788D4760D8FA471F9C35A2509D3BD86C1F0E3E92A74417BBF01D1455B64DC6ACB49001442C55D1105874773ACEB0AC4839BFDB021E1B653BE09EED14DCB9216BE75F0E2B8E9BB3D2804864BB92A618926D568DE28952354A7CED0384A9D21203A68111929E0B0F34191162D722A01F8B55DEC3F9DDC9D0DFB3E", - "message": "C9ED9B897C34D7119115A0758332FE70D4A9E11FFB2D6A800AAE33F85FAC59E715AAD93BD79DC8D958079F3B5C2422F8FD1A1AF9406E8DA3297226440E30183051FC9AA52AFB8BEEA2228E88D193F231F2422977DDABE4AF4F0437628C6AFBE68F70CF4F56153A2691F7A4241EDCA760D4B3AE0A17A8A0214BF1BA65221DE64647AC6578F4C7E4A14C401F7DCC30A10A695A7F72B04393F4E9C4163AB68667B1757154BFE711BB54255F4DAA9D8AE6622C71EC8ACE5BB79C6B4C8AAF1B0A0099EBBD07B292CD7B55E44ECD68DFFF4173743145B71F536E7D23E78C63679FA2F3C72CAADEFD5A9471280CDD3DD8DB83F8AFF14FBEFDC8C5969B050D263EA462C28CA64362F7F165C3EF427FE5E90A83310DCB07C9612E9A0B8EA1D0631D84B4A7F1C7485B0C91C3B7BBB0EC98D353376B692BAAF24C5389D50250F3BBA82173DCDB52382176EC5CB8BD531DEA049C5B815D788491608FFA2AE8BF486849810AD89BF0352ED595E4EDBC0B81467D72944AB83C3CB2F90FCD10810EB65BDA18C43F9A9A5D98E714BE992B7DA02E9F7C389F1A22810DC0A473F8891C43932E0F6B5D3A21C3B611AF6C394AFC576C07572DC4A1E56B4576FE615E516F48544D099683EAA886CD41DA848567F70C2103C467D271919CC5935605C0EF05909635D431571E5A316E299E553EAAFE9C7CBF5063E2057D297F60B5DE1C17AF6B97192E840474CB7266A76D509A10FC7A71721D705A9DAAC5BAD8A52290C1D8DC7938663B24700F992FAB008CCB3801258245A0F5F329A4FE5553F4130DFB1D673338889B357FBF11681099FE9BFF18AEEBB31DAD290C1401D49CBBE38277AAC8A99C8BE4E6EDD8A0F3C901082A789A1037768AB7C3C704BF1C6E890D20B3DB6918C477350F4F25756BE1742DCB31705EA9DC975DE0C38C21D29B340C63438268F6CC399BD644EDCED36A7B50E8D65A507BEC51A31BD136525F4E7AFC1EF9E0E6325D032682EB4AFB7FB22F1716EC6F4C9852054429B5C5FAF3BC86213F6D800281913D5722F3A380307B59E1CC290EE66FB9699FFC627770B52619256C7B76D993FB4024D2DF0602F102A6A1257A200DE1F39DB54614FEC2B60F3728F59482D71C7E5BEC36F0D90D6FB0B4FA252E7FEC4F0FB9EF539257EFE87715ABEC75B2A5FCCBCFA5666F1C9BE2F0489E04E63ACBBB239EA8397FA2EC24C25C538BBBFEB74EB8E15FF93B0FEDB7F36FF67F7CB244CAA067EB2C005EDD2AC9E0765DD38E51E7C71AB72B056B230ECAA8985DCDB50439BA261A0DE57E68700C64655E1EB8608BCCC33480ECFFF1BB75D0AB69CEEA8F2E3E9515331A1EAAFB9BA32AF62798DF761267475DE343CFCF5A352C907A0314365B8CF6FD2E72F2142018C4BBCE4CF0A160266DE320EBBA359344A60D32CB135F5FF943173A3F9C7F4A68489E78621401425E5B8E6273309FA3313DCBF13D7C69B63C1EE34D3200BBB4CF57518A5E66D010984AAF34CA9B7DDC914A3AFB514FA1B9D3FCDF3324998D0D9058FEF10C30ED6B381C41DE363CB31C5107E7C00D4C0CCE485DBB4CD2092CD929E5717DB8CEE4790A48475E1DE9178E49B13C5173B6F301D5B7BFF1A9F8B3807A5FC84DCAFCCD8D585B77014EE285074E64448589A738F1323C7A865C3DD482499640A3F166F38E37C6F9ABA8263E4F3D1C2E7D7AFD16BB02B9B4BE8A055452071F278C32C3247DE2BF83A0633BABE7FA048BB18FDBA27022736615", - "signature": "2BF99640D1E8D1E76A3CFDE44072BB410AF19920F9FCA9F4EDCC534073063A5D196360CA825E70EF3574000607834DF6770604757CF5FB2E9F677530030988AE35E32C2AABA32FAB3E38B990CC1EDDE319E77E78A554161EF485FEFA16506826AFF3BBE5AF4A248A1ED0BE5049317E8148AD899E970A55191B2F31BEB20D0DFFFD774A5404026E95A04874429B59FE1FE29453AD21790F1F520657D657D175B8E4B8C497D2D271D904DAB7B93EE744B745BB50D310645FEBE6BA084686263F92A6550295822E84C3771010B4034602DAFE05447A858FB68A8B3F17B4539FE2A7839C7F2218888BB8FB8DFC54AAB71CC165B335C2F266984B1F402AC09F963016DCDF2FAB74E77D24B31CF35A36E2003228C0EDCD4E0639049C168E9A06D5646657D0580297C60F2F05318D039698482AE9F34501719251F82FE375D237D964221CD95CFADD4A3724A0C23DD3E860ACFC0637BA76159727F58E0220F31008E789E699C93593F2DBBEC88634AB2474B644699F90F56785F04044ED6FEBDFA8910A286919FE4A7B5AB253D578099152031E4EFC75094DCBDABCA8072443756B536E87B87114B354E4BA4452F540A9B197FAFA7C054085340F6358DFFE0FE4FA4C9ADDACF68C619A672E841117D1728EDEF147E797A9B3DEBD9D4469C71CBB684D134B18EF7ACBF66D52D2AB45CA47C7A1F7861E3EB59FE4CDA18A29C7C635E20CF68CF8C869A372866494C34F703E85B9F367E44D4AE42277BD8BF805DE61D988C848D6049DFF914B2CDCE4BA147127A9DEF6DD79BFEDAAC5AD4653C14D086A7CA154CED8860D12ECF86F351E558CB7C6542017E233005C1A7AF959D7E83CA03F3A07F1B9B7DCFE30D66D81B8D5C36C6BEB651D5A36E9330D2D585E36547F88A32241CF28014CC96A3E234ACDBA99ABB541FD370BFA65591EACE4D268D3EC17D86F4A37A359FB95CEC77A8BD4DEF36D23A46AA72906759A8F46D78CAC6D160F277E4C9E82F7BC3B48558E1607747D7BFBC8DE7E50BE365E62D003246F429E67340D1949C950957D7EEA52096B584192D935AB88E00F8AD54B0E1D7EABFACBE81E2C1282E9F5685F37A54EA44596516D9F5CC24AF26C88C91047E70A53CAB06A33D71B6E058ACF6FD7BB045FBA386F0E07BAC67A3EB256528680E4A0A31F91957FCE294C7EA84E7492CF8D265962164325A6536DC8AB542DED323FD2049930AFF783C466AFE9FE811716F6FE75ED28CAE3D768E7F73EE9C09547C40C3287ED5584AAB2BF801A3DA15CDB3D02A7267B131D22E6F1CCD23FBAD9D2446AB8B303E3B89D7331E8127E3BD909A6FFEDA8512057B86120D02F0AB0D8663AFF465451A4C8E29D8AAD0BEAF00B51C96C09A0568AFC3EB9C4FDB78E372669FDD78A296C6919602E4C9F60513E09F1F5D2BDC6D73AD9E48FB2A5DB13D6E935AE49DCFD455F017A41A0E70095A55DC012F15E94E438C266B081D25EA275FE2EDF7ED894779004063921AB3E84E44CD2638CF2EECA02BAB9978ECBD62D153FC4390A6F2117115508F355349603BF1DB25096D00C4E4B4296632F78C655BA6ABFFAA7B72292A1F71010D6743242E553D6326BB361364B44794164019ED114876FE166F331400EDBC665EA23AF4A178765731206A9F63950B3EB5B89922A565DFA8A23E47ACF14DA53D2AFAC6F5AA9FAA3DBE216E9AD2C07A32CC2A690B2CF1DE943000E87EB95D906C9E52FC103574C5C50548BD9EB8DEA4A0CD0BC3153A2193E30CB6385756FB0224F6392AB526CA21326B065C0C9C74F5203AC313B25F584491ED20C32F40A896F99088D07916D4F84396B67EEE7182B3600E418D353487083F58AEDEBAD6B9C73042748D2F3DF695A579611A41F4865329EE8E807F184ED2528AD1503A61B13D4EBF24D7A5371ABA6A053A4DDC63B0FE95462FAD2A62B9A23D50676D6F1B172F0E59DC0B77EA7C45E31CD89CB8B8BFB6AD07017B5E76D6798E08764B5BD293B27B48A392B382554EC877783099148E4C81401665AE7DAE8CB36716C56D0047BFCC5F57F5C6162ABF8700BB394CAC55D33E50FF43D20D2A1C27A1499ED068E40ABBF855213BCBABC2BBC71A3C7F8D11AED8CAB07C0BB8E5F10C5E46E726A353559265A0E511389C05760B4A6815EC4FD407486AEA685B37015BDB6E8DBEBA29636FD23DEF0BEAD64F38668244C56CD37517D586E08159F518512BA72CD86684768A42EDE0241C0EC6D286CF3DC133A64DFDB52E1E6C59743DA59FFBC28BF3C989A0B49248110871832DC53280A250D8C7704CF6D0A965BF74EB1E7610EF67C514C963DF6ADD4932CD7B6809F725FC65F32E5A8B7341C4587DB20A79F4BE0F42035B76FC1A7F8132A5C5D0CBBEA2E98006CC2847D11DEC848CEFEF19C29B45117859371166EFDFD9B1202BAF4183CCA16C2BCEDC391A01973B63AFE3389EB1E2520FA9C88063D038E9EC6F2A9429EAD33A559C79496A3DBC52E2CCF27DA58AD1A840207E7762A1F10F5ABF5F158B05FACA08CF40630E36E4044B69299835CB1EAB4DB06F33EEA1E1EE9692D427A04947FD1BA3D9A24C0C1ECC9CF203B25C11BC196AA12CAE8F8E1E2D37BD51002024F51BBB136EA9324B80B02A1D43B188A8334FAC96FE409CE4D056885D0AD5922F065772B895ABF623DFB4B0D956F68E65ADC37F34A10A1CCDA07A2603991F29598FD24D2C409FC1A3086892CD3EC9B22D7F01086BBBB12497A1B3EFE60E88F6E26FB4E2DE03B9FCC1856CB46B8D6617C8F6BB67993402A6AA24E9CC42A0E102BB46BF5D33F84A13355087B9B8B080FB8E82153ED8587F56A08226628178BEF5C7F139024B95D2854D8F37DE6068B4A717F4A8DB54E2CA731603E3AD6FFDE96E21A60A66B5F9F5F9B024116A999960D2893CF7CB3DF2781296E6B9D30FEB57842EDE5AFE2441AA32C8DFA2D3FA7BB1A3B0557AFA82B0D0ED8E088D587E4CC1CB6AB6C2FCD2826387FC289EF4E4B3D884A9D5DD354EC742D52962797AC5928A7419947699B10A46B69BE370AD481B2DCAD7ED5AECE4A7CF04032AC1445F6C867794ADA0FEF34E18FE0503A89619DA244E7FD4AEC38448147B49B8A312D3A6858BFC3AB91CE61ADD9456F4E231A55D0C134ACE6D43E142A40E0DD75D31C6EBEA609D2CEE42BF221B6B83176CB79AE6BF46181893DDF1527DBA791723752A78949E8767A194F6FA64C386D0B00F7EC3E22F2E059A37569B4B95ABE43A911D1AEBA678D9A15AB025B0171D48F17BDDC8501A04F907B9E6FD8DA942C728BF87A3EBCF82564ED11796E25FB861080A010DD2F0EE1CF8A7146520FF66F034479E2B8120E4A28FFCCCD0E4FA1E6A5E9E87A6B8B87DC8A3EF2D68D73F2317F294FC7A15A3A4E90564BABAB922B210878B64C20AC1F8BCB23756611BF042C201DA4D0697DB25E64C688572A3DC62C236555522127124608422BC9141BE17386F6423579697AF73CB0ED14513220AE13AA49A535AC241097190AE9B4AB6FB24E8200F75A7D3848A16DD3676E3E11BE281E04A9B642A1DB504948A56EA9A1C8D0A50F97F292560B12395A1B1138DEC127DE6679CBA8B849E33F888B1F595795321BDD543EAC2A28C4D89CFBC732E7CA6A7A04F66BFEBB4745D489A44FC4A5E255281AE35735D85DEE377AF98751BA4CB8835732DB983635B656F24FEB594F0C0EF5846B854BCED5EC137D8FC1471A41CE845D486E905BD247EE250E766A7F8624181263F2B184D07DF33614EF3BE0E0BBE3ECB0E3EEDE05AE25E2861269E0B0ABF9884A9DB377A360D9D3BF7E66EBCB490F02D0EB9B9F95CC59E7049C8F96F80D05B93AF90753930643422A047252B93FB9C0ACB4B88B0090AE098D1F103239C03D569DCDDD4D3E20EB00BED8F1C67F1F2D3A3A4F5F1E554B2E462564C6C1F4780007272ED5CBCCAAA46165B7978B206E3E099571DB7EAF27237B837884EBEC15DD26B40CB665CE45B29841B2DED76D9B0F1C9E3A0AEECE530A8A16F7FA1F45F9B9B7610A393D4580C5DB025B78B02261F5E4FB307AB6689934F3BFAC66ABF1C9FD202E07F20A1D82747E4ADA8EF9D5CBA6956434E94C9BEB21F32C74DA98F796C575B3B58F43B493D2D3568964580285CFEFB2E62B06588379EB296324ED06A7F1FD4F8790DF96D4A773E892AA0D9E17095D7329D9B31DB6FBE956D5061EF8611EBD39AF2E5903F2F36A75EF2BC9FBD833D8E8D2044D33B44B6B744FB66D0BBFD90CF7702567E92B9FF18A41582BEE4A15DE30290CB07A5E3528A9A27FE160617C351B8BB362A22C37F340F4C3B6FEA6289D7E4D637F6A1EB28A7D3C0EC52686D5A9AB790FBC2809F7F06F4871C4E3A24758975FB37C3D1733367024163EAA8F98CD93466FE9D53629E519176F349685F0E61D093801EC9A026648E72A13B8E4C05F906387553681D00719E572B06D304BD71DD1F5B36A45073127CAA88E68036BC26F9B6BF7265E86803373277BBC5BCA7762F7AFDA314949FEC84177FFBDC696A5497FB40C79E70E566E391F1BFC2B324D2B310A450D9807A5A72E0647DA940FA6BC3BFAAA4BAAB81245DBDD55942457B21DF8BD499A2E819A16BE59A6F7E6676CF3BCEDB9C646BE387279985182989FAAE983879BA0F0FD0ECDF712326A7385A7FC1B2C3F4F00000000000000000000000000000000000000000000000000040A10131A1E" - }, - { - "tcId": 26, - "deferred": false, - "sk": "A4ED7F80956F1A44672C9030C85547B54619A313032627687F1F158976A2D28907900F84E3B9D5336FB661CDDEB5DA32408DDCCD61859AC66D5E623EAF745E858C1D51E75C98A689342747AFA7C22CA287DDFF2B30EE9E945EFC4FF74BD00914687AC4136597D0DBA2AEBB464A55C00007A397971F11CF922E5108F20B895B7941207013811437764076602057327650014846512521051134044721728840471240468158620851514470636303001350088771812801531688000733466441861513742525412601875458731315486847771662050347316344525702707057377764035718082720307174511475224256283107861781131553717714042076114552115453832756862775232773050805741536122157711646367700242428287222761460706108640730202305048004271137750473622514020882603385871776073866148241884265850313425124232184264815577340717562333801724206311260451483381762216524703666716683462381156603313541080053820757730826678818322826883061861335148373782208061718105775375826777672423588433254824486101823767282154027254361868335678543353805617821481162730652045145287554024323481137013167450247203075702807580765272817733061138110138050742533065402722575387148728268663883012058511436440708755322742756705443143872727618411601186033417307153814781410058448267271130100732602686516231834311238647026760152547113031066482361633044416843658581330423061736710024767084324838453061881648523633073145626613485686817505362474214104803222606853556234224865753748040484665857228745563151400065331467076364034001854708148516718643014448254581642662324580472540817760016334875431813615733342068658625221436633877448827353301133165100217143140503533081867240242288376423706818517408834337781383674383187725187780523321864245136772216405236663621124437888768426042072813436208810360206554680333862732263101403067212832824174614502520062327687743605156465476282370734160232624636614258885304101344844586018105357847251401285316763376185064183603001641775527412116344815872823276550347785718752750352857227783051142305354808613116667716627278876620522410851068428786657414384410663404801846405041631402661336873256432535608683333558305507630406032814477633143263257074135750334036686836723317701210415018766018220628550711780864682005421263438423340416413353070086841488211041250620327222208657643663862137722367033353738671553527108308134351574435151103425678758048472876854021260323038826835101538487847208802126638654312684104325807876770077436312012363386725511475331337542627020144121211014663122140658514307281185501024006018177482712312474614161700446687886722647162278322132585863401702314217876006468328164146581047085401421760440321582542441117553056048835224066102526308431765121152602773303251363080350616883864358271348413640038283567734581504521116644336856306352571210550150067264084884453428240000533610751625013670107040138826466331222242287483473037278656425874000521127357382325247351023460401842120860208858010418511736611802200174883450035706425872070364332078257248857812267664537025601262182676445510008434415815140885773555147384536274812741577500878000523602141344148306644333741235746141117460853768768473488606543427458420223345786350554613242521843216282474064647007816386531203354608282C7D03FD47511B27620F8A1E8CADF4475E865E001C554F08A3C8357B8D71825BF62A6312D4984FC343B28C5C2BFB5A945C0EBB5394EB69054F3FFCDA20339C801412E8F06680CF79416D0EFFE1A4A7568279FBE35302106FB0A2C7A991FC66627A0915DCD8C344D056A59846FBB72DC0F407B60E25ED5B855A70694548E4F89D9CE64F56D41F1F905F485D5ECEDB38A3921EBFEC726FC9DB03608BD182DB7D8E07A674929C406CF7151AA2C04A3BE99AF5257AB2A178E07820A15C69302A78314E804EA86D2C2E16761CA9D4D781CB18E5DAE5B671E48E9BDB2DF6C75F07FA0F285256007A891A6F50C49535C19D838966BE3A6195D3AB635E038312F222D164522B744A1BDD080CBB76B0D3F3F864CBA93AE9A8FE4FF6856BAC2E5E7B7BE9ACF80BA79ABF25DDF14F84355FB4C43EB83A532863B46E6E6E64BB64CFAAE4170C2498A4E61E8B270F27559D38EB709F2ABB04AF4DA3A4093400D5D79D4EA004C7DB83461F3C10ADEA1D25CA002DF5F238E0C1450801A700D0DFAD0661CC10AB6BCFBAE0DB95DE9F80F59B7B28D9C02D11788AD52DEF7F4A10A0A3F6C7DE7655371C5C4148B6F8444D4BDAD3AF25708517E4530CC22C4790A9BBC34999A2B186B4C8AD6D522610A3FA43766C42BECC3F9D32ADB22FB75DBD152E7E1D8D39F35F3DCFE8CB2F51C5537E16D0D231F6BC75BB925F14C2295437EEB2DC6FB906206B4AEFAD0CEB91F33BBD3C0E773B61984B781C39ED2EA1AA55D039BDF859B93B5F5618F565F6011EFECA254E516F5EBA19DDAAD7120A11591E81941EC42801B37AC0C362FE593907CF0C99AC6479646EF6C7E4093C38DC132C288F1C0184036652A7DC583B2F9FA2330155014E3E8841F659F910E93ADC4CF082C87CE9D5DDBC89593A99B2E4AE6C43565FBBAF606AE69ABA8EE6EC61FBB22FBC715969F08DF203CB83CA8EE911410A56AE22145211637D5BD82260C7FE5CC6CFD9CE9AFC86F1F1A67A129556E3E989694454C57D5BB6B24F33F5D81386187B0BC6F33734E5EEB3A2E148DFEEB5D3A0D3B771F77A010948BA781BDD7F75DF23123D0165BB263D25271FF6FE747F4DC953AD2EDEE4807A698BD1F1229ECD00714E18EF445279FBB1BFBE0FD7F0F80255690718293D67D27919C482FFC5CAD430FA4011416D883C3C3AC9E4B3DDA28C3BC0DFBB2D2C03BBD196CCF7BB896B5F0A026CCC3D9A36A41BB9DBC8F7C4887CDC64E8C6ED97719B03686C1F1A2888778584CF7702E74AA4730E1B56EE347118EE07CECFBE43555C77CB20F2519576C6D67665F3DCA0A3C436FA52DDC964AA0CB9EBE79E8BD5A2A0EE66510F40E53DEEC226A987C5219FB639A07C52E58FE5236BB4613CE4CC53A721C55BA0D5125ED860E340D882B6F2B0F68AA1EE6D2C1ADB9925780C153F58B8047B7533FDAFCA8CD67EC95B6FBBA84E94806220ED4AF1A2861F4B3FD3122591706B8B3F5519FB51A7A63ABDB03B411746A6E2351C499DEB6E023913BA4E2682424752C17610EFF3296E7C71D09AFBFC4E9921FB13CE3169331B774B322B1925FA1DFBBEFD745825CF01B9EB0A03F760C4343AF3AB8EB8664D7D04298CAABAD39845132763ADBFBB42D7779724BCFBD8A387466C16A1A4CCD9B40569765EAEA58C2C74B0BF2D045C57C267CF9D57D4B1ED237793B45BB947BB83D9EDC3DA763EEA702DEB209591ECA2B3B53CEF1A2C2C09DF4F3CA377857EE30F81C17E098C37AA6A852E759FDE07390973B41322E6F45E552D98309B6EA13E1BB53A0D0F4F6577C0E94AE96DC0E9B5FF47F7C0E57970C49E103F4880A3E9F3DC694FF4DEC024C662F42D44EEC975C7440100F09AC08F5AF04287D77C409A261E735A109AEEC92127991CA582ABB9C38AAF556C0BD7891F1D3E9F76756ED0F8641418204F5BCA432A3E15C446198666F9CCCF6320964A19D1A992570908B826AC75C67E1D877A1EF3522AE5952874377CA0C0BF6083EB8D3550E00F019DC7A909802217A97C7C4564309543326567FD57722DEEB12A3A6F37063CC5882825893B636B6959DD2E6CE24B2F762D59E473429F40D05579A66FEF7BCD812867312ECEE3DFE08691D7DE66DB3C9F6F7B80013FF92F1986CBA42A31EDEC08E3D71DD8F104A1CA29FA8CB4A7D46434E572CC6DAC54D73CA6C86AD04B948C904A14196D00DFAB1CFBFD366A594E5C8A398C849CE8B1E88BF37C09C48C89B4264265A7447E86FBB8DAC8EB39894F80C18D8E405FF15069EA8DCA779662993DA4C0C60537448A39DA002BA14E56CF148783D6F9A97E166A2CCE8A01B67DBD891F7E75A70798FECD48CBAFB97558CF2643E4CDDDE7380E6BA2178677C9A8F1352E75718922C97B1399A84A602DFFC5086DB40091F825467833F1BCF99B7A8EB719654BA1C7D3C57AC0C1E2A21B6C16C548B6BB148A3C4624C648F27B168E534ED0198FBA6D8A335FDF8CECD1E762412BCFCAAF484738982CDCBE17A2A4515E9152AE926BABF7023806A7208560E6C14FA56B06A736C3AAD6AE686101B0A09AF7221F66919709F37837F1DD496E4567EA2A7983179E9E86E252B67DB29D1899AA33953F71FB4A0FF655637E4C125FEABE278F55DBBCA569EAF05C2CFC9926353CDBE609A3325BE0B9934344B6EF5BDC26A70CC1796F594F74CC858F38C2435D692226131BB627DF3DDC507E50C6CA9E8270FA43833844A6B973D078653C1B2CE63E5DD83E888292CDE058CD57E9FEBB432FC177F0E5D7AA96557D0B6763F8801E04CEDB88BD9DD73B72372E309E89F8230FF1DFC1AF767F564AB6218910C9D8101601EC2E108C04F72467CAD035B8288F370720CCD840E5294962B6B8C34C8393AA2E84BDEA310B0D8C32C41A57B40B64F1761901171F958FD17A469EF879F566FD1C786E8D40F47A1444095E831ED353A754604B570F7D87430507A0DF27FCFB4896B503CCE146F4000FE5F20E7E48560B053A64B2ACEAB204EC523C13FC73FC857799F92AAAD7F66A8CC5C89C5685A31C603700720550818CBE3ECE24C0CB47A9B90E0EEBB36053B75A56E68252E95DDA53B876187EE2B1F8E273B27D0A955BFFB67D76D291D4160A7BD3A516BAD136E15F0428E01705941C37619BC4347CA00C5E5B7606D5B52721DCB5C4D167EBAEB2D2F33443B073E7C9AED9700D5B382D5F61281BE2F245F6F7323F6F449C4488BB8F3253E1DF2FDB709DB2484C03BA27E53071BA7C7B510D607F0548454026F960DF5C97A727350E0DBF51E7691A2A2175B57D377CF206E1A38EFBE2A3E81E688684C69B9F7847736C58F0526BBDE9AF4EC377DC8DCA89B97BE3A29A30B820DCC0C6FC54420A5F7553C62A83F2540E5AD504CDB15955034B8A850283DEB9FC413FD746797CB846025BFCF721D03DE7EB576C083D0597304102084DEBE13C73BA3EC43F1110510C7E135735364C181990A18E501F9B60D249DF5A97E9BBC94BCAA322A778D112C4A26CDF73DB7A4B5C195D4DBD8BAE251827F38E652642D12729B1C8E69E8B1C2282DAF805746B1CD", - "message": "258FBC2A94EE48B415DDADDF470F14FF8DFC069CD949BB88812CD27B2BC3D9522E00F302C0B72533C9A612A251BCD292A291F3652695D318927CE1B922125B287FFF9B1AA2B79180622C32AC624E0463E5F48E86EB5952CA1A95BA51388760FC5374F0561FB8873018DEBF785FEDAE4CCD1A41820EAE9D7056BBD329E7A95F21A4919A109BD27D26779C3588C9A886EDBEA1FB97A8048DED858B299DDFFECD4D678820E5DB6CEEC8B1EA879C9C22FB7F59B227B4F7C6AAC577767D899B2F11FE39D1ABC527DFA0E656F25E53CA05630215C5CCF0FC071F124E48C57C5344BB103D51A1FF24114426A324BB16D8F80D3CF2D0CE573F4E50DBD1CFD66C05430A1109374CD84156D2E31C0C3F4DE2F1E225B5CAC05D56C4478929E356F7F46032E2719E07BB1EC207B32D241C87D87ABF28C7CBCD38267CB011F26A9B49090008389417C7A219A9F18203E6D907D63AF4C42C60F7FD99C7F9394021640F450A9A072BF2C1CC3EEC88BEC866FF1FB5F032567AE053A408342A56E3068EA168B9E902068EF808916EA58004FF31C31DDC3FCFC2CCC92E0DA09623FB523AE46C8CBEF92A1CFCF4C0F523430E60449E5825A81DEAFB2E26B3131F0383B8FEB4B1B4E1499E89E9C5FA2ACAF1F37C422CA41ADBF907EB984DD65D8314E2F71E8AE616C0518DE9B8331FB00983490483362802FBA242E4CB71056E3256BD097504AD13F577B36A2F9FBC1EDDD25D9DBC09B3401D58FBCC9DDC8E74BBBC897552FC826620060D3777455BF76EDFC059E5C02BBCCC0F05F86ACE1903AF2BB08A962BFE9E2C435EE8C580502351669AB7DF3D9F6B4720A0509BAEA97FEED3B8C769AC5D0997A097852C72DD6D5FA0A7144E08D667F21936F434953EC3C88B5BA2EDAFC4F87BE8BFB5A592847D15D5E5D972710A4A75A5772DA4D9F156563C17B1F0F242457A198658524B0D6A46DBCD26EB9400DF3C4C942FF53E1102411101B2FCCB58E3FBD16E725147960AD56C6CB6DB336857EF137C49D53D16E98CD7A0E856E2D6B391A95954ECEFF3B9956A6D0C279DD9E1FA5895D37EEA8C54255A6244002C7542789453B41463B084E7FB3361923C43EE1BA115CB254F47E55E6EB79C74DAB4C9CCFF486B8CF5830F23BA23C5CFEAC2DDF7D71EB5F54141C100E0AA9873D43F0AC1034C54193BC63A560A0C661047C508062A70B3E575CC185462A75230D91A3021330D95F3C807688B032AC15A9623A833DB718D04603ECE983F1D21A4513E80CC67FD34EFF8E377B775142344645872844BA46F5AE6971E68FD8ED640BFDE9F276E26B208A8F3D74ACB739C7EA6CB26165EE182F165EFF21905DCE3D02E432B1193CA108B6ED066CE95D549D9B12445E05E0583EBEF32F17EB121D80EC26C1F154C4DA2ECAC841BE1CC7224576EA43ADEEBA53C4D58785F36B6BC0F8AB23340B92CB87DEB0230869A52DC634F68A83BC1AB8A4102264CCDCA39A51C331F6DBE30C18C00A966E5692CA86399264399DBD3F02FF8706302462D62E4D16B5C2FFEEB02A7E8447C2CF1A3FBA5046C792FAE0B1079621D59C1D7AAD17CD6578964D1ADCF1256F2A4EB4D534C51313BAC17A9383B5BD02EDCCDFE59998D2FCA7F3EF52CE0B1842368EA66E0A83FEB581A7137004655957E91B25F5435BEDC0ACCF69238AA4CACE418F08ED0D961E13B2234187597FCC012769F798D969C13F6BB4042897B0D8C32E6CFFC06680B1E0A40F5F149B5974B0E7F0D45367E93B415F7F6DCF86C2131137DCD0DE30A3F1FBCD5F8214AB20BEC9738AEAAAC200900F4B2074688C8F3026140A354A22F83BC2ABA66407F87671C3E7EA4EC6F8272B6D16F3C66C76ADA231677A9B1CF496B3C241D2D1ED7DB703119CEB162EB097A0AF2729D0D6CA8DA57D83E1BEFB880EBEFE090F6E98D64296F7CA90EA1C2B26131676232BB394BCD1A06BA83004BEDDA287073154D3BE16C242DD65839C2E1125B3E66DC93A95C62F5DD31CAF9895646D5E2D183D40EA09843F5DB189B41AA4CD1B40C5792C2BCF9F44823EDD4246100457299E30EB2C66896F89F4FA250AB19CA06EF5B899CB96FC5E0369B773691E3447E68475A7552C10F96F44B3282D92AE49A246508A67EAEB9F4586074D6FE8A44D2D27C7B8FB4EF6BF701084B73641E41AA7275C1D6B517FBE3D60F64BEB9119F3FBE96A11AD45610E63CBDBD79929003BD1F2DE89DCA036973974FE5C5D5A8B5BF82DE0368DC60D75A138CD91E8A9233BBD439666ED1211EC2FE7D7BABB1247315DC480CC64CD8F7859BB9BFE8C668F112FA96EA48BD91088EA44F40D3E57314D3759F867BA52E52BE822400D9B0C2123F50601EC5F8E8B562C4B1F49F9779A99C926FABD8A74173195CE23173F4CC4098EED74C8E0FA74320772EBD1847AFA1B397F5A6F05A00179DEF2E6C3B092D9182CA3C4E382C4092396005D8BEDF6248C81D3AA0854F0AD43C1079CFA1E0A42650EC9D7B9077BEED377BF5FB2F3D2717BED04CDF2F7E7D1F45CCC6F71A780D2E5C3516E5F6211815FD691E036E4FA002079448AF0E005B67D2939CA88CBC57567F634BD0402EAB06805ADF8BE550B3E27452B372CF8C92A7055714A228986FDCF4045421321555BA06173CA0A761BEE635C541FC984C5BD3857DE696E9B21EBCFB87ECA437E9A7B54F4CBE2A601824EBEDFD5446556B64E1A88B0BD9CBA507C5419CB8CC4CACE48A0C9668FD2D045E9057B13BF0785F59B35338501B73B44CB749EC2EBEA97C9D29EECCA6AE1FB719F9A67E8E175D50B2705B6149E9D5D257B34487B547FD050FE5C998412AD0B4159C2225EECB67903FFE332CC3B86266C22FF7776334543C1E954AF5A89C4FE59C1F1AAB5097024E2AA7BC09831C9A5ADB713591106CD3304873BCF11A9138FB08B7485E123DD8F7C107E336659DAFDB866487E197589DE47D2DE8298EC3560EDE21A633F820BE6352CDE9AD51515D309C4BB4709F171CAFEB407ED1A02BC4AAB53588C2CD4C273BD527F8B4078925FCFF8954536E0B4366E474801F5B938A4B81F037764D5CBAF19F237CE37D00246C60DA652B76469BECABD51F873DC75E520A75B52BF585D664B4CB9A09F8EF3C03FCBDE6B9E595C1371C2CFC24C16EBC392C75D2BA04212947944BC0377DB718A7FAE0F6F9008AC7DD30B94C1FCC6BAF750217C0119736E4F3B7E744AD72F1F0694BC88F71E4BE51ED8669F0E814E12FD9F833286E2064708951DAB852774D4620A26100FB44A8A92B86E17507C036CE6F3ABCFAB91193CA4BC4D4198DEAD7CEFB71B01FE2506995F2ED3A02EBB0355E6B67A2294648B8D1C1445164D99B966588CC253D1EA1361163024372E2550E9D29AEB4234F5F9B20AECEC01862CC98365F1C57FA4D5E0C1F8BF189E169669F825DB43172D1F682DFC7729B2AC0C103ECE4ACD982D86C515A208519D23F62934AF981DA66B97DE2389F2F669EB92CA4A5C4C844FCB19903371AEAEFB32E210F2D1155576566C7B529A98A1CDBA36B450F3948F34F90A49F50E7412E6EA68BC3BB0B0A0AFE3BDDEDB718D5A150EAEA784859953FF1DD1B371C539243547FCDFF4ADB06C61CB49EA5783AD06BC8C1F3E32A95AD3CA6D69EC1D226BF9DE0562888839E6243CD150EF6953C158F9FEE5EDBF173997D08509EAD1ED4DC2AAA33E18DCA6F59269CE457C412B58C4483BC96AF5069D1C2E3F2F8DCC5FE2825DA21AB2280984C359DAE44C2367D6F002D64AB47F9B64B5656622517A5F7D5E1A78D4182B6BAA82E0490659CBF2724080A9ED39BDFCFB21BA362DC29C750C5034A04EA5A85799E01FF8B16ACD2EFB8328BEC686AFA20E591E7C7FC55BCA8BA1A3C388B785AB0F57208CEBBC5619AE3A0B799D1816B013BD67D440A7AECA7D0BA517846B68F70CB5D6ED46C36F663D6F242E8FD8C620C9383EE1BE9250D63467504B229378D2589B525348DFF852AF1676A18DE321DD46D7AAFD3DB1825F192FBD3F160E8CA400B201B1A61D0864257CA340F179F5F1967659AF4789846A4D086041441DCF4267681B83D4C8539086E276C21BDF677961015CE550E41C2C45D67A09AD8F56AC3ECF1058F366F2E35BAA9353A5CA40C7021DD09AC9FE0187C10EFAC7BBBF3B1A462C9C6C96699741AC16D3526BED3B30AE25B8E8A9ACD8CB2BB6C28AB89F0A3F0D0F40D10AFEFCCB067A37A2C93D3E8399A366B5FE4829870DA75B93249DBBE3C9AC9FAA70C4E414EBA720C323E6627759E7287472C3DB9CA9B1A5FF03E872374D6B893BA4887AB227E989D9D4D348B3965F7B96C5094F42D84432EB771BFE757105966C9A08D6C58DED7DC216B3D0ECAD2D0B025DF33CD3D813348B5E08AF95BBA08DB5BFE5D0A151C98A01ED27661CCF80F416A1AA260EBB56526AAA289F17FF5AE97CD0907D9143BCAC73F1F83A2A8DEEB3ED209EF0952D5E463D87145E0E4D8BFA1741E3FB737E14B5924F436D0183D98EF836DCA3F9623B50CC13EBB5F94EFBB76EF9BDF40CE6EAC9C49852D08E2A5A193D1DACFA04EAF3C545E0E25E37E94DF51FC1976BAD069CA530E19EED277141BE62239F47441B88F6555B0A998C1BAB53758A41CFD8CC4CDC54E1158DE15910408A6E79D33CC37F61917027E9D2F186466F704647B1CC1CEC06DC1AC37D1A668D44DD8B12621AC3CBD2039BF5A843A86FA492A847D6552E1570DBFE008F51652D65D03D8B613AD917B81CACDFD19DB7F4DC9A14E237CC6D7268FC5D3B228BD88ED36D8360488509C974E01433D78701CE07108C67D0489AE94076106B045DF7CC508466D35BCF156901E53AD2B5ADF8795751891A5839033A40EF3F5DFE0BBEBFB2C9D1C000691F902AE490D382EBC87FD40E76B30DAA963254674C7B6F304DA2C8BDBE8E1DCC87DE0486B4FE6B57A18D5A9E9E4BAE776D6147FF9C98372426EFD30C3B2479231E624A253A7B0BEE31E0FF739F862010AF03E227A12C3ED1F33EF1C0DC9D48A100FA24CE5C5D8B5F88F92BDB6A3A5328B0AFA983D57A1D3320A682B5CA94E75DCC69BDF2AED0C05887B791CE6F6F8885E4CC55C3FB050ABEFCD3AF2CA603172AC78B3AF2B047E506639498D0391A06DFD328B8E1BFAED8F76C6E4A93E733ED1097DAD8663F5BAEADBE1562D40C772D376786509323BF059FF17A5E6EF5A31BD668954766417E6633BBEC90B53ECA61BADD4037030A55A5EF4129D4958F6A8A5ECAA1AE7E220A87AE996AE8D9AE46B9C60FEDD98FF1E67807037970C92CFF9EA4B64F0BF8907198A6C038F9826CB968B1F301952E1F409DD6AA4EFFCAB157E792ED45830708ACD7A50BE8C08FCD12560344221104827BFA495604A57826A49F90B8B694B2BCACE4040627AA0989E3DB4FB7167F50E8A04982084FB3ECB0DDCCA5F24A7398620D19B37309A4DC0DF28909E16645F35A81EB3C5EF6BFD650571DAB03A7FC02FDCCA5FD09C9D2D3DCA888B8261433DE88D05DEE5D6165080A237D55ED718486AAAF1E2534CEC3A87048ADB40EB9F9DDACFB2C883EA6B20BE1EACBDD72432C7A6C97721FE1E0D9A5589C951F7D46F2C5F0FFA909FBE12E1CCF00161E741C4505681B0B018FFACD460528795CC3810BF7F94FF9B75884956798F21ABF36DEDDC1F95890894EFC15EAA6F19E9148C71EE9BF4CFD41EE3E5DF8A449FD95E5744793B9C223D26ACB44E691D7E5B68D49A19687F0237E7287841D3B0B4483E2A7C29CA81BDAFA5D96D9D2CB6FD9724B9903E8CDD03DA810EFBF94BC7179349E10566B5A314F81327F76C5A8346E222C408EA43FE29439132CDDE79D0D69C45C7217399205C2DA4D33DB521940C4EED74CA22645D5B6A549E8712D0B8CC50DC180067D13457ECE66D489F687DE218449D974620B3B5462FF3A7F00C439AEC73A53303AC51EB84BBEBD51AA48A5DFB8F93556BA540F5101CADB8BDB912D7BC87EC2AC67971AB99093C8616C4D1F3E7B06003E4FF22D99E6CAD7558EAF5C1410199EC97720E5C9278548E7EDE62BE9105A2B27A54D95673849CD5D60424ED97BB64798263F98A63DB58BD55965D3A4283797CD88C7CA67B1C4F90FC7237EA35AA24DB18A4420B827B3FF7FA5472C31499480EEF5A97BB967D1EC46E7B05A3D25212C75972D48A9269D67048132399E1BE0C02150A3D48717E4DEC2ED47458EB870A1EEE5381209B5D182DA2093AE46A4D99E3D4F12ADD71001BDB936FE8AA96797982F88EE67AA2E0F340E7AF498D5AE05C177F0BD2650A02ACD4CE23018F9E00DCEB9794C5C76418EFA65634E01ED5E9FF94FF86AA73641117BD554A9391874A75C7CD1E7759755B9D2A7F367621C0011F61B588D913C7AA0A0EEE3A2201426EDDCD56A020F54AB41CD899721D6E1F05F8774CD5FF6417CB68EE14C20D9234369C9CA59627B8796C37B4ECF1DE2F981ED0FBCD5737DF0B82637D599A61826909C978A2B68CEF01C5CF84B50BE77B49C1887544779BFEAE3F533286287E48F0ECC0D36C27F1209314726855E61E5EB5E9A5D7E3516E29DD369F94D72004742E246AD4699C64EE996BC7B2A079344ED32A528A9CAD6D5AC02970D0168A8B5BC713E28934F2880774418550AC2F534D06B61E627BCB8711AD9FC6F2A4D9301EBB74E1F3C73B05F28DCE5623BE1BFA871C14A947A947CFA806AAC43AE515D6CA65436BA6B66F62B0FDC8AA4A748DBB72D9AB087AA39561271A986229EC02BA3719CBB1798DD333248E4DDD0B6EEA4169D3B03C9F4DEF9616BDF97AE993F0FEDAD31834B6F78E23164B556A39AC1F209581F61AEADD8E504E81A808B1E97F79F987892A8F7FC35FED9B1A2E9D3E17BFC5AA64680DE98664FEA7B479567CBE307AF2A8516BE4CBF9EA030471428CF802FAFF85701AF96CA1D8F50F5A79AD63F20C5CBB954011BE4B1A7F627A8B5F5A0D022D27BA6FCB8D3587E8632A2FE5794C7E8FD09C9AFA3021B9F43BA82EF48A3B1F3E40F2FAE182DDF9558F7033773F5627906E159B794C4220219BF1A9878B175996A16F3CA1DDEDA56B16E63C504354E5E42FB90CE4D2C1AE7C93D8CE27480F3BCCC076CC253B574A7BFA6D3BFABEB3FA6A19F196C7E31A0D6E9477F828689FD951E0FB033DBEFED6C680F0FEDF2F43F48C0136C722601CC7C4B48B24121ECB6BF84D6B3DB240FBA1E014F7E3ABDFC1F9B98A16F4D39826BC1EAE44385FDFEBBD649BDDA129FC7EA3F50A5F481D3B7508EDEB04FDDB3006D6EE943930E3F0AB405D151F21E8AEE5BD87F225DA6E155158DE27290B2048D384BCC54F0EB905961AE4CE5E6E93543016F62445AFB5C39C3EA2F3367A0B8F0FBB83B37518C5DBE1CCA1DA9D0B54F34B15A1349A2F03563732DE14EA9BD238F481D9B262DF69D24A91534805ECF57A538D8F08B2FF11E96EE692DFEB106D3515A7C69386A781DB1D5434AC18713CCA12C92557D1E7DFBB15605AE3BA86267F3E6CBA42B6084478E460F092BA2649C8C94D66128FABA2D0EA7D9BCB20663B0DE6EED2623A061778DCB40373B8CA38B02B7A49F6940D6D11CEF549CE80212CE8D3A85CF2D774431343FA1FFDBC71C5334B1CEC4D4E0EB643E1AAD67D1A5B73FBB1BFE47EFD83CD17C798044A504FBBA5726429F41DDEA7B7265A76A48B0BAB4845704C771638977511092BF6C6DC9D574E6288C6A3B96BFD37FAB695F8DE20F28ECB27EDA70A07FB2ACDAD88DBDFB2DDF06E83ACFD3A136C5DF4811D34C242BF9206D579BA8DC6D20E8600B726C9F1B918EA573B9DB2F96444E17B6EDC15822B85D452CD99CBC847AA205EF79E574ED9625E33B6EDC793E5", - "signature": "0EECF0C5C5646C6C01CFCE8A4236C503F9C21F7A3FDF1B708851290611FCEC8D28234E40B9061C15212969D6BB647797B77E3CD2AE88051929E75E9A0D8EE4491E6E709DD1E43225C545CB3656C0F84520A56BFE0B3A26E2856A1661CC2BC5BD289FA800CE140070BE31080CA1245114624EA0C215E76C32921E54F83796F9CD9B5F0FC621AF39184C4857667414EAE4A2A7D18AFBE427B48441A99E9650344EBA609B879C42CF4DEB120FB5C44D542971182F83C87EAD8DF96ABBE1A7CDF1A75C538ADA01C1EF73E99F80B792F61A548D3A2154008B20AD71CE0C8AA42480D8CED5EE8099590057D15B339A8D22CB86E0E3FF8B9E902EF7603098B356CA6A3E8D8826B1B02376825B82420239F04AFC1088B16255EBF6030E183FF446745EDFC94B6DB334B4818F5421E58710703493859503559DE0AE797A4194E46AC916428FC84944B9F97BF2BE5DF2C3DC0E918F8AA58C73D92A052E59DA75AF1E3E30896AAECE657CC427857AC6EE80438C849B7D129726D27DE10043457BAC8B6CF88E91DF12ED3DD04B930ABCE64F4A140B551720FD7122C0C201D61F4856FD901673B59EDDAC1486563A7807CB94DA76A89E3B358A78BF8054D7657246200685FF47BECF5AC5852CF2AAB51CA8215CA1EDD6EB6B1B7CFC6D1E79E00692103FC124A48AEA58D21C1682761EC72712D2FAD386AD3153C1A07F40135F38D6E3BCA30F387DF057D4E26FE94E1B89FD1C63CAE97B0E0EB18D53C45F5A1C0332F35FEF2BCCF9192758BAC873D3C48506D23427332C89465C8A08516B1E0511C56DEFBDB891B15DE0A58771C31F398FB27BF63F3CBB9AC9713F75EDF32323DCA0D2CE330340B2B5946846AC0A0961CA3DF970B827C311F4E7D04A859BE995ED60092BB8FECC2B0C5498E9B0F88B4B70DCC50B6C01286494C91EA3390F162CEFCE4B83A5486AEA9FA866350A3A3EB411A601623F9D77585ADAA9DA360B0900EDF684095A9A581DE3949F85ABCBA9525398CD58A81E91AD655649FCD21CD40490A5892C0E8CE4709B1E8004223F8B842389306CD9640A3D32412B4DC53E3BF04FC39424156B3E797E7CA688AE6DA5A4113C8CBA7290315D6A6DEAFA09680857C18B696094FD67DEEDDF1D69A1A53F73696733CA54CF0BD144AF0873249CA50F897CC5B487247A1DD5AE8E7161BCE9C5723DCBCA44796CFCCB5D16B42A1EB3D2ECB6108DE4F2BE18AB41C287C6B4677E56802CD919EB1EE762306902C9D731EC5F0773F7CE7243BB6A9A832C4052F11E5E56D20BB6826AFCEDB7DBF9B4F72460BE0C45FFD628EF44F0BAF2CE179D9627E5CB1D10235D3AB21206EFD5E74A823DEEBAB0DA04BE8D9EAD7487BC96EDFB71737A15A27452792CDC237305E8537619930567AF51EA8E5848DFCAC9871C7B260695A340F03A48CCA700E60220A35A01B2E195BC3D73A5A8C6918567BAF8EC47B473DBB487F77CB37EC6E37D2D6F885208AAA845C5ECFBD2F128CF2D5A16C167D26B00CECB517E753A121CB4CA8EC8B3A5F735FE28BF6E0B988E03E6FC2DCE9569721E1A03D91760C0EC81B4C1DD31470DEEC860469DE3A74777B5A8148DB3E7BA6AF995BC8BC14F30C7567886CBBB1C6D40433D93D52D9D866D897727F55558CAD5871D461ED8756938048C877C9183AEFF67132CF8AE015F59BBD60DDA63B1C2DFEA4FB19ABA2019BB52A135935F73BA5FA359EEA99BCB8254B3A3D82BC2A8AABE2A653AD58B2F13609D762F2D7E89370BDD46E46E55B9B9217A5157BD696ECB992809D1DFB607F1E66B77E417CC0EF7F3CAC38705619BE39FA625EAE2615D9137C0F702A5206D95A2DFFD7ECBC308CC453CB29507B8582A1B200A33C24F6FCF9D3E37814D029DF14D9D7E8D6A98B36BB75A1FE45FEB1A61F212C03F28E9D45FFBCDA5796C2FB2B9BE9AA778BBAB82F9C2BC4DD45B64DDDB6FB1C71F57E11E49246606947A4863434C8CD23C0080F11B31DC7BC0FA92E45415C57314661C1ADC1358AA49EA4D69ABB9A230BCB0D85A8F2885D261584392656B15643323B270C68ADE3D7727B35FF8948B1501B8458FDBD59282E713072F0799C2EE69EBCBB441CC1200047A23DA61DDD7F73D59008D9A802DFF46490DA652B6EEB1BA3D3B38FA04FC2DF2235380B026AA69EE90DF21FC5045895581D27AE6A6D8F99215B116CEB03F9C667CE8DCA4B63F1B875A2B2686B30D1A59297CD7A491178E3A81C83B907A1C7850092C355E130C3C41BDE7839B115E8A51D729D252AC62CE03E8B9EA488338E6ABE1A1151FF037C94350FE5B89964069FFE68C238B901B72847385F937F148519C0653F932048D6B0E7B57092625A1B4BBD72DE1D16E7D96A509F39B3A9E50D1FFA7EFC5842DB79B8C15F2842502278F5125EBB082C5EF78BEC9E872DCAD120FBF2A3D544F15EB51E7C14155905C50503A3B12C24ACC6A37A051D54C6226E0FBCC5DBABEF1C0CD4A89463873379CD95B3708C5E56FCD03C71B3E5788AF19033DA37771AC10373544CC25696F0A342307EB92F58D95353F45B5B5791EB3EA3DAA88CF74B3331C21DD448D00A1DD026A0DA7443B0028D1E35A304B0D7DEF9B74C09C377A9A5B1439D64E7D22C687FE420E1E037D0C1AE5B2DD33093C1E130B5D8428AA2E430CB5FAB92B316439CC9E7593628D567D7055428B7E6326E7A004D0820C22C1CD015DF8F0082F2FF4D39A05A66382107C8467F00344639CD32F9A4BAF3DE73640F06344D64BBA6E4E830FFB98BB23C02D0DD9D1AF3B2E9224CFFA7B62CF7CD552DD26128DB065C1CA91083D7426195F9DB63061C20D9F8ED337437B4D69BD7AD9DD13349708FDE783E86BC1F81BD2A317F3B484DF3912A2FB97E8F5AC62D14ADEC7A7D1029FCA2DCD81EEE23CA87D66BF43E21273D57DA057B35D8FF70404C230989B15DBBF3B057367C005B5ABC61533C623D2D774546119AE87B2D5816B5E7D5039F2D1FA568E338D4EA9FE809126B46D2EC92EDAC8717FFA55D678BB94F0C061B0744F7006E8A0A703156E8884A81AC0D8BD86EA1BB7E682E43F99E2482EC27697293A00792676042A660598B8B54029E00D5F0C7D10B07E4275620C3D193D5323FAD46AFC4B8F4AC825618E872BC184AA97DDFD96BB395ECBA6C3D42580F4BB877E5AB7D96D985811B580417D6B006B1E6FCB3C14F84AFDCBC38D495674B8AA6976B036B5306EE593A0584A55DF7FF214C1C6930CAAE7AD69423CEEB46E95D0DE88317052C5C62B77C43CEA863AFFB22F0201E5C451BD9ACF2D8746346E776174BA21527EB5A32AF89F12F9E26A99F15AE8017FD9720E3CF71741C5D7A23DF373B0F229B89A1E1849D569E0461267267BFF654CCC010F135AD41EBFBC63A3BF4805405F3308095A90D4C541BD82BD62D8EFEDF4B9097AEF796C199521931156A3E7A59A7641F9A0D6542C05EF29CDAA28F5B733C7B30376C975FF08485C8CCE4393B5A8D3735A13FF6704544901B22FF2A239BE8EE2C8CC56175FC928E3676209A003DB9D7BE5DC0FA7C6B3A5CB92F2BB9EAAACFB740A8AB47A509D2BB76060196F26D54690794C5BFA48435B79C854E79A538F1A796F1D4323C016A72667E85DA2FB595E5F8B98E5BCB30FA0BD14EEA3055BC037B2D11B6C4C8522961ECF541E3F2A98185ED50E9EFA20516B0353B0DB96A6183AA9EA9C2C8CB7175158FAC07B08D5C01089B7E835D10ED00D7B3CA28C22FDBF1E0821297DF5EFEE9AB47BD245CC29ADE18C0D0529F9070A2F961D558012908E824B89D95474D0201612B474F7C2E4CF4D66AB165883089013A4A60DA26EBE8D7FF70AC279CB81A22229BB098FFC26EF456B49878913A354F66B8D8F730FCDF1FE01161E606FB890B9923ED849E6DAE68BB3364E6297B66682BA3CD3F0FA7EA4B41B8C96C70B16D606DE17BE72119251F6B64DC78A97924CADB77C228F4118F2C93CE007A4A60BCAC6950FD2526670A9ABCB6436F8239DDFEB8905B69E7CA52BD6FD1D3669B24689E4CF050C7760C0001B7875F76A195E043ACD6AEE609E76F1C800FD0ACFB96D93BCD5A0FFF5F979A96CC82A376DC443D694AB9D190A96EE34D6083702DA6FD73233AB5DC2CEFCBEF22B5B32F66565D0DC948297D83FD04E919CE4705C26506E896943C5B1CE8055434180CC62086FA39A12DE595949C40EE564E5010E22838ED76DA6CB72305F5A160B04777E10B24D7B502EDF16574484DF1872BB115FD6E91E0C0B0AE2FF35FF01F8016D8EFA6D5033E7EE3138769D88A96E20637AF1F435FAC584F94AF8F9C12E3DF67814EC28CB50C5C8C473EA39AEB6080E127FED93AF5CD75677003754C9E31120FEFDE2B23EC17520063884FA1CEE1D4C0FAF3EA7139CDA87C050CD26A349C55362401D311029BC2F21D29793FC8661DB90DC18D96079AFE00EF88B007DDA214BC8800BB7BD30C942CEBFBA0DEBF1E68E9903515C990C49D323A73A804B0EE4EF439BC5B67F298D63B9932C201634AF618DEB8C49DCA06A0FC865744501BF3804668F3331155CF61DB1DB6CDACDBA1119D3558F1A0BA05633AD518C563BCEE51937C0283F3516B812AB2CF2B80305F5DC15437811EEDCBA7D236E7E9AA8BA295A7E8412494E683F5985B920343891E4F44E585A6785E2E6000000000000000000000000000000000000000000000000060A0E12181F" - }, - { - "tcId": 27, - "deferred": false, - "sk": "C8C32C98B4C3329B1E9F9B8B0A06F728FEC8DFC05CD45B51C28273061A7C84B44D03DEAA1D3D423DEF8D01DF94252EAFEE18AFD0B714F246A2AA8B22919F4A64E8254BC8DA58D79694F68A8B33FC23190C4D19E3D686EC528B46E14D752CBE218D0E18B655AA5332AAFFF4EEB5CFFD2BA6A03F60DC018CD23EC259AA4325EFCE08852158642851628354014253336656040034734085244624702650458046023414141653265662553257528848144434538583171237621870046622542527580662760688425754461883673651187381743864383543514734285686547356774154037857147010824422821820372371434640278657362264124415854343344041688413722261224658655223800244426352431335075843223847830638802787087632058358458134612063704650052330674634702657828852755171178100888071574872500003761125174467551513406085034688414064261281865718534556361580681066615474883681774570757571780007105873237730643787603255741251882778647716627735424330287653567230817703068376113812788174132853265501737207541765673284844633087711520768836556152784146844502445608448350455765277306601008336883210200716413782342871820515037658772672513172866057305014605013778856128828263337372405472843534375648655082510264478061188683265047702226038855710017543066112306303885632257413744062041317752202814804005205448814280410780017846728458263376183744528251332866682020484544067715461251381023268133503550626017320763011688141043558378413875642643444584351184365058376728644264005672381788337041681643525641530354046426331448556436657662128333156784163856374755524078102415500647382668666204378324674242332458875560880870446801506724870770075377623558535018066536113077736557373140121445368728505234510843712443083486066118634707435307287834841377048724203643811402168118565240877002038527641833114558786071676284684057368570785252016484650654480760442014125342136012513131513754542527403415643546752574520100488478715505263884185412513443846738708103777317714028531710677723682545550823825506760431583105357435861166168085225017870015035876442236026623862112188700714876376877706235072035840614340577178021553082422411251301420001307586123370726600337582487275247806637312456726385287223783713615774466050881878126110710021758600135101147142066365521572708410557043546161410781630038172422202645550360675605422888073255353264416833160257185872065350608713265217047530036306438828400667786630573535515217683235415121861604404228766416241310412807607544783206736820630303115444301271607246665073637418272420826411083048741645574851556481310322648258642846872020371271453707105300457683437487543257460657574378450022804404154248422852870054400115704171748041775074284552866412884625787625020238334401546627850511538557453800533335000553567035164313872271652448031663187004542613853645488711616002127354808730021575550780772055654173636682015662428213111586672337018624237806607430261432561653583383546454223153687813363744535756030611834227116883466042873648850082482071801637617701364885353218608856781116835784815225000572468806855765577805768462876401546171442778806140835684815656874817750328776567238860658770156531530633503227851364168542031232554515285878430550188057083146685505544383510160372216041617018142A2055798CD4A9FAED4129F4762117C2F9FECB68F55285D58DF9B1D97319AC4966C0BCC41CD28E76896A2CA0C448C002E606702A1D2716B18F92F3D248C5E576EE28DA7A4928CD072E2E06960D642D78C34A55DB793D4C6C27D68E2E7C2E05F3E997DB884F02DD4E294C0A37EF6655A74F98B3D118D63C8975645DD28E326540E289BCC194695E2962EB6F573FA010D9AE6DBC9DF30344189F87FA5A12E7F096B409CF4905A15010DD6CEF55A88E3A39ED196CF05DC1FC8A5B706452F4E49A2D07DAECE812F69207EB3E4D86289E956731033D6F0B90E9442840DD8ED3D4D7298836D086D4F171C0AF60644B7EB187EA185FBA5D04D6C42BAEC690B6F1D68764FFFEF1C719F690A2BDC241EA2A145A7B9193CDD67C671D14A676173F352AA90886919A765B2D89F46E9C13F35243982F81CEF10680967CA1D5AF9331BF64951F1C48CE1E0A24918FB07573F3899E19D3BB2C386C943D2732F5D287996C78C67DD2031BD6C635D53C51DDFC4B71A27DFEC7A308E568F2805F667B1A85F6436413A186571F99CC842C9CF43146B588DD7B0283C5FD1D09CDE662B510BD85FEDD31E3DDC957583FD08A1F8EFCF2CEBE014652E64E558EAA832822D089A3D82911D671543FE6F31812A435C1741BC2AC8C5B33CE4E3F546B970733BA7384152FDDE245FDD7989E1CCC430D134E36049DB88A3817AAA482BAE3B53D9A448FC536AE8F2D01919588A00A2A2CD1F1F48710F5FCA8709286B4B7E3F14FEFAECFBC830D3DF005FCB6612B782AF5DBFE7C2436DB6385A0F2C929849785ECE26D52EC9CC70837FF75C7E6D280CC9B3A61C8618C2E047BE4DB9A6A89E22EA3AEB8E2953B5336A388E3837DF09BABC71D308298D735D37FF4EF3D0D65247B72DC04E1B7A61BFE131E4264DA5A46B664FF4C44279852214BBF4867FE3B8AA274ABAE01EFCD237DB8D41F71DB2B386F596799C670C042149E289FBC3FBE0045994A5263E710EC3591C770717F5D6E4362ACBF5A2C133E9896AE4B59553353CBB626F854149A25728C4113686F16D0A6EA7BC54C8DFFBC8D7AD3892AD37048912B09648814B415D74408AB3868D6B1114FBF9739517D8AF886316E19BFC66D55AC4F76C6814E96C6A8F846961CFF17C8D6A1FE362D071D5013B2349724BAFE710D990C8CB0C6438535C5AB62AD3948140C1DDE116B7E552E3677C001DDA26E3D8B53BA7506EA0069B90A26FCC35FF94272C1C90B3D910FDBA5FE8E2AFB5B955847CFA4DF8460CBDE80DEE5DDADC25C00418C126F7D0C5B8C1B9D8710CD3C995500AA245C63D9497F6279130B23347A95A9D5694B512D4BC088290620738CA448B08ED871DADBF1725D2348FC4DD6FB64003E044B67595F64D3514B4CBEE61E9E12F1163B56C105EE952616A331B263330B29DEFF153306EF9CF27C9B178F671E998C07DA69C9D38B750308A7D78ACCD69EB30E1F04D86417B76360805576DFB5BB9022EF9D6FF249EF9D66255A03535CAC6323B084C5550BDB703159F570F47196115BD67DE8BDAD32C9BB29B7C6FF96EDF4313B101E28ED28C37AD1DF54FA6147F3CCFE8A890A423B047A2613CEDCAF70C0FA123BF1377482C1EFAC44C483539F54D3D54BCCF3CDA71AB23A7E27417C317F5B1DE41E99CC1F695CEBDA3A2ABCBACBBC7E87BD1252DEA50853F4C47053E10AD30490FD3244B0AF23B7F869E13F96591A363E05574808FDD2536E7887C0F621600B2352E3660FC80B7DBD09C4D06375CA6AD8227D60E19FD9532BD932A15CE6A79EE821447D6DCD26367CFE447C3FF99A408C2EF4E1EE16C0B63EBF1101FDC0E66C5F5F4E99D277876C7B007F26AD220741967A0023342B09CADC11C0821B4E3B42F708422E36449C37D197D4652260A29BC9DA316009DFD9DCF2FAD8E7C66E0856B16E2DC625DF9EFEEB36D17E56A97E85BD00988581F28A742A85D6EFCBCA370FBAF39F1AC123922CA40EC5B180D40F5EF9EF892E66AAE5AFE52AA7E0DFE6181A0565CA6FC3FA284DA2DD4F6FE76C5F3C89C38F8C635AAE6B006829BCA1EFAE1C06E35446AF3D64009BDD36C17E5B12B5A03A64E6BC2E83BBF6E6C3785933564343950D229072F11092DDF65DD267C9685574D6D8AD15DA4B9C835164E95215045F7BCDC7315374289AF7EB80D538F6484F5BCEDDB3AAFAF69E1A74B177DE4FFC6A869B9BD98F7A3E7109C9DEB78898FE57BBBBEDA72678E7035EB555478BA70E405BF2D3D8563B3AC065627BE1F4419E716A62095E6A7C5A54B22327ADA84530EB5761287967E6D6135F523F01C20349E337AEE6AB7D57379C4E919CDABCC46326E09EE6A254C08440713FE744CEE9BD8773783F27C28F657F277FF4D96FD0A1E0842529D1A55D1120E0B0087DECC8244A655C43D33019A9BFD54ABB232739A6D21DB35D8DB48B8F854E82FEB295005F55D9626532A8611AF392B67B0191530FC64422E02F9B99BB0E337C663230B5D7C92CC34EC68ABD6D9A32657247D4F4E90139DE57CBB0CA2AD179F75E244AD5B4D6A4A21179D5F423A125F3A52DC6E7E99959F3E3DAEF1C56EA39ACCAEE0B4E0EF1549763CEC5E1A138CE4A2B1375A370E04259E67ACA9E833C2D969934F9A494E03F10F3B843C1A24615BBDCD322DCD2E633960393DFAAC490E69ED03E9DA0E748EE1C30683034389D6291D6DF8ABEEB363F5323A20B8E09715EF0B406963FBD178D5F46954B356BF20B90C670F7946516A7EBDF67381BF26E5AE7AB0BB69084B3663E980F2C0F8E5180AF4897C6A0DC2DD052417CA772DB1F48F1336B49345759677AB31980F037FC4B6EB7546942659C5BB685FB2C862C7CA37505BFD34DDF9AE301BD9296F98C24E110E410068916F98D5B1F320D7D29B125FA3601A77DEC33458BE0875ECF4049996544D2A5B35C628CEBAF0370A8F8502FD349A3C431D4D8ED56281184723B569EB08A904CDE35647929AE39E6A112365058D618CD44DA7685D331B7A16AF87D735C6766E47EB49F2D93E05E9F0936E923AADD01DE901B70555FA8E4E16970D4272B29CBC34C1E3B57ACD0366DA6B3D0BE72DB205F8BA635F0B32A3A38B44E257382665C354DD0182C0B3956042A87F6F98ADC5A2E1E7CE21A4E21C8750913DC0FC955F2E482D41DB96C35DFFA5417233179EA6245BC10B69050B4074847C89DC5E8AF80747E9B4A44AD7ACD06D6D051A3EB7B0CB3D8383950BE581DA314518C85B9E5E727FD3136C7A1E5B35DAB57F4B6331F565C66A9753743C93FA31E8BED38A489B16ED62FAF78FE5D69FDAF311A1CB7FA4AA4F0F1E56E3797802AC6F2885CD7A1D38B2C944C47F4F1D937EC11DED2DC2D8893A651D1144629781BF77E94DBAFAB247B4955408FD4983CF62F106D93D49738DBA52AED82FF67A984C749C04CC1383DE98C0AFC8457B9B134B18084549B12F7C50949FC2E5C136EF2CD2A05B81EE1DADCA5658873E65D09E0DE3F6CCF51DC6EC5157EAA10BE575101D83614A4B679B196D19F351B4727DC4B67C5E32843A4A2FB41AD38741847F", - "message": "7C29C0B8E2A111F457E2384845E7698DE4BC9BAEF093F15EB03828664AD31C387B247A525623282460D60290FC479A928024CF62571A57F77B17DB0AC572CB59723490DF79E9B1B31EF2C9488B6D758C43EDD9162D8F6C0B03F43B08D646172A1F8DFD71D4DD805A3AFCF1C4265BEBB71FB251DC9DEAE670A664BDF943ECB00FB7EFA37624953F94CA760013FF1270C1EE7FF58756CE19C204220713724AD03B10F1D6961CDA361539A8AAB6ADEA92AD782F441428C0018D85C0505BAA793C752DADFE92BFE8F033931D47575C9F83547DB18DAEC0FEE90E83967E0D0DC93281000755303F0F5F05DE041211CF842404CD5E24DDFA3C7C83DE3EA21EEECE37A52E16DC80A350B3A18E88EB3C81C74D25B56CDB446F6198DC88F981F2B1ED8DC94194D81CAAD971A9A3933E9319047C5F31530C7C98793A0633875A14FA5635CD1B0441FE267E79C1E874BEA968CB63E20E7C48E7BAA9CE8393FF9A239B5A1D613DA65F7DE78BDB793AC72566FDCD06CDAAF56E18B773737A82298902F7B4890EDABB766E990ED87C94005A2E2450AC1D0192D72468F81DB414F88CBF07707A95F549B7A9EA0760821AD710D52787730EE8917272497E5891656176F991F254A5D582B5975F95AF740421A3C18A82158AF11DB15C154F17ABE1163F997C64A3BD989A573D12642B9AEE87C1612A39A8A4FAF25E35AFED3F2DBFC8FC8A2F9DFBC683CDFA3227107C50526149557CD773DDA16E36782A278A93CD7F4D8FB47DFC37DC3E389D164913316A885C3A800DAD0C57B1082BD4D804BB6A117C3B41E7D8AE9CC9622AE3CA8EAA9A0B502FE3F5A449BA8E768D2C98013F681C68A5F4AD3CBBB83F302457679BCD3F35C4D6176DD8D2B670E87EA291EDCCEEB9917F98CDDF5EE1689DBBC85BBAA30D191F1965EFF8FA9B0073D30B1E2456FAF880110BA9E75E4E29C6106874D32944F49DC7E7E7C56ECB9D287F2C2E87A779052F9B84FF97AAE007012A5EC497C4809F0193C69E5B29940510A354C866505424D4FF3853C94687636543115A73DC407C47927EDBCC4E0567EF4E451F0E464A1385D2A0D740C7327F6E92EC6091845356C2620EB163D9F774D7781BFBC6F6F652A4A2DEC73203DF5643E1B4C3C3DCDF0B4A0B160598EFB56499D2DB1F1E76612356AF3D708F9D61D968A6A0193D9146B2983972271A4C02E2136E6593DC47FDE4FAF2540A8F7744BC3230529AD1C9D2FF65B7671B5A5B16AABACDE8D45A940ABA4171E21090AC6AFF54CD8230F7BCAFFC42C028E6023E55DD02E4B7F976998AB5614A5681C615BF8E9E6959B038188F71C75F6DE44A6B0498F2A9254F3B0968AE7DBB49872D775CB0A5725206D648862734F202DF470770AAD184F822C56400F16F30F8BE40C463CA3EB5ECBB15D51CEBCCEAB43BFAD7DE7679894B90419B65912D67DCF2335212E82EFDB6267EEA331C1439BE2AF62E584C222C1052AD91C7F5DB6AA649F230248A14AA6A532401A28ADCF822089140FCD3B1CF2358DC26939850DB2721750F1537424F6BF2020A1B4684ED79402917D1028C1B59076867DA809D6C5D3F47277755384C20624388EF0AD68BBFB6A63005AD1B6E48ED654E8362B2AF7BF114F2D144A420712FC4EC71D408BE55EBCA8C2F185E7132196B1B76AA7BE44EB55DF7C82C768943D649631E4D87B408DCF8FE470164D9E8DD1F48CEE7F6BA93E239F889119A4DEA118D93F1474E516139036D640EC788AEE708637A619BD1693BAB6C9EE9EE0C495C0D0F8912C0F14199AA69B960F53E4FD8E2771DE4AAF72117A5B2388FEA0CA3BDCD594D1760905F26482459BDE80EEDE3FC89F592CA16B65B27E9A21F1789BD0327A26EE2224C61D80AE8FA6053480048D15019A80FCB5F3B3C6F64C168690E4384AC05E856BF341531045D2952F2CA8BAA0B8926CC41AF2D8BC5A1576292DD67114D521DD4AB535A77E5E9BEF8EA01DDC7C65446D11F90D6CADA94AA1AACFB1BC3551353D09252FE515A465C1879071F6FBB035DADA0BD25A022B026AAA5B5BD420237FF097099CA2402E68E4530F97A003E50CF693D1DFB551DC4695C760138E88B8D11F3075DBF8A6D9BCB9B1242648C0C9DABDD9D49CF132B0766302437C0CD81A0889585869DE92E6CB30C31265C84F58E9437CEBA891422967AA546EEF720A8FCC16EC7591AA0D47998275DF1AAA5ACAD1E1C5868CA430F4FEFA0277262C69311FEDBCC083114AAEC9F99FD98631137A117A9B48B32A6D88E76F96DC58D741395BFC102E147C456D3A78A0FA3D186485D65B4E6755B53D301BD13CC88E75277AF3CCF1EAC6E9C56FE1F10DE05A796A14381551705234F65DD6E717E9EC275E38690B73973C9CAB27DB909C5C13041723BB18EFECAD808667643E87620191008E4D10F471AD153D27F1FF00D8AC6A8C5E59197AECA5AB496D8D10BC79C49D16DC7948C6AF62703D36059587F6EE038820A84C0F287D79C713B066E1DA5B32BD89E5FEEC248B34AA5841E8666CBF09C47EFB17BC82170CCB557D41D40CC87F2E6C0246F0B272733854CE162538DF34559473BA5979AEBFC0D6A16EA7B399687E672145A1149E382954815B41E7E37CC415057D7536E65FA1A35B8EFAABC7B9B0000E08B593496B01E8F14FC950632C659C0A7F7D59787C7FE6E8FA7FA0211A945ABBA5044918CE8482C6EDB366368A9DDB2F2BB66C146BB50251CE61DDEDD8D6A4A60FEAF0F794B7B0DB91C52D7ED1A54AC85D7907BF3A5A96A60BDDD08F60148C0B3237DBD56628982375A67F025B0E3F9EE13DF254E1D6DDDBB057203CEB267200C7788D01342C064FDDE996183646FD3C1ABBA5D2155383CF391FF16C78660D0BBEB549483A4A4A971017A8659616FBB1C3A8A2E83230B610C0C74B8EB32667765F3C2F31F8C0D4BDA3D812DB64448684AEB482DFEC5C37EDE742091EF7EE6F22E31CBA2C9B9A6656888F446A1E9D52D9E6437D22594A830958CACC6F175D4CE8423178B71E7CC81BD6DC2A7F6580A8A3A1207C34D6A1646BC3D89953A63D22A30EB9FAC74103FA527843D3BDA656D1F22E729C3A004B923D08C9CB18CF406FAA89D0D63782C7264D5A8C8078EE6D259EE168A415E7BC83E4F17D9E674154DF08CCB21ADBF5B35AC28883F6943083AA97210C6DAE492C6CA4ACCBFADD99AED15110B10C9904469B4F06ED32546130B0EC4B281622A5EFC9C94B1F2280F251AFCAE857C4E17FF5CF472F038E02E5B7B3CF5CFD2F3969B9B8D5A27C8EC38DCA4284F0280C24F01DD97A618FDC5EB57C45D9E2A05B44E69FE2E47CB50F596030C70B62437F2B91A67FB84205D95CAE259AB1D5FF0454C5B4D87F439DCB7FC62B704ADC7A84502E1BD8E6F52109BF0F36824834D574E07B9375E693AD477A9D74E94BC4E883206DCF875AEF7FE84B9B7C1C9B1858E4BF6735235FAAE21FA566C866ED7C952B1BC19A911984EC25AEE310D8A342AE32F46255E0E00444CB0EE90C37152EDB6C741F5F394B5D47154825279465F0F8B19DDD85B8D9194A7AFAE5FE609A245AD68786C9AC044C008A1B3EFA3A8F4FA0FD49A65B6FF562F33DCB63754BE76244326FB6E416EE3267F93D7B2BDC4705EE7021D5D2EE66BA8D7B9DA7EE6C354E05470B31406DCFD2C32C94C22A72DE90E5A9DFBA99ECA95F73A014A3E9B15EFCBB67FDFA6D3CAFBE3ABBB28C4DEA6AA21F87693D68F0A60331786DE02BFA9E85A8D2AC8524EE184EE738BB3FEFEAD7E19030AE883707DF67ED12E8757B86E6E5FBA26715DBFAE2BE0F90453868931629FDE97712E08A280FF8888007AC27DF2C7113C30604C5DB17538F026F17C7F07D2A94AD5AB367F9CEA87BDBA712363D11FF5CF0590030BE9B342A7ADA48C08BC42F923DE939DE79616CD346B3511F41CE695B3F939C101F687DE7292CC96691EF3F3CB653F4A67D2EE09C791F993C726D574440EABFBB00E5E6328FA70D69FDD5F2EFFFD37C9902AA45EF4E9D06059B0D8E3686C74C94CF2F0032ECF740B31E3F297F15343A0093EE0B8D7F8EDA1118D329D05A1B992755181429D410771E37B56E28AE2ED8C4DDE8422FFE91ACE348E443640578687C57D79DFDF917F8E60E0A2F1C6223056C373F58C297F0FEE3060D31DCF6851856D1D05BB38B1FF426BADA10FD84B2E08AC149F91DDF4A5CB38B290DED4EA3B02EF7A3DF42BDC6B6205D281CE4A48A1C13FA8080B6B4100AA123097A4140415EC7CEC57790D6EB0B4200AD3DD9FB7FBD056A5E3E9D7B7EF47F44A63DC908B6DD8B020854618F7662391DFC35A88F4F5750D282F81DDC50D0132707174914293E3655BD2942C09F88627C0AFE4B921B766BEF41E246FD23482B5B14F117E8EE340C47C7C405BB3692C4C9E541148C2B38281EF0274835860E19C2D48953545247BD1F7A76CA43956C069A17CCFB4D0B0FD478556A209B5376BE9207AB174D2CEC96E09E1F8C0FA07D8920B2ABAC3490216DEBC67030E9285B3EF6767AB11E8CC935C4019B7E68FB9AF8864358E6927D350CC8B9A40662A0987C1C8877AA9903CC89A93E1979ACFA279FCCD2E171A467B76E1103C4EB166273ED7B4878908B67DB77C4FD4E49DB46109DA4BA78D69E03B48518F302647B8186F787F4CFCD87CC5A45B98F7558ECD0612378306C9D69FBE23B06005CD5AD84F73A563B1A3C7988CE0157D2D2703ECA8575D8BFF972CBED32A231395655DDB2188BFFB413624639D361B3388A9C9E13645C563A87C610F6FE79AD50765CFA8149E27F7083A316EBA050860A69BA56D002A78640D71794980C83573A5DE69A697C2CF2E17C90BAFAAD3D421C6E1D8A55B3FB4700B666AE3CC3EC114E9DB428F27CE427E4101ADB49B84CA7855458841DD1F4FE76D9074D940102FC47EA633744C2A664E22B5C5AA2721017F3FAAF4FB033FBB1D508EB98E1D643406ABD4D69C030A2349408C80993D9F75271F913D7417DA995443377E6F73A7DBA24E034A9C4820117D1F0BD69C93FF55CFFD2D36F8078209F5711FBD1587435517291498926E7354558945F721D00A73014C06B2C9BF04B7E695B9109D769BC2172CA7A70700A1D5AFF6F5FCBE699FAE81BC34B0495A82BED01B983444224B4B860360C07F8C3035FC4F0C4B7DD4D37ECAFD32E8C121C677ED263338359E25BC4173D191E869ACB4A5F6D20FD16FE50454CDD269DF8CBE5795482A2B40D52BCE5FDEBA62D9274C9C67127580795BC01752740E606D849AFCD6ABB8340613C61A764B6B92863779622E40EE7A8994034E7D303F07EFA11ACB70419A53897ADD558CFE157CAA3D47917CFE0287500B3D70FE42AFE36853188BC815CFCEC9F56030C83E85C60401912C14A75A082DE2E0400F6348EAABA59312C51A7E3B6A5B39D606306A304B4DD3472C5B89FC65DDA54650392A02CC6761336FD114D848BD889DA4BFE6D32931793A6515510CD802E3D9F2C6F8F2F9DD96ED039462C587395C7E6861FF48B7980D492C23E0635464C7D1969C12A43BF0FFA3089E6B367AA65D4678A571A0D47A75056B34E3F8819F8B6ECBDD6BE580D423D902D3C22D9D787E0F1B6202DFD392AE028292795FCA0177CBCB09AFF8B579A87A854432827CF797E494ADF9F96A56777AD6215F284EA91D35563F25355D12BD155C6C364B0C8423E1BBC809E736CE0BF03E0C0B728F04E6BC8F3F07A0D952AC9D9530C77547B687E193EE2D3565AC755DDFFE880AB0524624E17E019466B7D0E8FD6E94AC2BEBEFC617BCC5D529C83A90D36D57A93BAA0C2ADCF360377C9E9D58C456FE9F3D49CA37A8C3B5BC7C231842B57D320310943FFC0ED2F5F622988ACC7842F8410BEF0E0671673E7BA61AFCD2EA83CF066A169BBD97098F4B4F3C9FE73F5CD779F502C584849D1AAB52D7059D1D4432C27FC9284FBBEE43D07493A38B139152ACB71A171D454FCF936656ABDBDA03DEF3C7B27891088F940C200AD454308001FEB2DFA0FC38FA74F85A30DF4FFA64DB48E7D40C158F058B58174F18BA482AC445A6A63FB54CC6C7D4C8089794E8AB5B38C41C7FF4C6A8A5F294EDC3FFCE3C01F2C5C7FB569CA06567C8D3BD34F82046DB4EE7F7491D890DA1FDDC55B12D90A7853D8FB52E86AA1FBC669C7ED349A2CEEA9EF18F76C23E817AF58101BC5CCB0346A607D6C60BE5CCDE5DB9889E040223FE98B17D31D64E8C1456C01353887D75EE3B82D66CA0679B1C2366C44E52D73B09D48A39D1BA3FC87D73772DA601EF442208DB763F0BF888D28338709FCB008B83671442CD9F7ECAB2C1E26428391E559306904FDE5BA21E1757D94F84F18A5FD8A067C556834AB257B9D2E1290FE0ABD3BD622A2AD92BEB2C6BC61852D58384A20B7409E4F212F630BB280A46CF89DD702B2508752D6A4DA94BB769797B6E7FC318B0B3ED50D7F8C5D8579526D536E4D43F93C055479D53BF6159BCEAD8CE87504EDF7DB35E1D03EC7B4F13802AAE0207A2414802BECEA39664110A54C37415EBD7BFD5D73E871587967F24EA34B7D06CAD805EEDB95F1023B7BC3A74A59A6C9F3A4737FA1BB087012E0162CFF15A539E86AFEE30144F320FBAF088C6884489F84F16458755561C9CB0723CEB6ECB134083C3B82E93BBB57FCE8D51374D38746BECD09A059AD6623EDE82EBCACE009C0C27D5FFFCAF76C9E91BDF5EB895FA1E9C3C0AEC0BD73B1582C067A45CA5D15E2D45E7316CD4B176D9DC7241B05922A682DF919B2D2DE2F45942D3AE254FA55C5D90B8DA3C7DFE2DD8381AEDCC9558566E8DF302022FEFE51F23AF6A018AAEF3C93FD608B0903376E193CB1C13021808ACD538D3426F9B3399686B6FF4DFC0A4552DEFE49D042BA76136719D62884D8B93A349C22E0320B823740DDB3794AD53312DA5608DABACF69767D76327BEA7A644A304A132F2D2FA8E7C8F4AFAC30E389A995C0A2F912E98447CB400FEAE35B3BE089F46CD48EC8E38D4F2BB44F1734C67D5125D7266AEE3E9D1E91F800ACF8038D43B6E10750DADF6CF70DE75176A2E9C340BCD2F6D87F976AFBCDAF5E35DA9B268D3AE1F0F8172A342CAF9602593A5ACDE03DDB482E80B825A7E91E8B0EFC1C8D00309BD170D9F12BF5017780A54F440A58BE4A5257AB67190C62DAF9332F3594303B419D44A38C3A8032E38599B49872D241AA44905CC851DDD0750D04815ED88711353DC2264C0302DAAF2FFD34E9716FDF8A81F7CCB5757913B380A68F153F62E0BA8335F8525CC3A20145C2416581612B9C29C0B1B941946B2624731FA50420716162C64AACFBF94B43B10E59E0AF3836A05B9335B0C44370CDD2E45BA817631FAFA2E0ADC801772F6F71860CC2623E1A802B370823D02442108E5C142B68CCC9CDD0BC2EB9B861D763C715D516540F19E70FB474E120F06BC19A6629E8DAF67556AC60D17C252A44901839143BE5EC76B834FF11DE13762EB23843D3FCF1FF9CEB41CB02DAC74ED6219288575FA294157E532BD877D1B711AF3B98CB0B4BD7286F88C6C00B6AD9E40D66F38525156A4AF35F2FD42A5F25A201C66DA4AB5C4D1517BD6CC9FD9764AE2756379D73C8D81CD044174860FEE5DC42B4576008F13A3504674E0D224A9F1AA780C3003B7856692676A5E581418C65BA9F049CA20C3EFA566315DA220E837639A899ED54A07B5741097C47FB90A81A41700BB5C0D8C3317E27A0A6CFA77292BE9186396BCDE5C654C565754DAD120719E571A4A14207CFD205BB4A66C02CB68EB9E50DA7B1FFC324AD07D8A8A54729621776FC5DF15CA39F3DEB6B810A735CAE0E1A84C6842E80D1CF95FDF5A6FDCD613C54DA1CCAB4994EBB81C632D192CA9AFD7FA662A865C6F193B7029A9B6F21041E3D13D50E5A1DA47D3D3C4B101488D2308954C801DBAE5029E866E869167BE7DCE6476A64FB245247A84E46B5F0D9FA9F7BB10756FDEA659788C032AC654CBB83F23BEA1F285DE190BBB5EC4135E8FA1B134DB5D1FFDA08C06682C2DCC51E0D848F8CAEEAF51DED21830730F6BACC2A4BACF7BA62D14B009116EF2D157F64A7ECBC971D50349712DDB0871D007B2FBF83A832416CFABA2B9CECD37207EB9DB8A017AC266A5FC28DFE64B52D0CD7FD7498F718B32804CF98D2F17D22C2957782DD83F4FDEFC8A6AC5B6A562C939D2D0A0FA6078F7E6B4C95159BEF010C1DF8448158BA29E1FD1AA076972E64A9D534B1F27930BADA08EB87BDE6FB0A691D4379DF0001D84F2F833050E18869F2FA7C00A6481E4F87C75483310949653D6B91FEF1116F25E5EB0A10C8C8723E9C1C80F75C2875FB0C448B3E25E7B359304C08C310148683E1D8391C432A8413057A7AF45289B1363EB203779550FE1F074D3B4CDB77B90700E3710D6EB4BD1FCC209F2406CAA67B98E44AC91B876762D597D0F03A404394AE81BEF8F54A1A898B2F0F0CC3D3B6D84D759D1F1C5788BFDC7657794E384ECB2D5307CD92F3E135F35720A44743D93D111F38791B60E7A64F51ECD6801DE0ABC356409D00D7F785EEB88FF3FDC801C94CD7972EE402217DF018958A79DFEE835B2E7C591D2604B83E2C8B3CEED7BED4DC66B66EA13BDA4FBF5DC3158035A279F57ECBBCACEE3FF346386ABE41D0DBB32E15B02C49D3F216DB19474D295AE0A8DADD1DBA9AECFA9C92F0429352B558F69AFC7070DE8D47032956A9978AC2F388DBBD63AAD776BFAE969EB990E72B7D74A0D2002CD3CC664E77E52", - "signature": "81D31B99FCF0F04C0B2292A8CF472AAE17A659C205B067FCDF9FB4158C42955886D10F4BE022BC564230D2CB21D9023DE837E9ACECE2AA7EFD77E8335367E9F43A4D4526F36F336293FD0D372E81669B04DFB4ADF2091D18C1B2649B751E1877BF3AE489862C22108B02242EFA218828F53B317CB6537B2794E9559D2F93E3BA9ECE302BA948DC7C6596FE4BABDC3CEFB7F750C8B4D041204AC0F185CCB264A76F81A1783FAB19EA236D41842D9DDFBD2028DB890A652FE07836FAA7312A287A920543B8C393000E03F82FB712391915D75DC5825D9494C6E64122202D002BF7AFC234B334B12C164911D63333A2060B8D44DEB4B7E1B3E24F8EF98C09872AE4BECEE4561316B16A90507B25A20769A7CC25DAE276BEF51364499020ACFF97E871AFBBD68854CDEA120840FA1BDC1AD62283159E19938BAE5B2CAC8A607EB2ACD1B77FCFACC7981E5DAEBA3986B2E918768204D2C0B61914FC6C14A5C36090E52084AE245D9C6082FB8C3B5FDBEEA0CB779A656C180A01C0F188C2B4C11010B562711C5A4F10CCC39BCF5F09509BAF83D98C61E3A35FD7F483342115D41D8DB382E7E5D161711B8F718A2730D73ED7EED07AE04313F3D29D7FD68A92A0706936565924473CFA0125CDB2A2E22238F28ABECFBC0BF8F5E6852E45F24A55E54B2F26C5B9D97A3FFD4CCB09AD244D2D0072C575CD59D01EAD49A55FC2AC8857375ED477BD9287AB0F03E83BB29F19A6C1FB8A6D4B510A55C57ADA1B108785A16C52C71549162B7ED916B8309EE880B9B203F8E24B16E3CB4C774353D9CC9AA100BA200F5D197640DF6E0C0FEB9361B6E59481CE285C3CF2A54489A48B568D115FDC3B182D8341AEC078BEB288F0916C651BAE7ECB5EF165686819CFF2516AA90FFE3FA621D24F43917C218319456D58B5EB1F00437CFDBB66266C15B85CF5C28B29B1C2877F551E5A0B3FDB4852AA17B83D93183E82280AE94DF3136A82BB09D21DA75C6228DFA56AC2E538050B1155DE4133B40EAF22C63DF128E5324B4DC3FDE208ED528D4772C1ECBA1D11107CC3B8258F2BFB9CAEBDDE1B808D1F909D834D3ABDB08A2129B15A81DD01B82CA4303902AAFC1FE21B7AEEFCA8AF1167205142C65B41A8124C8E2FB6978BCCEAEEB8C701A97A311B87C9F46F6B23F8547EA728D46DD907DDA37FB143A191E66906B9715E6FB4D027A6F2B4DC94A38DAFB229642310FBB0CB28BB8415A9AB0B16E78F9F77737D0BC377F6E39AC869743067A7CC49A0E6974D86346BD5F91BC3D747A659F35FC133B02907E0E0442F948E2124AA25209E61F5209680B2E2D8DDBDB1A7BF0B8F1D17726D21C8730875255A401C381157EFF65CECD067F05EE56A9CA6986601A0FFBB473228EE9A64EF04196A78D4B5EC68F9A4FD438DB71E9A8FA5D0AC28D35087ADDDB4341C25AF1A0148D50C5041C87A508BC0894F073505880A550C17079B255C3BA5F58447C51603A599AA7EE288299551D339611935C5EA7F07D51BA76A0A9873635CD7AB35F8EB5A25A2B4453A2EE917E7103FF62D9476AA1B0C64777F4D05AAA5240DBA6956E1E1DE3C0EC1774DB2742D5DF8A6BA8E287631AB41B948954C594A63B7156218EDF19680D863879D79A8E58A1D5F975A35D589805B734C6ACD3E23EA920C8C1A9D8389B739CC3EC34776D2E816CAD3D6AE89B29CAD96D707E7D31BA731749BFAD67FA376E743920E119C11E29421ED033A1E73F2F522EC23D097830FA05CD62C432C70B10B9843CE2D49A544664EBD22213EACBD40922F1C3EE99A3E393CDB38DAAE81027F64FCF273846A9A789A76A50C79FA50A436D84FFF7DAA38DDBD5D40370B02ECB6F202261C5B284419F06CF4947A319753B1132017F46890A129E13DFC62DE2AD552F0931036F5296BF394311A7347702EB998A8DD6643EAEACEAD0DAD94225623F8652BEF131B9D4B0A6F5E7F4ADE344AA1D99C764DD9F9BDE6CC040FDA976BEFF40F8F4B0C5E6B20497E209F08290006DA5DD81AA46C5A0DB7EE7241E2C11CC411E4953942E2BE4CA6A61FF7C21DF482C8737012879C2B3AC90DA6EFC2F27B8507D4393D1647C4331F307C41038755386C53218818A255C2632A6DCB9F589BA53ABDBB4F7A9684D8C622F0B5DBDD8BBA59F92F5AAAEC121939263810535AA0D61A67A344B7B98568C8567ADA14B09BD6E021B1F8A0CF9B6DA08F5A1D66CD1CA8B0641FB300F11E3C4B7236135F4B01E5A50416B9BF3B7D88317315D35FF88A1663965CC183E4E34E4130C3AAE8DB39F3491D85B38C68C1F818DA553FFEA24595F5897071C84EE46FAA74FE240225EE1E325D3070665EA89F70BFD998F080C330E4759B4E79018DAB231BEE7BC73C20117E77A76BBEEDA3578CC2B26F03591E314B0FD26DB529BB0E6D747058DEA808B45064B832F3B1008F675CA2A92B5D38B464C5CDE4E570029891F83975E063EDC4A9B1A731C36B5EDA5E8F5D7ACE5F0A9F9BCBCDA5549203A9268B156DBA17E38BDC3D964CF11373DC778A24FC27613D39E4ED6311AD3E307BFFB3A1E45FA8BD2268C0B674368FC583489473AB3D4CE941177A3EBB06E6273F3C90FC5734514C4D4284954F5ECC0853523DCC3681257C1EB15B3F7AB7FE42D70899418D43B0198C971F9B1C069A2B443DA2C8E463CE510EC8B40A366B4DE82E2A206D7812A9EEC1AEDF669A66AA4F76364DF2167FF1416DB7710EEBDA11B0E8065E8D8BACE915C5282E742E0F1969E8A2B3FE29DF8A9034A2C2172B234E39957E5BF6DD55EEC3C4EA1C694827CDE661870E4C858FE91AAFABEE9E28AC3469B156DF911E00E31B44C2DBB43FAA617DE7782E14566DF4A744D8255BB741EF9C5842DC5AA275C73A7BBC254CF6E9CD1ABEF1AB5427CAE5FC4867BFD1D55478C29510493BF720C03256FD7F10B9095BE2AD621D8C2A6A667EA12DB50A09A4CDF0EC604ECF6F73A371374059F00FE8F84BEB0EE5E45ED467F44479E7761A20A06ECCF795017D46D4F554E73F3B79B4BD7DBF44217938BAB271A50F40871C6AB4E3158B9BD4B12861E9865926D87D79508AA23C085B616938970924DCE2F403F0297420B3B8DD6EC376600B1787AE8756B5CC414EE213DFDA291C4C94E4C36C9530305BA904EC6C61EE75E5C4EBCF557DCA2F01643403B5F25611CFBF3DB4D64AD5FAD075DF9BC3C317E0E4E6BC398C6EA02C58F4CBDAEEE9C66BE30A0BBD3F23F2C9528A54C080129633AADDAC8CC27CBEC1CCDA9D6C6A5D6E1C15F9F59AD01BF1003913185BF93B398BE28269D04383A3EE314D69A07AE8BC1E036DA3430CF772EC00C1AEF7D7B73CBD2D296BF0064A53C75C24ADA36D60ABC93CB271EA846C950BE8A58126DACC14295629E08403DFD9479AADE091C5C71BD234DF9F35B411CA6107724BC00E6837EED6526AB76D3E1AE0EE47FECC134AF895235F5E5C42EA2FA02381550240ECFB60AE9A37D77FE8A057F28711D25C0BEA2550B32EE8E926E539C499ACC781F9C3675E2D6A0D81E10FA653635CBCDC6686A8B842718E327A50CFC15E68DCDEF46FB3137A6F867AA63F97F489745E735B1215669DE7388AAE461A01F9DF1EC3DB31B7588D2A18650C60FB08CFB59F11283321E208823597E9AE5384755B1D106ACAE8A1C3151E9AF98E252A10F068BAF2B6116D37BCE404910DF63DA5891B00F5C8968D1EA70E54F1BF8E495707197B086D0392EEDE6AD60C5D4B9B108467435C9E0ACAC31A7E590D6A36B22EF1582FDEE7CE7E378C089AB6B8588325AAF6063D075005AE65B09929F41DD70B45B53A50C53D779BD37923213AA91A2AE0CB6D979588EE8D0DCD15E89929526574A5F8AA538CAADDDDA257F15B1294E6C85A2BC8DC3FE08F0D87963341D630238F25516990A79E27F2564439EED4C359FA83C3B7519928EE4268836D8D45DDBF62E4A9A0DBEC3470261EC5CAE7D0791C0E976C287340724D88E676B79B33A035D93C5BDBBBCFC0B6BAB952DF2A1A975C8CF7380C98AD3428C795AD3DFF70E63B5792F993AB4642BAFE4EA0771BFA24020F0D17A65E2E6F4F77A0801AD4C59FF3BF6C8F837A9430BD76CA46EF919CE743F685570B95667EEA2BE078AC45C46A54FF51D89E01A3726B23B5158C914B7B7E6B33AD8242B32514F251873DEC8FDC8BA607D156440326D4B5A5C5D676D0098A73E2A25C84F09111493727FE5D04C8B1FB9554AC71A3101E4CF44328553A23DE7BA2AD3C2FA9E9539DC47A58CE3CEB6E51F20C87AC6B2B14CF803DDC55A2E4B5D37A322A49FA38BE1B8A562BA7D314FBFE2BC2F58B04A3722EBE4E90FA3AFE1E80E4A5602BAFB9EC70739F3C6CC223B790C603FDCD188CC5CB3853DE9161A2EFA4CF3553BE3E23C386C6AD5BCBB7C7E497C30A0BF906B6E35585A69E327ED95D25107911902A3024C8B404034450B19254CBD832DE3E6FD46B3C2C602C5CF5A93D8E966DB63D111938C3BCA92D98D40B6B023DCE484E6E958EE5B2EB5AC0275824391F54E424F4C46B7E572F263E3B727E680556AEF3579E1AD6A0A43E764BF519711B60CB41FB2B85E34BC970BB3F98DACE7C8C1CF3F7254DB18B5DB18AAD3BE4B098911484D323427F8897CBFE41508DB7D501818EE418690134485A7DBDF4177C82A8CFDBF00000000000000000000000000000000000000000000000070C10121920" - }, - { - "tcId": 28, - "deferred": false, - "sk": "8BE522B4E26631EBD3EE598B51CFB44CC1BCE4693E87BB76EF1B3DBFFC2762169025689CB13EC243DCDB536B5592EEBA1C9FF9D3162BA69C6C8445C55561A1BDD5DAA73A89A567873FEEA609BAF57AAC39B28C9EBF0DB477CFF938EA069ABAC4C134644525C179B81B69A61400FC131632F9389409EFB2DAD28347B6E9DBC50333478537234180110216703713666267407332042117167285231861686761441210671057343688833122224741016000006637280104670885810336860677835038360856671708501706307554348172486017384536610442118411464278512074201323472226152744306444283276447347407701534240455752818374185812151275332674783343510375328081677738151215483531374201701647010142025428074334717432007611874182847823042007734883110521200373123872310064376640658218187215811731015263781030348654333721768352476037106520857001157228053468718674413501266737641245546154041643241410501404202331467303823172738661537631326412120620535147074330475675267385001422576156865466315087754081624344371427068152314726807147108662880315204371650357351315826372165054702134004232425418802463830782403784381115563683351588142725828012118040033543738720206011440856443223582817212677271158874776566724605581535176600567745870103826357027573672874654377285231557526888232382155662024100070470030473727043681088635050714638852408071501850808072334837044106823681822708546272403308813276035006162706663335231815226264468284147368331351772564002623064338284502177258683770086532412113081781761102623530322278262028713438163458525017410602014725837473653188830358083120808408517263643700355801282287367867716818464087758327804282311206361315488554266670483253832715616163087472867038811365080210210237462345637776788467178451732482673618811867731483512036158155276111185373836686408334604023734277527830555045716275074072450108113304336412220335448801703313347077660185246467603160827384258610827786040227788358515276647106422642717356782036318301654248323637160122662488623837433257521667160846766448032050502541655122882873257375732786387202663327831411364154328330125623422884575626558307557713473653281565632108110853544346667326373177215875188880426237318478516556653371343073506220865321058770816713770387242752781203737258042510133435774100138260342867165785468418463736503584203606438045376454072080283716557465775044371518453200301088283116123715262003810840120273260615472300483880225411134203712750473122131553667405410661065824344668381608711445062248365838180162845050471728814083565587567605831314536481816873614238866537046728070145831458843035350778852054744668616084188465173248757877750305585700014307233313471722355344716426435421467416072887431031342617388642656086537070667614703030736144320532164032037145102411420812042582084583621280125835662622287314366231327281824842763423073663418856204041328103787818034738187202808802170064570017265628525011080747850142683771068084483578052255237768183672270141750243375737386806347814658588856114864068441442642086057430676653065800650578614485827138703358681848874801543363582130444225273015665625525034606073587464023021552772813060801271401248635688136384706617355687552587855202183037066184600586417823285581816200837FB03CD1DC103C479132483591620A98B17B885473B466814BC26F9F52D1AEDBB07645BFD9D05B02CF3D37CAEBCB8DCE34EF4185699343A4DC07D7EDBF603AF8D3F4C79EF169BDDF5A0647F9D71732FF65A8142780E5ED3EFDD4FF8D496EA676516529564718CB376D9A8C922E038D84995A29661A54184BD3A32D2B962B3DBC167524DE2C4B07765B6BC71CD4A5510C646EE0AB6892992E341EB0E54160A8939AAAC4C424BE9D7D1B4CC1FB50B5731950D19B96E5EBAB09398CE0E476AD189004829896E131F1C0231CFCB374895A47684F063B821FE0C8DCEE3B2BD5DCE499422AE0C668C267A65735F7A21106FB7A584CC2D89A097DBE549B3FB84AB8351B6A5F61ACA27B4C38C3755BF1ABE272030333F976296E482776FBAF8DAE13A0BCB7FB2992F74F178C4CDEACC841B74A1A7355F6E09B0F58F9DB2461E26CE24DE7F8FD744AECD3A6053C49C7F23C8F7F34B35DA5D60B16B81AC9C9FCC14A5DC5DDAACD10634929E6540A5AE3BBCF8BF7A04F1ED438CA536279B58FB02E1BD481D9CFB6189BEE8FED30D46AAEB34F7C4DF8781A38B2C40A7C7C27347DF54728AD8B91C4B09CF48ABC5B392DC723E95157F1BD0DE34A76ED0C89905F4333318267E4BA6EECB1FF87F8AB78AEFF5A494B7323B34A019440CDAD40165146370E23928BF831BF0DB4A498AD2FD15A15EFC1A56F656E8CB58E93CAF38EAC61F3E030EB00EB2F9627514349C583E1E2D93CDF6775DCB56517F92D89530D29A55DF17135AF8014C34645BBA8D9DB19F28064B55AF5520841E3DBEAB3FC4A4AEBDB1C431B2F7A83D4968F120DF098B808DCC94D29D26B8211E489B8EDBB87A4CEA0750296E802796D1647A97093F5988024F92FAA1E857AFCFD5E43021B0AA190DA6D581D654DEE6B9223A31BDF5CCFC54178AAE8F4F72B6D9B43D758F95DA0E4E6EDA271E2C03F1BEC31924B827D933BE6634AAB033AD507ABE2EF144A9629C2CADE0B491042AA23005A25B163990CAE9E3F03F2B994CD1CF70716C4B0D1472185AE2630DB3A5A6F154A60FB7340087C554011D95300323AB37681931724326309355E5E767BCEA044DBF1F2BD2645A62D68448C1E978FE1AEF1A178D743DAC130CF4912F16D113C229764562FB8EB2D8496C1891487FB9985208E2DAE8EFCA29DB5788D7A623856F14E41F3232B048C794500DD52836C45AB7CAE336BA311DE88E1F108242DAA925FCBF4801A7D5D400E9E98B15323E7AF30566FDFD118011D1A6C8F795BD263BF38CBD66EE93F0D7DA35C276EBB3C7A2A511AA852C35E31D0F7EA0620214618B92A48A50262107D875DB22A5E6B33B7189F6F6918E036FEA3E7A918F59046B9ADB01B074DAEB58A775E9CF56E5ECA2D521298B355A8FECF7F8EC1586AE72E3F8AF3578048D735D8D750A28EE0EDCA3E3FC303613177DC3F9DE2DD92C583AB35866EB46DB11A4EFEBACF3CA6B9F87CC6C7819CCA4A3E2B7D6C5E9A61FAB9185B91CB90631051CB64E61EAD02D98F4361CE57A5BB54A21FEFEDA318CE8F384464374C8F4FE706CE462A38A2A340ED573E5F703B418D1EE2F71539A1339FBF89A553D4E3D6E309FA50FA08F9A3CA504E8A0066E0AFBB5186E5B3E7418DB1F14E73FD481B984B50595BD937E5AF3F735BE67B2F8E3821EB5B28A4A60A27B382B2D4E84C20F6CAD8DF9A200F819A664B560086BFDE6E6C0F76A651E286C4B0DA27DF31CCCA6D2101501250F251EF1D034B256BDB4C75ACCDD7E4A31EB13A71CB44187314EF2576383BD8E8AF0594E9FECE0738544571D241F7C0EAE00D9EBEEE2B63BCDCE13037CFD515A63541D93B3592FA483CB4E4121893BA48608C109358DFBE317FC21724FFE6F862EB5687A76F56A5DAEB3AF226DA6E66EDD79294595A7BCB4A1FB4A54132B8CD7EE4FBE8658355DC420F08B4C9412CB0A4ACC24CA5E174316A8B5692CA8569ECDFCB37452A48ADE1956C52FDA1FB81F507CD8654A716AAD3C9D8416B99390A190BFAFDCE5D2F054952795E13639CC0D509557793E64C2FDBFE16B19F28A67FB0787229D5BBE5C7F85BFD2D257415C4E024D72E7F7598DB32E61F91FD68A8ADC38D558D2AB6C0F748E7D0EC81BC0B3ADCAE6F9D098A1F43C1450581C2B084DAA7850ED84C76812DD7EF285F6A530EF7DF815A4BC54947CBD146296D615F5147C38EB5CD2BA842F1261542B5D75A41370860E8EA881E2E88FEEB020AD954420AB03ADF14DCF24E62DDE75B19568F06D9D418AD71E881613CC755FF3D11BF3DB0C0DEF57AF0668FC38F3FC9256DFBE28BA606441837B5B0EFCFEC92E6F658908CB4326200175B7388411EAC613A3A75EF8A1F856F3BA32DC777C668228232CC04F4FE6E9089C8B3EB9B4A74A9D4740AC8F14B5FA73C43B3ECBF1D37B50F89855DF3E899A2B3D277E6C72D284E075C3FF09024C3E5FB3B7349656197A468E75047402ABAE724094CD92170F4809160190D1F3844A0200E42E80D27A1A67DE1E2B8F2E10FB0B076D7827C0116E6A2319D99CC38E53A14F4B31BD4B2BF694AFD629C0B12F41744905C24886F2A7D1C23B6E3141632E1F1088A85CD9F6AF9A005576593C9CF6CA4F94BBBFE860D4F1C2388EC112961636CCAEF5D84157F8001BD3C156BC93C5B2FAFCFBB67406201FDE2ED395A83117E2735373E07C0BBA838ED01246022DA61299F080588E58CFE32BA6B0FAE8BA9B4B7C3DAF383EC14335A4CCBB7B1F2CA795A06C02BE537FDB9DEE0B46D54408AE45FC77DD54EBD248623E403217DE8C67B1B3993B23E14C5043F310FD87410699FE704440EB35903ACAB6CCD515880244C184EE43BCA31EE2DEEA3A5454801EB3BCE0255E85F6EFA63877DF43116EB900523AC48F662E61F7971F00CC0EB44D1E6F33EAAE274B8A618B0C0A402DEA2BC835962EB45A60DBABF55744B890301AD6FB863E84513F7022D52C9ECD758261C58525BB806FEC444D7BDF7D02C25EF70F9CC429EC33C7516FC84281684F6A9D63909A6419EA190028F20E301A3230E5E7CA25E86509DE71962E7BD91025E18B194F07DA2D32424AA734E94D8AE3E6F2099802700F37DC29405D2B7BE4CBF35FD58EB6C8DC6EF969114CF45DFF7B12FEB37B16DA34D133A95A6309D1CF28CC96D8D3D581E95B2CF94E737A757A36FE40EB11AA0F3F913C1B7506C11F59E046082046C906F5F25F310DCA23442E8423BFA4C977295509D6C8B2FC30C282CB561C60D44177A1F73E01A8E5F267BCA5A5C652F09E16C35AFD2655AE0DC738D70571C4E48EF34DBE632346F804DFF6D565A542BCAD86D0F6E52FB7F9771E850A39786689E1DD8E463E75D64E41456DA22D44D1BEDD3629D0C93143A1D67718C2863CAB7B63A6823BA00A6BBAB6C6089982D780A944B7455148D7DF8976D31CD9D13FD39216182453CE38B140AD2B621A71390CBFBEFB55FD66B9CEDC8F68C9504C0F28DFE00315A591AE709DFE9511269917CB4A89F89DC1E4470A162F89C45561A362A7A02F5FB4A8D82317CF61B533243BA755418729", - "message": "F55B1A381D9258CAC6DD7B5A57899867FB659A56873F31F815716075DBDD56D6D0D1480AE1242A17485AD259BDA2533CBECE28A906271A3E65FB5D48AAA124993738FDAAC65736230FA07EA27D96F372B90A16FF778D0ECD7C0F62174839B8C7FC50F0B0150D47D5CE9F3715F5964DC712A681626821EA27E912B80D2D04C346B67439CB5E06193B6D7F2161B4F8E0341D8F1C0C7F6E3B351C4EB62E48B555EF00EC0DD5CA6A572FB201D1A4570676A04000C382F4C332C34A0436B535CB3C3F2378682A982034E01211CFB23285395204ECF985F478686817A5F6FF4B694082B3032990597A8C3A85B7FB5C2C49694103811F754DF0434D09C1A5245BBA980D6EFCFC9BC63DD42362477537C6712ABDC952BAE377AE7EAF9FF0CE2E9EEE82FBEFC1CE56063293BE659624CCA0E23DD7EF4412DDB587CF3C5302CE5AFB39BA8613151A04491901DC30706B46EBD1B26D4ACA67587595100AC51770080FC32ED0DC109D525088A2579D8873C6929554C30BDD1E2A0A9797B1676A8CEB719F64A336FDDC3F95BD4A68F472F00C4778745203E1A7736764CEB94F33109AF197C98D94BA3F07E857A5B251858ED850E7E578057E833A2CF95D7505C4973B709CEE834A40F32CF07AD1861CD46CC4DAD37DE66F8037DF1B14CD88E62F81B9DEC286BE4968ABCDCE54F83C5E9E4FFA8144A5877D75FDF75A38ECF60DC180E9B72F256BCEEE087F5AFA5C6D779117070ADB4A671839E8032E55AC52E806C82AC16FCE76A659D6CBABBEC066782C4C068AD4FCD5EC425885A5CBC5A4BAB43D1A60D499C497A2DC06B136A971BE8ECEF3FA6606252029FE5B33661883608702542F7EF44720466D91FA1CFEEB9D8CEBBE4E252CBC096D99551BB90A0534D723B02146FEA94D1C1926221092B97F1A143E6B4D5A8438239B2E2842633A6D90A18DD67D05B2CB560BA8A964E0A49BC1987FF47895D664F92E27F8C90059C5C38B02B42D7A179A09B70023BF7D664A94F7289B29FEF89356BB51959FBB82562F6827CA2A3892E934A9F271282C204BC3C6B34C57882EEB552DEDC0644B43FB28284FDFC82A1148447F2457E94EC0437CB5E0E3B6AB7F7E48F0F53C80D7695801DBC0E96F9C00A4A96AF8D60676DC4A6A6D97CEA344D7E911BE7CC9CEBBB23C562BCEC6992AB1148384278D94913DC4BAC4F73313BF83CFA2591420B18429D1F88D68443B960F61A1AB8E2713794225DF2D4EF88CAACABF6F095DA88C52C011AB3A07D7B71CF209BC84DEDD7FF2D8FF02A0727196D50CFF6520602D9FCBE57F890D19EB7845C6529EE5CD98AA2FDFCF37FD7472D1491FC5267F1D7E6E91EE891D880D5EC20FFC761344BAB59A327F829ECFBF8E550208976BDCFB75BCD996599B68CB29B27D9EF68BC975DAE08AA121F4D95805EB89F2E8B2BFDC61058740881E9B403C54745CF6D4AA1747EBBA56473D00FCFC62B5F5DBA4209E0E7473A0A311619437D2DF22F1D5BABAE064970850CD51D4A62A51E9B3D3121B766632B18F8B7CDEF40B249812A6274D4C69C9EEC096044026022B1FF055A05B6BF1C919230723A952589F540E77D7D24A413F542E7E0D3F7F55B8B335CF3693603210E979718E8CBDF76CCED68396DEB561EE27E9008D7BDB428BB293E1A1BF2675D8A4568D3339682854BCF9E8820A084C94D78E5D0938D66676ACAAF7B411B466B6588E9E2B4A387D84F23963E252EF36A948F25625DCCE664281D76BB6EC1B8E20DB3A7140B194872DB439D89F18E74E1861E3CF9FD442F1CACF4FBFD16532BECBD97CC9A007978D17922A68CE98369240A8D1E8AAE6679CA5DB79D83EAC1A571D0871D5AA28F6EA4A8EB60770E8CC43A78E6BEBBD4FC63CAE26F297F1E21BCE999A509BDCDD20AC938E38702215C398726ABA5A7AB3F26DA34DB3CBD58A7882FED91C33803FAE62E9E69FAFBD698962F2C7226A641AA7B6CED1DA8A400992333EF5DAAC77B55F94D51F74226AC03F7ED8F3D567BEB678D98694E9E0D483815D080A70FCE76255C82FE020DDF32D4BB7B1AE0EC1679B3DAEF2C20FCD7D8F74F6FC684FB678F02DE6B53D03FB656A9B9562666F49797EC658C0E8ED14480A0532DB85478FC2AD1E21F8883F2EF3FD97DFD757D883C1507C44F812639711256EF56BF6F8FC4A73EC3AEA3099F6C2BE6B2380FF3AB7007129D4829103AFE70851917E02EC5F2117DE110FD8F4EA25FED6FBC24BA063B7ECF7585519132884FC12DE1BBEF498B92D6E2062F1A4F7C97FEE96BA87ABFAE76C50729AA68C8F374102B3CFBD69139491836E4587D0085F92FFE2A94B6A87AFE29C84D289293D9CB4A733F90389C96198E2250F5BDC83F123FCC4E42844DF74FCB65986CBAB77B692CA210AC22B5B56E30BEE2BDE84663B22507E00E0D066D5B1F5245EDFAC6D860D0493C218A541A1FCA4B48F1A916921153933383284BA268C3AB003CD58FA979A08BC48A57C755688B0859AF7F21061F9F1B7DA44088ECA4D393E8DFCCA52823FAB812AF36212CD137741C14F0860CBC7ACCE1FDA39431C32AFABB84989CEC971D4A257BDD70EC71192148824C17AF8F18816CA94C457E1023E01012A245F28FF6582C9015153DD7662E4321B465B33B1D5DCA9B1CE2FF49EA3A811B5852AF5C42FCE7FF42BCECD31C798C3B8F685AB50B68654192357CEE577F5CF1F85A50F269C28A1F2ABEA382AF5CD089C146B9473C8965A945091ECD1C02BDF64F9C3FFD035D8238AF974E7111BA4AB10288F105659C9E2847544FEC0B29B6692FB53CEA0DD312B24C1ED3CAA1BCFD94E529F6C27BDDBB7C764DC0161FCE578361E02E0F5F3FDB095B6CD311190466177A5FBA62BD18595DC49C29E8EC7E1F2F3FFCDF17D477F4AF8CA3EAC53B7018A026BC942EED87704108027753DF67BD36221E9121B49CD40E8EA7FA2D6961604BE0095099A4413DC11E93B4A876834776D144269BBBF8A9875648702B589ED4CCBAFDD726DE8E8A58AA5D1A6E142A470EC342BC3E2E1B49C7203F283E99E81E38F1D8D2CD820AC98D8244A705BFD9B67E771A0366C7C6958DCB6921A81C0C9D5152DA37CAA8CE18D6B97404B399052051D7343B3739610329A37B8BAAD173018708400AE02B8DB2A2414CD7DAF038F94714031B1D83A5A15DBA53585B606A13814F04FC925C3454E251CEECEABECD8CFBD6FC04F504508C04E25724807004612E2796987D34D04318F82F7E1FBA83A4DEE3C86FD1884B17E77231629F5D5D11CFDE976E639C60B436DD9D302C380E3654E671ED81D44FC595FA34EDF90710A6384BB62DE0D89B50C14A44215DD1121C602A79A003955D860C88470EFD320E8AFEEB114E547E50CE967572DF5A5C4DED09222FF7821F91598A0A9C41A731D64429AE7D9BCE1B4E90120BBF94EED78098C9EE30C38628297C86DF59930E72CA561A61B6EAE517DB39F5A61FBB8C1838E3ADAAB46187F0B5D09962A39955343631B74BBD17BB2E338E5FC8C43BF8B2DF3A78BED744A481A1D789721928962AF2B9E2187E6B52A19274EF68F329C83F42A28B49C447FE284A25B71FC95D9322E752E28C7B4B656A743CF6C56CEEB758E742CFBC4B8D8DE5465D63D3D5D6EE993A4C47AA72BF82126ED6C7423D3475AE098CE6A7E6DD6F3EFD654BFD5DC4414B8F23F9E29CB0D5DDFAA689BABC7B5A925AB19817226DCD242EE46B588D7CB8E88183CD87C6D06FA1A40915A3F19E2368CDD97A16ACC2DF4CBBC0B30C6289D7004A8B48EFE4186BC4D844EA01BA78E4D1F0CDD2648D0363CA73A19032A537F68E0AC01CE6701426A03E071A109D42EE5BF358445907E1D05761B8F41AC8A9CBE2657754A8C4D83A3516EA465D5AD57367BC58DC712A5C055F68D1CEAA494D9A845474F610BAAAA4CFC96EB51D41493930534D58533E20575B980F4379A80393DBF797969405D6A514AC0A9171B79D6EBC5B66ADED19821BFB090BF76FBF50CA6AE07CAAAFF584A7013A71D54A2B60678F6F02DA726E7448A2379C28BCE7DF968154CCD22F1CDDBF25D91C616234539731B8DF4F55E21F37B29BC77DB4BA802D9BE419ADC292105EAE58CC81A636D479B550D33D057B7AAAF28F743F7B8C17E26AB2A846AE08E804E5D4BAC09D11C736DB32F9DC9CEAD0442AB7B6AAA70633692959A36D6DAFACAF2D7027E5BF9562A93A1B35AEE5313C1E2015E65AB805850DCA7A65FFCAF14200E1EF0DD8F8F05A11126EB02C13FDE38F496E5EBFB09E9E2B4920E619A67517FA4749ACD8B0857C7EC5A6E94630CE3EA0841C64D2EB895A9EB7CE5E757F2FB80BB4F0FA429E779BBE314A491B2D45F9A79655396E70CCEB319C3B405C33BDC91EC2169C3A75C4F5CD7AE5AFD6CAF6C9F81A9223484E7A12512B600794351693E1111401F74E1439C99D77E8932E069193DF7562C79EEA22C41DEA4EAF9E93456378CDDD6C8AA97D8D69C222614E203B6A1FA6377A7A0CAEFE709C90CB91939BCFE926B35970B13A06FFECD44DD8A360AEB5D0432A532E8A3C275E1DC4A07D6A3E100B04AEDEF14A52C09AA90438D65C8E6141490BD1ABCAFDD5925ACB040A91A8E11D242521C1F00EDC14D62E1C6FCE721921DF42164B4B34203660DEF02677A6B8C564075865B030936F472CEFFB3446714AE18BA14A6E45247C9AE1F2836E2341B61940A63FCCFAAD809C84906FA0CB1863625E59B96CC2161A4715606DB12FE3E79C90B64CB9D3A93B451E1C746F6B820B4FB3B3521ADE56DF9D50136635F29EA908FFDB32C6582715B06487B391A36A6A7B96505FD8ECE767C38CA4D0F9599FDCC1BE27C9C60D9190139C4F02461A5C42310CBFD5CF506720C9A13067F83AA1FF66CDCDFDF59B673B6C1FB0301DB118F3F49D1BAB49069A9FBC2D653D390DAFC3CC5CB35F0E50EF4CA808DC69F0134E3EEE697597FE7E5C2A2CDC5ED4E81F344879A0536BE0076D7A351A199530C77C0AF25D5C7D5629641FC8A3567BCB1456C1AE1D216C1E408C3AD6CBC1629E14DD834819F94EE0D255AB1C61BC7C324445F67CB7BA0E5AC424EB9C3D5FABC47081752F98B0011AD389581B8C20333C2878367795E31F99FD2C082B04126A3A61273C94E894BA7ABD8C6FD743FB76CC4FFFBEA78A1CFBBD266DB4432ACEA74350AC06F2EC832BD71FB09481A045F7A17F22F9AB65CAE6782A2928147BCA3B521E001D4BACE5FF499B1462709525D64E72201D5620B5537DF7A3E8DBCCC6EB822129B7768469D18C891A60B948DE2C12F4E4DB574C6C8BC586A1B57E727853FBCDBB4EB148DB234D8759B2AC8ADA2FAD225B5420C2B93D7FEAF051B7B768E64BC6EB83688B5E7E59059E1079DC66C5D8696CE758B42AE75123CA0FB72438DB97D39F1340B2891A19A4084BAA1A5149FAA785F09300B9DADA3C45F19568226151382ADB16617D5E59FFE8029F0513A7156F67D9859A13C2BEA574BE10E319F1B69740CDB176A962810B8AA6C368805EFA56E4AF69E908A205DC41CFC3FE69E4A6BB7B1F541DFE0A0EC1B29E3C199EF07538BC8AD7B0BD31B6A4DBAF70B83443A9C6C06268F597A6D1BC50171ABF56D18BB277F83203BB671DE404FBC4DFC66EE8DD4D92FB1AB2ED20FE8E9327CB15CB90908F37171D10E759BB8D1BE2C895604F87E2307AF7720AF99F0552FB15229B0FE7B45A3005E6CB0DC88A6D15AC7C364189A84A6615A344FABF4D0DD82EAFD42892C86EFEE6E9F7C248462E4C6CCA369CED819AE94B3DC856A3412A0DB90353E6C6D9DFE31913C3249195A3EDF9F84BE94AC6EB82969AF272AB8802BA0E8967EC342834B8A38163C90431844DB073DEB60B388710FF880EFB8283648CDCD75615D35451D8AE4711C1D7DB1AA59675061004EF8164AF3B4095F0E2FFC5433BA41ED72AC2C683D3959C9D265C302E0FEE7258B7C870F62D40961AE5AC43D3BEF8241B38A574F75EC7CD608781EFC16B7B9D36C3844B6FBF477CAFBA155B91061", - "signature": "B3AAA36B5B5A4676F1DFEAAE36203D94EC2E2092F4D46070C5C03089AFE6F991B0AEA0528999A8151E95DAA67815DAE9F7C21956CC4AB73395EB4B87F82FF033BA5BBBA94E238F7B6C184B5F2B1098ADA6FCAB8CA0206DBB3BF6548F932E522D5E17B2EBAB6B4A0A2AB6D25E86A071EB858832C2B8D4D718FAF28220A9801583DDAE046314A9A8D02EB15611E74994E87D555EA1BC1D10DB200A385AF09D1DF4A8D460189EE7FBCAC70862816A41B307F6DD179D990BF03C634E103E37CD9E254AA378602DECB325919E6C528F90D1EFA69E1815F481F22A3D0E58C9AC8018350304B887AB7F5509545E35334349C910C4B7CA7841288879CDEF8F222DAE22D5E18589DA715A5E35CDBCC9E79D3B6F6151B8F5972631EE4F015ACE124311355EC29CD3D4B9AD445E4B88BB961F9DE36DB01B1725AC1F0215DF909AC68362ED611E9EEC491BC6C01B3CA43C0C517267FA44C43FD4F195FBEB882E09BC2A0E13AA71706298AB6655408E8B8BAB108F772B6054EC543EA36E9382CAACE0EB62A5653B43C6868FA8AA6129F902310C6BB228941FCE346586A40B156E8572F6AD4E300F74F6FCBB9691C351B7F5E9BBDD8C6187085193DED352EF786AD96525E3B73DEA31E5468C8101190F57B9952B4D8CE57A3CB1A89A91C766785D6987E90BDB809A32B8EE7BD284C95F32173FBC55AF1EE56110DB65C2D6DA456659BF0B54184C348E6FAB7C397FF05A182ADD25345CC5B3B40FDDDB65F107F1A5227D93D6CC4AC4ADAC5720E5D3D801342FD06916229C61581F39A7FB0903F90FAE6F7DCED0F0804E003E584B51520A7A8E4232368D7B555F5A5F4AEDC83C408696CE2122CE6C8D42EEF94C6F6FABF71B34321B3C457016BC576F01B94410742B52A60634B6F57427F9B7508BF9DFF7665B8D8DF8D4F5A4EEA53F9A7DAF5BE52353DF441CD839B846FCE51338B74AB01149667AF5A74C42C6D9B324BE5338C69FF350292EE69DFD42D8D186247EFBC72423DE170753392F9EE3A851FF2C01E3E34C399163BC611785303DCDB61894E6E32DC4287C87782EB136D1B865A7563426D23FB354D373869F0F13A058B2F626951A2C5F4BAD5A14FEECD94A76DB50C69F434064682509E46C71D5076F00BC058A89CB669E253FEBC72AB42BCBAB6851B5DF111A06381609DF87972EDBA0F9A77EC972923AD6F49CE0F52F3309BA7E614DF4C3424473EBEF40EF15588D728F7609C4C2D4C691E54A09E6AD00DFAC07E69358A5C01EE4B9383CCCDF8E8B7E14DEE51D8B3B966F2C1BF547E1C58756FEC20278A8C4547250129516EE0EC1CBCFAA8C3154AE3AD9135D15B957174C1F380509065B035B1807FBF48196801831736B168E009E023616A73E7D709579676B0BF19AFF259BDA7F1313A46F15526B5D1048D853FF83A6BCB6F446F18BDA693D38A313C445FEB6C5979AC2CDBB750C536076D0E8E7EB728C3F01F9E4498671A34909959EB82A974BDC0AE784B6B514BB435D2FFA7B85416E56A4610BA354C3FC1118BE292B6799D4EAC3719AB8EF6040BE4C6BA12AACD9BDDA672452A04432FB09447C6A125F6FC27A589D3DA986152A0C3CCB72AB00ACA16885CE3A2E7F596706C7A81060A29A3DE21170BCFB1F6029C859489D58EC47B78717705795D5EE92C3504F4B0A5EB542D24C9F4A07F5FBFA1F5159F845997138296A18F9BE82B7E756E075F60D794243606BF1ED443B207816C854291CF3E2085957D52D6991345AB1150D46E62C6FE96F802D21D2A15D1266973FBF540570F0564C97CAF5F54CDC812FCD5C21C8654193376EFDCB5E7A9CB60BA929E00C933B685B9A789787212D1DF26C8E87347C923523190C89C7B20320AB9C1004B8148080954CDC8BC5D2EA91724C4284C21A289324EBC3F41438336144D8C8BAF5476A9AE92B522F88759F2774D9ECDC52960FE0C1A20B32451F4E51A1E73029572CDFC5E6E6F6CE2C0A712D4C4A74A26D7D8A14CDE65A4D277F8617A9A8BEE3F5EACAC1226B0C1D73609CFA4C937FD4B133ABDBF5357A771D80502A46B57A430F6BE8746F67448634BA215C7452011A62AA480C6F2464B1DB9F2096DE42C5E2EA1CC50A460D88B5F10692D29D9BFD03B8B8743CD0500C61BB7F7DA4CE336D25E68BD9A37841F5558C67AE45E3FF719F70E3CCEBB0128AB619C23AF8D82CC7E43041E7F6270DD8946987A090955B30C6152B2EDEF4269732C0D89817B9BDE594AE9E44945F947BA87C769F7F632AD3BE05CA6A749999027172230A8A36571534D151E0A0E3B99968C47F8FA9FC2FF4703789A15B363D40F57F2FF7CD3202D98E47ED13BBEFA9DE66BCC5979D7A57C91EF186DF2F2C8F02B474624E8F4729653414F6DEC7F763165164944BF7E9876686233AEFFA733426D63A3C4D31A4DFE5A6A4BA49CE45F0C9B0D85ADD85DACB28D4B75779F8A14B415F478E84D48A797F0C2AEFF842FBCDEBF9B03EA1A48760461DCF60592D8876BD967A1018FD85BEE5A31112628A0C6ABE9135C43757C2F1F70CF69C6E34BD5327E43838C33A2E01CF017EFFBE6C5CD676B7C2EB4462CB8EC2DF4810B759B5660F221EB8AAFD11E816E4EAE234AB54A4BA67F26C5787952A9CAA9504A4F26194355EDD7D7CC0755E70DF38F323603E1CC8738306A4FCDB7E6E9C5AC26F70EDC1D714D80ADD9628D1CB0F50751FBD7C4B4FB9987756248F7A5460B7BD30982CF3E60EEB075DA4C2054EFB0ECF972E67CB8350A1B8A836E285680BF8B59989E0CC9B0CDACABD8D4527940ECFE45E00300871992C69F23BCB4BB5F79295FD520E4E7D89C448F2FFA69AA40590A11F7F856FFBD486B53334B6537568D43039EE2FFCC2A0A840A4BCE03BA507DFFB7CFEF8762B8FA40E48390C94F4DC6B74960BF9B67801F7C461DD9DB9377EEC32753555BDA4BB5043021DC9C4FA543AA3F58CEBD08003069A8698CABD428C091F0B06220708EFBAF640975E09A58D6CEA83A719E49E9053BC67923951C4117108EEEB2C0818D988FD73697D14C2145734D6C65E0688F4FB65C8725D58BCE41C152D292BF9EEFA242AB204C77D7BEB511E62E893E255FD4DBB7C537E79B2DF6A445CBF67DAE85F6686807B356B7DC2AEE18F92ADBCB5D7CC4C80BD2CC2FBC2FB06436B1B088938BC7C7022357F51EBFD466AAE707D75186DF4D50390B1A3BD4FDADDDAE17D17EC36961799621BCED05C06C142094DC22D8AE2C70D8A2503FD7AA71E08E9726E1FC486B97AD3F2C490AACC6361CEF13400D34502E0CC7187BF226F35C09B784F5432FC44E0E6A913FE34A3E11EF957E668381AE4024FE33C264004E36DE439194DC5961EF2B8CCBCF0A2DCFD77366649CD20D73AC577898D593C1F769858CA8467E00C783597A49A70320BD6EF3EC56BF7F5BE745204D6EEE2C702860D6A4E8AD77F5B23EC389CA800CB4DFF1DFC22E29C1F4599EF131F5B993B8F9256795033309F8F3B73DDBB3280BEB2582D81FB9466CA18C5A028BD09F90C4A1A725C10E49856E07C2EA752FD019E7F4AF0CDE66B9A2FB9E22F4C962B81BBCCD218E916FCFD83A5CA2BDC582D0B2090F2172F581200BD0122FF6EE52BDB61EDE5DAE73542AB3C38E85B8F871AB1FF6C5FDE0EFB25ECA17C1D6F6777F5F9020B1826F0E309FB7476967A317A7D7BBD9E4EFE871E80A55F267D6FA3CD631250B594ABA0EC0D28619DAD9DF904F46098B5935298CD0B37EE80A58FEF57284A4CD061E093840C9D4CAA6DC3D2C1AD09AF739905A4CCB12CDA458BC9ED96774F49C5F9A1C43781C2A08BC99C0884BFD9C25545CF6B9F0F343EA84E8270C97BC47D706BC56B8E39B0DDA66D7A9E130E572586B9F1715AC35A4DA378E7B10CC998021593DBFD027001D2288DA1A6D72D9A66AC8930317E5154CDEA34C87980F16D1FC4EA87FDA2D47267CD5330B39FE941886FF642EAB1953CCA30ED21279365844C4F5043205D482485E45FCB6E52AD8B31A7076BC96FD88583B34720106DE1158FABD0A4F4422FEAA65B1C828A3D4918A36A99D34B99B052C7EDE5A9F6EDD59E1FBD2B2A025DF5457A9A3641EE8F65C13E7969911F5AD7C520F3C9F7357BFF13626262340429AEA5DE00798D73FB517185B259DD44BE7AECA1187D14F161C0D68FD44A272C38EE1686FF56F55202283714B763833EAC7654D3485509BEA34A669333AE9DB252DF82BCBB65E85ABCFDB0B23FC44BF4527E9C123AD4CFEF148F49178984BBE8DEEBE0BCD4564A333310F8BFC436810BE3BE1349371F35DEFB9A95AF245D92EB0DE9E44230C85ED86280493715F540ED2146EB903ECFBDC1AB2BD66BA8744B983EFF9437673A1D32DEFFFEBC94FF3E46D25B3565B71D7428C1C9E28FE9E191B79B490654762994D98EA1F75808914FA6D93A1CD216D17CAD2DCC519104244E2E9EC3E607A84142528FADACCCC6AE316A8BD0818413BAF7A90535EC2CDFADE973B1044FEB5568748C1EF7A1DF8A35597D2C8D86A159A0C9B88572569C50820D9C85C8FF52C072A81B8684C4EFC7900048FEFF31B4D4F144264EF77488CF854523303E418A5C42A1A0AC90AC5B6D4E84B51C9EC73E2ADA8EE053E81D629F5A5EE992B86B7984DBF7FA031A6BADD3D6191E266872B6E0F4154B7080BFF2F500000000000000000000000000000000000000000000000002040A10181F" - }, - { - "tcId": 29, - "deferred": false, - "sk": "0297C0FA60D16D4A0D17A019F55A3F08EDAE88B98ACC1C7DFEF6BD42ABC7F9B95BDFACCEE817B390524985E281177E1F58D0D332D88A53ECC69D36CD3F2CDB5DB5165C52C2CE37612A4CDD2B62BA83BD66684F96B835670FD22E8ED003408BF9D1F52D90CF1D2D3EAE66D7D85DE8FF119E46F27EB01A4A88666B02B2C5CD7ECC71475126233751606406113524782512715333860324438760638762734863482074003581724563351353138370627434260445637442177740371643224671617725441344250077330875181226586513706860871721017807300117550675284633706413607083013276585716370368050360711636355585577030632744062432341561238384284175207553145658474417404154724103855270733216724328004787058212163440458651245376828170458827746751653134524478840643478264478207475568815633525051308106624207867342115378165346422073070271412006802582227512715153203088321004847547556737460264581323568705360343334431146566351401314880877404717661204337656538731582228565331786427057033465157483413750216317745537626715720244052725853713888388134843772034588472347173687745730066205583284724450000625141552705674515631427087434751825444380103432251711865645505836042741704560123523466822474632315045847723202654748142365813273005127174240207784056454887672623315657661530444776343656142117642778181763467027344577108463016407222826446461136448285450720774714430371008081132006480153606526463888054500118888003781136213148822370121275828340188141732881861617164087530333608831350247480601478725271843745774177873867312067462502403637155718413362531502661247285480024810234235400373287583667573412665140207568763110311725216005676866080753252314482804083063666176263420837737160682227765684481183417033821367724774461317852010100623286300633771066431466481720800788057135404721823251208256681603522737022068184055137381511425223830770027241631858506536650561586474834248364664527764288258583362258253611711468120685118836063400130368635701515801213185810606620114471462062014451636631838874230368660332432366768312320537254065462521272660077350618508423570831123312654084175610472468372463383236355463060552050638703827717733247850374664833535811821007341633446035721564215452045174715401058443708781470787635660678122871062520772570612807708024277164210323003680110227842476577255318133076620664182015776421146370080642876232368544572781206873058413012137383478200823323051100107156883162232725863430855777107357615856648065557274370204175012652058202246626757621404800874450550038325336061484681482363078018181432130234117583142652832864715748075227663747166702378321453044770646634388835406301744345204662683538438062348531701370655844554268761343776785460263714566588627783555812231322607824008010540740805513544233266705274246487108817323774438713754288718083217056316548462085815377128322036330530628018007677542067157424064876784444558815064151587171085581181235145012554740075736440276116856220542332347645738730270817668064813705460748025865533377527104018483583800012175176185223246188313570514482238856512801400078072461421870713162071176227243553400204034625862157643623617203115234046563256232806750543822670848323427755448215870168576404750227120773663868780623554673551445E94254DE0F4BDB570C48E4A4B84D39B8B491B4B272EE7207E36529E757A3EA9B5276ACDFE4AEA3CC6A05CABA81A46731C132A2EBAAE20587477129304990899FA1D512C5CE65287A6F8C0B1C8C27B44C21E70BAF94607D74A425ECB282990C7C05C66413809E6FC4211DDCD4A3DBB34B55359C85CDA312B23FC57448C8886B74B9DE589433DF4647066A32C4ADAB91470151FA69CA74E696575AC9E666B94568C1932554DB63A48FA9A44E9A34B0FD6C006148ADF69409885A99E32AF63FEB3EE8B7E8E25D207BFDE31CF17C2257A6100112B0512BC42DE1D38A9A292723CFB7F4ADBFA97EC6DB138F916CB479BD30617C74872E5000DECDE34884086D2640BA4E26A21FE0FC02F13F029A317D2C28BCD5C88323BB73C41536393234015DAFC26AFCEE2C42D8641C0054C6F8BD69CCC8EE136DFC1432DBFF2FA5239E032DDEAEB6CE6741D24DD87ECAE126A7B54DB76E505F93A6352BF154259AB84E0B6B3268DB1EBA038849E3C1E1A638CBCCD8C255BBDCE05E5A12951BAE8EECB62C4D8F69F89AFD2E57A216BE5FE914E82FF2FDB8DC8180FF798979766F95E06DE29907EA2BBEB325E3794773E1A1647F196F2A0D35778B1AE8F34B02A9851D132A0B6C349B3718231BEFFAD69739BE1CA60F863A91CB312AB3D9C3EDBA8D2EB3DA894FCFD91ACD00F1211239CF8922C5F970352B754C92A1A69D3B0EB1B1207F1E02487EA2CA8D1FC41578566E6760B9F65A29B77ED07491D9AFCA386CAD30B940BE4237115B4B335B080B77956019FFE5407081981C1A62ABE21EB27E5A74318021DAC60F710B5C310EE59EF7C4065C5B97E44639A1736A644A32AD09535B94A9E26407BE3DADC4BF50D27576151BFC5A57179EDE6DE8BB2A8E83AA215FAA3EADA0993FF66F2569CB5446C73BF3C5451FD3A0498579D945F23A26980426A3B9E8AA23FD26F9651D1E06BA56DA1F85B7C4C9408A6F074062DCE52FBF9C6A8147F86B793D41C09E3FF4317D68DCF0BA7A1104B30A2930CD8E248D3DA02AA931F4A3A6E46E20BF4E9B3EF671E0D5CA23BEB7527DBF6E36D622356867A870EE5D36F1496357897772C89D1D2C11F8CAB88F26F7CA6C941190DDB06C57001B70534F1092E23D43AEEE40483E4D3C4286AB6F51E07AB71DD86008F5B0268D8F3507ACF6FAB2C2650F1B43EB4B3E32A959CA23B2C1EEF2646DEAA03A81042B20B9A03A0595C86C5D8D85DE2DC31900E983AE122DD679ADEA13AD7C1820EB1D35E2237EBFE5E00A5ABA5DCFEF82E52E8AF34993D30160FE3866856BCEF955EC731D99B1962181A31602FC7E6746F9869F747ABA49C1804D742D6B072CCFFDEFF827E9F66B533173743FAF5D88798698BC2466D0AFCE77BE660CED7B90B43E4C81ECD9FE5E3CF23B27AC363A964C1EB4D2B75A60D439B6CA95E2F9DDE270FD722D4E14199EA6A5EF69D2D59446E8F2C8BC072C1488FED4C7CCE0B547B70F629E70FF7EAC26A56DC35190019BC5A141F2850DA2FBB79C847C338350A72E556B349CD82C2562D93C273A62815F6E17CF7D731224F9B4F0CB1CA6FEBFA28707A26A37A1CD6CF8793E34FD55865969AE291A23929FBA90EA6645AF179D92D65198E30AD5D7FDDA597FC097A021DB3CB85E1196F76A17AE1C8B907056E7263924400105359DFE7099C4BF08425F68C513714114CE9BF6505D4AB1A4C31743C62E11AFDDE423C9C4394731B892373B156BF828978C17D833867AED249B609C4107A43158C2EF607789922B6F72AC827998F7738D662E9A15CA66A1200D7F6FC9D8523E4D40BC70D8DB762437800114A6BD2E58F841B53DB842D345969DC31A8003402E6C2BDBB8782CA5198170662662C3701AC0F6C7C9E35FCE3DB31D363C594C7E2C98206F280DBDA61503CEBC145F73EB541913007394767E8FA21548FEAE6F29E3CEDB09AD37200D082635B3D87CCB2DBA9E56E00A50C5592EF3574D7F49EBC1DB5CD33A1DC46E5A26D80203A3AE44D346283217C72299370B254345409122A187F099ED7734863615F91E083CECD1D74CA49F4CD8142361C2378289CFDFDFFC5B54E837E41DFC9204D4905956312214EF384EC9A0D907F07A143228E3B950FFD27B85B43A1A5DF06736D57F91EF4CE7533B5DE81B2CF21006855FE5448E0071D40CFA25FA76C9482E7E59D09FECAD3FDC45BC640D36EED01AFEC01FEFBCA2E7EC71F36689EDD0661465F97628E817A9517311C5BCE985F40299148BD7F6187590E72FC8D56960A0886D93510D660AB96805E160D202FFF3752D6A1AFB68A5F06624F9A2127EB5C008DD5C43B3C6B4095A40F035BC095941CE8F89905A3C6AC8FE51879D9B5AF24847A52E1A5AF4548F3A70EEB3369E84558C16450CD9D49D2AC5CC6E022721F1420B93ADBE9FFFE2E91926FFC4F4E443CA2523AE8E7A96F10349D5792EE079FBED9E1BF96E1CE5F02FBB5F41AD564EBA9EBBA08C74C96132304FC0895DA7E6E34B5C99D333B97C062F343B249CE8A42C916C1E473AC763D0643063AD226EB9ECB4A51BC7B8291D58F8C1E1D331375667F0F80B71543B052A7CBB8B95BC267620FAF7CEA80D8CECE430BF1E515144817CDAE07802F5BF8416E41A179AF840A27D7E0449D8E7AB71D6A361E56DD57289A8638C16A6BD4C6B946D60C75533D343567107E67D12D1C7FEC1628F9C75C7F81033766162C4E3AE0635801EB74DA2EE0FE14B3EA5385154AF110657E7080A21A5CC50FA7ABA75D6C68BC002ECA08BDF02CE3A2675066FCBC846917365B988FF162866F19299ACC1E79EA08E36742B31953ADB3F7E1D38AF6D8B2072B35EDF4789639694EF82B0323743CFA075D839BBFDD66B6B6753D5EFE3FBDB97FF00F7BCCACDE4BA8EE392C4996FFF9A27F5E7EA34AAAB868983F2BC2127A3083CF3229E15D0CA9628D6F9CFCA04567434452594B5047767AC031CDCE5C0745340543584724282BE058DA5306D986C8A20CCF9229D40221A66CEA47E3FBE5B85E5989F464128F7941E29DFD73BC85D470141DD8845344DBC8A66F45CCAEA192B0904F58AEF8D78F39C4CEB4E289B75F2401B8036853188083C60AD910FEBDDC8FD7EF70F007B4B7EADC1F24E72B97AB441DC9B20323BE021C61C4708075B571A30D7E8C9A08FED5DFBCBE215345ADEFE946F44C9BA0F19C3D4D0589495864BBA958AE84888AAE853A59E274A07FC2452B082B84153888A5C15A5896EAA0CFF52BFC525DECE99AA476C465D5B53D175108A996812E21BEB615DC5EBF7AF1F4CA7DE7BCFC49356DD08224D08363EB068DDB19AC2A4B37053C0C347925AF4B5CD05C35413AC450E344A149FD32CDF9E37B38AC4230ED4D04232A21942780665C97F6BD893E438558F8A1A4865A9CD7DC0100B5DE099B163A3640B8DAFA75468BC0A93FF75CE9F58430810345124A8D4FA546376E8E56DB2610129A845F5351A31142973810DDDE9CAF498C7660BBBF3386C3AD4EEF7C3B5DB7AAA2C406605B60DC8710B94153884CA47A99D64DA2DB26D658C9DC3AE5E6CEE", - "message": "DA2755DCE32D07B6D2C2DAD6BBF7CF5D4C26FF0C9B6FB9E064B51829A1ED51A712E26DF8047B487FF0755CBBA8FFB60DAC3C45E238608F48205A582BADF82C2E7E83D672057B9A9209386D2AB8D93BBDE0C522CD1BCF2AE95573749E0D51B85EA01494E3BD97D3CE0A61B26249E4BB94F9667D6556CC4313669409D94AA4F3BB9AB70F736D34245E2A789A5FE2917D5F4CBE43010C5215AF880118E1F5FD47A4C195F3C74307523C688AB76B7CCB157F75FFD79149B5508E7E527ABF718CE8E2E4162BF810F35E234F8CB65DE0930202C1896DDDE02BBBEC8D03BAA12AA1C91EE798FF7ECED608E3DDB7BD04A1DD9139F4A5613AABCF7AE495F9CE18D73BDA0C91583B72CCF6A722C319AD5B1051E65C1B91DD05AE5A77220BCC7576F9CBFC8A12CD55883AADCAD1AA109522F286B00B70C8E3D4C6EDDAE7E1752097C85233583BA0E1C05C5624FF65A3F3894158982B633EC92C24382AF48EB2DF5EAD30759E99D67B8BB1144939F4080DF0E1689AC0D4CDC73DF1CC2FB72B92D5A69019087294D5F2DB196CF82B7BBAF953F0568663596F78B5A309738BB294F7AA3FC5F3ED5BFD4768CCF3304C836B476458E14B233C156C8407636FDB3EBECF49B97C96C31F51353B79C378C6F47F1913E5B14A82DEB126D688133F9139C12C45BA24CC9C7E2C16A26329D463ECF59746F5A99C6B03896E851815EF36F499654E2764BB8BC60EBC821C4D0B4C363EEB7849332A9F1053A975B092AA3AAE33F06F760BA1D76DE07A1F48ADBEADFF1E17C34F9D69E409DC5AC83C296C402E042FDBFB0B6B4E023B15B318337B6A1CE69F1CD3D93FDD0FEB7AE259A41383939253C317DB949E3BEB9C8F7A79D083BFB46C50AC00D382C846B78FAAA7399ECB902CE8B73A1E89374B1DA65B0723C67B24899342DF13C07A0BFE3565CBEA5892F8979E404BA84847AF30BFC04D8EC77B1C5B9400CB97622E6D3360836639670BDDF4E9CF9FE3D6B98A5FDA42422DAD6C829B9E33F53686E2663D232162D3A78A7202EEFBFA4917BB8E89375279C96C9054C2570DC3D90DCCF0E418B69E6443C1B2540BAEBE022ED9A9620C030377C67FF4C186A59459DE7DB1ADFE2923C01D9B8D3AC940486052DB67EB67A257BE7AEE0D3C77BBFFD0FC7C94540F11DD96C5100463C27D65D3BB6B7D867590D573D1C1BEDCC0E8D122FE4FB82F1404CCD061DD7C3D15287F39CBCD2448DEFE1FB4ABA858DCE13F74414E1A8C41B730A1DFB45B859545811C2A9DA01C342A1F3C8B916F60B5E4802BE672C2BE31531DD9E7014E681A8AB1240B5E3D5C0D26E7040D4CE05F9017A32E1C760F466A8D7A68FAAD421B2E2D886BF0007858129DA2F6B92C4CACBC1786291D7C95A3F6A12483B750FAAF1DA03059F89C761641C0AAB21A05E78E1131B8F45C60BB5E8681086717B918BD4FBCFCA1BB5DDD740BE289D8DB1C24FE083B3DCF0E496B1941ECB7D51182F9CB9986CF3F04F0CA4E01C63EC879FD4A3D5619EA1085B1431FFC019286ACDF3B4AAB03D6265A7B18F24CC2815269681BD37263B44DCCA5CF6FAC2ABB1DE317118219A73095D1BDA10B66B6B55421F049B71E759DBE6154F1DB98A7E3FC877FA90217A242B21F39490F2116A2BE8067168F26439C8D1928255B5A50CE1ACCC222087536BC37806FFABA03B7E787B04C2C67C1B0BEAA871F39D3DAC2221AF44CC7089E520BADCFD840E5EE24AC53FCFF1E7D6AC26694CBC15B80E48B10C054E8DEB00AE387CEC9972A28448A6BE3A01D5EEA837703D2FCD1EB2521D444F900846F59074D715AEAA2F46E956365B7E67C5528841145C442E6FD7B3D7171BE05BF8BAA415260F645E2FBC93C46B9F94D2997929349B88C2FB1AC6743B73DE66B30B44E5DB3E07E0FE9713D9D7575EE4E40327A58DCEFBA0EE95E22D06FDFB720993EB134073A80A4F06F8303C7758DD37CD7236E5D80AAE2E9569834846E7F6C75051302486B2564A1D8D987D1A3648192A63EEF4C2D25AD41FAA02C9F227CC9F655A72CF7207ABBC66F9C822EEBDC89833757013776C11C310A22C226ECD33E5B0772AE2DE8B8E9A876650D4A57B863BCC6197261D7D06903D414AF0922312B7DE6D9E64F99509CAAB8D808DFC5F046BA2CE55817512535EDC2477D8462A1817E45D33B9D7390A11E30C3860CBE2C4B519812ABA3AF7050227759DF3B6FCD6D3EE5C60C1042DFCDD7880888A147AC47A282EC51D0DF664451E37D7C40672A27B965CDB805CECD3EEAE38A0AF4C2349FF39947659686D30B9ECBDADD80C9B06293FC4BD5E7A0E1E9E883D7A4EB05102CC1FE45F1C9BE23043BB458E6B8B6C1C187761004EEF59E398B1124B98B0EC0F7B29394418B38D8A3003ACB85D96CFA0C3C63B2ACFDC2BF5540D029A261243E06393253B2C3FE253A220DC7AE4BDE0AB4B386DECA15FA2A05465740B072FBB0C8E81663E320AE931A2DC7A627C805AD80819B9D12EC271D9D16736156195302C93490B4F85E8B4F5199CAF233974079A7AD590374C4E5589D0FC26F70FF2CE51FFB3E6742AD5BD9840F62F745C42D6085E46182FF73FD079BD2625338105FB39110B660F8C55D0830587671CC802AFF63FA7FCFB3BDF6D65B362CA0B68B31FB802E7870C3905B04B41440F549583EC87218DF6A0BE0E209807AF053CA121D704DC0C90A499D1742658BB096C776514C89F6B2D3FC7FBC4A38C10DDBD3C08F64AB076C9BA4C7BF24EBDCE9C82B1BCB8E55C4135976C878B95B6ED108C2031F4E53DBB19205A7109C50289C743818B90ACACFDEF20EE33F5C9A7142B5640F4D875122E0E5", - "signature": "583E9A28CB7C3FD65D84170B159188C12E7E77E0F39C678C2ADF349676BC5A4336041A2AF283D3A0F61BCEED4255E2A04749CABAE6811FC2471148869D81C708E4B56FFC353196CBE05205F737C91C80DB8FCA7C243DED5BC6113AFFA87E14E0DD0D3E7A70B2EECB847762F5521D372C51317C95B6EEA2785B552D9AB045E48C03321DD041053C328A0081D86323CB37683CBBCB3A68A2F850E5C7A4826E88B1AD51D6C1677DC2B081DDECC66A01D3D3CFE26531B4EF89528735A8CE75D4B710C0F3FF05FAC74C99585695BCAA1D1FEA42D6D5EF176B90649FA92D1F089FBB63882AB9CD539C88028B380E610421D3C09314AF44F6BAD1129107AD1B84624AEDA7F3BF3A7698C478EF5DD2639D9555E53F60F327CC66143438C589285006552FE249B3DE8F4768B9774591672541385018FB6683CF04C85CECA1A9FDB4F44EF31AD9B78B70296CACBB35A600C486202BB771C75E83E1A0429A31ABFB75558ACCF835FCB68FBA01F5B766F3BF18C23B3DDE511087E8AAE570979BBF17C8C1FD69953823B4FEC56EAC6AE11FC4292A40BA01717F3A6CD108BF94520955F978354D78347ECD4A0222D89D1D7D93ADAF7679AE101106AC49791B3D17B6391B85E55AD4A12ABBFAFCF1D50667B37E49CA69D3CE3AA6692F85420B246355ACB51848AD2EB94CBEEF5E32D455FCF42FE73562B5B149CCF01236BCBFAF656E85C1D9775217E51D4F650FED78D8BBF2B47C67BE41F69AB2C2B1904E86506A371602A8B84A50BA179781215C0B061522EA66AA7CCA390055D0A461805CAC87ED7AAD205777344B7573D76690B5B46AEC4665E36A9173D7732F5E67FA166BDDCD56685EA1A41D440E469B7B65D7869744B1776DCEA504B03F6057F9A2D916BBBE6A5032356F4C3D48A495455381292C52E78F8478A56FF0EE7B94B83F1EE690F7173729DED18DD712BDCE3CBD887771B1D87EE2946F1ABE293F3D7A7ED224F6969D31D2E1F71F4D45607D7EF59AD25A40B4A43EC95FF0C8691D4C41E97832F345CB50890865AE483A163966F5B45291556826DD061C30C8CEB552EF8BC2E987BF6C8F629370A72941893F549864389CBBDC3D38D9FE7AFF8682EA318BDE62A2D11E543051A88B01547728E30CE25784251B73B771EA65259E90C4A859828A65A87FECEAE332B9F51A986CABF15B622AFBFAA04C19678DD200BC0B338C29B65CB121B70DE6EF964360F2D54C4D34BF7270212452BECC9EFB2E225A6007B35C000D276D34AD19A966D49D98E140DEBE503215D716B243CC9387CE52DC10C5B40BC765C2E4D3CBCF8E1617A1F0133DF0C98D0AF71E18DB6362A6E4EA9E454E1D6D986D1DC50AA580DC7DD131E66EB543833FC42A575A84B652E63164BC3FF383040E6EFF2B7550C2AA0905FC7BB4258176585544DA49F48A844A13052B06676568244CC66660021FE78053CD4ED1118C05E517107F614294B97CD4ED6685D2FB44B8B01E538874186E6F8D27D1F8829243016B1D505D42204FDADD54BD985BD647EB79A1BAC18086FA8A3568343F58A8D46A6A35C28DF1575CCF1700160EDBAC0C66A406A26DE724E1CAD5AD52554CDE52EC6B5063918C4A137D758C08272E4C2ABD41B7EACA4C44A3A7CE60F8628F3B13CFABF50F16D02B375A7FAD7460C53A8008BE19D982E9794B060CAAB1AE6FDA80320EAB2E02708063F4721DBBD8B9FF951BB6129139E90E7C1754D4682D029DBFF5FA9E713330AFBD9DC2FD1148BB388F4F857B4E4C63FB107386DBCA20AE196CBAA995F522D6BA4D2645F724269CA1A5AD24D4F56804FDD9A305B30C46901B484CE8D23166A5036ED775CD192BD47D9AB6612CB6D9181C1472A1F11E02E7C82470E8C685E92F21996663B18F8738469D61D98336D7C53ED2670A8DC26C21BF0BB105F5C905D2AD7432681AE8EFE5D868ED0BE906474CDDE2BE7BF5B617463EF59BE4A210C3D5682AD4DE5C059F1136D2C455BE02AA1E276F135C5001388600FF2F6BC6DA8AD0B72D1F5301DA9A8410FDC410B54AD0BB2561B01D646214C867726D82D3919B4C76600DC065C5933F8C7D3C916C374A06D7F062889CECA4D0A98FE843F8BE1E724D88F6B6E8E066D7B660B0FEE10CE8E36C4E60269CFC3745AA960C8BD9F7AF8788C4CEA7C4BAD51A202162CED055B6B60F8CAF85ACE6F60851250B1BA0ABCF9DA2C7EA2BF074EAD9BF81D73ABEA3966D63D1E60809050B7249B7969AE420E40387C36C4757AEC7CB328466D118E3794903C33F230114AF1C0AEE0112197DF6624123146FB3CD30F6020378040A8546E20767B8537812D0941836A0651AC90E084ED6673BCBBF18348D0E4E52FAF06FD1A42DBB1EACA550553595A388BF27735E85FC4965E61CE82E96430F40EA3B35B874CBAAE2612A714BCE0DDCE94FB0F4D93DBD7F6B03C7099956710E5EFC5C996F8A7CFAD679B496044F5204056D594DE05B61CC143F834BDD5D8B9F89557FCC09702848EF9A391CC4C3F07F1CFAD203B172CD1F44E4EF08C35631DE23B8E0CEA4C4848663FDEA9C9ED8B97B5C7F9E94AF6A90E5079E40A791F1262BDBA96BFABDC30643E2C3159919EE5288FC75703FD0D03DAB0C36D0CF06F0450A5E6D710764085D0BEC8B26FEEA7E5C2665C7F514AEB5430F9C307E7D03B30401646A0D93561FADA21975D8BC4EE1F20329FFB4625B3A484CA08DA09C61B45E2BA9C88C29B14E9B650869EAFFDB7EA3697F4DCE2A72752B2459601E044B52F0DE99BBA5510128944C00357845F374D60E373CB35FC2868DB5B948EBF9BDD3C66C1740F00711965AD9549347CCB3B5221301159472AC8CE0B3186269FD1CE5CD0DD456222F10264B117BA250B391C840E51D8680BB622769ED264148649D3B954839AAB5B27546B8BB58A20BB52FC8772FACC04101148C99DE07B96BFE58CF2F04DD5541CA9D24873557902F0BADE63229CB8658E8E5F815719A73F29F81208D0EA8985BF2DD770177C4FA88CBABBD0C9181C0DDEF7CBCA5A6EF12367882621E64ED026A859C60D0B8690924EBBDE0C0E3562E10B63520D8C801A6814CB1AF9F03C3907FD9A7AB8567FDDBA869D7200E9284933A414FE681F04A45BC3D909267FE62FAE7A52F2F84D3C02A10AAD86A1C7A9686A2B7A81DEAE6A1289B7A0792BEB805A620A38F7610D9C3AD1CDE838DBED11A760F42A271020761BC41522EF370726A4683DB705C7CDB858AA8A8036DF1328AFAA0A4B31839DB7518164B11E6EFC15755D1E0D477EC004F5593CF7F862AD24295569E3D5095B8B0F1AD427C1CE7039DB9D881D5E6AA570144255939C22AE7EF4BBF9CE36FDEFE30E64ED373AAE944907F5BD02B70312F7150CDF487099468B19B94703358505F7A5DC9317B9B17C44685E5D609A0F5156A1D4EE517BB681CF5657AAC2A1A678687E9995F089CAD494A6C039774FE62AAD3D2BEDEF62681AD24884D1630909293B54C68D7CEBEE284EF9E70049748558DE03DA23B478566B42B8EB327DD8BDD473130F1D967BC0F6E4501DC64836EB877BA0AEBD241432C503E41DEC7B264E08006C006FCA366EAA277CC9F5FA6155C9E48E852B718A071082FEC580B4AA599CA7708AB4C1995B6DD0679264D8372B5CD0EDE9E40B6CC0C3DB14D00B2C7D2E9433F08C23ACB77F991A454A3D1D71379D08640FA5074EB5364A531587907607FACD9AD9036C8AF221650F01308F53B8D0E432E5529F435F40A40E66A5483115FF438107F88FE5F1D541C500F8B12C9DE69CD5B14C3FCC5B462153F9DD49974C34EB1C5604606E56C746BBA8D90E3DC4556DBC3BBC656A54E08ABD3FE1C39F24E99D3D022828F59B80C4DEC6EC1CFFAC05E388D3F62510AFABA69C5E3EDC898CC8BB842F3886A88AED03739C85DA459E8329D1AE249E26EB60BDD2EE30191099C96C397D88FAE9922C72A275BEC1C7734CAC893D906E976FC7C0AC8A090986EB4F5FD7E94F8B2694AFB4170CAD4F1896092A7F6EE01C300DA97538FD5FBBC6EC28D158D3AF40D3598753883156B0DF2143131C2751F2B26DB6FAE76773E55AED9D115E7FA60267DEDDA65F41CAC5FCB0CA296EAD1EC688C742DDDEC5292EBCD47B0570ABBDC2CB6EA301E58778E1C3352E393598470D2FD2C45BC3A611343ECFE61AD64E71033B6B7C053DC52AB1CB246682750E330560F15B3B2D83E63F33BF4EAF608393C1F5811B0D12244184F20EC0682D236F583CCA8C8D332318AFBC50C03873D68AC44CAE4C2826E966E35EDEEDF4B232DC4B3BA87F3478FADD0D8EE55B408AB929DDC85FAEC0AB503C2F8192DF7B719594C7706B98C593C598543565C27BD8A0A0CA7E802B86214889D8A08337C65BA31BA08BEF281FB69DED0B30AC13274E1D98FE3F2CADF6B6FF28334B338984516877D3070F379991A078E1D0D25CED600D2C52CC335711826066976251DD11AD21B1C852E05F3D9EB0D37E95F767108AD378770DFF10854754BDE53F8CDC14F6A48C66463053F8DE46B722EEFC6F2BC2495CB107F3ADB39BDB2AF497FA6AA2CCB4F9801964FC6B88C9656D76C0FBD9A436D1AB57D763A8B814D2957E6344312AC137B3B6FA74AAEA860186C02156CAFBD455E8B999AB52B70DD05112E5C94DF3352AAB3E2071C343F656E959FDB000000000000000000000000000000000000000000050B0E141922" - }, - { - "tcId": 30, - "deferred": false, - "sk": "7D9BACA9C8D5E302BF5CE4C85B7685388CECD82D72EC259976F4CB65C360D74B7AA8B23CA3C9D786FA3D949A9DFC1600C821B808F0BEB38F815D7688928159D7D9E9C1F80FBEAEB0718B4A27E5AE16AF325F2362539164D1B0F282131684089E9C61442C8C6EF03818E4FAB383498A91F1A6BA3D1138FA2E6863E7BFC37C768B80881102106834535885567854243344502211757522267523162088466534441253602763327188226627581385652565414151784380762722456634142628231458738808653824328765256787544665871806531822248171715644617852253306323676053473565268176586832213365052846420073311447520430470886788436502856868764754304758685773064126124086602270614670066264160503303628808800428371124331158623773024150040258466354242631322182837265206682145238541377758026231302173751556168744863422724538416543335044260014140700080223635662746130854042515087002685102861285410486525326637353184253282228015078475041117212844878141825033873150751831805782170351465068071671207478634401484255326350633185463351180560737581677164273148337620650506318728817625581311474587143474200631175767306836700454673165201446440552351405570370765020236227650155735776370575127458246010022264663462424423213765310260018843165528661703717074062347113507035301545373865105171508624854887346415101230182053334304844180245311205556878267210221681707671130563111227840346163445346756381740517462567744211002860288204613256541014522561605650738111510652486113003236284705828187520165420710141265210772323357340165116445210432428531411538578270768734622774714255868725625185866516828826288225225382481362346231732171642643803148671271817471106245053755183045102417242701340831385358686761031752488155811285174784301446783814603452746400881104301515340323411220606187382848113531273238682142164176684773160428640811770836021008816722262735542177425024011656734742220208177654327651838237731115676205078445837425763855715746545685101718301140056042410640767435220144420781045324711834710612775235483708256718366036056834856355047187872866251726612854101127341052403064311315244428128784365157205414785337848650728144772332137377841026231712784787072708207440534642352015738400562513805485583235012405755534737647887617687056613236528823413687622035830161327666432826703008462403420246788067276833355848330825352627051271045102466531806664112101702762667023185287441052104507353315241367611074381635451018347836601447556273501604602706013545264275427561702133764222721520838326555538771678808754764612652255384672763068833424642760475458348132214166041671261184323442617226644673580125123380608502007202213714484438825036152616448882228853238503436651346737426226137454116521806224384547167800842813436447366152212332813016632406320458758564571656076278257144143508780111883350040472187651326241722885506068843614384407717837823233334577603583138607157753607181603248844021525518610382536002436628707660830482135508327523234521413058137640267365080463880375267721714644672516818385618535542842438636753417412616738466876353522248666700120623351178721720464482820874272415685137628481655455861246778640761403677012083646508583110082074453101204426410178432288412156182720465184485112240375BF8365FEE3A6C811138E1CF73BF1D0EA525F2BDD4988CC157A976B949022FFBCA93B2664028F9D0ADE28005C84CA7CC39EBABEA9C92075734D9F83990353AF6D72693CBE38659C9305C804B8A75C8BB1C5FFB6C5A681155A2A65F85C8DD4A14C6B61C45D6D2BE9411C00A29DAFDCF3D9F1EC1E2EF75214043AC120DCA4F22AA7354AC2B6443FED11A086B22630C1B45B2A372FF2F1D0660C41087F5CF818FEC1FF96F18CD710FA09F66589010708CF8D299EEAC86E1E989C2DDD60A2F68DEDB62B0E6421D4DF285AA2A32F442E35688826E0A9EF9FC32C32F09A28419F37DE7747DF9C86B5A54A558D374FC1C083A46321E7237BF37491214F54973CE3BA8D7229370DFB27DC68F33EE68BBEE33DDB63B3AC4E4346D6D96A6A300F49ADAEF370C98AB1A44A4D5E98C1B19ED433AC13C5A099894CA3481A36820E5548A04C632B0995BA976A359DA6F029DE8443D7AB197037AAACFCF2F61D33B604DD3BB09B26523B103B0AAD0D2163F09294A48042E8D23599DF7095E009F393C4CF5F295C3F5E49F2AED1F29926653C48FCD8D93DC39422405C38EA9E28FF5ABBA4FB699D158DB7F70E30716DBC1627A27E6A93F594F6241869332D4F3CF41731B84C17DF195B7C7CA7E4563AC9EC1CDAB2D1E52E5C6D38B4C63C3901BD860C038A34284E71834247D1D3854AEF49E2BF6F67FFE4256869A41BD44B0FA2E0CFE0345EB3886BC4356AEE11A26838D4F2279AC13D6CAA53F110ACBB1F6764BBE47BF3C4E1F0B9B99B00B6B9E0C50053FB32174BE392321A3E0A69BDC874D3F3A42AEB79C4BAB2753713A5DECE419E2BDBCFCAC6CB741425A64CC7D3180E097B5285E0B7BCBF9B7D97DE81DF3227C2DDAA369C87BBF3F876AD8B81E9208C2EAE363C3A0434BAD92F49EE7B6B805BCA9CD6C0A2C3E21E5D5DD9AC4F427F62EFC96C13F6EE1EC761CAB24E61DD6F509D08E8E5AD4EDAEAEF0679340677882BCDFCB6928AE7C2052DE7116CDBBAC3551CE0DAD8AE909D795393CB8A6292C7FB2C16EE62B8B5F05CFD5553A7303919D563B7612E65EE69C97AE80D3E407A448C88D508191B98821F03F3823DA8793054FB0D051D9BD12D090E2CFCCA4DB20C6AD515E5E8658233C095781D5BB1D40BC47D3BDE5A6379CF03511B2A3C06A2C315730A0349F83512778A5123F7CA9FAFC44F73B1259090F8746F1AE868DF6D158636EED34B8FF85CE3C07F7378ED5A3E7577A6FAE7CD3EA0DE0EE3576C48008E2E4F8C417F3606BB1E9DF468E40FE74A3C69A672B758F1C3AC570E44E9A08936788B44A769B28DCABBD3266A82CDA0CB6D2014B73BEACB33801007C40BF92B647FAE6631648F7E91DA022993A9198153B7B3C31B487C863A639ED7AD4B235FF3D44E3AD573036902E3C41A53D34704237304D2E4D72A3F41DB6BEFCE9DA8945CF5A9AA2217A2B36DD2956C3F4C811B3D2A95E1FA88FF2ED95A0950CDB1A14DFC89ED6E996C854C1FF056A73D7BFD1E8F08EBA003E3E834C71598E42430B15BC0F1FFF6791D639BD40923A28FC4B72636AFF01EF4F01C4894BC78A3AC69BC595760BEE8A227DC88AD1E633401B4EA43BFB070ABA4DDE38FE0EE6BC4958F1E6481BF478A9AEA4EC2AE56993CFC33975C06B571450DA0026DE58B99B6D44F2AFEDE582920436230A6E81BF051BB54A41AE6E6C34BFAF1C7F03A44B85ACDDE1B44DEAAB8299905FB5AD961FF224C717E96DFEDEC50D5CEA646D2FFC5F7B6017EC540924D1C9FDB8013F2957F271C85027985FD4184F22E790F91CC7C44C1890AE83932483AF25FBC0A9C740BAE467E2CA24AA7E86C41A9250260B3A4F805D6421B8772691F172FB63939606D50D03F7C4AA09EBCC2E5289BF4B9EC64A1307869CB4EBAB5C0ABA222C86E21D6EF32B82B7409B10C67F7A7D54C850C277728C15230C56E3B0AA375440AC0B55DEFFAEDE52C2F84BA5FD49A5AADA5AF6C9EADC0E413006F4149081EA8B06A3590E55D55051AEE474E416C7C76F0C41C372B593A5A22CF9D520C59F98942B2870408FDBFA063FD14B6615EBDA85ACD3020382E696B84B4E6E6E28B1F6E279EA4C5AC3444E670F5B1F01ADC3331B4E13B1387A082251FE63E391E3AF0FFC8CD5A77D2B77DDC75066E04F9BA89B65E62F3F74B5EB53068449A3A59A3CB8351B5F8012FDC5B3F7ACB10AF933DD9FB5C094BF085FEF0B27D9B01AFDC95B3B96633C5082369F03BEFA13D53FFE31836D1E02ADEFFEC0CAA084050CD5CF34E1362D4BC422418536A4F5048639A0F168743459733CC11EE616D810DC92B266BCB0B78F32269BA68F264B669302E8FC2E35F998E2B0438EFA2FCA0B14F0B337701A4FD5057AE3F1105526EB726381C54D605D21E9A1887DA4F8AA09C3D4CD0E617BC072F4050E125763812D4621F1AD8001AA027546E472F8317E9F37C27BFD4380D4A5A8C77FB426C3F13E462E06B6D7C59C8DAE7EC747E4C08822569421C70EB62DB7C3F1EE9CAF7CE384ED0B58A122A2C0C669DC843CD21F63E01CEED8CF7C63918CC7CD04B80556561582A4CA24732956700D5AD7E65E1F7D770EC84C6A8B7F7737F4B597E305199C8DE6F73F3CEB730CBF6E87E53114D931024DCC1F3EFC56BAC8BCB374C92E2D687E735DA892726B2E7B30135D1CCDFFA0F81B8986A9E646B9D875487D960FE87360C625557CD5ED7FD45D18CFDA97B410CA62BAEEE3C90C9EC02525D74606EC7EC1169B250E8FF4B94DE08AA95150E52715C18DD6A03F2A399956F3308B8CE72A96D2F41E2CD901D4D507F336354AC24DA68CF8F83B69F12E54BAC40F9A7BCB1D1165E456DDE5C60F5BDA4F8C435550B492B14642A329C90732E6618CC73B5A32C71CF306BD89B074C8174912556C3FB05DBD4216B246239B096CB8928162E3544FC40EAF652CC91004686FDE0A3FDFD80BF2770DD4FB79A7029B0DA6B01C8DB069414B26A05C180CCDFFE049401A348990E0247B542C7CFCDE012F3D6840F406F7BE782DBCF4F6080BAFC7BBB201EF6087D38C211727C15ECA30F003AD52CD540D8BC4DB81375F44E0E092A06F9E9891F6AAA178FC39B3E2868284330B3D2508B486836D9F1F5AF0464AE1DD2D696AC0EFAA4D9DEF2E5CD28A5E1D42E813D3F16DB85BF565EDEAE869A88D082EF43A33F936533D151E0BD06457135FA0450AAC65438C729AAC8598399FE8AC0042E3220E936F88295E45BAF653F405B12B2FA9D386BBCE3B46137253E7C64BCE7E998DCB4916390FF7E2F074FB1754B60C3418DC6C5728E2FA364ACB2C8BF63525849F2CEC268DAB24CA73C429EC350DA2900583D9C8B2BD0AA7F5458B00DE9E44209946F70BEF1C7ECA26CF08DEF56CDBD6C1816D52A373F822321468770A6C5D8BE130E6C752D63A72688B786168480AF505D914C13EAE57905AE47E10CFBD62C2097A7482432CFE5500B804E3715411AAB787FDCEE2F644F38EE9A0784E88DEC94FB9599A68A0105577162A6FD575EDBFAB3D6DA5D2CA2F086A8D55A325F8EBDA84E79D96D794097E62413CA", - "message": "5870BB288AA6130708F7BBAD9FBDD6D41E249D620495ACFE90C61737B57DBA890213D4741718545CCD8B3FFFC2DB33C39AD631D5B5CC902DE4D340DF03E09248F67E89D28071AA50FA532E94C391D2D1A61B1847C6B1088BE555E5C2694EB0FC1F029095ACD9DEB21EF886BE577682CA96AA2EB3DCB24B871336AC5F23C8488011860B455B687BD4CEF5FA11381BC292B4098BB2CFC1822B48ECFD28AEADA71809BFDA190836D3215CFE755FDD9374115E5A0CCAE15240EBA0147C2F89D8D24454D7A5AC2D20ECC0D46C040FAD233FC51C870080F1FCEFAE6C073AF5F7A78D610E23831D5990985FDBFDC6D101ACF3DB0A74D71739E0", - "signature": "4795C93DA899DAAC44BB2F2CCF778D14AF2687E26D40A5A962084FB54F037362BE239723AFB994A15B17B6B779A80CA4C88FA1EB57DC4BF743734929201969C7DBCB295F9D5F994BBA406E24C4A0EEC73368785D9B2C8CA45CBD7AF0A772442692E69FB79AA17FDD80198870BDA0A1F0DD2C89D22BD6660E62802F0D5183A7A9CCF5136E6BB33AE991EEF920FD80EF911BB94AAFE0BE9CAB7C0AC60A8E763242C3E8B4099C7B8B1661E63F756A0B743CFED12484E70151E39CE81320A687286A3719ADF712D006AC81966286C1ADCBF874A359EF391B892D4A72FAA7BB43DC894D0BCD7B77BCFE845677DAC9252046C2578F15C5AFA19ADC9B5D5D6DAA9910F3DC0187F1B12F7F19ABC6ED9AE0CCEC15C76E6003D7F9040F2F6C61FB568C16FA69BFC87E228AB08092D2132E3F50D07FF7020B400601C603BE610F10F19F1014DF1C56D4953B9143BCE64809426F3643D37C99BF27582E4ED66ED8987CB16853148712F82C3E49A4B2C763C010E74347F816DE015F8568024C1B6272A4F0691CC4360ED0B4BB81B576F46A8AA38CDB39972C930CF0774CB5B59871EEE17821B30F58A25BB9702C1A4868CE50FC3C7102E23A75AA751556DE1BD3266084645C8F6AA90B2ED743FF39CBB951A64C5235F1255DA9117630C150E1870066D5DDE4721D2621417AEED53FC1EC5F89D5EC9BD7A6FF0C98E4A2006B0118B2848312ACF3E25AE401807B0CAB45BF54C186A85D096C71C4D14948547792C290212269D8ECFC79BC0FAA3D37F6364E3FE33B326C8135851B20A7D95FF10BCC765251ABD53F4B98B0FE2BB89FE5E15E06D130F35871B5492FFC3A1DDA21E7C6DF0392C714907B7CBB0C977880DE4BD44E3BD1C2B72729D071CC1FC0CC93870EC8996940C943C0209D3008B90F22A8597320B201100F131214CB43E6922168E574BB7C6E4F4A85CE11BFAF32256A649E5C95BFF1B83ECD8825CBE665C6FA98611EE7F4977512476010015DA2D3302F7CAD95FD70910974AC858006DBC3AD8F8995C99C8FCE87078CF218985CE6817336E501480B53F81C1058EE0F7BBDE9E212BB1B067FF34A3F8B55DAD9CD0DC963F8C8B835DE200C294EC402D01DEA0540F5CF92B55252EE651A4190714581ECF2C9617E4AED4BB0230C23AA16FA9502409B03E6A3FBA7D213BE13180EE2CF63B73D0809225F59D2FD14A12119F0A531D250BFF575DAD676F692E21604E2C83AF932BBB7DB4F3A4B15BCBB45CE3C52C622B14561A39BC6582BD2ED428FF05A50B57DD355469A5B36BD5CA04E731F688BFBBF30C450D35FA94E74F7E9172D7F66DBBDF13FA634F3BDC891CB49CD5B33DDE0FD7EC8C7E538ADE84B446781918DB26D363598DD54345FE4CF3673F69CF2A368EB3F6C6FC98E369D9A514F8359CCAA96C8E8B9565945D7C8894B6BFFBA4CB0FE2B1317C424A080A189A5AA8FC4F09E94CC90F3CD74626C519C2A99C39734F26E3FE99DB512896F881034580E2882914411AB3581D8DB80B46B4ED9B22FBAFFC29EC1DD88BCAAFF56A56DE5055245897764C3A45D511245C3523AD1DC7898DDBFFA290683412E8B7882514372240CD523908B0C92FB26AC669327F840A9496BAA63D1915D3D1D8BDBFE63BDCA662E1AA2F4BED11F07A4096A348598BB1E9A239B2DF0CC2C1A7D62F91A6D18B1175CFEC5B74D63154FF2141F82EE5C7DA9BBB4523001BCD174EEED70225F16C73F2F443079E9BEE77205D4928A05166CFBE014A2079661D8B609EB4E66F992EACC830D0FC61621D65E34DFE8EEFA5D782C56426E9EFEB253EB8233B08A3A6CA4AA8D3916CFFB7783C9ECAF0AA859CCCA99AA460DCC193D878D6643492C10101CE59809C5186E3459444C395B036390AFA2E75416EF6F04939710CF080790BF2C6E626BF9E872C7D13CF642E9D9C57EC8DC106721C04F13A8BAB6FD151C8416F523D4F2EC038A2525096EF495273976F3D1E7DCA57D5758A213FE5872F242A67F1C2065083B1BD0214642976155FCDD227265B6A4EB47E6C44F56179CF514CB6D0BD33349381CC4EE48CAA16318DD5DF500E7BDCBF5A46DD24D0A5D5DE106B0B3F66DD75D210379C47FB5CF11523CC42A77CD80423F41364D064427CD016565FE2F1F7F2192670FC6C17AB346DBC50EE30015D353239116BE68967C1ECCFB9632969B848C2C7A768CFA771C8557970D77EE918ADF6208C9D803B41B184814A3C99178E835D89BD47403764EDB366E6050D9B342B3B3D6409C577214BC7CAC261C989906A57A0B4BD9BC9778B1D74076CADD4ADC43C7E79F2A0CE5F2E81C36AFBC66B526D080B85E0372859D64C28DF6A7B60D3A066FD3DEB847DD2775A6636F4693F61361B9D84D19A40A0EFB2C8861D9B27E43BB504EA6B082AD62CB4FC1B6FC163AE7DAF8D6A54CE4E9D33B509D4D7936267A0D32389987DC33DE09ED37043816463DFB828BBBB3B6E4E5286C091A494ACE782507BE750537EE9F2E609AE4992B8FD53E0A38CCE7EF962B75F749B74103477AECF55497CA31741D70B1F207CBD694A8911653DCB4D1F919B728EB2C03177675136C11BC2B772C5E1C5F4BA0FE431BBF4C1755E8DBF54A6A111733E855925296C09DAE549E5AEC0B6E0D9DE07E077825941D970BBC9B7DA939DD2CBB373F75530CA30446F3DE199709A5E68BDE9D92C6A323933F214BD4F3826860A131F301DA7895F34EF35642926FBA61A8E1C17492C31D2D13C20DB60F9C6E90FC0152665A21100E034065A67E2E676C33DAF403218848859342991888DC47F12A2E7522B62B1845A123723639593543CAFCDE6D9FCB2547746C2A7DE5182FAFA8BE1C794E8E1C968B70C3BBD84899AAD7A2231706C108406A7BDD6931A70BE7441B57E70AC353B9E8127DED14FEEEA41124F0AB57C6A0A857E022BF717439A11919962445A480D18B2367AC9E483C3A0CA5C3AD667E7A1EEA7D50335950997959333169F8E76E07B051A89B1755AAED4C49E0532E9D0DF5C9AF99EDFEA49B83AF8147440CF93C4056551873EA11887DD9FCDEF04F7CF1F5EEC712B1E70124C6155975ED419F206F5C16C3D7CBB13321599A4DAB457848974B74087DCBBE990542FB6F7F36D22469E3F68EC189893452D6F4EB180E9A2D1D1F010524A1F501F8DE4C484B35E47E517E166D1F9394DC6CB394C1FB1DB6685F07ACD0D25AA4CA1E3BAE21588A5C9B4D229A4C399854EAB3AF379E3D4456102F021019A8097B06CCC6B6FF912158C3DDD27DE33AC093EE6EE76CA9F8A90C2AA8E07A61221FD9DDB6EF440D6DAB8FCC2138B396BA43DB70CDFC90031F424D4C917F4F4C04D6B7ED87FD103FD195F39C755500B8C4120CB62D3818680EFD3564D5626D6486FBF8CF96C3C179AE85E573D1CF858252DCAFDB03DDCA86FCC65DF85E5A10AB4C549E1289FA57EDB1B2899469701678810BC8E709563B4F99AC7943684F4C56056E26C788B3C8E87DEB10319D56A52B3D25CC491C6771496F4A94E5A67FA60777E899945E2F58C9D7D5759CE41733E6845D6247812B11336062C88FEE525C44EE8F73EB1A0BD66CC64330356C7F2DEA6D3465E2C6EF0505AC68502165F1701FD40E0D5F7DC41583C076A81E56775034124910BCEFF7DDE4A2FA0072D6A6BE8695A8440BCBCEE4A3FE9ABE0F0440A9090ADDC40915D2D33D88F1489888729BA0FD0433828257C44E0C4D46E9EC6C9586D5BA3B9D772ED20BAE620E8D4619E9C720632FC92E153D7068E67A6BEEE16A01731EDD5AA48DE29B083820DE5B1171BAF4E75262353CECF8E2C2174E530D4E3B84F12F2729CBEDB10B62902ED39156C32E2C68C7EEACD2DE88C50E9F6BC117707A0E931311EAC9F836CF4DBD7DC289ADCD4E8A536DD3C7C5DB082FEB4BAFB6B7A48FF9C129CE97FDEEE396502319F6CCEB8B5FA38478DF2C0619CC74E43BC22992A526968AFA9D147CF6A2828ACCCE98A97BB63AF3576670C5B61EB5EF7D30BE747E1668C6CF3226B5DFC8FEA39E9D1648003AF4EF2EA6DF3171F7C2230B9717939EC70E53CD9230BA1E77A1C07D4E6A3CA26455CA7B8B6096C49DDA4A9BFBB2E03C3B6F5D6EAF4C78B87FAFAA5B82C0CF7321F5B8B1D9FE67E765A2C073C844174A21E9E8E16656C0D3D888BE6EA17CD1827AAED796B716DB2B23473472A574BFDDCE1D9F92E179FFA2231E75D63DD2834C792211B4AF030FD4010DDFBA1109F1292C3063A65F612A6B40849717C6B35176A42FC5DE4EAF90943B398357AC5ADECB7E77F460732B712CB0EE509D880E2B6419C2E365EEB36477BBB110240F3B20A66CB39722E9986997642396316E7A23532B2D75389B4E39EA49DF5EE29FBB5EE6E0B4035CABC3ACBA0D85AA7214553A9E3ACA04C0C8B800495220A8E0BCE1D0EB6E650EA0FD8334FE24C5DB224F5CE49490F0EB8246183F844705CD75CFDA3CEC386BB2EEB63F14BA4BD86465C25C97DEECA55D14803EE1ACF6968D8820474F86554CF8A1DDA9209CD5162B158031020277870B55FB8BF5B7A961238546E8BC5FBEFCF4E004413AD9FF4671CBEFDC08EDDEA1690D37D29786157C2856D3A2D3D2AFA5CAA4AEA82A0906A4EBF88E661BAE0A1048687AA1A8ADAE0D1A1D4349526DD40A3A3C667791DBFC13344A6568B2B6BBC6DFF3F81C42638E8FE8F1396B8AA800000000000000091119252C30" - } - ] - }, - { - "tgId": 4, - "testType": "AFT", - "parameterSet": "ML-DSA-65", - "deterministic": false, - "tests": [ - { - "tcId": 31, - "deferred": false, - "sk": "F26BFE126886F48222944D0218FAC17CD8A9CC6D67A023FDC07AFFC2D025F77063850D880E98FEE502E017327000CCAF614573B35ADEFEBCACEEA4B2C4D045E5BBFD3E5A72E371AD83B9949877D8E656D46B47750F730F96DB430B186088675D9A9BD78E47B89D04A8517ED2220695339F99A97F353CE4204777209F5F3C9E9A36145401574860507528646172605420754860327385342468637173812671683261247114182615057736275035218250153147482443761885661805642701060601454260806825080836130504323487007071700251371508282572616708526344078860420317246480087023564146174601577402763164738350627261627545734633651436461226043402812034418826773340185803411658880488327105858342553420184612542803671084317600408546717156005015334313375713864377855754817560373128522078655376108487571366035681366668415564637026210230283502458880020644582413888322342250471101864560673682221874116058608726318512708483886888510055025777421323140476807225515610631221038627302812013748325386154650053487610488183585444624674383022656414177865641752561360547650014323816810630612516305044130875005020682155746118620515510824011381336483230055736240617515782114136421470776807676177550611440828783508730863530282010014818346523102542402254343533717020615574330102605824801246413810766734634885064804232266577168180432013101552227557210004388766284770777140720537417511766844783610352100540465561472670402210344101034833057232758245852070808220236281154780236723733444338510055030034813013645110633822278754202404504474305304442022826642474758611854325461062827108274513731884735151671470110708621625273668440118637450311343658011165286425181511705680573603763858611232338138748827471818765582660347616152406781640034572316373318502664436248256388610405472702422727847078630487284570634783763255664813062772284201074250421764772350506225034112667030542041601271786677051531312620325053837440266847414403520403044642750774706158448131432481174806885811767382276161844554785364411520181504100002583416222125488777048842577754016462488816570026628641240306053064402487875682123300581177266887150250351422720810352735363571360412047125557581638632134517633267041181107371612011428567810862424320113575346462405201656833030612075070574141743722304186150136731753671023874218020486623525477274573238860508882702372084466443612576614251217346482015461575031656475447648164446558064265327221087840315351520861404032643314331454634368744412177612085062851156277203858782712224671513811154003783615573428532137350476005672484601566762361451235432358283216038622103627640346688507300538731375011328652186416634871704724853186608633528582681770888456527704482222545720317647262504353844552114021364748768687305224554458346645480073287524354541473248736417484063513406154213148630574248474761110166377122661312870342501307676062158428731727603762678058825258617028588762036573081836105802145740112745128772630145484137806001264003744684057052707415622314023265542551602653216334446480452065344401128466756817275513821864603228721706850751311443512600213471838788638584557230388665682183120086147780868372104654758703458732422306605012887857774238665848557856306556175462287001853080307504270FCB87B223D24AE5DB1890421C3FF1D59B84B19E24D143699191C7E9A464842206BBA247E8C6B27BA26E68AD5A71D0361CD5C74CE50C2CEF19131EF5466237FFEF7FE6B5FD198238E1CA0B10130C629CC9191F5786F5CD628A42256CB6FC7D7095688AF1BC84351A47B4B382EF61FD65C9EC226F42B0A197C6AD8F0B015D0B1C7E01428956A9BB2DE9A97E57566F8F56686A1F4680CECEA873B691CF8BD63AB7373BAE8095BA7763E50D6839D0035BBFB91BA60721798FB2C802C603A08A12405E0B520EA41438FEAEFA562DC7892F4589F8D2B965EE54973A72C8D335C626198806413310310E32EFE6B39B5CFB1D133ADE01BCE94216CF4CD8F8643031DB8C247B57321CA1EFBB853637D0C575214FC77A5A684D50ABFE4E971998E066E5024DA02768AEDE13E83F05154A9992948427AA98C874251AF569423538944FAD893FC656E9CED806A85D9C33671022529368E7EC70C9EE974301C08CBE6AC5E88E637795CB2A215FFAA08EDDE40ACFAEE2A40D505CF58A66966315A68982403D81BFA89E37C9E421DA588BA7E422AC7446A1E61C822299DFC34ECFABE5CB626B96C8EA6C93BDBD2D5BD70C5F8267A84E007A7115E5BE5F12032A37CAB05D541E3DEA51A832EDE8D349AFDD5E6FCFC8346E3D47CF17FEA875E385DB98AC2DBE8B4F80537310DD94CD0B625E99785DB049A01F54BA1F42ADFECAE2411D32B2F846C88A30C76EA0A38B271B6ACA8236E61EBB84A9DC49E5C5BEE7E7D8DA2C1A1A0A31450E08FABBB1B1F05AAE300D8CDE735B47BBDB05CCC0C05336BE451731B6B777BE5CBAF98535F7E08FFCD8A449E1D436A4F059901F56F0130BD15D7511645406BF313CA1F2202A4A86A1D047FD58A3E877F1D5A7975D16D67B323C6287B9CCEEE989EE844A93E7EFD3BD9D8316DA377DF0BB9E261A271D50CB70167C30D192DAADE960EEA335EEC52E52D9539E1F95D9EB65E548F166099ED882C3072536A6CAA0521A5AA7C6472A0C04F80DA205D52187707DF5C2F2EA25FEF00CA7BF0D3B7F81E319E61CA2CC5A525A27B56AABAE4D535E5EC242D811A24D74576BF4B8A72FA5FAEC1A283B61D60287E1E2EC8C6AB04565FD5CD64263494E8034163355B4584CEFA0B6640851AE123E98FBDA923FCA38E38B384E2B954414B364FB8B08756048B75C78531D4A51299C49DEA4B368C1982FEAD4AB1AA5235A4A17FB0646F04047BF08048A11CF8958B6834B7FD0031306A39C8AE68C35365197C1E5797FC473EB19454486FEBAAEC5C2EE92CCC3AF3C743087D2D564B7DE9E596F3124BE908F3045A751A7D7E37E6C8C1FEF332632D0BBE05136A44587F545F5FF52FB80BF2BF0BF4302FCFECFE08EC51F229D7AC28E1754261BCE7B1534F7D3BB08D01151EBEECD954C24E703EEA391426B701795D06938599AA7DDCF92E44569BFA9D912A8E894851E3D053B3AD4329B76A50C0784D42F37C5F9006AC2A9D5DE5183FA3C65ECDB6CF3167A47A8F5C59BDD79B7C240697E15972850274FE41AD84D90DCB341611E766D212DC763CF94C8C4194CCA91B210328E4A3374E29D248112BB668A392C20D87910376B5001F3FFBBEC3E008BF2F46F7407383A80DDA082BDB8FE925E4F12B3792270E5A46B8C57B6E5A4B95584EF380ED4993EC529FF2AA39DD6DFE88FDEB6EDA0E8DA79566B07D37AECC6437259518F97E6C8612B3C35703BFF992153E660E2E2077A05F265FB5121DD79F0A33BC38EC8308E2A984CD3D8AC609306F7793D7DE08D845A42128264E5C177774E35D587C96B247054221785DB38DDC6FDBF7BF6F664BD63014C0BF942A83916CBF2C428541EDA2BBCBFCF935DEFCB363E164AA512DD5FA795331400B9BD03CE3D72D910562C381FE931E8C379E3023733AB9186E5DEF31E9F6257FB84774CE2823D44FC142CBEB598A68FD3948371A5D0C0964C6E1215D89F658E5504AD093BC8602BAD236249D7EAFB6A1A07CA7C74DAC307A700F2F8140C1086B21F2E1519C1D4694932A1C18CBED0D0E29DEFC525297937085E2630DC62C0C050C4FF270872BE7BB522DD6991B596FC29211725D9960B16A52EA91781923C03B719D09D6E7106DC57055C19EF876E5EC2317E7E423C971454072019E28E65C81ED527AF189BDFCF521C923407554ACBF6945D185443DAC1A1A088A68B517D5D990E11030DE4F7509E87A77B37CF20A78E2CD4894173C32A327355116B71851444265606A0A9A6D9461CC5DD83B527E4DBD6AEE033D661C3DE8C18297E5D131DBC8F696E947C95C71772B6244744D061E14453B9FB11734802DBA6F8179B80DACFEB6BADFD14E0576736F8010C53287A3D3931879EF273BBFCDB5DE5B88AF51FD8A8C8F0A5894E225DFE873FCC03CB1C9B57825F11175C87D0878B9E6156B401B2FBE30036BFC7DB1000271B7FF5D63A8095075EFBD34EE73DE6014952D15BC30230702D87C9A96D5E9F1F0F9262596AA58B7E41AD9A09EADB944B63FD98B347D11BD5297C3BE2823859F2F35A4E54E13688909C31A83E7DECE4BDF31039C72BA54A1202D172A6B8A2CE96DEDCA5B24F7B942C14E133DAA8AB8CBD24C1F0BBEB12797672672E22CE6C21237B2797D8E54CC8FC76C43B4752966A3A40944E72D373F0D3E84F9A3301EAE9EDA35444B1E49E66118206A56EB46D48D20954A779A1E74E3E3B2BD403D46B3351011CB6F8A8672B2F3D990314755776CE3237F0A50E771205309C05D9A78D36888A83BAD78E86EDF36A88DC71C5F11568390D0B59202E29EE11ECB9F568963E81770839FF239AD03156CC071E8B7401595ECEE6234AC34B711703D68C67A2883BE9C18AB7F1A1B2E5C90A2323CDF1ED49850B83938192F628C9EF65B779395EE3734C7A901F7473886D712D215416816C3016CC28383D4787B46F689DCE111DA4DB8AC10E84F66A5C2BDA1B3FC977F6A0F732EDA4F69B97551A4B8B261D6887194D3AFE7F4B87FB3D41AC6DCDB8FD39BE50F2F382BAA4D19C7450AB3A1AC4C63CF930AAA517A15D5C0D549FE03220071D369223E51296ECBF80DCD79FBDFB8DF62904D5A36200F29CC47E80C8615EF1B78DBB26A1AA7A66E4D9A51C972AC9C94EAB99514B5ADAE6251E8AA30A5E587424E3B7BCC42EBE7333D9210972653F8118B83ABE1BF7E9EE9CDAC28997D144C34DEA65B59512C732927DBA8207D5691984721B7279AFCDDE06A6BD2680EBB9B2E3CFEE9A66D73D0C0DED653708B090B823065F9707849E3B37D4125CA693E742E023F058ADC95079BB00C56BE0D2F078182EFAB3072B0FD09767B8A13C2805A7591B5B2E12475B5C824DBEB157930AB389F915FCCEC8F48647EE4B66AB6B536C22DE3E5EE4ABB42F8E0009AF04554F128ACA3CCE403BB01FDB7B5E2A72B82911C1FD06523FF90192141C689ECCB0BE61B4C6D770629590218A4011A68B86FF50D23039C9BCD4361F6980A60EF88D1440D304C5B4B52D6EDC29112DC3A8AF28589E8F62948EDB6BE76646D596606B9E705FEE3F144A07BC9ED1D400C", - "message": "885A0BDD8DE74BC711690AA614DDA532F4D8C7EA2C27855A578E6361CAAE2C0BF7E773B4900A3293121A6E0DD610107A7A65BD6E11F619FC0E9CE7BF7B5DE18076E1B725572097B247D8E0462494F63F4EDFBEAC2FA2ECAE0CCAD428BD796CF26092A1CD505F593911ED10FDA426C7E3C5A439E850421318AE0785B05AA99F58D6856DEB78BBE488C70EEE42BB9AB5927B2ED25CD14377CD7E1A8834E82148002FCB985AB9431297010B2BC70F9132373C6DD2A2A9CF246FE0262E8B53E693F3D6FED3EDD1F2004ED17C2CF5B257F4ADA5DC1A7C151FFE03B96A4DB991E4132D01DE1F033ED81357EAE7C1A8D2DDD92DDFC06F671394D2F60212C6E449EA359324FED38C84D36D15432E11E7150015804F97A3C677382CD46AA4D7ACEE5686FBCED7A9E85D29C48386E69F40693D9ADABEB43BD0E5036ACDE631B54957F4FCE26F7A24B0DAD4348A6789CAE106130620ED2FA0EA38F575F28783BC92B32B0C51C8A6546F5D88095F9F73C65BF6F251A2C469746445C588C3EA8139E433D4FE2DE4C0D358B6CA8A6294E6AFC1B96074C068EF67B158F1129CFE0A3AE7EB9D454F357FBB6AB3B9922B1BCD55586187CD24692482782334AC9F2B861248F6A530E93E11488784DDE5EA678AE505903E231053308C1B8784607E063F4898A4FAB601D3E69685972155F63F09FD84B2B3DF741FB642ACA603D0D596E0A8DAD424F4640F98B96FB242C695DC331F5759F75EAF191CBD985EC5998D5648C85EB631295F61567C1163F990DC4FA1714091261E5F3E5F0BFE8455BB8BAA1D69421F15374E73B07E78579D0E251A41EE1A5043AABF8BE773EE7F9D0FDFCFD3AE711FAB1D3DBCC2843BE5A946B24D8B9B94358B5F598E88ED3D53F310F8EC63229D4F5BB1B6D524A5AF9C39477925C7E29095FC43F171FECDD061F362627121752C236B792F1B3190797CD0575C584F30B556811961904509C98BCDE8659D2280F495A0C9557D3811AF5ED4377BC7599E4959FF85F2150ACDECC1F7672DE1EE4DB44C1FB5F7998AB5DB742F6C5D32CBC0F2FBC954EAD6CC134B9762DF331386DECA316947884B9A13ADEA5CBE2956644FA12A7BB3BFB97E1D93A70191AC38A0373258C2C2816DEA6EAF880D69F45FBA4C290F18D34BB8368CF4EBB472BA499CBB54501EE3A28E5FB9FDC66CF64572094719BBDB48F3F488513B6550E127E8341C7E53DCFDA7D40805580BC7D30A72F244CCDB5AEF661B0F304EC5B7AB93B8C5C49A776838B7D52374AA41630224D616F310E499ECADCE93E78B94D3CA48B347BC0EECAA2066022965C807BEF9029BC5228F005EDB74D4B14498CE3AE13BEB7C693B669EE9F9A6F46FC00EC05E132BB6C6760FB5C51C8323ACD6A3C75A72E9738966D125B9613B3145C67B5E988187E85F29ADCBAF74E33A611FFF252AEBBAEB1EA641E6FC8BDF7341BE2AA857E443ACFBCEB2155D081ACB4CCDB098D57CEF6F6FD342DB2D83B6123E0AD3C93F300811B8D5A11A5A29BE60816F69B29D1D7E158869D860F6FB829DE80D3E1B699C3AB6804EB6549178D9473338D6AF209E1F7D263C667AE6895F6E2933923471F199581F8A51BD9AA452EEE4BFE95669ACD07B41B00C03F55A40D10B50F8E467BD071C8F405CF119612D32405BD5275A6BBF2217F9F1790D29997B7B6B1EC8D7924AB9E644C129CEE87433291A2C8ED6BC3C2A19D076B177EE6050692ADA8E95574D6CE9ABE49795D8F28EAB69676E7903A656FAB32025FE3465CBDB5701C177209D9189A5917C1337DE39F575E5DDB93CA76BEB52AF32E8D7127B28F7CE7312E803904721AB216E92A8A9E609FC10AF8DC2AACA14A97BB0E4B234C7000EBBE0C442F185946B7CE7728095CD60169B0BD97B36B3AE3855D98925B29D9294EF277509FCA407EA2BC47659026A8204D6964FC65BEF3531E9C1E6F970BF2FF24075EA17D136ADEAD2356B6CE498F93CD2F9E5E190D209D93E473FAA8ED92096315BF1FCA655FEBC78E09965C97478296B75D39056604D3271916DCFF225CB6B9A34E15DC164B2A68A3B42DE057A6BAC1732CF5945BBCA12B8B36159FB89F7BBBE9FE034218F5B3BCF184C207306E6D2EA6959EAE0890A7B6802EC1DA082BED65BB6E4EB4D5615701CB0E350363314A4D101DBBA605371A38B2D8A37FF78EBB369825388AAB7D3C623B93E512D96A9F339EC968B352759AF3E8FA3211C39295B0110E6DF264E90678C11E2B903AF322E4FA77028D3ECC44F6279D63B1E60D8067241015FC4F89BAA156A78FA77BB2914CAC281F4409C9C0370ABD7C1F8A5D1040B59752CC4FDF0D19CB0C56FEF34FA3A3BCEE1F064E360E86DC55DB5C9375BDADA672E72F664E3ACB2E6D8A08409C8CD60A1F95380AB6C3ACB6B91A8A9A3B775504979B8025ADB3422619BD11E2B54FE6D075881ACAC24532031CCD299060E4EB7F7CBD80836D4B823A5FFA4FE8C6B983D2AAEB8F16F6C1C2281EFD713FFDA22069A5D8AC491291CBF49F118C946D50F08E0D1732814E81581906A3153940114BEC8EBD49C73790F9ED7CCD985EDAD8DB3426B151398EBF16EFAFE3DA0C7F38B22760576D4885273F5E40B140557107FCE0BF8461F248BC43FBF5CEEE76EF3A9EBD230956C7B98AC898A399E5C2AB0CBE9E5AB9471DF5E530C72F26C34DBFE2F83683EB622F9647AA06A267D789736312C90C9E59D77122A88538FD0F53916AF08B236935CDC5BB3CB490C8309E6A79B43E7A54A8A07E1BAFB9B937EAC2FC3ACED30641F337919D2DB54EC7F320EC51CD13C00B9E603DF6DD2690C75AF3707B7C93E91CF0278D743A18B4E6974B424081042B5B4E78CEB7FFF67980BBCBA5E29BE61335616D65E86F0E746D183DFD46B75C9300D60C519FD95A8A661FFC82AE75DD149491F99D1414F1579008A8027A6C998D3E7A2BBFA07AB53EFE817AE9C6AE8D052AA859D0348B0D2C85BCCC4508490BE0F9B3213B8AF7CCEE722E28213187146C5DA05B765D83306FA5A6B76D69276D16A2BC60DB1ADAB5762EA76374EAB2D34D2A357C756FBEAD6A9E3C16307DEB95E5A302E414D43E91CA15BB24FAFDCE9BBBE735590F0D002986D13509ACA4CB3153A26143867EBA727334897589457EAF97E8BB0BBF3F4846E69952CF46B1C6539B446A799D668476E2E4984753E6C2E9A08BCB72F86685CE1BFEAA1AF59D671B7BDD6C5C2F2F3B536BB36234FD644590A4486CADCD4220F7909998C8C9E03A451995AB997767320D3988C5296E1657B4C7740B2FE270A11766E3B3512C64EC20ECC04B55191D04AF784F2E7E5997EB53EAC53DB611171564EAB4A68C16AA5C57F72EB1497A427A053A1C4707D58BDC1D7FD9FB88CCE34F9E19C59793124ECBBF56F3FA35A55B3DE64DFA9950B53F2A7257B8CAD259A35BF1546694A838C80FC37D0C36F00E23C63ABC553C18D4A404BE6DC05B120238BB8DF408697B95EA4B7A137E04B9ED9842B2DADD1B15215009BDD23A927442133171C6149840D6A117C77A5D68EE61D6E90044AD3543AA71A28C59401CADB1B5D78C5C6690D69887500020B596C3EC530DFEE8543A29AF9DD856EB30D836A1388D012155316FC5C1547EC6D4D182D88DBD2176CDE64EC708D19DC66697FCF616E4F2386F51A98474BCCE92F122812B9EBD832DCE4D863AC56082FEC5E4729FF76FE9560D219610EAFFC4442114279BC063AAD937E466003B0F59F572848448F0EFA728CE418F4996BB12345DC13A2F65F5735A2D738F9E98A7A79C6B2CDBFD3412156B339D9143BDD85CB782FEB7E29BC5224E71B85B165AEAB65F954D21F372952305B3D5F48843F5127889DA794F073CD98D205E825717C9313825D538D050E6920C4DBF2F6552429D041F62DF8C12EC24DE1D72DA049160B4D34B56DAE10931EB69569C2B3C0AF6FFFA5323C7DC9C7C8EF0C642023C4FE89878EB3A6C524CF037E74F7BF891ECFB102FAF29FD39D9900DA7A927D131192AD55F2E18272B16AF14505DA17C9A14282897731B672547C6810255730161508588BC161CBA0582933B164F44F06AA2531AAA8921C691E6EB6BE81DA9BE51C563955E0C1EFD3ED2A1C949BD4E00B3AE9EBC13C4C6C4E5E394CB034B9CB75BECE8644FF89EF95E76EF715E17AA26B1FEB774C5059B3A39A38DFD057D641E43FFE0F3E40FFF6B2363C1BF0EF07873D09A487769D0A73CD0CC644F53C25D2025EE71C69B7AC0FA6611557C427C069DF2E1BF629D9A0CB5C67C7EA4FA658C78D0042B059E6B658FFCE60166967DB94F716EB4D04B3D2450F40031F10ACDD07777FBE9FBBB77FCB7C1FA9FC1EAF0C5F86D7962DAED0474BA0FE68D9B23277A9CA7FC676C6616B8E439A1D4BFF72437819B5518756A7873EF584012646C3659A6BA86E62272614D85EECD5350E3CD0A125AE9C17CCE25239E1EE9CDB39CA7B18CF2C88CF146826B6CC1E6AA8E1692C915F3BF1C1DB34C6F37883CB4EDCE0F7C995B69E3ACE30DC166F784C93D6CBBCAC3C79BC319310CE6E665700F17F962F18B240739D15690B1B6C85D1AAA32D4A79744AE50CF9A90A0954B4A4D94C499B4123EFC0204431F72285B5DA9E1922230A304D3A1BD852087261B7CF0D8B90D14623EBCDC6387BC6AF65BE5F011B6BC123C1306A1E8FBF2DF0B6F89B0AE05DE0E4B7F50ADA46E53A9B6BCADA0643BE6BFDC2B06A6C75883C2DC613AC7216317A40C4A2C0866983D32C9CE0A6CCEDF403626BB23B5B9DA586777C735E1911D77B1196C8FA4721D6B0FE0B0811FC00B9A1242CBD4A92431008BEE9E15D1982DE34AEDCA6858F193020B6447F6BA6637059DA8DE0F8468657B81C571378418CF57D77AE756C59932E052503D1EAFB2D60D26123EA0EFF55E324490019BD1E5624872F7B980736D27CC59BE04E29ABA1B8351531CE651424F810B5AB3ED558CAE5732D7C8BB46275033089FE32F86599D088D5728803C95103BA2FFB7C390205C4CED8B3C27B298EA79D3597B717DE280B32E541DA1D98BD27EFF7B443091339C74016112071CBB6C9B08F20C1F040FB6E73048F73CA45DBE0F9258D32F23E36BEF788F8134D9B10C2580B20F878B64C7D2AA68140D13050382A5FBC818E0FD4D08799783DBE2515F44561A31A7D053FB5A61C41C60EBE576FC5B63863905523FC269EFDB86CF2996B6D90FE28A016EE63C24CD6B20CFA6E8551E42F57918284438A44316C6802017CCE4DC07C43A954F50ECAE61598AE41570A66BA6D6E68B92E0D42D2F50BFC2DA8616E604E5178EB0C529EC04AB092855C3A3D6995AB62EB2F9B12F52EB5A693CE1497A71E0A7B9474FB65D05A9755400271879C9FCB413F088D6ACAE6ECE67122F8589FF194F6E4D6DC35D7EB6B789966F9E21527C98C27B4893C15EE5271A9D2503CD231BB3AE587AF652BF2F5C944A2591C5796B9C25ECB8A5B2B7A7E933C0827CDB4B01BF3825078CFEA2857B10FB4B693828E7AD19F04ECEE243D8A5E56998D83A4057DFB36DBABD16759C74AB9AF99B6D8D42CCA8CCCD232AB51CE2D22E029B1731060A86B8F68AF58069D7236983FF36BAD3E7F4A009404AEE98A9E8A03D804CCFEE3F8A20464175477CA20D0801B36EF5931FAE4F5AF560902ADCFA6BC2623276DF352CE2F4C9CA82375FA569E075BB9305AB127FF72BF50B127EFA10C3AC97221BED8DCD5664A0A58FA57B4000731F24EDCE0869945E545CF27357957F5A27A29FA5ECFF9A99611E14A6CE5B88E78E6A14697AEB4F36D7F8ED1866B782B55C5DF0F4378EDD238E58B947A06C573175593ADA5ACBA818A6D734BA1328F21A65B513158D0E40B9346F251303E60E1CB3004158D1E87A6F638E0278481182B37BBD3DBE791A31B6B20CB2C52B1B96A94F8CDBA5DC7DD793638C2FCEC4F2B5F734403E9A9F5D999EA61DC6A98BEDEB934CC76B0E18C703AA57CD1C02A8E7D478A63EA306BEE360BA8AE46CD0183F607F9ED8B6997B6C35D756ED8DF018248312FDEED8EC5D8A6C0360E66A4E9E5A97D5CD24372C0AD2678F2B00812AE6C1A0F5330B3AB0153DA3C5F4C17BD2FB60E7E80874C1B929B62E389EEE2A014060D4DCC965AF8642A05A9EED50D2390B067D5511D18BCBAE6A5AD2918D506FCC9126D70A86E968B5F9C9943070237488CFB5FF5DE6926737DF63A2CE55801C348B0F00D56AF8C0F5CB3BA448C39B020D2938119994EACB91FC31F347DF33E1AE1267CB7220ADC0D14F8438A2346379C2AB81F2472E2EAC467131733BDA007A03EDE8BC4D6DBD9F1B8F4FB831314CD36F6DCD585937CF96CEA5292FBFC9502107B579FF07C2E79003DB2A16C4ED417FA0F13C8BFB182F7DDCF08F250DB16A45A604A572B0EDC4ABF9C86088A5AC874DDA26E12A0EF635AD282ADCDC7ED1686453DFB35C3B1BA6821B4B7220B55798B9CCFE066615CE255960D09E677FEFE76BE915E04E56544BD09D06F8344F968DC6825CBC664D518A441E19B076FC3389137FC1B7332E2B06895443B7A002336311579A9B08F3673DA0590E696CED901444A70A67B2A7D5512D65BFCD7AF1E34277769E171088301DE7846F088F487C4921BEB98354BAE9AF6EAB2349114EB21F618DB1D926C1D2FE3A5F229C57340C40AEC11C2D0144D0394FC4D8E3866A7D0A10B64C8B992B0A4DDBCAD824E43974378EA9A38E58C2C5AE194AF4310FBEC9028416C5CB7B8AFA524F74FFD6F2E98443F5E8924F6CF110E671B816837D59B2DB91CB1E687D6A2020F9108F69B947662FDE718AC28A6ACDA27F43359BBBE362CEEEA91E691952C580AB2CAA3AA39039A753C276E0289174B02427CB42EADB4D935B2309E2FEC9F25561A3540F1AF1DA4A8620770986CDE1E89C1D330BB827240F2BC53C7DEABFC7DADBFDAE0A7A10CD6733736A1EEA69688790E4A2C694CE530FBDDE1FE8690DCDF03F5172FF4582DD3ED3D7DA0B36E1ED3BBD957BA8B0072C4EECF39D574FA13F0D7E9100C7A5262D0C9D52DDC11D4FF34B255F99981B4C9140291815629F6A91A198E74B3A3D128B572D86F54157455702662CB1D152C7F4C9CB4DEA207D5A938294251674426977E730EC6010065C8E034882BD32FD35C6AF6B8D93A509CC339D96FB9DD558AF95235FBF17197760475EE2E3FCA0E83A8E31FA7F13D78CC7964805E7705DBB70F73533A56D8B77C12E8F65107C90143975175959465FD4D8C8CD3A8EEA95EFBC7F6F8400EA5D51E79B40CEF8B04594D0C6F08D500A2AD08B462E02CF630311ED7815661170DB39F277538426EB2B06CB8C9D820C8367D1D57104EC145FC93B1F77BA13B711216E58FD00C7DC00518022425288AE1299A79BDC7732DF3427033F3F84887B4D491E153BA4A63AF3AE5CB3D4104B53087AA4003561002F36A9FDA33BCB8A5D0564329DA58128B6A9DCFCDCA6698921DA4EFAC9E19DEF7FE6C3A6646B4007F08AF31D6D322591F34485AE14E0F6F2DD0E58E343BC055022D174B347846D4C47F1DDC39946978ABD82B6DF31C0B0F4AA0B2AC1A797F9DE5E8C6404BCE324BA13C77ED5D590FE07D0007B4D8A63EC96D621966C3E7103B6C7A364975E678B38D041331E67972640776942BB4EC181C323C26C481BF4FB56E5D67CFBE1757112BBCA0F0C2700694269B26129C7F99D44AF560CDF7A4702EF5D6A2EC0E99002E8930AA4EC06211930A1E68F2ED448B104A7568BF46E141D60B6153D40310B38F8E1457278FE349B2B4A7AE397A7B8F48AAA5FDC1288E43E05839320A14C63AB858E26E7D8C35B64737904D89C19A103D6B689A3DC90C72FC92E35D452B8143023070D48BB9FBB045E3C6CE9A8BD5C4B67F5D8B58C96A282D6E27783D7B990E052BD95E86508F9BF7C064A8F239E0240A20D8DF3A876EDC8FF6241B54F270A98CB8077AAFE0E58E5E9813C6A5F91F52897B6AAD2426C60DA5883E6BDFEE330A8609A2118B699F75CEFD0501951464CD62040987FCF6B22ECA92E44F55B38C6499A8DA0AC78256930367A4D75491A089D8941F6C53CCB260136A93E1FCA3DD72D55A92359E3D6282705D54AF57C6985E74E0F2332661BF2BDD78472904C7F05817FC9DEDEF156ACAC746CE12F890D85A9398A9EDFBF46E7348814A080729C83E704C4030202CF61ECDEE2795D507AC28814F53CD0660A5572CBE1AE53338B8EFDCA31AA5B95AA9E765AF4DA04C9B3162677E41C018A5E18AF2F98ACA145CCD1B8F7431076A14A7C20F6C72E8EB9751B7892E41015447630EAA84B9601CB954D89739389D52BB91A97F96087CB38B0EAB59A78468346555C71284C2FBBD275818E92673FA42AB5E0D977667A90F75926C80768775D23DFE0B337B48B0C8281FE63F18F245F88F21E11C56A5337188425A348B24DD0E9830DB6B6C89648C7A633CA9D83251D0C6F7A453950D02196A77BCDFD52B2C65C9BF7269C30CEF3475762959BE9DE944212F5FB789A6CD0A9A9E775BBDDA03A4BCFB47C177730026AE2EFA62189DB8E2D37AB9D8CFE9611180E9DCC3329E636FD942F6767FBCBFDB082FA0EBB84DF37662AAFA204ADDE6B372C77D364F08564F19B2B00C131A8CCE9A04B5B69CD3D8FE1F2CCC89EE7D228A4E0A910C8B5AE0BDE53DBE904B13A32F33E99D6C6735BD03D409902FC63C8DD843FC1FB749C0B738701DEB5AD7AC07AF5B93C57B5565866EC1DBCD429250DBD197953D53C3FEC2F965F3D2EEA47EDEA14B237FA10D256E804FE3B50CBA1C2B420B8FD9B64E52D2DB35D2A1C4E6D65176E7875EBE93E661714C8BA696DAF7CB06B7B8C4F6F5C629AAE113876F96BA0CF6798F038622E3FBCF86CF7C77FDB4EEBD42387FF2CCCB06EA0D81A18EB5E740C803A34BC8B40E3E36AB90C1FCB0372B83A13D56D6830F99C458B8946119A66047CB2DAF293890FA990F020265905FA2A2E3BB34152F0BF5B2CC8359AFA74D38ADF6525C53D90E3FD65386E279C26548B2673BAF5253579A2780883777674E1FF17BC5CBD8110ADD920E886CCA33763B04FAC0FDC63FB472C22B6D5EB6A14E5FC05016EFFE6A42726502EE07C619C695DE3FD9C5C60E70076AC3361B846FDF80164E8690C8557BDDC0860C37471F35F847F2CD962164AD46E1DF44794802F971393526FC120D88ACD6FA29745551E7AF3D7E1E7EE018B63C4B999D510251D8E9FA61882ECF73776571AEAED7A1F9E07F3046CB20ECF4D2C163F56F8A72F95B85D2CA6D35D117F6089E0A73B3DA1A32BA23104A5DD7AAB468975945C57C166FE46289F1D3B403907BA4A2CAA05D691BA9BBEBA0E2DEBE0EC49E213861929BAB69AAD01DF6C3EEA6C3F3291BE56E5289D0BAD86027801AB57F7FB5C25AC683A4C08839F3E739D6811C1320FD933D8E79607CFFE4375B33A39DB757CD450AB9E4F1BC5974E8B306D09F0FBC5B23B86CD64DFACC14AB74611AFC22A6ED097691D86E44B60014DC742D90AA59987630C544A46143D6E22828A7BD6E505CE1967AF8A8328CE9FD113791D1AF3CD31C1E884D7E8784846F390BFB2DB3124C6D45DDCD7D75B7FE7E44CC29E5B310EE23555BCFBABDA1BE64F86E60310A2DC93B1D44E19D602877EE", - "rnd": "4E7A017C15039DC20051D2960E5E1559CC27ED46877CB98116199A0F4105FE32", - "signature": "B865B00B2118DBB00B701C6645655E8ACFA84EA792B448642E1832C3707C87CF09FBE772F1D4385BFBE5E6CFBBE26C10ED6EB865C887F86939439A9BF768BF039D73E3EA83BDF18503B5D1B39179A827B0D7805F98428BD87CEA6B06960C78B4B586FB0D5EDA9FAAC0256E38823562A307966117005AA42F1B6554A04875F85C2E3FAFA652471D4E98065482FC7DF49B2C40D0E7B98238DFBE853D16BF9992BB08C19259F9B575EA7A4A80093A64A92671857A508920D60FF6FBF38341C5590105633A426D602DAC064DD7A7F11A60215C35B7B9C00E9D8463988CF472CD6ACFB7F722B8C4C62702607A674880ACB3D6C6253E71175A05B392CAB4BB14CE86A598ABC788D0FF4D82775E4EA0FC36363CD0E97B78A6AE4DA8E98CA612772D56B582F82C0709BEAE46673BDD8042865CFA95BF5338CFEA606A6EF3163846AE83B25E5F5BD31C83F136729A8EA6274F994FA9045FA8A90FF854B871CF82E2B701E8F4AC04FE9E28491B9A25FF263E2CF75499E009FD0229FBF7E5E46044344B07D72214A9ACB4FF6102ABC1262BC2E1CD2491607AE7AAECF4C35175CFA4383AA86AF1E62ED06387CC594836467F41DFCA8FA0CA71280BFB1C2560C8995536F842747045591453745F260382E3DA50793FD7CA7627185DBDCEDDF69B2D3E151C7F97288A382A92B050F791F9587D77C64D8B5D40AA199D4966BE2D524F9610F2FA02ED23176369DB939350DA601EA66770952E0F23EDA68A73756EFF610E8D6A9F49345658544282453B5E73A322A03267C969B50734F2ECD4EC9055760D928610E94E0B1628D6AF1B27AB13829F7F8EF50D9E2996FC64B06AC8946114766DAD8DFFE634F47E9D8569966C6F6968218C5B8633611BF42B4FC0E78D0C029EAB85F22F16171980CC65F28445A11A083AA02977C2E8886ED270672E512AE89C6A26FCAD1EC72B9ECFA5A5EFC70FF0BAB28F114F4DA8170FE8B63C2E11BE7A35466E979A127EC0D20323D502730ABCE640A2441CDDABA326D6783D0192DBA9E93FE507C6A73767BE56E2776576EFEFF1CA179D83343E38C6A9C2FE725DDE807D21725E730872E2AB3D901161F455BCAD23A8433A413151FD221714310E4D0B6A1E1B2CACA499EEE805A164F291D5075E6B65A79C2BCAD917B122FE1AC4FBB410211BA0A1997A31307C01F0FED3B3143D28340FACF09337C4EF047480A290AE02B2F7D87B8C29A0AEAE2E92C9C5447D66C55C1D1E25885D1037FB5FCC80154F1D23B4F27B5BAC89BE1C363CFF8EA75873AC3F6333E86C53ECA55DBED5E1F1126B1278C729C9A84C4A1B7F15119301C80BE22FE9BEBA175945B2612B66DDCEDF9A2A4D5F24F902BBA68DA75D95972E28D6CB7017CA51ED5873AB03DD2E926C15642C9D6E6427FCE80FC38B34FEB3C15513A687C35B94EB83E4AB3E1876679270F5A98F18A65F57417655FDA9994E8FCC616C6C6006104026D6CD7AA0563D510725760005F5FD39E759249029F03D9F0067103FA0452114DF2440E8C6DB65E23956EB1BEEB2C34E5B20AC316A03A95436666268C3D8228F62EB5667B3B6BB857DD0737B69051E9F26EE023671CEADFACAF9497F1ADE587A693EEFFBFCD550EC208C235691E8E366D965B62BEC16A661CD5DE28793220D66F2645505B852412FAE7B9D9829BF615F7CBD59A7BC1D034E6A25529CFB486AF201DEB7EA95BA708A3159171674345309DB8150E67EBB30A7FF80CAC9AB1392500A83E63BBF7C42EB9453C2C9ACDA02BE538234AAA7DB5A7F588FC91B90EE2477F2B61CD1062A7EF1E6E4DC54B36D0E19933E981CB763A9E107E01DA9420F82CA793592A47C4B977FF2C88498DA95C43D232F42AF99480BF0A4F8B7C4949D1AE1D4FA8E1D1A8CD0F9ED00DA595EFD2B766F0B79D4490DB928EC44B5030A74CA42811A5B5AE522C7764DDFD9FD92F006E94B35A7EF0142DA7178C2F53074D07451B15565A9E0C57EA1B94C88EAE741B1F501C4D370727DAD2765F795AD414635800EC1949D037139DE26AFCF933D9A09C127FC6B36E518C6DE9492BA70827B681C2D18A40123B6C5F61737CB9DC6AA9CE17D168EBBDDD63C0760193C974933DB474AA89AF30E162938F6DB7865DE231F86169C9E2A302FC41F1BE5F36C5583FCD91E21CB8A6757D30A4BACDB67E7A61B0C8E217E0CCBF50EA642CDE3FC74C7F9FFBDA9A1E684BBC9A8F7CD3F1BD0DB63DDDF4EA479C235652C5DCBCA7BDD4E2F33E87172C18B5FF39099408D272FD0FB0D6A23B14300DFC64C02743E523608E973613DCAAC9D1D14B3A6240EC2F2293991F6906AE36C0469F30911348EC12DDBA6C3CA19BC695FCD16E5AEF2AD7C73251570B5D049A6C3A52FA3FC9ED54E54973AE789B0BFD6F8CC2644A9F85ACE0678D89EFC12B611C3DFAE3F945034B899BE99A732889F17D208DCD7EE959D1AC761DBA4864C14B0A35E4C7BBDA096FB8AB3226926C89E7CDA929EF130C692C92659E6F4652BF2156361C77DBEEF5A0623A06704990E198A13673054324BBBAA643692F243D67C1B4F95B928ACF1686F60C14487D6DD7F8801EF20939E03A1CA7D7432DCF595F1E9EDF2B29357A1D4C7DA33512C451A7C6604382D90C33079D95738E47189D8549E43D294E73D1CA7487B50D0ED7CC6F96BEEA76CCEB96D3792004EB3E5491635A67F6FFA1F1DF6A1F2FDEE77841780AE0809D292ED7B00F42D80911909B51C9A3AE54B7A6D7D29D2000522D4F876E25C0D6A1577221885FD3074F33BDCD96CDE80404A37E1609F26CFBE24A1FBF9762A1A2332E7A2D82DF9D20F083ADB353533590BB1F9543349369E21ECF594E27807A56350D62384DEADA789BE92F012C1F8A72D8BE079F8D7BD040BC5F22336116D6F37DBFBD2C744C3AE78ECB4E05A55B3FCC31B8CA6DBE8957244908F4ED1D3466C9E00C6CCAEFC954D857C655F7471E38088CF1EB8BEED8DC4FB3E36F3B8421F37318DA235369E923DD8EAA7A2290E14BF591E1D9827303BF3576975CC3AB34999701950ABF67FF6551ACA2DA07350E09CEE07EC37266BAAA534FD7B1A924EE7361AEB35CC5A5C067F77CE523357739DEC2D280CC9BF069EA77C36F90BC67F0F6624652D302BD77F07D357C84BC30CA35BAAAFEAF3A39E9ED463CD828BBC5DEFE62A4D5B95131798D36766049E7171E6BD44156B2976E4620199EBF42E14290DBF8A02304AE70D25429ED70CAD30C6A349F9900C465B77675F0BE9A9FEFAC85F19F73509F7B56D513217BEE6C3BE4A9A33DAC690B7A76F979ED580E5029E58D645344D61711907691FAFFF9FDE9713A1DF470E8BD6D0754008597DFB7474F248F4231B5E184E2D2DC540D0904F9569C4DAFB394B127D221E9A685B682E4723B96ABFF7E25679DD7A72F95F206B2956EE04114C1634041454B521AA6A4640E4F1787C50F34DBC57347C6ABD9BEF03807DAB200F77876F93FB242082C77EFB432DC6D4E9278C66A85A58C8D89AA8505F3A3D0BC34FCE94E00D16CB20E0F51A136E28A642B2B1301D5628CDF34EA73E74047DA586D91ADF07BC2C59B1916D9BA2D072E7A5564A27561F65CD907BB75A5125751BD9D4C7198AB03D382261CFD966EDF5B8F586FF981AB7FB67ED2552D92F84DC96892C52CF5FA0EAD0B33898FCD75084CFA5E9538B4438B57DD8AD0AE5357829BF9F6B2CBB979DD364232BA8A471E3F12F61C968D206D04E870399CCB183B694613CE9E07D13AFCFE4A6427F628FFC10F1084D1DFC0F3711BED7F18046AFFA136599AEF9D013A7C73AD2C19B5AB8C308134940330D1F935D10493E4F9034C5EAF724FFF3C595F71F139AE00CCD619339E6AFD53EA9D8C48F640509452AEB12C551581C5520E92974C71001F3A456B414FE9C102FF8BFB59C6EBBE652E7ACA7CE416E00660A2F4671B88F45892668CD49DFCBCDD666C6A78EB3E472EFBAA66D7AB7E9D9B260B58277202AFAE3CBF5305030C61967A8B8FAFEB6DAB6B6BF079040D85B154839CD990F3A28D22EBAAC6DA3F85388F0868770F507D299C4CADDD88CEB0096B462A37B7931B285B06139F2BC1D31C30C7F709A6374C6CBD3930D437F8085877298E16E9A592E6CA89EC2C072FE26E8AF8961CA0D15CCB0BA10B89D772C6C28CC705B1F5D68D4C81F0F67F53E5C70504B3212E61ACEB8325F1DC5FB0777AD854595040D947A1FDD057414A59A66F493BEF2A95BCDABC782F7E74A1C906B9ABD93DD4156DAA50F5D572CBA07074B9133E61B0E259E36BFCA21CEC682334D424F2E71C2E76F16F6B7301CA1A8E3E7B171DD9F901F011D0ABD2C4A22845CBF610724C40D23DBC628B127CB7E06F83C42F9512F21C58098082F5658D7E0DAC4240CE8FA942357A6D8E2C5CC16705557C4522D94CE5B228E6C3D8E749DFD47C74211419F6A0AF61697B124C46C98F86251E9676D392B76195F41F4825187FFAA87E34687C0C9BBB5ACA0D15654C22C599E78F9A6BACBE2458AC1E5DFC38191DBDB9EE29CB9445F5D6D838D2D3E722F98FCFA5FC0F0034A42196748247035AE373427ABD692B8B452C9D1F05CACFAB92DCEF224E353F42D658DBF273FAF62E027BE12CB40A499AF47195F68697F8CD21E4AA1A43D5A626F78878EA0C0F32C60C3CEDDED7CAFE00B729DBAC6EE00000000000000000000000000000000000000070B151B1E24" - }, - { - "tcId": 32, - "deferred": false, - "sk": "4B356EFACC4DD5A922AC920BCA97F614627E70D1113DD58FF8C2F55BF24E5AA3C148CC1CB67675F8F457D4ED920DAD8FB854A9AD09E0FE616A744E23D45E45BC5F8DF4FC0381D4A9D865F759F361A009261ADCEFE7C78DEE80E9B627556EB0B2352E6CE6D987BF73992FD092ACBFE6EE351C11082BE380B493BF321A8660027C05406536203032064231151715182716178673800600414418753148363223335420506127526046225030837316057147673868431724275585752248574253132523661010113085668648184277243067835844644801472070571816587386538544161307432778468131713726265087852658757520752313386347407367074584715861575437767878784535868162650573626135024544671607758477723276642840617755017232854033881315383541785622582806374126132752386086537128012000006548208558044862038626414617684320185004256010175047834771806343054777236287272288070858351333171828314873073217615222178255157881745605453287677136880126542180682522303646784670165365614232065362622032121443746660431140775616276352778167338778572820745007018081612114217566256162176650383572678730485851846658833475786787627118474343618375106870718513203463202187076400355377420412561315150785602328512513537262476324148263708705066606868613545823024158862863312016615830177318237468303422784337108343323175086560282712130213318840052774863888054426410546016340228664104685633035758301124326328755320220158455542883065558153634250023534112375185822557662164351675037453732745222134302783706411666065328751186018100511082853188845033583064431766262308530338783051271081615651457548706023836352868635277885570062748746102156161572384840401736057383334868700226647166360541035647828414733184137122425131560805374615838266572430558476580347572071818141160203660757565400034630624662777201412780361444884243612073152714246402267040420805378541711607716742836032052184848387218032463528086003648564616302784075458684786765467345830562386685702325714181765807351626662300642620568720287748524572416877642174833767010431224238302727288834036560623776765556356785886176565807352133544230771433787752261284727254333782147456835854230275258403707034351022828370144403341847144331064562541227001302877425200614836035388324363476585318468403614688467756833452756082774147282532276125162487361558658507561248747261455227658666231867004316685537134558815533087021453310846615433671736808160628536387605020657854750656336873450615464274830778238662550823366321065332288085087043086620127047235686307808214412516122623130701485680658160852165655665863725428476222121068785268177715682485328656703800540305854823573462621421641657781256653275155256648884570067845576657106113881567345533330614133108642811580348825560033156758030853667423854563546131124131862104085640740007355035364736837670760716867574382367051118688317326131487372805133321238013367004750640065763550608518184276773048385454574853204436270376835570081651568710683312165064732472516310430817783610268652176544704123372045303324240477433636684677547505637853216267372883736123134675833200443143220272468346287300460007326137141675202506337308855876770215832823772388874047305232865258076583872617214175267774137603113420063824541363042111881288657464167D9A4CE96EC1448F468F64B84F7CF38545C7A594F3C11D228395945D4A7E60179CBCC844674B6DA539DAC64869C68A416121A5AA39CFF632A92CCB5F0C1EB05CEB4008C5AFD414A3BC378284C9C22F3590B4B6C52C5435F6928C062EE208CB43031A051FEBB9551BA103A7A7BDAC3945EBB5D5C50E0E59E38E947DF9EFB3C276DF187CC5FAEB510111D6D05B0DBE8505D8A9D5998B40E7E22A90FE76125B82A4D2A7F270A9816B0C26A597637640028F578C42B9FCA8A6844B3C7784F7A4B7A2BB398648D82DC6604D445505DCAB3122D56BA4AA7A09033F0C1EF29F72D0650F510035D10929494EEA11F5C3EC9145AFE6B211EFBC2132F48AED852649821C7951D4F3292B4352B1FC8761DB9DD4C6DF2112AA49AF973467B01C3DA8129BEADF295CB91AC6951FA1352B3919128A970A3F64155BD77055C40E7E5247FCB6A7FFE72CDF204622C6AA112AAC8F7EBA4FCF9FD622BB08B05B3F9B487FA180FAB5B5CF08D49902E444AFC1A63A5EF431A8B9F64BB7C07A820ED3CB3FB658FC3B2E1BA0DF4C9405A6B6E7068DE5C4B95ED1C724121894674D9F0F8618C862ADD2A5F948DE5AE9041EEC61E7D1F392796DA1989133B4284604CCF2050B9C300325555695CE36187402DB3F6C86F05D3CE4C9B84A3B8B76153BE20193F4C915AF00FA557246AA2EE6C4152B596C56BDE1B92C84D401FCC3B7D5D3DC6A676A89045EA7B4C8E82E46E7E01F827136731BEC6A76C241C53FE4C2FFF44DF0D9D2C2323C4C1F587A181EE48A8ECCC6232FFCEE2784CA6D4C8F2AC24AEF2182DCD499B3173EACAD1A82BBE7436DB83E53F27725E2DD17FA3826878958FFBD0C41E5B6383A53DA19A26A5FD878D81E940C8FA1D601FC906E1DBE1674AC6760C1F8319A04161890FB0B6BA5774FD0E8CE7CBF7A03790A5D242C8161E62EFA781869CD1A9DFD0169ED7B85A0DC06974C2CD581614AC3995E0DC1B6C018ECFEB7FDAED8B1CB955F673CF44EB4B815180B1E1D191D205B3BFFB50B8DF52AEC2B5CA1328289D69D2F0E904397007851B75600B88D41DF116874E9205AC05BFEA7366953CAFD8861AA1FB882583C65664F296AC66C6A905A0F37010F48E9B499068295792AA79D4E1C3B3744BE71434C6C2428085392D63F184909324628FED618EFF1152F1CA7410567DD85269C9AC089330C3CE1F6ADCB04EAB6C70B3E347A8A8B8D9944354A97C2AEFF52857B9D32BFF6823476FE1A19C92A5E943355270570803AE28D838D086D178305AC620BECED241F0D0301BB11466F02E39D20B3DBA7838F1CFCC11E597A2895BAB4DB9442E0B22D49F0C26496D54C9A2072160B239EC0CF4AE8092BA4DD9A287857F5C1F5613D53F1058E1EC47A899AFEECAE9BDF07E3ED87D75A51B3573B952953489419BC885A678E10347E38865F2F80B9CFCC37B5C594D1FCEEDAAB09F2C111227BCE5201EB71AF5006A48D6C22E1A6DA3578EF697FD523896E67F291CBDFFBA3FED3B8CF85D60621D279B1E7D7D6BBE5A019B10BCF6715689985F4E87DA68F70412280A2886402F0C46E9ED1A790B9DE5C305E9B7220494C71BD046DF8812BCD87CF6F9062AA95631ED01CC2B2E86E0609B5F5741BFAAE62E16D7102D32C4D3B5CB74E915AFF992E81AFCC8042BC61B4C3DE2CF5E7B408660EA5A2135874AA7A9DB451AFD0B9A9B84E87062BFAE6A018C49543F170BF56A1E5A152E76C348F1E77C2D34C49A98A14324433859E0FCF6D64C115BF5A598C8A5DE444785CC40776AC1579CFC66E604637C6B33EF44D50C3C36DE75903352F60C4CC14732858E7980516987C8447FA634A31EA9B1629C3B161A0E110007E716BC57DCCE43524AF8E68164F153FFC7A4678588FA0EB80E53C8A552ABA108A7AD6A8DC68F551283CF95C7D8264812E8F91C9B058FC6DAA4EAB93B8D36ABB5B7588F30B2234A273AC2E04348FC6C40057A77B02F8AED5E3514746B26603C92BFD8FC5B7B224C8698D6DBD5E2BC7CC9913A7C6EC7407CE445A1441769E0103FE231CAFDFC24CD405D7DD150C07AFDC8F341C543071100457363143C1DAD7AAED5BFAFBC5382C0B724720F024B2361A75D1BC9BB390F68E9FA51DB9B3262F72A7B2504E4E97BC44775CF558BA2EACFEA9ED471D605F1FB74112D029A2F566A38826589193FA5EAFBF0A324184A8B10B3E67717C1035967D235184E95F9A9B9F54F3B0E9AC649318D8B640CAFF68EE0C1A63D741B2ED218BEB9DCF27C093FD1BC9AE842AFF1E22B35D0A84AEE3547B7AF1C283A265095C724FFF4205DDBD002EEEB8AD8BD84AB386CE6EF6FD63B1023670C251D686C0AA580BD763F6327025D4EC5530D77779358E116F77008FA0B2FD7602F4C0A2EDFFE4D11446B5FDE23386D77DEF764B26910BA4EAA2CE7B14894EFDE2A8FC3FDF7F61BC0EE1D6DB0A487D2041A49A25088BD7714BA64DD391A0B40EB348D5AD698842D8B357465C2B8E340A58D7E77C8979977D31B9F202E8EDE1A7940363CD49FADC9F320C6DE154AAE1B4C89A4A75E3E83EFD1DE458486F485D2E4E636330D5B3D845C8C1356CA6F4A3933BC007A6A8DA66601AFD67A408B11C80FEC1C7B9ECC4D269CBED39926152B6175198452AFE94F041C79BBFFFF1EE3A57C6BBA2B7892351F64A0D8ADE062594721C48126982AD36F992F993689959930F6222E661A9E4F4754F6046DF5DBC243C20571FD3B39EEB750CBAE08E26F9C35400FD945DFD00D8B8195D2D5FF65067A3E497B99888C1B3F5FED24B911B65378BFFABF5F215E00A5AE612E92E0F9FCDC8E0CF8E35E92D0CD7BFC1875F023E3BFDAA0A89DD0EA278ED9789FEB52A7EFE4241950A9CF740C2B9D0B8A046535B11D6C560D50DAC6F2FDEFF20F3B7075EF8EDD6F98E66FB225BC6EA792D2431ED63358A36D31BCF9799EA404D7DC1FFB45B01FCE1B8DCF09D2B9602FB62497581BBCD770DF7EDCAEEA31859DD94A1514DE00019423F6BB8B817195A4F2F8BCEEE02E414324FA419BF8AAF53CA03053F605746177BFA7BE7A7F2A4F61AA312A617B109F184DBDFBFF42CFC278E39974CC16D881EF507B2941FEACE11FCE5903BAD36E70B3F9AA91996251291F9CBA4477D93D1B2932B755B7A64BF080D4E50575713DC40C3026A9242DC3C7826551E126171BD7554B2BFB03715ACEECE88243BB476BF8D486ACA0F8F3C385D90B22E09F962FE4115E5A087AB17DE80F8016C86C7DFE7CFF349C12737622735A0CEB001C9A3714F95400FF64DE0B37F7CC0B34A511CAD367411034C75940625813B30654BBE491C5367F1D24DB2F469034FEE26FA3007C0FD2BBD81398885A199D741A47EC37B295C975B40180E2F5CA98D5918512A5B466ABDAC5DF30A3423F08B679AB7BB8378A20FD771F1DADC2ED644FF904CF7DF0BA013F44E928DCCD446B7D04CA9AF3830A842965A6B901682F531F003B06FF3FE017BC32FF6421066A7437818F51C1CF74D0DAC72ECC54812C0D08BAA9DFB0D61547910D2BDF58276E50394B3FDCA9D2FCDDC84BEBDA", - "message": "552444A7A40EFA95CF1A2DFF0256EAF7E47F0A5BDCAC6CC95E2B0D1830B0D5C01D818278882947B025613A53901A3B3D986E4B95B9F2B6D89DCCD0EBBF1FF7096EBE1A3D9383652F14C34E928409962E17CD3827B9437E37BF15FCED595C7474F3BE5D2649520AD19504D8382975ED99BA29473493EAC7CBE463909D54FB34EDFB770771A350585E01CC12800E639B4FB250E98E4970EBFB300076A2B10B9DA885E79BC4C4A0EAA3B791A47FE6F7CC5B0641A8F1A4BAD5963CCC118DF410F0A54BF878DBBEA1915B428D481F0628C7418E6BB2A2B0E9A1FEC35A6556FB2C3100B1ABA8AD395BC6B8E459DB45B998F1A2220DBA2511A150F4A6B236855A75B41DD202B8F7CBE94F4990C44301DD47B1FADFC0CBB04A030269A3739788A4577D285BB88C6A92D062EEBD0529140AF3673D3BDBDCD79D10D65F6C4AC82DD70C4EB9D84EF54484ECD5BB9769C021626FB46BA06E95F310557750FD1057688CFA587E268B83BE5F08ACD1CEEC2C1460D470C3B354272F8B75455B0D544D30BEA4A8C47E20F5D23267C0C89E206955B184A44A41150C35BED69F1C5EB5261FD04AF23742DD99051FB1D8BF8AE6062A92A41133741E7BB0DCEBA2182615840B264AAFA54BFBF9C2B81968BCC5E82061EFC531E3C14C6A7FF03D333CA0521E876E9EA7AA47F6EFC487D280DF9D6BED0F27426B459CF2A9CEF5F69B3AC0819539F80627B2F848A35B0ACED56B1A5F768C77F4BD358C178E95509FF2EB51FA935C3D9B3E14F76503E578F85C2B88FA6DE7E1ED3453DED3D5371B1F18FB2D1C5367FA5D6588475879AC479B08614EA9B5699B1F07A5618DBAA324866C71124B808159ABD53D630907E99296E19876F9BD87902A47AE9DAD12CF9BC9924E410C4329347F5A0C314593E2CDA552745D566DB6D4AE7D5574B501B4B70683F7ECD58FE50A3FEFE4AF92360D7FBC639F61CAD61FC17E23D1F14D6824640A9E6753139F3145B43E34762E35F87F6EA2DDD965BF566ED70B8B06D49949736512E58AB57C22993D04212145F6CC0A2AA58B96DB8976F0291DD036386E49D660796CFA3F2325FA39B963DBAF808CA741C4751E6FA9EDD20C25AEDB775B52A0E0D1A1D19E0DCE9FC4FB3FC95C8315D7F947928B0F2AA7014A0B070EC3EAF57982BF5FC45885EFD34F844916AB38DE143371C56CD5D4604096FA568EE01E240D12EB013A974848BFB4675F706A3DFCA19AE82CE7F8076483FAF70DA144A33AAFF4B454A7D978FC6058BE7339575A37A39B9B321BCD19C26692DAB294A8A17D28A0B7CAA1E1973DCC03F901BA6DF65EAC8BB643C2CBDB66BF56353E164400595A78E12FB607C25ADE5DFEF633D9189BD1F1F79502FCF509D06DD1643B759ACAFA2DDAD209C750A321B93FB7D5ABD491BB70B4B10FFB87344AEAF706ABE4131D15D3A1086AD30C85A30690893040F4C7747C494E93AF9E9C3644A5154CF3AAB1436FF7CA73490E04BF4761AD97BD79F00044FA5595568D0C9E145178D7CBCD05B42747AA30F50B6ED2DEA520BC3CB188BD7CE119F85ED98A1A27BF7EB7E0E264681EEA4845366CE25EF2B46FE0A7345D930959B93035239E708CE09CD76A61864D86C8F19A45911636124F1CFD4917FAC496E8186730EB300F848DD64DA3F4AD0FB1B9F8A2F9F47C21C1EA1B653323FE632E40CB177038067E6AEB8EC1B2D8212EB44F20487A2904620089A037699BFB124F8925C422625ED20172CCFE567DAA612285002E354EED5404EE79CF0B08F136E9E43F5D3943B3B57E5696677D09507A58AB3F5AD1E5F78FE75F08D617DC2897DA4A08A7F7030D61DFD2132CDDD4B40DC491AC349FCB80F28C376147A593889183733C3216150C04E0DF2652D783C648A7AD699F6EAC0B177C1FBC0307ED410525EBB0A31D5BBA2D311AE0ABE3FD11483A6835E699AD7C3317598DD1423D1EC08A094FE9CB01B1DC94024DEBDF22710AF0FE4126AECB0F74D47BA4CE384F2F7E05C0CE540702477C8FE3B2A82250AFBC28C62072BC2480585D56EB127D41C047AA6F3C8FDF9AD01170FE4A2F246DCBBF8E220FF996DAEE414FADEED713B87BDA12D716ED103EDF38BFB64CAB65D0064C2EFECAF91BD31EC05C4CCDBED28FC7BDA9B0002BB9F9BE591C2BCCB49B4B8D1D6CC167DB75248A1302D0E7CE98FB638C6BE7F6F3EE720D95DA401EA6E62190441B66BA361C33A59FA4EE9DC78F989A3AD1B3D52C8FA98426F7830E1BC42F01A09777673235353F4014859C72990519E85CE2D5E8C128BB8298F06B5B73B925416137CDA981F61CA79B97544B2B1C1663DE82D5E97063D76420E82952DCDAD869D0C88FB069F86B31CC464C998DDC6AC14248354C23F609F1E736A1EC27E9EDE730E22795DE59AC14CEF8DF7A54BF9BC2D4503CCAC2094BF85D6E09150C3929ACC0A058289F3F127F12F7556EEE675FF14CAE255195AE88890BC6D4F1D8BF0B2367CEE1B4B0E771FAA2D2794A9257BF325FE2D5185D907BA25408101039B4518C41E7C6AE9ABED321C783E21151DD921BD70EA5294B4D0B2D7C7B728308387D84E3CA2725729640050C206668BEF71EC78C1948B6393456690C3944DBC3DF412DEBA0086FA51F3420C4DF5EA1B71866C15636634A656924EC39CC44A7B705E46AC11D8124B974FEF063AE1F5D20903651E0FCE0A84A034B6DC4C2E4A30F98CFE43C7F31ED6947BD37DEAD4DB1D6E9AE1E70534086E921E9F30BEB6B77ACDC9DB160F647CEAEA6A42182CAC934F7575830399080AD492FDA834DDF940E684001A7E245082F19E7AEF00089B6C4A537D39FF9D3B8AD847FF6682561B55C96A5AA398E6E6BCAF75104F13E042D3F9800E4033C2AB3127990154D0FFF811ED8ECF52DC94EC4893B10CAACE6313D9ACD0668A67F8E498BD2738753F8A7DBC1FEEA237B9FFA4501A7649286B6868601E30DF4EBC18009FB6894280E4F6BEECD9681336D3321A8C2F12926888AB220FB82D7BEE67471423158569D47BD362BCEEC1C39D78109D8A2F4695C04B1615205DCE6457A39DAE9CF58B4760BC39C2C4E2ED8E9DCB8FCE1C851F8C05E419BE6CF6260E4E98459A7D5F8F1D463D12A9AB4C89E9F9830B466C0CFCAD3E0B0E2C12C1748365E51F4ECCD711A901EBDB19225D9704103C8FE1798BE35DE712618EF89109114644F742509A16797484C24F5AD3BFAF9A06BD1BE2CAC86D276FD8E350862DC42B35FCE1FD211ACD4862BC41E90ABDBFF5B205266524574326F4736B676EEC20C6AB5A1893B551AF2D12403A0DFF519ADB30423CA6E47F855E80975ED037EF88ACBA414AA598F047EEBC0AD4B9A5D3CE5343A346E788DB07F60FA183FD405B37F6F9EFD1CDA4EE7E8739C581FC6585001494AF2B6FE6828C9C0EEF94177771A43E074A3EA5E862F27F132D6A157716E593C90B7EF4993F412885CA20A75D91A493DAF9034B18C9100393B49F27AB12663F96E1A92C158F370A95576F08769633B2551537DD467C8562278483D039E67FF4D2973D8143F9B902D649C79E2B37981784D90E2B1738D6D472ED15DE921D546CE59A400EBDB88B53404F061D40F84F3D5315ED8E43659F12A5FB49DF5D0951EC6708967A74FB3D72674190A64B8CCFCCBC72D7F3F9BB758C14C509EB3AF2A4E0F5519A00B50BB03B19E749B8F1A3D7BFE674C1F1EA574DF1195B8635364759B10A925A233CA6318E74C24B47BC9EE79AFA303284A3AF734F84D6B6F69A24FD552F0647E93ED1E0190975A16DA6C2D7D052105A23AC78B7427B88F52CCF4AF4262FE21A846F39AB4463EF0D6AF1FED879F376318E4B2D47398AA712EA1653F816D0A35C7F4CCB4693AE9550F3B241F99E731B70B751C4C98C61575FA5DD59E9C4D2BFACFB8D5B95743D935314B9B890EA5CF0440018DAD67D9EE9DAE24F742701AA1AAC432C568EC71B9992284268764C399F29F45B93DF7F02C9421C12B10DCFBBA57D3FF4DA7986E49F93F859D946E105FD934D43E2A7274AA11D95DD7356BF81EBF189597C39DCEC7DD6F2BB2A20206F2F8F79609FABBD2EC6AC2EA755F4CB925F1279F9A610956703ECEF9FC5EDF6DFB4FBD24EE91EA455FB2F6A0190D0C96D76C8A910FFD55B01DE528F4401B85E20BDCF781F62425B083369DF011263C98320F158241EA49F2D1B34814426E7CFDA307C755A53EA5ECEFCC7C58F0276366FA6B62BC1928E9D2319CC09B11147D008F8E17758C360394CB2EAB2BBD7B8F914E5A29BF6F0B8CBA7C538BA9D3701B9AF73AD380B8B2C0232AD1C8A5E36626BD46930B2CAF753B630FCF284C5A2E6593D38E91E338D6255A86D834AA6F9C8AA4A0E6D73904EE29891E0C56DD0D46FC5F7B37416D0BC6A31DCC0F1BD8FE597066AD3593568DE1CB15FC9DAADCF3F16AA1B13304DF0238DA343C651ACF042526C9E84ACF78E8AD927F1744A5E5FAE083E7DF1FFE252358B17DAE7B042061E259A282A5BC76D849C0B0592738B4B588AF41857BB15DC8A96FA5C1A8C2A85DECA64FF85A6EAA210863907CC7CF92FE73257024620C083152FDF050DE7F3BDA3D7728B93627DAF8D4A39283E2B0C59ABF8441E49CE6D5155F862035667FC59BE7732C8D695183B5090D0B372167B7723257D0A41B234D6A04920BBADCE305DFDBB4EB9A22F8F18F295C07EA50D9A76B40FC196C5FA14FD30D4F855BE1AC1110F75B11C9D3F86F4CC42F466BF65BB98AEDED66EEF4FD3BEC7DBF929144B6BF6FC8FD460A639558A7EB0D6A9A8ECD92A0E1CA11A11CDA0D3E66745E2B9F5A592ECAD43888FC9A54FF8E82C8023BA161DCEA31EC9EE48943008542A5B895E629B30FA53CEFA97CD1CD68F62B5FDA93800B2CF311C80E69D407C3E204CE67BDF6B9E2A395BCAD8ED0FBFAFA07B99107E38A100D758B9F0C57A561EA7D7978CCC770AFBC67BE1D9118A27EB1D5650E36F1415C7C9A2F2DA5754A61B24DC6304EADCF5F16EF82483F07AB3CA3301556B858AFB0ADC8259B27869E3EB0FE243C5545AFC72B1E66E5A2EF25A23656B444B4FA5FD7891B75FE74FB7D7CD4253865A9E1925774CA51182F38CC23C79A97A4037364E863CE1EE89D23917C36951E6E12EC3DCDFBB7B718E3C2A5A80312220578B312F2934A52E7AF8D0F2BE234DBD4E1CF36E9A00F581566F833B5B5CD75AC4F73B1116AFF3E49D6DDDD53CD1D1016785B7679BF717929C57DF2D29328C58CE1DC49F34A532F5749", - "rnd": "85B786FE1E9AE0BA921D7E2C8E9045C8A6CA848DE6C6BC102F803D9BC0F8D534", - "signature": "9F1672E5E5E66EC6ADA46E71A9BC54AA7034BBF390BABA58DA6EF4422B22E73BED2C9C23B7E0F1CB9E54101557657901C0CBFAB5C4C73EF99628F9935630D2C85FD7550B3A622CD8314F865E11F402243DED0D2139CCF7FE451F1187F20E507325D7D93B83983EF5DB632548C895F44EF52726CA94A5E4E9B75E6443CFEF71D8497C04B59B8BBD58E621D42A565C0E2A09A26A886084BF56E61806EF228C4F079ED4CEEF9140E402AEFB9479ABDF7D88627CEAB9680BE9FDABA05E3186EE77E475C7366C89D3005A7D648314C773562F6C325185F1C5016A8C0B7D7B6E1F128328E0C70CE4EBE1123733E49F53ABAADA49B49935E567725C3A72DA5BA7A4DFB9F9C78B7723517DD56B012AD2F8115D6C404BDD14BCC9DD47018B5FBAC37AE86AE570643378DE4181066A5717337EB6D60B274A18E3285DD9E8D205B810042010D71749D737C8E74C43A2E64B0C0448FC290B2BCF8E19829E3DC045FB7486204792FE01B62DC839D59C9632DB89DB22B5F2B74F74170C2AB3240C96EE941F2635E93666DCCDCD7827D076F31F5ABA8DC0E07F9F1D02A348B42A15060A85550E4408C5D7C700D300D6747070753166CDD8D954A96BE7265326C20C34B3FA36518394BAD7BEB1D55213CAFD1A6133CF72AEFCD059CECFC36751EFE5CDC2F72A1EA96D90DF6E70F5E8D041C49977585B287A30673F33F44A635B8C4219C1539646B3781F6D555F578F37056C28E46647942B3C2EF7E7631AFC72EAACB40E46F574A7EF4179DF325C95A67034BDCE30A2C98CFCBBEE4C3AA5C021A0D08C3B05066BE382828C96ED893959E3380228AF2CF40A4971CBAC6E8C4A37BE304A6B18F37D28CE795143EDBBE5B047AFADA65A02F026261BC3B0C765E208B5EF0F57F83830D70D12F1B5F8BC94AB6608FC3EAA7917828270CA76E4FE43189F594990A186D03A929B2CF8DEF4E3CB5D567B3ED72037BB64B99DFE7062D6AB6FE0728304621D16C3DE1E914D405E8A29B76303D47948A1AD68A750CF62A41253764D0E19A1C8442B2B5F7EC5E64400C73884355F782D7222A4C939D32CAA4914CCBE9005A4B2322BE091F554998076379BD4135EC6F09FC22979AED087EA6D86C095EC5672351496D3BD6220C66F58D4BADB28FC087A5466DE7470F758B382DC447B4F5B922E8B0A7758CB8A40AF89C3BE4A7143F0CADE071386FD7249863DB3BDDA416BCB9AB8A9CC2B65ACD18B8D777C98E9A74698F42E8E9F367608E183BC4783F0C0AFF65B5EAEB1482EC2E70AA787A0C75897F931B1BB95FFB6713928AE1BAA99A0BF86EB391BF1B0883EDD309AA59664C895605979A8BA477F602F389250FBD527237B41048961FBA25422CC63618E392BD8CF8A1431C84C87B641D4BBA32C0817E30BCEE665C047B766A5FB4DE382F2AB7AE35E8660A81A5680D9BFF4AC410F42E8036B611CAD4DBCA7BDA54668D14F7BC44AF5027DCB057088C18C1A6F01E69157332B069FF4954BA2B122AD34ED90C8131B7A39672F2301A7CEE4C1723A9D49431E866D14A2C2B0A9EFBFA55A2A90430AB5B6D843392030214F23F87A69750EBF1FAF1A4D71EFC0E08E351AAEA9596980BE023D81335C76549100905A42415C11A6370A10C140451CD1CC131CCDF82B579BD29EB90801462329E95398A714DD8A21C06B5F05C2D1297B99DDDA113538C7A4BB7AC605CB94D6AC1036EE7D0C4261A4C13C81CC846664CCCDC013F594A1366F3955DF422B9E7E765214E438BF416AF13596521A4FFF4A018AB668E62BDFB3A5D76AC628065426849C45B30EAFBD0E37E393B7AB0C72F7C8652B60BE494EDE04D76559853D13A0E1B1FE0113BAE4711906F4145640CD68559BCD02D9E59F9AA51F105CA33D523F3CE83C2DFFF356AEF1CDA87D31B02924C874EE5621AC026D5BBF2474904111E772088A669332E8A5B76DC56A29E94AAA31E89AC38FE39B72EE3AD5D58DD088D4894C5D99C0CBDDF52B5BF783C509F1C7FB62E64D085E90A284F905D6302D60CFC454CBD28062A91A2B7E21A34C9638BEBA4575DD14F5AE084DCCB220A67496238D0C96D8C2BB1D4F9C99F4C859D35D5773CC72944E661AF31126F03270A99A5EB50E4B7B3AB75ABE629B250D0D09D02F4DAD8C58C51B84ED5D0A8401E12B1141F93E9FAD606194F21865DB3FA109692294581EBB9C3DDA1C800A6B75FAE6C0CA584ED5058E1FD905C3BD84CAE476D6B35BB55559A7CF057A58DB96D3CEDA7D9D537B9296C3AF25D41B1162653B922463A5E6F68B70050DDD8338143CAC4D2EE4068D12211B46FCEBC8EA0FDDA3F1CA12504522699FBF5868158B4E54D12A002866FB631DA6CEA0ACAF44DA55B0F2066A50AC81E676974E5B2A7A1E36A9637F1B20B7EDE190D0D250C5904DBA5A44FAC3313BF040A4988E02EE466A3564DA06129B93C4ABA9E34D322BC820DF2FD8A831A01D7AF52EE34F96A846692A9B47029A7EF4FE0585940B5B57BF3D33456B0D9A09EB762968951A53BF7E709C34FCA1791FF9A4D48A189CE48E2DFC4077478DFF02F575DA342CCBBB5A2A5D2E34515A263329683B49D2F19B3DDE67505E57C37397D7A19060BE71C41FBF9CB8FC3055C0329BD1E52DDB52B413684412B73648B7DD9D9AEFFB8C96896754050F22DA2400EAB963310B16D905EC10D6E4ECBC847A1DE3BCB478DE4537D41B9D018282ABA9DBFDD9508F16E55AFB3C24D530B61B6A364CF15EDA2328931EEE988D1FDF47AE1C4DDBAA9BF55DEDE2CBCCC118D95D05CF6B330B113A85B9492311359AB9F39E9E3E0D04CC2409978243B3A2641B13668B918B238CD42B1283468931BDC315601D283383AAFF6C9D271456C1950991959027B9E2DA8319714FC32445489268264D3362F4941079B5BC76CDE0412441468C88F7D83CFDA1EFC1856889FE0FE3EFA82CB4D6ED0632592095E3A18FD3F251459DA833E98BFBD9C2E2C813537B3BD5AF53B90C8A00D8029FEAAAC825C2C56163D57302B1A9F04DF73F5D7A85B7E4F8ED80A397B57DACFB0DFCECB1CA9E43132F1C96A14DFBF520B5D39DF85F8B9865D04C22BB6242E42C6D52C09ABF3DB1F114FC21CC444C9A532D61AB1B97C3D629C82920DC306F3FB8966C0F9305988F6D8BFDBD30F7737E4FD18C854B7F15CBB2EAF63F276290CE2E55FBE8F16919AB7842DC724F687BB779A2720EED9813BAFC7B237197F848ADCB3ECDFB951B856A97FFCE6AE8BA17D9B01920C30BF859EA4D465FB43D7EB43CD1C98106B75745E99F5D4F8A43E7AAB8AE4B6BB995DEB4B608BA92746ADF0C731D51AF1BC82FB06F60993792C109A13029E6E64D2C5587D1603101E0B71575E97A753CC265918376EB6FB9F5872F970AD8D7D020DF5542275456185DA9E744931E856D909F8BF056B27EFA16C65C63E48578C5C4A572B7EB2AB716814D81D149AC510DEFB7ECA501AAECEF031192BA47607E6A6D05D5B14CF5D8ED2A447780DA119E04A0F4749A5050D8EB79153BB83EA7726BD56FCE4EB4861BEBA0752D84C6243ABB85443059685A191BA7953ACB492BA4F9881BAB0F074A2677A7A8F9602AFF6F669F9CBB5546EB503A90AAF6FF29673B459B85473BF15BB18E27AA12615D54819DC2C5A431D59D428D1FC5083D8D1BF5BF3948ED5AED666E5F9167761988B2281FC2DB479A18F10DA9E6EBE10D39C911D5698D406B40EBA33CE2A747ACBBB40C20A33F717328B769916853541C7A7EBE77D1F959155B421D81BAF624FC845B355DA3AC2A24FBE4442E9804D1B2E2CFBA405DDE9FE23FAA3C3676C7FF8310A26A157A0BA94A95B9B010B591D6D20881695B055F72E923DD4D0619A5576B776D8B08FA784E6DA6E7F05278EF9AEAE6F21E2F549FEDBA9AF660F5E4E18400ED68F44F8EA99E2B27ED0BD477DEE84C610B44ED9391CA0DEAF57EFAC1CE73CF6A902C52FE193EF10DEB85A83F85E9383626C870EA0DD02E6FBC8CBEB374B35B89BDFE5BD56EF38070F0DC3AC9E1EDEAFCCCE86B9A93434A40D416DD0770549C879A6B21E9C05EEB0959E4AA99B673DFCEA9C4CD7C1FD896119DD4E7111301C758D2DD0808148E9AB6F052820E4F979B17FA7088E4B1FE0609D31899C149DFAA6F8328F38FED27701F0B756545EE90CD01AD11D3CBF4F85003A238335719235A5EAAA07663A209AEA2940C5F97635D204D1BA25FC622F985749923B700C400F4ED0759C590E77098591495E67E3AD5651E75339B4E62E8939DE526ABF8763847D6A99684AC2768835168DC314A9D0011C9564AC68BD5D6BAA7A229744473924031FA2C0062B63CCC023A4071553C76FBA2E95765F938EA499DCF04428EFD8D663F17703BDED8F11F074B5580BAB6D1A2B7C2C95C5711F24E6C55C1ACD2941B8AEB1952E19A13E709E314A2F91887E86A0236EAA958F100663A380CE6CBE51FFB2072F43EFF740541E406D043202D599ED84AE02F6A633DFA64EAA07218EAC7341B9F78B798477490E7D48FDBB1A4C7EA726B83158AC38520CDF3C375D44A983BBE84F08DA704DEF77A13E12E8F66354C7059FB064A63F556A94C145D161428453CBCA1FBF7BF7BCCEFD38A62842654C51AE2E6C0455C699AED1A75A4A7C00637515E90A4F1820E144DA76D859DA0BD00000000000000000000000000000000000000000000000000000000050A1112161B" - }, - { - "tcId": 33, - "deferred": false, - "sk": "7EE364807699DCC1B171EF7697AFCED47FA74C3CC62D4B31508EAB28B90107793070FFD9F6E4E291BB243BE3661BC9F10334479CF94774A0B2D675A73F5A4C5C075C9F7C5A1F3AD42C153C56FA4A0096A890599864ECF44FC624C5575190918DB25642ED0EF9365EA49A5029632118C25BC353706E19F434A8583BD9ACBD0178626601147662345815030478008075046508171453260236220048153835224142604887325381776704830327507654380330128270618302451660516244765741333130207313070867858507807615254770386856715356623153328254581510857670100338338686141455250877738467188887704720311330203443015486446845343178655717730001428303223328155126584302773635010182256823046347814368858354730260230366711132523132716425153604515350680254864267436045112488377013036752038266554881058615402702657132780142432558642687434253820320032625645616776664083467506808211330653258107106213685334576103762716781245634321500128817253316451130051671528140362504105881488821713800164607146755065760688160543718621280743848732865852361852678157240211185687334353142717336354856016556473555578538417875751725466400024472312366688150488313121146007075716200007543526658340838881844006842700380382834232164542533472368224663537845745583636860433041070136228234481082077622376620678303368354216702542236670423402146372033505166601564428731623280705832823840136715073314816446241024176301575660048145120002242205718584228161013056607171377283255048262750850470087823837566285237075677233111022786313266784264321756335042421018820142531537353876518327210142277368465045855620866345617148743510018587426055818361571771053546622747133880437506658800400650817630436845112035816557630731546347117666513114417878770806254317511355201412145708548274724223150662816375874674851136332818333128174125154886078744742041625344432056425844222146208617200344287485004528111731188210487761766531482710535114800375747226862172487445171767667343186738688770045607534423146814375745432858668588748588332230370718052424475505322657107224600116465087540243388272487388701300685464725060407631800010613288320137323600144156250620850600477468054146361047633736613384462871441060082280463885576440432605015573754765012538621135881787407501877658803558125662486844400022067141233122102411543275811304821687313488860712450456454001801541234272253552652434765676387646006677870715616345358670165803013031582207274773730634201754666740831773660418654874702240274475845567372635401346060747328622168870375260246247320060702436233653027566060646450257842042375205074664540708417681110785088274158666332216417622424863545485016433075815726043564810555761228231522762511451204451556864471566704511735785231715383542260410661531411210057514300825237321725212750487324046447443840450620273151357084571004013511177711381564442344141535447627261186303185871874205786881032782676020684387284222185037741614587614416625522070185831673532116061357246375475106587508107430740086076578283038120584722042318120441123375152344277185544807736712803347603368270841110223567487831516463256057743365018152751800783617504346275728047461447333167282520736423316276657786546632410750632726720403830616534533830701282386323333546C9DF2CD332FA871D86F93144FEA2AE57FA2990BCAC09486D2B22D7DF3E9A7325982FB8029BA0D7A3D4FA0ED9519FE9290CDC25F027B18C0A3FE9634F387A474E1963B8E03405892AC99BD13751C23717091F8CA86BA14A48E9C0DC4FC03EC919A30B42D1A713A3A36AF3DD4D1129A8DE229512366769B6207D0AF0F8A4FEC06AD053BBA0427A70172A0FDF762AC47FDFCA39F1E1487EB78B1E32A088D80E67AB460A2EF90B32F3644A040F44B7A015772954280DA3330079F6FC3D7AD06EB3EA99BD7D9ED0449F319532C81BD279706884A02CDAACBAFD9F795EFB6D4BDCAF2254CAAFC1982AA2006C4C9184BE762B8EEF1028EFAF9611BEEA88D42815718FD2518D0169B27E272F83DB8867AFC94CD48FD0F23ACF3A33C0007B434806DD4D17E395B6C8210680279A6CF25837CA1E02C18DC616F36965D7D35787003B86D69FC2F40403AA8D708E6D6B4F2D793DBDABBCDD6B1936ACDAB8B7E55C6A5276BC52FE931778CBD25EBA6DF7C3768F470530B360991FE2EBF08DD240AA47282648274B1FE2887A57036A45584E65A48E95D6A8DC80710EA79510208D2F5350EBD14093EDEAE1ECA343E8371274986287ABB067844E42F27019E3C5DED895B3CCDE36E1742CB82B5EE2AA67762E64F0023CE9A5F25A10D9678FCF53F053E2BE39839AEF21D4424BA244883EA47C27C95F849F29B6831B0313EBFC44935451E55060FFAFA92487EC348AEA470E07879C7C429919268AD7A75F4F3704CEFD875A77304C488833FA75AE023D5E0FCDF98FD85693F7D75CB0B4DEC7628343D58F24310832B6314F54544804312E2E72C0DFB46A670DDBDDE9AC09FC1B09EE131ED6D961711F87D919DCA30732F3CEE0595B4B13B3C8D22B195F00E2C989D27912451B42D3D5C3CB69F4C41115D00EDFF07295DB204B7630AC71E637A7AEDFF8D143C70B1A06C4B8EE578656FF954586883A557D418CA2F6E561907AA5D47A590CCB6C2DC9D3F928F341646F64DBE0139E1E2E10734A0DF4807955E8E270D9D6352519778AC9C3CC53245234853AC8DD461AC8F5A22728B3CD59789AEC8FB62076A8B637CCC46FED8C711472A1D1D45F4F4527C29267FDD816532BE1A9F9E8CB5B1FCD5B50B7E8A5F76B1A14EDE1DAAA046B67C4D8DD9A9AA7906B4B28A36E9CBF7E788A6B2056BE60779BDDE51A5E7915A50D8A3390DDE787AB78EA9A1DCE3A52339641AC0AF8737B3B338B14D253DC27AF803AC6D80DC314E4EBEBB767111479A6B882883A4EC2E2EAF286836712B2E449C9EB0E0B2798A75378C3AF26538803BDF2815B4CD6FE1E6F0D8D2DA72E3DFB92C17B8545CC37B1CF59325A9CD4BDEAE2854EC073693F4B500F2076333A1B900BCDED21853FA4D1FBC054BE37442ABF9AEDFE5165A6C01F7FBA84A8590BB5E4940890318CCBCEF319037E3C3EB0A422E4C50F179C6EB52338E0AFAA4D417D2885CA7AECA724C226374AC4A2A003913CD8A677BDBB45310D1311BF815293D8CF9A39900E8D1F6B151602DD709D385FF7D15FDFDBC1BC7C2E1DFCE0B5F9A447749D5EEFEF9FCA66DCC8E06E667251B55AAD86086F0DADEE1A0BD5504A0E107E7E0CE722AB6D69D7D6030DFCB6E95B28FC69EA5DADD5FB222F2CF4A38ABBD89EA88CC895AD9658D2062C32903B8ADA50C119637A0FE2FDCC3A98B10D5338134663AF375911E19C4209A0FB6AF7BFA380D148136208C2C39E0E3BFBAFAA0922165C4317AE9B7499BB8B775DDE37B9D2F67EA1DCDDBCFA4941D19738EF8E4DA1E67E6DE5EE0B5B191FB2583FE408825F8F024F696743F5F46CF8AA6A48551C92F75B6CFAB147C95F99B1EA3555F29F094F477B0BE91AEFB6A3987CC8B16118729C7ED1EC0AD39C186A9BEBEF82D001AD9AA335798687939B17034109D133D71F13FC513AEA33F732C510B474B3B5948A0AE4D8DD9D376EC0469CFEDDC13C663E089F8AAD8B0CCF5D9549F31339824C62753AB409AE438D54E807E37F7A74FD22C230CB844DF307BE133ED6530C470EF5207FACFF513A952BE80BA568FDF36C48F9E4D39A945DC48836A631D2F61ADB4957991AFC25684E5257F446901B915FA4E55BA8BB747C0198AC5DAFE8871408AAA5ECD140E7E58AD300596167F4DCAB543AC3119713A189CB8A4CDAAFF4E9DF83F78800A8D91BCBD76A5F387F17FC479ECB08964479AB14C0AB549977FB3F5858F6E9DE8B56A57151652A57B58D11A0317A6C3DA517F5A7F8E71CD950DC883BBFD517AFCFA75559A468E3BEBFF51EC1E59B1934AFE8C4F580019DC4373FD99D550D0620C98034EB54532CA3C5B3D3FFA4EC3263698DD34131F2BE2D0F8F2608C7EF6BFB32F1024962FA3A0A590FACA14A750329596C0D6A657D66A9015EE599BDDD2F301F77AAC32A7C562C2D3DA7474772388376E61272F3B70CF4977F28FE8642011C3D2A732E515596D3EAE27AAEB469BB1C287E4523720A0C92332A6F4BF6CA622E9682ABB61B5736DFED9F189EE094A7DDF92E029A55E4A27954CFCFD078B3FAE61CAEF824148517AC8DBA4C2DABE002F8A02DB2F642850EC455F2FC9F199097D172DD9AF098F2B6449C64219B212AF1D097DA737C3F5F483145148876FF4E9867F29C51CE1D9C724A788BF7E3AD0B6D6D1F43DEC58D7A1807B35B5F4B68B98DB7528775556380471DDB56A43B6BE6A85384DC72013413960BCB2168C5AC1F71462F972A6714055DC7C88D53BA9717DAD6A9C3D8D2F41364F6C12C08725FE600075E3820A7D4C01B13BD61324621077163D079EAD107C59A159116C24B3D327F655864D9E0E2F52FDB1360D687BD1A67EB0032CCDEA0AAF903DCBFA68A8C1D6656B7D00052738493D46FB12ED66D54BAE27EE728ECEDDA2F91C64A76E5618469EC9C2BCC038BB33979FC9241358B934A6FE9B23FEAED172F629202C88BDE5397916052616B5B9D4DD27B1BF1E70D92B6F608447AB3A7DCED2C05D5483475599B57685AA6CC7EBD786F9CBE404E340A59A5650FAED4BC83B27636703D27B88BEA09F007B38DFCCD4DA9119E0C48C66CEACB8D50CFA97A35309410BC948ADBA130E74A4A1958E29C6996778E062CFB9DCAA1B773F5AC14DBFDABC4F771998318EE23C67DC81C822CF6C8997E715D5B28F2D2391302EEC9B726974738B13029FBBDC2CFA54F20315F2FE241913A56066CEEC51E294E7A2D4D32A196714086B344D660C43C8ECE4516F2A2B2017E3E2CECFCF6AA5C0D15CE52A273C604909B9B736C73151FDB7081639E7DE33A5C1FE066290E6F43FEB4CBAD3F02D8A7B45679A77460829536A76A07E0C42753181FCC054946198497B1331C8DD2D903D75647CC2401B493B47D36D73A65168BE33E9EF03FAF53D8310890822C61B59FC421B9D3DF406F2E122BA8064C7718246410197891310BE633309D1BEDDD727755BC16986A871F2EEB9BACD463EE948581647EAC75CD912611A7B0F572FC67074C4D3EA066CCE7C932FE982D08224BF0B1C60AEFA9E89B897FC87FD0046A9EDF1306A024AF1E2C232", - "message": "47E8F6B19DE86B50E02FD0A43DA2661688E2523DBF67060812CC4AC61F45608F68ED30DAD053751DBE35667A37149D1677C8DF109A937078C3C70512062A8547A908B9DAB8DEDE68F2ECD02FDFC9CF17DF50F0A58C0A9721C8E9B8AFBC680A8F644644062C7D67686D6C1A32B539627C76C17B10B9E98EED0FE55820464CD40D1F8568414645D95A60AA8F1AF7A7072009FFFB90752915CD888A4C05D7C712FC8612D9BC596C7B7151F139CEB716775BEA2FE759485B1FF942C2ADC1B62B4B9A7946316E02F150F15944EB95225790364C023023618C43B781DCADAA5DD5B53D865C26484DC35E1A5249E58C13A0D5EF6D0B976C68D2F69F8E7E32600CA33B3ED0FF36F847FD42E36E99F5582BD236B33DBA4D9913853DBD546D458FA6CDB348A2115E495412A9BAA5AAF2A68F4B0CD40ED92EC0EBDE502E488A0BF1B8E78E613F85A438A6458C6B7A397764B48648605EFE77342EF3CD4649058EE17E24F41D0EA62CD7AB6BD2860D5CB3B9249934D76C8915AD049C076B5C4FA379CB9AC72DF39CFDE95DB4E974AB7CD1365E2A96EC7E5A7B4551E7B90C8F8A8C95DF7E03DF9211E3BA86B232E7CF6694BEA997F5E8E582F7CE79593ED656839C909BB9DA403A7BCE53137B6F7629F59F90BE0F8F2C1A274FBABE3E5A6065F736F5295BDC6FF753CD39C30F10343DB60CD3BAA4CD8C79C5EB7829D29308B4916323AFAD2D35C95A348C9C09F106A0788C51460EF2C81AE6A25791A5C92BDF6A42B515B0ACC90853E2AC6CE8721C1C7C1EF3FD7273F74779D45C773589AB07A0750F250E83BE6B89C4BA053A41EF421A8C1A51D0CC547A68C4996F1853CD0EE8E6AED8B536A9976FC3C9C7EE5F0C124474CA039794ED4E4DC55CB81A2D2F538CA865465333B7E48FB1E5BE1AA23FC47DB39D47A75AB64D2D010C6C1B39495482E46A2D2489C5E1BC725D4EE11B505A3277F26382B238F7D689CF19157357EDFFC7D96BFC713C6F1720F9DF518DD6FC1B21E07226481C5C50679F60F8DD01B551AEDBB8176C7B12E919AC9E0E885E76E9C8F61628A89BDB7FF1D877832588C3BF0867AF03C0C51237081AC2239B4E28DF238580A1C0BDB95EDF78DD7EB31A04DBD03A5DB03D996F4998D6E661FABAF8CE562B9E2A6494F96518ED9D2F0EAA0EEF7CBCDE941D7F0AC2B0E535BA23D14B7CA8EB29C10A8098AECE7A30475C1F2ECD9109334637A1BA80ECA8ABFC42C8E04835FA4E3C779FF8AF031535D7FFF66B5BE1788203198176F727A16102309BC30452303EC77A1045130C4CC7AD98E1214EABDB9806CC327874C1C94CBDB305FCCAC3CDB9214516367A7E4F3592F538C1735E15082C6686D20B5184DEB18AC46342DFBCE659558063B308FE8D9F3DCAF89F7BD6811747DB87A9270EA2A8CA3E790BEE735CEDD83C4AE02C5008ED30F919F42CA8F003D052B53CAABE959F618F0410ECBD9857BE24486BDA5169FD183168BDAD0338CE4F65C987CA1B1221A72431954E201F99B7C7F86477406999D98057BCE03DC4922452310B56501EB789C0AB44EB427E70ED48FB72965C21807120D7E9D39BE153691DD7CC900CE1B23A8FC198C0DABAB16A2B58C1912DB0FC1FC118380358464B596C1FA6F3E99B450A8CA0475940428959DB4219E73BBF88C3CBB52B52EB3FDAD61BD80364148CAD443FFD51B573C8D4ED6A2442331D66327083BA8096E08507DD56BB211530F47D1D75374E6D2F0B7E4C4C0BD7F31D30913DEE335991AA237C8D6A81C1F21421F942176063AEA420A3DC4C2AB95C12715E17AD36362937947ED9E5F28ED3E8CA760568EA657C473E73245D902628FC617FF854A9BC8B27612D7CDCAB", - "rnd": "11602F615BCF6431BEC3B08E74BACA93CA8175FF742F01D0CCB0A89AB00B2A82", - "signature": "0E4BD44FE24127C30D9E30F32AB073331CF6AEDB6148668A18AF62DCA855E738F0736AB2097BEC20459EA468DC4DAFF9C52CC1D94F1FA706F79B455D7B447399FF605F0B1CBC3AB40B1322CE90FB30AD884737DD6A82FF1F0CD61CBF8DB89E6E10E46E580EF5AD7BE311239933D7BA0E6F9DE039A159E931E4880C9C4C9CB973950947D735AAD39D50F5192CFDB0E7A5384A64B7F8B771AB0FF15E2F2113762414DB2A9D988503F6A7292A123659250B737BC6A299A89A8B48CB353F971CF6047EAAF675AB0BA52F4FA4151E3A0AAA4D1D45004C9A7CE3B5B860BCEE12B566261A2FEEF083B27B1CD38CF4D5B0DF6A9C7B07B2FA294BEFC824A4891EEBBD840939719706904627CA9C3903FC5C29637BD1B22E8CFD7C5AABEC5D2FA35DEEF8A6E4C818E99C2C6458C6DE29A601CBE065274D64FDCA1FD72DF6273282FD2D72CD4A930211CCA12144A387FAB2D3B27873B8202B8CB2FBDBC4E4C2855E30ECD28B69C344903D181FF10E75C74E248FA257348C3720E6A5EFCD153379DBFE1D6FFCA73D0165E0D62BFD522CDF7084006C0470B1287C6CA25781C7210C0301E7A46B5EF257E7B96CCB02482D19FB8D59958D9922AF98C91F6AFC82FC4D385D79383D761FE3038211818E36A024C69C901AC7F1C4C6BBEE1C46BD2DB4DD6E6EC1C9E68A90226E64186DBFE40983B4F18AF7E80D6CACE29B4E558FBC9EBDD2D21EA370E23DF594D191ADF49033456F9DF941E53D697A0B9CAACDEB58AB0EF47BB9193A12AE38170B02A1AC867ABDA12EA550776B7DD71D9E734EC85E1355D884056FDA1B25F33A14E7AE6DAB194FFFEE5E40F4C1F5870E79C591A99A9EEDCFAE8C3EC91B9985F7C642590DE7867AC6951B2E211F758449341D2C9D7A0EE1455682C618D67C6F51A098B100BDD56FFF9D5FE5340E4F9A88A05DC1FDBD937E8AEE25B2A5B7394963CE40BA95E23DACD462225C29D2FEC884EC329FFD813F5A763D56900DC1AE97E35A1BC7672BA06FDB60E5DF2648CAA37FDE7F04E771CB8ACFF92F206165CE310F6DE2EF4FC37E561556B8C0738E644A7BA1DACD7D781CF8124C9B72BC51418E0C21985F06BE369251B7635DA34EEF5373CC02D18A86980AE1C7D3F72C07638B5E7069A74190ED4817BB9ED9EFFAA6EBDA2ACDC40211BD9793A25FFA13E12D852901739BB0BC53F170E2662093AB144BBCE29E0ECF5F8A274BB74ED82DCBF834E36A4E5C0004C44DB58257158974FC6E6FF1531FA755240899FCA6CC91D4E10DA670CEB1574FF5710E321156F04411CAFA09E73444780758A632A85647C3059BB6CBB5D754A53FAE4F5EAFA338CF55EA698993CE337C4AC78586DCDE1849300F0F652B9FEFC4D4942F864A087FBF445F468D57CE5B7CEEE5F5C58AEB9C952AD9AF50D8950942B30250CE60D688E5DAACE03D5019D4A18E84E0D92BEF8E0C7A9C656E9B912CD73906176B5E74FC0C60BDC390EBE63E724EB4DE32CA9A3C6AC26D811A76810B0E98320360C0E1E0F5FA99B19B6EF03726095B3E446B413D4EDE02F8FA9F289D2A6BD6A91AC9833743AFF438C82BFD10F9CAF9E77EB30F9F96612A3FD9C003791EE61FF8D9577F175F58EC09F92D7BBD25B53D826184183341D67A2094448091BED1CB729F1913D9463FBACCB9E85DD38FE2F27094819D35D03C7D2E96B72C564D9DEC6B81A9C5B7CFE42F4A9BB89EF245AF79C3D9D9E26C12903BA9EC0B98BBCA1EDDF4BC10CFD07074ED5EF4A0F867CD399E76D48E350F9CE121FED258AAFD81D33D971FFEF9A1792C94963CD3072A629E2CF23A6B1E66FF5A9A19D990C200019680424F2588547755E7AF3CB68AAFA049DE0ADBC7856A7B287E19CC06BBEB2537967D39D99DF7307AEC3170C67E1558FC8326D89C980C54F2FBF901851DB45EE52EC9F1D51907A23B8198B867EB19AF26BB5B63DDFFD7EE6966C91926CA723710B72FB9D05245AFCA6A68444B65748DB1B0B3CB9578B5545FA11655A1676C5CF84E06A2FA2606C46AC3FC1C0D863769A6AFC7BE54D8FAA8480109FC254DBA80A1FAA8090A88428B4AFBE1F57F4E1337DA5ED48E309CEE901CFD528B6C564724E7C5421D637B236A31E1440F1F37EFBDBC869C3C8E3328F5C56EADF35C9078BE9DA901F1A177DF535DCF6FD5E0ABB5393ACFB25E3BC0D295E408D18E4D602D783F980AB852F2F9658A5EFA61236A801A667DEF28DD3FDAFEC1A60157C5852AAF22327D8BF906DDF302F05902869CADDFBD544C7C7B0646107E065A62AFE25636EE4A8AADA1D0C031D6270FAA70F1CB052D1C29F556E5BAA99BFDE2428A21E63330A02C58EBBDA54769D23CD343DDE94E6AA78CF8CCC11048813E7963D1DE3896E801498AB8C4F61A284DAE89E2375A9A2A8C7093AF62DC784DED4CF05B8FADB9F1E50E33C6D1B05124A9FCD4CFBD152636C0BE9DB0B2DE26A9647968E7907B4E95F1B05057CCB5B6D58FD94B2352FC37435F72EBBCC64D909469C519B321A6F8F1B850BA474522FBCECAF5B5BA8A9E3EC865BD54E2EF66C192FE44B133B247C7DEBD69880313487F2C3FF6D525CEEFE3B0BB3F9DC9150BA56A5EA21CCAD5F3D5CE1C9C3B8396DE42407E15DED163788BA20E8F690ED2A9D9452AD1EF449D868B72245D59E6FA9E6AB3782EFC77AE33480CF3FF8D4EB158D70BB7C6AA30AA4C038028AEC1E9DBD9D6D9657FDC304644AA3F40F9767719BFD21B66F4EA915D363FA0AA11BF5ED4D42602F6A70E51796565B5FC795C4655C3164247CCF89BBD26787C9CC31A323E496AA21E48F5895DC57DD97A57AF479DCE670BAFE18C15874A2A3EF2D11345064DE38839948566110DB93D4D53292B079FCE266A31597C09516394F3B358F0917D7CC9B6188BD4D2CD8748FE6EC138EBC3D098CF425696C40552697695679E88B174A43FDF4E05525ECAF7C6D783705B8ED4874BC47E63E5EB5B49DB6D9FACE5642138893378E8F54E219EAA87DAEF549A4C1CEC095EBBB02AE0735058F12E71DE6897931F569B684FCE0615D0E87979216B8CC0937C66475804CAC95021BB86500249CA9AA4A81E6C9DD3F8FA71515958A75E4A1940C715FC3C18D711479689C6596B50AB3C7A1CCF3789ABAE26EC79E0426FA75231B3590A1F6EAD7F0ACF73C772855CF8C34DBCEFE22047AB6002A24C25C133F1A3FF6D079071F4C93E6C43AD43F093D86270B4DC3637957B6FDEFE7EECB3C85608B863433F13CC1DA65A4E23A3E903104C2286F7B7DE45DC0A17FDF01CD6259A381EA138C48A5E20E13600057714C16688C21968014F803E26B4FA47E11B4215081FF9313FEEDA64B3994A427FD2630E2DC0ABA996A30DCE1D305CC7049FAD77DFF3405B98BFD9AFD9C289F16AA53DDCBC6F3C8A7BB41109570D982021079E8380506012EE058A8B5E39E9D7D20491308EEA7E3A2837E6C016859F7715530A70385AAED25D8A22E579F360FA837503F58D231066C86115E7B5E54D91D1EAD212E8B8E77294973E4A3CB0CD8D53C06D647ADFF20C8E64506D45D7466223D8C6E929EC1ED4F7F7BFD1FBE8718837E26734F62E51C06ABA6C4FA277EF51D32F25F2A1F33CA53D5CE2071C8B39ABCFB18BF6C44E8B2556CD75521D4F0003E7AA7E6FD5C773F3B42652B3FB6277E87D3B016DC440466277EAACCFAD53372ACCFE6D4AFA5D8D456363A626A57D1A795746E6179468CDFF4A3EAB0C0135A0ED5004C3C4FBC6C50BF353B9BAE85575AD679A3F4D59B6110D54202864AC69F599B086D4F4774AA15D758216297B0A15E53C1CC562827C59DFE76DF3A74CF3B85D7953E649D8F0E897435BE7CFAC9F5842B366D396F596C68B10A02BECDEDC709E35EE8D4210C145E08EDCD802CA1081CE6904492D37DC0826B331D2D922AC3DDFEAD268A79FDED44929B5CCC2AB7DF3FF59C13D181EAD0DA244E8E9D24A243CC927E58F16A4347B9EE33E161FBCBF4B96FAEC78B9CB0BAC84F1033A02D2D8CAC719F94F7A93F1828C2D55578F82797258386D31E7446E095762692B6EB37EB38C93D6E347CEEED1FDE0278C50CE11713CDF0C0368894FCFF8F16AE2734ABC691365D7752F0915EC7C8F7352C17DF1356A2EE6E144A71A9F2633861F6347D26C69067BAE8E4153FC11232B52B799C7FB0CD0FC74182E65EC621A3F1118F828E7A8DEB322EDE33DB49B2DE9FE1A410148F72FFF3BCBBCAFFF5F6CE8B33AD0E5283CEFB53440419646B491F79CFEC6D53EA5580A875EE8E5B84F26D8C4B2A6818FAFCEFE994D19EB85056748935E3F20D4987DCE2AB0A5EA7B4EB025CDF5224A2FB83EF491147B640480B7B29552006578DF97252DAA55B1D1574472036C209AFAA3D3F630AD47E1508E5172E110F84E4D88D9C0966F384DBDD5673F30F35DFFA40A931F11E183704449D516220B8BBA2218FB30E67EAAB0C8DC3515C96442B9E8AEC27C5D0F9B06A566CA1D87E7E42895974A969DC092927903FF84CFAB7ED09821064CF6DD286686CADB0C5A8CE5E26FD3568BF2B65387CAEF321ED8A9F3FD6141753B5666F440E56450B704CFBA26E624C07A026935536B6C24BD8D6F5410C866091D801784E568843AAB368B6B5D24E3014F5A7079D1DC225BA3B6D75B7998BCED368F969FEDF62C535AA2C2C96D8692BAF8000000000000000000000000000000000000000000070C11171D22" - }, - { - "tcId": 34, - "deferred": false, - "sk": "FFFB9B8C64D694FFB0640F612979044C8B0E26672E75558165EBA6B607605C5586F358A7A2518645B48CC22CEA3777092B60164C7E15FFD97B8EE349BFB0FE1AA4C7B0C9B23461EF3057A178047E40BFA3E459F2376725A898048B61C418531937048586CC5E929304BF6847BCBE69978E882B74E56FA5BF94B224DB42B18B9A16428501544334843886452530620371687734860803175307713284251732413615153576282806784101866501461673161068217650235404246158005721380284040447505503476241762442322231330548277714614852337603132404705456358725043604857012047121846588611055306042662150701330573155502847742888110856758566056761541886330378750630817387174320642165414371557561252014336343364341155080540441663771641272458612002538044410645537664472626561640005238302803401882713115757656673622178654385117456814573083608576785164751744756810671444825880321575437753271707468042831843416782507546821260704023758032418786060684214817564062813312384443117234321678673841310257672302128014055416745340281244803858215286537748011231236635483161225041100325255287046155167486002816383500464083066564155454357100730061017038432668414024638265360375707883823122713172786048600588888704308352707622758814524563744463614173771848204015825306865861106251158613461116372013326465637530033401765263461535718674481760407063840166044860132036878662313547843166485467204674200230386163831358405704807575731378347100514103365445841366575004703322728887758380528156408884471084522784872270678380342786366820228677574184786387821178761273241101274154517052415302463383656570448644848286071404180106541047855524840650877515426830755660062847280545224250870770537850865703516516168366127745651874346706752657006414701282605663011644810606400476201060283203867537367645085776162328536777271108751057444060314656114154135051127886480671143661638442700353053410084133718848332866125716312470566487116824140456504084257284250456876120701730481575213057674058321460281724837423213874043162400755240741810828012470505740012120886126041107131416730627102001588661326368036831864655434724281288458322325237731427458133765443537471106256330160448165051746005537353683803708758276100125820133246088826402507471752601140530475426711152118276431065228804668111676343351853145382385736642665501307652624833884132830544734531400810423661705826835625006484628706718017517618871422387832227673221267146265865708544112866173471255637676381855207465550242180613637500724050480288700767255625102801068432785608254043207800038248884301434631642057571135678185507171763670732556375064154454038500804681415744242631387508431165861826218274516840057460531026565317776771074673385067212506228177664378480281205715863565607336348716524020488745077002172825805248446850062252738165238545885243773264648708766208841514653436152322483164186501360426836413023513387214835747651350820558678387616355027071325053381163184172511000874757638885213124677630842176811541711617212762836561880015164805860452465458558708300121026462277236058401167040472313582024756567047488807204785004216712714615264381134011543024600283502803652478016380357617566644160180655345041233770871450588810722414814145742060370080318344AD02A3E27D78BC5BEB3454DC63407A9B76EA6599B86E9E66969386499884DF172FB72F22F46BE747300DA32EC2D997BE2F0E40A89C9F2C5D306E2DBFCAF00F386433395FC3DFFA4F6FD5C278BB212B81C0CB2AE047055C1BEA11344190F379D58EFBED3F3BCB76F74198CCDF5F541F1A5961A2D39447D959A07DA6381863DAC2961A764E49B058C1FD67A367A895C0FD79527EFFCB143D5FB4930F9405EBB4580ED3702A2A12900C81ECDD223E283311B89E3CA8326800E6499292008D44DDCA81D83686EA23ED1957A1E163A89AC412F71C66792705649C48695DD3484FCBA1DD0F736FE4BF4F6BDDD79BF429413780E6F94EAC54D90DD7285570FB16132C079694A8AD4817CC6D14EEA1133FFAEC74F6524EA08C7FE4BA1964ADE672419165B2120EF6CF055D153D2F257DB3BDE21A664754C8DB35A4A591233EA03050B98AC35AD58EC2C97447DE51BDE15CF376148204AAB0127A76E8B552E5C84E01F7B1E077F8F7D5222E0B98BE4C49C88FD8F4089942D18C1248A859ED52F9BB0560793D10CFC4749483B38EFEBCE4D4EA86FF78BB53E1C04C97D5D341DE3023DAF8D8257AE13B2B29F14C096D9879D2D37FE0508C1D033286558E3490DBEDC69ECA5FE021C673384AC6C481F630EC3760E1215E7EF9EDBDFD78C18EEAD543641E874E444DD67BBC471020826383815CE2F222326396C8ED1A6F86F03F0DDCDD97EB24F46D757205A1E196E1D17B1EE68246B9AE50DD2898B689B3C040079DACA928FC0983CA9A474586E14B7D91032A1ECC2189B800C2E12BBF0DEC27E0064DB2B0E27771986BBE84D54B01A693D7AAC76EBC25EBE721EF53DB1AC37E432362C76057E9040DEA3927FCDCF1C316E4460A42E9C4F62D4122C997E39F878190C0DE1116CF2E4CC119D31D2E39ED08EC5D36EA4D907C6D1C825CBBCC80693D75C67ED81DB126433248ACC362AB93EC24163363AAF27E2CE908C563DB6E5FFB32FE0022156E875A64576C0B4E518951A2033BF33965588AB936CC7D9B05B7C316AA3C452B3A090BEF095B27A428B4A8DD045529140B38A9340ACBC01C775D39376F1ADFB12EBF88FE1A444DCD1D65B1189728D94FC311FB67C6884E03A0C14095FBDAC8430C0905533236645116FEB83C74C8114A8CAA82A00CA2A7387420A02E6301E2FB17646C41771A88DDC1D2C51E89DACF18381EC255F92A479BF0D90AED7155D049F56870917816EBE1112470F210B0B071F2457EFCECEB977009EC6522D2D6E382775874181EFEABD27FDD06438591403D6FF514CBBB30219CF10612E884F9FC9DD3AE1509C564ACD10E7E7B7A5810A9CDC71A4AE9C248670CCC8DD92162A818DE9CEBC11FE0CB35776231180F8AE8D89B7C57B582C571AA3CF3BEAA6971B0BEE6C24DF1D8EB0BF8E0F534FFCE929E222C891F1015836DCF2FBE8E27B20D8195B293ABB8FEFA6B9CDDD14B4CFE9F7AFD552F00169CB5169C1C994872D22B9C1AC98B5E35CFC47420546D955615053BAB2F139795CF480E5EF3BA92B280DBA43EAE9A58AADF064BCAE3390B69BA6377EC3B6CC119348F0546828F14D9475DDD2C8BEC8F562927C8C8438992024ABF81B877372DB8599CCAB878D6C3B01F861D115B87AEA1DE682C1B19531A4495B1FD027B4790F89567ED515E2E5D7035A3C2B40AAB04DF48B004FB076FC665555F53F7D8FC217017FB5BCB8DE4B9B027F3C7EBA143B0DC4C130F33924A3E62DD65F080F292F586A3E45DB1FFE9ADCE24EEE5029E65B8167521F8A07FF0F8847217BCE3280BE2433F913005E4D662E6D3249B1E535AD68D485CBC8FE335ECCCED7E380218BFF18343CE4683069F4EC448416FB704056D109D7345AA4C18FB029124DC1102DE3CFD888E69D2401986412B881DEE1A83BD63D77C8F6836EDCBB8D746F2552D7826566E84DDDA54E47E238B857B294FA9E349ABDC92A21DD5AAF8B40C5BE54E447A65AFC4244342FD1AAFF6B73285011BA5E957B3850D010DF5C31E5DA6A9FA4E8F9FE2B10B7DCB15484BE1D3BA516A524C252F57F5A1FC0C1730E614A22AEAAFF82F4DCC8AA8E5EF0EF77AF6218ACBA3A618AA0A1B8E45587D6BE5D477DC64939195FD7D76CF124D20DCF9783C4472D95CF2631857A4038056CDB30DE3834C90665FE097B371D6095855FB690B112543DD3303630D7C0CB7A1B242B4A4AFA34DA788641B8E82E715B2FD3B6B53E3AEBDCA00C061043AB90CAF8D96F2D0013FF1F73C54890860459DCEBFB1E60E1ED7380C8989BBBB9EC3356C38F5D9DE87379FD91AEBBFD5F051A28842DF25D5F7F6ED237E81437DF66550C556A76986168F453E1420EAED1A94DC5E87576C08AF905804866F28E195F2C6B29AACA80E9B1FABB3AE68DCB9F37F0749862879CA30BCB1A7A68594DF96994A53A84A050F00D60742332BA996EC5311AB534341D2B5C7FE6A608D57D1F95571975F9D6863A0941E0AC69717889FD537BA8DB60A2A4BEB7E13F2055088858D973A22A20509B6AE750AAA201AD1F2798EDE5C289E51969FDFE68EEE3FF38A543A14FBBB8D3AC35D3D49AA14EFC815FBB65CB2BF22D4A5494089FAC8A7736E4322B532557E6A41D46EB6B562C353BEBDF3731B8BE9F4C878CC4AFDDC822B9B36D9898379B8BE77B7045A10793F19ACBF1C4BB6C081CB11A421885262A166EC034FA3D73D6E292025049AAA261E01228E74245A9B420E859D118E9E066C83D152DEEBF0CF4C14C2FABAD96A609A91BC63796C53C43F532FA0FA182727CF062B4BCE2ABBDB962FF9C7954576A2BC842F533EC41437F602CE4CBAAE0B55933F6E3DF5AEAD1540E32075CAE5E9C46E4688D407A5384A49B7CED5BD4D3ED5736A5905DAA75FD9D7D5501A6FD4FBD1EE2E4848C881AC3F5BC8FBCC918BD12813F8D5750B3FA0B35C2B4B293206BC2E19CCA0DC9CADD3CB4F662F7BCDE92BB365789CA0E06F3770603AC4115FC8A3BDC37B7A2FB26E31C8570A2E3569C2418C6C3538B00E28BD99909EBE0FE1628FCB31B142D6F14373FF2832FFA29C13F7DB1E1779B867B81AE010BB986654100F8033EDDBC3AB8D2CEE316E24BAFA6F56800B2F6873FD35E84721E251632193B75EC5AD3404CDC2A4BDBB9C73938938673CC34575F050D8C342F9592F9036572FF605081D38A1EB7916D1124116719193AD680BEA6D4D4B0F96B4DEF39B742C590B218F63473A3233CE5EE1C68D1338AB25CCA6AAA21B0F221D97023AD61C81E5EAEAF5BF673FF96580722A524569C9517EFB468E7437EAC93C353638E400DB7321F5377F1A6259C489E25E51762093459B1BAA6FC4581622D9C61E6DD70772E15DD045B903F10F6957A74FBD152E0421883A021601BC8D123C62531D152261622E05053B1E1E6BD79F47EBA34B5AF260BDBC77F7EC2D2FF61B24C5DD783A9A8453EFC5544A11E7268838CDCB54280E085599423F18043C1EB98BCDB433D73770AD976F638EB7FAFD60A19E6298FCE0FF78AA29E57FA0F593C6AF814EE69F0CAF1E6C434633A067814F7B11E", - "message": "B6DE40E2DF69637F160032C3D41D7C239D2C48D88696C365783D9D19A153B657D500BBA059B53CD348F7CA833CA1A178E05FE095185C64727E99971C3CAC76E1836F6476965D837DC16135EA0941FF1059D9C5183539C73A7652FDDC33FE347DE2D3C53CB2FB52A67716CFDF96DAC47C76CB1A702958B548AC1771E803FB949040CBC5CEBE75DB7449EF70EA827351E73B00D7C78E7549A7A183B28E6F9C95E8005153E8C2007D4D92A9E5730057CC5EA5E08499E394E294B487CE3BC36E1D2F6371414ED1F6C8C09ABB5C7109FD2F70BE75FC8CCBF95A42A025DE8AC01708EE1AEF712FC78AD4A16C50923ED782B993128E52CC5C371ED5A008D9A69835102CF933F4C39041FE114158C3EACEFB4B7ACB77BFD14402210EB20270C69C15FA303A613922FC850AD16097CE7E46D1D711CE76BB92654B8E3355F1489A125FA810D709BBA50D1AF08709251DD23577FFFB9D83254525D13AF607463CED0C13F77D6904F645CC7495F4BBE163A042957A92DE55AE0ADD1214CD4F881AA20EAB696DC66067AF0ADE504B8E02583A9F8A7F21E94B987580BDDDD1B300231DC023F6131B032AC1B763DD77CB2EC7BBE4C8CE73A6DAC605BF8470F1221F13E7551C7A55BD3C026EFE25FCAF5058FAF1AE00F0C7E879393A79B4501E7129E7B3132DCFC52076BBD58FB6EDE0153FB90FA2E21A09D2271524E19ACB78129224EB0512EF09679DD4C809C3EFFD9D1BD4452C62B09614EDC503373663F43EC4997FB48AFCE985E67253792EF7982B4D5B458E0A3DAB11D97501FB74F0DAF04DF7005C1A4BF861634F6A0EC1708AEFC1782810544236C5F699FF835D4CD5508014E9B8E65AA3756C99D14003A1AAD9F95F484A405B0537B0E7B7BDC165FA34906DB06C49834E0AC2696B597AE6ADAD57C1E8588165BE3180333C356466DFD8F34B27B04E019AE2B7C9AFFF8C866BED1C1C24A03DED7FB71EFF6DE46606D37268F7DFE5D3CAC97B612645001DDC30EE17A33B38D847D0D230FA7A187DFC08FDCACDDBBC7483905854FCE80DC0B0B29817EBE16E039E4044B4546863221E784A3306B1CF7547D9F8113ED6188B8427995D9D36F5463B047B9D51034E7BA1962B157491E74910354DE027AA0719DD95B7A2E405B9498DBEC5EEFAE0AB95BA20BC46F0F6203CC97D63567F830501F2757DFC99089C5DDC1B0B94CDB1C7738CCD632DABFA8F5A9150AA81629565995392A0C15337621D4D67407F51B28C74FEC6EBE41C58939337D033FB26EAC51D9B5C475A25C53978B280853F8DC72BC54CD16B28B200F69AEDC6878CAF159ED3A6CD467C77D9456AEE9EE412F28159BF5DE311C4BD6CEAE1D9BF346B2F2716979278C0E68689A85D9529949DE1CF5A2131B7B4C6AC304B67B3CD062037DB93823CC6E24DA28A7612A9BDF409D39EAEDFE06B46C3AA535E74C56371FD9B521B8A32683B90AF3A8D787A5E190AA510CB24CAA2735365C6EA775791872F03F171C3C89A1A9FC3798253BEAC8995CBB5064C9374EE0D16E4244D07FE09318D4B2504F4E4C0AB5D5E98B9AF89378A13F27661C2157B28F665A8894578FD5C3231DCF6379C874116C8610F9CE572BE6D69C5055A3B636A425CA17B26D774BF6D359E2247A5F4D8F7D19C257FBD8497E0CF60B9376B91D053249C2B757E13B3EEE1CC207C538DCE23FC70EC0CB68FDE8716F93A8B62A03A551A75D57417D467BDA9DC0E9C0BADD909EB1CD8A6E6EAC8F910424AE5D15CCBF0692C292C96BA3FD416D2F67F89EECA60DF0BE72E90A38144A26C2E57A97E90A05C978BD50EB814D34A6849682F6B653F99F36461FC2788F40138E5AB8D8A3D603B26EAEF2E6454436CE4561898837C8817BCE1E7DECBC64786B93A62FC81B7A181E1ECABF37DFC7BDA432DC26E0EAD3C9AE22D452BBF4227D2DD6C2ADF2E869AA7C52746BF166A45020DA621F39824F3E41991831C5F66A927ABC25DC3FE888164215B930291552B6549A591686AD3953B302968AFEBBB02582AD71542D08FA79E0F8BC72D60240D81406FD762BFD4FFC1052E52A62790F0E889F4279FD76CD42107513D69959A6983CF8F40DBA48C4D5177EDAEA5B1AFF04CF55CC8CAA7DD11814A7BEE0C2677AEB4D3045617DCE54551BECF7CE8ED1F9DF65D63E1434E3D8726A71CC1E9DD0C21F3D69CC54EA54EAFD6A016082F03B89D0C65CB18476A84509852FB658BBCE567C6FE7FA18B2B02C176AA4BC89ED6DA220DA87DCE45D31F737727F15167C4592269B5DE0925C545893410EB66DEFC778AA4632AE5DE4F1DA508A566D1B536D262112AC516607E85378D5C1E62782719DEF8A7883A276A4C2ECC3F88ABFDD3E65273648EF7DA70312C9D52502B7DE9E5905064A49C8946C69F219F8791AB238ADD879B4B5DB769429D431180EE0A6ECE53D133CE87B16EEEBEC246611D0E743E1E405A994C3DB6C31FEB560A770589E583BD9506E941CA3821E889147B892EF44E888577EFF18BE9D71D0F51EA90D648D6C1EA4B02C2C7A3B74A8BD7278DE02E3D409B4D4D5FA66D0898C8B1E48183ADC0B0A15BB76B34E9D6D2D6965F9482A0CEF4D36D3D96F8771CA2B737AC9D758DE1EB6CA92DAF2310AED8E345D7C310BFCF754F5A0F64982C59CE0ADB7CE3C2BA17AE5A6F5351151D4FE2D1D6C25146277E331A6E588D3C3B5AC0FA42CC73F37FAFA6961EEB8EF3E9E3A7E84B9FF3EC5311D74E6F627160ADCC45FD473BF8C5372E70C9AEA558FFCCA37DDFB83B08805807363B92AA21F079543B76EA5A9767C25F23531F4BF38A4C69F99153EAB5E9422F58DFA2BB255B819015A22FA569C534D0CA6D244AB0B0E6D9F6B705A3808EF76B1B5320CC378DCD489ECFFBDA634320FF34D378AC545E8379ABDA48F2A3205F107C92E88AC469A4431A79A9342992B33FAAA9C3E09E74FE04DEE535DCD0E8C14703256C1782CAA8F7B417215262625EE1B619DB65676335E9AA6B556D60585A3CCC0B9688736A58850E2B44D45DA86F335296342B248E5399ADDF81DB50B622F8EC7EFBD195B177EB4400F3BBFDE3C82C46A523835147BBC7DD2B39EA569D8602E641B726D4B5D876198672DF5531C5E7CAD878D6B80939A4A5CF876D289171B7E048ECC2CA9304BE7CDC8C8BEB60966499627CC854664BD20482B9D8735553A6115D40EC955E4946A0CC3D04DB3E265FA8FAC37C3782142135822114D9A48BBAE068C911BF3F5F5CDEB34A698880552596937DFE0F340EDA6F002BF5BA28FAEB35C5843063BCF225F9D2B1465D84216177DB3CD38FC18065992CCEB264592E90FAA8EDA9E1CC00D2670CBF8F9AA7073DB3904EE9B8F493236F65FD648F5932B9624BED64C2D4F1C5C4F5C822E4F0CB96915D0C971291DBE80CAF7ED391C5C82F2FA480653E989BBF27617A94DC9FD3EE388E295889615EE2B02CFC5D9419263F8AA4C1B8DE0425BBB596F971748C14080D13ECB70552D4F15D5E696353515520D2EE20F0A7E10125462FAA5E53BB411A8F4FAEEA3AF82EAA956999E0296BEA60F44C2DB5A6A357BCFD26B033FD695AF73E93CF3DB24A6DFFA4C794FF9DFF4BF762A8C7AEB380AD5E8C6134A7F8D272296837DF75634C09BCFAE0355402E41D32CEA9066F93C32E1E08328ABB0668E0D91B96E3BB311AA068185B72E19EB690161C3A10D8AC8EC04CF3118F03B521176CC2D40B93FB3A6DDE82B2FD5410213098363FDD1ED5A2AE2729DFF69EF9221B15AF8203CF4FC656F959E57B5AB5EA2BE9B08926D037C7EFC5A35B5A5234C6C4FD0CB33E3C0BE0225C1014E5C468518283312A65BD2028C8EEBE0EAF7123670E3FAAE3AC376E5D13154747F8FFB5ADD453CD7DB942056FE1B9EAAC991EF569A409149B723CA54F01EB6D6A2D01E1B39A572DA5DBC87022DA1C2051876F4880807448DAB3500501F8A8462A65E08C010A721CE19F75DDEDE3C7EB773E9DF84715D24AB903EC26B639CC1BB8B554EAC6945FEF7FB75D53CA2D4BC6DA063ECE1461FB7F4FA62060FAF2D33FF2400B39AAA2F2B50DB159439421F0D963E6198A78BF5CC3EEFF8CB84A6CA1D9FAF274BB07AFADF391B68E7024E97EDB5E6ACD9BCBCE3167FC12E85895846C9B227E2D12FD4F443081E459A92658D6D657213CB708C3572704710B4BE02FD7EB60B4C8FAC0D6FD9B22D55E23F636D8075EC9876D6FCD50EA79EDE8FAEB6606E00750DFFF5F349FDE8EAC8558ADD015ED6CF7B2E60FDF3B40B3282F60B48B48A72D0CF30C2344FE10AF974DAA0E0312A84E9D86340D33ECFB5C03445E454F75DB57935BC078648BF22BC01AFCDB9844F78674B02A679F3A89CC6C70AF3729D1CA93284353FB991CFEC8EDD348BDB968CDB37B88161A09049AE65759956254DFFE08D7B64365F8720F8ACA346B3921E02602D3041728DAA2496CA94B6EA8A7C9FD590D699DE06AA1B792B1F0BC53704332C5023C2C51390C727596AD07B005C07A8787DC7D53A6293FFF5550344D18DF1AB0FB7369225084358BBD4409A9", - "rnd": "25965E34B6213CB624122B9E2436180F8A707033C0D62863DBC7BE8DDEC08764", - "signature": "47ECFFB94A2E436540502BB70CD056830FEACF8476B23BC39B847F4F080ABDE68B5F5653BD68A2DE5040DC1CCC99200EC10FD517A98A94D17D885FAF6A8D9194C84A88B2945EFF16283002EFCA2264ABBA75B50F69EA91D97E30D667FD054B29FCCE242FEB2F6B9880451E73FC8E930A8F0CBD9B378D81CC47FEABA63F8715F4F8F9A98C7AB77A516992F1E89959AFF9BCD1735C08A8B6D36713E77455426535EC8DAF96C1544DA05B6E13B3CD5690A53EC790ED4BFB7688CCF7DF6A8EB17512D240489515E8BDCB538315BE4E8229C2989A186A5F1CE3170DA8BC21A4000E8277556DA295CFF428C37DCA79403D87BD6F8359C48825AFBF4931DD9ACE14EDC84349C087A2764AF38CF62C8064C837ED1D1B19FEB2413C94EF1CCDB1B0978C037527A02EE099E13139B7971421DC98B8FD66EB150FE122399CE9C4B543A2DCAA4647839CC108B6260FA55C7123BAEA4FC70FBA8739082D29BC6738DC6ABC2FB89FEFCAF67556160427465F1686C7456FB5E9E340936659174CB8E0D23E9FC8AE327DC6A613461E03E1F5C462ED8C82EC87FA9E4953B19C65D961A33A099367A3E706633967E26942F77D90FDFCCA0C4DF4B1D130DDA4FDED462E613D688D93E4D852111BD5D6AFC30F7BC80316757C2A04AB166E9EE0C4F8F77CCB2C7F82A4A97DF5CB36C0EEC79EDA0B70AE66AB4B5370AF89980D84E1F6C20A03E50E9D68031E80228A885DB9667777949503D6E77554F6D02A1699833709AA31CF3D179DC7D4B8A9C8CE937466CE57A6C44E28CB50FADBD4194B97CE5FF90B44C27BCF5553CD8B39D2D4AB2774F37AC16869AF138345E6BDF331ACBD3A500D1582EFBBF7B0DA8D08C1CC4EBE0C5CBAE5058207988B5C3E0ACF0707BD7B9DF284FFC955C0FE88531FC98EBB526D68DAB09BA8F4B487D2AF6E42FDFFC03E3E38022351596D4DAE196F506F80B93D7B5ECBE5FDD3011B6F76B8782F44BD2EAC24513CA393B3731103E5224D7D4896EEE1E6F3847BB16A37CC7945B7548C96143B0959D4D5843A8579616CD9F9317B17155953ABDFB1D55D08E49B6AB495A4F5F54E13BA4A53F63D19AC17C63802DC7107539E216DBFDF4C07E44C89F332A221ECBB549FBCFD8BAB122ADE7CE5AB77D7FF0C0226903549FF7DF2D383A628A3065DF5F0B32ABD5CF723F59A3AF6027463060C38A6BC3CCDC47C3A21A35C727AE5429BE29AEB2885A04A6AB378F5E524A7C933A32A0B0D730C9D0D2F409D5510FBBC25CBBB5F0ABD25A3B0DB0064D4E20380DE169E92AD73291F43B10A370E7DDDF9F0475F29E9629442B179F8988DEDB1C24F928BA68A159AF3A0576FFA3E2E5A8AF45B167E75838220614264285855B7D4DF9D94CAA1D24C3E7D776E747269373F7B53D43392275CA7B74680E26574C2920127E82E40344D7B3F15C40E2E1DB409EEF8BB82CB24C73D0CB0772F7D9036C4D80C57FC0B8C35E8F569CF98779958869D2980DD303118DF9E81302A7726B5D53469D3B7CBC062685FE0A1615AFF538A45F5655FB682678A7E10ADA2727E1F4D0E761B5465F28CC3ED7BA6CDF1F15DE8DDB102BFE23803B36D627904BBEB7AE8005BB9D094702C31282D08698BD82852E6F409CC7BFF31E6FA52238B797FF42AEA3CEE15180306FBAB44794A595E318ADF2C84544448BAAED3BC84BA4F50472921B4F182EFF63E0C8A7BA19A71134C34FF01C92269EF03301FD7A9376B2A8F62A341F424401457939F405962AEACB070EBCC0DF0E7F7C8F2EF103442CF7890E7AE9E8509A3C0FAE20C8A60942ECAA70A7440C9F4BB3D16743EF3ED158CA1E5D2FDBA6BD240F3E998F4D2E68E029C1AC9196EB1D39EEC9C8ECCB358375DE3F229B0F2FE2EF8BF1A0FACC87EA891E574C12D37B7FEDB0E493A47F2F16F4CAA3C311B65C6F80CFAE4ED95B699C51D9D98679750F5F13FAB6CC2BBCE994426A7C2CB7D3FB66EED156FE848C310C5FD021D5B005573EB470B19A1241F6B72D011BAD6F20E139F022020A909AFE86FEEDB7FE8DBD1BE5B155A52471A4219E663FF84D1F4DE453BE2C6F71B16C428177D3D052AE9748814FA43A2704CFD9C9D826B75D4DB8C8EEC46F2DA1D0A7E64B27383A6C9BA1202BAACD54477595496E85703E0874038F826E34D14EC213C52A5B74CF9BDE05ED66CB99707B1BF541C1E755A4F5EC1DF914CF321C01EFCC1230CF3ED1967173156DAFB0457C0009E193158637193FC52515B29D4649DBD99C9AE662ADC726603C07BC9921B004D2FB0085A6A8F8D9FD047309CD35B8336474DB5D49EF5AD04BC8F1AA0C51FD539C2F77B55D70F4D3321FA507DDE324114D15C6E1D51E44993A5E5AC824078DD7D1AB01BE99AADC1DCCCA2607307AA4188CB873238FE8AC5CF241017D3EC9E8278B9EEF2ED6006F6F061936F488428F1183B761420D4441A3787222D826E22D17B27454EE30A892EA37DE56C0F335321795A527B832B793730AF65C55F3687F31FB915096A1A58830832F997942BFB01E54D9CEA2A61A7818970006861BAF54A7269BB9124216AAD8454BA1594EA5B36728CE16936220C02B5C4437B119A9B6AAE6552A0AE12A197B2741ECE792BBFF943EAB78A20ADAEF9F250E496130346781346E74A49A94D868B162F9307426021A1EFFE602EC217B152D84BEF34D024DC163104F68ADCE293F7DB5689E4E461E204D89E4B73856F2A713EA301849D2EF5F6DFC194D6370E4504305BF7229AC18A93861BE303944D00EE369B50D2E7F7CFB5A688F54315814CAC12F66F15BA5D73BF2545EB4113EE3A53B66151778E1835C22A952B2ED43D0BA60F616EC60C5DA82DAC98715A3A790C214C44F3F6A3D871D528329A32E6F220F110D0DB7B24BC9121FD0221041939B0291F15D27CBDCF72D4197C3973270535E785DA375C432FEEFA7147787E0E2D1EDB2BEE0E1906F0C1386DABB811ED1ABD969C2044E0A6C2720DA89E2B079404BEA58A3B8EA510BFEC337520D0D1E7759FBADE3172360C9CB99C1DAB939FB545137267FFBED6476E1CA74B6B7A5AB66A50BDD983F11807AA55AD1CBCF33DF1462F3417F55069A12B48EB8BBABF2E83E383F3896D2E8A1CB909DD439701D0EA7EDD304B25CF4B3FFF04398026876FBAF56E8775D58F8EDC751B0579D4A20599EA783CD1C169D1EC4FEAEB3412F2BD54FBE532A89FDD4BBC148EE00A412AB046264B7B043278DFC461C299E53CBF9C8B7CCA2EBF7BE11794D1FE2CB925055C91CB86C9EDBAEC5CEA3B71634AEC5347E5FECEC28B2B06F53E395885AF814C93AF92CAE9EFCA64FD41F0CF6034C5ABC162D6891F7DF44A79C7EB84DFD1CA32062A655D656BC596135CA2F7EC32F40B958291FB9E294640E18BC28136F4CAB38074C22CD5B17AC4C6AA3780D90DF7840CA4A5D4531AE77590FAAE1368284B9E3B52DFE7AD7BCED4541A0510885A80206D28C326179E6F838279C0088BA9161E6AF2DED211292FF733A7BF513DEECB71790FBC660755F50CDF7B0597E93F97861BBB5DF9037CE148B7F4123DB7C564BF9679A974D2380D8F3E62AF75AC90AEB1F67EDC5C603F50CF6CDE1FD83A2ED8E50FB58728CF3FF34FE06F5B68C2E3E0CBFC810772EE75A886575AFB1FCC7FB5B97D9F5A95A303D2D8822A0E794B3B7387B68B5E6D70D0F8A2FA63060C331C8F4C45CB4562D6413D71C194A3948B1D91AAB1DAC7CA7BEAE0720F8229AEB800F2E1D0A8704F4B97EF566E18630AEBB43BAE2ACBF6BC3F2C00EBE4972C9DDE9706EE696C7B7F6E46E21F92777EA7D3F4CE1482A9B5827D74286139913BB6492F3DCC60739CA96629966176FDDBF912DFFD50184154A7239D9A5B622D54E3C7AF3B16E651394B5BE97E74647E18BAE674EC6CF19B82796A53EABC6FC9D53F36500959F47DD8AB863E58AAA6713282C1EE0FAC9F25424290F6F97A706CDF4F61378ADDC962E25B38D9A0F4841EE71C32C0373F5EB7EF42DFB7D410A4061D8FD11772A20A535E003D009704C1544F4F98C2AB1EB14B0231D233F33B3D657A5D5C32FF1717FF3D964CEECD75C74F9F48A03267478DA5572AF92FED9FA01190850E4BFB6BCDF29EC31D3F4777C88C67E54F5462E2A30D81DD1D1C7C2B60C05E0AE198724620BC3DFB7749DB76F78EC7144F11B3675990907E8E64DE0B46E7A259D85246A6EBF0808BEA0DBAD3161AC33DB37E9B0FCB49C2E94CF2EB0464DBAAB9E236BA0582CBDB20DE24797DDDECE88C3C6F5B4E727E7D3FD61FAA22D79B8BA3A3C6D2523ACBF2F793EA8EFD7FDCEC1E4BC3FBFE5B8D194AFACA9BC4F798659600B99E09292B8A8DC982BB7B13B20DA6F5927BF83DD6E5708E8E90964370F25678EB2CE004848A089D6E80C56A3EED8BBCD1B5B756DA0D58B2F51DBC17F2522C41ACCB3C44DD5FF372A11513FBD56FF4BFDA09DE229310CE11B6242E131E511D7BD363DF06EB5D5DBBB6F11A4E50CF04A312C268F8F7DCED62776B09B33BF53C21AD0421408A85D32F610F2AB5F1ED4B5AAB3EB94C0C033934CF00B81E26FE4D5C88E659DBBE4382ED672DAA7B5A3D75B1B957994F01E77CEAC5EC210F620FCD1E4161EC73DDAE876ACD089DEA7C04123160617DCEE9FB09222844838D92CEE1E5F4F5FAFE15E0EBFE0B627FB2BC62C5F3757679F70000000000000000000000000000000009171B202327" - }, - { - "tcId": 35, - "deferred": false, - "sk": "AC50013453260F4585C6EA277DC92C1BAE9767F10D55F70AF733ECA1A94D74AB2B4F4D0836465E14EEBD13FF668D400D449F6DFD1EE8D78EF3055537703E67B848336791E71753572E3145205BE0378CBCA2F2448D81031DB2C5431637303633588FF6763AB8C77FAB54D4F533ACC7F6F43A8C2BBB4CF8441B8D7E039093EF0E486268416313803435277715718842842031814624063570542021400577256631250145413038530528828633556808745586764161367743446128204864825143457565842736664446222644411078876557716700748667654054868715828331213853758586800442505352438110864650817455410400823431582285020003606168614216118432407271030312608232513448062155245652833230028203642312876324002341864264764118331370765727648657223518123283238765185774111858764307253554742341765460134533137202740524264160427380226823575772480224035366113474558326445558238850721242267575457116541381718235661476160844628536784782167584214476118044505510454722241134885017765801075147101746708457272086275704278572031461743722362746865615836350404223152140133107718842112313761812107172475111841845207522043641747185671130328806710001333126127542136561755605216204284750413877675075244024782010346403540433650403865870303148766787675078468008655566021623147366434823521624337237360751611703114802834456165882383122781763061451286868851842754876185050577525640086238413024435681336786365048078014256885338212427184647753440365833850173652484715701361153875252722233674086224052670765253464263347356527457558780227342108661308514542857143487374268245515681728283544508145761755085205342088846124045671356550484366373337764436783202230587256512181110058604500527815252350753043244332086874055255068386742101251033428855071542202250023771256311266735640420061061850708087548650082017557762368157755223537711260466262456533841316031057617481835516387716013570515228337824618030418465833404786218655545310022220027334826515826814310711105454727025430746556041470458568810630081208721000338874153526640432226374210186182473423777557242522637730681470515038080226817400664551252034323604142686152613430505445106307743076384666054751423506404247203865766038347743174356301845718547282125742531723020361878048308607073132355014710338744641867340001042788743383772381302353142064167570614753217318428344608064286432387237823750305086145716370403765210046814075887071656411846748408560132551048340174828233772476445175670634150246821208282415473684232004832728774654288130507568500745245315848276385117420253274062157884867163273454162616428833158038237808346537403325507566086277257237658860830632245627060758728527160327137527804421134172854341704485782547540344778323660373886720645023000101164345287077216162146244268036041147265620501685386264226308526602265514136674301517538486488427015867183204661775246120858066143353070806554266733301644812557350702505332658653605007422520565102387428244678574784501501203351325571323475587420700823841381602405306021245333587507633746460442605688037363342667548681217644137501267035118353333817344536501557285224532753564213718266143118557133125165445538438842570356146123104650370004253113065622728283618447105326238211407686635161813556034626037853D8FD7BEA286D7288E0C77CD00E3F1B007B0FA59B2F3C63526008EF5AAD11C4F85C0B501543CFADED6B2BF0830623F709506BC5B668F6009C5300DBDDE070C484C3BA01F8E67EBD6DBBC109166015D447F08353E5ACC43C3A1EF83C08CC2CBE09C82D2B5AAAE1187CDE5AFFA8384D40ED3A1E2B003CA4EDB06FE8C4D146273C9053F2918416E7F6CA5B5458B5182631463E4044F946FE7FB51F65C44596562FFBF7CD248AA0777024BCC3282AB508406AFE7A759D1C4B50EF0CA89C8984D2D01E54A4CE39553C6DAE03D1C8D967677F08B14838F94DB68DACCC70BFF2DE96299BB680349FB8FB52AF7B069598245183700C4E18B89EF53A42FE5C743F8212071F2BEC116DBAFCE1661B1412DE97138EEE028F0B353AFD5B51BD86D9BD9B03A811667923977A78F011B8A706AFFA8EF300E174067B1CF1DDB50B7614A8276630F76322148811F2A7F01D65C47212708DACEA61A07DC33A31E7DA2FC30DF1A2944058457AA6DC886085E97819CE338F6D8EBFFB25CBBA70FDBE98CDD5877AAD8202A7B4E0FBD0715F72B4EF0EEED7845B76C9FFB5AC14E3855F9F19CFD42A9A238CF5D6B3CA9358EAB01F3CF656CE3A1091239CCE0F687D416044BF8387215F570318B64E09203E69D4712E727BF046F75730B473662460B5A21A246BCF5425F358EABF4A2EEA6DF8063F83603FB803101F055C9917D962A5A21EC6AFA19A2ED00123F4F71AA44A65572ACCF1734C0B1B43FB5AF83B173D3C59A83FF02F6A4D4021E9A73D6986F58DB5DBD4B12EF54DD4AD802D005E2C9126BE799AA1227477182D032F900DE72E561F4A9420FDA941E6FDB3F230C1536A5D86DF9A86F6915F32AF9CBDA428290E82266814E71C2B9ACEDBA3AB99165B9555AF61E95D53E460E0C7A8A908F20517DB829830DC53AA63A0D0B0ACEE0B6CE9775FA6A55974239C3642F5FE5C07931F107B0B5B9E2A07C9D11752A07F66E67E41CBDB5150B286EA2254E52E2A274674F66F5E9F6904EF463259C7AB6939EC9F0A40A9B9CB6369F7B060EFBE2A9BD69C816E48A65C0371CFE3EC5F0DD0B52A8BD5DD1C0044E98F4655C5414BDAE985421282845BDA5125B07C21BBB81730BDDE377EFCC9E22BBDD0DDE9DBD5CD484DD8B67C28A2DD3A3990E439AF2A9E59A355CCF42D9A64257B03E87D3C2E16EE774B73B27E95A87ED0663E4F1E7269AAF76E381CD374BE6C05E6770F8DCA1A4A33BC9E72EB2CFE33DC2BB4440890373CAB60706A1BAB96956177043FDBD5171A7D8F5AF980B33C2E7C8AA3E17982D1A8F552F11C272D38D0FE67B7893A1E1C0B16886C06F2B2D829720A46FA0869726BB58E6AE3E1B96DCA2531A41569F7A67990C16616C77CBA5E610B7B70625F6D88239B957942253595A9943B6632C8061CF448CB3B83B7EAC9010516D50AC9272F0DCCD0F6170232E3BB9BB1C4BD6790239BFE916FCB86AB7B55309B79B241AD3925E2D86D99F713FD3F2B17D084B110F551B2913224E1BF21118D6DF9EB379A780E59EF4BA35468D4ED4293B7E260870DC05053F5AF7E6D202DFDAC46CEE2CC39BBA4A4D4634AE0C19E96DEF7E2E3615E1AA88CF9B854281685A31326D9729EB3E4CC0D529998B05899FBA81B4EF093EA345EC025420CB48B1645889F5A862C38E5D92B239030BA7BD89E646E552F49355897A9A49FE383A21FE673F0327CE509493CFDFC441F96228C941449C3D84AEA359F80BE4C61CFA2AD4C70023122050D36116535C2E1666433BD9CD99950C6EFA355E5D920649C588711CBE3CF4C37A77A358316E066D9106C8C6B470746CAAE4043EEDFF32C6B1E85FB29261707EFECB59A71433DC1B11AE4FC9584CC9F534BAF1ED4508CDDCE702C3EDBE3C85ED2369A412CBA339C6B2219B5ED0154A574FF21D667C2E8380DD0A7E507EB8C098EC7B106AE57861801FA61BE688061B44C0C858CE8BF7A5CAA6B694B048456662397BE8E5E65D273DC287D0D403FFECBEDFA9159BF04EDB508F2B9D8ED19431184B657D8A847B1696F7B5F87042CD81AB9A13F690886D550513F45FD86AD96F03E73F7A88A75D48D8B855CD4CD262A33749D4C16799A3CDAF956AE286B436C669B2D02B0E0D7F670D7B3CBD764D1752706DCD02DA8005CF36474126818392FEF8DB81817B7C04878157D4BAB0E6621C1FE0A33BF1CB90CD9C98416184D31E3AA67C59C9107647C1B2B3672E8587B88C72F1CE3653C8ED94EC22BF6658CE41A596C490C21F6D1D9CCC8D9751BED750130F5C3ACEF3BD75070993ECD4B1EA615355259053846CA5BD3402677521BD251FA2F5F220E83871A054D6AA74E3507B5DAABDB69AF04CD6ED0D3AD3CACE5737FC596813F82E54D8FC1E312D3135F1D39B2AB77B94F0F6D1E6B1C831887A9BAF777665EF844AFA5044537F9164F7F82E1B326480B23E33E79A869143BBDE54953F9926AEABB42396768CAA60B1B24C93312CF7D85405C658AECC5D77E39C6A3D3C469EB5DE892E538825F297EB9EC1D2836355D79BE1BFAB33B41F68AB4AEEEC71EEEB8FC5610572E897D6AD2149104B85D5ABC3098325B776417204B618B2F62C5246D746B7FF8E164DE3F5FB1471DB54A82A2919757D8FB5B176BD4FD8E6F851D4FF7B534059E6EC3272CB521D62781738086DBC146DD7F8F3DF81AC26683BC7B3DD6AE4E2D2FBB3CF98E7D96E4E8DA4E0A3F5871D51791286F800B8289A85A5A335653AC1E84B7A7CAEC09357EB5738866F3566702E9D1D0148D4E60A82BDD6B9CDCE58E8D2AC534C4E20E86FED638926697550D4EB76C93281FA8B834AD1BEA2ECDB7F35FACECD755E3D7BD0D1E6259A2875D4F925D7C0B4A7ED75DCD20F87E3E1D1420E2CE20B77FCA02C62F420E9BC2E4C15CE7206EE7C1EC4EDECE62A5763DD55F8F58E2FB664D537F194A2BB67F547E704BF14EE4C40B81DF3704CE35D350629ACB363756F7B8CEE271A2C20B35BA9E3464BC65B951C39785B767128DF2EAD058F0C5F09264A2F703274E694118F459C979E6C6E0CF5A6C372A62F3C7C8050385791F98C6BF7F10FA6ED3151B26FD15531352B4C8297632443F884704217EF2423C0D138868ABF8318D15651EBE0AB227BAD9626D5B3C38C7A0DF1123958DBA4DB5F91CED964E2550ACB03FC56EA411F68D2EE3EA830DD7E06801092C38C555ABB6681708A42C6255AFFA2D431C7EDF2E3CFFC34755CF64F462259EBDD132385C5289E06828A619679BDA71B4B25205CE10E2F0AE31A3641AF242EAB08859ED96A3A0DA5AAEF81D6D419A9CCF024920F3302BC8DC1AC15469C93313EAFAE5A68FDCB36B30DD4F66F6A7016703164B37114C7330ECE4DD273E18D59E9F298E2B712BD9696491B5881A22DD480BC41C31F7457874FDC998A2108578EB65F02728FB4065EB22BF57205B66048D6403A4B80ADB66B09D979C69837F52163465A18572A926D53168ECD4BD6A1D15651AB2FD061C689535578BAE68F71493BDBF26FD0D3AF678BD01052640A76F63C562B17A0717B5EA9C5FF40995AD4A8", - "message": "A680A3CC812A9E70C717D53932683E2C519E3C67349BC77160633DBB69F42FCC0F411EB3A6BE9AC60F3BA54CF5F6EBDF47E698F55B3DE8C4334A8B1BF1AEAC6D64CA301D488512E99398A41D5FFABBEB7F2E69156193973F5F6638B8A82E5FB4590547B1E26A0EB0FBF989F27D472B6C02334A50620572AB7B128856360DE31D8B22648B67BE1FC97FCC1AD33F1352E7BC6FC68C4BEAD6BD90AE6F01348D7C16CDC805CF2FE7DBC9C0953A39C30259EB13BDE4B324B1E590F194724288DF5FBA05DED698FE66A4A022EA3D317BC85203F1F7E1944882F4A3610436D388FDB4FDC7B60115054BE3F5512C35195446952868FB403CDD267007F4DBE4E25BF6CD5704927811F0BAFE3234BEBBB889E97F45E791CA5655B88F3FC7F2D0047D17B30DE5BE02D38C7DBA325196F46D6637FAC4E061FA0F03B2160665048EAAEC50C8282C21F083AD5FA6E2A0CD086BBEF543559DBC554640DF2ED642AF33325F5AFF5A01B363A98D978135A73BEE318858B69937EE05ECABCADC8FCA7D1B2E954E1D8FFF91C3748F7A43A3A900101D6FF9545DDEC8817DEAFEECC528F223D13B2A36B7595D2BDCB59461B86BF0EB988F0581EE4F5658CB0676ED2A6E7809F132AF9394989F22F0E8A3B3369387F4D7295B3D31E35680CEBECE577B4E138069CAF54060C714F3CD366544CF25179A5DF23C3EEEE2D4E6720F5BA98C6D59562D73D94D2DE5E713674A2005CAC9902A675BC4D5A540F34218232547DB7C3EED3C2F0E604F7FF522C7E17EE224EC0998573726CA5A96863BD329CC2308AEF5E62C44F2D361E7618E251F6B2B7BC66BE5462DF6D0636A322F036F48B10D1B41320CFAA890D250C64D0789358CC589AA1BDAD93E4AE101E1D5D5C424283569175BAC30B426E246BF8478D8D2453F07F427977D1A2476EE63C1218AD791D43E25DACE7594B9B14299F5FEB43845C3035FAD56F9665B44E6D040EA66697B3CBD39B01D95489FB44A20FED85F0B472E4D278B05144E0EEE437017154904D240715409FC6693EA8E65C1A507559EB4FDE58AEE38AAEC91C73617B080D60575EF28537613092DB93C5F35F2A5164405F3F1ED1ABFF3FA94E868122920CF4AC35866BB4C5B91A6EB0049E1323ED5FADA5F377FCB9A5DDCAA74AE08B9F42D021E9273C89FF0A43D73BD88789B9E6E42F022075722EDDD372006ABF09805637478E580A181C61CE1B75A6DA9D17EE25664460D1C69A6E89E33F48EBCD25B97E0665AF77EF5D389FE3F70FD0B8B102CAFC27E4B2FE5C9CE706475740AC45B52B465F9B9FD2DA5D4AF75F3E637164C13A7FE52172410FCDA20572524C983FFF125A714589FB82B01D9A25B2BBFE92595883FF709B581FAC9BD9972282F7F770BA1B2CF5DABD5539F0808981ED9B973928054A3418EA0A4F504BF2DF358330972C134E5337CA6E92C8086AA5976FF89EA8CCA5B39F1393F87E64B039501D425B2610E1E62A4005DDC8E947ACE288A4108552FC77DE56B81DF968A33D98378C1FB54D2E4B707DE19544841A57218D6111925860DC2CF7A8546C62540BE54A61E330793A53AA3668F63F197F86AB14705D748877FA1ABC88FF90D871E97410BEC40AC56BA1EAE5AA0A428B98B5F7492CDE4BD82CA40E6CA8AC2B15394440BB81C7DF66CFC7F2CC25913C8666B358B404DA2CC294F5D89E3ACA8D6E7E1086D690B94EE179FC134990E0CE05324937360A9925B02AD164C0A94962D31193BCF3966ECF9DF9635D3A9A47A409B681E79DADAF022B042D4560473854C736AD8144FA848719D6E4D51CC439DD7041BBF90E109980A2D8A7882D88A672CE70116467C7E5C5BF8FF8373E41DAD28C4ADE06C9F6C4E89B15592AB03417121E1316E796B6285E5885FFD30934A5FC0367CC44AAC485D567B82A90163E4BAF53017BD43DEE3A489F88DB5FDC3CA0C5B56F690BE37A2399E744C5D10EB7D723D5CC0FBA0A5B5B6C63AFBEDE5E7D2A3D893957ED62117B62BB762F894AADF85E5729CD066A39FF0D5CCB2D5EECEF0016DE107EF7063E5D92C279E3F958A827810E9BBD5E94084E08206E2BBFB44DDC9F7F8831623EF6FA1488510EB8322F6B787AD1ACB98E8F9F1F82BDFDF042D5F3D1221628B4209262AB553BEE3317C0B62E5E7E85B81F0EB5A84C6204A1924F5066841688F84DC9E70099BBC83427EB71875F804FA34C87F7BB0E768E1792FC672D70061E995815BEAE11D23006C9C41ECA8997ADF96CC07CA2BFD10DFC6808D2D9C2820846B5FB2EFD89BC63C92AA78C1C72F61075D629AF785CC4947703386A759B6ABE45D091B09A1D74231C48C96744480134D28E7E3480D7E8D866953C61BCD8AC9291FBD41DB7C89EF40ABA8751353B39A374F533223DFCAA29FE498939018EDDA3A9FEA28DFB863A05A0BC312AF1D721FFDE4DF09A7C56913479CFA3E1CE4FA04BD58938572B17F1658FAF78CF3123F9922B4788B1CAB32CE255CD95ECEBB9B5297B625EEB795D3766FFBB4D9938E7020FBC9F9B83691BBE3464B1A4627EE120DD48A1B63323A631C6CAE1DD78E791940A2004DE1C86FDDB21A57291BB140248CD34352ADCF132048AAC2271344D53A7066CC874C7BE5502637EA7653830DDE94C261ADC9E9800D2A4CC8C71996149D90AAAD2890D5E7EE810C3C2DDC3D6C1171DBBD28E166E51E8F5D5C3369675D6265C6B3BF957FBA51EB4313AE070F6A867F322E76F87A63446A42A74A27D33194BB433D47C3EC439F51B6A245AA4F6037A883069BFC19A6A20E77ACD91F0C088E89BDFE6847120A86CD2A8F9E1D71BB161CC6562F61BA52BAAC845ACD7311CAE155C0B765667DFEFEB268554FD3522768451FEAE9ED5D4E402365E54511BCEE237963F144DA003606B0448CB0FB761F91C96C8A61344444460491669C83AE433E1850C5F3E4F1D4CF801F2D32A353D2890269F355FB06743F56D535AED0B726DE762F03CDFF22FBBDC18668A8839B1C3A3F3654A98CBA6E1B1EC515DFAE9556E9C7B0CEBF8E11BF5613800F6A2292046CB4E44326A0ED8F45EF92DFBF790E3DD0F08A3B8708D11F835CF4971CFF5DADFD848FEDEC6546740338D690AD951C4BAB9C0EC8D09089FBA2D0A96C14F0C71B7F3F74DBC4B9DADFB85BCB100373EF2CC90988E31ADDED726053A7C644FFCFCE49D9049DC1E555338029A5BD02EA4F4997EE6CE4BF11F583DD36C119ED5A085E19CDFA52BD871A35EE47F41061CAA8216D94214D5DE89B442CC124DC1A437B75390788AA0BBCDDB83BCACD5A5521450112DB5C68D04265A177060E9B3F56FFBBA24A31A6CCBBFDC9FCF18FC38A134B3B5C64321AFE1DBF6BAE55650985DAAACB8D576DA05DA26645F65A868FAD13F6DD109476EA218D1210EB8F493200F42483813DD781F15BCFD34E53A7112DAAFAF78766FDAA5E2B0865D85EFC2D75B4989E6BB43AA80B7E440D3ED41629F2EB6EE7BCBEE799929037BCE5E20035690EA7647D9AFC9C92B7B66FFF8F3A96E8EE47D994653B1D1915386851CD5FC1EE439D796AFE173AC5024DF7DC01AECBF9898945A3EE780787126294D5C19FE0AF9270AE5B341F7133EBC70C6DC32F7CAA0D2AF1AD0E535EF2F8AD8A6F4B268D0FBABB0C7D59D9247A3753F74D6AFF359CD2DFFB4EAF9B6A9EED07345899A987E315776DF8CC4F8A0979A04878F24CF92C052319D209A28727B4D8CCE3E29D1B80CCEA9A642C3AC0EBB204F137C31E77BAEB16F5B42954CDB0DC9A338D3A3C0D6BD80B976A07E543FBD84226D75264C2E7660720F009F38C6454A14A7035992ED9DB449B8505DEC10C06FEA7B5B82151260A69276816E9AF73909D48C8F149FA80F7DFF9A48BCC508D7036D9B8671C019C6A3CBA301A26B8D5E82751566B3143E0B70FD2BABEBB62C499418FCEBE989BE2F4B3FA352AB18FCA99B760EE90EACEFF05985102FFF64F6471E4E2A9F0518C4915E1413A3048790811D1B00E20D4A97BEA7F204BE1B0C435ED2A7EA4BAA19B49C580C23965B97E26E432B2C32B3D8FEF889C4B8C9B51CAD71BA6F3AF6F5D3BC494DB4BAFC33218360BBC9DAB88DFDCE1DAED02F56530251130856B7DEF89E281DE3BA2071F69DC8A92B1BCC162FA5D8724E33952DF19FF37E36A19A0BDAAE7C77D00A6E66700C5133FE10F6567087C49252928D751608184210A08E47C1C6CA21623C9DF4483B04DBA8AB3619E2141EB4F96BC294DFEEB47DFEA6A184E7F9EF242AE87A9F3CBE0E25275D53DA8606F8B2256641B0FAE509ECDBDAA246603C28FC85BC10EAD6441B3B1CBD89D9CB805890FD01B100F664E04BC340D357E91AD2A1371F6AEEA7F5B3D6773825DB30DD3DAF328B6132DD601BE0AAC8D09A1A82633298BAB6F93F8B2C5E348E6112559B0493EAEDDA5C5D7B5BEE189A79C443F864E85A7B763571189D1CE7BEBE395E348B248D24927F6ACDAE0EE02801DCA8041CF2C7CF46D0BF91C87D6D451A0B8A4C162A7711C860EB2CA7A14C25C739860A51F1CA3875645EF23655858DAC026EFA34B76197D6F9F5D72B4D33A5D2F5E74DFB095788F5BEF387B24E1BCE481669DB471F1BAE877103A97ABFF778FC11404213DD9405DDA6195065E918EAA3709712B62FB713380B2B8F1F352F0F0F5970DB38BF4EEF392FFB0E3253A9A30022DEA9CEF6D26CFC790152BCCD35D8B44BA41F9C190D722A6619989CA39C395DD85C450DE35AB3690CF43631695542B887B1CE9D078B6C77EC8D19AA4B79E0BF32CC121FFE60661A31171785756EB78FC3D406945B7C29EA6C336E4964E4802479BB9010E5069C9E462A092175C8BB4AD68E9EDB9E5A7AC2DCF7168AFEBC344A488D4E30B98E1E52AF94FED64EF6E182CE5D05A93ED8A1C7EC49AEF3694C2334F04828575B79A7DC27CDA44022671C8BEA7FC711F1348270E499AA516A362053D5113D5B82CC02857EF6DDB159966196AB0939899008563D93AB235E0F26D2F58EFDD6840DB7851409572A4762262C07F7A9884D3BBF51BB954B1317E00BECA94E3FE7759E594023566548E1B3EB78A6B30359EBD02135767364DD4DEAEB894248EE32DADCEF0B4195586E6125C5106288FDF3695E3587811AC45499AAE58BB4D66EA6D45E01A4B67CB82167A2404AD80E782376906FB0FFC290DC81957809B6B010B1609D2EEABC7493D90F255A11F745FA11A4AC4BC597DF43F338BE194A45C746B1B43780C2101CCFB265F79033C5D99A9ADFCDC10D61C4E8F15F4F078C26F9C0AF691FEB81E0C9DF65A9BD9A80D0A342404A40341666BFC1AFC9719BFF827970007860D70819D4EB13D437BD2374B272EB3E89F5A70A49104017F566DBEDA39D66E10F33538E70DA4FE74E5F76FFD9A5304D79A32FD0511FBBC46588E424D25223AEAD0D19E2C064E1B9D5F819F4D4A590E99BAE3FD74C13EE292613E3628425EF58544B957A8ECBFBA98A7BE44F38D1D858EB784AB1AA87FA4277A8BEBC0E6C35CA3742D6AD0E8C51D65FEA5F465665C1E4DFF1DEB9E026AB2AF8A3F6E0924B93E9B24AA50AB6B85ABA222AD855A2F2E67E894107A255E814EC4D9D6559368401383002394CE45B35E7A424A20512E8C85DFD3D649383D3FBFB879955EC9FFEDED42FEB3E7B50E3ABFDE48B7641D3AC759389F558155821137E8D8A2080491A732A6685A1988C42534542CCC497427975B8199F0703294559D173CACDA428FECAB922C8BB59549F329108715AB20297494B2E598F03C3A5F321DF0627CEE36BB6AD7EC73E9BB4A411A8A2DAB91C6728D7AB99A10FEFAC498061647FFD6647E56BB18DC1DADA32E2FC3E393B4D540757A1CC7C7FB45F1D447F59A1717EB0D24AD3F02EB07408F5441B4DF02D242B9321D2E320DFB11BE59A61F1DAC02E5E30EC5B6D56E085DA3AC2AC3D8B99E98F364A29DFCFAF9D3DB83AE0A49AAEDB9171A6E7E9AC6A75CD01A282CE1D7946C64EFCA0B661AFF518D607C7CCAD878CCD90B9A6D260388BD7008B7FC4C863458FF79E2C177C7C4B287948123841765871675B3153094E647B141D22BCC87E60E830193305F8F418C20CA020C4A39FF423484843295B75993A94250B954E57C89A1CC5C8459990B9BA749CD89288F8A01FB2610491188DAE085EDC96B2AE9D6ED542A9CD43BFA6944CD95BA7098DF8173AE7AA22AD3D1B33DA0987FC3DDD93162B96569A902387C9D51E31BC5C57B7804B1A7445B4C8F53BDD39F0DB798BA28E85B80EC11E3321AF3D6EFBA268E87DCAE4F177D06C28CE3A6774CDC1D2B528D0B0AA94DA229C81C2FAD07E73036CA0AB0BC380926C53292A82216D9FF62C8FABE1FF0F1983799E6593D4338543406BC504C3EE62510ACFBFB42853B10225A73E65B1C36F31B56EFA25E1AD2C12DD52D5E27FC59D5AE56DA56E30CEF273C44741005662A6264E34DA614957BEB02DE0832AC7755966A784C867E9BD668FC0338D905D5A03607D9D67C92C44DFBDC59F1BA75EB2A741E79E6A59C313C3B5FDF6A61905844F4997D1DD6EC7310511DE9B8BAD636476764C8324ACA39B425B0C2EFA2156AE59414C8F1BD528E3D50C3B0DE5057ECFD4F8180CC76EC58BC8A3B706429C4D301FC3A0FA6D486C9E7303E1EA386C3EF9614EBB376176720A3BB9C77873ABF7C6F6637A240ED00E903F898339690145902C2AB24A5333A399E7AFDA7BE8AC18064D5AEB7DFC6B1413991E7B051069AA1635B0249BA23511D1E1768F12F3A7AEAA8E939313177B4040B6648F6515850076C2CE239756A699E06E02E94CABDA781873809A10D07CE459477B424C157FE4CAB33AED7BC0223B28B4738FFBD487BBF8A0A4E4FA5FC3B1B049E3B981DF5E53EDFEBDC467C328BD588AF9D4922D2E4CF10D119A796DD3888792B0A48D8AB6228905AD1A1188C91A4B1E42DDE84B4460EE614447F1D7699B18DF5D20DD73DBAB58E21FE68E1CAE35551371D2F8FC57D4C38E1859261F04A8EC3B26CFCE1E2DBCF14BCA401017FEF6CA6A66F68055C64F9F1B3EFB20CCE723223FFE7D1378AFBC1A0228CF3BF6E0028949261D4226E8DAA84A386DDA37CF2A1B0647001A784FF087A92D79207E89D7890932FFF6F239693008F553692765377B594DC5CE690BBC391D1F7B9028E3AD9DA1953F7F4A7358DC05692634790D9724CD92142C17791E48A23A7A5B057EA92F29CC76BE8A051D7D69ED4787546E63876A711EC202D75A1853C97457F0C2B94CE07AA2EC94F1A5DC5426F37191721226926B1DBECB89A9DCB91BB03FD171945D5ED8F9668505E2783FDA5BACA4132413F955C985200825D9E127E28779D5A6BFC39784C5861B7C6BE03DC6E1638AF49B932A15882167F4E39E7F820161D2A606BBBF37A8AEC73E1EDDFAED14FBB4596329445A2FEC527F0B30338CB42A5A56CD42B295BCFE2DEFED49F1EA906335271B33AC5BB89FF8C9417C35C69EB48800C88B404A12DF8D1F850CEA28A5A3EB3106C2314C2B12E21D9CD5653A1DA2ECD772978E8BA43BF95C7FD77E9AAD959EB6B643798B9BFA984716F4860C2BFCE6F3A797BE345AA184705DCD46B369F90222D19136F4A6847F30DBE92D28AC4729C68AD883AFC87047FD3810100B2B6430342D324345B371DC3B4786B4A29ECC806DD872279A2D2F5524D6FA6682BFB6B7808BCBF53CA4F238B272B0DF1DA52EE7AE92DFB1E2E4BBF0126EF837EC245EFC169459C1767B233D8A551C462D41B41D1EE69AD1ABDD4BDA4D32605FD28C8DCEC8EE10D1B23DCE49647B8F2ECEF93282CECAB479F317DA37661C0F34B497B91983DB4F6FC472E7D3509DF98604B1E64C7724E78B9601AA185DE554AA111EE75E0193E0B545B9A7A6565A8B9D30382CCAB61053ABE5BABD648095297C293E3DDC3B29CE217CAC6CDAC0DD4643762ABD87518DE84EFB1287DFC56D51B2947883ACADF1C7EDBF7E48AE6F5EBE7D9A72C1E257CDE4BCEADBDE03078DAFC54ADC398F4AD0C6381D0545463AC32AC9159F5D6522AC8EDDF7DE8D6429E4E304C473618A27D40CE7E7E48ED69BEC8B684FF7E7FA826438AC56615347C8AE2C9BDBD122C62B6AC10D89EFD95B48E53F4B1646124670CEE5F7399CF4F8D186D7B14FD7BBCB37A1AE624E58B9786B72495B5A24DE906F6C6397AC6A67D9DD1F56335834DD9230897FF4E681B2E4568251A166D20837BA2FF62D69FC44A79694E4013D0FFABD23A02D525C98C06589CD93E1020E6EC110934342F1F1326DEBCC8DB6E74CA1EA7353AFD59328CB0D72E81E9C6A2074244BDB4DEEFA6E10C375B07B2796434DA869FE117622BA9C5E823DB102C4B82E66F413FA34E51BD884D9C2902F775D3B23EAE35488976838460032FAD2F2EA9605EFF274D177388BBE76A8EE6B009C818D00A3ED5ACE0E5968F5616D70CA5F3DC82D90CC08DA4BD7D83E1286E0D12DB77DA3C52230B2C3A6ABFB5F2D4F00C9C0FD99CF98B81A355222D4A02E64AA54C812B07E4A9B4CD787C658D63E2C7EBC786C873145994067EBFE606F084A8A0F72397B9C0B8926582EDF68D92FF633B291DCEAA8742C9E33BEBC0770E37BA6F09F88DC61EF10995304FB5DD3DCFF23E37F53EAAF3B19984EAB5ABC94EC3B438CA345C853E9A3068C8C15C20C7B399E6B40E3BC36F84A3657ECB614E59D1578C707C90D7B5A74D72B8AE2F961717504B04059BA55024B55B0B122C8B0CE916F758743717FF9EEB4FB48BE825E0AF78AB576D3870C9AF01A7949076A0F701FDA1D30F468FC2A7B93D75645551CC4AEB82B2248D0A8BEA079E03F9BFB9DB61B409DDB56FCC312ACFE478C35BD14E05A154495101AB0ADB5643DB77BA918B3100D135A3566E9E35D3B4D097E5E12DE315BE8B4BEBDB32EAAC33230E0205DF9F7C5DA589B463C32D9F352D3396B70E7A51DE7C9A30088FA55AEA071A9B3E6B01E8664FF45C7FC19258BC537A818CD5B44DBF4C6D06C705CB52020876F61CE9F3B0AFC06B6C5C3A9E4B836136D3E1A76261FE3685321BB0A8D2BB51971D0D16BAF2275C29EF37B284447E88B770D787A39925830DD7DC1B0CD8AFA21EE17F1CD33BD20E5B844088E50B0D614D27895875DA32163AE1528D0183E169781CBE92A6CCB040C94C61D5AF60645F64DD9EED4228BFDC7325E9847C9B5BBD5AF0E94A6B723FEC15CB8034B7A63C2465CF295C403B5A61662905E6B9C60C4A81187BEC84CA2E8D3ADF299C892606790BA24A89E6DCD6D6DC6D149A0079CC3F680A5ABD1F48C6AF580F39171137CE7BC4055F85057454DBD69B344B7A879D73F63AD458A1CA7E6B284FFD3BB8AC7111B88E219EEDC2793C62FB879EB4EFFF554AF1C48248860AE5A34D487EB0B7D75E39E83A79DDE865BABD1CDEABB022B970CEAEF28F0AABFAF208FE86527D375841A737C16D5FCD043D80CF2E427912E42AA0C6B609F97E95FB569A47E125E68AEB5F58BE944D593685B7EC0DA0A6518C50DFAB380723B89A65CC0EC79653BC298E6FD4940662C4D5D9CD", - "rnd": "CE94E2121CF82C17F6D50FB575796DFC8AA8070A85839687A18B7DA4C68F2DA6", - "signature": "F04427816929E46976493FBB40085EC46FE0C543176193FB2AE8AEF24ED1C7E03A6B685C7BB038F71D8581653A0ADF0D0945CF2C02958F162D339029F9E56A11B4C89799F3A3D18CB7F580125FC4EF62395FB0B8268000C3472CE19C93E7EC24AADAC9BE4CA0D121E0B2438F15BA0868C2DDB17D3FBF49616E64DF6DC09A67483EB37954E0B307BF6EC092A83093D360734E98C00AAE8023887A4873FD575F22F935EA143A0536A9F2CD5979F667CE06AFAD2FA3C20F51E88F40F6AAE1EAF1A464777C653E3E2157D84D59FFE0A4DAB9F2A613CEFE0C2327CEADF3676D0B5FBCB022B9AB1B48934398464CA65270301B9DC0F4CAA8FFFB21238F49BE0C29E42592B36BE9EEC2B54031BCC53744EF077EAB0E163D262DC06D808E21A1039F0B9A11D533183D11174AE630006F6CBDA1CF67A97E36A5BAA3D8578514F5C87947E5B4B785A1F140439DEDB3653C9A20C4182B76561B6F0B06BD41AAD10A3A8B6FC3DCD7F78662ABB1836FAC4C75137113DE0E23E04B19AADA03728A420FFC77474D9798EAE2C8152D62FF959CD9AAEE2BC1B45476519351DD0B0E46CB55A4B294BC23615C1172C4FEDC5CEA8D56FBA40A67AB5A64694F9B9DC0E35E51C0335132295EFCBF10C4D20881FCED973803071B78DD3BB8F6E89BB481473EDC614B526350563FA3761E3B4D6F60C8D0AD1ECC6311F333F4EE9AF7F281F7F2D6BCA29628FEF039CCC29A152388153E6BCAECBD67E524EA48F3A8374F36BEA4E7E01E45F251EFC21FC41B1F8A111E5A14D180B3CBB4FF2DE7BE12D4CC0EE7D92124CCC694B3B02583180FCC449CB557653E9086A4E0B3ECFCC11DA2673BF0FC6F23CE2336F8277237FD9C7B6F6C82D24724EE80149DC60DBC85768553C581A856FAE2632ED9DCC9EE1E446211C45C8010BD0EFFF89877FE1DA6B1F2180A2389299DC75C61F52E86FF9C545681BA8581880F0B815EB3A627ED97F4B897B88D6928DF9D6456561335A02FD93C246387343E8AF02DF6C9D94F3D5A7CE92CC0F3F722C4F4DB1C274CA96EED6D88B16FAD7A01B64F1EA9B6338F844BF4F4EF85286BA0F63B5C2E2B0BF9D815F802D83CF7884A695325724A2B97500E049A6A19D5CA691DF339B0C8045B86B89F8CB24967F56B8C59EED7E28CAD5A3120418620F1E193294393E012458A4D57653A4A19FE4582528725CB0D30E48700CD2035E2B166AE521A9F2E729444CC4432345E6CF542055AF999D2402901BE8324C81CF16FC0FD2A2FEDBBA387B09178FE1F65A28B04FC0C87795AC94F3691E9F461742B71B122EFE83DC8F0BB03B5163D0145D4B298E1CC544319EF11D6BC15B085E1152C381E446C8F0753D11C92F064E1CFA292AC4FE923D4190B0D02C25577DC483D2A133683D85394231A6F9775F1C80CC356E1E8923E4F5E1A22E4C3D57B0007BC150023E04C754A867A5370324457784331EF8F2CDE3D955936B9661D483C7BFAB0CE946AC6170110D36FA4AAA6D2ACD7B4FBC2566582BAABB85C1323B9F69B3E3167BD086E7725B00C0F83857E2A328B75B25EA056149FA0C9C3B60B2F70F2F8E765DF45D0C49E951E42E11099EF572EEABC78ABDED2A8DDABED09E0DC222C3AFC11CBC57AAB2F47653FF371A1D255EDE5B1B16140C893C67995D5DC031FEF39FC5F7AC718B4F3BE4DFFD1B5261A1CD9B3A823513518A8FBCC7181226157475FDED57C1E4E323B898673B3D58265C982DA36B49463DE0EE4BF7E657D41F1B3E1AE7881E93BA7676DEBE3A8A394D5ED997E9116BA564A340233C8F0E3CFC31C5B19B47D4971B02D5C570351D1D50391A312F706FF21414BE3BCEC519FE8B678FAE02013677DC6B3DCF873406598BA7916FF90EFD816280B30DE43AFCFE845363C0094F60B4273C5CDE86AB29EB3EC52224EF4BCA5420FC288CAE4BFA4F0037BD403146304359730B6505B45AA99E724BCF1C0790D12A68FD34BA081FDFF18D8A034CB009CD23812BDD7000DC28BA7DF884F93D106AA74A7CD76ADB887B88B691D561D744305AA90684582B4F2C409B88DEC8F17424A85DDED0552BAD8D0EADC3C1543FC74552F2ABC81797314638A9AA63B70620E5D199732C02745658191E84662A9179F5EC54F829A20A214AB6E82FC550D5DB5CC6293C771751A3A79844D9E374D1FE88C9C1CF1917CE91D7E51FE0D1B6F91CC58C81579AF70B33CEC87BAA150CED7BAB34A2A30DE9AA380D3BC5C5DCDA6C08FA7D024A46FE83D1750E2EF108A823A058147AD3F08AE7C42EAEACD99D2760DD9A1EEB5F9F02F585668A0B170EA05F002D5A1DBA805657AB7F9C1B8AC6658A250417872830C79EBE65BA25DBCF872B370B589CD65D7B29B1775E1F20B757997F0ACF8336250FAA93D5B3A045C2D2D7202FC9A9A8B2E53F27DFBFDBB0281D5FA7EC24D31F88380867A6614215D12BD4D095B44019EC2B85253691D6FE38E9FA0AC6FAB58F372BF12158FBA322D0AB42FFA41084290AA765773D36047D00333ED9DE163E0233EDDC92562AC59800DAE6E08C93DC1DA54B8C8AAAFABF673D7045B3E31191D6B48B77626FE9D1267A94069B59EB5088E5FB913DA6AC08A370C07A6D33C1D36DFDB9321D771BA01B597992C02F3270C7B7F9E4F709485A6473061C70D63EC08AB9E972D4377BF43659565A0E3AFEB111ED5C3D73F745D7ACCFCE1AE9B0C4F913BF9D12AF2BFD9A2F13BFD8E350D6784E9FEB4747D6087F7BFEE63C826358BF7F1047DBC4F0C4F282801942C4415B05258F0947EE19AEB8F69E39DFE1D613C6B66B860C8D47B18A9E82F10D60506B3AF821244AA255D83EECA75485434F02FC4D950B118B01769B1861A9A0AB9AFAB49974FCBEE56413758065414E8C8F370C406353B6FB4F1B2AF55AC83C330166BA59C9386B5481FDC9FED546CBAE2941B02CAABA62E572AD4E131D8BA39D1B9541E4766BB8EFED6B6FF0E09DBBFBF02D490ACE4D423AEEC4597A52BAE780C19215B57467B50D6268C3BF8D24F08F205C1265A2627252C5F57088A706BFBCDC4519FFE9B16ECD2594D0ED2380741E6BA70D8B13ACFF0F439A773260C817031709CB0CB7A1180454987884F73A30374A7FFAA062B11B3A6245CCAF114010240E1D0FB268BCB80AEC821FBE4643FBCA1386CD51128CD2D679D2EA5CE1D25741849E68C7B379EBEE5F157AEA1115DD92522497D718CE9E53339F37A95E6855390F1D29D73387236F6FCC5ECF85E90EC3FD24F9542BE8783ACD7B57EA5720DBC247450AC437D3EB426B43DCB4F48C95F1304308C07329D098CC6BABC59B91C724E4805204A0F112457E7300AD7CB67BDD857F3AEC1DACF123D903405A61C8AAE90002F7C6FC2882DC0E4186C6BB3397C48F7B798D863A74F3875E442DB517DA3F411059E4F48931FE0952687BCE338000FD878A86E0DF10558E8E7A337CB9E84FFC02F611A9E34C0592241A322805AAF95F6EEF5C862F5FDFD631D190D0A34F0523218801A2E3E6E00F69F9A9C7A023E441EB03495FE1C2F2BBD24A8BD77EBC81456991952BB759B41C8F8EE839AB7C19AD860E9B4C662B64A25A54AC5EC46ACE968BFA4A09AFE586EA6BFFAEBB0FBD0C38090C787D7CC64A1CFBD09CDF59E162CBDA6734CF894954A470DC6E2751AF1A2D59C9B0B5E81819C86FCC4DE401D6021B382860F302284D5CA764972F3A06F7213EB814D352353D0792E96002A0565ECBCE3BE278192A4CE889FD413BFC3C25BF89C8E652A7B4BAA2D5708E3C285693E371D35B6B91E87D776E87D8353D90070711CCCB80486A07EBCE3888A07FC6B64E85DD9FEC55E930D3E75E60F58C8CC479851698D7FECAA8A9D41C010F5235B794FC232B860B9E1102EB0BF7B26E40F0B385B3227B81B1932E77DE9F3513A42D56E6E43D74A9D88DB50419FE1257B865F8CFE2BBA67CA84A59A4413A119CD326798F754D96B5F349E851F25693B29F297749615FCB4BAA0B92E439FFC68C7459822448667AFFB077201D8A698551A0FBC54F432D5574B64D6D2582FED442E39EB8CB7782B815466BD0AC1778B78B96CAED56602D834EA5273C1FF41631140FDC0AE35C30428813E74415D3F11D551D796780B8727E25687FA5C7BC43E1B0734721C2E8C03B9510249AB140A1AE77658645C1872EAEBBFEAFA86816A5018E2D1E80154BA4A0BC0921D5DBCA32870A8AF1190884A88C9373E151DD2CDD4825BBB6F1F61D494403689B87BCEBE92DB32965E4ACC610EA87850111B5262D945B5EE5C71C34C23515E445BB55832464B4F7118CAE3389BFEA314F4E47BC94DE93CE3FC354714097DF82A193866C5A66066F9D5B14DB26DCDFFD86B3FB67FC8A199724FE18F91328777F76463D1F93923F73CE2648282F2E1F236444C2A3B73EFFC29694DBE3CB28A3F183ECA714C29E85ACB35AB0DD478E581928AC3CC1EB65D5F49667A9D9BBA0B3ABB5D3FA046744643FD9D1B8E1EB1E7C062B394675654A1FE42B82492A089F30748048C3E0DF7DACAEBF95CD4D98882C91F6882C36C9E459962962FCA4B31465B6AF0AB6D97E5896F2E66D553AE9838BE152AF5DA4191E4960548E1C9D027C5D55D03F0A71CC5652D8C9AAE01196B011C2E334A7895A9C9424F55588EFEFF02223B6D72CDD30F3C4B6B96AFBBE2586D7D82959609181B344269717679D2FE000000000000000910171F2530" - }, - { - "tcId": 36, - "deferred": false, - "sk": "4C9C0B3462F8CD8E3D50117937B34A0F5B53D764FEECF4E318DB26417D0EE37E74D716BA37492557E9C7ED7A1527A441275F8F0F41C2F42A45EE7E621A0B5DDDF344E7F62C64E8BD19D8F9A90F33ABE2B6F838112C4F03B29A29A675418F1422561C07CDCCAFABC3A9AE362290B977292E15CD20DE856604A9AC6F6B31F607DF63714655458467444561266141472500520485522481048732358760657113161827474281068181564576512354452008102656877300242027487145266532423335122840154134185262623737324065381854374182615541621005053683573708528363557333253402356853835446527180775340833370247860722575064281822175631505345077204461474383685103476702113527056154155543713015151524686372714388603047568751442038506806054761854572400484848724568428113736062614111803556452364603074021646138227154278458021701736414710453662857508416636701808462628083687348006006743311187066057812376803381858163872268558423157284517867241054805370263847180662113222804302730048331043876800133561770110418620460445578647658344830875125006131327683000831130144074062568026783187205043264765777266664254403613847570154541142542373824771137668170742317132176085120766848366375652744454778727738682442604652416014861416713550055225040114421566321312557400251543546488705840256326635118752217244235487200080441887217514325350263384677788640616170351007445782528057580607506484537062533844115406538055883564081118353860271478083465256650444481468183523024301787565647661386728731243222466566177231476444128207458206634686845784445558307786564825568110867337816412187555304126306411343383088062377701740618438863408158885676217683108252670254155453342385158237116740672811248766806166232345863617552115564282022350208570775151353083880116481565214233673614270174263110463681326860003084103465502620423575327515528644086817075042376118334346512167726255867863456070533226665654150354527525143605776205124404468375123401431722742070161373465055421772501584878070827272117876580342254405060653360043688736426537437841022343020350303683672818331536887468142164777610374705554221388170086363442714571212528680766236703828574082705324570848366604765672711154223633200558463468241638854655764135502826441101747700207125870273273028832571656557315104312474667218277726484517610542728703525604466748383056881005551381083766432572038885887278400103054412360764716684305602046730457512147841221363462473412804067001513320745821735142140230403051068446566061766381218713655568847558051568184413586072821815486858012638221574837236180754278047660177782405357858381055383056234614415427653473443068583012611773142158467213431113545512057132760240758261527344460863285764546151334315432263545367700355176184421676366444683550353546838071437364443005384514428870261466008231503178843031543172600072805840526168532651386325425774702621672736880075202500338546647263666482835540855821776615537527804030556822868477215344541612202551311150788526824138547082026658838402857373812726147256150525865124720830678106258521136415154214104771817271716320431816261788720730056458610682663867625540720757246008137463272574363848874012064817848647203350144263605515551023610652710564526364001288712544072865678840304622B0733BBA616D7D5AD1E1A6D9C95E96D85A9368E9F7A4DD68461B62CBB2A339BE4AE3780EC3C2D2E3A004933646265273C66E2CAFB97A740F6FE7F4C77D65D8BE9F8ACAC1980850ACED4896D3160C48D0431DCFC73BE8BBE189F4A5418F92F4DEBF397CA654EA0D2DBEBE8FE3F53FE8FA50B3A08DB064C4C75E6D4A9F910CBFE2C7A096D09BB85B83E0BCEBB24730A5AC9E7673AFE0BC249411510083EA9B2670596ED9F211CABD3094799DB50CF6C964B6C21AE8829237F4E7032CC24F5C256BE473953670A6E6AE40BB8D014FD5D39CA9AF3AA6DB4B1417DD0250F116BC1D0D215BB63C92A7AACF10E872C99EA49FED9E7E0BBDB9A092CB6F9AFA3221C4BD1C21F9ED1902882F9BA2CBBC203ED4CB74150F179E0F17315949152AAE495F2FA99D2989E4039B68F01869CEADDE531464BDA43C63C43C256553D8362480BA056FBD2630A6C6459A6FD75920B4B58D8252F1AF8899E7E7FA73498658BB91D1C3FADE44E0DA39ED266C1F07EA05C3325607F63F52E06AC710753E2C1D698969B950A6FF864412AABAD169D4F5806DA10D15E9F831B4E1855ACCFFBCC3A05BFDD48EEC333EBCE7A63720C1A4875A74B17FA1744290C88FCA56560293B9B6413A973B3A2AEC483627D52B728CC7077FB1478B5F248A9007D1641089583AB28171D03B80D679FB050A882AA3CB87FEEE2E7E13EA4BBC1BA8E86B55B31D1EFF6502C640B1F3C30CDC2B444976230A0BBCA65F09249D6FB61A8B566375E82F9B981697DEBDD985E51DA77337BD91FC4199339A6D4EAFBF32548F03064553B399EA41B58A9660B9498A00F8AEF6471831D5DA93A02DCE2E5BB48D3195B3CC6C5F69817FB7FC20BED1A7E3C5DB80F7DC9FAA4D206F01AACAD5687B9DB01F9361F78A7E7DBBD45E657F57F67C6AAE06B58086F4E4A56CCCFF068694784BBA8F53EDB6EF8BD230CA06284BC9393F1B95EFB2C2E33BDCDA7192BE15823EC3F2DEC8CE95C514DCB51815D511BA4EFE5A78588DFB0601C5699972FF1148FC49E07AFCE96404A41AB478F1002834D6B173F339655E5DA4FCEAC1D53E302D2988FE1C3738017E7CF9FB6D2C546E813D874313F1B4AA132F24B9E47396470459C1C8FB0C526A0B614E3DD115045642BF3D93058B3AA53AD70C58725DDD2757ED7E53B77E69B09F5E2324818FB87BCA4A6C6A184B29E5049F3AF4CE47F328B7225AA47A96BC3F8F36846B916F2B940091940266F479ADA30E91B088AAA54F12E704D68E0E18B3C0DFA2F5BFFF816CEB2674EC6B1F73F07D818C5757C4010E247EE2E4536BB964BE5E3A936167152DF4568C30226B8E23FBE1777570FB95D4D5126433D91ACE47BD80F0D50F7591414C7D2DB7B43D794A81F54D7EE340C1ED628DC841DDC5003FD5B4577D33DB02E20423EA59CCC88D35655E28A952197BC4D6A6584EFCFD2594097716EFC9A9E37BE43FCFD66D7D4428BDD3D998A76590327207CB391271459678C7E2D90AB7DD43CA349F47AEA46B659FB762148102D871F9634D3B2AEEEC130890C42130A6C37BC4D7C0D3D71A4E56C915A500B54B8257D0BF45CB6EDCF4B91E2A78A9C72B071EAC33B5CE3059162D456D8F2595B9BE25905705ECAC733ACC9A2076EEFA113FA710609211D22416566D10CDD2993CDA1C888B32850738C8AAE0454C2C7685FDF5444F93442EE198975BAB0780ED2E38A5DC930FC1F7ED64691F246D29FFA32C5B1C6D0EA5E45002E9E3BDF3870FBC65F0A6F2F231F79C1441C1399AB35BEE1C948ECDF8038E045B87958624BC8CC5DE5CE8B5255BC9849563BC3670BBD880010D6E11DD02B5FD4E92CD38CA62083732F80DB497F2CC62DC6F63D19CFD9B59EA47ED15C49888EA5BEEA690369806D48D7FABF14CF5B166D374136FC314CB41F48DD75E8E54207ECCCA8BC8C3A8375A6EEFF7E0449561CDB2D455195ADC56EA7C0CEC2D3D979846574ED60FC2F8B802DD43E15F9EC2B70453051F0CEE47302EDFE72C9FB4B4C9C365B672CC4D600A61150E244FBCD054DAFB8A8AC8C8696A02A5E765A26E67249997792773EE58128342FAC7C28CE5CAAE1CC84299AA25E43700AC675F45FB765D024A4CC5937DCA5D2DB84861E9913C0DE96865ECF5D06EFEA667889CD52C449E67C88B78208C7ECAD4A94469852011FCB0CB6E842224130ED67838CC461E9530B09CC7C257D08A9A432B084C16D3863DFE31E03CACBC699EBFB1C135C0902881758E41E2F3E4F9A590911E1C3FA6468EA1464896121418643602ED8A93EFF6AACB8D27FA0B528714A9E62419D4347E6F5E6864B3298AD82207BDC32923F5B73B24BB26B8493D57966A7562B14FC82BAF9145A37DBF2AA0A2605034B268EDD25E10C74AFC7FBE86231032D1548686942C0B77A1649DA90B98EBC4B02E81FF43C07FAC77A4392E2D36A6A45776ED617C85C728BDAACB7C09A0C7FE04AA64FEA26AD5F88F7FD44E5AF23AB787A2D4F1EB63BE344253CD556E4E62251DAC0B16F825108F9051C37373A92962A4C7C6C963218F2DB69ACB6C0E168CEA66C453B9E36C337A9CF587D8A390448B38C0ED7467DEBC3B85ED07C59E6D546F614C1286C17F073760C5D46628A2BDCFA558F8995A1CD91586F5B50A7BCF75E09DE0A4D11A6BCDC62D5AE2E49906FBBD06739A6A9BD57D065971F4B94E1DFBF69099543212435FFD80F41277D065CBEADF4C7FC3834E0F6185F6AEF552849121734EECA8E89A77F21CBB5A737C68BEEF0C715C98F00131445A602265FEB3E9EFD9339D4BE800541AEE549B0090D44693D587DF5887942BF8F6B54B2B261E16E5A4E3EE5F5FC984FDA7E7F00F0B0B7FCF10AE19850B455A0431110D136B106951073D1C1F9FE1E869903C377D4B3C4EFD3D6013EE9EC9DFD79B7B2A17D18B1F6926F3AB598F01EBD3FE2021C62D6004E5ADDAD874E94D5C2929F90AAEE6B9DF07B5EF869B6A2C4B764CF6EB63995AE6D2FB46EB4E74A12672D73FD52ABEEE4C4CB0665280C4BA18283145C329F09D13FA223A208B5C1840306C59E61EBA6991457784A93A207477E2E060823D4455C2852B644F23386E593DA5639753155E3196EBB55003C42D79FF762F3B36D127E37B565B3FDDAF4586D0B53FD25D6B6CC6AE834B51818DC52F252513506D5CF74FA279362BBEB250D2002299EE160A937337CE0715B8BB82F8CF44BF7C90F744E935DE6EA054AADDA647C6D6F4D4D4300730B94C65546FF079A1636FD369AE09880C126517F58F58A1915DB9C260CE2C4E48A3EBCDE52BDE1D64FCFAB3BC89E65643D916A6A26736BFDC410C33E8B5923E7094AB98A62BA305E35A78B227951B806045B1C401369AC8006D77C5402E1738707218C385B8BF0358601FFD09A1CB3F0294DC8BA0C7A548948D6127919325B8B49CDAE0473FA89C211CCDB2D062E1634933A4B25E72E75236CD38A9E99FADDC594DDF9725EBD3D04F93D49B68814B85AF820B733F45106C4D99579EDC6B527FB8C791E476B76AF0F00609D3C2D97A8E9141B2C8AB7E8E5959", - "message": "E5B0471D62EE751F73E4AEA9533E3A792885AE91B975013162B6FB0F099E2186952E693682AEAFC7FBF383124A74F3D330D37ABAD5C7824FE7CACB11B57013F6F6F81E46116A4CA23F83593CC4E8FC2EC7B0801D94187FB4757BA1CF51EE4A543048FB46A2BB84B0F00FD3547CF8CB88991D00FFC5433EF23FC102961B3DB112D7D5348F70954BC8B04560D30BBE757811BC0C0301212A64D86CDCEE8334F650E2DE12F171DC44A6200121EFA8165F1BAF86CA118E94F0EAC6A56CB53C6CC9D13408EA6ADA24FFDCCD9A98F20BF00A4421185A4D052A59CD49ED1570B81141B9F32DE0B35B813409D4D03CE76239D7DC1625C67D25BDFE14BB45EB0E2DD3AC0982FA2CE3CD2169E8957F0A033F151334FC4343641BC3B31F10ADD4C569CA88DED47CFD756ED3205A8AE241D8DC0EC2900B55D9B6B280867F709AB7ED7BF3CBD658E71202A51E8AD5FAF6E5A14324BAC79B4FB935A1E1C6E67EA294F8A81A506F8484FD97D65DDFC48A7A977867042204936008CB634F5B557FE95F85E2144F926E4CA665294E27A31B1C84FC3645D0DE27770DF8ACBFBB2AEA26E5FE01FAE00F77CEBD37E24A7CA158B58A1E79467B64E7617FC324C6602C8389B0A5EF8058A53BFE42B2AAB73FA73A31BF0DEB3FB39ACCD57E59A01B0DBA8167EE22F1B7D317C2765E2DE0483A65BA20DE3180E19472ABA15CC3981A1C992B23FAE41DFAC8196340EE80B15F3C28981674BDB439DD7B4C0B1CB9D03757B1F6108C1C70D37C2FDD936A5E5DE17EC85B2DFAEFCC13A9B7406BB7992AA5ADCE9E4C6130279756920640D05EF11DE704A5475F7D05F6FD5740B3B4C7668270AEF15C7B44E5230FBBABFFE5C96BE96BF4321D1C9A539E2A1A91465337520192EC0A3B475C121A21C2E1B31C30108E9E93EA07C8F86F7AE938B88E5E06E5F16EC830F658097D56FCFB168B153DD7E3A8F04D3928C1C9C3E26244C4B30E15384DF6F0F413B97FEBCD13C892BC51DD2EFD6C9D743E33E85FBC44AFD7F44A69C58ED2DDF26BD54F46648B6D10208607923A390F1DD4A30A2BE95CCA63FFE4773B23E919C3E418680D897118495FD2BB86A8AEBB6C868DAEA895C10BD3E2D9B87DD5CCE2DC0DAF41F6A595AA824CA0EDF530AC3CB7614C0806C52772250F0DA234F464E94CC7EB33E4661DB88E9474CF08E61AE1850DACE1BE19AAC74194A7135E243FF61BA9D41012314A64420B22B08D6807CC236CC673EB809221D8FE652FCA60C3B045013810B33E4E4C819861513B82C6A6C3727321D484F853B9884E607DCBFCA45C5D33530FCB3E968D9BF8E4D34CA9265EE3FAC704200D785447DBF2D5DBE7797C359EE4A82489BE397841E2FD4D9B947A233C654579DAFA42DC779889780FCF7DF5316FE1244A9A484040DF1B5054CCE0656BE4AB646EADA47F09F3BFD1FE7A575D3251197BFAE608E8C9B3267F7A4BCF366A88F3672DB0464AEADB0A528212F3675E959B23034AED5F4BD814B5F88F5A134541E3F2E2B5F2CE751DC5E84553C0DE691F0ED55E14784E7BD61C207EBB67B0C34FA643F15D866C6AFA377C98693568F893715F3F1D62EB85D45069225DC8AD995E517BBCB971DA7F4EF3C1FFFE23CB403F7D4668010E14CA62FD633805BA5DBC377ABB3576A776D9DA614E322D4E8338886FDDBB84E4141A87F164304BB5E09C25EF4D815B54B01C39CB4D15289BBBC62DAEEDE65783AB85FC178926C4AFA5287677CEE914B0E77655343F306A1031101729E0F1DD5613F4D8623242CA055178FBB8265AACD3F00DA0CB3C6B7883E82E59542B1628A1E09DD17BBC05BE874192A0B7B3533F8A6543400893BEF3E5709468F0C90C98F130AF0B66E41216301533893050E918501F2361C4085851EC03B58ED235D4BBCBC3F0A1CBA35FADC7074960E4AAF79AFF679DC585D85BE2D17BAFC592D91E7976183427EBE87FEEE4A83920EB2ACC9BC94868F1AF4BD4FFEBDB894B9244550027348AB145C0E267584D1059D746BD5BC7410AE8DA46AD01CA79E8CE50D83BF5011166A88594DDD33043375C4C9E79D3A9DA23CE3957128EDC1045239313AA90A95CF751196636EB0F443FEDD58A110F9D7BE1FB68E551F962800FBB7FED176F300CE65EAD164E8AD58CB38B51740FEBCCC510AB83DB9C90BAA56768F10B77C3CF9162E475DED5AD2764D605760C9ECAE900C7F7B0E70192F15C3C82C476EEAC912A98F03FF9EC93BCC192846D8EEDF7282CDEDFB809ED6881A1DE6271916EB9E844936404C7F6C8E07F009E4F8234D0BFAE14322FD6F1258E9CB736C2CC13BC5FE206A25EADA53C5F0EB6A92E7C0538D8A02E854DCE9CEEE6F211A90356D796292F1B55BB0C70EE346201CBC5D718A046BB8C99633DEB7B37C1AECF9BD99E60DA7C81471C4CF3643992C23949D3B095C1AD83A2B6B113AA7637A1AF71AA80F69B4B9F766DDA4DCA5D434A76E762B3D97020791CD03AAB79F3EE21691751A88409AA9BFCAD21B53BC954DC622B069997A1B800192E8AA137484C982215161F39A5767D81FA55917139A8A67271F4C68B113780368B4EFA862B95513F92EFE36FC64E56F291AACF22EE8B672911CDCD9A8B2B11F986E587FC680E2BC97780FCA1D1B73F3F8E52B62230061B134A6395575FC9BF8F90B527068DE44447CDFF290A9EB28DA7242C634BBAA2AFADEC15E1AD56F8C9A08B9B535F5E646BF19E70C5E0B408282B11EC5028694B2AE414866AF8D6E2B892E0DD12C6DE9E937454CD96E586C434560EB7900F8BA97D9E6132FDF2D8C0BE34554CA4E85E36E3A1FCDBD1E7E98C16127843B994170EDE84C571FDC13F905025B480719DD6AC99C74BA81E6A2D430F5FF33D8228E672B5C7E97A95F8FE2E491A46FF2BF9EC0A4FFB6C9F07CCD5C8FF5B6AFBF089AA9625DF795DA725A806665274F4332D9F795BE3C62DBF0B522E2591A03DFE6481BE0E792CCA7247EE16292BAA5AFBFB5AA09868607147B90F52AAECA5963CD13111AD70EF8DCD37E2BC550EE7CE5DFD1ACA27DC0F30762E2EFE07FA025504432410FA085716C5827DA898D7A076B7174CAC41A9D960E22B190486B4104AE07B93F6859FE5AAAA5C74013DF15C8F33B5B31845E2D09739A9AFE0B201723984BA99F466D32C6A2F928F1241130A910CCC06F9EE95057970FACAB109143D396EB5154783685B39AEA1AD4B5C4092035BB9F5EF3BE0EF99021C5DC20DDA0CDCDDEB53D317654B01BB41DADD2E0796CDBDD78C16F11B25C1892CACCE6A177B887FDB52F30E4FDBE7CFE60A60A278C6AEEBC7DA88638BB830DF6123F24C1BE8C6A27C56F4B681959760F0A2A94B0423AC1FF9E952DD1D05D5D00874A4E73BD7728F5665C525E5A8D41AB8A56861883953050A2E248D771C07417BD95E56AF4F06580331855829B74D1D76CAFA244651AA67CA5436423075C1DBBDEEDD32C54BE4B2CAAFB233A11E594171540239F8C530580C24A19402D008B565267783F8BE727903F3E977AAB78B6CE83913382B26013571D5F138C4E7A6B3265CEA2C8B417A848D2D5FFAFAA12EFE5C667BA8842E12505302C57343FFA662EDE319D9B5E8D263E198673D765538364935386B4A93973F36A0155EA55C1CF46BD64F32D8773394D1C53C1C6E48F068616ACF60F412383C16F151E97DA4291DB4D68667BE99A118952C7D83D0AE31878A9302CE79D1CBF23D0DCB7990C8C14F480CCB9FD07BFC63394932BF04764AE26BE1B23FF4712A7F7657E2BAFDDA61C7EC82F91A909C683CD2F740A45141491FC7C854F190AED141275B3C39B7CE5B79ED83004D9511AABFD242EDC5B351DBB2909A8858534E4BEDCF8F2C3B5C3B7FBFBDF3F52DF3D9B95021A73FDB9BA1D153969975368E186CE2B0F4274F61CC67121D886784A4724C05D01770C031FCE2F7DF8E07C44E9C4824789A9F40DF8A67916871D77D98B0E19E5DC3D3D73CE57D503506DAC95DCF83F506FF348610AAC9A4EEACA5AE4C17FEB9576594D2914F23AD20AFEAA82F563E0E1F239496693903F296652660929D0020AF0A209BDDA3189B969EBF139C5F0A150D384C4C37ADC478017275AAEABA4BE0C387083A6C4B466B70CC442EB104640B10111ADE7EC3A7B7448CE7240E8867DACC7118006B1A272716CB10DF650804E896843351951852DB87735593725C3680ABAA36B6ECFA904363AFF6D19F2F2A99205A8045091285032704FBFB5E8AD70D9CB00E90A2244217CA3C641A1C7AE0836EB31E4A69D230B93AD9DA2F115A80C8CA134B80B2994D3EA4EA1839CCC0DD02340C56DF52A120E730C12AF062E601E27631DAF97C158FC49370EB8ABA617B65C93D15133DF7F9A50CC795425EE1AE9074D29B4825A63F4A2093D64C462CAEC60388D1117676B51179009FBB5FB0586ABD32B668277FEE9A4E8C8AF30973A5AC82F4F3B74B6CC22B3BC2C713418ED6AB86E0BFEBD931BAF6401C7D39A2F1D44013E149365BDF4A7D1E8F9AE2762EB7CCC62DE4DDB4B88DCC2A4E9696E9E0BBD6A43D42F85A9DD86ABE74A466FEE545D7B2661A5EC7797E55D9A4D3334A09F1C2F698C7BB056A33E08BAB57320E6770FE82E19FDAA3B26F6CF947628D7E631615A6B3CD6FE4C8B85241BD1036E5779D3C315197601E9875C408AC83BEBC749E9CE23CAAACA4A24F1942BD72197677187D051F011CFFF852515F721133E2FA0FB3D787ADFEF4A35C336E975971E9D53619DF66B8CC277523903B9F4F00D5BEB19B2E5BEEAD90F8E3BEEB299223888DF0AF72E6F193963E0FC6343EF7D861475C00BAE2FED984A900D1F94F0A373C57CE3277B14732BE6C7E2D35735691CADC0DF660CE7B57C06761BA19B0FF156C44398AD0C1B46F3DBDCF363ABF40E5631982F964777B75E29FF42C2185EF8EA2B9ED7659B9AA4DD6726DDC445DF6B593823F083FA2CE59BA92447B0F8BE1AA9914943174D468A222C29B32D13608261A04B7033088A236EA624AC15CCD0F72A43E124C8411B94A856F91E2D8B9BC0553A0481FFD86E9AB6018422E1FEE12B3A474EC8D3B5CC76223B4891934034F2D906AAF6E80B4E791CB4DA84B73DDFF0F89C5E528E64C6F030FC8D3E417B5F80964B60B1FFD9C788A9DD2DAAA5FD62BF799A1CF2C0DB4E39C89AC0BF93E8464A6F808229ED499B158F2F2DCCAE9F9B01AC212687B5BF0118754E0B8AEF46B7C799DC3A40FF1ED09011D2A1D1F3B377C415BFF64BBFD01699C17148BDE9ACE830F111802653B0B1A26CD667DC48D299BE0BE537D777B8E919F28DF1B0B14D7689AEFAA48D7173A95D876DF498FA0917B331FA0B5036972BA5AEF1A9FD0E4910617F51D56085CBB807356E6EA35E981B9C8AFFF9C1BEE5EB846B3A59298ADEBBF61153210595A2A32BBBBA36121B86E0082B24DBBA3F21C4A0677B1338F773B17B708A2A4E9036B166BA28E37386430F7E63509D3C4A3C704B91C13C57095D54AF2DBC552B054358B85125F6AF6D666193D21C964C12DF27D5A53F91F8EF128CA0D840D9E7E6D19AF99CB01B7212257B33BA2B69960E2CF007A44C0C904CF5786CA818C4D89A2BCF4BB2A46902E6DC11A1DFDEFE678F34C9AD297413A61D4D9E05C2F25E33D74B02B892E8DAD7CA198BB7E229EDEB0B4B6F064CAC23ACD452248D7C332C629403DBBDCA09A2EE3B06494D10E7F841DB0A48EF54E247A308DCB235D715DE03569CAFEA6BB8F5542AC3F8844F2C798687FB934A46730F33FE3776BF5DDDA2339A88799A6E804D6E548F62642635EA8F8C00137949689BC0370E7AB92759E39D281ECA29BC0586AB74ECB2D243364278F0AE09316ADA5254B225AFF52BC24B1761A59A68AEDB2D95317E439BCD4DF5D703A67B72614532C28778F4D9AAC819C8788020391D461F6C107A86AD9CD9CDB6FF4ACD458AC39791EEB7BECE473E1FC81BE0659B04E511D0FC0635F8E7217A36473C07BA9035A8EE1B352E3F271B7256736DCF171004F306F55D7B33A1A2C71CE6D5D9B9848335EAF775AFF7FC173E6749E7ABBE3E611C10F59C3DC610A063CB2D2A465572BC3E1F2C0D782C25E8A323139BD4056DF4372D2B5C75B29251E86FA1D5D09F4A42031DED19A2658E477D6B5ED018090005910DB980A785DA1B38CE72F663A353F2033B94E41B0EF1F0ADD2D24FDDDB206B66157934914D8D97F1F81894663C1A5FBB3CAB4864661B0A325ACE252DDC135162D9328DF30F2EBE84095A2609344B7C07F01BF12C9334A8936C43CFFC11A14C2E21C8A1B8125FC72DD7DBA91EBE66762ABA36CF1841733B8AEA9042D65C866FA268E47FAA66364ECF3432AFDEBF8333AF1A1C727143A512917317EE511F0B5087BA5891F21590373CB802CD5414BE92D8F151D1BD0E19FB0AD6854AAD62F6C20196C48D526C24F0FBD9808B4EAFE926CDB55147D10CF74C37BB0E17168C10CD33417D4D4B7C582A3932DEA45A51B608FD9BC6BE302A137ED40009AA966E33CA7DDADCF4B8E6C284738171F48BCB4C415594854A568E98104626240E00DBBBBB276A7F96930B9D72E61D4CD84A59A5080E1A8642195B34ED7170004659A8A1C059BC4E20C35A5BEBE6AE958B7C1980467C8DB6A29C1567759B32E0FEF774118BA8C8E1CA902185B4CD125780C0C020526EF7CA7B244A893B86EE52590F18FE3E2F664B9C6BFF3E46F8DAFD1550FE53ED9BF017E5B240F1E4655DC9DE788E9FBA37A88F24ADBC5276DD8CBC163EEE9950BCCAD7AED335E6BE9AF958BE761BC3B4F13C03EA4F10B8639EEB2BA8FF8CEDBE0C4FEA4C4390E64B92DE45662FE161F925BBA31C9C9590A7072B3FC971798CE05F78AFD814F970A448A08FDFC7CF9EDEA49D127C7D3D36BC17FF35C4453EEC12BE0D25BEC0069648382059D351A8A64CEF84F85D8C3AFD85377FEEAB31B8D4A273D1886E0C7E53ACFAAEB76AB26E2C06AA777D19D15FE4367B223D13B380F6EF9B1C317DBF50B45C9ED9BD707178A76483A23C38986FBEB55F47BEB0CAE286A82F28E369C2BFA8D6A005799005438E39E2F8064A3916187E76043D582754620879C2B3FFA29A6C99EC654EA0DE34B98CAFE6152CFAF06AE31885F43F59953BEEB657C4CEC02E100825014A93F920F47A3386FD634318604E81841DC29291AB270947D1D2AEFD139D5968455B3EFC67364896C0F4BC4536882A73BBE3BB79607A6C899060574D00F48BB9A889A09AB24D67C93BF30C07A099A8391FBFE19F4701E1E5E5F149DEFF7499CD0C6CEEDEC14A23AD82F27B5260527AEA3F56C19AC18816875861D4E5FAEACBA7556C6A2B83D78FD15AA3276D994A57CAD744B9BB2BEF29668862B6511B7E50AA50049CB81D522EF911ED79EAFEAEFA0EB2F0645B951BBBE224777DA2C0A1CEC49E160C83491ABB4B905ED6E7C14DEE061576F2EA42FEC06C87D5C2D89DBF47F8D53B38DCB50F85B5DAB74A558843B7F7501B62189A940FD6F2B182DEC095F2DAB46F2B89354E11779F9D7E52C5B32E1AB4937E9099FC57F0C47E1AC6872543590A0018A66E7C8ADEABFC14F294C4451D8809F413FF0CEACD1599F5C01CBD63A49003270AC0A624A8B77D9D74C96D8ABA3E3783FAC9E36C211AE95C9315424C3960DE602F8E83450BF4CDF76B3E05A6622D1B0258E6D482F032A59E15B22966BED8CB7A7FDFA7C540907ACF5CD39ED6A8FF1EBC8BF114F4EB5E4FC743C3D586C41ADAFA04AE9580D996F37DEBCFD13FF9E951EB38FD8189C2C0290560816C340E569F2E1398C00ADA57BA1D7AE7C50453A058A007E3DD5348FE92C4B97FD893B47E55A0D434E0529959DF1650CA785594D285492510B264076362F3FB6964B97E0AD7F33D59E6E8E98DC0BA47D4B6ABE28E3E1E2946AE9C61930ABB2DC9E06A1416FB17766AE3C2E0BE9FC3AD13F7021E80CDDBC378D069225E5E212CD79779417DCE4EE6D53CB069F186F9BFC0EABFB43782B54321D7D265E1ECB31B4DC477B84F9497C3BB49A146010DAB5B364B1F01796EF14F4FB8E60591FA207672C1679CD23FFAEFFC292328C204FC17ED7450026335DCB56149E84A7493FCDE62735B0D1588CF865D82475624529937F35A998ED892E9DDCE8D2591C65862338F478B6B4CFF72770328A55D03AB3286EBAE92D6C77C25EDDE980C880FC2BEF2DF4AF156E974E69631610AFE70C865CB152564754B418E80AE64D02395A3E81E271615797647AC4023EE1845FCD442AEBB923BE7D0E618F4B477AE95C50A7459B707D2C367216D411D356B543632F85CFAA53E0A0DAF1609E98C9AE398C9859F325E88F5314D53E9AC3986F6EFF2815F5B475F5A99B6A8300D0400CB1B098AA43C5B56B78253A449FFC7B0B5EF231DEA47B5FD136DB1EA89160B48D58743B16CEF761A0DDCD905486ABD1C844FCE4B45E9981EDC767A1A46592390979C0F070C4C00743A68F7726682639D780843BCA6A2E4D48E500", - "rnd": "EA45540D9AEA2A3DD8EBDB2BFC09862A1969390D1018123DD820C9DC984E3253", - "signature": "A22A89C00D6E3211AEB48FD45FDFBC9EE1E5C1FE3CF0AE851B266429C9D085605C9BD2361CFF8C6D9455A5448302570948B00072930D1992655DC657A928603C68178C940A0DAC267DE6162B9E8F895BAF05B12EF3338441D4AAD68A61EA2F94780CA7BA7112FABE08A437543FA928DE4B897745599C067ADF1F10759D3919176D945F0B54ECE94C35B92DD888D627142F0382216652DF44CC24E28A6F5A9EBDE059868F719BA64CF7FD290B066B97E289A5D02DBAC0FA579A054B25518C179DA36A54F06FF945732EB2F617D3AB6153A00C8FD6FE87332562EC5A5DF7C7316B23FF818C0EDD8607426181A223C4C57FC695B5380460D22379701A554E115A51504DEB525DD81C10542D20845D686B00D106A99FE084E3553563E83F6F347DD379C333C74A6382C85D5C2C8F07160F105B95DDEBBE14BEDD8B8E9B6D2E46872619D8766E48B16E8012D1C8EA5B16E2FADC171F9A473CCC4999F56BFEF3D22C24163AF4E58552DEBEEBBAD6F1275400CDCB1A08C0F97208ED171D03FB7DD2ED4AC807AD04B01622E675FB57A2358D3D6C0AE213B644FC058891148223C6189B515F43CF5D7584DFB9BA65DB5694D73B0EC10C3F410CEF61B3C5F048341FB494ECB6D90E5CFBC4DBEBA93356E5D4A75418605710F47137144E84367AEE294B8C0721A39275CD3D21A736D7DB332604BE5185DA6955401B2FC60651E018D0B758F555F2DA1FB6CC6662BCAA3B28E33941196849E80D94FF621CFAF603177CCF1AEC9F6885F60D4C677CD1C296F0FD89FAD5C876DA00A363E3997962125206A5B6918633F0DA734A946ECB352341755260FE338517DFB6662DB51DF421308DB0DA637DB2F227F6E21F842D448C373590A1D58729F55299F428B8E9A10835AD7AFF169CC663D2507EC3A14FBA46807CC0E08E8B455F7F76B02E26AA179A3DAB31596E4AE9461E51CE8F429AE0B40A06AE2DDFE24FC59C51BDDABABC119893CBF5A7A1F17BDB159AFED66E05E79F087C28A1AA34A134905320492AB5307989251DCB8D5E1D1841DA00E2C3B480201A167A248176E15AB3FAEA0976CD2398AD430B8A9DBDCF07B6885C3C35D67BE523C9E34D37C235D6DEEA649ADF62DBE944E2D682F50C30A271D2B824A31DC9A4391A14884CF73FD48719DBAADECEFC72CE1A4A089E39ECC48F180C1051110765C41A4B0D4816580D7F60B453843E48EA28030D1C5EB63CF674BF6B1BA5D9288CD8826843E9DE2C45E18E3D3559FA65D0176A07DA2A77E83B566C49B41C8BE7CC77BAC22EE97AF3331349DCB6F6B60096C49C9BD2436C5545562D33D0BF2867B3CA2DD59199F202F0C937D962A6FD99CE92D6C0E39153EBC43190C613374371CCD85B9F8938388DB56B86930F14ED33B8988ECB559B7155DE10C5A46AEC1E6644D2857A45976CFC0FD90BB593AAE17DDCEA09854FCC7D32747DA492FED24D6974CA28FBCCF691BF4A59790B180CF522DF38B759FEEB9D2B3CC0CC662B28A683904700474DC94AFDD132CB748B02CE36AD383ECB7562E7972F83686BE443709157F2BDB3B900A9D736823AC549F9DA8985A53E9483BAB074F32F509AB60D3B81DE2B4D5CEEDEEA66AA69CAEE4096FAF4A16ADFB74E1879CB293B7C52C907577355242D1290F3CD5462C636C3B344C830FF753AAB87356F4B88913F4DC9E5DAD1DB010B7DF30F7A652331045B15696D73E547CF9D0E2B10586AF107A8248874F52F21BC73E839CBB6D0F2C79B9C633FCFA6CC6A445F14F249B28A08E32829AF2759B8629BBEC789599A3F46587236E86161CBF0D1A6D33CA7F73AC791584906588DF949BF75ED9BE97CEC78E3466C83FDB323320BC5FF2A45C49C8179170ABB01DE3F0CF188846F5047618271A0BF6DE867D6862B9EF354B0C5BA1DE7686C9605B48ED492D439CF0C421EE76B843096D7589A4005D09EBB65BE1DA9B2309728074678F82B5635535EC80396E5C5F580533134E5DA1E678637C396D593036E4C441197A07EBFF79D39AB6477B971F72630626ED303D99985AFDDF64A780656D38762A73429682A76B61421E296B5538C695C713B129FFC82B9C942995A51C243DAA2FAB84FCB2C041A4365D1B04B01E6E0949BB178CC7BCC49A1264DEC0588CBCD517905F4BC2271F07D09DF2983885D706C5DE2EE070EF6DFAC271FB8D9D00FAC925DCE531311E12D2A4083F45E6DFAB1D5B1DD289D35B5F446227ABAF3F6A9BD61DF0B48FF435FFE45B601CDAF929FAF2321BBC6FFCA7B184D56E182519789BC76B305304E27379855FFEC7EC77B32F7135A7942136A6B0B611487687910854C13EABAABFD1AB0C8AB237B4EE784565D5232D6E11DBD79DC7FCFF86DE09ED6456CE8DAD0FC4FB9450B24050EE718F6C84DEB697638D5C355C5CFE4487D8E5090A86EEDF9D7177BF88DD10C2B35D6E3E3EF6B3EE54B767359F60F844675D6786734A793A156C01815245A37402BDD78CCD616501E98302729B21F64DDB4A176AB0565646A4594B349DE5238A3997367F1C92E91C9DDE52B95F827852550655064873C9BBB1589D43316B7E2914E9D0EE82B2D232890B8D5CC9A3D280569A6B79561C86D1DB23FBB5D43B20E1948A1AFA819E2D9A939CE1875F9EB23DAB6E6982A2F75974B2C238C73A294872F662483FC9545C759FA1B9F2086B5B7B6D849BA2698707638A6B9BEAF0F847419AEE4F14295982A0DC4B6B6C73FAB59F266A3E52FD9233F566490018677A9B6E1D57750F3E47C47B24112AE5A93A976FA487A947B90E2A80AB227071DFFE54A903C8315BCA36D710DC35FA98284363A52DA19EAD76D28F9F523FF2960255FCC301E3327BCE8B121976248C297F83256D80FDAC8D0DEE1C1694D5AD030EDDF3F71AF5734F407285709A9CA6A2DBA11121419B9C97C27569D9235C3543DDCE2FC4F3B558409677BF2DD8AF65292AD978D361C8C57C7C9A9302FC05F5CFBDEBBD9B13350655233CB873E745A2E42A376E006A63BDAB8E4A5E3D35622EAE4EB8DF76E5492FA18F88B9C6A703ABF8519E2F0BA67F65E6950AE6D77D5D283F98369230A07214734599BB689280DE4B374F83D266621D418607446B4CF3F1E8703B4EDACA87CB7DC54569127792CD06DB467BA6BE8A4FE724867365A3FDFAC22364C517447FB6775D96E86A25204285FAB23D8B00D6FD37342C27DC7C70517EE7353711F173976E4345D5725A1FBAE72CFA842430DD35E445776E0B34A328CE10A75B4860FC3D17691C4DBD4D7FD0EF81C4460B7455C479AEF8A536FD47CDFCF341010B093AA9447D47A392D4A8728B5D1BBCC6DC1A6F061CC94E0F6ACDBC43662058B8B9A1BABE2E1DECA6DFFB33A938305A02F00F2961365860495EBE77A8643BAD628AA0302723A5E523FDD7C1412C26BF9C72D8D72AD24313007A8AFE759B7D2133F0771E297D653B6A20DA69F9514FAA84024D09D930E9A447F21CE0328A8FB9E6CE543ABE67CF9249803C2C3D6E7EDB92676D8B012E52A73A5F1A1E69A78AC491432ADCAA1AC3CF799F0B3FC6FA693DBF1B7CFF3636898BDF504566ACAF0352E96311B43142CC3FFA1B0E1ACE1A437DE776E1BA29966E2166CEABB82781C3CE4C44219511689EC8C96CEACC797E9FCC850A31916470609BADA9FEF02A43021A0194A6ABBA004DF5C3998739C64CD14D8F693B7AC6CF8C83F6ED5CE4A85D7AD2EC1B02F906556AA16BDF9A451F13166B40A12C52FAC402245A21D3599A62DB7AE4B6CAD29EC42B661BB1C4B952133749A0D89323C5E3A48A602266E932203452308C53E1BCE8A7B687FD1CE5C7E69BE8156448A2927F65864E09DE0EF2883DFDA6207EAFE798976AD80770A3B231966575C80C21223FD902D98FA2836EB7F76CD6D31C77980B9DAFB7BE681289EE8F770F2ADF7F537D62E428FAB5E073A2D4FD15027C5D4549B6FAE55EEDA47365F87488AB6D1F478E9A00F12D314E373062152E35204E29B8B245CF3E963E3718514A81BC00D372DA494F4012EDED0C284E3CC37054927422FD5926CFB707170F6623F15690FF056828F6F1D4386864EDF1A60F7830D7FA0B6DB9E61118BBBD8DF84399983C2DBD6894D68D476BDB393D83AC0E8210D2530612FB28CEAD71F5DF0541F22620D1D906D9B94A29FEF80300BD65AC748CE80E5BA7B01E77825D25081946D0C95978A376304C1BDEC374D4CAFF791F02D8A63EAEB3645D8F8B479EFC0D6D765E0A5E53CEC2E759AEDA7AB28DEAB1D2D158F13CABBA08C94E94A630E54B24A04C6C625997AC410CEFA06C2EF45A02D03B2D15EBE3C3C331AFBBDC83090D6E5DB275C10440149535C37814E797D586F63D6416BE151EA062318006D1FCB78103FE80F98E23D1DD57CE17CE29625CF68D4A1EC3225D1CB510AA374D9CA499D408563ECEBCE08601F9E329F2518A5AA85B72D39B4398D19AE07E62DBB53290ECFA1165AC839CFAC723D1C52D76831120871F6479A35092981EF715266C6D3D611471898542502F37BFAA32C0974D83E0B39BB23BCF8EB3BC5BB7D4B0444089CDC16B20C5EE1FA02B8E20E55373ED43019FAB679644722550AB856C3EF86D2E411571A2167EA3D318B7AE65D075258D4FB4FAACBCCE9FB49505466A601069CA2D3072329B8636A6B929800000000000000000000000000000000000000000000000000050B1015191E" - }, - { - "tcId": 37, - "deferred": false, - "sk": "114DEDCFCF33524B571F702B41DC2F32D7B65265A0D3141A40D633C2A7E9E48D102275737F7D37B008B86EFA9F826310BCBAC5AB1920ACEDBBD3378851FABA8700918A14962FA51C22EB5D52CE2C19FE74CAB43CEE3217852743DD8A9CF52426C431F8D6716EF3E041E2AEDB0F977AE6DF5551A91B0DC2444F470B6B14F60F5100885008512157712481241131368052750581440637621005831354565162836235177243307721335676515826743524770817217147617007254782315321566073681362354088153817635437810828534816573041554214000735456845802233054731387232160026272750268377648802708423161845102881738563332404868213658328408088163131822167527116450254234733525652148817764721672160616281416043600208886885168543736317120658755625553633047604484012536522418477002414887422451287230207454813726407358208255567087838016134077128773740436206415000155466027285287842530855862007558715134313801638566085803654201053222888101011205184037384361668733461570174818858240048628425176473806066844874420630111521703670536114832246580470180743633063178026203801424346842868106022122631711503218553717274607167566850415222876841072036810556014307653658488017682424014707321824030506686626384404743307025401858824007865805261137578257461040268055248447340127327547271705850505681632152680843646123434768733821685430717055783532138158108001126007418640868383854046585483064472114463647476610745142036312016442812505448702684147444160017831655727151444502757041631250227884456736208708064671303871721632678148754674632843533743311243213707457810242316207433162273215450047631302151852732788260508140831456326323164744753524222432636724850748324732757162860821320843746821336622536847742576150623236830117366884530751507647011533885853352222757006608216026285246527523450661417722028821688010748044512258887355265364557777680708337228627172858584681844551034516175410281808687636578606580606127828414328470015300708776513375708317061185316251201760043240612211153026076857208257070826733676357020165314734524020175254434420147437586187774216068600318175670732447137781281426634062741751512886253026088010857016328465528870025468086820426362148456223534855345156305272578336180787077727763186145217076071105766125763537827022613717520856868050485270506441300761475468026402676003840671040405580733423438406286653112385300773013178861321131583026382152503333844062734814740784662427003007432233011266022583883246275810080646217663237485081535038268333035022827402483563821301774285323787534720363004845584271154051281863876575137533177168488520051882588161370733563146202871847182064101086485680786326405311634445153265167767075603558736883332424168281868424022147010483771861464420661546536243548843607064706002068658431217611431615265171124650170667883263701144262341206177553713236811537432152136473625635086442724338637160308668672786273464033810314718418453404637846725666534775872282606718433425222853746537820313575101258316682561254651243164644817711408075728065373668425277664743006047464337500271153856807078588556371335843018086420541715583634176377547083705152302000152413607516083812673384266346566651003607268100404214237073104803615614556170765431508404583561442732E9FE9CC117746C51BAA9A178A3AD727FEE4722E392381E2C23F55C343EABE6BFE43AFEDBF62519336E108768A64276F72FD9D4BAD7389540E6E4CC5CB36F03A47415CEE47B75B5B43CF1D5EB100CE8AE6CFC3649B7994FF4F3B47EB493D92C397709529AA51583C5E6CBF01B97A0256C68B4A03CC23A4EDAB61CC0141F38FD1A2C53DE584C598C3F4EF6F59105F00E2508A9A083FD60C0573300259464D8FD46E2E99E02C683DE0FFD4469E327D558ECF1A47454FB2301B35688217A554C158FCE9AA6C56444DE7BA782FB0B8E86273F3CBDA13B0624EDCE90C56D3E9EA264113EFE00CE91BB112D9EB65073F937EF848D09DB7B5ED0A5551246F950B345089DFF4C468947AA8C4321747B0F35058DE340078715F5564E157031113F28FFD3CA831DAC0EA3741A5BF53DBB7763BBF581E8103BDDD8FA4C4C9FF7ECEE5446A1D108620A465FAAEA61AC9C4FB7B365BD7C950102943298296077E4449F50EE3F2A2D68FF850F93FDDE68C1BC4632EBEF6737636AC583290193C2F797232AD7B857FDDD029ED99D7DA1355B88E83D1611911FC98AFF95E80F0C758E55750B8410A4A121DE796ADB8458F7B9BFECAC92BC10F6B3944B9697A9E261EEB3D309E3A6FCE6D3D7E20445A3EC664735A93673AB582930E3575E0DD9771B50F304E1383329C83C1A072670886615B069683BD20FC3A08F9F3302916671375BEBBAEFA5D0D75AEBB17BCE8856640A39C6C1C98BED73A8C0187BD3646AD6F7440286D94101157E542E86874957625861D1AD4A2CB31BB30D682851AACFE45961D1ED730DBFFC78ACA8E2676D88320412F392F18202DC2925F5AA2E305471F45E650DC97DC1875913E9BDC319224FF598BDA5CE6ED8AA75991BBAB8B51F60D363B36D80DBAD9A444333C4F1315F0E8BCCB5989B401190A09AFCD68097C78D1D73B8B6EA1734296C626E4423FD310B141876C710270B157817742F022ABF0EE300D68123CE823E3614792A7F0657245CD1A7B21B2917E2D494D69E9A754AC7D039B95621F55B3AFEF28DF681725E0836FA1069610E1867020A5756946529A54B19BA2F4C50F9788645DD0E50ED43A867F7DF5A9C4763634D19F493668758962F578D2309AD0A6411ED5A6888DB95DA07357D8C54CFC2498B7EA2F90DD10DA3C0F04A69D11D7FE6DE34958768CB53328C2590CEE35F28086562D23BF0B0889ACE8B9959E94A863F5F7922D55038E630DF3C337F4DB18F20C1626C932CF7E8BE4D139C9CD217B655A0B301EEBE9F9827FB21435B8076677DF8106701BBA664D94DAC760789E5488E0F7A9AA304F52E635DE8E1B6FA1E930B3401AD2B74A59F54A2A5D0C9817DC7E20D84889BD1AFC2A015E477C08E7FEC14CCECA11A3191E3FD6F5008ACA67CF258D0641ACDDF39CBBD4800622AF2679FAE52F1AAB556E4F2A09E8ED4AF09E00169FAA3AA4F219A8D071F2447E35583E64F84C7A1A0388832139485CE30EAB9A1B1BB9D2061EACE701C3331DD42F01EFB8D6454D6426B4A3DB73E4EB83CF4E5935CC5BA98AD6052DC749CAEE5026B891D26A03FB6C71A3821B681401ED694F60DB217BCD19B1BE17D594C8617E5A0EF55E1ADAD51C46C275B1C92EF64C10096AF53BD42D0FF057C4C209976DA771517BCD590237F03DA63E8E7FFD9665D625E519BB7C40D92F3A31C1921361CF6133800B258C01261D7325473A60FB5E785A097957327BD2B1E14DCDBAA06537DF14FA79C48A67E55F1DF5E2AA4AA426FBF57EB3EB0A9A82CE38CF71632A08823331793077ACA000204BF50A2B8B30F9B9E9DB9260F6407E4FAA36109007E1E7DF5F8D114192B9830042D09569869F77C49BF3890F039893F72F8A459E287FE962EEFDCBDC0432D4B12020DABC2CE5ECAE03D86D72DA61034D778D86A84B1213C3DFFC4AF00A16FC7F256AB9E0CB3D2DBB7170B50E880B9C419F9582ABC7EEA0BAA768E2370054097B11D769A3F96D54DF85E61B7DDBB792C3493DFB5E6F8B3749A9F936A05B15A4ADDC48CC999380B5A37B3F0EDF11B4BE590D7F524E8012871163EC10A890C4951318D2169ECE0E3976FCEFECD4B502E9710CB94F517239907E032C2775114F5AA13E47A378A080988679AD8566AEE08EF83EAC519A61E772F47E8D6D971B065BBD52C869A149B2A5A7D2E0253552BB1164D64696607AE231608549FDDCED725F0400010BF7D633B4C9BCCC70BAA39541228DCE60CCEDBFFF04AB2F2CD69610E85F14C4D3AA879C7FD9B49CB1B7C3DF439C9C2466C15B13BA8715240E51CE10ADD7B2748BBD0CC14ECAB64CA6E7A8A81397DA3136095134BBD2E384D7063F5BBEFF749612890F7533CBE37254BA963B6A5856A1FEAB3AAB61A9AFE9AD9DD1B51428BB7E6BB7130B7DC5F6CBE4537944756E9914F90F91AA34A5B11F1918AD74289595B73567C16E88E448B69DAB2750B9C5A93964A9650B3054736007F0453BAF61964D79509C17D231E0FE3E1BD04DD968BAF26E0F37B58774DE3940D92CB96FE0D6E6B676D3CE6C66A41987109C8B98D6B2798A71EBF39AA76119BCF94A69C02995B644BA3C4B076DD82393EDC47ACC09491478DEFEF4B8A5CE77D417050007141BA1D82EB56EB3191A76F16D78CE18C823D5AB1AD9DB9DF5374AC3343B848A7F88150AEE103F1ABFC559851B9367E1DC510456B965B2334CCEE09FDFDCD317ACF7A4925123C617ADA71F658C33A7C2619EEAE0D4305F782B4C6E540D753F6C53BD42A2501671D4B052FB736EE402A8E110EE5F889F13E3497892D427C7538B8ED51936D1448556126222A6EC3244A2DCAD1C1D4567D2F895BC805C133F04FA7B322102A718B9EDA77996CFE378F8EF64C0FF9BADE5CBDEF1B05E99A3219089905F3D124A154835CABD4D83545D0DC7662F4094E01CD7A8519200866A3E31A62070FBF566EFE037A834022FD9AA7A3D1DF8C88AA0A1380E92C4F9DA83BFC13FD033634B84522141257009FDEE776E04453B12FF46251E3B2FD0588AA58ACEB0207E915E9CA77A9A2A5D29ACB0F534313BDB7F6C36D9C27292A954D2F8FD03F4779CA2AF3C6703294801B30601147E79E94D7D8115077EED71BCB97783E910CF2C66FB717FA05DF861069796A9980689A0D1AF932B584CBBB87170CF281D81CC288967899A0C4B1104DAB494D1560844ACF1263C92CB570E0C705FDD1AF700BAC1DB29A6FCF434339863564F3CB9EE38CA7879827F984CE23A9BC065D7EA1BBB2EC5CC06EC8E9F53D267D0D1DB0398AA812E35A28796D66ED7C6608D58407FC1CF26433B40E0AAAE6333642325FC4A7C3901EB2076B2DC31CA6379AE8BCF628E38599F38C058FF606594DC5F9BEE89CEA4F08DAF4E8F706D284901FA371917EAC54D264A55BC8725AD3DC76D7A33E77AAFDDA1EB0D8E7E79726697A24083B1E606F7F7CDF6B4051B5FE0F31C9F265311780AC1A13B2A6823BB6FE82EB62A2DE97E64F67984006FA6D077635AAEBF555BFC86EF39E4B22C61D4E7F46578CB2070C18DC5E19E32426548EDEE1E4", - "message": "E621ECA9DC2B790A45992D6284E9BCEFA98109A1A4CA236344B0693AABD721AFC515382344DDC21F597B7EDEDAAF55987F9BBE7D50EE9D1E4431869E4BD285C3780712DA813B8B67FF599042E96894CB4FB50C309B99B7D7EFB95FCF44C179E9BD67476E7BA54D8CCB591707C68DD8A300CB60C4BC432BBF768D7FCFC756C1166056D0C10C9597AF79C874C6582D646F89262606D8D93F8E2953041254C75440206F342AFC61CA27D2389DFCD154127A9FD4961C96E2859581CC23D6BC69E717C4451B6AA804431F43BDE85D6EC15A4C2AC07C3CDF19853CD9DC2F40810DE4BB950CBD2CA13C3B1B1176361C1E5F71B00DA4E4A0257D248271BCA7E31F549679D907BDE07168F00E61A1BA039CF7F880C04F941787BEC253ED2F94914B9DBCCB7AD21317E032FFA1BC6B5FE8D111B1064EF281DC20104CED1E9D127109AC7AC1898B154DFD4773412CB527D3ABE1F000A09E3EC55E46578F1F105E53732B56E43F0AC9C11151A48DB8DF23779F6BFE7DF1869D6090BACB524D279FA1D42B204F2CC73FA95EE1863EFFCF802A99A4B6BEB2337E947B83AB7EB428A3988FA35D3809BC1C562AB1B06F1A18E43C39807BF1BF2E4531632A0B481E6A5B0F51A156E30CB9AA149575EDF865E2BE87CCCAE90F37F539E68769F1B3D0B2CC18A91552D9A0B107228FB2E6F815CD9B55DEDCFBEA820525A47BF79413DB39C67C6E03C601379C64C7B56B145C99B4DD1C7DCCED972F3B1B6F168A760478BC8DA40F80ADF3E91922CB742A259E753C2EF1FB0DD068DED5FD1CF6AF1A5968D8F2DA098998C8A6D92A4E35CC6D2D57121F31E3DFDC6B97972EA74954CD13675798E1577DB0946D12D1D87867000C7D4770C3C382B100B94958BA1E06DA78B2A3B536D8EB74C8D5E3B395E096B5EF514CAE24CC7FB71D8D70CCCC45867821A7B16F2E5752592C6B3D427A9F3F7186169D409727822921D10D883217E005185E52D4521DCB8D92E4D5A6F6A0882A16A3E4AC4A9FD7747C038CF9E4E53D021233E302C956156BC2E8DF6E9BFF2DADCAF16E7019F239FC611C2B67888D76725271A6244D521C8413FD9E849B3890A76B14865A579073B8573155E6DB2968606C7AA72CA799C2514CC5008DAB902DB7030690F1EEE2EDFA9E4DBD10A3694A148A4A14C8F094AEFB06753D458A11061541F94F253DF3AB814397C05595C8C68A0A8B9EB1A66EB0522CCEE5996430915EA252D96AF3559F29FCBA37A0E6DACAEB0EA2751C70A9671A63437BDD1DA73C7A37A72F5FB3D42C80A70E5B0D891396A7AB0240A0ABC905D2B18D3E20D6473857C8C0B47D8275EE4F4321E5757B19A7A264512556FE053BEC24B2D4A2246FA28D84D72731B5FAF9D0583FA6E6B52A85862F639078D5BD2EF0F26A787C46468FE9089BA001A0D605F4CAFA132DF62D569C2E1BE9B359AA2925D8C808BBEFC4CB6C6C9C140CC7B4A21816E923FFE206B8FA25674012B3FB861CA867B542EF1BDEEDFAF633AE277C046F2D9CAFDFC7D28D8D0BF7D6CDB2C662A04B3C88CB23CFB4C5C9EAD16F93C4F1FC35F3D8169CD1593133D912A3E1A7D8CB66C7731978396306B24BB02003C0661D9AB8758B92C868BE55010587D66611790BD430FAE28BB4AB7E6ADE0490AE323960E90AF321E4A097C255A52DE5E171915040CF35FAC607A5AB976F335F2A13FA2EEA6847F862BADA0A2BC1E9316042ED9D3E2FA3A86024C9300255DCBEABC2833ED68E27CF0ED07FE477951E8F37A801732DDE22AD52D0BC123756C8E29F529F495120D962B51B7C60DCF6791C360086CB377B104B0BD45FAFF0DCEA8A315CDAF0B25490BE7339EF3E292E82B17FACEF22E1F93E7A43529EE1DF4C9BA459A58F5FA7F9C9252268C476F5539DAAB63EFB8C814430C0BB82EA7C7AB32638B0E492C6D839EF7B38706611B9FAFC2DCE189505844C89EC6C67989775029688797E71F1816CC34B4480D80B309C2754195F7E103CA0B621D613329B8534FC107C96ADE14F158C4C29D1A63B6D60009E021DCB7113121F275FC0070DB9EC1DEABB456B303B2A72E5D091225BC716E2DE21EC87A21EB756E7C6E80BC1FB5CDE4C2C6D514F3E218B8AC0EA2969F9E6106B82026A97384A580D95A952C6B432CFF9FB1C41D88164E08C83BFEC76C5EC9119AFC0F4CA56D9686E45D3B41FAE0E4AAD60EE558AFFBF2B76CDC170A0B89DE149C800D4FEDF30E850A74197ADDAAE4DF460A514A6355A1983BED3FA3F2A0FAFDD818ECDFC02AA5275958BE41943EA4AC7009BB0687B62D896FCD7A932A57DDC8C5ADA9724754E8F110E8F080DF0165B67069FBD069C09B818B3434A92BB61049E99D52F9F515067BDA14C72337A8BD9476A6594AA1C7561897AE975DD0C315E80C38399CA5DC6CC9A4AD97CFD933202292056C41AE2C822339F8D651EEBB1971D4A06657DB5FA9E2E7F76723EA80017DF08618FA34FA88629004FC4FCF44C10BC1824FEAA110A8AAFFA13C269F123826489596AFC6EAF4249B0778740AA994142DF63612A65A039735EFD5391F137A1888F6E95368EF0207A4F634B4A7DE8AC4DA5B4A192AB11D31E8FF9EC8E2991ACFCC2052956E6E7F680F50D3B38BFC96C4A8B7C239E34638DB8C57C1D857016878A9C0B13E93338CAC953D5F639C9989BAD7E5DA4B11C4908D6EE5C8EB1B04A56EC4605D15A76EAA82F2E40E73D3A7C15542DCECFC702CD906D668AD4DC67F8093B1330B5DFEDC87B4D24A67FADB66E61C339F6AABA85691CFBE4BF23F237CDD5ADED9EAC9B3F4E4BD78855301EC9742C897D0BA93DA5F7D9BFCCF52D399F04A255C54922E3F8DECFE2334FB15F28E9F112F8C3F7DA229AF60F81A57A0E307E273AB45908BB86244C74E6CBD89C075B6447035EB8C73E57AECD04A9084553B5AD0BECB8BA8C30F470B08A3531D068FAB889EACDC3DE8A13F26EE538AFF7D5D7AA179B4097BFE44F15C73D42DA31C59306B4A0DD1DFDCD494C83789FDB45BCADF36567F7646EAE596708CB9128D7976B0EC17E6CA5C83C110F00AF46194B57E058651A729DD455842045A5590FDC49FBC991EB332615130DD704CBB9F3CF9E0C61DB6D72D361FDF9F4A582B8D51316DABAA215B858B8BCC6D8EDD39ACD4A29A3FD7B6D26B6039EDF4A43EBE2DCEBFAAA9F98041D729C87CE0124767140473DE0885EA3D0BEB573BEBF8855E087BDEA4E5E13E20A2AB201A14B2CDC2AC25D689F2473A0C73959BE81A32ECF743ED3FBDD4E38CFA8E661532825DD297D3717EC8FFD93B4829B39862DBCC96C7EDB277F75A91341AEED6532D8F63B00C0877B4A0FACAA9BBD49A5F190E7BC0D193A4964269DB1F9822699399951FD278CCA6EEACAE2A6C73F4D1D27A396684827FE84D61DC8CB2E71452DB674EAE9DA704887F82FE30C9D10672CF1CC223EB0DC0E24822C6E6F14C29ECDD680B72F6C3FE949E14645564B81B0458DDC8DCC3F1CAD6DA35728C4BA2ACD3D862F8D4E55F5097F99625B5D4AB27CABF12999E20024FC64CE0C2475BE83AC3DA48F08C72CA26E27BE8EF13B817C7AC8CDE748666772CD8FF7BAF0C41CC70D8B9EDDDAC47A49933A8F0154CDB3F31EBFD0403DCC0F4A1A7F538311C0DCFE29125CA52F9F3C4B090AB457B082F12112087ACCC245D96A30CD7C170F83544891408445EFC5FC988C938617373F179796630666086E3EAD584B6A2C38C8DE8F21EC97C81A8784186E823A00F231B59BFAB5DFED13763429099ECD73DE6B1BC7947949ECDA124D765119DC3C97484B25BF4997538F72096BD872DA67FDD6324BBFD2493E5774E491096F601CE10D9BE405CA4A11B6DA99DDB8A061BFA356E5B136BD4A322C51F0095A4D2E284FC10B3A317EBDE388690809047690477E3EDE3798B0DDEC47CD62C3AED27ABFE49D5348E7DFFE828E7E6214AA91008F149EDCD40C13C6A30AF21A2F004B61EA7DB39B0405A5E55A12EB4B5F53E8DF61FD630E10BDF77280A258EECD3A116DD9DEB5FC8AF3FDF223AE99CB7F9369FCF8BF54406D243FA0793E8F02F7C993F3DE6ADEC94FE09FB53ED033505D71B00FA550B7602EEFD7B7A705DD2AA93BC356FEF63D30A20F4DB020823045DBE7A55768383DBB2091EA1C9A80D89C91C0386E160F3702C81947E20CD7F2180B723880A26EEAE1AAD96635F90549E9F25988139A3CB8146847C55219E79586C7E321E36ACBF619D4D2ABCE239F4A8D6B61CAA15EBAFC2D56A34B9887BEB456A889D54393B44ABDFAE6CE976A0EB7B3E04C11CD3D3D109D27B498B588F0FFA26A16DDDA532ADA7D2E08DF6E5823E2EE58D38986601E6C8564296D6D3279C6D95426BB4CFC108769D372ECAAC374C69522CB2F4ECA53C82562D9EBDA93AEF01BB2A2E21FB904B9882153DA2943CE5F4F03011B2295797C37457451B698A9BDAE9C307823C4CA963DEDC4C7478B0E99B3908383505C8C4B2BC6A7E94F42A74DE99B6638DD82F0D3875278AFE1A442DE2FC4935EE5925814D40DFB139752E8B69DA66C8A693E5D47EF6916A971605927D93E3C38F844F35526CF763ACADF3C9EFBEA103ACC1C1C6CFC8CA3D9E77EE44A48C5F3D3F0E4A0ADE138A786AA5AD49242FD2856ABA2ECCD122D1D99F2D48DCD5620959E727F9C2340BBDDB8E92E9A192595AE744B3B6BDD6366528D07E069BEF191B54474F928F0727492167F503364BA24795B937E5E0B6409979B6F0E97D2D25C091D93543E9FF141F3AA47D0E7FB01C29C9FB33B1BFAAE4999B2981A32661ED9E6674C342756C32D97AE790C55FEBC30B5A275B5ACB9C35652BBAB02CD88EF6CB79CCEA32CB76411555FF4DE51000444B566A321D3D575B40A78EC8C68188D8B8DCA0D5943719659C4488B216DCECF3E47131B5A147C37C4F51115C3102959E08162AD203E4C58D0C0B79E0A9A6BC51F3BFCB5C1F90FEE3AEB4BA59B4257116253258D33EE0B3AFDD5146A03B722109BAC571A218CAC060F969B2B794A2EE52ABA552DAA077277561E416E001E84D617C5F0CA2782CCB880D094A66561593F431488878D3AD58B777F9CED442DD7A43C018DD28972FAB342E3678093E9F6F20C869BD7C2C1D8A497793C22350E9CE85027905C5465C6DFEC4B4865DE6D05B3A1D1FCE11527CBCD5EE1374F51E6FE8B4946ED989D98C40867B1FF8E8E3686CFC98E08339AE52F3EC02DF5186D2E91EBD9D79C653CCE41AA0596C645668CFB54FAA57DE3D1D763E5AC2A67DE42C99E2EF7651A8A8B81744771DA0BFDCBDB69270C38E20C5C8850F46227E7B116B38510939221CFB4088CDDB1DA6B22CCC50D93DB7D92C8DA32C11835CF92175E2521DDFDD7C3D96F44A59E00BD3F1EA086C3F43F45D7379082E8576C901459A68D9AF0F80CA990BA4DD9B3B5234AC38A2DA8492839A5F9161AEAA6687D2748F85AC14B80C94B48CFEC2EE53FED527A2951D593D80CB468D81BB94455787CE93218A1079D74145FC08156DDA27D14D05F3F1FE5665A6099625FBF9528", - "rnd": "769AD43EC0A091878262914F6754334016B7D6B3BB766AA52E45EFE75CA02988", - "signature": "8B686F08D2545A2012149FA7E45E86E7221630B84F3BFE343C19BBE61C0F22BAA58B26BE366D253D05689B75D888B639E72BED246C6F874204CF2184C13717FB2B815C8EE1C05DFB01AD6BE89943608DC10FF7DE6F52D4742464D96A6909A1539D71AB8E4768A0E5059196A3F499E312084DBBD77C060F2B1E6CA12F26EA8AD70DBC8593B88BB6220A14E93BC8C086EE0A36931A9CE9A4C482AC26142ED087A5CF157BED906ACBFA0E028CFE5035C8C22464518C45E737739367F04A9ECA0FDAD7D0F7B6FF0037DF6607793F981B85D7AF190764BD5CE9933EC48689E9709CBC7FA3FE52A9E8194E5CD2ADA8BAE6E4563514D71F7AE810AF25A8470CE9C6004B7F564391176F86F23AC757EBC462956FE1093E63DCF20D10E8270B2B15811EE2A273919F2A37046E60F11CEC9D0AA636675E40FD44F2D0A15F94756242E152412B821DC0574446C4BD4154C48F22885C9990981EBF81419411CC36BE2F7E7B65CB4DB6EA5EEF7017DB514F3777AA7B372F03970CA6C9B8A8B5F7DEB04DCA089E3D4C9014640AD7C0BC2CE8F2DF51BB3D1CFE5CE8E2D65DDD8C9422D6BE8B0A21399A28768762822AA38C2575D4331D6B37AF862E670A4D98CD652C1B4332835F567D610FD5CF9C24051226F636CD4EC469B11051DADCD9B56074F8056B97AE9651B68DD6B0D985AEA8E9D3C88218FE9A87FBB242538E177AC42EAD2BBBC3B59DBDDB013DF16BF7A113873349212296FC5D490DB9B001F6268F32F35F30C4848F06B52BAAF89DE287801168367D7DD16739EB087E08354819ECD9763A39EE09AD84593065F79E41DA8DEB2D8A140E7BB7919951BF0EEA30244F34F52E689FE6B67FEB838AB68DB2A4F4E9E5945481407D69A241ABA5479FDD23C32A85A6FD88E0A27867B2CA052CF41DD547FFB3ACCF5AA5636E8B0F122C803B5FF8D36EF4594A15C7E53594770EA4D55CD7FFF6A634DCEE4D408CDA2E1384673E6799E7B569C375D724D4B42C4D6B4C78DB18E21BC47EDFF13B3B7389508791D5D30333799DFAC04583C92EF50EDF33131312814A77C2E3B25A43B319603625C75067975769875EA52E98EBEB6244EDBBD7460D93E1F2AB3FB458E81F332865F7603E0DFFB4E78EFD3469C180DF7A1955D11AFD7E51D1851AD71D89BAA35F2CE875B55F661EC4F704F07452647FF73356A0EE8ED3548C99329D11E91165D91F2D1DF455BC252344D3AE1161A398DCEE93D8B553E290D0BFFC893B6093A8B93A9C5F2F392D421FEB2AEFEFF2408E7E93817689ACF8CD0D4C899F0E064984AF5C291794F44520F80AD49E31065A796F5F19E2BF8DB591ABCB57DBA6934EDDD42F6F939D323B076E66DEBB121953349F87D522D4817049425F53D3BE62A5947CFCF62CC5670A4635D970143A58464ED590419B71CF2D02D4A171A8D3B189526779760201F85C4CA10966B762A1F5C72C1D644FBFB6047A53442AE4DDA7AB2B3F439300D29A99FB59FD2C2748E0FC819EC4792FA2BE9BBA7F85E9AAE0F1E8AC96E47B97E3A84C8E462410F4829DC62E9AEC0E40570BB84ECDC4BBDAF2996858DE6032EFF038D54BFC27B262A2EE165B4D42084AD37AD5BFDF4E32C69CCE446AD5E34732863F9C4C2FE2C06D9216DFD6FD9D251121D7E96559E4B2A08321DD533D48CA3CC6E54FD011154B78467E38E44C32B62C77071DC92406DCD9981247786E4AE9EE2549FE68982DF2F154C31C37AB4BBC31341D6E2979959658547E3B2F92F6343D139D009A58A3AB6AA0FF60B2B8824FC4D1A7C6FE50665412D2BEDDB57BCC2913A371EF27F91ED71B65AFFE338AD00D63B966D2D05FB77634B90E83D335C0CD65F057E18A5981B6D48882EACA00AADF68062A9E1E62DD0183B2CE06837492663B247A847E4FA6D05E0A18727865C5E2BCB96D3DA03DE3F74BE3E5B55DC979363A05E32F8354D51B28F66DE631654312C57E075C74C032B965D3FCBB2CA183455AB93F3B8A402CA9B251B9C23838D1470F82ADEDDFFA7928181CCF5D920AEBED4224655FD6610DE63CC80721765C2D11C24B980B15B30ED586E3878222807BAAD08F755AB42174D3EAA7FD402CCA1805F5E11996877D7FF875A3E7FF0EFA9988CDE057C75A423349965E6AFC4A0F3CADB1072D94F56329E7E361488C19F938DD0AE0514726505264949C5217C086F107FCB5655E5B7790DF81E024529577528545A3A896532646B63FF705EF851DFBC7DEE381519CE9E6067BA26B76AC6D918E6995363F21D4EF66949679C57D7AEB3F6BBAC4418DD6245DB176A0931A108556C3977160673708B2970B32ECC8B331310A5A1965B8A96BC0305290B7A146CA156B464CA4855EB9E29628DD377F10BEE64FED78570F2F98AECED21B12F24D7F754367C801E199EA1B45707BAC61F3C4AAF8693F05E75A49A11DCCB909680A75FFFE97216BC9D4E738E0BEDD4D251BAE9AF42B0A081F92C235DF8610F8EC8D08A0D17A2CA9B504A46A3CE7352AE79C8819301CCF5E8F952AF894CD9C989D56850CBDFDFB639AB94E61677890ABB40C97005E416A60728EE0D81D715A46864B899EE21843B408A30BF4414E65FB373AF731CE0B876AEE6C545C032ED01604DC5273B4A3DF8D42E508D4D289E1D4315ED51EFAC329D7DFF0E8A9582EF59C312D0F0AEC1A1F3A4224E288096A1583E9AED1CA61FB1E9D44394B569AFC1559EF7FE1469132E23206BE0035C0DC03A148757A45732286F5BFE54316D7BBE9E845F9B438B55FB315CDCE57087DACDA1AE85F25CE513CD2D8310CB00A42668241F84E0C209120621FDC6ABB2C0D4423C750EB78F34608FB3B4110AE0DC510EC2A992F6F11F58D5A0B8A0B7372EC2F1BE1ADE52196BC2A35D90498A97206C29359E13373614E43C1027818D006E08D5AC4F4886C0C70ECE5C359D7C0713397689F7B546630C1ADF154AF80FC552910374F66954C9B5FBA1B2D54D3A020932F61D5D1F8B07962B34B16C1791C2E3653CA13BF03B9DC8DB65E579B1C96CD570158BCE89FCEF329D14F4A9860B6A58C7490437A6DD428BFF89B1335C6F6B4749796589D139628B144F4DBDAF0CE5A5FE4975912816723D6BB456F7F17E1A3CC1428736A8952348C8E96A73EE0E6AE09E5B493D0D86DCB715CA8BEA28A028E68BAD31478D8CFDE39333E49E3272C81EF74CD17BDB3CD03418ABE0869EB754FB27301B3EC69AF5A9F0DA7F63426B5C9D59E8E1AAFCA6A058A7CA6E79D8124CD2FBB10E5AF7FAD018E21B75AC6C4907050E7BE626B4530BAD0D1AD4C8FB4367A78A18348214959FF0C745BA895BB9A7014B11080938366192EB24594F0D94F13AE8DAEC64F5AFFEFFFA4B5617EC60EA72DEC4169D3328E50C3DC536F1414B863A09F270931B104DDF21BFFC6950C9B1090F1ECAF9E16ED8DB0586CD171130C64EF87EE80406C0EF971AF88049DFE568F0F1BF71A9E97CBDDABC6614FBA15012000BD7FA0F20286AC99B6963A70E8AD57ED624DE0F128D7FCBE418976384A7F2221DC5FA55B6436A651C7DF5AD36DBA5D7D5B49EE36FC5DB119553DE5417A54640AC090606B5B9BA68A0C0FFA5659E56D403C8E6D1D7D0DE1045AFFA395BA5635DFD2302DD1D3717947ECEE9DB99C01F6715BE60D721F0D3B8507E1210DEBF717D8F9E305C87DFB94BFAE5A7419E4A072FD3DC3203B6356E732C6A4E3105BEABC26EE0FE9F4ACBC4FD978D841E8ACDA6FB02BB49CBD802295B4033AEC2AC0DFFE375EF79FC12E568333D5F09F5F269FF4AF8D15C35EAF8728E0E5FC1276C0DE2B77D5EFAAEB105FBAB62EDBB7DBD769CE491D4CFC8AA53F3FFFD6F0C41C2901C0127B29FEF5B54BB4942BD7CC4DBFAFD6764D59896676025D4E46F189B7E00BB80A5E3D4DA4541B508AF29308718D5DF6D088A22D024D755DB240A9D814015C816F3EFBFBD3CECA28F5AE1835F9D54E6BE8F13B4ADDF233C0B10072ABC4A59C9967D799796DF4563D3966C0B6C163CEE446A7E2A4471440425EF3E60E016B75F7D182FDE99677CA596C91715781C24C23610E8D1B3CCE51A1A2D60398014C2A69F74B23B98E2E20F2F2873B30E2DE00B4546E55210F5C53869D2271743B17E08B1E0B6DEBAC6739BE53C7B2CC7E3300A8DE57D412B7BF37BD3FE24D68D5F7F54D5E205D8F932F70D9F9F7EA15AEED22E7ACD16D997148F58E2F296BD927C67B10009C7261465DF3C4B3615D4325D160E78A4611EF5C4EFCB58C29EBE0BAE2C4877D901677AEC22A6D3E9DAF353307994CEA257B40339E0A3588914851D7B3A395E9762DDA02FC807B8F8D2E5381E760BD5CD03BDA9C97ADC6DE66CF7BDBB7BB68150BF22742F6FE973EB4F6B07224B3DDEC0538121036E33573CE8F3C543E960B3C662AD885ED49907B9793A503B991DC44FC440B90125C6A781E6AD48472887A1A22CD8FD5D45E70CB1E8B4B180DAC613315B7577DEE42389F54B2D0DFC3A6E89164401BB191E8808D08FC2345E238C9B8421C78EEDC0D23C7CBC109316F1D6C7C2C5BBF8D80C920B55634B58015E070213491C5E7FE21740FAFC4CC28EA8EBBB94ED4F9AC93A40B85905669580BA341FFD1D0B036197AE358DF71B347EE0D2B88A1A9B3D7F10220396691B15D7E818390C1031A5156A2C4106E81A1D3FA1436444956720000000000000000000000000000000000080E141A2026" - }, - { - "tcId": 38, - "deferred": false, - "sk": "147499EBF2D0FB64F5DD8DF57AE3ADD860960C33C3960F988CA1F46EAEB4A0AFB0B75B76991704819E12F089F9DF04318BEEBE890516A798554929578BC2F2C5B0058ADFBC66F81B80F6BA118089A3791B33F607721A511601455D6DD453BA977A562645EE6BCFCADC7D5E143E4BF76D48A4CCB81103D3F4D07C10EC1C8B0FD935884166866250862020454372864262654460626454548686317544353276405038366361304583344115288575720274180235474763852833555776146403644047022177681210707322860078144551683008605273620217161704532313545782277646100805181300072646175154310008472211602835242887207546213166786334031861452853804422540646753767853018017757058030160163065781815702462285015403731806238804153264828336081083044475272570706216642062100478820744588251600082673774642671223668838663151762058640323638882680476620638441221045618360630840806306632866368340328241501632864868441816541245525476830353152031656046307423657440088356582101850428657815281377534578071181450152581485166812753385100607536264366788245023742535270538353264842041663577011733657511314673335300876022647565703322083071375867706684363504511048258701423161138512486412835285624242828187577376486543625166106317386687888551551248881286383445017536372386837806160385202423328237847172633151408588051452527033711528545544732362571524042287851465278661828304475647825261651151180785211475210158406110367140048511321780114188623230483447576831486262353106715150075887065240135663674464167605877075263510616812463865028142534070003181342068030427815667313870850071741186615081665456700875460484574856284863100544725600561881673840783488736282158034156774517326438501580401458058266286234827727677371748611255760836140125672303684220665533648117302570237526530702275541556035086508052334048722022462300765631775080787460872605288842887644878580707513658075121823073038218035607616217323847877824751563120331071530182421608362063855200138484456386070457421023448378824154187312181175018181388483326285506884031471356807851708513515014307214715332131846101782037728257088445255608814631501360637332013712078588056865473660661410266440573338715810032618622684721240618044387241161714252204354186357487478475414072052178750011481065704021112848020251083465833480767564467757605566487186334644465684324734655543355441480102272554233644385505247221265087123321421540831831203127024060401837368541205260884537545201763126081571150802567271388857337556114728451155007566521802581111131068115511013548313368242865542352466185265643200675216474566113231127711002414887254262640415433786273414381202837385028713426810673457828427585114338242863122262403603625625601003487274275842514631243647568210540663603243332503448746123078036582460301274166878308418610266471780676780487886814144762557180776804028250210014327548186380580424324654346705872285003757511131306404228612027418320132203784723420386736880833401810641170685761713221456743712250238435521002031362564401604273834308148676268741428842512846488003417344601866473661773314800117256733458722123850778886263153353014430840685618316173808012540752436315188338085036180517363111763148005572333063326152577664566671146486073177056550635655E24AD3C3D07FE57BC5F7CCBF87CF6608BA7F9D6FDE4C193EE362E0B9DB29514D7808BF29D852DEC88E4278C2F5D367E69DCB1BAB9F3833B8309BEB1D4BCE6F5C1D7F04F6236E54F5828A337EBA9C6D44627A5FC53F1B6261DD9911E1E49C14A5DA327C18A2A9408EDACADD24B61214BA8841E8FF69F974C58C27AA66B2C29A37EA1B8CD20BDF157042E273BCC97CF1B5889B43B8E05174B483480C243E6D94824C472D78DAD51DB97052E4677E63D59D0CAAF8B31049B386C5894C5C83DF28F9061490B06941AE20A50C4B84C03407011E3C1AA2B81F858B84E1FAEC3BBFB7283F97430F46A34DB1637F6ED51E62F5F40DCF6D919BD7EFD1382A1A7DEC7C8E0C86CD4241A6862AEA8999B9BC6BEE5CCD811137E2B6E33FB0498F49AA356A4C33257E3466E25E9329CA7B990CE8C8684C22E9379D45ABB976743D9D9388A5CD4FB5C9DF1F904C1ACB0CB536661505FA648BEFF10D4DDA0371211AF91581B6CFDE74CBC27C98517AD8B155C8709F5CDECE681EE06578623D22F6BB7FAC1C4C16A326342D47DA56AE8FF0BA9C7420425697B940DC61C1789E28553CFA34CF97B88F1AB72B685063CB9E94AC4AAD15ED712A9C78C20094E2763AA4F46BFA0D22206566B1C43C3D85EA3BE0B7C9FEBEB1CD2F6D9CE95A481EE55BE26B6F542DAB9D42A95E21971EBC8A5AAF2C5181A40D2F27C7E80D68E3DCE9795FFB32D89EABB15277A5FF720CB1BB9C0A09B7123FAD491E28F53C809ED72EBCB876587344F903CAD896A129F6D8A2D28BF14DC7C2ACD5F88829DAA9F5252CFF346805C3C36113D2C0B1F55E9B6E8A16992E88C40D798BF20EE1A6EAF7CFCF8BCC3D57F51019AE10C54966037F9C641D2D14544120658CDB654A36383E7E48D298A18DEF2F88B9167539131655CA123B58FB556ED06F962064D1CBCB908D0726B47DD1407D4F801657A30E0261103BD6727A54B9A61C4AF42955464AFCDE0B8D4BCDA320544D79493179A8FD67742F335E2C4C4DDFDB3B74F1ECC8B0A06A898E959E7E0505A0803D26CC367E2EEDE97B8E6F944B7CABAA11590D1D654ECA334AE7545EA4542B862C900ECB3ECE6014BDC22D24D69C7EE65AAE5DBCA5831EC29F5172DBBFBCAD66AE0E3D5C7FC7EE600B59EC235A71C9671418C0F677BB795F02CF7EF5FAFA83DE1B6A7EBBA349827569AD44545982925C1010097EF3A441E16BE02CC98C5181B20AFBE4A72748E39E36677574F0C30C228AE133719765621260164BECA96A37C14A1D3363B3EE0A2BC0B6689385537465DD0155D91EB85FA60EA7CDB701157E563B2C602A15759FC2BAC4DC3BD4EC6158D64E4C32AD3747C9685B7080B8CF5E8493D1259711A68DFF3E83AEE0956095B368BAAF2EE426BA3F738F4639D8F8DFD6887C07FD1BBB265DA3324252A59318017101B50DACBE7268AAD9F86A99923E040F4335C63E265152C25DD6E322DC3A57D947DB460472AD2EE893226A0CB88BAED78EDA4A327135F58B11AF0CFB0304D27770D5C28587715C5853E6FAEFF405D232DC045E6F68C65BD4A70697BF24BD548ED4E6B0F4A8E973B83B789A481291574561F5581FF902E9F92555FBDB2E270090DD8C381DB1A388B71DF72B6E3A5D9910AE634AB4155609D7EE50DBCAB2B02874802FEA2FEA46E0B5E2C82F6E985E73ACD1FAB2366241B3FB91F5FD9D9796E9EF61F25BA9A6F86830499887CB429292BC43E22AA3BB0B02BD685097289262977E4CA24D3EAD68968CA1FA1FC73AD6C6EBC350D4BED8E5B99F5C86B8A205B5F04E75527B848F973221C6A7B6FFCD2510C7A2AB90D133355C1E08095973941F956D6C4D0C8162D8A5903A72620F43037E0CEC559C9EBFA1F5C40F8224FEA02AD022C5A75CD99054C0074167307E8304F33AFAF7509EAE4DB6BB8E5ADE9F248D90152F961A198D0F75EE045FFBC0F379CF6CDD58DF946CC65B8F636BEABD39484CB91D416299873948616E85BCED2D0A59B98443BDD824DBC3E7622D73EF048EA184C480960A24FADD1CE2F52BF858682C49FFE86833A8F7032BAFEBA2C03C67F4791A3D05CC307AB556B53B72B19F069308A5B4818958832B80E11C76411098EA480E6E61FDBC7DED4B3BBE0C742387B4370AD64D8B57DCC60A95E6775BB979BC0914DD5BF274A573812C0258B6678A3A411196A965DC4C9EF486B07E3FFC70B09BEFAB779BD58EFCF11E4616F5F43891CA1F4FA0486646306B607D8FE902042A457ACE72D9895241971AD6A60E701175465BAF161A9A14F29AFD32D9AE5CA1987A87D530063AF20F6543215293C7311EE7F6490D042FA1376E7FB9CEAF97F465815E6F7D8DEE8B671A923131E8A945B9A824F2CE9EA0F094B44C5D96B78C1D30EE1D3835685D305573E675D967D8771CCDB1788A1CD3623110EDBC0D915C2929F6C2CAEFD3C5847BB7FDDA8378314CA9FF44CA81A853B4465945115297310836AB9A5F6597DCE5D86EFDA96C13245C7E6A93889DCB04D9BA1B8CB5AE482D529DECC965B4FA10E55FEC6D923A6006CCF7D1A63649A0AA85FA5232B69C1C716BC1C35B644CF1BEFEF42C2E662E749FDC5D10FB401910F677F47B4FC2762AECA1DCF501CCFE0F686E479931CF45B72C679A4C9773BB275E954CEDBE12982D28AA9022A951BF1EEAAA4E77C15C5474DB649EF1382ECF7440A87B122C0F34C834FD967F37D5BC8C98B10D528AD54101E669128D99B48C9AA9AB62D26D064D27A1FAADDAA79E007574BC56DC48BCB465A54269C7257CA84571022AB6130420899901C5F9F746FABACA4A06504860466AB7E3CE0477711A80E747545B695153310A58D493CC1A5B56FD1C83408F5C964CC88A134BBCABD79EAB21584B050BEDF3BA4F60C2F194EF8F955630054F576323C95EED1376810DE9127229247C70EEA636C4F4B6CF6BE2F4FFE77E488CED88064F8F3FAF918F12BF1079555C0ED58180F64A1734DD4EED69A10A81211486C133C4A67B9E24B3B2EECA4C3315BB191FB44ABFE8F15A02C19FD93AA19852CC9A1D894736BD3BABE33ABC47960499C978410C4528754952FCE51A735574AA8FCB7B87B74A797F69EC53A7D4EEB2A9A62464F22F109EF867F8B2D9C01A523C03E2577E94AD8C67416B9B2C815B47A81A780603834456D0AA4419DD39A63EF25F0E7316F961C4E335B1ED341E272433890AAEB231FC23A839A30AFBF0DED4E196817A5D36DB8129AD27A1B5DEDEFA133AECC4D2C832D35031F73F8E3783A5769F7C2627E58D72D969E36453A6462A339E91EF343370C4BE1B1315FA2D7D06355FA6F848610033F4B858DC29DF5D67874DA65300BD5F42B202D51660937AD5C9C247293EC8C441CC4FD5BF8B55C201E858A103D194F1697D5D614A912FF0145B6B9256C923170E27BD65F21AE0E86A55F642C6BCEB9F90B2515A98B2BFD903D23FA61E2539B9112D96CD9D2A15D21F12F488B8AB8A589C733443091A79E7EF84B9E8BBCFC6ABE4EC0178315A059443850D05CB04CC74863B77A9ADB43B3BBA7B58FFC63783869A", - "message": "F17E0B4F668B372D8EE6661B1913BC1ED8C42533A9F555EFDC0259E84CAEA24997F96958384DA4E33E670A7CD3D16F5452F9A48DF7B70E5BD7439C0B6E769599633AED89670E187D511CEBB7502C33780DC85EE14805838582D16751CBF6FF291F5BA8064A7D1CB1DBEC937A3D912C3E9567016D9FB4F50B41380684C0F46AE49628487D6AC8E00F36FD963D11C4BD8956274535DB965168D913CF2B8D53AE722AA43EFB1A8266DA9DDD04F11CCE1F106394D86F669489D5236300D1A37DEC3AEEB30B30D4211D2E96ABC9646B75CCD9E472A9798E9D2535D5131C38B1FD8666417066E8A703830C0D660C8BC95EE9409CB2CE29E42EAA559CB334582E2B95A33793C355B5688BB29C8DA839F2C1E9096B4A6346A1BDFA04C51B5133B61F9AB59FFF4DB368558A00F96FE7DF337070EDE7EB77C8E134A384462BAA3F688422836CDBA963AFD0F4E313457B444241306F5BBAB8D8A207914863FC835D389E4574B3292063E0CCA8A0C31AD0727D0681CA88E2DEAEF9D6AC8D3E892F5770B8FDE3B7F94BC40CB8523968B2AE4F94D0D29254F4153581FD6EFFED2C1B32051152726964424F99D6BF9E175FAB67D59ABA5ABB3468C32B6648F949E49ACB566999141A84E94E2A8EC7BDB8419BCAF6B7E487F8729C9E256CF653B36DDE609377DFB329A21FB922B2CC57D38E3022B9FC6627452D43361CC3B6393D0B01F7E59B4CE86355C65DDE29B53BA8B961DCA6345FB564C3FCDF5F4308F000FEE3D7EE7510356AD65618B2CBEB410DA37A25B3B73820E3F06DF6D0B7BFBA6E7829CA6BC3DF22DE1593DE5442A5D1BACC961FFE766829C84E9BCD98EF4AFEB5AB5B579CA50EA4C2789C1CE0006E7FBD05E61BB57565C9D0C66F7968A19B7A3173DFC3C163D7A0E84C94634039EF38C8036F336A7C72956F1DBB7346F6F056DCDC55CF3937822D385097270BD4E78B3AB67059F87757874319FB44900FF180739F3827C529EF395C68AAC203B5AF6A624C83377764F614041AF92870DF95E3129BDDBA3E49D7BDEEE8BDEF8B5CA23D416B2425F3041C505977719CE7DD211A57361EA6F3F0D58672773B93B5508C75B7E00592F9EC193142D0AB14CF49352A7B723F18D2591E47FD1D120D365E21058C41E61C079D8C964EF1001138D3A3848471F1D65519B79EFD0C2F8683682342E1E3E873CEB99C6D49943189F81B542DA3957559A003E875B4B4D5A30AD62B807BF82C8C014719FACB91D93E8E6C53D3B0395CAEE99E3A0E70E9BBE8B367FF23D2BFF54BEE046700445FF7DA11585E709D890A09F9FE4070431B9168475D59C26CEB96ECDCF05CBB4355AD290F7D2A015203450D296B0E69ACD23B4BBFAA55F18806583B5AB073E39734750768EC427E6751129D4EE1C9C527F19D50D3F4EFB85D151552FC915264A194EFF330355B4A220E3FAF63B3069E5855CDAD1515778627A63DC336658DA60076515580211AF49FB3654B7A175F9BD94CB78A3853DBF2EA6F154A2AFAFD8759BAC6C24EDFEA0FDF0501F10762F53CF167BE34ECE761C7389F356A31F9F9A0A46CAD705450039780A371991A13921FDA4644239BA2F4072B1B1251776BB3519E1B059A81D083358B59D6E0EE8CE34BF1ACD5E54A98BCA9062F40D8858FF157846026FE5F84CCB02C8EBC574BFA366BF398E169C238B1C41A641E4E80AFC448B122DB25F8D6E3D216981EFC5DD60D257DC0884AD7A37960851ED44357E3484A8B192D591FB32C7BE2B80C3C9937E3EEA77531C8FA5061DF7BFBD82552C68B23D4B73440C5B59AAE89829A3882F55C5E43270AE2061D01BF5AF30FBA62B6FD7DF08E31F5962616B15837E6FB0FBBD28BB63BDB50437BB106ACCA67DB67F2E6707DAAF4548012991E784D5EB723AD8AC1CE77AD48267B27E4E3B2072F458EFFB6EF0AA8997CA102648302CB6A6094B8B3FAAC6A67A8D57A254370F583761D2043B8BE4CDC61846D39DE561DA0A16A55D8357E4C66D2B8743CE6091DEADAE1BAA1A26CD5B56DEE3246133C201D", - "rnd": "E48C9BCEB01E1FBBE27BDF559C1A74E0BD0ABE1527E3F56DFA6AADF6EBAE2015", - "signature": "CFCC68B4D767A506E2DEE986887B7DF1FDE091C9A4DFEF8F5F8A23964DCA77617B74BA19DD5C36C94AC78530CAF58E70413B3B9749EBE02916F61A1D7EFE87603FF18F2A2CFF31DEF6FAA4A9EE4C143C913BA2F5C10C0A2A39925DEBE77FB16484FD50F6EA70EEBF86B82FDC6B10101B43AF3752C657AC891C87A4EC94371E723E33E8D71B2128B1266A475AD5E128D623CC00D0984975FD9D376581070B13C3260CB8D8DA1A2BD6488FC70C6FB810C78674F74142621916B3CE00A52163D3D0FB3E2499E4914385B4CEC89E51DE90BA4AB9F667E5833C32764DC84B236DC00F241885D6A5119131CCCA3DE0E89A8DBF03BDD280E1C942601FFAF64FB5E897590CF59A7021C19A448447EC367C40CABE30CF897A91E6D9310B627D5FFC15A25BB6B4D7691AED66E4007866ECB0F6DBB8254B4814F76258FE7540D1AA8DF378994AC2851DAEFD23400BFB52528F72A38759BF5F22E237EC2500F49D96B54DA86506E0056901C55D829E0BA59CC2E36ABEC64600828E1179D5651C92AA1BE877F7FE541BB894E2B5B2FA77FB7CABB7789C8B2E5C032745B09E4FB87E90F7A8EA7C90E058083C15A6A6561FBE9FE8D7E6B62A34CFB7B1E48D7C36D3EC448D7C9BC8319425E4E6FB7CAFAA121B926415C503F685D1AE2CB99DFCCAE2E3EA17749A37A9C22E4E02880D99FD34BD2DEDE4C4E4E43A58F6B93F99DFE62BA49701A6A773F78B8DBB1E4FE3C566CCEE17ACB2F5BDB3F8A618456F624D4278868719EE203FEAF6EEC3FEBEC8EABA4213BA1BB60270091DF6E20D6D81A586EAEAFB2674A39785BB56423EABBB237AD1C1527DB92D60D02E5A0ABD98AFF4A4EA66A809AA85EDAAA0940FC394591F40D9031D2FC2D60AD97F8E33BAB951A75C5C3752D54E45202832DDECFD3879FB28D9C040C4D5EF78CADFA9C6780DB94CF0BDB1D6ADCE3C6E331B6CFF6A96A597233CA6B881FF02899C0A3CEC78CC31CF6DC644BD4675FE1DCF623218F0BBC395CCF8FB202782B606D6F1F0F6CF55757DC478513B8DD63EE2FA31F2E4C9B4BACC2BF35263B67BB9298C398524C53F1FB3043193836177C1957A6E2E1CCD3B1128D090D82C069F5F4CE0DFD007A00654585759873F7EBC394EE005E00FF2F375953427FCEAEBBB3ADDCCE7D895992F8E21FE5CED0DA9C739E7F9ACD71DC37876D94F920F01ACF00DD424CC76B8761ADE563BFC079B47469673BDC3B8ACC68564C654700EB9B35A21A27C314865DBEC2037FC47EEB62C3659586566A1F436E7FE14B8DD66C87D3D54EFD5DE81F5EFC76C8018632A2247CA5DA307368FAC020330965430FAADB029C0AF6185F992DD2217CA92AB1E23B9F3D8CC671D4D9E9FF94C5D817C264C053B79AA5181234035E983EB7FCA98424D4CDF711052B59294E764425239D2CF4F29A9A093C354C444597F7A1BD7DE64C253B27FDF16456718F8690FFFB43743E0358926BE4947379BACA3CC2239D53945758E606098AAE26E71FBC7546976AA7F450B0A6785289CB263854EE2D57D43F785CBAE9E93E9521B2883259AC8F440DC51BD6185423320590EFEF05757D6284AF7B62A7C86812D68DB8B558615D8DDE08203416200FCB48B8576D1DF03BFB26DB9CE92555804C9C7A42B8010711ADA044C41FE38AE5CF56335F6B8A91AFEE10DF5D824099DE9B4ADE1AC3FB44CCEF6CB96ED96388309BEFDEAA93C6DA9553521E80E467FD498BD7D10E793B7DC94E685DB456682CDC053C8E5078C2CD27D836FC57116CE8A1DB7DA39D66BBF2AFD3C8D76C7AF9C972651B240E1CBD50157C79CEA885578A295B4CC3E668B9AE19A16BE6F5D4CABEDD972624A478C1C2FF3B74C6FB2A1C90B320110FE70E3840D0355D29FF8497BE7BF6396E19A3F7C3A07AAE04225FE2BDD824C271008DDE515D74EB71A1B918A5E7F2D4FB533422F56EA91353C24BBD6865294B2CF58868340032A05F1A81575A4EA6AAAE7660CBA27B0BD7735E8BBEF9E8F71B1B353569C0C9821EB370BFAC36A4526CBB6514F99833C4002D71000EF65A42F806D1BC0C814F6BEC14F9A20C8B0566D48059EB3BD1B3BB6E0551A6CE3EB4016083AB166537A2129C563FDA3A8CF6C4B1DD46A00BA54ECC3E8AC08D5CE26FA905F9280CD66FC4B7A3CEAAABAC03D0C6B7ABAB3C961340A50AB9254B815B571D750E2D2CB7F8E0EAAEBE3323FF99A514560532BA1192AD5B2698F49F03106734CD63E747E9A2789DB32976A65D1AD36D1C4059904CD81F567333CEBA530064CB31DB858D6BE26C3C95E4C783B9D07D831F9785B60FCB5FA117264A4B5E08319299F5A60407536B4C1C7CC32F3DBA3D1296D376F8C8A7E8C801163DE845D47C07920AF629EB4FFE047D7B941F6FF015861775E4D048C91C6B59F06B4E92ED72876B8024D5565914BD043EB19F73784E1C6813376D06B3CF86F43690F25446A1C208E6AEA4266DCFDA454E1E9A05807C57636F4A0ECD925E63EF140D1284C098FF340B9639BDE032CDDF6A3854E7875C3FD3F014F2790FC6C49E719BD77352A235E84FCE90652876121AAB57B96BD3B0D9CB147A66DA8C26A31B21AD560775D14F03CD378D616DDC683CA1E8724F523D42BCC3096AB40F4A9F4A3C1502AE7DBC72FE79366ECFFA7A864AB3AE7CB05884C905200CAB8416E37CB1C944B0D1969BD8579160EF306C02693ABD91297DB6DCFB7721EBDE3E3F35EE53F92B0F488B51453E72DF159BB6C381546160F3C6316D3A181B98AC13AA19060990AAA0395AC223BA4F10EAEFE5EAA3EF0BC0DF804419562FFB89145D4E52E0F3F85C9D2A25204B391ED52636D0212A7C46BB6B3D3541567F6198CD1E580BF4DB670AE6344480FA9D4BD9B587BE4569C109870E6D9742CAF5A36ACD71E9B1490B35DED60D19FED617D4ECDF1012A59CECAFFB040A9012813C0D8B4AF3CCD95951F484F35B14FA7FA7A07F0D7A827ACC5682CACEC4F712C22C0D3486E5F96D07E5113D076F64FA717F30992C9CE5050837AF38E339EAB57B7F5AD137CDE9993BAC44ADF5621767E8C8B235D2BEE00676668871CCDB32E5C651AF726F1DEC1AFA80D79DF5520D29165CDB2720B687AF54EE42C7A5D01C9E4F6512BFCB1A064DCE6CCE97898189BE1173E415847B3374C1819D7AFB262BEEB0361ACBE096B5A74B74B26B47EA1AA32BCC20B72271B8EEBD1E3B4E9BE53625257D879145719C96A2A437DE582D711B53B42DB0222267BA36B07F585DFE58B897E6AF40814A1446672225EC259C885373E501CC88931AF7F358FE861E875852A917A412F624CF6272DAF05F9ED9934215EE58D5BA3A245AC1BCA4F45ECD151AEF6320C1488F38F8337C40971DAC7C1A478737660B0B998010198409445259F2356EC3377692F1D9558CF7BE671A582D13FADA8115F6DDE62F9A6F1EFF22259513E5553F94770297FCC7FC3BC730951143642F72BD6A29A780A667E07DE2867A9DC44392CBA5EA363843AB31DA2AF05C01F04289D1A954E682B510D8143FDDE22590453F9331A94387C03AB5E08FEC0576BE350D1C9B5745BB5B6E70A5396E1EA20A771ED9B0A21D549D56588C7A4D69C9EFA38F96750CC98122DC6B4C763F56F76F6716E36802A5A1336BDBC0E6CFE9666F8EFC9289731B399BC7541D2E3EB4FB5EF8E05FE401AF1352B1947844F46F9D6057676C70A67E49D537B60F1E817699075EC4EFCE6CF944C53CEA223B897F30371719BE4DCB33BF105E50D5FE53D70B37B0ADB848094FA68A46A2528915E5A33C1B8517CD9B2C8BA6EE5631C4EC182EC9FE5D9E567D1435D60058495F46E19083519F8D2EB2B6B05CD646943BAAE4B700805E9550987D2DBA5F00178D9E24EE24DB8864D56A3A519617C7CC267428EAB18CDC7BEBFBDF57FAF2EEB5D0DFDD8705A701DC95089C82FF6F533029170E288CA340548BC889A10788743AFDC3A815D470286C15030348EB0318002B3934AB142EFC13F551289CA104848C794C08A2682A2CC25F635966DB64B0EE1A1C5AAA884E6B02675A8023441D3DF71D3809E877C9A9E2138AC31CEFEF674F31C3AAE3455137FBA0991BCBF9062FA3A62A6D7E949404C86D217101F8BBD641982A91D7745DE1CE5FFD7FE6D44772A45B486BC3DE7D95E4FB63F337DDD59DF0090B3ADE036387670200C6584C8ACDBA478C26969C6552F8F9862C29D9A6236207AD365CF5CA7885C9D098F4EB9778F9EB8C30E788879F7E0AEA49CA606E11847EE2291F05810CCA64A19C46BFF2D2D99BDA3C8363E77C9B876EA25D52C8686C072D15C81810F1D71C7D0B675313060DA465C30DCE80E179EF23BD960BC0AB14BAAD1EA734F347F28D1703A7418F67C9B22E0A3FE69AEFF2610EAE2C953BF3B4A54804E9625C4C719245C30BC3DA39637620CE63935B202EBC4FBD94F12B5BF75C6BF0C6F8D4AA7A0E97675DAC32D00DB4A4F3F8468D8849BE1D280551E6916BF701C5EF848804E327108029F43B9F0DB94BC30DFC31B1963EB311E11F1BB2D19E4174F0EC2649E71794BBF36B6173FC4117855666E331B8902B979FCF0C9C7EAC885CF7D7F0CF2CA6F2EA26946CD32ADBC307803077D1AB7FFE14D5FB7CD9D021F4C4E8CEB20556F7D82A1A50004687986293F50EF52818AA8ACED028690B0BECCDCDE0000000000000000000000000000000000000000050C11151B23" - }, - { - "tcId": 39, - "deferred": false, - "sk": "9F5162E3523C1AA02E0BAE9DFB89A07F9CA8DB95C744CA6CF4AAD160767AE9C3A7FF4F642FC967BC3C645A8429222036A60F9418D35186B92BE26D8EC1DE9365B8489584570228D715221BA610E28CD73CD6AD9F92AB0AAC5F233DC801251B5BCA81C6F1274F720753931DB35386BDB83304770C5D59FB0529197BE8CAA0ACA387233753335153502373823668407331780522135801287265818206102663321627422001644708740453145874055406070356747286183628143556131380408870743613613158834526165508443764526884066637552470454457715858830788630522116362416414674348455480808271820101757103287020485208432165417765652072520371778038622581461526738560767607156110380413816265647602512116821067767504121464101471602652516707464303212287564217220401867271473804274856353383410842447761351360033448273306781277487060174480120476175585474683434385612168448544350076445111388234530078685184742303062454024111684133072631684142642424032513234683705818514161371200132567065403824778040443048875204438035734540314170451878153826780523651885004247050874824876080448815623722882350142670173123078515025263600311580601766472753363352632236230284854082552027660582450683234818087211616050882222408474721813411211245086077707136513082664701568204704587512871443240561168866562637786511070552181001740580542005334630067857180664757117057642275526337602836372215788181145257302286480750253033100870803636442436821035163165445166282376808401832831368352638683323268445162873305004021014608037085351830370120033708724744207801631543852288563176277056403156745682857553837368808760662411465843763631130672651356853701846531622060638764416235876005228272540364422325524736806158188786536804518463474735077774250664710361806541855661633704208660770486728112800244324364082455362014470685880371441467443342342207315888888826112274156231156704245770462516574301747547107081162273125760474460634442456177231233613178551050310464101421571321715357848738430275181147051254808223806485726356583015020830312246836552725265007845075108628312046412477657533085058261020158358611545770032504083033532435288604848833143556505702287437838702275580675034484414405023252560383013665226382515322764338531638441115450246455184218361865818153863734213010544456635658417726302178240728355546862575463156621526546846460214218367840627263004066204368818557580710266153627535434531066607783456316348525873800051285045875465216768325515664128084036528642621508517018863283427315555232770862264700572077282540117046714486317372602837012651150501403786447627341337003236850464675558513037085061176725484686583807630561853635648858485275325552311416744508160182442540820026022655527378713308346320715345238501668581654103865684506466502040622186151106131748080800526143332417477461038455472020408114305228857185780573186418467757155210437312713002723273631828452132311526212064125712468556746435274535013131386534651741403134427383618512288432623162021500470253663680544117186274278311221223608370828823258355705753200640482378388831743724082527430335318865366601888553611668052028728420273484641778236138463714835516104061356603470663820711636568135472518724606428685354571437841814335520373150308335122F2C036F38164B2AF7118F95B49A8126F9AE2796159EAAB46DFC77ED71BE709BD3EBE789C23958F655F177486CA3F0BD71B2C370CB86600681601818791318CC90BEAFBB33F7780F2636753F5DB671C554BB895A590A3C34AD859EC92A5D3DD5BB18375F655362CEA25A099A6A40E055FC38E481F61D5AA40B8F8668A14AB0F46AEEA5415269D0004377688E78E91CAFE42E960CD01AEF79864DC84498D0768702D11B520DC55AAA1CD4C264F34D254ACCE07DBD852CAF2B0138B4768A41C9BD942B705664B76246CD27FC37734879EAE974CA79F788DFBD0F7B521EEFD00893305E1C9DC448B9A08734E9672C3260072A602E2B168A0C967D68BF3589CF14829C322461045C13038833F250FB6C150CC997531CA425C4239FFE82BF12FD68DBF7E077EA5E72852A76E207A76515C3489A53C4BAB49B7CAEA9A1F6698E602A4775484BDD0E5EB12853EDA4A3DFA3171B95939268EB08954B275AF38A365BA24B7324221A603B29AA914C32DA873136CEEFD1CD3C6C7C78BEE469BFAF5BCB6C141EAD154B4C39E0212D5E60A46D692475A2E8E21E7563294C7DA38FEF03DB2CB0B33AD3350A302A5ACDAE59C196F7AC3B2178513B6D2EEC8E6031B9CBE885571DCBED47F87E5D5F92371B95BEEB02C57FC2221F2D3CC7DAB82CE056A81669FCC765D84CAAF9EB74550A5FBA065188330AD7971E3366FC68AC93962DC42DF7B3FD975A54E3AEE7BDB3AFF8DD0549AEB7A869548FA2C1EC173BA23B398208166BFBFF877DE96867237ABFE6A6C1E326470C638CDD3A1CE19F6A233D3379044115C374E8C4B3B21C2D3EE087363C53278B07F4F4422F19526CAF41688DF07E0054FAB839F4055C5CF5D2DCC0E7D9C96D86C558138DFB8060201BB06DFCA64212BB7A05F1C72501EC7650EF79222B62C251B0BA6BDFF869E732CAE3438EA6376E4E83E35296540DBC15ECD7E7E27A5C927D22CBED981247B6D58081B8C90D404C4A7A6522903199BF189AAC6308AC0580ED1D187F15A892DB3D9AA59CDC7AA728173AA0879F692D9F79CA021AE1BA7B439BA8086E4D03C25728D128126052D45653B707C066E178C54121356A78E775BCCB7CC11421752CF5CD35318E261B9086D3432ECB0987C6CA0E741577F738B1B49EFC3049F2CEB4BF09010C020C5336D8237984854D2CA866C47DE1B8BBEF2F078E6660EEBADC43AA9F96ADC3F024F48F48ED83A1138D547F354ED39668F4806E5CCAA92428F831739BB5445C79537B03E8C447AF88914A56CA3F165663E0C45B6400700AF74E90CF48ED0AB7F61E2274BDD1B10EF3FA4A2DA3F558439465FFFDC71212954C50351B5ABBC54799DBC8E7ADA4C479A22DD95A454F0BB03F0A84E6F4F5177610CF67CB26D533CFC8CC6BABB68DA632AA0ADE67D3EAB54051C49E1AEFC070CDF6DFBC9C03B322E13EA2B574657CB236994B0D790D93543D38C5CA0C4326C850809C429CC4EE3CBFA325902BF1594A3920129D33C9511DD8E439E768FDEE1C5755EB871C1BF14D3DE1C13069ADD0199731BB9605AE914E3E4BEB3B0DC6D50EBFC2D00E00541234D5EC10DCFD9B5210F9F1E16E1BE473EEE318808D5AAA256F50BD440D07D5D9BA9076A5B31A35FDAD131ACF3E41FB935ECB1C8843D024E158589000498E9CCF857B7952D4FE10797907940739D4F3D9C07CEBD8BBEB4B28617C4D1EF1F49B8D36FC27B704F5DDF0B9EEBE7928BE31C09FB1CEBE9CCE00A2CFBD49011AEE1DE6CEC117B211226A40CC2861589FE90243EA1A9B288147780565F202FBB03E83A2EAD79A7EBAAD52C5C4A171D6041069DE143D350A7827216903F641214B8442FCAA849DA1EE66E5180F86209A9F94D73A7C4A1968C968A6E69612AFDB3FD38F362BCD7D4444AACD293815BAB5841FAE715C128F1BC34C363AAC54570E14405DF42748F08FF1E528FC73DADCA7E5783A350D075075713BAE715C8108FF350953333EBEE230430603B1846F7183A90D222043BD7E786FF672FB2C9CDCA738818602A00D04279D60B364F3EDFEBE8C279D58C5F3B789DD1FBE6410C40B9D45D58F57E757A94AE7D1CC4AA9DC6116C1585F3C529345ED47EDB569967A4D79174406EE0E0A7719ED69C3C67CD43963FCAF4C8CBC8ADDA7D5C8FD2D49D8B18519F38FE80B3A9641B99B07F61C874F72D38607CD3C8AE21B11DA9135E26BB9E586597A9F5DD49E23A359424D87ABA4B59C72F9640F7D29EDD9E05AFEC72ACB2F463CE7DE96C312A9A346314B41D166B8905CEAB296967D9C98EF4477C26E091A9FF2E6CF186D72A256849D2F0BB7CA16F57302C06A0FA51DE1A47646E5E06A036FC5BF11A9475607788F76B91B4EE8475227742560A03CF234EE3530CF50ADC58F232F27AB52C371087D81BE38B1D6868E557679EBBA3B5AA3D0F3115AF1AB8058451CE78123F299F4C3C86CE237F931A2DF611AACCE6E8E5B134A1F09B507DB54F71DDE544794A603F7EE17A7524F327408644174B3D7EC7D7441DFF422BFEFFE5976EE67AE80AEA88597EE0C0AF43A7DDFE5566344EAABA3A49CF1A9B15BD11872F64BBB992030D3F3D9E8E7AAA3BD9BD3DDB2CFF77930965172F86EA244C53253D4A630137F7B49DD7D00BB2D890287A75D4965D407CC3109F94F6C8BF308316673E12AB7E83AD9292CEA3B5F1AC1EB6FFF1BCA4F16863AE454366BCBA3893956CD6FBE0644A82042E464A13BDD4680C5EAB189582D3FCAF88AFD0DA02928E904D57C7522AAEAA3E89CE8E9E116B6AD0B71C66F3ED605E9D006AEF39FECDA3AB1F1A9A1E242664D61D156CF37B5EBD2A41C12BF602E270A0BD5099DACAC707393A71B1902BD19820FCCC5B1CB8A09D095E4B8266BC52209E0C52BD98491712DAAFFA8E247F2B9ACD254AFD3A0D2D89B1CA3F3012B7BD033E8D5A60D244BC53899F90A2D150C55BFF6195977047318A0385D52D941DFB5B5E9503BDE5BED2766ACB5DBA7B2C645B193083583C48EB4637EAF6CD6EF3209DB6E8B6B9FE64DE8F6E78E322922DCE38BA78FE2EE9DDD09DC9523D47C86090520FAF6D0D6529788F77CB750F7DC9AE7EAA4D533EBFC3BE2A65052660B65F8393B449880441695EA1308D867F4E98E36BB37D02A84D9E36A67A250739630765136ECD677F072E20E52B0FAD9342932682FE75A19A5F3892A1C1F7B5963DE8791CAC7B5570578667D44870B32566FAFAD8AF812D9B416993BEE1801D3F526DACEE2BB7B1C22311B18AF9B39B569D2C2BB21D8CE5F626F25080E248EF3B42C2D07BE06EC2C6087F167661124AB24BF06701ED462C3758A1A3AEBC28273DF3E8F4752CD2D82819A127778F6AF0FFFD8D4E5F39D207ACCB90564F70B47A8744E113585043FE4DB499096EDDF1313A8D186ECA61F3D6E93049235DC0C43DAD8CC9BDE021DCB273BF82DCCB487C7BEBDA9078A0122A1D72572D8DA87F0DF2145C9663D6D1F4BC3B9995EB39B249233F34C82A31A6566A68F500C79EDB0D8BC812656716324D74BC6160EA4FCFD1884ECEB0CA745CE12DC3", - "message": "666342529637B4EE440E7B6780137833E969A054400D8679636499630C7D05FC7FF8D7E06A3228E697C873E17D99859184AC2657D98B133E43AC84BE1E4CB6B7EFF90006A4FDDF0FC179E0534BCA26E823B7AFC335F5F580FE7BDD4A41E960771CBFABA381A948346F5B4CCE0C11B921F7C6A87EC4D2779B9C82AFED314E6B0E48EC6505EB1DAECB367395AC909202AE690F98ACF8A86481C597C02F747EA80408DD600FC023308F72A02728543C325DB1246CDA5373EBA8FB26291BAD206C5D9CE9E9C2EFB4D2D5E9EC20E45160A8EEB36D50E0DC45EEF19F50C393F8197C93847889FC2AE5CB0104481F42658BF9BFB9213529B4F0D626E614A8BBB6D71D082E866F4B1F610FE89704D1B26BD406480B796A1522AB19F4C3A95E3ACE6206D6FA8A166BD30538243757D4CDE49ACF444F771EBCAD179345F14250588547406CD2B64C3A1855BF2A35182DB5F00A361401E3820FCFD88C46C52FC0922F6E3C650DC5D81BAED128D186ED95395E5875B2D57FC7C2AC4D31AAD1FA0C41274617CB528B0E65BD0C94C9A62F5D00835D41D270E8D8473A8EF11B2A9627429ACE00E3ED19979F2AE69AAEC601519D685B40F93CA70F282A04E4EA2B394B58BA5BCAF7CDC65CC4577E798010024C1F791C5476EEE19D64C6CEAA49DEEE1DA466ABB01220CABABDD22FDADA0BD5F6D44EC3D949DDB2036A6EEAC287832EF43158845606D69AE252663128F14C0B4F88552D78D2207628BCB187AD021D20EEFB2127E55B5E4C01C695FABF066EB4F21BEDDFA8722915593EE0B452D861774C263797A63E273C68FE9FA2E77AB40970045F0E7969462693C7660C97C64AA1687C74740FDFB8522A6649EF98BCDDBF4B777A9D79C9F4C09A46775F9151A3B1EE385FC43AFF80EBA1D9D86D2AE16D0A27F75E3A7739D9C741AE748FCB5A2B02D473D106C704B7A9B2F2D65291356F0ED642BABC547725BF3E26C8F1A932DE772C6AA39AF0434DE1B3B2B29DF818EE0A9F1DC2AAD2576D770DC14A14E56B5B6490CF6B7F3F0F2C99ED8C13C1EF3381883BAE5C05976E4797EAE2A91DDD3A6EC774A1D079A029B9FC235A1919EE5759B7DE274F5332CF0660480CA9F80C4FF306A6021949EA60AF8A028FD59DCF8FA393DAB56DD04114CA8DEABBD950B3BB8CF8F8E8A991EB346D4CF89068FC5DF11B225C5DB49847EBEE4F94047D57ACA81B6A8C328FEAB200F08F4DB5BC2F635E92681285F8CF26182A87D25B92DCC3BA01B5C0CB5BEF592EA8552CDBB07273C1AA26E04112AD5DDB36E721E8185A551C6AFE2730F00D8473AA253355AA5D004C70EBB5E7F92EB928E5B1D9E0620453DBABD638B0BEE3AC5F0EDA6FCBD5428C0FC884ED6C3501F3A2AFE5139D6D934D1AF10898366CC8D05D57EAE9ECD0680EF84E4673AF1E45E3430DA4798F40044AF7C64034E33ADA563B340CB119450047287454A2B88A135A25ECD311C203046909042EED1791824DF0FEFEC3796AD0161F677D93AA0E4F25B457C56688CB5539F7851CE95C20AEA608FEB007B0C8B2EA535BDD173DFCEF26ED8A0DC5378B4BA006AE8B2C552372FC7FBA8F99343CB0C11DFCF2D46C5BE883B2710CCE1C2D619898E4446089D0E6452F4973257FA297FA582AF39823E4854A0F15FD3C68A146F2E00F3BCC3709EC119416B8F2A6F798AFAE756F622041A7D4B17B6A76E27B5BE73B191D18514670C78C14DACBB937C6798BDFB7C389810BFE278D12A7D079256EE272296C71248E6538F8E42C40CF62C3233AEF07E93D5A64858E3CE0ABA9C071401A9B1BFAEAB47AE6A100E3E6918D646DBE5090EA65887D8E2356259F750739DBCBBECD34D08274CBD96D72BBE888DCB4DB55B3E29B3CFEE7D0EC7C5E80545414BBCC6F6E4240C371332C2764704E7AA0B5A6F3C91BF5A73A2C0F7493F3A8F801D1E3096329925BCF1FCED843772BF7457F7006785526F7C42F99009D10E33F0C709F8F6793FA10BC1F49EF12BAD7D32DAC857633B468A0614A9C5E3A4E7A190FE1931B4B58A4CAF6A3BBE1F68741618DD34E1729F221A08BEBE70B5DF1B477004077541C65A77BC4AE695454F48B4956F94FEEC67B598636AF81F3D468795FF810D682D1985BDDC215928379574F0CDEBC74D651AC88D7C248EC77426A905631E2ACA4016A05CAD0A09B4E521CCF2326C35D65BFAB42A4B4D7ECD6622B7D5D63E59F497A76D03B21338193503CAFAF1F4FA3C0C7F43CD12B271BD1A527FD5233EC8B01CBEF72CA832559FB7C6DCBCFA992FE607EB14AEEE66A38ED4054617B2EFE011C", - "rnd": "3711CD61AE1E39F7801877C3683748BE454387655A043521F8219FA852DC0C1B", - "signature": "2D9A5C1DEA8F5ED462769BF45A1B5D281B31ED6F16CE8B547A9D81B7B12480E495AE568A8B18F5BEE87B80B574E66D0BCC8F6853739A949C6888D6449F21D6F61A9E8F19FA163A12B551B50140E3F49F5BAB5722AFD390153D9B5258F7041AE6C4BCD8888E0A056EA5B74340E4D69124B9349B13D9547975A79FEB60D5723B6BAEC2D338A0DA3915FD187F52195226A3807CEF8D57AF65736FFD81F10BD58A13F05BB1C28E4E97360BA67711CB534170AF855269901BA3F738C09DC6B002550140CC78433133CA7BDFFDFB9CB7EAC0F3AF757281AEA53C43FD5D09F4F4575A25416F050C8F357D2713723A4F365EC58998065C57EC0FCBA4603E446633D40E4404400C3EEBBACA13401D9A2633357C565D9DC774EC47455EE7FA4E3B6D05E8D4C32E3EF8A07566068D01DAB05D6A14B864E4CAD161ABEF192363573C1D3E38A7E32C62AF8D21967BC3D5DE317514E5A30891C1B207FCF996B9DF7064A9BF338BD2EE5B9547075431A84CFE4B7EBC3415F527606771D0298EEB6A7C155E4F5237C71B89AFCB7B8B71913D51EB20E304C27A646E053218CFE3E41DAECB93E84FB0576FCB66C84AF9E78467AA0206D36A1B3CE7BB83A6EB80F6FBF569B5E82BD59F1115E4EF608FA471FE3ED6E0E7FDAA0747EF0E3CF740A60F689981014F3AA57D40CA7F18805BF0D6471BEDF9FD04B50701CACE98F78EA999D4CA4DA767AFE53E7A228413CA8EA5C9B1BF1DA0AFC16A0B23C3BD9CB07D3EA28C137D64C86C9ED9FE8EAE3D2D88B225AA941D353DB5F9D9EE01E90E48F52C8108F5CFD8F12CF6347F5B301D5753786A26CC746F6A6DFACB3A125C4CC009B97462D0AFCAE11BD43C9856A38EE728DF44A995AB5E8D66FB1E12A3DCEB16C7CA4CFB38A4B7FED58773BA7A96E1D006D3F361CA0F7D17794F8FEE001FDFF62CCE4F00031397FDA5B817DF275A60E37F63ADEB4A2B3B3E46ADB3626800D393A4041FE43FAE1E72354C375FA712D3F8FBE2AF6D2E9D90113A00D4B15C7E4E8529AB1FE12B6F623A078C28BEADAB11753B3F3590FC1064B3BC7A461AC30899EB67F375754D2B4D2B0B41D4411917CCDB2DD198B540C8F0D17A12F832C4E202E3FEF328A129D40FCF43DCB3A9211D49E1D71471C273A8984A6B3A0C84FA98F63144FAD648B4D606EF2E1C1EF518D57FC4ABFB2C55098DC242079D40C1CD0890F01E747E4286E9152EF42EF2F4C2AD0FA5BF3F86BC8A1127AE74434E0283846530210E1716EB7D8381579C9AE937A5D21A3DBE23EE7E7A521925A20BE48E5AE3B00CB473D04AEB9846663F5A2B87F3EDE31030DBC4F65CF264FBF011CC7405C4D807DAE98DBE845FFA86871735815F6D045C137F3903FB581EFBD1AA6B989D2792A1816778FAB55DDF814106034BA25412FC43D773079FC855B8AA1C8F7CBE7545161A879730AC3C46230AE8A20A6180EFF36695D886CA575D298D9348AD934AC34F45735F9A790462332F1B22481E11EAB21AC84800F64E08C1087294A22A17ECFCABEF280DCA36CA2D10B32BE88F526B2E381E4EEB8F82C5EAF14A6D82756078A99416FA331CB1BAC71573375ED48303DB31BF34A2B96FA96E3EF3B5A09D0D4E037DAF2D6879C7296B399EA071F9B50DBD924218C67D30DB92C648E434C9803447C95A23FD28C2B299B50E7FF87DD575CB3D8ABF6996A21E756BBFF83E368C0CC747A75C47D55925C5761F304885FC8014C8D8FF15800A25C3DA35DA5FDE6100A1FF86DE814308BE22957A37AC9BDCE9EE89EA44D0CF48AAD3FC2632F03425FEC7ADB3EE2CA5EC6B3CBE344D6186BBE0A40EF8E52619679DE54C474CAAE2E09669D43B514AB48BE187810E58621A6B6270A785EE5C440F1A02C8758574E0779A9CC11307EDB501D8EEFBF1A3F3DA9D11994A7BBA4EE73CFD41B9F450AA774137ED4FF90ED00A5C841C06DAE8C90E98269FBB2643ED1408455C511006DC718FD3EFB88A8B41FC996165622387C1F3FEB27506B053F12056D19E21BAB7F1DE32F6170EDF2FF9F5B7870CD21223272BEDDF6E21D2A3F88B2689130659F9CD3654FA08F8B31914EA5F8D70D084E28480C5A690CE32F65F8EB562CCEA4330EB7A1102013F070559575BEA5854E7C3943CBF9892C428A1B3C8D15D9EED6EBD371EF2F207902D6826CA81ABE62A83814F322C240C3BA283A8D9A5F54120C39F058EFE366AFF3CB1E1C13C66DED5DCE1506428B5E601DAAE7B30607D7AA3EA67D2E885A4114542ED2063D84BBC61BD661B5ACFE1BA914507E0D655F6BFC752B2F93B997363A9DA6A837234670AD2E41B7B31A1C75FC0B99F66F6F4E9CE08AD54B9A0532B2932CB0EFD127AD24AC4BD36123C5F88F72D6ECC9E16DC2D9D6E8162CC6F3645D840A2F54D74AB1EBBDA5F465FA0DF47B027BB6C4EC0F51DBF4F16C8C9C197AC908886A516F0518080171FB9532495C66442B3F2920FB49AF74A23801B9E9D8C3DCCF85890100354C4F85C2F579336CF2193973EEA6B93FEE9B4A446756BFEED28B64F54E31F92627F206103E8062754932103DA2DBB120CC39CA8274E658FDBCF615876A9F76EFA745899E6E50EBA5555A148078AF22AD9C6A8F13B1E821F8B9203528D3509FB3B583668E3DEB5234B9A1456DAF8595C29F1DAC002F9CA6CB991AF8E6945CCCD9679EF77F449746815A05411C3406809CB39A64E3EA0026A36DEF5364535BE7094EC1B785738B9B6F468E66BA9BBA7DA652810103EAB853C51DB5754C6BA60128115CDEB89772EA0CF90F9299DF85F2816A0B2928711794FFD404E8890CCD4DBBB282AFCAB43652763181CAC8A795ACF1F5A454C343586AD7DEEA72ADB0E173027A329702D0A994C26DC6CC9E1FCEAD323F1E8FA1AF8F7D53D966B03F6C89BED6E5AA6D5933BA4F779CE6E49DF847DA5DB7233CB876CF828E09DFFFFF74B42E93E940CAE644B07809C0277053E9006C7630213CF9A3AD0B6209DBE5D2CA786EAFED7B71817E89A0158319F7D37D92FBEA14E479F89D76A433010928921336B3B1623210101522A45040B13F258A6711C0074229741EC4D0A32D7CF3D5316DB30C445D16EAD878DDC2F8093BDE9A50DD90423AF0CAA024C1F610F4F0E62776F530385D9FB78B5E955DF5089F447DA163584217C6661D8EEE5857A9BBCC885C8A3A0FE47DAD4C8F2D72C744357D8CF3626C3882A98F1E74FD94091DADC472D51EE377606CF1904CF5A79F4EA26D22361B05A6A74FD93E6493EA463BC6BDD096131D9B80FD637DB8C23D902DD00EEE3C685DF2CEC6242229C6E922AEFE5BC7C738D5F642163B5DD646287D2A998C459D13067D4567EF63D20593665BA9D6C2638A50D88CD89D74FF213792978D9F826AEC33836271B0729FC17782395E235DB12D8701633C200C07EADE539FFCC155B372288D42016FB3A8CF0FE101B32209AC441BC87353A07EB23B9E273E4E4FB7D778C8492D183B74DEEC030846B0BCCC56DAAFDA649E99BB21B12DDC610DED5F573B205B87ACDF5C4FDA43AADA1D39F0CF31B57C061320A030A58AF342B05B23651ECF8A529AC0455E2376956305F1A2DE87D6AAF854CA4198A18D88E791D94C0BA6C373D789C9D6CFDB05034B689B0143B8E50F4CAB95CD6A748C5FF0FD6781106D6ECB88B647AAFA713B15E082DDDC96ED2B05324FA8AA61A2217B1FFB25DCF7C61A01B984F080E2D91C2C41C94FDF9F2697765048386E57091C8E63724685A4FB0F13443272AAC3FF4EA189542788CF494CA615BDB2A45C16EE31A3D89805977837A55E9067DE47845EF3518B555E05E8F34466114D48936CBB6BDF0B6D825798A13299BCB96C8370752E0657E340FF4DF44B76CBE922532A61CF89D06E25C44CE63A111853D2961DC635070841E4D39DDD5D865E1DDB5B0B47AE7ED9707618A282CEEEB5F0D4FF78CC8E34738B108191772BFC0BA8548EB9580D45C6AFC7B0A5C514EFA0EB6316D813F48806B0091EF4316F86F93502D498C3A3AFC21ADA0A84C0220A888DEBB59FAE43A40F4E8B779496CBC36A8CAB83AD60513F31CF1324FC045ED4C5E41ABB94EDDD676EF8E325B4645BB8585EE4E5E25C78D17C18D02B1D296F352CFBB3AC8FE92C1C41DC6F59B01EBE4B69509A9A4ACE60D1C2131DB39061CB4FEF6E0A9FF942D13D98BE2A5F05FC6DD634066A3293BB0C0FEBE17A5B9939600385130E6CCA8BC83DFDFA75FFBC9EC6CC92E4B9C2BE4689069FD562EB585EA6ED3A10171DAB5F41B80888C00B2A7A18BC036C6922A7941403FC9FFA2A3EEC363CCF35CDF07A1DDAEAFC28C0DB9E75F2A4138383A582369DA10A713D2C2B218B8268159A961738AACF2CEDB45A8E219578B69A0379D5365023F6D1E4A5C062A8A1F13F900089A46AA7702287753C990338E2E9156308FB51A4FBCB6BB4F59E86A8BABE79FFFF7997825CA3788A66D2E34BB53A0289637B541A75FE84A4FDDCA6B176909FD0344B05D049C0BCAA846881B1CE020B0EF1A5E44844E222B4A345BE5659333991322F6186CC243095AE2D2084BEC7087C0CFBB427FE9528A266EEAED7C97B8F0F7C44B7C9F512100C9E5589178BBD0C1098C39C7AF6C3DD0196C62596C0E07141F263D8285EBF409155E6C72D0E2F3F94456979EBAC057A8AFD704112E40B8CEFD8695AFB9DFE7F2000000000000000000000000000912181C232A" - }, - { - "tcId": 40, - "deferred": false, - "sk": "5F4907DADD3BBF8744FBA19CB11CF2D3E9E2C1530A1659496E0585CC3E5CF7D53BA1B7CCE9D9C863A20A1B4B54F452133EF0DE4EF06A115B08F3B9956CADE9FA3E227BEFA2C465BAE9FBF760FF37C809511E8FA316E7FE64C881C2362FA1D7387670B4631ED3C9592F8A7419583EC55215A49AF5C56F838FED8A08EC158DB2F801735207762158061647336216358042330080005772680162715880838061517283545480743474267483032160575114205718322343526658361288166735684026734586875126348884637402542258373335223400073077546866381522137408051612887673065404740765023788370075068032225546076074267183056441464431726178328024212674736331660457607501178501812241742345680142015243018742572724614215486675664753460014521722602437104860704661405172244888522337034178213784781068521347004484322571052208601320055503134305170740034054142578420178647772626222748566181244653374447610470171715347843317336546461770852468010812014347580211088344154723061807035760720105553788353566421621454777480882322705382421322172853278807334756768684285820235326622800855281612345062024661837411834632443228065022228434680448107472816881835503386158083648400857813537524352536845061735203766185746835323827121277705251154576427636022547072742780823573725423164051301415640332474367414501471325701571843178630556031537364151572467834300054704035774805836231511178184361511325421822067643841837323167137718817610443646254585664667044561106313720110031720132104576770138733104270571573617808747155521154126484177630386438502203254602873064145336630763574364585361435014164676340450874747305672517211271471717117133623320027700710383674060325250125783024035515173263077310814763432341036611852855744318407035846230805306003048507476128427254121447744065803137373111118722334611350888831144634067012727424301332033220468004578122370804616245052023372467665372213544000788068446403578453644434155001047270060775658047271867222228815115126348072685777264033463064156668162833868042813430158188607152515824550520700517388306868582301307514718718836053244566802816888545522231446527762122767248661152560603852522716665085704617268013737703184134341218451720718140203365113543808813687400627840568187008357161034625363052765738767001337648876648575725582467541545038304512410836561375730120340817064641330114184786537654450622560840637172871566525143567106274456067871705863513742520082833856182771328428748763485823577478102545306378682526260876483662261233837220683758035136548706744613456610845218412746275831018871843737878157033866662716208076118163030611881773235760654781685722467125156520385527355473144660841188656653154523023832085784374801205264143158571108344404777478048346806504265152871251610402262281120435826858681325680315708148738781314766755406744125241670424624703710561887124818833134000143403180016788024656202435840484628811570377684270277514702166828520202085531476770354624275317668248334876310544357083451622484226685373028082231224466136260227655215521606383205160704341228208648356435276543820628834087221750786215453554306358715267015443364822617555473731322257861888825760273282874214121552865072648270314820405717862171340071676532448265341446085775164878F75ED5D97F994917909D08A0462F133B7131F17619A4683C9DB104AB6BBBBD94FDD3D6721B0F12575021288B1FE48D1D679C36FF45C259AFAD992EE6EA8F1F69CBB9E3DF54289F41E9D62B1BEDFAC4F13CD65C84218533D4D0F58AA78E01F0529E7B7FB9476F38FAC1301873F7394BF9537257D3A1258A264617FC2F109B94DC42B5391C0B6F724A121134D064E6091675DA25CF069F5E61931F73B80D73662E28969A642161CF7B8C27A8407F5CEC064B60285131C509FA525055D77EE8938B6D39DE1BC74513BA8889E53DD34CA1630F64C8C5E129FDB94EDB97551E8F637927F64159099F6DA61B73C10F22A9B6BB8E7AA556BD683954FAB2776FB63CB7B9E83F0FF3B5500579E47C1B8CD8C6E0FC9DBF87D73DCD08DDE28BEC7DF85205964452D7206C9A1E9D3C0707B882B46EAE2F2D74B28DC240B4153C53457CB45A6D114F16E83B930B10CA7A7933AB7183558268A00D4B9202AF6470FCD091E691E5219D85698D1869E35C565B668217B36543E99BE2A659BA095D531BE91D0551E7AB01A347CF00B0C0D90E6EE8F9DFC5DD11AA8CD0CC38F86A0D4618D76B3C3D2CECBBD9AEFEA563001A67D55A6C689FAF90A22C1A26FE69B2CCCEAE7E085246A758310F16BAD61B80E240EADB4510A1B1A007F6CAA3B79C0DBC0AF3FA605293842831A4D5A8CFEF3DD4E0D93DB39C406B988ABEE5BAEB88D566C645EA2A46B0E0301E3BE80ABCA972761780773C7BDD359BC4A5F6E6E860AA6981E8697B0809C2F8FDB308BF59EF7F376E9E9A2D8BB6CA004B6BDFF3734E3DE36FACD26900F060E15C0985E95D58703AA238CE7D3A05C7A9301FF9A755727A2C48E8952E22F6CF6D73BEE4128341FAE00CEC74164C8DF7DC2BBAE65C46BCC05C38CF91C62F6604D1DFA6822179A5686317C0DDB15A24E91B3E5A639B827FDF6FBAE555EB22D7830B8DCF6DB3F0BBCF56A3FC71B1D72E32C2789A4E6BCE4E2273C1FFBED160C334D33AEC3C196B6AD9B0C25760021FC7553DEBB1D2E24E1D46F083654A653C05AD0F2E6050D375645B98409B10FC118CE1636E852BD2C77A3A53D681B179D986D1679924FA7C587EEC39B70E014055656397FF612B79BDAC6C5B15BF854DF3F85CBD4386A5D9F3C6490D6C89D362C458953DD3A1337A13753E4324470C032F50E2E4DDE7F3E66C2E9F95035F2EDDD1B4CA84533B0FF1DAF61AD0F7099F8DE106F0786ACD1FCEDB7FA9BFFC8B026853FF4CF970744394C0667FE5447ECDCD99A25837838A8B9B0C55EC55A1FEC97506A30E207907FAE78453A59EF719952B7CF24E65A937E3A7875C9E3B79F13E179CBB1D01C462110286AF3C2985072AE94CE3094273B3613BA246693C9CBD5FBA4D13D5FDD4913E202159DF262E56183C822F8312CF933CF8120A9F6A080CE975B85A32A800C3AB3BF5D237E614F5DE8A953F619F262A9FA78B61FFF1C8D2C4CC4B71E83300EB12EE49EC00E2F89AC62E90DEB8B97DB4AA467AFBF5B0AFDED5FB8D654648D8AC3715157059E8FF9CC2E52349CE6A32A01AFAA2E54611B61901B7DD9BA4F3BF41F55A4D80DA4341AB90A84AF3D370F82923F11ED4A5275710F205FBA6ADAFE57A965DF94E54D4C5366729810100859F209B624A46FEB1E209EA02E0302DE4A5A992AC37356FC5D0AE541730F5FB1B51E39289BAF7CA375DC84BCB9B7C1E2C87C05689CAB4F8DE8D0AE4333D3D6F6653F7811A1A024024F99E70D89A2F944C81CECB1E3BF505C6ED4895121465529AAFF12FC6951D0C311B7D08C97A16C69B9BEE54A74A003AFE2A8A98BC48BC22429B2DA25B48B487F4BBD5F30D14FAEC3958645C1FFB1E71C3CC9FC65F97202C0F888EABC7AEA621243056941DE24F09F5FC534B8288C56C2514ABB5CF03C7E40E0676910E5F16B2561B9BB6D2CDEB3AEF95FA828578CE009A65CE79591245192A33210D713B6FD63D7DBD22E358441BEF29D8E7F7AEEBD7664AB2300358CF78B35AC56587B5B3B1C537308CB6C483393DA6AE47D6FCF665F4DD2F5252B0892EE3E12A40DFE3A38EA65BD40035BDCAAA733518D453F9780B657A11C9A606AD22FE771138919D03FC5B3AD1C925E045BA522D872B147328D9D111606417649AFC4A823BE4093143A96AA3AEEFEE8732026E5CC704267EB53AB00857F271B408DCD48C7284174AFB13ADB60FC1E5686E5318890AA32F54F449F07400E21ACD68976E9C98850EF9C68C5AE2E9210D0EB79BF9311F7A0490046E8631D2FCFF51FE898E5436A62B94F036E695F08C2CC2C179E3FF268B26836AE51FED6F1BBB3D986660457BD80D862D98C00CB840B3C3108500463FE10E20C21A32F936859792FED3D6A0927032B9929B15C783E78DC84BC931777A563A2E47123CBD38A5F7DAEEE8B0ED18AA8B72DB2767A5EE00C38D2CDBB5CF3197690EE1693FB26944DC24772FE009A661B2AFCCC4A1B4E4BE8A71D74F24E8CDC676044753BFCF423D05CA7929AEE13842FC81B82D6CD5D9675680ACA1D5B9A7C36C5F4FF85F1085647B81FCF38F3A686DED1E6AE5E9CD27433EC862C570342D48B827B52E478AF7148E90C1AE9ABE1C7CDB4B4AC14CC5E9A0F469DA306D24E49764A610AB8E2D2A15215F1E4AA0520170EBADAC390240DD4B01477C21CCF5467FB6E2458B1E76EB5B0822DE190C6BEA190CE8DDB8E359D80EB09EE3C90D75642362DDEF90A4784ACC5B7742EBC541A601E4DBA4DDBB527687249FF7DE44D4121844CDBC909A9E1C4800CC76630145BF961521C5D3AFCB6234380A81690656779FD6EDCB95B8E2BB92E16CCDA1D6D9BA1808BF803AB2C7E44A7A5219FF05AEE1F0E57DFA2A4E5F84E5B05700E7CA04D3A6F0F8D2465A8DC7593D7AD5F13B00091FB6A81C9B48A10EFBF6980729F64C5452485A8F94A023268AD707ACA872EB87BCFB5DE783283BA7C8596021675E7500AC298019F7FD0E8F451823BF6F7D8A73931B4574510914670E3827346DF29752724C6B594E68A967A41A01F0E1E3271D64F366AF0AA01661442497F0FDD4869F2B7FD84E3A960B7761B4902ED4316607022DCEC48CA00C3D154A4DA13DC2524A8FD56201BD641BFC3996C4E51383C9D2873ECB1B31F64B5DEEB0C1E30F5B3418D253190D940ACD891005B78AD52F4CAE6FAA8576A7B304A6CE063A5C883E306E87582FAD28EB7A7D2204DDB1885232CCD7AF4895E54B98B7E824A88AB1FE35C6E4BDBA05AC4A712F4E431B70DA1BCF8321F7A3E116C519B54A1BB014BF31BF3521B6F6D788C229AA2A4E4CEC92539259D4F518129633AFFC914A31D149E77CF81A525909F7FE919644BDB18030D31D65881E231CF4D2E0F8A5137BBCED6F5336B69DFCBBED4C02AB92F604A20BABE3F5F4960E109F7B17FAA751DC035D00D32C5B4A4296C2FCE3032D50F62CC1C65CE11E1733B51D0F0EB99EA0E46DABB54477AFE3BA0E604CBD3D9BCAD3C47ADE33373474A210F1B0D9085FC322B9C3FFFD2E983887D5EF0F28956E96DE322D4F6D4ADF6DF1D9DB35D3AFACE2430DA4", - "message": "CB606EAA2755E6C407B02BC3BC8CB09246AC6767C116E70383AA3BC920D9BE1ECA482E28E667F46C5CDEC21190FB11616A0A42586260BEFA8855111CC143A2C9C1BBBECDEE1B9D8805C9C78010705895C6FC0DC2A380D988151D4384F0F936235ED281E890D75E78CDE5D83BE8D317CCD90215F767009B43A34EA44D936B6EDD05AF53273C3297DBF474C33EC47DD7BA6AD6EF5ED63BD3B2F9BE1A27B353EC91249CB8C08E81A2C960EC323AB29502BE7658A07FFC927ABD70E2A9DFFBF8C827AF76D4C63B4D120A56ECF151F84394A39E161F7B7A9B08F863F40DA18CF9B5523D2B7E4738A0D495D31B1B048BDDB17D8336D9B14A05522EBE0C6610E3E62571F17D2EAAC118D977C76A81CDC9C605C904F087B26BA7CF6CD5405F12179CFF55E8E5CB90A7B66E0BE944591A72286E1D1F7EACE23C0E57BC0ED6602F23C2BB2085F4F638E42448B1D3C3C1C264DE42367083D5D3BD8449DE1EAFB5EF6741CFAA07BDF8B55FDFA1F4516A6785ED756CC3C5C871F36CC2DE7DA9551785199A1B3B49AE38D1A208FEE27642969B02F2343535CF89837D18583F8E9ABD5EC11837E8066A7822ABA1934E4BEF0CC5026C1867B4D99D508221A6C1D0E37335574AD1830898081B5AE80FD2200BA423DA292301D014A8929B3F810E86D20BBA74B35AF012E6EF256EE97C5C6C389003302C94DC9EE8E9B13AE46AF7BE7704D6457B0BB00FD5506E06C2E9B9C6E27705373F868BA8503680646AC56355F5E758A2423FE33EC743B6B83C2DD5684D1BFF47BFEDA6D0A718855F4A77538B08AB33975207E1E2BEC525E65633C1D595CBDCBD516C01287FABAA2421A103EC2A0DEBFE026A342AD850B3C016257B523CA6014D647D98F4A935028631BA3372853B0BD185FE7C9618403AEA60AA5E8132DCDE5514892835DE71FC7F014D6A133B146B75A6AD2E1BFB15D68CB37765A6B504D49CCE6E86F1B1B27FB41978ABEFCCEE61C65114850679ADC39A7AD9E85E2516F8AD3D37019DDABC892CB4A8C8BFAF51659BD68BBCADB111D4D00B60AD3ADE335CE2385B41328937510DC236174D7DCFFB2814C69282F930087E6A8BD52CCA4B63CBF6468EAB797962680EB5DEBA8F3E5BE08D788641FF5329C706BBACEBA05FC3A0F1A78CD9AF88A09B0891D522F70F391676758B8EEC5472831F3E331A146AF9E3D8D6C9C955D2551906739672D649053AD6C05699439C76BB70E1AB05A1A70E9E03AB6BFD490FD7CD0ECF2A630FE365CB44D5C22309FD8F43D313D92C9F64E831D6A5553B144A0F98E35F97D3DF4ACE490E4B6A8AD8E44459E67F4859A8BA2DA5A20AADDE2C7317AE5F9B074D5676C31C6C81E7CC0A8B3B848482AE2BF96E33EBADED49A3663BCAF51874151468C8DB95AB41C8DCA6DA93ECAD141AF7682F2374AF7016320B6F5D355D8DA79E77E9989E79175B1CE3E35CC4205512", - "rnd": "94D882E5E35BD20DF2078CA27853204705F51CAC298C776726A0EA6899449576", - "signature": "0A9D0D669B0D9112ED2BBF4F464BE80753D64C9D065514C8B401E5BC78E56E4EB2C365A3BD440D96602E04270F07CC9BD609BD966C07C1561E48193F897652A9086C83F544EF794CA205F43817E4504B819CEF546284941CFB518BAB745A600AB56D7ABF65E784521D4EC35851A96F4608311FD71C714FC628E59954B164CFD93F84F0D5A69D9E06BF73B6EC1C8B7F36B519913B1BE75A992B86D297A97EB13D734B4E58AC80600628554AC3313A6AEBE72C1760C1A6253B986B9CA1F2043F53A43E1A9D314377701D9512BAE6B587EB821F7E7D36E9EB941867E22E11BD54852DA0B3D8701F7F49DCA84658AE4B63BC1FDD559C30304038309A909B29F2704AE4E7242EBC06F35C709C084415F0B991EA7252BBD051E6F870BBD3D24959E8C124532F7C6B1264C7BA18550500078D62030A39AA4E48F31350C87897DF0CB584F969DBA8BB1697A6B9CBCBE819434919D90E6E997FD7D8EA4A2C4CD7EB655EE74FA8B012E166F7DBC757430E4D751AEDC1DF217BFACE42863331FB83D63A807D2CCF45CF39D19818C289F3EB7E1F752697986145ACE1EAA4947DB24718D48F069A4D57C952D6E8D9A4C260B29B6377765A8AB3317B8F7ED3F4939C9763B52750C066CB6D0859B045889463CA1FF62DACD9AAF6153532E4FE2A32255A3111DEEDC8631416CB928C6369184F6E61C8EDC09E28B6D382CA3EC31CD05823A6660900070E56B3166DB65E254C384CA4F91BB2D8F3B1103A67091F17A517865D4443DE85D940D9AA2A280C3C8460F3A3F435C4513ECEA54C0F0A1CB834988D0F0135DB45279DF57005B37D2D340FE96F5D16AA19FE574DD5DAE5E1A835E974E2A1FBE6FC6E816422E4C5719AB42E0D78897117680A29FDC3C3D247DDDA66B5CD1A7869362D579C5A12F8A5937714E6A8FF451AF971DFBA9C7F84BAFA24F5226C2DB44C0A0DC2AD7502B52AA097644DD9C89FDEC6BE25F5CDC99D6798AC79EE16297885A26F7BCCA399A17CEF1EEFAF0B6C44C5C43D405EFBBDC834F20D060018CE5DDDEBF8115AAE226A668DB4948251D92F965653296A45A98A63DB5071077FAEB313D81ADDE2B21DC86B71480FB92CDB38DCF610151D7005C8554FC50AF9B22DC9A58A30C5FA39DD78A0B0BEC362DE3B89D3BBBCD19B8817800AE4CE15B0D0DA4597A62B07065D3DB3CA3EB347D8892B1D0A83CD96CB9CF8560A3245BF506BA1D22D12020B04612662335FE1158846CF2FDE49DC210FA2BF1F4B09C4DF9BACA7735662246A50EAEBE0B87275A0A85777042600D7AD6C7FF6A0DE53446B82C086A3BD327474B101BA56BC24754188D827B8A6EABFD3F10968D7693B7EEA0847439890CCB20DB19A4D994BDF1620BAA7030854CB80081D76CB0612CAF672CD29FEE0185E0C1A843D55097ED538B54A9312CDB34CC55DB6534EAD8462A366B2221CB92A7D14C4026B8603ED5034072EF744FD00E389E75FAFE96BD8DA37F360E7145878E8D9FDE772084240079282E487C26F66B70DB0BDBC6B99ABE6A2C5748316A64DCB2F8156AB521C69BCDADE6E025ADCDD26C085AFC660DA4329AE005C5A64782B109D8690FE9D36AC008F77BFEBD4F4EBD0308669AB1DD0FBCC041B8292902545B7A5634DCF4E599EF86584E159016A22D5951BD133DB42F18FD36AFFEDD0618AB926906290E84921030F876750C2CF95323F7E585519335A9FD22E629C20FED1C281C9B4B86BDAF5F4F52D55B56CB375DE10CB923AC7E260C7502F98A4298DB20AA2454441E09015A45C3547EDD63BDF3FDBA673D4D0DA9B20A8EE451C38533F1AE456CEB478730FBC268CD3DCEFDEF7119C2F5DA22C2B4073BAC7CDE7861119D4DDB95867D9562FF64C0ECC96D7E347BE4ACF4FABCC22F59A086D5D4C811FB87B5E3D19727A01D33276F69FAFA41EB01D0514CE680D62A8A45E3480C3903FE3CC799F95FC530065659FFFFB1450284EDB571B47784391205BBF6E601419450F27EC59C0079F978491807AC6C98C979F81DABEF718DD42AD4F16F877820A7902C727DB4363059E4612E882EACA68F0F76E3B652ABFE3A0F23D87EF4FFD82253551AB49CA754EA6F544B6881F5B16D6EE81A0571471B59C229485A3ADA0545045F93F244703B4A943D5750DBD310A2034C2B93793FE4A3E840631B87A2A109E03FCF9E417E36608249B52052F1B29CF227A54C60EDA204EE971238E9704993D4EF1E6F97A7C49EDB9DDB21869D24302A8D4CD6B8FF5A92D7647130AE2E0B4A7766966437E03420AB875259C6A659123B29C5F76378718DCA937EACDBDE7E57084BD2A5617AE24C2D3CDA8DD85D528D855E9A1632A8B78530F29E198D264AFA437B9A80787F08AA3E2D2D1A95963B5E32103AD4F47FBEB64A123AFE5B1D373228EEA0F3FEF6AEAD3A39004F3344FB4F2DD586AE404DAE7B502E6C28A3274CE9C90F490AC11368848D1E8E020CF1AA2676B74006C9E14E20409D99ABAAC1E518A07915970D271D9CD06DDDDC2B83D770E1490BA9C50791B602B558B23EC5CB16343AC6CF024444D518E817B00294873D65ED20C792D5F8A4DF2DC08F9B7E1D7D2826E883B253DFF508527170E63667609A0BF39768AAA5C0459DA7DC0576CF4CFCB65288B6AC77273F27C65CD37183AD8C5842DBA3094691CAD4327DA9EB51687BC57E38CC4869C944486D8AD50904D7F8D8F619EBB48145D28BAAEA8AC88C9DD89380D0E3022F7EADD1CD9D4299C789BC5D9591764C251A2AF1C370BF14D854AC6CE7C19D2FC29D809C9037C6FBB0CD50FCFA9773EC94E4B16233940D6AE8FB36AD80E1CBB47F877A2255B1C652CFCFFB5577AF0471738A9AC7543C9AEF3E77BFA2A4F8C557383EE4FF34C78E1D238A7EA2BAB35BD1F59690264E8EEE9F380F56D77A86B9B6E5C7EDCC63709803808E96B4131B6041A4C5014C33BBFFD8557FE32FEA9F3B4B1A67E152CCB065C33689F03556C467058AAAF4D207C255BD425E2568377463F123A3D160CC2719183A04CE4AA4708EDD77C1A26E08634C6324E7F7698B025958E7253A5780663A9990E25366FAD5464E22B4DBB183E15307C32C6E66BEB1899200B0878EB1A383385285193776D99BEC6DADE00D3D166969FE209652BDC38BEA6EA9C1D6D16DD1775674330380F54D62216689E60C02B4B537321613E3D947707592613DDB998B320136F3414D995A7C1063CA236E153D684EAFFE4A5B26949FDD9748F839A3A00145AE76632DA8780FB1474540D90AA16490CAB6714B0AB16FD3D86AA56273555484A0E3E5D196D877CC9D02DB9C7BBD5B76ADC7CA32E163C9B0029227FFD6FEA513BEE70CABA1DEFE609E378D1300635938764A97C380BB3172B4070D83447B78405CB565F959F482B142C3A5E25D7EAF8CAA8DACF49ADD7868703C15ADE4F3EFAFC2C8B75584E3E7CDC65AA70594564EDEF5CB07C98F4779540B21B738BB5A179C4FA58FF46489D2FCBE27742DADC5A2594DD8C875FAEB24CCEE827C9BC1B5CB2E49CD99DA507049F66D18771FEF2C8E3DDFBDF47AD81771CA0C1C11CE1081DBCA0A90FC17F80C049F14E0A3A6FCBF0FCCEC6DE175DFC3F465D8971DD0FF00C52568445ECABC9D50AF72A4C5703D21470856B1F578902BA34B70CB834BC783D1315328B220C9C5B637186F660045497C1116CA617D10D9DB886BBC0FA75B33E9D2DA5D0AABBCEBAC26C6FC28C7FFBF8DAAC4EC85285D609A91D22C2BE664507712020E9E5F1E02EFB83CC888AD4E5BDC2929E0DC18B4EA975CF7EB5DA10A5D872CBDF3D4AA452E8D0BDF8F93611717D16B1DFCD6B17143D93D46493D499BD9BB1219501D3FAE66F38A135F7DB4EDDE555DB1D39EB3F42A48FA42BC2A92ECEA56323773373A965DFC9A126F81B33AC23C99C0A5B231C52515F72E3FA09178D07D9BBDDD2995DABDABB322C9FD0E36020140333A95CCA0B18B7A31DEA8582263A10B2B6E68FD0BB7B718DF255DDEFE6CC616B440D7BD8227AD434323E3125CEC8AF757488284F64A2E62C640117A26ACCA9E10EF6C5130E885CF6B5768B28AC62CFB27CFAC57E8C82DFEC7D5EFCC954CC6625FFDF1E689E02625E6ABFC2641029AECFDE5E47B5225DB092244620050B6B18B9314C5E166987C093F947F5EFB9F29179E74A64DA1D5D3F9F5482FF11A49832E1857FD5CE999ADC2495925E95AF58FB95BA5A009645CFECCA8E7AB4B6C461F20F63F105114AF646D0E1C47A026A9E9BD7141CEE954F24A653EBCC3F0F3C699A6ED3CFC1464E4480BA8A297EDE705553D8C7CC4F1287257B1603176E3B257897D8F4CCEA2253CAEF8638055FD5A8E86FCF24FE2DAA101B32F066A8451E04BAE5744EA2EDE845424ACC04B86BFBB9C5DA50042F1A84BBB0B1E379F4F843668329EB9F2806C6F6A652C8EDC7EE99D2079AE31D8C294DFD76E80DF11CBCB164127A483ABEB6D518D269CF4F592D1F52CB4DDAF26691C7A74A920A9CA7EE2156A871142C08B1EE002C76D4FF5894F5D8ACD64F04F010DAC069949449999458BABD1DCA779CFF07FD57FBA27CAFEAB66F4BF81B6A7FDAA593E4304E013BE783CFF8078C7D224EE2F9C24B4FB1579C8B700FF32E70A620393D999DADC707153458616C71762D33F35C89A1EB082136870A0E1D3D4C597AF1F80000000000000000000000000000000000000000070F12161A23" - } - ] - }, - { - "tgId": 5, - "testType": "AFT", - "parameterSet": "ML-DSA-87", - "deterministic": true, - "tests": [ - { - "tcId": 41, - "deferred": false, - "sk": "13FAAC5CAA1C92AF31DE6C25B147014BD7FE589A649FA0089AF0D606E4B869EC1E4519E3AEB57924B329B085EE7C80501241FEE198F3F41A94AEED9BFFCFC9F7250182F2FB7F56C145635D81FD4981B541AAF62A572520FE29FCC0AD050545BCD377EDA950D1DF476FD2B85C8C9E749807ECA53A51D6D0F4F42A339AA7C48181C83851A0A830D080651C3741E1A805D4324624272D21366D403652024250188488CA24804C842892360462109258844503326E13390E02928CA038044C348A52A46054082DCC329204822D5C9869E2246918914462A86560080A0C372010B9890CB92D63126D13986C21B02D20C52560340918C641A20872048684824026DCC26418165219223158928940A8408A3646491061E396690A2690CC042D41302119C06510872141400C83120D831205109905A42844DA06201AA30502150C04282521A430E03601CB804C1AA2618AB621610410649450E3C630C4226880343210C09021944589248118C7458B904402126250B400E2866800A2041BA68558080ECB228E59803192847159262A04216D13A00C0C452D518845834402C42846199345630069E2060E084528CB1271239484E2386E93446D1CA26D21C60561B228DC1406D19870DA9211CAB48DE1A20503376262B6014A284259948D80225010108C18354D13982912474DD3B8209A40120A398A88026A8B2280D99460E0A80491246D5B060D02012D13272D04154240860520948D9182215890688084115C0248C12012D0B68DE438666306258A884C9B0801DC087083445222404109252AC988851AB7491B899114244A8A043103408ADB3680593488410690DC084AA04830C9441198142E1B038124B06464209223B484A49631CB82648A9669A1C230C9A484A18420D9226A99A26513C168234404CB224940926C61066E83C8418332254AB48002067102007213A57123842908326E54828101920D83344A5020251B84718A182C64B064E31049E4C090243592A196308CB89109C3109336812399415402101C196153A68000022C8B10011018914318705AC20C1801665B341109836811B78998C6618C40910A430683204421284E41368C94202ADAA66541141213B9605B442901102499904C41342E24C28DC9082E11382E00018A9334455810009090316348610C2860D4262981280DDA10519C140C1B2308D29208C8464E10322E44A848633490810022501845DA420E24097162A04908194453C06144482622C42188320A01C00952046A1B25511BB185243809C2A86C603689608684448065D1226223C98DE400468CA0504800804A283044084A220640D800724A0062810425E2A22804C04C0A408E891089E0868DC2B4850C274843167291220C498061640488D1B605121721D1C231D4C2811B8271A4422A414212D9982589069110220C99886002B7219A1262D2C0219BC28412496A4B089022824011106603A749C1448063A65160380D84460CA4A28C9B162A09A388522426C3A25119A6802410860BB3888BC66C20A028D2A664A416721B05119CA42113932C1C86491CA30953380C92A67020C7244216280492714332221440406492514C448C8AB40188308611346560100CD0302D24B460A03870A0968920842924A88D58002010286EE1204C14286DD3402DDB38251C1381E4B465CBA645E082015A022CA01612C3322A14A36480124A01042A0895250C8440809051A1282524B86D08318AE0220E210692DB966C83124ADCA0692127065B1828C1882D133209434411C9462049C48481146C18956948C4480C492603080D18942000130901436118A60120474819111018A50023019022882818054213069191062509480E11456E8A00449914010020122092480B8320E4321210B429C290512139049BC411129890DA14661245048322049B442A942291C9A845CC408203C77181429223B670D924218BB08422392C4B2860A012905A807113462992C068CBB68D1C8064840482D9B82152202A1B0565018545D4462DC8B620D3404003C42051380AE3228541086C04C62C8B20051B091008A420E0906851B685083825E4428C504866CC98281B1171D2208E4C324E13424E02044984B20513B9059AC86500472E9220710A300CC13620DB8808803840188810A1A84D043582E404320B048061345208C5201B92401032121C426A231904949090CB9810B0D16BC03B32C91F22E9DC32FD1369B126053CEB625567AEBEA42D32F861AE27857C24814177623EE402427442714970674EA84BD573741F3ED9C297758E0666F718D5E61117BF138734FB56E3348CA54F05492294F52FC90C243BD836DE2D5B9797A189C7D38E6E35AD95E1533A32B5B589AB56941904BDE66124FA6CDFAB90C80A05A4EE8E50A5DE061DA6E11D3B40F218664631444651497AC3AC3E9A9114C9BA1E92D2FCEEEC9168E27296AF943472C8B4E251F753EF79F80948F2ED5BF690E0C0A074E8E0E4503410E8FAC6D8B022BCE3FAAD1C29681FE2223125F43FCE56DE461BA8264DC83CA1E690BA638E49052D0D05EC5176D12458159F2FABCA6556F15914598E014A4582C678C0F6ADD2F2AEAA330E816B0AC0BD5457948FA49FC4C954020070451143D8B4B4602BF9616BBD1D9F76B0EDD63F186BACCA0C0F861822E6AB56F771C6742106314D54EA9D0F1BDE66F4A504C6902D86B815F46F47E6D69A9DC16F290A8A9EFB06695670196D17E096543CFBB6927E25191B9538BDF5858B54EE4F69D35CFD511FAA422B6955F0EA87EBE5506DB4E7871C7FC5A2F974C736FF12AD545CE507AF4E430270E47EAD8663361CEFC3FFA2E3CD85982ADF648DE6F899056672D6CDC6841B1F2668CCEE9CC630AE9A91CEE7648AAABAFB09E4AC7ED0D7ED8165D851627A01919AF56FAD39CDFE838B5CF60E8FF5A2A7C91EE43F1AA3F81CC853B178E3481C32C2D6FD40B0EC924CC1887FC6DA4039FA0BA82D0A57472C9D6003BB3D819A0533D3FDBDE2CB06BE052AD7E56B92B431652D6D5991BBA6B564C15C1BAE95360A07DD76F0ECE8532376D0B71EB865933D3520EE7B3B35B7656ED684FBE914D01502EC4BD7FF39FADF06F6BB002B882213C4D42E6CA651BEEBA228BA93D825D618084917ABD3130C31B3B935A253D8D28BD45C5FAC4B05A42BD815B9CBFB6198DA4FAAB4DA6E9E95194E8084D66CD6B52BE2DE2A86DFEB25C254F59C4CB168185E00074E9CBF060639CA6ADDB7DE514CAFD5D1D3C74777C11957416932E8745C2B01AB7DEBE2E20FBA37476C0626140FCA24D3EF4F53148C51CA78C935C6C89233A6D4C57C317A19712A8040C1C4D3AAD221C1D375DB372FE07250FC3C1BEA8ECBA24D781492425702F35CEDE709AB063EC0804E71B8669B87DAD1563606E89EE0DD2A0B11B8836F5A2D375AC4B7F85FC5F80268FE26121210A4E1CD24BE3FF9E6D92A5437BF9019002140A42C317906D61D862200117FF0F8B8EE8D4C289C3950D083B5E5670D4ED32DA5C691F20CB648DDB715977ED6AC69F64DF8D5C99B4177E8B98876E7A5D29ED0C0F972CAE6256528233E15B13C69AB592C3AA260C77BA41BC608A57CAAE46AD240DDD5C2232E2297ECC90CE628DE5B83A551B06BB68FFCB152785B5AA6D1702DEAA8E92F704B0D31498692C537249D71DC6B1247948CC07413726DFAA43F53058807B77C4C73874EAA526EFDDFDD9116C98B0E2C5B7CAF9A25278761E2EC3B34B766877319243E138DFE6A3A03038D357516D9BF64955EB8B0A4975E026D0915BCB8637C769530458F242F65A68DCC78157CB30C4632938AC32781259BAA48F11B3949616E06C4D4E63F15B96E203D4B4A8110307D5CB3552810B9E1F3F4DA4209CF1BA98359F40E7055C7538ADD0AFB326E5F865B3F69E3D6C9F9F18358C0F6A47777B455B8CCE6C514CEB2235A7B376EF92482E2E86F42331511FB94A9038FF41FCFACBF353F3A43F3A79997167306DDC94A6D0628FC346B06166EE9D857D4B0C63990259AF271CDD8479F4B08633139663A1155340109B5FDAE255D1E4E21539C07249AECFE8E6AAC44A772B39596946BC8080D84453DBABF1E62843D179C1C38F1AEA5CF15BEC4A61810299632A2F3B9422DA99CB13C852B1CC6933DD52EA336A5A09D7D9F568CEDEF14CE1AECA48D92996CDB2CDA36A3C8E95F62DEE742CFF293037273E51F77BC208D5B345331E72C26BDCD0F51C9711BD899EE82128F834BB0B2A3DE473358F47EB2F98FBCEB2624A5D2697B86C7559FF40D14744C93AA2DD6570CC799C4B5669ECA0463AB0B4E1228032DC19A42E4F6C64D9EFB26E1B4E622AC06FD0C47B5A39123FF8F1085E4EADF768FBE9D5E12CBC5F380DBB414775E2836AB19CDEB19A0F653E7CCA9DE567D18020D19D24364E03C762EB54701E1893FFECA6D23A2163AA5CA9FC2DB681DD6E8AE2F42985C2D7E477225AC2F9C5274A5584E0FD90579B32D2143B89F9AD9576DF10A8E82D91C4987AF05F3E720D8557093A1DEC1D2699C2305651CAA0FD621EB48190751D74478381A499A61732B917E84B749A0465408014D249DC7D5C247AC0BF404B4311A25A55B2EC1301350B76E3F953EA2E67C90F1D5B9FC29BAAD30D07946AE1C2976A4FD32BEF26A2E93818913B36B237BE40EB7A907595B27E7BC80039683B3D28323F53B5521D244E3C87798478A8F9ACB55EC09E97BC5220F955057A889E7003B9DE288ACD5594AE65777F36D6C73FF5A17C7A8FAF039F60BC9E3EC54284384429C62EBCABCAE2E78F5B58DC7132994DFB16602A54B444B9A9C0FBA6F7AC3E357308CE2570743B8D2B5DE5F9FEA05A46307623E579195D6B5C946C47C57A14D5A6177636025FA555F700BD61FAE9822ED336AB21DA9E67F9E81CD815F2EB79F25AB194E8AFC564C43CB4CD8D681CD8F1BE41D9376668E45EA7E707EFE2E58BAF0CBC091DD427009B0716B819B857FE9841EC48248AA49EBCFAE706E5F8FC65076E6E871D6958EB1C7A357019950146CA8AB3821317C289C744450C293D3DB4B3006EDD727B5BFE7541F6817CF5467AF94232BAFE06E5AFB845C0216491DCEC3D603B32EA59AE651739D0E26138408A5E37A6E0BEBEE2956269A722AC36D7A3D2732486EAE6F8100C9A278988554895424EC080E282EAC6401129F51148DA16ACD7BFF0C1CAD9516F189AE1D1F4EC79110B942C026C6995A0AF85445AB9DADB1B2FBCA7BFCAAFE884AB6BA0717D3D7BAEF75D9A4507FDBBBBDBEA858EA7975118B94AF78E250F494205715B0EBC31755A38C1AA944F0D80452AD54639B2701462B2D82E522F8752110F44BD381E23C1EA52C15BF9A7DDEC0AB0AFE725B5993A0351737C1DB72989F48FB41AC479C777FD2E7808FDA72790640F9F741D643CCD0C1ADFDE90B9ACC84345E0B0739768ED8265455AF008BC09970B18D52D188AC387CC1DB7E47EF83A0108D39F7057BBC02E611DC34F9DE364B7ED9664A9C5C9D691DEF8E8FDE6C61484A097CF8A937FA55F353D439C380357BBD108933B6CC49CC5C5042D6E5FDF8F85BE9E4315E094EE569C5E3F38CBBED68948FC95226CE06ACF6D0C88408F3AC265B6B10BE10EF0467E011A5EF8F10026C7C54F8466E9E574FBAFF13FE9988E783BDCCD4B02BE46EECD77443F4CFE8969BF3551F2829FF2C0F8630DCF7B088C5BF1FDEAE2E81143D1573854D0D6D6F70FBB5ECB7C6E60F91B241E5543BD4F316C66A7F3C91491320587DA5CAA6345FC0D2240530BFC19AF88B43773FBB4A6369F540486BF74E3DC4DCDC4CD265C7C0D37213037CCCC1FA81D21EB4081C254C4096E044EB6BE48D07CCE2F460718164AE3B68B7298BB1B267FCC0AC3D0365437ED45C742A3FDD746910C1610E6CFEA9A17225DF2B577E790EB870F5A2190ECC166EBA09C171BD825D5E8EFFB3703746817908D299426DE95D605B368AF04D27B01FF5CAB91515096DE2986A0C575D14CF4224AA9523B661128740F19DF8072C917483746547EA422F8A3B40CB67FA87A7989A13C49262089A80B1E4113BB1EB9B469275D8BD336DE344318EB3310B3ACF8201A6F5F613CE0F2290AF5A8B9DD9A5B64AC8BB94AB56C36157C8EC8DBA4125321F30F753D489FA42C4881A3450DB8720892A8D3F52431B960A2404A748220A7305109A2E80EAD78B8D5C1F79D265B00C771129A2117DAFF0D24BDCEC32D53DF76A56CA24B6CFA0775F67614186D7513528FCBF2F7CC47D60C52580BE1797A62C17778DEE9FDC0B6D32585BD35C86276B363915D3D2E5A4BF58AA483891025522B572F4B635CBE94FF014ED19A017EFE0088CA05C54BBB6953BFCCD8D6F867769CFB02280ADE6C39BEE714EBBE252AE5AD84027F8F9C2CFF3FD01ECA4F051591B7FD9164C3C64386D177A74E17181CDD3C55C98AE89CC2C1A26B88D6FBD16DFB76742B631DD8F8D78B308D606B486071C30E81C25AEB864A822402CDDE0CF27FAE8B6CA16500775AD44733FEC8F10AE6677114A330E59FD52747B992113C53EC9A09AAC1C3646FC3760CA6024BF39B7DA597F8902CD605599779509E3F8CD8B03AB66C1993AD4B3317949578351B74055C7BAED3D7555B315765F1065414F39A7848DBACEA596C51D10BB0081381F7D5601DCD07D719BB9CA9A294E092376F6D4CC32B26A9A8FB5297CBE32CF4356EA70225CB302693A6DBD36C816AAD475815E9543F7DC8064C34870A799C32A6BF76D472797F1DCF908FC994604407B59C824AA76BAB6334CDDFE8D0227A383B0CFA2158CBC79DEFA98BC93A38DC0A0420C99B920BBA64DA16819A78F8BAD42355EFB42B4BF17C68AF75F7428B687334746245F7C5145B5272B9C504A9A0A3A985A9738BB1B42FAEEBDCE7E7962CF0AC6EC80F77CC5C9733E49DD1552812957E1FE30C4129A702E23DDEC09FD", - "message": "67D7F4FE3CC57FC8BE9A3D06BCA0FE4A39F39E3A6158D3E4ADA9CCBABEB542CA67CAC48167928336993C569AB5AE55BF95C8291AE1A1AB2B595C90C0FB19041435F3B411609412630D80DB0C832D413D69C8D3C3CA78BD1BDC24167AF590B67449DAC7F6ECBF87698BF3929FBC874F6FD68551B28E4EEEFDE9A0D0E7FE9E569F1F9893D39C17C3BA7A6211B875A7BCAD0C14194C30D60CDDAD640EAF7A02CC9DAC074779345B83F0D282899B2B9B61F8504BEACA3C02A76611C82F2007953D04FD3C54D7A00DF8F6DE554FD83D1EA5DC841645B706C9D900DEE7862D526245215AC6B9D178E60F9602F1931503864D97F582834DB797CAB60DCDBDAFA3FAE8726B525E8BB69B5E0763FC4ED17FE7CD9C9629273AD5B073B9516F6CD7EE729351C213FDD122E3C11DBC58FD2A501B267AA4AB21364BAA856823816E77B81B6061279FEDA6617247B86073E55B19973BC0E725F34ED4BAF0AFB95E436A9B2290A2B316C18CDC0D9F98F9F6F13C5A3FC767EC0A9A49BE1378E92BC9B3010B41AE52AF409AE0FE27CB816EB2614DA41C796D5F4FAC4A743FE34EF7C0B3A78E0E4A5B439659D4AC27B698550E89A1626FAADF71420F559DF2E808144707B5C02090F754C3BD4EFCEBAF6FA4493C5D48F895FE7674C81F069E1F00E455BF5C965BE2926BD19AF76E20533A6115F4BCF2CC5DD3A49E10A2B3FCC9EEBB2B6E4F25118599062F2AA6CC3A9D86167B1BD08DDB2C53A5E46E1BF4E8C1967866320BA66AB67CE581981F2003B812BA058B75924254EE3715BADB8E6B1B9E4F4AA9844D578CA2F0AD12E1C964685FBFFC87108711E022EA7F63330CA72AF86262838863780F4115138672643E6D9B48C782B8637E01D3D20CFD5C98A1B57720762037FFB12742B4EA8E89E4B32EE7DBFCD5C11E4A6E839A83398ABBC32BA39C6A25922649971D88A102D1019B560C96B820C44551E14509468196CEAFE3B7BC8F253ABFC59FFBC01A13008F77C91B19083A9E7BE733C1A5E558C64557389CA19249CAB77014D0569BAC7812862A610DC6EE074C844A055ADCAAD496F6976C932587BAD9D7E2080F8623C5ED8D9D4FB9EFBDDCC4CCC1284D22A2997824577A619905B0D6E451CAA3B2D30DAD9728FC7623F9ED71F80599D65D9F2AA285BAE393D05C15891472B2DD2ED5CA669785EC4D441F3308EB4BBDAE8FC449962EF9787C39A533847540965601D8BCB6B4299AA636589BFE371D3904E18BC9AAC9B3B6EB8B7E8F322C22A6E01E6B26244F9E39586F124AE4E504FBC9D860A61B20B4C127FD0C55EE810AB9803D810233E6126488A6E95F8ADBB3F8E06D113DE6A3E361209E0D36B326E042CE9D2698DEE469DA15464AFF82D5603434C07CCFC4D956A7D55FE79CC127AAD2A56B34EB10E8B85C3CD5163C4BB8C1083BCE5E5EF986AE028837809641A6AF2B8295B743DD9B03931E755673DBDEDE56F6294270532D685DAF1187137CD7D29248F21B290EB8317E3EB28B62E45E140F4AFC6D1438F81E9EBFC6FC0F1A4146AAD83AD1F0EE2952643E7B6872CB2823AB21A155C281ABCD19E20A52611C6FFAA724578A070935B1A0BFEFBF061101A81227187E14E96B016242DA269FC91253FD827A73743A4BC49FB63E2D830D0FF409AA1C73706D7C2297CBC552CED567DFED72CD15060A522F9B88EC910B03CD2794A9FC07A8FFC5CB97817DC769E64D8C474A305035A49D05B1C572363913A315932E391B62AF291DC203B9A40F04F40EBF26A4AE186056CEC45EB7D21D88CF50258DCB5EF40CB2ECF949B18C72626469978FBE0964C8A25E8C2D27149C2266748F2B06746E8C9E7E2F0977BBBFE3FBEC7353F583FD5F7C2B0139EA928AE1F67004706F6D4ED7BD8D13BC68E0F4A49877C0B2F692936BE5FF99544B2B19B23A97EA6B5F585ABC9E69E689EFE25E15804C650444C479E0DC63C9CA2AEC41A316039EC7F675F1FD7C0476707370CFAEC9C3418CCF30B5D85FE0E15056D6C015DA59F9BE9028D9C2D93434F99DD8C1BDB41FA1EB021BFD0FC12EF0D038CA32B0FE1449342D83CD6BAE43A8CC4077074FB1191A8887BF29238D27415D93880682017470A42872D6CFA729AA2B3F8B37038C83583E4C33256FB871A704527594596FE858777A93D3095767BCAD2FE295352C93D227E1766A59ECEB38FB7C2E3664D6DA0DD4C063975FAB3AB4B68D125AF16D233389D96A337DBC18DA11F37F430C1E49BF8AD30258601CAC9215F32771C6FC2B7BC03B55AE9664E0D719C3B40C3E4FA7DEFED8571CE8E46FDE8701975D94319DC5FFBE93B4FC4898E2EFEB3CCFFB3494AC50BBA364C22A3953F052F62E46D0C35692AF40D2FBF899A23C1A4721375F307E2FDE2E588830753F908FAD96EBD5FC360D742E2CB2C38A7E142C95376ACAE29DE8E1034207D1CBC1DBF2968677AECED152B1EC1AFC195F3320352953F2503227152444BAA74EE8F98F2B4512F7ABB43D7F87889CF1F8C12D9BAB91EFCA5AED21058E322CEB4E59DB4DDE13BE46FBDFB225F4AEDF7137B548503008002A36D7A3E98C0ED65ED9322D66FAD4A741125EA4ABBB26A2FDD7AD136590061E7BC0D5228555D1A59F8A6E4B97ABB61F4B1AD9564E84C000585DF8BB31AE61CD25C9D91D1A1FC21A69AD286CBC7E00F592DFC1C65E2BE755DDF041486F3B52C8F72ACA97A149FE0CE1378236D99EF099A668F6847659F7EF617B66192CA452ECE3010AAC18A65D8964381F561B48D044096DECC22736C902D7E23EFFD26245018D9D7EA9E2F907932A1EBB405BCFD29F7A397C71A5E08962ABEDA5203988A81F787B25EDE84A7D85DE92A2B19974EF7D0378877B82BD7CB28B67F45F7EE625CCD054B44B4CD51802B4FE2E219315CA9F4C24065F5578732DC671C3004D31830DB435C763143CA209D7DDF3F5EA42244E68429102F4D90297B7C987EEDFF0DFA7F31964B76432E1DE27FA38570F2BF64D5FA3F12DD9772618ED2B95F51AC90410350320E19084F1596F6B791AF1EFC24DBFA2B7E30015AB14FAF43B568C5149A1152A47D278B5F01786F242858C210D28812147646A1A3A7CD69996809B784BB2F0053CFE18446F060622FE3B9181AE9175D6CFD8033AA752296016E7BBF639842DD4073AB282FF50F94B9E116C63DDED805277D4FD7987F740EF8118946851A5336A9F6F6E2FE3ECABCC518B31E741AA79AB500D9C6DEFCC437569966EAB1D4BD6CFF8AD0E5698D15F1342ED46CB6DA986F0C4B2B427752C18ADC5070043FFEEBA98569E90C79A3D5E0434119A077A097D69DA6E9AD7E32C6E8875A893F6D69424DCF4C0D4EA12605E5E8A9853E4B58E5659FED6D724CBAF582A89A228F99BE89D88F55095D0627B40B29365863C57F82B9EA22FDE731D1A2D8A9037665213F2C410D4AADCE12CF888DD4AF53FF839E962F0F53BEC60F97133D131C2C8EB588AA7D25EC025B9E821DA8E8FD8E550EC5E4D5923BFDDBAC522D1FA64C503078618B52F452B57874285AFD3F6B182CA6C979734C94F040EBAEDFEB547683E98F4D13F12A252E8839317A827CD97A7C3D81962A25DF7D8C62B57812EAFEA9EEAAD7D6A9E755AE4CF3AF42CA2152F663C1BADA0E653EB165F6FB56D86212378C0B9BD5733D4C37178FFB58E7357487B98DEA35127AB58A804B13E61E6D3E385C96884EA91C744DF6CD44B3EFBEFC79ED19C406AA6ECE144A44F1E78B33046C33EB17E3BF61A17D849493D08F0FCF8232AF2922D96213647A47A05A9A08D28AADD3B3BF412F29063C9D78CDD3385BFA9F8BF06DCDA23FF79A5912D867EE1B0D526718EAFA6F0E231CE6C51959BDCD8D201838A50634F1C6BEBE2E4F5235FD01A6D27B90C58C12D8210692BF68FEA5B8A8651E64EFC1DFCE07EE670D473F29AFA63E080F7675F23E7D2866E5F2F9A525BB657E8BE5933FBED1E206C7BA9FF097EC95B91E14612E16F0F4082F70A1B01EB6219D47C716455F4C1C60948CF3228557E787A3186B4758AD35922AF28BDB328693BAED15487F7448D1796BB9DB5C931EFABB4BE436B2710EA280368A8E20C5782A7FE986417003236BE9CADC560B3D7C2CA92341536CF67D412E855B92D0229C45B1C518D8BFC82DFC9F413D3FB23D37EBD96AA0CD0B39EF88B23609AE0FC2BD16FA9E934329558759F05C8D4C8F3F8728335B659D3986E44508322E47121E592C9DBC6F49656B473EF7DA53FF8EF7BAE07D1BBC68EF4AC369D7F8BE60948F34444C0C443A100443EFC444E7FCF0BC4DB6A2C2C64662A538D1F68F4DB95B0B83DFD744ABCCBE5DA343621F0E182CB9E915B2097C186F1B98E7D8F297C347B60EC26D04B6D9C1FFC01EDB2551FB8D11D49E52956F69CDE0E49E2E7DCC8E7C8E78C41A9B2A01483BAB11733A0943A9B765A5811451C07A195D87060F157D114358E478FBA2F2B755A2A455E9831B77EA9D33FAEDC1C562E1CFBD8DE156FAEFF10AF655713E36FB508342D9B4A239D6DB786CF9F57E1C39AE65A7329E434AA88C68F82359E6F057873968F9FB63D898F24BC13C0F7748F92E404C6185CE24C98D4E4D8D4B3C129CB46C614E773A89EAD73CF0C30CD7E6C9F6435F7C83A4C3F877E034755EAFC5F30ECE03F6413F4C7DCCD01649B6ACA9C1C3AC3D112F216AB852A27DB3B846CAED86B76FB699AA7623548EADFE6D16AAF5A3ECCC298D5CAA7E84ADA0B75290FC6ACE736051924DAE8FC5BA6DC9AFEF65F369D054A4A18950E71901F4483A4BDDB2584DEDC31A04C5F8916DA2DE33B37078E5DAF3304344A8AC368A6668464FFD7898A18D10685BDE6D0097F95A3587717F6A3A8827B46653D56E461EF861D6908AB7D865B532DAB37E02A7A6A72A06F25572D83ED6DAA540FE56BFFB2BC9D104A74F135127ECE457991152DD0564BA955971E8C9767DDFAE190052A98A63C4C0DFBD1B51BF60643E4C5EBCA678CE5150F03A6EF09AB0B1C2A0D2C19C2B30A645C7DB9B56B5AACFB862837A38407070DA9C7DDA20B99CAC7B03D10C8F28D6B1C686FD26F9A8FDCEDA6B188D472BC593AD51EA62DCF73D32EED5444484853AD0EFCAA60DD42DD2C50F5AD15DEC7B71BF585581B9F9C68C7C94C154CC7E0D19ABC90508C8EB2DE93F0BE4295973C1F443A1B2419E20F3D5F883912BBD5CDEB938A4452FE0BF2361A9E3B2ADDFBF000DB07EA19B2735CDF0E8E5C7EC5CC7CCE1A9C3E869718272E54CD9875C21DCCBB06FEDE38A4E787D111DC6A253A4604B314FE47A9B6F6FEBA3F8F013A456DBB78B497C4CA7F90CC6145F47C96D266BE5507DEE27E968052CAC85EC87049CDC68D723D8CF89B0C91F67CDE2908C0C71808004A070CFA2EB6408F5FD6108749406FFD3D5DEB6FBEA00FEADDAC4CC0E22A9F6F50B9893CC4CAD028FBB73C1B7BD4292AEAEBEB668859BAD444D0C5FEDE3C469CF28C5C726B59E828C473C8787453BAA3AB2BFC29C691FCAC2CF496ADF3949CC42FB16F3677D456E614B1F88406E6C9DA7DB9937B00764D61C3D347C140FDDABDF8CE5E3E2D385C3FA6FD9F13F3BF8073B5D6AACD5294938DEF9C6ED414FDE4B3C5EC43865A7FB02787E50F94033CFE32A85BBE24B09FAA3B55B8BDDE60E325B691A350F2F128CF74FB5B6DFCD0E946AC7BCFB839B3765616DF35AF29F3AC82F4E2DF7D4AE87A016094719A07B5897105E2B08AE3D807960FED396CF38863E69662238541EE295C06B290404985444F4B28388DD942E51867216C734580B3F1D5BB204B05D4993D6F8ACDC8F16FB77B607FEDA67939A2B6AE285ADB2C98E7D37A81AF0101A5CE39CEB2C67CF99441C1FD980C2C542E7284BD21F1D30E68EF3606C65D3230B5146DAB41D4ECBD5FD89FFC68441BCFED9AD8B4E0B616127A7AA39E84DBD1343E2A41B4DB1AEE0627657438034E890C8EBAE19791705BF6C948C630DB1423D310A34BF151AA8ACF3269253BADDF5B40AB7EB3A7AFE2D7891B925F65EA206F4CA121175E8F348B4162917A68FA768928AEB0504A60C4F42802DA25DCECEC60ACD21FB236080AF1FCC9146BA30AD964416F4B524ACC416B5357206980305555CE3485425EB8F87401FB1D8CCC184C486B5B563242BA9531147D6A2E7C0BEC1A56E083F05344BF97A18D0CE0FE56E8BE869C746D4AAB365225D8871D4F99020DDB1CE2B5D7D2E5DFC8A0DE780CBA0A9B9ABAC87F19C73639965AC2382488387F06199A08F283794E1B8D3580E5CCADE811ABA6881908277624D5395021016DFE21C345B9A21B474043E187403E5B0ECFABE43991865A424BD33D233AC4BD30A3CE73DCF49B58CC4A3D2CE25C54FAB3480FFE0D51A43B71FDB7E1126E66856D263DDC3BF1A31DCDB935DECCF858FA2CE5AC89BF32E36D8009657F11691201290A243B5680E060D2CE30F1BF2444D67DC94A24708F8F9261945D1B5275ECFEAAF40311CED5C3770A1C194EC44501DD25B7F5FE67BCF62D1BF31119F8EA7DEC1CF536C1026A8E72C7B2E167BCAA8673AE5506CF6208F3E1B6057B5D488B29EB84D6F94AB8AF322B8657075B9EAD3297505AA521D601C21540EE71349614CACE0E7F14EF42D6CD5377DDD0241E34CF273A1171135A376B98C53B218503A908577C268F6DD46CA9C26DFF5942998851627474DE9E6B46F49DEDE85CEB993A52D01F6AAD6F96439C18B0DD5A4FD559812227BBC0567A28C1299626B171855AA0C74E2F9B1AAA781D34CA58C72C708AC49F5AE1453902A1FFBB8458E8B4786771780ACAD999F8DB036CF4C3F77AE345817EDA2AD8F7D2AA9228C994F6AEE512F7C2D2AB72F2099EC932D818E495CAC8507B06CDC6702944237DBCE338C20EDC84D958C14233C1884BA09A023BF5284F0B0157048B6AEB508415DF337A553F6435140D0CE5D5CAA77F9137B2C1AD5A02B13738772743F192E53E970DDB401983535CB096F7D98644797F487CFCD18F1B22BA7494D892C1E5AA05E66B1A4326C70E348350C97DBC26CB110AE8289C97CCAAB150020827B7D7AC7913B4FF515583677018949D39CD73BC7DBB90696D5EBDBAE6BD6FC78E3826C8218996F079A387A17456875952B268211891404E80F8360F042EA3D9F7F7BEF772E64FA1EE8B4EBE0A1162A46EC1E9899766BF4D3099AF712A847CC86291B3D6FBF51B3B3CFF87D7DE71E73069619480F6056AAACDB9ED8E228BA075622C2FF242CB050342DF8F02118D071D27D1FDCBFADFF49184F5A100F95E1BCB019864E58E0F02672C8F5FEB97EFA06FBAE6EC3D57A10EC712BE0144323292A2CB27F1B1FCC104140F556D09A6074F853AD4328B00E6F2F24A61A7932311BC999805F2E774DB44ED72ED244A945928B9512556EFCB2BA7BE0E668C41AE7601339F0162CEC0A1AA91C3FEB6A8A40158D7A3560924455B9AFBD4B3881F6C08EC2895C84CEC30CB0F5B499B4A66267C719785F94A9B9F96FCEBEE939AD0FCF42D0E65DC241698DED0EDF1A9BB4147898E6E83851499175105BADFE4CB00B9000404DC92EFB4EBF41D9A9262EDA550DBD0B99353D001F90AA05591100BB678634FDE4E0B1C174222C253870DA3B8A797CAEA9B446309DE5210F9A932D6AD48A4A7361A943C1BC66BFDF75CAF5409034A8768BD535B20996A728A26E28340191E03DB17A7032FFF883EF664FD7351DD37DC2D72F0CC4B80BEDD1DC33BA3046162F5D0003140DF78FA588A9FDBDF778836C6CAE7E5A20FEF030C57867B295712DED14474FB87A301C31214FFBB4F8D166498ED93B6E233A669CB88D441A38A0E5846EF68F5DB20245980CA184878BA8BE1992A0638B058CD3A3A501CACFC818D2B5D7876DB6EB08E9F26430FB06EE0B9E834D1C331B66CD0BCCAD7A66ABF4A9D8F7A872932A3C0B25C5BBCA480159711E0BADCF69A1107B286AB199B210CE95BCBC4244780C074C42B6BD43869F27BD666F9B2541B1561B4C207E9A667EB1E31942697FCEBFD0B920EF80CFBC5CABA6F528187403D7E8262C110458B5382BC376799032362CE57ED39F0D29D7822C408923C29242385CA9749FACA43EB4483E095851E89D24CAC7BA5AAC60815CB5C8C5331CFD66352BC8623D5700F49FD98FFF9E869D5AE173961138D76E00CED6DBA09144083437CC8FF5ACDA10BAEC0081C8BD2F5838666A093B412532C521753C4E11ED0521923D1EE6BEF3B4FABED7467B9C8F75FB24FD8D96759A6146B34EF951C4DF92228C2E58231A8D25E3F08ED5A27BF6041AD7011DB41F815FEA503973D4E7B5798489B261A0AA4D0C32A19D17C584B1702713D1174E542BE4EDCEF27016BFC78118445A63FC1D17FBEE5F71DFF46F1EDCD050239C68DDBDEEFDAE7EB8963B5BB4819186D45191C05AA049E50C4319936C8788AB72744912AF28BBF5CC77C835C35BB4F987DBA6657BC2A7E58B7CE69AF37AF680DC0EA7797B29528AC70D92F295C561E2EE0D0E530854AA19EDC43C01A383035F6A5DFB354E9306962EAECA25EC85B9B78E8A1DF6CA50EEC733F60C81BF812981337F784F8CE07D0C03D8B3E72BEE1FFA55FB92DD0446CEE29D8825CBAF1A6ED295E613FC700FA31167224D99338C4F59B1BB9C1E63CF77476BF84F2001D42E4161F7737B47C1A5F219F6AC8B8E3ADAECA827AFCD6BC0CA09615BCE15F1BD0803BDCBD41E68F781517907EF3DD8E8A33A1E30ED09D7EC1D3605DC72C9232EF9F92475743164E92D953177B98906DFE5E414E134EBB63C79220D4907869CB2D93280F60DBECCC81B532CA336510E2A7F1D631F7BFC517AFF223430F9804C4A4877D8B7A385ED48F390ED9666A56EBD62F6C943D0E52AB1EA247BFB07C05908E99358A51E6111486133F4A6BE3BAF6B2D4C01529925ED911CE728B4CE4E8CF8379BD216108BF964496269BE76379912E94A4984B890A4BBB9692107D56AAADAF27ADE475E98A566C0C9E33DD1970A3DFF0E2F79197F6315E320BEB5E2CA3E3C904B557075981118B363042BA687DC682F13D213974B1647FB43DF7FA168C9D4F599C5BDFF2941C111C6C43FC75E69C290601EBC9F23D665F944A9B75932DF7792CB8A005A7CC83DD071376DB11F9C950B38B270E06C907FAA102AC76722325934755F53F3650B42D0FF293FA37086241C00E99B9C03FCE21F8D7555CFA93D09A0EAEE3733A8A5E4C45E74DD5EBFFD2F75EA60942BE34412BC82FC9959CFA155DC87FFA0AFFC1E7CA5057EE016B9751C16DF25610F1981A08B8E3352254AFA433E9B86D3CC13FE9B5B7FBDAD83CFA0FFE511E44412DFF1636BCBB49E9769FC52B302AFC7A96A3DFB233831007CFD6C302CCABC119DAD45EE63303DFA1F11C39C702AAAE00FCDCA913371F158BE5493A9B5C3B06AF66C8D5DE2BF9563FB617D1490FF6510971203DD25B27E1AFB289DF894396B8C26548BD53B320203AAF053B19CFC815C5D37E3115FD6CF8231B88FE4C330545F131A01124BB2487A3363B3E534BFD38B1D5138F8887EA63776D78783AC45675ED598617077AEAD86206B9FF61E3669C93C3C3A3A8F39E7848A88C0F94878E5D359C22BAE891FC7478BC8227FF320B047D0DFFC8218C1110136FA803EF6395E52DB8326CE8E3AA928CE42FBA04B1E7F1AC7B73296CBC1567090B9E92238859A87686D8E623B780F0376B8537F41B1BB102CC8C480C0B6C069F562468D4E1FE111B24D51F63E9BD38C47F35D8C2B5BE2E737274229974CC4CA63BD0E1F0446F6C4448EDB2498F2376EE26BDD8581242703715AD434E425908D61EAF865FAC5E82578EEB0525F54320B6C264F37DA36B55C2308D4FC6C7FB2F4D12A88CAFD93953193B7CC46804A0C464740B4972A71B7EAB5F6098FF78BDD452540AC5BAA894C10CD69A992217B422C88CC7849B4D8357D86234449B452AB4D49EDB1D2769512CF8A797F5FFF4E1E0A3FBDE292D91722D71322F0BD48C68A3CC998D03F7581EA7B5F5150E7AF58A076D09D103E9F64E61A2D375461007210DB511EA89FC4EEA75FFC71F7BF31400E7783F12F69A1EB5B7228952E2CD1D6FD57109237BDC024780006C229EAD71EBF4B543647FDD9216D98DC78B43CFEAE12166CDEDDE09B52BDCBFF089B1F7427EAECC21CCAF3FD5A35EE72C3107DF0670891E1AE12C1FB81581F3A45480F1FE06BECE6A494074FF3C47F90C961E371E8014707AB0FD004D19166140AF7B1C9D6B7E4B6826601AE104CE18E17939CF77C2A31F711D5C7D5126F4CB642178CE542973466696FAC1A0858ED62E4F2741E47B83B97DCF4610B1E4E262E700A06FDBFC6709BB1D4AFA7C20EFB72E0D623389DCCB049054CBBB322E63B09176E2903DBCE49083B01EB07F140D498B793E149573D8CA91DD2BBF8DEABAD9CECA0F896A7B306C22F8A761A65CE2BC1358A6ED07327AA0FF4C0B6E2906882A12C50D61D021A1316646461013D8169C4B54C61614CC9EDB2CE0AB0BAC96B36908BA3ABDF92D11D96EBBB9A60DA780AA58B804DC6F91E54D82068FE2FB10EC1FED54B794836F54503135A7F91921E2BBC2A61C99B6A0BDC04FBD2D4E7E430F16B5D3C7F06243517452BB7D2D51340BAF550D260A26A2F3B5451AD7D4E3A70CAF63F92E25D137C9E9B1433CAA5502DA269211F58AF2720FE3F899282C2C02B78E66D3302C5B9DC04B98197D3685EC4E6D4603D79B357282932689C2928361022E79C197A470212A69AC2BFC7505366CBB2BAB8D2E31314FFD77A04E85076D76948E836CF2A87918D43208CD856FFA33740FCAFFF9F690B2E6B33F1D89F65C71", - "signature": "6AE10E0133138AE0D51C77B5667D4C9180E04D0935EB5F282E696BBE794C8B96EB6A21A232C9366518132BD8EDFA9AC38142BB9CDCBA77C729BC4D1127A13933DCD44630D3CC6D1CF0242355A0DE121D15D7D4618F501E509C4E0BA296BC956571AF19BA6C8C2A75110DB6ABC3E7C682E87EB280DC29066E5D45C5D318DC3F14396AD3EE29A772117429E28A7B423B54470508A48D67CB6395190855A0D92B30E71B34CF7F508658E7268A27E2545E6B79E48F7C69ACCB09DCABF5BC5CCDB8CA8CA8CAA2F2869773349C666583702F3BDF94C40204514DA2B43A91443B119EDB0B421100AA587CAF238A87F916281435AA6FBF00BF16AA7BAD080D60B35C53792C438CA39A4BDC72BD7CEFCCFD877F82AD557B176DD5C28E78563D1DE719EBEA1099718B0F4129A493C11CBB2378F989D18A97074A2E0F3338CCB9A8A36C1B3749E7A99E7A765C70E5D60386C71BD4CAB64BFDB815509166D5F55CB4A380C8CF24E6BBF61AF3FE7BA3529D84B11FCD6BA6E18B87121857B00A737B0F3D9665720C38BB54C09C8D3917C5AD646E3D01359724534BC1910AD174761D64AE6F796900655E0B13AA3EF2282DFDCFBFA5B0F6585D33455D7D86DC6BDD252B040B66EC6A03FDFB4C06E54C734145817A20C42E408E7571FFB9D6D258E585D5904BCD45D16CA6E44FDE9A25E06CD3645A302EF8F3589D897181450C178E4DA1663F2F5960B4755A0107CE43A265E6EB0C9C267929CFB1A93ED1881798E9B8A1D91CAC83E63537FE0182D022548B60CF0BA47B6A7F90CBE86E1E5D39101C0D2FB333A82E2E99E9E0C1AD46DF3FE876D144FCD3B1D78424C6C5CF0F6E0BCB447A6E9CC337481F5C14D4FB74D764FB38B8EAA511951A50F41A4CE248E13E4694704A0554853A0AAB9405E2C274A4FCF8B5928667DE041E668B17AC577173B0F4CE34363A7C2AC9C3E0A45A39A46F0248BF3D45DBA806A230DB1DC7B0BEE80EC18BA8F042BD6FEE173177FC0194124AEB21BB06FA079A1BC80758B347E4B129D69EC6E8416BD89062BACE16F2288076469237231B6FF4902FEAC3BA7D884DB747DA6371E792827017778E43708A421931115EAAD9E4CA316814904009F1CCD36763FC63038641BBC4F6F93235E16884F8A12F8D71621354B0AE4A9EED64DC5462917D4B35370AD9EC8057ECBE3A6221FE8C39B11444D4BFC380F1F4D5AD18091059AA5089E109181247DE78DFC231401A3D517E9DB655EBB914385BAC1B2888E3837FDB08A9E7AEC206406B848D045593BB837DFC41DC283CAA753D8CB64CEDA3041B2330BAEBA2F1450F646BE15E0B2A46578B1F54A73FA4DE57FA1D632F3FD410C0E8B17C11E197B7A17C522EAC6FBB78001DF9F96CC5F6116635D404AB454BF4450D536250B80E813C8F397E038590011C66C5164E05FBDE695482185F02C4B6B566BF3FA564E9232F40594AF96C96CAEF18CBEABB292BA546EED3A1AEC1476A8418B25DCE79F12D7B4F89303688539815E05F96BEB3B1818472C7E4DA7435652DEB5FA4277F2A810831F88098899FE2EEE35C1B0E6F74DF159D0631C5683C2D7B86390BCECC534CF69F3AF74FEE59EAB25B634333470A55CC49C28C7252B1CF4C293EF500589805FBE5CC056573A10F188A02D050AA34289A21D8B7D587C0A288114E47F346DA3772FCAC58CBAC669DA616C9976C56D87CC275AD463F2131DF95460A151123C964B01A2B908AEEEB7DB3E2FE12EBA46321D7A3FCAEBDEA0FE11B78605E3C8390486CA5D484E6C413847BCD8C6BA1B00BD2322BE537B173647BB63BEF929223C6AEA687F8ABCC4A8B81C44F0FE24588D2C40BF76590AF7157E2E4409804A28AFD25E36275C34A976D22213D457C162ED9274BF52E20842ABC94B2A1D6A4A3F9C2AC544060974DD687C2BB96AFDF8C27522C0C438E7E0DD4DAD7AD640A4B3ECF50CB6250C0A97FDDF15D8865421E490F84650144AC489AE7920C4941895D7B2F1911513E428127562F9446BB706FC06F07BC6C9922987A970D4FC21937BC09F072BEB132BDF8014281BE75BBE6F8C74E337EABAA16A064EBC956C188787CB34A83D5698438AD22CD4FC80781AA1B66E5A2AE0180B50B77FBC07EB6EA60246DAB074494CC9381F6011C2ECE64F97B2F5CDA92FE91B5533518A7DAC9828FB33ED428890A7FEBD0906095094576CFBA1048665782B07194839CB86719DC91EE8C2F64D4576605C2B55804299F314DE8571D0C58C78F071FE810B2FDCD3D7AF0C635303B6ED0774637B1E563855D54D2A1B0FEB5CBF84E693E512F59A13A20E5FBDB77510E3356CF211DB09CB471DD1043D9940DC1BB6A26CEFFCA03F48BABE03C15226EF29E0DEAB6108BDDEE6462884F8708E79709775AFFB39303D78BC51C8B9EAB5D91A56F8BD1518708EF243AED01A637F525E25F297E0FEDE03F3136EF23C4B33DC1D256CC92E3B6AE64C368542AAF553B1605C94C255012D605D1291098D1F0B855D137BE49D198CDD3EBA0A9D9E7519B8A5BFB4DC3F338219CEA7C97251166B5004CEEC23606421A8F9248359E5346594080FAD04EEC15C56FAC9D55EAF4C399B1FC8D68501B88002212FC0E36DCAF5016371696AEE5EBE4396C36137C535B13F09D490564D38D1E0FFDF13902F7678FD06EBF8E34E81BF712D918348728BE21965F5956EC8AB1F5A8D8276E6A72B4A69FB7C5AF658C5DEE4C8BE285ABAFFE0EF41529AD44B31EA310C3665F2EE61B5817C1191549DA070A2BD4BC790E283BF81C11EA05A6E4652823EB3FA05283E784C4143F4C029A6A7D485A1B892F7462CC26B1879B4668D133DCF6B9827D3A91E069B25DFC72EF00FBD6FBEE4970E26222D81874C748C746DC5564732CABCD0FD99983034E4F5523A43831ACC1E6F3989FDE186D4BD07E15CEECD8E68375A5EC130AD93C0837A27F5EC5810F6C87CFD8E37BE6117496F7C283AEA1DD30A5FE5AF6F8A94867A5A7B336B4070B1B5539608BE8D10BF765F6984FB2D0AF376A7DD4E5E25922078782B77C4E5D5E086669D265C6306CB40BA5755E6D83D93D33C89F548FABB20DABFE7086B9E658F4A8BC22C11C8A12A106C534EAEA38F46FFC84C2A4D96C5DFC31F6F21B3FA32F988FB86A38D7103ACBCE69C5D143C33D1186C1FCA80A13C642487D5B221DC76556249EC81E42AD4DFF51EF86F2ABC45274AACE72A79A7B985412A3E94C92CB824E3B54F328FD2F06B49DB12338284DCCB5E03D063CAB73B939FB59A569E4E693E53B446279281BEF3637B55FA1C77DB77A389F43CA7E00B8711B32F98C9FFB2FA30D66075DA836CB528CDAF3FCF65B6EE3C0355E05A46DD0DF6B3D71E8C705B6C14514A537627FFCAF805F8545A86865D9EC83B243BDD4A444D6E09A7F26F5C30D824C39C65E1596BD506F70E793CD5E703159736F7A7C1B1A08A88E348FE12D0D74A190EE4C8CF1E2FF44B9FF40A28DB611296835E251E8451068C1016A3EDA063242D1DF3DDADE57998C1FCBF7B9F988392916D4D405F82ED894AD693FEB4206E1131911E3617F5A5325701D01AACD591469026E10585C1A73ABDE7ECA706C97F48B125A8E101E55D0262334750AB98A8C4D33F98763684402C16BC7BEDF35AC349AB471E3EEFF92A79AE0F11F3CF17EA1406FB6DB669537CC0E46F0A7C42695C4595FA2F0E604F048357125EEB01AE824FFB63B70F10DA410EB93933398C13B485493E4DD5AC42744B00D2F81BDB3C7030C3DEA36BDA258AD26D4540D1FB83C7E651E31C0A2F7D06A328820D85321B24E4B798153885D80111D17811D5ABB97C69B24E3E82B44649CB8C5E828A3D532DC8EF2C317890BCDEB43571EEFD97780E68E03C1F751F5EB823D75965ED7714397112774934F465F61C25271F1AB2EE80BAAF7049D1E0C78EB59BBC3594202F002E883B7B579B98D0D4865ED783AA0ADC84A4A37E73C3CFDB5F464812AEFC6081EF899B5F4C9F903279E77D39B2DD0939329B3C5060990BF8E0BBA6CCFB6F7BECA77F48585F44F8CE7293D121335939E3AD785BC66AB2C9DC955941EE85DB9D2A4F404B3F45C7A68452E6AD108530A1FAB8E35C9EB0AC7F647DABE0E0D50358A007DB71B6D76B9922797F9CC377D675E70D9E166B750FF457A5D3D649153C81CC1B659ECF3656BD864FDDB3C430AD6FE44B21DF23D0827D56899D8F0544472298FF1E12FDA44466822409222063A8BC27A2C2DF44B1C4F56C47062E7D717705967F8C10E0F1A35B0C4F1EDB14B4E3A2ED44163651179FAADB643E602F2C92DC144FD96871AD3CD194BC83951F18C77B92518F8F3013BCBB49E57A4338FDCEE5000EFB89A3DC2177ABEB2DC34C094476A8844CF072A17FECC8E87F8C3D85B776972CDD5EA7F8ED6DF4A123197F78150A2E9CF2E3CF88617E82FBA29410168DC261EF9516AD01187ABA8E189D59DE5E243CB019E5B7C34F5BD158B5E11E9D7BC75BDFC71B040EBFAEEAEFB7639355AD3BDD27AB9DD799BEDFA24D2AC5566DE15F46CF601E08A702B133D391B0E236951AAB4BBA409C5B8C49EA0D1E2DD2EB9D6EC67F76D12571C002C1E3448FDFD0FD6D5C070E6B749E9C3E6A86DE347E34A72DD2B19C51F405B8A4F4DC04E7A7F3E0BFCB51EDD253EBCF47171E0F57E7DC04C0B1ED1054D06B7DD2E8E6FBEDBB16D086E1975676B0B3D34F3D290495051DD8EDB5C6FD727C8A460668FA7EDDBAA5AC776727EC2A155770B5C98297C45F192C5817C0942C62FD9FF9BBB5085F7B197AAF21173E1B2313FD94DAEFE9B76E068E8D6A46F25D6E81E09F34D0337F22086EB2F32D4917A6B5D685E3FB94D919BD8D513BAADC61643AFCFF3B1DDAE63FD0562C3F60228C951217142269183F4D9BF65F438D86739219161F9C6AEE0F65244E85758C0BF3B137B30536129FF7557E5C52F05AF64883FEDD419DF69DD8B9C9EA6D4A6B018CF676E91855B58B37120D84D3ED06C7173BC3BFC65FA01CA02A01E2893FEFC9E0E708506C84698BE652909F0F9793C443635A032CDEC61C5ABBC097997A62BF2894133BC991A19567C9F4549B30EF4C081FE2FC52724CEA974DC6CDCD4042D3118AFFA2A7EBAB82ACB14BE405FD6A764C8405CCCD0D1BE12410855BDF950747EB26E948C7FADFD2089D26824F7100FE574815B487865090CA8D8307D27276C8C5FE813A22636672026C72B81290AE9917FDD5A314029D02BC37EA1C39B592EECD57883952907C4A2A4203CFD6498C19328E55500BA395947B0CE523836ADD259F92C358026CA86169D73D17044AF5F4B7EB42348764488FFEB8D34237F17BA80D5AEE6F5DB8977898B2BEB745B065FC20DC567CB4090D65D82003B466C21921FCC13C6291CEF5B18E6F6F77B8E07FE9F803F40EB4A015A76E18C03B40CBB8C8095AAD7AE64B52D6A1AAA31EE00C5E4EBD04597377DFF1037A0B12D2585E8C2FF784659F3A57CEF7732CFE93DC4A7F11E5124273A656CA234AAA7503246EE53F430A79A0F9ADA4B6C0A5AD6DF6054883339C013FAA1B6BE863DADD11B5443B5E4686C5CA6CC2BC43415A116D2B908F8949FB594A470B2D6017FAD537F066B8F2BF20AD2F376B33633F90BCB9D262EB23B399E8CC8D7632E17B49C4792B2217BBC020635CE2ABE63B1039463C7D069B2B004D0CB650CB917311A049B97560768EC46A793F19FEC3ECBF9493AE80D16FE24F00953348E522E28B2668FE430454AAAD914C385490786CA7D98E6A1CB345ACD0A67A6B57A175D8A51C2B51F8763861B027D29181655D5548E2B15986DD3835404A9A282DE523A045E5DF42FF092144ED9392D589DE70678FBDCACCE10C956AE96987A266AD001EE70422549F7F27BD92748CC06E7D24483CE0B83C3F2067D522E789D849250E7F7588A2DB9BA9D5F439D9369F04CE59A12474CB5FDFB08C2AD9E0889CB0F2056A7170428778D3BEC8F9084072D6C0FAA922400D8239119E44BD7266A43C55A70CFE0984F60A482D08F9E77426AA875AB50748161B48390A43DFF04534054C2A2D5E4A84C804C03128A0D7134BD3AB8E0A2BC7753F458A38B9B244FB654F9DA3C2784CCE6958DE3DC806DDDD84A8D2AA24A8382AF4D11E52E1F47733FF61B79895A9AA426BD060B4761EE687F1134A23EEC3EA828134C4B8108A6C5B9E3AE6913E955299DFBCE6488FE32036662FFB0CD451A98D97A1538F5BC34D527ACB9CE6D1DFB5862FA889422FF32319E35AB53102E566C710D4884BC3357280112F2C694D957D26BD3372D99CDFD00CF55098238994610D18A247BBA60650EC3AD7FCDB208B15C4AFD35A25735844D66A929037EAE673D66159185E4B2B79B48746BD9F046BA5828595CC6820EB8A860EC9C458E7AB183489C3ADA179C40A386B1F33F2D41C8B1AA5D571D1E7088B0ED0372C95824E870D63A4B95D87222C121766B270A3F5523BB6B69284B676C81F20D0F37418FB0B40240414E95B7CCD6E110658CC41F343F4F56BAD2D31A495D6BB2E9141E374AA7B2B8EFFA3E41434B4C4E6385BD0000000000000000000000000000000000060D161A2228313A" - }, - { - "tcId": 42, - "deferred": false, - "sk": "6639A514256A8CA2D510FCACD916BDEC6245D3AC11A035B7C7095BA4DBB92C62A8D0C518807AD496B31228F96E1A2A23096EEABA09D37E615E24E5965E1073DD0192B175684B4F326189549EE36FE38AB2CB29380675306AF7FEB99B2BB8A07D5BDAA761EB9409F46E70EAE199F0B3A72568BF6964E6A58DDC6CC223FC89E27C104004C328694148109306900C0085913042D4B211E2922D60A80C91008512101118C04492344863824C81C20DC8200819C051640444C10470E42286618424149040C2344292161009400ED0203012B10991A404A4B24011A848191800DA128D83803003182C03A5201B4066D9462102442484880C09A20C1047689B140914B70C84B068D4282823885081128222326CA24882024150A4B04C44264059320498926924496950C0841910840C136E1AA10954A2889006864222665C026122304A20A36D12486181306992368509304A1416210B064EA3320403014D918885012051023701101411D33840E4206CC8A888582484444486D8A06C03C6499AA67140804518216024850001896522483222932D18052922344954900DA49890233351C434852025420B230122044D9A26604B266E8430011A2889C120240819461AB76503B50554B2605AB429091591E2122E1A320EE43808C8880D4AA264D3960042C06C24C92959C024A220208C942152B06513286D11B440DAB20104B84804A50D088650A4386049988488A28108490A81328442388EE440021BC811A1B204A1482E13B2842007501B288A24A9092109629BB465002966C44682D140459BA8400381108BC8051B826820466C40301111C77140C89112394444B60020992901178D624202549405D1320502872D02164598104249A0114A182ACB3802D0944552A441C11641C986255AB864D1184EE4B44D821224E3086A0CA30C5A18100BB3900C022C194780DC126264248801B9880A265110272C142025C4328659124423262D0BB590E28090A2385010042103876D61284618C38D08A10D922684D906501A33611B8468098830E3844C0A4424222640CC388A1C05110B460A24004C02132408067224C4611AA62409358AA4C6112322629C464E20964D580430CB388603B44C64C42C0000095A220DD206655040415A2864102510C4300E24A46DCCB28D89180D1407714AB8451413409B323011396C5882005890911293081122850BB94012050018C905C3248520B34D08964003852D8C220D109270D8464ADC34301424840CA480522282D1346D8CC810D4000C22850491B224D84688C084450AC30C1987111803618CA6644A384D09C8012092040301121A4722C1844823A1858AB24DCAA841A4160E8B34889C249280208849A0851C46290B1260D804604B4451C1C2911C0729013381E2C44019962062C28CE39220031824234202C24006C82264483466D2B630DC90880199054C242804424A5B0628D3866C1200896424492025050AC680192921E088812413204988448A368C20A36519006C00410E23304A18A04C0CB96C8A46210194105B82251B05840A15840A185059420E93C289D04611CB0242118100004606A4C28D1145114C186A922260093921A4941154C669534625898208C0080E4848061197411AA36CDAA80C0890655A2284DC380823A44CD04680011370C2840C8092249B1648C134801401445888215B4620A1A84D0BA04D4006061CA769D9380C1AB78D0019669212911C020E91A0909232515C224D243662113242CA081104A950E4C02020C069E3242E0C3109E4188518427261B84C840422A036605B1486120022D29881A3900542480613A54914228D4CC44D1B112994403112C6894C06665A384411499083904864C82D8B002DA3142CA2320261303044342CA2322E83464A923885C424690CC60C0926528844300416600C0741D0126244980888228CC214704B9069C1C84CE484440093449A226108850102C2212342282234650046698938660B371160840D58120C09102110B4451847480C434D1B33111C990459480D90260C0B464259B82C9A200D4416062139310BC38188120508806113396604318D8A928509372698380E21C925000384CC4228933031D2982C5332461BC10D5894451A47118490691B386083482D0A8921D8B82941928120156AD212414A90250C248202310DE1346950807101106864808004A5604488712216244FCA3DC070EAFADBB8E253BE1E85890557BA06F6FE596C9EFA6CADB19A6FF51D64B2F169E1FCAAA7761B8E4E94A6DDA9B390A96D7C0BD5AB3282F4F4E310FF1A7745741B15A80D1DB35B18090B1C35467939147179082650854D3481AC46C4D5F372ECACF58B439D2C8E9BE32AF5F647C4D1C8C06C5FBF01D95D35E4D7EB2D0D0FBA5B152CF08525006714C6A1DCC41281FEA9C16F1950B66DF989AD4671296C9BA6E565227A47EE10536BCCE94ED83E57092ADA82578FF23FE0C01268FEEDCC0953EEBEE12BE828BE36415712733E973D6A984747296AD5D24CB48002483869BEC1AB4AD0487BC6AA09CE9138577A5CFFAFE08119E3142803CE2C88D83CC9A102560B8A2BD01684F0C7FA1480421F4372F88CE04C3BDEB9A09FD541C17C67BF4D06781B6B8AB45A7C1DAF153B5CA37C1736A12B7999E05D213A2501AA67ECE2B92710749BBC902E550C33FD2A265CED7D3A88A961503E8C4A586867A9A2AC605849FCA19DDB92ACF22D481FE8A16B6BEA0E916119A83B8826B7B64EBDB9A8D7F5517A8812B9369EF1AF29818940FF4C1A41A8193BEE2685866B887E48DADC162929938202BBDA46D7FE090A185883192E45464E88026AD24C12B37FADFFC15956F0A2BC1AB5E4917EDC664D3B35E3C9E2CE2A73E9CF319AAE5A1EA8161B747989D2269B80E82086B677D417FACA39B64DE63AF8DEC028ED2713E7EA645A9367DBD8A4BF6E52BD45082712BD30A12D639DFF1069EB150941EB3204FB5F7D12C655F22594A70AABC428131168179AFD776579865A2BF65988276B9337B553EF75BCDB793B67FB602583A879747CE0169B72E2181C6BC1569A7353BF0476F7DCC04F7410F1C94C6C1E164E2ED651E90A3288EF61DC18B89BD8746C0491F680EAABDC51B68139E8EA42ED4CEC08CD60093D18EF38E26B1615789EE6206F8996B34EEC3773C098D61C0B4E4ACD835C98C16B0F3DD0A8145E1A74889297FDAF7FF20519A6184013E9773BACDE0705496D3B4103E5240759EDB954C9E77A05B20E4833F446F4CC447CF862778E97A388312D7AD5E0D2626B298BEAB7D27F5CA67EB73F3CDB03ED0239912590C787F9C3F4B04B170C6582DF1FA489C7F8FF48E78C3AB63EEB5CA0CAD4BA17AD57EB6181FABCE3D00D31602FC3ABDB1231EA961A5F64558D2678F963E603343FE35B4B97B60E102B95BCE07BA525F4122692A28F891A77A87F07C6444AE92C621875CCB9A973961C55D920BACE5050C42938B6FB81663DEA18FAE1625B13FA3225CC80FE23D557C35619214E140A55CE2ABE8BE2D82122BDD702B5263498B9C2957CD3B2D933F3C62A0696A0CC96D99BC106872F0E2B6E70BF9429530ED9B97E68C4ED660456D7A79E37622C0C854187985C9928850A15FCAEAB8D8D9A3A7CCA7C13C400458DB650B0B37C858F52B04FF135B6BAF86E4D91DBDFFBFD6CA957B3E1CBB1381AF4118D9FA13B70692030AB19C8D068ED620D8E7E150236B8B988C38B6D4002A3B4FD078F58B96A3C4A996A13F0C6190F783C6E6AADB8D69BA275D7045E1646C56C8024F8D1CDA3EBCDC42877674E480A070BC26C118504525595F034B4485CBB9C4C48E5B5AC4A250EE8A98A8D0448B5581F9AA1F92BCC10199A0A63AE5AAF39D6C2F82D64E6165C9878B3FDF4F3403ADA84A57202B94F4B65B4EFB551477FAC6338DEA7281962698CC54110B8F15D4BEB4C091B845306024445EE008933A8FFBE63AE3580E098A18FE33681D926D46AA99F5DCD9E9C6AF4CB2737036BE094EF63C0310A42DE5CCBCFC75AE57EDF5DEF3304BFD6854405781FA983BA2B582B631E4773A62CF8E3B222F9FB0C484653E7DC89851C989F62596377E35BA2A05F544D6C2AA1FFB71365BE259FA6AFDBB797D70C2E40474C2697A510E9C277133B26C2ABC03786589859134F5719314F392093125F15EC2334A2833BA6F4E634DE374AE5EE93E7C6FF37D978117122A19F5522E63D637E6109BBB80C95AA807B205B78821DE56BFD0BA9949BBF0A58E2D3803B89AC37DF91955536C5381D81377AE430C261992EF2501AB8FD653D715C93F63A98C7A00667AD74DE5548B685BAA6D301D4C6BD9E40F7B50434D8E88AFA19F73986CF55E5F318BC5264F909F8DCE692637FC09F62E9CFF2AE21FBF37698736557ACADB9E782B6E60A214216FEA674815507A12933B0A9DF9165180579072283F7351FD9696B1C7EF7713845B3EA3F618A0E52ED23273484EF1307E7082818903C5AE7A5EF2F11E5D1E813B8B2796D2E134C43EA733DEA8EC94CA03E64B0C06D7A52C38FD63658F549E49872BADB78020B9DD64055EF006D5D92FC0642EBBB025C44F436B9586C9453FDD9DF65B94ED020A5F647717881470C0C27C266AB56C3115E4336633E492893DC34359732740E954B74606232D2F6E988CE1FE565527395CDBF66F1CA04F42B34DDA2937857589E3DB5FAAE2B0CC97A68408B2D73089AD0098CBC66F03BEB12FF72A00AD72C5150BEB7760D700D634A0823988D20BBE9237B9E1E60737CFC7A97CA65AE467026E3664D2D2242E73C3D43AF26D33828358670BFB69A3480CC4483114FF22D93B452578CDEC1B93C732910438B66E30CEB14EF03CD044EB6D51E5AE1242EC49F176A4D888DCDBC6036163160D404B5B17F194BEC4A1A8FFE396B6A1E3500D2C1B17CC8CCA3F105A397D62B4462D3C09638B01B6A60AE76D93A4D7A204F8CD381C7ABB9C06F9B4F835D89A69A5F0424052C19D5AB4FED48B4CE549976F68BE60C54BBD5CD80E8A0DBF80A75A961332ADC8377CF2A286068B8E4C7F9BF85B2FFBC9FF2B9307BFE33070764C49EE7B2DA597BAA459C4C0C1D5BDA7DA4EDF5DF2ADE76F44A2C64576CAC913BBA0059027E98666DC03610189BD709BFE88F0AC93224DEF65D86FEB422563A83BA823F9F312CD13A7707275E3701369CB009EDBF95E966DB3DB9645F493852DD1F71B025102D2B5CBE6DC315DB57D4E47C9FFC1B65E0CFDA0FAFE7937459DEDBB5983FF57ECF7E1D38E9B67A0CEB91FD7CE01DAB9FA9CFF2A4DCB19C8F74A4DE51DF1D466A44FABFADED4CDA52FBA424B312A873D29DC420F8FF3C94DA1C896E0D54F8C882BAB83573716DEADC439904093EFB720A1120A7CD9E18DEE7B6674466737C36948A4EA961AD122E3C461FE6D5A3843262A3845CBC97E37EF41BA9274D0EE4E77CAC71DE5AA39E860959E353AC28D1A545BCDF977BB4BB7BCDED646BEED12A6E03ECDBD2FC3C1D845D5C9299882D15A295AD1D39888EC943216CC0175AFCC605938A2F72EA01F1B7BA77A954FE1CDE49A7B7E224D1807E81BD09634346DE0ABA64C0F5B3D2E6A9C47C497D28CD231A70347DC9B9713E1FE77CF42DE2AFECDFE081395AE1E2198E2C8D5FC05606D648F18D3B5E0D96BA194C1D9E4985506F6A96C48F1CA647D478EEDAE301E86DA2D916A41832D28A6315A2B95381632A3CFCE232621C8477680D4DC096A57163E4B570DC6AA475577A60166AB550437AEBD5810B523E4053AAFCA5D5F702F26C6FEFB18637B23606568C43AD1047AAA51E84178814319C6FE2CDA8128B7156F84ABF9D11D201390283801BBB87FC2AB6B050539D1DF5511893F809CA261303C54A7C8BF4D433E330ADFD495E3D36D61D469BACAE8F1F8814777B3D20B4F98EE5727C1826CFBFBA2E5BC624C4ADBC32519B731A666EC67D082570B1739066312284C1F560A9CE45EE0E576F5269EC5C325667D13C3A62EFBF24236A0598F973CA99C53DA3E5D4130FF8F4791E5A900B0B2FC93364B234F85926BDA82286AA1B04A2EE280357CB6D2A464E8DFE9AD6780BB2A6937F008DCDB8B64A904E9CAF6B75A4A3341D068381D6C8646992A7AFFC4C2749940FC7A51D4C7195F291F8A1E3C4E0C7AC189669269036A2996B9A7A1D696C35CEB82DEF7B4C19151E1DD8AC8706E38FFB945907D2D825B06F65EB460A5F51CC9B17310FB878D73A436788DDB87978BADE32BDDA761EDB2CABBF9D44B9E7112BD8D158B502AA34F7326244E2FF83C778B5AB05C2A8CAFA7E218EA97045C658152A21D8015B4A62B27ECB39B72CCAD51F52D3F323EF61F35304BF52FF7940642C38A0643181A6DC6042F8E4D87BBF40D04770899AE2165B39C2ABE3D00E41311FB1B3DD865567F9C60F5FD03AFEEFAA9EC299B50C1F378EBBA3700DF56C4EE64548C29A6ED299B8392DA122204FCB5CB990E898379DC6CFE26B6C37FA4F25066BFF6E296D1EDBDF8578A5E939CFB07EF8D5040DD3F46AA3152D5CD76285F9F864664E465FA66E338CCA55557467D6E7B443478CA00900A6E14FB8C7FE7F27984153A3A1CF070E91C8E520D1F6DC0D627AC966D6AE8B3B10B61BA99F642C0945174E3D62A3448A0F90C3B1F7104409FEFC05286B4AEC3BC389698D500E199F70F8374AFA60D2B4F83A22813F8121FD99E37BF310733F61635E4690B0C6D0498563287FFA83F2D677906A4CB0630CE3A768FA827125B8E37A5F5C855192762B8ABDB0DE0C94538E441620CA1B3F24425B37F7C13A9A55EF08117B8E5D2624A670473741449647E2997BB4F7A1E08A2D58ADA29E80F453C271BE545F2939E2F95342131C2C9C3E4FCD52C24F25D3D3C6B040BDF0B8BB0FF47B0E4A6EA11A3F3B10B68E4F2225D5A5E4946E6033926EA55A21531F7C344B06E42B49908C8F3D43439E949FA1", - "message": "36DC7A310D995379B796EB8F9CA346EDF60DEC7F6C00AA311B3E09EF96A6795C4B077C1D371DD8D4A538AEB78B81927D08008E817A6FC6B3F9B14FE56EF9B2664E76112F214EEE848E67EF33B4A4E26A2378E9480CC7D25C369E6C25A2673B946B635B6EECB5F5F1499B484DCCFD5165D6F14CAA8E1EC9A9E4FDE417403720D7B4BB30060AB95C6F227767D671B75A1BB5AC5CC33EF0509C69652748251869B072B9042618071233B48A9BDEBA330F0C450A2FAAE79291B9E2480D1CED11FABE56210A80C39F25E5574356CFAA32E57782145920D6C0D27C3AC7C63DED6A770A5A45119FAA92209F2A066AB90FCB81A886FB87641C550368C1B412E43F4FECC2FD659B2BDA6B7309797575DA2893314DAB058DD92C7470F570EC0B1D9C9A149FE0934D40182CAD14D5B3D98C4B7454CDD2AE7E54EFCD554AA5B458888048BD5201C04E7D6004FC2A597DA781BF15AAC9748B6659EC16602F10AD44145607917C3599A1F53DC95839086A6A4FFD66F8EAC8AF8F11C4F2EBA3B58C46B93D0494C4CDA4E8B8FF7278049D2B4BD7BA16BC57678219EBCB5E211D51A168B5CDF66453412565B9BD606CE29A5A70E60F3D451D4214B0A258D6E9325EA5196C55125F0E115B14FF34FF6B172471C2B4917FC36B0DBDC82D0475AF56249AB9297790535C0F0265D2A853DB0B41B418072D0ECC17CF91FCA86F6E10762EBC520F0AADCC3C79EFC25E9692FC0A66389B15ECDD1377A9C3D744CCCC4BD160FC65A45D4144DDCA04E5408576DBA6D5C875BB4071729361B0514E8B96405E2F48D47138D2D2DCF4DC865F717428FA1262DB0D2B7B1A356E9E76301D38BA506456B4AD70ED09B0D5A1375AA6E132D7E06F8745E7A5B5E4F6455F4282A87D2B372C40A34C09699AA8C2B2E060107BCDE0F9D99B64F17DA5FA01B6DA87B1738882976B21AE12D1BA0AEB37644AAFE5AC20E7F3F631FFC2A24EEFB61DC37485DF27FD9045BD9BB5D3F00B9B2694CB94B01E7A4F0D909B8612DD28BD64E6C1C5A612CB30DF6004276FF58491B8129FCB0B539CDF891A97AB58DDF04AE40BAA5781C3AEC65FD7E84DFD0369A53CF36303270DC80E3E428854D82B08C7AD022BD99AC0851B16C7D8D462DA21126F70D661A59E4D0FE4441806DEC48E37AC4A271F15D916135408A2751CAD53564967196763B512D52240B2B0D3D924B83CF482B5316B7988D73A16B773705097F5ECE0027CCB2C2EFF598B8F61ED4D6BC015E56D4549432A6A95328FE3122EAED0149E2144E4CD2262C7FE7495E41E0AC9FAC9A11E21AC940D25E74AED8EF6FECD21747FF8166589B7038EF1DD504F51E01F1ED911FCCF44949638AA6E8526F0B9DBC5E536FE2AE7D4DA9DEE66402A45CF55D0137FAFDA9207AA7E22FE396455F2F43108961FA6B0339D89EB8ED7EF13B936E3D2DA18E5EAE45B05DCAF5D845DC62CC55553E37CB328AA2C649ABEED0D862E8083962B81B84A85EC12D3CE5B600123AA7CE4764139BA7AFE5CD02F70D06DD9AB0BBE868070A9AACB951D362E2606FD940A8F5BE632393E0A179C2A62151A094901F5625D952D39D7CAA87B77C4919A8633458AD9B6DAA16D1B1CAEAA8075741094FBC0C08D30D9956812C1D3A75926C546ABD78A2B9D44C1B6EF8D6EC2A2EA8B7C23D0EA57E1320ACFB576FB9C575DA98B714D6B01F03364E618A2C03BA84BDF0E5D2A0403B1379416D87B5E022BD958B0C9170E82F8E9A727D39C8F7549E34A14792776AF0D72A27FCF63EA985B3882A717091EF35F5835D4DA127554B6637AC313BA3BAE8170B9E70A6DDA2DBE813A49F045D8C3A65ECFB4D5F71FC75AADEDAA91A81A958273ECF0CDC4512F0D0ACCF9D9D001A30D0B6B2D50BD216D6086AC5C9DE7388A7B1319F2E9E6CE128B1F72F765804E060A8A92C93295A99C66D6D79BD7DD4F7F02317927D60B2E9FD59EC3F95A874337228339EC673BBBF53BF0FE1886A4B14F19CD7FA9B771894377F904EE8BE48D64EE5D40882C684C81DA3198604FA599DA8D4EDEE8EC3294620B6555B3BC9627D4514DBD1F7E3E9DF7B56BDB4CD395A8CCADC184B2B8DEB2AC7CBEC6C96001EDB67E6CF6F872469B110097C69EDE1121D22FB5B5AA4CA540474630651A4F9E8F7B0ABA5DF568D882626BD158F925F8DCE1D81668EF7CF770DC615ED0F5A807E25991EC97BBF2F9E997A532A1BD82A2A616250D2232F72067A17550EE516F28940D8EDA9CCC0E02EEFA496010E499E62C50B03F1D3C1571342DB8A5BDE1F432F7B6163BA3AEF35656434937A42C4E1F473331E38467DEAA483189902364463832ED8C5E04E0195D3435A6FCE75EA3BDBDDB0A0319262083141B1BBC0C278CFD40319647E90BFB51374B0AA5EBF3C564EE95B7AF618669C935756AFF3150A93EDA92F0ADC29253758A6C8A83EF55F97F1A4C0DB566668F30DE59D93D8185BDC1CFFAFAE472E0B0FC4B1E16F0B748220EB2EB85EF127838D576638E738E9F93A05D41CC1264AC6BA03B202D9E3B06946CCC68DC15261A029B0C5E91DD81EC1D79BC51F74BB5EF778F00AC091513443308410F60AC1850F2548C8101DB3B6B4D453541E36F0ED57C2C14F465196F8F1D0D3ACD49CE3252BAA0C10521311B8B8366C579A430526ED58BDE92FED3F0B359ADB31D67BFD212BEDA7236DEE4615ABF13C856CCC93DD02AA28D1CE1F12C2DD69FEA828BDB9F4CBC9242E1017D1063A7BF842B00C75243303EF9060C8EA501BC73B3EE470919443EC91D1F0D6D0F23A899AB86F2E8A0898D318BA520DD15D9B24F4F10A1B9FC52457714A151E075BBE419E4216857500B8354A8445B5FBB526A6E008229F33D8DBA14DD42F424DE3675E704DB308048B2D17904DE46B76622BA08C62F17EBA3E9F414A1B10921858832EEFBC282755B319E176ECCDC32A25CC5E76479AC112570AA86518BB1E6CA3F46E010E8132C0A1E8273403C5C4D7046A05398D461CB6843D70EEF8C94DEA5DF53CA1A4C7842AF5DBBC6451554FC7F9913E56957C51E0A602D882BC389C5E5C7899539DBE6832B0AAB5EF26B2C96CB03D1795179A62F748CA501CFA34D5ABBAE3271AC1F005112645F10863AABB062FD2C781E4573173935B5392CF9E88A1A31989E1B8E94F77CEFBEC591DF6529C6D2FAB72E678C534C4EFF40177C41D02AF0EFEB6371835CB55AE0AA99C0653876CCB56ECA127A0A1DFC0F9EEB49525C9A5786F618DBF57C41C5CAA971A9505BECEA8969D9DB28B0E707C659EDC42280035254E91C522300368F49F2C36211E455FD620DC956AFEE41A2493BDB2B0B8AB78E0B838DA6584FF753BF88CA6A523042A285F84ED90E0FD5E28F75A21B53F618145C16925486DBF6B1E7D76585D0D117EC562E22239E14A49ED714814F01DE2B250E9B3B6A1C99D1A71CEDEEB3ADADF611C4A4F97E1B26AF9780AFED5783129FD58B1232C7E2DB9050AD3D494EAC254DC46B0461A1B4B63840621D45ADE97EE5663C9BD8FB7261152545AE35536611B5C65DD6D66878DB71640EA429F801D6FFE291B06062EBAB9B416DDA7D261A46E58B154684E86176169CFDC4A60EA38300C3D44F9A4C9DCA0CE1BF37DF8F786F28B5B3CC7B0199D3322CFDFD2CF88C5B794C69F59543FB985890471DBC93A313992ABD33691CCF69B96A9396E5F55B54FF7BCA82A31199E5E81CE94B6B523EC5C3E2F2884D8BD744CF0C072E29E4B542DBB370FA5966F68CB20ABF40619E76C099BC7A9A373707707624E8999D4CF0A75D4AEAE113D7823D7D2ABF54FB4E68B8A6A57A198B128DC69584D2DBA473B6725FBB8EC9561D6614D606ADC4FD9CF449008C0D54BE4F62EC1441FF79EB59442AEFBDF1F0976844B4FA3969EEFEA10794FDBE35E89EA52F50AB26319BD1604D3FF5AC660431F1073575ABFAEEA00E1246DCD1D9399939D655C222E19E9DBA5FF42709FC11E7E365D7F7CE2274FBF1738DC5CF5631547549F2BD4DE896C8FE039720F5E0149BD81533022DAEE22B93A3AAB9AA9DA15180EA071D98E9FD176804A5B04D089E9C2D386271A8B13E7D668AA74BFFFFCDA3B4E528937C41D43A87DBB46C2B49B63BEEAAB978415536A87D845F6C2484F21D71D0F904438C46E7B0A3C6DE5ABC01C6F7CBCFF21D3E74AEE96C20C32884DE4EBA0F282C0FAD06BD9CD6B7B5031F149E4788F102D2AC2C99FD09B14A4AE3BD6859CAFE6F5A494EE8CEA29F49D871B79BB66AA6E6EC3718B97E83765E96D5603B209027BBBBCB09EE6FDE3AEB65AB1D73684820AB1FDEF88086B93B6338BEC7088E04F5F6E520E3D715C6C5E5B79E73B9E7AE1C5EDEEE4015860CDB9FA21FB434C3F28AD865042284A7FE9A5FF47E8C6158DD83EDF28BFB18DD5AFA07A48BD5AF25B9644400CC976A9B0FE9D9071E708113802A78CFDAED28378AA4FD6FBD9390D8A17D6500A0E1835652C7E0B332A382576AC4381CAD51A31E64E5E24FEDBC62EF9D0CABA0C8EBD8B94625207D0C8C1C6DF4EA2B20832EE44D1E2DEB799BC97B7245EC404F10764296E5BC4A919EC24B4F5F7D18692FA8DCDD5BBC170A81BE7590B7BF4058DC7BEA0C545BC85F0B3F0936386C37115A333285451CCAFB8397F1AE1B56D0A8F884BC968E729D622D21FA26B89BA2726C91E6886838DC9912797FF2BDF6800665C1D1DADFA4A240BB9BBE21B6DD750389AFA49C5C366ACA5E9C3B31B358FDEC42B0032D9E2C22112E43BED2023B364DAB334BBBE2C3B669EF700702B5D1837A6EC15CEC2B2036D56B8760129F593A669FF00237D26BAD9F9C2F4ED4018D998E555D2C3CA1D53EAD6A1E27906353983D4408904E5FD9D79AFEFEC26ACEA1F39218C36637977F6E2F3F6211AA06AB9D5F991C76F420B152BC95C4BC10047E107CC82E3B00B2325ABBFDB0FFB2966D5FBA0EC7E8DE1DBCC053C4186AF23A6BDF3F14A7186665AC2682FB94B0E10516D500B7F67BE4BD2523E194A1ADD8B5564FAD9105C86B6D16B08AABA604419D55F571F11F4989197144DD12867D1636D12800D54D36FA88C620008095560103366711B8E3AADD5624FBC7FF51318D17311F02A807770466AD559CFDA0AE1439442E4413944855D4D0074D529CA8DD621DA02FA98F46327A7BA600387EAE5E724D64A82E94ABB760C891EE39F27F0CAE8D1AACFE20629DEC5DD9BF4CA91E65BF413FD2A9566B7DCA9E500C2C328F533AF2A957E46D9FB11F0DFE99127656B1D4BE20C946BAFF58E5FE1A9ED282ABEBF6EB35A35AF324DF0A858CA8AF507CE43D228ED81D863F7096044A084DAA37ACB6AEE98E5A94D363963D4F852B955C2F076848092E6199E07990372E56BA1D590BB83D0C7F834C852CBC39B666B801CD32A0C36B034264F3BA6911A719001FD0F4B63D2D628FD0CAD34B4C9355534A8A38512E758B110F48E5A09B504D20D178508E09B1423A1E61164E7D138B4A9455B95EC8EA786F5FFE67806781F1E619505FD7DDE9A904E9003CA7E5EA1077C94C228D36667031502D78B3B52C3B5A09FC398D8B5497B6E3F0C5381BC99DD7B11DADA2DCFAE352DDEA2C749F8CF5AF39587083C2C19576EFFE871AB94D1C7CA2183FABDB74B27A80FC4F20CB86B46B0B7F86384540EFF1C888168F74634F2C0BF7FB54F7002EBF90B6C4B2B25DFF068DFC7D087A27749D6C36AB0A33423044AE027DCA8C42678987005FB9DE5C2774924AD2A5A8FD2E89C288975F89B5C0EF70A20EDAD1925060A12606A9B03626039635BFF332A0E6BDDC4F5DDDA209AF8DAA0FEF045FBEA9523D04458FBB0BD81F65396938436AFF5FA66E997AE58D64E7B5C1B589558B3DFF6D035E31008D2C76CA426B07F1644F609945909DBD16559B36461CE882A361D0415A9D93CB98A5370C56913A299B2DD1AA372CB75C7E590A9629CAA6C439CC5C7D94A21F36F998C6FDEC1C1721ECC500ECE1214EFFDE65E479D38C635EA223286DB326EF9B19B3CB862C96C162D3DE238C2948E7613A0FA4843E39EAC51EF293AD7EEAFF0F522934C982890F83E922B2BD52815136D0A758B33641C54E7D4E0F3B19AA85859B750E7A7FB80892C3DAC5048767132E2DAC5804709B8560A4B3828B1CD25DAF263A2466AF7FE328ABC84EBBA26902FFD92B0D765AACC0C0DCBEF962E1B35B1195676E8A67ED593B23B2B0305B611F9E16633E77E3F31794C58C5309BA07DB5CF9AA1CC108186318A3F16A7141854C2FC8B469BC0F54BCB22976A3CA05FC2C8E23F1B6A891E7527F204ECCA0A5400B68565906E795FE4DAF52ADA95A9883676F9110B14CEEA389CE9BFFBB5D040E60D3D03C4E6D6CBE9ED53EA44B1AB6ED7EDBACD0AE0613DBA5A5C673A534D48B539DC85F48175F13404016C5289348504141338FE958AC28331853AE80ADFEB49A6637936BF82FB26B95295B2E46F4F9534720A4E86FF18B31335877C9CBA96A9B450C1C8C9C9862E51CFEDBE3DE5C8B901D792A179AF9A782C330035A14CE6A710D398BD28416CD72373FE216744F6237B38B97351A77D5D0DEA1A26A0A9A24FE15503240933E1CB5AF458E6FCA8624669A0DF439CD7FC13F7A1F10A0CC7DB8C6AFAD9C99B5FC45A7C565B5DCB74FF0EF426FE7C260D3ACB1E9E83DD8E6E11A642145BFBB7566D582D0540D7931AA28B7F8F682E6E2D90B6E6812FF8B7F15FCD3DEE686DF06E8E6C456C99C6B4215C4E874BCEEE3B4F94BA825C6A45C2A2B4C6DC04F8FF5939C74E7DA37E02D8230340C6E2AB7CB82BD226DDC1A7C7BD0C0FB36F71F9C772233132B8871A0D76728C2A141741C2662438C5CC7B129A6C8FC587A0E475545D176818B51190F0F19E91E05C04477283A0A7D4D646EEDA3BE64459780BAC1862D83E6B99C5731DF91F0CAB454E70A0D94D934D0CD83C8B8301DE282F9A1FFE49E73EDCB520C016FDB4AD02C261DC1A1E73E38809E60F91A4E38C69EC70D2A621DF0D21588F24CCD59D331C69E16F0F6BCAA8F24031DD5718875BD9EDA5B420C116E4316137D4B77623C9D73D182900BD7A0F90A193CD16107E692D469AF09F74702492E22C796B6B4A960D47FDC571B4A264EE3528A0F5A9D66DDAA33FF20C3101D50299EDA3225834C9429976EC8E590C6D48A721A14972BE70955EC1A0348D2F84347C1E8E21EB0C1FE67223B42A6BCCAC43648F3BB5464121180F8E3E682B4B664D91584AF55FD1C7D2E6F79A93C680238D29CB7FF36D259CB703DE03B2EEF6DE0CB77AAA8F49C61EE482A8DAD30824E603411D5F09482DC84BE794BB6EB65A7BC1DA92C8BC8364AA88D4B8212561745BCF3CBA0D6AC8B8AF80373DE3F44EE39CA3CE4C5763F422CD4E8827B1E7BDFF79DB990A52530E4A1E21F6CCDF50A322A086AFDF24EB5FE4D99F1D1BB4D6DA965D168E9726FF7A4C82F327A748DDB1DA5A3D0E9C8E0B060872B009CC9F913D35D94FAA912B0D6FBF233DEA3AE3C2A4E35BBCACE21CA3E5F7A7B9A486AE9D7A7D2E0B79FDB11D87072F1B307402BDB22746B86A1A0E6B41433D5BAEB2048ECA53A1ECF895E9EB9BC5D6AB5D5DF72353566BB90578F12C6A16A163E95CD35DA27C79379756141DD05C315B466871E2B726B8821FB6FB439B49430CB3CA47CD211D03DF40AE4A0BE87B6000BC9C75AD23552E2129F47AB64BC9E5E1620C99405CEDF7BC059547D547E2868A6D470D813AA5095D0AA4BB18D91964988391EE6F05DD47CA1DA0423CA238C5E50D43CFB0527973506B9F1DA4A8055C47D1FA1E0DC783CE3CF75FFAADF574EC2849631E2551368291AFB5F2C40A4F1A184E37A19E511F482B7920F6D51B13065E6327F3C21DAA7F73986F2D1FBF375DFE2505C0FBD35F403D253BDFD0BA1B00CCC5A20B683D4F1E1F2374FD914C7D674901A0F01BDFDC007E8021013BB9A2F885F0699D16805F9F2511A0C7D3CDC06E36679983A2A0F12662C88BB7DC643FBFFB58CB51AAB3CED28553910D063ED8FA37FD756B79AE4151521450E552E4F2B62EB6F6BCC8086BBBD30331F3F2534AB3ADEEACCF2A6E66F205935A167FA1D5C747936050E276E8E4CCAFD9E0A056E4AC2AC08738BC3A598F07E933B0ED285BACE3D24AE6FF7574351758F983FD7EEB3944473EDB4EC9A9828A5FC656BBF04DC623C75F8B8038F3699BD5F255CCD3EEDE4FEFA12AFE8F64436DDB1FF2DF100B09BEC657DC5D2B18E5722D5AB30D075D9A52A576B6F9FC8C8BA3ACA6A92E6596F688FF5D2A7E3183B696AB277B0B17F004843E58760683F90BE0C61DD0D1BF9099A865CAFD1BD1D8AB1B7D4AF2F86D51C18D7868BEFF3F6C53EC68FC46EC9F23D1AE1FE85CD97D8CECFD57A562E7E574ED1D0A7005813EB980C2A46A98CEC602C0E022E87D4A6EDBFD7DE9FDA8C02EF85701BB1CEF6013F4869D32CBA56B0AD6EB007591D03C76A839F9D01985C546C39E49D59395B10346820324F3E298C5CD977FC2FF83BD422CA550DDF2A69607BB8125647B389246ADF0095F22692BF907EC86BF8D70D7E8F2C50E35DC6EF34FD1258E1FEBA0B254470D43C77CB0073AEB2D4CE5F6772D49A101052D8CE943E1C7760F2994071644D27D26BACA88EA07F29B2F2050BAC5E05F2226F1F584D17DB80E4056B7F9C60A5D9DA0CC577C6BC802FAB26E570BF017DCC7236A1173E273397E373640ED02B4F9863C40D2A2A7828C3875D8081AEBEF349143BAAECF9089EE736EFF0EF80078D2CA7942FB24A92071D229A1FDD0F6A87D362E5165D57F62D927757BC31964B5DA63B90EB3591552F2B9902E2269A163FF221863ADEADC9BC92CAC0087ABDA02004C0B9F34E5CA8599DC3C4261489F7527FD27AD2B6501E602FDE47DEEBF3F3EFC0166B1EED95116CF43C8AFC0EF89BDAA9ACFB6DAC613770DEA78960C99C9628C0D21FAF63A0FF7A3F2733EDC0FC07B83F107A811BB3C1DFC6CFBFEC105193272A4BF915B1DAEB232E16216E40FD3F9D9399B15CC4C073BAE8D08A4EC42D91609574EB009A9B52F06D3F428F6EA9B0511D8319A1B1299C154C94B103CB586370A58F18F04F5D21AD3B638660D6C04E99D356A7289E37EFAD643A5EBB488D54F4A0194FBC4283A8C4ABB8D9A1D70150AA50F991204C038AF54B5B74F722CD6515045D62276A9E936476F42B282C3B08D9328089AEA259510240B95BD5E81FB9D7E006DCE0DA832BD9A833799E05CAAFA6305D16DBA4461BE13D3CAA95773B98F09230F2DBE13936495C2DF5BE3A8F3EEB4FD211810F4B07D3E2BE1A11CC87079DF1B32D44B6FE7942DF2627AC19FD9F584E771D7ED98AA4C074A9DA5B7C156F83D90EBBDAE78D636D51EB0CB30C7C7CBC1A96273C0AE0ACAD8E15D1196BCB2EEBDA332896BABAEF76B4275F863732D646C24627AB014AB602A47594D6031795B17144E6E2C23F0341422886C1E2512222ECD530017DA02FC015EBD5BDFB319F3AE942D75A55C21BF347A44B300ACCED7A339007A2527EF4499E3BA5DE334BE58D59918DD0CB55B2F478837F71E9CEFCBBC90808E0BEF8CC7712A3B008B69476C61535FF0787B7833B70C69B1EF506EC4F445B72AA12FAC2589815874E9123BA13A17477D61E41163CB21ADB8151658C99F1422C71A8183B8D0B1D489EF436564C47ED8482A0DE9170CD1BC34D88CE76E1B47B84E770020125F718B4AFB1E4587668634FC7464114762A9D74A93E33A5C0CDFA824CACBEB097B5CAC3B554BC0D41C402812D8E43DB37C730A6219AB6F0BACD096BBF261C78E991DE0A2278DCA7D1BE0E5F2FED72CA38BAA86924A84275BFED3B91FC8DCC5024316EA0587C96E030544F631076DEF65F05F98C7641A958313686B8580CFC20221ED50DE4D2CF32461FAACD0174AC46A6949EF8ADEE6FFA3F537228AEDCFFDB2250D7BDBC848AFDFEA67AE53CE9ACA45F349557E81F70F9DB92926FD0CED8C104E6B7AD180C7B3BEB86171EE84A8DD2C243F6869E04C2DAFDF0C938C0768415C56330C9BB6EE756BB335BAAF96EEAA5CB52E554E39E2435B0731B0062376F4730108DD2F05824A798DA24C239724D19F12C6F2FBDB52652352021E0167F31E0F5941C4687DCD13A81A20A0AF05A55D2533280941865DB4D5715AEC293A64AA2E5151C8F44A14B72C0879499027E67E4E2B487612216F6122361E8D34E92C2163B0C88583E3887DA93A3AA0E77FFAE3FE8FD5455BC86AE6D6D5AC7CB7BDF156A960C98B0BE50E1370A43E7D183636DEB2C64B264FC5922D4BD46A8206F911E7A742E72E4EBDBA39B6151AEDF5A6CB4157B375D9A59899808F1838C61EB4388B923423D3879E8228AFE0CEE9561135849A89363F84B41BCB166EBCD0E65A2A74FE710F2B3B55CA9DE2FA9DC163BFFF4BE91F10493936FCA15F5F39422C75233DB22299456D1EA3BAC26F6671557B2A5FB0E9460997DCA797C67C49DF109CFD597BE34C8E0FA0353F28B815D0CEB31DA93E49EF29CEAF20FEB0A8F5924DCC62E830353463245899900304A8C8DB5830BC0E97AB83853D8EB05660D6A9303833D170E138FF6F1C30D9DD64574D5F875F974225DA81ADE3D97924A38F552276F46A5208403AEF82D1E92959675EA6B353E5C6091034A295D9C12C288241055A2334C30DF0A37D2590626A7D1787A4F591A6E494BF55ABC76842BBBD508FE54C5630D11C54386A487A756ECBFC0AE8957E7CA8678D5B9B044117365AEBE79AFF2E6678001D23624", - "signature": "58BC36248443BED9F1FA12DD93EF6FE7D89828D96315A0FBEF047B5D57BE38BF2BBAE0DF7E983151E879479E00046AB12BA8354A6F51F9C286B83560DF391BB7B1B2A495FF27E582D3D09412950CE565F2A800D18454C0C17181153091B57657ADD3EF44C97FDD8DE557FA590474BF804E569EB7FBC36357710A307F3D540F3457FF382730910BC41C20402449A0CBC5A93B5FF47DDA2D39E59DD58A862079FD60B24E8FD43BF8750AF3A463FF810E43CC4E84D9B54B716C8EDC3B00BFC0A8FA7210E30DC6FA7B8668078782643404736A7FCE53A870491E3CF91C38A9E761426FFE7ACA6D1DE13BA213273E899DDEBD4E0BAB8CA084525DBEAC382D0155421B800A1AA921BC4EA1990E19CE090696E081AF1D4145B5C6DAC1277FBC483500B80F1CFCF40F49F48D2D86531E98EB3D14D1F54E435E976F0C123B14A4D8111927C2B425A43316FB10F9DE9BAEC23D49F7CF37D2369ED11FC3801E84C981472DED8DA4D1AACE2F6F4050EB94A483F79F2551CE179B31D753072D02642873DFBE5C7E61C9FD32701C10847C6AC35F41A2DBD695DACE401814743B88C579BA7B188CC878150C71CB5C8AC5763A805801FDFE267D812F65FF31D958B857C41B06A738646E93AD2D9D0AD0E1678697C494FBB76CBD41FA63719A3331A96A4840F0DC65F890F7F81BE3D22CE8500CDA8E3AE5A6482DDFD749F363882353D2EE9BE0784BDA8BB2AE75A011869108FC9736E6E6B08D9F6F42DD42F4C06A561C5E8B585ECAFAC49BE7B17299BBFB4B74398D8A300C6447108FAEF5DB463454010217F01AE45F0282D4A3B9EAF23FE092EB750EC081D6EC0329A9A537A5C270C31B1499983A7C293EF72F0A4FD91CDBEA3F029DFB35FEA766C475A07BB4EB7297A9592A20E3FB15119F5A7A9E658D18C4EEB3E35963C122A1397456DCAC9DE8EC08DF9873C751A10E189B9C8DB3F63721910E930397C4CDE3D475AA7E5C56FA2B139690C20418DC40F9AC14BC29B419A45ADAD66AE2790EE4CF0233EFEF06E75CDCAD7A594BD9D64F0A030EAB8FD2C77B3AFC4E4737FB5682FEA678FFD75A794DA8E2A0348088A48D1321C9828E0CBE6F15A746DF22248B360F51B501A9BEDA1F7263D5BEE948C72C9ED854EEB7DB56E5885F6892BDBE019B8FFA9CA30DB9D1C82D3E13AFF7D75B0D0A713FCD4934B559A80F4F32062BC4883CBFE4B4F905B8B8E639A203D69AB8CF33B61A3092B38F03683EC64605DB4585C1E30021294BCC7C98D8DFD80940E82E65DDE8621A38638D6EFFA26E19CC215FDD0A305E6BD731ABA1CD14BD397ECD52BBE7CE7D84F88323A4C2D709D28333BF97DF22D24BF792EDE7B5F5DD1FCBEB169B625E36D2DFA95539188CE7B7BAD539C2BE1BA1971648478468AA3413DD6076A213EDDD1AB0FA85076B6D91DBFC858F1F935EF31DA87A24E3171B30AF8F03E8DF50A1781FAB6E3775E5D14B3025492B4E0309228AD41B68B278ADAD656EF83B0F8B1ED030835255A4A07C94A35D27B256AEC0381C35E640C1565A80D55D8905C7DD3BB69801DD362AFA95EE532714BAA8FF701E8F8F30A6165DFDF4FF260C6DE1135E66DAAA7EA771FDB07E07F818E4B2F7334850789F8FD0E385B23641F0D8A7C754A60B35A76389F5920A4DBC0E890A7207827F2B6368CA95241DB5C6664397D5A294FE3CADE660D80F69F0458171684A997B68E6CAD05417DC192638F9275DC093FBD4A72925DF8FBFC7B6777CD28F13658B4D3745DBBC82C88E42A16C31766A9ACBD13DE946054131FBCFF70677F2FE91078D9593F12423A3ACCCA5761830297971F6AD925455B9313683F01541B53543808D1E8C6ACBFB93D3B4C715880545B77AD0E7F1CFD6A3426815BCCE1F3E7EC720BA259046B06803110F12508B33D7C04C567BCB2069DAD995C590A2560C766185D7F2A186AD1B336A1A5BE702F6691F90978F1EB6F3403E00A2464F19AC7C76D2490CCAE4C0D117DB7543BDC73E6DCCC6AEE86D74984FBE575C10E6AAAC0028D61BBDD001BBA9186065A7BD1E7A8C13CDABB33F6F2FD03BE5E950793212CEAF82829142E7BC7E97CCC4F774892456870B23A1D6CBC5E1D2B797219AA1D4AEB332F2B38DC3B230E0EEDD600935523D9C05D7C750B485F32DF4BDD932676E6FA4A7AF63E12AA149AFA49ACE37B03DBEDFD502B97B36238DCB412E5D9C6AD0E8209119DD9BC5C22ACFB7FF53827CD2CBF259DA76D48CDC11C452FFE69D73354BA70D9CF566872011AB6D06D027C9B1DD93B97963F964B33F8F4FE51EE4E1F4436E5B3AA240320BF3CC6FE63B219553F6923A134D843C9B49F913525B4FDBB87F5F3235461E8DEBE849449BBDED39DE58BABF6BC66DCEA2115AED2582504E5FE394B9C2C346C5251E9F058C6447526CB3786A8A66E86747129EEBEA89F6F27AADACC5A97D6D9EDAF5533218C46BE6C8A108F8723F78576133FEEF95920D3B92CFA38B2547CC48B97087EC163FF9C244343F51683E8B1B7D29968A81423EB1346DDF5C4E638D796C8FFFFF6C482E47227327FB87885F52EA0840B06252E5DE252577838D869B074E6D0FEF4811866467B82121967283C2E47FF209D9E3860FC43681E0AFF54E6418443D5B3F769ADE3EF026F7E96762E1018326A0CBBAEF233996322E495DCC06693729D7C744ED8B7780161EE1277AD7C9C4B40481869AC463653E1E7F7F60AA5C352BF1F1A9CE483446F13DC6A26239A6D784B9F44DE97299ADB3CDCE3896081A7C93445C45D9ADDA1ED9FDC49E63202FA99D02B240C46DB1DABFD69AA70822333264064184BD583FC949B5134902767D003E6ED1D05581C1D6AA5AFD9A119B15F745E835CFC832011829AD48530C7C51AD17785B06748230985E77E2A2C4AC40313EF394052AF472A74044B8542261BE57136759FFCB1F42F349A464066BB4FF963D9517D4D82181B1851654B73203B16E302E7F7875067D2198E33F819270183ABC0AACAD3ADF227AA20314979F296AAE763E9934F15A6544FC5CAEBE33B6D51897ED5DD4094B377C51C931E9E62E5C05F340507C82C4E2788DC84E6B719F0C1A729AAECB019946C9DA7920DD20A7E7DF89EBA8BDC8E8EC1B03FE6ACC18E855C02408FE1EBEDB17066DBCFFDD0B1948FA53A45AB7A892C071EE692454D94453E2D5E8DC33E7B6C304154D3843C6FFACDCE3358F8D845546E2DE5C1E9641646702E6CB83AE5CBB07B35E9CD28DEE1C6CC88D8A614F262681FE0AC38B86AA792CFD0509A76928FE196ECA25D9A8A231A1DC659CB37C2D7EB3B7702443D879D6725FC633D503841F43B4EA7AE7155074B4DE876E2918339CC2BECA755F757183748F1E9FAB045C3F22DD5DC2EB5752A4EAF055F64F9BA6B3AA65EABEA3F585B72D712E40FD2B9BBF5F62ED5E9343D613A59A81B8D4172ED8837137DD07FB77C3D1B2095B9686F9ECB15E37C6C1B19267A5C0D299A1DDF368559F615733F451532554D0250D52E4C56242FDDCF6DF7F4C5E0F372B04AD24248687BF21243FFE82ADBF602204E9281C2BB4F47D5E3233A6CB0FAC7854BF4B298EAADD9242C085856126A1806D7B063C38D2D6F13CC617D22626BCDA228ACA22B798C0BBAD8D3BE108DBCF6ACAA304EC51C78BF2D06CFEFCF9B279B7677F78AE5055F77E0C8BDB8DEC635290D154F59E13DD6E45CB81BAA882A54B26D2447C8DCE935FD0A9E5EE20136C3FC643ADCD342EB901DD8A0C9A652DE28E552A73182616FD7AD0F662A465EC1D947A0442F5583811B7A921FE210DB41614A01B880C0F811BD74325967CB5361235E92C6941B4E5EFEBD38DB1F22A084C2AB64308BA1E47AA7223962DD65E7152C840AEF3B0607827B6E99F6037FFF6749A9B871ACD998F719A222F8ECFF7B060F586CA9CDD6D9ACF769DB558352F7ACA2A2CD8BCBD91915835D96F0B1770A88097C234D5D46AB064D9AC7B3A387280C9C8A16FC561A7585F6FAC747FA4091BDEB5AF963E9AC134B948FBFB32805C80FC5DA7798061D0B26CC8675E2FAD9AE52DB944FDCBCA68870B29E270D9D51A113B064FC6273CD3F86AB72CF31B20F0B72E1B964A2B2E42CB71129481AE61536DCD409B431E2859BCFA5734A47A05F149FF91181F081846D376730E4D492250DF165A2B542B39781977E96802A4AC38F450AB89EB87BC19E5F8C323F29F13394228C985DFE60A185728ED95DD62D764EDEB4F46C6D5F24EC9B105075ABECFD0A27A24D52DD0826B18F89BBFB55C27A42496F5408D283376C20807922609616B07425B4E180CC6E33BAE22186AC37E3775A6786BB6E930B928CD682632D687A2915094F520D76CD439DD125B3DE7295C5C3D1D1367C49954CD0B2B944F5CAC8CF765F39BA61B89B007CDB7D46ED1AF4ABB6E219C67534DF7AD50C422A0A34B2204633E4763A386E7235DA77CF46CD2388062028FF8832FFC74A4612886B0AE4554BFE6D82E604978101B413B5AB9478FF79B39F49ECC91FBB639DAC7A72B97B7693DC8647FB472AAB87CC9B28C0CC91AD51C557ADDB3B6D864903B98793C0E80AFE5F02A2FAD2CEDB1486BE609832DFD285D92E67D46FE19AE445F4FFD7C166EDDEA185666FCF0B4B9F75D169B440056DEF1E376B0F6166FBE07BFFB1925B69A2E85C25C7737F9FB48B87E7F66D2E1432E12BBC585E3D4E6C5ABD5E65326A67D1C944C67DCFBCBB0A017666187E71D2B1CAEDE13DB5A4576F2F0606E892B7C57296B95B009CB92137729786672E11E66CDAF1081E167B0AA0BE018711C8CF7D285359B6961CD04F79F95559801D1DFFD3AD1E712AACB0C121BAD5604C9A5B95782BFDE6F1A2DFC110579197D1C6E6686AF1CF312B95621C6B72B4A57CF8B1FC47B773EAC6392B6CE10F6ED1D9A0C2827A0B12D058FE72F99EEEE750CD4D41BD4A3D95B1B7880535F78E4942A7D83D3E2FB8C1892DAA7971E4A0092CEFC9786D69D689AD31D7AAEAD2CEFEA23E0CE14305BC745A472AE0782DD31F8F5484EB129696950B2CD00A8F401C19441FCD6A16BB2AC5A9AB36DE2B75EDFB5BFFEC0AFB37886F415D79DAFA24350BD01FE8B0824FBE6FDBF6B34DF81F0A75B5F5F87D94011014AE543B1B7F5C1F7BA542BC3F4B134E1D9EA6345339F4606D132998969FDE118BB0F305F2753D1D63EA33465199C5D04D2ED4889C19E180B68D2C5CAE8511F9C69A6539B1BC24EE28DA9C9C87D7C46887D01740262F7F2E76447C5CED2C8E23A43CF9B5A9EF603C14BF4FBF4578A1A316029B0C036D085EA7AC855516CFBC6F658923D54AD182AA66F6FC62812C49E0A209F5FCD343B1BEED407C74BD4499024DC312918B45FDDB307A8DCACE261D070F84CD26458B62D7F3E9BDCDF3946384AC7AA1C32A34A218EF6C9FF835FAE4508485D2A3F4E9C94425A5B3FF0422EC098A34CFF4583C722389ECCDED9ACC397D53985F362DBD0DD401CF830E206BC956439BAA66981F2EF63C30F9426A389CF72F144DB8FC4F7A245A7DE66F1594629FCBDD6CBF44CCAA2C4E3D45C0137F99CC69E08FF6BA2E835DEA3D9DAE61DB48E684BBAC10562B6587193DEB0E6980EAC9877A5F954E1AF915D02C8C394483DF6C8AC9840DEF57D7885E0A38E14E9D3B85EAFC94BBEC68BDF2CFE33C08CB3CB7A8530E8759D27EFE663724FAD3F23F6CB10655C0AED09BFFA78FB3C671770A2A9B928C4DA2B0852836730C1874F7A027C861A805DDCE2CA765D091ECDB3CDA874165B5B0B87A6D6B64A73A47DAC6B255AE65BBF445E1633440FFC2882D487CD30D5BE629A4DC58DF086A4C62116A64AD799E34BBC46CDE85EB71E7A7B279B6E50A13EFFB00EE7E86FB19541596D7CE82F028A26DD5C9D0D807F686492E0DD3FCEA572A1D1E544EF62C282A904803CC2C7B2CC0FF7804FA14060A1B7D8E06A61F5DC2FA43179286B4DA6EEB8065C3D6397E6CE850562DA4E614A44BF81C3442D00AC3AEBF682D5B1A9625BA462556CBDBE75CE951C3FA91F83105887C24AE3EB3ECCD05B4BF4D6C910A718C6BAAF44BE750CD008C2591638CCBA780807D02BC462B9A16967D2A5A927FD75AE048591B5CB40B3DF6F092469BB30B2939CE425A190847B904B631E08323B88E11958BC5C6FE6F97DEC18B7EB94D14089F9EFDECA3D20958780998A7DE03881BD99B7315465BE6CEDABA61F0D3935694D1FB6610E00BAD93E96ABFFBE51F653FAFD2353F3ECA0A65FE4CF7D5583A19D99CCA53C11A5E8E5450A2383C7222880062C1315D81C705F85ACCFED53B9E46DD9CC544F588BB7C7594E4EA2B7720984C23347BAEE26C015C065F732ADB6B71C772FF539D9AB8458917BFCD3D8B8F6F9A495A942DD429A91DB1BBBAA2CBFF201086B14B8104D6CD77655510EC4EB8C995B95B1939BD0602A893F631499C81B0DCF7D02293A839483BB697E7AB5B364B8A386D481648557206AF32F4C96DD05232B37536793BBCAD81B515E6E7D92B8C0173A5D8186DB189BAEE053B0DD4B4F678FDAEEFF14295C719EEAF1FE00000000000000000000000000000000000000000000000000040E161C20232A32" - }, - { - "tcId": 43, - "deferred": false, - "sk": "5B62D37A8591CFB588DA48B3B1AA1570C3491210EFCB877AE913F5C98D06C5853C78D526C61C387FC6E15BC8E612762899056F844B324E4829E5DCE6E2144804682D4F5D3CEBEFA61305B64386107BAC5022DE119038F94F656ABE41A61717532E374C1196780C888EF1F7455BF502420F61FE9EC389C1BB6B75397622374EE00AC0856130828C806CE14840D9322440B02923822D53126A0221108B988822A191D43231D82831E2C80CD4A8705B086D83B001A0A64183180681027040220D223269DB940802958C8AB6500C056E2222311C91491B9451833064D4280A112750232610CC088054222ECB344511B90063128119C04CCC942914C36114C1049B1290A414460893242316665B184262B211E330868A280CD9920504009162A4605A926C1B28100C002E1C4491C3A869C246860200050B1888588664520625A0102158409090022288A468484685C3844CD428919BA0300381300C372191B2001C086C13142ECB30710B3021840864E44465A4B061E2144184808118B70DA4161201398C0436810C2970DAA029D840600282411290898C106A19140A6394711C256D18C08DC488249A881123418DA33491CBC801D010680B865090104161B0511A15501C0104C01605D2B825E02226D1A0708B98248BA22040426A529220941080D34006D3C86458B4651C1440DB168DD1A66DA0B67108325109128A92C869833400CC842004064ED9340502132D1992800424309B260E2319105AC669481061994028C3A29163024C52462A5030221496846280250A300862B26523282922292410436C10B11001120D993884A34661830430D0100A00318589444C5C28802330884C22445148248A083223C02C442682E3C86C5A0088622224C2444C0A854554B26D18452214214898464A1886610B26205330310A9840443669C3208424380D94C62911C445528249DCA431DB4211C3824CDAB885D800655C462E238288221980D93468118441E42609601488204486623445CB02411A266DC392514C142D1AA8515CB60DCAA22819286522368D4A0630DC44491B036641C231E0064CC08430918460142670E0000CDC10624036852348819334308230458A38300095319B082D608268911868C2C2109C048D9C084120B16C82804C14C61120C071D1B850930245A48420D8142A4C302663B29103932521466023094A0A076C14012190180E901012C2B62458C809D0A004429885834010820629D0102462C624D844021C054CC43841D4082D0A498C2425600047621B90001AB78C63A228A1A229121126828820D224028344285448640A3104CC166411A52520B0205BB61052422509C62912474CCA226289261222812D4A28428888210CA9210A0965CB948518929002C56D59C04DE0C04C54360063426D62206420C8815C484511037209100C14122964008508A225C8068E80062A84C89198A411DB302613851023C6681BB54D49066041268501B970E3B005C424458C8425DBC469A2A45011914DD1064261080212C9010AB1240035658C164A10358621A38050284021196543000C03174800394108B448049571912481A4982D1CA669511090928845194642094226D4B42842800021028423294A51284DDAC690D0262401B26161C0250C8265199290A136680B0689C9B84D02948002227053386A0C08885B962899988419060490964DD8C86119370C21986D8848515CA6294C042A2208441AA93111C2905218220C454EDA1404C42488C8280C20433259C668803891DA8000249301C094089A008C53321220C468CB928D623881E30426011505C2145181488D008244A4468011C38499A090E0A425133510D14088E394000A271108C44822362D8C004D4A86512430242405818C4624C9348598882CE0B841091612204968A1C830A096108348106332068022610CC491803062082301D88045DBC82510C18C6486601909910BB3480A244A8A9870813031532881C494111A88605B828C0315022017901383641046890103668BA451223840C002458A8011A032101C35514A481091488021990CD8949148B29112282A224440C3127281920C12B889524024C3B0655C8209D104712143710A326112389213042C9B00820431000CB344DC1010E2B82859982C032602CAB00CCB843113C6200331280AC061D2848C1A4110911430D3388CDC005262C0858AC660B6B814546CB4270B543A708AC86BC1CE481601287A65C59BE8D90379B0CAA51F6D98723C5BA4787DFF8F095CE307869084EB4783EDE6ECCF369F923E9F435FBC1E5AD11B5E20159EB53B41A0596BE86945FA60133274AF288DEC348188C166BEF153321723169E4BBB7CC6CC2DBD6158374E10891EB82EC47383F1BF3A103B912FC2A929461137DC00FFBFB8D5A8884B1702D329CE3EB967FC0B1847DBBD06C3CEF44CF4EDFDD34E9671A3B51572A7510174D26968B869F044919AC6CF766250953DC9F4F3D0B28FB6D7D0F973BD3944B6ADA312044A09EC59E008EE8F92329776708916B1301D2CA52F9F571EE458AB13D13EDB882305351E3A1B41FF9BDB54D1BD5B768B7AE758EC8CAC4668582073FEA7BAE86D6ADDA4A4F582E7C4C298178DB1A5038D9D337B1AC18BE442865444D24B0D2443D6200A6C938963A812F1600D3689D8EAE1D668A7A0C2A3745CFF5484D0E1AD2B25A9A70CA3FB16D423DB83318BDA289478A5C44C5F81253AF25A7EDC4B35BD73CBDF3C621B0DF2ACB9B1D9C5A87CFF528D0C04F77A31818BB36492F3445E250712BCD2A0C2D3CC3B1BEF6AE9D1F4653EEC35E2C34F14CD872172FA46ECAA5824507EDBC63A5D5E8222308044C6A0647924F9D1B8AD7584EF56467A4531004AB4AE1D48203E032A1B83CB53C8BABC556AA6163E7DB321E71E55DE72EA992BF47E0F70C2180325559C33F6A0F9677BB801D99525CCCD1738C19DE9AA91A85146761FE773255D8B6BD41DB2515C23444463616F14459536703096F595E841B93AE455B9F37AD2E1A5710C83042689944C5C4A39F944E98C07D898C59F4BBB9DC8A4AC6F3789286D8B61382994EEE1C7581B3F2D12309FAC0A1F5B5F02D0C4978231D52D57D3D56D8F12075F4145270A3DCAA543A008F8A39D95FB555E1EE9D2C9F1FF557FB6C38BF4050B6F59C51C02203046ABFFD51745EDEE1B5BBFCF7A9BE1017839CC6A4638F4316DC6CD63009360ABB2B6B02818C542124B280E18A74BAEB9273B3F2DB8111CDA487DB87A18DFD16D380B037DDC8E60B5F1874D37F704E1A8743D51259D9A778DE571EB1962ED8A07B641B21C274BA9D1385B6406CC3D8ED00B697FEA1BD10967FE481EDD332EA30619655E0A454D58E59672293694DED52C791ED09E2BB3126EF1FF977931C0116B67C91E038FC70C382B28DFD692B1ED75A3B3753D5859A46AB0159C7F9FCB7E6CE9CB91C13A0A3D243D53956E444E7EA734724D45EDA455ECC7C3C74B2A2C4214C7D2B6B66B1BE97C7D6057EE64794EE0130001CFB597BC8B5C0C3E4D159E76F6409CD2C8D6ADA7F8BE816992B191B80FBE9835BD3EDD60CE62A79141DDEE46673B189A0F1CD0B103A66A6B42A3D9319B92761BC8A54F416AA8942E780BE5B70262426B11E3AE9EF12B3FB3BB884E3E230471C020DE7FCB92091396817AB83B9A7C40D53F580AED146CAD8C64BE7E0B5F84F0CB35A2731B710A10D784874B5CA4FAA3FFF38536890F3E48C5B6BA96BDFD22A8C02FBB2668D16AB52BF742D79ACAA94893C81C108622AF5B4B0D1DDAA009A2B1205B02D1B8F754134AC4A92E0669278A0FA2119C62F9F75763FD76CD4712D04B00042C00BD8E4DF2176918F97D83C03DAEA19FA30FDD16E1F9FE534B444C7C4A3E01C2779135D773AF35ECE0A3CA8CD3F3530760059580980DCA09DEEE0740F5D83D69DAF36A5A92D9F4096CBEECAED0816CE1326EC1804C54584E8C28355E5D00795838907B20CDCFCA4FE18C0D3D6E0DE96EC0A6C502057AF96C61A265DDD8D874E4D42289FD04F9DCDA6C270E7C53C3A2B23B20AB13AA8E3FB8B0DC77C0CD0F00B6C2FB8A36D935356E10D51A20E53739A5BDE93F96B49ADC09AEEC0B35EBFEC815880A56DF5B1D110839A9BF7946576E33C226964F6075987489DF3A7C0B574E21A219B670E074713ADCE8E401969B6D1A5D2EDE0F725C0FD829AA435EB3F4B9E689061C92008547F4AE3430B259F557E1A2DA041643FE2FDBC8E03286B50EF73D6DCEF0B9C6C75AB40F1D2F8D4CCB6725AF56A37044A3933923FC2F32378855CC0FBBC0327F25C16C59285BD19627CEDA13CE715E35A689B67DBF61C3B45C48FE507B02C4C2689ED5CA3D76418E3C2FC5269E3525A7C122A0FDD0E00CF4F960D45513C049223084BC5519B028F17F94A3B7CC1C407618935F248C3FBF0678F2A7A05E8A1911059264409A8801BBB80A3AAF8E0B6D86CFB3775F7F9AE87152371C6216947E89BA04EF44E8AC304B876028DAAFB54C3FF067029F15AE768235BAB8F854009110645AA801B2904F6939014BD76E5AA510BAB9D5AC17BBD536FC32CB2B4505A47D8679AE67DA0304E4982F03E22E77068A23B32192A24569D40356FAD23B1D79E40F17F5D2B0DF23EA437EB2371CE2C7278653A884FE38AE0CE9D9C60F97CC88E3CFE5AF1AC3A1D22079BF9FC2B42435231F110DB596581B44FA7E31265BEC9FF7C86EFAE208B898F36302B66E409184EEF82DF40FD60D6A4796C071C088BCD95E8F8AE857047BF83CA41EC4A845B48E5631F85192FB998067B0B7172E575D6671917363064C08CDFF23CA8499F240738D730DED8A79CF015FD9FF34D53A0B6BD0D1DD38B32AD0B3585FB99AEEB5C11547B8AD365269FE96CC855E3E7E5508930A639D82BD105867396D6074A6C2330A35967B1914FB52AB94F44E3DE354D8349DBC86E444B5165ED20376B11DFC9FA5F51F6069FD743804BD04222E22A79B54603AB0983530E1101227F8BFFA3A24E084D452E1DBA5B5FEFFB23B9842395658C38C7970405E17E0E8451AA188BC920887B35917159F83D7B187227B26B659D168EA4A2C8FA6330D372DEAFACD8854852F313618DC847C56832CB2A3C8029C5770F7D7D63CD3109EFD2725F24016232028CB1666DC9F407040806AE63115BFE51D2BD2D74286B205557C7F58F7EFD4755C53E2BF24F3D9F97E48ED86E2B7689B385BE82849DE6CA634963F2782436ECBD35F58EA3CEAF50A452EFB16F6072FA1E9A10B3E948E5F2959C4DDDD89921D4CB0214AF3149B7FE5E2DACBD9632720CD06B4B210350435F663C4562424927197703D7ABCF4F278C4335C623C55D8021B7A5766854DA7AC210F25A326F84E0BBDA83495D44BB923FD32AF32528A68F11C7557F4DE631DCFD8C233F473ABD54C6ACF3B3E935CD6942495FA61211CC158B7C2FEC84F923D6C4F902A8A19B46A931C68F420260A477A6C3A28B3B4133634EB5751E3A7CC46022B706BFBE01A3E062284C2D4A8758ACE690514B137FA480676B09EDDDD309D6F52F94B2D0287270CFEB1A6E663B762080ED4C4769BAE6C168CBA07AD79B1A1690C5FBE0D9A05656D4E52466C906271CB7C023A72A2F015BF869446FF35E9BC1A59E23D9928CBD1285512AECD6C904CA47F63A8747FE79AC8438D6C26F13FC4549453349441D959B66DB25037127C036AB356C8CF79F99F10BE8502734CD91CA6ED2F543F2C2D5412CB6D16DF798204510CF5A17E6E33397B38BCF4BC57546AF7824C0B4DC7D107392B97730CDC0F1528648FED45BCE3443A44BDF1B28B31FC8FD17A1B4A737CD28F927559FE2564A3018DBE808D3AB4A4440527825D2013D487293AA875E5E911510CB8B56B04099F96CA23C62E72C2156EA08B6C7CF5E45C869BD2468AFA718C7E3B73C6D02C7FEAB0AE69C233F0E46E57945C4D4EFF7796285E8988B51280323A8E89CE7BD8C068B0828CC0BEB77C0F44E28C5E75A21853AB9D8159B0E2255C5DD8F5746F924E237A4A8FA3745F5CA39814EE64E7EB1C94DC7B4A2889CFE7A01690A89285DAE12AA6CEF45805714F05BF0FFF97ED82E51842B099FAFF2F0C0F2C608FB3CB6E069D276714A21D1AEF73A870159CF5C56CEB3403D96F4AD1D413D03583985068349F73524D66760A17AAAD749931870581BA8C576FF6549661A43529A2145739AFCB3BADA0EA472AEA14986670A97FEF749F520054CDF4820C191E5D94599D95A9050CB45B6E8E5FCD28816D331F21FF06EBA6C0DDC495AB8F1BC645386AD1EC65EAC1FB4C4AA5FB8A301BCF5A04A7D61A8310804475CA128824C767426E55EED148C766181E2F2573149C2AA36496563A4497DD9244F9B17791AF92489B0BE38BB5A778E679B93BE4BEDE0C06B60A048955A0F598FB16256799ACA1CFA818863EB852A7329FD13BB9177B8653E3EB32D6C40601AC61F69FC91468737480C6C8D422755D2AC35E410D7504E07DE414A7FAD9A00CE495C84452ED9EEE7817066DF613156995D4132CBE14F1607FF63BDCE71849C7E3A20B5F728EEE14DF98C950706E97F6C2E340300431EF2A6E0FDD9B2EE45139C2DC66FC4FCF8231A86B9F498FEBCCC3E87F19DA17D09FBC476C8CDF0870775891CDF0C94411FC686FBB54C9EBB8AC22BC43AB8A72528DBED5AEDFE87CC534E3127CFB22784BDB2811B39D20C29A0FE79061A0CD54787EE228013EFA979413F8BE983F7D9EEF5508DDCFBAD3F4AF8526291A1840BBBE247969C8EA5218778571891783F16D84E517B7CC7F1A50999A23085AEA463EDFA3AC16AAE8ACF4670C69437821C57349A12F561A87218BA746065666A7B76EF92EA8ADA926BEDC8F25F809F4E747F92B7F16FAE68EA88BE10542DB5ADD7042E8B26115E2A587C5BE310684AF723C6BA4BAE47725FA641BF4C0218F5315E5B2EA0D89F0EF", - "message": "CA0104B9DF99E87474389167359968A307F63AA32F0C804A96B18FFBE00C748B1D6894CBE2B7BA06EF17B6947ECE31DDC9F614348F01995FCCE77099A0D88B2BCD1035667631991C2BCAA4C86B4D31074A2FD46C38429B52CF0BFD7CD3E5D194DF22E2B0D57C0C9D624C772B54686AC963447E716C6B4DAFC00AE383CFFC69A2F6F931D616954BC9A140D785F15C5DB28ECC793D88C78D11F8F8452046ADDD3AD26988B21BF895DC810739FA7C45A8062B2931AD363B0C7EAB4CCFAC71CDD0DA3B54CA9A6388DCBF79AF799446395DC7A5B7ED1788188E9D03EB3BF7B80F8CFB9B7F33DA0D4DBE1840B9C6C5D80F6AE64487BBFEC86C596E2ED8E721A11D783F7552A4B01FA24F60B5B683E287BD75EA0DDC15314E014D402F527C5DAD74CFC49B4D824EFA77C359B90AFF15AC89C1AA35959570E2148DF7A09E27E2FC096AB5CB306B4868AB80A24DF745DCF9EDDE57357866182A9AF50796EAF97A1A1051FFE6F9038BE1F6239CADBF0BD81B23E2991941F34D0851AFCEBC4D3F8B472D6259CF61FFDB87F79928C66E69D969B254D57541A87C692160E5D58A837A1FE90A1799758A70F958DBC1BE5D6E6836845940C75E745245FBCE59D1F83462B9578534D7A05DC3F21C34EA93ED78387B32DE09ED3CD2A51EE2B8F7387C8C2D426EAF3795E99B158D467D9A039234FDF207D65D2577D1688E1B1E72B5EB096FB6377DC8EB6B3F51900380BEA561C03D546EE242EB4264C0369AA2D53B2B190E0422FBC4CF896CD549C2A08A37070331F15A9ECFFA0E91B1FC4D5157418914308EB8C6A992B197F33DDD517DF4610E88F2E35E505BA7C7CACB8E76677CA9B39A4094EB4590F6154FAAFA76C1D95D4072B5CE01F42355C47AFE569FA80142EDB49E2ADB34D3C356F4D882A52021C5216B3678AA6A5D52C51CC8BF09E7EAEDD2501A9886FAC977EA5F385F46E8718D39073D8995D392074C2525A4ABBE228F531E6B16AD5BCD5EF5CC4C3C71AA77EAC1747E2B763D0B3D66C7F35458BE43369BAA0ABED23202B733B3C7A111F9CF407A7D62EFF5BE3A5DDC3E49AF130012BC6D5D3641EBF268236473EAB09BE87BAF7707546B7AB194D2ECF5B03A56662B1D6462898DA94747CEE9DDA08A9026538D799F163E1E771EF7EADF8833C0510104FE7AD7EE75F44F8D4572E299A87FB17429718C576B29983B50FF81F8D48D41CC764809429A7CFE05F68168B6B36FF66CD75DC0021D774D07BC716A74F9450EAD2995089FEB89D1EA73A9CEB83155ADBA737B3DE33B6B617EE7F5CB6C6672AFC439990B612A6AE71540FC6D7FF535FC88DED0E6A80A484735F63209D39F12E6E129C4ED2EDD8C8B5A24472B83A058B0F1C86B7F4C53D88927C7E9EDB5C40C5D6C7F0ED8A626C5F35E1D3981936F0F1FE4E8CEE0FC7F66F0016B14F3D1EAA993A5DB9B92C03D99C0A867FEB343D9F43BBBBBD85F58B2380811CF153FE66E5B5DD07D5A87ABCADBBD472692358777BF17AAFB622D487A100062465D9BFBE0E63B9D862A02F09E371EE820D969B29B4E6F6A1120CDA9F9E3FB804B26E2E9C3DE219044D1D6E62A28CBC90C262B76914B8929465FD901777F6F5C112D196A002A0F4C4FFAFD2578B5CAEA21452968400DAD6490E313D32A708A42F64E9CF412EC0E358F6B833EB0190C5933037202C266ABAD212B570E609FB7D338AD3F850EFDEE9347EBCFEBBBCE90E7F27372E244C3F035D4ABF1008055215E573F0C4001FFCDA5E6B6C5B29B7F59132CD86481FD0E1245EE4084DCA3D44A0C9E6B6B14E1BCBF56F470F15609DE76588795D5CB62BFC9C253EEFCC155C116D70CCF9112D8E0A801A3C640C7D16634EA02DA9DB9AC57DC2F7D43F48ABE631D3438C2BD3EC97832244E81223EEE47054878BB2472F64E9ACA0D5A8B0B04F783C5052E0ED6AFADA5274C94084621E989084EF9814128226346996CEB6FA07FB957C7432878505442FAFC4D945A953336F9C92B8ABE4E4A092DA65E2BF1A7A274E1EE9D7958E35334D9B7CF8B314F0AA5C45E93111460A8F5409C0BCB842DF9C9887FE4643BF8958CDB40EB66438BA53972E359EB712BF4C553D871ED702F74C41D1217D7887C891E49043C0826FCCEB2897BFAF9F217DC9F566DE1C416DE9118491162113E2EB56CDD4C024DCA4A33359D88CB0247BDD6802455063DE9666A4C52075359316B3B557D42B7C99700F55CABCB2B802AE4209C6B937C798433AF94159A4EC0A7DE00C809F6E6675A4213A1CE8A7099FB7FE6A0C7FB383233444B64AA120BABA1C4E61C6426001184E897A3C6B0BDCF9759A72146EF848EFA65EF09076A4FF2E6DA518C5A08F2A2A12D904C893297234E53CFFA04F285F350412456C9A13E153421D65DD30B236653AC13CCE3D5CF1EBCB8AB46808414BD3725987D6E464EB4F97321595153DBF9994F7E19AFBD19E9BE929D18563789567B28B1AF05BDB5D2C5C289FCBE8EB159D0017E09DA8FE5E9D49D3A231814778370DFE703ADABFB175859A895A6ED86F9B6B52CCDBBF936622C5E5A01D50E2B6D5730EA4588680EFCCF390211F211472F9E10314482CFB45A24706BBCA8CB515B6A9AA6EE1D2509E8F9AE9D6F545BD3971A02CC26699608FE1F076A925008AB6CA8576CC5A962326A369BDA8ACED3618F02BBC55337FAB2D66050514F904083D4386B43B6EAD553DF5603201C6D684F7156FBD2D3DDE3D7EB0D569AFD42886E57B747F21D44B88AD58FA2370FE6BF2DFA4D94D8FF983A1C2B89876E75AAE3828D1306DB9A639D052EFA6A0EFA0F61737CCC45E0C516815E92E256BA49E7853F9E9D4670593BF9402E59EE80F6CDFF8244D156FAEA8220D483601794A3CB5E1D7B60DCF991A545D2C72F62E5EA05BEAA77FA86A80400A07B97D8159F0EC170913ED885B578767CCA7A5BFB8BFDB7AC99002555145D9DF5011654700D6FBF2EC2BA609C969EBECFCC0EE346FA01B6CF07E6855F3C832BF1DB6E247448438BAEC055FD41CDBE921E5F62D93F4E7964258A9CB3991E8084BFFC2E5B29BD1E32A64E32BF5E27416CBA7FA3DFC143281F3797E1927AE9D9E07FB424833A7911C23F231D676EB0FB061C179C72FF0038E48068D43A805D56C3B6A16F5A2E5E8457F1A3E0F927A8880CD261F0D0AD8F82EF0E52E1BED003661F1D4510F7BCCE680CE84A0181F046366126A53EE67C7309C6982C28966B6CA1F324D03F5E09AEB111486C44B6551B1C36E84C2A72F78AEF5CA31AA66EDFB0792C00579C0C7C1FAE501735706CCFADE03E9A0847E498A24AC1DCBC7DB8FFC946B8D914633559B63E3031C214414BCC1921D2A53726695340648CF6C2BB4FDF132C77BC39E9CEB2E4D22EB138D807D7B79F78CD9713F5BE7512FD32E73E886DE16A9B1B19026B91EE6AB92DE4DE663D9774344B283149AF4890BFA57ABD1C9DFF128F9F169E4CECEBA0FEE1C33D4E34B877EF04DC887F7109B2BA65EF5732ED4B7C6B33131EB5867811D4A8A3536102F5AEFCACAA681A6A45A3BDCB24C4FDBF49A134244044E2B424996CF6F3C514C77EDF2AEC177B8F80A1AB77F6D3D920E508C76EB71ADFE2209A132839E9BB16BD9991A545AA0587B7594E0422647DC84CD355B20983AD582324D4F19E33E9CFA5CEDC739B26F43BBAD1F165720306F48CB15B23B961E5990C2DCC39E5BF58A9BFC10829590A7AA8F60E13EE1DBA85EF5EB9B1F6DDA891ADF7357E16CEEA4ACDC00E20F8F364AE3EA838CB4A0FDCCF8B439A242F8D18B8E0B9FB8E074922E0C25922CBEC46C98A82E93F0E95884BA9853CC738AFADA3F08BFB66C17DE7977EB7CE5495B8620B537B49D1D37EA4B3477B79759EC7D9AF17EFDB2EF89945D453BCBDB349CFC623FBDB8F125EC492CCBAF30006523B543B6A17245CDC5EE7E28EA895654A5EA74781CCB0F30343C73B4BB88CE07BD37DE9220712F11748EFACCE925626FFDD8447D37BD9CF2476437C093BA4CC0AB674E4CF9543CEA67BC25B9BD56946C0D077F0849796EFB74C7F66D5B86CD9A38B8138D816F677CE08DE6A6A911BA4DD1834751548578CEE4CFAC50C11D685E52DECB77A475FF5468C38DB23853BB2118C78AC3D52079042FB7F370B3D0406E402EFA6432D3055C572C81DD999876E8306021118BA87D5D430E4AB9C24670EAA1274ABF4BFB8149D9067C427DCC026A61C5B724CAE1858ADE366FB42CEE52C36F0F99AC02E8BDF784EBF311334B83B2B277982519DFFA3AC35D97F9F30635CC17BF8E017EC4E209EAD104B52C58E8762052CA62BA7A82FD011860E4F298D889A11F6A2BB1B4157CDA42AF9CCD0B5324329A92CB9FD6EB81DB3FC58431BC5C9A6DC1B07F7D2B00B32E5A39960C5E2CD69CA2914F23365B518ED746B27733D713E8ABEAF9D1FFC6D3D9B601FB386A6911F24CC818C0353658CB826F43FEEA792055720065601F1364BB6184699F16E3EE2B359CF0642C85E9115B18E55482356E2F91121C5884578F3D2C45462E47A3D477B3D63448A8C1679E68F9B7AE509100B7B2B142FB6BA20179E599259414520B02B745E592FD10D0D40D780A95C164D651E96A7052B69BBDA979216989A57506638F891336E2EA123303F997194B7AAB4F22CB192AB59A8BDA7CC88D0F43E4DD949146006CA3F91CF28535ED42662A61F630AD6E7319A7B98FF5C7200FECA768F14BFD43BD60DBEC814E22C26F1A8191ACC869A6BCE61991E4F36148908A5B1557A507C407D73A6FE75A548CBB8CACF13E57BA6B01FF0DF900051AE7C0C346D5DADE5F1C1BBFF967236BA5BAEF19A70FEB320BD76035F3A6B11383F13E6DCB8D1533A6529C98334A3F2A9105A5CF1C940659459C405C197130EBA44F0A2881B4614B7A0BBDAD5930DE5C3389A7349265629E29C0123CC89F3F540FE5C9019662A4383A38248F22201967D908EB48D530D17D50A08B35FCAB73AE8ADFDD72A8A7551EC28C7573E2B33EA4F61EE84C3DCA33DD5861B8FB7176C4AFBC174250D51F86B1452903191E39EF099C0CBCC15B3FB5DD30A2822F68AA37D59583BDC1CCDAB1B2E0337BF397647FEA9111A5B94C6A3369E90F3B86C266F4C11C9A7D9E24802B31B5F93B8EA9AEDC6C2944965D6B54601311D251E81C77AC1BB2159263D0A92F377F111DBC8D554C3AF747FE7E82A6E6BF0E4E3743B7AA42C3B5B8D3E5D9C3B427B3290452136E61592609826F4B61D4960B7C3784D0E2508363212AEEAE624489B739D0573CE23B35D30826182DB5F4D09772582E4D6B61938041344EA434614C21B01530327C08539A84F03275D0C4A77FDF230FBE6639CC7A12C34545C5CAD34AABF8E25D64AFCA8206948737DBA643867A146F17ABF81A926294E2368A5A2F0C381E2C244B21843E3ABBA680CC3F1F0509DFAFF4C70B68C82D3D7EF8EE053DBD154376FAAB5D561A19362314B037CFE18DD03BB817444FBF08D771A13B9D745DC066C89C10ACD53597B74916BA719F9EEEBA865252FE13EDDF97978092FDD1524CDD865FD6AE9C14329EB62B322F46905804AF1CFFC13B46B6AF4ABCB107D44DD27B460101F7A38DC786239E34CA9D1A444898673BB3DD92EE88478A3C539A563CEAF5CF499AE8E07BDAC0CD5419DEFE2977105B5E0138D84A8F9BFAD82F58884377B803C8B68164A3E678648C18127A832FA994EBEDCDE4FECE85DAFF8CD6F44F4CE57694522DC30BFC492BF62796D05A9B87BF13A7D538EE5C55E6898D50ED127E8C12F87D160AEEBD3CB126BC4144A51F685079E962DB6FDDE3BA6D0C8038BD6FD8377C4BEFC2EBF1A876833516D206C2E309C61E4CEAB5F86ED83FF20C8723BFE63D8E480798292E6EC6D418D3CEB623AC6983A3F8A3AD568F73E408F15AB88C8F56F3CCF5B32C76BDCEB1FA41357C42E1215CC503A316EA0A83FB341ED6ED20B1154E5001A754F92E97570F9DA7EA8AB7F2EFEE7B79A1DDA705645ABC5B1E04CE4F922BB03435D11FC83EB580CDFF7EDEB78F2CEBBB6053410E84477864C16D4CD7CD9D16B932372FDB99DBCCE2DC3B5CDCCF7DB86AEC9BDCB8E4F27B65ACA9A3FB985CF95C5BAE253797C8474D0C25F0FFBD151E6558E524C6E96267677EB7A3E128C918CD3B09F1DDE311401152C62B4C59EA1D408ACCC4A12A34664D7C0858D7E99A0327724AE9CA55A9322D865EFB4FBFD37FC79F8D7B2BF08B1824D44777153ED6604E05DB1FC9B1ACCE05F8C53C32594A84F32D97AE49E819029204AB7713AF2AF2C281448A34C69D5F3DC76345031D2CC05B6B26303198E182901FE65710EA95793DC8495F1995F0196DC9473B7AB922786BBC61A91868BB0BE05E2034EFFB288502DDFE2595887CCD144E98ECA4D1E0C044C642396F98473BFDEEE796530467F6B5EC0D5B79674EBDF5D1416F94A8EAC7F4833947F1DE610029779CD436729E55AE3D959F99D5438E0E4407D0A870A38AB31E08F16A06345B7BA730CCF55CF1FDA1E9D04833ADE5FD74A34E2629DCB75A3482312860404F7E75D94D7FD2C8215C6A21BD5FCAE81CF4467931A984AA24B927039526B95C2F5F39AB2040A23C76B64CD2D04E95DE6DD9B8EA849F9F7919A619EFAC498E7E3F4A70432E28B1C5DEDB08D122AE503E98D34D13A4E8A69FA267C3E20671077F977F71308D3EA1AAED5DC33B3F41E0ED981050B3B915EDA07AFD71CFD3AF13A2063813039BE85EF98706399299118D2427A7912A131DB7BA731D18DC2838A116E05C4CBC660895294A73D170C060CD83C9AA0884C5F3FE52F4891C2101997D688709F356A556CE202C571E1170BC339F3E2A75A5A13810E3A2F2133438C1705895523D03F00BBE4F4FA9BCE6D7A14517BD54E281F202BAB40DF35253961DC9E94DF5C2C5C3F0E420AC67A85BEC2ED70545B94202AACE5E58180104E42C5AA6F7F59915BEA69AC10F678D40506AD2B502D77EBE4D05CF8253B4795094F04BBDFCC8033EA131BE83F3F647D22D1212C16895F52FEA576EFB344A476D2A8EC74739BA62632C4B5B08076905BC0103CC9B2193EF6C4785685F2B3F79FC39B5ED09B258E5E9BD346557F24CB542B69A3ABE367123179879A02F941F9781935D44BCABCC563BB1F31C44BB77D5E7A4FC7EC2C11D597E7288C6088497DCC97910CFD8245A4F255CFBCB8FFF95905E8224B770E910A253356916EAF1B3277D831BEA5BD6681C6C7D57D363608EE78973B7BBBC156FE5536C963030B6BC8D306F3C1EE72F14163DE0DCD0CE741EF975A9DDA77EE386B991F3096FEC95FD394E26578269F491572B36AF42CEF1D86CDC82D63DF00AA397E1960378763F5CED239BD2A6D0EB7C5BD7CDA2228B684FA57B7FAF497310D510CD386DE6406924CD592ABB1E9753EC8BCC594ED52B70C04F7C53E19B0CB607DEBA79FABD6748A52692CDA34BB7CBF95D1ABBFF8AEF8F8AC7E5D52EF58FC79B0C7662DA90A0F737CBD42E64B648B624AB497162A7B27E41850A9BB4AF0489550773EBF1EC6742CE8D53A20921149563AA74337ED4CF1EE8685F41D36F748B6DED5F894BBC50A8DEC84621B6AAE690D6EE0B392A7266A480CF985295361B14AF0A5CEFC1EB737ED3AEA5E5894FDE80CAE477FE742395CACD1174CF2B345774BDDF71853BA1854EDC8F5CB03D33C5F58EC386ECBAC8E4209F8881473A4FFE306ED3194F455D4441D132B7685425435E58AF1F2964B657C71EB6E28FE3568183F7A0E570821EA49DECFBA3128002E77208749DCBD3F5E15453AB6DE9EB313D7445377B3BA74BD2F67AE31F560ABB628CA0DDB120CAC6CB62EC9CCC65051F70FC41BDCDF29F885FC9A558929F58CDE1200072F96C3D8F22032A0AB3F705884F0D827823FBDB62FFAA39EEBFECD9F57DA083D1ED541CF36465A999558F2299A865456C94D67E74F1EDC7166F91F4CBAC8F89E680BDED946A174E9260DD50C6B0A980A4B886850797149FCAF8871AB3080A76B645E333290A0DF319DE058981B8CFAD7A54FCD62345DFD9C3E6F7A26D212C97FA6F09866E23D5A19EB9CAE760E876B2AAF43BDF9004D5CFDC41570EABACACD4B57662087B6A91B6249CDAF905BC2B1AF5934F1A05D20E6C6784F0FFDA0A3E79A2C0939BF36C55EA0E31B1AE614D44CD413118EA165FA549026574D1549FF7D63B4C464A896C5C0E8D5569AB2B10D1DC56458FD1E069B5F91B1D084F7AE34F67ECDCBF33299B12C102F953CC48B0661AB4EFB493F7E4B2EA8F6FE59C3D5EF7D121B26B912B86BC0AE987B6A3543558F0B935AE62B4711A586DDAC9E5960C48B99CB80191B11F4053527905123D20C549457BA87608948933442CB06BEA0E73FE99E3C4198E9E7C51BBB7074DA46E752E46B3E419FAE2AD60D180303D710C0A59C6B980B24F0BFD39959368B5F56AB3845A2167F4683AA82A9613257BC801F5146CFCA857F2DF4FBEA85C54930D4373F70C083F661077567F1173819EBAA585EA3675F97951CF8C9997887BBEA9B99E17A1E0215DFC2B9A66760A277F68E747141AFE5CAB6B25D73D562B91BADDCC7938F2EA75F1C990E88311549F38FCE2C52933498B22E2810227D1EAFED4BEABCB153324622E107A6D96214F3C6D5DB91855005056A8D1BC5D5518867C373709D24DC1FCE21537C58999E26CDF4FE61ABE5E1225DE80F98D02253999F39A145FF3008F12880C173A7ADEE15025E3E186FF0C2090872A0A51505A09094FA2946AFA1840B0D6D526DEEEA95FD8E259E70B2E794C97F50E7833B165E7BEEAF5D3CAB7C3AA1CEF00003B94159F0F6DCBC74808E3FF237D5C3E94353FC0E700CAF48DA8BD94B991EFFF2DACC9E423A2AD63824CF879EF838C784C7D4C0CEE3DACF5884941BCC14E043082D382AFF598BBE0321DFE9406434DDF558EE2BDC272C2B04CBF8CEF92EF8180D0FEBD3D62E1F73F3B1E7FB0EDF9B50538D49C52CEE53F3000E581FCD7E6FEA1CEEC9DCB4876B3F1D1B1A301A2D395DEAC54D68181406D7ECA05A416D3D8E0EE10228483D8515A0F662D933C53F945B50C65C5B8D51EC45360661C92761A1F74EE06FAF8889244620DABA05593DDD4D6A82A30F34DCEF50B1B1D261CC357AB0673370A38DFEDEF3D591377CA29DF609682EFFA212092ABF84FCAD677DFAD758575CA35046467C6925B6185F9B734D5E194F5CA48DD10D0B84B7E9096703A9EEF0D3EFEFFC0F58C4D38D741F15AE766D06156B26E9C82B464C9F609F0A4FF699D52E0E11E054738476456CB81859ABE457F3595E9D7F1CFEE5D0437094CF093F468C79C093CD615F7409A505C610169010F46E148F3D264FEEA1DF42B3E78D1C4B33C92EE9BBD9C508E89BC4CE0BA0C412F75821EB54730FBB627C6C93694810CD741167D5288768165A68034CE2B16B0E73ABFBF75A905C9A9E577024EF2070EBE8A68076AE37BDF3507C7CB10EAE13D3A05BB3DA33F873F488150CE67AB892D61A11FAF5850B6A26862FF0CE85E4B0AB3EEBDC81F68BFDE39B0582185E4322404A0195BF5951BF7CDDAA6530DB0EFA0A2E6B2A9CF8DCD8B0D15447448847D1EB5FCCDC80EEDF166988D55DCF3BCE37E24A0A5F302F820C2782849E70BA47523A7AA1FF12F144148E9B5A1E05035A346FC4028BDA824B8D5FDECEC4036EB2C3A7DA612A703EFBE4D5E5E17CBCE1EBF546880C227EEE2D9CA4113D0ED61AFA70171700F0F9A1BC7CE7807A081EF09E9CEDA5DFFDDECADAA7CB5ACB2DBBE26550ED006C5B7DD89A2585EBED5995F8F76F3EF8F13B6AE77084727DC894C74268D4D91000155FDC94DEE049E54F4E4D2494EF926F23B73E60EE16CC3711B67B6F6B3A3BA6BA8CE602AE1BA87ACAD58650AA8F7F0F36AEA21080CA8DFC618AAF865B14BBD69FF7B413FFC81DC6C8BF2A7B122EC2C13DD7832610DB9E6EA0E5CACBE1703AF551997E6C51BCE7BAD4B3EB1F392EE12C5691F795090C6F1D6405D0E682F279B3DE64A9F45B1853346D8D337FF8037370CB4DBE5B241959FB8DD985A4F154470833E422AD9EAD7A14EC1CAF6308FCF7E9AAC13ACAFAAD98011148A2D52D40511CF13C7CF0ED1E320617B908BD1A6A442FAFB2E543703844B0D40FCBD1B392CDF5DAC9CE4C2CA69C8F04AA033F5D6D11DC1A5667FB352BE6BF88A9978AAD37B01BF8652A2C475E8516AE1A6E56F8CD596B9A780864ADC65A04F615ABB2BD4BA97301FB0CB7D9AB5423BB14C29030DCD5345C54D556ABB116051C04D79C81402B70AA9F32CD01B6C06FCFB416C4CB7709CEB12DF3E8BC541333C90E6D991B24D7D1D98D0839AA86614F3D91ABBEE5DF138A9DF2C0591204FEB3D9DD546305FD017B72FCA4DF01A7C1728606EDBA07EC101D7172971C9F4ACE7D6D09E06BF9E8552A4CB3ABF6FD84FD350F60A3E1826BBCBA484D4B5B284E2E1EF2A164FEDCD0D22AE77026C4A6596ABCCEBF6ACE68C11ED108BD3C", - "signature": "3F1A9B8C87C0A08481C482D90D252CBC687B25E613C6BDC311BED7FC59BCABBE5353E8094DF52017277C5EEF17A07D65A7DE47EC40E127A745EBCABE4E77AC5781ECE95BBEEDCAA01914F00B98F04A6147222843A4F9A4F4CA0DBB5C26B530DE04D304FEF6AA5F3EB1789858760CBCCD9AFECBC45E02EC93827149960F8EC0867CE9D2F2E46F6DD8AF4F959DDF9DF7177BFCD67C43CEBC559037CC88772567E6279CF261CDB891631CA68FC3B88F7A5EE03C964810E29943607F890FCD81F4AC0554EC8FD304741DAC4A0F156B66DDCDCC7D12BD563B2D54411891CA94CD44F6EB127A7BB3C0FC51A06597639C97FA4787D4C819817A8100D9463FE92ABC339426B7C57670962575B37934E890F6924F95CAF81E62D42821B1B4E669320B4DFDFD8D213C1CA405F9540D3AF7776A3265A717468685F0F3A08A22E60517C6DAADED6AD1365D90E7D91DFC8F0415810C7F98406CF0C24A583B13531B52F3F492969B198B4AFDDA5340F059D21E8F5A830E1DE4DA51E17BEBFE8BA1E3B9F6C5222BFE154516C1C1143B96A49E04DD99F56F047E781FE925171D83B3755DAD89C361CE5D4A11A7E9C37C245BC6B3315723EB2DD15DF385A108C719EBE636ECB6529D6B9D4817EB011FD6127270831A097ECDA206519842148B029A1505849118CA06FD01FCFE100B1644C44379AE47442DABC2BAE7F342ED79B26379D50C0E61A809EEF8B7EEED4B403407B44FDB7E683EE3F85881BB715266F87A96E6E3DC1FBAC1715D1581CC3691729979E97D577D8691A9AB21769AB550C258A15F4A432EDC1E18669999051A7594950EE013D95E269973762E66808BE560D9765A104D4351F118653BE7F425D0FA9D3581724604028FA8A4D35C6AE687DCC0B55C915D75E5C590366713AB78A2AEA5C1515F36651F85B2997D6027C8AD330D914F3DBDA26A1ECBD1A34125342A32B5F432ED6E8EAD0E1BC5796108F5784CAE34A3207973A13044699B496753D7CD4420A8F45D71017C2439B773771229633E08E076F1AE5092ABBE3461DE11AAFAF154587342D3CBF56939B19DEDBF0A612FD3880A5B6D2EC518BE04D81B9F183250D9EB3949EF4B7A7EEDC4021B1A4DE20AF1B5A1633A26F3D1789C1DB42F379E4E16F1C87922B095B5751F8FCD4E9415438AC7F546B1BC000927A06A4BDDD18AD62B2E829C5C2E464F178D1FD9CFFE82083FE84CD61F5AF373D10B0DD30B151BECDD8FAAB9E185EAAAD459EC55E905B56417F5AFA8024B6D5B971D3F070F5CD513E85712B171D7DAAD6A47351279D4D204E33D6479BF0747F7F895117DC9EEB22552CE829DB8AB67A44E035748BF41C5663A17A1AC141DEEA02C990858508C62BB05D8ABB8825713C954C509B67D7A56259172F25E3EDFF8EB356A818233DE470F543152FC9AB0C0F2530FAF9B1B0CE6BAFCE2FAA46DDC76FC90F6B658DAC93263CDDA34294269AFD2826B2BB6F71E1608A6232D3CDD09BD5201FC7589AF0059ECF3F0EE167289A6C7EF1F414532BC981AF7D44B1F8787C4446D9619505B11E6F60C0C861C66291952A054DFCCBCFBB0DD75C9A74B0CCB3C0AEDA3A6D1C1C1DE0E494FF26133CE52A64B397A7DCD547F88F4F327750039B2EC77AD56E4D1A793A539C0EECF501B8E8186CC5AE6DC5CCF0A14964D2CF1BB83A974780972B2AF75545B9266DB1B3E2F052E15758086BEDFC5CD42DFB3E1F2DF6DE49D9CDFCC990174F52C66993AB07E66B2658C9B430E92838E38ACDD02CB9302756EEC3CFD74D92B0D89C90281A93ED479B7A37AF9D37A47F8E04B5B261669083F97062DE23B6C52EDFEF09CCF65B8F32920E5586BDEC1634009D42EF43640C26CE938B2BB5A5E459B74ADCBACC76A2BF7712509553DBC30F9D73EFA20F95B225808F22101CF4A068D6E1C1C64EC656EE535C57785296755F757722E897A53264E63A0311A13C6E47120C3850992EC703E98AB8029B6E29EA7246882D9083989C093382551663C570012FD42DD97EB86FC434D359B85716D0084844D185A1FE8AF8C90F17510F0E1264EEF6709A2C0E9A840F49C6E7E2984241DE2A50DB152AA9D43CAC0E7C6707B55BA44D18F36E2F5F89BA46A5C1E195E0860CF5B3CFB1C4C71A0A53AA1A1A83DE888D8EB9CF7354B361EBC37DAD4F9D0F96CDD62D108DA793BBC84761C5F29F24910D736C8C9A70DD467DFCB46A53F880414CD2634C2E8AC379F2C29F52167894B6E9BB41636F93653FE4371555E061B711442BFF93D04E0AC20D7B4E92A23D1BC77387A7679C688436D34CF37132FE336FE29B57F8D792BCC76C9B4F2CF048A2C8F9B3AD2EBAD9DFEF954A55978078AD5DD59189C25411717BA0C59AD2C89C7D58C6758019B3A134EC32B8DD5A7C90DEF509DF31AC9DA19BF136DC49CC8518CBC0B193D2A8D7681A1A8A6E1B4FD96896CEB085374A81C082C3EA606C4113C85E78C7C72945EB436497E5DEF79340B64DF13AC56123980C2B4985AB0F3DC4F1AEC2CBCD47B4693AB4DBDBB270F5FA2B7BC4A69D77B96164DBD43055A930FE97296034718569D3DD151CE0440B94FE8A2656195AB1082BA64881CCB1B196BFFD86584BECC610F9751DD29B0985BAB0DDC4D0583C2A12BAADE088C6A021A437989BAC7B72709340B4BB12E6FB9BACEC05EBEADE26AEA86ABFC225121672F2687B08E8C6CD87C744C62F65AEAD52EF3063F8492CC7DB1FEF69CFA96532001430BF131064FE5B2EF71BD65FB69F2E1187B34EF659AC499FA178B969E49F494A9FE3D0B3DF5BBBEA9E852D4A9587815E199474DCD774F5A1A4922E9F403EF9A56D79BF8D20BFBD3D3296757A29EE30F3A8DAB3CD909E8A50A775EE2BF33D136DF4234E7D44A2F5A4B8EEC945C6BAE494D35D24BA70122CD9071F3F7B3B217BB4B0C1035301D4BDFA7FCABED5E223CFA7C5420376B53EB97FE945BAC67CE84DA6E9E3A6BF44DCF46B5FB35957A30E922793FC47FB59AEE2808BA559D422208180F437108128C741F181E3ED84742A122F30B420CE3063016D0B8B8EE07293DF269E5B4A427EBC108EC22FDC33BCD7F02230A49B6433BC4E981BA5C72027398085E36BF72C868D3FCCE0CB15C8AEDB801254ADDA850EE2AC97392E36084A8456626131441587F72CBFD1974C3780875EA246CE93FDBA8757591A30F00900B9B9E07A77469D03897DBB6F52F8D6ED02F77469A825BC1F1C276D75DAE5307C3A72F09825C761CF44A9F78A2085B7F339549F0905DD0413211BD3A82961C5AD4FE88B9CD776640E38434392DF1510FF9F416541502FF9C81D0B92E5F6A6265A982DDA7A457D943F05238F3EAF3EAF88A6C300F1E6F800BAD8FB08CA1EB1C5655A5ED869F3BB7DDCCE5EC591A2D19A043342D554EEDE81242A9A3F0FA55887EB621684235398C15C5AAA9962361E94C223BDAD1D69C87A684390771364A87FBB854371AD33E80AD569753A389D7496A1A7682F1265C77DF9AC5B629FB576A4C0FB7954EAC01F5A94E213D1ECA6389D8F4FF9C4B768812E675A38870729756A14A7A17EFBA62981F03BBFD55248E515BA5913B770576652CE2836471C0A831DB7ACB9CF451CAA0CBE56F6FE0C84EBC5A551FA3C68C9C444D19552697E65B7A5D9535E7A6E5B1D322CEEA4F7DBFEA175EA716E750FE8BBA057FAF26D03F83011E92672E4BF4F1336FB883CD21A2AC3AAE4D81731DB30D794B04A25CA4EF2E389C54C237B1B142987383AB6F6FD7C527E8D3886ADA4F3DA08A20F33E252BF946424F058BDD055338E9DE72068D5BE75A06A0371102C429E980233157BB1B0B5DD1DB65248A9AADB3DDEC4EC4563E6353CEB01B8991D7E9A6B8C80519CBD8B06380F61A920395E4D2AF2910184870619F5CCF4E8D4E05F81068D88834CA0C64D5B91147A876A569BA0E23D430DE76B1A0CFC70B22CF4110423328196D2083B03D5791D7D967A82FA7DCFDED446518CA4D29BFE3A9B0CDCAFBBD4C74A5AF9445721EA1798C0219E9041A2543F31D8CCE862454F0BD361FFE6BD0B95D51C777C430D78E226E124C7A0908895C78A55ED6B0E841DCB6B42C8093958699DFA5F0B82F0C94697BDF822B7A94E1607FE85A801DC9626117E3D2FA3D9D828706AD8FAF1FA130B65400A5256EF7A174953D2855BE3FF62633E0C3C533A322729D5327AA103EF255AA3FE75A173224085BF3984A9C0E1DE30D08B04FA841BB0CB0C2C3C63BB3B8BF8310673200F2881AC80A621AC51DBE999B8561164A3883F022DE646A95DF2EB6ADC8A773805A009FD8BC5F72A758A109E4C3A4841BA80F27789C29E23FDE6ECBF23DBBC3C12556BA32737A2D625045550536EDBBE859D02279DF1A8DDAB731E1B2AEBF3F84588B21D109D9351BAF83E1AC61F990C564E34768025FD6124B0D8007E5D4C0D00521684EDEB739DA51D3A793C6DB364CAD8AE59C8D479E66843204675C8A6A76193D5BD690E349A27E6E55FCE7D20BA1460DAF762A0033CC54D42F1F387DEFB6D5108A3153FB43E425471092E882A06D34A226EB259667D6C85AA63421048C17B2E4E0488F5E4038EAE9C5D4198ED477470E4E4C4D4734AA77DD93F7172009E4583857501511C9E40C6D22ACA8A16A968F3C037ABE0E31437A82150EFBBFD7251EABAD03D93B2DE6159CB2B432802054AD2615F96552AA978C8F8F5CCD0626DAE79BE0BEEC69BD34C6988F6056F4FFC5DC3989F14EA6A486BFB4ADD7DCB960D25F71EF515B024CC9898EAF414EF07744A98F0DC3C3CFC91C4BC381238DFD67A29BFC43593D3A38C245E5E2077034BA8A646202AE547115BB40A4B4CBFB7D47AA6CD628243768F2E2A4A3B47B96ACE2E8C3E23A646C129C9F8885215EF0F7D13AE8E64D613E84366653A5DF27A55D606F95B1A44C56F40BDCAA60405E1C02D42D72F391E7BED3C7455CB3A26519DB1AE24D99BE9DEC4AB2119A6F05405C026AE30FE263AE13623F9A81F746DF4A0563DB49C14BD19BFABF1FBBBCCD6B05B565D9BA16B86C1F61B24CFAAEF2EAEB52D92CBF130FF5E49D834244FB34D478BB20899FAAFDB97C8901B11E906263A3F353AA2F87D66BA6DD41337D2C1D05819BEE7D215CC2B3ECA5E0A3A3A71F7FC9845FA2751F25FD292C37EF96B0017101E3C250AF43DC4307C449069E9257BA1BDA5B823E2343A7B1AD61EEB1BE94EAC4E410D7782AE9E8A75BB54849C5764C45935C6E4B2948BC6F72C620574096D57C14508719C21B02F6F75291A669740283303DF20ADE6A5B3038E82DCB3EA9508BAA297D8E39C56E1E1F98A20D57AC893DE4C1B59DCB35F1B15D2B923CB2ECDD2D793DFD3254B4CA3F8878E04CD301A1AE8177103E2012D17314D9BA9DCE0A05FAB6A7E23740E713DDA18574C8BF8AF2D116A16BD17367D5FE9C0C6375260481AD70E31FFEC9F8B9F63E5BB0FE6A4CDEC6782A5C62779B0B1ED0956865D963F89541D0508EB31EE26ED55557687934D2DC9A1093A5ABD5D2357672578D1E914E9329BE8CC1C6ABB8F82F1A63044C3119AAB980C1659FC7CCD04041EB8749AF7222E4626A22DF729D0B878A9FC434F7AB431041EBF49963F7F283BB5CB3FD433BD75428AD445B281524CA08E5ABD1AF6DB75208F70B06036399AB66BA84A014377685275BA2672A5016CAFBEA373C6176987232967F81E97156E1057F45ECDD86FE18BC95C10B3EBC7665F879B100ACDC4989427835F9E1A778F3A1E39B4FF2BE81E9B30B4F605C4144FBD8312A879436C532A72E6308BB794A2D69B4A6ADE42EF39C484A494A624909AE942BBC0C36B0FA7EE3838459B3C829F8A636FDD8750793ECFA500D04F10E9075957EB063776CEB14048861912D60DF85E43FA2FEDA98BE9FAD55E1B5A177D82933AD17C5B5913816C90FEB8509C91BFE8199AC75D66AE907430CCAE09CB2BDFFDAF40FF4341EDD45F7EBB55DB6A8691632D06D1DF6AF6974110322BDE9ACBF7E07DA4FC7D6C6D300B4CDA1AF21CF5EF780053BC38C17D418411AB6574D4F3F5E9426014EDD74DBCE26C76A53A09C6666B399DF95307F82B98264E45A6C158C7DE95567E74D67E8AD591E296B67EA01AF48C01FF3A7141F817C9B12C2A73BAD5B36694DFBD15F7D98DB91848A373946D9A1CE2955BECC1AB0801FF4B2F00256E3F62AB684B7D5F251260454C97FF6979E8ECA36F2956876009F7FD24A4FFE9276544C40044CFFD26C7579734AEB496F4E10DB0C5664300684D5D8B84E7466A4F857560F0AA1ED6916EAAC996412B4CE27DF2D877CD899DB377276E500E89533A9B70934365850CCE9145811379B924846C45627521E34AB03366EE128EFAEC353C695A1D4F13255D1393722CC03252B814890F7281C5A4BEC52A39AE4AA2F07565BC810DB4C32606F6864618E549E496F8712D45BC2B289200776958040B6B47F8A93F341DCB375994474059F46767F34021E3F424768DDEE1D2C3F949ED5EF3D42568597E8F309171F2046B7CAF00D1F2C88B2B7BAC1EBF61B36484C71AAB9D6D94C4DE4F900000000000000000000000000000000000000000000080F10161E283135" - }, - { - "tcId": 44, - "deferred": false, - "sk": "B6A445DC4F4638D109DAAB0B266BE84079A7536E8CC0598C04202D52A38D74A2663D2C880ADA729C99379BA01136A54B662CA0448D19740139F17FCD3D713992C3545BEA8BF149CC7EF5555BA739C80A9323261BD623B40C7844CC3B513FCE137AC51138544AF6C55F90EF757EA51472036D12F01E5D7EC3109C3E04C91E4F78209808DB8285C104884884019802924A9690DA0046C3A064600631212700E22264CB008191C42552422E100671A20884A080458288511CC66411B4315BA05121232024968192069010124859202583C6881132651B991041A668091871132322CA4449DB38021338622222869AA41113A73182100C9344808C107002A429CC1251191220591800828268093711480230A4221009271010B741190941C8924000822D88842941846490322CC8B840CC000C5B28908CA85124228CC416908A228ED0C445082760C9948C53C44C40480E8198515C8864C9B6200C172692063000004ADC8271C4304A0CC9250A098043040923002899A291831266C884640205000B94859218905AB0081C81491B156A0BB8401300119334011B26050A445092100D0245091000924A168980182E14244504446A143366620849A01400A3348583904D514480C39864483446122180A2484C1488095BA400841484D2248C649425D188690BB4519C181224992823316E194320110706839809CA30850C960150464DC3962CA3A471CB462C9C448E59C230D9C40C18972008C41018C7300238921217911CC3445C025220390861482164A26911C18853C24121130544482110306DA3A4904A462D20352CCB264A03985021B3055942681117262120716288705B024888940D99A061E44091888051E0B824CC086C2140514C10449C04002236820240104A082CDAB28D8324408C007120C589E4002DD8C08C9A24045382298A328060445122204C814871830628C416099AC289CB408E4C9801E0468A2011451834240B0790CC1406412882D146311B398ED3108C12A221DBA6201908861CC5400B090053367119A27101964D1C857012A605C83232A33861403490D8C2108B122958248154224693022E484060D24672223552C8120910264913802998926519458EC81864118688423022A14232C1880420454089288644064680C28DA3C0800B078012428DDA200E1B2080A4B691D4486A5BB4004BB85161B44102B32C0440724A209023822C4C46695344219844049C367019C1111B904814C605884289DC820D50946122B591D91009CA164ED3406C0C936D4C181001C4014B8824002112CA042809146A1C920C6244842034255920458BC671E4043150948458A48811C38D9C806504C9012016521B9821D93051884081232201D3488812014CDC9221C2183120006012995104B00993824123158120960C80C02D5B062108382219C72002B10099C424C21402D4000660306E0CC32DD2383113C9840314024C06490C219040262911382182A048C222724C28898334220C2846E30802DB4442221229C326111BA808208644E41620D8400013C80D83044D20283260080401074611018683442EC31804581206132342C998901134815A44901B26415A480A8430480CC89014B7858B002CDCC061122611C1422C44363199360420A9804A04605AA285E2B431E3086251166191824D41C02990046218B270404608221381C3B03064A441412292A3B0680CB80C00256AD34686919240D88029C41681001380D1288C1182811048690100301AB5901B0406D148425BC26523B08110152543006E8C268924A28CA342701140800C0126004406D026465C882DD148914A420E9100500B02318CA8008B38521C21520934121A498640B2210C9991222308E4B0314880699A8630DB40051C41259A32049314815400529094510A396811A68083160D830001603664CCA6242182850CA7600306661AB84993208560444E51948442122AE312100C0472E2184002B921C916464C868990B42420C20D03858519A068CC34044B308943B20913236524178548B060D42662DA0642604604110070D2121013C750D148716100099A049294102C23146D9BC86C848260D0B045C430222289695BC24C1880091B322D91A408440682A410641A256582C070A380298A48285A406C62140180486E083780249284A10042808888922082C9808840160551406423B16D24896DBCAB7827992C8BB6CB1790EFE735E25FA69A53857EF72C747691D235BDAA8FFB682A2A5835AAC37E5190412ADD9E5B91DC9513D2DBB8768978D32D3743156EDD38082F2C93C1C82994969F6719035478DAC4C0CD00380FFF08A9321B2E3A14B6A4CAA808A562B0D02AD7BB4DB593B318E55DE21EA3EA6828E15F150C0780097D0C576F3295C2E27B63139127E4302D7460D6443E1D5AE1B9B5B3B806F956C78606809347647DCB91331BC57D9C81B48C480138EC80A7EB9D623850C96843D604FDAFB611EB92201771CC4AF621C4CAE9A8D0CED827C6936BCB0CEE6E82C2A097CEECFFA25C62E713C9D9AFB571E42F1145E1D618B0A1395DFFF5F07291627EA5110185EE11B1DA3EB2DA29EC38596B47A70F34430C373E3A947E8848DAF8C269049C551FB61B25C704E5B98E44B39D34448E50DA0522F290328EFAC7BF9AD912579AFE639221AAA177673AC83563770A1DA92977DF8C7AD850437F0E77DA98747DD9968E965D5C1EDB47645907F0AB59C4374C0791C60A8BF3C447017E45A9BD4F2705A9598312B5AE0DEEB5C4F9011665BA56B733A2743EFCE0C9199D575EEEF740AE78C1254CC6D486509A26711742B5022DD0FEE1F440DBFD5C71C11FABA95006FB234E648395CB8B7F047D4112E08CC773043B848811E916520056F19198904B38831ABC6DE68D5E67AE340C08C1BD05E25E6325F5D0A38523DD12731F9FB134AA252376E24EF10CD7348BF0C2859257BAB1D09AD45023CD569C8ECA23C0E8C8F9159DA852A9B09407457F3AF0714C849D649275CF166344E6CD4367812C1ADB0E11F3DFE6A28FBADCA7AFB683E47A8FEFCC018FCB4D51061C8854E07EABBEAE2E0CBEF1F8D6302230982DAF37310E9D21F84C2D660C9D3C5D09DA8777634BDDCA0A1E720B8DC8132DAE59C3CF64D7EE262B49888EDBF98602E55F5B5A3D2CAD14438EBD8752D6C93579790860D47D5EF94567359A77E56B866DD04B77A86CD4A2EE6A21A476ED56B8A750B47907D65DE6F0FAFBCCA5397F125D519669E55BC5D03445594217141ECB649B0600FC257B8327F4389ADB0D6EB9080A444713CDE66D2509D9D8AEBDB3D6743580AB42568CF6D65D4F26F494D9F12AA89E5AE3146FF08A4EDB569E77CF7E7D238AD9F5FFA5082CD024676B010B245306582999936E9CED1DC493D8DF09F553A7F4E71540F10F75339E63EF17CCD3F9E857E17FBED81485C5F21672194DB806A66E4CEE58CB4BA9CE150506A8D139B044BFC1B985235AD526445F067BB4B458DD652475CE873B16BA403F4D2357825BF8F98D45DAC29376670C925616FF8FACBE01323607017A48E6D3CD18C78505BD0FECD7934D7448B5DABFD7C48D70A21B89CABA42ACF2FCF1C3EDB44A9E9C3CBBFF2A0B11330CC5E03BF8244F04F97A1014677BEDE221EB0E5BC64A8ED93224D517D8F525340DD0E2DB0227A56A3BD803E078285BFCB40B53F2980E3004ED1284D60A604D0FD420B83638020987E42433B52A31F052E5530029FDB0F52858D41D2DD6DFB85613D7BFC3413015CF544494A4EC1F21F5DE05EBFA829FC6811544F4B38E04BE93378F981006EEB92DFD62C58F2B8E89A8FEBD5F26C58B4D638D404382CB0084AFE425F056C6CC44CECB80E2247C51C20CA4AB9451060626C594CBB3CA5B1C3506E8D52906C0B5C064D35459B1D17CDE9B0A3A55DE2DCCEA8B71D13BEB28FAE7122F8F92355E247698FD95F5B954945D4DD7A80970C443A9577BABBB8886D7E08DF0EE7CA01935F46396061B3CA9126BFAE452235B04358E9574263FF5F0E052CC87095942C556C8C03A04FF808167780CCA0F0D9DBB9656BA066ADDE5BF6BB87DDDB4BB86E7CE778BDDC9CF467D621C529947DC47740AA21E275186F4DF83EEC4126590EE026C4874D67C60CE074E0F6CC3817965BE4BAABA2D4EB77D42DF37B792DB71882F5B10980F433B9DB158DA15E5EB9587AB568256342D82C1B8BBD4366730CE414AA25F7E97E4A0D27089C3A53EB451E51484C257F65D82A7F64D72267468E45EACA3BB5180694F842723E17901D4846BD5138F2F88DAAE1C79D84AC7C24E3CB72476AADA1AD0792DC4B031FFD4A35FD3F23960CE912693C67E0A3DB404979ECEF172CF8FE7D13D03D29CE3D57CC8D1C51690791682F68AF6ADDCE013D085107BF2674580D44E88D47B052576B6769607B7C285E85F5C4A18A3EC2CDC93C7C74289F769FE703D0D66231AF23631EB88411AB57E21FA1CBE2766B1DB69A6618DF0D9E85CB0D4D0AB001B47349FE49A23AEFCF72783B6FD9AF26F5863587CFDB320376F094D5DCBD6CC32631C9C564AA6A585C7F1CF2B4FB30F8ACB2A4C433B896D1FE2236584DE464BC17D680C1D4EEF6B561BE5516911299D7C7346228A41106A3DC9E5B4E75C8F04EEBA3D36227494B22B06D578DC99F8ED068220B4C4C791F6FCC4C8D9C2B94A7B3FD9930735A00675549E648CBD338157FF5163002E99CF94171849FDE5FF7530F552AF54A95E6CA4061A6556B30FB1385621253CE70FED7BDD09872165EA8740BC1E303E34F69ADFBA16CEA146C7ECFFD12906DE24947CBA94D068DA7F51B5E854CCC6DE513405A28D9CD3E409D33B70731040A7079CC3AFC2E502B3AB1C4EF1B2D514EF445EC99A530BB049D4F8AD7F58D55FA3909F76608CC23FF704586AEE0AE9050EE5F2634767997FB39D44688E949B9C82C3B605DB878D7E51941F8D9AEB66097FA206462F5CE7F17093389800B239B86D0ABD79B66DA99FD0C65E3A3183A143FE9B45FB85AFB57F2A101C9713CE6C4DDAAD90BE6731679DE7C72AB1EAD6CA954D350B9361FD143159B45C803420AE88363C327EF31BDA33D2B869857403615F20117AE708DB5235583E06B82B9A5E7B81AEBDEF1E696FA96D76C3F6388C4D1EB88EF3F9F7A95D5B9F446AC7C27D1915717FCADA4F22458FBCAF7D4377F2E743AEFA5246E840A96F017E139125851055A1B98A91D9217207DCBEC227D23666E76BCA0266566EFD0E2D735498A2102E4D52C6FD758568CEA164E0A28B67E2E2907BA6F63CC049DE87E61771B2095C6BD2D58D4A36055FAAFB51B63C3F9BC06F3B27F5514A9663950A6804A5D34C8E1BB6C924C8BFF44BC217423C5FAEC7CD56B61B746A0AEA7C37EF6C6351969AEF292178B75DC8922DDB935717C897098CC41E150E7633C91F6091969F19525FE257268AA74015EE2AC93163799B03785E14E69A87FD0776A438C01DD829348D6FB825DE7D2B01815C115ED418E5C132074904ECF4FF06775ABA0A498B1627CF49D8ABB68D3CA440517FF4B08B0C4B4845022A2462A0C1C5B706B061F406507094311D311ED0A5184AABF03B0B0BF06C3FF55D778F280E9F3376504DCEBE4B9FA4C4A55D93D7924EF9CB5849364CAF92DC3C5E198A3D1DE5B139C13AA39E9545959D6D738C1D88288A908A1E7DC3ADB26DCBF02D9F98BFD8FD61A6A96FC4534A2D212B208C48DF6BC95BB415932AF801B5519E8647AEADE54B68539484302C9B5A416848C2F10952D1A66078997E56AEF14FA8078FC8E35E1BF3BFEE35C3D91C31B0940E8218DD83BE1E633E649712241C61DE8FDB1B84C0BA60836F95444EC81A48E591BAE36FE7CC449C9B88F6298F9E9588FAE54C40F661A6914F001A75D4BC6280E05643F0A114C2DD71EE8FBF3D7D4FCE18CB8F61A6FF8B08FA1D20378922EDDBD2175A2F2920F434919F0F9F1AD7C6ED5E0FB13EDC924410708F7973270A03604A0043AADAB8F0368871040B418E74158CC4E7358BEBCDAE696EA38ED155E3599D06F86552D9556C39F6A435770AE62878C4FCAC7E8E558BB85EDA22D0DBA818AA3A6BEB5958D05520AEB2ACFB1BD403047DF27BA63B34A42ACD3CCAB700EFF0B6906D18672340F0B6E2842E8750366885E148AE0E5546D013427ADA215A4809C11590ED8A7547131880460A3179BED70FBED4A1C304452C1AAA8B0F6C5575C2F60B6E0AE93E0D7ED699A3B039A61BD63AAED95E4822D8D55452056A266D391E444819970CFB4BB767C6613CD0C65B259DF532D58B2E086BA9A36BE37537ED0562515B6AB8AF615ADDDFCBBA355363DCCA60F5EA2B07E59174053D6F29892CEBC4A44AAA4971D19171D2029854FDD977BD357D54E8DEB4DE463F251DC566DA73AED7170C402D3F4DF466CA5BCD8BD47AD1A499B176E39F4EE2FAB9C7225A3B98700787B73CBF36C42E934D0EF96B3859F980020679FFD83F106D609278C3DD780E2E5DBC262D9DD8250D7F4A24DD27F3937382B8E7B2C3269B6CA09B522D0DBE4CE098418E95C17FF32EF99F016AD4EC8EDFB7028CA9F85ACE4976A6D11E90E2990C762E7E4845CC7C447ACA8907C94E81CD6E7664755D378030DBA0208CF039005F433083E1E904F541B036E03F7C2686630D0E5F8785FBB33E03566E8CFD19056A4E6D1D277584EB20C8727D2C79D910F12610C003F90899CB6B5231D2B3A5EEDC0355DFA7FADBA5C949E9B9274E9DC69579C10DAD85552CABF32E90870D9D0CF579348F46874BBA064E918BF4A279F55984CEA32649111EE86059406CE0B0D50E4F52C7CCF110A5E34E01C414075CF5B31AAC9F504E9499BE75CB3EC35C2C19F7794769BBF34039F4AEC85C48E772075B887B63A5C81595EB4D17F2F25912C120623439E93482032C20F7CEFB0CDE27B2799EB945DC28EEA9B94A0C4C5592", - "message": "D46F4482D570F26C7E9F0F74A354174CA145033097CED3896350DFCE8200CB9448F522B118698DAD51F6C672E1B12A412DB6B7B95CDBDAF6205DEB631E44634412F026CD95440258FE5F0C72C5F3E64FB3FD13E545DD856EC2B7F51AC28C0D5D698C66C700DD3E409BFD96E14A9DAE1677ADEF2CA2CCD178B826AAD3859E569541561073095EFCA329B5B216563D956D8B7BB918224FB479FF7025FD8168F54D14ED1FDF0B399130C6117B5645D0E8DD242C3C7AEC6A8361361CAD9A8FC3B5A40BF7E73F1BBA9AC7F5A583A5B0EB95AD0AB4C1360D0145FC2C3A9AA50186D649B72B41DB7EF392E663497B3166AF9BD0C1AE21650D6CD04DD36532AEA0FD1071D6E9554CBB575B2C1ACEA3DD4E18615FE83AA211F8AD330C78FD32D920ACB40627CA4AC80F840A64C019124079484B053F525A5403383C21B164D0C6BC1B462C0E1C269A1EA0B2438FA64934CEE47149C4EFF566D9C2234E656969C1C89A0B0A4DE124EB920FF534B934172686A18A1A269960C725940D3307B8A913D56B78A6CDCFD559FF97E225B61AFAE7F62B060E7D3E2D4040D8D9233A24827434AB4EB31B0D528CB0085953D9A1A0FFB748588A2DDEBF241F93B41F5C856159EBBBC6571AB12F4EB534ED3C624CD3F5F836A99C7E6E2FFA0369654A5C07C19D44BC9FAD96983660E4D6F95DD9C38D84DE11271D23A6158B685CF050121425AF91C6FFEFD0B2061F54CC4393F99857F3B9775F81B6526444AB705F9CB88A2D276AF2F530B646FC3D93DE7087EBC1FBC7F9A8DB3F3C8FA186F7B636CCEF99FDC4532E54F560519C94B79B1158D85BFBE23D4F36B64F8056BEE7558252DBB3D9A43748E2E6A338162F5E2BC0934E89DC79091180C93D340D3615F82E7780FABF782E5FE2B5D504F3BD1874EB5DB76CB616CC034D9B2B080319FEB8EB97F62FA4498878FF049FA97C56ACACD2414E0BEF018F25A6254448F02E64815E525AA06AEAB53969A66D453B732891E31C36679B5C0A4637611A5983F21F6D4ADA1DA5E890C909A9E968F947C686C17EC73A0F9BAE5C7BF7433133F35F22D2A0B40CC135A7591E2CD216F7D8018969940EB9A5C4BF21579C524C41AFF5DBC0E141FBD02F1BCF376DFFCFBD06F9CD4384E128CF1F03139C853CDD04DEC61EFB8F1DF1A6450E4ABDDDD8A9D85BA79479562A08CDF06BDDD2E740DE7AD9AD1016D72A649A73246E8DAE183AFCD6FBDC64B6B6B2EFDDF525F3B764CAB39BF8D617D47FD3380B4A30081AE6C3165E9437B2F37A73AFC5E596AA626FE5A32D8873712F99910DADD0DE296577D4749F88639D07F83B0F6A05B1668D8008EA749580EE5A629FC2313FAA2F8ADDB5764B242B6B595A39AD76CED4CE5BC34C580069071BED1F98CAF4BDF740A5B1DE3FD30C29DAD808537CB16D0EF22D937F297F50E1681C898375FE0374ADD6EA1B84C10261DBECCCA8E1D224A4709497CE696BCD2BC1369F4135E815A781EA26A055DEA28AFCFDEAF6AB1117085EBF6B8AA6845FD4763FF9274BFE5FC6E377B9F9DA8263DC1F3D53C83F446ABA5EEA4095AFF91F3BE30022B9BBC2C74FC52A3B15CC76F29E541A84C5BF42D499F9B5EA134E24F01E8D866FCD20B7F7A302120B13DE636F48FE8EB99F17ACC153CE4371B266CA61D13E19793CBEF12C0EBA9C728096A3DC6A6750DDB0F52E3807C22EBE4DC6B2407593A1B7BBCED799DC3EAFCE50B483818D903765A63FF572F5D4481357CD6ABD89EC260417306DA1CCF71DA568240D4FD6858BB7833B2C9C98B9E7286FA491F9E318F25D0459071848BBA0D3DB8D2BDDFCB7B8E9C64ED67B4A2B5E1E49B55C6DCBF93394010A078E6F52065AB777C7F6D831DDCC115CF316ACF3680BE8766B4E15574AA383030EDA83CA45B965836FB2374695B50472C4159CB7980FE48B58B40C6CDD2629FE3C6DE6E13ED6728FCE45024C96402B78BAF37E74A1C071F4BCC2A1B84933C872FFCD87C02DBE65438A3E770903A04DF96C569FA69828CCC32D13A0A419FCCE454F06EDE43A97CE5A9A169C6E849F075C66BAB418791778ECB2C158FC19FF5927ADFCA90BFDB3B4216E19BE11157E858610BAA373237B42F811EA97EEB93D735828B2ED092518160A2ED894BB108AD74AB0113A8D5882D99A06CE2313BEE3F902D5CE9CECC835974A47FCF6FD1648C635FE56D1B2404927C49EB53FBD625E0624D5AA04D6C0D5A082C37BD67F477850458B8672C408CEADD9A55CC268B75BC51D7B3D75668D52BB701BD980ED22CC20611EF618277B82624A1192287B46BB5C4468F94C68D96F3CA3ADED476A18BE6CCED70924139F2E16C8A54FD6C9F6695E624499AC8E9AF86A430AB856924A0899E75C1FE4A51DA0DE1588E66044B2465C04809272B2A5C8EDBCAE42B47E439FAE06938810526DDFF4B64C515787B41885BE369A31F90E2D6F6C71528412572A67DF6E155C3705929EB28B80DF15345E0E32540BA9AB7E1D1CF0C015E50C9180372C678CE6C34BDACADF45B0172A1D3082565E16938F57CE6B55D9A711CF72E362A2ABFD45B7B56D48E89A0079E973F597D2E457EFF423E229AD439C3193C264E0BF9A8A1FB50266AE4E0BB671817CAEF10A3BD43452A2FD2DCBB2481D63BB539E0C81F6986400D3A619AA92F250ADDCF661FFEDE7617162B532EE2088A87F58E1FD071F5D720FF1F72335A5B4582F1BEB3BF19DBC9D51A62CDF68A855F7F6DBBE5FEB226C9918E7FFBC8A38079E411EDB44177F843EB8CC1F73B9765A0EAD825B3C43F6760B5F03BB75DC7469701AE555C2B7037952180255612DCC9CD35DDB31F3A9218397E1924791D29C410D2E4C3F5549B7EADF75045EC78D579EA7948D121E8297BC5A3A9F7AA2E2EF5776CAE3B9CB73316170F9B48B657BBE365B352A8129130BF1E718B386AA27E493016ADA86C4B3D3D116B7252A747FD50DC14AA28676F1C25150A86C9F4547189523280A3A897F80FDBBA073EC645C9953B7F8CEC3BD08BC0CA5640545B08F728AA38A860ED38C068F0D", - "signature": "216B7639BAE886F93D92D1BCB33B6014E962751B281796AA6DB6724C8B546AB7D62CDA401D6B651C4BFDC699EC03DF4018489EA99B8BE6A2D2CE3E442AAB604A02FFA0641523F3EABC9BC8EDBF7C19CF9DDDAB6A81E4DD5EC6754DE75CD071CAF48AF49CAB50FEDD7218564A02EFB0224957FBA6115544ED19FEFC7AEDBAB4832C60B454564957C0CAFBEAB5F71F4AFCB68458A503E800D6807155E5D61D78EA973FBC45CDEE09F5503D428F547D0CEB07E42118D0537712CB2554F25F0EEBE0C5AF76F9A5E88B9966D1504B92EECFB267121F1A988EC42E675CD605D6E58CAF7E9588E7306F64C6F81BBCB0D7CEE234AD2595932E723123EA215AC877FBECAC9D096BF307F487B0C7648A678CD608FEA23162D9F6FF44DB6D953CA947EB16CB90AC9D156A8A9A60EB7781837A71FCA2F9D9835DB909368A5252C050051BD72BC5056797E866F041EE2221836D4BF341683977FC992270D3ABB95AB3665EF002467A136CE28077C9868680E4005EDD8FE15BB499DC2E95846A9266BA44ACCE9E425E6176149F17EAE5D6176651D2ABD7C1B6538A8F26AEEE04840EDD165C8114CA55D500E1B260B2F469D3AB5FB90F9E198ED5A5A7845BEC24C3DBC48B06D6D211941BF86018EE634B3CC7D060A1FC3A38662E704338A197383526D4E55F5C09B78FB7DDB9A38424130D0D9BB3487348FD9ED8D0181BA9DE43EA5B5701C5F9DE3FC88EDF84846C7733651D5653F75B7E6A5C87C4F236F64147C3361E790ECEB6E20CD2482DBE6F2CCE55437828F4F8E1AAD0307947FC33850E27FE568761AEDE63026C167830A20F247CABFD0A2AD01E5799E0D68FA5BC25F0D2F9B42A2B8411B995636D472498990C549E538101D0CD0E29A29FDD5913FAC1B40F8D9B7655B250900DAEADEB417FF471D5B52DAD310FACA606ED22E4C98868BCA788DFA0AA030EE3637B39B3AECEFFABA6B14C733E997C2130503349E6F4A5CC89431B063819DED0C718BB8F78FBF763A64B28D315B6B0B90D48F94B306F0B42A41242CF27315FC69A83DE094D2CB11FD307E1268F976FAEE2053AA41CC2CB6A8B878407076E237FCD378699F5E65856356FC9363F4202EBE78483C4B2C730DA86473CBE588356F353B7AE64AF874B824B8060EF6E4CB302AF8FB027A25606B68CC4B3803EC2FAE996E8FAF2A6D52FA226E684D1EF4E950FEC819515CE9EFFCAAF7B277C5247ACFB57DAA0812B2477B4A18683B98D2BD11143504BC181397ABCAC048989ABF0386A17B79BF73A12BCD2DF5CE96BCF5FB6904D7BFD5283DCFCBD922EC508FD8C591EDC5B34A123857EAE97FE3665B8109E4F29F5625F475199B57F425947F37069CF30017935FC68272A1B18DD7502DE0798CDDA5A0B21E0C24CC9D8CC15F1F774057E77A007BE721343DED110C56E5E80596273BC9507B392051CF19ACB15A3606C452DEB350056CEEFC12A4467813A37386B99C966FB508D0C2FD757E9C10DF490CF600DB6FB3CCEE68376BD7092C03A3F3F60DB1EDBA925FB5FF7802D9C4618E53DE0DE1D8397330D1167D63AF0545534DC5644C16E6531ECE69579013D51C7B98497100308C1750629C8DF81B45FBFAD69F37102D36308AC63AB2D78D2F711DDB691D59BF4C3483652C260CD1A7EDF1E01FFD4E5D8364C69CE247B9F0924E6BD35D358B63B18DBACC7CA1E8C786D1437A730CA2D24FCC92D59E90F4552D490D19A06E11B1AEDE338A3A8D3207688FB27D581FDFE28C42B66240B6C8F5A24D50403FA2FD34DAA370F0504A87F28A4DF44AA86AFBB6D67C9614CE5CDF5C599CDC2C6294B25B641DB59DD7D73DC21923EB8AD68EDB4D0B16B7C16F3161F7C8C0EC493FA9951251D1C5394678B656B332A9FAB7477F32BEE65407B3D2EF6EAF70C1B430B45E104142FA2EF72209FE29558485DD26BE8E1B526B7098F252F58046B6EEB17D7F0734201AD865E7A6B838980707AAC9A05DC8C34E5B36AB03CCB74570670967C3AECAA9800106ACFB0B8EB38AEF82114C2036677118317E339D19CA34BBB68B30E46DF3136481AF7EBBF8C45951C8733C0CAC97E518AEA69A41C641C14EB71D6DE67A5F7C5C77F75C98906A3E5F2A6E875E2B6D7C8BD2A54554E19616FE3E8C39FC7360749B5133650508E8254601A7B33B82C1BA537623D6DAC9C4C3006968EAF3EDB233453EC8DF00D02D022B6A552FBCE8F3694EFE49A7C6088F3080421D45DE8C2F06C312150FC0CC0DA4DD35D25E7F446932406269D45A8358CD1E2736FE2E1C366F24D5A6DC11016FE6BC73447B1562B1C021AA9BAEED212B0AC8AFC337E1CEFF1609EE3F0A7AAC747E185E3D860D1D828B6EEFB93B31C7D2386155612A9815DDD2411541D91B0F99DE4D762F69C91C527F6B5A1BBBF6C8D65E7437F0FE9CCC669EF9D1F36E6E0CC47B682449258673A02B12248FB784AA2B7F15FECC3753119AAB9F77B3C5C677EE4BD54BE29CA5722E37D744E145F9E08A8F8015BE8A56057ABADB987538C0A1E02A9DE66B7666A0F4061A4DECDC2179E3613DCFEF4AE67C66E8F6114AC74CD9464EF29BEB0830CD2E64E9E5D8B547C0DCD1D625FDBC87E8FEC987C5F5F5E3D0AF5BEB341D62789F77851BF2D7FACDF815E101F335944D6EBD0F06BBEEE92B5DA5F8F98B1F41A2463C6569834ECFDEEA395D6D26B6EEE7EA08D261970D2493B86DBEA68663C042FF7791725A58F6B062697AC0724F09660E2E630C39FB7E0568785158CE9A7EF643CB93026131A9EF900E16DBE4E5E286AF8CF89C69F75C6CB32F3BA9D3B779DEDA8BB75193DED6651F452EA9124947EE70D43BDE04965F5A64DACA8CAF2B5885FB75D1847DC07B4C631E57843EEF344FC4B7A3AF886209D77CE5841BBD664E898F939704B7AF6AAE6D55BF3243E7E85991BA8F0C40E843E50CBF16A34A4E67B0C115542D93849F3C511D977B6B916D59F2DC7FEF38542B6B24EF7D6AEA82263C02AE73BFF5DF8110BF1DED037CE296AC8AD076642EC79F76AC62A1B3637BB4F3078BF453ACB2BBD3A9F30A77D01574933E79EF3C64A316935E8B69BAF22FBCCBCB10A2AEE120FC9F15FF537E3C73F2B3E561F5F470311BA00528AC575DB40E162DC23B9BEB3BD1C916D7E83860557DA21EA6C0E55AFD0903FC9AE08011716D67EE6B879EB7395B6F791B6E946DB867F6E9B1F11EE9BFE04D6AB7F294D8CDC6055AF46AC33BDA8808785DA377DC45BF488A7257C1E7AA193438A67E3C667342FF120FA076DB4057E8AFB443C07C72610BAFF2359CA8269C1795C622B7FABACE8599D039593832B46473E8A823F79B973C67183C8ED8F9173604CBCE4F6964265B93954FE916940E540949950B72DB4EEE74C5EB386109C99537D1B0E6DA10F12977320CABCB53C47F62E89F2C275C8D310E078FF098E4D6550CB80BAF8DF93DD77E5B3D32D94E13889C2146EAC717C7FD4231406391ECBC51E9161626186D475AF3EEC30A3FF8D6458D01980BA72AF05F03DA6DFF245DF4D23D976DA87D1B92663B82EBE0DF8A104ED77BD121357160AFF118D76D5A232E92AA1FCBB93038DF7FF9319481E03B768B68804B1BFDFD0DE0E1C58CD7FAA6FAE5D0FDB51E594BE5863303216E65D27B1EBEF55B77E08B4B485576A1A8FFEE4FCF29F71783721B9A4D8BB50D26BE513CBC62C787C7DCCBF0E2601AFB6373C69FB4CF3E50F4542844A266CF19207389C833AC3A03728A4E70C5AC3B4B099482B1999550BB8A1D25DBB941B51B872422FA57DAC6035732CA3B2F30F947D7B8FC5EB53808795695A295D7BA74B558BD0175A8AD7F46CFD6BAE928DB33A9E3B7D0AD554CD8FA09088325E5620A06C824A809461C378823293E0E7CA10A0A1B345EE60780FC1559CA354126F30FDAA421DE4A3A21DE4F96D8CCAEE2E1F2F99F462470F8215A6BCEB923409CBE4CD24D37252A6950C4B12DB6F2942F547F8C646E0B5F4C1E614C5B6F8EA0E23B249ED920DB9DE3E001CCF5F99FB3B88EDF9391833B510DEFA73F26F9155909773188557E57BA3C5268B45933DF9ECC4381377F2883FA121BA0D11CA20F989E16B43BAE6FA5B0D9C74F8563CFAEA595DF4C887E7970CD883A95D9017C08838D81559A95490FAE1C3CCCA7381EFDACDDF486D158704BB8EE0D9A388487566712736FA9EC72ECCCC5F88348D39D07D38ADD76788B96716C5008717C0071C413C3618727C48D0956DDD43876B50BD63FEEBD2692A01A1494AB26EC9B76E428242973AC66E6221D7404223F8AA8DBF1075E703C7C002B67FD49BDC253D604FB7BD38E27A56B9D27E96301EFA75AA02309336AA79D83FEDA510055C21D3A167458E883D260E11ECB2FAF4468D7D648EEBBF4C48397EC3058C163B76C49729BBEF4AA88B37D9989CEEBF3FFF400A1B05860D921440B5AF5B58554E6367743CF61246302D2F0A1EE3BC26038FB52304EE8E9BE69A3E50E7076E17E2462B44F76D3EBAB9761013371436F2564B23BDACC1134499DA39C276ED99603288D6A0FB997882C3257FDFCB71304B942D77987919845437F7BF114D6FBE9992A5B38E4ECC366888A9AAEED48504AF753CB88EE458C7FCC54045D9B9165D2E052DDAEB3AE8F8633174A22231C0013135D824EFD8D4DCA97A86A46D4A64C9E046B6DBAF99C3047C06AA8C53F19283BF3D649819E8E86E749D2C74C740C0BA0251D3C77C6EC2FEB3153D09900C7198569E66D96F40B566FDCE24B09964671E1B150E2C4C587DC97D3DF2F03AF69D9F13B3A387D1FBCD8A4848D9136BAA520E4CD55D36BF78CBAB778FC8DA179B7E8FFEAC21E3A3BD2ED16F332C2A39841A825EC138BBACAA19AD846A01F15B07431DC989F3B870FD27FAE7DF63EC34319E95304CC86EE8C978DEA85A8ABD84F839F2563C7FA7D1C7198DDE5B40FFBAEE7627AF62D7F57E2DA0C08CD02A5DE110C7FC04DF6B493D4656FD03B80E86214AE5DC00D9BA1F34EC1CF95FDC16732422515CBAEA1051879B87C397B10B08BDCA1CBDA9B10A53DAD9B8A13AD05478A73E88A107C0AC73F6C4CC08E7038AD4E2C7F918CC0BCED92AD77D0CE9C7543B6BB8539D0E3B99A7C6BEBFB4F90094BE399DA1ACE5668F5752859388D796B0FDC2161EC01E64EC17FD22C52E6FA14E5D057C78CDC060A06D0B9DE3A4E46E7EFFBA743AB83C14C3CA19554B1AA7232B6724048EEB80A256C7DF100ACE744CAD137FFC541D75FBC0EC762DC9BF26CE87A52FFBC2DE6C079A50F4BCC209EF47A53D6CE5FF88E90DBA6BDDC707EB93501701CBE6263CB7CF6A6A2B69E25B23658CBC94889AEE51D6A16EADA5C84181CC35257ECC21D60D8CBAE2B46E3C69C48325E4785BEF9A119BAF392CB0469B23C75BDE002898B6896ACBCDA44744081479F99CEF23B70AAB1378AB9F98F76564D81565B380D8A994AF696ED2B317379227C28F880CF58ADD23F0D49F829C5D23865AB87A237FFF17DBD23E34E13848F5F0B4AC551D4865A50183751419B67F30E3292F96DB6821D1B788B21880B5D6F0F88C1A9098C5F07F06474B9AADD76733D329355EC6E4A4658C81D4095B8E1094BE2B1EA4D1DADD7B4877F144EA45D102AA0AE7B9962F7BC5B11CB3ED7E9DBF83BE020EBD4D733C448426E7549A5225357C0319F8A690E2FB2FFE33B73F26DCDD461BDA2EAF1CBDFCDE7CC90A5F94769DE9ECAB066CDD158E55F10C1CE3A9B3793417F85AF871AD9BFBC8B02E3A94200F2510C0E61F5DCE3638E6B87F2B299FF627F121CF8DBCC94479A2CCEA282597CD59BDE0294857C98BD6D9066741AA6E4E8BDF83E00911B1BFC947778826022F6AD5377ADF7495F483FB01D7B83C7319E08BC13E6F161A534F5337395477FB7F03B5051C90FDD486B4B6FBE0C963E9650047E32F666FC3C4F9C9B391FDB4FCCF24EC379639D65F676BD686C0030A5946F0193C11759275F23F4AA242F6BEB1BB7C6FF4176F589AAB96C1D8C2A8F73F1D87213CC2AE134DBE1A5EEDBB6155DAE672A01BB621CAD4E32507D00DBA534173F6207441E65118459303DC8510E996A854015C50CA5508B3D3E9596F242FFCDF2440AA7DA52BCDB0CBD6B9578E0CC2FDF1B880C0187E280C4E2FDE44F2365A9E858D6C5197B56588B89131387ABA1B4845E1E515B4CF3C92478B50933F3CFA42553011DB91B47B16B2151DDD6014787F7AB7DBC053AF93468DDE606965BEE41FE7ECE2EACDABBACC069E426320AA26353F6CAF896D024AD9C5C94FBADB6BC93C5579CD1D9F4CB3F195C919D985E61B56B58953BC69DD6DD3D27B7A943D6BFBD86F41334D82E9262F86FA58006DB66433F02284796DD668D27E0E6B4C97D8A6442502603CC859210CBDECA85DA3CAE4D7CF080F9AD820C6CB8B54222A71A13864754518DE2CDD0E168DA6E601AA863FE4C05B08B4FD4DEBA3508552AC014FC3D2C35D264B58871B92A5551A033E40A9ABBAF2066580EF080D2B49899411393F556583869BF11D2E7BC2FC0C263B4C7FB9D10104353B5E6D9BA4CE0613535DF50000000000000000000000000000000000000000000000070B111A1F262F34" - }, - { - "tcId": 45, - "deferred": false, - "sk": "2C242C2E0E18E6E587ABBF3FEF52D5156E92A73F58F15E88501D7F6DD793D6513627423FCBD68B62D99650E4D4859A8562B9C868E08F2836C1DE1493CBD8E24937874DDBAB2564E8B6D5EB098B1A53F1117594BCD26FCC8A464843135BCB424E6AADEFE7FCC8DD6B27A966D7408C51872CE114D58FD4DC0F31EF954B71C322B8D2106E604801D8320A54B004D480500B179144B864590245C236660C064C924042E0904514282CC34482D82245D18290E01640DB428D1B1781233360D3026C12462501230A83084E9A088D0C299019388019366081360A14266E540648934206D1A28CCC300E04352018212224334888282C4832481A1272DA86519C4289118049C2C0411B484E43082D03934081400C01333153302100116E4C402C49268ADCB28022955140240614090188A66801A60860C46DC3A20D9B129299108A8AA668D8986CD9042C1C276C0A16259C4226108569D3866422A729A0240C9AA04804428189C00802C74014C75120B24122A56509058241B451141749882411E4A22118A40CDA306591C28419442D93B481934064000729CB86898AB06920148C0841520B3412088190D2380604B380D0186561904C802045E0400801A07008250102C90D82C4081221620436088B3845CC20664190402429821A458CE430051123251B250220A16D1CA53003244C4C84410033684C984CA120520986481133249BC271513682A4808084346E60004D2194650146501044611815029102405236904A3649DA168209364E5B8889CA120800308040221104A629DA30650C2329499829A0444DC0128E0A106A019028613850820611D9020D13C190184149404430CC226989A24C99343122082004B6098320296098891C30620909880BC7650B847021A0705A928198B05012261120290D2146281930460CA80844B049C0202684C04480A611C248924C140D9C260444244D50A408C8265281B42118A22449204598B8009A9848233400A24288A2360240368044B26981A24D58101043902543B4919CB60D1C414A94902D4428228B368E64048AD4188A9818281BC830A4402A1B0308CA8611CAC405C2C69121204D208460C3180E22264653961119982000988011A51160286A23037109A584C39849E0188DC80651E3127112A88102158CD3868D50020DC8422842C809D2246EC83888DA82812101609AA28DA242651C1205C2042E08830884A26D420608D38888C8146C90C4440B076CE1824C08394618C63181046409418D0C002A231041A23482003408E32051D2C26904B249D1364943C6840AC2245802319934495C106208310C232384C1B26922B781414641E1860CC4180E2349260A094A10031103926CA2A00018130120968DE3366518176519284C50126203296841B0211B04920497116388099334448320880B444E9B000CC2A6518304650428205146898812444BA68C54882409088454400C8BC20D1395915C260918328552204D91B0442029299C920022208662C6810C95291A466C9AC871A1B02D2049098A123118A20C9B322E5388518B387211820109022010390019337249C04113305061046410094420C568C1C48CA3C2489A342D9AA460CC326E4C30450AC90193462ADC025151268444000993A08100C784D80262510206A4046EE4A6481C29609808319328215A289283222524378449B66D64C4450C179101B54191226582824804A024018329D2004593A64064202513B42510200D4C8410DB901099466ADCB845CB46114B208210802DDCA28821A88921920500000AE4A84810B66D18A269E484814434728A244E82322204C270010324E234504C428111220600460101218A20274D1A39259442098C1405CC8660A2B84802300D093490D3080A0080688A2029123008D49891CA48828A82411C002120460CC0B8214232818C482A9308800C928C89082920266419116210454E61104CA0348AE02404A38410D9007080104CD2464921B304C4B02C9BA80583304D8094711221506420925B244944C49023207243202593C60521234243B04901232E5CC60CD3460252C669A0A04D193809101130C9466D5B324A09230A4B168522056612B97004C96C08178D13916CC232001C469082143183220418A76D40C4415C1001C8180EA0A684E2A2411128918B02450CA6098AC48C5A0890A1A801C1428E04B041803452D9A22152B86CFEEC2BACC5DD2E71A2B1C8A14D54A95430380F6D2F08A08E638EA94C74186CCEC154CE3B78A6B0E275C08A5979473509BB06EE8FA6A81AC2995E8373933A5BE90E0BCCB82D192BD1847A7319F3D61D040C12327370BF046773DFBDA9943C3B35CBEA6AA0FAFF2CCCA040BF38616ADF6EBD43D5DBAE2929DA15E0E26EEE338FDBF503D5F6681692C199A67F29A5938CF32E69EE7516B0C57F73C8C4C686B2AAF8350FD84FBA13AB611DBAD7728353276B0DFC78022BEAA249E4EB008447EE55C47492F6ADB6FA22CA3F924CDD0D2AFD8E4C5427DAA832192A3E36EF85808836AB4FEA9E5544461625A956CBC30B086D0FEBF21609361E0E690563DD39BEA5FF7138726AF93D868FAC9FED7866EF2AF190F7D3173ED949A76152993DBC8FBF3DE466A0C56E0AE069B8666F02EB5D7146718769DD2481E3BEF3E5F54B9F900AE8533090C904CB08633CBDB01054D6267954A315BF0BF748824BD7865DDF8C70A6BC0B47D4667C059F75C758AE56DC9939AFC7D71C2F7D12C4AD0BAF3CCDE9BDF0ACF2739FB0311BBD22B3D62381C64C9337EC0A735B7A02EE3E92939F63ED1A290F3D4A495682A3804C3587855610D2DBA663FB73E220952B6C1C4024E4A9163C853C4686C508B600C6022A4CD7793DF69F3F323807E4623302FF751ED61877221FC25D763A18574F1E0D11ECD755E6883318187D621932E0B30627E023CB5EB88C50D8642D1EAEC03F8FA7FC0179F602AB147522F818B993EF6938C02834E8D328B88D304CE8BDD502045888D337FE490CDF2AAC5237CFAFC3308DDE202F593FE3816B95561BD774F25A7EB0E302D08443D100C28B9EDA8995E5FD9C739D348C01FBE2A4DAD5038C052549010A8C8BC4CE40D76DB2CEA946775C5E46938AB65199ED491FF7F57956AC842C4EEA2A19F50E13FCC7F7A5B71247FB7C6B58F1B244EA25472321ED86A5498F914B243C135C8438E26859063201205901F45ECACDC37105ECA9606164D44A6EB2C9E26FD0017E7B6669C08BEFE43EA0F0A737D2A2F375B21E076BE884689477DE6507211BF8C34BD92D54738E7A41F33332B33E6655B66E4EBF48E415F6D6724272A232F85F59AA9B58F3B2E6F43DA613AF54872105FD116F4E24AB77DAA2D91994B45F89B7B79454A0FA77F1B369BFBBAA873D7DDE82562854CC987B45B3AA38B746F05E30301DE0B9E799B4976446D8D08469F00E9D64EE9D7A38854D9C9A6E6A747E77A9D2C526E6FF2678920B8F35C80BF488A87CE9053DDBF829E409A5375A4DFE0AFCB9D3D4CD8555E66E8FDE5438C234A579C631C7190D875EC6FAB628374018A31DB01795761401B45DE5744F86AD954474DD783B37E4942F5D90364DFE365A38F0566322743313F3E75299635E70B7C02EF7A1D36CAAAB4556C26AABC654E9BC194DE867C3DD89F8EFD710ED04AD115F5EF4E11BE33B67EC709DFE2D4ED3BB257624C463DBB5B24F0653ABF18736C6275E716A474F2E48271A5623F80F89EDFED811E5D0F807B3112B53D3E8D8BA71B7AE531A005B1A1BE3CBB87931E7DF937B2A78AEDC30E9543156074434F390BCD8DC83C43F7858750AC113F360DC1B73C7BC3D61BFEB2BA1D417E2A4774A166F3AE220417EA7DF29CC53ED50A1477EB003D3C00F95EEFBAD9D0EEA92AAC088AF47A94D847F79C5E43D999AA75728C9D80A0BEA59AC3407F1E41A0D46ADF15E51AB89A43056B1F578B31FD389C29936246266B7CA17706BBD0DC7678B26C199ED792E0D8488C5E79625018CD65564A77E6A9CD9838F066E431C312E17769875CAD6B77829E39D42A7A0AC220BFE22987D8FB3FABD9955F94965DCE2F5E534D87A1C2CE9962A6B346953651240A005E6D7A3919DDC1F34BF3AEDFF39FA895C842D33BC9B3C86636516F6ACD063FF512121E4F175F4E3F7C5E3449E6CACE385E05814F0B80831757A93C2C680F5682D0441892CB440BD50443F2EB3DDC6C76AFE8919D0DA754FA617F4BB3F07375AFD8BCC6D06E7249D6EABAE6F46226CF9FA61AAEDA3C85E16835E65556131B103B7CFD32FC1BDA2685951418FEE53FE2D0E13452E912F5E53812642DEEE6043C1390D8290D01EFBCD6E49C860BA552F993902277EA1A1C276005504FE5FAA377D4BAE7A41EEBF2EE689A7176E64D3627C8E01BECBE180629F63625D070697F6140F175CB4D61CFD527D3205BDDC38C2E5E3CA1C64C8F3023B172EBDC9C43B228E521584EC2319567DF0736A2262F1E4987981494AB775856D9E382B6A011B61F1FA4C14F4A063D725D5EB1059C3B10DD8108A689268B5A29780BB72499D758D70ED2548879F3223D410F098127179B3F8AFDEBB8C92E7E2E9F5BC3CA594752DAA602179E25524550D55CE8EC4B819B54CED54AAFB27231FF1FBE701CADF649B4CAAB181F786DCCB6B6F9448CCB080F47B58FB209B135B96B34A95A0F29AD629315205EAA1510BDCE86F3588E981FAEBC2476040B2A255917347FEF6BD984163360DC13BFA71642715CB6D75E3B06EF05823F827591236ADF211FD12EA3E9EDF7C33B95266BB4909EDA767B4312DDF1085E3E687E2A5210CAD2F1BFCBBF9D1098D4843B16597D914F2D17807D4743ED9530FBFE3010D834A552146A928B5142C427131EE73E8C1AEF179E70A05B1214BEFC391287E1D2F63F8FF12A5440129FD97B11FB4263CB92E54DACBB6B692CFC93ABA5D281DA468B81A607EED89B02312607648D35767DD52A031FDDC3787660DC772A3B1CD888AE7775E10A483AB1815C6CC07F7C4D959594B2B81010153D242AC9E9E77A4CD4A14A6F2E2A193EF320AD28F718745E3B68B32B97492D1D690C7494430F24EBF7DB4F1F18F94546DAAEB9CF43A2695D420582EA5413A57E2E03C6A276CF2A6E65CAE1D338E3945BCE4477BB8A702F584EB5DFC68EEAA082950878AD334F63FB91107D7763651622179C732B067E1C31B8A48559CB70FF7C31A7BA0A75671882D8831A925289E394C8CBF0AB0D001ACDA20D010CF4FDE387995D4151EB77309B7A6B6A1BDAB20113803046A48AE6D94F0C5CCEEE406315B4CA43D5418777E3C76DDA4F2E7C7A987977107E26F15238220BEB5EC511E749A6296C81DB3442C6E404E085232FF5B412357081251321337770C376F6919FE30C25EEEC062CA4EBE571D81B2A8E5E531971B7EA917C739B81658BD70F00A7A0F19C2CFBA5F2880CF9A311E4E67B3C54C0652D0834C3CA7924DCD9B82AB4A4B3B2FCF87409E547FAF41F40B95D7310CA5ED638E1CBCEDEE449934B222F189D19A653D9FFF4C567EFB366D614AEB8B4B885E401285154BCFD9D3207F166962C25475184B432837E698C4E4F6E7683485291B1E24A0D8A7F3316425BEA502F4DC9D9B4ED205699C92BAD86AB07D6F94A07D9DFF43F6AB0048942DAD6007DCC146DFF6B54DF61A21C77DC01E1F5C06E8B0C72C72DE39ED01F215F7C2A4D8DC15EDF2C26A7D5EF41876DCA11690032A756CB240AEBF823052E450415A957970947536D08A4481FE2D59507CC1A875F3DB2A1503CAB2E10D47AE301B86EE4872DBB814CBF04A536771EE820590434D066CBA98F05E04F067C12C5E04215CD68260383BDCC210C6CF84518BD630C2690193D69BEA8EE69ED4B1743B5F9E9AF874B37B6890E6A0A7DD660F4701E726D323A77A324F80CBF3800AC10A4CEC4AE1C67C65F5AA31E141DC3B4BEA82333F8A75417BDBB8590BAFC66384574DE632740E5DD2B393A4DAD98AA275D14751B7E0CDD81A651403F6B8BE9ADB0B5E6B1E02EAF0A6C0D9AD0CB7D2A3044872B124CC826834427951C48AF0C81488C046F7668528C7F53A322A9285C93F9B2E15D1A988B213827BC607FA79F6136D4A17BA580D4F16ACECFFF037B8C692B32818F5943479121189D2C8BF01674172B7A709E798FB5D903BBF93827887328865FBB40F247EC85D953714315EE33DA40BD74C0BD805E0C3A180FB5D039493730698178BEA7E4E7B1DDF9017835D8F00D5AB81B9F4C81199C5672E54F0FB9A81004F4E7C3FDD51F5852F72ED8F7003718178657A1688200375E419B47021221F6C0DFE0670DB8D6A9094C9D74A1C335E394809ADB6C101CB7A6FF49B894BCAC5AF8F5B866AB8BD50213A2D43F4FB1606AB30642546D071F38AE5DBFC348A8C8B9B606D493FB6A4B0E3833A52CE308C5E0E659292DD69BAFCC5FC8BD480A53306E9CB8CE71FFA1EB96791A18DBC6FB1DE53A3CD50E70225D1E5A386226F3A83D0630DEB8BC954DFA6569FDA606C51150D741B017BEC309E7B6BAB57367DE8CE7526F19C2FE78BBD4091E7419BBF7CFD94606B6C89FC9ACFA3D8D9E1A404CD93CE933A45A920AED24562CBEDB34D3C117361E7ECFF847D61BD8B46E351569B2561BA7EF25E4C9B2BF562A0A97B1105B8664F6F5408D4109632F23862267867E41CE805A1CAB1226CBE7535D1C7A155D03F3885BB1077E8013EB8B685291CF3355FDBD2F1DB43FD6D8E33320BEC59C6C7AB34FFAACDB152CC01899713AA5B6EC98743F8BEBE45A095B0C67F1FCA064C6727A509C79F2FD46F91972D17B52A192186F7F1E6E58654EE8585D2DAEA8CAE2E8900C598A8AB10B56D66A34020D291F21A8A41AFAC85BB5FB10F10B991F772CBA37F7786DE37172ACFA8EBE6C57DCE0A8DF0C44FA5968E2295B5154922C142CA5E2B7B45CD102D33C260D6CCF0DFEF41C26070", - "message": "78A2B7A4C8441C36E0A9831F65D41773FE6B81B3FA6259A320AB03D460D7E38F4AAB2B93C6142FB0F9584E4D47074670B07F3CC4513675A4367EB8F7F4168F2EF7CA26AC45C8F23B2FD3E970068F21D9A3F7EAF005DB5A7157715CB94F5E83E3C955DD68E0EA689B6F419FACA7CD159237085678FA5883D5330796AD64627CCE7F913D1C2259E1F970E44988B08E78ED1EC01CCC2D0274067100C1C1E3D880B9CA4F3A1FBB345354D4837A6E5FF4D5F5C87985E51C471EB9B0F85075ADB57DEB53A87D85834167A4A538134CBC24FEC2756F7760C3D46248D5BD6022D8F88CE7D037935DB74A6440DA49B97E8FF376101B296E3A9D4D22E70634CFE88142EE5FB6A33F323519EBE3A915AEE5BB687DA4A5E264C657438B0F6AC977A22D0E56882F74E70D981CF37FF0C57D285D8CB07ED7FDF6D7CB1DD39EB0D84F2999DBA9273E0B716CE754A29CBA2FE32BE13BE8B9F2117DD7359494A0E0CE623AB9ADAFD3F15F644545A39055D42C6C5FBDB46D121308D649AF9B86A350B70F77A977C8268FA1E04F4EFBC2C95A2D72BC37E558F0460BB281D33F75D2AEB240086CEB8246E8A44416A5B31EC58AAA88246D355591BF7C622CBEB1CAD3B785026CC04C73E352DFF28D77186CA93870339E132D57B11F0154E0CED426DB31BB2E125C5635BD489B52C5E77593145D3100E48CFC8FE6975FC3F60ABC7FA4A4D9030A2CCADA3854BF9AA213EF11E2F85E9D4E79CBB434C65ADC378F8A7DE33E66B4F8588B73FA7F79AF4130554173975280879FBE0A59D25B969FC45AB20401CBF85463A83578E63D0C8324878F5CFAA191428E7EAE37BB17A18D0459378CFDD4C8C0B23B1429950F054DF5C67174E99AF9FCE6B0D8C98BAA9078D2CA87EB8A014995FB79F7F49D78F2674839E14C8F74588B45C28E4769C439A930B2A187764D87D71200E841263EBF74F7428EC554C12A7352FD3912D95C96E4BB1D325DECEAA9D6FE360DBAE7AB897ED467A300A8F4C6630F8E721F24860D1FBBCFEDAFBD94DC9B4237B91B243A01C41D5E98E67B52B4A8CDF0F1C985EC0EB85131F5E970A6DD6D4E1F525D9D94530157F70B333F5E50B1B95D569A012ABA959456AF773B59BC2891D745CC036D06238AF3F34081A20F00A831422CCF6E4593EB56CAA3B7DDF44B388CD54E5EF9E3FB8A260847BEA5EB5FF9665530A4F4B56726A4C5E669904A933AB1E56C020967FE61E72185D56B38B03D343302712FFC1DF9D857C6F744E3ABABDEB3F65628932D69C65FA112AE3F7D6ABD2B4C3CF572EDA73C959637D0C5C188343415E9A26E698170F8E31CA45A8E6E8E96BD066BDFDFF49C98C491149D61AA7C456D3DAE0C017A32B81CD5668A400127ABD4316F3DCEA171C3F6A3E99B398CCD4AA7E45BB51963C82C43398050B8923CAE2D4E2A2FF5232AC8F2C770C9A775F29C261E1C7DAF54F9FF606560F869638B666C90112B29F469C3620B0912622892A432EAB443F8A93E3E7953235EE78CD3FCDAD3F1391A2487DA621526EE92735284C347853D5F65395ECA2B50B0CFCBD988F99C86B5AC56ECB82813A93208096ACA04F22AC015CD9860889E9006DDAFEE0B472FF7FC3D5677EE089B0AF7C6C2FD5A322D60BED621B8F099C30C2344F453320B6FF405639CF764B101E1CDBD312495C2D4FB30E2FA7B3C345B9935BB28EFEA69C829EB57BF2E2E5E42B8515DED4C32F9C84C33DEBDFB345A4BC592CA56A769533FBA0A631D5D0E07DAEEDD2FD588FAEE648B6391422924D28D08B4CE36084C20E827E6E73A97852BDD7508E1CDC1630094C9D3A2C8517A25A244FBA388EC7DE2CFABF139888EB7372E2BE3BC4FC71788AC3CBBB3EA1CCBD9616E76F2CEB356C13257A8E5490F3C4F7DBEBF942BDB941937C956DFADAF3A78903B49C5DE34F5EDBF0E98E3E04E51021B686325955C14AA335427C4A116CFCB3B89349B1258B8E0E354F13F86C86E5E8EF8F57D7B7501C5D75B1D9615D942B04E1FAC4EACE0FA10E6DE9B9721EB0651EB3C9DE4C61EEAE7D7E17C0D699EBF7EEB122B8C1A599A2CDCBB9B665DD9A653698735D5572EC379ACC6A8470CD7CC8245F871C83E6FD92111F5128A9797AE802889E4362104775CDB69FCF37AAC22EE4532FD0B5ACFDC4DBD56D9CE8B9EE2A8B923F42FC512B54204CB971BBC9677EBC49D287A3F68A31DB8AA49D6477B287285B88AF298E68C6EAC3C73FDEC94F7062D204AB310686144168C155281627F78C883AFB49DA50C0F5139E2A0ACB9A9CEFCCA39C6F4F0F5356D2898A4F5DEA78FDD20B79662F4D066E73EA4069DCE6CAE300B3028F15C98801912A86E0CF34DF53F7F6E1868DAD92DF22A238C710F471596A49843D3E60E4C381F713C21C3910ACB1515E5E30252C94F040F00A9D1A08A4FCA329DFE190B5464521BBAA32932022BCC5E119A96DFC941965CDF3B739F53DA156553C6BCD72927B07CC3CC945FABE44B7348257A9FB41EF85AD5423304E016E74E03D5164D9F15838C3A4BFDC29C6B9F134054B53B29183A6A145CECACB3EAC7C18E31CB4BF78BC8FE60A3B8EF880CB6C1EFE7EFA8D77580CE200ED96713E32FF23B86CF532D8EFA2FFC8DB1A9E65A78EDC30090E3DC02475D84F8D9F2BBC48B114C9E4A01FA79C17FCACCAB1FD304C7F901942B9EF57C918588C9CCEF0DC5FCA7AC84ADAD547982EF9E855F6E88D02751E8E7B8B76C3796F94C9F7B7C6860042A3A33EFFA55AFE1B94C97D68B76DD240346355012F036DA9C7E025C3633CE867510D54CACD36D8638FAA8EE47D315FCA9D5AE4BEFD6150086DFC368DCE8DC623ADEAAA07287F9B291252628F1BDBA5FE6DE45129509651FB048D3A686FFAC5F2299AB0133FCDBEEE8445555F5C649598649678847FFFCE6E0DD9C4E75E2F6E77B1CEE3A1740A94E678C1191EF46FC4D9648887DE6277B11D4C242DC4A427AFAD5459BF213E0A20EC74EB0C210D0A922B9E690EFDCCC2C160E011AB94F709C174F22629969B6332738654A133E8A13EF7C914CE75ACA1C37DE05A84708DA741161EE4D23C025B405CDEBBAF9040A1CB7492294C381FD069C4622BE1EBB0113F25F4E1D5A415C121055CDE5616662599C2364481BCDD35F7E498E80D2350AD3B34C205C5EA73F1B923E6197E07C502BC6F4F4288EB46013BBACC49A5DEE5071ECAE62B192294E904BF3FD7BE08F0C43E3EC6E23A7F68115FEB285AD388A0F8FB94126EDC0331834179C1F10CA5EC54159FC256D7E0AB3129B22E5AA5D662C6A03C7D9A6D066400859EC2D5B091C37E35DE31365F5125793E7F653013C722045F7292C014123246D611A7FD59E9B09EF24221C7EAB249330C91BC9F4D3A223D9C2CBF7130C5C057961BE89894221AFB1EB27A4604BE310EE3C395E479D852CEBA4C2F74D4DF416C8836861BC13D0692863667AFF8EC89BB9194407222589E1C27B9D59AC49131765273228E79C2933445B83D07E48A789FD6E406064593EFBAC4FFEE64614C5AB34E5C2A717C50AFA79A96161203531C161E46D71F447FD28CE4AEEF197A3DCA6BCA306AF09086D6BDF35A861820C469A40958923BA824F3A95CCAF8531E930210BE46D66CF7156EA0728F3448292F47ECF20DAC7C5E78A2A0AD5215FF37594D37A2AF4778B15BB1B5C4E0A44AD5910B62CA3FAC5BCAA4CFF5BF97C8B8CB239126CA09E92492121C9E6977111E6E5248661AD122C87007318BD3D98ADDFA1B2CD60F12AD1E072643FCF82C630C2093CF4A75B2D3F809A0496727E04AD60F14CADC7331B23D9CBE28EEC92C68C97E597C2EBF99F2B", - "signature": "9DD91BA5CCF4431DF756B1D23F47C0CCF24F869A2935340E59CD015E04D6F524A0F40C05247F5C8E4E0EC6DC0237B948D25679FB1BEF9435F248A20B4C2449409FC6E7AB855DE8F42423C83192DFE5EAEAE504ED4A490BC1FA3A84E66EB522327AB8741605348BE8C74040FAAF4F4B63D17B2157C3B216F20774412B70ECB568968BCDA52B6D3823DA6126FCDAC3837395CB0A22A6F4C704828ACF0E0B48A29400973B9C3567A0B4C0453F875A3DC82ACDDA5106895EB2B7AC33CD2982B1407E0259EB05E0DF60EC4AFC471D9FF5A4FADBDFD82FDEC3A3832A8F2A0776D650620B1DC4BBA31CD1EA10A93AC38DA5E22D9A0BA83FDB8C8E0F1C5751A11866E5C3E7BE5FB2147D7F67FAE52278BB4FF1486CD3BBA2FCD0544C71C1A5717AAAF6D1BD279CD97530BB1BE3D692CEE23A0069138D1F7AEB88C6A7A136763C132CE5C6F036E703D91FD76F3BC200656B61912576CD729540616FC49754E3371624137E39346BCD74990099A20A32FC20E7C2A8E23A3C0B3FE200F0402B2F79B825B3636C4746A283DBA0072B8D77CFE67B9EBC45350FD96B6F8C94247F98B90645A06166029C4B8F44DC998C0FA8DC5A0915CBC0EC139DCF1C75FCC68FA18DC365A198F46FD5B6C6FB69C9CF6D57586A0586511A16E4E1F94474337D31F97AF17C49E2283BC610F65E3AAEA08FC8DBAAE8A7D5D9573C46EF3445E46207536F57B7D69D5D0B61FEC95C883288EBFDD33947145FBA259B9C2947F7B837113303CA88DB7E0B8945F0ED413658CB0B1A200991D28D69D138A096803D964F2BE8E4BA04705F5F7E8F805871B7CBA8953B24DAFB9C1E25C272430B7F514DFAFE7A5194186AD8FD464015E09BE097F257DAEEDBE5CAC479E517A011E7059CE0FF415B42524F7CFEB49A5EBC68B0A44E54AFD136CB6EE143A2C6E8001FFFCA92AA4EF2579DCC06BA93A921DC261003C6CFBBFE4A8FFE70442C5652137FFB849B383022702FBF3A6197E13996C323D385234089234634777A9CED6A9E97DE805E78FEE580BCE6EB074B1174952608E05EFA173EAE7E929DDDBDB68985040775946BD70223D404E427ECD91188AA0632BF107EFD0A7296C4E100DBDB8EAB415181A4C12B43BAF42EF14A6B6ED171CFF05F96F919C0A5AADF18CE68381571250E59630C0D0967CE8B90FC4E075F03CAFD851EC009630001034D81B1CF2CD864D6CE6B4741B056E1E3769C34E82296B4B856B8523E5372DECD8FF62E289EDEB8368280D74239FF203BD4EE9A1D05438BF325408E199D28980DC8D3847B412D0CA652E419DCE0C42ADB52E5F33691304C0CA16551A4224E9ABABCEC514E0D183230937ACAA3125688F7F47EF9FC7BAD92DAFEB157EF880DDCB4BD1E1F8AB5E88641B1C087EE49824C2EFE263F149D353DF8FDB8B784438E74A17180A66792E02D84F1E7BAD76DAE2C5EA63E76C31CDEF083524912C73430C21E2A8E04509621A612FDD5DAD1213424FDC2518D116E93795F726210AA627AFCCFA7CFE3E563C5B97E5B0C276001325A13211EDDBB19017A0E8F0DAB523B5ACDD88D4FBA45CEA00ABD38FCFB98910A3330438BE4944EDDF55C9F2A3AB31406A26392340BD9907F1CBFFF78B320B1F9DF7150B215401B65DD46EF1A5912EEDD90ADD53F43E44FA8AC1BF010BC5130DFE9229FC93F36E4121D0E2767A88591001408D60C8507AC3315C74B72AD9CA05CA4CE9B81DF98771693A6CA084F8FDA0BD556FBB15F76D179494892EEEA3F961EC47BFA0826CC936451E66224045C82ABF55875F02658C82AED63E486941D37144E1CF3386844E2CA24C469B4344775C0A59FD2CE6091F575A260260395C52B3CBB0E65F5C3C540A8F9F8438370B57435A1F2FB465C66797B0B03F874FDEA6700C0831A18A7B50AA7B18D424BFA9887B3AC955E97C80FE176DB27EFB6E8FF0BD4172EB49D984B12A210C30F5D4A6AA3B28460EF2A32F8AE7D057D76E7A111F8CB2116F266F3070EDA1BC98AA52BE181903C2882F4739DAA06C21B4031A732375FBF23BC51A4E9695118113723BB1BB1C351E8D72D9A847A434467B90ABA082556980B92A146BCD3E13D9BEE551C14863AEE87CB56F7002BFF857AC9BC5E2156CCCE21724DB781179564290392CB47CB3148844F3159246F39665B69CE6F52316D0AFDBECBF8BF2B2A5F9CE79821B2E7471E97748D190268E8BCBEFDADE82F3D5C8F75768269EC41A4648C5BC86B267E680156D41163BF787278F3BBD9BD2AD483CEEBB9624FE531F76906C12AD16D151FB4AD5F08BD277C2B55650A86C060D38EF3C54DBAE10B65345BDC4CAC61376A5D052ED0D930E6BD8E9F4C08F257AE7D2ED672E82DD8FEBE17CAE8F3829D353638B2B104D49B7A7E62DA46C642CC3646CCA36DAB8D9D65AF695BBFDBDEB65DC07FF7F6599D5CAA6BB1F6694A8FC62BB3479D1889B2663CE704F4099C99186D504C3651331CE06E627FAB29B1B254B159435AD6A8CB6A678F6CEFFFA7988512328D8D868CC439812FDC8C4BC7D086A1C6532A62AC517D0EDA6005C16EEC0C93BDD9223AF2CF5D3E272416DB60561DD0B106AD25B23E00232BE30B9EFB7C82F97DA6C564AF92E5E16227CBB94EBD50E06CC34A2D22C948EF264E5A1B4420A36AE83901C346792FF99829A40714454757FA1CB0D7681798102AA90BA5D37FE7C29C64B86005713711D5890279CB0844536C0F974A46802320C33431588E42CC0F35D5BAF2C828441538843B185C4D93F57BB90ED1261B980C6B33B121D5C8F1B87C2D05442C34AB56512F40B06D326F8F7EBC5FB29D06AD907E687856D558AB423C72CC3B85D683814824DFD9CF34B810861B4E33E41F15569159FD4C6622A6FC797CA97E8D0B0D2824B199A2EB5B6FF06976A92775FF8B66763C1A430DC452F0CA701357A00F3A7C1A29412F1C308EAC4896F55EAECEF88D89F6BCAF7A02714F68E8D412C591A2C5F11033F7FBD2F29A0DB8B4171AA8D4C7E4A708B9742B51F80DD6F9DBB7242EC438CABE48E39F1C12AD886B7750FEBC9C3C4CAE1F6D016C412EB6812815267590F94794C90FE793DB920A4C6C0ADA4E80D2B64B81F04084B65A8251076073A84C2B4B1209655847420223A0A87C7612CE67C1B9540C8ABE46A0EFA9312C0C1FE5AD3165B90E6973F0FF8DB7FEAFA2E01EFA3ACD58AABAA0DDFB30AE7AA819F5D5E9FF72402117FB8CD9BA3CCA0BD2B8F52AED5A435E1F705ACE8E18D60845B8F0B13C967C39AE8D1A6D1EF3BF875BC32B21839077DC0FDF2A4D02A0D1554C2128E55A370168D0698438B21D02DB8C3A5691712B439D4E51E5E31DB45148977A8B184AA5FB63F41C2EC48A7C9C64EDF88E6B480956D9B0A63FC1149D85966D045312A3BD3AF480FD4A3C3F09DCAAD041427B3355B4C1F072A6A12301A1F91880F16A3B3B425BF150E01C6F369C84655D6F167E94613C052D73ACDB2A04CBD4EDC141E9633568485603E5D0339743E030066AE49FE5AF1BC28CFD6F4053348FDF7356EDA04AD72F17376339FF0F7AF432EFE60F3B4325E7C692A79C5099C29405ACB84DC6C991F70E73E1F93B4DCF749B5776A8D5E4A34744192D48E6450B39FD74F162BDE7EAEE2DB13061547169B627F3209B4D06E2C0F71C8D05F64A6245C9097FB0931BB838DDE1F26A211C27710900DCED962114CD51646E5DE093C7B4A3D18FC99EDD501DE8EA5695DBB9581322F903BA408E74D859EF91CB1082EE68BBB997ABC44BAAD87C51A82FFBADB819743FD0D06341666624FD88EEE897168E2EE35CA6DC71FACD98E754B7AF4FEE2B77E4B49E718877C5EBA1706EED84049DBE7019FC42698BD5E0696732C61828FFF5D15DB72654595C2F2B90D12E79691B69F2EDA1C137D2E69E396AD1862F1625AFB9ABD111D495D8FF41CA4896D2A83AD8D00D49B15F1BF0D160AF3CDC637BA2E32015ACB2299A13FBF43D054B420CE97361CB38022C684B695C4164D0CEE286DD1E6E34C483BFB5F91049351762D9D2609580B64425C06084275AB7ED3C3CEB8863F713FCFC091F460DA2351D54CD4A59261BA01B3A0D5F97C04A4A598DD6BB45CDD6049F2BB52D68A9B219F6474751C655F404DB8F75DA6AAA2609BBAF77E7F67BF27D721517A7E128DC4180F0612EA7FFC343501E048BC030A85089BD2F2542FFDDEF0F4B98B7A45376D9B33EC082C17C8815042C5DDC3DCE0CD64CCBD3E8AAF9AA70475E845E8FB4C0EDCDAE5CF67C2384737D602EE1CDCA0238E5F2F0D676E3C9564F9C1D4D9CCAA85BA8B1621C8E3161714256D6200A61642C1E3034A2E072E6D32FD941B87BAF22DD2715FDD8B50D0D366E20F1E9ABF312F989930145FB158D4A1CF607B507C1D3C43C6FA130F36B2355F24DDA2856149357AD1FB9D608E6F25C57B61CFE450EE9393042952AD2BB04EB4C1E7EC92A19BAF7FFAD5FB4CFAC804A0E18AC98AD1462E384DDE80F22E457FD9DDD58615FF9FB4A731F85B1510FD18FD30FFC74F56CCB569002B85AF3B593B4B117E6927E8475AE2C9406C383F686B8E79F22CC4DABA9759DDC9B1CC6BD91C13E451D5D30FFD1AD0D1BBF5F888AFC54783CF930DFF4EBFDEC0B1D0DEC4F781966BBAE1B9D0358F23BD5A83F0DC43699F30ABE458C7FD2E1B3B5B04DB570C598EA1C9FCC0BE0E607418FD5F2B375DDE950CC9E416868F0D582268632EA4F6777AFD49EFEBF7DF61B1F6AF5B8915A3DA8A4BD5D7501426AF0C99795BDE3D65317175FDD10BA8BA957824D45EC0B2653FFAB6BF4207798833D6CF875A87A181CE8B7188F09A69A8987C836EA923188D59B02C0CD2483B03654120794459B92228A8E029D149D6854DA86AA59C7C906F06E314C193C5BB1E94FFB4101B2AC1AD22F520F6E2D1B877E2CEF0CEE8FEEBBCEAC4DC6E66E270250FD77ACDE3E05EFAF41029645891521C0A471F268173EE36F5A6DCDA14D1F5D30CA8C2F772AD1CA92A5AD9C6B111793F38D62FD5734DD9148308344C5EF4D2D7F524576D3DE03543054FE8AB8E317660BC23513D4100FC1F3479984E1F8BD8D18F2097640A1CA2DE7956BA400AA5F06BD13AED8D54703029E7B927AF48A1FEB1317ACBC7DA9F3B0421611252ED708515FED233615C98943B9B1D4337EA182CEAB73B704C162812677B9F96B41922479DA97BBD7C83E6A588B0EA87B53FD80024877037FA98C058E3CCE7027A425957F87B0CEB5129DC8DE0D14461646864B7E69C862B9C4EB1C2240F35FCC0FEBB3E24F98A182737515BCC65A95E53ED42CD15FAE2F3329D61BB0CEB24FAA956A33F358C8E29BC610D02F1F9F3B92C5A6B2B4F1E00B3494DD37814CE79956CF2706BD3B1F92D6E262CFCA492FE20C2DE75D1B8C20CCA8146237536BAC89DBEC536F00B780A906BCAB0F3669CF0CEDEDF8314E3ED4811B2C8336A7CC94FE79D97E4B65CB6240820C88B785CA79D630C06E9575C9A2EF67B49A150B481BBC873BEC1F07769808953695AC1B4A2F971233C9506827E439C37040FD31FC49E76EFF585E9157F83798FF4C7CA1D95258BAB04AF860805C554D44584A478D3274E0C564594EED9343E3349370D30164EF7B2E2D104B7978E8CE758CE8C086D8F108BD3F925040552CAB65853B05A51B3510743B70F4120150E062773071EBA75E5DFC774CE13261DDF18FAA0A7741FCDBC1618D1874C8F7876B200F8A8E5158B65F8E015970B0C3C3283778DCED0E2FA6255BC5E0BF24CDA13F6A47CDF2452783C46209623A7C425DF9845EAD1E854BB810183512043A66046996C19AD1D89C1E32C1C3D9C697E7405E6CBC0E5642816F8D9C72E9DFD7222A6FEE81C9971657B6F06F9A0C8E9550CEBBC44C2593C60B1EC54E5DD2D93501FB9EE42B8CFD29DE790CB8A15A6BCA3F61163D39F186E771769D2B7BA9ED1DC0FEB03DEE86834038116C5B00D117B2EFC56C283436EDBE48A61C2C7DABF5DB3CC638F14D28AEDFF375AE638A3E05FD871D56D86413477BFB8D902DB263ED841367D29C4A95B03D758CE9F2E4781915755990A4C4D5CE8AF77376F7F2CD050CBE42BAA3DB923CD90665FACE9034087F56115858441C9E060B05542053324A0722FF12E6DFAC3330C12F20679466CCE4C4A24D7AC09A04302B95509A42F5538EFFD1BF3DBF1E9537614ED865CA9390854F286C243F2E7AA7311B40E5B3DD2208156B37FCE086CF064C41593BAC8C6B00DCF6386BED761551315BEA7F4E1600FA1FDD2D0B20B26613A312E1C03D82D3FEAA24D3B948730698C1342B4FE97B7085B192573FAA393BF62437C57362706B17B22ADF289BB31B32079C9D9DC9AA1E8FF63B25C8EEF97F13A628FA5CD151596E67AF80A4B1A71443501F6B6C8B6825F8AC7B5A6520F056D589E849949E93F0C2E52AE89CB81F3EB7C31388A56D15B25EAF35F9570379EDF4E8923B4F1C6666BF646DE202359CFA3C8E10434A5A8DC3DEFF104298B3C0FB507EA1B3C9D8F300617487C3E93CB6CAD5FF4D535E92CCD1D8E3000000000000000000000000000000000000000000000000000000000004060E141B21262E" - }, - { - "tcId": 46, - "deferred": false, - "sk": "CBCA46632F51931999369241A839BB7E57DA0237BC70ACEDE33B32FD3A66B20FB4EC73B8DF3E9EEB22782E3359A9CB10EB8CF52422CE70C71824C705B7862DDD926DD53A787E5B80EACCFC8BFA1BDCAECBBCC0F697558C85BF745C0741CE0C818A1A2159B5E2D645CFD5FD8A7914D64095C4B2EC86549121848871229F27D91D58847013928851224411090690A28493166A994460490891E4065221B98942B44C03850564C071C92472834244E086650B377010102924382922458601B224149085D44622D43231C3284010182DA2288C1AA10990082A542286D4042680400103196A019780D2A86DCC062AA422680B492854327123C36440180C61B070DBC02DD2300A644009A2922548262658200C14912994464813046D0842008B989144400511474DD4180598C67142B42880C62163C020143265C40241C21624DB420D03068A8A382448484DD0A40DD3924489306D09A52012856C1A4450113125412820421692D34012583481092912028684C094040136451C200C84B48C00932512190294A07108A388838064CBA88484022A13418299C48D5386848A4692188890233820DC88519B16469398000B046D10A45012B14D81A20454468E9C240ACCA028DC420611295102A4608A968DA2264E0C2931C13272614280A2A28C9A285288B40150A28118024919970814A7110891680A8644E048921BC68DE3C04923C261DCC00822C08840A030134972802844D3920C1C304620012500C64DA33485134140A12406E1226022130648006022C309543491A20881498425804240C240640A456D04226112106983C22D53344C42902120048192B80020238D23022ED094901C33685B16500CC7440826720081481294200A9148C9C0050C13109130650924300B0889110461C3908481B06C22044AD1B63181021091362C54C60DE13691C106084146508182240B20020C416A53340A132822440026C92089C48660D4300962B0600A274100C664E4A084098788D11646E28010C0444924444ED32471C4A851D9300DCB884C81488A1B3025D8802464982411C42DCC022A5C38869284311A1610A2164A0483601C33510B336020180D4394441B07480A21104940321C28804A402A81C840C3106E12C8456288819C10654294715482082045892048461439864C068A0AC585E4148AE2B02424400288342052464C53064A84226C932850C2187061244182487011061180A668883649C22220D4982054420E1C070194C04814A72D9226268108810B03651A210ECAB44D0020026140122202308AA48D24B74C0986416388804C1871C8226624C249003971A0164401246002810DD4C4845C32701999919A90702297712348019318025AB429029785E4B4080A300954B80923434E232888909268DC92440CC525508680621069143989C4282E919248E298059C308564201208B520E43225524668488809C12868D928442193045140401903095AA84C8148288B224A04B369C4028452360043442A004800C40445CA304418181292320888C690C8284E20B101A310268A1490E2464DDB260609498E1930260BB58D5A3866A0C60D4998619BB06864300483226D194071D048520AC829D4903004246010258AD428860A320A10C3091C4661E3C0806428686480815A12024A4610C8360A9C2442909489140401190409142721D8020998128C5BC84DA29409A28271CA322DE226825B16080CA00912384E8C84891B3748C08848DB980D04A84808982C24A59094246C2113669B102611162A13C96890485220B96513394CD2A26CC9320D14952C0202651C3980A0B62C18988483242A623269C20202C8446A82062A0300255294880C18259A128618C6401A310684066D18430D88C06024416281C06000380622378D02096E83440621372E50C629E148819C882D03400C5C48301B0384221061921490D446858944110C2431144051CAB421198444CCB284538050A1006C23418C8896298C300C50A60C8820848CA2509CB43124356D0C21120A3749C2C06014B44844108A41146E1281045B32080181088400054230900B344E03A048C834450C3290CB88044BB6844800901C946D1192100C1600E2366AC04866504890C34892A31830118600528871CB26400C44684312665B380C19852010228C8B928D8B40308A900C03C90D1C036D1C2652922032030120928248EA7FD68A0C62DB31279B2CEADE3F558AE9E6AFD3849A6FDF95B9F0C219B6155FB29921A667B0130D8B21493847393DE153BD4ADEEA031270DB812F827F974A2CD6520E7BDB2ECD99916FDD5C439EEB41514044ED8F02361EDEEE74F03C183B6E3F3194FD522321188ABA2B3D8C7B6BB4B6F2473ABB3E5337BCA906E716A6DF660DD51B543F02D35CD9A78B9D58312F62AA96635B8B65844500413B3D52BAF6E671487E6D882ABB2473AA4F321CED5A1F57072AEA093A6D51EA0C701FA0B915B14D5EC6F16E4C559C85FA9DC465044097ECC21498E3D6F919D75F8C364BE6371753D2CAA90166BEB726118266D8D7C5C3AC81307E74C0F796E1B038F7660E770D1707F10EECC95694A2C17A6306F661855DAA243033E624D208268461860E39936BC6915A86CCEF098B4D687AE1C1B22BF476C2AB753C8F5F528C7F749749372AEABF9724FC7E3F554B483D10EB78F3099A7ADF6CC4CC03E4EF1B6D0219DECDF5AF99FFE4B2D4CD18BA98C2D62B93555A2989C753BAB1D4BF34A982A71E0B10328E165BFF69A18F494F5F40DD2AA52B23CE544F7FE4B5632A0FA4C879D221A84CED7E097DF3A17F4E4731F87EBAFA97428C0CF9B51200A0126ED983C6FCBBD52C64E109A809C1353C3ED3A214C07A29BD3047D0E69D00B8BDA5242BCEDE709961CE83D1112F19BFA1C6C68FBCBB1B3045FD681E3EE1AB7EA91BD5F501F2D9CA88F9E6E040516D1DD238ED79A84C3E4E8318427A41ECDEA73CA4E12E575403FE4BB9AC0CC9FD8A7A1877F09612B8C8746274117D7930A0DB55EB493907822208DD541CF3BDB71635BFA364B01F293A3439AA6DA458ABA62F063500D2222A6CFCA9E545BC61624E1097031219D61DBCBF8C8D32E345058DDAFCE284B23BE63B5F3AB979C35F4B5AAB9BE0CC37DCFECD168298B744C37D08CCC0DF515AFB01461ED24850BA5D84977D4352E0838EEB9ADA60BF0862971A83A0DE929C06F4A4513E3E01F93EDA9CA7408233ADEE110DD0E1270AD957A296F8842134178893D39C0AA07496EDDBEA015A1E8F42F4CCA571D1AAB376556156863FB00BF1F4B329964B98505B0FF71D39D35EAF9D23A8589188F872D555A55BC37E364C0BC41468130B2ABC8F43EC7F3C39BF0579692CB04DF4A29C4E71AC4921A79B7D722A005C226A4CEC49967AE22E2FED24CABA43D915522E59778BA66F5D2E3604AFBD076DCB7ADF9CE9CC26711EFB4EA190A6660F5F7BA77E2A165912E2AC8C6A4756B5A305EBB92F00294F771B75F1B005E7E042D4FE23EF90C564E385A6968B0A61CA8940E8C67ABFDB4B57F16FF6EAB60ABF48866479C6B891C5A7787AF18906B528F8CCA98EF2D1CBBB5516B95033CCB060B8C66FB1B0049AB88CA15776971FAD4903639A1B354923E13E1322DC220ECC967C581334F8FC2FD10B7B8EA6517427637FD2A967DE71C49F24ED2FF2A72A43CA839D8893472CFD453AD66864AA73C002875C4A09F631321485D3E8C3403406E2462030EDBCE21E7BADBEC4774CDFB7914DA8099E846D69C6A7D58451864F5205D1854EE420B2915B84A933DD381D9152E4FD6C0795CBB90F506A4234AC4128A4AE863D68B06DA74EE36BA3AF8A35B30AD5AC6CD7DC29C467A088CC733AA88055F2246B3370947687E2F6A825555C5E8C6B6577EC2C3A9777882BDEA26F8F8E1871E1664F702DA4B580DACF7DDCD6E29763F5737B000BA424528D197937EAB91CD31504D626A3C33ACA17757DC65C7311AFFC35731272B18AA49CD9452C7497958089FFD021A8D234F80CC693B286C12AF252C9B32C8884CAA75569DAB60F2E3A0CC8CC9ED8615FC67866B54E2762B69F3F81DB13B510208974897A62EF4192BDDC9A7B8AA27DA597C5BD59131195D2FF648F4D13DA5E25B2FE99F1604FAD38759DBFDEF52D8B5E93706C0BEBD16048A496C8A95609A4D370F131B3094C928F650311FFF864AC94F6A2AA18C7E203DEA188B9DBD20FA08EBDC4A2A59095CF7E64BD16F1BDCB44CEDF7409DFA209B1698E70F0EBE387DC40B45C47B621961A34BE1F53A7CD634A538740799A3CC17B69579B34168D1D7C601CCA733B4774F3BA611D38DC44D3A7FF829577304B76B3A2A3BB5A3AB0FCA3CEAE0C4E50B985C7A18CD37D517C4C53F91C8BAB32B90A4F157B09CF14A0536E01BC382C55DC83DC27289EA546326D7F7D91DF5F9145C4590D1A83494D2C3B29AF79844F0658B453A8C3E44EDA25198B108703584DFECC3686C0BABD1078E26FEA2292591054A5D9B555D4B056CA7536CB81F8F7D7B5A2B6028540E9CD21B2458F1B2A5572C373E31922408B26AB3D5184038A7CFD9B506AD4D3CDB5B6AC8DCBCF56332C042441C79B9CFB71D057303BFD6DC98AFA0B312B04EFB0ECC4479CC1A35D53C13ACE0D77C600D43BB79319ABEF7531FEEC9E42270DB58F8692A51E023614D8ABE7744E5B822DC883FFB7C11E2CF2B9CEF5A1E0EDD47688B653A0B2DCA55A7F46BC2355B0EF5981C1672D09A7A74B93E1A92C8D8797322E67492C2025D6EF89A2DAD153F261BD967D5D63A1285F134077FA25E1714108444F76F1212C11B4EE73E448256F93470A44D1E0F7D9941BA5689D3121A47546C6B40014397927720937C6FCB50D283BE16EF175BBA7E1759A1801CFAE26E2D00D0CCB9C155FA15D9D269A880A5B1A769FF4C74005407BD7CA73DD3DCD09F0E940B7D84A1876ECB65F0D712993B5F2EBB9BE0699F6C2F79DDFCCA8ABAC2C88B0A02BE72065AD98C017ACDB90FF3F90BBBCC7C8C34146272CFB36C2D04D073049AAB6BE66266046E975FCC31C6050BAB10243F774B75B12986F97BEB30E659B2EFCBD53001654BFFB603B6B9CFE03ECC41F1B46571688D33DF1932AD1B82DF9535D12FF964618A2F76C6FE4153D53264982466D1EA1101B3A4225387330289EF0ECE4F11A8F2CE5643DBA7089BC1482A754A000B53BA46DE6F55C13B4B4C858C0D494ED768DF9A366A2021157908D696FD95750AEF985D7A7A2C56766BFC1AF0DD3591A63068FA1C6E1BA9F13B0C08FCC71C6EE02C0A2AFAE2A9C7C35F0DCEDC5E9823F28D5C1BE4E1B656469C2551704DB934E9FE139C2E9897553424AD74D68AB31CDAD48ADAC6F0C89EAE8BFFC8C4CEFA2F0D09E2C96A134FC158CDCF62B1CDDBB072F62BA0930755C9759047553672FE03D21270CD5BFCFA6F30E9BB67CF9FA9D02F8A30C5B977BE4E52D71AAFE6D3D1223F73EC5481DA72491F7C906FF6642D9731B396C4F26BE506B23084421A527DCA74AFC6BE1F15084078DC1DF2D813AE5595F40A94C15A7FBBBF4EC05F0608B28F283E29F8E730268981DAF3AE4CFC111F57CAB46588F4E58EF2C1536B0629021D6A599648F8A5382EDE2A4452E9EF6F5A7A221D35E9C2BFA134D11D5C5DE65F5F0500A1DA11B0DC055D0C2C2789F14F8002A487478D1F989578AC6961E262A08B31D913042410A39C4F9F71D1E70C2B1951732346E79A0CBACB0D63FC4D78D45A0D17A2BFEA3B81A7F14E3C680B4B9B967447B95E0F4E06DEC7226BA245597D2A39FCE4D1CFAC9B204DF917CA3CB8F827AB9718EFA69DDE17458EF3B0C0FE1CC611955FBC64A436B77C33C28A690CDEA44E0EE82B346E2461C6A1A1DBA39A12FEC61A892CB27027C57C1F72CEF1F190ECCC686DDFC043CFB2FB0EA8CB280928139731D88DD257A7C5554EAB6279EA0D0B819595DFF68E1612B71304D007633EE49100823E90EB41211848ADC7A0821A4B3A9113383E8217F16C11B331867AEEA9CF4CBF8310F0EA0A477F5EE1B2CED3EEDC4D0B300BA19BB95E4455EBF195F5E12374D5B6FED2A0E5D6F98C2B187B03E6B4CBAC7C4B446BA02D057D20CB3FD80CE79CE0D74856834228FB07273F4FD4446B8350A8D7C8AA11C64B89329886FB1327253FA162E4757D9CE08968A5C31612328D24D881F8A9E81711C7778B26EBA4E93AB00F3AB996F3BFA79269BAF026F33F5D616A4B306A100BE5899609BEAFCDF981C9EFBDAB444AE7A5982BD925E6B82603B8F9388D7AF9474B8AD18348121AB3E5DF4E7A9151D91F7D724CB2D6AD60A2FEC17D29DF3DD2628D6022711E7D4EB486F90419E66EA2C1479BCD02D2543807ADB8D75226E8B7386CB4C4057590B466B4FF7A244759C5724910A7CD569DEA50E8520387BBFAC32DCED5575B6155BC66C82F6132A780AD670A8C91A6813C89DB6D900F17285DE4DDF110579FB1E28B323CFF7164961B014C82EC825B25AF70EDD5D0BF74331B8FAC3A69913D7030DC1A142FE2FDA1D4CC5C83A747024DE772BBFAEB89CDC880851020A9D4C5D03267CBF996691A7FC1399BF265E985BEDBC9BB5B79487B97E9BB2DA935579BC5AB555EF633F2FF85E51392FAEA07A664F329CD923D4460423BB6C74BD63A4AB0DB1E3BB7C0EFBDABDB95AF5727CD5DFF90878AF51EAA0648845AF99A2286479E7125F867B31B3166AF309102A05F60158A968484FE5F1C0275E67DA8A84AF33A1ECAC4D49DE5D925748FF1E7A5BB442DFA88E5A3797A10E4CB044EDECAD83324986DE44A5A3896FA6EC6C71C646C2B4431AF55A3C2F325C6A62460C7C9BE6235A503A2301333F0261D97AC6692BA5B9B8BA375149685F85A443FF8BCC240409B6A959C1045CAD6EDF0EE593F8C3FF535B46125E00EA4C4A96446BB3E261429BC6B656B401598BB83E365C438EF16C8CB2C25017", - "message": "B5CD00AE06396DEB95C9BE213BEA279AF0D10F1423B5A71854413E99F7216D9EAE76C8AB884545496559B14AC9A69801EE3FD2EEECCC557D7988F34B82D244461388C7D4EB16DAC3C0FCE0783321A1488DC16C3C688126754BB4C26308054545D2E46C6BEE26C25A7C3B701341A0323BEBFC50C718162B7FF3B6FAAE7156FE300F2219655D8D44DE89845393011A2B466233B907355467EC49C9F832044BDFCFCF722D6DE7946FA503861C80037549ECE8FFF95026CDA33C9000FACC334765A60456084A0614455C83E0D5D991F7ED43952B7A69F1E326D7BD33822CF1F286D85FAE78F0B8DE186368EB334CA56070122DEBBEB920C5547C46C1291E78AE48B72C7A39020A1A2E54E59A2E46606C99E652FADB39AAB25399B0830AE733FDFD973294B93F47C30D0824686C735E05FF51A95C1C76467A4BE6BA80C5182353BD510E8D4B60BD43436F7021B3F5980D1A769B2E3BF04E0C257EF577828B327E2AD85E0581787B9B7FE44D6B826BF8405D3D0BF8974D2B1C569006C7FC3D2891DAF38DAC36F64A256E337B660CA59D2B45F1B4AA1C0C72B78495FBCC9EE9CFFA4B5A101F973E3211E728040904B0B2515DA4B1CB3774EBEA1324EB6907324E733C7F17BEF6FAD0F6BCEC1F08F785DC6FFE02FFED5C0B7A631907196835EFFD0730FC8FE020B0545C920DD7B2D705F22D8D205804397F6FCC60386F4A576204949EF60DEAB269905707396CCCD8DA9B895270CB39839BFD3EE64149B0085B96FEDAAF8C738E449E585ADBA037BD560EAAE978A6ED61DF432B6A9C2E50C2EA33A8702A23E6848401F85E2C18C7C767DB15920C9B3B030728FD9511F8903DFC8572A3679F986CA1B684B3AAF489DCD93C622C6C4D475DD60F10C390873B09B5A352B6F5A104C90782E053F8121317EB8D1D4C0145E04E3B68446B69A0EF81097CC6BD0B756AF78963724D9C83C61B7B79647F0844867B605E2B60988D2D7AD07CD6BE2D8F904F0D269187C141AC67C9DCF9961BBFFDDF3BF34D9CC5781D1BEA348F49EA8FF7750F7F3E0624C16FAEFAF1D8B6A818AF5FC5C04E2504A0CF4C2DB54930EFA759A292A2AECA1EC3A08918513D95C44BD133657FF043318A17BE4A5DCAC54B87FF38869D017A4B14DEB60480AF1C5F19A9F87B94B8EFE0DF3F931CFADFFD7AA50AC86D9CAF6D434CC81E6ED123711E34B8295A446B554F6DD5350B44C614324D8727F1CE501743043DE6EA085DB5154AD8E30E114A02CDFC96BEB4F2718033B227CB8638BCF617C73BA4473851E62C8A287CC4F9C659190E60AEC468DE7EA8841E3CEF893F3DC79DDDD56B63102EAA5B2793711A0451EE1655C6768393F59CA6085866FB41541D9997C94BB56F6ED5D731585E7B25B1DC853830DE5DD75F66298BDBD2E505DCB3850F96CCE0D7274633234EE2FA1E2782DA3D6CD8F5DA2C3063A923DCB6A2F82614527CA2A88C1AF21025B88A08C3104C679175DE2CF00602B13E58FAC9376BECAE56A60A6A8F144F1C98C8FBDCDE6FBCA4ED13228FA77CBA5CE631BCDB368AD9219568777FB4397BB40485A9AB63E9E3FB343154108D8117CE25BEA30BC854A241745FC6C26AF0D64124AF10BE4BE01B8A3D842FD9CC4D805B2BE26F8B7BA0631443F48C7F74207F640B215E0DDC42B1954A1EAB2C68E63601DE3AE3EA54E16282BDED00FC7665A9E8B098BF034F5E950ECDC46CDD22210244F102E41E0930FDCB24AD6C72507E5AB6FCCD4D6B2A2703C358EC1B51AC87302A5F507BD01CA6B5FE04EA2A5322EDFAE8161965524C61956CD201C4BF2F01B54F008F5F4B6770D0622099CDBF94D6C41DAB4A5362D630B9BF9CE240ED08D698D1AABF29E60BA533697C3C830521314F13EECD95C7D2600E2A756AF19AD94D9EA39FEEF0E3EAB3EB401225C2E55B2F2A8D7D1A3AA77A38BF9BA31399F6E6458F3F21DE354BBECC2E29740FFF91FBB23E0F61D7E0698CBF82D439AFB018DC5F5011B7BE98993E8B655D83C666FC0CF84A532C7655365746FDB97874D62329B1EFDB0B0C8A46056A85B60E38AF8979FA4910D2D9CACC3B5C1E42049D04C44273953350E0F756081D2DF6429193768802577C381897BFE540BC036293643360C848A1AE388CD17781296A99AF0CF75F81D568D0648C8A15436BDCB16FD83287C6A54F88F2F75E6B28E1C5A3AC03501D6D723AC5EBF90517D194A596F7F95947CC169CFF2A65D2BC9B54CA6AA45BA9E901D4AAC81FFE9E62A479EEC5B3F9BFF24C69FF56EC52F1183B5AC48A5BAA90BF595990B6EBA5B1CB6D88511C7D0D165FDF2615351B0343918B966ED1CA0CEBF6956BD2CA599E18619E1A5930E47CAEA92B8E9647A0262A2B24E955040750E6C7B935982CB742EE756DB65B462F677AE09A7521B0D3A42C2E97890C47148618FA6089975F5D491F4D3F69EBCD54C2B53130698A1F4A47505194F675D68F2DDF5983B008E498AB4A25956CF724F5C1250D5F9C75F3DF9BAA696E300AA86FB4B9378EE18E79D015CDA55D6ABBF5B0BE819F9EE58B49656D3B112AD8FA6651A8905061A8E37760C3F2EBE6DA611BADD44268975B5000051BDF7158EE3DC200B47FBF8568C9F22719FBEFE5906444DE9300689BFA1AD167", - "signature": "B2E661C2BE985A4DAA72B12734EE09DE1C78621F91D7E247553F39BFBEF28BEEE7F11654775416E4694086B0A640960D1DF784E8F62E16FB831097DD07A1121B00251D35E4275ED3312C22B41CCE76851A48D9BB0C46A64243110A4CB759675CA7D1B724CFD94255F11EEAD5AD01C88F70E2CC02001D6F44357BFDC159C4CE44E042FB429CC7D32968C5CA8BEED69C6C3769BF2A83AF75A7831B76232BE271B33A43A8B69A91D23E762280E2880559392B4752D29BA296BCE607AEBC0771AA0A92A30B72282611A693E828D068B04C34EC01634488AA8D1862239015BC437A23807FC2BB1B27CB9EC45DB5BAF866858F1D69A3005D4D5F210E0C25092D658CA9224B49FB147CF891C5127FAB6674FECD864A1C26E4881803BA3F8E6394BA98D70330F5D1221DA1D1E966EDB682FE3BC4F7CECBF7326AF5EB7C582B085B4B7F603212C3C8C6E59524A09227DFA93A44D532650F617470D9D250689538ABC832F38503392A96B0E7BFA01323A85696F3E80AC0A860C685AB4E248CB646A107562008358B53842123593E5FCF233951D43D33B110FFE33EFDA0D4A0CCA3F112F94C85F967F0C6A0F7E20B6836664B70522F962C395971692B29F659F0418FF753BD862966D10E44B406F4CA1DB909FE01B6F9F1B60715360D4617E7C0FC4B37692707ECB68B50D38DEB8F40B8C304080D81B84F60D49B7E4EC50B02E36E063FE28BE9A23E6BF17693B8B5C909B5B136BCBC6A3832D53E83A29ED9F933A8BDC8E318BDCEFBC10113888C1CBF39464AE16E2B30FD7F94AE1A0FE8B965CA8DB4667BD41B52E497D60C31277AB70C19350B2C410AB302754BBF7C126C1C9C8C298927AB39E9B4A024C0F47691880E11C0F8F7D5710D480FBADE860D72F43D1C676118E3F83A76FD6CBC7093B7BC18F851CD93D81B0564D4BE4BD39135BA2ADDC6A6DA8AB8F7B15284794E935A339E234E8452F766DDAAA0532DDE46FE6E4C727856CC29D7E78FFEE115147769543175546B8A838A0F831CBE16BE864C733C63F37E6FBC1CE2A36123BED296103FFDCF8F3BC36A7775A9C17F69193DEE0ED7C1423FAF6AE7CD99EF943BA174A6262916B78F9516B0464E8BFBCF512B80340C489B9857798EEB539062F40E39AC8EA3649E787C0A87FC548F0CCB801AF8C2B2156FE3FF69BBD30574D8C11D887A98231B7C6F24C662A48329DBD3DD410A019715DBB61F72D14883FE891731975DBDE9BAD0C2A85FFD773297E399B55D78C3A2C25C27E4FD0BDBBABAD85EA6BD6A3EC8931E0130EE4D068ECAD5BDAB22865A537B3ED2312D1462EA6E36E14D5E49F742F2A232E5216FBBBB1802B5ED89E361CDC0D2FBEA4555A895FDDA03597F2B8966D147FA586BB53316DAC62568CC823447B24052680CF67D8BC8D6399F928781A682A8BDDDCFF8785163A3615809D1D10E14ADF471CB1D93052434CF9D98F9D0D849283079FE431B8114EE9292E52F49C9868A013F0403A20BE45A2E157803CAB01F9C93701402595BBC90132E9FFF845165C799443F8B38E360F660AABB901485569D2B0081D00978B8A1B059BE9E4E98EBC19B027592E453FCA390F7C9DA085255D6A7436C8F1A857C547545FF0130A9F1E6A1B2DCD1EB03F7CDEBF39CAC153817CB450E501A62A1B93C450FD18CA956659D17A31310D517A81DC62640D8102DF1F79794CB7C096B5E37C2AE352E0BAF1A17DC8794D597A258BEFC66F26131298FAAB9EBD6AE3FBFB6DAE24AD74496BD1F077ED87BD1728D1809E96F70AB8254A9B8E3D30432700BC61FB747141609D4B9057BED02338233EE71B26364DFB9492A08933A2D3392C6453D34F33940C54B956BED2C11D9D1C68DD135AFF9165F3F2C801E0FD1480EF0BF99B95C68773CD2D765C1ECF04E1CCF68E659FAC8CDC03B44B5376EC888A485F7F71EF2E24195D75016CA6A9229C2D0FEAAFCAEFE07C46D3DA5942A15AD5EDFA8FCAD9A46ECFEF23A31F342071DA70A138BF5AA5003B70FEE1C00514EE0A3A2D5988F5EC5C279D7BEF153844DEDED0222DB3EF8A4579AF641444ADEFA07AC6CF37F58513771B8C7E406585296A7A2B6649B2FC1619BADF31951AA902EE48D5A9AE8DFD14A160538FF861FF64BC8E577C6E77F79672BC0273549D14AE1895479F8941AB0BF3093C5C439591F8A4FA453A9784A1F76FB792732405F05A8660740D329F2F68CCB6167D12958CC58AD567746667048C696FFBA426D40027820C4C740E66666E50DFD07C0ED76DD4C2080FF1C29794D6F17570A1B9D3D9AEB90AD34626B94A08202289A6409145D820C962183C58CB0345B287BE9EA15C5C443CE113270ACD15A075399DEE56E95E4DB23EB19E87C3E29BEF00D00A5442E67A7EBC5E12A096090C6AB5576DB5BECC84B8000D382540F98C41EDFEEB99D3DAA561FFA0C7FD6CC16FBEB6C514B45A70B2358EF4A53268612BF022FCFA354A80697225BC2AB988322DF31640FDBD05EE154F7C79A89463B2BF0C218749A454CA38DC8B5D1105183B7108E64EF8DB8FDDFA6BEF048C14CE5620A456DA5CB576F0BFFE4FFEB8333A9211707F5617628C2459A2104F8D5FB7B9581EDDDA27AD3BDCAAA7D037A3F996EB765237CF1C42B090F3B0453DABF26F9C92DBA120BFB577350705736EE295BE77CF70A7D3CC6AD388A526CAAFBDEAF67614224B6363E14B3DFCF2B6F4A0E8E2A8947D64437FF0E90DB68DA40D87AE431C02E9BBC647814C60F3CE5BE422C2BF3AA8529B8D706A5F6C3512979BA6E54401F405E6A8097CD0156A8B9D4C434014C2BCCD0DEC4559A87ECA3CC06200D77C02718330CA621F4F1B58ED3493B9126482BC941CD34A5BDC4BC3268C780479453CDD932C421229246D9BEDAD0B734F8B4D06A3780155FE9A88DB8C540FBB8677DF962FD0E0E4C39197479A68E42D9AAF4D1A1F56071F994B1C0FB4B9E6D150220DA7FDA2205E4729FC5517DBE0BFD9256EC717F0CCCE43C2862957E8630C10061D36AD371629912E9C1FA2A01B45AE331508D42630B39E5DAB3F141DEA254F1C6EE0A934B4CEBC4FEDB5B1BF6EDAD35810B836AC2A76EA9233D12E39553D77D1AFA964F8B104C48BE49A65CAC8EB3C352EE1ACD5EE14127340D6747886FE47DCABC13CCCB3410BAC0F96C718CE69DAD106C3D6F3565781EFF03812306F65C82613DC032F10ACABCA0E560D5A673F427FB231362D46BD40BD0B811903C259C2622E893DC4B91F21787BF0FDB976C4A6286D799EFE8269F9E8DA6870C9CF1A3A29897AA5C9D2C75D7C9FB29E467DAFE12A414398C6CE08917BB2A322057FF7BACE20782256624C1B7DDCBEC3AC680429497E06C022578A7D8CFEE14D20122C955005C0C4D3851C3D9D009334EC9B036AD7E1B08CED43DF8D148D5F6C72BB87F52A458910B0829B2848D082E3AAED3251818F7991136BF2E9433E025DB193C2581D1BD438F180CAFFE618CA88E677D0798DDEE55C4CC1776DBAEEB564770567432D34BCBAF6BFABC62E75C714BC76EFB785A37F91446E338546B5A1CFD83BE448405705D7F86B2E56F10FD54E6B3A047EC215DEC3F787EAA157D317C309B37BBA666810167EDC9079A4303D7402B8ABDB03383EC7A37964AF35C3C18D7713F22CA9D278A3F49FFE6C7D158DD97FB23AF1F23916E88539DBF6176F76A4DBFE11CBE3F914880AD2EE49FCA530E483859BF41DA5E42F01B0503A39D9C7A8F0A86B3A8184D87AD5F5CDCAD88BDBFF3C66907E7A448CE0C98260507CE656DA3316186A19B902DF6D1EBC77693BBFAA8121F2D679394772A7A1D127BCC51B140867EE4DABFF35E303BCDE2493D5CD02D302833AC464E34EBF202542AD81F38855BFC1C369F25C1AE2B3DAB609461BF7870D68D2E96D78176C2875F0C277D2493F5653CBA632CF655125D01CF48E2773C67EA58AADB857EF6CB50614AC3D1925C016E9112F36A28E142DCB5F2C1CFECEE0B974D254C764EF65C496D9489F65C976ADEAB8A21C2FB447FD7568C7E7D76617C67C812DDE31108200E5FD20182A393F2E2D6970195F7EE3C57DCF6392755991951F5471E402F88AC6200023E4B9E4EB49AE838F2289039664EC744C544994EF66DB2B86B970D20317C8A853AE532FEB55C5B3C09239435E1024565FB50B0C91A9896B2369F9CABC190C3131BBDA5C8673BA8C748A5FC49EA8E671C424F39E0162A9E479C3C611B5F5940C297050122978FCFF573100FA891CFD64D9825319EE01086D12A81F1D10FE77C8422DEE9E518F37A74FD8D1AA0070C99647B758D7EB8648618EEBB22A2049BC18A6FD41D3D9F712448AC3322B4F9BA2330E61AAD6FB3048AED745198ACA0598A97DC5B7A8BCE9803E0A62E19A2F54BB2C3EF80472AA5E27EE039B7B4E722358A242BBE7874EABFC76FB3ACF9D7F00C7AE2BC5B841DE02A8388DC800855340CD4B0A861B4E7C04FC5F50DA66FD845BCE7CC8269D81D7FB5D4968566A7EB7C984F71B9B5CB3B1D5AB3D6669472E92CDFA16B2C6B5E67BEA9FC54ED393121BC887BF0B099BA46082DF688126891D06808D2F2905B4F1607182745975A5752D890C4023BAD18A5FF8B4A4FA529B4EBC1244D715F186440EB3EFD5B6930C58DEDCD071384A1519B73F2EEADCFAEC130FA6DD6A6F0233BD1FE25AE7CB268405457EE6507DED9202544E0B5ACCCC830180D4DDBFC65DB3E32C16FEF0C1CB73949C2FB02ADB9A22C5727F911D308B3389A520441D5B5A7CFCCBF1656E6CF5B4B1D10B638E3D84440BFC32E45A74C0D428FB9517D765166973D25EB5BE2A5385AA6335975A4C8F3E94421E7DE1DDDA6E9BE97857C70F8C339485B5A85245180A317302A2E58404A1DA5D5583A806E8A7C8CF766F29A816C25BFE9EB6DBC2567C0D1D4D971FD95B7CECE133B6CF6B98CCC6C18DDB84B4B23FEE7BBA2FA00EF32110AE0B525F39DA0B0A7DD8C7DBF2A7F8B3CC90420B5EBCDC46A2367D236BB993ECE7FB1059453D08DF84ED0E1CB17C357BCD681765F8A6126C36ED49ADA5C82273143906B8FF421EC0B4DF20E9012B896DC3EF63FEF1DD1ADC09C93FA301C906FCB38F28A36EB13B4CD4FF9A6AC5D2E146595236047005814048A31226CB80E2ED09DAD75F95D5981AAC594B8C2EEE9D02D9C7383CB7EF4108EFE0FA7BED68F3E4B0972F2FC78373D7FBDFA91BA0A1982D47A7E6FFCD7DFE17CB23EFDF20B10460676EACDA5D46EB5EE83BD48B77C4F4559C460FB78CC3D7EF8D3016DA618D1866B69A99882812BCD6F2E72C679D894C97465EEB5EDE357FC34597F2490EE3CA813237AE80C55C86AFDB734627D188819E56C884286B51C5609C027D9E410B5B7ABDF45E539FC23B71F9068DD1E51C6A1DC922CB90716862B2F60532F34ED97627B43EA6D6D6A770DDA98E53C9358767B364386B549DB2B91219F17632BB02DD407969CA28CD8412B7FC8455A9C028A63930786FE41FAA360D240005F915EDA9E68B559113AD23F66541EE22632ED38187D4BBF77C15CC9F873105A749711382E202B5B66E9DABD165F3B296CD2A712C82BCDF9C3F0B9DA1C9BC0A34D6E9EC01397008492BEF118B3771BBD5756B42817BE46166C4CD13C8BD6D9B75D73A147AAD5F4863D664CF84A84BFE465855D7F373FCCF6EA3CFCC0E28BD76E5A5EFD85EEADFB15E7AF47ECE44DA1367C90C30092271964FF524909B97D2592742832933A0B04DC59CF62387AE581A2D7E13756C1D93855B8839F7965A46D830A083036FF30E42FC5F32F9E0021F79DA5C62E16BB2BF0AAE7769270704676A9257F62B0956EA742D8A3D176188029358F90BD91373ECFEE5B46AA23373CE75627B0C45C9A4F15D07425B5C1C1E1A3882499F030775A3CC6B5E2C91F48DA0BCC98CBD74691D7513E3817798AC0AFDF0C6B349829DCA9B9742ED77B4EC779366979829555FEF4BCF7270328773C850BC9348542113EF19012168BEA1BA4C1F607FC941A1B9BAB11F89D5033FE873D302CE0AAA51BAF328F74448E70907C302690385BC3C5E32AB5DFCDD887294377CEC6E1BA90EBF9204C28DE77CA85C7E870C3C74B91DCBC88CB30D07847912100B081578CAAEDD44CF9F79736E91EF4F0D8C3555D347ECB2AD272607AFAC189D3F8AD3C7594A66F2614133658D9FEA2DF536F6A11AE1B2DA795EC55FEA5435761F7A2E8F76563AA346F00CEEEB41B0E5D43A99BBBA029988D792FCF7B9E085C1052D319B5ECFEA85E84D354B832D84E370880D0552AB9DD31822D29E6476873E22E98EBE74A14B72437F5EF7E36987E905722B781B451053DD5A5D3CCDCF5ED40BFF1AB4D43921DD019C1F41B0A9E75CF740B6646380DA9A1372C4771E29C4772F67F0EDBA8FFA3D907ABDCC881F5D76E68EB8124A45478E9B66B061CE302D1605B708224A7DDFD25709F4F28E803F0E9FB3E90739CB3BC84CC84621A19F4050C4E93CBE089A2ADC1CAD12894C1E1000B6C9495ADB0B1BDC6DEE4F21B20689FF0F70317181A475F61626E717EC7DC48555E63A23C494C5D5E5FE0F60000000000000000000000000000060C101D2330353D" - }, - { - "tcId": 47, - "deferred": false, - "sk": "8411ECF640CB9A3AA61EA95BB60D5A31B099D67046A1A1953EDA3CC207F8009EB1C0CA1A40A71137B98854F470CB52EF825FC9D08CCAB2A406388DD22421DBA0A99CCACA95CE95F9E32BEA8AB715A39A8271B7789699217B8452188F4AA078C4F481339C532A2C2DE5535CC7665237D357BF547A7A051B0E1F47270231F00029A1B204049189CCB20923322024468D5C086052461120334D4A06461BA9518C148922933190A460D9B4852107929220310B31061A284AC2122894A2300A048D1A9609E444319000269886681244841397006312056118219424602142868AB86489C2218C302EE3C2611A366DC1405093304221A24409B1901C20821A8624A12800913430C816860B49614A44090AB84DD2B25100948CCB040442040911407108812909886C442082C22401CC2209E194484C263040082660422A03C08D12B90D91220220172820474981806020B27000018518C90C0A95051B224053A040233830123246C0908D990201C4426900954594A070E218112409251AC5908C2602830225D0487124B90D9C024689B08461146C62404D1B45440C886DA2080A9826895AA46980004E8A308E19032DD8C88511394549948101B225D330690B440C52862D12979048206A0C041163C808D8A60189B0691A858118882511158E0337108B200D82B229E184718304300B298A00A4610A1522091748D13006DA262560342E133461A2182A12B885502810989408C3941118A10D0A102A91162849906924348AD9C441A004010CA521E10610110968DAB28D08A801C4A24421C37122B570D394710BA700A1962194886D0A1802A2240C10900910A57020A86D6130918A04290B474020C6288490204B4648518420CAC404D186440A257010460282A6101A0166534804E1A04CC2423208C54148C07080160093B220083382584440D490648234868C04309244628120620A154198122803340520084AE4122D189349149565A4C8015B184299800502A330600486DC026C8A488184085103298188928DA2480D624065213371C0088699822CA332920402821244649A4260100131A34040C3B8291B130142801022C2200CB131142885E390858C24664834451CA231CB1408232506D0982DCA166A1A982950C26D128065C2306824174414496400B36CC9022A0C1704531225E32808C114021B18049C340D44488904302D4A242E1036325B34104B401044A8881080290AB16C1C9871C44606CCC81042268062248058B08024476189A43020C67093042C94986523496689C481A1446EA3866C5B46325236509BC28C23248622B39120228D13040E98B28519B02D1440681A230E03C92D521829003170D410441CB760C132490385305412058336021394911815204A106A6218259A883143064C839028D9B06C42482E4C286CE4C88018148D4B06514B8280DBC67001A8280A394908B86DC106451C0866C892091024521408621A27901200691249658B4852C1140E24488ED4446CE096715A347241800964884D53A4708A36890CB964244391082305098325A0000652965010054DC93671C1B0444338824C42914C16901A314101014212232A09882C9826300189440293312484281B8525A3468448141081A065043169811872910402A4364C5B348821354982209083C02123942943282043A8092437881B454D48880840122521004A93367012840D14A0055A188A43168601828C11352C04312A00046409054D1816300A0849A2B67124128410B545DA228DDA380E44B44C61002452A46CD406122484604B148480428EE14400DCB288C200915C141011334151980158084ED1887058B02904810544C84449B6881005310C132DD2145114008959282D63404204042A84160D9C1245481091A4482D9A1032E1883101302E14120409B25109B084E486600B4429D4A88003932CD822001CA721DC8680921849D80242021844204601CB2090C43428C314500B18090B9061424426CB288DCCB845839431C010304124319C304ED4C82CE3440E24427201230D23C80524216C8CA48D528669C2060808140A0098201B13684218655C381004C31121B5715B242EA216698B1040530490030441A4164DCB483049286860200DC84412030324CA060D242202DC3082132511119411DA36905224468C286421C3505324859A462A13C72C403272DC9260508240D20624E833A3104705DC227A3AD315484B9EC824A82F500712D61D5693BEB0E024505429B4D136758D53F67E6A5C66C247B3D03D763B77C17CA1632E2B0FEA3CBAD528695E70753FB16A0727C6031DA837CE9D9F7AE12A7F091E8E246CFAE2955424255667155384E6BE2A03689BFCA5E1C58C7F16187AFADB4CE28E2F9432F2419173A4CCB0154D7F3443A15DA2687E608C02D6392EE3942159C2996700070C00A194D27BCB61945E04A94E95F60709E59DD49CE955044CADEDA9EE37FC28ED3F3EF89FB5F03B77C6EFE685706B85A1ED1E810195507A55023A2D1CF2A0A9E78801DE90E1C7B80133B0A7AA8E17C022B574B3D9503EC2E152A4C04564C9CD4F84B8B8342359EDC28A7578F5AA73F5A480DAF80F9831E3A1C102BFE8DCCDC4621AE89409FCF986B53DF21425C9CE4C9744B65F706AD99B975E9907F2C8B5228E072241CC1C25111F5455FDCDE4D72A28402C2DBE6D730F588387E7265DF3E8B3B6C78E0AC3A5A2839F1E2E021843BD0BFF9C71C47A0BB0DE3AEB0E99845821B10949EA2C72447C64BFAA143220156FB54C9A62F6EAD3D534CA9568457277AB8EBA9E8EE5F3F42849C8E661AF178461663FFBE17F78D41C830F3342EF799F97C6B0E848A96C4606F4B404C382F5CE9B36E3CE90361C4E8A7665736E0C5ABD625BC4E1D1F3FAF90A366E3D3D9606C8FDBFDEE49DF2CED8FA268E6CA4CE20E3F4C962CF85E37BCA06F6385072280E5F5533711B2E676946813083FEC5D6E2CDCE4F4DA6F58A6BAA13FB159C6D8F33B6FA8ECDC0E792F72F64766027DE385C3060F38466BD93C8ED981CD3F7EF7B81FB78D76E6BBFDD565DCE1B018372102D0BB8537C1E60B1BBB564D6D98E45108D45139C71A96AC788CA14F08837E200DC1F593A19337E518C18E40C4382ABCB486677804D44B31DAE664959D908C4611ECD2F657D46B72F009AFE3501AD50BC49AB94EA2CB36A07FBFE8E87D5337841BA123FD8AA72CC9A4AFF0235F4EC2B08796DB4878A9F3939834C324E4E0D37A9C5C59153811F21AB57B260E9E57441298EE7032C819DCC475236ADC4EBFC1C5B26778B7156C3D37667C8EBEA75477F3FAC495FFFE7651627C6C87EC7CDCB60A3692EF2AC72A8820225DA85A5161B4C7274DB3698F5F1A92E197F99689B8FF5970DAD8776550038EF55825E4E0C00CC148DAEFDE552BE9BE94C351069153A3148B30C1FD9E9FB6E962A9A8824A1FFF238395B61C422CF56013BEF428638F961BCA565E5F4BBED2831769EABDC0BB3F5729BA331CAF666DBCB7AA15463A4D0CBCB26132F598789C96314F5B51F34B9A0F48DE75DDA95E2D294589EF30D43E7C44CFA63865123DD3ED045038A8ED261007374D096A46758138B7E112A58482BC3F7B14A83B7CE7B5C219B8A16ABA3514E779DAD6BF06A3B530E6C2A2E5C81D1C6152A63AE3D1159F4BEEAF8D57F6670CB15091CA10200D7A76364D1A48582DF316B7C65FD0816096FE238360B291772F8EDDC6380465261108B53F3C7EEE33C5950C76A87ECC41E86432AC231966DAB8A0C1FF9FE593F98FE34625901CFDF163E113730232E98F00FBBFC068028CAA132F071A828BCFE78F52713DF0F7EF903D5EE10F272CA06EF94BB1AACEEE6A9B89D459B48A5D580B085E844AE3DD20B866796492B526FAC2028DECC362A7FF42CDF73A827E2EBC3712A15DDAE09EB26E57CE61211A7E108B8C588EDAAAA165C2AD916EE80162024A29B6546AC6CA73FA09EC898E93FC399ABFF13DE4E4DD22227105E207DB1C50855079FD96383B3BD50C32C3D1E37B8BDE972683453C3F9632749A84A93CB34CC130070E51FC0D00CF504D9FEB9A8F068D4A1D7AC648C8AE47DC54824A69506189861E6838A0B08E13A13FDEC95F9148F2610084E4BD56BAA4E30B39862F86CA9600B9A3A945A7499F391879390419782D2934D45636013AF6B23A7E072B393E6F4E62140146AB55C9766B872050E085C152C79DFFE2240CAAE43FECE88B4C44791ABAC91635CD3BF47981B65215F36AFC2ED63F6A9F56AF736C2A0651A6C9208C3720C8D5F48A0B42C7ADC7F6161DEE6EB2AF5270612932F7ED33E2EDDDC61C4F3B291D42FD90D2F28B64D26863B07E5A2C445167C7EA3CA8E9D07FF0D44795903416110051D4DD9C481124A99ED2DBEA7F59C714AF50A15F6FE518277A3C9B17D71B4265BFD2ABE06FEE2E27109BE2E53D1D5C9D287B383FE32500148C5158CBC6932F6684B07FA33E122D1406A1E313C0F5A9901E82CE5224E31CCD04D31058B4BF53D2E15322C0C8EC177C6D15A250FBD3474EB9D255F548253505C979E65E671A6B7D1A60876254314F1329BFAA0E5E8BC8882F6BAA9D5442C38E0A5C15C2A61F92D2063385827CF052553A352922F9CB6C035D1CC5E15E2625FAAA6FFA2E4954F31CA10B18A3ACE08C122F826CB33F9D6995C12CEA96766CAFAE5F32A381958EDED4904C12EF43D66BFC7B08CE8FD61D42FA3F6F91ED1453AFFF2819559A385B932C484530D33BCB406BB87BAC9EB3F338D77B506CE59C6CD59CEA376ADE92B9D2587D8987FAEA9F0C707900BD649C5B81E0D46C17D467928A2CB9C53AAF0C55CF27FA09673BC6A6A031402126A163C4EDA10AFA09477F8ABECC81A49334B14CCFDE2FE4759EE15FF7D7D0D60111269ACA4ED68FAB56DE7B6F10CFE2C7A0E6DC968C8F90444D535AA34C1DCEA03C84F1DDC7C392868EB07289C4DE14CD53D5C7A1B768B312F6E238E2FA6B93BBF14FF286DA3DCF9CF95583917AADC02DDAE785299907BBCB06D559A04FE1DBCC75FEDAB0E42231F6225C9C5761E4F7603F87DDCA8AF1CA9424D36324659E2D249D7A83FC187B41434CB7FDB08F7AAD100DD2D29E66CF8188EFD1B3ACDE47B281BE8974C255FDA49CBD06E55596CF3E387430FC67F8FCC4B82101CFC11184B3E16E62F18A4355AC5C6F84BEFF3AFC12075B3BA48ADDA38CD6FBC04346EEA24AC60F2B527AE8F3B61EC32EDF64D273322326C2BDFD441BA40ED87852A0E8FD197A7E7E05117AAA639692C35CA5AC4DF9B590DABB9806122B31047AA33B30BA68CB405E539CF9927B6F942465DADB9F4F70218FA95565E2290FFCE4D77D122C1148E0AFACF3C1CF89AAF85DB4F06C48566166AAD370EFA52A95FDB52BF5E55FCF577D43B0C2C5DFCEBEE16BD4A0A426E84AB1FB018B6D701EF4981DE257E2D1096E206435DB0E52DDEC81CA2F8E16DEF12D411329A1B0CC3C3E5474F452D20C2EBE9B219DA00CA07B8FE5A14E56E8DA3EFEB1539EA9F2ED9C7474DB12B93C744322746AE42D777F22E1435D5B9C867F29C2BE6316A0941BAA39BCCAB41C9A7B5FB4C918F6BFA1FA76FF242A2514AB5E4A7B8D65CF15BD4336D151BB374D7906DBD3A187D02C4BDC33BF26448085F7D66ACED1BD6E8E67F4B3DA551CC68A4C493AE35AF18F7DB09133EC0692AB08D6DF34F1FBE23491467B5457BD831BE4F76830774BCA5131CD539F47FBC5E6F041B01EFB6A7E586A02742D50AFE17986A3AD7B20524F9C1D2825BEECC5A2AA757A299C46F852D46834EC67AA048832BB46D76C7D752150854B8689A5D0A501D419E5269E34C13464F37FEF2613BA45EAEF5083F7F699213121456E5AAD50722E8965B78843280DBD07CE3267912BA2FC59AED7540CB9C6B464B1F983892C34C1E2149ED712F8A56B2C6AEF7996D45A4AA3A6EA833D5DC471BF3E9A47E83572EBDAFA3D3DA7D930A05501F0C9B6EEE0FBC9CDF86190C52851AC7961C36688F8BC11A39251ED1E2F1528F98FA360CAFF6C1F2DEEBD712DC1EE31A4B5BC819AE169338E4DE7BAA00224CE4F460E25D2586BE63AF29705D98705840930E64EA0A9D7FFFFABA09869D78A0E3866A137A412AF4FD5A5E671B735FF456C79E24BEE529DC0706C065E0C6D8BE32535DBA578F36630E6C3EBC3C69B6FAB135A530B4281D40CEFF4FAFA364CA274CCFFE3F8D16DCC2AA7835C7F7E7A376E16ADFB940A2725B64EC782FC5F0C36E5F990807DB90E6D1C6869D6406A07CFC0B84A2A3C1A4E1585D854BDC2B506EC8427940299A9B19B2FE3116FD4A0BDEDE83EF42741262E7A9CF4393C2DD8A7E60297CB76157C861ADE284D44E73447186AC00B064B5E02568716565648CA88623E16EBB81C00D4377FDDE04259AD5CDB9C8FF75C4C8AC2D4F96485FBD353130548637235D100A646FADD5341927CCD114CD6095E97C622F02AADF7FB634879DD0614EF0ED2BECDB5A15F2B05100D97BFB128407FD8D54A6FB35DAF2B206DCB2634C2B14B33A96F7DEBC9925052B075340F48A096BCEB99E4A0DD1F9A35E8CC14EC724AC3ED3EB512E1CCFBDE1D755B1B3A3F63A66573946052022A89838A61DDC0D4E2A34F3C2067BC51AC14DB95DA6EB7C31505C7872620DB5C1B623A92C91B895A65EAE4938D3F823DF37FEF1964A71DFA1F6EE034F7C07772835CBB43465AFB6EF5BCAC326FADF26F762DEBE12432EDC8E53390EA89334E9BE32E535C5077D6E77684A1F51B1BE2F28BA4DFC42FDD63E88296262CF0C66220DB4A88169CA24B4F8F1135A50F9696C0ACBF3C2D3B345010E43230DD4F3044B2C39B91A242505EE5B2F690972FEA4526A3F473839763021A620830384645B9BBA9947BA6BAB37A1727DD94BA14AA9EF039023BBB46DE81337011DCC78B8BA6F9BF3F92EDBDF55B0F9C7B0942E397EEE1EC85719C4", - "message": "506462786389055DE2E4AA2A7C80388315711A7B5DCC73F2039DB99380D48D9A3DD8CC8B929B0AB224DAE74EA90808C302197EE9D847261DEFF4136D3B2A37CA32533384443B9D935AF2C384EA63E7160BF4BEB89EC0EE705D10C72F2F65A4E75ED2B1901F14B8C1D21DA9C6B8842DB62443D3DF12969CE4E45298FCFD6FB103B87B0817190C5ADED4D04E3BA4D2C3F60CC49FE0695D6366EACB9C79F28C9121584D997B7A3A7AC3243C3C75FC86AF81CC8B888E90095051F7825294CF7E1A11464BC153548F8195522FEAB9AF5AE93C5F6CF80D9ED76C19A0ED0BFBCFCDF30FF6EBD0E5C20EEEC4992765FD23F13F027E2261C38D11FD1631846142541ABCB82C0EABEE5D675EC130861F9BEE9D9E02305F168C85201DA1DA2E4D21CF1E4BB8C2539BC1F3706194AEE7E3ABB2D7447EA531619FD27F0CC7D09E5FBFFB0DA81432D173321C433391FEE90B92E8EE3F39ED492E78327D8A3586B7052602607EBA79CC9AF21132C7D3A9931D5DB4937FD5C5611F79C722E0CDC48564E416DD251C46C02567C4059A0DC2F59A124A4EBAEB9B1B04277CC47A9F345FF8AC3F8AC844A668AC6F7E1BF1C9889C3E42C1142CBC31A46EDE21CC84F230A483B5CE23A901375B27770BEC8F0AFA25F301B7AB43B714C6D0E98B009FCDDFB75C0E26EBEF7C9DF5ED04CB4183028DFADFC09963AA8CB3A9A1BDA047F62460F2B88FEE1C05D9E68D646137F660B68470308225FFC097474B2B2BC5D50A025724FB2CF70873BE7D04C05AFBF1D7DED56693AA4A4E495B1FAF9762DB83DDA6E75F530ED5351D171B7BD06E5ADF46DEAD06AEA37CF262AA33D062141F8E394E731B3942D084E583090F9CADF87C2B81C4B7F114D150C221A12393BAB92727B828C9EB86600B969E1B80F33E1304CEC68A1B3B474762175EA19A4D67220004FD4EB0B2C643B69C00FF3876E9AF63BBEF8AB6BBBE247668DA8F2E3CFD0B95D6926AA3A2CFF4587C45DA60BDB03DA78DDD9758FCF9926FA1F080A61FC0FC7660BDE9B4913C40534887B04E2DC666E981AEEE38746C52BF46FCE0E2233CE02C9307262499BE567C150CC54FB9D96B81D3A3E200EC8F7E87E28272E7B956600DD7692799473A8C63AEDBC8F3F43542B9E399398349B896BBA16E5F26210558DDFFB984FC924E1B0D272CB8834B1FF641A894EC113460C65C66BAE86248B48F675F1313EA76EB4DD0AB6EE41014FD7589D1A7DAB16CB8F113A3FBE7E01EC67B0B3CCD81C0A8C7E9824658C926736A574E9A0729C3BFCC34E0D4BCB1606E93287494577A6C4B1090FA6B997DA098C6CF555B5574473B1063B739CCD139C2541CC3F962EC42BFB3A40F4E64D322836EADA5F574B48B5722D7809A3A20EF1FDF5F3EBC000E466BC4CA10E0CC6A1390FDF159BCF0182293D9C408A8570789C485DBB977642074C869960E9648641C2A80D8A1C4E474FB98D7A3DD75D7AF01D2605945E89493699EB53E30EBB0F936B63ADF5859D9EA1DCAC44D0BCDBF2A069982BE907F1B560AD8327BAE013FBFE6E2709C9FDD498491F1D8603F9F6C9B1A643F6FAB97DCA752D9BDA1DD6BDBF52B03ED7768D98E46092D556C266E30C77A10E68AF76AC3D359D8752E2453B2E75DFECE6F66E6AB00EF37DA6E6A367FC808E1F4905339F4FA73545D13DA7E7DE49CC0A2A63639A96EA039C4EB643627B7EC4FACA1374EA800A505A80F554B3AB3233FA492ED6C17B5832BDEFB3A99FF1C64B35F1531A023415290124EEE2C9A7E34FE8563528B6A4B64DE425A8FFA91B753973CF0C96FB2A8A3F71D58B77C93C5866DF5CB5152B3A0A32884E349C63870E9CACA82F121EC2ACAD7B6052B0D74E9C28B20C76A7A821D192E11B59A7C8059FC49662C655551A7356046D46FCCCEB4DE1F5FC91F35B950F630D743C8218A10AB25D2FAC25308225540FC24CA794EF171DAD7258C2B7FCF43297F6E77A6E83184114DBDBE408EB644ECF49E04FD79769E4FE9B0530F21F8E3913A51094D0E49DF012144EFEC415B8B2A34AE2462607E7B89BB86F0C733A5553CAAFF9B19E0799A1901657BF4FF5AD6DA7886B477358E90D56BEAC6A963E0669C38EF47173503B0E9255AF1F153E673813053A899418E2BF217D01D9162C073F256CEDB73DC062D201FF6056180A8A6887B286AD6D3BD6B1462231D6223D0DF2BBB7299FA6FEFAA9A297C56ACA28E163533406141EB2E65F0C94A6286A0579C76A3A8EF96DDDAC9DC6A550538AD345FC4AABEBAC04682D4AB0977D439CB14F02FB504E10252C1F3ED01A7C4BFDA6E689D842D9B9086517A84AA4257D1C8CB842E15DFA615D2E3F2464E4012C0067EEE60489C044F43050E5B1AB3E54507422E1368CB3EC8CFB03A887DDF9695AD95378F875F14F7DEECFA54A775C60C6B7025E5D6C0563E0E76C05C93E33C3E5AB6D1E1C051B52D2805D3BE0A4D3E8F0DCE6BBA1DF04C7F76F7E13D8C3CFCB2AB04A1E605D4DAD72A43D5223FCC36EFB34D999095E742FB9DD7B69A28E070FD28138B403DF1DCA75E00A160ECE9562C92091DFD3A24C53645DED8E17B39D8CCA4C20C96F9C9F9D14AD3B45A1E87DA75B831D400AC14BF34A9840936C3277A135BC0E8C65E0F5E670AC912FA586FBB4E149B09F64D338C8C886BA65730039B5DCD0DCAD9D6EF11C228213438A1489F4FDC39395E8447212599BEB570D186883E02B442F8BF97884EF98D3D6E59254B3DDB77DEB8429D110F0689715F3E0A4F65908E5EEC867AC7BBF27CFB965727AF0A1EF37B21EC18CD60A1C87287527BCBF5249596083069315699CAD10FFEB2D87810C4DA090074FB26978E56B7D06186C48BFA4830A0BFCEF8FC7B95E73F64EFF78043E8D93F57EF6DC636C8FF612ED22FB21174EDAA59BCF89D1A60F0E1C15C5F8EB8E6A39139D500E8F28A5DB86C125C6C76A99BC47DAF66E679121557D85F5093806B748B3EA65CAC386B59C0A372AF2FB7C84111F0E0FA2C71E137958239534C4A012B1B421435B7BB8CA577DCD8C8B0A798902BAC9B95AB87B6A0735D1839DEE336996C2357C748F4EDAD858C81E2115595ADBC173782E36D4E720A5D29A5681231F9BEE91D455554A8632F7F02FAFAC0FD9D03804B10DDF4828A69AC1CF0581D2C88877BA30EF2982E0827147766F8B71E264E82C3949BB87562F810DE835CCF78A7E5FAB219E64B1FC615E7C952577B9B482F78C0D0C512833994895A125F43EFF066CEE293004E9E0E5288A61EF209EC52233EC64BC0DE76C78EB2678559724FBC05BB5B43CDBE86F6C481AF3BDA11EBFC0FB384AE00F4ABC212B0518644638F01C38030DD05FB06A7EDC6406CA18878DF38ACE8E974123D3699613ED46673BD04ED51C352F124A8F89DF8C13D2B44245084B7FA02677D5287D22102AEF4A4A0AE046BB1C6D9FC9733AE5066C69A10589B0F33780622C1709F179D4E8857564804BF5C4D83E03484FDBD1CC4D71C6A2421AA59043DA85F0B51EF91FA5DF9555072278331BF3102F5147021662D135F3011FA48DDA7C97087F01B7F86D549F41E244AD7374C7C1F698801CEAD305026D17666435217799A4A5FD0ADDF9B8BF6E31E51B654E4D697554D5F574213CF579EFB1B11CB2C136FDB9EBC0DE4D16DC9DF43E17D88EE22EC88326F65875439066CB47E4C656A3AC59BD9A576D05ECAC5B3E7AB7B1A3C0C1C48807C06F1AE4881158D6BAE9620B08BBFFCB9940B6A6D04396014CFD54E93D863156D16F6F9C1556DB1E13E630326C8B681CAAD146F32B6977200B204B632F6CBCFB2BCE9670D89A9CE043E2004773913188608455FA715D1577E03826A2471EF0143DB3C39E03D890F0CBC85040D1675821D282822F80EAAEFF5CAA49699B68B89422D1BEDBC3041AE2A3D6D5205C72123991B21AFFB312F5EC8F96922EBB44D7A0F8ACC2E390F9E3FD82353276D73E85FEC904AE6319B140E5C54FD5B6F19D17E65DAC5EE270DB3E402534B0F408BB3C554D93BBD32B255D478F33BEDF4A192233294B320393D38284D7D9987708C019742F2FC023C041219FBFE2B603501629BDABB9C4223F5B751DB78C144CC50D3A35370EE563D6DDECFD6D715F08E14A00FC265D8433055083048396F1BD4E9F010EFB974D6102401B2FECD972C26008A4B94952EBC61C35DC846FF7B3E20DD9C6E033BF1185F35A5F02139068E1D4F30C4778FF87057F34CE1D2D40BB61423EC055BB57B56C502DB8D0685B0ADA42F9C52B590610CE2F8237F92B71B3AC2AB75D2E6ABBDBAA1E554D99CDB687B72DE98ED0FCD618AF5D2B0196F1D3C19DB77686F01228C3D1DAB1F171A56DF9311939CCED0F7B22A1B77F473E8DB65C0FD6E307B6F7A0F0FAD69E5C1F87D01EA4699F4D5DE39880CF2D8E910313AA6026C17941C41252C06687A085903A502048726AE8EDDD2D8918B71A19B807889B6C2E866FB818810F427D2A7B6CB137D94746A88BBF068EAD31216A5511A54D81031D36C8139776E0FE29EF7C8A5EAA730C3BBF05988BB892F699F72F098F2931F9B4DA17243404F64C311767A98547284063D44AE74735DD246B0C189DB322058198F1D176EAE6E076965CDE68DD0DF2B284D23B94BADAFB8650F21B148B9C990F7044A777F9BD229F7905B242CC2E267610A42A5C3185C64079DB340D86598C589F9A96F3741356BF3E6D2A811B6551850F917E07E5289A07382B8B506C510C9396DDA81DB336179EAC1F84DB9D0E7BF52B906E82FD132647A84A299BA202DEB338B79F976A8D257E246B2B1B60425161C72D534B04355B2665129AD8A44C09D73AF51DEE7043228EDB62B858399B5A4312DDD7ABDA09A846A60FDA8D0C00E0ECC364A6CA95643FAED93D44BC8BF1264FAFA6D98528CD3BD1BFA352BFE1FBCC202F44496FDAF9F9EC53007915EB67F9F8BFBC88D82100210CD471C48F5092AF4253302475F9E60C287F0A8549DA00538432A342814E1F6043BA4355D72268F6E84A43264EEC3CAC024DD6E79143EB502A58E6F8478AE985797F00A295E84A0F669BD9252A3AAC6B2AFACD7AD398DF546", - "signature": "C1023740D113A2AA12CAC8BC94DFF2FDD05E5A70F45818FE3113DA3D727C8F99F9268FB99F75F98D3F9487A4084175064A4C06548D37E8FB76ECAE0B8613BB804C9C04ABC54570FDDFA0C938A339F5134C5C37D7FAA2037118ABB9D1FBC522A334AFE43E529EF3DA76AEE24B27EDCF98430CBEDB46EFF55E9F53FA479F60C95ED0FCDC31666CF15AF8EB6D4B870BF0FBED290860ABF033C9743CC8544B02C8F85BEEA3817909B39D3D68049E6383EFF3677D2B94830073AAA44EF9B056FC1C316A2B9B94D347EC2A551F65F540068D6F787786BFE45EE254663D6B99DC1A8E32620451A839C9C7B6D637B993F2906287EC8A0F270EB23E99263510BBD7364561D56FA3E73D87F0C5632983B63C9915CA85A6C38970CD6EE1041E7307A797094EDEC1F84D947EE2E4542B3865237C60AC5125F7515C805730F07D2562D76EEB5DEED5E3AA000E38D00A64E754163A42CD2508E496E02F7FB7C1078AEB7D673680EF47EC7D8F1130E4D61F631D6B6D43244345322F3766F1E246DA51438C265F66BFAD6C20A4FA0A462395BF7408B14A0791C21BA5C307FD38414B2B8DE07D4B134342A9C12CF170D3DDBA18BE378D52963514ADE5F9EBE135D86F0AEEEDCCED7729E2AA25456CA85ACBD18BCB8B79E97DB56AD29D94BC295F1F89EB9D8E71FA14B1BCAA46B8035C4AA25D14DE7C35BB5A02CABEA4EDF9F090873906906F68A13396CD2124410EECADCF085D5925BF6308DDAC2242CE240893CA7054C4B4C19332F4ACA897BE8F998D83E82944DAB9D65125085176CF5CDBF60EEF8954428EA0ACCC6A7FBBBAA9DB34AE72B93BF5D3A709CE3CA346644D5FAFAF3FDBF9D9D7C504E86371E0DEC5B3E2EE120E064CBF4FCD455E99207549D27E233D06FCAE3699BD34D5D7F195509601154044EB3EAA0527DAB3F9BEDBB316023AD53FEB71249F0BCD3A08F0CDB9878403C1812D36883DC444089999FAF16A40B75679E2F053E6EA2B835DB463C1202050FAE236134BCC8703397E1CC344CA7901295D3AF28B39853758D086561AB9A6A9904BAEB37C2AF4D973B702850BF0FCB08CDC48D582238A0FA0AAADF832AE76420439BF29A9B32FDE6D67D3D6B25EEB521218B013AD3408AF36C466F67FC5722D4EB2E57D0E58D045D46592BB1FE907D56E0B378FF59DF68B2819D21BFC686364DFE074764DB8613DF0BD35A919048A2CFAFDED34CD3331124E8C5F8811D730803845C7CE568E66F9E50A1EE2DF92450321BA09AD2C4D75D1D92CACA21A2737672559B1B1894130472F40C177F1CEB1C348EE8AAD47B5D1ABFE148877C39A0A46B8F9E4D3FBEF95B774AB5D768FE130711A9DD9EA2B8F4DB4E7F938352772ECB46E9A00A9479C409A4F9E4526DC307BAF5C3A0493EC9E1816D11CE212E0054501D2CD9865F6E942856D32B971E83C81D94DA4F584B230491D2013E84C898386F55C8F224BB09FFE58CBD0D9E9D7E21BDC2AC4335E2FF94EC95CE2D509CFA5EE33BA848D75D046D8F576237417701A7B11B3E67BB9740B7BA3D7A37784E6CE081D3F41E8AF21CB46D46B083796A08721B7E80F0A157E86BE0F08D3125A12F4733F8C27236AA898E6E950BE190A931D07A08597633F5187767D3CFC095D1886769E1CBDF6C20FFE471E9396476660DCD21877D799A124A2F0251128F08F9D45AD45F0DF38FC9A42CBF4EC4BE10ED87FD86B63DFFC5246239517690696EE839A501EE221C16A153C0800E7D6B4385F6ACFBCDA62981CD22F06A12497B97D13C6EC1F39879B2432BFE6FC7CB3CFA78DEC8B3B800916CE777BE327641DEA9E7F156EF6E943161F78466C0300A29B1B5EE8CB68F532176DF4FCCF606738A95B3224573D5DC26F90DA69146BC8FA37D1917E3CF3336FE8D444B606979D9650B2649B1F016F6B9543E31C6E9F48594F538CBECE25C4EB8F78955BDC88EB9540BF7AA4AAF1E51DA958EA818A8DC9008FFAD91529B4D8AD5576EE1CB21216136A0C85BA87C01B8A0E8B9B31F7826537A0F920F335CE24053500CCC4EFDFE3742B9403ED950D61BB27FABD1E397BCD6CDF885DA0E3559B21197BE6FC71B25DAE1C4B51DB765C154E4F313A6EA4BD79144CDDEAA94AAA9AD40D0167C5779F022116E56154F74F42D67540D8D0988A5869FB30ED2EAEBC4B0D80E1A547551BFA5D77A695094162557B76D52472A1601884331C9A0EBE0405FA61E5F5B38278EE11A315B20633F534115C02114B24D07A343003E2730BC17BE1F4432B617D0BC160BC2249E7B87A4A4C0B8DA3C6F082C8D515DA2E90FEB30852FB35D2A19A0A39C4C44561703C97C0B660A05FDC553DBFB21271011BBA5D4ABD2C8B757BF022C6225D401A56A33C901961DC765626B1607443368D2BC37886EA65B35A9378923B9F6D2962B1DA2A4DB3250928E2DE09DDB7C2B6D27EFA33A21FBD7C3C38B6B193A1AEFCEEF9AF68FAB8F87D20E1FA1DE0AF8E40BD00AB5C88573F2FB1FAE76028EF40793EFB36D92091A353F6B044603711514C4E5288BDA0DFE9BB6E10BE6FF42705FAC7C05DF1E49C7C93B464C4F3571821378B3AB9BF020999B2421F6BDD98DCAE5F976EF507B9E0A02E1F7C7BCCEE1849403F2FA5851D8000AB7933AD568313771A436CDF40909360A33D83D42ED1D2D5DD1D1BF4AF704646DF4178D83B3031D9DEF090CC6271DF522FC4013E049D031DD504856D217E9E79F5359421EC1D3F77138F3E2CA07FC83FCF72066AD407C27A80D48A484285ADCB8114BB6D98CE6863428D3D378E5C1132E0139CF6DD841230AC0D5F0240C589FA66D6EF1380C9C2F5D9482C0E387DFDCF966EC364FC614CE707EDF8E16C783E22F8FF29A31791861F70B3DD487B4C72D5658D436FA5B3426CE337214E705489798753666B47CF8591B608A28871239BECF722BD726C0029DD7B8C72BB2F7D60CA8D2A8091749686B62BD642F55AEC9777AFA52BE3ABEE6FE5ED2258D6FA3A9A1B55B7A263287A8A52EFDAA0A817F410FE325B16A1BE3B70CCBC50EEC72A70C27CFEA321005FD982EC093D87286FE7A46822D640893334BFA932BB62AD41B4BC88D87EF1890C24907BCA4136C5BCCE546B5470038E5D70D177E7F33B0571FAEB48165F94AFF353CFD315C303CDE5098093BA39052FB1ADF904F1C117503C58A7A991F9FA1422190E0A4952374D624C7D9ADCEB0F124111000047CB5662EB71B6325528C72C1D82F0459A2BED71982CCF84DE2434A4A7DEF2C1210308DC1FAE705360DE9BBE42E9F9204044C99EFE50361BB84DB15657E3B85C7E7E4D298A34933FFB5754CE06B2CA1F6F7599790962B0E77641567AD3DFF95DAD0315DC6CBB3D29EBC8F3B68089140BA87063B21E45C3B1AD5DC6972A7A65C711301C05AB5E48F31F031EE939740EAB8CB8DE627445EC5219116D3A43FDDDD91A967A400F149399B9A82FC54C0D629A349C84085A3D30EFE9AC4381B7C8B24501BCE8F827F27CD507BE20018DFDC9343DC5282F61D74E4B4CBFEDFBE33A3CC67A210BE8E012C8277FB202608E96C355BFFD3B4FBBCECB65B7D4A61C1B9463A7F6F732B5F73A51B01596CC650EBAEC8DD40C7C3ECA3F95AC010DD275D6CB419BE78CC107B6D0DC2C060F57A8D7E4BCD53289CC57F5FE0B0831F93024148D60CB87201335F4DDEC3EAA0D749C04D08C345C0ED169DD4AF598169990CC2C8CA3986660712D615C084331030FEAA5078C0C28D3432E9B1DC5B4F48F508417D588A5CAB2DEF9DB601E0FB6975FA0E9D681C84AED7B5364E192F4847D1090924E6463E527B1185DEBFC376E0EF221D55D0DD556C6468E56D09609484391981DFAA3558CA8B35806E4CBF48489EBE0D23A9A035C52BCB4839DA20BCC6939463E4B03FBB7382E435B97C7A53A48183AAE0A8095D9E04D750535292E6F5293B5E75E6065510537DA2E919E2172D232586865070551EC02ACE7DB95E75D3B321CBC233D5D48B5EEED7E93D9FCFAA378DA92B704F9FF3C992DE34713BAFCC3C38D672194D314A3CCE47DF297C739CF7DB273EFA474D436CFE109BE692E1EA8786F703D81ED2928CA69F38F45D819B08FB8BF9213DDCB2AA24B9E50CE9421ADFF3FDA75A95E3948803FEA3AF80E59C7AECC594B2E11F35A37B9B9C684B5977E5A4A0F9DB7C89772DC17B2D2902DC6B409937934CAF22C27FC38EA4E35F2AA64D6193AB2B340B63201C82F91C20E4BB631D684321C0EED29925FFE916CCE3F403C6364F827497350274F12B405D8BDD2E9FA56F088117B1F682D98AF2A8BFAE4F4B3B1A0626632F55E747A40B1CDD8DF9665834BAA353413DF698C5AFA6AD56EB8AFA9EA22E6B042F6016F803201E974E8E1A19FB5DC9B6210C192196C97B2B4FC0FB24441A6CFF898691E948D0082DD19F72BE037BD4F48D553280708F41A7DF37C6C6130C9C02D540DB3F6CF1AF3E1878E57F267D08F4E761B5DDD7D0276726FA942328A4393A2AA9FC25F6F4B531CD5C32E92D1436DF8E1491283318445D4F0BC81830B3A1B016E02A885751C65044610D24771A9E5F72BB3B62AF913B923DD1FF09DDC7E5077F6B91B19B9E7D552372E81C05B34799814E839C4C62FD8F7A010073DFE851F273E1AD4516B4D8F8389951E47B10BE213B553C76F6BAD8F19EC88A8D6D098F7CACA69DE23B9BA40AE8862981F3DE150207A55FC474ED195A596D96C64FB3A6CE439A89F350FA24B93EC74D4AB8793AA28C3C7701B0E6A301B00C4B384B49CE713F439F853CF204CE46A330695D640F1243165AE0721E2499483E879636CD5C6126EFAF822A21A4BD77FC6B067345715D879F29B41D53B3CCE27C21B68B2A46D14D99B34AF1A6317439E52C8BC1F3A6A83B108381BB2EB80991A1EA80687D61ABAEC2895BFD9DCFBD45E3B34FCBD031446AEBDEA38179533EA7E3D15C579D3B485EDD7778105717DCB70A727A572A978DEA742C0BD05836497AD40A39BD5AA945C942512654884015B32B920EFCCE1EB74BE65B50FFB9FEE543C953A8D586B718746C4214F0544E66D60E6E78F8C3EF6FA35344E5147CF861AD2A928C451D00B35FB6FAC2CB3910F214FAEEFE59CFC099B8E020CEC68ED87957512BAB2CECFA9AE8D5244A6637CE8B2ECC60417D674C10665DE5DC64392E3E0E525CE8CE3877E9C0C9A34B2768AD41206C3E172671E9D89556013CC22BC06B74BE25C6856E89EED22D7D9BF8E3F6AD3B43D9BF966EC521BC6424A9F45E5D459B5D6370CE73312EB766BC89B2C283FB59FAD9F857FDD67F599D71E78827834AFE8CF5A002659CE0B4CC03609321C8398B651C6D1EEA2224A0E54B819C9C867116D5C7E00C588C38AFECBBF35CBF5894130F9FEA689D6389CE65D77B16DB62AE9B8E2E68AC9299AA3AF4DD65FB70F2DC3F01B1EDE3D75D61FF92F8FC3E0FCB6C2F3D06A401AA67C445CB80F045B9A7B79DE15BB997A5ADE3BCFFD8F70738E61415A252E91FEAD291303EDA176D9B9004A6107F8C0C4CC29AD478099BBDE92A5C95B35559065AFFE7B5A2D65E7A85E95FD79302B229EA40A516CA45D320DF15E7F835B0A1F05813A5706B6B73E50121758259DAA790DC21EBFC25C45934717792B46215088AC8CF99857FDB20D985C3DC1BF052F4183D895A55237C34B2F0893F091BBED221B68902A469CD505E6F3EC768823135666DBFAC1CCAD86C149D68BF8D86CF9EFD6007EBEEF7973F6DE09C298637C7FA4ADF1A2159B07425B1636DC4CCA613278CAAAC7B6071C8ADC69DE93DDEC276443C8B284B7A0BB8B38B648171A9066CB6A7F868B6204AEEFB10C26D3774DC290C39CF87E7E9B9FC164E4D52CF5E3F48381C0E9E606FD0B2EBEFF0888F94B3EDCF2414F9D922AC26C75894E61721C18B6C381CCFDB847419CDAB84F3FD033ADA263777F36E07C38EAB79C28ECD65C3623E25479E3E3CCC109F7AB3F1FC3FB2D3529D722AF9A14B3A1D553F009364EFC462B3629E077E918674DABB948CB879430010E829AB6072C25CE6FA44439173026D0487D6F89337C40CFA28D4131D4D107CD8A44D677CD5256CE7A18DB338DD8FDF2159B5F1AD1E980E76DC0FADF27A970449A5059F4BDD6BF1D16A22F11062974AD2F8B267AAC4A3F2F1607CBCD91D0B55895825016E6D721B51DAA94E49BA45C1EDA32610ACAA0E5DDCB146C72FE55964F7CF76ED809749741D6DD1894C083BFD787FAC25149C0D9F095A9383B0256A4680A81B4BC4E86997EA0051C8805456D572ECFAA60E868A58F05B6BE4DD28BA59E64143CBD7FDF75C33D545F2845DA1496DF3BDB3D76268648245C00D8B6272F1C4A986649DD66574BEC036588508519F4ED9FA08874AC1561F7A54BBE7E29DCABC1499FE71467CF0F278E792CA6942F145011BDCDB73C63541B0C9CB7B005EF6243349471EE711C2D086C3984FE00887A408015787522D0037FB7AA0774F946526DF6FC0D1925325B5E67AFDCFB113D42A1ADB854717283C9FB020306262F3C718B98BAC1CCEB0F535FA5B5C4D4FC03151D46556E7293ACD2161B336FA2AA0000000000000000000000050F151B28303A40" - }, - { - "tcId": 48, - "deferred": false, - "sk": "823FFC401BBCE83F04D9EC178826A5BB4894DBCEE86C43B44F2D9F93DEDF2A58F1FF2BD5F907D42D6C18DCFE32F644C301C36F572570E985327F49254E9F4138562EAB80024CD250525C4C7FAAB88132E1BF3141E5CE354AA95574F75C48FEB3B742B08859BB4462738E5EA9ADE997A97129059FB937F7C5CD57884AE12AD95DA11289A00206CB068663C804501851D834812226451B4912C126048C281192464850900C18B54024B08823C02552904101B8280139664840882410015C9620D98001D40252E44811089601E33410C2A60108120212108A9012919038655B2431422065229468E4306A9A988C543450C8284160C28109251191064DA3440DA0B0499C182550A891A1A24D1133681B16280343504A2248CB28106498098212322423604300299B0869D8B80414890C0417721B18920A05859B14884B0071C3126184048000190C8B244D001349C13688DC046D2139068432305832905C828D94466EC93446C9282D48A00C4248119B806CA1244D100861C9B640C4127124337201260C02A241C2029113962C1CC16C60284E0C382C23190D01A22520836552B291E022800B3442DA2066043152E12846442024C1404558204A0B974119132A0BC3294C38000B21525B140A2319221A428E40124444362248A27084A048934891E1088E41020842C45063146020C12104A1455C228909108221012E42C0250B0569E1C68193B84089B605C0B6081016810199101B28204B386D04874C14C14912419000A58419900CD410110499250992005484010447015B3248244771A046214914640B024D084140D10022A0404604C4002037441825059908641C310DA2C02D23436221A76419B3455B261103C64CD1824818C420618051A024485022064AC09108338E1A92454C986C88407011403120410541089019B38C5A3284C92045132452998468C3422211B6914CA2450BA95064380862168A54040E4984100CB78923444104364A04A9110207211A202922034D888830604049C3486150984518801092960C18B22D24828562188453443088C62DD2B041C1202204312A02270D0821095390440A475088988121A04051426109C18983122CE3C49108496808172D81A6282235040220294C928818940911A9881A210AA3A44D0110890B4544523480D04085C8189011B2905A84058A92895CC051D9C42C94304EE126719242860B312DD3100821804120196EA4460D4B12101C002C92308A219961D1440AE3A00C9B206DD3B688DB4045634621D3C04084986102942D60420E242609CC424608C04C61900511308160386C438070A34209A3366D01850CD3144102C205D1C080A4202CD8A65142484D9C106E42C4091C304684C42D621260C33044C8A6640B043094448823B6711893655B30095A028E84A02D82204481066A1805301C082A20B1685C22298B46221C9204DBA285132622DB460510415180B60D249171E3202C04140A13382C9A8410A2140699B2318B207002B35002B080E20632901025513631641089982885DA4430113048E0024CD3008623916952C24D981824222185A33690D4948D9A028DD91888E0882482086DE2486502972C1C962519428519130A03A82493088613458808306C0B030EC1B828E0104AD1C680613826081588620805234588093781622028D2B610C3204283086D1116702481250C324124258411266124028A09158E4B34108A949092C40D24997084B48092B600C100641B292890003289426CE3A0299332701C910544028414097293900D1A424522434A04978512C22021156164226A00B9212439508B1492D9C625232449039201818690D208460016681A364209B3905C06268880701B166E1420281A03601B45618282908810091C258512820C83144ECA146022A080A41226884652C04849D13226C9186C9A2481124021C31881981048A1022188164D54962553222118C548E49610239509D03050221681A134284AA824D81022C114494A2681E2184E1A444401A64D2048848980410B820063A66D4B46251A96299932464C464003110852244519292A1010068808411B114824228404B30C53A08884967002342120A929183049603446D4846049829010954510B22853C01002020E00A00491286E1319258C822C19330E0C874D130610C0164A91160593C609E44072CB18709A02620A170994A291666064069F3922967BF867A52B7F48CCA1475730371BAE7D3CA391B017ACE1FE2B9E67D4F8EA687910569EF4CE84372DDC13FDB1DA2EB9E2634F9AA71E87CFFC9E28F1BFC862E08671CB976A54EA31AAE67F4EF5E7391CCF4F6614920057B8617E6B7743F7795E3D8FF767D908614D9FB5FA029AD4B9289CFB78D4A8084DB261F67F281523C1E191004FB18D7605A5E1B61B2ECB0543C153173C981B86EE4B47602D5478FA02DEF589E0B4CBE9A95ED74E25253A882E50C64C8BDD131487E02AA035B47E2B11CF723971CC44DDFEB02C6A112E2A5BC929E53D6A4C8A197C14C2995550E9CDDDEC38E9E09A5C4F8AA97DEEAF1BE0A5DF604230916128ED49ACBD9F59A4E0F4144391A8D718D3F7C0CEA8AB31B04CB0E6E5415AA6E0F2111601EE1C98E6A6B670B265EBF325208036407D3E768B7D68C0D9FA7DB1830A95BC2E41D60273CD0E0E9C8DB63BC1A3ADC3F126475596DDC43FC64C9FFD82B92E2D7BE1E095DFC89B18BD5DB3E601A1F1033888730CDABCBF13C2C7309E4B14E687236B11CAD4853D367B146DAA251CDF595858F4190C01A95292A94F43FF7BB3FB0D7E6747029BED764134CCBCA8C517DD44A0DBF59D135C9E7562A64FAED25AB711AA7578DB087BF8DD5EC7DBB7FBE54B6F7EE9E0C4D0625DDB0379D1949FCDF2F93B49D7949E81A1DA000461FC3F5DB8152E63F37D3DDD885DA6CDABFDEE4DC620159DA78CAD3C9E407BAA84226824C142A893D7A44B73172BE3D0DE12CAB4C247DEB9575EB2040A180E7C8155933396AB69E5C1F6995A3C85D1FE0FFC3F09522ECEC1CE40B033424CD27E22C8DDCC9BEB01796524CF433D9DAA4895D0EF1FDE770446EC32C2DD87D3B42CE75F4146F7528EB68ED027B9D789405C41E4B35B3557967480909696E00B6BF1AD7903D97A58422EE4A4DD9F2EE8AE163C930530CE93DCD6DBF475A245932F0C7EDA1DE3D7BDD6CBE66F93C0BC79250606AD329554F94CEFBC7C1DA08C4B1FBBCE1C4C68F36787F730262CFFBCA4CE3794178F08402890FE3948E0C9CD5DFED68C83D40AEB2C05BDAB5EEDD980F9783F6E29DB2058D3ED5E6D1952FAB5BB9DB63BDCD1BC2F02B81A7AC09FEAC6716FE18120D48DBFADE9A919AAAC8757488B2CB53CE83AC2F9A3DA3549649200F2402F574B1A636A40AAC099E8F25E22CA2949380F53D2A8AA9DBAA36088C6CCFE95B453F3CB39D147E25836B789A33031A850E16CD99C11CB8856D0ED82CA8078417D73C1C716672030257EC839D379E9095FCB0E83406DA139C9F93C0546B476899303B333609DFD11AB6788C650EE06BCA3948651C315F12EB518D843E8A718C04C53C968B2A951085E0E5A28037427C72C851467C8E737E72AC2156E4FDDF491097062126BAF36CDF7ED41C8BA4081937567618BFA869C2A21B0046269731BEE0BB1686B2966E3658651E259151A6A98B1958C5F37DD8C5CADE9504D1211A77773A78DA9E9A60070250443773B7943E0FF672C77219D5F76ADE6625802C9A7221B10A5DBF9F3BF5019983280ED3AF23BE20721564CCD7868DE7DB9A83A80AAAEDF357B215DCF9095F79F0DA5D4C3BB98740E6BE09070829C33767A52CDB97E3EEEDFE6E43199EB09881C2F3A18B43EDB5BC835AC7C3DCAA7D3E638C07E0CBF68DE1E6D14A2C3DEC77F26D890127EF9C42FBBEFD04E9C74D4B9C80A4E4B3FCDC8C8D9AB2CD4875DEA9D5AEA72BDE1E5C558B4753E480ED410FDBF2946104DCEF40525BB445EBA4FA77C4C65B0507FD0C9542919B3B367EF4F4ADC5A1DEFBD3092188758B4437B7F7B27D8D2285C24E4DACAF513391A8CB6733DAD32EE0E00710E278072DB19A2330ECA56D923DAB749A671214E812B324161DBAFBB2ADCC33C96ED14CF04A300255DF22ADFC618C405B718988E5DFA30255B75F8F0357A57761642811E3180C18D7D167E5DDA6D05B1FE2392240B62ABF2705DE27360061F10F6F98A0ED9CA604A3F1494AE66E4A8D637472EC8674BCD95B4915511BA70F5DE8A26EA034388AAC5BD8990A99FC3BCCB61612F99708A307C0BB966D198F603A777109A6416565C9AF7D06F620F48B44A9B2F32E034D2E5EF6B6CC9012BEC98CD1F89ECE7B3E5B3A1D61DEC92FBFAAAB32D668892BB315498DD208016E7AB0EB95B6FFD2059DB926E89053D78293E1F17E07D8404FDC24B4E2B4C3B3BFFAED8539FF095CF7B7BC97A4FB06B245E0D2C0823BC869F935CBF844AC346F0E3D5976D815FB6A484D7F5E72A1C1A6E8FB0F0BC209196B0F016E672D17771E04EA919EFFEBD317604A0FB5D4327D74DF07CC1AD6165733ECBB32623D0FB6A3B1EABAEE89100FE1B7F2185CE041E030A4271DF421D5FFDDC55F846F670498B59B4397BDCBEF252EFEA81BB4B3E4EFF3756E8B2A46CE51A84AE69B774374B1995DD2D9E5E656B0573D16676397BBD9955EFE959539080E11268B071F33E125BF2F6F90FD8BD166567ED9AEEAAE0D47F5CB9BB2262EA1C07943B4413E39470B97A2B5E8C92C083AFFD1BE622C1A00B436CACCD75C81ECE9262A737E3BE3558058A330C7C570F85CCDFDAAD6962503B91D16AFC1DBCA076F8023127FF0BDCBE1C343588B60653C6BD695E954EC4ECE6D034B4DF63A92F2D7FC212FA36C88E8137B3892DBA87C2396A9FCF539098F73B043C09AE38D0730356A0E90516DDF0300FEDE1FDD0B4C84E61616F9BDA41F50388BE8D5BAC92DC42759023679B05D02A536777947E3D1F24A91D935E2AE76B9AB5A865F83E2340DDF3AB0B9A56A5B08FD648B7900A48D2D65954F51D43CA39925A75E16F32DC1ADBD22301B0EC93DA01F06ECAA8EDA6F770D4DED24D512BB1764CC515D69D87966F0BDA86769149D38DDA1BDB3EDB7EED89C603235CA16890189F560A0542455E8E4A09BCB02DE7D5FB06DF64DDCDE70F0381C98466BA48A69436DA9BF3DD713EF802B214872A397CBE53D5C573890F9E9D2212FBEB99231D1DFB98241A9B10F10704C91E313115BCA7F3663F7203482CF6696E04567DB6AEA8E8D7B29492A0EBDBD4A97A7E6F0965A84B37D55E9F88777A968BEBFCD4A3C5C94A732F5C74BA11C7B4A57648909610C89D27A3A273A0D5DA2B3331E7036161807F1162B602EA5D7B83984C0EF08868571046673112D4CFA652EB927109DAF76A728DAE6437A6DE15027514983FC1C1CB08DECD7B31C609B0F7AFAF8D183F2588D4F60A1C7E80BED6D0FB64F05AD8C7AF5B6B5E861666761D53A6109310C11AAC7CCFCAD51CC54222B88FB7644C2625397D5745E4B282F8500AD496CDAC91078124E5416C3CE66FA8C82385A3DFD549ADFCA317A3DAB331D203EAFCC3DFCB7536FE8981FDD6C00912DFDB2B0D708C162440C5CACD1EE593F4FA891DCBDDD18EA0BCB1987152B3FE0CFDDF75DD31751E8F74AE01231BF3164D4917A9EA2372D5AD19523F657FC24C4A6D0C2BBCE794D2CC270B6585A4F7E2153E6E41CA9BE747D0348E68D7269084BFE188E4324E4FFC55AFC7D8DBDC2A47B6923556C9BE84CF29B1C6A3AF1B82B723D79F65810C767C140430DFAC14968F2581259CBE74475BF427A5012F93DAD6846B976846EC308903C489DD1733BE7193431EC09F70CAF0C14D539584F58E23A0B93CAE93128D1B52A68059D4D3FA6C4F7568C991B3FEBAB081498EC59EF340F91C2640596C7C8A69230354346C1BDD89DD99CFAB4EEDC3C2B0FB8A70C5391BE2D533D26F6A3BEAD450C05C93A43D07162068DCAD467FF6EDCCE1E1C594B01717E8345EAC25887EDB71A221BAD69E5F3E9B62A7C0303DC62CFA8CCD93659FF50F2A446A797026C0DFDD5D1D50B0D0297AF09402B570196DED70CFB7088E2ECC5D474D7D382E4C073130F12D4C23A7071D93BD7E66E2D6DC1FA98307C44D013F6C1335D321620591377FB5622AD625AE9AF030BCF3F6F32608AB45E2C15E78ED195488E5995D933FD54ADC6C73A02F105CC03D19EED13F3733389CD42F07F7D900FFEC6179CFED21C5AC4CE31691578805D2E6BEDD06953D0EA004CF9B630CA71FED339FBC6D465E69397919B3FC508A3CAE49A9B3276D1B0A75C78D8686DB7184BFE2878C0944256F98AB6C25DCC67C90F1DA7720ABE159C8743C15B3BD3469708879FE4C915A63AAEF01E5407DE35B1772513CD33D2678A9A34F430ADD7B41623DA000578A24E5737DA976DBA5C69569296FAD87A5E6E8DF5C7C2C1EDBB7085C046106C50FF4B4A3500A00E7E730D8E9B0627E10ADDCE06C296A6F5BEF4E99C411BB8218F6304311FAC1218ABB847D8FBDF5CDB74CBDDEE983FAD3A9447BB80C60C58AB0CA05FFA8875275C6E973EF9F80917F11B4C76EAFD58AAA34650A438B18246A4D87ACDFA57DCAB2209F65AACAB4730D6DF6CFF2E87FBA14B720B16ABE927590EB015D288DDED8DFF500FFA2E0ED288CA86CC76DD7FC7F84F5F926CBBF026C7E6D5D85D3DDD25EA103B7FA98946E4CD8D450D457E85ACA4311F8B52F27B4EB8AB2F993CE5C81583021CD385C2589073F997A21BAE447D3B4D3BEA154F188F7FA7A19C7B4E9315BA358F5FFF6D9FE9023C8EEEF0A240F10E698102A19FE48900C304E049C5A5C3C476D224815AE298520CD4CD889B44E5DE0C052F76AFC2F7A9F068D5A81E38CA8FD5D4D9ADB47D9D385E5B5C4BA54B8DFB42DE493D5080B326AAD8D41104D7EE98F51A147A9DD8130ECFD817A7A", - "message": "701B8AE25CD8187095349A4D41A067D4FD48732E62547E491D38845B3507A7A6AD8F8AFC53D139E47FC5AF2723B1BB057FC797519AC93CFB18DEB496BD9735455CBDFFFCA5E69C95990EF89F509728D1CE41F36A4C0364AC8C30E3EF67D3F3776400BF4C838A477231E455FF76C92CFCCE1B69B00F99451B0A8287ED59CD79EF0D6E697C93F7ED38F20204921E6E2F141D3DBDE1C201E5CE7C524370C339753676746DA5DE4A398CFC2CB1F568C16D4DF34A27CF04F0637B1447C6CC83E965A3F86C538CBC235E440CC2D1257CF916421EC75928DD6DA3CA002AC93C8F464ECD522EEF7E048C154D73053DA7BB63A5DD845512D2B6B7D1E7EB5818D170D14A4A698C8922D69A98319A10E0AF558E2318FC390ED990B75ADB50C6199DBEAF5D53B49235DE7CA116932EA38A109322AD05F5D681CE25FFDC9F6A05C4ED2EC6D4242173D2039318EF7D0733D86D57C4E114B3476392D47FC68796C9F66B1F1EC70610E1D57436614D5969564DEB8673686170E40BF5CDE506F7E70964E07258D4551F5EE0BF2651F8BF3D3177DA76AE90FAAA69C4F373E664F0A1FCC62F208A8BE130C499166D13CB34D77FDB32D5A7F3AD38856BFD3A0419B8744DD2F186D03E18634D826A5BC87F1566FEF88D9ED93E74ED4C005EA3EE2EB22FF5DEED283132D00C7A0B131BE1FA38E30EEC68B748AD533BFB23B9A14A936F609D4C560163235367B0D64C2C796F1106A1A9365E8F507B4BE0514C849A81E2C7388C8AF300D98D444BF808C4F9338C47A853222D5AA8ED283F57DBF0689E5FB89A456005B6B95AC3D791077C79BAA2BB42B423F93A7D0D999241AC5B9D64D65274817F9BEFCEFBCB4D5CAA67427F69ECB279553EF0D33A19E14FD4B284A72081F949FBE2A7543497F314CD7496EEE866F33102BEE5CF9C706426EF2365EFDF1AD141552BE65D1DB4373B0E8D449F3FD1733AA164C1F2C24F74E240C5096CD201A11113D6BF5CA19595C4B0A81E1153A4EBF88F38F1812BE517158787F2B378E8E32C9F97432BC9027292E5EDD7DA64FC6A32788154B62E40A85701895E13287BB18883820DBDD7647AE4EE1FC1D43C199EE69B1A2E2A7067AFAC541A8F44E660B2A7C114F402E2054DA7ACC41DDDEDFD7291CD4573DA22739C7785EFC2240B27A90BFCAFD1AFAB6C2B0EF5509D0DDF349C173E9A6C906BAF5692C39F6E0D1442F84AD2FC118A14B12C3AD5DF8A79056017F4FDD76603717B080E3AE560D7A601EE7FCAA36DF7289AEEA59EDD0B73BE91782377150F03C2C2ED40F33A250356CA17E153480A7E848F090DDA29C65FBBFB495FE9B7A2BEE342C7D422F28631A8C9CF643DC76F07F162DA1AD3F24589971032796BCDCD262F55A8C34FFCE05FA9DC001FB35D6FEE75B42DB6DDD2138C0517D003512F0EA8E982C2ADB5E5BC1F19B8ECE67E4AA1681383A97976B6A8F2025EA80B1BFA1796C27F6A54C583711E2EA46D85C515EAAD22ECFD68C5D02853D688302704EAC4863DB1FC69F8C35411EC6F4A9F0A7E7B3385ACF6DF805447BFE863181A945E8E7944770340496F5A19CB7DBD0D9010B7EEA3C585926408FD40F245D852DD208EA97CDAB0C16C1EF80B3E5BE77D953A04C1B6F53A23080B54F439705E417B9874B3FB524794D26DE3DDE88E9DB9FC36B1508754EB51D389FCC46F822F50FCE199DC14E4B4468B8B15A2460EAD05D0C47668C05A2315748897AF99D320E70F2AEB96936D7D739F72ABAA6960DA6A3996988F6A3F7AE7772D49915753B936367E022179E69B6853E1A83B429B42BE19EE03520A5666124B657D2FD6D15447AEEE45AB1FF4593DE9A2E6D152C64DF45C1F62AB9B67257B2A2115D224850A3AB2FA028F8F9FDE7C9A9FBA2FD291346037A1B4E00B0642B07ED54BFD70F3DCA3D1B8628627859611006DB2DD17A351751F85C60028DCF21481291526B1DEEA4C7CD2D3230653E6FEA1DDBDFE1BC3DA93FBFCDC5A405975A5DC68DA0D8338EFBD6CCDA1F2374D72FBE007599E81CF7D5C37985EA09C561A1EC40A70784FC606FB7C3FCD981F112C599C78B15B7739AF4DE129D489336BFD3966C10363A60E749162D1D8311C5E850B22910B999080DFC86D1787C35768CD5470E9F7A51D4EEBA71241DB57021D6569ED2BF201C06E235D6621B292B686D23E29DA4E81C873371593CB07B3DE46E91FAA3D4A2AA6F62FBF6BBF1954647E731AF4B99EEB3C0FA6385699F8EF2D8E1D7F75161129A1C7F8C7C68B906EAB8DAE8BBB3541FBC65F36BB67ECF19EBEF54BFC2EC4E1130A2E4F36B5644A73CB0E244738B6E5788A4B4457291B57F1FDAD2C11FE5C7DCFD4E742A0AECC460BB660D7BFDDEE4CEA074958AB94B6FA4CCEFE02FC7001D3A2CD013684A1ECC2E2F6D90D246726EFFFA99C12D1FE4AD10A6BE38D70AE3DE5C4843FE6CCEEF587191B56F666C1662F5C6FB03955C557E1B4CE247A2806DE39EC40CF8B97835EB0E3F2D829E0FEA02FE60C934FE72A25930FD6692B9ED979F14536F406F04C3CF0BE98647A5967B81DFAC353A2F8236FE147BFD7D3731C49476C3191981C9AF239AE8C72570C6C53E7AADD48E721E623D6CF11A1E386EA7C30F070E7AC4F63FB42AB74881BFA3FF3E8A35EBEF04D39B853DDE0FB17DD9DAE37A76C96FF55F64669CD9521DA3900B7CB297E813521239D87703CA395CDC8D8CC4EC21CB10A1C672493E013EAC0298F8076C8E0B56AFDF9C31EA01CBC1BDA4AE17FE103C9812E940A34EB321BE7BB288CF8BE7017AA58AD528C9DE09E269B10C6FBFBA5E8B6883FE7E08A0D184F8561FE3F43582CA045DC25CABA52C0157495410382A048BA67D051EA115D867D780CDE5EF512BCDD14489C43604F86D929F83D118B905C63BFF451FF3540E9E220851A402BEA0DB1A7CD94DE0407AEB9CF862BFA3FA703924D0A4803C463AAA827A04B0F09556054F27DB98E22A96D07F81662E0E910836B9423968C3F002E605BB688720FA7CF3167140BC21398B5E4968804F3C3065FAF125BB6D887C869FE3FCC27D88E048FFD0925E748C096C74BFB1E54A8FF6E2C838F16769FA4D8564E5CCC58DAE3B102EA300361EF89EEC689FB5BB0DE16C5CA98A60B8990EEC0006A147036871FC2A6ACFC6A6EC907D28E18A76560A5436BBF9353789C8A5DFE559FCD68C117066EEE5B00F349D6591E104295E78F445FCDD3D6883DF50D1DA6A04541C7E8171523FF36A9C072164147D14985BA30FD449667B580D73B06A5971B720A8B1D2A6896FDC5E4D4DAC78353ADC3449AA53919AAD15EF250AE12E9E40B8487F66AEF0B15E42BF34AA816F559062EEA24EBB01BA369747B29404DC1F1108DEAD021898298E72F4BC1DD821E4C88329D6F03F971F554A87FEC87F34430ECD1CCC6627D8CA49EEE1D5DA6704CE960021C847DAEC2DD544D4EAD2E2086058CF131296B7F4FA4B71A1DC6D6C642A256AE0C0EF9D1211EFA3845B12243BFBCB4F423E913A2976C1015569ECCBC159AFE70F1EDDC3AFAAFDA45CC02EB60BA0DB9EA83EC604113479BE848F381FC63C63B3111DC5179A637E0832A26EA32555908D79B308351CB104C43668371DB32056BB63540B9C3E5551A063D2B525F8A016BBACEB402CE7D7072CB9F37CEC13E1EAF7D867534C013D78B9DFE01C13DDCEC7A3444AFF9E182F12B6901CD9A70F21908FE692E4C0536B069C89685BFA9D973983AA8C1DA461D18ABD27A6A717D9F2122BEAA9BB1742622F51FF616FA2EC3A6D4724A3A9215D7B29A1BA372282CCF60DE90B3834FADE6E3743AD6B2F9B7344F45A29740DD7DB2D642F94998579A5DCCD2EFCD2F7D08486BB327B844EB19ACE3B4FB0D85F8A24FACBF318C98199A0B2C7FC2CCA59AE84A522890E22C2A7207CE91623362C7DD8E9F946817C75B71FB9654E2B7F2E83E46E75ED5638741E414D7F8E70914315F0E37B5B4E3E1CFA8288B1724113E4A00B59B7764C2D61443537849E77083FD13BA652001F39DD9BD4B20AB77CB945C5EBE686A0627ECC52F38A852BC9E1AC8D303E3B96D9D086920A19E5088054DECA635E802385600F673D3BD0A5CBE7A5B9BA8B1C4B73B9246C1A1C1071E5F98ED42041037FAB67184C89BF4FFE3CA0AE2A9BCB020F390F0B76DE2B8AADBC99268D3A1D467A024184CC9A455A8F2FF287A4C9DD1B0C86C8E176BB15B12023B291D44E7FF0C44577F7A6D788D82A75C68C9F5BBE504E7D64FD2AD18BE209E85C45627FC045BC81E3531A2B886173F3C3029D1FA98C792501A4942C72A7A892232F390CCBFD7863AC38D837755011F919AD8934742D0795523E6D48A958BACB9A9F7B9A5A9D914C37114CB111CB536EED3D753D6333219EC993AA5D39BF74E8E9FA02D8BEFF369EDAEC67A5CBD128FC9BA6F82E31A4C59D783A99912C7C389EC708824AC7FF05D56BA6D228C0A9D96324C6D9725E3BE17C44CAC7C4D49235BD15384F95345DC36519466A13110A58300F7E3362295DD7069DC6A88B542F2BC5C9F33328D9D8D1683902C025427F32FD562BE3F0680FA05851296E15C5FC67E96BAC924407AE6BE37E9B61D9A6383FFBDC6E77CC0887726C474AD735BC50039AEC665D827B0F6BCDF7EC87EA6BF793386F2A65C997545FB93F0D53737C53D00685DDC13960AF2632380F105840A1699ABE53999C568978ADAFBE21913193DD0844D89BD582418BF8B6BC430FF1FF7750AE8507495C14DF21A3437AFCA7DCEE7B1F1247C802081FC5ACE5B125AB2BF11ABAC97E201EEC2A8C90ADED920728EE77E1FE2BF31A222A1CA5263586A16FCF80E582258654D0793B1551EA3C24C4EBD27C52956ABCE6ACD05FC2F088273FEE8ADA0256F30B5ADA8768D8E9B70279DF95AE5CC68FFA99934C7520E12F57D213FF18ECA6046A9A3F32E280044023220140E2485A3B3EF7778006B18D4A9DCD177D190CD903CAC1EE0897F58762299A0E026B8EEC6F4F3D0BE1F070C648A2D73869F22DDA21246CCFDEB7A9784AE967F0DD0A2011C637099AF33E0D608AA0A5B2103060CA1A6718328D451368EA3049FF60FB66FE54E778DABC48413966EA14E22083A884E8C8EC33F885093F01B5E34477745A9F82C645C8C5498306AB00B78684252ECD74C163BB8AF9B49AA03E244F4EFC4A2E7099074F512D465C84773DBD1FA96D26053230C192DB289A1596E60B96178DD8CDD72FF14B340FB5830696B393CA319649BA56DCD517F5A08A528350E2D9531B3AC187414FA6E06C0F05D9987BB2FC98F7C8D4F922B8AA45287FA83B900ECB6C9F02669063296F1EA389858F6D2E10228E136FAE35F21DA151EA7AAEC593E5948536B68BE58ABC57771AEB406A0C3F931E7DCF85A350A3558E5C1B1F70E6299EC9FF8B9CC13E905D9902FED957ABFD7D09FB84FF22BF8410D387BA85D8555A75F432EC5789498EA36CF235276176ED48D1E374DB5C2DD1A64714D64FD20D4FDE2A605034E4DF607EC6E11D0465DB25B9D79C83182384D64477C126E9B8558489F69AF29730B4D5650B9860326249777DFE9EA5669736692D0780E9BA346C1727138F5DDD4914487CF32A4E9CB1DDD5617B6B45CF8C981944684BBB7921C88F5A25120047BAF2D9346E220EA08AD168B30A1B82B3B63C4913C708C02258B6AEF1CAC96E2A90EF7D0E1EFC0BC5BBE05D286E143FC0CA4A23833CA12727F0F83079F7BA80D809D6C739EC4D0DD9CF75C4FE30B12A892096BC4B9167F16819694B2CD5DB4B80DE8DE988AD50677695C4FB3E0940913C250645333B6F55E36F649A43C3A39ECAA3DE3EC1FD4F9F65D9F7AAF75B60DCA3BD1EC06495FF5F1D4FD6D83CC6316E40BC469EE5F44E5AE56ADB229A7CA5CA37A1508531E44B0142B4330048350A40FC82279D25A87E043240B4BFA7321340502F0D37073DF068596C4753F8709BAA2A7264ADBCF5F934E857B3225CA47D8A182B80D3DF24C3612FE4931EED565BE563115414CC2B6BD102DC6BCA9F104CEC8B24BA5465FEBB7E9730C928D6FC1144224232A990F8BED27FE6D28AA35A91F90D6A0AFE9A7E37A5BAE51D8AFDEBB7D5670F2521095A56862354D2AD946663B4BBC7049ED1884347734BF3E78ED227428476F1070F4DB011F8DC86EDC5BAE1BEDC9C5D253E4C5C6816347EC96C5F62AA3298588625304118EC32DB2DE0597BF2056046E17C69EAECFD26475066AC54D40A673741BCE72F138DD98F1939598E5D94D565C1337D1179DA057D4453DEE27B5C04777EA710D77B317A6E8DD3B4F26A6A9B3F4917A0E881E5EE528462508DEC6762DE2BC3F8F8C42E8D721BFEF7583C99DFA4D1CB49DE2A303B67AFD505F8A3865D853BF19C4A0F7CFA92F5CB18CD5D8E378A5B041449EC9ECFB80E0865CEC1734D34BC44E664243AA8F605366CE9F849700593C76BE0CB19CA1255B074A8630FC962B50106CD93DB41C6E4DF53B6B1257872B0D8CE9AD5F245C3027A3F75F19DC568ED1E0F60CC20DE625241D300DCDC8C953676363868B680B471C2EE623DA408C7E030833DBAAEE8E701374156A6B785E0EC7D1A0A55A599605BCA0FB517EF99939889C862CD790240709BEE0226DC7E8177F641C747A151A89340A6CCFF6982EF39683325390DE72E4451BBA74E3CB102870F1E9ACED30BDBBEF160A49746A23C432C3ED7EEF580969110AA438D00AA03F54E039195D61B7840222AC994784EEEA538B7E830A6508AA0B460DA4B4C0DD9CB052CE6254774FB147F7E4F80214AF1FAE59F8ADA6509123438E90AC13FF7CE71AAEAEF7A39C434C3824D49B894C389CF320A430A7F84A5F4972FF98C388D61C936E453BB1A340528A9FA5F0B0DA9543275435E91B0F5560E95F9AE4EFCDECDE1584761F8F60F0280ABF40FC5834BFE456EF66AF66ECA1098DD49BA2CC4B12CA9CFE256FBEEC328D049BD6BD19E2358502672F029888DC3AF3350BC2EDF5C4E07D59DF8DB9C14B86F1FE384227953E98978997902C8F237C8BDF300A72248B3DDEFD52577BCC0F99F75B92BC056719243F7EE67932A2DECFB15B59C95B43E183BA3DAA41B97E177D03CA320A5FD5D7E5A88C4D54A8467B883E0CD5924912642A65F191DD4DC2B08DD28EC0AD2B1CDB86EEA3DBBF6D47754B1BF7036A0BE90CC3775D263A5BC688844BBB9B1D9296804176E17C55D6DB888C2BEDA3D546FC496EAC5243AB5D51686AF9B29BF6D4A138BECD49665458B816BB09848CC4318136E6B170BECA544E8ADC35D40DED979111B8B1D4577DE2FADE6A1D97F9E82E9D3F069F3287E559E99224C6494F36233453036DBA617088D619395518B4E6725125850B3121EA957E721244DF53FB343483D27E6C3A53224B38C11C1D64CBFCD7041A44836AA606D170A80E84BBC0973556B9E4B1BD776C6A0876D727BB0526809700A0EB318BED67843CE4A6BE2BC10FE9D8228A4C94D7A506760E580E8A0E544ECCB07DD0810D79443046951C72E017CEE5B2C959754D477D706C3E043298CAD200189F4390F59BA27B0099DC551673B5138AA654E054676BF30DC61CAFF444CA22EB32E5952A598C07AAAEDDB83B8B3789EEF97663ECBD33FE356DE981A24C29DD5217E14DFCA30C0109419D8765A061F747BFFC1E221D3ACC7FE239375A9548483543599C837F48EA189880278AB2E06EA44417EB945F20ACB464CC458E249A8969273A460F063C5FAA907E42C9EE304B27C85BF41FB170708969A2BFDEF37B97DB4A16BBFE07370039369D04D0A9155623AA390ABB75D47FE2394E4606759648954FECDF4554F660D3176AF33153A9D7B0A935753B11E6C7295B0FF5680A18A42ACE577981C500581F741CA23DFDDBF22EB6511E19C016EDC96DA545AD16D5EFB9A8F10C45D78E01C74E3552FFAF35CFA1BC0C3DF9D14C1BDA9D510FC7C7A755C71B5273CD7CAF3AF44AF066DCF18B1B7D6C0D546C9C0B0B1BBE88F512824CB8B512438ACBB23CAE1178DA05DD67DA6392649213805D680AA61D26092BC1B2CE50CECEB7541D7F10808DB2D4A6B12841C8B4B6C5519C8683C998A74AC3BC3CC44D81B606A9A3174929E4AF06E032A24E67E9C66885004F07D4775A6C66A8F42F94920749FF902A8F1C3BC5A1A35BFA24040EF3B7ECD05654CAB696D3323485EF855361DB57A65C5AA0B238DC551ABD6B4A8DA0EB987A82F56E5EF05CEBCB4155181BBC61C645B2A4FA8B316FC6C5B3BA12829E74899D0A42B42821094B57E6D221FFA108D5D0EDE9012A88A2BC361D90673BB3D19D6355B9239131B42FB3CE832DEEA6E4551BF6C6533CD8DE572ED3E5DC51BC1ADA13C0C7E4F723CB964125DA08E0D08F1CFAE124568DE55E2B39B1475DC8F6558ED763FD7EC2DE373F4C54399A0317087630AED2A64BF13D113E8AC32E6318EB7BC0DE20E846C0CACD876F47CBF79DB6FCDFAB75B371156CF74B443E8DACBEAF94203037BA14E821A66244BBB7E989567D176FED12AD0BACF79834D067662C11422631554D1ACD6BCCBE23BF1D0C042C1CACA4B9BD01D6C5757E52877FB5DFC92161C8BB15A60222D12CEEE973812B4920B38547304E720AE246FB503C9F97BBA79640485624DFA2F4D508300BB80C70CF8E271770876062AA1EE0F548F6F7D95CFAA17FF1FAD847CBF6CF90B01D29C33B43473379F4B5491532432F6CAB98C365B84D357B48B416C2A00B25D07594ED4E4CA0E1BA5C92AA2F1DC7A6109AE8D71B9F06440A770FDC2501900B9EE466DDD853CA5482B4636BFD58AD8B24D91852ABAA0A37536D4118A122951DC78F02DDA8EC8029ED938125D759B24C90B0FEBA1F589AA1C10FC9597CB7E703D93AC4AFA43D3C239337AA454BCC471CC6BECF89266F588C3EA71AE50F146097D9CCF21E75790A5F3A252977E4D848DCF5D96DDD4FC1D0CB583A28AF9D7648BDAF8F1E94A83CF5349B1F4AF63AB1C66757B75C58D10F27F8619A5A6BADA67E841B6429AB40A09451313EED76B93166B3A5D5561CFB6421D83A5E343C8D277389950328A1646C3DAED357BCF2E8615695D7E8922030148844058D177D4E68A8EE31D5D810C73D9B38F6863083A8266652DB82A43615A45E6D14EFDF00A4333404DB65194EB432187C1EA7C48F819C34E48EBCB0836C84534A238C42E0B9BADFBB15B220DD0BF40F8C0511BA69EF82FA57D099BA84EE4AB6FC422442C3BE1E8DD910B4117BF4047D49419FCD2380966F665001FE4793F06F272E14E1893D502BD3343AFF5EE94A58CEE04E745E72E51124AE8013EAF2C2141012FAC54CD25E97B6FD3F0891BA1DE663EBF009A7008222F461B4E7D50628133DCCBA7CD0AE44BFE9F675E094D972D896551A1205FFE0CA8FCB739192488D2BDDD4E10493B43C7EFEF60888CB11ED68F34630623206E81ED04D300C2C43B6F27E41F18241651FC6B84C19EE1EB018BFD7A0D4483B0B6DCF57236AB27BF4CA17E52739E4D1C508C78F6B6E9FD53F423AFFAB01F75A9B1AB725C247492DAE3227ECEE2D60EB186BD8972FE455C393919E6D9760AD1BB706138824FC3C9EA0F673C1323366DEAFD260591DAE60AEA2DC22FFE5EA2421F35920550C0FBD78C4F6469092F89FB6908457BC81A175D75B1F97E2750194E68705B9D1E9F762068EE2FA9286BCCD3ABE98007AD1AB27AD2A094C6E164C5BBF88CD4C5F325E4E91FE2867A94E9FE1A78DAE2ED1C11CB4D365EC2F3888612FF58B493268645BE9ED69C196857F8C995A42D5CF4542E609BB35B0BB1B4BB85295ADE635E8FA237C5DF471B8CAD7E98420077BF1DBF6DCDCC1322C8BE1B8DD5E228B6E6E04ADA1D533B0C6221FA83BE7C19273F9AADADE041CEAE389D0572D2317906005BFAA17940026CCBAFAF8C7A4BBFCE30EDBF4EF82902E181B41A1FC006AC01BE64CF6E4A4A14FED995D6F323405242BCC5797E43276ADFBA44EB8E3EEC029292D2DCDC8E6C93AA6C02766308CD367D3", - "signature": "367CAC590EE6829B0FE910294F23515114CBA0A04D39CBBAE3BF908DC1A13ABBCD5CE2A9DDD0FDD2A011068C48EEF6BE5B4524ADCBB6F51E9A5B0F57068385D42704B0B48B3CB8D1AB011B8F13AE83726E0EDEA0A5880590AB8FBD689E6495AD68379993C44AB4308D0FB19D3F0E6D98E61BD2EAE1B49EF4229AB10D18CAC1750A60F1CFA9430649A7DE0BE1330A180106BFCC165CF60ED91711E5033E7B8FF29812CAE5A8900CD31A4B254CDF41ED4C5B4506F6FEEE43B389218191246A661CBB86F6C8F790D3D87343A37108E1D79C2DBD9A1533542A5766D56C9D013D74E2D7CB1EE7AABF50221ED657D8C2AABDB26DC3F7662CFBDF5F6484BB9B04060280AB53F0D22093967A19E754EC5180024F3AA2A615A45A0A43AF44D6204BB8BF512CF9F5DFBB8C9E6CA594FA9875E9801B1A3BE7983DC4865F649E3AF8AC28B0780C65314006024569774E8C7909A92539F9A647BE2CA6874B4438E0FDAA7691105C3D6CBE3F355FA37676C65C3508047A521454FC3A5F13F028465FDC9074BDD506365AECE7120980AA4622A7353C366202046CC2EFDC87459641CD56FC9AA723174DF368EF63517CA839813E16072951F53F4A2AC0B54F0E7A5A21683B81ED562358DA14794A798C1C14AA2B51B2F87637446F235316F0B047E757F84D8EA86B35A9F24115387DEC18FA8FDD6F0DF4A918EFFAD381EC87727578185A214B334C77FC5545923463D2601A302BDB21067FBBA672B7E33F3974FE1C2206A0EC233DCC44412A9440D7A09EC3A8ACFC99EC24F9BF021BF3298831AF56F272FC1C7A06DA01B1B38E8C421865EB8092CEDBE376E836B9D8181D853BCD48E97740E8AC046FFD2013691587461DA91FEAD7C840D923B0ED227F5389536FF871859F459FE2FBF24C84A8D290189BDAB6EA31BC1BBD98D64958106FAEED0E8B9BA1C10B66AEB7836063030E641A8E00422E2827D8DF1BD982773E0F13D17BAC5CE3DB813F712C95CEEB0E7CFCA45FD27289EBF6C7269EF58A5E4135A6F651B2139AAE3E1068E19C4EF3191DF10F37872DA952E95B2A831333742864D6FCEA8C0E37BD1CDC2EC902D210E7693D30E36595892CA5724853510B6C01E91763F376F20D650BD1C3A647FD2C29FB3ED1B8A8D15624E60837F55F65E0D0D8B0CEBA1A903293BDDA52B354196A1B138677235E41CC894DB5B1FB474463B168E25E7F55EA5AC0572428768DB4CE75255C47422B2D92C99F8AC8F296F1F823E59591DDEC09DD4440BFB9007B8BC04EBA7A7A959BAA624E2165D6C5C3873DF0589A377C6157A4EC57773F98763745627A51FB36CB82279EB9514E452F381AA65B3EE860D0EA2DFBFC838C98821907C1A99C0C18AC49BCBB6FF01127C46C439BEFE217AB080337B66F6FFBF934FB5A6D16118DDA48CC987A13D52416F7FB4D10C7F22D8F97A9E380C8A3902C2014F3C6B2F36702EBCAD5182E33641FE6D65A2BDC1729FD8230D5814545EE15D6D02907D2615E9DE534EB49D638FE0CCF5497D351C421C7F25FE57A507749640328EDDE3DFD807DACDB335971FC46AA37177C78D179DF12F187B531CD5B02A08A12A0C5B7CDAFEB636A1EFB6CDAFF16F4D128A0C1EC96FB97083C622C94F3F65105F865B1FDC81F69A56427B900EC13EDFA938C0E8FB31DFA821F04CFBADD892B1EEA6F596A6D02947F50B3B66A3F0323B9A1FF95C33F68EC2B833D2CE958552A8205B5BF0E554FDC441EAB46DB0E8FC319C7FFDE01BB3F118413C8FF941C37CFB39A60606780EDB9F5818CA4A26E1240EE6AD117745F173DA5B2936F1B25FF1AB49E10913E9144F6A1C0C547A93408C5C5E1155F02D5C90DC5E750F06BA51746536E351814F1639AE3C845BA88EC3FA60111C7F8285284AD1CBA5997BED7FDD71205032180050C4010FE353CE4695AC49DB104CCAF5309949E2D6B4485C10E92656FA130C7D0A2C424F98683A8A2F4ACCD31EDDE5B11DFE71057983A79DEF73DF46427A00952A69C0403C73707F151EF1C1B3C39121181FBDFEE8EEEFFC74BDCA8DE6078ED56A7968E2B13426CC387776CCE40411220FF01E2ADE27EA9F9445A635EB8C0D073232FEF7F580143EDACE3954AEDF5FD01756102F639FA9643173146FAFD50CA4FE2338584632D433640FCF619D141541B0C15D39C89CE07A47F24F59B3DA68A42E7FF5394A02B77A35DA7A61C2B7C430678FC9956211038CC2EFFC9D7C8E04EB0CD6277210F49940B39395022A226553DB46292774276CE5CC184B29CB598CD85672BDDABE25B8F20486C775DA97B9C3B97B4EB9B729854120555C25F130FE3807BC886A43BF605FDA29898BB7160DE95B927AA7EC5D5A5249E82D4D50ADBE591FBE49C927EDD94E557FB64F73643464E7AF168201C57A16C6A6FF6ABF1FF392F8561A66AFE569E51F820591C0A7A43D841CD13AEE08FC15A8BD8C0EA63C69EC331881697EBEF2C1646660E34B775BF497C9432394393A7E3200E63E477169D9C3FD737BB79C1155ECBCAA73B0C54A5C0A2B8ED6DB93504C5ACD7FBB15181696C9B6EF1A93C002FEFA46007D8DB5DF3A7F659AC032BC3780D8A7C7FF485761E632573E96D052183B287174E96B230025543288C37DEE87D6EB3C44FF58544C598EDD123CABA17B0C17C1D129BD90D72382FA5644FC94CEE6BAA9C152A04F6A1B5F6D167E8B27E2665D861D5E439F2425B562DB155DAF1573B3F69649BFFCCC73DC72F3E3A40900D56A810BB99DBC75A6594840006909E78299F4C56E451147C3FF9F069A65399B296C2B906E5B493FE4DDE19B4831F43BC2F0221A833EE99938E60BB2A71CE0E4E47140D73D5BBA00952E01883D9CD3FDDC0430B9C413455F732FB0AC226BB59DC0A65C73C915023C035C6C62CD6D1F3D5C27F473A0AB4C2D946D726A0B8742E8FCAB04D2CC23DDE5B0BD952D5223501DA188822F481B8F8CC377903EE38A740AE1125F4789777D94176042C70317528ADF14DCE224FF871105257DF7F1385D1508C04F46ECD2C2E1F3E49783181ABB0E2E503FD5DECF38461C9D6E093CC55850DC0239B7F550D7C054097CBB554CB53C3F43FE1E7EDBED3B55491AB564EE3AD7A9CF330BC4D42F2837E56F15E9676A838489F0908E1DC59DCE7AD7E72F57017BF6F610F486FAD183C714F99226889020534972BF58D414E6DB20F22FD60EF8359438FFE56C20F28D966B41717D3B63250DD0B5A961E73E06793AAD1836F8341C5504C15990B1DA9F37DDF87EA2046AB57D894998725CBE7CDBCC1B5F4EF0B48B05E545AB5125CD4A9C883BFB58BD3136F03E3CFE3F225284E17798A1F4B38A91747DC5A2D64AE13E2C72CBC24D25F809AE19100FF0C9B9E9063BBDB08DD776F7CF2900C56201F56269F3BD8C3EF15BAB0821E1330DA0C441CF3A5D0EFDDD4B2B48C0F567C00346B97F8EF9D377A7A590FFE77A6BB2D6FB6AFEFDB7C8260CC1EC3A3EACEFF8AD086CDEA49C39C961DCAC0BC22FE446FD1F7099425D559CBFBFD68EEF03525B01DECB52D5ECB1DE9FF4427C8C607428CD43E33F5DE8DF9D995D033DF6A41F69BF623F36451E53E422BE18F5F9667F5AC1FAE21B4106CDFF91333749AD32978EF6FE73D7AF88D4DE4D9E2BFEACE96D8DB08DA9ADF8BB51A16D326378B3394AE7307587F98FAD697BA01C1B78387DABB5D6E8A1F2CAB663A3ED1B8A833E4F76D11E0AA38CCF4476847741AC8ADEC7A5C4DD802604F690CEF94B014A1CC2FBE8F2F71247F426AA5CFE3745706E744DF24BB7BDB8BBE8BC8EEA92E46F8BFD515D52B3CFFAF81F127C5CB65B1AE5D4925161610CF562B660CCECABB35EB7F8BE085761EFB4A8F29EBECEF2726938606D2562B4ED69044AC08769EC112DCD7D7D54331549C41D7A9A9D9F5B004E4490ED183DF65D917DD1AA8A2B50E86F59576A304606FD527079F60A3D0EC2E36A12D354B6187D1A5301FB1977EA5E5011F3CC02B84BD6A5F21D411B4BB276129A81AE6471EFF6432427A191134542EF23CBFA2E32D2007C2637A189D7AF0A7D3990BAE139BCD2E225A671740F83856825ABC24F6CE908C4AC1FC3A61AAD816281985AB215AFFD2AB0060B66885168260028090FCFF612A034C68E0B2BC83F33585C3FE403A094DA453ECB21CBEFC03B69AFA16942691759701F101BE11478DD5A4DA021781642D9646040D6539A8A8B15868852E8E233178BF9DF56D048D17A88CC5C5FF875B2AEF274D18164B16CBACF4D2C12C2DE37EDF89A76E4273C7F888820B5C56699AFA1D2322D399010926DD5363B6755F75EF1AA5C0DB58D92FFDC0D666E2F466490B7FBDD01D2282B014F08581682A8070F48E69670446E0E8A22D388F2C36FE6B4A0958BC20EBD7D6471D89CC45C01CBCF09F3EB54ECFE1C1211F5A5C27D7C12FE983CB1CB02ECA7E7400F700B78346B9A4B669FE0D7B6DD805BA558DB32952C90EFA3E1DAFD68D8A00F5406A9B127B8BABDBE01FD099549A8F006DD30D20E7773027A3A402D8972FF70A02E33F6285D55990F0D378A56F5CB27F22904A37241C23B2284DFF79EC41895ED8D37EAA794D45C1AD60F6730F423F874AC4F2DCD82539E0EEBA01FA3B1EA2042E31999291E470606C96C23CFF97270972D0CA855DCF5BAA7CAE8205932D42012B0DE47201218528A76C21E5C0685FF03306656A6E5BB15494AA2BE9F01CB9FD740B8B0FF27C852665087EEE29806EF19265EE458275AF2BBEB9848D2E1825E617AE07D14A8B3C1C270F0FB607EA823EED616B90065F2BD545A0F6782E4491994A57D785D40CC92742AE7CCCCF12459461415449C8E59F44A8799CBADB6EB8AC5E0DE34DE602FD536BECA0C2A5DCACB9AA8A46843921A382DFFAF4381776C2EC6A588437D908F0639FA2F23C997FEF001262C996B7E28E074B7A1D2B217FC28E9C72333C89577CE807333F1255095E624530DF50FFF3E3FCF5CC25505E294A022E439611827C869E5D13540348EC4BAEEDF3DCCDD78D771AFB3978D82DA1799A930EEF91CFB315521CD70B194E413FDD1635DBCD193916C3C659F61DAC973A879F189D696D3F175FBBBF0FFAE496A5668A6E20458C9920794B0DDE8D06627AD4E224E112AEFD59BD32AE37BA750624D5AB84611D8031A3C3A377B10E2BCBA5E12AA23D3DFFE6BAF03FFC5BE4EE39E6612F917DA9215CE479AD49F59A34353EF65E82DBE07FC3E9C8D92EE011A5879DC5C9AB26EAC415D520DD2B72DA37E948C56AA177CDDD4B7DA86D1F6E739FEBD5EF78EBDCABEDF4E159D15DC81F2C9EB46079E1DF3010B133CE46CAD6350FB83833D4C33AE8FE4653B4A441800AFE90D4F0CF74C4716FDAC1FA292DA454791CA823136EE844CDC153FF4AB5B2FBBD2924B822A2EA96254CA33C2837041B70B20A3B15830EF876008BE6A8E412CFA7207B35EA6185A7A1AC2B81B4A6EF72A1C2B105836D49B7F96CC9E219D3511FBECCB704DB704961E669EB3FA517A7686DD118AEF575BD351AEC67477283344ED69C0F5308F8B1F82E3DC7A5029542E2F991242B179E92201AB8AE951C0198410A5A5C7C4CAD7CA714D9D706D2F7E0F9E4E2F04CFCDB4A3316F7984AF20F4D2A5BFD44D1B1D043954DA9D6DAD6A53E6B9F3574FD8D98B3DD7C207ACC73118C6C76EDFDE760E87AC11AC8B45F5B654C256FE61CC7F19DBF91E17CAC7261A9D3FED328E2DEAEB1EC2E8AC6865D339922892C680C84C66FAE7CA866468A67BD7AC99E532BDB02A687F3E7DC1DF7B6321598C0CDB20C994F2C1D84B601D8C497264396040670710A7FACB3F245E32044F988F6534766081480EB66208A03BC1B39DAA90200A98A0CB3965FD17031252F9D8E1BA3E5A555195BBFF408C899B138E5EF0F5F83B80AF8B9EE51C7264B2EA53A429CDD28C67020FA23E5D84165409B5EB01D091918648BD630DFF02CB082DF2FFF46E7674EC85F8630D38F5814879EA3B4634B2B60E73AD8540904A4D1AA123F2B21C3607EBD8BC49C4CFB36059E0AB14A528152552611A3B542A31A11FC238BD954A38D671DEB393D8953F0232A5FC11FC99E169B0B47928FE5342C3759CF052DA0C40CC39CBDA11D9C7FC05ACE2AB35454B2BB3F44C647499CC55174085BAC97FC4051E18E48D93F35FCD6DE8CA0FB468B7A5429C3A5845EFD379686F59B5FEBD931CD9AE932336AACC05E2840A8C599A560C25570C1F4B0D4638FF832628A7D9BD88FAB4E94A185C05FD8919C91B9D44FA4B52DCF678DD0182B9F2D3628E751DDB91F3B60C29D5A0B29E745EA2A99C84471E1B0957F1B2C591032BECD263038ACF0AE3BFEF0F28CCA64453CA4A02CB58752AE9C1E3AB98363FCBDA22A23C4B070AE3B92B9145B3C5BBF3B08BE93C42632A54ED8D728F84C5522B313C007B74605BC965A5B2B2C556A12B4D8CBAD54F370E86052C63CF26BB83EB430AD5482C8EC7DAAF302063A455878DAF56D8C93A4C6D34F82ADB4CBFD4A8BB8E3E6E7FC1F2627416ED0021E43516C81B4B6CCF5F822455860779D032033719DC80000000000000000000000000000000000000000070D131A202B3137" - }, - { - "tcId": 49, - "deferred": false, - "sk": "435FA0487592C90055BDC2DA68F33959F690A4F2724A4363262E2DF99A6073EF6EA41B044DA7B536B18FB802026B7A0DBFE4A80D41CAC87FD98B09A9AE370EF97FA99BD302424B43DA240CF31FD918246429B393D5EA9E01963E7B03547A6E19282B86CBB267B1038DFBBC3AD915C4997F7547CA709F68F4E8534A0E54FDBCC650B690D12005CC14444CC088E2120E43C0511BC391D844721BC6900A0744D930215C082E83066590462164245003A720422209044308129740424888C226615CB831800432983464C844051A3268D148501B326020970008C10101810D0BA41054300299204D0045662245494832104A844D09B9500438701BB889C80248844202191701C0B805422048DAA245A202060A4021DC006A110085A238092496494000411C968181808024B7696086480288701C9811900209A012814AA084CB122481300008314C49124940A62098286D99326E0906299C3804E082294AB09140A84508019011237019171023A45018B491C01601CCC609012601A1884991A06CE4268561120E1CA840CC120D0CA920491048A0A261E3047089460519B6248B446C5C306D5B8608C388444A428123144243C669DC44080CA660DC826D99C885A31092E0446D1BA605C9C870D9A085633269921866DC34508B305158C4211A496049384DA438294192045AA24CC31090DC366180C420D930041C0511C3B085098080D9C25121014C63186E4A16262129510A9185C1886D5B48921AA94121C14998162C98844841B444CB1062CC18324400460315440B252E80348092960422B74458004A12010E4106628B486481389012952109377002B008000651883672C1382ECC24201912700234461C2182092421241150A4B28553165101B2710A8770CC983149224E8C1630993046DCA6704A240944324D521224D2907111436923164A24394C18203223970491B0014AA87140A01011394002302812A365199065114521D882640B30061BA220D3082449402599366D22C06101B34199225223B460D8226818100944282218468AC11406DC46864AC005540260A1C02080304E21417050342001342A0A382590186018154522284418C94898A43092323012004C0192619A102CC816004C906524064A44028954144E21B55084B451E2366C12018D42826C233260DC240EA1A8081A896812359224854818352C9B1492532430203192123390A48228D3B281581849D3A6895C086A90A28C610806D0486CA3242A00076911B831030932211026828288022286D2A87193142C64047200B7088C80114398840C058E803265243631049889DA4881E0825000A765C94401A01648909885588628C8142E1A8380102185A3964903B8480A996C4C92319AA269CC864CD088095400260A80510824250083894B02481B108E12304D908449644490CB289012158A1AA724CC384A59360A42422858128E13804CE1124A51B691D0A46CC4328C1B8861080849239584CB9260200661401840E438204A2070C838888C3852214761A308604B04465194914C82010AB4442385612225024186809C2271D2B689D012691CA2458C420A8BB0885A040E9A926509A22881A220DB42695C42224A325050382D9C362A12262C241446212212CA922D9A166224108AD20825CA9844DC0825919045DB402D09A86504201188A629E014310836491489401B4520492449E2203122B46DD3184D600242981400449610C0880481A65188B0804CA4110A2650133802D0960D1B17264A48410807309396218A086610B29101B32459962094968411818118A090A29210D4806158903103018C893850A4B44140C004C0184200210E13012D0249649C14084A2646CA046C0C316DA1882904C02C4B9621082208A404325B264E9CB20D1AA549198484CC10626106291A1481039964C3124481186640326A220402999611A3902C1B097011206C5A342DE1128A88A4801A49401342849B82911A4391082525A3346DD0B2051A852C4800720800840C376510930050A22D5C04711B426D91804C82C241142632C8C86D8B824800B69090C088509060E3420DC41066640640A18401C202210CB32DA0A824919051A1906189202A12806590182149244683B645E19208C212095B96050942682122905AA020CB98091B302D09C410CB368CE3420623226122B070D4A290440841541208D3326694860C0CCA61EB683B44A65D855C8A8CD65BB1DD44C7E676ED115E302FAE539B8D26405CDB80C936C02CA3ADCB2D45237F170BF28E29C52598FD7B1C389A1A03C415B2B5CB096E345354FB26AC5DE65678CFA22BC9EADE8B1AB9863CA97848EC9D5E343F1C6936186D3C9DE36342175D26A5611E46F424D3319F65787FA40EC6E0C29162F572DAD37CCA44005DA35F5C85920C0463C266C502D2BBD9A697C0E69336290C5818A692CA61F1D60487043756B9F8FB16B807E918C4DA8B0F3360FAC63809682839FA7B52296BCD67F98B5FC0691184670D463143AD983A1ADB5F1AFC845A6FFF947DE0A98CBA74D06387F0BA27FB7F45BF49E89BA49EE6BE6D8F712F976C0C0971B766AD7AACC39C0ECCC4D2F2046E3390076989789C4E8C9FEE60567BB71DEE7CAB410CC1A9AB8D0751E5204D2AE85E38786FE3F436E8818FF7DA12949B52E9D4A3ACFE5E738163BFDDA76965FBD9FE49FE834A0B8C27AD5A00522D0B515E019E4CE8808A828597F25F2973DCAEA91F99F4EAAA101C41B9D9E303C22349FB39E7DFFB916443FBF9F9F231D6A615ABB5DAC5C63636B36D0E493A66930CD8C18B8E30B51E2F35B19B7D0C6118C9CA787F65148A3953DBA871A2B2105052DAF29C09DED9D838448E7459948501A6612013C599F51EA8BFAFDAEE41C94AECA8643623F46CC19A33A20191A9EB4FF98F484A86F7FB60864D5B4DB538A0FE14D6D12FDA1629B2D6BE674A242FF199F3567623C7BB649E229281C2BC355CD19C577A38614267471EAF4A46DE3FED534E150EA30D14E4CCB2C10B5F8CA2B8086B5B6748CC76065CEE5E96B4BB75649247164DCB67750B9597CF7F0C4A883B8D255375B048FB156F4B1E587B7387BA3B5452204F76CDA6DDBA7668284EEEEDFF0A504E19B737D733CAD1503DB662ACF2BBC9B64542EB1EE2D3A589A2DB224188FAF5BB8369245839449AE58C84D907E0F34FA83FABB302ED92BEDF217903C5769581AE4D783D545A8F3DC924119BD7998CE47919824AB5590A74C5AFD2D0A484232408710EED75ACD8E2671CAD9FC7A65788D6E988A621AB764E2B8B7C35D77ADAA684DDAB63B72316861F593609768AC761782E40B4C81D84169E04EF527B631269EC3F787143623311C7181B383FA6ECE49E11722A6C5A5900193E2427B56E961449874240E4E23523BA8B321BE7A0D984E1E84BC51D3844593CC56E61A6EB08F9107A097CDB8CE39FAB34DDD12DCC3475171FE0145152F44B4AE66E4D0226ED9BE6DA532C04DEE1162AE6692F8F94DBFF4A8141CA11936F1D2FD56CD9244036C73CE0B6EE0203CD328A5E1A04E0F6DEBB5FA6D648598EF1F0EFB0D05A16EFF32D527BBABD964425135105E67D0418BB17C3C5E4C53597C5CC9B6CC27B0139B61EF053DE290F511D7C39393A6B8C5D8FA46119C93E79AD18657B199A35A01CC48AD090CD6A68F84CD512A44514F997353A43F1807221B29BFEA62B5FEECC1F9388CB72FEBD181C49BA1DD96FCF24A6116A62563F8088148D5CF697CDF140EB000FBBE2B54FFCC36CD5B90E92AB4BC8B5D6D4C47C74C5329E70D87D8361A3484DCECB0C018C1A9EB6DB8094B8C7E0F8E5B1682948F76BBCFAA1D80C5CDAA1650428E2E1409DECFA7A1AD4AD428469B6A750C74297C46C7F216827197F775CD8D12280193E0471BC7449D8EB97A4B6EE40C5D73DE0C14293DA0B4C40C9543C284F251C2D4ACD332289D10442B72C3FBC564C092F3D0FC86F71E4E4228D7E746EF2153CF2A2FDCFE50E8699A7F5374B872EE9494D5A00BC50D7D9B356F9DBCB7DF82475AC89A88C6515ECF1F2989745EE765D4B347CF8A2BB358579B7C09C797A339CD744E8A69646B122F7C5386634B5F69C2CFE791DDE0EA8540DBD30187C9AA5737B728011160DA202D96D56E21BD38DD33EEA68CF5BF69FC64985FDAD57F329CDEDACE0C8103AACEAFE3AA1CC3F0A79934F6E57B8B5EA73F2DCBD0B4FBA7A7FE06C6707DC5549E0567FA09D1FF4829D127A5B427F2ED0C071A3FB317088B689DE3585240E74CF8920AFAC2E82F16541863DBBFB7FFCDCEF75F43C186DD87C91D917F4B9A25E8AD13FD4D771A427BC43A27054CCA599AFD0F5864B3C92EF3D0F29A5B43079C09BC6BD9A7F8C6757BBC2C99A944AF3A0C34D56C91637B6CD7331FFCDEE817DB1F91F30B5685361DC8C58007FC2A95DE3BE0EE011859652F72A0892DE1FF0B21E81F6155613D0A6A58A5F91272EC3FA864EE9BBCF875405D9CC9F103D0BE1F4CFEE618EB7C9F872FC1DB88DE967CE96B9C6ED273D1916D25A07702CD27D61162FEE2646F7B147EED996F817B0CF5EF4939FE7D13D653D3A8FF35427B50C0FA54E1788CBBFF7EFE8CFD7B7FC17963CFBC817FA2D75E9FE199AD0A92CA95A0AE769D40E71B7D61D4EC90A69FE28003844A0117538FC5CBE6F1B4C65B41D9161477C23D9F601B7B40A8AD23D79699A8A28271C000F160998FFFCEA6B0242ED8449C692AE85B64D3FB0C0DD3F0EEC1FDE20143504043D63EB4DB27DB8C3FB1A9605D1C13EDAB1025784FAA92BE63714F8A013AF297BC0C56AA291A0236E444B197704A03577AE59246F46EE4AC61A0FD9781F13DBFA5BA07E956DC9F7018EF0814B9C5F6F5EE95654D6D222BF1CD75843FC1482A8445C73AA2A82345904FEDEFF0EAABDF4F1936765A2FEE895F8A933A88C485FB39F1D36C9C6C3194B46E9DDF80B5F0C3F63A10C4E2C064D6D81FB4C9243A2C8449272C1B2066BC8E8662DC7130F940EA2B5BE2E7A5E31E1C7919F09FE277B7C0425C4477AC534E083789AD5FD06976D13DD229E93DF2EA8FCD22B501EA1D6A31BDCC34C225C858E6C307368F09071963A431F5DAA9C9CA5C5195AD9545DF69989E23871DB3D6BC793E5CCFEF6D9FF60912CD554416052E3D72865BD9AED12F48FFC38F6E9F0349566692D0E1711005C5925D3F679D6B118EFFA63CFE7C0892BC58A98FC64E1D0853F515CEB10693BC9D25960038A3F0F12D108D0094F0D4AB855847DB4F8B9D334D76589CE2A0F9C17A297FF5429F239DF27899C38C6BB426E459572A4620802BB55210E74D0B23334AB8686F2F0A078BA7668235E60E487F494165BE8BAA98565D7312357E7123443D9E161E663EA4E1F6F46BF36FE77D06A220D6CC7741C96C20925A99D7919588A21AE79F6F279E23D54CFC3BBB14A189974AA6E74853A494E780492F466AB4B49678F66A4C619C3E9BE8B904E9E6B3A0BAA7539C975E23FABE9BC401A4EC308239C73E9419C686A12741D5E75D940F6C59425C20137FC8F7A36E12241CCB1C3C97CC2C6D593C3FA81BF431C976C3369BEC74785BAEC41F8A671B983775416978AB2A779B907D76BEC0B25202ACCFAC15C9EC0CE171C330A1D2079892A4F5AE3F203A941F643C3C50CFF426BEF5833996312D8E34F4C606A9183A9B959136B7CB151E4EEB84361DA76A518285790BA43ECDED59377AB75B2E221D23C8CE880528A24C0E237A7A64FCC4D90BC0508C092D25F3F429A49F8FBE908497122BD8D2DE287FFA11273B61534448061426D37F960CD06A94E374AB6D7F3C69125F2FAA9B76F8A82E32AD4905BA7925415F0BB497F546191F4C6F5283E73D826733F1B6EA5B73A9C3874887E46D7F5BAA12BBAE84474CA1EABD2A5E83DBA51145D723B670187A2D54467ECB82C83F08636586D962147AF49C5AF9971B2F0F391F79FB96E2714C3D559D196511627487DAC91F0C011C8E3D73A6274DE801BE34762FFE9D030AD0282CE0DB79F1FF2543BD92E9EBC0317189C7883450EAF7DC8CAA45554D5E1359BAB98EF23E75A832B1477AFC4BE66C5160FF49E6F50B88EEF8DFC5F4C97BCCEB5BE1A1E9D0866DC8477C6C6F937D7D458CD7356A8770B4513767B2B4D9A8D29D763EF80698CE2605D0716DB6793FC46F46DD361AAB79DDC2EF6E41A1EA9D0A912BBCDA555DF3DE04C09F6AE1154306BCF9BD366FA43A1FC73CBDF41C0D46978C4BE84E999A94F9B36FDF1ECD0F6DD24A974E7719C3D63D6637BC317589EAC60BDEDE1208E05EC87FE382D0EA7179B713EF9C5DE38631081181C8D2E86A6957E5D75B2DB09CA1C1A6A6F6797F059760866B7585F0E2C6754237980B0973486C63DCD260E5846A23A7C9C45053078E0A1CCB4535F3CEADB65CACF20E74755179AA370F4214D81E9425261CBD181D25F192454B1E3BD890518C56D43CF46B2E57662E1BF523D864A6A705EC23F3B57578283807349261BC38FBB0D856BDEEBB18B545C96530722039F129D79F9784B99A960D32598C54FDD6D3F62248EB61DE26BFD73C584FAB4ED339AD7ED4062596E7908C2111E367352338AA3FDCA8248A6958CD153C395546C258DAD42C0FFAE0E5145F14F9883706EA9DA06AEBF193F02B03F27E261DA3A46E13DBE6F20A319230BE1A6E480C159B85261C74A0A4956799D03C70396F9B0F7605A54E4F2A928C7F68A2D4EBC5F930BC381EC7E347706F27C44CDA560A75623324B6C0415B4E78CEB6467BC987845917F63849F2DC6467154E65C8F14BD7D5FDD23547EA2E10DE39EC26C13AA36AC27728826CFB29723EEF5F3CB62809BF3FCBB0DBE718704CAD9AACE7EEAF4E56FF90DBB3E0F383B3F71166C25923580BF42364DD5050DDEF64B48337E0AECE1384DAFD79A00D7903E7B16885AE76134750B9E9E4654C819979E94296EAAA6EA011BC6D6", - "message": "14A8B812B4C9129CED02A09C8AB19443D34DBCEE85AA12528B61F84A2AA9D9DA49011C8E2C3C3856FCF761EA9C9882FB18666F3EC2C8543037E54FEC1F0F944FED3D350CACADA9428B7FB7D9DA4937DA4D1859BEF8C6177F0EC93BD67FC3D5B3D13C34D472D01372246704DA4763FA73BBCEB0F4C3658B2111A7DDC01FCEAA9059FE3DD5BDF2A9FE0D1C2384E82926EB895AA529532FB20E12F1C61BCE208E48ECED036E4F84CD60F8042475749E13D8C3ABE0AE17967D5C6D8C598A53A10231929822FB01EA976A08BCC0D18B1F9B6C7C1ABDD15121E00EE80459E6EFD61CB8D5AF950F0A8FF2807C32CFF7A56661C67348617059D7E128A72C8AF36B149DD8B46537EDE60EB5DE8A16A93349883B73F7C4FB8CAFD01E0C9D7B1EBF6D7C9725651980E0DA598A6ED5114178E47EA4C6ECF870033A03F134461146717C8AEFCB8E8DB1ED4E286C68C7358FA105641EE3ED9B4A5D4826B31706CF0946C152A365B246DC036191613655B829ED1AF8044F5707C320EFA1126B90137EB05FC220F122AA990AB476EBB0BB3AFF5B92442A857F6808E144C60F4B5190794C411C705513BC32447D83B760E907E6FEED63FC0A60C0CCD01734AD55EE178E6BD6D4B8A238ECBE8E4F8A464C381F16F11BFE62DFFC5021FABEA941D24B81CFC3D0F07F00F902FC5042F95A81BB8B795907F8D6BEDB5E5C56D4B2A4353D0188A90C01D7B2781EEAF2BC3D3D58A6F6AD63DF7FD4D32ADBC5A7A2F81EE3F5B98E8052017868EE59D8DCCC0199A006FE4FF39699EECC82DBAA846AC60B51FAB6F456DE4357F5EA43FDCE4B57AED55F2F6EAE49199AE90F6CC4AAF662ACEC2724337AD7F9CF74AC990D3083FE384685A1E616B233752E31CC4FAEB8048EF77480CC849D3376464621E2BF48CBB55E1A7CAE855A216DF4A8D1AE4E4016958F5855FC395C53C23327403720271EFFDF1A90C44E93E74D71BA29D860679E877E410ADE48ABD0EFDECA426DA792271D813116ECC894D799369EA8094C328D7694E8CA47459F31F5065858252C1EEB1AC4750AEDDD327048894F7D79A1D64737EF6E8B93ADEB938C1EF31E38DD60E8B4174AE093697DE4207C7733D82B4FE92590358515D30264A408746AC252ECC0BC28A9C98BFCD76C75845E9611909B0089B571259D1D115EE0D5DC6BD6F3697E1289C4742CD99F97B5D3A22631E33A81734A5D2BD1FF4A819CD6A22A938D3F18AA90794C120F4BE7E14324E89EAD34820070F8160B140E8CD5D68378C081DADABB41D365663AF26C606940E08B20581F4E63AC6E68FB5A7EF5DF86047BAC502223AF08F6CD82E6ACDE60116593046B5CDBFE2411A3FE89C438A1E84CE6D1CD72CFD3E5F67C331E72754F6CF2BF921FDE2C6DD5481F20F509A6852AEBF55BFB4B52D1F8B3E397C9B147433198073049638DDEA7E21C2043C786C88E45E566B6A7E8742209F5ADBCD34FF26962E87CD235CA1052AC02E4BF75DAEE60A06B19A4B0A61A15D9651473DF8AAAC6DB951EB6E669FA5F89175DC1FD4D881D688C477D16CEFE809E623B2F2A996909C3E10CFEF756ECE8E93072AF27B87715953E0C48946DA8E893160CD351E48FFCC6847975621E5C75D5DBEBBFB79297AB368D13BA95308E3D576F1C54CCC1C4D5EF2A41BE63AEA2A9F9A27822ABFF58B06AD99515B97F260843DD2304C855184EFE96BF10420184CBA2CD3ABC38D11B7A74E4A9E40FC26CAF3A84BFE8794477335EB1F4C67ACC9513BDA5D8252E608D03C69D493F8876FFF25D39DCD71442707AF2681CC6D5E117BD24315B0FB5C9E8175CD42AEABF699B7B77C9A8918AB94518B48DEE1777EAD8F18709A824F277BC06CB67915A5A2508E18094B0ADD29FC7CD554D8671CFB47EED2F850FC84B1C0F27767B3052869B653BFFBECBF6D8077697D1F440019E3381FCB917F5C06008A04C8A88B4493698C1964E25A551B03805244570D0EB6999AF2BC467EA4732B460A40F7C2EDD2CBB07A2DFA99B4E5F4663A45F2774C1ACB0C8B965E1053E3AA140E973049714DD644CB9317D9B3252150CC9A525E8729ED4A9A7900B417875391F7BDCEE646B1009CA479A1295555759C5A7597A775A1D1CD8D870A71DA7ACE7CCC7D2F38B18BD66441D80068F76AC194FADB3ED5F4201F26F670621D254264A4D2A88426FA6077895B9BD794C8C84DEF942FC43F2FA115509429A939052200196CC921454A65C4BF1A6E871970A3409FB9773F356BC17E03EDDE8CBF2F91E7D2B548380967F756D36520009DA5032F20D8C8CAFCF4B561A4C2894CA13929DF2AFC2C1C9FC41968746433FACD66309D2A7FB5D90EBCE40ED1E80C12D07BCB075FED76DE423D9EE6B1C787E1039749A0E559B86C4079CCA1CA7E4A3EAACB300C453782071725F6E2DC0652DB5EBE7D1C16B6EE0078004ED1F49DF439107AED04A2E69F70A35057C36A307C8F5BC13FCEA76AA997DFD2E2E4B835677EE961234895BE9C9E7D1486C04ECDE36AF4F7075C0CED9A33C372C33F751C953A2096815D9B6186632D3CAC31AE6D0A931258014D6F88157ABEBEBA1C11B9CB2956253D4950F5B2F64476E4125848F27D9ED4F93035FB5F5DEFE2435E67DADA015F048A90EAA9780B983748CED6056D021D21F6FBCB1A2DE0C627F2D9015B3D9D35CA17C54B0FAF85D0C45A53DC2575E2CB54B9A5681FDB66C9D5A09A3F48DFF29B24E45BE82856C6C76F0B9680F7B666B22221E14DD8B22A15FFFDA1D666F4EC6ADB5B929C2804ED36077E1A39F166C777770124253ADDE6B77083ED159CCE35894597E7BF3DEDB346571C2BBF69AAA9ED133E94AC7E31F2C30AD079EB4B4452232D83E49B43DAB60BBD92673D90F187FA6F3859EEE1630D3A232B99F3F960E8BE49CCA0F1A519156D2D861F8B6C15FEA4C4635C23F2ABEFDE8589A45947D391CD1DC3439F965C6DBB5C5C9AD14192B3D784D1C78B3DF6719D5C474E02D471B9B857611E2FED83869BFE8A2A74493C25D39C78DB019BE93E3BE331131CE85C4586C0D40D676640405FE363646C2264DE6F64365F19F87A8C54C884703DD369FF52F65CD9179B8A09EB92C38C284E06B0537EE686D7BF3BD399FBA8E1703BE3236F8BA262E2C84D55EB1E1E55DC14780DBA04BC1106D98B05593F9164F1651809E8AFA0A04BB0B51F9FFD5062B495133B509A569845CBC3003BFE23A7D7ED433B70C2EAFF5FD898009CF1ECD9E9B6F37CD7794234A098CCC39EF078E3C152017CC73A19B811FAB4A2CEF721029F6200A4D1E4F9E95A0A758A7AFCFA047B6707CE048C3BEA6BC561D152AC4F161347C098F4F44AD92006090324757D73DC074F1E1D445A500AF5A92CBE19EF631D99FFF870C60BCA8515125EEC36D004F22FFB420F5CB01330315F00CECFEE3254E54A047A7FA3C7495E6ACD579A9159F667FCAC4C4448579E7A68148D5518EFE269E97D90D67CEEDC378657A45E9DA855EC55E7BFD0AC3E52DADAF76E800ECFA61F2BF532E7365C4FBC8CE882AB327961C6A48C24CF0F0E6F2C54D732BC9B592008F2E6C80F7EFA788AA6BEEF0B6AB7B21DA3F9D92ED8A8F5F3F4B1D1BED6F66B6BF3ED52E49715C07DBAFD67F4F253DE368619A306C513E645CB5F154F7823781EB3E15F38EE482757009E42CEEEC1530A0159D25F052F4D4326412CBE6CD11C0DCC56B6556DDF806868B83602671C96F81D8210842144757A36CD187EA0900F36A0A9DB85B9609C11DE03A38A9984003EBFDD4E7C07CCA7A7DC7FB5F9F16E6C0C32CF86774B46C56BFE2840D8EC51E9FCB719DD1CAC4206372126DC8EDC9A4A2EDC8FDC8370C7589CE9FABE0DF3C8CEA90E82944B8D489C0F52F73EA3E3BF56BC3644A1BB0AF88F4B556A554851593E5FCAB03E235670638E4AD77BF012AE074F331F67222899694CB5EABBF0D6E6E6CEF75151FAFE89DB9D66DA4464353526116B3C2F382825B11CAB3CBD221DDA588F4BA13548CF627B52478F47D9B61479730CD9CB3F6622702C9A115D69EC232CBEB3FA88AEB832EB266B855A98424B2E08A699453A891C89C45FED7BBA98D6E7A2179A24D41D201C4214444BFFE6D01A15CBE640C3C54458E8DEA5DED484FF7AA78541686C60F9FEE76D1A7ED1F5686A2EC1F0AA037E6CE38FF695DE0C17895C9326415840FEDC1675E9CF30B8C45F8EACA1E65DD18290E8ED826738876FE8B69DC3432174151C051FD23CA4675A75E73F1D3DE4CE172FD657B57D5D03FBF8B29E268B3EBB8E9BEA96A4750168E8AE5AEF6B34701276DD18F1FEB01FFFA2A984D3A59D05A56552639D506BAB3021D507D56D0FBD80DC582B3C20940DF2393AF24FA5233DF073C7FF28B54C7A921949960CB2593AA4F93A06D38D896D547B28E9CAFDB479B7D1BA2EA7B4A6BAD33BA8B59DF8792B22F5FFF41EDB1FAA926FA3CF602FA63ACED78E85DD7C3094ED48D1F3381BCD084A9909613873513657879AD8599403A52ED0D16AF0B3B43C672867700167323D37FD6373C4D51B90327F4981A897CD54C8E35A6A5904F5AE0CDE36440393A59119437016E8CC88894B2A6FF661C10AAD7C7B03B7085B70A8145C305D5E66CAA265AB42B34539CFCC9A62B5D9BD09FA4D3B94BACE361B4C6BF6B550B89922EC01041CF05C0E4632274949D244B7776D6504C9803A67CECF65F750F9876109167CA77D412A7EFF06CBCF129D057143BCF03CB1C1AFAF937E55477F5B15020149D64F53887467AA16C6692FDDE61406D552660B88AADF65C03FE1B8D485C57FEBACF8B11C569622FBC56CA1056FD3600E1BF51084FDAE32876BAA1E97637F73677E8FA1462222DA72FB0936ED66C16A5E892C44093CFE7B4E3EE33F21091E04FC4A07C6CA21E93A500E5D7378EC716A9ACB27A5687BCD7F4559C32F6C82E8C06E82135ED16C35762E94BFD6BC33D5116E4FB209C98C871FA8E9230FA807CF1FD509A75DFDDFBA5CD4F131FF8B666878697B372B92CDDA15D0113E8BB91A7750843B3D14AC4E8C956B44C7A3A26720E774EC1A1F68435B122E539C8A7515A1AC94D456BC4DDD54839AAF6EEDDFF8797C9BA3A15AC70C34DAF78AF1F0C21734DA32A79C1BD3CC8B2636E12B9D2E42AD10446EA1A9FFD45430E03A78D8F38B64B64C9D308D18CDDB4D5DA13F1B4D15157063E58C36DD71677334B4D9BF09D8C765FC68B233B31105D0957F1B675798E5B9E982B1BAF1611EFED0E39E1E9E70BC790886A422DEFEF325A07D97FC603866C2C3682FC651CFFCA09B8122B636A65E2D6B8B9FBE6BB9220959038AEE11AA7003A9C4C4EC9E27F4A8350FEBF1084C292B6BA9A6E03C00979854CDFE566831B077823B025FD1B9C7127BDBBEF34186C74759E32FC222023EAC24A6A6653A7073F4033D77CF83831E8B6BC8F26AACBC3EFB2328C6EC35C3A509FA85E2E04532DB6E466BBF8071FA6020CF5585C70C29320786EBA815EECA6FB2BDF9C9F3A3DDD0F1800E93DEC3C5E6DB4EA5A695865303C48986CE26346B6CEA4A734668D5BED675EB0C2A1FFDBB9E5511EC715BB4BA3604629FA28A53CC0DBA1E819A521AF8B7BFF16B4FBC6766543C0111E232157B7BE4D561618D6ED7D13AC8817641E7AF77042E96C7209F1B65C42D115234F6C63B84D381F1820CD656C88BDEC7CD2A814D6346E90841005F66D6E36E63C5906D19904EA0D33502BDED36E7D77FF5E2592290D6F29200668A25A6B6F44FEA1D3EA00BD4BA165D122455E8F97EDB36061DCB335870F44068EE4A64FDE5695896D6A5B30D7613BD8C8B11DB330AEEB0EF239C105CE6C0B2E1BD81E867A2D823FF88E3E82FCA69923E281A2933D5FDFAC6B217D60958D18ACED57D670851D5A6A445A120F5B563070995793E618F885F149A3A3D498C69A0B9D99D92C16327B7568BA8CC35128500FF515273099B645C683EDA30092C225D01E6337AC652586C0872C9C5EBF09DFECA43697BD97B86FD5463F529CF303A105194BCC3014F4458CD3BEE8088B8B05D58A960334C73E1CEA934CA0ABB2597F703428EAC5DF6983A76A5EFBB4A20221E6EA04F67273D52D0311AB99979CB0EBCE738B0BAD72F0DA80097609F4422D962DE43D5B9E27F2FB3FD55DB5B9E98C1E74533DE23930052446A31E656E150261C6658324BB243E0C55C43BB397367D9E6EE51FF7A3F4FBB008F87FDC3448C07B88F4EC3788FB04944AE1D734E00E1CC58052AD2F908B55B39C0B1FBFB889EE2CF91CC1B3FCFEF11C14B083F8A898BB28B838662274B9974AA8E83579181944CEDA7FCD9C36D5FEE67522E828D6FD9CD28537D9FD57C8ACC7B8F888FAE4673FFDD859F6446B41609135BEEB20804F4331E31AE057171D27D1C338DD976634A460436977192E7FED668FF01B7F996F00958FEF2F89C78367507225C458A7EF81513D849081E4D22013A4A8DA7E6E9AF687918486E785E2E5D4EA5CEC4F92910E6A6F89198FF7911A16D7B46BAC5752AD5F7457E9B65AF0DB57148812FFE9F7C70F5531D11CF96ADF7A3AE1D86039FA5CFD5BD5465AA1649C40A513FAD60B54F7AF15A5A6B34F0935BAB28A1AF631816A0F5F1E53E1A7DDB5FCE521252E25910555D70AE1A309BB1BAFB7ED3856618161CB41206810AACFB9F748B06F6BB8ECA8EAE07B77934CAB2FC72FFDB061D5FEAC548CDD1BCE7CE5D04E9D2E4F38834AAD674F0D540DD6EEA85CEEE4F67B1D572597E9F2B66554F7F835894E81F4081EAB2578CEB8FA95964742436FC6741A5A9D1F2257572E7026360708EAA41D31ECCCB55811D5BB7648EF4021268C8AFF001F2D6BB3E1D4D304374E892E4384D66869CFFAC575398808D2042B2A33A874BF364B6E7A859BBCC67ACD4B5DC3494C1A6B55CE004A354C8EA8F14E9D9A4ED282AC4D78909F42BD38D044FBC1C730F921A1C678062A200CAEDB0EBD42D48C0B758F138EBD6BEEE1E45BF92157E3279C6534232AA6C361953A0AE37E81261832F29CDEE864962D44CC6C3C68C05B16915A8FE35B067EA754777725EAB0BB4E20C3BA7D6E75812C498F29A94D18D90D60F49339CF46DCEC6F0A546A90E0BD6E75B95441CEBC0B25945F2A38F3EEB1A9E20805A81E3008750588397A9A168C73C81C97FEC1BC16659DB16AD7BCE275A884EF801D53868B0DB816FDE421A9D7FE37E61B699736986325592EA93DC18B036D5B237115C35AE3862E355A1F3CBECC5BA89947E6E304A86196E0AD6A113BED701D21E07532A6D02D014C9BDEF9F9060799BB79AFFB218F3B98A4BC9488E5D2CA13531842C6651621484207723F41055274364FE30601C33663A6DA49C8187008BFDB1FFF4B7B3DE89F7FB0BF57F2E273EE84ACF8EE91A5335364BD034DB6A1F8025E6522B4F3D6212F3E75AB34179B21AA28FF6911736724FDD4F3229C6C26142BE5D6F2148C9BEDEEBE6C56B6A20746875A6F74CACCDED95179AF50E1C5E09B942B4E3C5E227C1A9DCA36F04CB89EAC24D5E87D07BB407922341590A739B825AFB80F544F2B1B70D877300B46000E660A568999EB8F54A3809D6879935492CDD67DF15A1FA902AE6ED30D5C5EC1178AAEA8E539068EA2A0132EFE51DA8A43E5D48ECD5D8BBD0FEF8F90288E3068D17EEF4204D639665BA3DB7C172E99913E97613DC4304006CCB37F1E9F62327E1C2B5D97E31822A52298BE0D6457708E0E2EF25A0C4C932F16D25A277C5BFE1AB13FD488BDA7BF30F26E89585F56D827DAFC799D7DE3BEF0B41A3EA3491514ABF11E633D7F4B8A88CB6F3ECA3D48495475A33C9107EF39157D53D447308BA03139C7A1A9AB4ECB178D818DB6F83B4489626E2EE9464D7392C80F8B4B6317095926370681D1ABC3A48D82DE7A810124099E375F39E5C6683F4972556FF258996BFB0FB81C44E3C0C1A814AFAE8CBC041D7E7EA4FD830568DE534B65926D6CB83D306A36861FA2874234E33F4EA5BB8AAE05C3DBAB96CAD63295D7BECC26F5A4E862546A166A09E059293AC85937FEB612178B8812541A929B81A090FFFBB17DFC3C774C5BCEA1398DD530C5286658D326D7BA7DA3F2E15FAEB038B8A397B68AEF622EB10B248DCC942E7BF4B4C942D33A4427B685A0DF2BEE8271E89A366708C9E48F6A3992174E8D401D821DCFE12099D3EF0BA0806E7ECD674422731B0DB2B198C495E9DBA6294FC736F41EAD9232A5E404A8E918A18D7A7846E0BB6716C4343C2FB00286049D7BD823410EE8F71347008A89DF42EFE049C61CEE782102730944DD15C0DA322F6DE4EAD8F9EA549767BF02BEDB1F091252F08B34B6728165B11D2C62805ED24ABE65A8E95441D1D5FBD361FA87B39135A75D749325F09416CD3E1ACBC04F6AC8B989716C55B06FC784B0254A884EA4CCE8ECB2EA278CD32FD1FD99C3085585201EE9492B7F7A2259479B1FF820661466022321457088B202B5F1E67709B763A3A945B19CB5A6EF0A322272D98F8921B775A37B6CF92F66CF86FFD26F84547BBA75AE82411E890A7D8F1B74D657380287606ACC8572D8522B87CF26C0247F25A7F8CA12911081224128ED444C5AED9EADBFF6EEA9FB7485884093C340CB326BD467CFC4F6E6C17D4F13C7F9F76192BF4A10F2F28F538C76BDC1F8528ED1360922E5A6DF1A38AF9FB28542357231478192219477D554507A47E9FCA585730292493A2B3EE225E0DF87C747E0CED460BA677EC691637F444D248805FA183666FA65110AD3ECAEFF59B2F8F619A275034CE415DCEC6E68A3530D17EDE27E93D87EE1EA55D22045CF436A34F907D35264116A848DF0B448E4BBE32A18BBF16A8DAC00CA6B07876ED0720591345223877E26D2DF4C0C3FD8484DF1DC40F1B7D4D49E871D8F527837F1B790CDC9FD95D698231CD090C60915C98F1CE43F7825613FCF8EC929BBAB9BF663A555210868653131556553F7A36368B0D83AED6F9A970CB2D63163C607ED896FC7342A71C6A1C90A53DA0F32141600F28F31A9340ABE97D0C6E8AA3270850B6598670DA455F8E2816EF82D3267D39A8163D34B135221D7D5D98069A8233802810C7605AF9764C6DB44FB55E29470503090CE6A720617DC9D17A5091CD3267DC4DBC1A2B7032B50CE46522A2FBFEE7BE29C3DCFA1FCDD43AE2E09DAE7330D2E6F2B15D10F53EC6D607066504AC50AA7F18D3C290296A8D9ACD1F5A3708BC035979CF03966E0081FC53F654AD68A15A3D17A65A768A4CA5F647BB21872B1ACC5BA3DDB5F69DC215735A5CDCCF50D555FE968551D507A7272FB591587383DC5930C5A572BE9FE0C2797B622DA16C6B87A03EA563845B8201168C45E7603B80E5780E493AE87584A40A09AD6718CDA3759CF1940479545789F08DE83333FACC26D28AEB54E2088934332EB7DBD5829F0ECF89D22C62636063532B4361B9C7C2B1D582E9A7DC72FF7F2DF667D9B7BAA543FFA20AF6BCA1A9CC22B7D7D177B73AAB087F868AC68EA0CA808EDE0C2F931B3B0CCB28E472CB316C0DB0367D4D7FFE0C02977CD2E5B20F28867DB1EE0DA77C5935155175B33D3275426C3CC5B73748426CEBB3ABFC50405E30EC21A53073C83A85EDB485B26AE7B633692326003004A822F261D5E20246F99B03D0AAE36", - "signature": "82A8419E4D978417C3C821D056A9393685833E38237A688EBAE52F9D22F6204C7AA8F8BD5898702532B6A56388041730123C978F23EC29A03340C162C9486044FE5263C5BBCB894F856153000923BD19369563F96DBB4E44D2EE7FF2ACFACD81CE7057D8F82DA68C4C06718732002C3441CB07FD7F01F72E28BC170DC10054F8C8F75F0BC4757E2F97B0C8721B8B8462A0452D3E8A9D55EB9342B9D747019A05EA83C6548905F72B2C9D62ECF92103DF350C926D46C4994F35E54D436B51E1B165B5FFA4AB85D5276270CB94973BB49A5589F2CC9919546E51DC629D81573D9A0FFA2D52D31A1CC81A7FDB76FA7A84FD312804BA266A5882E82E71DBDB8C816ABD9A631F8619BB85E91BE69C88ADFF9DB36794D7F97617E7C118BEF10AD3178BAACC2104E11BBDF22642A79F05B56B5827D1790EBE998BBE2821CA1D0D69D5091FCB2677565BB6E50AC4F7F3D1B4DBE411692F289FC0E8DD072C3D93A2D617EFB8E3C914941792E39480391A8033DFCBECBA8710439D83A821D3224965CD0B95EF31A160334458F22C9FE4DAD9126399D2E02D6D539DB4865A780F0A5CC125537B00B581778BF1FC8125C09B319DB6DF5F9AB2DB766589DC7DDADD62CB3E67215B37C34B3D019D85E4E94E4557EB934519679947F09FC5A80AC5EDF04549B4089F14AE3768914D05E22F6FE2AD7D098C90F13E6763E8B230570A13B15F0779525EDCC704F43D8E15EED9E1FD7EE39BE339A3FBB7FE91EC51855BA72859BCE0F78983FD0CE5ED5AEB6FD5F1380507DC37F893FADEB653A5693E16397D1566AACCBD9853FEFDB2FCF300452330D3353344C51ECDFEC3D055B7B113A337A94B43F0CAD1C74FB3317EB9E08D5CF252584D7B3DFBC9577D7E440D5B70D6C2DAB679B9ACDA3545A9AE523EECB01F403F3AB123A3A6A79E89E5D4DAA2D1DE6652C09E4A62EFCD924CEBD48B854A2F17BDDCB2E332F035EAA85810CE6DAC97297129EB4827228F360D4A30F83FE0E5F05A69F115A4315E83A9355D3F02819FAED553EB1AC05C67E89B095D1B09689F1F30F6E5B1E3281C52919866F0E297A6E70A507AA3643C5A7B1217BCE36851BE4A45C2E690FEFFA210A93C8EACD644BBACA1B3668B61612CC299ECAF8413AC3DF9493FB99F1FCF7CD4F261907B6A7E823F5D7DF62856EA94351AC0B1BD24532E8A58B7E9F49BE2C0C8C6D102327CA90FB2A20AA533BBA2CD56AC0222F697914AB7DB037E53975821F4A4D12FA24D5C8E0981B02475ECEE9DEDFD7EBD71A3D8FBD9940717A70681D3A5766082D2012D534949D5EE31E9CDE629B12523C4CE1BBF0EAF468A871C06E4CE30C05D5D5CBC7B75604F0288ED84C49FA80897281F4C1BD56D3ADBEA4532F6DACCA40CAC34575BEA447DA7EB2D7BAA676971D5D6C1B6EAE7F4704E46F9EB0F90A38BA3D4E308A685E0EBC44DD79EAC9E93CD94EBF8E6557C877F5A06F11C9AE05882D653E9214C6BFE82BD52B2E74B6BDB1FC72150720DC9F92B8BBCD96B0FC6AE0C8C51CB35A167FB93E755C7BBF39914D5BF1AD32AF8E2A53C4AD96B73F6BF5987389C4A089FAFC2527779FA3DDFD9C23AF408EB7637B0FC9FE1937B153F63FF3502C70DCBFC15E1E2817F3AF7DA6552F46696EB0E71D992B391B3A550E0C2078FD17994F8F9913ABEC08E8AC2812D2DB1BC7C1A3E718F665158BE3D92199EA226E5C1E2CD56A8B0D7A780A50E2E519A81E13909016A920CC7D557CC10AE56274FD6137C292CF4527172093E8268E1E4ACE29F9635E34EB83799F9E3901D5DB653807BCB6AA5217923A7FFC77D941A878383CFE455E5D84823A5642155097F60768F494C6C4D8737423FC66575940AAA46E62DA5F0EC6F20F517CC5D7F3FF12F7E127E0EAF8CFCACA2A198FA9EE5A0329926B3AD63F2D8EAD33877D8346965E93FA5E985E5171498A4DC3E6FB5CD914595D8FDF971EE1F63B5ED27B4D74D302ED11D518004D4B68A3666658FB3636952387055D0187FFBD7C18B29AC28C8A06B284EB0E9543CEE183BB5E98E4BB4CBE2291964689C98F21FBC4505F309B1EAD2FD6431CE913EC4415C01E3FE2B75586041092E77E2F2D1BEEE3084BF9F5D9E7D035F4E789924396B52EE47C502FE881520895C0026297F7336A50CD0FB46E966D32E5098C665AEF52AB2EFC89FF5D7378B2E6972291A57D4A82629F3F14D98B707B60704B18B48F0093AA2477C297E5798D34E1EAA25E8F440D8B2E2A4C556B8DFFB7D08FC690E15291FA768C960A8C7B962C03632452AC7888F20170CABC04B091D5A173592EFFFCC7860A870691AC48D44AC35F29CB7D57971E5051349D699DD8B511DEA73816A592B7D4E1C66B8406608ACFFC09F872AE6C2B13B0C8DBAA51186CF9BC3EA3AAD2DE618E13F0079984B11CB092CD1C938D3774AD4708ABA354880F98F0B3AE28E6BB4C8E5964FA69ADB78A68B075C30E08DCC8E8849C0631B8C9236E986D2E6FC6C3982F5F1C4683D7C61B8B469B617EC0976876A69C22180C37D9DAABC654A91E991122EC08BE674E9A02CEF4D0EFAB94EF5590D5E797490810BBA7894DF86219E813108BEE6541AB9E43F68AD43477AAF5FC5670FA2FAE1B3A559AC418E674994CF8E57BDD99D2CB349E09C1C68E5568282DF501B34BEA35D00613FE208334573A9E88710BB32E68363EB76F6B9F29297DF743609622345E4395BB52B9E36EBFB5A5A5F7F8EBDDB081C36AF9C26C9078DC7833FA7ECD78A4DD3CDBAE9C56ACCC711E29CDD03B740ECBA5D0A53E3F0F9379B96B9561F80186C4F0C8EE7BE11FE864B6F2E21379698820C32C12B8D8D4AF2E5781830E84F03A9E84B66335A3A454C269976BE5CAECC27894BC71AAD3AD6A6F0774D4DFCE48D6882E2BA9259AC6460801256101A35CC1C56955D8589C91542B9CF947EC7504FAC304C57C8D862A292DB0351DBF5B5B100D037479A401AA81320680C4EBE9E3A954CBE168B24F930E9928E1DA3714BFCA4C2D55DD971EDA243A92122F3648B9E1DAFB6FA303E4C48D4085260984AA0334713C4CED4116BDB3BD10C004451071AEBC2635ED8D401AC9801C694041B8A25398C50D0C1A7A14EC42A403ED3572AEC00CEC00F51C170E3E3738F7DEA1D64CB61270E38172760A71B7A9B52ABC0571541FAC7B96A9C0B3F8682E8BDBAC16E049BD38396787004F4BF722B6ABED9C5B3B058D06D92311EA9D2C67496551F2BEB1D353B52AE714723B1693C7CA78B1D0E5F212D2DD95C34DA583C95ABE1BB4ED435C5CC4105390825F0548D2D960B31AAE5558071DA276F28AF4F96B1FDD20A51499858839C80BDB845F3F799855AEF0069D20F3C9D455F34FF718B953B6B3AD111CC5ED7AF7F0B37969A0E474B21B1908F54806ABB8F6CE24F147C7767D10D1C42EE17FEC645253BD993E85DD82C77483667748E9AD17E463925EF4756A90EEEA62E0B9984CDA389D9B784ADDEFAE9CDE3279BC9DA177D842B9C1964FADF4694D9E1519D40D49D194089D1561FF729B41C6A111B749A14B2F84718892EEE595CCC97CD64048379024D76F04D31AB78348887B53DF69AD1F376C69D7FD86D919C98CF8B6D974C425D6C0F9DCC70DF596C8025E1D60C1D0C240B02DCABF093A7CB2287A5596FA1C0170645D4646584B4A27D65452AB91F79A9AC938B0058C7BD069DF24F5982E923CE56B070C84109C11ABF5BBA299DDC0E9E78E0D34488A564D4313562530828D732D98EA08E73DF307184470E3A010B8A0662BDEDE5CBBD15AA4438552D809164BB6C3D2B2F0A8AE13C3D78305A7D3140925D0A5D7E5F14CC168673E682C5779C9A325D3AF591B88BE881C47A313395FA88B2680DA2625AFE996BCD98748C2E82EDC20A3EBED94CD3FCF8FDBBA910D6EFDF22B66B955FA84D5476686EBF6F8A29D90F679773FC237211A4958FADACAA5C24ECC9A95A3E6D077966577159A32D44DA9FCE2689326C56F748774551E9F121E43D336AA2A2766E0A1E8745B4348BD36169D11A7046A98A22C866B2FB05EFD40BF95543FFC25993F2B516937DFAF8C9211D6CD6E10EE1FC1C4A6CF29999E7A63222433A4C54B98F00941DBB2A8B0AC62FA5C32E9436F9B2A88E1E683E04E36ECACA272B9515DE52A1B5ACBBB0C5946DC21665DC7DC6CDF9FDF40C9A0273BAF5D5F052F955528441311D12A7B92F306BCB08687CBAA3C094BEC781D3A05A3AECB65F22F086382CCD76827F03F1FC251428776FB4BE1AA65FB12A07F288FC4522E3BDA80C0195A2AA683F18BABB2DEA6B8A030A4FBE833300D1F19CD52FA250C178E214484B528BF01CB674607F5D5C36A7F7FC8EB52A25645AB38610104DB09DA179748AD16E35CF972BA3014B683029DE092F966F730124EDDF09F91D145024C74DD7D48A28F5111B73D3566C1F1FEEEFE06AC83D805CA81346C85B07D80559747A94C7AC24DEB3E54CC75A73235453DE3DCE3EB31382E83E398EE877375CFAF27199B51BABB70DAA700B8D0137B46AD7AB1AD0DBCF1686481C770305B2FAB0AF378C9BD4FBF9C11FC744970B5E2716FDD7E79E2FC57749120AD92292750011360A51987CF58998911AC914EE82C56CF3ADD2B8DF00EECEE9FA4C5D1905CC1A97A7223CB86EC5F1ED278141A681D772CE3D5063754C549BEECDDCC422A9C5C7832155D0EAA42D455D7F7D916AAEDB7DE3575345C9B22F6584E169167D818A8BC670B9E2303332B91D52CEA5F26674B819927B6374429FC5AF1BF08E8D9848E92BE742A93118606601D8BD2E42E1783224962DFFB826770D960FC9E0E5F3D68B635AB2C277FE0145CC03523FD06F52597A3D4AAFBB191B9C2BB59CB4E89557D801E77D491BA4A1FF81FADAFB2AA137A1AD099F839F60F74986A4E69E73595F10B7CC6A2FF94DF6D6887FFC45E3F1A39B2B0AE850862022CA4A3495FC0944964E0C5B517130DF7C7ECFFC8327AE8C3AFB665C751471863D3E59D79D8BA048E5C07772705024396930188C65CA8C2A3B9888B9D651483F7C2E96EFFE962CD5C3C26B781C506977D761A3C0E3752F1E45889AF1A74BC14643D44E79120323D0C649AAD09FA903478C7F8A4DB3F96514F78B6D8D46195EE66443B11569170CDC7898B3514B7AD9E7165CA58110EB58801E5E10466DF42E347CC690F6C9B95196F143AF84E3A81BC412F7BFDFDF222F8EA0D6F742C37BD4DBB77EA9BB0A942B10442285BC11F631A19A25C34B01C11552544981A3A6D0BB4DE21FBAAA2FCEAB1D65B961FE7D546C7942FABABD25F3E605100AAB09A0B389F7AB58668D31FC54EEB0433DF42D64869FD5662233DD5D48F7A9495E30068F9C80D4A66FD9BF1C7CBECB9944C6B79DBBA18981F7D0ED9F2945BD2646464D7DA473B2B64A9CC1388A0A7B588328577B644EB7EFF0E62A413B56B422D9FE36AA6B2D0B7F609E11085C4EE889CEA76E41B4B0DCF8CC0E19C656A17EC184FBAA22AA3D6E5DE5EFF0C212FC82BE6BA92653BBD044726D4E87AB68A1CF0A80D0F8B8860EFEEA3A257605578EFFBC43E50A8E86C9663DCAFA6793BA37B116272F8DCC803B5E9A819827B84EE975CAF6367E421B9970175D9593402B7394EA56703B1BB241592830EF0D168A4FCB54C0F3D88A90D5A1C2F977789C2DA3ED638C08F5932E91AE20341FF9CB9F65E0C07656D9F79420EE20AFE7F5C9F49DF3C87B8D23E709D1FD3ABF9375E095ED34BD768F8C07EC0FFE9A9C93453197738E16B76D7E02163B489C6F6426AE9BB86AA9A653F527A1D93FF780411ED5E59C478FEBA710D2C475FE2B2649E1FD940BC1223CDDFB566D94C9D2B4D0C91D3DC2BCC6F73B4C586A5C0BE72DA7B1B5FC1164B3E3091C58BB89529B83C3578A82B11542FD27B33D2ABD1E3D4A45EF0340D912BF8EC24C2D315F6C9F58F68AD0DA46920F896241EFD7F98DA1D10ED22BCBEB6A273CD7B29BF273F8B6895C05A622687B2BE13B3CEBDF6175CE25607CB83E46924C5CB00BFDD6F73F2C5DE790A87DC10FD1C77CCD9C9630C57A1973AF48EE1D283964891859D64D3FFFF8EE500DC4744D8871F7C2A735AC4366DDE9F03690AB740566F611C78D3E238365A017020C3959AFD4E152588F5825F5D8DB0A840FF6C7BB1F7BB87BB7BD1BFACCC806975190166EACB26FD8C388D940591A68C489D32BBE4E607541D05A6381157D53AA2120216C971B94E2FCF834E8D37EFE65EC5F086F30C316C889DB23FFF9B152718897AE049E4A191A043ABE2BBAFA94CE73F1CE17DC47EADAF8C8882D40000E2AA0C703C04D5332F54A0BABB7641A1F4C3376345B5800D737EFF9D99BEB908EE59069F504B6B8625A2343F070E6DAF42BA24FB48B9795332CD5A9EB317FB7DFE4B2663A17F6270BF75F888BCEFB51844E711A1ADBB9A935543ED5BCF134C1F52E8CE1404F789D0BBAB14CD229F8267CD5F631B9BA284F6D633576B6BFEDF1394A5673CBEFF90F172B3256799FBC0239567DB1BDEBFE05ADB6C71E5B7E9DB4B9E0E1015E7CA4CBF706073341750000000000000000000000000000000000000000000000060D151D21292F34" - }, - { - "tcId": 50, - "deferred": false, - "sk": "7377D2CE98A125D2293896EA97285838DF426EF6D3E06D3EDBBA7C6BF034FE0C3DA0A5CCB79ED5176DC24ABCE7EE76E7C1CD259CC05A4A784C8E7DE70FE1F4C1CDB96CBC97A40CAE2D0F29CBC084E65111808FC3BF9FAF728738346768C481B8DD506B9845F3A22B533A384D394FA268F6B8C863112AEB94D469DA66C7AEC36703035149C02D0B124CC89825A2A644D4A089010549DBA0885B82898B042094064D209988DA0432D2A80D8CA08922955013A79064222401202D9C144422B16892820D0B821180B66C62284EA2B40C08A35122C760DC20510CB77104446194006523B68058820449064199920D18170C02106E12146D40024D5BC40113056AA310284AC0302180292226455A384E8C040A08980812436ED838491318295A90651B094909B7248CB04909B28C18C34D044989420645A2922191A42019409198246C1B877103B40102048201B14801212D14130C1A204D0B176CCB046A03485112316E0B4572E2325013192C8AA640D98064022001C9320209100E134849429030A114120392445CC84CE24212C00844E0B62918A00514200241080E04456858B0101C1930113320111280028689D84684121168A3A0211009718BA42C0BA1450C279214972D01354E0B230C88C0418320492047660A908889064EC2B8449B206911B20413C32C40322E53162011096611072CE2420CE0106D1947720285254B264E58A4815848861B068E12126453865013338D8298500892285120111019708024214234080C1306CBB46CD808000CB3659042124C82612219296102411A94410980490A2580431450DAA684403249C18008A1067101C38514102EE1B60C99244459006863201104134A0B4104242352929845941872892249D038494C8490200164DCC864D43440A428060BC009E482104C82411BA088192649C4B64822208911986CC9C240A03442D340710492708200651A032C0CC4118CB42CC032051938280AA30D63A04D24C03012864DA4088559380659B868013852C8C4044C900C4A026582283101A7091402449AB8691C85701C414113148E0B4084A012120BC88559C82C22876912A10122950D64B06150120A23344DA1A64151C28408C20DC3825120A96420B325E0829118C94423924C03256EA28444A0000C0A4712A226621B43311C17464BA6458A340E228830C3368518106E09038E01322C01866010C4100AC4204C2282C8C07120B848D1200200426C081200E4A8040C444063A4718A304CC8B421E406521C92509B4889842082CC406108155020B171C2184A4A246C218421A3B004D2B608A1880D63B02C02B4455AC881143606C8C410DA86615B3466203131D9240D20B530021206E0264151040EDA048E4B2822A444319B008ADA822023086D1090888AB411CAC44C980282A016002128928C44325C262159182D101571CB406840C22DCB10669B30024AC00023B84C138724A4B030241764E1120604961161068084000104840D204461C8A610A00469A20285CC14880886481002620895240840401B421120A328D30401E4381051901091948459C8299B40895498681C3712C4A0905A180D04312003B5800BA6699B28244486509B3242930680E04251E2320A99420DD4A248CC929004B9310C366C09185200238600B14C24B7014A887108A1511B850023A328C846529C40848A8045D4C6715344290AC8650B22304C28268B462922008D8844691B230110C0480B492064148024223104466E21448A09430A22056601896989228C24866D23337062288E5082708CC031130341C1022D23007188247141102E09A684133266024661C9B491C0B08403B90CD0821012312249B00C11356A83A6444BB64562A84199444C63A645DAB42DC38601609680441206DAB840233170C338925B1271C8A660A04402A026068A305283A0458A14825B268C43445222272510332E8CC6414BB025521025A0142940486522982811194E14267102336420A80043124C6128241B3952E2C8459C086C90B6050B3452C1C06024210921A06053C68013360202802C80486808A54160488E1B2784518420834244C8C88C443690CB04860A42269CA62D9132101AA9515A320800A5845A8831A2B8641434605A146414152C00C90C02B510D3A229021728E40826E482014B280690B6851B428D10C225D38409C8B029E110882024200C280512454DA807B179BE146E96EC60914E74B78099DC2BB667ED709C1DC39DAE07760FAE0FBB086016F3BE0FD574560A68A9DCAC7A44629362330AE6293A88276F4B82BEAA2A42482D9C708EC75E60DC52DE3B70EF0F8EBAA0F591197273AF0DEAD7CA2BE5F6B7F67C99AAE59A016938F035DAF644ED94B5E9B64E153EB0DC49EFEC8F61BDFCE44B28532FAE0FAA09F430F4DCBDF34CAB952FD7E7C61C8FF1C36D9CB8330B556BAC79C4286331D7BC0023B643325C4E23B6E544D62F8D1E3B8B5F1241BE69A9AAC2F124DEBBDA3127093F4EA42E9DF7C7BA388E44197FB95FA17DCD6E6562D22C933C32A73F0D3FB9081DE04E513C9047F4DBB0F1A085CCBDF80BC0B6BCB652C302400F2D4C0C67B3698C23FC888D4BF06CCACFC202830D84ECD416189D0107B2F27B173D7541335004AAE5DFFC0DC60854298B1FD961D96BB8672A679E0D360150BA1E510B7151A440AD4BCE9A997B5D330DF5EEB6449264BDD4AEE6A86B8B00E0173838F2A645C9D8C4673908F6DBFD634034D840B378B185B21C92BBDCCCA0804ED6286FBC375473C46AEC46415B468CAEB97797FD03C374E422461F0807AA53D4C6CAE6FB5AF4C5EA616D295C5DC7D6886E5816FE47313A90BE1A7B8D528B96B351F1F0379F7F4301D7C669C0D27813EFA58827C26F04A09B4D9FF4B6007FF8BCCD3CB91E7CED0CBC1D0CDAC5F9205E6C9F3A1CD17FDF88CBD0C2554D162BD6BAC9AF0390A80745C6221B1CCAC44C6FD5F68DE32A9613AC4D4F77640A04141CA967061228F4E2D7C514C9FFA349004C0251E631C10B45BE25F148D37B05E14C3DF976B20EA5C26925818058584DF8428A8ADBA8377F74658834B3A72B938DC6C9FF8F923B22E99990730CA9723F531A5BAE5D619725CDEBA78FEF75ACB0C9D3BCD9C5BAAD600282F4145BF3E3BEB2A1BA7AE035659CB10F70D11D7F0A5DF5671466CF6554766C024AF1B9914F87BD74719DEB89014A9FD6247D089063D1578471B5BEDA5907825CD0A024716C21B186F3147F3C1309968782D8AF9CF40024BFC067111A68E27FF2E93D640657F422FC45537D9EFD2383B770E3702E2DCE1BE4530D17E4FC4C3755D47963B6E0184D277ADAB8037117DED146924DB13A05ACA3D7694CEDF95A0603F7B833ABAF05EEFBFC2585FD1E332070F63B486D93FA9D5457A09D9D27F84E80D49DB6548326D5F82A56B259271AD9EA4E90875D38718B2EC45E97F556FBB48FFDEAE2FA95A2A8FE1979DD2F48047685A3362C5F08B4C119305364293A498B4871CB7F5DB4E6B62E909960FC7495AA997EE6B885D5DD0BDAFC89BE1B4FFFE06789F6AA25497BF225B9AEB737F3C21BE2C7FDAF84F495E8EDABECCCDE3B0D60AB7E5958AAF5D0C5C062ED8775DBFC07E7A54EF47C8CEB59004FA347F1799481607497CB029C0A3981E564D4290C61BDE180CFC82F5ED40F6C89AB93635AAD175D488C1BF1C9A787DD3586EE49C028D65BFF792842D76F20E643E4E14312B1A52958DCCA1D9F7E0AEECAAA07B8BE1612AB2D5076A7F079F3872D8CDB5B128835436D14323732FA806B82014022F68E04862315FE6F16EE9254789DB98420BBA3F0DCC51159CFB7EA79E248CA2D21879E262DDBDE7F9C10757164A7096F5343AFA7ED777B8E2F0D13DD0A03ECA6F064EBB01E2FF84DA3542E1DCF62E7F911CE8CF632DEC6E376690C5D05CDDB42F7B0ABB6101D164D2A7CE931A12BCAF8E6BFB3D80E6E4CFD5ACAB85D4807054C406B7A93FA29F3589D5693CA4294834542884BB92BC1C88BC27AEEDD69E3D836130DD467F5CDD6CB82C2529B1E82837864188F6BEA25ECD031A55CF035A9F8523C30D30F93D2AB7BBC53E3E632B8F432BCA0D45F85FCD007CDAD638749DD09F7EC85C8C6B6FC7A4A3D87347515C73F64900C9B788B9E27C73469823C9FB6DAA6760D95626E74F18EDE6CF3E5888AFBE5D4CE686DF584AE67B5C300E8352288BFD55E5B8337A4CCB872BB999E86AAC9EFBC559437B10DC290D9A745692795D178B9134592232A696C5F0FDD653CD10EDABDEDDB746082AE54A800B43235DFD791BF7AA582155794D67204F87D9CCC52E51DF8ABFD24A4769C423C70B256C2E150844659F68E974B277840E98A6879333966F79B7A41ACEB1110E7E8B9DEB3D09C18285BE31A833AF62923E81B2499AC91F6273916B8E067892FC407074D2A99F287E78212194CB3862AC1F48D4B520B592D3BAB72D0101FE8FAF11564C88DDE8856FDA56AEBEFEA67B7F0BC4836190A8E6433F3698C0837F049F04AFFA2313FCCA95D22744C2C6FE08FD296E884E4D8BF1C05C0A7792F077900647B7D496CE3E2FC2690F2EB4402E853DE1BC21BBED13BC4930F1F3672702D9E676EFCFC6DBE120C398D6B335CB7F0C2483E1334FF4D526D59E5DB66E2B6BD865CAFD3A7EAE254536B07B67F7D883B92E0A0F59FB17F1B116626479117418F09F2C158EFE88F082A89957F1A4A625474C970B0C7BDB0AE0552BECE8485640C4BBDBE3E57D23F8D2419D8D5FE63CEFA90B239F611A13D2768212AD616025F3989FECB6834F3644ED914D75F08B3DFBFE497731FAEC81F84136A312BD91EC337E82524FC5E00EDDC07F59823320FF38DB34224BCC5502FD7BD572ADCB0EF53E4C16A35F37AB8B90E908016A649588AD1917FD5FB489C105CD2E59470EED23C90C7D9370F6406BF7EBDE494A658CFA1B93515C9894085DEAD882195E381BDE00DE045D1E1D4378D0DD80076C647C12DFE6441768CA16424331A8E8694C8442280BBD5CB6C1B6D504AE2DA853D089F56100E2ACC709A43FADF2FF110DDE85D2AD3F9F74854931CFD1A45CC769A444CEE253817D66AC7D8D2E0088A63D86608DBE29D1147AE85BB7F8EC87564D70FB2BFE0EB6D130EAECE850E9E030E1714D9E9A5BBA7EEC0FDF5BC660813B7893342B3959D137253F43EFDC6214D20B3C3C905A4813522091FD9D35D41193ED8E8478AAB5CC2650C19E4278EE10FC1F0EF3872C4CEC40DB39DB6384193E67E7E105A781BFAFCDFA8E88E1C85C5B893B8A442B4BEC0ED103F2F01C756B92A8ED8BC184632F9344C16EA3062457171CEC635DF6B1994CD1737C23CB37C32529B8A810DB30AF3376378F3F230BF58FDC564654ACF8AEB082E3C4DF005516D1522A7683F7A7092874861D46C44F605DA94DE8B004141B30152AFADFBE54744B0C1DEAF8F13221C050A9F4C967C1E5BA7BF78F579133C47767DDA12CFA827E76FE8E4CF31483E883ADD009639ED4EED93F4956D93449659C83EC23A7BD30AF8A55C8E6921A3B16959B3F1386A517A8C9416C838362E9AE08827F45BB10C1D222694AEF09B15D79140F8C0AEBCFD88394FB764371B67EF88E64C4140F34012179A394DCACD9E1CACE336BF723BE8FEA3D5E52E455E4F49F3900BED703ACBA38F27BFA3319445C4EC2EDDBF9DE7F9A1168CDC603C2C642764DDD0ACCD7809E98E4D36C838C2A57CDAA9444CAE82CE4DE5CED4377CEEE1922D10C96392262B4A57875A95FC4418A5953BE192580854EE92AF29E0949D4FDDD15AC811279E8E8EFC95183679117FE9C43A26AD455960A07FBA34FAB01386EA50072A0C5C026D1FBDA924525F3DFABAC3BCB69A7D2F800CA81872707D4EE0AF663768506C54A9A036D4D9C3FC3C20F8CC2203CA5F8DE285F70F4919A8044D39FCA06F484084F4F29471C2DFD3DF9E6D1E1AB2DE12287DCEA64E91EAA7C9C4CAA063710F4637983E66269D4C55CF24A1CCD1F02A08FD00EF4154DDDD104040CD15F588C93D030AFB06B35D7B06C3150E00FE3421DD24BCC0BEAEDB8185BB36D4E2F7A4493B98FE5613AB335475DE06B3E75766E9C662973A3BA91C0071606E4FD56EF9CF9E174BE2A42D8158207DCB81EEBDE31DACCC1EBC3BEFCEDF6316F929740C1F54C9C95E1E890D0A12CA2EDD0F265B5C3381DC8B1C2E719A4382862481E9D990F70ACAB53DC63BD502D9C99473CA00C452A604C137921E7BC050A776F03EDEDF95634FAD43D1DF4A239F047595EF220882097B282BBDEBD72AE26AB6DB46930E9ED585943A7CFD3597B134EBD74EA45BED2E3E06601DF441D7C2C9032E182B15E6B82276D4A450146B533BDCC662C9EB3D78EF75CE870272C0271C949DDE533FFA6CB4B9C70224FD877054B500D2D6192126F4659D11DFF75F624CF2304C92CFDCC1FBF02D57BEF75C69AD9502E387AB0F3C8A225D8486BDDF480C5B10F9442BD52A0DA149E1AD34185767A663A721218C7D06AF3E6AE29F5DA9BDB16E70856C3341DC58B8AB7CC133CFCACE0798123CE6C4735477CCD8E10499A0BC2D992E084A5E438605FE967DA5A24D0F66F769F78E2B321282717FFFECE8347B3AA78FCDD633E53B6709C2025C89A6DA9538AA643B833718A85477817AD8AF7B5986034CDAE1A4816C7449C11A628577AF65AD999EB00D08AC57053ADF533B2563001D08B001A65D46970E00DF0F83B692FB8683FBD62211B706E53C4AA30DB159D14235D0AC88FE1FC4FC994277A3838CDD84A0A08061F85CC1575831E7B56B87FFEB5E404E64B72C36966323F98E8A19202FA7F3C187E925DA291FE4C3E34A06C0C5CEB76BB7F8CCC0436A0001DB12B261BD47675C2490C914401694FDC04118372678AD2AE171F40B51C6CB4D40C849320F58B877CB72B222F2E4562AFC4C2FF91267F81BCF6D31DB8BF838F6EC3A3C45", - "message": "4F4C7E0134BE5200C4512299D134770A64A76B73A82463FD8C86594939DCFD9DC55B895B32A2E96B8AFDB8CA83AB857679C372CD88754CD8A7B0A31D2ADDFD7D1BA64556AAF1CDD674F3E8F5FC0BAD2FA38326365918430AB2344CFF785D5F73F2B5D631DB29FAA0F9CCE5CB7FFE0CF4AF1C7A8950EF32F1D72080A492C7A25ABF67F409FF5D4B1E0D77268C0A1B2A32D9DEC61BB71EDAE6BFD58F274707182058F0E6AA31E6D3763732A82BD6F2C76647C7ACAAE7FB4AA51125F0D2D48351B6A3FC7FD18172FA8689AE1602C4EC0CAFA863AA98BDBB1CD8C2681C2B6C5C254E346C18E2A270CAF2606A6504D30C0E2E505C2FF9D18523BBDF21424C645AF0EFB2EA0FD21B5D0CD85C7C1EE176FCF904B481855C4CD739443F3340AE48276E7F4BDC00CD11C2B0D6B97BD00AC962EE1FCF8A73D3DA3CCBB3B72095CB33C5542D86E843641CC98E27545F99188AF064D5FE74739C54F5678F411D96A0EA043652935BFB2E37EC934327C7C841CB0CD04EC17FD06A18E88882177B51B00DB6EF1DA164245A3F2554CEDE8C84DD777F0B92CDA456D922D8B7B8B63B548CBB72CFACA540C0D69F9EF21759F243CFA03EBD6B080D23DD62945E623BC4F8323DAEC1215B251C35EA13A0F081B86E803BF37DAE6D913B7D942BD1C276ABEA3F8F74D0C8727EC21EED2AFD438BB7", - "signature": "EC857FE47C6764CF4EBC33AFB24BCB47BD927916A484087D8C0770EB6B0E09427AFC3C3D41F83FAC1FDD609BFEB217C6DA6F54792F0B7C7BD05251CB34001A4B77F1DA65BEBF1C8CC8778C0DD44E8EE655279A96860E333F8EAFA468F3B2C3CDABB00E4444EB8F6E11F4284B17979010335493869C1DAD4D88293C629900A5AF6EFCEE9D0A685D712139FB5CEEDFDF5212C4DD6436376DA5890165B11F47B45251FF9F83F5218B966C0A6CB2C3FBC25D50950D9552DF6AFDDDFB6FFF40CAAFDA74A3A6E697142CFB3F3327293B45528B3D46CE998A24DF46D9BAC9450E64D73FDA9A14307E7CEDCFF2874E65E8CCDCFE66E93A6D07BE6E27494EA75170C4028173C638D7CF1125D3F2FC66025A3B0FB83F80EFD11B483B7CFAF05B86AFA62C2E85C4DEF6049A11C4B76E9CB0E9A959669B8376359D21C26DE603C0CCA5F99BE34872B9279E50A1504C20FA0DEE99BF757F68C0759E1287618F86F157DDF2F8D532D19F77C42914FB6C3E88EED0E52A939BDF22D548937C19185516B9358B4EB34E03D150B0B4AFB629E754BC5E4067284AE7133D0D5EFB3BE5DA06F567A2A4B1E91E8D1E7AF50B463E1ED8967131D6D1C33FEB94011E8ED1074D4EB2E4D30952FB76145541E5CB643750223F6952C196D51393B3184AB35F7E7B4929647721139F7D115A9F02745B46C22BC5C5ED151C7F764064C453179B221935EC48128026525EAF5287311AB4FB87824B772C093CC21DE77E660186B8D5A4493DCF0B4EA7A751187C9AC73953F22785371312FC4D12421A17EAE731FEFAE466BD923E08BF2196A820E94E1D0334B2B86994CACACE28256CFE1B1CC5E56102D16CDF512D5135668803AC9BC931B20162D17B1861C8D5A7584056E462815E9726AE29CE5BE9547FE2A698E366865949169F30430B8CA0D73037223B6D2D97F6552ED21A2FC0A9804A5B12F07AF98D44FBE3CF12927AD586AB80953B25D308E3863D5AC23A54AEA7A0EA0786198F6DDB4CACBC2EEF4987913FA6CFCC6AB0354EE7A226CA9F46FE5C8EFEF7B9D1B3718D27FA1227A47F213794116ACBF4F120175A189DFB83D786C2F89A7CACF23825DE573274F7A964B3A070D66D049C7245D7739611FDBDFFAC21373A1B52D9DD3068A814EC08599EECD46ED0C775AEF19513622DEE75DF2792D7F123A45025378912A35B303708D0B3426C65C69B24358ADDA1708989E2D1217EC7F7BE32C37449BE2D1B843C77555EADC7B29878B71D95C420A9A744CA247E3382DDA1996A4E749F7315942E47EB1383339A1C20A7943543531A9EF0309EA7114AB0B3DC4ED9EDA988D6E978092EB9938815A355087C63149ABF9FE4D1F1B2A37FE3404F7587246F42758BBC7F8B111136092C28400D45D28E50F685240019A30574ABDC1906CDEA07B29155A71700731904CB3B49A3DE0626003E6D903C22FE058F47D8CABF213BECE4C4371A0DBF0EE89C6C018EBD8C6D0C74B548931514AA46B6AFCEDFDC5BEC48A5333476CF48704DD3F8E031F62937214FCE74DB483740CEB6898426635C38C740939EEF69B4E009F8C3D208769AC3017C827BC2073911C3B1AF2BBCDF14334BC9265A38A494B033FB887E7FF7D1C3931C483CD8AB4E5B1374D03C325D7E266F6E9D9ACD06E341AE9E4C4F18E9CF15FFE0DAC5FBBF65F6ECACB4798BEA3AE6C4123B7BDFF4A9B34DBDAC333E3ECF74F892BB91BAADF533161764824970683AD1D513C98063779BBE2F1C80B90B29F9A333CF5FB391354F1838AD2650F3B8C3519A0CDF69E359D73379FC11022EB256FD1DB270EEBED9A0FC2E25F59DA828F8B0D0A756ADCF7F1BD3ACE22811062219CB9DD16FF101BC879B7B057D8C3A53E028469CE476B136B0CC929EFCAE217CC49C941F22953084C50C31F75B9F7E309CCA6AC26A33A66EE8F4FF4B3363D8748C89115D38CB895C653D07BB99677DC919BD6DB824A31FD90BB56BA5C62546E45360AB276729F070456CDF89B5F48B50AA534C8EE341CAE2CBE2A79689464C2CF7D65318C6AB8ACAB5FDA822F132F2B5637963174A628156E1D166654A11C77B3A428B41CC7C618E03C97EA13E8489E3BDEF8AF3EC98B74EB68474191E15019EC80649A04DE49136384EF7C0831E9B3F4582402D5F07F0D75C12B57220C7E762243996065366F5F6663A8621DDE3819A0BD52AB1E64A07FB0006B9FB458761C3255E88BF794141647E7A42A422328C87F6BCCA09B8CA3D435B5815491ECC58B874A264E61EA49BAF9D0F8C75CDF72A68B1DE29BFBC0EC715E2C4B9EAD89B30315D8C5D554ABF4D862CE78EC051D635D6771388B00E50AB1C1FD412FC592ECB7A7C0F36EDB8E9C3EBA02B3FB4784199D7C3984DC56B5B19847CFBF6A889BBD98F3105CE8A4039DAEAB3CE4784DE71E3AE19C2355C09982653A5A85C554F7B86A3839B7928B2E3433BE19C4C4C2B2A23D0BB99FF2297AFF64CA4983CA89F450D5E173F930733F63E83914D771022353D8DB88A28401F785ACB7D6BC3FD5293F600299E22871422C5DC47DEFD4D818AA741E64E8DAB7354CC927FA2A93397218823340CC695998B073DF31808C41A0DA96540B64C10C929FE54C62C99319F628CBF8004977BD13DBDDF029D2902C2DA2C0A0658D85D336CBED91B1A5813C63A5149BA4771E2EBEDFEAE4FBBEE78FADE02E8F1E03BCDDC1C07C6F9C402CEAC52A98FC6CB51D3EFF91F909DADCBC8E469E2E5585DA9914A93CF36838D737CEC90718BFD30CA4E0AD7EF7BB2C6C0A6E26D0C54E2A3C038177057B079B241CC886EA58E145496C932EEF5461D2D68FAA6FEF92BB8A0EB10544E81DE7C3C1FE3BDC25FD0F60DF0B21D55F005AC9F2D0C4E9D39FBF213359AC59FE2C6489149661688918CE6521BA46491296EABA965F6109D3E521B74556CE80ACE4F8A34B57D0FD6913BA3F1C68D56E41735F8D0EDF9E2C293659A73455829F1ACDA870E9F36051DC977C828946B3B89C640340051447B2F67CD5DC2A5AD3B298E655D49019B8A8AD0CE4BB3A3BA7DC10E8A619B12A394027E27060C9CB9C890206114A3F688C154703D468461A9D4A3FCDA140101035923B27498BAF3EE7F0D38A870E85839899052C48809C54D266830EDE8B5BA0F85C7BA5CC857DDC41D6013D51CB64B7F7F1258C9B70C9A2109DEE3416880253E05B4AB7191A4E4411154E84F623138D755CBD55F9CE28CB6560A4B9D8B2D391CB52FF989A147F48BB17587E1C382ACE220619E5DDE43EA51F711CDAAED45F9CC10EC1713DB50FB7DE410CD39F97A6779AFFC4A0B2C889A15C606382F431BDDA0186889DDD99FFC7EF6A871DE751BD0D3825F1290C0853C488675B4F29DB3EE7B6D14BBE454D8BCB005815725CE413F03DE990AD6F2AFAB259E70074CE4B7F9800FF680715F3FD20A605366B32CC7632C2E703F0084A1D821B7F760A324B3AD5E65D9098DACB039C75F9DB9F9A85820CDC9A779D3722E3C35480D8A7286E2D36FEE7E8A14D32F3C192C39E67ECD7693B3280266CA07A06A3BF118DC9EAE1A23F4034CD976B32D334365058AB3C8DF0BF69879C8FDF90FE33F61205ABB6A89369DF4C96476D77B6C79C370F853E4FA49C186C221411F7C504D5CECD66114649119C26FF8000433F4F7392CDC073D51B3D15210ED8BEB5A2EB60645F8A4FA228B971F347D94B9ACD102605968AB2F7ED6635B0A90A7AE75F3E526F86F6A062C77BE9B0391BFA87C219D258E5C3FD64D3CB360F96DEB05311DCAB0B5A0BD9AB1BD36E4F9C4AA62BDAADA7404B08FF4328FF5AA0D9651B676B23855845DF4712980E04262C6D7B6CA5B4F4941EC0F8DC4835355559FEC78D06E41EC597B47B74C1E5AD7C61A987B5A88D1ED4362B3C132967EC09182E4BE876BD86F1D5C3B1632A8F56E13125C0387454E66C6BA34412E509F1736FA4FC9694AC550979AB064389577038662628922316BD7F042B6A69B516F46A56C28C2139A3506AB7B4283BC8A383748C9BC24504993C2B2B42A83C362CFC1798B342A9510BF37654FFC41A2DD3B14AE1F23F349CF7F920A07923AAF8E106A83929A85200E2CCF4BF4D78418A37DE65A5B4F9D270DD3213910E765F8C8FC567B2BA1062153F9DFA639779418EB343924567B0E42D85015BF2F3379027973C080107285650AF8CAEF9B892E607DD3321914EEE134B3DF7282ED9EC79FCAB130A15357A2B858FA77108D9B086263A08B482DCC375F0C4CFC5084D3F1181FD4F64C04B3B8088E9E4D18FB75B376890798DE7BB1E85132A7D92E2E0EACDC92EA04B847FD07B9DB141F0CD1C823C39EB20C0C8F53724DD314305A2849044EFC32F0F0535DB38219C98FD8BBE0A8CD897FE00DC500D9F44288468B03C8E0301E2555E863128FF3F9649F03275EF56204EDAD48B20E05558EA52A2813E998E9BCDBA3426E53D2A3B3C047F42FEE803C5561392887C3FA2449444D6CDFE4A89A9396F7F6BE56747961C021CDED77CDA3230D30CFF132A8A6FF524FF7E1E6335D6C97D5769FD62B1BE97675770286712A4B72D8FD3B3674EB8E71491D70508F9B9A1624C8A4F9EDE2EE27CD3205E6890FF8314D840CD3C270DAB6A4CCF896A7C3195E766F96E67381AF09D303A22C62CB1D6C66DD51028508971E2916DBA5DADF4DDF6AED606B16A34DFFFD8BD79072281351AE4C55A9136683A9B78A240254CF3AE877A9061CD17B33487944BEB504D03DC2F0FA8CDD563E45E4FBBE5DA3AD9B9D5E27A8962915B40997FD64F1A10EAB864DE75F67E948B116384DCC14CC27D8964AE7E8D70BB9B8928883E435E34B923BE01F35140CF7EC5D1CBCD0B8FADF0399453F4C048B9D4009A82B8864359B9A5BB53B98934656DD05CC8B677B87740A84D3DE64C49D802E81F5AE95321DC249A466D87CC6F64C2DCB666B4437A75C42D68E1DB5CCCEB1CCE9C68A6E1F47F920CC7299DE922A18D95CC894823B38A900CFC2AE9F23AFAE8675F89D590B0E9BB69C8BE83B9F9EBEF273D0A7EA30690F66CAA88DAF29CDA9BFD3C88A11B02763602F978500BC2DFA0898D83898C09D4FDBFF5928D2DFE9CF6E058BCC1DD30508E58ED1ED170090E523C9413734AD74CE5CAC2732E012FFA6ABF04C6B689CF70F10C04938CAEF9946973F36B3AC4EAF643FA5922BBBCF32C6B648488207D7E7E236351BA4085EDCCC8C6F3BAF37C2B532A5DFE4AF3F65F65E321AB14E3F7F75B6F2930F47BC93FA683842F45B7AE9B432E9D160F67B45413DC31C319ADCB4E075954C7E5C353AB7DB1E422F123C97B83EE25F8A8A66A8F1880819365A8E53BD398D8C73A5EDC546B84780E0BB633C082AE93B0B03ED6C8CC900FDBCF386062516103F618CD8EDDE18F8885ADC860405234121CAF7AA1F9C31AE56B8BE807D8A51C67DA0370FF637D085CE08BE04834FDD95525164A1741117A6F15795D70585BC8355636448504A5DF0576D94FD542F8103D418E99413873D52D11EBD6E46B23CAACBA7898FDA32B33D0CF8B7A4A25611834F309B1AF06DE37B3993CC77EA755466AC4535C5970DAC912D0F8DF0DB18FFC17F8B9882F1DD7E01583B85662C8003E0F694AD2FC72732490A090D25F5933AE71185ACA1260F4719880BB46F1E22F56661BB341AD226814C73FAAAEA6E054D01A5E0A66B525DA998C8CEB1D90125B54D5599BF4714F5D6CAB9D7D205D90D1D0A1CEF7D241CC987F6F9767E73DBE3D734393DA178C72B1F24DC9C2F1E5ADCF10EB893AF6ABF157477A88DA0853E01B7F7D34DD77F429E76814C4974B8D8C2BA4CD8977FDD1156C5CAD5C75FA438876AC8C4BDD8E44843BED62F649E7C993096D26A77B067B4505B9FF6336E30D2B36D1B0C7FA8202F1FB584E47F8C02D5663AAE87575287C5896E3E6EFD143F7E0DEFEE4389EC579EBC9C8D75BDE56B2F7AC703AC85E97EBC6C08B55A29BA3A06C8165FB2D03889E300E39364BC4CD856D67291524C81E884B5153A45D7B53C66751E863594D40CC00A9B23B9B22E40AEAC1D9F12F4D4EC0A73A1456506AEFC318F8AEBBAFA5F8467209F03AFAEF0571863F7735C858776CA4016370AC39794B42509668791F614ABED4F3B31FD92E52E5790E0EBB47344D62E4254935EC21FD3443B62C6CF46FA9E82CDC3A2B58958FEB91AF1E26537BF98734112E2F8C70A4CDB3AF63F60F746339915AAA60CA846C4E2DA28B43018BA24D9A34D348335A4261CBA82A7C390F86B51FA5478E1053A5D7EDC07F2322AC52E0BCAF24FC665928979A9E51079F71A61144A8F13B7F979303271397998B349F1AD62B53EC90D0DED31B429A9448ACE6672AC28A74FF45CD596CE60D64AC247467AEB4E54C6C9A46719DD4D98D37642BF87AF933EE2D0492115392AA79373948D7D4E3BBF67C46E52B1CAB534FCD662F40C0B1F8EE5465FA0C40D6D49DC0DE315BD972B3EB87CF6BB182D507C8F97FA061BA7AE4FC2E5484C5D769AB5BFED418B95AFC1D2D5EC1B243D40586974A1CBE403092438565E8E90AFC4F0F30C474C507BC9CCFE000000000000000000000000000000070B0E161E28343C" - } - ] - }, - { - "tgId": 6, - "testType": "AFT", - "parameterSet": "ML-DSA-87", - "deterministic": false, - "tests": [ - { - "tcId": 51, - "deferred": false, - "sk": "F17916D95C512FEC0CEFA6A15C9FB3BF84FF8D7FA35522EB1C915C4D254E8935248E3C08582B745EB2FD13152B5DAEEAB0728042B00885BB92F844A86B4262035C9F448A2B78EF5DB347E0250415E1015FBB3431912407C85A2F362A85A9AE427723BF62697B77991B3E93A381133F950D40E7C1ACBC17E4F1D10CD1274C8D3C8402020AC5101CC34DD0947024C08994084DC2302063C024E18040D0266810970183C2915A902D44946D10095011A70DE404899B808D40B8454B860DC8B605C0C071020906A2002D0B2486A090112016821B2442CBB670433605DA16259A346CCBB408C4169024296C42900424064684126DC2260088400251C8409C162482182621060C12C2715098914A40284848215A18491BB7015AC648A1902C14182DD22062DCB64900096D40A84D24C8244C060880404ED318881209918B1231C91604641072DA849192C66522104818C90014446224C16040C6104A48289B4466911052D32652D8A60C0AA844D8260C648645442000D24885DC4632C822455B008D20A54501C191A2128420470E98A825D9A04DA4062D5BB00821B0804C102CC49871992424A436714BB649E1920009924C8912491A392AE0226961B25040268EC9A2080A902413350621246260B001E3C6295B2889209070C4A43108421110C071989820C4A8291A1532C4866C18146A024646DCC24C81026D49164810946C0A85909C348454242549A82104A62C610001614692E0A644E20090C8060690B82D0B858520230D83940454265041922909162054C62D81C88C094444E206301392490B1748932886D8A450D1329108B805A40262011582E3184283C644430281538804049831191846DB02891023810390718326891A0105CAB0014C840910118413B12061B8411B028C09986183186108C16D448609CB888D93B441589081043108D1C40419B44C1C8820CA30721CB58513273284B444044220611852509644033886E3483102826898069023280410180D1028454C846C09367182266418C6219018220A3708C49428E2302C92B42463467052960C8BA405D302850932924912211843280132450BA5501416659180650A446613B64C0138711149282243020B340401169180140E129301001180DC2851118785C1342802A211023844521464C2A0011B428CC2B271CB1600CC102104125284242AD34812084408818844012350C0A2098194500289610131881BA261909484912409031822A3466010164D48848911002ECCC0408CC051E44262DA241113194693344C424224C448900035801B98510B41600C25469AA88912864CE3160914272451264D1B0210001728D4A84548884801C70D93C8405B024951024A014210E1089003854811A8688B90085A020C5A18501187519C3892D0448210332188442D24280D22A330498825A1B2015C40201C0372CC968C51A688E3920813B0085C384403478E93124A882048E042208190094B066DD29010018249192891DA202A2085400A168A1C8360CA484AA2C850E4023188868853008960088AA2020A0A34450304421B400989A0694218494AA88C999030CA38910931728B442952A28D08146EA184501C314619B701CC06291109204B406640C449001324D0A284CA1629D0C084C88844E120291A97059042900440719C324E642622933666D30649A326514CA68984368493466D14078D182942523472441090123781D4106404A5088424091C088D02996C1B30500989811930485B144DD920200C012A00904DA102641C0301C2268C140845E312480920094140619044214906914BC08422955123380E5C2870C2402C9418629A304AE2864C5C108DC212219CC44DD996880C29451B456A1A006091300C120069A2A0048100655C388A18058948322481C64D609031832212E1C26C89009014B440D3B84589247009266CD9328A83440E21446199A42044162E1AC20809986C8C188C0C30628B46458010212033325A384C9806451A3309823444022009590041081308DC186812478643B82162028D5C100D609665A2224C83180941084163C28013816522039204A94D1CB04480C62400014422118021956409998CD3144AD1982D19314C0A924013984814892023B30D14986D1298059B14065B26910A380908982C19A0454426000A0521DBA0695142920B4300D1420D81302813C2200327601083910A537EA14F11545E254FCF2803952A580A4B6C9B29103D97436C003E2ECEAE2028017FF1D518B0B5D5E6242664ED337CCA4526ED5DB5EAD8BB3116941CD0C8F0A7ED5A1A5A00B98C336A9BC8EB6B3A308316F117EAA80D4B7756DD4A91DAA58E80D7B577558397AF905B67C59F14E12C158D292CA6B641ED0C75E39A914FFA1A9F24CA28F200C748DE709D15D722E7ED2C918DEF08CFAF9B7E24DEF2D51A4D420E7E8906FACD9A5A98B0D1D5345C8B9AC0BBF4B15EF0B46A8E3B6BAE0C6E9F092EB3EF1D49620B65E7DEDBEF687EBD0EA095972A56A0EAFB2D75F4321B80ACBCA32B1B11AA576FE4E0CCCC205212654296F0608FF38369AF19807568DBE171DB79EB8C1CB76A8EB95B288C9DCC620BEFCE96060F45A6A2DAC22F55E47DC7BAB4A793D9658FE27C662CA637008130F100D965B478177AC6DC35931A5ECC5F933122402C170EB8E0A41CB63FE5602F7B18E1DBB6DB30A76155C6CF030F738DC0916DB180F83F02909311CB6B3B9E553FACA05223B33C69602D0F05A08BEB84809651999A5526E776F3DE39304A5FEF00950A9A810D12E01D15D886DB2675F654CA17FAAEEBD1F561F9D1A95E0BADF7C3315AFABA8D4BEC1F0542A8F10AC666FD8D0C5AF1D6867A9D826BFB6B030B58ECEF6778D2C52BF62CB34B81FF936DA33EDAB31DB39AB76366D094362F046D5078B4223504A12BA0C7B8E883727718509BD47A696EE9880CAFF663612B9586303D6DE0D21F9A21962278EBCE60A6D46844095C5F892DACA48D782822453834B4E42CD3A1FE3987356EAB11EFB8EECD8E9CC8F39A0FF1FFB8069A441F851EB438E9C0B57E8818A322651E60F4B67890E5ED7A0FBF7536C3FD50D0B0658D7CCF275E8A9E9FBB99BE2E5F5E167BE290B7E96732F89E40D785AF25C1BA61A7786D3EF2D0C114D1048E7646DFA3032BFB7A51A63605DCE3E1D8989500D6E58E960519931DAC9F14DDA428F5A2C9C74D916D907707B53EB52C44AD71D727826EB2CA68070A6F0E47FA16E52E9629B7AA8241DAABB19497A5824E58D72675C3A67E10A119B274B84D9BEE2871728ED2F94F8559B97F979AE882EA549928D6B1A9A4E4A229F6EB3FB1A434A0FAEDAD62B70330CFCB24CB3498802A679F8F54BF83EF34472296919831CAAD59EBE83082EAB67D4ABD90229A5E93A0B580977F0813CCB15ECD74FF715FE8DB5B05CEF37D3493BEDA270584944C02098634514DAACE7047E47432F92ADCA491A3E0961A5D9F0144852E46326335E215243DAAE837927FBFDCE691F49859266E9008168C6A5E2F609C80C68E0820E72719E9B5873FA199E197F9C494AA8A3A65269E95B761B67BEC6113C144A56989C5750D450542CCF81B2462092F70715D4914EB2CAA3174BC9EEB20AAB6C640F8B5D9C6A0DCC6F0AEC97B3AF647EBF80034A43BF319BF40ADF79AFEAB5890D2023BAE02C9FD02C5BB65879C1B5EA406029AE77845CB994DB8C35211CA1DC881F7F20A4706505F29D9CD1989AD42B07EF52D9654E28E3DCB830008A1BE3199387E066B28B315CA1902F4BB0EE63FDC4C93E1AB886FD7425261C37AC58762D03DB60706887E72CF745A446DF6C6662F53DD612471A434AC56C4BEDB3C9F3647E6032B3CC0990A3A2E87052B36D4A162424E2D399E1BC237928D0BD77158079CCB208B7195079655BDB76CBAFF447C34C5829FAC199BB027A08006508D56C81D187090E71024DB7FBF3A7D64D8FA4874A8F470377B15380096822FFE465571B50C540558BA50E90EB81452F41275C2515BAE0592D53F6A6A34D2A34D8EAC6E7A03FBDB52494F4B981B56C09626084850C7CF962F9310722515A62AC085A6189ADDEA381291135731B2EE83A4F1EBFA09AF80A91268A87623CB557C9F66DEB454FB2F4FC2648F44415A7BEF29962D5F7C16E78579F526DD20E9209B6CA6DFD130F92EF724645B5B84D8724F3CF6F3A3B2A9CF61247A54BA928F53EACBA7E6D6B812C4CE21A18BA8D11450E70489BA572E5EB9A7722D9DC6AAE4F957936009E26EB3E74D9F9933F3DB4DA0A1F5449399B5E1010311F87D92C187AD2EFABB0A2C86B7D7F9A072ABC0C6606DBCD920177A225720A70576B8E82D7D53C1DFA48EA73181AF0AF086B6AAF80AB24981F275D66D4FBDE2C51AE8E8D45833729F45030130BC85B2BD9A14C813A37F1FA147F815488D7A17C0C039EAF866CEA75F5B2EBE05EF3109472BA5F7CFCE4C358B6080400C5CC085151492D13A5B0096A0631FAA30CB48F2DA873B857DFDB386D9339818073492559A0EC2DAF3738E1588B098751FF0FA1C871B22237E5CD15B0E1728EA267166C38A7197B6CC7DAD39116BE61DF4333CD7C2A413DB3063D7F0228C61FADAC3F8C331F44509B4D608531F995D15FAB119D847E6D8549575B7D850B2600E4D13646CF96B6B9DA6C62F2A80AE0258A8CD6EF4C55EEA7E78D20A464A194CECBB01E73F3276D66E12AD377451BBB94E5C948832595F6B6E382AD142D9F1B8689795E9EBC32A5A101E696CA34ABA005B4CEDA27D1200FE48FD82C17217E508A8484F0388345C9DEDE2A13928FAC32921842F6E6AA5CFBF57FAA28F43E05E9A452312502911EF9C33C811EBE7CAD730623DB7048EC218C7EA9DFC6E1965A9857E9294C4E47F4D9623CB74B65F7BB58622838DC44E16D915D9596555CA3D261C9C2AFCCBAF5AC03DE091F0DBEAE1B4A7E3DEC4390989676577A053684F57868D91FE6A5B7D3D7C7950789E89D83883BC3DAE55CA3078B08D991831BA91502A5A3354B88E159B0AFFD25B0DBB72BCD6F40465DDFC00FF8B6339C067095D6C7CB06F3BE759C52740395DD108296F2BBC2E7A5DDDE3D1C35D18BFBE3968EC59ABF85C1BD2928AB2AA678A7891746E88F439F8B4384031C3EDB73197E52A4E773D2D8B7BADDC5DD0A7E44C808D73B8181D191C3C89FE15EA90D7567E8916A337830305041B1E94B3B406DA4C36BEF05D9100AB992A4D562533730E0D8C052B3A62D3F69A83A0C9B2124F12AE7DACC978C4A0ADCC2EBA2D80F494AA16EC1E8E71C79B02F3261B6F9868B8D57E9D16F42B7CC66406549A276D371437DE88B7F39E74087CBBC5611680312DE8F0C36814E174F91EB600CC96E3CF51BB20258877A2AAEB827F7F5ADA80786B5084C802E606DEF388A39CE4F0D5BC19394CE841E2D2AA7425230580FA6675C51741D175879B4D03C390F652A503A7516A1F075E3082D52C60B8642A8240EE944D5FB427376B40B0B282E19AB908CCF20CA926116490AFED57EAD0DC0C8E296C79A48D088E837AF067DC029EC631F9933EE4D20746E64E5F216755A138974D308293736DC18604276CC418BA69F872B58E7F6E3A8B846EBAAEB383E7F890F54E77F5D7F5D4A58DB783ECA049F186171282BAC2607D51B298B14938EFB1928FC8D07806E8C3E73B4646BCF16890CC1380E7B633502B3EADA4477502E2467CFDB9ACBD1C72BC6AEB4F41E1C23C636839E357135F76BC39C4F9AC1CE8F1BEEFEBFF8759E8F71965D4854BEAAD0AFEDCA9D4D6BD1E63D348A42CEEFFC170D0EE9F136F5BE9901466926122F948BDDE2A9107D2A98BA2DEA6D6F2DA17724702EC518C03753D51EA831E95CB8708D5DEC822DB737E44143C86F47177D85CD098C21B9BC800DFA9DC26FDC261E921DE002D81C159F8EB1FEE67679D621ECE6B36D01C775A1645D52292B4B2B8227318772A8091E9EC017013B195EBF4EF201F4E881C493633C07F27C9790DD8AECC9449CF63BCB11946169ACFF39542266B0C6685BBB080B59F117EEB2A73382B3D187C0680C5AE709070DF03A008A7AD13226F3C3715392052F2441B4A178D7CF70518339CFFBB54A6D9B9CDE3B0B57DBC79F4E47AD6274CE2180C92AC6410E50D05F6665A57D4D4476C2C0E6EE0757A3AFEA2B1BF86A551EF98AA1DFCBA96315959452B2B3A2FCBBB955CB3FA1EEBBB83BD178767C02EFBBEFF6C7EEF94B55DF8831DDFB7B202CE7DE055EAF9928ADAF6ED0E3159CA56C483FA3BA3D2478CA394824CEE6ABD59670953EE80D383AAA608E15851135C1CDEEEB5F6A8897C3C9E066AB4734FDDFABC3BC3BA1206BA5434DCDEDB9D8B3A81A2E638146D83F14F06E56099C0C8A0FCCDB9ECF0F3D88DE3792F2D0B651B619C571B69F4BF8E7CD1910F266A4DADF8C2ABB4AC05BD1FBA058C0394C016DEE60C66401A17D13459547933389A356569ADA532C9F487698855A4D7BCCD0EF69531094DA4086F52BF98CDC9A4B0BC888DC3891A76096C7C483490E952326AE402D8DFD2F3DCCF1AA5D7BD698E2AA88D294813A88FD31866BCA11B3B91C009EEB667601CEEAFAFE97C56FA33F9381F3E4329901AC3B7EA7032C019E5C8A8EFD7044C973644AF2BE420A033C6C2C7CE0CEA3934DC18B42ADFD7A846F42DD406866A390929026ADE5C791B5F61F942B155077D82F2AFCCFFF85B0406647A9627E3695D4BEA3D58A63E1718D184E46B5F4BC8410334A4095D0FAF306FB9DC109425C31652D06FF051A162EE2B7B1C54D6C7DED6E395AAD1A86D03B1B6C800767EC14412EECE134620A61D369AF49E21B0D14BC4230649CDD3E9FD847AE50BE962EFC8CB0F339F9E6D3247533BDED8711D461D4AF2AE3FDD1D7D2A289C78CB19F3CDC2142BF52B23E6A27B39D699543C3D639B9C72CA80B37EA2775B5E2681F0DD01DFF0C05513369062FE", - "message": "9EFF341506D18BCB27A7FC4EAABF5A7C4A593777196F664BCE316C955B835AD4C9F5DE9A2BF89615DACB9C1E618C78E71144CD4B7046F47D9A600E9CE66596C4C55EDA23A66CC118A4A7BD0DED00ABDDCE53FBF2482033A4188506EC113BBD98D9891F0D69463A0D36156BA3EA0D02A14C1FD7A3FE704EE56B446AE179F72E104AA81AF0A2F8FCA6F6F96296059EE8826680E43F4B0740F47AC10566ED310799AC7141D38F6921315F23AB3E64C8A770AA57128090DB828C7BAA59C3295CCAA238C75FAC0F93DA7900741BCD94BB9FD3852EC2B7D33F600B1D51666AE222A57AF140FA049C2C9F6D0FE6C0F1E7A0DDE1143BE5CED7BBE232CBFBD8AE00EA5FC165026D729DB30F6AFD9973B6722C07F600665441E30B7C5FB297B8AB969C06839D331DEE96DE48687DC9DA531A95CA83A76F4B076DFCF483F00450E51C8D34D8ED8E4B3DAFAE664B6DC13ED88E6D63027DD438CB74F412E870CC9DFD29B52ABCA169C17E974758E03AC0FB7FE564508E017A9B4749D641AF0DE384088FA00C6940233DDEFB657C181C82A1B6A31FCCF4D52C9D351E6BDFDF48BCE414607462DB769F9EB15925BA9FAFBAB229B5896BF1F8E47DF17C8208DFD59604B6052CD2CEAB56400F11C4D9521E1AB8274AB5764C73E94132420E32B6AEB0763378D9BA68E1FCDE2BD6DEDA3917C000AF39B78F4CCA7C8FBF94B4CB8A8116EEECFEF0131EC9F2DEDA0140C902A8D6E60E98B3CD9D9C75248BF8845AC0D7E06BA0E18310FECE986207542CC1EE088843EF74A26AECB6D06F0FEFE1B72CF93306C32ED28AECC55BB103A0846D0C84136DB0B054F3DEA39A726C6FD6597F9B038CC23846017638F44368810D86293DDFE54861532F85F53F093048C3E009C4321127ADAAEC6A5CCE03E0D9E91DACCABB2F50E01EB2AC2B396D24B05D453BD51D529FBA51E46D30C56613005ABF6263B98D8DFEB52616D1CB7892181C2FC2E2043B994C816658482E0606348378A3CC8540E020273F10B69E2021A92D9C36CC9B9779FE8CE7A499AEB53EC6DDB4F2EC22BFB452FC5E797D3A2533260006FE6DCCE4E97665C68C3993DC7EA0BD4BDCD24721B02B0902B1840DDEC5182038762D55FC11B9873A0DD2EBBD55ADE3865CFF3D545F76335369DD9E70B0739977F6E98A6127194A1926A697E47F73E04FF5BD525E8F1722008F7C155CD3ADE0A5B66A3136FDD844AE5ECD6C8277C3D07F39721E911950E12820883A6BC8A9E793280FA74FF21AC2134E6BAE713F4389C9E7DD05BB4109B55EB92351C0EB921A0C3FACC5008CB85C3F2D5F9ACEAE9B4B714825FDE2B6263FEE1033074F59F073E9395C0D8BB5D1EFE5BFBBE180F7C591C172AAB05E7C53694C377AD27B9D1CFA0FE09293405DBE1CF8847A351F727768E2AFA56B54FF537CCD9D6A49D1CA745FF5DB54F860A74166DEFFB0B2F92106B7814C9CEFFD11D563D8F33A81C49D1BA83773572629F8B47F9FA27D2A632C70081E2EE7ED73ABD24C027EF11526E1095C2913DF692925E56839109BD05ED8E2C9086163CDF945BC16DC804C0F61EE8F3B72DB0245F6786981FCE0322FC2AFCD4E8E5203B51C7C372C58D5E292A7E2496C3F5D7F2B26701C0C167F49307114EBBE13F4F1AA5ACF98F20729B5128480014611A444AE6DE0437FFD5D84B56E3E550DE86613A9285A10840BED0B69F019699B34B86FC622D325269D1A046B53A4DF1293A52CEE1C35FE816B67819207E09A02C9D8594D51E8B314552FDE26DB7CEB8D80124A8A1C33748E05C1AFD6E87B567C41E0E73F325F25DD2F482190C404421A3D6A0E5D5CDBE2B0188BAC77C6E35D77C0A32B1D9629F88E70A765FEE38C1AB23975B945F2161F6CFE7E682AED96849547051DDEB77B90F6AF00747C47E02E80B69A0D4B78A47DDD81E299271FA78FE423ADDF120DD04D46C132E970F4A04E97A588D27C7BA84326182AAE04C251289971691D9678D409881688F3BCCB950830E65B784841004E404458E6165963CFB4EEB505FDD135F31ED0147CC9E9877FFF4107689106174E7666EECB6CF2DA9C9351DC434A9449384EED7F5F9077B42F0FC5D9F0F5F7219132FF9A470983E19D30A4F37D189744D832FD5FB397494E11ADF74F4E900A4187CFF5DA8F6D7B35AEA016A8DE8862265F1369FB367EF1860C8E07C33F3282B4D9837CDF3EF658422D34DEA41E56DD18703681D044E3C403AF33D1E7AFA96A8C4435FEBBA0D25DE0E4AEDFFB82A0BADE76B66CA9BEC7E9D73F1CB29CD73CF00C2F6044D83453CEDDE03F972EBB032062D0A8239FB699EC890D320F6FAF3D207BDC9AFEA2028B8699562343AA50F70A4E8C62DAF8B8CCA72D024763BAEC250023EAE825C651ACC4AAA0DB6C5EC7EFD071EDFB95AF610B6401614F4FC6362775C3810A9A2169F84A21123B031CCE087D520E99E262E8812E84098EBE9BCED6E6A4F73B674541DE0BCF5E7E318F906D901FEB1D9D1CCB6CFFE850DBFF75C8A89F43CB94895F28696FABB6ADCEE7697E60090387436E19B138819B90AEB18AC27D2C659B0DF17794A72F8BB7CE03EE9A78FE8C8A3745D505DED88500F4CF98FB6285B0BD82E27DED933BCC1873F88ABD828F6047ACEC472DEAE87D8ADE0AD07348FFAF59C17029D84538777F73BFED5C63630BC443E0FA12DE722DABBBC2250ABA3FD86154EE208D53A327A7FF26A01793394D04158BB320600447E2FD7D7C6DE076A513D68195B067204FF6005B1625542B28372F06806053AEE2EA9F88AEA29A2702154BF443BC707D0A96EB06CE43EFE66AAC1F1695E28CF107193D062E71B63AFDCF9E050BBED7484EC5E80C515AC820F0CDF965DD97F7A11B57B21A04BF42F2A33D619764DFB36311FDAD8C83A748BA3442C570645A785E6703E5BF22E846FC516CB49915FD63B63E5DBF56F55EA40116D5034BBB945F58D67695C796F1C1D053A3EB28A95E8F388E8004C3B24FD5FCCA7BB1E3B99A9F3C945EF8A535F137432071A5CA5B6F7DC7B8BCE55AD0F3B6CF1BCBB9CD35E241F86E4697272648F473DBD5B7681EF0C78449E6C5FA930D832C851EED2A651219D7D9C3BB23F3C6AD7EB77868541F3CEE09F51EE04EBA1BBC29698AEDD3C7ACEC4429D7A40CFABDA2293480164F37ECB673F2B5D7515743AF7ED0B6E096F0E2FECEC89F40D6AFE0BFCD70379169998CDF4A20DEB6C67AB4E36AAD53EDB98A1361C5E9B0DC1636D751A87B52053BAD5CD2BD6F6BA951A7E87EA4B677AE00893A1F76723FC56C494FB5CA2F5DAEF8589AE25B5476F4AA89D404AF1C2665ECA181062A4B5ED590B8263364153325AC979ACA1B6450828F656AD447CF7E937DB3CBFE550A469322B546ABD60559145E1BD42DAFA318B7A0D71170DE818BD664FD38BD29924180C44A6D341BF059A0D64855D2A5E291B671F490978B0ADD90EA619B30A62F5DB4EE7A10405989AC306E9C7BBC117538002EDFED874730FBD48AC6BEC720C83D51056748DEE2BF955E7BD7C786DF6857A929BCF8E381621B3758F2FFEEE8280836235B24681E62BD27C26FE9636753C78AB5A7EF29FE60AC29CF67409FE657CE653A2FDAA7F20C5019E6F7432E8CEB9E9992E646B78D4365FD0217746F7BA31E069D754E05ED5A71FC5E7D6D645EAF4144D6BC43055E6CDB8934C7026408AE96535BA2DECD2F7456D6ECA42368CD9AC5057B7D1E12F77AA87C437E7A43315DA081E53AFE23B5BCC2F4CE3A8006E81E08AF0A33C1A9307C8D5AC59389F26924116CAB0B87D549D0383C274E8E85D46E0FCD70E36842CA4C8D6D0F48F3EDF9E9435DBF5575F8EB789372758BF5BDE99DA2B98183DBAC82D1C12003724DDC42AEC81C0C7822772791504C90EA138B6C91DF5D25369CC2064FD5E2CC9D893BC4235D8817624EC9FAC8EF1D45E1FB58B38EBD8DAE12FFA037E07F5B411D4017AF952D8C42C61A2A1E8E7025D6D3A285AA17FF0DB439D0F2AFA04F318D6D576AEDC6F1E767A66FB39B72C67F05AF4087120DC898882DDEA17C9532B27AB59DE40D75D4175BB49273AF873A92DA4D87E253CAE72A5264E0C1DE4C9CF91A1F3AD605A0CC8D919351F9371AFC68EFBCED198E4CD1B58CA285DA0265ABACAECA8EACF02A4FC767162E247F73CDD73EE3278AF94AC4A8CB2B01556834A3C0B8D06D05F23B4C1747E76453F49DE08DF8EE0EA625647D1BD080E73C4197AECB6A23C25F00C6C54C8A4CEF76659528B36742EC17FF0EE37B306DCCB887D663365DC9E81D5147CFE5050DB409DFAD889C386F12A5CD0C95534113A6D0ABCB5A3F56CE23EE32612279E8BA239461258ED63E7883E115BA0581B81A7F73C1B79F29A1162E6E84C715BC50285FD38D4D6DC08768884BF4FB55853DA7B5471E73A1478DB1E1CFE6153EC6C378DD6A3F42296E619DE763FF2DDB83E51584C28DD8342E929E15B7BBCF5D6ECB8779CF7F3A9AC16A431F52A234E6A3699D9E44840A4D3D485DA5D90394B181EF8998E6D14421835909CDDB167C8C3878194B6D514DF8636D4A14A1BEF3CA381E36CF2E6D5FBCB40AF0917D6DBB875CFF64CDCECCCFB8BFB805458DF82C74EB863A969ED98B9C46E7173C090DB068B2D80CCE32DE5172B5D4A8B909A5A4CC47FA9F2ED66E6069CD96AB1F3E848C68720FEA32C5736E8AB51005FE425833F20756C1967623779D0AD242A1690683BAD2EB123D97AB23089015514D0C6A3B0F371525C23E5F53844C81DDE87CFE9F065E11687D686B072C1900F5C9A7C31FE8BABE9F090CE2CB3B687BA89ED83C0885DFF9112B52F6CED71E32A40A9ABCFFF420B62485847FFF703CBB743642255FBD0A9086A7B83F9EDF4324880C5208F7DCB1EAC338F9131665A0CA6BF0D612FBA63FF7139199B1DEE4EE1E989BE4A03AA8AC4A483ECB9EB41D221F5997248CFEDCBF6CAD8DB0A327FA288FD6AE313984FA618F7DD4EEBB13ED85C435C0AB0773C5CDCAD4699B9C382A1F37F9DF8C3AE157DF059F9751CCA693D5492AE9CD4631226E62E8139064FF0027CFA1954EE936AFAD0206DD2AE228B6DD65CD9A9D5FF9C0CC48C8C2E98F5AE6E2C9797A8384F8A3E3C748C706FE6A3625D2A2EB4AE2CAA049241A478C1A77F5C90DDC94184D898050187D670043E4E78F54DC608424F3BF5E92C70C0549BB612F480AEBE5FA8B013327103EA1283311301F91477BA63ED4F9C28FA34EBCA761561F9033541506219C5707C2F8ED81ED3615C8ACAB1280BF7C5E00EC1B27583AE9092B23166926F9CC3C5AFB66BA32F9AFABCBA7F7916A8242A79D7B0ED35DF6526D7D2BE6309901BDC03D1595C26719D90FC0791EABA767351253B06AE4B90A52EFBDCDD40C096F24E9529FF89F959557075FC8DDAFE6103A5138F09FBDEB0F5F36B52A57BE2139D89D2904BCE2B86D03F26D56F41840071A158BF546E10C4DED0E81B00D9888C55D53E11DB70026C6467ED2AB0BD91EE0E7C3C3E0837F8CB9BAE004E2A8FFECD59E792F13F927CADDF50F74D29BC62EF2F02AB0F96E273E8D66DB4482DD1BD5BB516E723ACB0F0B97BC3207C10CF394FF62E2FD7DBB3D4311B3FA2205BF870FFDD181C630C691D4EEA86B37B238F18789E00409ED18A63C189E38CB9FFEB303F4E43FB3947C74036CCF1624F856E24A7E9A21B8C27CF43D851543A5CAFDA305CC638D948270", - "rnd": "16B82B9B0A905BB3D87B4A1E40AEAD3CDE63B22CB716BD467A7BE84AF19B7CFE", - "signature": "E55D625692737213DD3D7F5142F3AA3387122F20C950930A7E7CCC0C6D21B95D6247D5FB3ACCBCB8A15ADF9758BA7E409A76D01CBF0F14C3233B21B05D113B1F70CB21785168E23A294A0DD03250DCBBD1CF80197AC7FC372D5A5ADF3E7E892DC60E759ABBDF698228B6D0F3F4CB4FD5DC5DFE8D01B4939F89531874292036BF34CA712B0114FB66942881F1F17E80B64E0E9E9E60D76AFB59C7969FB49C987206C16CAA8EC748E6C3AD8B4EF7819274C05A2B548D4715ACED4569D07C288018A39FB714C651F9027098D9C109C0D7CE8B817B30994C851CFAAEBF0595BB6E01E4FCE711169028C3C4369F11CDEBEB7115081D432B12A64EB6F935E4370DF749DF734DE35733967B72452F9270BB6FCD908267BB319D9E3875CD5B55106BFC0015C8CBFCE11841E86E92EC1A26886CF62A5C0594D7B8D07852688DC5BDD629F821DFB3284374C70E99D30CDEE90644CD77133482BA36207102B16EBACF9F1536C8F14E3630342D236C77ECCABA7C174F3F224A34A15CB38FD848D58A2C8B1BFB87DABCB6D959D69BF06E8DB152E18A3631A783CEDF36EBBEEAC3C6A6522D890BF95B1D14A9BF3731E01CF52995F0C008E897EE532785817D47E5ACC51B48A5361E8AD7F5C99374CE06EAC32645FFED39C10B7A593C0FEE89EFA4ECD0723495C9C47847B6B7CEA4D9A1B637C1F1FB4E4C38B04AE51363DC44C47E869CAD6929FDA1FEAD3B59242F70AE5F2C00FE0109A31087F0ADFA9B838F48968B9A35E74DAAECA4CD267C3EAC93269D6B8334C471E1C8938809AF00B57FD95A8E36C12E7EF10CC52AB3E448DFFBFF99C966D228467C433996699542ACE0C20C6599C8B0AE76E8183EA91D44811465F7DFD1D17B7C28E0779D799CE41AF1D0FF8EEA5884B347BCA14748B7C3D5D1F3DDA63B154CB3B5FD529D7EF0C7402C34BCCF1C6730C04DA1C75EADAFCDFA21E4B5338B372DCF4D074861B0B68B2705A08C71958402B21E59BCB6E22C3C204CDE1E3524C15B3CB42A8CA72DE3DC45266E29525D248AC21673DB80F291EC053E2E9E39125E118024F5FC864CD9F97059C8C8575D0F68753C7A3D1BF7D0DFE2F9BD44FD2175867725AFD328552A607D799C722F6EAB2F26440CFF52BDA1A907BD9D2A642E0BA1B878D3C4849AE1DBB44A4C457A8ED5A36B098D728E6D1734FFD6ED24197DC62D5B8268AE2533BBCB7DFD001583EABBE7403D80D59E6CE03C7E3E12C7367E4184E8B416CA4AB7EB16ECAB5A69247F5E81867D30614E0F7539EEF2F4DC5E2340E83CC010AD5EE6068E5F55C569655FA36E738682325F36A76B2C26CD64C8571F067AAB8BA7DB53481A068D36F17774E6F518628E8ABFB77F7244ACC89A0E604BABB29E95DF95289878BBA95D8EEEB484F5817EA1533EBB43F6D4B760FDF4F868B61D9AF7DA77FABB7444DE7C322D5C24D84DBFE05C70123C43CC5F00D51FEA5DC93A5C32EDE0F159A0B771DC65D2882020D859532D302DFCA9EA45B0F31E669FF6F15E9B671DBF5E19B32AE8CEE590FE825C197B843E45FF5DC22E496AB12D502D21F72AA239478DB517643E96139053EA574CDB3D43C3E7D65C5489DF6EF9E4C664F0881CD0F69D9ED7CD2CFBCC540E96D74E05D2B38885D860A4F2E4D7FFAF122EBAC45A3A3EC5D7F3604F27EFE035AC4A8B147DC4EF619A692E4980040C18B942C68C8A9943A65ACD7220ADFD9CC4AADF6C6C03EF483EFB4ABCAA44EEC4258FF98AC2247315FA0ECB00EE9B393F601F0095CAFEC22C355FD9D129B54DC166518F173BF4F14942360C5B58F29B5901FB157F21901F56698BE2A544CB84984B75A8CB830DE81C917FE4578116342FCE01AA625444B7D6C7F1689A003B7116F9966A906C2C4E58BCDDE93B60B7A097EED634DD494AD985D1B79514EC6A40E83180F1D85F75F6923A4FCD0A6EBFA12748792704762CAB2506EB43DD1B4B24FC93511C45F6AE77CFC9E620E4A52B3D7DF0EB517CCAFE58BAC4079575620C5068881A8A0D1B5C531A9CA84EFE639BDB05700175A13A08FA51D5F681DE69E540B3F87C4697A64EA851479CB925CD4EEDFCEE036ACD9365B368096FE8006A3FBFE86F09E9F26F442EB1817604DD6EF49361E578D4DABF05A1F49DFD57069C134597F248E61AB5AD091104BBA0A8A3A333CD422C66C29480159D567402EEA7E490DDFB0B3BF07A0244E811C43AFE732A4C923C23378B4F288E1C4E7D0D6BFD20B593B3753028C77E67C4DEDA27A9E3F2F525985F6BBE1180234930C88A63F9C414772AE22142281CEB9F7B70A82BFB2536A6ACFE8EFFB68609157ED9268FDBF22DC2FAAEDA50F62453DBBF929D7E48CC75ACD0D345092F0160BBAECBE6B330DAD9B612CDF511CF2B2AC6619A0559085864ECDB77CF64E24B6EF407685EE931B13867F9292E7AD203A6293F2258666A07D8FDC503EE66D466706DA4C4A1EECD4DFA3C3436C2C51E86B87B7CBC6716F36EF2B7EA961B0DA2C842BF30092A6D9D35B392BA3EE2E9E2AA9070CE0F07FA7C3BF7667F5CFED9721C4EFE7E868E7F628D41467B4317B944ED391B3EF92DC75C9DAC0500C6854EB8BC29DF6D6ACCEBD64486AAC95549A13F595EAFD5C9961984C04D1BE52C428D2CC8830026BF469F2097EC2CA92CF0A711EDE2A257834092F358B74ED63A9DF0DDD45F8258D3720569FF1EBC749087B57AEEF8CE3F59E1C04624F89D93514A44FBEA58A6AC9A7CA311A347442411F5561A3BCFECD92B6CBAA6A267B9E0CB3F8DA8C48A45ABE2101910C9DB0164C00B6F3BA1E9EB749A6393E5743FD37BEA8CD67D66DD906C696705AD70F1FA52BBD53D0E7E87E098AFA6E60E259170CA36E4F8F7951C48F6629A4DE4E73A92C62EAB8A757C45DA54B16D2ECC1346678FFFDA18E14CE46AB6AC65320C63D543B58BB152EE0CBB623430DBF708C6E85B07666D4B39C6942B229E3E45623D05032B1671BB851B6E84D3484D6326609745B8EA439600FE0B85BD2240A4A72FC1EBFDB522D51FB3EA7C6D20FB98A5F28470F7B92A12630C2D976CC276AC32E2B13AB3AB9EBB61B46A5F2D4DCE0DFB9780894A81FBB2723766B908BFCD9F63B2BA54F19EEC116726C798DDA3C5508617D5CF519722652B71F7348455C9D1FE75420A5A3159E88A0DE5771CF5FD270505F728DA54ABBDDC50B8DB2EB42841300440D5F012D7163D8F41E7707682B9C4B21F5710B6C4840DB1B821B27709F6D59CE4A2FA831356943F376D0D7C7EA0E5C8D9420F35B1DCB949D5EDA8900914AE63B5EA620D9E6D93BD3AEA24B5ACC9D17BBCC6C4BA68B165FEAB30D492D9C19484E1204E287C3A3E8B4479C7B5A595C2C9A83F9267069A12D3AE78870E315426DF97EB6CF3C95339ED505AF96A03278EC6795BD4D35797FDF5CB14DBBE39B9648A75AAE34A1959697DF87D8CB82F3257BF849E454EC4A065A40B7336C5D107F81C9107B80B4BE54FE6A1DF2903E768A4328E218F1551576516F055718C28D882DC8AC1E75CF2D5B818169F638921F1A6ED21DAC80A10211898D0F29EDE5AA151C9183B687975E7F4F9BF5FBE6135A902562D99D895FA788A67241DDF1314D0B4B62111B7A4068D1DF6D5502A0A423C7CF11F151C8169DACCAC8FB9084EF84E3E77264A1F7289CA917799BF28D23165303784668A1CC6597D489B4DDC874FD204A08B8B373B1ADBCF633907F337CF0E2FEBE62AA14CE0753FABF7DE4883798930A71BE8738E9D1DF65C914F447C04A707C8CC4A5C81AD487CE5195AC4298014FAC2261C5028B9F67F8D519ADABB8E90BA3BD94D61BEFD33C0CA7B09FF36847011B4BE81FE71EE81D761BB83A6A0DC2004024C1B4DED8AC13870C369C950C21764AD9D446344E5327B90E3EF4528A62392CBA1FCA8B439F1B1001F06D4915DDBAC7D87D4EECD4A063EB48465AA4705417C95473A4980C5AC32416A3A2BB9D92180C7C1D0C9954BC3EA0D3F0EE45AD8BD11D0766D3CA764D8CA4C8F582CDD951FBB768D10FDAD45CE716E2792C4A6174695DBD8EA9A5F0EE00AA2F579C374A770993B23D73EA496B55477718D782ECC0A4EF8A996EEB44B5BDC526DE16136E132D6A27B2ECC7892A18159B8C704113DF0F9F93E473CEAD5302DAEC047C861CC9C2EC04016117313F319AE724472C559512E9FE307B0CA6BB01520B42500EDFDACD6348BCAE8C63BFD0222E6912B4B61DF635C2B5F82072359825E0E21F79C371C7E6FD4FA91408B9868BD602F0AC8C899A1C610F12753D3FB2302E78E95B1F021CB90EE8DE02757DE40A3E78F61C18FC50C0FBA05A0588E868AF572E134B4F68E6EA421754373E73272809BE71D788F0D06479E4DB4AC3E0DB81123FFADB923E0A437A63DC215F464031F0A68ED3737E83E5B4978FCFC1206E8C7CD3AAFD454A7047BFC66A6A81C380C2608E6EE47258059A5398120EE5F499A0137E99618D0052DE373D5083B1846FE9E675B9EF853052F96189C090DA605B39E2F0B5AF393FF29F34F62D59ACE7464D0BCB308F1D322A5BE640AEBA5F51B7E0A443B1DA9489A2FED050F44B36DAD392CBA8E2BDE1738D169EAAE4E97CD61BA7539F281BBA90F6F82D4CBE4938211729AE987ECCC6DA17D476020B6EEC6AAC03C9508A08BFA04F66F6548CAA7A3A8BB3B8091B66D2F9D97BB52E6C424999763ADD2FDB3946DC1FBFA894578803CAA3FC07E8D3700A770D6572AD317B19EDF969840B81CCCC6CDCDB0F32353B64578A6A0886106048E1BCD1229500FD28C8951D1740BE3A7758A6095EF6A98C735A5C0FB4C88A1DACE793D4E4F917588E05F17F5EFF849FEB1DB0DE8B2F7D490BDB06B3A1BB5C6FB93EFF3DD60EA6711FE6ACC2C642A852E2439346BBCF889B349829CC004296D25CB19E153C6107D6207D2838B89047006604FB6102BA092F41A7AD64FDC6C6C27E5EC681B957C1C952CB70A8DC75792004DC05FD4F4883F8D431205E2140EDD2CECD52F1AE697DCFE9680673BD46373FAC84F4C4F2D6876448EC2199944EAF2332383C8B17C27439B67F9DEE1AE03A5A52B96B2EC4A43A76DF4DB325B54D663EA65C2A84B80CC652DCE6F612F58D1E5648A428DBAFA355C9ED5802D5CC347FB0D43207AA437B22F0B43B994D3D9C2D7025D6A1299E7326CF00C73513384A90C66C919889AF1B6F841B1DC60A480730B21F9B8017E660DB42B538D7D0BE1A30C27F62F2734537554F75E051C5A940814DEAA98D9A5A0BE80C1EB3CCF7888A4A203F8791F8484A70E951A85EF4CBEA299AB10DD853F106A9CD5DD7AFBF5D9D9AADF0378AF1DEC18EB00B664B575A500DC3645BD0C66CEA9BBD1F7E46ADA0E810F6A71605C41D2124514EF6FEC22734CA794DD1A422258140C4E6D777FF5C96981A3B86D1C3947A5C4611C912F67C35E871A85817D76F2E0B9D04333F1C1BA486F48D5AEB6DCAACAEB0B6BFEF4F16E5DE49053CF9E1380CEE5DDA401BC1650D078963F2B7A718E86FD1421DF4DD7DD4259B3ED81E3AF7157E704D226A883FC03908C88C4BF745459D8669FE27ACE5B9CC437FADB409ADD739C065A2143FBFA1B41319FF4240905FE5617529CC7E2CAC91FBEE2EB92EED476449AFAFB076298ECA0CFBFFA5E1B8BCD33FB1A97FE506522089EC38788CADD115EA7CFF3070A340E301BC5CEF7A6A431B540B881ACAA07E07D5E6A25858D1D82458276B265693E88FE21FE6A6B97D6707000831839A6913FB1B7ED11D3F97431EC21A2EE6904C0EA4A171AF8DAF152B278694FDFE6B9F3E7488B095F4A7A058EA8F6693D917A6F6CAD0316EAE004FE5471506D31E43776D61BA9EE567A3934240058E32FD497576FD80E8BD3887FE87472F7BA2625E4D586CDA81E8D49CF04925B50D0733CC917C30E6702C5DE48880D2C0D6804D551DF4F23897A2941B27ACA86A5CCC4F5D3E1EFB8CD84B56DB6511B812697AC00FC768D99D9358E4D3EC0C10E8D9BE579F3C7A0A4A6A2E98BCD367976F16AEECF918D91B1AFF2F543F6B23A399FBFDE160352186293B509C4EE279C566F0C1C1242F034BD44524C327E64DF7816D99ED78A11336542EC3607EE3F19979B929D3AE49883DB0C8539FA8D73F5BFE07540509BF2E6B6A533D0C4D6ABFF16DE309C6890E05ED3D5A9B0D96B0A43459A3DE8B666E457058E5B72FE50448CE46843510D9AD336A9C7F6CF6D2C9546986D9E7890871964D5DE1D9B374E52F514AAEE3183557C380FB3F6F21C6071681F06BD99FD4212543EBA4B60FBFB514D02CEE59E59B2E69867BBABC808E4080DF53B477839245680F06A1D33055FF2A238ADDF5CC5EA9CC70A1B5B43E9593D680023325D25FDA7CADAA1FD224E3496E70DFF893BA6560D1113A69D3BBC12979A2BAAE9E2CFD2D3EF95FC40809448805A3F4AD2B57D61A2267BDC32CB842E9B296345740D8554B216779B47516333E91A529DEB26067F97A0A1AA070F1E23ABCCD50F3E88AAC3ED06253A4A62859FA7D3F51C9ACC52879FB8C7DDF1506670ACC62C2E8CC9D9F600000000000000000000000000000000000000000000000000060D131D20272C32" - }, - { - "tcId": 52, - "deferred": false, - "sk": "D4732215DC31C10B5D2DDD6848918DD0B49252D9D36E7A1C7EC6CE516CC4FE334124098F2D07C14E787B6EE72EA14B5866D5AAE4BAE1D494BEE9B45810081456061C09E00CEF115FAAFB75AC4A2919FF822120A66CD8D4AA77D10FFF8272054EB0FE08B08C894F9E6FAAABFE15E27E565F9B46ABA37DE9E7E898C303C42FB2AB48141111C16810410A1C886C22A71023B671C8C84DE390111CA58082C68902342404102213B228D2904940386A6202518C184AC1222591082561182CCA3840649030118210121160E3A820D8C43018B170C1A64551C48CE2C6699C188211B72DC4A28C2229044230050C24261A334A9928500A498D41C8510B4408128981DB2602CC486843B2101448250225519B94840B418C10A82009B88DC12871A198640080444BA62C5488108938454B2270CA261044004C02B888122080030272DB140A1BC38894960043909121A42502306823184EA44661040280224786D3B2280C3848D104128B06041926654486255138841143006116305C224842244A03922553B270613232A3C42183260C1182602246011C16051B45300AB06808812008372E04466624266C80062482C42861C260C0160624010A00014689949023990863482E14362053B429E240101B838C0A346804B24C83A00052806410194600A6090A8501218188C2165003C6911039489CA8918B406E20068A091806D3362A4A2010E0A60508C14C43C009149100C03411D8420E419884D9C85104117150324861448A8C0450C2442E99C8209A144ACC3852E2948111016842266D942205A49681DB304224480D89A830C10061CCB809DC8620091764149021081872022940A1A485E344209B101013C7511B4242A2423191C46561A21149864813208AA214849B164E23197118318408B0285024059B1628940266A434512331212138298A12510C8540239571E4C68060208224B01094A431603689130150D2922543306E9442661044711A216018414EE3B6294A3020D4B84113069204494DD0C40D022272C8428914A00098262990A04D6484448A08809B8405103721D2C86118042948443004278E5306114C06281BA729DC148D61941064465063386E2447064BC66418904CE42852A4064C22440E93482AA13831641288E0168208997113C00D03B62D4C3800642000D2040098C48D9CA46958208C913060A22466A1B46418048154243010B8700B9821129310144401E4424D40B86519A1640CC62023188E12B36C0BA040414462DB008DCA38614A266C1B37440BC78518B00118912C22192A0C094C8034481B2180D3C02861048011814510938C90000159446CC4106912864158900DD8A86D1AB9511407200CB31083A24D534260E01085D14871220568C83626002882CA100501138E4B1209E4C06D482652218281DA38425084442027688C862923A36DCC967123040D921472C8984C934091D90272D424864C96818CC20812490E21475020050C8B9401D22440CA3600D4463088300DA3341083A411CA02901B122624C04100A3405904512119605346651CC58053207008244C813024A18401143550E0C8600248715448520B9224124469DB407164004E12A34C62B085A29890D990250A0909132491C3084ED93021DBC681D848245A2601A3A46011332A8908515418311BB32CA1B205D9262A1AC030DC884151864020112E20094001A9450883648996209A846504408618B99044282EC02810C098719032845A444019C14D11142409482ED0362D831062103991113072D83846C3240A9816858AA805028028104230D820655AA291D0A85118342621B820583868A24664109051441469E126469C304CCC9081040591E4226D58088DA1324004925100C129D1A868CBC681E1848D00C3100B230E22A2650CA9659C00240A2820181181D4B640A198851317455126899440460B2969E1C64CC2000E64023120448A203571E10866DA1429980880910492E0C2440894709CA62042384E43A4041B456248C60020130AD8387044046EC4386C89C00D19006149C4481A918D0BA42194C0919B30401344881381511AC72814284C82888918250C001405C146885C446642284008B76100270DA22246018270D1144E6394615A8005E1B644233708D49290C8465008448C942291131891C8024D53128E0C137159800891140920140018B6308302282046701B0400B199892B43B9C22F12E85984706FEFF279553BA31592B15FAFEEDD2AAD38B64279A9A7859130EF52DE8033F622C477B9DCCD0CF2BE9AB11B9FC9C2EB068B7067025F0920E2975320AA4FEDD28A61CC4D31D6729065A2FEEF67143D7FA32A0267882E176804A4AB50D45F77891682A9B071A3B6EA7F91844F6865C2CD8525A7F305AA1B1F237A2861F03EB4255D2CF2F1AD338C5F12C25F5C8240F140440103AD3B212A0480E6AA45D8FC7917E85BD91EE0A323F5CFDD292A066844567E7FFBE1DEBA04454424070FBF0EAF35D55D2095119114AC1CA7CCF6FCD0981E6C3203D16400D5F5FACBFB0C7FED2A897142BCB02BF767481A085F82A12858BAD2F318E27405BF8DC0BD4F941A16C009976E82B35A7C63D99793111EE36374C2A22CDB25956892EAE68A9C20A185CF6FFF2B374D7D62F5FAB5DC408C5411FD3E957DF529F3142D6EC5E37A987099A41F00BF00A2062B6B0DBBB8D9CC32291ED9AB477881ACCA9370119DFBD46B937802BAB1D366EEBEF995CE60A876F2F26D0468460913F6C62715E396E3FC1FBE99C36A8FF994F94DDEEAD4DB70C7FAF0ACA039BDFC2910DBB2EA8B344529C3021773D88E519D12EC21FB016447860D421B6E60247C72AB9F2AAC6C856C6F7490850F1F6DF6013CCD70043B317B12C74EDF3C2FEBEBC65EBF284E468EE276072B23A9736CB991EC14CA4A32F082988354E66BEA2CB683DB43AE72664F0AD2FBE189D8B4A75DB4EF6815E8BFA37615114FB48AEF3AD588C7912CA74844A6D930A43625CF9815014F15A1518A5876A51BAFE5B58D258318D32332CFCA4B47E01F5275414FFACDD83E8F20562D7EF60AA9021DED08EBB8E900138529BD2CD06B4DDE6EE598B20E0FC056012A51BFA0460A35148331AF80118358BABDB0BF6A62839A08233E1758990CF95F23858ED16EBE11E92A471DB396E0E5FBD15BBF6C01B7039FEB9B9DF71E6348FB7129CBE4C908EC2FF239DFE55A21211FE892A06542B128C99B030FD2E2B5B7A6A48F15716C67132C05016D2C5500679CF3F30D9F0B477CB5083CCF40C89D7F996E87F2FEB4D38B33985B7FFC2CA627CE772369A85C8A46E82F64D5E1F8EFE782DE14B058180F2760EA87B595B994E66A319226ABCE8CE1938830E4C2F40238D3D5D111F8013655E06CACB8BDFDCEA72B3B53FB9A0D7889E670B4C4A60A9413DFC4B8CD518FE0568C3F0D92BAE99F8D3D1687880FBD930313D14012DF2AE9C765B3E045573A1A94C16A95CED4B1419810E41431FC3EE84E1A689873AED145F31ACEE02D1EC90022C327EF101978BD0BFF114316F32F11CA3CB534FD37B634A96E6527446B4594825AB2C9ACB831DE697A33476764A00B2052C77A71D3399077D6EC5A5150C37D9565BB7284FEE8E23703C2BCDF3CC01DD475AE8A6142470292ED8009143D94FA293CD22058C2D6379115DC964C7961224F2A246B13CED08904AE423992CA500234DFE3CCEFDF2FEB8B14AEAD89BE7CDF2FA2A752C3480E71CF525FB912D639251DAFEE65AADCF496D920A9CCAFDBE8FBC234D6727540BA58435C5B9659F293371B3081896BC09D201412946E4F59FBED616CA7E8879918DC844EC63937F75EA0B2E0C301BBEA51CA06FDB35DF398B8AB0876AA8EF3E7CF0EB9B4ACE42CC9A6154ED9873173BE2442810E54E14111AA919C56608253493E0E37E0019FC8F336575551C29F6E9045B94CC7B17494783C9DD849EEB87B946CDA439633D32A81097BAD2D503EDA2DB4D28D985CA16227B9FDF28A6CAE26CD153D5C20B7B4C93CB411526A67E5D219AD777C605EF94FDE297042B67CCDE1C6F8FA09B28E55B573BA9638AC5FDE92955540F93E19B4B5C0D5BDC8158E2F97AB306FE327D2D00A86CE3A729DC4039F8613C2CC17C9FDA98036FBD00DEAA47239DEE5175BB973ACEE31D39523A2778C13A379EA2D84C4C5C0A644DB76306D49C1FAFF303009A17F58E64107B14F81EA88F8B9009F0ADF6F6C9597B7D08A49ED7BAA150929EC183F072D17BF02E1D9DC54EF9EFC50B2AE169181F040DD58A333BD1AC649C64A1BCA43F799C2453F2DAD72B8C9421D0497283ECBF8096FE558F2AC0C35DE49A742DD553892E757AAE91553B4F42AA130C8397DC826D1DFF96BFCA500BEB9864B642470450E2D19C6387F8F40E482F2E72BFD8D28BE379D4D1B4B32C76E28484425C910AFCB1F851734BF59E9E1558B70E4DE7DE7465EE0BC24672002703FC953059E063BD82A64D6C328913FEFDD2462AF24B4A0ABF0C38C38C32428F36BFAB0A8E6EB902D9A13B019EA999ACAE7D425BD8B9D995F7612DA47A30CD0A9D05A7693FE673789E63C07A9336B55AA024D2DD8D6D424ECDE8AA5144D296C94DF9FDCBE8CB39A1CBE0AB83375E531CE5BE7577C552789244CDD12EDEA1B668C7F6A1D86E62922053DD2740699BC612454E40BEAC997FCBB3EFF27FEFDF09EB6374411A5EE2A4B476E7352269D57AA14E9D9E824B0A9AC54051688947C4C6C8FC89C08F596626DF0E2988FA9FC4D6EB98B6A4631327A17726B3A6FBEC9EFA4C31B897F8677B26EF200BD5BECEF497F93FA5F2F50F93805BAC6A7B13DF5599986B7343A547780BEFEB6F478F198A2E7AFB6EAC84C0420140D147AEEA92D706BACF44470C42FA79634EEBE6595FEE0E349FCC5D3F66E0176E6020E23219BF52D6E78B5BA320884A64F00B1186560C0B6B2B4262554E19016F5B75B4A9188885C9D18A20D065AFB1F9BAE4F85021199BE862FFD07D4B2BE291C22EE580DC99225D631058C17A26C65D9D1FF043C33C352208DE67B5199D27553D576D4356CC64C78C2C7746D4447A75E943ADF3FA920F790221CDA9902EA22A9D88B0BA1EBA471C0B6E5FD8128A2FBD9C6BF892AEB6C6AF58929AC28AF03BCF0ADB80970EDDB67E229578B5ADBDE06EDDD2D5EBB7B36DD19870FBDBA34E46AF80C2968D8A0AA601D8163DFBD3C120E0E756FABB187AF351ED09BF5236972A7EA17A7060989DBE3E917EA2B33AEF0C7FE61A5C1A3E59AD2362DB7D62962C7878CE0D4FBA09CB8077E1C904A33C2E5CF2AE7DC623C826CEA732F87D7558CFDE29B3F6D0BB777936D1CFD590C1D3ACA5354F1D531891767AFEA3D5CCD906F67F52A8F95D8FE009C64594956A97C000CB1A5101FBF46B8099E92BDCA7844D3C59C92226F1BF3ACFAFE67BBED8F478E4EAAC5D665FED72C89ED486AC21D918AA83F9FA4B094904922059BB9C3309260DF3A9F68B999DBAC242D81489E4BB0AAF75500C73F4502B26A2B7EF1E135217F116F0AA53C241F1CE5A99E0D43A707155DF73943E407481FADC82C0389C8E7051AC5AFDE160828BAD22062AC33D03BFDFE511E670B1BE7F447A9E3153D2BD8D3D301F88F59E55355D833D4C37FBDBDD04ECC3C1663C7B4AF4B00847311486B6AA6E8118FFC2CB3291781064E69DF5A00CBC423453992E7C2BD447E7B3B1E3129984907989A36B504685FBFF594FBCF7BCD699A404B03BD10FA844CE0EB5BE620FEB7C1189F830A32E8A6C91918804D63CF7788C81A7D366484790EEB9BCE8F96A2890F6504E75AED56928D49B10F2897BD7C3454D15AE4D436F9D3E64E8313E440A16DA6D9E603C1196FD023911D01EB5702D7884E664695ED4A3AC77359B22C254ABC76CB7B9128A7D49709829A0982C1048E1D7265D85F718BD58FB830D4A2F5B07E9FBDC9C4CE1B83E685E77782F82B8FE1AAE447C56BEE5408D6FAED115676F56EF5BED2FDD4406791028125377FA2B5322C25731F57DA2B39E1C72B6FFD1732A07CE5AC34077EEBFBF57E336608EF4B57AC0F1C56D954A6758DDC07C811158315D6F1EFF5326BF2FF0F568BB089855D280DC81ACF8D8F5A767A9C9695E5E24E5D768A98D741724CC934A65546E25E586FD0ADE826891D37EC263F5FC3CADB1E9D2CB9071C6E3A3867978564EED6AD973A2E451B0988F915A1275E51896EE3E61EFE0ABC10D31A0CE101CFD0DE4094588EB7112FF64F0FE9697E4F817D188C9463B84D342C08E1D5FD9E0253B374B5C47C5138E62EF7C1EAEBC86661BD08435CD0C4ED4214CEA05D06F99A78CF29FC88451B01DCCD839698197E9227D8E950FF8EEDFEB0A44B767DD7076824FE9A29A192A4124C2BC9BE2C72DDABBC8D5239763A237F9A0E887ABB32741199A7643F1A53F6805E56BA71490A262ADB118DD965792508C793D28C69E60EDD79BE3D98B8B92B4D0FA6AC45DD496DBF3AF08B96C4183D58B0D5A8455EBC4366FA1F731EE10F73D432D5700F5ADBBD1FDD5D324EA559E9E2E87783E2A48162DFF8941221FB7A0193795C42783A743F7D8B12F60A407F5E72986DD39DD23313243DF89B00786BAECB6A94A607E28AC0386EB70C97947873F5AA91C6B5FC49C754E476203613211DA0D56F13452FF35E990ECB70C9CA532E160517BF1222377805850DE105903C5AF0DB6E5C2F7A55E665283887D46B5C4B1B3A079BFA63341AD1D921A82727699FEF69CAC37113C579D3813484FB66160C72476E08E9B985EEFCDCD635A2EB683EB39219D2E8FFCB070A2434D2E4615622057FE47C7EA090EEA6D80A99B252B1AB5B39D254D5FED455D39133C9C2185022F792AFAD256B9A2BA4274E01618326348C55228A28262C67A0B7D4D63CAB1A4D290CB33F20997882266C32809C1A3B4E1C1AD6FE2E0B1EB6B29E8663CC6F53745FB36D02D3D1", - "message": "0F2DDCCADE26134BC425DE33091C33A9D2C4317DC67E56A56CC097C759FA6C37C610768C08C7C8AEAFE00CD762DA9B50FB0FE29850DEBC86BAE591A7D5C22BD1FC410EA46D2EB9B45C825C8304108AFE676C8A85CB6979D5B5E4BBC17C25300B6410E7EDD903BD8595AE01CAB3726A76A60ECC06CD8FE2E42FE8A82AB44F625E4C0FF56F86310C34725815AE4DA9BD5E0E6F10DF847D1A5A806E1FE5382FDDAA5C4E7371D079E5B7ED5083E8EA62524ECEE15A91FABFADC080C6E86CE9F985F640FF109FF78B3F69010A9E313D9B2068DB08DFBE261EAA6CEE6BFC10E2E7C28B82C1840ACA2D57AD9F80AFA42B9B2B7DD6CB54AC8508B7C50ADACD4F39DFEAB1AFC9CC6919F7332FB564C6DDE3B447BCBB36EFCD9872554F2A9D02FE5D0C12665E93597358E7B4C698EC1EDA57E1620CD92A5C4C454944083D2550CDBECC1BD33F1DBF46C120E717833416DC7A92747A6BC0CA78E051831ED91A943FFE37FBAFC9996CCB5CCECDA3A33C9EC8671E23D1644E05B97CE56DABE91C148FC48A5321FD7EFA9E63D8C97079465E4DFD6C3AEEA958CA5258F82EC437D0A4263E47EA01899C35A20CCD292EA15DB1AAA9A47B8D4252D6AF8CDDBD3321076B8D076BCE2BF007F279FA7D4180085730162B4FCBA35DAB910C72DB097B1630204D4D3285D174DDF97448D938D45F498B9659D3634154B9BF8C3D4209EA7C3B533252A0C993ED8AEA8F901F5D1C38CE4F7CC685B7696272ED17C5725B5F6C8994A6F670A3AFC5511C103DC6B342D184FF98A1767411E149A3F54F8FE4099A275543612FA13767F1F23A9698B206683DA6AA7CF686C2CDF6D597A80BA0B78BB3A9EFCD1B7F782E7B8F28384107B7E14C01F04670BC4417225FE1A7D0B3F7192A7B9E4F9453692EED1A383B9DE52DD77D685C03BAE20751F9832085AD6549B4CAC61E6EDF344AA904AA28770D3D9B43E58F0D1968C2E049EA7D84DEFD6ED816914679382912668A82C5C59A2BF1CE7D621EF4867CDBFA43FF478046BECC6ECA455469DCBBFD62D91589F56306DF916BC342AA6C381E6BFB2234368BEB7C147728CB79BC5D92C00C8A2CA4E7D61D7835D36CC2D2439796BF11C66E7C0AEC05BA71CB807E1464D78615EE03CEDD7CC291B04077F1378543A94A8E213418D6FB8EFB826398AF29754B5DFA588641E04D32FB8752057A013DD56430A78AB034806E7544AF2BAEBE190345F2F2745BA7D9F118D169994470D3AAAD1256C82CBB3D4F6FB32E1BD26604652097764DACEAE8BBF8D445EE84EF21A4608191B323399ABC409E5F4362D2C65DBFED896615332B3EC67902C6777DEECEF691ED98C3C352AAFD8B80D729AE35FB9ABC6B72BE18354D19547675E39747C07688F198CD60192B5F477F4A8145933CEFE65EBE3E6457E829BBF9DDEFB2F27DD6021DBDEB24E1F97BAAD616005F0912326627D6141DC39346DCBDAF5A94D6365E80A98A57C6A317BC73DC02F79DC4E76A5372C5E850FD808D74838E3C9D6D57ACCDB3C5467466A42B1026129D5008C96AF94CC7EC83041145F0FFBE6ACF27E2867A52FF662FE0B71B5E49EC6143708C33ED5D637FF3D1FFCD1AF4262C820375FC87550EDC3BB7C75DCCBABD82D12C3A172B406E44236ADB882E3B1EF73E84D61CCBBE8E7E87B8735CA187EACF592D0938EC65B0582040BA16D49594AF1369E5B68A17B0DB65267CDC998E84DE80AF1EC3EB3160233B60347B99F3A504940DEA26656A7E78F1F46A4C88EBB954BC5309799929BCFD8F4B210990A1CFCF7304C752E240318A29B8ECA82FF06E5C69C41C69C318085C5FCD6797F4A830DD9C993CF6472219D9BCCD92A2851BCAF6E215B1C07F6C69B0FB0F74FB1AEE57BB5A72C3FAE651711A849CD52DC9046CD3C981864C638B4F60942348B93D9D7592FA5BA7F1EF94776961144BCECCFDD344C9B2998F8152160263B38E5EBAD32FCF6AA22B9D4935866210079E7A8DB3142281038D6D6DE03426F8F02776F78871008FD882E1205547561F076FB6780FF38A2985E72CD4BEA8EC834BF2908CA56A80BD1789803E3EA7682F612B16CDB871EB81B31C61082F181859C01FC8BE76B74B1E3C6EEAFA743E46E7EF5BECD702ADA313B10744F188BC2C0184F57C848F588A4D03187A5B859D88F70DEAC55B199C4F3CA3571701054E37B6CA6F98FD3653D1B5B6057451E9476AC9084940BF73F7711CF2B2D8600D4153776A64A2EF6691414DAA38538BB941EF7CB7254358C5A11B6D5FFE8E77A17BED0A902D93D9C322EE4BA205618E65D01A802A79DCFB4BE4A4FD3D661254DDE3530BC7B85BD4C219F694208E3C6A9E58D371526B5BF587B5C2EC0155F3B9B60EDADE7000E739426DEC856F63B00ED0A652301FC963B7C2C40BAEF19D41AE9F65F7D19D0D11F189F33BB5221EB99263B48A4303931EAEDF77EC82F1702C7D230FA429F614C25BEA56C43E78422FAF46FD1F1E1B64BD438EEDE55F68FB484D31B3F852CD008F83D2A6A8C1D7AD9CC5D7557D3ABE5E311B6171298597940192189BEB14080604C437DD7C4D801EB5B8737DF36A8E60E81DC80158D1C5C6604EF329E08C651043CBBF0B9AA77BFA1DB943EF4CF8E3F4BBF82750254BD1C3D0D284F7479DD8F8A7C075D75E4959106DED4C29959599E5463AC7B8850CD0B8A21E55F4B7E9E769E3D985E5DD292F82B1AC5DF50473E226C63CE12E07BBD22CA553008ECC0ABCCBE2519D78BC5F212769CF735739760CA3AC22FE74B5CABA80514145FF5199522403976B10168E48C5B096F9C23B236DEB5352271E2FC0634E61B3060425D2BE6291AF7AA7615FF5D3412E3518191C3358466BD20FFCE3D47E3ECD700C6289F3E6AE12DF6F7BB35625612302033FA11CD1BF698E19B86C75711EF65BB88557F7443174B935EEF3C2D4848B7C7155F2759986F5635ACD255A6848CD633E88DBB0DE9557F6B43BA2C723C45C3F13D4BE3E8134E39336358C9B2828F5D8B5178631C39E51309374A97D1A2B98E6694E825D21837AC4BA9E4F2FC5EB6B5EB9BDF3BCAAC68D9632E0C2FCF99E32856451879486AE96A9D331F7513483105671A31B4CB1FD38F1E2090BB72C4DF5B1F083B2D641DC01D409A4B9E3B8709F3E98EE49EE5023091728C97087839F4E8C14AFC2D4C1A844BB926B70BA1460BB53918F577ADA0A61B357747E86979340795FCE4473C431CDEF6924F8B1D6618BA750081BC419AD5B582386058F98ADDF8B1D471C9F070B5CAD5371283562853A5D031734771E5EC07B6E4C7F20DE2060915A5B3711BE8FBE85803A22DA29C9A4A2A7E4AFF93F3AE65458DA2EC690DDE7754B52FE0727E241B31074B105B319569C120FFEC596ACE359635EF30042CFF9323FD6F38066B7B2A6A946A623934AB34BDA71958A0F264B3FD264BED988EBF9B69744506664310EA79A0DECE2ECB6BE22387BEB3B8690778F3C58B1745E4CB3962892DA516CEBC7C5AD1B1B86B6889784D91D263C8121497195BC522BF7BBC3B594A26B843A97405EB76C5DCF020D4C8F84A83022014839931615E8AC497E320BEA1D9303171B2D093F2784BAB55F867E699CAA29C6ADD228A5829F68A07F853B27132E898BB62B2ED2F6CFD470DF16B67D892CCFBA5A1E19A71FB9434AFF000FFBF499CB150407966B6584E5C77A475FC5EA68A18F8130C0DE448D934D969456DC964EB73EDCA1E52ABC51EB1AFD5D35B206D9DF56DCA649ACD8A7B6E93253BC509FE224AFFA659FCABE7E35CBDC9886FB77C6A053E5F5BFBBFDB2A47B6BA4A8F21CC7B38459AC79A62DC44C9B61475E7C23228DDB45D91852667E5B730CCD8E0B1997133A15AA1D04A1E52CFD4825395925B049FAAFC2892F02C92E76B11A8B5AC295C19BA1832D6C1C3C9DCE081A1C95F40D8D982751A0DB33B4BE42163A413EB4351864BB2E67B348704B4F9EBCE3C00B45B1F359408FDAFA7DCA083776DD688C3C8BECDB27DAA601E7D8B72B9A58FDBCF5B8F4A2CE7B4022F48C95D4689A212877EAF7B9A0B6C33954C2D480B2CE87129E70D19705DF7733458D92EB13FAC3BB5869FA216B9C2DC74FF98246AE85AF8678A8CF2B557992710C6256CE7E1333D60882056155FFBB6E9C2711975183959B5B10FF46D0CB3E5ECB4F21260AC9EE6091D3C944210B9777EFA0F694D85DC12D8860976C74C4AAD1C7276CEC77AA0E92BBE9F513B11EFCF37D730B7B9D0585383C98D1185CAA4A87E77A631DFE15EBFA1B93995E95FEC65979F416BF4B914C2A456B0263A5292655478B12777875E79433570CE930CBA33EFC764283FF9212F9F2DC93E5A91E52277DCA29393DC2D0BC7716515E8A3F07D850AC82F751A41F71C44F3A49315EAA84B5972938A3F3EA7E6E94271E03D7492C25C44454A308BFA602CD2D28413F509E355535D36C2D9D94012500104B223EF1787B8882FDE0DAEB6B95654188EBA46EA5734142C9C1A8AE4741357DF32A3C670EB614E5AEF6117698FE9514DBE4D636A3F43B878A4DA78C6136780F5672EA00AA41265F224863E0FACB8F714E09E5C0508BEFDE2AE6A93415362D11D60C412770E31EC1A527C193D2666D3381BDC38E474F1B989A5AE3C802CB86E3DB354668FE112E11982D106C2389390EAEAB009B1A09471D7540399EF5B6EEB593E51D0C741CDF8258DD978E6D91D9D3F8D97FF1811AC8F841BB85DE9386EF30BC7DFEFC5D32E72E9D81B5E30288D9FA1FCD25E4E7AB3391E27B3E5C4A7C030EC09A17468BF8A01DBD669CB5ACAB748018CF5B9794AFCAD4C489F5FE50A5953A36618E7609F1CA7A64B994B27FF81BD7798E02DFB73A6F4F102138557205D751191CADC782ED0E1AAF12D104FEDAF5FCDF680328F6AE56E3291163170B798D36BE938D74F5FA3F7DB6F88D0E1E9960733844CF003B96E4A691A2C2C26AC5133D20EF9D5E4E2E41AE683FBEDB54E786EBD3CEDC1EB6AE255CF2DCA236A8A7BC75D4E2F6A4843342156385AE61F3D68234D86B69273AE71F169422929143A43316A0B2B2D61B5F573DF51706D5C5BA7F846DE6DADCBD5C2786B81103DB70372C695B731B725BEF1AB3482783616DD72897FE03C8700D8E89BC240DC636129F64797873ADED527D873657E76B47184B937E48157AD5B0A5DD08616DF0E225719AB36F9CAD005671AD79D87916EA97EA2914EFECA8AC52D4152674045FFFF760B06DD202324260826BF0C2CDA9C6CB520CC06DE742D6DE6DB6A1DF0E83C1626F478240E23CA3AB97FC32C2871A0975F534F8C5C16F3EE2F04F0FA6DDD95DB52D77DDD61FBC004AD281DC2625C62E7D5C7EB96B39EFDA4C1EA1FDE287762D73225788B59865F4AE9F31B59BBC5C84ED31971C0A4D800DB62D753C136BA07C871D9983A9B45F14798907EB46A507C25BB4688204FD4A0DA6013D15ACDF7DB68B785BA27EB73856B49B1A555A260EF342221B90212BF4E2C0173BE20A14B093DE611154994AE476458AAEF9E00A24E1E348295D725C189DCDF4ED622E7EE06294FA607F07F23C6C7F8EED39C9C1D7AD7A6A60EB76458E3FE11947D6B6630532C377BBB8B89E4B4433A0A3009BF9B614CAA3C634B1A3DA4FB3181E5336700D238E89337FD6A251409E118F50954158FF6C7D46C38693BCF6F7915A09DFE956C2F13841F3F8239211674DC76D9AD1E10D21FD3C8C33FE5BD07D2BA368B3B88D667F2922774F79FCA90A79C2E26439229AFA0EC16C4FD5EC13AF906DF5CC9C8A292F2CA6BD6CDB1CE36A8C621F120B61EB2170053EE2BD9225E68E526B5D67356C98D5EEC524440BFF4DA42AE1FAD3A202FCCB5C020923FE1EF1CB0177DB6A88946E5DF3B50E5DB67E720F62E1DC83F0E7052DD6E5FCA3C98B8AFC23DBC27E0EAF850665EBBBA830D2B159A6D3AF891B14A6C3F5E9190D9BD348AE5D3E3068D719E2116AF79896ABFB17EFF39777123AE73A54439A97F1C1F0FDFD8267A347C2A5F11DE6E9705568E95E8CDBDAFE99D1CB150185F30DC836C8FBDB4D01800A88F2CAF23148DE4FE8C0475063CDBABCCB4BFE03712C398C972265C4395916B03AC15A9597C9E4CFCE862DBF80A4EB9C8D353463B1BACCE38761BB1618ACD6167FC8F54E6A47F100AEB0BD3D0FC1EE53387D710F6F95782F10C4DD88C993808BC33C806EF72319FE44A4F92AE9DCA765EA85A998389A530037EC72834636A4A7DBA71AB726D8D8E116A9AAC395AF1C834823BF6E3A5B33DDF4A747D00530A8EF678FDA0560F088A9F4E3F46B7847A77EBD78B4EE250C36B5AD7AA7AE82CCC50A15220A3D2ED9FCFC11E57A7111E0589C56CA9DCA3BBD1172CC09DF5CED998F6F55054CD0E3FD495A43EFAB367E02BF8CD79548113B1A1061F3EE3A78343FECBD1CF974D06D2F319EDCD9E54B1E04610681139CD957AB68C9D6B900159C2533283BCA3BE00940A0736FA0BDA4E4E71AF304D69E6868278757D97D110DA2A13E997DC93239F765DD1F7B0401DE024247E7C6A2B6DBBFB1F26E043345E6601B77707EBFE72BCEE196BAB15D195A958B8A1F6471291911BD5965F4011A8E208E7D955E976A8D62AC59EFBCC8981816E76F1EC16675DEB1D507E94C49D728D053834A76304105AA4B85DA50DAEF19A7A6AECC29EBE1A3D9F4C69F9C14D8E886A9C9ACE140BFC5B39909A2094ED27774A4FE25315ED19AFF648A35F6F59FB4EE8F28225164BDA5CCE02AFB85E0086329BC943CC9C677AECC1B109FE58BA6DE958F8311B2FC3409E0C7ECA90D9EB6100470C09CD3354371A1DA1F856D9E6DB989379A3BF00CD4EA5968710C381889EBA17E3D53442F1630CB731E86E78D7151D425C1968A578E41C305CCEA650FE5BF610613DFEF41DE4BCE24937F4D97F02652D61C1DD8EBF2B45D2D94227BE5545FF26C1ED7B4C428F0429A817D0CEB6E582747D0BA6ED72B7FDEC7A3173220E550A2A06ABCF0186E22908AF5046AD17C0145C6426036F7FF5D280EEF22E7B97A379EEC4E88ECB31F6AA806B16D35538ECEE98AD1AD57833DF129576F0F82162842F82A57F99F668C16739AE373E828B5971E723810FB7362F5E6EEEF78C993058B799996EBEBAC40229ACC20B97923DF18D039A288A2A2DB8E1643A6E08826E294545C97C84086D0C1FADAB2D60178398CCF779FAB2759E81061D771BC6D3BFD4DA22132B2AFAF9070E4CAE18AB33C6588FF141C857485B5860F4777D1F7B58BDC656613670039A0ECFD1430DDE0F758D9A86971F91862B3B68933EB509C8D8515A7C2820B160DF1710D35E7283B3EBAFB97135E7CCB329FE7712975F2AAAD21E53C6C1C9AF3EFED06E53C2CB74A25E0FE2596FEBD72C281C35D75FB0314D7AE39ED324D1B3DE09295D1D13E4DF6FD5D6D2D89C959E70E178A87597B8585BED8248922B5A7920D88EFF0E5CC8A4C091DD8FB80C2ECFB385CA2D9E029C5D0827B9D5B8B5613D559EEEF76C59144B0F16BB01E4B07005C34AFE0368A0081FCFEB582297C7BB8BA3B2303811E21AB19932CDA6225C38504A51AD744114FF95C6F0D9771ABD7DDCBCDD6E2D00CA5760BF4F286845DF00A96272D015A4786911EF40F27942C9F0B19B13752305AAC31A6741ECAA26DEE6B96A1C411B6F18F0320063D7D3D4CEA2ABE95F473C987AB5B38E3F3E94BA7985B724D737E575EA00E2401DADBB6E515995D6A723BC960B90A201C7057FFB305FBE2F36253E5489430D0BDD48291CC77A83BF29D50A27B4ED5A059C7EC8F70CBF8836CA82D8E508CFBBA14B618365963E808FFC8CBAC88678A20F0A472434F4586D50ADCF4B47FA803BE4AD90A056FC644CB0B3BD4F7A10360615CAD36534B45931EBC87FC9E2EF343D4BF6CAFE9C8E7CD27F7BD89E364425D067B23A8C27CC22BFAC2D2ED3DED3C89941E393AFE09DB84046FB216763F56F1A9C5E9DBB788620DFA6BB9C44DEC3DDA0E33C83956EC23F056DB30258ABD96B38720DA7BC74BBC5D588F2721F9326035953DD30CF2DD128341B12674E5BA9D218DB3F6AE22D317E240BB17687064A17D5016DF27DE24667ECEFC4EDE2DFD1970F897869BAFB14C7564B231595CE0808F905372FF2B95B9134EA65F6E487C9471157449F0F431D0C2150BBD9738B5242E6A965AC16E2EE441887ACD7F736280214A690F800FEA26EB15E02D0FD7418E1C26D3D0C89DDEDA25F458DB1B1DE6A3431A94D9C6D24A013B5FF8A04953D99A6396EA6617A59BB52330E1CB102586E4B52A81E871A524068CEA766353010A06C06901A1019BCEC503057FEBD8D6ECB1C34CA2545A99036437EB01E56B9FBBA21BBAA2FDD74930577EDC82740A5CF28ED0E1020EA426C16266D8EA31F34CA286798948CB64BC92C55B467B1BFB693C221DF4320D25352B648507B9690F8C9EFAF87DDE467E0F8202EE2743D08B46692042F9BE91479A0358D0C7DBE7BF81ED9F17066264897E1CDB8679A7288DFB2B60EE79EBFC2BB5005AE268C59AEB097C9650D1CCB6A758992DF6EA4647F4E6C09561C6F13C183E71E3BC09BD23AC12C6CCC19C0F4E918D27E0B5033B9D98BD639F8B72ADB1D63E32601F5E43CE384F313187DF0558864C080F78C77A4A9E904100D8F572DE444DACC6F4959A9A9CA0A7304EDA2DDABD3B95FE50F2FF820427F6BAF8E06FDF7F800CB5BAC3941B4B5901784A7F71944B3AE147D5F25E5002668988B1E6F39E18F1AFC06F79159E836BF1AF4301E98EAFA7A0EC7F88D12F407B2ECF6217863C08447A330E213CEC2660CFA7229ECC3036ECA03823FCE39225BDE2AB653CFF5212134E0F321F7A50E0C4E8621AF7ED2227930B616A99505654AC5389721CB00FC2EA9E0FC1F3C4414D0AD17352373F784754C8154BC13CB0230F02F661C85AB2373A995A6F3476EFA95622A649736656A3B451CDCFE74A5C440D4438E36D9870B11BE7B88EE22C982197FD951D81BE6747E563F9380CCE1EF3273D9CCD9887A6EC402808DAAD3C06AD89D99D063D8381AA11D06A1384B0D924C266CAE9DA21FA3404D3A10369781850777DE8E6F2E05AF22677EE92BCABBFE12B7153C58D7E2A72BF8FE79876A821006226BE43920596152C58680593BAC4EC6B17AB8A787A7736C07AEB88F6874A8E7C824C80972AF9D7FCCB4004B5EBECAA18DD1FC1379D83AFA7566E8BDC92E06D5C1DF08065DDCA8BD8E328FB2A1E8C2E06C81BD7F4A7AB6C03B25D61B5D1BA24C76B23411AF27334B41468E30A866105B7245D97B7A8D9805E0A73D8117F9F41C632828C2343526360D27FCE270A77768A6EE05513815749F847856C56D30634E390ED81FDEC74977970190FF1D2C7E477C9AB18B382D1B4B4807998DBCCD379E271A1EFEEEE40358693D8E4360CC972DF6039294DE9A5847FDC703E21FB2B5255501BBB44A644B1F3F8015907519125BE9B93071E29CAFE2DE595339F332E88ECE036C731870D7267585317E7D26A15101071508318328B174D435119AC094610E82B7166A1352FEB161F51B4E14B7037AFE0A97A3F7118519C6967B7F88887A908F93343A1C4F0B9EB8FF431842880B5FB4AA234B34E091C6F132B92EF1B7B0B50D5DD62016C8251155CC8488D8865C8FB57D37494D87FE55B34AF24150516B4D881B9EAF07C0DCEBF360C323465501F38419805D0538C0AC0CDDF0E3A4187218EFDAEDDA79D09935DA4C821E23FB33B42EA659D27A4B2865F6188FA106A728757EF72E7A093099DDFC0AA82DAEC6C48C8EF78ADC8DE1100E44E71B13BE8530826A20D4F877B2ABB972E7C39A596D5D012C3E36472992A643EF962CB4FA1CC5BF95019AFBD7E0BAB53EB46F24350FA471AC05208444D583F51CACD93267EA7DE21C089A0DDEF9165CB27B1CBD97B2F0C8D8949F780ED1C82F1F69E4EE4D7D205B7206E735D88D064B7D3F660CF4A36F019B26AF9835FFF9034E628AE534939C18781150F6C49BFF883CD567F7E50691AA5F1981D995A86CD30DBBD1C8053310E5374B03964DCE2B2CF0453092C2F6BF102A90284578C3638BA79EC4EFB8EFCD6D782AFEA416BC3A876F0A9CF9240471C2AB9AA7D2A0990025EF2A5288458A279D3E64A734B95AAAD262D8EE88E942A5FA170A79E08D0BD22F5FA7FEC19EAD504D83864BC9FE98CD157B34DE72B85FCDEDEBE125A5D7AB137A3EA5CD86701607415B96E8B73081DB4CB0518B908600C51D2E7EE795FEBBE46C3D7C4BD9D58D7706C554838D7CFC6CC3871451CC0740F68A8F9303E72CDC95DF1455A39D455261021D92E17C8B44B032660472848B08B1D109913C368F8499A6C10EC23D2EC2C7F9A8DCC4C921F01BBBD9837BB68366DDE692D2500D5C09EEE25C037C970099C5E1BAF5FB68EF44B369AE88406E76E5BA3D95D2C6F4A472EFA435B41DD569BA4429F1E2AC3DA473B959C704803BBE249669E8D65154C3C7D45723AFDCA8AE7A7E2EC40E830D5F9313F7279ABC78DA1344125CCC5FD7E9183884F00BD0C86AE0E4738D5A4EF236F33638BE3A6CFC4CC4530468478992FDFB891300CA0095DBD2218486F94D3D17BC59E65F4DD3622B394F0091ACAA8C657B7CCA9766BE80E99586919C98259BD4F4B112C3FF1E6AC61089BF5AEA2B5263CE1CBC951221C8CF2DD56DB89982A4F899FABD0F0E5A822801ECB92F7DBECF033F2B2F4D1E35CFA1B0112E71367CA2D9A93D09A92E919EED59DADAE1C388E04C56A4253C5C5E25A3A3DB90AD37EBF2DCDE8CA86DFB15A764677B9B43D9637D50BE565D39597156519AF4CEC5F5F668F51", - "rnd": "C8A2E170B30E35475992075A595EF5037D31198D80BD6EDBB933B6E72B1817AB", - "signature": "88E11FDDF391804879D8B14A3AF402CEA0952C6583403C48D0F6F630B7D7B2EBF74533842404B96625F092D0854B75A1525651C774D9B246E68A8199A2D391F8335E3127028AAD1DAFCC4D95BF800F9E5217AA109976CD18743B8514D6C1F5EDA5FC5EEF357D4613C4AE1DD2821797FC09F3D5CD966D4B3E023F3C4F04EAB4B6EA9358DE7442FDEE4F520EFEEEA57AEFCD7730D59ECF15773C43F6FD804C1A8447D8A7FCDE7A9CB83631A8B673244BF23FE639BF576632FEA0FBB97A01428496CEA7D81E73F551EF541BEB500CD8BD9CE7FEB7177F3D10D63C23CAC8BC9CA09F839AFD4A35EB04138A35FF58790BE8F56B222FC15DA91C0FC95496CA3EB7254FC71B238453525619BE30D59EC1B04AD0E95C27721E3A41A841118E50DF5F67EE44ABE797E04536F2573E21B43E3FB3E9566BB3F3019B82BC4EFB53752DDC600FA9F22166206EFD210DA98D6E639BBA202DD0FB33F16C35D9F1EF6C30A86B02FE2DA3E7153376D7DDE9264BEEBBB59F567DF101CCCB13596A360C4D7F2E9D02550ACE2A83A63BF5D91985BA17D1925E41364F5AC3DBDB15332E645271BC03A4143194F6BAE651C379DCD880A7565746C1CDC1370AF89C0DD2B50440C1700C751DDB9898E0A204FD4F7AC75E1C0DF62AD1211C2F2A39633C7DE668907213B197B900C28459B212C6310CB6ABAE589ACF9293B7D57B5EDF6C34E6BF1C19FB79224C674FD61706CAA1BEB39960A89C7FA7F548FD215553A876430F77CD0AEC25556C37FC463A2B2C6C12D9360FA1553F1BD148E2D05D21F331B3A20A646EBEA66C54A46FD008D94ACBA610B02A26363A1057BE3231A76434C1EFD875749957B30D2CCD6B3FB4BFF5615AAC3FC7EBC3FDB09C4D343D7989DAB3A805AC01450C89265C21C9C48DA744F12F7509DD205519AE9B5EF6F925E484B22AC17D3ECE38ADFB982730520A8F609DF65200CA2F1C2CB7C0FACCD994887EE0B0186A27627B3AE90EAAD3A5198334EEAB4A1327A6958B3662332E278AD34A44DE33C26CBD5053D845B003249C6E989873691E17CB98F8A5EC1D94DD23C3CEDD55D7D7DD8363F5C99477D5F6BD2FC5CA0EDB05327234E0A52D392C54A3690FAD3BCC4CAB9ABFD722947B93B6F9FA3D31821C44045195D4BA7FB4326E46BC83012AEEDE3AC824DF09E829B7629DECD95420E71A52713E2B50DD88059B73999E81691852AE4DB268A9F4475642C7C4F5564D569678B4E44C345C17C0F0789B7C6A2F2F5FE8DFB7DF1D3173FC1260F7EE5125E6164960AD73A65806E8BADD3ECD4736EB5B0288FE42972D020DD8358A32955BF439E1CD8F3C7D7EF0ED84D1DEA4AA877A35324201F443039A2EBD6E3CDD9CCC3E048C23B5760988EC8BDE884A9EE9D9A4C3B5A4166D1E1348FD93BD653EDA2943F2DE97FFE902537A00B494959E4849F93217A6F25416ECD9EF83A9AE1523D894EC7A350C689578FA655D8A0CCCD2E08DCAF1D555D57952DE9263D0B38DFCDEEEB886CFA5B665FD4244A3463FC8F8E04D505810F4D460AC1AD8BDA57A3C96A9B1549BB04E02A3852DDAFD2B900109246397A2DB91E3A3696F03CEA3F9F77E423470FE11662572B50B6490A3D215E7D90C73D1B1F4545F8A92D04295660F8B838692A5D2E74222C7E236717B55DBA0CF1F633D12D5637E4F5467305EBFA0C59D3D932C0EA1FBAC0050796BDA12F99E4C779AA0562326D65EBBD77C1485747B98214C2E02C343E106EBE2CF585E5BB473959CA87350C12136BC4FA5E01AC2D36A21720EBFBC04250AD56CBC7EB8977FD1DBE93F2061326F62B602C703F69BD89D33C670FF04CBDFD5F0C7060A3AF97BD4252863E2D638CC5D26080A9E72CB87602FA1B61EDFBA4721464A1E9ABACB0D7F1A65A272B3762BA9C270CE58ED32D573A7EB6C88D8252EF5147D173A42B00D982BBD832C66EBEA952F99931A048D6135693B518B9674912B74CC8C16D0E46874E4C09A6171AB38AC76FF2A6512F12F620F7C834337DD3976E82870331ABB2F9C94D9C3B946915B6185A0CAD49AAE611B3EB2B7A074AEFB241FB143E3FF21643C1041147948F27C9ED404B6B61ECF763A740A10F0A61DD309C9396022A62687B0A0FA9C4DBC4D6326C464A2034B8BC66C1C12295A377282FED0CC050278CD72A4DED6EA7573EDB08ADD82453AF896D4E1729A4D0AE156F068C4A2DBB5D1AE079A28C2804491409C6D7D84AC2FE043A4DA0E8A2D71EA26CA4A83EB0D1047A0ADD74703F57734F3AE7762AA8F0250C1198DFE59306F5B1F35C4774FDFB186868282D012BCFEAD3F634786523FCD979DF9FBC4A966C7346D45BA8A2CA8AF069444C81C986BCD2D1FB489C23B8A60177D042556F482EE37A290C9839F9BC7EE82DA773DA85CE2D647D4FB14DA06A7B01C1DA128F4ECA69666145CEDEBE97B81C9C7979A863B9F60E82D4294914AA65BD56D0E134497C57BAA980BF6B149455557E9F0C90E621DB4FBDA4ECBD012B95B733C4E8DC9861F9D19CFC633FB2DAEDF1F697360F6AB47586201503E0CB2D2FEE4CEFAE0F6FD999DCA819358AFB5D83016BC918C5CE1EB2DDCA9589C3710ED05F1D849189917B92667EDDF06E984C7D4BBBA47E1EB25DC3B740A08C58559143563429BCDD16271F06680A98C3BA688627F890CA6E4C5D156D5D667AF1EAD5033C7D14468A1CEF5665521955938A5C112A050D3E6505BB4F5CCFF3EEEC02733091D4D5316A804674FBF29E26D9FC11F2D24565BB35E835F5788D81015A65D41495BE82FDFB5B0B1E032DFBC8C3CC5919EEFD11B48E6B06874F45ED1114D9A1C4C0F60D4B4944FC0B2A42018A97F76DCD200598DA6747870604906FCE07CDF973B5F1435023C7894EA8FEA0D4D9E126D4CE0157F9F8595E48AFD76685422F9CC94C1520E48D66BD04478CF48448334B34A55043A8684D36BEAC089CED40793819C25CA057EA762BFAE79F0F90A6798F61E025A0ED8704AFAFECD2DBC6D6E01166DCFC3194948A02B74C735D11F69E1AAB1DCD875D100CDA177429009B5570F5F4BB9E6FF4E494F4EA7E127691F8FE31619C771CE587C5E8BDF1D1727C21C0493125AC3C7E1935D0A49EFC0ADE9621FDBB4C4099DB1227BDA48B7E9D9FBF8D1391F74F2DEC3E040436A2134098FCAB229CA43835039CF79A44A2BEDC4342DD21829383753B319A9796934103DE48752483C1F551F1288F489B96EFE084030AC1706419856CE3D893313F8CF2A816984999CD09EF64AA86544E7267D0D3473EB31D95DD7B25971A4F4B7A91B355269B29E88896E967E6908C44EE25A74A63D64C5D3C49324E00B099C652E11B0D5BDB91662B6D10A974014E2BF306BB0597ABA30B69013590377739C4370D1D70A0DB022CA4E39309A91F559BC9EEF3326DED7E16E4A4886C173F70D17B01E2EF7363791A0FFA9152EA8BA4DFBA6A7AA5F5004E2C8EC07BD6D64ED86E47DEAB073E231DADBA8E5C7AAFD5F46510158FEFC7925E6084759F15178C5F59A7EE4499FD739ADD42D6ADB20FAFDE883DCAE598CDDD4BE56C2A737CA14E4609AE9F3FC7DDF29BA57B901921E08FA088DA6D55DF25A5C955049B8FB58720477CCDA8CC36754FE725829B6BC2D4D5AD17706B1CDE845301970084F1ACE4110C35F1F3909819569E8B4D09819F14223170901F356421EBEF6A6D87F605592A2D1FE74990729E8CC178CC0FB95DB0614C32DA2C6CA95248C5E49CCFB9324288C4DB7DE4F360453D709810DB5ACCD5971ABBDD59D8542EBE07D79FEDBAB31B17FA7F174CFA92201B713D85A1A84D74EE2F75AC46AA17ED102A3071CB6A4BE05D89F7CC52A1CB4B6B70077AB7F63F022F92270AFC92EEFF099982953BAD9E2A6D7AAA28451E6C4B504C676DB09619A098CC81B5C22810C22316FAC3CF63F956D9CE3878CD0D5F07DE678313A565ADB2BDAB4FF35023F0491D4826E232DDA2900BF52ACC1C064CEF88D471C18F8C53B46A6536D82CA9C198087AFDBA057D7F21268211426F1BF94B14DEE4D910B11207099713549736653454B078C341AAE03775D3A138EBC63C0D94F81BB8A0B5A0E6BEFD5C9E01E258E4DD5336151D1D299931FE2E5386378BCD8537928E261F606FC25399809D57D0F0F2C9AD6B05A6C231F4ECB390E72D2B0AA4C366F83AEB4E9BC95A51AA52D03861E02B8D8FBAC8979A58155AE5B887AE064DFD1EF03B832B6AE866F3CD14209CC13A686C9E6E01576633892EED2728490BD753CA831EF03D4BAB0495BBB7435B200E3A5BAAB6286633F5288EA9DE38CE1A68828D84881FB173729172A91C606B3BC1EBFBCCC66E96D569CDD840EC53982DC561855052A1A806EEC0B436C1DF42D5A7AF9209E377BC7A6ACDCBFE0ACBAFC8655154099EFA4BC8D25C6A7065C8BB008C0D2D5184C645F3A354D689C0395E032489BEFC6771E952F90032B511E0B87494279D5E5BA583D6B281192162E550911D61B7007C34AF3958CD7EA50F5B47D727106BDE27C8766020573C1DB97446AE2F346DAB2CECE3532EA7C9211B61807C6E9FB84995446F3D8E5C2B8396E920EC304F43A028F59D0F9C4962A2262406C3C2E280B1A458B1E9AC0F01C1A038145001585B21FD0442BB45615577B12E25A671A6FE94DF66D682F4CE2F53599D7C5C9E4C894CFBB7FBEB8134EE10EE90ED5A4301A80D6A5662D1CE604FCEBA8424A7ED6D17EBBDE716C31BE11BE36FC755E55F8FA02921B5BCEA1148816F67376FA7487D74D9AA45881A5D9706B41A64E9FC3C743217B4C56E44B156A9DCEB2A927244BCEC968AFC9AD28F13761BA50F73590C98E3007756C6AD030B0EB63304FF9326AF130202D044134B1910D1EF2024A67F811D73C772A3F3955A694A264F68ED3E54C9AA928D25F11905C61B5907D4491789E1B43C37ABB9E47B734B63502100CE8102E0024355840BCD536CC3729F5A062D09DB4AF21A159DACE8BE6417454C13E8C090BD60AF16419EEBBB4C23A8238F674766057CA1434254A7790E0145437C3AB49D027E77FCF4145232AD469B0531384CB7E10C244E0F9969BEB8532C14BA38B2A564BE9B22B64B975DE8DF44B423523C78F3009B3BBC4344BB97888C54F711B12EFD172CF9244657F9FDDDC7421F748376961662241BC69C610DA8E80F65C2ACA7483EA71CF5302A639F5C11D1644C4DA25A46F93539F2F92E47C113B2C51E2C6B6B221E8B79D991EFB88547E0017EF6EB645E8613F44BCDD962E909B4D71BC7040E93A9441D0F8EA65B014F0B10D64746ADA7101B4C7D6426A7879FB2C6D392D48B68277CA18608AB57A76C12536A5F0D08EA699C137BC58ED51183BF49BB60DDDB6B32C845AFF4FD8657E2D318C4CAD65259023A488AFCB1423D3B620E253DF1E05E65E4D61FA13FF6C54B80A1FE3D5DC3FFCA2E85490762B064883A91E1603308A0C2AC14651DAB71BD2164878B5E19B89BCA4763DFF9B02C7A0560F935FA921BB475CE4922AC938A21E96E04494E584AB465BABC536582FFB0650D6C4AED7F128494FEA3E598ED651A52EBCF3AB11CB1F5C2821F935CCE98AD4BF502FEC70E8BA7C3CBC658B5BBCFF3A08C4A1BCA6D23EF5E18ECDA5301A6C05FE112B44B51CACADD352AC478BE1D6A5B95C44E74B814035EDB328DD5432AF8A346F6C9EA047FF099977A0E3E6F38F66FEEE3A708FC81FE346F8CFF6896B10AB8B1001A6C1FCBF87A74A5D08A7BF6E38B7B1B6A290BB425749216D3C75BB2491B009F2CAEA10657E0BFB4AA55F41F97F0173769A56FBB1DA124F9DF3BD4A4D5AF37F03626A9EA70D95AEDB42F77C6D8767115EC5EEF663C590992F20FAE559BA85EBC01518E893B56891ABB5E3A3CA69EDD0000A504CE6D4C3B0072E122541BBF8EA1F92B541918EFDAA0BCD769E8A502FDA186DFD1101D08A0402A0ABA32E654A35C7CB836B9E1FBAD1A05119D994E2FDD42C521750E73FF32F8424F0BC062F02AF18999DF596B525EB734EE3F2DBA259D6CCDC45FAB25C2962C9D7C3BB624948A81E67E06AAD58F03D8810CBD994A32E6A09631753F968AD52AEBBFD4C63860E182A6E4C40695576739F73053E07A45F4F630DC8AAFE9DE67D0F110D49377F99A95FB4550A8209DD7DCF97BCFB20F8048C2D40C697B55E110CF58183DA9F8C5E1B75950C90426306594FB458B9EF2E12EC3FE2BAC4024CE9A2CB30E0CD8389962996790F17B81E21B3B460E1D15CAAC7E514FD62AE6266E7BF80606AA5239108556393B2F816CDA74234AD68273B013A5D5F699CC7BFC2AE6062471959F3FF361B26B6961C7FE142B865C4CAA9E2C145227682B0A014FE3392DC984C2033E9F6A6AD0BD40E2D2F8A09435D7CA8FCE6E3B6A27DB11738D4A4D62409D806ABFC95BA74BA2B5237091B89CC390457E82B4763AFC63856B3059C37C8DFABD7FC2536FDA49D547A5353849D949CFC99FF85053B5E72E5FF14181D2432373F45686F8294070F42669DD3B62B304295EF515C5E7290AFB9CE186874E61F33606B85888BA0A5AAD4E0000000000000000000000000000000000000000000061218191E262A36" - }, - { - "tcId": 53, - "deferred": false, - "sk": "9CFAA43CE568A87D072CB544AF4992BB2DCAA86AF0BC22A2990492C8D8FF77353E33E8C93DAC2CC3481C58912D1385E4EAB196176CE275E38DE46564AF01FB84CFC86AFFA7F40A623395C6CEE1C49D0B544314733D1B51E7D6433914B2D768CC79369C733040E177C2AE17032F848C9A6D86DF02EF9C85FCA6421F683E111AC5519245D91661D2A22CD006700B319019B985C0A48C12106A8CA2898A269023B4919B4225041350DB82050805050CB66510B9918B2868A2A4819CB25180408683C84422B86C62289061320CC1446E9B1070E14401A24000C3183019B628143370E3146118C98909308619206404C7051998494A0042190505599028E0486A0B908D98B224DC288C4A12720A001010030294B8845934210B924023294144C0648A2006814690C8B46451244A122866531288E2407242A030DB4001541661920405E2042D9844908B8801220406D1241151A80C4AB00051B62C81848501965163A02889442A01A38004412D0A99089024651B248ECA429008476D63B83198C4001B0224D2422D52B20523C7018A1431540264D434240A174D1C124549C624DBA28C01B58403A82894B20DC9C0041C0980483482D8120A04B780C44289C9866462963123A14914222ED12672043732094585DCA46DC9C40CC12425D386708020295348101B1082DC1670C020859CA0456286610B957001192E5B3884D32245843001811682032449219769193202232332A0B291524424114921A4B66940064A90B66848308452A46520B96D13B209208264C8980062848D9C104AD404220B2920933645C0C831C93009D2A829D3065189248484C889E23232D448300BC70C0B4410A3904992A6018B326AC3A445C9B805E3C670C21492C826061B076CDB928CC2A0451239111B292D02B58C01C38183A8049AA865C988091AB54001C0808B106111212D1AA6851A854881002EC24009E01884E4324D1A37698AA04458C28003B48911280EC3028294080411285112480C0C242E21098E0B832D19106D11038103C02113004001166883088C40220E0A00400316709C188E49286588000CD3A24190A64560B20D43C669410610542824DB484C1C330540848C53226AC9062A0B954000884958A8901B4109E4800D59A0041C2188223744CCC60902172583B03048B2914BB0911AC2855C42119A426523306A10406C04056EA1182E82300453A2609C848409304598A0250803861A880DE448821B222DC3A2281334000C07481A268851A05011988111218A5912881311024A32011B3209C8120D1006701A92690B3486C9146220B06C82420403308A1027484B46018928452489488A8860841820D0B4292340524A086C23124D1A460584B27014B44D83288299C28419804403877004A45019343022A889D1206424242019946984464823080DA00469610044899048500432C3848C441869E1A44DD82440E2A2705292851343605BB68CE4946463328E9BA20510A88001338C14426509062002C02553104A81264A912031202700404648D0224C22424200B93192B229CBA69082C250E018419902650002225802305C4030A0B04C91809081B66951A688C1B46C4420420C098664C00CA1825114254D10B6481340099B986100174A9B0690983228990292C928508CC00DE2A2911A3168E0B271E4C88402C448C9887148B08500068C01470903112D4A184A109008C8C82044268902402122954118A90044908924349200B3301A390AD43649218405E1386D8C482112968D102512C4446AD4128591040EC49025C892910A0252D9C24118478160B664220886C4127012146A8146500A132610320541206918322961C43153900013B58D84364DA4A071D39648D1886C11324A1A178C8B264220800C8BC871529491D1380C538671A4C22850A60D11062E20246580C02C0B277024B8258C128C22C44C89126458406608436A4CB489D80400DA225189042600C068CC26408B342EA0C48198A050A4185243801014B34D8308210C409109A37098B40880142CE2306E0A0381120020E4B889843491A34408E0002292140290082123A584A2864C1C22328A444610805014265210B9440A4860CC2892D00271C9A82CA43049191284E41468C290910117096428819134054B280D42C06D03244DE3028D0C2221988664C1888D1903311B9520D9C26CE0B064484844CC12100800817B2F78C1B6BA544AA20296E17AF66295BB4E9C2F97EFD899DEEBE0673C5178418C2483F75F60CCAB0C83134B9B4A94845909AF24825E8B2B7FD7C302802E41BB9483952C269509821B2767F78EC81221A8DA39CA557746194BF9B56FDD4116E8DEEB5FCF17CDAD92F22E976681D0E37F5E9CD6FC873B02CE92FE785892F22BEA2534CE88F2D737A22C5E5F73D378CE58AD2A62E63D47A939FF23A386FB778E4631E0918BCB42ECAA8C1ECDAEAA6F608425C7F5CACCAF1288A1B1CE503066DC671404559AA2052EC519C8989D41575F36C301C03462B63C81B4F287E16CBB2EB12B1431AA66843CB3DD859CEE21BCE990CD359BD42E1CBDF357E84E7584EFA3F8F118AA61EB8A66F16F3712CEE9CF8F4DFD2800F8CDC8F3B7729521EA42156DFBB84F9A8D0A1D347FD56837AEA38FC9563CC7A8D0541C1BCE5E3F81855634C5B45014653DBD30BFCA27BE063B56137338DFD80FB96A8626105D3942D335C6CDBD1936A14EEFD04B5BBC99126AC18F11E0FE6BDE5F51C0C8D42FDFD73F4C39D82E2382CE601C3E357E1A1788DD64B2115AA7AE1C1E873A283551E3D801D16F2947493E970F60C8A2388BDDADDAB0D35EF4A546844653504C0C44310268A856EB7FFC7A914BE7682E2DFC284B02D3389BE94051710072721A3613325EE27804B28792CDD00D837EE96E7195EC21C28C1A9C247DB9E1EF8427E724700940675E55F0AD0469D8F869D05BB426EDCD8414953AAD17BBC422EC5B40F5B99F45C27138439A45578EE8906AE4A9F9A6B1689E637CAB44FA7F901C056DBAB48DF8DB3CF7B4D35B85064DCA231AF02186488762502EEA6235BF6E05D7EA9DB422BA528DFABF1675F12E623BD830678E4F766AE7E4983DE20869542DC1072DCA6602D11AEB33BC50DAB0A9E649DC15E96FB6D54DE9174B4EF6D887F3D818643ABD9E4DDD49084F1331A55FB55F62F76D08E8CD07A6426B6A58E749DDD3B625F1814B16F397142C564A8618309D699E96EFA073CD149DE96CD85B93C163FEA1130106BC2E21F3BC0EB1DB7D1531C59DD2DDB10EF74631B8802D96597761D2221417A1723AF765AEF0E771CDDB0A270AC231B94DB3F7244CC3D73769D0F67674EE83F425D8B19D3B67F40AE79A66F6A41A61E4691B13F07A1CB7FC8ED1C2A61981BA4B61F4A3A3767E356A8285C5CD4411AB6B357822B6CCE371737400E4EEDA392739AF01CC06D8C4F4A93733E1C46471DEAE58414FC9113EFBAA24831AA696316F7B026205FA243B5AB9551A406EFC492492286774EDEE8B44ADBC103B5F9D839E5951B30ADA098325190F2C29EA51E742CF63132C75FAA5174A91F32BC0F8DA4B134953B8F7BE24DF61F4E6BB063273AB0743CD9A588D0C52042B54B98B6418DE97FDED42CBB8B8DC119E5A25589C74AB3C04AD8F8C3718532B6C58A6FA3ED5FF8816134768FB0E759073CA7CFB9A1111E7DAEAB996444E90AE56F37410ABB89DE79BC7E37645D0E95CACF95DA965291EF0D591851E21C169EF7011D3A6B22FEB6B59FE642303FE007F670053B735EC0CB5EC24A086CBF97A61243783C76067230E6F2675B4A774654701462086AF7F1DE30C9A5CA3CAAD054FDA848C73609305EDE249E157924BD7BE51827AA4BF690B48291D32400CCFEFB958CB772720F14667971E0C4EBF0D2A30F0DDE81CCB464150061F0BD63F86F73D5AF82E4EDC2D157D65468FCD911267DDB2E5CE1A81E53EF15207EF35DBAA121E357EF896B16E57567449F5943EC09E582A8389B2A43654AE42A705B71F2C991111C654C209A1AA82230D41331D12068FD3CB4F8BA7B79648F0B912253F0016F218366373BD75697714599062BFE9E3A74CC41963DCB4D6714750884A808B7002D8741702BDF6E11D0B2CB5E50707F975BA16521E27A2CD61B212ADC3C2BD18585E892FFE502B2FD544839194FED40EBD6B4157018BFA88BAFC974CEE7BC2F48ADBC2DD83623E79E20A8140C1521117500839788416803E8624818DEE8C44DB061844FD59FE17718030B128FC96A4F1736B0A0A1DD35C4DB35C32311A159869136F3DFED441DB5E85BC65DE9364429E9C875DC9B45295072DF8E3A27F4C15BDF6A1AE6F3C8BAD757B07AE9931F28BCB881F24C0C905DDF30576FFCDA8C9E69D55C799955486B71DCDEFC0717BEB8A259AD2CA0EC56096AC600B85EDF86A8733741556244D63C4B162A7CEC011DDF0FBB729CD9100FF5E2B36C1FF8E0CBBA1A266B806B601E69A3FE9EE2DEA984A0912D17DFA148CFD3C6ECED913F1A87CF0F31464A8F87705DD52ABC1062876DA03DE4665FF1FDF672A336860C12E26FB1F3048C02337AD24BFBD29E2B9D806F94E986232D1EE445BF8E5BC74AD02D5410B9630EA4B4A4A394B9753330D7461A71AD6241F301BD01D2301DD9CAB3CAF9223FF5E76559D5E2D541371B3EC883D513DEF4007934F8EAD5BC8AACDB637125AD95351191419CCC6FF3E4B563D6EFA0DC05CF9751DBD8F378AFA2309CE3C997F8DCC6EF5474F480B20538D50E748C1A93246BE6AAE76B2F1B7ECD70F76A28518DBD47D8D7AFB153F90810BCC144E046EA122CA08731340007B15DAE2B92081AA296C21E2E25C0C25732E69CFC0853D595E21E1A99BC474EB505F7D7F2946F26D1B1A7A0F52A24EB66E8BCB6CC52C8D9E81FB6E41A45592F6BAAF1395A043C9C8DEFFC8F71568A0C4295752FD2B71015E0E6EB398BDA095D12BFFCCC9BC497BF655412358BC72BEEEBFDEE8CB674C7A9F261F6F0A733032A6BBD2336A84CA177F478E2597AA9255673D69484CFDC0F1C0998D97EE70244609C3F79E323D071C059F8786E7E8F5A3596287F7E2C8D60083AC7326FCB75B3B56E624CF4FAC34C01E21C34ECFE88405D68C4B230864EF4CDE22B9FCBCE5161A6CAE38A4D099D4A93F169928C319CE21FC48EA9441643471F2C449FDC13090BC25B8762B132D750A7F5A6B2B7605714D9BE7C70AF6BBCB0A1D5BA3653DE98D0F1E03A884080560EADAF1E01F4A6EDDF4CD3D98C8FF0785DA54A418BE93703FF14712BCE9E5916A2FF52D06D9C539B51FCEAA7CC260457EB3D8A733C67A2DACB2EEF8D46CCA4FC13044D14578663369F1F7CCF8F23C71252D66E926D26E128E857D710EEFACC1DA18C1FC859A61DA318711E52FED92598944541CFEE56B48D41CB94ECBF0B016C278823B500EC1FFE57068E7EC25E81A6417EBC4FB0EF446359315AECEE524CDA148F12A5BE2A80A269AA17A54246AE7122242607C6BA9E7779E4CF986A2C8874AB5C2A3330E921BB1B19B76BAF2C0D4B157F84E92D9EC674E83D2CEAB88403375AA5E78BB45C140346982C0FDB88DFED89AA3DD2128E0602F4A1F10F21A43A17FD7E8C1FD4567E8A3D82529385BCE54F70A6C74011CD4B76F52DFCDBBFE928EA328B4B7E1F0EC6E4F08FDF6F642AD1A5723D99CE8A8398D445D6508F7088F7AB2D268998E72D18234AF6AE40C0AB80688623C917F4B1450DCA2D24C88E012BCBA8AA2EE1E4FCB1AFEFC2D77F98FC92EB4379BE2327E264FC3110F297DC9E6C0345ED0B492C870A93D1169B7968F0C2482211F82F079EDFCE64BD201A22E43E6D6044E3CDFFAAA0EBD26AFBD8194AEBA9AF709C47A2567B55E6C82FE5DD1E37405305604E89C33F48827E0884D2AEDC6747D99359ABD51F12CC6D2C21E7686E0327E9971EF810FAE9BFFB6B03E77557202355A6EFFE4273ED49F2D8DBAF1EE9C7EE3B77CD4F322562AE3A4740BDCCB8373D35BF3B8E447B74EAB1EAF0CDC82EAEE7565B4C8728ACD87CF280FAA8DF09C7E90B60A92825C060D9106F86ED34BB70F610DD9BF3802B5BC777875BC36B7F7676B60052761DEBB587F1E2CF9D556055B7D6B524B58DB8E3738E3F76D8D6615C4435C8A1AF698815C5FB515BDF9AF96FB1B14C0DB6775EF4363EC6F2351543A1156B85D843D526F75F6431FE2FAA52FF7942C877C99B26B33942C0A8A3B5FB3B019EE52D58ACC7F25505ADE989A663599668B8A6FBCC440393FA9DEA85F2588F602778ADEEA0809415C14D15182BD2663400D68B6F2146CAA795FDC265FBFF2E62A0F46B6EEC798366AA6C16F1F145B7A633B5AAED5F619003545871385533F68826BB1770E004FB5640FFD3D06ADF51A334CA0D59EA8364219FC27DFC04422CCB92B38A59EC0AF366E2DB116AC68D6C783391000F8BDDE5ECF594C49EDC5BE7BC014AEF074644FDAD28D74E29FAFB009B8E64416B0B1C0A0A3887129B77DD7BC07203931E384CDFF2C0E46328D1B001C36227047147D8A7F7F545DEC73E82EF9416F21C17AD782F528E7DD6BA76169022914A4462915EBA170CC77347C1AA0B818D23E806BBE51617CD63373031B5997C00F249D6A87870FE7F893A1AA9B879D4D8DCBA0E5DB2D89AC96961759E0238C051B7D7CD35C0990F702B799995BDDE3433976CE8F71D127FD0A03AC4F568C23513A8E60679C738BC6C746C349FBBCAA9CDFCE05ACBA07F9216B04C38CA47FE8AE6E4DD859AAC69685A8D1DE94CAB64377ED91872003ECD2DFE75598D5ED38036610C859D87697F003FE2DB798FDFC7164391263024BEFDD6A5CEE7A0AE0EB7C3C3F3FAA469FFA981A74523355AEA17319AF307A3BFF42E2B049CF284B1756ECC18CF950F6A279418B60C14D6E816D4EB574FF8DBA527D19ED0C87F509A0C021F6EF8DCE2E6B9ED896CCA1036AFE189181", - "message": "D1C758470730A9530BAA46E7234AE84DBFD46DD31974399C9B1CDE3A0340DC723A26A7BA2A66672FD116C8B02B36D974B29B5A658D1BCE798282AE6E5F7B6AD45B711DFDBE9BE8193AFBEEE7EDBB1F4A8B3DB66D1437E3572366551380A22AC0FEB66C4A8064B168096E9C7173F1DFD8962E10893C688AC7BC9E627004F187D76C62D9CD94B5789CC7F2D69FFEA0F685D65A0507", - "rnd": "445315AE90AF35312B52025DD2DDA792C1FEFC54768E9ABD95789719891BE1A7", - "signature": "B23469A18C93B7F5522C0E570114BF05FB9F715E3B7589D2CFE22EE22DEAB53C0600246D1D714C2933913431B628600E0BA647CFFC8F77F2E210FEBD9C3B363C2AFC13B2DD175166D01321CAFF35314EAF7B330E1066DA97D8053ADC3F480C3975E9EF0EA9938E58AADF9E08CEF9CAF23AF99D0F5E13F5C8AFC2D09A6224395A2B09882A2887CF73947C391186A4ABBB42322DE8BF981D4C7080302991A80BA0C3A027AC351FA60D05054753B1788540600B4DDAAA15431E1B67400252D92FA222F44FDF9A2482E73713B6DE71828C2406731E4B0D1376488741AFD61644F0868E740DB98B76556419CFE047CE04830E45913090D185E9D6ED5929828ECD4E2B5E476F859D05874393823C6E84CC9BBE95E61B7BE71B6584DEA865B2920FCC3CF9876366A4EF2ACE1173A06C040CB79D356776B392A6AD8390460897338A1FF236B4DF0D013CE97DED428A90F5AC5E84BC42E72CD9CC7829B32894C16BC4120ABAF2576952CEE833A8C8D00AF3977880A08A717B4C761E3F1534376D802823C161CEDE94D07B8889FA5CC39424A4752DDF8EED2378AFD2CD54DF531179CF2E94F9E88042E4C4C136750B70BD72088EA46B556215A9C0207AEC083A2B6C92C919B2BF1B7328CCE3AB628F6BC612917A66E4F6B146ED91B56B54EABE8EA4C95713F5AD564DD893A4D2DD57835CB113EEEE1B0D7D0A8F9A5A1606D143871DAAA0BD5D2EF8D3D2741CBC7A7419407A1D79EE695B47D00DC95165AFD447F69F2B3F82982B7AE8A5809DC97880DC776DA44037005635079C2E9F9422BCA1EA2BB37FD8C5B6F43AA42A1BAF22983933DFBB750EDB1D0B3A438DF1A7E2794309370B33F6F8313D2324750BBC6A2EDB48F3F849CA8A6603B2DC47DD7F70B787A12AC61531AF09903252FD339665CEF2F5DACB3F8AA1B7C97B47EC5FA1DA16998559056315A2F86CD0CAD4854EE972AC755BAC824685379C61EB2900F08ABDC83DA51082B5567698E9B6CFDF394B2782EE9A9EF37B90F05B5B7F914C45B4966BEA1C20A138AE185C8729AA6489A3CAEE50CB5CE1A57D6D3BD7DD3D4D3F1609106A80E81AACDC11D6AAB0EDDBBC3CD69460477E443B33FE6F9A432A080DEA648D1531B9C7A6F18E1708AB463DB2F15D1D6E88E9BC05B9E06595A66E96D70836D903BAF3E2ECB477BE5E209EE9527C0198AC0623EC8469321A62DF735D495E01377C4615087AD6D1D032BDCBCA10165B80D64610B1A2FA48967ACE769D8A95C22131CAB9211192A6745C947BBE12E5A612568AAF749F43105D4057ED411153CE1EEAEC8ADB94CA2997E4CCFCE645EE1DD5EC1107A43E90C277E781B24CD5BFD27365D50036E96CFBA58FEBCFB6A55D7CBAF749255A5E6FB69C17C706265D7B4C81D1FEB22721B22D165A4E1F8DDA0FC6B9251404F71C5D827DA36D8E82C35DD8BB5E886C59642EF99BAEA1DF3DA04EFDD669D5FAF274A98033EA891C0FCF1885860DDE13502FB5B7B9C789A191403183B71D7DC1BD2CEA43ECF3323577D1853A7E6FA8B7965CF5E0A14BDD7E9DA85685E392E32CAAF8B935E219E81631F7A50B121894BAD39B173C893AB13D11089CD555149979D98980B18BB81115C9BE35FD83F3353673FA1DDB5ABC0C8821BBC7793C391DF12D10ECDCCA3F1B57A91A21B7DB46862030A35DFAF3799C7CDE1F3C1A5060D567DC8BF00F92661183AFE750F2FAF76E7C5341F01446DCD45D7EAE9762400BC875BDAA1BF92F6FD47D85A629BADDBFD6455B8A53BA8F0218D7E7BE96CBB3A0756FE5DDE75A3E0F763D44790B5F6B0273B55C4953AA108CCD9DA438C253ADD439245119C83E066F89DB8A4DE618B373514D905F4568DACEC9564105C28FC6E37823C3AB7A391D1530F3DCD971DDA4DEE72B2FA971C025BD25937DFEE61E45ABA3DBE8B775297CB9E88ABF1549B622813FD5B5620B9248FD1E2CC8B562AD308E2A359F8AF73AE153D7DEE8A63357E48C8E6BE80B1BD0DF5407387F8A1BB00F19F3DEDEB5E30990FA84325B8EBC6039B021C1033EE47D1C3C806406B0635231517559CED0DF7E26CB651B67D79BEDF66365E9C2E2298FB3DDDFFE589E5DD1982628BC1BF4DA4BA3FB325E8BDB7B8191FFA1DF9815B71CB483773CC20E4E09BE8DF2915C24C2ABCD7E6EBF225B8185F242A62ED78BD29BCCD243A48C0BE697185CEF2FD6BF77BC6169AA7D98DCFD187C0C0551E954481128BFABA82269B5C3628FFB8656F367F3A6595532EDF2349A9D335003A44343F0579BAC8D65CD2C3261309855D9671009B6E644FE3D4C2DFE5F4FB928682E27FC94FC7BF65BFD71B1559B848FFE25AD07FEB7CE282F88547FEA518EABCACFD0CF0EF6BD56EACA079F285AF04D59E31A0D2E03A3F26E8F9690B29CA857093EEA5385AE8462A100D57AC2137F7C3E6A656D6BBDEDA706964C8BE08434BAED38729E605AE209F2C2A71FF1EA894484439D218F2F1A1CB4A89ABEF4EBE122DEB17026E488C2F894F42147263E4C2894E04715C04288BBDFCAEBC395F93159602EF72A1B89D9FA26D1745B10A87D038BBED00964C6719989BE6411F68670B35E4BFAEEE9545577F755E2311041C40F30DA03D4ED31C3C68AC5F6C03699D50051623FB6A186B7FBF38DA82DDF7595DE79509F36EB6566A54AF76213A1539BB58227314882C219A5C7912C8446F58B12E34FA3EE343C2056DECBCA69F93828D40E20806413FB3AC335D1855EFA8C860C8788F9A1FFB8BEF7A6F5203EBE5E8B92204C0CBF2B6DA82523D22A30D96BF9A4554B031A8866F1C41487295C61E43FC4AEFF7AAC801AE6C66B3A619F586AA28425A01312F2B727F97B87856B75296037D1AF3A87FE88705D836BE4FF958C16728175E940041A0C21BAAF6D62C6C87EF64DEAB002213A3C73535CFBED83318FAC82A4EDC91FC65B0D1B769AC1A4384D1E0D7EED6E576E9C919BA9529F6D3FA37C1A8C4B73D2A153A209740B78310581E408D5AA38CEDD36926E375743D006504331B4D2CE32079414399D380D4237FF1927C2A3CEC0F1CA4EF99F0E6D13B0E8B26F9B079AFEEEAB584153B33B10E5D6F9F4FFF95B7069AACAEE850BDE099A6ADD09959BDFECE2CA640E025CC44A7E9806949994FC618CFFD21CDB30570028E1FD606433D2DDD0EA7606F8839969438CC36B3536939A999026A4DDC1DC3D59BC0E784EB322984A475675112F493B5A8937AC8F6A728DED17BCC8FCA6C010A087BC159C711D1BDCA47769E929BDCD86613635DEE4FBCD4838293BFD9084BC7D2161D8BA89A1D2443BE00FEA224DA2A67124C632C7B561D1B1DBBDD7458ECB089CBA112C9698300AE664B29C1A3A99D2DFB8140CCEB489D928D2178A92829A8C5CF43AB4B9EDF5683AAB64E46B988E5FF5F4743367F84B459103E0B4B8E66411224C06D07A04805719873F9FBBF315B77ED876B4621C8C310D5C75A4E4A9ED3BA6918B81879D7E37C538066525A80C92B5A46E7FDE5ED2643315C6A3FC49A87EDF3B9C6D59F9E2455EF1FC09B5E34A860A6A07DC7E1C49CA2FD6968A422258F77E56336E5F4B4F2C00333571F2981BCA4CC6850874636CC05EF72B68DB6B0D51B757B620D215E4BB2DE99DDEE26660103789A0A5EDFB63B02E207A22BAFA50428C32A4AF52166AF0EBC8ABE13AB17339F84E09174EA0DDAED903595287981C1CEA280D9C0AF6679D0A4BA935896FBAFE85ABE5E398C7B8F1B73F63B7E2C9029D265FB53E13FD53CD587D96CDF400D5DA3A27ADB6AAF50248AFCC810B31AB00FDD3E697372ADB83FFD575086425E9A1090852425537F07E141648213A457A1641879C666BCD42466E8E2DBE7CA7DF3AA7CC1F738E44ACEC1CC4A2E7D15EB2CE013FB04150C54E029FDCEC0DB3065157075C3624383D07ED3084498A8A03E5FAB3962F75F28549D394C8082783BBAFA2505AA750CB036522496436AB11671D014CCA32A8327EE421A69A1E6A7C640329B12EE060AF0D3119B2F80441DFCFE9B127AEF36EE39E4563BEBE683EE1173133B1F7F2195F4A47687D67424E72D5D6B06B62827F41E1833409FBABC18E4C3C6A64ADB7E34B20F16381419B5B1F638D65954062B693F5A28E9A1CC6E25F0885AB55BFA7E8E94D6FF880CEA8437AEFBB8E9197D046616D03B2F736A18F2636D8CE224F6BC7E7D4366CA443BAFD890E583066BA5B614980FF5CA476C382F0319DC11B5EE10666C3341101A139BB43273E17F0961FA4FE870237BD4535CD41CE33532DD7B422B389769FB471B008C170E459DBAE2876EE8F23475A82D987D369687126490D17A9A2AAE604F807A4F9CAFD1C96A2ABBD913F11FC4BB9A80E78E789B0F6A5E10E69A824FBC9FA3E30D2B41CC86D0EB60B3E3DC2F1CA93625B0361F14FF8036D7EEE4CF98D1EC35C66B73E685198C52AF6FD59E9A53EC7D8C88DB4F86951F688FD25E837AAD3DA6D1019B7552406E46A8B2563E5779F61AA3F366AD3727883096962838F10DB16C8687FD451B776275EFF7FCF6B3F567013041C569D1E60C1B5C8EC1C879E3F2E5CD3AB78A371EB1D3562692D31C3DB9669D66155CB12BD053213181BE515A84D489D96A1EC85543562FF83A50A78786B5B552643FCA918F6A41EC34800DA6E14547FAC68F20948450E4AE1899A20BCF161CDD9B5F6E62A87942C9997CDE3A5DD354B82CB8B3539F2576E2EE0C1B93D8146318327315FA27C342F9221BA8944CFCEDEAAF238A21C12AB4EFD5512E4AD5CAB2BE66A520B1BEB0E357AFBAFEDB2BC8C56E1CD1B139CC2937F24FB81315A0796BE92EC8C154957AB4EC1E290174F12AF1D04E87AB07FF03A4E65D1AF769064734CDAA14A82B1C992D4AF8098465F9ADB1004044B4239B84AEA88115D14EE54A1E05C284B6D94F71D300E98572A07A335E5A986909178B31B572E9A4705383087EBD75F3945E57802F8FCA532B5BB4358A51B5D726AB1B959B35206DD40051E866730C009C89D442F15DE88888942BF4B9338F47443DB9646CC5C8043F757EC219B2BB5E7065710499BF62AB47A93B415A9340B4048000FD3943E692CD0EDFDC129D83578E1CCDB3025AC43B7FBB06953433347EDE591C987627D27692A21285B0907E972E4348FF7FE2DD33A685EB9CE5606333C243EEC252F468AEB1783D1884615B4FE7F965CC3C770D4D7715D6CC16914BC3DF693CBE2D79FF914F96BDA88217765B1701CC2D99FEDFA60D8F00CC7B6A7BDADC5C30AAC45DFC4078BCF5A33C1C7C22F247540880D328F457D4C41CD24462C502DD854707720229FC2A0158CD0AFCA67F701853431CED575310FD0CE9E422878656766DF0C07A7A38D7D1E3AC985039DFF8B365B3B909A48D030661DD1F3FF9CED6A256F603BC7587325C4E527E1E2116F47D2F6D606FA6877101A42C9D70FD8D1B5542E019205FB0052A0CEF042CCC20B88A7779DA8780BF68613B23D19DBB9F27A0DC2BAC46EEA362FA97D7E90595A8A17D7209834E4E5A66336E9F649A36B644331AA377EDF4D29861149CF4B569CD4FD727836B924575591E323FFF2AC5ACD1166FEAA0BC7734DBED34201421B76F31B34AAEC60AE123037625BDDA4A3334C7022657887ACA7212E2BA0C5F1AA1AA35C6467127C255941419F1B8E08016CC1398A98B003C40C7EB68F9C6328C4CB9AD2D4B6DBD0D699F1E278ED5D61BE9F84A7479A8C80AEADFC67541F8CA679C61E13CB57F8B9AF4C284007CF2EAF0C626CF3F53BD2E28FDBC0166E2C6E2DAEAB98988D2CE41359DEF85D3407D1D3B874F5074B21B550CD56888E886BCE48BF1D81F01A605F250B43E79BC3DACDD75477C8C0C4CB8E5A555C90860634504F7AE33B8DDE118AF2F0AB22E9F89350F374960DB99714D95B11146852DF53A508C8D318113B8B0548172A7FCA1F69F001566567201591204CE1D435CBEEBD92F9985BCDABF1A34E3DA49944D8A935B6D2F6911799DAE3D8C06018F238ADF96856740329A8FA33A76AF3480A73E7793693B6B356495FC7FC5A647BCADFD0EA7C7BBBB0C532707D962B4779729C2F7636BF14CE858EF0783BE5B53C5313CCD2CFD6B670993BCFA580212A030308997569EDA43CA50EF678633E918330AD279ADA75A06E0187234ED049878C4CA06B24797BEEB5E460E7A4C37F15F69AB3365A1D4F378C4524C020C63086422C7579918471B58F5085771C850B03FAC49449CB774D66FEECDAF5F20A15D4579C4A7107DE3383FD7FDD7E3132071263B1CEAD3781F3D46EECA48F4702BBF85ABDD62F374CADCB7FE0BECF8B3A7E7E167EDC0881352883F4F99C769E605C28C64C4ACF0A35BE8C45B6DCC15B657BDA6817EC1554B853D751BE8693D8C388A031C691D0C7AB63FC4100198B60932C49EBC60574E3792C14A1E1406E8CD187858FE49EA79E88E9A5839FEC759B1637BB78ADC2FE1757CBD7A0A6437DA02DCF2684ACC9D93A79C6D4DAFE070E4C5D71B5090B131D436D84A3E2F1053D5F6680C1E5F8FF0311125071C4CD217391CAD60927657F92CCDE0000000000000000000000000000000000000000050B111B242B3037" - }, - { - "tcId": 54, - "deferred": false, - "sk": "209CF1503755890910D7957E3EE07CA9D8FB60C485199EB6E94958413F8DCB76DA669CDDDA0A5ECEA69908064F4A7DF347BD6C9565A3A2E4B7F499B4DD21FE5532CF2E7B20788408C7926F9819CAA78835DEF06207DAC7ECCF49592EC2A63E3B80A5D3AD6F128037ACDABB63EDDDCB123AFFB6B68A4C9CE9E8A5185943E0910949162A54082A08C210811286E3A690E0B06C631202A308129BB465A4286C19A704419669C384859C96880217244C301023257124470953460ED3B02422C8509494094C226A1BC78924A47018A081130480A24220C8482984183194949094A208D438295B424023304801C8280C8310181871A1000218092458C08161144AC8445281B861C0981042C08081444292A66141A0511BB98C4A122D12B40D14A64021A044D4066A50940159265040C41002C92463088681088943C4491C270E53882DC2B22C0306244448120190455A02005CA091CB868DCC92816200010920211BA40C0345409AA028E10466A48490C9086541328A002952E1262589C86182B24484863123298D50004EDBC83013B2440C8249D8462A93B820C03208DBC80042388023C97009B38010066E12381112A66802B765D828021B32711B9964E2C0205A3049E4468E00150A242846A1C820184402C8C42010440509472020C689A10851E3C2400006499936706348510905628B328681926802A05061B805A3A02C4484692419061C310E2120051B0730A0826C12A68C811292CB064011156803484E44865184B26CE1464A02C42CA2140D10256C1987644A0206044602D246525230319BB660D90401929271CBA02D4084401A160104242C030085C98204504240A1340E42148EE33692E40809004029C4288583B66592044D5B38490A1469428468211341C1B010C2B80CE1329110276459B60908334D22A06CC82650CC3421D3924D52442D63300A5C225048B805C3480E23244914114688069221454C114172412211D3808D5CC22D128909E39269A2A4611B170A10B9041A850922334E08804DC29481D1C2700B314E1C112194324A5B304E59202D21282DA29489214048E30206548240410472C904644484314B9030610261531821418880A33605D1021111C84982C46191269152B4658A9290C02004D138620125491A010962166483348D03992D80242CA1264CC11400C2326E10383104094063804508A460492081808861D1C069CA1832941644130208802229E21605A2349219038E98226854A88113030520480EA43824433860A2185103066E08162E103952E4C62803444143462584102C19124501202922204A23B03118270A993486C3304DD3206AE434015BA691041552438608001469190084C3A66111388C1083081A336852B47163266CD23804A4B245514611E412519406010A31498AA06C42164E1031921A924D4BC66D9846869414419B2010143212A382411C27628C12909294210A074520167091887002B569939841DCA841CC16240B254163C880500231C10222241850D1988583C22021B42CE3C22418490C5C440C610892994426441802A3042421C30D6416015CA00D931409D01086622492C24806583846C8960D01A828DB085082488109A22842108C5A004C51C84821A02CA4182EC130654B448ED4320E12A54C4B267021351048324604224C22B665984864D48485A00221C382244AB28412490C5812315B3462240581C10060512208800692D8384809853023B1219A3062C330204A4000D2C68149440241962908168910B564D1246252488DE3B810C2248A22172622C48CE1347054C26084866D58189153B844441010D2C264DB44849204929428258944011B800920343060243143028999242021A3502011410A820D91100DD9B47018112050A40598085292440A6148511C482143B4018A004493124D022541D02828A38450A0B845629890A49000183985194429202344580829C9A440424610CB3405801664090832CA904D9BA2054330110816280C836140A828892430C19200D096601CC031D8B48422B949A3044D121902CC462EC212926184219B0206099400C94062110860D8280842A67112835061A2856388040A192CA3B261223342510269E11046C9B421098428D0040E04032C0C93004134865C140488048203C5918BA04948108D0A959109C80599202212009251A2708AC288C9864123122C48A2710151E50058870C1C30610170B9FD587BC4B3F85B703776E6F8ADD94EFBF90CBD56A19B70FAB9C75BD7C2950C0A19A76384441868738DAF758CEE368883F85ED55CC375A8B93900C3BBAAFC5B25FB409EAD61837A468FADDEED4DF9353ADE759ADF4A0F281DF12559D48BC02694DC5E64C8279503E0F1F22491B7F961801328EAFB849356F0E6F65CD5D17ED98807A8534C468C3D31265ACE7CA849B586B3193402FF6A6A32863301FCCCD2FF742370579066CA41267F2C2FD089A5060A7B020BB27640B31020078B290CDE6FD19F60BCCADD137FA78FA22D776C48ECAEF97DD45770AE889048229275D2F4413601A8F368B4EEC27C69567B7047018A9C9A656AD46DACCFA7351749D0969C3974C01DA631F2EEB2F16F313DC51CB7E7D13AEF62964BC6835FB30206E76C3F1314C6793D55916A56704D472FF027E6C950DC75B29290C922721977A1136B1D8695AACA31AE3031840B603BEBD5CFDAB31A21D2E52115CDE13838F56ADC86C3FD9CA7A3F371C55BFC84656444827C94F1E97998BA50E7C548368B131DBCF03EB86A9721F109FC97DF815A66006A4802B7AF8725ABB9A00EDCB85DF2101B278504D18CFAE6DF34B8A6CE5807FA94A3036E69ADA21525C69A9635594C68977CCAC05DDC80878101CBB64562103147B13B14D8358520433692D9658DF7FA44B40C159F8029AD9FB6D660BB46765C9DC705087E6F571D199D7B884D04104F93FD7EEF066E339546E005C6395156692E364B9688FB38CCDEA4B21686C98AF009A6CB8AB0B3D90C8C11DA06C4A54B957D4BF11A0B920426E7C5AE45941445E7C123329BB68D3AC9BF243B495A5E7CD28FE5D96E8CF5E5065FF414B2922A17F67DDAD671036B6C00AE92142DB0C9EE9400EF838CF119A751D22C11D408A858E94338871C2FA52278FAB1CD9D565926C431E66953704C8CC1373B2E89858B93F219A6801756F91390D8613B32C4727A54502F15A64DC5EAB77D6478B376B91D2B1DA996BC052C2DA9AEB9D1C5631CB6DDDF835D1F69C6164B54AB7B2689B74343AAA75957F87BD383D58DC54E8BDD7DFB1AF9C6BB4FA87DBE36585C693630E151E989E3A8157601597D9B83DF18E1095993B00B4E6FE4F70209F4778BD0FA5AFF80E906EA410502CECD1A017DEB921155C8B7835CB5E9B09378ABDFB054B22ACEB2F83C3664E8966DA5FD9A202BA7FFC0AC4895F1F7D3C96D4BB5142381F61F5CF00C792F710C6F3FE175DDE276999A70B6680B92F27A9661519E0F4241279E3315784B40BAEF111ED48D3DC850CF176BA5D220EB269E9171C9F712F70C19D5107732E44372470517463FEDB22D5CDD3A7809037878FF294A9CF04B9A58D0433FD299765009650D4FC1663A79CF2F24091A6261C110CF84BED9E62AE2475F2B40CE90AD670E309D4DCF75596D7651572EFB1434107864CCCEA64E9E1A9CB29E91B28CE86D85266F51B264CB15FF96A150D4A3CCFD31396A83A20AE19F011943EA2CAB4AA620272713EBB003D6975B5BAF761F3640A552B73F240508A940925DF60A7C6C42A580546E4522310E3755A03D59F4B376563A3C67D46AA9027F71F81DEA4074610AFE620461B348F4FE5CC193320F935AEE4954C05CB1CDE81D1D7936F08D8D796BFBF4E749A1B9FEC4BD528C2D0801EB02004D55CE6C03118D5BE81996A074A3E34D9F6EA73A09D37A2FCA4E7A6CA108AFE608C51D5D4B389768C0A3B873C445C5CE41F679FBC03D53F339E37F292A25B3B3DE21B241BBF8DFD8DA5BFC02D95DED7D17647D4A185AB6611DD3B5633E3550C5D36F3C6735B4DA9E387E27538DFFE1F9E0E59338AD012F2B3FF600EAF9823DE61986787641F1E3DB10A95CD32E88F7572E5ACC4F9192A2B479F5A7A51324BE33327D728E00DAB05D8B71B91ABADC2B7C2A8D970B680761CA1434532A6E9B88F055AC48FBA402766E642ECE0BC7D3F26A246FC05037E7B6F9309FB7EA888FE98CFC80096DF715DA794B0699D4CA0BBCC281CCF5940300FA9DF493EF84915F8A69081D5F713FBCFE566C93314C875583AAE4F20CE3D96D3497DA9DDF2FADBC36D428B84FB7DB4E283DCF3402D2364442BD98EE0300FFE12BE140B105F167F8DE5D5FA172707E5B06BA9D037904B8E16A343C0025584A3578FCBEB3CB81DF4A3FF307D161121A14628B9B3448FB41B7A6C6BA0525C6454B6319C4D8ED75A072249BB15D4CB4C53B2FA1699CA553133651FCF7B9CF4B5AFB5287F1D12EAC913A770FCAA9818756FB5BB6B6DE0969A0649E28B58FB0264659EDB203E54F9FB59BC1339075ACD254726B272DCBC5266F62435B4363254079BB656624009CE7BEBF9C0FC75444F1260E5D253244F0E8D41F0FEF7675ECB5848312B5B21BD3BF90C913A5A4CAAB1AD8047AF7A4AFAC85715A28693908296780E8692E30B14127727FF96E6A7E47024DA021C3113B21A74638E992A31E4C2C2AEC14B4C844279DE7FE7D71B4239ACC1737A64E2344976DE6BAF28E871F8920FD8B709A0968950F2628EE4D1A2BDFE643838147BCBF7DD4F956099964EB4019BD02B1CD1C910839FC2E31BCFDEA6FE30CF0BB6212EAAF68A6AE6A824D9FB34281327FCF710F7391AE2B2DD226C3FD5B272FD32AFC79B06C56B105AE000D720C14AF953CC61CEB99F3596FC67D066E24F8370BC39C72324848DCA63D6DB88B647972D500CE65626905AF5E7DEFACF8D320BCED02F3A70B04004D3E6633C10B274274DCD08EECC7CA63BCFB6331FB3F276F29D5290140F1F292BC2713C8F928289192AD040B3D38D11F09A70FA0632D40A1251A4759EB4D63DAB9B47F4C6A60B8B75CE5E3B80378D9490A2C53401A9945ADCEB43C59B6B665CB13D66F9C2997E628B0EF6A4DEEEB9BAE945E901C7F5C0E63ABB78E0039B122CBF2A9C1D0480CEEEA1135CA6779558C3BFB3335FC967693B378B90B5C540445073656B81A956DD293225F4EF61F4F90EBF9251FA1B465B31F560EC9372AE878DBA10434A55462654226C66730BC525DEDF0C1BBC3CAA44F03325F893C145EA6E433E7944BC4A7F287315FBCBF4AB60231832BFB7F1F4B2D2BB4EDEB6ABDD9660A31B1C73692734B3B0CA047E8ADCFC2982012AD18501C0E74F4EF0573BEE43F2C381C8A724602B405EF1C785EDB21671B46A6BA5432854001DCF0CD6FE2C5810E66C0A592341B56608BF21A5FBD25CD42A872E4CDE0FF1C04A26EAD330E696215C1EDD63E4185376E40C94F9ADE402C1E570D3DE551D1A61E90B6BD917C7131EB111E195E02392EFC8998E41F83F7B31424615BC5BD9D339D4E7BB1D5661CB2E368915FA405785683BB5FD2F310A2A2F786DF64CC1EC6632DD4E52DF98A294BBF575777AF11A253F7974D6F1001381C662D6FBA283CCBC4EB291CF5B5A79F284C0CE6EA9947207F5D4655C8A26162AF19679185FB2204778BD5D22EB1F1E4DC3409DB4A42539E76AC0E65D1EBC3D46365B96CC3C14ECE10B8E3E4CC63FE871DA586680879189EFE5D8D915AC3E6C5C7E2C5757851C3F1B393B0F374ED88528C1BB59C3E95309870DC002A0A10CF5F92FC5F333BF5943AE89701523E3A1220D4CF32F46E0FB2DFD0E93186BFECB7A056541E98F9B6F41CAFD8B37270447BA29FCC7900A80664044D60A7CDCCA95B49C64A81F82C855F1902CA8AD535C49D6C2A86EFA02FCD213770EF00E9F74AA8C8FB40BC83C536D199AF9FBC0E133D0459E8AEC4AD49998E9A985AA63581DEE44E53296AEAC9644A7AB7AEA0158ADACEBF55F9DEBAC3F33EF7BB6CC509B7AC3D6831D8F03DA6D2F103B882FE2E09FCE7FE1C2896AACBF008A6C5E47D8ACCBD12AD47E85543D4DE56280201E4F6243F1542D4308032A8FC662D7ECCD99E2D54FDD436AC317D69E80D1583B153FD8779B2DA53C4648FE434DDDE7BCBA5D77730D6ED126C96CF90E9C12DE3E54B148A9154ABBD083623E37363A0B9DC9B9D4C3A339B8B8791D4AEBB58432F2EF97DE72E3298D68F08D61CD2260FA4CEC8791CFA78734BCDDD485E5C35EEA534269F896FBC3A21A9F68E23F5CB5BC8A24516E2B8E5CAFC55A53A69AFE6500E37E7B8667462A72A8D2C33A652446E8FAF29492BA7AD879BDCC454AF4672D3A184DD20FBC7AC11954DE7DB917C70498E300DCB4DCE12407DA39A903EE84035019371C7AB01036F15676383F3D84421FB4EE2F43170C4A577FA7DF722D8B0F749DF41DFB093496496DDF5FEBF17DDAC067A1D8CCD880C591FB4B3168C8EEAE75444B5467DFF6532B8906BC92DA98BA0B7B9178CF15D881B4C837764245AB2DC3960878D8F89CEFB9ED76322138D51CD1AF6D65C65A415322713D13F03930763E54D3D59E54ED7E5C81A80D1D7BA3583460548EA385C3854882DBD3572B67E4CF836186C516BBF7A6D5BB21F2C14FD6E7E93890D9874E47CA2755B88B8F79469654890ABB4578EBBA3481746B5ABD9A7899E78E3DA3E6639D370F77A4D5B76D18E1A5E4A92A8CCA023C96E82EBBFD958F4D38E2C1FD9D6B57ED41808D7222711CDF3549082AA865278971B8B132F030EB07E9F60F386E133BD7B65DC0008893EDD072E2FD4FE5A426AB8F5DDB9F6B61D30BB07E5977CAEE7FF81C590C65557B26237BC7A1AAF24F3C91891FDB378C96136D0BC5BF4BE4EA780432C0619C4740146E8A100DB1855254DDDF1D53E847A8CE30B4A6735FC540E19010A5F41987B", - "message": "D195727ECB5183C651AF26E85116ADC65D8EE8BFB9D69CEB16EE2907C651A92661ADF6BB626FF86075EC72D375374D69168E0E41894A0CC750D4EDC4B2F8B2C3829B209F80C3556BCF720AC69EEDC004B2DB0079152BC2824C767FB7DAC8D37FB310C0363B00441608246D4CCD583DCF8BC88C857865D443D15C9FC4DA5D8F3DBFD71FDCBC4CCC3F6078DFE96F94DEEB3B59146A059257D2EC7D82083FA58FE70EDCE1AB447828A0339218D038C1C15464DF6A69449D1AA0836455E5EC00D1794917AB31E843CAA5C259081F33DB3741636F09111FD8FFB90DC9EF0F1EEBFA3CB14CAB6F0325C36EF089424457276A737373D1E73C83C5F587AE56ABB1BB2E049D5F479E4EAAB534564595E4CD86676475A1CA4CF0989CF9EAFA19B85919B3856E0FCABE8CE0143DC0C17FD87DB0EFA166AFC565419C14681ED37E62E875F5D61E1295BD28CE133B060BE90401BACD695D012D4FEFD19803CCF38D9F1B1A49A9C581934A194CA394FEB536D99FE15CAC739A7D311EBB57B15CAE09CB6212F03CE589E65D664003DA334C0A4783F5B1D6BEEFB20C572E32ABDEFA8B1C26D6E009FCBACF51B71A9B26A7D460516735ACE8CB2FA2431CEDF7B4DA9D770267AAAE939D717D2FDD7C066033CEFA4EE30C4956FDF2C7D46A7D7B7AE9ADCEBD7BCFF5A122435DB08CA9DB92040CC19767E061A85BF3D15C4CD1D7FB2209D8B90F0A6DF466622E45B5A549CF4F14A641799E83C266DDC8E9C35B0451891356D6782AA6AA4E3A35EBA2C88624DC95B75022600E78DF51E3B6B5BB2E9B4DD10D3BC926640664C8A28717621349947EA4F2F65122964E1FFCDD300B73F0C24C4EB6111AA28187AEA245F65D98DC2F13C229ACF0E89B871E556CA7ECB4070E99E4AF3F425D56A850E3DFEDAAB5A48BA4C9E5128289A6FC8DF96E714BD26A8D90F0AC012480F9F9D4AC3597E429818DC6B77A564197FF45E6D3C03B562B54867AC3172C436B431E2027AA81CE8DCF4D35C59C9F58E551A71CEF6C679F19207E2D0424B476B6536357D23C923E1C35523B605576AA828A9F788EE296CE9AF15DBAE89D03DF0BAD8B3C4621E385C935FF863B029177DA67CB0704BF24418FAA78B5C15C741BBB8E3DF1CD51124D92A437B224267813A71F165CB9BF6E489F588D596F752900E724ADB4153996F0C485C77308C39A1D03E82BEB5C5B406842522B6341D6D359173F76BF437CFCD20A73B8FA28B19BCABBCF2F42CE40405EE4F130110CA0637D7FEF24A38E55EC322BFA2B9DB9245A73643703A55453493BE3041530AF27CD3610721F8224FF02BF758395187C2362F921DF39D9D674F09F7248A3901461B6C112A8C01C1D7B539D11D91A44F2BB848694299265E8DFDED18F3DFE779D13988FC888D301A9F723B44522B9B4457FDC70C040A3ADF07E49E6A96A13413098BFCA8E5FC3CF2B44C738D783E432C5883CA27E2E105DDD27EE8B57FF45712FFA372A547E3C81225B9ED09E81D5DF0AA1E5EFDC433B67C31449CBE1E52ACA1565BAAD62EFD4AA7718E6BA95D37127F3D07182C95BD6EAA899192829B499081534A310A8C8AF7B23AE4AB32DE301DC3D727F7BED3FFEB9756376126BF759C1CB139E97B0AF99734B5FC1C7144C4D1EAC84208376651BB3CB53BF423CFBDAE5755FFF7A02AD615DF6F5E009F3C90D34A5B20D45DCCF20CB8EA044110C8F692C68B5902181F3D0B9CAFD529630AA540F65CCD2A527439A0680816ED3672B5B488C11B447D972017857358977D6A14CFC73AB3D68D8F53D1CFD6A94826B28EE537528387CA7C8BBA234AB9B656098701503D9FB567FD071C58D5B1094153523F29AEA0F47B650D66F02BC3849BBCB780DFEA9B78F1B893D8470EFCC7D38BD5F6CF55630D9A56FBEBB6917DFBD55E1B55AD9485274A21849CAC3B5B6750B3F87E17A8D2B70255155511D5AA8655301392765D8BDBF9FDAFA20C7562BFAC1DC15117C33BE8F081A339607F24E9C391120EEAF785121500314391C338B59E85D436CF7E17674EFE99FB6FA0EC3B413175452AF135704480CF2F3A7AE79A7D02EA5CBA662B48D64D001077D9A2E43F7BCE796DB5C878D28EACEAB6EDB44F1F11C502951BA71FBAD2FAF36A17FEF17B860CEEC9F6AC42157F685175D61BC1306A3876CB1E7A4C5A886009F7EDE84AD022C0D2BEE4B9479890210F5801A81AECF2D15262DF143C58CBD3733E34D2468EC0632DF0F8C401BC9B55EF5AC3082E0BAE4EDA24770B4340C1DB72F665D2EE7F8BD2503FA3C92BCCF5C96E1254FE243EC9E9112341D2512092C1BA2491078609783458F736F7E4BF622BF6C82BD6027BF003FDFBEC56B3E4C9972788889DE8FC9199F8677A2442C7D4FD89F5B72AB7CA5A42B28A04179370ABD31B89BFB9BCEC11BDF2E3906CBEB28E02037FD75FB7E510D742358A0ABA847D98D438D6D0C9D87D51557F1FD8A1AC783C84BEAC1109801BF25A89923A4D772D02BC420936FF12C0AF90D0EFD3D76B60E47FC781D79739DAED7FC5E38A881E323542F7440280F7F41686335AE46D9BC83E142A487FBC6FF9F0449A2EF33946E2EBC54D6F9FA9751EB8373E37913A2F87AEB91CD17AF9F782A286ED779FA03B54CDC48503E53A715AF59542773F0280EDCC39DF2E8E14B770D9329A11046AA40AAE7D4A1217EBB18DE7AAF6226AD0B54CA7F1E243BAD9C207E6ACFFA6C868F5EBC7BD47F44F38DFAE8D9A08401CAE1DC8D9528A0A467BB7E661895AF78A4F17EFEB12C088999E9F31FC38CF62C03391419489E5D058E0FE8835E182EE6ADBD74CFCC873BDEFB242CF32D2EB44F3FDC7F477C5C3618C14B86EC0A03AEC5DD204E77DC3609828090767EB71F5014FBF3870CDD0B07FB355006D60ABC6F72A3E3127E43B043C6E95D5383586C69C72190A87A7552A8EF9E91271FFDF2DFD413CFEB20E672A5A46DFD5E86FBA58D5D7003C8E99082418E04F9F0E954B1C448E34E29E5C9D9CAEA7A39FDB7E0ACE98F7A7CD1C13AC3223CB5B4FAB15D1FDE6AB43F33E43508D941C403ACB3BFF643FEAB4E08321C798717335EEEA31A8FEE27ECBCAE24AB94DD83AFED3AC2DA569BA35715414B46CA276264DE79138C882EFEC587095B9A9B13EC994FFD43DBEBF6AD717A2B498EB3AEF51848C0BE8177D3AC3116AED0030C1D835ECFFEF4C040AB249DFB8A5F355F1573570C68B71F72BC9844BD84861093A9FBD961A9A32706028000DF313E0F176AB59DBE64AC08F7E5087326FBC2C0AB04CE3A9976A015B232BCB970AF057A30BE3F8044321462E3955002BE5659C2BCF1AFE4AB6FCE57EBFACFD2C6909D47E8C7C980BD7FB25AE97AAA67CD8C0F8104824A0EF6ED42FA3EFD00F78CFDDC8EFC1D8FCED85E440600A5D2EE690D54EBF15CCFA21E9A657796A2DE0285B200BB681375227801DED42569A95B65D89C1DFF85AA8CB945A1714007D0B632696FA90137C6062A53719CE888E7C00CA57F6658116BF55C01F32F1A9F75EA9DC75D0D29B600E43EF42E6B7B078EAC74BB11B5F16D7D9077995F011B05FB58BEEDA377355C7C1E5A70D4D5A1E38FBC030F3415F833D7413E9269A6D45B5412CACF4E0BC391BBA8D10AE9C8AEBB22E040345D7018C5280CF86708F1044D2843398391C4C3CFF160804CDB2140CFA846836EF4FD9F8E955C9311DBB4F23BF5AC2B29985702A64E3431FCFEAE22BC1ED31CFA2CFAF9546DD1DA936A1204225D7EFAFDDD5EA2C441B068EE510C5F6FF0FE23DFD74FBAF0A909873B1B4357B72282085E1D12BB41B3F34AE7EAA35DF50CF5D7C2C927A566DD180F98A056B78B975391AE016C65C8C1EC077DB59709B8A22891D3CFEF0AB3300ACA83DA7C2EBA70007EF45BFF1D9DC8A7B1D4DAD670A79CE915CF10288B1647ECAD1F092D6F72C0E253263FA5A2B7F7A1FC5B0652A0DE29D4B149EFEF9CC426BE99FDB6143EC403B7267BB49A7B4D3304BEACEDB2D5E0EA633448F2722AE75D08C1BAF2D5BBB64DE90DDB338A425D1CA3BC19D7F9CDE8798BD372CB8CAE10935905F7F898F0EF1E95A5BA9A4E6CBDD6FFD5A083BD416300B953E3C5D94CF3A4A829A048185CF2443FD7185CCDA1CC6F984C178052B9BCFA4E10558A352FF5AE02883C1BDC56221655F33D7A3BB1100FDE18F5CFFAF52CE4447C9E3A7347387C52530EDDB0AB888D1B11767F9E0176EC4AC8D16DAC47011065EDC664E33E27CB73DB7BB19E5AD7B086A117FB0692D20AE082799A12AB58CD05AC38885B0E2F330D7C12700B576FC363E419051507BC9E75217213713447854C87090D1E3A94A0A62C03C330482B5395EACF5A31A4540FBA57C3EFAED560103F42B937AB05AE323E4BA96A1676F5391021E9D14587C805BEB513CD6DD3EB5097193926813C757FBC15E1FAA913C4CD2430C39926F72A79683A7321846A472045537DDA431A6AD4BB0FC96F01313F32D69738B5F430A314F47D40EB10318E8584E22BE9459A645DE6B7CAC90B1EF7A926845212F0CC03713DC374A877508B86D9D58EF8DA66B728AA2982F7A2E0D76826B73C9CB7685A12DB0650FCC20F8668AF6CAAE3871D6062210A7A4BDFDE788DBF37B7FDB83BF384B815153BC8D832257461D61A6E97A0DDB5F4D8ABEC1327F14219D5F534FBC98687197A27FB1657F9B5675F07D0BAA6952CEBF882C17A9D333C115120D2E78CD368A6D4142DCCC9AE779925894663029439A8DDC1CF322C5C2DA7F3C4C4CE93DAF0A56BD24EDF3D09ADC8B5EED6CADB2FD615EE65C27D79D47923F46AD676762C88FC542193D8AA280D9F3E4807A6802212CA3B3AFA1BD745C7FFABF8084BA9EB10BC9457ECEDFA1150E9809AC240D3241CFCB67F6287E81C53410F8EEAFA118D390189DACB9C1EC8499DC1E3372B86D68D95F31AD9E3EC9A965FF30BB644AF11CDB8C5491760BA0F168F624F217F7C474DC5D29A0BDF46FF4AA03B85AC3557ACECE263B472D39C5F2FFFF91FE2373AD2E5A0410EF09CF4306C381DB3C0EA0E10AE45875C5262E78ED4C336000FB3376853FB70BB4506F1743FB5165A62702266FF09D21AA08ECD555B8614E21033E683937F23E2510E19815F27EA20B74315E8A54734F636CAE877DEC1C95F87519B29D5CE9D7759C8AE33FF09E48805AB1625E69C34AC5DBB5130F77CAAFF42198A44B0F0CCCE68FB85DAF391B188FBDFF388C00B7812954B1AA19C0572DEA2A1C5B192E068F934D7305EAFC9F7775DED36695A4DA007CA1D2418E900A5985934A3EB080E7632494ED66112422FB96303A2419ECC12468CCEC00812B1470A3843A0DE835B7AFF2ED5366D932DD58A2536C9300BDDDCFA122746830EA5077FBB698EE8CC54F02D33AE1E7BC7256DD351CEAD19310274C62C6D337488AEAE4D50FD9200012758D250FA337FA30868469BCF32BCF2587D4E698F0F25274128672EC2842F6B08A3848B9F72AE50DE563B925AB5B016DC0FD52DFE09A4ACE472C2A9845EFA44FBA151804899022DAA4C7334BB099904D1EB8CBCC92A0C5A23CD24A1A0599D518AF79CF4B9820168CC9E580B63C7790913620321AF853C98950B034A01CECC0357D6FC3513AC67D50C3B4205C2A165261726706C5DF428862CB0A020580EA40FA31BADC8EE913083CF6016D70C6848362B5B58A6DD701E049FEAC64330363623134E6E0BD7918270CD4EDD7BF9C771F3F3D1578E31B85D122685597002FDD2ACDB0F9F7D5B3B0783EA8A5F3B824489F85AC84002E21232B3CCCA46DF146CFB2C895FBF83C0CCBB34D43AA1646B2ADC6C656DDCFD2A5B0C9B92604A1770DCBD8BEFCA655EB0EE6637C66B5EEEADC51316E1B6BCD1F8EAF7EFBE70712704829F33294F2A7F41BD23213FD5E8214BCA0B04874E990F10E6DA194AA71CD410A60CAE8CA9B9B9CA9B657BC6CDB8D3044196DB4482CD10302CDDE208F41AA639E9EFF8A8EC63E1A55086555FCA3BEDC9E30D644D56BEFF9EB59BEF8B5F0950F0C44501BA81B612A6E43102816CC6CB1B684111450B6B7FEBA9795EFE09C6D75308C2259557560AF55370B8D5A9A9181399F952365C59B3E9DB59118CAB65169D07AC2B85D96515BB786E9EBE545A44BB060A632063DE003347FFFA6C118363F22E0D30EE641E1DFD19B6145C8DFAE8D6C5230F0F5745AB379B8FA3F7622E718CCB2CB83D310ADE1519BB660E159BC3EBF65D9B830F2F1EE74B61F9423437B87FC52AF851E5DF3361A61F3E762DF69995D2D82E1AAE36B6C47D9E1D656B843558319305AE3196C324774AB9C6F39C8568C665C7698FE913CAD829E8A804ABAB60E53212B25F5FFA9A42BE03C2018FEE6646211017E41A8B4345640E2B3106E37B0CBA56E202CC89D77CAC841B2C592FE75519AFE726B71B3B15157FE9377747C7D9301B3076437FF60837CEFF56A058C54D45A278CDBCAC27EBCC2582C2920E4BACDBBB851E7D2CF8927DA3D2DF06083A97417B45C2F3A395B639AEA33B1173AB0AAE065FDBF007C98B656C715162619A706194353E18F9B33B97762546B85DFEEEF43540A0799C2B77B95EBCA6DE2C2C5EF55C991061A03FEEA7D9771B7E82EA2213507D8FC08FCDFAA497DF58E85A140E92A4C9A27F113E72C500304697CF0F98B7A401F33BBF03BEFE19219F1305EED7200EEB8E1BA1C61443B94EC34DCB14C537F25ED632351D7D32E4444625822B13C37E12AB95468B157B3328593D35A3425F47213F19B25532BA81D4A6B741486C128BF8F10E740D593277888867D8FF078BFB886EEF3E9FBC6F201FA29FBD8C04BB90313C3C2F3EE7B5117DB86EC553DA247464444504FD44C735204C5CC36AB02FF74DBBB3237BF03FCD72EC8267F1906D7C66096DBCFB094BE55FB71F7DB528FD001F6055C0568A7DD200410D492927ED40C911EB68B04F57A27B09ADF8C2400F7F36AB8EDFD0378D52711E0C53ABC7EE0DB0E1BDC5A834ABAE3F25F7E4DCEFF00D94B81118349D2287D7939C5CFE96C873EE8AE7B24DA43847C3C27CF2BF64E60D7A0AEA743BDD9898940B69E07C6F70BC18B749C3FD6A187E2D4DF5CC36B693407418CB6E52E12A374EE51D65236594B88EB3A952A55A2646793D556615E67DB2718C461028FF6FC109EE1E23B091BC83B30AB2B36905CCBB29F46EC2A334266C08CEF7DFE848C34166125772164F3AE8FFF89B3C528681696B2F59EB41D5D461603473EB7ABB7B4E460439EA6E37EA82E0AF98779687A07CBA719A64970A45A0FDC6A900D21A98977031C3F2023BDA0594F0F68676D2270A3545051252EB800AF73C26493D7E73D6360E4ABD92D5C1BF83ED5017143DDD240FE77F45F0CEA6BAEF56C8C3FB5EF2E4080AC453F637F2B58AF6E1F9A66F61BF0021A730637BE0FB6240F4858A4CB665E6F78775FDDD45B717E3C0D1CA09FBE4DB5210B1C3D8DB8F80C1313CEE0A984BC7AB02A1533C1210D26B093F0A60BC947DE38F23977D10E898DAB20FED18222023CB32869D78C76B76A82ED3C1746932D01F55112BBC16FA319F1A1AA888B8013FCAB474938DB3D2F4BADFAE774188B2F55A98A61A62EBD73FC513504ABB265556A61549275F8D69C66F73169355BF45F065D6CEDE0FA85514DBD320F6794267D1720437877917CC2976B6C3B700B313E60ACA8D23F8C85ADE9DC33F2BB6E07C322A174668A64FBAF2FAC6A66A87F2D71AFFD7D6F57592E9B96CDED7330AC6EF1D204AA9D7CD12BDE1BF02B5E182C7BC74F649F1A5FD9C7DD4EF147B63317AF4AFA729324467CE64F17DD492F266D8CEE84208AEFE759746528E11A631033AB652F51BB950AFFE7DA448673D44EF0BE595467E9EE7CCE9CB6079E142E573AC58BA1982FE4C6D1466E0F07AE841F8C034D1F619DE5CF4CFD4F368266416DF6E1F31A8350424DDDCAE24DA93B7A1DD3387DEF8225392DD01EF1EA6DC281B384174A81CC6747F9E2CF449ACBB5DE4EE7BCF90429D5754163CF81DB4A350D1255AE03878A51CADC3C97B4F7669CFD51FA4C1F7AD4D761979EC4D397438491A7C6AB37B917D89AF727DDEB8B6D14063756C55FDBDCD3CD9D571B501558F2AA1823220B7CD454274A27EC4EA274B8A2FEEA2C99FD9CB4D9D2280C0D3F12B2E3767050441002F063F0B2FC90A6A5F599545A72D83C792A7867421E7D4844EA46B892F4981E1D0D61B2690318151C2BE095444219597B867B086E612D74B2DCF3DB01ACC2969AEDA673DC43B2E432D6D87F83201538B54865659B22FBC3813E062BE75AEBE49B73C5697ADEA1D0EC063B6A24AEB2B8F8DB25FD916E1A504711527E24AEEA6E30FD2E45E90E13EB35F6D3A58342D4D3BC2ADAC1C92CE1B9B9AE678EC9E7D7CFABBEBD09726EE3C3ACFF1A7327C40EBEA01C65FC6E962CFDF690A4DCD1B0DA5079FB79820184E012273957E61AD85A6E7B494FA43841BB2530BE8E62810B0D04D5355B823279F7FFB09E4E29BB5DAC850335D7DEC5BF85D58DABFC0974A0B065631343C75D6D9453180553CE1748D13CC803134170701818FCB8EFD6DD1005146C65628C9A74881677584EEDC8828E6D82D91979B52CDAD59FDE3BE5841BBB66E32C50A5A65415E17CD86E4B45B7F7389E63E28876E830CD0B18E0A055F4EED5A39495CFCB1CD165619061F5E9D5FE708E91DA62E15EFB88EC2BC287C97781DECE4821343885CA78D6D3E772712CE8DDA0AA27D7D3BD2DD4D8DE459595B8494912D322C2B39F2AA669BE201F23C45731B1583002C094B1F11AD4D3532C342706F31B46D86E9A25D0BCE86C95AE48A9AC3171C9BCBF3C6459BB816CE97FD79ED643DE57DD7088B37B14EF4F24EE7D7287BE433ABB0A7AD55AE8B76112154ACFFC0D5B0320C067FF6C3CC42784874D011CA372243FC39C2156FF28456FF4F04F3C73C671EF8A25F9D2830E572BC1C4733E175612547733C27F4A8D46CA4A726A93FFF9590A8B2862B5C6AB73861B6BE445E28FE26F843F35CCC0FD17ECEBC08DF6947297A61A65BE09B59693BCF0837C527A328AC8790F06879F63603932185C5A58641997BE5E786D585B6E9AC6D53021364A05382AD66ABE0A460492C3166514315A8230B4A2AC8F7AA5AED3BD10DDA406235F973C8DB4DAA4DE3A6AEDE312F73F1BAB9479365485E141C5DFB10F8C44B0E285D61DA43FDCFEFB6719388DD130755FE339558E968C096D4B7C6AA3D60BE772E8BF238857225501230FB26DF32CBE3073871B63B799A1A96E64C684EE120B29773BAA9F70F8D6FEAD1D28382577D2020158B5D1356EBE934E94812E21021E4B37E7E5D52ECF89395840D2663CE04DFF92E796FC6D33115D00D95EFA323F4F7F835528736764F99845131446CBCF7CAD9EC36D607191A0505B4D4A2857DE5C6C979E25A99DDCB2F058089E0D936CAA5B01B6C89EABD71DB8FEB6402A6551A0E320A7B3661A7E54675209478F4AAF16AB77AF79F8C18D144AF44017E23414F9AF97E8ACAA0821FA7BBF9A1BC02211F91698744F6EF148DBCD51BB8804EA03F17DC969A133B5AF1FB70E7B419D4A76068C4501E62582C319392C625927D8F8E6F1276636289E3E288EA9C2220A81F82FBAE3610DD0F518D40F923F71DE2DC9892085C3857A30E9FD52E2EB4E66C2AB789E4086E152296CB4ACE077128B810B69E838F4B60A967041D4C3374DB9C5C476A4CB02E997A1C2253BCE1BEA72CEB08A2095043B495043912A1E93245EA882C8CAE9D14C0B3BFEFC643E064E279A6067E785F63C9E9F6076170E15869E3653421C4384D326980016C192CAA9C65AAF4FA5315AA1EA9F1C5FCD07E41B52C09F2EE7DCA8D6EA05A93237D0DBAAEF2D7DFB2978472D654B1EB51A6EE8DFDA37F79D4DA9D74445C8B7EC6EBFFD095436BEA5D7CE435A5DDCD8BF20FEAF91F207F224EA2FD19DD355B97CC2A4FA3DFA4FA3CA00DAD7DC5CD1BD1F47AA9A0F458A9168FDE748F7F0BF70AF9AA02C1AEC1059CAFDE51C8360E00C2327C25D43F5442CEECFE64E440AA1AF2D6E48BC6904D4E194FE9F436269514F3C3B43A9AFDCEEF8571920FFCDA5485A414785E4B02C4776C1723", - "rnd": "799722D7840000F900795BDF0D9B116977B5329B368A215E400EC7BC9862E95F", - "signature": "A62C54CC17CC4F8408F4364579A2F8A1F7995D58995AA61D3BA4FBC83356B6F675B4111B9ED9B6C4595ABC0F5BD47FF12B75702A9F0998C2AF1C5AEFD6921DF3FC72AC5AE2418EBBA4CF44C633BABE8EE9F0A6149E811969EE24561EE39D449E83903197BA00648E466D4B1F4447184CCE585044FF0C9137C61951DEC58A4D594BC6F3B4FD1F0E103A19E705D5FD74887B5F9F18146E849523B714A59765517400A2B792AA3979F71CCF78DD566BF4CACCC3E24F2F07BD346889FD622DC0068EA0DEF1DC1286FEAF5A0B3D09ADE4D621128B9F1C68784835834BBE2A65B78E0C8B76FB94E29C0A3E15C7115C8E6F3FC59504BB52ABBE3E9DE3843EB730384F11163288B414735D625A365E73F1E83E871C00BC9892023DD8EA4BA7798B5252DFE5DB6FA8592BA6C1E60C0993002C153796F69C814AD3B8F8B8E4BC248405FED4527C6DAB32BA0ADF6CA9F8D13EE07B91CF7A7B506ACC46E431395D03AD2E41D8630D5F59077C27876AF52B72BAF199D9CE5574F1D02C4883B18119FF923BFED8B586F119FE847B2877EC56F9C8C8808892C43ED72A8BD271372EF7BE4F818D7C71F26FA7DA8439D5B446EC4D33D4D6ED5C4CB31E6C6CA633129563E04F89AF20852B1BFBEEF7E59E2AF36B93DF19B047381B39CFA9C091F3773EFFA56D744B2DCCA2F0D961977F38683419E28C931231BD4FF0572507CCECF6886934D0762D4378775000F223807B59AF01B8B3F7643A4D013DDC9B7C560BFB255F86F6803FB3F63CCE9C9CC12CAB063DCB9EBBCAEC954CA38C4CCE9DFC61BEBE686A1B1821999B254E4CB97E78F690780F597E7B6C5CD3F748CA5FE50C651522D996F7D39F4052318EB8D6AD32882AFDFAB2701150C9AF1AD7955FD195EF98DC467832F03334A0E3CAD1246FF9D3E69D4C3C17A0D6FB773251473756901FE037EE937268BABEBCD59512AE474948045BECCC0165A2BF3FF49BA36089018C64278927EF512A39F323F066C17A352B18FD072FB01C35489C97AC4354AE927EB2921DCC4A086662F066B0E603D44CA6C0EDF977E47DDC1DE342EAE17895B86406A3EC43EC0402740B26B3D949B473ED6E257B845B7B0BF92BDDB1A580F5DBF6BF27132C5D2EB4C232724869B50F6928BFED7520F9492D0EBBC4908D799EC3D5B3DE954538FEDF05FC9729BA30F129D5A8C379C2C90040E7E5BABDDBAC4AACD9ED1B77C46A4AB53DBA2320A39F9892A491838CA0D674CF26AE3275638E593AA1543FC2E67A811E1F2E105053B7D78C919DBF1BAB6980AD045AF54EFBFC62D7DFB55983A736EF368A7ABC0D2ED2A4056FE2F7622D82AEC0A83616EF034083984FE137582540012BBD137117F3A19EB33BD0D9DB05F00B5ED27BE8EFD8092599AD6CEB59B4DD016318DB383FD6BDC1F018F9061AFE4DB76B94BAE7DAFB1231050B551EA67CBB596293BC3C3E06C1D6B8DF433D0A740B73D0133BD631AE835D48BB646E0720DC1CEB0CF5BE0899D64640A1C3B06936F7743C4F35068F04C6387547FEF9B24A4921EF5FC797975F2B75CB605A0C3C5DB341A5A9B6CB43446FB36C8C5D41DB1179AA3A8EAF9BB865C4CCEB65087A704CD3A105A6B7EA7DC28565587AB63F3D0E0D0F92AC43DB920AABFB45340224D962FF2AF0AA110DE5537DD4B0B94304B8DE6CB943C63C5E7D46BE493B01F453C694550A67D0E695C45609236291ED9C8A7A4A3A9EDEE727C310204D3BD2785FB27C3D300EBB57A9596ECFAB2AF51E63A25CF983D6021FC382F1F953A38D9E431DAB5FC245059F684B477260EA2AA4412BC4D821D367F4E07FA74B59D3BE29DE61D4F9DC6524E659E025F92556A2467AE2186A7D74C947584214296A284F6F8EF3F8C49D0BE2F9545720ABC60F8991D1A9726C797445BB737AB66B6A54F1CA025B6AC23851169D8F94B236477C1465147723532B92CE5A84823C620126F64E13973583CDB2726A661E4DA98593A57D440501A9188B16405FB918A35A0D9C8537C7A6A349B3F8E0557718F0CC90E17C829314960C62986ADCF8B04F644D4255CE73033E42733C43055B018B4D1051D482C5E1EA515946DB15235759174092EF06BF2AF602C94DD2963DF49662C1E426B743E597C3771A6243A909D6AED01CC40CD3BFAA7331F12DE39CF53FF30742F018BBC85A1888BC7BDB9862FDFBA85395689922570D002B0D25928EE54B82C40E4DDBCCFFA3A1D1ED49BF8010BC8751DA47AA62A846993A8EBF52D654331C1619E2AEAC1A7F8FAC3627814C621081EB6CCBC4971B21AB557F7985043DCE23553E4C9B30462745E602FFCD57A3048E3E4DB42ACE5EFC95170EB652DDF2ED453027EEBBFEE6B38B2D29D661152FEACDEFEFFC02A005569D48F93C013E513ECFF362A7F752488B397AD2F068BDCC18833E6797073ED325D9154C8283461C737C2A41C1B925C7A6B20F91C029FA59BE436812E3018F139FD743C3833B316B34A86DE2BC078919372ECBE7BCAE5BC609A6BC8B019CFDA94CC258B57FC229CD80CFF8C57B73B49D33A0A2FE3730EB8DCD06206D49DDADF190671DB8775C1AA514DE4DABA86B204E30708259FD2B320AC975DD92409012B01BA93BCF52794BD4F31CA2AE824284C525A0ECCFD9DD20ACF944C8ECF285B1261A80C313FB189AF05F59E724382869975818FFDCC04C7CB91E25B5CEF520EC2039887B8C98E1AB707188219A334AE1EAF7B51F39657186925E13B33BA75A5BC18FB3580FDFEAECE7D9325ED52CC29B7C7A2736B755E48DF69DC1FD86C980C33C11267B0FB5F6805C5AD537B14303C67229F20B39BC3EADB74DECC4047A4C7B4DB918D47298C621BED28D5665500A74F5C11ECFAF1AE81EB3CD94EF7A4EF26F48D92DB0BAEDEDED05B3C8182C036402D203C2D490A3DEF43C295D768058288F5510E760C4A4990161E4582B551FCF877F49C49BA7619C3A8D5F26C392B6E6F3FC4E3F0172A1E202972F46B4F98498F18836E3DAC21E47B4DBD2235F9CFA2D2451E3A9E520759A53DDF872D2E3D551FC406982AEAB8AD10A2FB3F66D2B0CCD026030B47DCD6FE9D5E93E79AEE7ADE86F48272011270D27F6C0FB97587A2CE6199F8C3191725214DCD8915AA66038FD3750D6E2BA1AE78B083B531003F74F315EB103D427F2F13E90C3106EB6065A1B8D48AFE4591A3234840493C4C89AD3049A3C6FF38D955CCEBEC075E4EFA9ED5135ADE944B79DEB8E3C82E7DEAEC9CC3850505290BE17CD1CACF41F4369225A761992F67BE333D8A248E344C37915D7DCA1C90D04F10A273BEDDE900BBFBE2A04E523519A97482BF61FFCBFF4D1D1B9D6CE87CAA1990174A144CE142E1D2C09E094F7C825A26B07D5B8CC0D97F5C102907093FAB1FFCC862019B50507907D3260CE849229117E8230BC583906530CCE255DE58F41FA15E68C447D868A1DFEB5411DE87983899A44DFA64EFE546C52AAA4C555CF2F0694BD9117BBB295B551F3225BE367A60BE271301EEFCCA78F66ED8C8EFFBC33FF3FA7121F7490B11AEAEF55D2AC5059B97477CB636B58F0A776A744C32188F405F7FF3E4A2FCD96FE7E76EBF0DEBC6D18BA9C1BAFE210AEDD680EBC3662E74DE900BA8F0DB6516417A7BF041699A04AF099EB365CADFA63B71DDE0F1C36FE4AE4BA6415E31B08BC834FD3681AC039AA135D366836662321AE4EB8157F2AC4762FDE0972DDD8A57F421588613494E47896692F6CBA5F978900AE8873C34FB6EEC4A6E96FA7DADE18333E57223ED224F4BA6D371E101BC759ECD9346483B1C596B57CBB8B13A712B056478F3621525D37B5CD65D884F2DC322D1318CDBF03EA4E6F360691A4719874075FD1340B0CC7EFF1A611C15493A48D83259ECC5AD8BF1F730C269FDD0890A51DDCF07A0460B73B0F2CE75288F0FB968F3E437515B0238282EA3B0AA3C557DE9487FE38898073A2127F97BD5E280696FD382DC7C3E73D2E6BFCF42043A6D19F3950714EE7DB441114A67F2723EDC9464690E738233168E7A6554EF99BEDA5E842D32356EB9070B0ED4E0C6228A5A5320C379C00F77317612481E38792BF7532A8A93E24B3812799005E62B79102167839E18742B0E0DAE18A47A58BAE35637D40A6983788CEE2F7435B6C0AB8366B14D151C3EA6E942D7E549178ACAFED7F15CA5018F95AD895C2781B32ECCCA0A7995378A8BAC2F69EC472860577D563196CFD602B1FE2825A79421B572E484657E42835AC09A5A6CA07220C843F996089665231DE1ABDEA1A69EF045EAF04675026F6CE3BF096EB2E39DEB876F9D06F91C3D7DE92C60A4D5DF2E227CA54B89900EBDC4CE467C6F92E22F7A6EF254D71B6164363EB9A809B786ACA6AA79D0399D5F150DC9AB913FD17501C90F1CEA2602DD827249AFAE9BC198D4C13253106319FB3F88A64C136A7C5409FE096CC7EC86E3095A79D27F8D72537256F6867BBD64EC2840B09EBA21895FE9F45590B5ECF44F9D5A93F785B88BF93CA3DA01EEBF1561CC6D2B9C2EC82C85DCC2C07E411C112D28A116D1AAB68EA2C7BAE03CD434F0C500C3FCB95608DF1B95BDCDAF233B49C60359651EF15C3BEED71568D86F49769E930FCED8E547998959188B70436DA47620297DC1447318C5F9BCE57FF6E42FD7D43DA8D8B0ED7C5B078B98B9F96B83EF4CA5B335590F12CCF991A9EE01287D2025DF85EF3A7FF0BDAD77D34D20058F62472FFB7BE1F10F2ED21A5C5A7B716BCD0C7ED701CAA34819A2D14CA8E511922B08ECB2D94873299DB67D5AD931150928F391ED5E2E0DC75922A83B38670F399782FF747651E8F8B0B651184B8A589F816C7711220AA73625A314A218392B9B6B0005F7F365D1285E43680417E443A4093138CF20BDB93E8D97E2C53366AB7AAAFB4B8CC1E8D24E7DF82A8FDCFC9F6C2A8EBA8B602443C18289371B8EFDE5D74D8EE44409ADA7D41D5AA879056A4CC2D7FF2384218834CAAC737AF681DEC973E0F701D05C8587155487B96309F36C95C6EFAA6FAB32488FD224B0D5EF2D8F0EAB1EA01923CEFFD32BDDA0D9FAE6BC221439A1C58814D2535679F613BBFBE66533A491E1361B40811D51E32CA739F06A43CE4E46C977EDB08C4EE121EE05B828DE8B086B68EE0B4E56C1AD4E4F211D101E9D41E24CB2B2633E797DA2F17E0CD3FBC3D545C468747EDA65F2625AB1A6C1530C628E13466D28A4DA26192BBB199C320DA9AED6A78AC380455B47537C63F2A555C2571CA2BC9A4C9FA78D9F04341F9C90E7FC95D41B9C59AA9515793B9335D0F442B2EF348CDF197CB6ECCD50F942D1394694DCF1FCDCC12A031D02823CC8A2F6A20A6DF7E71F28BA193C6D06405CE7DDC2400B74AA50899B3685AE9661DFF5A894253F3A873BCCF2CEF4A5C018FD4465BF56249CB7FF3A591DA2B409A95297E8FA04730AAF2458508DBD28ECC7E23D8831001E86224F895CBDDF137E92720C511FE8FDA800CE73A6653A9C1060DDAE88C03EE0D49EC876FEDF79F364FB41BCB17A6654D74DACD809205D9EC3CBC787FD8BD4DDB487BFB20558CDF3AD1ACEF8C12770EE24E4EFC41908149F8E0D92FC183CC3321F0FE60D63F23ECCF9353032704DC7714B59448CA8BB2DF7AAA46236C84D4AF7D1D61AEC7F7B321C22F52E2DB28C00A5D2168533C767DEAEF2B12710A7B7B92A51E3363255918F4DAB1402170235BA6C359FADD2A7F255032D4D90DBD2BFDE02C965EF7FB9EF4AC633B4E8E40430946257E4EDE1C9970B195E993BCF4F00215E9B7983BE138B4E3F8921C15B2FEEFD6F065622AE2BC1A970B2D854C383C9B46BBC45A702CFB564FFDC37F29ADE7F412B678FA41A08D4AA2874BC12B9EFB6B20122D113795279DFC42BD486FB9925307707F860C5D5AE65056918B4F7B39A5E967B493E1B1187A989B486305A051EA2C7BCC3DFEA9CEB8178FA5DB800D18729D448957706530F93F6C1E9207450F6911167B9D09DA305050C3D6CA3FB3EC01A9F16CC023AB7E95B7480C77BD62A023956C7FAD148264EA2C6127E30762FD6488577D9F8F36AA06AF20B635A3949DD889638F00BFDAC7FA7078F181F5CAFE7E1F0342CE048308D482C400599C1C53B90915A52E9B6F03FD013957A213A1F46C0A8F3DA9F66B87E9C4A5B3C5293D429B0FC43F968B04462AE9F1435AD8C080BF63388BE2807526961E068DF2A9401F50B3B74EC16B14EFB5D95D9085933C955B23BE69A0A0F896A7033F5B1613C00795CBB5A562AF979525D6125D285987F13A95108C2A020A51D9DABA45845FF33CB89B7825D022ACBA8BFFCB08B53C8592ABCBBC7F2578DF937D4B471A7AB2CABEF75D44DD8A1CC385D9F5AB5524E4504ACCBF0BB0C8F1FC75117B70B32BA1063246D7F9DE8AF0A8CF6839B2D05D0C1A266D1CF42F02225F583E31068E1CACA429556641069B1F2D0308195BBF1A3F5D3D9325728507595CD9124E6194989BF2011E3858A8CCDB0C135A65778FA8EF1E28515C5F777C82216B91969FE50A23395F044447777C80A8AAD0DAFCFF0A3960808AC2C8DC000000000000000000000000000000070E161E2428343C" - }, - { - "tcId": 55, - "deferred": false, - "sk": "F0AC36225FD5E8DCB96B82E35A78F9FC254FDE9BF232BEFB5ABB1BCA3BD4B120215C71DCB2E57875CF07504D34DDD3E18223CE52B42568906B23F4AE49A658FD3A0BA784C5A724A7E65489A4F95F1B2CE9FB03BB8DC2655A48F2D6469FFC28EF9B6E8372B23990C2D9F4A8BC44820680A6A8671D933A733EBFC97B9068194C450880481CB32C1A9468002424D3187109C0210C1604120742E08009199764524441A2444284C65002C92554086D882220C1440AD8347212A261C9A66D1BB40DD99640E0904C8C42224AB289624609DA424449464959804909090EE0928CA2C46802C780102391C8187111A0691C926512170119484A84B4815B2690149948511860A0C24DD8A25111A650A1360521138C0A826199B451822022C2C88CC9422D5AA23090428AC10208DBA220D2965104984001016480306DCA28921BC3308CA06D82240119046D8C0250D1A6501A156AC84222D4C4640C1905CB2625889621C4B22104A789DB92640C12401142851195058AC261098104C9144E900469C4C00119998818368621117119126C12358C0C304A89400400230CD9103042C22019370D0B356D08C16018B121D84270D4086189840962264C01A008DBC284113222198771E418728B22229C000C2427882295105CA02410266511A51020B32D00C56D83106D0038228C38329C848413A811039029D418244C404E9A38496014601A171101368D0A074952381193821024267020A18024058A628849142182C8360D9C340660804C61028D0C0266D9C84560A20581228253306E92962DE1B88024330E904020838491A2C8104918650B39040AC32CE2800112B36C20802021028200044D14882902A771438269A2B444E30092C4144D11890913866C9AB884913672D8160409107021324C0C078E53A03108362011C16D43A000C9C085C1B44CD2146C14084D0305245B24221C026900C709A0104410450249448C9846445BB20012C2611C858053048111305224C981010831CA1632D84204884826C8442CCB26010AB54DCC26929C0206C4384D641424CA0651200845238909098688C8B80D50066C04B94C59208E5C3661DA8068C1C68C0BB74060B66C13302903874189B68822076990406583A2244A2031209824DCC00DDBA6115B18645034082422004CC008D022640B11725AA08992A06011A13183386408B824C1846950B804631405C98485101506E20246D920314C280024086E823069511861224909CA44249B480A09056DCC304012163080123010168E03276488202681400158188DD440209C120C402452C8064521147213210D104704E2100C18C9110134105306450B92458346040235429AB8881B446558C068024545011980CA864C4BC684044521001060141668923288E1B425121344D9C27010B08C422448D8882DD2C811C3C04424B729604460A3065283880D18A965CC282A19454A034949CA946D04392564444C124501084930A0A288CA18092305068948118A86840C07105C302580A444D11205D40812E33822111226C3120A80A46C89209112186902839061420E04970023232699048EE0186009C52119174C129648E0168DD012628A220D03058E1CA0210B33066008119A168908252489C811101268E010264BA665030548642688439480E34846E1066448380A2299601BC2085A86511A167200034CC1B0681BA464583050E0C48592286194C620111849D4226111843064464E21B59049163123A00000388C24B90C1C080D89B4011B908DC4A6042004445AC44C48C0080AB721E0A470640891538601C432659A006CD8A209038811910284D2B42D029644C0968581846CA23870C90864140044903852CC320C148040CA86459A202202B61051804C938668121381408484DB4846634206D22469C9B270602049CA345252326A8A4221A1842D21A320CA3441C2C8684146661A45301B448009B921C4148A089708D1846988A00919086021C38D1B36251CB0201C346C8490515B946C24220DCC982513B58D538240C2A80482120A43B42DCA4030424042593066A124000A83891CA66841980564903000C451103786DA06802190050C884DA33268D0A229040664C4328524B52023884901486461C25010A20D0A866909316801220698462842C48D19873061260643B20113120513452D13412822B21094A090D8126891289043C810A1C865AED83E6F4913C6A6DF09344301517E78C34ADD6055D92EF588CFE8E1F50EE39BED84EBA124BA65B99EAC176AC3F449AE8A7E72AF7EEFDFE7E0E89A695EA217129ECF5C6EF3237E9F045024D30FF326847C81E21F761404BB6AF27E87213EFBC932BFC967626B7FEBE322502C486662C14BAEFE175C4570269F70E171A7255B8C57CFD539031EE483623370852CF1CFE72076B9827814D424B94240ED3D0A852C0C5FD3E06880A23E79EED4820FEE4992941459C8A9C0B2291528242FA4D15F2C5483096C06C2859EB48CAB7ED5E1CA1DDBEE881C1E5381B9F6C88F3882B1BEFF06E0DBC8600423C26CD071460D1B4210D4D611E53376FB1EEA145AC846833CDF6EDBFCA2F489C70531569DBB971F5787D8AEE1386256890302FBE54D49884BE03057CF7F2FF362A6AF3BA84A126DC304D9627D2A4320BDB4ECAE38F74396B6F9B682812EA0D2D22FACB01FC18AD3F4C273F4312E1DF6E1715220947B76363073CC0ED1289760905802C81A08E0C21CD1A6E87BA18F614762FC3402941457CCC36DD97AE3A9923B2BCD1CDE0A624F358F0F30ACA7B5DEB2460D0456DBBF1489030D53FE13D7439F5E418D7BB79943001CD82598A11C9513170FA34345D777E7329A85D3C81D089474E19F79896F0DF4D8191F5DCC0C1CD0DC0BD9720D498031BDDC8C2D104D8BC5785B0B7457E4D4D1C590B86C01727ADA0AC3DA690EFA708D884E1363ACAC7C569C76207B95D3C53B4EDFDF454B14D5F46AF612CCEFA32CA44B6FFB7FF3A21198C4F66C809E65A6458711282A11F1DFC76DC664C94AD56BCA1F19450823A1883DC41880D61AAB80E881152B554FFA0292C5D4621A1E15FBC910928676C5A97841755F513EF86CC18ADC4E87C0A6ADD65044C4F5A421B9F32BDECB4E3889A671DD279C245EC03078922ECF083D8AB61DA95F4ABAED8F2238837A309A40158777D436DD1C9D0760156860E7C433763BFB3F550E8EB4BCBD7C8101ACCA2FC25815ED1C110503F7CB2128C23C1F60DADCBCE44094E4BBC05ED4C3910B25F409EE3BD6597160011721F233040ADD61357AB730C9577A89F636200651DA9C6A4423B1EBA50103082BD1915D1064C74154D4B95A3EB7390D607C7B2239D821BE2260B55D16BD30228F109B18D74C2BB17241E3C91979E34F9796354F4C1057F9B09F318ED50715DDC0B5663148BB61FA980681099D2CA0EF203E2AA2634D8213CE8A1299381701E8396B5C689B992047651478CBA0B8CD130B3BDBE1D2A42BA0D84F0F7F210A6B5C6FAE141D13AB7AB73B22652F98F901F1D930802E40A4D7C818C5150EA0DC5CCB558AB0EBDA316EA2369FC6949609F64792478ABFB231B782FB91DB5EE80DDC77ABCEEC9C3CF0341064D4E3C85E0F30B5CEEAB2C1B09785A38CF168513C4A2C3CB16A3E0DA3DCC4AF6696D6E8F99058B2D9D33C334E947B6E24E589B7A62778A1499CC53B174580FC397AE4F7D3B245D0BC63D867C3140037BBA5C32A40A93C90B03E4B916044B78B976E77160EC7D2573AA6371415193AA8683983EE061B9FDC9476232CDA3AB690D07AB2BF9E3C7035726A3FDFDE53B88B3DFDB5B26DDBE3D85266248D409A143F82B714B842A5D5D987FC2FAA3A2F65E0E6B98393EA0955A754916BE9426771B8D663D506C9EEB6993840664B52E421A3A8A1522F0C463864265272C6D2CC85D71C0C497AD305A2CD7B64F08F5192803F48289BE9812265478A562BA235CA0CA29BC38CCC94C5FB5ECBABE42F191CAFFEEAFD814F7F13EBE1DD2F2BFD6419E82DE56EAB32B61C93C5D59D50E5D32938DF28894EF70FE97EC29C94B8909B4842D5174BF07105B7888BBD8DF85A647BB66517AB0F932DB3FA8C122417B7D9FA46C4A360E6CF7C39F2D170D816200BEFBCDB7E60A6D1098EBA2DB0FB0C2253916E23E32BA87CC61B71088368DBC4BD8F175F03F3B298CC5BAAE99BB2F7093F956A72AF375EF3F8D9E32A881AB6420F41C7EB3AF3975A393AED2F497D20BF810914FEFAA8CD92A03C30434707EB28F5B75D187C3CCD3135320063A630AD09BD374884AE5FD73BF25CBECF3D493952A4053FA7720B6996956E6AC51C6E1A1DEB2239CCD1CB067555F337CDEB000EB091C1E4CE0F3177B1DC3E593C08047B4EC51451FA4DAA629E81104CA6FE854DB5788B2EDEE88016C2694D5A7671827E75AE71610A8E6C827A83A207D8A8D791B86C1162647020C7880DEDD43A0DF26B1E8BD5C25F08BDC8013F2DD108EC63759BC63E83156E73C95B0078F8E118CD2403AFD40E7C7EC6A3192A008354D6F48B58B537575BE0630B6CD485162CEEB93AB1C649F947BBDE90AFAC754A8BE4780B5C4BEA6D27E7A37BFB376366978FC4FF9EBD56DC201267A483A01A3753621FA5261E159C578712D0C6056EC275A8EB6B5A27CE645E5D47C129232B8745713024889C893CE76B3C4616E3F723432CD82901F4E67520A6B7E21D42B919556282294F7AC6A2620E4AD365C3C6B2ECDEE97317C765C1FF02C023044B7AC0927E5906DA029F79E24979C41CF12E299C185B243D4DDDB4E3BF8A58F4E22106CFA4537E9CE307AF1021031C614D4D46464BDDDB13BB2959D31DF9965D6BD545C8A0EF85A0A3D6A89CAAF22255894867999A29AFBB3980F5CE40E08FA6CFF6DDE4E0363B8F789A4C0E02DC737418B276715D77A20B3ECA145CFCACF1AF370293E4BDA116A9A1EACFF6F3746E0A5274F1B7DFBC9AC8F22C285F5D748E3A9A79EAF419EE06DD4A76A8B9D4268321CC0669FCA025E8EBA3031173E5BB1C66F476491F902B23C34B19CE4BDB40A055A82D50B5298EA758D9ECDEDB0B30DB99B79F8F84CC387553C8CBFACADEAAF386EC67E73532B4EC743375E462947CF69FDD04E146A8E8734F1CFA270C3256BD6FFE1921A6567F77D536521BAAA5425A78FEBD1FBB55081DEF63EAE9291D1506FA7687152DF66AD0B043333F1AE39D48B6CAFF310EE78674C7A6AA97C1432D76F411689B8066D9E6FF2C941829CB4323D8CE1AA2CFEBCD85CCFCB4D78953C6F5ED2D682FF9E2518F7FA6FE65378C0DFA8215DE2F7FFD0647DBA4EC4F931AC470CBD7000130D447C990D1B3DAD3648ACB4E31B6CD1CD8753C41D32BC0EB2861504AD798445A05D00C8F08EFEDC6DA47490C1E25F27693119DF7CC8AECCB9BC74AC44259AC1970AF44083EAC46AC3D058CD6FB562CE552E490D91509DE6DBE7B75A62AD8DD23D1375F3D819633AD477767FE8406AB4F06B0F2F5BA2E62522D594C7A68E2EE6C80F66095DB3FC3724C1E3EDF776C56AE2E1DB6A505B933F547EAC58B7E7CE5E5B98625A1BAF607C8F8CC740DEABA7C1CBAA5157DB304F2D28791C85D44E380B5B9E8E9F149F52DD3D665D999B6A4071EFC5AA032D1BDB86CB4EE1C0150A375A830AD57E7CA76DCB8F88059DFA0F1C202F5EF8401F0C10AC25CF2CE4BF66F3A3622971A54BF23FB26B5899F5509FBD3005DA82CCE78720E2A37F588642277FD61EBC594EB4E830E82A866BCBF8AF64E16727B11D6067C265085A5B557CCFDFB25D251A0C5DAFE1C6F6587FFC7093C7C72442E87A200AFD7421CAB51667B9FDC304F2746DAF72EB987DBA3E4B3E3E0534CCA125A3411D7F211E7FB4D9DEC0806294477D310AF637F440F44EA0605FD352FCC1C918E71BA7231E42E15FAE6FB4CE70760ED37C4D7A50B004B85E5941A8079F1484779837A417E8659837CF9FEA2A52D31BBB145E873BA40DB558D3C3BDAAE7FE5980D66EF1169AC04538C0988B2AB1BA4D29F62EF6B794A1CE959ADE2B506DB3D1834D02EFC1C9585F3C12B0ADCBF0910D412C86BF165FC3E165DC6C850A3E88C2811CE951E40EAF14D1A8FE7BACCDCD187FDD36AA38005767A5EBD7EBCCFAB03F7AA3D4AF269BBBA40821BF43A6F55E008BE7A5E9B3514B40B85C05DBCCD27016C6F4266241A2755A226CB6B93AB7CAF55AE26F495AD9D9B41DF10C8671C8D043738A8A921A9E863AA0AEE6A4B2CB8C211F879FE46ADB50C9EFEF606115D8CDEDB38F2A01111498166432EDF424E0C548CF8A60F23C30AB6A32D32EC6BE995B7147DBC5C576C76CF10D21BDE645B195EC8559CB8AE23C6E3E3106B5629DAF03FE7AB12FACF7C1494CFE7B235F56A04CA11FE5E1FD6C0CC270FDE3F72F385D9527316E626768B0A9B0FB0449D38BF8B8D928D8F9EC58C03CABD289F6471F7D9F71DC1530FB99CE9B5C28EBD91A90D2FEC091FA6972608755E329AFA477B06F9F1DEA9A10D9CD6D45C15411FAB89A743C7CC748EE0B614420CE7314F1FE6C279EDF31CB3190D008F7226551E6EB6E860D97F1E0C0F10DDC6C70F675ED77A5CA6A5C26C4884E2741D879F543C7B6BBA26BC442644DEA3EA2AD560E2A617BB1C1CB436325BFEF34ECBE5C8F47DA46741CCD2125A09B14A88BEDD8DE01496D501CA93C47E457D6F9889A2B5855AFACDFF0BA60E9C10782FFBBFF40981A2BE94488C45DE42CADEF3958C9D2F54925BE9A4BB85F63E79C6698E3EADA10D586B583D71DBDF77C04CD3DE40DD8B67DD5BC4E848BC51894E147AE5469865B67060E41F6D7D5F08761201B46DAE1011792FE8E102F2475A5F9152A083E175272C4CD1AAF4995A7798367E713ABEFFBC73F5E56A017D30099E3693FDA0AF0BF06C948E196C13A726C82FB2A1BBA80DB55FF98F0D8443238B121D93F3DDBC874F3E284B594DCF7509CB", - "message": "D04A01378911638A1EDD841A66822B74D9032876D38D86CD4AC6ACD602702DEC5C3177A5A3E6A5C9B399050BE6A85E6F97A9E16FF601FB48F0A41D2FDB172323E96BC3C5F2C21DBA721F78CFD6777167F687ED269316581FF66968C0A018E82C68DB83581054F684CF74854F21F2B25965BE48C3438BFE6CC4D319E947ED2FF86E9AC188D1D6253E4B31B292821CF21053B0ADCF1057C72963542E359242B68106076C1403050A128D581B0BB562C0F309AC2BFD6E35FFDAAEC58DDBE9B397663C67F4430FFCBD7EAE1C05103176EFF13018E92AA8F2E9FB4A7B10C183B82F93694C81A454F10BF3D6D3F057314A56BF861194184700B2BD0C48341BEF94519F73365B87357502C431312A5BB0F5447F97FF55D558A2CAC5D4B61A56B53C24012EA14C75C9EDBFDBE6ECBB12C58774269FEA5813968040C0AC2575F551E9B1EC43F0E2251BE369EF13EB55986376EA4AAC6B40662967F211C6685933DDD2C73C841F89B0D12091DF51817A88910629055853C71925350CCCA0B446ADC3BA718E74E79F8D7C439D7484669C353393C50C161CEE4F603C2424AC05F36F941646EEB7AE1B57133F2147A328554A5AB8D19423DAC309A8293C903FB2CC9E8A409CDAB0F7EE0527E8E7D92697789DCC63D779A37EAF31F0F6E5A5B4423FFA1948DE1BC622AD31317512D20CB3008ECEF0D37EADE6E6695C63FC5D281F7A39BBF38D2625478E9FE2845F89E70C94EC540EC52E7CFBEEA76E046354C28FB691FFFADFA1A0549C941F4F7A9C8E546DBFB8BFEDDFB179339A952E7AC2DBAEEF5C21EDDE55CC4CAC41ED76A8B09684D6E8C63F03B2ECD77FDD4FABEE4C95890BC8FF1020643C34FFBB71D9B630568346837B0F4CE676EF6D41521A8ACB081D1BA4A7FF33DC0752F8132679A15A19D1F8D977F66AB02EB2C733ED28B6354725351233D0024F5CBD7AE6C07A993E225B69094FD2F13D304F74AA4E909A8238B98DBFB7C3B583DA48AB68349A00A25C15C388AAEEEED5E5EDD6E953DD970825AE81C11DF653E5E314F83EA7D62B0738C787E598C030B97AAAB60BA99997D286533F5FA2386AE4FB5B48DBA868809BF98082EBB01D5B640D23F987DA4F412CEFA0A627722487BBB23803F4253EDD7432905AEBC587732D7BB1832AF41D1CFE506D1985DCB32C546B4872234AD716914DEEA5F64D919A082683DA9F78F303255B4DCB3BCF2B62D787A87D5F8F99B05650FB1DF842784B1CA9E9B03F8AB4FCE8A702BDFB2D668C6BE6E76F99AE43F2D6C2655374DCAB271948F8A25C9649BFF6412BA3827073BBA370FAA4699194154B4647884AAB3D134A842D6EE90AFD658B51002DC38F381E4BAFFEB2F0F6AB46B7E2AD59FCD410F76FEE32BA8EBF6BA222EA9B15D74BF7F9A0445D5BA2AD027D3FBB2D54AD1F502666D879BA88D862A90AA15FF274EA01E4375A794CFA77CFE9A9BA93F068764381DD0F00D9302E53199158D27296AC38D2AC96CBF0A12D3566B1AAE9DCF2F301DD13F59FACBDAE7A024A1A7A30DE8193939785E46A5456777CBBBD87AB319E330B88B0F4293FCF589000204718A9F12439551A7A25FF8A8E071FDE7B153E7A229133232102BBE9AD11ABE3F4E25E975B37D3C6265430672FAAB3AF12EDE00474F402A5AF0429F7007C6FAA8D2E3541B632CC5C1AB36F2536E3284AFABB651DBC38122A2414C92794ED799679674A57F5AD6A780A9D3C871E26B9792BBDE57912E911D7862BEE21AAD6F9573A8E4CF05C5408DF357706CD0F9955133674FD8E44B325C657A6ACFD8DA0F0106B4C207439F0ED294B2A2D37AF697D32287CC19AE765A35B0286E14A7D530962AFB5378DCC7E8FF80FE5F3E80E284C39F1295196029FC6A2DAECF2C8E9FD0E3F123C5FFBA26F5C7A12C43AAE077E47F54FCA478C931C9F0EB1DAFD28F8A2BD4993FB67561D9B0439B6E4B3A2AE787CD715EB6BA647A23A79937C97A7A8135FC667E82784565DE0BA718F2FCD96328B4981A53C58682432BA7FBDB4FD5575C8E6B249D53AC1FE7D5243D3CB7A5DB937487AED1C70F9110F3C23E882D3B0248D3D098D86CD7B06369E15356A786156A302916422E3B3D17338175041F79C9287AE4B2DD001BBC8AD9DD0D0416C4A278C64E01F6637D2D96AD98E429628A4066E56A2B49FEEBA8421F79CF5BC1EAA027BAD78E5FE0BE92963EB1B8A85DDBF49928CEEEB6EC6D5054ADF2A4F6136C58664141F567237935D42117B74F304634B46FE2B82A40E169B03EA1C91682C3ADE600E8FE9280648BE0F93FA8561D8F06771927B9C142694F3FE485CBAF5A2F03C96DC4DE36BD4DEC29B3FA8390214E460A512345868D1BBAEF1FBBE07C9E3FEB7CCFC9A45399579A5EBE46DCFD486EFBC4F269DF459BC3930228778E579CAA7080F7CBFF1D1338742078D15A101DE366AE138D170EC0E348BED6B79C0D8803301866FAD0BF1D0F4219689028D48269C9C485066ADCB2D78BD88B0C1C6541ECC091B5DC89D7A7EBB47E59D9E65CCBC3CAF31CEDEA58A4F5F4E0D2889AC18DABE35EFCE4A85D6CD6B27F5F1FC2B7C86E6125DDAA01353BBD866E39E6BE5A6B139E1C81AEBB2CE9A89D2E1326162B542ED790E305D51BC864FDA81181F60A04C595754B16D6900F442BB2B5C99A296597E02FF0B32FF088D933584EBA71055B52F7AD4F7BC3344EC85403066DE4FBBD3C628297415CFC72E4E10E5B256853572210AAC55765D81A87614DAF92E579D78E7DA71DC8376BFDBD04A553EDBBB01603A5EBD7BC7A3AE3704ACEAD5AA9778A44EC16D58E56FD0DE8674F92495865461EA8591A6FBEC395532564B5354454FC96EEAC5301CEBE5CB05B86801F9E18E50003E1BF961E78E13F18A43CA3AD596EE75F20523D7559F057FF28E89002BDF76218629EB34C4BC740D9C86BCF164BD9342682CD957AFD62A2A4FBE1D5C9CB07846352FF869D956A1CC5DD2AD80CA543E0FEA25B0A326AC507E93C48A6688D1E049068645A2CD7E6818D0FF03FF55BDEED925A52D7CF97ECC7BD1C6E8416F71CB61D1033DB82E63B518A1AA22F22722457B05F9D85432B14D443F740683970AC2F2F22A219A39F4D3FEF9602D46C30BEFD8497F4B3164BD8CF39D77AD0261AF78CFF1E5FE16FA8EFA512B3C11BEA5EABBEC7667320FD9B3D7F0411B293346FF3B0B1FD3317EF8653F7B8E25E53CAECD0EC7ABF3019CBB97A32364F67C3A0A89761179BF8CB3B266E07804EDA77DD63CE7BD5533BDBD11B4CBAB87E4E5D8DE446936A2BC78958A64FA68B0135186432A074ACF5A7E74C019CEF1551718ADCF908B5574EBA7DE86B617D4A77DD6DFA521C29F91B569699ADD22499AFF4CA238A2E687F2F6A706C998FF38C41951E26369F0A1B95050B6177E4C1BF1707686EFDBEDF960394896C37CF0E16B80E8E7F914BA11853B7E269C47C03B8C6A83BA796BB9AC004BF61D7A75DD3877ECFDD8BAD986752AF0F1A987EE445657C30BA0B567CD6959A2C08089E50176E40614E19E17FF980B382147D4124EC1CB7F027BECC23E8CCD9BF0B97292AE4C37C6BBD6AF10D65A3FF863F4F39B05495B33123731383DA0DCC4F174713E916E2D15E2D95CAAF4DDB734B429631B50BE1062F70301DB621AA01880A3ED8E8EF421C60F445A15AB533613139452DDB85D67DE030032B2353C593DEF07FD2AF0CBC807071B79B89D14632AB63618BC57901F7ECEDE5A57FB28E288FCF82A0E7EED492B50AA6DD8DB36BC5D582EDB17C5553519167B173AF619B174F455EE5A72BB58924EDD128CA936FAE6185170AD9DD6DDEA529CCAD67F97096236170ED61CD5AFC9DC79EEA34087B6E05297D2007BE88C032B0B2F2185340B3C80521460174C7DEA51EC9629DA09F582BD500B8BD48AB44B7726239AC000B572A3C9AC360A74315E22A68A303404294EA5F0223BA7AE052D891FD448ABA091DB1CCA2D04579B72DF8BB339DAB73E6A4C6ECE3A51DCD23DD1CD03D27D53BC115C81416E9E50981CE041FE0EE47FD3315B9C2805BDFC131D8A697E9C747CB4DE9997B9ADE8990674738B3764F95DA64F6A784E313256A9152F2A08A5C40CA817A6F86B8BCF3DA9AACE5A5B66124247930E42A91C945BD6052388EB9244D5CECFF249A741F0B4921395E28D085BCC9E1BBC4C7A93DC9A604E395C4061513E8D5B62B733B05D04E089D585B7F4AA0F6163EA3CD0D130318625F90545D03E68994CD73717BD2F88578D1EABC462BF5A547F2D7EC9EA8B64927A746239B591FE349AE8774FFE8E8EE1B3265C36C3ACFB8833BBD7CF720281C42635A64C103B7EE9556F705E488D0F56FCF1CB6C4F8BC821C07375347B53A30B46BFDC0DE58BD27F92ACC28CCDBBFCA8EF5223160DC88303438CD7E3BB119517FB3E194435FEA91F07D934D38E0CAE97573045116B9F496003120C8EAAD958C77F51987B5353D834638EB557298715501B82BD13D8156894BA6D970E330CADBD315D5AA45DC91A14441E26D33303CE9B21409B58978A24DAF5F5456D671D538A61E95BF7223691B7DA549EFDEF5E8AFFDBFF2B87970FA78C547DDBEE80F469E21C1631BE03A99A4CC832673E177957D0E4C662D1FF6FA093A75EA1BC8359E94293B577472E6EC53ED02BF738A24EEBF53A5E476A37FC97935D602CC9E76B77BF6A0A8D026F912F2C309ACE9703FEF3D4288828FB18544C20B8E6D95E9AF6D89FC2FA369623137E625960BF841D507A37BFC7BFC00A3AB9A1A0B016EEF4898CF01EEBE77D36B29BE7483235D2F6EDD0CED4CDE727E6F68AAA786C48BEFBC7958F32B671EE1E4F05A6EEA6B694E4310EE96F12B58918BEA68FD906CC3B598A8DFFC7190405D63FE18A5700E68D8664B045A8A24889C75CA836BB472E00D95CA6D4333DF99477B68BB89B7DE6C1F561D70706A697005EC13DC0AE7BBB61F87C073DC1DBEE5E6CB7EB3FA2A74A041D57B276A9267DE19A68B0219C654C62F62D5FE6820318A7D8802E838731680EE2D925FADDB18F57", - "rnd": "CC123C9A7278524F6841CBF47A2E0CA2A13CC57784195E98C3C0A6704209A5CA", - "signature": "AB5B331F079CBFCCCB3F95543C2181CB4472A1C24FC8125B66996721D1D6D801B9FFDF2F22E383CD3DCDFA174312D393BEA20C4B825B26A72F3783219D45893324147CA7E7025A6CF6C626C0616553487FA4098047CA72769DB702F9DD68F1854CFCAA85AF2FD79A288A5F9B7C72CE3DAEAF5E72A0FC271BEBC2D7FC1069A24187802469EB14012E1703F6CDEEBC3F5BD4623FEA9A50994E31B76BDEEE26621776939D5EBFFCB8911FD50969FF52128D28A674D26E1324106F45B10993390A6DA58EA3BE384064D2951658FA3769968BF7689908306A527FE4AC1BD8389C143DD85F785F4432E9449BBFAE3D14B4C4504F757E632CF0326915D7B99581CF632188A79E526526FBC8A9257D5158779DE9FBD0F987E438056DDC6CF1EF859BE7A1FCF86206F2E9A60B0955A5B4203A33DDB7F5E5A79246B6D99E26A48E9E93DC702A169D8D759955DB97A385595F8407AB5FD5E76EC04FFF7504DDFD90E04BCB909B7D246A5D895FD3A63C0B80AB73411E2A64451E488108CB7A69C98BAC1E3BE1FA49E2E6D42A964C3B47115159982AE0FA427BD5C137936D3728445572B869416868D3AA1420464718009F6C41952739F74090B855A09D1D0BB7BE05772EA414BBD2BAAEEA25AEB27C4F8D3B14DC1D8387423ECD5EE0B111D35A074951DCEB09B41080619C865AFFB7705C8C57F67E23204525A2B93661CEC90411168B891DEBA115453404DCC73E43E69658473A686EB221DD05C1E75B905FBE9D4E96A5F1E62BC7B8A6B10FF82096644241346C9B02585214427C35645349FDEC0C42B7FE9981A072A09530631020C42A5729876E269FC3FAF24F7D46E868049837E6328194A72C38A5736D3BCB122EAD32825F6C61313B5586204B0E91C27A6E7C323EBE3C7A20C0756442AD7F73A8FC81563DB633A662A2AF880CC324CFB6582B7DE62F3977A948B155D6038C822F5F929C0F96C660F0B63AC378FA2450A7BE74C9B23D054B7F22F95EE27C7175FCBD747AE1C0775B396D2EF5E509BFFF28E1CBC766F91B896ADC4C08A49A8921C8B4C35753A5F26DB6401968ADB83447E1C6DB12DBEB11D2E2133D7F88F7C1FA30DEAD09CEDA4CF7F631CE52C475C7A1E2FF4C2CAA2F3FB960529C35917D5571224CBDD150F5472F91EE589BAA89DFC49C83B59584826A877EB2389B3C642DACA5C1EB06935B811B2C321C172A95EC083F0CB1ABD05A478B09630F5F2994D7B8DC64455EDD4BBB376CD67E2E859F25C3C0753DC70E27C1AB76F85339F33A5B323823BD939E8963A04A738C1C8FF41339E6E8CCD45FCBCBB35E0B3AB91A59C39ECD858462F06989BA791CBB0DC415FF36717B9226F2F572327F85A2C6084C9A339FAB94A3449DAE1BAED4CA0E92F47009B756CEE81B1D98E40AE5F90F145206294EA4F9F1926D3FA7DF39EB27C4590B843C8042442C8297BAB972DC1C45F55E9B68A9CF271826FD39963112F56314FF949EB909553D9EC9CDE10FA1232EC66E3F20E038D42F581D259DDC9DBDB04C6338B58D0D2A8AA8EC9A989570E2DCCCD7AD21522F6E31AD28A1005B9A3B72D16C1BF729A769215DC2379FB7C17C9C20B0EEB99A50CA37399D3AF036099E51DBF721BC8D25A98D0369EF11839EE3E736C12969704107F64EA3583DDA37020C65A40F7F7A91C5C1F0DD5EF2343B09BC4072D5F7E43D52AFB13DC93D8A5F24E7E9EE803397F2D77C7905EDCB2291C7EC25F61A7CADE5E3A0D0B4DABA97BF54AAA38A322EA7E6BDBE23C6CC2FBE3F19E5606609BF3795156E0FFBD089261266BB61EE83C84C89C45F45C6C95A6D0D34E843882BD8B0FB828415A988B949ABEA029B1C96BB37CE773B810C4718F8432CF322D6F5F1E12D4F45107F5E8D01AAF224A8EBF9B6ED6A85854823FB9DB34C40CE0860ABB74BF417A86A47A4CC7C5B28267F04040FB8D0610BAA0ADE6D73DEAD3056EF3EC3FB68050E3D4926F4464E7C4C85EEB46685401AA505F9FA82353732A68B7B94735F4AA9BF1FE909C33A587DD926F913C99EAFA9F0DBC3A336CFDB8D68F76CB1309A71EE69C723CE65D8B301904A2EC0D4AC789C60E5C3A3836E751CCA720AF09847957EDB983A37C6721D291D46BC371CE566B427D2AB5E9847FC48DCEB3EE764CD2E28F1B39122B1048205A78147ACF6303D24021501B4C81D6897A22F5EBC4CA1FECD9D714B0288CB40B8C6AD3593B536A9DD52365D15C11DB3CDB91A9AE00B51E3B6D56F5A1D9B25267806D5A6712358F4F49709FFB4FA40533729715D6907DE3E4BCEC953BF673DB6947A9E8E3DF5AEAA537D93531F53EDFF79756C3B2E2E8739C7F980F525297E60775F8D360B10C2A4BF64D2E3C8345D56367DEB6555B44F6A786CB76C4781EEFF4FA4F97F9BCCFD6FB0EC4CF1F46D2485B69F4183390D9FEFD93549753E98960E15EB5573CAE660800AC76B3B96880BB45BD75038884D57133C722258A5690318E11404D28E29CCBC07ADC05C5BB2BD953672CD84F51C6848D50787525173B0F69A2D2577215E685639C220671AF98C41535B4E5522DD2672134E0699DBF75851B131D16F43B17C49181088DD6734D3CA60A2B39F0A2C40A8A85340341EAB267F06CDC5427482FEBAB0AFA7CAF6D9CD57455314DF952EA26F750C89DC0DC18C44DFD5117E8220BF9B2A34405135893FC61958CCDD0B75DB6477C7C1911867B0604DC1682A362F660E7B8DE635B48B33CAEAE41BCC0A23E32C2EDD76619378AE09E1DF2B421032283842E4202E4EE5670502B5E9CB4FC4C6DB5C4A735E10C8CDEE47E0C185173FB8797F06C54669EBB8D3DAA69BFD85EA935D1D01E7BAA1EA3F2096DB81E154D0160ADF4F40510F99B2D72E683C0AD51B58447E27D3618AE71802E25FA0F3DC85948210E3D2B1379557D872E8CB08D501D1C62ADA7E66A2A7D30E27EA641E9DFFE76D8908D05A23F82F3EDE12B7336526A14BE119434982DFF34F0D0344CEDAC15C165F9FF41B042071A7D2079BEB538C35C6DBD0DC26633263B719074EA231038F0EA0E3A6C177081613A175ECCF0CEDF95E19489FFE773C981BDAE58E1BD49994AE4BB02EB6873D599310F4556E4E5C9AA255253E0F39C83DC4461DA6239833AB98F62290A7AC3E5144D8379D0FF59BBAD9D2D1168B6697BA23B2353D3BE3636CA910EC9A29BAB68F04508CD14BA60F8FD51A25CA2178C01CE1A73D320C227F98B1B0026E1EA65AD0827687354CB85A652A3661175E7C0D784DDBC62B48CE96754BC8F718D7F2FE8233888502BC56AB1ABB44195321D970E274A5791CA37BE34258B2F5BEAF8A484BFF8D6A7D11D1BE946DDB51E41D9A5E51D537EC855C1CDA789DC172F9D92F4E11E850D0E10A72ACE3B9AB1402EF3AA180EE1D0E39F7D6E873639DFF2E3FFD86DC45A9F55B62631CCB2FB0C3C6E12D061049E2A5712101993F4FA6B3FFBD7360A6572DBFD745337DA9732D61A2A5D94E6D77B265D3CFB4BE594AB0E95820DF5605F5C1288F60F0B94F14EC32640A60451C6243DA90E15A202801653FEBB8A93E5484B4E2A42C3F5AE97D0AF9D59A6AFE875976707CC3C1BCA9001D0FDA847505EEF552B22189C525F1DF86D253956C3CCD3CB327894B03AEE4F680F703A66D2098F9033E19BE814A0E1D6EC6A329C47FEFC1122D8E2A150AE8D4586BCB303163B1F0419114CA8C9EE841FC75C7A7251D69102EEBB7180FE08FC96020181056DB5AD304F8477745CD2FBD69BDFF35D7BD255055E9BE32FE19EC26FEEB7859CBA8105094ABA9E950B455EF18708117DF94B1BA3DB8A8597DD93C40639E1A77A78656C02D24815682D85D0A794CFF5ABA6B354FCF31B207B6D99FCDB8E0D95D5C10E446CCD6701D349C917F9A9ABD0F27BED861EF090A95978353CEFBC91973C1A7CEF2644352416FEF6D9DC0985AAD28D6A0E61822E2C998175409EE23EEC0176016ECA3A14C96B73D0CD660744975305A8A63D6E24455A82B007BC74A4515DB91A3CDACAD4680858B6F8220139893E334BF6E09B24A1984A61FCE5B1ED482274F3763C7E76E30844BB6E75AFDEBEFEC2D9E88348AFBA365C17B2477E21898977152E458EAE491147A231EB71FFE0AE930398E94D05243CBC953F45F21ED5DFC4E65A2A2D0DA7BCAF57185197E45E269A1550B5643BF4C9649DD9169A4C3CDC70272C1A1A062C51BD14E6ABA0A7CAC34EB03DDC7306AE783B5EF5FF34E149A389D7FABBD24436ABF6729054DEFC18ABF39897247FCF6F8D7974D8F5B13DB9416D1C68EC5BE73C7F01C47BBC8AA9CFB8A0BBB512F3E1838FC7F5DE5BDB515026A2EB6AAEF5EEAAAE2421BAED716C99891B9EAD216B72F3E21DFD3904540CFD5FA00EDDD1404AA6CFF7AE6CB0EEE60561CDAA1737979FDF7D782FA086B8F981F469395945DBF5557ACAEF48457B11ADD20656DAD7421890550DD38288BEE1C93D4F93A47D230C7EACF4F0C231E441F05BA2AC564934ACD885EA0974E28E3E8100D71221AB385DC43ECC19B5548F38CB133342FF70B08D3BEAA45FEA0CCA92D501245A7AA905770382EAF6AC86EF572CDF536E85EF0EA594B3A4F4E4C6DAA9CD2818BC0FD4A2674232095A81038F52B28610CD88B9E995A9EF0BD32D11A0957DD24D30909FCE013D5B309904F0EA6118090557E4A132DE23E9E9FDBD90A8B4EE45A81B00FB05AB1CB3078508258CA5B1AAC1C447F18771138F877361802BD000F30F170C53E948C90D9F1502039E0057CACFF3B76C818E76CAA893C02F5032B5B5EFD9D8C1E835EF254D5F5DE2C64D60CF36B8145CB44D56F8E07D3647B9682CB573ACB1AA0887FF6E20B96DE750810D17B15264035E27A92E3E35CF9CF550FB940429B48262205ACCB3B1BF3A07E4488ABC44ED04635939FF3BF2A3FCC3B47FEFEABED2AE35DEB1F27CBDCD3A9214DF5999B4759228C093A342D37A19EA329F1F894218CC2F214D5016748212B49BF51E790EFC9DD899BAED4F74F612E0A9C1BA2634F9218C9CDDDFF1A5D13A633EB4B59C393CB1696BB2C8F57154C3093B35A759AA39DFC336DC0BC96169FF2EBDD3684F9A33D53C977D4BC1D5677D83BA13EAB7139E07C437D1592DFF0995696AD185B6B0F22A9B07723832ACC329421E6DB36230A0E42C716A5824EF818D8E06CF6F11DB050640224EF615B3B784245251BE99B063A232C787AEC272D3229F6475BAFABF19DD32F2A149E44C98A95B383D3BC8955F37555F26E9C8C1DF5B7D6236250BA93C342DD9FA69F2374CE06EA884C91077E829FCB0EF9DD546FB35F6DD74D14F077174AF244CEF210D7AA9B3DDD632D547EAD0831EC9460A6E7A9221B4F9AA1B0986A0CC54A6A6E97B285745A50B6288B793E05E5A373BBE37A1EA86A041333D8F0F70D256D645782CB2DFE72E4C3B21F912279F56595FD8E221487264B96BEF634DFE05B5730D7A48867F396C5CF230907A5827B5BDB7BC67174B3D77E8BD7FB91B220528D6675C1800ED7095E46C7A0A62E12AF7CD72A6680780D3EB0BD2E46D166ABA7C4A704A997BD7A3EC521C94852AD53223BC0569A1E95AB9242F89E66B82D66BCAEE512AECF483D4040A08B516F9CF3824C1411B690D3A1D4C9BF5F67C68DD8BB350E2A6A2345C3EA550049692959AF6AEFD7770773E597F658BFEAB71CC05454D74F20047B0CA6616B2E654EDA1315527295F7DF24DC7CF090E5894D12422232AB5F85B7A8B94CCD1FD30B4AA8C312AB62E1B159057842DB5E2BB4703376D99816027714A039FE51B03EAB7EE65D3F823BC9FE6A007EA9A12C2B5686F1FB780829E1770EB5B8D2B4DC2D183A016C901DDF020EF401F2B639C30D13784ECC896E6425CFE2A386FFF52CFF7605BFD9F3BD2C6CD69F491A8C709F62C3D58B6CD783A1DBADD0AC8CB4455FC9853ED05D83C19CF3E44668F687A95BFFE2E22F83C4F1EF2764E32F226DA4E510ADC65CA85446422454AAAC851F6B5A33A77D9F3985D5BA33B514E8D9EB50CF3926736E23148A0DE4C2B136BEFD72DA5BDB5ED0E7AF38F77B19A241288206851E4454D0C6792D238EF4C32508D9BFFB0EA76BCA169EF264E1E1DDC1A08B4CC7FE652656E672EA21B5853999C5029BA0EFF364C1F62DE9A049E2B66FA078C7247A4D293BFA8E8562B6613FA90089ED9B83C6EC417CE5002E2D8D642AE3DB19686C25FB4BB1A9A5684CB911984241BB1BF31895EEE6CB1495A3FFFEFE790E9F3A535A61C90C791D81AD94FC34D495BC35E00C43406D45AACFFE5ACF8F18370F3F89D3514B33E76732378A91333CCA609A112F0C75AC2D6DE22B2CDFBE6BDE1E8610F4F01E4CA562B54318EAD6874320AA17E831F487DA76B9528E2FBF8D4EEE8B4F9504222DC040979F13C0D116BA6589D81E7E72B94763B5466F4D3AB306DF48BBFCA96D66827272188D7DEC0B01C88D9081888677E587DCDED6BB69AEBF1187291C2E36606A949EEEF2153B5FADE1F00223267CD12F4E7C7F8D9DA1AFB1C31020285D6B6C737F903B679FCACD0F27526C7071909394C6292B2D303A65788A93000000000000000000000000090F141E272C363F" - }, - { - "tcId": 56, - "deferred": false, - "sk": "0F1DFC8E70C9C500D56388DE7D02FDFFE2D196A5E59759008F172317A2F06B4A6412C77FCF9958BE0B9C821A85CE99A0B37A11D634A82FAE1129BB32E266CB2F7E08A6849249AED1471927586F9F773957FDA32AACA8AD3696806DF59413B260ED59A4C29DF28F9C6A6C605050254BC7FB42789DD6B1DFBCA47E22A07A7FE585E3088D04010C48A65008A240502885C2024D1338015224114C248081C28599143121997193444124438A1C221124014D1026714C344E13264554283210932C813625A20891CB148899B491A2846DE00225C4200908A33102300C0040689B3001A1422D52409142908983464202396A4094444C420A51A42C82A844D388080AB8501AB729593420C2A22D00014A90C83049000C09102903B191D086890C018C59B84863B4289B8005809609148148CC00080B426442488118A30503426AE49649C8C420194805E4100098B241C1B450D1920000C308423452A4064E5C88859BA071CC984903842180280E594682A4369188B60803172D112772C8942CA310468C361143027184A420090864429221DBA484244502483681833670E44051D304681A272A40820044428DC2B67040C250C9288E0932001242700C346084801024260DDAC091842809A388682018520332851B1481032250A11031E3188124410D59964904A7900BA16884128563C2045C264202077212220ED43020CAC86109241263C429C8A600882804DC4012111506003600E10464812060C316299B888D01B340A1C2090B898850406264060409081112868050166E8A140509416A4134411C4461C49625C008664286411A10009B96450311519916428C3272E4400CD0B62D443405098124D3C63192808CD9922898342E4C20121A1404004564A1140A61100C1492219A8284021051E19470D02421D2B485E4308551A4400830048128859A806984968DA4B20D10468519898C204012D3048CE01881CC8220C03644180368DB96900BC385541486A4C450D9884D9184102403691C00699AC80D9A841151A2504C4284E0429202C868A0466910176613380ACA020C4C1861C9B8619424710BC71003284042428940282C02160CE0122AD83271590231CCA2512196455A922023A68C4B20690944300CA22464325143C64021146EC98890D4020218033119A88461164CD80685D9A40C20338D24C621983865E3888C4B022CC0C204A1308C8B087001A244C23806D2421263060004357162222D113061A30068C03852A102508802711BC20C5CC090D0C46120C411DA022A51204E4B9045DA884CE0202484A2850C456290442988364560088E8A046C4198445C240549260803A94184A80D52C04C02A64C91189012A81042126283100D10C34903280D0A8130A2A0715AA00CCC266E92A02D14B0712118109AA86160A885149309E1922D13160A21392D8B282911268C23946060347103002D619489E010494BA08D891664DAB22DD9A00D8A4408409871C416651C0062A2080652C86CD1048A13C44DDA04905344099B18446182514B3241D0942D10C75009484D81A42DC348441C37620BB30C4804321233669A00824C28861C878D41388A1016849CC84944B060100720E2C825C186859242009A025243C22DC32820039130D2180E4C9800C1C6600A380ADA3080C148260893404CC425A2C8490396854B264D982281433832C2C030A1B42903135100A22851145183A470989665A2946062402E18190113092450B22819A5455820800B834091C26D218810DA068A24438C8A384A5932200C456902876159240013254A43062481084D149744E0122E144209A492100A268C1819090B0412002460D41269E3166022A490E2902C52106A883445128124DB328A0BC14802108C51B421821631E1B49144A860C0A02094A2248C3630D1062C9C12680AA24C1CC18D88124C0B4572888411C0924423408D141322042768CC046D0B972483B4411A494A912248228689C3B28904B269033600E2160D43C6450B468E8CA2884B484A4218220AA34880B665E19644C3A048A4085163446C82404921216D4CC4600CA1216136915008621945480BB58D0116219CB669C02628D9226C8B92404B140500942423239181C2444424921297054CC44400034904C691C802720218700C1252540049D9244A002805CAB080DA3065A442120C2149E3086E1199415C2812DB1465E48850150489421E0424E5D4198C0BC610E7A2C0AF89A802920E94BAD257C4A20FC3F441B15F18C12989823936F7500D9F396E7EFC1DFDE4D091C94D8274472A705C5307493D60973A7E6D1AE2DFD41172C9A1B677E4BA7D6A96CF0EF65C24EFC2F88C7AA2FBDF60C7ACF9F5D75B5313ECD9903ED84EA5553640D5DAAC7ACE3DB5D9D456D57CF61FBAC3B16E80CEECD0E7B81889A0EB73598987D3FF8CADC21477BFB83686D08642F97988AE8A115C76DB5AEA428F15836723CA2EF3A3C4CDFB40A90DF0B8CE63DEE8906916ABCAA454AE346507B7DA5138378F3CC640F7B9B6F4DDDA27561A010517037F3C4C41950F7B5C2C54F0DF192651EF0EA87AAE7406C84FA46B7438E9A75F85AE1FA95DA2171BC53A5659BD0AD135E71B7CFEB13583810C8D87F5F5D7F5DC08906BE60406369BA69745DBFE2A41349FC7BCE1822C18110B169B780AE66CDE18368316E8279F2DE020003EF92CC0C9137BA8D794C50D40876F891BDF2E588031E3AC95AABB36E1EB0CF39DE0C4E8EB7BD4486B5075C3F6D62273D3372FB22FD33B7DD8B4619AAD1638903D9115EED288ABF30B2115E65B28CA97A6106BC276C15B7394412F03251591FC74934BB646EAAF8084B53FB280199E1F944BFF4A86D7CC74D45F9D836F8245B98E2660B9C6257E15A6532797FF4B5D85C8A596C2AF154C23F938EEA0B93A4E35F54894C38C907758AA9B79E7FDC3AFBF0101A0E3707D2CE72C771A7919BDF72C2F58EB891EA62D9F6A5392DF9515205141CC7C4E0DB0B5514ACC11395613B66AEE1DA4386411E2D85EEB40063A00923691D246CA68014652CF4D0A2651494F059AEBC1C322E6EB0DA8EDFB1BC2618BA28FA3A10428199E297EC248902C2D5C671E285C4649E2D4B4E55931B62A25164DB73DBBE3A8A6F068FF054B749FC28B77BDD5DF7B033BB4B6B03B2C6770A509CE597328C17C845B6896D3FACBA71AA56CEB3503D01FB0E24038C0E635DA3E58D492EFED02263C3C537C19183E2EE3FD82CDCDD08CFB64BE10D8F4D2FF5899B8F9D5BA2505ECEBC43E705DAA8F7237B694C630D3BD0934C322002D524567770047E718F76AFE6401FE9D5AEE53535A07A7AB835177240F28624BDEA001AE4D1DC70999EC0C5D98773BDD2496AC287F819B8B2403D95D61FB9832E7BF669C6570301944F931146441A26732C2C214AB9E1C25EC6D31DA964D424DBC181DCA8AEFF5C9F475822D1F9EF07E6FBF7776F9A4F96E25A9213F43E9D03D6CEE14AA4EDE5B349EE478DBAD04D0558B0F77163E65CFE9D26969E2F90AA3B655674F8666014EC3149F8A848463A2D3553FD45724F1430D06A47A95F4C9941A436843995FBB4E86D3F7BCBE06A2B4D8B185FB98C1134B12E3738FB4A70B74C54C367C957EDF6262EB34D78465CA3E628F2AB95A37194003F9299735665EC7A5A638735BF11EB6ECD7B5769B599EA686D97092A9ECF34133656DDC4C1AF1DC0CA76BFDEDADCD447D1A1A2669DA555864B8D731535D5BB25B73542042F00D22E5CAE35C2C6903E501A48CEA7A75C9E876A2E8B6F1EBEA481BFA71CD7EC5A52DA70C3EC10032BB7CDDB16CB90E0FC09AA81A7D2DA695D96EEE71D5A686E5473D3BD96EC2764EAB767D072E8BA310BB9070BF72AB485FE905BACED609BC27AC6E847DF9271ADE7566130515734DAD6BBA77C8C38F588EA65DB5E869FD555F571034D8808D8705AF725A98F92A257117425663D976418989DC4CA503B3972A358ED6A90B49065445800F4A699EBF1E9C48A97501955FC7FCF0532B5A00B46EAA38AFF55E66BE0EE57511A62A2B2A1F8F367AB4B4F253F8637E1BDDFCF3EEB2668DBFE823643FEF6891013FAB5E8F486D3D3E510A97A8FC036B3A5C7BAB61AD50252C9C4617FE5AE6C9C735C6C20FF4185CFF4049A33CC6C254D4201CDE1417F22B31937A67A8ED41C968D548603A4373D344206524A6C172EAD2A496437D3681B6EB435BEB40C2F6DB5EC5331690D936B4E16BBABB593DFE5D823E8EB94A0379349A628C0B7F796AA85ABD28019D3FF8DFC2617FBC497DFCD3048A1DF6691636557D5F99C8DA83D954BDE8B7CF28AEEDCE8CDAEBD4E1F94F89E30EB53FC6F2C0CF30F84251C5B24CD2CE48DD590CA9EBA785F2D369B8FB92E054EB6A7EBFC7CB149EB0B6D93651A6F34544ACCD69BB40714AE401E0065A063A9786BE20E8BFDB349A9A07C211968EC237FEDC18EE6FB729A5817AC72E93B9ED4D5178399C9E7D7D5213F9C841F34B2C225AB0FF57EBF19B38144936D5AEF811921976AAFF85269B4F197797A6CC21DFCBE85BBF9068484E35257611CBFC9F6DFB808CE3F767DA0C5C0071AD3CD6E4538C0D05357B207D16B6A4C3CD433CE251BD5561268CFFC85223BA60D64B87941E0ECBE9021C07282F0E24B90CF4B26889C61C28773CEFD07AF92FDAD15483074AF6FC6E55651E473CE08FB7421F0A22397EDB4934F43862F4C2E9E5FBDD87606C0068DB2D7C56CC87613644400369A2B559209511EFE060928F8F0F9FA80AE7B9FEE5C5D96E6A4314C3CB274C140D56DF061EFEE25705A1792DD25F543470A4615EAC86ADC4D7493ECC75CBCBDA2AC4CF170DFBF709E15A4D79979531E88FA6C71052270A8D38A4EC3F9F6E0F91573FFE2094F0BB9A9E93935E14A4EE470FBD835E2C54673455FD4DD8E260CCCF45DC3E26881265C36FF3F1754C2126B857E5EF003B59100EBB4A6E2BF229E1AEC8260A5387415391006ABDFA76BC0A20756F77DF5542F4160CD0A7EB710E5121DAE6CB1F7882D7CAB20C166F6604507C3509F620B95F0C6CE7C20FC48C0B1F984B9873DC48CCA10784E3BD50EC90F5173C086505B0AA7633B721F27131F7D43981B31123E0E53582B1A56FFB01D29FF0A1841220922F2CEE0E61751ACFA55FD974B3E1B04C01D2B1D80AE56CA70019A5E4DC42780DA6973A949F197BA26066B94C6A07B6BCB07F0D358BDBB1E692B2BCAE51B48D5AADFBA793CBEE325C9FD5D498937BB25AFC2BCA00E69D06D0962654D136EC7DDB527575EB49CEF9A6D701492E9F6FD1E6A3977DDA7EAA13A844582832370A93CA00DC55FE4D19733756366B7BD021288FAC67AB985E9BAAF2BACFF23E99CB48FC2039C71941AACED3AD5567172557D2A1C324DF135E85B53A4398D165ABF22D45CE9292D6D3A6EBDA0BC4C886DFA80E8176A825033317A86517403F667881A79F2070443622D4F30F8BAB16DF733535DC1A825CCE694E1B59E839D4226DDA99F3DB362FC894868BD17BD35BA08BA240DA29D6DA8CEF984ADFBC321D51740487EA5AA13A1CD6E838473EBED93BFF889834424EC66FA3B978184BAC861B0C747683558ABD4D496177D6B7DFA3A1AC7D3B9F0554190F2AA650EF14A7737EFA46BE8F894D4ABEC0D260AB9BDCE4F256ED0F6F32E5FC0468EC982FCCE20C730FC39244975C6B84AA01E2A80822E48E3B21BE571689F3082F66A00AC75659DA0C376111FF4BFCA1977E6FC3B975FA75EA57D688F9273643EAFCC6DDB522533EDCD6CC9AD87BEE439013DCA8E7D8F31C879A02B610B403B6E2CC7595EA1828ABA4515C2A49CCD6A49E44E00256323BD623BAE01224E4760B63F1A36C3F901CB6244CB1F92F37B8B037689EB59F1792F93818C8F73BB545864760A06B0A6E8031D9A5818A58281D518142ADF7B96CF566832F5863B3C425BB48D8E32CDB86A6DACC3439FDD14B09A4A70883C3215B81CA810FD5839194363B80670B263EFECB8B4EC05D4541B02EBDB6E3F68CA7CE2761EBBC5C0FC8E7A8C19332B3473153D52439B7367FB121178AD1BE8E69C416F782E2D30C7E091E6999EE843D8672A0166C4423898DEF93CC8693F22EA645BB8DE5C9A2B0367E2EFEA6D1C3279FC44C64E34F784239566D75B38ED1F1044F4891010F66EE6F9F71C6EB2FA12691DF5672BD2D56A3F26351A93CA6FA179B00FA45AC24ABFDDBD47E2D8E30392457318CE9D0199091C1CAB1EA0E86A9AFA0B3F8E164109ED8DC3FCE62348767C6748F0A0054959EA99BD07F802AA15DFAB905A5657503663862C08167D8EB16DB0DB8FF6222268EF1BD6B36829BB23063A50BEBA7F1AE7D9ECFD3F16DBB03C52EF038B971D80FA6D00A53ED2CAB0209A980F3408FFC94AB11EC7FF89D08BBC2F213262CC416E999F64757BC3BD32CAC72FD0BDB6FB14F01F4674CD800394163C058E5283B1E7266772534A58E1AF5555A1583E89A0528DCFB6731809C4F8AE8F882F0BF5DAEAE416535902A5C51D6EEB7F4850211E3D2DD8A273222CC81AB4E92D9BDD07F85AE0476D936570981128962A33B7E77203B27830CB0D9C27AB41A2A6D4901A935FC41C4D57E213F207F00556B20771564F1151F7B3D0680CB80575C90D49F4E67FBBD24B5042A08DE7EC037533E95191845111B79187CF7F532ABE616CBD6A0B3C162E00778F56B5842E501F56DD9F22F8DEB07C2F6A53002F5AB883E615C4236E05B3AEA9B41BB4CB620AEBECA39D1A5DD7CAA64E8B4D321CDB918328F97CB8741B2322E06A3BAFE23B4110516880CB54ACE7104AF2C2BB9269987AE7D3AF337AA58105711DB2B44074BB33E67DE79C2871C3300588D5F3FF5DBD337E08FC30DE72E33D2FE6026C8F62F7DC40DD6B82FBA1FAA3FC0CA80C299F3A61CDD866A6D1B59AB40E4A44E42938546AD5BF47DD1DBAE68ADC1CEF24B7C1FC4BCFCF13C54EF", - "message": "73D988FA53D40EBA2286EFEEF43BCF96E20FD6923B7B5EF968C6F670682C90DFCA92E24B0E9420FBE91A9460075AF3952623C77D77E4795525978E73CFF8D4B7E6F648E8D1F5B9A98C4E76B5D18490F73AC5693DE377D5137AB341C73EAD4960CF66E497522E5B8F60ABF44DF7F409665FCD211959A41DCB8E9B162C841A55819B6EAADAEAEFC55CDFC2E1004264AE91E0C6E2932EE5CF7940CE87178A3B5142AB36B1A685E92C416150FF291E5D9915B2A068D65C00B74D152FC4163126ACDEEBFF5EDB796131489C3E94E633E4A905E5B83E361A3D420A122B07B731C980F537320EC8627FCEF0D782149E0ACA781DE7F6E0B11CE311F9C7C15B485208CAB1DD9FB0AB0291FBC56A5B1A2B370ACB6D735ABFFC7A5E95E7DE10595E44384BF1AD4BA9D637EC77A7F25A10B2CBEF09211FA0809EFA78FC8776E8977938EE207A0DE51A412BEB0DF4F8BA7577E50BCF768A914C64B359D7C88CD4C145E06F6168D1F5BD9B6594B26C0433F7D141895B372D78E99956F16FCA8080D5DD571227EF8BB6004143FDEE732AA2562324584961B11958075FEC1FD13601985307DC0E5B561B298AEA0D518680488675C3A6CC19D3DCBA666E7E0BB541EB4E94836EBCB01719C9F0721D3E6C7FC6866AA260BD85951CC1C48D2675200B9BA72979D04C06B328D5802B613695A0478CE39E1651E814C764D0746FD9ED9AF551A8B3DFB30BA92581F449D14DFAEC363466140F155D445A082CDCF62B341C1E52785B23CCD4ADA0F2B47495431CF440C6A0A4F50CEC6EADCB7FB360AC9CD9F5898CEE413BB3D7D85B20FC830B0FDABC8D8892052AA6AB40BA96D6A4AD09C1EF387FA51DD981C959A6CF9CB72D2844A12361696E8C12752FAAC7C3040C7DA8F8D82AAC50B1FD1DF6F71E18A0D655087D9BE32156019919E4D0571BF778C078BE70720D36A6E08445B86B08A5F74586C5BE3CC5843C196BE56052303643D562FFC40FE65C1BC7B960675D6F6C7F7937008D5FCCDAC03CCD56CF28FE6041ECA327D8871F2E4614248B1785C10A6F3A0E5FB27123E6FD3A87E33D2C714053D0E62967DFA78DD9E972B145CA1547200B834169523027160B067F15F818B8C56A562CCDE215F37B77B1E39939F104B99DDC56E537ABAAFDB40B7DD223058ACD0CEB37CECFE4FC61697814FC2DDC2288D9A21B82E5C5B0A225FBB2DE775CF48BAD11755C7ADE5CB85E3BAAE74DCFF866EAF52F179137DE8247B2AD2B9D5B9D136061CB26420D7E09BAACBAC447F854D2264F39157054ED7937B869F8E7166419FFF1E0A1A11FB5240AA06C7EB0163AB1AA944101749D0540026D45F83188A9262A6BDA81A9FE666851AEB27695EFE67DB19B81913C8F84D97389A0088707D3BC16016D9793EB4C2B257E90F97779CAA275CDFF0444C02798026D6DF62A8CE7E1A729F060925B4AB0A0C55164278747E180CA946FE87AE50661FFF3DD9CECF176E3B880BE5A4A6D093CE87F2AC68998F54B0AE21C02CB9A28E74AAAFF6587991FF018EEBF7D92EB62E7973A83A2CD510CFF5865360CE28ED278FD5146AD54A1776B22F81896974EB140EEFE919D12253891585307FF0541E9308457CB432B51E629D895C806E264525F653B4DCBBF56CFC99572FE3ACA5001EAFEFBFAEAAE167B3CCA51F3E2EFCD03568DD14F062CE72C7F417A5AA78DB07ACC77B8D4E6BBE031B4427AB3EBD51144EF1A8CEA451C79A3D2E1B6CAE0CABEB67D3DC9F333BD1DE278176B80CFBA0E350C5B2566442EB8956BEC91049E584920C24A6DFA0A1D9F1480D019FEB1E58F63E6542329EB8000EA37D411D3D19EB391151D655E1DF4892F8410E74519F0697DBF62A252EA5E3E28A88BEE944D2424671632EE1B624EC688A60E8829A9A97526695FF7F605C9C30339C8ADE37D303D0D3A90EF8E16D3DDB758A81BAE6278F0566F6BC58B325FF705C104EE40051E31C2BCEAA19A00E4912EEA2955FDCE84072808B302AEF2FAF8DC2AEF73A801C7E1ADA6EA336AA0F909711AB8852A3B22F434ACF008E7CCD7ACEF5542930956ACE670549020C3B9B419109ACE869FE94D1EBEF9CA54E838353EC6AEEC1EB90AA440A0586F775AE0EEFF00D8401D0A9D5BDC73FC9EAD974D3EDFCCEA00B2B8B5F251B7D923FBC5C01B5CA761A227170229C660A5D3AB5B5B1AC4533438753D9560A3FF581F3364BC8146A8F909B112921405603D471958F1A9D60D88B74707C355B112B4B92C078904A8BE2B9D0432274C0A7C403992467357B88426BD6964407246FE3CD95F9C914599D08E8CAFAA2DFDCAF11B88790A53EDEC1355BD4C22D5364BDB48322FF23E2505B943E6345F6B0E4172DF3E9A8C4D8E306CCB9DC296FFDDB7C2EB1AB96F6FAA2FB514C698845AB7B018534BFF8CF837F601A19F9C6DDB1A80DC6A8E161B2695BEDFCB92C34390D20C680A9EB080B922500236DF042E89FA48D80A2956661FBBB603CBB9AE483A2DE1A6CD266824F28B06C1F436D7DC998A9879DBFE707278D98E73C2A30BBFE344390EBC9DB8227423D67A9BCF40AE2E78A6D778928D733B9E448649DC48C906A29034E406554061110C6871AC10BD60D7500A6C116174781D1512DD1A34818C4827AC8CA0857F8313E8DA07059151B022A17D5DD4112D4E1CD46A85D8534AEC136D02FDC1DF0255ADDF7E3EB0914D889BEB31652094FA4B246E6BA3DB2D6291278A985319EC9C53079EF2CE5C52BD887845B23BE47277ACC11CE95D3209F4A0AEDA916D19C5CD4D2615D79840BB670ECC9DACCFCD106CB9F8B218E739C268DE37338AC4608A252414804B502B705ED90423209BE82BD4389FF2F73FEAE2CE726603089F956B31ED3895FAA1480BABF0F103C90835CFE23FD21F3092775EB90E22945CD66150DDCD2B556ACB6AA657D0846F9EA4F0F007C2DA69EF72395D43A3606548A0DB30608FA8BAF83C92BDA9C19169F0BA0219736A353807C1E085872392FD881468E93A7529A0BE645B3CFBE12ACFF8C081D5A0E879B18A15A58930661E53798D9ED4908A2A7190A202ED1BBF4EAC4A10ECA6770B8A27E8F97365E6BA42C05176FC498D75DFE467F8E12B0F62AAFD7B8C43732770CA75D72C4A706E916A71CD114FC6BDC9388E831316418061533369E1F7512B10D2A13CB912C60463F77D3A628D639514DF72DD6F83FA11072EEAF34ED3650FA5D45A75E5DA9C3B16FE070E2848AF4B47823D4706F6006B488717564EDC036A05A58211D9AA17512778D46FEF42981E8438CF523D6BB427E63320FD2CC4B3EA6EF650C067348416D47BB3BA1EE69F6884441A01C771605666EA465DC1EBCDDB33F3558EAB1D639F3A97C39EC21B122C90E1E9F99FE6DDC484FCDECAD4BEAE971976D530122F496D3EBAE8A535E45244B51A1B6F83E651092368BEF58BA15A223CF982155FC747AC506DE0F1EF012C42F1696C2EE1EA909C8B35F859DC9ADB1EACD8A7622744AE2149FC5A1482DD3E1CC29A9066C006FBE35BA9590EE990A9AB8163CF2E1EEFDC81D02D35DCCEEC46E544E1EA85465C817B07C55203C57F4E7ED92800C8C383FDAC1FD6C2428202A9ADAD1F8D370E82D3822B92B11B9CFC57936FB7DF779AF305D219F80719DEAD0EB9E0EE001D12BE36B8A09BBCC85516A527EFA1F091BB8A9CAD3CA0F6443A731DE85B07324224473560489B0236A141720F3D428DFC966AC013302464471E7F53A2D25E0AC826E3697D9E86FB7C9DCDD2A1E815C48D16F04666CF58258DC4D3E644179F0373E35A2501CFA3ECDCD0906B56B1291B05C36B41D6D1EE234BE539218B63CB0D082384CB031B87F958C61854F2A40BC6E65F491025A827F7AF5E4089C9FCB2F524830F61780F7A4FD390E9FDC99D818C6E021D3E58F0901885FCDB7E6A5A8942C3E2F2743079C9039DA200B5C0ACF48ADCABE3523E76D717F740DB411318F1D445AAAABE275E3752555BB42F078758613EEE965C2ECFEC6EA01AD267CC1E5F52D2083D190E3379730712212BE47831C9A7A860726AC4DC82C4B8F1A1D13F65778799A8385100099F6101200B52B02692BBA3A63295E6EC7A418E1917D2DA74281E74DC0B0BEC6D4EDAF559573E1E11DDD0C47C456783EB63A5B325BE4FE495BA585F29638EF65637E90EB68049912E664C69FB6795CC8848D76B026123565D9076A2E86C855E46CB2B1112F0CCC2CEA8154915AC740B5D41CCAFC1D5C28249FBFE8243183943B061157073F30D54F79840C5E46C525C13BABB22B035C05C3C9E051F44C45B0F6DF9B6670987C618637CE48132FF204E1B43469F27A73D66C91FF8390C71D1DC1A73C404BA6D9F5959E2", - "rnd": "706E732161AE0909F0DC9EA67C78B2102557DE18010DF12C9FB5BA9BED9819E7", - "signature": "236B770A82EDE02449A455C5FEF6EEA16D9E3CF5A78240945462CE0A0404FC1A23D9E499F7D654A5D34B9ADE3CA0902EA0EE7297E795E956218491280915329C2CF8AA9F69872213ACFC0DBE674A490F9E2D999E875FCEAF88D80EF1571ED90CC3BA7824F71DF567447AB15821C0A8EF6AE03673FFD11E2B35010364DEF5D084895B76BE2FFC8171074FBDEDA6B0B2D95EB56EF7915CA85AEDB0ED4DCFF10185A7CB099FDED19A2F4EF7C8929776C7549AA765E22A3E30D3C185A4E48B5B7F12BA2221DB96517CD0EB7216EAEF8AF51EB193C077ACE562CD6F7B0F2E212D309C7F37296E96D9BC8AFF71C4959A875BD291B55BDE785EC3C8FD35A07B42249FAF729C2279B506B3473F4F50B10D538507C0C7DCF5B543EC871AC68955B4947570D570B4B39DE614708DC014478D7DAC07545E9794EFA3817B7A68A94B9246F0049786FB8C340B600987112A36430E7D1553939170C413CA6CCE66626108ABECCC81490EF9C7CAAA40FE6A60C2EA3871E8B436ECE929585FCB5ECAF5E4A872B52D802FD821276EE0F14839AAFC30EAAE416DCD6F819ECF95D640D903D0A9B05CC5FA51CC3A5773DF9789F4633D8E61E2FF83ADEEC644D230D1D34F11A92FCDCD9885BF6A1FB2360A6B4445342B9665FD3FE51759E14FE029F485DE6CC069986E9871B167651FDF0D0DAA23493797E61A4BAD6F039512D87E21F03659776EEEC28C79FB8E2366270A205883BEE683546CCE32172591DB6E34EA5BE155BDE40C3D13FC054F622CFF4B46AA9D84F5E7B9C4C2FFF27DA2E36ECE7427191A40C35A9D69E2D57A1ABD730AA61D12AF2D862A7AB632FE552AF70F905597BF689AE821F3A271B2F1FE5335A5A05B8F16FE131AD401934B107DD13A108E397AC07AE3C369E131B9DA8AAF18288C0BAB74B721EB84F71007DFC4C14ECAD88CB29D849726BD7F7117AD142F1AE9C6AE5B63BB316BBE5F6655CB7E05CDD86B1DBD4253C1A6422D7256CF32CD0CBC9F30500E964F07DB7EA2CC5AC7D8807D313F6EFCD6DA44D3E41B3F8112E5B1E0EEC5ED3A995C77CD43877BAD85EEC96CCC9F8DF50F5BF94BE00AF0CCADE2270D4FD7A844979FBC3C9BF9B3890E051F1C13BBC02E94C44B4601DEC5733DE32DB9947CDFB4F04B9CA3867A8C4C96AB5B1C6AC84BCB268216EEE46599FE6700608724EB7AFA7A95B8D487FA253D5958CDC44ADCF1D813377491753BFBA628DB2C3B04C2C45659863A3C7B5C11E86B5BC77BFD3C79D4D4F184B3B1CD3CF5958D19BE3C2BC2846C8807E07B05315B39BAB840C8F49A19C97F73460AE1D2415C05EEDFB32986B5567B39E66905C5D9558FC739C6DD2FCCFD5132C3EF2C2A765E43E720B6D54294712DDE87746964908924AAE29B58CD6B8E15166AFC4B40463F44A64D662DF03AE020157ACD344B6F45EB95A7C82F662AB711A03698B6B102A756DDEB2F81C43AD5D3C4B897C1EA15690DD28891B0BEECE56796675D0A1BE5F1530C0F7445C690CB693FF30F815BB6CEBAC8855A4B597B8AC9E3794AE090A776E38DF28D342F04D96C7849E6ED488781928DF0E1729827ACBD4C89DEC4F7752F68B0DF925956D6DA8F50AE9025BCFF574BF60916F3B552089B520F35199AE5122E4D57B03D5637217E42371DDD017EF3E376CE4B9B80E37C7790C28F2385778E79BE816025671AAC39BAC1A6ED7F28901DCD639A2213DE75540A2BF48FA5B3067C64ACB21EDE5D2B35129061ECCEB899E7ED58A7BAD11229E3A507B9E2A17FB0F13D7EA938A05BCFB1046CD7167C9D1CD022251CCE25658DB7A6CC1F20A3A0B5F40415649DC98E80BBC898D1172F1B5D1EB38C3F1D9AAD089863650284A5B886F225B479A27D0FE1E2C1461A3EDF10B1A9CFA4C390B698C44852AF82338589AB0ABCF9376C8C280397B33AD3ACAE81CF2CE76D5D7FE07ED3BEA6820676968F95EB7D26FFB9A2B2C254E0AB3A106538B4BBDD4BA5CE8DE7AE355424395961507A684A6960D4381497336E15C886EAB8BC79D7CC405276B92BEBE88B01D8EF4B5A1973BA1FE74812D0611451EF0232DEB5AC30EED0E81E2667DB4CBE29787A73BAED8181E6D09BABAE9E4B6992BEFA8CCF5FB75867ACE8BD91788350EB0122093049A677A8B74317CC9F9B9DAD51310732AA33E610E2F39F359A389DAD02CDECFD4303299BA6DD8C8003AC6026F26A3B7CC1E29FAFACBCAD60A0752C15930906532A74F9342BA655580186656E5774174E47DBB205061C66CF69A9E08A6C76517A95FB52179ACD225D132A48CBA945452BDBAFD90E3FC6D28A3C04F05D64D5B4BC5ECDD56F8F556C12EE7562F043BDDE9235EBB8BD53EDF8FF20E568C3D8ECACB7613BF3990776AC925B93B92231DABE18E59B92177912EE3EB533883F28484554D8ADD89A34C785A8C3F23E284EB0CCF327FE620D88DC552CEC4AA6EBC98ACDA945A64988AC1E12EA8FA1F6CC6906D6523EF8077D23AD02C4162A2859C4727A97FFB63DBF6C8D7BB83C39516CD2A17E83F27AF6674C254CF1DEDC7051A2B7472AAD54080E247569712B519DCABE55E82325291CDD9A4648633A66381E70AB0F7B65557307506CD404FBCE9F8C137DFE328F178DB36267CD357A69EDE4D711A9A0199E17C87A200BCAD16D745EBE617FC11F64CCA396ACACE56AEA83051FD298856428BA47854306C804911D2779E8C6FACD6680808698C2E57759D92A296610F5F46A05BBDD44FA5D21136EF31063A9CF9BE7EA0BA61881E8ED6C72EB69E70C7741696C67273B0B2036C5C25BA5DFE3641786F5CE0E35D77195718CB31C8AF1D79907DC35690E9BD7909B8C8873FE2B4FAD75E9BFC91C4C9F3764B9927341010C07E7AB2B0695B998D0E696D936F494E3618BAD52B5994E44C051E0268AB16C17DE391951DFFAB6FA17BB8603B65B30B21A6D8337347D0E5DB460A594716A2D354CC36A38EB8936C80074FCAAF0E1370DB499EEBD31072F1344E259D6CA2C4F25759526909FCEC8F3BBC5685C06CDF08F3678784FCE3C5026219AF2EB4BBCD6264620B556F70A839992900CD89611381025724B0A1D4D9DE9F2032959F3554504CD1BB116EC73E93924B3774CA7467CCBBD415287A13CB82F286C4E3B60F15FB6C6BD5A11B036504083A3BCFD7ADC916994EE921B0A15931EA1DD216529D4A9149BEF3BFB3E5F531BAB3C7C6653D0F9D431D0EC9835C6736A8596ED756530923C362D246D83D03DA6BAB711601CA15FB4447BD357B6F2095D7607C17FB57EC31F9D9113F0FFD59E79C5BB59F0FDE20647F5AB4B59A0E7C9BDB51262B68C9E5B39D893685BF868A942BBAE2869812D1BC61AB2A93210F0F37ADEB6E8F721AB20FDDF8F74CD94574F146204782F2AB3069681D93428C437092780549E9A7DFE4710EBBF3E62FAC75D15617B5E66CE92A8CEADE4A90D29CF7A750AE8EA9060CDE98DF39A7E933F5E1FB636C7F56F5F5ED7B4282E62A5ED04720E76405CE7185F200EAA6FFD83E58C8347A307277F4E77BE7C407A82BC5D769B744F0088D1ACFB3916E86F01191101EDAB8E5F155CCD9EDE85737F15A3EDEC7960D9E5B5A1BA530B078CF005001CF6B1D441254248BA747F88775D274CF05053526C65341C6203E2B475A6A5C6FFAFD07542EEC8A38FF3C8521F9F59345CDC2DB4455AA21382F14E2D244C5D43E6C2069C088F31C337D0D24361C0229463E0A42667B19DF96745AE52EFFF3B64F7F63B1CDBECA36582E1A24EE5C940CAEA1EFEE35F0E9022821B9F782A237308B32B44D2184E5670A7AFCDF0EA4CA0FD4717DAFAEE48848F12447C0EF9034E5D0D877A70D9CA133CBA00EAF76A7F786B343F9CCF131085EDBF30F4E13F208E60F78E1DE15D4585F88550E407D9904875882F3E10485AE12DB0926F59C5D54D44C17EBF4B7CA711B6D3F0B7744D75B083BF9A0E4ACF36CF65C5B4EE82393013A3DFFD8F58E8B20FFF4E3A2A598F24E28C4203ABA8980BCDFA0F45D819B11129C192A1B2063BF3111332925144BD1FA37168B3ACFC86F11726BDAF4BEA757162FB077567B71FB7B9D67FE655A5149656271413DFB0C51548A00388556090606DF5EDBE06AE344149128701688F42D1201B33AA4CC1B209D7838DDF0D94E747A0FDCD0086742CC4412F8AD43AC2DC73DE841FEC9753733E1209FA60BE760F8646CE29743C3A400BF3310774A94E271249BA5DA22DF7E7AACB9768CF6BCF8D0471FE4980E460E968597976D0B3F990098014758F67E2F2410ED15EBD596115DF1124C5C782880E82F57077D0DE64A214D10BF9883B6CE4F43550E395832612B639F13168105010B52BB64871157CE78205B8952013B94C339711F70F9276110BC3391CFE0C112EBF1FB020CB8F366E0C017AE557F72F2166D823F5CB6D7C4DA26E9798385240C8D9A801313C7757B924511CD4140F0483BA6C0F71A04C4486C2135DF377B7562868EE0EBAF13AD34CEE1B9D836DC7708B82FF6E5BA520C558649EB2121ACABB393868FC585857F69E5356F28EA5743928B5B22F06F497164A9DD0EC2275FC16EAA261B4D23D5EA18B2512D0288BB1FF3D09B73435BCC9CF63A6414D00C1B3987F3C4A272D49F1971897E13EA3FA0ADA3A1665C357A24AF3D818B2E25450CE5D0685153EC6FF3764448F66167D60D1E09F83ED9A9F2EDBB986DD79BEF8EB636D8DD6D618B76E1CD9F56CA7FB15BFC8706B18C0FD48C96358E2C8A7AF0631C7530891D45483A1C78BC5868F949C24DBCF08E500A85E96976EFCC72E1C80C8EF09D2B1B953C14A0798B7D58FCD0F0CAAB1F5665E2C3A2A2561D2E64E6BB9109FEB037F9B48BEE0B015D7366F3B5262511D46FCC2AD1986D8356EB41AD954796BD1D65F39E1A789058800138B32106A5C503B463664CFCB7A62A26B7ACD8C798DF3E0B7CB31EABDD6FD48CBA6F2E4250AAA1B0FA3DB77E9CC93B150E93457B29B6F7087912CD77AEF45ACCB1FBF22010DBFE40AAC1D64999DBE6563A5CC1CE47E133BA2F147EA637DF7CAD0BA9FD7AE7B71BB61D9CA42BB6A933B355C94D1DBE4BF4D335F501FB8CBE8CF9B0D38B8A1A8A656C024C58D7EE7D5BE50EF4E40E8DB9E34740B4697E35387BAF78733DEB8F53E15B9F1E0E7D078C76615B344DF6772B8CA61EDF2946667D1F32141C194743EA1A32390610980E9A4B1A47B026F9BF64A42098B4EAF9EE5EABFC6A44D555CC261E4F9C46EEEC3166BB15EA5FC0673F9B588C09EA98494440807FFEC724A90B9CD37B0740B5C48625CC12BC0D0E90474F8748EF7CF71E00BBCE6FAB65564F0555855946434DDC70AA85441DBD669D5EFFD790DA8322E57F0AC63755422C050BD9BC87AF2413DE495CD656A2E7E7F16377DEFF67FD05C610806D19E4BDB8A7E077A85A8AA480867315B380CFA2F5384B81C44517F748599CD85789C370526C1BEAD42A721608DB620DDD5B101DB988C900CA7FD93AB973BEFD69D79D90797484A95851AB2381629D924C12ECA441F7E973AD819956F2C403E6C67FDD23605CF8F59C7BA36695F04FA474DCD2A1CEF2008306665DA1E41810047120347855EA0525420CBD387DFE44C62C56F139E22C52A95888746443B3B7F1D0A2D58E087563A1BFCC84CF7742610E9CE8C01DE1C41BBD0645E39C7DD7DEC04082A22176A205FF5C37C1DDA038F8C29367E19061295CFD0E59E4484F3786CC793FA3EDB92E4D873434A9523DB3B225919C2E7C8B9D135F39E0330B9E9728C58C993A23AF111A79FDDDAE33295FB1CF75BD618D87CE76DCF28A86106B663111E54A3DC4D60A3FCCFCA85617907F1536D82F678DCF8E604E55D95381C4330DC1FBEF01CB40486B34DF88B5592C7A8C7BA31998D354E4174A5E6E35ECFEBB7C40DD4C85B8671EBAFCB4085F69C1DDC9A620976B71B8CFF203C9B29A72D25E965A46DA99017CE894281264E206F42132B52DBD7C63DF063E6E2AA7BF9C286762A60DD8D839B9BA332D536762E246B50A195102999DED71A7D9A20C31A592CC92F5CF8C705EECA1F9FF488FC442688B427C10427905C24542C491A7EF16ECF3AEF18D9C813F4A13E7413157822E3087FC8CAB2CABF84AE5F8F34C7B69CE5BC9824B88E595AA2E6D3EC7965A5BDC18F12F48D9BEBFFEACDF8296AF282505859A788942C456429A7EF15E63801C13EFC16A67C0CB7CC39A06AD53AF77A1D6A84C2B86D7F30B01D3BE34C8AF522F7D2355C19987C93786F92F32641F524A0275BF6B1C556D2F83DF47D2E307D1D22E73BB3C2D91CD5E8B67618DB023B78B38887DE67238E49C3C76FBC1F8B65999BDD299B33ADEADE0A6E1BD9965E97730F4C83B29CD289BB0160BD57343792F513E026A1FD527E530E9BFC84A184C340D10121F953C3E2A0AF2E95E6F335641C16C2402D1C0A799F54E061072C11B4540FBD0F77002A52C62971BAE38A9A3AA85867181D2438497388DDE1FB061A358B7480D90311565779B0FA8AA5CF747C7FC3F00B2428536E76B60B17464EA0A1CFD3D80000000000000000000000000000000000000000000000000000000A0E11181B202730" - }, - { - "tcId": 57, - "deferred": false, - "sk": "1718BD673CCA459C0C1E3E4B3DEAF8F07873B62AC10EF3863B76D57A52BE23E6AD8E5CA42E914633F9974ABDFFBD666778235CF1C9CB28170BE6B9E4FC27EB647B2B7AF5FC370DB2E54F69C984022D0D5D6070F3B52C137A492EEA0F0414A4DD24F0187B8937EB064CE899492DB2D1D24C14C8F821624EA7F25F1EC2B01EC06A0C9580041280D0320949428562B66099282408B72818252D1B250C62068AC92201DAB628D2B40C82B001C9160109C62561122E10266CD9B62184321124012D1BC08C01496C9BA0840AB93113396814C90542A288413841C926490010841199208188689010445A124091B0881446891A10451C136613163262006A4B1812C9A06C83060521A1410340658AB8292481498C4626D3C82819066800196809B901A0382189A404E4C66950C00C200426C44681041992A43228803609201420038470D94026C1388502A3051C250A213321D83044204411118290C034095C36200C282C2449208990004CB46549B288DA982D919248081545A2285121A98500896510222992386812922822A9090B838D5B1852E0946411976C40808541184103088119A5800224900AB800C1324914C885112451D2B2201B32615A248A2247290BB82813312560B82112C589D3B4101B374CD1C20C5B384E92408121978902C7241A138280064AD4806C6006300BB24103122042160563466458B024C2244A9448120249080408220300268A14290B33000A25120A310210C20C880046C942860BC62D93100C14286CD84072C43280A316529CC66DA1225200B78992160C902680839244811649222701C4124CC0062E41846DA1386E44264A1249440183284040651BA02C14416CA1207113242D400406111671D2964D13069052422019B390DA26120C267252366DA1A05112A2001A2869091891DAB411D3B68411B2415112515AC06CC216821009468B026849B2659AC04552406A23B82D4AC009C8428E420882E22468C8084A103150A2340D0CC95189C4611293289B022823A4051A4988543630E4348E591631DA308E1A016400C46860B8601AB151D4B64D0A298A61B62CC9422893420061B280D182510BC2409A326A1B354E1246115C9070E3B24D8A2231C9B028841812028144D9A6640B4180112820D2007288B24C09974448B6005B18309A040509002EA2B68CC91406483064893812E1164E80080E21176DA4B06C142651D0B06D21428883085112C7449A924488C64118176410B48CD3208DDC10119C186444088A03C38DCA0866D0283214C20102429004198602920C424865E026921C154DA014016488100C03928BB80CA3000AD3326EA0246DD3262504C3480B3688D934015C868114076CC2243213C951622820C3A60008410A21C84D0AB21018292802471214108221468803230060C82D94425100901009C2641C430D5C963141929042186823C5291810520CA62051A4295B042209C18940321062324113078C9B92890A331153183108054DA3968808362DCB1061C3226C113902D0888D41040503C888A3A850C1964823830913288C0A838D1A4806D3C62544C64C40302209060809234418008A5B302E084052D8281140402112382EC014901C043009474158122A1B44260A20900C057193902D4928410C84689C007208C98462902D4906668A284C020190024706D1906461904CCA0864DB12681B8248DA3048A1027254065044B870A0488890B2250C492620892D5A806D12186AC8202EC9320AE14210629440E4144059A20CCAC8919A88715C26129A18690CA7480A398250C20950C46523A3400283041141441023259A286109270A98940D53C431123280E01446D424291B204912A42D61806D09B75004212C20C320222206C89644A03609533892004391543221A01244A240884A000AA33212230711DBA22543284C21904409C34880308E92364284C44D0A2629C9308D5A28696004090281508BB008D12084E01805519430D08060E4B21181B231CB922C9C484544C44CC11688903244413688D40801C0020084481112A28064C445A3386A21B590A2826964A6902297048198118BA62543322E11A74090822904B84CCAC4906386649246659880290C464D4C422E1C018211400D8C00810C89842201228A326CA48865C8467163A225182470C126614214655C8071D8464110A56180C624E1346523A14884266A0288482E67F57FCDA8BE49745E2940134FBEFC906E4FACF23F089C467CB95505F5D0EA92D3B81D507F513870E2CB01ECC2CC49D0E174DA78033445D4BBC403CE3D8E994ABACECAA4EAF3827C089F6FE8874D32B9D0F123973CA0B090E1CD16CB8EB6B5E95D1FCC4AC0A6D2386E37B2BB8AF07558AB52908280FB8440C8F36F85476252E8BFA1FD23E00B399FE13EC2EEC784A23801B41263A94D945C5B336244FFBF37424E60480B34BF732BBD37881A6DA29349904E9D89D66C1661E69A8421AF8395EBEB9C924AABF6E09425954A86AFDA3A0DAA2FAE51C25E288CD90669F952932D720031D41EED8AD35238843317A543AF0BE6CDC613CF64A04E062B1D25B17B68546D359B303CF0698B32B4A8CC5876825AB6F38A0C05CC7D0A12379C0836857F0E3400F4D3DAAC8A0706BBDFC1B6282D0536CF453C225586C6A3F673754941DAD661D1B395394BF98FD195D77AF9E64EBC40B2BA1A793A27E1A83E834E6B64166834EA7126D20EA1EC7ABC63645B3B57690E9205B31453B5E8BFA56036DB365DE2DE666003CE318B011B4DAC8A5D0ED264826D793817B368597B0829AD03379D462DC9D930946579D79533FE6354CD3E0D6D88595A2B525447EAC920B6614CBD9FF23E8593A81528CACF2F4FA730D985A2A26803483255F0671B506ECF086D8407BE3397E4E18D7D360B5A16A532F75215F3B45215CC1096FF8F6963B73CF9BEAF8A2A245AA5D7433C07BD04033D0A60912C52D79BCF651C3E3D5E898F73BA91825B3622C81F9D6593D1B34769B34A4D07AB2E26C455434DD70529BB5DA7A19E7C7872D5C558B1A755D59330D53344732AB03B330A71114AA22BB1CF9B1BABB10BABB8E317A9ED4D7F205E19010037B3A2D19B7E2E7BBBEA3D683AB0E5B66461C23C8F1A21066DA231A5BDF8842F867654FD6EEE50489670B7EE538E6C8596C0BDED51B2324AC33890B421FF31C5C6C1DA8F19E42188FEE8BDE4F8B68E7884EA646761DA3D653FE36068D08DD34A2FC0D6BBE39FE62A2689446CD7FE3F814C504F937CAA3F9C02D1DDC183D79751036BAEA4572C310B4F86F2766D71D050156623F78B40E47A48C995095D52CBE17F3F3AA23990F5A3787329C4E6BDEF606008EE95E4D4672D3C06425F959A02F97D8D42B3A0829E6044E1881F43357EB1298F69CAC5F574AB387E702EAFF35887ADFD2D6D70DE86F636DED31808571E456458B535DC7C89A1FBA607233D42AF01F6AC31AC3191BCE2426456CA9476C832DBF1B82F3CD7A367B8E4AA90CA1886D49865D76C6B09EFC788753D9E7DAC35AED2A459F9F71FD07DA1F9D17BE8278D51F185C82B702A2AFFDE2CEEC0BF97A3926833470D9E230F24C200FFB5D467F28A002B401DB07084DA658DBF19C60C53B61AA24330FA17CF60358E151555DDA6B5F053389724DBA5EE5041C6FEB7EB4F1D9A0A7E55A488A95BA809F0292EB3C96B06B8795DB645CAD085FFE9D8AF6CD17636C1AA897A657EB4F3D3F81024F83FFD7480BDEEA4E85C4ADD22357A4322EC55289FE4CDDCBC4373926231DEA7F0919E6A52F04666C0A1C2F5FBB457826A12AFBB6EEE07F5CF920062D54CED0179E7ABB79BBD53C2CDC69BBAAB8434A58216E22169C41446401759A602865CFD7DB34230D981EC4174736AE13DD36709B1F0D6FA84D523735AD4005647D8A190D8C5BFA8ECCF3705CD07399ECB638F2B868ADBE5BC31DF3565962C62CE3D48F45AAE701C8BAC0C4BFCF757CF9DAE1A6DA8A977A3815D7155DF0074FFEB54DF36C736A1CAD9CFB3EF56188943C3C709AA2B5693294708A988EC4F0D3EC87F53B433079EA5E81C4AD6DE29B73A8C88768EFC9309E08C0CC2ED37433A5C9DE2DE6F1AE6D24F220FAFEB6D9961FB269CABD025314AC0A94383FE093556C13821078345A8851A96A93779872575CC1290720C39CBB3C7571A940978A9ECC9586F6A465FECAD6813834F615826590E85201773D0E62FBC06CB94EF9ED89889A9F78122109508704054F31483CDAB9DD70E03AB3515E0A4EE529E0AD8ABD2051FD454C3ED1824CAD852ABA3EEC0189C5C8FEB2588932081E91533EB2E5ECE63481BF9BA06304F4938476D99DEF5E3011674E4E6C71F8DA376C528210E6A27359AFC1513FB6CD27AFC89731A0CC71C2E59F5C11BE669F6CE13D6D7EA6783FE8518B39C1CBB77E2EEC810A1742B4C64FEC4D285AFC6C2078AACDED5BC911F365270F10C9AAE5BD6A4A2F430C92D2B55E02BEBDF02C99BF92187353297212209A24430CB74D6FAA5BB9CBA74E88033E68A6E3B47D35925DA8A7B2F46B16FAB19F96A660CF59471952932FEDD3F3E4F39BE194F0D50B435F29CD102F6292EA6C13B118D59596859CE06D476B37F192B07F42A6DE274F197FAD16251810AAEB2C98B8E2ABB3D33957392E436341BF20037DAA2073412FF748EBF54EDA9580C3816A5F732D0CF9F61F58D0F93DAAB636B67D2AE3D70D57773C66B488B717CC5A9C901AB34ED8F5E6ECA7928C2F49E296CAFC9AF0D7A8AAC7DADA151F76EC8888F82515039D455C021DE319F548298EA7836F568A434DFA0BEF58979517F296F2A3CAFC5A1E60E3BFBD708A9D7667EC9173C4118410A75969518AC6F16B228CE2D36DF47F8E17A9501FA7E62F3A8531D9B1B5F5C43A978D2958682E23FE7BF9D4629748768320882A5DEBAA13424A1A793E63114B625C01775AF43B4225E9231A14360C55DF6B70A867A43F80995AE586F7739B8E0D6DC4B59595A8B58641E040F30131832858047A898F62558F2197B9769739A695927DEFECA3C5CDDC3D561C25BB3DBDCD6D6D4EBB7D5AC42B15D5201E7762BEE43D3618569D48B88DA5E58382197F5B76FAA1D3B5F1A2B4779F869AD59BED735608C13DC447238D5D5B985369053130DBBB345E4B488CE9629FFE839B94B50FA6CF7646961E8FA660331645D878B2297ED01BE3EC0A5AC56F488773444867C4DA671BEAEFEF971B0A6F406CC2CF9E04B47F9AEBEE7D4C2C4EDECF95B09A4243A62EB9D6FB544B168B93C5DE3684EAE2E3E4051ED740738DC5D57093B9E89946F9640386AA0B27B8E3E434CB0176BFD10B834FE140F53C940B551CE7335404CEBA225FD2C5AF4B698CE98D8264D514F6447E9F23B8244361B47C415F02085A787BEBBD04C3DA201C1095755C7512DD75E29F540EB008E77AEB544FF4DBA1875F7DE7CA16C4BEAE118373B74E7710C1F7BA90D35391CEBED33D4F5665CD455453369B8579DA2724BFE165E1EC24E223D9CBAD40E704E4F1EB29824027BE98F0829F712C3DF8EF8D83E0D55E624F27582BA13638B14630F362B1FE9D8EBE660686D011354A261DCF9F22B67CE1F84B7FA5F51D9FD8C272B091E40C6BDE3DE2DFA49D93C05FE21158E0EA210F96B16BA4B9FA272C39839CF1E9130DFFDE0249EE7FC6451ACCA87C853D1178BD05C585AA28BB90C0CE7340467632B746C3C72EE468B3E8C6EACA6D3DF8279C3F24BFAC72A2DCD1D6612C2682A51741DE2CB3C18308453E6047EF119F53E16410801C1AAE04274FDD8F6DD7A9B6B90FA292B6EF23A129764BDD65F69689ACEEEC6B646A3B9D1E1A78EDAD27D6331C7E1AD23FA0E7C136112E395846C9E19252C9FC9BD8061B6A5416D68EDBA8F449BF9612B70AB2D8848A9F7F7C0D2C4AC39DA904D7813D5D964A90A567E4D082C9E698440C68D2EFBAAAAF62FE66864A98015A54FC55BF202D2E29CFCA0EC0235B4E0B5E1060FE84D96E2B72E26A41D4463E1FE0DB3429D8269DCBA269FB2C27F2EFE8D2DD81997275418FA4B54EB8CF8BA6095AF2F6627623A75963B257CE65A5A4F00755B3F2EB13BCFC6645D5205E77FD86218FC812EAD4C069DF85E6F644A6048381795DB64C366E550D92F4D678EA15E2CB5EF550267BD44A98B03B5330F5AFA16C59D246DA9A84B525F1DC77EC15F6A1BEFF74685F685CF9F4A1B97027CACF4A7939ACC584D0FED204E49E9228005EDAE479B3D2DB6E95746C7DC0D1E43FAC0380FBBA5FA306CA852084C726DF271233E6A3546201D1898C7BD2A43DF0A89EF7045305C9FA28FFE6AE7CC34B479E9AAE2935B6AEBA436B4DCBD85B9587F9958E086CBBB5E221CAC4E5156A748DBEB37D6F54671BB187EFD8B4D76C6EFCAFA2BE550068BDC379AA0F8E8A9EB50107D7D603055A8DA4034A03DB3E448EBF2E89E696B64617D905478BE16BC9D1644E861BEE76D1293B5987F2B9AFFC8546EAEB71F14A7A4952966701C787EFDA6F249C3AD6C8E2D02705A7F4B622BEAD70488E08048F1D18283074CB5F88030879880B7A6896EF30B48EC3FA5218171433F9B2408216C62D052DA8196E0931CFDCE3018C312F37788DB4D9A5CE16B7B6D0F9FB595F5F3534412C70A7A0568BDA1204EA0CDD4901289DB5A13C25DD87469E0771C7D779CC219A95EB79C9E6184E105C76EB3797D78F807E01A32367632B6416BDE50216EF583D6AE95312467737586D19EAADEFCA10355EF539EF11C326DC08F22E76DB7BCAC5451B4AB6522DBA7F906E6A91538FA959A76C8B611961FB5CDFE417CD64D31164F8FE682A94FFEB4CE32E4942453BB22DE100EE0C9DBEEF671313E21A74341835F8233E3DE644D7326DA7A5A0670040C75313C9DB4089D2EE1815FADDC976C68BF95AAF6021B60527409508FF1EB193201A30C357D660341807B23B7652B6D5F1579699089D93A2D", - "message": "38161360466B3700B9AB64F10CAA42CB552582B219C76E76EA8645BAC798469F647EB5F8F93368D44142FFEB56546187EEB014452639E6ED0F0C93AE3F7943B997BB466D32307C696BA8EB00B47D837D3585340B52DE5AABEBE729759CD37C2D42B469DAD2960D22BB662380E4D2D439823082BCA6866D019519043F5338D08F28D0D289B606AEB741DB91C0DFEFC4F0267DAE6C63A5FD153D1FE1804E4EFD4D260370A8C2FBB6319DE561A49CAB207799528E5085F692987895846C374B9DA37F2D6CFF665E42B4CE3363F53E76ABC28B18CCECF27D7A9303D60605B0846401DBA01B476EAC8F663E80CE008A956F7F9A34F09C4D78439A75DAACF6C481359C33ED8AAEF545F77CB519643618EF6DAFCDCB86E52098EF654E108D66294580A3B6E6EFF7443D4A201A11353CDE91AB0240D53C4524EC8323E5CFEB3F66128EEA5643C7C3F2AE850A10AAD2A3BCD4353950F478B730D7E67EAAE2A6C9475ACBEDB5F11113CBFBF6B98D6C1C0A6B2D058B99339A31FF43DC685693BFE86712762CB53DD1C260CE6DEA2578FA0C3F3D1269CA0EDBBE87802A86B372E238E51C3188785B477D96D09975F121B12ACA8FDA39CCA405999AEF88FCBA6892FA435E0CD7A2C59C1976DE0ED0A775AD107DE5EE466D2597F1F4D44D1475BE5BA5A041EB9E322E0FB9D6475E6396F96EE703FDBB150D333C2EFD3E06B27E7260D541A4C9165DB10D38FAFC7AA9549430FA86CB87D5939C496A5748503F670AB550F0B3F8C6F3F4B38BD34FB2579E94774D7E6DBC33C35188396BBD0A103CE187AD53183ECBE2AE6843FF4A271CD6B52762588C21EEB708692F7FDA755C37B2D5FA6B890DC6F7CFDA9F5C743C2C800814E01942C212DCF33660DE359BBC4DC4B73C77A825EA9641A51B9EFDE1EE6947641A96C220EFEE4CA39073A3079CEB789C3E62A674E523ABA33A31B15F7F84AA04E6D28735EA021AE2EB8D48953A7BD7CCFD7C65986D2E36A2CCAD2309D03830D909DE8374B87619A3FB13A21CC577515D3B8197B05DB4E26A463FAB04A616F58EA90D0D8BD9124E942CC24D4F987DE177B2C91FC6C6DAE617695D86070B466649633B99A7EE03275A485D8A44CB4CC7CD46B64B0D5F59C943B5FB8F006D96F2B706189C5F4A282DFDD67E1F8F1D9B12F95DF39EFDFE6D61FF9BE4D01C00FDD967EDA8DFDE4524C1E5B3497AC0596427851890FD46FEDF5FE6F6E1840B0DE147513F78F445212B895B3A9CDD5D5458E11FEFDDFE484E18E0E2ED0109CE80FB8291A7CF193A84176317D84C5EDFC14CE700B004078F73EE2058B3795C844261A8987C9EAA3C589124F66D71376F70945B49854C302893FE2F510B72CCA90ED0880FBCCE731D966D4CE02D9A8EA3402CCA7F236A55CB716567EFBB40A9A5715291FC14779C3A137EB4DA17A18DFBEEEB92B5173EFCA0CD9D865909879B4A476481BB967C8ED2E2E2BD1F0A2268F8BE7177578BF109F30D2779A34A7E1CD19DBFFC80994B6C65431DA6213109C74640D1D82658390A44E41B0702E2D2F08903EF29D268A9C99698CF909635EE0F142A5B753B0820C0C692652963E10434D4B4DC0F411EF2A1B60CE04718009CAA0D7EE80717A6A466133047C50A5FD676DFE89133DFFC8DFD31721CE06E33F10E5770893958E41D65E7BC0BCF1C2314D2EC4E7B0A0FF41A97B741EB340C8C221FFF64E91E32C2C55AF2A027FA93453F1CA6286C9053F173408FBBFB1D3E0F060EB69F145B40BAFB59DFCEFC8235A952B35F2A43129AD9BE14BF2AD92D1BA529EE235DA4E6F89E47EA3A076A1106336A68E917C368FE296B5B850DFA88A536604AE002B5A0123CCB2292423B06344321BAB27E637CEF09F0D8FDB722C3C1DA2C760D9F5427ED1DE74D93B271EF016912A7D1BB62D2AC6DE93429A2BDFA895ED504323D6F47EAF375145010E9D83E1A7BBAB1AB2296DE5FB47DE63F1A6231385D7D8BB00A7D23C353F351403161EBCF744405EF32E7DC60B43CBA930A3EE6C7558172D5A8B35F80A9E392FEF6939B6F11F07E012A87B9CF53346369FECDA7E6F248D3CCD1FCC0F2463076ECB62F9417A6B861B124D810294E43D269A6A6B020D0492E8BAB412872A2A2DA3AB00813259D090FAEEE772F20D47E0EF96F6395206A27F4C9543121B6674F2953F9E4A85C3C41CC3BC61B47C41382BDCCF790C2CBF6D31E58644F666944D6CA353C43A3914B0589312F8BF4887F5819BB9B658D328565979C75F362C673FBC6BBA4C71D2D3D583284C247318D70934CC615D9650A926EFD5970E0E97D8A4C796018651CCC1F2F9400701FA082BE077D5E71EC12EC5CDE20C0943C5CD258A2A462CAF094EDF2BEB328C6C1E9B32E9196CDB342202FAE4450AC520E8AD2575BC159D2CF1454D431A1921BC130AC8B73CE1F0EB42D1AFC7731DF44691E9350CFE9F66E7426FDB0A581E15D1DA6E023951671A2DBA1415230CDF9CCC5F95512FEAFC2A15442A1E471FAB0F57F4BCA71FEA43EBF3191FF918B4AB0150B6EAB557761A8E717DFC7D4D5A234DA32CC9DE0E3053B704FCD74A696DA811B167687A5D5E3C21C2BAE7639148E8CA538966B0C66C78C93138038397ED4958E18DC6261486C709ED903A870984EF08706F27B2C689AF879D8D01146829C20D41E0F8805159398B3C2D4A65E41646325C6BAD59FA8B49DA1E278F4E02033738062E9D5FB74B741DC9123E0053BDAF1CCB03279F51C83BEF30AFDBC576F2AD7A2DAE239323114573FAFF22266A7A89E9ECF640BF8D54D629B1C0710CCF6F1CEB48A88ADDA79C031BC2A4E437F1FDAFA1BC9B3483EDE622A88BCB2F363D0828EF3714141A2C3685218A2EA5A00D51F4E0F6AE04F85E440F6CB2A7142CBD9D4A6854F199E6DEA64FB18382D7FD52E55F9FF7ECC377608DD0C10AF2B07BE808B4522BF8956CF1ECCDCA1575762F050A5F73230C3571EF6650FA6E8BD39C60653709B1ED07A258829C2D5EB2DDC1783F4CEE9F10E11F12764F239AEDEF8E1A2C7CF336FE6E51F8EE84041B47F82E89FBD84E09FDC8ED686DF8203EF090EC86B77546E167CD508D56DC580E498D0AA67E142BDA76358F736E6AF44EFBA8D536924DA8529EACAE27B2C44F8D3C4BC362472BE7C5C77ED45FC7E59E05E50341A669844A0CFF51C265D9F3595A955758FC60E9524D5F3ECADC5A97A45112782B0C1EE4E48548245BA96936F4925B3EF77C46B08E001F608B4E1982314AFB3BACDE95A4899CC39FACEEF971ADDA7CE46E9BE29F8CCF56B0A09871B824E513451B07117186B9CADA1BC37FE4C0CFF90CF64E7754800632CE501C5E5476EF632CC3BA41A6D77322D5E062A5CF8DB6CD0EECE8978801E6FF5CBDF8E4A99FAB4CB192FD9B9DDEE5E58DC6893B8F62F0B744C5EE0FB3A0F61A5F48109CCCF0F96F1BF208B044FB82FCFCAC388E2C46476D4AC5E5A2FEC74ECA53428720CBD291C654B571D6D03B7D2A68ECC6F26B596CE678EC7F6EC74E149DC8D8FBC225FBD9C3AEA3E7892CC059BA24ACF1036517A34F04AD1CA5A6406A3C4EAE9729E5A1D759F03C1A1EA86183858215AF218A534C6002E163FD45C9FFB8B28FFAB045EBCFC3CE7B66B177A62068AA627F95F91CBC395EED05B565A5D566ED81C4D8CA2DE801AB983E469CAB4D0896C9A32B30ED4A7758C4EE3DED7B6C0CB2035CC4BEC7324D8DA083338414FE4D1AE", - "rnd": "638940DA83C6DF9A3B72710AB62DDE43528F28387DE06ADA4233E87BFF87D468", - "signature": "E540D8332B5B3AA03EAD9E51A396BB25D3353B6C8A9E6C997D4C18FCFC0964093766F9A3047A727C8FBA23D14B12C1B84C0CB90D90BD73922470B082379B647AD8235B317ECACC132E7EF9142CD6B188C9B03E274F79F51726EDC4903FA16C74F9D9DD98FEE960F05D2F629C25D09ABC6C9A58FEA0D70A87D360CF4F3B45FBA35BBAC4359FD42879BCAF6EC103E6E8FB3E919B26FD05BB4FFB4B256432037B34D6D12AEC141E4C6F701679FC19337EBC7D3ADECF93B4038C58D6626BC10C9F6EA893561D8EF7EBD490294229EC5BCC84321AFE4E30EA88AA04CA9E3913913B13A6FE9D03D502D2111B892974691218C5AFD376F0D54C2950AFF93D62452546B93C569F9F47893CBDB4CEF77E99BFADB6FF671FF1D2A6AD6DF43D48E64305FFCCB371D4B0506E73E205A2CEB0B8F59CC26FDA82007DB02314B5F9D6DDC1696BF124E8150125FD925A174BD08980A08DF39305510A85408005BA99BA46D7BB3966FF8C9DA0A256F66B7BB249F5004B63D8FAF09F7E7F66BEBB4AF5CEB4261E25D696A1277432380FBCE32D47645E0401518E8A8FD38056D8E37F67BD51F3C9C262AF184913A368BDE2ADBD2815F71E43CBE950FA07FCB772FF0DACAB97D8D0DDAE8C060FB3CFAA175587431492A7D6A55A859BC2D9750C6EFCC3148A736D61BAF0598EF50DB101B0E4A1D2A67B6DA6A9D368265FA60C66D3E07DF155F7EB73ED8642C8047CB6CCABC79C550BE0E0DC30116B2840609BE9B74BEB77B7AFC208FCD895F4131656F7CFFB77446CF2BFFA8D221E1A802E0F5C01972DE9C4415CF8FEDBC1DD95EB72EDC3EA3E259B7EA9C5A6F4470D955039AE00673C37B98D8722D6CA1578554197DCE1510B54547CD610A9D4CA7F6DECED78303B631A2B2885BA9453BB5A7ADC2F32DFEAF847424FC57E43B1040D2F5519265926A60673CFBD429B69CBD5C3B73C69BB70ADA2423CFAFABAD543D3DB2D0B3EEE9584230D3A10A5A0B3B63176005084B34FA3AB03B6163EADC56316C28C13944932A53F181120734FA2B0B1260F57D2B7A8795F684A2E1DC415430BD678883E73F20AA5E9EC2DCBA06B0FE99D952D565E223E33C2E274980F215E5A76F04FBF38DD463898AA1C440E2ABDAD6960ACB536CEB74BD8D1FEB34368D174D76EC54D1CDECBD4BF7C667D9A5F6C88783035095C78423FFB4A0F97A921B8DECAD99F29566C524F6F9C0AD87E490A744D8BD56E472A3071B5E2ED3CAF9F94202EBCAC9272E712B830D2F851499F3626B7715FD8ACA7A807DE58F87C4FAB37FE6CFC33775C8E09F1908D7345D8FDC072B838696896FBDC24338CD15D0AEF9BA97F434F983E8CFB0C4B581134596A1EACF88D632B03056691EFA1A3C7EF7E8E15B33EC6AD17C565C6ADE470C014E58A5B8DF56B0ADAD6A68CFA1AF078397B7521D69F1D195C59C0BAB0EEBCE447FD1950227B71375CDDA60E797BB62E2A082FC636B6D43F0705FC6E97C3D8942EC0128A147CB2C0385EA95DAB645C06EFFF098D2698C46134F4ED2A89E7C1D18810FB2F75724CACF8E6284ABA67885D3B628E4C84110F755A19D7A2A5804941D28A0D0FA0970BF871A32650FA74E6230A9559AF6EBA554E8F5AD416994C55A42ACFAAA669ED0D7D1BECF4FC53FACF92EE00E85AD74CEA4167410239AA7D583358EE3D636F7DC22DAF59BF277449CE2709D0ADBF25C3F90D30504A6CFF974D7F236958AAC212C114CA0D06DDDE5414B8203D0490FF5F498B136E5D43C053F75BC55FC5FBA9888F7BDFF003C279C9FF8A0E720E48566F6DF0C04B853296E9D6BA962FE259FD01DD41BA9998333B1FC8D62575F2AD59397CD4D48E5D0459493F477DA97B5388CC4DC4D473C247F560A68DBF054AC28060E9D93E454359D4B4DD6EFACDD39E97474B87AD3B28B6F44702A8626F11B9C750147BDBAB56AD6B6661945C18EB443A5341FA5555C583AEE2F2127B93D1881C862D62A4FAD82057B051A023119454E24AC2CE518B5797A3891B565DA66DD568BA925681DA3D55F6EDEE63571AA4A1D236571341E5DE8B521C27ABD57EF7F23FEFD2A923F5E59A3989001F2A00D9EBFE804DB09856F7D7F30EE85F8CA0E7BF322496326D228F22154F63801AB74B3DAF0A06A727AA122076121FCC93B5B25334CDF2B91DA0C445F1E2F63989CC60E4449EEA0848B1855F9F06FE3676FD9252C6E0EBF1C961AB985A5A64592C01E5F001CD947C93D30E31CB8C7850FAC478D1A6EED4307A6CC72D67B8342231CCAF9B52AAF3A1C4738672E3D04B59437DD6E9DB7B38C666E845D2D191707A0F97B2CE26D2A51C3886A0F75D8C403F64F39DB680A2DEAD1A65E81E4838F76AFA586182B2C0336D821698913AC2B1052CBDAE05CAB2C0638FDA6D901A670AAB12832E82BCBCB8B151899ABDC6E30F96CC5D8F0C894E80FE1F9C26ED9F9A7F686D896E39F578466771DFA8B1D81035E3AD99B5FA7F0539C48A1975CF2FD9078F25C2328AFBFA6F4FC46682E455A8EDE9F831C29AC80D47FAF0E75D75526F5955E822CCF2BBD20CA6FC8E371A887E45B733A72C4BFA0FB0A2A5F17696BC2050CCE3ABC51ECAA2794107A6196196ACDCB19079CCF97D0D85A4126D2998D5BC9DA971548C8CDD460E100F311332B5AEDAB0512F9BA3131A66B797AE63AB4FC061321D5F4BFF9D24FDD4D575806497C4A0F3DD98553AC2C1A7437AC17A9511B99A3285AFE3F11E78E3162C4549191FE6605945285271A4E6AA75DF65E1D414D2493095B5CEE985A7FD20EAB8D2763730059074DCC90EEF484CF85C45AA6CE6D9992DF1618C44E1E0C08C5B776E4EE028CE1A566E985FD70E6E4E4866C374B9A643041E2E3FB27064780872512B5C381404D5EBA6859D77B1D4A3C98A972ED75E9A0CA335063FB6F7FDEA6242527AF8A2418833449D4E07CFE519D654BD0D78C0AC97EE971B288FD8D91F68E92856AD26DAC988BCAC36DA16112E336C0EA07197CAA5964D5B08F58121687BE9B97AD46ACC3D72C8DF243F4A5659FC7B0D4762570683511B3139889CF19DD10632682001B6831D9C72F967D896F01083F4918E7249A424660BB4A0AE6C28C7B4D70106F0234E9A47588F13799A255713211B759AAAF944C5F138224BD746DE159BE480D5F6CDDF5E1C3B1BD26F68DCAD5FA0FA85D0FEEC69ABC0965BC233DE1C625F238FEB72B8938EC28E3C143D3174BC5AD8A34B36AEE5F092BFC00E711ACACCBD4456DB9981F8443A1F8620C43C82EC74484117664872BF5B14D7C81BDEF08E5105B4A966A7FC0998B1CF0B29DA31102982CEE44C6A761260250D63AA70C7D9603CFA7F533BB1719CD3CA3B44D740DE2355110E14BEB9BD456614C8141873ED80FDAAC5B544399D17F3B39C286250E3A05DB3F011A1A140D7128444285FF79FA1E24329DDEC18480D98383AA3C7FB552024DBEA14DA8D648F966905E8C0A7B846A2B74D1263451E7DF5079E6964651F4AD708D420B5C6598D4E913AD3125F1F3D24B5D3C3735C418CB5792910D2E5CDF5B28A885F4797922F57861879597D7E6461558FB3974E2BAB195B11B85FE164005222FFC1F1FAB89A1289ED8C2C9C7207E5B648B78264D93A0336A3DE4E24052541810D965ECBDCC86E99BE01208091FF93A3CB7AF6E93E11E1C73F4484FB05BD74959D96D98D7CB26E565FDE4887EF7892BE0F725AEE253ECCE0DEF7457A811653B1A61690D3CED8DACD871E72599864CDBA0DAC0A91F1DCB4A538CE0E8C61D689B58377B34129156E6FF5060A4196E30E4456501F609903D841F3EAA91E5F3716231AE5267080FB99AE40543D2FAB6509932788A213ACF814635E33D6F5C0D0B44B028CAF5F80F66E18BA4C81A8635C99F753414C2B5DF4D559B554233EFE2E5B26CA8F90005E2F8739159564B68B80FC6EBC71AC3263FB4E6A224FD607E212F54ABFCD9F69C0AD451C4B48A2205358F67AD8CA2CF412EF2E7B01B6F9ED3A8B39089316C8A4AC34786C127E27437A82AADDFBC1D52A0E4B240F9FC60E71F3FECA518BB1EFB79D82BAECE98B693E42635FEA32FF03E6DB2866A3937884A82D0AAA4B577066A603D81FA52ED761B4015B52DB1C2A54A3D4DCCA46FBFC386333F98614EDF79103A6C617416C46D13C2D4CE8BCF656D014EF62AE973EA1B2FA738889FCAD13B09D33D40B0C20F3433ECA31E171C41CED4E1514670FFBE245EE1B427FCCB64FF8F0A284D46E963EE5C1411AA35DAC796FB9BCFBE5719E4E19C5599379E8396EDD209A84C75E350F0CFED3476E8732EE5DAC6BFF9FB985A4F991AB4EBA5475E2A29661F3A179C0D5233B4768F4FC51E9CD93C50A85CF137515458CA33D6FDD2A57A486A2D466772AB30510D91648700B36E97494FEC74E8A3B321C08009BA2C0618147A86D1BB323FF9BB62367637D0D461504F66A99113A30FEC880F60BC322827C98E229DA0E6761D4EA0BA569308F985378C3375866A795008B82069038C673680BAD8BE5A032085823A610DCEDEDBCD968790326907E618922851A43EDA9E5E73589BD5F17CACCB5B457E2E34965768BA04C3D202E54446A3A2867CA01274F4518A5D3E8179A5F06CC3E8F811E6FEC5F353F4CE88C8D5B3F9B78FF92E197ABB7B32AF9932DAF62CEE6CCA2807B1292D47C345C0375603803C94547C93CEAF3541B9F42279E6AD1D5069C5B440487E50E6E42FC85418E99ADDD4C4C7298C05CBD843B15948D8352FCDE85ED55E7007F1435BABAD8E68267EEA99B4E88F8DE12EC2F823235853DF988A0D87329819E51E0CF8FA982CF7F6983B7A3218972FD17F945936887A4A079C670A9D55E24363AC41B042D073DAD452A40E341F6C93C4F4310A5EFAF1604045AE59CAD42FB00CC7D38D83E89F1A29EC7186648F037B71F9AC59F616E2A5D636AC4B77D0C1932E595BE877C418554D6760D10EA1DD92DA611E8CC3DBA267CF550C7774A75C80D0439DEE4F885FCEC8F4CB9A8425EB336DC414A07E5ECC2B949AFF62D8EA3A9C36CF95FCBA8EB1AD8222170FD50142E5EA6F97BFACAC40230DB389062FB5466FED4DE375D213AF8E998F7A89977CB8860BDA7E7DEEED380FDC6764999C49611F024397C85E98C572DC06FC43E1A5EEDAACDF22D418C6A91B12BDCD363DD70631BEE69877392A564AFC94D40A4562FFBD5B2FFEF205B45B26E1E64D58C5D6C059E21245DF82A4F52793319779AA4B9149C24EC48F89A88CA79C1732724F22E84B6335673A0E1D9D9F0E1F6F65C968BD3FD23CC7284CE4518FFCF1B901A1ABC8A4FE879E88FA6AE545044EDDA55CCD1CB7770DA620F569506EEE789571C378B1A0093A2D5B1D30DA08DDDD8330D4B640DB1B3E32384CB4BAD2FDFA4464F795ADDDE61C73446022EBF046E1CE9B2CDE6E194B1BB9D57D6F6FF410D602BF4D7EB20497086CF7A2C143B75D9DD63F5B6507181A20367002042015FF32AAC962C825AF72B9E54A84133B05C966191FDCF56E2E09280D9F7FDD0CCDAF5FC2F938DAED2B02EECA5901081B80D9F28312DC6DCE95664F80C7FB3CD6CEEA4807461219C4BDF64729522D5CE338FF91AEAE38B34FB5C0F3E396B5BE94CE82E9A8C2F222B4B2223C8BAF24F63E2D9F41C3F582C35D7198236AF5290D413AFD29EC8830064D3E346696B315284260C19C16D6B06163A6EC930A28CD764AC7BE2BD6BBC808EBD180DDCFF72206150F71B0EE876EE34266EAF4BDF9B7AA05B9ABCCBF2CCF264159CF81379AAE9FD951C0192DA9D636FA789AFE4CDB4A25ACCBF69DA889FC8FD73DC3E7D0A2B9BFDA1FA84EBA8CDB3959FF42A45C2FDCCF236A403D35CE50C781DFC37F0E42929F3567EDFA0C2E5113686EE3E18E2427376D5268C4D701FBBA5F365556027334843AED745A0DC09E74320E786AE5A8E51FC55305856D634DE15BDA96645F29DC72CE40C5F8AF85699E3B04EE0A10C8AF1B048D2D2CA8A9CD9E9ACEA7FDDEE6DBED51EEDDBC3B1AECBF4CEE3F3C6BFBBAA84CF470205EAC475D0D74379D8E2446F0DBEC7B63BB98F0A39C6CBD055D43441D310413D256EBE5C7AA4AB080F2421485FDA3CBA5172742EA0ACBDD45645E42B553C8A50C65274522FBC75AC20E2A523FBE57CB8B3F6E2763638CBEDF84243E88E34BB76E95A652F81B0F1C0E5A97D78654802C7E1183BA7E78DC9FC0C8ACF1C9A6A3B74F176E57F016AFAD9791122D3D1D2B012A6B92B02B0ED0EFE6868CE8154B462E8936C7EBEEFDC64D4C00A71ED95D2CEEF6B204F116F0FBD20E5A3EC7D45C9615230686729EDE9B8B23B5B5AFEA296096CAF3C8ECE2E985251ABA2BD5B794FD5F25F1D0B58FCC552DD295C796E5E75FA147A6285461864142270C027B1C38F690D5605F6F3A9E0F17C19AB95405F2720258BC032324B7A4CD6F96C836AC87BE8C9AFF5D244009F5301A814B8FE746DCDDC7796BD29F2F64B2F3D00356DA9D11B737E959EA7B2BBCE657399C2E80B7BAAB1B8C3EA07455A910E45466073748DA0DEE8263F506368102C59BEDAFB000000000000000000000000000000000000000000000000050E131A1E282D33" - }, - { - "tcId": 58, - "deferred": false, - "sk": "8D144A2DD8630D50072DA2AB863B9C2BF4EF934D975A52E011ADB8E9C912E37878748DE31FD4C5AAD033C3A6CE0F06848796FA1CD82315828E0F2573FCF2613EDD63226C8A38496EA8EFDB8D5D54DD152A6A44AF742B13D33B4687215559891AB5199521FB1BD5E2D7B1D8757EFFCD6DFC241A8C5A5EF0BF759B371E206672EACAC209E026685CB60C49980942886914204D91A84804B44544969020B29019A741104466DC3824C2000EC2440C22016A19A42D8CC2200B26910CB1899A40261B106CDB084DDCA64DA136068B26044124818392400C328AA1825163B08C0188681204241C20704912915C1284821841E01044D1A06892488611280198002DCB242ED8086A0A228680366019022E131770D9460C42C4000237261896044B48245496610A21248A1206C8C828133069944204209280D9A84501A5701A48321419710C0211208850220541503432C3C0400B4584C2046D6104669B002503226208008A53C88549088A923485008900523825E0020289B620CB3661200226A010105B066124A164838609D8802D22206983180118188983924809348ECA243180108A403891122669D2B62CA1B49083C45118333104C5641B260813860D2329519B442499C06D081612A4942C8A0250112490D90869A310500AB630A09820110784810651DB84608B347101A80090426E4346204CC28CDC8064A424049902505916488322890B002902278C11210964102988A42CA320309B3049149551D90431D4908D43440C09B82464B65040364880B82C590661C946060014685828268C924503875011A669E4366C08A904C946281A995004296582166E5244714BB0699A002C4286911B312E22800054080D020992A0328C5A4849C8462A0B390120362C19442010191262984402B36CD41041588288D092601A304002C04C948881DA842D208391CB30111A13108A242E0806801111724BA66CC3102DA2A46111868D112604A1B460C9A0451A38490C858419B88803204AD23612D4B00402050422A4280BB8215B9610588428CA8841C20890E20232E3B045C34026A436624C484E58A089019449C2306804030C58903040288548244614994D1015698B9408098624D0828D9C846DE2262824194990220453942D040906223946984032A0044140486650C4501907815A242610428E133520A1825058C8448B446C093022811885DB484040346202202209190814216D628680A10845209801621040DBC64561C66DC3160A63086051080213C760DB326808260520470993180911B7480230295900889C844C01445299920C19016AD9B870DC2289912270C1428A948020D9C02122B82C24376C133608188664E4C00CCB0288D0B8040918318C249252162C12038403218D14444AE2304104B5119B9821224112612468422429CCA2290A260822148523386A8B14240084855A2884098691881641884689893889230871102260D1888462146DC0484AC3406D8CA05004B08850220A5B928C0205914A44820C9165C8A828114051E01040A30691DA4670D0020242B0646044308242124CC82194340502214E4448892349320245610B35500CB86D8896682414105848449898908B8649C8464003B1452491458414294A12441A940549A469C3C6009A420554402A01406211998DD8A090D33850E3C405498880118411D0140CC2002924A964DB04501C92108B94090231205A4829918408432430CA4621A23486001324D3060E1034200A936D1B17418A00459BB06460962424388A00826481B84902350C51488E9A1604D2B445D0A8455086684334911A45268438825CB6641B482A8CC071D1A06CC4202A09116892B80D004448D1A8655B068819104150C24D48A42911064888A20D18032D044944D0C40C4A920C1A086A49004959484518B808A0A061110606084840014904034128DC040D22A32C8034904412610A08849B0072118289A3C66D9B128A030221C9A4711397505486400A244610132E54C80C811605C8A489C4969158B028C4B48DE292808CC62D21994150882CA2A4010A988C82806888265263227054A4445A006E191552DC948114874040268E034470C0904DD43605DB3842224090DAB6041080841BB3801C818524436E22110594482959C868120765D3026D53A408500082E2826D10138D13B10509B26C14883082A005229848E02020A21810A4522471625C747F79B1C4A0628B79CD627827FD552BFEA7156957BE600D8ADCD692BDE40F4295669DFD87C1715BC459AE0A7228906167DFB96D858C0CCCDB1F5438D9E91BC82324B50C604008ED4CE3641AD2FA5D27E01075A37E39993C097937D893B2996D206500BF98918CAD253CC78108DBF40F4701E199F5F8FD7597F397642977680707EE2BB018DEF79EB480F97567B73FEF116643A5061B349FF75720878C7279C6F22DB3223F52E7C72EF7C888E8A375B4943326A4B25F195641527B64C2B08A89070F87E2AF49B2377825AA8EFE043E75ABF82BF9E0B2E5F5CACC860D9B4D7592D22058E65358CC82A065C0A045B95B167B68FEFF0B330CA00BBFDE6AACE6F31222F7339B675C77ECF6334E679F5768A70078F02C0A0C848DD72F3292151C696A1AF7A774AD7145125831F3267E6CD5FBF284E14A076B52D06CF94063C7A298AC17709169354F62EA1BD025AF60699CCD6E1E8613F305ED6AE463D4875ECB69F946AF9505A49C4C7B2646E4A18974D6A0283CC225116DB90DD2BF7CB826EE1C157218302B3C83C91C341139AC76CFC069398C2003917EE241CED1D716A60FCE15AAAB9B14D3FD843EEDFFE1523A4E6069E2D18A1CA942473C12D55821177ABC71B65575E4066754D063D815F407B415E83A7F73CA4919F31960C75520788D88B3949473DFDC907AE5071217B2738C5733B68FD72D8F6AFE7BABBB61842F7814FD89073F636608248AF55D941445F3AF69C7C581136906C3E0989E2D50F2B46B6B6B2F690FB57F1534A38D577ADE7D486BEEA5C5020522D35199F50459E1DF6DEDAADA7922B795BA7A057E8A0A2F38CCF5499F72F5D7618E8459053BB0701815C0F0518CB36F26FE42CE5D62EB3D08A4BD1BD47A09ADA0DDFF2DB88547EC648B9E25575A95DC221435389041F8BE375260C60FA6E8347A925113D96F13EBFA45EB92AC2F5550F2D94520B836328535E44D6EEF298AC11E8B165A96B90A4C36099B5BE52537161AC5238C65DBB1B05D2DDAA5EE46BAD18C0CC9B6AE090956D484B83E0B61EE68490F0B125AA20D12576277EC5BA6ADA3FBA73461F2DBF288C61090E520EF01DEBEF1EB012AB5EDFA996831490700A3871EF2B91A7EAE8BEDBE3502340F9876AB43EFB6E746A9F7F5B136DD68E2EBA65BD909C16214A595A50C4CE1933C58DA66A5BF240C2544A352AE7E23F322390D9EEF129CEFFCF7A924712331C84933F24DF19877D73DB29E141BF9DBA79E3DF597245FD64B271247BF28F94A5E6CFCEDC0F2270D23E96B30A8D751BD647FCE50E49606D732AD46494858EC9CD99B91DA59E61F1AFBFEB7736A5ACE95649DAFDFDED4AEEF49144BEBD173712294F3EE06EA0359F76D24AF451CFDBF4B82E89C38FEF9883F2CE470944B9BA5ACFDCE187032BFFD094989B9F4C165BD8492B647C31A1209727596AEA59740C0182C50FFAB12EF3B8D1706C5A9ED7E050C510C240CFC25EE47CC72BF6EFD888D47E75ACBC453E0FC3FEA0DA6B2A5BE352CCB620848021F4AB26A8565CF0BF37FDDAFB5FBD6A47B3E311767CF269E7F27B2AF2305B4A2A40B725A5B5FF4ED5E2B3318EEB8F0D0937698F41AF39A49A9B5F0F62461D31475F41566ED82FC674568C03B88D9502BB67C86386333BF03CA31F90DAE2E15F8E775498C75020E9F91AFB983E700C60D64F6A5EE43F61DAF91F7C928DEA7C730B55A41590A183E4BF535698E2DA0C40B7357C37D5EA8BF4E3D8221ACE0E12A3E859F2D548CC07711AA798B036BFF5947144F8F3CE3B4B78CD0B1F6B9E6C2E398B0A5B97B7E7C3224999021778971D6ADA7721FAA4F6DB2A6A4C37AA49E2448F78DE890459CC22469C398F582F0655FAD41C79F2330618F1D6F4ACCD14DC1396835CAAC3822A3A1F2EB5D5F4C08E6BCA1FE29BC31928C4E9E14F6FC8E7B522B934FACF7421165F0C2817507E4196AFD52778967538FC4F7FAF702C86F374144BE9D8803B494222B6C2EB1B0005C8A2462CD4938230C67C414B8D2EAF93DE03CC87A4F507021AC4175ABF3285921563FB3DCED4DCBD8B92188647F5ED9797E0BEC61923A2E0B567C84E0BE536BB78166342ACC0E325BE16AD7CD0909B8D2A2A2097B23F6D3F1872623F6BB062F772B8A87A55A82E51ED3D641A1662D2EFEF8D2ED9A0090A287746C33A304E7131655BCF98FA44C1C9726809A7DAF2601B6EC9BDA88CFA0838A7D2C9F27C7A36CDA11F15C52D8ABC6D7334092C6B2FFACEB37163F60BD31705ADF5A6138E4C7525836841BBD5F6CCA3A8FD0851404A29B6B91BF0EC89A4A99CE9E7566185456E4051F38F0FFE9FA6EC51A4C98C4958F670494189A4011890CBC54A4E37BE4E6B1DDA3DABBD593FB40CA89D72E75C16FF5DAF8070973830BD47E480B02B09DE28748D646B80671BABFCB2987C7D8529A07C951E055A7978278BCBB3B6EEA646AB5881A636FC5C16558D6B1449491E7830795B89B05B852F835C9C3DF32F8B8AC320FF5D63401452C695E5DAC217AA709EE92D517976D438412B4ED9C7411A4873D6617466B3BE5EECE45E5B25006EA7542C88C3C3D2A8BF8E55C1E51F479B30AC6FB80C7609A03D91AE1A69278EFCB361A7A8D8A5C2A22106920AC9BF66378BEA6B12563A8AF3BD392A059324E634B9544ED5B59A053C897A9EB3DA18DA0A941B71912284011C570C2AF1753758071F71CC303C586E6842F4B555123276CF8AAFC3C42097C50911EC9C87E6C460D549AED1AB45A9C27E42D11D83D0EC51619A6C1453895391EA297E6B3E0029C4B4EF9DBA056CDBD8B179DBF9E354EC546084C3401AF1AD49AE86D799D9D73D60343D6D52A10ACA3AFDFFC83D296F82261E5401ACB7D780CA05490A6D3EC2BFA076CA2919E53A7A3C43EF728FD6520FE3196912E15D9FF3804D7A4857AC4A25667584C7B237568EF96DF93B17B9C27FBDFA4AC72EF17C57BDA2008F3C1AE65C2F742773293D71D0F598F7F3F0897466C9666E11D71FD1B49F08FA176DBCE2EE6993F7F986EFDA64C3A1C34AD5360A5BF8F779412675FC0D3E2A5C5A358A803BA9F976C9D2BB3710F8B9A6D9CFCA7F36E972E74DCC31EC6527C5F03145F31FF66A666E76C2FE412A75BAEE7BBE114F2D9831E6C5FBCCEA3167C5E37D0ABD9205E9C31A9C10861BA04F7855C96634E4D01FF9C4CD53C1075610E213FB5DBC87E109931F0E3D3EF45D73B7E889802164789564428A420CB201E7ACD84C49FFBC2F68E22AD3691D969694C4918011EFFD0C06C54DCB3ABBF7BE3BEE5F47F2BE63832DF9C4A3A5A78F76D642C02E9E4009AC5C33CCF6D680B9827E1FD9BF8385435509DDA48477F1A77B82B08A9E212A40BF7787991936A54D19BCDD25FBA051393830BD161ACABE8CC7BAF1AD1AF75A2B73291CA4D5C2BF85BE372053B644DC1CC7BB3806B1E7F9E05A234992820FE4FC525B176ED979634DB3F13497C00BC4DB8BB07981F3043FCEA6144A72A55068BBAD9A7898D663FDD51C4E5EC37856D290970B717C252C0F05AE3B9089C7041101ECA99B9565064EEFBB27F10B1E8FBA6BFEB8C8A96BCB3D728BC9004209D334D71D1B2DA8A274FD67375F92D90E7802539491681D93DF0896FEE2F2C47089DF27408FBED77D1251EA5EF7133786C9D75EC2AE0C73E40BF12CCE9A321C18559F236B14FFD024EB58FB88F1590658A29DCABD4D9D93ED27CA28D852EDC513BF401E6179AF10515223ED756E8B3166261AB002B34F13C7FDCE1F94E1372FEE67BC6D16D5A5CC3CB1C4DBC129BFC8439E43B456BEC1FD2D4872A2E93A984647F686EFADFFA39D6A9C6A023713D48AD586F2D6C636A15F05C6A52B47E74CD812DAAD7FC50075BC295F02CA578DAB9848DE3FABF117F532F214E089E42ABDA6EAF4D3A6D27A8CF747DF8BF25D20B7653AE4F6481EEC205E751DE58C3647E47CBB69C8BC16050783AD9DEB1C61A330E5A73681E79D1D2BC247710222EDCC9E0A06F0FD313244F762B24694FB8F01F0E8C3B7BF4470AC9D48FD43FBD15385BC552EE03628026637BAFA37DDFDA92B1BD1F0F804D1B9DA0FD83C7A8FA5F505D7D558D330A9398842AB613A4B1D60198073E17AB8FBBA34E897D7924199DC67B4056657D743A0CC02E53220A0071E2924379C7F3B9CFEA806C6C5E49033DFDFA865D9BCAAEA9FEAD79125E6CCCAF0A8CE6FD2F2BC34545036C33EEC1FD49DDAC243486CB0A84264E755AD432A98D061268E12B5B1E3B460E331A431EAC3762D72D8EEAB05181F5D482324CEA0449CFB484EB15E60AEF939AB954942A4C16F0C82EC1C87AABFDF30031C044D1F4EC26D664EC7EA2CA0DD56436B4EC8497B27DD49ACA689BA3E36A9389D1B0AA7A7BEBCB58D65A336DE83B3C41CC6BE6FDD470BCE35E70384DE651F25967688BD9662424BE19B3CDC15CC1B5C2EC64BB9E7676D8C1214C6A85F9160CCBE1CB444AAF48632A754BECB450D3139EE39227CC22E53166BF32D5CBF4E31E12F9AF24426227B3FC39292F14CFCAB5A6A3EA4212CAA01C63F0028424684D6C6B38A1F05B2B5D1DF14831C29B5B263BA730A2E38F54E712EA8C7452DED75FA0D492888CFFAC3DA70D755C9B04E9C9769BFFB2B690F43825FF3D65B4D0006138BFCB6719893EDD8D624006B0303D88A6911CE616ED261181E2842726F6E05063D4FDC5B620FB9089A4D90566A8AD3CD474A83B8FF37047265C8E1CFC", - "message": "F1EBE589AC8F5DB9F143E620F88F6FFE216DC2464F4E5D5E3A19FF97646DC912C57C4E521625AA57709430D646611BFE547BDBF7B683D53F3DFBAE56E7CE4E221A2C82138EC47AFD6579CA248D9B5AE870E765B28FE33F488FDD1690220FD03AB9BE71A0498BE6BA2E6BDBF5CB651D548CD066B80907E18CCDCC9E747EA868406E9689AAEFE7B8D69F6FBA706F0C142E5195398A503FD04369618702618529E9DC4B02E0936EE9C55BB6F7DA4B4AED55CF00FAA891448B71761D19D9AC138C974905BB5D62E32E4C3ECACFDCB04760833A3416EE1C73EE97A864C4C1BA28902A92A821ABCD2789E5EE171B80DC34D53BDED4013D3E1F3F6BB18984ECC91D63594BAC1086823E583B71540D5CDEA0212D508DDE1E82DBD7A22FA4EA2663FB3AFC73F920FE6126C8BCF2831915C26F0F9CAFE8E70319D7536CAB72AD4BFB4ABF8A6AD0CCED3CD1153891F8F5D5488214DCF0E6702286A5CC40E75DCF775E5AB4E8596198D64B0082200A6DA8E6173BC97AE90BA6B03318EC03A717EEBEF120A53ADE0C1111FDFEE89696A43B72A87357D51BC197049493F56A7395D5349718C445E0515A6F11E53B80103B4428825F997C4C85D6B666868C397C22F7397FF8D2DACDBDD242F0A45BF277FE8A20CD718D6ACE542C69F29203B2934A136CD7B37E9A5C119A0FCA68D078EFC9486A381F848F8FCEECFE932EEC67CD9CAAC01D4ABCC068C34051011C39BB52BF97DEF9D14F3E0B30B79373E75D9C639B2C0423223886A8413C875E8FC0466260E5F0CB4F02FAA0CEE356D16402A44A9FE1C1639C1B37B0622EFCCCF00CEE8689F8758BA83C455D8FA03F5AE9E9D73E08786A7E47D05BD671990794608A410D3D3FBB3B40ACC209600933F7F1A8496AC25C5631192BC64434B6386B45A566C39731023253999B5EA984AA0D148F8CA9044C3AC64DD93E40720FD5DB0B6C8E0A1648877E524EB6FC23A30A586B38530A9144D7D3B07C0B1EAF55810A96BE02B3DD164568991EEDDC20EA4359F8EE95F3196C9A0D206B215BB0209C402AD7E767FD0247012B6D762B51F83ED1D8BB3F4C96ABE27E25FFB6241770D5104A3FD45FBB1B15373A2B9EFBEABF0DD68F38CC8531E680FF37A383123A812DCA6961EB5FCFCE0AA441703216AB1921A812F0A5453A3E71359FA32DC5C056A86D424A150C6820C7357D07C3A21C20A365694369E3EE70147E6D5380970388AB05134F374E7E8AEC7BD494B54FBCDF891F3B314E6C5BBCBC7A989396549B9CC933568082A63FDE96B7B0C49FABEAAC1104A81B33CDBB018596F5772D14419C407440A0FBCEE3323B6EFE096EE052B2F1C5A8D8F0DB100AD3524E66D87B4C94C11EA5F25EDB72BADD99F743D78F54D4FCCEF279A903BAE5669E7C6E88C1CB33B1D599C2B54E80E33F51DCABC176A850C0D727A4AEFE6A5AE05A41DFBFB20BB945B9B980DF14AB2372A178145D9B40A77D3C21947A11EC6B5579D76172F385B8653A47011E268CE26CA2B59A6AC0D3B8BBB3D2446B71F38DBAD8A66BF7", - "rnd": "79B16C7039AA7B852BA484BFE318033C952945E279E72701FEBD176D2EA4BD58", - "signature": "710AE5EFC5E9C10E83B560B5F5CA0965C9A1824EDB19895E210F0DF7FA095E0074EBD42E07ADB3B4398FEFCC92897CA17E059ED35539CC1E4B8C2314CA0550E5C2284E4B0915FC852EF490FE1AB6416D5E8B587960994E1BCE8C10CA7E7CEE3CD10D7EC891F96F901437E896034F13357540F58B12A8F31FBA1B71FFEF900BDE1994C06A01B4BFCE0AA0B275F4D5F9411AA13D49FF692AA52BE503C127D46D7076E5919F553321871DDAE309CC67DAA04B557385E5F2EACF8B9063547C53D8D9EA43EE3F9BC22C8C6DD55610F5BAF34D566F860407DE3DCF1751C4998E2C06E96BE7B8D461D0F003CE8E7A8774232ED8240B129E0FAFA27E859A5E7C8A7180A27D61AE58AAB7E716F7A2E92DC07A8A5E468BECC1543AA13A6D68CFC6B92E2A374AE6AA5D0193E1518D548654DAD993F34B3A44B8FEA2057BB566A086714311BDCA61EDFE3989A112F469CE7B8C1AC8EE5969F85D9FF05CF11FC48C97EF7DE78B3A3E72275123F9E1AA30C272BC4BD9FBF531B7F7F671E67AD24299AB679B565A344D38F4A78F62B166EA53588CC8396FB80C1F2D85D885307DAB91D51EB5CBE2671FBB0D3B48E1521A24907C13CE606EFAFCFDCA6D3BDF08F65D98A75D0BC874031F5FB767D03766BA680970639335D3355256C46D3A421D06B8A111A1F1851BEA0E49A6E4970FEC0EBDD420E82C864AFF3ABCC4FD011188EC170F006DAE9C3859E191F6B839875BD32B0E5F4C7F9C7263B56E4C33D61710FA61DCE629226B0B9A66CEA92E046F13415CE53C62733E33D4EA4AA9BA487D98F3CE16488A9577C0A3722A501B3FFCF657B524B4978A58180045C0AACCED96D2A87A931D83FDD411C1C4C091A10B609BE12C136EC7DD23EE0236D344FE51F3C118B56421A640B10DDC544E977A80D40C24044F13C8F1F4A28B0D7E3C0A9C69683CAFF27E5D80019EBF49BCDDA4321B40891FF3E5E82189908A248E07CF9D2486D23D06B66F642A5A4197F5F6A7E697C0B94E7C9F03CB8AA027B68B5D78B39C4F24193DF93CEC3909799932103105257178F492694A36533778EF74F685365A3C87F7D26E4D07A960E837E23DCB53F9FC9307C72D86A6910C117EC52A81E222D889F83B41C70A811AC7022A5D45245137AF8016CCD74562785E22A0C6E024DCB386CAFE9C57F21CE7653D1698310D856B2835EB80F72304885A13C1A08DECF70A7FF676703DB0DCBBB65452F01FA7D0DECF9F3814345D6C696D8B2F3EE2A607B943FCE6417F8A85833D48897A1E0A48FC862C30EB704EE969344F468121FE68535EA11A4A3501C9101DA1DBB0A04E6DF60D1595A76D4872AA3387EA910BE3296F28385E9666625E79B04B03E02C737A14D4D890A0333CC4CA6365577150D32C8E48B57950928552ECC61E857015CED476FE7126464EBFABE580FF7B481AAAFC0DB0440F64759B0201D0D58A9DE5BF97FF01533DFFE5808B3808EE4AA3E852FE34F3CFD025AFADCC3F6673E0962ADFF96E2B661AC311E3363127A69EB4DD86F3FED96F01EE82D763C2AC5040D881A710CE3402DEDD97E450C66DA7D684946B9D83C909525F347123CE76796AC6D02507B26C8B0F87E81BE257436EE43D5B1570796072EDDDCA3EA5D3E1BB2AB923E1E641B474F29F7C6230058942A91BCAB261CEF1F73368AE7237494EBC6CFC6BCD43D2F0F87499BAAB45533665BB22AE2FE48B98E4D32407C5905483F0D3FB8C075B6D1FCCAF2C222D7A7F01D7AA0097D7CA24A10E4BE41E63F64503CB225193C2E8FE3CEAB16E8980EABD2202DDC190F45743075AF1817B9CECC9BA576692DF4BEFC748C4A00401D4EF0537ED7B29924F4F5466825C260C716CA7547976729F534C9EA8BF91ED957C54829CA6AEB8358EDA49A7B9D6F4C283DF5203350E857099F3E8F0C58D1D88A4DDB274F60B98D3F97FD064041FEFF037D06B450F346947B32A73C07ECBDDD0F155AD53B2E467B6A796470E998B8E2D599EA74991096610B604EC33DCFAE5B7B09871AF4C8B12476830B1607475C686A2E7086F09BD9D3D5A347993CCF2C4CCC4F5452A72B46CFA1AEE7F5199FF28E9533BA06EB599AF219371EA6FA7C6450CFCFA8DB1FC84660E9A04E29BA4C0A3B70EAF38662E1554D2788D4533C9CDE1268F8BCCA9464CC216D24A477A26443345E037A24E452BB078E5B11C566ACDD7A8D53CCE9A86AE68656C96A2887548A8A1CB4A6EAE2949EAC0D18ED253B57DA4337EE5829383E31274A13E608271C20530DF60193EAADAE38C10E274B0E2E62F13BDA3AE60B482775B423B8F2B10ED86B8AF4FB56023AB70EF07A910FD79EF73D829CD096C5BD599C2F9DEC66FD018ADDFC2AF46189EBD00C3DAA0379D6C69A8F407FDD4AA633A43424DD9B564524CA14C5BDD96B97F5D66B6EB9146E0A4DD9A6B258525FDD4BF8D07949E92929ADC0E77FC9619A9F32A0A888E23269AE028855E54758FD187E29C6B09EE1124176849E6D55C22CC7D3254A3C15DE5D26887EA5A2B6A1B951C6C062D9B7DEE29F2CA45B54E19A9BEDF9099536208D1FA96B83AFC20AAA1A78E72F4BC3EDBD88A25E021E3626C462E411B547151DDAB86194FC82AA21F20E313804D592E90A7BA77D51245582C6BF608332E4723410E5A5899235050077EF590AC4D73EA0650DAD87339EC7F4B5C0D82E0B560B41437E2E52CA013D5F15F6B9B55C5B5EFA3A8D58275E2E705E555CCAF47E8631450171CFE1C4E7584D6717AF9C3B1A47C68CEE15476332104BDB15A32C6EA7C7048356582623A6EB2AF60B33806954E9CE31FB2CE27F27E15AB1484B7775C2EC8BB8563D004528B60629C8C326F798F2E35020CF0DD867B2778D7B59FA12252E19C8EFA6480ADE2635CEFC8DA37367B8B3F40920C47CA1AA283A61EEE06F66AB42EB9B4B6F7A9D4F01F2F46D6D759630729C98B01A20470D515AB99FFCFCE1CAF1C29862AB51C7900156AAF3998FDC735B5441ECB0F03B4DF0BF91FBA60F6D43F0CF424AC16F167888FF559CC3A4854A76FD93C729DD29BEEBBC992AED8D89B3892F15FB0089D8F50B3458A98CC2D2AF7FE6FCBF60548ADF5B7E100B6698A6222A9D857A5AEA9FBB8A691B165E3C8FBCF60912BC4EF6E73287751ADC907770BDF68B864BDC2D358AE8FC5679BDA17C57983CCDF77D17D9DB0933FE919B439DE354B8A36F826DE8DC453025002987BE4DC240318B6FC58A096A04DFC4900D01F4BA6A8A057D71B7082BF6A05F5904DE5D40F42E5A58EEC0A8EB0B08AE0D6D66F2C5EF94546C675905A6474C2F0828BF078B552595DED13EEA7545E1B48C07976EFA314B1D27EAA5C42BDD8D5B53C73984ED4786D2AD4E7ABE92EFFA0AB8B12A024FADBD09CD98330511522D819F8C469CB21F0CFBE2FFD1BC43A328B2FFEA52541FFD441B42A7550F179EE2F80997F2982F7BD4316CA15B29CCFB18B82FD46C9E9B3DBC7228E97DDC5C05AFE8D1EBD1C4F1D6D376A83335761BFE2ED91C297497F4A4C46E3C462219B89BE7E62BDDD0DA81367027DFB81CB3A19C5A7EC603B4B0CBA7DE96CFABB553A2BCBC763278014452114BA92850B2D254A72D06EFF56BCEAD95F73EFF3AC478DDD737F919C896AEC8D28DABB043EF10185534FEDA48BE6B2563BDB64C40EC4C964CF28E3685FD43F275CEFA3528A2D6013DDF487858D73FF137A1F7E2EFF845D13CB5C18BF3096778E160D0E547C22DA37529C5D295B05E11EF7B679FA0CE268C6B5BA28444732D0FF8CBF0D557CD0170D3B9F973A319BA3521603F940B33D4746BDE2B66A20E7A798430F136C6E330F8621E4BD4844951D0D6B78592F838D37B8879477018C5787A1224032E12252B243A2BF78F1C129E03AE8E34B4A27B1F76A299FDECDA1CD547A42654EB6C3F7C550B46E1736CF0F1133B5F534AE847B5B4CB066EC760BD51D46A235CEC1FE69D8452C396DCEF30EE40976F43288A8D0544B5423E8E674F3E7712C0B5E85BABFC4E6A946F356E9933C7E0B422A47D790E076E910E88C286B161A33D79AE5680CE754836F7097A895C6D0EB67B116A79DDE2E15AEF9EBE6A2D717B3D82060C4B6CF8C8BC4DDA37AAD2DA23463A45787AD9C50585571BA73E3B3395EDFB041B5B7CD8A3AADB318D6E16DFA971EC2B97D816C3FC0634A3E08E58B81B2DA020ACDC9E560966F1144BBD2E7F981343822ACAFA69D4CFC7D50BD9E7D97260E00989FDE885EF10CE73B6DAC004E9FDFEE4024CAA2D58962E25141287C8967139E1F5636EEB141D26F9E70AC55C4B628C1D2D876949D3871FF995C48B1F02FFEA7294DCE29854BB03FD260F3E32700D9929DE7D39FF0C7170726108E31874724AA11EDC707C24C1D5F8104D31362021400C91D227178EED1660079DE10B21E8BD2C13982AD09312C8C89710F76CA4765F329CFC227B64DA61C950967D4AED060E4F53613BE363CDF3B2D60AD446DBD0E9F5763FA76990530E57601A4A2C5197977196F8774E06CA7598B48F05F37CBA59E2FA3D6B6B5AF6FA36232CEBB179A3D3BBE262C69C43C85856063F37A986F12C86834B4DF4C9E4F7FB3E8D787B98D7EC11018FBDE3ADF667BC2CE6C56A1EE5B0BBD1128DEDA1E733D467280E6380ECAD8BDFD66B004D0A080230D2CC9E7937CA7189BBC91E8A7C1BBC843AA2E523A9229C62135FD3F5B179710B97E167068E9FDD6CC3DCC66D5681801CA3A4AED14E166FCE2B6C594EABF4C95D5B1B15DAF33E1CAB2E231A2BF69C2C512AED6682925E75D488DFC2C1DB11034B085210F95F4DBC9D80FF97B968A17482A57836A1DA3683830C134750FEF774AED81588594FC9F882EE528A02CB4C338119F2E4083B48DD578EB2F9A94E8FB56B71E361BB3E08659F5455149D9444B0F37E65460DB7D8A23E05141BF1882F870DBAD3A9244D089088940318163FD04D32BE892983EBB97ECC8C71EA2B8D58C705D7D7B37130D98848D279F0DE1B3B40F0A09A9C23E8CDB61EA306C6E0FEB11D05BB5A21B53103C531B16D106C1CCD154CF4D525A2A8D4B22E24A515BADB06B075BD293C322BEBDA1B16E88A1586085972035C1A70FE7DB3A606F483E08E2C783A089F105B55F1454B7402298C051FFB138A369A69B66A2C531303F686A3E3688578EFB4B67D4BD956202FB5CFC5ED5C8A9598B58E6C2DD255674EF9CB95F5CC2FCF8AC7AC82620084C399B22E9B208EF4A7A930EA419899E5B6F01B286A3F401598D6A3E0491CBEF9CF76F288C52D5316BDE8B81B25AD01BC3B8F8D7630ED38F0E99BC12BE21BEB227CF34532A4F6101EE946778A82D16F1AEA580F323E9E6901E26C631F1A1BDA9F2D23B80A8612E081598A3A4665DA6EE7440E59A7B18F183240F7BA20762C1E381C0E13BB14151F6C9BCA5606F120C30F883AE5D054C6B11BFB096E319E43974C67B0C335DE06351B72A1C23381101D5C409B223300E1E9743064472124B560EFA5DB460F2CEFF0FCA7888B34E0397A9286205A102DF324E844946FBCE1FF6E1F8FF0C06B91D2544275A985690102EE9963A87174FAF672B71839C93BD323A224005FEE75BC8184C8C873FCF438017BB30C0E5CFE875DF92D3B502B896E8671ADFD8864685DC7EEDE73D0ADB04F05A0E5291E7098E2FE69C3143B9DFBB316F59989B7670624AB87C916B3422AFF08B1B921A1084285C201FB09FC16B8209506EB72ACEF64832840D9D52792353D02F10D14FF4FCCACE35783560FC318C1C7897FA031AF1362064C3A6E1F9759923D148E9300FCCAD73F7652A7B8A61DF62EDF20E6067246AE679822592A673D3DBC14BB5176BFAD02FE61859A36EA4C9E78985A2513ECCEB0FA19D34354AF9FC1F7239F68FBE87381EBED55B9F413C0C2E330E3DFA52B1AD1BBF6054CC81B6ED46171C8470EC64B9A826DAB0C038EEB91B0ED5EB666EE2AAD904549BF677987707A2AD7E83B873E60D8B1CBACD54235A240840F2E2109C20A10AE9901BE5642ADCF5EC18BF47B5A7753E8CA5CEA7348CF666CD03F75DFCA3A7C28640693109C48C0AB75635830614C8FB714D926AA560C8AF47AB1FC2149E761BB8A4852A11728AA4B2EDA24D7D1F842CA51F84503CF919C2177D3B5CBBF2DB3EA61B7365FC80BE7FD4FBA8CB4D3B78AB6C5E94F443FD30B834FF67574BE205761368E23B0BEB460F0AE98F902A2923368A1A17F5CC1E1375D5B6902B8B369FF19A9E73833D2F7AB1A9BDC14E997932BDC4DD7F445586CA6A0D03BAEB73FA97F43228B33AABA5ADA5E339F6520BA1793A6AD17403F848C4E5B69C1FE1BDF0FDBCFE2095D28819C3F151CA42D34CAA187D10D803C06814F8F202878E836F4778F200CFDE3F760EC93674957CF8A9219E9A904A5F6B4A68F9A58B162E7BDB940B317DCBCF3291552B5F779D9B917D93F90708CFB00E95F39A9B1ACB7D7613D5A3F835A93D3B660D8CBB937DB642033406324961677A9BC7EB03070A3F4375848889BA151B242941585E96EF0A96C2132B596D77A4A6BB1A336071A5CCDCDEEFF6FD0B2D326882B8C00308143A5C6F828FACC6000000000000000009131C1F27323943" - }, - { - "tcId": 59, - "deferred": false, - "sk": "9ED577180D038CFBB5D937D2F2EB60674F6A6E3F49A8C14141E0C0CED545F1C857B5C70C1B3D7489F693425172A1EB3A8427101EDDEE89C783AF745EAEB672A58D7441DDB7667DA21A41735A15845004DB755CE182588D21085E293DD933993CA383F96F215AF341F99201CEEFA881765CAB31A0B40704B2EF039BD6255B3BCBDCB24143004163100A53964D230961C496048CA65112026AC1A6419310900C214209802C820211D4160992C450E03290E386114A202A24877121314A51900843866DDCC82424B0209900905B20211C014101C30C103941D248820991854BB28D82828810052180B2881895451A3109A0846002142D19C78DE3388A04422A618630E1040E09A42D24021203B704A2388E40324581242459C071CC486CD410504CC601A1B00492822104B1211B430500856903B0715CA66804A38863B069084541D84466E2C629D9029101944508190A418489DB3846190265982224E30048C02485CB9224D29441E0B44183A40851A420C3344C53288CC48091639221E4982C93C208E49261C8088411395293340640902109328D93906C4A30011038040A33905296890A45251C8291E4182423054549A86862180113345000B10054047091060192B6904B2801421449224552D0C808D3C280424809628231D3B80144222A5B94449BC811D33091133402DCC28918B441CAA408D406811AB0501B98441A01919A480CE4382019008860A06859A68991062994024A19B725503609C9B86CC1C0000B078E1B4642DC30295996695B087109202943963183948093468911C911508451C2160942C84404870CC3228EA020902144889836721C44446190490A298A0C04089C348D80168280929082B00DDC10651B970999368D08B7081B228E1A218022040C8B82911B43851A248A5B12861905250C075024426289262D42362902950449926DE4C22C410804D19689D9B4651218800AB925C248248B022514293100B20D11A5100A8750DA4462238831C2300C220021CB402A8CB0410228829A848D20A349A0963060142DE234880C33819092448908040CB500D3A000500648C8322423A790D044814488410804241CA72954B8115810406132252000205810650A168241B0889A028699886C4AB4905888849C8651CA4032A432924C260549B6894338810B874042924843A4215998602022081A27108B020A934041CCB62D0C072619154A832869CC8061E4286C11B9904B202214C681C322094C1661D0002419416142342ADBA28CD83861C0244018268899B28021C66199C44DE0988C10A68418432E43924958124A011180002509A3384E5B34464336484B184CA4320804404003836C54168E83060E1439425222911A91411106504112869A442D9282911210401C1500D338614186310A255200C3918AA844D2B020A1420C04800C5C346D90486009A0040C2929612000513472CB402418852111288DC242461002904B80295906610C284E61388E11262A2003050CC78DD1203203B429190891DAB20014A49051C025C8142D9B844084960C62904C48164EA0365014434DD49230D4A8441C21114CC47058A04124B66918062623126A99244102852D61244401326591A024014690203461849830E3422D5BA44011B54D58188C20B669C3980582842003046A191902201542E11449CB3608D0046903C92988A6111418305C80645B02866124004A026E10B54D4832051B26240C93011414640B488101C369219310DC88002246510B86619A288C22902413000D24347201306E4C82041A41115A828083003258B608A3B22510934C19490188160D02078A12A3501B8765E1C00002C290D3B2095C0041084908C206248C12840A038454446550B4416136068AB08C08108A13A2091439720B43711AB630981872DB3850610869DA2480013885A4284449C44C630888120870DA103062A46C18856588040A994481E1B6315C9671DC32124A10711A41729296451C385113810DCA3052100409100612D8C6042182401CA05098122611129001856804254E19812C63400821800001192262B86D00158524268D53804913476D02000813A18CA3B60D119164822625D1146400188D0C188E89002662224601364950C26489462402B2412037259CC420544212A0280993904D1B37441B16310B482A4C360CA1448909913084380420976CE4466084B86D026FF2D8833263BA2BC2C042E32D7B42A4CD80DB7DCAE277EB729BD769DB28FAC30614F6154C726CAC689FDFAC54AB29B5A80E36D7D9F5C78FD5BC62318F0EC3D7276F1A6FEECE174A39AF8F02351CE28EA3B491A9CCB6D12CA74F5B804E938509F7899D6FE154F9AE31705AE6190ACDC6D75E1B26A5934C90AFEA03279A0521F7242A08C182139DEAEE9297AC0B0FCAD1EDBFDB058A9D87FAEE004E4A05B8B4845F9537DA55244173820F5D9930716A3EE9A3D424A37DAE38E6B57FA7B2A2E84A0BBF112C0C79FC74785E46F6E94C0976BE3F2E80F00CA1984943E6E5DB90C87F0D5CE2791268FD23D26EA0C7D5EB046C2829B4DB162B8C0499DAD53E4F5714F5AD1F119EDD7B7F1B9DFEE77ED10768F35477CF9668EE0277224C7B99A93FF7A9C86C99D28E6EB7EFFCAA6C4311F80EB782DD34CC3A430C7388D32536AC05DD512FBC4C9042A1EF4A3EC99168DA6783E4859404A5CF350E18C76C5F44C8CDF6BAD1ACEA182486CA2480E833AD200BE8C38DDA71D9B9F4C6ECB78E0FE37551B34FBBE9B5FAC4D11DBB64D67AC0B597BF1194AA558182D6084F174BEA6A9DB366C60A3491D7227B50EE1FD93DF7DB3D3187B0E3903A76676E69FA90AB797F305AD7D169C5B7831319070688BD2C5AFDB0DF725704F69EE41F9423AB25FCB6252C3EB280E5B46AEF5B3F1EB11A532594BE3408C063B4E6BDA200E30F2012F5F2B5F7AD09A2C840ED8B64DEC8EC4C627401DDE05FEAF2EAAA181093A16B4355A8B7A9D75AEFFBFF36CF1F3DB263731F079DE31E0ED09A5B2E74E6FA925FB41E803071B46749101E395797BE9620910E17B3081A2031DD94C1162C7CED02A99E9C1E8FF157C5E2BFC6CC14E26B8AB9C35789BCE965D5EFE319EF4AFB16712A8B8407A64281BB0B4053BDD0B08ED20A7D347DC72C615E1004B3B3776EF9AA48481B64DEF0046598DFD413C156BC474AA2EF7969A3068D348DF5B74C22470C9323DAEDB55F76663B43422BB4E57716513286C58D4C243B7553F1C8FE892A6F11491B98BF6F5FA8FC93E4C915F3DE618ADE54DE1D8A1A7FF264537CF54ACC5CAEB0ABB56933BBDE2E25F556067E778417ADC6C33B902C473CE32AD2E5BCE0E3D978141F5E7C011E0CE3EE5C51AA77C56E22C6232BB8C9A9F80968301B69A098FC0DC0C3064288B93717820456FF85864D568D3BAD940012D0F5C6C4132B6828B30F21E9E1389DEC2952F830356014C98B883788A6BA6A22D5E82878012FBDE9D717A1B860C786A189D77BEE8F443CAF8F6C851CB17726A4F490B97F938338F9F48D826810556CEA4EF31DD58FA2EB97F2403D17D72C50B29EC13B1849EB3AF77D181B13896607F7F8651EE625E670BCEC55E05C7C02B7FF38B261C49DADB033E4E7E54F8845A81703441200D6D5969B03BEB61960338892B3338F5EC837959B6CE687E168F0FA2018458573A89A27BB5BDCAE5D70A4913BE8A652EF9896717E0B184E98E517FDEFA1B8B0BDD5989549661FFFB2CCF7BFEFAB3422BC19AB7C5127149941F9C1AB04170AD9E5A197671F136B2F2C4BF4F0B21D9B16D35DEC11CFE0167745787F0C92C252307B342BB12DAF5564516AD3EF3181B521BEB76C3356A13B6DC00B0B9536463E72F5B72676A2BB85BB49E9745CC87851C8C778C90CA1FE86D44D8136C3BB25034B181E7FB551AABE35B3ABA5F96BEFFC090123295B7E846E63D121DB9DB2CABCEC9606CFFE428C7BB3ED76BBD1394D3C632CD7CB2B7A533E506A6CFA69F141186756D3E23CAB8DE30CB62D08346BE31A9B778E4441FEA8D2CBB994C514EDD843648E902F7A6E2BD9FC715D19A6D5526C7B720C2E7752A9FF1693DB76B7FE4F03FA1E18B5F22FBC3997E9D724241B8F0C33F81648C03056D99F3D94590C4340D65BBBAD06F8AA090A8ED237281E4392B853BCBEFA6C1EBE1EB0BF878AFF12D383E9251273F75EE7831186B3A74A93E295503673F26D3B91504CA555020E950DE527EF8CCC1A5D0B7EEBF295ACBF008BE0E46B6A81A3FFC48D3B74B5F34FAF059AAA65D4B3324B9B6E0389DA387AC670357C53970253B76171B59E6D3980CFC62C0267C3E572F4371385AF0719B3752885A1066CBF5C1600AB3DBEA291E0BE9CBB06FD39B5BEFCF9FF9D953A745FE56D5C241C7670B6D89913A732899F0C36242B877907C7C736749A6BC462D875E895796EFE33913B2AD7BAFB93A07D06BEC8AA613A2A4A5937CDDC2BCD504597B79492F00366A29E0BE581C1ED71D2614F4C92490D9A9D4BF43E32DBC5E3A32EB81C6F40143D14948A57DDAE7C777F9CFC3F7F4B397FF2E240147DDE7AC72F9661300BC83E887C3D96FB74785C2D549A1016C638B12248AD5B4CBFA4593F3F8DC65ECE7554C7361201C8214F82DD9CE4279A285091B8CA5072904E56BCA0B9357819438C3C7CF4C37A501AB16344C623DCB4E71A8BF598F31A871A58251DCE6F3BAF5F341AB0BAA5E21CCBB09F52130BFC1B3099ECD91DA824EFCD3CFCDE90414A09A15AAEABD99BD991D888A43DEE1AE8D8CAEA29D916904DBDD6632B8C3550B0B2BAA5AD06371D6093AA18725C345F88A3FB4B7BA1DADCE711C292EFEE8FAF0A86672F3BBC2107C70AFF0C535BE5107F194988A98CAFF84CE790EEB7FCB806EE378A299AFE9CBCA8EB36DE898E114371BC7BA257270ECC127C761E937B8147C328433874A9FCDD8EFD08D111B80FDEB62C977EA4F8800FC77DE54809ADAB4BEC652E743CC868165487E998696FC55A5326379169B868FABAE53C3550EB8E21AF1EADD927B62BEA41AC4F16EE651F2019E25A12FEE6A2C9A61F17BF567B72FD32D3DC5197B4847B8B7A0F77C166150F69C847A8A98DFD192F14559467B57A5C91FE84BD9CA2B55617915B3C5BACF423D4F79CFBFB00ACB37B5BF99C2A6AD319B86F004BFB569CB681347B6A9FA9D1D1EA2DDA71B3EEA66DE8E6605038997B0D63C20A5190ECC8521224BAFD6BD40BC827FE9438C06D3CEF5146262D7456E235F3D643D4B0A29C873D0FD69F98663849BCE83D464483F178116B91777ED37F34B94F20C175A84B6041446A711EAF6381367BAD9E78B03272BB2F6E882F71FAAF51CCEE79A2E8A19704EB5C7703CCDFF88076ACA75BA01FA886D7EA2DD63ED2BC0C1AE633374A37A353EC3645D03B5E650FD0BBF72F714FACC8185F8A1075355219791EAA297EA8E0234C3332544CD64540928C87F4498CC26BE188A2982D639128F3290C11D495EDDE51F26F942563E0F5B7180375519ED7F8CB6D2588812F03E1579CFF46808F6F66D6F4A6B6B6DA6BB7986CA65BA6409FCB059C88F0065D37AF40E0F035E9A1CA46D1FC682718A2EB8AFC1EFC70A72E8057DBC97DD340F43C7EDA96A0713D39A995064DC145216DF14A5AA10F18D42B4CFD43E2ED30054E26AEB1648A71B6F50DB7EBAE7514C5765D69EEA59760CB9A9FC1F724516349676DAF1E5DA679290D3827ACC54CD99577C230CEE8276DDFDACD485070E766098A76FAD35CBEDC6FC8CA084506DBC01F4C80F1C92CDB349422D7ECEE14CEDEE941F055C53C0303D140A8D710244A285CE38333F31CF2F93D3D67BB7B42F99546E91BB66C89DA01E30C214369822D0840FC598EC613724061D28D074E29E82452D04DB474550081D9E9BF581949E87DB10500F1BFC0F118EC0E2BD8898E15740BE4CAF0C1DE99DBE2254975BA7884F314A2EABBD36169322CDDE8CB6419D166AE8EB5EA45ABA08EC2E608FBD4E7BA4B4DF6438C5D90286E8B95089172B975A5BF5CF00BAFA076F85DB79ACBBDBD7A74A3CE3F62F10E658B177AC8A7AE9FC8ECCDDFB05932C84B8A9B4A35ED560D313CC738CC0F21D2ABE89FBE711ACC8ABAFCEB1019630BA0E357D6686A86959A09DBD6850E1C8DBA5E31E8EE826F2433F15A7389A01F1D655A6E30266045396BAD1C43DC0A816F9C2A940541AB7FC0F012BBE4E2094FBCB08BDF31AB5DE962CCD92D876A4A28041067EDE706763235188DF58E18C74EFE3C0DBCBF190EA6186F48E393D2961CE6B848C01BB17191E04734F57D41E4E95E47DBD268E419199EECAFD57B3B97F7AEC98EE3A07B27BE242A9D1C1C59382FC1847E071190AEA2C8CE760D56CBDF3A7D09744B9F6969EC5D2092C14E733CF028D1E09046DD5607DDA5EDABD55D04233E17F50D78595BF16ACDFF44015FBC8BEBAC543556EA13C1954F793FB2440EC674FD582D93E1A68F2F129772CE80DD4248068F853D78A70B66EA043537C72F1405168023DBBA7D50E446EBBC4482F6491A793E4286E12868603E38B0A8FD563007F9BE3FF3B09DCB327AA3E88CEE3D85E25DE06D416F8A1F8BC7D009BE1933981ADC93B7759D15940B3CA8B936F27F2076319B1655178D833FE47D86118A0E6E142300111A4ED69A531FF5FD470233E48D4BC90B8F475C69BFFC62F48F8A4BAFF33770E54D8F51AA5CF8ADA4D485CDC29DBB4027B1D35C42DECF1D0A874A9E074812CE4AC3D3EDC0494285716F62F7C3414B1113057A9373D55DB5C1939BA63B4A48561834B25FA1A2D2F02E3E32CFFDA2D78EA0A15D1F7B8A928C536A9115B7E70A9EB47C46CBBFE67D387647074ECED0AAF66EDBDA8FADA3B4C927B9AE214FE615806892C7125EC1D00F4EB624EE5E8ED825FEEBEDA13D98C977476A0453B40DED69A89046E9AF4E4B909F805A5692D6F4E9425338A50138A76963", - "message": "AD01E3ABF8862531FA9AB236A880738404C34D41D087CFBD6D8C6A873A19CA4CD3F7F56C44F7216E9AF3BAD41DE70C5B8AEA89873751F2A36E28A31AF5C024B56ECF1DB4DCFD6E8D4A8593C22A3EE610A75F475FCF391CF0ACD26AB3856CF42DB5E51203F8B3BAD24958C154429E75D9DB2887E9EDDA9A81D2156897CFB8E60BD9D561A017C2392E48353969BAEF0614693A6B6C78CE0217852AC631E2030782C27B4348B3DF13479400B8F0F120AB98474A9BD73BA9871D1D157F2B0ACE2F01262A8966884D5F0411A61500EB202C0555D00011052DAD4CE2CB9613E325EEAA00A3111E250169485BA005E9F56AE8B4286351F87830A53749AF68F195BBA417900A6AD4D45569A7C97941AA65F7FC4ABC2CCE883C7EB46B78E6748EA832C19D4A6BE0F1B4A5E0F7EC8E772D9B1D1EBD3E11235758EF8270FC1F79B54D553541A7DDC783B43A5BE0832778BFEFB18BF19BC1E4DE73697A11EF952C1085641E644D66DE270EB97E22EF97C0D30171052830FF196BB982A78604D63D335D4A7844FA7931F4D9BBF0B42C9D601BEF7FE82CC8895BFEA819DD7E5BB8E3FF6EABC04FB3B053E99ECDB28BFDC2859701033EE7D5ACDE1D9A2BF44E63CFC28B46EE77B235621E2E67BED8A7A7F52A9D67404E1D432AEEE55DF5B1D2DEBAA777745981275FECD84F208211C4913C134CFDD2080A4737E5C816D69F0DB23FB079826AE3BB422770704B955428F205BBFC0364118F3429E15814C34FCF5D24E575AB03C94D3917B00F613C34288FFA8B66A5FC3197B45C7D4BB81DD2F237D1AD80BEE4227D6B61F935FBC6EBB1759975E7B686A10AA4A359CE8134AF334CABD54CEEAAC205E141EC4707D53A0D2AFE8067501E9E0C1E9B2A80E904BE58A8000B35D415B0F601C6065493C0A6CE2442D2408C583357E1A9629EA0C3CBE7958007ADA45F50FC3F0DBF847580B6803ACA44B5EB54D8AFAEAF952411EF03C04A7BD44A40E19869F8BE946507E10676CE738EA38416636ACA478E3CC849BBD372C7657CF785F4C96DC8CB4FBFA3F73CEB5D6ECCC37587B0F8CBCF35AA0631C40D5408FF1EF2D43C4051190BC65B36997D3843FA0DC8287BC6846ECBC2351B86D492ABF53D75752F577B95EBF14E346797916BC58D0656B849457494212BB8D63D0A59FBC2CD2BE8FED000648171C13B1890F77A0C58912D8D6DC2685E74FF57E0175DB2894DF78E0C771E1E33E4260CAED208208398ED9ABCE349BA5B37601CEE3449A87E6F0E21B17A13F9F34D10D7281EA0BE90ED8C29BFDB22976FA8081F71116C44BB4E2A4E91990E0FC1AC75DE7AB8626456D22D5A7904F6A9BE9FBABF8AD5A6682C8B8F8B82F790BE47052EB584E037296793F4177998D04BDAAD4522575615EF62F9BFB2E2CAF74BE9A7F34950D05604C111159FC50862EC3E72557A427A653B4E7E86DBE4F93B7D33BA20DC850EBE2F28889CBC91636EE9D5A4AB1E472A060A8478580E007F8C5ECEA60333F23790E9909DA54885E9B3A68D875A71570A2436EE131415F84ECDCED121A6440AFB712F1603286C61F41E988E505DCE4E5E8075EB0E2F6367A7ECB909073DA38241F7EA55A9CFD77F0F451D777CBDE408D7D50EC5288502E6C7D9E6DAA77BA61195154B3565A5236C459E7110152A408DC76185AD4E39978C2C4FFBCD3C1D1D805533A1BD4AAC695C835DFEC0122E35C2A622F8C5FCFC4537D295E1CE01A7CA445E833E4BECE6AFC02681A9947069210E1EFC7406627B04947F8EA4F96D8FDE2DF16F2A343C54BE1A285B410190C4C5768E4E5EDFD5BBB488B87BA0AB01D81B67833A5936E0B05C7CDC49C21704BD0F1F39A5D289F761684BA50AE599D09B64EB7245BEA0E4FF1C61D755413D065A939D14704666C38EAD41DA3D36FD1234D11D87C971985A2490800C9617A4A34388DB07F7CEA2B8EBB4E3DE19C5748028F7EFF9E4808F369B94E213FF5178728B5BA0B2B6250924CB020758A734EF07A37F5D0E892FFEE33A922D01F26DBBF30D8B1208CC17FF86067929E363CAC8C995D580BA4486FD9E646CC9B5AC0F9DF4E66A236FFD85DC243AA29487CD624F0448DA108F61A15D31FB108EA93C39299B00F646B3CF10A3A665E25CA2B7F8AEF21606EFD5AA9DEB2C1EF280A12C420796454B7F7C55650A38AFBB2D4DCE7C237BB2BAEB43D06EE780739B19D9485362922F2A1EDA7460AD0149C044921D5EC837CCC9F48FD436C16426F4DD036753F8F34E4BAB97B3F044A64AC07A92D20D74509F802D4147B0DDDBC1D2CBB907F7C2C35317A092AF67B7FA0A3B40B2128336F2ADE4FA29174B0BEEDD5BFE6BEA4FE28A728C1609FF213599AA458D529EBB36C03DB508EA8235506920A0B3E501623F978EDF6D494473A7B5CF7D5F67B52B8E904000CD2AE67069E0D65A7CA7D6041709AD427D2C4B77C00BDFEF5BEB1526C39D478AE9186CEDD90B0CB9C0047E87A42A69748E78C8D51B2A183917C07C759A975FFB2F7B2F807E3CBA460267A1D945F7AFD861AFBE229877061998EA2994520E2062DEC37F5402CA244D9B614C2143B1244055CE84BAF93DBFAECF324AA38956A74F88E58B693805A7E66AB7605825D64BE38EB2EBFA5EA947692DB759AAB08F05FBBA72F78F95B3F340C8E36341A6ED6529DCFB338E5262C27F75201D2B4670C9CEF907468BFF28DFC1413D5C2029BC894BE29F1A795EFE0300FDF7B87474347E25048DFD303847C9F675918C5562BF772D949260C495CD5BF6377ED3C91F5452CD93BEE0A0E91EDD4264AF47B9F43B7FD0C0D7C9C70212E4E42DE74F168A2DA6BC4B8190E19037045E5A62D679B189DE87955DF7C5119E4F24A070D7EE7D37A43B28F943D3C2142EB79CDA655136845504D6CC4D2F69CEB58E5453F6BEEEA139BFB30DFE078EB553E38D6093C72CA477972FC58FB6F758482700D18815F7BB1730A292F5AE1C85CA66824588B2F5B65FDD69EE7906D1DB52A9BB1A8C581BD6281512897E8C81E085A9CC6192490204418D2AA3EC20D02ABA201E778FA12E97C7158F8AB637438A81550E4A308BFC70204ABCBBEFE3EBB8A0C9C1C216033694F3FCED8EBA234FFD481A87D7D870F47BE2347AC5362193B4A34AAD06358CA4082DE7BB2407DEA59B10F2DD83978E024DCFF64EBA0B637CAE21F46D60BE5FF0259E1E66DBBEC37131EF8629B2D0B5A810AA6C6525B1422794C279E8780F952239A4AD39409FADBA351B00FC33F73E280A6C7DF5E09994D3D85F068878F98D31ECB921F1F9C0158DA04CFFBA851A879A4BF2E2064181DB5B95A6FA562D4D0734D58517BA928A1AEC72BE77BCF42A79D2B533D67F2D63B70374B37B14AD884C1709F3E4FFEC3DCE21720F69F885500F11BAA7DE79651028BA8404F760AB8DFCDCB6FC0C033C347994AD3B90561E3B086B1427A1A964021316F7203466D17C5C036687348DBC23385C51437C782620DBB86BC9DC08906364EA89C8277491CBD82AB3B777FAF47335F12F320CC9ED9DDF1F95C531AAA610BADD822800F114688E5E0C6A160540717E9D7383184B40E6138AB93CDD2029E595CABDB76B7210A874487D4DAF0127995C72E55B8F3BDA7894ED9B119A89B00CABBC6B3D9F9CE464F803BFF2C3D5D4AE9B54C68D2CD4A100085C5350D608AC333A412283AFC3ED2200122F313CE2D4E83E721946BDEB4DCD3F1B018CBEE5762835FBD598BD1220B59A83797AA2E01C09E811354D30E12F10D9DF95D07887A5798DD21259EBBDF973BF4A28EDFB27ADD4EC7913645E04FA4754C055B785E0FFC37074A150B50882FC7594522A2984D02F971BB1784A16EE2F22C8616EB96F0712755171CC5644F09DF15E7A4C331C0FB62E0F278DF27514E241F894A6A6745BF0E18547383BFF3EBEA8A4ED5FF82F27B66E07E21560E897BC8AADCC94029942DFBE727C5BD27EBE112487768A329E8F0D8D973FE85419625DE11AB7F91063451E2F20FE873CB54EAEF0362EC24678D641A6DDF848B871FFBCFAB910212CAE485349BC0308E036EA85DFF75954D55D16F13BE3A859B68FDB3229DEBD273A2EA54A8A041F5C6A12244F36AFD793A4299AB8E04B4FD1F9D35769186E1A05852034B78AFE7D7015F73D8BB5A12C0EF9F4A144E343476FE5304808743553A79DDAF162BDD087456D7EFB28BA350241DBCC9E6C16B8DF7682F2881143EAEE111FF8C0B7E307DA9860B7FCC2BACA626E428CF26246739F5D91D4699868E8FD6940B6F21DA344CECD2FE5E0B615704BEC8AF1FA40532FC7111564FCB1D5097D416D113306B6EC5F3CCD46920D84B4C28D863EA2E6296A7B73BCA80903819B13C1F2646AD7FED22A2CD723ABCEA384BA1E677D4CE8CB6FA5D8E931D8E119375F781435913ED3290AD3276D55CF4364A59589233AE01328F683A33E0109A552992DF2EE3348194342A25E6011C1F34917EB3B7E33B3645266477EAA8215CC6933382E49185A4FE113BDD69F337A70742E2654CE72D88BC8760A4883292D01184291DA8135226F6BB9AD57BE7BDB5DAFCAA7D8842E0EFA0DBA646B87C5098F6A7C517A90293A1C06AA82DD6DE6452CE2920E8CB9977D6ABD2204BC512919ED971B3D04A7BDEFBD57616F0298CB1D1176B694A0B3A0AAA881F9387FE6927D76AC1AA98AF8BCE27733C12D6340FF63F5A2EA4ECF9FC50840A636C08935227E84C4B001FBC1BFFCC4853466BCE150DE41826DA265174227AD166A49F58167AC997D0EB41E41E66344506511C6731EABEF2B41F1E1BBFC9379CE42E125034D2A96FBD9DB8C400983744F5E62AABBF5EFF7904D42ABFEA773589BF428C45AB2A2B310CCBC62163B3C6EEDF0882F552F6DF7073CD8A5003B63B83CF1C87C777164D78DB8D928ECF63468F343E66260AF4A6371A036BF8A2F6BEAF5A9594BA42FB2D452E8DEA092DF973DFB63D56C255961953C6CAC2A45B6C06C586C0784342FCBC8B00CBBC24587CF1ECA7B754B9BC356FD2D8D7A6FF862E00DAA232762FD61B971AE712F7C568F22B7DCA58C25C46B8F7FCE05E5EDA17A3AE0881151683FABC356A139B72B422502137A1CEA3342681EFC8C660EC1B85BAB669D72A159A39DD4C6D9CE8EE2681BE5DCC79E484CE0D8522A6BF40613729D25301C1F472801CAB1C368CA0C959289F19279805EDE8BC885E59BA32354613C90E564216C5AAD5F5D257CD41466BDEECD8E49675003828951897AF5875FEF2D987D30C98360183BF9C983E067DD5100DB23021382F9BAC1AFE7818595A728E006E3B166669911D0A1CC610AC43170D30F0F9DB03FF51149E496639430B9075AD34711D8B0600F78D3420894439E58127BB23F9D02FC2818BC62C77611E412AA60A4A91C43EC854EADA0AC680DCEABAB0C7578436468FF7D6455C536AFBD1880AA1662EF4A6587F3F6A30502798C6D819876332A64BDC0C393F381CAE07CF2B2A226F57B504422409FDC01252B9370E620A5B2A16FBBA69F91B2336CA527D0F8C83095E9738D274B18A2E50A5D5275C75F26F2B174BAE338106808778F3AE385E75E78A15ACF0D1256275C53F3B6089A2AC2A688ADB85741D1F0B980A07E7374F6D9C165EDA08A06AF9F69CBFBB529C9E8A9F502AED95FA8C46541E4D5BCB1C0F358081C80F04320C555610C611BA613D58F3C523E66CCFEF5415631C14F5B10ABCAE7A2C9FE5925FB34697BD754EA1A97033431CD5D8ADAFBD11BD9153F542ED139614B353E160AC009AFC841C7D0111B6B70157E2D4A0C161DE1DF08192FAAFCAA43A86606860818B25E176AA1F7DCB124F344E951D915E1C752BC462FBC1F21196938A481350EB05A6757422BD368D9270FC53950C466E3E8299B143762800AA1433D09D004C1E92C95AEB7BCFD0B6267F3A9AFC6C064577309A8421F3B46091E133F3636CFCCD1BF8CF9B51BD9EC906CBB507D6B9E1DE07A74D99DD58076264BCA91A98D771DB771154EE4A1DECB4CA77DC2966291D3B0BCCDAE54873EE60D719A94E725940E2F51B30F3F4FDAAE28C860DBBB8DE7C1DFB1B73D9BA76F6A80549DBF4F0793AC8339507D24708467FA6956C3F2BE3AAB30EA9B7AD2174780CED77FC3B6D5177F8B529AF63917AC7A2B8954E3273D420017549466861FFE1D308995D0EBAFF1", - "rnd": "DAC193E362091E309A9D4E75F9C0F35E21582233045F797FF103AF70BCEA7DFA", - "signature": "3ACF457FE704AD0AB2D5A82A9EBB7D04CA8F75FCCD035D72EA3B7869EDE7909C2FE1761B025D4255C4AE0FCFEA24C049761293FA15F93FE6529349C06C6477D21B05FDB8284DDCA41CCD73D9BA9683965CB4D3888A7E4757EDF1E7C8F5583E4E19783AF6F168C5FD4418EEDF9A7739946BBC0EA95A3CEDBA7C8BF88AB720346FEDEA1938D5985DC4533432B03188AF57C00B276987E7783FFA05D9091D6C4EBE06DE51C538EE1D0935C6BB58FB06B4C9D26A39A9E4520E11D93FE4E522AF70CDBFF228994017599C92770EF758F8BA78F0238CACA1D5A10C77B57784642B6DB6889721AB6A2A9B65EF29E5618763D12D8C28E8918345CE6F07B8E71C174477A6E896046DFE5729110548A9550510E4AD8CB314A88753CD1509CE817ECBC7384198D1B9E141BA815E1DDD016413D90A7936F024164BAC19ABB967F2D195EF943F9D85042781F0615CA169552BAFF6AC83AEE7119D6298172214866FA2491E4FED12154B8EA166BCBD1D3DC84FD8E0473A5608475105F46A84568B361724295FB7291445C3BF3943A27EC5C66E35CA64874831A9427DFCBEB2E76D91C4C7DA1920116C33A41D249B668F30F3C4C683D86E5047B8B19A7EC2DD73D2670A8BCAB3F95FE665BFE5D9FD490E26DCBC753E6A50855060189C066E4695EDFCA623EB2409D51616518A5C711106EFF8B1CE1D924937F940087CE03063FE37417B74A510D0EF889E749778ABC9544014EC5C9EA6E30A9326BDD5ABD99996797693EC3707AFEF0B1060935C31C8995F1EE9FAEA306579F91D060888C57BA7D56B375224314343706B42B4CD0C8D21E8EEAC19F479ED566779AE9C93F5024430A899ADD35374068E5D792C710B6F35B07E9BF7A2B681FC82A5A06BBAD07B2D3B19F591C79E808D99DE67399CCE1146792A762FB2FD9479179DDE4755A7900E195499D2BEB6A8333AF96287793B47A49BADF98B7A5C3002A51039A6F08A8B946ED3E22026FC3C33F0762059F9B4445E67D8E8CE999CAB79404EAA53618230E2CC0563045E961D3ACA75368A0B84E4D281A14DBF2C51C20428D224FE0FB655A9B0C4CE8CFDEACD0E17331B5D872B96D893798247FF6D63A7E4768A1E8FB3FF485776A75FAE12D290B192F1480A4947C6341117068C23AE9EAE798D0A90EE82A2EE83DB8806EC26DDC0B062EE15B2765B68298AFC40E749475F1179DA174396D6338BD908250F854D36552472C4D7CBF4C20E0E2F47CBD421A97ADDF04B3B9BAC818DC9E9F1C8C9F034F5C0A411EB4C26A6660339582D78562C442598FD5B20A8487873A8E7B0265E74238030559A847A47AD7195362D82DD411496ACF0FDB82F289C4B7963F0C69E1D153151EFDA802CE9B247FB4A5F67C966F90D666FFE6E135CEAA70B772E45E68B4D9ABD8FE7F776EADAFEFE2E712E16BD38C67985F6139D95AB3E29FB6BECDDF072E391154FE733D7A7E48AAC0357DEEA547B001D121332C314A418A579AD8FA4345E8192A22751BC86FF0E6A822CE9772993967389FF85643318E40A3A4F8D66889F917E3615F29E9A40468C54D0EAA92389C59745DDD5B71E2184FCA9886D14A82D3D41C662E4B78F652EA08C14DBD6B4332B7E3445C4AE2251B0C40F6D445FF9613FCFB82F8D04261B9DE204FA93F955F94CEA006ED205C172D250BC6DD96821929A54D52C8196D59314181CBADB6F4C2C254CAA7B2C82D98EF8088D88462A2D697DB0DC75C099DA49D0CA63672EF3149DF556B81E4CD6B5EB3950CD8FFF37E94DCA7CEABB31B2795BB396AB8614989E2B787E82B219D55877D5F0583C43B86F2DB64635CEF15AC7BA53052A50AE39239D69EB3B02604E286FE3BF1CE271CECE732B428E54042000AA236ABF8F1D8834A51C5AFFEC3D6C7C273087B667FC69FCF05E5261C77BC7C15B6AEA59411E493C224D825EB89A675DD7F04803EAC12AF3F9C8A1E6C31421BAD74A288A742563E7FA8D88D51945CF13E769962CE7E7CC5BAE81587EFB5D8434FE6495A22133DE0543BCF23BBE48B3596FA88FACC83C7E53C3BF075C350083794649E9650DF5743BF521A120739560399C372B5DB8AF0FA188FA7A7DDE7267B647ACB3A2D4628FF0CF7E563BAB95F200945A58B97CAAB5309989E37366E1F1DEC6BB7BB717D70A7B55539923EC1090941A935C9FFD7FCAA86324DE1849372381BAAC34B01F5E61C38E660432F12FB959225501373D0BF512E88F202BEF42F92107EE6AFBE13EC37110864418C33EBA71A97394BB174953EB22D22C11AC7E3865C185A78A2F17C6134A7833EE5879A17DEE8D46D7573F0710769F7332238C7FC91A1C7AB2FCA97A79762E8B3E56113C0E1200142EB5AA59BB617A27C7626A3FDB3CAC899006E8B78AB6F43F89A8C100260895241BEBD67EF3DE03C3A52E56A58BF65BAB3626EB3BC449340C5FE83B071462E8F579A077FE9A332A9007D20BA429BF6FA8AF03A254C5991B9E6014FAA07C8F5E163296C8CDB48533EE609A771911C0D50171E366A1B9C237FCBB255AC68D7974460CDF50A5ADE6FF9C98313F93CFE3823343FF086979C7FA3804117B7882610EA1532B7BBACFE2C7924D2691157040232226624C2E10E5EE7D9C292C76F6B9207A293C1B17059B0F0CF067ACA10C141E53E5D49C2A3F5ED08548B67B93D073E775CE49D81393FD9140A88BC28E2DD36A9E1BE70F731A8C205F4E5377520C6F6D441380DAA3FDF63D7C3E002DAB0F7A078938C0DD65C7B9F6FB0E43B2D864C669133435E578825DBCEE29A407B826D925CBAAD633CE4ED040D612DA96DF3719DB9BECCBF53B67A6680BA0DB982DEF3DC956DFB7B922483E6C9B308850D24E5716AA891BA8B749265F52C6222DB1968ED9412F593CFEE021B118181340750AF176E080E7F7B3E0CBE0C63F2F2D0942EE8B45531206ECC088D9205CE5D26381F37DC3A96561CD3134BC9B10101D73D2C6D9DCD097C310A52C873BFB46D641663486B062EE5684FB86FE7F61DDD1F7864D4C27D4897671B2FAB2773A41E0E894D47357A3C0C9B7300914C3D32904753CA87DDCE8D663A3B4C8EB0C2563EB9C3F205AC09ECCF85F419731905E0DE587BA0C04D8D9E618AA0A7DFABDC9BB5640E99CE82561A094E4CB6BA66FC4FD9950736BB20F669261304A033B09FD03C0A452D434912AE33CCA5A66EB2BAA3F9CA781F26150D885191BE16FD4A93108343291AD65858A830394A75FD9755BE223A4A6CE69ACAB3C711E96866CBD1812514D4FFAD3436F098DFE7D57F8583C84768A402801E25326C64268556D0ED482CE3409910FDE35FEF751274BB4F719AC8767572C11723A8EBF7D6D7D246453577513CE8F1038505F715F42EBF846E825403D6E20EA5D12454ED1E2747A0F1AF4D99633A91BCF780E49B287CCD3D92E4A0141C0265185D75106406F7CC309EC08CA67C787298839DF87DC84DAC33837C535C70BC59A243ECDF8336FEE32F5118522FA93907BE3C34DCB5B257A54DD76B563F8A62A48D6AA8CA5C83FD4D1CC8161762B0915CE6812541BD9857F16A8F4B13C27EB4CA444437FF9C37284708EE38F15FDBC5247A8884FAAC95D9D5E82C8729C3463D22E794D232010DD26A1EA42604E26D1441146DF451903364ED1319C20B46B4D6849FB40F60DEC81DF061282B8B7E8022BCAC0AA53E51868B5558EC14F0B432A60603A29AEEC168BA38751B8E1FBF586F2A68FD667FEECB6F2FA11D94C49E7BE858A086430E0534955CE3C6C4B0F1FA75F42ED8E094DCB55B5AE4B334E1A94ECA4383538FA4D13A687F1AF3FF0E749416BBC504C05E80853A71FEBB9674FCDB22ABD028D3BA8654B2B5D71BF96D68B9358E14865B43E13F845C53F2F2AF82AE6C4A83C779B60A8EAC75F1DDF7F72F7356F8613FFDBBF8C11151B29474E91078119148EA7D2826E918EE878B10B9A7719955E27694699F2170DE595125A4EED51BC2E78EB1601491BB8584629C88B237AD8148374CFE9EC7C438D65D8BABA450C688B98E83A8830830A6768221D24027F6C932E0C006DA50574FD1BEA29A6F09BFEB5ED25B30AD2363D1C68919DA2D0EAB60C1FB15EDF568F8DB694325BFC5E16C7A4AD74ADC17F5CF4803950F56D5B2EA3605B6002693D2DEE54FC34EE67359E5408FAA05F48E62DEFE4E37E745884C5AD1054C68682A8F47E8BE71C9C4D8571023A9E0908EE02DF074258AA3246B37BEFA957B75DF2A1A45707A0E549FBD3061C6C250290691E7E3898163056D648A954EC8D3FC72522E4AAD76AE2C71B06594BCB377FDA1C16868D6AC3ECA7FEAD8056A5E762909F638D8AFBEED065B411D71B37B23B7AD7D2A1110F2F62785E32823E2C9A63AC14C00D6DB06F7CB985D77AB38A1701EE5D1688CCB53BE12C2F485E33DC7BFDFBB035CD5485E6189F7F4D996F4306DCFEBA0ACEB72DBBAEC07D15F5451C7C25DA027D405F50C1D051ABFD87D3EF9FF3E2BDEB037964A10E22FFE23864557873A8BFBE474AC2F12C032729C5A217435E41D13452470397D3AB01AE279C63253F1F654ACA822D705675924C0D6F273699A190B6E37B7EFC6FAA56A87FEE682EAD8DC4D230CA74A0CD611A3983A9A75B8B64BBAD109A69232980F235E0B7793B770949948C747531D92D2D2C9A5AF8509B44A1B6D1200086C952232674645E5FB7E170DE7B3862C28506B7392B9AB968FFBA569CEAA800156F07F4E6FD14CF2F486CFB289F4079A7F5EB20D8994076F2505879597579675CCD72A67ED19B5FD0AC47D495481732661D2F1B860BBD630C3EF573999287F7DA0993F1B68AEE9CFB124AB043641BDE18A6BAD7A17FA6B32C847ED87E6BD3F80F7B715E9AC2F9523F2019CDBC37CA2F11460886B871CABC6B156840F475366A8CA20ADFD7027029002F6848186AB388B9F374C979141C99D98CA3B28EDF9E6CA4DD5481676CEA525095ED2DF4FBF03D5DD26CAE384A65CBEF049D1848E4B32F8C472C8550334EC0DBA1641EE86325EFEBF7733E5DF9DF93538FF69798D825FEE376412354811C558036654DBD7FAF88F65501B8461680F588781C9AE098B32D1428D446ACD54847935BDEA49B9B8714F5ADFF34A63DBC3EED95CDA2DADE8E1DB4FAD64BA63233E7C2A23FA76A9E603697C3F789A9945F786D300742258FBDD4B48FF24041B82DBFA7F80275FF509B8DC571DD322A51F1E5F8C87A444B2CD0923F44199082429624535CF1EEC044C40E05EBF21B24750F8A8681502FD0C45F4CB7D1E74E26501AD42F4216B7802B24598BD946A1E93BB0EA2EF41A9B3879D6FD15FB450C25BCAFAD93F777E33006AA5375ADE104CA41A93599CCBC07D77B4849BFBDD79B8C02F8AD672F26CEA9BB5EF0B839DE5279C7BB6F1B52FD76C66F03067F078A0CDFAA3D7D3C73BD2EAE745476973E4BEDACAF9131989897FA9EEF30353D8C675E5C394FAFE9528B85F88D69FEB078B2E51D46952E7ABF1044321C0CFBADF522C81D8F182CFE6F9A236DF6399C9E8A78C956341B533062F315E511FCED297FC3E307813D6466340FE1C1DD3E5019B3B3BE98642D2C616B2B6C39CC1D7E0226E810432F2C3E36A4CA521E505DD27093C25E6412E84B90142E9411A9A6869C3F4841202E08B10872489B389613B80D24E6E793492A66EAC7ACAF36D982412F45E8F646D596DBEDC5E3A2A4806CE94F253717317B07B56B3ABEB2EA88F7191733298F17EAD44DDEA72B3512DEB79ABEE10738F3F7599D119925BF992637FFFDCAE9E852920DB9F9EFDD8287D19674329A967D1482F6EFD9D1D280635648F6A6E0DBF15D63B29E369BEE976496BEDB3BEF1330EDE318D7254127850C1F6D78C26E017CD212699DDA4CC3E081D7F60E68F76827262D2B7DC033B03123B4DF9835F8A7700CD171BCA68861C76A1E12A88668507EEBBB995CC59EE569A3B316E1ABBE8B628D7067D290515E50CA5DFF0B3E9F27CE6EEC097DA7E8CD4B52AC50D96250F92F946187A326238F17FEF842262045F8CF3FB6A51CD7C259892ADDC865A9D33D3096E1DDFB3DDE1DA1114D0335915C67008DCBC75DEEC2AB7593F44D26F840F94FA221402E3566F11A89081E7D87F4FE56D58C65FFCCE1BB149F3D0EC653ED45FD8A7B604DD94289D440FFC61581021C4BD9E6307B1FA2D1E2A9DFFDCE0907090705F3507DD9B8E2D4DEA44727630C51186E5564190A24F9E582AB3B72608CA57D66C61BA0FA0A188651249BCDB7A98FF15F6DABE4196C9CA725FA99D33AE7837DA4D258F76E87459423DCFACA5ECE7A5DDE57CC4B5DA9C2598351D5139FC9FCA0BA3DEA071A3EA5FF82A901F4E83AF628EED0EC51DB28C5C274272F4AC0EFE6A3C5C8C5E96D9399E6C414AAE650B46C00FAF61EF8B56DE33593738D8E23610E4325BE41D2D37E4F034C8FFA442E0A49AEB2FE81673A3A1B80D98ACDAA804CD3C3E9CC12B41BD8D92C69797B7CF0FD141556626D894E5663D5FA08157071A0A65C6C797E89A7E9383A607CB6B9BDE4E638B0B5BAC32E4993F10000000000000000000000000000000000000000000000000000070D12181F282D31" - }, - { - "tcId": 60, - "deferred": false, - "sk": "0CDB4AACB50813772D9F13961B5F51018335EBEE1BB801A0E8A0832E901077C302B0765110E4D4E6AC3653CECACDC2EEA6403F2918B2E7683B4508702A1CAB340F1AAC24A537DC044B7A7651DC8D222839F41F88D8A82667D8AE36815108BAEE95E01EAFF181BE89E15ADA2CCC1393FDFC696E0B2682706D5F4A1CB69E68D87124320E993872CA24709AA22D4BA291E3340D18164214896CDC38910344880CB28523C62D59080504456A19178C44362AD4C289E23849220866C8286C149380134051209425E1844463908C58866424B311E4042012340D12474DD2A62490340E44189194042E14080501C2448B26225A04484C8070D88401CB0249C810050C42521A2889CC081111C89119060812192000480E80489204C421C9248A6104651BC28121172EE1B211913609C9283183348E4200269984691C90714CC46564B2254AC48D1B072904826923C92C1B35244C1465C0888DDBC441D94825C1865012B84042C8200434041B4565C41006E1324811936DA2267000040E9B400690146800B5098B362E1B932D63981120185214212C5B04511C9729032090E3A84DD3885098226264902D204551D1C62C84268D0C258D80123002408E21334ED948084996011CC1891110085AA44D60042C9192611B032AE1166103A10C12A28C82C00942B8485CC244124421E3204CE32261C000715AB011A4B2891B85908C164061222CCC88815CB8480C256804A48C21026C91204560864101318C22124148A265A00092031582C106708B986862404C1BC40989862520C300010264C1420240142008038822478E9C8020D402814B1860994601C82224240571CAB85090A8088030911CA81142B80960A804CA264519866C1A816C90262EA208014C062ED3262699348C149481CB2462C0A8240CB62D42B88D18B829D488108116218C222A18B30C84C82D88C424C38268A4B48082A63114991012930104410044368C8A144981B2100B3000A3068959488893246122C82D5800699280241B006992A671500885004348049464DC80856320844CB20124312691A44061A425C1C261223012A3800C59301201C02C59340243048522C681D0140C501642431890C93402C1C66D8A160E11824103A264D9988914B16891984014A44C1028125C04814B424D12372E5CB07083208A9B226423C5600B362E833425098949584465030505223321C9B41081924D83026ADB364153C0618C3089D8B489048665214124A1B0699088810C4785E22030831080112308E1340D4B3201919848D184655190091A02029808115AC805D1862C0130484B10102130299C882180125243342419944CA03488083342C230690CA811230986A4C02814043102B20DC0184A844805E4464A41304A61C404928441D23269CC98004C964008396D5AB28941224E22124DCA4281042201134810D3204C9AC6259322064C26901A4604D4A2041A34681236801933009BC401D4922510213119108AE114261B316CCAB6715A200DA246284AA250C344311A45500943080CC62D21034908216803C751E49601D1267091084814064494B825CAC64D04B140D04060C3024900272504C880E00445033402403084E100709C222A03008DC8266C18846524C410142130CA4645513264D844068BB62D984889CC046513326C981204E3264908C561C8B44864A80C882089183785CB804D58B648D2168C94C8610B1560E2C0901017928AA40854B6084C4026C2162AA4246D51A40450A6101A3901D4806002B08104B500C006429C3625D840059A000810A328C0022101372D1A342E00272A41807020C02511B241DBC69199342EE3262C140666D3B00951C08409A02CD20020C9000ECAA20D0C88908CC2608C140C1A27881AA81063A085994690E3426DC8366940080D22A66194322513A94C9986008C265288B065CA48604A208208B1510B414651364981428293A049800044C4C8515AC611401045A08225A4242E8BB24012108E1A241291320501C865D0B6318C92211A4286A3348614166C12C10D049269214241C0A488DB380C91C42D8B246852444A0A4745C9201110324620940D5A20629A224AD0246409C8481C416063202460040C01C54082044CA30650A4C2804B184DC1446E1AB265D3148924394203A05021040D08058E1A1220490625A1186D0A211099A82562120E11B900CC240420A269E4860C5E324BB1C1AFD2EF43693324DCC483AB792B3D96E6B304D0222791D25CE8932BE83F480CBAA06CFB19C34D0B35927068ACCE2C8BEF8C8A923BC909137C869D424A09D29316F523A471FAEA4430CFB62B23F5A2A2831891BACBE4F2AF9A7F54311B174516FB251D43AB3DD76CC90E5D1F8519C0DB6C257E528E2F2012250F167338AA71F5CB2EDD3C06C9C44F6D5703742C802F3EBEA338F7788ABB53F78D80E36FDB09D03562CE51DF3C9B57D7A51DA38413F40311586600B33549DBBA8C8DFD5324CC5FFE16F97E5454D220F6B2D9FCA26D3D389268F28786A404594224E96B1571318EE7F27D3D9DEEEACAC882C38CFA1D90341A63ACED680E766CD4870F5CE929F551FF98B52E8162DE2A5529048812D1E590D0CC519018FF6B45ED47D4BE3515166B16A428CA56388EDD01B6F56A1FF2FC8E6729BD85E01085E33A12E27DF69E9E0D7218FCD71F105978F4F23E7A143A0FED7FDB510309C951FA85E666DAF2E336B94C47C5DBF08DE47CF2CF7EF30C9E3D667BF7E434FD1557855F5381FFB3296A409BC43092E9EC00D31A11092F63888B169B140FD845A728D6B659D39A30D8D37DAA815D697074DCFCAF69DE9085965D22ABBD711DAC1FD3CAD066DFCE629D79903C9AD6C1C173C0A909C6048601142F316C2A3580F65A8D96F546CC3E2AD915001BF6C66F12D415F303860D704A8FEDBB4B1127465D8427CB2D5C2845762EF33063900168DAAFDD1F8F06248A4D3848B5065FBE346905B5C96965D8535A22F22BA1FB2CBD4EE244B16A662B8352185A5F070DDE1EB0A9D72853643F7FDEBCE113B7120510F4C0303F0ACF9DC7C6D4E99841879701ADF806F38A798B50ADBF2B0AD42E8112A21B1FE90B4E93A1CEB6D953BBB19ED150EFF5235ED488F6DB7AD6A6C690FFA153B5670905B3FC09975D2A1EEEDAF44FBDF46B7E267BE0AAE8B94FB7843C5E31B4B3BA3CD6563BE68AA7BBA64E0C892CF7A791E4D5F6D2C434E082AC0B95922C303A13495E8047A8400B171C8CC7D7D61FB858799B09E315473005813554B94F8A0C4989EE8412A9225CC9140C1E4B706FC070D37E62D38B3055DCF1F2B26D84E373498C1A9C900DB1D556BC585C440D8AFAF057967DCD4A2BE1420F9A2331AF1C64FB25B79059792B3E8A69B0F1B33CB9EC3A9EF30CA1A4B75819FBF05071753957185274BA1535665C26B1E3C93BD27BAF47F705AF0DE5799A223DBE1B3D1F0444F1CE5D8F67F71FBC97FBCEB8AE8143634999E3C8B7C3D8D2D613D96CF8AA3ADB3DBDBFBB982F5863DE70B654B21C64C6E992EF1B1F0CA3821AE6904582B763FBB08422281C54DAD924BC8B2BFE14C87EA97A93E86D2E841C81FAEE5D6EFA35C049B58E74A06DFADB300D78DDE9FA06A26D1EC64FE20D5FB47BD7E56B999D21DC0BB85DEC6C1814A27640B8FE49EFB84C3D8A94185D82CE3DA91471870A62CF411686AEA06C4FC789FF5F0C2A37929D29952393C8C997BA86830B9BC26AAE9410D28E81F9DA87A3FDAD8B9459741D7D134BBDD297A22A4D9DFD157280586EFA73E2E77EE5A957BECFE8F01ACEF9E0E41EAC197EDB02071096307B8DA63C89BF8F56A14E094FA955FBD4B60EF4C704AF5B4C970B1C0C580ECD1B0764025655C20757E6B863F631151D64007A481672700357F49F57D551E3C72C2101BFF3F788FE00DFE3C8BC6A8CEE46A1B8EEA226E8327E4C872174D78ADE31CBEC003CB0A916B7514974A2FF5FF5E75066F33D74728B076F2DB0AD0C44085724525EDB1A0D9205D4873C9D0292110B9493ED361A33134B8EF16F54FF788ACE7CDE2DD26867330B87F47B5558855052C002E2EAB725D7508533B12239AA4DD3BFA64B09F7127AC953C28627CF2F4723898C02F9AD19FF790519064888CB84AABDAC48FDE34231546D42A337F38D3B11CB7EE1A42590584BBD75266F2E884E5C2553DD7A5684F1E94AECFA4716DD2E84ABC468C73B5C90D8FCBDA658F8D3E4676F126E4B7FA292D0391A6A53FFD3815D0A1CF5D6D58FC65F2E42EFAFE2EC38DABFF171643452B6AE1E5D79E4998CECB57C4C81C15548970C9F33536E846083E5BF6B9DDC803A57988978315D2B7FC74A2D87D5A635FAB415922EAC1EFD08A302812EB0CF3571DF982AE6546D35BE5844E110AE3C83530FAB2E80608082E9AA6F2E32B05DA5D7A99B7FFD6D87FC0183EF22347745840392218516B58A074EC5B8A3B28454D560011BF57E2D19175916FE6ABCC3A9196522C6C6D36DD39772F1246CB545432CA046C460A1070A65E8EFADB3B06ABD379D5BBDC0D359D20CFFB39A07D0905CE7B9C0E20D8E19EB0C630E16AA717FB66166223927DBB0E76E3F399AB813558F83DA52616D430D41DDC8A7ED70DD5B54F9BA13B5B29DB051558271BB8CBA9D01EAD2567672864A7400481799F0B06E832D0BC7D78640C78DECC70D5412F83037468D4ACC8C7809F54C5FA6FF73CE146A522A91A1A89DD44A6EE280CB85C43AAB4DDD09E25295E030D5FC66C2B48ECED1C32CC554DC69E97DFD3EF378FC099DE452AD76F67200018D180C2DFAB8550378F43DF30F605D25332DD5DEB554C934D7F1DD2FAF1E3EBE5545D38259D9FD441E6F9524327CE6F868498B1E13D98025162574E2F7DA8D8003C3779BA0134FBCA08A7E10282F0DBF480AD30AD669C5768F2EDDE0DDC17FE97FB7FD724A74C2FC0D19AB5EBBF762F708EEC805FE13F95E5CC8B9F87F18D9219FDA0895BBBCBD17397C130BAADC4752C575EDDC37DBBCBFAF9A894B90F02E2E1B7645F64350857BC9B11776B40B4F6BE8AE4779D2D68C69CE207A4FABEDD687E87502EE15E301409439439BD23306B76CD98F22F05DADC5422B84A1FD0CD6ECFCD9F53DB6DFB7FFA8ED87887C6060557FC7A664A6CA09B7D85790BB34482728ADEC89B1D3088A1D315FB30639F6BCC2B3E0AB571AD624BBB6D05DECDD8A1E3CDC29EEAA5F7A2FCF9A9A122FBAC8F5C9FE3F8A80E5F45F972CE575915DEACD097606479668142EAF15F7507DB1F0FEF8C1A7A8862B7842D2B018798675C0C192DFD599A27E8CBC01483AAE21E73828FBE25A5D841E402E46E310244C6088185BB9ABAA76020C18BDD33CDE7976A33635290694E60983BCA35D2742F6C3DAE63AD5C2A81B87151D9F9C0888A0225D909518B2B4A23F3D4EBA16097A18DAB083AD4203F0BCDFE9F7FD9A6DE4DBBE3BB52CB23F2E12AFB9E68C5098F14FEE38C81D768630FE51DBC843E9AEA80CDC199F7655FE5172BBF8E0E1F3D5337DDA45F0E8A5BF4F09A934323689D8897BC4403A0869070B25324C600F03947529B259D9F3BCFB951F5A397456A19CA32FBF6AA949D87021D5724BD7A49CAD6E3FF455211DD4E93852338D2BD2CA92AD4B29137215547FB57ABE65B7ED1A5D4D76CA893B48D18522EC84459F9524654EF2649144A662DB0AFA7925C134EAF87DDBC3F2E614F77B7EF25FE55639AE9563EA7A438B6DCC61AAAAF9E2852735DC7FA8322CAFB0B8B626384CADB5A91E83F291C63F07295E8B8302A9E6827CEE130A0A6C1E0FB695FCC411B38512F035FFE522F8DCD2E2E092CB0C6CC2B0BF8A975DD14DABD03D332EB6805CA392AF97A6D43C684BBAF73607D5A34A036835406D72D528D0F42D96F04231425DF1F8F58E1BF79D2C25ACCFCF63FB6974B867CCD0E2ACA54929D44EFC8CE8EAA2592A49533CED723FD5BFD73BECFB5048864F8526A3529994A979209DA05C0EDDFD3D69941B4C109465D167F780BC10A7BC93FCE8CD8A6EE414ECE2020EB0F1150630FB9FEE8E45FC8B68050981AB885EEDC5027F0C546398A456B38E72968279DCB81BCF205D5539C503A2CC246D36F4A7464C67973A38D48AD935C3FD0D6946AF7D7EBA58217E03058CB88685861C04E3A0DF5017006397F3D3823CAB0BF29A7937311BA55F17A50BB64FE35C7BA700EB23F9838394D719CA2A9C46989D667BDB0BAED2D010A21FFF8D072EAFCCE4905D9B7CDF70838DC18AF4B1812EC0BF1453D731E482E0CB86A38196A20961D0B96E12F4F27C7BB2F1AAB70CE0361C62DA4121D9791E9C2853C635A649217E06BA5D7B89272E13CAF9C5EF26F15A1C98280A36380C6D7C1EF9C8E7FE571BBF14B2BC08085C629E6A1A59C5911B02403593B8665AEF34F611CA87834B8EFE0A853ABF1186293C9244EAC56001E457B684CAC67CF172BF8F9B25D87927DF2206DFB7F032850E1B1AAF1D18A62F763FC369808993637FFE29A7D7605ECF9083948A4561D2051C11402DA25C26F6C60B156E8E533300E7C14EA530761032A6B36C7C3D79FA82C3035F300EB9B663A35D3D01218DE9BB45DA8D69511E3587B38602E81DF397D3AE33CBF5526928F7AE78C6E635507D295DA7CA15AAE276AB20B56CA3A491B8B3154EC810B84B97BAA9B8F86884B37362369C4AADF707905D9B730CC8A6D4BCDBABD995FAE9189AB0148B815411999CDCBF4D0BA60407DBC979E2E97132BA2167A631F8A98C8876B18419AF0920D49CABB1BE0E74D24D0297DED9650B81AB70A91953B9995F1E48619B806289C4DC1CD9D44E86479EFE86FE0B8D7EFCDF9FE2625CFC84FF7CED422D8024BCB302F14EDEAF25D1841AC76AACE19EDBA4F0C516C297FBAA398089890AA3AE42A8361BC16EB84A795491CE937622B0105D1E6672B17382FC60F8404E399610F9122D9EDF6AD06ECE7CCAFBCF502A", - "message": "5B33CFAD9E1F3FDFD71F676AE23A6B1667E9BA1E8F88E3698F3870054DFF752507852801D8940D2712FE057B474EE2FB7053780DC7D3158435A742AB4751DDDD9BAEB9C435DB69E0F681F1A50C1811D1E3B7562BDC11D4C1495EDD417503A803A31294581FC5B2C77E551E9B945FE212E9B7AFEF5581EF3007D88AE8A2E736141D8605EF2BFA8892A6ACADCB41DB9AD4467F29AB18C58AA801BF53A85859732C215F772E3328921363C7B5DF2AF0EF5A81E2411513577494B43817BD0DEC5A5C8CD7BB30351BB687953D028C5A3EE1187D6094B2B5FF03DC90AD4AEAB0285066540F1E0B096DBB1695F71517340441FF23C8E65E52AF6BAAE3C59EF1314C7EAB5436919C3E05E163BFE76221AAE7A22F9E7C372FD3A59DE6AB5C11EAD17AFDF718C0FED633E07B5BF8B903EF951707F4B0706B2F44976B530DC57CB960D91DC2D6F738B2DC529F09AB7CC63EF9AAAB271671C4EF3CD3EF5072DB28D2EA26D7BFF8FC99403F1E66755FA80334E7DD2E359766E0379815BF703777D042C7FEB2AEB0AE1C28DF438EF6A95D05FB4427C8421DEFD19CD5876D15247983CD140FD264A4475BB0204C256902B5BF062BE3EABB44E4519A6356F60B5E3C7405AD91AC686430DF2EE20D276E8935F3CB93CC52987E305EC177379484763DBD47BAAE9FF68152D27D7C69ECA3A6C9D1F8DA6C491C842EB44C872DBB37AD5C97CEB0CD375B2DCD37DCE8D6C7337CE5EE336E42E00D0C6E15F20ACCC3B82FBB54449C688994FC403ABB79558A9A21BE184BE6EAF201A033373A62339B6789B1327270E8F19531D51E6043814143A87726A5344D6A612DC42D8DFEBA6A1AA07E3DBB99321147634C98504C1FC6CEC135F4CC4E3CE5C66CCBA5823055E1C9256A800A5003799D4474E11A13D62DD2475DE3DF838F8421888DBE13D056BB4566AB277AF20E2CA415785CD35D6D532BDE75D9EC9A48754CE472187CA88F16A0473F8767020C47204A7D28F8DC6994A00967A2E6F70384EE1329863A2F76223E71383CF10E5D92815BD0F01F3788766BAD47F2CBCD87D9843196C4958DA3F13A9D608152D541E7FB326F6ED088B684D7BE14DD20B0C09EF28A1233F559C5F0CAA178D5BC5F347F8A67A38B6B7A6496648B1D5A7E6D93B2731CE18654CC4F9EBEDBE8351F1A10F518924BB36334BAD31166FF45F883CCB2D697F0CD554D11D61B06C0264E75FD63D115DD4A206A4964E936D466A36BA57E0236AB1C7EE20BF6DC6C1EAD98A40AE5CDA2B09D01CEE982B36FAF6143EE433AB358CB585BCA0681B3DF180AECFDD399971755E6A558D7CD8F06E78463BED5F5760AAA6C3EA1FD228855F5D89C78889AF3121F19E4B9445EC409FA58ED8ED6A9B8B5837598C7ACB7303AA0E9B69CD7895FD4133A678DABF9804333EA592E5C283FAC757402E86F074D87A78FB3C4A1F7F453874AB716552D29855D08CEF93FD8C954AE5794CCDCE61FCA50BDBBD47FDD4B01E49806267CEE040940DFCE8ED29E44626433A2EDF9D8EC8D713404593669642C96A097843A2E8751458DA4C87390FF5516F23EE30AE2A17B1C4155043F4996E4A7421ED1F35B54A217ADCF9A5409CEC63844A2CD4E0C6FB5718BDF8FD09EFE1428F8D142563799B9BF8DF079971307FCD126A23E5DBFDD798575098D14142F072667AE5B05A0ECDB83008C2C86F52B7A19F4A400A6257BD654D7E243131DB94CB9766EC38E20F075274964D995325168B91CAACE60E97E952A3C7CF6151324E7DA225FD75DE497C3C204EA24BBA613D1CDF8573704946E194ECCA725E4B37A116E1F80A8031F601154AF62CF03CC62D26260A98F2593075ACB63F6BEF5EB7324D4EEF11D78753177877DCA0CEE397C458A9D1157D84E00603DF81E3596E88E1FBC51088012ED7073B781DD25F34553E9988DA7840A2F76DC6E040AE8E8E9F965A3BE51422315D332221B864E2A6E6448E1071E904E31DD0D932B95E51F928F3ED00894588D35F0B71EF5B5E83D090804EA297B7728CA6E3716DF7713CCF127D703C45833724E725C7F465ABC68F3ED0A3F62D7466A9202283C06A7FF916FFD78B21EDB2A144766C170E50A2AF2AA3EBDDF0983CA6AD9F6DFEE6D7BD910E24289714D66A7B1CC14C22D41206072F195B7E0B7E2D3F96FC518C58DF7280A930390457D1C88611E75C1DD7C3930F2BC6DE595856D137387078DD6C8C6268EF13F6771121CDFD72B3D4DCB555B01FC9CE18BB4851949FA74A3615DF3B49E6C4017387E36CCD448216BAFCF688816E965808A673267A529BD9D3EE6640143DB0CB5536B44667D2749BE1B2B430798B38AC65E368FAB2194837DE4B4F31D063C97F3D6003BA0AFC3B71A1253FB29A7A15131046A3DDBCEE2B68F0CF42A34415C121655EAA9EAE58E309C115E8ED7248F710EE835791852EDDE7FEA212FE060C879A02B1FB919B03A677E8390C8AC62A1B13BD58AFDBAFC3D360E0359244C0DB32CD90AF078D5CB4699E5F0765689FBE1D90F6D3C948CA28391A4F4855F491F57F4D919C38E3CB01E7869169F3E8EE22B9363A344A4018D469D992C29F444B0B0842F0438B48F457D53113E21D23F1CBECDE8C910F9A486F911CD53D4B90430B68BE9DE5B4CB0145D749DE92AFB9F14F06DE52D24FA3B99638A51E8C8ECBA1A3C3C39C0E7308AA3FB0DC44C9308114BFA963F8ED3416DF04CD00FE5F0AB2121C031F13C4699AA30FBB96F92EB886A73704294EA0D7B4B2E79805A9161855D6AA0AFD4FE7B818D8F804D091F6FE670A762706B4D16C1D0952F6DBDD4292B7E05D8DF795C2FCDE4DB90ABACDE117B9B375484BCDF8B364A190B04CC5F5D1D3B2C2C1A9B0B1EC52C1F50F68461DBDC9AFCCD1BF16557AB2074EA97215BEC34D2140C87BBAB77685246EA148AABAA34B02D60B894303148B3E8C61374700C1634DBA22E958B0AFAB5614B23AE0B93E6875F072E71210F7542A212C5A62CCA9E6A98201E913193B85CD2DAA4A574EBC6AE6C3F3E0E76AE54F93460294366CD8F05F19799D24153C79D16A5207509A9A2CC562C73BBD08F0231F260E5F831CE01F24FAE4F17B71CDAE0FB0F9D78DF475A19585B1268BFDEB440AF50EF1C33C2ADB41EFFBD63C2FB276894329A84CFB182E17C18BBDF8320F20D111212DF856F1396936D2A6229D631143A9588B1ECC552C130748B465941214862E63AF40F62FE1CE4874A2173B256085E1520A46854F44C062242838BF81DDE8F9D157FDF90295B3AF006E01259E472F7173E771FB0E67766198539BD380DEB675D7A57254E1F9D8C3F554ECB5B668C5B00BB99E3853B09F43ACEFE2EB69B903FD13B78E54073B3B121FC5ABADAB13518B3EF59C84DBCA3D560979802D0BE899A10297D907E3F4B5984E69F2811698CD3D0CFEC4036A0694ECCF7258BCC3898C1256C24668505E8A0308F68B60B6FCD8523653A6980AF073490029667E07CE8EC9DAB97DEEFAF380B386DEF3DD5F951625E0507B425356CBC4B1416BD11210D1FCC3DAF5CD12C8B2B195F9EEC6B5248A6C0A788ED9BB42A4D07690B7ADA526AD7595B8F1DA01109E7F3A3694F827425568EF1107BF8677A5C5B506DDB137FCE83AF216091A9D798D02380551610869D75441FF9A9D51AF8BAEC38F538E12D6748BA7AD620E96A76889AE596F121679451894F087BC789FE85424AFB1F6033B6B971767EA5D726C54D9AC132D3A03A04E858566B97E6D9BE3820AD47AEB7104ACDB9362C254FECA7F4E7EF5586C11E3389F8B330AB006FEF9D9BCD927E1BAC3CEF48F4F2D3C4FD9B88016C07D5775A06B22C635BF30093C2AB09F022EB74A861EEC5CCE1C8D160EC53A7303EC31BF98EBEB907277C9B01BC29BDC333B05142B83F3023CF0518BFBA53DFF6F5BDBD7F6F3DA1732E2DE8911294D2F9888BB3CC4A9CEDFB438A372F31E7350F0EAD958E23454FE77D9BDFA63B73AE06344AA7EF63EEA48A4BE0C5BE251E0F0ED42305C09B07432F7B17BAEE2739DC08495C4D40F50933136E30956775CAFF378906E0177BF763828A9DF9960112BBE1483A8924569814B43B80B7FE89CECD75ADBC00E31A2442D281A3D90ABE6E94252F1F354240ADF38AEAFA3CBEC9E52664A8B8059538EB007D7DC9D24A23FFAF773F81E3B032762DB25238CE1BA2BF9B53EEFD0A6DE5D3A713D068B96D6046C3B816DE7E65391461B226EA69DFFED0E536373290E6B7C655BDE71DC59329539DBB18CCEC87F6D2867EE3C1343B918E3095FBE2C1FD01DB8503657438BF9344745A26FA6E2F66E118F83091C23CC9BB311FDC58D89DAEC4B687FB53690ECBB610A6FEFDF6C3AD0DEDD4806FC1B8628056CE830375A3EB72581CBE1C3C54B59968F24A25BD208AB42252FBC31006E074A338A71EA833A85ACBBB1D8077D05FE9989076A22C06B9FDED2B371EFDB72E769D36EC9C3D4D29DE94762B761D77DF5970F97B3E7C7EAA90D4E46CD1123DD1F7313BF8572AD0E213CEF320D7968DE259FC4A5BCEAE5FB1958D176D2060F8D2B54EC204FFD1DCA4CBC8299E2E1338A74104CDC9E4F21FB9363AC934CE9CAA3C6C2134103ECFE626C62F4EEE6896EC5FC2E509CB9D65F3EA5E00D4E6F8A2D319B692341A73FA8D4BD06A2ED8DD7EBA0A21C1D7A1B661CFA13CA80BCB1BB691F5072B6C23A00D219987BF2C6C062F9269CCEF9D8998DA4523B5D4289494140BFCD735076FE887F9BE4B6F7CFB858476643C9FE026B3692A0F9A54AA9ACC6D0903BBB1F17C93CF09AC1651F2C3EAE0785F6EF4019E18C7AEC9B29B3EF1330F0F3E3366DBFDE4E5593E3EF8ED6232DDABD946DDAADBAB3C6A97AFD661ED0E48A404B325A095BABF3D18D0ADDB825E5EA014894D39D714C363D3FB96BC22FD2AEC197A4CC0D2F1342680B5BE9F0F10662D6CF85F17FA611F5074F892C9E13FF3D770BCECE88CCA9973A0479BF764375C65C577FC15D49AA80563D88B6B65D46E1BAC22D76B762BA4680E34B1A36782290064F79E4F5BA0F9472862143032A7A852EA03798D38C05D63C657B5CEE1D1687709BE130D27581F26B00F2CD38F6BBFC4039374CFFA32BE7704C5A87AC7AA565536A39CF26CABE65FD374C0F63861296ED27C7838269E1BA5B07FB90DB8F29B71056535B8DA91417CCC9B6E16D86EF7BDD2606D621B5CBA6B5B7684AD27B2FB418A9965301FFBCF3FDF9494E109771C352DE1BFB334250A6A9555B4A9D12010607D788DF4A4259F9214A18826C750C00F1F55CE381378B9178E0955BE8EE3E067BA5B31CA873C8BFB19D32CED3D9873EB14428DB288CBBCAF4214312F20B865418FC5BE3A3BD452AD085603D028FC2CBF387677F424702D79966D9FD9E993511DA354EA6958AC618B37B222B544531DE2EE1AC272D509957A2F17E79D608A5F2A0B482345DF1ADAFAE84DFDBAEA5D907D0B006348BE5D65C79AC98432A649D8356C0C12D5D128E2526380CF3AD03043B44A8DE739BFCC371E1DF56DC16C3D7BB788CEEA2E11DA0BF2392315F67B82BC078BF07022016103573B24AFDD1A1C7578764BBD8C37CFA4BAB0E99AC3247343CDD287DEE2B6F203455B22FDB695BBDBD4E63969BF4F8F8F6AD2261405A65F7A38DA4599F5F15CB1E00A0C1CC63977E1C4EE41229EAB1D126B7DCF3E68D20D5177E8372E7680C91608D715DC61FB0C3A108FE613F8D6636F09BB19BF076489F5E76E17D3738870AB0139F8011B27CD853CD7A2F1C7F5C08EBCAAB6E72BCA4F01D830042F804911B380AE08B8651F1AC0A2458A57666126EB9D981C843CF15A09F25E2036E770CBC62E0953EEE15D27D82FF3D886D4415FF866EB9F4B1040BDD49DE9168CF849B37BCC5F99C65A8DD63DE42CC5F9C5F7F308EA18809AEB9725C7CFAE7BB79B0B05F4ED9E7DC84A4A11E6858BE336078C8218A1B197FD3EA11A4927E3106C745CC9C763CC86480F95BA8216BE3B06E14DABE01AEF1464D268C173E78D5D04CD27A5C191C483B36D9C07B6166A66FF1501D784E8DE93191E5B8BE680F3E5174BD0ED7CBE5007B8D293BFAE0933C05E4F4167CCA5A8D5BBA46312997D55462C4B10E9D6C8B6417CCD7D2DBD9A387D31F4083CC620302834A6B633FFCDD435FF5059E78664B4678C0887FDCEDC7B71D863E06DB355978532974D8A2F434904CA4B0A390B10E11162BB925EA563C08131E67649D29F810A8965F7677516221F662D608E5EAD584EADB20D346021EA2AFFC3A15262B0322BD969E6645F8FC36FF0F27F908DBF44D339D8FA04CA5A7370C956F739851311E6BEED4DA3809126A8B6D88FD392B481F6FC27657497F019260C67F586377A477FC611440EB541FA9F4C91F4E38180D8BEDC2EB4CD92D7F803FC03E57B30733AABBC10536A725D24B0F4F84C8FF3152AF1E225F971260390197CB76CDAF2EE979821E8F9AB71BAE4D69FDAD022F174BA68DDD769C70C5B94B5BCC5255734C48BC41A3D04AE7E07C94CED06CCBAB84CDEA10EA09F7DB2B2D6269777B33B07D1DC6C95886ED016C9097C551C79E2812B2D6F002C291131204D890D1B7887841F6867E84EE6E5BCDFCE38B1D09E003BE34110FF375A7038C5BB7B6E2BB0E501BB4DF41CB5C6C33B2CA75B9C62D6EC9CBCB4BD007A42D213851CAF112211633B6B9A88BD3BBCF0A1428A41096EF65574CD9E808FEB509C430B2FD9A56805C66DB1CA92B74BBA3B3C43A9511686DD435FC21717E97F1505FE51D37776F9344A93A1C8E7B255188CE48700A4F14EED1783A6D2DAB3986736987CE8CFD79EC23DE89A9F049D60E9329DCAB050B6AE82E621AB1639361CE532A566489B87B55794D8B65273350FC29ADF09F798CB0D9CE01770852E339AF33A0ED41460FAC83B94637B5E528E9A56A6DA4AD32A57F307B9C64263C349BB103609E10D8BB69CE4B2334E8CD3C762237B33CEEA43D1FC1C1C60CAFCDF7B6FE2F04F25B5B2168974C48EA527730F6884C321DF322BAB5F5BBE9423152B6072585AC29C3B4B26455B65FA95A32DBBB03F76F55D51D3CAA58D8B70DBF871EF6F5A31D2E2244FDE792073B2FCD139EACC998C94049ABAA42A3DE6EC1AC546B90E61CBCE8EF9553DD47B9018F5FE078C79A53622B17F503A29C0CC376124590A3969B1035DB29002BB3E1455D5E364F774481174CF8022BF6528811EFC107BE9D065FC5AF57CD48A1905A2D43EB663AADEC848DC0D2A6F35C3A680323DA9085D12520C388E42BFBD251E9E3EB5E665E55BBEC7046E8D3BDD9E8A9DB539FAA9B74457BAA49CBE69A6CDB76A49070DC0605BB92CE6614CB5CCF6A8F7F7E98D748F68A64C7546C19F87A529512459328596828642AE89115E91CD00663B460ECF1FDBC47B8CA442E69E68B5F8BFDD82CD5DE33D06B9AD5053E333F0B72D60073D9DE82FA7278F69D4883FF0FEDDF59182852EC64383ACB84E83EB0BF678CB268F6793ED505F07FB2327C1B371FBD33EEE29698253EF6ED08B398FAF23B390953BB1ECD21BE4BAEB0782B6B25338F2DE320EBE860D06D77B39AFD10B4B0F7EDAD915EB64DA054DADAF77892B6AA87F5D44DABFA18D69AA2615C6D869916A6291AD215AD39537B8F1AF4CEFB82DEC4111186375ADA12BFC33E8809B92F7FCF99F2FB717ACB997C1BA8860CC8A9D93A7B059CF668B099149C4CE146B56F141517CD68D4BD59C9AE07EEF7E3FEAEFCA4853D78CD44879D02C7B8CB4479A16B039C84BBC54E5E67F3D2D18DF5B360DD57815AF81062A099D382B723254D9C8F85D4BB54CC068DFF7D5DEB7DDE6B1FB9FADE18E0F9374FBEE140B2434DCBB5DF40BFE9057D5BAB7062442F502191EA95D5F4FEEB1CED3F6EEA28A07776F0439CAE0D0FB8F0E5AEE9C925CE28A629D781C83943816863EC5068D9FB2C357496307CC58A0913A2CF1976575EF94DA848E544D5EC1D30C0522816236BB00F2541182F0BC0EF0F2C67B4567441BA9BF273D49A0A41768CC54C4DA489258B67159DC811EAFBC17CD2EF965C78E27D0E06B14BAED2D5ACFD53031ACD4DC1FEB2B42D38F15FC15D3E22A77FB74ED98FE0199B6687E84F944E8F27D33829E4245296D52608C286997D4923EE67243C25364B44B162149597EA35FB77F93E9662010E93E3640FCB24CB0D8B2D7029CA4A072111DE8BF532E68A3935C3E751A6F866A418216E33464819C0A6A50B1FC12009E2D990270D0629300216AA57E4F571A2863D4149C42CD0C138DB921E62F890E38DB8DCC3497EA3F551E59B040780F562C507F3B0B4BDB2CF9CE995A10B8B25AD2AB1E8DA5836BA79FE05F776EC6DAADE8C9D999895CBA576933509F3E891FB596C8771A26F82006EA0997C5A2445F496DD8E4306D49224AC64486C58955B137A602BCCD104886CCF947E2ACA7809CEFF8D9F5EFC0C6B753968863ADC4194DCCB53F463E34582363C8A5F6259CB8D229F24BDFD7216676ED40F12633AB4F71EF6D7F647AAA8E3AD8B0175637B3F844BCBB0EFD3609BA4B1AB9F1CC6F30D37A1FDCA91DE1748E38EF82E9916D802FDE0D605607256F4E998A61D908E27DBCC14285D7669105A412C2346C84A345ACF3C1D34A2BF216FFF6423A238687516C5B068CD71A74F1B1578B481D256590D4AEE7605A4ED9C34E199F4B57435D305BE059D11577F394531C2224EF402F9F429A7E80B7E231C52D1C04CAAFC70DD47C7B894CC4A72B522F9F438C1406E052E44F136517D9ABE52C1D7940CA223397A8362ACF9313EE55FF955A63C75EE3A75DCEEDE25FB50AA64A1C60B2FD2AE889020BEAF7AE3D21D232721A2280F6018DD0776BB3AC35A2932DD90CB5E520C71AB8DA59C9EBB31EC8829A180148387F57D146D3C544A0645CD5D6ABCC05A36C4A74635A004DD3D3A43CAF5411917769D9A51158526B3C7D13DBA79DBF575B77D6ABAA79B21125692A983E01C2B33F03729502287D7917F5ED156C26B6FE6BE23E72075095EAFFDCCE8FD26A602A937F015D9B2A3A99EADEFC3F63B2EDF3F8FC029F2B563341610DC03DC16757133551C85A1AAEFA6D8269C83B91F6F7C0198FF62A7D967B5BD91B0C9698BD03B2198D365B720783EF278036A7B10D5C6DA359FAC41A71A16BAD3A619D9D22EEB8117A48EE649B1A1454119B1F0229963BB9AAB88676142D627C9AF78C1CD700C2A038D1484915185CE071D847D31E06A5C77D759EE58EF1E2C292047CF8FA852D586F3E08CF5DB92E489D1567F6EFF48017F087A1045832DE41A0A6024461F9F5D8CE37C89E1E954E1F7AF7176C3282689448DDF2F05EFB8F37DD2664ACD9A83FB48199785889C8F5E2770000E869BB670553DCECA0AE7772478F51671377C6207ADF80289988BB71347EA067D1431F88443ADC72FA231F35A9330014FAFD7482DED24408F200A1E2C5D610C0E321A648A44C6587FAA4F2BFE772283B6A8147443F8488778CC3D5A9C2D717ECE307A8D26F6B964242B3066749D1CBC7AA64B9DDC3F3C78BF316B43A8EA73B010B3C90B33AD29F235F0B37060F7C8D40FE6351FDD8232973BAE2A50F8FF54D7ABA16E3D712CA2BFB619101EC67816E98254330DC21F517EF13A27D65CE01B560F79E887E14B3842F4072F3F0123D1637487311445645194294F88A96F96B6E548114297DB9B60B368787213A38ACE79E3976D13C563774211C413520EA0BB661AD2B9CFADB50AE1AAF677BCB663584CA1875A2AFCD1B801E0E05CD68D1BB9E03528770BC760013DB269E57D6568326EAA906DB890F08E91DE713FAEF2BD4B8063ED24E8D202ED0F4FEB1B8B639683209F5F93C89C1DDD5A01591EA47F5118CDE54903E888C1BE3E6909D66E5A9FEAED25BEF01B8B30D977D5BDBA904156092649761B5E73A8DF9F6B1F097595A307BBE95FFA78776243F0A787916861295D627F6C11624BD44D2027778DCF3170FF77161BB99EB878925AD86722C0D90706E8DE3AF6951A2DC7A2FEB2F109CD2C67CA586A6F68122BAD66012B9013774BE328714AEB994B57E18583DBCA55EE9386788A9A1CBC2F8823C9C431ECFBB35B7EC918EF9D4394E26465269EF045F561A7EE27436EE614FC081E8E708BBFBD08147411CFC78681BDBBF98021B82796B23A4FE1AA03D7CF8088E0762EF140DBF496DEC686F82FB199982B1B3E76ADEC7E3D7FB167A453D6EB0B09EF891019D8C72806CF94A5C431FBA795FDDAB2CA8A78799638DA1803FB66636C5B2A2B692F8605CE09011656046659D96BAFBA4A5756340AF24FAFEE952107E5FAAA3A8BC51335A8250A20CE837BD5D8B8AD35034C6E1695B5E08C553E2AD829CFA9C1DA4F1276A0A2F6A86DFBE9FB8E94DE196D5AC78FCC84899E4BB3D8AEDD781CA88EFA6AB6C21A8FDADC2AAB2F543C402DDD0840467828CC4505D481307DD2D3191B3E27CEC2BB11AD914FB888D98F72DCE44671A08127E6B6C93D61E3B8211A84B374AEC70934745EA8C16E6EDF857277C849518867868DCA0530F34719CA7F0FAE881E4C074B1645DEE9370EE1FBE7BC747BAE3720B91CC1C0A6022F7A4347DFD0505AB741F6F36680824184585E7017507D8A51AA5F5FF94F5042FAB1A6C8106D8F6D5203383A0EDD488680B26C2203A0B3C63263A56F3DB25DFF7BF5C0BF070303E07A5210DB16AFFDF7098D12573EDC38BB60BDCB144DF9BF62DE4ED9FCC4521393199AFE4C5C24740D87F368FD253C3E55F295012AA61D8B689E6CFF8ABD75FA628A37837D222B4071D87131C9625DDFCDD99772BEC49DDA9D182077AC965C7EB9CCDB4B050A17ED6543D5C870BA9389060995E72C3FB73DC53C8D951F909447A0E1EC6CFB63E963C0B3A2760263172AAD300830EDFD60A629C6BEEE6DD8A107C9D83B97D530C91E4A73D48CD5D104742AFB7DB0985E1FDC79C19DB47223E79540785", - "rnd": "99E19A50C56D2755BE9CA2EE96C22C236DF46E7D98DEBFA98B6A057997A1CB90", - "signature": "4FF204815C56D5C51452860204405E49D9F43E1C34A98C1B014E87DBFA10FB99054F398FD9FA520AA1467BF785E3565EEB4E2F6C88B4827BED418B4FDE96A4FB370C394D870C776A6B75ADBFBAB97A39BB0E004356B8D0A127D2B422E736D5453E53F658841D91A6165B34F6B00D59ABCB29E7F611E640C188ED3FA735827AA8A48319F37A543EE4DD2002AC491926DD5FA3F732669771611E0888F01FB4923153ABEC9FB54A83B2FB08A286CD964F692ED4D44C74DF5F86770534CAE9277FA27B401FBB40248D5E548C7698C7C38247C22385E34740AA8D883F57C9A1EE00581DB297256824D19B47608214A1B9935A14163B1FA1DC70241FF46EBFCEA830DA689400424FB3CB63B060A8C544023D83A8E01B6936052996061116E254E129BDFD6CFD23313579CF537BD75F72BA992971CC41EF879048F793DEADC2124B1E40FA758F9B331785DA765EE11F5CF204B2C0E5213D853A3D764351B296B4D2B71AF6B12325E30827AA3889F529BE132AB69F0FC3EBEC83F1A481237E666F3A7F9F51919E0DB53F84722D73F7874F93634D5705A0B445023F5FD166D66704F1C1E5E42615DEE8454A28B82F97BF871F5AB22D766CD3996CF65DA8D63CF060A97861BC67859DAAAA4D527ED1BB534BBE2297D413B61BF3C6C599C26E9488D470272A2FE186A886E42C7F8EDC555B4D6E3F394FE52AC51ABD99935786566A7674EDA529A830ED4F48364F2A934BF8EC63F81EFF65A069080B1056A7DBED12F824525A83D3994D5F6176A97BEE8BBF958C657909B93FBCB8B7904A3B6583DAD8BEDD1EF1D6B4389461506AAA43CDBECDE503CACD3C7AADAFA616598BB6DCE1E96666715CB6C03DC5645A9211AB2FFE0A684795A92EBBA2EEC565F64522602227637FD544EC38EBDDEAE706F420BC51E2DC9A543FC3B8653113269938E911C9251AD2E8279F8B03B991CA3891639B652460BE2DBE2D966852F97B8D7D52E5CEB5FBDAEC1F6966BA3708EC24096B13CF80BEDFED360A939689FB8C75C8C12ACB27220B68660AFAB12C9F92FA3AD57FB0D12B256E946C31328266C3F54C558A30BEDDA86F4B5DFF5E52D02F03D7CF660B1B4EC2699288A0D354805B9AE1E3EB206882DBD1E594C82FF773E921D4BE58834F72A79EB7778F889B0B2529797792E8E905FDA6081C2F6FFBD753766C753650FF6A7C056B8DCC54B5FA7C110D8DB47C1FD98F7F7FC5E221F1AFC5F6404FE696D72FE4DC31A9F75D1ED957A1306AAB348B2AD83766B45AFA30D1C970BBCE8103EF29E1BAAA17BAB49E6AFBFB6DC4F201AEC5FE98BE5A9684DEEF7BD8F647474367E37A2E35A37ECC0E0904178E422034EC1E884BCEFBBFD9ABD27E07F6E49F7C657BFFEAAF2E1E46A3BA46E93ADD7E537DF724D77EAA018B6FF28DCFDF002708F7CD8E8E8F81CA499D5F4542991F48C330BA8823B5336DBD0568653CEA52D3B0AAB8EF2CF3A77CFB561C250A7C2956931D09686FD21FC68BC8DCADE1731CF9C6F93CDA2571C8951A32CB24F1DC2C1A1FECE255263392FABDBD4D5E4C5E3C7F842D0630E9EFBB57532D2A623B36ECBF616B5C7FDED9F45E2FA37FDAC7257FFEDE0DC5B6DDE6A5B49E8C151832F707AE948E45416E7A9082B257CD02152314FFE399BC48755EC6A311DE39A5C8FCA15BF547DA0018E5B98FBB02B0550D7DA298EC788E71E34ECDD769D3CAA36571697B3F9EABEC88E8EF76F492006540128C1FFB4F140796559E17EF660F34386355F46964A9FCF8D37992B9803BE4822EA8B8358302B6B4038D8DB1A71688C8AEF77FBB1013CC677777BB2452EDD89225B2F713683B3C27D35F4EA5DF3061C2750FB011E789AD055BC3035CD1EF947375321770C53C8D4CA48F0B51E68C251CB49537FD231ACEC8A2C2BDBCD349FA651D8AECD202719ACFF8B7EA26DC31DBAC5EA338CDD2160D15C534EC6426E63B0DD3141B133F73B67CDAC053D54A35CB8DF2B9619273110558E0B29C6DC2D9BDB0337B11C4297D171990C32CAE1538C69B858E61F4F4306DD4749BBEC8FCEDA713E54B3F742BC6B691981770EC5329FF93B140033C252551B37AE873A2179782695D4F8D18835718636DA25A3F40794676F977AFDFF7364747C1FB1F7A8A2CB08AA11034FFE89F2D4B67439AABA9BCD6F9743982F4CB318BC7C906322B0E3AC02528A80C9D2E6E3C2A3EC4DEAD7042A2943461833D6E6C460223B2879DC8E1FA97CC1826C620A01BE5F991B0DB50C5C7A976F69A1FB19E16E03ADA7F0448C1CA4573D94E13498A1FB51A1A0F97D277D80774BE06CF1D6D96CE619FA7E7C79401E331293706CAC3B185C352EDD07C91572A31716320E1B25308B371AAF43B7D232894281E4671F9ECF731F228337BB7CFFEA68C0A5B190D0BFDB47BA7836CDA5923FE3F6EB64273EFDA6CBC1B549FBFCD9B5A9B4B9EAA9F86B359905D014021BF69B3862F57EE44136015F6C32E1CCF0C08BC1322D4FC1185AFC3CA38C3F7ADA19E8885C108EDA8111A6A4179670C18E718523AC4A04C9316F803773A68BB5D4C6E82468037EBCA5E6602383E8DD2C4E830C1834101E4F87A9A931199D7E74F7139FDADCA6817374A9338A1AF2F3458DF29D26B1A0C63FE9AF6970B993D9A6005BC57AFAA6002878367E4AA538ED7468C52EA6CE196A00FADF1F6ED083E5B98E70742D28D92D60ACDBE5B164F8C03E0E96F8950D230C0FC3F6CC9FF447B74561F66A55C2B962D4555962E51A30F998657DF2986F47F1B3DC5C87D8EE5DAAAF760A06DA656251BD6B21AEE25FFD6C61190C1EEF85781C8C13839E75E206962BB4E3A3A34438EB1DCF1B8EA649CC3435A41050842D61D3370FEDA4E950D28DD062181780B5BCCE085EA7A976CD38B52464B2D65ED01220ECB4CAA1D7FA2F48123D45014B522872FDC8C642BFCCB801C6C87D26C4D62C031CF927FB2F1EB8B23499E3ADF4C781F5472D914F8641EC60FDD3558A81FA988C38D6E26B97E1311D1AA3FE9DA26FFA9B0CB821089628B7D8374118C59C96385DE497520324DED714BE995B6A08C0B5333AEB7ED41A931319E7F25B23E41100521EA8A8B661426D676469F1E67D9F61881E74212C2CF74BF332358D396EBD53B312C13D22AA8FF3C709BBCC85515B3DAE37546EF2E437EB807B8CC0F5C985F19A3ADA2C84DFE44EDD45760A409309A22EB2DEBA59452B379F952E85086D0FEECFFFAEC7CEED3F32FFCB8B5C363296ACAA0E891DEB5D463B068B40F40A5E8DDCE2AB383F93643A9E5B69009203F76F3224E40399504E47D13C5137579C25E10B997D2D3F32D7B882AF31D63A985EB05725C7DFAC3CC58EEE7CA7D25DD6223080B1F8413C7AE3C65FA1A3FA61BA2B83451E7D782CFA6378CDF3BB5668610DCAD3E8A251EE2CEF84983F436D354AB7F3C203F4856CFC8EB64BD06077523BC70837FE92C1EFC6060712B9B5C545BB45C66A8CD79857E1C265B99FD83FEEC38F3C919F1F83B7E9682BAC6215A53A9E074885D737EBDB4D9A851205D211F92579312026AB3A7C4CB57E2B3AAC6FD6331976C557FC24451B199FD1DFBC3EAA4F49EA1F79A9AC08B1B05323326D40230360E454B5EC83E484E3D1C0A815D97024F7164EEE646361F4DB3AA830B2BAEB07CB4F3768F56626E64236FB8B03559525D2A2E9C80BA074821E0EDEBFE288032983F765A589CE902C2CB4003996BBCFFE8D372EEC34F705FDEB80A9D7AD7287FAB144117C19007E6FBE30CEE999ED98A262E7790D0B2CB10AAF174B791A010CA89CB9E2D682BBF3FA23BAA83401B86E71F91B3A389A4F250C524DADEDEE6CF2938D928FCFEC5BC843BF1F46DC49E73F2AA5C232742F0FC96220FB17D71EACA22080A9EAE6BDE929236FFDBB4B6A86D0C68BB04ECACFD4EBBAFB1BF11B78A9C7DAD0B6F7058D24035492195205837DEF4915C8D745DF92A7FD9B669C079A2BE092D702BE9367A57B22C0D085DB794CEB5050217B53F901B95384D95614EBD58EC6137BFBDD9DA4E4DF735F02A344E95F316347A982D791E95302F92500479152375F886BDBFC33299C45B629766DE1C9AD3B51B7F3ABF0BCF44A89CBF30446F75EEDB548C65EFAB80D506BFD1A740FAA5AC16203C2FBFF66034C5D2FA7577A543F8A1AFC6370AFDC03B73088CCEC659CB96481531F60E7BA5DB671AED97CCFF08D4280ED70E5CE1C54FCBFAF120C44BA63F4A76BBA631F35DE27B9D13AA4275E0D17D40B41C37647BCF7BB1439B86126A63545DE4CEEE5FAB270D64F5A18ED479D2C7B6190F45EE9E284FDDB7359AE17DFB28BB0AB54936B366BCF0475DCAF73E82247429B30EDA353E30B887132D0D50AA7388FC49D599837303F6376AD03D090BDAD02B36A9563EB0FCF8A1EA5693D0C8A335E17B79FDFBF77C8866874753CB1D248FEC3915394C6BB10B3BC26C6B03D54056908D504AE7320A4F5BEE4DDF1FEFCB1FDFFED710A644DA848FB124DF10AAC1D5818F35EFD2587B04CF588C1F228EB18A81FD1DF31E79382B9A9F74540C76438743555B9A74DEDC0EFE4584D3A69B1F7CB5471CF866CE6CD3D262A8D8E4913B3B7CB53DF8CA7B023FB199CCAC264C0D314A2203FBB08F5DF0850811D342E6D5067871AD16D70509D82B58282AB68FC4B6317A930842C5630CDC9E6A49BD8D3F6B38C1F3F1906CD71C1E1027B0AFA520EDAAB597CD5B38F0F23345957F27E440CA9E6C78E1D5A9FE600064FC04653E13884CCD9B927764973845DF9130587F06B5A879E243EFB56E91D8FA19B9DB14EC81020FB86F7D007351013EE0320202C19E7C2AEDE274D60B146328D9005A1F4D9BA1E86697208E26BC274FBAA0E441F65C22A44AC386880F7672B89B3ECF4784E462253FD4756245DF47D887BC82059608DBF0AB7AA3A0E4131D732553A4AEB07DBD7E49990AA2346E445643DD65F0FBDDDE9F7096CA57959288D425DCEFC093C44FD2A70EA12D3A1F3361AE88BE7855EA010E775982568EB4565F25116D26627E76F78CBE9DEDC068D123C785C5C500CAAF212667F1C9A269B4B798C2AF1344DC00CDE7D2FF8372DA48F0C943634C631B494D9320017ACBB8D2DC3F3227BCF2B17C8C6DC241F73D797000552366D8663B1BC702871C3EFEE8C058C5463C4FC55A01073D19AD809CD1C70FF18C1D8995786F6BC1E676E532C5D1A9C201FA00E3210BBDFE33BB8060DB4D4F9FFA2DCBAA111FE12111FD57B60E58E9AE00D6B858E16E1DFD2B5EAD33C989CF5FF29073A75957A123B3D51A9A0BC9C34EE83CD91FACFB2E3B28365F824CB4878C2326FE3C6B8C2F6B92A2EE3C3E313C5F8053E3B80D68FA476BEFF203A196B79ACCD76EDB0D54B2B6CC244D6FEBC033999EF1C7547717B07E53B4EAABAD911A7FC1271089BAF11F8A0FAD5C9191383D2BA83126DF21CB54CAD8D4757BD45974B7CB63864138E67AC0690C9DB790E728D5DBE6FC1B7B8D271CAB038A0AF1FE2B8D2B009C3E50EF9068E71F8C53E1FE648FC9AF86628037C909F21F0F9E38484D0DAB7DDE575DF0B1C63E7A8E182381F1438823C5AC9B3FE2E166F18C2A4F0D4F309CF9AAB0330AB9E453F29A3DFBE5FDDAABBB1A981E1793F7B7330A5C0A80DC913E1866F2AC7CA33219D89E3314FC5B54B06D9210A58F959DA6B0CFC591B22D4DBF9DE82665375FDEAD8EDC7BE99FFE00132CF4BB3399B39FD987D23731C7830B5A6D38A141110C7A67D98CDB4B21B22CA936251EADBF16E9820F5646D85877266DE56DA00E732A2AC682EC55805FEAFAE9FA18580DD147DC7B4475DE3AB37F10350DA49929515A2104627C8EA40DC11F58D64EDDCF9AD9E566A3F75B4E206AB1BCA16B9216C484AEDAAD5EF0D6C05CAA29FEA88F14C7EC842ED53FB6BE79A0D07B78B5DD72C42C5B06322B2CAA430A8D6DAAF008E1756966A706C9331D92F8DA4846CED35E7CBC9095C7D4E7781C856A4EA6DCA8F15A7F387C582DDAB0F908BDC04646913FBA2FC80CFB652DF0E398717A0E9211ED22DB5470D857CB9E5FAAD99126BDC4887238AB80AAA3EC0F0117B0A147F541EF4A330F4079CB1165336E0C7887482EA09E6CC5748AC7EE16F83CEC086438A054846BCC8E5D93EBF31A9AD3FF12575901FBA88ACDB257955275A6F2ED26A0F4DB7C98CA63B8FD6121A4D6322DA3D07B2A884F0FEBDE956DFCB028A0ABCCBE4DCD16E97EDB27D297B40935E42B1023CDE63F6DC6D86900036582E61C3D3ED94FD205AB8B9BFF81C6DAE8D603CC9AEC3F8540E7222F0FB9BF02FBBB58BA6E7CEFBB105CDD5002E6523D27963642A99F7D2B520A0BA00A91F10B980BBC0F15819E8196BD4E72C7FFE206FDCE8E0D14EC0A6227E6EA725E9FE330D2DFEEEA928B50EDD959A70FA3983D58532CBB996CE0D5A2F9B6D8F10DAB2C39A9444CDBBD1DCC9FB14FD7C6D309224E6B34B439C07B340AA77B5EDA8C0549577A88B5D8F5FA0A102C4C54575E6A81C3DB2D2E5B60375B6B818D8FCDDD070E333539457088B3FD142448717ECFE5E8FAFF2746617C9FA0A3D7171A1D3739408DA5C7F20000000000091418202A343C46" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json deleted file mode 100644 index f8af6142f5256..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json +++ /dev/null @@ -1,396 +0,0 @@ -{ - "vsId": 42, - "algorithm": "ML-DSA", - "mode": "sigVer", - "revision": "FIPS204", - "isSample": false, - "testGroups": [ - { - "tgId": 1, - "testType": "AFT", - "parameterSet": "ML-DSA-44", - "pk": "09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066", - "sk": "09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9E7A5A2506B0783E5309F18DCFB0AC4DBAE97E16C09A7C15216B9F43CF1FA0DDA852F5E3BC76028C3E884CF87DBABE8D530527C68C404ED51534564C40E5CB3AA8F3018B70D93D1743F9DC5925C41D00498724F0752FCF8E76BBABF3A84238AA7213806609624C9B46103C76C534841D430614304049A444D923002E1066661346CD90485012048889440D140128A167160B68C14928C521071E192319008900435485BC2010318202000285B120AE2245264388D03954008A184D13671D8182910838402482D54385144206CCC088D9484840AC84D2495518B1891CB9665614432DAA0800AB110C2424E89364210306A9BB80589C83019028E4AB480E38650824025631241C3100E9002824326861A910DC19068D8287208326DC836100C8685C1B6845B8871822808A2324E20C29004938C84086D133500DC408913110D61903013140020935154109008B40014944914872C22408644064158066051368C91001263B0611300440402519394842421700B3189CA862508B131004720CBC22119108AE296480925910CA3618A2809D84066CC384EA3266A24349051068E59022103168A4C128058C26889C63021B364118249CB0421A4107083A281C8A449C98028E09488C0A4045B8225628221C10684D3A47194A21052226822174A0BB44D534410E248719320125196881A9308E1184463A2890039226182315A86405944690CB089D0308514A34CC3304294162AA31051944248040385D3900CA382111983815C204501A02801265144B20098142C00112D03410D090792A22070D0967001300620180C8B002210270523C92162480620A608643600C0346E6142845C062C01C44048A06809C4640C43889C0202013082C01002DA326C08C560E2C2050C938DE4080CC30028A340301494291119800409504B368A50484220A668E3A050C886001202024A442CC9C408C1A64524102C0B43911C234E548489C94080121606441625A1205088140D90229294384C80304C10C47013302A8AA84959162ADA322EC4C465D02811D3104C13A850D9000800038C23064623B828D18865DB206C8892899A80054C128A22986D99B00003B600E3B22582440081442061166661965111B4201C08680B1928D3286E082100E42288E2825048328948028A544001244829D9906104C468249561191705E3025108C024A08005D0282013384504290CD96AC25707AFA29A10322AB2F4106E2BE2F6A906A02184B4355C2F26D0F8C0FA7DA77565461BCC8C40BCE7A4C9BC109CB1EF458B6ED858D9E3FCB29D75D3952AEA72E1ED308AFCBA0D4FFA7CD0CD91257542B632670D8AEA9D87550F02B51D54870B0A6DBA2B625898A386762E1CD774DDE6D3173CE1EC46CE6CFE2E485507416872A24E1374DD2705833631DD6ADD3AF142E9CBF4313108250BF16C9A6EB8C680B623F550EADCD872E06DEBD5673374D680984B4562CA8F784594A6DE72A048E5E56DC74C77F2A59543646933EC5DDB7C09D27A6BA87DA77F164F8439CC2B31C069A1B1ADA3EA264869B6C1180BD57C947D804790003C197838222BD73B41CA8AA324F345C08E408DB6FB3587DB4FBF73591A181D97AFE1917A5BBE48AEE07AE176A9E1596A36771F204B88D227435C586698356C469F3A9BFEBABC1C276742B5F5A3BEFFC0F6CFC9DEB8F3D82A3BA5C865DF146149DC9F7CD8CDCED076D5D6A308FE78E505E7203C836C249A1090D8A01BE81A000C707393F8851637DE57C5B4569680D31859A5CD36E1585D0D0FC50FF220B6FDBCD68863B280E01144A0F8582357C652A1892F8D2F68CB684917DFF64A9499C680CFDD261D7CF375EB6B7B7DA353019DE45342F39B3101079432784C074F1C2A181CDE6CA25CFB203986F94D20442ED4723DD6A54E5327AD3714E262EF999BE25E3ABA175C03A283D17CDB852DB4FD683D312FAAD9872844D503132A21ADCED8CC09089F9C952928BA086B597B78C2EC5B8B78390BB91EF456A5616EEE9D846157B0B2F24DA629B04B18B1F54E36348C89DF6E06D108EE6E6F8DF7C1F918A9636DA9433948429BF62AF9F702DA9A3FF5CB76D633BDDAD61EA7ECF76F4B8282DA60735E4A0F1D4DFC59223925BD212F065242FCC990A8A9C72D74EC498207590E11DE6E9157DCDA9A4DE9007D1F20A314A8E5BA0C0DD8CF839D3944907144C132E10054B8077854DD8D18BE88E4C109586C0CDCE798DA594643D749FCE0B3556C28774CA4E4BA765D0888D4DB090F2A5691343A3147CA49BE3393A0FADB7E846EEC459107BED1106CC891F35020F82ECB52A7EAD9FAFAB62DC257192D6F45B97A67B076B546145902577BF59376A0188D5EB322543D2CEDE9147A189B1B40233EC1DA8AB2EAB9C4EF623D0FD33EE0768C4184519F216C3A8AF0FE83A9E2552973BADCA07976138E2EEA5C707E48D9220C3DEE8CFB2DFEB37D43BD4CFB1D8F1D2CD29710B3A0012379BC89CB1FEA8B57351FF1C03BD0B0D3D91595E4F75810F5B713923F7C44D2DD8D3DEB254E1C9770F0FF980ECA073CD1B4B1AFF9C3A77EF4A75B77EFB29C2B0150BC98E829BCE3EE8F914F9953101E08BE5E90F2F3C88E39D752469FA7EE6AA6C0A017249ED3DE5061CF50DB924201A789DC6D9CF1B3807BCCB5472C1E701DA329181ADAD34CACF79BD80A21DD076572CD6605EE71402F541D09DA885F1D6C4CBEFA068B1DB5AFE8667D8C836C15015429BDFC2935EA45C92162B3ED9F283255E68B9EA863F27FE1BD5D1BBF93354734BEA18CF2F09FC331D492C2AF749E085C2D472B6128E0FB4D33C6A7E03FDD8DD7C41D8CDD4CAE3492F69F2FD3813D561375A5B9CE632BEE8824C5472F4F76DB4DFE5C1FB852188DAA42B73FE972FA7B5BDF3575F4551F5A7AFDE1258342686EE67D0378615BB971C6E1201FAC15447A1AC82BBC2C2C1247BF2DDB704B2DF84308DA03513A7291C4EB505D039DEFF232A1A984D09837142BC7949C54000B87D17A22BF06D43ADF14DAFFA7AB5150F60F42C4ACF5C7A5DB7B3FEC0C1F544681F27274D6F6F9EE1AE7F60A82F76B93D5BDC31E9AAE4C70282D71CA6711A0804E862923D7C5872DEDC16BE172B3570DB3DCDD79E37040EB12E510136B01CFE7F7C030C1E34D06143621E05EC46A3CB250E5D8C18244491E9982F2CE5716F4A6BEDF61EC85E2B1D777B4985C9E33AE94C05992E9F4723D96ABD7BFF52B1A297561C6A4DDFD86B483C19C52C95514D6446447A920DFBFF52312122E972A5F6869EF39612E2C4EFBC266D4838DFA9CEE0D70DD6B908BEAC448F88FE0F455802C1C1A07856FFC7C04F98A3EE5714A30E2DB52FE2D7F75C395F355479440D5FB10EE90FA1DB1120E80CA4E357C7D66DC86590F319AD3A0DE8A20C6611498E8A6C7CB854DD9C7C19CC1378FCB3F626C7667C8F92154832E28C5AF942549D6A81041F0E01094BD986D14A67B14D0B598B79EF4045CF58C88E9E587C344DBAC001F9E6FBC8D56F3B807594CE6216238DF8091E862FD800B5B44C347B69D0BC8C0D34403D3F5DFAED880877E809671541AD300A0FBE80F3FD7E044", - "tests": [ - { - "tcId": 1, - "testPassed": true, - "deferred": false, - "message": "3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B", - "signature": "4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834", - "reason": "no modification" - }, - { - "tcId": 2, - "testPassed": false, - "deferred": false, - "message": "8BF66DD868FBB9FB6B22B0BFDFDA837C40928C26CCD6100F0F53B4B12FEC0F313EA8536BC70417D0C16C4DBA53FAE01AB59836F6841C47DE6134DD80CB7B68B9DC03BAC0F538147788114314B57244EDD3802D97A6EB35F86848A4DC7BA0E20581032D97E7B49AE230DCE1BA15B02606115821AE80E9BC099BA1748F1B45536A", - "signature": "3B11E655917F17AF59EF6E3D4D8F1F0EEB2390C83FF37D7C55762B8C5605622A8838BFA7D7D8DC31D0317A7B5D421E3561AC357017AB598EA70AD59941D245BD787A05D03775287F74D376B928A17EA9548D1437F57D884B533B978D7CE167779C70A31D6A7DBC538BABED0AF6424F3E2600F3A0E197ED01E5F8E21F1C808CB6B7D8CCA838F2F1C9B7D2A0953ECDE316E9F05AF601AF3C2847C1B50E1FBC0FB300EF3E3B683AAA9E08B314BD6DC2A35A8FF6046E31D0C432603CD05EB12B817EB0CDED0192C6D9EED2D38B759F6186D75B6E14FD034FF6D806D79D8BB02183653C5E147098D78A991950BA72628C1E7E8852C860E945D75019CEB7D3AEC42AA49DFF0184EC0FA79513D1961467E08D258D97BA9C50BF46BB40773B0DEDCB2CD73E2A14AD2DEEA373BB57C2CB49A83285537197F0D6BD5EEAEF09E6B542AF74131D5BCC47EFC006703204AB8B98EA17471C67FA1A7531D3E73E59292E94DB910602BA1B87CE8B1CC8C685AF989C3DCF9AA48FBBE201074A38D96EAD10130EBA27433F80440553A1FE77B96888E85F581DFC8C519227FBF25DE6EF01C0457E25C1AB975D9E90A86808CFD04A38AE2AA5957A07F7363F865687724E4B04EB8BCB99C8A2DDAB80B60E8D6FEEB1CC280DDD3FD2C666E929ACE254B5169084A91A8434E763E99D9DBD2E1399AEFDCE40AF79028895753C6E7B5A612B47E9E4D4AEFA8064449932738B49FFF8C4283244B4387A6EC4E2E87AB51824446B536116587521D4C1D6488BF8E54CE21F8A976619CD30700CA2A2BA9E0C0FC4AA079978EE78739F7A441AFDD1B114E12EC5FC06BD169762B2BD2795E52B16CC263548EFC10274CF8B544C698B17E8886952B3D9BF20BD55DDBCF5E555A306DA426FCD7D1B8861A53BEF89DFB5C904FD0499F7BB3F334D5D85A972236B2F3B2A9C70D10C4AB973F8298A52B85B636545EEC91E208CE9B7E6100307FDE532946284DFFF5CF78E0E8229E38A49A3604817DE56947907C6CF4EFE5077A968E8029DAB0204EA034383BD57FCBD1EE973CFAA7A27781C5805C474BC14487339BCA8B21ABEB0E8BE05E8288F2ED0BD1804903628D1E3045841BB75804FEF40277B80364F4F67E3A6B5E6D5FB0939AA678D700C64C9C23068B3C3B35F337B3A0C10F8143E8A24E31B655A199C06733E546A5403C2A53A07F12514F955F2575419A16FAF5892983658498CBEDD8291C7E253DDBB9CF82E834F09A19B80E17425379F9561235B86F7AD0372BD1CACA92BA68EC3A381E62DF2CF8E638664C1736EB083A5F81AE5676421AD8172292B1EF34C0E5CA25449214C6B95886977A78023327193FF8980CA876AE9D6A0B1294E8F3779862E920860D35516E7B7443CB3A0C7D0EC7091303DD51C140ABA26F0E67B8F57536E5139A650207272DA3D99D880CE09233E9FB9804FC59B8D520E91333E49DD26AB03499B00EAEF1FABBFDC6593BE77ECCF03F68DFA3F704A9F54660C8807D5E5210D58F6B8DE248F8C607B6CAA8BBC34698A683ACE430C89760C541C4B38C1B922FB0CEB93706DCBC1E6C215DE9A8360A8AC17FC322A4628FDD9916BA865CB1F6798346624519B135F3B65D90CCF808AFE14FE49F659F14A85CAF939B29B6E9DF1AB3A55783C048B07E4C46ED555EAB538B492DA75B2E261B80A6227ACC006CEDAF1935970278F691C577942AE070F2C7EBF658327C75D5D7C427C2DA62E3192DB633A931059FAA500F6E3E4CE25E19E89E1FD2FDE0A1D663ED7E2927AD0EC833AABBBEACA0D1C39D492722C99F7104F14C07323BDB302B8B86C8EEBF7E3BB758A84B665961F14A65BC7FB8035253801F5E597D8955C48F6CBAE138636A82093ABA37008570ABF8B91C1E93A180CE041CAC1C45EC7C6504DD36BFF753A4A03973626B920132D21F6620FD4B00441E3DE4BD82691B073D97A725D0F8626E45B9A2B3CF30331E833051BC7AF3A4FE1144B347AD830A804E3126DF1CBF95F60400AE3B9EE8752DC1554B54F5A24DC95EBAD0332C2A5CEBF4CDC174BC6DD58F4C26C7E05B32621F28C9587A89DDE0168780F91B1425F486DCB4992E3D42E47E1532E01F9A1961CDCC3BC3A703D77B015642DF0BB7B82316C8B87C48DBF3F32259083575C97AE6DC391CF7280E2389D32327EB8FCFD17BB0BD7ABFAB3E55D40BB9CEAF378EFF25BFDAD7491B29A00EA1DF5A0B193B90666BD1CDCC2A4CFE10C6E488BEEA662E81635B0CDDCB3F93E4C78DAF10B032578C556A0B715D276E297891C0D25AFE11B1F4A216E2490FF309D3728D88D079B126C61654427927904F2707B1BF2AA1AD82C86B2581ECADB5087DF09D773A0EA490E6CB81375061EDE897DE8C7A80D907854714168F84E4523FFB9B91684D3EF6BE0E03338D6FC23C83C0974CB1E28B5B6CDF74953F0888265E98C7EA760AF434E3C1FA6C8D690E26A5FDC9717EC4D0E18B206A675D4741F2D4C4957105558D0421833008EC2A2F96E7B18ECEA1B1800B3E4C07BDDAA71FD923AA713BE1F09A016890935C707A78CC5AE8E828F658A6797D6CF75414E9BB154BA3D13F1B2782F182D2EBBF93ECFAE43CF89F5667A1EBA62E816863F62912A64E4A329B338B7C8DF34801C9B5E60A097954F116A1DF74A1355D9CCECC700F4D0B7A8E432594AD104C6DB2D8C27EA98239C9A4A231F84BEFF79A8A797BF0684450C7E5F31A77119E613F6A1F6D1636E305B24A263294FD24FEDD9F063E279DD1FC1BA5A0150EE3AF0227BA5F46FC4F58289B1029A4A93C2C6EC1A5B9984EBA0C33411698AA154437CD0BC927119AA64D9C148048D77ADEF38895B2738C4B0DF42B9CF9CCD08A36731C89E64D9329FD5B8362539A1797B76D5C73C051C8159ADF9FBF5E3740ABC6B57292FC69B20451D58F5A9823D89CD79803B9FE5A2A67DE620C10782A4EAD26457FAD1620120D7659A78B92009EE0303EDB7A0D0DA75E0F7B791BDFEF285997C9445361FC8EB84470DBA40116A99788386BD185FBBB02C7D8964A52D1BF9A27FC8942732FA54209DB998FADFB0D591E141897482844201ACF0ABB077BF58A6ED1D2A1438657E486B5963757A95877597AA73072AE88A5B681D4A1879A0CBC361681A9ADAFBEE0796A71825FFA889EB7C258F7D6CE02F3C2647356013CC115C9EEAE8E574209409D271AD544B329A8F064F17BF3DE31EB439307E4A4584693B2D319263810C4C23BED480170081FA870FCC67DD50A336B9B120686BAAC8713073C3707231FB7E02EDB04AD8BCE6C024D5FF799D78E844C64F0E34EE88961062850ECFC10BC9495A7B8386949EB9D1DDDEEEF6091D263C494A4D5765686B929397A2CED0D3EAF2F72B2D2E3D52618A8E9B9FB5B7D5D8E1E3E5F2F33C3D4647669FA2BEBFC0C9CED1D2E0EFF8FB0000000000000000000D223546", - "reason": "too many hints" - }, - { - "tcId": 3, - "testPassed": false, - "deferred": false, - "message": "E071BD6366C43CACDA4087185EE99855D3B0F6C5A83FB9C2167EA0CE365D6ADA30844F05F178517BA72519C3439C6ACF57BF6CC76D9F8D3077AEDCB740E4D1F403CBB5C8B8EF153F77646435703171F335E0B308516DA5E54D08F506B8C8E00C5B89F5B48FA0AF0AC8BE351384DA396DB4948020F12D7DF87F446968F9DDFEAC", - "signature": "B4DFAB287B55D27F80117C3B131026D75F552F75C6E79800A1F3EDBB0FE6F14DC1FCEA47BA927B065D3577DB997F74778BE8327A0D29C50FAD1B1E4804A6E55EC18A211E1A8034330D5A32CF7E84E91031FC85CD7FBFFED70AF934C70B852818CA282CFB4B2CA985C8003922FF4706DD3899EE39ECB3213FF2BDB44E0534E2DCD4C2EF67DBE3983FB73621B2FCD04D36896EBEED28F9579C073D2E3B730BE4F12F5A0A791C3A8301133ED772B0368F7ED525EE98E06D0796BEB4AB2194746806654F9D0DD4A6C4232DB8F4773416F4EBFAE9E87F86698CF64CAF39CB86DF0B8C9D64ACE8E433950B9A44C6B97DEAF1A29F9C3DB8C0B3D954E02486DBFBCF7F9627AF3E32D225C8D5687B5BB74278887CFE4B086F89B4A8F19F4D6AAB0750354FC1B0F8A82AEF587093D51480416FB8B69DEB39812CB94C0B96901691D4F21DBF87AE08655DBA6D6E13A60C3784DCD3F2DCEA882F92957BB8BD8F59BD18841B68567051FB84995B9FF45DA1293ABCDE2E06EABDF676088928327CA67C655607BE1FEC8B37A542BEDCFDC35E9AD3AD647937CD1D616A284E4FCD8D8BE8B08CCE62FDF34060E519CDA7AA6CD7365C83C6ECB46867552FD9DA6B5B6E3D158505AA2100AC963B000F66AD8147AACEDD8DB653BB974A426A222C80056EE90C0445A3D7D3054BC2190096316922DC182FD35CB30EDBB8496A2CB291CA66C0638B383681C8ECE75A404A16654C5845F7C4A95C22E91534329DDF49070FDAB46A5E9C4562308EF10338204291F4725DEC429628C138FE576A418B90394FCAE7A0E1A98A713813C71F3447963E5568CA592F39A2B2B15F106076893D8D15888DC9C0CF428571493A29C9F2C5C05C24FA8341FB50002FC641BB4A0CCD2F89E8E17AA8EDD6F57EFC96908D9F5B1C5ECBDDC6E87840E6530A8EB372FC22898359D6422B82B030990683EDD7FDE884E8EFFEF9D7FBE224E22FCF03614342BD08A92395F0305D5308708890E744DC2C42AAC0C22045C6BFD8E69AAE13142CC566B71EECA31C5A74A33DC5C4ACC15A9659F346EC9336CAB7AE2BD9ED3D6117FBCBF2787D4F3717E14E47A6A6FF907EA08E065CF07956AC73FA2655C153E4B3AA8A7BDF0A22A739A047FE8766BFA6B1750AB8EDFFA78861267ACB14716D2246BB697909CD5CD4C0AB05912F9165D174BF8C881B827E795D4EB42E2717E776851D1E98E69B93849B387193CA1A28DE3BC7FB8093E2A76945EB5489FC15EB13620568D0CC1006914FB3A495118156031FFB96550C806D1A200B1DD528019E97F5F805874D4803A981A73B8B4C11B6A9A6CDB899C62B7692E2D046E47400680300B395C420B2BD92C50243A2B7A86F2FEB753F84CCC99572B5028EC98CCF208D6CBBD15470BF16D31BCC20F5EAD65B93B7B82846F58CDF9F6B8054120D54D86DAB97914E17EB4D54CB1F0DD6DF7A1E9272EB24D96C28503FDBAAC0509ECE7443637075E294FABD9AD0209079BF5005CBEEA1E9800A496265F1C7B57ADC0CE0235F04F3A39BA5DDC211F3D018017C8E09F178A8431DEE9BE29EA85748A0657AE0934AF5BF0C859C4B2A87799961D8AC4A930B1E005D9138C18CFA74439D8784BC1DD24D2F6B229D6098BEC97A9114EA0628BA2D7ED2507CD1A0B96EDA088D0FD45E9E0718640461D6AE038068B9203A9339D4B23A670840A4A8E6D09A29C8FB4AC4FD8DF92A4063285875AF6A291EA6C509CC623E0F8FA1A8F9E45A54932625040FE61F0BA7FC726C940F0B64F3BB61F0EFA508F8C21DB5470E2ED612858525E413F4C42F64381C88910AC6ABAB7A47149F8DCE26CF7333A50F09CBC91F7AC3FFD8B4220B9F365B8AED8F82F14F45CB2E55B8B46FC60BB030FB230F69E2D6FA107B0DC2EE435922553AE2D35122E53214F085467FDF5588586874E62FD115162D46F18270BE41FDC721D3AD44E0EA0B0A4C082E39A868C28E0E057A353A846D5D5B32064DBE735C935157FF961FD86D6FB774A350B7BA3371FD9D0530CF1ECE4C9C09FC92DE2925A6C9E8B285F6ED9664F829B62E24B5CA9A078009D70CF7A30AA0D732239D3A9599782B3EF2BEB88ADEE90E59027C1DB649BA94CC5155D4B885905AB56AF333574A68C17A52AFACA56EE8665593F28D5F671F0049E9E376EEEDE6532837C03A52B3AA9188C3C991B894C2AAA43AD953E62CCFC1E4F8260F29956AC68A0B68D0E0B4B7D5BC10111BDE08C0027AAFF48FF21C591E095A01A4151D157DBF8DC34FB421ED7EBD181140930BC2D0A370C22A85322617F738ED12B0EF27AC7A6DCA73AA39DB422F97CB4B6ED1DB7B0619F9B3669DF905BA703E34A63AFF0D2233D93C4117593543218F1E2ECA0CB190BFF1AA792C245D1379D57A586EA7DF61314A201092037858D0F9BA392B185696C5555587982A74782DBC56F6E522498A33D007BB7A9D54BE23FC18E88FF57FA621800DAB6CE91EFDD8ECAD1F8641770A64E782308F9AB2F1EA59DB2E95DA6C77E6BA906C87C6334877210F54BD37FE7E2800DDFABEC7135DA997D403E5BA3C4B4EB2760466F2ECE0A2148C10CBECD02430395ED9F33F308D68B08A6DB7E6FB3DD50786C2E41FC333C694A39C74D8A2BA054EACE765D36C9A876BFA9CE150D92C60B8C9ABE3BE5496FEEC40C3BC5E8D7DFB2EDAA7F534742B85819CB90F3D3A02BF34BA793181D595FB77C50F583D8B3CD4A1E1A5A2E6AC23E127CF150FBB7BD6BCCFCECB5555B3B81CD35B325C1A155189F7C079E8649A8CD52421C66E9340ACD05D431DF7E31BDA1B2304907C54E41B968A355A6966EE2B8A666A1B823C6B58AF431B3A49038D0FABB4E6E6D749EEF97AF3D6EF398BBD04F72FFA053A49908E0EA03AC44461F87B5A915F869800C461A32785FB421A1A435DEF95F840B8755FA2C7146E1E02FA8B50A9A3A7571741D82596C9490B09C8378AC2719F66173B35E03F3CC634DA6FF37F73DB2C1190533987405B1B7EE6C2911D83EA6BF4BAD55D85FF2796EE044BF72279A6D23E84AF03C5E737815E31AB5BDCCE095BC4720D5DAE26605B0AEB993F235674139498FBB153FE0EBE49A4D76AEC2DD4252E9C63D891CE3F304CC88A6D22DDEFD880E0B2164438A0282B24777632368C2E4F37B8F4D5388971DE5A3BCF4ECFAD6950AEAF6C0C9A430C55C9A72DB4E40EF3D2B7F70ACFFCC20D7B88B347CAF4E15B8625231777459D90CD339EEC0CA4CB37B26E45A036BA317F279865E1267D698B94260738A6B15D27DC4A1B60C8C679320E5696DF6B78BFCC045941C94D1CCDA5CBD10D30A9C5ABEE227994050E0F17292C3441434651535A5E5F676C7D8C9397BBBEC3D6040E1E29313651899192C7D0DEEA05177072888C93ABC3C8CED0D1E2ECF83258637A7D878F92979DADB5BBC1C3CEF1FC0000000000000019273748", - "reason": "too many hints" - }, - { - "tcId": 4, - "testPassed": false, - "deferred": false, - "message": "13ADEC8EB7907557621CD4AD36126CF3B8EF81650805B8806BB75AF36F98321CE21AB29B849F74FF43087BB49DAD9CB1AAC46F57300D3DC648712E2C90B960DDD0715AD2C417B72847B17346CC00F299E4EBACCF76038E3DEC76B23CC7BCB1B74E47B58F46809C5794E55BBF4B2A3CFBAEF6E84270AF258501A152616E4C0EA3", - "signature": "7CFBB2E16D1D00B96DDBF76479F0EA008E851390958F220CBD13CC2AF84982584B99BDC9AF25C596FDB34266C6E95662DB7817580F51156BF9BD0F1E30C37DDE8056EB17D3A706BE0F21C9C7DBFFAD740C16C83019E8588A3339548CCB7E477942902AC5B3C1A05E5DCDF575A62041915CE57270CBA4BE6CAB1DF2BC021EB206317F8FCD290462B4E6B4E0118D398A5A4CA8B91137DB39497DC6B4D9FD20F9BA9A3FE59DCCB7BB23FE60C23DC48C571E86FA020DE7EF32DD0CAFE45925E138E3C9C6090A3944F4328D22081D6078B9163FE52DE4C75B6D6210DB4C0D8C1B46357604E743DA5C4F6F32C131B936D70933DBE748A5ED74362A0985C84B48E4C983E33EC8E2A3C4A47FECAAE3BC24077057909F3B8FC9F49B0346B82BE85C941E97094F7711E1B4A4C355FBE91791EA809EDBA77BF7C90C13DF3B9ABF4FB88A34D58B8A09B26D39E2865DF480BB592B34EC8EA2EF8E91C65D0DE9B53BD058AFAAC7CE90CD64F5218FBF6D961D7169C809C5171720C56BF8737AFB22B46A552B30A4639B48782CC5C4B4BC28DFB9768D65903B7BD18D7D1A648F69F1EEB7F6042FB148CBF373BB539FF1A94F4C99E2A2F060A900EA4474954244749B8373D4C78616629D3AE9F45CDE61DACB8A45C153088FAAB53EAA1A4CE489AFF229E1A8E9EE1F0BC74BB0A4A9B0452C2E153346EA3A4CBCCAA70AC06270CBC6CDA804A8706112CC8D42A7EB70CDF0CCF4379937ED9570ED58F38329808445C64640A16142590A0DD982EEA71DCB122D1FCF9458F58DEA539CD74E83A10B935698E6F9887457963B407D434B52126DE56E12E56643DDBD0DECD749F6C42DB19B6AB00F750257DA25B5310AD0DCAFB8E38493898EBF7C0493BE5244163001EA2BFC10CA8331B423094FB78A71F8639933830D8F8A6BA295FF20DF9890730B18EF206927B0AEA93AB4210CE7B061E64F8584A3719B84F9DAB14F95AB6FCC7B7982C1682B6E50300CB64AD2DA9362AB2B31BF273E05579A9493CDF007D5C3F62A23FED9CDF57C154E3C7D1D2CAE79B39A021CA488FBC06B3817AD6D2637830B8DB69E38D002AFBED69D00371FA06D8415D6EA91FF79500C2B04D4DDADCF91C0947FCE32F9ED2447F0ED03BB0F489C35F90E7B17EF1A95A5F5C99CD4CB04F7A949639F11431A49679470F49FDE30AEEA26A0F3AB009BF3B89FF223A2092D40ACC32C47E9A2474C5A93D3C0A8AC2CE633476807271C13EF5C3E022636F87E1B6854E1ED156B0C193BA901BB74C6E60E74214558E576B67E4D53B6DFD6C6E351A3F940FBCA28991706CFB6CE20F80F62B4A337E2497EA70826A6264F128506AAA2C7F408E3A903D3F1D7FB2F8F72590F9631F55A3E55D7DBAA9CE4B6FB4CB5FC828DB7FD9CD525198664894D1A37AEDEF1A539E93E5729F95F76885EC45CF05D83774ED5EC524DCD421C6589EBB12712D14966EDD08BF997BB8612D050A12EB510ACA08E07129B61E30605FA77BE1C3D8A15A27E7D2DC1B3F81D3206CD6361222C501982D73D947EAA4A93FA2941A4DBF05F03CECC25D1F6CF7A563608588B8E03635FA5A254D3994BF062DE3862DF9F8E2B97C01FDC3DB009B299108CF262F6DCD00463F1FBED33B96A1593590BF81A30CD2F8D41ECAD7038301D4673915CDD4F937EDD166FDFC7790BA20693998D6A4B186FF5860B902D53A70414FF20AC7F89C883938C4A5D4AB1979BBEDF09DE309235C8A94A6755C7FAECE66B81BF36E7EA59F9D8B08A987AB6102D4B2FA04CFA3FA9A6008373F9B1A800461094F0896CE1B94AEE7096EC7A608431F4065293546447C8E1A848E31C632A54F014B42F81346222F0FA1DAD0EAF017CD47344EAD21DF73C2C00EE7052F35C4702690D0B5D8069DEB44BC3BED23BF6DFA460A758BDD29A4C415635FD4BEE274A69A277DD2057F2344723CCF932776022A82279C710605674DE3B783B6246902B19CB3A7E293FEB723149B0FAE1756CBB8D472A9D2B713CC44E38048286C0CEE06D2802A7290118C8B40E8859AB23FAFFAF6283097E2532FF48786CCB9FBE1379FEFFF6F4CCC96A21EC8E1AB218B6FDE46F287F3B123E661C71681AAABA15F76C0747DC050AF3A8E72607C7A2CB6FA8A42721C8D1506697F8F2E33DACD6D779A6E9167343B19760B86BB7547B09C2623412D344086C2C88DC9C59E383BCC6B38F78068E90E69804799B885DA08234A6DA74F599BE425738B18E4C45E5196AFF673B3DBD6DE81A4D2685AA8B474E128BE141BEA3D17D972AAD1C159E7828BE499678C7316E1C0108D14F9305297CEA54982EAFEC308BD2994C2C3765BE6B3CF4EF7CF7985F0EB909748FCA242BDD65DA8B279786E9A52BD9846E884B881640F1DA9569BE33A7431BA43FAEF27C835028ACB63E68AC02AD54FB3AB9AFF1C8194782641E2EEFB8574D6086FC5021245A9D2B5570A4850651605829D491E8E5A63135C91DF65D1C24F3B12B35A1726320E96A4A43C6EEB097B9E4F5EC83F3AA88BD15EDDFCC847ED1AD15332A86828C7FB85F87C1DD2BA15E1ACEE80A0FE5EDB4F0DD18CA4DC95703A24B91A98F2FA2A327E7AE3856C5D8843F08F3AFA75FDC443AD5D35C385AF150606C10FF4F6ADB5C7E25DA5BF317EC8DDCC8F7C8792E80AB6E0683EAB2C3CD5F48F23EDC5AD4196427F462DFEE7F742A71B594A75AA70F63A71B4308E0F8FFC0A0934812F959E5C12BF3F38EEC30ED74936C3E23E31CA3DEF3658776FADE8DDAE0DF6E3B9AC3372002C4E4C3E73B0CDCC756913B22970E4B9D2BC88E1C1BDDE37A840B54DAFC0B1BBA8C467E968BF78FD59A7A0C61B03415569AD9D0EB8BC44E3913CA8F980F045E7D52332E778F39363B3B27959F33E6574FAF8BEF0836E49E912F9245927599BA10BB39E4758EC846E146BFA643BD53BEF3124F0BD2EDCCB302FC18CB7BE16E8CBFD279520A3D58A34EFF4FABAB36344CF25DFD7CD5ED029CE63F895FEB4EDDD9D6F26D945F1E985F532638464305195CABB0D3D0B2074642AAC29A4EB966416769E76A9F080F3DBAAAB387F5E49C3A0FB95019A548C51D8F09D2A05E266622015FBE1D6D00B3C88F2F32DD790CAC516B2C2E6A2948782AEC0396A2FB6CFD9CBB66917E703C97E8EBC50E47BEC61FCEB300043E957D236B0AFB15A937502BB9DD8EBB2BEBAC3AE44CA43EAF48A3E9A3FF65107F83B4D77F7E39EB49116DEB83E2F01D22CC1F76AC1E69E1AD6C5D71B453FCE314886C31EB06503D5AB5DEDFD9DBB33D39BC3230167B94F4719F043458B44B19800CF6BBC16802929326432739EDC2184B56608E969DD0171F323D3F6C6F797C97FB02070A0D2A4F6F869698A7A8AAB5BDCF0622373A446C778BC7EDFA000000000000000000000000000000000000000000000000000000000000000000000813232E", - "reason": "modify signature" - }, - { - "tcId": 5, - "testPassed": true, - "deferred": false, - "message": "0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9", - "signature": "279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A", - "reason": "no modification" - }, - { - "tcId": 6, - "testPassed": false, - "deferred": false, - "message": "224031EEF8F5E31DB25B2D2FE2312A8F169D8F17DA7D6A0AFC7DBFC2164344FEA82BFC8D20967D96DD80B5BEA1093EF3D32DCEA654DD781ECD5185758CC19E6819CF382124FEBDE443E3F4529C375B82F34C83B4AC5DCDE04C208CDD7BC17AD2D352F6FD8B323F57E27A0422BEC53F5A2E0036079372BA0FCDC45364569F5E48", - "signature": "2CA336FCC11BB4D9A3F6DDA5A8B1A03F39E2C6FC5AD45F294DCEFD35EC61464A7AFA41BD258F5740D924E7C7961C8CFF7BA028D05B5375E1483B51FA6B5DF83B30BA4FCDF6618B6A261589E019185BB4D080A40927BFA3A6068BFE7CB849651DFB1FD9A5087213C6170A0F052CC374DE843E784BA3020552E6F317A229906C7765D4B0F9EDA40281758A365EC1CAC3C4A988DA93857A1F40297A1BB268E5313577463F26355A241D2035AFC85867BD3D2FEAF144697090E873182590A0CF1A70010D1BB5CFD3A9EBE9630237F4AB17D95376E344F310E2469320B2C6E11E9CFFF1864669DBA775FA6B8F6B894B74307A5DA310013CC5491919D03FCEDC59E92427A61196744BD5432410DD4F542ACA46515406EFA08052C3E64CA35C1F0091109968E44C2353FAD3727CD15B058BA2A88B862988915FEBD10DB8FD515D5E4DFF0B4C212B74839C50C488B0D8D52F47223EEFC87793D1FE803FF7EC1B6B984E00DCF750025D6B58403B8D274CEB877DB39E00F575611738C9B4F3468C23696E832CDDB0F136A59CA7E29724473EFEDE9C2B645ED5F109CD5A187AC21182A05E6B5A121EB86B1F26CFEDDCD96628EC769D6A839AD31C1EF817F6CB3DD9E2332E13DA61BC1AEE42BBE645C3268B1A7AF79175026F78FA757E058B2385D598AAA9F727B5F2BDF93F71D1E2007A53686B464BE838F904F067ED06782C7A09761D1A0D679563629EE353AE183F6BA7091B3BEA4230B32CB6C404A4AD735DE64E042735C5D60C800AF870D7E3BDA384F2D033047FBE85755C935982A5D84684AD7A068E2BDF66ACCD48F35C1F17DE3D0DF4B974AD3615FC9095A21300EE8AF23B91581FA4B596E9E3CCDD82BAA694A273EBAE7664052BC31983730E8B12E07A8024749186259A3A5B97FBA2746DBEC6D44120150795E99760E667E506C93A5372E55DDC84FB9563E644C8BC8B413BE27CE6E479EBCCE0B02BE7DBA69E91942DD00D290C9FDC76A96776C371D1627B985BE7A5D9ED1FE18508807AABA20EDBE9768763716541CE6CB3C1A7C9ED699C0D52692718D2914AB91C99056F31F0FD16C28D6892CD59B4C183DAF46D0A9763E2451C6698B93E55DBC617F25DD528E783BEB671F96E947B487AD9A0517C19C4F47A41877B955AE97BE095B9D650F1413A31C10ADD0AE047464E1CD5EADA4A3B93435210EB35AEAF8D395AA29B126EE2E9B9EC9FF3232A96879BAEA38395B7AB3AB866BF0EAD9A4241DB5DCA8BD0377CC9D6D772321F5EC6B47A9CB94C4D9F2008663165F400AC1A16E1BE2BAD0A1C3B85A2FF909183359528F6B4F43745625CF3B6EE4C71952224D057B653295980C6FB452BE01078AEA2FC5A780F10D87F7E1A12454DBEC9537075289FB178CC3FA5723E0FF0A7BF2EDD9A009FFDD5DA9BE606000B427EA2E7616A2057D8E395285ACD47FB7B54014D50A6FFAF463498117A19FB5E2152BD75E8F36EBD27BEE3912136D39A57414474F3D670A07761ACAFC0E2735080D9BC781CB7F3CF7F28CF21332558ADAB9384F22EACABC8D4DD7801256BB6835F12715FA43BB72F2C8F9653ABFA35A72B2EA6009EF90C067142C82467FB596EDB8D4301DE6D60D90CD474464466DEDC3FFD086312DBA730A589FC7A8F62369AD00BCBF89C1417DD9323A5ADFC0DBDC4B18DF614898BBACB73A2DA5F1E71F25CDEDE5CBC4AD32739911E8CBAF9496402A17DB96C18E3AFBD69166BAA8863C76353D053204897EFD95E3599468BAD7A7E2A91679316472004768B962C026D7F139BEEBF00576478AA1C8524A87AE96AF26592947272AE88692D1D8F5314252BD408B4779C2FE49AE3991F59969FE9B55F02EA45970F048D520D51685D84614890003E827976089D3124E88AF312D22135141D29755F0BC040B9F3B2B0476BFCA69BEE23F974FCCDBCEAFE85DB346139F5F8E004CCC0FBE19EB0FEC0E9427C528A2FE1E2B7E03E8D7D8C7021D5E44BF45D0AD3FE388FAC30606E6E1EC6149BB3128A8FC13595D635CF8BB1B52C6656019AF80C49AFB6535F99B8B139AC76EAFAF918F3B6ECC96EEE29EE1B0893EF8A51CACBC7F24DA9685E50E5FB938006B28C70079C047C61011AC289763EF2E5DACFAA3DA80710AF393D01986978E894E2373F4E9CBCDE51C0FA00C471A4A5C44F41D25912C6B43A0BE14A8F608189E3209D69689488BF0CB4E4B5C289E589C662A16451A0F0A849FDF9626073C3DBDDC893BC41B2A845891DA6C1F5C8F37B5E8AF3F2E7F42C22C2E28ED25E1CCD47C4C2A337FE704784CC8886966D2142F2FE8F3AB8DE8ACC228C072FDCC0626C52196E94BC926AFF04CC14B70FE5DD12A7DB2F6120E3AE6143CAB3B0E8631CE0EE90D5BF507312D0009257553AEA15AFDAF81779F0E84C48426103BA189184C4A71B227DF89CEAAC7E4DC6F103441567B7EEB92A7AB2576EC0FCC0275B8A9D3588B909CE3C1675094C0551C7CE0F82286D226133FE8B751204E31BDD579005F7605B7C6664638F4FBFD3C1F8370C07EF3E70764D12B13FEEFB6459B279DF1ED2A40E9B58F84589773F0B64E10815E7905E476315152A228E1E024FE1471C8451473DDEE11F04C01DF26B8DFBF529F32E022CE4948995FDF79A95FD462C83F38AD7568639EE078B3DF84ECC0EF17F8052FF048B5F884F021468A319A2CB65DA3843B9C28490317C8BACD42193DDBD5AFDEB9A6870E955FE869ED76A4BA41AFC65901C0EF6BBFC46A26A619E04F8F549B9565BB1C9545075522191D5993A51AFCB448AB9E888FC400A060803171953897046D28470BB0E73C2B308556789522E3514E84347EABB6744E7052123343AFA90C0C529534A389E561B87774F1408E8C28F669247C93813CF680CF8751749DCDDE11134B92C76D6BCD758FE9EACCBF165CF0D41269495487BD3C5D7E85890F00718156B4907DCCBCA498B528E88DA1DF08B1D7D3BFC4ADC9F30DA8182E9971E7259F9958CB3F8B905E27513332A6FEE7BA3CB659A68EE15FFF061BC567F09D9E53BDF2E61D3133BF92012A3A54A5EDF5093E6871FBB824408AE33623E99E4033EDF3CAAFF1DA1498A235C1DB7E02B18151C045427B701586A396A69A9335BE8A14C9C010E11969AA2BA26A64739F7015B288029466E7479F87C938C40B46E456D6242C107488E2B272846513428899619DAED1F5F084879763D330FD8E7A2780DC57ABF27EB91CCC2F9D704545DAE719AF611D06E45F5CE1D6D3EFB695B5F6F8E7CCDD394EDCEC22051AADD5C069ADBB42DCA5206D50A95C77AE2DAF141EC8B66ACD8161336B6A119262A2F545D6269ABBEBFC2C3CDE6F612182A2C2E404E5258646D74757B8D92A2C0C6CCCDCED4E4E7EDFD071B20222F343D548092C6F505305E666872767C7E808289ABBCC7DFE3E4E9000000000000102B374A", - "reason": "z too large" - }, - { - "tcId": 7, - "testPassed": false, - "deferred": false, - "message": "8408024F21F9BDA5DEC8F651A4FDFB30C7C427B3C41ABADC17AED23818BE04ED6AEE3B9B0DEF2C5B7CF59AB4678D1AEE0DF7DD537F7570C0A4103F4E553A9B797D5DDFBFEC0928A518A62834DB5EED56FC2872B338824B4AAD28A535944502A529761354E4161780AB15D6CABF1DE84945D49357DFC5EF91B2C4D50389D3BAEF", - "signature": "3A7DD5B02C1CF92484C244796653FFAC9F084F2F04AEC56E362B9867418FF3435B321697D50940794FDE228B4FEF5492ECCDF59954157E3B2288EA9E880F16D9B1EA67D50D25976E5F32D14C2CCAE68E388FE6AAF6B349A379BDCF90FC3E6A2DFADCD4D5707D0EA4E9B4956E051407F52112C4FA0BA8F11E787503268228CD2E289E18F704237614B2D44C13087FE46E02E5EB89108565074FB6BF1423F69ECA48D051ECA83D14841B8AEC3C05F722E38A6206B79E39FFDA6033E36E6A794ABC84508D449B64B847FEB5D20CF56FF1E2468412BEA8106D66E417EE48D1DBD3CFB167BAE14E593048CD1B73A5B0399C1A7392C9A82B4D4BB62B4915FC75DEC75F39C029F31D379ADBB872312DCCDCB91D17E2520CE4BA8F41F8CD3D33D6EBFE9F9E7396C632CBC27D7AD3552C58C27A13FBDB1E9C2C5BFA85A66C4CC206B719C4D2824BFB6CA59358F2E90B40BE4B90C981527A08ADF997B5B0407F7ACA27B2AE7FCCB0CC56E43051F6ADB6B27D1656D93F4003C30732B3B16E227C8D3E04526715CF23C4AE36AE3CE011CC3FC4040FD35137AB8C4B007AFC26311B32A540975BD79BBEF2303EFE157309B7B60DA66E63DD3A202FE46BBA0AD37F49F2452523972DC59D5CB37F976463973518D05EA823FE910D0F9A32EBCD5FE15B794573899151E585F305320BFFFE537F3CB4EA229F9A7425FEA85753BEE0E3938734921E55395B1C534E85B0568B817E53A69A3D835C8333F771D9F0DB43C40D33A6C4F663B8A7F86D64AD9CBF185D4AE386C2ECFE8985FA30995E8ECF2F21E3D22640E2902588C879DD85E66E03F0B7B36E3889A715BF6310FB6D32655BE7BE67F2739CAF620BE33EBD135E139FB6BC494E23C744F1943CB225D3930BD6A6F05F4757D88D7A06FDCBE327EFED6061A66B66C41B10EB07A4D9B0C20EC48B6B106BC32D9D892421A169D0D90C27C12E8534DCAE38555D1B2164261C1770B5091CC6A2EA35C48EE5558B26A741D166C43FC9EAF1D7F40CF1A6B7880037C3AE0118F374BFFC09B2842B91CD8EE1BC526F2ABD4B1470DE4D4D2B8A993D0093EA75CCA353669C488E043B926CA7C8C800F2963112D931B047C9755CE0C6C4B49DB1788B52992BAF1FBC35A10184DD41D1A134FB4C47B37275F0ADC9AAA0B66828A3C903D333B0D8F423A71A2C4BC7281B1E79AF89CCA0DD3D739BDEE1DB0452D2B37C45D5271F414AFC2352D2AC5588A3DB02DB60417455CE08FBBC440FEC58A058CF27E30C237F84C202B3ECAF3471A65D9496189CDB48629F285577B69DD4C1FB39D697EE33F974891DA644DB9432F91A3A57131B803320E3FB26AA87F41780FF96314BF60D657902A5CCE713673345A93CE9D2429B2336FE9B066E080859DCF9E6A8F53CF460A14F51E7BB3D79C04F9881A1F3810859F23BC510D41AA2CC1D587687D75750C9E028E1D2EDB28F3732F81F35D7F2437A92D78F132650DB653EC5ADCBCBB7FA18549024E6AF37D8B663374CC73FC2B0A648F50F9FBF7D31A4174635B55F771C1CAB0F5EB9A0EB2BE7037D56C1A2E2111DAED6C811957C7192784BFD6E73F469F13122274A96AADCB983BFB225CDD61DDDA7DFFBD35F6BFD2FEA9F13F6CE6E1E41EDA5EDA64E816C7A11FC272B3426E8FE331D2D72532292D61350BBCA519D6168497D8DC9FD38783654F569976BB31C4CAB08E7FC0E143929F1860343FBDB79952007F71408224E40031C871AF60F040262C54917E3A5FF6FB907F54A8A243B8B1616D4355488E979789A9797CF887490542E013762DC10D02636792CDE553906A9567A3C4DA2F82317662316407B3106C9B03B581E628F1C6576DAB45316275C1476070417565BE835E076148D2CF15C0A1709E678E1B45F89574C4FEB1115CCEC6478BEC83388D244951813ED4D23B0017E02870412C081A79E4AC515EB3E99C65F4905FA6A061383991B0656535C461E18CC5D0F23BEE21D3C89859163451D60B7CDA9D674BFC1862266C09BC28A25B5CA2191380565DD870E06CE930EBCC844DDF54E05B3F17CD34E031452741C05F90985A45A369DB87C237F6523DE2BEA9075655C1B083007065A083B1D010F6A69A9E4E1BCB0E79ADDD9E0A47420DB96CF84DD34C3444DDEFFC2D3E5E2400BCA8242A46E1855FDDA2E5AF3C730A07887347EE14E230DDB58E1D57C69508A555BC2F2CFA218725DA0F913118D2023923C834F2ABE3BA63148D252E61F8232B7D79AC01050B9D8A24388ED265C10A9F23480E55D532B874CA9FBA496C8067875BB90B9A29F7DEBBDFA27AA5F3DF4EE175783B542ED4D880141AE992EAF080BEF83E378A9905D307047D1FAE932D284E2D54A91C0871A1BC7594176285B98776DF3D0E0592494B8682D1F8A15AA461AACC46CC4465DEB060FF8096680109377BDDD4C43B1AC107AADA2D177B480706D9E7587E0FCC75D37F338021B2F3B1B5857C46065FC3F6563E4E04E0740A8EF45FB332766D8395FA7B51EE29E350FA63326C157A50E81031BD0A8F3E48181C34C2DDA2A907688601603B88855EB5E0A366809CE919725D9034DD33FCA05A6265CE839261EA286E39045D77A9B46898032E486058841CDF72BC44420E28B8AA3A44A03D969F8C1444263C407E747BBED65DFC985A3800BD3919273CAFC0E88654B5625F8DC5B6479F8D10F39351D570752D9541352FBAD34CCE44AA8EC3D2FC67C9F052DD1555B11E2E51D95571A468F29BB2A31D2EF9314E131ED76ACB1CBCBF60165A26F14E5FF25036F0BA03A29F8A382B33C042A4B5281245B75EF2ABFDCF899481ECDED394BDD8E9A41DD554B1F847B429D2A9254EA15611174453188F2475AEB692F40EAC3E4B3515A8598815372BEF0683421E174242AEFA4C1FD10CD042A1C6F920840D8144A9CBACA3BB15E27B20208BF6E8CA153DE23687FD02E570165207CFDFC10E37D73F2BE2DDCF5B7286EB79DBED8474CD2B69BA04122FB73469E66613E36B6C7953526D97B92246414023A93BDA49979F75613B89C47B0BB4A2C3AD65688857159295DF92C32CCA2489BC0251CC3DF0D42BA777137A5E4BEF845C82B65A9FB8ACE89AC1005A00581010B2BD446A965BDF81EC216BAA6C5A6AD4CBEA18E2505D750CF67B97EC9B97A7008BB770F90BEF9EC3FDBE2D0BD0CC43E046D56C2884EAFB92137521AA1C3655AF5628ACCCFA150AB517538F8F293941783354002F243F8E7F1BDB19B8DD81FC7EB5271C3453F8FD9F93355CBA53897FD6282CBC8072188A18AA6A77E24FFA3998BE511AC7728FF05191EF87DE78BDE35A9661C4B51537C8689909398A2A4C1CEE9041446505C6885899499E1F801101626334150525B7D8EA2AFE0E5E700040D181C21252B353638454B5152565E6366696A9CD1D4D5FE00000000000000000000000F1B2B45", - "reason": "modify signature" - }, - { - "tcId": 8, - "testPassed": false, - "deferred": false, - "message": "422DD79F96671E4DB6A498AFCD51F8D13017391E0BCC3DA960142CECC7649C3A729112FE4D9D5E14EE1D2660C04770F302F0CCB702A61D542B253DF57C0D6ADC0558F63D45FAC2FCCF3CC4282068CE9D0AA9F93240A29368CF57F80F9A2E51B24647C98FE47A9DFB220D5A950FEDAC2335D723CDC0B123CEE7DBB8E2F5E40A29", - "signature": "8A93A49DE7D00822747BEF9A59FF02E2940753A7AF6F6DBC20EC14F685882ED25061533DAA209776F6174341A9C5B83BABDA55E6FA094DDA606DBC7915E5E5A6316D509117867381F4F69B2258ECC8C5564956ABA4BE7C80C0919C2F0319613790BFC54AA2E288AB38075AB5237B5A022BC8D7F1188F605DCDACDE318D4E2D1D1A24A326F6E41941E9105DC934E6CB1BC81A6ED0DAEADF8DB7E21D61148D5E46ED7E7449AA04B07936E7B90DFD4B875D3265B9EB5A370F9CFFFE2CCC0C74E691F5A1F673320E994CC3C2FFC8A1A384FE4C92D43D67B3174A2357E8E5D688456B366620DCF02BE7897012DDA1F9683658AC61AB34B6CB5B23891D4421ADED563734280A7FB42BF1E56962889DA2E7BD2F089E7D95BC365FD5A18EBD802D7722AFC6932C4B01C881E30766539B20A14801EE4503370B8485F7ED0EB02E2621D2E8D998C4B56ED5A9DF0F1C7AC29ED509E1A1208C4A173CD0ABFEEA1BD542468EA13C01B7A95C44B269D40F3BD0E6F8C1175FF28A8D43F2BC27E4A68C3D6F980C6455E1C3F4835874EFEB2E6EAFB0A9AFA0E35576B212E98ED67E04CF4057531BA4F78A96D507B84535FCC893095D28C87EE070F6C3724BA9CD4F79E464245A09EF73F0DB69ED23B73C690596E157C394C75C120D26B94AABD91A9A697B4159D826878E6BC8ED651EFCBE4914B55E9F65859C123CF2BD0754509C062FA9B9BA0588B71A9FF3876919C07D2CE5F5403E40B28FA51BB309F45373D0716DEF200F875CF1609DC74AC3F6C13E5C7C2C9A47FEED5AFA50E8FB21504BA7F35758B05FC351F5604298509FF1D44613741434A29D37DE8ED7303E0BFEBC014B35E610EB73514AE54CE930E13EA566721469D6878372791BCD22AAF376EFB73FBF0AD2D9213277678EF18B0FF2C2F280A140EBFD0909628BCC6E1077210022404E216224124F2A672B9A079F42D933B79586681FFEF7E28A1EB565F3A5DDB0282DC818023D1D30306DD3F90229BAEF456FBD5DB6D49A07F698F5E4B8F5554E08D14D9D670059E120369BF25F1E4E18DA778C94D3F8D9B47D4D29A42A08FEB7EBC0A5DE6BD445CD8A6E5B537FAEA2E6AF93177AA1AA7393CCD876259838401CCC10C9F05ECB6CB301CF7C59D103E5690A5BA9EB970393EEB272E6FEA4E502F55E9227D22F8BA16CBC51FFAB327A8DC0B634A44F131F57CE89CC4EE3F6C440FDB50A7D54B1C4BD6CD11D4A8D4F820BBE15997175346EABA1C895114FAABB489FA7541E0B9B117678CA9C745F52AE7DACE76098B5AEADCC69780F607E05DA018D0F9CF6D02996FE07DC2443C2DE8DC280557669B8E7456EF852F90BFDA9D1767F3132976E9A30758DB8C127C6BC173181E0CDC1558DEE0B897C8445BC12840A45ECA768ED06D82685F2EF907A90B60086480758A8F6D5D5FB1B5BEFAC7A33660B85E4A8A2502FBACBD918EA748B4870B171AAA498A62170ECB731CC7A6C14CE9D179766E433F416BFDC3BAF1E8635DAB2FE48CACA98597A766128FB1BEEE7BCD73D0E6DB5F24AB1BBF28EE8D9A8D00C70DA37D46390F1EE0ABFB5282A8B978C3D8350CCAEA2BD0D75E0C8CB10FDD5C4B89D418590DE958D5F7DD51CCCC9BB553C9FE5AF568914B3910A6F8BF74957C546DDFED572A6C2B8825492DC03CD516C6AFA1BAC6877A090618727B794204187E46E5530082F259C170027F521170A70CBB7C59CD2F62E1C86BFF439A368759857FE547E742B0814D7ED8BABACDFDB2CAC044140B2120255DF4B7C930A1B3E434ECD710C01E67F6A38F399052BBF59073D46F3AF2DA1462938606F364DBB00F5E7633694FDA8CFF2CDFA9F5C5D5E1BE9E67A6A8135B4132626FD851146C3702D17C0CD3EC0B1E824CB98EFC557EBB9E9EC17D85A99A797AA24B587536DB3C0CAD1444D0EA777680A3DA2D45B7BD613F71FDEF665EB334194A7BDC1290437FAEC0ED1F2127FEEF1D0B98E67038DE9131810AB1FC07F9B785E6F5BB5D54C0A75FBDACAE7C4C1C0DDDE98F514FD08D474C7A7ADE09A54C645E42044AF69D47B28C94C95CC21BD6EF867F5D4225EFDB732D17A222DC2A74F0A87641C34CD583786E8E11046967574A02D620027425F4D5AE34087E88DEF7AAA658C43C6E6AB9B008602932C7EE5A03AEA56E54CD72B80898BB56769419DAB7BA811667965126B6ABF260A75809BB036A94121E767314314B3185B3E6859EFDD9FA7622E24A39BC64C55DA5BE1A9C31A04CCBAAA24455589C15365FE8BA01E3B12DE45E3FC2B248E7552DF2D5A603F9AB97CBB4DB762C3198C9F2A5E200749B35891696AC5D14DA85B323FFCB9323664C10D1DDA7DBEDABA11F8753CF4E310257F5041CEA0BF03B4A6777FF4C929EF0AD1A08BEF3B12E91C542653060A5A420B4EC72D2A13AA8D67287688DEE3CFB8B2C1EEFFF045408FAF927D0865EDEAFFC57102140E94B5F808DB19F566CFC21629667EBB3712E49BEEC070FA4E361A28FF888DC58B4E6A26A8FE2E6FF8014FC9E35060853CBB5162D06F301B41E5D1D753C0BE60531A94CCC06919B9C0E96B40FCA2094605C98BA5F4B8527FC7801B93E0DC512F06A05311A101CB954D0B3D7E142B2ED010AF4E8FC247453BA33B72CB06B03E925F42A283FD71A0D7FE89D8FA465853403C40721E804C79025E533EA15DD2F67155E1963A66878669CB3751F0054AC722B9C0B18C1C9759C3AC0337392E53762D37A2F9C4CFB5049485B1D2EE725043FC0AAFF2D7D81E89B33C3E8DF1D0AED1BBC7D767ECB876D2FA46F310E5F31881590DC2C8F68D2042C565C3A89A7B41F4E19912C9A51E0608125E6ADCD5B18D2AFD01A68D7E1F6237B2F25502777F2E882F4D995C1D2F5A3DC96D12F6953343E70A46A0F59F835BF4EAFB1C37629B94A05FF4D5F6EC85E22E962DF3FF2D21D827439DD7FBF833EAD23940E6F6CFB2A9AB2090BD323A59006229907A72A6BEBB79835FBD95DB1FFF0138AEC4984E78BDC817D7E6FEEC791B56D9B51A2D54C1E45162191FF311A4FDD11C2C5F8843E9BE4019CE6FA84EB7A29D98E1C56C14B9C30E84FE2C35E93B93635B265541835DD1BF20A3D94D32F24E618391FCE02B98DA28DC4081AAF408A6C7AD41C249F2FD783A9829EA0808EBF0D4338849079A88236EB18F02501355006BF1DAC2F1DD1AA9AB9531880DFA90811EEE2E96792590F47F1842C6ABCD16A8F5B8429E2AE9A6E56D9D50C72AFA9D0329B77C8230E0ABD756CFB2CEAB0A21E59DD9250786ABEA3ACFDD43E18BCBE671A99F23E85FCBE2144A7559F88C81723BE12FA5CF2F8DF13300070E1B28444F566B6E96A2A6AAACBEC5CACFEC0722507F8494A4A7ACBFC0C7CA24252A4061838B9CAFB6C4D2F0F1FD11161C283334363D4465A5B7BCCECFD2DCF5FF0000000000000000000000000014213043", - "reason": "modify signature" - }, - { - "tcId": 9, - "testPassed": false, - "deferred": false, - "message": "1FF8DED450645CED8FF0207337ED352C2B2299E9E261C2FC8BA836507339C0742F9BC51A691CE3A015BAEA502605B3815717D83F4D768AE51348F0330472A779414778EA6F8C440461E6606C47D6457CDB3AC21BB301BCA78534A6AE204486752731266C818FBB19338B41091D1019BAF611788AE7CFAB68B3F97A2AA57790A3", - "signature": "17C9BE2E3E190941FB3A1A6F839FF514717F14B707CE8686DF3CDC4C111BF135093E7F3BDC3D517076DC8DA23F9B0C80D4ECC32702347A7FA169792197C4B11E698890B375E64F223F432D74E913578902520562EC8BA5C5ECDE089C459FEC420CA0C97A8FC360F98903B333B0F654A5DA3EA25FBD42ED7CE1365D01428DCA0F36A3C9E4C2F5618E4B28501873BDC7C85BFE8C604881CF342E3782B023A1F448DD4EE9154D8A04CFEE6E50E415B2E2D7F08E4D9C6235AC1FE8EE3BB1FD82C88F36B3C7AF4C1CCF0DF31AE690B72A1E58E230A34975BEB0F54C8CA80548AF0C2555CDE3714004544D802052091CAA74E6784982CFA05BB55A86D828D74A5EFD15F15D7139F8E604A6372BAC7E26D03EF9EF606A7450138A63DEE4552A601C36705A0BE3C6B44D6451B1482A87BCDCF52D4F5B75F6597AE5696384DDCACFC862D63A5E29530D60E5E47BAEDBB9DC1DA4EEFA08E85555221C52049EEAB6E6C83BB5B34FB70627CBCE826C9429AFDFC621861D3C44A8D64DA2923DF55D63465B5D93D68BD195B2980B41CB4B0F3E2B2A726841BA149AC9A481018B137E92D61DF393D3A423AB3DC39FDA160069F255B9CD92114CAFE892425E0007382004DC0ED746DB396CBE25D591D8766223A40D1292838CF3F89466C914B3292BFE1FA4CC5E6CEBD992387016C9325E319BECA538A8C42F1D4A4FF11A96B655C7960649ADCA5F42E57031586B6967C4F50B2E3E60207DBF03E5C07C4B4F9CA13F7ED4DC46ED2B4249389D4569D415EDCC84528DD38D1E7EA8CF74F7CC1F0E23D3981C0FB463E27DCF8A80313F39F3A52A11240032C299E767630842976D9DE2E9B3442A244BD9DBE453F42BDB934C47EF9E5D800AAB5B4113A9ED1AE4FF59811652D1C0AF21E389170A4DC36E98A6EB811CCD56243DAFF012FB4332610E686C8E3FAE5F5824EC57E3DD96DD254A16A1D42A3318A2893E3865ED9922CEFCA582F82013909031C0E6B6E4788A284BC49044F48B3E0C10A6AFA0FD6A672B9322ACABA141D970DC975860A564BC8947D4F27F9A69FBCFF4304A05E2E8E696A83ED863F845EB9A401D2BF060A5D5063CB0596489B2B1B2BC3BB9859B9C47A6885466F98DD66A07BB52605D3941D271DC7C30668DF692631C5325A2D6BAF8164F779D39C9B8593B290AF5E4D6E7F431886A3210E892629CA5377E7144F4CCEE2CCBB315545311C8D04C8B6BABC5BBF8DF87700523E3A306607FDFCF151768FB2234686D2F3D8AA8E377CC3CC0A0EFE07A18AD203A221C16E3DE5AB9CACB2FF58F53241BEA58548518220A6A3BE12FD2C834793D39D1764151E3BDE9D1306647657D5AE1D0F50C9B034A46C39734C1BF676E1D855D1ADEDF9D8F109DD2D9F84659F5A267A1BAE72DDF211C16B1605170FE3B626F82DB76183DBCDCFDC7889B184E8211C4F7B8826DB146C12D937D73FCF616259C4C055C4309AF2BC4EDF11A7AFB4BDB5404DC3AE4B9E34426B21975364E2AD7EAAD30A86B6071AA25FF289A7D50189981B2049E1251A2DD602B1344B2F010DC4C826EDE01A54F980B8466001E6ABB527C5AD637AB7148607DDB800F174366D0C2CA64F8B00E35C87126F90EA0DA21755FD36CA879308538FF91494D2CE46C11BE7264768011DCAB2552993DF1A3FA6421444950F608E149DA05A591598ACAABD529B22F9BD9283FC036612B68415E72827717BE0BAC25601FA00511E919054B5E08A583ABF3D33E4BA3AA1BB6223447A7DA620BD1A2E47EBD1A9A2150B1C4DB831DD02987F1DB2051D9B46DB34D4DF96B082C602DA91E3FBED168F41577C26C48B32C929940879DF80408D296B2879BB93727F492714A370241AA86357C23D1728DA0C88B699235792041A79DFA6C11F09DA09B00BFD14310E56E60D3B0601191AE06D21C0357D8DB2163CF3EFDD87B45F54D007F89816C41CFA9B0A5DC616053CDB698545F7E99C15C8A3D4A7133FAA613AFBCBF50D69423538FAF9C65C19D502CB58B6A7E4E29071C9719A923042EEF6537CDC08C34BD02159A807335E20AD0A599BB605DFA95DE966962D23FDA3FC3BEEA023D0ECB0EC1A954F4F3303A4A8FB89B4A8421B5468EAE82284F0C5D8C85DBF26233B13038222BCCD6199E5DE244BD2360CEA95848319F4EFE70FC8E98FB8C49A1A151D114A528C6D0FBAABE2DC0E596F11C20CE836F2605EDC98F49C72E9F1BE0400B1152D2F85F171EE261845E312AD4B1D1DE166FE81E07AE2B97C0BF0D508C430E4372B0D2AAB07E2EA967C7BFEC8919AACCD30F271B810F6CED2977A407E565FFF83CA6DD414618C217811ABEA2141E47C482C85AC2293C2C392BAA9AC3443275B4F0616AAD4C457ECBA79DBAB96ADC06693698744E39B3A1F6D5801C9C9CF6870E3C5C5AA7E69837E7E8E58AD72F3C6363A18B7E93EE82DA43D383978BAB866AB156BF46408B3AA9095E637AF1872636FE0AE5C425AA37E8DF12E31C38E5A1D7F7EB0EEE5C929CC9290DD1C13F4DFD1A674A49B81FAADAB243CA1197BE9500F2B33CD57352915330577DB372B8B3D9F37DB178FFAAE4A7E39C696232A57D2EA249A2928CEAAFDD7E9F44BF25F3D1477DF29FDD2BC08BC15F2AC452F308858F5F6F9D83E6C0678E272BDF9D2281887BA1FA8D6D7858E0CB8A61FA6273CA6C7B02CA95E862ADAA91CD292764D738224E1E5AFA6A5E677E528F25F0C5DBCD873143C2FC8EFD5E561060EA7181601851ECBBF594BBD902976D3FF31E6D693A5BC2A97BF2E9D244077E8F2D2F73E1C9F031ECB735C3DF50DB16FA46CF424EA1C300143ED17B96F0BCF66026692EFA599E7C8B746C6D8C0EAF77022CFFEBF4CBA7BA5EE2C42A646D483B5C7F002ADFD08BF29FFED5AE3C168E1B950FBC04D9EF3F517395DDED4B1D54DB9E56F81ED1B162C56BB5AEE6049E7F3344223944AFE06C4A2A4F8607B7D751B54FCA004DD5F545CCF3A4C4C257812E9AD0860D4FB5D86D5DA1C3BF1AF84F731DEB8E3210F83267F5D243FBD6D287006788A46A02C1D3F51BA0DA9434BD6E0E6BE5D405B572D50092AAA542943C9589F4FE4B607F7705236CD8C5918AEA04604D18521243612E134DBFE9D2D5EB164557783B12513648F9D294036B06AA00056DEFE08DBE041FFA8E949E9B555367FA667995B43180E6AA797DAE894C84D7EE33CCFC93EC759D974D41301FE6DA75CEEE62E924F9AC939CB7975E9A8EDE2302203D9975B8B5A68D2638BC562A7C0E0888E9DFBF7332380971B69A224264E2C84561DF8755968477AEEB26B94EAF58A11F3CA84C2D7EA4427393DC090A0E151E2A30375459787F81888F939496B8BAC5CFF4040E313D495C6D6E7B7C848A9AA3CCD5DAEFF3FA02092B3F4B4C739DE0E2E6EE0E1A2A353961646A71858AB5BAC4ED00000000000000000000172B3747", - "reason": "too many hints" - }, - { - "tcId": 10, - "testPassed": false, - "deferred": false, - "message": "3A3ACE744153D62F1499D0AC7919A1ED6C1511FC4D70473A86E328CCB558C682BC3FE7F175E48C6D9CD177157BC2BF58DEC173A14B3F14222C4459CDC073008CAF4C6F38727FAFDFB75C3C6192737EE0B0E93FB6E476CF2C785A7124C443C9D8330A89FAA26F421E7758171B6B8C7D9E681D108A4C3496394711A8B49D2637CE", - "signature": "967170535FD559F7D1BD00172510EC12D57ADAFDC86AB4C8117840F02FE63538B963D3B4504C5BAF8FE27383FDA4218A5B9687A4326564BF8784297890B028D21CE19B29A2DC1EB9B2BE990D6A633FCF97D9AE42CF33AFC7A045C9469DEE6AAF49B4DC0092E95EA0F60D259493537767CD0A2A495C9BC2EDD71CDFA7EB021D0F0673F602B9D4915A8FF44CA197EF4F0AAE7F81D698077C45993E4188477AD4FA32DCFFB1AB759CB72B6B2E2E82CE7D9C96B04CD4C28AF152DC89006C2652B14E4D882CEF6037E394BFE523D9F4F8BC9C565A123645B96E9C83B9037F6B64956B84B257345F33C711274EE28D46D55903F56752F9CA2B5C983BB9AB1786199314D2417A7CD7A61527C8596E4033C6AD7C2DD60A1DE3E126BA9FD197D3A0436EE5DE4A256FC57A21E537C48911BE0580912BAA0CD0AA31248EF67531CAEA67E892D31AE5FDBCCC536E47E193B8AA12C1F36786F2C88BE923930B4FA4A8619B5D22E4F0B2469F094FE619DD4F6F2629D48C05B2C58E78BDAD42F2DD6B0863E1FDFC0C3B7F907942BD134E19A329BE8F9E864AE99C36099ED95F479456A99A6148448407E006F163AE5DCF18CB0505B7B9E981A7254CBB9AF09913ADF7CA293C1E468DC7A2F309266AA491C48686A6516E2450E7CAD0E126ED14D0E3AE919BB5DB809421020F208E4637B7714B6BF0E6E153BFDED992C371AF5445FD1D78512C75B14DAD92415048DB65D44143C67E1B8749AAED09755E9FA99CCF1DF388BF252894FEFE83ACC4475F1EE440D255E51B3B66B0E25ED9F6A6287913315055992CCCC4B24F53496D592DF92A463F094F36242B4344C4F2D30A1437F638B8E6989FBA82A6246D740948EC92F97C7E8155A7C14EDD7E7E06BA746054776973CB0C12E416B0CE6397C8CC6060185B04397F4E101CD0A9A9D9801AF6383969E796DA348132AF707F01474B545FFACDF1F72D0BCE5BEBBB9A54DAAA8DE145A8A7B3B2E77E87572A994BE0489FF696F1E7175CB48A8B4B0BBE600B7A3C2F28C88DFD9114DE4316B918C61B72E2D1C2BACF74E20C696D17F007CD0166E691B8BDA303525467F8BD6AA007C7E65112B3B82AF99B1D2183E69FF78E41BFAB098EBDA5760B0D95B1A73260149AF6B559AA6452DECA184CBEC6753835DB478D3E24C179261053ACC333C0401C3941E2957FB700889BA2541E88A19029C89DBB3B2083B85D90D7652F36357AC00A256B14D7FA8F825B5E1463F110B88710F3C77A5AF468A9DF5170EAA2E449FCD5F122E4C6C4DD04A4853531B0E4B4626F2DA3E49D358BE15A7AFBF677CD84D4EFE99304586C959BD23FB345B2B10A968A70240683B55DDF75D1B76DF5BCB2265E4D2B48CD283BB9850740BBACDA014CD71355A737543340EAE3CCE32B6A85FC712C7CBBD6E09C40E070C6DECA43351B114B5288D81F09FE2EF3E120B02CB0C3DAA000945DB75B69F4CD481D7DCC8FDB4A23FBEFA88B31E9ADD72BEF59C182D6F9674822D40DCC0898B2202A7A41D9E1AACEC4D7C5E87791C14AFD9CD9B5D2764414E5ABF306AB09082322397AC75FFB1AA473AE7A35750481E95DE64FEB54D12CD2FAD1E15574FA5F159AE9E450FF8215B7632ED333E768ABD20983E73CB0D4D9F1D533098C86E21F73BF739C928874752F44DF1F60A09D157F49A0839ECD5AA00A6A62948E52D8FDC0AE1FDCE14D6732A2CABD22192F1CE599C7144807BE8DB4307D2A09B37E5A7160CF624CD571A73AFF849B1B13328E8128418C957888B57430EA12AB4392AFAD89BFC86299CC4B5589FEB47303099A540F63D6AFAAC6AED978C4A36FB4EA8E425F7CE11F11D178E4FC83F7ADACC1F9C69763E3F88A6F558364C37FC12BB0F25E1A22BA3FEAB13A3D418CA93C7FF8EEA6028EF3B5E8C3A76505C3355151F3480CF292ABCE382DE98102C4165EDBE9056B60DB75F046FE17C47FC742593A79F21C35FD928CE5CEF29951A2096D3A2B79C453B9C17AC1794F2FCE53CEDE0EB1EE299949032ED031451FCE1C00DAEA8B4B1439B2353287D5A6E0ADD3F44BD527DBC12D99107AF45BF8002BAC28626EA1B8582F89A280B7DFAD9D6067FF059407E05CEA63AF80BD9DBAF201369BF6304324EF9EA644DF561664DB7113984A27C1FD1D3E4ADC3526F47A0A43EAC82B33B81FBF72E2FB386D3B8C19525EE2C39C74908109971CFF2019144A5FA7AB96F6EBAA5B1E49A6266F426468E318EC81D4D25109E337E2D04415C73B181021CE0ED3DEC2CE028B4413E36649313AF07487B62D9FA493EAE16A2265763F3A9FF493A126EE62BB448EB677AAEFC614B2E78A48D7F1E11A13D555CA2A22C5DFA35FA7D8DC8DAC0BC9FB0DFF12E33597A5706B8614F849867A4B97F3ABD6E8A6692A3866C7C961F052F16D8058FAA746B6FBA495C26A9707C5BBD8ED04ECFE3F81DF2A07657E3DF4D7F34C1D93C8E37414E744CA927FBB6E8D00A50FB291F8E546256A6AA27E76ABFF9FE60EABC0A4F89D86B91C04220D1EEBDB80FEA506190A405E6DDD2DC1E99BA8CD1F1EAE073FF1C331A59B4AF83600473E66C3421749049ECBBBDBF1854618671C09B6810ED42DD43366DA42DFF7D37AC05D402B731CA97C800C125583EAEA5A191DDAA2D9F0F2FDF35252AB5D5DA15B102BBC5750FA6053885F99A5BD6A9B09C23B2AE95CCA5701511C4DF77ABC6F19AD2115F63A81E6CC5C82D86299CA76CCFE694DFE1954DBE43304E1AF252A15FCA8F6723C34C137EF5CFEDE5057457662E21809D17FD7FD398C5715FCC0F96097A816F7A9F429451D89CBBBA0815E56435C576BF22A027E450210AE155E84D32615E6486E67997FD81557C327027E30319828D25637B606957B10B61BD764B361F57EFED8FD42121542E1DE940A4F9FDF5B89E2DA7FD14D3CB9999F2322AB73689CA51DC6D1585169633BEF128FAEC72F3D3EAB21BEB8D5F07D5D883C32BDE6F6EA579ACD3FEB9E15EBEA9A42D5EA26762A376589C576F916B710C679194ABBEB6A1B32DD6502A2DCE0F3AE83CD677ED5E927C89B63CC26F0F0FB0A6C3561775D46BEF7A7195AC07CB2EBA43EA75FCB5393DBEB781E187AE8509FAD509207C87BCF2ED1F9467067E6DD3CB487B520F573E3CA8431528878B18E7CFE5ACF914EC0DB0B99609F7C9B306AF59156E58588028651BC73BA562D0343A3CC10318AA08C9C79A25799BE7823BBC8335EC0234EB42E52F7E420D6927FD8D19A676EEC7F0D535E9020A58BDAD870D9F8CAD9709CD0D24B8479AD2E940929BEBF540A6B447E46AE630F30C1C09857A9B2766D9F2664022E323A3B417DAAC1C4D1E020232F464B4C4D5053686976909AABE5F60A0B141E2427313D5269797A7BA5A7ABB1C7D7F0192025373D465376777891B8D6D7F3F80000000000000000000000000000000C1D3141", - "reason": "z too large" - }, - { - "tcId": 11, - "testPassed": true, - "deferred": false, - "message": "3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9", - "signature": "4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636", - "reason": "no modification" - }, - { - "tcId": 12, - "testPassed": false, - "deferred": false, - "message": "ABA83F23917F4EE684C8C3457433E1CB08D1A3CE58EA49A597F82C9D549DFD2C8E460943FA31D252C1CC4AD1AD2FC99E9339B7F22EC228B4EC395563D20FB2CF9A70753ED17404C0C3D191819F35DFEC5CFEAC076C979D0384DBB8FFF19624524DE9078C1C269C4040248ACCC6AD90A43947FAF66200B9A2FD91646EB445E54F", - "signature": "42B0AE8FECAC6B9747D4DFB2CDFD598926A887BB9B23D20F6F74646DB40A6D5998A29A3F4D83DE79F2D74F369EE126DE430A4A1E4B2E5976A979FBF22BD93085058D27F769411DE3F4D80E252DA1EF8B4BA705A970CA0D87E44F7F1B4FEEBA2570E1EC6E133E639958D8BD3D41073509503B4BAE906E4D663F00F97577AF3AC5260215BD297404C107DC603B70B4F611E9FAEA80051E211C34FB4284F439A67BD9266E76A9DA05A7A3E412483EE8A41F1E6587D1F5442539C133D18036A5C194AC776EA6522CBA1A49F40BDA2D3606E90EC36E2A806CD988ED18E2D4A6648F31C862071F9F5E07BAC0044579FE5CF8C9BA94D0EFBC50ADB427D51AAC95BE74A91E30902A6E54A33F8BF9E476EC191203C7E4B2E759E734C92112CD6C1FDA595E5774536BBCA83CF12A001C4BD4BA29B7AEDEDAA1C30426BE7C2DF8FA2DD3F8E28B6854EF142C38CEDE769F0572562B93062F19079DE5F82A4DCB62091CB2A9A6ABD833E7860121EB09EDC8D8104A67CEB3B74CDD1ADBD4CC7F7704946F3C1F561D0817349126A387FB41AC0D08AFD35A4BA40E86E49A0E30DEFB78E24C49DE88C6991AAF09B72AAA1EC1C5BF0F67B2988D96EB8862E6E88E3113F87642769300DD5AEA8D72983736D9B6B670B6C4EAA8935087E0DA7FA6D918C2B7DBC752B6182A6E507340161B1F0AD55167E01BEE73F4AAFBC51E82D7CB2F780F943FA78644DCEFC46137F76D761E83DB23C0D7070EE7FD705BBAC5DFE39849F28B4AAC5B17072238026951AA06E0CD956392DBDE08901EB9DCF5A42F97F843F1168BDAC6B20E71E8F61331E2303EAB3B779EADCCBC7508A2F2599DFEA3B1BA06274BE0313BF5BFE16783F94F3DF7CB9E27E72FA51A80F056AD216C76886BFFF80C84A22F963EE95788BE8202671FE573F2ED3644D60C23C9FDA2FB84717A5AEF30C96FDDC542CD60D6B7AA01ECF2019DFB46A1106583B71E862F17EE7585895FBBD001E2B178851379596A7EDE42A10A15DD2F7316E88868A11501258AA36D96713BB2E52C87BD166355AF173930E6FA3A1F4C08514764A4BB7929B46542974865EF0770A349464FFD3AE35B752F8AD97323CA7A669BA1BC73425C2D94CA7358E67978E24199D271B230903C457A1F77B2D64F1C00118EB54185898AC1DBF8CB2FF930C1A05B3AB12B317AD7163267681DC171A951B48AA28B6B00039AFFF242A1250288F763B23FFA80FBD40FC5794E9A24E70EC0B22BA40C0D1860B82FE5271A6F2744A9A7872E29550EF0C05E90C30ACD553D0126E49DBF22C9E2B782CCECE0585B5956D286DB789ED1132AD24F08028D7B4B42866C055D7D5C0252048793CFD01DD46E814EBDB3534FAF505E7A846650376CE28097927C7AF6D496542E4E5CADD6BE0F211E9B0E1E38081B80CDD844D9C1D4B14D3ECA12961C7F1BF04B6947B12D8C79F552A3D4B78241C35F8405B3FBEE75E3A47A69101607D0E03B8939C477D80DFB8A3A75560221E2067E6ED24B3ECBB7BCBB77D639D395EAA7AC976DBD5DEDE4F0C2E1F68EAE3E59A933B3270F398192F0060E2A28E3F80BA5008D0E552F66213365127C9E296DDC5A9FCE9F7D5FCFF72EA3C9975846B9FC0DF2EF560D22EE11E069F80B5634998CD18B88638D66C00B456FC4BDC56C27FFB9097CA96DD2DCE53FEF52CA59E216E1BEC43233951A830C9CC3F98008F32668F67CBE022CFA4DE4148EDA39617ABF6E4072187234BB52824F79853A0677E221619EB3A413E639FE7165C0D5371A360B6529C877F02F542FFC31962CCB2EE6FF57D376A066A1A8BAECA89250EA67D87BD41A1CBAAA6FC328C9340A326973F6E2EEC86E48F27A86485AAA9752FE9478CC765E43907EC740012C161BDE0A145B74CC1F091599EB03A97076E8134595D7645C06F13D2DDD311F605C87067C87238DE08583335151163B4C9A286B950023A68E7DC01EABD82D22B019D74DEFED6331297D243A42748C3AB7762ADB63BE289A76871793934D76E15BA24A91FBADF3337FC5679D6979F757BF87C6CCEA4DA1C11EC2B93E87A68C42A9E39173EA3B45459E72696EC8BC68693E8C6B1776214D07DD3F13826226D3F3D3B4719E4CBA100915A3EF100C7910B21F6E39B8A86DEE7DCCE80B0C21F7E690F65B21BDA14882CA27AD34A4FF516AB126AC3A25681B20B4250611F7F748A15F2597EDD9DD3C78B588C74A493AF73312BE434BB3D911ED2CF45C4C9D707E705BC6124381109F517E0876505B8CC90C27FC63C1407F02C28FAAFAB44ED64F13ACC751FFA0F6521F7ADA08C0CB7CCFBC295A7C5BA498BB250732383B5FACD5A5DA43A2EA99E8C4E1EBEC7A98E085323998F9400157F20D1BC2B9BCEBAF3BBEBA85A33D678C3D9B8AB90129252338C787A9A4B039223ABCE72E270EE4F23AA971A638B4E27359CF9D62AB4E4A92A8798B8F70F3A4B013C195EFF876217376E0B8AE1FC8303B892AC2620409AAB45917F2996797A87DA6CDF27AF1F4BFFA03A739DB169D490A163D5699A517CF33A6E151E1B21405B42AF3300C901A9A247081904A330EB605085C2099BF7D7D5D319A1537E6630E0DB811E406F6E6D37F7829E997D659C016ACB4F9F655A0AD18EF09293D8436D9C79FCA1B0ED9D3A9E2B8E7E3BA7AA0A89DEE26BF10E01B6E19EEBA1F83DC559D2F817723A227AF950DA4448B5406FC9C98DFFE09B62825FBCBAF2004FFDB6F94F297465170AA39938891A7806FE54FA06A622E70C878EF6F5F7323E786241115C062DB82690446D9CCEDB9F7D596DA5CA2EF7EFC62AB1B500EB396F6C7DFFA3458397EAFFF1CAC18E987CC9D22A82C385829EBAC28426E5B3AA301E58CA8F73CAB8D893351A0D52ADEE8E9FC65C6685B3F6CB567D6E0B9F3B509D544C22013A5C8ABD1BF7FA8B12546AC1349354A09DF81E39E097DDEDE876BDCEFBB1DB2085445C159C44D433A9B05CAB7BF13E8AEAD2F3C8EC24DB9083B7C5A2AD869635BD0956D541663281F0DA3C88BF9EF2AAB1FC93F71165A1408ACAEEA60878A15A5B50D7D9EC284B7B84D746C342F8AF4163F2F97EE736FB968C4FEE84A2799B1099AB2459AA6BE6A123C03100D31270ECEC936AC34C54612D02FEEACD4E02AAD3262AFD143D9DBF8CACC6B863467DBAA40CD38161E0AB1A3726390643E35272B9239290F4AE945B8AD975BD892CC8321BDC6949BA3E60DB447B613F035E1507ECD6039D158D0DC08D0036C20F7C91CCA509EB91A43B5BE76094577A2E6A7842166DBB5B4815A8721F7CC639FFD055931E356F6C33688D2F8041F6E6B2462389A344855767F8592A5A7C4C5D805111F263D3E40424B5B6B95A0B6C5DCE3EF080B0E17334149616A7378797E898A919DA7BCCBCCE7EE2A3941707E8BEE00000000000000000000000000000000000000000C1E353C", - "reason": "modify message" - }, - { - "tcId": 13, - "testPassed": false, - "deferred": false, - "message": "50F8492B1735E32E32D275E0BC94ABCEAF820FB6E3B9CF3DE97620C6E086BE112286FFDC8363C82497CA3BF753B41B3B98273B561A1E724FD4CC8FDF597BF86DCAC995D8CF43F6EAD92AD45509A40A78567A42D9F388DAB75ECF207A4DA24E6C20449C5E2D72B5DA002FDFF5D5D11EF546DC81A8E718B26627C24A851EF71AB9", - "signature": "0E74E2B162C50F7CEB442CD3453B911FE47065F056F3DCD291FEF074BF00E094B2FF7CB329C7B8DD8F6196168E3DC8FBF83156B93ED0E4F42ACB7665425F0DAEE7F8FB3D4A6B29FCBF9DB3507B3255CE86CD52C6F7CE75E9F2054A8B31805441F344521E33F0285B58AABFE6F539A8C0CADAC5D091AE88A88642F90F5052BB9966960F7FF8A2AE4BC0959374BEC9C5CDB98E61D3699B545A7A5B2331C3EBC5A67A9CAEEDE9CE63FD11CD0E1D1CF2E33C33591ECC8433C1E4430AADF33ADF073BF1DEFE203E968DF98604E925450EFBB9F899FE1CC015D19B37B9344CEE5FD1BE7C495C472C4FA10C865C34EDD0E9B7D427EF9D1EC2F39617C984E26C74CC278176B4B44C5EFD2D7DA000C726A5FA9FF0EB2F93D8116CECB5297F45D4DB7B66E7AAB2B054FA3FA6D09A8DA9593EAE11E11AA5C191BE5A506EAB475DC0FBB4F1B756AA3D97ADEC0499454111A5017B3885C199A834FACD8671E03175E45C86EE8D4280D204A44F9F9A62AE65CD275DFEF5B0F2D786DE9A95560DE1E7B145DCA4BF1878114989D9B72B346808D01C844FA5951C75F3FFB325790205114BD5CF4818A041FB94FED2BA6A7A8F11ED90E63198E4B2AA55CC3523B23EB926C84C67CC0CBEC1B59F248586E0F4E26FEC64FDEDDAF8A2F6F35BCF8502CF99F0E05E080DD42AD2CC3A9788F261F2F88DF7AAE5A1CA027F3D4E8B3C16B8777C6D2D4E022045E3781DD8FCFAE3B420DF914B19F67D958C59354146A4ED1CCB6873F971C7E19DDA261FB66B97633F05F1BF493D7A34E011AC2A89A25C9008F0987D96F4C4ECA564B95E850E24427CBB286A0308C70CFEA8F2A13EEE1C64E36A112B009B8608741A6A72A28A8775990670CFF0F1368F22ADD78A8E4547F0F9630DF86D4B89CF42D37BA06FD50536C27580C67912D6D52986C3ADFBBB1959631B44F03A9D37F00A0D1DADCBF7AA83BC2D272C67F1FE260D7EF2939F972FBF0D3E6E288FFFA421DF05642C0E5567DA8E08557A4E592A24F5A2A9E5DB5B556E9BC37D9FCF5FAF21D306498E9B3A8275337E42863D5DE3256224800230162817AB4991B7DB1F0A6210773352359EE61FD98CC39984BEA1055CF6C5846C50D5FC8E575C088A09685E0E210F9D92DDD479839A65F4A7274454743A7571607F72523BBC677F65D975BB18342351AE18302ACD54D51E6E1F1BDB5EBFE5A53F3B7B92874512E2BD1E2C300BA0078521447579123B30F748047B190C97E13A4DEEF48C8F655E9FAEA4D6D0A9F9592CB3FC94DCFEF700B526A3E06C5F7A405EE3E24AB08E844EF7643678BE379A02AED5AE872A87F78F6C56AE4D7B81C171F36214F78286687C51CB5DE95A91307DEF21E11BF95B326602C54F0595C816EF388A887FCF234E806D04FD11A687BA9A821EB169F480ADFBB5206B766C69093316422431697556A632DAAD5FDC2D5358C5889E19F46E022973BDA3FDEFE217CC91299DA3010B8F8318C9EAE7DF3F16F68AF73549985EF95DE90EDCD6D23CE02F197CF2738FBB7AD8E146AACC4297B8845F6B2C91DD8290031C5D51B6DA785C41A6BB4C15F4263014E095611E563931720FC6843D72FA72E9F948A926FEBE2BBCB0E6AAF83C9C358A9D129DB81BB93530DD07960C710641D87E50E624DC5F1627773A91E4353EBB0D52572AC49B6856CD9F929191B3A826705D81C95CEF71334B259AE2C59897D5C113F3FE65D758F81F7C458714B771285DB2A24F6278280DA17A4B31FA41A0A226CBE84CDDA15B02F4061CEACC167DA3B35514FB5F56B8F298AB11BFFD8295B632374F662197F73467FD29A7D43AF4B101654FBAED108C009A1FAAC9181EF63E20E431EAD51C36C399FF6C2DC50524229CCF97AE5C620165CEB51E9C584000BD36FFF1F7BF7F5F612B9F0568651D8F82B5A3A6CA1F3B0C25781DEF1D5BA96362DC367E6FC1EE38F4BA5C79F2D3158D71671BEB04F84C11329F222E4936F805A65C6DA45D8B16544D82ADAEB89B67F83F422B135BC57EDD52F3B6F3D6BFAF1905CD6B8170869CE6F5AACF73AD978797D9A0B2311B032B68A32445B28745587E2B729A1745A6FA46C56380BF8821D988D233D0B360DCA043CFFD53531C42736100D58BDD022A475D01ED77F85CB79D17D81B704C6658E4FFA5FD66938AFB6B4AE99D61347F5680DBFDDA1A3D273AEC674A39534FEEBED087E458E07067B3598B5F6EB9C40AE020357327FDE2542EC2D48D243A2E52DEB9D17A5DA2E98EFD5463759B3B4A7F50254D7443DA637B7FFBD8ECF0CB849D0A741E6A4A07159C99C53003163C43DEBD3394B138DE3BE7120530424073D2464E80119C3D1C2AC670010CB83F41BE5DBCFDEDC806A3AD9336F1B0D81C012ACB910215B351D9A8B6CC84D0F2C8AF78A4D207D36B908CE67A5EC979ADD6AD2413B5F1C17142A3561C1D422303E1A9CC91AE2F759FE5910C8C39374094CD7247CEAE835AEE30CE1E54D30A2083F29A2B42D91BCD2F2E8D2686B8FF5661B3F0E49883E8477A8BADDF769CEEF24E245DC6786480EEAF588C9FFFF09EB02180F9BD4FB297A2868CE388CF34B6AEAD480BFD65EB2D168B9363CF8F02198892B87DE3399BF8257170CC5BA9610E7D1C0ADC9BBF5125C2D95A6CD2EE39515C7DE203C20C022239D752F75A4B0C84D9ABBC70AFD02CCB8EF03370575A391B6B726017DB61C51D68DAFBA9547D81317106783B12AE6CAAF840BC53E6F7C640E36A85734CDFE104B9CDF0FA9EE9FB5BF1F3E616FB93DBD1A55413BC8896ADFA633B311ECEBC6715B9B8FBEE8D0BE9435D5ADE4334801DB0643497F74B2875A1862D3B1DECD42D1D154E79652A8C549C7EFBA49AFE36489CEDE1595FACC55AED93489D58C2FCC0C661C0F4FC88C6523E62F17630A14E874B028997E0FFA15BEB33CAFE8D4137EC88C28FE0B77773C5EF4DD2D1E82A4D4261AEC5E96DA98E92A891FBAD7891C86A937B900C631EF9A1683AB69C69CE3B9DD114602EBA81239B06DF988A2FF80E95BF21838EB19FF79A309D839BB1F9DEE08E24FEFFDF4B43E1EF277A45112D67103B7E8AF4EC88C131C5384859E593CC03F483A35F528B021B38FCF46EDBB14D9896E89095D41BAF69D97A6A31EFE6FCF0E0B98E8507F92A552953CB733377E7EA66F4AAD259931E5E311127F8147C8D3044F536A2863BCB7E597BDC9145DC9C32311E18B25FD61175884F33858FF75FC33371B747367BF92EA3364DD9F26BA8D9F07585BD2AC091A07CB1F0E17CBA5D5A64944504D9E30F2AAA0F3D9D33F07FAE122C398949BCF7FEBE4419F0B8F41B7BBC2A181E222A2E2F3A4346595F74ACAFC0D2DB0F264047484F7C8587989BB4C4C815262B2C2F3A3C47576B6E819293D8E6EF030710162122263D6F768996A6B1E30000000000000000000000000000000000111F303F", - "reason": "z too large" - }, - { - "tcId": 14, - "testPassed": false, - "deferred": false, - "message": "8E9B39AF90A95C984BF578E798B18C595CBF19A8DB8C48B198A053FBBDD3AB7A8CCE81F27F86768A97BF43BD098F0C868F98EB012B3ACC0F8EB8350734F3578FB38177A4381CF247C145E3A89CD669CEA887EF15635EFB0373B90E71CD37CF7A67DF93725DB40E7EAD4E60273D3FC89D29033E036EBF6E47F4D458469B9F9620", - "signature": "4CEBE38D2AD86612E5E7D8028F307753E59CB2703F743CC2A73A9A413051E28AED6E7C59653E0B6CC88B88D4EDE3978663280BFE4CFDC154DD0EFEBA84B8E7849D182852DC5EADC862291387DE3651B4ECBCE7AB39544CEEA95697651E79C8837CEBC1A4EDB81BE99196771A464D5C38656EFB0236078EAF1F7CB0426DDE117115F6889A8EB97BFCEE6C2786873424AD45DEBB7FE010066D6A498D1EF566541FC0805AACFEFCB0A12A22A46D2BA151D0D7169A9746A343A30D924C3306BCE616F0C287DD27FDDC68C39C53D1AB9AF812EB4AEEDB38D756D44295B38629FFA164DFB34708D9DDBEDE30721DF5F53E3388C77B95FA1446811D098C51B52247CA6CC2669198C36C45E1254A2FA923D3908570709E052E179AC01EAF73248E2D97ABE1C7E06AAC64A63EB092059CB7B375CFDDB094C312A09400A6AF90469804E4261D7E2C7B8C4921A3BD1E2F5172FA6DE10EA6742A7ACB9DADD33BADBC70A3D2543F208252741AE4674227AADCEBBF0F2115AB647C7BA18C4A2F4264AE94056EE63B8503DF9794B85B984B27E19BD2BC46623DB2BB480A76CB10EFFC2914D0B7D8A72F3CCD94AAF235872FB225DA2593998A2A0E1BDDD63C7545615D190B699B2251D42C1828DD9548398C8B457DCB5CBA4B3633F12C99E731E65FAB21083A437A61E184A05A26D6531BFF455DDF8AFD59F4B98DE10ADE3A07CDDE526DAADB475AFDA2A13308CA9DF38306A3E260A722D4EDDCB0C839C48BE17CF265444D941CD4284E1E0D4FE2DAE9BECE5483B111328DAD3C692F6C60ABF4FA6F6710775336B9B22CDFF5BA8C24D39CC1687B400696198DEC9FD11D62AA3AD1DF428C826337696E6EE2CE3017CC434CE945CE69F4910D7F56B9F480B050180EB2F34E9A57FEDCA57BE370A8FD802383062F2B021DBC96F403CF305352A290FA777733084D64A7E158B165300817398B4ADBF582A718681CACC94A117D0210EF81C922C2AB690705C8524DB63F3466CDF672A999E4C29FEADA24F0C95E08EB374F5256A576F40C8CB65AADF36D15576F4275E685E2C8ADEACA26979785516A2BEB7CD3DD2BD7AA662C008418AB760F1015689D3B2AEFA8BC7F433EBCAFC0149E4AB054C5509643AA03C8DDC3A4B8940083CEF3474DF5ABFDB59E6B9F50A467F6BACC556E57ABA8B7192AE57E1DE163B69DE8D4513F7DA25FB4B4B3AC49FAF9EF529F569E024320FE545C13109A9DA93B812D158722D9F1ABE71A65681F9C840ACA1FA017CEF3B175C1A53B9E5C015DDEFE07C314DC31D4CF04594CCB1081F177419DA161623DA9E56BFE349E1B3A7DFFB65B6070DF582A11BA3A02BB761F0FA5F6B2DC17382FB71429793B063316E96E666659FD663F8E740A89DCA7283C4A5F69532F60D201E59771E08910DDE679963E0C10B5413D1B5AE21A0251547316A908651CE207A371F26DF9EF47C5189A71631354952A5020C7EFBB8BB19C71EAFB8671855B48FDE3EC4700CE9A78C5772B6668DE037A17A6A7669A1EF28AC9CB1C96B13116C9956887DA3EB6E708677C423CA8B0806FD7D77D38B2EDCAE4726DE88C5C997D1C3D8B1043AD2301B703844DF2AC732DD1140A3092D80D639BC76E94184D6F18E58ECA747968B5559E359C3518392104E54D9C53A8FAF83B1C8E9367D4A964B0298AFE4F13F27CF4F10EE877F36C9595A9DD9DAC2DF2776E1A5851DC377FB59710F1F6C3AC0CFB73B6E11D3425CBDB5796DD78AA538AF0CDBEED57363A414748F9D897488F5F8DDB06E726F1893200BFEC9CDAB19C32B7CDD4428191CC2C25E90584B272C48242E80B644E30B1E44F15DAE32E5B5885A14F711382592B4F4793078082006097FF28EC1005EAE0FFB3E14D490B8221DD4DC2B57DDC1A2204C6F457C3598929C4546015EEC272E37FB6FEA4E9EFE6CA920C220E40947667EAE9480D3FBD3042D507D08C69EC5F9B58C6AB9FF048E8FEABE2A28ABF55A20274927CE4CD793EB4377A085BBC4ADF4FEB88A5AF8D584D2A7F4FFDD642515839FB4FFF34CDE645E27EA8E8D84D50132576DEC28496C72F636DD75B4828F0BF4C625D923DBF165ED7046741C596069175D0D10DC6016D770D841EFD78B6F3BE195AFD2E0EF07AD597E528A0020746FD21287919BC01BFCAF333BEC32FD398C9C8730B4397C0E3533D0B1DDCDD88F29C0C937CC2CAD72CF65A3D64F43974FC11CA11FE8242E1EA70BFC64A43F3CA095374A55344291997B372C87440F822D07300B9DA15B0470156771CD89C5DD01E3C0F86984D9B0EABEC9991D178D3C260DC2EC8BB8549C54D55E1A05F7F172FD319040F4455D6C134437432AD75740A1E1369ED4C6E5D244C8650AD36FEDA00087653AAEED5C92D1FE12A53B1D621F99AF69581F349F3F41A50D0B18B8361DB4C7FB64AC006F2318E8C75682874E8EE47FAA1E59FEDF5F0D3E97A220FD50707A025F2C764FF02BCFBE728057F6545C444CEEA6DC458B8EBB10E64F539F3D07712A33407B9AC48F93CB484609D313AD3E6DDB24364CC3EFB579DAD11E4F42E3961D1A414D4259A55D1447F89A8CBC18BC5E2757E177605D2595E36491B3710056DAA9E3B7A2AF511B3843A04B0D5A8DDA943A75EBE00F611422F1749495BB3F18731F14B43A2D2246C6FE9005B6D4EEFC6DBFF53A8B5405F732822B7BC772F80635F5AB2FD46E4E97AB149FDC12465C21D2F0469153E3A3AA79333130D29BE4C41C998A06AAC624B77DBAFE4B8E64CB9700843A5717CC9B59A331B676B4078C52620FA1D4701B0F07418E69835035D8E2DAFCBE70F4E2874FAACB9E1EBD3314706FDC90B389696C703546EA8543212984825222C9502EB4106F1C7609363D1B74AEBC7DC0054C93A5BAD6433F7EB1717FF50AD7ACDA8419303247DB48337F201A362F826EA0BCD70EEAE6AAE6D4526BCD39CB5465DE1B08A4E8E659B8817952D41C40FCD10576FC1FFF52ED566DCA0AAB931D421238867E5F7A0443ADF92C6E5992E2368BCC5F5160B35B75E5A6CAD96F201980D0727E2C0F9B6E2FC4B64B1A02A31EB186A0EF3E6C43A4185ACB596BCFCC5FFB7039E3BBBBF4141A26A45FF9DFD045DBFD8F8F6F59FE4674FD7C92474827A8BCDE6E4B9E860273B6609BFB275135EE189B1E5F80205ED147DB85FCBA0D998C185B40B037D544A51DB592D3F4A573B05CE9164216DADA873E8E3BE33FD0F5591E21787BC8A1B3665104EE1445477DC6CACDA1C8BF08E02B6B5D81FC7A67B5F54A7F883E92A99E0D07C4DBA0BC6AE79C23C25A50023A47E83329315BA049CB3985A051893BB530B1530343A424F515D81909FADCDD9E1010B2A5965717987889AA0A7ADB3F314182A3B43454B588CB2DBECF8FA0225588B96A5C800000000000000000000000000000000000000000000000000000000101F2D34", - "reason": "modify message" - }, - { - "tcId": 15, - "testPassed": false, - "deferred": false, - "message": "D3C632A9AD8BADB41A22CCCD57B1D429B2DA6A47880B95AA529B9BBF9B18E43F59412C8441F0FB7956D407A6ECD3BEB65A7EB816F502A4FF4A7399A805048822C9B8A115672FA86BF0604A2C0ADF1EEC44A0C3243AADF8FA5793B3E95BEBD9A00112860AC003571EA2F3C4EEFDFB93FE5DF594DEA5893450C26118BE4D4A5EB5", - "signature": "7AAAA0A80AC81B1D4EBDA407C8B7C2DDB20ECA18DEE95B35DC21985816C8AE08070C4911D8106C50CEE8C21C72AEBF51456E882072435CF5D557ED219A82DF76CDCB3638E2353291A1BA8BA35B9BC2EDF03DA73D7C0A0E65A2D6EAB1AB2AEF4ABE3329D9EE81477E0254A04C2C193DCDF57D535ACCB3FA9E37037B81475935650CB816ACC7E944B45D007DDEF7D86B5F1E50E32CCCD02EE2EC5595E142BF06D4ED48C14197770A7C4E93198F9F75452DFA915E30D4FC7A504DC38C29ED11E90F5A7E16D9C9E00069743FF052D1C368F1E6D1E793E412191B3CC53BBA0E0F1881B3A48F5245A5AA9FD0D5EFBCE6573E3945EA5638AA294F9418E7462059B95285DE864768D4DC12CB46BEDAC3234176AA689281CD559175B0F0B58D3FFF54F2B8B5B2CF598793D9ED74FEF1922C2D9ADC2E3278D4224206FCE9B776F8DC70B3068A11053246763A2F7B0D841B649DCE656D3A9BD3454DF86E238247CEBE45F5D4CC5DBA7FC0281730F46CA1CAEC0CC12CA4E24D230CAF5FA75590E5EC2CEE5AACC653BA6C262842ACBFF89FD435C37F4D2BE5829C1EEE1D2EF0FD6A3AE250D44E2791E20A640219FB4D10ECCB22BB78DD4AAE7CCF4153815F35FA08375A9FDFCA3B15FC14D129F60D5528F5F369AC01998E66446159AE628488E876DDA39DDFB02FD915960CE91F212E5915DBB684FBBE7C78BFF70E2ED2EC0873EF55F8DE4769D092C672E397854E41C7568BDBD8C2B829EF68E6C76A6A98A788EEF06DCE863710D51EA91E3575BD349A44F273E50C6834F85A90B3972F24519BABA64E2177D8FA0BA9C1918B99979D0E6654E6098AC7CD00AF97668831464F466FB628527500DD65C35DABD933900D866F27A53484400EE3068394681028CAC7E82652C5AF959A58494E710F3F7BDCA057BDE3B8322315213A1E19739C361881DE0042FBDDDE573D7D2CD312F66B71D1C8CB41A7922ED058E62C78E2DFEB6E414593DDAC5E66D1A88AB95836FC6B183B5C189E14C1EC833C5EB8D4D6DA8676202436345FEA6F3DE400C02DD8CE746E2F30278A599C1F3A2A9D97C3BBC9529DAEFB2A70237E39738CF093A4E10BBFDCA2EB3967541CB0D7AE7D0B16479A337A4EFB13D38D7B5EED9D477B4FC5C9463CF6299CED1381F422E81DA93E0A3086CFF4055785817F0A7AE99FF2BFF5D67E73082CA9CA2C1EBF13765A61311D9467506830816D99DFEC08D3075FF28BAC221A098AA9781C862245347A44595DE3869A58BC583319F4F61945DDA28C5C25ADCC1864492EDA40526ECC07E326B63838F1936E7E6F0B16F69583840E46A78090595D4D6BC6CD1A7711BCCD2507652B1620B48E0EABF157F08C49E315CAACD52D3622E638A2DE884CEEBFB954C95EF5C3E8F30B33BD0EC3B1F64FF6250765DD87EA6F4AC3DF3114F5214A37EBA198F4B66E2551E4DE55F68236677B234BB72EEFFDB3D404711CA81D28CF5CEF24B662E5737779AE0A76946454E960D566E575C3A6D3643AF381EFC8FBEDFCAA505EEE3CE26FCC023AC5358E925DED12739EDC663AC8ACECDCA68BE55E3E08A20EAC19156E3E4F0A7CC84F7FBCC1B359F6CBF6451CCA223747E9368D69FCFA355211762F4BF6EEC7C28566F7DF508BC0C612EA08868274D847FC6464A6455212E31AF3AC28DE1DE1866B60FD0157A0C005267014BD23A703FF17D7E8B0979BEAF8A145158213F530129BD11DFBA455293434F8E2A55FB6C13E14726953F3FE68C5A21242FEA35AB99334F7F93EF3756D31E0AD6D396CEE242628DA0E47ADEAE5891F2D04F184BA746D8E3D33AE4DEFCD6926B43CB46241BD0D74B7678EAC2D924B0C98DFF71B00D1185B3F793CBFC5AE38B499BC0B7FE4024577F8DB43DA183EC35BA7D877B60F24B42BCCB6B71C6D0C8735707751B507EDABD083C05A92AFF3E8A82652C01433FD76DEB991B2FCF0974F2EF05B2F823302FDEBC91CDCAB116354531FC50E6B9CCC71790D9D9C7D7EC98EC38E8BD030D3E8D60C1D1FEBC50D8EAE4432E6D302BDFEBEBC0CAAF831563A2EA338A17E16064F3370FDD18C31C636E60A23CF9CB609581F7F64524637FD3571D3CB3B99DFDB230750A1606CFA5CED44BCC6FB149B836D8D703093EBD6397A1256C3176A3D738C703629169077386322CFC3EF6F3453F9BBE1A654A53A7A5DD17456DFA1308D91F5093E245E0FC287E206E406F239A68ABA77E3BC6D3EB77F8BFADFBD285C8F171646A74B2224B1CC9D8D3B4521A195376F033954325F5050FF15B123BFC21EB5197242E6EAF6730DF2135D9753B210D8ADC109943F57E4D77089D90A1032DC2F535746D263DB4B9E2E23274A486C4FFDA9F43F981CE616703DF1813A54272C665F9652245051FD61E2DF34A38910FF4F71704286B05B44D8B4D7346D92CF5CF17C5A0C80562390180CD9C42BEEC2111ACFDBB708BF750316D49A8610F1644A31DAD2A1FBCE2A3980490E6CA887981F06B8FB2E44083AC50F8EAF429F6E8261AE49EF2D1EEC077738E50487F356C304044B49AC3BFC980C76963B95FE4D48F2109871B6AC32F40D538EDC54774AD2B333018CB7412053C69F86F53C2344A90988711EA630A4BCFC93E212A5C183C87DE65EEDCB00F0A0BCAF14C00DE91897FAB1F12E57F3C1993DB6CEF169B75F014A2CB28D07DDD23505ACB5303099430C4B62614D96EBB4F2DF2F77B51043875C1F5AB2ED40E5E3B5487E9943F6BEA13441605385FE9D09AA0B7DC32946D13A8862990723DFEFFBA9E86D80FFFBD0857A9ABA7F2B18F52DF347E8E390CD1C331FE9DEFD1DB0257EE989ABAE16873342CB7B195CDA930E37D9B5BC4AD9E079042079D4A3119DD025E73AAF8009B6F67E268FBCC281AC2B9501606E71EB179F366605A6D5E1CF7F1BC8C152EDAFF9B841DCFCF32D70354EDF9CCD1F5CBA98D6DB2F8C610DB50151EB6E38F12F0CB36833D42902EBBFF90D443054C3EEC43C04DD6C719DF119E3B9696AFF936F9AFD73FAF735BBC2D79A60B2788BA86F857B2CE38E15754F419DE346605800651E159038A87AD3A6808A6B66DE07FFD106F4E7E41F2D026E6558EDCD811F4018112A82745FFA55BD0172DC402ED2D0196ECC9733D2FE372E3602E3D0DD5FE629406BB67522D37DC0077BB7234899864A227AF6C9CF3E3A35899F17D57CFA87A2A63E8DE0259818A93F16EBA5BBA4B96618E10685ADF1C0BE38563A0850440A76495501A71FAEE49B4AED01CC0EECB303005B2ACB97D31C7859D25924D4AF86008FC4387D5529E03EE713289FF5C7D7AEF659A8AD75C39BFB40676103104C5E667B7EB2CBDAE0F1051A2529355056587ABDC3C8CBE3EEFB000210243F80B2BCC2C6DFE4E5FB0307262A606B6C999FA5A6AAAFB1C1C5D70000000000000000000000000000000000000000000C1C2A3B", - "reason": "modify message" - } - ] - }, - { - "tgId": 2, - "testType": "AFT", - "parameterSet": "ML-DSA-65", - "pk": "6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956", - "sk": "6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C110622737E0752B0C7693004EB0BE13F45B0E746806722C07576AA784DD5768B8E9717ACF948317C1766ACBFB4E7BD185519904E6C692864FF50284E8E8A9375EC4EA34F5F12148700ECC62348233220AD775B1FD83A9D3033C5726D5D2B7D62AF0F321073265767333773710146658307501027637053370657250225555720040341823880257151604303437436364873068203400580355270640528800356423156175845702205553010102421157700782401137236740715853511546827780058171285586565471778437044287102661645257880336080652346080345067355710525170351103044582875788416670381280332611148212542274864328145641171634161472073852747637700366176681206471154344726473362010558700767083172687387540864551263076218207175324250705811241381122505668870883105533887700160238574586677413700824715657338861660882118224618741375072746665774007680684008408864784248583305731165636605282311527846513814557422254225763505335185805045772607486115373775501301805588136883017444342358512002083355886761447611843130517161431236500430633468042808454504363744347278406783741362560056114518381568433131845104766515171258063754487005546787785164813636668836714814331250407272582855656455511302530021167653585048803872700335710803434230171774356436378811535174553563760650830866312030043372500135850715242334552801436552652110143858484825063518428451016281466626867327412840616146432745720226734334344336864822713770160361506648005108030701043675607201545188516112422024543610332866143554022500172345126884075052637375885843455637816811081652004223238015767462112427318073848157877473355128053258038403285128525243021068260454320361252184050053654686616407543807371115562533303056062263720288443812612332480436644178134504083651088857081564755707730220287025300326401157363132137353852252445460322112121458848603250488457321572732862717725572184234644216036037273104120246263515180767257548713266788448387550377150332045814585223076167211046522802041228835008465653353475403760827857254217371277417513518217322601416217082333145811872187548446230625704712408403728866868256173636515663287433218023005128757488114046826253156374566356518567854271258515782580235784787078510132518218835241154170380682321437624740206653476855162418705517324874146320502540028563553337227338137006846351826061025422151576867143646335103655216308746420764437120657888051475701461726087878200883725652314647322670452815523887856664444466486206152851777584535231176278615046820787684744516215818777031852713826230320241600661118701454424002376662882163632310542162672683874733463167347138530146864174004655605137026283771585270368460221040288147108303664158073248587845541156271113728404628268142526020534444710553471748763668442470088242387126541621045830510034783657806137713048564534131885226765508146165284157135227545278676445535730788018243348644536176786163115841288118664034311357777385628338216462375410335504164603274025383302566113744712177274654435563367786763665380177257043122543435171305472235768533118803341085768577357055022185512180623748870526213438432586831083855300868387436611124101644003645154833742857702507323136330340D29203183C9F15AD8D5170812805AC0B6CA848D0A1FC80316375E73FBDA6CA80FC412483A1CD90E211A82093984B22E46615EBC2D64A311E2718C89A14FDF35E5F0C7871D83BB3FB731A0B2614D7B9FCCE48D2B6B155BBC7F246C20BE814D4C9E9093AC20DCD3A4F89BCBF25E86F1B8314125F7CD14F1E395525ABABCA5EBB33D28C13D97199CD4927CB0CA5FB59587856C9FB22035BEFA45F44CA9F0E5EDE014B88825A304BA5E47FB95791FCFCD3DF9ACCF4F4E74C7BEE8235952186ACAD1CCFE60C7EE2B911FC47A95B5C4C1FFA3B6F582E905A33E93BF8733CB6155E1859E7B78B8CCCFB61DF62A13A2C744CDC9A61FE6023299508EAD29447311032097043443F482C8512ADCE0718F192BAD182D13081E690F1452E81AC9240843419133F2E59F0110DBB0060F6F3719D5C1DB49BE3999A45F187F53F7A5BA7539CF2F01409EE71148F77BEBDABE257CBEC316CD853281625B4DB4F8E8300769AA431B2D611C4E52F1D9BF8D8C5F85E905983AF2E7E2A3612FA97E84121BCAC53D6EE09417D7C7AB07FE6AD777A3727B5923AC21282BB8A46281BFDC17F6701D5AE292562CFACD0C60E3309B27875BC69BB4E9CFA1A68FE484AAED9AAA3FE7656B0C2B8E0D2FEC5C8D37B90C3CFC951043A2FA3DEBAE6FD3A3E1CBE0AD2C70929069E4A7B79A750411F7096C05BD858B51F20C7AAE0F5B1A0F457469CAFB507C09BEA92AE3AB67F6C339553F2FE5E865883B5DE45BC2F2F7B22FE875BF662F9E644B97E9E3BE68CA44380FC50E2C66BA429B1B5F417DBF5C67DD0CD9CDACE53D9BD86CE66C7881768F833E00671EE5D7251DDFD27CC912BE279A43B8C700D6EDD288A66B87858DFD779029F696928C1F6EEE18E794059E9C1E39D72EBBEC5F131FD3CEBD99E9EBB818D8BF300081847B2D154286520E681C7BCC0AA3013DFBD4A440A1A0A9E00B4711E5056B58F0176705B888AFA318144F8742BCD9026B8AAF6B9327478E4B7E217BBF1DFC88205A4C91C64DCD4D9AD0BD29B44300B405356784F50FE51B525AE16AC295D94563EEB5A0C3035A5CC7707B418AB1302BEBDECAC06001DB4DC9324D7BF9652BC1EBAC4413F0B83BECFBD921A037918A246910AECF75AC099CF7DA75B8102D4223922D8351C310109949959B8D8560BF05C0E5FA24D401259862F0F328E3451789B09D09566B62DF9EAA561C17C83280019D2D15A287A49C75C712EB70B520DE68229A2B653FC6A2067D2A0AD42CC37F8AA4EFCC96C4F252F8457E3187EDDF63F2E67EADEA0DC5F1E419CCDFC36B864FD0F91420D4CFD5E11F3801502770117B81AFF4A8C99E3D05203A7892EA39EBA0B0FF0B42215539438E72A1AB2FC32889E92C5600EB03C388E5359797FF906F387B79D00AC97CFC02DE5AFD1BB8AFFACC34CED19B200F20A4BC28F074A2B074E2AB6601CB0F1F1FF2C0046C4A887542F3B8A93FADA8A7C647E4B2ABD7EADE8DD9138A9EA86BBAA8D8AF39C6D822585C9A3359D87D73A77A938229B31F1495D4778F51D5CDAF02D42D039662E84BB3826D881802467F56ED258B3046288DE376CD9F9DDD5184D5441AA6B12FE72F55800F18C7E170159142F3A56E865832846713F430E1A0ECE056BBB99A8FFBFAC60C3A2D89E1BDCD2E6DC4FB570679368428CB554D62138C7CF1B13140E5554E2D33E3E4D5A983E7AC68D3CEA0AE7C5B8F81C62AC6F5ECD2ED572EF101B9E3EABE653075D58D31195DD5FBBDCDE459DF6439A1895E57B968F970A20B78E50699A3FF8BA5DFD52FC91F2DBB9539FC0E1B164FAEF6520A7B4740E6BE81E167D5461CC42AAB74C375B6B7288349C8D0D9B596F4526CC37647C1B92835503BEB5E982825B4E9AC787EABF5745877691E22A560B65635715AA5F334631A1A76C51C674B0ABD1075DFC925AE284AFC4686060F68120016EFED366AE69313EC67B23328BBE383ED68DD73D8EC267867D4ABCD8D33B91679820DCC602EF8CB6C44917330B08950C2B83689029DB502CC9C0F9FD63E290128F4DBD5070A1120DD95C0C7DC1D03FF9B91AC9FCD1766566A424048D583672A2CDEF1F373CF8BE3F6BDC4C980075D695440FBB8FA518DC5B53BAA7736FC922FFD67E7F41F9BE95EF41B5931AF7FCE19D3359DE29DB8A00D7B7FAA44D60E81C16F7BF2D5258AC9791777F8054C4D1601BB8EA5DD8C24004C723DA0CCE94F7077FA8BC304E9911D98A4D6E09CEFD61598A2CD1D77FABDA70C9E42E48F9897436FADD1A2F578357A0A8C4BDE8BB1DA9A2BA6AADE3D103F9DEEE26B5F7343940E478650EF3E40E3EDFBE6070865D27DFEFF04DD80F0FC891B3A2D9B536C02589D0806FA43E635EF6A8A1F943343C8C993857931809ACF4A25D9D93EA36DA80B3E49B01AAD63AA646060E5A6CC11765CF34DF3D2FCCC2A32ED6FC2BC792C055D85F477F374D63A9C1D0B0B7B2C0A92241AF8DF99A7BFA037045C5BE91B13930EAE43B44572A5CAC5A76FB723B57BE9824F78C59244C38565B74E223576E7FBB45BAF9747EA97ED59AC3EE567B66EFDDC73DE2FC27087CECE955EAF33DF2B71A1D64C7ED6501E2E17A34D17541677B96F0236E7C4CD58C2DD73226B215EAD1B76E38B281C8B173316F5C5DBDB91CC87F9774BC76B66A2CD94950E6AEC59FC3559F79238CC7F57083B943604BA9CAFBEAF413E4E38125031AE173F9218AA4CDA7544776EFB6C1E416A0B10061A9DC4C855252E0751C5B58AD141AF38B96F887372FB3B7FB0DDA5F2350802E89C1FE7AE20566CA1FC147DD2AE19958814A105757A07994B29B236BCE28CDFF71C1EF5F6177727CCB2B1D1D9463172D82CB513684D72D74DCCDD9CC459FF5DD5947DA7222647BA1B7554FE500238A5B6B07B9FD9BF3680E33DB9DF7E2F166CCC0AED8C6A233222C6B5034B51AF8D25DA348372DDF66A6E5FDD2DBDEF69041E0360A69AFC6ADFFAAB2956F28D3EB6AC07E1A974F889AAA79879345907661123A66970ECB56223233A18B06CD1480F1988C172793CF89E97E8625BB57463741628A8A1137D9B25F9254896172C6B687296E185435BD7CF6EDA2AAC36C3066C3C867D5F206FEC34683CAC889693496A851A74B219D389C6E716AB5F210D50F553ED0EE5B9BD8FA306E274439620FC769F25FF1F11D27A8DE79FB651763334DE8FDDE804F5F1C29F5171D43C0CCEB5D5AE2A458AFC3A3B0A51138D26A42A923A0E551AE38B16241686CBEAFC673E900607B1A54DA124B2EA588BF28EA334D7298869AD1D1E96D0C92EDF817985331E6FB4E09144ED04FCA941B2660494372A8AFC0AD18D8225F0ED03F1DE7F8F918C27380E078C12C2693A72DB09890485ACB99F2B541B3D3346F9221B67359C30272B527279C20C35B58BA2F3F0E07CD50DB8D8570A0A13181F0791531A48135C395F88AEF1F39A3DFBAD4964226BA27305DC0DE338FCBAE1BEB645B5A47BDD6CAEA68A7B21F110EA35320BF756027876A83B11FF2A443EB31393FDFEE5AC6489762CFBB68D33DB4F55D24B9889D018E11E3E7", - "tests": [ - { - "tcId": 16, - "testPassed": false, - "deferred": false, - "message": "02F2F930680B35021015B0DA413D328042F9844348FAAC3DFD586757C3574E4BADADE11EA4099FAF12617D5EAA9F4CF4D4E78628A0D38FE3119D3A08BB47648E735B798D320668C9222516D7DDBEDB3761229F27E5C1A6273B13250CD2C2D429395B1C86D6AD16730F6CEA46FBCAF737AA0CCB8F719DE98FE1503B487978350C", - "signature": "CD9BD3FCFE65F76BD1A9C0F4860737D7E1E5DA8E7ADDE2D528B2F85283B36B9E1A0694D5631A2B32BF0F133FE522E5F40E398B696B506769864672328C942D7FF10DDE0E5644FECCDA421E89DA2C3E65F4052AAF4F2A372B0A777CB76EDF55E8D4C607EA72E79E6F81154B35FAA6992D2F3A8B0C2AF0E3672464A87D3A343D64D99366AEEAFF81FC9F647EAD1C7035F8DE518D003AA0912D15C63C0DD3B73AB37ACED424610D6CF5BE6475B4AE5C5BD9A7485647844C44E1C9E01BC5C469005F31A59D0119D872B7AD4D09BDCFCC8BE28D446BF7FD32041633A8A61F55D86BB73912BECD657BF88BB8B8F7D06443C51BE667D3C0816A068D1DE5DCDBAF3817B8CA4E1997BBB5186A467A0EAF1BC5B0C9F7D18BF63F5B82C69FF5DD403601C48B4FFC3CCB9C4711073DBF8130F3108F793569E717509CAFFDD2AE659E4292B80283A9BD6C1067A66A35C5B7508DE3C665CDE71044EDE2489EAA6E6C42B10F42DC321511BB991627EB7227BC4E16A4CF12243359C7ED6EA4E396046C50F5E91262F0E14A53B5E7F6EEEC8344A9BDDF90F9C4FC5C1452685E908776A454BF66A2622CD436F7DD21EAE842448181B8320F87B169F6A4C803971FD6A40AF7B72B97F8102FF44B5AFD170F9A91C089D44AA803DD088B4FBC339372497E44FC9D784753164C5ECA5601F2E13043B7E89A7D86489AEE236289DE7EC9EE4C37A85E41D627787032EA98AAE2366A15FFA9226B28C116A82E58466B78D753937E38D25B5D5A63093EECB73A1E6BAF7AC1C7A11CF3412218C6021A1DFB979500E7F361D7DCD998F964F2AA01261C38795C20AFDBDB911527DCA0397837FA630EFF6B6909AE84F740DF12E8F2BA2E661C3F341EE15E1F2D82856EEFC1413D9CD9F4229BD382AE541C2EAC7332FB9A9D10F6CE35AB6D5EEA16D9C192643EB0C95B45F4712D70CF2F562A934199283D270B38DBDF5F288D64D3FC5D21841600843644D9F1DACE168118F2AB90892086C4C3EA7AEA0E0AA10B79A40472E020F41DD7C071A99741A6FC01FF56EAE9EFB62E43921C5C042696ED35403FB42F8734268442CA28A7033E4E495D89F0C79770C3457391A98A580D504C4B17E138ACC4F1602B47C63940291BDBA5C77B8FD0059797220238E9C9A9EE266F5A37281CB1255BB81F309A45D0119B5D2FD04385C91AAAA574F65D71AF509B7C0199F26EECC755C36C58FFA9A355220C4969FDA2C6F576D90507719BBB88BE2BCE537AEB9A1B0F84F7E149F6AA39E0D1F59AAEB9D41EB380046ACCAEC5649EDCF7EEA83367E572F88915C1DD31A0419990F33C33064AC625609423CB87BA10A61D104E35848324F1833BF6BFA95E803C1DB3AC312C4EC6A55BB6622B584D55349F23BFA68B96381C557F15F403285E44C4D80F629AC75B559D8D1208703848DDF77E45E0A91C4E3A7E9A6FE379B970C7D053C56DC55081B6D774B1B2D2F7B94289E55E7503CE5D853A481AFB21F49F758EF29E927E3F848FC1EB7EFACF1539D8DFD1ABD91455334A6FEB69B37851406987948763B620778F3F9C34CCD0E1E034C50DC0ECB30407C76A5EEC86591DA373926E7D7F89BEFBC6260DC26FA148485B48C4C4C119C5C0BDDD3811C31470846193CAF12F265EE484694D3CBD7C3F85498D24C09BCB4CD721B20807D22B8D8CA277E3B519970E21E6601051E8E07E59A8CA6D3BF3CB8C9D2D2F9873527AC5E842BE878508EED43CAB8C44B94A07358301337CF0EF1AD221F77543AEAE28DFA76B67577C945CB0EC09E92C9C283355797590A45A707EEC991B70D6B26B476B5611C4CE4497343174BF3F1424C78FEB79E42ECEB1C8ADEF26C08ED8325C34801B4B0B458B0D3B2FCDC226A6E0B164854871ACFA5D73ED78419F60DFBD27B5CA61C5D9FD51636DC61C3727CBAC0C4A82B69CF8859D427F23186AE35A7C41C23007D382E2E00C6EAD5109D1029B3CE2FD0B55CAE9C054BE7E8280A022B39E26AF444044CBE847EEA25ECABC2BF09A36EB90A60938E77153D95FDAADD7938E5650B133A936910A09677F64B073C7652108B73993BEE1CF79B88D694E46FE461EC80561EDEF770901BBE3A58B167A7078E32795B842984A3E1A06D9E1A8CBA190D424B5AEB7A29B69DE0BDD7E4053181DE85402F58595063F9ACF66BCAD182B96EFAA9F2F9A19765B3D7105DB3C6F9CF8DC3EF2D05E886079E9970358BE2978DF6FDB47EB70D1CDED8C155EF8F1003DDA3D38250CBBA07B43077B0E25E610FD64C2FB7266F471D1B245A528577E1BBEDCB6C4E23A16E9F629AB52983F48F75801908FA9CC68C1B4333D4EC84B836AA70E8395F25EF6908DE54653070A721C4B88D1E10510E44394C92A828EA30EC54D833B06C91E721F5D29F5E8E510B478A35A6F0C36B559C3C379A82DF46AF0E851414095395F6CAE2F7600BA07DF7FEC98460598C6938C79B20AE902D757A739792E40C7BA73D71DBD1158FE8768080D69892D574D28F912A6DF07EDF59A3174E10D043CF046B77AF5BAD8DF15CC79F6152774CC2C9DBBB4B8DED02D00FE683282515B79D3325CCD342DDFEB8532EE5663F7A04BEAF9D9EA0F7BFF045A43E15484521934677868F0707916E6384E9029E8AC655C60F473C682A84ECC01F3635A11854985A218F819294D39D9C320AC373B4E77C5FB415FE9329EC62F7F5478520A225831CB2B93D474A4F1DC72C80F9FF70B0F6A7B94E0ED2EC5F7B757D812FE61E1DA3DEA83867106281F54CCD9F5F8E1A6BEA410FA2E90C67DE915A17EE76E9C357D0B4CB2575F529EA7561C35AE39316197068A42954C9C0B95C3835E6FE4C60602CACF403AF965D1B12FA3258648E4307366625651099702888AE8A5A9087531D01B88C9AFC31B0F818299C3B56A62514DFE077EC466AE06547FD5A04CF26FCE02ADAA4FEE49F2083BF76587DB80C6D3476A34AF25164A8A67CEB6843BE935DBDE7A6BF4C4489A8E249837CF596CC83A575432A428E74FB706BFA6558D394D667A6F24708B80B3D33E918B148A916BB7AA98FC98ED8654E5D2B124D39ACEEFF3542D0C918BE561CA538E3071B0D8440171DB8ABE17928D968710FB71F529E0A80A57EE28B26433F9A5A9C85B1E693F30AA246965225D9527A3017010899621EE3F2A4CA0AE8D86994B8EAA3C19AD4279FFA1D8A9CADDB933247D6BDA79F392B301B80D4C0CE9756E5EF4270A77B036EC9823A8D8BFBA3A0D035F0E8EB256C5D715B819AB3B2D65A46AEF8E60E3ACAD85C5DB355B4E71308F524B419D4FCBE97C0D88873005F5D9BD06AF38E5F759D035B2E9526B9F6B8207F884DB1731B0A6BB0472546D819F959710F22E347D97C26FAA6A6962E0D931DFC92E897822B38820562F4CA63ADB20C6D143A07831D0EF3AB6A28BE35BDD10958B9AABE1D4D226FA4451312C2E2A94BCBE990BBE7EB9BAE9A27A037B2B9AC11787D3099DFC5283066CB9089FE5F86D8957F79F156A45481BDA3735B9CE2E37BAD42CE4D5AEA8A6D3DA879225A5401A8800AA6A5AA192C1328617F4E83666181FE79E3F65F6688A4C38BE1C42B4F2720C82EDA1A380A3E793403E30A44F1C154E57856B5A067E54D226594B11A191F1644E499BF29CEA93C0B6215808D35C5016327FADD945D896942183B8CD7FD34272A3CF5E82E0A5777F4397F0B8F2D75C95C0B337165E18904EFB0AD19EE5A98E9E347ED13213350BD848C40D2DA8055CF20344A2BE18EB0A9C6F275DFB989190282A25CD043DAC59A115695C4B5AA9D02AA15DB9A1F4906E34000EAA57BC408FAAF13BEF5099B12B2410244EEE412542A3426DCDC5742B3CBBDFABE2BBA473CC1D0FB05F8523B06E08810F061ED148ABF40B8EAD4BAF88F909FBDFB9EC4EE7550233F3F05A4C450C6B38C442B99FBF7AC6BCE1761116A3B0F8319EBAA9A909E0948ACC5BBB4680CB651FC3808ACC7EFAD908EC78214D243EEC46EDCBB116151FD08BEB75F1F4AAF17F5E62A5194E31491D4001595A7BA1D9786BBC8A78FC109DDC99290554759CAA0CEA1691C0E2F1ED078DEC0C04A78826A459C1ED8B4A569503A142A4D6FBB8E26A06B5A014D691CD79EEB46C2E980B674C5F21072A560EA1068A079FF80FD9B1B8F44C50DC22552946D0E7F02EEB28D7B223850A6CEF8A01DFB3FA8C6BA9F9A3090F0383072F01E2630F678D660C0DD6B9C280B53CF4C99BEF4E72AC617A852F8F5ACE0780E8A537082EB8CAB63886589006E6C5F3B14C1C461CEF8100969AF274584C1F24FEAE0F43D0150BB87AA8D969F584BA77098A43C7546E53D2CFC93C3FAE48AAF554448638EB6D2D13793302143DC8DFCABEEB1F654F5E9EBA944A24546498865034204DD429ED6B6C8A65FCBF746DC443BF8F147078CBBBFE59AB1141966861A0BE4E95D7BA986E3B1CDC54B06FD0919F7D14384ECF6FDFECD00A5005BCBA03C3BD70461263299381B2EC69EED30F855BD86B3C7C148F854D76114F2FC495B5D744EFA5213C9C4D1BD828B8402CC5417C247DB4362A67F469C3A3EABBA6633D4F34B4104FAB229BC3721A6DF64CE6AF6DE84A83D859BD053C627B28492535ED37E7D84ECE655F0EBDE090ECCA26A6132A3F747F071F294244515A69BA021F214ABE32346684898AC7D2ECF42B2F575A7C818B8FCCD7F4F6FF0000000000000000000000020710151F2D", - "reason": "too many hints" - }, - { - "tcId": 17, - "testPassed": false, - "deferred": false, - "message": "D5CEF84F7A7234B844DD16FE5F1E9DD744955D23E9EF8818FAA19ACE0A9AB6392850C48CDABE3FB1625A57E38610E80604BA1C01112C43995BD30EBA2496139CC19D0F4724A19261976E502C88E3EB085BBE651D3677D63798E92E6C20D620B387E0C7711943C46AD75378E864DB82893F2E9044499B7C890E288AE90B69B40E", - "signature": "41A46D25AC11DFC0C8DA30D7CD9AE37A9E2EC564AF48C02C8F97C10704DCFA791F7A53EEFD626B6586C75C7B501EF5486928EAB66BB733E07E176DE56F8E64D10EC68A8311057B6F858C22CCE4A5661298D7EA48528D5207F2659010A94122519300627CE5D0F7DDF0A9101539A0D21A15117BAA14621D5C9607B0DFFC4FF87C981A1BAACB2D2696F6A7A93541D71F20D8FC9C4D4BF3085A050B473A45B8CC101754435384713A7FF622C2CF233171912DE74870A073DDFB31B21FF3DA4D10F8CC02FF8E363D44101D2634D510E7452C32755F739AE6B427A81081350B476A4AA19193A9A048D503CF9918C3B712BCF2637322550B854E82061FFA931CC0D6947B96C803764CCF15E968335F0ECD5C8A25C4412103019670A2604883B207E25A772C2D106BBAB2E3394EDF27B02007AC6371250C94429BB2295D93DB0F13112A5FA87D77EB8D26862202C14A2D87B7FE9E4CE680B7A20396E391C9DA0424BCD5EA3488F0260AE859DE7C97E7E6C34DD32E1DD56A7A8DEEFF0257783E98C9B15A7AE673AAE7A13A13135466D0E7CB64EE95C4799F8549E63762E35BEC0608D7384FA8D1E5EF0037185160444107B07D87A7F2136F1C0B10D322ED299A6847920364F835B35515FFEBFEF21AB72B958806613E3BDFC98A82E2B276ACE271EFA41905614D9CEAB00DABEB1922E0FB475FD5BD2C42342845C36A73BF42AE17DDD867362829D8F89F4B4887558E7BB123B00225F42E1E8E37A7773D00000CF967D69B75C8668FAD82C6F6325914DAF958349C7D5E05DAAABF604A24CE93C672ABFD6520F9F7C687AE01DD3D91F08A4DF299A9DE3E01E2B6B80FBFE8870A3F492835982C0B4019FF39554225EB415F5D469E2A9CC6B89516B76C14992560C0130FBA02EB9123EEFABDCD802D875B5ED5BCD7A56F3457246D6B68CCB9228CB04CBF5DAD2B7A05B77A3F62DCFCD4CDBF75944AFEDEBDA48A0AA051BE98148DE2F81FF91967FBA311F8EB5456E5745C64F6000214D672E8DC43EFCB2BE8D6143F9AA7B301A343E1ED93D324D3A71A7A33DD56D97B1C0DD3CE928A2852BBDCA57FCBFCEA7119477CB0DA51FE44E50C7E21923947037E1AFD20FF81B0533B0289E188A323BE9A61AC5F29027CA360D6E8BFC1B37EBB3307C69680BBF37741A94340EF4353577259709C45F25768CA9EF0EF09588012F284EEEAE4D435E37AAC4963635F9423A97BD11C43A9FBCF174C43FE875D49C15798D35C6C2A1E38FF0AA86B2E7448D66CD2078C646C1745F59D2BC9100D7A61822A5CCBAC672DC7FAC6711432C4864937D90EC296AE75D2F07B7B1136892520EF033B394EA7B490F7C92A3CDDDCDF83DE9C0148DAA0624D125D25C2E70719D937085B4182C0D6D59D602B5B2F501F34A545F11269F35B870D43DDCAFCF544A6BA598430BF99CD2201558C49DB59DF1F7DF9D74EA2DCD814F214A2CF28148AFB13488882C090E413D118F9613E3C5174FA8A0C7DE7D37D8EBBA0376B57F8DD651653466FD7D5FFE5BC036747934C82C8639E4EF539D0F6C6E14A12C2C70610EF0CCB52A3E7A8C2D9B1957E5163A40F633808D835BE042262FCA9925315F73A4A3E2A38C8ECA7B84A044DEF8E5F5302070E634E56F6C214ED754FA9F8725D1729511A40AC5A7DA7356F2FFDB577CB69476F4B064C47E121ECB1A50AE0E7B2354D3751961D705751AFC789D5256BAD729C7B418CE6936519D75B56A3431732AC1D48010E29A91CBC30FC6EC973A48079E847FA32CD1CDC21E39F2E4EE3B0AA90EEB4C551A9A960DB6A3F5A8967FAD231BBDB5F6F99F49CE02E9BB62E86947F53E96E3772ABBA6D425E315E8C2D6E673CED8C9C73008D9111B53D96EA61ED19C4B60C55A15D265FCA46C76DDE199F2FC6EE573527D04C1047348AB09FF1C4A722ED626711AE293FDA3509EFA76FF1FCDBFE0C661F1B51F457A53A4A228C93A3E6ADA6487C67D3B74FBCE72F812CC4C66816D137A9AF266A81A8A20BB71A55980B79F7564E9D421D2822024B1E8020271A2C1D8A41AF0E086E5CFB3FE7A70A44E6E9D3DB48A818DE6EE2ADECAE6DF102F546337CD6BA9AB34CB7206C2F66966CDFE50016533D4A2299B8DBF60A2034ACCDA59B10E2E0D95E60766634BE61E7B8DD7B432C9E842F609EEC1C42DEF8B33756A10C17CE782BE03787C100FE2E5C668EC947FE21D7AEED873FFF010A6E939297EFE68752167DC81F84C0FD6BC8F8EBFC6E2009C521AC503B9BBA57A9A8AC1D770E3E310266C73847E2A843F0D3C3099B8531DE2FB3BAA9516C97DEEE06D26BD11B691933E40ECB46361A8D31B2CF6A1DB942DC0B00B193D5F20ED40D603CF48E24E56C9786D5704F8ED6DB94B26996456214E3746BFF6CE971D813115AF28EAADE0FB3F2EF6180B4D802FD022F787192AA75B7E7E2D11B6405060E29E93CC251983DF2A7A69772771A2CA7E1AC9528681EA8820151F4ECAB5144C0CE88413789335776147656FB6B085320F6FDB9A972F0DB63CE10AE722761CD538B5B7D6457119FEEFDE7068A529625A1478A43F85BA01C9FE1933155880CA6A4B24EA043C36879AF2EC97F2E30493669AC8DB8375E8A782F2EE16317D742CD2D1EEEA354A20A2B08431AFA6C67A14C07A334B3D7AEB0ADC26EB2069E2159166D59FA14FBEA6EA2F0F2678030DC933091264B5F9644005D118FB26D09C2EAF6D9166C15E3AA1243090F10996FD1E7E8672C650BC0BD095598FAA5DB90F72CE7147FA31E1C67248EDF9B75E84D62CC637547CC8347606E5E4A353FB5D4928D1134B06D06447C106F8FF55E3F55B2128E950B7DC75ABF7A941B29B9CD6F9D67A68A53252315D4CA7D247E0A107849C1A01098F62F9CF601850496BBA2413FA23E8807EE0667FBC60E2BC76E52BDBACFC5485AF03BD1BDAE72490EDF58D4A97610781B338F3739753B61A42007D0DE7CBD42ADAD09911D892FE02787A0463D55B0108770D0D14FEB60DED8CD32ABC1B07C5FCD796D85B792E5F3FCD9634E325C30BCFE761B435AD214422157653A59BCF7729BC2F036AB7C5F7666BCD25E70BCD07313F93BAC1E62215EDE7DC6C2F3D4B1A7AB9C84DA53F4165F8110AEF95F5701D02E6F9A912C4850BEA44D37AA9640809F2E0B42B8DEADE4E9438A6F1B615E9D2DBDBFDC71D9E47882F9D91B5FC6AD5B2843F63236AA99C894C156E876ED6EE88CE1401E938533A0DAEC0996DF97A6079C31A7DE8B8AAABF05A98A681785FB6F5D03F5EBA0D43019D613B3387F9DF0BDF47B9F2D64699C7113851E53DC4E28F7379A85C07A62445D8BEA23C3F8CA145DCA267E5E95E9CF3DB3DAB806BFB39BED68DD5576EC5834DF9131B3B112B80D256274553B82F60269318E721175E832490BF145798DFC4B767FF494931C3A2BB2E62AF33C4C305A3706E2B0EAA0A26326EAEBABBC04E89361A696750271978F99BAC4CD2BBB8D04EDF9F0AE73B0B0B45213A959941A8E774F74073B9E483A94A4737E849D2027E2A656C2AAD8190C73721A545A1C4A30C46674DA3023976E49236E0D332EF4EFE5FFD0872E2F9F170D70601EFD9B8DE625CC9325129E1F13EB4AC5C64F051463C994F54252470BEDE3769FBAE61F0B05C01C306F5A003CF37C34AE18FEFC74E23CAAE39A966289BEEBB4DD5ACA07AA4017219E660621139B11BF6FC52C294452A9DF4578A0F07DB7BDAD6AC0CFD9349D12D2494CAB88045BB7C75244EFA7CE6F13BFBC6A27A202BDBC69BEEC46D8F3A7C670DDBC6D7C6C72256EAA21F64D6FDB52AC54BAD164A0D1DDBCD361C8F1C5A747EFEA7E56FEE083F50891765CCAE43470A7157C0551390AA73DAA380ECF6B11A850E4A17463CEDF89A41743636C28D58B571CB69D8A7E99E59941AAFDE9210E7AF4559D24310C96140E43C29F3DD385F55D9D7A7A678F9FA7545A13CB62118E3FE2D8B1383574CFA80A1192F46FB2B92C3B8597015094928E91217B8B3927C48F71B189CFF533767758DC89EC5DAB6A5D031E96D0A23CB2CF76FE6A0747AAA990EC6B82CC21D8BBE0D8D805270E3898E4990DBF497B7292E8549D87F224949F2CDB690A88E3348D03D9736A9F6ADA868580ABD5F96CD0DE30F6490BFF18D8F9728E84BB595E7AD81EA5CFC1389734E1B9C5B4AA3DA8C5B6EB7FA272C36114DD442A4E951EC170A6BD66609F73331DE4938E82C92E5090C4CB50DFDF3B31E9FD2C058CFF7480F0FC081745B07AD6B5C6BC724ED85315936B9A49988623E15E9E7BD5D17C2FED4FD819EBD9E69F3B5BB7941F5C429E4820A45EC76E04409154667BBDAA6131B9E12B957610065A769B1314A9EB9B9C3300271355D1542E2B7F23E8FFC8EE0CFEF10EACEC97D3476A3FDD999188D145F4B7BDA19081D099F2FB1013D65247BEE63943E9B783F701F6F8089371D0642C55F4BC86702CE6B1D78AE140012978943D42E0E86FC0CFCB09028AE47CF80F429BDB65E5F9350FE991D50E803B70B1965BBBE7A6359272EDA393BB49E4F35594DA2F6E8B208ED81C743C028B7ADDEB0A2CDE6A38E8A740F19FD67EC37AB2E5BBC060ABDA35A280777116661137F76231991E28328A390219375F88F915262C305C666A88A7AFBCC4EA1541C4EAEC54595BC0EFFE1C869597B7BED9232783951720436570C7F8000000000000000000000000000D12181F232A", - "reason": "modify message" - }, - { - "tcId": 18, - "testPassed": false, - "deferred": false, - "message": "322A8DD07A5C30E8696FD2A11CBE14DB92745C958ED07B3533E8FF575BC056A26E83D681FD6FDD8933B1692B6274851D0B41FFA4BE760E08AC8B4058E5639AD29B3516A2DB1F1C92191A0C9DD927C17340E5BBF593F2D78426B2A11A02F6A33F4E425324E8C502C636939795FB35BB4DA6424E89A3E815EE59FE68DEE65325B0", - "signature": "5ABAE281A15ABE7A3C0BE553F406B6F0C5760900976221B0831DEC6F144ACB426B3A6252D517C1C592A5A9FDF576C38B7B8960E781201346EA99AD5E52937E3CFBEBBB40F0E29C17396A808ED58F8033C7B4BAEE68A3C7811F43DE3C18E02A38EA071E043F811A95802B06A37BCCED5053813D477AD60DF5A3A5E23D442153E8F8DFC245741680440CFFBD364A0225978DED965EACEA576B0C482568093ED4781F48CE4893BE763A36D7BF726C3DC81306E74A1E6261C045F06E990169442A81B797E2F0C40E917504425E4E6D971596FD1C760458461560F02B2149EA1A8B9C2840C58579EC0A973B46C93C71FBB3BA7EA31B9703E6E908FA0FC01E9FA00F847A1023B006767BF9783E91F5F37125D36E2C8444AC340F7B2174FD03C66F188272EA4E74E6DB0CFA18D5B2A63DE17C7F53F8418BEF351F36577099E165DE01F8C302B3DBB987779CDC6586B8DAE20A2450624EE005052ED95E4C12A2CAF1FE20A43F7276BAD038222C35F930D7EB1BF3172E53070D424AF84EB4EC1678DCFF2B431C5FC7D16C4711CF19E6140455E526105F174A16D3733FF91FC81A5E92C6A916F4D8F9E2F334DAE8804E682B5317660EEED9E8F9C8C4E0B0C07E0BC4AB193C1A47501A5982592F57289FE5C919BC66A861429354AAFD66BADD3F3876727BBA4898BEEEB6AD7E5852493DA29688D4F480398E75EFDE419D9EDE15FFCEA1BC5C8183E017B9F973E6D77CF73B6EED2BDDE82137902DEB9A258BE6D217B9DE7A08EF0018E116F98440F69D628BD127AEE447A17AB8FFEA119A3E69A11DE67B15AA6F9AB63500EB3764ACAFB465068977215D8E310505B5622C3471EEFEE54CFED8BD730DF2C7AE1C8CAD99D5453D58F5BE0FDDA386BD4690622D8006B1E95ABF5BF862229E34F8C9FFC8C0662857178EDDCF88E8E1BFC265734B28FF951EB8F303637525E7EF1348F40A7B14709CCEC2CADA311863FDD0DCBDDF8A4FDD7D78AF63D5EC7321F15FE15F1AFA64A8A622D00A7DAA4698DD0FF584C1CE16483AB9862CA12479BBD3814C8E546159EE19D490BE8A8396B3D4F0C6133ECF602BCAFE6701AB3B645A6C3D8BBD3DC3DB1D96A0511B3456290BCC1C232A44C7384913079CD0E0CD99CD7A1C91D2961270AF6CFC60E50B78F47C0B7B0926575A0440D14B84AED885963CFF172C8EE791A84DEF0E9AD82E80C5CDAA04F74638BA355837C28275E456833AD1094E454E9339C421CFA4DB9C3454ED084C8B15F94BBBE62953CE2B3831771D9B8BC8081CF76C285F9A1CFFA9C02E7678CA0989E4A267FB1E0A9CC41C83A57D896F09CDFEE5839DEFCD4F99E71553EB0CABA990A1B41B3985423D1CF5FB65C9C8A651FB38A00A46601F9A7A7C06873A4D65FC7C451A7AAD7AC09C9EA3CB1C98CA8E180F7409EE43A9058879E21E860908CC433DACA33AEE10A81E16EB56DD4ECDAE47252DCC85335054973D69E4E5BE549AD7FD1BD5CAA5B259E0AEE35ADF5E9AA6EC6D67A8F1E615F17D0936926A44D7AA6475A34426EADA003CA8DD2D541727C1B2052E261977A22A16139B2E1D04EA110392BE90F35453C215B11BC54E9A06BC7F31375C45D584200EBBEA77A025D9DDA57B1D815C47F5B296F1E66D8321E1B448620F387D19D97A36530FD0CDF6E1C689BA53453DB02B6B0BE903E3D273628D577288A376DE0D2BCF349905289BA6EB247FB54AADDF51D8C219977985715B33C10FD9D8381140083E2485DFFBC4C55D70C9EEC73F46A29F61F76C019701293D684DDACFAF5A3957620E549CBAC75F349F8C3263486411F293BC198A1EF6B7C31A947FB51F35AAF5637ABBA1984F1468A2C5E7E80ED3664DB8AC70647120D249A9F22223DAADEFAB3D4321A3DB39EDD8EF4D72FC9E707C92C10032BA6FDD56FBEA999C4347284659702C34EE4C23A284646A38F3D02E08142A4977DB49DFD321BA864A810B4B5545640F3E441C627860DB79C69D46E13AF6292D505C35BEFBABABAAC33EBEA381B777CE44E54AA9C9619BB6AC07D91C1B1EC448DF9AC348E7447415EAF09D34D8D3D7879B44B20BB243C6251607ECC3E654A317CCC72EDB65BB0E90128AA47618DACE668BCA5BFC8D68A4A020AE6EB60F886EE1DAF5D460BE08EF65C83CD46C1745F7D313B9989D9910F866FCD0564E04E6223C0BDA00EF40AE9B971BF49E7AB0E5D055AE96C50F96D9CBD7C696946D308636B0B6F7F72F0526FFF23D0AD61911ACAD1CA72DEBE007663D691548BCB3DAA1725578FB2551C0730056BEA3E63E30E4B2A667C58EE7A5951263CBB74A9EA776366166FDC60B3AC3A14E4FA1808492A899FDF85C2C495754C55697EF4402C76E8F09A201126F97313FD2628A4109B34E29D1C3E4E135307C8C895FF8E3542C6888E728DE15AB81E73594F5368350E02AC4B1433AF200E38B0EAFE09317D06ED9DA3E61A82ACF924249C760E159358438EF1B32E58F0EA4E7B3EEC423AFDB6F4A25AEAD2A6EBE96B140483FB2C1833F826E46F62AC5428D6C3926216DA16967419C60EEAA7D7D3D9DFAA94A411843B3AC026EDD80A73B52A5F29CC0C2526AE660128015BBCFAF0A0DC18F5239B2A397036D8BABB4E366449842C0820889182C742A1AA3CBEAF728E9E22E8473DD8A7C0B70800F954A00E73DF3992007AB34BCF20B795B4DF3392D4A62FC52EB24D4598574B85E6CC188CFEAF1FBDA45B1EF57B99C89347006E4C3C3E0809EE541B0AC27773875ED6C1EA615CE5190133EC07036A014E41B4C99EA0E3742355A02FF0579DDD6E7AE9B7F0A735F770B7CD157E9C5893592FF384DC78FF864C2EC5D966305E82FA41AF3818A122AF70C54B16282958D262988F81D7571A845A541976E730C37D79F931B73843D41E927A677730BEE342F774C8189FE5547CDEC9F8C4E5D8984EBA8DE3DBE9DF73AE965EC39F6FCFA0868E30F5DCAE6AAFA62048802E7A99389EF1CE6EAD5A9C8008C575B8D41844DF779CCCB519EE6C45E9A2869F09AB938F4EF564B40E7CC9B6944643C3ACDB4C3C838BCEC1E652069012BB7A8428FC8A1B205D7D13F36F9BF6814AD4C8D3EF646B4E5634C794FE0B1ABF6B13DC41CC5EE45F84234C77A403D306664F9D7B116AAB371A769A4ACD163EA5FC8136B26024FE501088D7698F3F5780F5CD350B35419752FB98C5DC5DF3C360D67988DF71CF06261FBEF28EB46D91F24B41F8B82F5617C1EDD527A67D4F9C1A4B46CF753359A0D12933342C1E274322C13D0185125A24D4C20C5950E5703074CD6010F9B3179D56CF5B9B351D8FD7DABE09A729F8DC90D889C2FEC75539672C765AF0BA41C9488BE77B51C0BDE49A7B43EE9D93272647D129356C134B43D5C38D7294FE164A366625E239E2EF737FBE5C4A3B16C09D38D4CE6C16C783A79D2EE0918F4005B4B703C8D08422B8AFB93D4594103BDB1FA7B65B889C93B0436D7E830E1DA018BFEF2D52E3FB48DD19BC58F59899DBA4B81CE01B40DC4B42FFA05CCFE2C0FBF53C60961B8AFF7D3B2053032630C54AA105B2F3EA1021405ECC07608E87329602EA6B4FB0041F891405C8D9F5654FD17826074A385AA29BAD71E6727045ECF8365DAB7DC5B8DBD673C1231E9CF5B4C2BD9F870819391909C5FD479CD973AC7DB6C16ED38A2CB9B06481081C6486199A2AE7DD612240F4E14CC09C7614D5E2EF4465A83462D8C6C26816BB755690DCE898A0EC84AF3FC773C1A1F9401764D2E4FB346E38709ACE4DF955A64ADC134A7200213CDCB4FCF4A4189B1F55E917350E90EB5A5D7BF1EA9CFAD58C92B765E95D00DAF217C68122BB85546E1BBD6BFE8A47D0038C1D71C425BC9F6B978BD2C6E2BC5A99D89ACFA359BE65AC72FB1769B106FE0608659B672FBF22FFEBFFB924DDCF744E964490689A0CDF9A9E0EF4385CB591FDD8D64B587EFFB90DFF3A1CF2C051EE94C36904CF32A6BE6D51D33E445B48766677E24386EE1F779CB7FF582FB54ADDF9B908C83B0A3B7CD7F393CA49440A062AD6E79B4B78D30EF43E157D9692A673650A993C4320FB20468A23ABD333621F4104ED0F4FF07A30ABADA4DB3FDDAE7C27B39635734EB60C0B06EB64D4F2965B3577D0F86B3B3331FD9D2BC74F2ADFE392C9E7A191A4009755D988D8B4795058A3A87F9B4D0B8B2FA649F41F68D7A3A3F9736B6AC164E5A937AFC7F66F28E6908337EBAF78D318D46989D0123CC45BD274321A1005F115CD47EB1839C032FCAC6237F013A8FD5214A87611253B05B2852BDA85E8B1643E76BA5EF2C450FAB484C0525B4B31377170A7DBE4C860CD611645CCD4510BF2745705D9B1A016C847874A2F8CD7A169E2BC0F7281556F0F326CB0B084DDB230726355AA6C2464EBD1EA6558E09942C393D98FF4D1D9FAE9199D32941E0CFA9B9BE406DCF09628782844AA841AF274E8600A1463A5B9250D80EFBFE835DF6C7E5E3DF2906556F1E0B8541EBC93BF6CFFC8CCCA6DAC6E6B2935CCE34205E9AFBD58CC1D9673A1AD76AC69B5C9970FF5F4E7F5191250B7C483E94DB54AA5BF6F5D5816EDFAD192F5EC2ED893BA7DDC881502BE0E9608A5FB3F30CF15D2BA23E3CA5740CD426762468FDB387D4E54D6F83ACB0B7ECED0035243A8C8D9A9FA1C1056E767908116E950E23525D7DB2B5EDF10000000000000000000000000000000000000000080A12161A23", - "reason": "modify signature" - }, - { - "tcId": 19, - "testPassed": false, - "deferred": false, - "message": "C23CE9096B49B3B16C601264D8100ABFDE745D21E8D54B1D4934BEE8FEBE6D84561E9AEF470012E12514CAD48B15B709B0BE1834C274715D2B30097E2BD8C537359E7A9019BA7EF6A91F955933774E52B2E9C1C4F6A322D0AFB4AAC5F6BB01BA6DFE4CDA6869F371830ED8E4442012D5F6FF3A2C9233368278E2FA0C2C010481", - "signature": "D26C789AC9F192902AF965AC03815AC01FC94634D9D8A59FE7AB584F024F37EB23D128FDBFF8B88CF78A0B3A9B3B65A3615326A5C57E9CB6E0E785B9BFE71FD99CB92F4B13F3301CF5FA92E16F2352F7099A3409C87FA240A9B4641E1D4BFEF00F0A6BF71600E86EE2052A25F4425C641D53B41D2D9527C06DACC2E404535919CC9879022A4436013AC82C9B6A6F4C949D41A5114749764A65FA490A620012E4E5F750F50E2D381BD0921FEF3E900DBB64EE32D20A8521287E9C5B38C4875930C3A6E4CD9237CD7C3AE80999A73566EA5FAF1028824FD8F5583E149F8EC08164F1EDEC8559BA29871308A41D5A1270C8C7DD5425C2F8CEF4FF101FFB2E77C96BB4EC02AC94D7CACBD3D70F6B540A23F5577FB0C3D40ADE3DC929397EFA7FC4BC522220C4795A6E28E0C876A18F3C2607F6F9C7442CD8CFE98986954BC839AD483907974984135948A68BA57CD127367DEF3D038DC6811A528F516F5C7BD8F3FE6C42EE77812A5E97D131FCBCC8FBD153182D24FEDB3B2CD1DFE5ACE59C67F81A45C7C58102E942A8F8DA73D5B9B9912D70F9D81C423E50F6289740EDBB66871ED8B9F4A7E2CE2B61175EDDA2F8F92A9A123CC94ABCC5629A44CC0FB10FC0B6231B5AA9607E0D931E0E01CD00B82BF3EDA457704C0B851639A3BFE49CCD75F85F93C41EB600C633EF980FA0974B192A9FA2524D9212CD54721EA40FD8043ACB61121FFA9BF191D5F5A74202C53EFC3BF151592BC7E34A0003574B2522A0B3AC1359522BB916CF7F96F7D3A32B5C5DBA09FDC73AE0B463C9832A8CC998CBD72F343444D6BA396FD5195C70774725009D54585EFA6C20FFE4181E5A1E66545AE0F59EEDBAC996784134CE78E47C388B247E295374FB538B67E7B05A64B918224F8EA06AC609D45EDB4382C5181CD167D772507292F043C546CC86DBDBFD8C4C1C0D158021CF93A4DCAFB98470C521D2B97D0DB7BF0CE1A43EDFD2EB6A8BB74765CA6B92610A99110466D818F598D56D86227BA96541F67E56C40118E9105C44883D884976F8123102994E3AD063A58D2B2C9B43806834CC98C63D43E90475E4DD62BA8BC782CC99FFB80E92D45F74468F5F799500435E355BF69CC12B0135D2C3D24EC61050949F10213B9A5C2DC972B4FED6F094A5671005743850F544747D3BFB8B3C5A5FF3BB293040E895C0E9C69E25FFC3B5B518FE2056CDFB27E8FE9007C527FD81074F5AE1D1D84070919F0DED0D45B14F79976894C0359F80035557E7A87820F2A327DC6436A1FB9CE9FCE4AC85147EDB0BF0A214EC9D1D4D3050C94A521C22ED55FC162EC8D40AAA5B5AC631D00332D4E1A3D39206ADF98B57CE9AC41236638E24E1F150709E776A91D12F5D93A542D30C5A145384FA03154AB4BFE5824E0A9B5C97F21EC74ACEB36DB12B3ABCD55BBA3642EF0878A3D96FAF554C6F339867C51A2D2C43231FA4A05C2BECFBCFB08EE96FFDBA262B1E51E2FDCC4099EA853F95A29E0A9DC260B9C239044B691E02738D442C3F1D59367AB1DFBFBAB80106B011CD7150BDF2A7B0F9A45AF105DCDAD153550D37F54B1EB4C520607470565CDA8DD1A7D12EA83B3E3E068288494A16FA864EE6C50F617EE28540201720AED47D6B727FC5CA3D2D11DC3318AB1C0B48368D94215D6A1586269FF91C298BCC9C866360C122C5157A3F7E219B0D04CAD4BEA9A8B517B3B50E8CB6296775267FD1489C6BCFC0B61D2329ED2937A562C8742590E9B98C3F4E80216874B3DEA5AFCA3CDFD91980016491A0208F42389F1915388000DCEF86AE8E9B4EE3062560414FE8496AF7CD6508393A35E79DFECE58CF388D7DC49E5DCB7ADF0364DF00495B26AA5B1E130E59835F8688EEBF7CC4BE433EC21AE5D4FAB50A93DC85DBC688D873E2F33D4D3358BB7B43EAB74BB88D983C9551BEB76AE33C22BCBD92A9CFD1EE4B0A05B90654624056DADE0EC560F50799643BCE690F821070A5E22CC62C8E30BA3D21658A335B143C4B96C85FB21B9B4399390819B56848E3A0A789DB58DEFE912686A37298C8FCBCC2A63E1A6D41E971106A4084ADE356D49D2040D196021971E1C945B175B118B9B9C619AA19C42C622CC603D0C555499D7AF6E121A34B24E9F2118B632A638807D961E324D1726B7A6AFFD20EB0F6C8165ECE661E2A688B5F4B7F95D919CFA2586DF48A00FF537D7621DF3C618EDEBAF87C250E4175DEFC07E53C04444DFD71EBA20E4C819B919D294C97DFA4ED966D33D28BC0E230BED3E5B71AF6CDCCB699F5F28D2C9BE23AB854CD45C6639C79F89A943EA4E7ECC6CE9170BD62AF65F3A03E29FE42BFE466A5448D728FCBE40E1EE88DD467A53AB8DCDE9652355452AB2D511331169D574F39AF8A022A79B9B3EBBDF0FFDCFBE400388BED569DE2B48BDF7126CA5030F1A6BD20EB90B4451C67726D8E3D85D05BEE892877D1A5494EC5414D33A6E3A8AF7DA146758347AA33C06C7095F137CACFB3C7D479180C43941FE2F2AA6E7791FBB66A25C4E4AB06B2C1A4DF85A8864298D6D2C5004FD8554034A7E8499FAF763B49AB68D6D2EA1618C9EEF39DFB950295E96423F104D5F48D71C1602F60747A042319FD9D9A6BCBE75DFE6EECFB4078522447798D41A9285D0B30C36B9AAA06419FEFCE7AB3EDB392C12DDF08BC5813EBD3A6D55042495CE8010A06964C1724EE869AB0526A99A0DC129A7F90B5BED46AB5F480912AFCB43B95F6E5968E075FFAA61E696A986FEB26F47F472090E966E74ACBB041A207D6161077F2C8D1DCAF2DD374BDC1A36CE0BC5BA150402242311DEF372213E800B8FE450ACB68B76E0627205982D41CABFC76F020434684C6AF085F7F1CA286689025CBB3089700FA73DC287B3D434ED0E3BD50C6E2FCB596ABBBD8A5E6E801EEC96F20AC2E1C2A9E853DE118E5D6A7C4539692535D58E011F8F347E7A97389775C1A9F8FCFA661B6D9A085227FABD918261EA46FB0D6201D1A73DB702ECE279FF88236D3538D19EB7181492A737D8A2DFE00595AA603A95F6DC040447EEED1167A3E427D1EA56AF160EEDC95DE2BC1B2F7465F2FE718CF31BAE5FD4A731AC9A71306A522815EB3F19D6D6DDF7F0AECE01C74B7F34A083A3552E60FE9ADD5C5A307AFBFF4D6416DF6639DF9F3A1998EA0AFA73C2202D8B9E3975E0944AFB73DAEFD9E145F79A2E9107115A19F9743EBC34D17F6FA21AC1F65FACC3BF5061289DFDA8C23ECEE83B90789C835C7E58882886CACF96A6902E6F20E5467FFA0FE3BE62A3428A04E03FE69BCC36E66400A423C789DA05710143E22BD72BF48AE4DE9F245F86E9DAE3665B0DBAB60B8D270C9CD43E757A178F8D949CBCA6E5D69B94BD08A4357EC5D48039FD07B973883FCF9FB8402B6280D9DC14BB0515DD167AFCBA4E66A72394A18557E1B0C74E2840B32BF5C21569FB16F0DFB33CCA31511C86008C11FD546CE895E0B9C10E92E9B9BF3611F8EDE669512E89BB1135D1CD2BE5D314A70E53CE1EE85636D2474276ACB2464AC94D26A8DD78E0C613E8EAFBF649E474E2730471B18E04748C451F735C04B2F00EA063103097A36B054ADAD1E5BFFBCD97CAF46B959959EB1B1F581143EBAAC81EFBB7D182162BEE1EF939F8F5385E9352FC2FC4B4E74751EC03071AA8DF882134AEDD888F86FBA8A7E048873C945CB01C714584A1FA76F477FADE061D37E02B1B1679B0980D6FE828C51C367448841F3EA7722891DCF9B6441848AD3B02782A82ED2C44390671D55DDCB38FE2BB48622E2BCB31BD932F89C20FEA7B054DD885E7995B006D76CFC9E88B4D442E231AF1159F3B7754132B07C7F9698EC48AB54C12042DD111301A5E67BD430F5FB5124188AF9A9182809FB670DB9A4A3FA5A3B36A30C5C8A5F12A879DE1AED9C560FFA9A84B5F1EE7D4AD1BF1CF72A70E67CF94C2615B34198C2992683637914805CA45B71981626784FF67F2208EE07A5A3AB76F3466CBD7C6A8CA2B29278C9065383B340B8F8700EA8C3F5D0E460A1C1B5F8C0D910E38FD3028DD6C39A86616EA08A0A6B747DC6470FA38B51135BAE7FCB061B20B376F031224A8E6B49A84D64F166E10BA0ABC398BB3F2E75352C1C2427DC143211A3CDF8BF7DA4052BE707F3193448835EC86A14B9E92D5FF836A2D54FFB592DF00402C288FC23E5210528707AABD320454091A748E2D8EFB0C5AD84AD0BAD74839899B619773BB68386A46182CBE0B9B48659BA3D4A5AB17B89AABFAA5DE7B83250CF322EFF7F6EDDD62C59BC315C8886D0695BE0993A0E20FA231370C0EAA9FDCB23D6608D246F148F2C004A46755AC799FEA3322C8B0B6226208A14BBEB62C54B2A82FBCF060940F9E33232F2886F5C5216721B47838BAB4CCDF46C74FCB564D39B626453E5F89518DDDE578D7C1013717ACE1A3D3014131C0414045B9178EBE3F525C2D22E197B14D6FCD88F11107B9B161FB11972D990B638BF56C1D517DBA8A2DDFA257F37C4E6B8DA9C9359541BDD9F1953D6595B082066BF71739B6AAF762E0A8EF266DA22BCC59EA80F6239EBFB3AB53D1E6771DBE3BED9743E15C4B4F9C3AE7231AE1D37B23F41696883BC57726EA5D319B48CFFE18CA3ACB9DD1D4677B4B93B7E878DABB5C50001295A6E7881ACDB476377B0C4C5F41D2B2C327990B4FD0000000000000000000000000000050A111A2129", - "reason": "z too large" - }, - { - "tcId": 20, - "testPassed": true, - "deferred": false, - "message": "C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E", - "signature": "E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21", - "reason": "no modification" - }, - { - "tcId": 21, - "testPassed": true, - "deferred": false, - "message": "C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047", - "signature": "051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922", - "reason": "no modification" - }, - { - "tcId": 22, - "testPassed": false, - "deferred": false, - "message": "9130D413AD0F370925A8F3A78063197F17C7A777CD304F31EF5925E55AE5208702FD41CCFB65D2D22B2D6986B1288E0E45C7053B9B3C08D2FDD07880E162378F2EA4CF0F715E461D0342B3D5024C0168D9074891744E2BD20CB32B4282D515DE036CD2B29068158D597A8AC70E14852812FB56F6413AFC0157607787EC9F978C", - "signature": "BE9D4FCD5E8BCAF5B1CE72E924F236017258F62B9AB8855FC614A1BF12D0961D783877B47AEDD9857F9FF79FB236BA15F170AE2603A2BF76F3CCB132DB762B95854BBD4126625A2A87AC57CB0B18A5D4321F7606829793BA8D959326E717C6E6F7F454791514C41598BD4A3D275A0D4B4424AACC97F9B2765483ED2D77A13CFCA170E9292812F127171A5EEE16CFBE43A2513B08E491A4F119C33411662BE66FBCD2C099916D5D7C346271764548C669B7499C5972D861BE96076A2C5FB9B4312FA2DFB58D0CBB02D8C29C131DED78CF9CDE95D0088ED8817EC6420F6FAB906D33F29423BCF4E156ABC4F65417353F24938E6EF40D7CDE482D258A55D22AEDDDE239B256AFB9F1F1537C9F220D6A4F9DB6748318B020FD426E3A84269A8CC3B98C0A4D68A19385B74DBF6208DDC237E17D6F374E7B8428A5E8E65A1A54C34DEDF025C433AED396C799520E2631773824F35F676B85CDEC1E03DF3E18AD52E503DD753A26731E3B68BC3CD0B431E2A1088D07CAD3108E873ED2ED6542436FFD9F8971BC059CCDC312EF3E37D6DF2B416A2EF8845FFB70664C1CEFE398BEB505AC690FBF6643EA3C11D3C6777FCA35CAB40A7EEC3E74263743F6627958CCC3FBC4CE47231119024EDEA799C52909C46A6E90698CF8659177DC72D996C77F6C610FBECBEB011F01591FD5729C0BCEBFC64CD098E19E013229285B4EF0AD28D7CD2E8E9639A6C62D654CE40A181C6982DD9C7049059621928FE7FF164CE38943853FE909E5736C9ABFE1B739217C69390FEF037B8E018CBF47872FE33C0389FC365F47CF72C26FD46A1A9490F5B72084CCD58B1F81F80923A6967D0EB9B3EE6150875DEA1750929BFFF42F1DEFE7D3E208C37EFE7EFB44CD500B3BE75E3D0E85758E035FECB2B04EDF951B3B42C66F61553FB6FED7C7AC657ABB82A752E16D0C162AB25B973F34989E3FBF97AE549C547DBC35A7E3B37A8645ECAC5D0EDD78429B86AEBE242135FA7F64698443E4609B6529C94E4297D70E9F6083F5A35169A4F52A6A502ECBF1A3FAD02041CA3F89F62842E8992F5D3EA932E6B3A96A09BD50CD45E8F37A1062514FE68DF32DCB1F73E29CC7D34FE2925EAD3C64B3ECC2813DDD2F11AEC2C69030984CAFEA9191F230DFFFF45928F6A4F789E508D26682CD6AC443D680E8E9795BCE04DFED504CB325A603FB8C349FA0ACA42C5E44B6969ABAE230F97D8799AAB41F58082FCB946DE9791D2EB7220D4DB4F608C110355F91DF9B0625100DE20484324F1D1EA67D5019F47766409144C877DF69DC3AE64343B80E5DFF07A1CACAEC20D8A27B7893ED1A703C035032B2FE04D8371A7417DC88CBD0B586CAD79A2B5931915AD32DDE4974856A79B086E44D30E6A9F857E95B03545A61EC0CF829CE09389432B50B01845CA5216B6BB1B76AC541136C73D2F0D2DA139ABF5E2FE80A9920BFA554830BBA02F6F178F74A2AE76369F0C0F1B27AEC1252F9FDBEA8A21E1B7D5C926E75589E3696CA9AA54BF647937D5CCCA98A385CFB145634F0419EAE62E8A325F74108A8295D02C23684761DF58A77B6CB23B86FD562C6D41FB88BF16C5DD11666FADE6B9827C8D37C56EB63A6A32C548BCCB675CD2850518AEFC8DA57B2B27F6DB88B00DDE2417D8802700E9FB0AE53A21230377C28B722DD3458051675152BDDAD610D2E70735869D085F3A76088E9290B78D5DCD9137D49C21EB21E36E3DEEE68D59953ED2EDA2C2861CCE3A99AFFE8AD4C130B777E2B62CB6079F9BA61866048B0E5C8F69E1BEB9DE2532AAA18962803E08B95B079CF3A08AD1AF5C0C0DEE3D3D4CB9CB0464979B5AEDD2C359853A7216F89F899456C910F97801B4EA2FE08197E77FFA5F73939EF6EA6503896DDE19CC808BE5FA91DFB8441DC5D7655E0794E62D82FFCC2586E791F6DF3DB0360319B56B400E6876A7AE010670A04D503DDB102DCD4F2DE59B1C629CBF3B0B9736DDA9DAA8E3B94FC156AF7C7BCB293B3C03C401BD34A751687DE8EFB6614CCF3E36219BE342D9438F55BCA880C2A0288ECA0A183E7A2C6690E3B87CE6D7DCD706E8F8C7EC5F0AE42689125D948885F47DBBD5B574F44982FBE108E8A66DE9FC709437BDB58934F2D3A99CD793598944AA6D7A481FD5DD52D56371F58D83417264C7ABA14A1E2F96B95274DBFEF317052F66B2AFFC603E9ECD4FB87954523BBD13B25BE736F759FE31D288CCA9265115A0A16A78D15E8D76AEF8E668255CF270AFA2B230CB9D9920528C8DE0885A24818C66A587C7F8E24AED2B9BEDC6C03F325998E7BB31AFCDB0AC4C0C31711B22F4692DF4B692372F3CC189B3650C1A274C9CB9F87AC3D69238DBF1A9BF34B3C800A791BF66F229E9D0942E46F390D2C871DBE11A6015BA9D59A34D8A38D7025343CFCBF7979EC8B9237443C4BED2BE54A58082931A45E0A98F9910BA4F2EB09260B0D96D446D6024EE2BB25F63C428F16882E903C427361EC90AB0FEB6FDA2C9133158DDEC6D8E9059AAA10AA12F8F32EC58CD78348ACE6512EB26163D803CCB9C1602875A692D766C859B5AA3A9E7D8966AFC1ED898ECCE5854532353B8C6ABC4F70153A6DFFF80EBCCF4452284F8C059B15576359E11B6C0A3EDFAE3B925222F1150F4B2703971BA35DD2D8D6C564B4F5E60FBF3BD5CAA6A7087C72AA1B566E339B18F794511AB00B1226645B517A6B84CD3C04E0ABC4EDDFC29B3426E62CF83916CDD0C2B30A1D569E4B6A39E8AD3B7BAB25EDF5BADB7B9DEFCA4210794BAFB6FB0E7F612D3674ED68690BC5D0152B15E8340FD8B612AA91930524EF917C6F9332C24B698EAA20EF9513B8A23001F8113A9E915F6B9A6359ABFAD88687D029C911EF53E61ACFD59CDEFCC695AA8724C634DEDF3B37E5038E6D95179C7E91BE5084EE7E6D130DE5401ED9113F552F227AC9F707D0C525A7C94709E4C1DF40EDE3DEDA83F8F2ADF77161837282CF2BC478178BF18A6EBBDA930C1C77730E7C3F9B9B80156BB45F912CCE523F6D52B4B3F2415F012A59D8E8A477190F084ADC66450F2C67AD4EFC74E91DC2EE2E582A41BBF0490D2F401267CA2FEA44AB79CC5A11DF418B357B9381FC76161D6D9ED5166A4587C212046C06DD324115C2ACBC100AC70C976A67AFFB8FA1A186F13375B11226496AD9440EBAE45CBB02AC351129DE637D35620B392C7266263F6D8F47A4E65CAF71DCE0BA4D4C3EDC467162397595196D8FCE5884975B7E09A3B00BF2EC46A054E326AC6776BBBD964E368B61458B085FB9AF75EDC27F2D81194B8716A614023DD356AD548854D3B695EB8BCAECCA4B0AF983FECCA875DDC7BAF0E1C90BF307FE57772FB5D392439838EF9F0C798CBEF92034B019232480DCAF988AF4EE3C482D3FA877F22E28706FDBD2A8E7705801EC67CA3B8C5054E7447E0D3A63F9D9307AB3F1992A1E00BD765E861F3580007792BEB4577CD31EB814B97396CE723D8C633684D08AA53AFE5BB543B3369CB8B2A24A108BDED07033915717292B2B303DB9CB9BCF67B5E8115832BF4F669E9AB629FF2A793F0AE0B8B4C43BC74488D1725855193319132AB1CB3876F46A2B48E7126E8F4BBB09022B02152EF906488611EDC82BA87D687435FEADAEC148F0A2DFD784D3309E9B7E8AF7C78C8A52B7419F94CD6FF1917D7518B0802038A9414EA235E914BA03A001CF595A63A5868E23EF0F243C62828C625593C2C5907B11C8348583F0BE946CC7CF53990EA39A18AFBFFCD205F11FE2FA257240CBBE77CE553008EDCB7C15512811642CF46A725DB8802AB3964AB8C08FE4E06658D25EC46E5B38DFDCB9EEC0BBB3DEE2CEC204BBFCF32382C1F4F5A83901FDC8C33CE0E0E94AF6B28C252A57F3160A3F28AFA7D5B0E81E2ED3165C89B98F57B01EBBB79943D568177DB9D5277B3F4A0614BCFD8B464FCBBB228012B9417D0ABBAA6E49FF25B1BADB1350675760F21C17D1842F04B36940D87BE06069C0062EEC8F85A6989FD151431E1D977570E1186ED00198E7C76B26D6E0871BD695C78AE2CF71D322346D51F140719EBE9210C28C76D507530D73B2343EBEB4BEA944EF3BFD48261E739853C16C009FCB89C9507B46C6493B8C1E1408BBDF5C5E582FDDD36EF90463D4B098BA267DDCFC8B734B367A517CA10B57638A91188449668EF135E23BB376BB53662EC04436024A7B83988FC0D3E84F183EA7341F9F29A9533AFEC13D477A82D3CD3E1880E35ADE1ED374A60522F46E99C6851FE93A8A6507792C0B6A7866CD2913863B10A916D7DA42C6076AEA3F8EE7D9E9500BF15D5F49B62C60E26F9F10B79D409D9F0F1AA88973598CA186877B8BE701CA8F1D65A3275C1C6A14D6047569E45DB8837313D65F775B2B85AE34E300AC93820EDAE934043CB6F195B95FEB67EC987AF7C4CF9499017C199457C4B2D6A95283A550D688062477368362E8C1C58413BB957452AB3B87A68B6DBE54BA588903BAA15D75F1CCBA2829664FF61AD8CC3A9C532D9E70F076D417838B817F76979345A8B5988D2B1990A5CCFE31B12C5052AC8C1D7A610458F594D371ADBEFBD485C9305AFFBE9558F08B132F880B5FF151E798106B001725697BCB1123505160728C949A9CB3D0FE34384287A1ABB5E0E924294758DE49879DCAF2FA5B688593959699BFC1C200000000000006131C212731", - "reason": "modify message" - }, - { - "tcId": 23, - "testPassed": false, - "deferred": false, - "message": "BA59DB4AC8D2DCAA1390F6E0501A5C81A68B91B66D1BEF88F09E9111F11733D94C0906A998B88E49AC90E8B3790DCBEC51E3C1CEC5C16AC1037303561B893BFC4470ED1B07AE65685A5777D8DCF3FCF4F5AC9A2D14774939250E58FD21E8A02468C5A67601C099EC11D5460FFB8FD05B71243FBCADA4C1EAE6EEDCA09A763EA0", - "signature": "93A3538393083407CCB6AC0AF86469AA48915CF869B80EAEE9BAB41D5A07DB4A8855FA49E9670AB7A60078E4D4E72018AF92CFCE91F385DC4500AAB15638C9F701200D8E463338FE27AE7CA53FDC65D79123D72696BA0ABF3FB7358E4BCCFA765DCD62D54A7874441D3E0B1B845AC8628B3DEBAE88C6F4D6123E32086BC4AD7DF032C78FD9C68107A73D2000D2614C9A432FCD1885E14BAA467E993DCBCCE5DBD1F478530A0F249FB8BDE339E16DE6BDE7316BE37F6B7534A3FF6EC51E8283191F4A1CE9894604EFBE6CD3C6BDCE7887669D7848DB88764ABB99706E6F2EB01D1326DF02B6772D0A820E1F078F203993FD59B0377EA79B5196EB6C7861090AB44352C86A381B6C36C8F3897613A299ECC87469AEE0FBE450B6C42959ED8A696644B5DE0952EDFC71460EDB241843DC32ABEF308BA3A4D2DA892BED1BBBB00B01C18DCBEC6190EE88C25E4E08E52B400C619F24E341698EDB9D66A77B1211203A79B3B3700B672A469E77417E8A739E0C99E68EB99B2AF05BEC0B8022A051CFC5A3E67BB205CDFCD902E7D2D27F14E625F34EC8254C514C64CFF9EFAA5E009DEB6A4A8AFBA5820CFE4989B54582A6F83B8CEDD782BE8C57E5EEFCB529846F9F6D97ED8873AA0FFDFAC61F22643FAD4F2AB0D9922CB90704B3E473813B6FEBFDF4B915B3E56E1DEF11A64BB2CCCFEFB81DE49E0F93C36FDB576BD24CA7E2349AB3BECAFB0A121952CFAD177EC46C1922EC5E37B7E03885A6086E12B0FC47B174857DEF3D6EE4D7C7CACEAF1694F0AC63CCD1F6D2467AC090D88E43137F6A303A94F3EF941D16CE01DE3C95C9AF1529FD34DF659DB2EE995406910B4FAFC9357223BFDFC4E95B02696C0EBB056FA9994304FBA56BF54ED312F998FCB4B79B5651B25BA993AF01751336AE38A163390F172AD25CC2C448B4582A5365E3023903BA78F97DB6C9F43C006085DE760EDA485BD78564A4C2006C59A8C298532A53E848547A636C602F4F1AD80E21B11040822ED28B007E268516367A9DDB3A0603FBC2184C8E295BC5F59C49ACD72D0A98F909F0523470B6C1E441ED8A9DE09E82B1EFE67095EC81D4A818E4E51EE16737B0D5C6B26A2EC75EB21BDA66C8869E09C3C1516837707B3C2C0220075E6ACB9D172B6D406BDCCBAE3D649DB31C8F30B4D992EA15CF8FBAAE8491CBFE16B94E79FFBBE9C01B075F26581671C9C998058853FA7363C2DEA9B230905C5925A26F3AA67ABCBA1D347CD601C77F03701A35C651967775693B1053C9E15A79BF7E04663F9EE1C935DAB43B46EEA5A33FCB501B4F57765028CFA88FE7B11A104CA98508157403BA8771BDA0E6D89E6C6870471DDAC89A7C0FCBA4E4362A4DCA911DFBBBAA8925798AAEA69B9054A482A0CB0364CE402BBD57A41B248562AC4573C219813341EE3A693ADC4BF5B087713D3DB8C9A0EF8039C7525B2CBE7E602E52FD9004139A36AD1DB24F611E2CB846DCB170566C7F2B3C05BB2C42232B17C9152B087B30BC840D0F9DD55A4B255D1BE4E8D97821D71E5E4A88D2D03C18CEE56A7A89BB3B5F96C17F683E6DDF7C094407712C7D68647DCBCF5FF000D4E4BEF3F13B991DE29E2CA06578E8DAD5E1FA2631BBE7E6CC0704F08E1B48499F647E3573AC54BC93D338B4C282FE13EA7802A582086DBC3790F44429956FDCF342B77C3D7B3E94383F9794FE9DACB4D19AD92C20BE1E4CF23BED7EF067F32370EDE32890019FADC19BB4EDB4D5022004EC16441BDFFE4DB752005E26EF733290BD14ABF168F7709E80F9A3C04151A6A1B19AFECEEEE49DD6C02FB5625A3645548D837C1FE95BB6CD954F57A26846E675A20F0CCA237B373299AF9BC4E387BC7363D7B54839E0F0D57B3D2C3432F4935BF6058BCDA8F045D225284136DE050E80A3E7A75E168DBE5204C3C8B428226F9A901836423717C785BE122F6D4C2AFAC95DE4E3837B25205F75E4B26F87A86E4BDA187BFA19C42299A2A527D9C600EADDFF8101772F05C2DD2BDCCC4CAFD08CC3141963911B6ED617C2D59C9A4CF93884AEEB49C7FE30119516AEA554D592E981B4163E54AF4A7FF32930BE9064F6134DF3B6869123259AB4FA0DE835B1B513C063FE4A2861A9EFB8662404A6C7770B4F2EDB717FF6AC75D67366CEFECD4C3B7356B6B863B0DD2B340D8605230CFC5671EFD4CD3A1DA7A78DFE0F1EC72DCB0846772AE2C7C9BC31C4BB0175EBF5AC5FC2E0CB7EB850BE3541451296AA0BB8EF5B4216CA23180BA2EC15683CC32EAD709CEB3EB1ECC9ADAA936335C4A5FD5BCB62589133C8282E11E774207924E7BFE4A3E668C49B428AA8B5BE652A525994BBBA2591EB05B1987F4F4567B1D56E3B26A03BC3774037C117D01636ED8E49BDEAE1B2882987F08707BCB99BE22A8C4A836119EA0182BABF3D139F60F12B54921A542532508659E71911F4E076DD04FED381E1BA91020E06E220F1E874D49DF7C91DEDA8743DBF1014D11C97AC61BB0A91CEE6959BA1E3EC5985D9C11413044E8F37450327616531F5B5DCC99C3419E0053F51D654BF8144FC2D8C7A31BEE6B92075CCB831CF84B5E883BFB6602673C3FFB2DE342F69FE1AF9965078F3899FCBB57F42FC116849387A7FA24F0929F6C86082624A95AF60C801D766F9957EEE61FC16644D616D4B43AEE84CCA01F9AB32451496EDAF7E7E372442B3981195B846B1D5AA33B799C07759DD285AD425199B4FB6D934EE45BB80D070FC2517E07A29F744E2CA378AECEE110F18F186DE866D76E5C75C016EF6D50A4F97F7A3321ACFB1F9227C50172015C867EB53004F03A7F1384F221EE24624053A485F06D6CC7061313586B1E85DD2CCA13F8F82D71BD949D944C39F9AF03A2C4263D653EB7B1D97ED48A33FCFE5A8162A2049EB921BEEECB505A87688DAC4519B32A2C907103674AF3EF91E3A137E82727D5FD444F85E767B5D98C08D2AA6FCD4E149AC664D53DBD77EF0C774A2CFAB8313C31A31A02D3BC8B4607D5D433EB0CCBB8B6B3486FF7A644235E032F9D7972BD9F2A8EE77A425FDB67E30A6908C1257D87C12B8EBEC3134493DD03BADE1B83CC2C4F82ADB39C002EFA45A67FB6A63D7E132DC278CC4CB51DCC425AA4C7E50CA20F9E89D06B7DF83FB7B0A26E9057E5409522EC0A8BC45E1BEE97E4E2CD27DC26A64B33FADD3BB7B65A24D7FBB3D8DBA0B519E7891F596C6289D34EE3ED72B46108DE4F1B0AE537E7B2178467550207DEE1EF4C7C0434F62B8B215F697EEC9940420FC1F50CFBE18168F36D846D50782670E486C16F4FB8F026BABB37FC1AAAAB6592794233B8AD74A786B6A3639367B480765ED1BA14D219CFD9FE31D66AA27809FFC7976C36CBE88F6AB537C5C347989192DDDBDCE848B465E5C9C3BDDE6A2EFC140C841B50E93421F727085CEBE43F2C13E0DBCCB03262C5F6A6D5F32504CF26582FC936FC610F885D7DFA3EDB7CEAA495142AC58BA127AF96CEADD0184AE269A97D3366612791557084E58304908D0E939198AE87CDC1B45E5796EAB37C537A68B6CCBCC09BD6C0E652FD20633E99B198128C0A8BAE79A4C6D6C96BC3D5ECDE776B3A83E88862E70F975557BD383647E6F531B4789C8D47D0E0E41FF5FE4E40285E0A3FCA6D8501F51D834869ABFBB55956A52E3FD9486B7DB6DBF11D6A1916F09AEA9C8DB59C7E7D6D7FA23E0C250501E6623F0A19529F7207B86285F8FB6861A5E3E2916B9B93962D3D7543B198458B0967D2E50653F99765E885B6FAAC4C0B2AC1371C82460C7CC21E9B855C3FC6729E5FCE14BA7CA093F905510F53D648EF056AFE51AE7D7F9EB3A8DEE1ECEE9846D0E94C1D385CD079D252F8A9547A50B0BCD73C44E9854F24FB9CCE13FC2FE4FE73186C4D8AF0F4C9328EF9F2F517AA31FB0B536E4B61F085FB1411B448176453CFD8F9345E541D69BB248003E01A716FB2C03439CBB4B41DD4064955F2289107DEDDB4AB065702E46928F883CAAC5430A7333F3D20D7CEA9ADFDE9E1505226C7923C45DB48CC7789A3D7DF6D67B85744FBA31A0F215AC354E8B7F9B0D6A7668ED60608537993D42FF354DF4663BA27EEFA28CAD71E8A7667B239192ECABBB79C78B376A46B8A30BA64407DFB58B22B44A5A085E64A07F6C740715D4B4A1DECB57CC4154744AFCAF0D7747AEBAD46DB51F1E85ABF82839E677B2198F99806F2F0192D2A06906310950F6FEEEB8BE92C6883EC716B66C02A894083D0B38CB88A511E35D45E694F7F136591B7E43AA1F091C1F4897C1552D0F6160FEDEA5D913291FD0292F9EF933BA3179AF2E0F50DAF3BBE6FF225DFB4DC256118F4F2AFFEBD346BB6A29A3FCE50752116BB9AD75E9F35AB55E37B3292786324C7BD34408F2BFFAF6E6E985CA044C03B449DCDBF25781BCBC65838631F9A40828FCE87FF64DF81CF26A1DBA89C453A86E507DC27E32FEF9BDD78CEF8ECD6C2D8AFEDFEF10726EEB8D245B338E07D8F148B1B854E07732BA48FC2BB9591788B2A375C20FFC6BA983629620F0779C66483F98523C2CE549A8AC54ACB48C4B4A775143212CDBAA198E9630E0D685981A01B97B63C0BAA0700964B8362F3B59E525661C73024B0299080B454E4F65698C223852C3E9002A2E3E409DA1F8101F3A69838EA727577C8696040B6EA8C7D400000000000000000000000000000000080D151C2127", - "reason": "modify signature" - }, - { - "tcId": 24, - "testPassed": false, - "deferred": false, - "message": "4E86E38D9C01D9DBC6A4E14D6C57076F6804F8102150D6D744D7644E57D8F1FB21FF10280C07C16832BE270CAB2E85FCD01A72B4D949DA5FAFEF955D690B99EDB18D7CF254D889DAB8D259FCAF85C7D935CE5AF1C5A2889DF1650096E2793A8CBAD6917208BACB2B0C385661E6CCC4AF8577D7A39754C443FF84AC1F0395120F", - "signature": "44089B2C3AAD4A6744970DC84374B7A97CCD127A4F7AC00CC3E513FFF8377F457B64F273972E7151506D15B37603922B00D8CE35C5675BA43C70C2856452928BEC1C7CC835188719389F6F3E35C135DE3C4D4786504B45309598409CD5A0107169EDE5FEC7A0439CD3A8AB1F196250483640C4B7963620A67D421A4C9BC8F1F67C5FB36B6B405CDAD5E78320E71951908D0CE9D80055DA4F499C67C531639BDA1535B9D44A450C63430D43139D54A941183CDD49CD608F25E37D018C4A2477B2E977779A1DAB8075A536278855E50BA4A18FDA14D1B8CBFE3D414DBBE42ED79F0EFC393D3ED5964FE6FBF2CEC87BD693A7F986A6983EAE7CC8441E461684BED2D19CAEC6CF65A9BAAADF13934CF02CDEF9FE1CB8EDBF7461692C65BF71421D85813752CAD9281881FEC42D031EB791F2521C234CE082189D1EDF718A9DB28290BF29FBDB6B08B533588E85D9877669FD6364276C0C0AC9373645C6734F77A59BA441D7738AEFF290EAF281D0CC7D6EF5132E0332BA475C7072FA750AB4600AA2F45B00B561AEF2FD145267F6CC53CE3EF1D12991AC16248BFCAE693CAFE1A5E1970806FEC9FC229A652D7150457B058126A39B3CB685FB24A270F52A5BD9BAD7210CF642AEB0276CECE63A099EE768EFAAA29CD8336EFD6B1A18B45BFA07769D6289AC0C0F1BD987C9636B10A72EA145CDBFA13A428EEB7EE04C77EB133C2B3B7DC5F9948D89A8071EDD7177488C0D75D4831D5850C3839D5EE17A7A7DBDD7A4EBD75231EBE52403A65BFAE535D2CE4A2BE9D06C7AE78CE11A2A294FB4664CC9AB62E307167A30CF49AF09817A85C5C302A28604F95BE33EC078A00BF2ED02D1152DD86F90D3AF8B8D795FE70C9D457750392FFBF15E5F5A57D704BE8F1FB7964CE11A4DBC9F9CEDAE2EB3325F6890A684A58D353779A79AF819AB993DBC1A4457D7A9A1CABCC9DE83B12502523CB065AB48D1FF71EA4F7746696A113B3BBFD06BD66B995FE7956BB7E5376C5A8363418498BB4E3D793BDF66F7D2F7D39AB842CFED646D4D93954DA6276490D27B55B57740A65DC88B766C5325DDC81B5C154811978F73F4CD97FB161D1258A4B928A3F62AF8BB47F65A43038C95168331C50987FE6FB4D11E28D93CD36AB5D5096139880B0AB265E65EB5ECBBF5F6D107D18334876EA6785A36FD0D58C2F67B2B2F06409B8E6A5A5BC31C97F071DD0590395069886B7C12B6E7C1E83E34CD7711B2A92D2BA19CE529496E020C50CC76CCA4BB86969D3F9A7DD6724C09DB6186756566F662FB289FEF2C49C731F2FCEE636FC9947D0CDD5B1762BD7DFCBC0E9FA34845B33978514FA11CC64E8E51330D9370636BAB77A0A523A4773717A2D01AD532EFD20C68A98D6BB4627160A7CAF7E5BDEEEF09B77B94CB8ED8BB44BF70EE9210D0C2672192F9582E5D78CDE2FA306F7A05FFD6BC5B8038241105D8F11D033493E6975437DC8790752EC863ADD3150CE0B5560C07E59F4302BACAAED464799962E62F5AE579FD4E2EFBFBC51A8CC547D0F26C392AF44B229E6072C27D789D65C31298DAD6F7619B1A86D5E8A1CAC881B1FC122DA6A520157761D6FD6605C49AC53A09532DCB1C3A02CE1C83DEAEBCBE63DAD9FD84B827F8197911CCE9382D2467BE64E1F36C5A4D5CB93CEF7E43A699255D2F021F9E04944D1FE5CAF43F2ED3F85DD9C03FE48BF483BBF706BC88476299C13565105E019E3785A7BD8C16EB509BEAD5F7F1BE61A3B9D3930DFEF308C881FEA75C4660AEA4B5BF8F518E513A421066276FDD528F1DB56D626562DB5749BACA10413077C2F84F29B1F4D23834FA2E27C3D23395432622AF4DA6B7FCF3A7F582F56B5EE28C15A88487C322B4269A9EBFC75D765DC2829BFCFA598830D55ED591BDE032E66F6579636C1ADC8A28B1FD536B29465AB6384FD04C721988B6EC52D66A28BF694C9F74C5928C2BC7E1C5CBFC74AC3EAB4665DC39A3A2A1AD4FF98045A411811C30D1F372A2C50E288C6546E07C5CA8ABC1513F6232D6F6F2F09E58291F8B8964897D2ECC0B9ABAC89817CE3C18B074D3EFDD14B27FF1D676A6C9FD15D0F03857491DDE74DF20DEE2C6E70C3E7C7B2759158A845D9BD739A797E2AE1A7C57436F77417CBE94C44863629CE521F6A103378E467AF443E0D4FD3C1A3C2A5158F1804AE7F5B31F509AB380E5ED15D646983C92B2FF6001A511942250848AC91EB5C6D988FD1E35C99C4A1EAF69FCE80FBE44B7AE6BA7C4FAA5CE7ED20198D380AD67706268918E94B9CC4CCD12448BAB33C78FDB7A6A43D0B58167FD59DBD2A0F2E0395FA36E1BCD2A2ED329C39EFAF9A2016240BC80E4E2F6A98EC9C7DD07189598EC9A1153798A4F615DE69E57A188464AD363FDCBB1A9C1675FD890F80E53DE8D4A7AB9B486269BA4ED6CA70919FA00A397538DF10D797231ABA2D19FDD5E6F9C642A8A40AB376FFCA700BB86F5114BF8A41C315EC230182FDA1FDA64354E5CFA541A40316570749B6D403EF168FB50E3761A697D50937D777DCFDEC1394BE17A848F9C2D87114134CC299C5414F862DE3649351CC848E09D2C1F49C65CB6E357C2787E36EDE57538428AE13A8F0E6012D885E355A7E310B49688D77CCDDCC5F281C4D702E4F6921E4C8C682223A349AF763A0ADA84CF82B8AA03547D4E4A3F6816EEB6A9D0EA3765DAD7440E21D1E2281F4539AFAEFF46B4A90DC473A903ADC1F791599353294E9C71612540395A53A851FED2E27075BBB7CF9D03EA69F775E6B1D9FEC2FA85D9677D56E8B054B4CBE7C3B4DEF91CC74AF8A1B7D543CD6E94DCEE83732B75177908B7483252374765F8AB2C83DA20DF6C231A2C6625FF210CF2DBAB3DF5E51144F7282A0B3DB1F1601639A30505933C1655685B1EFE3AF7536A2AD76DDFF650BF8F3E02C39E6230E920C8F4E30EFE3C3C5A7515E216AB9A681569910D7D3E047B6890155C88E2F0DE2BDE6F21AA2ED11CD481A865CDA6100144276E648A25215CF491019F2B8F2207801003C2A7D139CE24D1081D1E8636531D2BAD6D98FAF8760610446C379A7F636B188FAE1B92F06A70D4E293484536F10B6609774B0F3F768D00CDD464A5DEC739AD28259C28B3E7DE34D55E31BC734A8F02E40AC404AAD277A3EDB6AE75A43918E10F3139CB03A40A32B52C4BCC5B9891064616C88ABE5EFBD07A87485E81B91AEC8D5406399E819C6D9EFFD9FBA81F6C7209E3EFC7FDC2F5758450EA076B95CC777C3C56B8A7D5303D77A41600376FE003DDB8FF01336AA912B998AA7C1204D861C0ADBD693D891A4F72DC40AFEA71B8384FBB5FACC134AA0DEF3D773C88B42A2729DB00F20EA4D5C3FFB8376DEE9FAF62FE11879E52A2DD1C547224DE8D1D8E0E06BEFF57EA00EE79E7DE50EA2DAF961E9567E41400345DC0CB201ABE605D0DE8B8969174EB469C4D9664AF7705DEAD5C0F22237AF3486634AC83799AC27C8ECCED21B034FE4FE468B0F658A1174856867C8E2D6869A40596F9DF4F5F10E9398FC8EA8FC96589CDC07B8D8906AFF0FEA6EDB959FE7D35F6EB11D5681F6A44538429D69B01C92C1ECDE3287C83C26CEAAE6B8C3C1AF639F8CB89744142B250B790436FA5DFE2A3C5490E51043A8DA334331B9B55726F3468A5AB12170AF783298C7422231DF52CE78BDCDFCE0CE277237677E0F0878BD60AC3C6FB6800533C77265C3F1D061F0CA73C43490E3D12788B859535E489ACEF874C2DC72BF32F14FF0813CFFB22B12C67268A2A949D62C56D05974714416FFE18B654FA2FD033C556270EC7D1F8F7FAA744733D3DACABEA4B7DFFDBECE868EECBD2E97AF552B9FA792BC6165836596AE3A21445056C8B7D5938FFCE31E2B0DD91FD6DD63799FDDDB3C58BC4AE8AF01C0756F050709A3D33C08AC4FEF17B02E29FBA4DA1B777240AB69EF5F79F8E88AC4771D658DD3F8D19FE4C77151C7F4CAC47896812A3C27A0B435F51B4D82C038CF7B9A6BEB2DA3436D5CDBDD3FD5E6C28A1A5C1DF75266BB1C8030FCD233567A3C94EE4844B031E0BE1FA7E61308AF9E251FFB9CD54042C5E189D44421AF87204E740AFC8C7E7BBADC5D966E5CDC96A2B16D4E89ABBCA7BAF8AA0375C15085926188AB47571054577483A10399F9F1819147DCA4680935287CF5FB8A012461F28B93017E71AD35F5716328153A2272CF0162436CE47B96D37901F0CFD835F33AB57E1065D8D23AF79EC096469D0C7D9D7377B57F35D5B05AB518B74DC27754E79213FDA8097F455A1D10A96C4BD0785C8626B77FE3F5817773B0F0C7D68FE7DEF3899CBEA8D1C017591EB8F7BF29A498203124B8BEDA298DC22D9DAC2092EE64077383F3E603D1651F826F6B4E5E38EF01DEFEC91C62EA2752A755B61FF46B0F21A3FFA79AAE80A72A77CB1805A355AFC7541184C4DEDF9B2B27A28CABFD51BA0175B34A9AFDE50D92B032D74A28B810782DEEEBEBAA9F61BABF76703EE34590B9F816659D05D30B5FD204B0609FB82C7D9C8C0B71218E7F62EB4202AAD7945DF4FDD156C9F3E92142125F9054644BEC0DFF1570A632098C9A1281E8C929EC72824B7EA0F0EF034AEF048BA47484119A54D069139A812353C434859B5D25B6C9BBA014675BEBFD1D2DF172226294E85888FD9DDFD115D7B7E81B8BC0D16586B6CBBC900000000000000000000080C141F262C", - "reason": "too many hints" - }, - { - "tcId": 25, - "testPassed": true, - "deferred": false, - "message": "62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227", - "signature": "9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25", - "reason": "no modification" - }, - { - "tcId": 26, - "testPassed": false, - "deferred": false, - "message": "A03A6A2260AC6640CF95C0735AB67D18EA114C8552D2F7280E61EE1073152FE4A0E28094D29BD1EC79B28398D10A9AEFC2C55125C994D821CF3DBD3199DFF2522E927EF4A540DD3B36161A2BF3C665CC9387F066675E761ED626D4B0D6080293DE775F36D72D76B22BB98340B3AF47A3EE94399C73D0C98EC955221BF209F4BA", - "signature": "AB5E7394A0BDCA1DAE69C30E1CF49FB4FC57DCBEF58858F81BFD72B52BD9617F71AC525BF2E6327F551EC3208DF67D0FAF5633C42E45F01BFC23BEB54980EA8FA1C8ECC4F3C71239FFF932D4AAA763199CFD07B7CD8760BEFCF09DC593272979A2BA0760B85D36CA151EF200BE3C87EAB2AB3B00DE6310F6AE8BB6E6BAB0639AA65E06CC88ACB84E48E5823BC41E581DD199B2FFCD04ECFFCADF37FB5AAA68C4FB4C4512DC1CCC1AEFAEB1A36C156567F5291E49012E4D09BF17852EF5A0DFC3F9F7C7269E8C034CC0CBC28A8E4DA941F01E0A40A7ECCF0FB4D727875923BAA510F5BA2BBEE1AAD6432478B488CBA8C7A779E5F10331542FFADF4AAC397015E8F8B24050EBB415DDF9E5A3E03D0895567AA7F359D8E18CC68EA24EB43B98FAE321B5CCCE983A1E4D1B86F99EDE4485FD745F10E11A647EA1BE115103B4648C91437B5E55121220FC9345B2C9F6319C472158E021E90E329C838B400F7ACED72CE3909BE9C56788EAC3CBFBCAA6851A6A8BA477636F830BADC2F68068FB62C58ED1A935D7428A92B0F04570C56A019CDD31ED67067EC64CDE1E1C5ED6B997AD51702806DB0F0D15E335D8411204FC44912871529E20056824B07BD2EDB6A21469FEA577D95C777A14102ECCFEEB895101C094700CE2EDE19B2DBC0B9243A01BBB1DE7C00453FB2363A17A383A327A6AE2A0104FB86DF2EA59C403BE4A88F6D6A6DEEA284A54DC3AEFCF49B448BAE1AF32360E01F6BA07B2180C933F0F9006F77F2842AF5C1BF2D18A405762DB1062F07A7090E3F2B664A1B4E8D2DA0864F7F187877B4CBB4E68338B67CCE16D3772EE9A13AF2C4FFC3BC30BB11C7B4269071AE96E7A83D11A87438D3D2668DE92E71BDC875DB484BAC68BFF9831D9A3C60660C3931B4107B4B7C99AE846B9E07C54D57C6F75D9292A8C9CCA3D58852EF86675F92E76896496031B2426EB244FBEEB55B05E913AB9B7375981033696780E475D0EA327A89B2CFFA64F5E85CC492C2163396DE4DF698659BF92BBE304667C95F95621AA46B4DBA9D60DB9133B0D461C73223A417DAEF23293E106F8703BFCE01DC9924437B043E937C067989804FF2D2E3386EA4D5C3FF244261203246F3E72B7F23CCE42D66B3BE2A0F950E8EFAC78954A0EA7A47D87E51F52B5E7A8DD0F342DF5EA40B3B574B973DAC7B3BDD4F4D5DD688798275AFC5FC92E1AFFFB789A68D42EF1632EBDAB5A88FBAAE6ECA47966871283B904C4E28DB8B4D51690D0FF4AA5E5F3A99F07C1CC9AA7D634036F396BDBAAA11C7390EEC95545C831CC7084C84E5397FBE980E7B7398ECCED80661F3B9D103E607058D7DBDD1AFA1E23473347BB8983D6AA634FE946930EF6483D89D51F64ACF4DFDFB74B41AEE1A38479916990E8895439B95C257EA7F0B53B5385BC113CC169FB805D61F0222DA04C9EDBAA46D7D0C80EEE91C58019C63984FAA0DF17B946449B8A146F0709AD25CF4D8E1EEABB5F614050DAEA191D7CF57B5743336F90BC9B09F39CDD7C1E5A5F2B897D6329C5680025305C50402992940796A5E5A5B32017B14D80053489755AC2F992055D7BE886E68C6EEAF07D54E326BB6267BE0F7B5E797BDBAE654800595D2D6602AEF13346A834E33A0F594C51100DA306CDBF0C8DF9D0FB0A304D8B4E3545908712B84CC7A1326EB51415583C5091242B7E8B3F71185523C637B8530B704EE79F1230D6B0FD5FF4328F74444A17ADD464510C09DCBDCFAA3A4AAC9B24E8B5F14D4E57D64B877AFF1506276BB835BD66DA230C40582E6DC4C99C32A1BA63D263999253E456D1B88028A2DC08E92F82BD5DD639525524761ABD0C9923C825599D3BF012156AE6C6377039201DA90EE5B6A74056D32B683CD97D4346D60E66673B794A724F66302507544DE37A76DFD88561A9FE5A9AE61A80EEF73B641FFFF4D76ABA97166CAB36A4FAF705F4A9C4C27CBA3DF9B63CB1B4BED874D281E78FAED9031B53600805274443286F702C7DD39F2E11F86D4F58AF9E5E9A04C4DB19CD97F05FE5DFCAEBEB863759CDC4BF74A85C1A1B552943BC1F59B63A2BBA9D707CFF9790FD47A2D2F484FC438C51D1832B96D90765929E3C40E83CC64F7979F13C530A49891E2F64944C33A3EFC95DC99808968B3CE2AAFC11C007AB4196F04EF65430DDF2D0CD38C81E447EA3E16F35D1BA279D8DDD191F21F2AD3A3CAA9A11E44158FE703183E46B48BF22A70B1ABC607C5C8E22F4EB45167EB87BB56E2F4E091C3F5DD98A7F190009218961F82F830025E217B47CF75E5C71AA0FA8F33A7F9B49C7FE4CFD4D318A9EF7C02ED51F6DF5568F4DE182DA87344FBFD66450C9628501CDB19A86D8E311F625F70D7022CFA950A53FF47B6DA118D32908CD1B9DD6010534B6D9BE0D9382C6221F706053FE232C42A97A32984ACBE1F78571454766BB596B13E71D763D5FD44B80418AC43EBFC160E5C31554AA2C710984531259751ABADA4D7F3810D03BAAF95596DAE4D1A930B5BBE89688EE4B80638D82BDF536E52F3437FE94185264850ABC4C908C58E35D8959C9D0B5BC531BA8637668E4BAAA3ED432A12098D9C076CD1D4359E2508FED7C90F6B5931598ADF772301BA27AD7F4DA681328E39785B0CCDAAC3B23B94E0EDC6FBEAC9D9CF31A573D972C1B7813547C388F17E9003D11B66A873CB19631F59E6E4C24E89DCFDB477015FD5ABB50AAFEBE00B93C835BF89FDBEFB32F673B7FBBBD2969FDFE4EAEAB872B470BDCFABAB1638B8281CCFBA0464FBB431EFE358B3611E6EA2224DCCE734EF9644E0CADFDE0AEAE01EC30F320E5BC6BCA88B2D2EFD7CB32173E2E9EE1CD288479B24820B0327414C4BAC9107C5D86E3CB1C313658E4EFF0C3A5851A7FE9A03B9DF2096C77C768C29221647C02F2760BCF9E361E1350B0E2FB7AD94A1DDE61F93249F7C7CB12C0EEDD7510E34C4C991364685E2A76FC8E4E94EBB25C4DFC07DF48936B52BAF32CBA17D3CBEC7270A3857376DBC14F6EED0A8ABB8E9B1DD2C3890B1B954C2CA7845269CC5E9A3C42B7FF2104D5CC87E89C35881A7556596848A57E5A76E15ECA79FE31090B97DCE0BB6DA4470168B5EFC8E6F906B4D67DF3523EF0775E5B3CE947D7ECC79B7BD43FFB68EED3FF15693FAFC17A3E48E232508CC12314D72EA3310EEFB4C3A21D908BF0817BD09D7436B05EF2960FD64C81A779368150B4DB9B60D0D02EBD4BB01B7AA065F55006D2B67754A3F5E5A67712E7445817AB96D50701B42CE370EEF826899D6B8BEF0ED0F26553EC03CB8C6B9657FAA30B2AC670B03C3BA9ABE791118E93CE084A669A899152A267C373978FAE2E95BC96034A4CC6F47E8D2C6E3F5E8A09800B581F5DBBC57DF6C1ECE709D159FB1B8C6D588E8CB7F09DD03989BFDC6CC04942AB0AA3AC2D22BDA3933EA04A311D39C7E752788BB073E4C4E82F38BFA7DFD809CD62200AB04BC235530EB26D9335F23A39496B34CBA96D54D485CDA83FA98CF1D2532A29E97CE8ECD123B4C601D1C313F0E62931FA15A003DBB8197209993991E869D0C19D278EFFF92BEF16E1E29876DD54450851D43ABCD8BD5CB96CCFECCF361016E4DD9D00C893C982E95733549758C106A4A71C41213AE35C7E06DBD7B8326B1C1927D2D310219CF847D527F2EDB0326CE9C62B1230226F12215710CF311563B2F5357A935A5CFFB9FDD4BB046C60677EFB7D8C71C5E8B00E8808556AB9D7CAB0E56CF37D5D0D257CA124BA9DDF50DBAB9CC2245C4CF50D29A644670D2C80BC0F1BEB2660BF579179879BC3CDC3491C215A230ED7F20440C7D1FC701EC26FCF57034AE1011AE2637BB94470C2C47A675493A26D9DCA74342C006E26C83C4A3BB3DA4D5CB4D5CCBB4C1464C906C053752F3E297F71E5E90D7032B1BC83A274C1A2E261EDCEAD6EE493F920139275D9B03D9B189341D0846A415720C1D5A033B0FEC98BEE8B21397EFEC13FB39D49717530B179E9CC6A5CF0721C3F3DE79D8B5F30B124A391B1A985B1E5E5A62C57887E63D7209139A566F5D7817FA4251D579AB5F525EA21D54230C3EDBD914A6E4B4B6EF870B016D966746BB3475FD98A5185570FFBAFFE7BFA696B86540D03DE2DEC443BFE6F287B75B04502D260535D99E826E735C097AF30654E38B64399F2066E62C9D24DAD37361D3F7C9CEC99CE170418102AEFEE3B091423D497A71E899F147DED7B676C374EA71EE2565BAFDBA9EE69584ABCDF6728A44B999B924ABD3B25CEB8232724E1A744F57C1DABCEFCB6C7B9B6BEFF38E3ACE5E4529BB527AE7DE7B0F00C4C0F94FA58359A588CC23E78125D2A51AE14436E32893DAFE64BE3F5B45EC34C1368ACD588AAE845A1C76C486CA333ADF09459783BCFA29A96EEE2897DCE01607F807D076EA7CD50C37BA90ED8CA558663E2A701F3D31C6A118083D4D8931381647E03358B7BE9789EA904DAC783BA876B92FC55B1A846AF74E4793B9CB6DD6825E06E0558093394F39927B7F1C1458A7808EF2328FA60D0161D2A64946BD57825FC4F451B5CEB71D13FB85328BE1526D1AB8A8C137C585AF7541F32F3A03ED92134537B8B008A73B6E4DEC8C17879EC6240537F87BFC3E6E701345D9CA3D4182C31749DADB2DF0D122B505F6072939FA7070B6ED8E543536D71899FA5B3B90000000000000000000000060C141E232D", - "reason": "too many hints" - }, - { - "tcId": 27, - "testPassed": false, - "deferred": false, - "message": "EAAB79BE1079071DC26001DB743D1F5C085DAB69967A4E693D8EDA97594FB4C7855F9C89CBA95D0BB6BC2B36E030336D4F025F9747487E863445686D84BDDAED97E10CA8AA6E5E67F4F3B2150083AEA5FC5E55333C4BA9910747F72A1151FE68D22BBA8FD630CBA4359BE2F0DA86CD2C6F79BF8326AC195171E2D876139303D6", - "signature": "772E55BD1F938E1DC74DB2D4A126E060650FF9ABEE2C8EB5F02E0E190DA1609AB6AA3476F9550774D5F8667083AFC49A9C1E05F2D7487C23D25C67C55D3BDEE6C78AA56D9E0087FAAC929581B87D08BF0C89C77AADCC99AC150947459D93101B2593B8B9C92F33699DAD8B0EAD27C248149E7A439EA425FB8DB40CB7036C3EE3970D1903F0B88C4EA0954AB78D4D60A04AB6036A7B56FC5400E5FA00E8842CBDA39566A43533EF7FA217ECD12A912FC8FD55B3088E504A3B777DFF32963628AA345C16ABC566C280F788FCBCAFA568224508F4006D92E1423E0C7CAF31B9AF979462DE827DFF858FF8E0D850A69727E7C68CF0644B56E1E5DB072476F9400147CE4AE8D87B8A2ADCB2A7C0520AEE4B89559F8474FF5D02BFCA275F1915761F4223A7D88A9FF05D0F32EBB1B0D1A7C60A7D9BF7A39F4AC73D3E941E29BC0BCE4C7C04805DCA40E568823A0239509075AD0E1F11F7A6D9337DC3345FBE8B4739D0A421202035BAB8DE52915E173A74EB1DCE176BEDC5792F9C9D65970A811B3BBDC10C2069D71D1F00BAF6C0A3906CF46C99B42D66DBAAB45F8DDBD582E31B0FB09919BE9B10E4CC90DA9BD32C1B87D03AF2478B82966BBB5F2CF5D0BCA4EE3C91A2375340AEC44B6E8DF29E7BF87723478A086601D477FA274C1483E348FAB9649C842ECBC062AFF4DAD85E07820B097D7B90AA1726B516778F5E3AA9A23624B0F217A9E92C4578172F97852207A1C89D57D7473E8CDC5C7A922BD305236F92FF20A7575319FE2FCB4E953951A5AFC25CFC6D5A54071BE9358F4F4B80B4D91145E33E88C9E2F6C421D298AA49779A4FD5A7A565269FCA1D068B708EA4F1D9BD55AC06844FAD15472DF6BE71910AAC27AAFB78C6227C84755AC1B99011B3BC85E12E92D2C5BD83311DC28F1B3554C669A5688F8FBCB996800365F009E676AF23BE2D2AB3E5A5CB5999310A151207EAE2AD15709D88F4DF84969FD2308A26B5DD15D3ADEF04567BABEAC298DD2ACAA5B58B44D592B87B6D32E55700EA77CFC5CBCAC319DF13D7DF6AAD2207D34231F1D3FCE1CDB3889CC8585BC13884ADE337E81B4E7F85DF36F48B5BCF405F62906944C77746B5F03D94524BAF5217CD4A0E553CA10CA15B90CB9366829F9079D2B4F35E0C47520EFEC8A04B72AFD350CD218C0D60AFAB37A9D52A020B84E2801F298F6BBB2261C14298E8BC22A4BAB82A725B9A5A34759BD7567BEEDAF966A241A9B6407DE844F72FA337C6F2792AB5F054FCC832D3826B89C1E93F32BC6D7B70D505F646B94780B2414B7EB4590754F13492AC09CD805AD88D8D5BD41C6E53BBF42F01F7DC2849280E840E20DEB7C8EB8D8DCB738784DFA6D80EFCCF7A6CDF03251723F3713F65EA378106FDFC7871931DAFBABD6916F6C43D24692D684C4B564844EDAED0F268E93ECE36CB9B6F4DF8B33D5044471EA9F3BE8298DC87FEBAAA9612829A2E188CFCEC1090BD1E84C39B71C72F7F650A4BFB4DF9A1F6B830233AFBD7D244993A57876559533A695F162C577455326497AE0319C96A34E7FAB0F6BB1CA56484B4E6CE3394D2F0D7C646C8C82A1B406C4E532486E6F10E35956FFF230AA48CD993E7EE01E1C1A4F84ECBCD6AD1F24F1A77B47981B7CDC8BF5450FF61A12B33A4FAC8BD98609805CB290B955812646357BD3803643400C252D2C9746E05DC6EA178D0AE1042C70C75BA26C28B84A2AE0B3321A45ADB6CA5B6750A7B5B58A57E8AAB749DD89EC0EB40375059158357ABC89E023E47569B37DF9A5AA8BF46FE06725995BDBC58E9E910C3F41409AF9C84A1C3DAAF0A02DC2DE0F844615EDCA580BE56C5A064D586C5070095104C32120AFD6943EDE8CC7D6FC7769C340EC5F32FD471242C964924AF0180E978F76295412D68C4D9DC1A3623B96658D5A04CB55C5855326137D9FAED00B661B5361F7B3DE3B5B17B8DBDF3A7BCF41DB9E880FC2DEB7F108A66DA4AD99C1376C0A7469B184B979FECE3C4B0E84252D19333661E1BC86F853ED4744D0FB6370AEB83A668188D089CC1E56F9ABF6C8962BBBCC7E3DFEA216075230E34A09E9E9B9DBADE6CA87818D37F44372E8EBC717F09BCE684CF44002B4FDF9AB9FACC5A6B510241B1FC89789155771E0199179532985F2AB2E5A25BB83471174B8B018FA438FFCB7B342BFE8269BC87BCFEB8B5C93A34384783ECB8B3E65DFDF5F221B506662C162ECED16879E5E71A88DCF34EB7265174397A95292390CF0AFCB090F6A44993F74700708A8291784FCF280E24DAB5CD8558A0B030F76AE6723C6B97A8EAFCDF1C94AF0A97B0059E8CC4CADB725D7CA274C3660C29CD37DE55098359B1615CB73DB1A9FE1ACA4D3C38CBA8D9FCF2568B073EEE016CD6A96768DE41D8F2CED20F414019E40EFB7DB7890C0AE3F0CABC9F083973F560A2593B0C671A67A52EBB3BA1D4A1B38CFD77E9A83FE89CDA9DD417784950B75CC48CDA6575BF9D2B795F9298E50CDCC7CF6D0A1C7E8C58D2A19BA30E99004D4B78FF807A9223B971F4104664D9E035A0C7EB0F05EC3E39FA91204B71362BFF16EED4794A09FA87614613153AE2B190DAD3B732BCB4DD0634184E96F1915EE499913B839F7D802663A02B65122C7EFC566FF8F1477D5FA09DD595547011D7441169B194A16AA4C7BFC7258AA39EFF878E88BFA47102275298C6023B3613DFAD69B384B01803768905C162A6F1B632540BCD3751349F357037E97C8F8DA5B9E2734DDAD13D1C1C438C1C5B53DF5C348B8F13EA5E13385E93AE453C22A105EE64F95D7302F870B1C31DEE5620BCC29839016C5E993293EDA36F85A4834678A4877A45BC857E864979062D860F3146154DC592EDA611A9705021A6AD5A219C222D09182F412D8AE27A4A14FD5DF4F22F887254F8540E14E7772B634A9B1DADA498C5CC86BEECF360077FCEF43B624B26062931EB42CDFDE282C0A77117A51E3390FC0B710C2C98DC6C525E690998EDF2AF5756E019592DF54BC610441CBB4B941C0F1922385DD29DB0D5B3E58FD0527759006CEF36ECA0A40325E2B8EEDEA7CDAE059A53F95420DD719BEE493011170188C5B10D882641AABA98F9D475D4E90876DEA7CB1A9CF36A0BD37294CDD2142607A7C940B9EB5C61E7D1132BB55DD7FA3EE35ECDDD26ECEE9D2B0E8D474AC4788A3AC4B888663039F2854B63273C3EE4B0D0BA402DD91AB5A88684EC93352A4C52C61A30335449E03DAFDBCBC25F1368EA0462023417CB26B5809B6D797087D92FE25047871FE11771CEEA1DF59665DF7FCD33329C6317323D84F05EF72684073C37CDA092B60B9F51EC74690497DBB9BC6FCB9138ADDB3C3E2776001210C45962CE8DE95110C5E194A4D5BDE6EB1E37C678C0561D331D84241D2E697D0A860B589F586E9E8D8DDD4873E11E147947DC430AF3382356DDD83E02D2EFEEBFCD191483232ABE60821FCA0BFFF456F2DFC5A147B98F9FB6D0211ED978FEBDD603E06D4E45CC150962EB8C740FDB3706EE4BB5A5B26EA854BC059CACCC0EA418BC8BF32A6989477610889A4DCA186417549DCB83991CB1C15709B9CC9B6FA6444FAA694DFE607256A9577ADD098EBF167B1F23C70124E4C2E99082C876994BEB57084DC6A31C3AD23D220DCE10A4BC18385301430CB1EA2BB0C73F775E4EC21C849F98402A3CA065E57E2BBFE93D8D0B019D889AAC393A2431F6BF29AB55FADD47323E534CA3E22AFC2CDE990269C8F5169AF0FDA26634A0C164588F2F34B11991AD52FA94449D15787DC8D841D474706DDCFD740F9A45BB14E877D30A310C364D21F65BE4CB2DBA391410EFF55583A05CB6B015F51FAB6CCE2705C4AA342994475AE3E47C72F113A96175191271ADB4927F8CD2862424D17FA66A089EAD6933CD50DAB62FBA2B24B3F08F9CEB08342DF8479330DF1CCC65DCE00A50F1FA53CF86AB22A8D598F66C460CA1AA1A67C47119358EA36065E08A96B7B399053D09801FBA56350BBAC23E606CB1F03A5BACE7D3FFBF3597402A6F4B39D75BD881393C7B486F01CEECE4060D5DBDBEA8987D508CF9172341237040359E4F4314313E1F158C105F2DE9B1E8070DDEAC3A89474EB227188828BDFB323C3A1162C2FE2FE2E5EDDADD653E9218FE8F16DF41630C327B7A5AFFD0F31552144A9A348256A10110951F489EACFAAD087D12699A26621FB883AB7807184F2C8EF84DDD6C262CE2DB192B2751E54D070AC79933E65958DAC87AD3592BC3EC1B3B8C72649E19A026FF7B2BB7EB2D7847E0EF58AA38FD2A9EF2A24C8F01F74010DD5B15DC47243309F32E47268F94D8213931B16E639B71D125E069C295216622AD548A47B6527199109B243355D1E0506E8C76627F92CC170D70EAC2F13061D7A7325F2C03A83815235B89E2B896D1ABBEBB715FA68FC3B5E4DF3354BD7AE37377E57C07FDF091E2053D65E7160D70DAE06CAAE7172C8C2E0F5A0383377A0B4FD83BDF4447FDFD418F79800D8E554B7E564F04D0CC0BA443055AE7B34D3212BF56CDE38496E1647E61AF07B40082AA9DB16DC041E2DF4E94E762C20D8BE0320611793663DBEC3350EEDAF9B2E7AFA46DB0D4DFB6556ECEC2CF0814D3E00C4B578A90A1E1EF4A539CE85C9294A2C1C3DBEC232A4446A1BDF8043A6CD1D3D7DD0000000000000000000000000000000000040C10181F26", - "reason": "modify signature" - }, - { - "tcId": 28, - "testPassed": false, - "deferred": false, - "message": "07F9CCC3426B0CE4C1D28DA2314BFF42BCE5EB0326161797C40BE656BDAD88D5996E1B6EDBC82ACF96AFC7C86E6AA90278754B038A8B072367A78C6C3BA394899AFC0CDA4D78B707E9758F2D397F3F507822F9523623D1A64968E693D0134525DD0147ADBB222471C781265B31508C4E3B5C8080C8728AE2A9C7FC72E97F8910", - "signature": "6F33B6CD8314F3735E912010847923B7618DB9EAEB0161F4070AB7D76DBD7084E7FF1BB01333E80BEF830D3F06262EB9A70A73AF73552DD901138A4CC4C30153C95F62CB4A33B14196DBBCC551B5B3D0A7C052D9251D5C260CBF683049766899455111E51F1EBA80D0F4B46A4A2E95A47C2326E837CA160084B80781A325FC0C7511BA80487A31D07E697E4328ED4630C4E4D9B3547DBEB8B9037D4DD0AFABB8135C1983CC92C356FB02F93DB17D42A042D5A82047B67B26DB54BDDC9E6A42C2F4B4CF6A79AD6F294E0763111FEBACED66745D3D8E3EBBFAF934F6CB4A1141A2380CFFD99E9EFD97D8548424FFCCE6A6C3C73A931DE473630FE364D0CAE7C40570486046A715296ED95543F65F7086D1EE3753381CFB1EDBD6EF38A3BD3B982A64235CA1FB8B714A4E75D848EAAA3489DAA6DAFB896936C38FC4734ABAB020FE98BF189A15ADC08E1806F5B36F768D76D9101BB326F76A385F40CDAD629AABE51BA3D44C1BF526B0B149481ABC5E36310BD45BC2C6CC150F1ADCAC721B9A88421B76E592D961AD1A2E101A675266D5CACC1B5BB7746F02A3E2EE93F34750594C288ED3C09C6345C1C25B90FFBDEF95B2DCBBC2239BE3E522589E2712030675D98C76BDC0B86335F06037E90C7BF706B65888C135E48D17F5C0653DBD7BA8C25F8BAFE761F08637ADE2E6B52D4084A7BA6ECBD3A243BF5B92C7113B10EE46B631BC92088A93FC1875A24D1DBCEF1320F037617005EBA9421E104E4D4036CA085DC50654CE458ABE7C0FF8B830FBF77501502A49D65385D447E00829EE9C28FD94ABA580DBCCE095C6A3402AFFDF22E4AD23519626014A47B66AEC54AF3A41BECA3C276D06BA999BA7E5BA31748AB274BAA1F137C9C2EB61DE3BF4490D9EBA754CFA68400B168288470C46F2653CD9F12B8538AD3B1AF5B912E90BACC76D55D089B9A844BAD581B50ED11AAE6FE522ACAF9DBF1D6B379A7A1489401F01E0D2DAA4233136CDDB30D8E9789A528372D21D2385DB873E355998BC78AAB08D8BD0100C4A0B76FB90E1F55F44B6811CFE6B35FA3329FA130F775257C97806D79D395560F3999E42F3850D8E5116A01C802285ED4BBD091A5699A2C63A27B372133F5F75980CD5FBEE1DB513B2CF9A4DDF6ED2B1F7F198C87B61DA236B77A2DF6E9385D1F3D2175140D1E0C126CFD932B987A9BBCA2F4D151C93F8F355333B3B4D830281A7C10572C4D64C9D2B1FD587036FEE580E5319B58CB9D918925AB3256F19C6D41CC2D1790687F42B22A910F2F7E914AB826C489F41C85683ABE8DA220E7535F636DEB2D578E81689F4BDF9726CA78D3F9EC367E67848ED3D3AA82C09F2A9E01B78B4CEC6A02E591A41C3519E2489B9CB854D71305C2F9FA4C3602415CF0DFC1193485CF8A2F6501A7EF50BFF5EA3213C45606257E26EAFB7E424A7A8E22E99F58511C568571E56C3CB30253906B3A0FBB6E23D1A23B28540A13F5C0A55D97C8DEBC275D7EA127C4946A3ACF41C14BBC48E9D93A616671206D4FF6ACE1087855095FD5799078D9EB31E77E2AC9FDED6B2DB8B691476A80414228E45274508BD0B8C4B020C73C832CC08E2F641B23D805EFCF894ED099FB67A31CB4DB809BBAF71B1E1085667353D4A45D422ACF3F7CD126603CC657FF6B381A1F5768981641A4450335748476EA00C0E37EC411F9229B2424DBFFE24A5DAD587FB496B85EAE53282265BEAC8E031EA966857FE00C46917DAFC4F5E9B440A371C33ED31B940C74939BC92AB425873C64B4C7AC597D27A1F891D1288F839FCAD64CA9FB5A41795C7B9B495CBE1A9398AE9D18A25685ECE4BB7CD63EC00B8929480CE0FD2ABEC9DABD5EA6AB30961F0C4808D5A4EF33B8AD395B8DC4CB057341D5CA89CA90F75CFF7771714130A661F6150877C79D521D145A8934724C387EDA2E91FF4F420016794DC6A477D28DFEA5EDE130A5DF51F96DEF285564BCEE0B577CA3516B0357D6605760439C7737497D9FBCF5916EE558E2AD88C7420D4BDD6AF34B677ECF51440036217227E3C80F015C20FD0869030F4E5B8B117FC520D4E508BDC007F67039B28583336DABA25ADA73D053115910C6B28A77B6DC72D3C627868BC5E05114BA0D67EB622D232E80CF485DC236E9BD3B88218F09F852EFEC1391E42B3F21A42992D3007390D78FE161F784700C31E99C747BAFC93C95120B5B542B41DB2080DC608C22E975EF2CCB0681E2C170B297A6F45354E7E2992C67AB8F2A3B7537F902BB35048C199A147E8C6D697FA08EC3A8B3EFDB6573C82059281D5BE8108BA99E09AD6139CF0A5241CC364C7E2316C983BA751EBC26183A8E9C6E74CAD33689D3CDE4B74EAC6B566FAAB81F6C888DF9C30098C5A7538D80EB3CEB86EE6B8C75C62FCEFC4CF913A63888C1A33FA5B862B59541FAC78E0423DE95C2277A17D5A7F1C60B52A21FD6D42E1DAB770446DFDFEF9C5AC796921276FE1189BD38C40B713BA0813765DF17110E6EC0A9532D8625132090D15BAC647E16F99E9A096F8EE307793AF2422D1DB178F618B60D5F71C82B7D667AA4E45BB2775F72C72D95360FA269F374F140D116A110598CCDD0CDFD5ABD067E7CD1C8C335650F96F235115586E16805B442AE0C592CFE4ECA870E8AC0122F4D433AA3DD66CD7348D925B209670931CC4D9ABF11DAD7BF711072CC5FE786B24673A056645B4478A6C7BAC1B87AAC4A83EBC78252362E7D703760CBC6836011B01723519344337A0548F058D72601BCF8256AB246823EC2157251180B28C4A86FB401EE3F68B9F63B4808EA5902D1C4FD86A0B06A718DE7E4501F989D32E58EBA01CFB40FE0F9B5A2D47CD6FBF802E83230DCD51AD89707BC0EF7EBAA171D0BD7C328AECFAC246B5D5796BF0E54B33F42BB1C76D585CA3A1EBE7DF9075AB0BF4701A3147AC73630ABD35FF113F3A3505CCFA799C02DE5DB1EFB35D985E70FAB2C1755CBAEC01E95B34E52439DFD7EBA30BC80D6222ACFFCC962A7010290BE5D7BD84C84BFBD9A166D7209AD9B187125E7439BDBB1D2BE4669B35E26A165A15F6D6D86B6FE75C7FFDD854F19E6C06978499E4D3C807849C5A55744BAB74F0B69DA7DFC7824124D2DD73C34F670943771A9022557C1CD7D96122C67DCF8C05AABD76FE45A89E1D4A820ACBE587233551AA615B0573DEBBC1B8FD09662DF7B3F26D1FA77367A6991F186F1AFC079BCFA8E36708CB26DC9BD487A82A1E4404DC71DA72D63FE8170E9CDFE02AD400B2B54DB2C9D8687F51857AF1C04FEB4119947212A3571F54423AC0265F5D06ACF77AC5550D53A1589F5D8F17CE5EAB25C6DD3048E3BF24E04F8E55F35663FF00EFA65DA4C9D8788AD7AD29DFD776A72E5C9202C08CCE2A922B9BCE81B7B7E047C199DC4D3CC66C993C405B6CCE80B206E2B419A89BC36518FDD0D3F902EB6E6E2E948C182A0E2BA1A6F466C95D48F87772B79BE348E12CB38FE5C4184B5D23CDF87EF6FDA9FC674B890629861245AD9F401C42A2BD69A4CC8D133A952A960DE206AC95E44306A9817AA5C63D69ECF47ADBC6DEBA3BC504FC5029B2EA0FD71E6BF3997BDB9A45A2477683EE5B8BDDEF8BBE61CF90E9FA426DF70603C381A64495776214FC7F89E42627C7065F7CA096F91AA357FA3565706D5D108EA1D4323D0A10DB99CF48E374B54D8726DA7C25F09ED9322B63410D3F017B4F6DE87BD442B339F50813942039876AE0FBA196846B66FE453405C449AF7EC09AE1B31B5695B00D7BA81524AA1EFA1140283E3A8140575C33B0C6C679E8F6AC6C8BB09E066AC3A39D732EC29209C96388A6E05380EEC6F9B957D6613A979EECBD8D41CE7A075D66A44A212C9335771F9902682887ACBBA4020752B250ABBB886C7B0BC50B8C659E4BF89CEEBEECA053E52288BCD4E5536ACB969CBB61ABCDC00E4F575D5B1084C6EA4321BDE61AA728F03AD072A678FDF203386ED0828F1883A96DFF45B15F81A50408A5E54393DC1757DF3FD304E9AA212287BBCEF5C92587989AB4A699D2AD3EED036D4D5FA575D183DB87E094B8F066F125FB97A27783C96AA9B8628E491363BE4369607CFDD81F4F6137EE707325C4420F3DB2B5ED0883DBF9FBF86871F6EECEE49FA91B0972A9694D0DD6BE797F6CE18E2F6A135F82EA01ED3F269C46C659B0A30E9A7919309AB224C2E8D96AE5B1135EF962BD9A22BB68F9B8479719EE5B22961673F5EA324FA6FAA011836ED1AD1C0BBD9378C82C8A20EAB448169557ED4044833B2B284F62E34BD3A6DFE3730A6D4C73ADCCE24B0599E730019D71EFC032F849F0044C19FAB0B37C4152CB518C532F78DF6CB6DF2EAEA603226210FC42B19EE66B8AB2EE61DB703403DE2696E0A90CD0B3EAE8D610EF52C761A91CE16AF4A6507E04820CBC7A83C679F674979232BA01A581001DC0211D37599E83D2081A2FB0926A0FB033351EBAA3C80DC1747630B918F004A5C8D4E68CD0AFFEB74695EF100A19637717353C586595FED8C348143EDCB834B54EDB40B0E87BDAD3497AB4011FD48D6CBD6E0A04D9B79F981ADE3340E1A3A45EDDEDC0ECE121767F52D1A28C06973C8D9800774C23FB32F9884E38262C376688BABFCFFF61790F164E75F0344E768592FA476B7FA7D5EBFC1C222F337B85B9FF000000000000000000000000000000000000090B10161D25", - "reason": "z too large" - }, - { - "tcId": 29, - "testPassed": false, - "deferred": false, - "message": "0579CDC4FE55C4160377BCB12B67BEAB78BAB125F9BA892479066031413A63BF60E31ABF90D9DD845FCF8F6F9CE1964B67DD8A92877A7320385D9DDBD923E592E75993C1B32588034D399F6CDBC28217E2395526CD4A18F4A5CEE419DC2ABDFE3C6A321EF87985BC0457DCA06E18EE1D767A06962221FD19778C3A39E28D5B28", - "signature": "9F04F0F9ADAF2FB20F6A51946618176F160FA06F75BB13ECE89F42A298B404AEC07578CE883084D4C63F30B62232F725BC16168223D1C7B4375657EEE2208A9F484188D9F54738B47B7966DE3B8B16BB3DF1786CCCD81E921BBC520DE5B3E7347F47E4EE104B958CC4D2FEFEFC9A1918CC764BD3FCDCDF9218C53921203ED71631E0017B93D7AF56BF3E1073B0976F4B4BDEF744464E43FAF0AE22CBEAD9A78434C58D03F6CACEB3F234E4B3129DA9B2CC582EFD51D3AD76654670AB94BFEBE62C5DFADC56089AA1177F0B8FC03818363256065FD6A7F5FD9A1E4320EC73422A3DF374F6FF2C747C8F77EEECA899313D5990EAE749B2EA5E00B746EF61C3122322D4D207B21A020D40B1B46E0434399B04F366997EB6A38BEFFDA6B523E14A367ECBA8BF4245348CE4F0612FAECC89210C45C359BE25FAE383F62F5DBF15D178609D5D615E5BA86D11D2EA06906A61F4F2B2F7645B9DBEB37FAFC92D70789A85ACFD6DFBF5BBE2668AAE07365FB5D14CE9613027FE9BD88BBE22B9C8645DE8B2F4A395A27F348CEC07E0D5EC76FF82EC79A2906F04475E6CC29F46140ADF86FA189AE38263CE15E221F38A1CE51C339D06F9A2D4A43D75618173B86F41263E27D9C7B07F130CF03E7059EE3A98037F4390A1AC61C59F718FBA1F17EEE2BE456FA63CB25B8811B51671CCCF8E538918A8FF10E69922F6B9740258AD2A08E26644646D534E3D0A622B74A07BE7C0C8EEB5B1350F4780F3B66FA803521AA3EC8C9027696DE80C07D19EEF26941836DB535E00F91252446222CF745C33DE8B42FEFF80880006AAD2B0DB5ABA4A436ABC36D7431ACC87CE57B698C1A238C7CD75BB6D5E3D7B3F8DC3A4B0B444D6598E2B21E664FF595F49B7267E3BFEBDA2FEEDE3FD313B5479A4F8059F0BA56FECE23EA9E6018E87FDEFCCC34F2C9F0AF400C578B9AC335953DF6CBAD3220D86B49D4E6D933DC6B37DAD9C671AB87F30D829E5DC6FDFCC1EBA016F37F7014A911100B0BE3DA87BC53F453D323D567DB3A36F1DF24EEADFC5E603FE4D425347408DB8AD7D40E530B027B13136E30B5B9693F084C2A160F50D6A2224C2257864D5DB52E36D9052DB125A282E90A3314554108415087A852D22605BDEC1996424288B9D75413B5F30F1E0489B8AC76D13731CEE2F3A6CB0A002FC25BA859558BC17ADCC4ED8627415589410AE3A52B6F06C7A7E103BBB350F8DD4D6F2BB92FBDA54AC9FF6D34DE291C966A705EE615F3F868F9214B77ED9A54ADB9C97FE1F95313CFD64AFA6BA4594E22063EF070FF3B913E9F05351958B963423DC3DD85FBA36C452A681D3D65D6CAAF1C6043F8A21C683ACA6038E7BC2C1663FA6199A57C881B335F92B3225F60534631C30025F9662046E6CD1334DF335D0FC45507AEF68E4D0F02F07F88C0D40104BB8B64F7D8BAE8156A6027266BC0C820A0AA5E44896385112A0489291C5D55F24065D5EE636D5FFFE2AB7778E4A5FE5555E535F30AEC4AF0436743379F0D5713DE40C44079810F6F05AF48D149E2FC28A580AD45E658248DC3A0358804149A6FCB3F006700D4B27A8D457B32B16E17F3CDCC132782C38A70334BC4B7F8F178CEAF0F1145E3B52C3861795C400678303CAD2A2CE35EA95F6604342EBE4CA46471A5725146486E477C8ABE47DA05FB0EFB8A06B4477CFD4A8E1ACDD95937C8AEEB5B7629B5978A55B08844B122A75861D71311CBD1857D29AA5ECB8AA0739A4576FEDA91724D068674D8F02A9FFF27835E1B0B0AAF395732270A95F66156519C68E53B623CA04C2ACDDACAB3422672CBD55F494D219CCB3AFC52A042020B1BAA0CC92145AE2D663327236864EE590E31ED424014E0C152C99F04C8029A5ADF03E6F05F19754AC5B9B5D9AC272A0F01509580E149710A5A5B031E0A79C52D29A86E153A108686D68A9B6B30D64C6F450B18703252B773FE1A5EBC24971C88D40C07F0BA78230507B1B287399D58C62F60EB76CEDAED0B72348BEAC679466576AB82B44BA81C0228DFDBB557184EBC91EF34543969A5296607016773D233F345CEA830EFB0E0DF5AC94C573E48C3843020CB9C0375225D68030A878B9861575114A8839E888246EF6E2A023C6A062349565F13093135CAA4A06FC834023ABB9799C5FF14467EC99CA844957DF3DD1C18AB93B5DCF2E36BAD64D70F9F42889B5A709E6BCCC28A3F08BD8169A3B2B5C637EEB3123F7EB3BE9FB82E950E14027D2CE76C3A2A4E0169CD66F8C2B3E942A8418417F439E3F09E6206735678DCE772FB2F45F6B9907636D17D1B1E6AB52D726F04CAFF9451E70A6807B6B563AB2625EBC1067C7527A5F1AA1F6F63033B216C5589FF612488C44EF1813FC767AFDC421E96F16F29E7BB60A3F6B76C907A2AE4DF42E8A6E3091A50BB4FBEE01E80F0505DD30BE0668FF508D12463C609A5DE7917ABC84F36011695DBBDCF88547E7F229D7708B91CF24F6B3F435EE75D1C9CA6C32A71DB3F2574A1898C81B099A911FD5AB42D8FAC3A5E1011C0636A29D9804C8A1DC97E430798B6A060CBC0E29327A4ED8FB56DD1E2622A2AEE4626F250FE9CA071BFE0BCEBF3C07D19DBC1A3AAFA5CA9DF96BBABD0F54973457DB8AE1833580F47B2BA7293E89CD2DD1E6A3CA9157C8E1D37A888FA1A697D0A7CD081578B9FA424832D6AC08C36F37F163F84A4831CE0C74EA8D419BE6616888E871B39762C395781C4D3D96C73DB5864AC52589F3014EA6CE21A252D394AF8E9FDC1C7EC1F827B0ECD0A85F1E2B44C70AC2AE9492351AD429E8845CD0B6E8B5B1053B6AA7A26B2F9C4BCC0F2A7E56AE91A23B9E3A87CB125F1A4BDFE41A61FA1D650C7708426DBB9726608E25E47DD7F7D54F5F2795504B13114EAF4DC314DCF0A90E862620D9CF055CD0ED0435E583C7207D365390E13603278F4B3D481EB49C2B85ADDEEC89C742131744C970C53B25C5A7180B5FE23EF5D537FB9E329867365A3EFEA00E3B4FDF3C6A711034E01FDC4BC2B51A49B5479A0C214916CE3B37CF09ABBE137BB0B5BC2D5FCA19A2274177CFDD293AC37B0BE57C84994B86F2E4D1D97522D90C12C1D4F8562273FF024516F26F041C0410090655DD50C4BB3A8AE54073636A48FE3E25AFC2FFFC39F558F7F17BF4A8D10B01B57007A1C69948CFF1EB43D7A46963E650563737990E3984E8742DFF692830BEE970A644A13EECA65217ACF8D662331FD2037D6676F4D4FD0480FF3F5159BBA35E23E490DB27CB4B43CA8760AEA2DF0A9E0EEE7F0ED695D2A844F1408CF8DE47CD0F0343515A7167439E58AD8190D7B1F21EA9F9AFA90C5724AC6E9B9A1A2A0A6D848322316FDA2F0748299D3343BC2323E06F4F556E6A537E8C04034B456A553A29F1F91B23DBC364BDB7CAE2B38B822B25A1C40585F20D44F182C34AB57F93407FC02FDF72A7A6BECED973C84BFAD5058F4B58A58ED2B85CDDFB21B1340ECB6767DFCEF879A7ACCF8C11E5D8D9E84E5962668EF6CEC28648FE00845AAFE8742C3443F5DE31087F1C48FDB1ECFAAC5EFBEA318ABE5F8F71C3E9C212982640F7139901DCD23B94112BECD31D2D218FB1FF454FC72506785BD74D97026743EF28DF62554B6F9C1F9F1D4BE5B904F0B756EEE696CCFC4AA1D99EB7EEFE457AF23ADCB8EA8E77591FB0E366895536E016E7C5F8F3B79CDB28E91F16B207C9FD2994BA8A123F737395B8926210F1205FE14D28FF9143670C4DA3CAB12C51D289A50D8197883F4B64E8D046ADBB74A2F395472FB4401D85AB76C4EE3E1430F4A4C29F884C71A0D8C534D707D77F80B9EAA77CB9FD1E9B8166D9B71980EF749BBEE6FD9BEBC9F8C7864E734D87FC946E2DD076B3C4767F1EC50C767E31CF2D97DAED75068D5D8F6A0D49BB5C0FBBAC550532063A0D8D487D8C757236AC37F1FAC5FFB5B18BC258D22C9C8D94F774D4B000421B5CC2294680AF883EF82C79048810CC32FEFD1989FE254B7E0A445E0C055CAD61A0C50FEC40D44B642D668DB884BE44A1AE6DCC91ABF5809826C48F46AD5D26694127AA3D513AC35C4B43B94EBC9F3384881F48662C77ECBFBC7DFA45E2C4F22DCB909F08CF1A828A2DEA3FA7615CA12B77B48DA7AB10AFA247B993500943E5CB79C9CB5D0D98754B69C5F2A0987ADD573007B62BE5781C9F371ADDC1440D0EC9F9D95F0473AF1A39A48836E87B63A40C7B62768F23DBC2D51E1F54DDA555115DF099F2E72F4A32D09EE45ADBA7919EB2DECCC2A5E381D3F10EFC7338BADC11BA2EA7921A82C926333907C5637FC0BF3CEE18070D03DE66FCEFD96218F78367F8668813A56CACBC97B6E9D5349BDAC6FE7D326125737066862492C1827C7EE809DD5FE26284CFA6840B29C01A31E2AD9EFFEEB9CB8C4D1752DC17DCA784CCB9873DA370C83EE854C7AA6722A7D35C7BB9D30F3F506F39796264E73A27985F23E5DEA5568643D573A8EB57A428ED67B2B1ED20558868E5C3C92E80B57CCF9A71551C215856C6287181B050766E0BC9BB6D5C6EB767F872CC72D021D63D3C48CDBA7CEC6F57592745BFA99C1E3B8ECB4E2BEE493884CB488C2E298E63964A4DC91BE46A8B4FD804A6EC31AD797F271A3C88A90B0E5C8E45647497A6B9BCF8252B639192DEEDF7FD11168198A6A9F1131D39567F8ACBD2EA0000000000000000000000000000040810192029", - "reason": "modify message" - }, - { - "tcId": 30, - "testPassed": false, - "deferred": false, - "message": "3C77C67FC34BD5146AF5DDEA08ECB7E59DBD4F0C676228768695DF4A7C20854B49E6959815214CDF93D58ACFCACEB6B71308BFDABC6FFAD20FDCA00F2B69EAF5C4A8B8BFA3CAED5D980C7B6135385327A50BB466154AF302A53962037EE4EC0F37BF071EF55BC2C76ED524B0719F0C72E01EF4177821B4CCC6AE1A66915C32BC", - "signature": "2D26E2B81D841244C2B8FEF240C6B4EB2E4B78E3363EF6D931C2D1379924E0C0DFA5799D6A5AE4A6C5AEE785598F5EDD014F3FC086CF5C00609DD68A54E2EF651941EF663A788F776B32B2B32C3E9DD53C6F2B2CEE72D770B3A420C6AC5D1F5D1850ED4276552D4E3A41B203A209E79535CA43A5F576AB37C9FE1304A3C3E275D0278E05BC90425DE33C9A54DCD4BDE1AAF659F673EE154BC92AA76456BCA5665837EFF2E4B7F9DF03B638C49C013F64C13F13CB52EF34613F315A8763522004D77C5728181B1B133B070B43CD021271E697AB55E1063CABC89AF7978A822BAB223AB8D0675B26D437E645C8E8F909AB88D1797DBDA878F3C5DD6C237F718903813E1464DBF47CC134348B042423138EFB81411729BC94068EEC8DF1BDB5950DAA03E6D17D97DEA579109EFA0800CF2AB52E9091B0D39B3DC576C66F29D0028A503DA6144B63DF6229995AFDC2F3E1C038463E29B3303CB89D97795725FA85AA35EDCBB4428DCAF3F4DA6116049D68060EE16CFCDBC8C66AEA37261F7E85F711D882B1EA014AE7C4DAC02FDAAE43A7CD3B27737A3E642CE3059340995D61C05451468737D3F88DAA5D9EB9EB12364A77F9381A55081BD2370CEEDE386D23BD9812DB1A09AA3B9268CAEB061B2530299841234C35AA557EB6CC4F9671ABF4067CF14939698816F3F8BA59A14ABCA1CA7521F6595FC5E90E37DFE52E23AF66F17AF8B2534366FB022C861663965FFD1737BA6B47841AC269F2DBF1FD1CF91C9DE5DE46E90EDBBF259548FF9B89EF1BD29AA6519C2EA2E7778A9FB76E8E36C9C9EF96ED92F93F1CA1A26C636CDF8C162389DDBCA74DECBDB1B9D543C63B9C231FEE27340389D183B3B2D51E614CB0024ED0B52DB62759F332AF45E4033748AE6530BCDF3F3DD4A83AC5D56FE1F4AF3DD6421C1DEA849712E1DB78D816C6889FB320B7A18C6B8B0ED4EFD25A3D500F6505F3A03867FA6B8AC6ACC026411743CB0943E1F5C409B03A532CBF21BA7F98B79850D496AAA4260AA733761C7A144D6AB40F110146F7F9B47FFFDAD1D591014307442CC1403D94A99D5985FF51A42F1E513FEF30652EF70E40D12F131C259B2023514F4E0EAB848FE89FAAFB2BA14DE6973016743D645CCAFAFE07ECF74A39A3175DB07009E645758C7FF9AAE413E9D97FC107C46DCABC6948E6A7BFF4F591D9BE8C3F467A6D1FAF005CBDC511491F8D71FE6938C383B353B058DA79CAE4E9A8675FCA2C976BAF4DA3A0D474D5C1E588F9AE73BF0721FF5DDBA42B33F2B5EEB2E300AD0F75A5C08BE9F91F8F4497D3C95B509AF42DBD04BD0559D45644D5976FC06C492C67545AF347D86FA8D076888ABE220818E0744AF6BCA8A01D36AD99B984EB30A79C453A2D38070706751E820D05FD25E293574352E9374DFCC8905AF57E7BD7D80F4132CA730FAA66C3F85FEF050EDA1EF647CDCCFC17C2BD5618FAB36A15E328266033AF9E6C53E8DE860060D0712C239E20585A50673D67A588DEE874185230221E2E66B86ABE7DF161F9CC65E5CF3F6A8E817E9A9677CDFCC147A71ACD6B1D955A2220BC7290EFCDECA5DF07102172CAED11E7AE7C8D96D40804601D3BA83B7678BE58617BC90D24C5F4549B22E39C42F9FCB2D75AE069F3B609A53B70F33FBDE04552344D44C876B1A4AE5C21C72487A01710C579DEE84A77E9A431446CFF0A41CB9FE30601D19DA60B4718E5CC4D006E4F9081F277615A5E5CAC3E057C25761ABC7F35FACBA35B237A29AC99C4EA911CD8BBD1D292C1510E8D7742A5D7D41C14195C8E7DE4F4D22F1F265EEBA6F0253770954CDBBF3A558A34F5E6304CC6088EE19293AE1B32BABF93B3542A0D7DE13439B23A30A634F55E9AC557F00C7494F16FAB7E177CF828261CF6EA2B7CF9CE7E870A915D3443800D81507E9CBBF06F9B2444B347FE82AA2E7C9934382746CE71F625B582678FC55278CC7F3FF185358EF49068E5D9FFEBCF3EFA6184D290C187FFC290D04274CFE95DB27BE80BFA7D7D4A813525D275F9DCCAF5F42DA4257DF5B10EB1B605401F1C2A59614B1EFC7B6E5BB5BFFE687F970905F1BEB8302A1122C71F609B413F7E88E6CC08445ABDED5EE6D40C7DA0F3AD53046D209CBB08C95AC4B39DA6E72F697603182060EF4635D34CE5DB99E5DB5A9A1D1A2DDBF1082A13E5C0B07A43A950584A1BE99FDC16078BE1D873A6F8B1DFCF9E4D667CA42A31749445D62C4D480200F1905FC97CED9984565BB0A1E46853C62E9739E83EC0DCFA21120203F1D43C5F732F3A7768387D254C2E4193E00BDBFEBA0E630797E59741F1540286A30949AC9B231A151793393D975BC74390A288E07E143D8C70B071323C0294EE54C1AAB8E193FCFF85B4D6863ACB6C4CA3FF4E23EF4DE7D15788EF8E2E4F285E23D827BC2EC88DCCF9E054924A83B369DD59C21759CF494511A63DAF8FF725ADE637C68DF6B1DF7139D56C8634EF66A25846F1EE8214951ED1B11E28AC9BBC3FDB3B3D8E9DC098826298554ABF8437D8382F7DBE3886ADABA8CD7651FFABC710CD3775D12E880066161775AAE2F247F2EB58FEA434DB535555FD06163B1B1E5AD6823A3EC2B673725F7859C6010645FA6CDD8C667621BC31767E20340928655CD613F12AB6ECA70A7B2183A1082853ACA2E618DE29D1B2D8050C7F6814AD4D73D9DBD9A19A26E800C34CE0F17881F1ABEF381AAE4ABADA2F05F394D125259A919CF78E8E65480CC6C61B779EE5719EE6DCDC7C625FEBF5DD68C34EF77620E196F8BF9E3FC454188FBBA2BA62851D82F4F9B0B07BB776653DC7F929529CD258CEF275956F92139B9328F5857545BA5B2FF560E945792697CBAC7724B0209CAD1C62FFA479B196AEF1EAA9DC66E4260101959869254021493B8AD22F5E16F0711658A0E808D54A943057DB7E8E7FEC1A03D316548D586E78986AA3FD21BC96F1577F89C77FF72B75B4A937A54359D5134BAC694EB15610292FFBAF62AB08B10A981A8BDDDD9A54D21953537C61BC575E6D5EF0750DF3065430729B6B2FDDC324B81D1A70FCDBA156A538FBACC078E831010155A2B3945B83D320E3B754D50CAADCAFF6D7931F916148C262DE2E0C62DE8211BDBA6FB7F5D68F012942B21DD6B77058CC19737992A3004D7EEFFCB2E3B8F34C2CC9626FA8B8FDE53390877B73A76BDAD294E93966BB03BCDBB5A8314FB7EACB2A17DC0C2897BDB841D8C2BF64E2AFE74FCA2EFCF6A11CB818935A7B2C329C9E70D89FA51887DAA8D1AD1DC2D52D4120D9EF2D43BFCDD6142D5083A352FD0B33369E4B8CB627FF593169244E7D44A769566A10FA31343DE188346D11EBCEF039CBBBC8CD57F9143D7AEC2C4BD4C32814BAB972C99EA7CF31E94EA9B634C45BD666B56BC1B7D9C04D7255A1B8D8180B559ABCED0B986A420BA0D7D9376F672875D01ADDBEF79656B3E676081B8A9AA329FA82715B4EE63294BA256858E91AC9559E5C633A7D404F5F8D80BA201A2D6E976AF3C3DD6C97455B0FB701870279D429271929DECEDB870514BC703F7988AFD6653AFBA5C1915EF7276DEBF51F564C12284D4981B216E00D20DD651A58C9F83BE32DDCFCD8F7BD4419EDC7A14558FAFCB12A2DBC077A15F525DDB339ED8FAE9C3EA17FA1B49096105328784DE1F3B6AAB3D411CB7EA74FAC1CF27D9AD594CBF5931AB825864ED976A43927A1DC18203656ED162B032E03EB9C1866255DABC10F141E49F0E388E1D4859A89FE15EE09CEF6EE2D27DB1CEB5873991C6F069DFC101E218652B756EB6DC724A8073F0F9A2E287A76D96508229D85699ADCB8A1EA78C98549C5FA53B3BD34873DD0AC236D1E3857D0E6170502FAC157F0A73014FC611DC05286EA49BB255BBFC6AC480722BA7B1C28396622DDF9E45217A4AC64D365685BFD22D3EEE8958D3230C7DDE7653F96665F62276B21D919923A48B51591BC57FFCEF5A051E0DB7C02AEE586DEB174A0E924FABEB3CFF1075FECCE6E6F231337E00F6E890203BA7B52224D0EC696E578EA13869713F68BC654CA98DC489D33784F081664B4EAD87B28B32D75F865F32685AAAFF37BA2A719CAEAC5B971D0B96C89B53A80AACD005849E0C5DF63EA42FBE93D09F2A13B15F46E189874FF57C33D6A2EDB2A6686A3479A97441BCB7FA61101A05E106EC16CCF10B85140EAECD8E1C4201782FCD23EDA7835EB6D5AE2F64C723A87430B24C295B0F281087EE93859A6131F36A59C936E0B23F0ED061A7412A3407408D49C2976BC6F50E44BA32D21F819AF80268DA3E25B7B517FF9986393FD9B880C1CA9D372A35BD50F98C6EB10AB1958DFC1BE1A5AE0D606C5355EE92C5B0D9259C1CFDFC2786A81F1A7B77E185A9BA960019E16014DC64B5032F91958FEE7F87A8CF659789558C82E776480A6F4CA133844E0A54F7F2C315FC6927ABE684E0543163115D6B6D3F247BFB22F0CD6CD4977C9B88CB588011031B265BA469CFC2BD1DC17272BC8547926C255335DA0FCA8F66F31E0777CF4317C26FF84D58A3CEFE5475E753D12F793F1F929DF9ECB066348719EAAC14D71DD11DF23C3747272929601C89021ADECB02C5525CE5B73CD1FA69E9B36375D68C4012F4552BB555E84D2FE026C7686878C91A8B4B5CCE2F30B0F455F9195A7C025697498CE0000000000000000000000000000050A0F1C2429", - "reason": "z too large" - } - ] - }, - { - "tgId": 3, - "testType": "AFT", - "parameterSet": "ML-DSA-87", - "pk": "59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761", - "sk": "59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B76EA27B03A86FCF8E129070FCD8B5A4674A7AE44692497E3E3732874E08F66EA283C547766DCD7B618D05F5E56D4C53C22E1604405BFAE54D3F0CAAE9F74AF58943160BFD8D16D0F8E20CC0C1A4455E0DF5CCDE4892A154C569E9C9CC44810FB5C3324848282DA4C2251B444160342A100040220649120986E204510AC929C904005BB285DC880891184D1A09048B30121C480D193388DA40290AB44D02C0644B488A020946824605E042080BC2305112691922429CA2255038868820464A026E994640512685E496305B082013288DE2C65114C36D24A8119436241A97291110619CC021D42222D908081431060A2006A3C4850201650B976CC4885000C32D60040902C490DA868980A460E0801101908D1017669842728BB24402A60900434A59046C4A003040A625924284182141D428815A06518312851C18098CA809013772992029C296494A480A80A22100A64588384D0813211CC95180A48154C00C1A448AE30820119925A40010E2C64151282014904C24034A88462590804518806902958989184420165144A43011C6805A0010D1928998B63109048A113165E4142E2423058B404E43C22400234E19332C041024CC184903446062802DA130101C49841A8084D83006A1062681224244B4301A265011496C2207284C042A10329108C86C239181510486DCA20812890C029785CBB49093468E213530A2128CCA20308B3221801468D20205D11280A2346E84920CD4448510912D041551D3004190A66464B08C0C15801207200AC304D0366E5A8681231682DAA02C4A0851C2362A64280A8C468EC1002900820C41266182180DE1424124952D102831D1A42911C06949104021336ACA444521370A11C39164120DCCB4649CA02C5AC0881028825A148219C868A1408D94904DC31408634051DAC82562026413318152126941B0084304208A12000CB6649A160C10B90100B78D1334826346429422258A40295A44450B368923404584240C11A6691AC229A21802C044414C9285000805233862CB3291E4446423194ED8A68C0C47210284415B406E0337715A865141A04D5346120C1425C1406410334810314C990051C13850184271A3A8319C86315B2040DCC46058062894847021962948B64580C4284B08862237529B488CD132092301241BC7091BA8008B424C144450A002420228060CB501241100C0B86DA4C2050C4392190966CB204D2322115B188C60A068D4C431990006804890D2B62D5C902003216ADB162DD8380640404A11A9680BB1015B0651910225983204D89625122925CAB6804C480601826C94A82D18A4001983101935610C158501832C4BB8618334618240459B46620CA84540B06510346C98346D13A24553468053B825122424E1C4481AB16883A04CCC14291A997111920811250501272A04986C91802120286A093648E084108AC6915384440BA87003434C11992D02C36D54B84023490400C748D1261161925111B7614AC20001434C8B1408E3200E4A10291C05719B202E43182ADCA28C24886099180E0C444D81324022386E22112CE1320D54A0205898441B3260CA2480589665938830E3B20D4A462D108068CC886D2120880C198E8428251BA32DE100221A176D9C824CD9088109C56D444862DB400898A0448A4272D4344E22332AE036611A810C91200454904C44026D48302252A60C84404242086122162A1A471251C0308C806918813111372410080EE30281032666101470D29228580209239210113289C0C85194242211260D63A28922376951140061A42048A22D0A28265AA801A4286620288A8AC8900C2024C1820C8C2441DB060D1B03805A326688244C91020A932648D90689D2402680A28424068CC1024823160A4226099B04669C228D0B446553246464009113198948122C11091200B7889816099C966194300DD216201A3062482249D9022C0CA241493425E4042D234346CC96510B3644E1B82D0117105A4800C3120C0130869C922D2294099210451B329153C2111CB33120474D849809C9881142A070619410CB14408C023261B668211182CC246CC03810C23862D12425493245A0B04C53C84C11111208352E51309124A30113C5411C930C8A386C4398640A460C52949112148A24804D5B300D1B260DA4840D303AD0DF21AE5B65EBEEC1655F182345D45DC837F4F00FBE89745E7CC7FAD39370D1FE8EAB00B966ED3F8285B1004DE2690C5C29F7DC8F354989E4E1B905280759F03460DDD395C2797399B1A752E7703C4FCFDB00AD935D6E6F903811C9E9CF1F6FAC75A947893D5F694C3E1D956B4DE18C77F53C98BBAAA9AEA36949CF09BCC484BE2BD1704856A056C87EF210627CF0FDDD95C4C59F57E59031905A90ADE4DA244B9853065CFFE3C79406471A413A78E2E9AE0D9367CFF5D0F9B2B724F41772A8D2F9AD3AE834CD069CFD208F0799AEEF7DA2A6E7CBDC3AD47BBFCC82C508CEF7F32AA856E545529EF977E6C52D2699176CAA2B3A5A4295F5456E4E279F19E87659F753F2EEA37D57222B2C082EBE1A822C387EED1A73FD0CEE31DAC551F83BB5A18EFAF5BFA97A9883644A8E811A2D7EDDE63FC16DE02F6231AE67D2369C341305E5281D36B48547BA92BFB6D2FB9287E311DF58F313BAA86F9E7CBCCC208EDCE5D5ACDB3BBC4AF7607AAF697F095D97F9655656A3A760758875DD013FD241FAAE8349AB8A3CC588228CB0C1965E3685A5F81242095FD8B5DF3EA16F86CD1760EC1A93A5E38D033D5C5D06B9F99F8436E74138ED4E265B88DEAD42B10BD120EBDF87FA1A01B027A84610F9BDC644760E9344BEFCF76827D58890685718CD407613C0AE540BA02D9E03688432200C920009B939311CBD16325EC0ABFC60FF567D59B20E2FFDB84259D7C53DCE77475E809E6CF70CE681F2485CC67C9F373D66279957616B2461BFB9BCA78055254C923E6D555C0A47D4A0AD35FC4159566CFDFBB067884E0A505E7E425D084339603E68925B7A1956E9B3A9988264EEA0CCA20B8E9F404F82DD65AACEBD6202572A9B3CB2BB0AD1282207AD5DF4ED63364974929D75BECF19DAE767041BBF1325889E45700306CD8A1F694AFCB77DE75D17562280AE06DAB6560DD17E9EC74C0AB48DC8368599305E856762C822EC0BC79844B182036BD65CB1BD5F612FDBA42D45C7A721ADBAE463A6B27413773CDB7DF6EE5EA901D5CF061DF0428320003813757C5E6C44F433136ABBBEA4555A4600CEFE45D4B2300C290F150288DB8A9AF87EDCDA4F6D9364306B64EA44467FCF9F5D574A73944BCEB06E318B0C79BAD4F1A7D060F7B5482158D49A73C9C0E20FCB2C6EAC18FE22C67976345F0EA1DE7DCE9573D51FF894B703B409C45B22B225CF9371BCD6B0B386B5B9D756C7731E178EB32F068C35571442A3046302A8685961AFE47B957BCF901A3686DAA130297CF9AAAEDF2265FBDF0D183BD419AFD428420BD1C8E8D21FD1323D48642B2666E2A4266417F5BC4D2730393D69911D748B2D8DE772C21586C4C0E942FB3BAAD097E9BC4FD38C95EBEC8D8907D47CD5E7F47AD5E0B5FE427FEF6E251367A790D3C3E09E2BB332F334EAF0940A59A9C6F52A92FC9C25F48B3D189F23E2C5174B1ECC90AA9F25930791E83461C349197F72EB2241F29C22EDB4995DDE6B849F8B294672D26B39ECED7FFA4A4F4F08FE789B2A89DAB808BA87F79B86DC9C937613A1A5C8AC911342E1AED13ADD930A469A01B6BC078E2A783A63D9D8CA38BBAB3BE6835C4ECD25D031B0AE71B4CA1AB6001F14AE7BE6D9A2CC935C19D513B33A51252ACF62DEA70325781F6C1D0E99ADC0EE0866D77249F671D6A98CA80DD0ECECDBF76FD01B42D32C21766BFCC6393FF88B1165AF83116DF5B0562D6461589BF9941B01526736CA75BB11181A3461C1AF3AD742F3F64B1BE655DD0C556CAC0CB459F2F17FCF1BC76B046195106B170AF0D6CB1ECD508570AF5BC8CA6D8411051FD13D01F53632D8393D21D1C7B06B4C2C9B862EB050890D9052E3F59294CCCFFDE5FAAAB8C53A2B4BB35187C402F7D60F78417ACB8CC89DCC15CEA2514A68B0AB57DFD9D51AEE33562E7BE76D155E55B2F263BEF66935B74BE28AB1BFE5D4CDB269BD45552B8C8B8DFDDEFBB00471B5FEDB6655EEF628F36FA32B9A95369844002919316A047295660A05A2B58305A474C86A2F0D7A5533EB139DB818B08961E59864FC4DD68FEEC1D88B8AA31DCC31B52B7E33A135CA30C18A2DB8760C628FC99900D1BE36CF21F7F7CC4ED3A5D73585CE97D9028ECAAE52F63896749A228ABCAFA6624665222F1BBA1538A839DB33717B3543ADF8108DCA296D66CEA06630DB0B77358B8A809228F8D9DD214E6FA65E38F9A330FA8023BD509DACE1FB99DA49CDF07A462A72D3B5C89E632B0F2D88FF81C71CEE084C21291642114CB05B6D90E07F8D6606D496ED74899D812517F51C506612DB09CC01E5B21360EC1A6212B65D75C071F7634D8E641C7AEC914E52979A293EDC56C5C10818AFF8748D0625C642240344E0DA90752BFDD1E1EBC9C41E6523215FFA1DB8EF2C60EF0305912B3C70C9294F02F0D8506B9D47BE1BE95CD965B842091EAFC159D04AF9BD06B8A63E87EC5F8F9689C2DB8B019D3BAB17EBFC35BD9E2A8E84353CF1506F52F20F9C340A793BE25FFE16D8762209F4AE1C86419D6EBD601633C0EEEA61822CA59A62E2C2B44751916B65C43625EB03BCF41FF887EFA5F77349CD289039D62CCF36D073D4AF58A109273E8421ADFCADA71D84CE653510795C83313CC82D04AAED74A54428EE53B777BFD44ADE392541398E40C94A5DAFBE65C78B7062ECCFCB7733CF99C567A154D819E57462BB30F8812D4486E8D70BBD5C06ABB4CFD721CE54107342B008CFFB8FCC0757B4066C8EC9E7E041B7C5D2375874EADD116F960A00A4EC283E67024206F4C325BF7551DD10CA437961BC573A63A4A922AACEFFCF3944FAA867163ADDB6AFF5DB82D0B262764C25CD84B47BB0D2336F1711DE1D0F695099578C8D46182F1880F495BB5447CA9F6A50134D96E5BEE01BCEFB0E66B5F2CF18257D0B30B315BDC6197DC9A53CEAAF26C02307DEDA02402D03C46F65A97CC753B86F8808E339DCAA939A111FE105E2B09625C222068B6ED675B1F8F719F571A787AF823D8B95ECF7B17C1BBAD30B626D80CAFF9A2B75A0F97F923E5042DD2D88F6EEA818DC350661743834288FC5C4D7A1DB51DDA87053429810E04DA1DF5126EFE6125B18F670DC6C0BF411834E4C284CD12F5AFC38100E60A26B7B5DE7D5AC974646BB1CBA6D17CC559E048E74C5BEFD4978EF7CA43294E270D2BA75213AA91D212B2EBA891AF78804B384A277BE6EF7F2F000E1414439652A14C89782419B1D4A30FDCB4D80A66AD16AAFEF3260E3F107A83A4C0AA9E5A43B90951A21043F19F8E2ADFC12C967A59DAC36F82C0ADEB0A438DF75A223BA905C1360FACCBA9149E1A9D0362D0098FC30C193CABFCEDB7FCDB0FCA67378349B32D8E6035D4FA532E7EC066200F4A8D071CD9EC30B25EE049DF928338161DD0BCCB52C45C6F6357267F392FC0BC8845E93B038C0DEBC9588CCA22B4D484C29595484A58B858D55B84502369F08B5BAE4D9B2F6B03BA2E58444EFD18E17F33BD56AD64ADD21F7D9238D3A6205C5BEC19AC57A263FCEA53CC6E750DD0FC24281BF392ECD9CD650947BE9CB3756D3DCCEC813E26E457A4A5533EE11D68B2137FB83132C88DC99E323754984F3516C2252EDAF2BE7F259D976B36094C1878F24F3706394A1A9658D7A7EB44D60C716D9FB7F4AEB4E0220446B673A9A4A6F4A11D43CF551A16B63564961EBD07E65F78B397B471B0E75233C8AB278D7B3FA7BBB5706595F3FE360E6EB385448FD92790CC06BAE5067FDE83C233BAAF97262EEDA4383EAD8079A3A6C05C162E18E98E7FABE182C2C1B3463A6677D056CD1A8C1563B4FA547447C8356B0FD00B776FEBC76EA81FE22EEB51C648A6E36B6D1C0560D9B2CA53739B18B93480CEF3D38B4999F83306F8A672026E2D18BDC6F84D18FCD9F4E0736562D763840D5DC76EF5E30B6291EB3FB89218A5E72A87472611BCB5F44EA4FDC76157E12763503E02CC0527DAB70FE1D183DE58B84197F4901B4930687506BA2900C51FD3F89810D3C0AA26D4518FF5DB44EC4D230572801696A4AEC116B81FC6F2ED93DAC6313D549E9AD7641E5B13A4B328866B51D51E9B54424670E494F585D77B78178262D5CD6F21332D908678211D6A81184EA689F2EC2F7981B650FDE5F2D8B1ABBFBF34E3D0B850DB2131D363883F7D02DEEA6A6FE32EE80A9F0D913F14607016467FADF9CD579CA154A455E0DF4E1923865CE7B139DF9D44EB3465BBA9AB678AC942FA7BB5D02FD53A52D5C44688F758CC1BF46AE3A43BCA881D60A1A1ED3BD02C4D1DE124EE1E24DD3E20BABBC9FF7DB0FDD6FA30C639E09F0779F7B4DDEE3D4AA70D1B30593782BFA5298A08D0EEEC899574AB2240C12A1F1A98343D6A705D10CDF376B6BBA4AB117B680D368B970183020C7B5A99097A16E9682DB66B3CF066C4145EAF6680AD9E0C138D14B8C6867872ADCD2EB4A7DB5F2ABF78F6DD8E54A9048564BE24C66F05644563D149548DE47B4E26A89A754D69FF2ADB7561B9FB8EC5A2286CC44C66779A33A9422E30DAB2BF5AEE80A5C1F6B940BFAEB072C3E252E16DA09199FAEEA472C29CBA4237899FF726275E59875C2C35DE4537A4D39EC1478E711D982DD76B7A5CF958EA98167CBCE8EAE1BED579977FC776873DFB0EF2ADDD1E496CA4F1D28B9453F19FA23BF30720DA7B14CCCB98BE19C35E415E44DAEEEDEE0C356B233FFEC7190E5B5A9ADEBE7DF1D29", - "tests": [ - { - "tcId": 31, - "testPassed": true, - "deferred": false, - "message": "4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51", - "signature": "4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36", - "reason": "no modification" - }, - { - "tcId": 32, - "testPassed": false, - "deferred": false, - "message": "5BD074132560F373C7BA6DF8B31012982EE35DAEF19705A0B46B3C34D474DCCC8B0888E5C2F045BA71D6B6A08C31CA63B9576BCF10B43BE4B536036A1B654A7E5AF9297E74CBF099B26D632D7BBAD7B8D657991EF336C6B486FCB0B28AF828D403315B63E9A0BA52755E06D669C2E066E98E6343394DB0B55C121F2E1D66F8B8", - "signature": "CB2F66EFAAFB006C0D60A81B32461B76A31C3A814513444B3312469427395E0B530C67D9CC5D2552AA544C4E2A6E132CA55E187642DD9FC08977FAA7012349E23E537418A90691957B03E8FD435D670F8AC671C0CBBE3ABF6EC28BCD3D66362EC8A13402BD18C7D782C96901EA26235A34EACB04D2949072430B0DE3256B3ED27630EFA915FD1302E1ACEA762B52330E7ACB34F306DF3DE26C98559E362E930E89919D1C2641BD37542C035A7EF25F6B8C29044667ED394F0E3F830876DDC296C880FEBEB30D87876911B1F4FA582D191FC7C274F52C5E53E0DF6F0A5C2C3B6D781E222B72C0A41C5A40F48986EA28A6296BDCFC48FE8FF0A557284A4CB4968059F44DA7FB77A7A5DB8684D6151EE35BF1BC7958C086A1E5C907C64469AF213C3E7866D404508F723787F6A1072914F66279376FBECDC853906E8E806B3D07F06E6355D5F97191E4C55C55AD78273F10650E7018A989542D68EE8073501D331C7B9D80049C94B3F8CF6F0D7E569C53EB76A4861B94DB95AAB1C09BAEE0B998012E72DF702176CE9578F1995B64A4B17FA95DE9EE4AF0C012EA0445D065B87E49DD2C36186630585A414BE4780007866FC3512A8CE80AD1529BE7837D2AD5E0274DFB9ECB0B92F9848FC41695DD25D05C31E3C4A44C75327032065A005A4F2349CA9319A03705FD802BC73D12987095693A60F920103A248340C75F38EDB9068668795C9166351F045CE8560007985F140218B865478DF7A53D57F0802D48C28DF1122FE9A7EBF0D449B361ECEFD2637ED5D7627B184C73C39510F15CCDC35132CD6D5EEF4FE10CA6FF0FCE8BB70FB974D6D6B21CBCB6A972A070AA8DE01D6CA0AE3D937D0FBEA3148DB2695D2B8A14B1533F7A303032A35C71772A272A8786805C3380C4F49C9B5D6136075676F806D4DC83D3164E1E7723DC4F2EF20467DEA7CC1FFF6AC64C9AD71865B63797AE1D6A27E6E2FE2863050271A7A42E77C5A1E3A4C15F2EB8954BC1C6C4A969B997098A8082327E9747FBA569C81201F54C0240EABB105048ED6CF54AC99687B1539466DB4B1DAB99F41738EAE4CC5FEA8E7BC89CC3F9C8A19274E038542182E9D7E0FE0B89514A3B451101039DD65C552A75970A8BE70BEC1B51BF290C2CAD36F94D1569ED58A0E0D9C9D0A722CA8CD5FD73600A219BD20AA4215E914B7D9484DA8482BBCD7961986C211567FA7CEC033C44BAD8E3B2CDA9BF5EF4067BD196D077E9B7200FA54EFD99ABADC8A75F0F49E6E5AF498E7EBD25168193B088DF78C90318970C78748A1AC611760F90C85D190984B29EBE1C50075C3A9BC8C78584EC751BD28AF8C1FC270658DD975F32FFA4AEF96940F7FE4E4664B39CAD9BC72D6F51ABC37A93AFBF5A0238700A0638DBD158153215F5A8F79782803BF9932C70F4F0D51CC71AD32E90B98FD8134939961874884A6C0D372B8F67DB7D9D65789171AB096DF44AF7CB6375D4810B404B5F19E181EEE008043C4E87383055EB6D822B570191FC80B616A52E64640769685266EEF6EB7DEFAC733237DFA83864908D4231CCA0CA7F4C82BDB263B640ED78B7932542B2C1B0D73230B17381B9972F7F999131BA94E44238A2DA2FF4878D306E4AF5E0541435DC6C3C621EB5167FC7EF7FB73E6FCAAEF3B9B595D74F390E5D578BDADC44194E86FB8F39FA546FFB7CC51DBED456E1060BBE5564F5175CEEE910727936AA7A843DE98F7FC36BB1242DA716247227305AFF1A234F267CF09469D5C4EFF8326F0950AB60E57BB8D2BD1EF9782DED7254E291FB4945BF4A5F74AD881028FEAEEAB4841C2E036BCA94B125708B26D50096B0B8A9F08645A25C0CEB634D301972B4B6111AFFE0F3EF5773513ED97468E1CC1ACFE2656E5A4AEBBECFA6D74DA692ADD3289D227E4DC420B4EA3E768CADBF0389F1AF967BE317FEE9874B4406FAD1F0AB9C37E54EB48502F14827B308B146E889EDDD26731571CBEE367403B1EEAB26F0BCE876502852FA3EF2D1C383C322641C51A3BCCB6C706D7CB43DBE3109C569C4F8AC26E75EE844EFA4AF8E2CED85E1875F0B93D17170029C408F65BDB96F5517DF6283A24B19074767A46C0EE54E993048B73D887939A6D956F7B47208BD1963AA580D7932D0845220F59F3F2D57A227EB57AD0D302964E6ADC7461DBED7868C79F0562E0207F542F8B04AD35FF3E3DFE590F8DB991BFC54D7A80CA74985628DC5AE3C75875A34556A9B5B058D433956B0E10607161F0C3ADF653BEB8E694C2E30326D1199B6E68DDF987F9CC4B4F4472C23A7FF546CBF2A22F69C2575566FB57F31719675294B9D5AA9477953D959FF3D538C3EF619E12DD6668156EE016F595F8F675D2A509D73829B24C3856ACE4690C27F804E454BB2F776309CB8B784C5FE3A2C58111D33502BBACE754EB9DDD9C65D29011FC9D601D749B9390F21E5E4BA87037429A3A3CE2E8BE753A40818F3B9B0904408E1157D55A7A3A72857D9D20883FDCAEA9ABFBABE604B8AB95C6A2F4BC90B2E355F9FF5BB02D9516B68D3932F13F759535F59602F2AFD8CE288395E6A5633C9BEF5EA6F88C705C0DF1AD505799085F04B5543D44931D89443789E6C94CD6A325A716BE0BA14A411F0EDD881953388951B8FE937B577A0ED31BB09882DC153AC2C5F9D070874A984CF02D2EC062B6550585B1797B0F62F0D1AFCBA76DE932D8DF2D549FEC75533BBFC60AD7B1DAA59351790107325C3D146A766DF7C8C6377E6F9BAC28736ECCE30663CA37D144ABEBF36E9A6BD7FCD9F4DC3DF055C78F8852316D72AA056922AF21C2DCD7FDAEE0CD8AD3415FA3FED92D8F5697DFAB9FAE2B32FA800E04C7CF6109B4A8C682F5B11B14BDFBD1B96C1C78C36A3F1BB4DB3DA0CE940C917D6A61C2B9FC96546BF6E0D697DDAE3FC38E683CF29ACCB431453129273A1923AA9C70EB0A0DACADD0307C6990FDA42DF9326503C4A6FE72D7F2D81A0797DB6B2399EBC289DC4E3DFB1BA181708528519B378D67CC075D47C3094303267B9AAAFB487E2E93CFCC9D20CD2B0DBD6E29A020337D4D3976E07289CE76185F5448FCFDDF7986CF3ABDA625D0A5A0E0CF6ED779F78F93BE57CF1483D975428DA71BEEAC5D9F02CE9517FA842E9546FB2AD94EEC611CD89686007FDA46A63A5FAC8DCAEC36B569469519FD5951477CC923C29E3B540CB1E19D90BD42EE24F998C0B793C7BA4F31B2DB4135D11E8396E5EC727F57C0C905D6EB4EDFE9BCDC3E671A0AD7ECCC136D3A11CF19B7B3CE54D33AB535E2F99DA800677475C20702963A2546EA43B3E6793EBD9EE59146736946954B5C7A19DB21A0B6880625A540B74E4ABA0C34C12E151B40A2B53F548CBFA101C2F05093BF75246DA04326EA88A282EACC75C5164CD7275AD784F2D6FF37FAC83A7C1C9627DA7F52B407DBBB1F6058C40A20A7377E30CF31C69391EF831FDBA2C09AF1FAA9A97020D0CFCB9B87768D2D0A022F7693B2C6D436FB56809435B576CE887B7233181451C0F76124B84D97DF996D331DC77DED47C63970D852095056BEE43810778C95B96849D4FAEAA090B851D9BD6290703FD7BBE957746B7339B52D4437B9421DD3776B2E6A712BC3301E68FD0C3A2DA9261CC2632C89C9D8564A25D38ABA51D571BE57C53685816536C5038159198DF90E2B4AF9E93CAE5BA948165A46279F1835AF6AD7407DA77AE06645A3711D262B3D37DD8A9D6F419F0A74841C54785AD2F76BDC98B0BDB2CF287BFDEAA9086C459192BCE4D34FD118FE4ED082AD98F67F96798945EE37A2B0CDD0F99A4C92E42851D3D12A496898869D531DBE39097CCFC0A4C232573C9F3646AB622C5968DCFBD149C7EFDF34924C709886A4304C266F4E940E0A7E046DC4E402E80DB82A874E7A5107F3FC9F5D7AD452BAE62A829A4D3B0EB35F81274949C57F9077488CEA9107CA2DFCBCDF020B8101591F4F1B67B3FA981D0821A47673C4F8C2D92A5E1BD2BF46868E1913FF637DF2A00B770D1BAAAAE0D52C3DB5039AF27FEE018BDC96143073157A08A0734477375B7C6BC7465110D4FEA768EBB37761E35E0D9ABF88689F615C147A7BBA2B29F135B13E879DB6921FD041F185AE7997644F46F185C4501963522DB385115E817ADB3FE9FF7B8FEC793B805CF73937F1913031F0C2EA2E5261C7DC13940158F57ACAF3391EBB5912F29F8654F09D10C76ADB04E7EC4AF18B5E5180DE73304E6074B5A7BC3BC6C97C1C7F2123272C0038CFB1EB355674A14C3C5DE5990592DE1D4A86B1BF683B1884D69E741EA9F394D3027004E5A7E2AC7E703FCAED452F78E215AC665142E5B3B5A4D7EEB4B5B08B50857E85385D2E19DCB5A29C16E32DFCB75EF4AA77AE5DB84E5A5F861AC1629C97E4403F4CA948AABCB0FBA0E9F3AF1BADEFBD04DE312018AE989072CB743F353502CE4DDC7665B193177DFB01FD93076641D037AC8316803B9681AFCA01002B0B6A8B3886F959BB71D9912BAF99152118B2A83F214B68ECFB6B836BF0F44C8BF2A8CE7CD81477BC752BF2EDF295FA51C46D1B528D69555FF46CFD0BCC0348BD1799146764CFB0C851BFFBDFE200A0C0B077AAF057C6E483667396F3B7689193F211081E069DDA669A4BEF6D63DAD5D7D23AB6A976AAD27DA67C2ACB9384F1BB9CE1B02E55B1CAC61D6BE4C279F87628CAE6C8FD584893A875E1B1ACF3255437404E30E96376CD091C18E3D4268422852C0A038F1ABC37FD032E27746BF00C4358FEE868A5ACA9D74520955C10CF36258F6162E595A70D3E5D68E4A2BEF6BEED7E04F85411373937500DDBCF88CA8B384199F5E693BD69C0EB9D74674C35EF3D821096B872D0E091B5B4F13115445D286271B20EE2CFD6D2FA21EB45CA8507A71FE7B9D8E481C27D73A927AF82287AB82221B9FFC7139590C55BBD37494B3446229F233FDF74B9396DD89E2AB36ACDFF9A29A1BDB9ABEC9F9912CAEE27EC98F1CA99ED53434F180FF77E8EA9F9FB915227A706FE9CF012D6246F8A44D94A4F54C702B14938FF7E6870D49EB7D7EDA2957E4D0BA4FD1AD6EB645DC0EA96120C4A3C11E469B3189F939F39D9EE8B0B84D10532D1BB0CE358AE06DE63F880A338E9563558B4CF8643058A4D98DC1D508E9BB5338C7A5872BF3BA6F832248E58C3C76CAE350F33D0392BD365CDCA382B044A1711E9A3E2BE45B3662FE0D0E3D5DC18EA4F3FA02DC40B61A7EB1B13E49AAF38426ED5ADDBF693E046DF73A4F0B2E351A67B335CA63B850BAEDB4ACB369104BEFB192A3B5E29A4D7ABD2E27EC436C11C8305E370BB49649B66B7BC20A9C8C8EFB0B6276B7D2E46BE86AFA936C98B10D7B34CE3C025B7B6AADAEFCE6D1084E9266882B40F035D147DF5B169DADFDA674607E91DA77EB639C0C3A6149E0E57E3478CD79DA24FDB42F3C0295E8745A2CFD84DF6E886428001331AB711954B5ADC1FB3F3EA9D00BD8301B2D030A372981EFB155DA2172993FC8C884A2A1B43EFA3884E142CD191EBE56519E0D79FD5417D8ADA61BF7D24C1C12DB5BFEDAE5DC1B14E869C7106E4812B7ECA27C845B4035FEC5487507EC61EC899C010D067A41BFBD9C3182E76C79B2492BF6AF4D78AD413D672236432E243DD87BA8BA26C369D5AACFFE7DA458865A8F596FD24E740063F57E1C5771A648E8BFFA222C33BF137D21B967D69316B3426E4E358A08294E7F13FD129C09A8E424E6B4A0A2E39930CFB5E201802DB7134D0E005808B3BA43ECB843744EACC004CE159456DBC3470142C103B65B0F7F7CED63E662EEF1F7493E65B950C0080ECBDAA56E209CDCA1838FEA248BF98945EC17E3190624F27C5252C05F9DDEC36EC7C013C99C996A68DE737A9E06EA1F263EA3D1EE8F4B959F44C2B74C67BD70A3027E6E5EEA6B4C8027552F29709CE9FE5C9F26964D0DBDFA765261C9A29CABC89F8CDF712679DBC1DD80A4F676EF5B77B219A3E5DD7C9E55EB014002CBA4A66EBFF0467BBA2A7AD6CF696AD8358C0B819FAF7E7A18E896E6777BA299A8C3B20F20D7AAB99C2F524408B6A4264B2062D7C7E6A0DB8DBDD9C0446A4188FBFDB6ED002B2807F0997A68A2BCFF67A49BFD008FD6AA129053CE16907D8AED2896315ABB3683C7D0D8C846658EEF4719E3D763255F3FFAB2602C91CEEE93B698F738FBE3EAE3FF48CB0D48910F503CEF3FC054C006EC9181F0A6942716EB982565B79C9BB03AA05005DEC009C234A69D1F441B63FC803B59E9FC4AC22D93EC01685397F7C4BB6FCAEF590F272DD1B85915065B4E2C6103296D1EA056D843DB35387F3AC32CF2DDEA7710936A692A78095CD01D0CD5C8F0C1FACA6B7495FD1976BCBC5A03AC39F326B4F2877BD47A8AF5A35B1C256196C9C1F7D39C24624CAE958F38ED815B5E1D2979B900A453131DAC0D6C2262D33026A6F9F047DCB0AE1C4A394EDD0C5D899B03DD4D5875768D010D1640418D96ADC7CCD4233741515662646678C8D0EBEF094669878889C1D5151718275E9FBABDC02F3F5B617094AEC716182D3D4E5B82A2D3D7E6EDF123415B98B1E9EA0005101D252E36434A", - "reason": "modify message" - }, - { - "tcId": 33, - "testPassed": false, - "deferred": false, - "message": "FA8898A19236FEB6DF01469674F014833F997380A917DC1C6E03E5A1EC1289658134E16DC7CBFD745A08AE0563D530DB01B097FA23C922DBF5606D90AB58BE8D06A96CA5CB1533D6939749CCF2D17CDB9391FAAAA0900FEDDAAC82FBA2910BA4D4A1D7E0B1C46CFB5A388A33B7FD87785B1022B7FC922FDE891E6A37108E0E1E", - "signature": "2B0316A1A52484BED62083ADA27B204106F7B0E5717621088E95E2CEFFC2C83D91BF58ABE06B2F1D6CCB15536A49CEB8C1E611BC67DC1AFE04859CF3A714EB8DD6A9DB990A52E0C85F45602A7532EF160477BDC949F303FEC13D400447F6B2EFA9145423153D256F9265F9A2148066C3FFC8E028CC28A10F80EC6CEE2A41C5A0A68617F8017A373CD45249BBAD796032071C12802705B69A9933CFDF03B41FA973497E50B65CEC5258009C6D175ED9D892725532568C2D3CA4629301D718DF3F06057D90EE59F7FB17532BF7CA8FC7F2A9B570C2538384F0D9466878889E53D2BDB9DAC3FCD7F944E7FE0F2C098166D3F7D0AB82A670EE15649784C1E91F049EBDF01A9CB236F62BE5A3EFF8C98CBB4C22ABB80EEFB7721BE350497F199BE9DDF7A9473D79E8B9990ABB9778E13DD1EE2BC77B0CD8DFAC9D43B29103CC111F4BF00198BF755C96FCCA91A97B8CC548800EC14D4FB55AA816FE5244B0C2AAB4618EDCB2DB78B2B94A7CBA1E0919282E467328BED6FD2603ADA2B8ECEC7295055D68599AFC01B00AA17F03D85ED47783FDE403368985C919DDF4D4A32F83DD1A1A18F72A364E2B9ECD949173D05117C1B77D79AFDCE6696A903C161329BBC75E353EAAFCAC98BF9323D5944E22E8B2610EB65E18CA86A75CC5AF5B4E499AE5DAEB82BDBBFEB219AA245FBA3593CA62817D3BB254086353E3C8CF1563B9A2F4F038ACCB11460EAAAB8785FFE3EE2EAE9CDEF5922E3EF7493307E1F7EAA3E9D535E7CFA480AC009E4F8C3FA64B985DB9148246E709531859E8994C4797753C5E3A572FDB73784170EF3CC7643281B2742D3D66726265B1D54717527DC542315F57D68394EB0EA1922C9EBFD58E2D61982B6645B79F446C5C1389DD4852EC268B58C2A8B12E644FC4F504E06D6FBF74969600D55598E9046F3FC227E91AA8F03ED29A8276DD55C60617B0AF63AB1FB7EB8EB3DA92C603C10E2C1E6C5412AB9CD480162322C74FFE3DDFE3D7F8D26277C88E47CA2952C8743D198DEAE2E25458CEF20AD16E1AB346626A9A5DD8371B9CF46F45DF1021289BAE310B71B3F8671490FC79EEEADDCF190700140569281F89BE21D0649417EF414DB22CA11B61CC54761A8814D722489883EC63ACEF8B2F780A36689FA8694807CE9685224557583EA556086B6D2944E20ED98C67E30DA8741FCC4EC6EBE67748F7F324A8460B7E65BB9958103688584DC9662FB348D17A7F5AEA853E2B5EB921283FA40626C67ABDC74457892B13A34EB8903EE47C49943CC9ECC002A65D8E91E9CA799E799B7ACEE576989D627042722465CCEAAFD6A10CC64DC91EBDB932F21C76932D5487EAF2AFB637DA0D66A7D5AD87A4AC4DFD430E7FF251E3AC9D5F87DAE67D23D93DB777E03658A267E838CD5E6377DB8FC6D2FBC0208470334B18D071CEA90C2CB75FABE46F4923F4B9BEDC32C6661BBB72B7A1501E54C17E44AEBCB6B5C89C3BC7A939986EFA1660277570781F2EEECA7C011102FF10FC3EF87312C89E879FBD380FB42DA15C989FCD7420E047840AC1F962E8A16125702598B36C4ACFBE43698E596575F4DF5A694F11CEABACE90B2E25D05740782EED193E660B2BE926F469E9D7BC73136704E133E69338528B52782FB820946FA3CAEC5C695053BAA341AF58F4F9C76A13FA7C7DDBAE9F9D1EA34AA374DCEEC010EC3C0A67F383EB2758F2974C54BB94B1A9A4F8D18C959B02EA03534CD473DA2CDB5D1A73EA507E6EA85A013942047DD8DB96AEC221130DA52E1BBE8BC62C5A726845E46BDF7D4FE685820D4712528BA4442512A7927503ED61BA21546C24D4DEB73F6FA2DF108988F73C62644FD0EF8DF5CD9CE9A94E019174429BC32A0AD3D0F9B46FC07AC4D674D758585B31E1697658E55AC6113C23674B7B5C28B3CAF3FE20CEB0B6EF8209A35E88C22683055D974C2508B42D1171053842E8911882B0CB1828449B691D48363C221EC4371F9E7045FC376208358368FE803C7B10EFB3CED14957BD6048585BE2D4D3158AE3249120F8F0F984C317E2F76185E71515A7958EC162A07D9EE3805A186CB3DBDA4FDC27E70A9360019B6A5E2E492A8ED2B3736F7F0601FDAA1FA00D91AEE2E6750240176044194AF9C2D2BBBA8DE2EC119324BB41B2DA37E91EC4A772079C9DFE91DE77A6BF7822454C63FEF6586B8ABED3B6B8EF74D01AFDFE12CABB27CA898EE3758F429EFB2E6037BB08CDC19F9870347B246CBDB960770CA1AC9F6326644CA4BD263B85D580B7E709C789A0E96377FF53E94866F59728116CC11DEEBA5B8BB3B23FABC13BDAF3439340D6E5410DAF61F091B7BF37F2ECFB381F1AA0C059BC5CF4119E6EA004136E5657CF4E6A0F35C27D5EFFBF3AA59AB62BC4D75F0EBE0EFA2485B4BD61D83C2BD4FD2D52B0253673FB971C3674B94331216B5C69DB6C256B4F5073D4CB337E76225B26F4E13E70606177244644F18F8C8C0D80A64801F4A52989094A5D5A658AAD70CA0CD71239AC55C75BF8522E0FC36C572439F6C62FC0C56861F966FC9CD55A75E55DB5B968DE2A1D5F4832C601D4AA438714D3A9D7549E854A1A8360B8A7E0E9FAA042883DFDBF8517DD90D7D68E1A18B5AC9569848C69DD5A9E9B117154440CCCE5D6674AF8A2DB3FFFC651F766CB54BB2FBC1D3738401CD826991AA1F5EB0C0803BA752B37548864BC2D90AB0B7C8928BB46B88181697AD0D24A0B0D58341C9C6D77D76094B07366429E8073BF676918E5B0188A28C5355355DF7D762B9069F4D65466704DF3BB1C130D4C9DCFC141C29267346387855DF49E1795BE70BCC3D3142AA11B99AEE4E1B71550281351FDB294D9C13B075941EEDD128448FCDD246656A03C7F8E54118417656D19910C75DF7F96012F0DF7EFB2094AE54165EF8350721ED25E54C2B85659D72646D07F3D50939CF68DA2C85C1C45F36BA35A70CC5F767C67FF8BA5EDE72A8E2664E06EA90FA5D964ED2B3DED93A7F005F930ECA1514D4231D057278BDD1868613FF69D0B3614F94E73F93EC4DA38255357C6A37A5B9BA515F3DF427466FDD40E3B203C66287A26605182E44BE3703AA5B09105CE43DB73D75FFB35ED95205FD03107F5DEAB124EE6F40A1EBDA6C8E78C814FB18FF5C7917F0ED173326F0A75B00A2F001A7607D661019F7910E928D8D2A5EB8BB099F5D3BC09BBDBFE3339FB59678A6AB56D8A5C7AEEA30F08CE081A2BA3B0EE91D3A7CE1133C7552EF3B31C828CCE11D5E85D136CB6CCC4015AAEDF2112DF3C8913EF467F658FBF2820703AD702752AE1908366ABC429720080B53C4D8C0974D0C4DEE2F82CA85D4C3CD4F81232756853F5D441C8D66FA0A07519689DCB52DE3558E1E974D59FF93DC9431EC58B22023B010B1719C4DA8D60E620E979B4D37CE3FD9232261A9ABBD1B9EB651C40AC920E30792D1CCD51C848363995D4D13567F38F4C194EF00394B387D87572650BAB9591433E4C17E98B95AD927A124827195DDF3BE73B8CB9B4A0953A3D318065A30DA3A053E9FE93C3CE0E9C16AF2C8D4C808166877022ACBCA915954948D4D2DECE5946558FA0826C5C95C27BCEC580983C1DD5F11757CA75580A333C5BC839FC39F2A562A17B1728303800949C5C942968927D6A74897E0806DF7EAB7446F02277238E93EED246C8DBC8FFBC177CCE02244253F5F20C4A344900AA3373AB86E0451F2D7BD8B79FDFCCC6E038158CB12FE00685B5ED63396E6BE28283607B0C71FB3C20F1CC1D1027CE4FA53091537D46A7DA3B942862B1E713C1B940B9FA35C3715949CBFE0684B9F15EA436B84A867CA6A0B09A1D8282F6F9781EF5E131814AE55BAFBF243D8357EDE772C78A453AC367870F794E8A707BE4D4C1B6B5CADBB4D3E5A83F969BB8B928545869D93C0BDD184DB99B7DA1B183D4CF97B3AED11C1457F2C491BC8ED64614891D3E9B7F76CD2241DCEEDB9DC2065A905CCE77F24304581F0DA12434A6FEEEA6EE4E7B35160DA2BABF535398E4501ADB0E70C422C910F3DA9F1B0EA247978BC6BC47DA0B3FC9F178977FF4BA4C178DB0FE55E3FBC2B9D30670030E5DAA5804710F685A3CAE659B0624336D078D839E034C7C02CF4083B0DE9D1079D04C834A01F0D4A6B1C0C3D1B99302ED33ECD71476497A4451E81271562DCF28AE7CC17719E50FD6AE47BBF2C6684CE651E739EC6AFE0836395179AFBB65E78E0213BB243F205020FB39E83B16E43CB6DE10BF09AD231024C2D4B7DDD17FDBBDD3C4CA0E2CA035D959B2B6BF8C9CFD9744EBE1D76B6C0F7167EEA0ED03B12A4622C76E36DC1FE53364CB6AD7F516649E03C566B455A544DD832B2ABF6C3C6215EBBBD82A393EFF42CB596DCA12996EE1FC150E6AD01951ACDCA4EBB12059A267D821CB969A78AC2AB7039C49411D462DFCB628C24BE48EADB7988E53ACDBD8CC1EE9D9A32213AD77EA9AC7FFDAB0DAC119A69436DF3C3E8B93B6A2C300A46A56E852E156A3132F4B8FF9DD85511F592B8BE20F0A989E6F74F6A9F7AC5F89692FB49C784686E7A644ECC984AA45E75E2F85542346D1CF6B6B48F699D8A945E6B601435A6936E40B68F6DB3D2E79C5EB16A86980BF7E63D49F4C16845F5A42503417372717E9C9897752D256DCCCC466003301A5A249A06804E261916794DABA8506E796C14612E5AEC53A76FBA6235FB32EDC41E1E46E70698A02456CF28FF289A980731F76376B9A8393A41043BDFB141AB7E3C32FFB0E1F19EC9E3480BE487C06F85BA790966293102EB56A28E0F33BAD28F66CB988DC56954282A0AF25B338AEC84729561CD7553B5686A98F3321635CA0EF6AAA82CB6EB711C272A041DD3ACC5A9FEF21EF1AB4F42D8C197F604D8FB8E1989AA8CE75300A9AD43FD97929FD3EF816B2123C0985E736A65502E090D4DCC6ED5ECF040CD6D0A131562B9CC185DBCC2731FE88B900509D45F11756AB7E3CBC12085C23E272F5534A1823D8C4958B4C376551526874DB9537056F254E04639776EC75F8E78DA29FF55EDED2885A855ABDD56F8D086891E04870F8E7DE47DA1104495221C25E13B5F5E8A4FE04A48EA5CCB752833B0517C25E9266F3E33FB6CCB2881D9299EBFDF82626C3686AB4D4C3F32E6C350EEB0217057555330E86A414D2814EAC14368580D122CFA2D90A211F2F84B0C0C72F30FAFE87CE30D55ED5C23D71FF8BE34E83DEDCA732B850505154375CC8E5EE7B55221956FCA214FF076520F8807C845793472CC5E1B6FD2150AD626D2214B7541B9FF9C26EA84905B201AE8BEE42224530C5F5ABF70649F14A0AB94BAADEE25A54523A84C1E94B75F0D7863391737EE79034CD9F2B7D8114C1A6A889932A9D0603FF80996E812D9C40296B8290B479D068A01FD76405A3A9E684FCE29E31036B3904F1C52149286FE9393B9B1A92074DA5FCEDE5478F027ECBE233053A8350F3CFD95675FFE6D13E332E079DF3CD7682A9384244A7BE1932ADCFE3EC87E212085E2C5DF0872868F71DFF4C9B6EA4DC82C501B62FE51A15392C5133EB156C702DA9B7C9EE78DCFABEF2F962437387470381B1B8AF784E362103E3BFD6EA7078C0E3815E207DD973E7B5FAA74598890EF9D992756BA855DD6586DF4E3830CC87E19D88C211740A10F1E52BD14A69466B88C208587846BDF4BFC2F93FA11910777B98E1AECB26F8369EA39089A2A462E042A701038D5AAEDCCD419AA42C1579625032462DEF31C713FD2F70019DAD7C11C3BF6D2250472FC9850D9F638430A225F084117B28CEA4DFED04DE202F140C5196CCB78CA80307D28BF0F8D052CD3744539ECF6B1439E670E90AB0C8A89DE7063C6CD0C9F51E3ACB5381307AE13F077B21F32602DC278268F375288127829B6A99CB57F9DBFEF94B4F0BF268C098DDD397F92A8D6DC346AFAD62D8C49C041B1171BDC8E979717F0062A1DB8CBB75BE61CB1884284AC713B8318D917451BB899491E7002AAC371D620FC194529531E930318B7326C5397208502E1B8E5548E2C09206333043DFCD1DA00B957012A6FCF67ECEA3E4161DB05B6F7F88BC157E6B68F09C4AE22C6287124581CE5751EBA46FC893A3A8CB274900D6B4FACD08045C07B9F4F480B8F9F7419938ADA318B1C85F89FE2A64D683A2509FA3FC90C25DBEFB3F4B344EC2D1AF1874FD8E67E0BE52D322B5BD8BA228E088A4590CD7DEE5A534CB622E4FE35775577E7E99F3DEA58AF2D6B0D80E9319F4F9CAE87744FBE2916B53BC113CF778FE9CF7361681369C92037F38E89821357ADD3690D5699CE580D920635A11EE57A772BC78CE4049FD793CEFA69EBF4CFA4A53C9EED3540F1767885DF1136F46277EF6204AB948536F354D7935C05DFAA14BDFD49E95A361D3F7F0C2A388B818BA66EABC8F3D7CF9346EE273E927609FB253579678444BD3DFA5B65BC394CFC8DCEF55430C358460989FB4B7323D415CBADCF5F7061C2E84A5C7EB0AA1CFF51C233B71999AC01D3C424C7F9FA3DF082189A2C0CAE4F837417788A7D0DEF80000000000000000000000000000000000000000050D14181F272F36", - "reason": "too many hints" - }, - { - "tcId": 34, - "testPassed": false, - "deferred": false, - "message": "3FD78CAF8DFEC532282C5DDE309BAF88CF1E58ABF79342580853DA3E886E218B8CB1FEA5596AFB306B18624D076699BAE4759CCB551C633D7CE619892F304B8B796545CA5594FD6BE9AEC85AD1BE3E22DC0A6FD3F99AF1D17C543957D5E5DE3373340C468876C45448956646EEDF92B63DEF6F0E64BEBF85ABCD401AE846014E", - "signature": "CE15B9C213018F31DB2B8D42292558C307CF883C9AEB567C33DC2AB94F9493E9E240BBFB6455308ACF55706DF347E55CE50BB5A80FFEBE8656F5EA7D816F6E996F4FF5CAE356E5D0716A959BABB4C100919CCE60E507CFF07A1A74F06D3D3C5232B11DD93FFADCA9C2DD5E88577B13403648443FA3F253283CC6C827269152E1D47E5CEB8B325CFDBA80E7AE03195AB88DE4AEE19E82D6B49F142D05D7667BECC32CFC2EDEADFE301EA4F545FE335CD6499FD97D1E9F7EA4BE9F93E14DDB2B41BB2BB2B30F7936D9D75E89F3C6665A1E12AF364848B24D0D06B2414879149EB3D1FF1209DE6A775986718859E4284FFDB444AE7742130C67761A0F110552B8881B76A2CF55D45474F6B97D9D2C936362510583AD9D9F1926CB26FD2389E83E6FF57F5A0C8E48AD44E96ACB402EFA2AA35ED468F88F7C49EB713EC6A2314B74A108C51401407BF5AF0EEF3DB6FAD8A4D6434B10961C7E7B38EBFC0E7F614A96499AE811A281907780FDB57CDD94E55CD642D47EB5D19126E508C625C8AEB4BE0ABB29BE84E0D26062C6CDFC93424DB3F4097675B14201ADAF869AA11AD2DD500C67A0F2B6C0563B671F54362B81F9592544CFB080C136943E2A15DE2A1F9FAC863606430B077E65F9039ABB52AB3761665059D22CD4A626EDDB9D8D63ADAED7132407064433052314A61EC08C3E83117CA167F717347376F85BA787877BEC7E7319EB06B85C3C6C85EA04E5CEFECCB877C87192E4FAEC471356E62234D16039E3836EF4999E9AE3B3E6D9DB5ED5915EA84624FCBCFDA4470DB4E0FE04BEB93E769EE2478FC47D61D8FCE62B7ECFDD20CE74ACBECC71A493BAC2D17A11BB47FAAA1AD17CB0674B93BC7FF771C7B952872EC789D70FFD9C3F0976C9E63308382883167372082A9559F2FC190AF2A8F6861F9C6ED86736186114786DD07711EED8699972456D040DF7787EA7883E8C7EEC9B0F6AA56741B20817FEF76DBDACEDE4CD0A7CB5F52A196A03B382B7593C1A7F84985E194371646A7AB40EA98F7AF1FA898E118616E168F5CEF1F09E3E72A8DB311DDB798459179769FDA5B9FF5E05A4E072703D517B176610C3C585BA956CC7568A94DDA4733F054DBA2D8DF3CF680B4616B92BDF1E47E274E4E4786B428A50D852E369A7D109DDA7061D44118D0E826B1406664D7BBEF49A26AAB00F66513D342199B6B66D5E1578FD7177E4AE2F7A45B711DCD800AA22B6D37FE2B376BA07E8B50BD7DD7D5558E46879DE6BB9BF453C329BEA037291A9CB05C32655F33BE34FB5A67C54FB1E131510D3EC42FD999FE54193480ABAC2F162A2DC3D7D2FBD5C8189953086E49B6091AAE7C90F242EAAFAE9A1A47FDD0F7306140E2A2458CEF4840C8D76AE4E0AB27BCEAB5195DE1D76EB2A89A12E67382A43E97AE4C194A6664AA9A0595E505A176E297D11B67A3631560F7585F5FA87F4A24B3E1E8CD72E1858857F988DFC310771D3B566891EFD357F79B075552E341CECBB22C95AC56C490DA3ECD9F6724BC12AB1CD367394B9EF1B6067CE85378E47F288F3DE8081B51157D9003F7163070FF1A8CEA914F0F8374B645D71EAA19B0A8C239A00F66F7167D25E5D2F3B0C250CF0AC0441375D0EF6645C4C0EB2974A712083D415284DA2668C9E3A0C9CCEFF736C1CE91ECFDD605CF3DDAD2631E3377762516A340D2879854A3E3DB98BE6C5CC57D404EF04DD86500D915983D7288AB095268C82B1BB032354685A003AB8D7784D77B061ACE0436D60FA17AB4B4C14898FED46B645CC1716B5C6F2294836273EC02F51F839B394E37ABE7BC14374F34CD3D3EEFC57CE78349D7F60110685D8327B605FB975BE0EC83A829743615D792CD1DEFDC4B3907B45C74E95B0C8472E282C0D1CB6D571D5EDC39D6B868423164ACC8E418DD01AA445C54DBA6DA0D90FDA6A1DFAA754DB3D4B544ED6E323EFB271B8B1CD313A118FF0BCF052772ABC2A792F629B94BA2CF4F7C6A882B954A1A52A4CFD204DF72D858E67CCBDD659EFC73CFB2A1D06808CC0602D264FB763C727B6C383696D10BE807FB665D4CD4D48D916515C590969BC6AC969062B37D6496463D7345C556CCBD2204211B012CE12C989B36E4995E30CE684500E8ECE510BE5E57BE0867F7184A6470F338001D490DA764140E93211F20990A4B7407F371CB04966FEAE7BF70F667383E90FF2135AD36718826CA1D86DE281CC6D9F3A848F2A30B8DFFD076683FC1B4667681EB95E9F310F49F36AD872EBEB6017A3451AC8F99F2334FD010F113D8D93B5F9F9DD7962E7E974DDC914CEA28ABC229B999311A26B856185F0A1E61872C11B21E79CE77755FA53E10B95C48FBD4922AB984F953618C468AE496A4525177B9F6D02DB2C997785ED70DDEE07F4768BC9DAF9CB3040F02799A37E768EA6E50A013ED4470EEBAC3530BA2CF02286C49A6604D82696141FC78FC26C841063A7BB22246AC262B17DBE0DBBE5BBA61B0FD441B3C476425DB857813B57DDBC4B704884C36EF43A96B5B265CA557F78F885088B201A86A18EA573BC66BCCC43C61410531CB769C8C52DAE25E49FF58F06F63BCAE458DF6F587B3BD730C81ED9BBD0C408B04115A246CD3A0458A782FC7B89356A665D24AB0BE5A5AC84E2514A438353654605ABFEE00C4C4DBEA70F9EC56C063AA8A632FE7F6A161D3D868CB7C2E8853FB79D36AE27232427E3EEEC61A124E3296067C522D7F653698FE6CEB7BA6CD37CB9420BC646610DA7C9718DF4773380B78877898B799165FC7981B7BCDC9EBC2F052C8949AF88E3A734909D76D63403BEFD144456D895151B9FD53E815C38AFAC6BFC9D497C31446ED063A2EF5A30EA3FA0DDF3519CB3CAC529B8845E6B3598088BFE64F3EC8BC7F5FE16D4565CD1A89C3F5BF38AF8A13BAFF9E96C12EE28660E5DBF519304EDE80C2657211ADF4181A96939887220ED4ECFD2EC68F04DA8FAA38CA8F01D69B387C31E28631EE7BC69C8949911E8088593968EAD3D704811352529D1A6F88A9859A347EEA7F3CE7A36235DA5D6F532F7C46CEF41C4A1EC738587C4065323A1D88646618896EC0A408B524762A0EBC2B1D3855E2631FC7BB9B5AEC0DB18E2D22FE96A36146693E32323292CD7C8377DE06ED17493B891C0B6475B14C7D3FAF7ADC40667D98230E7E53C9B5BB17BC07C14B8806347B81583FA6FE095BF9B2F735BD3D7CF8084050599E39D06D95DEF74D63F641F90C3BD73652137B9676DB23876708D4D2A8554A8BE9739CF0A41D881252E7C543A89C4249CBD8FE11754135D0B61D3AB8772D3D0AE720D31AFBC1FF259B5B59FF408DE206EB289E6C755707B34C043E58BDFDE1ADB74BE2F17205836A5EA327A6988E1E5BAB36268ADC09874DE034FB748A32B23FB1C8C2A77DBBE9E74B9EF421A91F2D547D8689FA0B846B861803AB7EC9A8E671E886BA211ADC67BEC738C020F6489E9ACB275D88A35507BB152113EBBB94CC43B1E2C2392009A3E80472883EC9332D30717C629C804C6586F36CFBC67C0E29B61010A2B7ED29AF29D3485B2832FAB942516810147EE31BF37B332FAC89629050826E053A0B73BADCA0F26EFC9EF0A874A1E788BDB78E8104BB56886B9D86CDBD7731B76AC7FCD719C76C281A3CBE011B1FCEC4831A173FDAB0BDC1B35F3A51E0C8F7BE8715FE4AEA8590E6F4BD96BAC089BC8AC2B2AFC20756056FFA184850C89E8558E1A552801FA7D8BBEE741BBDE30BA140BF66215AF54F282DECFB944C53F525CCED0ED07B747270790E7CB54E9B8099639513792B374D3D378013F558A608B1FC95A73F4DB92E692D5CB72DBD6AD7B4E28C2FB0949ECD3A2725AE7195655EFF289E292244B4C82A803349C9210ED23EB343AA7807F5EC73161F4370B3C1B486E6D80954021A23A492A4BB594871E24B8CC5C7C037AD8B76A5683D63C262B363DCDD6351163838CC5E0F4D6F287D773AACF92A3693A8431BFBDBD4EA5E6DBCBAAF34D66643F5D4593DF71A2AE95FB23F72858DE14941D46F3CAA016F67BE716C30A31706798F2699BEE4F782C7A9958F443C5F7D7D8649A62367F138BBFE49208CE94626C923FA6D2E5A8B6701C6F7DCCBE70E1605EC4668DE789FC6DAEC1B5EBD38292091AADF152DDD11BAD0430831D0194D1474A36148296C0898F85C945E2DBD55C92DA90711853A22CE20DD71B5CBD12057F3C00D9EED62DBDF3CCD47251401EEB7B2132E52864622831A43FA10DEB7D05F96E1DD1BBB25648EF8524A03D771AF597CC2D3A6E75728FC9E96357CEC06FD5B9EE31D728D8B6BCE4BEA7EC0EB5EC9206B746BB494681DFAB5E95C62CAED2EFCED1D73CCF3FB61F976A874C0A534CEC525D88A7EF9EB6DA892FD76C1F56E400374D58343DA6470D8E33BC8920C9C9364EBCCCC2F61D6E8ACB005567AF19DA5930514CA8ABC226DC94EC3258D580C76ABAAA2E21540B77FE5B37D26EFFD315C8C5455EB87FCEE70ABFE5B964A7456EBFF0A97398D55AC07F689FD7F1BE9533168643B901AF791D7053E706412164E0B33B21BB609DEFA3ADF48DBB6B864E260264E1B22ED8B3C261F8FFD3660C18FB57DAB4010485A48D6FDDEDDA6BD235807227463D2C1EEE1F6045063778C46EEB7C1CD0961E84F034FBA850A462BE09BA88072476D71CF86B4BFDA5B74793ABF074FCE7F8E9883469EDBA7BCDBD490982FC111F47A3EDA59726A772AEB7B60B155A024244FB2AFF2864D39DFA685887BCE3551BDEF870BE953CF1E13FDC4EC645071A468D4E9881D27845E0658F8D6755611D2D4DEB535D6852FBDB1C2CF888F3F43FCD5EC9F6AE566FB1D071F60413C5C3B041D405C813DAE726DF6D704937709FC517670394E1BBBB0BEB3FDE7E4B1C4E0090CB18BF0D5E04F56A6955E859DF37B858EB68CF41BCF9D662B2CC6554B2246E7C949A52B2DB14A07318169DB3D9149A98DCE0E9474C7A17DC137B928EA370B78224CD5E06AF1F83101A96BD8010EFE450E52A918F77A9E330B81BEA98AD44053E20E40D7411B008E45F8C1FC472694AC85D722397AD6103E71EA955DC3750007A6AD3253E23AD619FDFA24C32FE8E22F6344B513303D7144ACE4C6EA5AFF2A41B545F5A6028173384A00E6A6B8751F0929573EF5F604125A43CBF6D1CD4ADEC7C61844DD799DFF6311A5ADE2A71369A80F91C3091135D37F2CC830B67811D767292DCA85F59E0D0C0E712C730E5D87987A35D97EDEA6D8EF10AF7462F851FC2901444EF87BAABAB761A5AEB02039F87E5FE22CD23B981F6BE4E7F8C2CE8333566040F9B34D3C097BBC46A420449844DA66D4E9AEBC1A91867378E565DF288DE5FE2B8BEBD10BC41535DDC5286EEED3DC4F729EF65C04CF2F1F920AD4C41B624B5875881F574C74E92132DC2987351305A3985686BA43A29498391BF5542EC5E4004D50D873EA41A8D7EA6F7D9C1641932E7F65731F7E1973FF13D21FE2412644CA7C6DA082AA535CF36B0D7719FFC0FC7A401A245685CA950D2DE8BA689F7F0B270D379CD523556ED54EBC17C4FA661B898A842FDD0B2DF9D63AB8313A69F8E9E145328500C57031DFFC73A699AEA270383DCBB8CA39DF61C6C8207515F0EC8039A18818E60C8F7976CE0390FC4E02BCF8DC21D79DCE8CE9426AF9774315AACBFC38CAAB473DCA7ACCCE7F5BAA1054D2BDB002351C9AF7841CE683CEDE23B69B43DC83183CB263FF5183AEFA397057F66F4A6B665F9980218AFC96783B3AD24B5D277E65229B337A14ED48E5FA303173D10C5269D61AD43570C14DFE9FD6C824E81EB95CDA16F0B01CCE81311686C493F92BAD1FD5F210EC26660F983C5AD79418994C71D3EF5155924F2E3B88B137795310A1FCDB63D697FE085EB08130E69729CC62D846D0192BE9424FF15F4F0CF1AD29F967D7F85FE131D8B5A35D8281B02284EDC8D5207B822BA7B5341398CE0006AF2B466A9D1A7D9760E61910A95508F05EADE6C6F2BED17E68AB3F0F1A8E8675EB74A1E034681C80E757E7E69800C973B1C39525668EBC5C5910C071E2004EBB57F1C5E1FCE6D4B62B84F48A4FCD7E11C0B2ACB22EFA901C25B65C64EB1B95533C166AF4807C2994D374FF28AE4E032909C30A6FC5F445BD3CF785B625227E3672E5B9DF946DE67AFDF80FC6829BF207BD686E2418C2332740E2DDA4A98350694406222CF445028A352DD4934D1C1CCF638D3A01754E1337220271D9755DD40184CE4DC3483A4D568639BEF1751CA0AE5B7671CAD3F9FE5107EA6F15B794F0203C9D4B9AABEFF8151AD6B1FF3388B4D6D041B2C062061A96964972C3468A87C0229C69D5209F190DF30B61616295C08B7CD58FE5706D974E9B4DF522B600149CC873A3EF0E83312263E5ED4737A6ED2A827F797383BF86E2E4E13D0FB11AD8801E72D420DF2A5165A0839C7C4E7B3903C27AA7CC1C1E25F8F991562A2C62F424D536C9FD4D7DDF1F536384247727381A3B4C9D5EBF61B2227306F82C3DB6586A3A81A4F57646C9BE9FC617375801A1B3E728695AFB0D4ECF1FA0000000000000000000000040F1C2428303440", - "reason": "modify message" - }, - { - "tcId": 35, - "testPassed": false, - "deferred": false, - "message": "B6A320368AE214A12B14A0A9503171000081AA8631151D69404A1D77C6EEFC219A540B4F488D2EDE8C9873345244CE047DDE56B636C850C1F268C3B8C1A0399E49F2EE1E36EFDE5738E14F82D70FD10403DE18008D45138872423E26E466BFDB1A4B442349D1E395DEE4FC4A51C304308FA81E817B53E98D1538EF1A84BD3B34", - "signature": "C62E458802B7062014E7A44FE2D8A39A16DC699C777CE258846BCA2C9B310F8396814754295365ABF071321722F3BE06A000B88475F88DA9088F636DB974E4CA96F38F667C7F13674468A01AEC084454FC5A714A0CB39D7F29897A5D1B1C9E4741277D6A1C63F968EB23B206DD26779505FF7FC5B7B87F58D57392D077D62A3910D11A5E7B2E8034318E9D4004FA2DB0707987DC8250801F6E53C8E0B31D28AC60653D18FDFA33F846FB024F09C8AB23E15FDBF568573239297971F4E8587BA55A63C2FB1A115E62826B65AA28D3BE1D073F7D8B67FB14F8BC83BF849CB2C7B8AD00F28A8B841CA912FD4B66FB8F400E5C43D402EECCA3FDE103EBCAECF7C9294C90DCA2A0F4E50D79F143D1487C06C69E1451E9A47DFDFEEC9B8FE1D8C69074E9FDC9A17018A9BC0273472B9FC75B08B691071CDBE8937E4406C0342F8D214786AF0BDAD4D5B58E455137754774C699217AE9C565FA1032A6B7400E2B34086BE445E518176AA016F8C09FE716D14E99D7A710150E224C3F6DA2A6215C9B2EBFB9BD357D598D6ADBE0696D07CD2F5664F081284991CB15764E6407040C63683117B2ED6436237B76FB42E6FDB14A4623045DE7F06F52241DDCA7C6B3D6EF39B6C3A76ADBEF073AA0368E80162126403CDB2A995544B5CDBE42D256ACE987A714E00E9923F5C7D09DAD6F0F8A973268138CE1947E4CB248A046C51CEAB23228626F07D25D8EBF316D797EDA9800C25DB1DD0B0D0B57E9296A0C614D3CD1C585C97B88592CC6D545A202A70ED5D9A79E68F9FD6537E51ED5D398FA0714B4179CBD0000B6EFA21F22E40BFC9565EBCBF7889DAE85D47C4B33BC73B941E7CFDB48AA6E965FCE744C03705A9B143D625E8C7015DF83AFF0B46BE9C9F9A14C13DFA3BAB1F00F594351DCEE81D2B7B9D22867366EC613E621737DE605A7510380F83ECF7F923EC8FDF07B6CB208754DC248A26D837A34CFA80C8B40A888DC00BED9734E6BE19168E4CA7B63C0B6615E4D1CEEB952B8FAF481BC9E362BC888A0307FB23EAA4616FF00F4C3FDE918937489B920071A3215E50C90F97D1A05161E13C8AC4A08CC456AB0AAB06DF8A62465B085952EDFC787F798F4CB65A17198AAFE06E21C932ADAD45C87DDBAD4C76F0C75E28E5505BBF9FFDE930B327DF02AA154BAC08BECBCF0DAE652EB8477D96265D37D21851EFED964ECB9A72E22B914742A7F851BC5B1E6AEFF22B526DB0EC5F3A590E6CD4E177FB0927382E5928AFCCE04C794435F5B4FF7403FEF36CDF7DD0D031DF22D7DD302C48AF80C89BD06AE5B25FBB42842DC1E04B9B615A0B8BB15D532B433D9D639A76EF492CE89A91198D64A53B5236A5609BFC509AB937C41DBE42256E34C41D7B4A50950BE530F24A0131558A8D60F5F6DB33047F91683642FAAB6B0ED597EA7CAA29C2C04C536EF572E513B2B37489A2F71D7CBE73153DE907607420D880E8DA21BF6302487DCAA93B73B1DA8CDEE9833D50D5F8BEF6BEF33CC3BF47D4EA6310E79BCADD3AC02B76509B9D94B1DE0B3559867D26FCD294B09E5CF01192D6704CBBA94B48222ECE358F0AA0AC3F9FDCCBB5E258D2C94B8F8D3333F2A45FAAEB8D508FABA49E37A6C08431B869E6B19CE21511451AA6A6218A7BDA8B4204A615BC0D00C05B9872D086F3C28F35539250965639FEB8300F24FD29000B74904091E488159737A13611EF47E79A5023D6A59E83207C64212B16E63F5C6A62DEB6EB9B9CDA7422C531302D576BD19B8B551A4C72B5CB0179C96DF29AB63519D6C2D7DB08DDEBA95420744CEAB03AE8526ADB51E49CE35B86E3FA92AED98E84133B2962DC73C219CBF038BA12A3C3AA979C88EC7F3A218BB57ABD8DAAA9E2D487C7690ED55A89B56D834650CE24CB6BE05B1F651AEEE253C0D14AD9969C3CAF27299CEF38940C792A8C29464215FB9D7EBE90AA4275DC6D7CDB71EB2547F320F9A76D3371CCCB24174CF768D5A29A7199B25A9113067B430F9E21D3F1F1C699F8D836885CCC5C0B8409BD6E4E58FAA18C04B9E16E366DE282C45F31D61E9168D5D15D7AF3BCA6EF8AFE6CFB720ABB39098EA4956DE62C68167B0DB3BB61FC3EA185236DE3E93213ED4BECC992C7A2D03B60DBAA139693C79ACDB097E9489474660F140F100B9A6277F5168D207E15BF26279494B2CD03401939AE8303021652B44B4E5A6B6DFC1200E6F5D188A04EC407C9F46CF7395F16174314A65EC0FEF310ECB46F37CE9F5871DF22297A78B1321C371E0DE2A7A3AC7033C2CE18060E24D209FED3977198B3E025055493568463C0D0158C2F8E81084C16001091BDF93C144A7A96D463646438E0D18E9A873BE209B16A6DAB29569BF250D6F3193E6EEDD3DA2AE0A807A0EB1A124AE7F259EC6620ED362F91CF5AE7026628986B8881CAF7ED412D3A42E15F168AC443424E068DC5D5E9F43626BC00CEE747CDE4446BCDD130B015AD51F2999EF2A073C551EA1E0CC3791FBB7106487B9F9B5F735D136DF4DC563FDCE76831BD8B132921A303EB122DF714B9B3D9CCA5FE56FD2B516E24F4CF4869DBBAC1A39B6F727603784AD1D365459279320C5CFBCF86FB5D824D702FAF1F9C1F286FF3813FD1FBE345DE64BB86A22C981AEA10E6FD99120A8D6264AFA6FF5751D108CEC8B80583FA6138B0FD87308DEFDFC105AAD5A32A20BA3B677F49C2E838B279F7DD712C0C6D0B64F5B90456AB58BE58D39A9D4CE9DF6345729601F7E6848A85A808CF8D9FD61F7ADBC85E4E1311BA1507B002875BACBAD72220782465612FD66A0045713B0973EA82A0051768DEEED945EAA763660E831CA79CF6CA0BB396A1681730D0CE024F8DA6FFDC91787F7A4937A317DEB2AC641995A8306078D5F866DF5AC147BF8FB88B5BE36496C8AAEB2CDC2F31F77BFF6A5ABEB9FAFB8DFFB50688B49483C9F1834173CCBDC833E8D468E792D5DBB9D89BDFB8E4412B627891305D3DD6AC669835D215F890A9970A4E103E848258FFA2423C417EE2CF401AA53572F942CABC4185A712468B413E77A8F0709A134835298C96D2DAB39CE0AEEEA1C0B50D81D2F9E69ADFF902727942EBFB2C782D32D2F8DEA3EDA951F1F389C7DBD3F00D26FBC19D9432A6E1E2CE7F98AF8B121C72F12D30F98263CF53463E027830C94D735A5B90C665C634B57ED04DBDF1DEA737DB1B263A27A0FBF13A4FCD2350DF5216D0FAA704F72AF057056EF6CB1B773A77F749EE9F0CBB0C160A353B9F1312327E8EE4B62EED3B12273F28163069D62053E8FC3C75FE7BF55C66117AE91148470EAA9AD52E98250483B76C9AD4F116818123D49C67319DB33FDE4B3F7CEA47965FF2B0C12DF2BCC9A536A357DF98F55D06B213AC32C3B75852062A0FD06B59F5C76ADE0864AC1FE68942CDF42BBE083600EC89F9336415BE47A6C6657FF11EF8D39105FB7B30AE115BCBF652FED8F0CC153E92E2A94E8F2F4E123653B7E0DBA8D40EF586377D0F8035EB337D5253D4720713EA93E7BA1B15B67C488EFEA8C5364DD08424337709B2A8881A11BBF59D5FFC072A27E181898385139B4EC6173E88467E8969B37A6DAFF57E5FC19A82814DAA2DCEDDBC3CB45ECB397F31A3FEA34F2057AC1F1833E1457AF861AAB96B55EAD269D2BCC0C393D2B621386E653279DFE5DEE3C03578CAEF2263830DCF865FE513BFCE00C26E2E70C52E5A89ECB4D123E9F6EFDEBB554DD6BD5E976F6878A9AA726B022974207AB01F8462AEE960BBDB2A049C047043052C4D53E2F77901C0D6231B2DD57C13A0DFCD7A5A33DA7AED45147188A6A1EE330485B096BE54240BB0E2CFDDFA1A89D60609527C87CCC768DAF475F80B4CF778308E6CE9D4BC72DFB8213913807CE1F8891F84E7AA2EFD3B6B7B1F1F608625EC896A192FAEF1DC304505DD542CE64985CE1BE3A75DB797BDBD2B170823A3D0D49AF854C023CD37660B46292630CBBF8A7D60FB58018E627BBF900BEA588FF7A9D7E18DCE62576CD67320BBBAA31B104605DA9D8EBAEC31F37DA1AD5AA0AE36DF024425F42D72221EE8893E305379C593B0F914AC2E9B489552884AFD7A54BE57C02B9AC8622974200A5F236EF02B399B169B2A0FC7AD625784EAE3B59BDE0CCF8C3792746231EF45D95B111FA1BE3FA1FC5F6ADABEE9ADBD1C4F3098E3696268A317B2EB9152BC60B21480D59F9D182D8EC3D99FEA7A7164D3619A8C5EAA0860E2B1954B6A8A383B516D8D8FCC2783778CC1851459355FEE257350BCBB80A0BDE46FDEF9FB0333B430543F9BED2D9D687841EB37C45DFC1B95EA52E71E9CA55BBF9177E9A9006D6F2120C31FC4DC43AD1F7089AC54067CE468BED4E78FD09EBF5857EE9A0C99547E6F7A039F6BFB6EAF5331B0448BF330B5E44252CAF59A47EE33303D99E2B9D43D2FDF3B8A1E6FAE250C3A265C23FA1D20E69177940E55495CCD326B70383D646A461B197224A3BC7E22E86347D61427346CEBFFB734FC6D71FB20CCFE21079D631D30AB569A9DC5FB9465B7941AC1072E9CC9A51F7CA476219397A39340372988658C4A43B7865B10AA66627981D0AB0A6F73055AEBC2BBFBD9183930A37169A8EEA61158BD1748EA40AADA0025DEA687C4404609790CE1E0E57A9D3F2E3BE362B1C3F111FD9FA982589D86298D049D99A51F54F57F520AC9044D691394996BB455FFC7499514CD4C0DFF659460633370E4C6A8D945C017EEA65F944E77080206EDD2F0E13FBA76CF02D54BA3A8A35017F4E227978898E8897A6C1C5E3193579DC75EF5A729E2554F0556E4B19E67031412DDED19E8C6850811CEED24AE3D679EE9EA726A82CF18410838B5435E826E8AFFB61E7E524186D1522855FAF4123183822CC1295B0F3D722038672FB6A7F056FF9B06DED416A7B59D94940C41BD9921890E11D8FBBA21490C1C0F2391D871D19B1361409E3239FA7395EFAC52DD4D215B25858484A41B1919287689C2E93BFDC3CD3ED5DAA0D3D95F160C6EE888CA5395D10D8112D1DAA07E80E4FB0B95B6EDCA7576FF98D7B53B8C9CC09DB06753C0FA874D9B742E1D562AC911783B4EC89CBE7C660EF9F1E911C5C8D375B9E049219E6D330A8E31E0958D3E991F245B9920798CFBF43511777EC7816F09EE1E4DD04D08C4FAA9E59774A3F3AD9811C08736AE1D4D5B25CADA834C099AB1F8AA494ACB8BC04759224A27376DBE5A2E3BB6F6D5E95C3C86BC15058D95737925B2068A3578F70FCB62287693BCC05FF8594EF64386C81837AB40114D5C990C6B717FA2C6AA7C5A538CF7E0525ED93A335139EC7C5E7ECCBEE8F78D72C1873E994190502378C46CFFB435A39B2CA460713F25808ED17904BA5251DD5A0C8BF6DDDC8AD6FC6BA184DB52C16C451B91F717163F26D4FEF14AC1D1E837FB22626B12284568AFC82F99D52BE96B0FD3B11A76E6B135EE0CC72568789B61F1B96F43BF0B0F63B8971370E6D654D260005987C6667EAF75A6FA5E740892CFA84AF5C10C1EA2E56215AD3AF49E6F4F549644549E478397945C050C6A38832C4C750D64A103245A04ECC50BA1F3E6E306E19168F29C5967F0AFBFBFFDBD0B97429000BE3153F530AE0ED22AECE0EC84299AB8E5097D65CECE11C497765741350C43BD85916F140F5616C66CAF8D7AAC20BBF4F05ED44703149E68E9DD28497A8CC8DB4E3733F3D530AAEDBF57DCE7BE717F63900593E09A55FE30C92EDABB3B96F698340DEFA02AEFB772ABDF9DAF216D7B4A4875CB6B023500CF11BA8DC8CE9D7C3E8C069C5DD1724F0F9CE07BF1B28A3211DE569DD2F73C228CDB529D538DF444972D04501A8545713AAE4095279C21AB2D332C8A70BE4A9B5DE41B4FCFF970BF35DEE2D9C899393C1D0E573D248AEA42C6D9DF7C28DBBFF23FDAE86140BF24B4FC3598ABB00605295569D75CD92E4B3655355D497CBE7F7896B9867B60033CE910FBA168CEDD75C5B369B452C5FB8C020FAC800B924085F748E19A57B33E2967A110E32A624DB453BC83A8DF22B43E9399591717BD0F36DF5A9D5539D87F5427577C20A01548091F6C5261334C0DA1F1C2028422ED3A2AA67C774B662D332644C6FCB353DC2EF12755C0522038E611F4C698B3F9ACE1C4F989DCC336D5FA8901A5F2E76E4C5CC0EF3D9620F369D2EDE2AF69E041D341AADF7F3A5319D6CD3F37B1C37DEE089D9143EE0096C8EE99C4B74EEE21F07506277C4AF200DEB327DFB94E4C1472C235F4EEDE61EF21F55A6E7086983A628253946276F5880DD95B9BA8C2585E3DFD256C35D6EAF7CB2A6EFF89298FCFC7731E9E24FE37588188BEA692C3A65F5768A7F5B0B98386A24C80C9A276CCB0E24B1D4D684B1E2AA31B86E752D33833247B4658F9F31999D7D1C5473E4865C976028DA0D1B1DD55CA9CE0825AB264BB3F24FC1286A59849EA9BADBFE4EECF904751FDACB74637259E75C010946B2BCC1CD031F32787EAAB4C53C595CCA2E344D6E7079C0F61419575A62667D8CA1ABEEEFFA5D828488B4BDADAFB4BB1157A40000000000000000000000000000000000000000000000060E121A272D3134", - "reason": "z too large" - }, - { - "tcId": 36, - "testPassed": false, - "deferred": false, - "message": "200617160BC7473B67983F090EB24EFA04F3DF7722B6288437F32CBACE387ECA67E384F4EADCBFDF21341A81C0D24270C2D46819644466A5FA02F2CBA7686F811900DC502311CE6C0D43BB885B228629BED3233DB998CB4333A705B949CD23DDBD75A447FC0043E61222B22F87994D00BB3B98CA462CF7BE47D85066F7E08EBF", - "signature": "D1750DCCD7D25AF7D16C5FC680D2ADFC8AF7ACCD53611823406448EB4B748F85B08C71C70AA94A92AE83782F510A0365DC9A342C97A9F430F62E87D163AE1422427ACB89AC0DD0C1FDD25ACE097A2E7852494D5089E1BC6CB1E08A66A48CE391BB3FA9C691182D7CC18E378E50E129A87A33BE6416D04E411EFBC9F19B69BDA966C778644FA7C62FA63B94BD45AAC7033507BC1155224C124FE2DBABBC5FEC1C65AD761C92552A6B4A2193B6439B1EADD04011A7D630CD3B728112BE33D6A9013F8BA2D3BFDF78CB084D729C50E9A71E4BAE1A921B606069B557574E3D89266997DBC1F3FE0B713CD8CBB66C29CD434253C12F8CE897C9D85D88F89F953149B3A4978D38FC3AB6308F3292BA7BE6C3AFD9D60145F5CC7B62FCFC46C62439864D898819EBF95B7614415FF2769AC9920F12C47552B569F5850F45457762945C5F2E16D5D70129A0B0DA677D002A47F730ABE8B1ABB915523D872D6EDC6835972FC8DA395315D2742B708A0746FF5E54960C20C195A336C8383B2CC1F97E5D59BB57BF91ADDBFFAA5C31D10B438AD9B4EFA7658C4048A17226B621F787B9D7A06AD14FFDEA85CF33895574F4A13F28FD02E9DF58A2020A567DC529F552770DD3B0FDD4C643B01C1D0FFA48ACDBB2190B900C99D27E107EE84327ABDBCBD6CB5ABBB880BBB6F556890D10286BCE97A13310B33C69B7E44CF5FAB8850B4F526A8915D35469D5945AD8B5EA6A65EF961A49A7081CA5D3DA8E0A458EB15AC11FD9911BD2E25B380AD6FC01457A52807D70CCDF5F9E0F363B6EF057FA35AB2013CDAFE0FE3E4C9539181B5C95EBDDD92C3E915A5094C0C2005B22F3C5478445BDF3F2D628E593B3A2028F0CAAFB5786917304F76D719B951362A745A9D4401BD847B927C240E2C9353A64FD1AE944332F43CAEAD9BE09B8466CBA0E095B74398DB39761B8BC37B9FD0C8EBDB62B1265467C2C19BA83F59B9309867F2D432AD6D8A94E4DF8148AA33CFC48AAF4C56702F1B7656440AA20071719807954B587E906C34ECE51A3E564313BD28035E588704BECE95D42C5DB875681B1AEF67FAE25271D13AC585C5921F1D47C85A56807E09941EDF2B233A697EEE085FD5BB9828AB5EE945ED42D596D103A4B5C659603C531BCFCAADB32CF33581E4588CA1E2C7BE8F24488DD1E372EF7F06E6F23A068389E9983B0D83D20FAF56FEF369AC782806AE6CEA531B1ECD41C89642E84F9D617930197D712A306E6F0EAC1C32FB4E0D9E5CAA8385781548500698085D236A8DEFC51B78A8C6797DEFDB858C686633F3839BDC271E177637A57B49B053B837D5E4DA82668C3337D505DE11F13C078F63AF4A287D49C1AEBE157C96AB9762AC7690480E85FCB2E8DB3EA32B6DAD096BDEAAB9403813FF4AF4555203CDD7F245EC7800C5F9A77AFFECA3E40589C102574401CBEDC4853561FF04A22AC7DF323C770783A224EF33387E4BC6D1FB2F6012782DEB3A90847C61A7830ACA74C9F212582C15388EBCA86D9CAF3F239F77AEF4970C7AD802B17B39D4943DFF9EA67478FEC49079E0A0DE0F29166A09E7ABD74B1573787F24BA36B96094F171F722E08277288F7FD1667587DEB64AD2E00E787A465CBC3FA23938571177476ACFCF5A7B0A70D678C99417872B01865A84FEA308E344DB3386907D88E733F64F471D2419915EE8C64F4F1D37CB37D88A2DE92ED826C44A990EA3669A8FBB280810F4F2BFB13EFEC01D7B479983E7A7FB04EE34AA1008A454A2DA3F3C473A2DDD66C46541AE06E30620AE4618849D021B03C97D741A9993E855A75245A291D43D171A0509A6DA1ADCAE892AC3C6C4D7CD03D5A22BD0B110D345D1C6E968BA01DF34762D36D0CA07EF36DA48E6B72C93899DCD4B43FAA379722D09E88ECB4CDC2189F3646AC0F4229D35F623EC9AF96F56A82D6AFC3DE7DAB71D1D7AF15567328BD221A79114FDC7A3C2CACAC9206F67CFDC34CB47182D146BAF56566746A23D9A8894D5DF5CCA3DF74F013E095835A8F92733493F49FA1ABA71E47DBE87059A717BFA378BFB50064D7081290BAA056D8B8679CE0683A332820E60C01AD0C4AECD7EBE8ED71FE875BD688CE30FEF93747A86EA9ECFD8E850530612EAC2AE227C2041CCD4A9FC942168D2ACFE19A40CF1AF665C3E3C300DFE4BF925AC4C5110F5B0CD13EE2245461BBF56D87AC735910D52332280CD49D49B022756DAE54E94E264CAB28292496408F779F2395CCF6303853A31095F81BAE6832E97CD7C2310C3DA4363131BA7B54FC128C7B94CBC50464AE9A785342B5C59CF7550C1AFCB190AAFBCE292ACA3A0E77E21EB78742CEF7644900E85E904ECEF3F4C85A8D524DEAD6BD1653AA452517DDCEF08733CBE02508CEFC50A6B0E359C8A10641E43FE133CBF6E65449FAF39021FCD75CEF6FF4403B8262729A41850AC6526635A024796E63073CBCFE892CD04C1579B827FC859A21072EF323E3771F63829F44972F6A3B7B7DEC4841A5A0332C58B637F8B5709E8CEB9E4A5FF8E9CD884C729E4EDF931D67896A3DE87D8238FEAA85EEB049C9A7BDFA6124A58C43964CAB536E1C180FE35B9362C5B97378E9A9BF7732E7C084B2BC81588FED53E3D4B6912461676D52620E473F0B4248001A3F84197A14B21611F43006AF624D115E5900893F2B97CC0D3B40CCA1B68029D685861A9DF94F078BBE671FED17573329B5B357A4CB59B13FD8B90E50FEBCD7516835CDA8148482D59816E4F98A0473296A87B2047C4C1ECE93D17706B5F492FC7C7BBEA333742FB35EEC0B73A0ABCF518F95A7FFF8D8EB91D0132705040BC2251325ED66EF38AF83107AD7B3048F86E8880892D5E44F2DC47C8CAC005AA0E3DF7229B90981FAF35F11BA8EE78602B9A3E122F1B9E57CF54375BB317B3AF1623A131521AA77971C0303873831983F8E252995A03336AB33B8A7EDB4A81CCEC376B9293387FAD9FDEDC0B79C46D42A94121AB6A9FC25230D5433E012404AAB472FDD008D87E10C0DBA9774F3DE93F86BD66308557133AC6623FC77704024FF63C337B5636784B4E2457EAAFFE3DE4E125227FC7E64869C688960C659820B67DE905357B4C816940F28C3B8379B1148AF47DFD84979C3B39069F56174982912457ED1DF33401C12ABB79423DFB40435426F17A7B999214F1123D00BAF37342D7E861DFCC2B55522FC9DBBE2F55D7AD73B770D07068E270A2A4F41A334D6C7D85FA392E9D74357AA15F98D73D0B0FBD23213918395B63FA6DB4F6DB19B5C01F8A404EA9764FFAF97321D02FAC636E81C964C8B1869B8592BEDE32E988FEDA3F7044D95E37F1098251E4EA087829AE2BC3DFE57D7ADFB84CB8C115325334933E1C52273C3634312BD5FE72F173C7B600E44EB2B363F08DFF5259FD676B0EEA185EDA97C7E025CFB46C80CB46DB56184A6DA09DB238D13ADD9DE87C7FCB195039D2D761E6746E1953F09B9F5E5847ACC67F30CAC3F002C1D65747DC10289A46F7881485D7327360E432C9BB978FC38182B756F3958CA73D98FD16F9690B019AE8FC610D6C9D6942C2C44E41DB400541CF85482BD6A571677FC8028E7183785063A425A75091455D5EFE6FD9A4D70FA72F541D76E54AC7558B5D412605A6E5466E351BF976F29E4866CB21DABBFC7E1CF32C23567E230F67AD57B55DBDBA2B01F87ECCCAC4490F03CA5FD2CCD8F6A97DE46C66F10E97D5D438855C9E83DD87DC2BFED0CCE1ACB5EDAC96A1A30B00C7F870EE9701481CA4EDF224F3AF0A8118CE77DDE2AB046054C2A6B05AAE6309CD52A0218245A64F49EF55C14AA3B24E65A21F26AA5C7FFE248BF712F77B59F646881920AED9BD7D8D5F2411821ECE61ADBA189D1C9F6AC79C99D33CF9FFF4107BB2D5B4EE05E9118D95F8047295F58F10B4E309BBB8B1DC0AC771DF706C70DCD05E89049179BE6F71E5D6B61B2CC5AC484B4453BC1FA1BEDE2F2F3C57ADF7347703FDF4BD3B2A62BA57FE9EC3F1D147D4813CB6884037D7677DFEE8E3955517003D1A699CA99C1145AEFBB92019CB7B44938CCEF7D00956EFBF528AD0A6478194D62871B45D2B9CD7B4BC6EF5BFE5620299CC72F9909C051E983D7614032B4A77234863023BDBF6CA1B9A8399AAC020838A13CB839310B352AE9C9BF67A51C9FCC87048444E7BB82FDE63EBEE2A99674E3D49C8972F1EF68003F47351398A419EE619C4B7C4EA5195F97EDB480AF58C89E876E52D2043E80A99620E450CF1FA841AB658A2E772DF8A5FA8EFB9798938193948CBC51C721A1DC557EAD943B7465B34C93E7C15AA7FDB96F11B5B15A65BFE43238CC5683C5CE81D50E44CBFF47134CAC8FC10877E4045846CFFE4D9393B9E67829787FD91A2DC3B482FF4A75A207CD98C8027BDCFB7CA55914B26D78CC5802D918C22ABA5E95AE0D186E6A02EEAA69E55EB7C1EF6683D301C354D11452BAD3EF7A355CE394C3CBF986F4DF92BEFF187EF32659078B0FD2ECFC71E74822AEAD42E020D8831D4E676C80C82EEDACB6A0075E7D6203BA4D3EA67210B00045967D8BEFC515900C306224D85AB912C22D9912C3E06678E2ACB5F488D106EA0C959E89B4F673D89F961283DF3D74E22315797C8B7C89FD1FC8011F70636EB0FDF1734D7513F94D8CCBF808D5A0FF0A26205B3A71F6CBB82A761CDF235B1074ABBCEF0FE4C4D1330079C1C326073090EAC172696C584DE080EA8B4BE658B26370014497C38A8CD862492E0B62CE45EDC9AEA5DCFB5DDF98103C280877DDC81D54C26765CEF43FDA32892A7B9E113194C3B902E907B2C41A53FE9B8A9E60649B0E8CF746671F1525ED9E57398AD5B60B59EBE1FD5D8109D6BE635A186F3F7EDB9B233F191B0D38F99E4922ADEC45A7BE20A6DF9EE6DDBF847D7E1FBACA0D83BFB13A4941033FF51AC1892C23E94173F85398C06D0816418C29E1962CCF0A3004FACC78087418E0ACD2BAB0B4D25DEF5444130CC93CE62D62FA62ED95FCF73B588D83779ADBDA402C83BEC861F5896D92AE20F1DBDB7E4C7DA14BB1A81189F2C9A5C62AAC6DBEAE751964F9BEB24B97AA71B8A4A610BB10034DF3E6B8A98579F15C272E3E404CFD2F33DB7A89CC0F68ADC9029B80796E4C798F8605E59D7CEC8FBF4645A099C64A40B75EB3C824D5CD98567E06DB9E24B7EDE00E1C2734E28BE1C69B5A0315642D15D0E53741948ADD056E2C5A120A450D65B227550540F58B319B08D55109580C22552BF46BE3DE71B04BC7BD1CE7D57C3B052AF354FA0F90C63F5B388A0564858EFFE79EC73BE7CAA54683665D04CEA3A0A0BF75E191742BF0EBFDC0319744365DE8C1167622D41D919C629974755FCE629E1BA8779CFB4A7CAFB112D3AD4D38CCD686633F520FE6AA2CED9FAB024BF1F13C7728D54A49D6F772A87E0E47AD63CD2F3EBB58F4F9E8976E8A311C14A9605168F558246AE226023695FF5ACBABD0A13E54A1A53A03CF30EA3CF7E6B615B93479B63AD07192A7DB59F2B650477913BACC4085F87AE04BAC4569D5E707752F0E690ABFC026529D29EB4507BDDA65F5C0DEC1FF25839C4477EEC97795CC7F1BBFF9FFFA7F422FC4AD51BEE8ED434791167A6CA3BEF366003F0099CCBDE3723149EEBC956E1C7B490F238B54CCD2AC7C19BBD90822299B4F5FA6AD6F1ADAF71EE65FBD1B2D1E0567DA7DCC6636BC0DA1E92BE70AC75071455E91C239E52D9F9560309261F41EF1182FDAC9E47B0A404BC52343FE0EECFDD968C7294408493F7C9E2505EADF3E42A7B1E261C486943436F702857A33EFE05BB1737610C4EFF71D941730FF7A77DE1E5EF0257CAE318E9B78AF3EAA5B9EA2482FFF5B39C5E7E693BC9E66C597B7AC73586354237888D36F4C5C1A2A7E0C9E809ED4EE39C0A7AD396A2CCA0A6AF60E5C78529F893B3592D275F3000029ABDF68F9CF0A32C50DD06575FAB733978C0F0A0FF35903C578F6B59876013590F19EE18EC14D2AD693ADAA3C92EF4A1A9C61FBD22B8D67A98EA2617292D3B75BC17D9CE1512DCF5F47E6FE500E5F2F94E4D27CE083A8FBEF4F7BE479FB0B4BFE84880E6A60B203C81DC04F9AEE20A641A01B263080BDE6EC021407C7F1823162EE44EBD94673DE5DB5FA5C7BA4E69008C75E15B1F7BA62BEDC28DB3683DCEB5EBD719BAB6E6BE37190E0D7139F78611EC6D157E222097FCF4359920AA58F4CDC56D1417EE8D45916CE055C9C3459B6B522A566AFC55970BB6ABB2D9D2A2F93B3191312C4AC2D56EF96FF3DE000FF9C67ACD1FE539175A23F90FD3C7ABB5C25028A688FBE4DAAF7A8DB6CFD531ABA7C8FC3CB9836C4147933096FDB4065B7A88B42CB20872ED42F159A2F70F7FA1740CE45D2295DF32CBC8BAC47ED2ED56DFB5B60F1C578612E0A0EDA21C24585DFE325402DE9840B649F2F85D4C62E048AC84E56B555754E68F32D25F65E1263F54070A6B3B9D6D9EC094C4D507EA6ACB8BED02245CFE8383F9AA2B6C8FB92DEE03C676B739AAEF40E484C82FA0A272884BDBE000000000000000000000000000000000000000000000000000812161D20272C32", - "reason": "z too large" - }, - { - "tcId": 37, - "testPassed": false, - "deferred": false, - "message": "81E44E2A69141D37CC4865E66E763731779F2CE35F8F88BFE8DA1D19D85C159304ED11C1C156DE0305E866E8E25E996DCB0831625E790093A50F804817221F3230474508E3033AA8018A5C60232ECF6922343BF78E45DB49F6F5C4FBFEDF8E61488916B2C7BCA20700C0A739C2F6886A0B7F27A58367BC46F90DC5860A3A69A8", - "signature": "1FAE6DEB76E4E0313CB77E0F14C21A095AC11EA26C1E16FCB316ED13C1356746E89B6A14B9172A8047AEE85463B63670BD3D5A9876452BA25392C07AD179484C74F6461DF5C71149F9FAD28F43471D811066BDAA0E53EF8B728D14D8C557924C9AA7C1471E31812F0EE86F4846710B4F50AA693DEA909B1CBBF62BF64A549A7AEB38286488BE3A5F1D70D467E0A89F585B3706375FB39BBF878BF940BF4EBC8B14614BCE154D726DD9668A62A982157C444FC972885F36CCA9A7B825A3A4A627027B3249CF91DAC34C07DF076DF6B34C85A97CD5B50C3C26A3CCCD72D8E9B91BC328E3D487E6B50DE028AB628F1641284DAD8E6FDB183545A37A55F2B2754672F3ED82C999DB5BCA4AA96357406C8C04EC8327DD1FD1E5B0A6E8385339ED420437B541C48C058124BD688B70F9E0C433A8FAC5EE812D1D11E61FE6487B64BF0A998C143F7F351F2A2E954CE402B316BC678D4812ECA7DD749010B4FE4D5A6E5FB05558B5AB395794DB3716E7104A0A3D9DC58482BA461E8938F7E01C267D4A56CB16A4530DB11A2D63A87D9AB959BB54C601B1C9CF785ED1AFA5FC9DF821EBE779D8AFEFC5222D4BB23E096391D1A0A774D272245623546C8B9BB6FC5461740DEB8E8AB350A83E779C6C90B50E7A79AE8005FE23CED67AC0551CFE6B55594951FEE90A1D18601D637D086AEFA9890AFEA64659DF35C7361C3A42A5C270EA58D5E29280C62BF62DE181FA57E0F99702693FB678D6D0033C4CF216ECD2290CFDD9C902DB756A20D0E67B3FB4D38953D731292BFEF03457BF5A05F40AEC5D441F695D169F62074D8BD68C1F855EB52E0224576BC8BC1B76C6051DE5FEF9CA18D01D1F693AE2338DCFB6E860075FB4C75217438AF492D2D55419084B09B2DA80BAE5D41574957CD5BB7427441F2C13021AD851F794C5CB0D18838284DF6CC6BEB466F65EBE8127F77F2DE2A3F0EC4F09E288EABACF101149851F985A9EC9925DED8A3845292EEE1062EB355094E4C5982E097A1CFCEF4BFFB1D9BE16EE184B307E63CC7F2356DC807632DBE14FEDF602801AC77C21A34ED5359EF3D60D9CB370457EA89EEED425AA9A40237265644BF5FF3E114878145A118DEFB1C013C17DBE32DCB53F0B4DBC59EE4650F8C69A00A7FB532955448F601FB7885F817AD83A801F43BDAE0CEC3ACD4910E839673AB22BF91035C4C52CC2D25E43CBEC6DA80CDED7601E1E9C32D244F57A7388EFBB79EDCF66D87900259B91D42A8EF7DC5D5A0CCEC2027696E7B3C9D37A06817D0586FAD9E8B4AFBBA64A7ADC0B8969EE9A971A4E5E60DB0A7F32DEC3439515CECFAB30E4F799F2F0386C9E28A9FD50DAABB37DF38E034873BAF5D9839C4CC7ABE73D0D92D59995EC37F7CDBCE32CA3682A9782FBB446FC27DE2527DF7099EBA7DFBFDF750587C78FF89FFEEF91A2FD467020A35C05336B73611DECE1BBE59ABC5127477D3D6AC3DE6EB2066870E1E919663227848F360CB9132D7C0FACC01B4EEAAC0946FF96BFCBD7711C41397E952ED169DB0E63C73EC1FEBC62948EB32793EB1DB2D19597BDFFC222665074489876F221320CA07264AA8F7314569EFF7D249850B8B754F73C40617BB8B8B8E442D5B2CB53BA3D1511C63250F7630E2B09ACA8BC178485A38B0F1F2D5C7EBE66ABE352188B10A1E07DC2E7989C6CAD52239703E18A7A2A5F92E366CFE7991B0AF9C27F77E7F268C1D5A6777668480BC0F616EE35D3A81A1C72C75325693AA418D5E52D622BEB1384477954F662F6F913203FF3A02AB87CC8539FB9A11266C9E0F508593502DFAFAA65FA8BE0EA5171C06C792D4DFE99E4B105E0FA55CB9A1BE5EA9F201CAE326170CF4307C648CAA2AF0655793B995E2DA5E1C02097621E43BC309A4F4CCBC919EBA6E4AA6008174264A47AE24B23C38EA67807215640193AD9C688E818E3AF38DBB84286F3D1C950CCABDC27A020DECE6264A15B9321DEC8448F5E74A2C7F7AC71C95D94B63972BD06D5B5BF39BDA57EE9E3FCB7B81EAFD6365303DD7678CD4FC1014A387316FCABCCC24D1911E4796139C064D0C8072867C95E5A167DAD38537CFC7CA399131CB0741560DA001A524CD9B72C9B41B3C0CB416885F3CC6A963E437F3BB43530F44C28693C20997FDB1D57D76FF2DC42D22ECDBCD1940AD2F2EB3E0A2AD85FF062E35A56CEEF8E58045C46F7CDFDBA569FA7EEC4FB6F741E1C799B14409131A0CCC0D370C7469C16A9F45693FC7F26C9497BAFEE42333EE3E75F44D4FBF83C7EA9554BD97D1202A5A9A5183C453DE9A42ED1E68B68DC579498D25A5AA82A27837146C0B88BAED74235AE59DB5C4D1313B899BC7F553400A931340C8E6DAD468ACFD2652A6E07B80DD2D8276C39ED504FBCB8984A8225C546EDF9316B838A03F118391FB76F46D10F92BF1E90C59E30109DCD8D72D2A7827D5DA23551F9FAEE61FE57FB6BD6D614D9E14727E0B4F040064D21EC3FCF94F059E44129D47C4E32C9126421A32A0C67866C4BAF624F959B85BFD9CB83342CD8B765820B9E18F49AE4C7D471C80E0B91765A83F0A0120CA2FF212833E4E0A64C5C8AB6427D40781965EEC92A9B61A1668083B22BC2C422DC4B9BC96EDC75A95E180A78F8675C3EF4C23687B427B4F33AFDCA81921752DD4727DE2E53B0302390A4341E072B1046359EE421F2451C33BAE32264DCE824E6628CA6A2087C434784D39B67E0909BEA410E4A7736ED93F4F9ED6BA9B9379587FDC49825C021719D762CFCD35504FC685C0CEBDDF47E528F733B24ED1A3107C694CF1F7AED351B51710FC872B5A74FD7AF8C51D867DBC44FA854577BFD477A3B12EB6F30E01E6B1CE3B88774543BCE9CD9B38FE9F5196478E39ED88E122C60FE5767A2B0F124F698C5F8E916DA161FA48715325398E97A8B7CFD222225D6202296D89A1CFC3FE99E63819BA5A2C771C4DD53783908020B2B6D04D19E43EA178C880F2A740F4B210005132568E0CC25BA2B765318DF5C9D7721734BAF1CF8E16E0930F7CC658F1F3BF63FA9385BB7D42D72741F2DB26CC8648304C444E3A8BE6E4330D2099BB6AE3887C56EF0CA6D05DA6A96E8FB9AD33C4F31531EB36474258AB81663FDB29C97D1E5451E48C242C580B6A8E7C37CF998F10AD9D182823B8CDAB95FD2FE21C057363F0A96898F835624461140C1DC348BD762276F28A2DA880D8486796516E024774EA4A8213CC9705F799920F6A0D8167F7ED2F7C10B2D39CDAA9B5CC374E532E9E04CF5C26FC4F75B0D43FCCD3F5762E9A2CE203BBBC9E2042484B4BCCFC06587F4429A18BCC17AFAEAADD99F50B672EEF75ADA07B16B4E72E92E946A369343CD39303E06D1187D9E68C8E8FBCEAE47C0D4DF3DC9C804C8C789FDFAF233ED9CE2A8B4A3E4299AFB0CC82C28B3B6034B109F882CA2EB041FCCF4E40EF5FA1AB3341B12AB59A230519868BD2E547A1FC3C47ACAC9AE515B41F053071DB21309DFE6769073975B1B7731FA072D958D2850EFDEBE253915A90B6773E714C9E907C057D0AD225789A4A293D6CCB718BF9467E5840B585D0C4C63344D74B7D735358E77E1395A578F9C8FD615004894958118EA422FA9398620C0513A1815504ADD0DF7239D5ED48C532291E68BFA47F8CFDEBD73845A96532A0153823B69280C33FD24DC1D44A1C180B6CF0CE017BE10D48D5238D90C0C168E7E50F53BF8915F50E9FEC70397FAB98D4496CE127280ABA40AB1996CCC80B106AB5790CB1EBE626C5039F493CD10D5BB77405BE0A4691ACD3F2527C18B9FDEC56878F258B396A6C0E3F5429179E447B21555DCF9E6C6864E137C478F475681193AA52C99D511337357ECBC461E9EE6882B9318549CCB238D8B1D82BDDF365AF2C49DFC5E18E175788A1F8C679BDC43CC96162FD2EC70EE92C3E967B76CEFE507E0855E05D85CCA7EE0C181654373855C9541659A4B5C5E27F1B642E9DFEFED3BDCD7B917415BC6BCD7EAA774D0B9995905AC7E5F8E703D7EA4349B6BFE47139188F831C82A2A202ADA71584744F6F3772DE98889319EE9E8C83D1D2ACFBF05301366D5F447FF1E3F8AA80873662DEBC351226035089ED0BE4143A055D3FF006EEDA8AE3DBDE42A033BA067B2770BA9E4599353E928CA61A1A1180F715C6EABC3EA72C05DD16151B8D23DB12420EAEF8D11F2703C64E9F0215B278BD9683C29BC0E66470A298058762F822625BECD3266FF5444ED2C6D91D090DC0491A0D0AE2A5F2F36DD34532BCE4A5BF07EC540F6393FC18E61397DFC2826BE2DAEF6FC74F6EE8BBC46D57FC4CB1B1890441074D3AFCFBC72F1E88D7E27303AB82050492E061A0DE93219E0E552B3CD45ABEFADB711778275C9EB4CDCF92C84D78B59DC6A1C273E763271D4DB5E697CF06BDCA18BAC8A5F29C184F8530CCD4443AC12BAE4BFE68E70C03A9CC729A2A977A484B6D19B03BA8507C1A2C04B58F8456038918BD442C1AE7D18159CB78DE3A5BE89310BE8208ADCCF3CE6A29008DEB15081A1B784215DCA0423DB82661BA6189774F908E4BA4E851301C657FCE5355AB5DE06634A09811A16186B22B7FB65AED16CEEA0417F0C85E6C2C3B483412FD35BD70F859E95D8C9EBC51E5EF3538F127A07CDF85A472427ADDA5734CFAB812B794E3F9E3E2EAC3FED574781CF9D4E1E5EAB72978F6B44D9299A225D25C338755B473D0FBD0DD5FC1AC9B6D1CA09E8817C6F7EF2E61E8D70E347E331DF5813CAD79426794278B5B832AEBDD058C2C6DF73150A798484966E6FAA48341F5012E7C244F818F4CC0FD6C197431C804A508062E46BAA14CCDB86C47498AE84CB3D759EE50A306DBD947DF38C95244BD0BE7E6ACCB12EA5EB588DED383E01E2AC820CECE8695D96DDF76474025C155BAEA6C77E8B36FCA710821A2402FB796B9B5300C9CE6F80BFAC600BBC4F53F173EEDC1184F7F641D40C4A9DBEC9D7DFFCA92CCE1CB8C2812032DD2E5347F61F586DAD275B725807A624E6C75D2A4239FA2A4166794FFE63DC59994815732B26B659DCBAC5720BF721D483553F86343436B8EB29916D8C37484F179BBB0B34FF1C2C4D7144B7881865E1976D25BE8FFD692344E6FE2D506E84569CA18C43222675B80E88E35E25A9EA4F1576B51A224AD5AAE126208F71A572DBB78F9DA3E581DCD28DDDDC43083F20F24147AC9220BFC2CFAEBB4619DCB5062416D7DA5C9BD09E5D62E3F543D39F7D9F97FE6B1F4EE7ED5609283752B3B2ECE22C12E25D6EA2CBDBA4CE9A92FAA2020550C5CDAD05F7AF9186D9E6C6EA80DEE9B8F9A491A55FEB52FA858AE349398EA17C06CDF14CB45677A2159C99784E5B562D5F5BD25438EE1311A86CDEAC43DF25B9C277248DE1906CC9F1498873419D333A42EC1D57E2E46561B30A6FEC48E87DD2ABFB985C23407A6CE2593A28195867CC9243E06A71421535407E557A6138A6DFCDE0C12A8CA6E11A830419C666A8983CF111527099D652B16DB643C14B511B91B08ADFCE3FA143F754C4E225A1619D2DD11EA4C89AA3742292BB3A33558A31C214CFFC31C3FDEF0BD735B5F39692D574CD5FBC0809228BE223C73D126A92453DA092D7AB01BE44E2017D7B8C588FC7AF41A0BDC66AB335A0B437BA3BF7E1218C71C563AAF3AD81DF557D767CBD48451C1E6DCF30C7E8BBF73938AE9A0C0D27505CAC3AB8957506F4C886CF7119B0FC00738917A28F4FA8ABB91120E7DF7B0B8EBF07F2B5D5F2607B68AD4C3ACEBCD07BC2123158AD577CE5D02DC2F0A8EB0EEC1E0196CF4FFF02015F8CA74A8A100A8CB69C6D67B88E0F8E3F9D360DBB4927DC3E7B31876661018FF9BF6D0E181C3266297890C541D1AB9583EE1093507DF4970F60B6BCABCE7ACFE79FDC8E507CCD3616E70E6FA961EAFCA887C0BEA2DE39F205C2C5667A4F09C151BC695EF8E90FF3C2D22AEBFB2F78F7959E290700C1A782ADCA186C5C6D9719558633DFBB217A93395985C9C7235D6BEB4475E74FAB80F117B938FE06C19B763946FEB44461A08AB448D898C9C5828DA0F2C639020A9F105F0F636E76A7CD44BBDD4BBD2247B6356CFF228D81F151A8FFF5FF7F3F954059DAD4B0B4F5CEBAF811652AC5E1B9ED5191F9B7A90FF06619461900F0194108230B97AD061AFC44F4F61CD6C20157107B29424A1FFA746A214485B95AC87E9B070E63CF65D255943147837EA8F3EDEA4DED3F7D8A634451ADBAF1C86F7D46729D0CD87D3C1AB946D0FDA220BF97387C75457C96E1F3C0D0AC4EFC2514EC309BCF035B51C1146C4F87FF09D151202EB7E410BD8DF8D096575A180D8796E746197DD9FCDE9E49BDB2C98C66E88C2C2E3D61F0FA66A3703A8624D9A1A9D8CE2E701BAE19F8968E089CFB263DDB65A9A4BDEB7D643DA19BE1DDBF331FA36FA0F656734851C62E699E593A4872FE04203D74D01109553D8368F04CC4C6FF3B5E73D2DDE6080F23386770D33C5183BEDCE3003FA6737B7C84C9F0FF105A91A3A7F403344C60A52B5264CFD3E2FE0000000000000000000000000000000000000000000000000000000000050C12151C22272E", - "reason": "modify message" - }, - { - "tcId": 38, - "testPassed": false, - "deferred": false, - "message": "9ABA3D051A7E3E19E6DBCBDCCE6677678EA0F88816BA02140AE5FD27E0A56D38201E7622199340C0C8B8640E28BD6D318B6EF56F67BD7610DD57995A3E06D14AEAF3993C9802D5841060458DCBDF6BA3403B2DB2F0572CB95B0F25EF1750210D452FEE9460AD6DB821E5C79477D2200346B0AB5F14177AD988FAEA06BBF769D7", - "signature": "F8B96BA912811CEE92B0D15D063111FF3775C2A96BBA5A4F79A5EC6DB47F2FDE21B64B04EF9AF9571D2E189888C2170D8C35DB68EEFF492C68135C6FF69D0E4D3C44843A8E65D1311629600BE1D6B14682B54187D5D75D031D0A58E1D63D832505AED81313210B4827835CFF0CF4F31A6195CED3C9D741AC745BC0A70197F71056E15061935366A6CEF1506A3D9584374FA9BD71B0576C6A817CA9DB909203C21FFE1733B0F35C470F931C52010A3478E27DA1987EC9CDC814EAF80958906903D1D8A5317874DD60200E1DE802CF261FFC31B9FF76204644953914EB27EC07DC76932366B48E74A517C995AD3C366DF1722D6D9648943D5B3396E57B97F8E5ADB1ECE86A420228E3E5D3C347000C2FAB7B1B6FDA0DAC86E7631B1747D7533AD3C8B6CC9E2536784CC5AA30E42150E19149D133F6DBEB87A0D9DA69CBF3835FD61D380EA799A619CD69D6D70CBFDF300ADE3DA903589AD4E3CC7B5547BC42F0E33363833B504DFE925F3865202C8952E2DE0F13DC0C139A153D5B9135F1B21BD8DDE1211018B03CB09C8B02F883CA83A7D02496433C57E16E039E36851FBCDF78866ABA9786DBE8DD3FD9EF9B6C28962ED85C2B7CE21694008B41E3D5A8C4574E13F065F78D904DFAA5434BB8B4A9B05F2006B7DE193BC86049F82A7D849D071112974AC9B14CEBC65AB56917B3945C124CBE803A31ABDED9C9E30F3707F2E795974FD1F8881888135FE3E10EE929667D6FECBAFFBF0FE91CFC9A8848F1AC941D163F92639C2F056C6AB3E26775CA383B8985F23AD599FC746569593380308E6A9526A1174D97966218E63223307257773670798FF8840CDDD4552C6CF4324415DF1E73E064E6C85598AB08955004A796C7F74EA377C23C1C426ACC7356D81B4F129C1A8554E6E05508D0E7B3305232652DEE0A301F1C4733CB370E2F099DDE24966B87E559083ACF965319A5CCC6631EA195CF1188A2DA1B63BB6BAA9F35479E2B48601146CCC422403272F28F65854E480E51D606B3DD2EAE6F104D30351BE4F2690AABF139CF4F8ECEB6EF0D2EB08D9C1AA63742AA45006F2D7F486E752D985AAEA54F9E176C4844C9D0B3566E46DFA7C02FE085B0D04C67532401514DB0C0BE8CC0BBBF47F319F6B7688923A93FC0476DB7B6CDA5CA768E4B7E4C973DD95268A3D3AE322B5B34323FFE61C4598C71705C59B68F039265286187598DFE1E45E16A622F6E75AE5B84D6634A4EB6C69EDCEDE11D57B1E4EBEFE7FD1ABD578DF8CDFF0FF7E957CC35446101D6CF372FB230A9187CE31D355982DD1E174B4C6C27B08C2ABDF81F2A4EDF67D109C22B5AE15775279E549194A0D84515976B19D2BC852B46896457C0EF7C5BA08AA92A671AA461DB21C6857A5E42663B822488BFC7DEB452377CEF9F96429134E6EFAA01E45017E17A7C66A15C4814ACB051358E7794FE676C0B26EE96CBFF0CAE8E3BFD4DE21671658752916EAAAA433ADDAC6E8611E2494B1021C7B63392B15214BF1F50B758EEC774038FA6040B33B33AD6F0A98603CDA952CED33C812D45CD299AB38E25EEEBE42AD90DAD1CB64DF58321F6F26FE2AA739130BBA3550602D3349864D7039F2992C94EDBE8ED8501FB4EAA8919C421247BD280CFBE16A3CADC66EA1986DF5B753807020D6C77C9D8A3D42CD599DF41672460FFCA7AFD80FB2F1465CE208A69AF1B84C568271BE21DC607B6302A9D234A79B510C49E3015B3E2D5BA9E073C376AE251ED255C62AD2469839E1920192674EAA995519B0A915FCC38804CAEBB56F8398A46D89CE0C1CD9240EBBD154B4AC9A0F28E81371CB9CAC75A2CA89645519A59D190A677DC8D411F1592CBAB5C8C12B88DE3E494E8272E7104EF6B9D7684A727A73C6B2D099E588624693D23EF0DAB2CF27924B06D2CA6056D73192B89CFB3530760920669A966CBDEE3AAB9CFDEF82D662CEA11E57BFF4BFF5316B446E5643BE03209E1EC4DA6D7060D388FAF2513AA04F37AADE5FC87463A70AFF8B0B179222E5F1B94CC81E48D42A2AE3990243BD0D16526AB2FA273BF003B7E1C76AF28B2A697424280B5A39DBFE9A48479EBBE740C76F599E8F36CF0E5CAB87620F2262545D82AC40CC20F30DB847DF088E8261703AC60BC8AEA56023A337F5FED92EE8BE9FD7ED6738535E489C0BFBADEB275277D4FAAB2FE03862545E18DB5760B6E76F639DC9BA96EE649EF9C67CCD3510762EF405C4AF841DB6A87E794E440BA8E25FDCCA2A947B32E5FEB0C5CCE31E04B75A50A553CAFD5B9DC682852B44A7EBC1924AE7E8C16995AE94DF8AF1638967E531193CD97DE15CBF1FE60981F7C2766C372D19706E9FDB67CB8AA59D32D260B2E6F8084D71329FE0AFC9414E19FEA8ABFB03A6F5A80048418BA2A8540747F7330149FBC1E54526B205B9188BCF9E10AA79E563FA057AA2BDD955972CACA04E21426580270C7174487E5E27778E5E819516C3E1EA2724DA7F421FE1F0F830BAFE519913C9A0202F7FA9979A8A8B40E668884ADAE379AB14CE65B77BF8EDA5FD564387B968E92A5C823C4D3D644A53200D15B143DC7001805267C0C54842BF2D709F7416F6F9461E3BCCCEE27C2395528DE2457ACFA1BC59BF9EC4D4837EB57C58756E98741B562423C40BEF2A5D57A57C41146AD81973BD1820181A275425E77964A0FE88F0D93303B6C9AD08EADEABF6C1C90B785D0787FE06961A5F063EDE1DA0AB5D163AF45037CEC18E3763E18C61C57A5F72E0113FA68708DBD8A81B3DC2EFA834B0DB36B571F4FCA7CEAAF9D5B26FE56ACD77587529E73A2E54B97482A76843DA1648E47E0E4CCF09864EF30A4C1E1825CAAD8B5CD946A4924E53D26EF0719BDA223300F1CAEAEE8D8649E633C18522A678E28F18D964C81A7EA1C51AD3BD461E8D32FE431D6A163708FDB8423DFAB9F041386CDA39B1B6779B5DA551E79BDCD69029121BDE222D2821F1897BF9DAF9EFC5EBFA36DB0388593AC4BB3D5B2B2FBEA0F2913C7F024C36AC635F971D2815F841B8CE8EDB809240C2B5D69A28124AB3BCF4B3A202096AD2FF86E1C67F75E13796488B3E7D246A08D3941DF661B55973CFAB4870B05D5E98E7CDDEC0C62807BB04473669EEA93415ACBD16DA333F845B400A547609B455DC15D225AA3B2599300D59F63FD4A9EEB74478DFCC1E624DE46460101651FB8FFA621BDAF01C2EC0D41DB2A6FCCC6EFBA480EA1256BFC4C00EBC5CAFD144374CF4B45E189984F3E02C835DB71E8886E1F74A87BD565D4B15216B893D7D7154DD080BB35AE16D41200BC9AD818E3F79E44F5718C43C6AC07120EEB0A7B621A25A47785D5905B7272372C11FAB913360416BC8D71286EC68C2AABD611F9E4103AE32323D24434486F82AD739264D4E0A17A9AA2A1BD0365E4CBE9697008614FF730413E2404F3612DE9E7DE7D3EA96D02978FE9ED2B26938AF3AED998325D20CED38A14276BD86F42A8D14090D45B21B205A17AE869F93E6BAFBE1E604869F920F4833F9D46B8154C3BC3A0272A4F3E8DEE1009E6597D50CC02329EA5DAFB88A863084A6AD17222F3E77E964C07DB97A8283C057373319D150A7A2E84D81B03955A2FD40ECBA0EBAC48C300945D9BF862F3BCB98C124DA0F83CC54F4EA75A184DF8E035F62E96CFFBCAABCD5BEDB259131EC5AB9C65E66A3F3C0ABDAA158CB2EBE18644042E05D048F044E82A3DE759D54773F643EBCCF7251159BA8ADCC4822C1DCDE92EAAC056D13074BB00CFDFE60A22EB685C6C758B5B0562FAE7D047FE43A22267554996250C0E56CBC5D43831C40FF8A4BE41E990583348DDDC769C2B4D12C8CAD3491A1E59A2A612A56159C0AAE2B39F4FF432946ECB2A206754E220F193F0E4799A05F954EBB2CE6512B95C0BF3FC8ACCBE5031F367BB9C6860DEA165362C86103F1D8FCE8525E9F98DCC3C152DDFE24DC939869CFEFFC367012DFD064F8D1ECE56225D7C54BB11AB48C1A3A1E092BC92F683D75915A9E11ECE7775858EF2F844CF9822EBDB5DEF1FD805DFD2FCB9DC2C94F62A7FFD142229FA890E6D066BDC0B5E253346DCBDDC6DF4E4D81C218950A7DFF0116DD8BF2686873D67B2852BCEE7918FB6D64EF099AF1C5962A2DFDCA5B63535DFA82CB7023B201429A51A02047870D5C99EC90D8F3673A75B78F20B89B91E323A314C9E0D13BCFAD427A29FD6F72110800C772B0576AF15099C91AB4220678EA6737D9932666B10F39AE5861287562D8D60E7A3EAEFD8085EDD231F2A7D91D9A1218AA17FED7157B7945B582A75A4293F087FE3AF3C5AA8BC85A14AC00812CEE5AF591BAEFD22F22A3B3C3BC4FE04B92AE41B3738CADC1ED4FBD16A8E5A572B79F07AE4C468C34CC60ACE8FC6CF02925886B511C437FD01727B21E8FF06F2F844D9127E2BE7969B9EC0F09341CC2B5B4843C1FC7C1B23AEA33BF2831CE5A4D94C9291F04BE6C87B37916030AEE74D8F97BF2E8BACBA220C8EB2D2EFAC748E2315B52BBEA898DABAE0A6421FBD2CA75B041EFEE67BF2DDBC8EA31131AB105AF70F9F92C566F675E2AA982F19783085D3822DE6732212558FE658ADB36703ABAF9CFCB4A052FAAD081BAAD616C05CB20B65B540EA8F67E83429540EB71E5D6D8283072A09CB8A5DE291D0DD67F67DA1B11CB7F564ABF248BA6B6E427F62B0A9D406BFEC39BB4AE854076EFF9876A6EA052DB5CABE436D292C10ADBA4F445180D300EAD76471401E29532CE949732FD24779ACCA31DA03D41A1BBF926E1D8E9656CC02F0EA60116BAC17DAD90190C65580F70009C82D111EE70FB5B81EFC94B65648913EAAF79423BCEEE03F76C4C80600B409771A8F0EE87B309DCF15F432B2388B4D8A3525D3A31A8C7D61EE4ECBB3D3247E6A358C23CB5C1CFBD78C3CB64C9C560D355C8A5DBAA916D22909458BDC0EAE6A92443D3EFE3B69B443013F3B5C0F0BEB32CDD46E58A4D5F5D7B8891F0CF78005BBD04460BC5D6023A413E9B709E8840B322C2FD2EE01DA490B903469D60391FE21D2FF21222FED1DB2F324176A9DD403C1888F68DE34E5A420868F013E205E16082BE0FF504E8D0A7A79250D7F9A38CADCAC8A4CC887E6AA50412FC8F4C358920B29BB09551F21B858843CDB7C3AE1536B80E0082C0BE3C7C48DD08AF37AEE343B30A0D3D68AEB2DCEBD57E4EB7E71752C422D5CD0426C6538B1FA74FDDA2F7AA7FC57AF89016FD32FB63CFF54B5E2D4484027B8A66E0E8C3DCAB404EF02EC1DAED9EB8C234D49ACF3A92B43782C86AFB1F1A6D482F0B78D1F7DB4BB7DA4BA27939AD0A744137295E802320DD305FDFA2CD7B31011E9FDAC312EB6A7A4F1DF3EDF3FF3973AF627B6DC6F1E8A0EDAC416D1CFEB566F73560EFD06C0BEDCCC0A9C14BE273F1279A962CD06B04AB2F7B9C8C05F9D3A5607CA817F19890D4B9CBEFAE9CF3DB58D1AAF3D3A901DB7E6019A816EA1A3B10E4ED7EB0D89526C14685823218113DDC4FBF5BC73165A08664719B7DE597E45994E92B667A84DED5BA2BD0CE6AE57B985ABCC62A81D41ADD31A4A6B3AC1ECD2097918A2120B1118262FA112E53521F1BD55A5BCE15423B9E15FD1676B6C2B71C7ACEFA34E79E7674B1C6007859CE58700D1D5BA8CC3600C606A954873060038B21BEBBD6333D6632405D7FCC7682BD8444991C51EDF01097CB889E6958DEAA37392854F30A29147F317A25CCE4CD6CCC5FDAF4D6AD0FD9CBF98EF9B047A5EF4B7904B762577F974B4E04AC516ADF0695183D153D5E321A2EE192216087A3B0F3AADB81B64BC7B5A7520129798F799ACFC2FC1278B2CAD8E41083F06268C17813AE37A783B0CDC88A08329B161774DB27A1FD7826959FC11D494C6723F99E38264C29CD1D6AC5407C51244E10E20140439B2BBF4AE9D60889B1A484972B5243D0C17D72FC0716F0E3E38244A627BAC2F1E100D4F8DEFB60D55CD8CA28C3AB55243B080D1E528A61805E943D0278C126034D1641EABDD09B2DF1FDC76494B1CAA37C7AFE153D6D5077E616CBE4D7399C83DB15F1770771BA5ACF40802B266FDCE07240D2E149566A10C64CD42D0BDBF21F5023FCA7E976EB69E976BE4BB5F5DE97FC688E972D7DDAC853F70277E42DA44AA1D800445A05177052A581380F65997FADB548A350C398F7F076BE8E6135161268936CF6B90AF84850FD1C849AEDDEC104A5ED9C4723498B88E0375F390F14A1FEC03064669B3D08501DFB2A0C26C755241FADF278811E6B5A6ABFBB6D72447F55EB8F5F7C9F7759A1386D89FBA1DEDB048C56A5013F30506B226348DD46F45FD173D6814712DE2708D7345B9B6B3EB251D22EF2E0D2256068DCD3BA2F0327A20C9CB5DE5C86440BD19DC447204EFA578DBF769FA022DDAA02ED58E1C3D02EE35E6FD4E13FCB23018743B83F769BD08E75088CD2E01A8A8957C07A99CE305D50DE8FAE597843E102B3B4664ACDDEBFE153B529EABC2E130666D878D9299A0A5BAFF58768EE8F01D39768AA2C5F40F234F59848FE00B38C6EB2A608BA8B5BABBC0C7CEDBF70000000000000000000000000009101B20272E323E", - "reason": "z too large" - }, - { - "tcId": 39, - "testPassed": false, - "deferred": false, - "message": "8F96C963CADFD3585A29E3E7A46618FCEC87D18F54B7F283E0C761C224B4FC93C4FD705D7306644F3215D4527C58173B2CAB900567A37800F43C692F2F056E2F7C603FBCA145A77D8C3833CDB7E6C049F690C892E379F304B911A31A83F18865E38C393DA10ECBF53E747E5BA832119757EC20B76B52BCB59DE1CA6D3BE5F10B", - "signature": "F32303279F880224A7EFB85C7B5769442BDC949700D6D54B5E3A76ECD8EAB821FC8515D215934AB74B2F10EA8648E6727D91B11E0DCA12A1F3E3EA935F7755C48614EE56E6415614542783EB486418A05DAF900774596469B262CA8608A96B267F0C105327AEB9F83541F477FFF4BF1612BA658F3EB530FEDFA5DDF32A0A8E04CA0392FAF2B37823D9DE329C0154B08535A47F7574B9F2CDF672B6CDE23EC3EC972F9CB000B7197F4CBE8E263094A8A3E3CD3F116A9084CB7F03CA76DA15104ADAE34AC5B7CF93A535FC8F8B9DE68FD14DAB8504E9AE3307825F93C67BC29769D5F09FA1630046EB8F0FD873C533CAE2294276CB734F2139724F0D06DBCAF4C3B9E3B8DB72242A77255C0950FF383F0C513890751253B39D00BEC708DC0DDE724BDBE1CECCBD8C77688A98DC9D18F6453E7617FDFD32F454E0582AFB47816644A951702911BCECE4A5146D58C6931FBC762D42ABE0D50D4D3C1B703220C662EF96CEF8269290DBF9DB1A4EA83C23503764F098B1C4E13BB90857D6FADECB096D53772391A76293D2F3F39EF97652CBC721FF4020775927925025FF2C5E2B7837574C60E9D6DE8CD5CDA790304B757D194FC04819ED430C39A79756DB693D0B9A0CB4F9959C21A38928525865EB2F4F85781C8D55EAFD724A2B05D296B182E30064F5C13643472E77C5A9E57C7D3C35B6F9276065A8B7A29EFB26CCA534F03AA8F56485A0B17DA02629494D77B3657E64192C3D22FB906AB3A36E2223D8E3C77DE16994B782B5FC3CCA105ED53404EB672654E75EAFA0FB23EA9E04B21A1E4A9F1812D98B91BFBD9822CE0886EC7D963E25C1015C9C81CB825EAD31C19B00F0BA2951C2E1D3BC898AC34DF10695DE24CDF92ED45669B3418BB1DD9FCBD5602EBAFB5A06FE45A581B3CFF7B948FC9BA3E218F9A70A711202731E21B04A3C1D47D14D02B8FD2AD3032C55072AC1E63FF42DB2FE2A4B7E13C0349B8772F46E95B9AFC058C9A8FA813B752354ED98C68C1E1748C249513DC5C0C12F9C1BE762846B4D60B20C8A2CC7DE27C521BD459A783C37550B478005C6178E41F3E7157C73C415411F03D64F6C84C61C5C492DF74F53E0CB50092B457252ECBDF3650457A5BF08747CF2123B01648C061A997AFC6928B433535E7A0A9F4AF6CB97A8778BABBA06DEBE52ECC22F7C32743FB0FF168A1A42F6C8C9743D84526A5374F71F2B748BB308469B8FCF8C9DC85149FC8E18A5002ECFF106A3DE03D4E75CA5A2BCF0FF08ECAA488940F4B7AEAA23705C00B2325BB207DE4B6CA8CE6625542DED262B4C2370D8D4BAB4A171F702345A129F1F65A10ABAAC7676456C8DA4548B024F2E189720E0F4183AB26C2EBE42349C1A81547AF49C0EE942E429F665366316B493EF48AD4DC5C1C87B69CDDE11AAFEF6DCD7574E781704E0CCB9590C839F44DBB05CA4AC9B24BBB5778C672073082123AF023F06A8DC724FC72B6216D72BFD5A19CE87D33B8F10FE428BA86C9309841ECDE54DC94206ABB2C3341350183B249A99695A38131D961F5627E5871032AB2A823655BBBDF25137EED1CBFC48A964FDF696341469F11B8F05E411C8A83BEF26A9F98CC0DBEF0AE025EA7F420C19BE4D09ACF5CB13819AE74C10C6FE3F1AD08356CC75A89722B50CA5A754E87DC397FE4D8E38FD7D63FF6A764B8C984E0192322FE082ED3B6D5E5BE5C385D03D98321BE49FF1A47FFB981191ADFDDC10ED00BB73F8915B4BA03F7E87E17CE1E6F53BF90B0EDA5D2A4D6BF02E0C3B95609906CC976D83E49D364E9691A2AA552336BA33DA41ABCA4B9A111347145D3C6BF70EF1A1D2CAD1F84618D4958EE680F04FCC59E66364D83205FC72DFC54D94428336B4B1D8595162CBA370CEB8EA4911051F5DB258F110AD5F4286CB4E00B3816FE9DA7C9696CCF8BB6B51E99E20354906EBE996D460BF5BF484CF102221788A188E0443E74E31BFE648A6CEFC3562A2610891A19453D023F170E93178C570644064478EC7814CAD9F4DF2DBF5E6C74B80009A52EAB3E54475D9AEB34EF7F0462164F975390B69C3AFE2D9510331D585186321E06CBC57F5C80B9E989260CF77F67EEB36AF15E2E9E476C7115607F2D74D8BBDEC2A37F3AB6A646363572FA1E1FFC0CC06D27133BFC42C214862CF21F31B3A123260D42CA6BBDC9192C553E97D26874A721F6F9E14708DB2EE51B09E277A6AEA511373DB5F5E0FDA48E9BD153967992C79589A72C9320F78E85F59E06BC4750CC73FCD930C470AB38535E8E46AA85C24B7909ACA478853B6CBE134CE3EA6FC7F559F44F4C4795E2C6B823AB4E5E880BB58F160F621DD56F22E99FCF5822ABE04D8FBFEFE3E82A77B9D47785399B710ACAE177E399F23476899CE5D6DF96329BE6A366F3D155ECFD95D4400FA13E7AC025A8533168879B51AECAD85173BB7E4A2F69F73338767EF8F3E8C9F58F6E1628F8003D328C6F7D5EE0D1DF53BB86FBDE535238EC9EA1CA0BF8CE19DB3BA4AA43F45D7CA77E2AA8707D3573FD70E4AA43E7544CD55793DE76B35448A25656408964E6C64369428C87667D19E1071B038967BEA44FE3333C55D325BE45F052EBB8247FBDB8D64CBB2D4B13F7631359E9EC19FB38C36B5A74955A17B7C3198C8CB77764489AF91CBB16710F6913022A0A1FD3933B824E9A2EE2FA1B0B2E1B4DC03C0EE14C351D8E14228FB4CF72888A559021BD00B496529211AAD4C4C5BE0880A658FBF144C53233D6A0EFD563353E40B44236F3FD43BCAFDE78A634F3EBDFEFC604D4C136099A338FD31D4A0475E14FC8C672F1B9CB726DB60EFD36F2CB93120CB1D794AC1EB0043006FDAFC4701EFCB035C9B53F7DD286B5FEC8FC96DDB58C9F36D9EC1EA660F661B9FC6B5D8A86E66FB74FF7BA446FB9FFE60046D1C222FA6C00037B2C839FBBACA7E4A4CA6A721D2E8B5502AD23218285EF3F9727D863DFC1AAA49F19382C6554C51B423F7EA1CE48A8A90E4F98C035AFA8AB5170A992A8CE672F95166142A39F2DE4AD2FD3C88D9186C6F1CE6F53E4AFFF7E17653465736266BF7ACBCF6DE80929028912E61B0A606C0A75C76C9D3776ABAC8D85839086A146735E4980C030077D4909CBDA90FBEA68EAE87193E7817980DFC8640E74503EE46CD808833398D93191A08F5446CDED75EE1975AC0119779F6223E05FA70F4252108854FCAF18B9FCC56E5D305F1F074A3A20742921F6FBBE0EE1679E30D06FA13A0A21A351EAA943FD848FB2B8CFEFB0083B39628F0E74D438EA14AED6FBD7A251346010980D0168378D78B07299E97458942F03BA76131442771C0FE648D118F7E4CF18096CAAF9B86ED02C7DE8C498A9426A4F39E385A6C0A3FB4F2D97FDE40CFA0617075C8BEE816A977A60CB3FDEDC41CC162216BE52599D69AF917250F9A2839D305023A6D395131130027F1A93D3A2822132609FA01B298CF4B56428407E5372A9ED9B0BA2230705856C8D6F8E6C43EF52322FEE4DA95AA4340F274A58217E3FA5B071F8531F0F0CABE9A7C42CCE6FC3C3B5984237600904C12A72CC93E64E0EC65B236562BC66F93E290B6BE43CC6E828215252B8A10AEAF54D2DE1E40E0BA6503BEBE1AB9FDD30ACEB9AA2E0C7FFABEDB3CE00020CCEC59354C6D1D102DA9177105D7D4A0ABA4D812BB16CE42B264BCC8FDA518ED5B55951E5FEC855708B6FD09CF0D10971B900B23522CE089ECB231ECB04BC821007DC815A77CE6095729D5608F06136389660F34DCE02958E753AA42955ED9EBDC41F2DE8F480C07B95A17420FA1EC4AD952B4CB3D1ECE9EACB599C2BB46CE7EB138E42615197676C301EDA16B088819CF7324174E3E9520970E83A28C7E26337BC084FEFD1B9FDFF2E7EDF5A13A3DCC80AF8F506C6A66490CE57497829C58C3ABB5B89EABBF40D38DECBFAE8A03DF466A1380E5EECF3302E2989E4FE1B45DB7ACEEF2B333AEBA5DF806CE3E38F6804CB6BD32953991E78ACCE1545933DD41C7AC3543C91374E8C77C1EE0A2BB079A41654AB178033CF30271B6ACB7777A9F1585BF3226B81128EB67DDB35CC7531FB5215B04F171F10370BC968B65C6F77512EA8A8A82FD93E934535EC74663130272B1D63847205D4951E27BD8F4B9540B6648DF8F85E493860BA6AAF8B2A973FF3021D60AF5A0B9D4273C129E95793B273EFC3A52B4DD795CE21322DDE228BB6633904645ED74C08B94163E5A95D3E91C1EE5854650F8A8128CF803DEFC7872B0543055257AB908F6E5627D97652687923C600EA8F2CFFEFE640D773E84B33F28F6CB84F6ED92388450A3FF1FE46E43955E8A942A0ACC822963C56BF5CF956F99C41E7926AF9C8752C62C51C1E8F8B310A4399C3BF745052506FC869193EF7FFF5F74F0FEF88D70C579933B85D35C3972D85660D6806BD5B0DD764161E0F863D9FFEFCF87D34EC3F70C1B664D940EDB51D334340A9E4635EF480676A22B1B4C801D56E1B774D4652DA87CB0644E979D10778B1C041B1D90F2E6489E26555E8DF53E0DDD8E658967875EE41D25C7EA3307872F0EC6628C9C636C41A992910FD6C99628153D3DD6881871B7F82AE6F0A6E91CF871AF51BFC38A21CBA5AC463287CF7AFB765AA501D2C0F3FF8DED54F5D446AA3AE16ABFDC122A953AD0D6528F7E30C34B79EDA8DE0C4F912061124FDAE05D60001EDBEE9548C622B538BE2748EDA45DE098F2DFED34F46460DC9DBA30321B74E965C74920B9EC5AACB8661C63F45614CCF92089BD56D218E0987F696A949CB512B53264D0E8B5B283FCDEB78BA2B3D51F46A1DDD38F249619A82CE93EC57A76FC76407F8E5126C5B68B068DE7066E67781C2E36DE9214A260923F4CC22E07CCB78B7B3301BBBBF38CB844E745F9ABC72D149928F999915BE45D93B9966E4863D9D5E1BA79B6B4D93907D08C0E1B5DA2FD80986822E21FCFFB5D17201F1CAD026155FBEB9FBA5F8BB5FC08D5959DE9F42635FF8707A6073B55E349521275BBF7B72B4C1C7CFB6B121DF6CE2F871B98F72303955A79DC50872EE27FB6EF8658A70640749A761C545C4046B12B55D26C2888EFCFCDFF19E020EE96F30E37EAA0A098CDA610679F82F3924A17969794709A55A50ABB5FCEA546A59C49A874792294A26A004F843C4B472837C21AB165D958D86912823C1FB93940200E13E773047738559E64A96DF659439B6549FE542C6EA24A495B1E22F7C115145C5539745496826CA8052DCE4D0F28C55E7CED257EBDBAED9B457F262B7C99179499468CB3CE0273B524EB74679D2569C3BEE69B37E3DADB594BA93C78F69902291AB8A07246E9EEDC98CC0485213C707C4E7BD32864310B38C72BB1C7A9B1A444CC57B7A1EF39B3642FC60ACFE978D9363CE66C74C5066E132CCEB58C32FCF51CEC41FACACFA622354D70766448E5C447C640076119861DE0249512FBC4773412013B194828FF8A8EEA037C371704C4A7CEDD2E3894E05CC6E75410BF3C25B42E63B9D287885E682BE8E5FDF512F9BC667A56E04C094FEA642E7A6945E860775D4A9F88CDE98C6B3BE2D43A7FDC174C8DC35423CB7444F3561A561534B42F8F71DF4936320CC8C40FF791D8E7952D370C58B3926A7969D11EB7E79E8602C821CBB57B6F15DBE09E9D405F2F6CB9F3C5985AF3AEB6564228C042333B55A55EA6C025B80F0549BF32519D727DE5946EF2CD3E6DFFC074D15E0BE93A5F53F531CEC60130DBBF9E588427738AAF9070D7B87D1E51A16720AA4F2088756D2A01C9C5542EFD7756E20CD20B5D9F3A2F55404BA631AE2D47C157DDF29B635F596312A153B620DCF70A91C6AB93895398C3B91133B47E690403E889874C9E3D1ABA23F35A9D914C27D3FEB9053CC039A2F87D71DA703040189DBFCD4CC114C0A8A9227E8B674714EC030BA474115B5B3CDBB20B964A1C12B02D927E140A6C30F1B09C4B3680A1423071EBF8C65FE367A6AFD13255D6435CB69F3F0D339ADD6C20B7BEB7B7D9DD210A587DA87D588F565111F90799DC7CF17214F96E90471413DE85519B882DE15F693A2088BAEE85BB5873B0611ED7FA0C11E11B16CC05635B8B039E328D5400C8D3EFE76A3402267EDA22FF90B7D59E506E8403C2ECD217B310528B5FD30831492E6723AD06522E8B9AE979919DD0429652560F3E3C264E213351F0272FA697A1E0F27FACD720A60621F0A2D5A578227D38A421E0A088306262118D813048E2E763022EA832AFF510A0F93C581E7C80F94957CD6FF9059F72499A2A51796FC1170048C69D0AAE791612AA9F0ED76CE1792AAF06A88616A47313056A95E931F38219BE85DF42EB827FD88117EAAAE1322427600E7B44C58822B0AAC13A3604FA9E6E8D271731949950A5B0574EA668D90161B74124528BC09CD44057DFAD61B43B50B4CF81EB207933C2ED8F7E43E2848E1C5A21097D2AFB407BA94C3D11037A8397A5F203506382A0C8CADE0D2F484965ABDDDFE6398BD31B395EA2A4E8EF072F323C4258D8F9216AA0D4E148516E76A1BEC8D9F3F700000000000000000000000000000000000000060E171A21292E38", - "reason": "modify signature" - }, - { - "tcId": 40, - "testPassed": false, - "deferred": false, - "message": "0C63CCD167A88F14194286F529AC33F7296594D9FF530CF1C7894A89C73FF3569D2AA1691BF58221919AAC325A3A86BCB55F0EA6EB4808ADCCE8C6EACA20AFC574E02FB068E857370C80210701D9D98D7315AA76046736CCDA0952722D8EA1B3A2AD0B33C7FAD15FD6130E2215E2B71E5BF3786CD452738014F7AB3A482D4A1A", - "signature": "C95E934CA235DC9EEEB45817A6239B167709E59FE25C8684221315C4F8A76DA028286B07D6DD0733D1FA713A94964F325587E2BC491908B8ED3A40A014C82FD25D26B0377364F6DE69CCF14A5FD65AF5F56278B202B5DC3812C9801E96C40381FC45AEC5FA23D3B0C99E79FFD931604FCF9F51CD09484A671A1374558EECF31C83EB837D7183072FF7CDB1220F58E6B77522139F0F15049748A46B404CBB0DA079A347CBE281D717616DC8F9FAF5DF5373A3AF9FC22493586068C14F7BA5FF7B90E692A65688C8965BD6452B807BE5CB76EBF45ACC3DE9BB0E1B35B1FD8CF383933F1A9928825E62DCC3648D933921C926C1BE1B40BF7294BF9241226500ABEC0420EAB0BD021B0410D9A79181921680491AC9162819AE3B9821E4377754A37A0AC9A0F3ECC038BFBFFDFD7E3977D0087435CA1843B218E6C024759124BAFA889F59AB0D178EB2C3896CFF031C57DA3EBBBBD66CBFBD72BDD52D19D1AE307CB9E2B8BAF3BE556DF71B28BCA6F9B2EB69F8005ABB8D29117C43BF42459EA813C8CB4385EEC23984BAE661C59BFB7F9F06DE0A41F70430AA448BBBF293A9E66B55995B3A5114032A11FABEE6BFC0DB02ACB8E488A05D4EFD95ADA2A47561E91C3AFB64D24B69D0B1E320B1111FC4CD1D48F1DCEC0C8210E6E632BA1CD0448E3399BE8FF9FE05D280CD827F09CCA0A07FAC04B2C1C96DCB778A16735C5BE6D71843E9FBD0095C460C6033750A3A6A40788DF53C115624A75147D8FA8C1786F392DF1E52DAF68BEE09DD081A22440D801061260BBBBEE3FADAA4481D71E9D837137D6EA56AA4B8A30D5EB0163B7117C1404BD7E2B843FDF0FC3E633AC03295C405FD1BFE2FBBEA961B5CCE96300DE4D402B35DA3CDE854E55E9F0D89EA9E3E05D5E004FBA53705CFD74DEAACD1BEC24CD167A05B5D65A895944EF7729FBEA53B19959891A98EA2EC69E5FF4C22D3B2317955EB2B2976B096A621ACCC3FE812B8D59C195BBB7E573393529CA246D7DCC445270C60DB57EAAAE689FDCAA28ED889FA1F93AF6B454C8AC59C667EC338DAB35B7D2E6C5DCE92973E24E5B73DA0BBA9950AB8D2330574A10EAB9B41D52C607463F5DE9344F1035974E5B166EC36E8895D1530FE1A165DE7620F9957E795CBAB4A83775D4E267A6F660C73CF85CC675C0ADB8DC5957F960B3084DBDA7C2A6855D65F798E8F9679A4D7F96FBE07F09382FA424481FA2A4D808D501122B46F1B6B9D43E8C9369457EA2C6A77F51669D80230D02F2EB017B19352851B7A0726E4BE6CF69072AC54B7FB5D431940D06CA58B2EE61CFE8690A0686C62E1B29F4C22C28D3C386A16D63D8B9BD65353AA48188EDB9F9B19FC9B2302FA4D7864243E959C1BFF2DE4E256BB985D4DDE0C8EF9FBA0FE8A7AFBB2CD4976C3CD3B9F6FF162567B65EFEF5BA87F3AC5509976015BF404704BE1657A4B89D1DBC98072838369567C08DB761FA67A4A2FFA2C7816AD31C0BE09B0DB27D2AE9CB7DA26DF378516B17CC07E90D7B702BC7CE3568F3AB902697164B853BCD36E2A290C1B7261959BB5444B6D75C1749D939145C6411DE4FE5D1847E70E473FBDF632533153E701881C43B89D32FB3E112BDBEA5E36B12E15F941F4EDF669A5867D79B34B23F1F370501043B8ED95A1EA088A46A5D0F3177A2E81DC06026539769808058916F003E05088A062CABCD190D9CBEAA12F8D3A7BA0C6EDB6AFBCC3D1A269F71835CB1D3BC4649F998903BD1EDE9000BE5908DBA93BB4C80BE7DC9F97A28BF7EE423EF15F6769F9031AADEFC28C4715A27494CEE7EC990B59D941FA42423D8C51B6869139302834567316FAF4595546A19F317DC3A2BC8BCBBD4BAF3546CBD3DF2ABAB198DFEFE75C64574A35F3B1E1B9BF303FBEBF08423DB4638002604DB5BE70C47DF86C83096BCA682E1EF3C65A819517DEBFF8E9EA59C0DE1D8FDF2F809BDD4D8C8C3CE248A4F49FFCE91DA7BEB1361F40948CDD5F6FFA77F4CEB79B3877CA83F93B098DF64A3E864DB265DAEBC7FD1B8F7B8C83BE4A77947A43D5351F107E84F5A080D91D85B45466906C6DA51428EB08E0D9D61CB4A02A7E4B7C66FFBD1DDC3A3EFAE9B3363AA6DD3A09DA1601C9158B604852B24EAB2904224F24EDEE8359F165D536E17DEE779E3208B8960FD1426FE9DB8861C81201CF55F527B2465BBDC2E4EF30B3E4633DC01CE8E34E1B4CC9EC0C78AEF18DDEBFFB013145F7D80F8ADCAF2A4D1DA1B30DF901957D36DE50EA5B9B5560FF3343DB04C8844B5C2E546DC426BD945F8E08C4A04454C0C6257F1E1D796C29466E099956118AD53847F4A579D01976D5CFA389962ABEDB6AFBB91E31D380CD9B833586F5DBF598B70D76DD6E1E2AB8BB52CA97DE3705ED68A2A551C96977DA36FFBD27ABA84BF99AF9C539AAFA55680259B9CE72F8590FC786FE62A501D52B0FDA85AD3D245E9F29BDE1E278D1E2722088086CB51D97D960511814F9CAF0A5A57E2C616867138E587C17DF20E968BAEB83179003F9B3D9DA0D6AA15B61547DF2E9612792111A271F723E7DB4E8F2AE272D356EE9753797B85401E83E6C5A87DD147DE6BB95A55C00BFDE51E3CC6360C8E827456E423799D294EE3BB81A7B79D9938609AEC20B51D2CC17F08D6AA46B106771B845358985DCCCEC29F861387CE570296BFAACA9F2676B417D625322B50D9E8BE4C05193A9FED61237B44851F3419BA403DCC1662C0EB30EF3BADE28686E3E1CB3783CC3C8D78E96111562E08C132BD8D3F26C8E9665400EB44154E4D1C7CF16A52108E21137DDC1FB310B7A8AEFBB7BC7C09BD062C82C3F490D5B5991665D3BE017EFEAFA648833E958D43D16482DC95C867357103A0F141D230522A6BF24C19AF25876834AB24239BA5DE9BEA4CA4A22B09AF59C69DA9BF998DCBF49F8486D8FC4A16A411F9F273FA44998950C620B3DCE24C5E6D5CE4D3A070BCE23B20897BBC654C154E159B093CEFEAB13DD4D07ABD1F4009FF72FD850AF9098755214F668C2E1A93DE22D82DA6711D3E804E0F20A9A95775276FEE50B3F3A348154628D46E52DC934DBBDC514CF9BB6754E349482BA658C73E90AC72C84550C179172F87869237C4A902FF0FC0B8466BF2440F0EA1CFC4EFDBD925F725A90788A4A89739406EE38975CC50563C08513ACAA7E490AA33D67921A189BE3216FAC4376CD5C0CD255452D7B353C5DE44BF66BD420AED104C144DCD9B6F7D3C40B146EBA5BFA6E479892CE194BBEA3EF1A3C4DDC49CC2A564A5AE61969A951F5BBC5B1F580F04FC8E19896598A0B1BA2C81A9BBEE1F7AAA26FEBE6367BFCF8F86F6EB2A72F88EE772AF8ECAA0B2901C487878ADB9172E330434A72CB709258BA93CD819DC15D836E944C1ADB83E57547F6C0D3D1B026E7585A8B7CDEFE1E48DF5C83130B13FF078526B21F57D3EE3A2AE3BFF55BEE412EF27F9065177943617CBC0D7C164EB2D46CFFAC89A65B7DDFCC75AE57C63A5CE04741D51E5AEC1DCFA0F27B47C4219207A418C82CD513AE3252131B9C9F46E86A4FB45939328C5F10753136C5484D44B49CE0AC7373CCA7DF7AF2C0B7123AAAD87C0921B238C37668CF8BC77D7105EF2D994EDFBAF2DA2121C158B6DE42A49B5A0CE371C2B629E2B7B585665D5CFB24EDA544942C2862BE57E6823E7CA71C46C3C0AEC9711B19EC11F00DF8FFC8E1AECC8DBCA323B51929891DE34968B5F58F9DD2A9DB8F1D6528AF7BF68AC5C0EC44A11E58FECFFF780077C5F9AA436BE772CDC5547449B7F9189647B1E254A449ADD1683FE7B7D1482A3B50D664C7B3D170E47513B41EBB4C46A3780858E1EBAD19D1CA4232D53A426743DCA140FCBC8A24D547CAE2CD561ACA7924FEA71225E289361FBC2C540D69BCFDAA9FF51D43EDE5DC6494687046DA39F3D38FB3DBD776119F488E722A79A9B416DC4A99E0EC04787D2CEA75C134C7AB7C05A332CA04423B6F45028D2FCC4705A9C91E6351AA120F4C78C4F2F0E5BD221EE7C07ADF701059C16A55DED766A05A43DE4FDB40EF8BE2E69A45B4532DEC5F169BF404FE709FD5C9113032BF8818F2F51A5C3704CFE265B005C481CAB1732D94511C331C738A838B15E084021F5E10200E034C02FB2F883F2464474A40B918965279AF19225A2748872832CDBDA50F0729319883739069F78B872F71337BC35EBB581445A9591388BD71DC5121C1E985F634F4DA5FB8F1917A9FDA424F4904BC21BF6AB7E24BA6C00FC9A89B3A647AB5756456003D47101B4A336800EDF75F08CC0291689406E416BE8C6D4826960FB9D7098D1786D37E33D2D0F3778C5DC7F87CA6858E3B4D5D880081776B5B9F6A1B26D2C829AB9E862E33BCFB9F25F19FC3F683C2D3E6F89518C5A763EF5A64A3256CF889F7C8C86FE7BBD800C479D507076C628F54C61D8F749A6D63C363449ED55BB9D9684C9E00DF3C4DAC78D73B499F229B708E44F7E4692FE6AC01D8FBD18D486FA40383B3BF7B00687E3C0393A0D4894B60F8C9A395C7E6A873056C486FD05B983AF8127CB4A100F7D49108ACEF78C6A92390B984C7517C6016819D0A712E808C46A6779E3FE151E12C88864234EECA65AE2F3CF39B1671DAB8A19726A7F088EA15A51282BDCBA93C22EDBF67FB9FFDA481D929BB8A3B35659DB2C235F3959B60901288D111D65042FF4BB30E4D92A90B0E8997E9060C833D2D26E9076B5E1AFAD0EF1BB06AB415C7389A76324184DBAF2B9571379BA4168D316121CECA90BD032322D3C0B227830AF93F3E62A02F1F34B0162B957F26DE9ED9DF233D2C3F92C25018B5D38794F856C98F76DC40DCC6AA5DD78986892877B538EEC358DA64A2DCC3812BC4B66F28FE12DC453D8A3D04647408F5FB040FB54EC9C645A2BBD5F04DB4ABCB5BA5B0865F1FE4428752A6BFBB3B8C9F92B522B6324BE69F567F96BFCCAE23F50B60744C72BF69C319C241B87299601933495D055CD60664E410BD484B06779A0FED262AA5FEFE085EDB88F3D9719A2E8345BB8E43AADC517183AFA83BD75C644687351D15759659B244FCDF5FF2672CBBA883697FCE4351820659A22E6106301E27FF03F850246D55D535A9A1BEE416912D9D95CC662CD6E3B7600E3F60D72EE27211284BAC7527D49F8DFD2A1C294AB5244D27D6202A7DD740E60DD744CDD35276DA2631ABFB3F5BAEC841D94B2CB43ED93E2E0717B3EB22BB4FD47734E599FB1C5C4AE4EFF01BD51582B0B8EF1E8025749E1B0C91A59B09AA55FC4886703A05448ADB712164FC815A6662BCA0CA12425C38730B45C047852ABA90EDD23B30E25421CC59BEBF3F701B861DA76313DF425473BCD7C09D9F5F8E2D91CABDE0E84B4F26885FD99231573A5E6383F3CD9F38EBF906C8798E3B29A2E6C86A1970537B21B4F0ECE582D7906598A0BA7A04B0F3ECA48FB28EAE5BA083DF3C3FA714C753E1C72595D741E374F67E8DC85455B5253BEB0D7CCDF3A1F8E565F844676E4DBABFF5DE3EA1CCDA3A03149E13B505CD2D3285C7AB79355D25846DF70612CAA9D13E8A070594BB5B254DFD4D632F42295E0904719FD8FC26A2EA3C3194B155CF180E977BA9D3DAA9677C5B6A125DFBABCD52CAF89A406D33AEA504D4EAD84283055AFF09278D6B0EAE9B77A03402DFA1BF7917DAE721880FC1881DB132FDBAC8563DB1A4B184AE8805211DC8A8D89E61148E2F3100BD055573FABE9B7314DC7F8314A040AB05045AEA1EC0CAE452D6FE031F9135F2D505B1BFF78D65F43D9FF7EE01AFA332165C3695C11C8CD48C975A3FF2172A8BE049533F0A98E011471681F6F728BEE5721987D4D14806F525721C09A6210AABC56ED566961E167AB8C4C44714916EC6B9C3600E32A06667E35C12ABB832B9D94A6D05FCDB5F3AD31BDE2B47148C80D808BC108B2F3AB3BF5CC9F84B60473651431EF01ED69233303E26E60A1CDD6132085FFD53524C8DD88722EA5A0CA7974C6C1962ECBB487B58A5D1981F0CDA6D3244F13C4439B9B394DC7D50BF616771816BDD17E7E64BBB51EB36421F1095F1CC6DE363F26A3C0538D4FCA4199D5BBDFD9A489A71D88B768773920C281BD9FC9A848CBEF9D136114D215A6F996C61D601484EEF727E01405EE8D99285A14DEBC231EF9B2BB01108EBF48E3C12B0D723707FDE4C87A673D5118730CEF0D23DA56CF7D1FE6E4F7CA90D30550C073B2124C83D78835EDC93B86B202BA64C6300EC11F8D7A2307BBFEA50ECC3FC41560FE2DE6584D1C9BA7CA10DA7C70284052053616FEC2AAEF2D5AE024BD2956497BF35969572E9DF383773886C36D2F4BBF76E3A44CB36CD4F64064831F5F3C9A212A6A23DA7FB5E051890D78140D4113E21FAACF8444AF9C73AFE4DD54772CDC9A58C7836C9EDE9827D6C7A2B1D99FA6C33756003771D6CEB3FA05139A6A8977BE3A931AE65DBF9FC4EEC432F7FEE2337CDF20D212F68BBE1F33C50525C619CC2C5F0091B7B8C8FBEC4CCE18298031045565A65B808121D2E385075C2FE11606A959BC300000000000000000000000000000000000000000000040B141D1F262F35", - "reason": "modify signature" - }, - { - "tcId": 41, - "testPassed": false, - "deferred": false, - "message": "0B340E19B2043941E7B0F80507F1F586BDCC03D19A75DDD23809AFD11CCFFAD3C4673C825B14877FA1D0DD6624BAA8E480A98002508CC648B66A2D3A83DA12C5161CBFAFD575303DCE545E61BD943C664333AC2E9511EF841612F78C5256D3FF319BFA6120EB172CD815134010DD5AAEF67F9057D94360117DE09BEDA20953E2", - "signature": "49A65D1140D46675E154D99E7C158F424C921204BF93E32E84A7E3209F55D4829E39C0BA4AD6C100B4D6AED81C556962F12B50C3A1AA43E07AA7D19470E7D9F1592A69DAEC642E705924B523D4F21970FACB78BEDAFE43967FB8F475F02D3B8EAFDEA3B21FE862F1E9D8CCDADAC689A605158D0D06F3EE2DAECF6DA2DDC0140D31AE1A5F9917948EE2ABBCB54CEF3C4F6307CC7280D38CB4A51FCCD538DCF4ACE14369792FE880FAE536F35C48828B7779A1B9BDDA19293F043DE269B97F0CBB2647ADC0F04341DCC7426844B58D4F32C0ECBDBC068CAEA0A6E4B8960BB80D75C23A60ACD615119B3280947F4593831989E5426E2D268364B6D381F31CC4083743F29B56F4C402F636243A62B0CAD315B1CF14BC120D1DDAEA3CE7864ABD09366A1241CE925BB5CB1B0E4CC51C2D8617549D2A627A7C5062307FE01F0F16D7A33EE3134934FCADF99D13574D66D8E97FBC02ADD7B18112975790B16288EBF426638F80E3FA26DA81505C56AED3B6AF8DD58A171A88B35D63060CCF56D715252C1E550302E40DB003767569335B03DD483DED86CDBCC8F0B62F4FB7BBA0E39ED8A65714459757665E9357DDEE1C10C7189FAA55A95E11C99CB4B01831E325244EB1FB21F89EC2054A23AC89C16FB28D38787BCA63B4642E3A065436650A78A2AFD7C8DABC4C904BD255BA40CE53FCAC84F07E85213EDB8DE9E5EC9D92EC50495F64CFC871985EED039DC5F538CA4E013CE29551C3A32556B7B661A5CAECC65A4D9C565A5BF5738121A8950ADAD2826C2DECDD65D19142E8346BDA85207880AE284DAFBB485C4C7FE9D2E91B2A027C85542267779143A3C33C00B9866384F88AD93CBB7F134E12DD06A8A2555375C6D2681FC2FBF931E534A37A1BB8CEC823C041E54049776EAEB8BACFEB899BE4A2D9DC7727D3A63398CD230CF79C9BE9A77FBA48C1236A0AE076CA169B483B0057C21A3E7C593377E3760979A45E2FDFD653B4C0EF75EAF2979E3288A78E23C21C15B421B9504DE1800A035CF064ADB30E6213D829D293FD5F7B27A96BA398163B0172EC91BA569B01186F5488C98E5A3BE3973968409F31232F9967F3FC1B1B1F14C1A4EF9D238C840544FD466AC31EC5CD915774B1B6D31DC3D8015A842AA31B033306CA16432060209AFEAD43FF68A0E688E9928C72CA10FEE9BFC07C14C7A58F6C0959F994AD3D9573CB875765C9072741D47E67D48CFF03D1C159483774FEBFCF186616BF0F61E8E560E40889C261859BE21FF472809539AC713273EB1C3E3B39667B6383D55EA05A4159B9870214B175EBA1E393A43EE2A4354F507AC845B150B6FB0C1DE94DF02836854172D56FE92E7EB02385B2BBF938589FA1B280BE72B53DC26D65D6B7F8C5AB339F055C0A4EC6C57C6232448EA637219429D30EBDE7465A57CC2E798BE7CB0B83191D3984F3054EC7674ABA773224C2FD53C1D7A14F475B248FF23A9BC724844DDBBF8FD690C8CC2F660537B797039667E6449552E39B8FB5638AEB3E41CC8AD8C048F403605275C0C72588A593D11392C5258BCE745BE5EBE364CD84052AB3A609BDA0CC1F2B120BB6600A7E24BE93DC5317D3F1AFA0B3B2496D744ECD6711C5E2E1D1BF0F75656449BFDAE5ECF0BED74A0E76F001893C2D1FD118B302BBC33208BFE5891B47E333ADD1522D71368B82B68E0FAD57DD06A838FFE76666C3C055B9DFD1BD0A3549B22E3A42902567D3B59E0D1EAA3C290BB9911D54FE40950C74094C8C7E56F4443B83B0BE8F04169F4F18796E7D4CDD04484E780D7706CEE1F53303E604199F36C62E2A0CFC18379F428AC26FFEE3D0381C5C7D7E7E8D9F2B34BF648442BF2D33817E2239F9BF9ABF5FE4418E9D4B5AB2521344091C5418FBCF73BCB2F6F639F7F6110FD6B48A6DE268EBB6437C0B10C7159D22A2A5FC510F4C5CA3E8F23D01E4C65C17A88D5A1E7611EB7607717A22A7F82560E83C20A902543387506679178A129B36D1BCF3192C4B3B1A5B8A97508BBE95E90723778CB574CA8210B23E95BCA2CC380CAC5B0BA367F1B38997BA35BC89548CAA818E194364B465FFD28D10814181B9F71923E94F09A817FD0C157B5529749AA130A8BCCAA6B7551236F665A30E115041C916C291344C804FFE423C31F7DFB746295110275AA29E34EC03F5A2FADC580F011A0CF9E13E657963E552465728300422648986AABEAA1B90733247DB28E636E0594AFB09BFFE21130C974671765D3A197922F633405137FD490EBA9B953AF7174F3202AEB0CF91FB96200CAB719EAD3E3B93B0E6AED95FC38F6736D8376CB4FAAD3B275636C7239D8DB7E64DBC3811B297CBBA994E8EE64F60DCEA83DCA533102B412BA540F850957AB002B62388AFE9485D298D4BB64DAB4C445257611741A3B25A62F8433BAECB34B0BDB6E2246BC62F2156690BC67DAF50E13C8A797C911AEAD9F8DD61EBBA1159E9C7DEEF678673C06A0ACAA57472EB5BF0C6E26139F551054EE16B1CDB244F6FF09CB2093D273BEA1A7CD04CD520582D9627266EA91D2F5DE1E7FA423AD598904EEB603C38EF13D0B4069109C48A27A84B8D44C9B3F5FACA26C1055AAF326E1C560B76084D5379C7BE7457146CAA6F7223E82C32EBF803130E1B9928A5D65F7D4713327C1E62318B169277AF942758E4ACCCB3AF60A75ABA281089DE3D4210FE485C3F336ABA95E0BAE3204CD33FCF0F296AAA646814F1CA3F7AF690FF289E29A8564038B20707909BB50C48431C0A4EBA40E0A9842C9524D3956792A9B0902C8C5D97ACE13AAA07D86C9D415EAE821080AF50882E4F1DBC4AB93F82601AD4F9F07AC7F072542844C9F326C26654B17BD5162FC3111A62CCC9D5CC5058C357CE008B7583808526135B4A3FE9BB726306997D520AFD46E24C790D10E63758C28D7E610BA2CDA843C86A97B842AF876295BE7743E4603CDFAC7CD7152AF2E0564607086B62C488EB242EF10CCCFC34B7826BBCB6EC1BD907F6758682E39B8A9CED3413326602345D3271F3FDDAF77BC2BF378F7FA999343285167C61A5E71F9B6F01FD903B7E7DDB6DABB7394D0C889E89793AAAFF8FBA202477E7920301EFE2A1021994D9DE9EFDEF8D4EBC15B29926ABCDA5CDC4D84035A43EA7BA03B1556E319F2E5155FE1F625D65572E57DA6ED93DB04D85866F91EC083A109EF9BC11A8236B496E80A895A48E52B18E5D7DA80312FC77FC4C4EB03DF576B3BCD1C8B35676E964855D88D561E981D5B280A0FA090E0322FD47F027092D7D40CC414A24805AAAB2D3544DB6223E739C899C578843E3128F9B60F344FF95EA911D57111224BFB33621904468605C178E404F5E129523765198FB59C6C5F57B32FDF364CBA6C1C6E2135616C6F54FDA431BE95DDFB92C3720D91C5C99431BA9716F3018B533A7E41323210CD7118DF726B57A1EEA7025BA0395F7DC34C6294F9BBEEC48EA2D643F856B67A5A7BC4B26E8C0078ABAD5DD1774A15B89EBFE4C6C8A19CB9CF4A75678A2540FA907D0E1091650AA77B10891E33979B31D2F7B7D04ADF648FFEAE0CBA18BEFFE582AF1C2BEA0C02DA17A7EA2BA484DEB7552E73151869526A418516D511C3D3475C14E1EC9B4AC5A122C93A98AABCBBFF3B3128CC280871B4A7A5197093EAC1BA34A2B95C9D841D1E1D604491CC259DB8FF1F8791B24659DA53A1C3C95FB627C2B855E656C01FC6FAD6A5CC0B10A51BD635D4F2646A906697E7BBEA6E50EC7DDA0BC9853B2F537C24A7B0E3922760C082C437D6EFC19F9C8A749171CDF7F3C32BED621746A95850A3F7DAFBB903245FC58E3C9E40B434AB0097EE96150F6FC87029DB5CFD7768BED7EAFD8258B795B189DB9489C5F27E5CDAE529ABC08BC95C8A05779411ACBCC2563E5BEA4633E3921459AFE4CD167192B2F280FA5FDC761C1239BC22BC558C3699FC0A31AB388342F580C4972C2A96D9AB20AD24A3B27CD4407D4F4C37E2B3E4EAAE7A0C5C62A380C30AA6D2D103FD15FC79C9C37183F20E7A4C13C4A633DB8D54770CD205930D27AF97C242B13571636FE1231770CC5EF8934258844F373027A888BA7603237502BB0F00C7DFA412CE0996052CCC446348D4F6AD31DDF4E6E91B03C0329F7124AE619432D2D391A275189BD86DF5F6F64395FA08836F692DC7B5A5DED430CB3921E059C52248254772E1D7ED3E6D00DDC25D2DEA29BEE0F751EFB30CADA85146E4999EC5A4D9BF1A48BDDCF4FED7822A50A5C600A61A24A03A9E60EBD713A1506C055F23DDABD8726F3CCD0B91BB38FDA0B023BB7BE6AB85596B54CB3686D5B1BF3DDAA8F41FB6FEE0966FE2E17E75F483B2445B096100EA28CFDC822319CEE645B7D66797D7419476ED8F8179DC3041D2CDF941064DF71FA0E2BFEAB5BF4EFAF0C9DE264FF4733C494EE4709FC6E3E7DBD25A803DEF3141E3EE722AB3B191287338F07CC017053723A5469860BF631246225ACC9600E0E91EFDA6009DBCEB469F8DF95DBDD7395944DE61E0F4FBE360D4CB6AB8D19D1A479BA373E076F7E70706A1BF95AF39DD374E5FE9AC42BAC6B10784AB8220C0397C3E8BCDACB9D806E4323E841DC80F39FBF4328D46F964E5ECC2A33248EFF1758A388B22D620B52916CD6D9CEAE5EC7D23296339ECD7E3A173E3DEA02227B6CC0E036ABA79B0CADDDF3F08E5EB0A8496F85D26C2592D2A4891A5C1CB34395A7C72C244AC3A528A7E3E2BF478F9D74D45CCE1C1699F86553F17D9C3FC6A16F8D449DBCAD72B59B52FB9410BCEC725F4D964FE0B43F7C03EB677156E2A02381146A13B9E93807D860C10975E8E9D295F1D626647CD9550DE87862BC47CE239B9FC997732FE794DD99AF7C3068CFF65A1250F91F2CA3F90BB6C1A6B0A6CEDEA611948FF04F4E0B89E0FC4B40B424B8C50C402CD1441E9A5A387A7A577FF9F02EE2EBF97C4FC00ED606C413C71B873EDFFF415A5EC78D4E4CE9F73BE817545B3475B4E485A062CFD841EB7F4572F7F6F705C7CA0362C934449BA673741CDE8FD43786B08CE02347D612550D98139A73AF83A2D377C1067BFFFEDEB666FAEAA1B9C9C2CD8C6939CB73DE9AB305E125B259F0A80E7B99F2E5FEBF27F5DA65E5C036B50470BC78430C1CB7BBCF40DB773543040B1D8007669601B2F1CF098050871B15B8ECD45942C79D995A2A7318A0D00FC2B2B25C04C7D3357A413593A166FF7C8CED6E5AD92D0D8737F42FF18EC9FA4D6D39F1EA3BC8CC253285B4847ED982D2ABC5D3DCD51FEB9E13437058A74E5F72971988B7B354D0916D78F3EB0A378BA1917E089994D7BE851A1A17A7E0F25ABC1E17D539478DF18194FF7CEFA8B2B35772C6D8DF88A8152F9EABB3C9DA3101090F1AF76FE37F54D1954DF3EC25B1E014F2DF3BDBB063E34509520DC07DF8B11EF61FB00206B423F43E10AF77F0E401DB9D005D253E284AF929B0BA17B65C8162335A768406ABC9AB6C2A25CD257F310983B15A9B2861E6986DA7A46D4A09B43CECE1CB052A6206FF8B05CF5751E854C12D83AEE4CBACA03863DA4868275B8F08A5474DBEF4A5A5CCFA69E8A7F3732A82B5AE22027F62005C771D907A583C72D8949D7457CEFDAD560063534DF6D31DF32A6445492248BA10D6107F3A00225F4530ADE4969A0F567FF5711BEC3369A0271A338F66EEC97635363DF4CFCA6429CF9CF711260AA9901B12D6605D0342A86238CD891D50736430575AFD05E067D806CDEFBBF7D501D8D394299A9B3C3A66A6324BA6C9052F9B41A030AD4AD2957D77907FFC29BC5007CC15843887801FAAA3BD4F3C52FE093890EC0B45A90DDCC99E14896C039668B4CFBA959413049C1739A430502E7643011621BDD7C97116CA7EB093F4C5719C8878FEC0FD31D4B0683AE5C4FA5E33A7E0834E5ED6E68DB138F95F748C450FBFB7399B66B418A8AD203796FE0B0D7327F2628B5C71AE0F03394E6BA312A61587F8E62ED5CE71C202AC6910BEB31A23382D60654F659052E091B5AAA8BC5A33D0BC3312E914C57018EB54EA0B3CE4CE0D55CAE2668D37DBBCD38CD7B7CA1A61D4CDAB75F50A23AF9199BA6BC7EB7D2553DC0F9FA52E48B8C68C7A731375A5A9092CB470F5F28BC59AD309ECA693AEF5FD0E475E49D7FE1F33C5A324499259628F2D5B26D5ADA97BC2F983EAEDCC1255D11427B61B18416B3962DC03CB084F23DEC9F61115669BBF5D833662664328D365937B4D845AE7829BD553F47E1D327F967D90D642D297427FC8521977637BB27383ABBFB736235A11EF55E1FDE9ACD2E94FAF24F4789350CFA58C1110CBEEA2A29C4AA9269C532238BEF1D6EB65757C2133AB992D4ED116C94BC44D746301775506A3B220D2775A57789207D49668A5C32858EAF64EFBD33F1C258D29F906E7336D6C3237BFA2022E999275C5DAA606B006598CAD77EE67E3336F3E2737D2787F8F5298011553810C1527445157CCF80640477889989AC8EA045462798DC9D4194B616A8ED1D3FD0732455C89AACED4FD3E6589A3E9252B5475BAEF00000000000000000000000000000000000000040C151C242D3239", - "reason": "too many hints" - }, - { - "tcId": 42, - "testPassed": true, - "deferred": false, - "message": "EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059", - "signature": "372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336", - "reason": "no modification" - }, - { - "tcId": 43, - "testPassed": true, - "deferred": false, - "message": "EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787", - "signature": "A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A", - "reason": "no modification" - }, - { - "tcId": 44, - "testPassed": false, - "deferred": false, - "message": "72CA115375E612297C7BF0460D38247B3661F5ABEB7CF4E3278BB49E2DF2A96600F19D95F67BE92F99DF204D06ADE7C8F4C04C527AB5F70F6007CE5F16AB099DC8F7F4F401183C83B47060E38B55EBF6EACA4A378F725EF4E59EAE32FE9DA0F9C2ACA2F1A4D2933EF8DCC5D8A9DDAE0E3ACDFDB6A5CC4A6BE998C79557345F79", - "signature": "1211BF1AE554B57C92AE74BD8FD1EDA9B22E8993D2675D2A2B68BE5E075B1815DC1B65582426A37B0C6B5F4BDF20129E0B1E04BD27E33888148ECB88A0EC7CB7CC58E3767BFE3538E24996761C624377D2150C41D59E18889DFE6B520CA7F7134B2198F4046F49C93D17670D314D856175E6984EDA6EAF1136FF2504F9B6B82A84C72DA8CA0DB3BC235C7E50E130369A85225BFC014F127A15438954A2837EE902119B26AB40BF6B7C44737B535C4E97EE475BEADB0F3F94510D05A6314DA421EE021A06DE18374B7AB1C3B4D024CF66AB103A010E40D12D3B8AB73980728AE88DF3172C5267095618070D732B52BFF4FB42FB68C9DBB9AF8B3A09E535D7F65ED1BA967247EFA9B8FB7CA86B30701E1F91553E01F95444A52F76540C85231E114A7661A7C479D8CFDFC0FC9522914701E446921FF84D1CE4C06DEB0A4478DC2ED341EC19BDDE823603DDE9510F71B5CBCD4DE3F6633E3FF4832AC830027D9D73F362A01412B14D7778AFF81ED02DF5E2DC21309C79D6397BA38F620E98D65A0DAFE1C8D54FFB0F6E01C6489679205F2F9191707C755C4681A23C2224CF3825AF56171A892066EDC36011B781DBF79F7847B8C2CDC657840501A5D0361E8FA9C273AFEBDB4313603A50F803ED419C65A741A921D25FB60653C8EB57703EF4CCDE3CF251DB65A6CE1EC4E2BB5302F2F173E717C180998D3116C89CEA8C60A85AD425AF90819056683A299F02D20514CC23A09EB5AD82514FE04CED2E51A11817C38CF666DF186B52DA61687E40AF5EEA73A07C37C3EE76E7C72F957A83788D4602664ECFE8911C353CF34223701AC2244C3B2D13E3B0729AE05BA52CF345D63A33E0D4C8829088E392AF3D6AA094F5AEB09B64487745F555A3F6FCB54EEF667A8E75D397E5825489B3EBDDCF86342372777662661061549AFF706042425E311E3584035E5760D3ED592BB84F236D8A1DFD94A49BCEDC2E23CFBF8DB8DAC7730FE9BF8A89F7A7A12BC4627E19CC8E55C7B68B8F92BF42B7686083850F632C3BE403F988CEC8EB04DDB206664C5123BCAC26ECEDAEB75D39217A10C2A366C052E54D18EDC9AAA5966B5D6D52B31E88F1BF4E986DA2B46F7B1157C06F7B924DF871BC8F9387FDB9073BED2E883B43CCB57A9D7C8DAADC44156D08BADE88FF9B3730829568954EBC46A75840E7BF40CF4FA994B0A7F03D3307001E3F98073424BC7F3D43FF708DC8F17492DCD0997630F912A16FC28F388B81A0262FAD6BDC1830348616A56203E8BF36CBF4C96B705A6C7D77DBF2E89B15DF185B3ABE8B58FA594C247E7A97CB9C616332B50E4B14644158F3755B4333B09564C26C15B5EDD3403F526CF6F078B49EA32AD3C3051A0EF7230D43DC09BD102F28C2853292C108B3D45AA2402D5A7CA29D9FBFE922C2F9513CD1E6B76CFBFA1D0FF147F35C9ECEDBC96FA0A33FB0EEF37245474153CAB8BB1313BB3A328ACC1D2D3DF243C439BF014855AEA9D175000485168C857E47C43CDF01D19F5480425CDBE8D2A0243DABBEB1D2DF43FBB93EEC2497EA63FEC6434CD256CA73D4D0F173939B82FD9869431E86AD231C3DFEB9856B4B416F018441162EC0D747A4B90DE0F4E009E002BE016570A5617CA1DBEB5705C56DDD028CC5D107227BE307AB3E58FF43CE039F5F20B9D84B60399570084C5EBEA82CB74C2033E6C0CC65E557569BF2DA761B0DEFF5CAFEE2366C68561BB679CB5A36CD8F41228E86E736831F825E5ECBFB11AD0795865169BB3CC17DFC3487763DE2C9F97AC9EAA39347AA0CF08377B046E83F7DDDC021AFEEB96BE53BF0B2DFE77288D7EECEAE08A36E29BEBCC8328551982ADDC2FFE40CD0F2EE075F2FFDBCBECFB188793BCCD837FE62CA5C70DCA57FD4B2D041F7D6785223BD0160935B5255003C850BC473171302C99CC251B2D790FE0A4A2A12F98B1DA0055353CB9AB3A88DC2C5BD1E10A3BA0674F3B533C9FF5523C6CE691684CE2687748DD5B04F7B8C0472DAD3CCD7B897FAEE9C6977913EEA790FBCF9D78B29BD0509A7B7422EF951CEE5A979F54AC17CE08D666D0B49D7286BF064C11F23EA72C25A2F4AC497F9D4A7C2F5973A1F9ACDEB383498903EC9BDBA617EDA67C2F1EE12A895F82729CF0B709AAF901DE1636572F39F9AD56E925687B5425EB9BD69E381F706E6F5FAA4B171D8233B56FDBB27B949486F46CD13C803467A654EDC7626B2D19874C1BDEE25C4EA73B007323F091B8C14710EE1736D88FE4EF330CA52FBC76F79FE9A102FF706261A999E874C685A3ED5B5E2EE995CE1330580381BBC62DDE13F917CFAD6811DCDEFC9B3064CCAB8CDB8FCD125187AB46B335BCAA7E69C9C2F5E95A94612362B3473F6263D5B4BF635867631D609BE0039D32DA303AFCAA32140F9D08DE2391F7F8D2566DF591C365D5FAF0EE3394DFEF4417DAB1F404005B64764EE9569D89C13C2901D0526CE45AB4EB6198354A97FF080B1AF57C06F4F062A6C295F8AF86F9CBB49922377354AF8C0598B2FDFC0E51AB9A429E9B973F5804704352717FFBC392D094BD5049C1360CA561490D5B57F2C14B40A6FB7597080A28501BB2AC61E38CAFB10BD97226F7CB9089A9D4F913345DA269CD4FED4D54C35F4908D97FB1FD79B84A81209090E12D642BFAAD5C6DFE24468E9D0D89A422F78308F0459FF1D7D444B63A37D91469EEA6C9F6118D9367C76FB60CF50A731F8EEF6A1C19C7DF13FF83C6C71026A8C3079C2BF5B430CAAE7D7BC42D2957A561E22895365AC8126B8350A2899CFECFCDF24357D3D4E19A127E934E6313F65B9C6E9E9FA34650F89EC90A042FE8B152D75B900E1CF4EBF10034879F279E3321D80DEB7161C5F37DBD5D435E2B844631F9DD6590ED6C33A5BBC30D71FF6A03897FC11DDD6AE2EA9FC6B51EE79918EB583F85EA0FD4A3F54E4458F0ABD971E9FC9056C9CCD91038A19A807CA267C6FE287B30F054FD8C05992B405BC6C509E7C7C1CD7E8AB2609AEF6A8904546CB727B7D857E495F892797FB5749EB043047E553647B408F55BC0E22DDD8A05C1FCBED4A4C1C70970A75EA91D7B38E30F47226C9DC20C9286935AD568D2024550E5865BA1A807EB1CBE7251D72803D35EC6FA561780FD088B19CD7B43D089E47EF8ECC1B4BA5A719EC6B99F20139718667DA4CC80BF793F1E7B4489B59F0D8EA66A5C8B70DD3C8CAFC9868DC9133F698E76D0543243E6DDAF6AA06230941E0AFA461CCE0DAFFAF61EACDF6A5BF16E83ECA3EE0E47C25E831AB9DE3FFE14C4D225C1EAB929CE705A22ACD28F59A21072F2A1FF2E13510C2EB55F379AABB00A0F900D1BF6756FFCB8803D860D3CDD3071E6063728942A08127A2C8535D751A42E319B012110F14EDB97FE1C28E9BBACE0523A4CEE18EC642E7DFCE61A3BFB6260FFC3BAC8115F5050617FE9B5E9842A4FA4D88B6B4EA76F71AD5DA7ADCFE47A68CDDF50A9EF291D1444DB124A36B2105179803F741B832A41ED087D11CC4DA31B5E884243CB9640E0F7843A70C681486C367F53A7A7904C6E5B813A69B26FF695B4861167564C7E4355AD14215AB2B083BF33B540D067F741DD2CC4DD423F4F22D00971534B20D7D14EB47F54F8CCCE544ADD50806EC36A70E7DE0D6E92015012B238D2CB2D7BFE2FEECEED2384751A23157F5BCA0CEA478DAA5D84BF6A4A0081C1965B575C6FDE2B0812660398A3365281768D7FC094EE6CA0B9E82F44329176AA7236F360548316E538AD9C17F938CF0548CD151A862282B92873D8F1506B1732735E65A7DAE16E20982D8B2ADA774D16062A389A832792E227F6444E83225B7A53CB808D37EBF4A7A520D93DA08EE86C51EC5CDE210EDA7BDC978E0186BBED9629FAEDAED542FBC1224E6D2E96770DBEDD19BE12192330EF7309216E7A1BB10E2DB5A903A83A4240D9C241AC877C08EBEBF5FD5BCF7B762302AFCB9F449BE0C21EB01D69CFD4F770DC67529DBCB7A7926AED09EFED76990D2F6FD4AB731F8817CF3B72E9D4399E498CB2E775579A23DFF83F3D452984CF536C1780A3BC3CA8F6687FF6671D54A099F3FDD7E136AFA71D84FF2D4026546765414A88F6EF70E218D77B83F3072251A439C954E7FFC9DF07D8DD75B05C4948816FFC18E05E80C178E5D4410240B5415DC524EB2657C6DB58F2DBA84FA5840C881DD071133EA193D92AA42F5A0F2ADE18F23817F5A2D89517105A61BF75CE208BA92D6DE21A4CAD67F7842A6523517F66F339777961C11084DAE3B20D88F62E4721CE8520D6429C8A2C0E55950E62342B7DD49DF933755B9AAD0AD055F8CE22A19DE1AF95207BF5880FCBF68ADBCDC6694DBA88920D57A768D5485CABF929EE2574B166CBBA5E8F7604EC6741DFE4388CC2BEBCC6150E87E1B9D9B2770F842E3EE68E15941EAF4DB429CA65B77B457251A7424CEE4E75B35DD03E35E8A4ACAA25968B26903B3F81EAF7EEFF5E96B1F911D4EF5F2CF3A18F95DFDE4B001448578448FCCEA9D7D7DA4D099DB0C3CBB54EE4AAECD771AFCADBE5F8D6435D9050E75A7246ED9E7624D3EC62603A0914E4DCB495DA579B0E9BD1B246C84CAE2B12849DCC58ADCC1EB2B7A8ABDFD31CF1505C398BFDC783CAE10366C78EB0E67E3AFDD9FF8FF57AE9F5904223B054B72ECF1B929AF0777D77234A5263446F3FC6324BB32FA2F8816AD713C47672E147DE009F8741E97023F16162DC5CD40C0D2305F495911325027A299FB7A2C4B5FC8A95315A7BDB3FC27DA121AE5CBFAF825470C466500F82C146E2537CADD7D518CED56FA41B52A8546FE4F3CC764A5115CD994704EEDDF98F75DE7D38E59A0ED9CAC4906FC134485DDA5253D4FC77F550D5E24CBFEF5C5FAEC45B7276FCF21D27F6939BC5FF768D70C1D07E41253AF08A91978F60D7E289D664CAE8093FD0EE10F0BD4881E0A6F00632BF18FB04496DA0B266996372DA181594B5FC39D4595F65EDBA2095A92BE0A8D30697D5EBB5E99CEF9BBF1B68277408D17F79EB6AAC978CD468D83AC4A4090046F603FB434E9B0A1970D65316E97664F2D3965B92AC6E970BDA957321848A77275BCBC2392A640E6697A06781D988E05C23DCCA29BCAC0BC260DBC52B1C1C0DBAF67A4C6C04B7063F00A095BE98836C3A48CB5C7F21C6A58F7EB3D6F71ED9A6DC8495B7C4A8E1FA0CAA350523B7B9AB67F6437EBFF921CB468B8B8935FCCC917FF2D692380F0630655B14FE547CC8EF7425F21C1438BEFF38E76207B752CAB4013F4167E5E5DD5061E9B31B785E7AB042EB71074432B5C078878BB9819757CA9FD287BCFB994C850A247C2F2DFBE787159A4565A54482361411321418AD24BE572436BACC704FE8D4CFB60B7355E1FDFDE349C73B9B4453EDFB6390A8EA3FA5ACE7C66D125938E16AE96DDDE4B01A05B556E766F3785AC36545D958D5EC52BA88676D4F8BB7F90EAE8FA401DEAF1387405364743CB00CCE3D1596C3B2AC687C6748B1925421C1161A7B757C8301FF9DDB64D25C892203DA38830AC9FB2C117A92B2837A9212693931ACD8D3169ED009AEF6B0509524A66B2115DE79EFE725C9E6BF718F00FF39E22473F5020FF73D82DD780C85008655B9D9A948955CF591C76B01B55F7D964931F6740F14692D15A94774758569D73F6CCF76F282C81FDF08170F50431B50781E19A915F108CB6934872F092FCD7F7F434B5B0229A215C0719478696C718057E0EC56091315C3395EFB4DD1C4B03A5ED74D0B739C174E938CC65A5E07507F439262747BA5A22E6E14161A681106A3096668224AE1305C97AD7F22173B6032326941AC075DFA9EEC0B7B0C1C3C82170FFFD43E173AE5178AC6C50BB7314A502CF4179F876DAB4AB0E20E7F6F60A730BD873ABE401C6245AFFA904EA2EB53F689826BD6B3C5B18EECCE51E8E02F284497DB7F2F7DDEB992B926EEE37DA59EB72C2C853B939EB6F9C37347032ED5464325228DFA9F8AFB92BB4CA4CAF01D501AA06CA09BC3E8FD830FF9776F6FD6675721DD8FFADB62C3497D486C3835BE0F715BF68353B56C4C05040F6954366EE383CE3020E946C277C6A843AEEF7085C2C5DD80BC16B2AB45E831BDA62CC38B25F987D48BCC3675D7CBEF0E8A3D8E95D131008172288034EC978D4C330C2769072E335DA97C8F46A1D91998442C144A8343776B108EA205DAA5AC7C7E5141FE11A1A045ADE76CA5241F733165AD2B80FD4B6A3FAA1E7FBEED3A5E0A93D6D2704251D5504F47CFC3CD7CF4F34BEF0B8E5D8221FD7D94C4D9BABC8BA952EF3FBD8B74CA4C167E123014594A46346B5AD01C48D695565ABE8FC554BBCA4CBC1D42226C06AC9E08F27578828A2FCFAC732A5D96DCC889517F182C45118456F914378476B3176C3BC0AF7CE0EBF92DF820B3A7094BCA1105A9963D8AE10292FA43DC11DC9E99DC6D61D9D02F7FC96FE65B2A33143445B65CF3E414F777EA8CEDB7B844161839BA4A9B9CC4049AFDDE0E1FD3B3C72C4F3273BA5F2F9729098F900000000000000000000000000000000000000000000000000000000000000050D0F171E23282C", - "reason": "modify signature" - }, - { - "tcId": 45, - "testPassed": false, - "deferred": false, - "message": "836BA1D986C11F4D70FA74ACBFEB03E265591CF909EDB3770DE8CF10B5BDABA9158DA368E49AFEFA0D0C2ED26FBDA40FB427E9EF98A7C826D3857485BC2C5A9FCDE36A63FBB70A4F49B5A1D21487FD816E8B3D105C788C7FF19E20EEEA48AFAEDE42596D3E129AF13846682526BAC5F4745ECE6CDB39E12750A87695A94295B1", - "signature": "7E17E986B981703C6B9C925DBC9BD0FED0043D532C3D10BC26F822F48EC27A489D983D33EB27D647B1E1BC79F35F61FC51E69B4B4E98AA108507DF2A521FDD32E01B6918298FE9B709B9AFC62D807CE4FD00F8FC7D57B9BDC8F26F18404B2E4C4D71BF87FE960E409DBB1E147DF3EEF02C22A277C49C34A086DD0A3A7DC578C2CBDB82D8ACB98749D5739836F8874F06A2C253D546B59562A72ED7B79B1421E9E4EAE922D004D80DD374B30AEA20677D1E38107161CC88BEFE64E68DDDC18BD9EEB7301671F3D6E3D69E7F53D5B8C59369059CDDE011FE083465B49D062416036BF9C93F3E73F5B96E4C035A79A53A935FEF300872CEA993A8505EDE7483224E3B07090BF480241000717E000F4F3A6A97ACE6506DB1D0939F0551EDDD6A6AF1283662B9AA677FFF5C37441959AF5ABB88F92D8FE2919FE36B6C0FAEA55C3DDE54BC201617E8FD1FE41D433650C59E96E247D4C865E7F2CE026328EC144C83BEFF286B1636F02072E3EC09225F5CAB89B555DB19A052F4B22BA855E644A4C0B77E211F901BA066DC7E78AFD572464C0155D2DE4833E98916FB2EA796E856DD6FA709AC3009DF271105600BAD669397F0695DF7D89BECE874BC70B27148A1A1BDF62BDFC5659F66F8F872EEB2083D43B6935EB8F9D9DB1F0ACC791051BE61DC1856F6BC397C25C33A324749D4918C4A91B9932CFD68895DA61944494FB1ACA3C5FD846CB6288E6307DFBD91C3AEF99C3EB230DB7039D48F3EC3BC0F4D200F8749D290F858104355C843A1C405DF0F7414871FC08EFD3A65E437C5F37F60E0B0F189D53CFE6F218CC749BBEB14DC81B293673B0690A058A2D03749922AEE5DFE647442CC39AD04B2045C04EF7C452A3636EAA7482AC2E4CA4B4922223243D4A83D4FEFE91E7A44E68F7266BE7FB3756692C3E9D73F025A20A375A140B936069E59F759BB3D16BD01309F9E6B2DEAFCA8FA61A72B982F104AE39EB426E01220ACA0650F87D7DEB2689F8F6DD169D58D353960D2657AA434D40ECE88480467424BC60CF737B712514738B2154F464FCFB3CB2FC6B1D6D347A1664D5A494D593C4A69DF1E98FCCC79DA39C06237016F0F25F8B273ABB98F9E3935B03EAF0A5A3F415B98ED2CE6C9309D21D4D147ED07FA05F98B0431E6C22F79A31267C625F6B4E57DACCF9E60891403D6F610E4E0F3E162D8A5167019F3332522E10C29963C2641CEF2965D516F3FF0ACF416FB029167FEAF09C214ADB16F1EB9750D8E929C0A908A3934A7A75028DD343CE270B91D1751B527E480C94F6CFDFE9BC9C9CE4B0FFCFA92FA2F1FE7921BE4E22AEDC6FE4EA8D28B5A627CA3D39E3ABC67CE5B1BF044FE922D52FA6BA8CA194AA0518578697C7723428B96F15C0D8D918E17A360B1A0EF817DFCED301A15FE536274BD36268ADC76572B49092C5BF4ADDB5453FCD57A31D9E23C358126A4E59170DF831A1D62C3C7FEE6A009E74895374A7BFA33DFE98AFACE0AFCD61EED6BEBBD9B5A2671D8EBE4BDA3A55AD2276FB55A52E27809CD8CB471A6B4FACA92EB03EA5AAAFA4B8BB1CDA709F1EFFBDBC63BBD545AC1658C751F180BEE1953AB66AEA4A129BAB458E2DAEA62FA3360E744330B2F0293B609E4E3AF482C8B116A7FDA359E9ADA3A6100BDE1F1458A6CF696DDA2923779F19C0BEF05A4C103A4F239FB5133DAFDB651CC78F3D0771B9B5393D1F245134141819737E506E774509F96ABE3DF1B5F6224981510ED4D2D3F8EECD9E2A9D0EC0E4B891FA6D8D1BBD6D0925B88AFCDA59B8FE9060633CF1AC381B73907A923BAD827EDFAB05B1109459596BA150C3E9BF15612A1C3F94B3ED874E0B0218D470A1C2E219AD9ED3E63476197AAFA8C9BF7B179E74961EC099A487ADCF5B56A10D7B974F6A8654E1DFE5A981193601AC718B99F721149273A82A7194575DF5D58C0E4542F6E313F24F6759436F96F366BBB3B4E7B901B33A4578A94E61E07F9F880B47897DB078D7202231B950CE64305916B57052C897689020898E34CC9DB8628E009B906FC2DDB56EC1D989F2C5862967132AEA827551F15ED16663C3079BCADCF570E05F3AF2500C6664063A798EF4414F6DA77640BA0ED7848B17CF614BA3D7AA909A93F050E393E37946D8B59BBA67D1E510D418246409B6A5BC6DC6BE13B6F355C57892CC917E68D99172648268F09FBA9F5319478E34C807327BEBE2EF63D366E50535603562057022FA4300566CCE7D0E7F9FC9F9E47CA89DEF061ED4C70DCF0578EF7A9CDB0345D78F091419E25BD38D3A51DD8692DA19F9AA1F3965FC0E4ECA0A9A7467CD27A61CBFE892D65F959049DEFBC9F1FE3D6195D067BFB6773E8934539DEA3BB0520A4B07FCA5BD61A2D63307F8F06158CA82EB71E9BF5C356DEB9AAAB2547848FC88A6DCA74543C50E4B29B09BBD20A0F45C95DE94DC7D3AA845422791CA69E2D75868111620EDA5A3F9DD57054BAE58A99FC9168AEA69D00513DC860CB55BC3FF0393BA3A686A7692CE2A76551C34E56AD3FD6B617618E9227D78B3468D9756290DE73201BBC91DD41F887F6174697943C080A3B5B068E3406DB5A03457F85200FDA20D32C36A11C26FA26B98C32B3354D9910DCA8D91C487D795DDE0A45929293285F614F7423C85FD5DE6F0D8EB5D8ADA9D93B51DA697FDDF8D7EF0652118775649E1CDD74C4D9457EF3CAF8B372F6DEF2BD5B3754ACC0F5CE3F4DF005B9F2A259414B72A1EFF73E15E7E161EF1C5BAB594CD09AF3BD8E6B07C16155A3B2DDB171285A5341893A5929308DCF07D21C46DF7F1AFE4E7F9F6328CD09055D616F7E1A020F7BE39E958EDE7A6B63E4053F22D77B72A2C9F7B977D52BB3CF1D43AFE3E477EE04D2A8927371589CFB65359D74E46474952C5780F23804FA89C7171F4F9E6239C66BEED14D08AE9623885EBEE6C3D6E55EC693A3D6426219E99347619DB8994DF07AB77142BCBDCD4F276D4EC9091D7C04EBA33FA51530559A8EE014DB9B6BA9593DC62B7D51B262B2AA6D4FEF6E09BA103B697530C1B8C559D5257EE50E32ABBDFCEC786E96DE903A609FC1813A9D1279D5D23F0A5A51362D79DC24DE3CA4C252E1224A35B4E63075CFB4D75ED902043C6718FEEC7EBA6A3F7E8AF52742DDB3CB2D069D76B8E2403085C67B54BF15FE23B813708E0B076070D00C0462461639C9CA03FE487BE8ED5EFAD12747E5500FFA5485345DA9157A64EBA87E78A9A8683D2C26B797E9D15081C2D5250382D79DF4E4D6F9011467E25E9BEED0BC3D5CE410450C6A44383076E720BBC8E54CA57591F67E0D3CD41F53F40048CD1350400F0C0F0B0C09B95825DDC2019A140FD55C3FE6C5E39E2E539DB1179EAEA035AE6994DCB59EB5EDAAA83007CE7532B41E408274900182D305ACE4E50F57B46E7A17376AFAFE7ABC6F3E86A4FE0A3F9D9CEC4B5C05D7C4D022AD3FEBA6F091D0781DA85AB2B7B81851C4D4623E8273BF05C317090F5F1C18ADABBF04DB385FA2702AE48D7B7563B41DDC549373FBDEE10B28F89857F941D538BEE2A53B5B83E3E5DE203BE4254707E5B8292669F204C1D3950C6D47A169C1866D234A9C4B9EF09428853790828AD99C24DB6978D7A0B9D6648685F8B49F5B244BC275E426973AE36C4F3F7F695A10B9C9A72CADC969607255E960AB1C4D4F88C01664A8D825EA6C3E7DE4D6E3E705F072ABE1888EEA6FE33054A82BFA9E8442CF3B10B0294FD66B5E794837D0CA7806CEAB4D388AFFBCDAC19C8FE6D11C3227820F65AEE73AF7239804AF08C28D08EB349E4F568B5A9F9791B7B14F7C5EAECD4F032E6630CF1BDDAE50E3429FB87DB02B65066148B440FEC27C4959F63A24A3D1B019A4266764EACF703EEAE3ED1C4D2B3896756B59132ACEA166487E0A92BCA671761CD1C6D1D0299E1B7092461F9ADD6C268A10A5208BF7A6250123B1BD1EFBFAE63356654E63703A9F6CE8C80B898FB490CAECD58058F9ECD5398F8150C3F07A0CE122F346D9C75C9B3E4DC2E7D7B57EA4BE32DD78ECB95D84C2CE3A7D724DA41205CD894D843F87AF5EA8722A06CFA4AA2426E7DF4C9C69E8CDC4D6C7FCA8AAF0644A3066BF07F3B7CD2355F8641519DACC4D77ED8AADA6FEA6560073FB9EDB9CB970F73A66EC4663834B0274F9A6580017D4A797231A3CFC2134EE206DABA45198B02DCE3E534339924B66690C54436651D68C9E217AAAEC59873D822313E03D7FBA864D3CCB469711444B764149AC3B2F844153D8C8E8523FA8273700E13DAC42D24C9314A13EF8CDC500B51D85B7274E876E6FDA8E0FC7DD30160602DAFF6FB0693543183DDB01ED4C3F47949C314F32B7E00AA65AD8D9692879D1F9C0636548F60944F4179D90D89E63141DD6673C0899F181DDA52B958C08B53C4C63C5C49532F500D15FDFC28A6A0CE8E85BF4FC6AFB8CE196E1A53777C34290BBE584245A39A8E2DEECE822E24BD926459B9710ECCE302FCBB9839155AE890E8660F1D1505FFD989C6D9C78339984F491BB04FDBE410B02DF01CB426B992AB719F6B07686525077687D3092A9876869E37C3B97938B5668F307FB2011D36336AD76C2210163C26EF8850247DA30710E9B8419B0CF7BAA88824A658FED3FEC87945D2AD5BA693B6962F9B4CBF096C417A038FF10232E96DAB2870EC7584A7965AB845EB4BAB27B943087826A1FAEC43B13BB9E97609A9E28A80B0FDA4E7C44A3A751095760F1C9C7B1A20305E2DA0C903C6FE12B4EB65835533D56534044352013A174886634C3B02FAECE1BCE571CCE84BCA0836FE4D787711DE5C186D451890046F4011C265E2C463FFB3CBF9235C7A717D680491C2AC4E4C0A070381919E833EBAD2504D22C9DEB00A0F1F07E3A274B6192D28DA577DF1D2C58924D3658E97C9D18C93A69E5A1E3113D61C63C89805505C7EAA01BAF89BCF170396EE54A4959CC8B5A9D294EA8EE2EFDB10EDC9CBD920C92C320CF985E626EC1B5D07EFC03DE66BA11D6DB5E0FA415D0934CA62492E2942E373489518A35A56F36E62AB4F3A7594F1E027A8F5EA56FF2B23D66823090C48804CDE2D8E666A711254DBBA150DD623DB32E86F8E794FCF2B1ABC6351D22CD6CAA26233A4A170A2E872E5921BDB67747802D70EA1794E02490FD875CF01FB161497B79AF6DC6B0FDCE836917F90E4699A094241B38EDBBEE271FD8C4F90E6C8F5FF79A2FF6ED2C134E4BBE161DCD0FFA3C4787640AE8147CA9DA4E7E6CCD1FD5BA8701719E77964F9A66065D4A2C3789CFDB3B2322723D91A51A176CE783C5DAC8DFA0B62069A037356125C5B865DA49BCFCC578AFF194FBBE0F2DFC07413E7DDCC85A35002E9936C9F0B259E51696A1A2EF654116777DD0E284CFF3AA2D04E1AEF6E2FE18FA119EBACAAA0459FC2DE11F6D6A1AD301C7D56D8C8CB1ACD07758B43AEF09036BAB1442C65528B1F52BAFE6D9B8E24114A82AAF432C628A83BFD25571FE0A5B6AE793D6034F1243B029A9E082E0D47D9ACB3B6566F2DB0D8869360847DDF00F238AFCC61D51DAB0915FE704C6368E9190D3BB4E244166151F94F2CE67D618E8E97379CBA6D33F4EA1B1C8277E0AFB06DE5B2D9212DBAB0FD94CCFAFC123E9B7B60827358959C50A9D6494C566A32F84B7670B3E9E0E3A0C8E148FC42A077CCBC0707495F2A4B9D5F6CE53615C64CCE446A6E01E2A5995366486CF2746CF03A53BA42EF6704C084C48F586303D3589379B601C14604CF5AADC330A1CCDE3A835A8CE22C1AF8D5B248169F7785CE4DB9D62EF49CDED793F8C88D927BA6A2195EC5356F2A417A442B708DFE4C32F40EDA5232195B60A1F43407F757CB11A08A2BE085A1923BB29FB4F13404503B7E84AC9A0B81A16E03343520E68F4DC685714C8AC84897736BC1400075DED531ED9E4353851A01AAE3941C572C2DA112113462EDC499B909C77E65B4A7914ACB88E8DEABE3B447C5CA68C0256B54438F1B893BDF0DDB2AD46851EE62873F8B97EAA8FE8EDBF1DE15C4CA8C4D57C1C2E45F3D045C56903CAC81BB083452D23AC838E84F26E62B5176785616EDEBD14DDD4ED349F6AC3F932FC827447148FD05A85B8D24039953414570F51A4D8B2FFB401B2EACD14EEC7C3C556F7D80D68CA89AE772D7ECE3B4CCF14CE8C2389E934CDC192F106FA31FEE17D69DE01571DBDB8507D002892D77FF8D9DE6B0111433E1B9878A37D97D14C46FD74887014D3BDBDB8378D03A6CD1C30120C95495F1E2A00BDDE36827B81B7A6DF0DA2244542F4230B19BAC1F36B8EE9AD92472FC1514F7379EE38E8BEBEE584CD2998BCF8CDA8F0EBC870FCBFCAC7DE7045163CE73932405D639384AAF4D28B4801E1F75924F8319E9AABE7F567E6583569888FB1C0C607DF08E8A0C8C3F30F38B5C177F2334C33F537142E57E89CAF4B1CCF908C0D7F3DB79864C4001BC45C3882BD7B263840517491B7E4159495B0B6E700536389AECBFE2D3F4450D0D2DCE5EE15515D66A6AC1B9018636D76788DA4ABB9BAD20E2B2E318992D900000000000000000000000000000000000000080E151E24263139", - "reason": "too many hints" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json deleted file mode 100644 index 7b93e2782989f..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json +++ /dev/null @@ -1,1023 +0,0 @@ -{ - "vsId": 42, - "algorithm": "ML-KEM", - "mode": "encapDecap", - "revision": "FIPS203", - "isSample": true, - "testGroups": [ - { - "tgId": 1, - "testType": "AFT", - "parameterSet": "ML-KEM-512", - "function": "encapsulation", - "tests": [ - { - "tcId": 1, - "deferred": false, - "ek": "DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB", - "dk": "A5E26E1B2360203944ACFC2D7C376780E55B5A5CA38674919437C794F54B8217BB0629C84C692EF7827EED864D0C508990CA4553F16F4720CB75368C1B8CA9DBC175F51BBEBAA456F36611A2364775D248C0F4C40B342608F7370A983CF75C915570248E367375B665D9357CE4A8553E659BE4A60CA68B58724689C23B74D34C9E78E168E7CB0DF84641E41B6E6807BE6CF4CF8F338525D57090B08AAB5721216395C49147F6E817B117B129987317A7A5FF15A279F86AF93C6A4995954000C3D4D8B0A07499A95A5C98D0B8303702DFD801B67C37268904C96ABC462750384BAEA767A5AD30C5D452682B3AC864D1671DB38F1CF2CE6E6C901D39C144DA3D93B863F95717C3C585AB876D3EF2B10AFA0B8142164C3C27FB179A923A3F924B15CEBB22EC762907324F1CD4C47573CA1F103CA88844F3B86687280B3B5BB569B1C118B63565055834F39F320CB88C05C199E29684D7802CF45D8DA342CC444D91A84D6D9461C873B66F9785488723A167412019077C9A7FCF4C7BD028BE3007B3483026A442A095124C9607C950443FD69993615697E9AC1CB9D380437B85EB300CE4D9B5A5BC2132660DA3527031A1057A565F2C76775565B0088637707410F2E955355425EFE496113149CF52C901BCCC48864C8AA4262367213602B63AA1A8BED77826C0C476152AB3464A20C9CD73F17A1D019466F2AE37859E6E5A8BB8862A480C1B12D6797B79663ED2333F188F34E6CF6EC87E43979F88787CE35877DDF0B689547BF5BA9EEBB2659D76354EBC39EE83975310ACA4F8867FF290793CC08BF29E60A97C28A71EA3084FE27845AB3664E80592412043B03056FDD5744BD74C9584094C2B75C689ACA8E4B3D3F91994E4722B9B331399310975275A0065935B6CDF5A6A8216188452394238BC82736488A84A0C96C580A81C69032AD5E96F4C3061DF5AB246C258CBA0B68A32916BFC6686730B3FF0944A070F535A113FC349CDDB0B67B40DEBFB5215167090F9891365BB3D87639FDA05843A079A430FD5892F57AC4510450DEC00B7905A3A14442231919F9ED4A76B2B159A6CCC3685B3DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB0AC923A76D541CA65FDEC9C788A407326C7DB508119F617F43B6E8A6F48A398702E051C20C31DE77A1BA6777829F5539C886E3E14DED294D56AE5E88AC06AB09", - "c": "19C592505907C24C5FA2EBFA932D2CBB48F3E4340A28F7EBA5D068FCACABEDF77784E2B24D7961775F0BF1A997AE8BA9FC4311BE63716779C2B788F812CBB78C74E7517E22E910EFF5F38D44469C50DE1675AE198FD6A289AE7E6C30A9D4351B3D1F4C36EFF9C68DA91C40B82DC9B2799A33A26B60A4E70D7101862779469F3A9DAEC8E3E8F8C6A16BF092FBA5866186B8D208FDEB274AC1F829659DC2BE4AC4F306CB5584BAD1936A92C9B76819234281BB395841C25756086EA564CA3E227E3D9F1052C0766D2EB79A47C150721E0DEA7C0069D551B264801B7727ECAF82EECB99A876FDA090BF6C3FC6B109F1701485F03CE66274B8435B0A014CFB3E79CCED67057B5AE2AD7F5279EB714942E4C1CCFF7E85C0DB43E5D41289207363B444BB51BB8AB0371E70CBD55F0F3DAD403E105176E3E8A225D84AC8BEE38C821EE0F547431145DCB3139286ABB11794A43A3C1B5229E4BCFE959C78ADAEE2D5F2497B5D24BC21FA03A9A58C2455373EC89583E7E588D7FE67991EE93783ED4A6F9EEAE04E64E2E1E0E699F6DC9C5D39EF9278C985E7FDF2A764FFD1A0B95792AD681E930D76DF4EFE5D65DBBD0F1438481ED833AD4946AD1C69AD21DD7C86185774426F3FCF53B52AD4B40D228CE124072F592C7DAA057F17D790A5BD5B93834D58C08C88DC8F0EF488156425B744654EACA9D64858A4D6CEB478795194BFADB18DC0EA054F9771215AD3CB1FD031D7BE4598621926478D375A1845AA91D7C733F8F0E188C83896EDF83B8646C99E29C0DA2290E71C3D2E970720C97B5B7F950486033C6A2571DDF2BCCDABB2DFA5FCE4C3A1884606041D181C728794AE0E806ECB49AF16756A4CE73C87BD4234E60F05535FA5929FD5A34473266401F63BBD6B90E003472AC0CE88F1B666597279D056A632C8D6B790FD411767848A69E37A8A839BC766A02CA2F695EC63F056A4E2A114CACF9FD90D730C970DB387F6DE73395F701A1D953B2A89DD7EDAD439FC205A54A481E889B098D5255670F026B4A2BF02D2BDDE87C766B25FC5E0FD453757E756D18C8CD912F9A77F8E6BF0205374B462", - "k": "0BF323338D6F0A21D5514B673CD10B714CE6E36F35BCD1BF544196368EE51A13", - "m": "6FF02E1DC7FD911BEEE0C692C8BD100C3E5C48964D31DF92994218E80664A6CA", - "reason": "no modification" - }, - { - "tcId": 2, - "deferred": false, - "ek": "49469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5", - "dk": "5639898D7A061A47880E01A1DD869A4393A58EC5811124A22AF2CAB3C61BE3E70492F22EACBA0B52E2C2F31914A466C647379957EAA4F16C9A10440BD25B6A6260626C76C2B5B7391A16897681535B1A279C38CD4661CC04044425297E47F6827BB8258C246894DB965EDCBD6C864D7ED91DC3A12FE0A86C6D2C40EB5812FAF8421F447DAD43BF2140AB9F473C1ED23EFEE952DC0ACB86C068CADCCCC32BB22117B6F8F9B6184BBEE13184B21BB78B87B33879147ED01BE9441D6D240019C2AF998C771A51B616983627354BF0EA1A4C73B8E2A092AB1772CA7CA194666DBD5C06A3464F3A55946C8B816147103AC24934A3488B95185414AB05FAA360C63FBB00A915271C50F25987E817CF849463B8C65CA76F71A83676D75436D27F2362294EB8C55017BAF3A77C57064586D0BC08AA4906E86DDD13830E2C21716258DB81592814681C823DC499752D62B414925B76B5A4BCA94EA30B2B20D489D887B63BFA72D9A327C121C635904800D68F3BF50A01E765E86894D802C1679964A0CC528CA558F960A5A9D8243CF01D94A99E68E4C2BDAB0576A1780ABC3BB8783E35F7441F395F7A1134C4016200E32602640D42252AFE3CBB3A624724066D5644BF93B8BE699B42B052591FC685D00A289AE76766C5A8A384034F5274E4B81ACC6A52EC0A33EDA0201FB600C702606D5806E95C2610C367426A02A7F1808B09B0119B2D71B7A1D9E93F9339309B941C67C855236761B7DCBDCD501AD736C15C0609C4141D1920651A631C39EBB1ABF4AFF51A56F3BC11BCAB098E960DFF115DB306121F19723A3CA5B9838349DC25781CC9804551C8B80FE9897216D72E1036CDB1C11D6BD710BB60C110507392B32DCB3A1ABCA4B67AD5A88DF76399E5134B8063CA068736E626C0CAC3655711D7004E19D56FF0C11F18417061E70C7F2B9A2DD920E297284EF21CF30BA29E1124C3945357C0AF8EF060D949613417A6B35305239BAC986B8E51468655744CD31BC9BAEA4E0BEA33CF665EDE79BAFEE8102A68AD5891AF29FC0409C00AEB904458FC73ED36460D191003A707EA81CBD3ABC5C2C24049469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5B2F75D3486FE6CEBB15F8E0CB70ED8950970C944912A03717D9D168C7B589DB71AC2F3294D2ED2611E9CB1E07CD9684148F13E9ACEB931C8CDA7427873B44B37", - "c": "FEB020751BCADF864161AFEA7B63E63088517A5EADBC52F0833E6DE2E03C66EF3F71F92FB61B277A26D6C2D9E01B88F0738E1A7409CEBFC9D7230C69E02D3BC7F0403B01512F0E082CB9023C7174623478CDBD6CC5E6D65A09AFA63C8B2686234DAC6FAA19A82087F0847B40AB47ABDE90108A13F3AB3601B7EA70B766F1645E7B4428C4AF8CCC19B62C057C8EE9F41E77DC00E5FF5F4ADD0E8EDAD2CC9D6DB40015E5207E7CDAFC915B8FDB1FACD6415FE3E8EB4DACADD7742560C3E2D3EE0EFCD306FAC97A8FE45CFEBEF1AC1B2F5D5316A4EF9C7D3DB6582354680E8932079567D148473CCDFCF32FD7E6D7F3226EC30EF2792F819229B55C5CB8514A77CFA44F6E8531102D073E8CEC089B4268C86B759F043A0E9D8EC8D57EB5618C6D0ABD44D64E9CA25913588F6CB4CF7D0BC914625737140C0C7E559BD00B2C448886B983893FF7F18ADEA02E41A07117644D5A208928892B20685F7A8476C641B25C48EF63551712AB97B0FB759431B287DFD1488EA11CEF813240E2F4E1F5619084B5D7EFFDE09ECE072614BDF6A970168F8D6628FBD521F1431C9ADC46CE31281AB6D6E762E8A7779FDE0F5CFCC36AA677E1F032010F110FA6B460F7294545DE7BB28D6D5CEDA5D8832EFD3E32F9605A7BD43673A00EFD0CCAF63BDEB49C9AC1872B9D3C8CF7A9C81936F18667D15261DECB9A354144D7C3F2BE726FD0A83B1C27E8C6AD66B1AB77425541EBE321EED279526C79154FF27C1B5306414E60684ED42DB69BC2785A1CBE14CD0AEE879173CD3C94020210CAB4BABC531C058857522D9ADF25FC5C3F2FB0A0DB8BD15F23807AC84C7319EC29FABCA43C99F72354415ECA9844D06D299C9F4AE49E0BD8CA7623B8FC9D2DAFFF3F368E4BBA32489F3EC202A9799094469C674CC216750AE88F387A6C030D94BD8E870706D2D74A27A27CEC92CFF8CFD9E09BE6FEF40F807CACAB3628262C501ECAABCE9CBDDE8B3766813BBB8189CAE1AB38A3605F6354F95432E8EBB8B3A5768D2B816E2F7D22139C0135D0070CC41D40ACEECC4CA16636F08C404E3E5E6F6C7D8D652F6084F6477729", - "k": "9183CD7EF4AAF2F21E2E852771F524B10CB2BDB8C0BA1DD36EF48AB391DC7307", - "m": "4660985A5838041F2E50381CB4E7AC908BAC83CC1E074220C6705E3F5FBFC2EF", - "reason": "no modification" - }, - { - "tcId": 3, - "deferred": false, - "ek": "C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160B", - "dk": "AC789443C51AB5E60BFE7B56D8418AFB874C4C563C88C60B77A1A1516B01CCBC36445B90EAFA778CAA4EFD759982D2313EC061F1E259827214E415A583A911A68581E8B228DA8C30182B3157B50742F835121BB501F7B96947330867BABC615D1044BEFC0467D8B88E78FCC2089C9C8E563DD56BB08FDBB8A5451EDBDBB7ABCA20573B7AA8BA48BD5BCA558CC7B2E512A314CBD5D6A4CECBAEED533216007A7AD988B0D06A37C1C443F16B5B246C2F7C38BF68CDA1DA8098C6307C60658D6C596EF67759923FFAD16EBCC4912010785B7798AF299296653E2D865A12631C2BB49C417C19A655897CA6491CB6ABBCA64B6BFA5D811096D2F99773888153590068F8220534705C7C0E0B1C2538D31A7F0C70ABA02B50B9449D111792372B17C11F85AA67202017A2D07CDB6B25C1D97ECE11991E0C0374167E82419802BBB45F87899F262CBA0C5C74C993849B4CF412C858700B4BC9BBAC82907EA400118C59289CC07BE9CCB265B85B7B2294944F8E50465FAA496FF3865EE52CF6A07492231FBEC32064B30B5E6672616650983B730CC19F0C3BA4B354CB7A1B77A9AAC32D30712EE302CF131B6E38C40A9CC40C3C661848690710BC4DAB94D484B4D7EA7596C380F6C6AC023C01CD773260C95DB6A317F56C62CE0B62A0A59D5BFB99A77B6533C026F4FC25AB3221C643C44C75AB5F70A73A40487AAB651CB62D6E0B7AE24A2D736BBB26777417328078B6A16E151966A72DCEDC8E3C309F99A3989FC61722CB5EB6EB8D3C8993FA57B487D8B6D9C82D37D865FFC172D5478262C3AD8498593E2CC6E9D559F3356DA36CADD4560356351DC40466FB2B840048C4FC857F323126C5944C5C762E5835A90629C0155428B9F99472555FAAD44131E0193021C40DB0A9006543965B8CC1FC0B80092C69938DE4874EC92BB3207AA76CF32ABDF57848BCAFB6F242BF7905C782B38AE1B77DD2787FAA90112768544AB9A8354B9AD41304B15167747A1DE82B52B7CC55CC0D6A59140AC29FDA1654C628492AF47DBE02C8D809189B098D9F8C90C57A91CF853BDE416F6D09638AD2AFF2A0A7987C25C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160BBD4FAFE5DBA7B6E6DEE2892A0D23D7FF97262CF3BE7D86976521FD0E33969DD804179FA8AF901D178A41C1E9F51DBADF03A4393E002689723B0C5963C5EE326E", - "c": "7E132EADB0E35C2A8E0916939F5BD7EA42DF683EE4E64D0512D75B2882FB6372A5233B6BA26A9A1C418171EC4C3EF24E98FD578C87396DB28E35C980A6B3DEC1F772086EDD53126C46A82C6D4F51C1B57F49CF1487D188336CBF99F740EDF5A01D30729FA486B551E0B236D5E08C56C80FFDB2D1CA10040C6435A1E0711E2ED6FBC1A48AEEB6A5D8A59D036D9B702EB3A884476C781BF2996F9BF27C79648552F2A150BDAFBF8E134D44B4B4558EFD9D92F2289CA975E65B601BE687B31D6F028A51B16A5C83B0C20DF3F279C9EFCB66060330854355C02405CD9690BA6F8942918CA5F7C37CE3BA8BBF1F285A4ECBEEEF53BE3366D4AE61377BA5A1730CC82444753A11931790D1228E8CB87F7BC9CA71E6E871351EB81A332D33EE06E83048F84169BE950991863814917D56F97F8A0896B8D8A4725CA965C726BD3C1EF3892175B19D8B9CF83AB82CF55B02558BD255A35085E88D3E3B6185537D8559A6675F8773EC7775FF6518E281701D50A450009B845327D2FA5FEF85FD5B5F6F3BC3895742FF16E483CAF3356B4AFA6ADE61C96D09AE63AC9715B4C0D4AD64072EFEE7B70D7BE0E3AD7D84CAF9A8439AABBFCEF44B624DAB8ED6A4AA57E2AADB22AE7D42DEF201862DADEECBF0BA88EE5D4BB723EC35F99A8556E67DD592A04920B8B228D0460ECDD389EACD55BE9F77EFE906176C5C9A1C3D3B4788410CB4E7035260FA2A2E6E3906E5BA6F3C4CF5AD16098392A0F3EAB85FBC59673BB49B3231229963647402533FE2A8E6EE7B85110300B7E20955974347CE5547521032BD57D8D7A1B202220142FE22676239F8C84BF4ECC2A9A18482EFEF216A232E7ED7583E090DB56F61AAE17B6755506D366ACC6516CCB54537D45B10324A46282E4CD881AC40B45BECDC5238A9605BC722FDA5332E2596049AC12DF07FD8011AD170E12CD8B05E261BC4DAC52D7B0BF42B88267D0AA310F480D67022C740666F9101701ED5319C1DBDEF15F6AAC5E0173CC5436B28848443C7099324F78FB2363CE5BA841DB75C3987C3840659FCE7C675BC5047F9F5C6BBC0057F28B32DFAF9A09E969A", - "k": "941DA82106D0DB42FFCB4EEDBC4123DF57BF0DF2A4E9119969872904FDC0B9B5", - "m": "0D643FF311D83CEDCB3A95BA0F76216A49BCA389A225396F708EC9A51BF18517", - "reason": "no modification" - }, - { - "tcId": 4, - "deferred": false, - "ek": "E868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354", - "dk": "F9D66260ABC38576A4B54864B8CB3C1380365EEB412D896570BB243C29359D36366CE050D839462A5CCFD56BC4B28224715C39E0848C72094B5DE99C63252F20BB07D1AC305F34845A914684E0B03CEB6F0DDCCBC118CE06E7708CDC1E7F660824F7AA21487B7CFC1D6B788428FAB2F5062223CC6EC6285B70D7AAFD50832970525B7406F59C2A974AC1A6C0C813B4A71EA45371B1A7E2168F3E972F9EBBA639236E9947482ED75891FC834FC8CB44C51AC272A8CA2A0058F57A05C22D9166028D063BF5EB3576467368024C739514DB517D4E1B1CE2AAB8004D4987A96444B4B14CE633A4793D2B40071A77373D630A8CFAA884B074AFA03152C882E9C14806E65797340F0ED100F9D161ED46581B7C750926C009861C3CC89894258E9CF2032283708D1B83AFFBB7A6B890D9F9C725A1CF2790ACB1424C5BAA05C0B3CDBDFC78808695D6531877254B85819370F971CD196080B70AA1AAA8C691A8BA40C44FB60A898543979B5C29C3A40C0117C0162BC06A816626152B472F57178050E1BE9D66CB6C30584912C39FC45D60F26689696836FC60521298F4529888286636C5435A36BF6F2841D058AC19AAB8789924778B473A567189B4711F655BF5D25871D548AF92CC5392C30D2B50EB3C3381033D00C48B89C58E8EC81FA9942A2FB11A79549487F602FD8A85D6439C54C34493966AC4B3C04BB670A2AC537DE04E52218DE78ABF019085E470949565C111106F0C321620A65133439180783BC7261D0F47024423C43A2038544A2C72D480AFD1C219EAC504AB4003D11FAFDA4173B4A4E7E038AA659A3309AD9D1B2489C270F88CA659547F49F45E56FA149603B54A1611061762DB1B4D8AF629D1DC1396069BF1B9324195B5DA92ADE118588A664389BABDC35B92E5919DA2BA30254521DA834DD728749F9814D6777EB4A24AB4BC7BE5910EB39331CF3461D7B56392F99AFCD2B25E4A2948925C7BB744FB05C3BACAA53500B25109B4881C5BCC28661BA6626D648F3396450692503624737D5496C68BB7A83801534A9F86285EAB94B80536292F0A2FFD59647428CB15DA481DCB2DE868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354804C79976E41410C336BD08C60D65A16BAABB81987C8E6C6716060488905CF550084F403AAD82B09B96BB6C85D25165EB9E5BDFE784F096522D8BEA8007E19F1", - "c": "0756A8BA612C014FECBE00AC1E49271C6FDD87EF587C9879D6F8159E10982B920D3D1F477D9DCA08619185AD10D802A9C4C68D4E68F54E7A530126EEAB93386AE1F184843D90C34A1FCF7E9F54EE61B40A6DD52BD091A4E44DED49D8E8C9B63A395FA22ED602D03E399755F49AD766C49E24994969CCDA54C986DD47DE9646BF5D1DD5AC0EF7B10F86837C7EF18A05E6AEA2254A956D06062EE2B9FB3640C60E8F5907E99524B4B0EC608B7A0FA698B78B7485B6C07DB74897290659A99FBBA2D8CE4FBA364F4A5978984D1ACF0C175B90B1A04C14DEC67561FD9FA789D418EB8033C99863CF52E6653CC4C951F95D718D77088CBBC36A9B520156803B85F3BAA123008C4B2CBEB52C47D790BDEDFD7E7E8B7693DA18AE01A034781DF62CE288DDD29949DCCF28D0B2FD712C4A28282FCBADAF8CC9F811C1D81893161EE2ACEF36D0C3BF128FDFC77C514DE6CE81A9762E7CFDD53D90FA643F64C68969B2076A259BE106D4C5E5DE63461F48C50ECA1AACCF7EB56C288672FD5E7F2EE3167FD01C3A0FE73BDC97BA69474ADD93203BC01BC1D9F8DEFD59433CE26D117C66692149CC8610C89B5DF5B6741AF6C4BDA814657321AE6CEBCCBD5169B32C70083E2A52D6135FB4262862E080888716245CCEEFD6243F0C2C757A3C2915ED58F2D0C82CA5F9C24547601DDAD0EE1832DF0D779D001C28AE57845444F9A527F32ABA50318135931D3991E629B575762B7DDD0239A9E9EBA94603EB5CAA3B2245A608D84325D5D8093DC4136AA736F5D70E581ABA35EFE446E0FFF5F727D413A9C5C5ABAE83AB0F27A710D32BAEF300BA753C4DC7A997AC24A3E8908F1A705DF7D16876DC3854FD25D747CB8FCFD9202EA8DE379891B98A1859CE74F035BCC28ACE3EFD85B7AE2AD566CF64B91B9808686A4D4ECF498F53DA2F514A34F45EE14E28CECFC12BBB34A08F5FD68D6A856C039102C298F40787D64786085255A855965AE4A4B61C7CC395B4E04CE55BC9875F6C179F707008544901D64C3A3C987C88525323D075586A3FDC6FEEA867F0161F619F8004E4093D40FAB63AF2737C51C9637B5F", - "k": "8A77C7C5D298C5A9724AC05B9FE0D8843A7D859CC40E07C786F1F96F921F76C3", - "m": "AA28DCC71FA83D9997DD733D8B0D0394D84D33A3D3E1B74CB74DC6049628F861", - "reason": "no modification" - }, - { - "tcId": 5, - "deferred": false, - "ek": "76608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D40", - "dk": "7880A126F08E51F0A6E89329E38741B15C1D4F2410131BA19CD49B9BD32A71487081E4B0E4692CBFC01CCEFA210BA23303DC9C05E317A9F5A51C535BDB6BBE7F1043A5F841E04B7F70E566AD3C28A84352B5064B25DA223B16A8478BB038E221E2F853A1BC07E8940F97175292C6BB8236661D587F6F539BF0616642B82456F7839BF0A9A393919E1356E070058E0442A61CA6F9019240194E61C453420181F8D0A108F87BAAB970AB0B6DC5A7909AF7193C975BE88849641341E42C6F92851EB8885A951779D606AE9CF7271732B728C35B5FD7611FC7C44362A14B16B16F779CEBDC1740F6A8CD9540CFF05BCB95B1C10044EA14256C34B4DF46C2B5363B33390728C152A6CC9778E21A0C909D83001608C773F4DB30E6774DC7F6B80F966BB1494764E8983EE62F35B14C977C1B05C43734528B4281412738C3C10CB4A1016C5EA5B220A4899D91311B786706285804038EB83357DB1B4FF3B12C71850F33733A52582707351EDEA8336C30A326C66805638318E32E4027C97485A77FE4817AA65A48085824D24ABED83443296EE2A306D4642F71FA98C2647124022812C5652FE4AD7B6892E2239FAAA9261F9B2374F242900461A469AE7F2259CDF527F062C1D55C3948840E4FA7305A088B126C27F40C6A9FE0938879A5C7F56157C32E77E417E5356BA200CAC228C647244CFC03479373C40EEC90CB115D4C723D1057233D42AEF5E7557B0713E29700A246BD168272EB0348D282408FF66B6DC16968E7AB493A64EE626F96436D996A181FD5583BDC2F8609B9A6736FAFF56C80375055A8992EEC85FF6575CCAC18C2B763F1E745691259BF4695324C0A42C3C87B7639CD45352A7603730A44FC7473C79A3C72F18D77CCCCE489C897FB3C7204145DA416C214818EDC7AAFA0262D5A330A4C4FDD72C03DD5568AD1620F6564F19A98630C90482C7C064A9788F0A227F7332B901BC359A6FB2ABB30C5131B98429DF96C35A2A81359C0D9426B516847375B8AF236687A071179EC53B54C1736918599C193FBF5C6B421CF7F029B691482DD2A539C0268E590A3CA563FA88674A6238576608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D405D5240D40DACB83C6E97603086982B2BF96DC0108BE0A5C76AB85AD6985BD6891BBEDEA993E606D87B101D21308B55560DA8BC3F7C7AED02BFD2D42E4D722BF4", - "c": "371904CA3678917FEE951EF2AF3C21CFFAE77DBD02E836EABA8AFF8B687D8FC28E2443E2F6FA020FDD2962976C6D8062FB57F22A3ADB52EB9AC8472EE2A08C4F4D98632D1D752AB7BE7D57F5FDFCF6355E1AECF7C68DA4FAA809177F9C8A749CB779F49F97B65E3467DDE74CE2C68590465B53E91F2C5C988AF7A0BEEC8090E3E3C60441FEB212D2602CFA3AFC27EAA686EB92CC5BF7E914489A33646FC6A63AF1284C108CD287001CC9867A70E3D62B7A437B1B87C095A26543F1B7EF16EA944F7D4FB382AD3329121281FD6CE8EF3EC215C7C13C2FDBD971CD5599ECF5ACD46616B1C911F03AD284826291F56BB412467143D392C07AA0A50BCF9E7B66CB9FDB25041CA81413B9B392C2F937F033D34A8A293E737D7487E2BCFC2C48E101878E03B1EB0CDEB3BC55BC318286521347828C9A5B4B12AF365EE268A743AE1F12B4A145264E628FC9D35DEE5ACB6122996E01E78221E46AD966B53C122EFD33774C7908BCAC16D79BCF41CB6F648DA913293434B237DD06511D2A5A05E8E5C01C44408E53CB4DB6FB22874D492362AE1D2BF16170690392D979A76627C3D5F5347EBAD4315A76649BF09C0DA85A741CC72C5D63A71E3F7BAFA97337FEE2C8C5EB5583257AC1A94C601AC42071FC3ACCA48A8C42ED3667847B3D938BCEC9AB45C8B150E35F2323127583DFBEEF5C1E8CD0E1333B7F4204FED4B5C2FBFD978B3D42352BAC156AD32916B2C22C76C10BEC77BD31046AD7AEACC2A55DAB6E5DFBF9212FD45A763E125762D6E6D35B253F05E18656DF844594987ACC39A34CA480497CCB2981207E16A2FB2F4FA75C8F603CEF272CC63E771EA6F45AF51B18AFFBBB7B2D3C8E31260D11CE04224FFFEE8E665D20977C3C30FE1C9E34495C3AA47019020B2B4582F8CCA36D34D5D27904A769DFD6C6A224B7B7AD693A7C24D04E04063D5B0CC653047895DF676CADCA882DB762FC3E432171E358B2E2C24BF514FDB6303635C6D3F3CEBDFB711E97A730D63D8C71A6DBD0349041BCE85864CF021EC2D335E48647DDB8EDC5C2DA942D87B922FCE5BCBA8E4E59DDF31EAB6A97D6F01049", - "k": "7251DB9D63102DAC680DD894609F12B795371A4012BBD22C05AF846E5D43E884", - "m": "A4BAA4C603DA1368C1F2AC552A331F77BF1D598C6BCB540D43CA1E6D4B8BDE77", - "reason": "no modification" - }, - { - "tcId": 6, - "deferred": false, - "ek": "E331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6", - "dk": "C97A2268733ED7822CD3B809F395637709A15E02CA5CD7381F27B78D9060BF67B334E193372029FA6601FA5BCAD83429A1F22ED0291AEED22790F62F27A57AE87B81D2A7B2BE812B6988400A62156FDC6DA8261C81283DCEA41C0ED48291128E38007784F65A2B39681BEA58945971551BB873869DFD5C093EF64172583AC2CA8A4646B81786A0A5B039C1F00D3503B31D352A92C2AA7880945924AF63D872E8C85BA6D499B22B17682B508CF981F9C9A8B0DB33B0E7917F9197D0D05FF4A5C38A5102E20317DED4837F46A88A41A1A9D588EBCA92440651A1F5774DC7803D3C88547C57A297A4086855AF7C197254CBEC831A0A4666E265C68CA35678068600303AA17B49A4893B0ED913BBEC197E323DD48B94893AAA0999096E7791F9E628C2E26A9E70C8B6B6AC3D1C6B61943E0220BF30D3A70BEA3272069DAAE676CEC68405A6821E0918B0730CD8D282AC733E4749C05CC382D5E727567A5B8F7258E3358831B160D9F90DC76856A0F462D2D6C66B9266C487131F37634B276E2817A2A946B71B7B84F93C64495CA2BA2947F731442B38BA9A954676580B1CB504E3903AE2B8B02CBB1FCF19A6F37342CB5A13FC923529C0AA1B18B16CC1C7AF1946A41950FB81617C369555F5CBB720971DC8076764A20AE54557AB2208684426F25B0CB0ACC6B75D0ACA76713495528461449C2DDA394FEF871B81D38D651529D7BACADFA3CC05ECB0C27444E1A53C3822641BD0B43220A682772D67D7AFEEF60EAB2B3AD3A87DB56391E471968A65261CB3B219CABFE9975A71645A7A2C9E2A234AB49B77EB689063ACA410134AA8570B687767D8F50687F4844A2B3C1C5B05B188005A0B17D4710086D283F6834EBA728F12996841350507CB5BBE247355A464AC7A008D4B9A07240475C2BD3FE1C469788F51003762F7AB89A9C980F4ABBE76782C084BB8F106AB453A7B7A16047222BB4484F992472ABB62D4EBC053BAC367EBB80579A31F2C949D53AACBCB8ECD9AAB2FF07D86388B26E47AEDE4971A4290DCD7358D306FDD951681513FFD5054BB568534D188D608870ED2028DA36B65A37AE331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6A1E6FF9222F4F2C0B6E2F4CE6BCCB009EFFC6A423DF374F485EDBC06000C8FBAF7868913CFD39EE71033FD55572599095F2E641FFD2175F6472AD7E38809A25E", - "c": "A5A62163CA438B8A067E66246A18B815146656D4015E6CF9A1FF0EA73BAF7FEC4B3E177D850822CCAA0EC3191B18CBC05EFF51C78947E4565E105DC3570946E1CD76EC2AAF0AA18FC41D8C8F74A1FA602891DBF82FA7CBDA9E0235A35E9256DBEE2A4708C7472AA5E55F8AB1362883C267D1629163E5BF048056BC8D1C67D934B274C4CC0A486BCAEE2B8BE3FB21126643417607393E57A93483BF37A3091CE196D4FB3F1B645A17B8CD6259301BBE4FDAE4174512690D68CA888DBE194E3E2F2B7AFC4C43B6AF0EF99BD4A9CFB5114A178F501BF2ABAFBD74230C9BD549D91165E96D0B19BBF96C3A938B8E6F0C30EE148933399F0FB13B70F606094EF9B02C526BD66B6E1C2FCAFAB16E0A24911B7F3BC7904FBA00C27A752072CD94E9DC7A894BAAB5E4118AA74A32B3F8668A4C5098B466746B99008A979670572944122DFD32807564C4B56D387B7C48F727D121CC34365BA85FAFE27793EFDDD70E5B0183CF9E8BE4E9B92276E49DC675001E0CC8D061CCC36845C05833308CB99C9FDCA57CB8AF659E30BE417B776D31DD99835373396E7F58A9D07D301525DCA367C1FC39C228BDDC630E0FD76D651558B220891B209DC7AF154E2C51A254B088F083A1099F80CDE8274C6FCA19CAF00338D02208327967537F8FCE0CAD2F37CB90F10DB8FEAF457A25E049D85165433115787CD7487D8ABBF1BAC4A1D694715FDA4E145BE3D9F68E18551C2A8EA31163A6407AB6968FBAA88A0CBD30870CA3DE1D61BF4F72E582B9045C83BDD3E2E26276C9A3E0D81FD9E9BBFEDE81C047E2B3F3445AA5BDE4FF909160181B1F8089F759AE9CB206C5027E04991ACBA93A098585857CB1A983DF67F8E543B626449D7F2A52B64296B2DFEB1673FFDE4CDA17F62AA035A909FF44853AE23DBABF048248C1333BA6E6BE74D2EAFAB8FF52AB31CC47CBE84A2221D4CCC498D670C8BCF382ECCEDAE8599C4FDBE7F1B328A4AC91EAC2CA326D216BC904EA0AC019DAD008ACEAFCC6CC71C97A8AB70DDCB16761EFC8ED656CA72E0385E97F14F971132370DE24A682764A88B2BAD33C56E095C7DDC6F355", - "k": "F8F9921AC3524E9AF70CAAFCE21A20ED5FC76DC988625CA9465A257D43A6FBBB", - "m": "C08584D2F5C950E371668A4FC8F527E20AF1532CC28EE6B5620729155B06389F", - "reason": "no modification" - }, - { - "tcId": 7, - "deferred": false, - "ek": "83B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5E", - "dk": "2DE77A797897F74413868189055980F0040EE0C0917405662CE681BC387D80339E8F5190B63CC50F66867CE78841379DE141141EB15A06E3948439A0F438BC56656A5846C98B21C037A888D1D23DE23A1C945B8B2691CAB7B1570606149A930200BC23B2EC335542619619BF8CB6C7C1A0B8F60C4EFF721ADE91C4AAC36E17894E54D3A006B60FDC62616666927C90A5BFD633F124BBCCB1355A901AE432CB344A72B525B58BD3C78ACBB919C3118E1346631B7E8A514F19006CC3D93AA693296EDABB57D37B61A863D3E6BC95F9C5BF114124FA5BE9425679CCA54BF316C97392BB5A7A16BCBD00953BA7650BB73BCDA3278E1EFC1C7D07B73F942326D871FFD470006657AD2B26E930759C474FEFC2CE64F631C7A39017C9B07D41434925740F03CB10335543D17BEFD57C5312A4C8609503924A4880A7664339FBCAAC331863E88C21F1109740CC8516201A20F349CF62CD56E3004DD1C56B255918699B3DBB3F262724C3F75AE212C9B0093781222B10EB9953806644F958702B80FF6274169979ED5C02ED270634B68F435433B6A36F49731C216C7C3E58BBD58ABC299C14CD1AADD4E9098F7C14354702194412A7F5341A451B6672AD433BA3A7331A006D781CC66BDD8680F5A201FA71B3B9D69FE81A624491CE09D461A8B50558B66C72F198B650A329E729C0753FF7E33E6DD41161AAA43B881DA83CB862BA187FD9AFF7885DCBA80C18C730F51360AA08CABA71C88DA42587600E59B97EDFDA010308A2E8483C71F92C3DE34625DB9E09540A8EDB1696E09C97EBB86507BABB3A901186815128A3A331CE51042E03875278048D4B085DB51094D967CD6BF6A872641E3DFA0A5DD7ADC582A303F3CC5C032C89C6B841397FE901702682939452C88D615BF488C7AF3CB433B72163436DC4E7112EF62F82D91C783ACEEB047D6F46036B70578F79634C98B5962C0EBE98AA97401ACA4B19E6A86D451206E9B06E4CB774F392AF4E1C587AA415B191818E438D0585459E43A50F61AAD3E934FCB09D6C78B43DC7BA6DFA50236984C6992149900843959AE8A7A9AA35146F78AABE2C2983B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5ECD8D9B32FE7AB08059F4D70A3AB29FDAA5385C32E8F39DA46953FF323FAF2E6A0E461934F91330CFBCBD4CF4142F5CDF2065476376506BA36FA778DBFB29077A", - "c": "A07E5CA46B6B8A0370B19BEAC4FD58C994AF463C5F773D1638C3A296CF17CA8C18F3A0AB8E1DEBAB9E42995471B0EC8B473AD1F54EDDC84F48DA0EB534C567A73775CFE32F81C94246D991FA1E05EC6C31AA0B802949D5D7D8E5C4D7EF65E3080C01946F02CBE93F65BBAC03898FD25CDC32010EC4BB0119E30BF07F71A38E30FB5091F17D9F856653263F1982F526855324B6898C2671751DF332E58EC54C903A6BB6BEA0C96263913025DFB386651E6187BBDDB1FFE726C0DE8266FAF77384D2992E5EE8DCB31F41044754839C4525B9DB85B57E13F8C02120816D98B1C220687287CD7192C4DF31327676DE1D94C4EFEBEF3628E5E444386ADC087773ECF0FC79306828E58CD5A64CEB419EF383CE920A6FBB59ED2D2C86A78A069C90F9D52BAEBF4007AFA02C1D541BCAF0C8379D1788AD0AAFD6AAD91F4AFDF9C1C165CAB4EEC304DF6FF9F4E40E18F20FB78B3669DE6C0EDD35A38DA399BCD513C49A07F517AB446B19F4A0D13905C3D496CCCE68E8E778DAAB503CADD99B10951D417B5B6A3753CF9189C2DB624C39D1913F97C8ACC47A399DC2DD3539B083A7EDC3F1B7968B2D342BB78B0D8D9B2D026273D8CA46930A98C113E515F9FF779D10AFC857E44A0E190F90DF1E9B2AF4F5EAFCB451535AA8046CC7338722C29E729E93976D097C0BA766C1C977E20796472770BA41F4964107FE11F9412EA5846E512A7FFD42E71BF50DE6D8D86BBF01EC2A867006A0F881AE97104F2E476244A869C1FF895DF12FC04DB5BF2830191E1CF58CDED8EF7494C9E532282B36C6E72D1F961ECABE75CE5A572E30250E73CE74FA5A2D3C9E5DDB5DBA93865BAD0A219A3A8670D3EFFC7CA1119F383F36768CAD4B514E0644DF95D2E7EF768D487FB98C73EB489D79EB8849A96AB0E84B8B4C97464E7E1BE4F0CCA859BDDC3881DB30E333B68CFC90D8B472E577983544EBB38B729CA073FFA80DE085C861668B7843E3576BF89579A1B9FE0CC7884675A2530D5BCC38E88136A50BB28C491BB6579D789106315C91AF1F0465FF5853D1D1F9D762514523A80559A90DFBD682C4B0E1F522D855", - "k": "70D18ECFFEA01D8C2D4BA32516A042A925618FE4A3A69FF7B932361EAE5C6B47", - "m": "1D51A0CC52E85972001B77047D97DF5F47AE11FFC6C31B4AF42FB0791A3DB40F", - "reason": "no modification" - }, - { - "tcId": 8, - "deferred": false, - "ek": "28D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACB", - "dk": "DBB9466138876E21BE1B9311F2D37C4BC447ACE23FED0137DF657CF6A396BAAB372552BB03B6AB73F6B534DCCC9CC9A40740BB0D833D64220340661BE56346C9A6A6B2E9787D5A588D1B8721218075048146F75434936CB948A8A66B5DB020C54B542D03BB4C0F352E0377B171AACD222259AEF33D2DD0A341C2BFF5BAC187391800363AF7EA21A6E535C6E226FC50661B85CF44BC1782E74963C4329D785C8661CBFA4B402CC9493A2042CA0743B156C11DDBCC2B1667EDD786C3C73C83C793A069ACC9F9CD353B94F88222A732575937B5BE0B23FAF5BD1BE1A958D77DEAA54C8AD5845E712241D92F8D1218E4070E527771495277FF0828E3C8BFFEC984832141A49264BF146FC9CC9676C59A8EA66C223888A3835932C39C7DDC15D2862C5EC54F125C799C804E6839309FD446C65A1285547662E79E54389030874A55EB6AC6D488E45863E6259D0473366E7A228EEC9A2BFB747378146010B78A712098E81F3FE0666A4669DC2B1BF9FB2BE6444AAC940427D764153575B82A143DCBB78B2097953731618A947F7057949A2B9890A43B702C052C61A5F35BA53825C02C1685A0ABCFD378F232A5251C38444B8F8349A860D67499B832271457940C8B437529D92A92B7676380628394244A8D55B4B845BBA7A674675289BEF6B1DCD532F42C6C9CE199D2AB0CF0AC4FDE7BA0B85266E540A651D6264B0A071C3C3DBBB0BBA579B587A0CEAA6C4E30305888C3BB9D073427173672063D8D5751BE6133996332846264DFC5092DA38246A74BE3A415895CC978C7A890961487650177EC32F6E30F5BFC928C2B36D7181D8F925266355A48247C4DB35E099363D303C157122F5606180C8AB08200CBBBD19B8240CDF7110C5F558F61565DD920213C60A906370D9D5820987AA2D0F00264221B5FCA7EB791A9075552FB015CFE3582B0A37F8D392D8FA3371531B9AEB54B07C0521CD9BD625669D26AB998E354CB1A5FE0D058FC866D1C67080FF99F1163917FFBCBA3D16D1071A895FC87967230A40BA46610AAB97169085700BE733346758E9B567C11C93C334145A37BB65F55CF09849128D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACBFA704DBD0B4F1351219286AA8A868F5F17C01DAFF0AA77B36857D416B7CCD47EA078DF2CFDAAC3393EB22F912F4DD6B49366F5C33F3FFACBD766EA7DC8E2EA48", - "c": "B687F42683C3C4EC4D178FC0B437B20E0612D06B76E78D3F74CDD1A3FFC75D5CAD7271CBF01C65BFC917B214CFFE0041AD9E0ABAAAD326746159E02A81567075CD4EA0B3ADC31DFD8F7D85099E2C5E43CECC717C9D9AC27530EBF7FF76D529A499CE1DA92A15AF94261076A42696A24708C8314E9707D14969BC20F0FE15CD26BD53793A24220DC346526884027C2EB342C680DE9F6CCC816035B9263F8CA25F47E5FFBF564C08CCD4C2CBFD7A53C68BA6C8429093C0474D9840734838664C7250D1A19DCC381434BDDE0DCF8403E7C5FB4F79DD595DC601BAA787173F5946F9594379C2D81DCA8E460D46A19E5C6881607BB08DD66DAB954DC5650EB18ADCD3AD5C4E50DD88EB8CD224159748EE0921EBEBF569C91C0CA37151BFE3688049F791D7389E7E8356611E6FB2221C407F3AB2C8DAFEC6B7336BDF115BE3F2A6D22A852FFDFFC258DA596A1C760672708D16A0DEF4902538EA39FD8D34D79B43F45236D265DDE44B64AC3A6106652FA301F2A5E8AE8E5D181812EE0EF7039EB6C34E954E85568BC882F0AB4EAE260621FE45B79C2A71421A3CC73576439F9B15410A62DEDB1E1C1DAD45AEBD86C6B91E0C6600D28590BCF8DFCB5222890DC48AB7931136AA5793998C1C7C97267B460B5E7726EC03287BCE6A815A5CCB408E2C945BA6E0BA9539C7DA8182478F2F466661B5780FA99C875D9B0FBA379E43526B479B202313728EECE94B3EFDCA70696AC99EE56237C3E5665A4495AC4BAC8B9E2DC1386CB2FCAD904EA3BA78B9053E631D8F84B34BDAAA590D74705911E27D14B012BD85364E2CC2B92E11852B0AEFB3CE7082998C7AEF3B376AC05984091BBFD25697F4F1161C7379B84C8F0E84435D3023782BF65BB2DE49B32A7D432310C87AF0D79B1CB59D86EEB8EA100C17CF92EB85881E2A29D17363EE263F787D8BB054079161ABF904717024B40293B1E9064CA9937805BAC81B4ED9809557CFFBDB1E68F39E4176046769C85124A66A78671B9BB2B105560883521E2B000B423D5AA9D94945BC0480500BE1BD0F2F13214AC13189CCF95A6EC0E825389D4462AE9B7E7B", - "k": "82D886E17A88F82C66E8B1E7E329CC61EB0EA64EE63FA02676B362F8DFF29D51", - "m": "BC2D661E6283B835BAEE160D1448957AC2366DCD087176E252F81F1D11E28781", - "reason": "no modification" - }, - { - "tcId": 9, - "deferred": false, - "ek": "70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83B", - "dk": "E2FA96EA25A100737368D8A9D7C3B3CE4C0085DC98854BB29306C45025C0CEFB64EFC64688D46485F8CEF9A81C8D4B53A3BC04DE05BA93EA006A760F55FC46FFE1B659A14FBB16AA00CC1EC3ECBD6C55CB64055F95B8308B690488B146669308C3C3B82D59736CA2A204F07D7984BAAC0109868C666D8644D4A29F0CB02F9C50853428A2FF773E7534989DA2567D044AD9A353628C107D9635637AC330C5A5ABFA1D548C6D552199746C0770B433848258FD185834C309DB32588E57250E206998C8783C177D8DEA3DDBE3473FA8688D7065E1BBB3F5EA79DE04AA4EC5AB16609FB3C4CFEF1659AC60B00765B38106A860506DF15C20E3D474546559822B91D5208CC03931B2C81F54122E9AC68115FA5F608CC0BFBBA7CA4211FF330154D591A48859F39B68BA36BE285B1147DC45FBCC5147A84C42315E4A412BA3D28D537C54AE295CF3400AD400807A38270578692DB112BE01359BC1CFBC001A6AC9AA070B024DD2C6E16B10C3987118F680389A34DC05606CAC4192599D2360125093905FF719A3792A1D83AAC0370A2286959C0B00A7371FF96B9035415DFCD6A0433B19D36800489C4636469BB195C4EA2563B2131B22AAB5059A30A4648E2A956535073E08376650024E52A72F1303BFD1393C7B7C2D320C74DDDB36EF035DDB3CB81F74ABCB2616EDB97FA96AAF8AC65311F790518636D89A80CA289FBFFB2B9E899A8169B0F855BA584263031C8CB5D7598AA43FBA3214FF490D56223168F6BE27557277734CEB673EFED604EF647990A27C0D8B5AB126649E3590A6F5588C7468AAFA7E4AE1C01BD96F66A645B88565310C3CF917B512C22A19589929D867D977B5D33A55DBE92C13F28FF92C6866CC4E75528CC7F5AC58FA4CE523435E08CAACA26CB71B9564C1B167BA48D9E724032368FFC29D8B15A695903210F2300B5415AA25A7034BC5E35B7C91670164DC5559185D489CCF9F168F4F175AB1F2B42249B95589474D8C9FC7EC1D15449C233A41F7A0CBE9284866A7B47170BFCCD2052F5838391A15DB0018F96CBAE3356356BB00B963ACA97A1E15757FCA358E63453F70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83BB3E7410628F44018D9DFC0EEDB18DCFAC7847E688013C039343B7FA08E0F9E191F64385D36D685D9D38D2A68F5825A84B881DECD0CE337355956C68C7F2B32EC", - "c": "FEBB296071C87A2541D8C0BBEF2F132BC433D608E04E65C035055494F9D3AEE01231784514801870A66357792C0F73238C18B99DEB53522AB3DE54A40EA37D24D62EB782187CCAE51E9DEBE131910ECABE37F312D6FAFCC8A5C1091C0C80769CDF6ADFC3A1C1F3F11DAEAAB65966885B193ABEB6D2B1A81082BB171713A983F073346E672D9F51ED6F1F1D71DDAC85B3A8188B37956709240C78D1EF276E6F534BFA98C52DBDD43E0506F665319506D11642110BA872A9DF8C197ADA9575980048639C930F29C9C45BCD7BE9774B49C2FBD7954ECBE0158D1B6911ED7FDB4EA3FA92F63BBBC34DAB800B2843B5BDC15B2EDECF6DC700A304B31C8E19049EE0371BC9A22E3F6B1C710BCC3AC662148FD9FD729DC3C339E17C4123EEBE60A36269AF28F8A81136379E76C35903C3E017B40E38F273D1B95238F71FB2D2FE6C880307762CB855C0C1951DD2C2779DCEC5285052D60CFCDE76C73B3E95F1D4868C491C71928A3DC04455F0B7F10564D4D65F358DE0AEF7C27D25E89B89E85F6A0B3C34C8AEAC06276F93E4E631EA6120F4E0130F1617891F67731075F6438DF717A4208E45DE930CDA28B737F902C3CC1592CDDF805FA269BC0DC98C40CB9DDD24AF71EAFC6B0B10C9EF2CE262F6D4A22F3C9FAF2553638DE522E5207570248FB87AE1C3DF5144F8EC2DBB4DC57F1C5F74D401D92D0F9E1D7AB98A6BE2090169FAC2C9FC9C6CFF726BD87C3FF2565052C85478FF53CE69EAE1700254AAA94125FA1B7236F4D9258987257B57988D8091AE2B0C06732C8C9FA35C2BC0896EE39825CB2C1B889EC496CE290DB565F403107E58F3DB1B2D40261EBB52492F11E3AEE9B755332B1A000595AF766AAA3D15116865BD3C6C1FDE48A149766BBE0381498B5B2BED28E4E8AA2C87FBA08D28AC8AE64ED47E8796D006169A90CEBDAA2DF63C8E809F169ABEAA9662349D740312B7ED2F26B7762352DDF8BCFF3E545DE5CAB29B5057086438944128DDA68C36C937ADA250A1826532231082E7CEEBB082C62E0BC2E1424D14FC40E057A1591886A6141C49EE309E97AF0C64D1F70FCF8BE9EBEF", - "k": "21CFA40FDE8834A21A9E419B7AD8B9E1F59B7CB184A0CC18932523CF45A1CA75", - "m": "6745F4F0730AE3F14A428A95C9CDFE82717EAA94F65B00A01566A4DCC9ED1E5E", - "reason": "no modification" - }, - { - "tcId": 10, - "deferred": false, - "ek": "5E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D", - "dk": "09035BBB278F4BBB6709E427B18149B8D60E9697BA4DEB42DFF673B87682244B907B476132C8914F26045F1794ABF41234F829E4C38A3E1007FF6C74CDD639057185AF8A419B6C56129101D4A428CA92BB42481F23F5888C596ADF8A0F51BC42BBCB7D93305D072832251466D65C864B48794D126F6EFA34FC22592FA2A843D1AEAFC5B7B84CC982CA54B0C62A4C083EF545BB8B38B7F3C97BF9067277A5CB65B0618192091159200A321948415C387B7E4D65C7061331C65A29FC323E76E11E2811A76788B1B811BF7B17952820C077954A6F731A1209A4F5F68A2059C3E7969B01FB3A2FEB7EBE0C304F2C604DC0B1628A839478059674574DE82A35B0B55A22818399247DFA2363161EF981A2E2E117B3B1A61EA42ACA4A6030E5C139D663171867AA364E7DD904AC9BAFD69B480CD35D1A9964CA5C96E3D0660E10B51E805605968AF4747D1414B258190CEBC6C87B1C476AC9B48A0A8161F66E10BBA0D2FC619C415A0846346C9AABFD2B25773A40B3A242DE25004001CD409B8E5B99C0408ACCD8127355790E0D9B03A7AC3BF9F54E1B4466DA83CC0CC7920BF583DCA743568907AF8B381B4553EFA608204A86FD59A03B333F8E4049D3FC36E04A89EF2091169BCE577368043C20725861E7D76C68497D9EAC7F2838B0DF8CB44A829C1A89A7030A3D5BE81F480275B2DBCE88BB08435446EBEB5236C1A38ABA7B1F64304B289AE2073A414434F7521E44B8CBCCCC4784B16649F5B63812AA5C723B6C4024FA8BA361E44DBF21684FCC9FE99BAF2B71BE70AB358A867D85628FA4402A97B836713036AED2A8C14141424581917B6A88A48B9037CE5AD49A4B3CB86972BE77A83A773BB64E63B8AD552E97D9604F596E1B64A891B4526BA6B9C31226C7B491F0C529BC93A2E5651FC1F5C02F27A800683E52ECC087121D4A515864A8602E3432761A385D7355B20475804B98A193BF503326EE3163821677FBC371DBD76502398199D1577C576DD7128BE9E7621AA7BE650A1A4841262BE23A6946A4809875279A93107589C8821DDD23B0C0EBB16FB047364221E3C1671F32325575555E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D01E6E2FFEC99716B96F8708E8702954EEF4142F1526CE74057D0049AF5D0376D8846E9C3DB8A50D814B91408C2FF732842F8D8DCAB2AA5CBD2848D44A65C056A", - "c": "8830427E2A9F37CCFBE39067C9D14B9404B83F9DE1BD9AF3E167D2053FD526F8534FB8960B8425CBA720065307602B8E89EB9810D7436CD44C4ADF87EB25F8B8F87865325383238931ABB418580D4774D645C71ECDDAC6B9F4EBAF3410DC142ECFDC357CB3521E62EBE0EF28BD41DF94A593374D8B9EF362D71A7D5AD6300E9C31514B5DE5AAB25E421646E152D5EE9A530F8BE6D0FF5D77DDB93827E525862437A9B6593ED284AFCC8453B409745DE7AB21FABC824307CEACF7D68D9E0EB54E69C98E3B94C61D9B0B84EAF064A966A7F99746EDC93F36DDF7826FB08C635891861FEE8D72A4FDE67F5BE139044BC775E73E7CB2695E24D81D84B2274461EC66E6A7E62571D306A667BB7C6F53AA1C3D403E2C6D48E03B29A164DB2AB7ACBB7F955F1E8CA6F836125B386453E047CB800F65656684FDD5BE79A8F12A2C90839B6EE89D73EFE016C09D878F16B92D62819B85E4275637305BBCD4FB25C578FB5CEDEFB3F9DB6165B5211623B2E53B53A71C5C2EF62A4255BB2E5AB6B9743353D0013760F89CF8A07140EC75D6BB8335DC3E1D2DC1393E43535119F3661F476168522CC25C7A702B58967113771FC6EC6B0F133DD349209C35012AA380819450487670359A906529490000F7B7179C8B6B44ED64C5700B190FD2B80E089F81E724B560E2F9479F8CA9C325B2D0E3873458E9B387BD1B2D84BF4CADF8924F55DC9C410871157B9999E0F580DEF7449F4CAF080028DED23F5437ADD8C3BF004268C9E6BAA21EF9F9C117A543E946D469A9FED47AE20524C3110D1F968A02A8C1DB24DE10316D5C2C0C28A10A043A1FC6393D7C0D6F2AA5DC379D64C1B870A1FA8D543FB17F0E5CF8F174208B370C6A4C44FA851CBA345EF09C70DCF5CE5412BC11A56E4FCC38A48D9BFF662DAFEBE105DDD686575DB01A1AA327A35E64B1DE9F55D1B3C6439E5A0396DC60A2BEF31D52ACEAB818B7068456FAA775F3F3D0BFDB4E78A3E3D38FF6162AC0AACEEFDB04474C93F071833BFC0DF73E0EB4B3A6AE04B87EB3490151A6A1DDE59BB286D449347ED0370929059D775E7909E8F35470DBDC6C", - "k": "CEC6DF7A0A9B79894EE00697CA123B88C4CF94EDAE8514C8A024498E909C72D9", - "m": "C3ED79224CB07A8D37DC9C789BC7AC8E278968E429087E5B2C0E878934DAA53F", - "reason": "no modification" - }, - { - "tcId": 11, - "deferred": false, - "ek": "F3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B", - "dk": "8B177D624AC1BC09657FF155207B487BE10A043371240026BB1578A6B96017F0BD124038F96422C1898C85C2B5ACA61292D39C1E4A472E99B5EA32631364C6B509A54CF0810FAA061F668199F32673EC6BCDE700894236B64B1F01A4A9599529E6950748830E3E64B9C1E12EAFD26147A86D585C35F56BB1B2689B30614185DC9E2EB96A72FA560EBBA991C36BD5D5B75CF2A7E217CB07AC500FCA1314470B99977248475BA90504EFD64D9BE624C3C13FF9DB9BF3E85EC9B70536451C2D2C993455C8F1061C53A404328788A80877D6BB2CD2432375B37D9DA1146A0904F7263D7E01429DC1767274A654699E862C4064F6C165C6440B3A9393315E8B74493A0C430DEA414C5AA1166B47CD611DD072A0E78A64E191B8C369809F644603C2C92527B3328B9C4C491CB92364E0B632A1F86052302DF0CC196D259828113977347AB59528C91409C2B15E9262966B6980A4FC3A472318FDA787A94B52D9499076D118D02259DC5A6A16D3B90EDB5AA88C40315C703EA52A4B227A2D7103C2C0BF0EB455442A692B3BB9DE56B6528B8DCF383569610872C9469B21BE123C7B30B251310BAD364272C4D7691514755C149EDB752A67854A7830A2B5E6C7913549A4B78709007F30178C832BB9BEB8072FE42B96AC73C17A55ED10CFAB0690AEE71739A8828EF27D3B356156461A9E406E864A931906AF731A241B8B55D344B7ADF93C0477B4A8EC41E82457798666DFB96BAE33876E384CFE3AAB021622599078F15CAD6FD5A7829BC87D20595A5430BFC6AB2B138D54BC36A6B58BE1148906C2566C5347BE340C71949DC849A0F38081DC0B7B7CAC8DBBA5341EC61A1DD889D262BDA734A0EE691063D0CB08045414E37548195C6CA41B1F69BE334638582441E3A3CAF965962277466CC1A5056608B72C5B6232B2901A93D615CBADB57F2265917A330EC8208BAF046BA2960B80E502B4F48ACCA6AA972528D3504C1696C6D4D116325361CEB15F9CEAC560019C3B3A8F374397DD17AE23588D40779473684DE24768EB628D38F336C075A2CD56402783863FA2827AE03B74A2B3B0C4AE36300FF3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B5FA88098305912B30A55D51412219D3B2A6271BD46046F454AA4AE238431115880FCD17FAB3E190E96CE2AB5E42ADCEE8E516644801B0C0D42BA08B82F5E6E9A", - "c": "128FEFB85AF81CD2D9BE101E5B2C6D4D10C43C870A5E180D9E811541F16875B9D1D4842CD6B2A9555D16C7C47A1A30647BECC8628788194ACA88048B291A3A83CB5D4346C5D741CAA1AE631B59020795049046BA09C262D50896BC4D390F4963970FECB91DF2DE283EAD7CBA46F8DEF0AF5C9819B3F76B7EA1C653584911809310ECF9CB171F1B0C83F147D70996F57B18D0D7BF596983017E02AA7B465210B5BF402444167831D409D2D9A7CE9C24D3DC6CE7A3F71DD0E7F13F66214B29753D625A7874D4606B3688D8FDFDF0459034C4B61794EB476D02C375DE54E543F4C5CE160D0764AD5F001B4CAC7FEFE69B06B5DD4188D6A75DA0EFE81C8BF2B378F888BBD41F9976B56CEE9B6A30AC1F7DAED843FF1A6C209CBA6AB8CFA42E0270817C7CD1A8EE1D8E5552A5771A95B0C621666AAB4738897A5C35F54618D41E4BE592EB6E530228B21A09D56A86039DADA8A8D530E7D95658CF9C3AD3E2476FA037B38F8730EBA96423F5CDF884E9F707B18326A9BC9EE51072AEF8096B9D2CA9D2347E4981AE99ABAB9A2DEE0DBFE2AEE8BBFF5F2EBACE1899089B2AF44318F1530E2DB95F6A6004BEA7BA1643801C2384E254A4E42372E74B30CDAABA3A5A7868A43A91F58503C7DF9FEA920D8C29EECFCCD6D42332D2DF6E2A689865BA65A03B65F0E9338BCCE725BB3E50B28FBCF0F194E24D7EBF89FE4B7B546014667962D92FB7F33681110958A6F5AA0129717FE505C5EB2A009E641FFA73AAC6F214F9B75EA658D012FC638D7C607D6C8292140D856BC2FF86E5DCA2B357C6C92934E342C84AB22374E2C65C5071F1A29E21A3D346A5F4F2B6EDFC1985CEDAFD9F62BC44B07C42E4C34B24450FA07394FE067804775F98846E5F72977CA6B58484D2EC6A5634B2C11485DA0D4AC1F96226EC3920A3FCE229E801F2C9F175C56DC03059B00154A7540CBC4A538B700DD948C19EAF88EF6C206B5F58EB6538DEE0C87E132C62086F38C8F1E9A799E845E2A7472DD393A3FD455617A9C687C1503ED17D8E01C992F503A699249B81BCBA9A9F7606217BAFABAC90995A85DF6663A7BB6370DD", - "k": "9015AB2A00F4E86BC82E6B3F5208D45BA0A725876A9E19D52C9A43332554D3CB", - "m": "41C74E66327238C6F7B2ED2683FC5E88CC35083512BC285CCB7165499F34A0B8", - "reason": "no modification" - }, - { - "tcId": 12, - "deferred": false, - "ek": "A4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0", - "dk": "5260A5E1F6990DCC65328126BAE9BABC0B28E7010A2F9244362218C5E9074A331179B16A07676727966476FBBFACA90119722A168C6CD5A1619A0548C15144FB408C1099BEE94C25DCB119EC6A677F3B0D0D705BF8B7047C564BA5C1843378903CA64D1EE7357D0A2102865417865CC97C93EA5362B4BACB5E5604ADE8CF16E6A70F455A91D104E98C9D63273476C067AAF45B8739099C527B7ABBA56E9B1D939C8A776C4931A14B9B34907EB309FED94406145274738D7C061F5F7038CC2AB9AF6243C913A3CE212ADD4B983FB646A7732BF1B30BF2759CB52936C325CF475C47A6A54979BA2A17D4066D52A728BA6198CB52762829D85C56F0DC1B4352A191AAACE6CB1C26A348E45A25BE0C86A66B16DEF9AC236C2C03BA883CC80908F8586501C5C8D02F0EFAB2D9924CBC2B2935CC73D946A8A370362FAB0C8D94891D980CC8665290B7471D5477902B8A83A0C5B5B2A8BBA4622E272AA9FCA8AF59C40E109C682AAE7BA0C61B49C127629AB0628E402828E7246219AC368063660B1910C7D10CC5992501841612C44F4056B319044721EC9550E235BBFC6D384A9013C52C61257BB9D315F8C383DA7C66A4690C29930F6912665BB494CE63A96185B4DA193C1D58CD79A312ED57BD4E4A86FDBA31D87995C9409A6D03924D6C35145BB0233BBDE8A717E2291F673903839047C23B401FA680EFFA41869664F7F3612C552B01C9CB05D518E6010A744CB5756A31A50BB965AB3ACD62781955295D7C4A07FA13EF911DE93AA477952D99CBCCB3A83FB0E50046917506352B34158E8E451AFFCB9E31F7B800D00D23CA1A927C4AD9B57E0DC7B69EE270A063B3B286ABDAA22C946AC6C436233C6979C3570BB5889F39264017A63E09FB54547C5711B0B6C8576A8F1C8B013A0EF8190795F42E376C803EA4A8908605C8F51E07C3983A357423D594D79080C71AB3EF930901D31D6539328BA5B18725BD47E6AE466C2891F4C889426D5BD267A9B696EC4739C5F978619C786333472EF241353688A02C1154D4650C0C5E22C61AB77B0FE1D193573760720CB2E633868B0B114DD8CD03316DA4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0AE9CB398180B4EFE7B808B5881B8F0E5F9A8C23F7FF068DF3BD63457D3B48469DFD461BAA311495C347EFC0C40ACCA288BED6D4DBCF3BEA45D5AFCB6E7FFBC2D", - "c": "D9B7CFCCD8D7790A264374AD1ACF09AAAEEEF36B2AE84D657C05C697901FCC6C6B6F31BE49D729E31FBE760A93D9BF54D0FC37B81F6240D3BCBD911142EE7C330A570CED051BA7DE20810F59D6A2BB0B00F7525F071EDFB8B9DCAD854C70FD454784EB8F68638A1880D468FEA90EF517EA77594B53E901A2BD3FE2BA66F69B6F644FA0556D43FD799145B389CDDCEBAFB1A84B9C6F34231D0028584A8FFD70E69E1C84F33884ED6D95793803281561ADABF1EEEE72C22790558F3A6B7F0A54FCB96BFAB67314951158CE54880D201E9E8B0E76A47DB6FE8E7C767A4F604ACA6A598A25233440687ACEE588E5085B7A28C09E01E4906F3D834938833F165CD6FDAB1524F7FAA64C0B44C1691DA39FE88C19548F9D3ED4EAB68E853CAE954C7749AD6C55383E254E7FFC9662D500AFB1FF1A6A0312D7FDA9606C9E3665C46D0F7DA6C3B3F61EFB25DF574126D3843FFFE720651A06ABF241A68702B7B9A07648AD17E5238FD29D1CCF781605FF482857F1B10E36CE1BCFDEC8D8A0AEFFE0643E65E1BF0B060FCDC5C591CA15B645B701D33D1FB4ADEA2D13562D73CF68361BED92FF108BCC5C31B8E9AA913C112EF54C529BE6A4D2CC64808DFB5CD5EA8499007FA9F156CFA686248FD7232E797E4944E433FCE98B3864B46751D2C55FBC1C4C71FE96A875CBEA1F47F1D6A3C98E80876780B95936EB0368CD56284B211E670BE4ABB5536E6F9C7BB1D2A23C04705BA1D851408A2C566E9893B5C9EC60245EA2174016096B9FB8E8476A94E174E7CD68C66AA805512A5D851ADB17A99B49C33754BAA091E834A09C90880C95032D385458BF514A3B88C67FBA9E93317998AB39F712A5C38F1BB51BD9FDC0B538189580DFDAB817341145752F840FB4207EDB939855745977A65B27642F7C28C91FA7D78075ADB813D896DBBD57DF60EEB46A9C00E07F1F63867978B61AE357F695A1E2D415496773CB52258E94012527DD1FBD35B0A239A48894C4F54FD2606C9B5919BDD52C671D9FD169D8F4C6FE9D01E19B358A84876D303AF979222BAB23CEECE34209D8C1F890091B547374FEFEA7E5A6B8", - "k": "6D339C7DE13DA2BC3F672AEC4DDE931C811FAA91A8E91182DE4F94F2009EF16B", - "m": "6DB6A3F134471A89ABEC3384BB48A3C405DD3B2A5EF53821A3C1EA74DD562799", - "reason": "no modification" - }, - { - "tcId": 13, - "deferred": false, - "ek": "34166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B", - "dk": "BE01752AEA3528793D84B87D34010B58DA56FA4219F62A2BF66530B4115EA494A0AEC432AB2A2F6624C984E522BBEB6B34B1329D1501BF41B48CE820D99B3476413A87FC1055EA373BF32DCEE2573F13B14AA43A441BB2FBD97CB863B1D2CB0B60078552E8941F7A9A4703C6ED6621CB055C5C2CA4BE869887140746131CEDD20FCE9C38AE2221E49C384D76A9CD6141EAB46CDEE4B8F9EB734C0A698A038E1F14C4EB92A526711EE058502F54005DF57A443C11806496F14756687136F44B80FAB94E5A145F6A1A8224886DECB1B5C872202190106A95C588C0BC8ABA28EA5BB4C3D39330D17FA78098E1BA7550EA3CE47516F91801D01BC09AB8C9897495DCE68E45366A8BE5962612A4B0E6943DA72EBC87270A64B083225C2D408EDB1596B0FAB8BE0540098B0BF32C18B7401AE1F65C14F4C81337AB8F64A4A7818127AC10195C929C51B85001498D9CA7BB5A13D2FA515CDA75D6E795611B1ABE18981B972D3086136E5841EADCC52C2162B1461250C9111A3016B3B78BADDC6F59E4BEDF989DE0DC03D1555B98CAB2CDD150ACE44B241B6C4938002EE610910A22126B94937A9A7DB1BCB2079DB81B0BAF0A2A1AA80D609B76381888E0FA05329C49C379BA71300A9171B0227B442C610FDC2995C9778CE990B3C1DA83F3C8C1F2C499A1B9A1D936538C9C61B71C83524747C4775FADC055F08AC79622B4CFAC6996C5602C992713607F2D59621A9B1BCE67517A26BFFD636922362E96DA43B5C72BB0697F24167DF97B724971AA5C8B5011C02DE7857F761154E24B6D1741C49616BD17E360A9586D612589FA81625A5C55083092550C8F69B883E6C1510A122C94860EA277274BE1028353219F7B0CFE837B59D895F0A0597BB1AB93D39C6EEA6FE41A70BA395B97FA20B7161437543CBD107BA552CC13BA389F985622C5B4BE7C7F600A6C45196DF7B66BC1053C5A4C7EE2027B49E6ADBC100996717936C89B1F878ED03C4254E84FCD3251129A078749AFB1713635A83FAAE1C201F1012D68940BFB0B44BB87D43344FBC1C2F58B29B2943B148BCD9D4C368837B0BB6A0AEF083134166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B25939AD5E8DF2448392861CD66369376BE1E6828D87503F46841BB7682A42BA34940BEAD249B04A55DC051633480E518638E7792F57535B3FAC26F0A535A9494", - "c": "3BCD7972030D4F3414C2D151C52BDB8F96500ADB92F89A721A305EA938987F4B0314F093FAE503D8375C134046365443E3E000E19984777AE9189169E20AEC928F3DF3E1CCD2963BAEF94436E3D8116721413C7254F90208C788644A3AD90AECA2814526EEE017E07E222ED0987E5693C2C4EBD524F2B79772B974FD738C59D18FDC9E091F32351F86C57F57A21BE5706C6394D06253FB4526FEB48ACD18668324B7E662E5909CD76F160FE8C562975789F6C7290D1BD167E647FA2FA61FC753D5AA6FF7C62BCF3D7144D3EC02AFCB3E162C3D47F268D78F08FD3B621F66970C9A2A95C003092C3246DFDB1104AB31FAF7FC140D7AA39AF34F429C51041AE7BEDC26608A8BF52D43901BE92E65DCB87B832442ABC64A9F61745F70596A148D3EB7E40E7C8A49B24155BDE63635FD26FDB6458145D06FBA000E577073A407B36D4CD898A312285871487B50B25589D39BB453521F8436DB251710CA8F6F3E5D6EEF56F52291F7AC3DB7520E03DD95058C5CC4AE39E35FCAEC9C7E0284A9483C09D473EA173BAED7BAE5E6397F128C872469CB092A65FD1D2CEDA8E659CA97E7781EDDE6EDA94E68746182FB5A44BF7951C4768F66532445F577950642756BB1FD08448128CAE0D819BDB41DA547914CE892963F64C609C44170AED7918B3192EFCAB9AFB493CEEB327A4A6D21F7FDA7ABAEFED12FCE2F180C8A01FB905482B8BD65859CBED2FB8D13C65CFF497D8C9E0621DFCF8ABA62FB0FF0DE460C04313127031FF4883E9077A4A3FFF4D21740E02563F9595E2DB7B5867A7D5AAC7D7CC2E6206B9DD07CA8D2743F69D3FD0D5C00EB16E55827EE917205816DB1C6ED1BEECD4D529C9A1FA1C9115312B3C9392790BDBDE5EAE4078C90D7CA55CDC4021EEE7D488949AFCC05F2D7F4AD5505B3613983A87ED316B0D16443CBACD8206B593D86ED37B4C884B7C1124B74F30C6F2FEC61AA6EB96CA206EED58164F87D5849814F793FC54BFE5D5AF81E497F60E3C1CBBE2FA1FA8A602A4A36F60A567E9605CD439A2096B2EB051F3F9DD901BF119E172F52D617B6E5EC6422B0B05C030C20649C", - "k": "63AC7D8750E143131B3FE26C0FD5484F5D60DC8D22B542EBFF0D5D8B54F34EEF", - "m": "121DC782B740EAE666E709EA6E3CC6CEB8EAD204CD7D85D2256839E98CA57003", - "reason": "no modification" - }, - { - "tcId": 14, - "deferred": false, - "ek": "F3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1", - "dk": "DB859103F7ADE02C4713C26A95447BCB6BC359F21EE93B845C5C0A145A9841BB576D206B60E46417AB9163A86BE30AC95FE3C9F9EB21DE282FF8D61A68CC43EFFA3FE3BBC9A5D56C304194DADCB94BDAAEF8CA74857C6C5C58A35D415D4E23BEBB602ECCE89B376CB61365C5014C128D090BD3F1CD51380A7D63965C7B143A19663F007CDCC5736BE624ED2721B5F915B8AB4405E5B44C3CAEA181B60A6347A1F0AD7278A879C75829935B056600D078133361A495539E612B9F677263A4A808A0851C54F65D54E8195BD4313D76A9590213EEC21B8FF2561E191DF5B8227D03632782B8A539524E6349D1693B61C0BD4F47B7CAC2AD539A69C609BD6146400F9590A0796DA89ABD99B62C30756CDA7854A792AD8DFC8FC695CE68FAB4AFE88134090AAECB29C0D75C1916A3B6225A76CB6C0E530BE46A60A3A2C8C07427ECB7C090002378B98F03450AA7AA0D8AE5226967C7E9F43AB50C098EB80FC72347E631120B8BBBA3E5C731A7ADE238B55A1763772A86C1159F96EB0B96D5CE0D3C9BA68B9D099A7184A461F91010B8B98C08E0B67A67CC6D4414390A0009493955172B85076F17BAA9A9645C21101ED962574E7C5AADA2B1EA401D05C92494A07664E6521219CDB248CF2D7B76E4D8BC77E30A6CC80017B282F6F55DD81355A8D296D4F0C71D95C14D9031510B012C989BCF959B51B44913B0808C786467AACB0E870C4297034F47AF6226BF8C3527D83B15C547CB94070739367CD48949DC7126E3672068C09C55C48BFB610AC87B81CDE4619221656C624DC1C24C6A038EEF5B58A09A801B225A132C85EAD459DB0A49DEC270B2F046C9482D41B20699E97C11905D4333ADD8139C659289537A411E3BA8FEB1072DB3C723551C7057BA55ABBF0F6755A465B73A93312D4C0BE8C9BAEFC872B48131B6920CBB48114846436E091554F2C352C919B6B16BABAABAB0D1424A5AA5CDD32FFF661DFF15A5BE1A83A0E517FEA9CE2462554F3C64A21C2769A18206F34071C1B2AFA03403B814CFB90DAB476F29B6ABE9DA68F4AB42A10C11C54A54CE51BD03B23DF85072B333114589BCF3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1C9EFC09C35370E689B7071A0232850E93F30C5E774FCD37BEE6F8DB91C039E822D53C0A2C522F3E692881F0A4C65BBA41050E7D310898A6747509513A03A418C", - "c": "DC29B9910BC0978FDB8F6D7C215C91E003C550A7244B5D98509145A3544C5CB2AD40A332B2817D15182C8A31108109073D4416992C99149241C5FD147A48F23981C2B69C34E7A72D11B7DA6ED9973AA55A4812239BF8E0DD193E1EDC85635D31FCB26F094E23D47C84F805755D58D3FF7B30E81B8066986D2DC94210778F2F52F94C569AEF36A35F4AAA445B54180F703C28684D842763C9C1C0AFBFED51895B06670D97F68548E40202BF56A1BE5F874A6A440E4673E4A3E4095DB97FD9D36B30F4BE492FC957FA898E4E9BDE175C91927B058D0A1E10A500DA733B640B08DEE07AB4ABA009DC5B5E300F477E6E34431CC8A5DD699EC6D7C509637B6475C5D28DDB73E790F7EB60F7398303B4501D56E2161755D3E43B24AB4C1B391E4FA041C8FE0153BAD4CB6072213EFCE733FD9490583B93DB3D319B51E8DD497A1CFCCBFCC3B227747A9B86B2C5DA52F36894450B2750CEF3B425671EF059C0C4BAE8CB25E6CD626409F79E63CE4262B2275A45D18618DB57E9CF3D8CEA6B22B69340B9807B1DD696B9CDBEA445BD0E1FBDE9D86C92265C808B677A10EEAEDBB71E04949A2FDCC3094ECCD5C37C08A9B3636AAD670356633BAE9B7C16B5A8C4AC79C2873B4056C65E1CBDF13F7A55FA5EC9C4E530B3F13479D8435AC937C165C1269AA8AA7D939433AB0EF01BB87D2FC4D9B9405545D59FAFE004DF0A8086F486B04B1105DF829840CE198BCCE0F55C7486572891E31EFAE42785A2557CA8A685AC8A2655D71E4266D3418BAF29728193C3C5C22E7BF12A933CBEA2D3665C8A155B7B8B8E9EFFC7F99B580393AF3F76ECF9D731D5A299E8D8B2ACD2EDF58F6AE336D3DEE5D7258DE80C86B0E311536F8FAB511574504DB04B4E8326176C15DE143E5DA575C027585E1C8DA38CB50A2A72DAE9D5E266F106261395CC2F9575C6E59B7C73476A65BDCEDDB9E03CF299EEB5089683043FC97A8EB247CD46656A7CC5812DEB8E111CA1040E9BD541CD8AD4786FFB04ED643456E72F3C6DF4D595B1ECB097D6564D42D5915BE55D339D7583AC55B4C1D8221258C0A5BA1443F9BFFFDD2AEE31", - "k": "CEC93D98469424039335CB12FD0ABA4CAAFF3E3B99E55A53507F2CD3458536F4", - "m": "307C7DF0692D264A8186B8D844C7287B236D0FC7EC148BCFBF261A16B0FB7B61", - "reason": "no modification" - }, - { - "tcId": 15, - "deferred": false, - "ek": "E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A", - "dk": "372270C8D59DBC34CF01B107E7E711D265669C5C01EE729926C033D53B0790D05F97DBB75059B3BBB122B73309ACA75D91582C409B39886416F5D97219872FD564935DF0B30F0A5BE2B3B6D08AC5193283E70C93C25C558BE17A93020F375C44B640AE41D974EC2020640515D74CC083143677B32C73D688088B03E8455DF248212B7AA82FC01F1BA0AD96B9430711BF05DBCCB075732F700B124C6B298B171D84C4F338994E0611FEA9AD4244C968DB44AB2967AA7666B8652C12588A3E728235C7A9B88A4D3D7A6C05B46A0D53C31744ACED6BC02B372B364085DE5CC13B2B4B7BBC36C0B06127A67AB170B9BC7C7F938A0A26254808E35A6024920B463EC8D223ECACA90327488EE8246EE5B076CCB5A734B197D61676576A2A4714FE0B3D69B87B581660981CCEA31923A1FB3498802BEA542FF3F1078529161291B014B94785F6BDE14595ED2B0B0560614C547F6952AEAF44974B6365C488235CA23A93759C9F707CDAFB8D81D701B31B08E473852605A493B8CE06B15BB95641069C85B0BB7D826A6F77D743B4051210C742314B787C77AB9193A9765256402C4575F3910C63C92EB816DFB9821C324D6852A5792041FEB441102839DDCB4D49E6ADFB291395B12DD409756E7CCB67192A3137CDAB072DD5004C7742C60A68CB45D63EC2A85F4452A9DD1A06781200D9D65A049BA37A7349402175E6D82AE4F16F802598A1463B46C2A45F583C8F051A84C399F227797F0A0A5051A3B13171C47A8A2CBA99EDBA992E58A5B4E544D19944DF60A1E7A2CFAD69216F4377B48B4B04C206BE5C6F83EA47F702620015029AD3AEF31970EA739ED5E887195C8DC94CAA7B199AB88634326A8303F535B71BCD514C44FFA33F5613388D32778B3C91BACC9F5E659CD170CEFD174D76B096AA2923E99C1AB288CE5897C9066631E1D82267212FAE1221905A7454D753FA916F85094B9DD87972F49D832C19351125BD754047F7200FE049868185658318BEFB8D913A41C6C1887F79C02567AB9236B485148D736B063B6B1EEA0C5F9D8491D279264261B375A799144C9BA787B5DEA211BB85A2E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A8034B3E7058DC6E140C0F4220A80B43CACD9758598E55F2931A11A2F5C9026556B16944CAA344BD9BB904392078ADBE511660D4F9228446D69DF2A20A6CEE850", - "c": "7122A73DFE33E937B2D3350EADC73B3EE70C3BC5E9C4B2E7DC590A491CB7DA736B3B37294B0F13013BA8FFD8B25C2164E8EE528044A230220D8203AC4D2ED48FF05C479762CE72DC62957E839580C7FAFA23556119AFA66A53655C48E6193E1B386E4689821F5FA81643B22A7455A8BF30523098721042830259D90B69E21F038607140030A9EEAF30EBC813835AF12CAC2E018F7EF30473D235E6631ECA0306D6AB9E45608DEB559416CC92A7B4D465CD56184B0C4353D8A8D96C257FFAD6A90E090C8D735FD32A14849DCA6B383ACA3FE0A9F482A5A5069AE3B9542E83BD873C3D3C0B052C5DF69D267DB237D65EAB2E84F38B4272F079F84FB6D64F17D864464522E6F79D2BA9C4F1C2E6A0EB8FAEA6CF8AFC71E79B084E77D7BDBAAEB233F107697D245EF9BA19E142C73C9513E711621530B040DCC9B70088436DA2564F97FDC79E8D062ED490778BE78BBAB0B9E71559C6F5A7A314D73C4E16CE627E88F27F1502BD90C001607214772DDEA44C59040DCE7051F0BF2BBD712EC82CEE54A6F41E19DFEB32AF373BFAC06469346AF5CD7B32A15B66A5147E0D880FC180C228ADDC6755C3957740CF7A41F83B3DB58D23B19A33A4275EC795FD1EA20CF6BE52F5070B261A68AA0504CDCF3391A84EAB931FB14EAB16BDA72F69E15364962DA5988E4F0C37C715E5805DDC9674CC1E44449A0E534FB5E4499B32B6B959DFC0E937F40C4F0922EC6B29D8D4C8676F2555FC43B6D860696294A0FE7776D4944CDDCE8133646A0DCFD9D9117595E542E8F82BDFFDD969DA7736724A7FF71E322333EFE3CFD97BC04E80968248BAD48BDFF5F8AA6B0BC1C5141A7B70755199F83B0A896B2FE547F68CBEDAFFCB101A1520E1AC1E6FC364078D626FF53140271CF9E6FE8299D58DF313C50D082D7EEF995DC34BB98BE6026EB87EBB6AE6B776F72C71030DA2DE3F9A84B45953F80EB0A5F06B7408E7F9BC9EBE7064AD8BD9DA234CF4F29DED508106416A6B39131862D4DE2774663658F02F53D85206C8A9A3B78AF18623574E109DBF54EE08659ED285543ACEA5DD2533045FB16EDFF387612CB0", - "k": "BD132E98714A75116BB032DFA0C7B0C34EAD0780C576DF9EC11200256B4BDA87", - "m": "60363F5CDB16BC516A1367DFCE1B72926FB2189B88AA1DEBFD22F440B9CAF0C2", - "reason": "no modification" - }, - { - "tcId": 16, - "deferred": false, - "ek": "964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC", - "dk": "879036ADEB2F85A51E3AB14979E71A494A8D3DC4CCB6B6A35F826CB03761A1A799F621957DB260133988DD12600DC33602226CEC50434BF059E3B11FE5F19A42BA1DF9164EA118090FB7A1AE857AB7E8ADBAF66DCE7CCC01B8BFA93153D3E5A644C56B1116058F47C663CCA1F54C3184BBB0FE8CBD05E53265ACBE72CB37286929D85B856CC8587DB46DBB3622930465775893FB7401E9E98430FCBDB9966DB60280C8319349C18C62E56DC9BB538DD296A47169753A1394680D202A7EC33ACAA12B315BD69F93A07F77B9C6396209FF4198FA88508A4548F16503B1C4079F7086CEB9BB4F751A0B8175B3F193805685F098A45E0BA16EF3828599842A240B05A201ACFB45B63C4C2D6BC35EC36D69E4142666B8600AAA123B6E6D7C15171BA2FDD94B0205BBD4963A45CC46BC089BDF817C52933E36DBC911174EB62CC4AE4AC8C4E45782736125948A97A2C66E7C9A756CA146253D8C07349A6C4D4D97BE122BA433DC388F972CBE79695C878A23537F33C3B339879BA0481A41032E961618198529DD154FB38B918A019A0FB75827084881871176E02C1E8ACB746832F44191C1B36D2B96CB630499E83007636AC656707998F436C1472EC3406515276E7A4840DC509123D2907AC7424416A656A74E49EB478A01750470ABA7F5AA416BB99A50CC6FD823AC1B9178376A8DDACCDDD2975CD68724FBA3970216983219B70A4ECE563A00C44CF121880FC8C5936124DA62008BAC6319806E1368B4B8467CA8980962C826FC20761D131D6692C2F1907BDDC83F2CEBCDE692C8CFE6880BA357D1D056A022A1D3A4C0D7F638161011AA83B18500096591A1D6B55110976CBE0A03BB78AC7CC34FC5774D794B3871B94BC7C081D5895CB44C0EC7E9B2782004C5C61564F582C537C6B72B5B0B924799181D6D012EA130B2D5E0C998F0C3CD829BBE48645A6905F6D240AA518CE42851989C987CB9CCE9F71C43328703F5882DD13EA0841251FA4177B593BFD58AFD146631D876C1D96310CB2C6850783C5939A431483DA78E09C3041880B1C3686B0C45B442427B61443D957C01A580B287B1AE964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC6D63B8A32687E3ADAB407548CE8B83437F355FCE2D96C1BCEC6C006F7E493B743ABD1651588386750AD3B35DADE74C328DF82778D99596561ABD71F194AAD28C", - "c": "4DBE5E9CC3989D6CCE8D9F491B94985E770AA2ED9D214D45B03832D90EC0817A9F06856EB4D6AD8BEB6B64B7F1892EF9E13C594C7BC1B9222C655F259603868047D35ABAA67FE36816BDC493502E0B3E4129DD58A8971590E182B71386F6BA4F4580618EF186668C0579109E6DED3DC1A8F22EF6FEAD9D20D9435C144CA8D46367F178CD0957A638AFCDA69C96C59B3FE03557107915629E21F148603EF68FFDE3327FDCA00A6B1A3E498F90FE7634E56AEF588DE8E9C567D3C9F8E5E66A7DA505DEB1AF29DB37CBC5089C27BDCAF1E06614D796B89B3C1D9B40294FF479D6E64BEA14520E734600CCAEF6AFB0DFE7B66291F79859E988A4FC78431EBAEF90F511273B16DA1FB42C404D793EB36414A40DAFEFCA07F1787FF9454FCE27EB142B985D21D8E086ECDF1B2DB9B7DB12F1BA442BA3C8C16613A8BB7D4F155155F6AED9196E54BA77027B8C040E6A047AD6F41FF174FF3CA4F38A167221B8715FF60661E744EA43F49335C3E2197E57D7A1DD5CF53DA8D3ABF359251675461EFEF9CC2F033B6ABD73B35A8CF740D65089CCF5FBB94DFE1CCAF26AE43F7E5F630209C7A6EC93753E808345AAD1068D18DE64BFC4A8BAA6EB6E72D97824216F922729D9FE73401EABD11113FD7B69AB97FB10525F273EE35B2390446EFFF9BDEF7FEBC416E6668B06FF5AA7A5C50DDE17554606228B8586BC93E6A7B9B239D8DCFF2E4E55ECBC75C9E449F25E48CC2100C3F130429EB3F841EC2C1A8297769AE8CA81DE932833DB2CF10C9EA57A682A48E26E3D42D9BA9A6D61C82F4014B804B8AD8619CF84AFD3645976ACD87D1B3B7D40CDD87C35C2E3973296D22851C80F84B792FDBD81F549968E2BC6DF18C37F50805D29CB657DCD9C392070FF3EB4EDEBA8DB298447A713E517B94B1CA4C11CD462B2ACED35C4AEA82D65E5D5F050CBD7DD8B40BE07628025F8A352CE8A15D8FCA7FEB78F9D6A1D179FF4AA336CDF3925FDE9631BB53649DC65BAA226CDA770E50ADB9E2E3651A4E6776748D76F9444960FD14B9116AD419F6E5A4D74116890F05AC8ED0BE52A1C70DDECDEEE8C6914B40B1BCF", - "k": "CAA24999EFE659AEFCF18FC9C722FAC1D5DACE583B716AD3828B15C7DF5D94DF", - "m": "579474C123B3381801867203E0021E2B7F15E5F9426D75A3EDA6CBCAECECCF43", - "reason": "no modification" - }, - { - "tcId": 17, - "deferred": false, - "ek": "87EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C", - "dk": "77E8C08006BBA3A7423AE68A67F48336EB0F5FA3B14F931F8B88AAAD384FBCC3CC291480228079D4179A3B6A0E555A4D3E6A5C8BD72A5C0779E770C56B53BAE1974EE047AC3DC953525C03C5ACCC0164C02C65B10407CBEA6AB0F9A413F0E169CCE31446BA219F765B90353F8FB327F9F8C767F6BEA749666FEA81D1186AFEB5170977BADAC98E0BE57854431756C042DB86430C27A358A3BBCF823261C8017FC8B81F9970BF9B73433531C13AAE0A960D82C06CC491865CF4450BA6641D1729B0F7769D073FFE99BF2A8C8D40538CA08318FD163FC5F12264266710D7259F765DA6786EA386C5E9543BEAA54FC785C1C83940FEBB2C866B737DB93D2E798E03A52645330901D118D0C973A1E997E5BC39967577E51C752DE187EAAC8E5C167BEF272F79483A658B6382B93F67E07E3182A183AB9842951FBEFC8CA6525D571B9B7C995D89366AF8E62B371B6A5A0990F3B7AFA054B997E921AD708623950EE7A2C6AED3316580735002C48A298AAD0174DB794A5C862092061E0C25824AE84B6BE824A33911A112AD51509E29424B4D933946528224E64B4BF924552706E7307B4FB7B8C2D083B2245A5787A19100CE78465C3B663330006C8BD0B626CBB9ABFAA3F551ABF18AC146081ED1AC99A37944915CB6E1713DDA4049C3F0CCE4611E6A21458124A850119CD5B846867C6DF0E9592B0A1AF7F1C5210C6CC2E5192A44778AF59BF90935AB8812E811B909528A402174B3747ECF6CB6DBC58DFAF15CE849BE309760A0F9274409C8EB25A679764090E59F27553AE4B31A00DA84B25A843F23C6D9024B23CA942EFC05753123C703391C21B539C9973E14611562036C793CCEA69B0A51785664C0367B94BBDC45833BBD6F132F1A34A31134A934E72A6F988A36A9BA6516981F242F67C33C9F71C113D40380147274427F429A1F26FC5C5EAB9379F0A73DF442B4B2A299E827B0A522DA24690DE17F72A547E9E228D98541C5C02058B1879D5946AC83B338277B6362C72371A6F866C2C72481024A4ACCD0B91AA560249CB5B01B0BABEC227D1AA1D6FB5E878C66214A9DFF0BA989C78987EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C29148150CC61C6C8B7FD408B3C9B21B6BF530E9D9AB72573FC6DED2E4A10C4C0D01000728E8DA5326C713E45EDF82C441D51791E0AE7663DF7E931EA208B7313", - "c": "A707FA4EE57BCFA296EF6D10B848DEE8A48BBF84A465529F837977FFACB3E429D0D2C58BA2A10406995B6328AE91728087648B7F018FF9E570E533F982EB58FFECF6BB104CF2E6D819E3E17CFEC29F31F275C64450B5D8C14E231C563F03FB978B214A51DAE1118D8BD235920B401A706F8C3917D3CA066CF0D1D6591893B244ADF6F0E514575E67BCE3CA8217330153EFF5F91FBA1C23CAB3906F2DB8BEFE01742EA2DBBDC0D3B7127BCA805430792E30CC2CC7C1108EE02CF429820C232A65E4A3CED4949FA184A8B624EB4C4B72DE88750FF7565E35A54E71DC289AE7E59F9F05A915BB0B35C7FD36967EBEFAAD806779A116DEEB462306E3757C94F2B6EEC836DDF1CAE12E3AA58F44AF495F410321661E5451ACCE0365C74EE70A630E59A16CB48532A8A7DC7B2276120450820CDE94FB32DE747E643176FB02ED2BB06111E56627E790C304AB163AA0B424C280940459900F51B95FFFAEB244B31873A5C452508E354FD8C7B1C9DFCD73B79F9D1D5A76413CF25C1E378461F075990599F452E0221C0C8ACE25BF0227632C667D8930D12E5A136F8EE42E19677FC3A1ED91D88238527F4F5B8DDCA69A9E25B2AA84719F9D6550D57D8B2BF8B42C3B46D760694A15FB894155F75FAF61E67672A5BD8AC7C1A2F82812944558701181A8F7AD48E1C5E3048F1DEDF19BF5DDB322B0A5559616DABFFDABA2AF717EEA488379E75446524023563FB1CB34102715A63F1E2966C72EBD6A7C590174699BCF325C627970DFA7DB82D8FA9C39D82E412FA7827CD6CC04D23607985B97E5E5E368A23F25FC516BF771DFA1AF4CD65794F72FF61DEB1541001C08C8038E633800967F6AAE7F9CFED288921DB4A8CBF0BA1562B93016DCD051444F4E23817EB081E23309B044390E33F8D73AADC7ED244239B090740C30C73663170E0703DF06B886BBE4735BCA02E44E25382A18D6F18C0CF9CD452DA692C5958CFBA89F84E4BF5DBFDF2B3002318E08E8215BE0E5D770439BECB122A8F8A93CD93D3E8CEB6E89F83B224CF6D7F7526B1181E4D7781FED7A0177BAC4FD82FC229E6A8A61FD4A958A2D", - "k": "F9F4E46B44C781A74DC60E149C81047C89C75469123ABC787DEAB36EE769102C", - "m": "E2F0D46B6C4A43E94CF967EF2BAC7B68C6E0424A37DB52F2BC0C1695D1A66B67", - "reason": "no modification" - }, - { - "tcId": 18, - "deferred": false, - "ek": "FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091", - "dk": "F38BB156C26C61164521D1A109AA9B8108251877AE7E9878ACD67C3B497E40323A94D891BF700CA9E1A2219C7BFFEC710F575AA6A3BBCF9090FAAA82D2F0544F325A8B72A5B2F616CF87A9B698C7D5790974547EC5A8963D9649B598370861AB3C1628DB704368A256542B944BE03E28BAB87B6C28AB08ABFAA65827C5045871CB9F7911B81A0D577C1EFE3AB8FA5671A1565AEB286CE9C2175E60CFCDF809AC7384CE260D904C56CF6036AEB18A7B14B3B09C902337707BF739C365748B08BE40885DA99AB3F909C6C9D401ACE3C1816B2D2C8731BF46910A636D5882460C061DDC175290290B40B2AF1CC80CBD1C3BC669339CB95FD3D320A663C5937CC6D0C98D7D211D9CAB2D9D26764DD446893646569A14DE84A7BD7037DD4C644B633D4BC23BACE8308811BD0232A8737A011E98C2F82627BBE173640BC6A22AC957C5BBED4433F802908ECC8837152152C167C296C9254695523AA427A919D7942AC5952EC691697E0216F7A4C0A8C3A6D9B9CFBAC6A47EBB6C80C05BA64B2C94CA8A99F717B1E503C8185A3103A6A6C229D34753ABA4A2D1E9C977EAB176EA1B3882051ABC9C37ABC0D9F29F01753730C90E811391FB75B8EBDC3A9AC525BA3A02B54378BEF835EC51A824C63C5D8509A394183176004A2A0D0A565B439A909A5271D1A3C7CE3A9C09F809C1E2220D28AC38B52ED6F93D73D7A97779B61433CC709323EB8349D5902242861F99E261744A4EDC58073E676D1D84BA5C070A87240F6E82BD700B7AE7EA08E720815FE820A5629CBB498509AB53F359526977B09EC7A33C78CF3985BDDDCC86770106F834900E6A41622AB6A4C2B02F8A7AB54A53A0AC112180B5CA02452056A421F140C5B1BAF5EA0BA5B34B95B7CC71678F31E97C95056C1E4569B3359261A1AB1DF4749358468526CFC922C499C97888588EEF14BC31DB595B71742BB038CAC479B79B3083E77460C9CD860C1AB4E2595A99942E97A40CB0743E5403A9749B5DE2ADDB5A1A1A850353B213F4B6667A561A1E25266773577BD2367193A156DA92C9E72E036BA63D103BE6E0AAD5325F9F5A55E1D749FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091CF21077C6E3D08D75668EB9DE6088C89F26636404240ED78CF9683E58F178427D527C588E4CBF3A4A4F983B4DFEFB28FAAD96A659A16B403180DDC7E49391AE6", - "c": "34F172C9C056D82BD5DA9A1EBEF6241212452C78A2FB05DBC7C234F46847B3C3B8A1DD0B3316D4C96F84FF3F45B9A8E2BE97417A58946A83892A39C553C59B20164F64C37A3BEA9A14913A6F384AE5FE4B3E00861B903FDA24D740C29F086D1A517B24FB1A101F5855A9D2FA1237472595889F9826C6C5DC0F0FD14A359B2FC4A39A49BE7095E9CDD57D112BF4792433078CB93FF7A36BF5500B61E94545E1578C3817D81AC2E86414BE0339E26E9395E65957370762A5AD089FDB6C74960E7D6AAD7FBCA78833E69F0FCD60A581E836EC41CCDAB3659E422CD2EA42F95D86D79A5974DDF913E6E85061C29467BA1610B5C81E5A5E527F7B7BD1E2B1A21F64E00E11D7ADD5EDCD8898CA3CF5E497DB64DC68502D6183F583FB4BBF7826F8ED843F99634FD6E00DC4E9A87E0271777C7980FD2E72ED83B253B6F0BFE363413E9FEBCDD261ADED6822EBD9501A0C10EF825D4D20D6DAF36068AE03C9B8426939B81761689A6EC6019389B99BFD1DA02D3B0725FAD3DB4B9DF9FE5F291E91414B81B3E64680CF7DA55CFEF76C14D883C7A85299971F328402CFA1EF2064737AFECC27E4A49074C47F08DFFCD4E3AE86062BE0802F7F0FC1BA9C4791BEDEDB83BF432D9B81925C968467A42CDB2C7CF581C2B645933CBC5B03C9B285B6C559BB7985C0CDF7C242A908F0B78DE6DEEBB9BA848F8B3BBAD7A4663BBD26540660E1160C918EA19DF06C64395BE4A439F9963F4982A6EC981F0FD844F1C6FB5507B54618ED1491710ABE264339AB866D393C0FD953AC8B38AEE24AFFE1988F988982506E5D7CAACD8B5A78E13F68321C77F8AEF760B8D45CE5307CF6A3DF13B2D77C6901847E7E9715D1B84DD43CD7A806F8D0DF99B257F8F34C1F2E7891B226F54562FF3C48A05728020E768B863FBF5A2331CA967D55DC8F3468CE8BF5ED401D0E98159C5882720CC34F61FF9076256371377A179A25228AA5450C28AE27826491ECBF5174D70D94C5B6E4AF04853DD89003F7FBBBC241CE87B96AD6F6BB0C3407E448F2E75D2A040F7978B8FC717F69B3C1124FF46667234B2D7EE8946FE63BB18E19", - "k": "52C8EBA213E652AC3F3CDDACCC5586E3C26332A4BF5E57B69421E6DD45C5B873", - "m": "7B34969C65DB28996B6F9C440DE09074CC98DB4F08BD43E4CD948EE4ECFDE8CA", - "reason": "no modification" - }, - { - "tcId": 19, - "deferred": false, - "ek": "894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C92", - "dk": "62BA496B01A577F941C19004EACA6997F59F417945028925FFBBC684CA3BA6D1A1B9427387E7B7E84A1AD2E00418D471BFE304428AB3D0F1587411BA3971679FD42DDF418546B6681AC8AE63774E62F16460402A3A4730505A650D23B2E14534A1D00CF974A0BA035DA2E29A4A616F1E7832B3C37181967DDB5C37A18023EEB07B0E645FED3A34EF4544F336960CCA7B83A2139DD671C8369016A1BDFDB6980184B98E376A92701D36D07E6D0964ADEC327EFA08D0F84283A58895466A47EB084E042938450D5A2209962358A719B305844210971766C2A756D372B1228302601853C37B3F1AB45571C6F714528F223BB6F8A74F91BCD4840E61924872F7B7FF7469BE8935EB743BED787E4FD753D56494C44591B15990A4F9445856C7938CBD38D546CAD98179C03DB1973CB4BBC3DBD0AF79B28386240FC008357F346552F21ADB551219433E3950675F100E10345B942672205924A80607D6160BDE629EA14C012EC62817D28527A80BA5081F7867AD3516193E80B6EE726428F6409BC6B0A391A6DDA32839A9B6B9F23625DC1FE2CA6FA021BC1A44CE6DABB640E480CB0B5306E5A466BC4C16BB51CFA79AA5467753A5A47873A11B0C670F1C584C4AA39C91A76BC361F1DB598BA63FD3490517DA397F36C669686BC6122131E713AB8083C3F10869C80689B5141BD4BF1C92C22D9ACE8651AF5A236132428E2C2A064C977143528CF9233DBE4B8B913A69E8C34D97D5309A9B1EDC5915EBC42138C93005C2C4BF7C83E857379529A6FC124C4297568EDB7EE47C031308A26B8A17F3F0BA1D217142E300340945BE8B0A85035C5F926ACD21066B8248EFD730E842772996259BE076BDFB1398424360EB38DF029E9893A274E20A44A87CB4FA5E90A55099F96961AA5BB6E69913C7B9117697570A261A4A24C3862198D359114C767092824BB7B7684BCAB4B7017CA3172DE25C187B4728792A305C966BE64B7F2A8A22432136B864E75A14AFA433B7A1C617D80C3F20707124BB3B53CE17E605DAEA53A6677530305C56927D5F5C8493E33B1C37B4D796955CD4A7DC60C56A44703AAAA0894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C929492E80637971E303800ADF446B35E44F02C1B2936E5381CAAA9738F9F9F79B077A1D61917B642825666A5D08C5DCD13E5ADC0A5E248F28DA3A32BF1188864A4", - "c": "1077E1871719ACE56B2178A208B3F891C187DA970A51633C9996D278EB738375627AF9052866F15ADB21D21B8D0070A19A3024893FA32773D2E832DDC2480070FCDC03A61504857CC40E0E024AF04532E288F5F37F3877303263F4C66848ABD68E5D7FFBBA91B8BE624B63019D69088ACC1C37E79AFEDD5D1D2CD7721A0E5328AF2081C19417873E2B29794A2D2BAEAF67783B64BFD6E473B27E6B05EACC6079F4B8EE61C07FF13060DA3DC04B556307A1D6A7B896AB496CCC52C94897885E59061E70D12B4A9EB0B4C81F331CE3AE2B47B753CFD5CADF96E9C81EC90021F28F3FD33E2EA2EDB61B87D9B7894EFDDD968DE92A232A148AF1F0C31CA9419DE93ECDCB06055FCDAFBF655F2FEED26D3A6316BA259F7AC18A15893A95A635E364A1338C4EAF1F480B6E6DF424584F8DF7EF411902CA5A9A12FC440EC4E2E9CF0E1C3631EECE02A5134B793EC9C8EFFEA700CB8F6729C413AD1432EE4C8A92AE41D9FCA9D19D7871ED136EE3E0B8ADAAE428F0D4BCFCED8C107040D53C858DD2167E0415C98F46FB6327FE7D1B0359D8B3F3A491F4C708CB46064BF872D8830580D41AA8BA93E40570307A21554E5204284974F23287BD6A92D8A2C64A6F1687FBE7AEF7E224455F639BBE235F027DCF160D7249FF010F2BF6E1E358DA17314399C4B5129741E1171B0BAFF8E5BDD4A7BB8DA81F8D387BB32B8A3192136231C49D9A5B88BD1B6A30A9DA7B508893152FC5FCA58592F808E98914781D48D0CA7314A9A166F5154F9354D060BEFFDCCA00227F3BDAA59672820803FA83720D5BA5035B78E02E3ACA332DD0427CA7B2075D6770D8DE005947EC6E82389117D51C7186ECBA9F0BA3C81BF927AC6D75ACAA9826C612328A908E47684D7A97D49673261A7794EE63B9E99F378FDDE9580492FFFE99535CFC76C4D57CDAD1B5C51E751FFEFABE8772F6CCC1634808E2A0C9E09548AA41A267CE0086BB78B14163AFF59E45D603C495E3B1EBB4F2527A5B1DD4638A5DA9CF1429370E1A2F886EE35AC4287FDDC19297F7F96C223191698B35C4C78E1E4A46FFBD3B3CCE38FE63199BB8D46B1E", - "k": "F7AE95AAB26A52F3E8976BEEC50476D3B5FBD7ECF1A610054DC199A99497A1B9", - "m": "4F7798D88974637071717FCAD2C0ED5333945D51341FBA4BF1962A3915D986DA", - "reason": "no modification" - }, - { - "tcId": 20, - "deferred": false, - "ek": "42803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F70", - "dk": "DDBA891C987B8439ADA0114885B54CB210ADE141C92E3226F4B25E1303B93A68092FC95B5FD9BB80805D8EB2869AE6320A90458E4432E6510ABC3C478C291B63F02E476235390C0162468145234744C6208D642DE2E56031A95B83843B7FBC2E20A83AE5229A4ADA7DEF77864B975D475132CFE0C94BCA0762E369ACD52BC8C1135BACC67083819EC229D8962E989C1FF548A127F86E17C60C8695B592D1C9C3689EC3A9096970931BEC56E99499FB3AA982F663F67CA547115D320ACFECE132B3CA9CD5D223EF20B39F7B78E1526E82C816436BCB6FA822C105319AEB9D2B5450129ABD8D1971A043AC7BFB129B5504F35BCB13DA4E1700CB215A3B7ED6512F558D62EC83DAB765D0816B4D085C09E0035E830996EBAE1475B86F39B23613BE9E403A12A7ACE2DCA602722C593043301A35B4DA84A3BC1D53107F3C1C6260323739C27CE09566882BBE3B31C86CF8381EEB10D86167F300A6E510A70E0A881F282FD8C4A1DCE069F417753F069EDFE46A91837C2FA57D737B425B7A4D0544B6DA399368926296C98F7C5C2532374B95C03F3EE15E526B98E2C48EEB3718DCE2C9FB760147434D6FD1BF040AA5A329867DE87094BABEFA563759E49E1A94A737D6488E2280DE5BC827A90A39930BB78CA70D33A476C65CC9F6CB2F8BBB7024652E43212821568288533A51627F8765E1B64AACB86F08333A428AAD4902518DCC3F77563BAD858CA32515BFA8992A5304D8B69E5A6C79E40B7D361B70C2762BC359CB08401AF7967D8C3186EA826A3C4C0748F67E471B92D3216D39091F26EC477051CCACB27696D9AB918904D75743A709CDD09460AC04863B5412E6E935CCE23B3F6217FBF2CEAA6CC37B8C2B6719C4661510A88BBB74220622B589EBA490309A0FC8E7998739CF6205883BC64B86A317A3E1A86F0C65348C2D62A741E80A8AC416467133581BAB2EAA7B5B88025F4711914ED6996DA29E429B5A03C358192C049AD17E6280CCC231AC0C075E3396AD9258AEFAF757FA23259CEC41F5E7CD7AF7B12DD8219AAA5272E7CC30C240B2E2A7B92CBEC265149EAC2A42E3B92C2C0242803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F700F0ED35733D6D2807A9D1358FDEA6AAB613409738917AEA1C9F4D0CBAC25D0298A10A703C91D253B506276C2E15E683FF297EE8713F9AA8F400F73AFB9DBB392", - "c": "4391421C7C0C25DA903B2A944EC32FAEC0E88682FB3146AA621952E3219016F2FFCF97EBB7C7D6EB95891350EE783147BD5B0B1B089743DFEB15C4D81D6BA42B119A7765A73F19EBB39C565D2564EDFF9D57B2C48E8F42DC891315198D9EB17A9C5B5A9FCC169EA8695D1FCB82A96F79BB5432D47BB06106A9AC0D0AC91C3A23D28FFC19971041716D6688759DA314D6DFD40D087489E85780D7BA66D9D526E70038A5DEDFE6576DD240E7C3E3A629606632B71CA08CDC9206F593B51B80190364FDE88448EF5F110E650DE902C27E48BB82E9F2A007610B671AE048F29119FA07A98C86A46174598E0DFD6BD21C8D59C95408600D5181D600EF0BC302ACDF00F99E6D391257432D314696E4E12F2FEE1334574773F28EFFD813F70E9327D83FC239D04315B1F9C95C4C214B71946A733503064F3171C17DCD219DAD8BAF21A31EC0F9817B6A8B3C4B73C43B70357DBC771955F797F8BA28B56F31032376044F3BB33EBCAAE4AF9A93E2584A142008AE3A9CF75ADC2B3AED29ABCB8D03B28DA272AA5E4A695F9E6CFED430EFF445881F9208913A2E0CD61FDB5BA029D3228AB334EE9CBFC730AF95161ECDD1852E52C41291E0CF8ADE3790DA710C5307B5EFFF0E528A9FE2F6C2027E52501244A3E29CBA29E6AD9447AB43F5B4FCFFF9F3A8E7AC090CF1C6D2BC85B39DE79153E7BC36EF2D37FFC98D9BB21D37AD41E457D5D4E36E7C128DEC48422DB0E26D3E76823687F39D43ACDA2F77531612D449295D1740EFC6AD532C233F2CE6A14121C62171DF4B7166355E1F1E939FD597B3038F54AA056BDEEDB25026998E1D0C047C78D648C2D3373782E1862C8BC0D9BCDA9FBBEAAACD80104122091B3AEA9EB113533C75F1C2FDBA188A08DC549D229F408B592CFDF438B61E8321A367F6956CCA81F0E13DFC3CBD1DC9FC1504307A3F14843B4B3E09571E26FF61F69F2775BEEBBEDB5059A3333D5BFD5A7DECCE8FBD89E50B8CB5C52779A9B9CB19866560DB4EE457E3D18991A561268869E47DAA00C59445ECC7B683171CE81E58CD4FEFFD93E31D5EFAE77CCCECFC995A16DC190F59F91A", - "k": "5418AE44ED01EC65F14D5CDB12AB6004B35744E935AC8A9C3D8D607F946BB706", - "m": "E20AC1D70FA6A2C8A286EF0E3665C79668A5E6AE80197BBF13A0D0EF553ACF1F", - "reason": "no modification" - }, - { - "tcId": 21, - "deferred": false, - "ek": "39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF1671", - "dk": "F5A19CCA8A702ECA16162166BE451187A9300AB182DEF2987683383B3861ADC83BFFB41FCED714706AB26B1751B53B09282500F3320776A4C75F22C7710636C21B008988203599BCE9D53EA8E044E9F37720D2C1E34101186B896FC590A6593AC6B2131A093185C82D61D58405780D16927BF7514B9814BA5CB42B4AE66A37C55E06044CC0CAC774B01CEC02554CC40FE55326A612AE1DC76D7BD6418FD01C7ED25A15AC16F5B8129265C54B0065758390EAEA0F69B212D33B94A4854E912172BEF1AED684AEAF1560DB303AB1FA0146C715EEA9950D317A87953730B32886C164FD7845DDF6B3894A7460509DD9122B12A3938EC40649537EF21592BAB202500331ECC1A39C5AC2D63A1139AC93E18886F68189078C7090593584D59C50D12A2B5CC08EC6A9FD33BC3C2391A7C3BB4FC51F6A536D962C6AB3EA7978D57290719A80A8926A812CD034422CB0CB49416ABE61B03B041E88882059624843679AB699ABEC6988D918710F5B3FDB188B6031C7FEA47C292A04E05CA2961BA4263C298A06956631705254AAB817C46903B537328B6233B06E9530F0AAB1F3F9C16BC6276B746DC0F44FD9A476CBF23DFD27C45B4B56F8B5BF9AE0092028CE72819DA1C6A5FA48942CFC0A24B04ADE63B33642B5B112CECD370C3F3930FF6305B1B0A1D2C490DFF73706A8AC5D34B21CD8AB8D3111559B915634430D9C78460961F805214DD2434411C1C28C769DFAA9FF19C3E240638181B5C83422E5431028420F74A707914354881938BA842228D2C19440CA99DA68AF9372B8AC6D68A34CC75832C41B1406C66EFD1161E8D0B42CD27EFB18A162006375D40E13E24FAA32489DD91E0DB8A32F11A4BB9139E0123C5DB00D5CB1BD4617809CF3214C581276312BA0819699841C6072128A8C3046656AE6815B78F61AB3890FD7E2BAE1A2A37CB27D3CFC3E4EAA84F65350E5DB36DF499FBA17839192901FA7570EC72381A86581B69760A277A8E63EE3C16D0FC45EEDF4270EEC32733B6D0DA8BFC0539D64136E4E260725191B78831F37F942018946C5113807F9161BB89F6A168C6CE2991DEA0F39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF16717815E832D512DB0C38A08C78F9C7D3CD3010367902146A12A335AD3148A3C8BBDBEC6DE5ABF972F91D59054FDF0B3F927DDD6EC3477C162C2294048A4E6C3FE2", - "c": "9CA67EEE0B5C186A08356C38E33B9E7317637F3CDE3EE9D6E04C1208F9B9CF63386553425BD51F35E523180B29E3DDB8161F1FC632528A5D5AF0418F5C32B767106A774E5D97047B0A49F6C9FE2ACD3C12A6D45B49BAB8A4C95958507BDEEE88B4659373F8A1D605744F5B65AD2E5A5EA081AD2C55670793CB78691B2BF2CFBA1FD1BD6AD4D9E87FBB64A52CADAB26B4D66684AB2FCAE330173F864FBC3B6461ED1B4EF1BB054D59F2CE2B8C62CA06808B99AA29AB2BC941026494B3233FB5AC8B5E200DE2F2F40DB93C0F567348033C1CBF08D491F3CDF59835791BF4751B4A22AB312A7A9C6FAA6B3FD5021F10F8F3D5C0CCC40483CA28322CB75A80E0DA05BE5D848F43CB3473864B26591C27DAC580D354A9D2DB35C9BFF76B42DA9675A2CD63075F33C2A1D1626992D5ACFAB3E7DAFB8F017F54757C26074DBFD523F18C7757ADDB23476528D540A96EC669E6BF0C1DDA200BABEDB965511546F2C96024D344EF0E17A4481ABFB5C2C07C8D23757321BFC9A58529D5B71428D08A056083E5A027BB059E2813AA9A015BDF7C941DDA306B3C54A08D1613109716F11FCA932EC55A4D31806BE21C47CB1B10A88587276C57CF389CA28AD40EACEEC94A57A5361007B5A85F0A44E5B5E8E354B2EC791F42BDD1830CACF5722788A48837AAD2A2DB34E33B56F9C986DA6E9C485FA96487C1AB608CE903B6D335C47B1ECB129D39194B99DD369A122C6A16948F689C94C8A54D6CB4C5E39D073570460BBE04AEDDB0D0432B69E1724DD61A8941B9C2D26B49ABE6CB87FA1D093CD6DE08033C77C11808B0315D8B347E7EBA33537F99F64250C65690F8AC19951679C580CBE6E36A7FF0A624FADFC84B220FF5EB7B9BA306B4A03DCC305669C1DF2210FE76024E21904E1950446EC85FD5A04580CBD9843D5BE7F90F82A901BDFEED370AB83D416F92C58B5CF143D4306C9FDF43FEE62B6D1A0248C2B6F305331F4159382D92AC6388614EC84729450B85B7DDCCBFF9A97403B186DA21480DFD1DDA6499600C326B3A813AE123F8175D2AFCBCD5A519BF706CFCDDD6F36A2DEE5FC3F34263D8CC", - "k": "89D60F46DC4A11DD81C284E97631F08DE239C06B157529A15BF9B53C9EFBF9DE", - "m": "AC25F29AF8D8A2DBD359600C8A500144D6C0236D729DA016C3F116CBBF621002", - "reason": "no modification" - }, - { - "tcId": 22, - "deferred": false, - "ek": "0AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6", - "dk": "ECC90EA4A07BB0F318F976967D17B40206A6D06C00FC1CA6AF95AA38712DB92093E8E94CFF6450BE071127ACB7AF76A5FE8A71FB511488E57DBEE396D65807A5D0A86BAB9DFAF69DF38A362E62ACE8F7AE7CC638931716F2411ECCB621CDF181C4677D66793AA969BBEAE71211991DAF14968C95754B2BAFC6779BA5E4697094B28C1340276322527C7F259B4F39CA48AB2AAD90B2959BF1B12F983C0B3B9014A04392902C5C47A92987ADFBC654BB87C4DE63AAC4B2C45A3BC37972A607F491C0D891FD7BB9FC96032850BD110A2B09EACC134B9E99B5A09BB11D9D5163B880CBD73817085C68E571AAB45439A79117F7DA5E81735808F97A42249728A0B63834001D1C008AABAFD72A068309BE74D49C7BEB0EA9251BE6C1C7323B84402C725C212D361BBA03385FB7641AB1D74B39690DD1448B6B01A85F82A7F43C22B0E3962214246133750D23CFD1776FF64B4D1FE17B8257670379320FAA81447395D7069A74254156E900C9278B9789629EB33CE7C0C867992596966ED9875579CC2A525BAD71E920AB5B0A69E69995152BABEB1D4272A04F3283D988826AD0AB24E24C0B505EA5AA02EAD063D7B587603383148521005034E6162106E29A7EC3926EEC024DAB8AA0A5768C7142EF56A5AF17829E505224A2C3F8526DAB6A76E714766D2450D60A68D23AA4FA392A2903C276A965FD1A15693644515A336F6115CB050709855E95035564157308F3062FA03B0DE2C00269BD8D414C6A574D485061A6A28245375513009F205CC1402694BE76338D0795849AB011205E880537E0696E6F4636CBD9ACE8E279A8015D57108BE0A638B3D8516487BF763257C00A6175407433A204C099BBA4972EDE1763EA5889FBFC25742CB66B9360A6A5661DE7BD4DEC856E55A5BD354E01DC6843B4C306B957E72CA528188403E324AC69AF09820C74E6A389881CE882B86517BCFA881435BC8817A1489250A35EA19B80C62CCE52A0A6935A89E47F658041BC93B2B979A7DE815D97D15E5B55310568BBDCE78C6437C848D479E65C60B75391FEE94683BBC379EB83A545AD98A070F281837E24090AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6CD2DB91B660C482E6C8B2AAB016B0354DC138DC2BF97D5F960E1D8CC51F09806BF737AC0198871CA09B8C1E4928C4F51B47816A69F4174A4BC9A274F2E10D051", - "c": "398189254F2C82F3B9F6826C377BE31222C4E199954CE883CD44E135BE51E8B1A767969BAAC6FB3DFBF59BF38F2A005798D45B1032FF660C37E1AB24E629D84F79B0673E44D12359CD6632BF4AFDB2ECDB2A1BC960E7B7E12ED89116AC5423ADE1AF5CB43FFD173D2878F11BFF604E8D2B59FF847B570F52D5A5048D16038FFD3A6A86F00513C8394434DB5D87019D6CC46738678A45577698DA6E13B466504DCAE736EB36C83369ABC434B8296C3D9BAC5C46C700F5D0CB0EA37A64017E0DCD82A1301649ADBB8339E7F7C0D6CC42B1EF2690F769BBBFFD50AC546447858CD1B46A31E43CD1133691C4600D745BE6BAFD4E9A4B08E4147DEF63E52516FDC2AAD98A77011876DB533374A85805AAE72B25F0A1B30331750914E79570ADEC5D20B391EEED8C235D295C5C7B3A6FC9C6F8D46EF0F2288785BDB4A99BA461BF2EEE99E58BF46A34989DD128062B511A4724FA7A528CAD251A3D4144E0CC39B89DB093A07FF65204B3A44FD20079ADFE17AAE7AC3306C79495338B73D711C11ECD0BF5BACA4F51BCC6A8CD54EE1D339C146241344433B91436E54E17B7999C3101F4FAC0C6D765407A8F7357DB41C43E1E899C5A786ABA6FA1CF216D8C795A98A9A4E6F4FCB6BD38D82A4AE26E556D672504CB8C33ED921B6CE69FF9B7E1F29FEDB7926956278C1010375360E9F149CDEDC4F44C69D18940E85EFDB467C6D7979549882B94BA635694EC91AB5D3459F244DF94863C180BC623C6FCD5297A1797A272F6CCE06EFCDC1F24E6FEEF30C30D50605D7D7FEB2886854281F573B0ECA200739B307706ACB22B05A6755C50FDD9DDED42442990E9F34778B6615DB04A3F39EE3959C0407AEAB90B580ECEC910836C6E2C30561B056BBCF04EB576284314135CA48630155915195B36039B52CD4B546882F536E2B71E5E952AD560059AFA6DEB52305DC8923FCB52E5C8031596E9596BCFF1F0D05CE5106969532F040BCEF32A7FFAEED70A12050FB21835E3BBEF84C548830C9CDEAC86BC6D3AFACDA53CCA62ACC28ACF22089C70014469D22E967C81D3D7B8BD77F50CA03930B7099801CECB", - "k": "66D121707FFB368BC5D4C73FD24DC2DFB742419B203DED2B3E157EE56044C128", - "m": "7114A4B4195826CFF174FCB75336B25D4D1BF2224D585014CBADB0C4CFBF7729", - "reason": "no modification" - }, - { - "tcId": 23, - "deferred": false, - "ek": "F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7AC", - "dk": "9A6264C4F2200B6775B81585D2665C5FB3711C7CA596C23FA6883AF47C8FF44158278A7437A32488F5C2AAA9A763674ABD01056A767E1CC48D327B0639E85148C8A60F97AC7EB55BDDF389057C72EAB6419640C4EC7174E420BBEAC4C4B9B8A1A726CAA6A27D226529245A6BE1496303395ADD725CCFB43FAA37206011931852B2E117AA93CC99EBECA070B6B9F5C28B60A3469A6497423A638D6C03E711AE1B64CF613824957973F0E30253B355545206585113A4921DBC32336E750CB940C574F7740E145CDD41C6FB1AB4C7186A3BE12026F1CDA6D80A15916CEB8C78A95A094B330C83111F6EB50A6EC17129363F6684443C09716D129ECF0A097DAA50CB021014228E77F6826350C03F16388BFB7578DB3B368591397650ABF39C947736D2D49E1D4625A9DC3CFF2B14520282FE9AC9E92C9C72745DFD1550474AB13510BB0709A69BFBBC7CB2BB1C4BADB45709F093AA24D09CE75BC8DAC99FF5243E98872233E0B51BB87C7785B5BF558DB3CC5CBEDA8D710039D1E260C878836E4A493EF67534F4C269D090F5F0906BE7117F6B848AA72187DB8DDBB62728143A4F569D31439D72D7085C299CD2F77ACB2C8D8C7C33D4860BD9C5AAE7821D1D67BA3FB81FAC8AB513F035816B019B5C464DCA4A289C1E503654E0A8160D1C37174C565EB876644A6EE3FA6107369A08D27EEA331614406ABA1B7EBD91AF36ABB2A7F9870272CEB7EA69DC0431CA1960A8352BDEB4526E729F49AB6428C15C00EC30D6A9757A953AC4D51063973BC954BB30CA1A37C57B1E402C9E7AA653679F88B6CA0BEA8EBF992F7EB422E90697E6EBB1AD72C754130088759E95091AD4DA61B5350138D9387E5744D2B8049457A0E07265A42961ECFA043498ADD3FA517518C8FD8C0C16A059B4E02BBCA459E3FCABC68C0E656C2AADF50DEC8624E14AB964174393F0A152952069160F1A3724234316C290C398F4AE3F7C3D8720464A4125E3F831B3ACAC315B2DF6F58160F98AFEBCBBDC85702584442DDC9306E66BF234B5017B9AD9B51D95C7AB7431428E36C31F8288DB21B8771B12784866A4189FFDA8B7F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7ACCBD82243C1021E9F731F11A6853EABBA8F4E69636C67C2FA6A4718AA4B2BEBB16CC4395DB6F56E75AEC04D1DDE60A119BD846E85AFA528388FF76A185EF98201", - "c": "6DB2BA6A74409C3771A865799F60210A98E0FC38795DE8978FFCF49CDCF97CD68942C89386E5EEBC6273E1C61223BD2BBBE096B43A45E9585076D2A522B2D14FB24A60164B5D49BD4C648CEA83059D12344E32AE6807AC1BF67C7CEEB08C23AC7A0E379FBE383C0986C3B93AD367CEBEE306082B1B26CE6C47EF6F1ECE2CF6EBF836AB453D1A574E7931E1E1DCDF709DED62B534D84BEA05BDB0C6EE0FED3A8465EC43AE00766E4BE8FFA01AFFE5B40165140D1723F3456FE95F62FB4E299295E417F1EA19DF70E45B17FF5951F2D68C87D16FF823FFD6DB683C0E0D89280BFCB6E0E273705230CB70BE7E1890C461A534DCC73C94A2430190E6380A0F48919D7349327E0514F53D4E10677C8FAF771590C9A6E4F8F5443527275962686BACDA101701B399D6BB2911460F84B636C6B1FF92A5D3141CD28A00B1E2484D9A708A1B2BE85C4FBDEF8939634D3DD1B9C9AFF193D9D97850B92880AC8E859C0328551BE21CEB3D553339A5FE9D450F08087465F333FFECE8472AD6C0DD4E41F1C2189178952DEE12A444E1346F744A3A315FF524F41339A0395F65FD97DB4211106118CBCC438BE76087E7E04F47F8C999A8AF661D652FB4EAABC82DC3718739C5D5106C3A85CAB0EC34FB53913000DACE82573FC1682BCE19BF8816B075DDBC871D8DECF5D2350FBB1392A54E94222C9A038AFFEC64ECA6AE2B963D5D45E82DA816B893B4327E0A8A7F11C5D4A2E153F3B4FB1226F707DFA65409439B152B65E38256D8288DE3339BCE574747E5AB26F5B0B114B29A3503DA863D32E3193434ABC77F35807386EAFB37959E9F18C8A0FE654062ED0A589B71C6539A1251B00E816DAAC71F63D35CA189893E0A95D9205A2FE5DA7CD9408EFA51EC442B6EDD8DC1666BE3B222A7429D76A1B70F39A291948D47ACBD8CE0D581F6A8984407377F0CF3A2D7C23A62351B8151AC0FDCB7CF5C3458CE9F69F5DB1E57EE177B46AD28306E1701F91C8BA0864BF447C0E5CB39FFF907EA79B92E86672CE8CB4CC3639FD95EFEC48EB59F855AEE1417ED920BFDA282EC36A2035FD0D7FC64F1B74BB300AA05", - "k": "5E95F007FFA0F4C822238DE22203E3ECCF50020594E1A8D993E8026FE9039159", - "m": "C78E7B1E5EE8F20EF0B67089306E1ABAFD15760B2DD2D7A59D2C00D496FA0FE0", - "reason": "no modification" - }, - { - "tcId": 24, - "deferred": false, - "ek": "F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF401", - "dk": "DA28574C93C4660286CCC27A47B8437391BE1A3774E46106D689A28AAB03C3BC86FD066384FCB69B51840B1647730A63B7A44D338C7DCAACC24DDA232615962E027E4F5A6638A222EF484826EBAEB557801EC3C0E597BC9653863C534A5232024DBB234F6014E940346B27CB391B87DB64CDF6C642FE87C534D554212C4A8B531AF5F13F1BF1B49E837A2080908C802567C23C7FC1C4274152C8E3A11AC92D9C71639590007C2175E3396339A55F9181AB21525E1EF64EF64B08C3739EF003A6312A439D18AADB1673665B3E154241708C88551941EE9C6DD1126E3C6294026476586907AEBA78A9D04F3E885EBE6B1413CB01BE3383A3DB7626500D8A95C076A7CA5F0CCB7CF785C6939C7E67A16E015583433739D588C0420D57F4719539722B3B4A1FC8A89F93C5766280C2DB4BE16296DB8236A4F7AD2F963A24E9CBF10659E4F7332EBC549471CF84A0A7A17A3942947E4C807C11B37F2144431955C9C4BCC6A9D87DE013408D6C735F9C150F51290254C70D1573838271039661D9860805148B8721A0D73C6589A49DB56C5BC524418DB313972A0277773EFE82139F800501ACA4295A2E95933D0C97A38B27814775C951C0585413CCD8F2197BA169A599A0F8429279584D38D569FF4B3F8B8B40D2C11DFFF524E490490CA21E7312A5B4423D6AA46907B9C1FF46173F3A0C257A80A8E9601C5C4551EC28F52433B62A1391A87EFC466C2AD564EA4B84D8A50128533EA32663A0969CA22A4E34622F1EC1659A2884D76267F904A7D1BBACE0FCCF8340B1680A3FFCB1A53B3213E59C5A7245467CFBC5C1C27910E97F455B8B4B73C04DB36DDE46C063F9AF178853DE82A83C2AA453286B71E14BF6372D4FF46EDD207962079C1E46CDDBF5C40135765465AEA5B5A2BD9059C32A530A8816A63126651AA0A446AA6EA30FC6B09E0F6350EE4C4BD2A750020083B1F60AF0B13702DB7B69693D2F00A06710B7C59710FB813C24E27767E28A1422B266D18A29664B6CF1A179735640EACD3C0A8FFBBB9498D57C4F399DF0F638537A6815024C04D70DF7378DA0910590E58F59977B858465F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF40142C07F795BB51073526A3ACAC38565B3001A89053744886DEBA29F978A97E55A5E31EBD9243C452668809BE6A57BD4E87955928132F1C0AE88233769F141957F", - "c": "B098B60E7D24AFD22B6D949017D7EB64F5B22E09486CDABBF5C968A552E570814AA7EE78C4812AE1F9A62DFEE18AE28C460FAF64B34DF838C868D9F68605E6B174DB175DB8703BB461228725743526B4746CF3196BF15980B6D765D0C70E0435D06EB99DE367CCDBA94ED3062E793DA70678CF40581F1510A715971231429E4CBB97BB68442147ABCD0604D77D1B086F224039B81289C4BB649427BF1509A72FC94F5D239D45DEF93CB926E031049BCAC7E75EEC5689D731EA0A619BB91EDE099252EC631FECA51583C80EA01271310DEB2B075080D7E57141536CE566CC42BDA1EE5D57783C47460597D6919E6993FD57E0C35C612182C6EF8F6924273E1749C7BF6963F37C5A0CE92473A69487A5E40E29339920376F369BCDE9C3CD87A1FBC5E204CAF004372C5839BB725DFD16ED3311898CA15F05BFCD53429074679D0A40FFC162409B339ADF37877343F18C6658ACC96A451940FC09CB7441E0C8A6D309C2223D69095CD8409AF38557836AB5F1DED6B0CB8B3EC30E4C18C15FE1B764A7B932DC3831E91BB5DC62E50A880E1E1F6FA94EA688994E682E6EB28958367456BEFBF61D4CE5B84F64CE980AA2D6AEB4685188E1EA1844292912E5E00D89CA39B11C326BFB076688FB2F03E6BF6EBE8CDD381B5A3776771BA80D88C2625B357815925235B111AA823980512103ED6C861ACC918FC9EA208F08D0923E2CE6A168B13597D91C2F05A9FE7649BB37018922C700C90C5E467DC58E4E51EF87FBEEFBCC8D64E9C4DCA60C4F32B250FD19A0DC8D9159FC936082175C52E0A73953A0E9B8A1000C9F87F0A6E49D271F053D8549FD1A014BEBE89405A54A3F77DE7CB136BEA832E94E18B8BABE44F11CA6E798B1827AF292235A896D865CB3CECD98F8F6AED3952CB33C85F6D1156E1B16481DBB8D74158A1F84A403764BB120F4853D17167E176CFEF7787826DD9A1281E269A7418CB87D80485FDB0D1B73C0DBAC76F5E07FEED9511090B303B4785A72BF77A9445C512703E1942F2E72BDED8508DD4C1B5D4C21F76D0B535ED7915B8AB709521F85814F1AE3F0FF3F4357DCC94216", - "k": "759E8EB2831DCCEE0EADA89C237570E11A9419694AD1CF4474892DFC6877AB16", - "m": "D23A22F6DE6C0F3C28F5A7A8E54581BDB312A56BC90CF3B22A5BB39C9ABF420E", - "reason": "no modification" - }, - { - "tcId": 25, - "deferred": false, - "ek": "305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA", - "dk": "CB402B0AB79835868924D80496343B0AC32FD1A13D7B39BF75893DE4529754B68219C58ACFDAA4CD964316AB05C170249A763416DA3DB9449BF32B0D41F7B53C406C62C24C33E2820A6C818B93992A1CAF55F155370BB18FA415DBC45977A335A0D03C0C9757FD26A4CC00980A2C35D699B96838525867A8A17719A109BA6FDAC6D187671F065BA38255D2824FDF5C66D0065858942982EB5C9839181170C633D76D123918D30A23A3A8884B7073C1E2C914FC0117F190C6C85DD327886A8CAAF01A6F9DD537E7797DE0D906DF15CB305765AE6BC724B7B911D293CF8AB7A9C9119D4B09A1794D388347A492CEB7C0664427320537B6CBA990F76581856A2AB6534AAC19B3015132EDB1023F68BD4A935C293168DFDB96C49A6C40B0C86592CFCFF74F59781C6264528A63653649A021568E71290EF4BB3FA445A925682CC04A161549696F3A984BE61B3CA46D3615983F50987E049A5DD1B0BC885F44F0AAE5E836E468789BEB6F7DB10F2AE07C479607AD156C96E49A790078D13C8205B366974AA32A696962434CB972BB78724123E33396463E83A30BD4265CAB598BCC61895D6BC4443C8D3B1B5D27B607599707E3C0454BC2A84BB53FDE1678FE905A0EC7A9458C2540E7741A10AA079802BAA2BBE90C03C3C80EA6178989CC6A3B9488551252B6828B9138B8C259A38DF9412ABCC01A4183BFD19545216E0FC1532119AF0019603F3C247D408ADBC9215E3614832BCEDA531F63A0729552B2EC99B120B8722275440B0C764E7A6BF0A10E73ABC0098761C45068E7E1549611822ED923131A91DA17B523309A1B59525CE427359B6BF54250B282C56985519C151FBD788F9D4737D8EC1968E79B0BB8CFC9E012C26AA66DA8284EAA3E9770B1D0D760A68254D8A111CD722362BA6E4969422B21BBC41838B3171046E87277CC400120C293417E411673373B98303BC533540192E256BAC46E57BB96F6D906FE291FBD843899A3212A894709349C3A22084A3CC4DE7B86CFF66B841583991747C36CAD49667AE4EC295D76765B401B78E59B68B0B0208A6D12FB3720BC9B77FCC3E56287305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA320C1B0462C9C95B0367A4A13BEE7F2574BFBDF01921E7C2BA5AD3D6954E8334C39524D35D19623E3F4B21EA8BFFAFE599515D49A90278F7529215781B9A9F82", - "c": "BC00B2A45132B099533C3441157FE9E260F7B47CFA31730421FC913920B72A7AF375DAA469C22A17E8A4EBACB8ACB89D1DC841028190538BCACF028B7709D14E38DE97A99004F54B8D84A1372C250185895486C5426E6AD1D4C42F69D4902DF59A2ECEF40979E6C240EBA46FC0ED0788CD75B1B6BA6F382950BBA1C2A0F779B3100C0A26639A9733F3B912FB1CAD4DDD118D4AE13198204FAE7EE59277315662B9CBC9EFBC1D756127525B4996CFDCDF9B7DF7E9A2E71B9BA72650370DBF75A2F39D0004CA6F7FA59C8951FAA76091362C8938D5EC82E6EDAA06BFDA4852DB9F11EAB5C659D21777AD6365AFC524FD0090551535A6DD2EBB8E5F8A2D1C1DDA87655BC1038C6501610291382969EF3CA1730947DEBFCD5B95B68D63750E77A59CCBB328D57347824D6FF2F09B0152F0B404DD023A6F2DF7E61030BAEDC765500ED03A81237FEEBCC3022403D17EF9398296B0AF4747209E0CFE925DCD71B70DD71DFD96181CA30129EC97A21C0D18E3B6315CDA1E88DCBCDDD1912A4947E6E1BAE6250CBDD931CA1B7D146041E973AC0139FF6A23107D44E61293D1AC9E249B5F4E3CF69E55361440DDF9B2558EC793F8968CC09716CD9DEC2BAE26A0A5587BE97CEE4B9CBD3506794559C2D7D3550011CA37424CCBDA8BF479098A5E76031D729EDE3B67C6E5A0A2AF11627C1AAFD3C16F548C4841AD9307096AE806210CC0173429C9699F5D95162B9B56D7199D4809A294579905E2C5D3BE1F890F65727F92D97CEF4915724FE3CEBF00E3A01336FAC1C86ADF6A8ED654256DEAC45464E537EAB98A918C69CC6AD91A53E69158DBD71A18A83DA3EACD67A65F7DAB277E82B5F9535E61448A1AEE1F52FAD989E14332EFFE97D3309CC2BD58E45AFB5A7056C20AEAF1E4D5A0EF5B0C1507923CAF7937657109A83A437EF10CC035BDF983F88FA04EE6C338346FABEAD3413DF0071F960AEB121FECDE71BEF8800142CC159F9A6EB729205D3A980F11B5960699EB3A9394237B96E58F141058F8057A4D15895D4F77C49BBC021B452FFBACFF2C74279EA83D0C57EA4CE5D7952314206A3FABC3", - "k": "2239EC88DA575EBB9329448904221C63CDF517DBE3029713E3840CF4C54819E3", - "m": "C0A5ECA859643D0134F2231C8F3764044B7E6073C92C9CDF71BD64FBC59ADDB9", - "reason": "no modification" - } - ] - }, - { - "tgId": 2, - "testType": "AFT", - "parameterSet": "ML-KEM-768", - "function": "encapsulation", - "tests": [ - { - "tcId": 26, - "deferred": false, - "ek": "89D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C4", - "dk": "B09125AFB3CFB5295581373AB6885284D9706318280D223EDC987FD14410DBE82E6AC89ADFAB70E67CA4B1C641AD037FD8C47870F159EC79CDCD52605B9890499BB6DBD8347F342C61436B642C0DDF4617DB06198B8285DCE4C09D9775A2F41C8CD18AF8E75F57D4127DF94D901AC83BACBD584CC50C43750F49B357F59350875C9B475480A8AAA168592DDB158614A639813566D205368C6C39F0413CA3230DF60D44008282B682AC66B76C3C95F00B2A555035529C86EF3905B4A3968FEA7802B6C5EECB08E8F0C42D7AB7CD21A62FB136412A1840B52C99970CCF51892F73497C3775BE2189F7FC25E7C74D81FC217683292AA4866DDB04469855323A0810F0893DE5C7F94A9C0B5337DB83C44891B2E694695B76575032BF51761682958BD4F97BE9A355B4A85BB6858B7E5A5EF653AB781056AF9187D811C3A8936E5706503DB57062410BCC9421F1AB867A657856C411C4E025ECB3C387729AE8E112F330B988E22F47C35C280750D21B107687AF7B329EF3CB5289F06FB7D44548391E97BA6DD499B5907C54958413D92AA99D5646CF47A8F48CB70A07AD056B4EEFE6C8C46645F7028A32410558638C48E83AC1570160C3833BF64052F5B7DF4364D3E0B24E790AA7C98CEE0441E6731D9DE22D156C61E1C740397672EF54724F01B9D49923AA321F86B98823F21360138392B90C69434635275F9BFBB9B8A99E8E1B7F4EC25F75DBCE33C13F750170BD6722EFE496E7463E16AAA5867B869A96AD41B22BD2556C924596FD778D79A102F6E46D8EB18FEFAC8DB19993E5414AC816705286892492C8C9E852D6145DFF0C10E4A6703A459E7E732A6DFA2766A622B0622BFEDB8F41C125F61B2EC264853B9CCC165979F6A263BEB148905AAC7618A70E829E23F28696F92EF6FA07C102CDBDB1288BA5CFF3A81ABBA15974535FE3106A80068F14E98964572350A7112B1601C196710C096CCF164FBCE1AABAC9C5B9535070E61AB8068D611CA765FABB6412607DAB30C4FC6AD073731FDC4C48B88E267C47B439AD2560C30561815CEB1F52C896489944BBBAB52B1B1D1680A1057964DAFA600C93A39A447DDBB0ADF911AFE3E823D8ACC7CC04659F625F2C1837BB175282542CD22601F621581AB5A6C0384E087CCD32A5380B522FDD3A4202B5B41C85CAFF2903B2DC2645703D9BC711FBB404C0C0376187AC588AAF5718522D2273A9408DABCBC9701698D2DA172AA6267A4C9693A24011C2265A2B6DC8E96304A98DDC5319A3140C399A08412C20F48537870BB84C32A094457895511FF7EC421DE01A64B78534653F78327441B90CD115939DFAAFA95B40D0A63D62D12EB5C9096018CC83871E44E6CD0BE26D16B7B5A209B8E6471D2954ADF9FABD0153707C9CAA2BCC38DED841C791A0EB597EEEE2C518D926EDB28AB53CAA5B7746466931B0AC9150688BF37049C1F82BCF648332434CD0A92FD2C958353A26CB65CB499057109B2D688CC43C4B385DA7C50868AF1B8075E57088F5DB12DFA493EACB6DC4EC6E205BAA2A89858EC2823C00553714CDE47A96E36C7C198B3EC57CCF74D92CDDB86AA0A8B8B5CA9D52BB60ABA79F4F72B0125532CEB7A9077480D2BB60DF51A989D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C472E31DF613DA9A1DD33B5D2D8939684B89F7649E1C59B959FFBE972786C477F66177DBF3B059173FD06AFCD90E80E862174FC57F97607BBFF5B73D6360FB5C37", - "c": "56B42D593AAB8E8773BD92D76EABDDF3B1546F8326F57A7B773764B6C0DD30470F68DFF82E0DCA92509274ECFE83A954735FDE6E14676DAAA3680C30D524F4EFA79ED6A1F9ED7E1C00560E8683538C3105AB931BE0D2B249B38CB9B13AF5CEAF7887A59DBA16688A7F28DE0B14D19F391EB41832A56479416CCF94E997390ED7878EEAFF49328A70E0AB5FCE6C63C09B35F4E45994DE615B88BB722F70E87D2BBD72AE71E1EE9008E459D8E743039A8DDEB874FCE5301A2F8C0EE8C2FEE7A4EE68B5ED6A6D9AB74F98BB3BA0FE89E82BD5A525C5E8790F818CCC605877D46C8BDB5C337B025BB840FF471896E43BFA99D73DBE31805C27A43E57F0618B3AE522A4644E0D4E4C1C548489431BE558F3BFC50E16617E110DD7AF9A6FD83E3FBB68C304D15F6CB700D61D7AA915A6751EA3BA80223E654132A20999A43BF408592730B9A9499636C09FA729F9CB1F9D3442F47357A2B9CF15D3103B9BF396C23088F118EDE346B5C03891CFA5D517CEF8471322E7E31087C4B036ABAD784BFF72A9B11FA198FACBCB91F067FEAF76FCFE5327C1070B3DA6988400756760D2D1F060298F1683D51E3616E98C51C9C03AA42F2E633651A47AD3CC2AB4A852AE0C4B04B4E1C3DD944445A2B12B4F42A6435105C04122FC3587AFE409A00B308D63C5DD8163654504EEDBB7B5329577C35FBEB3F463872CAC28142B3C12A740EC6EA7CE9AD78C6FC8FE1B4DF5FC55C1667F31F2312DA07799DC870A478608549FEDAFE021F1CF2984180364E90AD98D845652AA3CDD7A8EB09F5E51423FAB42A7B7BB4D514864BE8D71297E9C3B17A993F0AE62E8EF52637BD1B885BD9B6AB727854D703D8DC478F96CB81FCE4C60383AC01FCF0F971D4C8F352B7A82E218652F2C106CA92AE686BACFCEF5D327347A97A9B375D67341552BC2C538778E0F9801823CCDFCD1EAADED55B18C9757E3F212B2889D3857DB51F981D16185FD0F900853A75005E3020A8B95B7D8F2F2631C70D78A957C7A62E1B3719070ACD1FD480C25B83847DA027B6EBBC2EEC2DF22C87F9B46D5D7BAF156B53CEE929572B92C4784C4E829F3446A1FFE47F99DECD0436029DDEBD3ED8E87E5E73D123DBE8A4DDACF2ABDE87F33AE2B621C0EC5D5CAD1259DEEC2AEFF6088F04F27A20338B5762543E5100899A4CBFB7B3CA456B3A19B83A4C432230C23E1C7F107C4CB112152F1C0F30DA0BB33F4F11F47EEA43872BAFA84AE22256D708E0604DADE4B2A4DDE8CCCF11930E13553934AE3ECE52F3D7CCC00287377879FE6B8ECE7EF79423507C9DA339559C20DE1C51955999BAE47401DC3CDFAA1B256D09C7DB9FC8698BFCEFA7302D56FBCDE1FBAAA1C653454E6FD3D84E4F79A931C681CBB6CB462B10DAE112BDFB7F65C7FDF6E5FC594EC3A474A94BD97E6EC81F71C230BF70CA0F13CE3DFFBD9FF9804EFD8F37A4D3629B43A8F55544EBC5AC0ABD9A33D79699068346A0F1A3A96E115A5D80BE165B562D082984D5AACC3A2301981A6418F8BA7D7B0D7CA5875C6", - "k": "2696D28E9C61C2A01CE9B1608DCB9D292785A0CD58EFB7FE13B1DE95F0DB55B3", - "m": "2CE74AD291133518FE60C7DF5D251B9D82ADD48462FF505C6E547E949E6B6BF7", - "reason": "no modification" - }, - { - "tcId": 27, - "deferred": false, - "ek": "F5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD382", - "dk": "62DC65F32C94A1365605B30807CA5A34996AC9311532B3A23906683B44A9D9B6136BD9AA72F369E77C701E72086E5137EC7350DF480B6437B31B2863DAEBBFC08B9C27D00CE7F6349A971ED1E505039B73EDA8C7614334216A5F2719587DA3CE79B92D14581BF58590BBB3C01108C21F9B6933E4128B28A7834B2DA4922431F921ABD52EBB5295AC4957EFD662ADF97265E912A3D115F6695536AA2D6AD15E74D58C29FC0ACB536C2B43157FF21C57AC1B600979FFB223DDB70E76EB8D56502921654BBCE29B30E5C7E359B86E25A5EB018B0428BA5D53B23F6BA37E3265854C1A58DA09B9FC3DE4B98906E3A8E9C575DC82AD2389CF2E9C32D3BB8337A8221C59077722C7D39C9F536B3CB523C8756250176155907B20F5BB2C7F3A9B85E5A527FB0FCBC01D7EA971162789BDBC840ED68D24AB7F626B0E401BCA03A225F5E4AD2C17B8C87893683B7D1CA83B1AE0B3D0CBC34FE793A07469049C60E9169A47701828B395ACB3BE3364CC5C2A5892713137B04AD0720FF7307D917C61A269CD5B583F4CB65BA2FB562AFC535117264CD46AB03637D832A37585640379A2C3C80D4CD621D4638D3F6972B1EBBEF61A3CE5461B6F1A253AC2C150255B188656CCF492BDD41A921BA7CEF679C8D33265FC0A8AEB6988E2B813561EE6C4A9A8297E935008173C58112756E5288A4ADB6FD192A478546A41D88041038289A4708704BEDA425988D493DF57044E6304E89896CE25C4978A6278AC70EECC27EFC271F1E4A9C0F5AF17E1441357B8EDC88799421FA56A8731063776322837E01FED1AA6B2E4C86A5C55FC5B735E315C22284B37C238FAE93916188247815554DA511AFB634C75A1B8E783F5530BD38A57B4F77E48C812DE683507F5A24CA867AA3A96440678F21404D9D6B182259190C87ED86C6F632C90D03070F7761ED85C7AC22261C6566C76B66C2E800DC427C07633C90A61077B078E2DB251527835239957DFC2055F176FF758506983135D437650E71D77957A8A48B56CE59C566395078C2E7008A4D7604BAAB7AB78C461B7718D6BB27C55206630C331823619A08773DC562392F817D73B350421929D83BC49C6C8DD5C38F6D46F08755C316093F5C5454280A3DBDA4E5B508E40E0ADCC80AD27112E2D2C9DA3392A034B6277F8157FA1BC0ACA1C1F857CC4D6A6EB880C667164F6AB886B5A1D84C6321D735A5A1047AD985FA0DC317B22BB54E0C04FD3C27FA976F2EC633DC1B14A502E5A02275AE67E6B68583B8C7FF97827059BAE1CC3765A5C7202227AB640C1BB68924B928B489A3F6BAB68E2F0C9D338589443C3909353FB98487BFA6A91B71A62A9CDD39AC6065668680388E1A33467A3C32EC61A1D605E6AC92751D05BDE0930867A96E2713D933582D1BA4A85434590324B33A522A5B2BE13F667A96914D2F6289CE735BD3CAD15F6ADDB4B4BC7AC47C88A2C52FAA7CF434E7B8995A4F54A7043273E357FD6B37F3EC924457913C351BADB0B415CE60754BA7621A8C85FD0C678E1C9BF4C3283749A33784098B9065B4724A6A4A5A155751E0845F908B67C673C0B6C278C35CFC86A450A8526608683DFE69D59E1C905D4A3EF95B9E134AF8E6A54FDCBAF3E028EF5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD38239082384D084D2B67B5956A1463685AAA7BDE716AC1791935C47504893E18F24866531E34AD01E68FD6CE8DEE12B40398FFC74FDC4A8DA6785A966640FCC4F85", - "c": "BE483938DAC565B129658D168D494E522B52D031DE7FCC2FC6D52BDCE3F649AB140ECE5B25486B5F85D43ED6D85F6BBDC4141DCFA6C03F680C7B6D51484B461F700E207E2E281070DD48AED510A64E6849C462705AE29C566E6F2461F90387DAA3108FE9372A2B8D11CC2CD6CA20D9D1CEBC31C12B3DAF01F9CB67A4DB488DAF1760A48A29BB4E25A26752FF161B94DFC82A9773A8E5B9F761DA751FBBA982FEAB1A7FA3460CF669D5B8B3BEF8EDA6310009EE7130478222FBCC59CCCC248FBA6384DB7BF5D3B553C8ED134135F09DECA3877C9C4B22A478F892317841DE917E642B966906886358B09E8761E98EED4EC8309C578502C070E7C4E43CF2FFDDF1E4CED37762FC8D5D5C65348FDF01A0CC85314C022040982B94F4CC7FB565EB00C218CC61740062F896E992038F58D02B170DC903BB665B2A6CD724E201C17E646816E2AD528BAA20C43BC8ECC090F644256AA22FA3365820FE7C8AA5D168D67A21785D4BB2BEEE4FD3943FE351A0E94AACF9A5B4859EA97F3A5AECD213169356876B756137697F4C40A567CD960AA0436E61986407B2B88839FA226966271004C1445E057F932BBDE1274757A55F2AC8846FF770B1565C746814276487A9D3E454F5FAB0D77C82723A114BDE9882911A02192DA811D9B3DD2B2C7255C15E3346D6ED745C28A1F3C7BF4CE2DF9213E6FAB9CE90D7941C86E5EBA1CD90C9D12B94274D2D2C3AF727690A425BA8DF2527B26071D5A4C969EA61B646773810513A1AEF7F7E6AD5C5922569611CE5E94B674069C7914EB0CCB3DD03842A9C32302EFD8CAF9A1E4094339D7E857C994FB30C01D7F116EF66D8A502267848E38B080F0E5206DA26549FC7EC8F3D713F1241A09941CD7EA71DD86044F909A0D8C67361996D12E2D42C16E08CA7F789DF296C00393BFC83E47AA8130454F78DE07149D4FBCB304810BEDF462542B4B24A1A1D0A9F2B5B8706431287BA88B026E329E8865AB4F0AAD74D849F34945EDF6B3719E8103B110404A8FBC300592807851C442B506295B2FC76A600A0F9C3B3D796CDCD3C27B10FEB1BBBB462BBCE0BDD33292CD873D2396B0924BDDF8DA7408C4E680956DAD992E45925E9721985D4547BBE2684F4D4FD220FA87773447BF7A620F979FD529D86D2753F0E77C498E02B1EB55812D9E19EE6C99A61543EEF1C124716448FDDB46EB2D460179148DA2F01AA91C9B9B04A350A63D98B8CEB6005A39734C8F3CF9094D650812E1707CAAA98EC35D4ACFE425C48E4D8A1BF190DA3438684A27564255C8E5D1A97033F87077429711128BDF396DEB75E304376FAB9CC33EBA906D3804819534817EA309E3C260F9697F55BF4AA5C08A8A59EAB27BFCA0C2301434D7B490312CFB5095BF9948E3554E5409AA74EA7BFEFB9BC7CA61FAC565F2F7384F5832C2C29FC9F5D1EBAB56612C6696DC93FF21DB4DCD87F09705EE062DB948F68C6D5F7D1886059C87604089ADADA5DB49EA2BF3C3813A71018F1F559B2D72E35A013E3D9CBFDA480B43E616B9C7A", - "k": "44263624052C18E3AA23310697414499F1C0EAE45A1060D84EEB65FCDBCB5733", - "m": "76D04F481E68B2F901ECAB58B6369A2CC31A9DCCED82A1BBD426BE0AEE266AEE", - "reason": "no modification" - }, - { - "tcId": 28, - "deferred": false, - "ek": "92D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B", - "dk": "96B453C51B12941167F1E155BF08755F122716B9C82F92B94DA348B5BA4D8FD517A1756B82522444DB1F28172BB0C37658351DC545053D7995D6591897B39B3A7478FFCAA784D4210B0B291D81AD3921BF093B4329C505C63C1ED5B481F30CA2CB3A9951F00F5091BFBC21319132A0C4B46980248014967E687102D689B0CC04813503988F2C1FDC6CB62AD7616C1A85A12134A6F57F00052AABCBC990CCA1FFB91D14344E4A193F9F6346E8455221830D14B9216AD54E82432402CB51AC44A988A6A2D6035BDAA69FD46206C83B8FF43C33EBCCC47B22B3E57151E09C803869709A5A9597E1830B0C050F87580C23A64BE7C82506CFD238A36F34CF613CBA3AAC9358B84043D9A1938CA244454D7F6753E7A2012D5497F437662B57791189C7878B04617A719B659416BB22ABA04E01159CC7745802DB76F7334CE0715956065F01F8BB2CCA7F9787271CD75E4A918B0462B715ECCBEAC34ACE288A0A23C98924289DF32F13B04831798D9DFA64B229CFEB380F4F70A598A93A8C3A68AA7469C2027101B30A26298099A8CD456826EB5B21826A0C56F4C619938E5150523BA79595BA73B8460A681391B052CA2060AD68344A8A2CCD2F64A211C3A3802336FC583B7C21C53311CB89793D7DB5C68EA15FE49158F5E73E065574EB537D382C7D82B14231732CC1633686E53C723A1F43874AC6B543C4D99335B327DDA3BFC49119B00B3576321513D156E415A2D85689641A7A782800DC234BC8D589F5A384ADCA2A91053E41E18F2AB97F89E98B0C7984C0497EED8B2FD9D828C4BC7676C54C009D994E1786A4B177B7557508947BC8C706FCE8271D4A9630F3BA9D993ED9E82C5CE4A4F2BA83225C08E37A43116708A7B27C1B3620A539334F846FEF6084F8193071BA34CC9B919A0311FD7526C647A38674C81871B4F6D49DCBF83D46C545E5C543D26472EE9BBD04628B0E5434A2B342FF3A950DFCBD9EF078EE8BABBA09BC420967EA06832E78C2946746224B1FB539BF1E44CD67A9BD42F9C319EC7244EA5088949925778304E1BE08A2A9048B37B225325B22A3FCF2BAFF45C55110175E930BB7F6603F95577325B809179A09662E948453DF33313620BF195155C2D36E2B7B4BB4E6AE680B5C9A050A341B25D8BBA007B98C4AB554169952ACEC26864B9CD62B20A43BA2221903516BA174D25143D872B6D5C1C3961950D08EE1350E5700A111289987619E8FD5A18067A94D0B16D27318E4623BC80312F5017FFD241EA1A58E8F4A19EC0B4B7CE44E832A80D1C8C39FE7A535838179789115E83873CAB5BAA2BFEDA8CB07414C3BB0BC44C09D5765911F3233A7C32216914C520A5BBD63944C0153A8054B2E825A83ABBD3C564E7FAB19D081AB59AB138D1B250455B5FDDC16A8D080339182C1540BDC615D0B1C9EC1DC01455B4E59E5917D26BC0EC746A7D300D836B74D0BA16099BF4D87A9C6526BB8A5A9115C59B5F538CC0A17B3965513D92335487A4263C17AD4BA9C6144A0A4AA4DB83EFFEA9970B96C01260E91CAC3D652C88375C50CD0516929B364AB3BBEB15D68FA83C4F72449C47112557741058FDDD3CBD6898241E27FCB16090280002AD686F43A91F9186DC6898292D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B1EAAA1990D4FB6A021D7CF8F417D45FE1F49BA84E111A448E8B7DEBBEF902A966BD5EEEA2E6D38487D083F30093ECF02E7EDC4FD4585C73EF6E71FAD24E15E2F", - "c": "2E7CDA2E97146A7BB3C33C5EF76D1A4F4D93A59F1B8441BF6A32D88EBA5609490CB3283DE2C43E4D1DFF2DB55E4DB9B4C3A377B3E9B33FF1CD3D6A2047C7FE0B6D8155DBD4C0296E8CE60C74DCC82080E31AF13169D638EE6396439F49AE426BBE5AC6BEF9B2BFF423AA24BD2C168E0F4F2078419A5865F1808B866FBD19CC221791952D9C2101C3EC3A6F597F97C2268F8F6FF273E4B443B8E95D93B6AEED85F71509ACA3F366938E6BFECC3B0A35F859D3EB486BF321A1F3A7350B39F7A89773DA2C5B235132C9580380DDCDA3A910E89734F03F871FE504BEA38918299DFE7C9F60A6E4CB607768F0A3338910D45612B31BFB6A0424489E0A4E514D2F41C3B4A0001E794A5275F8D047C892870E647BBED53BEE167BE27EC2A43D2D7DC10982F96E3B586119D27EEA5909A18800B79644FC9D15CD7D2200229C1380FE2E939DF89FEACF4834DFD1D3C8ADDB8F365BB94359C4698AF15AAFD4F3289233701C217CB4FF979EE781C8420ED9EEFF53D58F046B774B821EA3021F7DFE33A79F882C955C86FED0702AEABDCC6D32186B7D40DD325B9FB7BFDFB1D34C63B19433F0D80739765EB9D8BD210669675DB3F4349BBF23B49B7A967CA2304ED8F143D27981C26FECCB1658B5BE11DD858BEFC3DEDE25DBA9FD22341E63A5884C41A0ECB68C543E0B021135BE381D42DDB9F67CE1473D8840E00138B39998018E0E869FB0F94823A5191B928C7D13F157318901EA8F8E5A5A0DF0ED71FD2CBC6489A46E5171FD14A09F73420C77947941DCCB4F122866E93D94A9DB0030A20663705B11C93E89396F1B7E7728B6B450AB5DCA0932850190D712E3F27EB207473D18E29B20B433F4E6BBC99B28AEFB5ED0DC74BA529377F0F8A93BB7208CE98049A862FD513E81290187A5B2765E4EC5B4F211058310D0396CFCEB90B9E86E681AEC3D3D81C787A3BF16A412329AE643576A50F2A72E59165AA357ADE9C194A4DE0ED5254FD206D05BC375D1B5E8960B7293C768B7A66796DE0D5587752CDF7921C2053A5A970B9FEBD7A20F336C93839D567D1CE241F061565A893A409EAC2645C02D3FF00AA024F31E50946A8CEC435508486AD757114FC138E57B42F2CE12A248355CF35191341892DD910DF5528306C947B0ADFC0AFAD68DE715E8B2D9A43B8858BFC04F73B44A04C4E0D331DEFD57587276B188965C5924BF1118713C05E975090C52C4DC2BF7BCAF47E4E274DEEF4FEF3D91EBA65F616B8C476FB9EFCE61CB8A0524D97C27491A0C9BD7D99B0EDDB2A3E50248793FEF1C248C15301A3B765E9AE21FEA0AF86F09A5BF42D21638FF6D169D6127463962D3BA17F5CA63ADF63F317CE2B7CED21311A05CA842E0DD6664953DA479851E80F270B4A7FD11C3FD6A52862716AF8A67FEC893BBD104F5394F118D579B787730D6C37AC242A328F724DE9C0AC6E091A3E4CE01E29400836ABB6D1363E049C3CDFF2048F0FB1D36FA1B70070576B8A14E766CC098989EA9C624446DA2D4D45E7381AF63041EDAC0197149AA0E", - "k": "69B8F091A450890C0DCCE0120E9BAB05054C7785A797C93B6FA39FF5E0BC5A70", - "m": "FD3C91294D8C974930B4B6135AB647D4A7885C83FCDCB30CBD38332E14094491", - "reason": "no modification" - }, - { - "tcId": 29, - "deferred": false, - "ek": "CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD602", - "dk": "58C845051321CDE3A3C19C0D3BDA49688751B7C113CAA67BDAF87204D20ED9D79E39D135E64708827BAF19D25807B35F76500445B971DEB6A7D2680D46032490D042FD59B963291B5BA589776499DF1635B1249A12C3CF42322EFEECADEC1A243738260F2503364087A6AC839D1B5B85DA2A0B337BEE74761683A0ED501F67869FA587CEAD708A2309329A7483A8A3C895241A15732C46E2A864C94A33C36C6A71400E70678863B89A5B6BB8B0129679591A87127518BC2D903F06826605D7CC0DEB7E5A95B5BCB691ED852C94CA95683025771235156B406DB024CCD430822C785C3B265633AAE6BC18E4BBC4C6C983F1F0B0F514001E4106F36CAECE1380D661242E43B585A8B1203431BF46BE69567B9A883E2F67539B4C62EA6294B7365796578FAACA0F212B8B87B2AEE6BA128A07A03F20085D8122182465D46A8C227363EA7B4400920CA22C454CEBA538E5CAA110B7762087B86B37CC1932A2B5595D265F3326335D407712D80EA34C4ABAF0BF9D4429300B14BCD2B9E186301BF25C43EB544FB32D30BC6C643BB028577142761C33243D9C038BA0BCBD7502B63196AEE79A4D8DB630BC748D7220C43F76C2A77A7D60F728EE1133DB0C7AA8F0CD1DC0100B85460EB31D0BC9658021443D6564C0D3AFFC6CA1E59C5DCCAA454156923CE7B2E8B123B1EB39EFBAA7EE0CB17F627C79B690816B5EB317210C16A1BB13A803C2453197A19E2728C9F61017D20D6C19C48D21566A583A848A3BDE79628CD4150A30AC1C44AA2673C1810B89545971D9E4199A12B82FC05774475797C6CCD0A9C699F50F0CF663DFA14FD809437E0889B285959DFA29A08040802BA77E3C3CE275CDC3A92388518C9B70BD66BC3424F67FC9FB924F59C500D2C138E7C06179A3EBD800D6F96490DB82C041AE9C958D5015A66D91320D86A243AABB8BE17260D86AE4F5A6229859811552E0BC1000F3C47543698DDC7A61CA5F68E68D47A96733F32C8437B893B10FCA1B0A6866ADDA2CC610E22D155984855A9CB99339FBCCC972F62867D7BA04DA7C10377419E36D8E3876B2C5ACE1380A505CBC418A181196B150B53F5FA3B9AC08CF34E78A39A9B66559A859EC22461C9D836CCC433B8342C94712EC46BF716D0628AA3D421AF6A24B02F38DD4C54E3CDAC15AE47863B0AF21214723FB9592893825031DA00664C1CBAC1585B60E7A71022A35B3E23063CB49B278CA82B51EB9E010E6A3B7C3227356733A6ED0BD3D84A6B7C1C0BFF42842168F9703B1636698B171902AC4775E1A15F0A44B39E9247FB61C0BC90BBE2AB156B11EB2CA98BAB75DB92B844154258FC6BB29C164DA177441968F094941C3FB417C078654CC6358C6143FC32BC1518059105EA8DCA282F138C3EB61A48B2D63266012966BA12654C7B4142129AA0D5841BE0B5784A94CF1007FFD5112EE21AE82D7BF3FE0B1509710569CA6749A0B706C5B79A883BA985967731276FC2B8431BCAB9B1E2E9330FFAC9DF591AB5B17317AA93D8903708CA8929EFB8DBB2861E067CF57A2606F174C5DC80FB26A70EDEA0D849A6977D39866A78F3AA417B3B87D1EF00A7AE2734F249D64C68A84F016DFA57C8FE72443848EB058A5D5B784CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD60235DC954C8CA6DC15AB79B2C974D77BA09F049C2007BFD5F81A2BE06F178A0EA5FA1646B083D3C34FDC56A8B5797E26890EC84F86E18EAA17ED3DDC78300313E9", - "c": "1DA1EF5325F46C686D3AB385F8AA79758CA0E6C0092265C636DEDF9C5F34A0F7A36783AED59E21EFF5A8CEA55439E5B13C42AA68E1C19BCD0CA8C629FFF79198673D416A9CE82DCB80D7905968B02E84EB04005D0AD971700B87A023708F169369DED4833B8C13C8C277CC1CD7EF32488DB63E5C1058CCDB73F88A679C41A36144EC2866130D68914503889E783A5E28A1E701B0C198AAB245E6F61337CC9B1CE2CE8B8CD6EB106B969E120CD09EE174E458AAB80ABB5795B091E07166A39F15349C0EE271D063100D07E46E9AA07DE76DF152753EE298930E0172900F7A4E47128E5BE9CE81A317B07282E3735AFA02FC0F89A6561F5B4275E3DBD31FFE2A04947F8CC6067C3A8E8FB625E6BD23BC20F63DB535FAB0E2C44CCD50339959D3A83AF0FD57AFB2C6BBEE6B9920D56A805447CBF7ADB6F957B9DDE850044E7DC47ADA07BAAC747069241FE4B46F1F1DD8DC2E4BF52ED6792ACB987A1528B89213E10EAC95D86519A95EF6EF5D9701971AEC0608EFA2A51A5D0127B3BDFED8E8107FDA600D17D913ECDD8D9860C16E8788CC9CBBC99EEA2A7AD8CF35B85670A0B15607F3ED98D88AB1A6585E1E0561C37DCE34AA00757BC1F6CFC81C7BC2EDC7A011FF12C1C35CEF9D1F8BE5B80860B5ED0707A04472E94D2C3D7C1B1BA4611EFE6D023CEED3B486A066E3B0121687DD9AFE0C4771678EB7B0D85D249C77BE8721B89DC086C4C5F14D9851C51D51CA2646A32929E36A33A35EFA58B0978B2DEE5CBFCD23F3B830CF1AF3EE6743538F82E246F7A9F76B6B8E43C84C9539EAA2A0DAB6EDECB4061B0B211C5547574088B8EC42BF6F21FCF299BEEC8CFF41CFD1B49639032F4ACAC92251B9F37CBF51098F4DEE7D88363A1910C9A6BF689E8DB93EEDBFBE8FACC4D1707686E1BF9E5E790DDBC6874218FBB43128783F611D1EBAE677D526057A87FD33AF449648EDF506E93342CDD38AFB6EC3FAE952101B384E841D889C025FAD91099F2AE41EC3E3DEC70252663C01B4B04EC1501422A97B5AD5AA27CC9EBBE2C22BC22B8C706F04FEE274764F1DBC4CA60DC56631BB2CADDD5399A2F061FCC21541D2595D15CFB6DB464775D4ED48559CCC97DD25F64CF2FCD30013EC35AFA96C1E3368CEAB29AD03FDD5B9BDF1FA1356132210702466719DF52FC34A0A1479FB913B6DFD9CCAA0F9D672AC618591B808B4315A5E17889D99E271FCBBC3C4B496DE8179A74C1293468392E2B592F3E6925B9F81604790DDC3EC0D1056F31F3184FC0330497961EC8E2737FE866AE4C262E5218E06EA7C24B464AC7D5FBB44069B9BDAFC96E014DDCD168C457140078B0A7DEAABFE04773BB1335497CBCCF4083E6D41288B3901029F1B266AA938A9F14763C679DF1E1C58EF406BC2ACE2A236B37557219DA24812036E557ED6B6C1A3A1776C5C0E64E1AE1A2A0747CF2CC55E32D48A7B1387FC9158222AB2582AF43580043F858E527B25379081B97CF0BE6AA5653E186CA066BB7D57B6C4AB8131C68423B12622CFE234696D761E", - "k": "C21C8C4B59906D0C4ADB1F3CAF47F9EB326B8A62B3392407211D502F40C7E07A", - "m": "7DB18CA35A53AB3A65E4C17FA096DDECB19FC7747E657B49D1C1710DBD1D197B", - "reason": "no modification" - }, - { - "tcId": 30, - "deferred": false, - "ek": "0F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F", - "dk": "E434A051F4253EDCA7BAF48841E07438B892F47ACBE249CA763061CD3B6C9112629CCB760107BA96C260793CBDA5BB4EFA184DE27432683C96A20B39D1B72C4FEA3D05D299EC16CB7BCC7C853B83E92AC8064C38DBE256C86C711ACCA9B0C480A0444C6F8C8EB187C32BE0C5A1F20EED5365C32656AF7335275920091A38EFB8BAF8629E87928E51B2370FEA2B66D188A09264D21CB0AE66B5590A051CA16CE77CAE914003AB994691DC0A09FBCA27644A7E48405AFC5F4CCA9525C113DFF133C1BC057E742FCEC38531EBA8E2D252C543172459817C18774CACCFEBC227D267B5684C325E17C0EAC74B34D22E136B98C9A8532139ADB4ACCA2F3A63A21751D0324CDA8A15230918E3856A07C4A51813569B76093A14771E3606A33C389ACC42453C05027501E9B5AE311C9D2D640E165816FCA60BF6C5423C9C585D642151F7314C9C656E8C3572C407C6DC0EEF1169AF4B5B130ABC0507ABBB52681135984BAB688AF080F567B93F1C2C37E231828A3106600FE11429DDA8C673380105E26423A06BC97BBB7B619A5E54429EF549BD9120BE23892073777F8C21E3700C90751BE53658BA9035380ABAD8A6522DA19ED801646A772353DA9355A75C65164940189A79439985545863DB9896F95F7553BE184ABD982C4EE692CC08046A8951C95EDCCC3B5B942359B82FF4C3ACD86AB0AAA5DEF49ADBD344291A8A15F613A1A8591710BC1B854682659D7FABA1D05924F063942E384953EB59CCD55F3EA4081AB38E13AA12DCDA528CD06907018E9C287042583191B8BC75767266A0C9AE074F0CC4B946906941D17591014ED2FB4A0A3A01179C26BFC85A5EB9A859284E13F04F65F589FCB9557EE5095AE79036033E2D5336A0AB191776A4CF01A6F45B62F3B8767A8413DF6539A5B1781DD30C2BB41A940A4E2D209526E600C713AC522C104BC8C428895F35547E4DF1214804869EC5B92BF9C2FC28A361E050182805E4919BB4EAB368EA0417E03D8611CB09F884C05B3E66294A93EC62D694BD5393AB3114046E29B3B177B997F7CE9E2305BA257A923B10C7A3BE7FA881DC1376FA879BFBDBBF0B8000DEF00DB26A522A96598B450D5B39B943553291D42AC6EA0D1FD04247A41420DB7314F676557765FBB15BBE314EFC968C76074BC3B609268C264B0441EAF92E09E59793273DD8B50ECFFC103DF067496C8015893D05DC28ED3445D726BF0936145720CF7794290FF189B8C38AAE3BC55D2167BAA3AE39BB90D19948DD439C7D827CB2F37C17B0A0D8A74D6CA82D4448114DC72D91991972F122018197F192B4ADC4AC41EB0F2C220DF2A94E61463BCC105A174C985933B09D3326AA2989E2CB4BBD7C5B557C46AD9990BDE8183CA63CDFE98F51070D97C7AA635C8149276C58E9CFC314BE31455939C854B03055436650D3651C3D566F8129648749499AC1946F120D02A6CD230100D5A2788FC35D4C47B7CF086363193843523A81221FD09461F06919DBB5287D727957EA4A2E448D0D8CB3A8860E71E8C60EEA37885878B7E07DE6323908830491DACCA88B50CB901B384ABC4B33236F727D1A5466E5506F6100AB16AB4567937E39A2605A52783D574DA5C961254704795C450F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F81E7F3A4D5E46DC6FA36B4C63BAC9B8DB69CD90E250ACFD99280A13C10C4F6F9B02201A4ED8B58B3F3F38D4B28A3C6E87D6AAB11566531DEA6FC00781E6216E1", - "c": "A0C773196F91C0A7A3CD3BA0764E4FFA331F6962116C3B9FFF775F47A02AE2B0BE69FB89CAD33F5E059E051B92FA124FA25810EDA08AA89F4E5838A250315952E85BF73246C4019DC0F8DC7E6FAC2C0BD1E0191EA0032221F4C5549D914145B3BE2AF25886DB7526439BB9ABB6EF57C959D9CC76404FA02206B5CD4A2EDFA23B9F137729E7FDFD46CE8CB326CC04E73EAD7DBDA6C76EC19972E10049394E03BE7933315AD8B4DF72D0582EA9E36205F07A5B3A0B007A683D677D4571B907F0F967227E5562873D45F96FF2A117040EF2AC2026BF1B6470FF40F50D0A2E53979F3F61AE0E041EFA26E058F753D2436AE9DF06E70252268CA9502859C291BFED18AB563C2A5A74EB4E572E1A916C75E8E7C6B31FF39EC44D29B581598439F8A5E7FDD72C720E703FA24FD10FDEA3A43B06CE30B5C41D2C891724C7872642381860252B20345665038444E8E1167D5CCA83FF29A40C306E18CEE1B22CC583E26B8FAD23D2FA3862CAA0A21F6EF090959982E0E6B1E58413969892A41614A76325DA18C7FE4A73F27FCF275A3495134DF24D94AA1D4DD96174922360F39441F69F8F07EC5B060178AAE1CA5D00F3DD37ED4B55DABFD28203E65205AAAE8B2A885E211A5E35B9FE23CCF991A7A5C156FF8E1B0253B42AE6A4605A55C1A0F47E8054D9195D4F2496458EE4FC64DFA8FC4D2BAEE710900120ABDFD16E6AEA23550BB1D33175B9441E04BA281998D89CF3DE29184CC2EBD2626A1FEA4BA05D1867AD3FEE28C7154EA5FB0E463268B2AD17DF5388C2A7259F044CAE83D51894D61FBB4690E6DCAE9822D63A39B2D887BB2D81E8D57085C8D52773ABE2AA9B8AB04735669311655A3B6AEA829AB486B54E54F6E2AC63FDED2FF90C8EF88C9E2812218433B59677DD9FBAB3E15558DF418DA6F3D61ED45900FB3415B5F1A2A7C600DB715EFD6A17F729FA317086180BB126BF26FDB8637B8D7C2523651A70E233C5B180403B507C04D93DD01A60591BCC77D60FA874CD3DDBCCF7246ECC63FF447DB9CF31C114D3A9E4518D672E803E0D5A9A7821855340DD65FB91157FBA1005EA5EB64E4AB762210EA81E7F93F8F3DCFA6164C5F68060FCA6E3D52F83E6FBABC47B3684C96F5F718EC731CD5CE61A3C368AF5E68EF74020A2B143D37AB268AA4DAF203EE27702DA2446915D000F55B90E2C67B01D1B2ADC07D613B6C88760E6AF7B50C08B88446B43FF419ED8994B9E380A8E35C60AB495DBFD8424F50BB85B1A4DA62597B630811EC6DEACCAB4B049AD3C99DFB034A91DD144D757D88B6DFD0E1F62F4ECFCDD76A40F6B01C6CF27FD2B3B8656CE335A194A9A7E04FCC08F234BE1ED5DFF2A73650EFE7A65A8F9298F522926275FCBA55BF167DF37CD48208F37894949973E3A3E8FA7DE0F45317C01B5A5139BB30BA10767DDAD39864C7DE034601577C600C929245C97016E82534B74575135F2326303B1532DAB96500D314B41903C22D79F7067FE2BBB33424238AC1BAA581BBC6E0DDF3A0162A8066D3D88CED57736", - "k": "7265696182169279EF65779A021AC0A0E0E7E4CFD37C8546D4DCB1BF08572AA3", - "m": "876B17263B409171B746C6936EC65FC94137F958DC974BF98110A1D07F6D95F9", - "reason": "no modification" - }, - { - "tcId": 31, - "deferred": false, - "ek": "C9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C", - "dk": "F0AA12AF6024851A922B789BA87B869072382CF829D8AC455EA25BBD3C3B7BE58C4DA362494369D9482AD1C42952C64DF0A220B6668DD4364AD3E698BBA190DA9C5E67263A7ED27C3E90C8FA38441327CE092C0B91E08ECDE5C4CFAB7A24271DD782ADF8FC6984701625579F26A196E9B7A7A80B8804C564A735B7A9BC7161129F5FDB0FD0E6226A89071FB288884C3635CBA37294253EA57AF9BBAC807135876A338A9A2CAE4CB35938BE4735BBF06CABFC797FD2137282C8CC15F70BEDA8BBE41962119C4D326113A534B4E29AB464924858CAB7B8ECB0B388C6D184B8765C29B5218806944ED636B8793A0D70B3B1B2664F9AAA0F18D5991AC4C6AA3CCF0A633707BBC97D291BC8C96FE6B32490632383886F3723BC6EA606D09C50B28314736A317C15804E1B17C07045A1971869178E9864C21C24902EE70CE3682A31336DB482BAA9AB22686A725716CDC84623CF39365B44AE6F88AF7C1B42C3168C4CEAADD875609AD247068202056C59DAE502C7B421394328D6197EC4FABDDAC3A47D9C614F7A0587A54476A7C370BA84FDEAC91B460C8E266C28AA5209D80885B7279CB685D5D184FEF93525B41CBDB6AEE769BD7C3BA3806338A27399398B617B45C6A94A9A58089E91367366DA0646624BBFCC35CE5B33971243EA0A8D61137CE7AB99636008326003B02B13BF200A93CABC55A2B2A2382EEF3732ADA819E3806AF2E8BC0602CA86A8ADFC41B0DD4A0E95FB9A25296EEA0027550A8FD04921EC30B7D50558E4B7CE82193F39A998012299CCDA061FFA23391519023C1CFD66C341765E62E38871D9A57F80A657D7347E927E55751A9F768A842A187E76C70440517523B7D1C88B1635208D5C7C4C357002E55768B21462D483318B9AECA5BD81A13507D36CCC7063084CB2657183A6C0C78D5B62A7E75C0275C29B304375C77BC8E85B569B968FCCA5E0E2146C951B7590CD0F3CB38E85586D02763610C67885AC56E84048C40FAA129EB05B8F7A67468B6145F949963CF165CA0B56F7E45DE523C1663B311F0B5DA037862559B2739C974B5CB18D16CE2695668D7B0DECA64EC9928523893C91850D91AA4B76B030C2E74C65A0AC5576399ECBB4E6723DE63825D3B9A1CA374AB763A52A541E8382245542896177AD07D9CFB5F2C3EA87AE2164625DEA89DCD06AF22753DFB1A3CEE1A45146409FE655F1C80ACFF107772562784C2C5CE67E9F395EFEA4609BB7308E13031B68C7B3B0C1CE9626E311264127CF8634C9DC35CA53036E9E30BB7B35C286236A2DB2BB9808006F68BAE0125512531320B3661305D0D4B1672D64C424D38536BA98C6417E3EB175D6C1857788C231C02ECABC4B28BA325FD47F3B56C62D0856703C5296E2576D258B98AA273E3418B43C9A52804EF842C543313ADF481F1E974E93210BFFAA36CFF758CC74914BC43110FB1C819678CB03952DB71C0A560D5425287D9590E6F1373902884A38A908082363E0CAB4B646AB016754BBA4E2FCB14E572025C806BD031C7F415377287001811E4F69A110D48449D24085FC43BFAA5465C1AF82A833A7575C578A464442A33C93B0CEC7952ACAA53EA70B01F49200827956B7B21AA697A6859F248C1DC9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C9D71C52D37B30F0CADA8753234F7BE062673BAC70613CE6AA0C704C60E481CC1DA9B17E5EB62AD1009253B91A5C9D143F7BAAA3E76BD89AA399B671CCEB7619D", - "c": "2248562375F15D15580AAD60BF6C78957F86C7BD1F78D47B6FA78E68DACBEF2BE4ABB382C409B81A7F746CFA6F90246E0A33540A1C22ECF83298C0E0104E37C29755D5C0025DC5D9655A0A861A534DC58B23522B4F0961F8D40DCE1FAB1A8FED98B7ED1A027C784AA3AFC5B06680C8F64CD281788326CC4CC2F746E0AEE756F71DD7C3F594458E87382B0135DEE1F4897B80086A4667F260FA19C9A9C4BFEFA1FB054504EE11AA7286FADBAA1192C176294EC7E5A9E383A8AF658077348CF74D1707DA1A8F3E400187401D26BF9225B4B36A00466F75276BF2D10A0146C4611951D75B3AFCA5CB4F8ABA70D3999D56273C86413CCD6944AEAC00FE4D5FBD49F00186950126847AAA2F1D87732E4A42B5944BCBA773A83A8F168875B89ECFC6AB3642A7CF2303EB9929825F1B9A4BAD731EB6C2A6848A959EDE0FBF95ADEA3C4E159A30A376DE5DD9BCE1DD4B85500EAF83871A13F3EC1DFE74D86A383C957D6FE3BA1BB81CCCFB3DEFAC3567FCD167F9B202E72677D2F2012BE72CCA62DCA41E5F92519266FBDE6F60A691D78F0366FB0D79BF924C98D565511CE23EC62F3C7FAE1A3C1BC7817CA67CDCE53D1493EA94ECF0176372F9891D81D0964E409C38079D7548D9DBD463D5CF2302E07FD565EA41E8958C563293EBD58620D08CA822D70F87F4F2CF37E963A730DD5A591F2C5F372C9697118AFF2995170308BE96C21A0EF094CAE5372E1FC43172EEA54509C74E5C83A0BD352663BC49F8100C64A65D45D216CFDC69D8333049487261EF03F492D1DE706B00867BEBCF86ED3CF0CAAF4D94D2869E7BC62DBD4C5127FBE626DC26891D67EEE545CE2A3C6CFA5EE273FC017493B08535B907A852E9F4A166C7B8D7261773B73B6FC96822150484A04954A92FC05D0F8AB9716F6653251794F6B2FA63616322DA4CDF97D352566EBD6E23ED822A118A41C0A80FD420408645D077F7F1561FF5B342445C0C8DDDA5E46CF2F253513BEDED0548DE267ABEDF4A9B7809436AAD6F5258FF89581B4D66D9A1B5DCD1A35BE090DD4B67C29944ACFFAC110B65332C469D1266B256BB4B462CB3B6C2B71D8A119D3218D40B00CF449F9807ABF0B54313845FCAB484AFA418ED6E532136EBFD242E0BC499C7A6788FA9BF64CCFA6E5E0B78FA2708D3B9DB1ACD3EF4E3EB1B105EF73ABD0C0AB0D0055279478FDFF8F154CBAB11A9A5FA8F8170D9DD4B1DAD43F9B0DEBA377E674B2CB9424E754B3B203BCF6AF2C71C8A012320DD57CCAA59F2017545CC64A76523C79DC9932AF8999F2C01687CC80FE4CCC45C6C66F6453CAC8BE9545686920FDC8FE4C5D7B1A9C4C556585D70D520ABDC01B650A409FC907A4472229EB981F74E70EDE2DFD97122AA2C1468210932B8A48A9A38A5836F387B5086D1D3BBE516E33D4D989F73105D3CA0B6E126CFA3C11DD270E2D0168C4E08D9E61C951D4E759E6B97313F4A2BA4E5C7CED65D8800083CF016750646A851F533F631FEA14E8CBDE9EEB02FBB5E2621E31DCA51A60EAAB8D9C57BC3", - "k": "9C6EF50DAE26887F7FE5B0173C055E88DC2FE09384890E11777F742B99AD7C6C", - "m": "E0AAD46FDDE0B8E64361C3233263D8A751F5583DBE91AAA6E69E6318FC7A8EE0", - "reason": "no modification" - }, - { - "tcId": 32, - "deferred": false, - "ek": "B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558", - "dk": "B4581DD3A668DEBB44ADEB1EB7274625494C6E4A8B303528A3C0CE78F58CA988834A4766B1941DA48898D7A8022589AE577B79DFA056A0305A034385EE20543941ACBAACB71A0184F3D308E790C52F1C210E12C726006DF729448B8B4C2B58B14D150461CB69BE1C840463AC5D4A5BCD07AA81246A3DAB0E82D555B624A3D878021E4604B4907BFD906308024D77B15836C64984C422F5EC3784448DE4D5AA98BC9DFAE665F82B046C446D33321734A2AFE72638683CA596822614994F54B856D9E80ABBC312303C7341F99720C080DB72C635D647BA733CBE521230F528D0119377436CE8CB1F7A48B7ED15904C414FB8404A5DD403D3B07FEBDBC129D274472C634DD2A5BF14C304F702C0861DBDA793834ACE9A851BE24B5DA56A4D433AB08E48C1BE6C5BA22067FD59C38F39A25E1230CEA26BB89BA94A0A3A5FD78788E4A150819E951C1C09B6B9D7B7B56DAB4C38A51A80B56DE30790B72B1743FA7782E40320104B2715A22A7794E4C3BB90CB493B8A4304C8084D18C0E822217A9985BD282B26F60F0A986865C39759CCB69109177A826275E663CF81179FA6181D746230DA0F73D991274BB1C3F802FD324CCA01B284BC6E33D9B853D76B95778DAD094E1DBB2DFCB099055C848B540CBA3962A843211DF6B15B5591C5630ECBAA834A9460BA5822A6200DA8E51B5B5292FE221862A36282B306B08AC03454C8A4A3B0C4AC15127C1CCA392E78B9C15BB8B4460A357DC90C2CCABDB7284D50D440D651410AA849648435CB320CDAC8782E31CB868C7F0375C5EAF51B6628C52AC6BEAEB1777C9B53277BB014EC831F3783E6086455CBA77E2391F89C2182DA4D95058120D2451944C0C9D91272BA1C70732EB332B83518B8925781CF90887F43446885C3A1FA6AB1636052731E7D3B126E556AECD9572DA449F97509D9C795E03961A1B82BBECB74A3859A802BC47EA0B014F5606C678FA15323D571AEDFF78575038374D99F13724FB5120890099A3DD531B7ACC7CD286C78C7182AA00140F48595F47BF0B8B6B74535DEE35C1FE904AEF4CCC591AF85E9BDDC978C95DB382BD82278028C79F0741AA85DE2DB4353C1C38299B010F7378CA21F0DE3A337B15135318E5DF69144593947B1A0F9110E5D3B7710D3892EFAB3FEB3BA67D0B977671F81CC44F38355D6D7C3B8677846A08159CA574CD150E5999C9DCABCBB342B5DD1C26B95762B5619EA21350616BFB06C04058BCBD6F9887879574020C4234CA77021CD52074BEDD81AFCFCC5ACA6691B2B4364183EC3C220E20A0060C4A40D4A5592C4BEE8D87E57E6A2CE99CA299631DDE545AA745D5FB9594A67011C5C2AA1090608E4078CCC59CAEC5F40DAAB6991AF1782B9F4F58F8CD25A597393AE1771DAF2246838C1A4E40BFD3A2C1366A563D698E3321B06672E523AA863A3B68E1053FC8A8428F7393F037290BC177337B534F80E93A19021DC3D5C94AA6859022CEC5AC5E8C16A83470AAA4C72952F823408D52981D8BAAB4D529751D02596CA129031C03576BF3B32304913BEAA20759F245D3F658C8A3C1A41D69EC10C6DEB336CC00B25E332253385B1E6F52DE1EBC45A487CAF133EF1104F286AA12FB1A2552AB1B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558A7F40DCE21FC27EB6E7596A711E8B29FA33B3AEAFCA1F90450EFB0FA358688A591271D83D0E2BF964B9C7D2CA6227184BBE74EC134043A44DBBF8EF3B18EC43C", - "c": "72CFAA01CB4D24B32D0A12BD199C20BD3CFDB6F063CE9608A0DEDF0FABFFE8EDAFF2536244B7942B6FBB62297D85456519E9CBE3E587ACCF54FC28062765E0C6250A204007F82ECF4AB4CE33D78CD0B4B6E502B44B0259A4634FDCE0116835E5449313C089E603EAD7C49C08DEA8DECC81D8E2528B5AC9C98A5EE6BD58E3B60E98922614ADFA9390F9A2B6B66272024B20263AF2126C3477447C04F0C8A42FB8399ACBD6DD669AF1C805A204C2173503ACFD770ACE4470B7D683F751906B7B3E5E8B1EB6241EFAC9ACCC3AB204F4AF77AE4C1033F3B177C322B72AD1C52A10B35782631B74EB883A5CEABDEA1961F327AA53EB14A1DFB2B58A4E7B37D14B5B565CA21340F181BDE4EB3C6445AE772B07ADEE4237262DE99245ADEBDCCFE7E68F96AE76ED8ADB62A6FCA116397011F3A77074D568F38BA6A131EAA7727FC9BC8A2B00016A37ABA76BA1CC11989771E3FC7AF635B46AB69487347B6C8684885436AC1E8CFFB1B65054AC01268005C71C70F36899F543F876C0B9742E29FC4086564A074EE95AC5CB395D6CE1B1E384920AFE580C5526C713D963DAC69D20C4A96932303B632ADCB361D2D3AD37CA4F7875A5BE6AE62C333751283A430E78842CEF8092F85B54B064A558DC1D25A18BBF3C0B496FFF38B214F5D9A611019BC4EE49C3C1ED06DD705D720D58A97AB6FEF5518969F2A8605BB10B64E6FA31B8E096BAC3573043854921E4210DFFF279578D2DAFD40738F0714EDDF16C2868809223FC8BD6EBCBB3B331B1E8ADAAA7597E53E31D9E7B478A9F6E7DDA731AE9571F698A1C977C4F3401C9A05665E0B8C080B34964C15E13ADEF0348AB9CA3B64F18BEE6117D7DACAD1F08FD9B8AA8C5F47881338BAEE1B94FC40ABA11B0FB914154583BDBCCDA62D3AE898BD60B9C643D67514534FCE277087CCB66A25D345290AEE7C1B07D57D53896574CA762AE8D17A61D796F4A8270022DB314E27CE7906E4119C003385D88BE165BB80493FEE768001BB42676D2B71D58FA19199E714A0864546F2166F46F4787845525CB59B2F6F8C3E0943421A70EAB2705420BA3A62ED9AB8288DF8CA09A5ABFA64FDCD0049C61FC7B226249E0E116FA5CC0D9C2EB3B7391A40BDC0921F4D2936D368D8263791156741EE85F2C0267E858FC01E89B6149EAA18B0F8C8F827CAD5F8AC68F24FDE5E185B3223333E3A0B8245EF30B8E5E5B3E04874ED3F75A5CD25E1AB1130F0DD6D5DECF88E332F96B4F9A4C58F14ED57250B47B1CF3AD093E2B9C54922B1214000A98049003D1266ECD0F68237285A709E24704ED1CD37F3C64E15CA637D431AF5CA060AEBF5E0CFBFE464510669317944FE07F7EA48618478300725961E04EECDB73B411206EF5F3DF2809573D7FC42458D262EFB242D19F9D9AD9A8F2C05AFD31AE350E83CEDA11AABDAE85E2E32B1A226BBDBFD2D5C2B7B4DDA94012D53AA7289AE675C33E9E8F8F6F06537E240A97998DADCC39C836FCB8AC24D794AD291D42127E8B513CE0346E145B488FA220BA149A", - "k": "05BD5B91C2F634E5B8BC59697D180CF1B36A244C6EDFEFE7458308B5854C77FB", - "m": "90347D478D5D964D66A54BE930FD9F7FD3C2AE1492DAC35A6CBDD02616BCE14A", - "reason": "no modification" - }, - { - "tcId": 33, - "deferred": false, - "ek": "AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98", - "dk": "D261A4F71B7248868BE7C32F8AC688174747FA519CC3A4A5D757C3D1E7641893849AE969D8F8A6B553A1CDBA41D46B74ED9B8C8C19409D3AC3664226BC74AD96A74221C086BD3A0BACD66438239E0A8B7EADDC72ED7A453C6B7570B4C763D84883D788D8F8A080972A0635AA563842526327AACC510688B648231B4AD019B3CB9ED6F161673A6C13A6CC850A6C5692B5A3150D2A4805C0875028217DE1058132E68A97501C97AB81DC229F5804079DA5A7F353A1B999BBFE63BD9A4A4B6BC212BCC5B4AFA795C6D25541A522E3BC4FF86841AC12034D9553504217E7DB127504682046604401381FBBC08DEA12095AB71C882FE01BB95B7723F3CB196E1B8917639FC74007845A1FEDFB890F096A13E281D66B9CFAA22A93C8CEC9C9393C2BC81395B37C001D56C659D3C541AA97133D09CDB4758F148966EDD675999248CB786BBCF2A15138165016114F5ABB9BE105D8BB8A3DE8835C85A28B3C49E0C928B89512F4E380F371882C745056899B2FE465DA9130D478C46B2B4075B487AFB96DE727B88A83962B8B99D42C89CEDB5C4369BE78F7737F721AF0645263709E2DE0CE96C0CEEBA76DAAEA7757077905DA5F75D932C965C844C91F09381147C021549783A47609111965C619AA7540881F281633607F7B9983E0E2B7AD011E41CB5BBC186B4BE084CFA136B5E01B36328416C997D87376EFCC277C5AABE703C0E70C741D1809A0A36DADE7BC5111B1F046AD63449BD1C149B1C47FC18C091CF430C377A8AB0A92C9249FBBD106E7A060A4B252E1ACA050941A1AE333F2C3651F27B2CBA7C5CDDC86F0519B9F485ED563CA9E5773F72742877109006D8E9A3B49712612B5B94115024632AA0FE39A8F527891E03C97FF2C57EA532DA594C73C3B03151376702C21B6191826E7BC42DCC5D9CA2295165A85B4981D311AD1E84DB1E0249933AC134796D84166E335C478A46D1AD893325256620B2E60FC9D71832685D406C2AA13D3A614A10410A27876B1F6CEA13A88CF401242665B9051C137802A63991D82733801FA5611131D2CC745481253FBA4788E520CA165AF49E6AB6BD59B10C95CE5911B73745383D91A9E99620FB9862DF06FC248AE44C43D042A7ECF21B6E70A32660377651A24A486AB48598D1D55AB858ACDC7007D98B66D74B368BB03AA4992CA32D2483BC67050F2A302D0133F31071F3CC286A09CEB2139320B496A607B2B36B07A245E90F3850CAA8F9823AF2CA6B537439C861737348765A988256C597370954B02F44244AB15A9F78BBE9C7908701E4571B384A3147D8A4ABB0256D3E45DB5057AB156A4B6405085D31D8A602ACF6280C0E9CFDFF756A0EC3D43C65FB70867B09CBB596206E0E3C14B62188DE815544247A10122788884C3103BE557877698708236BC2363BE9C0424A0930CA63922174C3AA2585B53784D2362B25EAB9AC55AA866C8CA59A7859006937D206D6FD1AC4F80BC1C433F4A67BCAAC05221385A70042AA011104C56037FE0875E2C86BDF384772600EF391E8DF30AE370CC792569D7A5213A6C7866DB65A196652F0C699E4C57ADB90AF0498D33CBB1C6969659C22C3A2596FBAB175C992530776CB8A6463D37CD70E89E075506AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98D74B9CCDA4F1119680B65475539C5D6AD9CC013C32F7DC34DD644E17FD8FCE117743372B043D1C0784B22FE9852E14D43E7A05A19D7FBDEF102AB9743822A129", - "c": "36A6244DF4F7569DCCA35691306D2E1CE906993034093AA928CA368540FD0D1787051D491033CFFCC6805520137FD271585D651FD67D6C4B9D9BDE958892705DF8A8D2C55C426B6ADEA1F187732579DA8F922D881994BE04A1CFF591F669019FC4AF9411FA61BD3DD88073F8E119C67BAEFCD221DE8230E8B6D7D4D739AD28A1F6B2C9FCE301DB55CAC39778FCDDD389A44DADCF65513AA05853A88D472A7E46319CAB47E3AF09913623360E1ACC954BA17AACB84486F81B0FB34AA3966F6796293EB7F4233052BAD3BD2EC9B1CE1079D8A5C0F9B795C9113EA865F62F1103260ABF902A5D6497BA7F74D1F0E5B2CF564D5B3ED6E6D6AD186F07B62FAB78577CCBCFE6A2DA803E9199785EADA1B6675B6846535FA157166713D37A55C8A99AF87A4038B2225C3E55DD21557238C96226D618979A57204F9EA5447A57106EE6E6E8211C30CAFCCB709B3CFB42B3F4A538F29671578B66F406FC5A6AB274219A58629DE5F84C55AB1D8C39077A42342A1A220C65D5AA8BBB0097E3AF13A03166823474F0798D4D0B36C8EE7C2F71C665D49AAF9CFAB1E72E69783347AA4416055DB68DD30B31C604799D970430209A4F73E70ED3F8FF056A8C9E9F8064766A3CC31304DF31AF27BC6A5AA9BB6143483A89DA5F376EFFD539CF90BF120E8D8E2F5753F99D9415D27E79FC888907325E45316CF5975D717690DE4D587B4539CB36008C127205650865376B78FC07CF7F5B2EC247553A116E386307570913C423F6713875D532EBD576B440E47732FFEEFA7EFA76F29ED763C088183C08471AEB47CDE561D01FC41D063C41BE58BBBAE2EF0C1DBEA24C20FB789697836E0BD63FE39F914278C75BF6CB1C8B1A73F67913D56DFF3451834CCF02B57411DDAB251AEE7D939DEDA1F3CA918B76F6757241E97F068F8D4024731258CFCFBB5CAB90DB10337D2FE85BA4139A329B1BC44DFE1D26D36CDD7E43A62DDDB749098AA2F403659EE15356FDF8C23FECCD02482851310BB702031E126D1D9AF109B6F2B452F65B685C85A67E97D4658FC7D551286AEA960FF348D47F81583B94032D1F0AB71997077F8D119AFD039B3D4DAF678A9EE0F23422B90F6898E39E8F42C6A3B2D7BCA38364EA6BDD2277A8FE32AECDDD4C2822F78B3E0B7DBB0250126D4A8F813EF6B6471EECB3B48753439D099E2B43FD315A259A5757D0DFFF298ACCB6EAB59C964AE7FDD3FA35630FC7E72CF9D538F226916BC11250B36C24DDE8404A5F4FA684321713E57AC84CFB0F1DFB813102E77ABA2D5D77F789CCDC760F75DBF26827FD5833BC42C9EB86AB9B1C2E4DE4E4D5D257170D20D8673FB0E4795FDB5DAC063EA801AC14E67C8E98F3DBEF3F3A0059CBCEF321AB5A288A4BC9B093F0FB958CFD8694E6DD9BD3F37344A9454AC4F86D1CC5959CB6714DAF0116338479B99F251D5C2C8965F3CF1B4966348E1102972AF4FA858B09F9173A72A1ECC911ECA8B578BAEE37F7413D821655F3A207B6DBFBB7FD7974EAC6C9923DE8F65F3A4F8321D16B34", - "k": "4EF33F2E08DB26B11979F95FF6C624B4168CE9055FD31390EDFAAD5E2DABA6A8", - "m": "119BC36B5F856C0A2F136B3EE42041B817125A600E829FF6B4B402131A26ABF1", - "reason": "no modification" - }, - { - "tcId": 34, - "deferred": false, - "ek": "463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF", - "dk": "ACE60FD2C1783948CE064702818B3CD0DC8151C34BFE02B16DBA87042A58A26286E6E20D990C478CCA9A56F729F5F34AD28A85FAA71F8B89C6D188539685BD873C76902229D0C982039A5B95DA6A91C7883E1AA82C81834169C74B45A021C04A4FE665EFB41CD07B660D9478D6F831A9BC70ABD757D7BA3790E559625186C197CE99E6979640A60DA017FCC83351D955F03A32B9234CA6CB226331C5F5A342506422E3C099FF702444659BCE0BAEBA2194C8089284F8A218C903B368C563B6A05557402D30BC73EB91B6B2A5626664E34C44B4A04BCA0187B7C733FDF4BF02A84A513753261646B01BC4F333BA66EB4D710B6884A26D2AFB3032C5474E741940F556D9F963B97BAD3715B6002C941833C8216B220600B57A2544AD497D5E5029E0A0148146755F0A72E1205AB7FCA58E31256C44178F8309F6A81FE9FB083F019D1C4407BAC85EF6264B72531C3BD5A5F270A68884841E190667759CA884478F3A641F798057DA702B998ED17C18D099B71986045A7B5163D72C40225B0BEB48943B444477B56EBABF34877501F94477CC6582B9025395B387E23D41321D225065DDB933E2CB0C1C35A927619BE10217DEBA2A812A15AE83AE46C9B22F03C65C73B108E571302CCC7922AB500C3525F34B572946309C7FAEC5930122772377BCB1B9990C3B1DBB19051FC4805BE809B63A67B5D9096F7693E78762E4640A2C55C8A4957C8B1130A3C464F2B67AAED0191145944887CAAE29C4595C7FE9B4630706968A6B8AB79AAB481A31C1C02E2C46A43CD69D7F5CA1CDA7AFA185AECE69AFAC3156D7F1470C26B812C7453DC724B94A809B94A6880C02DE987247EB777D451645689969F1450906B82949273A216D60C757E470A9C6C6415A8051B33049B6E82885A78A12FA4375A323A686CADF08C5AE52699F6383C1F6B27C558F915B0D2261927B3C24BBD19097A19A6C905544FB664BD766074B31C870140B8840B1E73F63A68D6A876C40EB80EA96563A469423206929DB169BC80B749A1AB26C9EA4AC44B2AC611C51910B9300636570D79C362FF2571404622E6510AB1B9E6B2530E9E420D423579B5802BE18913F8CC06F3789E74C69DF8C80FF451EE84603868523581438CFB9959A83BA0C9A6C5A629E97C867955B84BAEC4FA36597BC2999AF7638D10BA3F6B68C3DBA1F5828B234CA83B2F14C9B7281FDE8B7A318A00D1A3E87DB04A94091F1D0A326858AB8BB54B1F27BDA8BA3E7C75C48B03386A06903487CA830517369120B8103E86809286C92E6033D37F5C6918139B8CBBFEFA9871B5934C16B6441635E7C478C010A554BD4CBBE119C4B77062BE49F0FC301D4D6394AF0C5518325C9C327E8E001FFB78D157940468AAC6B8BAA38A20A11F439DE402DEE5856A5866EA6A9B2FF549AB040B3F4B43772F89F66138B543A644E6B337850A09D7A747827473406A82973479C1700CF72B39C813F8EB51B4DD04B13FB9D945C42BCE147E56074F30485F800C63510B634C08BEA128AFCA6B4EF543724CB6CABC6B160DB957490816BC8C33122C2923B78FD87BBE1453C7DA562F185289C56017CA572DAC0AA2865499FC0322DA35EDD7919FD9A20D2D9C1D1586C8E5205463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF885E38C95A03788929E70D0A17C2D4E23764EF31D826BD4E78F114E7D8F056B2C07BD30B423B29EC3F26A36A916A247C45D1C67392F267A9C3CF0AE0B2F75A56", - "c": "434A4E54F4450AF0673AE77E391B9C25BE63AF58D3F65507AFCC28E6C17B8238585085E39D89280C7F8BF73948AD6A543F9A5A73D3EFDC039F654EDFAD6B4216D60E121EE433C9A347DF67792F8C99169066AD7E5B19A3F4236C240C506887E2F98EC51C565940249D992006D04CA1391A433A43EE2C8EDA8C54D4B731A1570FCDC0AEFF0837D42827D2570AF1A9FA900445F51FCC482F0AC088DE5D4DA40015535EFB350A8797F62DB7DB8DAA0B96ECF6DA3024EF80520533C6E394A197BFB22E91A38E7F6A7CD7FCB4A7A78C9510144D42E94C3AC8B2F0F6914C11078720D3B9B848E6BC211D56447D2FC7F20F59F4C5A72716176CF2274CD82DF2FB2BB0E634AA0EFE9D4EED10C790B14754A54AC295BBCF4DF1A129987EAEDB0DA0FE3931888C9F0EAFD5399BD91A6036B7169C788FAF63FF8ED16DD3A92E8040FFFCB6487DC15B734297FCA279155F365C9AFFEE13EB303B05C52F6365D8F64D61EBCFCE6076458D80E97D325C12B1B9FAF46D8B078DB977963DE5DD75A353C1E7FBD9A1EFA97A6F10AA77B65FF0FD699D2118D6A9ED13499BA2FD10AE9513F1417F6BA75448D7490CA487241CDD2D3300677695095EA755495F6327E92257FA9E29A39793F4E9B8CF6E43E0E1D6EB4620B523E79917C0C328C3A0C55ED76B16191AC58325C32FF4E6E4FA570F2F8174C2F21A9A6B8B1E82E2F7E0388CF7BA95AF70C7F0884C4D2876C3C6E479510520D62DA9D49F435026A401CA1E5E6D5F0DF062CD34C8478336BEB3073D38EA7F37ECC969545DD503F4C10FBDEB112C947EA8CA38A180BE6E3CE1095BCE75EAC5BAB6C436784E83DC03A9CAF1D90DED7784D97F141E642334FD2B51D957224278948CADE3885003777031CCAF8BF81D40C9EBD7127CF4AA9FD983A2F8209EB7C8F27360123EFAFA1A5ECC2B5C07CC4F1F6F5268BF0655C9AF176E0D6913BB5A2886D74DC727C8B72AF1721A4F75B0C54A76365B87367EBB38B7B294B8F75019A2C96E1C5D62E782E903B7A772589410A84857F565939018612EE18E81D535C8435273E5ED6ED28FF4CE7734D643501EC0330F3C46A11F8E17A2E8041D4E0F0F01B7B865ADCF440B7313ECC1C1D5E956AB82783D89A635BDBF7CCE80EF21D3151A80A83FA01DA706394592140E882B8F86A36D58BBFFCC897F5B6A26B1AEBDA91B56EE668EACE53E6DE716939B8FEDDF0133849DAFD340B3B658778CD9F6E7BFA550463903E46C9BE92EA6B6AA6327BD197EEAB7F8DA8FD7CB0E1C4A4FF5D4EBA425D647353549C853621D4B617CF2301CD6D2F2BBEBEF733D7C403F3EBA5F3FA504EBA0069C4CBD4E017F2A0F15750D89F1A0D129806C6466350F87F3939593DF02F211A2096EAB5C917320FE98173D66DCC57EC74500FDEA7A56D011C32D60007D2F416FD1971AB61F2BCF075831F094BA7F75F4DF07525D747E4A313F9388465AA0A9448F75DE2524DD4012A4161982B927F743B5813F35120EA5BCA90551DD3ABEADCC9AA7238B115DA518464E51526F213D4555", - "k": "A2F646AC5A87355FBFE9A37E58F405420221E523844C9D00AB089EFA0FABF280", - "m": "697CC7445AE2C9ECCA2569B7871F0BBB364E63E4B782F734FAFED4FE33E4AF14", - "reason": "no modification" - }, - { - "tcId": 35, - "deferred": false, - "ek": "0387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B", - "dk": "030C762257832CD05D14B5940C483177EB3ABD152BF255C7E3131FD131867DF38679D2B554B2B397282071344DFFB7729FAB95F893B912D15B3BF43D39A97CBFD50C84D83C0D39AAAC921827981AD5D0001954369C3344FE869EAF7A45332334E4F30A1B94350D7951A0E4549612AD016528E2C94128052A304A87E2E666CB101E2F765ABFF89C17F1823D211C4B4355E1B734BCD42326B1BA24491903063B2CC18ABE453B003389C67590F00046D174C1C8B237A60AC9FC78AC381C11C358B37FF7B791FC1560D493630BBDB3C40CD4556B9E671B36814AB439687CF248B0CC794C491C4DB2066325257B45370F2CC8519071615BC73095CA69834955131ED7826FB9E89E56926615730EF1B6C4538B3253030578F63BEF067C0EB70CC4D08FEF146488988EB2EAB0648CBBCC4C163F129D32318536CC91AE103CE058318A9530AFB73EABC518B59AA546AC64B736167AB41DC27C8BB21912CE011C50EA1C4315A5A480183D9616ADC79EEC86B813D38E449B1FE0BA07038811BCF63C1EF57AE6DC2F58BB522B51C356901501A608D547B2ED4439C420853D1BB62E438CDF4CC179E760CEEB0B35DA53C0606E7AFB4BE14B5ACD9B7DCA6174D990670A8BA5F5D391B22781A051946F6B33B7D098155048515413819A0544058265403F6272B6FE4625A78A0F4196871578A6DD041476D0339049B1D70A2583E6514E089144E32960DBC233CB16CCF5691B8A5A1434B42F9B9C73A7BDFF384CCD952A79C507E5A4552FE2ACC3CBC118974DC0260024951FAB3A8347CA016CC220E1B8CFB22B769258223AF300639C5F3F2387D4B204C802BDAE8179222B4D8626C88E63BB74E33C7D210F34749465991B38844AF6A43BC81BBE232698B8CB8416BB55B385CB23C086ABD92F59B209ECCC9C4F660061309815434C5B27B6B2CA33918B0F97A813A59B007E57AD04B24D31379964D1923B218CC79798EB8AC65489B9F4ACA5097B248D1A25FB5A3C44411CA0195B02E0538A7B9A89EC660F2B796FF39D42A18E7C585A0B737798C75AFE74B1EB8941D10831012841CAB389A1DCBFAEC211F3535C34EC05F07619B883B3EC04A4CFEC19E4670486E57DAF0C086CB0395B537D06BC2955F90684FCB38D17B0AB43A5061659C69A522B2970F5579A6450AD2DC76163B5480F89437F5B46CF74AD6A85961E265F595375B36A2C96C52F80D4246DA29BAAD2A18DDB3E38F3C9C18B8732123299A00F689B1E32C492ED24280992CD5C8B3AC3109405A631C5F49C77D97158F93F7473B263F8B3395276346156FA7044732CB5273B27715228EDA6C53CAC9165AB3325622BFA9941C0F93913CB29D55A1A4C1404C8C8025DB6A80EB95B16E80A0E348D8EF54947E6CCC4C8374EF14284373C83B677D83ABC9B5BC0B7C67AFF0664B0A2786575B0A2A962209335D13B003D013C11C68176B6C3337C920AB063D12331D2D0282BF0B460634A3F823F2EE8776E4088D33651392B7E16BCC44E46345F2414CF175734286A73251C6163C1B3F60AAE7A1A3E478EF5E56AFA7C3391F7B0C4D380A1A60DBA7ACFDA1155975C1FCC7603929247DF2B8040A12D63369B54849A52F41B2AA77A32DC867B7304E092110387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B429A81D1EF4BA900CF2342C35E355A429B5480869376869E37EF269561E028999F094D80AFE79A90E314F0064F00819FCA23920F563589055EAFF682CE66C3D3", - "c": "DB1E2920A7C52A79F588F79A711636149E2D0FEE6FBE132DA3F0AD98EA4AEDACA476BEADF3CF1D6DB5337430B833AB4FB4ABB07A0F05A0874E80C3CBE9BF0C044F711444EDCFE6D0F168BB56687CE965D35FDD06E1E4C5E004D2BFB1DE6767BC41D834DABD875A15AAB03F3A0F8155495684F45AAF2A28803F50C994681E1677FF8A960B3864B7E95599FACD1ECB063B54837C0C6F3D3C39C7183601251F6CF3156C8F544D789D28348F2F26513766362D6430AF36216791592C2F496D77BBC5B1793047E7EC5561CD7393AC4A540104745EFC932D744ABFCC302943905BCC00073E19509CBF876699095CC53425B772F8567120C662219A40F3A818E32756806C0A283D949AAB6477BED8C0C4E1E3510FF96C929D4173B38B10E6C93E5B9B98914FBD4809D9B8576FB4B403B199117087668B19799B19E3B830E132F98DDA88ACE8FF3154D92233CFC5FD02186E13DA50AC91C6CA8E1CA486BAE9255A57FDEF5EA7DE7C0703E5093493F8D0E0EE50400EE69AF8EBA22FF27C834033B39E0A48F81E58F5E5A7D801B0BDFD8B57981AF14E7267A3C24F897F97A6CF2A4D2E143707C49B51A234C54EEF76DA73C5681F302E272D195DB2C52A79505387B0B6B0DDDD5022ACE0AB94AE87A3F0B6F1663571EC9F3494163EF107957365778EBA8E0ECAC280DB5197C6E6349DF677D653084013578D2840DC3490D50CB863360ABB5CDA3A2DDE41992FC9805B8D418EB4BEF140F199FABC45039AA26697346C1C4A6D32E8F52D4077E4081BC7355D3E4D8864B98F8B9EF7911EECD44C5F3587827B7E8B8E4870B67491B61104A9442CF662FD0A9BD795FBDD5C364ACD4B40300B60C6225D6B6C4F5994D86B9EA4ADBA280B3781C11ED11F9CDEDCB03BD372DB567279D332C794D3C5CC49A335C4D8E174D25C4EAFF55FC23342EADD9F55E1D180B88EFA835286DFCBE8CA28D14F6E4C900BBF80A693A32D8654FAE9819612A1DD9C3C08C5B5E97F3F8E74ECBDA90E5DD8D661E2C81ABC2BB571F977CF86637F06E0CB5E9EBEB9CBBE8CEA5B223FA6343A7CB7C8F138364E9E4DC4D1D4055DCE415A682EF76DA70679F72527B3E913EF12A28E22F8609BE456638DFF0756BE30CE010262DEBE5B8A1656FD5823705D9AF35666FA6B7B1E43977B0AA229C8343C45B8BAEEC0F0833B1A2462A19E78F4A6B4A909BA41FFA10C2FD8F98FCB0B10E75B1E2EFC54552747105AEF1589E8BB8BA7DC9A2127121FC63F9834F0FFEAF85D87D53FAE1BE362B394A8574701599A8918D855D2F39A798D6A2268C984507D46FF978F1DF46F2752D6D593630459E9ECF827ADD4693CBA0D6A22DA6ECFD6A7A2B9B2448292C850EBB5FE03C0DB452D7F06278D779EBD87FDDFA445A387A2F40D040D9F97DCE88E164A766105D95CF2A91CD85795A09F5299D5C51AD28FED62F4B67186185FD52837691956EF5A116A1C37B6CEE25B59025A319847A4EC9062FA343BFAC0FDF62A9C4FAE854823FA0D8A906632DF5466DAF9D8B631DCA3310C090D9B7E", - "k": "DEC4780793A61DC6222167547E251BEC419B282883B18F9BD06E053DB258C174", - "m": "52CEBDECF06579F4A9351F77CA95B5CEDD034D812F3FB7FB50320CA80E4118D5", - "reason": "no modification" - }, - { - "tcId": 36, - "deferred": false, - "ek": "82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B", - "dk": "1BE898512189156358E1203AD43B548D039403004E5A5287505054A04B6C9E13B13E76332AF0B500435505D8C9C46B1FD6DABACBF58258479F0459BB13F5977A842AB7102092CB9BF67C3C4524AC2D25608348756529C8CD0652D5E1BCE22A1C8BEA2A72655EBB6A4A25C95A4EB242C760091DA949805A8F16BA7CA0874E01173D873590EBECC87CF79B103096574524B8149BBB9BC4A813AFC20C2D11ABAD8802834A362908480E76E79A3BE55ABEE3336326184E9A7B044603C4A5636EE88FD4974F82511926B95339AC23001B342041735719AF81C23A003C540DD79F34584A025429D477B7B4858FBE4A9D01F5572E8287385C5C69B0223296924EE27BFBA2757D5B11A194803B1094ECF66267411052BC0C021A77C773A940AC08487B90FB33631AAB5D9190AD613C6F360216725505178952CFC63DD5737B1917A63208586E5ABFF7EB03C9B7066B190C03B6CF77048E2D222719D8517E707DA6AB4FE42B4058161F7DEC4145231A6BAA9FB04C638898081543503A5CB7488C77CB0C6D39E45FD793B38B9019D7216C0027A06729854F378C7FFA6BF599A54BD290BAA60A92FB60CFA46BE667C052C176DE9A1C526406566093B4E899E6738C05595FDEB833BC06B3C5014AE6820082566E65AB9F55D915FB3B0B2E560EF2675E34107AE23BC746E23554996DB1AA94A6DBB20A0B43865A9907D644BF46C2F8E5BDCD298BD78A214049A69F650055725174FABE4CD2309A509BA3CC96EC611BD0C6BC5677B95D0B3BF3A51B5BCB06780591B60A0D22291922C27DC9F24C1EEABE27A704463B5F52829DB80CA0EAF917437841C8230526930705EA5CE2BBCD6FEA79F2F196E7CC74A560B13D48C7A2650D5929C08D53168145935C7638103291A5B2518314AFE8819088A25205D17F4ACB5F8080A824874B5DC559597B24E7D706AF510746EA651A3B66137973E163CC96F13E0D631BC696C451470B4145B073360EC034A39421626FF7510C1B88518262D764CE8D342720674B368C8A17F96F992979EFE25272E50402796A2FE59B3AA37EA1E63640B470BD0763D40029CCE3C54024BF33E63A8FE313AB9549E4D32A75C67D21E77D846AC79BEB704ED576C914A866359EA64A548252395E5A873805472C233FFAA6B5766179E0B1CD83098A16971313871762E531C7AB2483A1AF2C19559633B10FE80053504E5584104082C6B8967E86D63025BA11949B6CCC10BB52C93B032936512166099680C83A90E0EBAB162723208AA16E21418010C6C8B79354422695429F382380B08BAE2138C6679958A7711B78362DB5E087BD0459F27AC095031CA024A37ED1624638A7EE4C54A89009888659B2C9779EC4548D0257EA03CE5ED553A4DBC6C8BC7FDB21017EF4353EA450D4B1548BC65E42097B5C86411693260EF44CAB02A008158BCF81CE94388E87BC38E0BC1261544C8670A9CFC954458C02A310BD00DC174C3C1F06326F9A34AC0D2B4D37DA1389D31F83F49E169CBE4A5B742E475CB6609C4CA9B90B584B664741FB97BCDB84A08FC6028317BC03F2C0EA665355E589BB24448F3222976A59426A93E4711072664DDF616D5D5C3971EB03F2D4076399649F11CBF23194208C0D82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B988AD4B51E1589D3379C6D3E70209E6EA8655AF17EB0907869F974DAB202F540A54A288137BE236A5FCF6A8FBB160B2C2EDCF2F1F63A92F0E985CC634563DB61", - "c": "443DCF704633C6E74255A6E83F0F4BB686BCD9CEFACFC536EC6292A2F4D70C11E4F9FE4A94F4B8E92548EC234FECAFA84BF1372D7858C554BAF1E2556865185C02B0214E950F2C30624E5E42FFD1702CFFC5045F3FAC68E8D2E48063F9402DA21E69E49A1E9AA77DAC5EA1E60ED77E8C498D70FC67782EC17255E0CB7E116DC75168A5FC7C08A2D4A974A71E08A12CE9948A15631A90CE034C04ADF9E99F3B93D5FC4B2C9E880018496F8C92D40181C6A47E313DB9565B377BC3EC2D5ECF0D43A9ACE5EB0439A230DF989A01A662D83C8D2BD7C0A5402ADBFADF91507A8313F1C6B7D705E930182FA10B91FF7359C0D2BF26317015DFF6845E2F4275C76F5CA9F115BF90067E95EA7AA2847F05ED50897F62CC8AE42DAD71C3CDA04AF5FBB756CB7F11C78794F8FC4544D8B3AC1E9B44B545AFDAA2E7C5945E11832DD2D693952F51B87837DA9049D080843D1A4CBF551227822A7B522F449C974925886961E7FE0849790F9B2FF8DF8D0D741E9A1B8B08647810A64D5420BF795E5EA336CA4FAEDD55876E12FA6EEE591AF0F1989D0C1E1CD1252A305467CED0B12766D12316CEDD93FA773B11AA9BDC9D74827C30FE4AAEB456B8AB700D4AF165F13D8A0D8AAF741C445F341628AC4F4254C96063A6986A5851EB19438FE9F633B131029545A2665093F2972678F62EAACEBDF7A49F3D4D67790E4142E2B2A0AA57327ED89A0B9E641CFAD529F61A82ADEABFE7DE1C0D7A99078A8C1E7A00C8CD251B9EB8ED4997508E16AE39B50AF7A132A6AC83031C7E0207E894AED90066CA97F2F616D0C935738D18401B9BC7904424DF5756525EC5D8358EC0B9AD428D0EB195541A93E75D35FADC6B0F8D5CBC8BF15C9F3A7C22BF95A4D864D011D6944BAD207A27E2B05C8C51C6686E9164EACB06D3C675642575739BEC34660A31CC45970C28954297FB37B4C51C4B3337C9725E5A6F1DD0831A8A06B4DF2F445DBF08612AF2D65EF19594C4B3E3F034C5547491EFC3AE9B34A47CB2F35159AA21C097A2FF9CBD66C7A50143DE4F7FF9E4218DFDAF52DAF4040EA17B8F1616E590699FF6C71C37D1386806B2F36E534195460E2774D475052EFE3338B43F8C906D3FC0A736E103FD192B4084F6311F34A2BD162C0B2B9A60EF6F3468E881D7CF56A1455B815F2999934311894F4EAD90DF175E60F56B56C1A2BEF12892563FA216D1C477F061C46DCF2CC056C5E972C5F3018DF6346983163FA7C787EF85BA9979E30AF9CB4C4E2A0F4DFD6EE5B95AC7F8ECFD46E7491B4424C22E82C521F436E4656E298931E3791164360A0502BEAE7654D43C3BCF66B2D69B5E2EDF0CE17961ADCE8A600789E6545AA31FDC12030CCD478C82D1E319F4DFF1681B1209BD867627A443329B48FCD884BD986D105772CA3786CD336366C0DEC0E9469ACDE5FEC612DC24862A7FA00D45EBA7019D237FBA37EA67A4A074C652E6EF910B2C206FBA0DE6D23CF8EFCA947A18737410DCF14E496F64582B06D78FCCD7538232C4D8F122CD9FAB29568B", - "k": "9DC0B2ED91CF4609FFB8F7240D6CD3F65D45105A35770A105B910BD9CC911CD1", - "m": "161889F2E92B1BB28A257B45D179FB76847B664E6D7B5FD9698204A426EE96EC", - "reason": "no modification" - }, - { - "tcId": 37, - "deferred": false, - "ek": "FC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA", - "dk": "7F7A7CC42A00986601D7E76792ABC9454422BF39AA4FA93144980345066236F60D629ABA3BB74FA79718F0A95F6434508A9B0F0BC672D4F5152A8561B8674892BBCD79AC8082394DF7E95F7910C8A2945C55DA8D847B5480B34671E20532B03229D51B2D9A3288E867D59A9C189A8686295D2604B048425331700FC329A948236AF5A83E9DE525417BB235604C43B3B2628642CE11B911A2A88038A5FA233555B3104BCBB733E446E9455B9D1A7409357AA19656F23590CA11CE05336B0BE8406DD39CD3B6A725D49A499B1809791540A948D72C56623A768C27A32826744D75871579B85D16695905BC62744885929723F308D4870ABD61B7EC3CAF86D2422D6C53CBF92DACB85AE49622F6E37B96F3BA812B26F0C1220B4C4D37A9BA4032197FD4025FC2C75147534F28CC8258A0314151DED61CB391B17E842FDE96AA3AB89C2C13C6BC015EA2DA00D12877320B4610C34526D31E2C7A981028C2C55BA22479A62F375BA7400AA4076617258C1E5A35650312F75253CCB11B28FA2FCF170FCF9A96C34385EB181C6D777621BB3CF6081A8457A7B92C89F0167B80976CF7512C10E1662DA3018AA9129E3661A59ACD85D75BA9707CECDC23A9FAB2DBD6AD85938DACF56C8FA27C2A7BBB520CBACEEBCDB088B65E47B9687865A231A393D645F080B61BB288C9166976208FAE67B8919766A7910BE02BBFD8586186361740926182A3ACA832B2151B5FB01A0E726650D4E92EDF59BA973446E4C886904919D07A8EB67267AE366D8FF6311C78B6F17193C655B46F51CC47E05B4D3416984CBD2C14AE228B44C1141427876AB6818DE42807FC1723B3BB2266418219004E68B59CA71C5C2B8B8C6D7405A0508D6A63ACC2B4C19E228F943718F18C8C743A020BE75DCC1B1CE1F1793FA52C6AD5CA3D63C871366237DC82F01A837A758D9005CE677C9E1477CF5B49A2427932F971821461593426498DF90AAB257A1683355DAB67FE9234AD2832216AA0A2F4690E0785A08459A2809717DB7A231C3A5D84A98EC91A446B1BEB8851D2A65D7D61569EA98DA56C7A2CA24C71BC511747111FB31CCDA0CB391638BC3126D4427ACD9171D7D2A79AB9815ED62C332ACB36335CED45411D1545E3832B52685D444344C77325F1372E89F254F5E33A1BB450B1A54FFE32CB4811B813E27C12EB95161A5A18105D2D937012070868AB3975D552C056267F0946E1A5C9EB585F170CC5A6A578405382E030A2A3265F468A9911341F7A4746B71C65C090398E4443EC6AB4486BA36788AF0996AF5C6389EB31237CFA0DC8C17132051A28060376A0C133FC51F6EB81BC035501952164504115F8C567B52E96BCA0FE13A2BBCCAF08637AE31BB4C0032EE32514E041C2DC4587684027D988133658414567328F42AEC2FB89B4C830ACE152C326443D82687A19C87D122EEF72C1E742BB4A8C52B81646CB0C487EDB917A122B44751F209489ABD629A0F232D0502DF7A5BF5710215DFCAD13F2B6374535A839CBC9A505EB3A9E8EF17B16B70FE04752C8E1936926BBEE856A188C02183768217293656C4B1E9372B363BC673110255014FAC01ECF6B48371B8E7E401C01E1640B8A4F1C3A4009489FF2D46BFC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA1279BE1122713D340A3C86B3CE48C6C5CB5E48522DE5B24AB57F59FC341BE6ECC2F75B1351CDC350BD1726A124C06B996F566FF820A4D3569F634D564EE84224", - "c": "58919FC3F7105957A7599EC0F84E2A1031F42E26DFD7DE44CAC5B99E1272313BB2A6F52B8D33C9054B368439A123AB49E75C7B3FD397F1E6B962126FEB574D0005C69572CCF752B10D9E84569C9BCF3F3550784AA1239E0B4B4FFB38EB5937B287B5C7D8DD0FDBB38E3BDC081B43FB7967E7E35D8FDA89153AEBB7FCD7DD810738A555C653B84F6BD246A17FE2EDD0FFA8AFF151EAB2973F2F8600FDDE69B61D06EC99CC547D4A81896A36BA9A3DC66A5251EF145C9A690B2C696C165FEE89B8C2A14ACF8B5A12CBF2216118FE3B29E2FB0F194D418BCE181B096FFBAA4AA515CD45275459BC5FA6E1D1ED33D00609F11DCDC5247FDFE841E01ABB7B935BCFAF9960E7E06C82463BD27BCDBCC3D12AA0F033BDC4605109AF3D7B270FC5D18C3CFDDEC2CDBB3587DBE25E4B0E9AB2049ACFCDE49874960482CD25DCF45433179A9BB69145DFDECA9AD2D3BA9AFA4B6B8681DED8DEDAD95241557BE198A7CBBBAE937F70D7FC513782258D89AE870FD2411BEE47E4993B9BC1F66852E4D314BD54C848143398278F11776CD8FA01FF345E606A514ECF780AA5EEDD94B7F88C495F8E56FEE7FADE2F6CBD3406FE540428BF89CDF66357A0F5F45DE330D9FAF72F02D41D9BD7B6EC9165C70386824DBA7E2322A0409764FA9DCA366B4A9C1D3E01495806F959D13213471978833CA2BA501C634322E67CBEC59FFA4193E848025BADE1971035636CE8CC833047EACF669FF064772647AF66CBA4C5C87D101C1EB2EAB87A8C3CF31D6C970E846C8B50289DD1572B19705CCA364D2B3090A75AB299749D0A320C2260A686DF569F802FDE0589799BD54BB5FB8873ED15CFCE76CD20954E52BF7B3DBC68B573EC0502F3D6715C249486B5691F91CD11B4A7B3CD1ABB8C942E2426B0AC782B306BAF6C0D9F2E2EF53FA9E142BDDFC4FFC6930084036BE9E51D997C8E24F89556E0CB21BCCCE16330AD104A8C6851B2E6CE8C58613E19459E2C2398C9B33A5FFD19CE5D9624344C52F379AF49F04F1405E9510598622B9C6F88E95DEE43A91C0540661AF86E3016BBC2339C2E922166AA2D6ABF987F1E78EB1E3CA9486380E62577FF487E1E7A4536C7ABE7F8FC9569E254B96BBAE04DE314F7D5C36A388336D53B9BA8667350C7F3A04DA68BCEA28BD95C52D14E1DFBBF78C8CAC150CC15D015E4332FE109E9FDAEB64BC3A400599CA3D2CBD2A720FB35675A5BA78BE61C4A82B4315D3AF4FBB0150592B7EC135E063CD5D7C23CDD256D4501513BA576BD6726878F2B43B64ED0DB79CEAA344365617570A1E7957ACA8F5B5F2FF708190B2A4985A6101CE0475DBD528489F4FDD8A9E4276CBB7E6FCF74866A49B430A666C4DB800DEEEABC4E7AE9DCF6D91C421246F91394B949575CFDCAA8527CB9A4CE58CC1A53C7FB43193FA39E4C12EF8DEC1F1C6CB8134E5938AB23A9CDADB4099498F5F39274F10228FC297EEB7BE6E392F00B092E70B0BC262F5E8720E87C8BE1730E22193290DC1AFA0AD2D98BA6206AB3E7B63FFE6C69D576", - "k": "D8D24017609D9ABA1414D18AD4AC9E14A0954AC1A80AE9F29527351898F61483", - "m": "3349557DA70FF69886ED032A91D8FC23BE9E5245406670679A6E92AED870D369", - "reason": "no modification" - }, - { - "tcId": 38, - "deferred": false, - "ek": "ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B", - "dk": "F8B574AEFA5362C79AA69AC10326288D0571F154CB001C7FBE1C274C1586792068209CB65D70CFFB21947ED752EBE9B7D72502726C1DAA9450FCCCC3A4C4BA0D1890C530C601C18A7001B079684EEA47AC24251E9A599967A24EF47B52B4FC580E995E411237C02687CB38030DE74F3EA0C1740316269322482C64414A8C73230A3B58554C57142F2613D190BAA3142220FC4D99A5806C89785B8730B39C12CBEA94F69573A61999C82B7E4BE3A9B605243D25971E24B330A7A51E5681774AB7120C13DA25ACE8494019192F8CFC3043628F7E6B531F8886AB2BAFA1D39E09CA373AFC1A46919F8244066ED1B7C2124C01D760D216978191BF3573C093A15FEC579D83EB5C6074B0A4BC13094232857181DADACD2C5A4AAD97C016894EB413C2CE671687A875B45CC1BA0C63D9696C4FA102BBE797FDC86634DC28FD121EA9D904642ACFC56C2DACD2A7BEF96A43A23F11591EB81C954182403416ABDA87BB5AA75D510007B8D53491E0BEFD149658AC135D1341FEA37983D1A0EA0B40CE08A2547122C3022AE2DA8E2E7BBE8DF46548A91A50A1C8FE651E8E487788A2AB894B7912B15C10D09571E23589D166C989329B29349CF7A037916B467AB29ED59CCD37AC63C0AF6F335F5FD6BC09845BDEC1C86748BC389889425026E3105DCBDA9E4C5664BC2B75208287EC78B8AB031B6B494B37D51B0F540B4BE0360BA4744DAA369FF384C1D5BEF1640A7C76C7FD4743C7EB631ED126F0408809E00700120CD6DA114C5211521C067F1C7EE001AF1AFB46F7DCB90D70A3A35098946A4EE53629CCB678642A11E18B687C9680FAA3AE926C60A5672A0C786F17273C313548D6894B27D52AB5F51E9623B4B03398FE9014E376040E522178185230456D505BC1026AB91BCCAD5B2C38ED2BB445753F30845A65A816816476BF184CB55714A64375E480CEF74917E616CD50E7AB635A88D96414DA6710E49A468C3AC91B85726536B78C9B93DABB5866998619B377BE0B54C5B6AAD4940156C549782C64653A68FB0B15E02089FBAB37955104BED20696C48E388257375C080C33BDEEA081EA3285F6A94A128736DC221C17A88CB50A6283F4C6684AC0FBF8C110344DCDE703E4A7C3DC49296AA684A31CCC0DBAB7EDDB2EF9C40D35A42D077C62ACD734BAD82E7475833A1527222112739C8591F61D2156BD6BC886FE501873EC67061C3EBEF03427C969647918433088C0C8C7CBACC9CFEABDCA3A91AD17A2F5AC8C9F195D53C294878529B0B9C8D310897C09483B3C46A841CBB6183107154E99E7A91DF44972C7BC7162926C9672ECA74FE155BBBD4160D039821049A8FDDB91C99752B99B34E122173F654CFD5C69DFE7608CC96F7AF1A0B8476FA4B715E8B81F01E24A79565D01005667DC264D31AF87F6777E118EAC48346ABCB281523E97A787194B6A6DE33362F31117958C1D35AB4C190818C0049FCB6B42151C8F038B8018B997CA0E7DD9962B0A62FE38A424C06A4E650E68191C4538AE67B1C3E997627BE3B26BE14166F016A8E80070CA86B034ABCC358B2CE917FCA34CC2850920656E80597A35936B28794C63FA944151C0CAF278CB589F86171D0F263767F294A71B6059E496ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B3185127E1DB71871889DFF67F5D4E97656F7115F28F00AED6D032FB3816189C9EC00525B2D58F1FF5026A6F9CEE39EF8DCA115C0BADF3ABF3244BB9FCD113DD9", - "c": "0E505EABFC938559CA3FE4C830365B6EDCCA3FF29E815FB9EC8CF1857458A49E461FA69EF81E5C2EC80875885CB2FA27B810375368E7ACB588915944CCA39F196EFCA8D7D8DC4C7A41B12997052C80141058C24FB77E37AF8B590836B81913ABC4F8705F8A1005CE016E33230C04437C8187C4D94613CF60AABA4D664A836D5DC8F5CBDA739A1E464CB8838CC6E9B8D5A80A90799AF838724256BE25AC34E6A3D4E622B254E3FB8AE2D7C55BF64A88562853C876CF18E8FCA1AF3548570492AA3B400E3FE33C58B303BFEA014166ADA4E2BA779B463C4E606F46DBB00EE7F937788872F52B25E8DAE7BBCBB47956A1117B84E8B3A01354C5C2C276F89EFFD60A0CBB8B7B8BB5F29E26C47B34F9026E05B41C06B10CAD7F15446DCCF2740B9EF4E26E7AA3DDF63DF06A530E0E6765B24E213DCE686C292B4210C0492ED87B08BEA2C18F0B7AAF6EBC0C67FFE888F9BD0D55B4F232BDDE3F6C00DC972C16601EF2DBEFA5496547C913C2A51367E8E5B1B16AE02182E668BF8B7B5EEA226EEB93BC4564B74AF9B2EC5A9210EA9608E23B7104DF0C400EB97CD23694EC81B529B0B4E5F5881E3FC53414534482E6A22386B7A6AAA7D79B714395FC88A1C626BFE0174A14FBD8025E6841904D7D3DDD3BE941A102C1D435EC9ED62C0F07A60BE6BEFCD8E3BF34B2EA2FCA21DE91469479D5466CD6B599CC6DC9358319BDDE21484BA923A8293FA5A3A6664B81709FFFFC61180602F2E82E09DE6F80098DCDE7E50543A32A2AE4DF13F30A2ACC1F143AEA50388380F68ED9A70D8F90709839557E87B71A348A6BBE8F2BCD513B8AAD667113868F8DBA8B44F844CDDFBD6079B0964BC9164D7153EA9042B0166C2D35048CEF2FEEAC4979C5DC6E7C3470F99820C1B6FB72BBBB421D7E7602BE9424179515D6A6EF4E9599F44C878D25F2A3EAF38C1B06C6C45DBFCA9E53199AB78C9BB7CDFC9DBCEC46BFF12CF77D6F1F00B8A52A943BCA9D85A5E485E07C053FEAC6A2FA26CCE9FDBE9441CE1F379F15FBA36417EFB888EC69C2966EF3E52088E395843A32607575CE79C686FAD4E20223E198C069AA592CBF7EAA2B5FA375A01D2DD78326F5FDA930630D93C7C095B8BB7D0B6FC6020F2729412EC1C0D89F03989B1FDD708F21D22E5EE9C7C1F0D6E116BF633F7F989D693508EB1CCFD87F0455CF8B796FBE8BAA5B9043DCCB18FE013C91FC6CD47CDD38FCEDE636266FF5495A0493EF8932FE569D1E8E3AB4C477A106FE4C5426493DDC24C02CC59CD086D16DC4C7F494C12F75FB7971C0309ADE96445CEFAED2067A18D0AF1B6992FE1087F0A863D52DD2AA128CFA888B0FED293F674E29F2C9215A0558331F52F8E8F2C58EB9AD654A3978C8294A083795CFFC311F94E743A83FC684921D5A56AF179FD9EEA692D3AC2B937B07D54CD132DD802238AD59E8504603368EF12114F6E21E2536AEF4956715F24A58F8F59971FF0075DC6FFA14965A4813503674A3FF2946C4B36BA9520B5C8E905DCB770296F7A1C991C28C6AA5D3", - "k": "330D1A2D0E0B5DD7F759C29A22D91A09BEF17F8C5566A0D3F30E3817CFB7CBFF", - "m": "6F1694589DFFCE022DC4DF1852FA49A41C6E8AB9F7887E70DDAEF4232B045DFE", - "reason": "no modification" - }, - { - "tcId": 39, - "deferred": false, - "ek": "48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA", - "dk": "C6DAC8A176AC00983EE672BD5B613267D594ADD9096A5B3FC477B5E5E3AA05D1981313CB7848B1A8CCBC7DFB8134C56FD4EBCFB1CB1069663FF5425829F23ED1501E5C506C4FC8CD2CC36C74A63EF2956F3D71C3A22CCB622282069584D019090148CAD445333881AFACB2CD7FA2C5FED9A081678718D9A16982B5F35869B682620C968E9341760DFB6BA865CEB1873B31021848C348B30982619CA19C268F77312F20FB939778A09020A4D1220EFCD70862975930D5B36D37C361687FBB0186F972881D3CAEBA0686719C8FE2713B28B7C470BB23A0F47095286F9B5BA8F019C8B04623734800C205BFC4702E7DFC70FA32390159565E39A18C19CB1E758FB47BB8905BBAC6E53C92C52822C51D90CC869E0C0354B94C54F181252714C45426F71839146510564AC3CDF3ACFB0213C1F1CDEE523472D043EC8564209B123FAA0D5BF344C31C74ECE10E66B2C169079AD7D7366D404349F01BA6D247A46B57A2264C7093BB4D27514DC5620AA91E3EC407041AB3B8E4585CC870F4B5153BE304C31A9A3EA54EBC071D03D5758F00C6CFE8BE6C6635B45498031072EA0932045763744A1C8BAB8819EA6764805D73D994A20A5C8C4ACD505022205A4405020E1C74B06B89A498D871DBF37E7E46B3439BCEB0809FF1141678D428A2866BB14B00E7296961C7BFA9D932F664BC310B341C9158172876421736CF18CC14B7B3384A35319B8552351A30BC5225AC7DF5DBA28AE696E4B9AC30F426EF7C1272EC4567D21E16D6B5C8E44DEE901AD7C6146271A7C2215F2D3438AF669D572B12E3639888416F9979448A45A6528883C9F41EF0D6263FF04CA17385771C007053A5DA700DE42B05CB0468ECA8840B822D73F5268D192F5FE6B15B87A8CB790902A295BE32A62413A9867239FE08A422322E688BA4306BA98359A8FA726A7A1400756CAFE4DC67F97904496B5FFEF21D5CD1396558B4F7982D77001A87830057F569355C0E7D7870A6696C0EF47B31A0CD97757B94F195AF717CBC205FACFC10A8368F06F747AFCC6922297C3500248616781825A07A03626A371EB78A065DB3A7BD25CE0C722EF4F6747CBB5997EBC98BDCAAC92B12CA4A4647327FBB980F35B8102A105DB7361B82161B89880F1AB008B739775B4726D856C1A8D13024F36CF0B9C1E5828677127F0D82A870CB19572B93215B02281C0ECB96204C40B13653416F3C8CC761931FC452258A65EDB2C0A10560E184052D87CE52D2CB90311578494562307606195E2C484C91D93A3ED11957E3B162F7CBF66832E2C0143AAA80C9D309F14B8FED067C745A74BEA5AAE36CA0F264199B2892A00B430F616C43939F0F0C5E64DBBFE858AD17E5122CD96E5E312F27CB2AD4DAC9F628C28DE55AA957CEE08CA6B8C9C35136702C12233FF42919331C01D53DD4F817F2DB2B587585CD92867B7786212475325C50EB9254D0A2BBCB1B2AE563634224A8DCC167C8910F7405A8BFC0C978877528C71EECD3632E13997B66C242A9A3D69A768355C333D73BCB66AA3664074DE3A644D24B5AC48CD0F13A39AA3996209E9522C499F87777407E24B746C9CBC7C63256D2C5ABA644B2C1267DA61520FBB756724C9D09095803A13F48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA963F10A9456E56F427F58784728D6C58B3417E8D6F83A50E16130B751D979C1AA9580773A2674830CD525167DF109974FFD07155CF55615E23916E428C12925C", - "c": "36D0BCFFC4727964FF08A0DD933907E5DEEA4776C814FACD5EB4A45CB3C5FF4D0FA77C7A3E3922863E6403DD9D13A7762A72EABE484109399F14D8855CCF28E66A0E33B8055F815B61CEFCDDDA9B434556C3F696997FD5889EFD254D8340F84D845AF95ADEE7907126ADF6CEF4B4F37A9F6F9CCB2877821A0D7DEE947D13DF4BA7F1FD358D430F49B92962EB32A7B39B20666298A82B5EE52CBADD02D4D4E202330A640663D98CC30759DF86D4F5D8542B940A80C87B3E4AD6EAE0419AB6BC6696AEEBDCE1A8550F95947AD04F47A3C9A4F84E8490FBAB2C7137E8FBD20AFBE7D94FC35558C14149AA277F937AB28BFB33B7084C74A4F860D5738DDF8283248F22DB16F752B55900C8FED3B9C56B94A1BB525CE054504DF3FD651894F0F1EAC0B20D052DD0504C6E2DB7BD742CC3527D55BBBBB184E7E311F72A125B230E7D1364D77CE5B5B104BF1DDA76E054BDE897DE4437DEB871E99C5CC16D537BD40462F0756B796477E7B0FE435202CDCE1A3B5F30C0F757BC0263F3E8B6B4A7275CFB1EA24637752034BB32108BB1627DB0461EE9C521630022E00F7B340B69F95917A8AC0C6D7EF6E37D8E4635E77A8C3FF9E42F452EABA5CADCEA4D686C220A252DF9FE3B25F897C163EF40820DFE0A5CB27A1926CF26D78E307FCB67A9019017BC667116A46BFF210FAE126688765ACC48EA0F8D8D13819A3CBD9DBCCFCFDCBB604EB97E51F7D23C20B8221D34B5053DFAFA549C2D374BB2668CAAC16DBF6A9ED52A86DCCB5B59CA41DAC1661C597896A399CB6ED3FBA6A4C1F5DF6A29E3A65CB6C2F0ECECECE778CD1DBAEE4260D3FDFBCA9AAC3E161FE45B88152B8AF6AD0EAAE9D964E9EA362B5643621B997E35781B1232AEDF4B02543B339F074FE630C5D97AA49BACF3A0D3EA57246005B4497A14165C8BF39AD54B430A30D2EDABF024E0245F4C7B732DD90BF4BA1145C4B88CB81E6408E9D8CFB9CCDC4A9BFC4D9240A21091A11543FBD9DC8BE2F5A02E3650FD273EF529BEC9AAF5C2E30284075326B7CDFAB4FF448CFAFDF21AAA5DB1E0B2D3B181BB7BC9F4665557CEB08DFE29E0CE924F7ABB3D226E9A3EE74BF69EB0F59E58A232E778724770591219F2744E8149028CD61F6AD182E8F42462DA51546882D77F44243C698AC7B61B8FEEEF91EDC73C0B96A40DB2616BECA5A5686D8506090BB3F02075400A151B26682C8D81F05E9E87BF59024EE5AF6B6D015F9A81E19817CE5493571CBF8946C5BE67548ED11971877617B6550F372D5219BC07AD00D659196149250A2A32CD1387B46F793FAE968BCF3F1D4F0BEEDDE6E685C975E176DE2B5CCEC08930D0C7D176A43CB43AD728D131C5B5646C41113904B919AF4E8783EC14CBF11B341CB81CEAD8FF4599E2B58FE97E297C79EDFF394891C5D7318DB5684FDC0AA867F677B6147886AF4F28BCD8E69F3DE22A597DE59909FAEB7D7BD991DFEBE3A40EF9A61D0C725619A83F82088A14E2A1703CF700BD0189D39F031FC2E7E01A3BD8E8A4D6790A2262669A", - "k": "44AB396F38942BB69C09B2602629B53B820FCA6D3D1043B24AFB3184AE9B5565", - "m": "D8EF97421196B1A91448B2BA7E2B4D4B035B91DD85AE4E57E8FE3F0B0D524AE7", - "reason": "no modification" - }, - { - "tcId": 40, - "deferred": false, - "ek": "AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC064", - "dk": "B7649A90D87901527052079DCBF86946E8C05A3558D5B35B185BB6224938B6B5A18F490AD2B439FCEA41F1A7A2DAE9B97245469237422B2422CA8B0E36D9A045E296DCD817CBB29CDA6A94445848C9EBAE5314CA9B063D7C666C9D533D6CC1CC4CB3CCEEF55E5F4A9681125142B77C6EC6CF4C94452E9CCFF601276DAC56AE1020CE7A0E9817501856ACE069566C62766827335E4897F9D47D7C777DE56561654386CD579A1535C569EA4172312E7106AFF19836E671399A172AE853656D206C63A2824D46C6DACB6AC3E21681E324728818CC977134531C329A9982686680E542208C3DCE02579051B37667814C439B45A3ADC9F12D597B42D7372B5E863E96FA8EB8A61EE999A2CC22607A057E6E69516BF8628A041E38C378E0A360CAE6BBB3E7846698C5917A2416BC5B81117CBA8905410C959B4A7241BB96974B29AB976BD2069F41960EDA9778D1EAA1BD7A74F6E40611EB68EA33583C707D6F005CA202ADB84C6009354679604B3D78A21DDC1910DA0FE554A872889CFF801AA496B0B5D498DF245965B783517A2B9F495FFA714FF17B28873A3BD6B5313C8AC70967AC62B90762620818EC1EC1E21080F5427A59C08BF7631F91AF9BF17814A238983526221774C8176F932AC90C240BF48996B9E912A7E6A187831EAF2A9B69616447C26BB598CDF1D52542E6C39BB5BCDC25B457241CE9F2B2E9713639916EEAD5B5E85637C8D527629018925A7F59C539F35371AB49CD49098DAD905296F28B2CA29295641633ABBD29513C886A82F0094715380A6B013B16E578FADBC7089C637BE0C6FC85A68275CDA850981DF357CD40C3DBE21B10376ED5C9AEB6FB3049889431D23C3BB6BB175A24A7233C5983C5D1864F1035C805631FDCCCCF301739BD1A82B4A9CF895439A05629024312BED71D4E93863B22B05B5494BA666D4686971513559E5815A0C7371D50B209C185E3326AEB222AE51C74B72B07F3A7A913E338DD3B94F750406D533703663B6DF204A7A1BCF2D608E3F9A72BACAF83B8393E8456A1D25CEAB511BCB7452DF51CC2EB75D5042E6FB26BD8B518034348A795878CC52906A478F57107A0D8548D9442AA964954B60F91EA1EFFD80C8511A26A7907234ABE3440BD60A595E02813F8BC76C9B83D85D7C0D707378D2B4081C7B0F7FB5F37C4BA0C7AB2670800D698134F4538E6D79224D9ADDF82986B91C856FCBE1B70940A103081D09CEDF1B527D94DAEF6427F968742961C6D910F6CBB3CB2734CB710BA1BF2C02838CDCB34482A452290843B12251FE776C5319A7319F47F22C4AF431996A7602E35841B0120151F427A307590E5321735CC8B2885B9B190A0C6466DDE597E41FC4AAC417882FB23E3866D3B325DCF8B0994434CE75A988B4B30EE9162E56809F638300CB647623A708351555AC4705081C628D48DC7FC7EC0F27A822B1650888CAD4CBD9D9B07DE6B82BBE47A966C331C743F46917104736D3ED15277B75250401B7A030CBB7A82935BB7E885C606A851701776E1B5487640444F33994C325D0DC99B2E06021C753F3C6A4B556A5B4A7705F2C0A32F4315E9AB35267C17002131AB608CDB13C02C50A1B152C4FF0C4D80AB8AAB6C4C8BC508AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC0648599741BE85FB959084A514EEF8306CAB0D933C51707EEE4782831FEADF8AFAFD6228B0EA7F3512B3757EC1D5057642AA3ED2265E73179113245683986C8FF04", - "c": "5DB0F63E2A2E640FCD26AD49D437B9287E2C3EEDC2E82A25A49AD859C867929BB10185B6457D64B467A1DE9176B5B4C163FAC1C6C0CF0132BB685F4B99366B8CE702BBFC369CBC1D294B9490E47FBD2335EE6641404D6444E7F7EC3C435F5FBA9134DA5D807B2D41ADF37FF44497826FC31E447C6BF66888893F38CFF04C5B565B036E1F9BF255EECC0F0CDBC625010C8CD211E74164394A87569B08469C2C892ECFB90D5D614C1F503182D9F7C168CEE2A1E9553BDC7E0919B9FAA1C2FC652A13F87394B1B43595CC6218BFE6CB8602F864295D06F0A60119723972BEFE7E73A70F8F9B99ED62FF27317DA4BE60F7CE98BD70A0C138E4E4874CC3D254CE3F93DCAFFB2C8F0E200C64DFF97437878E4FD6BE6F8AC8FF6C5982EAAB879955A699AB6071F0276E6999CFD2FB58329718C64928A18C404539CC1DBDA372098F9686C3CB9D945824424B76469D1DAC5D52D0A172447C19781B43BE9067DB2DC18B6C2CB1A5F9F0C0B4234FB605D4C96396DB5C2E38EDAA114B4C6181BE8AFE6DE1FDCF38EAA4C7EC97FD629F17F2E530CA5CF17DA32F14549F7361E38D64A08180E2FB7AEEFB2CACD993BF39020555596BF421C95C6DB96A0FF59CE65B2F624249EB73D19F34D6F9874CFA8AFD71C9BA1455055077BA7E5E2A9D074B8CD2DFBF1767BAFF41AECD9DDC1239CDB6BBA904A017665B57F2CA765A3C08CE233782A2AB13C66F6B6E55B14D71E1AFDF18F093FCDC1155B7471E12FFAEF7F13C01458544DA9157A898B6756620A8219DB5FDBCCBDC3C4FE21AF3902B2210631E63939D1BBA4B0B674F184000C985D4BFA7C7E3F0FE87850DB0504977693AA2B8D12A35B7619117D5DC8FA5AED0E556909D9533A25A5130F779D3DB7C5250F12DB5E1E51D035BED789BC6EC2D135F9BE244E28563E011535A09AE6EDBFAD5311EA083F0431F9C555F07AB21F0741B7DD4508A99CA4E6A6334C21FCDCD25482E987510FE623822F9033441844F99B4A489491F70C4459BDCA67DEF22C76528A8F0D0FD36B7099A7A34460B5EA1CFAF7ED83F0C7773B062A6EF062383703ECA07612D4960C410C86AAB9AEA0764F060C08B4B20941AA2541E8B8521A8E4B03913A48FBDA62BA060A762EF6199649D7FB6869BEF764B6688A7B77DEABB337BE54452947282E9B001D6B54974180B756219087AA81A8DA6C2E708BB894F099A0C5FD5E858867F083E504983E3FA1F0D9580CB926C7C4DEED4BA51D1E5EC0F8A6102880928BDC7A996F2257AAC86F25313B1D51E7EB784B2CB78102AFA94389E30E5FFA336ED49B1F9FC0D557DD7F9A9C9DB959806C9509160FB9EC4758825C5CC1D49D95CF134CFD1565016899A7C102C4E19220F011DF4D363F3B8EAAA419DBFBDC5CA66FAC7DDAE1F144AACD4209BC01569E0BCFA4FD383EC9AD4CF36474E0C2F8A9335A5E6CC595C781F3AA2EEEEDCF593AC27AAD55FDD46D0224CB3B88C3BBBF6CA6F2E7BB4043FF2B0C88D304B962F108C052E8B7CDB4D2573E47074BF146BC9E94783F811", - "k": "E5DCCE174C4B39536E548CC326893C4C4CF649699CEE746476A827CA567D12CF", - "m": "132E7CDAB9CD5199FF0937C266D50BC50BE764AD027DE45C858E3C2F79B7F07A", - "reason": "no modification" - }, - { - "tcId": 41, - "deferred": false, - "ek": "11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA4208", - "dk": "8620482F5A28310A3DA5870035D90D8A47ABCC1A9653E4458EB04D20E6CD97A8CEF6652748156C89DC35AF000653FC4BC94165ACB185154400D53C9BBD746C8A3BB010C9A3CC5C305C32A8EA817B5B743747B63B726937644090ABD7B0AFD73AF359007ED3418FA18E4455928599971E95C0F321B2BA193E9BE79FDC00B70096A05455BD201C36F669C1BB830468D135D4972E0B363E6366555630AF095447009590EC93993E9A862B791B8E0555A8E9634D39145598C5F733C9052934ADFC7F491A787DF06DD4C5B7765A2C26D73A4C9A928E60C81A8595883894317B07ACE63342450FAD15659D4491C1387B66D743B9557F21540A3F8B501DD6BC69D7B9BB056ED5B04D21B8065EA95E83272B42485E22FB1EC394C0E0839F255A75403355B8C60F8FE3859BFB8854E418DA0266BB26C92EBA7F3D37821942B367167893F35B8C4C71BE82540E441DB9B252C7CC2753923A5AA15CA8393803B453BDC5435120965B0C96D7FB54276789A157B84A398142BAA351124EEBA2102969C8CF733B0A4008EA2B1FE7CA9D6A1827A6C51C8128CE97CC96C3188019D596A0CC7CE3705DAF489AC823A4813490B84963504026F4537218F1AE1757638318386AFA447191AEC0F14446D093ABCAB1E897405C67A547D0743E145C1015B9EB064FE743761DD717D42C8801C0B79623A622233066573F7A264D172C44884CAEA0C1A7A7CC5E8874B8D68212CE884943822B2E190C98A6033B9004626203705676801414AAAA2C44D6AD81828F821A85793B903B2A10EACA5AAB455297B8C6D6C4816664B97B99B74E194C3A5465FB8A2F1932B5E42500F67C2799328552EB8DBFB71200C9AE2075032A99B2C25863A045AD44324D31378CC1BB8C7B2673F9E0003431235139A6296A03E3C8A7E102A8DC7224E7D1296B4B2D3B284AFB3346E5332C43F01AF48703FDA319A6691364E36B41B8BA2022120F300ABD2A45D0BA630970BB07104E9B8A35274A6674E534A0880D89F13CCA889E705B188ABAC8F3B62A25228DED82291FB4A06D9483CB49442C02B4CE038498A691FFC98A890C4BC34C7FEE52373ED9A72A3725093A123C2B1DC7105C8A1C435693503DA87374644C1AA4A4A2A6C1A42C411BFCB20D038105137529A91114CCC5ECD5622FF5C8B36522EF5106C68885C19C579A68ACDBFA76A6C4AEF031B5C00A0F2A5B243D2A1C97ABA7B0792F3AA57583C9981ED1392E70CEEF210527AB5C7C1261A6D3501B16974E402FE29AAE78588E85339C6DA0152DA9025C95B5F09A2627A76C23651323096D3459C286DB946EBCBE3C8096A18C290874644B654DFF62CFBBBA909C37917D572E50D90048086FD76B346235858A796627FB0A9B1AC79E90615C47309F87A14275A1D17A11BB2B523FBCAB0CD5C0FD8744FF70453D1AB2AA98BAF93697BA411E07E1BB7174669945B6388844D692B324E4382533B0BF454682B155EA408011BBA2373A4FBBB6BF147CB75CFB213D428BBBF6074D38CEEEE78D3F9C2F230A11930308FDE482261C14C5B1B499321798105231C7375BDA983DD03EAFC8682369198802D0510626760A7CE5CC45F38377E93A685D7369310631711230C618CB83A20A92963D11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA42086B6697FD26E70625FE8F9F9519FD2E06C00167545ABD566773BE01A874722DBDF9212A246D98C21B61EEFDBFD8BABEB04F75EFF4D8BD5EC606AFF11F6C20F33A", - "c": "199604618D182236DCCB6F33D02C92C0B22A122FE24D08AF0E4360D48F2626A6D3FC9CBB712608997F1C3806DBDD2CA5CFA9223B3D9BEC3892B7680E6B6ACA245D024D349B1162610D87B3E80B45496B2C8A930666F52A94665169B3D1242540DB797E4E2CCBA389240BCFBA2FD6E0FD3C7C01D908EA99AEB014362E2B20C2793D58E7D6B7B6DFE4FC06D2962AA2BBC7DCCAAA9FCA60493E90BBA138C7D2F300758A8A04446F277E9681B29FD6F572923B4A1D0D3A8E0E26C952D348607E39F69A4FA6F4AB7D9A4B9715A8CA8926C33442DD72BDAD6E1E72817973C6E1C8D5518558A3727678F89D141E3959F572EE533D9AB12633A65E032CF1F434A73E7FA552FD45D2B43BA5152A3172AD58FDB6E2D005F9D8A836AEC708B28972C231D4BD69E77A18FED0BACA032A5D11FEC1266F532FDAEAF3C2F231D07332B274E07226B4D35B30611FB4B3E2F49343B6DFA74CF312FF82AAEC402A1995F7CC1866DC78AC4B7B05EF8500C5C8AD5285E035CF44A6E7CCBD7B11068425D60A66C6D8F5D24415D5C8146C47835B5FBE4882F5AA33164C8BC348BCC3F57DE43AF5EC5400B37CD32913DECB132379278C1B672B006CC0F09510A4A4D1FC139263E2A163AC39FE625139DD75553A8922005E6BE716CE6E5376DFBED8CB7CB4D5F52C2948C033BE9960AD3B910AC5DA388B14E19355C6A0829E5A804E65AE885062BB8B3527DB4FF50BA41A5CE45263720B4A7877D838D1C29EEBCC7C5CF9F5212088D99DE9AE7BE18C74EC7D677BBAEA6BD25F57D0233FB167C5BA0D20F4D32EF6DBA12C6F7AF794247EF35C32D9E4C989B43935BAC97071D3D966C37EF0028E7487077F71A0380E3F32FDEE8250972CCAE6857483C01BB4CD2B177F4F9504A636C307670AEC32510312BEB2EFFE0639A68218FEA75E0E4B6E654DECAA6F57656017E77217E6FFD095A7522F0DBA295986A3998ACF71BDA96016552DF74E6991060098A20585E99E33F7D6200B6EF22958B2207D029566EC96B02CF2AEED17F66C426C5DF559A98E5966918FD0ACFA54B6E6EE70BF3042100047FD481E5E3B73288BF03877C7B2F3A1D206C76B3426F37362388ADE66C05461441D944D99FC1EC3E67511C1B9B9919117A09680A7CF99D367EAB6E493790942C4394875B86B464D1DC98F5025B9F71D27D146C7AD9EFBFFF979552AF5DD127C2231E4452513C106E8D7EC6DD9CBD4BD706AC1F022DCDCD235CC45EF6804FA2D98D371D713178FDA88C5DD6DF98E1B3573D6092DE3C022E49D8E51EF237947AEEC5EEAB775107D714E3C4DB7DC2E408EA0F3CA80AFCA83288CD1E147930FCC727C8E944A1E013919C92109E9A764ABA96A090D31C83C93F8735ACD66A087193CE7664757D9B8868F03F7DBC3FC44C1049826B4876FA2FE06B16091E2E78335FA55A839E719FA5BBDC46B659C3BCFD91122F775DF9A9E8D0C43FF9CC2BDAB401B64E5CC35FB17681512C03C14C3B1EDB2A84D8998829A12E1C7FA590B8CE15CC8AFB37253FF5BB78E0B0EDA76AA", - "k": "66D5307AE26DCE8CFFFBBA9BC0B2C66E38B6E77537AE525B3E9A18BADBD72FE1", - "m": "E15BD4603F0EB64E32B3F1D1FA8EF6CC25D673A1D0BB659CEFBA2C153724C1E1", - "reason": "no modification" - }, - { - "tcId": 42, - "deferred": false, - "ek": "E65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDD", - "dk": "F755A8CDD185E9791ABB61B4028A435B336475DC9D3B20B5FB7C703BE6096C23C2AB95BB71127264E29EF9349001C70D26548797D2C3B6C23D841C1063513738F398C281786C908AD623B22CE690838579A7A08ECB5419366A65CAB11B7B598A38D1A878535819C21E08E1B25EAA50D5740C80D90877B921B522831ABC6EA9F7C5753292CDB21D47402F0E95179D0C3247E16C66801F9B057EEDE48070F456FE58906ECA7EA91ACD9B537AABE8A105B5B0AAE634A1E59E1A456B49215E9C792A0453ABACE0539D14C661ABA1033B7097945BF7D0AA35E9B2E98C9C48232C041BBB32A928AF58613898010DC0892591781343369EA7CC68D93ED41808B53AA1E7C69370281653109BF900A783A231E0E78FB9ECC75C5262D99A5401D974B6069E6ACB7DCDFA2B9E61A7D87117576C1076A497E096382775C47B2C20AEAC91FAFB5709670277B20E88D8B8174A44B0B565D669B108A4B61A22CC53262A79948A3779C4DEF87E8AE7222EA1061C76B052B3B3A07BAB2BC52104D7B093481B6E7A9AEF4530502126E718153F259C6D9142EA7ABD97D9037799368349CFCB4C6AFB541201856B6F8CBC4A6219FC963BA4951AA266402749C4F066B5A1703CAE32831901B6E51215F7F0A5370A6D1691284EC80126710224D42B7671A207C06822EC5420C186D253339D9A058DC552B6F8C38230015605883E777158413F915C3284E6C8203B21F502830B51193B39230A963BA38A3C2F0B122559847972923B67AAABE0A4450BBCE87A1F180A9EFDD8A63CD3ABA8274BED24C4E464A9AB1B893F9C08B6D4CF2F93107CB1148C5719DC81358C07C14D41883439C7D0E5C757815140CC79E1AB252281A4D190590AB36C0945C03EA3369CA244E3ACAAAE9C4BE8A77C9458A28774B3C1E794B459CA0EFA190FD681DB8BAC0A771D40651516073D91DCB763CC2761CBA360EA5B8BA402A2110E3E92522DC9A9C3737FC7D7012C33B928184AE22BA23B5854953648D4E9AF49DC3456EB3A38569F27915ED388AC17D1C71193CBCB4AAB74726D4A324294A47ED72C86D84064EF707A4AD7BE50948D82B671C49A19AA338948947993F6A819A669D9C70F910B6D86325BF3046E6FE3913745ACAE5A0EB1A62B203CC46774CF210B2B19C9C63E1A0E8EA9428FC20E2ADA4BF87A871F7C12125AAA8CF38550AA09EF4B82CDDA83121363345327C4FA9FB8C61877216441610F3368752B16121AD7746B405303E83E495CB8C19C3E32F039240392CA8C4E9EA1BAE0136463D032A3139231E61C9947C987980124B56D19C478A060C3A40AC9AFC311BD247818B499AA3811A2584303A58DD5F82355D963F3C27EA57556A5CC5A369619AA7267CCC49C6138ACAF63BE55E81EAB119C923B1163795ED4901F51F1C163FAC7A3F8C080C40E8F0895CD774B0654B137CB72E244B0B7FB58C8F133A9974E8AB74226F7BE847B5205E80E479633EA574B16005B47512E28F3AEAFB0B0775A1A30664888C45913301832F6C80737964EE58D79103F3BD12B1B704F6E8A770B012A0AAA003990BBA4E092A666C6FB1BABF941B94A6089C775479790A996C37B5E44923384874FC103690763B892702E6832CC3A3F69157CE65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDDBB5310F78E18E35EBA80A0D5382866560D6E502D58908A97DB5FED7E935FD7178E82546B2BD2675908B124B41D52CB487BD98DF8D7BFF3AC859F4C685F91001E", - "c": "50F0E77866A24C305F778B6D08E9C33CB04C31B98D93A1637D5B2E9BB2443337333E91626DEC0C1C59EF1DBD000BDC394FDB2B6B471885CE4A2777A3E0094122A6DA08400897A635CBE0AF1D56654F4D56CCA59BE3B36B20666036DB3C02BD6E6E605ABC070525756A9CD08767335072D99A067D816DD3438E0F4EA4BA1150A7806E41BBC7521C70B66FD46496354CB47500C28695034480CE91E1D63937EFD2FA4F92FE0B95CB65EA70F610B1B4C9519DFC8C175410BAB2E337F07B3FEF8A8CFBFD45B2827A771EE5D6C2E6A3DED56D21E15563490F763B5FA668F5F4E982823A762AD38B78B573B72C9624798FD092A11EE9A010A31A60F8EBD647A5B11E437FF4502863F78EB2104A270692A541E15AB5731F13D11C20391716D60A912DE796D83387C152E9C171F86CA1EA439B369DFED63C68FBCC103F72E3A9D4C01558FEAC56C2DA7BD797A48257FD342870523C56102CB413069C833BF51AAA31403BE6C2CDB64B2C7A7F6CC9F848139320B974C165717D6A0A891CBDB27EACF96F23FB67C1B218360CB68B158981D32FAB2C12AB14890B0230673A29678EDCBCFC6D2857D2F78EA375962F459213F377E7CAE4DD79393D3C2ECC44FB64091D46F30926FF7E8C5D07E70B1407636300382633E2093FF708F541544FDC5F642D92B78CA167D2A73A871AB4C4D611AF2804B3BAD14CD64AD5BFE9C1DC4E142192A90ABCE2C5A8F6BA6D7D30A19E5AD8F9FAF34AB516A02511EA8D88B1A96DE9F6DA9616550753AFC151E7064E4024C661667807728CF85350B32DDAF7606E4BD491FA61FE05070311DEECE16F30F796E0B6BA179A4D7C8B3756BFF942AD2E412299C911EAECC18A3AC3C68EC76D82195615DBAB4C492AD1E2C7F210923B2E54056E557F78422A90FD647520B32626D017BC661E28CD7FF81492EDC2AB88D10F26B576BC6C8F7A79C5DB1279204859A3C82C06A391214F6331973A0332B27A339540D00AE047FE2C4296352190C2DA7C3B2849AB1A36E7EC74FD641A46D2EC61B3C0D394FB3218C6A0C7FC8B4ECB47E026929E15B0D1CA2513C17564E48543793466D72EC2F5355D43DAC60EC6E55FDCCB27A403148386DBF7BAEEE056AF976B1B4D06111701A3AFDF289A0E3969942CEC96E33C095DAE1334DDA76C54FB67A36735C96AE5DD53D379F5B05A51684D997593B7B25B2EEA0001834A9737AD050F6A7CE679D27D852C0DBF0A6644185FCBE7BE97200C586002206341CE063B042CFF9289CAF378EF0A4F93CD6B0736E8A0EA91A1D4FBB6FF30B255E9B604BB8A5F06D2C7C0607876568465352E76C5A31A44B54B8BBB7F0B016D7ADD77B23C443D3C8B1A7E67C05C80A77E2D9BD0662A37A4EC501482FCE4CEA342BE00321E2968107D0B265F168E6560C427B3ACEF9C14478A80DE557AC0A41025E32D8741D638CC8F76E35AF1AA32728E5C5592122973D1947538B8793420FE6A1FB6877ADFE5677F677761F5071AF5D6A70D706AFC275B7E551623E97EF793B814239DC1E3C53D23C3CE", - "k": "BE4A7B739BBBFEA62A02A555571465EDCFDECEEC83846760A0D39944F99266E0", - "m": "D176C0836015362D1DEFFC1901127B5C41C14AA518BFEE6C62F2EAEA1F226AB5", - "reason": "no modification" - }, - { - "tcId": 43, - "deferred": false, - "ek": "6453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B18", - "dk": "A996A675909C3F1B1B676B54D0F29769F24B86FA482FD3127086C82E336C9D606B7CDA5F5002C6E27AC69DC26DA9D90BF31561C798CFB9B78B37F788CAE520116A4FAA4826765A41A16C650A1C33CFA91311682ACF0144825370D76657E7B18B87233A0B1393BA92022AA22D28D04B4A302380D780854519C014862545467626B8F7C0228E19960C528D4A511259C7B8C92A5C4E7060A76B8182A0A0ED5B6AF6F920FED0B1DB4C76A4149910B755D69A43217B942D796B9AC549ED9A464799C25AC0B1EE229F14FB485A795A2E072684CC33C8F20B49862157351A0BCB37932B7C4708374B7481C2A5C19DC752164235823935B96A9AABDBC4AE88C4D87131D3131467A8C969671503CA85B65B229491A33B4789C41722D9F10F97F335C2BB86B7945E0A489AA7171C13817D04C4534D324ABCF0CC78957A82214DAC93667E92CAC094003C4440C560CCA698A2287BB0A19CB0352C951D238D13BB89F9AC3AB184A2664423281681E8813D6B433A8CA7BE7B3C99368A1DADBB984FF298FBBB2645C11D6576131DDA12586C6DE2539641FA21D4870D471C3702A4C3376355C1EB42A90B5676756905C2173BCA5775192069382B3AA4CBEF7C95CAB35E44C49981D6ADC8C68E9D41109F5C18BBD80D13E80B661371B0CA6B48D19886E610FEB6AB4CB500EE0C12A7C770EA6B16F80C4D2EC016AE26B02A2520B5692437C80A857A09A6659218D147923375203AB1F2799462F28427C01900B08A8307B5F3BCBF833104A04C7B4444BD069BAEFAC4A271537702514703FC2388777CB7735AAB3684E03741F1B45261CB53ABC800E9F8AA77B62C7A805B9FD8895B568FA1136CE80A6E47D470B26A0ADD4A69BB33ABC8A6A49D61525866256D2656E46827BE895162A01CADBACBEE418695089BD9F1940408483FE87C31A68FEB4C35AA561827BB49E97776C64036379B16E719AD10F02BEC795760BC167FEC3F7B571D88075B161862B6C556B8C87B3636398D32426B1A11350203B93112531BC8AA0ABD23454C9D863E1E150990918A96B2B3A3A1416B0A8C2968AE5A110DCA445F515A15373026138865F5C64F625151FC546F9DC1B8A2F17C2E719BC97659CD255D34A3A6E28B8BAAB1C47EFBA49CB4B1220142EE843E24402462E785B01B664854BC54D6205312B6B70117C5C1C32D91C7B8032CD46A83B327609AD91519C9AA203A0A0B9C36B3671AF62890F301CB6BD4A3D39175E79A572253331144144BB2133F924A3E88142FE04BFBFC15EC84BF968A2E9A2459B109144E0445097349EBF3AD8E0C87641C74FA71699B687AB505B43CF0A668C7B5C4BB1A4D676081D8C1EE7B8A881791B9D16F92116C5D786B1678AFD49A761D9AAA33754E919972DAF27CEBE3CEFD3C90072119A78387FB056D98D41CEA45648CB5B87D217DE730703CCA26C7726F14CB9FCA3760646A627B255EF9AC156B6C1721445E20417CEFB3085394A3D94AAFD1273E4B75A5C340274160A52F26C376A018E0D880A578A24A8961D9D443A5908A32859F2A9794F80C62DDB001C411965802C6A0F10D572171FA32A44BD56ECAE78B7FD34492E28E61C47C8CC66686B401EC082013CA8CBA84545596A9D781786453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B1835EF87CAD46B39215CEC187D9B96A895FC9A8EC843B7CD3531BBCDF1BD64A22D5001876DCE843B5761DA9110759CDD04CE17B8936541525FE830CA69E53E1655", - "c": "ABF144FD5F6B1CC8E11E1405A8AEC1039BE0D84CB1E4EE622E50F721F9C76C74AF363507C354BFAE546030A8BF746315F1B223F2092AB783CFA62CF86C9E5F504BD489D8C6B009D1EE77B082C5112CE2675990F401573FA6643551C6189B8545363835404066736BE712553FC8408BC370DB3603B086198B338C55368F0342B617A6314C4147C27D75925591C30BB2BD39BC34F0006C056BEDF6D072A4F3719C5FCE7AFA82CAD9A21EB92A4E6C833318671EC4D262E4DC321164DDDFAAFF6EA91514F7942888C0625DC03D16878DD5F2A4ECBD0B4C508849D20E98D6C84D0D2BD7A7F1E70687EE04F8EA275D8BE04926F3213055107135F726DB314F6BA9E4FFAA23CC074BD50A5D192C25F4354082A7B25C128F3FCD87FC6BD842BCF0E8A05AD2DE51942978F5B2B322D5205095570FB1855B7AF3AD9B5A6FD6CE7D418921EF31E15928E733D10F96553401ACF750001D7814B4233F7A512F2A7F768C189ECCB5ABD0206F7463C812E0186B60D9C06DD93DBC9DFF13B3B39AB3610C03184A4FB2AFDFA964BCD95C1DC8692A01EDF4C22F0D8840D997D13FE228E393F47DC5591E68F64DF855127B5951E1F8259CF40D9EB5281781B5E171B908CFBEF4FCE13BCC41975890182AB74E9739D9CB4CEB30D600EE3FA70D858D60CF89D795E583BADFD5EE032653C731C52A67F401B2927C7492926651044608727570FAA99F618678000A61EBFCEFF973E40A0B56B961CF24959EF4E324811A4F1EC878E41B386F27A13BD322C012756B0E29ACAC140641B77B1986BB7C41D3DEA0E38A768475C3D6C6EA3A6851CE4578893592A5EA633C7C6E6144BE6DCE7B47EA653B8176C84E2754F3AC6AEF843A5E759626D3862A13B85C222A6E5E0836FA4ABE18DC57267BC77F2187258CB81D24E62CF972F13D74C56F970E4BB29D0D0F39E35E61D6DDBCDA0D90549AB5D87C78F8B7F7543CC95B2AECB0CEBA735A8EBDB8F78BCBAA41A27A9AF77C2F9EEACE5176C12B340ACCF63639538A6308139C1D9D4A68DCFDA14F2AE7239EA6D0454EA8A1684455DF3B57C4581F9E5B243F4A3A7B74537F8F8815B30758DA124044D9EECED7BD9AEB699CEB3D0C708D76F4176AB94DC47B6BE84AB40E677C937146D5EF26F854BC96C0050C2C7B1A99DEA2F8873DDEB668F2E4129C1159D8C4312E6D4FA1AF9E5739B04416B7E54AF21EA1864037B7D74094F970E9B7914066F7ED2220BB8CE88594050A8D20EFAAE7993E3CD4C4206542047A0B8D00DA347D8F97066BF9EBC2D6F77A68E91524809CA14E5B9559098A25F2BE13CF64F97EE4B9277C798EF544C07114E1B4ACEA057DB041D8006561E97AA4C60BB5E3E84974FD51A8B12254950508272883A06394EBD680732F9A0AC66DEFF31BA045174D2FA5B15D8D9E326CDA635799F38A5AE0D13EC12145B3EAD39FA1E8F6F97AAF5F437F28936362A235D00A7C85A4AA6BBD73A998347F06F83F1EA9F71F318B2EA96BBDA89B9149A5765C41D018BBF2190B3C6C526933BC828EBE4FF35B", - "k": "CC54EFA4BA6B3C0B651258EFA6C6850B1B31FB159C282D6F354DC18C8749ACD7", - "m": "4E302EB2BB5392782E7820868DEDB61F5A6AE558CA307A01ECDE4970E43EB448", - "reason": "no modification" - }, - { - "tcId": 44, - "deferred": false, - "ek": "409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611", - "dk": "895C17908C9C3325068A545C951A7E5A2970A205783F8426BF3359F556014D79ADFDBB03CDD8B2E56BB3F8A095CD143B2D73AC87D997DD64633C0056203971E38A1C1E268F1C3A0C19D0A573F9B6A0401FD6FA93B65BCACB7C5E7FD660C4F7802D99A01B41BE77C776240737BD2234BE38B655857AF88AB3E40294355A5B485316A2109447606B3F86C512D726F3B915524589D4A3929B223D9B9157CAAC627F037AAD467C256A39484B3C1F3CCAC9F20F4A8AA840009998298C7FFC453607B1E1F43F0F740631B051720A3CA1392A34D84C06AC135B3A22AB277E51C56664917254842ABB134EC4576D33C69C7C66211C0B40C6912547EB5B9DCA0AB2035552956860DC230FC616940AA8B3249F8D8570F763419DE0C8FB1678AFEA395A553D1E3592DB6B4766684FF4421E97CB3C6D12C7798C63EEC9CA09868D8290C0A8ECA681AC1280958BD67A615F947625C35EE0C36F15D6B6EEF79FBB811386A9713A78B9FB581A6D47178A0A3C8D11B23BF6A2D997BED0CC34662C109B843C455C87ECE728C790AD24E690376806776A0F1AB9CEF70C6E96B46916321F77251E42DC7775BBC8BA5C295473186A7A277B2561F0901E96602E5ED31D50038CA839B75A3164AD17CA92308F3E75264A6C8EF0D940FACB9DFAF855283551609B4B2CE0329BCBB76A0710E4807F95169439C6AB571477C4C485B73503F87157B75418780C4CADB54B4E2CADD6791688E867FAC57812671D31A92F18141AE033570D21A12C1420733CB7A9835B60AB4677445C49756DAE5477F1D400FAB10C5134092AAC2C0D42693283147E033CA08A6672C4001734233F496966C214E7A36ACE327AC883C944446DE2085233A84D18C6A24BA95B3684CEE5BA0FA30A2C1A483EC4668B74C356CC97C5995247AF39549C92BA9D544580579B1E3B49FC2864D945A7DD555D2F5CA42A519615AB75EA593B15E9BCAE108A3B711CABA18E58ACA44CF2BBEF8C00E99540888297AD37CFEE4BA60F843750AAB223889AD7148164F28330926368F009CC440801989BB4003FEAF3A25B76C6E6686C06E3889DA28DC62383035042F1E64196560775C3B2E6CB667D30578BFB889CE194CA582039710C5D673B2983A8004BBADA80627A7A33C3B524F5CABFC88995D99A58709A634398505D77121D76ABA1FA8B12F93E171321C8EC7CD2C996FD714D07A9B6FFB389A05C2761C45AC9F3B35C24A246E348AC7B0C7BA347589041EE24BCA378888CB6471546CD9E04A68469956BD59865B6682011BF1FE71226077BE7E9C81828AC7312417E46A00570A6D65C4FC4274CC43B73305B43EC8C96CC46BFC898535CB578A7F483D63C43DBF36F3D698613ECA11019581301AA319BBEEB29701ED472955B4C453110BD381F328573EF83677C65107BEA546CD930ADA0CBD153ADF7C7986557438CE099583C6F517C99AE62BB35769385459FF2FB1C38E130F7060AF97333D38BC6725374EAE980FF69046E905DD3E33F4D546C3AFB6EC146CF85A66366B700CB544FEFF9439D9521486240DCF31B821121DB914F107B32FFCA171B764B299C4A5DE793DB42AE20505381B820E7970AFC2064C80203D9B63188DC6689D67B009BB1B4A912409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611FA9DC07F088B86A0879CEC27AE467955EFA0EE0A57A996B3B2846ADB293805DF1C399367603CB39ADC06F676FC6C04ACC64F24D88C1E3F36191D5294C82C45A4", - "c": "8C8DAB2B1D37BFAB6EBC4E502788E061EA1097C8708ABFBCB2375B77B25A985C608D83AF0A1049594D56F920830B98292E64DE1D6F6D748F543D9EF3847492DAB472D7C54949CEFFED40434519816E9C9C1E5477C209F4518EB441DB2036B7C1A4A26833A25BFAA6FD5DAFB2F39C04266A0E53F1E2886137943AD5EA9996206F10D5043C8E3BDA12122BB4419E1D9192285F153999A270CCB7BF0EF68E638A95F3BB416F670A8D13A4625B4FAA29B0E6DFE65C74F1007A3716113A3F194C6319D5FC3B354E2EE56C9C2CCF256A2CCB3B3B0E5BF573CAB638F826AAF85291DCBC01B763E83A834B1423400FC170B3112D2CB44653E6C17684CB2ED01CB247FF1FF1BB242F2519C73B41969CF912713F8BE34D5F9EDF33D431307A0F42481CB904E2A6A7D062A6E0A4CC2E63699029615F5F3B35361369A0D827D4052D50A8EBDE1469B1CA6546DAADFBBEB1424330BFB488BCA9B1B594E5E2962BF10F000098C2CDBFD9249A65DCEE7A887FBF19A4CE484AA3ACC53736FB24DC1DF4D54E6E4B37BBCACAD87E9E324BC5B48B7F8612575EC416219DFDDD225A13BACE2FC7498A92F6B19DF2ACBB8408259E4058A96A2831E71DC6DCB396B350DCEC403DDBF3262BC70721F1B7EFCF8653560189B70A78F4C74A0F1DE28490F9ED08E0E93C7AABA92BC52384DCB8D24B2B998B1D4345C47778832355A7B87C66987C53B0E0F1BE3A163CE306E2A9A579291C582E7FDB7A8845D85C6AFA78361F8B1EBE36D3B65D6EEE875363F1087DAA2A04183AEEEB2F65643E4D75217C8EEF3438052049C581187E405A792D1CB25D2BAC78B2F92BF8E90B60841B2CF13CB2439F2CFFEC0927B1C47D6415ECECBAD2BAC55122BE81C4C745B18111806670A4BC77C89B25C0FC79249481A6619877067D2C7B06350BEAD29AA0DF24D966F7BF5D6B46A2AE89408895121568F5CB93575A33E5CF7304A162C89AAE63C9F044D5BFF63542E60140E25EC9AC5A653CA7B2C8CFE2904CC4E829B32F3382E5CEC4D443DE510D970D17D42333B8951CDCCDB40FED38118AEEB3AB13A1AF93AD106620CF5538007A92E3354B6EB0E8DDC3A733DAB98BDC532171B4A44907E444BB13F44B78E5DA4BF142C4A8BA8BEE4CFE55045D42517016F86CD088C992AA15486A4236C55FBBDB052F26E15AF989A2045B647F5CAF5C970EA516696B237080AAEF314A05E76064EF8DE9AF726147B24BA2936F92429FD7BA2DEB5D1D955C73F81BEB2EA6471356E3E503A6C04BFE39E3CD98F9A1C8F10BA19C454D2053EB67B6CEE908A05A5D08B5E89D2B539D2123EBCFA9A8F9DDEDE7E6DA52B992F5AA88339BD16DF594CF53E81B6550B49544A70A1268D36A43AFB52FB0CB164E183FC7578A1CC5A1F162A1F0C86017E5B24D07BF9B554DF40916A35E708A736F6AE1732BE39F11265BB083DF21B41F92824A44E9A6CBFA9CD7803261085965F2B7E6561087041ADBC58E00BBC8FC111D89C36DA9FC71721451A106137B2D2A221D3F9A8E09171D64B98CB1EF4F1C", - "k": "C26DA6A23332B20914F703E7CB237D84F807CC7248DDC47599DDB0D40FDC1FAF", - "m": "7B334E045896C00F90D811489D491E8D72C4E3A22ED831C019FD4BD967B7A802", - "reason": "no modification" - }, - { - "tcId": 45, - "deferred": false, - "ek": "D0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B9", - "dk": "51901DD6E7BF9FB37046292E2CEA4037DB8874DA2A9B24403D879FC8104A512C52903CA118E159D235C9344B815908C62C99AAEECA688F8756BB844AB02A15F7380BF92BAF4DE4CA5BD05F5E66914C136838231C563CC1D1729B026190D5085DF49C01794541408A4C50042636804E16D3AB3FBACEB6798119436D42945A25860825025F21279057A775ED835510E2B99439CF13B7261A83CDCBE39D62E42DE49CC96C45AA6E8018779B372FA0A1661146A2A33924298920DAAEE3E81FBFBBC5EF514B0E773C35D76D8FD413E9D4C07D60212E91B06EE1B795E3B8734660C4E3C44F745CF2058AF3AA5A7045317395078193C53B034A621A9798208FFEAA3B53802554AB077AC3B59AD33CF7782065F9466A782484F6049F54BCE6E85B2C957460478B7070860F108655C0901C26ADFDF553755B1CC1634A2FC820CE1B3F190C8A81A78C6E0789478B1D6F594300CC0C91979E222AA9BDA73F1C88286C94472944AFDC97326904C982855EBA982068B4A88BE346D939A2C4316FD1268E6E0200D40C7A7F701003028F1A05A50A0355F8D2CA5FC074B7CA4D7CD1087EEC90FD77300F73214C68093DFC4AB81C2B718B278A411185B9C86C8237C3A402809C632779136C641BF938CA3650900B62BF2101B827133C014398C503A7FB1B98C23BC5F492AC50B706E387993EDA7707B9662F180AAB380793D9B77D0006CB4BB83A1356E6033BECF84111A89FCC8A9A1E313A1EEC78227206670854CE4C7DE9CC87728B8F94F647A5147CC7B5B569D8B1572468D3E012FC3558A59C6BB808A1E7F1400B7CC92F1C55FA9C6DB91B884FE4C60F77A2C77624F5185EEF787D8DEAA066C50A4E71A1CBE964F06674EF8730B4E8BD599496A6322F25093321EA618B624D7CF15D2E18426842BE2F289AA4515D86CA89A077B254D95E037853780A238DECCF91A1123D3176A68C40B72085DD5179A49207B2A7AF7FDCB49F536B8A4884DF25684736BBCD546551589576499F7AB43625EC30F3786214961C89E32FB2C13E306B8C85A64D68A063B43425110420FEA50222D9A78A0409A550A4CC633DF75843C2CC3D71CA55CE012733997028E8778709B30A4C03FFBCA251990A8DF57D22B761978149DF42C8560246C72CAF55448B7FF114D2245CC58453CF836E40A851D23C754DC66574604FCDB49DD5F74C1EEC429293C3394CCE920A9522B598ADD73C8BC8C71E5122369B4429B88B0FD08DB19690C65518C8E243746734F6649C2DE845E19A19E594894D8B5382639AA87C9806525BCE13CABCFAC521884B4E2B26BDE7632A9A8C581BC42F87241F1408325B16C46532D0522F51E7B3E7E2A7F4532A2B4B8710589CD6B32EA0C7BEB60194CE9372A0FA79005214FA45153CE556E724A383AA5DFAC973EC73CD7D6CA1EFCA49DFAB32C32B0EC27879ED18932140AC340006BC5CB547A532DA668684218B997325F206AC22D169FCE0BABF6A1B0336B1CC039776A7A33952ADA8E54706FAC9E4B295ED219D2C334A30149647720F025920DF980DA164B0FAD128D415652F3BB8DFB0AD6B23A8EBC776E1035E863ACA12C9497F189185C7C2591072210C97BCF833ED28302E388247D325302394D284CBD0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B94BEB59C105550656320DE3955835AB95443E5E29C3324284CAA26E76BB6AB3D0B37534D57066DAE72629C29DC0B9090EDDA3D3AE710D53C3EDF2C0A8DEA0FF08", - "c": "3812F9581A4D32DB0FA1D98110858E6539FE3150FBD28F25574851F4A073CEA119A2389B50CE230D6AB30EBC0042DF57FD9C0EF7A0A2EFFCC08765EEC2454306948221F8C2E6AF8415C2E9AF939A148CE20C052C9E56429DD4DDA625485A6918CE70A9319B5AF49392EDA205449C083B3A14096C1AF57BB39A1C9453EEDB85F69FA268B3404E686F9FFFAE236D97DAD29AE3E2B84EE8522ED3D51EDC12203620BDE2783C061D248CFF786AB3C61C5BA6FE1804CB514D872A391E968C1A980050324DABAA48BBD7878117333B8BB793B3198E4D94AC7AF564C5D4947163C84FBAD5DBA3D8C8FFF49518550299FA5323FE20C50979E44EF0D943EA1CA8D03ABEB261E09D0D0CC2F60E108D462823771C9E789500088462DF65EEE971DF976018CA33D38028855C3CC6B3019ADCC82F31F2EFC7C82AD3A46BF9EFE934AB2C9BC7EB7B2745416A3722B03DD7A6030C697E1C5318D032C8F506BFAF1C6F3D0049B4F9741A9CD3165DA27E955A116545BC5FA274980FA302A3083DD3025310BCE0E88D13D58CEEC02D6AEC1D1DF9D90FA8C206C0BC9E2DF2C9145503BD7363F1BEEBCC5EB6797F6732D7D0BD9299E2B395F75C5ED574513E17E2378E0F53DA0ADFD69921B88DE01FF6A2B94059451FA9F4D19864178E3FE343624EC063617AEA697960EC61C01A6943FF92D32EDA1BC6BE8AB12690ADC7E7983E269CB552DD01D5A61C549D932B9D936BC2B8E15375216C2BB391E96F021A7B1D46C625FD76E8A9111E1AEC67885C9DD04A72BDBEA5377E543A393B8989A02D65FD269EAF8BF9C8EED223277EF118D888B3CC8D3E0D9CB75CAA04BC22B7440260B74594C9DC2B2398DC6FDCF7B7BBA625E475E6CCCA2089241D6F3492E9FC35E29A3DD934E6CD0E3BE920B165207117C9CA858B88E57F7175CF1B1773EB8C292DDE4FA978504160C1F19C1FA4991FBEA15DA8700FDCD70B938283EB38FBCB740250CFE2510C85B5CBC1967A94C065A446133BB4C1FACB5305DD3B497CDEDE3440150868746E5A8E1775C07ED534793DECC83458A3BBD1110739E3668F3E1195134458D23210E2C973696B542D99392447921BC6249C84959DA4657E2D3C675520B3A52349CE7AE92D0900A085F3A59E73438C3281505744ECFB53D8FE24494D129BA778A28113651535D6BC5D47C9E8FA0F4AA159C3A9EDFC40DDD399A808EACB88EE6524B481217A1F1575A3F77A25A98C46CC674CD53C369B69755C66D637CE35ECA9DE6B660A718DA7F5A88E77ED68D99616CEA7165AA840F60A289157FA01DA864478A519686657F0D88EEB1B9A601F80FCFCDF430A07A2A86CD076497C894297ACFE9B9DE1F27B6107E19CD278E3AD83E135D153B0D8B44E9A4A97F869D1F6DF45B4C96722316D22023990BF12B9D177119B4985B0FEE3317557EA0B832E9745A9E09AA814E718DDCC077C2809BA164AC5AB1B47020804A5C5E135BB67582BF6B10830030E7656E09CB55DB575EB54ACBACBE80D901011A5F73594772368F47B7528D8BE68940C", - "k": "104177A27A18B5F35D2CBE9BFABAA2EA987B4296946DEE575B45A3A9B44CA99D", - "m": "947AFE33934E8150B06BDD1EAE40CF82EA99C0C0106B101283EA382EDAD94A8E", - "reason": "no modification" - }, - { - "tcId": 46, - "deferred": false, - "ek": "28C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1B", - "dk": "367C6ABCB47754ECB23287CB530C5F29BA90464CA083AC4C7698C44487B209639E37E43DDC8055CC936A0C3A4EEB215EBF7651B6D8849CF2077C5969D66194D6BCC1DC96B21695856E072D83194D4F2966C649A55BECA2E9D9BA3E9049F985C9F06311A5619975653D0617288EC85BB13626C2A713E1245EBB914E4EC7651366615470483E478DAD1276A3C46C08E0BB1AB4AD833A584DD84222E2B880450806426937626FCC4597133B9FF2A4355EE20258334AA20C5BF7639A215AB2FB4B3A4D74AD8D66C06EEB290D370447053F9EAB57FB42821C2667011A95BE07CD33847FBBA78F44C7B10537C3AE97C2BA653232827C9400538D4BCCB371B2E7BBBCBA0C34A83851C0236750A472AAA163080C562A40908D1585549A4F8C44798AC877D4C2027A2018399C3B5A03C278B20057436B1A00BD83B8ABC3B6B78D18B7A94252BED77128617ACAF3BEB1A937F516AD7D0330DC9694D7835E38A35E63156D0C9B48473639B3C1A34315C67C389D686669CA4759C41748E6A43BB6648820061C54E41B193B79F147659DFA83D5FA3EE7D195D0D826203899EC813070D325D943CE82A7194D3A5114FCAA71266A5A2CB8CC2B837D261E28FA2B12C5AF2C20C19DC6CB49559BEDE9A793A5B272F8BC357A291D55CC0347093AF3547D6913E61C4316E49422874D84342BDEB508C4B1259757C4D9D139729404B4C083B242A1A9920328FA912A5B9B1D67300528741C2A0D56F5870C1316710C6950B93E8535A8D1512891A257FF17B71FA46BE18167951BB87A5CBCCFFA8DA5C3C471144523400F7C06B6F6E9CF2595101D230CF4B256BEE416638389569C774D1B5A25BB2690B4BE446C4FF68B1C64D87CAB248C9E7682E56CCA64FA8CEF2C9C43CC8B8C265EAED9A45945B308A4A946399CBFE59541D144DBA75F72E87272996AD1C1752E1524DE6C8965735E7A12544283A7438264644B32E9D78DCB99B82602AF6AA75D10C645AAC8A30CA90B02C914FD512C1367AACD1C38FD38588F527A24E01C9118A71BA0B4C71AB6298845A26A24B6A4762A537BC6A0797A8725DB5BA56FD67038B1CF6ADA8E7B4887B9E369478061228B8985922B6A909FA318AB2477867DE299BC957087B26E11E134C3EA4198659971F69302618E1146CFEDB6210A99657C075C7A14A569780E6E94395EA4AE38CC735F7375B71A4C6066CF08251859036A9111BB21D03EB9294A756C7D3002052E9492500C77B88C4F9E41A0D347424D095B816C96EC790527D74928028A7F542F4541BD3AE06E11E24481B36F4E22930D29742E4A3F3D1B2126258CFE080503F9CDE8133A99D31AF41047269077DAD309AB705DDA9A7CC44374FDFBC26E771ECBA3A420D162DEBB440BCB87C4A993B1C656F4A0250B029F20449C63105F865A1E26E21915C0099A2CB0279A0824DC1DEAD981AF301E34759EB985C313C7488673AEE516655421997C811E6F3676D07C9D52C27022C665D7518864840F7536AC69432451A1C3E86093852B12C465BF460317C5311E12D3790EDB06B22B54F9B7018AB16E1C06049B774C68C35177F369BF2B6423F5175A76777E4A30E67489A1D0319CB1040454B9CD1C9976658DFFA43009D62128C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1BF710097FD6086E9C14C3703A3FE5A5573EEA9872B6F28B4A383B70F37099CCB55B07AB371A4D050DDEB134D78D044F9937A01F9E17DFBFC4E495051A4948CD4C", - "c": "20BA3A872DA897C006AA6DA3D6793AE2B384C1F7B97CFF48DF291419D3CA55C4745A4C5336D6D62BCBD9941140506E39B4E080A3E669DBC5A123A20D2ADBA8A47D89F81209CFCCCE9253A639860333201E0505EC1E58AFC7DF41EBDE37569A22D3DF0C6E1D41F0D32F8118F83674D681E907E1B1E7F5A14A9E3E1B3435B30C375F5A8776CE5CDA68BA32BDDC44B900A6AD0C0AE3CFB468ADB9F8B21FA3C1D7EF97C4DFE1CB1B4F785479FFE9AB47FBAEEC6A688D288C2904124C2DF76C5674813C92E8DC3F246A515D268E44FE1BD1F562B0705C5DEA91B9782E96E740852CAE7949A84C14ACC6996F1D5CE5B5A2261DEAAD4787031CEFCA49AE532FFDDB7E097DD67D2C22238D8279EE0F8D1657F80E630DA1629F0C12910CCAF1296F2BA404CE59F8C22A792611A8A4BA5C88D88971C86A9E45E0DBEF51D4D14C5E01DA5F2C46E9D031A07BD9BED7A4375C895EE84B57C6D14211D90DC327BC6ABEF72779C9AE856E93BC74F1D8FFE00ECFB2A212AFE587B0022727082FE09B79A130CCADEDECCA7CFBD852AACA426819A688E9AF837A6EB5DAE47F73B46EB48CE5E059403F7C5D522E3B7E26D0115677428946C516023319D78AADC641C7B3F7A1F6E5F4429C00C0C5798DA60CDCD79111C0EC5B4BD86CA2A47F676B45D4380D2C94D6AA360E6497BC9B25C092D0B58D8DFD0D315DE457D95C09355DD9B36950245FD8909EE0AD6A1637F4F00476861FB8930E81040CCD6224FF19D2B84D37D0C7A383C6E2CBB122B0167260EB0B47BB6C424123213AAB6C89F2D527E20275966638B194F01F16863E2371D45572FC0D63541B896DA6943CF59CEB74EF53834ED8632FFF4975AACAEE7818F7B3F0514333CEE2CDC4284E2CF68BE084AF748880988CF77011EFCC00A66B0B4C6EE5628A950984127CFB4322FB98A9FBF1DFFA28A9E5C2893F3CBA1DF900D9ADB533DD9A991FBCB94E5E5167A4C8FF2DF80E504679090B7F729AD702F3EAA6A35FC4336FD0FCEFA1C8532E60321A7D72FEC4F10EAD95D210479B060EAB5BAC9A3AB6F33D22FCDC514401B50DED0187D3483C8F49C2B00D39502689E666009DBDD1A0B9AAD5EE2F3A7EE70D7E381D478F70D38C1455A7A39FA854BDB75C2E3F32A01F42936D684283A9E12A10CFCE0C8ED77CA394930A68E1CE4383C25C18A93D26A2B997DF21F12BCA7A478CED58C08CD353FB91E01BC163354791C9F7B43A5A90FEA0ED92D4E9041D0D9C36F1C204498568105DD409FD71A3A0BA7B0E740EA3690F5B8C487BC026DF1BD7C8F9C9B9BADBAB28D815D3EA200A9F75F0BB9D55AFC4AFC5F38A0609616DB5B41C7AF9479003BD2F1868AE2BDA2682922CB1C90270DB852FEA6F7489E686C85C20534151D94DB33367F02454C415251682A53CC2A0EE1A845A77F6DD04ED14B3E0B6099375B7DD10D4412215F2413EE326DDA5A4285481A2A70CC0FEC98DE1D77A8FF93BAC3196D7610E842B6A3D2908B61AB7A864C0CE2DB55D3E7DC4BDE89766BED1709986009DCB00FCA4BDC3", - "k": "A2718B4EB96D591690F62FDFCC264BC457C3A1B755F4CF64B359BC945C254CE9", - "m": "DC8510F45528D6981E59C1AA6B743BB844377D7339E359036929F0EEC54FE63C", - "reason": "no modification" - }, - { - "tcId": 47, - "deferred": false, - "ek": "4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A", - "dk": "74D0A332727A99FB07FA104DBAA09E120A80F2C3BD27971D5C8283E14C587A4C1064FBBD25919712C34D561270980352939739D378881F21813C077FD4A30A14873E01FA659B567069F9BF7BE0A94C9B2F62A9243C986F4B8671074BCCE5421FB12922F8B9BC50A9B4A4015F3B58BB493B34CDB7909817B0E1CC76F4B71A6BA45E32C03152D0BD972B6C557A3E84B62CA0F830DCF55FAE743AF419C75B253210347B00383043B3BC5B9425DA8151294C03FC422F1C22235AC1B3D487C84D63882A504CBBCA84CC192173225FCC3BAE53601AD905554BD1CAE026867141802F41111411824580837E35B5B4E47FA3173530A40285000E695610488407ED986041DA7B0059A054F1877BE8887CFC028417C1D78ACFF8A09FED7B289BF96F3F993E805CAB566CC0FAEB3A29EAA40A2820CF20912A1A4F3EE1C5A48C212C421D78326D367C6C41E7136E810F8A8B00E2514AC351358D574CD0F7344A121B05131B05040EBEBC08D0E203599503F3029EB3A586DBA5862F371B78852338281982B1CA30C70580ABC429D80EBF9A972D9B026FF24C387352F63943131AAE1A804B10D47059E00885EB670D462DD36BAA0FDB7E798915A0688D6FB3313B100445465E66E35CF664B060E399ADFA9712A32AC631B542B66145505627C95664A6117BE68E7BF3B12FD53CE02B43AEA449652A6BBAE782FD4178F832C766C09DFCA17686E57CFC563B32A43566C30BE1A85A923A6620FA5623ABCCF5133CED5499D424A67983620BC519BD3730C51B6E894BAAEB516A5AF16881619903B3051243013E6B8AFD20B2AA56ADAF436EA9A9A59AF2922DC07B644936C94B0F7E4057621519AFB8C53485BBA390777C591BDA7716C8B1383141197DA00CB9975B37C6A8DEFBA0E45563ED27336F3A19D64AB0A803A7CE5A5D5C2C513A1CB53434681AB0AF7AA96A946B5A598A15C6AC54192B447ADA0B1DFB08DBE72734A87AAC6B4F65CB9F2D319CC984AF4428A41825A504C1963B719548418A79918A5723514155389EE70E2DE0BFC46706918B7C0EE0022CE04E86B21A98646850A6329E8BB08EA78FE1633B4C64BA32C4B1D920C543CA6DAC053338716F2F194DDC8AC1CEF24EDD52CB6EF39FCD6B5B04C306223BBBE511CA8D1315C56942D4EC321C63331F099655349F174A0A4729841C8B5DEA646D34218E9DDBC48C968B6CD949587922D8CC9E94EB780055663085B02DB26063F14651218B31210A74C72CD273383FBB1236659F4EE69315651785C822B425BFDEB96D53D674118B249EE6AA963C31CCB76E9CB068C4681680FB6167EB6AB3F518CAA5175693843BCC678E0C5477D93CE95ABC023590F3EA9708FC98C7045C75EC3905662DBC485ABB02A23CAB7E36D6B48FCB8E43F74D507BBEC5CC827FF186111ACE6BB1B2802C5EB9552698C320B523A692F68112267BA5BCA8C49589352C17F117078376A1FDB6B91F9C6ABB3059BBC53796F90E0FA575DC203DBB893AF1B7AC43F2050BD56A8C4212F055AB9BF7579EB809BF9C71F64BB3D6314AD5E8643A4240F5AB35880905E9D4176D25567C502C4C103910F78356C1C47867A9E2AAAD057C909865614612AC0DB4679561922487116064BF4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A159FA6BCB8D2EF121A97A25B0607D94B3DC6D5D48B620839F143E8BA01BDFC55E8D41C96F1D340408D550400AF1CABD517EAC8447644605BD2B50A850216815D", - "c": "473A1EB71AE24A5F5F3A2FC86E9F48EFF07570BAF66E36C2C86453424F218BFDCD2338EA9514242A877ECC28BCD1BE87A71CC4D413ED8A2E3EE4D3209AC01DF03EC3B28FDF3D572B0F8713D41EF8800C3C1DD4B60AB084711F9B402AA34593D1549624DB9F895FA48314E0AE94DBF0EBE54EC81733DF6B3F5F38DF0DB91F051ACCEFEE0B32A26EBE37A5B12302F3F809121E879A7D0A3F29F5F9973CAFDD09220F848F03E2CAA1E64B6C6AC1D46A9F9874796D63738B11C91D9971AA2C1595A4148B145379CD0DD606596CCE45C334255BBD6761C4720870771CE40D8A9D51BA655854915F2C23FCBB0D40930B0EB27C96356A6C5503FF5453E10DC198F5D2AB476988030BCD2A56FC235EDD3538E997D50B3007CE0D28E46D2FFEDA62545F2AC5D6ACEB37B089C900CE167D68D358A445D1BCCF6429B810E74BDF07E04CFAFD5FD30E59CE541B2BE55AAFA1B928306715741BD806256E4D71F9CEE10A119D6C8D860866324901C8E582A7FD658EC83185103F7F0C9E9230052F0DAE235A93646F3754CCB6FF9D4E4E1CF47B262E5ADB4412376A3D1969CD7B2413F37382F665E642699696FA9868B25BEC0DF374789AE0B476E206194691C0EA5A16878113D39903FF112207B36F7617D6A06B864AFDB5C83095C194A71694623C31EAF91CEDB387F5A1DEE666B6EF95065222D6F98384FD59005B2807A68F3BC75D99D298C7A432B2160A2079B5A8AFB97EA67F37588FA5E246FEC3BF82E18A75370BA268A4FFD85B957D2A573F23BFB004E79ACCB100087065B33DEFCA73AB7523F17AD2C17F76773B84646D92CB3187C1F6E5B74EBC7C7DC71048C7358F21F029B7DBCAC8543CE74BA6C59625E7897832CEA6CBCDB64DBDAA3E603A9374F16942E00C2BAFA6A44D9451365AA1B9ECADE2963C8BCB79FD2F836229B8BB5A0385D39A017CFA6F875DFF4CADF9E9D9290D9B7BF6D0F3BC009972B9F15D330A9EFCD42246EA642209A712F922630EF2AAFE31414F0C4990513C2A208BF7D230ED7F9827C5E449E32FC4242851EB2D78E1EFC11C26A15BBD6DE677549B2939D075A0F53C3BECE462E56ED9324878928B58A85A5269025B9FED7080D77482A4AC5747310BD52367126B6322DABDFB5B75CFF41E4AC012B1FC141285D6533A78A8D13DEC193C1826B20EE5B7FA13FCB85E514FDC69C7D6E5C48633F2E7524F9420074719FF206D5E1757FF9512D4F8B44FC7242E9DE11DA99B2388D1B0F2327407FB01E5CDF0A24C94CD9D706E9DC8D0673DDC5AC818D96A221B732996DBA40BF68AE1FFBFB6FC1E0294908601D3AC88D76891FE62A93402D69EF797D2024966EEC8E6B96848F0B9E39CA6CC80E0C4556EDD85D6E70473DEEBEDDC4CC49DB1D41EF18B0B3B3F17E28B436C29460B6C9BCEB3492BE8ABAC057C03ECA4D266D60B173D206ED77C1D3480D7666DEC028F31367BAFE002C9F63EC6CBA2528D72220D5E987CEA74E9AF7B3072F681C72D2E6DE1DBAE3D8ED43DA7F2F5AC75516E38F5C244D42B061C3538", - "k": "E87B61A6496FDA38F948EDC5F9CA5735579D47F6355B214727EF5BEB3C13CA32", - "m": "62A2DA94F109C0DEF56DFB275B1A0EEABF82AF8C6CDFFA94085AA93015BC1821", - "reason": "no modification" - }, - { - "tcId": 48, - "deferred": false, - "ek": "36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70", - "dk": "705A6AD224AB8C18A1DAB7039A7282EEF71B9AB515ECA53B257B43E39C5890B131027737F089115599CA3513CBFBDB536FA39A872CBD8DC10CCB3CCDA36CB910902CDECB4522AC2146A39EF42465921A767F56670EE297CE2A3C67A24D7D55540DBC15F2500831F384E9D9646946A4D133CD0686A9F8AC3919C36466AB2B72E668B1659A81699B5A9B62C79905D6F2674CA471BDC657FE973FF95437304708E88B0805858077D28BA3632821239B2C3174B21849A0492E4B1B6A42D39C656B41277B0D8D868DCE06906D82210F9424FBD1CFD81134E503AFE93AAE02574AE1D32608D92CCFF667BD87B45F58ADD75B79A2912A73672F0A9794086084B9F58F21B7137FF42333B47661FC6695B56AC18996064606B37426C4E04A9173425B985B6214ADE879B8A0116309466BB0408DB243A39E123F3EC68E7D47C7743A22A062A12F9224861069BF8C50B80A1799AC28BDEB43FD0A3F6C72BE1AE97699A1607B68644D09A546945B57E69DBEACC41165C8E221031DA43A41B8312E3A1C1D1C7329189EEACB0D9946600D63B533ECA1EFB11C3E6C12D888C0C8C331553361E9623CE2D29854FCB3064A9054C93F7142A8862CB83529183BFA66309858444293CDE44CADA626AD100DD0D76DF7C07B455C4A7C3B04354529445C9D12B65B0C59A7CE3C7F350619C1D3A65AB314F624A0F456715A1CBFB970BF0A571F0B9C78766014FEB46CD750C52A06B5CC8B5FFDBC8754792E44B7AC0B6332BEF32C57976688800EEDB0482062011E99C801CBC5A42C8768624B84DC4FEEF6580CD86275891B460218A8E652CCF228251B9ABCD9A9083A5AFE088BA85A0F1F10485784903623C347F9554EF0722E605C2D8012CCA89822500EEA037C3F319F5EB8A070373F34196842D96BFEE44E1EC9904754A3A143218E23968D28A83F91CE70908AA9178336E50688A446BDD85E1DB69DB9018A88D427F94474BAC3CD473A687201801D590277736C10047ED9790A33A39FC3267EFD154351956374339F50D75EF0F61661B68E7E59111D153505DB69E65190F80C9B64CBB77B958E83FA82F9CC6A945B3F46039D3B368E18A34CE7038D597C2ED16833C3F7B286EA17D58CCE86DC4FB7F1007E9A4C64F573AA053F778B9ED71825D97C8E1C52C953B08942A1AE30935F8765787F44505FA38B9CD93258F0CA6D34269852786CA82D980BBD72254D4D0A9C1A8559420C232E98CF222A469AC9893B6643DE6A499A53B4E73A9D989A615D3A22507694FC051EEAA27274BB3F19938758E90BB83B0999BC43A90B60D424901B7522220414D5D475AFABA945DBCD83807A58D3B5C4313F9F7027EFDB2299E873AA6A18658963691070D9A6A8C8BC061FD9935D521C0B319323F1B7209866BB052207B6AE8FF81EC8C12A3E035E29404FD28086EEC313517BBCF4A173F3573D69BBB77B177615874C0C04C0138C83AC8CB576E4C29363ADC8F88FF29A67C44952937B7ED61A1A0F11147C345555DA1089B768D7A0751875B44E36A63488A23C281FFC518E4A548D3EA6491E634AB97A5EE71805F5A7C037E2B2720CD037A2501D9C239DA14A618C2A53DA7C7D096EC2D0481B70A1D45075F2A000F5C60EBF9A8F36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70E1D563B9DD64A334930BDF5141DF65BF77A06052C9EA81679080E231A8A61E0B97442F30F0F28F7A851B0D3E76BC74DF890916D2ECBA20DEBCBE3453655F78C9", - "c": "07C9FAC7CCCF6B5497C9BCE51371F26B574BE236DB8009103A7617953AD68ABF08A3F134B5C2807229AC884903D3B6B2596020D6C789FE3CAC6468EE89F4004C037125BD1F848B1731424A94574AF2A67ACB415E6EED82167C590C61DB7B34BCC571178794DBCDDA2B404B4F4A25D17EA1503A820504BD0819F248F472B48FF54B3CF01F8DD743ABA8495AADD848F1F8B3114614463FFD7CE3E9726B9F13F2A4DA5DD7B761C484E2C98D457FF788BB5DECB6C9223F112BA6A5064854056D3884DFAA65A677C13E785CB30925BD5878A1515087472F285969D38B937458F7A8C968BB86D8AF7EB851EF950F83D554115E84D743A886F7B2922D581499B36CE7A049E35C9CB629889B626620872BDAF1B31B1BA08545CC57D2680B17E21F0FBA6EA16EDE8B956E497DF4C2960221FA3D697BB33CD592BB3D370834D9A5DD325ECAF88B87E8249CC70643FC807D085B357105B235800A0A7260267A9C1888D9CF620AE27315EF42A808BCBCE4D705C63EB5319530B228FD233BAB8C53F84277037A441ABC26EE386A06028BF75470D3B2CD441E93547F519DE930EF1871F96FEB3210FBADA58A39CE69417137A9EC019A12CDC5DD340B613F6DB2C08AD937EA3C31B553D40D176CA69643ED16CB525A1FBDA92FF6FA87528DC20022B75B99ABB49A5838022F271698EA91F25D3613A34C686712A9327ADD20F2324E3A32C5C33F234F879CD28024E312926C9B2D5C327AB26A29CE4E4200D23B4BA7CD541370AECFAA6A20AA025B969EC6017033B32798CC20E3A2C69725B5262ED9B8384110FFFE13687EDEE0AEACA60DEC2576CBE150508C25E69796B792F28A08DF7A1949FEA5FEA4AB9376CC4C3A604847CD69B1ADFD171983D6E894FD886CBB3F1CF3704ABA6EA413D0846CE803AF766B67A37A058F95818AF1FACC2AAA90DE7CD503A188295701F1CF204344E31EBDFBAEEF2521201DBFA905774C31791F7A766E4221611FA3D0ED8F0CC491EB9A8B8A9994073D746619FB2BD6A11F9770C0DD00B17D56234240CF014BE52ABB743DA0F9CCA508BEDE7BC5A011DA9F24C55F1AC2BFD18A813CA6A10985FCE51722211B8A6FFAA3C793D9CA4675F56B8743D454F78FA5EAA75CF80030905B844ADF4FB15EABB755FE5BC18523C8BDD6CB75BBEB3EEA082D9A7FBF97F409CE8B92F366195C80EB216C052C45A1915530BA7B9ED90C6ABB5B13B723759FCA390BACA96C582DE3B3C5D4AB46A9DB5E241935F12284ED11BA6AACA5988F39D2F0196DBE0C15640DD2FC44F206C60C936C53C4443F4BAC175BF5C60C3FB28ECC4862C03AB3AC197577B3CC4FBA1289733124E8E247392D7C87AD9E365A46003FC510DD9C71194600BFF8AD87792F251E9141E577A274253ABD987E239B69A59CE5277576236423865B59891BA9BB053CC215CF0F1885BF5E54E33CE85A9C2D915839616D44CAB2E34E1E4509F49FBA104E0CF58A8327A6A7C53A2F3508E34568923B4CD21E1B31D7B985A290D08422EFD30715EC0F6A0EC0DC7789", - "k": "2418BB42B89BA875664583EDF241327F3798379BD14B64351044F6C96B3D2C27", - "m": "F374D3C7172C308D7AC5AB1F1CE5BB9785B98AFCBF4E9120B42EA83BD3BB1867", - "reason": "no modification" - }, - { - "tcId": 49, - "deferred": false, - "ek": "75F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF", - "dk": "95A85BE67984E9D6BEA070223A469C08D73C6012AD76261380F45A7DA43CFC831E92D55C566BBDA6E6B1BFE83CE7E5523829C5D3C2B5CF874FED240032B43A011823D38856E519868CB0A9B0433A51167835568EBD67A2A6991B8C529E9BDAA0A4A95BBA93480909AF3931B969869C3A425669B412C60B5AF2D6B874C98E01DA95FD0672599303E25CCD42D7B19B73508CF286FAB706074A98437B7C9B7357DE242200AC71FA8636381623233135E530BE92E83133092B17A26F688919C5A45634971D129542FF2362E94243F2249B65C9B2F9729FE6425E76E36FB88019C2A863CB617C58DA9209A92C2A405E35574198E83739772F63C97CD90753795C981C81BD3CFA384A6CC51DA15F21D7BDB87B6CD2BA10F928C9AEB1595A4539C8A3600331B07256680E4C0648A0A786747E00672B08DA47F29A3FA7D9CC2E119BC6EB579BB30037F66ABD645951F499FDF12ABB3C979FF90E15A5397D2358BDD6CEF02B5658B44242A74573D41C216554CFCC2CC4CCB48BC488ED5A450210CDD0FA1D04831E14514BB93148E01BA975B71E5463001CA8330AB2064F31346C716ED431BD91A477C660535D88B32E3AAB39C4A9DDC2BABDA392FDBB3DDB3611E06A42E1AA18F985B8D202C23A5443F5B6C161579B6FE0C2A1A20347B2A48D77CE8F954F7EEB193470C90A66B3EC7266AAE78BCD2469A5573ED4D2CFB600A7764364ED47C4C3DB97E5E5170361C09BA07E7B3B16D07432A7100F0615506D32771A7258F1D33B71101941A148C6368C9DCBC403037037F6BE9620BDFFB418BE497942C410C6E6A957E604B0F4467678B83BF9BBD628BF5929A63C6170C065B6F5D84D7E2BCD8EA019ED72A600E6AED7187A1CAC1506F95127CA235AE9ACC89B2CD709C18FD895002C3B2400C38DA16DFD7B2221D9BB212A471475845A58B7342830DC49B6676516EA9BBE4C458BE77B6A99E518AB1C1BB8CC54B50392FAB00367940B790C6AEE35B587E6060ADB3C92FC579AFB459B3992B6E110776115ECD03C625B9DE1378C85FC5EA0C8AAB6818D123A5F20866984D4C6D261156E78A15D322E9BB4B5B288B6E6C03ADD4A9285ABBB460C9D2C0629AD7CC48351BEA588848D95283995CC7C081A8BF453EA62B3AA48608AC2BC02067C93D01CBF1531C0B35F52C32BF1748E56185FC4C24127E9CD94A9C4E8AB12C38086F5A17B0234A41A6C772466255B1C8F95C4BB4D7048E9A542D8B7B36DD59CB3F48F08891B2BC6590A179787CC83E41453438CBC34318BB0B072AC6A013571270194508986BD5D74724BB22724B2B18AC92A3939C9589A03448B8C8E812C4E2486501A97ECFCC84D3A32824160EA183C16F3839FB20CA8FAAA4ED54FE9625993F1A064809537525F9872AB31EC9B6AB922CF6806714959AC63A89F51570A98033585A99E72713DA18A34C57A2E5A558F56A04E185864398C56888FFE66ABB96BBD12B39DFEB0909D0A932D6943031693F0296373246D35767E74B4C29EF52ECB1B371B77AD5588AFEAD9CDD978331B7A51E4C4CFBE9B17550C20DB02742EA8737D8C26214791F4EB3D7CF1329E45600542560E9A350CF74412F1681178A0ABEB6706595084A19D8FD5C99811A275F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF3220B4816EF8681B4DB93059811DA8B0D65AB12AB874E57F3B09C33BC6C20A028449B1C5A6D50E3AE0E604C9CA666594335BB1B083669CB54EE7E960D8905C8B", - "c": "36DC4E1498A52C255C5AC4A9A1AE3F17F8472B71548C919FB7C2F3ACF0A35D6FA8584307282CB7FC9B5B04E5E1047BF03686981708A62ED593B6DAB954F39670036102A0BB348839857A68212C783319678819F6CA6CE1191B34D86157838523BA0A69B7B695139C17C21FECFEEC191930E81C66D1177A277E77D714B2EDCC33BDC89A7F14A6B83862300AFA860F229FABA58D2B2E8C89C734591E7A1CB1D65D87C6A0841B78ACD1BF05BCCCDED0F27B38DD27E57EFFF3BC4C3E80ABD4A78F85D233EB8046FF2BB7EDC87BABBD280D1F3650A3BF621A23E0C3A7BD42F8AC90B0F741EA3B3E8D65F0B1774FCCAF35FC809514F5D4EF303D821A2DE926BD700B085B92BDB91E8D04B6EC23C8000D8E1426EB7743D999B845E79CE993A83F202E2E82B0B491DC6BB006D9BE69311BC5E980A95EBDFCD65DECDF42B887C29281E8F8C19607175080D04485E5DFD0F84219A5FBF8E94C7C16C44F10274166CE965AEA357AC9C5A2BE63E47603F6D4D5469308793D8E3F6ED473AEA36C68E3F9FDFDB97996B34020978BD69410961FB216DF9F3349CC6B6028ACD3255EEC2C14F2341858782B8C34D3141A19F8A64E989F70A6B67B200E8E482A2E271077489B7C97D567449E2543CD5735D7A70DC1FB26539B996A550DB92C9857C9687492238B108B40548C22A5442150604D0C097FB02061F5E45552B4B443E7F31D85CB5BA9BAEDCD839445613E9C9826F1427755A36988A7E175E729D801468F986B6A0553C00562606B032F7580D51AA5DB6CD214D69E8636A8FC957E7D3907CB5A33B2C80780B7D782E040B9914A7B8EC51AA7711B9D27581FD2D5055E618467D2EB94B4FEECC66C96268C62222E3F438293C2733EB921706F1D669B55C3EC9AB54F6507A4E0D742494B8788988E9A628A5F5C1DCC2C5AA659723006BDF0ED4E70A8CC194416E11F5BC812599ADB937A25B302F6A371808443377EEF2E2A3F8C7A3C7294EC7D7FFF22DBD3BE07F89207B30228A20DBF432CA96549794514BA4BD27C0FBAAD1290505471E7BBAFE53E039B7476D4DBADF13F1DBE83A9101F58351682AAEBB435C0AD8FD6148981AF7885A9F49E7A802BF226182597EC5BE5DD5E0381C1D72CAA2678D0FC4B354469669C271D331C328560055057B25F92FCDE0BC378AE6886434BB85EC96FEDFA369DDCE4F36F8AD8FF79894A1628DFC68CD53542EDDEBC0D92BBFE2F7601621693B10AA2A3CE2ED2CAFCE6BCBA4E7B0BEC2E5656F1ED4B751F081BD4A0356B89815F724A823030979AC1D6C8B1CEB63980717EA24803B2D6E3FDD9F5B4A3397F4DA86834D99FDD91661CB1A808A197F9FF122B2843B0E4230230604640D82FC26AF612AC980E6516E1B6C5724B579154EF2F770983C0BA33B832C14B691282B9381AA708E49D812F7EE180B0F9858D4D21386C5D60490083ACA768181C2840E5EA30833C3FFE79E2747892AB225703396D792BE152DE2E8802264B2939296A9E1733883F430F372455D520B839C0DFF54BF76F2BA87B4A5960", - "k": "2F323DFA37A737802227ED21012FA0BA624F532F8A3DD979AEFCC554C1C2BE92", - "m": "DD252F728FC9553CFEE90924565E984C8E1462CDE58AD8C4ED8DFCE98A7F39B9", - "reason": "no modification" - }, - { - "tcId": 50, - "deferred": false, - "ek": "19E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A1", - "dk": "D9758470207110D1C1DE602163F955BA262CCF3564AFD86DA03047AE9C63F5A67587E008CC3423D221949505C534B6998900114A3B6775F1715AB139CF4C8C5849A034929F957407C4512091930A5B9A38846402AAB49DBC39160B0ACF4B6A3E9EEAA095917828F28F667C9904B8A7BD4C231652A32343BEA81A7EEDB68AB1229FFD16CAA46B67B9F264150AC2DB97CE09B55E4312654E9012F2699243F41B380073C6A5985F87125DC199BB05620455A2BB77222764C9D7966CEFF2467D632964567CBD1B98FF062CEDF1C23A31B891C48C0B3833660C3C39762C4A470C85F802C5A03FCE328B21A658391A7B417B2EB5B37EA1262817EA78BB72C833C08CF74C9C34075AC0B975AD6ABF2DBB1AB72A9EE5758A1E47B1E5B41506D39995D04CC942A0C2306BF270CD43E1373F82B2DFD8A0294BB2AA37C762684969B2046FB04DA621AD990336E2FB3E53780B311872F9E581B1890A67EC4951C071FD7091DF250F06F367220B0EAD226286E6BF1DCC63D0E85A2C64B39BF924C3716F045411A54A31EEC41BE1846E08649EF19C78E1A938CDB1034BC5879CE91444BB126DACC12EA2A32D4C5749E3C6F9E270F1B4B0E2244E3308014499CAE3640E96E4ACD5F1C641D5B2E1CA4B9D65654CBC2A53499E643A9E9E1A2453EBC707A20E070793FDE87E12F71FD060186E5690E5B031F858CB991714DF959D6269209454360471C4E1E365DED681636B02592A2747F78EFDBBA0841C54DAF980CBF728EDAC5EA7B9556AAA7746CC209408495DA8547E392A4A02887618A7F7C25537596254D48E9AD94A52E1A334A06D2A22A358D1121C9A81AA6C1EFC08B3C8356212F259699163EBF1A31EE845E13AA10652B41580BAE9D683E8B958BA95257E947C12B04DC73299EF510FF5C94F598524CE790D21372728B38AFE966AF114C2DBB094BA216F65D2476E6B5898BB2C72A0C8C1311A81DA95C0B03D942C81ACB73BF13A7B1C22B289C0A5DC7C8E9A71480600BE6F5A14BC7340C9290C03F984EDA2A8499534FD0BB96BA1B4D1335974350A32FA9911396C3BEB940AA1A87C86C3F08C393A18CEFE7565EA6402F8C0914735AE938C3977576CF9941070583015A8499E84C588F13F9BB29FD278659759A08978585CB33D213CAC9270BD7AE3C6A1612523C8ABF8F7C4D3EAC1F6F7860F02C9316005C647B30B7C3E75CB73CBA301F2DB327C0B38F7223881B70456834565B3B0461B030EE68891F22F09129AED4613EEE57DBF0ACD9745ADB89633EDE163ED1C3CBF935C5EF90E4591C7E0B79E2CD629E9A963415B1071256BC2C3905BA30516D01B3CB1C10101830095BBA6D08E7F2006AAAB4B11852A0E2C8D780001C99899A65B96E6BC3B68D84F28F34FE64A9578C078611AA507F15BDBB99DB9F943768B1D4DD6A335D6BAAAE33288B16EAA6496C312B0A08B052F9B9552E23A0EA59E9FE329D461A8CAD9176BFC7006E20985157023BB503599A1798AA89D406FB3E4586F230F797CA17D121CA4AA568BA579AFD8575C801A734083F9214CACA3C6CF3ACADAAC27BE1807432C11CAF806C66953EC6A3F24390FA4AA78F5B90BBA061238F9817FAAAB5D2AB0CE8A3CBB6C686645C6A08CC919E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A16A3A54F67614A889B92ACBD1D3EC4CBD6C46E8B33FBC2F3C92DF3887DC1DA71A003B9B894A4AE13E6F46DED925CA80189437C0910FA73E146A646178544922DC", - "c": "958FB0A1F80268072D82D593A66B039E548E205C63A4689B48E0752F9041E5D1C2246EF6A1BEA2773CCCFF2A80059C651DA70EAE2AFCF2E83CA15AE29684A11213C01E0DC9F3A25B492A8B44AC188D187A24A6A30B82AA7BD80CBFB992455F280D0D36D2E0A0B3EF65606D55922D29C5A0920D57F8F6EA2AD518B41CCBA23BCC35BAD2E844B5D9000E36AE1F1DCB3D3CF23922D82446506038D5C33925AE96E174876F0C96220BB775EBEF7AD0E48A1E1C785633F6B3585F5FEDAF521F8343440981FCB72DF5860A42343824A0F43A0A371E7D41472199F749B310AA32A5769DD29328E60A7424FAF2D90E6FAC34653B5F59602785FBD09BE26D184B61447327F3772A072AF1A7D4317722AF139EE56D4A7D765D6D73D7B13DA6BF4ABACD1B82320ADE56624CC75BA78278B38F4F4E17FC704B5C88E4800A6E4F626DF21974E2D76AD9BCF70BB9826D790D8A7BF7F23FF9D03021D9B6F48D89D855F4D070CEDA92B28915EF2F77BB79BF80D9E03D9730F1B018AB3AD932588805E995010134774C9C061D11BF852AA5C7403515956D29924EAA1B6BBBE4E4BAD554F4C91F67A268744A12FBE28C3D7A403776DD742431EABE6EE093B988B7F5ACCFF53AC714E03306773F9E54234BA12B1F35421CEE91D81E8A2F91D8AF62733A97A93B1FC2053216083044156ECBFB9919B25C9F3187E07FAE83E9C662AAD0571505413664FAC5ED94C5407CA06036B8C377D8D7D306E1548539B5219CB3DD77D78475EC2FA6DD4C06121230D99151ACE36BF3A3B8DEA00636EE1F6E80D3604E76B3A8E13395B4D590A389F492931A6B37EE27DFB145C1F5C6EEF8615E673E6F6A44BB69F2C19E83A1BCFB3ADAE4815C2DFF7C8A6FA39D41D2A95BB4452D3AF38221754A41E132BFDC70B6B8097D2EB19DA00D55D8DFA80C59070D325766831451B932C2686A71399DEB0F8CF3EBD32C1F6360C1106522BDDD3F3D061196372BE337BF35040A57D1BA098AEDEC56ED240B8AEED2E8A8C0ACEA5BF4109CFD6C55DEF7883A848132BA492FBD364A8B0BDE322EF62D907106F07BD44D97D07AFBF9AF057D7397A2FDE829123FABECC1890B08C18EAAAB2F32B76A7099B3DC09EBEE6B9774AAEF06EDB414E5DB1559CCFA65023D203EE7D867AF48931F06BB86B3AD7E9C0D52A8BD97027A9AA865CDDAE57853BF8F3AB4279533C5D83F240F181A748BF0761CA97130D59C751F8C87544E93E98BAE954EC84AACE8F70E2E6BBDA10389C825E29A147415FAE1B75DF6F1F17191458081EC5CC791250805E5BC1E51273AD723BCA56B3C99FC51EF8B304B960928BF40737BE291C9FB3BC1B051F8D40DB99EFD3260E0121C66336F78901451D3A2D1C2F080FF3EB5480295E949BE9CC5EAB852483B6E7668C6414CF10F6B416603D82F517224FA679BF3057EC4F6DB856A010B74769F78171156A7A604B1F63980A4AA1C8C57442A1596FF8605F3BE684C1D0841F8F4016EC54F4BE2527349B2F0B21E926DC01D324D5842ED2A69290E908F5ABC8855", - "k": "C44EE4E3EB80C46D6BF5CC3E08CB93019C8C80DB0CBE89708E8A6902DE87B699", - "m": "297ECD18E2880A596F572B66458410A0D827851EFA55F1C9CC513F7991F0DA0A", - "reason": "no modification" - } - ] - }, - { - "tgId": 3, - "testType": "AFT", - "parameterSet": "ML-KEM-1024", - "function": "encapsulation", - "tests": [ - { - "tcId": 51, - "deferred": false, - "ek": "307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983", - "dk": "673751CBB596541131C66398662CB4B0EB80796A88B28144A5BBC854F80D4B35BE0AB241E4795F8FBBA814F50FA80498CBE8BF68A0A583A4C5981B41DF0667DB614A628C3060697438E62C8D36026EE29C96B673BF1A194EE49481351F4D1748DD01CD023142F01057142B741CBA8302E432F88C63D0B4B5767AC3A5A59AFA3A321E65B1D1511807A06E16A04B2F1070E465586D4A9B68E2B42D57A356FA7BB3D04E51B193FF4C757CFA0F15924EA6E49AFB83B2919C985869ADA544338F44AE96A874C425AF87BC73F3CB0FD2627B1539B1F19A77E36B7FC817851D39BD8A069A6C2202C17469D421A588E65DAF450030B6674EC1C734AA25414B119E61B26EFC90DF81059D2B9599414F93692BF45A4B1C5CC09EDB37B1B1433026AEA6B0200722B819C7BC061C53A4304992FCA2AEE2324A324AB91C3E5D562096B8A141756940F15A2800C274EA4F65817E639C5D2A278C6A294F9DB331F84CCB0A10309F530A06EB962573C86005C15BFC7531A143026396721297E25CB655A294964B2FE531905F2802376B8ACE35AE3E2814BAB7062BC1A840657DBFCB5F41BB55475697849A31E2222E995518CA7640AD4B9CEE9820984138BE0510FFD6AC225393A5F0CB030528CD2A0610E78A5CF1B073039A6D143068C53DBD15A1D4446DA7B310EE795D1FB31B2F97008F83BDF348A593A3BDCBB571907B36D0978162C253E6F50106C463149834ABFB0707D8AB4A4BABC323598A085B309764B7C32C9DB0C9F2D52EF2F00BACE7846868C33B82AFA430A4C2F67B698A60526A161CD62115DCA767C203E3E2CC787031A73B5B7DBA1EEE5AB04B77BB569B952D9A15D198779804197D23C18E5B055F5C8087D742F64418D6505E70418ABFC6B1BF7BB3DE286599F4676CF87946D65144998AFAE1C689449E3F349FD0809AFB856DDE4A94A2C0258D56432F40C3DA812D3FD3B72259A61D2882E0F50B355121E564C6BD33366F32BF4A5996B9998961354925A2BACDF48056118453AC3792A7879B71579ADB65F5D83B1ED6C8C49836DE379DAA027E62B96F683C1688935CB3FCCD64329267273E60C6CD59BA1B7FC911E2662527ECCB7A474E5EF00CA9F789A3838E889242E7FB2B08F3790613C4EED3C912EC4EB029B971096B384727697B4DDC3B698C9A6DA6971FA4C574ECD18EB1C84C0C5790153AA6B9DB61D8BAC0A680A37ED623582A7E8C0885EBB35AF341477764368E0647B14553672316D0B90317C5B53AA747E61B4750DB9E63CC3712900005CA24226B523E0A179582C85968C107857BB41521B7342B13DCAC462A53BE38446F2142519667B48B1C68FCAFA4D3C7E3E5AFF163C41F2C1B4DBAC5456C30776078E7C3A713819F6B9ACA55D77D60637183A723035730F94285C42AC3587637F66AC30F2C4039E60420967576E27B96C8C004D9585F33939AC44F0D195B35D472FC219076F12D0984AC844728D5D2266BB5CD8B325DDA497B4F397BFE722C9D7684201A921F502271985CB3F31C04884C090B063631253DC454537031F2C82C10A1722DE6C556464DC9D64389DA37E469480C921065C79A30C83C867C952B30548A6B5BDFEB6EA6247480F163B427B17CF94889220FE934564DAB90F5B6A11648870B654495A6691AE21FEA86BDC8C49093FA07E926AF3ABA0E7CEC21F613B49986C6C8A139EDA70B7ED8211A3215E8C43EF8C151AE61740EF83B48276033614B58E9CEB992233CD21DFF70C7A6F7171707A2ADD37ACBF136A4EB4A79517FD0C8AFF0B5126435C3100331F208A546C9A4044A8F0503C8ADE9506A018B4CA7C6E8D70120017D38B13B52786A85A540D81B8E71C376B796A7215ABF065086D3C80EE94B8F09E2A3BA13B82583B825388E87BA010AF507173563789A1DCD088907C52BD7FC1C6930605F060F37978211C10FB5717E3FA291D20B5D43FB74CD4711394B0027E41C52B523797470532CBE123C92950720E5E255256577D4E156EBD4C698D813405C61430B978694ACDE78031E74BA1D8517DAE2346F008411231FCCE7BFF75BC361E691E776049004097B36490D876288701B2D3A1743AB8753D47AC6200E2DA7458D3A059681233872794E6720186B20108B1D1033971CE19ED67A2A28E499A360A4AD86AE4194034F202F8FA3626FE75F307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983D48BA34134BAB88D635D8CF8FF5D686058FA68B6C2FEEAA5FA4DE65757086C0125E937BCC0D02FAA8988AE7169DF07F6A771E6E7FE3AB65E965C63C3E40ED909", - "c": "E2D5FD4C13CEA0B52D874FEA9012F3A51743A1093710BBF23950F9147A472EE5533928A2F46D592F35DA8B4F758C893B0D7B98948BE447B17CB2AE58AF8A489DDD9232B99B1C0D2DE77CAA472BC3BBD4A7C60DBFDCA92EBF3A1CE1C22DAD13E887004E2924FD22656F5E508791DE06D85E1A1426808ED9A89F6E2FD3C245D4758B22B02CADE33B60FC889A33FC4447EDEBBFD4530DE86596A33789D5DBA6E6EC9F89879AF4BE4909A69017C9BB7A5E31815EA5F132EEC4984FAA7CCF594DD00D4D8487E45621AF8F6E330551439C93EC078A7A3CC1594AF91F8417375FD6088CEB5E85C67099091BAC11498A0D711455F5E0D95CD7BBE5CDD8FECB319E6853C23C9BE2C763DF578666C40A40A87486E46BA8716146192904510A6DC59DA8025825283D684DB91410B4F12C6D8FBD0ADD75D3098918CB04AC7BC4DB0D6BCDF1194DD86292E05B7B8630625B589CC509D215BBD06A2E7C66F424CDF8C40AC6C1E5AE6C964B7D9E92F95FC5C8852281628B81B9AFABC7F03BE3F62E8047BB88D01C68687B8DD4FE63820062B6788A53729053826ED3B7C7EF8241E19C85117B3C5341881D4F299E50374C8EEFD5560BD18319A7963A3D02F0FBE84BC484B5A4018B97D274191C95F702BAB9B0D105FAF9FDCFF97E437236567599FAF73B075D406104D403CDF81224DA590BEC2897E30109E1F2E5AE4610C809A73F638C84210B3447A7C8B6DDDB5AE200BF20E2FE4D4BA6C6B12767FB8760F66C5118E7A9935B41C9A471A1D3237688C1E618CC3BE936AA3F5E44E086820B810E063211FC21C4044B3AC4D00DF1BCC7B24DC07BA48B23B0FC12A3ED3D0A5CF7671415AB9CF21286FE63FB41418570555D4739B88104A8593F293025A4E3EE7C67E4B48E40F6BA8C09860C3FBBE55D45B45FC9AB629B17C276C9C9E2AF3A043BEAFC18FD4F25EE7F83BDDCD2D93914B7ED4F7C9AF127F3F15C277BE16551FEF3AE03D7B9143F0C9C019AB97EEA076366131F518363711B34E96D3F8A513F3E20B1D452C4B7AE3B975EA94D880DAC6693399750D02220403F0D3E3FC1172A4DE9DC280EAF0FEE2883A6660BF5A3D246FF41D21B36EA521CF7AA689F800D0F86F4FA1057D8A13F9DA8FFFD0DC1FAD3C04BB1CCCB7C834DB051A7AC2E4C60301996C93071EA416B421759935659CF62CA5F13AE07C3B195C148159D8BEB03D440B00F5305765F20C0C46EEE59C6D16206402DB1C715E888BDE59C781F35A7CC7C1C5ECB2155AE3E959C0964CC1EF8D7C69D1458A9A42F95F4C6B5B996345712AA290FBBF7DFD4A6E86463022A3F4725F6511BF7EA5E95C707CD3573609AADEAF540152C495F37FE6EC8BB9FA2AA61D15735934F4737928FDE90BA995722465D4A64505A5201F07AA58CFD8AE226E02070B2DBF512B975319A7E8753B4FDAE0EB4922869CC8E25C4A5560C2A0685DE3AC392A8925BA882004894742E43CCFC277439EC8050A9AEB42932E01C840DFCEDCC34D3991289A62C17D1284C839514B93351DBB2DDA81F924565D70E7079D5B8126CAAB7A4A1C731655A53BCC09F5D63EC9086DEA650055985EDFA8297D9C95410C5D1894D17D5930549ADBC2B8733C99FE62E17C4DE34A5D89B12D18E42A422D2CE779C2C28EB2D98003D5CD323FCBECF02B5066E0E734810F09ED89013C00F011BD220F2E5D6A362DF90599198A093B03C8D8EFBFE0B617592FAF1E64220C4440B53FFB47164F369C95290BA9F3108D686C57DB645C53C012E57AF25BD6693E2CC6B57651AF1591FE5D8916640EC017C253DF0606BB6B3035FAE748F3D4034223B1B5EFBF5283E778C1094291CF7B19BE0F317350E6F8518FDE0EFB1381FB6E16C241F7F17A5210693A274159E7FAC868CD0DC4359C3D9EEFEA0D9E31E43FA651392C65A543A59B3EEE3A639DC9417D056A5FF0F160BEEE2EAC29A7D88C0982CF70B5A46379F21E506AAC61A9BB1B8C2B9DAB0E44A823B61D0AA11D94F76A4A8E21F9D4280683208F4EA911116F6FD6A97426934EC3426B8C8F703DA85E9DCF99336136003728B8ECDD04A389F6A817A78BFA61BA46020BF3C34829508F9D06D1553CD987AAC380D86F168843BA3904DE5F7058A41B4CD388BC9CE3ABA7EE7139B7FC9E5B8CFAAA38990BD4A5DB32E2613E7EC4F5F8B1292A38C6F4FF5A40490D76B126652FCF86E245235D636C65CD102B01E22781A72918C", - "k": "7264BDE5C6CEC14849693E2C3C86E48F80958A4F6186FC69333A4148E6E497F3", - "m": "59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72", - "reason": "no modification" - }, - { - "tcId": 52, - "deferred": false, - "ek": "16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279", - "dk": "4DD7722880771C554AA6D99D5A873FA7723F18EC976BE29EE5438D7671BA97438000F91A396CAA464BA3CFA2598586AB4D1BB0C9803A82AA1C5B13AD1647972FDC154B61800B0C87215657D13B6BF8CCC69E5C8572EB9AADEB6CDC8871F8F7416FD032ADE5A3E863591B6B3756293057F80024F67A7ED35706185FB6B30F8C836F9624B291C009BA6742C23C65F718291DA3210D25B594E7C00F575B6B87316682115D84116974389248921E0A94302C5DED39CF6C6455B9B277E9F48C2880AD64CB5E96115EBDF1BF42A540228A092FEB8A09449BC626571F4007AE84824AC8CF92EBAD8E25A62E776183BCA7EFF1417CB30EB4043B98649C9276B4AF9CAE89232C7F7C920608A527A92AADF809EC69C651447664E98F369B2704B3054C656AC4570D991C6C5859063C249B70DC5D49CC8202541B13B6005AB09F4A471C28F4785D1A5B52389C3E0B1544DC2098F5284C43802AA16E29F32C93CA611CB170B82C4F6F514A18A985755C3622C2A8C15514340660E9F7025462909DBB6FBBDB3BADDB700714CC47297316F45589922440D6A0AACA8216902AD00647E920C4584AB73CB7C546DA0021C22EA2E59D229536E9596EA6598ADEE85D563C2CB5D82908D60462F430F6245D882A3395F754D561B949CC5CD27240C2CA41406C3D09313ED2A4A600046871F030F41B4528E7316F9104ED550C38C43844789BFD330EC75A8EB3909C156A9E54805C568B5581E603C6C9CD9713AC995077AA52747D281C28BBB535B9BADBD867C65111680C2FDD1032E1E49A67C6C141F53F44461AE427A416B8538747C144025EE3278B6EB26EFE09C9CC8AC7075324D8392A44CC260A1297FCBA4096DC537AC82E5DB560E0C541D114A5E3891068B4B123CBA214D72C36A519B409874D4011E7DB2F7978343B3656EE600031229BDA3171E4480413716B97E5486F07C32E94805FDB48ABA2144288B96C1281AB180A1BECAC17B4C206677920C52B77B53F7D7C782C562C4DA6CB69C5A828056ACB445CCFA62A8EC3AB75C5940D302BD4E38A381015947B973D547A5CFB1460668476529F6411C7AD3A2B13A0C1AC5B71D0132568591374CB27ECB02DE9CCB41D150025C26CD48CAC600C6E9A6A1398884F49EA97096662C06C56F5B76E3F444336A2C7E2FA201A66AD65F2C8BB2340C89C7572698D84190031545CC14420564722820CB1CC6C34708530207B10F3660AF2D72E1C4A4A5729896F79B6BD85B93E8C1B74C521EFC79B10085C92D5857CD200E7A4C7A284524D25636C04BA9120B76A86957F848AA2540A6CB36EBD26354C38213F6713F255457821A47CB00F01185CFBE45E50C624985130086C392226501E6B84D1C666DCC959FA0209114804EF8B99456C16D0B59E81568AD092B3DAF8B70737C3BCD10DC9D48D7DDAAD2159A96B28AA77505364DC92E170699FA95BEF6C26DBB6CD4D972026A00A74896CA2E883E0FBCB19D21E5EFA2776837BE30C373CF405A1628C1FB795095B7FDCBC063357B862FA2823D43A2F1819B0D892A59104B7E64889703F8BE2C39C9892ED393AED6A62330C3EF2B32F5B8A59975488FDF60D8CA366888B9EAC3A094EBA3513F6225638A6D2916CE6F76ABE1242EFEBAD49F29D4A289D6ED2549383B66868A33018107C1618ED3613933A9360F27E6885B7A18167E3F124115184671506F8B6C2F4A18A4EA30FD7FBBE5752A1FB72BE2E909CFA441AFF70C15BE67640F12672DA671224B6BD1B39A7F744E158B9B37B859633068F493902870BD2043A41B605E1395CC305288D9C3ADE5551D92B199260156F3710EF09C8B20A44ADA53D17E31C829BA8775579CEB110F4177BC314653EB6BF03514ECBF009BC6A95A8B79B90E18DB763C46699A9C0C23C32A31B1BD350D4301ADC63A298A486DA95B006175E99E2959881B2D84CA0588C44410173D1148AEA165E93C34CF4711FA3E215F0A193AC679E6298874221B727F141480356D408017D5215D2463C7F62A554E11D0C204A6B93314116BA19CB3F7E1571DF533EB64372FB68A7544C3A7B793D9D79CDB0CC4DD3855E9337C7E8932B1DD3BAE23245FF854FEA2BA93FE06B18E4C694322873DC8C7B70816325A9AE1A1E08686A982715A3C10CACD17F8C2920CB13B251510C55775251850A21D3BB16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279560143610E550E6C27E7AE725C958594A71FCB0350F3CE623FFD626D381C38A24D9D475487B57327D5EFD4EB3307FC1A19EF63E2E11D82AFDC95B51A4FF19D77", - "c": "6930583C55501AF07198C21B52C1A66D60D3E6A403EE412E9751AF2DB2AE360BBE29EA953050D455E25CFFB6E9DB5CB6D881375E7B28BABAF2C7946BC5A4757F61A4970BBF1CADC21C72E782A4A31E92FAB1980E7B2D51AC68CCC6222636D05645B4C85DC7DBDDD6EDE4D52478BD336C81D85708857359DB863F73B839660C3383EED5F621D1CBD3C1C1E5B3F5A5E2BD340824FF5F48690D185F725C821A2681E27EF8C3BB76CDC4CDAF720A8C657601107FFAFE761D4709C35CF62023B1690F2068038D444B9867F2FD7D619F3162D286A42E4B4A5C23E9768AC694B466DAEC80C6A09BED0CAEAE9B1F063708BB800068CE610C0346114981A48921A9BA7091F4E615B5E4FB91CDDBA00272B98FC8DB9282C43B3BF34A393BAC9EB25B6C92235204AAAAB683142BF66E9B37DC1EE10122A3492CC31EAE416D4C364780F696C0691E6449F3570C0AF421192CF44684B1F2BBFD97E2C2B15D6DC4D589069C351BCEAFCE7D2AF4C57DAA75601EECA9CCF72A47D473688B9E21D3EEF68E79BEC63BA7CFCA6D1B47AF8F45DBDE1D3CF6DD108F756F935379303DC3FEBF11BAECA5A2B299586D8DD45B0A17DAD6F2E3F2A63FC0F6435C2108DE90E3C42387A068D7E26C52C966C50A253F9CE19F1B13CDBB75C445D0C01C2EC3133BF9EAB4B6FF0DDA9C87C37FB677827B62107685793406698F08AF44632260D8C298042BDE014A8E3510705719CE0F2A75169363FAF9A0575558809940D3C7FD1E8CC027055789A1A69D9252330410C66CF41F00E67935A7A0D927D6E8EEF2F183377D6CA76F5C0A06F606462B6110600B8345421CCF5F77FF096A800030A0729BFA24521DEB7ECD3AC12B2A7F3A65921F60CB10B3C23C572F5248CDF83C34AB1EFA70AB3F1E78F3CBC0361A407F649ED4F4372A59DE9C11183DBB2661A1707029EB5334BA67231A53C118412723C9E146E0AADC891AA7A37F05F1E63DCB22CCD774FC0AAFBE2A0148DA31EEA8D855F05427E0D416C8A24259EE7D7F0584F01348316BB637F9F18080466610FF013D050F41941CEED3854A90D92E6DA33181D7DA541F148153728C64BEFB5A9CE23F2506FF5A97F3E6372AEBB119646D8E7DE1892F357FF6B4BCA001AC9543BE983E4A919F841A6AC30945F3D516222A1BA8418DCC05D3C2A26D36F43BB2A64F66737EB94CD5D973392CF47EF81CA2BCE1A5C89023EA226E4FB0136D922AD2E67364858213A2CD951369712E3E61DA5C1E8B2F6C21A4A80908CEAA1DF311CED7EBE78E245DDAB3C298C7D2ECC6C78DC5C8ADA322281F6C1B8A33ECE1720E32614085986220A8F8A128097E65904B9285327A8940F02CBBDBB36E8C650FE065F7FE69B30197FDA4F61A7EB3AF7B517668921A6E3C10D79E00853A4DFA985DBEA19AD55BF0BA53CB5EE16DDBD417FE498D2E98921E743B1D2B0192590C738E770F7BCB60B129F0BFB3F2BCC3752DBA1B433C6AF5CFFC18E963BB906BDBFA0564205C482BF032F21DEA5D9A61278ABA2122560FB2030A7893868D10B03E1105AC27527C206DE6538BB235F14FC6DE386A9418A3227264297B09A9A9F1401C24F81B8A2A5A7A6373457AD9DD02642300D564E3030629DED71D014C834F6A5005F2DB283687A2744841A86D3F9DD6A5D332AB097FE04715DA746915FD07A1E6D65C9C60DAA1ECCF71D1F4A4BA8AA9516263790DAEFC1D606DD009E079D1AB84E808DFF4BD56D76336345B23291EC5EF217FAC6CBE590CBE5D31EFDE35D4F7041EB20F7B2232DF031699927D9FC2B08E44A36DB2FE5BFABB6CA53FF050F7CC1D31660EB375D788D83AE56CF359C557E5FD4B881327181C2CA6D86B39BCC22A4C45F7B915183CA0CA00B65A06BE77A56163674F49CA79822BA11596BB5EA52ECBDC139364D84153F97D193E5E05A4F0A618F6018B45F9A646163C999F8D40CEBF85A3D51C05024E39AEF608625C93A1B1144F34EA25A4F3C588BF6841E736921BA111215740F8A1903C065CF08FB2BCD24EAF3E7733CD59066DC85AC0206822402A6AEE784F194BDD411806731CC42430678D4A0D027900D5427639AF42262D57E7BC8242A3FAB2BE536C931DE54D406535AB881C71D9C9A4CFFFB37AD298FE879EB7279DF03B9A42C6B69618478C0886C23688AF1799227163E90955B016BA01F3B9AEE10DC5C889D3883F1163CE483584D7FC09D570BE76968081485086", - "k": "4BE636AD0F1522EE10798CE9EF454ED219A13B6791FD2E042A417B2A220DAE79", - "m": "2E2C821791D3EA49D0AF380B97AA24532F6109D85360A751BB8B4C048C48D26F", - "reason": "no modification" - }, - { - "tcId": 53, - "deferred": false, - "ek": "54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652", - "dk": "B3E23EDA19008B5C42573A1A3BBA8CC34B23AA7A36761143480C8FCFF318FC4048B8C697004D82D12907C031885B92C7EF5BBC4D22A75B493FB19512C5FA208D800C134B1AE9A1CB19E8978B2003EBA888609CB147D7A451CB5199B0259FF8511CC5561338C6C54C2607CBCFE85C9809278F5D0B79925B0522A017B4B45D380C77020A722FA93CCA36904D0B4F04770F4DE13EAD906DBEE00C0FD98212E21B4BF1AD4BD0536FA232C8733719B20B2D8250ED698B01104019957F532B2B4D9489529A265CA9C773178EBAB24659C16423C4C00517AF879AC016A53E70929292140DC9849B65F5406A730CC20C84BA41B29888607A49B4F9C7947D155E60C707A6DC6AE42C6091886ED8F3B5D2655E45DCC945603365E4548DC568C8558C310C84D8E729793226FC30649FBB7FF989565393BD4DA91ECAB1325A49B76BF20A2303B081180B08DC324E01A3526B5B17E13B5C46694948997424179C29434DDC09DAB11CB4A47A6FBB669E02172CA30B2655B2658813F1666281E33EF520CBFC40ADB07A45E8D56B9EC28617DAB8D0BB1C6098CD474444AE523A5C0C47A17C5AFD845BDB14CD3661676C5194C9C48C10230D3A08A48A23B50861CD1EC19EFD5B25137435CB676DCF322F40043998E801467422471752B8FC1CB9E8CEBC2B218F60228C2452396598D186CC9008AFA626326784656228A8A0B00829F56B1C9184E32C757205C80AE5113242B4B41C16C6730A54059F37E0338A215431B9260307BE517776EDFAC0537630C62688B4586CF5A93EB4959C7BA0CEDCB904B2B6B41CE0B966B73C4DCB22F0B420734137C5276E1EF428976C2EBBC055CF583721805D64C57E42C7B2FFB5C3ED33B83E21190B1432E8D6B7D7845D467499F4F1C28BBA4F69568B2680283E779645605901FC918194165C0B62386CB2570809AA1283B31652CC4283568B16D5B2397AE3BD7A19254AC4C711067E98C6203316AFE29337B570ABFC5B272AF386A4A27893B03D3D5C67D2649250F20B10D09DF1E93216EA2A6E2BA8B5B768E9084F6675915AFB917E39051895A5485877CB7C9F7192144704920413666C069B0B731AF8D29953669FD51BB16B2960B6A2470562A0CFE49CDA85982CDC4BD9DC3D28109F32E5365D056469027EBA86904A4AB5CF592819B5848CE425543309DD76B8FA6B9D854A1434A48A636759C8128818E3197ABB33584A4F9AF94FF56839D625799D01B4AEC07EAE36C0FCA3C5A76B6CE97C7F83D3617550A0D309063EAC9E37616065774B6E78C9E3C4140D618CF707295AF10A90702E84168A65B40E172879D6B249DC2094FBAC234E563C1DA060C4A65AE4C2357179CF87480B14919A5DA7BF64BBB40B148C91A960E4A2C3BCB903CF57BF09251AB19830028088FA49C4EF61511FD2A23299CA8FE16873B81E015A724BA5C8BD110BD2D657D212751FE88875975B0322351989831854397DF90DDC82A3F59CB8952086C8F10973242CB778597EC0370838651F02313C575535D97298FC2C9CF312FE066797FC2B61B15B3874858BAC6460D600856703B6CA5A8A90BDCF3490938368670C2E29FC8EDDEB8793481CB3BA9C2D14AF5C8A135329AAA18C31BFB72C1E8A9BBA1756E687300206B3796903A3C2C2704904CC00C947998F97F46388D83CD4E4526CE3A68348A1D7701C120C0F46D0509F904B5092594E4970E8D35F60F87132E68A369BBD4BAAAC11EC976B840BFCC19B1EF48CD2937E54F3AE5B0B482443A80DD0843DE7B66C3014227A383768537D009184F86D17655A5CBCA6D9A01AD988AFA6A52BBFD6C7048285F63C0A160B965F4C39DB142029C9BCF78235ACF2132A14B946D23DFCD7C44564BB8A71879DE2C038F2359D2793B30695A4E23942D08711630CE8E06F1DFCCC987C347BBC0AFE093A5BC0177C873052A26395806C936AB453B79B24F74B7120085AD7377590AC2BEAC5FB41536C152DAF934EE2D568EC8C60EEA14F958A18E6F0ADF0D87321CCCA163A4F8BC31C0867A32C74BE4CD3245FB7C9DB3535CE3C220EE9ACEC0663DA907364EB9673038A90E18C1DF523E5F98A115490F11368DF939A9405CF8E3B0E90E32931935170E28312AB7C8B875CD4AB4FB991BDBE1C692CC356B9B96159B69142E723C6599CF5B3502DA142DE136E54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652CCC54F1107CDD25CC96547EDFEE21D1854D037E1DA63CCC916569AAD31B3AF3BA28EBA34CB5F909FD026770036785C668C4181E8C5E6C458C1B786999C42E152", - "c": "E56A8BBA70BA91912F94B7B44F860C332F1CE8D6990EFEE73AA8BC42E890CC1932C65FF3C22B543EFC1E3ADD83757542160EB4C34C129B1260D4E0CA57CB3E403DEC9DC4DD08875BBE186D82401552D82B7E838C50ACE4096D2E2A07F0D4E5C0AA36EFA6674AD28367536AA0B608A552DA186C1F816731675A635CF39D1629D064736495DDEC6E8D494E27E64A05646D6F9C9FB7C02D62F8978969B1184C55B231560561934CD1EC48476E16F980A879EAF400EACE154F294D359ADE5E189D926FC567402BA0F031E1738A286B18AE6D4565CEF9CF884FF5108019704776D62FA44F0ED1D5E8083A449C5E6A1E7BCD0B5380406B05CB43493B7D91B731C0559CFD51ABC4CB452DD304B63061236F6E8845D469D593755CA9ED6DCD181F672DC4DCD6D950A44D632A7A820F3F3147AE93492A4C6F9F565ABA3DAEB648F6AF723C032CCBE300A83AC138C1D203368E2E407162686ED09955251777AC26DF72DED523E39EEF1A5C0885595A0F46F0BE5BA370A1CCFF54E7E34C6EF92EEDD2432C1860019B58E4B3091AC6DE14677522C037707D61C0B028B498E4CAD3A162B4579CEC0A72F2E4AF38E771F0D4A3BDE3F4B7AD110846B5C1B34A5828C3003EAE34707E0B51D8EE4C32E678F7F581386159182C142B1CDA23991573CCB84DC621737212D8146C8490517BF4AA8C16CC32E7B8157993147872802A8D6894F0B73F11B3225D5D210AD1F8DA8FB1332BDD4A88A559D2C8C8890360F9E91234AC29CACD7434DBF44B8F96FEE02103D6B6499B889A166E30F1B2A3EF53532866C65FC8990F6F00E5165DC2A46E77178EB12809B8D15DF1284DB61DC21A87198E59BBFF3583F8D1AD2774B398F36B8F7AC326D76C23A30F670CE2F5853A79C9C9BE46E98D3BF069CFDB292089142091D3D3CCE6EDE3FCA9C5E0168B655630072755B2BC4DCEF5AE34CA27FAE997CEA1A3FB94B9C94E1975DA4122BC65F563D6D515D2ED8A145B3DB0BC8AA945834FCB84E8C8F41029C8EA3DDF2182733B1CE6F806BFB6A8A702ECB73FA66DE4477D5467FBAE85E5E86BE9403B1ABD824B9E00C7DD4E9B7FA0F663A286B6C5461912EF8AB26A8EF900F060D491D2647A3E0111E5DC83B9E481D0D8DE18482F8D705C046EABA60574116D974FE8721AF9F2FC6C73D2D85CA9063FEB299BAE4AB386D23696EAE5D65BADF7148232D39CFB719642787B539DB6EA3FA9082DE19021AB24C29985CD3EF6EAAA6E6E28ADECEA9CB8CAD6D1D81B84C93ECC8F30FDD04B9D5234ADDC4872976687C667BA02EF41DE88E09DF18916CC26FBAC32D10F9AFF3ACF636FF8B4CEDEADB4F9DC1466EC65884AAA34D6DCCDCA02C86417FB9A98D4CCBCF8119C217DF2D3F5A43768D96250704C44ECC8E6FEE91ED46B4AA59FFDB154217DA4ACABDF56B7B05EE41E7EB4F1A5962B24617CD36F7C4C3A2700AD6315C83EBEEBCB6D799810841286C8EB75F7B7FC249A1195C331E617AA8FFF34171C5BE52F753E1C998F1801D3EFE61F135E963140C1EF17CCE1CB9006ACA4A2045F4D508249165F74DC718D5625017E6856590F439842EA064114CB3F34FEE61877829BBB688B4F9DC04DE3C7AC455AF176CEF8719DA7A44A1E3E379BF7936AC3693DDA97E5AA0E384CC7A7C20C4FE13B98AD95F2CCE880A9E3438DCDB50296CD3463DD0DBC3DADAD3D72D00836C7BD3232D4F43B89F73665E9B94BE84A31C9256DCCF57BB1DCCFEB11989576965C0007B054636A85DC70E6C54E5FABD7875E609AA4B9413DBA1DDDE880ECC37DBF1C3CF6D50F797282A623FBD04AC7EB21596123811C6635614B8F75952B83B11E635FB87F0229DDFC7F527197EE4FF99AAFDB9110057C075F2436B08A4A4D6B565CF0EFEBF397E3C565EABC7A26E662203109823E82978AC0B61496D773925D56982373B009127E2A75E33B1490C07FBEB30E04205C305689A233C5C2A1E5700D64C8D1A58304854CD0D06BC51F7C4B592790A2B0B786051E60EAB9D6515E54F2D1AFE4828FA4C904E5E7922B326E8EE663B5A4950444B396EF66471217BD0547FCD65C10B81F9223680D8F84B1BC33894B1D8B6FA2FEF37E79BCEEEB70AFCAA007B75E52BAD27F66889BA4EEF7428BB3F800345A2C2C95B9BED9C86C715A572D6B0EFC7439CB1711A632551F770EC5BEDCC67A68FE83EE6C30EC08E0BF8317819F7B1A5C9C27B6252D48B80E", - "k": "FBF22CE8BD5102D34529C46FBA28B1BBC9787A570C0DDED9CBAA48D29D76725E", - "m": "5729B2AF60A4A5EE3BA6D7F255D7D2437812579942FF2C6F48611669135DD695", - "reason": "no modification" - }, - { - "tcId": 54, - "deferred": false, - "ek": "6914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE", - "dk": "F13845558CB25F9604BF64CA636A3086E28549689AD94450429C7E1D3A556EF52DFD543ED6209423C58827149C8F121DB21950D06C2D2ABC883E260178CBC5B3FC4036CCA60B147B7B31BBA888913A2B16F0956ED922645F8AC26A9607A5B1C984FB5B983BA78838642B3789513790B738CD2A7805EEE46FE88A645CE282DDD823A1B6BE3B19503932A0B8E0BC0CD89AE9E657F8F519283648638C67545CA06BF7A3DBEC594358C2FC21528940300774A60B6316A7160A73CC806513278ABCB10214922C266E2339CAD7FC921A6C643432766A617EFFAC457F70087C923DD9E959E62839C1287F2611C4DAC7548E536E8A4764CA570AF315C2A46CAC87725D04003EC9E261B6AB2CFBBA931F76323BB52EBDBACD62E0418A1C5DFAC0AAFB556D33D5979F9A29EA264DECF7B7E59BAFE4EC3A03588483D27C9F275EF5E409B034CBEE79B9DDB9C2A04964B11437930C9F54161283E1B1BCAB696A82C6C983010E3A769609AA51B75E53C012DA673746676EA9A7CFF84016DD28B3554060E6B4B6DA9334476A230CC12DC4458B447B27A4D427E45256A6A4BAA1705AF7BC5BB19406D828B729D27147A93B52A4416B460EB72896000705956917F74578424179F4A42F7BF61999B9800294757CD992A1B3B17C08116B0B942B4585E5728AACA79FD8E05B5F90478B56276AB0B7EA18B2DEE307A8C0C017200F2DC687C6D8453F8813807610A043B0C0124092910E82D84BAF169B39E5AB55FCC5B7DA8749998D26836CF30A3F1393750EA670E10A763C64590E3CBF20380F6F329468603E8C5092477AC1A15081FB977A5076771ED2B127D82A555905BE784D5D0477A1D01FF450B863026374287F925AA3518359EF1236119C1304A28E6503480E72273493553255B416032841D907BE8B709C3C145EE890ED16C7F5AA9B8139715307C846083A23550688989CF214A05B4B8C4BF81C4190338A4707DFEAC69D54399C30A046259C7F75435DF3A1105C1F095261283612223582F8FB7258003597E96E5B062450A3665369B962B3B447BBB6262242043B4462721943250BAA684CA55629C8591AB7A65D0AF80B772190418083D06BA7943251E2AC5891821730701DBD2C3AF4678563B8590572223CE14DDBC59AE8E0BA67D8370C2092389B060CF601B433216AE04191E2C608DBC5D6093336884773562BBE7036858158DEEA032B505E8E275B1C7259C4DA6EE450AE1D108FC592C7BF327D2EC484E4586E74C7930233851FC7AA4BE99267D56E4DF11624762E78241D051BBCFE710F78797069364133D8B80DA2CB15E96DEC9A82BCD5B80142AD054532CBB87033B55C22987E7F9B45D007866EE057C1371098783D53662E33A9249B94ADF038554A467090448FCA0543F7B00D29A7B4FFE95D5BDA0DF929B7FFE619BCFA46C0F632FBA13014F09BE589C1D6372757877E62579F806336FDC6B93A210A04E64B43A693FB20C333259C1572930A778BFED83F2C1CA974C0701DA3576720A50185A8AD36C2DA2402679899BEB34B1732796F3B7A939B48D9C56164820531A755F7128C3B7517F29235E174CB72309239674FFAE391A35A6DB97785190C21B256273280422829806C344B3885C2C057558538631F82871678649FFC3F152B0D31B6CAF6F0CF7EC821BF80579B75B099A167C0680D946AB236E3525BC160A0A184F1C13194D909C26B3E9DD18236BB6FC4D71BFAE589A2E119A6EC668BA39965A64A3A920BAFAA9E1DBC18CF143A3DA9461F3050CF4A4CE1C53041972C81E2818B9BB332504BB2F40DCD18A8D852C0B9DC4A72C03EE74922F0596F119A58282A28BA6813D76AAFE9369D4C4B333CE5BC1085676AD58180CB20CBF829827207DC3565EDD1B435A5501803BEB4034F48C07D737AB924871B3B0C879B86976E2C8ED769A6CE8771C947B4EAF75229B8508BA85D41E9529402BA5B626975FAA48C08CFE5F6CA345A4EE105CC5E01B9CD826E9EFB7EEA3157CF5B34A66839ECD34CA355311EEB91A61A5EF6301CCEE5B60D05A4D3D02AF4D8CD1FCB7C914683F53B2CB6E620A2367420043927CA88129C2561709CD5C6AFE7D0A00D3BCD8DA9AAFE605E9F0291B5097806E112C773CFA81C1192811D24ABCAA691600CFBBFF230BB86E781C37B7EFD547DFC79208516956914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE684426A70833DA1EEB4B57F24F46357D5F7E2BC00853A19775E51394883FD13808716659B02B188799AF5A6BB44CA2C61E4453C93B8AFE22EEAD4A006E31AE22", - "c": "4EDB49DE2FB344B6E0CBFA6023FB26F38B58A6378247CEAEDC9C375B426C2AB0AAD40FAEF291E7022CE4A71CB4550A8128D627218864FA4FCB726778A560C6D2EE40829024CF2077DF34575B37B5FA95D9F1645C7C8121679E4E2D96B591203266CEF61A137039637BB347C828C550B725C551396E72976D23A354947200BA37633ECA962A164A7780B7E737BCF92CEDA690E87A28491C95E751DCC89E65BF511514E0D68A0CAF8EF6AF7207066FD10CB841EA7A2638EC1B652FD43C256CD207AB20B32BEAE063D3EEB063825FAF3C82D978CC01FCDDDE2F093E6B76ADBC6FAEC94FF4B3DD399AB7A24D4DC79BC9A70178A10D31CFA874A34A8953B2BBD60318F90907A3FCE6B85A45954FAC3143139EAFAD8450BB225E21AD4D40BEF3A812D26B1EDF5495523048FF8E7B646BA657F8123ECD950EC5A037FE6476B23466059F372FCC934B47FCEBA612C6D4BEFD6A1AA9553D376EE2F0DB2D2CF763C4C2D3B9DF0BE73A39C785A8B1ACD2CDAB9748443065F6A8FBE891A7B20CD2EB3D0718522C60B6A3ADB949779B17EDE8FF21798D6515758983570EE14F7A7C092CF91E53DEB45555EB0F888BAF4C6BF403DC0982C461E5D4EB51256A5D91FD0E41ADB0D15FD2AA7E2EEAFC12CDB508E03EC2285664D317130650191F578F4DB195D3FB2AEE0804B81939AB040A9DCC4B0523F18599E69611A83B2CE7DE1B77E3DB031498F7DF3F1B95F6ED23FC9E716B365DB32E4AB1A599D41E4C13EAD0BBE635329688122C13C1563D6D882160D75C62B1D72448A2B3F7415C1EC1D87E1C6D1CF3746764001698CD079BD9DC25C8D31F981AD1592A1339708300892187955163F74C937D61635842D07F919D8AAB565927D81FCDA514467C7C22F81E9F2585B423092D6AB13A97697337EA2568E268F84739AD1C04F2A2214919F967958500DBDB448559CEAC825B9CCA2B16B94D85B3BA2E0F2D8C22AE3E9267E73C30CA52E2EB9EBD295F6906A88277DA0FD7BD7E2C986561177B7E1CFD204368C6A82F2DF63DAAC040DFBD3F92C300A49A8884B8BE2C2C5EA32135640BAF8CC22547B3EAA81E259AF2BB1C67B45749ECAEF090CBDC7A3DA9DA00E2B879453EA20EBE8A73AD6E37B81D041F2BA9DA99F8140E0793BF1257F809C04702B2FF942BC9E6DFF57F7D477F361513A21D04ECBA1F17694E6E82347AF22C04CF8FBA55E6271A128BB17CBBAC1B07327E56B4904151EA709AD5E96D2AA731507C0C32F1F79EA64B64D172F7591F14C3D3C1B27F179FF8683B5C89BB63F790C2AF58DE6C529FCB0156ADA6A14E752D8D7F7F1E5ACC2FEF83D6EB0206B30044008E18A6C51C01E949B64243A889FA568AFAA6D3B39A04B9953090D39B7C127BAD662B8C146279E554FAF92892819F015C2A87604793E14B64C13F21A728753DA36E67CF7A9CB31E4CD48EFBDBC875EE29E3ED797D99127AD84361F285A117897E66908220FF417BB560268D3AE754E9C8C7981F210B6F3A0B0EBAB428EBCBFFBA22A7E9FF52ECBE3D9B12E12CAD2E80EAC592E42D17290E3B1E68982FCC7198C8007301E026FC4EEBE482F5132577FF39EF4ED9EA44E6BF410D6203187890139650907CBFBFF75284E5B07A0546552F41903A85E5F074B80F9D484AFBD86EF53667C259855015AB795ED6864FC8DEF018471524900995A7925D5B28900C28AC06D79CB795DF93B46D480417C9BCBD1E1BF3876CD5A2874E60025B0F9AD7A0CC35FBAC64E17528A668F3C005EF0D3CE305BA400413DD0A28F5046180564D689D55D9E8380D766E0C397A2E3F26F70E4833353E4C30A1B007C299D0CB5DAB0A1273A1873E2F5ED10651AA844C61FFBFBB753512A5A3A6A105B9AFF1F8E9A92E0C4EA7998E7261460A83CF36D553992611EC607097421F1A7034297EECAE76DE14AF5011BFD8E3407AECCC47FBFC86A702C04BEC48B47D8CF4C7AA760C5F5323D29832857B86E9347DDDD05C7110A7B8AD3752DBB3A335786AA1C1AA0409FB33FD69F85AFC5B4FD9D7864361675B7796AC9DFB77B17EDD34B84A217966055A818A09E17B0490AA39A19F048A9294DA105F285FF698394ABFCDCDDD21AE40BC31E273A3A814BA54C211962D80784DE017C75A247ACF22CC657E11BF64DEB7696CA6E23BB12410B57708174DD9B47E903BD44193CFBE47719417DA52154E1B1A3EF89DC46EBC855061262DA5C6E933AA", - "k": "FBC5B7112172B55A75DD415C4CB3D5C46A54D90A3DE27BEA4CDD116B19FB99A9", - "m": "FE8AD6E3F3EF1FD1890FB7FF75A8CD9B2A04CAFA7ACEAA99D06D116B81039DEE", - "reason": "no modification" - }, - { - "tcId": 55, - "deferred": false, - "ek": "DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F065", - "dk": "D6E3B9FCA0A85F25A724020E8FB38AB88BCBD82A7149897E5D0945DF34B0AE07B17055198A7A50A1328E844A186C375EE9B15008B8978235445CA39A73EC8941A14ABB6750B8B2A8CEE62CE44BAAE93585AA6945476B073D176EEAD288060801F9B71C27E366180782E0AC500E2105D6995E47141D25901632DC20D2D89AEA997B5031033F295F92C5C599A0237E1C24B9DB75C03A01C08A78E42A8A0BE3B469FCC341601823160581B529226B7FC161042A3680EA476F12AB121D6A3CB90C24DE501CFAE8C275239F4DB27D22D58CD47440052210DB6A291E080A51A34440A768B70085EF3251AA045FA40A6722C44619512D08E873F1645D0D542EEF6CB12F5B2DB3E3186403B9670A39E0F2CAD3F54998E459AD7647FA8B4F6D900EAE144547F9C506728D080AAE5B2726F5E5212036C5DF172648E6762E09792056C8269289CAD365CD18405A0C182FBC0132443701462B32F31F62E92DEDD4BACF3135F2453A28A92E0D308EED64854D009A700C0BC49B2BFF97C3D12BC481D131174B06AB1B9C10C92EDE463655506E13069B277A0A37201A8B3C6E3EC020B5882ACAE56A23B84232E66211821E2DEA3C9C8B069269229D59AB7FF7758A7C51FA388D74A85B0459364C3669E4B1A230E063AF9868F4CA31694B5E69752872B15FD4A6C577BC4B1821867C456DC6547954C8845425BA9CA5868135159417BD314BAC8BD8533E477B0C759F7FD48F1BF0281C79774A82927FE1264BC2BBB7D4AA479A76EFB9314FA856AD608793AA1D571775A7E363F9E220122047C84648F8596727817F80ECA00E0B4A046AA1255223632098E696BC0E40ACC6A5CACD84C19148B5B4716FDFC2C4CD477D923269E662370C105190983F45550FAD198AE6D512D72362E16C350E783DB9F4BAC4B525C163A20FF261E14A3757B8503C14ABB7F0C7618737A2E0822DA837D606996C073F389A8B68CC2B25170A282C051BE02FF9901FE3D53EF8367587824D4E8051CFE0731E676D754A532B3329BDE45A7F2A92A5055D96560E5B902DFC67B4AEF100E90115E6393BF70397981CA1DF6C8FD6249941FB4D7849434CE52CC0257E98A1724E9BA47425AA21A0C465372D0A299643564EDBD44E3E4119CC063B7A12B969A40A38D33DA23A059968965B405077A8084439AD9D8495876953896827C8E02855F8CD34B288789CA03DB8C8D5914D538794B97B2F6444CCE53686EB07CB21C0BEAC757B3424CE969BBA4685081F926B30791D63C14573C01E999455B1395B6EB19102B7A70CB524C5DA378259461D1284E1EACA66419C166306BB6A8980A54ECA11C2797C988716ADB5E5BE7F4B0E2C2C0BA6118D93A934D8980742285738EBA7F8997F2C9B4D6A3C18968772C821A8E7A9A6969B948CB39977D88AF487A7C7795F4156BB076588A2DC5C2E361EA31BBEBD689194D55D8C43A7420B9D1B0842C0FC45BAB664B310657F57B8BA72A5CC34CE9A1BA939164ADFA40A643B4EE786415891B5F67444567A5B85156F0CB4931F7A7E50157345CA00EEBCA7921A8B0AB00519C0AC2E174452C69D3D963D4FAAA68F6066DAF78D25F798F333949CD80E055116C3F687BA4B16E1A50820155BF6D0740533C4A9A7AFC863CB2C44175DC0BC3D2026EC66408CF893C65B8E31C79D17F33D1C101963D46C0E77C265A977E2D45969B602550873EC3AAE1536339BF51CC1F033B1130B3B269026331B17662B9DB79CE42078FA870946782BC169306DB8034AA72D38572342F621E08895303165A5303BC8B24C81062A14A6B84ED929127920E3EA2763A6A4E65060DB9565DC13305F112D61685ED4A1A8B52969143A7BB42B6B76A3C2FCF96242AB3B58B752188670D4F14CC6BB278C31B59E19A1EBB9905D019B21B8B054933B006823100B5015054A9B26587D9B594B083F01D80B43648A428A514D11814C42059A0C5EA8377BDD25351FD000178485241BB72C28CE0EF210052259DA97C589D66657F4A6B6BACB54F417ABF485E01A1B58FCB0D455925A21605274C16684C1C69034672082D6B923F08BC339753CB0A4329E37C6A7DCCAF3801D1EB72A49C03E7CD0B1A8DB9B44106E33ECC8CB432367C7C061E122DB7C31B8E2AFF9A750F579AA1561950924A44ADA9A60ACCEE2159028C356A431741D0037DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F0655D6E5BFC5F96134D2C183ABB3911441EC66B794509ACECEDFB7359BA96E9097A6AE0162D48029F424D913B464EC63CFADB3A377109A8759849A8D8542508F050", - "c": "5F7721D08E0CABF5F01821C90767B448F4F53DAAA7ED10FC21702CEE8FC28C32FE20AE36052291C7887B9E84D3C22EA9B401F870A12DFDDC32F1A848E0EEF27C9B7A7A3AD57340946A180596A38757BD6B2570FD92102528B2D0DD804D7F4A76620DAF0767428B3B63B842512EE6816B86B5C5AE08EA8B3A2D61431F185382E8957D399C3E32BF832322915705700EE2A19CBBFD12069CB903F30053B0FFEB61149266593F0733ACE7356455A6D70F7EE6BF7D07199FDEAC313CEE1E06EE5AD50E89BE5A39A73C82277E67DDAB9C88FE4E734FEF19065ADE9C548CB6F91F90C6B899E5FB243284AA1F16CF19F607E18AE8E8A01BDF06AA7F0EEC34E7C1ACA8C407807D986B6B64AAC6A6F5D395AE57A48A4C135F17DD2B5B62EA5C3B83675545787F5EF43832A908D5D8FDCA3D7E60E884F70EAABB062CFC0078539FBE68087CA01CB0401B634A275EBCE328633428EBFDCBA373505BEE1DAB5B531C90C4136036D5981B93CAFD71F6F9FEFF5BF2BF5B01F44FE57F87ACC60DAB8C88DE57087E08506097F31191C376B40048D0349B7F6F5A77E83A8A0B0F3C317AACDEA059F7B7949C2F14087924A28B752206ECEAE424BD7F3B379F29F74D3ABE320BDE982911C15FF6990A3546A8391AC98ED942C63290307F10C398F85D5B0CC11758DCA79B320EA26BDE1F898CFB061882B984FCE7487A69AEB5E4DFECD42EEF146B93F38318F5766F263C67771EC67B0644FB0854E77B02DBA2C05797D24EB1D219F473A732FCDF41317259C0AD919C0AA77B329CC8B3A448C4BE35CDA609F0C4EB4A01B801F380A4F5441BAA6D415507A4BAADFD80E50B563F570ABA9701B264AF7830482F536B49EC2EAC2ED19E853CD51A0C2D3F234135EE3B0A627F1070DCA5016CA3F381333CC546EBED09BD5A7B53B31874FD7A7391451C0195CD64C4256089D709182F4D5DC83CBABC94F53D94FAFCD60A4DF94E06C51F95C7854B5A9A34BB3A8BB06E6B25F2C4098D3A5010DC0793EC23AFE1F55B667E2D2685CC8D335509E41217F05DC99B9998369845F4793C55869300283E119A0C6445A214B5DB10CC62D7214D3DA936A264F566E28B06D9EE12DE50CBF2C68B6DA8E80AC1B1780E5A2EB95CF40F1B947AE4CE0AE1D169408D63FE4209522A5B4686E32E5F8EC4DF81B4EF33837D9C120843234B7431D997D1EA678430CAA9F0228518C8D7E1F0FC3AA31900CAC9EC0BBE002E478527F8E2B24A41253851B4954FB935094C2E3766BEDB53C75CFE7A76EDEA1365B925BFA047D8A3463E5F5709EB39C7E69B2E1B58375D177522C25BFCF29D8E58EFD215350C76CC4D5996AD0FBC7E3ADD94A87E154C49C68F5F18AD4728C9EF1D5040F795EB62DD8CFDDCC83DFF8C5FAA7861D0AE62AED8B232FAB8DB8F64A62A613480D1087F1430D6783490BF29E418BD1B524008676FAF04A29ED9F07FB8E3F4800E2217DD5176392CDEB059762AB5515E243618D7D6CA7B7988CBE52D7B76D0EBB87420644CDB018C92BFA53B57C116643D3DA1F194687E8004BEE958FE968F90E50153550992EFB49AF037D28835E292CF8867A7FDD055833700026E8A97CE9C65A446E9B424EDA15B036DD37C4122609CF70C04E238078A1B759B9A3901AB3336AB47D208FAC6D8B45946D9533F9F48D5B44FE228CEF14F9B9E67F140708E2CC4C9F8D4F55B57658566D9A5E2BBB6554AF989C89A0ED2C88934477F59C14480AF77CF7B3773BF5FA29D0BFD89DFFE4BD597634DF3FCB8C404CC935651D4EDCAD17E5150595D0E7A2599965CAC799C30D37BC2882E0088FEC1DD687471F194130925F931B0A6BC56DF3FA0962CDCB75C008F30F5664B065BA94091C7961BF7549089EFEA6D79372A7C21F2728363EBE32654A5E2AFDEE5E2E9584A658868F48F481032BCC65930031CFE3B777B2FDE5551013481D7584D133772E5230ED502D4208C6128998F140ED9589530B9CD312AE221A8DF4CF979F0D65D8556C5EA30C310AA84E493767C583954931F151DE4DB5491869875B89B7A49294044FFC59BC732CAB155BD549043F30968B821463E4F61B6E10C151A1F1C873F29C49D88B1C075EBF120951018A6C289A6DB7E352557F2DA5D2F2FD8A7AF33FB9664650B63EFA6778C4BE12B104BB3778193C6683B1EACF0264B448A195DB8566951B0BFB3D64EAAFDE75ACE82C067CD1656D88440F029FBF010", - "k": "7F8443BFA35178C5DD7008B9D8DDEFF28BADAD893E16313FCED911730A9F0B3B", - "m": "0AA3B1F8FFA63F89F949DA18B6D8570BC5811F85A4BFB293E9D411ACD43C3227", - "reason": "no modification" - }, - { - "tcId": 56, - "deferred": false, - "ek": "8FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941", - "dk": "A707213F208CD438561CF949B2A2066EA1234F619588A6A9B9771E26055FCBC313E918C225B8A6E4234C3664965F20B7F722CE407A68A578888343621AB24E429B1C88C5CA352B98BFFC66B6C7B01D861634B64A986CB5BC16CA4A89C87C455FBF8B74BBEC707F67C552F9B03DA8C521E02D147192AF05BE3C394091B60934EA3032646DF68680A91396BC091CD8806A76D676693C2366EA7196DAC82D060336FC81FB4BCA553C2E21449A69E3C4F84B9906D0AEC2B9C18262C8BA231BA5608972A67B1396BF98D26839901F0BEB0EFCD907E0015BB21CC7F0C22E09B76969E8C09FEBCF105AB9D6A754F6EC6253F615445180BC8668A8D03CE68C2609470092A29FF2127990B14467F960C536B37BB4A980843C8CC76D9D10B2CA26823D513380655883216B5E49C9DFE62D14C1A37132BB072511557118C7B43AC4488D962989394366B3402E739BBA1F69A4F2512F3A50568B8046EDC4A319725E5067CE423B58F496399C44AB2A51C866A26323C68891F5AFCC5B0FE7D37AC31403629CC5B65B9A71E192EED60B7989006B824E0B510E3577C92A3751BD2AA5B1538742303700212CD3C54183724B351C40BAA4CAE46C79CD9383FE1719D333BD4FC33F019B3096065087039CCD21A48C582DF54BC1BDF4BB5391A1DFCC5EC3C57FB95BC9FBE5B611453812E936EFC35AA4C51B42329C31A39A2860C921D9B326F51FE47945877CBFC95178450972BB4A57AD2B2AF1D28AC1D7B01505AB18E964FA567FD9F53B397C2C0891408BEC73494A4563598BD2D1B4DD58603CA80C35A708448B3CFBD4B1490C9ADDD35FA0A4A6F01ABCEFA421DA989DBB506550194FBBA8623AFB8AB97B6E90B0570676191B23AD8D25C5EC054948A8416D13AA890B7FACC6CBA03B1E12F819564A44A9054594500F8F74AFAC8B188EB350FE35A8841A144950C5C75538E8F78621C07FDBEB9A187B0A12773700E0B3BFC7CA6B317B89783250C8263FAA6CA8B53CAA662E3AEC1F07B1AA9461ACE168CD873787B28A6ED501451D5CA306E0000621C35E8BBE57A8795E978637FC781CBC76C60663CAE160D4968988634C9B5937234C5F88BC4CE140763D0520F635BA2BC107049C78B826A1B8A23DB4EA58EB1BCD5D1931329C04DF199030B07F258045DFCBC426B36A8BD0A3A7AA55CFBA400654A879AB97342CA506D6579738913E702C7630AEF8778C4CF61CFEAC53F9EA8D17CC766A09C646662A14077DC95600783B9E372660FB2BB806D84DA12C64CD110F05EA1A8E373D3606083E3382C9EC7FAA649E61F0343FD721F99745F8E2ACFD0707DB053B6F67A0214740BB999D9B434E9218B388F73097F83EAE9792D4515B8267B1F650896AB9BA11C778E3897871B28893281FF33C0441C767556B4FB5852608B01909398115216191A98E38A5B16C8578F1748D69B84BCC474817714CA29534ED17CA995973D0E935D3221A394BAB5F70BAC95590D2791E5C724F77C09B5E0542BB1279EFB4C2F842BB2A8288DF512451D503727187CD3B7812B67257E107248CBF2B63C099228064020AC45B46DF110FEC3960ACD0B4F992745450116BE351123896A2489A76FA4739DAC06DA63CE4FCB6C2C46BA3577D37BA1AFB296ABD2819F324100106745E99B534606F67898ACD724D2F390F67B8AFEA0B7310491F86A31680755AD1FB78E9AA2AC61769DFC01013C38D7D9430F697A51FD627B7699656751407DA16AD8173585BA595ACB14E019ABEF921CD49BA131CA7DA2B2C7D5107356961973039FAF30E551478CD3C7137BA6637673CF715439A09A6D7FC955A35330FC923F09CB33D31B5E3F906EC3BB229C4813F2B1D4D449388507A9377BC100264CDD2C50D5B9E5410A92B7A6B8C5263896CB2BF3C4643F7142A8CA2CD571779766890ECC84453584EE666D4A3C651762E1E267BAF71108E04C847B8693DC1CB2D6929DB811D505588D03629A25753A6787A02B19F3111C6F025B33BC80905DB11A15282A97A031AF8A52AE40B7B83939F7C210D995E24757B589182D92903647256A921C0520445D9B177F4F33F77174CA76577FDA72289D49592FA0E58EC50F9EBC0DB40482F277A1F6381E4372289168F3675A4F3731378590671301A9164390DD3656EEACEC005954F3B3399E6045966434021168FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941582D82EF332E43017214599D3E49B9F9CDF7E5EF8417B8A95EF46A21618AE908AEA17274D9BC31873ECE5211AAA326A34048F067A162DE56CD27FB17CEE38628", - "c": "78BDBF1509D64B097F89F9158A5474E57CC04818DC01713DADF6C574AAF9115C23C641077EBE2CB2B713066501DDEB196A72067639F30890A41EAE9A565E6EF4735F1DA233FC7647F1B9397BD00E7F387B58BD4C90CC310172AD52BCC4EFE4FF533A096061EE5DF3E3F86D7F196EBFCB02FCF5EF6BDC5CEA034D5F33E61F6F805E4F76CB425B466D620EA166E828D692E12C568767482BF32C98A5A8142015A66BE48618347D49997AB6B0F53426BBDECF1A653458C2D8A6D80D49B736C2445216BF580E85BB794987986955523C6D78573608F1E2A2EDEC9F2862A289DB9D9BC8780B96FAF5D2DCDB0C6AA4A381C97FDA9A67C2F6052B145C8DA98C5BEE640ACD64586DEFDEF5FE6430F883B68C57366083B24C783561A41A3AFE3435ACFDC8BC5F14711079A8B0419000D41BAA5D45B70F9BA844DAD01E3CE992BACCD90B6B22B6CD81BC67BBFF830FA5EACFD6F508EDE4A11998DCE7F9C715F404F20C0AA98FABA50E0028994DCC9BEA50EC89A8CE26F49791DDAB8E16150A4C0A9883E59DD6737EB9EC79B63CF6612A71DF6F4CA023591DF6B5800EDF02942EA286C95F650415EF28C6F71E6D29DFAD488D2BB735E5658352A38F9DB04541716122AB51AD5B8DB07098232536F93210B5350A473ABEC4AC6ED14C0F91E069D0208A3E7B805474D48069AF8143530A8002C682F6D2987841EBBF4DD0FE49ADC161EF507C05B705720395F7D2187AB92EA8F02B2B29863DBAD1E4A293E7FF2F9DAB5B522087C756A4A5560A60B1F79C017F85AB5B854A431CB36C8A675BDC8568EE681B62C71F0FE67AE59A56DC61D4731AC415B1D33ED23D52491446AB14AF99314B7B160A39EA56CB2C1BDA78A8396DF2F5382FFAAE8EF66A9152BA6FE38D0A0B8D12FA2B74C1FEF982D69E9F16A3A75EC3FE31AEB7531CB37E0E067232C2C3C3A441C8A8345DD2E538B8BDE88AE750CE6BC8CF8219F401F34671C1933C63FE46E24E422A1FEA8D46B0A59792956ADE770D306D358DDE52B6EE0C437581096370FB85BF38105D939DE745E7B08221E9F8AA9892E4B7EFEE803452748825E1BD338B3DB87E09395970206D97FEF5219387F5C56FF9FB18C1A711FE28FED5C6CBF6A65D4B86480F7A05FC1922272C0AF27CC072ACD598ED7C7B068717CACDF8222CDD114B977B0D1E49FE3EA2EF8624EC73865A6D89ACB77AA0F05BFB3386795686938A98CDAD4930E141B05AB6DC401E89B719DFA8A40C9641561BB38EC2C288FCDD6032C8575298B020DAEEAD80FBCF43645E893F34CC29B7ADD1D815A2F735B15E30A1A3192D00C525E859D3ADEB62CBFEF3D0FF0D5026E0249DEC8DBFCF57300AFD3A40C9838284D2622FE07588BD81B542E6E12CC3FBC2CB7991F55FEE665F9F19BE36E49A4AD541718592F1829FF22DECDA26A8D595F71438F899512E409C24D2B2D679094E9A65C994566166D27BC299C89D5E78713DE0AE04372EE150A93985177E3CA7423CA96D4CA89E6A862EF80223D88887B6075F63130D4E3292EEFE9F850F57D67CD0C57FFE88DEFB61D9A6AFA917550160A1806CC525792899C9BB3B8D4506138233724A159C824DF5164C34405DE662897F601FF533CF70307CF7CDA04C072F0777CF5C31A7F90AEE8C169ED37D15CCC23743F5C77A9A5D12B1C90260DBA9C94A1B98EAE019B09EA2A94D34DAFB8A06856AE14B42483746C52A41A403E5F116DEE001AE45F2DA987CE56CF5CD9BE99EBD0D2AC1231E9BDBE5715A594F277B4BDD6D96C23199B72A1495DFDC1A28EA7178C02F623D4B6E77520AC134870A8BD62C1083110755222C69C685DCAFD8D58B881A72626B46D8CF3F01BB37134B5CF47EAF95C5FB6E0DB5EBE822DD98F2061A7695C2D5BCBAA26926DA9BC55F2FD8B5A009E0F8EE9838D86B6434CCD28E05BE7E1FAE1AE2DEA7DAA1270890C170378B65995D53A7D3DD5076B86A73B3FC7EB73C0C59D2A9B54210458E0ECA8EB3FD1278FC1B8A87395B59A3BF37E4C52BE2A59640D944169B53D109E348B3ADBB62026FDE56E422372DDD77713B546ED46279C13382441F9553A28D55313FA07709A227230120FAC743028D49D58C1989E32A03E58D0F2D87D28663B05ED75F91AE849657ACD9685AA1F528A6F9331E891F7028537F08D86B4F8118D52105F297D1FFD3503AD700C5FC5A1187ACAD5FC6AD2B4EAE36CFB99146D6FFC6B8F8F3B7", - "k": "71E743C143334C36D7078D290BFF42D53E7D775C6DE3FEA876E054CB8042D3F9", - "m": "2429F93D29E48EB6A25ABBA3EE2F3423CDDDD0ECF4B2090C6CA5BF4883F4F3BA", - "reason": "no modification" - }, - { - "tcId": 57, - "deferred": false, - "ek": "FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB388", - "dk": "698C6D273359EFC42931A425DA3B8B9772747190B26204AD5B352807098287B672019B9604337BD50988A1C7AEEA975795E12AF9348A6D180B6F086AA9E92B43F31813B0A357C36CD31504F65285EEE03CBC288C0EC06AEF318622B21839E74A38D33C1FACC773A29BBB0652DFD728B90A613B323D735790DA292ED25403EDF5B2260342D75889732852FF4813F701AD3CE1C9F960C53057C293A09779A88745E901EF744A07E511290277D1467A2A082501DA4C10755E5F2AA8E3560AE33A5D37C77EC0809A1B766484422D00E3422CF19F64DCCC1DA80816E321ADBAB7E7E79B3BF382EB732F86FB771FC1A6B63A6655D161D8B21141034722480C31328AEE1167FCB477626521E833208EA53F95D46B8F2A4D36AB00E34B5E9D324D9C2A6E8AB7752E54CE1AFA9CA5DC461C208F66AB0370C90E96DA0E90340E014BCCC9676094BAB2FD7B831298C4589429E012739989BCEB5B09C8A0AA7F56CE2B680FE0D19D9C8171DA580034184C52E30FF3B712C5D92BA93B9FE8D61C7583227503B3F33A83CB613FCD23C3CA0B4689823380B4037ABA9CF1698F48C50ACEAA2D4BD524BC34BBFF4204C4A359CD3896E3057F9C367F0ED074896B6DE44CC5B492AF3E52A29643B87EC895FB3375E21A48FE5CC0CF3A8810B9ADC950C158F13E29994FDB67C093C09A09A4C4565A21E808916040431250BA91B95D8E42C3DE2A1DB032AF1A3529D1820ECE9A686DC554B86950FA9ABEF1D8B416EA11AAA5984232662F2734609C9DD7112E19B5550F115FA571CAC73078F08B601C649B1A6949875461FBBC416CD951CEA13B8E996DA68382A14664A4920B4E9240562C6893AC8D089BCC4B3B55719C4F9C331F2576985A07C8A0192FA599197C49260CF57B6793ABEF0619258B886975422DE0CFBC20383C3124F74004E3360D988855DA225E810A9D9C910079D80A21B2A806D851E8831581F68D3914C0A0FA9B518B71E387113EC8616592BB71E481928C2E48AB75C9C7A4BFC48ABBEA6DA77A45B4FA5C71BC31F85C902552B517EA36C2E3436A506371C8A827AA721CF57045D21D52597640F1536D518268B65B19F2BE40ACCE482B26671AC51ACA27DEF703497770083611AEB83795EC58C84262EC4A3D78258953D248580CC6D069273D12984BA5BFA359AB25484F79A3B8CE4739D570CA1C6844C8FB525CB764970A72B1381B68394AA6308AD00C96F19A17F7441B544C3C95903A2E9125090C12A8BAC7461CBD8E37025CBAAFA797B70D8896E6E5A60AD332516B3594D06F75A18DF335BFFF876F4B103F8ECBB85547246F226A95285F081337F0719A9EC453D4517B0A2838DF0117EB480039583C27B53A4684138875C4CFD06C7E357F6C836D5797A88323A8D7600979E95025372160A9BFDBD32101012034E64613E198FBD92226A4AD9954795A9227A9777C78F3B8669CC524446D77C8219839AD23B21DEA6486995A029A875D4767A866E51D7E00205FFC5FF43222CE923882D88D72B856FD7C00EA07266FCA70A849A3C9D227021B3BC90B8FB2BBA0173930984847B42B90CBE930DFF08FE4C14D424CBC82FC81DA1B6AE5477D49C30D9E4CC9C651AB6976AF47A18C188388ED0C3163E0B5C9152C82E859DF0C16D3B2478AEC5ECBFA4AFA7560B858142AB48EDB94617C92522CB07C39767CABC55F8BEB00CB48C9ED19497594A161E744E764104347777F5B8168A95F579315394C6F184CAB00CB3B27C19FEE96354E4B62E490572D597455888BCA0259E6F7027AE44F7F95CBF4592B722696102448E7B437CEE5565569B27ED9CCB23A75DD094A98678129272A6C2C27DB5B272B7B9BEADB34CEC5091C405649897665BB633012694F4094C595370E2B91BD8C585817063F556A39FC625EC38D86A5CD6D83CCEA20BA6DC108FBC3C723ABC62092C612F503F8896102E9124DA46BDD00748141891782AD9086876AC920B11C5A6849C67A4B70434236937243D940817C2016A644C53EB7C0F8540C52301D63122CD7E43E98116511D455D3675DBB42944F7CA936F51364D07249200A17A7C83FDA1A2017835C68965EE617DFD5B5C1F026CBD2B79B68A6D76443278972B6914A5937AC8C213292050F0578A0D9219EA00345D17BA529D6B5190381C255B307ABBEEF7025FA36C1FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB3882A9072AC6B041BA7624CF3158048EE475506482D536D15DBEC594818AB0E91025AB34FAEA7275E5D6C8EE1104CB19F4B1C14B6C51ADB118163C6A48540E1C5D2", - "c": "4CBA673C63D21AF9EF1A30F8AE10628CA81926A8C0799D276BE363A182F64C312CA1AE996865034FB1F2F4FFAB6D132B141C9CC01FE4BA6B16B8FA1F6F59D140B89CE159239BCEDA3E93EBF6D858D647385392563BCC1B421505F29D0C74FC6028AC536DF5D8693C6E4BD36A9AE85737B1C14632DCB11896B50775A75C8A334D334B7983D6778D1BB2452090736CD9B488025AAA2AADC091ADEF4705BEE3BA81A404772916AD78B4CE2E2EFA0C54F77FCB4AF0AB62720D52C9B181F80BD6A71B65456BB8A6EBC4203C8D224B6B8CD544559734A9E51270D06680240E48E72F6A294F29CE05C7B9226DB34E2883A065E6FB742FD38A00DCA0938D0DB500A012E84903425EC1680A71BD7688F26DDCAD3C8368C2B384BDF407E83C5441B427CACB25FEF42F6A8C350E67DEDC9BFA7007B28F6742028268358981D72C07C455630D8B845D61F77F0129CFD4DB594BDC4BE54D958E8A3D8B6A9A4DE77BB66B393DA7B823F5D3C25C5EACCFA258A9F7D9E05038E7F8CB06A32886296FAD4B7822DC2249B1809E5244716A552462C8F1E21D87A30703A3000C6D3AA082BDA96C441F65014AC10C74F708AB8BD83E5CF6BF42124746FBB44F5F65A9D564DB514AC49D43335A6D8677A30A54F673BEE43784B2596346F49073EA27BF4C2AEA4CD790A5F24E772F69F591129CF33CBCF5D012384230AD91D8603D3A54EEDF75EBB579CF4027F1E40792F0FB2769EA83494CBAA6D8732C0ACF474AA422DF63B8BB1D19AA37078C690E5C44B495C87AADFFEEBDF0FCCD969A22E151978AE67E9B7D950BDDB18D9014536E91B1FDA68F41394653E4A066EF8AC92D61CA56CA3B504A6FFD5993785A958A3E2890D40D58CE12790CA35AFCAD8569B75DE5E033B6813B6E85F1837C5F62BD61C3E94132ADE97F2F8F3FDA5A54A958865BA898A8A67C38E61C8625C563A5EE7F6D059E22FF626976332D0E0A4F7A240434999F16BB194FC77B21DD09A47EB819B1D5365553E8A86A09A83BFC612BB38618C84132C0E7A8212C5D2327F5BB7BBB5C55DE72E013A198CD806239112D0ECFCD05092DDFC34A9453EAAE2EA59061734C4A480CA346652025BDD35F49FEDE97B301E3AE6246EF54C298F26968D44F144958CF7094520473198C6A654B4105D2F8CE350C05359BFF40C15D61B633C6F963F3EF5D37FCE3383EBB14F3FC04150B4D6FF34A16A29AE0D38A802EE52B0585D9CE8BB8D3F27BA43A577673AC96FF063AD37FF4081A67BEBF1FAB1AFF168A0DE3B0220249765EF67481C7C30ED4A1FDE1BB62F10557034A6226B6B64892D4443BD8965D1A632F3EC8D58A82FA39FF13B43A02A82D6A1ED0FA651342192B4B4E799A398914C49FC5C71A7B8798ACD44871859E3D8CE777833D0295A9782EC48334D098D10EEBD198CF06B0795AD505FE0342D5AF7E4E99EE34BF0C70AAA2E4978419DEDBFD6EFD30E985E6539DC139DC2D96E28BE541642645F54781EB682BAEF49C109E0665F4928E9BDA891AB87D872BCD28B683F13336419010BF53DB4349873544331823BAF9789DDDD5BCC7831E2C10F50C6E33632C9D4C47ECACFC664D7D683B34934BA03AAA4A9FD1236C4F97A1EFFBE3B183268308BE20A781DD22D0A3BDFB450A102988525832F03DAC2A9441DEAF2F3C5DBE47060930EF9687008D7B58AA81FB79F08DB833D7F2C3E880B4F621AC7FC6601849C7CED42166D31A530619BB9D8CCFF269C20EEF4AD814C42B3BD2B35C4100DA58C8EFE5B46C2957673ECBE586C95163ABD5D9F2ACE64059218685F369B3815F01D693098B7EF8E7F89F202F8AE76594EA7A66D5F4B74F80CE0FC274E647B26CD1E63E88FF27AE783648DFA85D5DD56863000F03D8D215E21EF11A1C2E8E57D5CF770D0B7AE22557F458F3ABAAF5B9BE1408E9CF4823D7FE129472B9E4B89394DE4907F85F94A3A42299E432BCA661BE17D23B6B61A7F20630B0ACA4529AB8B03FBDABA1625D2D49E724BF7748AF96FD3FF11915A84408BF80C70FC0381E39016CFC8739B80F7C9E2DEF0C53383557E15FDE9BB31FF367C2625542433388F19CF70B568D64E958FD33FAB2DCAB72D4778E2F094D94A62DA941D13B56BC6CFEE6D1C3D81A82DA67344994FA405C31A90B9EFCAA8C7242F07BE73B3AD9ADE3CC4EB73017FD6D7AB37F3B34BCF1D2B291EFE9D4F8C4C33952C479AA0AA7B824E3B895F8B954", - "k": "91C5D5F6016A421C4C5017CD8E805008533F67FF7037E8C62FB52A2D6657EE5E", - "m": "B65043CD3672CF9AE2CACC94F923CEF63B5127ABC63C2A5AE6C064B8C6FE7C57", - "reason": "no modification" - }, - { - "tcId": 58, - "deferred": false, - "ek": "E7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA", - "dk": "1A47BE10A1273C9312ECD31E36786BF2C9A13382CE6919AB8F4C33A92A5E4C5A862CF22E39F34793A4BEA35B4CAC858A32B79EF3C56A6C1C7E9205A22F0CAF77936722424CB6B207B15484BD602239D66AB2D5A0C342AEAEC83C95E42BD6D1817A1AC7C50A189F4248A9EAAB81B53EE952C9897178C2E92BBBA7B84A7348D8C504CECCA2261A4F72EC9EECD82E1329A55D5A64B8743F08999B78B88D4C60C0FB1387398A2323946D7A071B6898C8BA3250734933764C31A91782F2050CB3597B0FC63C280C576298C062D0968539C740D6B89A6A28D20871F8E2C35BDB86EE8B747CA81B83D856407B7C0A604AB1F753D38844DD890209B337F2770883B82FD44808356B24A36195D23C88D5F5857F4624ACD31211B695F0638C6AB870856C1277EC24C525A37C39259A99707256BCE0DC9F2B9606AC93A0146A5B5BE41B22E63382B56F7203733682CA87EC80F8C58F4294167F4772F0E83176BCBA554545EAF711B02A7DB7B896D44BB0F47BC46659A8305329D82172A1DB4C72955839D9752277C3401A7D1800088A768F473B80B7C746AACC8205BB798E905C1E1008F454AA5363B1F8E9CF3CCA72AFE1703C03A585D66C528BC42A311E0479CAE4763D789C583A56A3F6836E73A73BBF01073703AC90254CE50B27560842B3FBBF5DAA4C6DA37B9858BC7F2054A596348187BB99646A7933234721B1A3FA65564A5E3525276C5A7D68960FBC7C095AD403EA0C0380E68B4A5083F0527D3C563313B21A2816446A4AAFB32B52D8A60CDFF26281412353D02205868F9452BF50E0440049630C022CCF05AE6A7289747C573062560A3316C895586994CC7D2C4FCBEA0974C5845400C0C9218BA8BA2FBFB8C93C025AFB6C341FB2B44DDC6046B99F2CA2A269F931B76C0BB89BB424C9CDFE54136F716C8613C461B92297429EB471AE1C47AB4C3199281039D41A3B67908F3586997C8A9980D9145BBA2A098524461184AF05576BE349A614862310AC68788A0F06C418E255FE6B63F03C99E30699DBD77378E02AACF6C2021ACE42F69F42A5716CC37C64617FA7C68721BB8A3CEC3609BB8799422074D143E676599154B186554D2D5C9EA57B3EA3917BEC6C61C5A351A9908471B94856758964B77EB7D7C2CB1A4DB3000D4A87B9448686DF075031263EE5C0253668AF61C8259CD33E1E9C1FDAB4B4B17012EF831BE6C3BABC8463B3084FE2524B3227829D24BA38F88D850B21CC06638F258378D15F73D4C6B3D1BA498959E3A9C9257C8DFB2624F99A15CB09B1CB7469F61421B929A5C07ACFD781A8F4069C446760E7ACABA6E2B4CFC89553969EC1B21A41432965A8BE9E5A73CD402900472CB184812E1B5B2136149E4083D17AAF728242B470209C9C466AA3823A9A7B1C35A36F062BB670573EA059BEE9A2F1E4612AAC19B7A3337C3AB647318A88A22226F606FD645E324971D5D58E89A0838B00553A14449679A01149298294B9FB641B08674BE4615DCE174CEB019982D75996220F33E2393D8397FFF6217AF3452CDA8D3820AE291839B2280BEFC2179B344340777009378E56FBB90D934F04809C3E0A8512AC69D087BF669214A7125337C15CECC2165FB7C620D06CE422A9E5EB17D5983AC0509BF598AF45428BAAB16546480670DA4042F93FFD147E4418254109B8E0D97260429E5AD2553A2C86E6E7294764943CF14014B57B8A5113B2F02E54220981177BA1D4720A0556AC211B44509F0F913407560961E0AA084A0AE2C15CFA7CA77D9CB8CB683400CC72FB39AC7A758C0C21013CE6046CE2950762704BB0050D43083D85751AA5A141771DD5E9B4E1785E83C2B5997758B6FC3628DC43EFF472C73C4C15100BAE570513AA532296405C5936847976AEDA9F5B0AA704E35EFFE533840599EFC74F3A1C587C2640F2509F39FA14C0630F8393C96AB864EBC0B4996468D08A5515A3B4D71856AC31BA1B141D36E0794A6633167A471E199C7694B105230E0D11268E809029F72CB0C798F889CBF4F79418505DD5E9112F775C77D6C75E089DEE49AB0B685B837ABB7391B6965A432DD6CBA0670871F601AC186FF56C8C40169238E71BCD866546603F59B0C3D510371DD53923C1C92EE71037C47A8EF830132519F1666BC574AD1A74661A1C46DBA709E317974829CEE7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA524A8A240ABCAF9BEA0AEAA9C7EFC5BDD617D02E395BA073E0E6F8E621D501F698174C242417B71B8FE5465BADDC9DED85C393381CD5F07E2B05B9437BA39448", - "c": "E34FC9C40C386D57D2086BB28B5907228054405BBA248DE609729521BCE8DFB4A24E4742B780449CD66C32D969D8325550FD1545E5008956F040E1CA31358B79193044F77A0AE406A36D28C53A50678570A880A5FD4547BD7C805F9C4129FBA6B0671BD997F696426AADC8BA7682844D43089E33C622AF15BFFFEA5F622B65E74EA912CFE0C7B6EA3693E30DE4DE61AEB0D19C42B94CD84D72016355CAAC4C450BB4B8789A0BC67BC1785DBE9EF751E516110957E5CE8B03B59557343424472888666D8BDCA40A2700711F45C398CD92D1969CAF226EA229D1FD0666D831F92081A7A4C0B3033CB7824339E15C2E92AF53420F482E8597D6A47F1DB85C2680424E4E6B465E844259DEDC4C8D7C36AEBABA1BA872975C0B4D09D3881161734BD52100CFC3EA63119DF2CB1F43464584FC689098798CBF89057E69E480FE292DBF4663CD797094E746C6A99A27B88A7ADA2960117A7649B98F5CEA23B98952C77F5101061BACBD974256EF9F9CBB47DAC1978D31F257A1FF7E3C7291BCF3C466F815C019E2752DCD250A73C90F361C5A183A7F98FD9ED2E26D8BC3D3448267857E5C3744425F89941F89FB1D0433B107198E1583BC1AC83D903C40D4A357BE69CD3E840075CD315794CBE003D3C4E7FD04650C69F86DDC7C375EFA202AE129B1283C65F9E251F94000BCBA61AA0231A230EF0224BD6D955B06D2F3E2C978C0A9D48E68EC967C886B39CEB2B0C538551B89E6C71E750480E6DD1249658AB6C8835EFFE9593A178F619DE6BA506C2805E96B2C6D52584FBB78036D35514945AC008DAE2CBA6A1B6845320B3810C66432D628B01D99241FB70FFAA6842330D1A4361619025F24B3EA7F95C9892B95FC60F84B6230FEE12FA4638339792B225F04798E574A95209ECE2C4BB1C0C1A021820C5C6169095FA425693948D3A6204362B855D58B8B8942ED05DEAC54FF776F7F6296EE3730EE0A48B143833D7C1D30AA9266202B66928D07DB9D22E893BF96AE5C84823AF84ED4C32790A959F5C282EA6D8F4488A587EB3EAA1A3A79DDC74AF8FD8F093E2C43016E9954733FF50A37DF4CCC3DECDC2C433BA22C6A400399DE7567E028758D0AE28ADAC787109A94C75B428D38757D3E14D4D4F332CA1B12B5ED2D8526F89BFAEE860ADAF3A7A68B2E18F1099B95351D13B36FBF624CF3493FDC5AF9E6E2A42F66760A79D5BC3778DA0673AC2D374FB101F4A54133E4606F5BDA0888E722FC8D721FEA7FC02F05C649BDB7C1B5B0598BCDEB6B4CEDB58EEFE2C85CB732A2F17B3C74C6893D051BA1806963FB75B3F4BB54D03B208534BD49709E7D3FA752F71936926B03C3B2409717D6F6670B4C448FA0BAE47144A90E175524CEE0595C9D1C2EFBB34197BF4095E4255AD1DA5D74C854C03934AAC68C88629219563AAF017732BBA45049F4011056AE8F624D4D2A7B53A1DEE0DAABAC0E0D9E6D1B7B910CD8C70FA5BD58A078BD3821ABDDA5520D8C3389D268171A433ACE1E247994BB54D78B06BFDC9C71587D9B5EF9C202E15A2977AE436D3E2401D78E6E63E74C1056CA5EFC62D978AB473E8AE49BBF81ED62670BC860909F294984453930E53733DD31383D804723848CF0DEA6407737EC575D6C9F11F80068855ADB886D5FF956E70CB09F86D5D5548FA33CA645E3ACE04DF2F8CB4F6FB283CD6274188C90C6A8DF1DE37EF648B73CC33ACD56C914D2F083CF7E3063EBA33C58F0E261E8F0CDFA45DBACD99CF7290FA5F8EACC9869CB88E4ABF16EF483EDF5792193BE06347ABF719439E0AD27CCF613B688201585730110FBD2584348200A110C4CA81FB2CFAB41505B345577E97A994FEA7363B3B0CBEE900CDCF41A4EA067BE2451214F878163789AE67A49739EB09F6E8B40F6DD1B0D8EE039CB0157D0DB71158463CE866145A62DA83E7D3CD10C99153307ECA66B1B076686FF5B023F532F58B2781E44F8CBEA51C07FEAE217CE1E202A4CF8662C6D848FDF432AF34C6662F43562D5D81374C72A9673B379D0DD2CCE47C6224CE16899172DE2F26E039D82C9DB631E8AF85E326424C299BEB570C943F8ABC251CF1AC2481BE4E7B2B8CA0247195730002E69748E6BB8A7E1CB22AEB7D74A651BACE2856D114CCC994D3B833AEFE17D7015D450568E776789D173485D389C136DAE32459FFB88EC8A46C102672F75DB509AC6A486D68BD9780B76B2FDF34807", - "k": "D82B00EC3ECC8818741F6CBFFBC99350E84EE4D4A104214774525D8B78C93CC5", - "m": "6C8C075658F4257D42010EDFB1D7EA290D3344EE6E4C43DA799366985AD52243", - "reason": "no modification" - }, - { - "tcId": 59, - "deferred": false, - "ek": "F1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8", - "dk": "01105ACEB10675548E2BCB6C4FA56A7B70C0824039D35A5B9BE38DA1187274C8135C24692024A44430BE5D0834CE64964F7CC0D2A8C86A6A64AFA8CA4F2BAEE347C05374B6A58A764D493F1F765122575A31AB87C5278B6E94C8704880795462E3E16177B1C3ED4B4432194148089B5218777BB3927B4650CE44160C8ACDC7153802A266612C9102289A73606498F3A6F79001E37330C5A848908C34C0C8559E056537C25309B10FC4377DDF305167D41714A70CAB02133C500627664D84359173DCA053922D874C927C1C0BF86468730254A9CB279DBB19EE0929E9776A20E3574C4403DAB3344DE865312B2CF49301DFF86BE06481C3EA9F7969AC5AD777CB9C8FC887B2782885E8F97B13728EDE4661AF68CA9CE80208763831F9385D5547DDC81ECE830716557242072039C469E9876247C53D1847955795414A6946FDFC6786F9389CF09EFC021B7B2796B4A2A48C0A3DCBBB8256507CC0CB7FDE45B87B7C2DCC8C9210279E84DA022AE65434F139A70629D15882A1B05ACB847049E9B72E1CB6AA7647F09447EB47BB052B9D8C92850E72ABEFD734BFB55DA941905B99228EC17CA66BA82C541D3D669BFC3AA05AE6966E4B67EEDC3468A632DEA41C30EA5D0F943B53D828CE6879699933AC6C15D85A6D78DA3F84D744455784642B520DC4C40951AC26725E3723BB48A75BA247B5A4EC5C5E832DCB68861F4A6A6F8CBF13719A834AA2F6C9B9A99A7A64785F65D4768EB01A2C5B719FEC6418BC98428C321C40B7AB923C0AB107F59B5AD0EC37FD82850F64782293C1CD0700C062AAC0752CA91CCF5409147F9526099997AE622945A91BD4CB32B61569C1E1347766935B3C76D67B4D704B5D9E362CCA28833DFA1A089C2C6A2380E63C812F7ABC9BCC6B53380E6B9943009A1CB4325A2D529EE5E6A428BC1F0F190BD9E20C4EB761F8B6C6B5916371FBCEAC171E2E976927D8401218623E3C403B072273EB2D68F78CEEC20DBB89669E56151B83775489CC6EB9C11903A81A001FB6408F0AA2AED1B576C16B2AD71C4293832DADE8769833A7FE517F332B9AA9394D915838F8A62A7ED850DFB7AD82D94517087B4F4C8B4314A6E0E0A49CA96FAD929184030FBA82A86E9A214F3C5E5CB7AFA31A3FC5217AC400C6FCF18C61686564F01D0C5B1832794103E8A198552202E8CD265203009D0882D4AA4508727D2749FC0A06944B7071DC0FA2B5A849B0922F78C3A8D300E5D536792348F56630D3A75A74EA143BD5C8B93429B8F74B8239BD9FF54F2F293A94AA3F4B4B9D9D6434D85750BE959F15479D2CD0C7C2CC0DFB8C95990653B7AB2F32100C97688672E09E672670CDF4CF5B4714968C533D81997FE8A92996949603691BD2216A320B46035DF84B256E23298B2B3FCD12748D550120988785C6B72B20C3BAA22CAF8789C0880A86A12C8C6C11B022A908BCCD8B144C191A299D2A95426C5127447AD3D3A70E31B95F38BFEFDC0D781097685CCE6FD8468EEA7046C54715968B9394B3934B6229067636ABC41AB644F555B5DB95CC5EF25FEFF8186BA226EA95AEB6D76DB3B9BDE2A1C3BCB72CC0B7AF0DC4BAB0F0AB7B1A12763A2485B22649CA392E8C0CCBA819BE77745BB1C4CB68AA8A439A970A939006B3AF9C3A585B094FF7A1A7F7AED61085EE4816D632A327CAAFBB6899C4458ED43B327975A0E2325D5A225D7F2CADFDFBC016D439147B892B05A61FD34AB2D62BB462468E1A9F310307F33928BD16AC3626B484CA82DBEB405400801AE2A06CA624673C3BDD2B72DDD3641FBBB7952703A5349339813404810E554B7DF7BC18793A485E97535038919046BB8558545B87248E3B80852BB7D5A23EF5E0A396C0239D57582A03350110426CB0317A5005D558A5516727B257B54CFABCDA8B49D433AD96979E575A93AB2376515C0E31AA5B0F08B2B7B69E232CB3D8C7C809C03752F355CDB5118A11BC3AF00BF2513095D4A6594457098199544C0224A80BA18C02D5FB951B4118235B1C7E9C966FF891059B11DC566F872441158C61CA2326B7D171A50015AC663E0ED71612247ED3712ABCC121052CA5AC04032DEB786B91735D612DD4BC5CEB514072145ED6B2AF926037B7655BC7379DE4FB3AAC64A3428558B8871B5979593BD33E22DA826E44CC313A2EF1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8839735FC7BB6B7B2B3ECAFF53F7CCEA5AED1A76414F3B57EB29825F79A4E7AD90330DE5C761E9371E9BBC4EBD1B98C390180BB2BF749D427500D5F562A6CAC38", - "c": "17EC1004F9E3F5AC1BB90F19D09F7CA08983179820FC9B945CC220973112318E0C212814C5F852B8E675B392140C4B2E20D5B1E4F972CBA5CE389792DBAF7C068C17211C376CFB907FA4FD468835703F559CEA25E0A12F2267326894AB7A3F4D7D83D9D5C98F922F16DEBD6D77663D2421A60F54248F5784A4D5AE151532E6573B8FFD81421B3A7E3FDAE32104F347049785EDC6AF47A417EA8BAAEC8B89E88D3B6870835EF552F7CB57E480C06B3CE95D238B460BA40EFECB0F6C9510211F02C92CBE6B4D7AE23471D187D1AC95AB0C33D2E886E32232427C1BE7DBD3342A4396378E263D7D64CF996B76ABE1BC57F12E55C9A4789B20CC087ABB217A09951BF4CF2778304F95231C05BCB803AEFD0596BF1164270ADAD28944771BE9B5050075F3F47E5C3FB5859D19E989F4E03429E1A877CE9D65FE605FA0B10F7062A003BA13614E35C940204D321D1676DB769817FAFF8D1C02321748189BCD6CBB961858FA080326BB24536A29CD19D7A25D7818FD212E28FCCC25E1949F8F6A0EFDBDB402710B4E0E7EE67C8CF475E2E0CDCD29B0B8F52712550499E24F0EC0DFB8DB333ED1C5B8F1B3D93DE676AF65ED80CBC1406E6EE78B35EC607986130F85EC3766BE06B01FBD1C93F98F8AF8FF8224CF7F23DCFD9B3CD4576A933672AC1817114BD218647BB5AD70B249F65981C2F12FDAF575A009240B11F92702527692310719D0EDBC87BD7B80D0067381BDAAEAE5FFBF82E9487CED9C51B5A2689C338E410EC6200EE40289166DD37EFD87CF4433FE78E470089DA0B2AED03EC4601B1BA3EB4C85A261462F32B2886F6BBFB6C509E058C2CB3643FE5DAB864676ADF3AAC9C4172E5BAFBDCA0BE501BFAD5A35EAEA5608E1D2200361E581385D640C2F71DCD585B6C9946F455A071DF253EAECBF61E1ADF160BF32F4AA1ED1B4F35B0D6FE5F83B2980EB81C0E4DF06CE50530919920AB319D3233DB5A5FBDE2E33DE18B66F78045F79EF9536C4AE168689B51F54619324BA1FAD9A60C406041BDD8B01A2D83C0406B72F5A6854625F41BA1AD27E15309C9763ED8FF0FE2CBEAEC0033EBE14B211DF23D16411476B637688C6269A0B7A9CE57A344373B948B3210F8666120B6A5F4F5EA238A8EEF5A757C7D20E37835CFE472843F94C043E12AC6F36EB65075480DC580E4B7510D7D6B49A794FEFD6F0FEE8AA3477AABFB26B3D1D1F0D7D694F5B1BB2618A57FE655AC2EC19869DF7EF57C422ADE6A181B57F33E6FC9B4810AE23F41EE82EC760F571F5511FFA71EFFC867B8417D719E5986D366AD7D01CB021EA809E80C508D68DEACB4C5C116982BEE6BF99BC2D052430A29BFF82EAD2A28FC816065EBBB05E4A20722BC677D0CB1E1AAD732DA8F0D854E044B5176279F1C401CF553A565668794AAB06956019E291916DB406641A0B4A94CD2F94AD954AF203B440997C9AA315D00E9791DF171B724859DF1FE44C6AFE66C1FB35543C8AC69F5953A98B015357AA829605D7246555F20296DC8D8ACC312AFBA78920C6922AD1A3C895BCE9D54C902DD87334391D5D68692E67EE3D5E1471E4EDD20A28AD22B5EEAF2A27B7DC70D5C53CFF4884DDDF837B74E8581BB2473C969DCE8B55F31EE0098932A0BFBACC0428CCA1E130466898637D876DFB972B0E0AF10C1133A8AAA8703172DDCF28A08BF8698228952E3BD3B29D6DD22C72EFC18583E80AD5523BF3828ECA00DE5D3149F09BB31B588D2F3FA205CD00C78DE8D01DA73EA5956EB0FBCFF01A3C6FA7A4B6C08B23724C47989F7E999FD49961820A8F9C7E84ACE6D7FFED8EC119BA3EACB18E1E16DDBAA0503F227BAF09E5620ED738BCCADF3FACF7F57364865B61D21107EABE4E961B04DF62CEA1EF0E7604711994CF92CF1A8B7940CBA6212AB98ED5E37934CFE9F4122C7AB33F8666BD5F0C4B240C3FCEE1A3AF8A4574CAD95D68230F9A8E66D96079CF2D58FBF7090885E83D99F6810DDAD3B0A546F3FF71CEDB22558F3C823886E2DC089916F9164CE4007F93D6BFCE1AAD3AB69A4CEFEF87F430D73F95FE96A290A3A61E4F6C5EAC36377A0F0B50A460404590E5B1AE3B4499A85123055B73296396E29083EBC31CFB4C9946C7EC4A4D6D46ADDF64C4D9EB9FC81D4BE566C464C9F93EEA01E739BC8077E9B13856AB53AE9A12C3C85DB5B06FB3A47CF855240F87D4715EE99EAC7B9C8D1F331C811547DD", - "k": "8AF0912F3635D93D537E9065529A3D69590AB2E66607540B4ED97BF6D985AD09", - "m": "BD990171C3252230BE21FA7F186A121686187B77C234C37CA5122A7AC77E318B", - "reason": "no modification" - }, - { - "tcId": 60, - "deferred": false, - "ek": "1909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0", - "dk": "5D802C21CB29AE541E06365D0E295C066C199C1668BC5255FD02C99323C31646625E2363BEF0900E13BFA27307D1712BF4D3AFFB80383A5ACCBAC575EE02980EB855245121E6359AF388B57AB94C47989497C38A09E517E6726316F2474ACBBE2E999A16E9989B8951C8DB8955F790E61B5D3F7304CD9A41BC64C8B692707A4418EF05B57CD34DE597172F7926A46868B2264FE7521289654944A066B63B67CE375CA069357D9B0B905AC871D0851DCC3DD49847A131AB6F92934CDB794A28A1AB07309811BF06633A5DDA037FF3BA5021C251589738C2A794721E42735D1EF733F8F0812BF12B628158D83577E0107E6DAB92361CA40A904F5BC3788FF609F04854B38210D441222128B0CEBC0F6CD25D6AC3CC14E616EB4A0D6E500EDF5BA06ED7ADF647A11E365533D9C3ED2C93CFA08FA715BE8A71534D007647FBBE164C4C077094BC372B64546354235861434192B85C68B7AB3610C15D5B59A30C1832F4659ACA2FA99118614C804AD75DD8FC51B2772E7225858CEC196B60008366C1F1BA8C837A4539EC10C7A14F938283175121489019BB419350121EA18284DD14B8BEDC9304CA42AC3C9E5674773CE84D621072F90873212669988978A9C3CA012610979A4BBA114A0F39BE7E6820FE881948D444D6254887E362FDA99407446584D75D78B848DB869FE5230FA2093B5C170FEBCACC3D55B1BD6CC9EDD2850FDA3C9937648DD614CBC86640453C05B403CE145C0A1A7AFF29A05663432DEAC8FEB4343B054692E923C0B99600F56697B77394CB6DD8618605EB5CCD5B6546545056081CA8A12FD38787C3FB759BE18F300B4ABC9BBE37E2873521355BF7091C6576A792B2BD6A42F367A3FA94310B14049AD8A0F710C6877A481753A0B42A8979824F1F850EA961959E87113CA2608C59AABCCC1332B5394B1B8EFF2A486AA7B0CB36361DF5C2C91AA039109F99249379B4339013352AFA68D41A0800E02572539D557496D944726677399BB136DA27B248A901ABB76890D10ABDA81172172BCCE82807A1900D2AA5D919B0211BA64C9806231C543EB6C35D2B27EF96AA2FA26C80742029D0BF7F72676CD0369FAAC07CB99251F69A0D45C952785D48655AC3B74A1E019FAFE1430B78B7B5DCCC42D6BF5956B6333925C13BAD2E853F0E75BE0D78935695214AC252EE1AA0653BB9C5330E2508616F4057A49C7BBAD11F10422B84E5252ED320611853F39C42C9E811B0B458B0B44142BC16D017B2896C8C223B96AEC573BD43AFEEBB34E4260B88D91238F3861E587648A6BC74128CF1024B034755CEA4927202CC7879A0AF778F04C47888B13ECBE48B7F08A4CEE7CB97A4C272B8A014622389281EC7E996AB1024379A5833362C420297AB97A98248CAE6E0A65B2644F0DA07C7193C0AC096ABD59D24603ABF827DFC6B7A5B7CACD23090AD900BE4E7C8E34C736AB4CE71750D537784206489810BAF00E2B3076628D0B13C058264D13B5B67064C9DCA02DF9C93B5002091347EA1522B15228B031276EAE603B88B384B075063569CF8E7634E598F2D872B238287B8BB0A681A4F3D711497949E93FB91753A0DF27258F79B3D8B44A62C2929E265789843717AC518024BBCB23C9EC658891128CBAAC9010E700B7371C37F48B75059443D89CF35C62294E68A1A65B19E7900A80B59D78808EC462AF659398D934077A3785F999B66C60059D24601D83957597C6EA99FC5E95E4B436AD988653BA05A9FE3AD8118237B1A84D448498B426247FB5DE4979209C06800D6A9D39543AE787A461B1E433066EF2B2FB0A481388C5A68557915C4B8CF7531120C1D340133F5D5705E59136531265E3B0B4A1A501172AD8918C1F02A7B06453D8C05B48D561345050B49F893DB946AE26B6245F1926CC205E6F81A7455935B775324F1298A3BBDFFE53ABFB950176C7F65820A43C519FF596E898166B9A1563CBA7CC971B73077AEE1DA384E88887289B63E662AE7984FB8F974B7A42CCCF17750B37FB8A9424106275F122DFD9245A0A28A319CCD49D985FC58A1AAB178F12B8B3034AE7AF89532619EF24A0A77637C0033981103CB5CF9AB09D879EA067193427FBA219D49A5A35F95137EBC4A0D046186BC9E3C091B14195E2B43BC5A79C0B793C97E02823EEA301678723815631909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0011C0579E0446E2C171BEAF2BD014E13D2B88B6515E2B8A11CCB8FA4B91BF2B8A932A47B71E782BA97D69908DB41682AF409C94C050DD621CF8D958627D0FD2F", - "c": "588B326FAF4C640216A4E3DD75FFAE0D4E6BA0B6AE4214491C3BDEF276E98585CCC730B0188706E3CB275EECBF0F023EAE4E4A5D07A68D961EBA5DB25061AE3C76C2FBF6B898D90C44E479E2859F0245D579032146BB34AF36DC16A9CA55E6FAF15A6D53C5A0554F9D5D39582AD6225A1729C4F3672C5FAC82AFC900740F7B738D99FFF2E4A660BAF194E2C129CE4C6DB57859C8334D859D49F1FB46B55D6A0AA71CFA726E6289E808AB016129CCCA273A56E78812B1F1A390311286E9C4F0E8ACF6806E9DB5EB2BC782AD0D68FF394331BE7DE253AACDE455E4185C81E7DE685B7358CED67FCB92DA724A93AA86A09D33B504DFD0DC2A5F113168E6DEE9098BDEA0054B3035142503A5AD671B5041113AD0395A40A476DCF52F2C41CAD9A862762639ED23205A90EAC964B68785DE9883BCC7EB43CAB6126A116F1303B53C0DEBF9A574F3835F3CD791CEC539CF15C4C20894013F21C3E903E39DC36B230A505D33F6F81A713533494F62241E1ABE839FDFA972648EDB64D3329CAF8786C4B19DE97A4188A5D2AE995FB45333ADE7122BAF902062B56E0C5A34732C493A2F4BE714B431B6E29AF52AC27061CEE02F05ED5A96D71DBB42B06C3BAEE5E23136B015C9A7DECA77AD6A7850B58119CFF9F445D1F36FA628564F02F1BCFABA5C2783469CE4CEBF996F6BE9C2FDF5210AE428C221039BB4E343A09460C81DA72C43B52DDB44616CD03BB9F1319AB399FF44837D14966A5BCBEBCF7CC482B1E691E20D2FDE85CC327011D1A6E5514641E3F0B76E5B6E1B403A76F735C785BA81CD53B72B237B18220F9EC51BE811CF614B454BA43FB58591A0C3385421810E7EDE6895DDF6566C1B265DF21965F9BEAF6FD3599CE636E66987F2DF9559D27E04E37F7428C205DC52061B92238777199ADC0F5A19FCA01617129284A6FE91AB3F880B5741932BB690ABE5AD7D68107E330534EAA8F13A35218CD16109C1E7D4F9203EC7A21404745EB0F1CD614B8AAC8E030F6FBD84FA4C554C3699170CB2EC060FCF2E21B7FDDBCA825418BF3266EABC203F77AD94668A6CDDCE524A805115562ACDAFB88381CC0EC7A00BC7CC168BB40AC36BA89A6637DE33A31B6E90209752F8364B0D659530BDACF2D695F1D1BADE99FCC6A726CF110491CC3C19A18786E2EEAF7E7978DF2D90E92B9C0C3344D506978F09F5F33AFBA3CCAACB76F9B6C11261E9AA0965F22DDE4FB8ACE9BD7EF16AA9BB1633DF10D96CFF15930D760898A2CC48DEF58546DA07D0A74FACB66F2A37D9DE09F1D95EAB1D695A247E55C648DFA2D2E23A89E755051C9CAAA410B6A0947140AE1A8B0E1411933AD5A53878D1FD6CB980217F96C6DCBD6F4D3D8490B34D110500C95435B4AF6946B019DFA20476B31AFDEE8CA8346DF824D2DCE53996F1960570E1A8360B2C583A44239CAF65591D931F85AFA503BB3A4AB3FD763E824721BAE2537B2FEB4AF06C9459D18CD6B07A68328132C5D4C06E0088812EE20689BCF8183C953854A48A3B8848A8990D3ADBC2F3D2D789029A1E58869B4347D1955E776F0DD0BF9E86AF8381DBEF172AFC9917595CD0E85921315E81F69AC5DFD4D334A13EA8ED5EFDF8D1334E4C873A10CC5E1BEA470977D17A5E4C0DA2EDA1DB017BE8152447DE1D3FBDBA79168C33BF393BAB32630658F10EAF6DBABE5184EA6437C69386F154D1505492271CFF931381E29B8442DEF27A3D123DCE1422F099D505C237509D6AC344A3B7C84DC0C3E5070E5DADCE76404456E6B46EBB1C38BAF1DC5F9677A969DD2BBBB351E3D0BBC54C50FC2A6F15BEE73EC0CBE906895573B02615518BEA90A75B1623F5E11D86D6019461691891C1CB518EAEDC8AF0AE64F92AF0A653685C4F219B974D3DC52496E8EB7DBCE61568BE3987E28A5B6F5B5161CA4B46E42DAE63ADB497C75552142F6C93EF95189601AD27F3213C150F34BE5C38DCB3A703024F00F9D4BFEE3058DEBAF13EC461C61CD51463D50AB338CC9475D0C3F8FEF25D4B65B5657E7AC200B633148C587549A6E0EEAE7EF63BDBE1AFA1625873991FCD7C11DB82E5358931024A10911F43C289A7816F293527279F90A3C0A62D5FDA98995AA784E557B0C4DE77FD18872F07351791623668541FFC4373731B5751689C313AD5BA560BC58A8BBB3514AB20F27CB721A65C1D88006FFF5F9EDFB69A89304A6CDBEDCE1261BE42BB7BF7", - "k": "3D14BBCD60FFC1EBB9E96EA5FB23A5A18BA6E370D092E2BA5E3232ACB5A5FF70", - "m": "135056EAAD8A28DEB1BE77EEA30CDEBC7B3DD89D1444DBAE145F39898256ADB3", - "reason": "no modification" - }, - { - "tcId": 61, - "deferred": false, - "ek": "11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BA", - "dk": "01D50182530F72E8711F976B0254B13EC997A6C63338E2A0009B3470A9AE5A014765380C3DD1964F4C92AAB0182DC07C11E278DC6C3619E2125AE86985F09107A48208B62AA764A5ACFA56AB5ABBEB93402092A86CC347FD674EDDDC9307D42B593C62D94181F85729657288EC88915066306ABC84D8C888AC4607C739590B8B5F08543816B13E5539007EE732825CAF044210371A4BB85382B7D76F3A1520296207654CC2F94B9735800161B952C8928BFC611DDBBC16DC13A12CCC4A6CF776B8EBC0A800BD72B71A138BB045CB0455A4B8BE59187ED12AE2D6C9A242BAF78B21CF544AF2EB7988100B3B85C68A638C3A123E58959559063C53C53568A326BEF9696E9CAEAD689F67B59087A0AD6721755B8C0DFC83654D3ABBA0B0484CB43FAC99BA196B86E0D26A99FA6697A80B7607020EA2CB4BEC39FF556ED6934678821BDCF69D91116EB82469C183173672195C74A0EE836E55AB57B2BB340A4569B0B91DB07270A5902ACE3647F75C429A78C942B40E64C1712C274FA4711F3494937661048F85BF81BA39F1B1CB2ACA86B4D7B4480A433B0407C7D4306CDA7A13F536AB3386C95301102657556C240A576D8791048609782E3A2593886EF8C41556B4209D45250C5B063412BCAB9718AC64C7F9A5BA775AA566EBB957C947447353F9B8C958679FCB2B93C4D4842E65405AF3A9F8D49C22225081C27F5470A6E3A44C8EE9979866A4F1E5AF959C2082494AC9A34F4B3813B0760CA45C8D489227F23CACD7D21BC4999243AB7286679E1E9B12DFF50AC8C68B7F8794FADA1B15A2235CF84752A714C8DCC5297AABF8C529B8C470F9E24A972056FE5776AC9C53359828152B984E016BAB14774BA956F3C6197452BA9956302EB63D9591307F7891B9F60BA85057FD48913E210845513FE744418B7348C66CB309A93DD4CCC15FE836456AB94BAB6D7078482CEC5D92FA178B0558225358F571C851E720A40446BD23CF2136B18D0530A460CB6BF67FC2B1C5C255999D868DDC5A04B0C0205A44278E7C100B2857DE304D37B93959E76D59D801A1D111CA17281BA2C82407243012626DA8066C6891CE9765E3691F1ABC16A56534F7EA0AD3517C8911C42B8085E3D1423F650957293AC6FC64E7F955926689CF72B62B6C8EAF178FCA4B10A147BA8A1201BBF20B3F4414C09594AAB84CFF465BC5AAAF17240AF7B47600E83336FA8FA5887CC761697DD148ADC21B12294281E25B08B22636E48E0AD94868B984CAD77BF1F1AC6FB9A3281B05CBC940929520A7A3094B1B611E096441313139E7C47A0B15859959BC8A76B2CAAB5A015EE09C19181693020B4130D3A6079947B0003CB0A94C644B190C24CA786889AA22882B37119274B4B8941967C49FB1811BAD43B7BB539A0EC143CBF61D9245AB96287164A4B1CCE519CAB092442C370E885794A81B185065AD41BE2760A83BC426D68C8E82C194A7C7020180BAA051705D21B291A95791D42081F68066AB243075A5E4A82F940C802A06BB910296DB82C4923A6DF25333576069E1900E0979570FD67832C37FFAAC3DACC48184EACE1FE0379F6C0C2EC6BC08F6A80EE6ACE301B8C259539CE7B7A87B5AB098978CCB0EA2A602DB1B287AB03568080CAB141066478A5E7728A642A5B9A97E435021FA8B5FC6B333C22185EC10839A94BD630126565972DB56408405BC35DA1786D068DC80992C3A0178F5C8A2CBBADB13B8F35A5B307A8086D216432B616DD5B47A02551CABA49BB82D306715097059D92019150549C70C0B7C53C4E763CB73384365C1004B369136D51662C41F0525CB6374193A498E23862ED0578619B20557E3A095355AA39A2F78E4257AC24DD3C519AB178C0700205C34639184B128B069BC14979885BFB7C81C89409165743AAABC78495A0BBA11950243A56C645BE4329624E71692B09E20EA4F81079FA50CC1A49946EAC26127833546FCC923ECCD3CE894BA5A4F5913192B07BECE87B3A81095C82B55B5D72A3DF1CA438668DEC2BE1CB0674C25CC51938ED5E9B2399502A2157A66B5053CC2117957490A113699975383F69ADB51A87CC9582D041628424D76E547BE32C273CB013F75388E7C9CF91190CA293CE2AA7F3FD749B2FC2DBDC9468B80904E061F06E8593CF33A74B305EFE157BD6B7E11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BAC17C983272288473C7676430281761C00CD2557C8470374B257D99D63E68C2631D1B02042D01389FB44726DCFE6501D72FE645D5F098EC86393687E2E245FDEF", - "c": "6802F268BD6991AF8993B2CE0365253B67FBFF0422D0536119A91A8AA3591EBA7BEEF1B3E08702DD63D9FB48D8FAEF6BD7BA282095687A9C70FFA21960EC27EC9D899A50FD2C6103E1018DB559D7CE368FE9CB0D4206445CDCE0B74F1BBB4DDE53008E50C632A36D9B02E97192DD633AF5936DFEB0F5FEBF306428E7993F9E3A8E47617F224AB50403725624023DC43AD6CCD3A37931E6514458D7F16294AB8ABDB042842F259937B31BF2BF327B2E8A86B20B6A0BA3AB87D897EFE6ED969E10D80BA1C7F53ACD704542DA064B8BFE8EEA9D73CF6453F3E1F0137E0A52C41A709689D3311A0695FF25B8E54512A4BEE5ABD52A887C52B1A509C2E7547EE621117E1A024800B935C1D50DC7B3A7D9D385A1172713336EB49C630EDA7E1490AD13316E5E0F7302006FB6ACEBDC6ED9EDBCFE2F9846ED0F7CB1CC2BBB593A7DBC6879B916C81BE5FEA5F4361B4B2FF17AF7B7D21DEB36D9DF9E504EBDF11ACD7273A1D7BB13D690BAB23A52777E208A740E75F797251E9F87915B975E7E764D3B2ADF90937D79D5F8FB1EA8CBA525C4786457E497ECA4A10757E533A7644FA04034308FB197FB133D136D0B0C9B40E0977E6C2572156F164F3917A4D0E6100B7EB9F22517450309B479634E9770F23C83EF87FA9AE94E90FEA32FBADB9DF1D50DB1F1F8ADE62F1501FDD1D90ACED42446A859AE7802F7F66BF785AA454E89EA8CBD5F600F9AC4E8237C3C2812D5439BAF89CB2D636441C566BD43C5D45489B61B2BD637119A5E5E0CE452EB309B4D7F6C7C387930A9FF6B90CB3C225C99554543EED7A71533090EE0C8A6CF857F4BAFF48244FAF5DC85DAC61D737B7E6CCDA8D9C439B2120A47A2CBEDC95D1C3E56EA4CBB9DDC89DEDEE5103ED468C8115F544DDEE5DBF41456F6465E1CD5C01DC470D9A9A64763BB679BA6592E64C82F9488E008235D6FCB84AFA7D2E454058AE57875F2782BAEF71F1512069FA24802E62AFB5298E307AA1EC074B2B91356045159CD6EF8EB946B6EED50D25E729FB176D4A866BAF36BFFAFF3907928D25764BE3EE7D226E7C82A7D9F2A3AA69022083082FAC7250E6DBDB43BBB8C77E03924D8D297CAE45097CC7A3833CBB75E69D03D01198A9B9331A8E9E10AB82EE349099918B07878120EF812B1B278283042234B36DCCA031B13687E9F1853E5503B32C1E1CBC51FB88FA5B1B044CC715F24883FBB2B5D45C7F461E3023AEE3F18A34030EACCB8A21FE0178F845A5380C3BD8B8DAB193BE5E02F45D30F8B8A0173D89ED0D6C4A6959CC1AEB34CA8B96FC46393FFA35123BC87D580CBA66A21F0F30E30F9899216343D6E65B8FBB1BB5130AEDFC4BE7234AE6665E0D087CD92812437E18C81AF042A55840A58C8C15FFFE182E19D9F156A246CC1D359C36CF355B71076BB6B9F9E9C8C6F9A909CC58F41CB79560D7D849626D6CD1739D90B3067D6B33B9A989A4107F6B0103F0F7F391DE8FABF9DB10F580EF53885DEA39CD96AA8343164EDE94E6CB7CEB8347C24A23C40A3D0C851808B46D5A84EE6E1676626DB741C7674B0D33DAB62FC8AAED40F4E6A9590354B0D24226FEF439D5D89D1B48DA564D30744F5ACE5C61ED8C3AD522D87381E0311850F03B76497AC92AF2D9B7FF8DB0BA1D5A2D63586AE3DD08C4A0462A39441A20C59332D2F07053B1436117B1A9D43C477D3D956E129ABE92D7E6D7A2A383E4F0A19F59F8C565DA746D847368ACC95E7A00581B6A330129AA1A718D0B1860CE775A1BBBE244B04C2D1A94F37E2E360757B9830D2E7814D402E808689C9B02E871061D3B8A6DC408ADE9D9C3B77C8B0CE8B3B23A246FC1BFCAAC2B2635C1AA12AB3EA937237EB224B5E87331B5411A2B2F17214B1A86B7644B2BC9CFC2515A6BF413E58380FD49FE624C0E3DE4FFCE4B880907436F425596A1005D55B366FD18188EE6DE1CBF9614A35CF163268DCB56C76355D4ABB3913D9C31C1AB3E9755A305FE2E186715DC3274EFBC1A7C97E2A70F5D6DC31FAE5C56F4F335D8C77AAAD4CA2DB284ED2E56E79FABE984758C6348B7F195BB082BF5D8482965CA1C6F6BE8D8FB9F0E176BB4308F8B064E48A848332A81E34D28811B76AD62EF9F51EE606F74DB8E98E9CD5D7B2356B28D6A5C7398625549DC0C35E4D44E9CFE30BF8AB8A75AFEA84CECC051D9298D7B91EA8DE1FE7736F1D2038B8D3BD2A1A1FEFF4730254D2BA", - "k": "B45BA5490571D2DFAB9D9204398EE8F141A3FF5B415A2E2A8AA3391263992C82", - "m": "54E7B2E3305950EA570F823FE36A7999E419BB36181B5514860BED41F418EE77", - "reason": "no modification" - }, - { - "tcId": 62, - "deferred": false, - "ek": "4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603", - "dk": "7A8721EBD06F9A1845A2089AA7437CBCDB4B86C4529BDB0043B7BDC5CB95639CA32989550F64296482C8CFC15590444D8CF5C699348C0541AC0224B94435B972BA98832A7B6C86600E8C4AD9DCB0409CC278F01A6748005E7BC06AD00BE8D731E4182F16563234960634683956B58217D1B69848C934840F02C49398F0BBB5EBCDD422C54249C7195066F9F900C0C982A9048F4CF3800A10CDD1858269E59C307B06DD050F5A58C6230A44D8A9979D491A289A4B3C88CD7AA9307FD93DA99910B9F3A97FA759BD25C6D9F3A41677B8DE41CA23D3089C43B584C11C8031205BFCC8A813BE1D5169714C84BFD499A019030514072E59A50E5B7BFBD8A03DAB360E16AB02FB270B434F274A77ED1A67F870C6461A5C641618254C8F2061BFDA921B1E906626CC956758685190017487128D491C07A33E3C023972488D9F504BBF27BBF02CC85D5B8F98E61C59F27B7C879F4CB341FEC1A7B7A13E7FC496B3A511AF593312B17C9691369C10B7E440A93292BB25B501A3522E4ECC1DCE5A8255092F87248C6DF39D9027C5ABA21E10F003F88BC2ABE25B5533C2F390C4C500927DAC631307C6BF17CF511C8927FB75BA1B44499900FE0545F20565FC139BE9A5221D99C656643FCD38CA16756D1D81ABE54971961A60D47C4365600EF43BC97862A41AAC136A396D3E549ED7469B1CF0AFB4D107E9C685AA8BB26FAACBD070B4BC9C1FF502BBF64350902972A75810EF04670EC9A9CB99830FB88C150AADA8C457BD338894A18ED751AE584758E16660C221B7FF538347C05EA7987FA92A96BAC91FCBF0CAE004107C8472E0118D78F0166971CA14E1BDCDD229FB631FBB81CA8D4A3282064E9FD3374D674D3D212DE71B0FE8765E05F66C251BAD690C300858A220A620205239907274B754AF091701E3EC2ACE6B7213190F69187164C8606355CE0C1B3D7716CB7BE1C335B506F2646EF18A092F6B6328A656A66A5F6D534962F5ADA6E335D7F37EB61776A8D26326B639B48C95099C3F801A7F3E511CA1E45400DD1735444055624F1235A21757349502372C4B6C01C96D96D9220D0638C2163CA7765DDEB58F80BB5F42442D20972DC94131EA83B6CB687E6664B66A3736AA29828F40949B4636A4A505B2F7B2EB9626B491BC96B16664B545127957B846626DE12506CA449D13A657EA9D8D495D0F8B1C0CE367591C1186172CD6E380828B1E5C4B0224D0298D872E0BAC79524707F7014369D520AF821BC1F706BFAC6C692C0CBDD9B96B8292EDB27EB7C43530F8A3ED848513946EA1D0BA5FA00784D0A85A528800B1C463440080750C7AC6043B0529F73B29B40358F457A68E164855E7626E964CF5DC2011DAC25DE82EF72A3503280F3F23A058783625E68D9480ADDBFA4FFDE76F5AE87ACC209C43C65F11F652954A658C86C9FEE684BB1B7BF73211EA002A25E1BED40750D41CB3665291843B0DB542BBAD481D6B3B021DD8635AE93D60D07807A95753C79DE35829DE5C88DF095301C433130A511210792624A8556379B0F35D9E3A2E583B24B1BC587D038C5C59BE09CABEE6597BB9CA49AD022E35C7319CE928140A026D05B9761AC129524332151DE9E65E4E9A0289032E5EBB7A47A82AAE9BB2ACE6AD16162336BC8507C0C24AC0C4A2D076D929A67AF8959EE472E14CA87BD0B89076AE9B4C3F95E3BCBE8815AA7A849F6A385A8B0756917A3EBB44122989A49A33517657D67021D2F6BE9D64A1ABE9B8C590A9EF81043D19C556B97DFDFC03D7A4173405C8BD38235EC07BA7C80BD97B4566BB89C227855673B63A09925028C24834ADAD1C26B7D804ABA3110326B5273B8430045B2D317B1770BB3FE592BBD32F55244601F58583580431C35BCC955C9A5656A3431B943A7E03D5B76967749C886458348FCF9CA7487A66F9B0AB3D92462ED192D19B7D8B58532B09642F490940803EE97576093C5C32D1A4770B86E7F58530776B5BA1051F1B1F35309ACDF97319846789292DB784259185B80C3B0288D103CC1C2E4E23B97E9B140E18B34AE8A4484647B66430996844E73B0A0F79A6F5179234E22C8DA676A379AB8EDA542DD1921B481E866422BD0822C2FC33391293EB31B31D7A9574E31D7E070FAF298E46BA8CEA3001FA0210A6890A6C68B73DFA519B66A23ED78D4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603BF822762AA356CDBD08EADB7D166690F4A00D797419ADCCB9133C3E5EB671B5654CBE9E686EFF218AD6583359070544146921F5107809454E73FC105FA7A9A0F", - "c": "566EE0837DD0AD41C30D9C318F736E6722D037E07BAE16234A2051509180D399518883004079AED8B2B6E18A2CD1E2056DB76EECF47C3E1268A5E662FA6D029F7EEFBEBE1587919346CF7D38C6DA819D7A3A89B2BE65D6E2F87A6F348E8F9C67F99B5ED655B5C0A6AFA15DA8CBB310B364552195C8F70B37F153270322E5E45B86F074EB3BFB3B03DAA7E81B474011F2F3DCEFC3CACB7E701B1AC7DEF0650362CDF5F6531E5E5FEEC973208124DD22BE3167F49BBB9F160AE159E692C007801E1FEA10034A20EC460F72FCC57C9C2E6CC749F5110AC6CD7A20B6CBAEECC6E6C5FA131F09B19EFDD175420B2762E4CCCC03906524AC63C6AC92B1995935A83B674299095DC4D2E26E3D31B8A4D71E9094A4D50F76DEED368F2DDABA358C306646AD0148408F8B8E6F5899F598CFDAF90C9CFB50A285150692EA3955EB4FD80BE445777C601EA5B59EE07E5B828BA576F6F300D674973D658A8D4B6967C3A3ECE68BAE27A46AFAED43D3392B985FC5BC7D79B0D56321316649FCFA84EA05F02EB8E3142D72C06D93FA73451CC0134B53AE1B038B4EEF71946665AFDD50CF3A33D188389DA9A32E7B46DEBA552C337DEC2B28CB3570DF15A229AB8D3FD86277FD5AB595A0ABA2DAFB7AA62F2CDAC997F13BCBC93A42D37CB83A52FAA8B01F8C97D196F1FD7A618566CE8593BE11DE0437D2F82476E65D522ECC3D8B1C247ED0EB7590648E1A51057F953F0932A567B799BD431344E1E0A6211BF07CCFB0B53DA9D39C59C4290ABA2930BC691F83830779C89F14FF6643D277035E5711333979D563DD1BD4F52295D45C98A60C5D59AEFFF4ED119B2D88C7D5C7E7EAE0F58207389547BA5FA995678A94D7127C407EA0BDA29CC8701B83B27447654B156461226BBE337FD69BF0FCC99013646751BC53D9070568E4D2C0DB6A06CA491BF80EB6C2C5807542CF6569BA84B88EAE67FCBE2DEABB56A5D06E945F8389EB68ADCDBDF0CD9018ED713BE071A0A87415647A97DBB6665C09C5F27899BED8837CBCE0010C70D7D04419240EDAA185EE7AB14A1C55AC6546ECA6781804997AB2B15CCFC9035ED7F170CEDBA0E280195E7B2C2C33CBD5BFD10CA8A2E82D977762BA6AE5476767F7E9FE787FBC624A81D1467C26CF2C1F1B1BAE476522DD198FB9FD5130EC41DA3683B788D07DBA2FFA0D460B66E5967D161AF00E61388BF317897E30B35BF8EF1A580DF5071471808E764E01043982082DD2BAC13DCD049B1DC66D44A670EF6E063B31AE29F391BBBA0ED0ADBDE06B0E5403B68BD1A4D997EF3F965E591D8CE8A0843D64EA4554FAB3DC9D5A96540DC2ADA49504F25213CC4EAD1E097E0CC516A4E3DE6F272D8DFF93604C39551E8F848E349315F46011AADDAD6F0BA68F1D6CCC68AB6AFCDAA1D47FAFBC056A063641DE73414C26D997F243DDA0817AEB734BAFD35C59F86AC30D45D1E5A0FBE63AED51B02E6C7851A858D5E0C23E53DE1DD0413D408F665D62F24FF2F314A283B7E3848F1E17AF5000BB9D279C0647C1434F783A1A21BC7A8349D62AAEE19FF06677F81C954F9D6A69ACE7BE06518ED800923C6ACB36842CE65EC81749C388AA92164D28FD34D75637F23C49DBD74353181655EC029593BCA3214C73A540CD9C3F6B1056A2137D0C280BDC90C13E973555D8C4D64531CB7360F1E67C1CACBE9F2D59AFD3BB5962C4DEA4FD9341D87E0DF55D344F4CF0A30CACB8CFB10D4B6B07AAA6B28CAEBFBEF4F0B4CF6EAD9387392A27DDE2C4BED1F9908DFCB9E1383864AF6B9271F0C265D2651919C66BC5D3850CA741A7705D0B4F7D2FB82DBD376079AFDA8523756200E6E400BED88992520429215C3702C97721D76F0C9EEAD7DFD2ED0D604D6BFED6D942DF0AC48ECE1BD16FB35A301165816B0B4DDD881255FCA8C2EBD6A4C1ED56CA83CD868AA7EFB0199709DAEC10171B870D3A9808809FF0670BC96B66CB45EE5D0198146C0AF1CD920B1E315879E8D24ECD8DC03F3E8C43A973ECFD91344F2E9520DE4922544592C26F085D53A7AE03A866C369366A4CD78EC059E871C90996CB4463F21C7F0A9914E38ED324743570818FEF155915F2E1087744DCCC6B6DE8991371DEAA4DACC534974B1838BF8A98066F20B07B809936A36B6D4C4CBEA220B16241FC875DA5D5573FF74E3ABBD2D110FB2B288136857CF5F0AF36E226EB792BEF4CB79A6A8741FFE20E", - "k": "27CEEFAB9BC1F2050BE2874B3A81CF1148567A1E73A5DFE89C640C0C88F35580", - "m": "F2C864FFBDC366EB96BC5F5FDE0D4B3348A07E861D9EBA90E70896F7FFCBD55E", - "reason": "no modification" - }, - { - "tcId": 63, - "deferred": false, - "ek": "44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1", - "dk": "1149A69B309A5FEA7002DA1B0D4B4A45A37D863841D68452692A96223C203CC24B05285915D48F00091A033328ED12167A4BA398A9BBC5063A0A28802CDB3D8B108C359601AEDC31AB8C8729E81DF9828ED5900715264EFDD3B0C77176D6D0ADE200685A239CFF946EAD338351A54A82921E9CFC6BCC60813F2873BB50C1796276501740FE2554E130A01DE941D8CA3A0B37318C467D893491718BA84A26A4229A06476986C668843198C12F034178064D4A4B7A889C921C49028D6B9272497A4C0C6E03F78C6433538484C3B5D662058BA9C9E9B474E636A4E20CE194BA87F98B7EE4A26D4A414A4C4D97A3A1F420885098871D2036D6E9A2FFAB978E217996E64CAFC34E30F453D2E1CF20AB6747D1C0931A23147052F2A30E1EA07927A28733799F88FC8199896EEBD324845119D03838F17286F32A7F1EE89408606E66C72A546333E3E714DE56467DF46AA6C10CED9626C999506AB60DD5226259762D6A028E2B4798DCD77217073907962DAF17BC6E54B11A8618F97104602250DFE40409E615226077BE778D8791838CB1B11A925AFF9622BD4328539CC015BC321E9CAEE3699B8CF9C075376E6F2C50C495821DB1903C2BC04DAB2BE90913CF845C368BABEAAAA79E998D1F066ACB67CBBA673FD3C1014CB743060B1DB2A93593C316BD982FE9FC24049221B9BBAD0EAAA47561AD4B81C81B46C69FD3847C8559E77A368C57520329A06CE7542C4771039072500AA324B723FC96605BA225654008EE7BB68AEA14843B18D3977B050914DCF2BC77A91EA7C4B46ED04CBAF47B2BF04129B05644EA360F3B69C2867FF7F5B710A4947AB29BC5882BE2169E5D7442D659CFB46BABA459869FD291B9D505181A306394AB9643810FAA68E5534351D3744E4CA3053AAAFBDA7523A33996BC344D91BBF8B7C41B1998C2623F261A94DC123244AC9DAAF49902D407882B067D12C1A835A5AC546BF99C2264B525F9628EEF5BBE78458A103236AB8B37D67A5EAE21369BE740D4D3B567242517404A53A049C3076C310560AFE9AE495557699B28B2DA72B91720A1524CC265067BD3227381741E0410F19C960E0B8AF48CACCCD70002403884A95E578B04864A81BC1737373135E9A2573B51CA9CD4C11A8248C3122C5192A3ACF167FA1A21879C09A7C21754980485A3272D8985A0F52A4CF77813AAC828231B06F4BAEC5B15D55638F889679653458620C54B45BE8C67C6D2FCAE05368741B26E9F6646D0142298079740A61A0743A10412BF2C4469D60C6B08966F1180C4B3C83E62D3B0E4D13AA29CB765D67A97524D1AC75A0212928766CA29114B906A93F42CC0CF1B2B6A6C2948F80E9A5954120660BBB2B1B42297B8C53D9BF349A86327249779C4C41442655D321A55F12A589CC62F18147599C6059D08B4365A3DE541C845FA37061C13338A8A1475BA67C12F0C67A3430B7CC53A46875241D3359A64F104910B73763197C5E1A88D5B1D05EA98B97524D4B9A59A7655276905D6B1662EC9C638AB0D8B746D93C9CFFAA59EAE762A54096B124344B0F4BC7CA6696D53385554B115C2707E203C6D161D14B31025F336C08B17F907442E369A54F404CC6B0DF3C62ECFC805C8D967A29A1B17030EA26C45AB71684F7A6065A8715AE7A37D6C5E3AE25A862B3185FA53C0424A3892197A339A6EA435264798948462F8846DE6A04C77C951F3C5C9262B16D3DC8E7D7B3ADFE75EE3CC84706BBE9B830DC0972C15E404B147C4FAC09BF089B057E5850153978C8C625513ADF872A30FD7B1D9F69B97AC123E11A611C6A416B4410483894BC8AC738B3E0A9C0D7F611D88611A5C62CAF879307A20732F17B26CC52531B447894193AD45497D64B8562193F670C8B8AB1F74DA79A945B16E01AD18006AC222345C20CA5B2099E9818E0DD155E14B64215C88E0A72A57C6574C692AFD1A382EB832F6033E8B78AD68BB60CB218F58908B92533C635A4D41723DB231BC2CBB5B7AC03D718A96D3D80120C79AE43493A9404E3BC46391721F68F80FEB7C47CA4A79BE9618480344D6790402799AA5E155F2E229C45C970E772D517995493661A04A2CB8FB90DFB056044616669096ED51C8E2F131B5FC729DFBC876A412024C692899540334071DA2911EDAA7D1C49FF6C96D4C4C2A51199B44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1E5AEC6C6BE5AE6CFBB5E8B66EAFEFC8DDDDDA717B32220C994BE42776B296D9F7814DC0CDB963F257E983581EFD3A55A7B58E09734B10FB5A6F1CE03B12D16D4", - "c": "E4BE80FBAA47E08AB72D52DDAB90B35FF1F4C1DA793739388E49A548C6A1EE07770C6FD8153A3984AC2800150B20E2347DCE0A06D2C83D2A203DFF7788C969C969616FC1BE122067614989F34D0D84F9CEA1767D0D9D83DF8C573CF4A3EEAA6A0147731A373768DD38505BAA12C18B524FB2682BDEF71FEFFFCCAF0A8CB4F42A3A1E048DF6A66CF898A171FAFC840B46A8994F7D9A00CA42CFC2539FB3404472A39EF65B0AA7A376A421FB55B619E65C295A51047EC80334A7B40F3925FEAE500350D71139F6DF4C7EA9655ED2C869A7DE115FF7E926DB881E3372D47079FF3F48A944DBA7F70B0AE01CE961F16CBADD7C57A94EBCEEBD709B414F7DA764FCDA39FF044FB0EDC16BDE8C68AA7DBE92C1AE3C226EFDB7C5F1746BB56FAA7ED34B2A32C7A95A05EEB7E75DF4F7BEC3EB78B74A058FB95C20B33EB9E30ACD8340B685CCA66F2D1F6737646F67B28CD62FBEDF708A4277A8B6E82F012895438D14A3807C087BACAA432ED6A099470E28E4B06B64CF6B249E4AE72DB468948E874565ABA879FC3322A1A89881C55628C37781D28B39102E97E74F0921932434ECB061E6C388611217D29E16A0DDAEFDA0B420DCB83D5FEC1552025A98C4D6F19D6C1E23E934842D07856CDF0E5A9E8CE20F68C8425C8D54F7216B6B66BC3E1ABCC6DD5841EE0E1CC5C7BDC5A7F729A9930CD4BC946A33D6534ADB2BE0DB65490E58075FE3A8CFC273AFDE116A6A4C317177613DC93AED69D85ECEA4C55E43DA1D08780B30D7FAE75BD1000043A3B56E58ADE657679A54E3828A97CBF7436601408E5C00936D4BD3A4137E75AEFE338C6843EF3626FAF2684C6AB8C3F3A04773C913DDC72DEDEE9D45E3F0E37A3D8D5AD2D3DC9CA90B0CEB666C646F265E5A75D3D6F7E2455E11B5866C9D620FB2EF4D9CE86D0106DC84B35D603985B2562B3FA0BF6868313907B852F4B23E2AF6840C808EF8AD8A7B51456CE3CAAB34CF68CCED6A81EC1F9AC7E090AA1F854E275169C888499407C52CD6A7E1A7D572E31BBE6365056686E53A430015E330E89CEC44BA98A1DD6872FA3D4D71B19C65903DCEA30932C2FB94CF8233F26D50EDF3213A9574874B0AEBB1B6AF0807F352C40E2945A134EE7DF88439ED578AD4E2D7EA11D0C9C6CCDB83A03B6B9D026DEF328D2B3DEE0335C8092C46381E65B159E7478C615D14C2E800126ECF70455C3B4DA925F36C186DE2AE1B22D814F974D5BFB988F7D09140AB99A662382EF56370373DEA434AC42D1664EF116E92A90442518FD84952C7F35D0F42859BE3427C4F28741335485258756B00E2A90E7CCAF6B564326D25D76CE8A6FEEBAFCAE375135C1CCCCF12D232A0B062FA46F166AE2D99A36DCA64BF2F55B0151F64028700F831D26E62C41DF8DF1A46A8697C5A2F8EDB75C910CA1D382BEBFD3A4521E174F4FB3A258AF666501D00ECA819D310257E7AF85F4087AD1501EC4E18D1661EAF75F50BCF8DC80968FEF78770065699E8A857C12E507D88626AF509A2331CC228E1A2BB3526B687E63EC763EEFB375FE751EECFEA143BACD4455E8F6E1ABF0F82E4D41C5CB770BDFC3F78150D584DBAE744BE4C20199984445F435BDB46454D662F41C61A848A7C887C1A04D41D4B92EFE657ECDB9387E84495EC37CD183F9C2EB5E859D722A614F3EEBFD13FFE2491FECDB4DD2C06914EED59F8211908516C799AD7B9B46C5EE5AFA808B67B1E36F81D9DD3C9B27188BFD40495BAAC44DAB36AC61ECDE47CDFDA7AFD9C40952AA477818A38E3060613D879E78874254C599697ACADD42F1049A3E5BCAE75F88F7771E294EFC9D3899DCA955263671F5205953D62378A310FAB336EAAF4837CE6DAAEF1C4A141F6192E934A20AE23BCF803215B5A96D6CA99EE65A205EFAF39082A42193C5090783B426B35A1C8BA6A6FD00D3341ED24008E1D70946E22126F7CBD71A49AB15D2561FFB4DDE90A497A89049B22BE50905B63107BBBD13E5AEF39FB761091C7384519455057CC407FFAD746145BFFEE33E120922E06FAAD8C5349B46B3133B4EBF1AD9C84E9ADF35B5DFCA3141353A1766C04907A6CE0C3E9C6D84EF9E732637AD033829B13E0B9526A1C8BDF4296AB460B32CF29845888277C479565EBAA7C30811D2DA71BED5560A5688DC18643818FAE07D531DE7196B947CD1D94F4447B77CB48F82DAC0C7404E302F0445B656475DC65608B", - "k": "0CA16C93880B3BF4802D0EF7F03E5C192440CC4B399E9A55637F1E6AE6DB225E", - "m": "EF29D988D373C381541AC8723EB67C68CEDFB9DEC0FF2B40CDC763378B380C12", - "reason": "no modification" - }, - { - "tcId": 64, - "deferred": false, - "ek": "E2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5", - "dk": "A5AB9B1E9973958172E182A9133A3DAB22806CDA0B88E72BAF581183973220061D836405C702A8494422B43568291CC432443543270DE0B7C85C56AAB20C0A17617C13B9903458C20C423A65092533AC4BDE6609E90711BC031A953C3A3139960F14CB17F8B3C3C68BBE6B84271AC5F003898A79912DB2B68A1C05AC204626C0275551BA6BE211D6962E7147863B44CF9CCB6D6836007FE44AC028B43EC9AB65B792B61159AE35477FFA5D783281BE62CB707496F1AAB956F364ED1B8971F35B6F8179FD77C30980A163A51836B06F44311C3E7062172B80391AC5B20409CF16BDAAB4047DBB56255C325580976CD60113C72A194772149C6C2F342507016FF6B919613260902B3DAC2673D4584C9F87BD093AAD02950B8D750C1304A749F703D0365433065476B0CED26B3DF644B5F34B89A055C707EC6D059620F12962C74A0B78FC7CE12311B1F94504558DCB10BB27B198E2D80E1F8378C1462133209AA1A99BE03A978726AA4F88152C05859F667C708A9430C6C1FED06784E72D0F30198749AE8BA86172263175FA6FF380CE7E325AC4A6BF3201881DC16705A530EDABB7E0A28383D16E6F5BB0A87164917A6E942A9768B049FE37931D0192C7B5928FE14846B2686307A77757AB142996B049ACFF85AD5F058526510AF0D72E67DBBB17179A91B3847929145AF84FC355A1F454A82963A52CE6CAAB7BBAF7B22044391AD76187F37ABFF9210905495292F289A45077EC567D0F5C077FD44DF2A568F682368D2046803880B85994C61637B4B19C32D217B3DC961D9858D88A6D8FF2620E9674D9F5C9D066B3346A765E8684CDE20C4ED300395B6C1AC200F28930668B426FBC509F810EFC1396B167953ECA9670D34594415B61293D849C4245A57F6E2481ED0A40AFC8B2C1F7476151AE95C68B26E6679C155239C922D0F89E10B9C58ABA7A56EC7890F97B31E05CE97C4691F27167929313531086D46041E3452F74390BF06A787416F58537F6395AD5397E59CBC118D6825F26C181BA514D0BB42AF862BA5670C592132D4473C66A13EBF58E63021887E96DAFB14FFC408149F55D8A68AFAB24AFD1482C27555818495BF1B88E0F072ECCB44A0145A880C51172C6A411940FAD3BC31CAB64D5A2160FD8903445A6361B9FBCE5B7CE74761E339BD6CC3517551C0D2357095CAB8B34656C182165979A7F01930B331D6AF6A5DA8B57BAF76ABE198C2492AF2365843D33C84D013E13D13ADA4B1B387B8CF4DB7445C002D689CD93017A7D3A03F1B224EF7075AB88616C5B2DC343C0D46504D292A1A51960189A5FB968C985D707902B54DC390C8EA9A8EEE19DA0B0436B1259268C7B87A26D48A978901B1C44C6C0646CBB0A079F999345C31147AA9B3A51451F11C766C5B3C0851A00BB78350D60AA6437228B84A9DDF6869310946B46C483A05D7C04060AC89402691CE07B1769B23062927B875B4506E208F939A02BFA0AFC954FD0B034FB5B268EFCA527B01712E12F83E8B7E52996A68B63EE865782593C0FDC222E4449BE0657567903D48827CE526BB4215A31B8147D475C06D629B2A39DA7D258123AA844CCBBEDC83872A96E426B4DCF546BF2455DD739B8D973BD5C43C1A48A2FC4EACC676C5062069F9AEBA459D3A8ED880C63FA6ED80C06CA906FDCA895F2D9CECAB617740891F2A20B14DAA6343840F0CB33AFD38850CA87B0813388339B582A8DB0721339DBA66C2B9C118CC1400047FB7634CE8A8063B20175D49BD4B22E87B3AF335535528CAEEFE31827F20FC75831113B3013492F3F1709C873C09666928559110A5947626A14093128292022EA021750828D8121477BB0150D07D00E715F08598520F2744BD849E7082DEF2384A742B1DE61B44073691D6A34519A541F7B265E9B7F500155931628FF194D29225BEFC366ACE60F3394ACA71C1E9A7C2021DC241B339244F0CA3685AF2CB16AA668692F485D31590DD3448352E3C7C892191DD81605EC9211330EB720922F5A096FF342BEDB2D02160B95686E8302B82408A5076324EEA620ED81AB3BD097E173AE25BA777BC03AD2459191B225CAB540F8C1197885AD7ADB324206652BC678FCA24A57263DE089ACE6E1794E4B49EC85735B91830513AA9808572818C7716A61A51B7C59408703F066B7466CE2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5BD1F755E964833390BB7E9BEE7B1C5B34D07CF3593530572F57DFFDE8C0A167CBF377142317C203D37A8BCA5289614884A22271B47D91E03EE6D366B24902271", - "c": "4995176407FA65D288DDBA1FE91F7D2ED8B686096D49FCB85655AE5BBB09001FA8B8167F20C31A62169C319F798E38BDFD580DD070FA31499931C580950E2023C739D0D9C13F96ABAD0DF1F1E8B718C78D228BE5855CDCB5EB3A0B63C6EF156640615A763CD211FB94F540379F1876DD0B8619FC2EF14CEDC6BB9265F5C01B2833EA4F726F68B9F8B3AFFD39E71925AEA4EBF66894DDD1C4761155E9663AB89ADE8A50E9EA6B8253DB7085B8002FFB6C409921D7295F37E9E0ECD45C7B204FFC45792238CCB54997D2CA0B7CC4F056FA2B783A384528721CE77A7AE5C6938FD1CAE8CE5E7BB57405C6D5DC0B9517D45C580B0BD91AF807EB1989BB713C2DE9D3C7A891E31FECEBB5244E89F7F9DD574159415A81C459BA845F36E39B7B5FEBAF565D8A79D1E9119C618258297FECEF53430933956BF4BDB3BD9F12DEEE9BD0691FBE24512C178F1086DD2063B46166A3B00679C8D26EA493F28490523DDE0AA711DA3BBE9E6F05F569808C97EAC0AB5C8C0CA1F1BD7172DB19D94625904C08EBB3AA704108D033BE20B6EC6520065E1FD328C01437B4373E8DDE6F86170563D1E17ADF963F9D82AD654702AF5FBD30B76727A75982DCDCA3B5398C82FA42E6225AFB16C6FB466E9D5CC040BEA834DCE7704F94E0296504DF1C63908AD8729FA8DF7C9DEEE23D1D5922AF0548BBBA27873CF73E2970976DD56CBD562AEBA199906F86847AB60FD9D25BDEAD0EC2DC3C7D251D2396EDBBEFB438A098C7665094C088D9BF57AD4327C61CB484E0E730D5E7E98926B11CD4519C729FDCEBF625D7C743996F3B2E8FC38C29433ECE14D427C08EA079AD0B47466A7533C480E06C48CBA27E180011BD10A1B1F7089A150D48FF59EAA9154046F954303F3FD9BBAB91C667F7367868DCE21471B2ED4F2200674E221F71BBE457A323EFF93E89C5DFA4E8EDF87C8DE741ADAB529587663EE1180D60BB42CD8BDC050AC41457C8FB931EDD71B68B0448D036679D5BCEF2C91EDDEE940BC8D3E412A363712413F6EE9697D932941281381F1FD1EB6ACBC6FCEA805CC6FB301C4FDF4062B6BF12AF691FF0E65EF4448DEB4E403C2D62610A8451807B14D722C0940AE6C7C30EE6EA4C4D7CE51076A27AA93F3DECBFF2E0D753DCFCC8444A223074FB0A291764DA8B4A8E7B17CA12F7F3AEAF69B11C0D00835140769C59EACD9E9363DEDD402F126480F1763C50676FF0DD8D21C2DD74B2F0C988A88D49EB40F99A728A3A896AFA9A27F865DE5F4F97A2899CA92F1804C5F3A6969EA60DA4EF3B27D822B5FA6D71C8690721A531EB637CFE3D1369A08F4B0B978FAFADB14A26242810F5B5906576A7F3F9C7B57837CAE2F10E164067E08E35D5A6E2A27DC81EB1C9E6058047EC8127C388AAD709C0632CA237FB23BCA6204763AEE078E876C78AF48B6D22867DC199065880E52EE13449568300EC14396B35CCE9878D6A6517B425F7E0C7A146F62198D1165AABCA7158C7F6E91F32D427006B9F1B160FF7E5570FA36DDBBD16971A165E6A550B1648DCD01BA4854FF7627FC35C95F2CAE53A742645C859A96AF248F6686201DD3AD31D783C093E8AF94F15B099EAF49A0DD4664A8767E0F618ADCE6394E09562AE39FB4A249852B00DE3A14B263DD7DC12617839FDFC57A7E219C638514BF6635B5D6D32379D15452302C9EB9EDFEF626FDF46110D10195B605EE6A78B5C772F57E91FFC73FF4DC0DB7461512D66D2B7BBBFA9B85D0B28F9FAE8FB979FEDCC59AFF493E1C3E03DD91FAAD36CA4B2430AFB342566379E49CD06591D70AA18C9880B121CDD802A5C37622175191C4497C11447ACB6390E604F9D026C9624D8A6E23292A4EE82F7D99AC1AE2C541D9380280F9FE484F4E996D9D39D471450DAD5BA51C0268AA0BBBAA02B06DEE0FB2E956E303AB1DBE5C221B69C5239EC35F95C0A723AB4CA76C4E0C57E6D559695DAEA5E7BD1070BCFC3D0968B7A2A2EC80B3E663421D47D9D5F0970D6651A62A1270D4B47B03AD4E1C3615F9593266849E6C0496CF40333AF199734051EBE1FC3B02B3B72F61872D0BC86E729DD73C81571421FC9C58DB88DCB0318A25B0112206B1BD2141435294CEC995B18A4FFB723C2F73327602656EB7C84D82266D1B288AB7D363497E009AACD7454F00052B96B0A6205A91CE542F6CA0C7C187001FB0EC8C917ABAADAED2C5DE369224B8F00EBADB8", - "k": "0CB1CD5F942305DFEEC6F10D2138621F61283C5A87EE1C5205D3BEC21D9E5489", - "m": "3D6441A62F1998E2B5B9B1E73A9A5022FD005778204977F66F7A5FCEAF17E30E", - "reason": "no modification" - }, - { - "tcId": 65, - "deferred": false, - "ek": "53EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD", - "dk": "76956EE8A1A973DBC0C7D40334A81B43D495168A6FBA8AB9A4392069096B598B99F1D0B9F0285DDB138DCBD1B0301ACAB6AA370C101EEDC17C748AA6B1F69A796AA6D20232AD98C64A4627EA98B3A595C0DCF558EFA42077B8BA2F29CEDF464E21858112E3A29EB327CABBA5FA33BDD1297E4224ABCADC68BD0B3AE7895FAEF1692BE2A79F95720D541245657C754330DFAC485CF3275D5C613FA74E99185AA8B38E21856C0995567DE346D2D9B8C691689A6A3442C0C2EE871D0D6B7D6D46C8C4C504CAE38EF7957886F70538803079F986AA945D0F0C25F1EA9C41FBB4D2C145460C39E4695A7A9560714A954647CEAEE703EC8B40AC38423C64A46E64196109C6776424007866AB06B85D73A267CB789A2A7EE4B827FF0ACEC846C4A31A01BBEB3EDDD7336C5BBB4575BF40365673DB24B4034F6AF1C0906C71AA3701ACAC8EC96114399B1CF3712FB1840C31A255477C2709D05C80981AC892B2275223007C8D84E9C4E9854F3A426819084EC2823714F47452B921B200834BD659758705BFF3CEE671756513A6562424EF1A1F21589CF321A9D790C846E768D3A022527937CB82309E95962643C2AF5A6422EBB2DEA1ACF32839A30993C3A604EA97A5AE000DB8F8144F414D7E86513E5CB0B0E2596C53C7851222CDC48C48224D4863A7B35C478A42285B8935B594970AA67B89323DA2B67B6A7A6A9FEA7B3BF648FA64067EBA6BAAD6BF640A44CDD896B68B125504C3DA5BB9DD552BA400618C453FE57683568CB2A8B86BC33B519885A06889981A87CE21D913D102AEB9A26E5474784F499914670AF5DC8613D9BBBB9A51CE708FFBC8A63F2A6E5DF6CB461A7F215A8CE2E472F1B813028C49E9E11777B3B1317ABF96513C1E349352FC2BFF7AB0995147CF46AAEBB71D18399F678CA8F72960C6C5052585027D180435551A3F8B44FCF06E6BC8B9D57A171601AE1EF3C21E7133C6C83C365C72B3C0A56EDCBB6B40695738C713D34C4BE6282896539EB261425C1572685C7026B4F56967F359A121FA031FF007772B5BB92B1167E25D706B99097A2F38ACAAC81C02748BCF02748DE17A8D2B857DC2474366CA0660328BA08CC6D52B3CD844B0B821AFF3B22F10294813702F7E24A78FE083BA1BB88EF55C11534524E059588A02EC83B652CCB4D55968E8B52F293B4E75BA1790E95701D850C8313EA5E77D62681156991B67146D1C1A6DC6E7004D2037C7C7AC48C80BD566A78EE811F3E0C7598948BF897A6F0AAB81001FB52B4974A3C1150BA5C9685D3A632E68BB9D4925882A48AA5B01AEE9A44DF574ABDECB7B1B3B755188804F74A9524231EC444300B4644BB56E6606523DE99ACC8A4CC6EB2D7A93C1847B5FE288CF19F96E86C49DAE2B39FD678C63844EB4A7C39A25895F338ADF1330ED92AFB2013EB1B5729BACBB36EA25B56B6C5C309021B74E96D037B14077F025830E8044EEA0BC36D1610B9741E1B5CDC9584469864CCBF413A2DAAA260C8FADD82702EA66B6C811CECA5BE4DCCE53DACEBBDA081A184C7A55371AAB3A53ECC2E9B82C27D743635C4240F5394ED05F5C265AE6A120249103D7E2443680C655F10D45050AEF210B9CD306465282A5A2C182089129E53C0B4C028F34761D19C4096A622EEAB6C5262338735FB1D28E1C50032DD31434E149E90CCD8123ADDBB0AD5B903FAD334F4EFAAA04376E225C17353B278CCAAB104C83A855941A1583D6938C5466A9D6C63AC98253338BB19AD8645B70C05F90744C96779FC9479384CA19D46AD43567799AA248CB3768F324D8320160712BFA9B781681AEC61675CE2230C1F02E59A1CE52836F3CC252A0D4B27B14C46B2A08A2D0C656B5449A390C90DB69B3571BED8A76A2E26E41E08C728B68A1B659E8E8466D96B653D132EAC36F2578338D2334DB7B237AF744FCC08013288C1FA9AA26D88E1E399549A323F41718C138A857EB5103A131578ABF0221520E2ABD914B8F993455F980B726597345942F4A319963E65A704B884FF02D01C76A0A3503020CAA99F6C5D8894FFA3917645BAF9AF793CD46577291216A4A415033C31E78AD8F8793E4E97048FAAC12887267C9C043BA1A5DE6C009E5C8A68026F6798479F45496A142CA031CF0A3C0F8FB1110C3C37148322897A6899895C125B385CCB153EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD1AE23027CC9C62AB641D0F46EB5F17471706A42AFC921B48AC0A39E50F560DC1502C2C1BF811FABD14733D6ABE45283CBB7292278166018EC48D33904703828D", - "c": "6070F979C45C39BC4191E7B6C735F278337E043F0DB0D24B7321A51391896F4A7D122CD14F98A2C0272C4D3FD039F029227B6D83BB800C7C6E09A7894B6CD86FD68A32F31CE3880EB9D4694C4551058BC58193AB13EAA62DF3DD14BB9606C29511E4AFC1E0566DA175D4AA45E428B241D6F3419710A8FDCCB0BB74792811570E0C24A29D034B83FFCF98755CF227AA3F8C80E9AF7370DC7A7705AD3808C3B33FF40EF131C879779F72722EA582E130D825B7912B3F6DBC5659D59088333C1883DD43B7FFF8F942D584F42352FE4A15AA8D3D0D5829884293A693585FD4763085541FF83BFDBB506DE54796D3641038410E4617E009042881A942311849CC789658BEC01554A4D6F9E5636E59A76C1733C40D90ED8B0763F16B8217684F484B9FE19E07A8947A3EF04C27645F300A664505ADD17015C2B1A319D414AAD10C638B1F37FCF61F81A80624CE7D75E2759E0B9942CE6251349DEB9EF56A5A4245D6B598046186D91240626F1F37AEE04704E7F6A14214A520603B7ED44CCADB8A2E39093718EAC9AEFDB96CA2822D8213F66655017BCBD465716DF13542B053FBF0D99018D4549E2D1B19735D6DB95041C0AF04A169183CE0A634BA114E90C30429984633097141E1BE19DF941F2FFD228E2C627F02798BBE3A886147CE23168E335590C1C3DD337E980CE4769AB187A2A6E855166646F91E14E3B97700753ABB6F811D474A412FCB951C2568EBA98EC9D2C51F08F3DB5D2EA797531D65A250579F98BEF2EC5FA1179C2DC6D9E27E66F983AD70AADB1F5067C104FE7B7A22F808F4C5AB71B881F2D6510EE85A0118C74DDCDDDC8DE8DC551D41BC14DF90294567AB06FD76FC87B92AF9AC0B456386C714D5773B500CF15596A4A71D8A6E23578AA9D89C596D67FD08A379868305148076106FDE47DAC20882E913BD2D397179D4E611E8CF25608AC3B50D12A7F7EEE1572B403387DE2D0EFDC35A3C8644BC3BD4DA9F1E2E1F2ED341CC1DFEE0E39416DCD6261AF74E84E0F6D33D91EB0DAECF19597BEABEA1B690514766F3C8EEE663923B3FD25D36401D33A39E5972B8B17A41D230374D7C1783B208545167243B31C32C9DAA330B3636A1305F96DD612990A5F1D7A4C407DCE61CF73F5BAF5C55B737D9152A5FDB19DC4969E9CB4B049318B88EF4AEF97DA536DFAF3BE6D3EE6D1F2E4C3F7E17963418CDA89C2A481237A6F2EC303F380595872F050D1569ACABEDA5A3219F8E7BB75CA77541395AC44EE9CEEBD1D4BF59507D77014F310CEBE3A322C8636DC450A279C54332F46C8205653556360B51B31E06BC1B5AC9FC9091859DFF301EA407E5AC051231F774C94E2E932A08CE22ADA65E4EF74D7A4BB1CB1947F5490E88D569BAFDFF756EC451494E4315FA25283BA63FF61BAE0E45C4582342CFF3F3B42E297B97C9E73E946151F8D29A47E57A6ABF45EFC5411B607DC160FAF7674665D0F0E5039ED8C7E59BE98FEBA7C81ED54DD51A4542E5CEE2712F25825B18177FB8E8BF4FE1657062F31B8D8090A9512CAF8876B09E97725CD36C9BA2738F1D4C863A7B99B27476812700D24F3576EF6007D2A26B79ACE6CDA9B291527C800F0D666B784A11BED29B8D8267D5A643E33F255B6693B129F38BEB976E4FE7AEEB0C78BDBD8D31326A155921236255B7FD029307B80CB002BE230DC3036F8AB7CA446BE34BF5A5F29E2D5A0DBAEFABABFF6DFDE4E400FE491F40C2861B0BFEEF44DCB14803C79E8FE79C7C3AE113E8FA0B2F507A3711B8C56ACD0B090935EF932E6004A36B9390260F3080C2DC75A61B69E758EA4D31F8142845218E1DDD85AB7579428258CB5C57286FE308D1BC164BFBD574246FE6F7ECD9BE6C91B24EDFEAE6F2BEF86B13780649AE57B1F7D764786FC4C7EDE4775C2461CBE37026BBE6BE5D8B0637239BE3A7F8B6E56E2B86478E9B5461F5040596B2207061BE9E7851DDBCD619DBFD7410B05A361FD25613BBCF5379D347E43DA571EE03EA19C8553B966E9FEAC579635241E82749F648A7935077163523D19B9936648EE5FE5CC902E66F4379156721A63824E97294D8FF0C4CA93D995F6C635E010937B8C94AF28BE078FC94E94F9DFF2E6747E2F0287BB6C756D8D3E1D1B0A736B92279F37861FBBFF8322C676472B44667815755EFD9BB4920AAFB689B7692892960E059D010AC883ACD8B5068C1EE9B87E82A4B637A006B", - "k": "12266ADDBCC27B282DC0566CCE7473F4D705D1DB4B3D82130AE29C3999C6A999", - "m": "637B7A1B57EB76C50417601EB71269E050008F415DF974C07BEF46CEFD08368E", - "reason": "no modification" - }, - { - "tcId": 66, - "deferred": false, - "ek": "51F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB57", - "dk": "2E78C01275512282C156828B65705F7163A682878F9E7C0762153C8E63012DB043810B705D9C3DC092C1427808D5C8BBD361A860C5260D36A3DEAA97A3D97771F7804B3B97CE43A4ACD7A54B3068E2727AAAC7C3F960AAE2880F8CF049898A6D90664024136967D18EA0FC6736EB0D20665DF0075BD9789E621158A4A20F036832E71C05D1B3218EF75EFAE05262A21C1A4A8A427350B0C128DF37C775D602732B21E5AB36674C0AF61655E28C56BBB9B1D6174749082F29D8177427A24E5597769758C2C4BCCADC32A618C57837BA8FDAA8B89B35AD8A2C72EC03F9707C0FA4C01A231976B0B15CB39438217C061CB54AFB40475911806952A42441E0F77918E7CBEA9639D1F1A2DB9C785EB5025307C1924862BB68C5FC652D2AA9AE043B31953393FFF3A2616B1DE4649088450617F548005A477C1897260046B60BC120764A25DC4D9E1285C48878D3738A3A47687CF36621267041982E50CB6311827E6D27278E6862C724007E75B35499838D9553D9C79196D84A7BB2B386790ECD7647D3A60BACE84C679AC3A0B212181A0478D72E4E50B7C10CC5A1B154970C0625111A4ED8CFB47209672B7597B16FE79786E8B571A32A7EC59BB71F745439C181FF23C26B96A5B10A41324B2F8021648CCB016BDB92D894CEEFEA1876A30DFDE22973DB8B70D7CBACF5B6B4B54CFB9B2522919007B6526C084B8F392326461F0BD6CA9966351BB45F2B77564D1723A0EAAF0A2AAB372B9C18FAAA21A00DD2F4570A367EB2EB4E3E719D1E72A164C4A8DE6609540B6E93F71759362C2A6C930385217821BA00D0BD41C059176086E61620187B6B7D448A34A8631B9913B2C3307E529D360749DE11571BF91866A098CCD29DBE9314A770C217356EC4A0CC3D98CA22EC85F9C3C4F3A065EC5C48AA9269A8E5482B9781E7A39B6FFB287FF730919535C5987034A32AD4101986BC9F17B2AEC906169E3C56DBB213D6FC4BFE48038B0C1E235C4E106C1616D95F75142CD02B18AF13B56CD45EB1C46E6F008234992385EB21A6A7C219021EF47B55F5301E60F9CE8FDB1E3BC56F4DA253F9799A160A077872AB7551013375A2C8B3B9AF70BB048C4389EB90CF31512E080AEC7673C7F23EADDA8BC17372C8BCAF100438B0167FE2737BDD54C9571CBDB843510D615198821A2AB16126D107507B5D31D4349C0A2E47D6044B6802700C9FBB5B3300A2B65D4C457578639696BE7336B618284D99514701CA0B3C6701B008CDE5A88908D813E2BCB86D032CB13B70D34A35D07567B6DCBFF3343DA4A9B7390CA1FBE195E384464D154FCB169AC35087C3013127835F3F98B996E9815DD4C14A6995ED766DCA79ACCAB324AC20184A93C616F53BFA722BC9FC55924048702820A423193A858E6E399470C3373F8B0FAE335A1694B96BC29B15B939F81312311B548BD819A8E9168B303E2F82AD8110531B8B21F00517A0483516C160E8229971CA293016B8A5828B83F87951B266523388A82458ACFCC98647B2043A2525EA8F5F0A66436AA8F0A2C736E8284C8257FA49475B2A54DB2C3A9B0BA5DB92C48088CB79572CB21B7CFCD8285B54600F75035A00AAA5B31AE4B201755BCF0E4B32A84588136C9D48B129837CBA057AB02BD34A3871BA824A286685B3598007E39B931886BC22944535F95A5E6C1E8A95B48E22A6541C1EC078903CD05DE9E43EF054661412629D860717A90F91685BC54B62A315348F4B8A74B672C19883BA58C854D349394B20FDBACC8AB0C0A8972DAF080759EC20C6677DD956A9A48B07A727ABB239382A2767FF2522E7217AD3A2AC6C13331799BB0BD39803598FC04921A1F90B7DDA2FDE2A2FBA4173C9D390FC31B6388684D6970BB4562A69688283EB6327D960DB19B308A9BEF87CBE30606C56F8306AB134E32ACECE27011F740004D473A6C1016C5C9F4ACB992933801DA80B379043845A3432B375EF670DE54C6AC7206BDF711B38F272DC916BEAEA6A370008845C792CC9C2F64BA10DB51ACBB18EE0EA99D028CDDE671F14FC00492BC43E282813A8B0BB13C3BFC0404F362A8A45012B77377B8CAEF7734E0C22C4BA4969F610482E47882B209C4201378611C88E9CAB82E5CA8BDA976F11803A11AD5B288C043B2B8891168E4C75F62678BCB05EA5B11FC66A2551F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB5777DEF69A903066F0C5A3F4CFAC6B7408862923728492E7E5FF26A83A48EBB8BAE5D9C71D76D5958744741B9FA4B7EB67799F54AA0717478C4BF0EA6E0B012AEE", - "c": "229B069FFA4848A699156C894955CD9BF623BD28ED0E2F34B8E1F62A1B3DD00A6AAD501DFA776604A874C5FF1E60C3FE89EC281DD320BA2C1EA16E99D147B0548710EE11CA2540DEAC882A7B63057400030EDE2E75BDA52622287D3680A2FA7DAA94FE289D1E3879E1039CE2B65C9407E7A49CB93E76B4B4BC1D247227F437696D816C08E401B2D82670E189AC9F6A33EBDB2C0B16C2E18C9009BADD550B1F533C265A3E0153C982D4D64B215B7CCABBEE4B644B1592A766C30B28963F0991EFCCB5A94D38B38813CF9998A362318AAD81CCD6A0251FE63DF879DA7B7CE4C9CC28E86211E97773D3AEC98E1931734CE8629BCC668C490426BA60CE2E28E2871DB69B9683CC6AACC4F588733A7ACED2F17EBEF11061251AA8745F147BF1DA650386F7CC637E9D02870C16E2F06164E694828BAA66610EE984B7C60D0BF82F8B6D79EAF56D75FE605B3CED809DFAFAE3F858632E3147C3BBAB8D931A3B00E90693E5B840A77277C9FBE86FEFB2BAF134AC21B8B47E3D0A009894028DD5645ECE152838290EA835944ACCD78CE3038E8A2DD991ECD66DA742FEEF94125E554BBE04F0E923EF1BB02381DDE16F1D41BEFC8C418A6818FEF891DC75ABF717DD84979FA47FA3280364444AA77D72C26E808EF6202BE04C4FBE4B26A5B8E60317AC1D6860F5E728CF316DA287B3DFA391AEA8AB4CABF0D88419CA2C4B461E8C4BC633F0F2A6AAB7A86179170DCA1DE6A2885983CB4C0BA34B1D2A53AB9751ED91C49DE832ED22BE9443B8C2732B32A9BC14889121E5B261946EDD759394474627A9D82F6962F76D67B94649788EE82FC81081F008F6DD183F27B69CA19A5CD1FCC962502E827183AE32DF8A369F1A6DC44075BED6CD3C909B161FA62CD67F2425DD1D86D8401F7ACD5A4D5CCB94B9E22E4D518A9EBCBC705ED3CE7068977E1F4D7DC12BC51717D00225DA24402BAFB56DA5B7C8580F53CF66CE8F960B1A58A40534D29014A73781323E520D60097B5BBC5492D87D9103F040BDACC7640DAB97E6127458153953E0624A26ADC8875225ED6FEC2876DBCEB536D01DF0001477E64DDC542898B6D502BAE3FD7B49049A1104A290107904CEA445A045EE1432E79D8B358C4F28E42DCB05A94D04B78069AFF8A0A2CF2AF94D9837C2EBEF85A914163EE1F10E411DCBD7805A1EA204468EEE5E6DD682E2C1C7E30E260DE3AAD4AF6F2C6FDFF083847962EDD0052F13F0B8F2E4659F8D00260F38EE0BDDD4D6953CA0BB7B055CF7FD160D19AE5C3A1967FA0AFB09D71AE4AB63FCA185DF32DEF74E786E050FAD63D789546AB7723B64EAB6BBAC9B0B0AC9D3C994A71A68BF5B378B4BA8336CD1D4725F3EFA23E4B9585D3006C42485312AD7EAFFF80CE82F7A82DE7864D9EDB3A569892ABDDAFDBE384225BE377A051B75F0F5FC99C291CEEA13A6D1C1E6F8C1C5E72A86016029761B3E2D024F33B7C5B91CB2481F7BE4986FB381A3B8E20F8FDD5A390572727541B4D4988337CE19014433BB47F31D1847AA0C4E28288B1707744F542383271B32D85B73E3857D89703BC80FA6695F617D6DCCC17147779B9A4522C955D443CAB3F61E3667B44C0FFCACC136C3A487CCC760F7952A28C2826A7F640BEB3B3712EC3DC52D75047B7D3ACBDB74F32B0139FFF1C2A66818EDABF1C3FAE5DDA87512C8ECF60C133D4B98A7D1E1C72DD8A487B0A2FD9F8AA59EA4941B9958A2025385636B9258F4188B8F1CA96C4FA50A34E326616ED2354364C892295D2AD5726E4FA077DCE9FD110A95823B5DC355664ECCB7543E987D9CF986453C5ADBD438F849C6578CE859842F90975365E3FD5D083A0442E7830D580F51819A04941EC9284B31FC457060A7A6EB91BA7A87C0A54F1F422C5F0B6D8D4323881DF5525B35CCF992C2E701534A213BD935D30684086BB916B44FD9D678EE8BA7578B9E427FA36C139F1FD92DACA7FC8DB85607DBBD3532DC24BA45B53A36180316DD4ED5FD4449034308F07A6571F9943E194A4200F6834557CE568712D41078024762C7D020274B6404B326996EBF2464E40B8D9842D0417890DA0BBA9013A97A9259FDEF545EF780FC0D501A0137E9AB22A1BDC96252BD5137C96697628E559B00C2AE813323F2B9A1E2616809AB59945647167AE2B2E757C21273FA0CB3FBEA7E4096DC1CC8F4F114B94F5D760D496C1BA8ECD6B1EC68AECE4C9A25D1C561", - "k": "EBEFAF52036034E249B29A1825226DBF469C492494E9C4F13BD1010B963E0D4C", - "m": "B5C84B4535CC622A5D6B93229BCE68789D3014D500D3263B6E0F54359D20ECE8", - "reason": "no modification" - }, - { - "tcId": 67, - "deferred": false, - "ek": "10971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E", - "dk": "57C613B806BEA20AC23E2CCCF3B36DD7AC5F84843F273C8D9923CB8770A34A63885973AD2E006B45437722151C3D0539D7723AD1682473C378C88670D646646473A18BDC30367C136874BDCCA49E5C42774ED96279CAAB1594777100706BABCBFD46652F42702CC00C810C2F753263551C44C928B6BD319F1C1444EB014DF1A874282B99CD11AE59413ADF4A3459F9A52592B1EC026977E9B26022A6DC059EAF38854D49C4F691A0E96A031D822907C664D3E6B263B35F3E967167F953D91A05A5AA0C4F5B5B288745695AAA2378420B6C0803D855C3D42A623A67B3376712B2B299E3B155134FDB582D0D221CEE318FAE1309A906728ECBADD9CC298BA245A8D4C081B7BDF87AB4E56C07DD98488F342BD405B3CB327FBDD85C80D2766E2485E3A351E0A3039AA60738858FBAF5BBF6D9CB25592E1D82468BC6B23E678BC5E4559F125F69B414E1AC5AD6B4498C9738328CCFC6BC4E7469CCBFE7AAAECA8A22874727A9194EF2BBD7564DB3D927D85A716A4551903944A642B5131511B619323CB620435B501580354BE09C3E46AB78BC25D08B29440B9984E75D75F263A081A562A2C96D538F6A037A6CE9C1B9A0021E0591F874AD08032BBD18A1C6621D597A47D4311AD0CB91E4DA1A03952BA7718187B86BC6E396CD716E539C2AEEC8285629A5A7B4596C6B4B5B5B272FBC00F12B49355C1AC73B5EC245C3B6E59F3C81C76E9675F51616D4608795A7BBFA3B0B96AA90FCF55BA7768CFF752FBBF3C0E2847EA939AA88D0C077A5C721DC1F09D2100DAC98B9F49848A7BF3028931C72451715789C11CEBAD69456131B70CBC27882C598311A0AC50CE188BD4A671197934EAB72B8842157F364ACCE67A4CE358A521895DA285331C412A20A88567B93623875949734D2665FB2A907E03A74D24531294C6FB1B45588AA61655977330C0F46F5CAF50466EF66AA89F8C15145A6903621BA269DA593CA28C5C439BBC2B0F74D3FC213F10029FF66CFA50AAB701048383A188EF7A8F40A7C73C19DB0C92248C95A3F061D53E3A3E9D76966C62C711B7DADD17ECA87B418B891527CCDD872B328C47B0F2798EEB90A9B46C75009523CECB196F5B941769F1167C4AC86249A09521DB9C005BBAE80B1925D01476E5C8ED2519F579CB46A01B1A618AB228342F06993E7252FDED96FEC54ABC11142FFCC6181F2071BF1B5C4A23EB782A0DD03078B1A9C5433C1E1306BBF4C388386814BF859C1070A033016DD599CD221A35DAC93739C9B97435013B6567EA18E8D60CD3F8186BCE420252027FC1C91CAF785135300CE525351A26E1281C05AB6BF9B0CC3AC01706A7B7B855719D7290BF16064D8136A2209A70DB24BC5F693AD385779A8CB144C80FA0435EC6C4EC9492015988634DC88BE46164255B9E78910299CC52174654F48B351B418636A2D41A474384562F9141F37985C343265A3788F7A53414A94A9F8982DE444BDFDBACEE37296FE2B669C307EC0584E975654C3209B082B4E9454B058D439C7CB7FB0D80F2CD77B330271F287A0F481995E26AC2ED0B572F04FE5C75E3B256FD5B2CF6A953EF0A85FC953A5DB971CDE68CCB2F5A804699DDE247D4C09B9AD34BBE2E7188D2C90D862AE1DF56FEA9A8639029CEF0B73C7352D1C94A29CFC28325AB1D14100A7F79AB087A8EAA749119B7F96E29B93293662C57533B47F66163D31BB3E4DF28BE89C48227C3FB2E3673EF858C7B11D37C2658ADA9DF048299EB883472637C774012A935B17C72987253F211C27BA97AB867A5D35C375158A637273993F68B4341A644405C013273C6C881E49D2AAC13C15213C9352D3C84EBA1951DA0394E19B660BC622696AEBF8841912B2B3347D9C8CA1D98565C4AC93A5255FD91B41A9A1BDF255C6C0860F05176D41F58CC8305D40F2622087133EE968165B1CDF41B4A14A7061710D9C00156296C4C428CE2E57163C0C77F2C9416E89905586C29D012111B07C475A79A9D227D9A531857A77B4017F0E800739980BD401503B472749ECA34816B76A22260DC120C986AD57861DFD2B2BE7D184F9B95AFA859392ACAD78016F18479BE83361568001F9187BC22C35A2A0BCE4AC7840354F3E9C43D711CC12E57E3FA2BACB6AC8B7993FC698B48574AEE7F6ADECA360233371F95240FF492210971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E94666B893AB96697ADA5692E4E959DE6DB5C00F2B2353E615C5704ECCDE45D38404AEA8B2BDAF3FCB7F4FAD5FAA16EBA8A4BC94618FE14508C39F39A66BC59DD", - "c": "2467AFABEC5F378284AB6501C7322603DA732D11497FAF4C59B2E858222844D4780B1F7B0777EF4B7F61DF0253584BE5C46638535FB39072286DB984DD3DE335282458ACD297A585B64DC354858A8167AC4F4E1D00CDFDDE658A6D217C9C1255442C66B1B6F74EB0529A54A8B07290A9E07D2F74B18345757E21894639A8267830E6B065FCF746F8D3DFBBD23878B76F8B606B1227BDA4F221D2CA559BE133DDF9343811A5E5B3B0DFA27B4F9E24D86B7E959A9FD83392EC4B616C39AD9DB1D96D465A509F92647E4149A9D38381457A3A45A393BE987886FC7E8CDC561341383E35FD80680FE7F2D39DF791681D3C6A7C74031788C1D92F1D731F4261E5E385D9BD8D23D37B1AEBF2611707A6CF7C55418FEAF01577A2E26A248E02AB9F7FEA4A79CE55A2E4A8733AD8B3DE19639588DB04A5D8EAB7A1BF139C2BC0028E30988E3F2C1331B65AFC026FF68C08D3111B8E919A380A7CF4EE02DBB48CF552221B6C55C1C7EC9435A44316A6A8C35C8CE1F36EF657CFF16BC06A4F42CCDA96082CCCF0F903E5F1870B5BBA2EE4A1CD2EA06BF782421C8FCC73B43AFBA339D4EBB0FCA2958473FAE663B62DAE9805D1E7B469EF0F121A3528B4BD07556635EB0D3A83C7D3F776264F3667FE41C5EFF8B1861377E1671E2BD552202CA3F26A98BBF7E2453C1910F686A2EE82221ED50AC18A8538E02B7C70BEDB0E60B42D894B232073B8A222C055A4DA8ED707DF8F63471C7E8773DF9D0B3A4F0CA2861B2B8DD74AA3F216003672E5B132890628C7F279AE70A509E7A744C285F08ACB6BBE7F75D6B5200A5530188F93BE1D4416FF46A9BEE9E77FCB9079E11B264471C9F6FE2AC6927D3FD860A18931ED80D6AF7424FE3C93289D7787EA6334854DF131046E40C8ABD10FBFF2D4D4507352A619F5BFFE9EFF570C59D4DDEF3A1443EC91725F4488521E8941646B7E040DB141AB414E90E38E97F04F7BA3523DAB892494E5F2AF8B46E84761079AB191AFCE3571086A3EDBF02654791FBFDCF604762B84AE98B4E23A4F8CE9471A720C9C4E3AAB26CCD831361887DE84637B275EBC41BB4D98D53670603242297254B8E2C240B62A29EAB940640B2625FDBE2ED8511D0C4F2E04507177AAA81DA30C7FBFF30F7A4F03A2876E5C91722AFEF4DCF7929B3A1055645A7DE5F96CB13A81F7FABE6717E86773CD031390D10A36CB9E2A1FAECE1F318619FB2AFEA3C4C985630DE1E2651DA675A4930AF07A5B64162B28D16E700E3B389E5F142ABE21FF972B40F8EF6DF51411685F350BB6EDE53054E93ECCECA9384770B45E206ED7829D59E90A7345128ED2D4C8FD74075B240C47787F8D8AD3CB3BBBCC796328E701510BF5999EFFCB75FCB30B23D4B8F25D607901A6A942D263E5D1F4103914BEE27C4342F34591F923CB81D893AE4F4FF0B8B23076240C8B034F31D69622A6068C9428CFBE4996C1259EAFBA0DBF2AC43FB876D11A5A6F7944DE18DB2BE640F812ED6BF68A6CD09925D2EA64D46CF6BB5D3DBCF5BBD42D932FA017411DADE4857C279C70DFC12BB3BBC9AC09E21A7D7337E666EC9E823C0A5B03423F3398B53B877299DAD9097F986FB11C8E6E4C9673A9D10AC9FA80A23A88A5DF3BB7E722BA0439845EA58082534D0D7BD495C62EC40A86BB39EDDBF508DB899E3CD037CE1B08286127B3E62034635A98C1DA1E03CC60E0C5962B83CCDB942A33442F6BCBFDA4A5746CE94BA762ED1768C974281EF1736346708E4CA4D3EA7B2AD6462E807D12C33A8786D1BB3D384A6D5A6A739661A553ACE176044F5BE194A3C34F5BD5F23D4A2741D79C2799F25C486B51BDB1216CAF00FCFD1B2C1864807D347784E1E6C268C1A44D2D1603F544C7FAC0D278FA3386BE2E67896B39C965FED7A965B48E3B41F53EAC185352305DCE69DBE5F3C2EA28A6A87F1D5F1F3D5414CB78CF3195DF57B4C002601C0080C86F0E2D48DDA703E5F6234FD2B630A3FD65F2788ACECB31DE9E218686875A610C25EEC894E4CCB1D8FB645C97827DFEA89EDE57713BAD1F3CAA3D6EBC177F7F3B8FBDC61689952202B5AF485E2931EA07C89A8FEB0D344F216E82C4036BCA0FE766162C804EF25DB55D0D69617166D4DC23933956E13EEEB85695683F74D7CE5E162A1C5A0ABDA10D4C2E9531B4A898E6575179EB571CAE7D5848B065893E8FFA721DB4BC3C8F7E767DCC80C346CC014223", - "k": "77A12A7C2BCCD4700A35BF559EB1B8062628C5F7D540F2FB50A99516A11F639D", - "m": "FCB46FB66E388182DF6149F60DBD0FCA88D1BB1A9866A2C97B84848531230B48", - "reason": "no modification" - }, - { - "tcId": 68, - "deferred": false, - "ek": "54B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F", - "dk": "BD706C3D795690598DD0B25656791B6B6B40262B01474B55119796CFB2642E827DEB6C21F8E8A9E8B10C78156963C1A81D66580F061DF187A7C19984CE9ABA8C598EA109C7EC0173CBEB9DC3594F87772DF044AFD5312345F499ED502E5D42C5ED280BC35B1F9B79C86E00A9DF6422B5C8CFC455544EFC91542ABC594C7240747ADAF429A9B7C1F0F8BD7530B1ECD1CE98541EFA4032BA23CAA16B723524A5D9223CC1FC954F56B2BCA820E0E50F30696ABD11AC5359615A17815A155F7C27C84B0A85B649C8E3C75C8003A9541A77EDCB2FE00376EE25A0FEC314D6B3057D21335D52607504B278D5A05AE4C653458525393149401E1B2751FCF09831831A20899A115BB0D5585E64F42AEDE11A31271FFAD587C8B6117B346BDE545B88311349DCC89B39664939AF3925A289353FC5F48B37F547A6BB2CFD1A1B1A1C245D74078E0C8CE9172D4F853DCB35B5CAE79B26C607F25530B9500D1E645904E4047424309380C3332B0001B11A9CBA8BEF28161995411503610773A801492AB47C4AD32A08D9D621C08B553EC2AF4010CF0B8B6D894B86B4E8032C535FA39B0053218515C6B27E807C73EC2B966601FA976367005FA0183340534063D6CBDDD46287AA78205B5738D49426F0A5E87440FB01B70EBA2EF522743A65AB88736C1144093B76A1317849A5C9CAD9119FE6E5A8CBA27E0AD9B1AD6C3EE7238B386B7DB24872DBF09C6FB3485C58669BDC4264C5CBEF94200DDA8635B0AE23455F156135C9BA68DC675FECF3568D100BF022CA70F09AF609262B1636006644799038E5903D39688BEF9364E6482EBE347EFA71231CA1B08D0B2F83E5302F205AFF055DCBDC4B309933D5C737B35806DB19A3CC62A63AF56652833A67174196261A091918C933C21CAB913BE2965E760EAB34AEBB1B756F028A4DA7B0B6C20C43CC47BBE837A74AA5B42180B31333A2E6887C1616292C9C2855200006C34EC21C4BF3139DB74C1F06686BF88233B25B6C59A332372FB86A45568A120306428580BF72E082886C240A1980EB027F61560BCC1906DAEC1D48583B4AE85366840CBAD733E5AB2DC5044C9500A1ECD7B1060CB870A705F73618F0DB015A4BA33CB57ADC33A825FB3761F0758B7B7DBE5C4377020C8FF30750E53CA05C6F2E2704F4149267EAA355F2878A89C8E7394268437A807BB29A839FB2173D85102C8F06BC91B3679905200D581CFBE69C9BE25A53641D4619C12AB887E618B2798570C61108884C7AA22A3727A08EB5653F9E869678CA049C55389B9A235D27195DA868BC82C3A572B8CB878C96EC0FC0A07511923A23069C26CBAB2B879F40C081E55772E9A9A8BA826719185D627342A0411901C6396E0A086946A271B64750B32673266975A124ECEA8F3FE66115F543C9FA7D64064EFDFB368038918F5773344A2D01B288E80321EA67BC9FF7614A8BCF3C92A77040B316E66619A68D000CB60B543DC3953C3F92BD14516560833273542B3C1ACD85A49FAA4AB1C9474D8F203B8D49C66005364AEA0214444C779AC700F8878C15914D0A8CD2DB8C19F3943DFA17707C268381CC8BA02195B689B9362C5DB137BDE853A97976CAD043E7455A1CE2A86DA7701B884BFB937C6444150C68147DC0494B0B369D82181FDB90F8949AE3FC5283DB35504006F46C6EFCF08FF60330B720826722B945E3233A14CDD11AC888F3A561E767F6F48C2EC92DBC76489EB516C6226E063C08E6208228CC14940455E9C3700883BD6158074821CAA410A9AA6C3DB41A1E02367163E761260A8C1205B28429B53A6408DB144EEEE9BAC587521D725529A75C8EF83F2A4BC9F91258443CA265ABB54DA06114541F4B1B385D677C33B473BC0045A64078F84C977A3BC73DB8B30643B3CEBB073F0B2C0CCC8E7CB98F94242F50598447A84CDA593396490CF74071256B0F5EFC0A2EE9732E611F07487A839261A0677219838BEDFC5CC932601B500340777F0C7A92AC18596438C04EA82783EC3F119B8BCA09A4BE77748E9C83FEFC3B582110415C6AB5C76EC830929185172B325D9439CD96AB463D3021435306AC72BF476A70BF96A486537BBB87467B0329E855B5B1E7CDCD405EAA3C63E179277A959E5858AAC275964CF9569FB22F18C5C175930406B9CB89085D9230309030A554B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F068034A9F16D0024CC9BB412EA9C778DE819A4CB27EBE5614C8994C9F2DDE25A96672A036E27BA0C2A7ECD385E3F4381DEAF2BB1EC0F30A8AC7B01F0A15A0716", - "c": "F0E6EFFC0E4FFDDEF79E12EAD79C5CCA3416B4F5E251DBE96E14A1E5865FD41C3A45900AE13534BAE5D95CDF84A02CB66143A44B86ED2E535FA1F0787F0C3E3B9736CC02D88A169D698C3ECCACCC4E2569F06A470CE0D012CF2920F9F04BF96C80CFCB0686B0CF93F01F28DD66ACD772A68B978DA2BD77E9C65178FE8FFE23509E440030ABA284F4C94DFFDDB2393FF8EA554AB99D568ADE6DD18B3240EB792F004216F3B528A4BF3B6DBDDE1F19F51498AB876CF9492D93CFCD060BA476E91B12845FE7BB290E42841B7FDF4056765A6460FDF4047B8DA73269511D748A27EFB971A9AE4233555EFC77F826F0C0BD3E3AC9BD2ACA40C7CEE537BFB288CFE14788366C04D9B2460775774268EFA0C3C73B5B60675750D65362D97C43341B6B559EFD27AADE3CD256BF89487DFB9BD467E3E3CDB7C06539CD20F314EB2E0582C1C46FAA5E8E6918EE28B2DF21AE24397DDB1FF70AAC4B7C861876B2A9034DCABC05CC4768494C77F3436D7F2D6CA8EA7CDDCA32D11BC22DC59049873EFB2A113AC61610C8833665ECCF7AD30936673371B0F9B561833AB5B76B2BA0FE402394C57692F900F01842BE61C45AFEDFB88194626E533BED9C9EE00CAAC2400FE98B66A9EEAC83CB7A337CC7731E90FFF9AF002B92DDAAB612A657F62B422C233CB019939EA79C434F71809DCFF197149C08D76EEC52EE00CE5AEAACC68ACF75373F20EF63F6195B1D550836E847F14FBBD48ABE5BC70698C46FC8C05856398686E249FA189B11423F4663092C74AA8CCD080FB100FB89060AF9813CE8E1EEFDEA21EA1A849DFA066200498F99BD3FBF4D57BBC992C5C8BB0918DB64B59DED4F5DFAF5DE70B9491E33AAEEFAEAC4E56F9D038CF2CE7A706A290E4CF9996387C789E0C133D5E1ECDDE5452548FAB8243BD5344EB3EDEF93465A53693EFCC664E0A845135C35E8702FC692CF64A7F8DBE02397C514B9918AB946F83C557CC85E70B258767E0FFAB91D4A1377AA7FFCAA5E1A43D07D1AD9649368F0A40E0E0EFDB16F68042DEFE20A75CDDE570B54895A03BAC59789BFA49633DA8E1B50552904650727C0799AE441E1499C6FDBA71FC0D362535EF708C8B9268D2C9962E777AB94F6A6390EEA9E296D46CE376EB295FE0B1E8E8FBC1B9ED154E32BA81F83EEB4BED921102E284D671961FE849E7EE7DB54B4972A6BD65022B8F5C3324AED5B177D6699D64C0D12462E35B0A00D66655DCEF462C7EC070E8D402B33AC617D8276CE022FB9550A6E4BB320DF06E903E7F5081CA65D644997454CD2EE845DB85746E91B9CEEF823D60665B930285B9D13B8120474F1E0C25D4ADAA3C9DD1AA33B34DA066C8527CCCB844284D4DE9A8F7E01CA702802C49FDE099442BD010224F83BA5FE71CA01EA4CBCAF4B01AA4E128B86E8D1478A4E06D8A107FB36C5FD6A73CD92E3CBE4FF1C18E972A552E9E733536E97F6B609336E3BFEACB0CF89D7D110D4A422500BA6A80EB169FECB4AF0C3AFC9B8BEF2EB150BB23B362FDB5E097CC75A17E25673DB42E434D7C0D331F8469456BF01F5A40DF00A7B07D955A8F47241B9359C8444DA41764C6F6B90D1BCCA4BA61FE386E63F4B51FF2A6E4242620463FD4011EEE199F748A572284F817521CB59B7EC568F9EE259257E77ED1B3A209B3B9E0C92FC96BEA77B0494D1004F84D299DF67A8E37668C98672A3F896A82D7C4D05A8E78EC412912085B3A63511FB1275EE70A28ACA0B879D43100DF07D43E9AE5D68224BD7A29658C1342F0D5C920B4914CEE39B0CEB3FC10E5E2D76789795D1C136E82E94E7951B370C3E3C41A8811C789D74DE1F888AE9C36AF369596F9FFB654A707B5416B2BAB90D52A4D4958CA9F389D1C46E4574848D2BD9132DCEB5A1B71BCDB5AECD627333358B0F311F6A5356161D6E78F6AEA499FF4378FDFEBF2105210D3E48FE5DC992362A9347A02CF032A568B6337BCC71C40A4AB4D64860BE0CE0E336E97E18063AEA8133C77B2B53BF9E9DF7CBDD146821E0CD1A1BEA0C73BD25D30DBFC994FFE911EC1CEC3524DBF480E9908439E00DEE4E3765DDF0C5459858E4EB68A0570B2EB6F8C1D90DA25215B10F2F5AC9053C243019524B82CA9AB0E184BCBACB131622582BEE592837EDB94FEE88B4AF8668714D8A7AA30C47A90CC0EFB1C421000FA6D2BA54741B238193E86CBFE4F7956B00F2A857417F95C50D69C0EB", - "k": "80376EC749550B531BC5CB538F78FAB38342C7DCD74B83FD83CD058227B9B3BD", - "m": "4CED177C0A454052BCBD682B39BEA31D0D219A73184BC00C100964C25BD106D3", - "reason": "no modification" - }, - { - "tcId": 69, - "deferred": false, - "ek": "C701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E98345", - "dk": "5C9509C7986A2EB53A2BA32392CB6D1C103793B5A8D2938E635B3BC1124B730B63B4A061DAABCD2257C733AA010357376D631178D231E30037625BC6CC9192E6678D815353E6E10519586385F6224526A3662687284AC3734C7A4B5C16FA2B81D9568CDAC1CCE8A01F9BA991D2C2693A2569A9C47E378C591CBA78870449A977C11E8B8117731F815ACA82365D709C2C5E532CB6FAA33D9C0D36551B07C8172AD48D424C818F47C1CEE1B0AC0C80565A2D9D397129557DD2C0372A898A79F5ABAF4B07400C359CDC7A67844AA7530F3ED4A8E9AA9FECE383B37A365FD6A6A980196C4B3AC7A6B511671769A9888267514E01A45A8125264781C9C1B7A7F4143359217A455A6A2A00E1C38FCB174BBBD1729270661752BF56B53AB9D1766D3CCB1F6A537FE37E6C30329FC1C5B2E62BBAE28AF9310E5F773FCE940FBE9C6A0FA302126A98BC87BA830B77B81154BC525FDE8209585B95E810384BEBB6156A6A77771F74392F2592557F4C8556D8689C2B56EDE29E0821304D9255E063C7B972C6DACC860930915411CBC1EA62E11B45072091E7F24333613698F842D5374513A69966A61842509ACCA0445C51366F7AC7CEB0B6681116C8F4BA4AAA256E8C6909CC596F167F9FB1AEB7533DC1F2149EB14A8F6531D3F36CC6A339FD3A711B94067BC4BBA63100385396192216741C8AE5FB955B7B4E80A23049603B7EA2CA0BB2A79800CF533B50F133B345C2344061AF6EDCA4614299701040C31128D99C1B851497A9BC843F537F7D31A16B65490EB1158EC29E4F88B722D76AC1F58C05F3B4E0F6CD9FD69FA86898727AA9E799957BF4B4893A67B624C285E2A99378823AD60AF5D2287BC703A0E377F84539A19C1B13BB5B6199A355728F6B313931B566FC54C592410E81A7506E60BDF4525BCE9C73CDF7C58DAA7880D8AD628A51450606FD0325F0CA3D75CCBCAB41AD7D80391147A57201D0A9FA06DBD13870E4051B297753A8075C3B2C5404C9DA6A20FB12CF45AA745C05A219D21DEE1793AFE144221BB2FFDCABA47CB6BB4B0F3C25AFA5938F5FB566A28601D6783488E2671DF06115C125C0D93AC13A8CA4ACA2404727F6D13194C563B602668D886FC45B3AA8FA357A19BBC06CBAA109B9A47B01D814CA8CCB2815C8AD8F466A936C0659234888B8C55F71C75792896CD9C8E8641F548225B7C7AD388A5CDFF705DF37A1F2901749C48791E62CDC5076E394BA15B26AEF1A38434564088B0D741C11970931CB8C75EEE092A71571F4409F76192C64971F8F395F69DA9F3582A8E9B64B8629743E3B94117B0DA2EBB7BE522697663E9BE12515659AB8811539D22933B7BDA0400883982B430430B1E261A25734D0D990BA819F2C59584FD29EF2FC10F95B05E7C7A73B66C4F6984153C45030F99A1E9A378028A17961465C1C3146A0AE7096300CF966D4320356C3CC1079A53DF829DEA5A711A683AF708968C4811A8725A0397C332B0344537F4E2391AB9BA656075251C216435894DFD97F8F0B63E3E5B48DFA8852C43A30D67475E64F32B9952DC6732E165D1D854A00B72B7D8A44AF57621C7B7FB6B17D8ED597CF825242778A4F5A03AB305EAB2BB9ED27C504816A05C2B2B13A9E41C233AF420FE7BC6E7202B850A24C861C1B0196B8B4C87F2986063C04CB90F56CD3207B93229E197150FD8BAB314C8D71892FA633001F5469F3AAAF694B051F7A1362C3C6D3485077A12DB0052907C493BC6109CE627CF2F953AAD71F654A9167B05D708789EC0100DDD4421237C6814073A5B10E3D1001D18B69A57815D203ADDA9610A7232EEC6C33763B86C4F777F2D7392CCCCF8D6C4297C1111020B11C8258D9B61B26D50E3142A94A6B50C0AB51607B43F6147DC6D45BD1E64A1AA25F2309BA2C525489A75BDF5848D80B6F3087735D55246D9723D3B7CCA2848536F7CECFE6B0FD031B0AD538EBF091B4F674AC53BE78F1A00E2AAE18B537CFDA0CDE143ED8D7217763C6CA2C052775298FD1662913859A1276DD1B2305D3469EE39164D568C1904D89B66CA4366FA3907CCE699D9AA12F36719BC4CA47800B765D392D0AEC702F452EE411271BF945FF58B5E68C7197AA4882F8A5C7C4C11C4A1BB3AC39205775298A9A1A4B677322413187CAFE99C178AC181F0446F9875FC701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E983458E7830EA58B9A79ECA86EC2D5F5589D9A7F30FC06A0E33AFC44CE2717FA011A531E55E9C652B7C9456926E3A720B75ED2D4028057F31ED51E22D1C75FC29DB2E", - "c": "34BCAF3DBA6667162E71A484F74C056A37DB223C1F9FE03CC4246BD9B1542C6AAA6B8C21FBA518633B8824D3ECDFEE9F5981C4E75F0CCEF4E957EDC63BD1A49E5D599A01C5B60D2391D280CEA34637692B80083AF030424DAA91D95A2E10D372B827A0A7214CC74CCD91B9EA4E85D4919CEE6BD08BDC8303317157E3D95D0A94F486F595E64D246EF015A3E2780854B09C9E1C077FAF641DE76218986FE7CF6C8C94C37252C5315C1B1CC9434F286789FD159A6993FB75F3936D4C04602C1EEF033F4E95E412EE772DEBBF4872600981D4B45749AFE498763D11541177031232D4F14143B6053ACEC654F2C9906896E79DC5A5AB57402923BDFDCED57FA49E8CA155EF37012F78B5353484C006980D90DA581410857C152F2E1DEA213B8C28A6DDDED12A782E23858F204CC1BDC84BED3C05F93EF03911342CA7AA280EE850749EDC1A3F5F998505014A824B63BC67D68BCAACFB6511D4BF2EB1ABA077899912540D78426AF13CC0888BCC7807E932445E30F72DABD6E35B8C04D454B4FCEF1E6BD17CD53EF04B363942C1361959AA7305D5F68844C3271146DADF8C588B470217CC10778FEA4AE93A5C5D5B5925AFA212E25A4CC34A8CE84D56DC476297B512EC89BD7DC67FC109B829BF101648D9B7F6494817AFDED31D85F68E5E98F717A2F0D1B6554066DF76713ACB17A1520127223E5E4B59B030EE714C1A9D3A7C4D08B928DCCFF1B53BA776B250DF9CFE6CE299F2AF835D78E62BD3BEC8FCE068858AB1D31C4F371291D54EE4FD87E6936299DB9051884155AA8F7C9A9EAB177E33787FBBA8C5026CE8FE935A5A7944BC6E48352E61314888F7A7EC5F08894829A88A4C955FB4E8D8DDFE4193CCA985A4FE6F6E16815BC524B0CDA186CECC4B6CA23A11330E9E2B9982EB6D3E24B36FDA826633E4D36318B8BDFE6628ADD238BEB63325EFA3F27F93BE9287E1AC9E3FDB6A5B39729961173E65D21F5A51373CC63F24F710064A177290613A172FAD51D607BA075805976F65331F5197307A30F12DBA0824DAE229394757EB5593E1AD31D98E45E7E6B864F7FC1ED00F85891C65C91C9E76A1E5B336D8E3AEA8DB52AF3A36ACD0E64EB877D19887E0B803DCCA831E58F6194F0FC651342A49860803240BC32FB8751FB3F513F43352DBCEBE6DAA56A3DC457F705BEE993BB325A9CDAF929C513BBD9194F4379BF8350F8AD81BC11D3CEFD110AD315E6402F6D01AC5B2B8DA5D0E78832AAE47D1836400B681229A363E184BCD5E45BC8A3F1F3C38FBF7D84C493BC712E1BFC80CDE8C15E53DE6EF27F10D68500EE9D3709E059B8A6BA91589B5F8DBD6E62E127C36BF3C97007E2E7E1A97E45C1ADC60D1B97F8348CB5D88C3592C375B4AEE18648DC8648CE3305E2D055ED01C3830D9E329C76E13E4616FFDCD6773B31BC5502BF35C5BC81193FF0873A77644CAE2AEDAD246925F4CFDF567F6853D45BF1485E8DA3DDB049F39A0CAFC67EBE2D155F41B9B938B0B22B082FB6D2336CAE45E17BBDCDA5E87AE0CF5C8E80F2757A40005DB5071475A183A200EE0563AA483B29DBC58F49C3C322F999E00D185204E448A838E9C63C85777D76B1057F08D552112B636A4E0F0EDB123997B062F1DD1CC79F8ED186A2C6F4DC8B2F1F1A2BD490623CDC7DC7AFBB5CD23708BB45F52C716E5490EDD2BADFE24B77F138C466A6DBA515485FAADBCE9413B6CDE0E7D997B9BEA49023867323B57FB8BF795F272883FB3F3A0D21BF74229158ABE822F1018B5AFDB650CF012D2251F0A4E5BC1974ADE394D77E0E4116B2A11ACA9618B000EFBCEFEB7D4FDE9738C75A05E14461B6064FD5399D260EBCB7B89D2C0D1589C1324259C37ED7C2224A6CF7350849B401D2A6AC909AE433DE8C7ABF0199ED44ED2B569221815455088611AA6C88FCAE75DE832E390CBB9CA075F07C31FE72B9C7CA88EBB6D446B60644CE9BC62DDA18F5C2C95EE2BD4955EF8CB50FA4157396CB156314110B531BC209EF90AC16608A2E080618BBE9BCE24A3900131EE334CC106AF9A1C41E9DC33151EEE2E980A45E7EAA649369585C9FC52CC614C8226F8AB2768285C320BE1FB6E18CC66CD160C66AA2098A3BA33F036FE1C743274F5D9029A8C8F0BEF6834A9F4BA6C0E26DB903DED5519F566B02FD32CDA1624BDE365191738C9C98CB0687CB138DC3F8833948A2090F0F55FA68F186D711D26F1", - "k": "E941F064338BCC6AC1F7679881709DDEBD2A94AAF087EA9FB5021838DACC8E72", - "m": "F594FE1E810814496BC73A1523FA1E0FF207AD5F5F0FD4B232C25EB9F6EB5B1C", - "reason": "no modification" - }, - { - "tcId": 70, - "deferred": false, - "ek": "24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F", - "dk": "A3254A747B57C2065E22233D7D2C1F9CD32B8586CD2FD5A2C1FBA0BF976ED7FB3A36B6710662B9A5AC6DC7AA11D581A0B6E36307E76C9C14128129C30322375381688A6C4A01137018557DCA3184B26091B91AB05241A4A080C813B20686596A5CA8C29188B2F005378E41055DD24D0544C624813A527CC25EB546B30B004B054438E333E5B5C467E08094EC07EBD25758B57FFCF9A958AB343B08BC248B0721A8C17DFC019DA719C4037DAE956F22C41711910513C79F7668B075BBBAA5307AE8131E2184C4164C17BE098E9C9755FCA53C0C781D7889544731A3F24C986C517C43156FFBD35328BACFF1DC436EAC6CB1F92F05231BAEE052D060AFC2C298B5C2877CA8B6BE22C3BA9C3348368DEC30AC7B05A58DA06A6CD1B47B32B709704679839DD873239A8A76F3CB8DABB621AF84BEE644A3C9C348A2B071ADAB3BE40973CD01958778600325CB70B486A7C84A0BD577B313328F792A284B5E1CA4B17F476F24C75C3FC325C07508E4EB9EEDAB0D321B2603582F765C481BF908E0CB574925046C50196A59B35AA282EF1936FE574016E4017F8A9E90E49D20F9279E262CF332CFC0E45E34E22FE460091DEC6DE5EC3A6DE702051284BC234E250B7A63D282215A27DD036149E412DC2C58D8E42E2F8A3C680C9A88B73C8603A53D08509849B379C5A3A6EA6B910539BF420510A833EC6527036139029AADD250A095B56C96A25DAEA70EE8B737366A1A6786769B78C874CA377B652C2BBC93276785D0893A196316F6DBA1248BAB288086D783811A2C1FBB7685B979822306C6B2CCC736562AEF3A19B5A364DD472442B37BC7A363CEC9073872BB4E65667B794A2CCAA319F6C437D2A4EC4A73F0FC5CC3D485837778A3C880005A5FE8890BB42BC88D070E5D7788CED8BFAFB28A07294C81F911A9700A38A880B0A85A97D2A08EA3B0FCBB69BE19A6D330B9AE492D8F3174F83BC22A3A98147621651CADCEEBB3A2D3B18954121D82183A7B465B034454E5390C191BBC063BE47B3DB5381FA2C6862BFC8D34226471E90C45E38EF602511BD4BA1807B95CB72930C537C99B0C1864267FBB206A66A836293F4775416521C175424191CA749A251549F6155EC8883890161BD09EDEA361C3F3CA3C086AAD70A3012C2C196366209264FAC4076E977408A91FDCEB60B8FC01F6B1C1F44C65AE14C3AC366D46F24333B567A9503C8AB0C0B2CC9BDA25400DFA0632058DBDB40309F91CDB42ABD76B82CD5248AE982C994119E08A524D5506395BAE3CBA8EFEA758973C8B87C8B132D12B32A29C75F94A44350413D38F426A57A6609C9D50B1CCC41183BB35CDE7026295777B5A0A5E29765BF80F319C8C7BC9BABF8102E798BF92F923BBD71DE01A28FDD3A0EFC27C52C30B5E7157E90C3E3F3019FA128FDC6934B5E773BEA3935CBB79BEB360B2841D6BD317757805F6E4CBE61012011BCE8E60CF0505A607E757AA96ABD0C75F15A948B45A56A137AB28BB3795FB7192C3501D060E4EE642F9A26AD661490982857E49280D99196899A70DC63926F41A9BC8A5BCA13B3CCA3B2A3998083A9BEFE93CD41A800AD6252D9993716B7AEBE46FB003C850EB86CD045FF963A528558353903FB0A62552C0818A43370EF32CA5E4045EB13035A1793AE75852229825ABBABB591DB2F1CDBED76DB7E5CB74086FA9A6A803D8B0D23B9BAFB112B029721AB70974E6A17757413FE363CDC040CB789562326302F509F317CEC82B489560B2C83C5E3E214579CC76A9140FD9975176B97A8E086E4CF46989C024A16067155971704130D4743BEF8A9E4E63B196142C2F46CCC5FC41FA2009AC1BC25B8A67DDB03982A161F5544AAB7CA22DA70E7CBA515AE7AB46185AF4473E04B593333799C9E31C91CA9CF85187D2D76FBA1B6086B6499C5CC614636CFEDB3A2C226AA0851AA7182D4C4296A2825A83ACA2B0C38E5538B5C7F42A36FC2102F6BDDB5870CA9B1EFD1942861C038B88122FA9929BAAC480B5C9AC6964A8DA9D59ABB52D69A8A5897EF745CB31E5891A1867674BA526A3B79C9405924B00896A97A83394DE4C4539E1B877822BF35968C09188B81ACA2852335AF8A711493E6FD843B7863EC61013B9401AD1B860B6B555AE394A11601518D45C7F089EA746A7852A0D72F2699DD98D24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F38849E1BC23427C122859A98B41D65FC5EACBF4FD851681FEA0ED777FAFFB534B49335D1DEC43FE7888BDDD29CD891FC632616E3B4107E091ADAE014BF7F473A", - "c": "6FC99751A98DB6AE5A504A1E4D3D37A91E7FC63F2D3457F3EACA0BF1045668E13D39B5F93F5EDE0CA55A0F5FBB90CFFEFE9292D8B723235CD6E2C7E92AB086852CCFC31D674BC95FEFD2505DD650FC3EFD43ED787A5BBE009B33E7BC2C47C1377C874796F0A01B9E3F4028C797932E39819EC4B3EDCDDF25EDE63EFBA53935BB421F0C63C1AC1BD0E879DD0B3A47B5A35A5F215158A35A22151EE86AB2C3E9F5CDC387FABE327FC38D0943F1F0D9891BE86F1D8F78D1C29C7700CEFB35FA629CF8120798D9FB27E3882E948C7B3BC08D09527BBE1F4D9D88F3336316FE93FD91D00A9A53F17AEC68E2AD8B335F18330ED608857C3996D111776F9B29855E75F59FAA9ACAB79CDEFA617AE017C0EB7F797206BDA76E1F01AE4C83D24A1166B68A7DDCD3B7B2A1C6D0A470D7120A273758BD4A078F1D851C9EF50C846B246213948F273B045185965028EF8B02AC189135BA3B83904EC978998F1F8A55303057F985BA26A85FA467C4E620C4742A36BE7250ADB5A937CC9355FCDEBB045DA27369DCABDE4ED33CA66906AB0BAD8C6310507BA241F54F37BD6F778DFAAF9B7530574B526D742D74DC1CE917843E27533E014C3A8348D9EF56768829BA4A03FA2A215DBF2C45E2FE06ABC268E6D335EAC3C584B6F221414955EE02BA70996CB27AFAD316D18D90BAAB3DED3C5CE0EF31F3B4155977381E5C76A106CC7BC934B4EA92142E18837930842DFD225FE0E57D32DB7C079C26DCC936C7A526E3A117202E0A29304899D08EF478BAF0A2413AA5D41F5758B22597B11E5A24659C514DB176E7448CED43D5087665E48FA2CBEBD8F300168BEC904E1DC1A39ABBB4558DE1F31725DB46DBD6C847D4BA1E260651473553002688FBE3DCF05ACBDAB5B0EA28DA9D83D6EA5EECA8862799DE09B42AAB2641E84A158240C495EBD6A527DC3840D099EE019F919E9667904D22B6A73EBBE5D5B1A781B9D480FE9915905722358DF0268E1BF3362FEC849C5883C4A34A707CF2C02E4CDA03CA8904659B933ADD46A81171F7155C7275C6035B2B572CDEF3599E5B4779E606F5FA757411BC97D9B46806AE144920B29213D2C887CBD79121D091FCC02B1D922B11D05583F1C8DB8C1CF4092667784BF4B766DD263A5832FBA3EFE2297224E01581AF372511D1C6FBA61D933D36DDC2FC845694B67D34F11F95B8CCD626463F58918D6A99C5D06F502518939C9AB9187F1BA2C1FBF9541B4AC2D9181495B0FE2A3741B556600CCE8B78CA02AD412B62856D7F588F6C49B08EE4E304D145FED15E2212FF167FA48E1D75883504C5CCDB4F4F2BBC3798DC2BFD9A74D747E9C8755127E73EA344FFC110F88164605A1813A8BF1EA4C0EDE38592CBC857A976FC07E64C149705EABA7EA02D8BBC3340AB38C4196FE28DBFAC25FC1A7A8C9E096D8FA5BAFC110862B47282472B8C731A45A7A7EC3BC19ABBC35077824B05FF19B9831D4BBEA9B34F8B28D50E3451D9DCF9B05E0C2330BB78C30A71F774760116894444B37B0FF1E36ABA0D0375DCEE290CF46219DB7D5110D4E51A217C0456227FD342CE67A922935005B3C7D1785FA79C608C149050373097258AA5B36D187B23DC602A970ED7CE5D36CB1AD10970C19AF67AF01BBFCC620D9BFC9C7DD355F274B6D2B585B730CE9449F697A51208FC742261780FBB178AB667FAEDE8422F734FE341DCF8D635DC7F2804735286F83EBB7CFB482685064BDA42E825120CF078F487B76D69402A74D6D4149922EFE4A8FC0837D8FADB1225A54434EBA471D0FE90DB55A3252B902BAAE0D3569F35055F1EDD9F0AA2AEC8DB9D1AE8A5F2D9D6B51D6FA65DEC58308274628EA66CC199CB209372EFD70D1B1DFBFDDED0B3F60F83C069A2E26B0A38F7DE67209E8BCD09FFC17B48FA95CB02D686CCC0E419D9ADCBCF5154CD18BF8F5D13A6FBF083A018F66D9BF28B84CBE9A1C3902BD55C8EAC8D72C8E7B11828D3F9B1794FCB3E6A50F498901DEAE1381E7F10A30244C94EA9F2471A1500772B3ACD0869F00FFFDAC3CB2E8F69385C60D7E8013B3C7D2C358DE712F3F34598A7D1623E6C68373C30F7EE7666FC4C96AB93CC33E4A3839C33BFDCFAA4EA20A25DD3E2325FE93D142A18D3AC06CAAA2EAC6A9CBF67E5E087BBB896E803DC358BB69992A7CE72A69C7C511A85535EF05B4FA790A574E21585C3FBB0B7DB585CFD98076816BE849379", - "k": "D3772614A38598397B21269656EFBA39B15E482299F3ADAF1F82225595A1B7DF", - "m": "ACDF91D5B4F2047AB9C7A8C2F4809FF69B9D480334C501E6BC66D535D309B100", - "reason": "no modification" - }, - { - "tcId": 71, - "deferred": false, - "ek": "FE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70D", - "dk": "4FEC81A2301E8E900CDCAB71152484E745CDDEF6C1394A31663046548620E41BB4B96B275AD23D004AC2AE606EEFACACA4815E06DC3F1CE76659E8517CD107F6BB3FBEDAA9F448999544771B773EC5A0CD23E8A090585DDF0892EA7720F35B2AABDA2E113AA85E9CA26EC49BCB6299368A66F2385E7D22884E708ADE3185FACBABFA4904D1378F86934A81217B7E273F47DC67BB91B64EE20DAD457531B4C7545B72AB397CDCF1158150B7A7E3193A322F9B4B0B72838BA8A642DBA31176095E8A338C889A0A8E419D2F2709D109863DA90D3A88C4D95A5C61E805A7815696391EAAC76FAF252B9763A1A390441C70B585A908E8829A60885CE870A50CA0697F56CD63E856FF2C24791A80E7284EDFC8C36580142F757A27DAB8279160CDF4581FC05AE611021C689666FA300281B3E46589A07925923A3F32260FD9B8454EB862A3E29F8F3C5B500AB7F911422DD737A1E117E7329FF88950E9A3549B41BFCAD103A0C7853F7241F48CC9A6C4A45901230C3358021489DF2AB5DCE2B626653B00F62A9533B3394136E934B1B977310638099B79AB29161A13F839294683BF99C031F3B3CA4778F76268785CA85E0580317B8FD225566BA2069409815BF05D21218E517A64DD9CC0140C90B3C05C8E1B9912028BFDB04722F407116598BFC4A80A71576F06918F6BA64663970980B6473845B9AC281915893F5376FCB00B90C323B447518F7A8C7214CEECF85918A97829718BB0D594F429C0BC990D9CC7AE39B73EA737832CC66BA0BB4EB07780CA40B4BA43B8CE54AA90C74F40E57567B1822BF83FD7C7ACE97509B3B6BF101C23CC6B92F5CB36472C1DF4B3B97218C1D3880EDCC6AFBE63A096A279F16785CCB7233D5B423BA35D6BFC383CE12B0A7B4F44C5620A197FD6C1AABE457DB5A274781340FA9CB603D830884BA7B632B0FB56753A5117F0C806FA208F89E1B7F4156DF6B8A0937C1EB0E5148AFB6BA88090E50366161BC222C17464719BC6026EF806B77578994877345D0111D834CAC01362CDA26868957032249AFCB522B92555A3C414B544A4F2CBA499FB918D7079EED7221A2738BF915AC7033A897BC1F8812C64A5271EDCAA29125C9F273578E73CECE2CBE628BA49C4C06450AC06C7BD960B31694A86C6322D7F35BAABF415E43B4A2A074E8CBB945BF9A79453B44B05C4A252AE8240087C97204D1A1954B8AC438A2293690C470384948C094D59A9346A1314F22D589844760C626488381F4CC62E647D4175BCDFB16DDA3C4DE819BCB3A00AF208B7AA2C652996993277932C79697AA3A0A777C56B506ACB1C7EAD291459C995942B3396FACFD5B8951CCA1D64A55CD09B6A3E5772E5B754C3DC065D312A5C41394CF75094DB95A741319199ABBC996255F06F8E52025FB81785813B95D89E32A19EC1803616C2CEAE484883F8A438F40E38735C3FB4452534BA16025553C5C459E9A9E65C6E7E84474B9B6FE17606D476099E2A3861CC1E01611A368ACA50EB2A01760BFBA72CFD75AC60A0C95B161CE759001E742CD8327373E6B507206C798167362C3ADD26216A105094575CADB712E2B3A10DAB8A8828496F3C805F61C0D0087783BB47173C6BCD850BE86B780CFA8463F555ABA49981C63DAA4A1E9550550901A012CA53ACB3B71CE400542C2B5CD6366F84A2D4DCB64F9C6D6B790376A0042A1285E4E52522A090E42266CE8AA8919C036E7C1B8A776CA945ABD96690463A766180942A126876C9BA0DC9961C634E049448B217AFF7D16D5B2C1B20768CC5E73CC88637C217138B917AE522AE3F742165B6B754649ECF7ACDB974B9DD310D69C58DF3A23D01B8A7456C6FE76CB6649C7049EB0634FC633D4C7E99B754C8A679D50861974CC8F5F01059A5B97F40C301C3471768A668D2CECBCA91DAABAAC5E59A80453F846CC3751B0DF8B0701F20BD35C9AD564211E2C3991A5606B823903B981CC9D66CC1E5044F484085800BCBD835C553B781086750675C04C1A1916781D363643932BA8E8C2BDDB65E00E0AC990684EFF2217BB02AE0F33FE520C73FBAAD021346882AC6794B9045213D265103E4C25B1DE68254253EEE9C4B81253987B193794B4E23B67FEA3B5036508F798229BC7C1D8CB476022B616C65674683384787C1ED222D5E5903BA31BBFE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70DBD81FE53DAA89CC40752B7C0394154498DA83D6C03DF3B7834AB3CB12CE24953093744B72373F405DAB7EAC89D0B66540FBF92B623BCC950B73DC2251610E6A8", - "c": "C1C14C85C884F4FE4CEE2D0C470FB97D54B2A992F7900B8E57025CD88C755895415E67F6CCE90E241F534E950F91CDF2E0A72F59D6A721B6203F7E08BDE5197407F0E79220238A6AE9D6A5F95EE0246E86C35E9F4473D5CF3F59421187DAF3346A513EE8E628ED64F18F9ECAA1968D8CE28BE468C01C0792F5B70FFFC3F2C7AEFE601D8B12B2252E01856579B56AD5E686EF2A3D27FFD75DA7337D7866078F2C830B405450F0233D60BCC06F90612A1C516770A0BF25EE2F59607ABA0704DFBB01C18DE2EEDCE64472A93F417797AA5A0BB4C83D03E283D2A0EA37BDA94B060C5D1EAF854A05DCD60D4A6BF7925E1182F15BA3E9D992534D4C6953B9AE08DAAFBA92802D63E0A67161CD00F0AE3D26645688B00398BDA91F7507B8112D24DE8C7146F223DF6ABA561FD67B1B58CC909DED55FF34EF8478C76195B269BB650C30B522724A46209998DD77C6D55653C39CA608770B8863F2BA3A12EEE891C9BF94E77E95F2578907966B121DF02527E68A100A7E2D528BDC50BEAAB63F70803A61A5F93FC3FF8D1EBB46A96F88FB3CEAC5BFD3AD2434875430EE00EC06CC1F79D4811E7BD4DFA4F07A25052579440AB733BC189ECEFF0F37929E93ACA05F52AB4FAF030E8A39E37974F421E97FEB08F0238AF55F9FD33BA30797651FA5AA4D8D44EFD3F00E1F805AE89585D1A36C13AE8C3059CEA591B69C54835E8A112E45371CF46DEBCB625698CDB3AB1E1712740B3C7C2AAABF543477CF835193944513200AE2FF7D634D6ADC7B947238717C2E313D606A9759CF9CE2CDAD5E271FF0C55FFF1CBFF2391C21D22C0969FA9525F920F0BBE5948B99F1A3E91CEAE892148B443F312B66534A7C4276D88E981BB01956E06E1AF8F2399EA1DFC6FA67E0185575E82E1A4ACF62E240A63BE3AE57D9F93BD1208CF2E36BF7DF24812A431E2966849F8C46610E7889A89DC4F2F3B3221B2A6A99E2811072ECCC7FABA0F4188D33E4A40EA8CA5B48A6644FE367B54C4D2C16B4F3392A8D6399AC09D820E2DD4D9756C63D9AA22D8E591C04E0F2D79D22C1B75EA4F393080C168EEF1F1CF4AE4FB87086D5E6ED067D1764BACD6002E4AE63E250364F09C2B1E0EE6D68E2F3454F541FD58704DAD3DD1E195AB98E9EB91D3F167CE1FF578D7F1E465996F14D281EDD48BFF29DA518678A7D17A7AAF37A4B0A4194E5F4948337EC7B6CBFF9BBFBC90F2CD1B9C778FFD69164AC71F3034A1031C08A669499DCDCC097E893BBA7520888F69CC9F29599576E44DFABB0FC4C3EF5C1F2BB9E5816D51F6602FF8B88F2F3B63BC66D685610BDB30076E6C8F3E99C99F483534B46813E0144101A82972F5C843884E613B9A75B0FAC9A5A64D1CD6FD44BB12233FB9E50183E66815F9CFE7AD7D12C24556E826323F7A2ABBA8036E84DF71292F3C209A4B5D1DBD69FAF65B5860A500AF82E17E6421EA59F11DE2ADB9737C4EADDE3F7334A53DAB3AFCA556762D2B7D0D1565C9952B93BA394C4A0CD75DF1FFE76ECB4DB2D755A29563A7A85258194CF8C7899A0EC125453747CB775496BB172D9CD580396A15487D2A1801D19B899DDAFEDBBC9E8832C0E602D25A4CE237EE79460A069445952BC7476F31B3C67CD2CDDA4167DCB65F09B32B800CB04D716D6D2995BBBC5497085F543AAC81A0944E7FAD8FDDF92B67058AA0C4BC32EDAA9760844C7351D64726C506A61226124C816035A3A32F8F42B9CB808429E77EFDAC4E6731FFE83EBB97E0E805065B25A318A2545EB6B5A7306F687F1144C3812209CDA0CA9F9AC0F66A9C29BCB5279BA4061105BE2BCC187C37A186EF9399B93E5EAFD81C70C91696DBFB0721024145E0018A135EBC7004BA5DD824F5CD95515B8E2AC94C6DF5D07C40ABF03B59CDBD138270B049A640A1C1075E2703DB1B547D8C013DA7E3970E1F8946F3C9112AE214109D4AEF6EE0136576457150E8C54C2056D3688147CBB3C533E1DCC781551477FE4FCE6A1BE0116C5C0748CCFC8179B28F27797F58600A99AD1A3C5595F0A09AA6442A516D122EEE099C60EFD54389ED65389DAD246386C6CA2BD9BB3EBFB0034A3B65D08AE6F10AFBA3B4558946543462D627188EA244AC96020FA9BC43313A46B22259AAEFC421E6A2BFDF450990A0732C8518DA7286AC923804928161D3C8CA77516AB03D2631AFA65CA44E3820295673A1ED5E012DA4294541FAA8964A6AA", - "k": "7E151A29276FA13C06F530A46EA14DC37B820963562AE9069C17A7FAD27C5F1F", - "m": "696EF6079C573B67BA3531CC69730216A3A8136EB6F647481382A5CD93C6B7AF", - "reason": "no modification" - }, - { - "tcId": 72, - "deferred": false, - "ek": "FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FD", - "dk": "DD5097EC5CB6CEA0268886223C0370FA495D5BD55C93D6B52F74B426A2BF1EBC3A791A6BB6A1B7EF585291E3C4176AA91CE998D73A2359361B20D715D8250385DABF4B4438CD26326A19A651D16817F514A317795496349BE3024BD7AE24C75BE3F313A64151E31BCB0BD533B7388A0A865C41AC4FD2D087AEEB1F2758771433A780D88A6D47255B523A72358BEDB3BD64895039EB2C9434524A926B0291C0D4084C743CBBE35C35F2866DA31C27A5EB1CB87C014B021056507702702D196B34F5B15E11B953B3972123A757084CB50E46B6A03B5F66F41CA7C7720A63C380935A90F9AFD820C1A4D305C7D3929E0C93A5801D62C31F3CD9C92A8C9C61350587F0972AD0C22B32209ABCB16F69C2ECFA89197B27D64507001C71AA22475E851560F046DFBC935397C28A9237D19081983652C80C4C5CC6C5757C8AB5AAA39FC591F88322B851CA8CE5609FE51C1D5B3B6086531046A4688121F86326D03A5E9FBB761B22B67A0CB84EFCB0EDA957B1587F8FB8330AF5BD01581DAAC976C46A9B0684131B75519251CCFB33A6E32322CCC9BDE7A2504A31A7C1642A631B116089BBE4D12B90A761C5D2BE88B58B373351C385467D196A169BB328970B196A3E3F5C0B06FB45A5C84020F37A9A94CA47F11D04B5A40B14C1093C45EB29AA834A3BF275B1483A4762E7434F761456F45F0C3116E78AC4B619B9174027B830882C53A845E9BAF1B750C8F52D1B5A3DE474A57F57BA9B0BA122A67ED4BB13A0C608325295F2E41629312E26674CE55C9C1B1A252988908315A662956AFD73609F546A70D48F63CB0B6650B9FEA1787AF017609B2CBB30B8F605A08BF12FAE63A0BAA37C25054FAB5004C9635CB2508E46E979777A6AB2F412072999A717030CC4C55EC13314E509D22A27BB290BC9778414C42552F88E739570FBEC7A4F87A4E9BCAB909377F5288A9F64AF721562B05CB5D92268614142BB8A9FBA30ADE6B825F8D9B0E2CB686AC9AF7EBAACB0695F24C1BD29C9CB1C5CAC6C9778FD8C45AFE6B6B3D32CE07570B2A804A3F111F07678E141AB27F12CB375B1E329974FCA796E2247B7B31B6AE23372978D7F7BB7A278897C25C7138510430CBB6F23BF5AC1B9B124B5E546472C80877D503906841547B45A72A319537C1E6A335B3E71AC04DC01D4A678F7C75538590120D2BCB0B767AC601148B12D66F1AD59A6CF4AC125C229C4C7A75DEE611862A47FD82A049600ACA1266BF4B06BEE3C6540E1796E23AE3C11317C8B158BC814F1931F2E68A4281B7DC0F48344E50FEE201F2022BF7E48C79B89AD917B3F6795A8E6C0A3F4C795467983EE9457CE57C22C18B65CAAB119BCBF10328EFBE91A9AB8765E989C190A1108799200552545706964D045FA54478CAC50DC1044266B70298AB27231592B2675E09705EBEC47C64868C26A416D6C97A1D87563DC56FD5A3715B45E063A632BA278A4C11B3ED76557782D1F3640EE305238842D5D8A0251021D63F976696516970CC6D8A8214CCA2F5A265BF2B5AF145A8109413147E88E9C7926F7C668B38289BC6556C10334DC3438904212A02B868F0B5773C088BEEC7F1A914DE0520260E5823F89935103727CF8325206963491335ECB4BC20ABB8D76481F0703BB077881958F5E55274BF9A149C11B7B92B4BB63B8BAF06CEC031A8F899A66E28E9610837100207DF7155B096A33BA1EC3A779634C3F571AAEF3B6B7B97960E268685466CF06E683DD6586315413FDAC5303E664330AB575832C394A084C65BE3D41BD533C631BCB411C718145C264F977435B51BFA8A7C2999147792493B8DB0892540B93E27E452C47F7E57B1DE09C04519F9CB1023855A06B2C76F5252FEBFC1527D55DB1087ACFB7AEA532471AE14449F843B47B96B8C06775F27642630DEEE6877DB17D2BE4C101950332614B4A5040FC74C52C07597C1B6C9D46443D68A2652C2FF9EB57E4F4B247CC31D6E5C732D9083A985BE9752506C07F02CB868004CE0B3154FB5A92F6F5A15472A9FDE333AB1B0F08386397F9621566790BD8AE0CB89763F2CE74495D1A54A800E657A8D42613B12A8F3A416795359AF55E89B28D2D18A3E8B110DA297D33CB0BEF9C14D4058AC8DCC633CC682A7C3BCF10BE800BCBCDB7CC773412EC643DC77B5F5CF0A87DFB25FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FDD737B4854C1D79C36194DA7346217580DB481C0DB2116D4DC3A296BF64A89F466B256F764B817B1F7901D0B12CDC08EF3C2419B0A23EB25ACBA70917A39F3171", - "c": "163F9FDECE0DFEC9D2BA04A7CF3A72A3CEF584D0F4CA5B041B72AA48068C21D474A61C0AC96725C657E6BA96210929BA18C5192AF13724E72F4CFCB551F6D0C2A59A4C4410D284D45077AF6C3A7911D0D0B4534409EC8C521C2C8BCB8B14D4901C0F8C85FD3CCABE31B6C5784F4818B2A195B9B837DEB60D739C608CBDF9E13C06B7F1132F6EC0A4823CE42B00079A19F1A81269BF26820474F0C0CAA81E20FB059AAF8E11B51741B5849A87FD0349CE05FC37759B61D191479B391CBB4EEE04908B7680E047232DA268EE4388D9D92FD944689D6BB8BEB9C4FFDE45FD77435E6CDE430D34C5D50C107B963D8E1AA79B0DC4633F31B79B5DAF009B76ACE6BD277F5F71EBF3B08A4BD511E26B8B1291D23689818E0BFE4DCA6EE0023297926D777F44B1A3DB409A5013E366118B98571059AAAF40FEB83E660894E11DEFCEB4A08CBAED1C17CA20836F81F78A128D42D94B3D71B010AFF7818FD2FFE7D34FAA458CDEEE897E79DD9D8632CA772303EFBAAAE1591810823BBD57BCD3858B37673436FA41D89D8219DDF163243FD773A40D1402CF4AADB34AB4BD75FA675DBA29B69A7C464372111EEEA8263D05ACAB73BA1655556CCEE0057417DE564B7C3CAA72DAC1AE5936E75EBD9B30671653FCF5C4C007ACF7C076688815492189D4BD7B76E6BDD2E4C5372B963DEE5DA9719C57B228299C4DE44D136FD5E125C9781CDDD9DA18F58AD586DCA62DFDBF3683AFB7BD5AFCFDBD0E5238DD89EA6ACEC0EBE39103DE643D017C67576017F550D7C6047AE2AEC3C1E4EE85D33C2B1C33AB551887C035BC437B7C5DDC5D06E08C35E1F46502CDBE630A4C59C14309EB2921D8468713246408FDC894C993FBBFAEA06A4CD8D8AF2E86A672E8763AD4E4003CD4379DBB1DB93B08CA8BA9B16BE4D039623DC264C6E0C730921B9B42CD665F7CAD4462B233DEB6DBC0A9CC5969D98D8783203C3E3004D29ABCDEF33E83D8FF5DAEF548B2AB91F558D23B2973A882A41B85FFABD54F908A79A8A0D2889BA54195405D8C24DB03EA21A92FA9B733EFB75480E8E7757F60F0E58433E599D9B9325368F1135FC3EDB9791E4A25D9A714F37970ECAFD78EA94582BB370F405216D4F22998AEE28D0FEB31FE42D2F533D5F97BEFA759F25684C1714677CC96E23668F697D2C39087A50A131BF8AE98E5618476464283F6F75DEDB24D7174D090C3E3685F10B6D90C423778EE272FBEA69D53C0BEAB7024A4D64AC85B147F9BE83EF3B26DEB5C3843131BD4BFB24CAE9564503F41197DD33355F0E7C7CF069A87B7D68B5BA0343AA5E6B9BAFE6C93D1894241C86F9163353B2E79C28ADB24A7F052A21BE8F3B3807AC16E66AC3B04EAC1D92ED78DD2468A58599DF566DA1F052DF6E7786F38EE15510D7491B1AFD87578C42075103C9EFCC49362AEAB9FB8F6BBA88506B32A536A5D535BA449AF8AA79FC4418F6A43A0289899CEFD33D93685FF4AA2BF413526D06DBFBE5BB95C6481A61755E961B2CFCECA472BE408EC95175A942EB27F21212E7C8E26F40E241650460471477B600A5895D934940C8B86AF54889C7D42454D8E40BA689FE02C7653AA7F6A6CBE16DA3C81BB6653B20B2AD24E172073C38CB3E73C192D7C6D0AB2E7DA418A3DFA2C6A45C53A8DC81EF0FDD349E91C2D62B1B38197B2AB41C8478B6F551437FEFE9BA127F19BDA0185E63E9DBB09BEB1519DE53A4811070B8E89F447D6639E76D4DAC5719D64A22B161D9A13D3FBCF707C2FEA9E92DC675B92F0AE208DE93E49D2015A33249CEA4B8AA236E4B27C3B4111B7E62A5FB4E841746AFCC5E37A81A7C501AD8E1C725BAF7C358848B63FF0ED9461ACED678DD501BA506C5376A69BA03258F681CC343BEFAB1AAAE513AED9910AF6A5970CEBC113532A18BF94366C280A992DAD57F2E57D6EA6DDC5AC1A465B1D5CA8EC6016A592B5CFB240D3C11532F0DAD89190E2B2B597AD12A4648EB605A69F2B34BFDD19F092738CAE74E5182A9E2BB91FBC5C87116F10D8DFDD751FD68806ACC64BED13D832873EA674D70755C89F60F1C0046B182D1F5BFE5C851AF7707A1B1A2E2C3A8BA52088454C8798D344F29283B006DB102910766C9CA33F405CA44207057479C4BA23D11C564D21D3DC98D6AB45C57B969DBF42513E8D589C0DFD602922CD875B6D0988527B9EC39917BE456FA0D8339999E68E51E07CDAB598D1B8", - "k": "42D06DEDA4AB863ECE98FCA1C9C3E5CCCF7CB03B8411B381B028034F12B282F7", - "m": "B2180DB6D5A468155A4C45C90495F8875538F05B8B8587644B4A668CC8936447", - "reason": "no modification" - }, - { - "tcId": 73, - "deferred": false, - "ek": "5AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E0", - "dk": "3B052C99E38F21B24FB9461F66218E682A2343807AC6B0BFA79B8E077257EA63B5AFEC54AA9565D85536EBDB036E82389E228ABF62167E1539F31A5CD19C87896C2A31117C180C954E8BC5FCC63ECDA30762383D7C7990F8C1689BF90F28F460C66AB468337353838D6B675CFE475C4FDC6BCF3112F5B4A142A439D64C557F0075B8DB9D059AC883A1548B031CA8EB58D2930A47A18A0B2518DD6B56A8AC961CB41B1C7A9DF2479E3E43C4A45703C2C66103A0199BC09347CB5E0D700E27B61024C45B28C3B9112A899855CF7C77B1B2D3237B6A3E36157E888597D87C07D7885A89A257AEC29369800C9DEBB1EC5A188DD367A6437FF3B97EF3D7201589987C3238570A8CD1F9089591068F572BF72954A07A160380C2B4C23DD9381878BC54140B101C27873356381EA7425D3C83EBE93C4CABAD33B292B15B68F794816175A5B69B36DD973966CB9EDE35C4EF46326CAA08B95C961F693D0B499103BB0CBB42CA25E08607600438E004E5E373A994A0883508BBFA002566BBB3A79269CCC9687434B22350A4B0720C549529298CDB3126D8162FAFF29ADD11154A73A1B3A4BE3799CD53C533A6A6331C9843E83678B2226F36931424367976211E834A50C0101A6B9144BBE12522B42B660915812C6D07204EF0934B258711E0C50C99A0979CA7A765817AB57A75264B336CD8AB86DB894BBB3414726466A7857E92509B8BB39C67315C205BBE19321756B6A3C925910A1CDA417AAE4B268B8C771D311DF152696BA0659384A0D5AB2EF5B7AED2880C75C83CB5232A3BD126668307BD725E901A77AB46855DAAAD109BB6BE8A3AD49755FB4450624296BAA08BFC48CE9DF0BE6A00016C966D1B6A8C6E959A5C8ABF6799B63F2280CA1610971C046C960C691183C233A1CFA889489BCE2DC927B6C388BCB74EE1FB4000EAA98D081BF2F95907A10CE2D4548B91159EE877C12A775538508AAB9A6BC59201B3ABE4F7539E34C56BFC13CC559F80D9A1796B81F90308AFF381B99B686680990E9CB7E830AAA8612862C1C0DC0AC74B3016E3649FA5D7B8BBF870C7459BB34213DA480D33C56C170C71C912B78DD4264C979ED64098401A96F353BE82EA241B200B7094B60566B1042A39B94120B053CD0F56644EF8BD88079BF8A935083A94D169C765014917A391A0A780CA6C9C0CB88CABE20928D2CF7BAC04589B108E0C7E55A64070C52EDD65CE50EACE1DD63B10471266B1547D79C919593C36A10894320DEFD85CEBD12647E984B48C259F59B398286142F0059726408E56538F5C876067821685C1CE3C8F05006BAFA48718D54295B64BBF82BD6DA9403A2AA5E9F21380756A4AF71F9EA1CF99F31F22BA7513609AB3ACBCFDEBA09D5C5DE45B0D83F13D0557AB627805D02588C2E772351B2679F86ADE56873C509D6F15120BE86BEF908BFEE629DE3B221D4B03A9909B6B722181085B82C087BD4C985601C6EF1665890054E90A897CFB06C38314F2766C7BF31E4664C0EE025EAB2A80233AA1533032AC809718A8577F1C2D968475E4A0BBD25514A3B27C68EB49775ACBDC22377A920948F2A7B4C78F17520273E4206AFC8E6B580BC597CC1773CB34963EB7726C55B7555041852075A7C06602B9D717EB5574823352FE49134D972EC7B2532A273CA0EB5540B9CE9C6A9CBD1B3079C0BE96B178CA71593DA4A49A52B287144C962B28063292EDDCC84C13A6F7B0B26F0B252E2835A7694AB7B8C6F8B132448583F1A27F8AA9A86224648B05551E332187B296F542CDF746754B13B395B16B451625A032AB7C044AFC6C8EF548321183B695A8CE05E29296804BA0D96902B98ACDA81E98B996748385796CC3DFFB46026A434A71428531C0D7F5C05B877815265B989A16BBBC928DB6CE11CA3249FC3410EBC8EE088B7053AC44090D050A1DA73275118B9D3272AD38234A294C6A52C98AA1CAB0A2089450BB7AAC635D55D1A9099A1FC951783078AD83B771135836FD32425C16C8C5EB259DBB0F27840BA574AFEFB52ABC6091BBC8AEF6D6684B02BB5414BB39BC65378B715A492E0BFA13ABE7713D401EE930AB98E5CEE7DC3C12F1085C528DB8121552D95E7A081C6DB34DD616BAF3D0427E0CCE01E5A804DC5A100958F94C89A2FB1D88ECC13B702ADD75B5847234DBCB015AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E004FA8E0B4695D94C8D670F7E010B0562E8AAA1C46B3EDD2CF2457F39E36967B6F7A6D1FC80331296B8B5568C0B506ED3EDD6DE5E81E0F76F63F7297FB41C2CC8", - "c": "8C4E7C59965B9CBF50961819684ABE5DAFC3AA381F779869ABFD60C263407D4C03CE96CD714C0A62532CEB8E460D2455B84374F4EA30FA5BCECC77EF9FE108AC3EBD24AF4E60194E8FE7E50152AC312B50F9DFF28AB23FD2C9ABE4C970E7752016C84093F9D8483E93F526B1E505097BA5687C7A7FC8CC2CD0AE94DACBAAFC2D4F766CD212F6C04E23762045A1C856EA1D6F505FC96BFF1D1E485654690E7A7698A05B48847784E2629E6D81A692C93793FC2BEE69194A106E3BEA85A82FC692A0A3360D96128ABD52E72E7B3A12838C5BAA00B5A5B5DF9CFF4E027EBB7D8270C2D6183BBB10CFBDAD15FC56C7E3166751E7DC11C7DB5E5ED6CA5414ABEDD0619890A03C713C910F55526451171A826997B3D86CD9EFCA8E5276D7CA2CE1EDC0266CF876380901AB366E0EF60849774A2DE260D2D155F27440A6FC88EF99DF76C70F4D4EECB4A901CB714C6EA72D6D3BF6FE1D71988E6DD8EA001E0A55C00BF49B62900A801AF1A0CDEB6096503F70B36CD85AB57DB22536FE202E1DD796461E6E78AF79F56C332C97833BD91260540C4A5245E81C08CCB70A62EC17B0E2BBF46D5601B76E2B8AF386F7A3F210D44A7E61A4885D0981907B40F01736E9C65CC4FEFF0EF978AD93B84C6C5071A8E793EF0572F584BF27C328EF33B5ECE0844A83590394D834E225C2CC87DABC829068FC0E7549EA93EB52C3311C4723EF6F84A0C0B94B7F8C610876DE7DA886354B7984A6715B4F0C9A22F422144ECDFC23AF2858D147C26F3BBE5663F5006521CBF222748F67B01CD80CE5B6BB9DC7807C93EDA3B882C7CD5E668E40E6026F70D6E58AB760162816ADF71E7B785E67EC786441FBCA9BE950377BB7256C3C559DCD937413131AB80DDD24BDD441551CC4F1A956CA96039ADDBB919EC52594A1D8BBAC241FF615685B05850A206BD4CAE5FDFE50DC848FFA52334DAC3C9A1BA55D481C579E5CB3F9D9206DA201908606E15B494373C458785362DA9FB2DFFE91C415FC6FA81B1DD682BF0971F6ABD89B954E4C97F5986033AD13A26EFA12C5D52CF90B513C9B0604EF1676F7CB440276602BB0EA117BD20B4F4FD1BD2F05D5ED3473DB2F047433E228E92BEA1A7C602A691196CE71B1745E4453E0E7F510BD78963CC0C31D30CDC5EFDD55CAD3DA519CDC565D73DF8A611CDEBA8D18F0B7B0DF3C5678198B6F39B478903ECAA791C3ACAD02CE3641C174C35BB210A48530426E39914980DFE742E4982BD3BC043585A4D6F65FCD35ED6C5CE403EA2DFB84B1E7E380EC0947D84E85EA70D116FB5D8F4E883261AB7BBD78AC094F45FE830E69451642C4C294E20509A6F13E769706ADEED355931F1193B5E76B1106F5F0D718DEC2EF7DEBFEDE714CD2D65370629FB920E54781535ADD8CCEF0981684103065785B34045190028E4E03AD5E5D509C68A117B4A00B6FEA07D26CEE453BA12321115BE2BE279E12D6EC5F80B263347D87DD6612A14F7BE08BD1A8F3A6A3D1E78C33E71C0F64152322277EE4E03DBFB009D5A1DDD9DCBA1BEE12BFA9B39DD542710B5AAD1052C767782FFC04180478E0AAF3F775DA8F68C094F84FB2E3A56B6E0FB98C79DF1A2A83449F63A351CB9BDEB0C83E871CD9146113EB5E4B28B8723F949D6AD19A5148F73541A7CDEE4ECFCF51A8EE474B27E65E983BACAE976C0E18873795C278489EF8C8503769037CF6173F2B62369AE7C39939AA5A806F423A76BA18B258748305FCBA016A12160C2428E7C60B839E98DA95742E15C8B32BCFA990B6B41F043910D3AAB1D1FCABD8AABA55D13A713D7FD62D25F396C67D9516576E2DE37A319556698104D1560FCB5A690C4D48D0E23D24717E8FAD776DE0DEE2339A0A6CF3338F930874EAEB38C75B62DD99F751D5616973E538C641F1C47034C8C9A1A565A889A1B565FFC3D012E16457CAC00856BFCCA7305CD90E295E98F26F8FBC438D2743D0849FCF0A05DAA139A64837C8FF56601475A80BABEF0A62671D4BA8F7A2D3B836DBCDC49CCE8685FED7C9B27ACF203687176B86D316C4EA9C549669363CC6D76E99A8E3426F34623224E7707DA7D1AECA02E19CA0985F05794E239BB8E21843D49C4C2F8EF59894A437BE6BC4C67838EC5DEA6D09DCB93B914D9E73628155D87C90E6D4B3D3DB2F31513BF692313E28E452BF205ABED9D7AE841AFD11B7483389F89E14CEC729A3CC69F0390A9F2F", - "k": "6FE2B3BA0E972312DB3DBD84F9B8E1D7E3AF411BAB1750D75E7374BAA6B25F45", - "m": "ACA147DD83685FDC5BE522178384DDB0C8714D0F818A5A20CD1AAA71730D8E36", - "reason": "no modification" - }, - { - "tcId": 74, - "deferred": false, - "ek": "9EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FC", - "dk": "BAB28389C4A099F98AC074612F487570115D0A031BEDC16B46D77C7493318891B30B259E7284749676A76B1637CB6CBD842260B4BB9FA1230DE3E151F1E5170A82110BB2B1EB992AF9E2BA98BA4AFCFA3E71765B9346412E10998BC8461232AB5AB24A16F23BC358AFE01A1C7F8A3B05A8AC5EA9591D2689B56466438761A6220D151682BBD0CD23C42B998A1871352C1C2C0AFB1889A47C0B0FA8B2768A5ACF1C4D0B34BD7C16CEF3611851432F361A9176D77ACBA7C88C219CB98819552279819B6BD6C57BB93AC239DAA6A8D53F9D1665F8B866ABDB52FDB1BD818923FFB803C5A8B61CF9B9750A2F03522B4DD5AAC7FC345CF28278F93B1E976A381818AC2275AA16CA44204C6513394439A75D7B1E5970735F016CA6045FA4E68F4A9C31F9C4766C6A56DCA1C83101346B3A1BD796170904398A859734B145933660AE905433B40A8763AA37A868C2E3A33ED709BC9CC1F4411472B31981F6AE08560C68759966B047CA295FAFB60485A28A8181CEF7954C78BC85F395952583CC026C46D9A540E8640B9FD175F4702E5A3A131503C3251097C93332D5113C57082B7CE09A9DD271EFB7ACBB92257C0B5B50EC7BB418B83AC53623AC6B7109C713D0C9C79A750A603B2B2714A109545FB4506A474BBB7AB8556462CA596741E9B0CE3A7FC63A49039450B41675F6E0AF517623C060218C755CD3702FB4A44DB91A80F50CA32F3AC56555B8EA0B26C9E8BAB210889873470873CAD9D7346D8253E2268BCA725E900C22D72318FF686EB9CC80616315AF936F6DC7579748094BDC1301B4A17E826F60A59519B66C2599B52E963054906AA85025F1E26E85CBCC2985ABA727C77A12794D7A67C82B8B41D1110C63C3DB43CD4684001E486E18789B4E207C34D3A207674EF842C2DE7322FB400747B3246387C84F18608DE182BA3C79C2414EB60A7F75040301F32AC543334EC028C0F92914089602D15099C696019A625D357D91E6BC79581F463127A2641060460F526025A0C020352303BEAC1F1BF53E7B258744813308DC69022A37B4D72969586DEFB883A299CF814A98601766CB861F97CC7321764794D1AA928B081593AE3FAC6D3BB71ADD53C52C21B350FB3C6BE59AF019C0384941B8932C673211134C34BE8C8697FA038C90C09730B3ED556118C455B6168C84E3CF5E1AB818C02E4F00002099C78D4120252B9D86B4051A7C446E5509C5839B1023A6F9A9947AFC10AB1764774B9475D941104278AC59C87A18C1F2B17FA0306068F291D0F2CE5F5069B4A3055118C60DDAA96AB0826FD374B4F8B6DDAC28BCF6398FDB9393C718F0BA2775E54F2556CE2C2678241BCD68A00B81B87991ACBA1D9003DB76AA36075A0131023A373C51B065E2EC083F9A3A5CEB22D246711346A357E94E10C199D7A09C87D1188D1C3C0D1134DA650D5E479051B140D4A0B49492C303A40FCE4457C00A023202B81BABB699845EC77244DA184A495196446C96C0D3A0644710225A744E458782D38C63C459BF2A08833755C7066396042479874976C1512BCC046C83786B4424C2D022BDA1925DCA930067AEE3E6454E1C78B1C5A7C603B85D506892852C9D39AC7808CDE5CB71E371378042CA0B5C35414BA7A64294DC42A0463841626A5BC6F37B98D4393BD9B9E5E020B7849EE72188CD1231DF530E36E4CD72580E05359A8D97108CB82E9D1B7CFA94BC92FCC174F3A4767CB1D6FA719E202D8AD68657A81ECBC0861B645D3A781A725A6552ECC12B64CB12A6CB0AE33C64624A8D28B026C482AEBC6A69D95557FC3CFCF4B2FEE502CC7210B42C089AFB636AD573E7430A8A184685465C6B882987255430D2842BA75E892A5AE23A3A636840E6B3CD9F76975EF41C034CBD799412584CC85625208855083BAC67D85B0FE011568ECC7365798AC3EA91C61442EE260BD380C2494680FB411BD16714CBB6468BE41013F724CCA4B4FF364D095422124652D4A53110C05B89B095BDD1C7B8D19689A706E1DC656E6C1A3FC767A1D44EBD67C5B370A0F5925DC551551AB6B604A27F56A19003731DC071B2E98C86F7BA9872DA783DC68E1B19ADED603CE7F3BCF806A7774A044D9C51B26C9DDB8B809C0CC5F8D0682C7C8A56A9C89F412DB5BC4ED438AA89574B8A77206396807FC431F9A2B29EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FCED356581C66D62FCFDA63A9ED071F7E5EE0A9AC9DBF48E4653DB78A6BBFFF1919399B9CE712E51B00A12EBA403E181CDA45AC150688E2D09614014661B339E6F", - "c": "E9FFEAEAA83250A944F247022FA3F6572C8496C0AFF81462BFDDE2FF310DBA5E6820FE52E33C2CE7BF0C8DEE97175E20000B3577BF84DFD69BF45DAD481E94AAF25BEB959CEAD9DC539492202E85AFB680165C8A1C2BA42490CEE563E4EF4B821EF34B0EE08C0ED8452235F99E123B650985D9B1477D21F936BD937CAF67343FAEE1EB684EB4E0EF202F5A58445DA5F6D5D8AE7071BD531C0D736C2570F5FD593FAE9BCA5EF988B6BE44A323DCE5883806DFB7678704004B228FCADE75EDC4CDB7F4F87B0C315FC9A40B4AE1E6944C96CAE75481907804BF308780F411FE068CF09BF99AE3FEC2F656C9CA02158694E5B22F044FCAB131B7D942BE6ACA98128CEC79DAD0AAB4BD566A2F041AA043520B9D8642C9B744D4155F926DFE87AA8A031BA5E54090A93EA5091D9938C6C3CD31F83D2BD46661FF339E66513E284DF7FFD64A047F741DC81F46A6A7F03A9025D554F93D889A5F8DDD75B3C0F31DD64CD4218050AB496C5D01E632D35981237F248D7B31C6F39678D4FED7DABB29C242699F2F588D2FC56972B6EE7A94C1FF01584F56B86BC3C1B58DA0B9616B9C5E316D7FD7AA9C22D51F0BF69A080E595D794B5F0924A4448CEDD0E03B414B91D03FB511AEAFDD5CBD4FDEA6CBC0C62849B2CA7A6023251CEB720E52407D03C9412F0C87ECD974EFE304C7791CDE5911F7731EBCBE969F039C6C3FAD7138CAECCE0D3FBB5F47FAF77B80531D53CFE23E1E04921864F5346EC3EAA4B663512DB4344A5579BC4CF32C8FF33C5F32CF44238608C19EF4074CFF9ECE4265084C4515E919E2118FE535480CA816E4AD6632BBA726D9B43DA4DFDD2DD1E0E85D001BD9FBD52BD9A6A8548A41251F939A63E683CC5A076FF3F0A2C33B223AF28997CCB36D3577FD09BF46F5988C0042C666929B877132B0D5375210D20C7F3816FA1AB81F3699091874E0CADBC1550BD6DFE24335EDDA44FFC421C9D89D9E250562408BEFF06D01719CA54FE91727CCBD08FB4B45BEF75B08F560B0FB9618103FBC216A3D5AE72A869BD40E51170E88DDBB713F8A0531DCC2645CB185F2F31BEEA7086B5AA84F5248B2014F9D85E56B330F119F88E26EEDF055A5DFD87582E91D3FF59FAF9AF3032D60424DF0DFEEC98F2BCD2702A10551E7DA73628D4F6E9065049B172AB861EE64176E21FC7DFEA1208A632C78D72DD2409798DE854C3EB67A985A4C04CFF154A69D8443F6AD9EDBAA666CD29260D203739F3B77891DAE26F03DD469CE4C55377B5F3AB9DA1A42F7F8F8AA944E7A921A53F7ADB99533F48D4E9922982FA0B149ABFD95095CCFBF3CD719F59535349E66653FFAC1D0DB3857688DA952426D6AFEF5EDFAA7732133FD9CD86831BE5A7809E209B5E1214FCEFD775D3627511340F53976B571BA909BF5234DF037C8D1E4A11BBBC8DBBABCD39AC47CA6CBBF38C7326CC253FC59163FA313CB86DDADC05AA6CEF529AC23FA315734922885BAD9E5CCFEE38CD20AD2A245590CAA674AE6195F4938A95F46E59CE060E7D7960362A7C19F19DCE8424E8E7FF5B084BC093FCCA9BBE9228B089497D51BE411AB06CC60301A510799539287BAD4E2FE023B6B29386349794AF3F8165AB8F6F4BDFFF114B817B10F4598355E7AEAA31CA73F8F06FFB478483EFFA2C11C94C10E8053E95E041ABF346498F1A2765B460DAA89EAF3EAFE952E35B10630D78FF742977F2F5FCB63712901FD9181A1C97E0918DF81FEBD517E6820D70A509C15C144CDF6D1EC37FDC7CF2353A3CA7136071DF8777E45D5D8B5146C058666926096F51025881DACFE2392F82019580BF82E998CFA5AE06A9EDE3FEA2B4C6C1FA0D02822CFAF4F2452AE695AF70264D5D7935FC19F2917090FAAE36790032CB85A5E875C05D0483B2D4021892E825A2D0977724DD1E73BBC8C430A0F6F4574AE112575F87AE30BFE94EE8260B5141A9E414739B518C11378A7C574962F0DFEF8E2DA1C1FB8B4E502D182E14F64A91FC55A80D65183B7B592FF077D3504B9AB88F6CC5F4356488DE0DED68A1C469AD9556E2B467187EB2B0B466DB99DE24BFEF3D9944B244C022F6977C0CA987BA8D0D10944CAF8AE6B89C226EE50E338F653A641EC39DB3AA834E25576B0A5853A7BA26E59D65031DC780E8588EB936D182D988BB77B4C9276A737E44CA1A27804687E137A84A872EE1970448BFBC7C42007E4518FAFDB544F9A", - "k": "7BCDBA65823F7A36497091555C7E558D933E707016AA485708FADD30EFB8D8D5", - "m": "B974689F6F36C7AB262C8B97D5469ACD3BCAA3A3454F611FF0B304FE1DF6C66E", - "reason": "no modification" - }, - { - "tcId": 75, - "deferred": false, - "ek": "A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32D", - "dk": "8CCAC9928C0FBEDB3AD6A04E1853BF4689B035E0C8EE7C26BA2140CE1CC8476960CE51732FA0310D636D06D802B164B826F376395AA0D371C9D56275D6AC5878D13655083769E14974B22FF9B02C5D1370332A47626702E5E2044E05B597F94FBC429E50E65B437223F32662A1C37081C3B7A884B37DECCA999C1EC3997F38696A48880589805E965ABDE6558722F5481666120D4C6B12447593399CFBE881BFA754B57350CB060A80CC7F95C65CC6905F6E701E1DB03A38CAB8ABE9412A990DE094C99A514C68969940B5A82776B6EDEC32F7DB9A5D7417F4012DB6F36AD8D8967F2B144488483779AAF36188A7F27B9FB8A9222A02411B110137BDFB835040E220E19A8B2F8A25453286561240C9E02A36591B6829BE48177E086599DFA003D951CBDB4B24313CB8D5FABF9ED54140FBA91E3921BA9184FAFB5136D64F22A2B59B27116DE13893AB6FAED8A1346742F838641DB76912D30D2481657194CE3E709E9AC272DE638C21580CAE015CB04A89E587CCEB0B05A972407F9C96F8474A859344EE0C31A2D30AFA74948FE2B6A4C26C3CD2C9C0D7400B802AA36487F6C216989A5F806536853B9FAEA2C2A91C039CD07A4E435A58D80DAD50A991150B1A1B0042818A38F6929E325B6D29C70BEA1877D73403DB08B856C10C2851D0E30EC6BAAA9DA6974851CFB31211EA282B8ADBC7425274D1BCAA806652344BB663D7297304192E06AA53A438A2D147DB58A1901786FA9924216923B01C1FAD85C0B79332E9DB420A94964CE9BC2CC19276615B7FA3A489DBCBFCD07412F186ED412CC866270AA53A5E645ECDE278ACA36BF5381DE2DC57C9B812BA13863E55BCA68C76E1F496F216663E877AAF2C1959397AB9B1BC21B1A1D9AB5091484780F58A399C058D17AC7653A288D27E18D43B4506C69C477640069446A5B00F9ACD93200E21B40905A09035886B11647F1182BC6F824CF7A5B1D1951FD9049690450EB559677E888BAB0924DEF1741E22B610894109CCB549E4A5EE0A5F4C761E6A293F61EB2C5739B659E4B5086A0C1B4A0382B27980B07C1D2035F1DB53BB82787AC249B2011F3590CD9FE5515F813C65953AE46CCCB7C3210E24AF82B16DB5916A6B23393844636C278641C48CEE2276760518C919AF3E16C3C9714D1544CED4D2A64DF482CB4794B8A77BC5E6CA2718513E6213F620BFC8063A667CCCCBC99C7CC1328A5CAA31DB820A4088CD825313D677C49419B2692E00813E33A0B62604CEB47A547FB2A92B63CAFEAC4B63A41FB1805CCACACDC62C373EE63C49F09899929ED85C89D884287ACABDBF717F3C49A511DA53DB43AF1AF30CAA7B09E0D760B66C805382C427C3BB77F24381D71F691CCA9DA8AB1FA56695E2CAC9B543B1F5C3BE2749A804928BC005F0908576FC87CDB88AFFC4869105A1B5C6364A64083793A4900434AD7B9A0196BAFBB3B54B7A0D23FB8440A65170296008BA3A94A94AC5AB36F11507F6B7443A928F592589ACA7C6AA5BA6932840124A7DD65A20F72A5D8CB356846A1D670CAA2BC06A4D64C4001154CDAACCC7F21CE0C1C877B2556833165890056D929510D4252A065EDFE2152FEA9876210DB26B7619F220BF5C4DE7D05AF2530E47FB43C6BA7D385482998994024C04D576AAA4AC2B1A951A01596A0EE36F6D8B0BFE0A5800EB2ADD9758DCCB368B701EA6D4B9605A11E7369E44F67DD499896CE297CEF763CFE99C14D41E11913337714C6C79084DE7C37AD76C7A838D6C40B485034C6F55345EF729C0930397166AE317AE5FE85F4DB999B3842387C245EAB7500A51260097CF87D77C56B86009F15CA8B60B624011086C229CB73C6A90A81296B4216145FDF76528DB8AEC671E7062AE1105214F01770BF98477F9098482AEA044B92B6AAB0C70480759108B4AABDCA580A1C640F32826B7CB4734D2743DB5090E8B97C1AC46E3F755AD8BCA6D9A93B414B7CDB15E81D9017CB1291FD263585A02E2EA555EE176E8D29AFAB58AF189C5480199409CBE7D871E42EAA4702C7647D023FCA094232ACEC3B994B1B93930CB9631E34C3BC6BD71116FBC751C872A5F7435376E05941D9BA80BB520EB9A6ADA4174B671B682472F3EE9AA57579265190D618575E2B996C3A1A5AC868B96339BB0024BC4385C96D1B5146871A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32DF3F0316106B102E875DF4653219F35BEEBE7CFD5F0C59D1CF68055C61539BAD1231FA46366271E63D3B696A0FD4569870859EFF47CB57C3C6A65B22253A739FB", - "c": "3E07145AEE491606A4DFBBF9C7301FB8F21A6F46F8F87253346A5981C7D83EE23CB6BDC508AB0756A8E2D8713A03275A551C0B291DECBF6C0A3F976758ACA963B590FEE44E8D1056AA95AB5D1B77A0016E3AA605EB564337BE2FB33E54054A08C7A3174E8E7FC0F079B1BE8C30BC0FA7C03972DE8294F9F24251F834711C0BD340C9EE20BFC74CF99E8C0CC8AEFBB057B0F7E3CD0AE6E0C47EF67F22C13C2B16179942D8AC24FF81D99CD9C5ECC5065C0BB0C4A9B36FEAB42B2F06A6A0F9AC2FF4AC50864C6D03CD97F785B7B3C521392E246DD0D5FA5218EE1AC30A223194E5A21267D1DBBF4DDF1018858D69EBB382907597BED3D90936B5C039DA96E5BDDDB8A5645EB1BE21C1504221067B293B4C6C81EB983CD49B5A1DAAF7DB602E990DEBF76613C6111B3FDD2ACA243C3B92D4E6988BD43082F6339A89898FA0CC05C1859DF99EE74F3748DA53BA99561A5F5C1EB1544A314343FB9167EE9E822814A6CE530836239DB515A8582CD9ED338B2A4765A7C265F0825B1DFC6E6CDD41E137C5FDEBCDA6878433EE1BAFFD7F64020D9606E397A12AF66253E19EE2CF4115C173EE73535DE0DD5A7EB7E2EBD769362982F9B09AA5D6548AE9163D0ECBF4929A950853069AECB829AF4F91A517C8E8D2DE761CC9F5729931E4396D261DDC3C66350B20FA1B37ED3BAF2092F7BE7C85DC1D73ED66A5C7ECA6D6ABA46E09B03102D0325E712699DEB28426AA5309D8892BC767BF099EFEE2481A589CE304427D9FB13A65913FBB37C039C9390C9E9BA3988A81C98CC60014117CEDBB09234FEE8529B9C3CDA11292EBF1678BB9B2A76C5CBB43AD1F947A984348DD8983509D7A3D3B3A560D6337CBE40D32F554C24E10BB720150D4440B630492CDF711193498E4CFCF3F8983BEC12DDC14EA3084C63A418050FE55085E279F94109B4AC6CE02E91D5CDFA62E9EDF05947A40F4BDF8C4A5FB712F86772DC1D9393482D45692463E3697A925BB7CB49F7B9E030199F4955EFF2C829C128DBDCFCB68A3CC57FA5DB71D90ABE690B97FD9387BB517352045F509A9C7A2F01EEDACB35E5E660ACF9ECDEA3F4201DA07BFB8AFBEE7AE32A77779D68A77EB23DF57FAB5E1C7B21E7515709F0BD475361311B831D336461ECBDA68646B8D036779AD9DE23EFDC399C4C90ACFCEC65B877C75A6C5782DFF158B618C0E4B43FC0EBAA641550A44721F35C09864508A3FD0718C2D6C0F235E454D30D969882DBADE20BAE506244B0D99EC1F9664A624A9F46B99B573210A4959CA9B3B897B40FDD92346953BB526893EE06C96C39EBAFDCAC9BC45759299754812CA556E5E5525477F88D207187B1916251B703CAE95B1CCC3585F7431B23969D20646BD1E61066BEA322F16CF8E58DEC2A5CFED648DD98826DEFD121C30302979B215FA0FFD233E61CACF09CD929605EAFA9D2083ACD78CA7C97227B379B0359832B5E1EFDD2CD72562DEC3B8D23B39003539E4E9B8F3C6A74398F18A3DF3F05067F95410F274B3DC0A3A8680CA8C53C746BB4208BA23B5752FB24121B8088AE702C8CE10CBAC6E733108072B29FBA6261491EF0F06161592C19846F18B9341B85D6A5DF4863F7F9F00EC4F8A669085F03F6461B3DC0271D38198FCD546AA1A8DAA4925E9172633816686FC07A855C92AB7D9B4E692D5BA6F51B0B9928EA778DE8A167123B0A80C8AB0B8CAABC5FDD12736A9089D8F60CFDC9D5A8231EB64EE8CEAD2B1FF610BE325DB34520495792E8B9D5403B0C2451671ECF9871BD5FCECDAE8CAD4E9E19815A60CBDA867CB0F5CD1A8A2366B5129B4A5799609909D43968BC296DF77592E8FF5F3ED02248279B761A4397F6930D30D47C31B657F8D1A13C99210CB3E17E84D414FAE4DC6E9E182106D353256A7271D0A5D23050FF33CDC1C48A64BCDD6069F71522BA1D33D9F13470EC1D0D348EAAFADD2DA2EF5D1CA6B05699EC818B6FBD719F8D42FC0F1172574F71C468204034E24A68DD7F92E341852984CF349CA5059E69B19E88CD4929EA8220D04CB4F06BC9A59F0F0528C83D59D4DC36B17EFE9F0B83FC581CECFCD981F419A987D2380AAEAAD7684EE7EF2B920DEF9C0801781B5B34C7E6FABE8EBB4B531A476D970248F2E0D0F17B38C5E2C46B45779383180620C5440C2FBD59033877B84CB411970862FD2C47CA91757B33243CD74EC15E5A622F44940F65E3F42372F8B", - "k": "06B511E4AFDB9427A2296FD9BD7C6467DE6A25D78866F770C2F41462D299038E", - "m": "7B93EBA796CAD98FDBCEAF0B8F3BFF196C1F89125B2AA88F623A91DC6AEE3771", - "reason": "no modification" - } - ] - }, - { - "tgId": 4, - "testType": "VAL", - "parameterSet": "ML-KEM-512", - "function": "decapsulation", - "ek": "5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F1312", - "dk": "69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404", - "tests": [ - { - "tcId": 76, - "deferred": false, - "c": "161CD259FEAA7EC6B286498A9A6F69F8B262A2E2093D0FBD76D5DC1C9FDE0DEDB36581004CB48112F852E7F87F649E8A42CD9E0349E7DABDF0A9AC1B521C37EA5241370A8AB2911CC79902C95D28224FA8896AD715209ECDD5D784E91DD9D0BE916B4565F4D5669AEE0DEF931E9768294EEC5258DE8391ECE271E7E4CFD9D23A79FAC3A8E0DB5DDD6E0107235688BBDF7BC5D5632F206C63A0C9564F30965CA58C69FF92D25A4F93A09EAB9B9085947E078A23E4D9C13B8A56E73E18DF42D6949FAF5921F2E373D450C8C09D07B152A97C245447429481D498BEB7256BC47F68F9922B0B1C62D9C23F9F733DD73792CFC7B43CBCEA277D51B2B8AD4A4F522F642CAD5C5DEB21F3627F8AF4D3E5BC9E91D4CB2F124B5BD7C2F4A050CA755BDB8056609663FB9511C9AD83B5039088CC01F0DD54353B0DD7433F0C6CEE0D075959810DEC5416522BB1F1F65547A0C2E9CC9BC17F8D39D29309EBE79F21331B75E12AF2E93F03F74F7F87D360F1DAF86CED736092A211A8158859C42E223CFE2E6E553437D80576CFD1944E97EEFF9B49E5ECCFC678EE165268DFE3D3596B4B86204A81C6063B0CDCE619FDBB96DF7DE6E0BD5270B4D59C4DC508476E7F0708F98C7A4F6645C49D06100C760C599528D1B8BBFE628191CC083C8D225A093F9F17E35574986F86BAA46898B589F3CB7DB46A45F3EDD4FAC20808F4CD0249DA693F8FABFBD4E10C02C65BA8C8610FA8C6DF3DBAEB6763DD482AF41558B1E15CC9C7A72E071685AC19A051F19245B9F77C3038A54E2958623EB8105955609E27D67CF72EC5C4A8E9B9C2924A9E2298508BABA13CF111FDFB062C9607AC1AAA6C637310A8894BF0B96F0C19136186B618DFFB275528BED1CC2715DEF412F77A3CF96645733B048A78474320D1A380F5EEDBDA21FA0125C91D3C37C54BF3752A1F8471C81FCAE2D3EDA966E14E66F223B054D79848FF9411D634024A098970ADE6A88B5F9069F760584DC4CFFFCEA8ECE11BB5566BD2360AB707DF2D21B67488D931F020069176423E6944490CB385E70B358A25346BAFCDD06D402FF24D6C1E5F61A85D", - "k": "DF462AD68F1EC8972ED9B02D6DE0604BDEC75720E050497351E6EC933E71F882", - "reason": "no modification" - }, - { - "tcId": 77, - "deferred": false, - "c": "5C26D456C6C7B0E8DF0B125E5D5428FE393655127A5E05BDD1BCAC14C47493783097B6185058FA700555DD8AF10F0F979A39A603826FFEB0B44E9487539F3F1A07C673E96640DDF754C8B98CD83473568B49D095F682C1ACF0E160AB93EB41A16A57D53B419620D351C837315080D530845CF8D63CFCCDB6E9DFBE220A2C14221AA392E6337FA364DF0D2E0398F15AC3DC822B5DD7217081107A45C8CB8EACA51E034117962AEE7EC0EE212FA67A5D4B07D355A0981E4285116ECF5CA9FAB6E3105E4DE4AEC5E32938A1EB91E65CE7B39C3B9829AA1E72B8092C3622E519EE092FAC8106D6597CEB941C763288723CB55044A36D4181052A78B424B0DE1B0260F624A8D3B317095371EE9BEEA9272250D598AC63C2138D23F99087777A902EBA2163171A07546B72FCE7F86EE3B1DC1B8EAC85440B8D241742C3771F91BF981909E4F3E2505C594761259ED3AADA6AA09181B99037A395D66E6EE4BBEF97DE6BA36C53A1808CBA50938038C151603105BD6A4199EA44BF4B08961672598CB708F896E03CD9B8F8AD89DECFBE6BE0EF0006B7BD2F4AA6EB21C0218EDE601D46924CF391AE3A44E43D96EBE84A630937C3409EF0710970C27E3ADD4E64DC64E83942ABEA9CCF498EF1FE72B254043D2775A37E0B5DDD3F596EA131E0734AFA9D0223F4CD9D1AB7304CA979AD37F717BEDC3A9526F8FC94433FE4614F82E709456F39BEE7BACC84E5A70114AF1C2AC8B9B3FAA81C8F35F5A5D24189E1A457F58166473F5F1DF0170AAB5E4AC8FC719F945CCBE6F2FED24B23321D95C4C850B278B8C4EA02E3098D5A599AA3D842CF889B7F284AC5E6E66386D63F2C860B997966B4DF2C32288A50045012B7362727B856AF4F8258509B563758752FFBB1040F3C2AD8B0DED64FC15C95C1A16DE0DAE6625A9EFFCE190FC7F3261D844C114913C6B1152A258A37761B81879B59C37A1DFAC07C3E934510B45DA44C2581A79DAFBF00FABB207306269D9B74B93F4367B3BA22CCC51B362DE16E49D9FDBF8CFF84F6CE6892CA2245D34CEB9C8759E702832B66A572DE9F3016A38F7328700F96B2E947", - "k": "A4A24E182FEA12FF128AB2D4AFE6569817513FFC547DB70636752C9C66C002B8", - "reason": "modify ciphertext" - }, - { - "tcId": 78, - "deferred": false, - "c": "79E255908B83DAD198AA6EA7219D5C170DA8548B172A2C28D53EB890914E16A6CE4405E8867112D35228DAC037743E25D26D720742C95935218ABBD93B4EB1C145794697EE761EA567BD561C6F5C076A48A34485539C49D23784606432B4913640644CDEE799961E5332E9502E683FEE98C9E1D071D8976E7F652EEE92E736D598F3B4D7217C0ED30FFA7DE590BBADCC0574A7280E502694A13A4E1D5D8837633A2EABDC97F36722D772A380595859134B9ACE346360860F8E60EACAB4AA3F9CF1DA73B5813F773008E0153B1BA0A5940DBC5C9E71E9A46BB4EA04AA9757E8E1AD0209C86334D05FCB611F3A00C7D983C7B9C160B7807CED18E5BC64A52462F4F9438199C2E4C6E9E70EDE2614913BE6D0C28894319B7B646444B5C86FCE61297EC11B21D216AC79159801ED3181667B15A7F30873BFD5727802E7B6588BDD04A5F7CFCD47043E600B4B3A0227E924E2CB92E514547BE4C1236C7AB2139F986AB956C704485DE570841F5857108D2AA57C535B3D44D0535208D501A9B56FFCBE8FDE32B375B90A5578EE44940E1E1888C21A4045D0338149D4C80CEF47BA25558E1842116E1E25499714163C0EE9A95A87A27CA2A61C4BD8D28BB04DE34EFB6E44FA7026B158883019B89AC4A5B5CA8F347A3FE892EE3949BD40D0614B9923052ED174FFBA720F516B6FD1317754A95520C66E3907B32A1648B344C34B3FA2ACEA2C8410DEEB40483529AC7D83351D888E968E457644CD76B8CAA55FC25BA1359F4A50119B1E69242DCE30E93983E50285DC0592537C6202F2E3C9878067A1777EA6A4E5ACC31614AE52787454FEEF503B82492828A736BF22E3278CF2ECAC1D0E11EC67815046CB4A66A8F48D04D4FB3C91CE7C251B37A8F3FB62A37489FFE63BDE22BAA18D4AA5BCCC0D8C709786B6C94D268382B649598A7A6785582CB2C02A2E9BECE29AC919785CCD026ADB6C9D8E85C3332DA956DC20B8470F8DD78B47E19B49BA5B27326D4937E93CC3453BB67EAFE42CAB03A70960DF236C04C344CA7177FD1E72E7E0A2C10D14F0C054337BD14152D4AFE9BB6243260E696EEE1327", - "k": "3B506D5A3BFB30D82FDD45B918F032A4023B9692D7EA6426FB2ADAB7DD5E274C", - "reason": "no modification" - }, - { - "tcId": 79, - "deferred": false, - "c": "D980E3002A28401678E1641E9E7A34D12CB2B4C9D986C7DB0FAB941AA83E43F42C44368138ED65B7A917B22ABA2DB0FBE44E5E9E7A3DAC3301379F7152585C8C7195031774CBEC61D8E1E093D694970B5377DC94CEDC53B6D3802BAF1C6F9152E05DCF66C1643528155C78118DFB00646B90726C75131DC934DCBB706ADBEC64E07F0D113BF71D4205D8E47DE67B9E01B224B82CA24405AE5591BBB1307D44E405E3866B1BB51ECE5985EE95D54568A81E7F285596DCAEBDC807EE6C8322EF2100EB38D10327DF92BC10A74A2D44842AA02AE9101A24736949D116CEC81F30C3092AAD941FC7F4BA10670CC0894A2F81E3155B9081004B4ADFB6532A1458F727F418D3F8F228E7425ACB7A4E4A3653529D1B9F72E57B8AB5852E35D0093B548FCC354A590C256B50BCADC30B55B5E05A3231611C93D5E34775741374F3E703B6E6362B35A68E33D859918D93EC03633220C61E1B81ED7AB1A5E46D4E640A9DE4E5A19FD11F0C24C556FE8D91F2358E7E78033A3C9FBF68C99DBA351F8F866CFF14E990C29E4A47579376606EB85A9D07D0BFD835C7670A5F4F2D4EA62B2BB13528A27BA3420095B852E3B73AB38E3CD068E276D8BD7A0B85BEFA48FEB72EBFC5240408B069FBC28F48B3A8E6556D7C601ADF98F0E9D64108F0BFE3C3B56C800D76E6DB14736809CEC22FA811EE92EA7950421B22F613E1349D259CF877075D476798C66FF58DBED013675BF6C5D3704528FBBE91486D7E956F785F73EDB6EB42861694F5C27E318C7B481377770125D99F236875D5B26CC8ED9859393BA2D8531E25FD6E2B3560BBC13176EBA638C72626C32D0250AB7F7EFFE661B18A641F75AE279C39771C7F23EAD50CD3AE461BB0EAACDDAD4F9C6436EDA5F2348F0ED4CD9514310AAE609B539368F53EA787ACD630080B832221B1CEF67FEB63CD2DDBA25282B020A3CB418130AD96D66EBAC09F09CB35BE0539B44924CEE15C6DBEAEE04C5BE5B9C43535FCA64B32BB204497AF175513375971B15F107F88980F0C0EB15D34762C98198A94EDCA385F32FD82CE7F6FB36F12B742C1755417A8D3F7D8A9", - "k": "68EE2117F8A66503091AEF490D1B9DC9EF3B3E62B97567F46A5EF2328263E5A6", - "reason": "modify ciphertext" - }, - { - "tcId": 80, - "deferred": false, - "c": "E1E906D018CCDE68680DF762DE4612106E918C29FF5D576D8FEF01D5241B666C26CB7B2F80793146AEEB9308511D9BA264A9A05D6621425730A50479B889F8C6E5AF66CFC9A3123D3B7335C06C8CD2F867484240E8B6C19EFBD3C15C33CFD10EA482D1897A516D07E39C3C1AA866C10655736F18689ECE7359D91E6EF5CEE957930258CD890C09EE1714150347A18DC97AD955B60750624755135AC81AFF8352B701EC5FF50AD925ADA003A617AE64DBFD305038E1E40108C6F12CCDD7738A83C9F7A76164F670ED4756097426700E51BA02EE36BF12FF22A316790F2C2FE7216C12F03023D87E2ADB99683229E77D6B1938EACF10D8686CEE46127CD7652A33FC05414FE370A159C516D250F7D345BAE5E1C9628A65FA9F5ED9E39FA10A316620A2D760C5DC128A5C6137F193226D18B5E013E300A41B1F2D1B47D90E3DF8B4FD71A794FAE0404570261477B32DC80CEA32F2DE743ACF7EBDD41EDBB0119EAF7F872A50A5F4C92A8B85DF792DBAC764C3A9A5A5C12D9E3913356C7F5463BEE9BD2A739FD485493B1C0DEEF716E129ED1E085F146E0D70A7E58D924F576F948BEBEF7842ED831FFD58B4656F91686B4D0F832DD3A4E6FA9F11A4870E9602E0DF0EF4FE9312EC4C7EC216D3EEDCA2076D0F0B5C9FE139145222347E816EBDC1AA70CBEB5D65954427A3DF6A78BEA86C410462596950AB8798F9BACE51A46A544C1BD17A86C2995E3BC82A7F965401A599103B0896E1B9EBA540614CE8F218DC7290103A6044E87069286E5BB18CBD89EF562B6AE1C7353F64D8CED183FA8D05D6B6A6633751EF342D839562733CDC1977684317EBC71378EC02B298671F76EEDCC3041E943A76ED9E0C496B798E10B59BAE17A195544C05CD1FA6A161358EA1D4DC7DF454220D79B235C24720021174C1BF47859CA30BCB57FC19CAD92ABF24C051D48B3D9D46779F910D26AAB4543DB2A0044BEDD491E1D72D8FDF361B50F1FD10AF4668D78F56FDC7E96CA16DCCD9BE8C1819DECAEBBECE41C09093DD508191562D6510307FA4685144D9679E84F58929D79E693DA041B12B76F629912B1E49", - "k": "B5191E505481428549AC5B5548EB747FE5290D51DAB6D49BD15CBD702129EA45", - "reason": "modify ciphertext" - }, - { - "tcId": 81, - "deferred": false, - "c": "3EAE23CC5F424EDC10108FCAE8EA3AC2BE8E90EB6AFC438B5A7DCD8E149AEBA25F0D5B25052C030F8157CC5BFB876A62F6A85B6C1C954F7C0F99EF4E3AE4B48C1CA9AF035543ECA1069B067057FEFB1E50FE0374F4162F0628F1D383A8B111EA9DE854EF33FB79488AA81E75712E5B9B6485290F0956B0574A6A9E1B4D677A832A85717CF7FF5A9E23B205C4FBD4ED7C2F7C5D91F46CD6A1EDB692750A4C1B11DB15C5643C7572FF9B765713C5C97C05BC2B861997CC6CC2C4D82CC62A32EA361630454756138C015D5501E362BC4E2B03A7AD679293658E45CF155B1C4F165954D594871CBF556CFAD2C3E6EB238DA3FF3A8140C5FCB74A278ED495DD14849D4C874C3E1F6E56EE657238F4E927FAE4588F1628DECE45C625AE0A6137868B9E86CFE29CCB4483CCA6FEE905F084B2B03A84DA421417CA5087B19654C803CF072B3C9E37A70B24E30E2F52B1DFCB6817ED05D38BB6FC7558B9B96AFA0CDBE708025D8D0454B90767753524CEEF8372150480BD104F1B7E659AD28EB155842CA81A55E81B707DAAF2F42A0B1CCE0B3BFF23F5ACF984ED20B0970ECF973DD0D5E33D34FBFD1672BFFF6725B5F1F869945FC67C5D01F3ED1CD8CD43A2008181AF7F65B0922D4BC634670AAD8A23A698AC3675EB3452DCE23D7E1A130964CCF4E26A9CD3D424A54ED7861E2D807F9C98E434A78695EFAC8BC86C69CD5911A2F52B5DAF50866151C5D00FAFCAB6219A9BA675413B4BB28619CFFACA38B9ABD1C3647BCE412336C02044EAA752B79248EBA1A7AED403801DAE5377CD55F517432B677A75DE4D4B504EBBF6453E319BB6EDACE30EE44810332CC84CBFFEE2B20548EEEEE1CA131AD87CCC284B3677E7F632D69F776060005439DE5648E466AF68C6616C63144451126D10311798A9B311064301BFAC1E4641830B1FAF4963F14A740529C360A73A351B6D330364BCCD2B012CD2B571ED243BF63F2FC1F1963604923B397A57680290D413FE7413B2C6C01D5BD6A0E314A644ECB10C69418251F48D3C3941211CEDB083F6FCDE24C5F5832034780B539D3FB1493C631F0C10F2F50262FA", - "k": "6262EB082F7C05044FAD90335BF60D117E52B382BACDDAB97D776CCB427AB672", - "reason": "modify ciphertext" - }, - { - "tcId": 82, - "deferred": false, - "c": "B3B6B84D9A33C59758CBEEF8EA26540D4E3D4A45BDC623CA1D0AC05D8E780D2DA1FAB26A0E250527FB0B9BD56B2A0686BD0FD310164A17244374B82FC9A93FC0AC6067929C4718B2054C7AA4AF1FDBC9EBCC55A787F7C0B98A8E6181E5604E8F7108B181AD1385422EB747286FF72BD1EF650AB88865BFC37EA5536A220C29ACE17F8AA82A77F92E0A031E526171C44BD5FA1E7946CD063B1A7E113FAEAF92015CB3CCFBDD9C5E0329CD3DBD1B8CA90EC226ACC27716615B5998E0F5A5BFBA347FDD3DD851682B8968858F4A73FE5FD952CE7FF597185855E4B7F76F44BC1B24DB7C8C3A37217DBDF0BA7168D91B59DE9EA219195D29A5C67327D51D4E05131119C81722794D825B9F01DDA93C74B176545E32E638243891EE09E2AC1A9693C83D4BEFACCF25C81554802FC422C75812E18BCCF4D3CF208BE6EB16FB4E82C4ECE33C838A0B3D3EA4C027F41B4027643D9E4B6A7EFBD8D42A65B29786F4A00C16ED4492F4E945469C6E03A9A297AD9763333A2B9725DB5C6F8DF1CA7B0E77F5E6364FB6E8E528578350A04E4E4617E72E5FD67FE029AE2D738D8DFE24730D9D737D8E30ADCB602102FE2D99B915C9B04CDA463D444ED9C6E6A71BCAAFE503BF1D15270DEF8B9D7AA5557177EDEAD75E2FB01A4635A46D2F95DEA6314DE4965EBA8358210F79E64933AB4B6600856124363A47C6063433BB670266AA8FB968D947AD96D97C4003A50B0D1119E3A73E00363AE5EE85B5815A5BD944280031F0DC9B98F1F5C589F259A486BFE26EE1446D937EEDAE41275AB72E0CD15EAA6368F59686DE08E147CE2F5978B366D0A4F98ACD7D4004D1D0A4897A0DF5B1AF9F811BBAC64952D10E36A3EF78D379EF0E95DCD2D804C07AD8D1A8882FE1F2FF188F31B886BB597FF16F4D597EB337319AB4E81565EE4AC0A9BB3B6C3184C9C66511D7313555EF703194A747D0857DD27F92A6DE12DB311828B684FF3F1D848D5E92E0EFD7BC6B3EA7039296D587A075781880039A7C0DD6DB66EDEE3A22F7F2EF02B267429F6BEE16F214A59EB96CA79EC5065784445ED2FB631BADF6645991736BE7ED", - "k": "94EAE21B192F9D8FEB94E72B8F24BB0E1442F1F569323B202A497DCB64F9791D", - "reason": "no modification" - }, - { - "tcId": 83, - "deferred": false, - "c": "FA42A8B407B527A8CD9351560BA4DA60756B27FEF326BC549B3A4429B2E58EAF22B3A36AE554B416DCE209E8CC708846312992DCDD43AB177347363F81578B94F451F1D046233BEEC6B42C9E0D55F3D741A55F7C564C4A9D5ECF6B067723E4403A17CBCFAA00E2F8D2EDFE1E236AE861011A5DB659042AA23BEB01A0471D178DB91039EEE5FC7EE85AC6FF3845959E5001C61CD1756EC681C97F4A70887884157D664A505ED7E4E1F4598EBF8BCDC0BEDE7FC0A89B3E14237187CED97BB0C0E54D21F4DF47BC8FC3F863978DBB673835D17931B7819535C1ACCD8706F8726BB0A0DE20BB824560AE5BAAE2F0BF0E3E676FF74C681474534C857837E7040C33B7F031AD9900A29DCB71BC305DB0ABF92CEB5DD2EB8E644F23AC0BFD8DCD2B44101FD7CB8A287318979BAE754661FFB13097B2A52B50236094693A754DC97CFAB550877A4D8C6CBA8B4A2E3D719ABF0EB13D40976B9E3F6C433DB1E16D794466D2C023988528AD0336CE43636DD50FA6A5E899578EACEFACA5FFC5B6FCC8C53E21503B83ABEDF2174FE08B4B960476934C5D6021829AB7AA7767492FAFBEE492A08524FBED46E8D0451C6BE1BE02B55653326735B0D8CCE951A5CF534E3547731EE36EB9BA38E0AE253B8CEC35001EECE0058E634A11F59FD6F21C1A3882E291F59B1FE3EC7F55315E0A65F9D011210462A8CAFC9779208452FD4F3B64FF456EA8588D2CB394A9169F1392646880A1C63721A2277FDA432FC6EBB61FF87AD473FF41D831DD95111CF0A1D69F001A008C3FD00B46F5342EDB8DADC818E6470D21C915F3E91992806E5B18DB314F9592E0EC8B8F0DEAF92DC89C194449A2539BE7C6A1B01B6F3DC496CF33CA25825B66971880652BC6E4FBD901A286C50D625F0F682B0B4CC769EB00940C45ADE947844175A3BBE8DB92BA6DAE5BE456CEA41384BB29A8C9D4E08F1375D4865A69A59619724900DDFAE48A2D12975C789E76104AE114F30ED4F836E46BCD8CA7520F4838651225894595C4F7BEFD7ED41EAF6F395EDE40F988CBDA7E08122A61E552801C7F3E84039FFF17E3534610D3434B996312", - "k": "23B74A4AD3F8E3EE73481A768E1F5CFAAE068ED38C0AE1E7A03159D2E9B0BA93", - "reason": "modify ciphertext" - }, - { - "tcId": 84, - "deferred": false, - "c": "9F972164967C0CD03A3DD68714FE0B4EE0EDF9ACF63AA068C10FA947F8A03264B4309EE61C8C9B0C03C5FEDFC7B77AA862DDEFEFE394FB09A2396097452585ACD0CE510324A03F36904AF07B765575DCB3B1A84131C352EF14C2572E39DDBC8118875ECFD7EF7D2E41D9C9BE858FF08DBFABF8A80BCF18FDA8735F440D9B8FCAE0E67C5BF0171B99800BBF0F3EADF76F9FD69BB0734F1356C53EA9CD64E86C14C084BC3B1FEF040E5FA939F8F0D5171AD02628AFD8B02DB7D7B5C3B32F1A8EF3AD4116ADD4502414163C14D49EC73E5F4B25C5BAAB82C73401975F2119C569E1F2873DA202F32BDFB76F9AF49F22604D1B1BB173DDF6ED70D82B360C13822F5F9BC4C4D5F2391E4FB6BCB723A56666087A55E033E50202EFBBE7DAAF96AC541C855AA4154E37CDA55B1BEAB005554947F781512E2873B5CD8B118EE0932DB2FF427A15BD114D7DA79C7D899FD820A0222DF90D8E85CEAD8A1BD96A88D6D58C0A4FBDE3AA55DFA1E4B12AE6964DEDE20FE337E4BA5EE8B67CE1ADAE9851D021A56B999DED62D0E4471CD928E9AA4AEEC5C878199149D82C3CF4FCB68F63DF27842C37E52182A7E3B332F24948F3646874326B4FDF215524A1095A224F6EB02355974A6DE9746824A3954B700903292DA43D5DD51DD9D8E98E63DD01C357E4913855190049E0F1A8D9725B095ADAC4885FE832E0BEE82BF3DC355668093B475FFCF7D92228FDEDF0451C441B345372D6EE58408462E2C3BF22A095E5E23A159397FC959C126CAF936A3E64552003FEB2B963AF7F915885445EB25B934D659900DD0506A5FCB7168392824945AABFCCD01D9EA8A2256FC8E7AAF0C4243025A9F47F295F9D2713D5257D626057E904E34B8C0530A11DF2D15AE6BF1ADA6971B233B5DFB59EF8B9EB813E7E52794883BD6D676119B5B86333CBE6427F97ED719C432127805A9790837A1EB04B82907A59CED1286164A9F02716CDAAEE48799599CB09F5CA8BDE83CE8278382776CC3246EB2C0EA91C1A9D0CD7406B419A22CD6115018B9641405F9F44E13D2CD6AB457825326FC5CDE85C94DF86097BFB5204530FE8", - "k": "E9A6006C6C4D5A51829AADEADE89CC104358D0823BA8CB5AF4599D59E1679638", - "reason": "no modification" - }, - { - "tcId": 85, - "deferred": false, - "c": "082411FFADCEE22B6C33277C32130E4C77CCB1849A2E7BDCE47EB519CAAACAAAA8DF129C5D876EAA7495ADED159D27F525EDD5F1F86B7A4FD50AC0B1F7B07C23F726D96F82D17818EEE6F032D0AEAD04D0F56EC244218905FD779268B259E29BAEF8BC66B42F47DC5BBFEA06620F38E0F373BA3F598CA7244A9F5B6823CA293BDACDD6D7B2E49BB2D00D1811C0F7FB2736876699D3F115C1D5AC58EBCFF10F514D863A56901F3DEE1328ACEF5D37DFEF841392BB29A88324CB51820A0CB30A4C222F7450F321B6617EEE7E722004AEBB5A52ABC3A984B8A142F0193EB90654FF86B8799EF7BDC01BBCD7C151587557334E01B833E950260C5E126C2BBF35EC030BBACFEF2812819A20960A9CA4E8D4836A7282F8F99AAC18BC02F6275582C7D1E6197938F67A80FB2363BF77A96355FA9E0AB19883CEA65A3010795E4A48A8B22FD04EC4578DA4452DC1B851C03A93AB147F3A34981515B75AB80D10A96570C2BF9ACB2E1662CF86E077EA455ED1B130D59CCA1F603A3471C408A342C42BE1AF6BA3E096E78CCF36CFCF6705078800E4E968FF372CE836AF5090E2442CF73E565146C69CBC0F55DB89BE1179CDF24DB6DD2C73371B00BD8CEC89FBBFAB3537DD0F50156FFA2D604BD135B91728DC93AAF31EBB51BCA15C02270D93051FBC0CF006C57F6BDDF5B8E60866E7A051358C4D0363ECB9A5EC3B6C745C41A3EFA2887B6B5AD8DC68E3C3FA17291D3D044D7085C6E2D3EB12FC3536CA8A6BEAC7B55BC2DD77B6F102C577B988E03AD963FF34CE4DFAF5194A05F12606D8E62FA7E20329E6630177BD60BCE780E014A856207A2745E5A22801A680CDBF0653EFC71F263E795AD7C495A90B7A5BECE0CC3F879B411A39A4346C677F53094298C0B2596DA1B136A32415E68A249161217414CC0F5F4D40614E162A3A757BDA41A80FCD17202AE062832D971FFD0A2F66D5EE94A26B1B78582E9F79F65A20D94EAC98DCC54D62B191DA89108126143E810AF6F8345723C69C009C481837FCED2408A8E37C96A248D7DDEFC7BBF73A5A91BFC10163813D22B0B26D5C6E380CCFCD6598844913", - "k": "3136E97F0A1CB0208B1CD89E510F2A37A5412AA5A2012E24327572886DD69408", - "reason": "no modification" - } - ] - }, - { - "tgId": 5, - "testType": "VAL", - "parameterSet": "ML-KEM-768", - "function": "decapsulation", - "ek": "F80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41D", - "dk": "1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F", - "tests": [ - { - "tcId": 86, - "deferred": false, - "c": "74A26C7D27146A22C7EAB420134E973799CEC1DA2DF61AE0FA7905A3A47485A063076BFA22D6E4FE5059DE0A32E38F11ABD63F990E91BD0E3A5BC6E710DFE5DC0F6D4A18147EBC2E2D9B179374D83692C53EFBD45F28A2A928C2494F903576C410EB1773895EBEADB119960EEBDA9C3C710795A6D9B781FC58B30D08107F4E20944A382AFB079F31D21724F2C26E6A53412F0A908BE7586F2B3D6D7C1DEA0270E98AA209244BD88ED68AAE01432342BA5F49E015CB476B5B78D15EA77A354CC9E9FD07137D8760BE42FD4746C62C02028E7B405DDC95DF3D021921CFEDDB3D961B957ECA302A263DAB2DC117BEB3E79EFACFCF936DFC09FC0D19C358D724FA381EA06CA067C384E944302C3907AB15A1DA4B41352692ADD59B061541F07EFF25EC42F46E1A0E370CAD06FF3FD997D4D2C5648AF762231B382D0593401936CBA21551A2AE30D8E8EFFCF43916B83138BB5E610364429879FA9CDD5B7D3CF2FEABAA1DC8D50CE69402E21103E795DF7074D1FCF65F8A4E18986D5417780602C63BE5A044863384BD3D8FFB685EAC567ED8349DCF2CEB702B7375B145729998049D13E2CD466CF2231B9D3A20018EE908F8514A6C6A89DF7232F91FCD84B81EBC8BC539E9A37A4324755564BE1BF4FA1FB4571E0ABBC9B52F9D090C33BE599DE6C8532C7CB7EC8B4E2D3C07505280E99923865903FFD18BC13B9C8164AA1EAE84E38D3F57FDB8801785F105A6A8574BD2FE9BF305848E525330BC2D24F0257E47A4950F433A9233E8CDEBA81DBAE7D8C1A06D01F70DE6EF663207D84952827BAB3D451CBEA0990007FBDB4240FE899A706F7C1563E05C70BE9D575189EF83E0CF76195F6652491CCE04F1CE2092170A92E0DD7301246A4C44FC0B4EE6AAA63FC7027840ABD2EC25F654589738CD38B9E10B975CFB6C1D2EB4DA97736998F84FDDDD810D72DA3C5AB13507420DDBFAA4F7750C1FAE9C7DFB30F40A12AEA689FC78DA900020E3ABB32A364D5C6B3C7544A1B5734A41E95C8314B448CD0B738D829AF772A8F81C51ADBA2D85F326C8F5D6961CF12D44A9BEDEA00D1DF5B48F429B1CE0C15EA5F5BC10B017247BA2C6BE922B0563B8E9698677CB6C45CCF2081BF84219D2904C11FF92199F8AEFAD62D8608E200802C5A07202CC820E9E520E31BF36A83002ECA4018B0B3A398801562AA86C77AB0D50A8FBC3768B0A643B97E7F9072168DE29B8175999C9AA48D301A3F0303172E9C7D4F16329D5CA9D42397C3982E10C9DA42DE88BD6C2AB91C1E71E778E58BB8F801F207A88A9B47F9C687AFBBA34EDA6D2899E4FA0008AA2B539711753DC7C07F614E814F683D6C037562AE1FBBE6D7D5FA54B7A6D9451E11B01AACCC3BF2ED64742DD100E0EAB2DF6CCCF937B6D5981ECA0E01F3245CF26A72AD1ADF066C8F5430D72F509963A657D85E554C14E26E8BEC5D5F3AB998C9B29F16B04747D80749B30E51FD2A7F690C22F9986AAF6358D6FAB8DED54971B32641DE2B258590EEAA6BF1F32324A7C4C983F49466D86", - "k": "3D23B10DF232A180786F61261E85278251746580BEBCA6ACBAD60AEF6952BE69", - "reason": "modify ciphertext" - }, - { - "tcId": 87, - "deferred": false, - "c": "39EFB90089F1DC32A54370B3EEDF2B12880DC7D657F0404E41F7DAAA73E7F06CB90BBEEC7544160768EC3B56681D057AE1DB58F0123286D3A8CDD0B414CF9894FDA1CFF3A37CF67B82C5C7AD3427F2F2B393978B94E524F33334E4A98AFFEA8D7514D6E12E85086E58A0C078EBA64435441F3E3702EA27EEA984E46893BB886572491F22AE09F8D50774B4DDD5CF478CB0B2D070437E86645EF62AA83599093732F81A75D1D5DE15C31EC81AC4D67852FDE089D580B71E3DB07C71394424E0936BF74D0C9405BD3DFB60B920E7EFA38C72D5912BBD301BD3F3709CBEEEB7BFD0767B77A8639913E8C228FBB7E3E13C423BF05AC65B7E75F29C9048F161AF1B4B41C495ADB53FECC57FED0DCF792050A2A586C33AA4A7F6BCDA9068EA295FB692BDCA756FCC47CA0A8C84DB5DCB6A616605F3D3A34C4D23EC14942492C07EF123C8D084DF21F3B2141D277FA16E3CF4D5A3AB8D78CE8370F411DF737647A2D6123120AEE1CCF7DEFC35A5408FA6013E94703E8E04C50BADCBBF2E1FF0FB82DB4AAC595B9EAA9E370C9C6175CEF20B1D0B8A4309AB91918451E6C8A6DF04AE468D446FD9E83F9252F145A2B44A19E7B27DA56044717DB5A6ED5F6E5CDD90208ABC324290292B1F2E84FB69F5989D9921DCB4F058DCAF7B99DF71B26BD1090E457767954B8ACC84FDDFD663D64027528077B3C9E370600942E4C1175B487FBF25E267474B5238576010CCCE3315CEDD5634658B2028F3FB9959D77FA23756DB4878697C9BC491DBD68986B9073D187F2A9E72C943D94C97DA865CFD9C23508105637FED62E56E745555909A49D23B86E620D48FD55A92CC2266C38B857F5DF9BB683D60B084819CF04F5BB8CBED05AC6F48C518EDB5B222F5E6DCBB438182A7BA3B2279E5856828CBE9BDA6009A70D20DA082D2FFBD092EDAD4B272E46D215B8ECC26222499F024327A391CEB007789757FF8FA8267429F0534F305F75709DCC4229803EA8E612F55890C5FDF8252794D5C9C4058C2258A5599BA858A02F89A6FDB35C4F2364A4C6B326A31F7D04F62C2FAFE51D280CD7A4CAB66404FDFD033EADD07974BCAA7F0CB7401B9484DAF9F325B6BA53FBF41219384B264F24AA8D65281693295E6F71FCA885F808026829A3FC32DC9603F0CED36F0B58A296B44ADDA3AAF10638C31F354D1A5AC34E77D4D0154C9546709E920258F73E039FBC223EE74A270840165F64E3051B10B5E63F9ACCF5D1EF40E43F5823B15F8C25CAFCE698A64F9AE316D3905B8E510C56CF7544CA94719735A640F2B8C3A2B828A04E0568863937595E5B9DADA33533D9D676AA657FE69152E93159A00C5962F4DFF9C901A9AB32DB28B93F4BA780E44A2F73878AA76E112E3490205AF83000EFD889FCEEA5E87AE9AE01EE1CCF6BA0461A8D8654B7702C09BB41C4F61A00D05F031B244EDED8D1CAC7916BEB9AA67A3880F4C3516A8D8204932EA00EFB3AA20369FB6BE404843C7411E88428568AB9A39124EAD115298D49C998651E5EF613A6819336683", - "k": "1D2DCACEC14CBB78FE9E418937835EED088CC0683300C965EF3972081F01C4E9", - "reason": "modify ciphertext" - }, - { - "tcId": 88, - "deferred": false, - "c": "A5C81C76C24305E1CE5D8135D41523682E9EE6D7B40AD41DF1F37C9B17DCE78076019A6B0B7C95C9BE7AF29507B2D5A6987C8EE3259190855243E6E56F5620608C52D96FAB103A8700FBA1A87DCA6078118A0871762C9534C0C0C3978C91C3A01F0F608DCF757815438FE8957C8A859183B1B6721A0865BEBC799D4E5C0E7BD3EAE4858E6AB6A2E7658ED80D4ED158B036B93FA03AFA6AE3136CF3D693C911BCC75905E5B0CB2865B9E9884522A77777613E53111D5A1C7D3DAB734CEB03657AE0C89763E99471054776BAE7D51B0E73A5BB35AEC30FF6BC93684916FEF1162586452F426653E2CA844D5744307FF9AEB287A6447783B21A0E939C81421D631F5DCB452E51ED34E3DAD1CF504E0A3B0F4711A8DC6499D1691D109569336CE1558A4C0A464E2087EA8F9E3B18F747EF61F4576AEB42B17CADB7F0FD84DA8E3A6F471D95EDFA65BE9E6C9F6AE756A22A4F1A5C543C26BA7BAD88E16D5F5B7E12E2D4CA34B3A64D17F87CCFC4FF8C5E4F53752A077C68721E8CC817F9FF24876170FF2AF89FA95855A5B1DE347C07FDDBCFE7264AA5ED6401491561D831538F852B0ED7B9E8EBAFFC060284F22D2BAEE56FA9F6D01432A115A2D6A64C38AE0A50BA362FB57B53E3E855B83CE8C42274045599F65FA6A8921D85F94ED230B516712DB6FD2FF28B3A3371D9BE058AE75C2FA591B7EC3C3DAA1F7642BC26C324C08090607E6662154DB37CF747967A1F9FC29089F570EBE60EEEF89FD24481028C85AEF1DC3B09F22CD3691BBBB821C7A8A0F35AD12BE1DD199B977048F3D48C16BB2CA94CECB8928770D5BB329A0327E0B286FAA1C65281031A31C84F2EDC9C04D475ED4E128E51EFA97D0148CBA6C95F674C589F301C265BED708E9AD8DA3C5CECBDEEED35EF1E253132BA89920D786B88230B013BCF2DC92D6B157AFA8DA8592CD0743D4982BE60D7C2D5C472AB9FA7F4CC3D12B0EBAF0ABE555C75805426844DD9428643F84406A1B8D6FAEDFD8AE6E73A72772A2159ACABD972AEB6F7DE091AC5FDD7F49A3DC6641CDF62446B4B04A31F73B80A62F80A404A8CB18CE3E65480EF7B52BF0091117E5D08EAE1B0AABB72E6DFFFF76F6E44BBD7EA570D6604BC2E74318BAFA315A38861AA1B21AFB2A53F2614F1D640075984AE62E2FCA1D1B4DB369F15705CE7D4DF8AE98264501051C0DEF21D645D49625AF02CA428D9F0C2CD9FBAEEAB97E8E9151662B6992B4C99AB1B925D08920363373F76D3FDF0828CAA69C8B1BDC6F521DF641CF1C8A4E7EF0C23289A4E2CF18ACEBBE4C1E68369BD5235120142ECDD1A73811E2E533A647D7AEE16DAA03B683639DCF1E1F1E71CFAED48F69AEC3E831733DA19CEBEC1DDBF71CBAE0800F2F6D64A096EC495D62F4344F7AA5621B322353A795AA099EA3A070272D053D4653A20CF210EAAF12CAE6023D8E5118DF04B384A44D1EDB91C44989EF7EE57F2BF81A24BDC76807DA967EE6525410C5C485067EFC3D39A9AD42CC753BAA59A1FD28AF35C00D18A406A28FC79BA", - "k": "DC5B8888BC1EBA5C1969C21164EA43E22E7AC0CD012A2F26CB8C487E69EF7CE4", - "reason": "no modification" - }, - { - "tcId": 89, - "deferred": false, - "c": "0BAF0F6E91ECAE3199F4921631891A14C13B418B53384992DA3A8DADA7DEFFB9E1E5F559D27344B60BE81ECD01CAB1E316573D571ED46F59248F4023DB0282207E730549CDB60E793E4CD17AC6F2800E2D1FFB83477A6FE1D73992682123EA730C63269DB13088D6DA46D086CCEA2176398EAC663270B8B2F337A55E19F4C500DE066B5441794C2D0CCADFE5ABDE7D93FD7D6468BC4F925633366D9316788B90B110A4D99485E7E578537A267744FB266A4F243FA02E3A81DA67ED477923B36B37BE21DDA21EB51DCA1F0CE41652145F4C542B2E5C922617033608246BBE2B5250A368804ABDB2EF6C31C491CE3DD852AEABF6EEF1530F4C99286B4B595D57CF3A99580B59AAA2C55E080B5230EA19CF2701D21A37FEFD6F9709657A21ADD063ECBC197B5AD068BE502A2E090D83F4156B671E46617BE6D6A17D0425FAC565C4A0E48966E9D900CB2C2B0D296E0BAA9D6C5E0514CD78834053058A97D3DDF81529079858737440812670E818C9891681D350ECEC93DAE389D534A5C78F01811917061CAC0003D2BEA390EB63FA0FE9BABCD7FF302D4B66567B2BFA67B20F962847D010AA4193CBE9F8CC1B14F8B237C22675B298A8376DFB6037BF7CEA36BDEAD5B505111F67730824B4964815D00F63EE98B9BEA0F2F47CC007D5606ED7F967CB15CCD4AFBC99881CFD297BDC2A509ED3CB320DF58DC4A5BCD1CB100B9D6418CB8E0F40DEF293DA2370CA729B0FAB071FA6AEB0F3F5D1925AB2DF732F98DDBFF23D5411E4921A1C506F2F93251E822C4CF83998B000FE65ED386F5745B1D4D91AD9F98B45E713C8D944409E9D354F42FDB9749A5107C8831562E683498C55E1475E552AC10858AB9867BF8003FB88B3B09F6E8AD8E94CE82E342B1780D68EC8565FC0684AB6C798BF09FA65BE62C37A0862ABFE99D7DBE1431B4CFE007B7EC7930B14F6D161BDCAAE2217D69D9FDBB4F882B9F464F8642ACD9BA018B93A8E3A965194ACCD96E661CF0CF4A2662076E20E8BC319693F1953DAB93FEB9BCAD666832DF42F250FADBCFAF742D68642021BD6FFD97720C3E5AB86D82CE8B14C0289DBF51B50C13CFCEC12A3922DCD2DE8473329AEB23580B22F9C36B4F06D6579751BE0593120F808F0E145D94D1DDBBE1D489B744CF6C35964C3DD96D95FB693543C69766877DA80BDE8ACDF62C366D0A4A553187461F671376F7E70F554965D57760CDF5C6F6366E33B3BFB550CC1F93D98D250F90D7D36BC01581C49417546BF6BBA9D10D41C0A008855F321547BDD5A6CFA2A2516F71415B5BC2D5FA1B9B79FDC7F2B78AA113375EC1717F0F273BD8CBEF59139518A4E8A67DB4D071257000336BB07497F72FAAC2C1FC0F553B2EBA53475F466A2B36AFE0B72B4342E995C544E6E14FF7D327F80E7AC6F65190045F380B5978F50E33272484626266125A39DA08B46256624CE34223BB17299B8B8162753812F2644C9A13C51430B02ABD188DD1A4547C920BA27CDAF145BDEBC6F45EEE3F2F55553010F7B35AC63A3C7C61C", - "k": "DCBEB5E4E8B14BD3031D5916BA03258119A5DACDAC850CB483BD7AA80B7038D8", - "reason": "modify ciphertext" - }, - { - "tcId": 90, - "deferred": false, - "c": "2513DE1E55ED0E862614587FE47F308C90A1F426470CA1293BDDF7B9DDD6C368DC152F45C71354904ED48E15A1CB449B4C45D0F201ED5C7D3A047A72F080265D66C47D39469097EEEABBAA3B07ED1F1AEAB80C7D24552FA8889C674A5D4840289DE6B0FA9A222E693708D1F252DFE8B993956883C07067C1C0844EF0BEB49F63534D21D471D6B727FFC59477F9E89E5BEB2AF0CBEB052F003414DA4070008753CFC0C6D0FA9D1C15388FE5886EADD3474F28E4682C0E01784A037DC3799330EA380767B0D0B6EDFC9730E04D1039548A6F83889098522EBAB684DA6FE26A4A6891D86D40FCD9A24F743D74B23B1596810727C81BB3F9F3BADFAE9997949EE0E24987FA182A00D73DCEADF667E90E5AE76A1F83A91FCEA78C96269F0C9501F1D4CE682506A7EA89302A1480E18CDC1F6D57B5312EAF808895B20897E9A782F916CD75B4981DA1381F14EB1EC248B27F0E6966A0CD75414A735928B2120615D88FA57AF5C40E61750F0A0F8E605747E7C32D5A23F14124969C072E949C8475E3108D689D2D20797FE14618811E9A497FD26B9E71355852D4B36340B61695E3745F8D07644AC6E2C18B3FC276D4D19DB69A7CF26086F172E2BCE1618A740A0C739FD504F72C2A72ADB5564BC85DAB4C9CE790D78D14D3BD242DF04106D96CE7C3B392CCED9B99DF359FD51F306CBCBD5B46B8487CD7B7EDD3C5C02965C84630DA1B6B8B317FE55F7C79E05CDAC9E863023DAF470E9C3FB8C01FDF3AEDF2193BFA69A806E2E70151ABCF96D31CF6A317C059CA8C7D456A8E5EBAA6C1283A319F188AAA80D8301E321754E5FB4E0B25594B01BC5F82FF25B064C766424D658459EFD7A20B65DB181811E6D5A4BD153F7066BD7757D2D417D21F83D7C4CB6A0703A42032F0FD198D9D8B0F91B359FBE908432C3286E1EF9D601702157EFBAB68E0E7136BFC90D26BD8A9A7018DE4C4BF05CE465F917D20A4F221A4EE78813A1E8A117C8470929701CCC201A85E7F18B6BC96FE80B1E074661525D3FD0CE2565AB11155DAFE4D3410328D6DBB4DD99A84FE96283D32322522B88B3AA2A11C0324B1D5556EF408D37B0DF802D163FE38D7C38916A26810BD175D22762353C3175DC6040C899E07A339CD4DDBD4D5549E02C0D691263936A9F63111412B60AA9F57486334E40B2BC1B8EAA487A094E45C3F77F72EA741CE225ECBE2B5E4A1FC080070A658FDF9E2B388722855267B30D94B63C3ED35D475B7EB22E3D2462ABA9CF2A86B738EBB270AB29708A2614A557E33A620B507286E5D4CA57E2CEEDB9965FF1C3E1777F980CDFB1445BBE0B6ACBA0216980F962FBFABE265B3ADFE8641088287468827AE601B6A165DEED39C0E8773BF2046BBF63634BDBCAF98358D25FDE475781733DDE8C6D6383D13B6D48FF1B65E2FF13AAA9CCCFC3C626935C5270F9E23A71A87CF2BD793CB175D23EA5FBD82C18A1822428C32DB9E31B94BE3144ABB00F5ACAAA431C17386719C3FF47C38720B1AB01889DAD877BADC9FC716F648FC8B551F", - "k": "2C37C49E94DF715B3C09E63A39E04DB8D26BD2B9072C9B21076BDFC0B608534C", - "reason": "no modification" - }, - { - "tcId": 91, - "deferred": false, - "c": "8A4336FDDB3F55D16ADBBE54C6EF0DB27F20679393D86EA4590CB6F5F09BC4EB76181A13C9826FBD2A7174BE8A11F13759EE23DA15337A4C5612480E0A843CC6D04F3A902E144EFDC0AC118BF8553B984E758E6D7ED1373B20A5726271C5F4B542FCCD6379671CE37A5D0128F55539B9A855172CA2DA3BB6823484A87DC2333F56CBADF4A694A5DAE341A0E3FBB3D852929FBAFBF4A5C12CD3494CDF910010A0FAFBC09B375BABFFDEACCD12E6E7BD347CBFBD0C84CDABB5004CA11DDC6D14C1BD700FE3EB2371E3293F7185E2A065532C3B6529E60240E7AB6456139D66745F17B94FDF2C54B13EE4DEBF1B77099718804BAEAAACD2BC60A190487CDC76AF2EEB906E4C9F2664A30FAFB65013B8CA393793B650CAC4A93377A6511D739C2136CEC59E1BD14584989A591E1F3B7F6D7237AEDB556880810FABDB1D7F8250B61A2D16A3337DA65AEA644D7E2226BE5F24CBE01C8A33A4CCA06F6F646A3F5453FE2D9FDEA8D8613F491BCF2AEA950DB1D9B43C7C3F86FA2F4A51CB44EB9761363C38723852925247D92E37FC694D2CB00248023D5448CDE2867125250B17388440C188F7E500CEF7747A101E0BF2521E2C8A2D04F42D834C0274ECBC73E94612CCDB1C4B908BAF63C09C945AD4645912A0666E9844A1614B7F34415C1842F9B1C7DAF7EE4459A8724B7050F6B5833341691019149F351A7F11AE2416DCD5B36F18B1A4B82CC3E924114CFC126CA309E319D497A594B0AB2AFB58C19DEF3BC3AD885B29AEAC81F346A19683B8577F4A1E0F30BDC85A3814CD1196E6B29E55E5C0E4E028872477CB675B2408E136D15E54C85E8A468423CB795D9348BFCC975B4EC20A23991E6E9EF91D676983AC26B66C71548FB46C4BF06E280D7C55E7B8DB90743A8F893F95AEB4DED1DC65C5E0B61FBAD9DA0DDAC274591AA6CF23C79C09414356584F0BE02CE9B500A3EE6BD4FA0119783F50E800ED36D3A4445934DCFD87A31AF3ABC02CAC39C4B28068EECC6D16B6FA187A073BA143209C0F38AFE100BC700D461B1B364ED298AAFDFC716FA6E3870E6258B66645091FCF9413EDF6BC79B75132A46D1DFBBCE3CE9B0558EF003929CC6E3D57BC4FD3092EEAC4ED71B7B7FC70D0E65901DC9196928C5B8CF4A63C62797727C192CF1CE4315120A57D4C8CFD03143AF8754432EEBADCADBCD26C2E3A14BB43A951AFDC19EE67AAEC5DE0722E9D11E3627AD1B624ADF0FB6FD2A6733B2B1B1411DD14EE87AD3BCBBCAD2EB4A38EA00575BFA99332400083FC519C3733F6EDCCAAF71D09A7164E18A9E9587A8D9B9A46563FD3F14BFA2F2B8EBD9FDEAAEF466E591F502151E43A7E1123273E5E0574814B20253A17917D7BDF8370BC50461AC8D86127DC527B8290FE386F1AC1E6E9D7B493BB7FEDEC9E5A82DC1402DEAE71B18AB4B658E43F707259039EB9978D4FB0D62839A0DD8E3A1183CE330D57BC7927F7CCF06BA10A0478B7E2EC818195171AFF75C29B283E759F4D2F5D55F0FFC35E0581D98E582107BF64A6D80603", - "k": "47033B02A6DC056FFEB5FC1E96205C166374AB84A5F3F7B06427BB006E71A5A4", - "reason": "no modification" - }, - { - "tcId": 92, - "deferred": false, - "c": "6095A951753A644DD898D69138B4E521A704DCFAAD44EB53E284F836A469349C5B9279248AFC57AC93FA34A643DE02B724615CF5865927FED60A6B41E4AB15B4DA3599F13D2C1996C6D6989443BE6FB81F5BA03BDD53462BE5812A3E177876A102B0EBDFCB16DE7B29B5123A79DD82E5CD47ABA02759FAF5401E3BF03144A90AE957EC04DB9864ADE1C5A700CEC7872CCB64FF931984DDC3FB8D4971D761E5544130278C75A1B04E641E070A747789A71E09409C155C7D341D5F828A575EE74439155930DF22FD7716185BDF917472432A30A6762C9FE1A254442F755804D295B1698B47A67BBFDE178200F9CC3D4C705F4AC1B00C372D468E16ED3CBAAA862A2574A9574A7280878BB82DA7BD1B2A58943456838F2E6AA9F6EF1827C5B24FA09DE07E9B3153B0F44A4F2AEA7610F9CCA92565740E7295BA3AC5764A20A44D4E1862E55B1DF7913B279F438B3B34E0C22FD90E06497F7DCF8D62352447C2B8C51C214796194CDF66D5001278D0D55F82FA31DAA72BA6CDA34E60D696ED79C7056BFE97265F3D1BC07719B745ADD4A83404D91A184E629FC24AE236CF6AFAE46295D24B431D819E366F51E1BB2B44B1FB7A3060091DEA1D416268CA550EE4E41FCA1F387E941DBE4EBAE222D3CF625632D1A61414038FD437BFA20005EBC404ADCDE2DC10DB741A3B7534C40822520C4703FDFB6B380F7DB72B725B330D0C20DF256BBDDC31E0EA20E636A9FAE310185A5081923BAFE041AC6FCD4E73F5F7237142B74681F637996D28C3FDE6052243269D19316C56993722EADF19A985E579ED559F971E69EB5125937EBC80ECD15A4F80D7067905A4D39C6220EFE43883CF22E9A366F8911E21D0491B8FF61FD07B733E707A08DB400E438DAA00D481C5AC62064CF47AFE3AB08027B3890E8C8835CEAF8128F9D887A6CB7FDE879D9611C01281A0F02DE0E969C9131F8512138036EC1967DCA45AA30BE8C5B1008113E17A91D9F8E9995C07C0B13A45668C96356F09C3E08FE4C7DF5F7230E0C93EEF08E8958B55E213718C516E624B57765257D21696A3458FFBA11DE708C4EE9AF2EDC5F37458DEC8B985076882D3F4DEB00BFD8E7EA4D57BAEAEC6BABC0E28C15419CCD785CF6ACEC96D1111CDD1DA9A151F59A7366B64A53F0497D3B5A8ECB60D7C220E99126CDE82938C7E131BD841300AE461A1817703ED5B0510B47F2C2980F1E11CFBECB524B295C42187F15B0C9F6B0EB1E70B3EC43ED955528B1E42E2BCB31F3A1CFB5E9C807E8D366E9227A87784748B277D6C885B1385C6C691B3DBD7841DD89721B3A8BF96EBA99C53D4BB3B41DB9409B992BCC2D8FC53E70723CA1FDC1341A3E608D7F62F2322C6A9BA1316639690A22AECEE364B4F13949A0310FBA1A0E35DDA5FF840DABAC55041B0931D9EBEC89B78DD930512340B4B5D0877AF546FF0F342FB76B647D604EE2E20207924F39907D6E72DD4A9A1ED0B6D7364CCE69981F56CBDEDD51CBAF6FDDB36E327AD65D4FE283D253E6BF3C7969FFF1F34DCC742", - "k": "F0CF9CF06A81EE545A33B310616117D6096FB56F0D4F7E49FE0A37550320D3C4", - "reason": "modify ciphertext" - }, - { - "tcId": 93, - "deferred": false, - "c": "2AACD2E6B884BE6A3DDD80155BDCA80EBAF0E2BF714312BBA30D5B367F2D95AC7BEC3965AB05AFA370A42A512B5EFE4B0DEFF3E163AF186B725BCAFD2AFB2BD2A0DBAB74C2BF9362E27D69B6B4B5AA6500EBC9316EA4112745F1C6E98F2DEF9132C7C0BFFEAAFAF994C89B96D3F436B875178963FBC18D2E06ECAF3871787C1AE93B3210896837EC1DA87F0FD8F14AB7C5CB2531E90F415FEBDA378E5492E1DEC8243FE2E8A7BAA6FB6A034D9C524E99D848A804F150915BFD66067C8603B5DB0FE29E27D3F6CA629E96BF3E9C77A5919701EC19646C69A73DFAAB0ABA28FE3E9EAAEB475A441B9B0D62B259DC6B77DEC964AB57D5D776988D54E6246C526F1E8EFDF454E7F0DDAED5363CE02B279CD3B554C251793C3A616C07A7BABA8062919A2B46C64C152BC887A27E382254EA6D50CCC0702B7BC0994BAC09B7891FA64A773AE0B4FBF8204C13A4950FC2C4DF60CEFED7582FD9FBB8C83442517BA0E3B60D9A04FBB24ABCECB303E3FDD37F1037741FD2489F632192A6B9C122A7344CB781A0F61D5011EB0251A842AD4838F9B8D52E21A783F0D839E8BA221CCDD6B968A2B5FD21B8458BF53C9C8076AC0C52C0F53097ED1C25C9F6F12407772D6743EB8E0CE8B1A926F0FDD0DB00482D9590675E56D4509CB5E5F32FC3B4A2DAB2BA080F9A7CDD0B611742A8F83CEE1B091E629D2A0371FDB5A64412B5FA63716961527640D02885C4A09B04A3A6F5EC01A9E0DBB8FC4DDD9E05BDB240AC4878F0D41461C4661777417D6150422FEAB6A39F156CADB5F5D3BEBE417BABCEFF5AAD1B7A624FC23ABE28B2AB2E8273E8F44636A60CDAD9236DCB02FCF87722C899AA321C564B25BC33B4976BC9603BB8B8AB18B5B04625981FB38B2A42722CE2358FC0BA99EF4B122C7B70BB347D0D482DA30638EF8B9C1D9121D83BCDBBEB2A608617054F4B3FDD33E9A08F8DF999A98E715DBF04F8EFACF123BBEB37B9038E9AD906E3C570BB398C10E6D36647A2B0B2731FD39F726171EFC7321BC67D936F7989EA58336E549A34B73F097E3EA2C25887EC6A2E9FED5D2CFF475E99F392162D959DE1C4A4DAD3C96542756AEC3367F7B2515F2225BF7B704B780A6D0B279B8B4EE4879A9BBB2F3303216CBADEA00D229C03E3E2843892FA8E5B0A600D0E3EBDD14FA229819CE9C10B8D5F393DE0119A5B509B80D56B06783447F931177123824910C9BFDE9A29FBA0252E69A90B3E717832866115C06EA73B033EC3B0D45DFDB69A76B484DB0BE7A81215B3817E1C02F9A5DEE8967B147DF9F63C93A6E396DE4251A5A706DFDE9670B8B2F6C4C3E2509142256FDDA905C125FBBB294EB29A3B4D9BE3B67762AFC049B96B3F41B8C31BC5D7B522DCD1AD12B252370A8A57E42F6A9AC26FF784B374DA4B86FFDB65CC753CD049F1A21CF832447E1DF7BA7D0D11E403FC18BC545501E16568595AEB6BD7811C214CF2FB1CDFB07BB32321F536E3896B6EF4D16130ADD71B271CD1027E35538D9E475A3A53DFEA430C151DF7D516CD0D9B", - "k": "0EA983FF9D76F056AA42BB772AA27C8A163172F43E6BC9BC55B83038E095792B", - "reason": "no modification" - }, - { - "tcId": 94, - "deferred": false, - "c": "8FFBC80E4662864D6F373DC8837AA91B3CC26B68124ABD73DAD025A1D1C18829DCF077D303579E5F39F4BE101BB9E355DFB5323882EACB3D184E6812C03A7BEBE25166D55F821A00F80B8D2BAB1A7EEC83D384AFDF30F6BBC9960C4662067EF7E200E37268B9F5348FF484642799258B45E541101A21FDD6FBFAA2374A28FAA97204953B95BBD1BB519785210DA7C8A09D071D8AFC9B29F2C3C2909A4C53671408B8083BCF5AE03D45C0CFBA399F44D24A06321BB74F6863B7D4BF0BFE73C8AF8EE1DDA45212E3F9C853D4D0E16F8EBDB8581C4ADEEE833D81A9E0A9E8587E9C19E689E6DF715564BCE27CFA73BA16226A77CE44DC496992F41AB918643C6D86A8B26ABA6F94F3502D22DD94FE55483F67C635B307745D33F17133293639118E70CE42C6DB7332D4862C73D5B84415454AD51F89B5559B5C85D6B6ED47B6958F21FBC2ADF8C8A9D43FD2E1B0C02418D227B83F85CBC3A81C719E8602781AE71E15E6D714919E52FCCCFD9A68B4751825BFBB53B7940B15B546158DBBC612E602F660B9E0FF439E0156C4C8792346014BA1B4838C7425AB34744DE51D854CBBA58B7E67E014122518036CE1541A1675AFEAE4F29A5318602ABBD0A1540F33176C984E306098DBD08E822ABB55F9FF38D9E31EA4695150F2CB60BC2EB5F4780CBEBB210CF48662C454C7A42360F306FB03617C998AD8A9297D6B71A71285F7AE8DFB336FA922540C92DC71F777D3B4D11D87B8D082FA8A00DF647CF7FEB27403D3CF50D829EEE3575A01E2CCA57849B11B14F001BE180DD5FA13C03B98EDEA6358C5AB30A526027CB45E33E646B37988CC84B979CC5CFC3BFDA05BD2C7B8CB1B11AFEE007E20FCCF8D0F764F4A6D2F6A8B74281800CBDCBBCF0DF1EC9D27E6A94968604D9EFD37928B6856C48F0108155595D03231DFC22DC0C8EE614090F37E0828B48A4DD371C677B5DBA95E417F12C9A396875FB05623F7A544AEAE41A0AA536FB8D767BA2E14752C84E147149F655AE7B903CAA591AE00267ADD3EA816612AB0B9A5FB263C70C4367062F7794274C75AC66F706AE93699859D55B2E4960E9D538F38A2FAEE366B80DC78BB673A9E1B057D711F9DDB3770947E6DD7BCFB425B96670506758AEA39A5ECB33A1B76B822AF903787DA3B61A7B9263C0FAE1B729B1A2E16FEB50C32A8728181D4E8A9F8376C39F6AABC2C022306B05E494CF9B6ADEEEC95887440508981D6A74707FCEFA24B9F0DC3AABC984E9C44174E6DFB51FCF4588C57F9659A8E7A6FAEAFBAE7ABE4600444936B3763463D4AE411DDC1C98585E0DE58867251079BE72075973275141801B98F7B9397C096A56B8CD83CFBD374E182F7DCC9A7C764DBBF4D7576A1CC9239848E7295D29CF034A1A7AE33A386C3DDC24A535168ED23D7ADE9433B50DC5694C969F4C546EF2293CD842F4B62B6B7435F597CF5C1733884E0A6AA47FA31887DEDC6C402D8ED013E49E5CAD7718CCEFEE0E6A041715CC9ADD79965413049ABCE88636AA7543EE2601F162838EF6B", - "k": "342765B77A09BA6863F2ADA782E3719803F7AB714EE807DE89A1617B5C74F60F", - "reason": "modify ciphertext" - }, - { - "tcId": 95, - "deferred": false, - "c": "17976BAC62F66CEF2B6F947C121079B6F2E9350C137E738BFD884FF2BA6E211640A30FBF2695EDF7046E1F5234AB1C8A9B0E8A3FF88EF18C1E5512D5F69E4A36CC9362F00920481E5460B1FB0C2B9FF0CD0D95718966AF7EC1F76B8DA93F6AB179A5DE70DEE34C579E284AE8504ED96E1A85898076F69AAFEC1357533EBB636FBA2372204DAB87C47AF27D4D9EB1B4FF4286D6A9FA7FD506C9FEBA596D2047DB765C1EBF1F7921867D394487F6BE926E6B0323058CB591195436ECC805C8B88615C7A03833AABF490337063DFEED698F7DA8DD589A794C956C2BF8D8CA4AE18B0A7767693802BD6DD53F543E105EC526C1D1D00AC9C0B606BD9B3A1D52CB8C56F8535ECADD8239308F2FE7E1D7BFAC5848B547B4579AFC13A0B2BEDEFA46322F92E2B73980695369C5F48D37F9345F20C7820DB6DE09D5E8313B73ED705B33646FB14CC4D40D65290A4C27360FBBD080E61A16BB15E9560A097E4AEC16F8B8030FAE1D47E024F10C33E6A1C56AEB8EC2F6AD6EF4B8FF04C67307B23E470FB3E5BCB6F533F955C36FDB46516A07DFF2956130AD0924158CC2A083378FB9AE32DE89CF774D82C2FC70DA48536372299C61927A5AE67E55E792B64FE61F06EFFC1F216CC9D739ADBF3B2190E1D080E00F169F145FE32AF7EC7CBA1D76FA6839D5FD2068E1DFFF557755FF2F4271204A5468C79C7BB8D00FAD63938F12D53B243B3FF866556913EB57AD2AE034F8B62B1A1B9DA2B1D45800B4CEF1E1943A0C92F0EF2EE924F80CF67EBD3D0199D45ED4DCC00140829A0992DB43616CC468508B852EB822066A05CC91D6BC2B47E5622B774F8128ECBBB94CADD15588B36A71E9FD97B05D69E8BAF00D30A3D3C00E663E00AFC9F5E1BAC8534ED5F6E5AB47D7EFDF6537753408299A9E8D5F5AE0FE36A9EC41C6DC9F78A891BFA9C8E90AA1A457A0C01AF70CBC9E55B68A5D8CC5CD3BD6886AE11FF510C6ED0EB2F5C081B25989518BA217BC1C153864E5BB312EF0D43D6DA4A0FDE44F1157CD238E8D70BEB420BD310F8E5DB9D74EF4EC9980CBA74358FC77C5D4FAE3036E176647D78C73900C79BFBF0BC545ABF7CBB4DC7F6041D4FA3B66E4D4655E24B11DC30B0061C452A605CE73362F2A3F052370D873FC68DFFCD3999FDEDB45DD9F2A02B4699BCF1FC5F888B019B5028465F30AEFAD946D481285D1122EA78F3BD8B1982558C38FA3DF0F058B12EEBB11F4C7809F6334EA1D7FE0B529C0BC9C67044648178D2AE9232E4E88DD6D0016D8A590B7703F1A017A4A2671BBB24FA97ADE1B61C489AFE9B3E63CF4CCC42168C98880921C2C0EA7D24DB6DD676B77F7B6C0525C8D0578C7F5A20DBF2F82873904D7CF2522CE6360397B254B18C3059A4BEA169A44D9BA17CFDA1827EABECD269FD391CBC0D49D71FA81AC16F9A0DED9E72A58D1BC2262979D8D7E531D1C46A8F107BDA18A1D2CCD17334183DD3E79D905ACA7DAD348BC6D5CE124A1397EB3B89BE7580720B5DD00BD3A63DAD813E0E967EFEDF17F3D960E70A4F83F", - "k": "F175CA29D36784E3B7A6F6D8682DE3548115C25EC1751DAF6B5FC3318F690802", - "reason": "no modification" - } - ] - }, - { - "tgId": 6, - "testType": "VAL", - "parameterSet": "ML-KEM-1024", - "function": "decapsulation", - "ek": "3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575", - "dk": "8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6", - "tests": [ - { - "tcId": 96, - "deferred": false, - "c": "0C681B4AA81F26ADFB645EC24B3752F6B32C68645AA5E7A999B62036A53DC5CB060A473C08E5DA5C0F5AF0E5170C6597E50EC08060F99B0C00EE9BDDAD7E7D25A22B226F90149B4CE887C72FB60AFF2144EA2A72383B3118F922D032A16F554289902A14CF7755512BB1186BAFAFFE794D2B6CDE90109E6582D39CE0C96197484B3FA07FC91D394FC8D88E7FC4BE002E2DB56F0C4D9D3FBDA274536A0B86ABC6E39BDA52931AEBB8F1084C5C1F7CB3177788B7F331B7074361163491D428E78BCBB57B630841AA987333377CF09569CFD14CC2A11C501BDF82C93DE05BEA20060DE89C686B824571CEF94AB3FDAFA8512619813669D4F53637FEFA4D028CB233E56930E2235F7E6034CA94B143B77AD4A68756E8A9184DBA61A89F91EDFB51A39211402473A5F89145736B2BF8569C705B0CDB8980A447E4E1EAAD3E7E0578F5F86B8D03C9DAFE875E339B4423845616799EDCE05F31B92664C5A59253A60E9D89548A300C1ADB6D190A775C5EE6E8A89B6E779B034C3400A625F4BBEDBF919C45B2BCD14C669248FC43C3EF47E100758942E75E8ED6075A96D70D4EBD2B61358224DDA1EC4C19C2A92898176FEB3C02EDCB9908BAE49BD94AF028EDF8CFC2E5F2E0BD375006986AD49E717548E746FEF49C868BCEA2790AA97E04061B75605CB39EFD463D7B3D68BA574434FF7BE8E2B84BFC47E67E9CD15F3ED450C61AFBA79A20B0B6F287777C72F4AD248174F1959477AA7A7C97F122C50447C7484F382BC47D81FCC9C7E892C8839D37B35394B53E6B2B1895ABB0DE8C98F2633DC4413A8D5735DFC9A64026B6F34779D6AC8AD99CC31AA898C2E7057F3DB8A1A8A98527A79E43552F28D1023E1F6A6B84855CF5E6DF889BA269F048946E84021C65C5A93B007B07741C1EE176C73949110F548EF4332DCDD491D2CEFD0248883F5E9525BC91F30AF17CF5A98DD44EF9A71F99BB732985BA10A723EF476FCF966DA9456B24978E33050D0EC90D3CE46378851C9ECFCFD36C895D44E9E506993082523D26185766B23568CB95E64108F89D1014747C67B6F3C8767BE5FC341227DE9488861C5FE811409F80957D07522A72CF6AB0378D0F2F28AF548185C3936777994466A019D33B18A54F380A33892AB4D4BD507B5A61D0D358341AC92F07B43B8F6AFC6991BB6A1EAC23CA6F73E91F2464BD119098D7E768E77ECE53FB899BEB42265ECF7B271F66546282D472C36239006BB0ABABCCA24550BAA0A601348C810FF5F9EE504BF7155DEE4141A11605A4F3509AC9CAEF6624D21DE332D5D50828B52E92885D3B90553B14463AFB1EDCCD3B569B5A7F00BB66769DADAC23AD8BB5D73A6F390E6FC2F6F8EE3CF4009A5C3E1EF60E8F040672D262E6490379BBC70495DFF237BECD9952CD7EDEB6D1DFC360B3FC8B0AF480FFE024AEEFCD4E9CE95D9B469C9A70E5110DA0BAC124FC3741DCF49116261796504D5F490B433C33C40EDCE2B75151DA256A868A5E35F86226B8151C91934CCC3DACA391DECCA745375660B6EC41AE5D810838CBEEFFA12557884412357B1008363D32B237AA1DD8E2D9C6367ADA09B2C95060206CEC3EED391FDC5DBEF6F08BDF0408E585AE5EBC8E9745D44FECA975ABBC140BB37B8ADD16FCC2956910DC72BB3F02E9A130C9A84F9CCB74D134CDF40AFCBA2009C8F0040239BC99220EF64C4DCCDE2E2E5C9B68602FBE8EF4C98B3468C79DF4E078511BFB8AA3DA09597A02511E7C21A7CF66A93843A94868F19E8552552E3ACDF6CB810634DB97CBC4BB569709DAD4845645446FA8D289FC59307B801E60CE2A91E06E9C22C16E2E59BDE38A416BB1B4AC5457438FDC5D64450A89ECB832C1BB279DBF59334681776AC00409846D09D6F687772E340850AB8673384215E12C8D0F531C451E58493E0EE415AD594DF38C34408C7ED9F0C392F1534604EAC3D9C15465A9A46632214B536990D78078E5BD7EAE2013FFF8FDD8B275C89D97C9353DF3C42A28E814D8468E2B48DB0976D88F5EECEFEAFB8F7F4AF291A728F6249ECF5622339269AA945329E919F8B441C83D5507F30DF0FD2B13FF806F522DAA11AF676A513C149C70F0D6E99A880450A54E0417FE3C1E513E9D920E30A8B42891267A2DC50AD81F98044920C099DF22C73998A25C581A5178C72B17AC875BC68548A0FB0CBEE38F05017B12433343A658F1980C8124EA6DD81F", - "k": "8F336E9C28DF349E03220AF01C42832FEFAB1F2A74C16FAF6F64AD071C1A3394", - "reason": "no modification" - }, - { - "tcId": 97, - "deferred": false, - "c": "4F90106FF7C3DC4E47417F31AB56B1C5E426C1ECD5878AAD2B705E75062DA5FA6F4D18B704C941C6C6D941FD21191A69210BC39E24950D9F851B6DE8CE30023DC7536439104D42245F3E04E6AA6763F8AC97ADBD04CC69547BCE0BF290FFB5D12946301174AF1B0868C14D4293FA9DCC5B23F809B02CC78DEFE7F27935B9B681E531FC21CCB2AF8EF6144D8498E63E0EE48AF8D4CEF7AC1F669AC740B06F79DDB58E794F2FC2CA832E05A0374C18A4F2CC78343EEA064ABC5F468F4DD11E0B6E8FA1D18A221D8241450C05EB9EDF90D9D7F666AC82E7FD44AF9328E0BC6004D5B114E80E9B980D18E081D771DFCB2ACFD40142A2EB33234F75733EAB7D8EE8A5A6F796681A4A8AF85CCE86971B821D4AD8371049E94E280B77B15D111A42AEADFC08D4F804BD78885443E81A393DF7C8754C460915846E09A0596587460038F55D06EC21434A1C2DF44D0C16706E8D2B83F0E7833976EF05BF1D9F0DDC9A37597E401B817C2BEC8E02EB9DF7591E239F25F8648E7F2F4F673093BD9CB703DA32B353F58514C6AB55748B194E52F153D52F5F33FE95C5F9F65EA97BA721E8DDF333B64D233A867A12701E00C5D8A9B5AE344F3D847C27C079DCC9C3B40EC4604A9F041E7987E8B930C658B9A132DE4E422C0E27553A2A0EAB8C859EB0E5677E83272725C5C1652E61B9BBF5C9C59BC2357A4D1DB9C607F34DC1BA074B84DFC69E4097A7AD2BA9A58000027296AD39FC1CE218A5EEC7ADFA8AA3B9100B0B603CFC83C152589E12E6BD9EE10C49131A701D315DFEC38E018328916F9FFAA7305CFB66781707D2D1020EB782F9F003DB4E46B87D693F62E8BDE170141FF71F26DDF5310C00C9163655F5217DD2C8B0466AC89DB55BD7FB3B0964BC9009E9686185117DCB50D6D0297753CF7F1217E819EE60E3F0FAEC4A5AF0C2EA83CCDE15CF045C6961DE8FF6235C9D93BA4C89B7A82A7471FCFB0B8EAD54D56E8A1DE21B3933AC5B4A0689EEF3598926E17BBB16AEC61EC30A2CCC0E0323EC282887C108C3A4E83E3666493D8653D0E92443808C79D770BFF48A49E65AE089FEC790BBA4C66354EF67A334C1EA5C6C5707B6928EBD1BDB6A940FA242C6EBD7F3E71272421C9082841A6CAD2894BB8AC85F105D8BBC9E6F0A3DF0D7C46F6E2F4CAB904ED157AFA85D4A852220A9636E1E8821643A9E4028D87A430432F09354B3973182385CF5ABFC8F84982BEE0BCBF5D18637399163A09EB45711E07C4458498C76979107CF91B3FC590EA4AD715D656D5E56DC32146580101C952E02ED7017960D54CAACCC70607196980ADBDAEA420A52C0559ED23C9514F8CA7AB7F3BAAFD2FAB58960A64128D5A50E9AD8DB7D23A90CE64C1BC349D118D3603358377F84FF5A64457FA1CF41B27094BCA72360BD429415B9EF9ACCB7A5D7B9E5F5FDCA8FCFA4592E91D7E5120DF7E3C6675AF2211BB94D856A5D2285FBBB36984A1345590930B13232565D54812A9345324C232653190323CC67C840E478D09E6DDBCF999F7AA3B556F80332E67ACA41EC0661088D7696BB64E9A98A0749FAA9854D9B48754023BACAF3C8081A46157C6453BDC89341D3092F3B5337874CE5DE559A56A2FFB7F401F6E28EECAF4FDE5B60DEA73D6B2182EF68E07A8297F3C959E17139B5DEDC72C7A0E103AFF866E89D1F62A1F6B97B61BC059BDE5A2A06087EF783A441F23DD191C692D03C097FF9EE831F7715C6E508BF475E79A8353E84B06A9356045C8FD09FBA35879069B9A3F478FBD051143C13D753BC45F3040E85985EFD6B149EFA9455A18E2894E6EA0BE58F451FF1156F93CC7117B5D091E9DD50D41BFCCD44F2C4EB7812AEFD13C8B68D7F0103BB6CA38D233B6AADD01845B7E44D13C1CB1577D6C4354B063991344787F8C0BE667A7440B98917AD64CC2EF2BC82EFC3398B3B1B238540756CE9FC5EDD26CC20E761D592A1A0530AA8BEFCFE8DADBAC99A417CA0827F4983FF5BE656669F2B5F985FF6B16C44BBEA131D1FCC70FC53BF31EF225D1F5D41863B51B57EA65C6164F7531AE492EFA64161B7DABA3EF4586F3459BE8A962367DC276597B98E91FF594EFE8849BAD4CF91B9E5F244CF03CA9615BE128E96958533544A56E735994B92E4EF0D5FAB54B78EC66641C7463F225D261C144F00A0270741D7A511994833635A8A9B670CBFBEF239BF83327E247943B205DA68DB94E3F3", - "k": "7545CC458E0A274A83B13554224F0BD01D57CC4775AD12468D3FEE5B08C93A6A", - "reason": "modify ciphertext" - }, - { - "tcId": 98, - "deferred": false, - "c": "26CC4F22E035BC00687D557655C46B6E1C447ACB824204FEF7582EB8DBC704D7CE72B0A5FFE54FB89BD7B779B5B1DD1573010B227473FDEFFFB74DF7DCC1E6B48B554563C6C23004AE2CB1996943821F480E91081F1A6765E08A8AAB7F203E95DEEA49A1129A676DCB21540D2AAE1B21223DDDF1453150483176F3EA3580CE631FC85508690D8DDCBC9513A4A5951A440232223FB2ED9E0E5A8ACFEE113D22548B8E98131EE1F45A33656F079870A146F12819BFDDF8792C3C9AC3BBEA3A92B8606FF2B7296DB9D9782C8E788AF4C961840041735DE456A35E5536D861CA118D67408E84D8BB9128B65F2C11C7147EAC928599979EF195A7979CFC48277CF1FDF4B0CAAEB3F8A172A3CA25A3A8C39AAB4495A70E0AFD3861C41A8C01FAD1E9D81281CAE1C33572BA4BCA9A5294000FFD040545B021AF583F56434ACCD4CB7B788517243B09737D355ECE53273FC0C492F251FA02E47EA846121DFF00CBF2767D4DEB25F705591D26FB1B6F839A58EBA4572745A618CB2EBE02CC0CB1C62AA9F0EFB794C385BC47E440BEB38BA742C7357A97CF33098E2EA4D823BD0B9699FB1EBFA806D64FAB18E106D4A97B23A889355C7A2635A9D3BB330A1B8EE5E707DC32C20CACFED68C8DE783562488A64400A4528EF568D833D73E456A9AC22431B2C22441EF5BCE3E77CCEC99D2D1C092ED8A28D686214313F683D4A020FA714459C36A257DDFF7B19B7ED05A16FCACA2570279A11E1439D07F2F23B88411404749C37836585182F31AD65CFEADCFEC3FA905CD4BFE2B6ECAE99D469F3EFC55615D45D19360EBB7C68C73ABD4562EEDA283776C887E70A971176DDC10FC399EAD6B9E247353C25289C0836C626E5376326FE5630C3098436556D61F5C75DA6057008A6E1D50B4F270FCB86F868D5F235428B4D7E13010D20175D4CF0759F56422CF955A721792DEB8EC887E5225F6E52CDFF40B8BD3FEE4DEBC7B363574FD1F3CC113A3B4281F4E8DC3AEBE4B67500ACB50B5DB1BB64F0634B19D4612F597DE2B4CAEEE8A3258DDF8436ACADF3677B46E7E5CF41071DEAD3FBCE2A73388E19AC0C7748E10E3F586E2EB844ADFC079EC0A2CD8C9BAC8E859460DCDAB688AAAA179882B91111A604F75198F55B17C79AD4BE3FDB493B59775ED449BF938B594D87A1C9F721D1C39868591496E62BDBF5CC2947DD81B65ED8CA0BAF0A64E924B5F4FFA88BE86C3594EA7472B822D2D84CDBFC7A2C5039FEC6EBB14FAE2D5D7E9CAF1C2B8788E7354BB6A12C4EA1ABDF0811417586F01553AFD9D8B1EA233066023BC45FA4BC064E7D289AE9DDAF1F985E4BAA86C55BA1F1866E010C55E166C3AA29A682A81195819B7165DF6CC72045D143135EDABA08ACF9DD9FCB8CE732F9CDF1A99C772A2EDAB78647132C33B80E7F03C84A044491B311BC6F3571E7935C6EDFB283BC59F29DD5CCFF9DD6A9640139B173E64F2755F6BBD977F15AF1524827DCE4C2FDF1EBB7C35F0F34800E5A07FC83821FA6CD41695B322F0909D55251372DB8B3CB147FBBF6264BF764B1A20BFA41EFB84D109D4E374564C760AAB66EE823970EE7BFC1D9DB860840BC4767E4A46F1855526A7D902D4FA954C7F337C7C1205FD4AAA70D7F5D904F1D0CF1DBFB63675991B26B590260714920A7249E75D21199D8C002BD702C5398C45A359965D367FA15A73B83197DB3BF3AE9E987479CD81283419E557F993884EA4F17996CCA39FBA8941EDD70FC86E3A46C84C656F77E9DFA5DB31D8761A8FC1D5A2FE9C1CF67DDA1408A212951A5A1D5E9260BF367FD824ECBE8534AA5C63F3E9E2EE4EC53CB42663A79706088A846614B10EDB58B45BF063ACEF64DBB5ED8808588B51A80EC327B95DB34A2107FA96776F1DD0340C7918D0B846883EED35F5730D67165D4A51DC50533458F045E1266CE5C1CA6A30D931DA81732A876987482F2DB58694C574731E92CE6F9083A5EAD8143F244A8DF04C6DE1B2B07ED86D5593CAFC2A7B3E819C03C70B7B32AC0D576AC2E2E5843A39E4D36EFACBCE679307A1998F9C9DED50BF39CD29A529A82F26B5B4538F9CBBD547B9E4D5F7F31B555A8FCA1F9ABDEF3483640DE77D558735C15A588D944F9D76B06E417B1DA873F38A21321CDACE8D4BDDC49EBA4165D40820BA19A437D65B337B8C037041631D09F8ADD1400524F4A3BC33F9213AC7926548B9C43A4BC0148807D9", - "k": "1A9EC19662B68932E5DE4EED9C3F16A4AA8E6E4129F8EFC2E9C7F0B6E82E3327", - "reason": "modify ciphertext" - }, - { - "tcId": 99, - "deferred": false, - "c": "B36564F2BBECFE4DD315E84612BD765E3F2E84F5D8D86FC0708F72FCAF284A0850708CE6E11D0BE154C00F930D18C0A8D8071B612556238A64B679A083B2FC1A204079EE19A4095E71E0EED695B3CA764F4F4E5D7366430A8933F0356DB074C2D68048E046481E5481E4F5A2F365EA9C4C7A6BEA51CDBF1BF31366F863327126DDD101F8220034FB4A3C68232C5CC84229EB1E35F19AC2016A8E4805A87797F940B72A472F129FF5B751964AEEC96847B0BCA5D7F391CA9053380DE83CBC31F341599FEFE36A1CD83B30A1B7CB588874CCC5F443F73ADFA2CE7E7271A5726272A7E5FC721E85D9755D672F5B2A0EAC8065D2C3835B7F0B2F7C77A27AAC438E345BAA378A572AA676632434737FA59A7E197135BD6AF2619A828AAC865D7F34AFB771BB55B5B7E93B9489AE98C694EAA26C6A86F41D0C53522DA4D90F2AB267675BABFBE963C4C68534A24D1EAEA2BE97702E28CABE5FD080DA6B3C432EB0E55F9FE8C1C0422A44F57002A1F96E6D53E8AB9539E909346D150082DF69F54D27017B9A7633B7BD9F7E6274B1F97D7CB4BF5FC2E34E77ECA1317E7854304C75C388CCD1386C694E93CADC856E136C2C0EE7E113A125C79443C5D1A80A9698BF58248B0903A45961603D1EA0E89E3C0650EA3E82368A6C477CCD1B0180542401BB1DE70E25F64A5DE41D62D0467353EE488E1F692EB60778452B53088473B084D0819B725268AAE752FC8CB56384C7AF9D319CAAEC958FC3EAEF57E0F35F1BFE1BABAA2C64A2D9813EE16F22A94C1C00B29EE82F11C47224A9C5424E647B9883918C9CF2CAF51B7FA825121C5D13ECEB5F66E4EA11526E0C37DBCD464C5BA78A36A31A62B2DECC7DF51C24843EC2325C74A771A7D73D35BF2AC4578932A6C2A7323375A2B7679188CFE804E5EFF4A04B7E14F8851770048F076B32BA4F19F4530364C0529EC3FB2D0DDABDC85DE2257F4DF05686AB498FDBEAE3A1439627DD8885E4C8744156C2B155BD2F965AF0F2017F163A6016C274E8532CA43C784B7AD4747A58253EDFB739D68E376D7ED246E5474454F463F4212090DF4F4D7F88C097B18180B05F2E89EEBB834B9BB6DD9E5F6036ECDD5908CA4962609C208A557A36B7FBC72158A6D86322F4303434F6AFFB34527E47E0599DDC88EAD31814646A81188E79E1B6D562E01FE1EF148FE8825758CFA5BD7B738E3BECDDDCA4C59093CA24581E531667DBA2C295B565951445E410FBC99D795887BD48AB87D6D413B64957993CD7525A0A0A5D393CA1EDF7788E4DFACDFA7B394B6163BB948C9C6779BDDCC8F26BC073BEAD0FC87236704A0DC0D89DEB4F8174E91D249C4DCD9260BC7C86CFB35B985813E1689D83083949927303741550CB782E256E79800F41B5C7D981D68E60978E5190A2C51C812DCC3952AA34212625834B2F8CF8CE8019AD6CE8F00FF910CCCF0CAF5A3596AF8DF947EFDE954F361665458F77787E528937BC52C59950746C783D8C5216570E6F0A944E6BD661F23C7A9AF3C602DF851EA2E5627186A6CCBCC470E07B290E4F754D5A8D6BAD8C34F39B4BA838CB467681B0173C33FA51ABE122BAE3DC06660950CFA5C228CDBA2F5EEF2613D2850DF9B5FEBE7333BE93F90E4DEE219AD18425DEE4006FA3009666C83DF7EDFB2EA4F99902C694248F9D51C7B6FBE53780EB218732C11368C33449D051489FDB01B1A1064FB06DED747ADE38F7A12DCDAA92D64DB4C2C43DFE53068A77339E1479C8C93192793B1C752FA7FB23B57DB5B428622D27CBF608CD7406FDB543FF3BD26FD7ED7269427C6B93491BE6724D071F58AF434FDAD2F0FAD5730A60F3EEF94C59CBC5884F36274C4CD984303EEAAD17E1785914DC804BBAF35406995E3D56094F0FDD71C7650A6C37393C0EF4C167CD2FBC28EB4EDD34B5383CA3D1B89D7BADB0270065B5AE2D461E6DEE53291230ED3CC3B616A7E8A86A4265A98C10A44066301470BBCDB257F35489BA5DCA320A390AF23CEF6ABA8B291538D9C4E965969087E394EDA44C060E28220BF72AB98F1C055159892DFF079D283C52997DCFDC2FD8291FFDF322809BE3CDC113DE9D495EA5F9FA5DDE5052192CA6F26BD510433B197131A7E954AEC5E58F0A341D7E4602BAE46BB1987B5C1D845E6AE5569DC2AFE0C7984DDD9B0B184CD6ABC0AADF5E13E0F110E8876D572200DD837FEF193278119B861C196C7522", - "k": "F098B5187D66F9687666207379D9A52532C38C0396F917827BE99222D0BE8762", - "reason": "no modification" - }, - { - "tcId": 100, - "deferred": false, - "c": "4B30E5256A941008BAD9BD14060445AD208769EDEA1C5B6E4ED506FB334A2378520B5EDC9217D626E1377839A18F2D21C0CC8902622E4AB79E83DEC449FFFD45A4CBF3AC253142D935DD310B5E4C5D591A9BD61795F8ABF00AA04EBAF96195B6CC7D7C3910FD7D75E25A9D0D79FA453178B06FC6B1E99F189CDA90276D6B69FBEA28D68CC82707A46CBEAB819239BE69BA76D749E27CAC9E5FFE88064B9972DB77C49679D6DDC6E6B03DAA0DDF0106B1A61141DF827E96AC542DC90A69CB316EB4F78C611C0155F9138F527006121DA16DB46531ADEC2FF599378A819CFBE3B079C9FE7E368B91A9E40F97A3E79A4F1F05574CE2AC3A525C206D9E55CE16D42D2F0F4863F896E808FE168B34A102BB81BD607BD02CCFFBA5C189497502A55F3E601F8F61B40A5202BAF9AC87D058E67B9E1CDEA0E4B02FF2DEED7477609A9AE2116512C42079D87AD74B05622E02979EF0A0F1D6375D93576EB6553FB1AC70ABDACBFBDB18735E949EC6D1667E978547A5CEAF2F4DCA6FF5D8346A960CE6925BF2B3F316238D6BC8ACBE67BC1AACD5A9A5D130A3D3B39C3BD7C1B06227A59BF4723AE9656D9922D9228A3404D4856E39702DFDC01C6E8CB6000E0779364BAD4F021BCFD7288CE7049D544E8423B2890C3083FDDB9BC720AC4C6A1A4EEA6BA1927B307E6CB72131B6B831AAD036A50A54608D106EDACD83EBDF104AA80C917314D295E903FDF36CD04EB786CF93AFF1279C2172002F7EE92DFAB3A99BF42C2BE7B7D0EDDD38029AB5AE18F5CFF8A2F1D2EA2EC7F34770FBA8A8BEEB0E1FF6F1C1A036F1BD84030004696BF4FB4161F252436C0401AEC911CBF1D7530D9D801B1B9B3A682329AE2F6930191E48189CD40706256B864D6F016597B4AA86FEE4F0E2362D8BCC743E98531EB2B335DE2DD299F231FAA808F6BC7D8F13DE8EAA30C5698D64E508D3534935B9941C2E40A458BEA82DAE4151ECF6DCD40320E1009BD9FBEE248F4EB6DB4437482BDFD83FDAF8367CC1845E64A23A310F904D5FAAD67241AA7748764C26EC881788D1EE0A39944071E5ACB656AB8CEA285C282545030EBBE6FB595E296E1EA37D7AE529B96CAECED11331D80C92D3DACDD7DC93237D815A9C6CEB9209C0BF3548ED1AD691929B2C1035E80A21477747E313049DEAD43A40B0960A96BF3C3E9BADEBC3B4D424FE7DC4DE5CE7788E31AEA3EC8965740D424CEB66D4A5678260051BFEFF09A3CB24C1AB7782AFBFEDE5EE1ED4EB14AD2A13142E8201CD1B52CE064F05ACFB019E21A73D84A80E30FAA48ABEFECA970BBF17FFA6F3A90AEF80EFA31C494E721231289143416AB9621737FC016380E6079EC6CD962BF7CC0750582EB218F869CE117D399DEF9AA66F7D2F07FD22BEB9E50B94CA5FC758C9DD4D2984A156748C52307731FC78F8539F8264BAD6DD56C0C23937A9A850E66BA298C3D39105ECACA9A573D887C9A4FE33D487F2126097B165594E1F8106C937758AB6EE75EDF39D2BCDE78AB611A034A72FDBEE67A80F3315571AB4DB94C56A19EFB63B8E7708566412F73D4974B160183FB5B6C44C8CED990B29C57BBEEAC5EABDCB11CCED9A17322B6EF197121B4094D7EA4A1B4EC44A68B447FE4C8119A6A33BFB66EA6844DB5B6094119AD1DE89449DE922B9A0D1253EA18C62418EB87330C6B33EEE02D4486F62A4D31CA24F098BE2F187CA6019025AD6E1C2FE69800D8BFA2C646F9FC6BCB3D369A78310084FF163D2065631C41748E7E3B25E8F2C9EDA2E107AA2046FE3F5DCC0A9A39FCE41813C8F1946C3AC07A22A6A56C4AFC626E68FF8CBC4982C1E60C3A9F288D1C4F2B8D7187EF2FAE30B77C4DD73499C2B3793B24014CFFEF6D80063DD1C1F3AC7F14FB61E5E81F850AB865BA873404BEB898FF7A2DCFA3B955DDB161B5781AFE8EF127BA2C8BFDBC2FB1C7D80FC650420214314023F6F65C17FC48927BBAE88D48D2E1976119C2F8310232942DD4C3AD4518D1E4DA9DD588691837122F5E5DE0FF1FA685DE134DFD1348CE3B5BE60B18BBF474074829E7D81AE087F149259122D47B728F369D1D8455EE571F715788C254F2EF438034BFF0A11F2F008E19B370BBEEE135A00DBE7F3C2970208F5F5D0E2765C395CA81B2FD80FC384AD046564229C759315B6CFFAD03A56996556E7714DABDE28F7A9BB5DE2C05B1F3596AF66C747D9A9313673F19AD4BAC6EAA7", - "k": "FBC9EB4E8D611C153AA9ADCAEE5781DA5C0112B3AB75956180A5CA40BFA0F53E", - "reason": "no modification" - }, - { - "tcId": 101, - "deferred": false, - "c": "CA9564B54F15561C8238E6CFD88137EBD4D277FD5D64BAFC33D6E575947F0FF9F93E3B0A4023DDB6FE480D7D6A2B9ABCD6E6E011EF37C0699A6D60D9AB4B05BC685B0A9AF7D3BD999C7AC1CDF017E6AF1DCF0313759CBB21539D7774C31D7ED8C039AC34D0C6A5F7590A3DFE193D73FA96B3458A364DE1555284D85A2BAE7BA9E57ABA00134E6B09C09777F2F1D7125AF858D81D14C71E34E8F668468997334B72E002920FD3FAD8D588355343FA949F1CC0BC263C7F7A7FEA6AD708DB756AF983B16A593EC224F7D69208938A4526400E326CBED532A777301DDEB5E539CFCE60DB8A022AFC52204C71710C204968FD1457919EB71CA15522AD56ED6B60404D62D1DAD0D06E4A2AD6BC746B28859A77226B774BF56BF7F019F2837F51509E9EBE9EB069DA27401CD1D7BF2A74CBE8341A7F213D061619F4E5F52984FE47066D910F1146CCD8DB48210FA2518D6B9FADFF16ED9D389292C07C8A7021F32BCD538AB06A6D5ADB13D7A96F65A4062A17E26B301CC8AD420732126D7CB801DD489AFF2D717D07A2748B4B01D162D228D5F1533CD5FEE8DFF8F032DFB270B61095785E44CEBBD4EA27158362D2A27582CE78594D4D7428B6AD958A9F1604EBA76A8CC0530E1001AC97E5ACC5EE670D5DC6A78AA45300A2BD5F0802CDEE564FA640A19FB554383A4E4CCF2E5BB3A41879C9428CBDB8DE1F4D3FDEFC18C2A8BAE42C096244279E57B307614C843B341BCCF530F6B187121DD83A9A160A3579C3188A98FE2F49A85A2705B9F76DEF04D5D04676D8319F243DFC99A5F90771B34D2A45EFF92C0CA8E4B542B8ED4C2AFBC92C26F8DD20B26B15F9E719AF22F571EE5B9573D5BD1931138D6315C5104BF80AECF830548E98AB23DFA44E5A23C6CF57740926D1E146937AF8D220684919FD89082E260286AB66F66F8A1B81BEE07A85907D07FCCFB9A1002CDD47A33535C9FC0938E3CDDED04D3FABE6326CBF5643373BAE1151704220E49E177C4D0C6168647E5976670DB7F6D0C12F169955E31F553A53A76093DA2A9A0C589F9AFDCCAAD9EC5449ACC01E12A70BCEB389AC104407415782AF2EA3C73D9EB2797CE6D3C005061C5059AB625DD7D273D4D92D1F4EB411A4033492F19921F60D0317AF286866B865E33B6235F0E3528228CF9DB242124F0A6375D50CAB3851DD2A3A022C1E636E332C90D97FBBFC2CF0B971AB1A89014BC2D942FDF015555431ACB3E7A6F258B816BA84892A1DFE3780A0E0C2E6C06149218E70D60D62573BB51856716C0DDA63A983C4008982E842E655E5767DD203DB3490E1E6BDBEC16350296D879F017BA695FC1CB3BBE516B741A67CA6CE09314AE27F718DF68DE698198289B457884FFF1E439F30D9117D19ED7E466084BD5A73E26B5E1567B148D4C7ACD1368B1CE2709B3AF233679E61914202D0DCFC81EF3ACC250DCEA602103C7E529FD6F31A186927E790E3DEE09DCE87DF694ADA7A3B7BB3BEC64456EE983E25DC6CA1CBCD752D72ABE6FDA2FC81A46F81E83AA9738D528C6FA3E69C453346D0C9A0734DF36BB7650D1D2AFA8A5C4C5A936D41258BD4193DA74FFB180CFF582A32D6F6ACB93836E009E8C880592BE61532215F1F6FA50E8FFBB82208A94D8510F70DC6633DC04F9D94C6AC46EDDD4EB36873E064CBBE65D343957CA7B75024EEBB56F589C3DD2253D68D12DC892ABB1FA4BF033B9B732E89A8B89541F04C6462F62F13B09C6705B31036294F1AC38EDC0C2298D7C6F4374C3B5C368D10DA8D371383CBFB4491126A83D1F75DF44F29BCD39349A9BF6526D14B339FCB440647A5FAB63A370089DF162DDBCEAC8966648DDAD6669E1EADC1C8A33E9B7378693E229C6B715F2F0AE54A67455E79FF8970F23E655E7A540D28958E2E102DC99B5CE5772D00831671CC6F7024BBAE8B04173E439054C96AB3BE918C40C5A8D42A9122CA29C56044D340420D2EAAEB738EEF70331D488169FE91B521835297D7326CA272B2614144EAA0B7A75CC7F3849138255B8A1D7DB875BC7C25D28EE5941DE89BF7B063046CA0CFF31A99D7B1846E01B519137B67647F024B3F6DC70045B6950EC6ADBD68F43F67464858D515D6E3EC5F99D9F1C849831BEB4224FEDB01236712E1D715F6A752D0682169A0E83F064FD6F081F338837FE654BCE7C8CAAA8CA90C8505945D9BB3EA58661102FF0ED3F0DE30C4013122D8CF08E0", - "k": "D970209BBE4676405E1CF15D053A04F93D800AF1B32EAEB1E4B644ED09ADE8E8", - "reason": "modify ciphertext" - }, - { - "tcId": 102, - "deferred": false, - "c": "C18D7D95DB69D4FE1E6DB385024D83C01F4790E2BFD25DB3F5DD5A208ABE06551BE0936A84091F081308471E82AC9ED6BAA90824D5525701AE0B638003C21D5EBBCBC17FCA8F522BE4F9FE5ECF38BB66131578163D50994E532D0776B187498C5A85AFF617D4550345F3855F968A8964B4F3CACCFFEC82C92BC8617C78C98E10C91AB505A92CEFE0AD6C8B66406AEA4C3FBC5275047B3E983AD42BCD31838A39B92E1C61E9E62443DF3A45044819D9E289B5514D4F74E08FC3914C0B66D2352CF8B1FABB4AC9B0748A43547BECD29D447D01083803D34E8B7EC89B4F0D78B88AEB33E308989BED2D7A78E1C06A11F3BE808F0B9D9712C80D63DA10475849DDF6CB0DBB1007FCDEDCA3C4220386B78D9EC6E380B4F57731D964470B42CF7D4B4E6D98A12A9021121C8BACC4B132A274941DA57D824FCB60B83565F5CE05D140653DD4C70F385B55D485D24935F3631AC63FA12FF50BCF4E431EE4074B2A05A2A97354C7B4169B13EB225F1727F8424F7CA6317A04C355FE785248E67E053C4D4BDBBC47DC7760AC71DFA2502FBAD1180F2B095425198A26BD5A0F7DFAB70524B8F076E7C7F215B0536B0023F8A9F7784809FF4DA245C2EAC5F9E0AB85D987C5B6FEBDB3DF197347BDFB8D5F1547FD2A59D4B434FA7ECF8D8535903D3892868BA0632F194AD6E4D5A3B30E5A6B92F829642DD4A3031358F9F0D9D46530602A35CE455F0E360C14A754828972D85561AA835D87275AC510856D26192EA319FEB45709346929DA5C5919510CB2A482CBB0F1CB4BF6FCC0343F6DBDFDE734919EF335356ABE82F80786EF0CA22E5B03A05963E7051E1FA7EA4BC3141B5746D264BE1A32CCCD39DFF8F9E5E2AB4C5F51CEFEDE3C1CD118351F9A8ED30649D407FD31F6C4BDA3AF44888ADFC3D118BBD04412FF810A7E106EC32F7524E4750DC5F35A9C55541421B5E412E57BAF24622627F02633F524FF854F71011580598C5CE01190258310BB12D7DB5F95E9EBE5F72C97E89287C2F9007A9332EC51DEF1AA2F2CADA9A8A547C3508B4D294364EAFC858B98C60C5469CC7C3CE3ED659B5A54E889FEFAF825FC777AA74A8896C9447704CA7300FC5DF5810681E3ABE083C1285B3B97EFB0E21F78F45409D00B2E1680DA79439734190AFF0D68E062970F8F6B0F1E84A559B09ACD9938913FC26484DF2125FB6D7FC2E3F0DCBD72D9E5DEDBE7E44CE7D895CC9CF6945BDE0C52F92340F9FAD3009BC90D4C2D3DEF7C1F10A862F9D71681537FE4E2716912DAAB8C9DCBD81A083220F68B05F7502F3911B1B6E3B26DA14EF646DCE67852FAB6145BBE7E21725C21CBB2849C63D01AEAD932F8EE9345D8666786AF06AD0C89B08495A6EA95992301E2D8B6A14426971C7B31626BC93BBE76CF3DB9487B5BFC5BAF298F1A92FC3BE276983E53701F9A550E2961E6E2F07317381364719BF3FC741E2A5A0664D8873120D0C11287E92DB12126332D43F35407C01F7F85DF7916B651EE4A30D602E71227733EC9252EC8346361DEFC23397CEAD0C23AF44C77A4C97242C7FA9065BF0C81983AF3E516C1B8FFF3DD5A6C43B6ED5AD8BB3327A09B6B459168F3E497DCB65FE7593E8AB429B8EB2B31F76DF08A6A8F35EC4CA994037493A8C04A73D8191D682542FCBE16E657D3E477A7D25A1D650450E94FAF485CB76FE7110BAA902D74C335FEE1546D076163B5540D8495E16E909E1D28C15BFB421756B921778A784E16207BAD407B64B9CD83AFB0A602374DE06F5C836F4A1ADFD495012DA8D3FA4B829F735B31BAA6364A2AC11BD18E40628DCF82238D86B0B5EE9DF6D179103E1D12F5191475FE3008A5382CC24648CBB24F2298758823B7F93DF10B380C3179F07DC3277021E9EEA2BE5CED646260165B57A18C26E259F83576938828D4C7617623006682CAA613AAB770791874B55E2D0BB32DDB628919B42C09BB7DAE1FBEE8661CC13F8B6A47CF5D6085A2AED796E305738B508599673DCD03AFC267023814FB1DF7EB928D5762BBAB4515921D81C6CAF551DC6EA16C1D31125B99299ADE63FBFB9BC1CE46331394CE472DE6DCEFB2BF9B3828B0110246419C47D2A1FEF16097B943A310C0664A92A155C8273402E83CB94D7E733E4527E7525E9BAB219B69676804C1F67088184038668D55AC4F6E04CEC0EED4B05DE649A9C2064F241AAF9732B09B0EE4E5BB2C0386E45FBD44", - "k": "B93CAB6CB4C636B56EDF0DDA556D2AF2622AE197B5AB78F95249204A6E2E824A", - "reason": "no modification" - }, - { - "tcId": 103, - "deferred": false, - "c": "E7B361D043C4A0B3A780121E9648DCF38DFC10ED5E47EE4DB5523C1EE1F53552640C89D9D7EFB9DFAA8EBAC7AF137A850AE41A0FF8F8CE31FDFD3E671555180EE46AB58322FE4E5F525146F9D4CDD1D1CA01413C5AC7259E1A2604A5951755F47D1761ED16B26D3DCFF79A263BC38852007BD3F381FC3B79B46A4B372918AF3117180726117BDB33C063BF5EE5D69CB48D267929CEDC890B743DEA43205EAD46FFA69D9B30C1AA5F146CBA3B0B7C4D4A50FA8D120777F1661430DA1B9D1C1DB4E10C5C3C2436D381EB13DDCC61EEB3F9AB46B60D2FB714929139E9C27F8730684EE17B077BDC003500027FAC94DA80870B382EFE41BAAD902A491C29DC95A8F80BB075A4E61C8F100FA738BED869B48F897ABC9CCE08917B5073229A94F3790947FC1AB6C2DEB5B012D60EC156A8A041DE151EED8884EC616089CB08EAEE37C006F5BBD10ACE9596A34FB09345A14FC4EA674E4A74699BA5240FF1282ED1E64360BDC9F7336051A33DD48809CF0011BEB3CE8C681588AB29F5F26175A8A6FD7884CB96CE3964FF10A67FC4A4E14CA516162C16D8127CBC45BCF7C88C89C8602032298B53C19FD099809814BE0504BCFD2407F48F2F24C5ACB89DB4F54A018DD586D871C58CC0D998FB4B0E5F5DAC631BE8367DDE88ED711F069FC8A80EBB573A7DA12AD8F13A4CA1E8A22D9EB53C55B80F700C58E6EADE6CDEB35C262EB42C903AD854F843547B79464524833A05E3FDC46092E41D8E339E7662D1209D338B8A02994D15A10439C1DC02A5B0EDEA58AF197866F43269A57C747DF389EC597F523211770E9C7E4CEFC5E43EEF791897EE43CA6146F3F757B66B9E7592E728565325D1740A1736CD0E678BBAA043F4C355FDE27094F74FAE27AD8C270930DF637C652BC1957F958DB013C146F2A4C5F451AB58A55C2B638A82755C11991B049E82F8D3CD3E7D3571FD5A83B60280E92031B610FADAC9E5F61DA469DC4C51381C970E03F09CA560E5D69D9B32AD6C1DDB6FBE9F8FC0551A909187AD65AFDC067EC6AA01AD684AE4C4F2E1F64046083D3EB347A6B6B23BBBF14668B9650D9364A6A7666593DB86FEB59628A91169F8AE24F67680789D316338B2F27766A83957831D98C88C837215AE3BD49767ADCADE758320ACE76D7F39E2970EDD19657F0EC12583164C325F0A000D065036BA2522F960C87F9852F30BC6BB5419CD8C0A1F9757BD358E748CB244A5E677AB9F9319A43A9BAC847A566052CA42C1C1DB36A0D97F144BED3BC5F11A5C8BEF7A74A4CC67748F1DF53F8B4714E0A04256B36A814B08B78A9737757E3F1347F9E5535DF1AC98B08ACC1409278B925F3B6C7863BC0969520FC6183E216B4E8E449B0FB999F1C65567AE2064774454EFDA67E1749FB24A91B55DFFE7DB75C4E24E8EF2389214EC3E95972CD53234CDAF8958D651A7A95802E65499A8A7811A65ABBA90129D5EC4247D8183316EF818E79BE839BB3379E4B8F4EE9438BFE310105C91F8703AE94D8F9D53096E2341E74E0237DB2665F16954B9713DD9638B05970A9A96261586B04F9FF369028DCC43D35B51F95E69B0323A1CEACC4A5E2EF640CDAF3407BF5F5E14C9042FF299786BC55965EB7C8BB161487FCD7911BDC2FBB65100F2200E16C690F801EA6615F9130EB99DF816B188B06E9A3105B78212B76609DF190FF102CCC451746CBAD16464E8E2F647B75777F664DE86F5089C37E3A54A6AA8B456CB98B42DEB5529C06DA45C2D2A13060BE56A061CE210ECD307FF5AD5BE39CDD8D27B4A3403323D4F53BE35FB4E31670F73CCE74CF73CFBB29A5FC2EECB5F852CA911942066D826404B77251BE5BC5980D0A6E0DB4D753D86490D4250536DACF05D82064A28324B49AD4AD202CD0FC939BB7A3CD9FB1E3E196348EF336DCDBE4BC831DF5847070D0B2BE1C4910FE1C69F58C6A7A2E7FEBD51BE1D0E050D5D721D7537A0325E7ED30AECA75A2A81BBD86EBF91CAFE4483D2729271ABDBB65C2CD9973627D2820DC7ADE3E26CA2F466EB117B2BA98EC868DC728ABC6907D49E2495504133FAA7F8758FD23076D1A65A91C75512F89EE4E2F3E480D6ECB0EE90793F4F93FFB75DF58A7072C91D5A1D9EF0C3B1DDAE79EF576E6A276F78CDC24664897F07B3A20691601EAD2F499C50589BDBCEC74FCADED1A8AFDFC061C2712ED599D48A3ACB3D86515D664D0CF3FA349A1910CB", - "k": "2E85AE4441DB0930391278E9D6920D9AC77D6C752DB2628CBFE9D76228DDC954", - "reason": "modify ciphertext" - }, - { - "tcId": 104, - "deferred": false, - "c": "EDD3FAB8AEB1240FB31B836CD1603E1F904BD1F87318DCB02A7DE18B4044385CDB51E343787E583CB043EE23899658420F9DEDB23CAB2BCD1013F573C0C7978521596631F6590105CB7B281AB1591B7056BE068DF838E0B1679F3B88D95208EF4B3019625EEA7704CE79F33AF339AB883B0C48B3C4413921F43AF2515A85023B5D98D06E619238C8D033FB7DD19611CC60CF395A03B0681913B299531B13728B278D353FA093C633710B65000772DD6D7CA59C85DB62196DCCE1B75559ECD3FB42DDD8E57EB4CF3B4E35B57EA3D6063221B81F1B802DD7D76DE308CB0A738C3B5833E9F4427AF3C3D79B521E7E665B052B9A365DCDFE5A688B06EDCDFA2143C938F852E32D6B49808CFFD01A8655B767034F8C638E8AF94BF3EB9EA39AED1D2D22E181888DD608BF9392FD73822303A41996F41D51A924FA6EF76A9C82709A21BEF1DD004693EC9468B335F9BD1FD94D5E6D89D570FC6D23B7F5CAD2975F418B8C4A0EB82EA2A3C979B1C15B0FB0A23F844764DDD49A8B89C0D4BC8C311BB43725EE9BAACC4796F58C0F1180A4F6AFEF45178659B35A74FF34A8E93A64FA4CD003269EC67C5BD528E015B2311B5E2D33472638CD65FC7D5127335EDA862BDEA05F4290EF9B370BE69DC89E7D71DD2522E669700D5D02D8DCD75FE2AD9EDC307225D61C7805CE1EBBC806A08BD360F86FD27B599582B22C57DDE77B08F7537482FB5D75BDB9F3F4EA07DFB0711C25AD1950058EAAA2E17D8F676BE6B72B1687383D8E0DD60A8277F6FDA202D6F8957EE21308AE81ABF72A89924DB44238B262D2FCE733E12E5413C31FDEF94860D5BB0FB0AEDCB1EFA8F87CCC76189FA5D8157FB4FB14652DC188157B2B746B596FE6F2FEB197DE139B80922C2EC14B58E743E3335893ABF85B99BC4566FA1BEED449658C5993CD08BF78F7DBFF808F611D6EB8F0BD7977E854BC195D711C03EA532403547B6ABEAE827481BB5D53C867710215835260097B6CA730FC722A74E230434B08F38EB1ABAF555CD4CC6CB9310E32F93E0ACAC1E915A4B57E0774B013BE7DD435B5C6AF6018944349841F84E8C28260149F266C99FC05E0DB8D5A63DE362CDE45F5BDFB6F30D55A84ACA22E8640A1287DA51714F2C8D4B184A5F671E0E907134E34D875C9A4709ECE3B7FE15713A0DD972505298C18A9D35956149EC9AF45C475016D7C8B5CBFFE2108882B86FFD380A79892BA1909489E016CF9933705E2FA72ACC8569501553401C397648DC47948935C0197D6F162464DE42BA537611CCB67A988030ABF6081946FDD1ED8C6B23691EA160E8543735894839F13C270B3E1F68607A7EECE09AF06A34F4FC9096D4EFFE4905BE56F3EB397C13472F6621F3EE45A59C8001ABF9302E036BEDEB2E0EC92A03FFE0DF52262621728C6791C4E7D8C226D17A04B6E7EB2FF8586585D639B449C85224EEC67E30537ABE85C8F7E2306DB80E968D8585CED3A9E21622BBC38D43A7D79E2457C67307CC208064D3568C476ED79359CD0A4B0BECA02FA702661056E187A51C2D154638F9000DF856ABB82CFE12C47543E46FFDBADD2DC69EBB3FF444E7E1E95235541015E6CC7A0429C82EBD6942C6420AD598C08080DCEC800509C142ED5A642951F491E748B5436148B90ACCBEC35D0D85FAF4E472ED3F1A089113808D3ECDF77EEF3E089FA5A1635B90EF99034AAA49D4D13058EAA5A8797E37C59CEB86C7CCFE1F574E1086DB9BE744BDE5067AD5D6C450FADFF2338DB110736FBBD86B41B29C29D3899CE60E9BEDF775416541350AAA9BD9B5D57573C542375BB0297912863C86AAE39D153CCB29F1811CDE58978951CE8EEFA6F9D10121AD1FB89F02AF8E96AC08DD10E3274E8CA79D910667166797468D3D3BD6D7EF5F2C6FC4F110268A2716CB273F29BBC347050BD98BDD88F30A96E7A9E840A55087F42A09B03D04E612640BA4D86BE87DA6D20ED0ECCCA2523EE7C4E9D2A96E7378BF71308850832769417EB6250FC768B0EDF92FD45216A235435A3E32AE5B22BF913027D81B0D5508D2AF88120A50206DD7837B79C45B21DB4FE59D23F4AB051BF012B13F6EE5B34C83C8D8CC9BB35266D0EF3834F52CE6CC5BCB7C5989198465A9E9DEE1A1F262FAB26FE0D0964E624869DF2607858815418F85A1F503BE5217794CED29D02E19D40C4BC8E65C46FE3815C1E548976649D4332B1841EA03022", - "k": "5CDD11E1565AF6FBC0DC373651C6F2DC833EBBC54FC0FE2855C0C19EFDD6D877", - "reason": "no modification" - }, - { - "tcId": 105, - "deferred": false, - "c": "C72FA15560FEE6B014E73F5F93C307F74EF9C49AA8F7DF578C002AF20419040D6AB6AC46F78FB03F56A9C5C95902D8CBCE34D79853EDF0C319AF5469E32D0B9FC3C41628970E0B3A6C408B509C74DFA218BD23FA7A11DEA2D2277B3522BEF6606E3415D0DD51556440CC1AF59CAE6F23368BCAC3E1509503368354D1E3EC9E91F8B2D377DCC323D578DEB222585E43F97A6D1855B576297F3EC39F5F9EA1B2F72A0E701DB35D633DBCC5FFF76A2D39AE9DF2A3F6326B7671A4C0BB7177897DFF4FAF9FE5CFBCC94966BD298EA2627CF19C1CA866E5927C6E41970F544479D9A6D814AB72E2963F959CBEF37BF905BE98D8C8F3C25FAD3983F71D0C0D27D9FF17E4B34C2F8664406151E92ECA980F6CBE8F8926638398C9BCE9C69A92A30CE82F28CB4FE4110EAC40437BD64D38412030FB8DB3A4242672807737E707E59A0ACFA782127EFCB7BCEC39DFEC55C3109F958E86E0D381C4E9E9FE43110517778C08A140CF440F209011768EE34E5742ECC1E4CED045922D698A29E5557A29C237885D8559F110E4B540FE1298B97920EDF59BC8EBCA11EB91F471B6647864B384AE5A6BB494942BB1F537301B39EDD6F664E4A7877C173614B09D981401D5AA98A8BA4BF1992DD7B7A65BCE7E87FCDFC7B29AB69ADDC9036D71BB9BC08F4E7D9A57B784911CEE7D0EE5A559332981B6475290FB4410D8BA1F00FFC4850031708EB6A83AF524447F491CC25F23FBED71476FBA5C64BCD50D88A3ACD2BE1DF461B11F6D537B2929D073FCFB9E2545E1B097A12F52C411B2AF6C20A27ECD1C084568F4A76A87A4A79F7711012CBEDA777D913CC6B15E6C4E9BCE2C773991946CB9CEFB7F105B15FD2CD3E721E6C1DF69B66BEDF2157ACAD45458FD8C9C1AF910394A13C300696BBBB5B1E1145076BC6B9E3D30A680EA29B6370618B47AF77108EDE6BFCEBFBCFEDDD27FD9F0DA6D289060095C4E309DC3D26DCBFB9E8AF34E12BDD335FAC434663D4D802C8B04AC884352D27739C4DF22F3D7DB38084BAE2C0A15485DF4E356DF2FFBB5BBACA78D0B4886909C4482A6366991776B788C0941437BF858DD83AAA50104D725171C09B7DB521AA65CCCA3CDAFB2E61CDEF66B55D80E201DF44654E7B1FFCA29EFC1E44A8CBA406C8DAC6207C0BD5DA964FBE137ACCD84405A94F5F51D82CE701DD16774BA5F0A7A2BED7F9BB9A4F25C3095D1F8980721A7ECBCE957825A9BE9F4F818E56D35909A3F9DE5487DA0011EBCF9F4D768B72D236042175ED599D731AAFCD45D3D837FB8B64304ED7F22A8C3949BFA25B83A8C05FE9748F63A38201B460E16FFE4329C8464C9BF07D45DF2BA9AE7A84DCFC4CAB7BE42CBD360F61051CD56F68A71FE9E78231986832C9564D02B973EA2D3FCDBAEC374612C1B74DD483F08BAC30F6C9306E7092CC8FE1D20B937AFA4BC605ED4398A8B81A470870E97EA7D51562111D04BF9D09D9BC07533FCDA1E8DA2F2823AD621DB169C99FB112E44FDEFD597B61160815A1776139B685DA9DF6B4C22F6FF6CA3CC46B3264E456E98FF1F301122C88D42928403ED0E0E5F49BB0B450429980ACEFA1A80DA26638B5D2310FCADB0836223CB0894E6FA014D351AE052A70AB5F515641F153509FFB90B8DE495B946AB8C7D7CFEF56D3C66DC871F1D3A38494EF6AB82066E96B9F2782D6B5931B78B7117C389D155759CBC1690897DA66E50D0865209887552C8A6035B8F6911760F8D0A450FB926096721D962877FBFD87D92C37C71836B8BB9FCE92B4637785DC8E8C1D379081C14C73872E676A1C854F1BB68649BD552B48D12F62B17E9A48CCAF63885899C7B781DC3A6D7DE7DA28E286C9FD644D3521F0320B7ECA8FD0AAFFFFF90DAEC85BA80868A2EC69CC73AE00AE29FF5BA37D94510CA19E1EDAA64F30CD79A58B42FC9A6402CE31AF54BAE84DFED8D0C76142A347542265B794A0AEF4A08B4B5DFCADBD56757ECD98F175D80B44121257964293F300FF750107C1B72463D4634EBEDF4705F76C908844763D0D6813FFBE5411FBBFE16C08F32BD1BB3FB8EA5C5339A1B0194DA543E64C1F8065CE526D2754EF95A287DDC97B790FF34EA37863BB166BF0BD99E3A961BC91C1A4F84B63700C9EF5D8D31CEC9E1AE33C554BE638D5C1217CD2DBA13CC143F969DCBF285407A9B608F859812E7F668D4538BE179D11ED767A6971A2AA9CBB545EA01998E", - "k": "C751783FCA654B1FB5F210C6CAAAB9D5E46A969E546A0834D618A952DCCCF3E3", - "reason": "modify ciphertext" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json deleted file mode 100644 index 4c338175910d5..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json +++ /dev/null @@ -1,630 +0,0 @@ -{ - "vsId": 42, - "algorithm": "ML-KEM", - "mode": "keyGen", - "revision": "FIPS203", - "isSample": false, - "testGroups": [ - { - "tgId": 1, - "testType": "AFT", - "parameterSet": "ML-KEM-512", - "tests": [ - { - "tcId": 1, - "deferred": false, - "z": "84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7", - "d": "2CB843A02EF02EE109305F39119FABF49AB90A57FFECB3A0E75E179450F52761", - "ek": "A32439F85A3C21D21A71B9B92A9B64EA0AB84312C77023694FD64EAAB907A43539DDB27BA0A853CC9069EAC8508C653E600B2AC018381B4BB4A879ACDAD342F91179CA8249525CB1968BBE52F755B7F5B43D6663D7A3BF0F3357D8A21D15B52DB3818ECE5B402A60C993E7CF436487B8D2AE91E6C5B88275E75824B0007EF3123C0AB51B5CC61B9B22380DE66C5B20B060CBB986F8123D94060049CDF8036873A7BE109444A0A1CD87A48CAE54192484AF844429C1C58C29AC624CD504F1C44F1E1347822B6F221323859A7F6F754BFE710BDA60276240A4FF2A5350703786F5671F449F20C2A95AE7C2903A42CB3B303FF4C427C08B11B4CD31C418C6D18D0861873BFA0332F11271552ED7C035F0E4BC428C43720B39A65166BA9C2D3D770E130360CC2384E83095B1A159495533F116C7B558B650DB04D5A26EAAA08C3EE57DE45A7F88C6A3CEB24DC5397B88C3CEF003319BB0233FD692FDA1524475B351F3C782182DECF590B7723BE400BE14809C44329963FC46959211D6A623339537848C251669941D90B130258ADF55A720A724E8B6A6CAE3C2264B1624CCBE7B456B30C8C7393294CA5180BC837DD2E45DBD59B6E17B24FE93052EB7C43B27AC3DC249CA0CBCA4FB5897C0B744088A8A0779D32233826A01DD6489952A4825E5358A700BE0E179AC197710D83ECC853E52695E9BF87BB1F6CBD05B02D4E679E3B88DD483B0749B11BD37B383DCCA71F9091834A1695502C4B95FC9118C1CFC34C84C2265BBBC563C282666B60AE5C7F3851D25ECBB5021CC38CB73EB6A3411B1C29046CA66540667D136954460C6FCBC4BC7C049BB047FA67A63B3CC1111C1D8AC27E8058BCCA4A15455858A58358F7A61020BC9C4C17F8B95C268CCB404B9AAB4A272A21A70DAF6B6F15121EE01C156A354AA17087E07702EAB38B3241FDB553F657339D5E29DC5D91B7A5A828EE959FEBB90B07229F6E49D23C3A190297042FB43986955B69C28E1016F77A58B431514D21B888899C3608276081B75F568097CDC1748F32307885815F3AEC9651819AA6873D1A4EB83B1953843B93422519483FEF0059D36BB2DB1F3D468FB068C86E8973733C398EAF00E1702C6734AD8EB3B", - "dk": "7FE4206F26BEDB64C1ED0009615245DC98483F663ACC617E65898D596A8836C49FBD3B4A849759AA1546BDA835CAF175642C28280892A7878CC318BCC75B834CB29FDF5360D7F982A52C88AE914DBF02B58BEB8BA887AE8FAB5EB78731C6757805471EBCEC2E38DB1F4B8310D288920D8A492795A390A74BCD55CD8557B4DAABA82C28CB3F152C5231196193A66A8CCF34B80E1F6942C32BCFF96A6E3CF3939B7B942498CC5E4CB8E8468E702759852AA229C0257F02982097338607C0F0F45446FAB4267993B8A5908CAB9C46780134804AE18815B1020527A222EC4B39A3194E661737791714122662D8B9769F6C67DE625C0D483C3D420FF1BB889A727E756281513A70047648D29C0C30F9BE52EC0DEB977CF0F34FC2078483456964743410638C57B5539577BF85669078C356B3462E9FA5807D49591AFA41C1969F65E3405CB64DDF163F26734CE348B9CF4567A33A5969EB326CFB5ADC695DCA0C8B2A7B1F4F404CC7A0981E2CC24C1C23D16AA9B4392415E26C22F4A934D794C1FB4E5A67051123CCD153764DEC99D553529053C3DA550BCEA3AC54136A26A676D2BA8421067068C6381C2A62A727C933702EE5804A31CA865A45588FB74DE7E2223D88C0608A16BFEC4FAD6752DB56B48B8872BF26BA2FFA0CEDE5343BE8143689265E065F41A6925B86C892E62EB0772734F5A357C75CA1AC6DF78AB1B8885AD0819615376D33EBB98F8733A6755803D977BF51C12740424B2B49C28382A6917CBFA034C3F126A38C216C03C35770AD481B9084B5588DA65FF118A74F932C7E537ABE5863FB29A10C09701B441F8399C1F8A637825ACEA3E93180574FDEB88076661AB46951716A500184A040557266598CAF76105E1C1870B43969C3BCC1A04927638017498BB62CAFD3A6B082B7BF7A23450E191799619B925112D072025CA888548C791AA42251504D5D1C1CDDB213303B049E7346E8D83AD587836F35284E109727E66BBCC9521FE0B191630047D158F75640FFEB5456072740021AFD15A45469C583829DAAC8A7DEB05B24F0567E4317B3E3B33389B5C5F8B04B099FB4D103A32439F85A3C21D21A71B9B92A9B64EA0AB84312C77023694FD64EAAB907A43539DDB27BA0A853CC9069EAC8508C653E600B2AC018381B4BB4A879ACDAD342F91179CA8249525CB1968BBE52F755B7F5B43D6663D7A3BF0F3357D8A21D15B52DB3818ECE5B402A60C993E7CF436487B8D2AE91E6C5B88275E75824B0007EF3123C0AB51B5CC61B9B22380DE66C5B20B060CBB986F8123D94060049CDF8036873A7BE109444A0A1CD87A48CAE54192484AF844429C1C58C29AC624CD504F1C44F1E1347822B6F221323859A7F6F754BFE710BDA60276240A4FF2A5350703786F5671F449F20C2A95AE7C2903A42CB3B303FF4C427C08B11B4CD31C418C6D18D0861873BFA0332F11271552ED7C035F0E4BC428C43720B39A65166BA9C2D3D770E130360CC2384E83095B1A159495533F116C7B558B650DB04D5A26EAAA08C3EE57DE45A7F88C6A3CEB24DC5397B88C3CEF003319BB0233FD692FDA1524475B351F3C782182DECF590B7723BE400BE14809C44329963FC46959211D6A623339537848C251669941D90B130258ADF55A720A724E8B6A6CAE3C2264B1624CCBE7B456B30C8C7393294CA5180BC837DD2E45DBD59B6E17B24FE93052EB7C43B27AC3DC249CA0CBCA4FB5897C0B744088A8A0779D32233826A01DD6489952A4825E5358A700BE0E179AC197710D83ECC853E52695E9BF87BB1F6CBD05B02D4E679E3B88DD483B0749B11BD37B383DCCA71F9091834A1695502C4B95FC9118C1CFC34C84C2265BBBC563C282666B60AE5C7F3851D25ECBB5021CC38CB73EB6A3411B1C29046CA66540667D136954460C6FCBC4BC7C049BB047FA67A63B3CC1111C1D8AC27E8058BCCA4A15455858A58358F7A61020BC9C4C17F8B95C268CCB404B9AAB4A272A21A70DAF6B6F15121EE01C156A354AA17087E07702EAB38B3241FDB553F657339D5E29DC5D91B7A5A828EE959FEBB90B07229F6E49D23C3A190297042FB43986955B69C28E1016F77A58B431514D21B888899C3608276081B75F568097CDC1748F32307885815F3AEC9651819AA6873D1A4EB83B1953843B93422519483FEF0059D36BB2DB1F3D468FB068C86E8973733C398EAF00E1702C6734AD8EB3B620130D6C2B8C904A3BB9307BE5103F8D814505FB6A60AF7937EA6CAA117315E84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7" - }, - { - "tcId": 2, - "deferred": false, - "z": "5D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A", - "d": "9EFF3FF8252400827F3B4389E4EC07E67948257C744278048C889D0789C5BFFA", - "ek": "3A51932399C6144CA7930C3B9C165BED5BA7B93635D2699EC5C85615254B9B8705D5922A0FCB48C9B561DE4114738BBD2F043E1E0B0DD601A095CA540944A20DE89CD4B637B4AABF983C61381A1CC0F03EC8E82F1D4C62269B1114B2673EB5BEC287703C42AA6B574AE2701EB35C5A017228A7E0B91DBB34537B9B19600DCCB26869813E5B1B1A92D22C5D89CF49BCCB75F3BC8DF9648B634B992141F05BCE85F19E64597D688234AFD830B7B5A41E317ACEF6707A0A60213622564440CD89A520287FDF8556453233282435CC813FA4356478448FE5D63AAF539FD526279F02A47CA692F385A7C2D8448EF6B830424FC7A88329C7B02554B72EB2A0994A649F33254C33001FF72C1034A87D79A34F2894AD0296CA529C029A5238154706C43B76B8568775BC1239C08DA177809BBFCF6A833CB62CF4C0A7103C2C7140963861A3B653A82F008D8D78742F1985B340552723AE6EF4095D22383393065F5B8AC63CCB8974614C1C7222458D5D638FEA48C577EB9D64760898B54411A4926CA95E23AA8DDEC12CB33B8F38131C3229A97757BCADA966CF1CCBFF47758DD14875957BE9607C6F66CEAA00A32DC99E575C6F624BC29AF1CE164A1CC2D5909FF93AC25821FBEA8BCFD27FC9211A0AFA2CEDAA0B1AFC89F7F3362ABC67A52AB88763803273C8B6CB2119831DD0D7774839386838946A9067155808F07A6A846B18024506675A618C8093B6D8C8E7AB47CDC847B60C660E7524737649EB11C481EB6273B28E68075E482C4A727C1FC1C0AF904539D335BFC837BFC7F62225FA8F3692566AF3247832CFE9B6C3A92743B2938CC543374A7637ED3C36724C651DD16499A023D40B07494C3018E39BFF4303BA9A3576D8C9BEAC6F45EAAE48A0ABF4770E9C697EC4E834AE04258F7C5912BA8B76FC613914AE31035276A5015CF75A9F3126AA37BED964CE13340942081DFC620ABA65963E33320912614D18CF69656F30BA15E079BE8A53A9E68C7C5D967469294D8833A81605BDD459A65C194B15F241B0D732A0BC87231B682E84B7AEF151C933C0C83410292017B85AA51537C1CAA114690AE2FFA37B4FBBC3591BD28EC78CB5254E52EA0C474EEE871848C83A5C90E6", - "dk": "FAB74ACD14154B721C4F5446B0020EAEFA1B8CE0897607CBF4DB9CF5472751D8AD3418B76614361B30CE0195596E832DDA286D69270EAFFBBC22E11B1EF4912D02B4F02B4C4E5073A7038BBD793ACFA39C3E92615063B460920BD44B815D02ABB872861EE720D73204FBC98978D228362CBA7FB9B999506137502813F92D7958895EB8C1F3E87CCDD25743F2279E8B2C60FA814860BFBEB52F0C3441FF9265882748A8B88E656C0366CB876BA5C8A32385977C1AF0A710A033277D3C53C2942AD7F250E9B3100B675E5539AC11842C09F717B62C60E85195FC0776F80C80612C273F836C5E9300FD0904D097A7609108EFC8CE4DD1077B951CE95257E2921EAB774A97C33724E295B6C9B72C357C7953BF01D6AE4145A708A1351CB800D60A7EE0FA8348F91C6C054F21403A88EBA965196813AA184C187EDF466AA6CC33F7E11E290508DB822019F50A09965A898BA270D6CE8FE6C6A5F059DC311D9BAC0D9EE289EA323838D317A2CBBF5B9C2296EB18708015B05427278B430E7A99BB5793E9E197666A02FC44514AB7041DBB1608F2B2A4A21ED885449D8566D9575977C3A7BCF45757074C3E3631EF1548453B9068685C35B9C4CBAA3A9F9B5978B03F7274076B99A3860172D038CC1CE2345E5A6FE372249DC3289895A9E567602DFC7A0A047A5625A055109747B09B35BB9CD9412A87F92A7F282258F1594B5A9AE9D38C9768A47D4A7ED108A502C222F2B51A30A46AC90A418F6C3CF953BFB50B9229EABE3FDCC51BE021D94A6F5DC4407954C073F76C509725CD0131130037E1F0A7216BC826E5037EC60F2D736DA4B72185895AEBD41FE6E6BFCC154C00F648A4CC62C686AE787445847C5128C924F7E15046124379258B8D651A14573584B50E95AA0674228DE8D6211D5083D849657E53868C08743B6479711A9B7832B99461C629635F91512C71E5662CA37BD31298FD116A9CC87F7A0036A4A55907CBB2AA640161F8A4FC4B7AA1FAC21D67360570B17A212E6E2B672E29A3C50B9063BCBEADACBA95DBADF509672172415F006E82A313916B6E4CA705EE12AB5447214E60C33A51932399C6144CA7930C3B9C165BED5BA7B93635D2699EC5C85615254B9B8705D5922A0FCB48C9B561DE4114738BBD2F043E1E0B0DD601A095CA540944A20DE89CD4B637B4AABF983C61381A1CC0F03EC8E82F1D4C62269B1114B2673EB5BEC287703C42AA6B574AE2701EB35C5A017228A7E0B91DBB34537B9B19600DCCB26869813E5B1B1A92D22C5D89CF49BCCB75F3BC8DF9648B634B992141F05BCE85F19E64597D688234AFD830B7B5A41E317ACEF6707A0A60213622564440CD89A520287FDF8556453233282435CC813FA4356478448FE5D63AAF539FD526279F02A47CA692F385A7C2D8448EF6B830424FC7A88329C7B02554B72EB2A0994A649F33254C33001FF72C1034A87D79A34F2894AD0296CA529C029A5238154706C43B76B8568775BC1239C08DA177809BBFCF6A833CB62CF4C0A7103C2C7140963861A3B653A82F008D8D78742F1985B340552723AE6EF4095D22383393065F5B8AC63CCB8974614C1C7222458D5D638FEA48C577EB9D64760898B54411A4926CA95E23AA8DDEC12CB33B8F38131C3229A97757BCADA966CF1CCBFF47758DD14875957BE9607C6F66CEAA00A32DC99E575C6F624BC29AF1CE164A1CC2D5909FF93AC25821FBEA8BCFD27FC9211A0AFA2CEDAA0B1AFC89F7F3362ABC67A52AB88763803273C8B6CB2119831DD0D7774839386838946A9067155808F07A6A846B18024506675A618C8093B6D8C8E7AB47CDC847B60C660E7524737649EB11C481EB6273B28E68075E482C4A727C1FC1C0AF904539D335BFC837BFC7F62225FA8F3692566AF3247832CFE9B6C3A92743B2938CC543374A7637ED3C36724C651DD16499A023D40B07494C3018E39BFF4303BA9A3576D8C9BEAC6F45EAAE48A0ABF4770E9C697EC4E834AE04258F7C5912BA8B76FC613914AE31035276A5015CF75A9F3126AA37BED964CE13340942081DFC620ABA65963E33320912614D18CF69656F30BA15E079BE8A53A9E68C7C5D967469294D8833A81605BDD459A65C194B15F241B0D732A0BC87231B682E84B7AEF151C933C0C83410292017B85AA51537C1CAA114690AE2FFA37B4FBBC3591BD28EC78CB5254E52EA0C474EEE871848C83A5C90E6A8ADE3E0536F87E2E908AA77EC32AD0A8555B3045331059C5AEBBADA69D0F0735D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A" - }, - { - "tcId": 3, - "deferred": false, - "z": "7A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C", - "d": "C6636E8C2F87DD52A7F165A2A3BAD562ADB28CF738AA56B996B6062E95F66148", - "ek": "FA66C756BA9DAF40BBBEE9473B35BD71AC1DFA52A33D4A47B9BBC7EA9524DD344E086A6A0CC72941B645B3D49F6D12382CDBB843883F723078D096169F1373C6C8C5132260116963A0316E7D4268D6E36946E1AFC0457CABB3B848190E52A27BBFA42F7EBC0839E52E43611C6E49ABFD97299C4804BD08376020CC21B92BEB1B6D43EA52155B2E8D8B36B584807ACC96F237AD8365C822C66DDFD8A313849E8481A61116939CA8281EFC3D446B6CAA7583EB086FA5214DA67CA46DF75D25537A8C970CA718113DB96392B92435A88053D9141C2BC646D801E9697ED9C35A008AAB59245F56D74F64D1A81DABAB29C4571A6AC000501F1426A7AAAB5F44D4BD4BFB6E8D1CA75AE7949161B10DF906BF72BC460A08C346B5B3A5A6D3325E628546D6F4AF26F92FAEE81C97CBA29E06691AB64F185595B1F35A97A9BCB7E0011AAB485CB4ACA1E04DC534192A0B0E3C248BCF197E7D9B4A317C75C59812ED1694084CBBB8A40EDE334832B714AEA19DC2EA645CD0C3113C31C68379E9ECB5875C58C77B3084709062D77C72416CAC063D04FAA8A7825254CB2B539A78E3197D56153D4E775FF04930DF90546FC145493152A1D37FEA05A86C1A88FD86A8EF32C00B7A5EB04989AA9317C49AC7E9AC82032715F1B4CA448ACDF51198FD1BBA4FC00D1E22693572B0E1F71CF768ACE73C9733F2250B8A7BA3B74D8C12383B465C1D33881411C143FCB621C5CCD7469259A96330343352B699B7C5B850534145E10271897656F4328864A0FAC59C7886B854E8B6D7981307AB4F8B222AAA200D3435562B95554FCA31A0533B5581087AF492E444647F27789A1BC501016079B8C4F5208B0D2574206C7E6A63147950AD0190751E9C3EC0621DF05539A724732069C9D0CB2B7D77940A9A9C0AE40A4410B73B6747A1625D0548BB4AB337CED7442F55063D58CBBC6C6F70B839C8303CFB17ABEE195283A6010DA5BF86A20F7522B9CD0B9F59204C2DF50424AB659280BC27E72916542A0918AA5D618AA739729039169C7838838022E1E61805C83BDBD84BCA9A7C936060D9722DE33B2F3882075028BE255365C5523B6A9BDD23CD16255D8240B07F18D481D988D769FD9588C0BA064E", - "dk": "8D0A672A78C8D3C6A7F4608806D062DE426BF05360F33A000DA72551D56250BB8A8DA19A553A79FCD0ADE3989D1C999C5A57B58761A2D34B7F6B202910384BB38473931356E801B67BF5CDFEA96E7F541982534821D6818FA20829AB9F3F3AA05C4096A1CBB0E907634E7707E2A73DF8C213E118742CC12E0353C9D0B3BAEB296A8EE69FC5D312AA3554C2176411D009D67BAA4F07B45F5B55DFF00713CC3408C46F37389BCF149945B437EB234C81F724FAD57156D370FBF5B726193371A58C48176F8AE9A339DB91A7D7047B55C060DA7EDD910D20ABB6BB9905B41500F3246FABF1AC56BA0D2925600E333E241B72C44ABA71DBBDE6E55197B225D5C42BDD8C62E3313161DBA36094A98D555F99134CFC2382E5877D2530397FC48E7E5AA90676A7B41468C042433C09A09F7C9B5F633E636B316244191F00CF053ABA7365905B7BAA716A9645E54F75706610058761F7113D689320514D38A60A44F8191FAA5C3B13910E4218A703C98E48754B4431F630676928B5641807182C74A3A45B8E8B9568BA210EF8BACA4300E98592533A965FAB9EDD8B3004442E04340C3D3B8528283344E262B9F755E1223EE8108073A36DDF17C9DDF00276B5AC81339E1D8AC541BBB65E5A8D3857B28E60C516A75CA109C7A602B66EA6C9B0B4BBCB27C4F93C8EC44472DA9A7D7AF195DEC6547992AB8ACBBCEDCC87E88140D765518DDB3779F57C8C02C75FAB9515C3807F02740361280B539048DCB6ABB875FA6659E3083834DC450C67BE32D9709F8651840C5A4FB96B048677F9E735FCC1B0BC09CE2F1C39FEA8B0D29193EC886D02F23A413AB7E98001CDE7C8D4F69AB60C6C9270159931702BF5AA226936E7D0B53B29722AE3B29C497B5B74747061838FD8978BC2249FE83A453C3AFF02C67D6B563CE7B3FCDA452C52CA3E1282C4EB90683999FAF29D509BC4E4C41023E332E3C82433AC4371B84824B07C05A1B76D58BCE86AAAEC5AB0DD09A774291A65705BD0764A00C5CFA859938F942EE72C5520E26DD1C27B4C87C77712266DF6819A5C5A39BA8CB9667F862AC66E40069022BACA0B91FA66C756BA9DAF40BBBEE9473B35BD71AC1DFA52A33D4A47B9BBC7EA9524DD344E086A6A0CC72941B645B3D49F6D12382CDBB843883F723078D096169F1373C6C8C5132260116963A0316E7D4268D6E36946E1AFC0457CABB3B848190E52A27BBFA42F7EBC0839E52E43611C6E49ABFD97299C4804BD08376020CC21B92BEB1B6D43EA52155B2E8D8B36B584807ACC96F237AD8365C822C66DDFD8A313849E8481A61116939CA8281EFC3D446B6CAA7583EB086FA5214DA67CA46DF75D25537A8C970CA718113DB96392B92435A88053D9141C2BC646D801E9697ED9C35A008AAB59245F56D74F64D1A81DABAB29C4571A6AC000501F1426A7AAAB5F44D4BD4BFB6E8D1CA75AE7949161B10DF906BF72BC460A08C346B5B3A5A6D3325E628546D6F4AF26F92FAEE81C97CBA29E06691AB64F185595B1F35A97A9BCB7E0011AAB485CB4ACA1E04DC534192A0B0E3C248BCF197E7D9B4A317C75C59812ED1694084CBBB8A40EDE334832B714AEA19DC2EA645CD0C3113C31C68379E9ECB5875C58C77B3084709062D77C72416CAC063D04FAA8A7825254CB2B539A78E3197D56153D4E775FF04930DF90546FC145493152A1D37FEA05A86C1A88FD86A8EF32C00B7A5EB04989AA9317C49AC7E9AC82032715F1B4CA448ACDF51198FD1BBA4FC00D1E22693572B0E1F71CF768ACE73C9733F2250B8A7BA3B74D8C12383B465C1D33881411C143FCB621C5CCD7469259A96330343352B699B7C5B850534145E10271897656F4328864A0FAC59C7886B854E8B6D7981307AB4F8B222AAA200D3435562B95554FCA31A0533B5581087AF492E444647F27789A1BC501016079B8C4F5208B0D2574206C7E6A63147950AD0190751E9C3EC0621DF05539A724732069C9D0CB2B7D77940A9A9C0AE40A4410B73B6747A1625D0548BB4AB337CED7442F55063D58CBBC6C6F70B839C8303CFB17ABEE195283A6010DA5BF86A20F7522B9CD0B9F59204C2DF50424AB659280BC27E72916542A0918AA5D618AA739729039169C7838838022E1E61805C83BDBD84BCA9A7C936060D9722DE33B2F3882075028BE255365C5523B6A9BDD23CD16255D8240B07F18D481D988D769FD9588C0BA064E851F4FBEBBC2AB265691CDBF130A1A566398C6316707F7A9AE78ECC419698DD97A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C" - }, - { - "tcId": 4, - "deferred": false, - "z": "6E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755", - "d": "EDE2E63FDEE6ADA2FC6EA906AA8D92DE87FA6199AC15446B0B6F075BF9F76148", - "ek": "72828AB4196357F09AA50129BCA411CE9255422C4AC1C492A2A60544C26B8F37A7EC9B053F27656AB1AE2BE0B1C95346083C15C8F89AD92C477D5C03BB95AC4F8B6A1C9BAA8D199F1D83823072082737BEBBCC1BC1E7BFF9742C4AE86313001F2519C8E93080C2AA1D63376BD61C31BC189BCA8C8385E5A7B3A69380EB72F14B164166227B453C6F43C59A34A8B6724193D77858113AB5C90B2A605F5C3C8E3FF8BDDF82C82F0C3045A7CEBA99891A60016C660BE767809977CAE5B8ADA668BEAC5374CE54692DD02F51E9A90BC68C51955797975F63707E1DF3AC14BC877529A02EF7A317976EA722CA3B80A316B2688B074108F05C3CAAAEB0241D1C5B05D458A150B692E288CE47CCABAE255B9EA13F80D16066155B2E46524BA5A3BDF74C9F77A25402CFB4439C497C03314465C4A91152671E4F79239937BEC7A72DAB0B97B30C1A00F100216B1E2AB67C6520608F54BC92985504033CE63363E015B9E0C9BF75CC2F90AA9E09DBC221258B389585927905DE077927D3AF6C59309B12B3DDD0029BE56EC0CC1CF8AA3A5041BD954B0B7DB68AF2BC02284C9FCBF954875816DAA11E6668455C8978A247B4011B1010289EC564999D069AA2392E9CD9A0E45636C014315C15AFB5148F513CC87EEB8B56334ECA1C061058C06B3C285DA8203DCCBEA8B750E9D43E8CB837F1AA0635954A924C866C33441E7C0C23C97CF62CAE10D32C2A641C1538C2A7B1C4DBB7BF069B43D4210941A4AA0E41748D788AE831018BE1916D056AE4598834B6BD56AB86C3B7528456751B33A0406A2FCF8C0FE18C25A1C208A5A4CDBE593DA6581E27C6A5B4DB793154233CA5B3C2469A80F8C8D3C22C25A8537270CAD4480B20D47C6AC56EDAD91BFFEACBF605AD61C44BF86B7624B95CB1A5248E9210D9F18837FCB01EC68BF434725FB75FF67C016DD78E303C2C6E775D17E61642776368F17F467BC9E0E153659C5219678490BC110B8184B556A2AD275FE6913B6BC744DF313EECDB273CD637A84234601599F05C6B358312FDD959E20B81A434A6FE200AF26A50C670837E8266303A7C23219F18A670CE910DF8756E403C31C561245110CD2DE051B61979D5BCFCC3E03F68C1D3412C", - "dk": "871B000F61C393DA0F0C56B0CA4135223162F177373BB58BA97856F3A0AAAF9540AE6BB239C5221D6B3CC3BB623B5ABBA1D7CE45A75571E01B6AD429B4A1A73E0130DF3947BCE4123AE4A9AEB52987D4BEC94446CD70AECEC5CC98EA13DF3A323D8BB48B08B07161499CA76962737F36A17A4F83045B78AA33879BEED71287B70C35B92BB01AB9E7B0813DCA539F63CAC3B87B419A852104B73F05979BD8296D0967E58A6333F88E8CCC9A8A4A4E0CE25A57851FB0F568665163553BC200C190C9178526FB53328119E99C42EFC0C77729BD6873900394CAD9197E37C00FE9C703CB25AA54E73DA5A41132C1B9ACA95ABD4508872B1F6B8288477998A0842E58B1BC9CE061CEC2703AEBBD3C230AFCD2AE7E576126BC72A7925BFED55E62C06E16187E24086452344B8A5A5A462522AB693A88F57C69835DF0A603145C6DF2244A1F221977AB54C3E2023363A72F277217E15E616B54D6BB3959E3322EC9A276B7434A796BB5296E83407999F16408B11DDC79CBCEB46D01033C5FD091300855D7E64536480DD945CD33CC9D4221ABE5014D068BAE1851717633AE03E6627BB17976ECCE84807D5C2602030844AFB30994D26CDAA0C71AB591AE6069403C13E4B6BA89439F2C5393955AA1C4A6270339505B59009DA51527C33334D6903DF3A37613546F076AEE723046C13FFC729D64583A4A01CAB68C5C95C25706F0A918635E61A390FDA5745A9756EE32975CA4483982505981A3589232EAC3C0C31748A49429A711CBC16355DDD10660557C9270438D9635850918AA366A34B251F311C65C579FBBD2341A53CB79BC9A993475CB6AB9455B82A9DB5EBA53592EEC9A2C481792798A1483037F115336FAA8A4B07AC253B0A347227A7B12E3197531F875C91B0A636107CB38BB0BD613B057869403A77DDA0A80A26266B61D14A75433B99BA055A7FB625C4A17BE9A92B2E168899B6539972B4BC674040645496972617FF70DF5EB63B17B03F54BCAEB3118C4F31EAE075D2C1C9F1D5036FEA818A539ADEA50795AC933EC886FCC248E49F12DBBD23D8F812BE0678B19888116254A27B5A372828AB4196357F09AA50129BCA411CE9255422C4AC1C492A2A60544C26B8F37A7EC9B053F27656AB1AE2BE0B1C95346083C15C8F89AD92C477D5C03BB95AC4F8B6A1C9BAA8D199F1D83823072082737BEBBCC1BC1E7BFF9742C4AE86313001F2519C8E93080C2AA1D63376BD61C31BC189BCA8C8385E5A7B3A69380EB72F14B164166227B453C6F43C59A34A8B6724193D77858113AB5C90B2A605F5C3C8E3FF8BDDF82C82F0C3045A7CEBA99891A60016C660BE767809977CAE5B8ADA668BEAC5374CE54692DD02F51E9A90BC68C51955797975F63707E1DF3AC14BC877529A02EF7A317976EA722CA3B80A316B2688B074108F05C3CAAAEB0241D1C5B05D458A150B692E288CE47CCABAE255B9EA13F80D16066155B2E46524BA5A3BDF74C9F77A25402CFB4439C497C03314465C4A91152671E4F79239937BEC7A72DAB0B97B30C1A00F100216B1E2AB67C6520608F54BC92985504033CE63363E015B9E0C9BF75CC2F90AA9E09DBC221258B389585927905DE077927D3AF6C59309B12B3DDD0029BE56EC0CC1CF8AA3A5041BD954B0B7DB68AF2BC02284C9FCBF954875816DAA11E6668455C8978A247B4011B1010289EC564999D069AA2392E9CD9A0E45636C014315C15AFB5148F513CC87EEB8B56334ECA1C061058C06B3C285DA8203DCCBEA8B750E9D43E8CB837F1AA0635954A924C866C33441E7C0C23C97CF62CAE10D32C2A641C1538C2A7B1C4DBB7BF069B43D4210941A4AA0E41748D788AE831018BE1916D056AE4598834B6BD56AB86C3B7528456751B33A0406A2FCF8C0FE18C25A1C208A5A4CDBE593DA6581E27C6A5B4DB793154233CA5B3C2469A80F8C8D3C22C25A8537270CAD4480B20D47C6AC56EDAD91BFFEACBF605AD61C44BF86B7624B95CB1A5248E9210D9F18837FCB01EC68BF434725FB75FF67C016DD78E303C2C6E775D17E61642776368F17F467BC9E0E153659C5219678490BC110B8184B556A2AD275FE6913B6BC744DF313EECDB273CD637A84234601599F05C6B358312FDD959E20B81A434A6FE200AF26A50C670837E8266303A7C23219F18A670CE910DF8756E403C31C561245110CD2DE051B61979D5BCFCC3E03F68C1D3412CE81BFE29AC4AA0EDF35537F3ADEEF43D0411B85C7E1D1C54612167DCE488EBE36E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755" - }, - { - "tcId": 5, - "deferred": false, - "z": "37B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22", - "d": "CD568FB1EEC23C436C011A55BE2FD4362EF000C890BDE7611EB5C4618AB74F8B", - "ek": "F2137B2BD0A33F81C4DF584BB46C60FED985D09589C125A6F7A9C4B3132F7BF4A4B4A268BB52702C3B5DED770B3AA30EC2708B93500C5E3C6998FB6EA1586EAE409B6D617C330827F2A417DEB0007C78C8F8C025B8C3415A31313378536EA672FF92625B3443EBE61836421841750E1372A81BA99825B67898F2009E4AC8D5F89396724B7BF29E16C72C1DF192AA5277F01A5428B4AF8B284D85D987E015AE1CB89AD9C9230E2313601B5B49416D0B18B9D75326123A02E363C444993213D387A1C7A021449FE4E35C4FC30DF0066CEA593BF7DA67EF6322537802CF068E2D56B178F929A630C3A5043528A489928CBE1A1468F2802F8F890C042114426BCE7FA6A335441BF1B159410C62FED916CEF3B0D6F0B54FDC3ABF9778743A87D3F417EE573897B45CD5BA4F893CB13AA077A696BB37DBA964D0189FD83DC725129D9425D9291652CC84EB3145FDC88482407748985D72C124EC835CD800BB11F81415A44E474BC553998C1CA945FBB0035EDA52B93B3D341A29E7F808418AAD2FE388D0483E15F68E3B903E7D9C6E051347B1988B6A0A441C8B1FA05C743CBA003BA946BF07996EE14F9E93AC88382CD7F2CE8028352CA7C36A73C9303337CF5377AEA685718C8802B7683019892A904C5ADA3661C1CCA5B4CCB81350D8484BA34CA49AC15B9DA09E1E6887A10802060AB20E04B0142367BEE71CFE023A15602BA83B7761FB08CF79424715CB6CF563E2ACB3E11CA3D6C4095084779213275E13A1E7F14389C301AD53CDE6369E6A9058CE282530593A9E8B1BF38BA08F40B85A94678B619550C437411861B957528CD0175170A1F2308B766209EBF454B4AC4E24C1B230CC793C935770543831131CE38A77A7248C43C79814A03E35D8CBFE02A4F5482E73B1B7F41569E42443A733CFA185B63A120809007A46D5C718C003DE2945B295C0EC42C30EF5BDA5107ADB2125A5E61575382F961C43A585C7400C5AAFBA2BCF595C71C94F0F59CE48904531E0C2EB862C4E66CD6CF280A84B926C42489CCA778A587F0935B7CA369B1140594A1114DDCA6A6F104671CA26E8804EE0D0513F39519217F5A027363BAA21AA561E954B5494D2482873722C7BF20ACCA9B880", - "dk": "DAF41A7FBA550B084674F174453A18D33994460409F80232044AB7411865F90281EA191165940794957CB0C26E1609B941117C38350F653A04E28438D54C3452379687EBBE463A4A7447CEE3836E7EACBFEE6AAFD5114DF0A595C9F98FD85C2DE879857236CDD0287B2F0041E58390C5510E1D288B0F690A49451B1F7002E13594CE71045AB1B455A280377393F54A0BB0C44EE06C024733675A1821E619434401608A824F86ABBB55B07B1DBB7A96B0B88C6885735966DCEC666CA3281352B8651A8C13E48C52C61220572676E500A6E0A5FFD238A76CA6FF29915CC975B3E5B3B6819C61495410F095023077EC3CB282675578C948B01C63146B8904C56A1D419B1FC0AC8E5B5CFEDA4D8A8A562206B4A8E93EDD180936960CCD206964EA5CD9D4BFD3540A4D5BB2AF302A7594820EF8115F2B0E38324EB024AD5E6AC92584C681D5A42079450EC464B900BEC5D9B8268A843A5095D2F41DCD648CF30B746F6C4EFDD77A5C432100073CA36B61C0EC4C4D64341A675E9E06369EC30D0E63CB702B6D32CC1DA0253D4CFB08E2255FA5A3B29305520AB737B5D820A0817EC5BB4A99C8936A5B396D927FA97177573CA01E568A67EC059E897A75E058429BA03321B2D190BFF5F8A4C1AA3CFF7A54EF3BBECFE4985BF253B2F126B092A8808175C0AC253C6C9BCDF3710C7B90FDC77B4F95BFEDF78347E72F806191FDB4481CD7794A993EABA23AF5E76A081243D54C118868BC1C51A2AC00808196573326AF95A1B4A4DA8AE0173588A978130772792284AF456E8B651A974A09D5795F0BE0B08F1570A6C21B33440FAE93966071ACEC727FD74728E4A9A1EC7687AA2884BB6B4A599129F857113637BF248C54CABC6BDA91739036B7B605491625062678638BDA4F111BA376DA0D04262BA8A082FCEA37E9C82FFFB330BB15506FE8038D6CAED266BC63316BECD6400DD7297E76068FE16A7EE6A13900857AB6C2D8234BAF41C4967C2535F9BF8F888DC655887B5C74F6D17A9AB2AB16F02D57D311CF6700CB238C297489C5016A09A15BAE7428128B158C23000E80A88978993E956489B93BF2137B2BD0A33F81C4DF584BB46C60FED985D09589C125A6F7A9C4B3132F7BF4A4B4A268BB52702C3B5DED770B3AA30EC2708B93500C5E3C6998FB6EA1586EAE409B6D617C330827F2A417DEB0007C78C8F8C025B8C3415A31313378536EA672FF92625B3443EBE61836421841750E1372A81BA99825B67898F2009E4AC8D5F89396724B7BF29E16C72C1DF192AA5277F01A5428B4AF8B284D85D987E015AE1CB89AD9C9230E2313601B5B49416D0B18B9D75326123A02E363C444993213D387A1C7A021449FE4E35C4FC30DF0066CEA593BF7DA67EF6322537802CF068E2D56B178F929A630C3A5043528A489928CBE1A1468F2802F8F890C042114426BCE7FA6A335441BF1B159410C62FED916CEF3B0D6F0B54FDC3ABF9778743A87D3F417EE573897B45CD5BA4F893CB13AA077A696BB37DBA964D0189FD83DC725129D9425D9291652CC84EB3145FDC88482407748985D72C124EC835CD800BB11F81415A44E474BC553998C1CA945FBB0035EDA52B93B3D341A29E7F808418AAD2FE388D0483E15F68E3B903E7D9C6E051347B1988B6A0A441C8B1FA05C743CBA003BA946BF07996EE14F9E93AC88382CD7F2CE8028352CA7C36A73C9303337CF5377AEA685718C8802B7683019892A904C5ADA3661C1CCA5B4CCB81350D8484BA34CA49AC15B9DA09E1E6887A10802060AB20E04B0142367BEE71CFE023A15602BA83B7761FB08CF79424715CB6CF563E2ACB3E11CA3D6C4095084779213275E13A1E7F14389C301AD53CDE6369E6A9058CE282530593A9E8B1BF38BA08F40B85A94678B619550C437411861B957528CD0175170A1F2308B766209EBF454B4AC4E24C1B230CC793C935770543831131CE38A77A7248C43C79814A03E35D8CBFE02A4F5482E73B1B7F41569E42443A733CFA185B63A120809007A46D5C718C003DE2945B295C0EC42C30EF5BDA5107ADB2125A5E61575382F961C43A585C7400C5AAFBA2BCF595C71C94F0F59CE48904531E0C2EB862C4E66CD6CF280A84B926C42489CCA778A587F0935B7CA369B1140594A1114DDCA6A6F104671CA26E8804EE0D0513F39519217F5A027363BAA21AA561E954B5494D2482873722C7BF20ACCA9B880BC69A3AF4B4C837C8018E52F6A1466D86D23BDBECBDD1F610245F0A670ED311637B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22" - }, - { - "tcId": 6, - "deferred": false, - "z": "4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E", - "d": "35DEE1F800CA85E482BB12AFDB882FAE62CC77A338E65CA2265D77243ADAE3F3", - "ek": "49B884A964CAE5E0223906A09366063C46250A551DE820A58FF3CDE2C69719316B91F6CF1178768B082F97822DF4D6172ED11876940230978B6B0156EC190C462BA75DE722E206535564A68F311C7EE015701CCD7E954B5B4074CF43CE700C70B221ABB2198FE63639D622669F309855C490F916BF39917E3E440C97FA6BFF270AF540476215A8845A88D3E3528F6715E86C26164B86F28263B01123DD05553B8964775B0C4E50A8DFE08CBF08B830A0973A963A09C1B077564EBC355A07546BCF2422C42500F9B26F586B2873ABC392633555F72126A2B51EC935333939C73580E44314407ABEB4B06DFC570287C5B758E8AC30A6B2E912833E2B72C55CB9BAC9BA7FB2AC03E560796480EF9A4342D49A6FC19E5C1A9386826C42EC6319759B1CA260D43247A0756E857A00D05B78AF65A9759159EEEB72E7118CB6D039930584111A8F2E0CB5FB449423871F7030AB5908B964C2ADE84195802521C16088D14403EBEAC1A7963BD9DA827DF908752568B230919791A6F21AADDDC05E77525FAD0323F215215DF107B4A3474DE3711A447192537145127D7CF2B33F9A4268106B2CE487612B000E6B9520CCC70D7225E2A6055ADA0DB8F024333AB1EF182C8309A697666FE2850C29A1B7B9394DCDDA8AADB9C3EE2910AD1CA85E34874ACCA693C8CDCB66A477E38CF1B5AF5B97260377B4A43B8C0E085C41F5B2EE44B4A7CA1D58D9720C62475986798C13C1A8887F3EC660C04C92F0AA7F0C581407F67CA03247DFC5AE411CBC6F3BBC6F16CA66B8389BBABC9193C22858AF6BFCCF5A4595747B9F9F9BA043E69DFE06110BF970B2F4C9FF1A149F76CC4A64C7C283A716791EA6CC6B3554367A83AE1545054B02A725185EC8042966F10F3F3B4EAA872DEBF7B10947986D1884F3C59116538A85537016B03BA4B7A156061EED350BD04868A60C93ABBB05F97314BAC935EF99BB4301C4EE6A59936443A7298F0584980E588E76CA44F12182DCBACED7F90F4C864F8747C0F2B6A796083656FB9953495787071E61B41B46B582771320B8969C9B5941055637D69A5D0DF3C798D00D16E7259CAB3C67520D2FDE0A3C05715DE22382E369D7644EA2C180C0FC5385E6394054", - "dk": "4795036ADB898D0B5E69AA2F9913270B8899A97750A219C2B88C2BC0795CBE255E04E959A081263087706619A1C9C19FE54C05B14B1BF3E5910E128643771DA298839CFA2D752836B1759C5B58CFCD3B4782976EA96729315958FCB11C66B25F0A1B57EB85B1B892A0937A877C4508796B3D6DF66CC19598D55B9842C848A7485CF87ABB2A340497CAB032376E16613B55147C78864B7D0B9AB1F52985F32561A3A80AA4BE63588983E90EC659B2C9FC45207972C8199B46095BB56B878E256732C892C9395021521780D40778C4BCA06C91404428FEB050F44225CE0693972796A3D2AC3C028377782F9C26528F45962175C42B526872E6B34D95355BD0B1EAA2707B6C2A7F1074217CAA1EE842C4064A5D556B9F70C37A7C52CB468694245E427CC71959B390BAA5FF744869165189C1A4A43BB3D39A9799A17305999A9F3171711398FB412D3BC4625FF04444B0557A765FE785414BF08B308A5F44A64CEA59988F294483F623063B602D55624BE494F2D057396883D48995D10080AB399663C00FE0E17162B2C47A19BD2A69CDB2DB76A3861336F04C2FE0A498FC9698C34BDCE751CCC3C9D4E9539CAA0C6523C1C3AA87C65908D9045203C32AB19442F0065CB1003E02E735999441DBB7ACB1E73C92C62E87D7A4A65A508829739A576B13A7C94331146EA66897248B4887862A4152B72B2FC1B9C7CC7447C8E449EE93BCB5F88AFC43226EE51AD47BB548C665A9A2833AB7938FE403A602051685A3CC89B4AA6225E47564DD09D05B101CAC312369A54B320194710AC53DF57C5479A7485250D1EACD5B8BB19069266A03C852F81947A1BAC5005E344447A9DB5FC4B87255C638524A9ED255BDB9700B31D514A5A72E08A51F42D963D71A88BF605E29C41EB8C88D48BCC0493CAE6129BA4B046B54AA08177634C8E8B1A5A948301256D3C3B6A9A8808B2B0F3716CBBF196427C661F342CC7B50CDB56990AD252242C2C996FC98DE1A26374C0575DB6773937F0E86A16F051D59DCBFA88058BC4801E096BAF9866B9C5A01A922A6EEA34D22CA346975BADBD28454821EFA0B1288281849B884A964CAE5E0223906A09366063C46250A551DE820A58FF3CDE2C69719316B91F6CF1178768B082F97822DF4D6172ED11876940230978B6B0156EC190C462BA75DE722E206535564A68F311C7EE015701CCD7E954B5B4074CF43CE700C70B221ABB2198FE63639D622669F309855C490F916BF39917E3E440C97FA6BFF270AF540476215A8845A88D3E3528F6715E86C26164B86F28263B01123DD05553B8964775B0C4E50A8DFE08CBF08B830A0973A963A09C1B077564EBC355A07546BCF2422C42500F9B26F586B2873ABC392633555F72126A2B51EC935333939C73580E44314407ABEB4B06DFC570287C5B758E8AC30A6B2E912833E2B72C55CB9BAC9BA7FB2AC03E560796480EF9A4342D49A6FC19E5C1A9386826C42EC6319759B1CA260D43247A0756E857A00D05B78AF65A9759159EEEB72E7118CB6D039930584111A8F2E0CB5FB449423871F7030AB5908B964C2ADE84195802521C16088D14403EBEAC1A7963BD9DA827DF908752568B230919791A6F21AADDDC05E77525FAD0323F215215DF107B4A3474DE3711A447192537145127D7CF2B33F9A4268106B2CE487612B000E6B9520CCC70D7225E2A6055ADA0DB8F024333AB1EF182C8309A697666FE2850C29A1B7B9394DCDDA8AADB9C3EE2910AD1CA85E34874ACCA693C8CDCB66A477E38CF1B5AF5B97260377B4A43B8C0E085C41F5B2EE44B4A7CA1D58D9720C62475986798C13C1A8887F3EC660C04C92F0AA7F0C581407F67CA03247DFC5AE411CBC6F3BBC6F16CA66B8389BBABC9193C22858AF6BFCCF5A4595747B9F9F9BA043E69DFE06110BF970B2F4C9FF1A149F76CC4A64C7C283A716791EA6CC6B3554367A83AE1545054B02A725185EC8042966F10F3F3B4EAA872DEBF7B10947986D1884F3C59116538A85537016B03BA4B7A156061EED350BD04868A60C93ABBB05F97314BAC935EF99BB4301C4EE6A59936443A7298F0584980E588E76CA44F12182DCBACED7F90F4C864F8747C0F2B6A796083656FB9953495787071E61B41B46B582771320B8969C9B5941055637D69A5D0DF3C798D00D16E7259CAB3C67520D2FDE0A3C05715DE22382E369D7644EA2C180C0FC5385E6394054BAEFAE1CB7C96BC32E97C146C2AD302DB01C6E7B8E43BC7A236C00C6FCA6F17C4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E" - }, - { - "tcId": 7, - "deferred": false, - "z": "B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871", - "d": "D9502C86FB461300B8D142A906B766B0B42481EA9C83AAE2BB74390F882B0509", - "ek": "36C0A54CE714E66B18D200AF7C822E555A9BCE32884D2313C0012FDB81436D8038C37258EDECB2EABC9174974758C55DCE98933322B49CE815DE3B83F3F4A7C0D7CEC0D2A08D68475853B64D21ACEE3C74BAF17C19306BFFEAAD2303ABFEB0AE941839A4F69B48B23447081BC42BC1CEC648C9D1B319E778DDBB262A7B7D0A0946E5B7B71AD54E881C42AA6B1DF268B998D45C2CA18B9F35900A6106F1D8CF88F07C37A7AE283AAAF1B94BCAC6A102F631053760C57B157A098FF4F47B023527BD526365259898484211749AD8493ACBA57C2E02C346EA5032553F2F590F785B7691C83DEB9C7124318969FBBEB81C361F6CADF4EA78C27185CD9B9BD99670ECB41F56C4CC261A39EC251DF34A144B189E108094244557F217312B1BA083F7804928C4950950CF75555BB0B7140406F38CC8B9D21449A756AEC213328AAFD6A8596BB20152BA888F4A591CE162968BC263984655F332ED420473FB6DD0BCCA2D0A3595E43046C61AF6D6317C123BC18AAD6E80736F41BF97134CA7DB2DA8C963F9E2518D865F7FB770C5BA20C2501B44A36E13782583C1579133260E41A77871CB0CD7827D7015FB66251EE9622EEC007FA88227C153B9E7509866AC836A85BF960182F14032606123608E302C0C07D2BDF79B9C398CC437A7A3A2688E0327418B483D1C2B6C3B92B76554A7E14555BF742180FC7F2036C260F50AF5D47AD24033FC62B08A6C10E2F0096B4C5EC5DA8260D2CF9B3816C92A353148C19AC410466C05699209C6B0628A5CA12472544AA822442B93D4F549F5C94A54C4A3BEE5A9375B55B69C77DC260AFE242F6333591279AD1E269D36F02722F62D235186074B3B1AD1C731E0A36996672E74797DC7BA677AA577A523FD38A4A3FA71B7782185911BD837432920A753996776465D33692C859252E294622EE86F2340A5BB624898774851B587B6203A7E94CC909623D027C9EF06493596B9E6A63C02A4CAD21B2EC4792C6FA70ED9AB90D8988F85D24BB37579D4A71C0823167DCC30382178E12C2082AC70F1D7A2DE652296A203D93C2E3CC1473C411C17390BB0ECA50981905AD7F76DCD197C5867AF1F94E3221BF042DCDC99B3B3679587BB2507C464618D", - "dk": "F9AA2D50611583687E826193429B23F39B07E2988D6A018D98E05E01A853C40BA5E321730868A55D245769F17CAE243F39D6389346A307934BEE6A011C4A00ED72610E61548A64C5F2D98BFAC484518C4304E454289CAD24A5BBFD3717AB191E5C83AEE1E22CC1B756C147786A13580715B3482A5301D2271588BE13374251B68EDF6024AE553F1BCB83CFECBB4DA1A0E759627A37BF3F83B73E267D40F867629380482CA32D6743A5C8565C7AC3DB3542813B010E98642B490B361638483728B47737A1B8367EDCC93D8B3960EB963038184AB09DF1945A154A8437556CE659054AA64D81048032375D795A21C89B5F5DB68DF203C496A06CD9B26B6331B2B00BC5ABC95DD6BB596DA819958A11A2F57A8C85C9471691F7570F41C0390C6571BFA22A91909BC9C09070C0B1A0F5AEBE59ABF0C3C36B2C17A5D1767454C15697C10CE453A1597F63440D6127A09941A5FB3A96DFFC86C82015BC623986E6BE7CB02AAA23B5D5E26E4CE01F8FD91D99B637A5BCAA23532D46B993D4EC5797C28EC6D248589CAC83A600A7D555E3EA7F07D09726B174AF282162A3B268A5280CFB6AAD7012E7E639598AA2003D9DD6707FA285AD334619978BA227B879B1F37DF83157DA95B5DE8CB66A01D036E766262719E21224A65932C6D1185676598BDC51C4A29330BB8C4B5176A069B93848B57BD24AD5F277A5681674138B5C1CA73075706C9797D6F8BF23E2AE5DB44D5D6B4144C09AC9C6BF6E556790968717C847A6C01AB99215162BC5B2DB6E02E19ED568A56C54BA4735A793DB473BE5708C705C784B9EE2E02532855F2F420608990101E34CA930C63A0833744B67965BCE0C1ACA3D67793DB7BCEFB32A7D378D38E87209F69C66097908EB8B07A94584335F37C44586A55C5024847C654B97C85BACE70B495559BCB60AB1625525E808DCA2496F549C8130CCAF60BDC3F782DA61AA98E03A80C05C6AF99308165B1291AE613C97C646A46E05AB87796DF6447E1D8326C03A7E9D7921BE218B69D469BA2449E5C714B7C5B1385C407BE14E7A978566E27409B72D04B9540FDC43D7BA0C95754C36C0A54CE714E66B18D200AF7C822E555A9BCE32884D2313C0012FDB81436D8038C37258EDECB2EABC9174974758C55DCE98933322B49CE815DE3B83F3F4A7C0D7CEC0D2A08D68475853B64D21ACEE3C74BAF17C19306BFFEAAD2303ABFEB0AE941839A4F69B48B23447081BC42BC1CEC648C9D1B319E778DDBB262A7B7D0A0946E5B7B71AD54E881C42AA6B1DF268B998D45C2CA18B9F35900A6106F1D8CF88F07C37A7AE283AAAF1B94BCAC6A102F631053760C57B157A098FF4F47B023527BD526365259898484211749AD8493ACBA57C2E02C346EA5032553F2F590F785B7691C83DEB9C7124318969FBBEB81C361F6CADF4EA78C27185CD9B9BD99670ECB41F56C4CC261A39EC251DF34A144B189E108094244557F217312B1BA083F7804928C4950950CF75555BB0B7140406F38CC8B9D21449A756AEC213328AAFD6A8596BB20152BA888F4A591CE162968BC263984655F332ED420473FB6DD0BCCA2D0A3595E43046C61AF6D6317C123BC18AAD6E80736F41BF97134CA7DB2DA8C963F9E2518D865F7FB770C5BA20C2501B44A36E13782583C1579133260E41A77871CB0CD7827D7015FB66251EE9622EEC007FA88227C153B9E7509866AC836A85BF960182F14032606123608E302C0C07D2BDF79B9C398CC437A7A3A2688E0327418B483D1C2B6C3B92B76554A7E14555BF742180FC7F2036C260F50AF5D47AD24033FC62B08A6C10E2F0096B4C5EC5DA8260D2CF9B3816C92A353148C19AC410466C05699209C6B0628A5CA12472544AA822442B93D4F549F5C94A54C4A3BEE5A9375B55B69C77DC260AFE242F6333591279AD1E269D36F02722F62D235186074B3B1AD1C731E0A36996672E74797DC7BA677AA577A523FD38A4A3FA71B7782185911BD837432920A753996776465D33692C859252E294622EE86F2340A5BB624898774851B587B6203A7E94CC909623D027C9EF06493596B9E6A63C02A4CAD21B2EC4792C6FA70ED9AB90D8988F85D24BB37579D4A71C0823167DCC30382178E12C2082AC70F1D7A2DE652296A203D93C2E3CC1473C411C17390BB0ECA50981905AD7F76DCD197C5867AF1F94E3221BF042DCDC99B3B3679587BB2507C464618DC0D607E1D82C3729DDE4E456836E956E187ACC8BB29F262BA6B5038F51F9F8D3B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871" - }, - { - "tcId": 8, - "deferred": false, - "z": "671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A", - "d": "07A9BEBF21C83F6E5417A73D8CF5B527568C903B5883CEC8347B4ADE73AD92D6", - "ek": "A2178E9F524466CAC53EB49DBC5367F4F096394526BBFCBBCF0178721902A0373BB4520D50F039517950C5C0115FCB53DE3ACAA4916C94BB19D746972DC882129B3A4F658E4671B538183A93B1775E56845C00569987103D1A3270D17D0C807EDEDC3F9390774F074741611A3A2B8723C671CCF6688051CFAF25B2310221BD0290F5E6C32DC03DD44C87E395B7E8B56FFE15BE62926411AC28F1A34DFE5B460091520BA244EF5A0D26401DE2B3A64DAA9CCAE3C6A09823D9C84DE1A17E1E94CB26992050F2381C3C947EF575C564CCB6580148A12200E97D9F2969295A90EA78548743C95D15AC8FDB0D91B83AF0A9A75A862AE2558FFE6A7CDA7008F0CC9B5831642047841314406DD0815A09ACA883667F080C6AB959C969140A767FF56A087DA5BD285265149963404293E2E1BCF7599A30A20CAAA056D5285C2731914D85C9F87BB3FC613A809293C81922343A0565B27B779A72BBB0B961D1AD8AC4AF5EC677F997A29C38BEF5F6CD90A897F379871C0B658A7849BA2C43725694B361331236ACCFB55C5E9650277C3D378259067354A8E2167E5578D8F8B610476B997403FAB4AEE365C118929956309B7F7114BAEABFA43408820593D334834B1826C9E705092953C5B73421785C3371687D8C366F9420706389A06198422BC13BAA7075F9B54BF6679A166942E231E1D60637B42FE9BC00E0A9ABC646B3D740201C3985EFE87FE5467F88D6456423A58B07B8FF8C1159E738DCB1A2B3313654DC9F60A072A34ABC3A8ACDBEF6429AA5C088666A9FB14119B69D37D9369D1662DFF3487E826686E812CFF23CEF60C52948424C4A11A933A2D28A8FA880A3E6753CAC7C79F4E111893016E0C067573CB588A6B1FDFB23DE855B9BA6441A837C9F47329A014732CB3DA8B9AC850816E7EAA56584734F3B60E8C732214A86D0309FEC791E7EB28A93836A0FD85C5FD497CED070D71101EACBB92A052140393B18D83FEF654CDF1CB587B2B5CD56CE8C4215C57C065F954CE2A2C0BB65744DC8C2D49930702663D2A0173E515450524B973B7AF4D6B7C816773B6C3B68EC1A06A3C74E038F9143015D3401CA6DBDBEF1D5EF5A349B1C9DAFB96E20DCFEE7BA2EECCE5A3AE6", - "dk": "2B409CB0052C3BB60811731A4CCA005D8C06028BB26D166770E680B1C3CF981608DCEC93069393EDC4559E56673D0B12B8884B8056BBB988672D373E26A3268153288EB91D1EC4642657B7081B7EA587294074555067ABC197A9FB83A15502CD103458CE2736FAF068B2344163A6913E8A232601C217ECB3DA3B57D8D4AA0AFB56A4AB20D250CF97206D78FC004CFA63DB3C27233B3A9A1B8369B102F03AC44F231683F10C4676C2E0BC19273606C8534C1151ACDDC299C9F0C432CB0F03FA1A8FBA4299B4C3AB6638FC924742B8871876989B7C4CC3685FB09B68F5F7126B5645F9D365E5342B23A12E09E4B7CA3ACC3EE06EACE941EAF54A8475492537295F732D8D88538A594CE96333A5E16EEF42155D241E0E2A1077477929A9C51B6737942A57AF4964E26CAD78F22859C453FCD1927592CEEC583724718C92B4BCABF121BC079992A1CA574894ABC1C364456D806A435291CE2C702247F286E9989FB108283B52CE5B6A209BF43F1C991BA200550D90CE2B2A23B715519AD3BC3ED277AA6A50975C2B54B6B47AE7C7E55A7B28BA996ED344A03C21824C9F0E0C55050A54F1F4CC3955353B955419B4BBE0962FB8D4C9EB94B2D2764BFEB41EBC6AB8383B4B6D58B97FC9394E6AA2D1B389E4BB5C4A72AECA0780F15B5F29D5910D3A40D1D21989379C640310F9598F05607F2E47129B27C347830388CA25DC0721B9927FD4B594819965843083B4D761DC76C67626393353999BB4149D4A0B7B5BB51987C96F10731E2BC51ED7621E68179120869226CBC3D4A5B4D07DE6E5396747674150B07720BAC4E94A982B76ABA552E880BE6B7227357028528A26850750685C5B73AB95FBAB8F0F604E3DCC5B4112A72133478942C68A878BD9D92C0E6CCAFB46B57E563C062922AEF461FD093463483C9A2188AE9113B24748077AC624726BD3D30D354497616359B292A9C4381ADEF34B215BB326147713274284F6B3CAC38A40BC9856E459C029A639299B528BA553C892F2219635D0489456B3577AAC3453B6075A72DBCA89B4F27B16F55B5E1C1A35214F24579033E5584A813F8F502DA2178E9F524466CAC53EB49DBC5367F4F096394526BBFCBBCF0178721902A0373BB4520D50F039517950C5C0115FCB53DE3ACAA4916C94BB19D746972DC882129B3A4F658E4671B538183A93B1775E56845C00569987103D1A3270D17D0C807EDEDC3F9390774F074741611A3A2B8723C671CCF6688051CFAF25B2310221BD0290F5E6C32DC03DD44C87E395B7E8B56FFE15BE62926411AC28F1A34DFE5B460091520BA244EF5A0D26401DE2B3A64DAA9CCAE3C6A09823D9C84DE1A17E1E94CB26992050F2381C3C947EF575C564CCB6580148A12200E97D9F2969295A90EA78548743C95D15AC8FDB0D91B83AF0A9A75A862AE2558FFE6A7CDA7008F0CC9B5831642047841314406DD0815A09ACA883667F080C6AB959C969140A767FF56A087DA5BD285265149963404293E2E1BCF7599A30A20CAAA056D5285C2731914D85C9F87BB3FC613A809293C81922343A0565B27B779A72BBB0B961D1AD8AC4AF5EC677F997A29C38BEF5F6CD90A897F379871C0B658A7849BA2C43725694B361331236ACCFB55C5E9650277C3D378259067354A8E2167E5578D8F8B610476B997403FAB4AEE365C118929956309B7F7114BAEABFA43408820593D334834B1826C9E705092953C5B73421785C3371687D8C366F9420706389A06198422BC13BAA7075F9B54BF6679A166942E231E1D60637B42FE9BC00E0A9ABC646B3D740201C3985EFE87FE5467F88D6456423A58B07B8FF8C1159E738DCB1A2B3313654DC9F60A072A34ABC3A8ACDBEF6429AA5C088666A9FB14119B69D37D9369D1662DFF3487E826686E812CFF23CEF60C52948424C4A11A933A2D28A8FA880A3E6753CAC7C79F4E111893016E0C067573CB588A6B1FDFB23DE855B9BA6441A837C9F47329A014732CB3DA8B9AC850816E7EAA56584734F3B60E8C732214A86D0309FEC791E7EB28A93836A0FD85C5FD497CED070D71101EACBB92A052140393B18D83FEF654CDF1CB587B2B5CD56CE8C4215C57C065F954CE2A2C0BB65744DC8C2D49930702663D2A0173E515450524B973B7AF4D6B7C816773B6C3B68EC1A06A3C74E038F9143015D3401CA6DBDBEF1D5EF5A349B1C9DAFB96E20DCFEE7BA2EECCE5A3AE6E2DD64A46E296448B930EA2D39F462B16DD4AC6AE402DA573C0968CCDAAC7F50671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A" - }, - { - "tcId": 9, - "deferred": false, - "z": "C02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F", - "d": "F682949EBFCFA5DA31368E3F177DD146448D0E62178959FCBA4CD4F02CD8B17E", - "ek": "0285512CF6422AFB54DD1C54CD200FFB3AC28AE053E8B6443B96C83DE8595F710D883A513271CF0D93804BE93C84B9A754802C04455D89887DE048B2484088733A701847300FF3B137F509D46033CEC89A4B9602D5A83F77CC20FF4066BCF95904E2789755359F7B04B174983CC883BDB393BE2A02FD3433FEB126A4288EFC4670B0670B2715CDC5700DF6631DF29643E33382EC89B89BB1AD41C6ACAD704BEE982841CC588249BB91A818890BBB3C590A08446D88647FCB5CB15824CDB09C55FAA2457961BB3C79ADAA833F55F154072CAA445B8D61E23993CB69441C956492AF07E702568A350C01BD072CB2E379071845A67149B2F7B2358551770A34A9AE6AB45B2B6D5F700E597184A1425B28047817720C1981C583717F7F4BBF2F13A6D31A691DD3951310A9D135591717A451F00FDD71ABF325B041E3A1EB095F31D27653D1AD0F3CC945D431333A3349B7B8D786B16769309808C11095209CCA1442AA40B9A863B4973E85586899ABC17D1034E64505C1F9987172538E227111EB86A66C9077C268B7A24A477991DDA6753672BD972510EF3347E1B7314BE172A457A4A0B9909718418C478D396B9F15BB6D49D919E192BB714BA992686292056DEB4B1AC84C0A356911437BAF2E053B170162BD25A0E554A757037C1E40BA6E341EE230B592D33F0B910D32C01CC3F865D104C3B652A63229A90B155D41C68C3008C3DF42CB757A36634C6C7372CA47A82A652C5115BC0383842E5AC18CA6239799A37C91700845180AEB407B88D9390F0A6353EA1459D258E70567E2A5530588C63257B3A33050FEDC1C4FD58BF7F547648B96927A4B6C01901F2CC97995AD993C41A7290F7D555C173C1FB12AA514446E2495471305C9D94236656729DBF9832415C3F130864C4A2807509B14BB187F6450F9A92F020B62238A8F23BBC8ECE7BB33305E3C70B43589BF43C88D712B386C68945F7A7F56A23DC8D45ABA95A89BF18BB0E1AEF4DA810723775AD3125C4316056433EB04202BEC5B83D84040514407E7862685652AE2BAADE15056A2106E546A134A8527A7CDF78866E42CC7C322861CD5BC3D7424AA358204AE6D07694FAE81991F5C67C160B09429BE12543DE0F8", - "dk": "893175C6F86630760EFF4332E35A8642202B2F8503DD24AF50B1BCF10B63951B8E6D426D0357B27A93293252852911C14765099D330D25608885934216114FE2300D5119262C4B959A9928EB058DCBF1636E30A173F5A31EB580A90ACD8774233E652CF4E78AC1C51282D2BDA92A0F6B74ADBFEA4CB8A68F2D3CBFA3298AA8F203EB32063DAB216F811363E69A28A8C8417B524F09BC5D864CB5B502D88B2226193C3729CBB968105FDA459ED9688B12580957180D6A01FB16CCF3E78A9D07CB35A55135B2A1C3D559F5B01A4DD58311417F4E1B98875456849C6E1A632B539180A9108DBF872D96847E79E82C6D23A51AE23042763361A125AE4572BD104F03C548D3F1A377F481F261BD596321BC68B34B31A40829B8AE3CB49C2631A229244EBC08C722839DD8748346C979A9AEB36901E0D9980B6220CD2B32F6C8B1C01C5C61AA0055C32C4F99B1268CC806BBA9D0139D867389B04A54AD51816E965B5CE4A0EF245D6C2006457AA0265081D26214CEFB5671BA20166680CE0C8A817005F7574878B9AA168A8E6A6CB99924543A374834742C48665253E03DCCBC552A5938C0115C5F709B298B0C0E245696CACA53152728B60ACF3C5EE1F92DB30131DB853371021AECE73936D0606A8BAC25430CE0138CCE05048395301A03860D439F9CF45F82680DB9B98B0DBAAA41BB776B60CE41734AA92B914458A7C1CB9CCD55731FA5660D567F489B3BB56754319954FD6A78E6626C69C68A6EA882482113886B8BBB980F118193C1165FFA3A9A8D1A20626514F998CE61EA8BF92B09E253C773D5B2BFDC7C3DA38115B8AA30361C7BC4344CB772EC722B55D1AC4FB7C8510CAA1886C345DAA0CC440EA1DAB0BD131177B9013925418B4B1D54B90BF7F5914AA49B65882FF1297ACED09E36B066671666B875BA1BC37D2FB76F80240D2B996BF6515A0198B66B66A4DEE40DF748C807E1378EA76308076A05FB1F6A071E2D635576F952E4F62A15CC6442563EDE9C8E204789A8F06EC8EA6032D5032A77CAA5963CDDAB24EBEA5708C7B761A67CD0464A2A00233AA648080AB5B2191D73A91D0285512CF6422AFB54DD1C54CD200FFB3AC28AE053E8B6443B96C83DE8595F710D883A513271CF0D93804BE93C84B9A754802C04455D89887DE048B2484088733A701847300FF3B137F509D46033CEC89A4B9602D5A83F77CC20FF4066BCF95904E2789755359F7B04B174983CC883BDB393BE2A02FD3433FEB126A4288EFC4670B0670B2715CDC5700DF6631DF29643E33382EC89B89BB1AD41C6ACAD704BEE982841CC588249BB91A818890BBB3C590A08446D88647FCB5CB15824CDB09C55FAA2457961BB3C79ADAA833F55F154072CAA445B8D61E23993CB69441C956492AF07E702568A350C01BD072CB2E379071845A67149B2F7B2358551770A34A9AE6AB45B2B6D5F700E597184A1425B28047817720C1981C583717F7F4BBF2F13A6D31A691DD3951310A9D135591717A451F00FDD71ABF325B041E3A1EB095F31D27653D1AD0F3CC945D431333A3349B7B8D786B16769309808C11095209CCA1442AA40B9A863B4973E85586899ABC17D1034E64505C1F9987172538E227111EB86A66C9077C268B7A24A477991DDA6753672BD972510EF3347E1B7314BE172A457A4A0B9909718418C478D396B9F15BB6D49D919E192BB714BA992686292056DEB4B1AC84C0A356911437BAF2E053B170162BD25A0E554A757037C1E40BA6E341EE230B592D33F0B910D32C01CC3F865D104C3B652A63229A90B155D41C68C3008C3DF42CB757A36634C6C7372CA47A82A652C5115BC0383842E5AC18CA6239799A37C91700845180AEB407B88D9390F0A6353EA1459D258E70567E2A5530588C63257B3A33050FEDC1C4FD58BF7F547648B96927A4B6C01901F2CC97995AD993C41A7290F7D555C173C1FB12AA514446E2495471305C9D94236656729DBF9832415C3F130864C4A2807509B14BB187F6450F9A92F020B62238A8F23BBC8ECE7BB33305E3C70B43589BF43C88D712B386C68945F7A7F56A23DC8D45ABA95A89BF18BB0E1AEF4DA810723775AD3125C4316056433EB04202BEC5B83D84040514407E7862685652AE2BAADE15056A2106E546A134A8527A7CDF78866E42CC7C322861CD5BC3D7424AA358204AE6D07694FAE81991F5C67C160B09429BE12543DE0F855656EF499C81763075415747986E379B5BE816E964FFC959698CAA61FC6B31BC02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F" - }, - { - "tcId": 10, - "deferred": false, - "z": "70567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19", - "d": "170CA6BB76C065255DFDCA3EB93C772E57EBEF8C9A291C8F0BC4444BF008C868", - "ek": "E295110B123EADD95814826F65D2568360578F2011EB917A24E45AAFA629D7E3C8DF3210D85831CB806B8EC64CF5157938CA08FF6848A11B19D8CBCACE2090474C30C6053E20138C01149114A2A73C129C8055ACA352B05AA4A464B07614C4ADCD002B0B477F624CAA0026820A2455FCE2CE9FF2CEAC299554DCC21FCBBE9C36A07AD67103C112B9F955A1B551D109C88EE54075F203016A30B4A437AFD635F105B7F5B1BD5ADC5925C9347176AC0374CB38250A6583928012A283D4B067E0CDCA554C04A3C1CB0578070CA5A545894841AD38E599643B1CDF94ADF4E917057886A8BC577ACB4668769707DC73D7186700F65DBCF3BA3964B952B7244070053532042924552CA4A8DB807FA12B572D7582B15BCC6DC152A1125955885ED176915448CB7CF5680FE7AB37D22FED7A5E76552481139112351E4FA01EC3B829822788E3A9A463A582F98B9DAFEC1E05378413D805D3D043234578C73032D9006C21C733FF45CB649AA10C09775350523476A5F760175FEC96A26B2E52BCBA008C1C28707ABE5189F2515164B0194BCC1803231B41DCAA20C335FFE0A8BEE5425CAA5832649450924BB1424734A0940E7A7A24D917741010B9B00C81DCBD4BF394BDB5BF03358614718FB1F162877824EE0156F4C462C597B937EB8768C2CFB6F7BE36D7C307C431AFA83824C812CDA245A6B923A5199DD59C1344895E4E67C07F448641D32E4F526693724E0A025369621B220341AAD6C43A4C7CF6C27A5CC65095BCCFD569019808B2AD850168A24371E292D55851A0BC58DFB0AE57E3512B1A26C57CB373F996C0341BDC4714C451979524A58B0502A9996CE09980AC9CB4EA763B8490B4A7B2530B87962B702BF1F04E3CA65AECA1086AA4317331C78848504A9784F40B4A36BCBE01948F08AB400036BAD091AA1AFA1020D60B6278686AB365F208A6D4021C90468FDBE7243BD89D5994A7FF092841389243AC308CECBC5C12105E1408D500A5931B86FD16B555E0AEC9509A63103EACA5A0090C0A0CBB90F8F970980B60954C5985F5644C0914D1C558B65C9F54A42343E824D713B0F1EC9F2BAAADFC824BAE43FE99FD58BF6E845A2AA9ABB4AD4171FD9ADD88AD012EA97F", - "dk": "17F2393AA323522A7D4A6590D57BB2C0EB6B54F578FEECC61C742BFFAA01C2E2A01F68586BC083907728C4431AD6726C58C3C35030CDF1B9808BD14773A91E01577B6E3B37312617D50672B9B9643638229BD151D6F904AB4023A5B1203556B690A41DC558A2BCB00B167C611F9977E5538F227023F088BDAC535556280D3BA63E65721797998FC2FABA44BBB697ACA8835ABF06247A184A8B91518B32A8295B086A9D6313E2825C27C7C126EA1365C68735FCA9128C6256202AF141CAF93525B833578CDC0E31EBB4B2A601643249D32B4C1021C79A1933ADB593E02555E0A467687A5E3044C1815163EDB75A27F15236F03437DA44BB0BBDC24751F04C1F5ED8CD87AC1D6A295CAE175C301781FD39555D688794E74C70D6674A80613A3AC4286A28095CBF68D51A98F50EA4415C6D35460049125A9197A18ACEB0819962BBC6C1055F64B09CD46B6CF9564EBE085767893F7A67AD021AB9157081250A150C904633F9314B6192E221543BB1B68B152B26A3BA74C0C50F54A00E3163505BB51658CDDFA59583847D99133520D08054F6CDF69618402A848A79571479AF36F84A33082E4E05B71401A31879CDDE8346412A481703A88C698416540D85380D8AF880933B5A252B731E9071FEB951500CA7422144A8080280E7054F840BB88763EC33C734754430CA01C5D8A0430B2843975BD1A283DB930CD4CB2B89425F63760426A93AAA27337F22B32577998C34BDD66B6CF6313EFCA95BE3A9CED1A8402533CB3DE7B52A94C551CBA6AF20010D0C7377F8165CB21445D9CD102A15A6A72C91BC4898A47A4C4262A06CCCF3B384E0A52116F05B3FCACF5E1137B96342B3E6BDFE9CCE7C0BADF855A8DA9A00439335ECD15062998609116A1B16BEBB208ECC37CD4ED3BBB3F6A022A9B708513D47164FB5CB51910448CE82186D3000CD487A20B84034929245108AAC455445743BEDAC9B62918644F7183F17C2BCC7770CB5355AB719024177B623478C2C4326E3474DA1924C963DDCF80048999E7D6BB3C9128083B83B9A13710F65ADDDB604FFF15B24E78221C427236799F9B942FA123BE295110B123EADD95814826F65D2568360578F2011EB917A24E45AAFA629D7E3C8DF3210D85831CB806B8EC64CF5157938CA08FF6848A11B19D8CBCACE2090474C30C6053E20138C01149114A2A73C129C8055ACA352B05AA4A464B07614C4ADCD002B0B477F624CAA0026820A2455FCE2CE9FF2CEAC299554DCC21FCBBE9C36A07AD67103C112B9F955A1B551D109C88EE54075F203016A30B4A437AFD635F105B7F5B1BD5ADC5925C9347176AC0374CB38250A6583928012A283D4B067E0CDCA554C04A3C1CB0578070CA5A545894841AD38E599643B1CDF94ADF4E917057886A8BC577ACB4668769707DC73D7186700F65DBCF3BA3964B952B7244070053532042924552CA4A8DB807FA12B572D7582B15BCC6DC152A1125955885ED176915448CB7CF5680FE7AB37D22FED7A5E76552481139112351E4FA01EC3B829822788E3A9A463A582F98B9DAFEC1E05378413D805D3D043234578C73032D9006C21C733FF45CB649AA10C09775350523476A5F760175FEC96A26B2E52BCBA008C1C28707ABE5189F2515164B0194BCC1803231B41DCAA20C335FFE0A8BEE5425CAA5832649450924BB1424734A0940E7A7A24D917741010B9B00C81DCBD4BF394BDB5BF03358614718FB1F162877824EE0156F4C462C597B937EB8768C2CFB6F7BE36D7C307C431AFA83824C812CDA245A6B923A5199DD59C1344895E4E67C07F448641D32E4F526693724E0A025369621B220341AAD6C43A4C7CF6C27A5CC65095BCCFD569019808B2AD850168A24371E292D55851A0BC58DFB0AE57E3512B1A26C57CB373F996C0341BDC4714C451979524A58B0502A9996CE09980AC9CB4EA763B8490B4A7B2530B87962B702BF1F04E3CA65AECA1086AA4317331C78848504A9784F40B4A36BCBE01948F08AB400036BAD091AA1AFA1020D60B6278686AB365F208A6D4021C90468FDBE7243BD89D5994A7FF092841389243AC308CECBC5C12105E1408D500A5931B86FD16B555E0AEC9509A63103EACA5A0090C0A0CBB90F8F970980B60954C5985F5644C0914D1C558B65C9F54A42343E824D713B0F1EC9F2BAAADFC824BAE43FE99FD58BF6E845A2AA9ABB4AD4171FD9ADD88AD012EA97FA29C976B07F9A7D707839A6D72116355207826F54F27A23B6BAF16524F3C4DA570567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19" - }, - { - "tcId": 11, - "deferred": false, - "z": "71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE", - "d": "176719D76EE1CEA83F7751BC4E3DDD00868B5C504C79AF8730B9F7595E7914A4", - "ek": "19288830B0ACACEC7E939B82BAFC8FBFBABAEF732309CACE58533E4F5C62B711C5D84820EA520F030A7E61534275206EB4BB00A53472AB206E50D68C7B3C3D82119BDF508272EA5D40116C9DAAB1F7BC5595B9623DEA2D683C69A079494E3A10BEB2B3A1667CDC031F76CC73595C20D3587970FC17671CAFACE83495037444EC6F485329F6A13328F67D5B839609A56D336C05FB712B1C78A944037CB3E9CEF1D46C420A118EF8712593172548C64FF616E1166649819FDE13235D5341C52A69BB154F48C672D3370B59C19A86B13196F25388089D8ED463FA93AEF6F3857832ADFB874765E318A59801ECA9799BB0A303B87867846A025129AED31C5D2336EA968120C0B88199A83221B1FE6BB2365A086165C0EFBC6185332FB10BB542A32547AB549B3C9E666246CEF04EBF3CCB3CD445C7FA2DA1DA6633E227B5209654AC28DCE78E45B2AA927244D8BC4D881C9462C87F228C07B9C488FA660EC29B60BCF494D6D97C163C53607556361298CEC90332732D7A921D5ABCC3BFE0A3439055093CA7EA1A5E75D70809A55ED886C5A9E90353860239EB907635BD3B46B78EB42821E773E62A1910331F127162B694CF64213305055AD00923FBD137A7F305F345884A6BC5B6C534CFFB6F986A9C444446E3D74170AA375D359E4FAA6C99E4315D230F9B69C37E2C444F29C7EC64C277864836410E8FC703437975E3E83E76F988432570BC635F868C96CBDAAE5C6B37D2E203D452C762747FE7494F146AB7591C9285B68E3973364BB1126C3585BB694DC2262E38D94CCA5C1427992E563C72C9A103FCDB4EEFEB46F5171E9DC2B611D9CE42197352E140B50902EFD676EDF89896B5A4808095FCAC5DDDB218E6AB2F5EB88D831648FF75B1382B6558BA9BF1D8316EF4040E82860716075E80CDC24799733B9EEE74702582320C5CB56C495670FC239CCB6FB8F91F7F217E5BC4A0376B9832F0AB8EB4184704B69C33CBECA37579FB085462705BC72AB7F37C3804B1BD14089FC07C85956038F80C67F409F433854B99198307B2ECB38170DBB55F422260D594F33B3DA9F35C4AC2C2DB9275CE21D56E9CDCF309777C616223E7C0ADD4FA7A6472CC0BC13CDE85BD4536ECB1", - "dk": "ADECAEBF22777691A57353B3D6DA4AC5959286C157A3245282D34812374C88067ED3109817C86447F5A807D24E82316C56944EBCC8A68C761170A218390193CBC14C2859466BD164753944C39269660A5583B2B3309216447886A702127BD77F4A5A03F9B19BE0A76A4ACC0F82267A8659BFC72054AA5A23C84940354323DA78569F1370553A71DFC54AFDFCB669377F3E324098E17709361CE1F824DD2C47ABB25FFFC25ADD519F6079C226D77E6B3231B5D74E11221869881A8DCC2188505628E86FAA2ABA16638400CD58B569002851288E631991C3C545B345A1D5646FE304059A4C742A4A27AAA9FBE9593F374B51B453C7E09427A6325474AC7FAB0A3168630202A016632B3E490D77CB61798320C4139780015F6B521A81E2C34494A6C4FA45DD3712B5349B142A1A57166C1FBC120FD5BEA702BA1878A9064028C575BD5535BF5DF70D46536A826BB687E82BB9A541DD795114359222A8733CFB5D6856269D977AE07887DF5395CA6553F74907E27B011320C103A4191E5AC4F6BCC1C12624D02B2295150C52CB6E5C1423E50922AFBCCB0BF70B2CE8379C2B9C635C44D7C72BBE11C23E4417BDDC9339A6CEE23514E790B1931820FDA6927DF74D79DA1B762562F207A2B14776B98615AAEA7276A585C6972BFEDB7327415AF609227A4BCB757762AB819236D5C615772CF00A492B846C731825E6643C53F55BE7D3555EA4B484A891FC35C47E406F12E6C6B34C090144C6754A12E969B13D0A98231AB7CEC0AABC414BB2066FE6F7297F2635BA79A18656914F4977721C6FA526081E2436975B85E9B7687ED16DA57413B5C16400823522434E38658983B7AC65A39EABD32043693D9B87C1F9F08D80E540A4A86033ACC7D6C961F1DC0C47981CD9588FE469BDDB86762992118B94CB9A213CB62A12E651B654518C843B3E3959612F0C6D97F419866CB89AFA055DF145FA28C302BB1E41E342FA852E3F47380F7536A3824A9B8697BCE6525271B3D0936C4BC172F5A5CB2AF5AD78B72A1DA30C761CA84F123E1BFA58B0454279B87517B906A030562F7691DA4A09C456975E601319288830B0ACACEC7E939B82BAFC8FBFBABAEF732309CACE58533E4F5C62B711C5D84820EA520F030A7E61534275206EB4BB00A53472AB206E50D68C7B3C3D82119BDF508272EA5D40116C9DAAB1F7BC5595B9623DEA2D683C69A079494E3A10BEB2B3A1667CDC031F76CC73595C20D3587970FC17671CAFACE83495037444EC6F485329F6A13328F67D5B839609A56D336C05FB712B1C78A944037CB3E9CEF1D46C420A118EF8712593172548C64FF616E1166649819FDE13235D5341C52A69BB154F48C672D3370B59C19A86B13196F25388089D8ED463FA93AEF6F3857832ADFB874765E318A59801ECA9799BB0A303B87867846A025129AED31C5D2336EA968120C0B88199A83221B1FE6BB2365A086165C0EFBC6185332FB10BB542A32547AB549B3C9E666246CEF04EBF3CCB3CD445C7FA2DA1DA6633E227B5209654AC28DCE78E45B2AA927244D8BC4D881C9462C87F228C07B9C488FA660EC29B60BCF494D6D97C163C53607556361298CEC90332732D7A921D5ABCC3BFE0A3439055093CA7EA1A5E75D70809A55ED886C5A9E90353860239EB907635BD3B46B78EB42821E773E62A1910331F127162B694CF64213305055AD00923FBD137A7F305F345884A6BC5B6C534CFFB6F986A9C444446E3D74170AA375D359E4FAA6C99E4315D230F9B69C37E2C444F29C7EC64C277864836410E8FC703437975E3E83E76F988432570BC635F868C96CBDAAE5C6B37D2E203D452C762747FE7494F146AB7591C9285B68E3973364BB1126C3585BB694DC2262E38D94CCA5C1427992E563C72C9A103FCDB4EEFEB46F5171E9DC2B611D9CE42197352E140B50902EFD676EDF89896B5A4808095FCAC5DDDB218E6AB2F5EB88D831648FF75B1382B6558BA9BF1D8316EF4040E82860716075E80CDC24799733B9EEE74702582320C5CB56C495670FC239CCB6FB8F91F7F217E5BC4A0376B9832F0AB8EB4184704B69C33CBECA37579FB085462705BC72AB7F37C3804B1BD14089FC07C85956038F80C67F409F433854B99198307B2ECB38170DBB55F422260D594F33B3DA9F35C4AC2C2DB9275CE21D56E9CDCF309777C616223E7C0ADD4FA7A6472CC0BC13CDE85BD4536ECB1EDE9E402A11646293C3851259F4E8E4412A3C5986F8BE4427BE39C4E869C061F71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE" - }, - { - "tcId": 12, - "deferred": false, - "z": "B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C", - "d": "3C90FC402DA953172300194876B3B3BC958268747751346DE7134566CB8FAA5A", - "ek": "99263CC303C92A0BC6810487CA1664E5405EEE5987A621C33E30483D4C7862F9760399B4C23822507810AA321D04009CFEB2505860BCA818BC0CFB9DF44A5F47D23AE80C25C2A67455B64AF2D276606A208C74867EDB5373BCB93B06AE81DC67FB73514FAB8E62516D0A0760FA0228E6BB0A252120FC7676A0340FC2939CE8118782631B91F962CB14200C928091876998B1B19EBCCD59F92815930DC6F9BE629099B3334772AB3A16D630D971B2093C136F29C2EEB09F03F8592FA4980599542E422FF636C8BDD6672454238D4C547FCB43DE1B10FB385CFAFB1F84D95E6C776973867E2E40615531A3126B076E9B30D3E9BDD2E12C34A9764E90000AD179CB159259202800299B2902606603227BB37A9B679320B60B3EB9A917D2C0F0CA6A3248B1F371801661A58FEC24B8807B06A5B67D087CC6E3008D823024575C5D7678C93973E8201101765DD5A10889091F8AF87512C206C2C60A96081FCFE32C3B7C18A643AD56515674A3B745D154F7076B65E191D5026301AB45076B00288B91DA147F02795A0D0AC9E8C61540405F44C8B7C766BB454525B8D48B9418B34E3135B8BA3AC9E2486B162C23B266856BC370B4833028C0F753C1E6490A9608B1C5169E6EF0B43BF6C5CE0A6122CCB28C9A96F794B4A5479394C49253217D4DE0A93884A1E47860B127B7DCEA8A0B17019AB410A0737BD81C6EE6EC6DA84569DA3A8ED34ABBC6588325007C4F5651814C45F9DB9AB460AF28B68671E6075AA8AC5F9B2166B79B81154274F058E38B24309017D2B098532964A3DC453F133194D1160A356098321C89033BD195848FF1C989FBCB92192A9E54C528F5259DA796DAF18831A040D8E8C999857FF5251A2A1510929940F1836216566F443AA903BC90528A9E7D842DE70BB75CC8939E48044BD67A4287CEABE22C3481B1F4775260E65A9DB00BF5218136143FC2E21CA720B11540A83DB93C16F10A12E7BAD3A27DCD807E15678687D325CB23256FCAB5073690E3B645329C87379C7B1DD7375755B2E9355D38A9870911B10BD5680FFA08C1442E412A6ACE489E4C89BC7923053748132526C541A0EC4C2A84B606573C36E027356F49F0978B029037455A22E3FA2390", - "dk": "30015BCADC63AF4C80E5F94529725041C8C0746963B3D1A5F655CBF9A8BBCB8B983DBA06CDD1256C1147B0ECCC4D03B600744139D84E6664B40AC22BFB1B03CD61908724078A8B405D868A462B7272594FC448C3EA5908A824091653CD71EC858291B26AB60ABB403884EAA6909A3AF7FB0519384D91856ECCF48C1843C50F1130B1A66DD38355DDE0533EF08484F4536968691BB1900CB52A80039F6CD201FD6C9AA45B0D1830576289C1D3B233BB11AC2D153F6E42A7B5A5AB4B204EEC2707AFB266BFE93C17B6AE2183513E38AAF7F6C0D29B347E6AAA31D24C2804606608A078A25CFE607846103744135E44872C0C410028908E2A608601730DE42B01D45400271033CF90691340ADF473C487DA2BA2E6B7BD2CC6B6EB0D9F01CD7031015F1015C6A24E0C19853E749E2F16C61C2809FF1AC00D113465868E56A919A8310FF6D43E3511322D293F9DBC5F965458A184744F3970B0A16359172B16B7C8CA43B311F4AE96380DA46292A3D1404604054069A181B1C202A02B9AB34DCE833BE08C2EB0DAC641C024C416BA0DB34E10546682F02B6B6B630B801CF8B2CC4F98C671307B92407BDFDCA4CD41B30B4AC8EA3811ED9665FAF479D1057B313CB113941155E539D4C61011360BEAB816CAC019051356533991343434E5C28AEEA797FAF85668B824F3F8BB0329CFC7ACA9992C3990C56CCE31A53F40CB2D07940093504E8A7CF091B137308E1D30B3B40A3624776F9955B62F3828DE769EDE44B89DC828473213AD08488C73A9C9FB2813C6750CE148E37AB3BEB0B60D2203BB444DE44ACCEF685047D9C325478F7CF3A72C9A6F1040A898B1A71EDA1B5F87B57FA08F2F75C4ED616C02512F205159F1881BC559C93925A639F05639589FFA2C38E3062A4FE091A507267916495B033FC0901A47C645A8D82425216EC251C8C0D37A4BFA44C0435E23D090D9D10528A03E611628C5654C5AA1C42280A3C54CB73CB26A5A68CC5D13496093B14B470E3A57038C30CA15712EECA379978521EC298E7BFA6AA698A04925CE47413A62283ECE3C79D955CC3E9C69F783C9B2D58438565A99263CC303C92A0BC6810487CA1664E5405EEE5987A621C33E30483D4C7862F9760399B4C23822507810AA321D04009CFEB2505860BCA818BC0CFB9DF44A5F47D23AE80C25C2A67455B64AF2D276606A208C74867EDB5373BCB93B06AE81DC67FB73514FAB8E62516D0A0760FA0228E6BB0A252120FC7676A0340FC2939CE8118782631B91F962CB14200C928091876998B1B19EBCCD59F92815930DC6F9BE629099B3334772AB3A16D630D971B2093C136F29C2EEB09F03F8592FA4980599542E422FF636C8BDD6672454238D4C547FCB43DE1B10FB385CFAFB1F84D95E6C776973867E2E40615531A3126B076E9B30D3E9BDD2E12C34A9764E90000AD179CB159259202800299B2902606603227BB37A9B679320B60B3EB9A917D2C0F0CA6A3248B1F371801661A58FEC24B8807B06A5B67D087CC6E3008D823024575C5D7678C93973E8201101765DD5A10889091F8AF87512C206C2C60A96081FCFE32C3B7C18A643AD56515674A3B745D154F7076B65E191D5026301AB45076B00288B91DA147F02795A0D0AC9E8C61540405F44C8B7C766BB454525B8D48B9418B34E3135B8BA3AC9E2486B162C23B266856BC370B4833028C0F753C1E6490A9608B1C5169E6EF0B43BF6C5CE0A6122CCB28C9A96F794B4A5479394C49253217D4DE0A93884A1E47860B127B7DCEA8A0B17019AB410A0737BD81C6EE6EC6DA84569DA3A8ED34ABBC6588325007C4F5651814C45F9DB9AB460AF28B68671E6075AA8AC5F9B2166B79B81154274F058E38B24309017D2B098532964A3DC453F133194D1160A356098321C89033BD195848FF1C989FBCB92192A9E54C528F5259DA796DAF18831A040D8E8C999857FF5251A2A1510929940F1836216566F443AA903BC90528A9E7D842DE70BB75CC8939E48044BD67A4287CEABE22C3481B1F4775260E65A9DB00BF5218136143FC2E21CA720B11540A83DB93C16F10A12E7BAD3A27DCD807E15678687D325CB23256FCAB5073690E3B645329C87379C7B1DD7375755B2E9355D38A9870911B10BD5680FFA08C1442E412A6ACE489E4C89BC7923053748132526C541A0EC4C2A84B606573C36E027356F49F0978B029037455A22E3FA23904DEBEEC7CC5EFAB5DAD8559722613802856CD726336A26B171DEC76493C71460B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C" - }, - { - "tcId": 13, - "deferred": false, - "z": "4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411", - "d": "24B783E39214CC39910799ADECE53B32408C19CD9ED10DEC039A9FA2CFC1CA30", - "ek": "37949792925BBDD82552AC59C024AE05B6C9FBAA558A9C4D1FD2A64EF27E2C077617C864F0FB704093B8ECA24CE0CBC9073125070C0CD24426CAF58F97B6549585C249E147E7440DA19B5D55C94EB99274B2D390D9BB6DEDC66545863AD1247013BA4021228AAB05060C9C6749599D8E74895E297C7F05ABB661B98D6003E6F064DF663BB5204D6E12A7ABF58ECF0BBF8C9B3379653E2AE073C3945E410BBF14FA6AF910B3562C7852923242B894E677777398413F511FE38B34E12C787AB75C7CB50C23E432A437B83B483236D7736BA515A3A76C956261B68274FF368CE9B04F1BA3C93E51A6A220744E370620C17B8A851B8A3B01A7017C6765150959AE4C567282D3C087FC6150279A8A3873A4A9231B5C4EFB998DF0A62B808A934F2701CFB2289DA578F1621151C136D79509EF3B5D9C16706CC3BAB798B1777A6A9C9A53F1B277D50CB7A40148485AC1550417AD735899532AB03AC8DACC790987A76AB988CADA1B1FE02400ABA70DA5C9C991725744740FCA0D5EE37486645E4B6047DA0C862A26A89268CB8B9781301AB43ED88FB5403BDA3A63882AA6780A6075474486643896B285F0E2272E261A54B09F0931099323781E797DD7173AFE84569F05BD12134C39B631A13812F2958B872950E25AA07CF2BC5CC90E930B71056B562F06AD2CA268CA82548BC6C7E079690B22B900E8C16CB9463C8B4FD731A74890C325B7CAD3871FD1F67DB78077A13A5E5F9720A4581DF75C4B9C15050D9C4923D7AC7669BE31C523D2C377F1917550862E8E5C39253A5317DCB16529528DD9B1993006DC796668B892DEBB8AE9E8A7E28877403872EF4BAC5367CB09795BD209ADDC54A329CB7549959F286A1237287756AC9943D2B5D21A936D1C7C2CC784E69661D76317ED0241B9C978C02A6E7DF86667506129697936E557251AABDF769CBAE5614BB2BD354110ADFCC8770CBC72738C13064DD14BA724B6755FBC176683B2B5283F6B99B60919A70A2C49CF29378847BD8AE1C502801334F8360369462DD97AD9E0836BEB57B98815D43734CA4C95247CAC55F38786A7747AFB8D8E678465921D7BF29D607FEDF94631E9377AFD92D51FF18D4F91280783577370AC011B", - "dk": "F6FA89BA9A8A3752C28830B89884388B95A2CB3624DF530E143346BBA491DC7082D5144BF36C9B2B828D1D516F9E8165826C1D9CD081F301224F8409FDE22C54F72AD6319033524F0331248043304CF53D44F31C24914689EA9E04A204C96561678A73ECF40E8938ADB137B9F3970464F72C4C115314304DC317ACEB5C2733661F49F1038141BF82174F3634AD82E08E69117A27B4292937482466CBB3041223B51E2BE32C8F7348E3B427F2C77A94D475FADB68C5613312B92A38A86DD694735EABB42ED21A90BC7FB0A5C90049BBC42926F5FC5A0F563E702266BFD44479D8B1C620C670E6AB0E7551619B8661F7BF33B97D12C20414C35866B007E34523184B967B9C6B4AA5AD7DD3CAB39497377C2F468538D52463A3E9945ED90F24FB964C85C47B202CA5EC533CDB286206A14B681A9F145B2BBB3F8CA65000B92CFFA80693EBBA5521C624D1B84906A8C6AC3C7881B10BC592B3B5549861B53BF1B6C1C19E70579EE366006D019E06492EF375BB1D8800B6C60EB7D3B5D78348EEE4B7AFA10E6786043B1C3A9BBCB3DE313189801BCEAC0F9B0C4E631366863297CE39C845835F5B25136BFC8C25C737054C184CE18074A1B079A00A6AF778EF8C3D45F5178A604CC19AC427118FEEF0014A047CC394589617040D96682BA919EDD61E0BC572A21CBE7D189F2AF69F02A6A313881D94A5259D8872A04854D11482635C9746CA083581680E5429BEC2C3A7164D39FB766D786F5FD54B9AFB3B90BB55459C2811860D7159BBAE38B67B4B18865B326CAB9AE62C9B1E636F0CE48260A4B90D6B1F4197371DC1661EA07E27993684CC9423FC5C15F8B1F34C0EDEB0B837A847B9ACBC53F4CF3E88766161C121595A0F940DF1E01C4CC3192F839BD7B660835C570C83577F3C9D88851EE3E9B74B00416F034DBDC2B7D081995854ACB5F4CFB55C9605E6891A8041CBB6101FA94B52F7902CFBB256B28648C9585E8B564E7322911B9A9030013157501D1991210B754983777FF99B42CCC87FE5A847E8A084662DC1D3058C6999EB6C7935B4470A25B4720925ACB046773B16C1E70E2AA5BD37949792925BBDD82552AC59C024AE05B6C9FBAA558A9C4D1FD2A64EF27E2C077617C864F0FB704093B8ECA24CE0CBC9073125070C0CD24426CAF58F97B6549585C249E147E7440DA19B5D55C94EB99274B2D390D9BB6DEDC66545863AD1247013BA4021228AAB05060C9C6749599D8E74895E297C7F05ABB661B98D6003E6F064DF663BB5204D6E12A7ABF58ECF0BBF8C9B3379653E2AE073C3945E410BBF14FA6AF910B3562C7852923242B894E677777398413F511FE38B34E12C787AB75C7CB50C23E432A437B83B483236D7736BA515A3A76C956261B68274FF368CE9B04F1BA3C93E51A6A220744E370620C17B8A851B8A3B01A7017C6765150959AE4C567282D3C087FC6150279A8A3873A4A9231B5C4EFB998DF0A62B808A934F2701CFB2289DA578F1621151C136D79509EF3B5D9C16706CC3BAB798B1777A6A9C9A53F1B277D50CB7A40148485AC1550417AD735899532AB03AC8DACC790987A76AB988CADA1B1FE02400ABA70DA5C9C991725744740FCA0D5EE37486645E4B6047DA0C862A26A89268CB8B9781301AB43ED88FB5403BDA3A63882AA6780A6075474486643896B285F0E2272E261A54B09F0931099323781E797DD7173AFE84569F05BD12134C39B631A13812F2958B872950E25AA07CF2BC5CC90E930B71056B562F06AD2CA268CA82548BC6C7E079690B22B900E8C16CB9463C8B4FD731A74890C325B7CAD3871FD1F67DB78077A13A5E5F9720A4581DF75C4B9C15050D9C4923D7AC7669BE31C523D2C377F1917550862E8E5C39253A5317DCB16529528DD9B1993006DC796668B892DEBB8AE9E8A7E28877403872EF4BAC5367CB09795BD209ADDC54A329CB7549959F286A1237287756AC9943D2B5D21A936D1C7C2CC784E69661D76317ED0241B9C978C02A6E7DF86667506129697936E557251AABDF769CBAE5614BB2BD354110ADFCC8770CBC72738C13064DD14BA724B6755FBC176683B2B5283F6B99B60919A70A2C49CF29378847BD8AE1C502801334F8360369462DD97AD9E0836BEB57B98815D43734CA4C95247CAC55F38786A7747AFB8D8E678465921D7BF29D607FEDF94631E9377AFD92D51FF18D4F91280783577370AC011BBEDEE8ABCAA18E82777BD6D7F6E49B9CED29D3E3687A5FE2B528C6AB45700A2F4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411" - }, - { - "tcId": 14, - "deferred": false, - "z": "9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7", - "d": "E4F2972F746E028108A5BB98EC97A307DC9363909DEAFC491F040B964675B9FC", - "ek": "32CBA337E8CA7A629B588B26218CAC94C03A73E67F6C2037B80607AD6907E2B7468774A836A270CBB03075173D97D837DF5C9E1A3889E26992900902F15A131DE49E6E36B212700C91715AB5AB568C50AA7851A83C353D60BCA348A76D26A62126B9152301A9164C3A01F05907E3283512BC72C2B39E4A7BAE0AB3963A129D2AA39A091F3534110243BCD036A0AD4A3BE03A1A7D3272D1F0ABE2E7455E82BDADBC8B25057667E79EEA898731D85B42381692419E3C101DFBF0132CE91448718B3E5C3F04274251C0854B8C3B3352B77F082DD8C10FEC06A7EE09A8ACC8A5370186E2DA4FA0DAC06CCB09610B23D8E32A1E756E2CB6A8A2BA9265C04075397EFF66A21D2B2C2990603B6664A1283297730C6E1C024D42783D982B875BA957DA4C4F695B49370A4F407ED3059614147D522936DADA78B34C1749C6C04A099BD1C19E09A32F2CB89DFD24696B2C3E97BA38C1BBB198D81C13B73B007D53B5CC70E4C3A856E0ABEB44B5ABEA1E449C72FA106DDD57C3BDBC592D01538A05B32FC85DE8E4952C2B4A2CBCCCA0100E3007885EB68473B95C9406515568AA0B1844EE2376308C841F70605BEBA3E8901707F7A874F087FBAC9A917977CFD63BC16269AC7800DE605663C16D3741077A099DBE6809C6EB162EF0AE62302114D01172567A11EB3BA5B1B425507966639E9916886A8882038B6FEDCC44DC2519DF6C79D8CCA6E7821CA96655136102FDC394A0F13FDF283B43A6BB06E2528E825398303F5940A852396B40C0560D14BC66243FE6773588591907005C5B39CA56267F2DAA4CF9455ADECA0E1CBA99E5E3991251072426C0BDB024A3F8771A8C19684A8CCF42C39948A0E7D951E9A63C5994340E43AB6937513608125FCC86346308BC87ADB154499802878A42273CAC8CA77B14D156A22921CD2AE9AEC363CCBDF2008A28621461700D288C199A51F2A6118BF2921FDA1FB963B9C048B989DC282AA9BBC9D0615F66CE21123CE5465273786886DA0289C55856B08569BC2A880742383A4B07A28E7F6B326AEA9BB5FB5070196BED6698015C232ED5A60EF9900347864D57229DCB6A9AEDC2A45045F720191A1AFCECAADC8C1E65E470DE2C6360C098955016", - "dk": "58B5077542461D311F6B00A10EAC4432C70881109FF588BFCB3073CB15382BB886119B2FF390C4BFD329D18C74A524CBFDA709CDEA35CE2AB73B13B399A9327731A29ECCC0589C762D594D80E12F1A005698B406E2D025F9AC025C46658AF413A17053CDE4CA13D128CFF52922F046535816ECD8601401C4E5CB15854567A9A7B165B42D84424F8CABA817B6631F9B20BDF41A859C56B1D6991F21257BF606C37A2503A83BEED9AD5085B4A0B709719CAA57484B8C639E613B766BF65C2CD449F8332142E0C650A618EA165DD0B594471C3C1E80BB95F504F8D2764A7984830765E182011336B9D2A23B07E2BAD8CA964E4A56007460F59A41A42AC62C17234E0443CBA6CF27724A6E8B651BDA3B788C8D99981A8281789C478143923883261C976475BD5602B013933CBC89A9959A9C2984CB3728D3E29702B26C3E728EDFB4165B387952FC5FDBF70AA32204147C458F471375AA961C1773A8AC3746EC49B7A120AF022A22878958B98FB6E37639D582C07233964106B3F015E95CCAF8A621945B00B61059804C8D47A82FD014269E2C5068B3ABE6B310D9C63C7D37B778D07DEB47B1178BA19C5B59C3E86796F2CF939341E1226C4A5537076085CD9B66CD731125CCB20E4249CD655E547748A8000392BA37F7840E515863E54575167A98B4BB81CAB934CCD53AF976CAB207868B18AB7530AF2D1908ADB85D000D32AFA706F81B90178001F2C57449402C64353F0FE33FE8139153FB3EC3577522373A0B092C55CA22EEA64FA886CF53E92B571C04465A7DF9909FCFC20463258957023097845C88A0C09CFB96AA960692F546B8A1893CE5846AD3CA83C98DB7650A42E56AEDC197ABB09579F6247F79257E71CBE27BA494F668EA60807DC61DCBCA1D1531261D776BD41901156B82C40BC5852517EA130D52D02132D151D28670F14494A207193E668613C58E0E8A2F5124B47EB5CFB2276FA75B27DF08359C5920FA9757A8AB32D40631F593C26E63ADD40B3DF6B849BC8AA8BCF7AC1530C73A802F2FF2CE94CC4EF26158A1F66C37EC4A947568CB68442A42C6E5BB358643BD90014232CBA337E8CA7A629B588B26218CAC94C03A73E67F6C2037B80607AD6907E2B7468774A836A270CBB03075173D97D837DF5C9E1A3889E26992900902F15A131DE49E6E36B212700C91715AB5AB568C50AA7851A83C353D60BCA348A76D26A62126B9152301A9164C3A01F05907E3283512BC72C2B39E4A7BAE0AB3963A129D2AA39A091F3534110243BCD036A0AD4A3BE03A1A7D3272D1F0ABE2E7455E82BDADBC8B25057667E79EEA898731D85B42381692419E3C101DFBF0132CE91448718B3E5C3F04274251C0854B8C3B3352B77F082DD8C10FEC06A7EE09A8ACC8A5370186E2DA4FA0DAC06CCB09610B23D8E32A1E756E2CB6A8A2BA9265C04075397EFF66A21D2B2C2990603B6664A1283297730C6E1C024D42783D982B875BA957DA4C4F695B49370A4F407ED3059614147D522936DADA78B34C1749C6C04A099BD1C19E09A32F2CB89DFD24696B2C3E97BA38C1BBB198D81C13B73B007D53B5CC70E4C3A856E0ABEB44B5ABEA1E449C72FA106DDD57C3BDBC592D01538A05B32FC85DE8E4952C2B4A2CBCCCA0100E3007885EB68473B95C9406515568AA0B1844EE2376308C841F70605BEBA3E8901707F7A874F087FBAC9A917977CFD63BC16269AC7800DE605663C16D3741077A099DBE6809C6EB162EF0AE62302114D01172567A11EB3BA5B1B425507966639E9916886A8882038B6FEDCC44DC2519DF6C79D8CCA6E7821CA96655136102FDC394A0F13FDF283B43A6BB06E2528E825398303F5940A852396B40C0560D14BC66243FE6773588591907005C5B39CA56267F2DAA4CF9455ADECA0E1CBA99E5E3991251072426C0BDB024A3F8771A8C19684A8CCF42C39948A0E7D951E9A63C5994340E43AB6937513608125FCC86346308BC87ADB154499802878A42273CAC8CA77B14D156A22921CD2AE9AEC363CCBDF2008A28621461700D288C199A51F2A6118BF2921FDA1FB963B9C048B989DC282AA9BBC9D0615F66CE21123CE5465273786886DA0289C55856B08569BC2A880742383A4B07A28E7F6B326AEA9BB5FB5070196BED6698015C232ED5A60EF9900347864D57229DCB6A9AEDC2A45045F720191A1AFCECAADC8C1E65E470DE2C6360C09895501683E3ACD9B35DCF6D9E93B006201B0FE23745F0E2E2CD1793BD7B3F6B84220BBC9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7" - }, - { - "tcId": 15, - "deferred": false, - "z": "A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB", - "d": "C5C26DF5BA8BAB4A293292BD070986A8063F736469F6ABBAB684F7127575172B", - "ek": "230563C475571E5CA17BF116280196E0AB1ADF4CC7F4909859177190D17E6A7390DB291CDAAC33A0A08F6FD11608DC404A43AF7E467AD3E77F6004192A758409C459F4CBCCD5AA4DB3D47891416EDC659F8628B20A656CEEA904893B84EE9B6D44B4B1E3D2A5DAE49D7A38882D6C01A07720565A878E3A3B715B27DE84B14721885D5A8D06CBC93268A35A8A3360BB10530130A1C8664117A83BD550D8CA2846250D0FF722931ACF79824A537915D21C9892A786681B44997CBD17F7C02498AB3EE4C6204C79E848BBFDC06C0112C3BD622B9FC4964F64B539630F943583E962B765816E111C850AFA6073C1BB1EFA6E450B9B518C9EB98144F5912F75B30238297F0A934116D63BC9007DE2F21D192A4A515504BD7C73E58462DB50BC1A373922EA1AD5CC4C5FCC64030B4863B047D37A0CBC2AC48484CA642615F287610DDB718BC562559992206191D1507B3BB94B6714BB062468C13921692ABD9EB93A8D3CA09C8A52FCFA36D0F9711E545028BC737DB2B3ACF9BC850A48491488DE346DED5C47DFC089EF074F6C38B3BCA7C42746AED58660C5C984D8E59F3D28276D45263D667191A25BF35A3469B55E36A449DDE713F648A18469A8E417BFDE0784E2CA68589A50FFD38EA5744116F951BF79B90B1380717C6E4C8940627C5BD4F395EF0B38BEA7C556A14C03F2A3C5A2A039BA8CB0BBAB2C0C2B4C88A5D76849F657C361212E18CC96E39788B1D086ED61440F2B10266225C48A36E0380D783677E64564BF39BF8FC8AF7C581FCE252FFF73858533B24F2610A78A2D83D7625FC1687D0CB87088B8F53B475A7A2E8E1720E6E97C1471712AD948C8A2537DDC06BEA22BC6CA8575A26D4315180FB17ABC797DD135545AE953925795FD12167796A54A9793DE8621B5E6851180CF681583AB7A33C4584B709836D79A1913E6197FC4A66876C638B12C77BC9C8BB95FE2A251D61BC260016287DBCCE42C0FB6F30B1E41440957AF90318A48F61AF588C8A86C4E6DF854808C88F2343EB075BD4BF89F7CC081F76B2FC1D410475C27244C8377852B60204636AA7619FB3D7196CCD0B211AAE40E5BE5AAF9651F99A040D32D1335AC61B1685014B4839D3BFEE2660706F9", - "dk": "206C8727F6315309314A290D77492763F8391F365742B55AA2AAB82B98492E008869EBAC27545657E38FA68A37B97B1147111A21E10AB0D522495B92F2530032D440D0C966C5D56762C841D4E68556748D15509F25142E090473D48312B453750C155B4E763B23D515CB32487BF1922E7747DA07A6F3613A50630ADBF0A9CF7A9CF2F11D2C2A244FAC0E4878A6EE24609BE2098A047A0B45173AE5788BD831A5C6C237B601371CC0594CA08E8C1BC5A040ABEAB693ACAE59B058F59B633612081B170E334432C44C80F4EA4758C75701E22A66963425840752D49E92821356149D1328C275669A3B319EE92A2B32A87D313C3F20A8A2C56021503B0FB90B599F775FD008C182F54BE04A63236B459186586804CFF9F479CD531386EB57B6133BF3545076EBCA22BC3002F62B247147C1057BCAAC43B559B6F05842E2687ACA49CF2D0C855E5051C86A74567503D975C342C2AFAC165857C90BA5472C517226A4297FBB62ACD11458788736D592475ED00B2F5C41F2C5B90D6762B064BA0DFCC40E5CA433B2BE5F6B69AD364A63999E4067944F12AA7D2203167318EF6B5220A10504778987F59A6A8A9B2B702799E2A03DEA73A66B7AC776364D2A487E043030F8A476416BA05C62E918AA8670A39E769CEF5993CC34A2A28533AA79635988278A2B2F5E787A63502F41EC81FF660E96B9801E5566F80868C843B992B86976671C9BE56B1A146F83163250558F2B489E065B11AE976872D3B4B0897A9495527B3CCDA0A9A83784CA8E764943AA1F8497451AF259B61B306EBA0995B29C246812F090481F837FDF6663FB277E384250DED44B6297A46BB58C0628A48FE92EF5802BF14666E4282101D3CCBDE76675C6B99B7125A5A262374165F3BC7918F06CBD651DC302C793820281A0B83657A836365E9C982FF973C83FB6A57754967F7112061B9198A6B749064F7FB247FF262D7B234DE684319BA5A4AC0831078116AC70BB643081E9D9AB63D06061852CC3607931184CFD7A904238CC8B894F22C2269A682360E3C844894B830611A3E896CE69B63B96365E4B32CC215A5645AB721A74230563C475571E5CA17BF116280196E0AB1ADF4CC7F4909859177190D17E6A7390DB291CDAAC33A0A08F6FD11608DC404A43AF7E467AD3E77F6004192A758409C459F4CBCCD5AA4DB3D47891416EDC659F8628B20A656CEEA904893B84EE9B6D44B4B1E3D2A5DAE49D7A38882D6C01A07720565A878E3A3B715B27DE84B14721885D5A8D06CBC93268A35A8A3360BB10530130A1C8664117A83BD550D8CA2846250D0FF722931ACF79824A537915D21C9892A786681B44997CBD17F7C02498AB3EE4C6204C79E848BBFDC06C0112C3BD622B9FC4964F64B539630F943583E962B765816E111C850AFA6073C1BB1EFA6E450B9B518C9EB98144F5912F75B30238297F0A934116D63BC9007DE2F21D192A4A515504BD7C73E58462DB50BC1A373922EA1AD5CC4C5FCC64030B4863B047D37A0CBC2AC48484CA642615F287610DDB718BC562559992206191D1507B3BB94B6714BB062468C13921692ABD9EB93A8D3CA09C8A52FCFA36D0F9711E545028BC737DB2B3ACF9BC850A48491488DE346DED5C47DFC089EF074F6C38B3BCA7C42746AED58660C5C984D8E59F3D28276D45263D667191A25BF35A3469B55E36A449DDE713F648A18469A8E417BFDE0784E2CA68589A50FFD38EA5744116F951BF79B90B1380717C6E4C8940627C5BD4F395EF0B38BEA7C556A14C03F2A3C5A2A039BA8CB0BBAB2C0C2B4C88A5D76849F657C361212E18CC96E39788B1D086ED61440F2B10266225C48A36E0380D783677E64564BF39BF8FC8AF7C581FCE252FFF73858533B24F2610A78A2D83D7625FC1687D0CB87088B8F53B475A7A2E8E1720E6E97C1471712AD948C8A2537DDC06BEA22BC6CA8575A26D4315180FB17ABC797DD135545AE953925795FD12167796A54A9793DE8621B5E6851180CF681583AB7A33C4584B709836D79A1913E6197FC4A66876C638B12C77BC9C8BB95FE2A251D61BC260016287DBCCE42C0FB6F30B1E41440957AF90318A48F61AF588C8A86C4E6DF854808C88F2343EB075BD4BF89F7CC081F76B2FC1D410475C27244C8377852B60204636AA7619FB3D7196CCD0B211AAE40E5BE5AAF9651F99A040D32D1335AC61B1685014B4839D3BFEE2660706F970C2B01D9EDB8083BFB5CAC9AFC6E0A6D63D33F40E61F6A8055B63E799623A39A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB" - }, - { - "tcId": 16, - "deferred": false, - "z": "80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4", - "d": "EF0F6EDB707059073378E3419C8D9031D0732CFA931190EBD07FE291B1A3EBD3", - "ek": "8ED594BFE63B64E0C4C5A27BAF4C198E11AB91629C1C77788A05977042B4C452CDB7D66F0991BF05480763591226BCB1830B8527E5BEACC15A191ACCA3947DA6C015DA1B1800FB7B98E94BC3A61733669C6ACB8E6EDA749F879F565077FB637FC8A6892165AF17A77DB17856FA9266EE017105449C514CC6780B41A867757AD551A33341AA145085687E2C9C0CB51224A3C164BE9A36024AA8CFE97BD6C01F8F06A51F36964F1C6367D6A4C22C6B759756ADB3C558E49FE45395D7E8BF73C24305632A6573A8BB574EB6072441D66EDCE17A5B080D6F97C3A7030583837395E7378901A80B1B2CCC2B89E4C9AF74EAABD5604F9957C08D18635D68AD566A56D0D773CD71ACCEE3C697C851544B96FA4CB18A42183E2C0071A46F01F47E1455133DA73A0599AD2EEA39EBF9216DDA7012533CC4610C035C9D00E2962FA6ADFC065BDFA09AFD7A981CA0C3A010CE7040CB6A838B9C65A2E1580FFDD36911F23D69D25F211C0811215C96DA9E0B1C9C2DF24CF583633ADA8D786B6591D4A306D874A6E8A8DBD09443578D128648A9163E8734057D4449E1917B73ACCF7F87CD85DC0CA473756D42A174A8A6CF1A8A5A452F0FE17034E216A03224A423ACA52BB2EC7A6BBCF06E5616A4154683FF6CA625AA78ADD4CEEAF8BB48D37D36B79BBDC3650DA67982F6C4B2DCC00973525B4A3F06CB56B2A35F68974DCF508E6D093BBBA7780B59AAADDABFEF569A480903B648B41D4929C8A5110D6625DBB5B206CA384FBA479898B840D50E45D5CAA30C3EF143593C5BB75224629DD906AA754394F8549E4C7E5EAC45F2C216225C487CF247BAD2C5397B4A42D9B128054A80D24D4D9068373462547799EF612CF61906E224C03693B4CA28983F302B0E935EE11882BD8A8596533E004C8F59380412299A97BA5727A02CE3E410DA564BBD713BE085BDA1192EB27314136754513008A99CC3A2949FBD664C92920807860C1AB1814E1428642151CFAB3C8256832541A957F5020F89230C5C162A03437A917A7B96791F4B1401E79CB55375F585C9C4D166D9760CC36B802E6B5079B0836CEA1078B3BD7E5D33AB48E02C5BE40EFF344F369B920AC3F396FE7F940C6218CBE3B81D3904", - "dk": "207B287A81A1C2223C1BB9B373614F93B575DCA90BE6567EEF7B535C1684A6D0CA4B36420E989A830C9CDA69B8A7655D28F18325741A8CD874A88686A802C26DD6B450966C1EB02D271B89FB528988D4C6ECFA95E7BACF0BF11AF655AA48717CD69497D611CDD2F3437E4C96342305F300953EB9881B4678E4317C400228D945A6924042FD5A86A566A49A577E90955EB6B068ED0568CD535DB1B957597B4B90D864BDB05EDE024EF7D4AF63D282C3D876A7F2BE1DCC0848353818F91ACB935C2CF76E652CB720DBACA86522FB4B0E276A5BE79740F2706DF0E0C64BA18C42E9A7A71092B880328F6866EC599DCF56A4254578CF219D87DBC2AD78186FC3865366415B7932E4B28C70C30D7256BEEA676300700336A814D122ADE949BF6872AE7762CCAD2C7701557139CB5D403215A52327048789CC86A5E689B609260425E7291AA15B7C30460B1B04C1E70647741739F03575E348DDF4996DB587DEFB61940C61A6C1CE6A118C46A701D3F345C1747A666283871B2BB00661AD995B26112DC1B48EDC25A1899019213A3555AB4FE17AACDBE2B4E404A117B7B4A779134090342250613CE2B632A8083D1B56B0501D026C309D25A711AACCD82806DB867A6CDC85F03BB667B2354AC4820ED4A823A0BB93C3921706259F55336D7443FA26BCA90C94D94514C38B17D0DB2909CA4C1E3568CEA34266DB9D5C6CBEC1E104B60BCB3C77A6E3B45FAD814F3773699DD86BAAEA5A6CF6CBF856A5EF6B7F21A74B61A49956935895AA7368640266291088D7BC64E70F7462343F2B943C75B68069435E53684CB74BB3EC3ABB0C1CF17621BD811D95F488C4E035B0A2C2B00C7C6F4757F5711DBD285ABF018E28E87FC95212E7A8CF91BB43C95A69C86B42ADE439189242A4F43252B0950BC43FEFE39BA66334FA1A0114E822A97B6E81356B5C7A7393F9206A38B308CBCC0EC49F079979E0739196020FD6FB07D222B8F9D7C36E5241E973BC37B58C180473E122A4A4554391A3BFAA8658A74940BB856878D39598A1C7DC485971801226F64655E310DF8C689C492A3FFC509840143BB2681C92028ED594BFE63B64E0C4C5A27BAF4C198E11AB91629C1C77788A05977042B4C452CDB7D66F0991BF05480763591226BCB1830B8527E5BEACC15A191ACCA3947DA6C015DA1B1800FB7B98E94BC3A61733669C6ACB8E6EDA749F879F565077FB637FC8A6892165AF17A77DB17856FA9266EE017105449C514CC6780B41A867757AD551A33341AA145085687E2C9C0CB51224A3C164BE9A36024AA8CFE97BD6C01F8F06A51F36964F1C6367D6A4C22C6B759756ADB3C558E49FE45395D7E8BF73C24305632A6573A8BB574EB6072441D66EDCE17A5B080D6F97C3A7030583837395E7378901A80B1B2CCC2B89E4C9AF74EAABD5604F9957C08D18635D68AD566A56D0D773CD71ACCEE3C697C851544B96FA4CB18A42183E2C0071A46F01F47E1455133DA73A0599AD2EEA39EBF9216DDA7012533CC4610C035C9D00E2962FA6ADFC065BDFA09AFD7A981CA0C3A010CE7040CB6A838B9C65A2E1580FFDD36911F23D69D25F211C0811215C96DA9E0B1C9C2DF24CF583633ADA8D786B6591D4A306D874A6E8A8DBD09443578D128648A9163E8734057D4449E1917B73ACCF7F87CD85DC0CA473756D42A174A8A6CF1A8A5A452F0FE17034E216A03224A423ACA52BB2EC7A6BBCF06E5616A4154683FF6CA625AA78ADD4CEEAF8BB48D37D36B79BBDC3650DA67982F6C4B2DCC00973525B4A3F06CB56B2A35F68974DCF508E6D093BBBA7780B59AAADDABFEF569A480903B648B41D4929C8A5110D6625DBB5B206CA384FBA479898B840D50E45D5CAA30C3EF143593C5BB75224629DD906AA754394F8549E4C7E5EAC45F2C216225C487CF247BAD2C5397B4A42D9B128054A80D24D4D9068373462547799EF612CF61906E224C03693B4CA28983F302B0E935EE11882BD8A8596533E004C8F59380412299A97BA5727A02CE3E410DA564BBD713BE085BDA1192EB27314136754513008A99CC3A2949FBD664C92920807860C1AB1814E1428642151CFAB3C8256832541A957F5020F89230C5C162A03437A917A7B96791F4B1401E79CB55375F585C9C4D166D9760CC36B802E6B5079B0836CEA1078B3BD7E5D33AB48E02C5BE40EFF344F369B920AC3F396FE7F940C6218CBE3B81D3904BFFB491B529857FB52940ADB7920E6785BF951468B8578AF5D830FC94BA1C12F80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4" - }, - { - "tcId": 17, - "deferred": false, - "z": "B923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6", - "d": "BEE40356679E3EAE8B0C3FA07C1BFDC8835CEC26CA194D5EFC4301481C256C0E", - "ek": "28669B7A46A351A14CDD8C5676451577D43AAF842AEF96BDD6AB11A948832082CE85A21CBA773EB01508EE3B230F8A5D9FC6617E959FAB9171AB232BBB560D84579992E00E9C338E77043B89B1804C4021DE8124E61C6D6D72BDE0DA854C19CC69D88FFB43B1F983BAC8A84B65480175B8C74B6BCCA470482FD813FA7773570B52B0221B73F48635821427D3B6CEC089CC0C1ECB398BF4956DB4666555F90385A500F24868545848C96C5553FC7387671957745582D662FBBCA46AC9C3392B929BF634DF35638C8255B8492BDBD98FB43B207604919FE855CB48911BB3186690600D80B417FB54E7641560BA5800D46784F97C4961856EA25AB3F2A0608019B0234F41571618851D2D6831B28B37AE777AF3C79A8CD9509BB9348A30A37CD04083660047A0AF514B328B4B3835EC0C2E66C03CFBB05D7418AE4B5578A58BC051A616180F899B371DFC1C441362B6F8359A7B83754AA2B46884072977AE1651137875D4440F04F173405A4E60BA58BD950EA49255ADF53D16B2B97E0C0943FC2ECAF4CF01357382708BE946448AF8721B10AE95A4BFF876B4D6C4571187CA8DF9940AEA45E7C8C63E4081C2096BCEF1679AFCC79EA272C3BC35E9DA7171712A0C3BC679F5379B3512DBA54583A6978A2050AC679F60C295099C82564489E3ACC816BB2E5D775D9D3522AEBC21856AB947F1C497CB20C1CB3F91446AF20646920A34A72394442504A7C817887C177E75459A902323B87A3186CD5001C16CEB73B9BA6A5EF9AFFEA729423C261F121F8653384740A50551CD90292B0671A15599C9164A5054AA9382F55C3FA5A376C868C5498D29E00F0CD9ADADC07E62431D11C21B22374474D5BB513C20C020400B696132EAC94CCCB684937B6CDC507B9B06C3B7C21AC37C5F70C8EB024565D896854C9507082C96A8B7D260C7496AC7546C3EDDA17620DA177F931BD91692890570716455497C8114D8B1FC78506E137813F1067869AB940AB5BF452EA0C02F450972570C4F96F144CA368D77614BF42494D84B3EE6A9AA8A74CE8D0988D038CD971A8C5924BB25923FDE557CD0F336DBA90CB12C38A604FB1DA89F328816D27707C8971D43A9C34B11B683DA50A2B46D270D", - "dk": "FF6013CDBC6DFCF608A3178E7F251FF65867B72B2B4A87A0C0B5BA5B908B0CD878B76BA6F5DBCA047C40FA96479EE2BB2B97CCF6C894AA68505DA331F932BF05CB5F41D394F7875733261E68A02DBFD360AD29589AA06E2440165B16A46913AD6675B68D8B9A27661B709B687969BE0E53CBD567A84CA5A8DD84A2D522C6643A9CA5321987FA7EEB1C0C3742BBF43060DA234AC9F21881644E4E18C7D49A9501930ACAAC17CF536485805E928169584B8C013C30C924A5C81508A9928D54E1325A298115C76F9F95C154DA38B1C857E8676F7A18A35EF2690F743C4F49AEAB6A5E0D67AA18B908F4E0477C7399139490BE077D3B3946BB7C086B3C261323844DBACE09F008F0D3AB5996498E164466421294AC3852C3066FB7191EC33415868CE554C73E0316B1FA0C414405D4FC576BBB6D45FBC2A6BA1882C8575CAC70BD33472AA62BAAD07586D7631D73CBC9AA8875A8927092A0498483A48575E8538760D253A73A8B4905253285A07239B4CF6A091699274BAA5D692CB2614661104AA94AA38228583AE3326548151F39821AFA55752DAC4B25DC0530115027B3CAEAE44AC824ABEEF301BBBBB79113651C686067131A6D41031A34B4AAEB9B868C6CA1122B63363EF7C373064B62E894A654651F348C7055EC758C90642B793622B050D48BB5C241793AA701388C70B3AAA248B270B1E996DB4024D8FB56810C985038C4CE6647B497A233915924E3A9E47A382FE277AE063C02D0371EE964E16B817A6919B7DBAE053117E2012ED3D54FA9A216B0CC3812168A56B34FDFE107E2157E4DD55460C8753293CD614CC9EFA12CA0CCC712CB97703C60D6B763BF23C6CD71539023B1D2958098524A115B2B201B4A1CFC7B0CE3A667C9814AD7C90D24A2295076605687D7CCC8926A1F3D209F02D2486A9764F8D26CA7BBCBA8E53714B52AB87148E7E69A99348514192C8C360718438E2A70ADB107C7D005B1F9537D50D930574A5ED684AE5DB38E6876255D188AF85CCB4ED946FEA92B2E29C5F93083AEF30C6D37B39FD45120BC0FB39711A52A3C108105AF039530505D48069580650528669B7A46A351A14CDD8C5676451577D43AAF842AEF96BDD6AB11A948832082CE85A21CBA773EB01508EE3B230F8A5D9FC6617E959FAB9171AB232BBB560D84579992E00E9C338E77043B89B1804C4021DE8124E61C6D6D72BDE0DA854C19CC69D88FFB43B1F983BAC8A84B65480175B8C74B6BCCA470482FD813FA7773570B52B0221B73F48635821427D3B6CEC089CC0C1ECB398BF4956DB4666555F90385A500F24868545848C96C5553FC7387671957745582D662FBBCA46AC9C3392B929BF634DF35638C8255B8492BDBD98FB43B207604919FE855CB48911BB3186690600D80B417FB54E7641560BA5800D46784F97C4961856EA25AB3F2A0608019B0234F41571618851D2D6831B28B37AE777AF3C79A8CD9509BB9348A30A37CD04083660047A0AF514B328B4B3835EC0C2E66C03CFBB05D7418AE4B5578A58BC051A616180F899B371DFC1C441362B6F8359A7B83754AA2B46884072977AE1651137875D4440F04F173405A4E60BA58BD950EA49255ADF53D16B2B97E0C0943FC2ECAF4CF01357382708BE946448AF8721B10AE95A4BFF876B4D6C4571187CA8DF9940AEA45E7C8C63E4081C2096BCEF1679AFCC79EA272C3BC35E9DA7171712A0C3BC679F5379B3512DBA54583A6978A2050AC679F60C295099C82564489E3ACC816BB2E5D775D9D3522AEBC21856AB947F1C497CB20C1CB3F91446AF20646920A34A72394442504A7C817887C177E75459A902323B87A3186CD5001C16CEB73B9BA6A5EF9AFFEA729423C261F121F8653384740A50551CD90292B0671A15599C9164A5054AA9382F55C3FA5A376C868C5498D29E00F0CD9ADADC07E62431D11C21B22374474D5BB513C20C020400B696132EAC94CCCB684937B6CDC507B9B06C3B7C21AC37C5F70C8EB024565D896854C9507082C96A8B7D260C7496AC7546C3EDDA17620DA177F931BD91692890570716455497C8114D8B1FC78506E137813F1067869AB940AB5BF452EA0C02F450972570C4F96F144CA368D77614BF42494D84B3EE6A9AA8A74CE8D0988D038CD971A8C5924BB25923FDE557CD0F336DBA90CB12C38A604FB1DA89F328816D27707C8971D43A9C34B11B683DA50A2B46D270D9F2CB0E23865248EA1B9E200008F61F1D55C1D4C1F30686982C673E44312AE6CB923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6" - }, - { - "tcId": 18, - "deferred": false, - "z": "1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A", - "d": "C6D5B35B90FA9AB9A7B438B57942D653CAE67B314C7FD152013B4E90BEF8201B", - "ek": "77531B993B3BFDA74DAA9964E4D8781244493F3133DED822179B5E12C252AA5655B7748D3A187F3B017E6E9C7B82A1A494CCA1AB590DFCECC946087293BC42DC7A48584808FF62A0E1CB46B04122144004507610FBE7A359E399B44A08E4452FEFD0BC6C906078210B84D981E936CD54F1BAE79A57B7F64E7B7C69585C783E9C4A1CC30F3F6302DB928C1AF4CC0E0ACC4E627F78D41329303265FB0FA565CF83D7BEDD6833873A9EF6A32F33575884C1639A054998DA1B1D93C6A25379A367C9A14C1F7F1C75258A2ECD071809953E9293BF8ADB2E5BB109A50B6C290211BE035F3B6B481A341CF9EA372A1626FD0B193BD42A7B622D8253BE1123B37B28B6AFC7A1937AAB444CAC44740FA112BB7C960BCFC0818689C7E2607080D24D53DB80B2811EA5E74287090604AAB587F392DA186F693B06F59B45256128C33A942E05779CC570143196E85A45032984C5A834FFA23F0C114BA96B0B0392959BD4CAA859B12377A905330B77C2BAFB4A754924157B6367910C91C3AA41EEA76EA9ECCD4B9667FC4839A8EB2076D935E86694B8D9A6C7A1558F70391067A0B26BB368AB571621957F097B3CD1870D02A5DD5A646774391CC48BFBC012C315B1F06A6474C279599490C76049028B7EE886C55D979C24FB03A28C8756ABBB9D9B7E3F281AB8107EB22104992240A9E92089361E65643CF270C222971D3FB385CC5594C41B35BD2A0FADB51923143762944219459A56726ACEE42C91D03DA6C49D1B46C5EAB710BA68540981C65B2B7638273C4341058E54CCDC8130B155CBA88C2A16A9B2DDC4C92CAC9AC9267151AC39379C0F2078958C33563E360B8118118B185F906CB438AC052D625D04A17DCFA7A5CE4200509784D679081E173ECC2B4278618363637555464876D47E3494CA408BA45507A492039ECE577A17725D6472ABAE1562F3721195D193C962B01CACBD80A85DCFDC221698B54B52874DEB8450A435DCF1204A9CB329E21374268046AB00CB4416BFE207F018390E37CDF8797DB1238CFDC2C0B4F495B015CEDB138C36D415DF9672AB506095DC6862D49D5541CD3D93748955E792F5729A3191AE5DCAC826DE5B8ACB573648D95D36C5BF399CB4D9C4F8", - "dk": "9904CDEB001524F59BA84901022C3B4D81C1A0BA1724B373F4A6869D0574199787069A1FEDF8AEAFD82AFB823F5F718490E1359F495390393A12B15257C2C9E56BC52691228E00C0311C9577FACAAC34B65BD5428CE226779C8208DB6B25F5BFF40CCC1DA60A4C6AAE8EE553EB64B235918C879B5690E4B421375A1A1350A960C643DB4B8AE405E58974878B9F6F87CBAB57B4A3B8B1BFDA9823797C239740588A854D9AAB4283400E8B93168A1D680C05B07231B8A455C39893C260B0182B66E13ACAAA20ADFBFC11CCE0CBBE29C1C7B79B6D78A931878C4604174BBBC28C0A54F8C50459F7A93CE97D393424A4B8C9728871E9741AB54129E5919742BC4CD95B1775499DEF0753839622677739E87A8A8C651062F7408B389EC818C15D300A7B95AEFBEABFF078BA0E27A842DC89FDDC5378A5CADE512B3CFC65D8472ACD311E8BAB4979C15A17F33125327C9C73AEEA3642AC225958778618D522472AA89853142D35AC93264CC423A1EC8CB460A398746CC9C1615326B5819B0697D1452BFE3A86F21B7B3D11B1F6284806B5A09FF362CC5B50E0A45EB84B084EE024B3A654AA5BB7EC34604BD6627FDCA48EFCB410B9769FB6BB3A94835B2A4850128CAB534E2B3A5A5B4B367DAC9E3BE913AA12C887589150FA64EC0C1293F8410499220DF0ACA7A52C2C66CAFE9567C3B0B32F593E7ADBAE1BE64197110E9D8B77864158AAF77AD1F8232212758A5C7BA401B32C258389347C37B0B3D8B78C30436D54B800FD88772E309621955C49B77A5F9452B4B74876DAC662F76B63760D52D20692647BD1707045A09DAE8324D9688CA56B034F0BB4E378288C328ACD742169B3704C02BAECB68AF8309DC2D30BC836A856635CA4701BFB74C5662C69B11B6BE0CC984F12493540CE50DB83D3D764A5E63A13C2AD3CF5C67E8638CEEC9193470C6AA069240A53DF6C68C439B3EED8C5F4DA7076306E5223B9104662DFB35276B4823531C848747AF50081BD56A6C4B154C39B2E0CD3131B4742D241A385D938EB2C673028636FD893BCF59519C2A87D4BC42862CBFA0370D8D44CF3E032178AA077531B993B3BFDA74DAA9964E4D8781244493F3133DED822179B5E12C252AA5655B7748D3A187F3B017E6E9C7B82A1A494CCA1AB590DFCECC946087293BC42DC7A48584808FF62A0E1CB46B04122144004507610FBE7A359E399B44A08E4452FEFD0BC6C906078210B84D981E936CD54F1BAE79A57B7F64E7B7C69585C783E9C4A1CC30F3F6302DB928C1AF4CC0E0ACC4E627F78D41329303265FB0FA565CF83D7BEDD6833873A9EF6A32F33575884C1639A054998DA1B1D93C6A25379A367C9A14C1F7F1C75258A2ECD071809953E9293BF8ADB2E5BB109A50B6C290211BE035F3B6B481A341CF9EA372A1626FD0B193BD42A7B622D8253BE1123B37B28B6AFC7A1937AAB444CAC44740FA112BB7C960BCFC0818689C7E2607080D24D53DB80B2811EA5E74287090604AAB587F392DA186F693B06F59B45256128C33A942E05779CC570143196E85A45032984C5A834FFA23F0C114BA96B0B0392959BD4CAA859B12377A905330B77C2BAFB4A754924157B6367910C91C3AA41EEA76EA9ECCD4B9667FC4839A8EB2076D935E86694B8D9A6C7A1558F70391067A0B26BB368AB571621957F097B3CD1870D02A5DD5A646774391CC48BFBC012C315B1F06A6474C279599490C76049028B7EE886C55D979C24FB03A28C8756ABBB9D9B7E3F281AB8107EB22104992240A9E92089361E65643CF270C222971D3FB385CC5594C41B35BD2A0FADB51923143762944219459A56726ACEE42C91D03DA6C49D1B46C5EAB710BA68540981C65B2B7638273C4341058E54CCDC8130B155CBA88C2A16A9B2DDC4C92CAC9AC9267151AC39379C0F2078958C33563E360B8118118B185F906CB438AC052D625D04A17DCFA7A5CE4200509784D679081E173ECC2B4278618363637555464876D47E3494CA408BA45507A492039ECE577A17725D6472ABAE1562F3721195D193C962B01CACBD80A85DCFDC221698B54B52874DEB8450A435DCF1204A9CB329E21374268046AB00CB4416BFE207F018390E37CDF8797DB1238CFDC2C0B4F495B015CEDB138C36D415DF9672AB506095DC6862D49D5541CD3D93748955E792F5729A3191AE5DCAC826DE5B8ACB573648D95D36C5BF399CB4D9C4F8956A0C263895B5FB51D08CE116A156237494A6C79B54BD23134DB26D3D3F0B9B1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A" - }, - { - "tcId": 19, - "deferred": false, - "z": "53F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905", - "d": "5C6051E18E28FC5719E3172B967D25BB1649D87743440F7715E860AA212A256C", - "ek": "DA73368E74CEA1A5B1B1AB47FBF38B33A47BA9F98F3D719F938082806CCB59503E1EA999C35272875B112BE8097414BD304C5C8AE127EDDAB111F6B5A8C5B8F8C39E8C41754BBA57683C2397B612A11747C508103C689ECB9394FA9B54F898678A3459FF6104B3350B8B548F064C47EE0702D6910213CA5A5909134D5B4176BC60D7533CD1BA294EB4751054AECFB73478EC38322A7D7DA829DF8A2F19C31EA9442E5AD30E00707747787F005B9CA9B9544FC61290262247B8AF26B490704B21676A138E11A797391ACFE7A6C9D0692ABA2FEB982262327749D55E34A6A4AFE3A061E3256383667035236422A38A371FA6D48120CB1C78E53607ABBECF319A46C0834D2A05B8E303CAF734A9370BD6855C7E676E637576D50B0DE8676D209305A11C5202288B9E80BD235CC543458FBB470702B4A2C4758EAA992320F08FDDE8B25AA4A08480BC401C534A6C4A79867A26B19297FBBB90739973A79E05998140587E26CB8C464A96A3DB1FC24C5ADCA02D076B352576B506C451CEA40E3EA4412DA2048B25093D80C39AC6300BD0B318A7BE644C5838A301ECEAAC5AD6364807255476AC75CB0C9ED033E5350900C0795584034DEA59D8844FB669B09EBC8AFA43C45135640316A5D86947B9CA445D432D02A624D0F46D396C5A09E3C43F0148ECA5A926147A200750FAFCC13D53CAFF188718883AA4B4BE97C72C1A6136CE266FF6451669BC78C862C883C86422366657097AAFD77F88693A9ED328CEC05D2E984D188A044E026C65E212B2307D838A549E623793865E2D13926F85128841BE2FBC666C6921212AC85D804D4655448A07CF7F41CB8A9623D4E48D72958004C1C28093AB060371642307F8F7859F1B08D0E45259021E2FEA5D4DD99E3CCB980DD51307776AFECCB7EAE1776FF09676F3697EB98DB283414D9872337565D0450FF3765DB8F5CD3DA30DEC806ACEC879ACF9995D789F03F182B8E2C314C92E6C36512FD223D6A99CA9657A04125CA5CCCDD0F967B1A767D37AB08F26759886C555E9713ECC22C5FB2663398592549D731C84693449AF0675767A72E9817E131209F3CC907B5337C46F460DA1941825DA2DEBE7A27ADDE90CF053AD520522866B24", - "dk": "6656048914A30A786B57E77371D5AC2F5327D5D26EC077B6D2D817FB1ACA449A34990B5DC22638BF6473560BB853212343203F60298E91C64454B87121147BF55742218327E0D84ED1C07FD7755AED894A3BF3393068B7E99009678BCBC6028B74F0BA5862B3AA5B704AA3A4EA658E40751F69B51171177620E2794A64864A2617B603BB6CF7068435CF38371F84977E9D507F298CBC6D717E4955B9FB5B307870BA8B09952DBB9724252A622A22F6C89956077099919BF2D7CE7D456AB3F70FAE9B68362593D7ACCA8C4955D072908C981DF377B58881A8F4046F342178812C99E2E86F9557A81CF632430333C5E961F0B167A1FC2FAA8B7648F342E1022FB8478661D7505503BD6D18275029C8588C8E675B80B6D722E707C8E9B28636B894AB8164CFFB3BDE769116078F83B97953DBA7C00378DBCB620E3C650AE72955E5434A2CAEE4B15DFBD937BBCC3D1D256ABB361B7E007C8C53429698BBCAF54B3283AE02461D17A2C41AFA21BA466B2247CBE01483A0C0743A32B854A9AC78175E6BE102A9C62CFAC5811FE527D0F433B8E708FA106DA30A5E0C9C0E63B6B3356557982B3B03B437CB412EAB525668A7723CBBAE801025D5AA7EF2D5A5AF5051B0B958FFE677DDC30E70D8507BB24D2600344D226CF602916AA175D4BAAF27D96696B4BEA828895AE8BABB449649798905575D71C60F3B9C0B73EB3AF92B98B90284421988F257510BC822DA501C6C8C54FE0117BE44AF4A12820AC9203C52466C76651580B962B2543BD0BA7EE73CE28B76411316FEC5859576CE5F83C8C3B159BD16CE58A92730F627E4B9770EC9BAA5D343FD630ADB9326DE8340BF5AC319DC43E5E03B50809876B6804582069258B9078267666416022382A1816DC6E670FAC16D18D861DAF022389762D915912EC7A7A3F0534F93B7D38CAD99670734883BD8D31E8B70BE90839963ECC83091086E689091CA6EF8477AB21960432593DD7694D0E898038BBBD603ACA19B8BB150B80960A63894A231ABB7826B1976FC331839586E3C816A1450742C719E674A2D1BC6B1B54D5F407D1E96849FB841703005DA73368E74CEA1A5B1B1AB47FBF38B33A47BA9F98F3D719F938082806CCB59503E1EA999C35272875B112BE8097414BD304C5C8AE127EDDAB111F6B5A8C5B8F8C39E8C41754BBA57683C2397B612A11747C508103C689ECB9394FA9B54F898678A3459FF6104B3350B8B548F064C47EE0702D6910213CA5A5909134D5B4176BC60D7533CD1BA294EB4751054AECFB73478EC38322A7D7DA829DF8A2F19C31EA9442E5AD30E00707747787F005B9CA9B9544FC61290262247B8AF26B490704B21676A138E11A797391ACFE7A6C9D0692ABA2FEB982262327749D55E34A6A4AFE3A061E3256383667035236422A38A371FA6D48120CB1C78E53607ABBECF319A46C0834D2A05B8E303CAF734A9370BD6855C7E676E637576D50B0DE8676D209305A11C5202288B9E80BD235CC543458FBB470702B4A2C4758EAA992320F08FDDE8B25AA4A08480BC401C534A6C4A79867A26B19297FBBB90739973A79E05998140587E26CB8C464A96A3DB1FC24C5ADCA02D076B352576B506C451CEA40E3EA4412DA2048B25093D80C39AC6300BD0B318A7BE644C5838A301ECEAAC5AD6364807255476AC75CB0C9ED033E5350900C0795584034DEA59D8844FB669B09EBC8AFA43C45135640316A5D86947B9CA445D432D02A624D0F46D396C5A09E3C43F0148ECA5A926147A200750FAFCC13D53CAFF188718883AA4B4BE97C72C1A6136CE266FF6451669BC78C862C883C86422366657097AAFD77F88693A9ED328CEC05D2E984D188A044E026C65E212B2307D838A549E623793865E2D13926F85128841BE2FBC666C6921212AC85D804D4655448A07CF7F41CB8A9623D4E48D72958004C1C28093AB060371642307F8F7859F1B08D0E45259021E2FEA5D4DD99E3CCB980DD51307776AFECCB7EAE1776FF09676F3697EB98DB283414D9872337565D0450FF3765DB8F5CD3DA30DEC806ACEC879ACF9995D789F03F182B8E2C314C92E6C36512FD223D6A99CA9657A04125CA5CCCDD0F967B1A767D37AB08F26759886C555E9713ECC22C5FB2663398592549D731C84693449AF0675767A72E9817E131209F3CC907B5337C46F460DA1941825DA2DEBE7A27ADDE90CF053AD520522866B24F8568A428B981C5C2DCD0C7E8B487824825DC3F9C0356ADF0CE075394DD1BDC553F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905" - }, - { - "tcId": 20, - "deferred": false, - "z": "9C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C", - "d": "CA351B0F454DE9DB364E1DAB8AEF6E49C2E69439941935B24C00BB9952E65BB3", - "ek": "F7F7C6DCFA28B52749357994F5C18DF3138166373F1D9C613410287E1BADEC6C23120889829C251831507BE05E137202A9336EF5C69D33823B69F91EC25369FE3C8FA8F2A244A1ACBAF5C851418515548920333F0B584F60C22063D66AAF545328F1CFA23BA676140D0E7BA6D6D94D4409AEBF5B209524A68645277111BAC6A2B09A13944D9471E9F704441215D6B93D63FA01E3BAA4BEF7C701E485A1A89CC8E8602C5259CF3A176EBB85487C3BEAB80B4E5B8AE1B54335BC5BD1E94D35090CDE556E2559A27F770053541090CB94BFE3CDECB1B99C0B9914460631061060927507096A16B37DB0091616BC00CF68461C3A47BB585E8997C6A46C09B07C98ECCB10E30C45D014A1B9C2559EB190651296E97C7DE0BBC475BC49AB13398CD98C91A06273654977AC3B70EA83BD5657F47381D9090909735EB899BE2DA5BC73B56232736AA326845FF5AE6C452523406901781E095244C8F689B0271D53327659D0A625D75914E34394149C955935ED88C1B41475671338451B61234549C74091C9CB14E90B02356BA21CD4C960522190CC68C71AA088FB2EA5D1A777075DB4210A289B208BE66F6BFB6DA19540B740A34E822232A4BBFD028BCC304976A4C2ACD924153A974FA345959AC74D13C6C287265FFA6F8639BB0E407C1380627D74BA3ADCC81176A85503213109493A2C745D5A65EAD31333537C51CA45E8A34A3D555C19649726C6675B645519645E6331A81EE47C6EA35B49283AD8E48FAD465A426A3352C0001E8BAE99607A26A71126355A0127C288266951E845CBC0942023950CC73677228059321C2BC9414A190EDB61021BE21A4CC26CE4E1303C430BBE607B996AB304519A4148BCBD72B0B23BB947A36DA2C983898A71A8D18F8CD571ED274EE76713C540118B0CB45CA6BC72C5C96FF1B231823ABBF112FD2683F12973DCCA995B007DEC83B600999535590AA98A61C711A2DF076E65803746E93885621557821F49E3497EFB4A0F8C34ADB34B42CC0F32B09D898903F946A569C6CEAE0630E13004BC75241343061D2BA6B1D7BF44A00712941C10E64183E5A007708F798456C695B15F75C3C6A27310393A3049089ED8EF92DDB01CE5F59229FF7CC3", - "dk": "B0A66733CA122538CA1C747B2DB0CD8E3A67D1F3B1F695BC40540BC5BBAB6CB1664697B5DA7BB181DBC1546A2F5F4C4958D8C73833372F0355BED21262146574E24BD42B3FDCD45B333750B0AA8A29E34FB9AA76BDD2B1CB6799539463026029EC43655B716351288C95D1B81DC572A8980CC1EB42914B0B7E957FDC8373533201317A54D2A497A4D85E3F695F579942750AC04A9A7D068C4429FBAE653AB8AED01227C9892D79CFE300191BD310BC704BAAF78F982BC09F40325D869C962AB618F25A18477B46A9A42657C00DEC939A5187C26342C552880DEAC83A5338D3B10EF4C71D54DB77A8EB01EA87A534ACA53C70B25C98988AC4828A0B49B3627F7B6156F665133AB01F42B47E298B983939857849409BB76C4B0856A364C86FF6B32AD81F28DB51740048853836ED972B92295E16FC51A15465FE592090874FEB183C28090465204490F561A388430AAC26C8B133EABA1FADD91C9832C43EDB9A9B8195490B4153D1CD3B34523CD98F570B33502C818C765188B40E43A8B26D120E4A67ABD430650F7978FD3551620A782615214085C28B44B4986C952212C0A7F681B355964FC0C4EA914E66FC8E4EA40750404D1441C543FCC3B938B20464229FC99AEF56B1123C11EEB40DFA68C6F473C3B955685875256CA0BFCFA39944443C3F1160F808682933053E7759F8F2494DE65D4E4C159AFB4F34C6862D26C41DF2AFF896116007785D58068E5086B2426EB5124FCD0A9C8339BFA01116F862581F5307DD0C8B361113D346629BC29CE3A21CBCEA14483010A878A9048C11E1E6A07E011E4BAC09870037E1FC4987F94513403FF9D9964639885C14851A1B5FF5C119F4522976AC4E7839B1BD607F113A48739670BF0CC7A37498F8A0CB74B8A9DFD298C9F916DF547F68C2A369966D99C623CF782DBFF542C885BB5D9B027FE3CD50B54656179332EB3D162B8CF59B604BE519A5ABB105C0012967CD794217A8E4A3C43B785255AAF80988DFE0979413C31EE13D55DBC43B316E85EB0C7470C5F2577BFD185774CB03CB39CDB408C243F26DA2B424A55C3D8975CB1F900EFA1A3FF7F7C6DCFA28B52749357994F5C18DF3138166373F1D9C613410287E1BADEC6C23120889829C251831507BE05E137202A9336EF5C69D33823B69F91EC25369FE3C8FA8F2A244A1ACBAF5C851418515548920333F0B584F60C22063D66AAF545328F1CFA23BA676140D0E7BA6D6D94D4409AEBF5B209524A68645277111BAC6A2B09A13944D9471E9F704441215D6B93D63FA01E3BAA4BEF7C701E485A1A89CC8E8602C5259CF3A176EBB85487C3BEAB80B4E5B8AE1B54335BC5BD1E94D35090CDE556E2559A27F770053541090CB94BFE3CDECB1B99C0B9914460631061060927507096A16B37DB0091616BC00CF68461C3A47BB585E8997C6A46C09B07C98ECCB10E30C45D014A1B9C2559EB190651296E97C7DE0BBC475BC49AB13398CD98C91A06273654977AC3B70EA83BD5657F47381D9090909735EB899BE2DA5BC73B56232736AA326845FF5AE6C452523406901781E095244C8F689B0271D53327659D0A625D75914E34394149C955935ED88C1B41475671338451B61234549C74091C9CB14E90B02356BA21CD4C960522190CC68C71AA088FB2EA5D1A777075DB4210A289B208BE66F6BFB6DA19540B740A34E822232A4BBFD028BCC304976A4C2ACD924153A974FA345959AC74D13C6C287265FFA6F8639BB0E407C1380627D74BA3ADCC81176A85503213109493A2C745D5A65EAD31333537C51CA45E8A34A3D555C19649726C6675B645519645E6331A81EE47C6EA35B49283AD8E48FAD465A426A3352C0001E8BAE99607A26A71126355A0127C288266951E845CBC0942023950CC73677228059321C2BC9414A190EDB61021BE21A4CC26CE4E1303C430BBE607B996AB304519A4148BCBD72B0B23BB947A36DA2C983898A71A8D18F8CD571ED274EE76713C540118B0CB45CA6BC72C5C96FF1B231823ABBF112FD2683F12973DCCA995B007DEC83B600999535590AA98A61C711A2DF076E65803746E93885621557821F49E3497EFB4A0F8C34ADB34B42CC0F32B09D898903F946A569C6CEAE0630E13004BC75241343061D2BA6B1D7BF44A00712941C10E64183E5A007708F798456C695B15F75C3C6A27310393A3049089ED8EF92DDB01CE5F59229FF7CC3BDC6A66F789A31E64AFEBCBB1DD2F94747FC7559309D17920DCBBC3C38C4BB059C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C" - }, - { - "tcId": 21, - "deferred": false, - "z": "97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5", - "d": "C467A43BF9E9CCADCE4581B53F8CA0B605583775AFCD0EBBB587907B3A813D94", - "ek": "E5169D5BCB1CFED42BBC044B89208FBE0399AAF9A3552B7B0A579A43BCACF0D1610F6057CF938A157A9DF8B797D402461559CEDDA6A15D754343DB49C4D095A4E763FD22833FAB8B909A2129E628B9FA656482AFE9659B52AB9C74EB885A667D42946B35D163136672F30404FB881FAE153B13589299C515185B25D878ADB1D903743B4ED2B96838C29FF3C5183CEB6CDA510E6EF85037163DB1D658831B97921273CA84A924947E47F88BD2E3ACFDB5B7EA634C70794D9CACABC67C08E4379DBEB84575542A108671FFD6289FC97B97F073C98A845E10BF63C1990347A6C165317A51CEA3231632A967D2A97619414701BCC6F839C51FB1885B7993A891B31F7A79B19176FF215EAD642BD9015DE7DA03584A867C83C0ED7B5EBB16CD6FB671B1F48BF426BCCC24529F91819931921016A627FC2960C8104913A6D4372964013B0951593E09B8256984E8999A28DA134AF4556F5A5A39A63FBE950828474FAEA86F33629DDA45C42CBB90A885AAD3A4C006E66741362A3FC9CFD92B94D6979EA5623554986F36F4C9898681B345C81823852FABC76234023587B10462008562262BB37981EAC047D458E8D14789C18CB740BE85B57BA613B884104DF64159B277C469F72EEF73095F34C4341374992BCE5D02169CCA1FEE5456F44BBB52C4C12610AB2E3A48DBC9A4FAE18B5CB6A1E2177191338AF490A18F107C4A9704DCE3A40F997233347A7ED8116BEC2469BBAEE4EC141AF80F45E67FDE896838761BCA4B7213D260BC362EB3924F0964A59A83827BDC69A1D816DB49A077150486245E07C3B7261B1DFA7492B778073BCA7BA8B690C4F47AC8398A3B10A18779935614282D64428C4B50FC879109B22F44E079AEFC50741677CB4566AE80114DE8033AEC9B04202EB45176E7BB77A9A1220845C9C2E5746037C422A96D23EB07E4B4996B2B12470C62EAE1C972A22A259B7B4098197C69571B9066DA5712BAC75AA1D69C4B289E2301927CC730E9E15F3E01928DE1AAE25B80D6A80DB4D834E61AA6BDCC8615C0638865C573B5B06EC9C16DC014BF53239F91BBE0D5C25D09A766405C35D11B3732B2D2AD39A22C1FCDBADDC3A81EDC8E5EF80FE66B2A69753C82FD63", - "dk": "4A7429DD79A88B892D16D35201558135962685EA2F76A67DAD213DBB846FA229764E354745381DF8B64217A9BAB2CBA9E143C22F901A3C0089081C6B7D4B91D7115C2A740D57745B782122A4D015BAB56E41FA2642DA060CE20078E57FC2706A676BB2E1381D639951F0866A401127A4312BA3F89CB8E558AFF6B86899617D57606BACA6351185F1159D9F4A469A0A8B36B50E13B164BCBC13F473B31A7118DC6A5C79702405E0ADEB466A359B8F47EB807ECCC0E0E28E55C28266219FFC3A530220B97B080C91302B77819A017B2689F7A5F9367EA8422412FA8AADB20B4E34006236454C9B6BA1B1C160BB46ABFA8CB0AC530EBC3D63909FD2CABCB009C67759AF90201C3808B35C917E82847232074C67D37D55454EACE4B4CEC23300BD58836786A5C02014E537848A012EA7C0E88071D305C539B7B4EBBB5DE188B566119956E264C8131DD318C80C56C000848C3EA22C0B358AC0B08B7B5A864601AE8C72C9A4113188251243E951FD9542061653502475D1396696C4C9E94105C3806E26128D24ECB03BDABEB2F49DFCF0795D4918E4394374DB596DD47B23BA543207C2C744C5D83C1C4E78C0C2B0072CF4A9870C4A6F1CB9B41867F6C1278D477928307752F0975FF30106982EDB719F1BB97B70C8828EF4C1C475B59BD61C7CFB95D95ACB251A0984E37C8ABC92A8B564DEA4A5C2301E60D10227AA7161B52B8BF4370CFB7342A756F343A020B84052626D3E9B2B11CB819D0358D2B99041320209248B9049B6D96302F871A0F69493721935F2753786CA1673A907618C83C9D3B9D2B6C702EB90C8A8BCCDA54EB782AE17513E38840BA30C6920F8B9C2E32653D7B5B7F6B50A08BC86CA5A1C756610A595F1D8034B26B29ED676AF2C26788A3CC3B271A9F30B2BB473D0E47C941711ED6355823A82FD957D1D709EA7152E5B5BA97F78CC2A997405BC46AE8CB24223B0B39129D8B7CE677C82BFA332B66B26C9E61DC13656EDF538C65C88AB15A1F019044BD0A5DD32090D0C7E59E269A4213EDDC469FFD18F1532A7AEAB051DF7727C14BC721B2F39326C43A266BC531850FBA0E5169D5BCB1CFED42BBC044B89208FBE0399AAF9A3552B7B0A579A43BCACF0D1610F6057CF938A157A9DF8B797D402461559CEDDA6A15D754343DB49C4D095A4E763FD22833FAB8B909A2129E628B9FA656482AFE9659B52AB9C74EB885A667D42946B35D163136672F30404FB881FAE153B13589299C515185B25D878ADB1D903743B4ED2B96838C29FF3C5183CEB6CDA510E6EF85037163DB1D658831B97921273CA84A924947E47F88BD2E3ACFDB5B7EA634C70794D9CACABC67C08E4379DBEB84575542A108671FFD6289FC97B97F073C98A845E10BF63C1990347A6C165317A51CEA3231632A967D2A97619414701BCC6F839C51FB1885B7993A891B31F7A79B19176FF215EAD642BD9015DE7DA03584A867C83C0ED7B5EBB16CD6FB671B1F48BF426BCCC24529F91819931921016A627FC2960C8104913A6D4372964013B0951593E09B8256984E8999A28DA134AF4556F5A5A39A63FBE950828474FAEA86F33629DDA45C42CBB90A885AAD3A4C006E66741362A3FC9CFD92B94D6979EA5623554986F36F4C9898681B345C81823852FABC76234023587B10462008562262BB37981EAC047D458E8D14789C18CB740BE85B57BA613B884104DF64159B277C469F72EEF73095F34C4341374992BCE5D02169CCA1FEE5456F44BBB52C4C12610AB2E3A48DBC9A4FAE18B5CB6A1E2177191338AF490A18F107C4A9704DCE3A40F997233347A7ED8116BEC2469BBAEE4EC141AF80F45E67FDE896838761BCA4B7213D260BC362EB3924F0964A59A83827BDC69A1D816DB49A077150486245E07C3B7261B1DFA7492B778073BCA7BA8B690C4F47AC8398A3B10A18779935614282D64428C4B50FC879109B22F44E079AEFC50741677CB4566AE80114DE8033AEC9B04202EB45176E7BB77A9A1220845C9C2E5746037C422A96D23EB07E4B4996B2B12470C62EAE1C972A22A259B7B4098197C69571B9066DA5712BAC75AA1D69C4B289E2301927CC730E9E15F3E01928DE1AAE25B80D6A80DB4D834E61AA6BDCC8615C0638865C573B5B06EC9C16DC014BF53239F91BBE0D5C25D09A766405C35D11B3732B2D2AD39A22C1FCDBADDC3A81EDC8E5EF80FE66B2A69753C82FD63D9CD4496493358B59E14BC382D58982A03F9561B4ED09C4D03D89EF77D9CF47E97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5" - }, - { - "tcId": 22, - "deferred": false, - "z": "973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3", - "d": "D732CF45D7F44788E17C3B6DA9987495AB1AEFA233F74EEF8D3BE5B6C0C04E00", - "ek": "9DA1B8DCA84AF685C5EE685BAF30CA58BC22E9C75ABF67C8D5B8C283BC95004BB51CC6CB001466230710A9E5B43891581C9315A3B579B28B9FB60C5A44D47733105D136ABECE627889E19E4FD25A7C94C404207A4B982327A05451250C173B67A4F7CB2F19CBDA5637E6462842B7688559C599D62A6828AB62B75738E632C381C36E58424AC486BA4C1F4EAB5C4C9A96D27A1F4D3296F65A6094FA7FD27B02707C69A7B92787F737CD4623E3E51444CC698CBC7B38AB98F9883C63210442C8508A126870B7C45127C3C036B39A4C1E44909570382DC20B31E8E262ADA13847599EEAE60BFA024254726D36717C4C43B4BA148F82A93667B82407F2AA3E076E19E513564CA6907C293023773FBA330B8B9C90B08665122D31564BED3632936C5C70C4C452880BFAB97EE6018A67E0891EF64C86E8C4562C29CA609381B8AF55FC09069673FAE60E0412678958053F160F4E4AA135D89FBB0172D10CCCAD38070AE918D85C0866882829603B8E4B90E2074716A05FFE7B1959F8C16FA7CD42CC8A124B930AB87812C4C47B8C58352677EB718F508165CCD4CB3F6B6FA86460B744708F57046FD17215EC9AC6F92EA354AF8C83C0B4369AA475233A310FF7A915F9C64A10327F042C8D6450B0248621DD7748D116C090C6C6B58447433810EA47A07F9956482073FAA67CFE513AECDB87A1695A23E454D918CE0E69BBBBF0761F1B1C8F535469CC25204592DDF8008154144D148B20460F95B1B26D0CC5FF45081E379B85E642EBFA1728CA1435B081F4F608A92148FE27AD97D10BE5D3550ED08319218768D31D5DD9B2E8629B65A2345D259D45B4719AAB8616DB6422B9AEDA535099D503E8A865F3BB46C3A49C3784CCEE19CA3DE5189873C212068DE128C86884C2A3841D2DABA8088B4CECAB729C0C73421B8D0278343DE01584D37971E802A0699CAE5B2CF86800D6C348A0D8C4942538122C521B56A45244AB672402CF7B1A9E999820349F7E311940B5B47FD07C8CAAB8CD817DB897A4CC7591BEB264F043401B06932F81C5E8F525C81BC5D4C75D75CC98B8B6502625CACD671C408C21812277B7BA3388D40B4FE46510A1ADDFC040696BCFF31CD1DE026A9D5E8D3B6F", - "dk": "AB606FB6D65B4A42C61BF14D57C06B8EE33E740ABE1068833667B8CE769EA1FA5AFE7447863C3DBAB8B86C1C818CC3A2AEF08C50641F566BB154D57E293A468437C6A7805318B3578F83C927E6BB56AA31F096809A315C5D88473DD0BF2162BE18CBC013918504E791779A4A2CF82C5085BAAF78CE27690F164478C1F340A3582C845B2114978E2B7029D6A861FE302653213C1F9A437C9C870513ABA2B64A744A92BC37CCC8C0664CD833065613E7770C6C01A6F9091F02A99EB5F85C2361038A0662B3352C09FBC1948993724A87E2C71D63F7392E9950B2A84F241678FC15890247BE20C660AC3B2FDA9CBB9C919193F13EF3A5BA98901CDED47A6E1B300CF779BCD137748B571FC4CF890A69C1B5CDDBE30650877E2D82263448CDB1882D57716A76294CE8EC931AA131F06965678AB8FD778DAB50C58381B8090A7912462400E0B0E8F7C9F1FA78C57A056B423495C75F62D5138BB3A1034C70208917F30263E66B4D2949377BF29362A6531A81B82EA88517D3B943A14868D7691E4873F29AACFA8B71DBA337C9E0BCC1C8AA8BA82A17A28395B45EDCA609BF95B883731C62C000A3D431525391860223579C247AE825CDE91E1FE3B0A056BE5694627BF3BA189031353429D0C64C79448E5E4C80B8963C4D7229E9188B76F1738C30BDDF49B236544558C9A7F979B1C34826C0FC10B3362E84D62A665B16648CC8376BCB1A71116E260E0439A9EFE287AEC68942F3916CC77817C9C89F378E5976B3C8B9815F7013D573C9EA656A95F40F1243B5940B9F6E830341E1108A45CB68B346600406D87403B8352FD7014CA3762070FB8DF892871087B7E0BC5562B9686BAC3A67665AE4CB118A602C28394224D15C5A9615C86B40184A9B7E4A68DE936C8144A157F4B1AB036F30D92F0BC497ED0716380BAB4677111AD19BDDA98B333C960ACAB48E33AE12389492B98CF4FC90F7102012840010F63CF78B6193E133E45B81E6380B4E01CDD0814C8E97732B4BACF3171215728A378BAB58853E38FC51A788829E810292C5089EE972B8850182D37D49F8BFB09178D5CA779E91776BF8579DA1B8DCA84AF685C5EE685BAF30CA58BC22E9C75ABF67C8D5B8C283BC95004BB51CC6CB001466230710A9E5B43891581C9315A3B579B28B9FB60C5A44D47733105D136ABECE627889E19E4FD25A7C94C404207A4B982327A05451250C173B67A4F7CB2F19CBDA5637E6462842B7688559C599D62A6828AB62B75738E632C381C36E58424AC486BA4C1F4EAB5C4C9A96D27A1F4D3296F65A6094FA7FD27B02707C69A7B92787F737CD4623E3E51444CC698CBC7B38AB98F9883C63210442C8508A126870B7C45127C3C036B39A4C1E44909570382DC20B31E8E262ADA13847599EEAE60BFA024254726D36717C4C43B4BA148F82A93667B82407F2AA3E076E19E513564CA6907C293023773FBA330B8B9C90B08665122D31564BED3632936C5C70C4C452880BFAB97EE6018A67E0891EF64C86E8C4562C29CA609381B8AF55FC09069673FAE60E0412678958053F160F4E4AA135D89FBB0172D10CCCAD38070AE918D85C0866882829603B8E4B90E2074716A05FFE7B1959F8C16FA7CD42CC8A124B930AB87812C4C47B8C58352677EB718F508165CCD4CB3F6B6FA86460B744708F57046FD17215EC9AC6F92EA354AF8C83C0B4369AA475233A310FF7A915F9C64A10327F042C8D6450B0248621DD7748D116C090C6C6B58447433810EA47A07F9956482073FAA67CFE513AECDB87A1695A23E454D918CE0E69BBBBF0761F1B1C8F535469CC25204592DDF8008154144D148B20460F95B1B26D0CC5FF45081E379B85E642EBFA1728CA1435B081F4F608A92148FE27AD97D10BE5D3550ED08319218768D31D5DD9B2E8629B65A2345D259D45B4719AAB8616DB6422B9AEDA535099D503E8A865F3BB46C3A49C3784CCEE19CA3DE5189873C212068DE128C86884C2A3841D2DABA8088B4CECAB729C0C73421B8D0278343DE01584D37971E802A0699CAE5B2CF86800D6C348A0D8C4942538122C521B56A45244AB672402CF7B1A9E999820349F7E311940B5B47FD07C8CAAB8CD817DB897A4CC7591BEB264F043401B06932F81C5E8F525C81BC5D4C75D75CC98B8B6502625CACD671C408C21812277B7BA3388D40B4FE46510A1ADDFC040696BCFF31CD1DE026A9D5E8D3B6F960EBBE29B71F9BB16A8B5EDB72516DEB04771759A6A306CCEE5D40D8E2EFFDA973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3" - }, - { - "tcId": 23, - "deferred": false, - "z": "D525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D", - "d": "B670CEB5612A1287C4653B158A3CC522AAA1AA45B34A4C770DCA1E5BF3988F3D", - "ek": "0148396E994C3C5809BA5A53B28582B5B12827616D84BC9B6FCC94B84A1FF1EA88D308302F611683EB500953AF2D588EE43C7C4CCACC276128E6509DAE5A78DBF654CB9A0AFEF98339A46002B432C90BB863CA5221522BC7E903E2D1AC26E4968B64888DE455D6CC61A7FB2BD8E03BAF87310337361101BEAE92C64904BFD6D74F9D4327E49B15A7468889C6BE1F6A6DBB3529ED166BB0791381D42A59C85D54C1484B50AFFE893FB2A5BFD60974BC804E30A14E5DD22284C361CFC311C261C02D450B864095109B01DF56016A8BABEAE78F6145CD65343A8E7B098E904453E165D31273ECB4486B1B43BF453AE853B74AB920DB1068E8D9C8C8779BB63545EA0A15D4A1C19897C8BD40CA1C66381832A990FB74ADCB4FDFB2185AC33D9A24B58983B352AC26BE979D2FF8B8975B7D6B09B50E0C635625A99E91C552F37C37C72B763047C36192900B0A49BBCBB19C611CE77562D48D06CB735E174184952614B9236C55A256394FC5661F4F70BAF5B22BC1D67860A51E0F301AC5DB4F15D061028026CBB4A35E1782B406C8F92A40FC500F5FE706CB1A33DDB73597575BE787CEDC5C43383A404C88503B351732BB9FAA65C07C0B1EBCE001D5D18203672885E201C3D9855F81C36D39B060761DCD069E7CACC758026456E266DCA665AB32908069448BD251F3D3C09B15B4DC2234642295BA9419574A8E3987B69C4058FE692DB8124821B1A7F4097712B828AB69C9B0F5A6AF9B515588146EE9A1E79780A2C9634AC9CE38282B1E47856F365F23AC249D0BB7E42520B8B3A08792161B8B86C59CC0DECB2160F536394A750CB9373BC62BB2C6AF8257935465C550382822A915A501693A777CC9E46F415BB581C70B39DCA1F84673B6DCA1BF2897B8A57CE247267013A49D3543CC8533EB5BBCCEA0A9C82909ABEB98CADC45EBC5B4034145B7F5A777759CAC11CE4C359B0AD4BC30567E9F195C9082B3A71779D9A3B4EBA72E557AAE9B964285D142BA0031C3990192912F34B540104A7E13674B30C0569685A4ADA913BEA4439ED3C99172A3672886B857830DB939A2836A8E3186C8B8CFD87CEF4EBC154213985561AF0C82B28B8C856D8923219B1829FE8B51954BD0E8", - "dk": "4ED9B27229CB08667437F2B6F0B28ADA29A384F726E1F86DCD26433D55CDD5511158EC7D257892080A4DEE204FA1103890821E2F233281FB064D299DC9684D3D08A60669B014112338476F0455780714524DE0538628C72AD360A795038DF2C3A44058D71C285A4A951086889A8A4DB9AC9B4F76821E12732DF3713842012F3A8F4A611202434A1E6046E58085568037A4884F3D8539FA5005A8E10E93BC03C58BC9D575761E4A5379AAA8422A1CBAF58C8F9C1DFA00BD0550980F86B32036CC2F55C4C6602F5CC528BD1971ABD7AFB1528F39A7CFE1A42CBA9716B1A6A8A6722F04BC5760497F79556D7C065E4FFB9A4E8019F38744849B57D3F17AB8C37FF71CA594691AE9288BF7E1BFB09C9B113C375B4AAB07C91452E384E8F8B1629B7E38A1943513CB2AC40A5803B71DE455FB2B55FC50CE6170A15DC4A9719193A5C2CB17C62B87C53605E955225080011468913AAAA4946C9A084A2405A335BABFF2E19A3209C34273CC96A4509A0041E474C44F53617A36326A7892B6D079BC4651775B0E06EC01C81CBDAA7574CBF84940384A15777F241268CFE65E6408609E404A372BAE702790E185ADAC6AA93843B3CE88696E3252EF73B46C5A4DDE135372A32762B963670565531784144399C6195EA6C924B89AA5F9B64BA44416D92B3E75F7BDEC264549B045922612C0995BBFF71DC7505F04D4BDBEC3A40E7C402A225EF4153C1A322B6E19BCB0328B9ED23FE36A6F13780A6A78171E875CD37A79C3375671D066EB20072DA5CBFFB8772DA14DE98631899597F7F55AE84BBEBEF076E709CB68946041F0095759360E003665408105184B39A7261545AC0E7984FD32A773D05A04A48FBCF02B08E7B3E326583DB71F59E15C7D1A9D6AF1494CB34E63D5C6CC07C23BE95F3EDB765C33131FC92B07592C724832DEFCC1D5F937AA8323C1089CAB760D26AAA49EE1805FF62382998B0A4B8DFF6C91970126833B44518501A908A0A7C462E678495DF876CE3A71528CA877890B56F6B23C9C2C560B0ADA3A1915E265093267E21A2EC18351079011E6E0CF76967AE3B80E1038B3E203A40148396E994C3C5809BA5A53B28582B5B12827616D84BC9B6FCC94B84A1FF1EA88D308302F611683EB500953AF2D588EE43C7C4CCACC276128E6509DAE5A78DBF654CB9A0AFEF98339A46002B432C90BB863CA5221522BC7E903E2D1AC26E4968B64888DE455D6CC61A7FB2BD8E03BAF87310337361101BEAE92C64904BFD6D74F9D4327E49B15A7468889C6BE1F6A6DBB3529ED166BB0791381D42A59C85D54C1484B50AFFE893FB2A5BFD60974BC804E30A14E5DD22284C361CFC311C261C02D450B864095109B01DF56016A8BABEAE78F6145CD65343A8E7B098E904453E165D31273ECB4486B1B43BF453AE853B74AB920DB1068E8D9C8C8779BB63545EA0A15D4A1C19897C8BD40CA1C66381832A990FB74ADCB4FDFB2185AC33D9A24B58983B352AC26BE979D2FF8B8975B7D6B09B50E0C635625A99E91C552F37C37C72B763047C36192900B0A49BBCBB19C611CE77562D48D06CB735E174184952614B9236C55A256394FC5661F4F70BAF5B22BC1D67860A51E0F301AC5DB4F15D061028026CBB4A35E1782B406C8F92A40FC500F5FE706CB1A33DDB73597575BE787CEDC5C43383A404C88503B351732BB9FAA65C07C0B1EBCE001D5D18203672885E201C3D9855F81C36D39B060761DCD069E7CACC758026456E266DCA665AB32908069448BD251F3D3C09B15B4DC2234642295BA9419574A8E3987B69C4058FE692DB8124821B1A7F4097712B828AB69C9B0F5A6AF9B515588146EE9A1E79780A2C9634AC9CE38282B1E47856F365F23AC249D0BB7E42520B8B3A08792161B8B86C59CC0DECB2160F536394A750CB9373BC62BB2C6AF8257935465C550382822A915A501693A777CC9E46F415BB581C70B39DCA1F84673B6DCA1BF2897B8A57CE247267013A49D3543CC8533EB5BBCCEA0A9C82909ABEB98CADC45EBC5B4034145B7F5A777759CAC11CE4C359B0AD4BC30567E9F195C9082B3A71779D9A3B4EBA72E557AAE9B964285D142BA0031C3990192912F34B540104A7E13674B30C0569685A4ADA913BEA4439ED3C99172A3672886B857830DB939A2836A8E3186C8B8CFD87CEF4EBC154213985561AF0C82B28B8C856D8923219B1829FE8B51954BD0E8379CBECD878337A3709BC5A62C5528CB3504D6A87427DC404EFF9ACAE893CEEBD525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D" - }, - { - "tcId": 24, - "deferred": false, - "z": "9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13", - "d": "3236CB10279681238E5B0E2F5138A7F743443379F5F1A845F3D76B75D2C2A9DF", - "ek": "E08607BB14655E1B5DAA36971A842091513B13720A20971FF32279FDE800CF82A95F96AC390749661958E510605DB13175B941D27AA8D1B07A76BB3EFCF8810F144F2566C938DA012E792F5EA41AB74431DD50584756963C752F8ED1109021521D4CA897019AF967275C92AEBA2655ABB291E9115C964C5E5EE748D8C0258DDC504DBB98218A7DC035251A958CC30821ADC997667616DE2A4497039189F582BC4AA9EA4A33BDC1858D8681D4088622A0CB8EA59413423BEDF0CFF7F36BB419B1B672820EC177B3920797244079738EBEAC8D34057804E9A6AA31B39F589F59198972213A12F80D4163A93511985B892ED8BA9A0FA260A4EA8A3BE1A556174C3A599F31D037293C5B8F6A229E23ACB6C772529B918C5324246C2E6B8C693C512BAD0C1677E013C7B10686E728E66723068256FE924F2F3A1578569D24D8327AC543C43AAF423776EEF10D43A69AD87058A37A95F4D8C444A08EAA9CB687E0851BC2A7D304B39B2953AC81A4E9E6B454DB06E75B495B11416D78C86009904377996BB0489BBC2C1B68C5FED757782082472616BCD7AB7747A36457B7BEE74F9BF39A10C9071BCC9269B61EE93B2062160EC69174229A9EDA906559F677018A28F1A278D6337CA54AC68F7265133A1CB59A64E0699348153613191DA8793D441C1422F498B9088EE3664153F67EC443CD8DD10D3068628F10C49662CEE84CC2C85B3C59553B7220AE499C1A9838A8D0E497C11717B5539575F62CB49597C9466A0331C118849F53CA4EAA516CD8343B28F5A0787313F6F1331976329203B0CF871A2CBA0418A574DB037DD12A139C3B36850C8E2B2C056920A1F656873DA9CEF9427D4FDB15D069CD54FC479DD63464F63598728D050444E2014D6E7040F7942991D34B228076B14207F8777D718180AC9C54379B7952F732E865A915F874D1BB839C1A4E2617455AD061509C83CD9A123A2B34C4393C8D09A2C9BB8D52643FB6205730C98976F99D649428CCDC4D109242E7660DA8187C1C1BA83FA11834B0824E31084F0693ADDC1F06DA292398906CF2C07DB5337EACB9492C57F12499B9BA7828A4D75A3EAF1E72A78C47ED24CDD9A7BE6E15D35A92BD110C97DF3F400DD95B", - "dk": "E3930A94D60F5D896AFC749DC3D5CE56A566D7D28795B7747EF95DF030C97C048657B6C1AC754E15F47120F75129E34B10BC3F11924D42655836D6B7E5D126309070E2D75E616A517481842B851148A586D9015045DA3602FABDE204AEDC633B95C30B8DD533D61222BB465BE3BCCD792868990C3E7C1B0E086ABD3EA9CF4F110B1E7612B0C32FDC693CE2FA3004E40A507674528749A470ACE9201D68F56CA717C19539A0418488CEF40CEA1458D6EC298FD04F60C9878F01851EF07B032C3A91B0C742A445E5E72131E00594D0595794745C26BF17E7A4297A9186B23F3DC90B0EA183CFC13AB5269CBC4310840029644876E6C6C73E066230F182CE3B0F039522DC7ACA25AB1DBEE371574786308C177E1ABE75C202D383C47409111FC29F72E18085542E231486F6F76A9CD0BCB9384DAF6318260761E96A0A36DBB50B902BF6355186B6BFB552AE94385523E02935F98C2A35AA3BBC03B7B9A4E4559C741347C304AA8C033524A8835294738908879374C8AE76BDB52C30203A50D5B9330CD2941E6A9EDD51659C50165C06232778B39AB6041E27BFA5DA56A5811C7CE35140724E7DB5072BEB217518120D5366DADC4653DB4D260C65DBA35342D34BADE3A27E3757345C3DC4D4B4AE1068D02989B63722BE94A2C8589DFF97B236B0CBEBC436F71B4DC2A619FB88C16A476A42E51410ACB5BDFBB01E9B695C2724536BADA18913E3F3555B120D61A158F8722688B6C703675CC9580C37C52E2A338E08192E3472BB600037DA863195F0A0E4C215FD57A19BA20CD57021F5025E0AD79FAB9123238890451547B0670491B03DA6C6567A767449B7BBA1FABEDF7BBD38E56A02F9AE20E0C5BE502350A1A27A9A5457B3C173796986F4703EE6BC2706630ED56859781DE66AA9B9AC87D9F512FE569C5F164B46AC0F3175516F633FE31C60B09893CEE29EAE725F65033E0B1BABBE453F84F6673A963FE74A8B5FA046108A2243690D9072406154C6A0024D2CA4B4EF1A681A911A781C776C126775B0CE65110BD8C76A1B2444F62B2CE4541C102C70C1F46B6B5AC0F8A8574836122A99B1E08607BB14655E1B5DAA36971A842091513B13720A20971FF32279FDE800CF82A95F96AC390749661958E510605DB13175B941D27AA8D1B07A76BB3EFCF8810F144F2566C938DA012E792F5EA41AB74431DD50584756963C752F8ED1109021521D4CA897019AF967275C92AEBA2655ABB291E9115C964C5E5EE748D8C0258DDC504DBB98218A7DC035251A958CC30821ADC997667616DE2A4497039189F582BC4AA9EA4A33BDC1858D8681D4088622A0CB8EA59413423BEDF0CFF7F36BB419B1B672820EC177B3920797244079738EBEAC8D34057804E9A6AA31B39F589F59198972213A12F80D4163A93511985B892ED8BA9A0FA260A4EA8A3BE1A556174C3A599F31D037293C5B8F6A229E23ACB6C772529B918C5324246C2E6B8C693C512BAD0C1677E013C7B10686E728E66723068256FE924F2F3A1578569D24D8327AC543C43AAF423776EEF10D43A69AD87058A37A95F4D8C444A08EAA9CB687E0851BC2A7D304B39B2953AC81A4E9E6B454DB06E75B495B11416D78C86009904377996BB0489BBC2C1B68C5FED757782082472616BCD7AB7747A36457B7BEE74F9BF39A10C9071BCC9269B61EE93B2062160EC69174229A9EDA906559F677018A28F1A278D6337CA54AC68F7265133A1CB59A64E0699348153613191DA8793D441C1422F498B9088EE3664153F67EC443CD8DD10D3068628F10C49662CEE84CC2C85B3C59553B7220AE499C1A9838A8D0E497C11717B5539575F62CB49597C9466A0331C118849F53CA4EAA516CD8343B28F5A0787313F6F1331976329203B0CF871A2CBA0418A574DB037DD12A139C3B36850C8E2B2C056920A1F656873DA9CEF9427D4FDB15D069CD54FC479DD63464F63598728D050444E2014D6E7040F7942991D34B228076B14207F8777D718180AC9C54379B7952F732E865A915F874D1BB839C1A4E2617455AD061509C83CD9A123A2B34C4393C8D09A2C9BB8D52643FB6205730C98976F99D649428CCDC4D109242E7660DA8187C1C1BA83FA11834B0824E31084F0693ADDC1F06DA292398906CF2C07DB5337EACB9492C57F12499B9BA7828A4D75A3EAF1E72A78C47ED24CDD9A7BE6E15D35A92BD110C97DF3F400DD95B402618B875F180B5A47574F635D61BB39EA75D44240CBD759B7B5C22C889851C9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13" - }, - { - "tcId": 25, - "deferred": false, - "z": "0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7", - "d": "C155568B6BA74DA317388423F8FB28585977EB858EE306CAE4174120F02A8D72", - "ek": "655CA28309AD58DA0D71919EED2C5676E134C1AB1860923F1E34AF07581D64121B72B8ACE613BE88AA28BD7B0138B44FD9C39B65FAADA741934AF9207AFA367CC1AB29CB71806735973188CD146813331DEA81A811F61FD8F59FC668AB29C581C5878F2D4698E5CA52DD664AEC16ADC357CEA156876BB6663DB12479F488AA46B7873968D0AA43EDC0B847F19FD4410F5E45C2A599A09E634E65B206352383B79BC6EB9309574733F9F2226D4402A4946A00D7B469DCC58F910D5B149BB5731FD89CAF9734C2531381EC2A60F68A9DFCA55C288C68BEE4A919A9A82CF01E5EA86A170B76ED5B35AD9573C3156A24D8A9718683D0F44547F03EF0237B430C16C1A22AF41B7D46E839CA40A7F5F982ECDA7EF21A7E93283B6CBB566E2237636925B887616DB260019876386BB9CB63A42EAC0EADC4C6B99A3EC4131667A4BC3015B19A9A7896422DE73655379BB57675C26F31609BF5525AC13B1A711974F7CB80BACF59B43A8C0AC6B3249968E462F782CF85661207744B4E016C22531D4879B4AD9BC80320503D311CE818A29B95595AA6AA4590876C4C62E0F5A75ECAADF4154634475425B7BD690A09650C7B543589D0342C18A2B774CB7DC8C44F3502A2C2BC148465061842118321A8D4465B4383B45A52727B389FD5A9601E560C9FF68882C629D209527429C79A1ACC000B698181AE827A7E6F14235AF281460A91DBECC30E4AC3AFC4A22E45B3F1209BBDEABDD678197EFCB927B47B0C4204FD473AAB098984349FDF80B960203530E36153BAA675545F5DC6B49A276F1D210373553F9F90B2A5C661415C65A973991E2A99C756273D3261B8750431CA866FA234A7E98035804A0AAACF8D36A0BF4A5C9F9C5614138287858FC106CDB6918E2FB37BEAE2139F806838776E2B3534D78ABB199833E784A6FC144A6D7CB8984C4563E273CE11421927377A992D602BBD11457A2C88B999B13A6B3944445CC7C8328F47040C5CB8B2EB29192FAA2720B1788A408F59828D42017D27587CEC9CA49F44829AAB7FAACC484936B38E02820C03C880F7CEC7057B89A1604D7B1865090CDF056B83E84864E13B8B1B16E5BF2115103F5E1A77266147DEB23013A1A909C1FAE8BE", - "dk": "03D96BD4C488568ABFE20B8FB2C408AAD328481B228C03894BB5248292B2F87714622714A36936DBE1BC477AC57EF3B3F46570B776014F0C12D3B0BA3FE81AA3CA9908ABCFB47AC622AC4A4ADAB3C0052EF8F133E2F8B415C3BE8943BB55C902F792CD6F3A363D3C6530D0A4AB1886EDD770FF18832BB7AD89CA126450A0A2CA587EE1552F149C2DC570447A400C403A2883A8D79B361E4AB99B53B4F6C5CF88E6B2CCE28E69356FACC4217539583ED813ED0A554562C02F6696E9AC5714B5ADD1BA77E603528A3961591B5593337E7EA552E9770AB43009A531679F4C66C0E817BA0354BA24977572956DD7043C911133F28982D4B901307375CB2EEA0089D1C03E6594AA78884BD5E7C9A8A89E9661C2E2629240CCA2E4235B13AB21F75C6FC6A529A574CDE0C5381E40137A9CCBFD910243174BE6225C3ACC8F38393365530F2905294F9ABA5108A3487C9D056559C9E8A11CC94F7CDC46533C391FB2A491973F8BB9545773BB90FB43DD7435DF6C90F8B411A8274FF648A0EEE54FEF30315993C5BFEB6BA0233EE920CE01927F8752A63598528E463A856930598643D825279F99C113B1578EB0B1D72B730D8721B8B149DD0B558977B0C3BBB0E05383C4B8844F661B6C34220D2A5FD7113DA3217EFFA6AB0C382808C0A177987E7DC8B86F39C3872A66412755230B0CB119A3E49541AD1868B9753F069A167E604BE6E01F129A684B880930202221D0BED12B9763B8BF41E639CD233FE6AA0B1A8082D6D46E5316405AA06154C622A384154FD69434E161EC4470B82466D84CCFA01B0C795C9BD7175A2DDBBC5B1CA564D942A0226F096A54AB5719A58A60387B5AFED4878DA08E9763A164E150F50CA719214181165CF1069E29FA2AD81ACA55A802DC9A03F351369F525C5DDA776B93717A617A969811C89CC27ADB185B2A197A47C6C360B7D254C0F32A20C8A35990C67098896180AB9456866B09E62941482B626BC40F63136A677AA7E1236A7B8ADD810193EC4C3E221017A6A8DBF079122CB288D60795482039A4AA7CD785B85B44D1817E5F79232318C0F6F408648A3E5395C4655CA28309AD58DA0D71919EED2C5676E134C1AB1860923F1E34AF07581D64121B72B8ACE613BE88AA28BD7B0138B44FD9C39B65FAADA741934AF9207AFA367CC1AB29CB71806735973188CD146813331DEA81A811F61FD8F59FC668AB29C581C5878F2D4698E5CA52DD664AEC16ADC357CEA156876BB6663DB12479F488AA46B7873968D0AA43EDC0B847F19FD4410F5E45C2A599A09E634E65B206352383B79BC6EB9309574733F9F2226D4402A4946A00D7B469DCC58F910D5B149BB5731FD89CAF9734C2531381EC2A60F68A9DFCA55C288C68BEE4A919A9A82CF01E5EA86A170B76ED5B35AD9573C3156A24D8A9718683D0F44547F03EF0237B430C16C1A22AF41B7D46E839CA40A7F5F982ECDA7EF21A7E93283B6CBB566E2237636925B887616DB260019876386BB9CB63A42EAC0EADC4C6B99A3EC4131667A4BC3015B19A9A7896422DE73655379BB57675C26F31609BF5525AC13B1A711974F7CB80BACF59B43A8C0AC6B3249968E462F782CF85661207744B4E016C22531D4879B4AD9BC80320503D311CE818A29B95595AA6AA4590876C4C62E0F5A75ECAADF4154634475425B7BD690A09650C7B543589D0342C18A2B774CB7DC8C44F3502A2C2BC148465061842118321A8D4465B4383B45A52727B389FD5A9601E560C9FF68882C629D209527429C79A1ACC000B698181AE827A7E6F14235AF281460A91DBECC30E4AC3AFC4A22E45B3F1209BBDEABDD678197EFCB927B47B0C4204FD473AAB098984349FDF80B960203530E36153BAA675545F5DC6B49A276F1D210373553F9F90B2A5C661415C65A973991E2A99C756273D3261B8750431CA866FA234A7E98035804A0AAACF8D36A0BF4A5C9F9C5614138287858FC106CDB6918E2FB37BEAE2139F806838776E2B3534D78ABB199833E784A6FC144A6D7CB8984C4563E273CE11421927377A992D602BBD11457A2C88B999B13A6B3944445CC7C8328F47040C5CB8B2EB29192FAA2720B1788A408F59828D42017D27587CEC9CA49F44829AAB7FAACC484936B38E02820C03C880F7CEC7057B89A1604D7B1865090CDF056B83E84864E13B8B1B16E5BF2115103F5E1A77266147DEB23013A1A909C1FAE8BE213234B8355942F1CF9F299DC63B953C236F330E3D406312E9E0CE14A3987E8E0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7" - } - ] - }, - { - "tgId": 2, - "testType": "AFT", - "parameterSet": "ML-KEM-768", - "tests": [ - { - "tcId": 26, - "deferred": false, - "z": "A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD", - "d": "E34A701C4C87582F42264EE422D3C684D97611F2523EFE0C998AF05056D693DC", - "ek": "6D14A071F7CC452558D5E71A7B087062ECB1386844588246126402B1FA1637733CD5F60CC84BCB646A7892614D7C51B1C7F1A2799132F13427DC482158DA254470A59E00A4E49686FDC077559367270C2153F11007592C9C4310CF8A12C6A8713BD6BB51F3124F989BA0D54073CC242E0968780B875A869EFB851586B9A868A384B9E6821B201B932C455369A739EC22569C977C212B381871813656AF5B567EF893B584624C863A259000F17B254B98B185097C50EBB68B244342E05D4DE520125B8E1033B1436093ACE7CE8E71B458D525673363045A3B3EEA9455428A398705A42327ADB3774B7057F42B017EC0739A983F19E8214D09195FA24D2D571DB73C19A6F8460E50830D415F627B88E94A7B153791A0C0C7E9484C74D53C714889F0E321B6660A532A5BC0E557FBCA35E29BC611200ED3C633077A4D873C5CC67006B753BF6D6B7AF6CA402AB618236C0AFFBC801F8222FBC36CE0984E2B18C944BBCBEF03B1E1361C1F44B0D734AFB1566CFF8744DA8B9943D6B45A3C09030702CA201FFE20CB7EC5B0D4149EE2C28E8B23374F471B57150D0EC9336261A2D5CB84A3ACACC4289473A4C0ABC617C9ABC178734434C82E1685588A5C2EA2678F6B3C2228733130C466E5B86EF491153E48662247B875D201020B566B81B64D839AB4633BAA8ACE202BAAB4496297F9807ADBBB1E332C6F8022B2A18CFDD4A82530B6D3F007C3353898D966CC2C21CB4244BD00443F209870ACC42BC33068C724EC17223619C1093CCA6AEB29500664D1225036B4B81091906969481F1C723C140B9D6C168F5B64BEA69C5FD6385DF7364B8723BCC85E038C7E464A900D68A2127818994217AEC8BDB39A970A9963DE93688E2AC82ABCC22FB9277BA22009E878381A38163901C7D4C85019538D35CAAE9C41AF8C929EE20BB08CA619E72C2F2262C1C9938572551AC02DC9268FBCC35D79011C3C090AD40A4F111C9BE55C427EB796C1932D8673579AF1B4C638B0944489012A2559A3B02481B01AC30BA8960F80C0C2B3947D36A12C080498BEE448716C973416C8242804A3DA099EE137B0BA90FE4A5C6A89200276A0CFB643EC2C56A2D708D7B4373E44C1502A763A600586E6CDA6273897D44448287DC2E602DC39200BF6166236559FD12A60892AEB153DD651BB469910B4B34669F91DA8654D1EB72EB6E02800B3B0A7D0A48C836854D3A83E65569CB7230BB44F3F143A6DEC5F2C39AB90F274F2088BD3D6A6FCA0070273BEDC84777FB52E3C558B0AE06183D5A48D452F68E15207F861627ACA14279630F82EC3A0CA078633B600AFA79743A600215BE5637458CE2CE8AFF5A08EB5017B2C766577479F8DC6BF9F5CC75089932161B96CEA406620AEDB630407F7687EBBB4814C7981637A48A90DE68031E062A7AF7612B4F5C7A6DA86BD136529E64295A5613EA73BD3D4448CB81F243135C0A660BEB9C17E651DEF469A7D90A15D3481090BCBF227012328941FA46F39C5006AD93D458AA6ADD655862B418C3094F551460DF2153A5810A7DA74F0614C2588BE49DC6F5E88154642BD1D3762563326433507156A57C57694BDD26E7A246FEB723AED67B04887C8E476B48CAB59E5362F26A9EF50C2BC80BA146226216FE62968A60D04E8C170D741C7A2B0E1ABDAC968", - "dk": "98A1B2DA4A65CFB5845EA7311E6A06DB731F1590C41EE74BA10782715B35A3102DF637872BE65BAB37A1DE2511D703C70247B35EF27435485024D93FD9E77C43804F371749BA00B20A8C5C588BC9ABE068AEAAA938517EBFE53B6B663282903DCD189736D7296816C733A1C77C6375E5397C0F189BBFE47643A61F58F8A3C6911BE4611A8C7BC050021163D0A404DC14065748FF29BE60D2B9FDCC8FFD98C587F38C67115786464BDB342B17E897D64617CBFB117973A5458977A7D7617A1B4D83BA03C611138A4673B1EB34B078033F97CFFE80C146A26943F842B976327BF1CBC60119525BB9A3C03493349000DD8F51BA21A2E92361762324600E0C13AAA6CB69BFB24276483F6B02421259B7585263C1A028D682C508BBC2801A56E98B8F620B0483D79B5AD8585AC0A475BAC77865194196338791B7985A05D109395CCA8932722A91950D37E12B891420A52B62CBFA815DF6174CE00E68BCA75D4838CA280F713C7E6924AFD95BAA0D01ADA637B158347034C0AB1A7183331A820ACBCB83193A1A94C8F7E384AED0C35ED3CB3397BB638086E7A35A6408A3A4B90CE953707C19BC46C3B2DA3B2EE32319C56B928032B5ED1256D0753D341423E9DB139DE7714FF075CAF58FD9F57D1A54019B5926406830DAE29A875302A81256F4D6CF5E74034EA614BF70C2764B20C9589CDB5C25761A04E58292907C578A94A35836BEE3112DC2C3AE2192C9DEAA304B29C7FEA1BDF47B3B6BCBA2C0E55C9CDB6DE7149E9CB17917718F12C8032DE1ADE0648D405519C70719BECC701845CF9F4B912FE71983CA34F9018C7CA7BB2F6C5D7F8C5B297359EC75209C2543FF11C4244977C5969524EC454D44C323FCCA94ACAC273A0EC49B4A8A585BCE7A5B305C04C3506422580357016A850C3F7EE17205A77B291C7731C9836C02AEE5406F63C6A07A214382AA15336C05D1045588107645EA7DE6870FC0E55E1540974301C42EC14105518680F688ABE4CE453738FE471B87FC31F5C68A39E68AF51B0240B90E0364B04BAC43D6FB68AB65AE028B62BD683B7D28AD38806BEE725B5B2416A8D79C16EC2A99EA4A8D92A2F5052E67F97352289761C5C39FC5C742E9C0A740CA59FC0182F709D01B5187F00063DAAB397596EEA4A31BDBCBD4C1BB0C55BE7C6850FDA9326B353E288C5013226C3C3923A791609E8002E73A5F7B6BB4A877B1FDF53BB2BAB3DD424D31BBB448E609A66B0E343C286E8760312B6D37AA5201D21F53503D88389ADCA21C70FB6C0FC9C69D6616C9EA3780E35565C0C97C15179C95343ECC5E1C2A24DE4699F6875EA2FA2DD3E357BC43914795207E026B850A2237950C108A512FC88C22488112607088185FB0E09C2C4197A83687266BAB2E583E21C40F4CC008FE652804D8223F1520A90B0D5385C7553CC767C58D120CCD3EF5B5D1A6CD7BC00DFF1321B2F2C432B64EFB8A3F5D0064B3F34293026C851C2DED68B9DFF4A28F6A8D225535E0477084430CFFDA0AC0552F9A212785B749913A06FA2274C0D15BAD325458D323EF6BAE13C0010D525C1D5269973AC29BDA7C983746918BA0E002588E30375D78329E6B8BA8C4462A692FB6083842B8C8C92C60F252726D14A071F7CC452558D5E71A7B087062ECB1386844588246126402B1FA1637733CD5F60CC84BCB646A7892614D7C51B1C7F1A2799132F13427DC482158DA254470A59E00A4E49686FDC077559367270C2153F11007592C9C4310CF8A12C6A8713BD6BB51F3124F989BA0D54073CC242E0968780B875A869EFB851586B9A868A384B9E6821B201B932C455369A739EC22569C977C212B381871813656AF5B567EF893B584624C863A259000F17B254B98B185097C50EBB68B244342E05D4DE520125B8E1033B1436093ACE7CE8E71B458D525673363045A3B3EEA9455428A398705A42327ADB3774B7057F42B017EC0739A983F19E8214D09195FA24D2D571DB73C19A6F8460E50830D415F627B88E94A7B153791A0C0C7E9484C74D53C714889F0E321B6660A532A5BC0E557FBCA35E29BC611200ED3C633077A4D873C5CC67006B753BF6D6B7AF6CA402AB618236C0AFFBC801F8222FBC36CE0984E2B18C944BBCBEF03B1E1361C1F44B0D734AFB1566CFF8744DA8B9943D6B45A3C09030702CA201FFE20CB7EC5B0D4149EE2C28E8B23374F471B57150D0EC9336261A2D5CB84A3ACACC4289473A4C0ABC617C9ABC178734434C82E1685588A5C2EA2678F6B3C2228733130C466E5B86EF491153E48662247B875D201020B566B81B64D839AB4633BAA8ACE202BAAB4496297F9807ADBBB1E332C6F8022B2A18CFDD4A82530B6D3F007C3353898D966CC2C21CB4244BD00443F209870ACC42BC33068C724EC17223619C1093CCA6AEB29500664D1225036B4B81091906969481F1C723C140B9D6C168F5B64BEA69C5FD6385DF7364B8723BCC85E038C7E464A900D68A2127818994217AEC8BDB39A970A9963DE93688E2AC82ABCC22FB9277BA22009E878381A38163901C7D4C85019538D35CAAE9C41AF8C929EE20BB08CA619E72C2F2262C1C9938572551AC02DC9268FBCC35D79011C3C090AD40A4F111C9BE55C427EB796C1932D8673579AF1B4C638B0944489012A2559A3B02481B01AC30BA8960F80C0C2B3947D36A12C080498BEE448716C973416C8242804A3DA099EE137B0BA90FE4A5C6A89200276A0CFB643EC2C56A2D708D7B4373E44C1502A763A600586E6CDA6273897D44448287DC2E602DC39200BF6166236559FD12A60892AEB153DD651BB469910B4B34669F91DA8654D1EB72EB6E02800B3B0A7D0A48C836854D3A83E65569CB7230BB44F3F143A6DEC5F2C39AB90F274F2088BD3D6A6FCA0070273BEDC84777FB52E3C558B0AE06183D5A48D452F68E15207F861627ACA14279630F82EC3A0CA078633B600AFA79743A600215BE5637458CE2CE8AFF5A08EB5017B2C766577479F8DC6BF9F5CC75089932161B96CEA406620AEDB630407F7687EBBB4814C7981637A48A90DE68031E062A7AF7612B4F5C7A6DA86BD136529E64295A5613EA73BD3D4448CB81F243135C0A660BEB9C17E651DEF469A7D90A15D3481090BCBF227012328941FA46F39C5006AD93D458AA6ADD655862B418C3094F551460DF2153A5810A7DA74F0614C2588BE49DC6F5E88154642BD1D3762563326433507156A57C57694BDD26E7A246FEB723AED67B04887C8E476B48CAB59E5362F26A9EF50C2BC80BA146226216FE62968A60D04E8C170D741C7A2B0E1ABDAC968E29020839D052FA372585627F8B59EE312AE414C979D825F06A6929A79625718A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD" - }, - { - "tcId": 27, - "deferred": false, - "z": "DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C", - "d": "444F032DD19AE7518C4B35B0732A41DC567845ABA8BD7B04A9C413A0CF2DE0B5", - "ek": "5CC523B2D908C45907A6694A665195171A5B2FB583A5C240CADCA8F0E83E46B14052C9620D3B7EF386CE8B9A5E873B65693B0D341C6EB2D10CE5E937CFB8C4C9134401BABFEEBBAECF47113A34B9C6E011BDC78A54F2B7BF36A5FFD27563D7443F2109F02A64C421411DDB2D1404A86F793A2DE62CDC560BFD6604D4B6330BA6AA621414E8C12DC71C25652ABAF36B875DE1978DD209AB53B885206C3A1B4F8B4A0670C087CDA9CDA7997437155659255C2D024822A448CE5157CF5B6E4C495A949960886A902C79591120117C4A73CE7B380C661851E1CA9EF1973D8A9D2A191B938C4110259C4227B600BA7EC9B033BB0300715032836573382445435A743CA61E923B18ADEC7CFAF10ADE908E582560EE91ACA012942319B4888109E55AA738A7BCF777C92B4B09A50A1C043C982C2C2357F73C1687B35BD123FC905E1A719353466A42B915DBF1A1750339BF0923419681E4531D97E2160AD896DB056570570510FB711169AF2DE0CBA51C5F5056242965AD429301E7020AE0141F845833A3FBA0B192426C001A7147C2926805CD86725442CADC2636BB769DCDE46D1BD12D30F4695593B5753870EF796FB2F3A53F283D5828B77CB75D5DE1BA25357C290A957FD501AEE0AE59D7AE97833B0BB640F781A08BD256C79117C220BDD83280A0069B29A645720096D297A2E5245439268C0ED01F75A939978372B9E05D93DA899C10BF6CDB18698C46EBE00BF90730E2EA393014461DEC6C87F17B2EE16C13B8507C6009BEE074F17367A5FC3067A28B7D804C32860EDE650E6FE85CF6E301D1B1647323199CA296ABC54D2811507572B5DFF92B54E3786D130938417624775D8534B0102B6B8006803DDB376EB830D1CA80E717BB7F260A5CA4A56BFC5DA790151725942AE7C42B2B9E385B4E0F995D4402161070B73A6BB0CDB77EF11B1286D75E315635E719088DC7909D026B198AC93BB4B6FE395843A4428F75C0C1448C605A8CABA0B8CD19CE465764B523628B3334E3885D68D5089E1A3045840C36A73AEFE7B93AB357FD8A46D7547A8EFB243E4953E67CA72CFA0B77835768AA0CD2D976820A97BC21C7033084AD45C0BF6B483ACA8A485641EB55A47BE36ABCEB96143BA90C515D5BE8513BB994CFA88FF4B3600E34C1E656877606B6280384A0F481458044C47732FA9B58195A5DFB48636E1558C56A43CB6941DEE5AEB1E27B89A7121BE166879B62BC01619A9ABE840CC678E028E9BC71CE233FD9DB8816294D71F1A080101912920534750DDE692F782BAC4D4481A0900E6BB952ADA798EE06232C200F57F76A914617914B7398A0433CD7A11B5AC09789034F39338CE567E3E7AEFE35B0C3B85D21506E8886587670761AF9BAD3261DAF22CBFC664604234B3B784EA001CC6702B9222545CFDB2965EB54678780EE3C9CC134CD2E655908D6BDF460BEE364C66D5ACCF4B492ADE9A0F3EB31995BADDE4628B67165FF6014D848541035CDA46949EC1C12FF492726A7214D1C7273FB85D5484E5A178751B56E3FB163D13A53C7B3038E09B847A8C06FF9B42E8C345CC95AAC1A09660AC1FC7A146E7845AB83390871655E604C4C009EE924AE107B61BC3664F488AC60783A1C346BD18C56CED3F03BC1B1E4075E9785F235EBC5CE6621414E77D52CEC3B2E", - "dk": "657004A34B4EA6B278BDC1BC94A997D86B206F88875A934042732CFAF8B3A0141FDD815F2203BD92AC478A9033126A8478FBB6453AAE005C03F60444163066EE922781D08DFB1508F547555B3027A2F75F28401A7D69A09669AC8309C3D4E4B49B214C4C76B3E4C26CED4940A325885C71883881B6C18C57BF22CB4484674A738988708FB7EC68855A96EF033B4A877038612B7B14BB3DCA791DC5CC7C85614A694D0672CB5656CA51C7B3CE11ABE1F4B790800FE7F47F97D640141702B147A3A6D99279B258CAE7899C353A66F6AF3C53C4A632BEB545B65A2724EF06CD05978E3EE20BF264A0335B21FC2137C71161A8A3AAA1A6AFABD023F58C0C393630E41561568C6669C2683B0B493A60A42889A178ACC3289BB135C891D89698C38AAE187C6E3DB16335FA61BF70C6D496B5251BCEFA9A1C95980E3810C0059C62E8838F1B0B46B4C5A2FEA19E790B2EB4C8C3A164C8BF5C89C2812E982B0F3DA0CDE958A26BD03A38C562CC67B2C07509E6742CB44C04320AA87C23C3E3A7506F26AFE94523D1B05280BA53B4ABB8C5717422D071396C6B7733A09B11CE1E6B2280F1C9215913FBA6522F90C009C0988CAAC61721993AE73DD71A551ED8431C1A8D286857455624842C4CFA80B9143CCEBF930AA1E738EFF1A46EFCC0D766B7E4AC39AD508D6CB9891DEB61B0AAC5FB9385E1D0682F786CA37C3DF1A38BDFC1162E975EB604163752CAC6C47E3BD909C53726C6D084188904CA98C743C9B5D700CBE4A809F1756DCF4C65C5A6B7A7F2725595A0C89C26381C218004B1A275701B50586A327652390FB68868CFE8084067ABC53A9A2CECC72BC625CA7751EC158F35E791008543EB202AE258C588E69E695425B9BA4FE0082ECC530EBFAB41DB23CFA8C2A63AAB11D179C91A712062536C4FF1C205287296B001121436C5F813747350C9AB63CEC0CCF7DAB3E642210517155228910C729BC9B24B138B85ED9A4678B2B4C67A73282842EA66CC458C706BF4A591BBCBBD370E09C937E396B76FE4A3B56B4CF638A5CE055CB63C1275D53B4197493A1A4309A4CCDADC3AD1F47A5E8C5C89235321028EF158094A6385C4E010D6F8CCF1C627BCB3600544B276D2AC9CC91D4BD5AD75DBCC8E7B7A981680212B5A3D395F8AA1CF2B0A23EBB63BDDC5185BE53A6C1410D0D96889A74265E3B34F4477FDF5B680D793F35C7A372B25A1F47C5875B34B80ACA2C25A0DE69D58E71856C55E37A79BC7376898C45BDAD66FD0A554D8F9BD69A525BAA4BF40B0AEFDEC66EA329ACF7B44D33C4FA248734F516BB0A69FF751A3E3D95975DC4E25194CD6F88E7264352628AF45B38A3434951FF99CBAEA812C04C354227431B01CCF2B5955B59BBB5A2BF382227D71631C541AF888232EF733A085AA1D14493C063B64E8BB28E3B7D0686CE8F942EEC58734525DBAC07159627863D97F7C198C50E9AB10E54979C394E90395E6A793C882CBA9D56179B75F11799709577F149CC93EA3A764C610EAE641F8FA2801A22B5686B335117C3C7B3D74986F70384A26A33B323787B7888CF873BE39411829D69D6E2CA2279971AE27660B5224D21015440844C457B6B9F2C50D19580489C63AE0612D423A5CC523B2D908C45907A6694A665195171A5B2FB583A5C240CADCA8F0E83E46B14052C9620D3B7EF386CE8B9A5E873B65693B0D341C6EB2D10CE5E937CFB8C4C9134401BABFEEBBAECF47113A34B9C6E011BDC78A54F2B7BF36A5FFD27563D7443F2109F02A64C421411DDB2D1404A86F793A2DE62CDC560BFD6604D4B6330BA6AA621414E8C12DC71C25652ABAF36B875DE1978DD209AB53B885206C3A1B4F8B4A0670C087CDA9CDA7997437155659255C2D024822A448CE5157CF5B6E4C495A949960886A902C79591120117C4A73CE7B380C661851E1CA9EF1973D8A9D2A191B938C4110259C4227B600BA7EC9B033BB0300715032836573382445435A743CA61E923B18ADEC7CFAF10ADE908E582560EE91ACA012942319B4888109E55AA738A7BCF777C92B4B09A50A1C043C982C2C2357F73C1687B35BD123FC905E1A719353466A42B915DBF1A1750339BF0923419681E4531D97E2160AD896DB056570570510FB711169AF2DE0CBA51C5F5056242965AD429301E7020AE0141F845833A3FBA0B192426C001A7147C2926805CD86725442CADC2636BB769DCDE46D1BD12D30F4695593B5753870EF796FB2F3A53F283D5828B77CB75D5DE1BA25357C290A957FD501AEE0AE59D7AE97833B0BB640F781A08BD256C79117C220BDD83280A0069B29A645720096D297A2E5245439268C0ED01F75A939978372B9E05D93DA899C10BF6CDB18698C46EBE00BF90730E2EA393014461DEC6C87F17B2EE16C13B8507C6009BEE074F17367A5FC3067A28B7D804C32860EDE650E6FE85CF6E301D1B1647323199CA296ABC54D2811507572B5DFF92B54E3786D130938417624775D8534B0102B6B8006803DDB376EB830D1CA80E717BB7F260A5CA4A56BFC5DA790151725942AE7C42B2B9E385B4E0F995D4402161070B73A6BB0CDB77EF11B1286D75E315635E719088DC7909D026B198AC93BB4B6FE395843A4428F75C0C1448C605A8CABA0B8CD19CE465764B523628B3334E3885D68D5089E1A3045840C36A73AEFE7B93AB357FD8A46D7547A8EFB243E4953E67CA72CFA0B77835768AA0CD2D976820A97BC21C7033084AD45C0BF6B483ACA8A485641EB55A47BE36ABCEB96143BA90C515D5BE8513BB994CFA88FF4B3600E34C1E656877606B6280384A0F481458044C47732FA9B58195A5DFB48636E1558C56A43CB6941DEE5AEB1E27B89A7121BE166879B62BC01619A9ABE840CC678E028E9BC71CE233FD9DB8816294D71F1A080101912920534750DDE692F782BAC4D4481A0900E6BB952ADA798EE06232C200F57F76A914617914B7398A0433CD7A11B5AC09789034F39338CE567E3E7AEFE35B0C3B85D21506E8886587670761AF9BAD3261DAF22CBFC664604234B3B784EA001CC6702B9222545CFDB2965EB54678780EE3C9CC134CD2E655908D6BDF460BEE364C66D5ACCF4B492ADE9A0F3EB31995BADDE4628B67165FF6014D848541035CDA46949EC1C12FF492726A7214D1C7273FB85D5484E5A178751B56E3FB163D13A53C7B3038E09B847A8C06FF9B42E8C345CC95AAC1A09660AC1FC7A146E7845AB83390871655E604C4C009EE924AE107B61BC3664F488AC60783A1C346BD18C56CED3F03BC1B1E4075E9785F235EBC5CE6621414E77D52CEC3B2EBBA283F4C993A010081E2CC571D97234472CC9858D199CF0D6E6B9BD720C2665DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C" - }, - { - "tcId": 28, - "deferred": false, - "z": "5AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F", - "d": "092271D05CA63C60880AF404D60BC4BB9539E2EA12969581898D56E0AC9A5A68", - "ek": "E1F90F4586A2A7444812451655F63852C48D2745BCC5D95C15552CA7355A216B1B5131656A95453A854DA8291046A05D96E74CC4507D31973D9606171D8405F211AC5040658411A3997CA061C3AD30EC2AE6CC79CD4C9AB1D1CB47996F02E42BD8819F62457CA5CB9923C570FC749531C61AEF02642576A04E88493AB084AFB353FC0B032AE8AEA812373A323268200FA820C88E1881F0A0CED7D9601DF56C891AC2CF6B299C553C6B1C8A470B68CFF347C2A071B26557F185B4E2138B421A9BB6DAB8FB41C5459644F08614E63C8C4BACC3DF5AB7F86C44E48239EF387217C9540DFB50002C08ED9CB631755446786D4B5BC14D16C5EF629CE2916687C40053A2CD50667CBB590F7D3A2AFD54AECBD6211C84739AB75B80A38E9F27B6D6F1BD4C838BB2706E5DA65B95498CFA61AB90169A2C06B0E79CBAE0051683221C98DA365A27C1DE417666ACCA178717934258207A51DFFA0C926B6E3DA5B084F07560D949AD615724C306EF1165A5B9616FBA84C7D71C1117BBF8296722012EFE25B29C63291D31758278430CD90E844764AC252F33135CD2137115933B38F4160FD482CBD9265C27AC3B6582FC201DEB7A52D23AA5B77BCE9B7C6D699655105B9883830D0171882612212272261A0CC9DDCBC7D3439FF3A01B0BD4B63972263D919BCC9B95018114A11BABECEA27A5BCA3DB896AA49543CC50BC07039D31135BE1354B6A2B6B4375513010CAE856B7AEF64BCE20912432C09FD18905200249D4CC250306C341CB837A96F2B67422B63C29FB8887A962A1F743F3D01795D34E277343E7577878F5A3EC02728E9238D56B2115F680AFC70BBB361B60C10FF7F4094FE240089577D59969907B9192097CC05516A7132C2477435C8BC01909B4AAE5537CA2C6AC79806B6B5F32FB688C609200F16279D9CA987B68EA83A6D6309F1230562196BA93767DF126C98E4C3A3A0BB969629BCCDCB428A333D2B96E50B814716A5479192DCC0C0E4B194AED6A169E5074EF977F689528C997C1B99B02E1B18794B56993743456214064F80CCDA66B71BC009772784AF04FB7F468E2E93E03C18778D13C72FA149C50C1C9F45167A53E09657B50BA2A19B31FA95C5C6550B14F9B931EB51C37890C95157DF4F974E3A167DC005481F945D23780B5498AC5AB80DD8ACCF2D1322D3253B9450EDA3C3B365C9EDC4A87D089AF7797B01BE716917842A4E99CE04C86A9F172062C473C203A328C10DF171FB10C97BA6B8E71271D705110C810843D658B15F2040B385B067B1CE160A4205CBD57B74926143609979F6A888EBBECB7703498A278AE963223A8AA41916A3D37D949A3E298F01CCD36A5B6E0BA9CFF38BB890AB18869B4FB7CA8C1711798CAAB2EAC01ABA26A060266A6A91BA877603E650F7D15C24F9B23C52A9C74F43150E3A1D5D25BD0326724A42572C32944DA713457CB36B14E30F72761480035423810D83721A97505668F11EB26285A1709321A1C8016DB8BB085996D1A4880BD3B1D8BF2754F3781D57BBDE68297AF710188486EB6D4AF7DE411D36787E4D945E33C45CDE051601243A1F7028AD52B3B5C7728F35DD5F8994D4B8D9FA767611A1ADEE8B38C5A7A0AA795D0A970C749A06DCE6CF1C8ED19D1F7E9F1F25538877CCEC133881C652489A84F948041", - "dk": "4967CD2CABA6E5B9C671732DA64B59450440532BBC0372C570341637B81346646971834CCB116C49C562D485982B3C602D723B721A8EF9A35CA6CB045F8A09AB9A176C55801901C2924874D65573F5C0B3F97C1DB4821AC3B23F7621BEBBFC4D1F924E9E0762F037904707128ED964B8B2C42B3B1BA7D101BB8C1A36E1040ADA4CBAFC2BFFAA9D12C69C01F3C65E3676C948C18C273F9EB34EB0C00682A285E6B8A514D1AEE73AB93423C187C57C286801A9AB79F2F7100FB08E03A24AB26625D972C1350B951064A0C2122179CB11914C284BB092DA4A044E2C457807CED5662D0DC23F8D8A951C9766AFFB11D3B3669826736A278FA44386CCD5519F3A04A87B0C9D693D0E505EB889CBC90785635CC08FEB4362E3B48134474B43771BAB84A9933BE0988834CB149A5C3724BB17FDA374D5B57F5260C8E60C37F440A8B3DCB5DC94B946495C025CA1258C7CA7AB56B3765C1EE0ADFD854E617AB40E26922EC667FCEB3192D01DF3D37A484239BA427823302440AA439580074D666DB14C1D1F0C9E5203822394988553C8A0925E04F5AA8B9942E6C9B0C6A942CE569F3987CFED7B7E7DE388AC6BBB7CE4C9FBB6C5D15531A558573431C6B398044F989EE581B95793279F0AB97F4355D9C566B231998C9C046C871A59C11A99B2271CA7364ED5C5A6FCC0EF27A7C147C829C69E09D01CEBDAB91F163C68EB18D382A1A081889281414DCB456CD6C2031C382771073B5621C7B60DC4B0A294C8AA62C5CDF68BB6B46692196198C1EB2FC9528B33A0B829CB9B809C010A3054230188DDFA60013375DC1C6A967146D1B77362A448E4FA97C3B72C2AF5C9A4193290630AB400CA5830024888AADB52A9D4894B5AA03322946062D523018131645B825D5BB8DCE285DF2977B96C02977BC889737C78C2A3DCC5666B652C6E8C24141516DD8520DFE84E5129AA6BF55BB1EC79C3771B029A3B91F9701677C854E4105D5A485F8CB6A5C29CB2F47A4A60281F8B1FC8BC150122B08296B45F97C58CEB743B42000720CBBE5022B7143D3E177023ACA482988135197237706C26A94B35E20DE3CC0C53CA9626F2615E4B8D581BC2656AA72A0AB9242670E6322A89489C97177E3EA1AB9C24338AA35FA272C76893053A76051F4A88DE1944FBB0AFC8E904CD1033E7DC0D0ED029A7531EB612C7B46775FDC09B54C483F6B06ED16427F50421B6F59C06FB0AE4F120C54644DD287CE3119E440AAA8E0A611AB9B52DB1B445036E2CF15BB8DC72CEF50DC3788BD85832D0C18B2685659F8A8BD55144A4EC9764109288B21113E4089E598BBA1453041C9717AB25BA5239FC54638B5A20247B9BB755A360E16F83246CA2D024CBD4BC8E966C2F102C6C02CEAABA0F92874179C8777F937D9A3CB74920BEFE6A759CC94DA0A3ADE2D739D43A99E1F06A0D6A41AAC076CA70171BD697F1CB16A3B481EABB2269B57D36599F3B734BCECAABF6D5835E365DF0261C5C11B8B5314E08EB209A8938B9AA6566E159E2472D97553972DAC5B83292EA350AE358C60FA7773B5C1AF64891C72643CBF8085176A05CB47577E50FA6D42E96C5A465E05C7DB75BE4262A7AA58090585A62363B6C989B8274C426802DE1F90F4586A2A7444812451655F63852C48D2745BCC5D95C15552CA7355A216B1B5131656A95453A854DA8291046A05D96E74CC4507D31973D9606171D8405F211AC5040658411A3997CA061C3AD30EC2AE6CC79CD4C9AB1D1CB47996F02E42BD8819F62457CA5CB9923C570FC749531C61AEF02642576A04E88493AB084AFB353FC0B032AE8AEA812373A323268200FA820C88E1881F0A0CED7D9601DF56C891AC2CF6B299C553C6B1C8A470B68CFF347C2A071B26557F185B4E2138B421A9BB6DAB8FB41C5459644F08614E63C8C4BACC3DF5AB7F86C44E48239EF387217C9540DFB50002C08ED9CB631755446786D4B5BC14D16C5EF629CE2916687C40053A2CD50667CBB590F7D3A2AFD54AECBD6211C84739AB75B80A38E9F27B6D6F1BD4C838BB2706E5DA65B95498CFA61AB90169A2C06B0E79CBAE0051683221C98DA365A27C1DE417666ACCA178717934258207A51DFFA0C926B6E3DA5B084F07560D949AD615724C306EF1165A5B9616FBA84C7D71C1117BBF8296722012EFE25B29C63291D31758278430CD90E844764AC252F33135CD2137115933B38F4160FD482CBD9265C27AC3B6582FC201DEB7A52D23AA5B77BCE9B7C6D699655105B9883830D0171882612212272261A0CC9DDCBC7D3439FF3A01B0BD4B63972263D919BCC9B95018114A11BABECEA27A5BCA3DB896AA49543CC50BC07039D31135BE1354B6A2B6B4375513010CAE856B7AEF64BCE20912432C09FD18905200249D4CC250306C341CB837A96F2B67422B63C29FB8887A962A1F743F3D01795D34E277343E7577878F5A3EC02728E9238D56B2115F680AFC70BBB361B60C10FF7F4094FE240089577D59969907B9192097CC05516A7132C2477435C8BC01909B4AAE5537CA2C6AC79806B6B5F32FB688C609200F16279D9CA987B68EA83A6D6309F1230562196BA93767DF126C98E4C3A3A0BB969629BCCDCB428A333D2B96E50B814716A5479192DCC0C0E4B194AED6A169E5074EF977F689528C997C1B99B02E1B18794B56993743456214064F80CCDA66B71BC009772784AF04FB7F468E2E93E03C18778D13C72FA149C50C1C9F45167A53E09657B50BA2A19B31FA95C5C6550B14F9B931EB51C37890C95157DF4F974E3A167DC005481F945D23780B5498AC5AB80DD8ACCF2D1322D3253B9450EDA3C3B365C9EDC4A87D089AF7797B01BE716917842A4E99CE04C86A9F172062C473C203A328C10DF171FB10C97BA6B8E71271D705110C810843D658B15F2040B385B067B1CE160A4205CBD57B74926143609979F6A888EBBECB7703498A278AE963223A8AA41916A3D37D949A3E298F01CCD36A5B6E0BA9CFF38BB890AB18869B4FB7CA8C1711798CAAB2EAC01ABA26A060266A6A91BA877603E650F7D15C24F9B23C52A9C74F43150E3A1D5D25BD0326724A42572C32944DA713457CB36B14E30F72761480035423810D83721A97505668F11EB26285A1709321A1C8016DB8BB085996D1A4880BD3B1D8BF2754F3781D57BBDE68297AF710188486EB6D4AF7DE411D36787E4D945E33C45CDE051601243A1F7028AD52B3B5C7728F35DD5F8994D4B8D9FA767611A1ADEE8B38C5A7A0AA795D0A970C749A06DCE6CF1C8ED19D1F7E9F1F25538877CCEC133881C652489A84F94804166E5248CD311286D6DD03E010391D90D76044BF498B53C9D8202A9EB643527395AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F" - }, - { - "tcId": 29, - "deferred": false, - "z": "7CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF", - "d": "BBF7574CF5F32BE49E1F39CE33870D9D6384056D60D223003B6B0C10D5C42180", - "ek": "602389F7CA3437B9197677CB9E9704A2BB73A7815EC1047D8D63A55CE1184EFBBBA3F701CB0C3D0D18B757BA23C6023B4D34964B66107C92C5E0AA577FB93F31FB9A73786E63E7CA4DA84215F6B05A883C19F8B0D0326025A41A98D056B70A18E6E6469EC63C80BA0B7EE330B89314838883BFA75F2C6155BAA1922FD446235CA76A634EF715776D3AA3728482C5F69931DA1FA0A406D75756D025C08DAA28EB2A226AC56988F68B54E3205C1B341528374B9B9BF07BA42BAAC34219597FDC66156155DED5A7C3F386103BB0EDA1CB1D4258CE1A971447075CAC2AF538A96F1C570014341624607A3C36BB4771DC99916EACCC04268D25DB95DC20B041B394FAB543118B74536187EA32BA1680B006652AEFFA9338FA00BC099846419630D38CE7D726C5CC84CEB9C154E9B309B6A99BC142CBD6B210408455704A3A644ABF7768E6E87B54734C1CD0C139B2292C612DDAD0AAFB239CDAB80629B91AD9585DA88A84857249E68595C0564F2A07735A76C1CAE64D28D14A191A9F0CFB709E216AF6CCC0654AC206B722A2E84BE8A0C13BA359BB1B741F191F076A7B27849D2DC146CD8456FB165157A2ADF2A45FC5647FD5213E8A105084138CF29A583A0B5BFEB0A523798085F2AC8A44745BD556D7C0959EC319563077F5D5137E8B7E9743115D390BFFB91DADDB0DA4A21433B963A15933FAE236A537837CD056F4145EEB7872E8153E0BA9702C7A20598481C630206EC359C5145BF123A18054AF7D6851B59707B010A0BC322D3E3CB0F0BBA619C0CCB5239A5D7B021007211024868DF03B4729578F029EA7DB1CE62C15F1843C16469AD144C805B5C217FB18CFC49CBEB80BDB9CCACCB181153C377997C509B6606DB808F04911FCC4CF1902035DC3016F64498C13AF1BA2C240C6567E5520FDF79A5A04634439641DD2672BA04B11931CCDD3629D860B9EC767C3AA4C9E09BE25A7752B64087B0A973E6B3278E66E89F4BCCBF3090A729467A88FA0AB1A6805C7ED45678E71BA79A85F267771E456B2D56627AD66C7CB07B8D73A69A2682C79B1C13986C07FC7986C7C3C84EA4B6A6C1691675912B2064E3598C32573B6B87E67B006E2F312F15A5AF4E237345468756390DB585514302A80746E985A104C43BA019C5DDA678047C6A48CA36A51CB3A333767BC35CA31B59CCD64A2C59AC884A8B1FB396FCD42C63057663E8A1F809709AE89AC805277E1151B92DB4F0E52923BBC093B7C6D15621D2BEC2C8DB77F25F86A62646C54C114BA03CC6154397127A033D402248383FAA8BD1980C93E123B57075633B6B643941B417890B1AA810C88461E60413264612B890FA83115D22041243C47263B57CB32BD84D839B9CB96E3777E2DC616D8ECCD1BB21D4AB00C83D4B4298A671CCC1FDDFC3E4DBAB48F1B8045D3991B3952D4799B7E1C3D31B74F9B619BF17016D143B16E593F64C08A71078C83B197BD530063D026367993E8C35305D211C2E321ACC889FC6917F70A33EC2AC4D7FA448A79A89B531BE89A59CDB8212E7715144721613619ABA2CC7E53A3D3F84908C09B26320FA3C1CC9D840F21851139236C7CECBB8B3C2681DC145AACC13B4BBB15560793364387A0CFC97C0312351F420A0892084CACAFEA4241305B12C78DF29F2FC5FFEE800216C1DDF275", - "dk": "7BAC37F9C7AC728C78DE12B13C0A2C1B522A837416529A93273A4A14007BADC7BBFAF03EB90A7CE4E8B87B70986806C9DDC9BFFAD06D51C081E8866E7624A373E87E8BE1A60A861650346296F8B89C7A0EC713CA9A0B9BBDBA370104A414C02DE8445B9F4314D4902EBB400226A827DFC6603812178786BB1D6A9CFD048A45B4A160333D73E344497BC526D262EB73AA9D3456375A9F237B004B2414171C6BE0F02A97E83B1F8C411FE350D9B51D42D11BB7A34F8C59AFAD18722B17B21C5253389A98B2A96E5BD798AD10AF6F27950F64638080C7F0284545BA6E2BD93BB141CA924966735C7383631EEBEBC1BFEA7160FC60C143C9359A43C3A03429D663196B723CD35FF4C465B356A77A7C5FA9408E91E08BB6F141F1A9B93B4452843873F5958AC7AB9C8A660BEE218598D09652F921E8980449A8087857B129B02A38FC664F0C21B4E95E3B400AF4B30EAF649B9C968C0AA5B2FF8781F8D01534FA5FCECA771B2A2ADD27710DB25402E94F66D37D52780E25E4317FF80F0C682641301015D7900A312C9643B336AC53C94889342B09138689E8BBA191700791197B0F804BD834064CB3446C9382E6839F25087F5DFC1C741B91A8FAA87E529E375A0CA9B424C429BBF0B6CC7027123EC211A9A5622611536290A0E30A50CBC567D08245B54224133923AE399EEE6454E858352333164510A8A510289F56B073ABAF82F5986BC52778A86253BB96E357AB4F78A7C3159DAD184B8B540BE1DB861FA1951C0C59526305FF005D741B2A312B586D75B72A6B31DE68A07DE4CFF0490A85009442390FB5F45F70F5AE3E286B20C35F55DC39DF6C7CFD992A3203718A58C2D849CFA78C4F9FB20D68E8A7B35065D3DA738F01C6986600677325AD146816137221E3C47B9376A3669CCB23A533A85B1028865BB4A99361486E789C0C42C3D36831D5E86278B48B2EF8042FAA2491B413FDD9AAC2493F44686A649BA866D30F887580857B7159161D1D009920033F9EEA92E37267CA936D0823A8CA195458731DBE45B25F46584268787D664FB7587AF4B67291255C66157CE7646B2F4B5015D75D5332C9E95470F52A9D8EB5438A390BD7254924D46C583A7892D53D42E9406E0A6063121A03F0A550F4AE2E8042D962A3AB69B223C37071F1BDD2BB1639D34041D1BFC2576B268ACDA311A5E0222DDFBC5D67A77EA0C37C90B474317195D567351280AB0E5840A3F60EA9C5162A706550877430F6882A68006A683A90B38F26C90D3FCC780C0CC7E6E88FEA5A02D912A1C485667F88AB329552A93837858235E98044A28A24E1F71435E09DE2AC2744BA2E116A136E95AED53BB906BB46FA214E218A815966214F581C1134545DD05EE4E9495AD172CB2BB199D79328E06A45A42A4EF37443EC6F57631D0959B84A1B169297A0F2DC16B13B1C43567C043237AB18BD53A8898F6ABCB0F8A012E2CE203649C4286C6D3C41346599E953B6899712D4B86BFC4B54A89B061E93B423793CDD798E6E5A1BFFD565245788B0BA6A0FA3BDD97960C9CB0A10DA892D829925FA4F85CC8FF895500933BB78B3993CC04006819FC93224D19A02E11651E5D3AB3CFA6DC1C206F6516A5CD5108D18B47960A6602389F7CA3437B9197677CB9E9704A2BB73A7815EC1047D8D63A55CE1184EFBBBA3F701CB0C3D0D18B757BA23C6023B4D34964B66107C92C5E0AA577FB93F31FB9A73786E63E7CA4DA84215F6B05A883C19F8B0D0326025A41A98D056B70A18E6E6469EC63C80BA0B7EE330B89314838883BFA75F2C6155BAA1922FD446235CA76A634EF715776D3AA3728482C5F69931DA1FA0A406D75756D025C08DAA28EB2A226AC56988F68B54E3205C1B341528374B9B9BF07BA42BAAC34219597FDC66156155DED5A7C3F386103BB0EDA1CB1D4258CE1A971447075CAC2AF538A96F1C570014341624607A3C36BB4771DC99916EACCC04268D25DB95DC20B041B394FAB543118B74536187EA32BA1680B006652AEFFA9338FA00BC099846419630D38CE7D726C5CC84CEB9C154E9B309B6A99BC142CBD6B210408455704A3A644ABF7768E6E87B54734C1CD0C139B2292C612DDAD0AAFB239CDAB80629B91AD9585DA88A84857249E68595C0564F2A07735A76C1CAE64D28D14A191A9F0CFB709E216AF6CCC0654AC206B722A2E84BE8A0C13BA359BB1B741F191F076A7B27849D2DC146CD8456FB165157A2ADF2A45FC5647FD5213E8A105084138CF29A583A0B5BFEB0A523798085F2AC8A44745BD556D7C0959EC319563077F5D5137E8B7E9743115D390BFFB91DADDB0DA4A21433B963A15933FAE236A537837CD056F4145EEB7872E8153E0BA9702C7A20598481C630206EC359C5145BF123A18054AF7D6851B59707B010A0BC322D3E3CB0F0BBA619C0CCB5239A5D7B021007211024868DF03B4729578F029EA7DB1CE62C15F1843C16469AD144C805B5C217FB18CFC49CBEB80BDB9CCACCB181153C377997C509B6606DB808F04911FCC4CF1902035DC3016F64498C13AF1BA2C240C6567E5520FDF79A5A04634439641DD2672BA04B11931CCDD3629D860B9EC767C3AA4C9E09BE25A7752B64087B0A973E6B3278E66E89F4BCCBF3090A729467A88FA0AB1A6805C7ED45678E71BA79A85F267771E456B2D56627AD66C7CB07B8D73A69A2682C79B1C13986C07FC7986C7C3C84EA4B6A6C1691675912B2064E3598C32573B6B87E67B006E2F312F15A5AF4E237345468756390DB585514302A80746E985A104C43BA019C5DDA678047C6A48CA36A51CB3A333767BC35CA31B59CCD64A2C59AC884A8B1FB396FCD42C63057663E8A1F809709AE89AC805277E1151B92DB4F0E52923BBC093B7C6D15621D2BEC2C8DB77F25F86A62646C54C114BA03CC6154397127A033D402248383FAA8BD1980C93E123B57075633B6B643941B417890B1AA810C88461E60413264612B890FA83115D22041243C47263B57CB32BD84D839B9CB96E3777E2DC616D8ECCD1BB21D4AB00C83D4B4298A671CCC1FDDFC3E4DBAB48F1B8045D3991B3952D4799B7E1C3D31B74F9B619BF17016D143B16E593F64C08A71078C83B197BD530063D026367993E8C35305D211C2E321ACC889FC6917F70A33EC2AC4D7FA448A79A89B531BE89A59CDB8212E7715144721613619ABA2CC7E53A3D3F84908C09B26320FA3C1CC9D840F21851139236C7CECBB8B3C2681DC145AACC13B4BBB15560793364387A0CFC97C0312351F420A0892084CACAFEA4241305B12C78DF29F2FC5FFEE800216C1DDF275A918B39F71BBB2C10DB35639E5FD2CE621868CC02149E029EB47899407D963007CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF" - }, - { - "tcId": 30, - "deferred": false, - "z": "C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D", - "d": "D12CD9B65B7C58B2195AE0BE0282527BAC06C2D25CB0472628D64715F7F6A378", - "ek": "C85428E8EA5D6D1C7E544703372498F68311C32BBC70B86F2A805FC94089A0421AD680053D5BB139EB95652ABA561B07B9C2639AC693972070F351A3FB6138FEE0A73BF63161B604D7DC0334D6C631BA25F584952045C6CB74A31581B866EB5FB69503A5E3C6F96652547968626CC9C6ACCFE9582778E928235305CC5447661A64363A9FB3CB3720868812B2A3F5E7820DDAA8BC799566773BB62B769A8C54E6B533803A48D877706303A76BA2188EA4900155728DF29E7AF050F8CA9F92B65ED59988496419070B0CD8E964B402491D134F59EB2E3995C1B3B654EA7A5628C677858208A7958C57C7CCC697677BC65091015AF9D6C688E234DEB528608A1AAF35C2CB2A14593376E1417098778439D9BD6EB31BC0B53F277BC6763794CFEB8766957F6B206D439BCDCE4466BE20B74F7A117D7102F4A2CC93B098795146CD2903D131315EB41E0DDBA6B562B8341753DBA98D1ED288D8F33148814847981C735600AF76BFD0B964521A8B3122B3B90BA8228B1C4C834C808550D7780BB33218F155752DD15713F5A32057C42313A6FF5BABD6AAA1F6F5460C774CB83C6EC16C84D4A5B8EF728E58E8B34D7C090692B73DB64BB02AC365800915D78A9452158FA210C99B608DA053F574AFFAF1A49AAA92B3058468346D9D5A6DA97A9269B4713AE17A214921AE76A90EFC5A4AE90147E154A562C1C96598DF670EEED86EB946C9B45460C63A1339BCBE23B4332A32C02A028A892478070624D35C950AC84ED7D1B5640A70A3A45BB47C39EC181F7C8039929003D4D674DE3C5C89B0678CF3B125C864E95439C20AAABD015AA52BB3C27316188A673785CF2C0C77CAAC7604439A69B46005EC646C37C510FA835CBB36C162AB7C944F8228A4FF32340C3C63FFA3CBC48C7E01D35A6DD010E211C21175171237067A614CBCF7B18CF98ED0E8B88B58555D871564B0B71B75B5D078428EE87E0379A23822BC34C00A5661602C4006BF5CA667780E81F1759CD63E6BE63CC6C07ECF44C2E11346E376733D185A281C8648A9B951E14308D7A55A0717BB5C9C3CD5C7D88636873453D6148E674093A406860028AB50FAC90349C5BBFC2A7B6A18E24655DE541356990BA1C7C465630475176A03D58059F26700CBC383A0750F5271B8D5BDD74468E98C189FE302A5A452D2E47340C2B04A0275B47229B2022198F14E674071C6568EB428B0C0748CAA0A2F8BC28FD27862687B452989B034072B69381CF73BA00F7B7C401C699BE466593918EA96C79A3980023B299595179065198F93C6D6456DD53B586E6079340952C1314A140605DD34126291396AD22F2C7820A4AC793768707E071772EA587FFB9AEB234ED7A250DB40A1DD7A3869104864392B6DFA23013C8CF8856EC8E30C0AAA748351284F67A0E3469D3CF7C28A85BAA2630907B70F7C31870E8A29DC7B908CA880BC03C3CD2CC7A57A9D48A238667776B6D9C77247ABEA49B0F6935AA9446F0F2CADCC7A809B651DB55131A7B662CE428EF89109BB33C4E423B05781C42BFB4514092D35BA6D8E77B71F6627C9D91EB3672E656A00EF64CA7551667882444DA47FEE440B0E59755FB33039FACF337CC572D7CBACD680CB882ABEB86D9A3937FF76EFAF15E6AD37597C50B3153DC8B18625508393935D2FBD49D32ECF", - "dk": "9FC4A82AB21F667A50692A482D59A06FF2620ACCAB62394DEDC7AA452761F38A5A499C8091498FD7A5910C1A14324685B9307236CC0773D98B36EB2136708DAEB21F8D4B713CA5456A02C1C8EC012514AE3FF6476D1C3D8D47638AB79AB83433B6592E2F1690BED646C0519EAD1CC58779786B384618604B1AD1340E178FD97A8B3EE4B009A5BA115CBC3832B92ADBA22BBA7823976683B8A4469A3BDEDB8FEF5C3582A5984CEB2CBF5A57C96B246D05BA21F08B8582CDB5632DFFB404C320A004E878E31B877C07B38B7A12142A5628D2BA4CA6680C9B9A6CF18B3B4673962533D7C503A24C0A91EC9E1F75219E573DF630724393A18A61178623224B9C4892F6A41657175D296634474F1C3BBD76E05B9C5788B9857655D142BBD8137F047A4927B923163493FB31EA5C151A4719ABD61634F8A8856A968C7538E2641D5B79CDC78971ADE70AF4F85B09770EA4E05642CBCF02F095A9149DD266809DE0911A5481CA22176BC9B0C5A7066A00434B15AFFF5C532E1042BDA52D425CA202A599D96A92D58B7B40F8A76EA34C6B45B76E6C07FA9CA20B3587DED93E94160AB0412697DAC2591530620242A9B41F37B11CE1347075271091B78EAC2221DD735DEED8189C0029099526E9DA24F234BBB423C590CC44C675AF125B021951576F5953CBD45B8F6326CA9399D3127EB430AA31F2C5154768A7E440F63738419834F41AB4A149278DE5882506085943BB6D19088FC11525973ED9132238A350F201479D9469CBB46117E7B74C0298B5E785F27384A4984452868BF5056D9A966D844ACD946073AE275D7F82C4583C08AE33499CC53D4437C3EF967F6C904B75F503330C4B19981B28CA8F26CB9F5604081B8706E657CB8E9431466CA0EBF1B71828A3238578BC2B38620C3416E84B3058174716A312C205ACFC481871588C37263B6839768C5CA575CF15058C52F39379B79D814788C19034EA17BE4969255EE767578B0B6B347FA9A52D199891B9976A7345B93C659CBD7814F5F300900581674BAB7D03585E802C8AEA7CAD748F5065039788B76813C7F991A642C44EB1F151C6A3BD96C4331F2C01EEC46A3A1BC30555BA7F2C9316F4CC7D18C9CB73962A71CD0EF32B121393041684CFE692D4834FD0B25CB0A04531E656706A7D593AA1D0FC56FA304CCA3B5BB3233E7B141B6AD1C448C35268C99815E451C2B821F034CEEBD748A72625F61B610E478099F6CCCD39BA2A050611894D5524257D9A06D3BA2BE2AC70EDE8717BF593FC159F8433CA0C54420453610DF451C4736512702A95B2B0FA5AB1B4CC3FA74B974A1354F8B2BEE35187BF049D0A8772BCC85443B04303051415324523DC1FD494268E172383F7570D366570DAC588A73FCE3104921B325E45A87BE798683A6C2D0C90A869BB2B4BBC332B7687C81A287853F7C06F596271F5596FDE93BEBA027977C788F472C114C889BA4C4D3F39C7A05A34E57A8D5C4C10A19C3A3BAB1711FBA07854824305AE9D46A6DD11331656C4267C20B511B6672C0CBBCB2D5B67973239B116035BF38C9BED8186762201CE295A5473A825C6210B70A70CC5C5E235384908104278AFE955628D80B43F13BE383A42BDEA6D05EA7CC85428E8EA5D6D1C7E544703372498F68311C32BBC70B86F2A805FC94089A0421AD680053D5BB139EB95652ABA561B07B9C2639AC693972070F351A3FB6138FEE0A73BF63161B604D7DC0334D6C631BA25F584952045C6CB74A31581B866EB5FB69503A5E3C6F96652547968626CC9C6ACCFE9582778E928235305CC5447661A64363A9FB3CB3720868812B2A3F5E7820DDAA8BC799566773BB62B769A8C54E6B533803A48D877706303A76BA2188EA4900155728DF29E7AF050F8CA9F92B65ED59988496419070B0CD8E964B402491D134F59EB2E3995C1B3B654EA7A5628C677858208A7958C57C7CCC697677BC65091015AF9D6C688E234DEB528608A1AAF35C2CB2A14593376E1417098778439D9BD6EB31BC0B53F277BC6763794CFEB8766957F6B206D439BCDCE4466BE20B74F7A117D7102F4A2CC93B098795146CD2903D131315EB41E0DDBA6B562B8341753DBA98D1ED288D8F33148814847981C735600AF76BFD0B964521A8B3122B3B90BA8228B1C4C834C808550D7780BB33218F155752DD15713F5A32057C42313A6FF5BABD6AAA1F6F5460C774CB83C6EC16C84D4A5B8EF728E58E8B34D7C090692B73DB64BB02AC365800915D78A9452158FA210C99B608DA053F574AFFAF1A49AAA92B3058468346D9D5A6DA97A9269B4713AE17A214921AE76A90EFC5A4AE90147E154A562C1C96598DF670EEED86EB946C9B45460C63A1339BCBE23B4332A32C02A028A892478070624D35C950AC84ED7D1B5640A70A3A45BB47C39EC181F7C8039929003D4D674DE3C5C89B0678CF3B125C864E95439C20AAABD015AA52BB3C27316188A673785CF2C0C77CAAC7604439A69B46005EC646C37C510FA835CBB36C162AB7C944F8228A4FF32340C3C63FFA3CBC48C7E01D35A6DD010E211C21175171237067A614CBCF7B18CF98ED0E8B88B58555D871564B0B71B75B5D078428EE87E0379A23822BC34C00A5661602C4006BF5CA667780E81F1759CD63E6BE63CC6C07ECF44C2E11346E376733D185A281C8648A9B951E14308D7A55A0717BB5C9C3CD5C7D88636873453D6148E674093A406860028AB50FAC90349C5BBFC2A7B6A18E24655DE541356990BA1C7C465630475176A03D58059F26700CBC383A0750F5271B8D5BDD74468E98C189FE302A5A452D2E47340C2B04A0275B47229B2022198F14E674071C6568EB428B0C0748CAA0A2F8BC28FD27862687B452989B034072B69381CF73BA00F7B7C401C699BE466593918EA96C79A3980023B299595179065198F93C6D6456DD53B586E6079340952C1314A140605DD34126291396AD22F2C7820A4AC793768707E071772EA587FFB9AEB234ED7A250DB40A1DD7A3869104864392B6DFA23013C8CF8856EC8E30C0AAA748351284F67A0E3469D3CF7C28A85BAA2630907B70F7C31870E8A29DC7B908CA880BC03C3CD2CC7A57A9D48A238667776B6D9C77247ABEA49B0F6935AA9446F0F2CADCC7A809B651DB55131A7B662CE428EF89109BB33C4E423B05781C42BFB4514092D35BA6D8E77B71F6627C9D91EB3672E656A00EF64CA7551667882444DA47FEE440B0E59755FB33039FACF337CC572D7CBACD680CB882ABEB86D9A3937FF76EFAF15E6AD37597C50B3153DC8B18625508393935D2FBD49D32ECFC86A41EFD315191F24D2E6BDD87433D5133D6734FBEAA9DA8043D91950000048C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D" - }, - { - "tcId": 31, - "deferred": false, - "z": "E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD", - "d": "79C006D5470C229AFCE7588546E52204B09F5086974865B426AAAA198C6CBA7A", - "ek": "52764F398C4AED89848544114193553BB178FBFCA4883C76BE23363B3343F69C8AF0B59F7C0482A64985B50A6EEA5C700CE7BF31DAC43B82372405638010A320E2A28FE6321C0AB85BFA8723DB96E8D1508900996B27812507885C97A1E7C581E35915D0709C9CFB2BC713B305705406C522D0305F5BE51EB3272524A797ECC2AB5330538BCCA62CD51937330849138620032917ACC188E8B70DE56B43E812EF030C0B4C062B1437AAE13A355AA9B41B00EDF4151F2C964FD332F3014BEB990E19C2350050735C7B02C0936B6BD37CA18114854750E32A6790515E1B4A31B2B71F9DE4082C225679CB220522BA6235B89F2C8E231BCFC815B9EBB15534D5B352566942A742AB405194AA74B90B26B98B669DA43FEC232FCF351FA5C50F812057E44858096395CE67AEE48382063A7928CB4904D623C56974FAFBA18519BAB743168510700F715E07EB331050C4160A6AA024C126027D11C324A87BA13C3CB10E86B2212343BD0088382769B9494F769918DA7C8EED21896C75711AA34B0E3BA8527371271AAEA05C906C5CAF6B5A6A08C4998492323E04CD5E63B1857A4FA972BF8B430036A856A5F9183C4B652A9311F1901AE3A4A93D302C4E77282B04046F7AC2DF2333C21B343ADB75C369A5385B9CC70280858971716A0587B74492637DECC8130EC8418954763E39AE47BBB084103225C21F64D94F14D55B9BD2579C5BB03EE4915016C2CA416806CCCD56061F92C0B1EAEA50DBA36B76798F7B8AA8AFF2CC06B04BC3106F22845DC5D847B5D444F05803CBF062DE581E12163094A5C7131A24B9327DAFF9134F32B647D9CA52A65A91A4899D64100F3376E0D318C7B8188BFA88654AC370EB5D693C4D9D481CAA98A2C99C168A0306261165410B32A53BBBBA412B54702476101C6550C286D6615AA98D8FD95ECD88BF45CA383DB3C6239AC7AC16606877751311CE8B447D0F6B9499943706B5A46F291A57302FA4F3ACD4645DBB515868371FD79887636737E333C9B06285508832401107089176E06A2F17E19E4FF61623603E17367D33F023C2CC820961A6E3500092CA3B900BAD66C179249C75A5E08A5563BE1CE312ECDC0AD370518F66594314CF5C8BCA20948D54C70F800542BD5B64ACC9AB68FC90F48662CFFC8F801C06DE972571E8C25EBA7128E95C13011EF88240C2C9C0BA555AA1C70956C9621A600F2817435C09C75F8A08CEF2C5D31C5C5834A745249CEB7641E6B19E404865EB374507DB3394A77A0F47149896AF1C747F86C97201D8C1CC8209E571B8C4D6972ECB1CA930B15516922FF08BF0C942AB5C5D197669AF94457FC9BA5BB47DDBD3A34EE941943B0B262A63FD0922D803CA035C6C54DB71B5A5A76F46C787036BEF777296E80664F73A78175EF7DB567BDB6CD8D97D27649661C76216D99D6264A7EB274C507AA170E1C3F23CA00A04B861AAA29EC33D4584B12985AC3B36689F129F3D29B19DAA5DCE4150162A10FA835E1D89A21FE10E4B1489E457C415961648044774C49DE6908201068D13463F1A999D3103342F03020F043DF3CC2E897B8293D235E8B408F2BAB266CCB0FCE19F6779A9C7DC89E368B07BF56F29911593E78009358CEA0BA304C0C074FC86A0782F99BC38571CD1632770CBEA199AF4181984FD05FF371931", - "dk": "B9C74FBF945530C8B3F846A803ABA28337B79D4B282B127D727A145BD77C19D980ACF4A5B20A09D770BC96F9A32EC16ECC208126D0C755C334BFE36E0AA3B968D0BD9EB80FA4953C9B843AABC828BB044DE62AC903D655C5960F45A4133CEA1AE6C4A09D431B43B19511631483E457C9108D7F3AB090203F712BA759602FED0A68BB7C8B10DB592DC38606978C56198B7F3062A200B03FE281FF95A27ED48C630CC1699423F5C6A07F850F2280101178CA24C282A7455FAC19869B207C46540AA0E4628246777CEB02B24ABC1BFA02326B846D7A20A7E642116B97AE68219AC53712A0077E325B4677AD163A38A6B8754DA8957C52B6CA5905C43131467B86F2CB1B94891A88B79058D6C6D8DCBB2C167156DC81C59B60F66C16938935DCA2BBB80084484B1F11330B5010C2F6C5AADF352D2E5421BD5B8A77758B72A058A0A6074B3C08A9A2B0EFB7261CE38219542CA7759FABFAA924721D7EC8C11EB62976EAB8202AAF0BC082370A47735B0931CAB5D6A92F8A67184DC906856946004B991394C7F1F1B84A4C0BF3F249B73747732AC3F04C5FD94B33FFD8250AE4739FA04233B6C381F69A3B0AC7E0003613329FEF9A63F033CDD09137BE13BA7EF42F36342A1C215A5FF4AA76D044C0AAB7ACD7064BB064C9B66BD7E2C398404AF7164FD0169BC8DB926BF63DD0E2433C7C17854A7E538722E74118CACA4621A532B2FC8DD0E204DBD01B8B3C7AD1A5BC78E78E8C1265BDACB7C78A62A3E10EB7BC3E7FD25ED8827C23428E3A198CB4821B0EEA62C9154F6D305D00BD7BCA42A1BD488AC4412D39B1573ED978EB912CAB796A594C5E9AE6AE7C94C76BE61DD47354163A7E4063B8A592C91A8A6B34451AD400672603C60DDB26F1B0587BE2065362006372081C1A52110774EE4A0231842AC6E7B4345B47C6A5C42D3C2C951014A7B753A90345B0692C8A73A82D8B01589C3CEEC8ABA357931E18026604576141ABE253CA18C356757A9D0BD49C1FC1CD90364D7430B061DCAB362257F80405D35184282C8861613D6EAC28F1360B1888192B25719D7A3ADE28AB76FBAEC4DC35DE5B5CACD64A66A39824993F2FF7783CB339319998AA102369F43E841666CB41CF0D39B998267356DCAC4F0933E5E56CBD920FC56AC33BA82E80FB13C6C64932C65EC4C66E903859C4F20D1AB5825FA8322CDB41F4341811D7663A6397363212DED05DA0D76EB5308D32F4442A488665DA80F54ACD37C406FD44AAA56CB31781AD393171DD539727C6582594BFA278BD2729A9150B916A8CAE861153DEC3493E18277A766019CB556882266521536EF030BCA36115753E08762142B33C5E34A9E80716C57A03BB362F9334AC44744EBA711AD8F44C2EBC151976C49F179D24B53C30615BB42CBE8CE069714A9447D939DCBC128126C1F9AB35C222386D894B6ED50A580B3ED13ACAA18C8D49F5A5826A9D1B6530100702E2C9993C3AC5C9286AF6324EC9B8323C032884B344EAC49F21D76323DA9FCB324E8DD7AFCEE162AC14BB427C0197C4AB9AE490434586EA76AD9AA042A060973F301F5E9BC91072B61FBC27033C52DD160D424CCA566558242C9E4B145C7B5630AC825ED5B932A00381C5C94752764F398C4AED89848544114193553BB178FBFCA4883C76BE23363B3343F69C8AF0B59F7C0482A64985B50A6EEA5C700CE7BF31DAC43B82372405638010A320E2A28FE6321C0AB85BFA8723DB96E8D1508900996B27812507885C97A1E7C581E35915D0709C9CFB2BC713B305705406C522D0305F5BE51EB3272524A797ECC2AB5330538BCCA62CD51937330849138620032917ACC188E8B70DE56B43E812EF030C0B4C062B1437AAE13A355AA9B41B00EDF4151F2C964FD332F3014BEB990E19C2350050735C7B02C0936B6BD37CA18114854750E32A6790515E1B4A31B2B71F9DE4082C225679CB220522BA6235B89F2C8E231BCFC815B9EBB15534D5B352566942A742AB405194AA74B90B26B98B669DA43FEC232FCF351FA5C50F812057E44858096395CE67AEE48382063A7928CB4904D623C56974FAFBA18519BAB743168510700F715E07EB331050C4160A6AA024C126027D11C324A87BA13C3CB10E86B2212343BD0088382769B9494F769918DA7C8EED21896C75711AA34B0E3BA8527371271AAEA05C906C5CAF6B5A6A08C4998492323E04CD5E63B1857A4FA972BF8B430036A856A5F9183C4B652A9311F1901AE3A4A93D302C4E77282B04046F7AC2DF2333C21B343ADB75C369A5385B9CC70280858971716A0587B74492637DECC8130EC8418954763E39AE47BBB084103225C21F64D94F14D55B9BD2579C5BB03EE4915016C2CA416806CCCD56061F92C0B1EAEA50DBA36B76798F7B8AA8AFF2CC06B04BC3106F22845DC5D847B5D444F05803CBF062DE581E12163094A5C7131A24B9327DAFF9134F32B647D9CA52A65A91A4899D64100F3376E0D318C7B8188BFA88654AC370EB5D693C4D9D481CAA98A2C99C168A0306261165410B32A53BBBBA412B54702476101C6550C286D6615AA98D8FD95ECD88BF45CA383DB3C6239AC7AC16606877751311CE8B447D0F6B9499943706B5A46F291A57302FA4F3ACD4645DBB515868371FD79887636737E333C9B06285508832401107089176E06A2F17E19E4FF61623603E17367D33F023C2CC820961A6E3500092CA3B900BAD66C179249C75A5E08A5563BE1CE312ECDC0AD370518F66594314CF5C8BCA20948D54C70F800542BD5B64ACC9AB68FC90F48662CFFC8F801C06DE972571E8C25EBA7128E95C13011EF88240C2C9C0BA555AA1C70956C9621A600F2817435C09C75F8A08CEF2C5D31C5C5834A745249CEB7641E6B19E404865EB374507DB3394A77A0F47149896AF1C747F86C97201D8C1CC8209E571B8C4D6972ECB1CA930B15516922FF08BF0C942AB5C5D197669AF94457FC9BA5BB47DDBD3A34EE941943B0B262A63FD0922D803CA035C6C54DB71B5A5A76F46C787036BEF777296E80664F73A78175EF7DB567BDB6CD8D97D27649661C76216D99D6264A7EB274C507AA170E1C3F23CA00A04B861AAA29EC33D4584B12985AC3B36689F129F3D29B19DAA5DCE4150162A10FA835E1D89A21FE10E4B1489E457C415961648044774C49DE6908201068D13463F1A999D3103342F03020F043DF3CC2E897B8293D235E8B408F2BAB266CCB0FCE19F6779A9C7DC89E368B07BF56F29911593E78009358CEA0BA304C0C074FC86A0782F99BC38571CD1632770CBEA199AF4181984FD05FF37193132F434783F38ED277382AA17ACF5FEC87E72BEF729A63E69AF7387E9CC5BB339E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD" - }, - { - "tcId": 32, - "deferred": false, - "z": "AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED", - "d": "B04F631B330D83991B5C01E7F69452DFC394F9689632F8C7F60DBFAB92A9CEA5", - "ek": "662293FE760B0826256FA788B6A061039229502B6887527553496F09937F25C86D0762232C5A9C3CF9CE9AC7C43412295A180DAEF55C01053F71242257610F9F2AC7AD80A220991BA632B4DF1CCB43865C7469BB54A24A12D759943921B62563A1665F864C710B947C629B6AC169A05FEBA11DC87BA54420D35C9FBB364CBE5449E7B53A48B6361CF417CBB825AF93CB61D987442C500FF147B8703D6600CBC6789A83119C51D460EE759638D5302DB28B62A1950F6C63311917A51BAE092756D8DA55DDFA066E544FB7C71BD6D512D258CCB0B6B19B6693BEC15BDDD3706FEC949FD2B5AC81327A3349B62475F642927440C757266F8736B995C996DAE6685FDB89285377A38384EED54622052D197098E5D30C74D65F24B8C1F479A78037CD1936868801A7E688B9E8BB5BE333BA48540DE80AC9B12912F017961DF81CD02700CA6B30ED19325C7A507C5C1004652568F6240A060FF0316E1554168C5190DD32895B389580BCB7A1F5712EC3192B601A7FBC7F3EC9A3CA6106BD99B2800CB7E332CFB3824539801D87545711D6ABE408BE2963AA4AEBB76C9814B7808559831CFB84CB9DAA80104C51532B4867C731B53766932453E7058C23B27E7D63CF303ACD0D9A2F69B4A7B07360456A8EAA14C5142824DE66565335B589B01AE667C9CCF79EB5251A11305CF2349A8C9681A17B415F5190B602A5753B917F693B61A04B96D8C4B5AACD873B1B900B940F3C25E568C8293A679E2020C7B88F162B641891C9263116ED94C5A726078325955825CD697440729087C4D67F0CB126395C1E19824BAB9A1A1AABCC8D570CCA3BB4FF1B6F416A6E239926768657BE34B154129982006DD6B5048B2CC06679C27F070D7746870A976F1699802A61882B65B7D66736574C2A4065352F06C056703295291968237850FAAD14D56EAC4816AE5CA72BC59E04AB07FF4185B29B9B4A19970A81ABAA505FB6F4A3C1E632B2421EEA069EA40C450E3AC2435428A18C412F209509D83C69717963C62748C130E5D1CEC8A924F1E81BA852B3780B38B44AC17B3B70F4694E550B497F9A5DD740A2A7651085261A7840B52D3C95D2AAA899160A6AF7289127606A85233044B6F72C2261F3C2B89946053BA91C6120EDA024C70435B8917C1C2413324A179BE34EBA570C4C0762A8490CB76B021C2978B6237A792973EB994DF4714F230374D20C89C2E5A58E777075CC83EADB309EFA73ECF34771205B3B67C2BC848444A247D4F857D8C6679306AABAA3BD2D4A22E9B7B889574A68168B659B8F2C19560EA178BFDCC509996E8A992B2FBCBB6703478F6C3D6E3020AE0086DFE2408D56468AF66722123D6654C7BB1B246C35B9AC8C2CFDB35370D19C9FF173CD999BFC3BBCDAD053B00C941F8173D2621AEC1571DA391654FC50B9F99E51F26C5313B85E73506A0CA7D156012A63C51D228005B26FFB6427D8C279E9BC6A520ABDB38981D04A2B7ED5311F023572D57A01E3BCE0375A51FA5408C193AA80BBA033A20750C2A09521DD94B7F023271EF2A561089E170531DA641CFF4525233B93FCCA87617C685E00D0CB1317C540B770514A97279C04119436F872DE43A96747856339064794801FD00460DA5663ECDDC739C783608FA59F2E27E4AB3DEEC74061C16465780B59E4DC86", - "dk": "74996BF2C7B505FB4AB2E64D9AB83F5169CA5B062CE625184B0315D2B79945D04C818259E454099C55BE3A262B57C31EDA5B4F095169A09A8DBCA39DE41057E3CA126E4781D0503FFDDC89D24B28C3BA4BC5E9437C83A3EB8497E2956D30FCCB29AB0393EB1C1A0B7D2AE177EAF705E69A5B88726839516B096BAE87BB4FFC394FBB86967300AADB340E83CC9BDBC9830171088363BD1080A976EB9FD9A6B92C5273BD09073B8848936C8F1486AF320CA39EA592559A12B191432413C1C4977FD6DB5BB12B0DE877AB4CD63155690C31DB93B5EBBDF29B2A7E642C382478C9794AA5787B7A50CCB9850BF199798DB18861179E6020CC2FAC59925A0B6F775FB219726135237CCB90E321906314B8EAD933D7C53024733DCF076312F358EAD020A88B586DE53AF798C3A87178058207ED806AB4FBB349B953E7C13E6D2122A7C50B1EAC96803C7414DA65020A7ED62A91975BA6EE7174BE62695CA3A7AEC723CA701483B95DEED68A82DB95CE175B0F94A0160332DBE4575DB085215A9A520878FA76C6D3968A8DD9B38EF48738451417B3C835DA8B4F393ABFCA7DA6560278890C2BA8547BD71815043759B5A802130E8957398AE30BCE688CFB3B71E2A77068C88A3C42989735A180B64144817E8AE04A4DB010A3AA4FE24CC0AFC25C89266295532F4BFB89087008F7B265161410B6A72ABECA6B30921A8FF39AED231369D39D8781A7691933F12473B56683FB49CEC4A939BC221C11C11CA904647A7C2F77DBAD979080CBBB624C005488F6211CE7B9B2227A91F04749C2776E399377124FC7BAAC11215E6B75A7725417D049A94AD809711C1B78631DD7D24ED6720458914649F8B5FB6A30E3F97EDD116987655900278EC3A60C278A5132007C91416EA4AA3694A87D481B2EEB40674277783E391D5EE54110787622451D62F922A721C010921F570A095FFC00B8002DE9AC71EA7486A0DACC5CD0727DA19DAE03C9E0C6438CBA0B08F69590C83D6284C2092C2A98CA6405F9B19DEB5C52F7B5F91CB7B653688C633120FC82BB76A8A52AC0D5E68E74009F8E655A2057642A6004FAB653D6C79DFBDC3941E59921D8850399810A881BE80C974929CE9781074D50094D0A469D716B47FA72F2A3A4772A469A31284E91CFE5854F5016CF2747118280276582020D1472EAA3BED0AC192981098EC7524ABB1410A392439A7D9BF940EA19BF3E76BE94D856D5EB3F5D91A917C8886D561BA027AB7E166FDC12CFDA12C7B06AA552BC27E7B67BEE1C19E0612DA58C8CBF0A8EB2B03818D8158BFB1C09268AAB73C1D424C354C8557AC3556D3A944D203276187032771E4C668CDD1145DBF3B00393AAA19447C1FBBF5EE48DE7F07215F85D648A59B3D6602F69ADF57205DC57371CA84C1CFA4D69E32D065CA04A1BC5FFCC1FD215AE3B91936DFAB4EF9591AB18093F36CC6CF36ACC204CE517B9EE9B746E79C5D2E005F96768CB508E7FC96DD38338915C17C95C1BE072CD46A59A3D36887EC80C7B022D3A56C4E495AF71E8A40F2944AF9439241024C6496CD85942AB17359229AB2BB54A0D61301DB560F15263B0196525A2AF546C8EE2CA18F212AC8356AC4B2CB2E3FC7F9A414776A24C662293FE760B0826256FA788B6A061039229502B6887527553496F09937F25C86D0762232C5A9C3CF9CE9AC7C43412295A180DAEF55C01053F71242257610F9F2AC7AD80A220991BA632B4DF1CCB43865C7469BB54A24A12D759943921B62563A1665F864C710B947C629B6AC169A05FEBA11DC87BA54420D35C9FBB364CBE5449E7B53A48B6361CF417CBB825AF93CB61D987442C500FF147B8703D6600CBC6789A83119C51D460EE759638D5302DB28B62A1950F6C63311917A51BAE092756D8DA55DDFA066E544FB7C71BD6D512D258CCB0B6B19B6693BEC15BDDD3706FEC949FD2B5AC81327A3349B62475F642927440C757266F8736B995C996DAE6685FDB89285377A38384EED54622052D197098E5D30C74D65F24B8C1F479A78037CD1936868801A7E688B9E8BB5BE333BA48540DE80AC9B12912F017961DF81CD02700CA6B30ED19325C7A507C5C1004652568F6240A060FF0316E1554168C5190DD32895B389580BCB7A1F5712EC3192B601A7FBC7F3EC9A3CA6106BD99B2800CB7E332CFB3824539801D87545711D6ABE408BE2963AA4AEBB76C9814B7808559831CFB84CB9DAA80104C51532B4867C731B53766932453E7058C23B27E7D63CF303ACD0D9A2F69B4A7B07360456A8EAA14C5142824DE66565335B589B01AE667C9CCF79EB5251A11305CF2349A8C9681A17B415F5190B602A5753B917F693B61A04B96D8C4B5AACD873B1B900B940F3C25E568C8293A679E2020C7B88F162B641891C9263116ED94C5A726078325955825CD697440729087C4D67F0CB126395C1E19824BAB9A1A1AABCC8D570CCA3BB4FF1B6F416A6E239926768657BE34B154129982006DD6B5048B2CC06679C27F070D7746870A976F1699802A61882B65B7D66736574C2A4065352F06C056703295291968237850FAAD14D56EAC4816AE5CA72BC59E04AB07FF4185B29B9B4A19970A81ABAA505FB6F4A3C1E632B2421EEA069EA40C450E3AC2435428A18C412F209509D83C69717963C62748C130E5D1CEC8A924F1E81BA852B3780B38B44AC17B3B70F4694E550B497F9A5DD740A2A7651085261A7840B52D3C95D2AAA899160A6AF7289127606A85233044B6F72C2261F3C2B89946053BA91C6120EDA024C70435B8917C1C2413324A179BE34EBA570C4C0762A8490CB76B021C2978B6237A792973EB994DF4714F230374D20C89C2E5A58E777075CC83EADB309EFA73ECF34771205B3B67C2BC848444A247D4F857D8C6679306AABAA3BD2D4A22E9B7B889574A68168B659B8F2C19560EA178BFDCC509996E8A992B2FBCBB6703478F6C3D6E3020AE0086DFE2408D56468AF66722123D6654C7BB1B246C35B9AC8C2CFDB35370D19C9FF173CD999BFC3BBCDAD053B00C941F8173D2621AEC1571DA391654FC50B9F99E51F26C5313B85E73506A0CA7D156012A63C51D228005B26FFB6427D8C279E9BC6A520ABDB38981D04A2B7ED5311F023572D57A01E3BCE0375A51FA5408C193AA80BBA033A20750C2A09521DD94B7F023271EF2A561089E170531DA641CFF4525233B93FCCA87617C685E00D0CB1317C540B770514A97279C04119436F872DE43A96747856339064794801FD00460DA5663ECDDC739C783608FA59F2E27E4AB3DEEC74061C16465780B59E4DC8644132D7CEA4F7CB9B06AA59C4213FA6293563C4516CF033491742C389AF38643AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED" - }, - { - "tcId": 33, - "deferred": false, - "z": "6F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66", - "d": "3D63BD6C310AFCF684292E5F8E1B98CC75B5A27B21526268444144AB24AB2967", - "ek": "FF22387C34AC69033FB8CB685DF308A47B6A8C9978A152A7003B583DEB864C3C26432780D56785BB511EB2507E40BA80100A1E4FEA67A2290F26F75AAF655827E95C1624A127795D88F34927989594D228F1497CF998BBCF012ECF6156FDC63870EC49E38C29C6C35ACB89B031419A0BD835425A255400B05167758F56474D8B83466738383320E22514C69203AFF561DB2B1596C937EEB49044817949B726FDA5B46D6980F9099B17E6BBC4272F4185739A687E8171BA53497E26BBB215163FE18448F1D005E6827C2177CFA0A3CC516B48F3D1BA1484C33169963F071E13C20BEF371DD4013B1D5B0608C0C0C52241AEEB42F81B5D6BC09A6627C6846AC962328A54DA2573CB4A4D71C729A4AEC7411EACD1053B71B8D932C3AA6A759198B26516843B9C344E1A1874AA22EA88353E7C6C410121026CC75DEBA8C5E3083D83BCA0A4C3EBA5C653021AF25C6251FA486CD19AAB6A6458FA6D29C02A7FE6CB2192553193AB92857AB1141458916653432A71FA4667FAB3CD1A602AAA7294148B17C2B82F86900FF55EB4CC0A8A14940982496F417809956874077A4F256448F2B661FB0163C687CE8B08EFE14C1F4279CAF8BE239338535836FE5B12C1A8A4A9EA2BAAB732F3E36262AB028BB30EB88B7042297BF92B22757A0AB0A817DF03707892043DEB2FD8963FB369A8C76A8FFA17237EDB8CC0450B2E9726491A36FFC2B58E7C9CA803517FAC9C047C4CB056B0316C3CAB239FFAC13315A3675BE2B042938C079844F72601CB6A8353205211304DE0229A249148BA13C7E969CA28E95183863AB3F838EFA3BF9159CE989358FC1A69BE3C764C87A4FB8B1739510E7211617806ABF4C19FC48C6112F3C67AD92C342A40B7F5468A559563B2C2BBB7869B221959526B22032059F093BF3287FD652CF51C7A4233C17DE638E8C92EDB41C77ADC5ADA927BDB12A7EE2B00CB2577A6937C0EBA364F9093E8E94AA334545D1797071A85EE0BC9037B352CDA8D2D874E16B344E02894635A3B5380CDCB6674951C0399B10062429593573D39A06817E84F7D517332F92903C7CFF7651D7F1C37F648C22A872CC007BCF33A4E991CBD34069CCC6771B9582D83136F52790E74A24CC86C439AB7C5FF1088CCCB81FACAB6E1D0092D14A05DDC999AE4C006899D6FA6186940925BCB614DF83C5C95555358894A5A4ED2B1A8D8C7AF8B5C63CC917B849B4B544995635845B2F50BCADB9E25BA6AE2C10458D2C1358430A8EB27884B8EE27B6408265CD24C59F9B7B3E0CAA48D744BE36A3906F488C432634D88123A981B79A54C50237275262A5AB111FB51AFE1847C9E284A91733DE5F38C6D39A51987CDD368CB3E136D92A312F515A243F999C04495DD7B3EBB3CA1B82B3647935C77951672BC9520092D203AAD318852F93866E6F6494E695F4C7A97D035956C68B3A56C5A51298F1CB0997528376DD5CBCB5B15AA19A1A5B77B98F1355210543A0C0366F5328B2A49647021CC3246F1856847C637AF4B390B521B890C346CE5B4E3F1A51A874BA7DB1D2D8B8356BB0EDF48C9EA01177E801BFEDAB6444B4B911549BBEA1230FA6183949862A06954B04F4C9192B9EBCBA8151E20D48FA3CA8943F13734D9C4E642A7A7DD2BF360600ABD6E84E29BBA27F96C191480EB71CA68", - "dk": "33D925297A649E979A40147093E74DFFD1749917C75E088AB9800AAAD81ABEEB293FF88634706904220E90490D968C097E33A2925C251904871E78975E564606617D0228227DFC3613CA0BD6F1B6402476AFB25BC4D0AE47A2A401C95C721A04D0536E42DA76244908E8D0769D5524B1A96FC9548A7C7A2C6BAB0B081618F2C19ABC358A1DD18D96AACBAF943A4CC6A7FC316FC629A25346B82B42A746A9C4D27C951D363AC0669AB3D6368D619F17EA93DC2401DF36BDA6835DB6EB02DD211AC6927B918071DEFAB2B9F671DE554E727875746475EB886286A165749504B5919A39BBC4536C8154E5B7A9D3076E0A1F068B2C8305595ED2A1469321A7476D107273221C6C5C9A2224D4AE615991D67869674B3A5994255470BE7383C1FF636AD276B7B810794B3885C1788BDA26256DE13F8AC1179C3614ED27B0A7F220DC22425BB7B8B1A8AE2CA6057CA5BEB447042A43CC82543D43F6134E9C5DE6D52388AB9D4C746202EC759781B4AB0C684B4B270570B23078195D4233A71A451E196131EB8AF598BE86B1511DC2C85CB50D001150CA2A7A3692C7E2CA09C03A243B5B0176E9BEBD629B5F4CB599D15FCAE7A7D7F44566E0A4571740864633FACBAD195AADCDFBA9B322AFEF119436B96624AB410F764083395FCB4C81FE6616CA80CFFCD6A4CB9B35BD8557D0AC2A61AA1042B414AFB0020EE1006E593DF29A625E010C15F7A5DFBA4FE459060F90882EC91AF77181C3E32FB027AD397B8CDBF52D397654CF68B2335A3A75EC24C87852B846BC9FD07FD9D767396A5511402A1993C9AD9138FF800C6B6051A6B94DD2BB457E9883F2954980715706B07A15A186CA57A5F0F83A2CFA01D22C5AD79176C9AABCFC481B67989648000DAE714D49E6C5D9E0396339BA1C22216084BAA7B403DD998F0B9600BCF419698A2CC853CD145156FCB0C193928CC32631A2B3954AABCA05D43E1E4C2A3EE34815C8A0095102E8487A82397D2283562B19A5D88993AEF77B57886B1129B9F442986461A33293AD5B41AAFB25A8D8DC48F128B67B07C047B1CB52603082E422425059A585A7B84BC948D6B7FCA6A9E7BC17B44251343202EC892D2DB09F6EECB9483A03640C4C56B32A5B8AA44D847703C988B1C02FC02C7BCFA7642AA7C1B67B539708743517444D470F273A112EC87FB7145789744F5037095EB88015932EC4B3CE62A4314B97935CDC2F252CB839442D800816CD6AA0FEC81251F6CAF6C4A1E1A9C7CEDA798135639311ACDEC014E4BA0335A9919501C42A729E6E9556AB9BA1A1EC7D96E225159886F7C67F520305436864C9A70FE7272315A7CEEFFA6F39AA8FFEA3CEDBC8CEAB1318A64335C1C5530FFC89C0CC1D6F7905C5809E61363719F54FE7E8844D382BCA679554D368D3976206289B1A4BB987A6AD72B59CA2BC2D91A61902144065B762CDA31255119C9E19C579F4CD2A7620BCE0546565C0C82A35001900E614C62D2B7856142349B25E32CBAF0634BEB9D2B603B67019AC8FECEA9F5144782EE47E2EF823E9E646A253ADA9B8B809435C33F890B0D80A565C7FB5A19E5DCAA39E4983FC149BDC1B8477B808A5FC6379C7018134C73FA197F1E87E7443373D108AFF22387C34AC69033FB8CB685DF308A47B6A8C9978A152A7003B583DEB864C3C26432780D56785BB511EB2507E40BA80100A1E4FEA67A2290F26F75AAF655827E95C1624A127795D88F34927989594D228F1497CF998BBCF012ECF6156FDC63870EC49E38C29C6C35ACB89B031419A0BD835425A255400B05167758F56474D8B83466738383320E22514C69203AFF561DB2B1596C937EEB49044817949B726FDA5B46D6980F9099B17E6BBC4272F4185739A687E8171BA53497E26BBB215163FE18448F1D005E6827C2177CFA0A3CC516B48F3D1BA1484C33169963F071E13C20BEF371DD4013B1D5B0608C0C0C52241AEEB42F81B5D6BC09A6627C6846AC962328A54DA2573CB4A4D71C729A4AEC7411EACD1053B71B8D932C3AA6A759198B26516843B9C344E1A1874AA22EA88353E7C6C410121026CC75DEBA8C5E3083D83BCA0A4C3EBA5C653021AF25C6251FA486CD19AAB6A6458FA6D29C02A7FE6CB2192553193AB92857AB1141458916653432A71FA4667FAB3CD1A602AAA7294148B17C2B82F86900FF55EB4CC0A8A14940982496F417809956874077A4F256448F2B661FB0163C687CE8B08EFE14C1F4279CAF8BE239338535836FE5B12C1A8A4A9EA2BAAB732F3E36262AB028BB30EB88B7042297BF92B22757A0AB0A817DF03707892043DEB2FD8963FB369A8C76A8FFA17237EDB8CC0450B2E9726491A36FFC2B58E7C9CA803517FAC9C047C4CB056B0316C3CAB239FFAC13315A3675BE2B042938C079844F72601CB6A8353205211304DE0229A249148BA13C7E969CA28E95183863AB3F838EFA3BF9159CE989358FC1A69BE3C764C87A4FB8B1739510E7211617806ABF4C19FC48C6112F3C67AD92C342A40B7F5468A559563B2C2BBB7869B221959526B22032059F093BF3287FD652CF51C7A4233C17DE638E8C92EDB41C77ADC5ADA927BDB12A7EE2B00CB2577A6937C0EBA364F9093E8E94AA334545D1797071A85EE0BC9037B352CDA8D2D874E16B344E02894635A3B5380CDCB6674951C0399B10062429593573D39A06817E84F7D517332F92903C7CFF7651D7F1C37F648C22A872CC007BCF33A4E991CBD34069CCC6771B9582D83136F52790E74A24CC86C439AB7C5FF1088CCCB81FACAB6E1D0092D14A05DDC999AE4C006899D6FA6186940925BCB614DF83C5C95555358894A5A4ED2B1A8D8C7AF8B5C63CC917B849B4B544995635845B2F50BCADB9E25BA6AE2C10458D2C1358430A8EB27884B8EE27B6408265CD24C59F9B7B3E0CAA48D744BE36A3906F488C432634D88123A981B79A54C50237275262A5AB111FB51AFE1847C9E284A91733DE5F38C6D39A51987CDD368CB3E136D92A312F515A243F999C04495DD7B3EBB3CA1B82B3647935C77951672BC9520092D203AAD318852F93866E6F6494E695F4C7A97D035956C68B3A56C5A51298F1CB0997528376DD5CBCB5B15AA19A1A5B77B98F1355210543A0C0366F5328B2A49647021CC3246F1856847C637AF4B390B521B890C346CE5B4E3F1A51A874BA7DB1D2D8B8356BB0EDF48C9EA01177E801BFEDAB6444B4B911549BBEA1230FA6183949862A06954B04F4C9192B9EBCBA8151E20D48FA3CA8943F13734D9C4E642A7A7DD2BF360600ABD6E84E29BBA27F96C191480EB71CA68D4F2A9B485FFC544CD3DF67D23C80150AAF7A45CD946F4B7DB2B67F4F8B222536F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66" - }, - { - "tcId": 34, - "deferred": false, - "z": "D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901", - "d": "249D48941ABC01C9290719FB34D91B05E774E70E6F0181E1783F2586E2499536", - "ek": "11709FB3C60AA689CFC149954EE25C7071A4DFD724D0C4CAB2F4B3FF715FC16302ED2BAD6A926443A617AA2B44FE2283A660C0951A0A41C56EBBF5AC1945454B8A878E3C4FEB22C10FF5B0A3C7C177A84EFFD670622479A401A5909399F131909B349799CB116C51BD02778774764EE6B02EA64929311281FB821D074B1385A6A965E71F9A065DB2B78908048AA46118BCF95CFE0BC6F0318B1E3C4C2F895B98613DA1141170680191D896044C40EB4741D2D21E0C506410D9092F821DBDC04839C6C6C73487F9F239DAA0346563433C32B9A1F7254717A456B04F65965C614973DDB5C43B9072A120294021A21275007360940A5B8613C01E703128B9F27B037CBF88049FAAD7A10C2213F39A82510A872C7C2850D3CE5A48CBE5DA4B3547AAA3B8612F64840C00ABBB09BCB4F031EC6C2AC284A35D84796D4B23FA621C9E0CBA6E04632B8BC5D840765168C08F591871986FD44BBD78E56C30AC80E32229A0F57420872528308C52A028B1993A93003A9E40A1B75B6CE4ABB8EDC109C77B3D2A80B21F1827904C94666AB80AC9702CA78963F36510CC7CCC6AAC6E9489342371933AA4C6329926437A58CB8BD5CB64929929FE9707A13805B621A95803C7EC68A83676578C039C8F273B12C8A2C1853D3AC6169CE95364F791F7A6986EF765C5F0829FA888C8DB3FFFC3A701E3B4D8246B62B3A4FB637FF532BF152452A824AC25AC24E416CC21667B09055C77C12925E77FA67CCAF2C9602091149A730CD3F627A8613B149A2D3789C19CB6B09E5CB64E42A82628C4BB168A492529680B1BAD2A6F0F7350708030495768DD9C82D6E9812DE35FA90689087B8DF242414752AAD8E15BB3BAAFFA05A1057A8262FBB1749C9A6C4272750134F72682CA753B1E555A60D91B26728EE540132DE67958D3928C3A72CFF02BF92997B0B39F06FAA333F5987713BD113026D327AFA167B040436D9940C9AE7799A4D9CA86278EFFC846FC102625583B42234EA114B75057531A07A4E23C340E04A066F3ABD69AAEC83CAA5A88BF27A0592F5B443223864A341E2F3B21CD0262AC3B89A1E735D6B9001A1C98C12210A8E45E377A8424132A10D317BF02939B6877DEE6AE1D7818C3115076B741C307B805C4860862382D1770678B4006402B93979B2383868BA1901F50776A28978A016C4F95787E8C875F694F94E3116DD60F284158BC283B79C7CE377C3F1197AD3EEB3BDB2C8E0505250E58BA75816A21E171F9A8730FA2CB8CCA44D02902F07B6BCCDB6AF8705A78E6854935299A340E62A12418B6693A0909CE5A8F1349A993E75CC4806DFC045F4C28B4DE8C9AACA04713E62DBBE3AC857B5445D6A5F5C115D5C29318F2BA9FD126F46960DBEB3B3DE53350051980E7CD5DF450087BA97CF36B7A566F0DC1479545BCEA5C950AA4CD4EA324B04036BB6A93D8519C66B12AB2EBC05F849209A603BEC768C96587A33963BAF3A8F5D8309DB35ABBA81423C365371A9DFFA649A726C4A84604F4B893F3E30934D065CCB0383A2058C0E121C3133C7FAA4C3AB4B7321C3EFC7741400004D279C5D76AA512692774D9C319A59320BA18D5C116838C8CE96A43AB562CED703A05357CDC20AD5A2A32211A2949927F642B278E71BF94390BC90A3969017B88B8EB63FF6AC90AC92362", - "dk": "88A386E9E2401A9A264FABA1EA2B6A13B5BEE6207582309D39C43BD37CAF668AC6D1D36E8003B85FC37755441F94E60719E92294A88B4E72170D1992B5382B7FEB489DD93A60383A2D29316B7179B8462346F85662E1C7AC72C86A496CA1635B55B535CD4348D6C97D3F5A74FB60C6ECD77A62B83CCE9BAF0693952C86CCE257AF464033EDD5AFDB07333C2A7FF358B45097A8FD87BD5642B12E1B5EAFD73761BAC07BA748429426C98961AF89771FB709EAE812F9724697B4C970583012C2C4B12C369BDA8EDED8A1AAD2C042CC7F2FB86C74B82521C55FEEC5C1FB5087A3E1B93DC1750133386A491695428F09F0696158659817C66C86AD2BF388E2F74B848941AD5A8D790081D3A63E85683AB65499C0EC41C8FB146664CF3FB9311C3786B1D90DDB54B1390AC902F42B30C29F02C236DC313026772825FA70DFB8572C3BC5B968B143719A5B132620D811AFE27F3F096BE180817E36B3F1F78700F00AC574CD8287A25EE1CDFB844F9224C39ADB10B99044CB7009DC1A67EF397B23F2BB9AF5A0AE6833210728449026EBF20E354C14C856C930D61A07CABCC510042E079415D67F6CFA0E692344F3397D0A381CD3E56DF6398C6730C346502039FCCDCB0389DD97C07F9C22FFE5AF7D22CAF6150A7D7A4D60787A67C3582EC82AE8A62FD3A175F8E27C653CAB2A2C69F1D844B1972110B2AC3163BC119A69E4D628DF2C0C76266599D08BEB6B659176CDD07B1A50699DD92AB3EB2C787F90533C28156B8405CD46C1B6B67BE6399319A4BAC4A93FCB659C819A6EC9A1845F1C791C6915F7A40F3DC578C8E016A0E2703F776310B3BCD487B638671628BA508101800B94AF45AA0C3C49559A46979906A8BCA9A474D0AD63F035E95B918B0297440203E154A676572F21D0815BC45D3E7402E537669FFA65FD903A76219C94D275B71C3B9D69C024A17E4F0284179A5F4E668F981B7F968507FBD52797B19C89941BBCAA117786C202030C33F476656207B7C87CFDA16699842F72C5746D843501D9977F0804FEFC2D603C9BCE710547AC047F94980899BB1E167C26301FC146A6C89081BA492274C3C894936B57F94C12D1C3B47CBA740023A494C90942AE0290782850613DE10F52727CDD2204B106AE37B0BB3F3626DC41A6F0B3CD8646CB99F56F6ED137EF803E4439878C58B2EB280BB8FCB95F7021CCD41D2B1A40D6609830BB5E2401389733104A8077B3683EEAD98FE5EC5AC7679D3A2C6F227484D73B4F9E285E4B7C4F47E9071F637C5F8B713127CF2FE77378E2CFAFD148E433B2DBF74FE0475596051EF55007AEB8A59959C8B683A6B726BFD706C1F3E4A748430C01C893078178E3063F00F797AAE6394FD637AD155221C49C533977CE8014136873942114C54462B8750264248F04165853944B1F744EDA307B62998DFC0C63D5EB9D23DC2589210493A69C0B9820D12282E5689FDAFC1E1EAACBF88551D04B2983C2163C1A5F5CA647FC3288BCB5B543C89765B9203B5803A3006F5666BD73F5A44B60A5BDAB85B7C63556323EF82B45A4CBA06BEB388707873D28CC096651E817215485129154C15173B7A7AA826DF0649C96592C7AC8E1B27872C56CF0D3495CB54111709FB3C60AA689CFC149954EE25C7071A4DFD724D0C4CAB2F4B3FF715FC16302ED2BAD6A926443A617AA2B44FE2283A660C0951A0A41C56EBBF5AC1945454B8A878E3C4FEB22C10FF5B0A3C7C177A84EFFD670622479A401A5909399F131909B349799CB116C51BD02778774764EE6B02EA64929311281FB821D074B1385A6A965E71F9A065DB2B78908048AA46118BCF95CFE0BC6F0318B1E3C4C2F895B98613DA1141170680191D896044C40EB4741D2D21E0C506410D9092F821DBDC04839C6C6C73487F9F239DAA0346563433C32B9A1F7254717A456B04F65965C614973DDB5C43B9072A120294021A21275007360940A5B8613C01E703128B9F27B037CBF88049FAAD7A10C2213F39A82510A872C7C2850D3CE5A48CBE5DA4B3547AAA3B8612F64840C00ABBB09BCB4F031EC6C2AC284A35D84796D4B23FA621C9E0CBA6E04632B8BC5D840765168C08F591871986FD44BBD78E56C30AC80E32229A0F57420872528308C52A028B1993A93003A9E40A1B75B6CE4ABB8EDC109C77B3D2A80B21F1827904C94666AB80AC9702CA78963F36510CC7CCC6AAC6E9489342371933AA4C6329926437A58CB8BD5CB64929929FE9707A13805B621A95803C7EC68A83676578C039C8F273B12C8A2C1853D3AC6169CE95364F791F7A6986EF765C5F0829FA888C8DB3FFFC3A701E3B4D8246B62B3A4FB637FF532BF152452A824AC25AC24E416CC21667B09055C77C12925E77FA67CCAF2C9602091149A730CD3F627A8613B149A2D3789C19CB6B09E5CB64E42A82628C4BB168A492529680B1BAD2A6F0F7350708030495768DD9C82D6E9812DE35FA90689087B8DF242414752AAD8E15BB3BAAFFA05A1057A8262FBB1749C9A6C4272750134F72682CA753B1E555A60D91B26728EE540132DE67958D3928C3A72CFF02BF92997B0B39F06FAA333F5987713BD113026D327AFA167B040436D9940C9AE7799A4D9CA86278EFFC846FC102625583B42234EA114B75057531A07A4E23C340E04A066F3ABD69AAEC83CAA5A88BF27A0592F5B443223864A341E2F3B21CD0262AC3B89A1E735D6B9001A1C98C12210A8E45E377A8424132A10D317BF02939B6877DEE6AE1D7818C3115076B741C307B805C4860862382D1770678B4006402B93979B2383868BA1901F50776A28978A016C4F95787E8C875F694F94E3116DD60F284158BC283B79C7CE377C3F1197AD3EEB3BDB2C8E0505250E58BA75816A21E171F9A8730FA2CB8CCA44D02902F07B6BCCDB6AF8705A78E6854935299A340E62A12418B6693A0909CE5A8F1349A993E75CC4806DFC045F4C28B4DE8C9AACA04713E62DBBE3AC857B5445D6A5F5C115D5C29318F2BA9FD126F46960DBEB3B3DE53350051980E7CD5DF450087BA97CF36B7A566F0DC1479545BCEA5C950AA4CD4EA324B04036BB6A93D8519C66B12AB2EBC05F849209A603BEC768C96587A33963BAF3A8F5D8309DB35ABBA81423C365371A9DFFA649A726C4A84604F4B893F3E30934D065CCB0383A2058C0E121C3133C7FAA4C3AB4B7321C3EFC7741400004D279C5D76AA512692774D9C319A59320BA18D5C116838C8CE96A43AB562CED703A05357CDC20AD5A2A32211A2949927F642B278E71BF94390BC90A3969017B88B8EB63FF6AC90AC923625D0BB5F514CAC167BB2E2B5FE989CE88ED65315BC610D9A5BCC77BA80DFA2FF1D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901" - }, - { - "tcId": 35, - "deferred": false, - "z": "A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE", - "d": "E1CFB8195877B2D4FF3363BAC3B4E7BEBA6DC3CBB789B1B24215393F6C9BBFAE", - "ek": "B749934F35347C7251B0359B6582502BABBEB5574F30C63568139B1CD854BE96B8A6F09069460205BA245182334F669E93F8C7D867945C3B75BF1CA810108E0F670249A62B9E6910D793C7F0A24BD3C40839D713F880B4EC6AA8AD8ACF6EB03E12FC5B1BF61ED2480A9CF68E30A441E3102611D25E9925503E704DA69393152A759DB92175E0343560B961759370BBAB159320EFA846E4A316CF8035D8EC991FC4529055A5C7F76F6FC5423AA041CC4691352A44E6E91E54DC129B000C0829C069C1538EAB1E5BEB58BF0733B64A17C5D159ED31AD4B15B36664465B6548CD4060B487C0C76890DF4B4EEC5705DE97BF47712C667023E627480A4533A9258162050F401CACD75232CF7621BB3B00F76A1CE2B42E65A91E65306F6C019C3F0C1E00FD2192E703EE5592A41C95E8263F53B16E54A952D72078A1589FCDD7BCEAB03A41D89E1D9071DB88C344F65C8D6714C367AF7C5287D6B68EA319A7DBE97F7604AFA67A27BA136C2B996B6A1C4647A8B56CB8C0D6A4BC9B33079D5B407522195ECB9FC23C778B27ABBFF026A8CB84ECB66AFDA43D40558990931736D32EC4937629FCCD01D7B14A1241D2ECB7929C443AAC703553C63D7C8410A891986C770200598F98C8AE008CA7D95CC347AC7BEC18ACD24028E6AA4DCC856BCB9D370195BCC85DD8496B62CC3A06B5A2A5961D781659C068143952C4329BBAE9A985DACAB8201B1854995FD2BC544BCA66FB927757B78207E9C44405C04002917B2BAFCAB59AA298B555717B79257AD5BC1AB1B10F92C229A9224CA16433D244770CA18A9CE12841EC38E8D131D75912C05372CF8C845E256DE2DC38283B0E2326A5DF7A3E4AA112EB91292709BA89F7672CA1BBD599859637782C7C25C61C03ED288CA6181F5E194A85C37615A1778BA51F62789614B715ADE62E85BB8490E7B7D1C81C9B578E411904D7C9C287442D406A1BD26CC759DA58FC867B0A39954F7B29702B74BEDB4C8DF87B7E57526C25C2123C1099A21CB3882C966191BAA5C89CB19B08DA6E20C588B68C954DC7CA9483B1B9FB508C694424D85C99E35AE8A084CED1C4D4B9CBB4246D28170BA94109853BB0224A2638E91FF3269AE2B013D515BD867A6BF7797B309342DA513DB1D18031BA29D72A0850669C27A1B27454B427785327225C73968FEA012D5389861B56631F89316F3B9D59C77E007B88607A53A5D7679BEB45320CD0EC605C2B0B6C7221BEFA0BBF1FD65888E5030AA18983AB1DED0979DE800DAF11B54C50971775C98BFB5B30772A6CE835021B4344D075022B4DA1A8A00E0BA140F26CC2A36F1685424642518F57217F60ACCA0B3B24BC2DFF61BF1A903210582B684178181B47116B4139E2478D37BBF006C9B8F849AF07497F493A8A0A0EF67268D8526F3D874A7EE3062E3590AA01CB09A4BB6AE73839602DFF6A0D335132864AA178C19D8D096E3094719D6ACEC6305CF3E59B190961C17B281077838E57805ABC615856C90BE8595B00C19D93B42247B925402ADB132E78C40E18C52459A542636208D0E068C12858BAA380FDB287D7E4B855716F2365354C63706EB5561C64A012F56BD64C06D2582E9CB34DCBBB837CC72C82A2CA557B328FBD9838D19A8BA5CAEF7F516F782E8BFDB53A793223A813F942BB5A6E0965E5", - "dk": "B325042B81C75CEBA41A96A16D9695F5842C3E6B9E7CE97B765A7B44E49B33501E72CB6F5F88A94C9A731A784A1DE1955A3337DD299DA82C5AC31AC581B46BADA8BB08C1736C785633610ECC5B68C2786D82C9A08D6277ED6914C43695F275286B5B5B0AB1C8D936AA569262B6358CA287A49E06392352706068484A14587C9B71084A35A5F8ACF78C47D34B43E84331835C4E75E17645E045ADA45D9F99C267B4345CB92241BCA8CA988353348A9DD73948A941D553BF444B0230A16F7F625DDEA463A2C49246273963BB1A9C2439B3DC18F3377A15414E775700BDC408353C7124E1BCA513AC5D415EAAD5A36D72A965357248E0AA5A8B84920C4BBE4104204449CD947484B42D49D93772C038D6554F0037BCDDCC50417025F4C0694EC7621ED82BE87BB3F3E9CDDE27388F55B730C40B722269D53C6BB388557AE11F960680F8F031443B6BA70C1CE45B329A6269F7B410D9C40ED4D18FF1B6CABFB20D89019F117032C5A2008484B078488D2AE065966C680F7098F860C896461BD1D0C2947B67431B3EBB3734664C4CF1213502E0C7826A4981FB8854A5A45B216F469C72CCA4637D9C61249232760B58D785B3B411683BCB33DBE175F9E240955A7B20D819C06C5AB567C8F289915CBC3C50204443F17EC096B399E11530505D94C93EEB9946E41362BAF7772C7B153AEA4620349BCEBB2243B85759093A98D13E5CDABF2BAA25A31464C19A358B1CCF6DCC10B5341E677C0B37C65EA52717FEB98C84470261E23FC7E02AF5D2CE086A326832174FB089B768B4701A9748225F01F98F1AC42DBD99594F34812DE15A09CAB805B695574145E0AB1D9600B18BE721E70C11978ABB91E159EAB67098A77D8F51ACE14CAAE9F3360645338F0A536450384452C89109AB3D9A5C8328B3CDF0334F748464A383883C033E673A6799678A860548FC4D47D970A8B24DA195CED6B52469AC36CE9BBD159A60FA6944014ABAF99868B963943685C7A15694D4B2BD6ED91734D601680C692314982C4445B6547CDE146B9B82C558F5ADDB84C2CFB93E91E61D4016728BF724377805F0060E3C4C943FB8AB1359979B495723C32AE096130E559604A5BB80817EC947A23785CBD7209D7B7672D1251CB234A196374364A0439623C51E997D2051C0C6630214DBB6FF1C88B1600BA11A0784D68807E830B885007C202376970B92625037677AD1B81270679349DC4CC56529B5BA205EA596AB489B8574CF668303EDA22578258739A525364A7A2C3439B6E74E9BB1A7462B2A51327719528358DA11D7BC856142A4118449F8B89C5BEBA43C117A27C65BB1E70DCF5B36A1E45416E2074BC1211F14AB957C4810C84818932653D17C4805BD6A00C80E0C0FF7C51295C670A8B6758C23A21CB21E6E097AF583AF2761AE3D62AF0EF56226E31492120B90322D76D6C1F657CFD0D2BD2F6CB4F8589012B99A73B82375C54E283C6F1DD12FD53B1DFEB540280375033B0DBA671A7D608FA3BBAF8422AACE1055A787C77506C199D19A01E1A0391798C8BB967A1C797C247C214B790B14606E3403EB91A57340557F872110C0185429AC9C454181375992D6C7C9F743DC832F2A13CCA8C8B42F63A609329DB749934F35347C7251B0359B6582502BABBEB5574F30C63568139B1CD854BE96B8A6F09069460205BA245182334F669E93F8C7D867945C3B75BF1CA810108E0F670249A62B9E6910D793C7F0A24BD3C40839D713F880B4EC6AA8AD8ACF6EB03E12FC5B1BF61ED2480A9CF68E30A441E3102611D25E9925503E704DA69393152A759DB92175E0343560B961759370BBAB159320EFA846E4A316CF8035D8EC991FC4529055A5C7F76F6FC5423AA041CC4691352A44E6E91E54DC129B000C0829C069C1538EAB1E5BEB58BF0733B64A17C5D159ED31AD4B15B36664465B6548CD4060B487C0C76890DF4B4EEC5705DE97BF47712C667023E627480A4533A9258162050F401CACD75232CF7621BB3B00F76A1CE2B42E65A91E65306F6C019C3F0C1E00FD2192E703EE5592A41C95E8263F53B16E54A952D72078A1589FCDD7BCEAB03A41D89E1D9071DB88C344F65C8D6714C367AF7C5287D6B68EA319A7DBE97F7604AFA67A27BA136C2B996B6A1C4647A8B56CB8C0D6A4BC9B33079D5B407522195ECB9FC23C778B27ABBFF026A8CB84ECB66AFDA43D40558990931736D32EC4937629FCCD01D7B14A1241D2ECB7929C443AAC703553C63D7C8410A891986C770200598F98C8AE008CA7D95CC347AC7BEC18ACD24028E6AA4DCC856BCB9D370195BCC85DD8496B62CC3A06B5A2A5961D781659C068143952C4329BBAE9A985DACAB8201B1854995FD2BC544BCA66FB927757B78207E9C44405C04002917B2BAFCAB59AA298B555717B79257AD5BC1AB1B10F92C229A9224CA16433D244770CA18A9CE12841EC38E8D131D75912C05372CF8C845E256DE2DC38283B0E2326A5DF7A3E4AA112EB91292709BA89F7672CA1BBD599859637782C7C25C61C03ED288CA6181F5E194A85C37615A1778BA51F62789614B715ADE62E85BB8490E7B7D1C81C9B578E411904D7C9C287442D406A1BD26CC759DA58FC867B0A39954F7B29702B74BEDB4C8DF87B7E57526C25C2123C1099A21CB3882C966191BAA5C89CB19B08DA6E20C588B68C954DC7CA9483B1B9FB508C694424D85C99E35AE8A084CED1C4D4B9CBB4246D28170BA94109853BB0224A2638E91FF3269AE2B013D515BD867A6BF7797B309342DA513DB1D18031BA29D72A0850669C27A1B27454B427785327225C73968FEA012D5389861B56631F89316F3B9D59C77E007B88607A53A5D7679BEB45320CD0EC605C2B0B6C7221BEFA0BBF1FD65888E5030AA18983AB1DED0979DE800DAF11B54C50971775C98BFB5B30772A6CE835021B4344D075022B4DA1A8A00E0BA140F26CC2A36F1685424642518F57217F60ACCA0B3B24BC2DFF61BF1A903210582B684178181B47116B4139E2478D37BBF006C9B8F849AF07497F493A8A0A0EF67268D8526F3D874A7EE3062E3590AA01CB09A4BB6AE73839602DFF6A0D335132864AA178C19D8D096E3094719D6ACEC6305CF3E59B190961C17B281077838E57805ABC615856C90BE8595B00C19D93B42247B925402ADB132E78C40E18C52459A542636208D0E068C12858BAA380FDB287D7E4B855716F2365354C63706EB5561C64A012F56BD64C06D2582E9CB34DCBBB837CC72C82A2CA557B328FBD9838D19A8BA5CAEF7F516F782E8BFDB53A793223A813F942BB5A6E0965E5B5E964695C24F57CD05B8BDC23949D382C7E9023CC1432BC131689528B1453B0A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE" - }, - { - "tcId": 36, - "deferred": false, - "z": "7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A", - "d": "ADC4DA59D935DD87420ACEE52AEE19CB371FD0BB498D79BA680159EF7CE37C17", - "ek": "266B5ED5BB000FEB4C73CBCFF6E8A980326E798113223C1FD815922E1247992A2340B70B46A6CFF3638A9E741B478BC7E6C476D2F68CE244BBA73AA919C7A48770C5A9A798DB1901B2D93836F5C507D862811949CEB4BBC65CC2D6FC36E2215078149355B83B83635BEEFAADB6FAA387104213CB6609F8B36D291B3B567ADCD85EF569966E527102AA159F0912E5617E1B0C295D12838EB7790F0C4E4A93562EC21F94C517F5B6CC3F7B3F6E832F93893417A2797F9848D5333CE5741ADB867E64E898362249A2632F7ECA4BD38034BD5184BCAB71F38854A02A2C4693B32CE172C1FB41AF3A2B2AE370889C485F98587293C6758504189050CB437A991B8EA5E25569D1A9ED194D0E470A419B453120288D29763C3BAB00F5180CAB07DA070DB401CD28D69892B77A847A47C51A2D0B39A22074627CBC068D42988A60481BE5934E626201292AD073BFF81CCE044A33E3F3339C7B9446C607E666656A94A0034445635312B20A76CBC4C6763C338AA022D79A826D2841EECA89D433C5E7DC041ED488610A1F5A951FA966148D1B8597101C7CF8AC44F5183D42C689079164E90B5DC582A761571496B7A8C3543FF275D403B923B032CBB87D5EE90EF8853AE78590D0E8B200C3819705AD47E71568051C026B4B5C10760495994208AC61A08C23ABB921828A5D69740AF57507E339EF977649999330C6A9B584642F5539356590C6CB64872517996CAEF853219C5C2CC1BA04F0C8537039C9A3047DBF17CE18673B039B2A9EC083C7E53146863B61199169C9B1838CAB40508A6B709DD8502783654D55766E6B671B6C83201509395BC565B10904DC27BFE30842479528995A5888AA8E04374E2918A9EB642629A135B9306A21CB02C925BC99401EAD40285A7B3CF5A809FFF6502E727B332269E8C445C7D9303BF35C344615E19220E391AB4F2011634C292C22022AC0CD5FB51339B83833EC7404FC38108207B8A5B1416C2DD29785F3D87F0BC75F24C65864C31EDBE243EA0B8AD015A003BC9EAB583FDB5ACB32BA3BBAD6BE5A189472560B22614B5BD257249C4458C7601C8B0E48D0C72DBC5743E77350D64DD6A587B67280D04B20D1DB15275361DCA43CEC893EA5401FB3B459637817A18755876983818CC1C745CF70D2A8CBB36050601BFC34BA9685A02B6652535BA101A5193660A06CE54DB9700A977AB36E612549E51FDFAA5AB0490BA7A302DCB314ED026CA1D765D54145DA1623F9A7064D2926F25A0C9FDC4B8CEB8C765CC9B3A55A4BD79CFB9754ED5786F04395B7A80ABE92687D6900DD14C3AD743E2F9540534C63602858371C3D304263C2185E29261237A848DAE97507DCC5FDF60209112E08D269F56418F2FC875B693D5C9CABB9BC636FBCCE548227F42BB001EA6ED64057656566F51A927B178E17AAA24A0616CA362AD134AAC5D36C5447BF4DD0CB7DB95C9009B7109826B1D8ADEF95CE8B9B444848B41002426812700850CD7572A2530A2BDACB8CCCA5485032454E855116E91E6830A68EC04DF98370CDD18E12372320BB865AE818C6B32628489B59AB53B31ABBBC944861A0BD100B66FDC017AA0C79DD177CAE432024181820D23688BC991AE597981B56C3F45B5E4A92F34C7E72882C6B4F1D791C2719CF3DFBFB8F3FA04ADCC1D4FF07", - "dk": "24C6ABF468CF8893385B625491F2697ED724ED371DD9C76158418A6FFAC9E0A4158694AF115BB82549A0D02BCCB13282C4C37A2AFC617F347D7BC64DD6CB94C50922B8024ED4FA598B4912EE2ACE81FCCE893739678397C343C7DA4446A55687F236201E071B9C2C7715DCA6AC566702A809931B1D65919CDDB51A87B44B07629C659A104EF61BAA8702355128B9215A40E64F818C1CA297698EA14C00756B6D52974A7014E69B59E477362A63BCCD09BB474020FE51BF5337124C24C8E6F60DD2E495F3370E14A4CB1504234A4C8009B97365F166D385AC511A05EC06465D962D1BA88C191A9E28DAC4F517680D6586923BABA11BB30AC13D40466D52977929D62F48751458087830B02F5BD9B100A92DC6E602F3F24686365476C33CB9F5409856C80FA490DD6211AB9776487A3E15B33A92A347F3A92744C16DE3F8B3E942628C926BCDAB6CD80A068ED951F2689EF7066A9E2627F39C638A580441EB8FDFD9B2EA1B39D043AEEA1A0F48EA84490408818C602A828F869098FD2C429B35621DE9BC8039C6ED940BEBC32FD0C6C396B3248CFAC85C74325531A296A9C237FB2C4452457B4C43F0DAC214575A96A770170ACE6E0109E4A9C0E5F8985F4AC37CC84D206306AD7A2058EA58EA09AB3B7926941996B8125D7BD76472006C003784CF4479691BC422E00CA9976840D886DDC8A5BAFB87DB268EBD8248033703F6C6686CF928FFD736BDF3A26653319F22996C52387BF0A294944FDB1051315577B244C78578923F48B435362711B89585841FDFEC9FF047C76864055757CAC7EAC9D0F2999C341D314154DD58519B602D7855B6ED67049AE402F8913177914051E7C5A8400969F5CE9A485D95D544920AA7F169A198FA710FF73440D8949550A054562F16637D5A813C10BB29422AB193616687F062A1FA1693E3A9064982F9E96FDDB812C0763233687EE08928DC800FD2C8A3143148A0BA97633B5D97062A5B0572A89B2B265C4439357F96C01C6F464E72D0BF0CC1C421B3CD38610A9B0C89EE956AB896189C0B03AC173D31792ABD132F7174BE4D210B76E04B87E85B2E4A25F41332BC379B10D672862462F6AA3875DB6A22158EEE6B13135751DD49084862953CF275BA4580DA07921CF9482FC692643A6E9A5073A567C593AC01A57A75FC3735CD89029C99B3945A2BC7949B64377EECC96FCCFA2AC94CBE4C9AB4FC64673D042F416A80D867C9D5B3C9CB276FDB3C693181B071553B0EB66138656F33D0546322330980553BB2400D1256BECCC969937305553E8BC60C2D24AEACA90061CC7D38E3244253414222BC0D321C73EC6FD8804E71092995D48A6CD1C68CD1841011A45F4961BAB52EC176628B49CB0B840FC8B1120701227B0C92E10A1B34BB2475152BD72A82232345CFDB5B46E3403397B5D1276FE3E96703950FCFD49F1172CAF856A333497BB68C2ADAF026A7198BEE890718F474D7090151D21ECBA4B83E56069E1C6D34C5BCBFE94BF0A385702A9D2FC770D1905120A57FEF816AD941633558AEF7F96780C15112710DEDF8517CDB3314687BD4BA4C2B5A0BE253498894C7CA32401B517D812172A2B13146F30ADCBB6E79641A366BBB96B0688EB285266B5ED5BB000FEB4C73CBCFF6E8A980326E798113223C1FD815922E1247992A2340B70B46A6CFF3638A9E741B478BC7E6C476D2F68CE244BBA73AA919C7A48770C5A9A798DB1901B2D93836F5C507D862811949CEB4BBC65CC2D6FC36E2215078149355B83B83635BEEFAADB6FAA387104213CB6609F8B36D291B3B567ADCD85EF569966E527102AA159F0912E5617E1B0C295D12838EB7790F0C4E4A93562EC21F94C517F5B6CC3F7B3F6E832F93893417A2797F9848D5333CE5741ADB867E64E898362249A2632F7ECA4BD38034BD5184BCAB71F38854A02A2C4693B32CE172C1FB41AF3A2B2AE370889C485F98587293C6758504189050CB437A991B8EA5E25569D1A9ED194D0E470A419B453120288D29763C3BAB00F5180CAB07DA070DB401CD28D69892B77A847A47C51A2D0B39A22074627CBC068D42988A60481BE5934E626201292AD073BFF81CCE044A33E3F3339C7B9446C607E666656A94A0034445635312B20A76CBC4C6763C338AA022D79A826D2841EECA89D433C5E7DC041ED488610A1F5A951FA966148D1B8597101C7CF8AC44F5183D42C689079164E90B5DC582A761571496B7A8C3543FF275D403B923B032CBB87D5EE90EF8853AE78590D0E8B200C3819705AD47E71568051C026B4B5C10760495994208AC61A08C23ABB921828A5D69740AF57507E339EF977649999330C6A9B584642F5539356590C6CB64872517996CAEF853219C5C2CC1BA04F0C8537039C9A3047DBF17CE18673B039B2A9EC083C7E53146863B61199169C9B1838CAB40508A6B709DD8502783654D55766E6B671B6C83201509395BC565B10904DC27BFE30842479528995A5888AA8E04374E2918A9EB642629A135B9306A21CB02C925BC99401EAD40285A7B3CF5A809FFF6502E727B332269E8C445C7D9303BF35C344615E19220E391AB4F2011634C292C22022AC0CD5FB51339B83833EC7404FC38108207B8A5B1416C2DD29785F3D87F0BC75F24C65864C31EDBE243EA0B8AD015A003BC9EAB583FDB5ACB32BA3BBAD6BE5A189472560B22614B5BD257249C4458C7601C8B0E48D0C72DBC5743E77350D64DD6A587B67280D04B20D1DB15275361DCA43CEC893EA5401FB3B459637817A18755876983818CC1C745CF70D2A8CBB36050601BFC34BA9685A02B6652535BA101A5193660A06CE54DB9700A977AB36E612549E51FDFAA5AB0490BA7A302DCB314ED026CA1D765D54145DA1623F9A7064D2926F25A0C9FDC4B8CEB8C765CC9B3A55A4BD79CFB9754ED5786F04395B7A80ABE92687D6900DD14C3AD743E2F9540534C63602858371C3D304263C2185E29261237A848DAE97507DCC5FDF60209112E08D269F56418F2FC875B693D5C9CABB9BC636FBCCE548227F42BB001EA6ED64057656566F51A927B178E17AAA24A0616CA362AD134AAC5D36C5447BF4DD0CB7DB95C9009B7109826B1D8ADEF95CE8B9B444848B41002426812700850CD7572A2530A2BDACB8CCCA5485032454E855116E91E6830A68EC04DF98370CDD18E12372320BB865AE818C6B32628489B59AB53B31ABBBC944861A0BD100B66FDC017AA0C79DD177CAE432024181820D23688BC991AE597981B56C3F45B5E4A92F34C7E72882C6B4F1D791C2719CF3DFBFB8F3FA04ADCC1D4FF07BAF18B5A25081C8A9F526111B600954D39BADAB9044F59903D2A8F21F8E1D78B7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A" - }, - { - "tcId": 37, - "deferred": false, - "z": "51D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE", - "d": "76CDCA53F781806D55CA8D3BAFB3F4D389D712F1221E85B5E29D6A46580F978C", - "ek": "FE97202108CD725098CDC892FA68301012B3156A2E5BD503F9D388B26B07EE099D5AB0BA6B4A5E7DF369F748BDAFC4C72B171747546B3957BCFE189E312058202885FE853966A7B3DD285E06D37000900228662910260CA1D783DCE2ACBC436BF3669C51A07FB990449AFC153C9C5630F8A2E4E4B7A8E8719A98920B104E72646F83D8C06AB631755239B4303B7AFBBA9DD72577FBB677C054B16813DCF373734A6E4D8B025B66C19936A13278B859165FCC6277E9F149FF979EFEBB9867A9124233A5107B5E29B2CAF81C84A3D05DE3DB316858C5FCB372FCF28705E2BF0B4855E6F97F17DB217AD6A7B7288310086AD129119FF88D20B35F2F287B1358A851185BC12046D5079A2CB3CCAF98BEB9E7C1E82A841F7B48B4F57B3B17467441865288BC7020CDB1B7564989AA3F47BAB9B0919C6819E671235CD7B39F39C71C870FF6A72612CB1BC58A86F565AFA6932C71F059B2F72BA83A8985DC26D91A0CCD49BD32080D30EAC67D96A061E906E2B15E5F43215A9160AD4682A27A2B1B9C3ED1C697CE7AC6A4B2B3963B9A99441FA9D6337739AEF5891D773B4C095C8E97A9BBEA918EFB6058AFBB2A63318972400B11B9523FD335E118CC1FA0BD0B03C8C3278787F9B7D1F752BF5B739FFB0EB0654E753C2F955351243C233E9CB149D49AA1F1459D61B03E452192B64AFD642D00800B4B815D0B9863CE2A4A8AF4C6E7BB3F845A32FD95184812896105946B7A8ED80A5ECAAB0348DC4D2C4C2B7DBA3D1EE6B6A9D35CF03A4585169FBEA45101B97BAD583F9CEB486612761A25AB393960DDF3C1A4E23E23134CE37B7E6833822AF3B278B1B69D27A4ED72221C055C7F006F3DC78BDD3C86759260E31C8D0503954EF31292EB1C8A877A00271109998D9A1A026C16482316994B2573D1673C5B727E75024786C1742414B746C1B2AC74B71920A2C79B0456C08BF1E519CF28AA70627A6A5C8496D9B061E4439B75080A763E50C1A4B32483E87AA5E67C25A8A7CE6FB864012C6A32535DB7123D24F7CA62750A18E96911EA0AD2ECABB7B02252D44DEBB2C55D552349D3798EF7812B991755A278CE158185171B696859968492CAD792DC82767E53333AF9812AA55C443959D14B1C385452367BCFB5A5955163B287254B9C4B0380EB818912BB175605EA55585F82AFEC62C2CB46BE6AC0CB99443E5676AD21EA08A467006E67C5FEF61193F3A54C4C5DE6A4314ABC3F62A83261A4B56AF18172B4A85C00C56CF28EA5C6BFEC6AA703530B7E641E792C35D1F1BBB1914D15708B88B87D161524B44B12167873C19237CAD32BB7C72B0CDB04C516142634101FD81B2B12ADBFE27512C0A091523732B82AA278CA6AD1AF28A03ACCFA28D591040FC950AE475976C5A7E192A9044099A4AC487D5A39E121B9A776CB190A2CA499403C3A5F9F027C49F627E6446D8FB53252E1B098AC8A5DD59EFAA22D2F57C83809003CE2B562231140542AF5D561ED7C74B4E145820CBE387254D78C79A8F6C241F10D94E26454764876631811492221B09B9C2A6C75520D03EA79CC129862A10AC2E0288446AF46165BD1F614C9D1C3606C9C8669C334534266A1946AFC0C580C19283CA1B59C88AD6B8ACAAFD7C3328CE3583325ECDD4B101DC28053788ECDDB4CB7A4B66997F9FD0995", - "dk": "D5DC5D1A0BA3C20670B1306E201A927764654F757026D15DAA35B77F5B81AFD975BE114CC9E9A31A4C5E83C28D86EBAFB1E65674EA7BFC5646EBB49C67D7B0EFD60FE283BD07D71EDD71B93C815C3CC066513A52C74081DFB0773EFB736D6C0E862CC5F11CB88FBA3AC62515C39B0692359AD457210371C65B6031745622BB68BE60337F5ECB065FA678CEA88165BC7AA4E002D3C892115A3504534F5DE12178FC17E2F513B3535813D30EFCCA68018128C5C3181225CACB1C76BF7A6E98195E0B793B78B0305121087A83A37D1989D0145BB4F11B5E579075B6C5AC845949DA2EA03BBDA446A6C7F5B88C8913454A605179004BD47BAF446BAA4705743A0B6E2833011CB4069664E80C58338C71BBF1C72CC89F77849F6FF354B280044DE60B6D16C31355B4AFA199FDBA078B018AAEF88D046B927ADB64935152273B16127701B0093EED2439CC89C3DA9A277D1AC5CAF65B48262A48521361192168425FB1C341D180CABCD7406154CF7F647F0A62700C630F093649E98936D12A1FFE00A368A2622D4579F521B57BB1510D6CC6D35C48AA96B07079C7C6E4265D768E4EF2C9FA463052E716B48053EE0521227544384C7AD1673389DC34029C02DF55199328376A4C07CE6C8AED221DFDB844F770282E537F15A83A5BE8873AA52FD17C324C6C4B763A7D6A3121AB384814D20B879A42E3149BDC58CE709B3DC6E87B6EC03375CB15584C0DFA6A05F48935DB376096293BFF5A311D4373A95AAC117A25C1FA95EB1C21658A2D313A3343F643969148B11727BA64882B8AB3EC772909EB9690FC72A8F1C6B249191317610F81999B161ACE6351AD330E89A18FA0986514848E80AC95BE41BAE18C1885D44CA30047FDC152EFB069D589296AF20337E12A1093CD54BAB36D252AA2A674A7C065A5676CCF507C1A07A2CC471C612500E124573C865F9C3C6D59AA02F54094141B5A3E8BB9CB7A7400A42AE4867440399306627AE9112DB909A1D6820C26ABA62428BCF27842F30BCB97D241D161CD17E8C3789BB94EE60238B2C987601F694A1BBA38581C261DBE2B94A89556F12620141889A7CAA997036D7693BC5EE961D06A1324EB7520953AB7E3BD00FB2B4E306312A6570277C71BF35DF403442325789846AC203B905F28127B3947780201D5B57B6BE7CAC796076D04B838A222C4F08004F585BF79645FE11EF52749B8C0A5656798F8F8BCDA89C29CF1B10B4429F8B65974164C1653B0B6EC8DCF39961A7B82DBE28604C579F3109F94577B42A4574AA36F2778CD424C6238996F4954605C7B25B50C455AC334D73343D90AC6A222324DF6BC4766B3D2C2A04C92A54F084DED24A9A4D5012AE741F12318D283B1CD668375129274149F33175C2E19453F3B4E60A1089E0647D37B0721254C86720DA0A97697B45C4CD5360AC513D4261BDF738A08F1BEA818C722367C30788EA2361384A02528E1423F4143C525B8C9A89A1A574A0D45AB9A8C4E02B01B894634C29A3FF9B1C1BADA025E8A99F38A092CE903CC03411FD25CE61110A4B423A01699BD922353FB65D8E796F4B77F226895EB822552F7AE0CB7C22788429F8132F158C824319030E770D6B9ABBBB912F3E592987826FE97202108CD725098CDC892FA68301012B3156A2E5BD503F9D388B26B07EE099D5AB0BA6B4A5E7DF369F748BDAFC4C72B171747546B3957BCFE189E312058202885FE853966A7B3DD285E06D37000900228662910260CA1D783DCE2ACBC436BF3669C51A07FB990449AFC153C9C5630F8A2E4E4B7A8E8719A98920B104E72646F83D8C06AB631755239B4303B7AFBBA9DD72577FBB677C054B16813DCF373734A6E4D8B025B66C19936A13278B859165FCC6277E9F149FF979EFEBB9867A9124233A5107B5E29B2CAF81C84A3D05DE3DB316858C5FCB372FCF28705E2BF0B4855E6F97F17DB217AD6A7B7288310086AD129119FF88D20B35F2F287B1358A851185BC12046D5079A2CB3CCAF98BEB9E7C1E82A841F7B48B4F57B3B17467441865288BC7020CDB1B7564989AA3F47BAB9B0919C6819E671235CD7B39F39C71C870FF6A72612CB1BC58A86F565AFA6932C71F059B2F72BA83A8985DC26D91A0CCD49BD32080D30EAC67D96A061E906E2B15E5F43215A9160AD4682A27A2B1B9C3ED1C697CE7AC6A4B2B3963B9A99441FA9D6337739AEF5891D773B4C095C8E97A9BBEA918EFB6058AFBB2A63318972400B11B9523FD335E118CC1FA0BD0B03C8C3278787F9B7D1F752BF5B739FFB0EB0654E753C2F955351243C233E9CB149D49AA1F1459D61B03E452192B64AFD642D00800B4B815D0B9863CE2A4A8AF4C6E7BB3F845A32FD95184812896105946B7A8ED80A5ECAAB0348DC4D2C4C2B7DBA3D1EE6B6A9D35CF03A4585169FBEA45101B97BAD583F9CEB486612761A25AB393960DDF3C1A4E23E23134CE37B7E6833822AF3B278B1B69D27A4ED72221C055C7F006F3DC78BDD3C86759260E31C8D0503954EF31292EB1C8A877A00271109998D9A1A026C16482316994B2573D1673C5B727E75024786C1742414B746C1B2AC74B71920A2C79B0456C08BF1E519CF28AA70627A6A5C8496D9B061E4439B75080A763E50C1A4B32483E87AA5E67C25A8A7CE6FB864012C6A32535DB7123D24F7CA62750A18E96911EA0AD2ECABB7B02252D44DEBB2C55D552349D3798EF7812B991755A278CE158185171B696859968492CAD792DC82767E53333AF9812AA55C443959D14B1C385452367BCFB5A5955163B287254B9C4B0380EB818912BB175605EA55585F82AFEC62C2CB46BE6AC0CB99443E5676AD21EA08A467006E67C5FEF61193F3A54C4C5DE6A4314ABC3F62A83261A4B56AF18172B4A85C00C56CF28EA5C6BFEC6AA703530B7E641E792C35D1F1BBB1914D15708B88B87D161524B44B12167873C19237CAD32BB7C72B0CDB04C516142634101FD81B2B12ADBFE27512C0A091523732B82AA278CA6AD1AF28A03ACCFA28D591040FC950AE475976C5A7E192A9044099A4AC487D5A39E121B9A776CB190A2CA499403C3A5F9F027C49F627E6446D8FB53252E1B098AC8A5DD59EFAA22D2F57C83809003CE2B562231140542AF5D561ED7C74B4E145820CBE387254D78C79A8F6C241F10D94E26454764876631811492221B09B9C2A6C75520D03EA79CC129862A10AC2E0288446AF46165BD1F614C9D1C3606C9C8669C334534266A1946AFC0C580C19283CA1B59C88AD6B8ACAAFD7C3328CE3583325ECDD4B101DC28053788ECDDB4CB7A4B66997F9FD0995CEFB593C11ED360F404732EA8B6542FA9796F2AEBB4C61EEA40B6D8A599C7F1351D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE" - }, - { - "tcId": 38, - "deferred": false, - "z": "9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF", - "d": "78AB6C49354A018BD38A39926F822A1AC4ACC4FF32DFD7C047CE0887A3AC182C", - "ek": "85787649612C798187CD986E9578582F607DAED85C09B863A5476626016F88212EF2B70D81145C671162741C70C9DACF566A1B68025A7B66BAC9EB5ED8879D4CD40237D9C791B0A7E6C1C08A7354424B71D6739192B3BE48755CA513170BF3A6197400FBF94E9A707FE6D007E4062BA2D1BFF9192E294A981AB19839120401653208618C6DB25E40A28B8DD1A9E6D91A1408191C8C6638B04D2A50983C6B0640B934E5039729885DAECB0BCED2784B998CC296980626979DCC99A5726C4C07A6CAE1578089BAD68190AFA91491375C1C00624363C4A049A086794A046806117B36FC8BA8D38AA8097C727E3C59A6378703749C97D35CED818DB691783691C138C325541A1ADEE01CAC4800ACB2B008A0A5976C90B6BB8AC55B06B693390C30905866AF2014AB5D340A4EECCB4F91C0A2C700A68C67833C6FE10927D6CA935D8071F98BA31A1AB4B73128CB92BC1B8056372434A7B9524D95AD50508998A4AB179B0EB79C71392515E29BBD09682183394838A52734409EBEF5852DF7B9073098ACE127A7C95FFE48C30599540161C5D12CBF7BE203CD5AA4D861BF6768CBDB5C0401F70E4AC7B0ADC0305FB702C023AF65981A61E11A0B12C169E3AD569C90C417865F708C2A7B4B1C1866381C7EA6D17F4ED35730A84E5AFA975C728DE8B593D92251AEAA5841D8CE9A3037C1F47F8529CDE366BFC08C2A7337B8DEDA345008C43A5A901DF5C6B201B553F07FA799317A216205634130A2ADE04808032B0DC1E715C1B263C8FC07B251B14B9B1EF422C1BB171CA7D281C706A0251911ED345340DA4035D8947B058FE1D38F6EE02548B8056A24501E3B65B2568802417E98567322959EF118AB0C471B37496424FA327751C1DB40AD909424B66C811118A958782F3E57351C24934650B5A110B68C581C26CB7E634A283361B94D544E0EC713FCF52640CB180F25BD40D4114249828D5255B7EB9A1CF6589ED4BDE602317B4909950606F9C91E59E1B68599517A089466D939B43BA14B0A91987662FA63C27E1411DA78255111B961B45366515022421FBA4A04F48244449BCFEAF630CC4397A98226BC0B2A30778743EC2D2A9747A2127889794637F780A0ABC6122C79FE0830691A7EC277239190938F1648FD733C1761A42A84283E40BC7EFB707748CC0FAB76F5141122158B30655765257135EB2F08CB1E84067C64A503F58C8C54D765DADCC4C7181FFE1026E423B44AD717DCE8A6D765BE2A94C115434D16661F82410E7E19B8E3388972484638B6A52A058F2459414D3C57987215FD753434349BA001007940018EB49A52C78FFAF468D939C4AE585F2C1759E0A582BFDA316E53A363A1006BC26474F49C82B93EF4D7CA94A473D3788F5865B5D4323C3471888B06634AE325826144B5D9894CB59E8C6C6E3406459BCA1791FAA9743853175C48AD982F9775936FF68093AACBBCD87F6F30BDC1F19C93B2AECE6A3A4CD99ED3244323A7AF72C8598416543F50643B713AD2722BAFD092084BCF77385B6ECB2AC8F19BF9D97B353229496A0C6A5C73CCB06C2F2C5924E284EE3185D2160ED31B72D1F29B322C1DD11B5DABC5848933B4FB7B9AAFF1394AE76F624A231DB3C2DE108F5BDB1878551FF178901D67188E6B6F3A49C904A5539738F4305053044EEA5F9C", - "dk": "C4AC07C1B9ABFCA3BF31365671954516CB2E01E39337681D54262DB7B06E8CE8B4A98028F7176518098879083F64703207213945684CC4AB9CEC679834A35A8775509FE8CBBB279429D71A48FAA18485446A1A4FFD2996E24B76715A133C1486B2346055F22FB8666F487C44328688E5A6A6376682184B9057C9B65DF21101C3645C58393793B939C9B11C27360AE96E15A43BA3CA3A00358DFBD08A395C0A02C70FA45168BB6667A843A691A9C88FE11B79EB85F2034097166989024414770F0E2537A0F266F659591A06318947A715DB88A84BAD0434750E582A12C7C6981207239935C8529DBE0147E0E1CFB4D1BF8A6C1A699B736991CF2C88B22D466C5E481120A51F21A84877E710228766CEEC0168C2314DB6C85CAB02007875CFE3B5B613B1D50366EC450F1739712D8889D6653CDF41009CD42D3D6064DB930BEB551702813213C02110E435624920C242AEC784351228A847B1BF2C66AA1068364AA2BC674B2ABF2944018273DAEC324ABC94AB2AA5F21B318C84A77FC7A6D60570FB193A795993F2231497D8414B0082DB0A70AE81C8E5A61B461768B5653F51F31EC5E96F9041A49CA27A50598F23C575E0751E10C921A71676C2388C97FA83D481B9C466A265920DD9095005A1CDABA5B76E36AAEAB4BB58892F8A4C9590D2C96615A66F43A06FEC673C57B7376709CB759C61E37DE08C04D194A827173F5BC767FB788CE4A972EF148DADCB00B993A35C5369B3741D4C227E21112FAF923AB8C6478B856849A8B508BB4863D1C4239C0A469079CC677260FC8250C75887728B86A95F46B86E7C01214C1205C727707D9361E619CF792121F746815F9717DB937FAB2C094C90AA118C9D72801135AB87C99BBCB877915F8BA4E2E70B87303672D53EAA80A11A071C5AE307850C2864713287F976F7A465D8E4AC626B2390683ABE583E7AD4012F40778E4676BA30A163C70D5CFB5D755C0F806CCF0CCA7216BC16C2B7CA3F16239C147D81C4BBEAE635B2398E661B68EA863FEE4B94E6F2A44FB0A0BD8A75DEB9CCAF4AA14F14628EEBB7C88B63731587645B721ECA388EFB5495638863A13F4F6440C2E71636C9C1767B192932694C82740CB457D99B30C8396976A32AA5C027D3E36D0C3B09D24128B748CDB5F57BBF703E4173CA5C115B7000625FF06E280574EBB97E759302775093DB2878DB545C345B6525118D1C4458ADC9BD5F212B4D3BC77D66B9882A336231719736B448833B20F5448E759813FB856F95C60E29BA726B1D159B2BB342B737DC3FA7332B4492C583F83D9714029AE52A366C4734D29DB1E88397D22EAAD11D4A9B1FBEB7435F0B7016A400D4547A3C4B8F54B0A5E1F37082B4B751691E7CEB7C07D383705B8F42139326F0A985646B99DAA088C1BEBAB90AEC2B6B30E96229175C07AB4AB78A344A13C9A2F02B782860007A2D5611C7287410BDF0454F76B4F660B488FB94655B19B28B929B45664E6C8374F096B3B9A9A6262E2C2355A1DA73DBFA8160C5A16C08C68C647FDB408C223AB5D7D05820C3A1CF2994345305FBFC7D74CC20EE02C7C97C2FA5445AD4C9093CFAB7DE1C467768A01863347D1990A5882E355937694C0A01F7A9072A8B85787649612C798187CD986E9578582F607DAED85C09B863A5476626016F88212EF2B70D81145C671162741C70C9DACF566A1B68025A7B66BAC9EB5ED8879D4CD40237D9C791B0A7E6C1C08A7354424B71D6739192B3BE48755CA513170BF3A6197400FBF94E9A707FE6D007E4062BA2D1BFF9192E294A981AB19839120401653208618C6DB25E40A28B8DD1A9E6D91A1408191C8C6638B04D2A50983C6B0640B934E5039729885DAECB0BCED2784B998CC296980626979DCC99A5726C4C07A6CAE1578089BAD68190AFA91491375C1C00624363C4A049A086794A046806117B36FC8BA8D38AA8097C727E3C59A6378703749C97D35CED818DB691783691C138C325541A1ADEE01CAC4800ACB2B008A0A5976C90B6BB8AC55B06B693390C30905866AF2014AB5D340A4EECCB4F91C0A2C700A68C67833C6FE10927D6CA935D8071F98BA31A1AB4B73128CB92BC1B8056372434A7B9524D95AD50508998A4AB179B0EB79C71392515E29BBD09682183394838A52734409EBEF5852DF7B9073098ACE127A7C95FFE48C30599540161C5D12CBF7BE203CD5AA4D861BF6768CBDB5C0401F70E4AC7B0ADC0305FB702C023AF65981A61E11A0B12C169E3AD569C90C417865F708C2A7B4B1C1866381C7EA6D17F4ED35730A84E5AFA975C728DE8B593D92251AEAA5841D8CE9A3037C1F47F8529CDE366BFC08C2A7337B8DEDA345008C43A5A901DF5C6B201B553F07FA799317A216205634130A2ADE04808032B0DC1E715C1B263C8FC07B251B14B9B1EF422C1BB171CA7D281C706A0251911ED345340DA4035D8947B058FE1D38F6EE02548B8056A24501E3B65B2568802417E98567322959EF118AB0C471B37496424FA327751C1DB40AD909424B66C811118A958782F3E57351C24934650B5A110B68C581C26CB7E634A283361B94D544E0EC713FCF52640CB180F25BD40D4114249828D5255B7EB9A1CF6589ED4BDE602317B4909950606F9C91E59E1B68599517A089466D939B43BA14B0A91987662FA63C27E1411DA78255111B961B45366515022421FBA4A04F48244449BCFEAF630CC4397A98226BC0B2A30778743EC2D2A9747A2127889794637F780A0ABC6122C79FE0830691A7EC277239190938F1648FD733C1761A42A84283E40BC7EFB707748CC0FAB76F5141122158B30655765257135EB2F08CB1E84067C64A503F58C8C54D765DADCC4C7181FFE1026E423B44AD717DCE8A6D765BE2A94C115434D16661F82410E7E19B8E3388972484638B6A52A058F2459414D3C57987215FD753434349BA001007940018EB49A52C78FFAF468D939C4AE585F2C1759E0A582BFDA316E53A363A1006BC26474F49C82B93EF4D7CA94A473D3788F5865B5D4323C3471888B06634AE325826144B5D9894CB59E8C6C6E3406459BCA1791FAA9743853175C48AD982F9775936FF68093AACBBCD87F6F30BDC1F19C93B2AECE6A3A4CD99ED3244323A7AF72C8598416543F50643B713AD2722BAFD092084BCF77385B6ECB2AC8F19BF9D97B353229496A0C6A5C73CCB06C2F2C5924E284EE3185D2160ED31B72D1F29B322C1DD11B5DABC5848933B4FB7B9AAFF1394AE76F624A231DB3C2DE108F5BDB1878551FF178901D67188E6B6F3A49C904A5539738F4305053044EEA5F9CA8604CD90AAF5FB9BDA220814069AA00CB5B5FFB7B60E4BCC86F16ED0B49BA9B9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF" - }, - { - "tcId": 39, - "deferred": false, - "z": "18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77", - "d": "13B75620E4CB9AB9A6689F6E2BE44639BAE6C9CB7DD641AC1C9377242D99679A", - "ek": "AAF98BBEF422DAD045B9D3C2F134C71ACA3884604D3B87130EF84890D8870A4783DA18BD4C8B0667FB194393941C7508FE20AE5C077FD06A247DD7C19FD20940568B45938BEB39B1AE18CEA618BB8001C84DEC8CC170C12C77B6704AAE9B745083B3B00A020510A196EE2AA12195CCF650CB50600F35D61910397E645B886BFC58FB7C99C58AAD79552E13D31F05BA5904007E3B504D717156D652CB1D2353270CAFA6986846100B81C7816857AD7EB98D5CDA24E6DB3342F346AE5B162C11BB9E8C2AAF95C857277597398DA82A6DB7D7C34D7ABB1BB3155E72B0C6C811031A06D609C23306473317948E1B1AD9F7B59E22962BE33D750561146B135FF64058BC5524F26DBDE518C872A98D14862FF4599CB16C11D654F6762D531718C9B2BB51C34DDE019364F246891A3891F823AE85B6E54A4ED6A18673D4AFBC2C8C8F47C07C2B51DCFA56E5A57211914F437C2181A92723D5C09844951A0CC0470A594AB0C0E8A378A3015E39C5275E9B9D4E202ED6A4AC9AD1742C8455642932BA68C599E8883A3CB5FA11876023BD153166C7C33B3105C1BA9881F92C99CD8B41A475777F239AF2886570F94AA3626381A6B8B3C3AABDC39C2A6C0CAFF7CB95CB3162652BB0493726A81339377798D78AAE999BD9542565D5491556B716B09D0482C603B99501F8823AC6C5018543527928D2981C2957B9B7ECC33BF423F3B89DF352377DC554590A4BD6E7AEF624B873916CB638AB426A50F7789B25B420E4380413B10416C048A8069FCC62BC727AA9425700AFE835E12682215606F84C70DBAA4BD9B93D1E156913C62959C98A741A74810B996063624061B43D225B1AA71A02C50BF38016B4439FF156ACB652B278E0AAD91C455F03B29998317F596A1CB0051CFC21B1E76B59B52409164233D0C7B01A2B7C93120FC42BFB533347C2B4DA782BB55034C0A152CF51C44F39204A63C1F7867E57F27332791D8E3A1A13DB9A61BB0FE5660C6A8A2EB1365D30A83C3C1B9F03E66E58B0144CB6B292847F68CC3B0600C32FC45569158EBED0BAA50B26303707C1796BF9569193825603FB9237FC2AFBEA9D8D3B283D775583990E2672859155C70DDB7C0FEB84BC07B851F7B4BD44B84DACAC0FC913314113654567BE4370AE3179BB3BA56388A7EAFC3A1A10C25891B5A943C62A4297AD469D8040829029A8960CB9F65C21E10B64B07A713C40313E6A6EE0E939C741AA7BA93526022A8440858039A357EA2CEDB342C9299733381814E1C78FFBB1E289AA93C6ACD93C6DB2704F79922D277C9800EB3983865F65842D5BC8B346207C6C33612250110AB236DE202374132D60F5202C77367912C4FDFAC54DEC5FBC29076BA13FA013CE0FF70543B8989190AB63FA721F677FA5D0B248F2646E008830A06DDD613CB6063A8B9C37B4C263C4904E3B681EFA3568F0E429B947936EF41B2EF704751317EBE86A9597B8C0E6C81AA278FDC93F0379AFA3D1244D917401AB151A7805CE881216F208EB976FC442BB9DE86943143107B4AB479681F109AEDB28309067B9DCD6030DB4B558890FA1C5AD7FDBAA9BE39E6D6CAAED3C5286C73DEA3B6DBB940E6F647D43ABB364D92BCF099937706F8CD48F58BF77E3972CD846B20E9A1331AC0CC350080B65731270F9B2A951D93C68C98C", - "dk": "5C9B6453A08BA6B40F1F7C6C7CA464C76237EEDB9D74F0925D200A599684E85862AF8C29EF28871E7A55CC5824D381A9B7ACA2096B78081862D504010E1A9366000C022B3EE8AB91E6F7334287251F829C00221217823D641153B865A30F24B847154ADD5C9B4FF2350EA51D6C49A975AC2F65B541A52827DA25C93E9B36023C6129BA29E495B4914334E4D02CE21B66F1437874F1A56F03A6726C142F0B03D46543BED89D4597902C0C5B025895A04A9E22563560DB29793A353FD4528D0C6B0D0AC657358B04E7204C21A7378AAF3F0B93730C68D238695EA4CF3C9B35AE19B052B8CB2E041700902B4600BC30A846951BC0B9E42D9453B10ECC37165B08F22675657A6FC2023F0C1B42BBA175D329935B62468522BAC0944B83C5926A1C563D9323F175BB6EA9C2B1CC360FE8B60FAB81F5A1C9F31443D698B34336C0A1EB86E8E162FA21330E909CC0B69FD62738D823B6AC0462DE561DFF33094C1029ABC49381C406A316A3E2A887FFA9C3CDA9CA48E8AD802CB0231142C5F2CD83154DF65540CAFA16D39190FE100812816ACDD0720B4A44D337611651B1E505B7CAC0BF832841C573144BE42EF280B25C7B1700F344F82AB0C575B2D10C3A86449614B592CE42195F9C385E4CA257478E8D5320BAC24A68883DFC399AC236C497C27B5A80842AA018C0C0B459C2B14737197870C0E6D661510951D290B5549331E6C557DAB48F349B829AFBBEAB932E1E8638ECE2279C697220152FB84AA9DB5A8307F93438A51C22E8A1DDC54AB722A692EBCE6E719A82066E60B345C75729B4E7AD173BA7F363908411B6E724262BE0CB05F51E7739A5FE0C304690645C763CF7128DA2F71B2F7238A43003000995737A4DCFD8682BA8923C6752E53150DBD36468D6A2459A5A54450FA6D14A4295B573423E4BE95529C24D7D035C5F65C49D3684943AA505869CD525665545676A52958180538A521AF9274033BAB2C7AC83566041D9D40D92FB2DD2C147E456456DF0105264B0FB17853BF991789B6818F9BB75A381D4978D2EF7098626903C857CAB673353783C12C860258A363CAAA771ECC724B2332C1A254A3CB1547CCFFD149C187B345FA282DBB92D9793374CC67D0C0B5F946B78D81B08E521275AB7357050694C824033B9568BD335A8B837627B1494D9701181C7AA02A95DD3915E55A371F31C14F90C63075555BAAB65AA100AB99A6C1C85A1051D7E58A8E65BB312E02EB5485C05F302DDF814EED49D39E4A9BC688C989A17DF074C7FAC62FB73B0EEA85FD8177AFF41C4C3E40B407028C4F58E60DA14925385E4A0A6BA8B13C8618A8A08BF6A1630AF1B5200BA41596C9E440A5BA11C21F7C62A46379627CC4DB2E43A565A829FB605F186C405C519502C0115D9BDCB8857E03343707843A28047BDD6B445445560A686801C4D3F4C4C773537AFE7C5E2191853F56A8E75A9EA852552440B4E0642C3133FBB4CC678C2A35D093975F17BEC7972C938A7F0159A8BD8910E847DB09A1A2DE43576F9818A338787C10709F085987424C59546BA5493FE9696256C1B147105092A77A8A329563B061AF8CFEED35EA1E625F03716FA75B7839C325B94CB39C6CF1323CF4CA486F8703BAAF98BBEF422DAD045B9D3C2F134C71ACA3884604D3B87130EF84890D8870A4783DA18BD4C8B0667FB194393941C7508FE20AE5C077FD06A247DD7C19FD20940568B45938BEB39B1AE18CEA618BB8001C84DEC8CC170C12C77B6704AAE9B745083B3B00A020510A196EE2AA12195CCF650CB50600F35D61910397E645B886BFC58FB7C99C58AAD79552E13D31F05BA5904007E3B504D717156D652CB1D2353270CAFA6986846100B81C7816857AD7EB98D5CDA24E6DB3342F346AE5B162C11BB9E8C2AAF95C857277597398DA82A6DB7D7C34D7ABB1BB3155E72B0C6C811031A06D609C23306473317948E1B1AD9F7B59E22962BE33D750561146B135FF64058BC5524F26DBDE518C872A98D14862FF4599CB16C11D654F6762D531718C9B2BB51C34DDE019364F246891A3891F823AE85B6E54A4ED6A18673D4AFBC2C8C8F47C07C2B51DCFA56E5A57211914F437C2181A92723D5C09844951A0CC0470A594AB0C0E8A378A3015E39C5275E9B9D4E202ED6A4AC9AD1742C8455642932BA68C599E8883A3CB5FA11876023BD153166C7C33B3105C1BA9881F92C99CD8B41A475777F239AF2886570F94AA3626381A6B8B3C3AABDC39C2A6C0CAFF7CB95CB3162652BB0493726A81339377798D78AAE999BD9542565D5491556B716B09D0482C603B99501F8823AC6C5018543527928D2981C2957B9B7ECC33BF423F3B89DF352377DC554590A4BD6E7AEF624B873916CB638AB426A50F7789B25B420E4380413B10416C048A8069FCC62BC727AA9425700AFE835E12682215606F84C70DBAA4BD9B93D1E156913C62959C98A741A74810B996063624061B43D225B1AA71A02C50BF38016B4439FF156ACB652B278E0AAD91C455F03B29998317F596A1CB0051CFC21B1E76B59B52409164233D0C7B01A2B7C93120FC42BFB533347C2B4DA782BB55034C0A152CF51C44F39204A63C1F7867E57F27332791D8E3A1A13DB9A61BB0FE5660C6A8A2EB1365D30A83C3C1B9F03E66E58B0144CB6B292847F68CC3B0600C32FC45569158EBED0BAA50B26303707C1796BF9569193825603FB9237FC2AFBEA9D8D3B283D775583990E2672859155C70DDB7C0FEB84BC07B851F7B4BD44B84DACAC0FC913314113654567BE4370AE3179BB3BA56388A7EAFC3A1A10C25891B5A943C62A4297AD469D8040829029A8960CB9F65C21E10B64B07A713C40313E6A6EE0E939C741AA7BA93526022A8440858039A357EA2CEDB342C9299733381814E1C78FFBB1E289AA93C6ACD93C6DB2704F79922D277C9800EB3983865F65842D5BC8B346207C6C33612250110AB236DE202374132D60F5202C77367912C4FDFAC54DEC5FBC29076BA13FA013CE0FF70543B8989190AB63FA721F677FA5D0B248F2646E008830A06DDD613CB6063A8B9C37B4C263C4904E3B681EFA3568F0E429B947936EF41B2EF704751317EBE86A9597B8C0E6C81AA278FDC93F0379AFA3D1244D917401AB151A7805CE881216F208EB976FC442BB9DE86943143107B4AB479681F109AEDB28309067B9DCD6030DB4B558890FA1C5AD7FDBAA9BE39E6D6CAAED3C5286C73DEA3B6DBB940E6F647D43ABB364D92BCF099937706F8CD48F58BF77E3972CD846B20E9A1331AC0CC350080B65731270F9B2A951D93C68C98C1783913132F097618BB39BD4748B4EFE63DA07C26697F9B2F4E06CB2D27012AE18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77" - }, - { - "tcId": 40, - "deferred": false, - "z": "C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25", - "d": "7C345819C7C327AD9571E5DF882449DB243870D686A9764D4129B21E17AC86A9", - "ek": "D6525398362B71938C1C721695157F1A2BC24680BF6E265DE8726594C26CBAB9B040462B4DA30402D70EC050958FF5944D181374CC9A29E867C1B33CC36CBA66C66A75F44CD68112B543AEE0026D9C105EE556AD5FC2989346C7473C93E2641AA42904C7751D83CACACDA6B2175B1B9C1C41435C49027AA21119428C61482F655D4A0CCCFA5315100C314B680F702CAD99FAABEAF08335257F9380066A09BA0D4B04F91A52FBC09F3C348F0A49B840BCBFF51B63D380C53FD17DCA7B76E782580D926865A79AA4992FDCA771F4232AD68956FD1A32547588967B402B2C8E3F2264DC7BC8B5B770EAF4B413C1AC44A8A4A4061CC7FBB7ED809FD97C84B6190BCAD156E36018C44CC0C5A84E9A872EFCE63C370BB257C46AC285058FA09981D1CEF51A07C44994E68C9C3CD6394EEBC545F438858A6D18583E51DC6F15D7B0A3F02F26932928BA1F281012D93050A8D6685F5364FF952BE1C644965A3D255A57C95308E100C4AB8343E2311927212E6F7975A9FC7F72B4761B78069DC5553D740A5433108099BEBC850D5477CE3708474481026931082946A949E3B00DF640AA52BA6D04AB3C1115C91147BCC519DDE6BB953582DE996D38F35A51C7AF0AB999FD78A9B34BBB209869D3776C038B0211849A26674D5D5698904A9DCE362D6BD858B3848B9534B84DF672047930CF63B51D91C79321127FAC7778068E7AD26EF3E61E98B757F33127895A07BA6CCC0FF72A5D5288FEE49AD4D249B7E1B9E695B91EB147D0B1AB2CA4299F9A655BF25AD3B9ABC9B36EE98740FAE598F17113D3C8912BE694A30207E86A5633A32D2335ABE7D7267AEC476771B0A7FC8B0DE2BFE524423D0304AB19632166C790DB214D478726BC7A281685B2CC77E0BB9F8BA64245A80A5DB5570209B1FB0115EEC3CF67383F35E7C05ADC02E8A2BBD1994BBB8818646BB9B87349FDACAE5EC681D40A03A506754700665F4B372C2009711AB55D0C0D62506FD4701EC69C45EA8ABF7A20BBB2669AC460B6728B6845476F49DBCB927723DFFB7A224CA159DB7D1E63322F22BA31B6BD04DACA1E30AB53AA686B8704B483152516C94078916C32064FC638467329CA008784847275A61B44E758A6828D5377747B8848D2557DA23090865A58BB1C7E7448AB61796697DB1B5A70C881CB80A9438F13C8753D662ECD495E74B21CDFA177544A3D5F8912634143938935B4F26874231C2D58BBC0F38DAE4135955793596C4DD44798ED9A57FC178A3AE245DE19BE18C1604A06D041C5560E69093854999EB93D1F82447103B54D46383FD084907060FD756DE74B6FFB3675E0ACA92AC5A89DA53CEF6042FE0CABB55C68DDBA367CB999D7B0B935E752AF97196D465E57081E0378465CC6BA56234CCA1283E22334E65A7F56787BE509C1AAAB0942B39D58167DF5421E35B6C966965FEC61BBD8AAADA8B59DD0664DFCA12F88B92A1CA158E7D5B5B5401DA7D038CE9A70FB5C890E52A19CD32DE63219DD94981CA9B269F0C4BE40CAD533C6DB8687E4497526392B848C4BB706AAD7A68AFFB4AC3D21385A2CB4DDF369D41B6C978719C8D121D43551ADBC54F74CB3528655ADC64F62C59461C3531B6272A4AC9CA013A0203C6D8ECA72D67189DC07FCE68847F0053CA9F0F6AFC7D795AE4ECD3D8E6A02", - "dk": "E4028F81A3115D24B0661A525B546BBC901FF645B4A8D9127E500279A0B67C028DB6E660343012EEC35B8FC5B25B61374B19053D910BFC716E08517187B191582971C7A2C1564BA8B2E6C72F417681224DD3F663719032D0649C4F69229CCC9FB9E6B775D3376708704B5A715B67766CD045DCBBBF861B3170E44EDCAAB276C6190A5B188401353F61C4BBEB413811015BF273C760682F414CB74ACAE3624B9C75036BB32E6113BC59A2A9B0770E928C445B53030A8B262D34950C930BE7ABAF65376C0C90416333B2413C4F849A341BF0124CAA691CC2C2A8C328077302FBA57314E0747569BBE664339219867E42A0E1E92332A2103925CCB85C3ADD190CA3317E0DAB7CFAD92473CC5AD7C31A412417C858AA846721B268642F9641C05A338FA77ED5572A2AFAC80AB0746F07740BD8925E856225D61F73C1BE78381FFB751D6CC456FB488D143208C6E849C0DC10FE295148293251B4300FD72ADBA15BFE82406CAB7E0E4C4F7545869737B46B669EA45470BF9894BEB9CE8C57C4E18042D071C0D58C27AAB46C05446EBF69CA18E45E63039E12A12ABFB3C291692016182349DC805725334DE86E8971449EF7AF09D52089872314757110ABA0BF576C98C1A9D8355DD45A3D842455017A4156101931198920354B0BB66ABD7BC4A2741FB5B06424C14D07104460F3B1A7C54DE8BB6C7AC6091D5B7FDB91BE0A4616AA412C807799D23379756658B9F39345BC5DCF9168AC5B22B2E94BF43071D241129C06714FFAA4B74564B402521942769A391D9CB3C15F7572EE2407ABAB96ED161388C6B76346504650CBB58025155B1527850342E9354804A16626ADD0305532A6387F45781BC080011A1680716C7C1B3CF72717ACC91ECD189A5B03C7ED561DA771B68CF275684C2CCAFA8711F34104E4CFD8F6BD050B5E196564D6D710965740C9A533D1136F7009B9B69CB6BCC388CF7644681B4C2A475410934840A6AA0E316357FC8CFC612E0A57C7ECE8321264A8BE56C468E8C431A0CAE612056D520AC26847DAA4BC71BCA9B3E739D454A4C7B3808CB633A603C22644361611A9D363A407E99D55C459BA856F8295B742357B0BC7C53436A58B434A0280473775B3B3837503828B76D8BA5E182E3AC8154BC99A727A70BEF0B22E631BC56B631276898550443381C1DA223E2CB3A0C38236F35200E1F9C67EA42CA9E620D148209FFBBC07B333BB2B8013233F4C908706F87410C6829C44332C084DB2E0489894593D9627E9F370DECBA867788F9FC99B81127F6EF446412A36E3B2286FD013354C58A04B32E490B7AC53653BD2A15A096682D01689194A0232BFE522B7A85275A5834DBD105D9AC03C3B9416F344302B72C232890390D303DE975B0CE6AF800B0F587A17CA759BE4315EF9D4A3C27033FDD290646C4EBEF4964DB66BCDAB216A80737B2B674F5170B1620E868741792AC8290C1AA21B1460C61B367367A5A084800652E8C9528431AC16F73138A69678B218434463AB5587FDE45ED194B830F02996D81A2C92BC6F524448CAC8B4A5795C7A423625170DEC2120D437BFA96F0E8078771C9AF42943E8A51CC89C9759D3A92896C5494CC584559742FB564C068811ACB6D6525398362B71938C1C721695157F1A2BC24680BF6E265DE8726594C26CBAB9B040462B4DA30402D70EC050958FF5944D181374CC9A29E867C1B33CC36CBA66C66A75F44CD68112B543AEE0026D9C105EE556AD5FC2989346C7473C93E2641AA42904C7751D83CACACDA6B2175B1B9C1C41435C49027AA21119428C61482F655D4A0CCCFA5315100C314B680F702CAD99FAABEAF08335257F9380066A09BA0D4B04F91A52FBC09F3C348F0A49B840BCBFF51B63D380C53FD17DCA7B76E782580D926865A79AA4992FDCA771F4232AD68956FD1A32547588967B402B2C8E3F2264DC7BC8B5B770EAF4B413C1AC44A8A4A4061CC7FBB7ED809FD97C84B6190BCAD156E36018C44CC0C5A84E9A872EFCE63C370BB257C46AC285058FA09981D1CEF51A07C44994E68C9C3CD6394EEBC545F438858A6D18583E51DC6F15D7B0A3F02F26932928BA1F281012D93050A8D6685F5364FF952BE1C644965A3D255A57C95308E100C4AB8343E2311927212E6F7975A9FC7F72B4761B78069DC5553D740A5433108099BEBC850D5477CE3708474481026931082946A949E3B00DF640AA52BA6D04AB3C1115C91147BCC519DDE6BB953582DE996D38F35A51C7AF0AB999FD78A9B34BBB209869D3776C038B0211849A26674D5D5698904A9DCE362D6BD858B3848B9534B84DF672047930CF63B51D91C79321127FAC7778068E7AD26EF3E61E98B757F33127895A07BA6CCC0FF72A5D5288FEE49AD4D249B7E1B9E695B91EB147D0B1AB2CA4299F9A655BF25AD3B9ABC9B36EE98740FAE598F17113D3C8912BE694A30207E86A5633A32D2335ABE7D7267AEC476771B0A7FC8B0DE2BFE524423D0304AB19632166C790DB214D478726BC7A281685B2CC77E0BB9F8BA64245A80A5DB5570209B1FB0115EEC3CF67383F35E7C05ADC02E8A2BBD1994BBB8818646BB9B87349FDACAE5EC681D40A03A506754700665F4B372C2009711AB55D0C0D62506FD4701EC69C45EA8ABF7A20BBB2669AC460B6728B6845476F49DBCB927723DFFB7A224CA159DB7D1E63322F22BA31B6BD04DACA1E30AB53AA686B8704B483152516C94078916C32064FC638467329CA008784847275A61B44E758A6828D5377747B8848D2557DA23090865A58BB1C7E7448AB61796697DB1B5A70C881CB80A9438F13C8753D662ECD495E74B21CDFA177544A3D5F8912634143938935B4F26874231C2D58BBC0F38DAE4135955793596C4DD44798ED9A57FC178A3AE245DE19BE18C1604A06D041C5560E69093854999EB93D1F82447103B54D46383FD084907060FD756DE74B6FFB3675E0ACA92AC5A89DA53CEF6042FE0CABB55C68DDBA367CB999D7B0B935E752AF97196D465E57081E0378465CC6BA56234CCA1283E22334E65A7F56787BE509C1AAAB0942B39D58167DF5421E35B6C966965FEC61BBD8AAADA8B59DD0664DFCA12F88B92A1CA158E7D5B5B5401DA7D038CE9A70FB5C890E52A19CD32DE63219DD94981CA9B269F0C4BE40CAD533C6DB8687E4497526392B848C4BB706AAD7A68AFFB4AC3D21385A2CB4DDF369D41B6C978719C8D121D43551ADBC54F74CB3528655ADC64F62C59461C3531B6272A4AC9CA013A0203C6D8ECA72D67189DC07FCE68847F0053CA9F0F6AFC7D795AE4ECD3D8E6A023B1D861C34DA182BF4DD683ABE8D247898E71E95E27AF72494C02BA6FF3C8147C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25" - }, - { - "tcId": 41, - "deferred": false, - "z": "EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF", - "d": "8D6DF2EB3DDAF961FE5EB556842B758BEBC7ECB312B6D4628B323F483B77D6F9", - "ek": "499B0EFC9A67CF754833785F22E7AA1AAA43EE135195F42410FAC0F90A6C7658BE53354D81939036C88A44801707CB2C743363D1623DF1C1C0EA474521979497178361A264C5C68DFD5484D6B19B1734CF6C73521266B4B5D81872F059A22C2A9219CAB4055FD8B95661CBCE716694DE5414B4CA0AB0AB3231A896AEA0883E6A6454F0025CB79894D83179F1036378A423D55005C973A297ABAD1B7321CBB89B6875F3B9522A27C83D7716B01AA8523686B3EA5F9F3722CD715A833CBB7AAC7AE3E24F1F08474E096D31EC3B608C3C67C1340E01B9780A09155C03C7971D54E0C9C7A6265C196C0FDB8E0D6C23D549708B9C2E2E7366F146C2BBC290673030BAD304B67A6133B3B22A41359262AF706785EDB44AA6B58EF1B71C69B4C1097230B90702BFD7657464991C46C4BA0775F807C0ACC14FCA9C31FDFAAE5FE525BD9538933C843764B7FC130322235823D55637B721B20B8825603A57862064517D2DC54545A0A7369270B7B15ED2B5265A401532F4ADCFFA3C94A5B6E89660530800CD317B45522AB8CA8E3EC71259FA60E97A808FC49EC9E998DC703FBCB3308069019DF8138E3B9B69D71F9FC708EB1364E7F7C2DB73765F13A53506AD03205EB5AC5DA86B24E322898B79917753839C5A63F400547D75B426F70D479A6340278D0607C765857E44A2A32AAC4A3D324BAB221FACA212E1A9315B452C5FE25EB0344138A1B191F8044C9A4CCF0901A66C8FA56AB468BA4513E8A045C6621F22719762C37C37C6E8C5C04CDA7A02FA287A2B04BD88BAE4A94DFAB47733D74B056C7541EC992372104A470B60F20E394C6994A13932236532A74B716A8D86F5ACCAE10CF6C1708D079766A7B5760474A9E351ACD6774A627CBCF10E441894940164AAC6554CF73EFA6A7C487216FFC93939561130F107E605C5A20A8B3A280F27942F7CA353BEB66EE67A2CC2AC68CD94310E8B67D597AB33368C83179F8F8124180494EC253B395114FDCA9E27FCAC8C7A0B1AE40D31581946C5506B5063E2050D0CCB6AD713024A9C4D08D09D211486ECD371F5033C8804C0531180B99447FEDB91181C327DC000E7159C1634013EC00C03C4C5ECCBA79DD138F20B4975F27946566A629A4819E7C77EE4625CD91C86615AD1A876E7045196E6C09EA22439751304D92B9C2B3C9BD32A6CE010C1BC5608245B76008A58A4A4C9072EADCA4AE103B63487366D130A5135C18FC4C6766CC8E06B988C51AFA6D1CD44133ECFD539BB0B8CE92A3FDD36127B9C03259161E8441A22F0436F9B1A0C57BC8BDC06371078A2C9548442310B4A5479F0054ABC375E75A1D170A949C91865326A76768A2F117CA524CA8047B26F7416FF677DE0BC07D518C5F71686DD544823DBB9622706FCA2A2112472C352B6BBFA0A3A7C2280CC85C35203A6DBCE3D3C4E8F9C1D454C730192968892BD257CBFC06179EADA01362BB1D1258E9F1BB563565535908803822969B3B2A21633390961891A2DC436B55EF392F0379EC484967A9068E99BAEE1F461241070342221660101651B2A2FA896934141DBA9B905E8C309F8981CC5B080C26CB585090EF97C4E01B8ECDB7F5DD88C4F8B85765B7908256D350898450C3592526E6A99B504A0D3D19FF79680DADC9890E865104DA28FE012506D19180565", - "dk": "073C0C1BB67152B5AAB7A58461B1AB82C3BFA8CBCAB360B48CE83CE15B8998579542183C8106743238809A43B848688025D2CAE11857BD75986BC0B2516552F640807A4625D6E28816883BFD48966FA2A39A3486892382BC799FB0C6623D687A2D7A9C6CC0867C2C96C162C272425C503CBB3DF71611565B43777DC805A799FCAE6895C709760689E45FB61779F1FA72EB7628CE299DECFB6D25E883D431069A3002BCE8AE00145AE57785D2F82E76F59B98FA5A5D31426DAC1F394B954377A6ADC243E67A8C05B389E3C013A7F98131DC599B6918B79C665D73C0DD676DB7A864534A536A75C108EA79CA267684812912D8711D32225550788E22A23B861C261083B9A98A3D325A08C828DA42753AB959E4C795FD370A1379C9C926038DAB8BD281AB46FB3D8C1795D6144C25CA1073F00C85A27B441034BE185B43AA0782A70EFA995FDDD35E753B226454A0C5998A8B6C0604991E3942AA699B91C6B17C67B373CDB05A48B05CBBD8B3F1B1139DCB18B15704E221179FD95478A6280DF1518FD3ACE9837E9701503476C230E582AB4BA5F88CA5ED306EBA481BA51B5FB5454BC96100CEACCE14B11A43915E44B0067C44408980CA872B568ADA7432A6B50FC6416DCA06D62B96F701BCFD7A48DB251D6949AD368779FC2858C6108D0F7C0AFCF9A7A8C0A6BC27BF76603B74438B5DB833B3AC8516EB3D99BB24BA310D12EA23FCC0111B02409FC670A1DBA9AED13849C78DFF1229B8CB4B3742046C4744BAA3067F456E8625974E3387662C6ED3B2A1B24262BC8A484EF185F222124C9B3ECAB4B7C4202C64309277B0A28B314C702B72D1C950647C6A27D477E50AC3B675593123961F941750192212B663EA79BE4314096B7A74E7517FDC6818A8C913C59C75BF6A72A2F34F6A77816B9354B48989A5EB62E250372AF04DBB56332B6545AB254CBF9867E354A8F2C4B614646F6F316A8294AE497B3B7E12B6D6953D2A764BC4A22DCE9185C7AB0A939883B2A48531B374F3C499DC746170650BE2F08D0AF4785094C96F3423DC5A8D90F536AAE1C3688353D9A67FF2E01E94CCA7E67A5F9842762B30BF8FB729D0694DAF93397A360E8C200BCF8B7A68B9BFD43159C89C6C88E389B5237CAD95BC85D366DA09BD2AB93A7E8B8CE58AB44E93680201605EF434AF729E3015A3F0F5A69C273724B557BC218360A31C88EB150A545C4BF7922852BE48972D2F479530216F9E75B4F33967214CBA93E601D5D536F8FA3083FB3E5BC6A752F9C3F87413DF31B0235ACB53EA6C96A74D5E02A22FFA4EA8805B0B721DD3A554108000A0BB6F25F4B7FFD11F4CD15F5F34201FB958A8D13F9A530E66B452FC8A160923928B2B9C9BFCA4DBF374923A301751175621A3EAAA2C046AAB0CD42D3B693E4AC19E7171A0ED87186C7C8EE4C576B9EC9A249B7B346B2119B32C78324BCA7C51497458A6E46A24B60E84CB583305BA0A3194E74A5EFA26A1E221CD85B2CD963263C134B2768C3ED37636CE59262A1969C926B29481066C76C17CF80813AA2C30100AE0F20B3C99395E9B2B3438CDDA5857F652A646777F58B38C86EA3F7BF2021ABA4B32070CC8B40CDB7B361AE3219110A00E55249C498F499B0EFC9A67CF754833785F22E7AA1AAA43EE135195F42410FAC0F90A6C7658BE53354D81939036C88A44801707CB2C743363D1623DF1C1C0EA474521979497178361A264C5C68DFD5484D6B19B1734CF6C73521266B4B5D81872F059A22C2A9219CAB4055FD8B95661CBCE716694DE5414B4CA0AB0AB3231A896AEA0883E6A6454F0025CB79894D83179F1036378A423D55005C973A297ABAD1B7321CBB89B6875F3B9522A27C83D7716B01AA8523686B3EA5F9F3722CD715A833CBB7AAC7AE3E24F1F08474E096D31EC3B608C3C67C1340E01B9780A09155C03C7971D54E0C9C7A6265C196C0FDB8E0D6C23D549708B9C2E2E7366F146C2BBC290673030BAD304B67A6133B3B22A41359262AF706785EDB44AA6B58EF1B71C69B4C1097230B90702BFD7657464991C46C4BA0775F807C0ACC14FCA9C31FDFAAE5FE525BD9538933C843764B7FC130322235823D55637B721B20B8825603A57862064517D2DC54545A0A7369270B7B15ED2B5265A401532F4ADCFFA3C94A5B6E89660530800CD317B45522AB8CA8E3EC71259FA60E97A808FC49EC9E998DC703FBCB3308069019DF8138E3B9B69D71F9FC708EB1364E7F7C2DB73765F13A53506AD03205EB5AC5DA86B24E322898B79917753839C5A63F400547D75B426F70D479A6340278D0607C765857E44A2A32AAC4A3D324BAB221FACA212E1A9315B452C5FE25EB0344138A1B191F8044C9A4CCF0901A66C8FA56AB468BA4513E8A045C6621F22719762C37C37C6E8C5C04CDA7A02FA287A2B04BD88BAE4A94DFAB47733D74B056C7541EC992372104A470B60F20E394C6994A13932236532A74B716A8D86F5ACCAE10CF6C1708D079766A7B5760474A9E351ACD6774A627CBCF10E441894940164AAC6554CF73EFA6A7C487216FFC93939561130F107E605C5A20A8B3A280F27942F7CA353BEB66EE67A2CC2AC68CD94310E8B67D597AB33368C83179F8F8124180494EC253B395114FDCA9E27FCAC8C7A0B1AE40D31581946C5506B5063E2050D0CCB6AD713024A9C4D08D09D211486ECD371F5033C8804C0531180B99447FEDB91181C327DC000E7159C1634013EC00C03C4C5ECCBA79DD138F20B4975F27946566A629A4819E7C77EE4625CD91C86615AD1A876E7045196E6C09EA22439751304D92B9C2B3C9BD32A6CE010C1BC5608245B76008A58A4A4C9072EADCA4AE103B63487366D130A5135C18FC4C6766CC8E06B988C51AFA6D1CD44133ECFD539BB0B8CE92A3FDD36127B9C03259161E8441A22F0436F9B1A0C57BC8BDC06371078A2C9548442310B4A5479F0054ABC375E75A1D170A949C91865326A76768A2F117CA524CA8047B26F7416FF677DE0BC07D518C5F71686DD544823DBB9622706FCA2A2112472C352B6BBFA0A3A7C2280CC85C35203A6DBCE3D3C4E8F9C1D454C730192968892BD257CBFC06179EADA01362BB1D1258E9F1BB563565535908803822969B3B2A21633390961891A2DC436B55EF392F0379EC484967A9068E99BAEE1F461241070342221660101651B2A2FA896934141DBA9B905E8C309F8981CC5B080C26CB585090EF97C4E01B8ECDB7F5DD88C4F8B85765B7908256D350898450C3592526E6A99B504A0D3D19FF79680DADC9890E865104DA28FE012506D19180565847F52D9587DA7DD37F7AE07BF1B9D4C94F03C702351FB4C5AF4200EFCA07F38EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF" - }, - { - "tcId": 42, - "deferred": false, - "z": "26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294", - "d": "DB4ED8E9C3E1AC7A35EA4B67A4EFCFB46972A984D161F79F084125D6D4AEE7AF", - "ek": "7BC585BA01AEAF899394E3C00223562CA2163F977AF21CAF967A9C174B3719B097C440A60C5AB746683F15294E4CE40031F16A6FDA79C608095EEB6945241B25A77DAE55CD95161C94836940C93665D669745A013013875A722FF1B285047C9270687FBF2310D1510680406C70CB97A65CCAB59AC6C80C4937810A2488BA8C37C6CF022E4FC14135D2100B613E3BECC8D74261C0912683067429DB79CAA56469CB537E432257EC2EAF370590613716C64FDA2A0EFEF27727E5A437000C9145919158BE240B426E63AD426018FD3271D899846E6421277C511FDB14CDF1B16C48B99080B6FA68BBFB4C02DB837C65E6CB02235412AC3534FA91AAD35DCB3AA773FC2A050975ACB0C7928201636A7920F46DADAAAAF9072F6B23B138669BA4C9655A660F3911AEDF97633ED966CD1253CD7B947C09839CA53AF33B80A370AAA43C1ED6D26D64981D756060A17331A3D4B452FC34F186986936C2EDACCBE0629DB60493BFA49451D44BDEEA1D6605BE945625654A6A6C13943B2972D0A95CC07B70196579ED9013B8CB5BEC81AA61066B5AF6673B3681B21B65905C1E44B808B1995819B211D0BA9D4AF45E6C030D75D2C63E77264BE92DDBE1B54BD54060CC4E8A760DDC124EDBBA6DD8910922D18222AC42D802A1A377C0979B3D9CF8736ABA7EF223413E6712FA523716DC5A0C41CC3CC462C6FAAD0CF30674EA8469A06B1FFCA3D6E3AF0AE95689C70F3325B3BD6C3158BC36014B836F908D91269FB5B05CE6075A80D4A70562572A64AE090C9C39DCC5C6197D84C62752E30DF9A49657DB5ACA0084393A25C6047E629151C8BCC3C4897CA2BC8BD3EC4115B8230A155C15775C7CB7A3DAD6560E6798C57A607FEC8DF6493C24A11518280F081BAB5359AD5468B1717560F1E60273518ADA29819E11679D16CD20514EE44989C62582B0E79A1C09997CE67B9E46850F294BA940C7A6668B28EB6C953C81F50C2B94F14A0DA76DE5AAC603395ABC8866B92B88890B120A62CB06CA8F0F14806E19A794F73FDBB1A9638169FBC30BF4C764F66475395515683C9CA4E587312B4301547C25B58108408E64D6BC0A6B9BA8A4CEF76649290A185BF25DF5C14B81F633A399325380A91B5C2AB21399C4C88597202A50A966DDD8AAFD4A2A831897385AA5E19480437B5E1EA05F778BB8C616391C2766F1DAC500D1898AF957E022202C33BEE93001F7E56B0589C25DDBC5CACBBDBBA308B30228C5108019280812925E395329D3A72B6566694DE690746A1B244AA21B879E54590A4173197C2C930E683F645A83F6B288D3A48D00A9CA97180AEED5685691B8FCA95ACA9136EEE892B5F46CBF60BEE6D803DDC05555349D4FD1AF405C78D6B86E56C12A26657832D753B9D901557572E7960EADE5A9110CAD2C1353A415BD119BB8A42924B0BA004ECBCEBC430F13B33F82AA1D4727CBD8150F416A14AF1A6CBEE094D0EA963CC4C814E6A9CF097DF9B9BEC7D9B68D5BB23F767F1CE88FD44B5539F80F2EDA4B887576107C725A3A5D80240397907AA15842A400CB6200325B1542E268BA3C054E350364C836370DE786E5077EBB4B4C8961917870019C7A4794D27E332C14D26B6BC02202CABC83B8E9E01A155B3D735CAB97C80992BE75623F2B79E41453AEF4A09F6CCAFFAC73", - "dk": "EE528DC327151C18138C507974649A95121F768132E6C6647F2A193556C06040C80058394883C01D75763041146349BC8FA72E57BA7069656B2D138B85784C79B11E70025D5F3558EB8BB418CC8BEA139310F850F3557FD56A10F0D297BDC0C0DC3B4916CCCA4A419B5DD6A8F8F6B0F1AB6BB2B606C73AC36C0C93267A19B7C7CB82AB9C96CBA726770C5475A6B889CAAC178B8882BFC236CA32197523E95112697F7B75248B3C12F132B45535CD55E274706242A69644429A1C3BAB673B580C7DEC34FF7379AD073241156477D1798D1AB09AA5C53EF195E65A7C15E5569781A9B06376F77337A1E56506C785F5D4C95FE05BBCC736685370648A90320C059CE45E55841F08CC8024C24C473646B128451047B44F1C526FDC4B8D862DA60A97AD91CCE133B5BF7C70CC0A23B458380602882EA2741440CF05B1C960699C8A404444A19345F113DE341279C11B58A7BB6B903DE6054D55DAA4A501741E6953739564770205571CC93861A9D5D785F273338CC90432D00B64A488B023AA5EEAAB0543CB34916B55A5CD69380A330CC194640D41048745FC74CAEA0FC8C95A03FB40F701B763E73FFF6B1C8D2434D2646BA3C870C0A29CFA45A880380F6675CA36AC1A86C57C56A16BC6E5A9ABEC7404F86209B3AEC736A8E436407D2476CECB799A880AC8AC33A3F58C68CC047480BF85258B6C1C159B01BEFC73B7BE506BF75C67DE85893DD2425C467B2F627971925FBF666B80DA59DB285813D688916109EFD2951995953BA729DF127018B7043AA3A57BA33AFE2782F8F319C754C4E91780B446C4D3360A824223657405EA34AB1DE6181C702AD100CADE0380BE942EDB51A93D1A0A884308352CB2D93B920F1B467FC306F6A6AF9E41334F861360646CEFF6770BC1B7211A1D2B95377546A0AC4BA431F824A1953BBAA8BC9CD66789E55EB2C8CCBE4B51233C2578B8115061276B48651B63097BE21BE45868EA513F69B91F6455CA569C1C26317E0E1807C7B7B2D4D43F16958C2BA32CE0585E2DD1991B357C72239817B0484B3258ABF39988933710528E82F11BB8E798CCD5C323DAA16C9C0786C1C73AE396946A0EEDE43FC7568C98D056A1766AD702B4F6478CAC056410FB9B95A9427C32A87C84BE3C9A21C0CB46567ABCB3D1CCDC3B8ABA0A1BBF18A6D23474E3659BA696197E059B6F536523E60C0C69314A12312B37CE51686B5CB742715BBC4F241ED12B342045BA69010CBD24597DA695A331C4B8E7C693157A348C9E16A0A307900D86A032E08B5E802A29842C13DC7509D432C5AA7B679BA10BD090CF9FC086E0C5C2AAAB208F39179E693645672123D894EDA35C5E32031DDA9DF410C32F72BCA22B5645E7A5A9C804A45BC67A861A6FF5C821D9CF79E6BC4D8386BF77AB31C6BDA9DC6E99866B5E43193D9210A790CAA629BAD25304E6A946B3D87235CC39F5B66EE8B4C6EA73022B867C6CDAA133A0962579612C8CAE71BA151754B4862C7193994934F04FC3BB2C20A71CBB6962C5D16224D1719555143E33A0E70B79A2D6134CE0BA1797C8A2F98B71882D5BD214E73A950C849FEA2006B242B83F5C8998113BD27C01C3276FC20041ADE77AB144CBF6368D45C18C7BC585BA01AEAF899394E3C00223562CA2163F977AF21CAF967A9C174B3719B097C440A60C5AB746683F15294E4CE40031F16A6FDA79C608095EEB6945241B25A77DAE55CD95161C94836940C93665D669745A013013875A722FF1B285047C9270687FBF2310D1510680406C70CB97A65CCAB59AC6C80C4937810A2488BA8C37C6CF022E4FC14135D2100B613E3BECC8D74261C0912683067429DB79CAA56469CB537E432257EC2EAF370590613716C64FDA2A0EFEF27727E5A437000C9145919158BE240B426E63AD426018FD3271D899846E6421277C511FDB14CDF1B16C48B99080B6FA68BBFB4C02DB837C65E6CB02235412AC3534FA91AAD35DCB3AA773FC2A050975ACB0C7928201636A7920F46DADAAAAF9072F6B23B138669BA4C9655A660F3911AEDF97633ED966CD1253CD7B947C09839CA53AF33B80A370AAA43C1ED6D26D64981D756060A17331A3D4B452FC34F186986936C2EDACCBE0629DB60493BFA49451D44BDEEA1D6605BE945625654A6A6C13943B2972D0A95CC07B70196579ED9013B8CB5BEC81AA61066B5AF6673B3681B21B65905C1E44B808B1995819B211D0BA9D4AF45E6C030D75D2C63E77264BE92DDBE1B54BD54060CC4E8A760DDC124EDBBA6DD8910922D18222AC42D802A1A377C0979B3D9CF8736ABA7EF223413E6712FA523716DC5A0C41CC3CC462C6FAAD0CF30674EA8469A06B1FFCA3D6E3AF0AE95689C70F3325B3BD6C3158BC36014B836F908D91269FB5B05CE6075A80D4A70562572A64AE090C9C39DCC5C6197D84C62752E30DF9A49657DB5ACA0084393A25C6047E629151C8BCC3C4897CA2BC8BD3EC4115B8230A155C15775C7CB7A3DAD6560E6798C57A607FEC8DF6493C24A11518280F081BAB5359AD5468B1717560F1E60273518ADA29819E11679D16CD20514EE44989C62582B0E79A1C09997CE67B9E46850F294BA940C7A6668B28EB6C953C81F50C2B94F14A0DA76DE5AAC603395ABC8866B92B88890B120A62CB06CA8F0F14806E19A794F73FDBB1A9638169FBC30BF4C764F66475395515683C9CA4E587312B4301547C25B58108408E64D6BC0A6B9BA8A4CEF76649290A185BF25DF5C14B81F633A399325380A91B5C2AB21399C4C88597202A50A966DDD8AAFD4A2A831897385AA5E19480437B5E1EA05F778BB8C616391C2766F1DAC500D1898AF957E022202C33BEE93001F7E56B0589C25DDBC5CACBBDBBA308B30228C5108019280812925E395329D3A72B6566694DE690746A1B244AA21B879E54590A4173197C2C930E683F645A83F6B288D3A48D00A9CA97180AEED5685691B8FCA95ACA9136EEE892B5F46CBF60BEE6D803DDC05555349D4FD1AF405C78D6B86E56C12A26657832D753B9D901557572E7960EADE5A9110CAD2C1353A415BD119BB8A42924B0BA004ECBCEBC430F13B33F82AA1D4727CBD8150F416A14AF1A6CBEE094D0EA963CC4C814E6A9CF097DF9B9BEC7D9B68D5BB23F767F1CE88FD44B5539F80F2EDA4B887576107C725A3A5D80240397907AA15842A400CB6200325B1542E268BA3C054E350364C836370DE786E5077EBB4B4C8961917870019C7A4794D27E332C14D26B6BC02202CABC83B8E9E01A155B3D735CAB97C80992BE75623F2B79E41453AEF4A09F6CCAFFAC7316161113DF646837A28818D9C34EDAD57472944528FFBEC6B1BD204262DCA04F26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294" - }, - { - "tcId": 43, - "deferred": false, - "z": "63435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697", - "d": "C6EFA7D5D500E5BF857D80EAE2A6EE6414159947FD4BE589350724FAE5E51805", - "ek": "B07C141713A0AAD60845A07EFCC54C4DD073348261F7485FF93CCFA7000967A24E7F03BE00D4C0AAF13995F2C19D0C92B3F372D75802891B0A97E78917301D429B0AF9C7693882024AD301C5B1448474BD2B39CBEB18332CB6252FA7920D94AEE849C10A907B5FC827B94A58E37378161A4407647D025B590D1A1C50880B2DECB17774B22D3139445588B9BC93F7020FF6A9959E9A04FFD15669F9A8CFD412EAC051B940B2ED02561A4B9F4B57753423C10DBA0587287D9DD068C4660138E6C3EDB94664797B1C702D9D89A1C9D086C1F7A21238B4A22A8F6BE9075D0B712F4567E55C0CC1BB4788F2A693D6088D36331350B3969B66C35CAEE9A015FC80CCCC556F1C034431FBCD2796BCBD9347B39C472B27CC8F36468BB10D4D1767AFF24C33ACB86D7191AB359903F43E73DB80B5F39AD25933E0645013B2AD56456081495B7036B28B652F577C1D251CCF45D3BEA72539D359B94DB50B150AA5D4E56FDC91B2654A4367C650E3E1310B72403135C185B90C5005A0FA11C569FB82A3DCC71AE774D97B171987B9D128516801B9A7D91FA6DBA6E5341A0147963BD29415E90DDDBBAACB242056E487724285BE3756C37538D60BCD7DDC44FB25AED0C24CAA663BD650CA4E806BC8A259E9794AC4642447F225BE560B541BA90C227629B2ADA4245D83E41117A095874CB676144782439CCCE1893D26B7D427CE0060A106903891687C17D636CB865EBE4C28134885CDB7722D84B0BE41638D5A14E18023191B35AE228C1EF92914A505F93901ECF598E5093E31A41611F6726C42A96DC2200C5178CC320EEEB8B223C8746B72847F9B586A229929A3B5617A54F6E56C6CEB018AA0B02DA6CBFB1278015B68BF15BEE2F223DFE4025349ACBBA505BCF592623C6D3FA975AA661E74948757000CB476757B732F8647C4F8C431C85975A09BAA591B95CFFA3D89FB3AED59330164510A303609D0726BF63479116AB2EA92DB8B89859C82D3A0966CD5348BE479AA15B6BB395165777515688D172265C7018D08D59F72C74A682290CD771C557018A686CE1B3451D6AC0D4149BAF16C871779031BBB9C4E70C9602B38A82200D2D251C5B22C60CAAA98FACB66CC3DF2A3770EE282A9DC328658A2D582B894DB7B5EDBB63A7B90788786072698C2904343A1B9F6DB107E5A6CE1129A444B3DEF542E35728F080294330343B4843AFFE144827499539B0C79B2CC29961158F61A20502BF3BB38A784BC8A673F3E680C5F8406056A035FD1A3A5E445DBAC0282E1B7885A891BFB367D236AEAD15E4F5B5CE26A6ABB4840DD177000806FA066380CD381D5BA64CBD3B048D60CCE49975EF778C1F8240A1484D073CF3B5625E23A0E02D22875465687987FA6EA8D42C5CE28443BF726551F6CBE108732DB119581CC9CFED76D6D1CCC5FE132A9B51D6D4723FE2B64C70B65F7DABB8E71C3A876545CD1AE11B835C1FA4629E69DE1D489D085575FC3A677585CA06C594FFCBD17E76162366092C03F2AB951FFB012E89446F047A4925BA350AB51C1526FD79A853B2273C2B68A590816CA0536C4C467D0918DFED84230E9AA89063530204F096B6E18C29381CC9CE4BB391D6312AA804E84B9170E59272C4835BE92CE2AEE6D55F2AF72FC20B0DD71E5A81C39766E3BD54B78372F1C6A", - "dk": "B4FC40D80B09DECC317933826E7985C4E074C65CA16B6C7184F30CF1AA705ED7CDEF878624007ED6017BF9D4170C20928A71388ECB8FD2906D612525F3A8139261419B1799040BA0F5F29BDF683E1BCCCAA819A65FD3286EA55B98B3B0AEA03972A0988E352112F0984E64A36760317EA9BA7267949BB02423D5A53EFCADEA178FC568464859BD634259C6B8AF7C2BB9A462A3F0BB66A15B2BF0956DD7829DBB2BCFFF47A40AB487E5D76A57AB71A2AC6C5B651597F631F37A9EAAE10E42D4588711B1CCF1331ADA44EF532301900A6BA2764721C81B2ABB3280672386BD64D52356737055EA8F9409756A03A5E0B410EBD4463FEA79ABF65254957447B6BCB9989F733BCD58E8CC34D74500DA128247264E0253F0EC811DF199DF1298F87A34710998045BCCB5205441EA20BFD776EC02CC70075B272533C011A25EBC541CE65B54D03149A4C04E950834D8A33996ADBE386411D168C4F735354171B3BA908A208B8B0C8DD95113BBB301D361189DA703372A7458337027C27682C04A0CE6C0C0098CAFE1594BA01787568B944C58BE9A3EE4600444BCB15376648222C167FA317866745D2495D9B30522C830B6C447F935A38588BEF31CA014C5106402933B098F8432938A1267ED4BCCBE24B4CBB45AB3317BC60C8525FB21AF8B5C35546D49A41E35ACC7B24466E1A7B7138A045BCBCB2D98C0EF242C5762CF38EB29A61AB7CCDB94880710B9E7AA0366AE25034BF131012FD0AFCF211312066A667C3739941BE616B3EE1139D890BF4CC499E6720BD00103B29A05E5B993C6B89E281760B853418A2AC0E6A278A2D2C3A213514D486D2B01AC73A8C21A01AEE891A324E2AD45338431147988799FB8D6AF44F62BC386431F3C664E9100B3E4B86B195F31125D58DB59E7858F45506CC5EA11A9902668601AF0B7599508AFAD51799C389BE4C164691515F59C4D02A2CA092A3CD06181C804AC81A651EE142866B563089BA9A6B459DAA746DBC0263E04050AB458FA97682566C3E4949ABA5CB3DE8548AF3BCE2A253F8043C0EEFC96E3E83CE3A427FAC302AEBB2AD104454790BE531B77604A910640313E5CA5EDB6AD8729AFF6C37705E2BDBC9A9917D36B1925AF45A22C7EEBA2C26544FE5821218A19207990FBE4881FB8B4CA76424FF9022C4C61D680B0F1F668B537103CAB1E1640396050CA524465A9F80221B8A3CB8CCA8979B7C85A141E26649C26BB3DF4666280961CC72060814FB6720DA96979F7E25C4A68588A00801A121E60F217D565460D7C1AD47BA858585A7EA696AFC91544B533A7D86AB68C7F81856F03135912BA1D0F69AA73921C0EC87E8B770C1C332B378A9387C0BC64A64D4FE6AB5FEC50CDF41FEA9883BC44A9175A3DFC0CCAFBE434881CA7E2B53A825ACA950AC2050B20D1FA9B36536A34E83B860850DC90B9568547B7246A115A9394455818A2B081843CBFE129D0389CFE27B192673E13C56B9FA38E99784CA5E1CC0529960534C9AC2497524948C4401259B09628A605FA659661C96CADE04B82894116931C63207F6B46675E14549DC767291B579BDA32B6EA16121B97C19BB4A90287C9B6199C904DA6B6A1278BB7A7B77405A9696493A45C8C27B07C141713A0AAD60845A07EFCC54C4DD073348261F7485FF93CCFA7000967A24E7F03BE00D4C0AAF13995F2C19D0C92B3F372D75802891B0A97E78917301D429B0AF9C7693882024AD301C5B1448474BD2B39CBEB18332CB6252FA7920D94AEE849C10A907B5FC827B94A58E37378161A4407647D025B590D1A1C50880B2DECB17774B22D3139445588B9BC93F7020FF6A9959E9A04FFD15669F9A8CFD412EAC051B940B2ED02561A4B9F4B57753423C10DBA0587287D9DD068C4660138E6C3EDB94664797B1C702D9D89A1C9D086C1F7A21238B4A22A8F6BE9075D0B712F4567E55C0CC1BB4788F2A693D6088D36331350B3969B66C35CAEE9A015FC80CCCC556F1C034431FBCD2796BCBD9347B39C472B27CC8F36468BB10D4D1767AFF24C33ACB86D7191AB359903F43E73DB80B5F39AD25933E0645013B2AD56456081495B7036B28B652F577C1D251CCF45D3BEA72539D359B94DB50B150AA5D4E56FDC91B2654A4367C650E3E1310B72403135C185B90C5005A0FA11C569FB82A3DCC71AE774D97B171987B9D128516801B9A7D91FA6DBA6E5341A0147963BD29415E90DDDBBAACB242056E487724285BE3756C37538D60BCD7DDC44FB25AED0C24CAA663BD650CA4E806BC8A259E9794AC4642447F225BE560B541BA90C227629B2ADA4245D83E41117A095874CB676144782439CCCE1893D26B7D427CE0060A106903891687C17D636CB865EBE4C28134885CDB7722D84B0BE41638D5A14E18023191B35AE228C1EF92914A505F93901ECF598E5093E31A41611F6726C42A96DC2200C5178CC320EEEB8B223C8746B72847F9B586A229929A3B5617A54F6E56C6CEB018AA0B02DA6CBFB1278015B68BF15BEE2F223DFE4025349ACBBA505BCF592623C6D3FA975AA661E74948757000CB476757B732F8647C4F8C431C85975A09BAA591B95CFFA3D89FB3AED59330164510A303609D0726BF63479116AB2EA92DB8B89859C82D3A0966CD5348BE479AA15B6BB395165777515688D172265C7018D08D59F72C74A682290CD771C557018A686CE1B3451D6AC0D4149BAF16C871779031BBB9C4E70C9602B38A82200D2D251C5B22C60CAAA98FACB66CC3DF2A3770EE282A9DC328658A2D582B894DB7B5EDBB63A7B90788786072698C2904343A1B9F6DB107E5A6CE1129A444B3DEF542E35728F080294330343B4843AFFE144827499539B0C79B2CC29961158F61A20502BF3BB38A784BC8A673F3E680C5F8406056A035FD1A3A5E445DBAC0282E1B7885A891BFB367D236AEAD15E4F5B5CE26A6ABB4840DD177000806FA066380CD381D5BA64CBD3B048D60CCE49975EF778C1F8240A1484D073CF3B5625E23A0E02D22875465687987FA6EA8D42C5CE28443BF726551F6CBE108732DB119581CC9CFED76D6D1CCC5FE132A9B51D6D4723FE2B64C70B65F7DABB8E71C3A876545CD1AE11B835C1FA4629E69DE1D489D085575FC3A677585CA06C594FFCBD17E76162366092C03F2AB951FFB012E89446F047A4925BA350AB51C1526FD79A853B2273C2B68A590816CA0536C4C467D0918DFED84230E9AA89063530204F096B6E18C29381CC9CE4BB391D6312AA804E84B9170E59272C4835BE92CE2AEE6D55F2AF72FC20B0DD71E5A81C39766E3BD54B78372F1C6A0B2CEE55AB09D33BEBC1119E3D8268D321CE675CA8233E6AEE598C7652298B0163435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697" - }, - { - "tcId": 44, - "deferred": false, - "z": "8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709", - "d": "20859B01DFC60B6109E0234F3CAC7A247D8386099D83D2D447E9A21AF9DE48BD", - "ek": "33C5396C96C17503A1F0D509FF56A842767B24B4C3D2C080D428090E61C88EFBC69D086B83E56F5F898D99EC04F588567B2077B0270BBA8263132C7690645D38AB584C9773AC35389B88C67E34424E003AE741521545039E1C3D2BEB4BD05674A700C150573E0781CE8EEC7D2AD17F2D214FFDA22BE21A55A9570488108B0A555C6D225A521045F6D002F1B330588049FA6BA2D79B552285542BFC3BF3BCCF76D922E7AB9039189A66B76D58D9C82443A32DD26A6B134DD3783EE3480018B04DE6D9561426287C9A8F35ABAFBFC9CFB69107AFD639E9C622A3DC19D0D19EF2C4394CB10E0F519E9C8A9A40F6C33754279ED5C1DF06B065B4760453A4CEE04C67E571565C82D5882211361B0D15C9C0F8A75892A2F1A79673CB31BFF12EA352A484E6CC82B44D1C7C20EFD72F112CA0C25450C672BC34C2B8ABB84C52FAB5B0C66FC2288C48957664ABC079296401C3A470D6BB0D6B231A591ADB1763EF1C522DC95DD4E47728E5BCCBC05A73D7C856309DFEA90E25B7A4ACB4705FD29715441565682620F992034A0DA861C51873212470BEAEA6096B737235CC2C94165723495D7EF43C6327AD9ED398EDF9BE0A29B83D595AC8C46A374B4F02C4B1820095E223092498503AB926B9302C948A439539ACF3C31E91B50190980BAE4411CC652D3108302BB1C4376975AB510D12642A3098BB7FA5B6C14354D6D490FB247FD9C1BF83D8C4DE9C7DC5D58780115D7E0005874BC813B40A6B6ABD1C802C9ABA01A9D893EAEC7EC3AB011EF44AC42154AE40066A72159A9015286C2115213921AC3182372236E7059D6A352626A6DC0C1F7A728FB35A34BCE2C7FBD0659CB6496CF57455E7034E979DF8F134AC398020F153D2624980625DB9AC24707ACE0D7490335561F8EB5CB0468F88DC934B4763846535701B3671C53D30038CBB2896426AA7460338266160173798E36C0C04FA70FF68A56F52A65379031F2565CCF30929A948A6C222D610BAEE964A32C2BB4AE389C7F85ECD0BB733BA1798BA347D142AEB482AE9200B9B4C589264B64A915B3158401B343AACB256D9E8CA942A9770AC4652066B4E16414C78152C3C1D123C2057EA4FD5A511CEA8B3CAB25B9F4258020144924878CED8ADBC9B4409F34DC1F87ACC4165A0F92A8EB364F469751CA87EF9B87B9674CAD2B8628966C7E7D6BEBDBB0B4E6CB51D017EDE9735CD3C3F12B83BF9651788ECCCB2D9B237A330B13B516BB40BD806974528AD133C8E68D839EFC852F3F04E960102E8A58B40615E3D53152C528291826216125907E352CFB53EAD5A33613AA78ED20F9CA3437FD3615980AC118963C8482AC806CE6237853EEC6FF62657A2B19EB6F8678722A06C2698FD15085ADA9222D211A86B4E1BF007EC5906704A69289A8E1F6C4F49A5CFDB90C13BE4771ED4641CB4987BDB80B09724F9A9982AA27AEBFB69D984A5CC04BD94D335500359095214616184993A37EB0422A263ACBE53A6DF5B316378C22E830E2A968661A840C09ACD6711507DA822FE9749DD4C522CD11CA2E57B225BC2C398BB05A975D7E72EAA2BBBCC6CBD88721CCC762049A44A70926778340F5FB7296BC33A8C010089011CB947C5B5E299D0DB66C9C89C5C3581222435C5EAF79EB6C152255ACF9BDFF03781400C9D599A905605", - "dk": "7C63447D4668CBCB42035803A4C9350E38AF8EA8A6296658D7A545B40215A2E7C70AF7726D32CC4B7062509AB15F776E1FB812C22062ECE079492900F0B18DB3D66B4CB2B871766145E237C51023286700238537DE2187A5F45F7671027B88A7CD372A54621D52063705E1B4C07786360805E8CBAA60D9AE953708C201B70DB39DCFCC88FAA2C0FF855C30F31D9C7193616333AF72C382B92DFDE56F48E20689C2C61E940264027923980ED787CD98AAB8476C4C7511A9EC9C0B08D9523D61BECDA2054E1B01B90947AED40961C7A7FF6BBEF64156B243159E4B3D343363DBD58B2060505CB066A31C629084B9E658425BB28D84642B1E216BED180D688415C81C2BCA4A49354709F4ACBB16B8AAF8263329314818FA98FCB7139E673AE702706D3274E020BF469C651FD5A08E6086F36C6451D00ACD94CA59248FD35C91CCD856056439AF18580C066C34DCCEF1C9700DB7C8206384E25531BBAA39CB3760FB346FF8F77DE85461F7198E8C396AA8CAACB8A42C37B1879B80953C1257E82770F098C4896C76A506B8605742C58385DE754797833FD1E08D3E5B45AB828666F15608B6C81DC7166CCC678D1CCF3CE5967B57ADD583C1CCB089C02CCE05B15F810AB3A43335BB0041F0699302972E23A5C229A67578AC9D5B1061CE5B59E72B81EAE01E0740490D84AF88EB572810CEB18C17008308FC860C65B4C1B9065DF9E2C37DF9AD096C96AA0722B19106984A24804ACFB36A9925B5A32D2019E933C54579959FD536992327BE519CD03190CF9595DC5303D4A24AA7D604FCC7BEFEC4C244E7836F63A876073CB757A61B919973696BE0EC1CC15041ACDB2CD9077E15C66FDDC9343CA2A2ECCBCC3FD2319C842F0099969FFA5DB4EA416DD83DAD971197785A5C3173981700ACAC5232C626A5C52B7AF217BD45A555C4898231B256866098518CA1D379822CBEBA148412A664E5094D24D1B6D77BCA7FD176B88856659B9E8513A078A1BD07781FAF1A697A7778C2B8A4A8A0CA48FB0AD8A03E39F7753C742CCA3911B948167DCA397F935BBE0CCEB9D1AD173A8A64E318F9DCA501B031C745939DE94CDAD55722EB2F022495C063259268CF5193B486315083F3B43997C732BC9DA99324252CB503F409340B5A64E74C11733DF256ADB10631C3C002B4E46C340BB99AE3246E794ED09A5524A742DA01076A78B967BC9204F764EC61B528E97176F92F440252FC1838D187A8ECD821E996B5239A1A0F320B12F11CB5C446001D6D765CB11C4A2B24B41F23894A9945B27902A6433CC4BB5B9AE19637B5E1BCD52A29745693F5742970606A89DAB78CCCB61EEA78B0CA49D678C2477B036C48C3D2A514005459728669F8743A23A26865B04A3AE930B6E9C67148A5A2A3643DE2B837610402E6039319969CD928D39794E1311739C0780A393E076C2DC89038A10C1079275F765CCAA064436BF5052051476C1C3BD4167739E2CBE63545148350CAB4134825B2C5D27A68524BBD937957C40F1C00BC06D677E2D5527550876BD7CA3F036DC0B5625F3976BF63CDA2E9B2FD4BCBBAEB911A01B0D3716CE5369F18A285E4BCC6269B407D42A7BDBB88D724C5AA6188B9716BA3D3A3B962A933C5396C96C17503A1F0D509FF56A842767B24B4C3D2C080D428090E61C88EFBC69D086B83E56F5F898D99EC04F588567B2077B0270BBA8263132C7690645D38AB584C9773AC35389B88C67E34424E003AE741521545039E1C3D2BEB4BD05674A700C150573E0781CE8EEC7D2AD17F2D214FFDA22BE21A55A9570488108B0A555C6D225A521045F6D002F1B330588049FA6BA2D79B552285542BFC3BF3BCCF76D922E7AB9039189A66B76D58D9C82443A32DD26A6B134DD3783EE3480018B04DE6D9561426287C9A8F35ABAFBFC9CFB69107AFD639E9C622A3DC19D0D19EF2C4394CB10E0F519E9C8A9A40F6C33754279ED5C1DF06B065B4760453A4CEE04C67E571565C82D5882211361B0D15C9C0F8A75892A2F1A79673CB31BFF12EA352A484E6CC82B44D1C7C20EFD72F112CA0C25450C672BC34C2B8ABB84C52FAB5B0C66FC2288C48957664ABC079296401C3A470D6BB0D6B231A591ADB1763EF1C522DC95DD4E47728E5BCCBC05A73D7C856309DFEA90E25B7A4ACB4705FD29715441565682620F992034A0DA861C51873212470BEAEA6096B737235CC2C94165723495D7EF43C6327AD9ED398EDF9BE0A29B83D595AC8C46A374B4F02C4B1820095E223092498503AB926B9302C948A439539ACF3C31E91B50190980BAE4411CC652D3108302BB1C4376975AB510D12642A3098BB7FA5B6C14354D6D490FB247FD9C1BF83D8C4DE9C7DC5D58780115D7E0005874BC813B40A6B6ABD1C802C9ABA01A9D893EAEC7EC3AB011EF44AC42154AE40066A72159A9015286C2115213921AC3182372236E7059D6A352626A6DC0C1F7A728FB35A34BCE2C7FBD0659CB6496CF57455E7034E979DF8F134AC398020F153D2624980625DB9AC24707ACE0D7490335561F8EB5CB0468F88DC934B4763846535701B3671C53D30038CBB2896426AA7460338266160173798E36C0C04FA70FF68A56F52A65379031F2565CCF30929A948A6C222D610BAEE964A32C2BB4AE389C7F85ECD0BB733BA1798BA347D142AEB482AE9200B9B4C589264B64A915B3158401B343AACB256D9E8CA942A9770AC4652066B4E16414C78152C3C1D123C2057EA4FD5A511CEA8B3CAB25B9F4258020144924878CED8ADBC9B4409F34DC1F87ACC4165A0F92A8EB364F469751CA87EF9B87B9674CAD2B8628966C7E7D6BEBDBB0B4E6CB51D017EDE9735CD3C3F12B83BF9651788ECCCB2D9B237A330B13B516BB40BD806974528AD133C8E68D839EFC852F3F04E960102E8A58B40615E3D53152C528291826216125907E352CFB53EAD5A33613AA78ED20F9CA3437FD3615980AC118963C8482AC806CE6237853EEC6FF62657A2B19EB6F8678722A06C2698FD15085ADA9222D211A86B4E1BF007EC5906704A69289A8E1F6C4F49A5CFDB90C13BE4771ED4641CB4987BDB80B09724F9A9982AA27AEBFB69D984A5CC04BD94D335500359095214616184993A37EB0422A263ACBE53A6DF5B316378C22E830E2A968661A840C09ACD6711507DA822FE9749DD4C522CD11CA2E57B225BC2C398BB05A975D7E72EAA2BBBCC6CBD88721CCC762049A44A70926778340F5FB7296BC33A8C010089011CB947C5B5E299D0DB66C9C89C5C3581222435C5EAF79EB6C152255ACF9BDFF03781400C9D599A905605EAFE2B26CB96B97C22564B28329B64A206331FF842BFED4ADFE3C7A0C4A471BA8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709" - }, - { - "tcId": 45, - "deferred": false, - "z": "EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7", - "d": "409E9F3AB58D736E122EFCC4240BF8388FDFDA6759004D42457018014A335BE4", - "ek": "E74A4568457E0C7727A53682E50CBF74082F01C9892F60B9DC57C79A82123703A8375C7EFBE299FC3352584CADA79726D8F039E7885508A897B9C54EE4478568168820DB7FFD82CBD0191FAB477199AC0FFF615475AA96E28980888B34A1E2C76115CDA09C2E1AF83FD7004DBD14AFA76773F755ACD40358A774045B09075703C2C08537C9E09727E23902CC453965CA74F9CDB865A02E228BE92850F078596F64841D093BC7BB9354E50FBFB31FD463762B800B88C6A691F22A815B46EDF848C174108DD7435F178B90690D5C8B0C430935C69C6A4451629958614CF00F5FCA7E88C08230E142C26C991F5782C1BB84A6C8750EE00348582F12365A761150B79489BEF53BE9BABB468A7F72F65B2D70068D5313D5011016CAA97C6961C554CE6419204AD28A7E5A7E807333DB1C759B6A546B087E9704B63A573752A0ABB7C702548CBF15100F3A6A807C016687C05058F76A42BAB1BE88C12FD574F4FBC051DA21234806FC279D122A4DD879175DC24E20570B435A14FAB908CFA5AA91A009164530417655799C0B379A10E7592EECA96F7AA84F9D718B95F595BF5887F2135D2BB106D599AAB77C5DFD5B4733506450923815F451EAEA6DA2FB0EF3C7AE6EB12543F8429B7B1BA00C5B05585964D334741AAAB7B2C787778709D2CBD9D1C42A061398939869FC0B21C37FA1A146965066C50889C5798B3EAACC0B5C6D7721CEDEC86BDF67A17BA37666A4226BE80EFEDC5262373117777B6995262F795735872B5CD4B52A59677B3ABFA302BA89E61DF76866CBF5C8F97C2620258570735C9B70265CB9AC98445416A6A1AA8252F89667EFE277C968101C58ABEC009902497D932C0D33F52C69221F96EB589E231877837491757BF2B05BE03C909AF3B780B8088F75610A02C45CE28097AAB34FE19CF364A865D77A9D402501C843684C1F7825C20BA3ABAF711172024FE6CB6F58591E4EEC4E40CC0CA891725927C56A55CAF5B1CC61F510ACCAA54371085FC9B03C169293E16FE74735648B4E752847CEF130A3FC031BE4C04EEC8614A7749FB7B41C2C69D2D23D73F205575655BD6A0F3FE19CF333A0F28A9BFE69B0DA112771EB2BBC30586AB0BC0176A400345986104F0832CE81A60E198B3180840A8BC528B0960CD2F26564D3797BE64DFD602BEAD0C94E1904773BCCD0162F0A17B3B4868B5CF57FCAD264E3F339C6E240C2861C6B6A0429616D88F5B41E991491652852441817033DD8F95A4B7C40EC5A74781A761D8ABEDA618D53D2CD86989AFCC54E5ED2CE26F8244E0247052364B0A11F42DC14B6B8A72ECC76754208560A479C2C104941404E22C800B0BB52E26449238235F113A23C4E46AAA4E54B6B7CD2A3802A2EBC3799B9556FB0164500C14CEC67BD36C31971291EE891134B9CB3E2DC01EF15143AC04EA1F41D9084B7B2EB91F96B7C9A97774A044E037285C820601E424F761BCCC712172B774FFB900EFF1158D6EBBE13775F27720FADB93CD98111E4E2788D86C0151B1458344025580C509738E490874B773849308B8D36C649373F9147781D58C31938B923218BC2E85F4C9B1233BCAE99D35C67DB3A85647801260409E6CF45924E4DA141B6C3A65B857A3D3DD5F476EF377E54214616593BC8CD4D05915F4F4FB9A98223663407787254", - "dk": "0D1B18A4D52F6BB6367CB50F0005BC6D9CC52E0872E86AB6B0B9132BA90A309B524E7B3EF93B696D9149CC17BF57A1A1F8371004127AA97A79E4B55CCD079470B04FF38833BBD732FE937B4877C3D643B5E489AC312271A2F9AE7B665FEB0AB13829696EF532F43CA2A848BE9787A873A4646CE5CABA271D82CBAEEFF095F153C7DD66C4484384D44663B1E75CCA0B479DEC62D7CCC97C5495D5CB3A1FA0C6DF6309A4E1B443051B00135166D77433C30B17A68B1723B83129B72BB28C61BC561FC25EEBB53E5E98C86B3B3D852B60D75402D636470E0171FC44716CCC4B9931178FD17B80A4895431492BBB1C98317E45C03D787A30A7C6530B814207C64CA1807D92530BF1EBB232460B68D52021A03A0C603AB6497F16267640316A8E5712DBAC68F3E1528A5B1E37D00856A32083E51958A265532B51DBEB02EB7820430C2974716582E92542E29255863DF251419777142691384C876263A544CE03039710B5A407B8BD7428307A739BA4B84E762C643A383B7A3CF266A1B6C7043D040B0A475B2A6402DDE1AAC192321D910553E2CC8A18CDB9D9B27C5CA0AD272F3145120A266C443A484E829DF079C98DA9CD25F4AA20B29F12A79BE03C7E86F4C3EE277C050831D8135DE1C3227627A732C1C337D047524BB0EB487EF75CA0365520C3E67324C5B2AF45A768D3986A395BFC7A65E673AA41057C8F698436C35D655A9D9FB54F441C1BF54A57E73B335D7B40EC992B4AEC0978267CA30387618C76BDB843A5461578C6938BEAAA0F8719E18469D7F76EA6FC5D73C59399689C1BAA8BA4812111EBBA47CAAD17D050B1E506247050FB62C530D0A1BCEB6D1C45C1DF048F0B14511A709D91F62BA10B4FB42591596456E2B4271FE817914B54DA4181ED7A9BCCC84DDF6614716AA561D99267DC1F8D596AF769482DE440F32B72A7B60DCB0035E94588C02CA9E8628D4A4B071007703E67AC0D87B2CD21B4502782A8BA6E201B6497C80A103003EC360374915E57154771C59ED6CA2FF272393DDC9449038B96B77E0E6C50EFCC7837996EBB3B4F1CD0079C474D9B2172E4947F2ADB7BB947090539AA43B48079133FCCBB92ED878ED76364F31CC094B68FDC371FA8DA78931C326F26961BB20F0DE742039A547C6C79B84B93CBC238C2252AFD504EDFDC14E9FCBF8051A43C75CC28897AD318CFFBE4B70A01373B324B4C732DAF4BA2F3019B5722ABB9D452AE092B89A5CCF7E8776C3222F03C50643B3FC3F8937D437DB19A10EB771FB755CD4939B73A24CFCD01BF6879A5905125C2EBC4903B8F3E91906ED479BA8B83DBC1A21BD6A8222A717FB6398AF89312170362D0486E0969F8E9A417B0C7C7069D8A41A8D9D3C3BEC2847ABC722D3851605C8671C23E0E82A96C1B1AC82C3A1DD758A0D63394F26F20BB6A6669883A87A1AB73AF02549F032A6C51E803DDB131EC47524DA9A283C39EE79AAFC78C569B07B403A89A5AFCAC7EB4400A6A8E6397B3BD49318AA5C37E13757B7145DCEC210C92AFC0186902FA74A604B7DE321488B357A8D9904913335E5A7CBE838E43309DE6C90264803F32338F92B6BAF7D89A112554F23C4A64FAA671D24201C61D8DA67D83AB37E25982E74A4568457E0C7727A53682E50CBF74082F01C9892F60B9DC57C79A82123703A8375C7EFBE299FC3352584CADA79726D8F039E7885508A897B9C54EE4478568168820DB7FFD82CBD0191FAB477199AC0FFF615475AA96E28980888B34A1E2C76115CDA09C2E1AF83FD7004DBD14AFA76773F755ACD40358A774045B09075703C2C08537C9E09727E23902CC453965CA74F9CDB865A02E228BE92850F078596F64841D093BC7BB9354E50FBFB31FD463762B800B88C6A691F22A815B46EDF848C174108DD7435F178B90690D5C8B0C430935C69C6A4451629958614CF00F5FCA7E88C08230E142C26C991F5782C1BB84A6C8750EE00348582F12365A761150B79489BEF53BE9BABB468A7F72F65B2D70068D5313D5011016CAA97C6961C554CE6419204AD28A7E5A7E807333DB1C759B6A546B087E9704B63A573752A0ABB7C702548CBF15100F3A6A807C016687C05058F76A42BAB1BE88C12FD574F4FBC051DA21234806FC279D122A4DD879175DC24E20570B435A14FAB908CFA5AA91A009164530417655799C0B379A10E7592EECA96F7AA84F9D718B95F595BF5887F2135D2BB106D599AAB77C5DFD5B4733506450923815F451EAEA6DA2FB0EF3C7AE6EB12543F8429B7B1BA00C5B05585964D334741AAAB7B2C787778709D2CBD9D1C42A061398939869FC0B21C37FA1A146965066C50889C5798B3EAACC0B5C6D7721CEDEC86BDF67A17BA37666A4226BE80EFEDC5262373117777B6995262F795735872B5CD4B52A59677B3ABFA302BA89E61DF76866CBF5C8F97C2620258570735C9B70265CB9AC98445416A6A1AA8252F89667EFE277C968101C58ABEC009902497D932C0D33F52C69221F96EB589E231877837491757BF2B05BE03C909AF3B780B8088F75610A02C45CE28097AAB34FE19CF364A865D77A9D402501C843684C1F7825C20BA3ABAF711172024FE6CB6F58591E4EEC4E40CC0CA891725927C56A55CAF5B1CC61F510ACCAA54371085FC9B03C169293E16FE74735648B4E752847CEF130A3FC031BE4C04EEC8614A7749FB7B41C2C69D2D23D73F205575655BD6A0F3FE19CF333A0F28A9BFE69B0DA112771EB2BBC30586AB0BC0176A400345986104F0832CE81A60E198B3180840A8BC528B0960CD2F26564D3797BE64DFD602BEAD0C94E1904773BCCD0162F0A17B3B4868B5CF57FCAD264E3F339C6E240C2861C6B6A0429616D88F5B41E991491652852441817033DD8F95A4B7C40EC5A74781A761D8ABEDA618D53D2CD86989AFCC54E5ED2CE26F8244E0247052364B0A11F42DC14B6B8A72ECC76754208560A479C2C104941404E22C800B0BB52E26449238235F113A23C4E46AAA4E54B6B7CD2A3802A2EBC3799B9556FB0164500C14CEC67BD36C31971291EE891134B9CB3E2DC01EF15143AC04EA1F41D9084B7B2EB91F96B7C9A97774A044E037285C820601E424F761BCCC712172B774FFB900EFF1158D6EBBE13775F27720FADB93CD98111E4E2788D86C0151B1458344025580C509738E490874B773849308B8D36C649373F9147781D58C31938B923218BC2E85F4C9B1233BCAE99D35C67DB3A85647801260409E6CF45924E4DA141B6C3A65B857A3D3DD5F476EF377E54214616593BC8CD4D05915F4F4FB9A982236634077872549E2FE7DD646C145484E163D6C36DC6EA5D802A0EEE6ADAC932C20FDAABB8BDD1EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7" - }, - { - "tcId": 46, - "deferred": false, - "z": "EF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C", - "d": "CE2CACEBD54AF1B4E71588DE9F22A6AF2C2E2AD7FD66B9FEC0DF19182E7F57EC", - "ek": "3F476A07BA0E59113595E59410B41C61CC5D509895725A7010E20C83CA906EA13C1C58A604F3A2590727D3538ADB2754B879A3F2640C929388DF38A559108A5519B221E3A2DA515EC34B7CDFD704A04C18DB604CCDB2705CF273EFD4B464D4A3A9773FBBD82840C002D8529BE9377009F4558BC747AD33BE9DB2C290EBBE06972544A827BAC51C131684FA3C0111360F59C72E5D1660269672389748E2B8546E648DA50BB8243B832C150ABC1277B4F7A350028EBEA582202917B8247E4A054C84D31B7BC97837C5117D796655A098C1D26BCD6C506DA164F362CD3B231C089371E711890B795B2DB0C5E916A3A169060969001BD88AF165021FBC9B1D649F9A740CC48AA2EE0348D46394C48A776C040D18D867F3506962E4B619C21DB56C9B3042ABD1B78BA814064979C643E6CEB8025B4289BC1716C6E07873B52C545A9488102200E2877C24806E15F790FF15C9677882EAC857C620297B9B9155044D9C26626F6B97FF8491C0FA33742C785DFB3D401BC0B8C50D17D857A13C4918BAB9BDF5BC8695AE1C581334559E4F83B076CA492DE0A9D97409DD676B051C7C97E9655E2BCFC0E88DDB85480F1A5FE60C7E5A002BD33B0F13F7B4897A9B2D3B140468B9114BA041D952B08B340D2B3B970BA44738BDDD3CCFB3039F7C04C0264875C9B0B5B05115C4749B29DB6BD801328DF89307307F6689A43F72C83940B3C7D72BA35B812C660DF39A329867A9727119BD9A379C6C39522B669B461F7C6A5383C23289B4C065862DFD430E7D9B4385401CD870228EE1828C9660F1CC2F9DB63E5318A97FA8AD4B693505B859C5FA86816473080C4AE6C297767A210D355A4DE59AF60844227781BF7B3B09C624C8587B0C2A200BA1196F5C84B99630A03B07C86A1BA50C002E523C8DC498BB89A4DE17CC8BD2A1DE3250E282961C956C6B197904C1269080280E2CC636112CCFE88195536E52D84AC33332C7612A4FDAB8BBFBADA5149E05F1CCBF28C706E5B037F65C7EA47EF5E1792F90B7BA4C01EA027D54AC44C60373EC931BB5E5772AEC45581C613D1497D227C0F65470C05187FF214593B44EE8CB18BFF8195365BC56B3608AD6B228E755D8F52449E7A15E81A26E372E1DC19DED021088B8A2247A33E0C1857C22CAC798575A7ACDBB09B4A018084293CB2E766CB2A8C5D1845B0B878F74BCC41667AD93137B66F352453051EC360559402CED1A1A73EB9D45A97589E05A5C991082F3498D1A75708A3FE582B0EE3B95785C73F7679B374095E1EB47567C41E630A971D60C7A6B9A02C372A9A56B0206144DA6556EF37DACF9002CDCA7A3DAB5319259E06B7F5473643E975BB93B079A451C5AA87CC0B8ABCEE48BC1448482F9769BB27EBCE597214AA73CF8734B9C6C3E79A53FD83F120C642A690C8220008D834DDCB99DF152C8456C817E106717B5CAF96262F2CB3D33892B1506C18D25B065C0CA1017BA4D466D0AC849A112C42E218C7978A14F362BCAEBCA9A5602F1C96AAD325C9BDCB6420B76926157C02A4CAA659134908EB024CC88387FF64317354B87D7383A7317643D71713DA3B25F3B939B060B6BA0CE5838697BDA102310AC67A1080B0C11C4FBB44701CAF7A360730F6EDECDE8635ABC55FAD14FF51E2A271F7D44190ED0D0BA95131BE7DAB95F", - "dk": "9F487527A4789D287401760DE02688DE23B049C0BB20DC05AC651478A591D4178C7E25CC578832B05B1E136BCFB28157AC8A4D75BBAE195CA628028C2BF806EFC1A132D93F40850D64445BC892CE03159E1376A1701C171AB6B18F437184C671158CAF77A9BA9B1B63EB4422011C7E0E602273D94C42820666E18313C61844C403F7127C6E47B17A41C7970CAE2BD78E8BBB353451269C13628C605295AB52F263C655831AE338B1B71AA25C195FB1096E0573CC7AEBBDE9E7751B22A74726354E88322F1BC2FDF03E65342F06C6359B672E679C25FBA03840FC53F147B9A778AE421506C09AB17242CE41735E2168044EF95EC4C4410AA284B79B5B9354C419B5A9663A7C3DFC155BC57A04AB22E7578059994D33D8C76C578C7A98B5B7351D5850BC48820A199B3411350C7DF650B9D1A3E8EA2A0C32A9E88030D4AC3C22078D4950CBBBDA707800293F487D023C6476223FA5DB85E229BEFC13B6B98561EA80C30C8BCD3A48994D255AB6A134AE25A40D4B719BE2BD4FB050C477CA417406FE9A3197495CAC610D6E861CC5A6CFF7BBB8BF84B71701CE6BEB77F273505559752A6B96133A5776B784343797DF2C024C41A9E05ABC38688ED303C5A0553232D2721A13152E9A0154152BD561AA7C1991887912DD79235A8B6E04AA18C1A903280417E42B07DCC0310067BC40633FE441082BF78FE4859D8892A973B78C4F9623EF88C05901AB6C1A039C494CCC4B542474C4B369386842726F13C62E72339A37B472B538FC881711CBBC32A88D72FC93C0E2A8362C7AD8D236C2EA6724616040D799440228EAF306B655754DF78FE941315D419342B426CB273FC4604245459367F30A6A071C4C73718ED1019B1BAA65F273D665CFE79A8967A60367F470BC74C7881A516487BB1A4B4FC38AC6CC21CFEE071CB67119D54A8C077BCBA3E3103EF8724CBA5406519122EB9884F645E7248FA64489FD9763459275BD80787681433C1219C5B31DE587487FD10112274C196A4AAC7794F28A0DE98A8852F37E96A0C0FBCB5CA3B8A33678C71E469B0BE1B7D134100D8A4DA009503F800A56714D06D6BF5ED7A1D1AC8ABA3B458FDB6DAFC28EDE9CC7744A7B3353CD36569A7DF2CC0A4726E5B8AA01093A9B7994B9473E12F346B992C718E825E8F1B05404433B20AE2B464CAC95BD0833C313D96BA607C09998929776A5DEB17D259B4D14E6C1616914B07CBEE1000D11BAA276F64663F23D5CE670C01AB6BBBC9A5BEAA07994099250A54BE9A164EC67174B8C83E7115A72756164491D233A0B38239A90ABD7DB1DD0EBAC93327574DA1B242B4B98B794B8B77E5C9B684F618111EC8A259279A867066B43C4D4540C92FC5E764276A1DA8AFA378F3287C7EDA09A8FD41A8495566E5B1C8C4260EF96B123160221308E97E23F7D6B281EF94F5315CE86F8768FA2270E8953F1851E20A790F0F60ECB03AA414600B7575109FC1632FAA73E173987FBC2EB3BC94B7BB2BEA78ECA17AAA9416CD2905845DC699236517F3A45B06975EC19544C4792E9248C1FC59709C460E907031F831326867FBBE55CB32627822187D93740C2DA9AAA8606FE5979D340B97707144BD437C70C768D292CDA79C23F476A07BA0E59113595E59410B41C61CC5D509895725A7010E20C83CA906EA13C1C58A604F3A2590727D3538ADB2754B879A3F2640C929388DF38A559108A5519B221E3A2DA515EC34B7CDFD704A04C18DB604CCDB2705CF273EFD4B464D4A3A9773FBBD82840C002D8529BE9377009F4558BC747AD33BE9DB2C290EBBE06972544A827BAC51C131684FA3C0111360F59C72E5D1660269672389748E2B8546E648DA50BB8243B832C150ABC1277B4F7A350028EBEA582202917B8247E4A054C84D31B7BC97837C5117D796655A098C1D26BCD6C506DA164F362CD3B231C089371E711890B795B2DB0C5E916A3A169060969001BD88AF165021FBC9B1D649F9A740CC48AA2EE0348D46394C48A776C040D18D867F3506962E4B619C21DB56C9B3042ABD1B78BA814064979C643E6CEB8025B4289BC1716C6E07873B52C545A9488102200E2877C24806E15F790FF15C9677882EAC857C620297B9B9155044D9C26626F6B97FF8491C0FA33742C785DFB3D401BC0B8C50D17D857A13C4918BAB9BDF5BC8695AE1C581334559E4F83B076CA492DE0A9D97409DD676B051C7C97E9655E2BCFC0E88DDB85480F1A5FE60C7E5A002BD33B0F13F7B4897A9B2D3B140468B9114BA041D952B08B340D2B3B970BA44738BDDD3CCFB3039F7C04C0264875C9B0B5B05115C4749B29DB6BD801328DF89307307F6689A43F72C83940B3C7D72BA35B812C660DF39A329867A9727119BD9A379C6C39522B669B461F7C6A5383C23289B4C065862DFD430E7D9B4385401CD870228EE1828C9660F1CC2F9DB63E5318A97FA8AD4B693505B859C5FA86816473080C4AE6C297767A210D355A4DE59AF60844227781BF7B3B09C624C8587B0C2A200BA1196F5C84B99630A03B07C86A1BA50C002E523C8DC498BB89A4DE17CC8BD2A1DE3250E282961C956C6B197904C1269080280E2CC636112CCFE88195536E52D84AC33332C7612A4FDAB8BBFBADA5149E05F1CCBF28C706E5B037F65C7EA47EF5E1792F90B7BA4C01EA027D54AC44C60373EC931BB5E5772AEC45581C613D1497D227C0F65470C05187FF214593B44EE8CB18BFF8195365BC56B3608AD6B228E755D8F52449E7A15E81A26E372E1DC19DED021088B8A2247A33E0C1857C22CAC798575A7ACDBB09B4A018084293CB2E766CB2A8C5D1845B0B878F74BCC41667AD93137B66F352453051EC360559402CED1A1A73EB9D45A97589E05A5C991082F3498D1A75708A3FE582B0EE3B95785C73F7679B374095E1EB47567C41E630A971D60C7A6B9A02C372A9A56B0206144DA6556EF37DACF9002CDCA7A3DAB5319259E06B7F5473643E975BB93B079A451C5AA87CC0B8ABCEE48BC1448482F9769BB27EBCE597214AA73CF8734B9C6C3E79A53FD83F120C642A690C8220008D834DDCB99DF152C8456C817E106717B5CAF96262F2CB3D33892B1506C18D25B065C0CA1017BA4D466D0AC849A112C42E218C7978A14F362BCAEBCA9A5602F1C96AAD325C9BDCB6420B76926157C02A4CAA659134908EB024CC88387FF64317354B87D7383A7317643D71713DA3B25F3B939B060B6BA0CE5838697BDA102310AC67A1080B0C11C4FBB44701CAF7A360730F6EDECDE8635ABC55FAD14FF51E2A271F7D44190ED0D0BA95131BE7DAB95FA5A66716D011EEDF9E6A541F9438F8309660657EAFFCDB01A172998E56D9A60BEF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C" - }, - { - "tcId": 47, - "deferred": false, - "z": "17E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55", - "d": "7E03015C5D55FD9888E730C1E60F90C5F6C2E3B1E8C7C08D869F0C1D15B540ED", - "ek": "BE62BD6BECB1FBA42DCEB479C8B8AF9D740F272661045437E6D0C13BE05D87821365509758B075C7D15A421876CF83C9BA1458F3C2B85002238DA64ADCD77FE7F1B33F3798B6C87609708DDD1C4F41AB9781A3BEAE2910D3D0A2496927C4907139CBA8D5B791FEDA3CD472538D9AC0FB9895DF079AF86B439096783D2BC6E967C211B3969B876CC0322E59C80A761495F50567276349EA736A43E5BAF638971C355FA4D3621FC60BEF5408067B5968E56DB7F2A2438233EED3AB2792443618A535389E3E7A3A1C061A8AC72423508C2747CBA968B7220911D0324522CAAFBBA85B5D1A830FBB0FA20CCF10F78656B512B34B28815C23DF718AD044937BD73198798858E41FE5AC16EEF5AC6E234DE5D7AA5AF49ED0BBCFA35843C7753613988707C2025F8654A9C8A37B4320BFD243BF8B1143B2644A715910C46DA9C88AB8F033EA233DAF3660F8630ECE308DE44B4699D6CEAF275065BA4DCA584026D261F753CCD0A860F705201B64B32F159C86558E633312DB15C2C3164889F49F181435A1877760C50206816F3502CDC3229107F92355467ECA127B51912EFBC911C5591DEBECA2AA6015274382BA5734F64B08E1160A4CDCA78CF722A1A31A590B5E90185AF809CD39A56A0D945BCDF0769E923C45E52DE4B45E2E22093E856FAD9B9C00641970B31BC0481D91884782D08979AA02484CAA2957CC6CCC4434EB5C814973B7E3A284DBAB2EC068A5DC047336CAD2990D37231604C584E05C689E30CDCD7668BC764E3D96184E7C45D6D988AA9B03CD3275747B2E1F0C68CB76326F263EBB910366D6C4A94A8252F6BA0F5269531188811A7286D6A2AFA3158F8243B7695805B8BDA1322B1A30049C684C6DCB574C20A9574BA78677B1135135ACF200A22749115C7E1BFB6A1614A7BCF612562A3CF6702742F586B6F55169C5AE1D14621074034C109518C86EBF191881D4B692E4027BC9C195E20F54A36B8387845F47BF23482359D90BAAC0B24E091D6937AF4049A043529EB884189D2B6FD4B05473E3696512910E9189C1508DF56450BFCBB6E97747AFA545C64B346CCB04B6F30733A1071BB84DF18A2A762460F8E6A1D9F0AC2840474FB61FE7087818F6A53E7CC799B0508CE97D06987E24BCB4E4B559161C5F1AA628D68B129CD178CE6069236C863AF8A2480C149EE5754AC04719E01D86855201554F922167B623236B417FAC5948D182B12E8210FBE23FFFEB81AF88532F0193FD61BD82D59FE646209D39AD75831EDC605AA6485CE90023DA218CBB19AD8FA858E7A661D85A3ECD136809E70B25F166339C307C350E4D5303AC844257872A2845A7F6CAB996918AFEC669C9A19D43F72A5862BEEA66AAB0D708C59C260DF09EC0BC2A265A311309CCD2ECCA4FEABD6176633863A71D75B0E7957266584D000A6824D467EC50421AA1369193B418072815562928D35C16227D22C821A8552ACD83A513AB683CC39D12537DC4456E1476C4ED9B4014C42A7BA6A78C9B72F3437228A918BCC6C13FCA16BD04C7B2B277AA4C2B903517FB8397598554C9C8885380B4199450A46635E7B4B338075E15DA4A3630862CDC2B811578626C5BBE0B73C0F375376708B4D8654560782F3D56064B96E318E3FAF0D63CBD17F9966EE839107DD8D6530A49F344E194B7", - "dk": "4CFB54B237989DB51A1AA97F36A3B2F4337F46AA0D2C05BB1D043A5513CE6FE84A98D62251360EC740221D1B7BE04098FC37A4AD633E95332075394E1C09AF426C146BF34290F50F318B48076653E9E66E972734CC9422750202995305827736D1F03464F37F8E468886CC8ECCD74F14706AD940B1CA73257451898ADB1476D0C813A0B06648A1DBC3150DC742D4B4CAA8EC12770974F87020B80BA9AA5274E4C63B747051AEEB5A1CF310EBEA23F17035DE2B4D51C226766ABD33F9443AFB1B21563C70E431E4D579E1AB26E5F6A2792A8ECF158C53C737F0582CCF50320FF65E634B26D3F9438E94981927ABBE2899DEF3055DC8AF679569A7AAA9FA4152697454D6DC04E2B5B2A9850AD75A1B9E060F11D817152C043500CE8391C0438BA1670B19D8333881647F5ACB813CAC66AE2065A603457EF3535B7338F32759E95923C4EC84D2248A66802D92A01EFA16CA74619C771048C1111ACF6BCD1508C667CA8C471409FA9C37F4A4AE23D505B9291511C1AD7996488CF7C611B7B3CA3855CB293BDDB19B7A1614017B1953BA7A218C50236A2F7D1B3B39BA1399D251D4D6394BDC244AA9C6A6A29FE0502E9563BEEEFA6066D5A9E52000BE59CB2D246E8A559A3B7B4B2E956BE12C2A6EB4C7156324BFA17EA8DB75A844234545147AB0AF65005D7E2470D71453224399F6C51A970973CCD3339C270A5615528FF1968811C652BA8A991C13FDFCCA4CC661F7895F54BBCC07E95E6AA6178BF56FF496C1F3576A42529A69E713A44A2C9F5B7445F794996C7F944325B34574FF364357910863D99060544606A619515B7103B76E2E4869300750D4766834750FC7867A0D98470AA502193131FC7C001B49A102AA135C7224E937973CB02BA1118520833892327428FA88BDE81E3A19BB030C6EA7E6BA69B7A82F6B20F19CAA2D20507ED3C2BB0A4BF814263D17324814017F7012EFF6886257615AE2B896B045231455235C09F706235A628FDD27685C6491EC91A1C8803BC6820C9788AE919C466F836C8CF50512D149F47322398226F7B791E568BC3B6C3E52B021AF3976E9562F582734796977890AA62DE021C0431527C7C15F4AAFCA3AC6B5B61DBED8652644523029495E268890F36E145C2060B84E2C110DDC0018F2678F99726E4A981D258C14BA453E73858492E786E5B96F6C31687E702D95110A68A77E7847C9B53C181E34434C2A51FEB36DDA926F60556202371A52A04391E662A26289A80774273BC8477968D76717BBAC9D5028965C9A9D537005C6A3CADB62206E5B2E7DFA877411C6DFDB1337FC6DFBD28BE42B774746C625D41D7ABA2D29E21ED3E13D1BF5AE3A12BB25650B480C309079CFC2E1C2114B6618E9BCC0B73D5E4202C992CB375B3A8DE0A35985C235B314DDAB4C4B888B216C761224780F885241F0C1F62837B247B06B719FA4AB85E9B63A52A947972C0678DA85B2298E81414AC5B42D41E04171438A25B56AB30C61DEEA1328562079131A52805C63DA0B8A6C324D56BA6F351B6D91041772A227B17384131A30BBCB9367319721C48743C7A9786252749082623780E4828601AB15BC08A9E103C5170181B0240EB4C00B7B085ACA634626B4069703BE62BD6BECB1FBA42DCEB479C8B8AF9D740F272661045437E6D0C13BE05D87821365509758B075C7D15A421876CF83C9BA1458F3C2B85002238DA64ADCD77FE7F1B33F3798B6C87609708DDD1C4F41AB9781A3BEAE2910D3D0A2496927C4907139CBA8D5B791FEDA3CD472538D9AC0FB9895DF079AF86B439096783D2BC6E967C211B3969B876CC0322E59C80A761495F50567276349EA736A43E5BAF638971C355FA4D3621FC60BEF5408067B5968E56DB7F2A2438233EED3AB2792443618A535389E3E7A3A1C061A8AC72423508C2747CBA968B7220911D0324522CAAFBBA85B5D1A830FBB0FA20CCF10F78656B512B34B28815C23DF718AD044937BD73198798858E41FE5AC16EEF5AC6E234DE5D7AA5AF49ED0BBCFA35843C7753613988707C2025F8654A9C8A37B4320BFD243BF8B1143B2644A715910C46DA9C88AB8F033EA233DAF3660F8630ECE308DE44B4699D6CEAF275065BA4DCA584026D261F753CCD0A860F705201B64B32F159C86558E633312DB15C2C3164889F49F181435A1877760C50206816F3502CDC3229107F92355467ECA127B51912EFBC911C5591DEBECA2AA6015274382BA5734F64B08E1160A4CDCA78CF722A1A31A590B5E90185AF809CD39A56A0D945BCDF0769E923C45E52DE4B45E2E22093E856FAD9B9C00641970B31BC0481D91884782D08979AA02484CAA2957CC6CCC4434EB5C814973B7E3A284DBAB2EC068A5DC047336CAD2990D37231604C584E05C689E30CDCD7668BC764E3D96184E7C45D6D988AA9B03CD3275747B2E1F0C68CB76326F263EBB910366D6C4A94A8252F6BA0F5269531188811A7286D6A2AFA3158F8243B7695805B8BDA1322B1A30049C684C6DCB574C20A9574BA78677B1135135ACF200A22749115C7E1BFB6A1614A7BCF612562A3CF6702742F586B6F55169C5AE1D14621074034C109518C86EBF191881D4B692E4027BC9C195E20F54A36B8387845F47BF23482359D90BAAC0B24E091D6937AF4049A043529EB884189D2B6FD4B05473E3696512910E9189C1508DF56450BFCBB6E97747AFA545C64B346CCB04B6F30733A1071BB84DF18A2A762460F8E6A1D9F0AC2840474FB61FE7087818F6A53E7CC799B0508CE97D06987E24BCB4E4B559161C5F1AA628D68B129CD178CE6069236C863AF8A2480C149EE5754AC04719E01D86855201554F922167B623236B417FAC5948D182B12E8210FBE23FFFEB81AF88532F0193FD61BD82D59FE646209D39AD75831EDC605AA6485CE90023DA218CBB19AD8FA858E7A661D85A3ECD136809E70B25F166339C307C350E4D5303AC844257872A2845A7F6CAB996918AFEC669C9A19D43F72A5862BEEA66AAB0D708C59C260DF09EC0BC2A265A311309CCD2ECCA4FEABD6176633863A71D75B0E7957266584D000A6824D467EC50421AA1369193B418072815562928D35C16227D22C821A8552ACD83A513AB683CC39D12537DC4456E1476C4ED9B4014C42A7BA6A78C9B72F3437228A918BCC6C13FCA16BD04C7B2B277AA4C2B903517FB8397598554C9C8885380B4199450A46635E7B4B338075E15DA4A3630862CDC2B811578626C5BBE0B73C0F375376708B4D8654560782F3D56064B96E318E3FAF0D63CBD17F9966EE839107DD8D6530A49F344E194B76A22A9BE6B0A57E59B2F2194C4AF45A76286DAB2B0E0FE8DD37AF72ED021ACA617E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55" - }, - { - "tcId": 48, - "deferred": false, - "z": "BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686", - "d": "8590BFC9A6FC25EE7E6DAB4870DBF4B51A1F141B7C9E96230C0403E799BC68E0", - "ek": "1CD8880468590163A4B0692D9569089E24873F9A5738826AA8A326B3D013C0F0C65B41CD81A42290F628F174006E08C3CDF9B012050C2FB083F97A7770F8A3B120972676C6944B06320A56605409E33535ECBC1B1EE6201A457309102D845CC631450C2D802FD62A793AFA82C0C9BAFFB22F8FEAC2B9680DA32A51AC1C75F7E3899FA01471F9668DEC6CD765221E765D7C714D46085CF9B9B6FCC2891EF16E246489CE87B9028A5DEC713B84594847A4554AB4A39985213D009C617C0524217AA1A51DABC9CBF689B66325517726CA3E955F742126F13B72CE936EE1CA2D913B785B4704F975C221437C6A890E354810E27B57689A8564DB22783B3D46488F8646B50C366BE75566EDC0422C2784B7A33D10588BD83A89A07519B754C1EFE901FA9001C0B120A70C0BDC8CC5342C8D20281B8A7A24FF4240FF6990BFAA3197CAA594F63EE4C75B3014AF834BC4FB8249604855597B5ACEF45304D75C035981A8A7267FB04867E9C28EDB8BA6C64BC6B70B218CC738B097FD6527915018EBF712E7044BC7B50CB9151395814278089E9A003965B4AAAE46A19E5791331876B985BF23DA8BE19CC4EF857C98C91084C1CF0441A1B212580E271FEED51C98D88D4003B909B42627860E5B788F99521CB3953371F1686A437A2F3055F8D05B7FB01BA29886DD28A7269A99DF979DD80BCA5D399AC18A919985C643D68910F9C0C5923CC3A30C25E8B9F71935503513AC28A520D194CFA7129BD2A08CE76491B886B7531ED100700EA011D09319EB66B8B44A0C09913A0E40A2B1166DF676C205E648872386A221B45A428B9BDB0C8281032D52C22028BDCC96AC2CA6470F407F98D479ADE32B1D202F1F1141C3E6453084B551554989E00BFC2A44E7F5ABC8530FC174B6FA30B3F26B5A467A39322612B1C9C3CE01CFC540CEF912058FBACCEDD8BED38AAB401B88EE7058195CBCB7D8405CB71DC5B44EA19B34C9D1652E7192D50A03136BB87CB207C9DA8ADD47AD870A3AD5DA51B5E8874F71560C5490AD7137522823B167166E89BFCDD3492AB836ABC952A5E957E7A0CA963A2C697AC1F42664D7379E6AB2361D657D47CB34236B70F9658E71FA7CB2D51BABD2C67187022380335D9014176BC52878C1CB721CFA6B63FB92C55A9A53EA635C7522A93DF572DF5B01E4C4931DD47ECC73514EB5A6085206B79209A712C60BA4B338254411D08DC7C289E00C0C3F230406B47CCF4183D97005A0687F6BA6B7A02A4E9E781C99C28DBA8A32DE80AF53075CACE4629F03872F3606228335424A1311BB58BA3309D4087F839960DC3CC63D83832F0768BD13BA41EC2ECFB03D882799D10653A4F6BAEF00709169346FB83232F9685E309E36B23DF53AC8D0996FAF14440641AD59E3991054678596849FA44436454BD535A2692922A3C57BFFDBAFE0913240EAA29646A8B5E7461C269F58F92680401B70A82529634325D128AD23A452EC9A5E52A622A524F3205B6E9130BAC6830C3B109164A65CA9091226666DEC395AA63B0899BC6C798F86F74E3E5265CABC600C193AB7D1AAD5085D2C198DE66A4BD4649A26349AE5C88FA44BAE97B91D2A17B8578942B7D61E25E367CBDC29841B0116458C97F72499AE6B74006261E57B749B66ABDF0FF71F8CCEA4ED010C6A97739D7351", - "dk": "F14A379CCC4C2B873E4C6366D676712F1B15BC620AAE40C3B6F31739FC2889ECCED39507D9148082B2B37C70BF95E42A98CA9B13C52A22604644839DA14B67B3BB472E376F52E20641E06E3E6104B551353FF24646C97E0D1C8A0008478158CCE8E8B6D522896A395DD8F6AACED41A58D3A9C0C0BB23C55484A9CB9BE11E9BF370BBF045505C99A08C6D8B62825D1020B3794999F63BB083BDF260714D16ABC01C741C48776067C373CBBD24558A1A4938C3369955EB0D8673C1323A243CB72781C68BB64C1E754C702C832D68F5C0A1E1A1CA04A0077955CF131B74CAA9BAE30284BA467AAC056CDB8F47B5848CC03383B275C4E62B34881E8FF504E30893A5A7C6CD9038149C0F83BB0410578A3BF42A7B7BA7CC174ED0613FEBB88E5CFC7A8E9204D30A48D4C33FC0752169874963A88A1019BE594B502FF4A341D3C59E14100AB3773AC43A92F0C901A04A1FCC256DDB73D6F97AE58ABFA75528E6CAC933E2B3A5A84F8C24137670C531E6BE9CD9758BC5BB043266A22104825845196895D6966577325769220775C9C2B480C36E6C2C18B7255BB5277CD40DEA96806858299C201FE60C5A8E590F565863DC254FE8431A3E891149D86D8CC24EF5114103D8812FE282285C3A2806432AC7629716CC5DEA1EB9576E2B9562809A0AE66790F654278C16B355E1A4087A9600382F35BB3BF9F9541B4C5A98382D47D4B569685537662D4D891B7C949FCC4A27C81CA7A594BD66AA09AADB27AD43420863C2CBFC7A5D818984E343785C863085A97B2B77E8C5054418BF43BA61E62594E7011C1B3360F278130595959FA026C14A893579363BDACE7C291065C27C73340D400747BC29458FA324CD8880DD84A09FC973487358E68BB3221C4E5C4133914A13D2C53297BA10F02327FE37C43681A028A865576410F7DA2A7FA8867D563399F59DE8569485043623A1448C613B6424CCDAE8C59CCB53F1E8B0EF4A5751367F193637B6F78E0AFC2013FCBA7FE8AB5D7C70385A6869221A8FD88E246C7DEC6C83187C9680A8654E02269CFABF7438A234037BEAA7AF8D54448035BFE7A7430E264CF3F607DB07C3EB750BBB1926D5ACC839F02612C4BE88422AD9731FACC22F6DB1213DA36ECCAA97F7B5CC94146A0C50671F7725388712B30A1E8EFBBE72F693B7652F7FE5A9C3E10415168F6F9273AF55109BC9BAFFCA3E80989BA88905C1DAB706BB77ABE38D4235C44B43515DBB6CB15813EB4B0D8EF97647B331C689AB67E3921B840FB78804F83B0DE72239EBFA22CA799BD88107C36A505DA09E9EA4C4EE5802DB5047D2FB6B9B2C499EE55CCE4347A33C7A6EB2337D3589A3D099939B0C8619AE7A2414F0698B4B06D07648B2059C8BF8583095426A0776C81D4C5D24EB5AFF450E79FA07FB7026378B1E86D6AD2BA7227475261F37A6C58AABC6447E054AAB9C61A6E19B571AA57005E8906BDB6960A425B8B95671407145837FDD9B5CF51A4E42592CDE24332673CE7D023A3E2544970AB55857A1F0200521114B8096A366417052094175B549F474173E723A2377525EEC95C0D40C94988981792A8C324B61EB381F8ACD3BA987023B2E64D29C0FF63D5134527FA8AA5199667ED2331CD8880468590163A4B0692D9569089E24873F9A5738826AA8A326B3D013C0F0C65B41CD81A42290F628F174006E08C3CDF9B012050C2FB083F97A7770F8A3B120972676C6944B06320A56605409E33535ECBC1B1EE6201A457309102D845CC631450C2D802FD62A793AFA82C0C9BAFFB22F8FEAC2B9680DA32A51AC1C75F7E3899FA01471F9668DEC6CD765221E765D7C714D46085CF9B9B6FCC2891EF16E246489CE87B9028A5DEC713B84594847A4554AB4A39985213D009C617C0524217AA1A51DABC9CBF689B66325517726CA3E955F742126F13B72CE936EE1CA2D913B785B4704F975C221437C6A890E354810E27B57689A8564DB22783B3D46488F8646B50C366BE75566EDC0422C2784B7A33D10588BD83A89A07519B754C1EFE901FA9001C0B120A70C0BDC8CC5342C8D20281B8A7A24FF4240FF6990BFAA3197CAA594F63EE4C75B3014AF834BC4FB8249604855597B5ACEF45304D75C035981A8A7267FB04867E9C28EDB8BA6C64BC6B70B218CC738B097FD6527915018EBF712E7044BC7B50CB9151395814278089E9A003965B4AAAE46A19E5791331876B985BF23DA8BE19CC4EF857C98C91084C1CF0441A1B212580E271FEED51C98D88D4003B909B42627860E5B788F99521CB3953371F1686A437A2F3055F8D05B7FB01BA29886DD28A7269A99DF979DD80BCA5D399AC18A919985C643D68910F9C0C5923CC3A30C25E8B9F71935503513AC28A520D194CFA7129BD2A08CE76491B886B7531ED100700EA011D09319EB66B8B44A0C09913A0E40A2B1166DF676C205E648872386A221B45A428B9BDB0C8281032D52C22028BDCC96AC2CA6470F407F98D479ADE32B1D202F1F1141C3E6453084B551554989E00BFC2A44E7F5ABC8530FC174B6FA30B3F26B5A467A39322612B1C9C3CE01CFC540CEF912058FBACCEDD8BED38AAB401B88EE7058195CBCB7D8405CB71DC5B44EA19B34C9D1652E7192D50A03136BB87CB207C9DA8ADD47AD870A3AD5DA51B5E8874F71560C5490AD7137522823B167166E89BFCDD3492AB836ABC952A5E957E7A0CA963A2C697AC1F42664D7379E6AB2361D657D47CB34236B70F9658E71FA7CB2D51BABD2C67187022380335D9014176BC52878C1CB721CFA6B63FB92C55A9A53EA635C7522A93DF572DF5B01E4C4931DD47ECC73514EB5A6085206B79209A712C60BA4B338254411D08DC7C289E00C0C3F230406B47CCF4183D97005A0687F6BA6B7A02A4E9E781C99C28DBA8A32DE80AF53075CACE4629F03872F3606228335424A1311BB58BA3309D4087F839960DC3CC63D83832F0768BD13BA41EC2ECFB03D882799D10653A4F6BAEF00709169346FB83232F9685E309E36B23DF53AC8D0996FAF14440641AD59E3991054678596849FA44436454BD535A2692922A3C57BFFDBAFE0913240EAA29646A8B5E7461C269F58F92680401B70A82529634325D128AD23A452EC9A5E52A622A524F3205B6E9130BAC6830C3B109164A65CA9091226666DEC395AA63B0899BC6C798F86F74E3E5265CABC600C193AB7D1AAD5085D2C198DE66A4BD4649A26349AE5C88FA44BAE97B91D2A17B8578942B7D61E25E367CBDC29841B0116458C97F72499AE6B74006261E57B749B66ABDF0FF71F8CCEA4ED010C6A97739D7351C57B9807586DB3D99C6AFFAFB04CD2551A4B1DF17FCCB8D7D94C103EE6656B14BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686" - }, - { - "tcId": 49, - "deferred": false, - "z": "F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1", - "d": "D5FD815092620DC42A223909E387369A74AF7DCA285138CF217BC29F29C42C41", - "ek": "A9D674C360C5B1E36D78F66C722392F167A126F09FCC4310A9320137EBA898E786F95B9CC5D0B9114206EC66159BB3A687427D3B2298F1317ADE160EBF44CAFAA62B38871C6239C38F67CA0922C9DD952D8AA55AA6A481386771FD003A271B659F4B730B589B717635E6EB62603C5BD6C96756DB4947C5B1A71B970CD16B6D2519205C08147685B7103BB7C130B40C11CFE9C73866567175CCCDF40522C10A80140D78F9A71C714BADB1CE2732B86BD0518BF4783FAA00694208C3C2BD4BA34DEC08ADD425A0687A0D8B392702DA57504A28E9099912A8AE4A964765D35E739C1C3158330F4C21DC3A58969AAEBC788EC8177443732EAA527DC1E5009E010D8F980369FCCB48527AA27C6553393709F0B252E9346671465D33C072E352B2619175878F946488AEE3B5EE201C753244E6C85A1DE48BC994B4B1F9AB4F81B9C9F6C243C4A57BAB99781CAB1FD152A205A893F07F16431401F746B5EC790EA89C8C672EB7267EC34036F5F541C334B499DAB565387C2341C27F4904546917295B8F640CBCDF9B254502B58A669D36AA3D834793CC2A4D6578397D3A6DA893710F6A1839D8CAD7067A020108BF98415569A5C5856C5678C9A41A3075F077E6150F54B57FE91691A1C05F5022939A322CB919ACDA1236FEC9885AEB2C3A975E5BA238F5E713AA751093846915B003E624577007C7048B23E29445EE123AD3D6604D5006332CCD238A0E23020244D99A2C8A28CB58A76A69A39CC05927767ACBF892E3B6CB27231472C9189FBC1BADD18CB9A0CCB9E9CB08D0BA65C9924BCB2D88EA9739835C3B388A7B416A5BC5A27B01260D732F237474292133F0E458F33CBC3A687F149A1F8D7B08FE76A0C7C9330F8582D378BE0E2B135097CC9527A24FA3913BC3C98F04298CA86A08F6969D98C6EEDC19D6026D18D93479698A237B319B8CBC7E266DD34162FDB07C04A677C7B27E758A9D42DB0E35B4369C325C1F5639E0AA30B87433BC9C977447A2F97413E351BB98242D68E02527053A75A0CA93AB8E1E8B521F4BA09EB1B32D6797C5D7BD2AC76E81946CA48BCC787A9D35022C31F0938F710482B1A5DDF91A9024900D019AE33B182D6424D86B558109158B188C3978B5345A7D85B70B30888083C50CFAEA947258891A192B05D8589A0B7415F6945D1275B9C12DC25055B372553D21ABC7B96BD7F821B0C78D6AC3CD5BEA024720625611126220A5A467A60C268B748632C6B19403391391D649BE701B85592FF7F256937843547339E01179E2D79F9D88168528CE5FD5A819108456A789F094093E3980413A14F11B71C57BC71617CA3234008B2907447B8EF8A58B87450AD9506BB84C9E3F66BCE6CBC5D503434D406387D8CDC22A64D53786C79A90C911723D8799B3A7B9AB20672DA92572FB609AC14D57435736055B89F9851DB4B621AA42610317F15802FFB457620B4A7712212DA5725C049E1FD3670DF15ED5A945549C38DE4826BEC844500A313B41921E21AA5EF186940497462117EBD8B383520680DC2646683E0E819B2DE992A82380F400BAA20560AB7A58D2176D4885204ED705F21084390C5AAB8879214286A1F199B3949A59E11B86582B5C13080766C7E2091EA99F1352D4488C7EA1547DD87024156A9FB2DF0C77B684540084890847AA6D85", - "dk": "49B061657A8EDBA51C06A38F4995CC0D68BD97C515A7576125F7961317046D3B0A21B44415B07592991570D05291AB34DCB808E57041FF249D97F471B57A8B7924BB8B699B9772360A8157CE513C58882B89F79E37287042A353A887761D73B2AA3A5185D999FD1A4609AB7FB3ACC8EA083E6DDB2A9592413CA11E7D51AD6378132AF88D977762A473A4849A303C648183D03773C610B8C07A6F741D2E887768E20FA9B749072CB64292B791731658E7297F8A584EFA2A9446911E155E0E27BD71DB8B1D52395982C40C4C65C7FCCEE20B684C2432A83579468B8A82A730305A157FF46F5C8781CD621143E31A20311803185335855116712E34498045093BAD6B80A8F332AB8C5A90025AD0B1CA6EC53401AA83DD01595540141C749687A53D775B4A691B69F6D32C275187A6CB1A4A336C341CC36CCB295C21609EAB1636EC0BB031345A3BAA345878EF43A46B82A9DBB7019658A43AA0368CAB4310103BD5589499B2C1E89A5C2A297ED707B7FAF8170FD2CAE245146929060CA5BD10D8316980C18824CDA429302B64C14385CBE36AA0DC6CB0941B204A55A710D2C68052C900C34C35A7AE7834CF5552264AA2583913348CDC79A08847ACE64024464E759AA99573BFC7B40F8CC4449379A40558B756B22410934C7969B42ACCCCC7D8231E5CA2DF5574384B9E0712C436FBC67AF74234E49B59480B0CF47C8DC31D47776BA9B000C0E80856B889FF09916CF8CE199680A45B16B1AC1438000D6472C79497014B6384AD069FA8AB1A004B518AA97066DCAC32D00893301D327008020431F2B01A4004523F0453DB14B3A84001EC3749D25473EB219AF1E0A7628BAE4A24BE7A1A5E24C3AB5D0A6661C4C1DE754755EBBC91865E8147C1D0233DEA643C4E648DBE3C50B96B898D81B4DB71CD9CD38BFFCB9E7C384EC58A7A27F29C7C5B20255149EDD02442E4CF8C8A34B73B6D36319F6FD3425BEAB4A8EB1698E03A1A344C88808FCF183AF5F6905B1B445CC9235BE74C1DB07D794BB867331EAEFB52AA165E31DB2048A62CA4D5197B3AB327281B132B0EAA18B1D8699EDCFB730B905A517036E3EC9BF40AC4F47440BFC231693025CA297B4F5198DC094066919934F32E5EA6712937CFE458A2BF916D382933A95487603B4AB303CC81BA94E467576787B7D8095B059020E6C43069745CA03C2B31229F2CE021F4D9BC38FC2886EC9570F2671872C766D40C970A0825083A01961FE97C9214533F3A8562E620A0C8B5354E8989420B4F639B323E415D8AD4732F299EFFF99A7AB47A100CB05F31C158F37FBF8B7B7F477DD3398A20F07F9BA0605AC67CE4379932D0B2E7E236882093846AC42B64806F4C3E035BCD1EBAB1D54084B63C870217B210D2CE816A35BAEA8CCF2C7FB4938FDDC320D9B81751116C4DBC2269C37413206704B631BE653BD20B7F920305F9EC8C46805E95FC504B1C33BDB5A1AD912F8D65221A784922A63578201FF3E869DDE76AFDC9068F657CD0B66E8D441DF7E642A01220F8001D6A1558F5F73F49C13F3E1BB8A9E7BFB56B677CD6AE6FE8C85C24CCD7A78790E1AD8809A8F964B43228155D2872A9B11849514035F154799202A0299C41F80D9D1A67A9D674C360C5B1E36D78F66C722392F167A126F09FCC4310A9320137EBA898E786F95B9CC5D0B9114206EC66159BB3A687427D3B2298F1317ADE160EBF44CAFAA62B38871C6239C38F67CA0922C9DD952D8AA55AA6A481386771FD003A271B659F4B730B589B717635E6EB62603C5BD6C96756DB4947C5B1A71B970CD16B6D2519205C08147685B7103BB7C130B40C11CFE9C73866567175CCCDF40522C10A80140D78F9A71C714BADB1CE2732B86BD0518BF4783FAA00694208C3C2BD4BA34DEC08ADD425A0687A0D8B392702DA57504A28E9099912A8AE4A964765D35E739C1C3158330F4C21DC3A58969AAEBC788EC8177443732EAA527DC1E5009E010D8F980369FCCB48527AA27C6553393709F0B252E9346671465D33C072E352B2619175878F946488AEE3B5EE201C753244E6C85A1DE48BC994B4B1F9AB4F81B9C9F6C243C4A57BAB99781CAB1FD152A205A893F07F16431401F746B5EC790EA89C8C672EB7267EC34036F5F541C334B499DAB565387C2341C27F4904546917295B8F640CBCDF9B254502B58A669D36AA3D834793CC2A4D6578397D3A6DA893710F6A1839D8CAD7067A020108BF98415569A5C5856C5678C9A41A3075F077E6150F54B57FE91691A1C05F5022939A322CB919ACDA1236FEC9885AEB2C3A975E5BA238F5E713AA751093846915B003E624577007C7048B23E29445EE123AD3D6604D5006332CCD238A0E23020244D99A2C8A28CB58A76A69A39CC05927767ACBF892E3B6CB27231472C9189FBC1BADD18CB9A0CCB9E9CB08D0BA65C9924BCB2D88EA9739835C3B388A7B416A5BC5A27B01260D732F237474292133F0E458F33CBC3A687F149A1F8D7B08FE76A0C7C9330F8582D378BE0E2B135097CC9527A24FA3913BC3C98F04298CA86A08F6969D98C6EEDC19D6026D18D93479698A237B319B8CBC7E266DD34162FDB07C04A677C7B27E758A9D42DB0E35B4369C325C1F5639E0AA30B87433BC9C977447A2F97413E351BB98242D68E02527053A75A0CA93AB8E1E8B521F4BA09EB1B32D6797C5D7BD2AC76E81946CA48BCC787A9D35022C31F0938F710482B1A5DDF91A9024900D019AE33B182D6424D86B558109158B188C3978B5345A7D85B70B30888083C50CFAEA947258891A192B05D8589A0B7415F6945D1275B9C12DC25055B372553D21ABC7B96BD7F821B0C78D6AC3CD5BEA024720625611126220A5A467A60C268B748632C6B19403391391D649BE701B85592FF7F256937843547339E01179E2D79F9D88168528CE5FD5A819108456A789F094093E3980413A14F11B71C57BC71617CA3234008B2907447B8EF8A58B87450AD9506BB84C9E3F66BCE6CBC5D503434D406387D8CDC22A64D53786C79A90C911723D8799B3A7B9AB20672DA92572FB609AC14D57435736055B89F9851DB4B621AA42610317F15802FFB457620B4A7712212DA5725C049E1FD3670DF15ED5A945549C38DE4826BEC844500A313B41921E21AA5EF186940497462117EBD8B383520680DC2646683E0E819B2DE992A82380F400BAA20560AB7A58D2176D4885204ED705F21084390C5AAB8879214286A1F199B3949A59E11B86582B5C13080766C7E2091EA99F1352D4488C7EA1547DD87024156A9FB2DF0C77B684540084890847AA6D85E8BEB5E40DA16CD0B6771A006BD6CC2A5BA77C278E3EDF52912210F80A5E1759F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1" - }, - { - "tcId": 50, - "deferred": false, - "z": "4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E", - "d": "D21D5AFED9AFAA3B49FB45245B2BCA1505E4000CDC29094A3600F5CAA49A7B3A", - "ek": "744793A77A843520C9EB8B057FF28854193916F711902B1F8B4B9C235251FBDC8040C8A38C022557DB50CB28CC8DF99A859C2EC017C24015877D2A3572571FC783BF1E984401C11158E32A95351BE407A8AE6B5E054A33C2427F4A346761559F776671095B495074AF5CAC98D94297FB05624443CAA8151AF3A497F73203EF184CC7336650427CDFD47B10245EDDE30C3075933E431DC1B1C2A77B2073257C2AB73ABE706DE138CD54922CDB09CEFA60BA473092E43BC3E3CB951939B1C4CB2AFDCB4F8A5310FE9A790E560B25A40AC9E18D35A27238A60A126B398980BE8425C8A01B930FB336CB359F58131BBEE6AC450B8C811B2DDEA836F9D0C2C72A709E134321DCA727641A1D678A8E0CAE6BD6BBDAD8021AE3C1B6067FB1ECA42D215EC2C4297F6891567712F75047775B741713097B1271AFF026323A134DC20DEBFACE46D5B01820A9A862BA93E3AFCB5AC4C2204AF2E15787D0C857896D24DCBD6393C1FDDC12CDDA6A1F337B18D6C3CCD5283B37239A80424780399281C3FF1967B3BB6DAE499D42F511997077F38A8D63EB319342B1BC749924E467C6A2A11728826BEB52A39BA7A1A03C93C613D36A3F1F544B72A8BEC24009FDE07E677101456A2B76EC3353CB8944C339081A4B59672CD1B5446FFA6FC0B468D9FC83EBF896CE12158AFAA6812028F54B7920636784D3B3854030D05A9C19D936C6FACC5B81070CD524728A96A58A2E1207C73A4C533DDB00098141158B11DB674500781F47DB9B45F3CDE244502D377886418287C22075B2BD172606CCFA6F4914844525C113BCC7C049B3D14A2DF91B6C62E0A2EE5922DA3194DFC0C506D48ECCF5697BA31BD0839A4D3B3078CB7C2936CE1C507B0B54023585CADA6BA5657726075659DE16A6403110CE38A247CA85CE02C1DAC79FD175BCAAFA116F710516A4B73D78BFC6F9854228B6C5F035946B1F61B629F31328A65556C8F0661D58622C6021F58C1ACF154C6E78BCF563352AFB89B824513A35502F117861A34C52B1011F696A85185186BBA23B518C720763529C181D902CBBB58CFEF77CD2E72F4780979FD46126C0A4BC1965A6E070FC284B1F856852110E19C268390CA9494116EB293F1A111ABEC1AF04F706B114617F0362B3DB4B99E076287AAFB7127FE2C68904F61664D63D4FB267CE07AD5A659FB81886F8E0A9C26261A0055F48F432E9F8242C439F58B5A21EB777483B2E68B3B1118562430270340243F1E87C22CB5BE2F167DC39CF4C69B8B8E9B726256CBE605342F47E23A871BA7250BDA8997FD474B3375920522F2C511B3EA35CF459342893AA12B128CC2184E304335AC7BA04653898590A664672FE744F301651442BB341D32F36262C576A50F803B02F91105FEBCABEF7030D2A76CBEC6C2CF36283590BB44842853102D3D350801167D7A96968648C0CAB9AFD39CB7F658909283CB83CA78544929AD90069CA3E660196792A654A911CAD7C23024C90E25AA61B30A4D568C5A5C12A53565A93E910D5940EF3583856017BC25B05C4473F48584C6908C13D2B19E7A3A7992976D31A464807199AE3A6307CA55765590F6B4721632D70FA47E2C1098E36898BE3125E43C61CBB7A6C246CBA0002CF325A5D337989289BCCDA54835511DE9656287363DEE85033410AEAE1", - "dk": "045AA22AEAA4A8E0C66661A183700F04025D413CCDCBE1B7CD9B839BA61671B08A859B1AECA9014CB3695B29703CD4314954C48CC19A89E106079720EF23B597FA6A833638B7A7B1E74A40C8BA7A005AA799D22DC5AA97627A037BA2623C659621EA2FF40651DAA0A95B2218CF934DB132BDE8A29F889BA084DA3EA9C8B58FD1BEF4D45EB4A2501447640C7869F21C9B031718209288E442018F63097459AFCEB75815829B16EC48FF822B1F69B6B48C3AA3C65441E60F552A154BD85A71397AB8290564F527FA8B1E84AB4EE6450EB5CA658B2120164B7D84637CC7488FFDF717F9349734E6B2F585C040065A2E910CCCA070C0070C2C215BC8060930D30D7A73A0FADA94E46257BE169B73D7A35DD43EB9B0183589AD657A429D983564031166253B4EE513AFE986E007727D75BA22F41A0AEA4939081C7CE1BEA5AA8D8DFB692AD37726E05A9DBA9D70102A1DE64479A928D9789035D4B645F088ABE8A51B06826BA64079C4AD3EC2C8A7EBC9F5EA6A0C707E88B2224DEA55FC0C39EC258088E319CA48C3F0C86AA203669F164E5FD0BA467548050CA496579BD4099D705A82BF9634995ACE60DCAC96C9115226AF2B6A9D86497DA1C49FEEE35F5639BA1A8363DF5114EA06C190179161C3C4238115DD55200BD28A03EACCAA46C7A9126B6F0CC2BFD9047D9BBF7A2043BD965F244158C7F10548FBBC39E040F040145A45B12BC90A74065BD3E34925C94FFA968BEAD241A79B6B0F1C3911C444E3958906DB8834984897CA886DC1B9D63CA43803C74C5633F003BD148A691D396C98BA81918A560542CC6435082957A70A312DAD0AC54F81903B2280BEF3638A013654D26E0D2705939A31EF39547FB80BE113A336E277E04B8B905C9DD90509C434277246916A1A0A7E66BC1C74C4719751BD8879E07AB97721C0B27BC08B69B284F2BB47E43290F2BB434C489570C22AC867F06643AB100457D336CB944B6B5A185B639A403A332FC755584A9F2EAA315C319D3099B30710B7EFAA5BBE8A3981A9B158E0C7484595AA1B7CA3F335BB38A7E5AB51F2799E0EC2049AB781514A82CA7CC5A53BCFF3029320636285902EC1D24432B5292EF7600097929D374F3485AB2AA5C8A154CC3171693DBBC4382A5E44600AC8B1646A84A47B078D06EC554A309A1FC2BB473C69EA4732B6485BE812A1004D583D9A0B9953312CAB9B014A482D8C7BD1097231D0041FF599D0E043C7CA08FD0CA71AEB977EF271EC13AF122766566BCAEAA26554F87394847C50DC2B8D3885184069B1A173D1183E68C55867E55EA78610CC3183A7F60181D1751A12107225C7156B99F86846FDF5777502A201FB583202B28EB78EEF356918D2B5B7594AE364902D45C2E8691137C98CA7B2425274068D765AFF29095ED546309C2D4CD6A5DE0571E67566DB14C386A87F15379CD1190EF02806D6B8387C87C73B805E01DB128C0A86C1013FAA7CB7D46770A0835C5343C931AB8CFDF56AE4241108C55976F127334AC3E2B52360661B61532CCB641CA043AE9B3173D0133CB0E4581748B6F1AC00BA0BAE4960376782A25F36765A1A4318D73C18781C90755C657847ED6849CE1301B11A2FD75616B4F326DAD545744793A77A843520C9EB8B057FF28854193916F711902B1F8B4B9C235251FBDC8040C8A38C022557DB50CB28CC8DF99A859C2EC017C24015877D2A3572571FC783BF1E984401C11158E32A95351BE407A8AE6B5E054A33C2427F4A346761559F776671095B495074AF5CAC98D94297FB05624443CAA8151AF3A497F73203EF184CC7336650427CDFD47B10245EDDE30C3075933E431DC1B1C2A77B2073257C2AB73ABE706DE138CD54922CDB09CEFA60BA473092E43BC3E3CB951939B1C4CB2AFDCB4F8A5310FE9A790E560B25A40AC9E18D35A27238A60A126B398980BE8425C8A01B930FB336CB359F58131BBEE6AC450B8C811B2DDEA836F9D0C2C72A709E134321DCA727641A1D678A8E0CAE6BD6BBDAD8021AE3C1B6067FB1ECA42D215EC2C4297F6891567712F75047775B741713097B1271AFF026323A134DC20DEBFACE46D5B01820A9A862BA93E3AFCB5AC4C2204AF2E15787D0C857896D24DCBD6393C1FDDC12CDDA6A1F337B18D6C3CCD5283B37239A80424780399281C3FF1967B3BB6DAE499D42F511997077F38A8D63EB319342B1BC749924E467C6A2A11728826BEB52A39BA7A1A03C93C613D36A3F1F544B72A8BEC24009FDE07E677101456A2B76EC3353CB8944C339081A4B59672CD1B5446FFA6FC0B468D9FC83EBF896CE12158AFAA6812028F54B7920636784D3B3854030D05A9C19D936C6FACC5B81070CD524728A96A58A2E1207C73A4C533DDB00098141158B11DB674500781F47DB9B45F3CDE244502D377886418287C22075B2BD172606CCFA6F4914844525C113BCC7C049B3D14A2DF91B6C62E0A2EE5922DA3194DFC0C506D48ECCF5697BA31BD0839A4D3B3078CB7C2936CE1C507B0B54023585CADA6BA5657726075659DE16A6403110CE38A247CA85CE02C1DAC79FD175BCAAFA116F710516A4B73D78BFC6F9854228B6C5F035946B1F61B629F31328A65556C8F0661D58622C6021F58C1ACF154C6E78BCF563352AFB89B824513A35502F117861A34C52B1011F696A85185186BBA23B518C720763529C181D902CBBB58CFEF77CD2E72F4780979FD46126C0A4BC1965A6E070FC284B1F856852110E19C268390CA9494116EB293F1A111ABEC1AF04F706B114617F0362B3DB4B99E076287AAFB7127FE2C68904F61664D63D4FB267CE07AD5A659FB81886F8E0A9C26261A0055F48F432E9F8242C439F58B5A21EB777483B2E68B3B1118562430270340243F1E87C22CB5BE2F167DC39CF4C69B8B8E9B726256CBE605342F47E23A871BA7250BDA8997FD474B3375920522F2C511B3EA35CF459342893AA12B128CC2184E304335AC7BA04653898590A664672FE744F301651442BB341D32F36262C576A50F803B02F91105FEBCABEF7030D2A76CBEC6C2CF36283590BB44842853102D3D350801167D7A96968648C0CAB9AFD39CB7F658909283CB83CA78544929AD90069CA3E660196792A654A911CAD7C23024C90E25AA61B30A4D568C5A5C12A53565A93E910D5940EF3583856017BC25B05C4473F48584C6908C13D2B19E7A3A7992976D31A464807199AE3A6307CA55765590F6B4721632D70FA47E2C1098E36898BE3125E43C61CBB7A6C246CBA0002CF325A5D337989289BCCDA54835511DE9656287363DEE85033410AEAE16C770D1FA4C0F5DBB660530772FCC2297F59BC9DEE338CD124F0924CF7E3762D4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E" - } - ] - }, - { - "tgId": 3, - "testType": "AFT", - "parameterSet": "ML-KEM-1024", - "tests": [ - { - "tcId": 51, - "deferred": false, - "z": "99E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7", - "d": "49AC8B99BB1E6A8EA818261F8BE68BDEAA52897E7EC6C40B530BC760AB77DCE3", - "ek": "A04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21", - "dk": "8C8B3722A82E550565521611EBBC63079944C9B1ABB3B0020FF12F631891A9C468D3A67BF6271280DA58D03CB042B3A461441637F929C273469AD15311E910DE18CB9537BA1BE42E98BB59E498A13FD440D0E69EE832B45CD95C382177D67096A18C07F1781663651BDCAC90DEDA3DDD143485864181C91FA2080F6DAB3F86204CEB64A7B4446895C03987A031CB4B6D9E0462FDA829172B6C012C638B29B5CD75A2C930A5596A3181C33A22D574D30261196BC350738D4FD9183A763336243ACED99B3221C71D8866895C4E52C119BF3280DAF80A95E15209A795C4435FBB3570FDB8AA9BF9AEFD43B094B781D5A81136DAB88B8799696556FEC6AE14B0BB8BE4695E9A124C2AB8FF4AB1229B8AAA8C6F41A60C34C7B56182C55C2C685E737C6CA00A23FB8A68C1CD61F30D3993A1653C1675AC5F0901A7160A73966408B8876B715396CFA4903FC69D60491F8146808C97CD5C533E71017909E97B835B86FF847B42A696375435E006061CF7A479463272114A89EB3EAF2246F0F8C104A14986828E0AD20420C9B37EA23F5C514949E77AD9E9AD12290DD1215E11DA274457AC86B1CE6864B122677F3718AA31B02580E64317178D38F25F609BC6C55BC374A1BF78EA8ECC219B30B74CBB3272A599238C93985170048F176775FB19962AC3B135AA59DB104F7114DBC2C2D42949ADECA6A85B323EE2B2B23A77D9DB235979A8E2D67CF7D2136BBBA71F269574B38888E1541340C19284074F9B7C8CF37EB01384E6E3822EC4882DFBBEC4E6098EF2B2FC177A1F0BCB65A57FDAA89315461BEB7885FB68B3CD096EDA596AC0E61DD7A9C507BC6345E0827DFCC8A3AC2DCE51AD731AA0EB932A6D0983992347CBEB3CD0D9C9719797CC21CF0062B0AD94CAD734C63E6B5D859CBE19F0368245351BF464D7505569790D2BB724D8659A9FEB1C7C473DC4D061E29863A2714BAC42ADCD1A8372776556F7928A7A44E94B6A25322D03C0A1622A7FD261522B7358F085BDFB60758762CB901031901B5EECF4920C81020A9B1781BCB9DD19A9DFB66458E7757C52CEC75B4BA740A24099CB56BB60A76B6901AA3E0169C9E83496D73C4C99435A28D613E97A1177F58B6CC595D3B2331E9CA7B57B74DC2C5277D26F2FE19240A55C35D6CFCA26C73E9A2D7C980D97960AE1A04698C16B398A5F20C35A0914145CE1674B71ABC6066A909A3E4B911E69D5A849430361F731B07246A6329B52361904225082D0AAC5B21D6B34862481A890C3C360766F04263603A6B73E802B1F70B2EB00046836B8F493BF10B90B8737C6C548449B294C47253BE26CA72336A632063AD3D0B48C8B0F4A34447EF13B764020DE739EB79ABA20E2BE1951825F293BEDD1089FCB0A91F560C8E17CDF52541DC2B81F972A7375B201F10C08D9B5BC8B95100054A3D0AAFF89BD08D6A0E7F2115A435231290460C9AD435A3B3CF35E52091EDD1890047BCC0AABB1ACEBC75F4A32BC1451ACC4969940788E89412188946C9143C5046BD1B458DF617C5DF533B052CD6038B7754034A23C2F7720134C7B4EACE01FAC0A2853A9285847ABBD06A3343A778AC6062E458BC5E61ECE1C0DE0206E6FE8A84034A7C5F1B005FB0A584051D3229B86C909AC5647B3D75569E05A88279D80E5C30F574DC327512C6BBE8101239EC62861F4BE67B05B9CDA9C545C13E7EB53CFF260AD9870199C21F8C63D64F0458A7141285023FEB829290872389644B0C3B73AC2C8E121A29BB1C43C19A233D56BED82740EB021C97B8EBBA40FF328B541760FCC372B52D3BC4FCBC06F424EAF253804D4CB46F41FF254C0C5BA483B44A87C219654555EC7C163C79B9CB760A2AD9BB722B93E0C28BD4B1685949C496EAB1AFF90919E3761B346838ABB2F01A91E554375AFDAAAF3826E6DB79FE7353A7A578A7C0598CE28B6D9915214236BBFFA6D45B6376A07924A39A7BE818286715C8A3C110CD76C02E0417AF138BDB95C3CCA798AC809ED69CFB672B6FDDC24D89C06A6558814AB0C21C62B2F84C0E3E0803DB337A4E0C7127A6B4C8C08B1D1A76BF07EB6E5B5BB47A16C74BC548375FB29CD789A5CFF91BDBD071859F4846E355BB0D29484E264DFF36C9177A7ACA78908879695CA87F25436BC12630724BB22F0CB64897FE5C41195280DA04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21D2E574DFD8CD0AE893AA7E125B44B924F45223EC09F2AD1141EA93A68050DBF699E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7" - }, - { - "tcId": 52, - "deferred": false, - "z": "007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D", - "d": "2D229AB46354901491476CCE8FA96E4A5FBA65AB2F538FEDAA528E35687A782B", - "ek": "C5712512984D94A039FC87739DFCAE09934E7658A82FB0895A060D54F900C5AC1161DA09E2D833D5B60E60FB000AF1BF4F43B059B8272E79AF4572349940209BB21BA3BC3B1B6ACC281A35DAA15923496D0FDB32A8505DC8626847627BDE759175F11B457539465CCE3E591933D8B458F561EBA446711CBDF2B604E53B7EE0E0C2C0A15C35AC2A2C91BAC918170E5372C542636D7526BAFAABD10CC6F4382B01C74AE28B47289AB5E463A584465C9994B739367C9F82639801A3681768E134185C9A0DEB8965079A99451418EC051D0D723FECE5B53488207FF7994082C16043B13D278ED530640BE0B4F9AC75B52429EDCA9BC4FA7BDCB43FAB630DB25A5EF576461313CCAD5B2E85E36EBF9594689201458C9B2D96261221C8D3C21D91F53D83F0676ED7A78A6177791557DDFA33FE39699C19339AA9ACD70B34D9036D5391AB57ABB2A5EA368675A565D24A796193351A37C69A5866F4C99482CE4BB3B7795B83E584761EDAC6BFD8CF2433AFC53641E4689571B999E8236A151B6E42855F7E9BBFB8040FFA59CDE707612C9C717F5827DC2B51766889784A6942E8957E6AAAA5D8413F76A37FE69F6259CCFFDC7BECCCC1DAE419D969620C0AC674367558F532EF697058250113DCA01C051A88FABE2CC65795949166857F0F89104A1187C9D30517F25F49308BE4634AAE29B30C8360FF3CC38B5A7BE717584C10A79929B36C1516DE545566B76EACE143E011A4FD42702E95139EB2A746FC04AC99C5E9F07344C83020C34165F9572CD86F50BB9A55B13C6DF33305C8601FE1B103057519BA43B8EC1BF37603C0495F40087CC68A808848429F64BEC6EB336C37AC50F2B5CAC04D6B59870E4ABFBE773664C3926D2954E3D57F2C8147683A519B7264DF40CAB6F3BF262B760BF794416A5D601776E5165FD50C4BA4B07C49AC494C699C4705254A450B36CB38EAF96D6B0270492B84E5A5C208D6ABED761F033138D3BC9FCE42C17B160696C7CA9726BBD2B1C1E42C92556A06A5018EDF605B2D789688CB85066CAA0528BDA4E32542621727301B90333C1E4393FDB539ACF8AFC202BBC42546BB88A04AF9C089717F4073360B567D3967620BD8ACD0BA1762C56603647DEE371F552C92C82A69B1E461E4D1572FBC881AB526B49358F21A69DD3C7CE32BACFEDA9D5CCC34E09B9443EB189F69798FC80B61011B76239EEDC7C77F1B78D3077C5549C48BA8BC720CC2C8B88FC85A9A5CB6C1DA0829C504A9FA502899926BF0DC8FF9C02DC9FC005676A84CF16E2B23B7A5946289E400D0D2387E36841A227B7F10822572BD62F134EEDBCF1A66B6FCC907F9E0AF8D349FA8B5C4251C66B3690BB21A3253F3916020934381B46F1BB9C5F638BF8C8B256300B62B5D6F3A7FF680B514F6B3352A1994C8511957976836BF65979E13002AF1453C1FC037669B3465A0366B7B5F94F92C7707675FB08B2632AEF3D725CC4B3B6496B4BCEA2C865C982F7946079287D63931C8940B130776F5A7629A64915BC4B1FB09CD4C9114B1018937A83047EB3F22EB7EF5C866E9909CC89072E69C973EB22BEE6A3B1E383DA4006CCA560100C72BBA81237C1C7AB0A48A0CC58ACCE826B735C8BA19A87C9AC74E77295A8B26BDBB7685053C5A1572A09425CAE97D7F246D8D0B85AF20350999356ADA86628A787482393FD85A2166245B442F64B5516D595C471BA4CB577644738F87853F65236FF46ABAABEB9236616CF5999EADC9BA80F1C0FE8B6C45BCB543AB8E9097AF977612CF5A4E22C274A278472FA93E2B817706E11813F2B3865851C96683C83B52D2369DF3F74C111B4F4B01202277A918660B9641691412B637B7991973035F77B02D75A2143813BD49847F082C16E31EC89A2F8A588B2D40519892C939D782FFE18BE5D0BE1B5A41D594C32E246F886C37D43145DB8334B0E3364F65A76E0533FE052535DC7945669019E7310587C4C71A3883E1123A9A5BEA542F6D8CAB83CB905D26C82EF72A84285A07687ED90A2A32083F1D8519AC6289C9F6A5FE994C96ACBE0303BEB3B7A5A7457BC0118AE7008A0AD860310CCEA57BC313595A68CC8B682328D8C4440BA57E749BA40E968D09A0783CEA0CCA59B43FE9B42F157F38B67ED0379802ABC1CD50288D73581CCB59E3768C9801138B658FDAA87AC02DF5B5386C2DEFBB8605988CF7B1BC6CDF5C8F1F770EBE3E49", - "dk": "81D65577F87BECBC2A8975A7FB237049AC574D9C934FDC9764FB79597C0CFD236E8F516C3DB4AC0F627A02DC8426C051A6F0421B6A2689ECC469E92A0D816E85990E9298483902A6CAB76E74D476A9300E8121958306959AA362263C885B483E326285CF970BD84A694A553E9BB3AC3209AAE0F0521F3564CF352890289A530717F5E080A916613EB88304A7340A2413C20B02F62B58D68A3C97F57C8A11B1E58611A2A18B23FB3222E84D2ED287E002C1FDCA2D47C03DD5BC0B69210789241AC177907CC3916088B6D5E6B9B7C4C8C975725E38C5A3F54964057114D7CA565BB71F5C8C866A83F0E62AF7866D94C50E89B1BD8F1A8596B477AB743A427252D2128967B962F2E7590ED47670542BDF2162F8C2B1CBE434862670926330B90002E4C490B80A57CC4B02EC03B40CF6250E727C8E1C05E2C36E9E0AAC4FC0C4C4D89EEA2837408B53542513E5C898E62722415CB71B7A9EE7E8634A00028D549A2F912797C84778B7C5D4559A885430124A5D161789EA8972EC9A5298693F4857A4AC905E53A8866148117AA60D43938F84BA60F8C15B7BC88824611AB8EB74852155BFA82127D052B6138E8A7ACF28774DC2C798EA9097723BCD2EA4A0A1B38CB666830008A256F05057D126E9C440AAD52AC7C4B2E370914C2883ECB13AA5F53E43A25D59661809C960545186BB6931BB45561307A4D45C1A0EB80EB0B4166AB12EAAF8CF4D25CA4A8454B179246D3019B8EB5CD86B2BE40513C7828653BC08CC652FA59665DDDB0B94E4AEA22431F7557329434C688B5CC0789E675B0A9395AD2CAC7DDF166E0F5245DF835A00CC172B3A6192808741652C4025566C43177F5A9911B317009A38ADA45F8339693971AA1D773D6FA240F6D7880BB5244115AC2EAB5FC2408BAF4705C7E016E9B1B6A47567DF5298F47437F1C74949232EC496C3054B0A4805C8CAC2255950A8B7F683CF5B531C4C798554963875928CA4204AE8755AF433C2D52784A36404E1A368CC4FAD29BFD879565CA3CB52D56B3F273E7CEC08A1D7180F5037CA61B289828AA3838D01F9958388779ED2881FE894A9D3699542BC0A2C497F7251986B50EFF284474794C845A53E12205FCB823872640B1A8583856DBE11BD6DE49AFC0142AD940EE43B06D9D7141674212297B8478B784FCB8A886508451B376822726E00CD7FA1CA16DB9F591007B2689E0C827929612035F5150800692ECB83B244964FE6922402297F244E430A06AB897DDEFC70742BCA5AF7B634A1B3C8C719EE2909A99C19EA602B7E22C66001CFE5401440139DD6398B26141C9B23914E5940EB35105131451DD3CBEF8654F0483887004D22AABD57559DFFC11038D3BEDE5CBD44DA0119D87610E0CBE392415B33A35F57364C1177DC514AD94570140217982593CD20BEF5E43BD0638EFAD1478CF9943DA093AFD278037010C7086C04A53C0F607D8B867222DB98A56436E6FC3B28D7382116706DB679D9316C473C6D86F85DC40B0A0FE24D8905321336488E20739FB11652EB62C7A05CFDA115791CAE294A0534491CA5EA8F5BA6730E06AF33964469983770D13C858CB66D091B02DA5181ECAEB9C4A241A2222DAA77B6E5020530474C891D440BA6E3F2137B215526001BE17185F0048F3DEBA1ECF7BBF1A55EC9D57485969B43821930DA7672B33630209F8257B8DD749FA9F6C73CE3C903B2300D7304FBBBC6F5304F6DAB322117A621A851CDB66877A82C350B4F42525E16328C7B8A07948794CECAB06D7A7B13CB070C61A983647319E1B6B4E27FC900BD50F485B98121DB4180CB62AE4C3C68A8D59F18885EFEBC90B3F1C9F480B068DACDAD813A28EB200EAAAABD9A0DC5D72E9B4505778807AA6A52AD6142DC517443FC55CDFA56B2A6AACDB28B4B5045344CB418795241756943CC5BA1A4B73A2C90A2122121559FB15B015DB43B621B20F01A4731438B148395CAE4A7C36888FBF01603336991572753F35DEF2264D93BA831A46AD5FB3F663704617B712B81595A585123F03180F46285397551F27E98970DEBC2BF8298329BC87402869DF5B207C7415D1BA9615300B67FACB7A4AB1287E37938C2347C172F96A8826C944CA75C63488A9BDFD206B41C8E6E854B2D9C59D169361BA549254142387337A89C919C84512B2394C5712512984D94A039FC87739DFCAE09934E7658A82FB0895A060D54F900C5AC1161DA09E2D833D5B60E60FB000AF1BF4F43B059B8272E79AF4572349940209BB21BA3BC3B1B6ACC281A35DAA15923496D0FDB32A8505DC8626847627BDE759175F11B457539465CCE3E591933D8B458F561EBA446711CBDF2B604E53B7EE0E0C2C0A15C35AC2A2C91BAC918170E5372C542636D7526BAFAABD10CC6F4382B01C74AE28B47289AB5E463A584465C9994B739367C9F82639801A3681768E134185C9A0DEB8965079A99451418EC051D0D723FECE5B53488207FF7994082C16043B13D278ED530640BE0B4F9AC75B52429EDCA9BC4FA7BDCB43FAB630DB25A5EF576461313CCAD5B2E85E36EBF9594689201458C9B2D96261221C8D3C21D91F53D83F0676ED7A78A6177791557DDFA33FE39699C19339AA9ACD70B34D9036D5391AB57ABB2A5EA368675A565D24A796193351A37C69A5866F4C99482CE4BB3B7795B83E584761EDAC6BFD8CF2433AFC53641E4689571B999E8236A151B6E42855F7E9BBFB8040FFA59CDE707612C9C717F5827DC2B51766889784A6942E8957E6AAAA5D8413F76A37FE69F6259CCFFDC7BECCCC1DAE419D969620C0AC674367558F532EF697058250113DCA01C051A88FABE2CC65795949166857F0F89104A1187C9D30517F25F49308BE4634AAE29B30C8360FF3CC38B5A7BE717584C10A79929B36C1516DE545566B76EACE143E011A4FD42702E95139EB2A746FC04AC99C5E9F07344C83020C34165F9572CD86F50BB9A55B13C6DF33305C8601FE1B103057519BA43B8EC1BF37603C0495F40087CC68A808848429F64BEC6EB336C37AC50F2B5CAC04D6B59870E4ABFBE773664C3926D2954E3D57F2C8147683A519B7264DF40CAB6F3BF262B760BF794416A5D601776E5165FD50C4BA4B07C49AC494C699C4705254A450B36CB38EAF96D6B0270492B84E5A5C208D6ABED761F033138D3BC9FCE42C17B160696C7CA9726BBD2B1C1E42C92556A06A5018EDF605B2D789688CB85066CAA0528BDA4E32542621727301B90333C1E4393FDB539ACF8AFC202BBC42546BB88A04AF9C089717F4073360B567D3967620BD8ACD0BA1762C56603647DEE371F552C92C82A69B1E461E4D1572FBC881AB526B49358F21A69DD3C7CE32BACFEDA9D5CCC34E09B9443EB189F69798FC80B61011B76239EEDC7C77F1B78D3077C5549C48BA8BC720CC2C8B88FC85A9A5CB6C1DA0829C504A9FA502899926BF0DC8FF9C02DC9FC005676A84CF16E2B23B7A5946289E400D0D2387E36841A227B7F10822572BD62F134EEDBCF1A66B6FCC907F9E0AF8D349FA8B5C4251C66B3690BB21A3253F3916020934381B46F1BB9C5F638BF8C8B256300B62B5D6F3A7FF680B514F6B3352A1994C8511957976836BF65979E13002AF1453C1FC037669B3465A0366B7B5F94F92C7707675FB08B2632AEF3D725CC4B3B6496B4BCEA2C865C982F7946079287D63931C8940B130776F5A7629A64915BC4B1FB09CD4C9114B1018937A83047EB3F22EB7EF5C866E9909CC89072E69C973EB22BEE6A3B1E383DA4006CCA560100C72BBA81237C1C7AB0A48A0CC58ACCE826B735C8BA19A87C9AC74E77295A8B26BDBB7685053C5A1572A09425CAE97D7F246D8D0B85AF20350999356ADA86628A787482393FD85A2166245B442F64B5516D595C471BA4CB577644738F87853F65236FF46ABAABEB9236616CF5999EADC9BA80F1C0FE8B6C45BCB543AB8E9097AF977612CF5A4E22C274A278472FA93E2B817706E11813F2B3865851C96683C83B52D2369DF3F74C111B4F4B01202277A918660B9641691412B637B7991973035F77B02D75A2143813BD49847F082C16E31EC89A2F8A588B2D40519892C939D782FFE18BE5D0BE1B5A41D594C32E246F886C37D43145DB8334B0E3364F65A76E0533FE052535DC7945669019E7310587C4C71A3883E1123A9A5BEA542F6D8CAB83CB905D26C82EF72A84285A07687ED90A2A32083F1D8519AC6289C9F6A5FE994C96ACBE0303BEB3B7A5A7457BC0118AE7008A0AD860310CCEA57BC313595A68CC8B682328D8C4440BA57E749BA40E968D09A0783CEA0CCA59B43FE9B42F157F38B67ED0379802ABC1CD50288D73581CCB59E3768C9801138B658FDAA87AC02DF5B5386C2DEFBB8605988CF7B1BC6CDF5C8F1F770EBE3E4987A74BAADEC58CB97414E0D82652052055EEE3E3B64001A0DC6172A2A48DDD91007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D" - }, - { - "tcId": 53, - "deferred": false, - "z": "E94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E", - "d": "1D65D0290B15903371D616D7AC3F2FADA8CB24E6C84D52C039A10BC1288C1110", - "ek": "F4A4800C492B0472295F4B65471C6170C96DBD90130867CC68369DF450214ECCA22420CE39341A321682C054719B33469BA78C5F0ACD0CF466F2A188713B5154B279E6A6BC1A91032D4948B2D521E3090E450ACBAFC250EC72B7E6DBA3FED99F22730B0588042F33C50F7A81F368ADCB348864AC6DE5479EB1A041F9E3B04304CA38694B5A5B0A674659D6F9BD49AC964ABC4BCC532DB8CAC7A437371DB665AE4CC5B68CAD6AE475472A05F21981998CBEECA435E14C72293127A12659AAA5572042A2789A3B8FCC1D81AA1B95929BDD1A8E13192CFC700AF0E99C6A839EA71297A2A496D9045FBB9425FACC6CC5111868D48AEF176B7462B321308AB199B02CB3A6783749CA845DAAFC1C1C3BB2BA6B0F6C29BA3B428F971C750223B84A5ABAB4B77285A04E03E78D686B38990208A0FA740D01BD05B828F0D36EF5B1056183B93F8238F4AB7AAF872CB7916BD63AA6288337DABA6A5593BBE431ABE3497314F9529A9B5A7B8212C4BC23989A87419903E7B9A2962B310F865969264F2C0A0E6BD99E21C15EB717626D642FC2C6375578780EE13D05A6B3581C70B32C96E4D4178A7920F3A012D3C4C9FCD16556E5965F12AD08B294582A3F441467A3185111E53DEAC9272869671C2CB435E0B60DE5AE0A1A2A53818667500E986395A997722A626ABFA5310E4A43379C15CD3174F4F209379626EF6C4A1F076C73539F26E7C4651317C4545709BC757A92BAF5F417F6B4235A3535D5CB9A6D903D64C89B857A841EA25747F7A0D207729CBBB3CA9B32CB1A38D2AAAD124658C216533F4380ED108040559C8C92CB343C30A5B6A156903E69BA14A3B3C4E9B8C73B2C1ACFA302DB96B9C724B28E6AB1EE489867AAB84BEBC3B417048DDB0304EA8910C55BEC887E59EC336BD96947DA832B213FCF8C68D9832EE0289DFCD8B91DB20BBC81C2833C144A044E917904E9968D0D096482549C55062C0DFA6FB1415FE491051BD9A1DBE65417CA39A0A5CFC79B1A8D909123D287B1E9B7F2A683CB864D693C65BD770C54FB6C243441328C95C6EC7EE5C0802FC0973CE88AD589353A430A543738FC9A5F9EB1730C7060A8279C61527B486669E1C2995F242DE5C42DD0021858C2A3E07250FEB268BBB38FAEF7BE2C4C6CC8B5CCEC0005627874666055091283B7E522B2D96F52A60B031BC6549410AB769BDDB15717A0557561ACE7082FDC463209E63F94919BF3C33BCD012AB9321A0134C017441B578410204A5BF70C57D572C7D7A17F12A2176668A8D9E0C9C216AE9F2466B4F961CBD1256F247EE3B0B23F2AC39ED8757E8A497E161B551CAE1A2C6B88629EE4788DEF79249606195E186398F01CFA070E8B57156922AE4823468DF5C7C5F9065F38639BC77B78A4ACCE5496459346B6D07C49128F0C9A08BBD3C448B97A31255F0B6A388BC8A221009EDDA1AF9C819840C67DAAC24F54D2220058C378E8A4A23825A49A5D4B631FB3080ACAB9BE2DE3A258EA76B01C47B4D8703CD22EB78B02AA2260302192021A0FC031A6FACB03A33055F25A2BB1D6698B4A8DCA9238DD5ACD6787C8912066EACA67FDE86FB6C14687B076D19450CCF75EE328BF9DD6ABB89030AD08BB917B738024022E69A243E779355850B18A7C97F99039271F6EC47418661779C0A528D4079C5ABED21475B864078AA92F69E64F7F12B0BA661B066114F1F43EFBA89B67C05518C15537115DA0909B4A097361586C064A82B6790766944BF99176D090AA8DF599AAD37922B16A2553503AF1B4D7B90FB967AD5A637EFB019E257A6CF2AABD470157352A3196B9339715A1B254B5FF37C8A799473CAC6D0AC6A4AB56BF03271831A33EBA29AF1AE689FF54A2431B5A3F3BA83DB5A51B0492CC2C0DE31962293539278A11B408BF50C0B6D82A9764280DE4F8155201424DDC63F58AB413813FFA011EDEEB4B8B005E707880AF88392A472AD487CB6B6CBAE8787F5F8B4A5822B269E74FD91635EDE9541B5C2A5C9A6FE15722AB2BB61F225D08A84D4A9577D52617EDEC650E429A45B0397147920DE7201925913F029985C229D1044DC1895BEA961F936165CB24BC9DF884F6F49267A19B9B623FE0095EED29B0C75805BD9AA29EE857A9970533344DA99963C057337D4C25D517A341CA4BDB86C74DF0B23A56762B5838F5C68FACD1433B948824CB86D88A1560E77F4EB4A2A95E140B648DB88D", - "dk": "25ACA925E757A4BBA64CE712864669DD8BC9A55007B2C3510AE778DC85A877AB08EC454C61F32205E76C509B81040466BC47C9EAE77B10067C14F241C2E992A16708D1C1604B0C3F5885BD2C86B7B1E8BBD90903B0CA242AE206A6D31846973FA38B9D09402A35E45E98E84D1B125155D86E667960CC058AB25C2B053352C64BC03A78CD86D53BC298A3D586A08C1506103B301AE502176804C328AE1F24CD270AA76CC223709AB7E4B8AF3F28043F5C21B8721F8C228B7F908ACD7C4F1DE5C8939B643B22BDCC1576B65901FCC0720C622C4FA5BADFB7442CF63CCC513A8C7709D3C399469907DF740DDB3104CEB9C92C33113D258AF7EB220EB9AED0B2C1BCBA70CB9C76B840276EF11FAD35BED30CAFE633CCC4E3606F758A0F993D27F80F84473F770565B371ADF5E61689B0402D681F0D93745D625DAD286356A152F689413FB89A569CCC39E71912B3BD345AC5643725969B896328B24568428E5C651401447B490180003CFA674A5093982FA465FFE017B62BB042CC9C67C955B3123B0755430666330547C333196322843744B9213C5528585B4080265CEA0A4931D77C7D81BFE73008B37ABD62082287608ECB2CA6E50CC4C9529E32DB7BB70917A5BC3F8BDAB897E52320395749629104F3B60E27A0D3C09508E422497B7D6F711DE43C315BD83836538F88C30B7AE4A5B5B122D9394E34479D698C8B535354C25B5BE572513DD24A64985D78517AC2F3861330663C1A2AF6C135E0E49E5B930AC6A6A81A203E0A3A4BD1642A304C654681A8769C6C6AB009690A7BFF3B5B9FB64B30C2AFB9280FCF10377601B9047BC6ED0A07310091A97A8016735695EC704FD8493273B2DFD8C1A372C6B7A1A91DA08D3F2767B372A688228135F69D77D1A20CB03C69482A7B67A1E59249FD098E19BC84CEC247922A52A3EAC641F9383EA19200E16874E876AFA5C2598355F5EC01CDA86BE976A7420061C8D9A2F1E341F1378FBBF31DDFE3699DC60637138DC3A19B5FE17D27F0352743C76477363B7C72CBAA2E0F83CB53A82EEBDACF0642C5C39868CDE28F5E83A08046C38B9A1367B2B68C50869E6A9B44379AF1111133ACBF3E51738D2ACCE510A1B5F40B5D17CF5B5710C70B20A1A4734934123C2BC8B1D3714123A4159021B0688484398CA1346D0B5A9CE6AB299F439CE0B83A29261E67B905B944C8E74041431738D4272FB11254CB483907998F364235668C960AB0BE12580908093C31C37BC769BFB285451FF96155102376B8803DB777C15683B963765F2BC40B29558275864B0668F4C269F36B1D6E935C16A2B160E6B9A922080039A2946198BE02A82DFC1B86B310539502B61BC4B8DB533D939B973830EDD6382DD02AEB876ED7332954D2B0F1831953614CE6622BC91C3729F7BC6C45780974B4A40C07B5E4614C858CFCCC4C42E32CB3492F4F36546FB6ABFF9C6AD8C96B54818B3EE3545D2A2687E14C13B29248C69403A63D79A886195C630BA97AA52539C8949DEBE323F68C53EF5AB121D4AA0AC10D2A28A90B39C03187761DE728FDEB17FEF21257DB7199D665D5A5C37823ACE4830F09B3440A345C3627A136FBB416033BB0E73AD9F1B2417075D1F0C928778DEABB59C03A8813FC8BFC8B27797CAE5467C6FC934AF36922F8983E4A8B4F9BA79E2C1B7D9D2297AB273289B8A1EE2CAF8740A201A9C6F2ACCFAC8A0DDF51BDF076521E22AB196811E0834E96AB84606A1E1F018868604BA32C832FDA967CAB1C3021AA4D59A3E731242D7792729CA646D8B976370C2F93332500A9AF32684EF6B6EE7B3690B57409C4A78AC92F9E58CBCF9854B18A737114045EF72C5B808DB039126A8C22C605287292AF93B932AE153EB932CCC06CA4B8DC18AE8C0237EB1122A1C0C1C95E4A5118CE674990707AFA146B5AE620FB44A3FBEAB22649A37495825485634EAA6B7565BFAEA2493D3605D9AB5140C27FEB1350C93998CA8C5E52B14BDB9679763C20D8CA516CB8B5F089BC30E5B9DAE631D6C571AA572F40922E13E8C9488375603605C1D3505FF27033F57040B904D4B71A30098A260169B49495A1B52C76E924FDA088ACD56B90565A49BA8E0A1C66F186367AA7710157CF4A28B2223C2D034079E5ACAA88DB0E9DFB585C7773142A43535CC6083B1EFAB0A8F4A4800C492B0472295F4B65471C6170C96DBD90130867CC68369DF450214ECCA22420CE39341A321682C054719B33469BA78C5F0ACD0CF466F2A188713B5154B279E6A6BC1A91032D4948B2D521E3090E450ACBAFC250EC72B7E6DBA3FED99F22730B0588042F33C50F7A81F368ADCB348864AC6DE5479EB1A041F9E3B04304CA38694B5A5B0A674659D6F9BD49AC964ABC4BCC532DB8CAC7A437371DB665AE4CC5B68CAD6AE475472A05F21981998CBEECA435E14C72293127A12659AAA5572042A2789A3B8FCC1D81AA1B95929BDD1A8E13192CFC700AF0E99C6A839EA71297A2A496D9045FBB9425FACC6CC5111868D48AEF176B7462B321308AB199B02CB3A6783749CA845DAAFC1C1C3BB2BA6B0F6C29BA3B428F971C750223B84A5ABAB4B77285A04E03E78D686B38990208A0FA740D01BD05B828F0D36EF5B1056183B93F8238F4AB7AAF872CB7916BD63AA6288337DABA6A5593BBE431ABE3497314F9529A9B5A7B8212C4BC23989A87419903E7B9A2962B310F865969264F2C0A0E6BD99E21C15EB717626D642FC2C6375578780EE13D05A6B3581C70B32C96E4D4178A7920F3A012D3C4C9FCD16556E5965F12AD08B294582A3F441467A3185111E53DEAC9272869671C2CB435E0B60DE5AE0A1A2A53818667500E986395A997722A626ABFA5310E4A43379C15CD3174F4F209379626EF6C4A1F076C73539F26E7C4651317C4545709BC757A92BAF5F417F6B4235A3535D5CB9A6D903D64C89B857A841EA25747F7A0D207729CBBB3CA9B32CB1A38D2AAAD124658C216533F4380ED108040559C8C92CB343C30A5B6A156903E69BA14A3B3C4E9B8C73B2C1ACFA302DB96B9C724B28E6AB1EE489867AAB84BEBC3B417048DDB0304EA8910C55BEC887E59EC336BD96947DA832B213FCF8C68D9832EE0289DFCD8B91DB20BBC81C2833C144A044E917904E9968D0D096482549C55062C0DFA6FB1415FE491051BD9A1DBE65417CA39A0A5CFC79B1A8D909123D287B1E9B7F2A683CB864D693C65BD770C54FB6C243441328C95C6EC7EE5C0802FC0973CE88AD589353A430A543738FC9A5F9EB1730C7060A8279C61527B486669E1C2995F242DE5C42DD0021858C2A3E07250FEB268BBB38FAEF7BE2C4C6CC8B5CCEC0005627874666055091283B7E522B2D96F52A60B031BC6549410AB769BDDB15717A0557561ACE7082FDC463209E63F94919BF3C33BCD012AB9321A0134C017441B578410204A5BF70C57D572C7D7A17F12A2176668A8D9E0C9C216AE9F2466B4F961CBD1256F247EE3B0B23F2AC39ED8757E8A497E161B551CAE1A2C6B88629EE4788DEF79249606195E186398F01CFA070E8B57156922AE4823468DF5C7C5F9065F38639BC77B78A4ACCE5496459346B6D07C49128F0C9A08BBD3C448B97A31255F0B6A388BC8A221009EDDA1AF9C819840C67DAAC24F54D2220058C378E8A4A23825A49A5D4B631FB3080ACAB9BE2DE3A258EA76B01C47B4D8703CD22EB78B02AA2260302192021A0FC031A6FACB03A33055F25A2BB1D6698B4A8DCA9238DD5ACD6787C8912066EACA67FDE86FB6C14687B076D19450CCF75EE328BF9DD6ABB89030AD08BB917B738024022E69A243E779355850B18A7C97F99039271F6EC47418661779C0A528D4079C5ABED21475B864078AA92F69E64F7F12B0BA661B066114F1F43EFBA89B67C05518C15537115DA0909B4A097361586C064A82B6790766944BF99176D090AA8DF599AAD37922B16A2553503AF1B4D7B90FB967AD5A637EFB019E257A6CF2AABD470157352A3196B9339715A1B254B5FF37C8A799473CAC6D0AC6A4AB56BF03271831A33EBA29AF1AE689FF54A2431B5A3F3BA83DB5A51B0492CC2C0DE31962293539278A11B408BF50C0B6D82A9764280DE4F8155201424DDC63F58AB413813FFA011EDEEB4B8B005E707880AF88392A472AD487CB6B6CBAE8787F5F8B4A5822B269E74FD91635EDE9541B5C2A5C9A6FE15722AB2BB61F225D08A84D4A9577D52617EDEC650E429A45B0397147920DE7201925913F029985C229D1044DC1895BEA961F936165CB24BC9DF884F6F49267A19B9B623FE0095EED29B0C75805BD9AA29EE857A9970533344DA99963C057337D4C25D517A341CA4BDB86C74DF0B23A56762B5838F5C68FACD1433B948824CB86D88A1560E77F4EB4A2A95E140B648DB88D7456EFF3A15CD68111A12974CB06566E9007C376E09CB10D47C73E43546AB16AE94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E" - }, - { - "tcId": 54, - "deferred": false, - "z": "EC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70", - "d": "22D19527844F3CDB8A342620A96E902AC7C36E54677ADA6FE8DB08DF4EF3B36B", - "ek": "0E4C2891EB5497C1BEA0A62A0AE207018A2C0FAA8991D76CD14C47916853C326123A3C2997BC27A0B7073F97881EDA9CA18996779064AB768749869E66C4CA6AA58A8B155371B4729BE2327165B103393B23941FC6941A2BBC3C9D1489D6692E146B73A428241172C1EE63161C82A6666B7F5F757BEA328CE6AB45D0D87FBD007333EA927C3810A0A1790DDCC14A607D45A046E23C043CD96196659337FA940E67C565E70CD7D45511BA4C01631D43DCAD1C09833D64BE170A0681E0978D1B4F27E253BBBC5A4C2377299041333A1FA1FA0329B9B6FF24647E3B03954A85BDD637697CA834C95E1A992011D52D2719AD5FC410A780291CC575E82A2AC229BD8C6C42D4673E958ACBB6DC6EA644AAE5B10D5D90907E82614881182B127A53356A26A62C8463B26E5415C131BD72B16D2BA1175FEC0B6E59723FF7CF917968AFC91FE0698F40F55A9C730A1A493314991CD0329083B84292DB23D706755CEB4CF645A706E43512432848639AA757C61E727E8112A06B590488C4917C74041B92C1F34194A849211785C10FF71D27917D45A3B2A67966BA454A3B4829DCCC3CA8493612AB1EB554469E9950B4DB78E8D96E2352CC1AB2895FB16362143A25B3171D4C05A2AA5E5DB845220AB77EBA1166A5842436B226966988BCA3CAFC7997B0A261F97AA24C70BEC48CDDD491A1D2CFCC4455D06AA956348478580D1C70008C0B4AEA3CCFE9EA6C37A3B467652179B446F4D060B532AAB668554ABB88974BA6AF174861D52124EB9D05E60E62E11D67F34F1747951C2C6CE385BCEDF5476B882571579937F57C5C605351D12AEF9C6CD9B8BF35E95F7AC70D50C62B3E68899C39173101AC8EA326DF755BCEDA4B746BACEBE9CB8B233AFAC73075738BE4EB905D26438C5A68D8A14645462DE90783CCBB841431A452B632AD672494377CCE80974247951711A94CB907611C7E96E501EAA13BF225A041FCCFC0318CAC430C58CA043719668E59B4CAB34E2FC2ADE662C7DAD744CB5963ED6A9EF2449A000A6080C555DE2B3EA80C5AB7091DC18C4811697FF6E0A6D2D98489FB211B6B786ECB0ED793448351B80668A46ECB41FB8A642F10A0CC41A1F836303023C33B3B54BA6C2599268C433C6C0832052174739267CFD80C74C3225AC4D75CA8235108165E69F233C213B5AC547794E7CE59DC8D21D76B2CE0CECE43578FD0A1CD38200DF0C020D39563B519BC138B39D819A7A8AAF7D9C931EA75FA9B69369A7A6038B4D3937F7EFB14CE779CC1227B7732172AD10DB932531E426938D067144B6BF4F67C3DB0135573C219552719CB67ECFC07A489BB81F4A0773988E5AB3ADF7C75445868673B6D255B72AA73B32EFC015EA83010F96148A289B10101990290843CBA81E27AC58495F12CB05F5A8454E66F5B10CF0425BB6A1A8580C4C4110304C4717C84431447E510B837C8D70C8B589241592A107E6920FDF8627357C3C0D931F1F69EEEF1C3C518BFCF4305C98A86CE950FA40195F04B79C1471D0389792502C344DA14C884890898262E8292C3E5912A595D0E561CB3594FB4391BB5F4B6571969C86A8457633A5D8212393773D5D736380707BE35895948AE4AE8A672A16BE1E536549A194427C24080BDE083A63AB65240936F3FCA52DCE473EC08B765246AABD6C1F9549C0236676AA2AD234065C65672ADA92281696CD10A1AF1580A88E602ADBA75BC84B10A57072D1695BAE791E26114FCB408576516B7741D0CA9038D2C100884C417F2739930C50E408CC0A83023E6B13C236965802F62B00BFDD0032F98BBE7084AE0B5C6A26613470A8BE5B6C6BAC59B9B725C55C71E4E8A381BF88A0341943B942228FA6E3B3BB614887846F05461D632685486BC73A8E1794483125E58031DCE0A5C8E175C3B73AE08C01D2EEC8677C32F7A2B0D620ACA1D128E6B42095D8B9179369EA88B5697380B4C13552EEA86D9F8188A1C9093B794A9538EEC3A6D5F621A9D991DA6974E6A804D00A2864450C5AE59C4FFE2AEDC23AC522939D5D2204168CD8F8C59E87723DDD4809D2913F6825043EA6C7C9340A91914FBD13C65384B06B955AA221D302112C1F0802F71443FA9ACA95CB236E64886B4B0332BAF527C4AC3A9B4D8956D5FC2904911B944EC3F9FA07267342FFC4CB9CF15CEFE7325CD4C34B9A742B4214F50A50E58B9BD03C053806F0677A35438CF5EFCD8", - "dk": "3E793CFC068B5ED1B1E6D8ACB44ACF89C78CFCA91603E5182B598ED7937F9CA4973DDC1FD3A5023AC5A7C5B34DDD98B3CAFC2B548C9670C18EA16C15982B8B46F74D5A56AB08A1C517FB3543F678C3A97AB45A7A0FB9BFD12AA9BDA96E695674E5A78F3BAC74E033C5A3687A27A13D889B4A36BA339AA25730DAC64C464970FCB268F20F79F055EFC06964F6679AC56EDFB065C39B475370C98C4670387B97B2FC488E567E3B6109FCF28B764890B1E8529DC3BF58851EDA97358AA7B42C872EBFD832FF17B31E2471B091C3254707FC526521B9256997369927286B332CF3657CF3EA584F46ACDC2901B98A117C86430E00474611BA4043953685449D415237BA4E63D99F92835F3BC04C575008FF02885CE26027D914C67CC7F61CBD1C492C07AB1B278B68AB37A13A9C3CCF0BB84CA18DB371C8C4415D29A47F20DB1BC18B52AE4A831DA34B4A541C0D0C9EB17CB2675845CF809709338242A29C9E6239F7797A790A00CA407CBC536A079201C1E2672E343CCE0714A5E8C446D413BAD40E569280B2C2A255481A169A43F5AA501E61914EE35C2964B295914FC4158F7D3678D9B4C3869782DF96189FAB4FD7C171CF3210B7D27E34A593A5A215A4966CF73BC1045402ED8C0E7E548363600A871A0330B81B6CE482CF33C368956E1A49B848755B910A609B77389AAB1E6CF60D75555D21B16336589B474B059813828A8925C681524D9A5FFEF972736856ED169A5E6096E430466D03598619B3709CC91CF24DD4F55AD484B081356A2241B438C37CB250CDDE46072C16454706922F35C5267614943A9155169483D82CA716327501CE7DB313C771AA197367E8E11E5092A519DB2D26FA390BD8070390294589871EBB26CFD636D3D438BB9B0055A8C99F31AFC91245650483945C2C265170D6724102B0B9D0EAAA914CA85C941A6D90668A39582C515C5EC10200C1458D53B0A5B012B4D8B27F917D151C0896C9328903C49DB6B4FBC4526722ABD17C2CDA19A3519BC781C00DF97C5642798359DB358DC153B2885AD8C4BC59E94242BCB3436460048A248CA40F8AF3BF04799B603037567C0A85D65DF17CB9C520B4B56C01DF4C26BFD39FF4D27A1984358465AF96558054A89320434910A54E80D860BC38168D7C1E0F978720CA64C57B7ADDC98B713813F7098D548631BB062B069682E30547AE8BBE394551CCA1A506ACCF37A8B052E86F03DBBFB3025482EA1B2FDC2A9A9B077024B2F0827A33E7661C199201365A840A11F3F649A4097F630B7EFB734438E83C67284E12014282804C46049AE7438352A9AFAAEA2F843A347D753972728B4AF1954248291B4AC278A8813FF5083C582FBB1B8D4D49A227A49A99FA04827265F8C9902B98B299CA4A22668096DA77F7651DF1DC723CB98DB9B921ECDA5634451BC5B94663440F35A358FD8174057A38EEC579E49209B11CCD2DE729E704749E70AD13678BFD365CA26192965076F1F3868503C450DB964EF48061159B0841A06E9A2D51FB78C6033E5A063D30D2C160526531B3BE8EC561D32857136C3E1FF757D150A7E48B876928A1D4BAB34162180E94545285865A6C6988645D1A746C6C744B196C317E6AC95163353EDC381FB7AAD5E07993BC3141A64489762F6B9041CA438F2C135FCD737503A64FE1E5592FA68587B40A7F9913DC560D1104C1A08CAD82275B4AE0838B3BAB51283078D619B77C82980569C524A50158B8F3D352F3060530E9AF6CBC9613C67110773F1A6892E3A83D30B918DE545FA48B19A797BC2A7246D29B251A46325F453EABC1B8EF795A24E488F3C269CE04C3EBC8C0CAC82DF837B4EC46AD747721695C5C18A45EBB52BE0CF608AA08A759F236BC59357387006968C913E97856810DBF266E16F46DB5585D8DC6510A954D3C090B4283318633609A7B3625C54EFC975A127C625AD768F1C03D57584B7D2012E680CCB4EB7A1C822E4BC3182D0483A6D894AA77AC35795717674EB0FACAA0B9C172DB95D257058E7A31B7F6951A3ACB8AA531EE9516C097AE8981671E2381BB523388082D2B07CC9B576401A5C195C05FD1C0849D02869B2834772A1EE6776EE66A970CE2B9021193D13C2642A2A3271C093DC858424115B9C1628AFC31BCF7AE18783602813012750A4CCABB1E609C2A649E0E4C2891EB5497C1BEA0A62A0AE207018A2C0FAA8991D76CD14C47916853C326123A3C2997BC27A0B7073F97881EDA9CA18996779064AB768749869E66C4CA6AA58A8B155371B4729BE2327165B103393B23941FC6941A2BBC3C9D1489D6692E146B73A428241172C1EE63161C82A6666B7F5F757BEA328CE6AB45D0D87FBD007333EA927C3810A0A1790DDCC14A607D45A046E23C043CD96196659337FA940E67C565E70CD7D45511BA4C01631D43DCAD1C09833D64BE170A0681E0978D1B4F27E253BBBC5A4C2377299041333A1FA1FA0329B9B6FF24647E3B03954A85BDD637697CA834C95E1A992011D52D2719AD5FC410A780291CC575E82A2AC229BD8C6C42D4673E958ACBB6DC6EA644AAE5B10D5D90907E82614881182B127A53356A26A62C8463B26E5415C131BD72B16D2BA1175FEC0B6E59723FF7CF917968AFC91FE0698F40F55A9C730A1A493314991CD0329083B84292DB23D706755CEB4CF645A706E43512432848639AA757C61E727E8112A06B590488C4917C74041B92C1F34194A849211785C10FF71D27917D45A3B2A67966BA454A3B4829DCCC3CA8493612AB1EB554469E9950B4DB78E8D96E2352CC1AB2895FB16362143A25B3171D4C05A2AA5E5DB845220AB77EBA1166A5842436B226966988BCA3CAFC7997B0A261F97AA24C70BEC48CDDD491A1D2CFCC4455D06AA956348478580D1C70008C0B4AEA3CCFE9EA6C37A3B467652179B446F4D060B532AAB668554ABB88974BA6AF174861D52124EB9D05E60E62E11D67F34F1747951C2C6CE385BCEDF5476B882571579937F57C5C605351D12AEF9C6CD9B8BF35E95F7AC70D50C62B3E68899C39173101AC8EA326DF755BCEDA4B746BACEBE9CB8B233AFAC73075738BE4EB905D26438C5A68D8A14645462DE90783CCBB841431A452B632AD672494377CCE80974247951711A94CB907611C7E96E501EAA13BF225A041FCCFC0318CAC430C58CA043719668E59B4CAB34E2FC2ADE662C7DAD744CB5963ED6A9EF2449A000A6080C555DE2B3EA80C5AB7091DC18C4811697FF6E0A6D2D98489FB211B6B786ECB0ED793448351B80668A46ECB41FB8A642F10A0CC41A1F836303023C33B3B54BA6C2599268C433C6C0832052174739267CFD80C74C3225AC4D75CA8235108165E69F233C213B5AC547794E7CE59DC8D21D76B2CE0CECE43578FD0A1CD38200DF0C020D39563B519BC138B39D819A7A8AAF7D9C931EA75FA9B69369A7A6038B4D3937F7EFB14CE779CC1227B7732172AD10DB932531E426938D067144B6BF4F67C3DB0135573C219552719CB67ECFC07A489BB81F4A0773988E5AB3ADF7C75445868673B6D255B72AA73B32EFC015EA83010F96148A289B10101990290843CBA81E27AC58495F12CB05F5A8454E66F5B10CF0425BB6A1A8580C4C4110304C4717C84431447E510B837C8D70C8B589241592A107E6920FDF8627357C3C0D931F1F69EEEF1C3C518BFCF4305C98A86CE950FA40195F04B79C1471D0389792502C344DA14C884890898262E8292C3E5912A595D0E561CB3594FB4391BB5F4B6571969C86A8457633A5D8212393773D5D736380707BE35895948AE4AE8A672A16BE1E536549A194427C24080BDE083A63AB65240936F3FCA52DCE473EC08B765246AABD6C1F9549C0236676AA2AD234065C65672ADA92281696CD10A1AF1580A88E602ADBA75BC84B10A57072D1695BAE791E26114FCB408576516B7741D0CA9038D2C100884C417F2739930C50E408CC0A83023E6B13C236965802F62B00BFDD0032F98BBE7084AE0B5C6A26613470A8BE5B6C6BAC59B9B725C55C71E4E8A381BF88A0341943B942228FA6E3B3BB614887846F05461D632685486BC73A8E1794483125E58031DCE0A5C8E175C3B73AE08C01D2EEC8677C32F7A2B0D620ACA1D128E6B42095D8B9179369EA88B5697380B4C13552EEA86D9F8188A1C9093B794A9538EEC3A6D5F621A9D991DA6974E6A804D00A2864450C5AE59C4FFE2AEDC23AC522939D5D2204168CD8F8C59E87723DDD4809D2913F6825043EA6C7C9340A91914FBD13C65384B06B955AA221D302112C1F0802F71443FA9ACA95CB236E64886B4B0332BAF527C4AC3A9B4D8956D5FC2904911B944EC3F9FA07267342FFC4CB9CF15CEFE7325CD4C34B9A742B4214F50A50E58B9BD03C053806F0677A35438CF5EFCD8CC8CB55EEE0FF5BA0F84F958550BE099B0E692A35E0908A5FD21A36B521C0F1EEC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70" - }, - { - "tcId": 55, - "deferred": false, - "z": "5B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D", - "d": "A00D1EE4147DD57B5E76C58A928DED0B720FB2FB6353780B380B5FBC76712E5C", - "ek": "B3C014D82BC4BFA186D2E2A4FCFB57E2205FE91195E1ACAA18A3699D1BA700770482C18160082946D85BE262136B7B1F5BBC00D4D20A1351C66966CE3C1A06EBF35A43036A5498424C73BA01C250C61399CE951AF176C96F317B0A23395164075A23A6D6A55916F5032310B5E28B1B970C3AB75B4058C86DD9A73ACE89B9F5A272A86B433AEB9AD755B166105AE0095645910E0AD6045C075B82596140213DCD231C03D0786C186C95342C01265B03A2A113374307B49062727C82F2CBA44862C7691703374AD76B772DA400C283A1AAE348EDA9582B9B42196216A8218305309C367648F58785B74A9E4DC068318BCE4CA87000DC86ECC52F2D465762A58BCCBA755E7A881AE5704C643278E784E646C48AFC3F240A728C4A6D2B6523EA3499C9344294293497D3A4A3E2373BD2CB48B0575DA052253693D1DB696DA0057B2243525AAB17770D61D09D0F3554D10AA7A56B6CB9A81F59EC73A1FB9A08D7BB08D90F70117A2988409B870AA2F82447E14DE7B3C16503CE645BA54EE5C6E71909642A3F76620AE0D479A6440AA5E457A946A884D0C741A2C7F27C9EA9E716EE1C01154120E777930E991C63E0A3134B030A8A0E220758C074484FC7019C5AAC212246F990C41A5B5E468888A5280A23057CA0B23947F332213A86910912C090421D4A008CC219C9C571AB09A9C59C248FE71A2C928D83E6C4DD5929D4D1B8F0CA98F4608F89EA1D59F063D827123026C7EC093A6360590BF54BA041C2C21473DD89314321B334680CE65B5737857D5FB557F1967075C9889266298F332A19C5888A3497F0580B8BE1AB4F7A300F6248B4D99431E4B9CF163E9B969FD7B664AC8248789C2866D05D01C579B491BC50C8099C30A0E6076800B00CB27929ECC8C9B7C44B32781070188B747C6EC1997017E8435035CAC06B2E74D54EC8B64E2A9B9BD6351604D3875C394C183B4B7D362866C96A78569A9E88C2D8767FE0CC0C55C506E5A50B1FB9CC18910D9F22648681CA8C66529EB3665E08BDDD725146C343BD7B9E51D37F57B602E012A1096793931097228A1536715923CA93D8C41816E04FA27A16F6EB50BDEC8A26D99FCC1901938B7475731DAF85C2058832315B93E9DA81B415B707F95EDC44BAD6AC3016E4A16E787E3FC59DF904AC385ACF28EBA6EE61188883CC72E9B298F02D2D49CEE59B6DED348038C7055202B47CBC0B40774BA78CAE78079B9E8A9392CBB57CE4400E9214C3784BCCF94151D510B182403D990C2F8C984B6AAA3AFC21F9F6711EF91EEB008482845FDF60BB5917720EC9C774943E04A7A5FAF161ED557701BC26717ACB2CC059E1308E2AA76D04919B30A70CC698402FA58D927C8A02773815A144128C5BD183A38C3182BCF19DB7A3158B9393C767926F5737B6B60EDDC01FE8930ADC2C4414146A9968311C0B367647911F4AAA4443AD0648C634828C62C0BA01C161162B5EEAA78CAA9A1425F55950EAAF71841250008FE1CA3B8F8421FB4438E65AAC914AAADCB45FE303CD9165CF867A7E9304CABF0B3E1DA63A5FCB56F03753D7074525425131D555B5E583B303B6616AB6EFB68CD5994E9296608700BD3239B03AA6A662FC354E2A49314B63D9E1801EA5127FE653E459B90E94C039D812DC031D536C400A2A70B860A9AED7BCC286182933C62F7C1E73B615F1525F6A165DFD4461AE0B856B298B96CB6756AA2255949255E6C95C12A969A698D37B6FC8B7B16BF1AAA1734DCFE1160D319B25236F591C7CFC8A08FBA48B42586F3371B0AB061C92F9C0E3E350DE5941C9F380D876480C2623F526111D676AB33ACA5D66185655A94E13418576B632DB8A0D3830738C44AF9C979514254ED8C82E34AE5DD6458E2039690B8492C353E2F0937887088B4786BAE016104648C0544482C562E0D2AADE390DC03765C7C1353634B83AB66AC7E1306378B5032B3148BB799E8B4907188EFA993FE72C73E3162F2DA43F0EC7C2F1C162EFFB5659A947A3AC6203B1C825125023926115605CA1909D912A0108C0115FD75D967BACF32B656EA64BB1808D1C1B43E8D7BE02EB6432D89B59F9A3FD109AEA36ACED2A137214BDD8686D977A68A6E4B6ED6C916A8594CFA3700AF608CB6A91AF150077D5A40EA4471AC19A7177B1E6A6BBD8A357F416BA8935AE73829A5B035B79AE8D108ED5D05A089242ECDBE94664DA47F187D3D493AC23E7", - "dk": "91200CC986B3575202DB535E04BC2E37A499076781ECFC2E5CB0259BE2A5618C1CED22128D194B0BF4397D6AB0E2F30F6AB23260BCCA10507CA7015C80D9409B4BC06DABC661D3A653208A505136926A554CE331E4B692105044DB060576C1C36A726C0E1379C463CFF2183166052813A6BC4B93365F2798825387209C8C53A1C2DE453887B20061E71245CA6C1C27809242C14215924FDB901EA035AAC45EB29B518D0477F5D8CCB7D39E16239EB0A5254F6380F328C1ACFBCDE08310804195B944AE8D98BC1D75325E062973D84C5AD958C14076720C4876A5B903E80DDFC7BD66E1B55356B896263FC3451E2A865212CA3B9C510FF0CA4865B6C1F2791C1A77A67336A429C9569AFABF535888D1075ED2B1A31CA78B9E3353020800FC18C1D47CA6C326529A375FDA667C06134986B891DCBA7F6AAC901768A156270A6E46490B33378EE75648BC4DCB1451A2212931F2096CD8500F23817975C25FDC164F41CB5D8A3613EC993A57711585BDE822B519683F8C9CB95ED701D6905F20A46E29C0C90C448B42742FD1BA05BFF590D2D97317C2473688A4B6AC63CC1CA28AD71FB7C5252C42534D27AF11D5947E1AB196CB2AFBCB41E0A8C50AE274D8CA1971B605520503E9C17AB6F41232FA9130BC951DC031A66A02A663756ADC7C15BC513ABC1592CCBCA9F5CD3AB29B2305B32D98C877217A1B92321930B34A096641070428B65FF4108A36C998E895375640B57788A72302931DB058ECB52F4D7A0623D74AC223C4ED6024515A364D280EE056760CB451280772AA0CADD1E0333AEAAB5357479D01696DE52AE2C8B71705706BF15C05064CA434280D4C8CAC411B0A390C6D6BBDF5E684BE3B850D3A83BC31C5C823604E533242E80DB57B2598CCAB30E53282F140C9897C85EA7BC9FC378761BDAB629E46336B714C0189E214EDB254512AAC558541D30CADEBB9665A1914A9D001F43504A0E0A566B311E746379F56558A760618C753A57B6B1A4251090795466A178A39904268A10F2451484C6B11C037953817AB156EF7383878B1BC38790CABEB4991EB2768A83F580945D46C49A8C0CA26BB99F72C40B73439253180DEE2A425C54C23FC6718A40611455BF4652F8CD91067B42131EC03CC5C0B59EBC5FF30B097D764306CB692ABB95D192CE44B1C0E981162F73997148DF270630AB6B37129813599239AFB46CDAA40CE472310EA67C2E0BA18765D34EC9FBFB82CBDB4BB6797B849BC778C9710BCD0BB2C611990B3232AAA4D1B898371738AAB9375813913DBD178A4CA2EEE4A8D09E72EDE6189272B1EF503AC8302A63396798FE5731C223E53E90EBA3805D1F8A65DF168C71408682C2790A167557A15E697A72CD2CB613B7371838EC85BBFB510B3344C3B61664BAA8B90079C30181ACBA83AB049808CE6421DB67393865C43D43C3825281492AA68413BA560B123E2140DC114060F93101CC08C63D848B172010C56C2F5377AB4B4A31CBCB265FA607F504147C0009EF812788A7EC53514460A8C8225A664348A5347291B73B423C8385CDCCD34A277913841F2C2434F2A34A2EB02B7270274E4AFB3F19933402E1A340D8A8B6F50EC4930086D462A85C9AA80950711C092BA7135A45CE30B37FBB21C574C6A1263D0554AADF36D9A6567716B914F41617047973D54C3F573805CD38170F004BD014989D33D939132A39B44D49345B857792B241B0A870396D95CCA133E7A7001579930DF70C201A71951E11257356129255A044678BDFCA5A7FC32001167155659F41B4022A9B15B37A197FC7C567CA63D74B4E9D286100861658139A98C868EBC9207237A5E4BC26EA867DA305A3C3A36083C9F79523B45F53B8FD40591304836B8520B227905413FBCAB24B22A7D1334452045AF354A4690455144390A381C1172C18D865C86B159AC944906F298A00571B61420BAA7E67787AC2256EC7217FB0C00C48960165CA6E4416059A4CAC2CA9535C8DD2265387B1E18950A7C917EC73AAD76A753E0D4A285B19089E264B6A53A35AC523FA955A4B48FCA59344503B12675B6C6C99593EC996DD9C456D842054A52DDE1106E89A30B5732FBF5C88BA98833A26FB47350D0509B17E8BA76878C2FB485B7CB5E7B4C73F6929FE09B54A09454A7145A4A812C26240EBF4126B3C014D82BC4BFA186D2E2A4FCFB57E2205FE91195E1ACAA18A3699D1BA700770482C18160082946D85BE262136B7B1F5BBC00D4D20A1351C66966CE3C1A06EBF35A43036A5498424C73BA01C250C61399CE951AF176C96F317B0A23395164075A23A6D6A55916F5032310B5E28B1B970C3AB75B4058C86DD9A73ACE89B9F5A272A86B433AEB9AD755B166105AE0095645910E0AD6045C075B82596140213DCD231C03D0786C186C95342C01265B03A2A113374307B49062727C82F2CBA44862C7691703374AD76B772DA400C283A1AAE348EDA9582B9B42196216A8218305309C367648F58785B74A9E4DC068318BCE4CA87000DC86ECC52F2D465762A58BCCBA755E7A881AE5704C643278E784E646C48AFC3F240A728C4A6D2B6523EA3499C9344294293497D3A4A3E2373BD2CB48B0575DA052253693D1DB696DA0057B2243525AAB17770D61D09D0F3554D10AA7A56B6CB9A81F59EC73A1FB9A08D7BB08D90F70117A2988409B870AA2F82447E14DE7B3C16503CE645BA54EE5C6E71909642A3F76620AE0D479A6440AA5E457A946A884D0C741A2C7F27C9EA9E716EE1C01154120E777930E991C63E0A3134B030A8A0E220758C074484FC7019C5AAC212246F990C41A5B5E468888A5280A23057CA0B23947F332213A86910912C090421D4A008CC219C9C571AB09A9C59C248FE71A2C928D83E6C4DD5929D4D1B8F0CA98F4608F89EA1D59F063D827123026C7EC093A6360590BF54BA041C2C21473DD89314321B334680CE65B5737857D5FB557F1967075C9889266298F332A19C5888A3497F0580B8BE1AB4F7A300F6248B4D99431E4B9CF163E9B969FD7B664AC8248789C2866D05D01C579B491BC50C8099C30A0E6076800B00CB27929ECC8C9B7C44B32781070188B747C6EC1997017E8435035CAC06B2E74D54EC8B64E2A9B9BD6351604D3875C394C183B4B7D362866C96A78569A9E88C2D8767FE0CC0C55C506E5A50B1FB9CC18910D9F22648681CA8C66529EB3665E08BDDD725146C343BD7B9E51D37F57B602E012A1096793931097228A1536715923CA93D8C41816E04FA27A16F6EB50BDEC8A26D99FCC1901938B7475731DAF85C2058832315B93E9DA81B415B707F95EDC44BAD6AC3016E4A16E787E3FC59DF904AC385ACF28EBA6EE61188883CC72E9B298F02D2D49CEE59B6DED348038C7055202B47CBC0B40774BA78CAE78079B9E8A9392CBB57CE4400E9214C3784BCCF94151D510B182403D990C2F8C984B6AAA3AFC21F9F6711EF91EEB008482845FDF60BB5917720EC9C774943E04A7A5FAF161ED557701BC26717ACB2CC059E1308E2AA76D04919B30A70CC698402FA58D927C8A02773815A144128C5BD183A38C3182BCF19DB7A3158B9393C767926F5737B6B60EDDC01FE8930ADC2C4414146A9968311C0B367647911F4AAA4443AD0648C634828C62C0BA01C161162B5EEAA78CAA9A1425F55950EAAF71841250008FE1CA3B8F8421FB4438E65AAC914AAADCB45FE303CD9165CF867A7E9304CABF0B3E1DA63A5FCB56F03753D7074525425131D555B5E583B303B6616AB6EFB68CD5994E9296608700BD3239B03AA6A662FC354E2A49314B63D9E1801EA5127FE653E459B90E94C039D812DC031D536C400A2A70B860A9AED7BCC286182933C62F7C1E73B615F1525F6A165DFD4461AE0B856B298B96CB6756AA2255949255E6C95C12A969A698D37B6FC8B7B16BF1AAA1734DCFE1160D319B25236F591C7CFC8A08FBA48B42586F3371B0AB061C92F9C0E3E350DE5941C9F380D876480C2623F526111D676AB33ACA5D66185655A94E13418576B632DB8A0D3830738C44AF9C979514254ED8C82E34AE5DD6458E2039690B8492C353E2F0937887088B4786BAE016104648C0544482C562E0D2AADE390DC03765C7C1353634B83AB66AC7E1306378B5032B3148BB799E8B4907188EFA993FE72C73E3162F2DA43F0EC7C2F1C162EFFB5659A947A3AC6203B1C825125023926115605CA1909D912A0108C0115FD75D967BACF32B656EA64BB1808D1C1B43E8D7BE02EB6432D89B59F9A3FD109AEA36ACED2A137214BDD8686D977A68A6E4B6ED6C916A8594CFA3700AF608CB6A91AF150077D5A40EA4471AC19A7177B1E6A6BBD8A357F416BA8935AE73829A5B035B79AE8D108ED5D05A089242ECDBE94664DA47F187D3D493AC23E7DE32CCA3941492845F6502143FBF02028F22B12F1ABADF29BD12458E5B698A875B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D" - }, - { - "tcId": 56, - "deferred": false, - "z": "384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9", - "d": "2C34B1476753095D0C8A48A00136F358A98D1416E5069CBA4540C6E26FA3634D", - "ek": "6A04C9598C985A554021C437246C8E1DB67F69B6092F7A18BA3309245480FEA533B478726E4C761568A00DECB368F104B1E908F1E9BE85022D6998581428881C6C1B06A89141831DCEC1A139303FBFD04174F06E81D09DA38251ABC33C32422917EA165FE821793BB13D553EADD9AE86C750A7C307AC6467F117B778ACA8E1CB8360152388EC20742011FA66C786675AA4813C8CD58EA2FC9ADBC4AECE94C1193B1799306D6DE532EB32928BD5957484B6E38272172B902AFCC4207958A433058280713FF055A9FB0FE6A3C79564A75C32AF13B4338CE1ADCC5825E9475C66201B8E6393D493001C29A44BB20326DB06983BCBA96805EF0573DAB1A506C33150A974EC96462473CA7AC7066F374A131854EF01A99A30770B0B508CDCB2B5D2B5F2208005378AD0935243EA61C8D876A1602CC047871425CF33BC22E07A94C71737BE251E75F85594F523B4CB241E97AC0306B8663075B8B18ECE09332991C774E225D7722DC1E87052E19293F8B802E7366A3C76D388351B63A11AF5703B4862699124E574B0117788DD89C8D7D2BC34806DCD183F28784E54B2725EDC9A797B1A9F110C0C91154BC927B06C77335A07E372B5C10C4DC8C5BD80EC79BB68AEAF8BAC1C583D4055C5EC4592462C60165C636F2A5FC3F9A0035B0094755AEEC7B076A7C84F8C3DA994C9C2C10C1E17CE56943933D733944753DF2546342890BAF305BA3B08628727BBF492F7123CA6DB9E067A02A7FC20B9138E5011A9E08116E77382C9AA594BE18470D0B9B3CA82FC652398A3B7466065732030F8622AFB4C29A88B1F8539976902AE18C9C0EF10780D8B405EBB37D873C6FE4534B8AC444D8A7817F6CE0C36B8C53AC03328B8D4B30DDA4111A7749B6476516B56147B3B9841E29D20520EAFC9247D9C6171A1165C971941A06CE6F58EC0A5B4FCF21CA78857BD6B2F0706BE3F568E380C24E537C31D74B0202014A24321AEE877B7E457FB669903A30D39AC9188239BA29157ACC82AE671C75887C0F1C9AC11DA5974E438EFA438467755EDB0C949536274DA3989972356A845811273E5308DDD4A3774047E7F347330133322521586635622937867DC549E058AC1D65BCAA8C6DED93C52FC329DD038DD244428EC602D0B11D5707AEA029328B61BFDE51B4EE3BA4CA8561031BD939ACBC70276A309D028A7674C736668D1735EF83B555689DD5790852916F450812F0A809C183A4BD2AA79B74FFEB232F3D67EBD0B3F97037ED8EA8A7C6CCAA4D300F3E01F2B8661AAC39FAFA78197A2482ED4745C56C757A692B1900D7DF921D6C35580F9882CFA294DFA0DBFC29BA21C9F648515EB2A81D2BB0F75941C1C1C6541D949A5454D96FB486C79B11BD9B56F45651B3567C75A261CB5C0B077352486C37715CA8D4CB727B167567BC58A530543047C1FA2459F87C837623C5B2939FC53AABCD5B1B8271A67C95B3E33C2D9922836A25BD1E61692BB36FF87229779AB75A883B26CB6B27553FB5782DC3C62D70C4AEFE86A3A36934770834142398187983D766BDE4916EB76852D74010E221460C4C5FEC132AA77B618AA0F81EC6A8E83BE7BE37239F1CEDD206EB8961F0D2AA3FFCB272A0785A36537240274C9993C4904A731995A3019CF6133C714185A449376565A65B5C2B1DEC8896C1BC46A1575CDF80958F2B96329791C208F51B4A8F41A8356000E0F1C51EC584ACE4434BF0035B5127478C11D659B842CAC49AE873F8192659A5735F87B7517B118748A74B8020D2823A25952CA3F43C7D3614741E054DC0B5E5AC11C8FE15E7F908A7B64B3016A39218134FB3092E7482E7399310709BE369CA383E95AD08718CFBA21F9DBCC8E0600DAD2C39B368A24E79DB0DB02395949CAE835AEE683C4A6AA6024B3109C18DC2BBAD65BBDAA52ABA6D9487EE3194579494B2441177019C0BCB78F8A2FCF7BA875548C1C3603AE3A874D2454C11074047310D136AB4EAA348F05B4662989CC6896DAAA24A94154CDBB30FB5023A37779B1E29F71A841830274B733ACAEA69D84FBAD4F138861FBC35F0545489AC8342A4F6F8C584A8442447062D35BAF44B3C92A38CE11A173FD5A3D8D6B24BB390ACE212E41042E75D50E318C6FB037AFCCB2B069E2BA66AC1233D53031279ABA1683AE42A745D0002805374165EAB94A17EF6881F0BA9392CEAC27250E82622E6F40D3810AE40CFF1F8496", - "dk": "BC00ADC7652EA7DCA970F2C234A87D9C3340EF2994A79A71B7200F9168CF76D9A301B85A01E6AE69D8959533A53F4890378067A6068C2C8201D373BA49C69FE6EB1716FB6BFAA4ABCC071B191515ECB758EE859D40A12429DA703052947F4097E7E40180477C01B62944CC2CB7E63952921E1EBBC800E1A7385B01E528548A31B0BBD0A5B0641E9160C36236CB58A36555D88AF118C35EDA2276B38D5A8C0C091795C1254D69AB5D4DD309E376BDD7E4A3E1333B3FFA378FDA8E62525201F9458F53443A255ED79B71102A2F3EC347166CAB38361B3E668BEE7588AEEACB5436B1F8E360F1D73999E290BC25C036ABAD878890C54BC8DBB863F8E23E5323ABDB004141C9C3C0963B7FFB7EDBCB545114A61A6B58F8487A07F388F4F5C00E9CABD425B7BEAA2B9947A0482A21572B48E65C8FCDBA214C0204E246CC3EAA069DD42DAF7285ABB55DAB8B2A016805A1C17D46C131ABD4483BAC6B5CB8C36A810DDD100E4A66A58209CA60877E40E2BF58E37BE97C8122D7097ED173FB272AADEA18EF91120405435365BF670C17B99068226597DDD7C4A6A16F844616C885666AB482B7858FA31405B86789CDA046D6561E997689C0D0A461E776C7313E811AC02D1BA8A95038B12430748644D0B933C9E35F685229D97BC810B3203C874673D18E8E0131FBD368C47466A9882F4A41473166C2E240A82D36B983273208EC4008231773D57FC9D4330703565CA8759E7CA9E64130BC5493C9F52C93AB4A7B3754B0F55EE9779CD08B2BFAD71899B75CD274ACA7C2BA9575AE56DCADFF13A6E6C5266BB7AD0D8BB820660023E9BE0FF759202CCEDFD7C3F2048D6B345CAA1C82D479A4D4E2C48A1818DA022435BC3D64B38C811B0BCFC147FAA505AF13740B78945F973BFD2A21A6A040B65214F934154E722D7F195877C5476EE615344462C2A95744956DCB5B2657F27DC2C6AC14E92E8404082D8A0EB6E488F2E56FD0292FDE931057D534051700AD0CA85ACBB5C6C02077DA856931899BE82CFA0A794AD1182CD3AB5E5188C357C3A2D9BD130A62223293DD249E477271C9E14AC48017D013A1435A5976C4165E8932CA032493B33814F90830A5AD75E32F747B94B4C52BF5EB30F73C02BCEC5903BA01F99ACF8B9ABB671B8D219C029BA1A2A6E847E86091C08C00B3914DF8D075C3913C805104A3B4BBC798B9F1D20AFB8118B7F26C32633B39FC792B3358606054BE3693A6E7B9C6B6B3A848A2D0B2ACD1C406706CB590B4B79B82BB88415CFF45376B8102B644193FA1890040127B58BB351862F3227AF18A50A9A983387A8646C99860BA2373337FDDF25CF8916E00252AD07516D1BC5629245EB341B1ED4B63F93044B131C01E301E8FBA5DE8AABA76F70F7D2A3ED4F78AD5210B47D8756E334D32CAAD88C22DBC537FB766447B09A05F1685C24A80F8C3A3202790B277A6CDC836767793D81955BC90A3DB3B71BD8C2FF01A12A59541A666202CA98689528DF9179A26156A6A414BB8DB350393B6B0F35DC163CBA4C94242A33C9778BB35563A8D213A9914225A0C6876B75035201DD14048DE28AF97D77260476DC399B37DBB48F3C943F3C990ABA7068D4299F7D289C6D66D4243570AF38D8FE95384B27E6B0C01258262CD0465F5FB5F424CBC9C39CF5948804F7034C632CB8A7B4ABC3095B174951C42364B05396E140524B989A889CDCFCA4F222830A98B041338A0273478E3661A5D44214A52A54EC65E933011EB7148EAB94E58EC1C9CB9A0E61C788880B15413B8365A929342B667005D6A35BEC272955F5CBB633798094A0DD84A09B6A04B16BA9D1C005D6B1708CD4300D26B506748CB7B4CCFB59818FFFCAC2A141ABCC1AB85BBA36C69608CCA475BDB61A56BA2FD6B2F75F502FCBA8AE05B11B73A381A810681EB0B1F446007267F7C12526BC3B430CB4BBED0694C290B0EB238056B5C64C1AA072C97F7173647BCBEB75965BD71C0747503929ACA0FD98EFE45C744A4B5BCC748616A8B24C5BDA4F0B9FCD42767420971A00F32415976B5A4DE31C03B10858CF1995B7B8526FC352A0C99A57095EEE0B8E7E40364587623B00B1799C807289DCFAB746B06C3E2912A6D3778FFFA8C1B43A39A433708817E7058C03698268E9275BCF21FB73052874307FE56CC8A384E6A04C9598C985A554021C437246C8E1DB67F69B6092F7A18BA3309245480FEA533B478726E4C761568A00DECB368F104B1E908F1E9BE85022D6998581428881C6C1B06A89141831DCEC1A139303FBFD04174F06E81D09DA38251ABC33C32422917EA165FE821793BB13D553EADD9AE86C750A7C307AC6467F117B778ACA8E1CB8360152388EC20742011FA66C786675AA4813C8CD58EA2FC9ADBC4AECE94C1193B1799306D6DE532EB32928BD5957484B6E38272172B902AFCC4207958A433058280713FF055A9FB0FE6A3C79564A75C32AF13B4338CE1ADCC5825E9475C66201B8E6393D493001C29A44BB20326DB06983BCBA96805EF0573DAB1A506C33150A974EC96462473CA7AC7066F374A131854EF01A99A30770B0B508CDCB2B5D2B5F2208005378AD0935243EA61C8D876A1602CC047871425CF33BC22E07A94C71737BE251E75F85594F523B4CB241E97AC0306B8663075B8B18ECE09332991C774E225D7722DC1E87052E19293F8B802E7366A3C76D388351B63A11AF5703B4862699124E574B0117788DD89C8D7D2BC34806DCD183F28784E54B2725EDC9A797B1A9F110C0C91154BC927B06C77335A07E372B5C10C4DC8C5BD80EC79BB68AEAF8BAC1C583D4055C5EC4592462C60165C636F2A5FC3F9A0035B0094755AEEC7B076A7C84F8C3DA994C9C2C10C1E17CE56943933D733944753DF2546342890BAF305BA3B08628727BBF492F7123CA6DB9E067A02A7FC20B9138E5011A9E08116E77382C9AA594BE18470D0B9B3CA82FC652398A3B7466065732030F8622AFB4C29A88B1F8539976902AE18C9C0EF10780D8B405EBB37D873C6FE4534B8AC444D8A7817F6CE0C36B8C53AC03328B8D4B30DDA4111A7749B6476516B56147B3B9841E29D20520EAFC9247D9C6171A1165C971941A06CE6F58EC0A5B4FCF21CA78857BD6B2F0706BE3F568E380C24E537C31D74B0202014A24321AEE877B7E457FB669903A30D39AC9188239BA29157ACC82AE671C75887C0F1C9AC11DA5974E438EFA438467755EDB0C949536274DA3989972356A845811273E5308DDD4A3774047E7F347330133322521586635622937867DC549E058AC1D65BCAA8C6DED93C52FC329DD038DD244428EC602D0B11D5707AEA029328B61BFDE51B4EE3BA4CA8561031BD939ACBC70276A309D028A7674C736668D1735EF83B555689DD5790852916F450812F0A809C183A4BD2AA79B74FFEB232F3D67EBD0B3F97037ED8EA8A7C6CCAA4D300F3E01F2B8661AAC39FAFA78197A2482ED4745C56C757A692B1900D7DF921D6C35580F9882CFA294DFA0DBFC29BA21C9F648515EB2A81D2BB0F75941C1C1C6541D949A5454D96FB486C79B11BD9B56F45651B3567C75A261CB5C0B077352486C37715CA8D4CB727B167567BC58A530543047C1FA2459F87C837623C5B2939FC53AABCD5B1B8271A67C95B3E33C2D9922836A25BD1E61692BB36FF87229779AB75A883B26CB6B27553FB5782DC3C62D70C4AEFE86A3A36934770834142398187983D766BDE4916EB76852D74010E221460C4C5FEC132AA77B618AA0F81EC6A8E83BE7BE37239F1CEDD206EB8961F0D2AA3FFCB272A0785A36537240274C9993C4904A731995A3019CF6133C714185A449376565A65B5C2B1DEC8896C1BC46A1575CDF80958F2B96329791C208F51B4A8F41A8356000E0F1C51EC584ACE4434BF0035B5127478C11D659B842CAC49AE873F8192659A5735F87B7517B118748A74B8020D2823A25952CA3F43C7D3614741E054DC0B5E5AC11C8FE15E7F908A7B64B3016A39218134FB3092E7482E7399310709BE369CA383E95AD08718CFBA21F9DBCC8E0600DAD2C39B368A24E79DB0DB02395949CAE835AEE683C4A6AA6024B3109C18DC2BBAD65BBDAA52ABA6D9487EE3194579494B2441177019C0BCB78F8A2FCF7BA875548C1C3603AE3A874D2454C11074047310D136AB4EAA348F05B4662989CC6896DAAA24A94154CDBB30FB5023A37779B1E29F71A841830274B733ACAEA69D84FBAD4F138861FBC35F0545489AC8342A4F6F8C584A8442447062D35BAF44B3C92A38CE11A173FD5A3D8D6B24BB390ACE212E41042E75D50E318C6FB037AFCCB2B069E2BA66AC1233D53031279ABA1683AE42A745D0002805374165EAB94A17EF6881F0BA9392CEAC27250E82622E6F40D3810AE40CFF1F84963DA07CBAFFA3C26C86115A24F33F1FAF547933AD64AFA40EF5F0DB03D53B340E384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9" - }, - { - "tcId": 57, - "deferred": false, - "z": "63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D", - "d": "F742E7B69E27A57A43E1034CEB5834CAD57C380ABE259F432F96FAAF27F981A9", - "ek": "0C25AFFB80C5BC12C3CA5357097716E75B025C298F040C5AB8C92F93A08A91953277A7CAAA1776440C9E3A5C819D7B9BD58AC0A53C83D9635D3A882C36CC3E48959D01E67A4E363273F05504274BC144C5D4B4774FC98638895EF894A78113362EC428E0314FD5119C40811D22313D42362176E001616901952C1100C59E33428EDF13C68086571E8A65D042556A6A3B18582F79B443EE22B53631C02FC03FA6CA4BF4BB0B8B97410443C0A3CC958AD42BEDB3118254C19752AA70076FF8F312E50433884A72F287266BB83A417134CED7C66EEC3A9C90043044B61C795CA69B8EFEEC56D808610EF5B6FF764A59D308E60B64B577CA70487D340BA3C8027C45766D270969B284B54DB8A29831939174A2FF274F7EC131858355C23624CBE7B6967288C0B660ABAB4C11C2106F98909AA7AAF50BB1CA0221E1CC00B31696DD05C3E46C7CF5A22B28E404B171A8BAB14146B740B946148591C0505CBDA8E2456809D019E6183D4B10E5F9C6122A7E17D579C5AC4FFC62CDC9AA88102CC386E50770E36A257BCCAB1826BC07D0CC58AF9C49291DB9A63753CE3F9C2AE190834AA77662BB5072F89FA29A2388E532361537BC28310A6A4133B5A0A4795304117839832C8AB7A397141B8A3C47A52689BCC26E3851BE6524CF2FACCD8037B69279021539BD084B31FFF084ED7AC403EB8BD3EB5F409B8778783697B5512C0B91B426714C426882F10DD165C91EFC240C2B129500595D08A5AF198FD8C6A1A9D497654A80EAD40E8B3347B7C51F2E220C1B950788139DD07B6F00B1789EB0A7AEA60844339F04DA7811824F9544320064725B809862447397786381615D3EF4AF575A4CB8FCCE137A4C85241A72BBC424343A3C916C6E51BA58768855C29EB17AB4C8C8C3F3A0174F5979AC02795B60716FE96BFCE517821C254F2A8DD8D77FE778B82E3A53C8592048104FC959B23FE36450913BB1265BF91978FBDACFB3601DDB978CDD77314C8102DAA75D1EB8266137CBC2956714294659809E029067D7D6CB6C93148FB102C34450118835C85509E3F980446767FEA734AAF7C8ADB7CB11435E7600842FF96ED8C75FEBD643BC1A34D1666D8B6B9EDB2B8C72AC5614C603AC200D00461EBBA069EC751CB3C36A60616C73CBB8B2C17798358CC4C588BA3122FAD04D97D51687FA3B19D465F6E9AF95C68AE5225FE04A14BDD61B54A502F820C9DB0256B11AA524F463C11A21F1610DBD800A3D690E0139000B026B7C1628FCA3365A358FF8AA01429CAB2106055144CF0597C2DAA1A623DB1A85730AA0046127287BC407073E9C7C74042DDAAB008CEA58B8DC7765C85844B3395561A4772B5D4D551ADF12687B18C63260518576440EC7BD699843F5651F5E04B25085448CD138257C2E2612733ADBA6FE7357F1C366FBB1457C2458C4F848A24A1BAD74B9A2AB1A603408C540C091C6A100850B4A327211A7CE336426E7B250D50012D7262EDA4218C3B1A55D50337C63A9790406A846CEC038B15D157DDD030FDB293B187A63BB38208F075599803E29149B1F097B1867BF65EC69ADB00ACEB21345E1ADE7E5A36E20B69062C5CCA550C95331F069CFEC59429531B4380A079669C777764DCA8ACD8087AC091CC2B6075CB9436A3B4C22AFACBC0CFB95D361C2232390515A21C37AAAA839005AB97D6962BFDC8959A51ABDD427A15BE830319CCEADF3BB23B59B63452F6EE2956D11C47E721FFAD1724CFA7C1ACAC3455C6E0A75834A23AAB786079947ACA32113A2223B2446790738B464A94683D47357E8847063539080987BC742BD149756541F94D5539E886C13FC1FB291BD1FD8445DC47347072D063A71F9224A85366D3364A1B97ACA267C717BECBDCBA78FAE3BB589BC8794FA2D20A8CD8D7B58124843B7E46FF0F629EF92105DC43DF6645ED57BBDA265874B63A193D351BBD0A5A48CB819979C2A57A486A109957487B51AB7D8283076585E6F06AF66A7B7776BB219911391B67380215FA2216FC061C441B87AF6AA077E77777AB3C7101911B3DC5C1D59952879C1DE1B8741A24C4CD28239132E89024C357C76BCA7CD4696423EB6C578C53C32098E8CCC41321C93CDF79A0DF21B6F69C3DE80C9EBD838B7FB0759165DFD7A6200B88588E992CC173E0A6B0B87554CD2C3C4D42B6B575C9180F1A418D8E400CFF37C23D4C3E3EC2627627F6BCDD1E1F45D7E", - "dk": "BE49618EF5BCFD880DC312BFFDC519EFB4269D0B2391B89C01D6A6B05063346A4BBAFACFC8C091B64CC1AAA08D6F40BCB4043BAD7416858BB4121567BC380C042C2D90244943028DFACABBC6219060721832241591BC030410064E45149CF96C36A6A1FAEC889382340A5BBFC9193DBAF8A43CBA44BE25143AE10A33C6AF8541AC2503835E0743BD74CB899373BE77987492A071E57027C688A2123F56A5B3D268C1EB70A21F6A98BD239F9EE5927F21254FA5BF11F41578AA84770C78B9642E2F3C94EAB1CA5D10651F90A1E49033074B78B6F2C9D0D784C7A931E2EB8336F8802EAC29DE8737EF897FD0A31A04F76B30B5C6B68B7C3A2C3CF0C5B4B313A83F70A59A84901C8B819F8502F624368C493231C19340D67EDDE503ED9805A05A3E23102E6256117D9BA283619F0CB3373E743B2771A7D1B020949600098A40BBBBC364F6AE171BC6FBFBBFACF25B0BD37102D336EE1438022AAA2DEC0ABDA6689A4595A18161C7A9728A0C9B4F74A65D8A432A100B1F46263BF525024876B334CD8D9A1BAC2599F1F0AAADF04E7C83C7EFA4663CE59873533A0CB84AB8EA28BC9B808CE71832D45E4ACA223D7CAD92699B2DF37E080B6F3B6861C95A210362C5FB849EFAB8A845C25C375078247C397143C839F45569786E3EAB14A05679098B25785ACBA2D49C4FC47796271949795925A80EC53A8F7DF6A2A6488EB4E991CD7976584A2FE301CDAB93A57070148F8AAA81141BD932951EEA748D6066FE3B9D60143CAA0339CB8AC2530A0AD0EB444ACBBDA16B0E6A0A6E54885FAB6170A7723F4E3B23D18615B6AC580B2401E485C3543519BE6A5590C7469FF47A3DB91338A5AF6FD28A91720402F70DB8A491946192AB573A6E668CDC7B702231986C114EE18902C78A3D92D1CE616511A66999CF5C0071E615E8A7857D561B0B56C3C35560DDA90A18601B8650AE2520784D1257B3A7339C09B5CE95138E57B69FE90C1F97C03280C0806BC366E75E0D3CA2D355A2E2BA661EF0B96F556C50656724567745C1B650634A8DFA4699222010C59257C38C7D202328767663127DF2F294B00390F674C021B1934F65514AB125132B23A0A427919946D1A96A84491C353405F505937FFB8FC0813700E37C8151386E248C0BDABF1961B2859BCCD9B33960E424A87042D45A6AF180B2CF77B25B7912001C958EF55306927E8DE71488C0BB2C7C8B71767403B6185B41C22DE1BCA99AA86297A2A1E17015F553B967720B159160843DE88B3D033B4D5D563326547A404B352466C9A82415B08A54456B37037971B77A937A540A2DE05B91EA5E540996C8D15452467D0F81568DB2482019B783309F77867175A4CED0A0660FF2AFC1F09B09A03A7BDC1621A613AA4C2571B23FD7C1CECD5B75559C37CDB598AC108255479667E117F51B0E30866F20B087D9088765E7613F3584CCDA8EA7A13CF8E5583EA353661AB7A42A264F9AC6EC529C2CB7230CF45D2AC1B95D729F00B8792983AFECD44B3E88A197D34E2447490729BDAE7547B7119A970B0C3153B379148C4BB61472662669E2510C76549102187D891E56C20A3328C03AFB32760BBF09F604AB0B5C5DCABC83E80CB17A7BFE4B147F6670128A80E93B359191424C80C47CE001D926C6830962083B8BF1C03FF9F1A1034139D974229A581035E73F7CC10D56B281FE96755F214738B70AD6351F8F30CE5DC5555F6B69B806C5D2574553E7C94362A623F2C4B31502FF8094F6E08394C880EDA1299B2C03F1C696D80C3640584C13789E32192A27B38896884F6DF0BDE386A1A327C5C52314A4BACA2D7928AC761AD898CB4298905AA76ABE3C5B7BE75704317D44A9C98FE59C812C88A6E334C0163EDE8AB622F351D9F3926375291B5510C6E3AF2641A65FBA17C7778B9B2A6C2E5BBA6BA225EA40CF4ABA7639D488ADC0A970F6581213352A409065CA92AA8694916C57796B42C96C830FA84C6C70C2640C495F10A48D1A210BDB8BD0C20EF2074825651C5D9B3EC606351B34796FC578307CCCE54A2EBD648FF051CA6FC9AB0636CB6ACC49109343F1465052B57404D46EFDF856CF330E539402DF699E0576953C497A9D662E768ACDB8A9822E3A9271C401A364B1D060924B84939F7110B45012EA36121A4A91CD860258D559ADC0530C25AFFB80C5BC12C3CA5357097716E75B025C298F040C5AB8C92F93A08A91953277A7CAAA1776440C9E3A5C819D7B9BD58AC0A53C83D9635D3A882C36CC3E48959D01E67A4E363273F05504274BC144C5D4B4774FC98638895EF894A78113362EC428E0314FD5119C40811D22313D42362176E001616901952C1100C59E33428EDF13C68086571E8A65D042556A6A3B18582F79B443EE22B53631C02FC03FA6CA4BF4BB0B8B97410443C0A3CC958AD42BEDB3118254C19752AA70076FF8F312E50433884A72F287266BB83A417134CED7C66EEC3A9C90043044B61C795CA69B8EFEEC56D808610EF5B6FF764A59D308E60B64B577CA70487D340BA3C8027C45766D270969B284B54DB8A29831939174A2FF274F7EC131858355C23624CBE7B6967288C0B660ABAB4C11C2106F98909AA7AAF50BB1CA0221E1CC00B31696DD05C3E46C7CF5A22B28E404B171A8BAB14146B740B946148591C0505CBDA8E2456809D019E6183D4B10E5F9C6122A7E17D579C5AC4FFC62CDC9AA88102CC386E50770E36A257BCCAB1826BC07D0CC58AF9C49291DB9A63753CE3F9C2AE190834AA77662BB5072F89FA29A2388E532361537BC28310A6A4133B5A0A4795304117839832C8AB7A397141B8A3C47A52689BCC26E3851BE6524CF2FACCD8037B69279021539BD084B31FFF084ED7AC403EB8BD3EB5F409B8778783697B5512C0B91B426714C426882F10DD165C91EFC240C2B129500595D08A5AF198FD8C6A1A9D497654A80EAD40E8B3347B7C51F2E220C1B950788139DD07B6F00B1789EB0A7AEA60844339F04DA7811824F9544320064725B809862447397786381615D3EF4AF575A4CB8FCCE137A4C85241A72BBC424343A3C916C6E51BA58768855C29EB17AB4C8C8C3F3A0174F5979AC02795B60716FE96BFCE517821C254F2A8DD8D77FE778B82E3A53C8592048104FC959B23FE36450913BB1265BF91978FBDACFB3601DDB978CDD77314C8102DAA75D1EB8266137CBC2956714294659809E029067D7D6CB6C93148FB102C34450118835C85509E3F980446767FEA734AAF7C8ADB7CB11435E7600842FF96ED8C75FEBD643BC1A34D1666D8B6B9EDB2B8C72AC5614C603AC200D00461EBBA069EC751CB3C36A60616C73CBB8B2C17798358CC4C588BA3122FAD04D97D51687FA3B19D465F6E9AF95C68AE5225FE04A14BDD61B54A502F820C9DB0256B11AA524F463C11A21F1610DBD800A3D690E0139000B026B7C1628FCA3365A358FF8AA01429CAB2106055144CF0597C2DAA1A623DB1A85730AA0046127287BC407073E9C7C74042DDAAB008CEA58B8DC7765C85844B3395561A4772B5D4D551ADF12687B18C63260518576440EC7BD699843F5651F5E04B25085448CD138257C2E2612733ADBA6FE7357F1C366FBB1457C2458C4F848A24A1BAD74B9A2AB1A603408C540C091C6A100850B4A327211A7CE336426E7B250D50012D7262EDA4218C3B1A55D50337C63A9790406A846CEC038B15D157DDD030FDB293B187A63BB38208F075599803E29149B1F097B1867BF65EC69ADB00ACEB21345E1ADE7E5A36E20B69062C5CCA550C95331F069CFEC59429531B4380A079669C777764DCA8ACD8087AC091CC2B6075CB9436A3B4C22AFACBC0CFB95D361C2232390515A21C37AAAA839005AB97D6962BFDC8959A51ABDD427A15BE830319CCEADF3BB23B59B63452F6EE2956D11C47E721FFAD1724CFA7C1ACAC3455C6E0A75834A23AAB786079947ACA32113A2223B2446790738B464A94683D47357E8847063539080987BC742BD149756541F94D5539E886C13FC1FB291BD1FD8445DC47347072D063A71F9224A85366D3364A1B97ACA267C717BECBDCBA78FAE3BB589BC8794FA2D20A8CD8D7B58124843B7E46FF0F629EF92105DC43DF6645ED57BBDA265874B63A193D351BBD0A5A48CB819979C2A57A486A109957487B51AB7D8283076585E6F06AF66A7B7776BB219911391B67380215FA2216FC061C441B87AF6AA077E77777AB3C7101911B3DC5C1D59952879C1DE1B8741A24C4CD28239132E89024C357C76BCA7CD4696423EB6C578C53C32098E8CCC41321C93CDF79A0DF21B6F69C3DE80C9EBD838B7FB0759165DFD7A6200B88588E992CC173E0A6B0B87554CD2C3C4D42B6B575C9180F1A418D8E400CFF37C23D4C3E3EC2627627F6BCDD1E1F45D7EB647A2888D86D41D8661A91766BA969E80B9741B21D1EC6E349B52DE8191901B63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D" - }, - { - "tcId": 58, - "deferred": false, - "z": "0A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA", - "d": "3BFC9A057D979EC03A705A9CC406DD8A46C106941AF6777B1D7F79C1508D7B24", - "ek": "5BDC0216639954EB53EF77250D2853878BC0183C0EB5359414CAC928E3ADE2E78213904D7DA453E96969A89259822C205FA46CA6703B6D324890E59F0C377C778ABB5ED2466AC929E8AA2E9D47A8CCE606F52B18A7C35C20F4C2AFC99AC327802B856F13BC1D9E3646BF2A2038C454095C147BD1474663274DD50041C9939EECCE460B7FF1605743D4243553A0752465E93C628324BB2D3783EB1B63AE85AA53311C5574071E56991211426DAC6F6AAC3EEA1569B04654D4193DD689A32432447E1A3F0F5595FB37A35FECAE5C55CA839A3CED94AE6FA436A7D34C2A81587CA84018933FDF39A931B03D81491624651A5F6AC75E08077FAAAE8AB023D6344557D15FFCB91C10B06BDA114C5C133F3782C309C347F2A4434DAA89F202817A227C1E1240FF41A4F3CCACFA497CDDC53AC5B0C55614907865118C2C7AC0D5031CBC106CB17A26B97755271C86E871BCC9590E1C2684F2C24A172B10844CA44346FB969CEBA1A02B9922F3AB68457CBB1F2BC6B5F5CC4EACB9D0072EAC617B31D27301E002E978925966B642B00AC53C912EA85DB59C5506F4724B2C356CEB40BD58AE51843537C537EC97B24475318A5B30AE750691765FEE1014644B1CACC77C9C334805A58DE18121FEAC6BDB61184D2C273AB725C32091CA3441E5140433435AEB0B51B9C57066C43F308A12F782BCA5237D7B12119CDC9AE2E7C65EBC66B3F02A0BE7361E08838114BF0D5250304A36935135C61597A03903EF215C6A223DF8A9515E622932F7A29CFA74807B145A20ADAA7987B0B981B7A62D115927504A090F61B37592A5B4E51B977821E4D92228531D2BA1523BAB3D6C850FB0660646892BE2A006DF51743FA383AC47572F651AB02A272A458B81441C8E774547E1773EE29A6A27BA4E839C8E023A13635922009B1111801872C391641F0E239ACA70CE3FC01E5C3736FEE2AB3F85C4AFE3A0BB2529D6EC047337819084222F0ABE8F859925708AE3E62815083196248720EC28174C01D716AD472A0CB2747EDB932F4A58ACE9E2BADFE468BA2A138EAB864EE00C034C1207F92F73AB084E32BC244951477549B2189568BA28553937E5F1CE6ED1B7F0C1012560296442AA6DA0879705A65D77460A86C0C06422A2E6949BB78B955355EEA2749BA0948ED094E5D9CE7C79B9F4047BF4E2128E41CA5AB1BAB1A87A2565CDC018890D426B37F01713DC923CD372605763C3B51A5AD58109F031BD665192F38EED496EAB15AF89DB622DB73A88BB6104D44C49577483F468658A9C72C1A2046252DF7840325978589A85F07C7572E44445F9A8854825E784706A25A70ED0CEC3F5A372C41C54185294975A70AB759B4250E1F2CB35E860ECC25932F55E6991041AC24D56BCCBDA579E421C905469052A34225AD50B69E191B4A36EB7DB1DC1216BB41524497B279230053E910EAB49859D1A99DB3C56CD70995BF031FB71B0AA40CDF031183E5B3D8D8799CFC3ACDDA54010AA6169A80D62479583111FEB337354F6BDF36A33279B7472800EB604710AB94A0D584942E41B78F2C387993A5EA079F3C74207F7972646CFD4E055FB6B10BC69B369D166143B8A8E7400134999F05C6A26DBBEC3B23D92CB90F77156A0C8A96CE93F73962C17F8104B52AFA2B68B62810F998577E07CB16FAC499F38AD628B57FC1C9CC7A568410478176BBC14C8C7A594A07A3568B503BFE26BAD88D2CAE92B90F1E1472E9697F930B6E775A1A9B93EF62757B2A28F6962CF2C1478626A9B65B5AB89CC24EE4C9F765B8071737C25F383DD57598D2289DEE439D28AAE91A3B21E389267FB3D146276B7810D126AA5D096A16F679E28D5C91A580777D9CEA13C46234653634ABD964C720A11A6514A7FB7F5ACB0992BFC7C16FA84CD9686ACDFF2283A89625BC65FEADC9171ECA359BA50BEE412D31414EE110AD1D8748237941683BF292618F740445C0B728D51347928559E569EBFE896DC6295F87517AB31A8639B50C0F3A08E96926816B7B17C8ACB476C4C67B1DF7631DF7540276C99053B102738BFA2876E42A028869C688C18AAA9B00DF0F3A74CD81D86D161912C09362AB35BD8731A48CB45CB92EE8A3374B811EEF93A37F17DD7D8AFF88958E13012E6F7BD6DC63E27BC47F506048CE24BB7411538EB4B969656DCE8DF5ACF28D1BDF5ECD14A44A98350CA45699F033EFA44D25E93FC2094C49E", - "dk": "18A2405BD102699A2B22168A31D2C0E7F946160428EE787E8C6C57ECBCA0FD170DF93BC66203A8F06A3292310EE08495D1BC0DAF2A2D92C243DAC2B558291276217430A08D11B9C5DA411F2D55406BD4182913086489B43D74C602780701295A4C0054765338695231E6798020E7CBF1697573474AB35B27817BB38BC2313E70AFB914B5ABCBB28B7124302B338B471FC89336D1C35FB6D59C007402D1D19A1F96682F7551D8527EAA07389E55A8080791178407301ACF22EB32E0F7119DFA0E623035364CB0243B19918792011023A086016CE39BDAF0868FB08A4E1753B00B444A807787EB973CE52F63650B12A6B51EF435048A9F7136A5A77A99238763F433C00813C5CDF8CAB21B445630AE2D733F7683701242751F5C17A4F15FAFA5AC7E5A231097AD06299DD6AC194D1ABE895A0315E834BB364C286C8CD0216BB032B59D797245F40D624872036BA369355AF73C6FA5540BEC829112F28294191096A8AF53D37C5DA8B151330098582AA06C5455408765D43FE5B24C9C0471C9C85243C205747A43ECE8CEB31CA87BB51B39D15433F99D6FA638BF02373D42A09079399B4CB0A371984061370078A677E166D3D7B82E3174B58885D280A1D44911EB0482C58C7216D5A22694C767B9CB35BB0A1B0271471C558546037BE5585D43C40F6705D8C0C4579025898A2E21A0C5B0A4A42AB290E1F37D58486631210EFA0669819A90742926CEC68B1801B44D597E2CC84661917C9BBB6E2FD4B00D11AC616A245088B6AE323332FA40CFC46845842B02328D6E9A9246632DB8FC960B9340DE367A25D3996F48943ACA2656250D823BC999250C357C718A7CAC1197868D68C70F324391A75EB88C09AE835FD732B9047AC4DE843A6D00BA1EF79AEBC350B1D3541B874C3105B901441BE9F9663C306E085B0B0F98A4132586111417346B85AB5C26FB0522AFCCCA2168308803243BD1C1611574533466A1F709027485D680BE09624B03944EA5399E62A3A8A005B74227041E6C394CA22DBE3A6666541377573AC5357106400B35473B6672A7D4517F1C91A6A1266D25809B57720207E4CAFD88751CCA82AB54593CA126A0C60771CBC49535CC9A83882DA67D6F94BCCF7A5B605215B874C4786B24995A83C679BC12E870C61A3820DA5B89C0863B369A6C79B13ED67099EA02CCA1B9523529992A215C525BD5D37A39E69891FABAB70594AF8119F356A85587604AF35CC3A01692047576D97456BC1BA23639D4452A91C40A732509C70C83CFB080CE2BA6F29A80B0066D10A96A038C72CA7B6860594EE3C7C592016E147C7FE478B90F8A4CBEC166A3C474758642EB76CA3B0A806B16CDA19013986B10A3844A0CF86455F2808429B371A0592129414FD31BA24C995E303C776B014BD35CC644095B7140F2AB3336D55DE6D54F9FF244B6CC8580111C7DB2492A32A073E0196FA256A92CAF6B431B6F6053E52C308D6C0F8D86001258B78290AAAA85C9B2059A931833A6C82825B332943ABABF65451272AFF4BBC0FC279B603CC1E97C18F40641DF91776EDCB7DE245DF98099A9DCBE5B1C6C67FCAE6FB18A4F950833197364D94D224B8D29AB8860199CCF8CA3C8D1217D99484A631DC29923AA582FBB2566A44BAA1FC037C139CA3AF90D9D0516E7B0732F552BF264325A121F20D393C8E794D1E32A3C12BF68C849A6548BB308753524CE72130F037BA1C02A50162CC10437A5337C6056E850E2319474AA21AC223F8330C43E3A0BE3B0A42227266E6639252271CB2023A55866B004B8B43CCF7E212457157893247201B1AA4728BA476AC7D3B303A6F3BDB818641151BAB769C7BF2A1EBF027A79F81214687D0886C99FD5A46C8B4A1F5697A98BC9667CA574A1CA283BB4F424237B37C96A5836709C7FC0717537CA95213322E3396A55439E1F8C7756A0625FC23CD2745E63A054C47259025C92AAD22E2DC52045A8467AC069E6E22B65D25C2DCA2BDD31AF5057B0DBE93E3D921341046E89E5618A62C562349F2A646E65EBB64091ADECE8CFE68460FF95842EA6648C89BFB0E5AB1CE11103904AA04C4F55F7C64DD810917B756B02BC1054A8DB7116D0718E584ACB47C679E39232E1C87934D84111B0087C04C86ADC5C7F060D5B639FD9B1BC85775461100FA6BACCAD22495BDC0216639954EB53EF77250D2853878BC0183C0EB5359414CAC928E3ADE2E78213904D7DA453E96969A89259822C205FA46CA6703B6D324890E59F0C377C778ABB5ED2466AC929E8AA2E9D47A8CCE606F52B18A7C35C20F4C2AFC99AC327802B856F13BC1D9E3646BF2A2038C454095C147BD1474663274DD50041C9939EECCE460B7FF1605743D4243553A0752465E93C628324BB2D3783EB1B63AE85AA53311C5574071E56991211426DAC6F6AAC3EEA1569B04654D4193DD689A32432447E1A3F0F5595FB37A35FECAE5C55CA839A3CED94AE6FA436A7D34C2A81587CA84018933FDF39A931B03D81491624651A5F6AC75E08077FAAAE8AB023D6344557D15FFCB91C10B06BDA114C5C133F3782C309C347F2A4434DAA89F202817A227C1E1240FF41A4F3CCACFA497CDDC53AC5B0C55614907865118C2C7AC0D5031CBC106CB17A26B97755271C86E871BCC9590E1C2684F2C24A172B10844CA44346FB969CEBA1A02B9922F3AB68457CBB1F2BC6B5F5CC4EACB9D0072EAC617B31D27301E002E978925966B642B00AC53C912EA85DB59C5506F4724B2C356CEB40BD58AE51843537C537EC97B24475318A5B30AE750691765FEE1014644B1CACC77C9C334805A58DE18121FEAC6BDB61184D2C273AB725C32091CA3441E5140433435AEB0B51B9C57066C43F308A12F782BCA5237D7B12119CDC9AE2E7C65EBC66B3F02A0BE7361E08838114BF0D5250304A36935135C61597A03903EF215C6A223DF8A9515E622932F7A29CFA74807B145A20ADAA7987B0B981B7A62D115927504A090F61B37592A5B4E51B977821E4D92228531D2BA1523BAB3D6C850FB0660646892BE2A006DF51743FA383AC47572F651AB02A272A458B81441C8E774547E1773EE29A6A27BA4E839C8E023A13635922009B1111801872C391641F0E239ACA70CE3FC01E5C3736FEE2AB3F85C4AFE3A0BB2529D6EC047337819084222F0ABE8F859925708AE3E62815083196248720EC28174C01D716AD472A0CB2747EDB932F4A58ACE9E2BADFE468BA2A138EAB864EE00C034C1207F92F73AB084E32BC244951477549B2189568BA28553937E5F1CE6ED1B7F0C1012560296442AA6DA0879705A65D77460A86C0C06422A2E6949BB78B955355EEA2749BA0948ED094E5D9CE7C79B9F4047BF4E2128E41CA5AB1BAB1A87A2565CDC018890D426B37F01713DC923CD372605763C3B51A5AD58109F031BD665192F38EED496EAB15AF89DB622DB73A88BB6104D44C49577483F468658A9C72C1A2046252DF7840325978589A85F07C7572E44445F9A8854825E784706A25A70ED0CEC3F5A372C41C54185294975A70AB759B4250E1F2CB35E860ECC25932F55E6991041AC24D56BCCBDA579E421C905469052A34225AD50B69E191B4A36EB7DB1DC1216BB41524497B279230053E910EAB49859D1A99DB3C56CD70995BF031FB71B0AA40CDF031183E5B3D8D8799CFC3ACDDA54010AA6169A80D62479583111FEB337354F6BDF36A33279B7472800EB604710AB94A0D584942E41B78F2C387993A5EA079F3C74207F7972646CFD4E055FB6B10BC69B369D166143B8A8E7400134999F05C6A26DBBEC3B23D92CB90F77156A0C8A96CE93F73962C17F8104B52AFA2B68B62810F998577E07CB16FAC499F38AD628B57FC1C9CC7A568410478176BBC14C8C7A594A07A3568B503BFE26BAD88D2CAE92B90F1E1472E9697F930B6E775A1A9B93EF62757B2A28F6962CF2C1478626A9B65B5AB89CC24EE4C9F765B8071737C25F383DD57598D2289DEE439D28AAE91A3B21E389267FB3D146276B7810D126AA5D096A16F679E28D5C91A580777D9CEA13C46234653634ABD964C720A11A6514A7FB7F5ACB0992BFC7C16FA84CD9686ACDFF2283A89625BC65FEADC9171ECA359BA50BEE412D31414EE110AD1D8748237941683BF292618F740445C0B728D51347928559E569EBFE896DC6295F87517AB31A8639B50C0F3A08E96926816B7B17C8ACB476C4C67B1DF7631DF7540276C99053B102738BFA2876E42A028869C688C18AAA9B00DF0F3A74CD81D86D161912C09362AB35BD8731A48CB45CB92EE8A3374B811EEF93A37F17DD7D8AFF88958E13012E6F7BD6DC63E27BC47F506048CE24BB7411538EB4B969656DCE8DF5ACF28D1BDF5ECD14A44A98350CA45699F033EFA44D25E93FC2094C49E47269D7A3C68DB2C273EA465A5A30D6CE94BFF775EF4CB5F323C7EF064701B690A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA" - }, - { - "tcId": 59, - "deferred": false, - "z": "681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E", - "d": "7C43F2E7D9B1D8D9C41D9F315E052A254CE3A1F098671773B53717A95220AD55", - "ek": "9ADB4E6D612D58585179C9965CF816553BCEAED61651C13CAE0672540BA9763333A25273B59864FB94AB650C6C41A6969EBBAAC0156A9A3621A1104EF578CF1185001316AF57F75C9CF401C4D2C9C8AA15BA8855C730577F128FA32122FB3B29E3813BA9C6CEA1B38BA069662C954794050C1F18C126542644D04EABB9656C446F8C08C6C6214AF2772264872E894086144B30712811A60C27E24C7C51A99A001D296B3CCB5CB1B9CBF4370208C23294442A9C229D1944B59C03CDD663E06CC73AC493D1D75CC1525993059EB4F61C6EE160AD229F3D015BCC919A90449FE8054890006E6BC98D19B602F142515371B8BAF9B456D04B3A429051006997A961422483B2D61857330F74D5117559213CD766E183210DF1100DA49DBD992A9FCAA1AC5834310AA9E9F44B4B2293BDDA76E22C585DB53CB904BD3292C84FDBC38D793136B12C2AF7A58D88C45B0212F0A083DB0929B1B070C74194EA0620A396BB43E6BA9AE43BAB85C589E93986C746EF4643DBDC1F0EF302CAB02512286F846702D4A3AB69FCA5D2B54C7B603CF5D4AE90705F0EA36A6479329B6461DF47026CA86765A79577F2AE1D8A2013E977FF49296247A3717401F7B961090165E34023E8E373CFC8CA5BE146A5690138532A01F9B18C138D9C7B110A66BC47161B708661FB5B5C507A9F3ED396A163A281B2809EDA52C78511C26CC8F478980DC429042A2CBE73600A8A06972260E8F2C387434FB0087435E711E14896B8841BC751A79FF9B3776217E53287270B26023ACD1DC95395F52546E94E287538D2E9539D8587DBE606748A7CDB76449EC2B0ABAC7170C439A4F2BD3F1A3F349B90DDCC13878024087AC33C38B64EE04427EA249D3C7845629CD8D0C82189814E6B2260CBC100B64039599B1BF91938C2B2C35CA2EBA70B8474522FA6C37A917D7B589F646266D2D07B348169F84968C466C9B90A7B00A6505F6A567D5A14BDD2477CFC0B515C7931B3BC1A7021DE7B2CC7C650097B0D2A94A7B024B207B6969E22C720683084CB998E0C422D1B2FD9969DA2BA9096358AE11A5E101C6DE23C8DC041AAA2F441F8693A01A872E6356D9907420EEC3F55B945E34562C0F3838695643DA00336C1CF1802199E093C07347F80F0959CFCA72CE65E2C675BF9CA8B01F97600AD177133CA15932C79C9781AD01B36F606DC74A648054AFE1B74352A4EEA2095A0120D7C5332D1B7A61DB284A3A0519AF63D891A2546D9748FE768604C27827B6E45E1AA1335AC8F2295A83A6AC9E42D0047AF55242EAB2534C7B38AB65749CD21B0441781E643BC16D03D0C437E03E33BCD4B92A9D32BAD6513FBF595DF30BE0475B69A632928A0B4E2A867E4229525953CF303C47CB83F609A1D20EA1D3146C80BF82061E9C5AD670E4288C01E889E95F937611B419C38563228BB9FA85D3E184109A004DEFA472848AC510CB81E18C5301B149B0264942CBB88F8995737C425E44F50F53B9B2A4C44FB0E5C7145775900D7708D51F21173A9170AB2902CB911BFB82D2D4B0333B1832F043A79A6A07530CA00E5CC58E6B0C2706CAE6A6A52D69C6C0B23C90812116AA971398D154404EC531F3712348D0AC62DFA9A1CC0B01C470E16693327AB9BBA8083F22B8314551712475E187400EB801F1BA34F78024A5DEC89B4C7811E68B30EBC91E08373BB92AC0FE8A861F4BF0A0B5877088371209D3294B866A86BB6B470344A069503AF99730773853236AA12CB3C2F679B45D0025876199C68E676298AB1773C92E33276A60C02FF7415EB10838A5035B7114E9834C5BCCA795330009EE57368B139F9D71135D1C86B0833D2CB81D660C56FCB3EDB848721C72A59A8CF45B6543CA7895E686C26A86A5AA7A8C1734C5F576D648482026391CD611389C44807EC771DEC4FE373B483B00D68F34AF776244EC07874A5C22C6C566CCC5C70369FB92A22B6BBC4F4144BDCE6C3A5051268DC8D6E8A2B8F8A8D48020804880FFA32BD01899CA9D3A70FD62A91B74ECEC51BB58594E7F162C7E94D44D64D66592880C55011A8550833A599375CF9207605784C11FABA854BBE6971065479B6D26589D2C756DB93C83E50936CC0C0089CCE8EE0A08149B732559586D07C4FAB56D7A263CAC656314268F55C64A1D6982E665DC42766D84206BAF103D14014221F2914A06162064F7E475811518022B301C262A125BB439D32", - "dk": "92D719984988C65BC4E3E60514E25F64C70318D049A14B110C2196176BB7F9183946C24894F075DE191261544ABE9BABD3280DB7A41B47A937C9597EE995CADC33C1AF87CA2D740F09249CCF376B7D5CBD1B69179323673BD6CD8CD9A84C47B7D232A912F4752BD94B93914427F2CD20C6391CF71F729472095C5D1C3C57E03689D57AB4ABE677909A9895638B790903E5E50D2421117F6A23E7A5CD6A3053FBAA42F386BBD3D82D8B788FF7E652D5830EE676BA978C60342694150A5B28D8A5AAA66C8172AD93D9B3B334C0BB4672DEC182E4395157A0997895BC44C48F3B222C5EABCBF7F2C2973C61B09B3889F0891E35934D4116663A60F751C48E22186B72969EC3BAC346B505CC6699C86BE8B1836152CD6BA37962A23E29B256C555845EF24F52C43DF0C20326841C77E3B87D16C59BEAC267056F40F7117E44C5C957465C09787A52594D1565825243FDE9C568115029F3C378B99F8E28AF395A2119590837B06B75E293682441CD7C5773F5BEFE7CCA172B8DD6EC0E792999D3B40A0439336F2629A1DB78227BB870F44896E112D8094524962F68370AD7092F60375C7A986340D32CC52633B1A714529425DF69BC918A30BBD577E938B6C1D06519078F3D934B7CF77FEB7A179BD8463829AA37D6C449877823231D0EE81B51FB12751946AA1C594ED175607B36D1B7B94CEB8D23B6AA680B9A72857BA61A445AE80C1CF45EF70B44AF6B3C428C8A25689AB8228218C6C0CC858E6A98823E3673913B9163A339327609FD459AFB05CADFCC2943E45A965B54F1A065F68B1F153CC8912329C0F0C0DC605FE6E52905C8B3F1EA3BD0E99418C645A8E6622DD577E9F2BCFB649C1DA09FB8E20DF470CC6317613D788FB544921C325B7B3B7A0A1C3ECAB62B866A513609590E871B17D7866F8A96B838C33A562DD1D47787D795BCE61AD3A9CFBEA5B03290320612A76BC198B0B84D8953909183A14FB318840469E2A909FCFA2C8A9B59E12C77B14A6503829AE8D3B493FB9A6BA6BABDFA7BE215B23ABB5B62C2C6042A909FA9999CFC2A23790548B6055D57B3FCE2C155A6C6115B05855249BEC0887F00369F38379111846946CB25F39305054BAF669E75830A505AC3148299E5AC2B4BF59C68986408270A8CA3A87A70A380EA7AD5871E7DD3165A733AA1D55F1184441DD84183B1002BCA518F370D02D5806498482B4236C8E1B1BF07870C2C7E1D44435077905A5C461238970B603F234B9351FA4213E0CB8DEC764475534AFA18AF07518C573DB0D9790C873A33293424A434B9A933AC644B37B14435D0AFE71B443F83BCEEEC9574016214DA8E66ECCA10668684EB5D776C5B4B2C05C2E03598A602717A72EC4B18E5F550992ABB76A1994B4842FADA39FDAB9DADAB09D6BB9B46AB4EEE69AEBC419F1587B8D7061BE188623F4471852C9294146261A67345F5A2347B206D2870DDA681C44CCFB420708AA398864469B8E08E76081C41F5977893813653A744766125F27C28E6C1DE51978448BB8770B8660B6E4767458DB70990E24FAA35B4DC7571B5EB69BE48C8646586F0ACB48A3B3252A02EF48A7DBD44A5E19177069C6F3F678794B8488C313F70EB4AD6FC09BF078467D362A436411AA689885B987104BC50E00340F8294A06AB8C02B0569B1A6426C13CB9B651677585BA213F7C297A949096B27A02E9510C803EBA002EA423AB3C810595D71F6201366591B60091B305EC7E80371E6DD171DB235D389B480F9C32CC7AA52DEA7714D3004DF5172E034DED271B9C679846A6AC4BE4580E4414EE42CAFED11387CBC98938BA6A59A07E2238B2B54FF6F18D3F48C2FB0636B5CAA3A581948067B1FDB083E92A46EED9B090032655A9BBA2B207EED10D419991AB813140CC898D11B24566970A601326072E15A31D73C0A625FC3E6B697575D293D1B3142F12190B28AD4DB6278CD9A92E50AEB3B60E687A14D2C48623955724582373F16DDE3919A8C7B98CBC514977C5E96895FDB17A952279B8222548EA4B08D4659517A7809C0E786986C2D69A1F7963CE2672726C7CA4A91509856476C13B9488A2A429804815126954C2CAA43F1EA7877BB10346C022A1407CDEEA6322D74C760283CA8699B6433AD16A0DC2238B9714887ACB0315D67139573EAB39A403C3459ADB4E6D612D58585179C9965CF816553BCEAED61651C13CAE0672540BA9763333A25273B59864FB94AB650C6C41A6969EBBAAC0156A9A3621A1104EF578CF1185001316AF57F75C9CF401C4D2C9C8AA15BA8855C730577F128FA32122FB3B29E3813BA9C6CEA1B38BA069662C954794050C1F18C126542644D04EABB9656C446F8C08C6C6214AF2772264872E894086144B30712811A60C27E24C7C51A99A001D296B3CCB5CB1B9CBF4370208C23294442A9C229D1944B59C03CDD663E06CC73AC493D1D75CC1525993059EB4F61C6EE160AD229F3D015BCC919A90449FE8054890006E6BC98D19B602F142515371B8BAF9B456D04B3A429051006997A961422483B2D61857330F74D5117559213CD766E183210DF1100DA49DBD992A9FCAA1AC5834310AA9E9F44B4B2293BDDA76E22C585DB53CB904BD3292C84FDBC38D793136B12C2AF7A58D88C45B0212F0A083DB0929B1B070C74194EA0620A396BB43E6BA9AE43BAB85C589E93986C746EF4643DBDC1F0EF302CAB02512286F846702D4A3AB69FCA5D2B54C7B603CF5D4AE90705F0EA36A6479329B6461DF47026CA86765A79577F2AE1D8A2013E977FF49296247A3717401F7B961090165E34023E8E373CFC8CA5BE146A5690138532A01F9B18C138D9C7B110A66BC47161B708661FB5B5C507A9F3ED396A163A281B2809EDA52C78511C26CC8F478980DC429042A2CBE73600A8A06972260E8F2C387434FB0087435E711E14896B8841BC751A79FF9B3776217E53287270B26023ACD1DC95395F52546E94E287538D2E9539D8587DBE606748A7CDB76449EC2B0ABAC7170C439A4F2BD3F1A3F349B90DDCC13878024087AC33C38B64EE04427EA249D3C7845629CD8D0C82189814E6B2260CBC100B64039599B1BF91938C2B2C35CA2EBA70B8474522FA6C37A917D7B589F646266D2D07B348169F84968C466C9B90A7B00A6505F6A567D5A14BDD2477CFC0B515C7931B3BC1A7021DE7B2CC7C650097B0D2A94A7B024B207B6969E22C720683084CB998E0C422D1B2FD9969DA2BA9096358AE11A5E101C6DE23C8DC041AAA2F441F8693A01A872E6356D9907420EEC3F55B945E34562C0F3838695643DA00336C1CF1802199E093C07347F80F0959CFCA72CE65E2C675BF9CA8B01F97600AD177133CA15932C79C9781AD01B36F606DC74A648054AFE1B74352A4EEA2095A0120D7C5332D1B7A61DB284A3A0519AF63D891A2546D9748FE768604C27827B6E45E1AA1335AC8F2295A83A6AC9E42D0047AF55242EAB2534C7B38AB65749CD21B0441781E643BC16D03D0C437E03E33BCD4B92A9D32BAD6513FBF595DF30BE0475B69A632928A0B4E2A867E4229525953CF303C47CB83F609A1D20EA1D3146C80BF82061E9C5AD670E4288C01E889E95F937611B419C38563228BB9FA85D3E184109A004DEFA472848AC510CB81E18C5301B149B0264942CBB88F8995737C425E44F50F53B9B2A4C44FB0E5C7145775900D7708D51F21173A9170AB2902CB911BFB82D2D4B0333B1832F043A79A6A07530CA00E5CC58E6B0C2706CAE6A6A52D69C6C0B23C90812116AA971398D154404EC531F3712348D0AC62DFA9A1CC0B01C470E16693327AB9BBA8083F22B8314551712475E187400EB801F1BA34F78024A5DEC89B4C7811E68B30EBC91E08373BB92AC0FE8A861F4BF0A0B5877088371209D3294B866A86BB6B470344A069503AF99730773853236AA12CB3C2F679B45D0025876199C68E676298AB1773C92E33276A60C02FF7415EB10838A5035B7114E9834C5BCCA795330009EE57368B139F9D71135D1C86B0833D2CB81D660C56FCB3EDB848721C72A59A8CF45B6543CA7895E686C26A86A5AA7A8C1734C5F576D648482026391CD611389C44807EC771DEC4FE373B483B00D68F34AF776244EC07874A5C22C6C566CCC5C70369FB92A22B6BBC4F4144BDCE6C3A5051268DC8D6E8A2B8F8A8D48020804880FFA32BD01899CA9D3A70FD62A91B74ECEC51BB58594E7F162C7E94D44D64D66592880C55011A8550833A599375CF9207605784C11FABA854BBE6971065479B6D26589D2C756DB93C83E50936CC0C0089CCE8EE0A08149B732559586D07C4FAB56D7A263CAC656314268F55C64A1D6982E665DC42766D84206BAF103D14014221F2914A06162064F7E475811518022B301C262A125BB439D3225F6DF8F68FACBDCE4839DCEEDC2B96D6191CA1DB11F347EA0D66F8C2458A848681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E" - }, - { - "tcId": 60, - "deferred": false, - "z": "40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F", - "d": "C2E1A3161F3734F44F3C2F1736E149803F71321122242A1E95E55E5652A91F55", - "ek": "F93584C1B0237F83AE90B664950B471E763CB7939C28D93604C83F73A30F80B3AA8F948086A142A132442712CBD71A9D495587CAC62F98F922E96C9D0095B1502B42DA76B59B1C183338C1C06A730DFC2E889273326593362006EF948AEE1A521E159FF6283DF3D11DEDB1655FC706DEB2C6BE879D3605C3AA463355FC726CE84962500B72776EBC9AA3D960A8084C3182EB8A43918F80EBCE5425257C2237CAC811022792485772BFA51CC7171F86F4C847782BFF123763FA650CB1B173D1AC78F7C19E764F5039736A3B2BF37B67C9783DA9EA6CD0A96FD7DA758E411575F6744DACB42AE2148B7BC9FBF49B4D25CCE02BB906B025EAB98171B80D55C8A328D15C2668A8FDC3A463CA6508E1818437498AA27B04D8514795BC4675C1B94ACEFD54603C498056038D3445745D44BD6F1A4316191B905C650668A3E2402D74E560CBB7A667A27EA4D38495010A71085957421923E21718E611CD5205FFF6AB91C65407C67E7EE19EF0A885EB88B02901478DAB0456D94E4073576AF0542E33C9286048E491ACD2EC2A02E5181436BE7D829AFCA68FE0A78588D886DF77B6F1F94A959B2AFDE328B8B5888569AC34D23771F0AA12C7954EC82A6E71C1760654C34A926DE4B0F07025B9517B2A036577728C7E35653CEC816C3677F703B0EB3C18AEC948368009CB013E365A1E643244289B0AE11440877266C27C955C7773D4377BA2D7C6B8DA7D23C48A19EAA7374A5A9B931F42E144A6CBB8CA06BBD42396B02C6AD16BA6B1E36B2161903EA4A654A31C507825347B9BB177C655B848BD943162F41818F113E864B456D504573B8C4E5B8A07F14713612F78537128253B1B9712C417CCAFB271DCD9683EB82C55D171723A32A5D40EDF9252D01C7ADB6664D6467421920C5B345B2D93C3DFCBCB1DC538D23454068AAA2B85CE41574079136476CB1CA401C1134977E97C72D2C85C37E872CB725A2AB55BB6C37EF2E517608A95C14A970480856A8A5737A06B46E93D03D6384AB8562AF2C37DBB1D52737CA8C5404632C4E9AA714A4A5CD3D073AF069CCDA490C64C42974B57D3BA6C500588C39BCFC4B26CE6119ECDB6A2A47141DA96BA2331996EA93C5D7618F4FC9A27FB6F5BA336F6801938EC26ADE456FDE01D41C22E1424611FB4487D8A2DA212A09749524F004CDC76B8F6339B11041A3174B8FD58B2C6E7B0166AB4246347D25AC489C43288A23A7E59C3CE320E3FCACE6B6277400ACF9E924FD12C0805B70354F3AD8DE92644F8B4936C81CF301FB87A7DC4578628868ABF501626B045D48537F2212A3FA5396C1C857B1084B21B1EB968AD60B43181C77712001290300C9CC2A3D6562A00FCB4E5F11C2AE412DD29181A034725A0CC75E2BDFB851DBFC28AB3362B8CF378BAC9939D340317C64469C27D8F3675C2A962DC7A00E9F67BA1EB8094F0B205388C59223C7BB963D8E21D933B779B360706AC5E06033C1907A8C8EB6E6017C285A8827E28B8CC7A5891CA381FD50D5EA231FEB5A7A4E4380FB5067A6505FA627D19715667FC5602B041CDF9074A3C58BDB9C77CF23F6AD1005C4A6F2581695F444578A734F8FC3E9FCCC07A873A5AD04CB2C724F6820AB1C081306B429F92834FE8BFE401448431BEBC4C7335EA0EC7050A0A49459DB286B774069B161DCBF3BABB5430FF727A419B1AF2371E1441BDD53C03E5445391A401668B693C6503F35CA6CC7A04CA298FFB81CFEAB4B8DF400E1F670801E7014DFCC8B3D8BD953BACC1D61F184A07B383A8325C1251A56E8BFCA75C04CF8653082D52A8D6C944191155AE886AD9AC010AC50BBD2BBA9144785F02B7B7BBBF7F1AB8DF210241F4AEA1700D840AAD5E2761C4066165A43C487B3AFF68BF3370891933BF46C13BE82331F189B678150748AC609B3378C3581AFF91C9A4F2B9C040661E11A917F7A604100E5B9863B8D3B55BE32CC1F40DC47C4F02622863A560F25B03864502F4304F1401B90E4969EC110331A418770B1CA626B3A86659AE9B7B630C6DE1576286976453377663950353BC8067691BD1E1C24C006204E3502C171BD43C33271548EDDAA641677D8D1161152216A4944D480440E3B418042184194C6E39FBCCD353C58A6C3BAD16A33D666D601237F341B7AEF3C98F237E585C8E152B444DF15A768B20104AFC8CE55CDA630D36C048C7D5206708B4699726C1E2FC3A722CB514", - "dk": "AAE64B6CDBAC89352E7D1311EA15C4C43635D40B98F471A9BB1C1A0B086868D2651546A3F6C1A1F6FB8E75010B8661BE3EF1251737126DBB8157B6A1AD3611B04B95DFE46510BB94E7B0B87B55315A98AB61946FE926984FB5A4BDA10333221B92EAC1CFC2A15BE83ADF9297FF61CF87991EEF977A584A3D4CC765D710CF3C630687990A85F4CD1973861868A8FA1A1D3C26A777371CF6108D1B83243B058F729448ECA2A5665B2B6B032BD83CAD34EB5CA394C6DE96AB3552BEF3B28DB6390978DB65A30C6B0528ADA091C80D42AE470078C1D3C45EA21AB418A865FCC2FA4C3D78B76E84B3C3AFC0BD9B2721A092AA274B7A4BC3B8A9DC57332C81B0695522316755A5B7F1F992F5E22C00B29CDC6281ECAA0E74A24C0C56573AB8453F469872722C8796BFD1B64D8AC93F123C74740511A0B983C20C153F005BCBD04965EC95975858045681DB4B8B70327CCDFC9FF8377D599384C15875EE346FC08066EF3BC09D46016B8754B8C0B6BD944D2B157CFE3392A25B98D48850536B5BFE119F58A0739A48654CC8BBA8EC1C1AF4A197EC758396CE4C0C4E66D0BD43A03CD65A6028C185C6C1C59FCBC4EE7017568061BE551BC0BB3509102E8F14829B603BA1CB910DEC374CEA99C301851111A3DACB2292CB95ED1C8B53B965C6D33307B40C538C63872B83DF8C3922385AA8CA075FC118DBB323035C768149221E2C135291070671270CA5342B89044DB59346314F95B95BCB06D0A1F66645B907862C60B4C8CEC097CA87C7B3F2720DDCB0C5D317B443437CEDD32F2357015F9350778A360219B7FC178531B2442F114F2024595EC4CAB1F6CA26F827542096F8B08C4492156424504CF46DFCAB2DB7074FBA212F72284194C59240EACDE348BFC22394985A09874B5BDCF788DFB9B38031B1AB762BC337195597A662673514603E49C2A485E61D37691B31C46EF67CA30C79A6037726735861BF5A31FE102B448CAF32B7103D3549AAE16BB8186670FCBEFEC61D47E923E4460B8CDB029AF81C99F80456033C1B1351F7FC5932902E791C8D65466A36523BA6D58FD370905F3B21465B88C125B23BEBA9F3DA624685833B4A189CE2480D4739AAD85E3EF41E0683B0376C561AA6685F2289891114CA4C380F43289C201CC6FB6E77213E1FB813F1A12266E9812BE91EED08ABDAD5477801201F313CE6A11B9C155F8E07310D6C7769E637EB123524342DFBC67FC0E20A3D09AB9B5C06B149C39FA12E21870273C8C97FD56A1CD346F627593A01606043A18F35C6A323A22A48B3DB49923D3A2BBC92051BD4A9301CAA0D9A386569A37261CC12172839499F928A6A70806B9D8A24AE304D98876AFE6C3E24D500BA08A8F285C9633414825AA01AFC5E55CB2AB91A53DCB47DC7904F6EA77196A8BB9E057A092208BD81C2B9675E1C263D0BA024D2D92B5E85C164E149572B0288531B6BF4BB1E629D7295842A5709D06810CCC896E64A5516130959881B58633F8C411F5032AADE7879CA3385715C8E590B6AAED47D38A708822AA7570848439867D6CAC7EF7A76DD3B890662CE65271EA065302D3A4B4FAA2143F5530E890A1B80B75935BC3C06569C7365A4166AB4D7C1B26030C2A777A121C0099921C77AAE3644BBDA315429C06CADB33BAA3CA419D5064A5BC9C7BC6C8D34C7FB0A254409372B679FCAB46D47C16B94BB2E8253475C0CC5BA6C7DA39141ECE51EDB844A4EA4AC6E3866625679FFF71CFEE1477A918CD82B0883B67BAF2A383B436FDEE7C58AD372E698778866377561BAFA8C9B596AB48676B08E2BA9EE1AAE07BB194D841586662DC64B1065CC8A52D899D09C6F96286E272895F8865B54DA8B33FB67AEA1133E611BF9ABB459AA4442A60CD09A4E39006616C3981604662F7006E0C9130739A66E79BFD123C679A368B64C331C285AC1CC721512A52148A382C09474773BADCA77CDDCB6E4C40022CA10E35A6BB205239074AD6B6524C2329103D281E8CC479AB4AA2E5C2960A903C1E05B48F07B5C88C384533D93A9BF07EB8B7376163532AFAF32B4C481694C11C97ECA8AF0E714F0427D16CBC331E9821E60C735392AE047303DD637AE5AAD915232EBF481BD03ABC845372C60AC586009BC717B6D1A1E78FBB7ADAC5DFA89C410E786AB4422A87BA21A088EF93584C1B0237F83AE90B664950B471E763CB7939C28D93604C83F73A30F80B3AA8F948086A142A132442712CBD71A9D495587CAC62F98F922E96C9D0095B1502B42DA76B59B1C183338C1C06A730DFC2E889273326593362006EF948AEE1A521E159FF6283DF3D11DEDB1655FC706DEB2C6BE879D3605C3AA463355FC726CE84962500B72776EBC9AA3D960A8084C3182EB8A43918F80EBCE5425257C2237CAC811022792485772BFA51CC7171F86F4C847782BFF123763FA650CB1B173D1AC78F7C19E764F5039736A3B2BF37B67C9783DA9EA6CD0A96FD7DA758E411575F6744DACB42AE2148B7BC9FBF49B4D25CCE02BB906B025EAB98171B80D55C8A328D15C2668A8FDC3A463CA6508E1818437498AA27B04D8514795BC4675C1B94ACEFD54603C498056038D3445745D44BD6F1A4316191B905C650668A3E2402D74E560CBB7A667A27EA4D38495010A71085957421923E21718E611CD5205FFF6AB91C65407C67E7EE19EF0A885EB88B02901478DAB0456D94E4073576AF0542E33C9286048E491ACD2EC2A02E5181436BE7D829AFCA68FE0A78588D886DF77B6F1F94A959B2AFDE328B8B5888569AC34D23771F0AA12C7954EC82A6E71C1760654C34A926DE4B0F07025B9517B2A036577728C7E35653CEC816C3677F703B0EB3C18AEC948368009CB013E365A1E643244289B0AE11440877266C27C955C7773D4377BA2D7C6B8DA7D23C48A19EAA7374A5A9B931F42E144A6CBB8CA06BBD42396B02C6AD16BA6B1E36B2161903EA4A654A31C507825347B9BB177C655B848BD943162F41818F113E864B456D504573B8C4E5B8A07F14713612F78537128253B1B9712C417CCAFB271DCD9683EB82C55D171723A32A5D40EDF9252D01C7ADB6664D6467421920C5B345B2D93C3DFCBCB1DC538D23454068AAA2B85CE41574079136476CB1CA401C1134977E97C72D2C85C37E872CB725A2AB55BB6C37EF2E517608A95C14A970480856A8A5737A06B46E93D03D6384AB8562AF2C37DBB1D52737CA8C5404632C4E9AA714A4A5CD3D073AF069CCDA490C64C42974B57D3BA6C500588C39BCFC4B26CE6119ECDB6A2A47141DA96BA2331996EA93C5D7618F4FC9A27FB6F5BA336F6801938EC26ADE456FDE01D41C22E1424611FB4487D8A2DA212A09749524F004CDC76B8F6339B11041A3174B8FD58B2C6E7B0166AB4246347D25AC489C43288A23A7E59C3CE320E3FCACE6B6277400ACF9E924FD12C0805B70354F3AD8DE92644F8B4936C81CF301FB87A7DC4578628868ABF501626B045D48537F2212A3FA5396C1C857B1084B21B1EB968AD60B43181C77712001290300C9CC2A3D6562A00FCB4E5F11C2AE412DD29181A034725A0CC75E2BDFB851DBFC28AB3362B8CF378BAC9939D340317C64469C27D8F3675C2A962DC7A00E9F67BA1EB8094F0B205388C59223C7BB963D8E21D933B779B360706AC5E06033C1907A8C8EB6E6017C285A8827E28B8CC7A5891CA381FD50D5EA231FEB5A7A4E4380FB5067A6505FA627D19715667FC5602B041CDF9074A3C58BDB9C77CF23F6AD1005C4A6F2581695F444578A734F8FC3E9FCCC07A873A5AD04CB2C724F6820AB1C081306B429F92834FE8BFE401448431BEBC4C7335EA0EC7050A0A49459DB286B774069B161DCBF3BABB5430FF727A419B1AF2371E1441BDD53C03E5445391A401668B693C6503F35CA6CC7A04CA298FFB81CFEAB4B8DF400E1F670801E7014DFCC8B3D8BD953BACC1D61F184A07B383A8325C1251A56E8BFCA75C04CF8653082D52A8D6C944191155AE886AD9AC010AC50BBD2BBA9144785F02B7B7BBBF7F1AB8DF210241F4AEA1700D840AAD5E2761C4066165A43C487B3AFF68BF3370891933BF46C13BE82331F189B678150748AC609B3378C3581AFF91C9A4F2B9C040661E11A917F7A604100E5B9863B8D3B55BE32CC1F40DC47C4F02622863A560F25B03864502F4304F1401B90E4969EC110331A418770B1CA626B3A86659AE9B7B630C6DE1576286976453377663950353BC8067691BD1E1C24C006204E3502C171BD43C33271548EDDAA641677D8D1161152216A4944D480440E3B418042184194C6E39FBCCD353C58A6C3BAD16A33D666D601237F341B7AEF3C98F237E585C8E152B444DF15A768B20104AFC8CE55CDA630D36C048C7D5206708B4699726C1E2FC3A722CB514936B2729D96EFF6FBF9B05E34251304A92EA873A21654F70C4632113C36F62CF40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F" - }, - { - "tcId": 61, - "deferred": false, - "z": "E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107", - "d": "ACB7FDB596B44A88A60ED74A3FAD9EF745BF5BFA4902CADB891EC5CA45F685F5", - "ek": "E42705D23A30A72638425280BCE72CD596BA2AA6B736A922740C52A0F470C0A1311ED82E15F4C5D865B6BE18B4810127282C1BE22A9BC580784EF371F18482F2E43777396A3E6A77FA284CBC6C663D63005DA53232B06A27D65547FA58E263C00AC701B3B6566F199F5EC172AD4BC12FEBA212C7159C90C589551110066D87E01D54924ADFE0CBEC921AC7B273B1FC400F6B81F23073D6AC0D7AC34F2DC60C08777C5559B013F23B91A743443B1B38375E91C254D8721F1AD2B02E9C566FAA294ED75BE16C0B0D82C1DCC8AB4A6C1D6E88B567C11A49AA055EEA87117A4C5B1C030F8ACD3AFC69D5FA8F082210E356A426C973A17492E8C3C64D87087A54589BF468071C0DAE016B6B51C52B628BEB986845B484FA213A27C6A1D505AE09D499FB92C17DF2AF010C71C1FA0FCD89A59EBCBDA4B7AFAB2CA68421AED1C464892C5ACFAA556DCC227929B6670904A01C5AB2AA0A5A246566C61A7BB9CA07630DD005CF8705B1B414CE8070A43D30CCB45572DEEB253E19ABCDE790A7F4BADD7863CB187FE8AAB9B0CC1C8309415F54AF4BA6BD6DC74C3AA13B0126254DA08F833C71810092E7332DD8CA4CC3199D4EB25405D310A3E9A6E65C8BFED0C6973A6F324CCC3EE16CC3E405D1C036086C5BE644A1A3709DB22A392EAC889CFCB6D9A03CCED44AB241AE735490EBE44A8B333C462891AFF72F2482C9B52B98106BB010A4CF03214330C5AEADB9B7314273D88880358A568DAA16DD8B496B6CA9C758B74F207B5001826391175EAA2DD9912E84B77EA257052065364949CE57365CC457854681729B389A7CC4782F7590EA6ABC49C40B4E23A2EF916F53240CA7BCA58370657490C52AC535E7CBA1CC58CAF52585DC148811264C2E6AA6728A254BBCC983D71716E82B7A53A2ABE376A5362E74F57BEB1979E2FA77998C869D6A799D0934D8475C8CB28AEBB3522387251D11352520C9A76697519B2DB6093CCC3A5A99D75E136C9A3D305F46F3176EC07FE4C30E25B21BDC2996DB413E0350AEE4A96125C5337AA70469F392942037674561D85969AC6664F6D92DD9B5108CDAC8A6E86E8BC1C1DF319AF330701E23AC743232680B3370B471CCD91761C110E309B5D77A48F4E06A681A2B38ACC3185946E7DB0D6EB1837D3199D83C676D667AD1CB51DC9982D3D36BCC121627D21AADF01928F32DF347CE495175F84641CC0704A24B7D099C416D3A56CC5CCD3ACA34F3F670B64C57AFD0591A628E4A19A83914C14212BB4D43AB1548CC772C25F38619692A5DD88730B093AFF5968B9AE60DC8AB8BE3D13F16928E4CD0CF604835F23B101BE7903876C8BB9970BC74A0E4752A67C4BE2F20C10BFB7765D863828565D190C5384273DED40E331168A4AC2A6CB8B0C5D600F5359BE70AB0B74C3C427857B34A9D2B7731DA6ABA7206253A67C22AAA10F7ACBFDB093BB7647B50D6AD449257AAA9CF29E5C5AA2982D6E0B67813BEF12B4E2A9669FB94394E34BD9583142456CA048763E0EABA7DDC48E3CB80736C6121F1888DB3CF85177942F322C3F029B427A6B8DB4976E1B80E9047BF91BDF2449F0B20C336E041B587182DD4A459C4800CA85308658E3BA78D66F47639AB1B70C45B43F70CF8197803BC1EC4A4424DD78C26039F4AC3C84F98A5AFB45A6970158E41296B925D33F68ECCD3B5A0B415F5B7CDE3473859DC48279255F9995561C205B244728DFC4F625316776267BD468BFBB287097911F8C2A32A0CBF14C3C708F9C4BF70C612C61FBA3720EC62918149165BBCA3CCD48CC8B272E538A1E818843B272DC694AD8E265E830034ACE5708CF22AE3D256745B50EC328CBF03760CA73E7E35241776864856BFD7C18577D411AAF99AD412CAACF44456228DE0176FA0E13CB925140F8A5BE9589F4B6B199F751B7A58751DB35680C78C69F83333155D80E08FA92A5B0FDAB909F9223D167333765D033213E3A65EB2B709BA200D861012D7145A9039C4A6B032D9D5802846441C379978EBA4B9970B275271292379B96717E48680FAE36DDC7018AFA8B3C1929AD62268F12AB87FEB92535A655158CE4957A1BE37C9922B4E08D57D85525D6F2B7698331FB3F1219D91A1272B7E92D3245E4649A8257BC362BA0E0462991A481A0A602809C46F4342ED40AD99FC74366406ACFCE7708AE11AA2C3436EE06121FE6CD52FACE80AA5FA2B65A0B1B28F8B28DE", - "dk": "8F841DB58339CB208908CA123BFA4FB00413A60A9EA76648FD69BEECE0B731042AB206368858B0AE798A7A26A1C96AA302AB998F352634CBAF93F81EA4C280830B8DE435CD4DFC3C3674CE2338AAF6543A57BAAE1232780B578BC3FB4230919CA56065A6E466FC19B9322404499199ACCCADB0236D6026BC927C58EA225D34A628721C746D2008C7B2A600CB94E5F93351088A1C6609CC350E5E0920D4D3139AC08A28A0A5DCFAACF057C3DCD933DB7A8159A657CE257481AA1AEA69BDCCBA961B82C56AC15A74DA139BF388610879EA716035372042984AE027C910E149FACC954762B75FE41214A7B808B168FA728F4D52500C88B2E96A121AC9249C3761A97C7333332CFFA182018A15D4B550A930BFE60AB73F20573345522162A5DF021C19F290567A95ACF4622A919AC20BB42B11BE06852094947897B4A7987981F989A29A13C31288B8C30B36244894CE502DA3967DC0636C94810A2A0B9EF72B215E936E330556F0309604B99093B246AB102553117CA48458E845CB87399A42499A0F7913A15358F334577D84004CF23522695EBC6630503B7ED77076EA7C0ABFA4218943413AD664F761C429011F8F0A66E5C22794F60E9FE2B995C004FE21AEF73AB339468735731A969A3E0E192998933F2864C6BC9A82B1A5A542CCCFB85CC629EAC5BF2CBF1F1438ED5109BE13B7F182280EFC07D937783FC5407215742329281AB7B8BA687DF328A3380CA3E4C09523B056EED254A4B7AE6C241EEE61A340528308D3C11F96A315D0B4B02BA47AC14388F2C005A0B15C75CC3D72717B2B13AE8A830AE7706064630A1C0B97858B75B228E7E6C12F1344F656A2D0405E3E932BDE3846F91AB60E183F2469C2A0B47E59E20B89303DFCF89EC1368243B03A4864C26D58B691026B2E627E9C36BAC877C048708B058B02B5327B3325423EEA5C52E311A6E208880A688D540127DBA7FF46CBBC35784BF538B5B04CE774BF5FF82BAFC844445719CE532D928339A19744E9F6391852B5B1E2C06F61CC2C28A16D3BB08081825F040CF0AA489751CE8C99CC0930379A426D3E9A15278B7D40021E5F890B06A767E65088311A8818B5088946CE9871A55D602B8FF389FD9B2E80060E053B82275436FC9690D1453B256CC510735CCE3331D109C1247B6875DBA71079A353293B624C6494762BE23B135DB14599F41CF3BA8EE07CA032E652E00B57A6214106C587B96097B45390A4431ED2B524C641112A95C65F93CCE87816E85B7955A91741650C4E8A944FA088CBF274E31244F77A4C50A98D44B96FB8625FFACCA584AB18740C8278A8ACA2E12989E60CE7A70145B394B7137EA86901D629C63ECB42BC59673DD73515DA3BE2C74D595B6E15AB4324786574D842A2518F2247ACCAE3012AE36CCBC48038BB5C69B3BF95D59016492E2E923CA562C8F8F444CDD3756A69336EE972786B88F2DB42DBB2309228279D6AA29474C2C94721556131DFD95E0520B0C23C2C1B49683D425EB313954154935CC06109182BE7C8A5D45A46B97196B6B794F4944EBE2052B3454EDC814938868FA1FC7ED4D76342591BA5EB96C73166AD311F7C80CFE7C149A2301DF1B8BB96C7742F03B5B3541A8E05418A7A3A89E1841B627D85CA7B6D56897DF5C5977A1E67C2B5D97894245620DCDA7B3183771081B4FD77476440013E417FBCFC4C38A51C1045219FEABD3C1258203A716FDC922F95CB71C15BAFCA2C777812C1AC390D540803B917D153B75D7A947AF328B620B93348CE7342212A286FB63812C2930920933473C95BB383B7AC054E4DF8CAF7D2A2C7C8CB3FDC5CA949177B40AF5DE102D9DB382D3C6D918155FAC94EE088A067C43BA21778D4E78FA0157C8457586E1AB6A07922FCE01407D63E7366BF68116EECEC8F01C262F766008C9A33C2A5A7C4575E95DB458E9C8289A30EA4E32E015856FCFC03C0EABD2021473B251C279ABC66D87EA1F66AEF5A8189544DE7A95C6F8544D8481786C72BF0EA329EEC4D2423846770707D922DDA38601B228E12451657725923B25CE29A10398B5D16492061D77E48EA023A929A4EC3634FA0073CB929CD1A42577B1E6F89CB9522A28B6A9248D243D423884E03799E6413F963462B7B3BF0276BAFE5AFE2F161EA76566FF4406649BA3C1B5811188FE42705D23A30A72638425280BCE72CD596BA2AA6B736A922740C52A0F470C0A1311ED82E15F4C5D865B6BE18B4810127282C1BE22A9BC580784EF371F18482F2E43777396A3E6A77FA284CBC6C663D63005DA53232B06A27D65547FA58E263C00AC701B3B6566F199F5EC172AD4BC12FEBA212C7159C90C589551110066D87E01D54924ADFE0CBEC921AC7B273B1FC400F6B81F23073D6AC0D7AC34F2DC60C08777C5559B013F23B91A743443B1B38375E91C254D8721F1AD2B02E9C566FAA294ED75BE16C0B0D82C1DCC8AB4A6C1D6E88B567C11A49AA055EEA87117A4C5B1C030F8ACD3AFC69D5FA8F082210E356A426C973A17492E8C3C64D87087A54589BF468071C0DAE016B6B51C52B628BEB986845B484FA213A27C6A1D505AE09D499FB92C17DF2AF010C71C1FA0FCD89A59EBCBDA4B7AFAB2CA68421AED1C464892C5ACFAA556DCC227929B6670904A01C5AB2AA0A5A246566C61A7BB9CA07630DD005CF8705B1B414CE8070A43D30CCB45572DEEB253E19ABCDE790A7F4BADD7863CB187FE8AAB9B0CC1C8309415F54AF4BA6BD6DC74C3AA13B0126254DA08F833C71810092E7332DD8CA4CC3199D4EB25405D310A3E9A6E65C8BFED0C6973A6F324CCC3EE16CC3E405D1C036086C5BE644A1A3709DB22A392EAC889CFCB6D9A03CCED44AB241AE735490EBE44A8B333C462891AFF72F2482C9B52B98106BB010A4CF03214330C5AEADB9B7314273D88880358A568DAA16DD8B496B6CA9C758B74F207B5001826391175EAA2DD9912E84B77EA257052065364949CE57365CC457854681729B389A7CC4782F7590EA6ABC49C40B4E23A2EF916F53240CA7BCA58370657490C52AC535E7CBA1CC58CAF52585DC148811264C2E6AA6728A254BBCC983D71716E82B7A53A2ABE376A5362E74F57BEB1979E2FA77998C869D6A799D0934D8475C8CB28AEBB3522387251D11352520C9A76697519B2DB6093CCC3A5A99D75E136C9A3D305F46F3176EC07FE4C30E25B21BDC2996DB413E0350AEE4A96125C5337AA70469F392942037674561D85969AC6664F6D92DD9B5108CDAC8A6E86E8BC1C1DF319AF330701E23AC743232680B3370B471CCD91761C110E309B5D77A48F4E06A681A2B38ACC3185946E7DB0D6EB1837D3199D83C676D667AD1CB51DC9982D3D36BCC121627D21AADF01928F32DF347CE495175F84641CC0704A24B7D099C416D3A56CC5CCD3ACA34F3F670B64C57AFD0591A628E4A19A83914C14212BB4D43AB1548CC772C25F38619692A5DD88730B093AFF5968B9AE60DC8AB8BE3D13F16928E4CD0CF604835F23B101BE7903876C8BB9970BC74A0E4752A67C4BE2F20C10BFB7765D863828565D190C5384273DED40E331168A4AC2A6CB8B0C5D600F5359BE70AB0B74C3C427857B34A9D2B7731DA6ABA7206253A67C22AAA10F7ACBFDB093BB7647B50D6AD449257AAA9CF29E5C5AA2982D6E0B67813BEF12B4E2A9669FB94394E34BD9583142456CA048763E0EABA7DDC48E3CB80736C6121F1888DB3CF85177942F322C3F029B427A6B8DB4976E1B80E9047BF91BDF2449F0B20C336E041B587182DD4A459C4800CA85308658E3BA78D66F47639AB1B70C45B43F70CF8197803BC1EC4A4424DD78C26039F4AC3C84F98A5AFB45A6970158E41296B925D33F68ECCD3B5A0B415F5B7CDE3473859DC48279255F9995561C205B244728DFC4F625316776267BD468BFBB287097911F8C2A32A0CBF14C3C708F9C4BF70C612C61FBA3720EC62918149165BBCA3CCD48CC8B272E538A1E818843B272DC694AD8E265E830034ACE5708CF22AE3D256745B50EC328CBF03760CA73E7E35241776864856BFD7C18577D411AAF99AD412CAACF44456228DE0176FA0E13CB925140F8A5BE9589F4B6B199F751B7A58751DB35680C78C69F83333155D80E08FA92A5B0FDAB909F9223D167333765D033213E3A65EB2B709BA200D861012D7145A9039C4A6B032D9D5802846441C379978EBA4B9970B275271292379B96717E48680FAE36DDC7018AFA8B3C1929AD62268F12AB87FEB92535A655158CE4957A1BE37C9922B4E08D57D85525D6F2B7698331FB3F1219D91A1272B7E92D3245E4649A8257BC362BA0E0462991A481A0A602809C46F4342ED40AD99FC74366406ACFCE7708AE11AA2C3436EE06121FE6CD52FACE80AA5FA2B65A0B1B28F8B28DE9213ED7BAA4999FD5812E87439CD569F1510F0536CB5A34D77C48FCD82BE86D8E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107" - }, - { - "tcId": 62, - "deferred": false, - "z": "ABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95", - "d": "0AA4E8D918201BB98464963B076E35337FF3265810723E01C435954DB18B14FF", - "ek": "0902C611CC1D7395142836692CAC578AA1AC7B12970599690FF9958A7048B7D276DE2088D0B06E5C3971190909C6F216287B2344E3922AF9A4BFC1CEB7E5AD35302E555A504B6B65F710356CC30DF957BD60E974FD31729EB63620E30154636FEBD84DA66BBE270151787B7A8B2BA3431491860C8837B5A93C35C62AE2BDBA43BB58D4126EE8139FFB5BFA110C4075C34F9AC648673EECCB59AF60CB8A6372B69C6E39D418AF88BC23161812486A5F2BB9B2D970B811C360329593CC31FA47BEC0FCA95C226E46A6BD5F39674458BD1683CA4673C39D158D9EE13E9736A6863229156BAE9340532D1A1BFBF98145930EE0A5229323468F7B5A9AE9755F6B603A4360CAEC054276BD3E5A4BF29C85F1DACA2C61A514C1449F94A63C4A3CCCA06D195945EDB3C0DAB07FBF75BFDE57A454C564B99C7DA3E5BA095A462C741E634B3D2DD9B7DF837E5FC076A0C363389C8248036EE55477F55BA27F17740E0AB891D0305E77A284ECA7F84CB3C5483FB3992610384E42A731DB8C3B65B6BBAFF04039D09A9BE4494637A9599CA7A4C42FCCA473D4E88B830A4D2358A324620F9B765A0141CB57DC1B70918053611B7AAA7D6D973C8D4C2CC135940C3CA9B7385823C8A86755717A63BD8EDC5712335786B21CA4106C3E6AB14381A87C6C6FB70635159077BE8369699823F54BCCEFEA3D3AD61613409B41C007947015364BCF42F184BF3BC8B03C6976749347EA7564076CAE9360F1CAA3BDF183889766FD428D13936B25EAA8156776C813705B79CF11030ABDE33B87FA4200544740598EA451AF9ED65CE3D0088F948AE07134BC2830253C9A680477C26180621BA679CB78F4E1304743A2AF124054499A21A9B510C78B2F875445B8AD58A559CF624DB8F8ABD1188812C122EAE81AB0F50435C77D72918E03DBAC7FC61DE848B4BC1729140602E738734B43CC62CB48B8131A2E257D82CB58F69AA6C4A348EA48277A0C8504D07323C61C42B68E5A212B01D66DB645BCBB6B34AF9B8AD7F709EB3720C1B79EF09352A078892787AE73D0B5DF546CC5F35D84940999D9CC59FB39C41762AD4AB260E6795F37372BEAC07005BF80F4A5620B4F23A2255D212746F4CFF73995E53C075C6790CAF4745A2AB8CAE2A89D94A601673023819166A709010C9D4A42CE9AA8C96381B1A7A236781C0C0F10C653F71353224242D3A8F0786A31703CD2063929393DAC152186C84253825481FC86BDFC70E3C5975D3A1DE8F23002126A05DB29FDD143A1F60222D7409B468138A8AAE2A34C1FFB6CEAA863CBC9666DBA1FE7138DE19AAED65256B15CBB08110E25FBC7209750C2CB225F6C5C97836AA04BA1B636BDE9235709483998E85BC1A28F713CA3935505E840A82284B879100389EC2D2A5778C990CCDE45B44D26A9AB74C28705807312681BD662F3E5437772CB7C383D72A53537404FB551CC87274294A85C8BB8484C8113E29708664190F923A387E81EBDAC3CE5890A2C440B9D93323E0588CE003606A5204B93288EB6B62F657C6E511059AC4B3DD57D402064B9C086DB955A7958C399F17AB353108E821A1C1084E11B20F2123C1CA6600AD330587988586C8F698BA258165FA3199A423548EED0B46535935C964BB4A0988B2346BD64BA7FA23D42FAAEF424901878012A772FC4815C26D54037F66F8BBC0E82C7753E16C40E1C17C2BC35F470251393B3B7E84534226DB0237DA2960CFDC99EEB4CA4AFEAA15B9271D9F74DF6CA5631935579AA5E189A715827220CE26BB1C07D719751560765E5A2296CB4BD9C44C4D6376E39A89AA8B70AF987AA0C3C10E714931059AFBC6B07B3523B1175AB9E0902BAAA56754A76C09C4CE232B5EED28F58F097BE3A0F5C290615DC7A4C4C328E413D8E43487E124F8C28444E70A7AE02B64D618D8831609CC939859BB100FC31513B90CE30B59061C38BD17DD57A6A2B0A3640E591524A06A6063259467D1F0821813411E62713A742C0ADE48FE3575338356F4CE99C1995667C34CD2582C0F9B7C4A3DA412C737253A3C3957929D5E4CFEFECAC09BB557231A11ED94F3C7A1BE5060313F540EE5576221386DA4C6A7CB71E307B395DB9C6D7DCB256C42D6F52908C565F06DB823463A634AC57299687641A556F5599F961B6E2F0A30053BE44150E1BEA7DC6D1A4488855127512CE9B2B1F4C07FFABDDF9E7FC37FB0A738DED0707", - "dk": "D4B51192A45D0D05BA48D20D7F8210DE386535D2A9204105AF184B50C81E89889DDF30942A9352C6723D2C94C31B709D452266772A8D69D2784C8332687507A1F678142C390737AD55C42CB7D37A28E9B9A18C374D220FC5A9560F655588439D69616620237225B543E6FB67ACE6B149BAA6AB5C45E334B65C87BFA368C581389B1246639B8550F9D94A61BC806850222869AB9041858DD30C16D0B62B53C85A345F26E3113F51C76F137FECACBB26C6AB1C3898E4AA73889039DD61CDEE46379812CB68BA0A03252199F102C661427088A89EB64D9E6CCE4E9929C19CB91BFA2A816340BE89A636339E67A124F659A45E6A061027533BA635854A0CAA45998E6BA21CC10E53A1A9BEB42DF0107F6765C7B9C8A8E98448CF2A6ACC6514765935064417C5E094B038123AF395B78746E4B66AB3E7BCEA783B4F4B5169478C78B82194961F80FC64AD314CD9D089C559815DD91533DC04B9359FD7936D7B8BB5BED435C77057316440926766F3A665F361BC9314230BAC46AEA6AC7EF648C9901DF017BBDE558668A606809CC717C49EFCE5B9F469BE1A0A9853451B130A952C137F6812978270A194C5CFD899CE2E656FE9CBBE8C3C769C700218489DAC47A07CDAA36EF22EE7125EC5223FD959C335B70C56AB8D52333B4C6A1C12DB76A4C02F7E7410CB646E75A5301F19A080561FDE627C9E42B275FBA0800715B1D77643A8193EFB61DDE898305B4B53140A76CC851FB956FE766C8450100A1C9EC0044C32BC17948C3D4CF44C70077447147BCA735EC9F2251A423F96D694F0F01ED4813713545A791282F7086B025BC4B133B86EB4856A3C99F21129AEC57175818360D678FD549ED769365E4720B3A4A433217DBEBA261C48B75C26828199904820C8FC80098DA6A0A9463B24FA5F43A445F33B38985637AA30CE6FC83D7127BFF9DA633E25A362323564D25622064AF20C16D90620AA0875D65217A389438D236EC8F2C18AE3BFC95296CB951A604B9FC15C69A5927F86D98582C3169BD16C7EE1403BCA5BB1C2238B93B5B0F4C6E3969D98325444A09DE2636DA4A046367358CBA66B28531616733FD816B32BB714CAD1B10DF570062223F6366424BB0388DC1A6CC9AD72CCAD22EC51C671BB859C4A3BCAC9525342B6EC97DB62ADE9949339DA5338D07EE433A868060570E087C34B8BF62ACF15F05657869556CC00713CAA9E5C2AF40474F472B3E117B9F8DC4D148183952A0553F49EEF609F3CF12DB7B102855677A443BD8C94429C9168BDC06CA0FB3781E450DAE94A96E4239DF01A74FB3C016B4AA3463AF3E18D8EC653E838249937B50DB57ADA1CC1215972B410AE459BA481836215E12655534A6F183ACE939DEE553435E9BDD00B4273F0A99CD42607E903E85864F0D27CB4A26474265E2E7A56A576971D69C657D237C05CA7C8070F0FE3A8A1AB8549866D32A253F7B4AEBE6521E557131D361999C5CD6B9837299A2100A52450C9AF85890833A9AC8A3B1B1C0B90839295BA6997BDF262AA93196AEA9F9EB1485E8415FF7006CAEC9A0548AFCF6816938A5E77D5A383F6B3C140786A3626207218883597BC3670903364BD275AE420BAE20522D5E69F9D292E7C5A6A3F3134F767004D052E1476B2A95B790B295AE6F68689828F69EC7965F495E7667E7B420EA2E5C738964FC0257E9D423B98C409E9A27B41E0B87A396EC079338019AE8DEC20DFE0477E940B6233C7D6244A201A0DA4B45AE785158C545AE6B28B49F799E030C762F0BAC8987E12F079D28C4BF7074BED316AB4580D21A8CEF4C30D637275FA2C6884E61B6843C4BC696E8615C47D573FF20BA1053C4259076153BB9314E6CA62F1AF91F594ABD444BBD2B3B203A075083AE8036109710F2B169A688CBCF6D563FAE94D3DF65BFA92B1D20546B5A3A0FF6B3FAB634712566B0E021D617232C8029EB2F76DF624C8DC77AB3789739AB12AE3AB59A7B612A40970D5526023F690C8F1A9BEB4A49F066AA8073E1F865DF9313A63464C65510E078B61320A34E3624E2A6A3E16B7BC3FD995436C92C28B18B149C26754C0DFBA3121778D8E345E6FA4CE8F104F71B77FFE64C0AD945F1F227A031522D07990F88BA91FECB244B5936E87298FDC1836E82C0CB178175CAC5A36C27D3B71EFF5ACAA39200902C611CC1D7395142836692CAC578AA1AC7B12970599690FF9958A7048B7D276DE2088D0B06E5C3971190909C6F216287B2344E3922AF9A4BFC1CEB7E5AD35302E555A504B6B65F710356CC30DF957BD60E974FD31729EB63620E30154636FEBD84DA66BBE270151787B7A8B2BA3431491860C8837B5A93C35C62AE2BDBA43BB58D4126EE8139FFB5BFA110C4075C34F9AC648673EECCB59AF60CB8A6372B69C6E39D418AF88BC23161812486A5F2BB9B2D970B811C360329593CC31FA47BEC0FCA95C226E46A6BD5F39674458BD1683CA4673C39D158D9EE13E9736A6863229156BAE9340532D1A1BFBF98145930EE0A5229323468F7B5A9AE9755F6B603A4360CAEC054276BD3E5A4BF29C85F1DACA2C61A514C1449F94A63C4A3CCCA06D195945EDB3C0DAB07FBF75BFDE57A454C564B99C7DA3E5BA095A462C741E634B3D2DD9B7DF837E5FC076A0C363389C8248036EE55477F55BA27F17740E0AB891D0305E77A284ECA7F84CB3C5483FB3992610384E42A731DB8C3B65B6BBAFF04039D09A9BE4494637A9599CA7A4C42FCCA473D4E88B830A4D2358A324620F9B765A0141CB57DC1B70918053611B7AAA7D6D973C8D4C2CC135940C3CA9B7385823C8A86755717A63BD8EDC5712335786B21CA4106C3E6AB14381A87C6C6FB70635159077BE8369699823F54BCCEFEA3D3AD61613409B41C007947015364BCF42F184BF3BC8B03C6976749347EA7564076CAE9360F1CAA3BDF183889766FD428D13936B25EAA8156776C813705B79CF11030ABDE33B87FA4200544740598EA451AF9ED65CE3D0088F948AE07134BC2830253C9A680477C26180621BA679CB78F4E1304743A2AF124054499A21A9B510C78B2F875445B8AD58A559CF624DB8F8ABD1188812C122EAE81AB0F50435C77D72918E03DBAC7FC61DE848B4BC1729140602E738734B43CC62CB48B8131A2E257D82CB58F69AA6C4A348EA48277A0C8504D07323C61C42B68E5A212B01D66DB645BCBB6B34AF9B8AD7F709EB3720C1B79EF09352A078892787AE73D0B5DF546CC5F35D84940999D9CC59FB39C41762AD4AB260E6795F37372BEAC07005BF80F4A5620B4F23A2255D212746F4CFF73995E53C075C6790CAF4745A2AB8CAE2A89D94A601673023819166A709010C9D4A42CE9AA8C96381B1A7A236781C0C0F10C653F71353224242D3A8F0786A31703CD2063929393DAC152186C84253825481FC86BDFC70E3C5975D3A1DE8F23002126A05DB29FDD143A1F60222D7409B468138A8AAE2A34C1FFB6CEAA863CBC9666DBA1FE7138DE19AAED65256B15CBB08110E25FBC7209750C2CB225F6C5C97836AA04BA1B636BDE9235709483998E85BC1A28F713CA3935505E840A82284B879100389EC2D2A5778C990CCDE45B44D26A9AB74C28705807312681BD662F3E5437772CB7C383D72A53537404FB551CC87274294A85C8BB8484C8113E29708664190F923A387E81EBDAC3CE5890A2C440B9D93323E0588CE003606A5204B93288EB6B62F657C6E511059AC4B3DD57D402064B9C086DB955A7958C399F17AB353108E821A1C1084E11B20F2123C1CA6600AD330587988586C8F698BA258165FA3199A423548EED0B46535935C964BB4A0988B2346BD64BA7FA23D42FAAEF424901878012A772FC4815C26D54037F66F8BBC0E82C7753E16C40E1C17C2BC35F470251393B3B7E84534226DB0237DA2960CFDC99EEB4CA4AFEAA15B9271D9F74DF6CA5631935579AA5E189A715827220CE26BB1C07D719751560765E5A2296CB4BD9C44C4D6376E39A89AA8B70AF987AA0C3C10E714931059AFBC6B07B3523B1175AB9E0902BAAA56754A76C09C4CE232B5EED28F58F097BE3A0F5C290615DC7A4C4C328E413D8E43487E124F8C28444E70A7AE02B64D618D8831609CC939859BB100FC31513B90CE30B59061C38BD17DD57A6A2B0A3640E591524A06A6063259467D1F0821813411E62713A742C0ADE48FE3575338356F4CE99C1995667C34CD2582C0F9B7C4A3DA412C737253A3C3957929D5E4CFEFECAC09BB557231A11ED94F3C7A1BE5060313F540EE5576221386DA4C6A7CB71E307B395DB9C6D7DCB256C42D6F52908C565F06DB823463A634AC57299687641A556F5599F961B6E2F0A30053BE44150E1BEA7DC6D1A4488855127512CE9B2B1F4C07FFABDDF9E7FC37FB0A738DED0707C266F50028D4382821B206CE45306AC320BAE56F49DFDD86F37E1B36C23DC86DABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95" - }, - { - "tcId": 63, - "deferred": false, - "z": "177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9", - "d": "F43EC0E96A791317938761FFBE97332D5D85F52D22BDA6303FE7E7107DB608A6", - "ek": "F4C227FF124D62F0269297261583A7D7EB570E6A52C8B9240D1B1A79946FF3990DDD20AD71284E7B004656270DFBA0681DD2C5C41939D6391F4AAABA0ED3C6AC55B4907534DE05B775CC6284D53D045BB611F5BC62F603327C143E100B6678176A40A4949A923CA651F1D2589896BA74E41722B3A0C1C652BCC7ACA769119332A080211CCA8AACD4799513BB0906A063F2AC750C99A805B792699400F609960D177BC006227BA40CF1C547BD81C9F5D67947B6A7BFABA98415C81A4137CD2CBF024322633A8B1B242594581ED8720A794293FDB282EBA064DF25301FEABBBD14BA4FB8970B52B4E3574BC57218AEBC5FB9E731F5A85CFD1154B42575A0B3BEE2FC97CB691AE9F4361F11692D9CB07D793A3C6588ADF24FE098B0CEA860E0173C35223C678A10CD3752E97766B28BA562D1CB93935E97E73B6DFC3248217E44FB08684B5419D749D9350F143CC66E9921FA6C4180D43A721424C06864EA98CD3E60C12020AE7123ADBC2CCF40577BA4F87E10B755A1567941F98E0D0A0D26A9303383026D021F2284CE313AAC3C0A765D11747EEA8BC2832EC87B22EF31AD0D1409FC66A782B2B09AC43EBFE215862B6462996A3703525281BA8328621E436DBD533AEA69B62B429F83A78843051AA0D003C6F8BA224148E15A5AB39A6EAD69262627C7B0C46730C66D2109512D424849A53CE58B9FF463B87945CF9E253130A64CB1F18A2ED875D43026BB8AA2B87ACB00186889C082391C95273BB864E548ADD29A876B3445A471B685C659E213853C62E1A802E2B3C4C392575620597C7131F2764AE68B95AE190927E110A10A553E008F39054DE62C16912064F0B7711EF59E85E50E30395A36A11EAED23CB48A01C8F67729F6B638E3B6820A0E530ABDE31A97E7DB117B035897952F0A0473AAE5897A86725C53855AA43A16BB31BE7C564FDBA0BDDB44D6E64E7959C871728C7C5111D989CFB9026902B82544B528D4FA8BE3196C6318CA1BB791B7069EF2D225277C60B03C48C183484250B4FB0A5B05E260E8A9C958CA51F9BC69DA7ACEB006569B427D2A60C070D81C410114E753BF85651E3504418E747B8D787F0237B184834FF8689519034FF6956313120A0495267B754BA5015D8A134688B11160A2CDE5E8B18D4400AB95AC6CFBCF5CE72020C60761128CBCD5BD36817360663F83A7A263B9420A654C7280381092B4D295B3DAC03E918926B5C29BEB0478A01A39A8B0CCCEC05125D84D2872CAFC97A8627866DC7380DE17709FAC24EA1A0E00DAB5990A919E0262DA522CCAF9B0D3F11268D0A2B2BC4D85E641F64048A3557887A266A8DB13EB555608960E49618B1E39708B65151C4BB8D2154CE7B6A13F86B75367B005C9A69DA98B82ABB17EF9678EB50F3F097A6292930191A15FE075BC304D49926B3D71B675C26869B6BB93264F74702E17102DB5BCC881751120CB8D3E05215E4B34A505529BAB1A2A259B7BC7999404BD15272E44B9AA4BDC891E01A21B8A71B46725DD187E2041C07092CFDDC902D3DBAFC29379691644D0E15A8F7378298A8834D1C1B078384C140F460B144826188F51852AE0ACBAA1ADC4D86147C02F61C1B154193B2627C609682A6E656725774A2FC60DE52A3837537C421A58312A7E6BD1CB7B7661FDB3C1D9C51C3A6A44F260982BDCC01FA149697B24B00B76C5DA2908181E8CE21A28D9142F12659023536F392AB3781C74569DBA10506CB79BA214C49CD18A1D9A693734791FDB76360A142B71252B9020099B389AEA8A25796CA43BB5FA881277D742B6C7CC4651CDF47B91C73B7CC816B16F040DCEEBB3E27C68F0388ABE1A4B2B8B88820B30C9D03C1ED75A9E46774B9612C6C039C1F0404F40CAB35369BCAA80FA2C53975C63F75211B1154F94C3AEE4DBB3EEE500091BA629900A54245CBB4C92296769D979530371A0EEC19DC6718AFACCA91D219E37788802B5C162237A7274C3BE821BC969493E884DF2E915ADC3AD6F1919218C844AF94C983ACA8038CC3874C0C080161D5B4F1266420881C906C145ED15692E8C24F2574F80EB3265157EF3E63BDA96390AC160CEE8B6A79B363C290B4B35AEF49CA4DFFAC0F0423249F27A6CF77558F0631581B36E58AD1DB09F4781B8F813B0ED6578FFBA5A73FABA29D94B6F9238A9089CF41BEE300083ABC96CF379FBD0190841D981FE9CFAD1C7FAF23D2426AE", - "dk": "95937E82B41B65D97063375BF2516320419CE2DA063E41B62E50AAB029407A98044163C56670C75B368D6771AB590A40177073DF486D083C62C5698BC02B97DA59CFEDE6305E3ACC6DCA183093622EE80177BC507DCB8C5780A398FAB838A7CBB7126883A006A848B743FB7D0FD4CE1E4CA026FACC5F981AFDF0AD72FACFA69904BAA9944335B14B9521B492876FE30D07F81BDD7162AFD5A4BAB76E13901CCCA7700C45B385C11F23951DA37740FF58818CEC668992C46B5A478AD221A3EC989F77A5D9B1095F2A7AA0849A731AAD51A6B51B0CBEED2A8531B9A3D3C39E55597E1076AE4B4146740A8A16051A9EFC5C4E016695BA97A26AAE6D850590773D00449CA68A4E65D0463EC15DD46813A7810051203ACC7A42814A7121AA6B45EC9E37DC2F40AB96A1C025835CA7C8198F292390E3D5C9967865F2108DD17402DA657175C65AC47842E1473F9BD29DDE44388695109453B823E204A05A9B3AD6A398B69185028460F8230E3241E4012659E05AAA9CAAB8D8079C65919C8304EB6AA78330BDDBCCA763B91729F81B05BAC53BD31332FABC69D4CDB85CC0DF0B47961731D26A2FC1649A5B53A05CD13109479A75B48F67898C63713EC7883BC3744C9A60C23AF5320C645DE8C242C0B17EB97974CCF76D57180E40330663F9BC737A40C2202F47B22580F5CA070C4488B1B139D0155B1006A7B31A79F0BAB9239B9E4B7DBACB534790ABD0F28141D43CA52792503B4C0CE96B0F505A4E263D1E9429F631447719B8580C902385B221FA2C174866E8872D1B299706B860343BC9AAE6660B77C7E2BA5C8C1CAE4A054A60038743655378080044EC7D45D36411768595BC1D30A43AE3805BD77211E1EAB4C97C9A4F6408FC48551D880B4728388F55519757B9B258781AD2915D40C9DA27961145AABC1666253171A62425C8BA9667322C7C9599104C034C1168A50A47A44A7BD078B24726561488661CF70FB2B7242BC354DEEA94324622B55607F06221A65255C2924982964A2FAC5BBA75CAD6B4677DA45F96DB2F91FA7517AB968A66AF8800AD431423F03936F3614D3ED7236C8A32F16B4DED28285CD46A5AC06A42397A2CDAB0FFE1A70208A226233A84B4AA6B0CC8BC1A4913B44322FACAA7917D119556412880286405EB6C9A7E75CE74C75EDF794A067747AA0B31E99C1F68C25696207C90B97CB57C5088982129811E08773249C5898FD4B86D79BCA5A02C1D389530EBB1AA2ACA1DF1A60FE19649F7026B9229B39A60F29982EAA639D9830074CAC4C375295719C4FCD03A36D99DC6306DFF96A4AA1B0110D37A1E716DDCFB0A322134A978C1D0998CD5A8943B267E2B6B0D6936111BF630B0CC89A549405CB295038ACBF22B6E15788CC8966060EC4BD71255511826CF163A6C45AE24FA8536C39F8C19C7856A3700972FDB959AAD019C04269C97D7CA55121A567BBA5711A7F7E28A13F955DD06988AE2BFF90C4C3C605E0B200DCBF139E576BC367C1D151A8F7297B5C76CB826208EDCA1CB23183397A37A92B233F65494E6E3644A364EB8F05FD93248DABAB286991297EA1A87B947A8C0C1E32A9B336B44E5D045E4418C8BD366DF77C2AD90CA2D690C516B032060C32314CB7DDA818E80456E588248609E4E4BAEC2B30FC1E8A984082C23555093D375FF129CDE4498BFD4A40AD1678AE78C5647B6998212CB0010241703A781727FD755B5907B12350A853440B9019F7BC3738A1A2BB291A549A9892D74BD2FC4B13BBA718F9877BDBA32B7D07F0DF33BC0C19AB3C2B567D7110BD3592274723F5A69AFA632FE8C41AE7CADAA115E61B897C4444FA7099AEF0290A6A13E8D551A3DF565490A825DEB6D808AA7AF377B27355324C355C32358955B883F6BBD42C66801CC443BF34F2FA040FCE4B7237C4ECEAACA821AA8B248841D242B6EA5561B070E06F711528109693AA289740F97A4169758151ED57A15381EE35297016B0699C34F9AE039ABA26ABB11148BB4344359CF14466841C7CEE7B3541B6072BF021E3B8348E078510DE0839EC55C38290F5C5095B429AF7BC970CE46110F54967C42A2AF4A3CD5BAAA5BBB500EA382E9427FE02595B0E6811FE32E932BA6B479114F5B7224F98EFDE80CDDE06BC580B30A5175B9B38958393B3BF0573A7086EDD0A1F4C227FF124D62F0269297261583A7D7EB570E6A52C8B9240D1B1A79946FF3990DDD20AD71284E7B004656270DFBA0681DD2C5C41939D6391F4AAABA0ED3C6AC55B4907534DE05B775CC6284D53D045BB611F5BC62F603327C143E100B6678176A40A4949A923CA651F1D2589896BA74E41722B3A0C1C652BCC7ACA769119332A080211CCA8AACD4799513BB0906A063F2AC750C99A805B792699400F609960D177BC006227BA40CF1C547BD81C9F5D67947B6A7BFABA98415C81A4137CD2CBF024322633A8B1B242594581ED8720A794293FDB282EBA064DF25301FEABBBD14BA4FB8970B52B4E3574BC57218AEBC5FB9E731F5A85CFD1154B42575A0B3BEE2FC97CB691AE9F4361F11692D9CB07D793A3C6588ADF24FE098B0CEA860E0173C35223C678A10CD3752E97766B28BA562D1CB93935E97E73B6DFC3248217E44FB08684B5419D749D9350F143CC66E9921FA6C4180D43A721424C06864EA98CD3E60C12020AE7123ADBC2CCF40577BA4F87E10B755A1567941F98E0D0A0D26A9303383026D021F2284CE313AAC3C0A765D11747EEA8BC2832EC87B22EF31AD0D1409FC66A782B2B09AC43EBFE215862B6462996A3703525281BA8328621E436DBD533AEA69B62B429F83A78843051AA0D003C6F8BA224148E15A5AB39A6EAD69262627C7B0C46730C66D2109512D424849A53CE58B9FF463B87945CF9E253130A64CB1F18A2ED875D43026BB8AA2B87ACB00186889C082391C95273BB864E548ADD29A876B3445A471B685C659E213853C62E1A802E2B3C4C392575620597C7131F2764AE68B95AE190927E110A10A553E008F39054DE62C16912064F0B7711EF59E85E50E30395A36A11EAED23CB48A01C8F67729F6B638E3B6820A0E530ABDE31A97E7DB117B035897952F0A0473AAE5897A86725C53855AA43A16BB31BE7C564FDBA0BDDB44D6E64E7959C871728C7C5111D989CFB9026902B82544B528D4FA8BE3196C6318CA1BB791B7069EF2D225277C60B03C48C183484250B4FB0A5B05E260E8A9C958CA51F9BC69DA7ACEB006569B427D2A60C070D81C410114E753BF85651E3504418E747B8D787F0237B184834FF8689519034FF6956313120A0495267B754BA5015D8A134688B11160A2CDE5E8B18D4400AB95AC6CFBCF5CE72020C60761128CBCD5BD36817360663F83A7A263B9420A654C7280381092B4D295B3DAC03E918926B5C29BEB0478A01A39A8B0CCCEC05125D84D2872CAFC97A8627866DC7380DE17709FAC24EA1A0E00DAB5990A919E0262DA522CCAF9B0D3F11268D0A2B2BC4D85E641F64048A3557887A266A8DB13EB555608960E49618B1E39708B65151C4BB8D2154CE7B6A13F86B75367B005C9A69DA98B82ABB17EF9678EB50F3F097A6292930191A15FE075BC304D49926B3D71B675C26869B6BB93264F74702E17102DB5BCC881751120CB8D3E05215E4B34A505529BAB1A2A259B7BC7999404BD15272E44B9AA4BDC891E01A21B8A71B46725DD187E2041C07092CFDDC902D3DBAFC29379691644D0E15A8F7378298A8834D1C1B078384C140F460B144826188F51852AE0ACBAA1ADC4D86147C02F61C1B154193B2627C609682A6E656725774A2FC60DE52A3837537C421A58312A7E6BD1CB7B7661FDB3C1D9C51C3A6A44F260982BDCC01FA149697B24B00B76C5DA2908181E8CE21A28D9142F12659023536F392AB3781C74569DBA10506CB79BA214C49CD18A1D9A693734791FDB76360A142B71252B9020099B389AEA8A25796CA43BB5FA881277D742B6C7CC4651CDF47B91C73B7CC816B16F040DCEEBB3E27C68F0388ABE1A4B2B8B88820B30C9D03C1ED75A9E46774B9612C6C039C1F0404F40CAB35369BCAA80FA2C53975C63F75211B1154F94C3AEE4DBB3EEE500091BA629900A54245CBB4C92296769D979530371A0EEC19DC6718AFACCA91D219E37788802B5C162237A7274C3BE821BC969493E884DF2E915ADC3AD6F1919218C844AF94C983ACA8038CC3874C0C080161D5B4F1266420881C906C145ED15692E8C24F2574F80EB3265157EF3E63BDA96390AC160CEE8B6A79B363C290B4B35AEF49CA4DFFAC0F0423249F27A6CF77558F0631581B36E58AD1DB09F4781B8F813B0ED6578FFBA5A73FABA29D94B6F9238A9089CF41BEE300083ABC96CF379FBD0190841D981FE9CFAD1C7FAF23D2426AE2A959860220DFD26FEE86E0F4EB1D8E31B240EFFB9EF6091AA0BCF551A09B2B9177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9" - }, - { - "tcId": 64, - "deferred": false, - "z": "79E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95", - "d": "0596F1E214B29A0CB7A641EA0BB157FE01FAB73B4A9BCDC165FA44C8FD5FBF71", - "ek": "BF2A86AD3020C241CE4A00913BDB13F82266DD873742A3519E44C39F20874575A780370BDBC32F50F892366C3D3E5A3CBD2A1A9EDAC8D5468A4FD28D18281C4ADB485B033E76B3B604A5394EB6A280F81C93B86839C2198430558889696CA715CA0B901D762A498875DE991479A45725E12340953D95461ED32AA018E33BBA0157F3A6BD1BF07FBE2207D81166F5410AC20096E95B6F48E09190ACB51A86AD4C51AD1733729272BE79BCB14834A230F00C64E0416AF77C2F155776D6528BD0C9762B60350430A3BCC51DEA9966D791A3904A1F6284A32B4C865CC67C1B66A7F00BA3C9971AD846DF61348D2C418DE0901ED19D32582ACA784AC96A55AAE69D27B58973B4816714B2139C2DF5A380739C43CDF0A161AB8535F678FE344C5E4881BAB8785805C615711ADEA09B702201360B2479CC7FBA69868903CED7074D7F93AA7772B3359644B0A3A169A59C177CC60E8B4360978FC7C513A95C355643563BA0371D973F7A991AD099BF94239815C7041A312CC3497E9A40A5D3F9504BE107FDEA73D8769025D75479575F5A45974FAC400F0189076457A2A96D9BC2C1B19C5382C423B3333F0C9B7E26FCA8F2DB01265460A4C253EAC707B39109AF07241DD6A8FC5A9D18494C3D715424108114280F3A5C23CEF53C5507BDF3BA5EDA6327AC15B484793011241305462DADE02D4459419909075C09BA1044B896A28E17866FEBCC0A4970B1734C4EFA42780C380EAAB17C82B96D72CBAA83127FFCD7998071BDF8EC59881AC74177C1E194A20BF5A4DD71C4E03A82D6E40B70986D2A368C53C54BD7B0CCE1B5A161140E01047443497EFB4C4D3FE126686BA354B504B9537C27B21B56355BC0A91F82E94853801801AA5FD8287EB5A1BAEA773EDF16B376311DB6089AF1950A385037DEABA09ECC491F4882CD484604F304730C11EB3C561F36B85D1B1ECAE15FA1326F9EA486CE32978E9C267C70AA33E0113F4C3B618B405A160B4C93BF943C806FB41C62F83200B81AB2CC57CEE96364D86D4630BCA5A70064151545EA9D9A419E41242B6135AF3A516C8DA4447AB71478266E5BF69F2B846075C30F3368B30912BE48A00CA3365BBAE0597A93942396515A72B675C460BF4403872995AF19CC25C737F86B642ED740C9E5477C0154D05860A30C2DD49B14E8DA87600C4E8CA63401DA998D7689D9CB364397C4DD056474C2BEE16060D4408A3E19BF6FF8A331466209F0B428F0316CA89188B9C7B2AC25A7940DB7A1766799361BA984A1BB7E789B2438D6777F92A15CE7A2D156369AB819B116CD99076095C70D265651550BCC1F4307497BB77E75023AF91D31F4414B38CB64CB570AFB56701C17CB692A46A444455C8063A3616590AF6064BC337237ED1824CCD7CFB96B55FFF91D7D4714CBBA74DEE5AB48A28389458E2D43476CEA2B1A0B6EC499A83CEB8EB4C7539BD93D3AC987AD07A1C9F079850C1444D0B5C9CC619614301CD77776661357FA80F29A3CE4A8AF8DF55FB259B754504687508AC12AA81DB8CD19C93875AC5C4CF13E115221EBA49F3BE008D4B80E9EBB8AE0CA997313872010497CF9556DF06D8F766D2025B03099BAC8202C5D90B52C5397CF55BFACEB5A1C079CC02960FB976A735357DF16B90210194627A5089B1D29CA4FE8A03B4FFBB544A645C5FA95EB386408DC65AAD89CDF0285F3745EDA596D070356D350775FA7A088D732A61C1AC57306359B4A642B8AA8BB91A347152A916D33427DAB37143AE14B2D804B0FC033EE2B9D996853ACD202B2689AD945CDA48938BCDB2D8DBA5449C80891B103172381200A68BB7B505EC5A373E15DF301BB7547770A5B21A571CF4CE87B1AF38D3D38329BE9AD366159FF1919DB40233E86BB497652379B9099F68B22EA91552273AB1801CE6BA9FE7B07ACE9A81DBB09B11CC4AECA25B5090C6FD885B7E19941D8561A15CC35046EC191157C393168C80311432C899B0A0AA578460963E7767750560064B93AB148AEF2FC2FBB029C89126535C6BF2DC48A04748D23A6225EE6C3EEA9B68C65BCA2E9C804EA5BDC441BD05293B8C19D96E369B5C3459DABCB20565405824EC3F57475AA4E19DA21A8EAC0DD312E9FC10B56D6C6EF40A130844D8FD68769E2CC08288D770CD00556578D853FE4896886536AF0633EFF38C1439E3E7950091189960045B3B3B18BD45BE846AA63E4D3845BA0", - "dk": "C62AA41327AC132035DF838111878AE1BC660EB53459381290580906A45376761BEDA32D498611D642173E7CA019DA1AF1E60EE43601F1262D3B396FB5611FDEC023C891407AF4A8ADF85D4C010F7DE70829138F0F520EFFB4C8D5230253CA72A6FA3D4C4158A65C12FB9A36BA440A40B476D8C65CED2968BB18A11751993B725920399933F3B18DFA9A4ED87A7AB277DC027CC33A83E43B9DB68C8F68D72FEE7210E9E1471869B347C79B848C623834C586B341B23203D2CB1AE5E9CFB87A1794D43598EB0CC8836BDD42371AC9B7D0513F4A7840C0371D73BA88A7DBC5A5753020298E3D616A8DB46C81C80045A553984939D7593535D6BF2A330BE54A3D1CC0B09774279F952A59F673298C6B1C078E0FC87038D03304E0C4585577A6842815D9C9F41534F216B5B0474F1574BE15051F3DD69CE3E9870AB13FAAD180C82A1ADC2927A1D20EEA168A97DA7ABCFB617B7570009AC7D212B6D05483B7F54F7C201588A879235823038834685BA5C7649CA7931D3D2B155A3410A76900E4738A24A614AAF119D8AB6111E383BA33A4614823063C31EDB9B031953AF6FACFD3D65ED1557EC879B89F3709D177A8818094B35500A10B30E10C7917956A0181BD6B0817F0D85347430EE6724B5380BEF508AB3B468AB6C8868FC48A62F3445104A41C8C288DDC5746C84301E5315C603F80E9B83F6C16920142611CC32B18BD7AFC28D3D343AAEB8AE7133F88E388AE6C7C4911318A3957904AA51E2905D5A02C30CB57DA0551B4134182C060DBE80BAAC4981B410D1D5104D92BB47D3BB6846937CF6B961FE66BDB5C069A0304D91AA22D8898F8067295DA9BD6DC3408F3636DE5CC6948C9DB2B17DD4651F1419668AABEF031CD06FC63BB9749C4DAB8A160B5A4C6A13F3A4F8941712EFA60E5B426E1BB29F65940368594B681CD30D41377F58254964FF0AA4D3A5B553327762036757429CD47D57DD73698BA0C765B3C539CE41A04A58775E70D4EF38D2B9775D203982479937E5135FF1B944F6CAA0E87269E52B52DDC3958C99C668170879B7FD03427C4F38E147B6ADEA1BF0123B01CBB199644AAEA95B76DA7C5E60839C3EC0D50C4A01E79810BBC1220F612FE34A89B173C7E6042BD876D0EDC2D9A03559027AE0844492B539F2843A2A49C6E969C121CC64E4CDBC624167C22911A27656109643F695334F3C73694758F06E94CBC15385F181EA1B012D93C5AF375034514074C92401A455BC21C8B97AB7D8CA64B58C415B53AB4D322CF28F69882A4C0F5BC060AB09AD643311F29398205753D623EA424C7F2D38CF0E1074F1CB5A9E91B19D91A637A83E15B3DF5B7C7987A4D5FC151E9012021F00CA8E31069F9451E4B6E5D7331E85980077367990AA632009EDBE0432722A825829074953E6BB752C7D86490D7C760E7177F54806CDAC557C70C3DA151B9F30877B22FF8742BE8077C7C82A212BA077C148D90E86D5AFA15AE30362CB287D3BC318CC28FF74AA74536A73009C00E9B8A7F8AC11BEB5CB6CC965D672141DB7784B8BAFA395996FA4DF8C5C014C8B73C3302AA6542950A163AAC35D7C222B1A2CF5C9A820D682B6E98242B28B8B9D32E973B823027211784415BF27E2A0C60125295BC35007E21A3CDB4BEB6E26FF26069DC1BB675032FFFF93924870F0616BCF6679353200152369881182937565B3BF4711882C9823B800EA93CF7889B14F521C5A34C81A6354B70CF02D0C195853846505DC2E82B3F3651815480CB739AA49C55E0B763C9982C69D0669DCC76A3D262C304843FD322E973159EA358E5811D4C324914BB89DC7BB1BA61C4C2E9C25B0886B6F5ABEB827992B6798250975BE205B6252CE3DC5DC2E00D4CB427FB9338D6A19166C2978EEC81A645714765095E89799082AB42D08FD2305159B42C80B13F44AA9FEB46B8F3A5552BA534B9F26A2E5B2C00822CFA573106555C9E8C5B1475A38E4782675B9A6FFA294A7B0A2FB26AA8387C46C20363B2BE83E9AF100211B02701CC0A10220134DF6230874A83C49CA846E1106591AC21B82BB587583C33BC97BC62C53C316AA58C525750225C795424B780EA39E9E79588AA9556B2AB9BE98057046EEEC406FB4A81ED364964C1559EFA623307A891A9B7F06433681B2D5F583257E2968786A77CB6C9BF2A86AD3020C241CE4A00913BDB13F82266DD873742A3519E44C39F20874575A780370BDBC32F50F892366C3D3E5A3CBD2A1A9EDAC8D5468A4FD28D18281C4ADB485B033E76B3B604A5394EB6A280F81C93B86839C2198430558889696CA715CA0B901D762A498875DE991479A45725E12340953D95461ED32AA018E33BBA0157F3A6BD1BF07FBE2207D81166F5410AC20096E95B6F48E09190ACB51A86AD4C51AD1733729272BE79BCB14834A230F00C64E0416AF77C2F155776D6528BD0C9762B60350430A3BCC51DEA9966D791A3904A1F6284A32B4C865CC67C1B66A7F00BA3C9971AD846DF61348D2C418DE0901ED19D32582ACA784AC96A55AAE69D27B58973B4816714B2139C2DF5A380739C43CDF0A161AB8535F678FE344C5E4881BAB8785805C615711ADEA09B702201360B2479CC7FBA69868903CED7074D7F93AA7772B3359644B0A3A169A59C177CC60E8B4360978FC7C513A95C355643563BA0371D973F7A991AD099BF94239815C7041A312CC3497E9A40A5D3F9504BE107FDEA73D8769025D75479575F5A45974FAC400F0189076457A2A96D9BC2C1B19C5382C423B3333F0C9B7E26FCA8F2DB01265460A4C253EAC707B39109AF07241DD6A8FC5A9D18494C3D715424108114280F3A5C23CEF53C5507BDF3BA5EDA6327AC15B484793011241305462DADE02D4459419909075C09BA1044B896A28E17866FEBCC0A4970B1734C4EFA42780C380EAAB17C82B96D72CBAA83127FFCD7998071BDF8EC59881AC74177C1E194A20BF5A4DD71C4E03A82D6E40B70986D2A368C53C54BD7B0CCE1B5A161140E01047443497EFB4C4D3FE126686BA354B504B9537C27B21B56355BC0A91F82E94853801801AA5FD8287EB5A1BAEA773EDF16B376311DB6089AF1950A385037DEABA09ECC491F4882CD484604F304730C11EB3C561F36B85D1B1ECAE15FA1326F9EA486CE32978E9C267C70AA33E0113F4C3B618B405A160B4C93BF943C806FB41C62F83200B81AB2CC57CEE96364D86D4630BCA5A70064151545EA9D9A419E41242B6135AF3A516C8DA4447AB71478266E5BF69F2B846075C30F3368B30912BE48A00CA3365BBAE0597A93942396515A72B675C460BF4403872995AF19CC25C737F86B642ED740C9E5477C0154D05860A30C2DD49B14E8DA87600C4E8CA63401DA998D7689D9CB364397C4DD056474C2BEE16060D4408A3E19BF6FF8A331466209F0B428F0316CA89188B9C7B2AC25A7940DB7A1766799361BA984A1BB7E789B2438D6777F92A15CE7A2D156369AB819B116CD99076095C70D265651550BCC1F4307497BB77E75023AF91D31F4414B38CB64CB570AFB56701C17CB692A46A444455C8063A3616590AF6064BC337237ED1824CCD7CFB96B55FFF91D7D4714CBBA74DEE5AB48A28389458E2D43476CEA2B1A0B6EC499A83CEB8EB4C7539BD93D3AC987AD07A1C9F079850C1444D0B5C9CC619614301CD77776661357FA80F29A3CE4A8AF8DF55FB259B754504687508AC12AA81DB8CD19C93875AC5C4CF13E115221EBA49F3BE008D4B80E9EBB8AE0CA997313872010497CF9556DF06D8F766D2025B03099BAC8202C5D90B52C5397CF55BFACEB5A1C079CC02960FB976A735357DF16B90210194627A5089B1D29CA4FE8A03B4FFBB544A645C5FA95EB386408DC65AAD89CDF0285F3745EDA596D070356D350775FA7A088D732A61C1AC57306359B4A642B8AA8BB91A347152A916D33427DAB37143AE14B2D804B0FC033EE2B9D996853ACD202B2689AD945CDA48938BCDB2D8DBA5449C80891B103172381200A68BB7B505EC5A373E15DF301BB7547770A5B21A571CF4CE87B1AF38D3D38329BE9AD366159FF1919DB40233E86BB497652379B9099F68B22EA91552273AB1801CE6BA9FE7B07ACE9A81DBB09B11CC4AECA25B5090C6FD885B7E19941D8561A15CC35046EC191157C393168C80311432C899B0A0AA578460963E7767750560064B93AB148AEF2FC2FBB029C89126535C6BF2DC48A04748D23A6225EE6C3EEA9B68C65BCA2E9C804EA5BDC441BD05293B8C19D96E369B5C3459DABCB20565405824EC3F57475AA4E19DA21A8EAC0DD312E9FC10B56D6C6EF40A130844D8FD68769E2CC08288D770CD00556578D853FE4896886536AF0633EFF38C1439E3E7950091189960045B3B3B18BD45BE846AA63E4D3845BA001699FB3EF1CB24186CF884DBF62F4BC68D598BEB013F7C438C66E180500AD0579E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95" - }, - { - "tcId": 65, - "deferred": false, - "z": "EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26", - "d": "D7349F9AD546CFE9830E1197072B6ED9CA21E8E0423F145F1DB84A5AEBA230EC", - "ek": "4D09B276CC63BC453FF20B31FFDCA2FC3C34AEA706769A58AB6CC210551683C2BABC76B5CA69256816172BD926BA7C91A4DC12AC5A3FB087B6E1D3C0042BA5E0F98E5031A6E5077108153CCE342B1F832EFBBAC43A9C0B5A01283522271E649C3AE8C43C541C88603E58F99C1E8502DB34CF70AA48EAD6802844A7B25594308537BF657A07547CE1380AEB994F4F676FF6EA3B9A728AAE5B4E4FF34A5B68530C582194320E6BF76B997A8CF42819DE5B0D1C82491E741CEDA8AA6280094E332D95FA799FBBB769B2BF769798854899D67C1007FA29CD7245F727CB206456E4020F80A9600DE948DD2AB469C1883151A440C49570430D003C97642601CF010C200198ADB7ABC04379864C7FE6CC8BBC29CC1A6335869ACDE9DA9DFFA17C7B8747848CB7DF12B52E8C5EE7144F2EFC3ED00846B9F72598219793A6397E7726F8242B5EB92EBE2577E686B980F34859B07FD24084057B13A98880C93458D59BCD5AA68314EA18E80A94CD826FDBDAC1F05A472DE0872027C1CF924D5BDC9F236B1893DA61486757FC758806F580279919862C0333B15A66C138E4DC6ED50B17EAFABE9074AF14270C20806AFF0B58ED97631884435A55A8AB394EEEF5347B2640E6980C41A30A18E85A86074E03DBAC48855DE4E94538939A4264593B649E5BD981E0917C26D563D287A600EA89CEEA7021E754384157C8ABC5BE47C7DAF72E15787D1CE62723547B0AD86F852B150A25660A4A074E707884CA7934F9BEE2555A0F574B7F750DD293496FF681A09A4976671210FAC3C8C84A03F99F39A7B649A19F3E05A1D0E7A3728B253C5784F92CA7348A4BC086460A24B620845662246F1C0AB9BF91C8CB301D7DC362A3137643C92C8797CBA7E59A17DB9B99D08977D56A4F34AAEBC16FFBC8822822931FC73DC6BAB320972D96C16DAA41CCC89312E43275856856C4598313417C1B5261D9C1430A16C1D2F3CED08C862A21678A170A2E1A643E139873C878AA469F163C97AF7C7A1DA41034878D7E144DB826A7AE48B97A5A131185813D775BEA667CE0518B11429768F58BC30946766A6FE5B7BBCDDA7CE18C29F396307BB456AEC16FCB989F32660CA348A83FF36D1AF452C4584E117A3105C662135997142AB16CBB7C7D28560B087BA4B7B66A00563EFA3DA1C4764F8B7B5D128EC6202C505AC9446015620C359555268BF6AF74144EBB26351E98AF7DA51571F16A01B320595754C0DC23BBC75A8F036A5F6C3AD76907FBEC72530855891381B9F2B719429D4B6BC04F014F50FAB14131C60CBB279B61469E1B8664A38917CC308FE0C7AFF637DD4A76BAB66F08487739B20B9EF850F7F20DD83A1A47B53F00471A1617AD164AC1C04A8180BA68984B4F5DA9BBE1D0CA352509BC0211DA0B321789A61C98222508A03E0A6A7CF3849126435F36575D63B342FC2F02DA45FB8B5C9BBB6E064328550CBB6DA1AF16424A3AE9C1EBE566F4C4A883F966479C0BCB6585D3A2B1E14C3608E05AC5555454EBAF80E5C7BDE47B12F66118027E19F325024A5D51779C17D1B933A1CCE61003D018A3BBD67EA16B02EF997EF0678CB776479C52203875774C05B0EA9586FDE02964B8C3E1968B9940C88763822AE563D814BEEDE38A7D1653B2131558231AE3470608B51FB78CAA99C7252EC8AEAD74025CA8BD5C038283181E9381C73188C403A0B6F88B855FB5673B180F7581AD69513163379B34582128575DCA936A614A17C84C36222C3893D4B5F97829E132449490096605B61925844E31982BD601538739D8E7B378E180FA6A7EB9874CFBB8069447A96CB81169F3514CC20A93A42E0C9CC321EAC10B8AB21A893FC247BD557B6485A9C433390076573EEF854C2EF08AE116C58FC75CBC03BF8FE7312EA5305781CAC7273A78F01C73319B0B26670F26513E57660340563ACB16CEE7CE7CF0BA52671E23A44C85EB994A7A7BA15941F4C301D3B87E0D2A75D2EAAF1789237BB5B02930CE6AE5B965DC5E7277C8EEC0676C55436014AEFB8AA3B1BBA2D07B1F91487C99673A9135611BCC3B3546C42B23CE0A8099D6666FDEF62D402925B4561DEE3986B30C1C6278609496A474928D0A8351DF30C83CB4BF4BD826CB4319BD620C7AD5A7F1EBA1B8913A46D0365285A38C4C1574FA4287C02D71E91A43EF856ECCF60978C7B83099574EAE8C27A0571C4E51B320B34ED55E8B1E576E", - "dk": "CA16BB08B42E527B707E18B2ADDC64F2FB9542C89FF37B4B9187C72DC602FD83CA619836032C19D3497D49FA2AD23C0939721984DA633C14BE7300029CEB1AEE6631F236060D378852F6B1453214D1C87806E42E956286D2356B7B42731B054829B72B6A89BA4C16308A00C35D59A717E72BCFE69DB53C77D6295243FB599FB3BCA5E6C179205E15EAC020826EE8800A97EA3B51400103A362D0669550D1B56C466535B148862258EF25C3FE14A16362B5C940362B30C2E9A660BA66837071AC18D802392BCF17E62AE718288D175B0A61A3010943131070F84374A47C2EA3E690F7660E67E1B813DA13B9E52BB422A2145482C1A536D0E81BDA906A45DA576D09350FE9C223BC31D89571FFAC999EFB71FA59B29B0431FCB68B1FA37DC9585012414212883B640A10E0937CCF3BBA568A2A519B1EB02B515A26335FB52A1D6B9D122C212A913520661A795855A4D65695D4469C3766FEBA11AA4CCB77B4AAE7608A82EA2E22EABD4105075DAB6D88591A2B2B5B11918C15735DAE6546BEB95656F195F0BC70A3FA3D6FE9898BA1284CD368666C8D8A51A7440411525C3F6C694CC586CA15EAC1CD4B88A1A8CCC713233CC5946C009799DA4EC0294CAFB09D94580EE4E705FB842CDE2429694141C0062508C79D69A2515B843204B3857F77A352764A88A5677C885F00A88615E3524C7A609547184FE029EE7572DB3C821C8552FE499478DA9DD708BF602B73F180B5C801C9D7465E77C7B42A97CAA3F4CD7B62BF0AF7A7F2BA6187129012E5C7443738572C1BBDDB784459B9921B9B39D020F169BB7FC6CCC2B71C231A27462BAA34531C3838A1C13B12F353326D870D541895E259208AAC459D44C7CFC44324AC3CC2B7610C96BFAD5806692CA9F567500894A073629D66741A3EB33F56720FC80305F60791BE328DC8C28AA10097CCC03500D1601C25CE03550974F12F8E384C8B310F32A5CA60DCCD230B89788B41CCD6825251C601B54DBEE636CFD491E5B071F8A1BB599144B402C007B80C73B3AA4E6A591AFA2F108C1BDABA34FCE43866661954A046F0D5AEB0F681602490B6118C2ABB67EFF83C349933AF394185F72BCBC80F0C1751688A42E247451DA4BCE4DC5BB5204121236623095B25E91B95E0B5C196699E2CC284B88FFB11426F8944AB174DB91484A2FC7787A97172596DBBE0AF50C68CB9726C11ABB6FF6366CC280A23D457B638A307328FB5E70403EAA029D2B121118AAAA39089E655857391C0D4A85FB7AAA84448CC12A4CE428A37D5B6DE999C7CA82879112E17EAC572001215EB8F3F07C153E6B251E699B3103855C747A6B2A1FF44ADEE996EE5F545373C972D431854DA74DD744CB3C7CCE52A31E332112D70736EE859CD47C381691C9275B8FBB46299A48BEC07506D65337BF64CC5F50E2C3A2FFEE688AF4B52A4DAB2E2E4267851AF5C2CB55255629036674E0185E069266667B9472C8DCDA95B4B16B5845940CB7A378E3CCE2FA9CCDB787415F58C30C46E691B6B6DC4A8B0C892DFBC7699599CE25812A478874568260AB482C5F69D7E773CD928BEDCE7067217C0454310B1694264E3A9D3E41300B87543B4235CF432597A5638EA41637CA894080437766C472047BF5BBFBAEA557B658174A576697613A8A73254DA332F6B232A65B9017928288A44FCF8889CE79718A329CED152E35B4E4EDCCE1B197DACC7942D59C2B0E80A0FC74FC726BB951898AA15CC1B106A383AC10EFB4D48445F9CF59C4BA17D5817618BB27879067FE2615EAD1A2BDABA6C17D422DCA06C3C4578B873B17714A6B8F2AFAF8CB445F04238C954B38B28D1028D451A25C3797872601B98543029F57671F52F8F25AE3C88144D011B22B88F9E60841C3BB52205A00EB24D3254B8C37BB845E10A14B528A8D6C1D07B7AE4E66E4F88C26D116A853B4E41ECC6AFFCA83068188189063030B5BA854541433CC454133FA2B5A3407852A64D9277883DA9AED1D982695854E8D3B114DA709E1BC3B926170C4A2ADECBCF8402A3D9253851274BFED70BDBC817DDE56A166B61DA0793AE0818159C0626BAB102CAC3EAA05D8F996D6EC01FE5E9061147A98EF4A5BA361508B385A5060D5FD0C462F340B943914D117B7EB032348003E89C3D888485E3FA9A3489CACD855F4E55864D09B276CC63BC453FF20B31FFDCA2FC3C34AEA706769A58AB6CC210551683C2BABC76B5CA69256816172BD926BA7C91A4DC12AC5A3FB087B6E1D3C0042BA5E0F98E5031A6E5077108153CCE342B1F832EFBBAC43A9C0B5A01283522271E649C3AE8C43C541C88603E58F99C1E8502DB34CF70AA48EAD6802844A7B25594308537BF657A07547CE1380AEB994F4F676FF6EA3B9A728AAE5B4E4FF34A5B68530C582194320E6BF76B997A8CF42819DE5B0D1C82491E741CEDA8AA6280094E332D95FA799FBBB769B2BF769798854899D67C1007FA29CD7245F727CB206456E4020F80A9600DE948DD2AB469C1883151A440C49570430D003C97642601CF010C200198ADB7ABC04379864C7FE6CC8BBC29CC1A6335869ACDE9DA9DFFA17C7B8747848CB7DF12B52E8C5EE7144F2EFC3ED00846B9F72598219793A6397E7726F8242B5EB92EBE2577E686B980F34859B07FD24084057B13A98880C93458D59BCD5AA68314EA18E80A94CD826FDBDAC1F05A472DE0872027C1CF924D5BDC9F236B1893DA61486757FC758806F580279919862C0333B15A66C138E4DC6ED50B17EAFABE9074AF14270C20806AFF0B58ED97631884435A55A8AB394EEEF5347B2640E6980C41A30A18E85A86074E03DBAC48855DE4E94538939A4264593B649E5BD981E0917C26D563D287A600EA89CEEA7021E754384157C8ABC5BE47C7DAF72E15787D1CE62723547B0AD86F852B150A25660A4A074E707884CA7934F9BEE2555A0F574B7F750DD293496FF681A09A4976671210FAC3C8C84A03F99F39A7B649A19F3E05A1D0E7A3728B253C5784F92CA7348A4BC086460A24B620845662246F1C0AB9BF91C8CB301D7DC362A3137643C92C8797CBA7E59A17DB9B99D08977D56A4F34AAEBC16FFBC8822822931FC73DC6BAB320972D96C16DAA41CCC89312E43275856856C4598313417C1B5261D9C1430A16C1D2F3CED08C862A21678A170A2E1A643E139873C878AA469F163C97AF7C7A1DA41034878D7E144DB826A7AE48B97A5A131185813D775BEA667CE0518B11429768F58BC30946766A6FE5B7BBCDDA7CE18C29F396307BB456AEC16FCB989F32660CA348A83FF36D1AF452C4584E117A3105C662135997142AB16CBB7C7D28560B087BA4B7B66A00563EFA3DA1C4764F8B7B5D128EC6202C505AC9446015620C359555268BF6AF74144EBB26351E98AF7DA51571F16A01B320595754C0DC23BBC75A8F036A5F6C3AD76907FBEC72530855891381B9F2B719429D4B6BC04F014F50FAB14131C60CBB279B61469E1B8664A38917CC308FE0C7AFF637DD4A76BAB66F08487739B20B9EF850F7F20DD83A1A47B53F00471A1617AD164AC1C04A8180BA68984B4F5DA9BBE1D0CA352509BC0211DA0B321789A61C98222508A03E0A6A7CF3849126435F36575D63B342FC2F02DA45FB8B5C9BBB6E064328550CBB6DA1AF16424A3AE9C1EBE566F4C4A883F966479C0BCB6585D3A2B1E14C3608E05AC5555454EBAF80E5C7BDE47B12F66118027E19F325024A5D51779C17D1B933A1CCE61003D018A3BBD67EA16B02EF997EF0678CB776479C52203875774C05B0EA9586FDE02964B8C3E1968B9940C88763822AE563D814BEEDE38A7D1653B2131558231AE3470608B51FB78CAA99C7252EC8AEAD74025CA8BD5C038283181E9381C73188C403A0B6F88B855FB5673B180F7581AD69513163379B34582128575DCA936A614A17C84C36222C3893D4B5F97829E132449490096605B61925844E31982BD601538739D8E7B378E180FA6A7EB9874CFBB8069447A96CB81169F3514CC20A93A42E0C9CC321EAC10B8AB21A893FC247BD557B6485A9C433390076573EEF854C2EF08AE116C58FC75CBC03BF8FE7312EA5305781CAC7273A78F01C73319B0B26670F26513E57660340563ACB16CEE7CE7CF0BA52671E23A44C85EB994A7A7BA15941F4C301D3B87E0D2A75D2EAAF1789237BB5B02930CE6AE5B965DC5E7277C8EEC0676C55436014AEFB8AA3B1BBA2D07B1F91487C99673A9135611BCC3B3546C42B23CE0A8099D6666FDEF62D402925B4561DEE3986B30C1C6278609496A474928D0A8351DF30C83CB4BF4BD826CB4319BD620C7AD5A7F1EBA1B8913A46D0365285A38C4C1574FA4287C02D71E91A43EF856ECCF60978C7B83099574EAE8C27A0571C4E51B320B34ED55E8B1E576E82D819925EC1B1F45E255B12DE1637697CDDD47F41DDAC13484983D75BAEDFB2EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26" - }, - { - "tcId": 66, - "deferred": false, - "z": "DDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440", - "d": "F05117E932CA0E0C202732DFD4F674BF5848219A76C64A0650C27E2E55095513", - "ek": "FB28C9266161FFA370AF3C5C163A9B187A5D2499115A1120F2B84D71948E00A7969685C8FB6B8185566ECF337E1E20AF4E4A87D1F4BEEB1BBAEA51499960683C45B53057891A288E5A8393C4F19A06C222D4C9AFEE5AA984B6798D45A3F271793E77A5404677B08A1BC5D3CAB9D9A20A4880A11B71B7D4221C1302B8BC24FE65C4C63BC7D1B80D8BB40A7FB535C672BA32496904A9976B328A2002B14E9A071713CBD9B48E55359D451C3EEC47C4A7B9CE61AA5A9516C34009A8085A98725C13949644A72A338DBB7621530858FA1B40D6BE5DA89E9A422A08031CA3C003A0E31AFC4B36D97B4508BA3537DB1B16D1A5B5A98E6BC1CB70696F887940A60498E276C1C900036A30735B20B9762A3517C136A9DC20A8F5CD73BBB047A00DDAC6A6DB40BCAE42C1D6329FF54B9C37F82CBE6214C2A99E31DB80AFDA9BAF06916BD3CF83643D27828130495CA2FC67EA441E38A8032CF0003926901245973EA549EF48A9C65ACDD5E25D5F9834CCA805AEC7CD9F687D5CEB8C2CF04EB6A1356B68AA7AB9CCE7452A20C5344F11BA6197343886A80798098C63AC5AA6095FA2A1D2B0A07195ABB3E98057953AA0B20C00FC06FE553FEDE713DD4662DBDA4C7806B44904411D85C8B9C57912A72A2D25460467CA25027BC74C3066C7A941858EE4D04026914B45354D342B6643A280CAC8C9ED60B9AE021D38303799387D12A98419C26010FB9492262002B0002FDB167FB668B2D8C453987E83F570A43AABDFA5762015B9FC196FFF6542B189395BCB5C4AE598A858597622240E01856B17511C480627B4818C413ED065C68F359266008E888B9EC435A906C6721CF8964885A160C0512FC4B9B454A10E9954048B3212AA9C37A27D2697B1AD530FB33974AB25AAA9F33B85358454610E94410D47F85920F2A7F5D13C74CA4C6108B768A476C5BACB57F17AFADB60D437C21D397A09929B2E97915254A0FAB1848779726D766CE6C83639C4172DD5A1306CCCBB1491D56C1A5FB7CB5FC7836F0765246815F05A2A13385920D0B2C518395AA997E1D33A2AF588B7EAC1DEF4BA688555EC4961596873CD0A0A443551269C73F0B97B6F8CBBDD45BC5A15356BE370FAD74805032940AC0E9C2269C0FAAC67A647FED78E83094D08F58C23745E2BA70366F24A42635A944771C3E13C8EA25B8BD6B8B0783487F1A7A4A15776DAB44EF4192880BAE74C62DBA92A24782CB91237CEDA6E84A0C68244B9CD350DA0A67CA5477EBDFC4D40F59EAE1A88E9043653F5882CF614611641380CBAB15B6CB4189491ACA9D1BC22C56928A7B37E678A4819D48A7D27887F12B4E3878E8318BFFCD93B2B9C4ADA1676BB72B93DE19295DB59909315DB1209E3A02193C1126DC30BF77C6DF59AA4EF921020253FE2045BAE6760C206A7FDDB596EF802B1F3C620D353CDB008AA0A4B8393744E25A34ADAA31D2313B480C29DCC8DB110049DF796DF298CEA91015C9686FF3A300A7298F4B7237A893E02BC373641CA88F2345CCB4A6E7441D30B244814A665F08A18146AB65C3761BC5A87860B2E20482EC89D444180D10337C45C702D82A51DD036B5EAB0FA81B017BA82E16AACDB3A96A53775B9874EE8079CEA7845C3CABE0C847B7B4BAB1FE0680B12986D821968579D963703D90AB8DE020A7CF28DA8395887B2ABA5C09BD7102B8662554D1C472578A9F80CC15F431F18980BA1E26754243102D03D42E69C52AC25EB3A19FCF57FF9E1429E78CF6AE0A501AB3EC26C0D729B142636B873E9B68E277370366C0FE0543E44C08716C4F9B06546B1CB3DD243B505B1A15976B33788E8D1987F810D5797A8E9CBA8B126923A1A81855151780CA9CD4055D9495603A84CD7886BBFBCAFF499066496C967501DF3D861B97C5D250016BD3B3A18946C0CACAC1238CD235A6A609611EAE792E0560B831B636309517AF489A30269E172BBE7470C2D158F83C4B20F15C524025D6CF164200B3870663809A00E6A982835C87F80A68AFC1B5393B006D220A0AA26B9666690549523A0A9711E03B2419914FF76CA69A62671260B34F1C1A11A6E64067908839B87D2940D433162393A6F65B08E4CA643201023C63DD3C3808E9625CFF4C346491E34153937589310437069622208C646AB58584DF10F9930BA2F761DE4C2564BAE2B31A9A645135536FCB58B94489E4D993C9FBD4A89198AD91BE052B5E8FF", - "dk": "A6247A7F4938C4589C972C928D7C65B74634ABE136E1C732A094A539E4892780BF56A5A7CA52AFFAC643B7168B997809AB95C8DD4740954164819C4D94453053634316F3186DCA4A03E813BCF763E6436E05DA840EAC0FB65B11D2D97EA80B156966C5A0DC43799B74F3797D483486E4647C8EA61569880774D68C9EE2A5907910839A95E8E33CB10B2AF59C22128B0C8BA9AA7D0B7A48E26C6E157D58122A63E571B059073AF35AF40282D1C8AC2ED5B15B2C980D6437C27212B5CBCDE888BD8F4B1B3AE398182243468C98F453569C417CF3C043BE9A9BBC03D058212523F0A6A2A263381967A562B63E7C1A83A4BBD1D86226B5083F8B54D93413350B39270C9E784430AD30752ACB0CE0F2B7300B478A3801C1133A84009106DBA42AEC03AE413F137812A35B4CB29207A7FC332BD07064019AE8CA3F6A723191058D88A460D40522FFE0841AD5507B1942434939260228CD993266DA1C35B920012C0E349C224D492DD6D197CE7473FA25187AB87C192A5382FC3DB61C817DF62221666D6D4858F807C852853EB1AA8A7DFB4A79935711698572E12485294DF538257F44AB92A60D5D23AC91F56E138025BE0C93F995BB3A9620ED0A7588857B4F847F996C9D7DF40BEB05C87FF79BCBF222956CCA23F377FC36140FA379CB89365532490D470C3C5B4CB8F3560A7A0C7FF9A19AA0B0E03C100B5090AB42A9C652399FE79716B61921DA7211ECABE486A3E95B3EC0E79A4DB614F5282F2C8087F8A1CCEE9417D4F99C108202C92499DACA10E3AA9B46D254BD8593316B9D220A96496372DEE61B51E93D51E9AAFDE006AC267037044E92A3440A469BE8AB36C3A70B070C43BF889F1DAA6E975CA464F32BBA725D75016B86C8089D9338C9816FDA6220169CBD445C7C78136E9F56A431957068373DD3480F7AF88ECE4941A2FC3BA9C2A474FC1D583A59AA42795365B6C0954F3AD810F55B5B0B959F414137B7C3AC0351812E9B00E8B6BE2953C7AA839F24F02D8CDB356CC64B5A361EEF29A2FE12117D9CCB86D4A399F51CA8D796A29778474838D903830706A854E83BD0267C7CD43B927B83DBB29C63E32FF5ACAF1A2A0C50609F4381C32E78B583808841F6300AC40302CCAB18A945FD0CB510588796C61540FC559800A7A1657736B347C50657E559685A226B19F62B34050FA4D76CCEB3A9BDF5A3815A7F4558AAF108958806C16A264132968DC63CC40342239E7640BD394CF418CC3298B7ABE9CFEFFC1714E96486CC73BA380E5A79900AD19558C68EF1BCC3DADC3E7829BC7BC09F407C6384E51620492E5B643B10B45E3BE52CA851709582C9DE447A501A07026528239054901882F5B74E6DC791AA9397DE9403D5519F1368084EC65D8010390F23C7DF604CAD8092E950901F9860A267578AC5043773616BD1792307AC8626201CE2A4FD5613CD97A074F3476094BDA4EC32A161855A4888223327978A8F74625C74A572C37C027E619C7D5577335B3D61E3B53191517C5A50FE62C63A08B6ED65C054EA98CE22C7464CA2DB3C23724C9868007133A235A36A7C56BA237FB58237F7C61E4A66F7B51A2751CF3706367413AD57A01B687107A513A46ED70025B41B785354BF986D4687369F97759D12551C6BB203A609F28931DDC076E6E38FFD083EF4E99B8C3919DE18BC7601260CE74EB75779FD1C6EDD4C843F770F6504B4C468A80C8C3C37D80902C736A15539406A7BF01206173066D29902348708799C2A7C88B751D62BD2760488357836B4019DA55B4A3050242791EF3C94AAC0A821BB71A90840B7E06F842398CD50282A15718E29BB4B75796AE81C76503629056CAABB2A0A319761C10EAEBA23BCD3033D911ADF754C25EB3923331BA0C332CF357758469D765A2C492565923872FB1322F5E1672E010DFEB7815B940595CB4FB6B64FDE59A63C689BE4B7828458B31BB5103EC4C8F1F905FEEC2AD1D10C7689C5C0528A56E4444C958107868E477662C25071E28404AFA86411910D33B618276A5CE51850F3B67584949F75651180298E3C791ACA85590E6BC59C0C8365DC6D5AE02D34D91B1E6C7BEFCA8C7F042070E32BD4883ED1D15128D516A40235A086A6D385784C457FEEB1C704C426CA4C48155445E414200A7CB6A0B9C0DF343CBBF95C7655B4FB28C9266161FFA370AF3C5C163A9B187A5D2499115A1120F2B84D71948E00A7969685C8FB6B8185566ECF337E1E20AF4E4A87D1F4BEEB1BBAEA51499960683C45B53057891A288E5A8393C4F19A06C222D4C9AFEE5AA984B6798D45A3F271793E77A5404677B08A1BC5D3CAB9D9A20A4880A11B71B7D4221C1302B8BC24FE65C4C63BC7D1B80D8BB40A7FB535C672BA32496904A9976B328A2002B14E9A071713CBD9B48E55359D451C3EEC47C4A7B9CE61AA5A9516C34009A8085A98725C13949644A72A338DBB7621530858FA1B40D6BE5DA89E9A422A08031CA3C003A0E31AFC4B36D97B4508BA3537DB1B16D1A5B5A98E6BC1CB70696F887940A60498E276C1C900036A30735B20B9762A3517C136A9DC20A8F5CD73BBB047A00DDAC6A6DB40BCAE42C1D6329FF54B9C37F82CBE6214C2A99E31DB80AFDA9BAF06916BD3CF83643D27828130495CA2FC67EA441E38A8032CF0003926901245973EA549EF48A9C65ACDD5E25D5F9834CCA805AEC7CD9F687D5CEB8C2CF04EB6A1356B68AA7AB9CCE7452A20C5344F11BA6197343886A80798098C63AC5AA6095FA2A1D2B0A07195ABB3E98057953AA0B20C00FC06FE553FEDE713DD4662DBDA4C7806B44904411D85C8B9C57912A72A2D25460467CA25027BC74C3066C7A941858EE4D04026914B45354D342B6643A280CAC8C9ED60B9AE021D38303799387D12A98419C26010FB9492262002B0002FDB167FB668B2D8C453987E83F570A43AABDFA5762015B9FC196FFF6542B189395BCB5C4AE598A858597622240E01856B17511C480627B4818C413ED065C68F359266008E888B9EC435A906C6721CF8964885A160C0512FC4B9B454A10E9954048B3212AA9C37A27D2697B1AD530FB33974AB25AAA9F33B85358454610E94410D47F85920F2A7F5D13C74CA4C6108B768A476C5BACB57F17AFADB60D437C21D397A09929B2E97915254A0FAB1848779726D766CE6C83639C4172DD5A1306CCCBB1491D56C1A5FB7CB5FC7836F0765246815F05A2A13385920D0B2C518395AA997E1D33A2AF588B7EAC1DEF4BA688555EC4961596873CD0A0A443551269C73F0B97B6F8CBBDD45BC5A15356BE370FAD74805032940AC0E9C2269C0FAAC67A647FED78E83094D08F58C23745E2BA70366F24A42635A944771C3E13C8EA25B8BD6B8B0783487F1A7A4A15776DAB44EF4192880BAE74C62DBA92A24782CB91237CEDA6E84A0C68244B9CD350DA0A67CA5477EBDFC4D40F59EAE1A88E9043653F5882CF614611641380CBAB15B6CB4189491ACA9D1BC22C56928A7B37E678A4819D48A7D27887F12B4E3878E8318BFFCD93B2B9C4ADA1676BB72B93DE19295DB59909315DB1209E3A02193C1126DC30BF77C6DF59AA4EF921020253FE2045BAE6760C206A7FDDB596EF802B1F3C620D353CDB008AA0A4B8393744E25A34ADAA31D2313B480C29DCC8DB110049DF796DF298CEA91015C9686FF3A300A7298F4B7237A893E02BC373641CA88F2345CCB4A6E7441D30B244814A665F08A18146AB65C3761BC5A87860B2E20482EC89D444180D10337C45C702D82A51DD036B5EAB0FA81B017BA82E16AACDB3A96A53775B9874EE8079CEA7845C3CABE0C847B7B4BAB1FE0680B12986D821968579D963703D90AB8DE020A7CF28DA8395887B2ABA5C09BD7102B8662554D1C472578A9F80CC15F431F18980BA1E26754243102D03D42E69C52AC25EB3A19FCF57FF9E1429E78CF6AE0A501AB3EC26C0D729B142636B873E9B68E277370366C0FE0543E44C08716C4F9B06546B1CB3DD243B505B1A15976B33788E8D1987F810D5797A8E9CBA8B126923A1A81855151780CA9CD4055D9495603A84CD7886BBFBCAFF499066496C967501DF3D861B97C5D250016BD3B3A18946C0CACAC1238CD235A6A609611EAE792E0560B831B636309517AF489A30269E172BBE7470C2D158F83C4B20F15C524025D6CF164200B3870663809A00E6A982835C87F80A68AFC1B5393B006D220A0AA26B9666690549523A0A9711E03B2419914FF76CA69A62671260B34F1C1A11A6E64067908839B87D2940D433162393A6F65B08E4CA643201023C63DD3C3808E9625CFF4C346491E34153937589310437069622208C646AB58584DF10F9930BA2F761DE4C2564BAE2B31A9A645135536FCB58B94489E4D993C9FBD4A89198AD91BE052B5E8FFF2F75EA69691E4E53E952F98536718602B96B7E5A2FB218648F9353EA65FEABCDDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440" - }, - { - "tcId": 67, - "deferred": false, - "z": "FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03", - "d": "A405D9B07C5771A5BBDA2BE9F8A40D9566CAD7DA1761ED8076A289063DB4A8E2", - "ek": "DD0C664328C53E5B29F9A9CC55D97BA265A18C02AB73427307E78AC23C51A56478CAA21DB400A3AB081A0532729C40BE3FF9ACA2DA1799E29BB2A8325F1A9E7BB99D44F3C27427816B3BBAC0FB3DB6B23B7323A8CF4587D505B1D1FA9D71696064CB6A7D806872D68040714D94162658780295FC056B269D4F16AA4D98A5245C7B33462129130425712798C879079217CC3195E5CA67D137865181B6C2F92EAD04945E97720DE0CF7531BC46847D68E3C13840B94DB2242A048F0F22331050950B8A4B3FAB51A487134A2C9A95FB659342867D252FAF091D1D966836F1CE964428C63CA3950BBCC3D8A800191FF628680D23A8EBF6BE727225E4B91602E46949889D910CC46D6418411B394AF072FF49B894A1586AC7C1823BB89AD2997C726C3FBC65609CC37656BEC80A6B10336A346412FE34075DA69D829B8B937A87F76968BC93BF5D5639AD76448E084DD0D02AF4A7028D7C0892A9728CF1114622494D8B28D05065E6DA0813043504293A17D29273572E34A14816A01F5DF58BDF44AA1AE8CD0C6C6622CBBC07540405D5AAE8C77BB3418A91B982BAAB4F8B388224EC3E345764D9E66C2AFAA27B924A07039720D7B73084098457C488137B75339F1D7A6919A29FCAF71F4DB8A17AF6161488C02813191AA2B98FA51A6FA07BE8F288C51B538292683A4C52C7F7B2863C52C0843452B583CB583B98414B4CF97185082768855206871CC76A0A409802E0DC23036B3586D9991D241FDCE67D4986CECED74EA7E77BCC479EE4768952E0297568528AA1712468B267D474D069CAF9CB11E5B0CD23DA09D5095349E3614194B1C63596E7E65BEB6769516B7B0759C8FEA02C7AAA1466A7B41C759135965ACE8857074B95DD6A5ED9D36FDABB83341A841DB163C1332881322F5D2374EE11ACB0616A6B1CCD9AC7CA6673619BCCABAAE562D4C433147A2802C26B6431BDD73A455CF8CC242174AB5123BF9C26F8280E5755A4BDFC1A98CBBB92C152FD11655EE4459ADB2F163928EAF24ED09C72839145C96179D8C94E6B3227AC793F5FD990DD638ED150020934894684A38BB1AA859A3AAFC49EC5A53B8646CF60F5585F043CD71B13F9BA41DB563677B04EC6D8270FB55C78F8A58ED494D9348B4A774930C00752121081514596D5B86FC0CEFEFB4AFD2682EE056BEBCC0CC9446CC3C1A0F5F34DCCE8AFF0949FF16005D121275A5915C6D4B9407357AFFAA09CF6783ABB260FD53A333879433B45FF25B9D71A500BE315D2635DD4F42B47881803666441871083859D266B96C1327F96B40454D17ED5363A27CB612A69064B268DA9185B4506119D7A71FA1386AF6BA9789AC06E9A0F04DA5C6CF478F18044457418E0FC986681B81BE1A7AC1583AE95155DB64FDCF442E5EB39515B06DB280A23AA5DE2C19A1051A4F9404F712955ADD66A9D1A7E963BAE57BA75190B7447B70EC0170EC0C2CEF480132B375D3991B90B729F9A4356F062C00D030BF8AC4A82032D5F42B7D47B6009B274C4D2A5DD5553D29AC86F148ADE931A81534226EAAD33612AE89BAAB7729F3855339625742AEBAC2B042AF2F5B4F3A017A74342501C274832B314BCCAADF59DC52A0ADFC061F2256875D960CB654CD78BC46C709B2B9133F8801CD6766800E12516D80CA41011D68733901AC540533E0CE532CC82AEDB5CA0DAB476CC5A81188B54E0AC9FE66A1D977A6631519810128F98C3044BAA5991920C381BCF3D63B785701421733FA25C521DC10BA007040B917E55B863F95A1A3E924D3FD0AD3975662D38476BD3B47E46769820C3BF4705DF9A89DAA53A58AA77B65258A444B2002B681031BA765659D9C18D92D826733BB575705D6D7C7DE3D19240339AB4B12BBAD51ECF8638E6456E5CB350FD551E5A5C67DF050DC7E7866F4A10989C40BD3C22FE480343E07DB22734CE89870B6804273447A85169A170BC53B861B9545CC186501E8A541575A480562E5D7198B4D905B8EA51A48688A8E488A2A36F7EB15AAA398E6BF44B69622A14B3473B0AC09401223CE775761B8931D53D25E0AD51426970403B0A243E9307502574B1D6323C11F7CB5D855ADE147211438AA7FAB0DF89CEE8286618D8181DE196A311390BF171EDA88DAF1C0FBF540EF20504209482BF3B7D023100D8795634BC28CCE86A4131048041A23549B016EF00A31156458CC5808590AD8FD2EF59DFCC0C", - "dk": "73831E2C2993800A26266635B586921217B9AF812D5656B9CADA071A384F69D48A210660F51C4AE1F2A6F2E18AC7FC2AF9901318A56E36A483662579736943B7855BCD664BC7441FDEC83DAD5C54187A2FEE338DC9A4AA55780F07F3A94ACA4DAF9145FB099F05648DAC3C19EF450EFF4633500B9205424C2BC4081A017D52BC3302B28BC53668185B147B117C9A7C427249037CC165134B6A9A4663CB13AB0DA3B501C67866201485C5645D4006F929AA4A68831038961B61C950110106CC98C03287D291B080A7212BB4A7AF92AB3A2A06EE19200A531040949C5D57B2D8B09D637638B3690C4F1457A1E9A5BAF903DEEB894300984B76A03F0116D570CDE59981F10A2DD8590EC91765ADF252183C10FBA093004D5700715215427F2FC85D700747C8029B9CAC9A1A4AB8E0641D124540DCC3C1DDD62DBFC89D884C7DA2E515CA87A92DC99B1BA97B0596153EB53D4B8818D2644F638545D94258F5441D5C940A7CDBB3B3E66D3A886457316B15808F0AD71421C34266073B1500CE5279315A00A17FACAA04660A556266C3F44275C67B49793CC0679DE3B29BDAE8C9B15458AFB9B2395547C3DA2FA6010A8171001A50863376C172E64F51F87354C99465796789A854F8362C78588DCFCC98250C4524E51A401203E5D4680C5261CA3440C3077CCC6AAC3E809315781C9081629C4199D925679F02B70A200B3F8C98A3E0B1D3B0CF15442E55A76EF25C0B3734993510B7465C0081B82BA8136C7251C40EFAA6E0819046D1CBAE353A9C8547B9E160DFBCCE85627E2B16C0E5A51DBB50565B3A81DCD27FC9698BB742356CCA03CBA3678028534FD0B1B3C852F734ABE2452BC583A103C3C09445396F1A01F3FCCD951299509B2EE2A7468F15B927B0B2D435B56AC12C548C8107EA5D58682B481A568DB4A4B1209E9E36B879D31876F708A039A39DF58A0F0A2C04A19622C359FD395C99B3C5F497304CC11F5FAAB83842B7DF06344657243968156AC67E7938900D636BFB1C4224F677E6D119827ACBE0BA6E32C590AAFB140A041714B5BD3E06A2D7851BF91098C1647133118CC747AF18B8ADCF01C530C91E805966427A3EC4234272BB9D38A8908285C46EB759F176AE6B7395010878089A21C3FB5132AA789B92C7724C8217E9A5E66923552C4514A915C0B43499F8192324A50BE4679C586A646CB0B9808659792984726EE2420B5FB102B96A3D7898B7C98900913237D5D8885B9580556549C1B59CB4F4ACDB481D92A8CC5D447282F5C7BBA6BD0C7CA0D8EA2D3BDA78633C8FEA1561DE37AE94D51C24414F9178C224A92E79138FCD0337BF00121A51BCF5D27177B0CAD3A6665EB77033B10A00037B908062D381AE5C84C711D4B5CA9888180A0FA742B506D86C03A0C54CA488FA404BC0493C47D531D420360DEAB873C000A87340A2915073429C001A088B212EE46A80852C3B839561CFE5A336557EB689BDD3CB75C70C6FE279AB134A6ED3B20A03750C1CC30BB1D15FCFB37105B34F34026B660905D640BF06D097F0C06BB7E6C628BBBA9386CE6AC212A3370AC4FA65C64C5B235BAF13011E7928B896D78754335E2EF90AC5DB53DF83BFC6340D85D444D469C3B9A329567243E1A2B900A76C756C46E26C6936A0C772F88AA38C03D2137E2BA4179D228F04229F5AF755B3C7128AA16BFFB9354395B575D81EA4F266407A206C0CAF14D5151CC15C178B7D567B8C7DB637FB26A62C048CE9049710B07AD28B6168756234539952282D521313AFA65959432E7235C9991487AAE661B6B7108D48C9E4760D6315C14C1725CCF69CE69C2E407799DB8507A0C66CBE15BC65E4692CD5910B5975A3E3416204949C601F55A438B104026D36A71B5B1399BA6DED58166F210847D863D302AB4C915E969317D806643BB85912B9A0C07AC80FFB588ED86B359840D8B58EEAA0494266A11ACC201C6130DCD523A2C5CE2262A243665AAA45BA30D2CB06D4850CF65CBBFC772E0C20F9F652AB92950F0A3B33F448D6C014F5548A241B53B2C348E494C883409B99B257367BAC0CD42037921F8298647D91C06FB1589A17C1D0A99458938570C871B7C865C98734E1A88C4C112294913F3F0A35E8A26B17F85AFE567780B919C0D94C6ABC5D6EF1C4318A6EF21A1F8FA75653F612DD0C664328C53E5B29F9A9CC55D97BA265A18C02AB73427307E78AC23C51A56478CAA21DB400A3AB081A0532729C40BE3FF9ACA2DA1799E29BB2A8325F1A9E7BB99D44F3C27427816B3BBAC0FB3DB6B23B7323A8CF4587D505B1D1FA9D71696064CB6A7D806872D68040714D94162658780295FC056B269D4F16AA4D98A5245C7B33462129130425712798C879079217CC3195E5CA67D137865181B6C2F92EAD04945E97720DE0CF7531BC46847D68E3C13840B94DB2242A048F0F22331050950B8A4B3FAB51A487134A2C9A95FB659342867D252FAF091D1D966836F1CE964428C63CA3950BBCC3D8A800191FF628680D23A8EBF6BE727225E4B91602E46949889D910CC46D6418411B394AF072FF49B894A1586AC7C1823BB89AD2997C726C3FBC65609CC37656BEC80A6B10336A346412FE34075DA69D829B8B937A87F76968BC93BF5D5639AD76448E084DD0D02AF4A7028D7C0892A9728CF1114622494D8B28D05065E6DA0813043504293A17D29273572E34A14816A01F5DF58BDF44AA1AE8CD0C6C6622CBBC07540405D5AAE8C77BB3418A91B982BAAB4F8B388224EC3E345764D9E66C2AFAA27B924A07039720D7B73084098457C488137B75339F1D7A6919A29FCAF71F4DB8A17AF6161488C02813191AA2B98FA51A6FA07BE8F288C51B538292683A4C52C7F7B2863C52C0843452B583CB583B98414B4CF97185082768855206871CC76A0A409802E0DC23036B3586D9991D241FDCE67D4986CECED74EA7E77BCC479EE4768952E0297568528AA1712468B267D474D069CAF9CB11E5B0CD23DA09D5095349E3614194B1C63596E7E65BEB6769516B7B0759C8FEA02C7AAA1466A7B41C759135965ACE8857074B95DD6A5ED9D36FDABB83341A841DB163C1332881322F5D2374EE11ACB0616A6B1CCD9AC7CA6673619BCCABAAE562D4C433147A2802C26B6431BDD73A455CF8CC242174AB5123BF9C26F8280E5755A4BDFC1A98CBBB92C152FD11655EE4459ADB2F163928EAF24ED09C72839145C96179D8C94E6B3227AC793F5FD990DD638ED150020934894684A38BB1AA859A3AAFC49EC5A53B8646CF60F5585F043CD71B13F9BA41DB563677B04EC6D8270FB55C78F8A58ED494D9348B4A774930C00752121081514596D5B86FC0CEFEFB4AFD2682EE056BEBCC0CC9446CC3C1A0F5F34DCCE8AFF0949FF16005D121275A5915C6D4B9407357AFFAA09CF6783ABB260FD53A333879433B45FF25B9D71A500BE315D2635DD4F42B47881803666441871083859D266B96C1327F96B40454D17ED5363A27CB612A69064B268DA9185B4506119D7A71FA1386AF6BA9789AC06E9A0F04DA5C6CF478F18044457418E0FC986681B81BE1A7AC1583AE95155DB64FDCF442E5EB39515B06DB280A23AA5DE2C19A1051A4F9404F712955ADD66A9D1A7E963BAE57BA75190B7447B70EC0170EC0C2CEF480132B375D3991B90B729F9A4356F062C00D030BF8AC4A82032D5F42B7D47B6009B274C4D2A5DD5553D29AC86F148ADE931A81534226EAAD33612AE89BAAB7729F3855339625742AEBAC2B042AF2F5B4F3A017A74342501C274832B314BCCAADF59DC52A0ADFC061F2256875D960CB654CD78BC46C709B2B9133F8801CD6766800E12516D80CA41011D68733901AC540533E0CE532CC82AEDB5CA0DAB476CC5A81188B54E0AC9FE66A1D977A6631519810128F98C3044BAA5991920C381BCF3D63B785701421733FA25C521DC10BA007040B917E55B863F95A1A3E924D3FD0AD3975662D38476BD3B47E46769820C3BF4705DF9A89DAA53A58AA77B65258A444B2002B681031BA765659D9C18D92D826733BB575705D6D7C7DE3D19240339AB4B12BBAD51ECF8638E6456E5CB350FD551E5A5C67DF050DC7E7866F4A10989C40BD3C22FE480343E07DB22734CE89870B6804273447A85169A170BC53B861B9545CC186501E8A541575A480562E5D7198B4D905B8EA51A48688A8E488A2A36F7EB15AAA398E6BF44B69622A14B3473B0AC09401223CE775761B8931D53D25E0AD51426970403B0A243E9307502574B1D6323C11F7CB5D855ADE147211438AA7FAB0DF89CEE8286618D8181DE196A311390BF171EDA88DAF1C0FBF540EF20504209482BF3B7D023100D8795634BC28CCE86A4131048041A23549B016EF00A31156458CC5808590AD8FD2EF59DFCC0C3D74CF5CC0859F5089855A7EA2267CDBE04185599344C8E93EFCB5B3DC588FC6FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03" - }, - { - "tcId": 68, - "deferred": false, - "z": "08FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424", - "d": "E66F17317C40783CE0594CFB5920FF86062591C5EA4254021495749642C0D968", - "ek": "E067AADA829618E4C683C404EA51ADB1A7A116C7A0AAEB995AF1BAB8D0751FBA714957AD6C7A0A9C73ACB8D347F9A9A469D85DD94B1B1E4AB74C94048F9AB578A2BDFCC75A213A65345129F78B26E3D901B3428A0F87952B91517460930386856AE25D00259D58EBBB403621335791EC6C2C6EC50711C07F56714B0ED3753F7459F07B83D1F838CA1875017B24FDC2CA6224B74423842ACC5C4B03D0658C7EED5A713A365CF523C9C2254E9C79059331BD730B123F53538955BC0FBA92FF9388192C950BC46C25339C82E98314D616B50993BB6241224AAE7EEB610EDAACC43ACD775941FD8088E03931F40C999D92360B74B86B857CFC6B5A74367DC72033941C78484031FFF53874308D52AA6FFA3491E0CB98366B8FF2866ACD1AC64B63770BC25BC33531175A4112D7684C01A8C4500F9FC083FE652FF78910B75093A34CADA85947D2602FF0716624FC9617EC71B9E87CACAB31CB3836A022523C3A3BF9F542EC306C22EB815E1038A48CC4F6596A1CB1482C7BADD7390D8DFB1FA01C5C30E458AD31BC5FA717503C0186F5A3B936C2D0AA7197733C2EB708F32B9FF611537773BC38B904CECB5D2BE29C988B22E415C7944726EDE09ACB76175448712F4BB8AE5AAF4498CF4189B0F0332FE774170F343A121071961CA130694B964033BC015F490B85DEA4A81756A95F3526A856327CA68F66E828A66B138C052115C0B6EB910BA703581617299855318BA9AFE6B152CC538836278D781771FA4C033A65AC5630B3EBA8B02A69717FFA1E73E77AFE06441D91CD45289927C40A1425AF113B179CC46C6606CA0EEB0D86765128A726AD50AE8DDC1AED2A07129ABBB3AA67B4E0192DA99D2C36686D3807E0B50CC9E30A82D97B0895B6C7670C01FC214DA38FFC54970D8399EDE259900A081954172F385E037C9B72B43A3ECC7FDB0510F6A930B837618ED756A62A0B3CF58B980C94210BCE63FB9CE88745FE8BC34D57248979398CB0C1C9B83AC979A107C955E97543756221AFF06C553A1F0E764AF19B93E0DCBBB9C327F76AB4BB890D179C90839430A749A2C43A66DC36394FF06DDC54070A2A2F152261E79597AC9B2AD32A39FA489382718E04DA6369C4AA0D4823BE87A60561CF49232C8AA20811EC7B29EC8A90A363F3B367CF9A81A08645C70A17EA41A1AC4C0E9407763D2A91B6732E46C6BA160972ED35CBE6000B7C1B83CA21623859CFB4317306593003B2A90BE01FB5A4030CC062C308C14924CA47A24FA5D13B82FA7153988DCD1077E2759FF250C198ECC4C860170E93BCC48CB009CA7535C62EE2A3AE61D07C828C68D19A55F6A7224F716E77A381E06933AC03A1B0D01B6D231E38D4A19EC9C6E8DCA42C218B290130BCB583F7E958FC3531037716B356948D726E602329A322A410945568BCACBAB75D65DCBB38B80CD20865563699838659E065CE749A6DF66542E8474BD140B50EBB5983F546FB393A0BF10C5891767B935E0F5171CC97A00607332088AED99B13EEF557CEF73429704244FA2B915CC7731BB9BD351FA131A726C837FE19047443A16BEBB02F4A5020878AFCDC72CB780485A793CE23BC6DBC11E04B0DBDA82F51B4327814471C01042A1119D5513408C119266A0476DB89B20B18EBB44A231CC5BC39C6BCFC4DD2A61EF9180BD76327AB05A37ECC4B2E8ABAAA307A6C58040484BF73B06AB4A65F7FD99660A759FA903A56DA3E8DEC389262AFF8BABE1B85168BD21762C86046290F35D51E4BCB8403F160D9DC4E00CA8987E46CE05A5FB04A112EC352B1B03219A4B50345C6F31915FEF4C2EF870D30A244EA4C20D82849628CB61ED677AC9890CB5463EB90BCCFEBAD9FAB23C26A33E6667D76C96220147685EAA84CCC3140104AAA4A559E51209DB124337A2795925C5E0230E7920D4E9338DA23ACCC8693D5952CF49AC26A74CAA6E05011E6385F787A7071CA08C61F59CA017ACBC15E9BAEB78837B99B93908A8CD6D7BD30CB6C23F9CE5E15204E0225B55C120B31C1276695C909C94AA1B5D0C0496278435352B50343A9974A55EAB5105FB4436570181F2B7AE82238CFB9C967F424C1D146BCF74A2349583D36C1F7629E70E0C4702C133F7475985B2DCD923465F39772E8AB76F3634C6A1F6E8088BBB0BD3A050CBF323F9EB76BBC4603617908BE85E6EA5E40A862180D9EF1380B7A859947562EF3A845669146", - "dk": "DDA5A4C182BC2917C5AEEB973FE853A397753BF576B753AD82583E6EF89CDE2B7B9B6B6FC65A349F66BCF4903902D22418E123BE13A3E6A29489362308452991448E53370B9F1315A83540D14A0CB60B9C80549556CB6F839B6062365693CA9665A01CD66574242092954B945D996ADDAA51F106A454002491FC0881D0489722979D90CEFD5235B9A1852D334B6ECB7CB3294C5B50A951E835DCFB24EF9BC124601567C0C05E1C194753CAB73A73E114C91C0341C7DCA0C904217F6BA200752FBD0B74E5503D141C17338AC6B6110E78F5592ED1B599B3A8FE65292779A473D95B3A1860DE955ABBC99349D0A4F85C97A32A154C89AF603799A438890E692370030AF4B69A3AFC91ED283EF4290524CC88E6E67D9CD00790F8B3E8626F528AC4A236570218B1710B82A86A308B4C4068E07422643BB8031E0D556700123F8F948463291257280CFCE2749812AC26A31C145667E9E94FEAE011C037C00E268F617ABC5DE656A8F8C858CA0A392201E144B9101BCD29401C98992E7F4ABDD02705E0F0AAE6D2BF2BF9081813CB1CF78454535146FAA994C666E628A4E1FB15CA5663551962380727A5933F91495B4EF290DE64A1D6D35CFD4A5279EC0460622C2E1B8409619D31144E674B4AE08951B25416F2839AFC4095D7257F34D54D3742997B77893C1C009C55A715D13BAC3092B9911F1BD962645C1A0A91639207BB98E15A37B570E39AA15011280E8B64B2E674CEC8931D26587D003CFC89498C997982AA60FCD8A3ECE93D784B0F9E7C10A6C380B76C1D6E91ACFD4672D4D9485B9C857B92C283B596D714A404444478117FECA0C14B641A0DD1B027DB7BF832316F0BBC256324BD4345C0A7CF3B98B2E6D01B1A9644F29010CEA70BBA08BE6877BFB1570CDC464A049C90C2B28C0A329904C1CFE6C92F076098C300288397CA65581A3BB8BA7D92A3D22C24E8691CFC610C9D3409B73CC2CE78A1C7E5AD07720CC30C984F73272CE4B43541AABF616714400D6D040609286AF1330F342A71BD3276454B3C33B5508817644DF14C42E93199E27FAD15309FD93BC8F88DB9078350797BE9CC027F03A7A18965682C83DDF182C411CB20EC3EF5C435973714255CC8CEE376654CB1AA6554BAB32F7E7587DEA22EB3C2565E760F503B6F103A54B2191FF3EB6E30126B951091B010BCB60C0A8A1C3FC958BC4DE5504A3C50BB6A2A5726B6B8E25024DBB7C02BCB2FE31D7CC581E42185FFA6503BD0A0D1C907FD13302EC37D191C141CCC0BF4D7A371A8C3389C5A799663709949B17195B4EC74B2DA225002CFB13668F83A1092A6C609522C07529BEA7A454EEAB74E15246AA17452451672A6314E5AA5AE0C57C2AB74653005A8F2B122859C0E8A0829CB0240BC0B5213AC9B035E9366BD3A4BC680D3CC45D96EDD33AFA02C747132001C0CA4FEAA29059AB0C1ACB1979B93C087B53911897B928422D0732E134DA0186794B4CD2E242C0EBBB5A7E10A82C44F874B749ADA0F91C6A26290B1CC49B7BFA150EE40886C9ACC8DCA75F813B13E732E94F85F6908C0523CA70C71A5BD394673D22E4648A443B25DB6DA4EB11C50A8AB30CB342A39B130AAD1A421B567601001B86ABA44A1311F05423A939B3F3404E5657476819D9E406FC265935542B48AF47FA78482C4443697358E784BB72B54B373E813E19186D5BA8997053189B314B5BB8DB699059CEC5FC2D58191B2A729D4A3BCA3AA7B377464939CC8E548A7789E56F67D08C1A0772C9836102321F659FF7B088E9968661609003DB687A295FB2BC6AA593DE4C9CFD6C55D2395ABAB916D3A8559451A6BEA299519654E8C8CBB56E455A85C37CA5A74FBF25252812F16B1B9CCA649718C00DDA596C506BB525159659C272FC1C7B5EC8272DA85D506959B231D1394A71D2C421E743964A58F38D52A60407FB8605961A63FA394431D35641991CB17DA5637732A5ABB2F34B81B7384974030ACD43886021A50B70924606BA1A295A489842FE3D10E92FB1507E240AE0B5616F8AA05299C94301E29A638A742028F9321F3955C61A59C021168FAEB17829025071B4015FA167FB6220DE0B29AA3BE2E88A171E32C9499B9B00BB867DB0C9915384F0A49BF3C5CFE539D22D3B998315CB8D09191634C248495C1977837A7B76C9B35E067AADA829618E4C683C404EA51ADB1A7A116C7A0AAEB995AF1BAB8D0751FBA714957AD6C7A0A9C73ACB8D347F9A9A469D85DD94B1B1E4AB74C94048F9AB578A2BDFCC75A213A65345129F78B26E3D901B3428A0F87952B91517460930386856AE25D00259D58EBBB403621335791EC6C2C6EC50711C07F56714B0ED3753F7459F07B83D1F838CA1875017B24FDC2CA6224B74423842ACC5C4B03D0658C7EED5A713A365CF523C9C2254E9C79059331BD730B123F53538955BC0FBA92FF9388192C950BC46C25339C82E98314D616B50993BB6241224AAE7EEB610EDAACC43ACD775941FD8088E03931F40C999D92360B74B86B857CFC6B5A74367DC72033941C78484031FFF53874308D52AA6FFA3491E0CB98366B8FF2866ACD1AC64B63770BC25BC33531175A4112D7684C01A8C4500F9FC083FE652FF78910B75093A34CADA85947D2602FF0716624FC9617EC71B9E87CACAB31CB3836A022523C3A3BF9F542EC306C22EB815E1038A48CC4F6596A1CB1482C7BADD7390D8DFB1FA01C5C30E458AD31BC5FA717503C0186F5A3B936C2D0AA7197733C2EB708F32B9FF611537773BC38B904CECB5D2BE29C988B22E415C7944726EDE09ACB76175448712F4BB8AE5AAF4498CF4189B0F0332FE774170F343A121071961CA130694B964033BC015F490B85DEA4A81756A95F3526A856327CA68F66E828A66B138C052115C0B6EB910BA703581617299855318BA9AFE6B152CC538836278D781771FA4C033A65AC5630B3EBA8B02A69717FFA1E73E77AFE06441D91CD45289927C40A1425AF113B179CC46C6606CA0EEB0D86765128A726AD50AE8DDC1AED2A07129ABBB3AA67B4E0192DA99D2C36686D3807E0B50CC9E30A82D97B0895B6C7670C01FC214DA38FFC54970D8399EDE259900A081954172F385E037C9B72B43A3ECC7FDB0510F6A930B837618ED756A62A0B3CF58B980C94210BCE63FB9CE88745FE8BC34D57248979398CB0C1C9B83AC979A107C955E97543756221AFF06C553A1F0E764AF19B93E0DCBBB9C327F76AB4BB890D179C90839430A749A2C43A66DC36394FF06DDC54070A2A2F152261E79597AC9B2AD32A39FA489382718E04DA6369C4AA0D4823BE87A60561CF49232C8AA20811EC7B29EC8A90A363F3B367CF9A81A08645C70A17EA41A1AC4C0E9407763D2A91B6732E46C6BA160972ED35CBE6000B7C1B83CA21623859CFB4317306593003B2A90BE01FB5A4030CC062C308C14924CA47A24FA5D13B82FA7153988DCD1077E2759FF250C198ECC4C860170E93BCC48CB009CA7535C62EE2A3AE61D07C828C68D19A55F6A7224F716E77A381E06933AC03A1B0D01B6D231E38D4A19EC9C6E8DCA42C218B290130BCB583F7E958FC3531037716B356948D726E602329A322A410945568BCACBAB75D65DCBB38B80CD20865563699838659E065CE749A6DF66542E8474BD140B50EBB5983F546FB393A0BF10C5891767B935E0F5171CC97A00607332088AED99B13EEF557CEF73429704244FA2B915CC7731BB9BD351FA131A726C837FE19047443A16BEBB02F4A5020878AFCDC72CB780485A793CE23BC6DBC11E04B0DBDA82F51B4327814471C01042A1119D5513408C119266A0476DB89B20B18EBB44A231CC5BC39C6BCFC4DD2A61EF9180BD76327AB05A37ECC4B2E8ABAAA307A6C58040484BF73B06AB4A65F7FD99660A759FA903A56DA3E8DEC389262AFF8BABE1B85168BD21762C86046290F35D51E4BCB8403F160D9DC4E00CA8987E46CE05A5FB04A112EC352B1B03219A4B50345C6F31915FEF4C2EF870D30A244EA4C20D82849628CB61ED677AC9890CB5463EB90BCCFEBAD9FAB23C26A33E6667D76C96220147685EAA84CCC3140104AAA4A559E51209DB124337A2795925C5E0230E7920D4E9338DA23ACCC8693D5952CF49AC26A74CAA6E05011E6385F787A7071CA08C61F59CA017ACBC15E9BAEB78837B99B93908A8CD6D7BD30CB6C23F9CE5E15204E0225B55C120B31C1276695C909C94AA1B5D0C0496278435352B50343A9974A55EAB5105FB4436570181F2B7AE82238CFB9C967F424C1D146BCF74A2349583D36C1F7629E70E0C4702C133F7475985B2DCD923465F39772E8AB76F3634C6A1F6E8088BBB0BD3A050CBF323F9EB76BBC4603617908BE85E6EA5E40A862180D9EF1380B7A859947562EF3A845669146A128CDD9B684F4A0907E80ABE2B7584BE10833A4DAF89DE5DCCAB7C001116B5208FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424" - }, - { - "tcId": 69, - "deferred": false, - "z": "EB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6", - "d": "F8CF49DA62AA762EC020F3766237520E7FDA4CA3AC11FBE50E6C5F9CAB3CA7B8", - "ek": "36FC681397CD63113EF7756444A3CD1FB693BEA7905A507CABA24AEEFC637104C90D311BCAEBCEDB1335AB26C82F255984118B17E28F2266C5D73818D5ECAC6DA8380189196C9568EC949DDF76694A4B39145758FE66A14301CD64A10CCFE46C3CA8419EE5766160465154680F8C435DC523F5136065555F503883165A525568878EEB4DC675445F300F50A1C42EFBB5F1C9A0A46684414CB4C8187255A2CBAD4321082698F2714F234678D4418E33A70CFD76313EDBADA57C82C65801C0DB89D4F7BE19857E31E16ADAE95F95CA0473082F7FAA0855723B5AE4186A6C26D482905C00689D1737CBA52583893995065B5C76C7FC7839CDFA9BACF1B8F7A68307B459CA96BD7091A06A83AE3F3146FA81296932291B2158E9B09EFADA0A2D5AA8F1DB2489E40E04B0C768335595960CCD586B78844F0E940F2007B3B9EB9747254D83C58443C2B7A347B86FAB1ED4354DA2D9669AA21DC2A938E0FBBA0EB57E4CCA4C2666B79559B70F9B61DA060E03C59850AB2D129064F8D6ADFDCB7C457235CEE9473B003DDC9252AED7C444644832A4AF310C431AB26292488C73C38BC03550F7569909417041E2924AC9338ED8251BF6CD18F2B9D1569FC688AD095A728C574AB8EC549AAC0ED13A6EEF5AB87EE622034CB87045997A6657AED6439AF8951946ABC47BB9BBB55A80C92F40E126D78B4353538B6995830044B6E7220030861E47A5CF0291BDCEF8ACECA5C9FB0B43901CB6CE99246D2A2CFBEA014F902046836CB0B58A6DCB79CB9275519A3295C134289880A0D6CEB91356428294AB0B11CA150B9E362872BC8C25E2A78748C9D245C2D36A05F9D87CB5D0C306A5C0DA74AEF98BB1DC45801B4B9EC5B73A0ABA407B0AB8065B23B8345A6147A258326450E399BFEB86E754561F09CEFD1C832E355939175A347303E0D7815C4056F862B08F7914051834423972C84010CAD31B34321066396D47D5C9A77B9F45111B93988C0692039B5A060805AE4365AF1F8B138CC83F2D681F740886C7F07CD153989DEA4A6B2A3597374F7D5BA8E7D01424BCB721071A59FAA49F74AEF15910E84CC138F09F31574DF9A7000175C80073A10CBA6ECFCB84FA680131B824241BB96FF17BF76C0243A03DE9D49895D640E841A07C2299A7C52E22D37C8EE1AF81847781BB2F25240CF91851A5634AE285825C8809C716B6DB795361CC374B87BF34687E18EB413D21ADCEA883D4837CE874693159BDD2920405FBBBE6674F19D0B3C3D6B6F4095A946A5F7E6B0C5B7252A8F72EA357BAEB475FEA0141621A607324B4B17AA13FB7AF2ED529E1728F4BFC083198628DE3C8968A9A92C8863E08AB34A00EFDC73EEE7A8F29F4906E848B8F56474DB2BDE054A660966C955418E8D387CEF43CCA3B5DFD949E91AA5D75C50C38C96BCFEA7740147FDCD8406C0536325A1B74576392EC1BB1B181D584AFD841B43B0034ACAC33416C8DA02777E1169AD4045CD51674342C468874B16B12CB13776E6E8C702D84C5D13933EC161EC10B82A9F339AB3B1D1A9519F342506A3C0E7DB20ED3D7029CE444C5FB4FDB88525AF4C565DAAED6A51B7776246CA880D0F72D5A40B88FF348E9677B37D19F0088997F77429EDBB63840070D71A60FB34FA5CB59F47B06BB03C3AEE80F393A9DE283604635411151222C696FA6401783431E9690BB8958135537332EFA805ABB5D69C9C8F9084EC38862A68082266CA6A0C3514A71727AB519C359CDBC663066FAC14600132D1216BE63AEC0CA96804096D22904F4194D87D35C6C2C0D5539C93BB909A5287C64DCC1246A48CD9CCD80311089CA694120ABFD5A7F16D06A0BE42C48878BE76253198A703080A463053D43867B73B67B26B99A551A3C0C41115D007E0EA0AEF1446FF88BA7FDD32261FC0776FC427C121B2D231E3AC843015B12583777CCD5AAC502A7FFF9B03FB614246848742342C2E0A871E1AD6D44847D0A5512566098C712AD89904EE051425358CA5A964643577B8C8ED09450E97B55F660C2F2F608FBD87CB59585FEC3218219B1C7C18200DD446402898E065879FB17C97914C1E83F262801A4E256E798598A176BBE952149F8AD5B992CE791559CE6AC90539C096A209B9A4F87AB73E158801EF2B939A511F416BD4DC195D406A55A66B3FEC2925C5474525026488ABE90196230EC15B09CC55CE383DA8ABED781DC5085BC8E58", - "dk": "67973C3154342CA60AE94B0B60FB2CA4DCB70BF13BBEF7CC9B54790AB3CBD882385BBC888321366F4AABE4696D0126B724A3AB8FE40E03137A28D1B9DE280C49342B162196B13C364FBC5E26651702651A15369F1B83A25B945BF7BA7259A329F107C91E13802B0119CBE59C463B3A53B51837683A6E75674174210A871A1F582A6AF0053EB862BDDB6FE53B21924A7A783C4712AC5A6A38062D83A31DDB6537A82EC135616947A7D6456DB50C95DF678B113275238A1A8312100270A730435E06E554268921A04A9B7FF5025884486D817D4D81610C2805B4207A013A4E4B785CCC0052F70318188380FA554E41A64BE315B3294C3EEAACBF46DB8C87105DFAD68575044F59CA15A379579D381ADC65101FBA2EF3CB2F4A02BFEF8A5B28A51A2283979CD45B753C06D3653B9124A04AA64577562C34DBBDC9A5AAE358A5C73259568A3B18E48EB536C6ECB05A00DD727582B2F51C5562D53311C09D26218DEF54455EF86066B76CEBC41584173472A6008C55C94DE4261116CB21D325B514C83FD07C49C30967D23FEDA60CB9373AB9CABD3D528A99E6898E7A6F4E4C9644022060C30757F5AD961369D537551312172ABCC1C228B9F4F642C952006D7C45C40CCC96FB7BD28731A2F277E7284375D03A35F68101278E70AA882AD82940EA1E1DE9616AE99EAEC6BBED52B1B110502062783B102297A144A54C10F43B2D4C529398EB0739DA57F183B195A39E3178501C9539355B8E456760FAF99D5C3C55B1AB3CCA017C04B94581B18AAD4594236456A02B4D99A00412F818D6EC1387680847D10539E0C063A334A2A86EE1794B49DC895EF95C3D801AB33748417C8F60245E69A8AB68C9BD04BB28783293C52051F9C5A532008CA9C0063FC77519709F05358BCD28955C4A9ED3D9319E1939CED04AEF489C0EF2AFF1EA05FF2C8189093B14C6917ACBA94A8C546063B2FCDAA6C77C1A424A81F3717D9DD88C7A3C64FC593AD66748523744BECB2434822F23632D6E362E5F38C6329958AA20096BBB4FE4F43167301D57332BAE31110E186FA5C41597B92922C79CCE8C59FF341A08E56CF7A1B610605D910510DC03308967CC7CEC7A4328600C601566D8766B601855CCCA887BC84ECB05AA1529DF77058EC0760377BF8E3AB30FE477C33594873B59F02CA226966DC9841569564F9A5557BEC87C2C81784664CB2C8A0770C7C15DD61F48B762CAF11E9C189C9E9947D788A13FE554E76CB14A631440AB2560AA747B447B08E20A5C8BADAD31BD79FB27091938C4EC7AFF409E69730E152048D540958458C219C007FB1A7711D9401B86A10685A66E3C439C005563746221F50382825E3D6A779E692022B2B98150B690723B8ECA370283611ACA06B5881F38A7757A38A25EA06FB5176788C68C01D33822DC9CF7248CB81B7511832845CB06FBA36931CC07BDE6BD299A69A18945DF4057ED724292B76FC1A4432C1C16F451CD1BD796451957C5734B90574D809B69A9B19F07837028C97FC56B10CE6779E81CC4B4714A34A254A1100CA2044399658DD878BE873036B8639609786FEB608B5134A79FD74EB3D485F1D44F39854B3C6552965B4F08F998DFA4721B6107C20433AF509FF0E571FB58B8AB15727AE24AA189CCAB216953F72899D823886364994CBA31EA12AEE12B85460D056C761024987F7683B40A692959513C346E3674CA736226A748345D5931D3250949DBAA2F5BBFD7361E748A6D69419A24D3CCF7F7A849A4301497A2BC1588B021314B0784ADF1C5D01B562B89B3863A92D9103638CA305146912A3588F3A6A816224686268FA692031F427036043090A6B93CA944B4DAB10B63421E69C948619229D6323720C773B900A8393BDAD30547E0BE24D26795DAB3F1806779FA13B1A09A4BFA93BCEA34F522430E1BC923E378EF4631BF76A0F1D3B6A6D8BDD6811293F02CC2096C0257A957261E87220169330BE5559B48698EECC58D151C50C85CA19C9471E7754A8524A8C742495D15365189A2156046CD7A916C2816D9F1626306C6575114703091CC7721CB848CA66108746B1C10341BE8608FAC87B869519ED8C6CDB0530EAA6C801110B8BFB8C4C0184660F79AC2485BEA7AC2A2C3C683D483113C8B5747309FF1AC459CB83560C8800502942B09D3870036FC681397CD63113EF7756444A3CD1FB693BEA7905A507CABA24AEEFC637104C90D311BCAEBCEDB1335AB26C82F255984118B17E28F2266C5D73818D5ECAC6DA8380189196C9568EC949DDF76694A4B39145758FE66A14301CD64A10CCFE46C3CA8419EE5766160465154680F8C435DC523F5136065555F503883165A525568878EEB4DC675445F300F50A1C42EFBB5F1C9A0A46684414CB4C8187255A2CBAD4321082698F2714F234678D4418E33A70CFD76313EDBADA57C82C65801C0DB89D4F7BE19857E31E16ADAE95F95CA0473082F7FAA0855723B5AE4186A6C26D482905C00689D1737CBA52583893995065B5C76C7FC7839CDFA9BACF1B8F7A68307B459CA96BD7091A06A83AE3F3146FA81296932291B2158E9B09EFADA0A2D5AA8F1DB2489E40E04B0C768335595960CCD586B78844F0E940F2007B3B9EB9747254D83C58443C2B7A347B86FAB1ED4354DA2D9669AA21DC2A938E0FBBA0EB57E4CCA4C2666B79559B70F9B61DA060E03C59850AB2D129064F8D6ADFDCB7C457235CEE9473B003DDC9252AED7C444644832A4AF310C431AB26292488C73C38BC03550F7569909417041E2924AC9338ED8251BF6CD18F2B9D1569FC688AD095A728C574AB8EC549AAC0ED13A6EEF5AB87EE622034CB87045997A6657AED6439AF8951946ABC47BB9BBB55A80C92F40E126D78B4353538B6995830044B6E7220030861E47A5CF0291BDCEF8ACECA5C9FB0B43901CB6CE99246D2A2CFBEA014F902046836CB0B58A6DCB79CB9275519A3295C134289880A0D6CEB91356428294AB0B11CA150B9E362872BC8C25E2A78748C9D245C2D36A05F9D87CB5D0C306A5C0DA74AEF98BB1DC45801B4B9EC5B73A0ABA407B0AB8065B23B8345A6147A258326450E399BFEB86E754561F09CEFD1C832E355939175A347303E0D7815C4056F862B08F7914051834423972C84010CAD31B34321066396D47D5C9A77B9F45111B93988C0692039B5A060805AE4365AF1F8B138CC83F2D681F740886C7F07CD153989DEA4A6B2A3597374F7D5BA8E7D01424BCB721071A59FAA49F74AEF15910E84CC138F09F31574DF9A7000175C80073A10CBA6ECFCB84FA680131B824241BB96FF17BF76C0243A03DE9D49895D640E841A07C2299A7C52E22D37C8EE1AF81847781BB2F25240CF91851A5634AE285825C8809C716B6DB795361CC374B87BF34687E18EB413D21ADCEA883D4837CE874693159BDD2920405FBBBE6674F19D0B3C3D6B6F4095A946A5F7E6B0C5B7252A8F72EA357BAEB475FEA0141621A607324B4B17AA13FB7AF2ED529E1728F4BFC083198628DE3C8968A9A92C8863E08AB34A00EFDC73EEE7A8F29F4906E848B8F56474DB2BDE054A660966C955418E8D387CEF43CCA3B5DFD949E91AA5D75C50C38C96BCFEA7740147FDCD8406C0536325A1B74576392EC1BB1B181D584AFD841B43B0034ACAC33416C8DA02777E1169AD4045CD51674342C468874B16B12CB13776E6E8C702D84C5D13933EC161EC10B82A9F339AB3B1D1A9519F342506A3C0E7DB20ED3D7029CE444C5FB4FDB88525AF4C565DAAED6A51B7776246CA880D0F72D5A40B88FF348E9677B37D19F0088997F77429EDBB63840070D71A60FB34FA5CB59F47B06BB03C3AEE80F393A9DE283604635411151222C696FA6401783431E9690BB8958135537332EFA805ABB5D69C9C8F9084EC38862A68082266CA6A0C3514A71727AB519C359CDBC663066FAC14600132D1216BE63AEC0CA96804096D22904F4194D87D35C6C2C0D5539C93BB909A5287C64DCC1246A48CD9CCD80311089CA694120ABFD5A7F16D06A0BE42C48878BE76253198A703080A463053D43867B73B67B26B99A551A3C0C41115D007E0EA0AEF1446FF88BA7FDD32261FC0776FC427C121B2D231E3AC843015B12583777CCD5AAC502A7FFF9B03FB614246848742342C2E0A871E1AD6D44847D0A5512566098C712AD89904EE051425358CA5A964643577B8C8ED09450E97B55F660C2F2F608FBD87CB59585FEC3218219B1C7C18200DD446402898E065879FB17C97914C1E83F262801A4E256E798598A176BBE952149F8AD5B992CE791559CE6AC90539C096A209B9A4F87AB73E158801EF2B939A511F416BD4DC195D406A55A66B3FEC2925C5474525026488ABE90196230EC15B09CC55CE383DA8ABED781DC5085BC8E587FE45A6DB8C05EA8FFC788FD2F73C26CEF305BFBC9BF7C5B32466B5417DB33ACEB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6" - }, - { - "tcId": 70, - "deferred": false, - "z": "DAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF", - "d": "08E36AE8586A59B8249A80D7F43506F9711FA4B00A49D182CE06DAD0CF985809", - "ek": "3201469EC68BC7EB2BD457769C69C09F1646DA20B3DB7A8756962DEB905FE387084A58B069901A9FE1A0939C38E6E414E23B516FD0651E174DC0F6388DC2CB8D605D3D5B1F6AEA3425A03B9A903C846ACC128C87CD5A17A46BB474A0BAB64112DDF1C35355C58164B7C6F9B8A5879CE8E1CEB4FCC26EA55E4833A401B54EA5C29D92E03A8FD5AED6C51E2437C7A89221ED73B2BA3BC5DC30276A0692FFFA3E28B8CB9025566D54A3DD84A9004730B2009A73B354644045B44224D9D96B6A137D8F61513BF8555FAA8F61F00215C8C8841091F7647E53055E6762A504C121474120BC70BED5C4102C82813AF656B9248ED6F630BB269CEE33AF26D474C8B3CDD8D959D10A5D2AE221D5C20D9628A26F1A11EDE680F8C8333A54AF8D79B67AB0BD9DA1680927B0B31B1D6653410C4CC0C6E95164C33506D8CD19A73E1031C733C55EFCA33F76BBAB03182BAFECBAEAD364CE38B22B74A0A244A15725B232616EF2CC0A3010758A698880A23FD58BB2199A3946F5CCACCC2D61AA5985488C0EB60D465566B94C762057ACB163CA636B548254C26F139F51A96E492035B9D725AC16B94C537E2FD78B1641882AD20DCD6C5BB21B79921A59631130E7885340F5311F9973CBD31783DA443BF7566AB3BACEB88232F83E7077845061C09D425C7AA01733CC63D5B7C17C6B3309408D1FA31AD909BC1B0AB6535B0AB6064722D847B07811098C7316071A751623654605FA453FDDE8176B42B2ED07CDA4144640EB5984B301390C64D520071F1C66AD69C550AC41D74915DC2156F78127A704CD678A655C87CEB43748F0989AAE1730D3E4B3374A72CE364F1E2ABA2E5CCEBBA440FDA8AD50A749FD908AA1578C02B35342BB96C3350392C5C25CD71093BB2E87A3A466B697489A3C9E9C84805160A7396D001633EE00AE5641A893BB374CF5CF62417AFE67682C08A10E0A59B8346ADD006F2B40669042616D57936593A62D5578808A1E9D55B1EF4C90EB049987DBAB69B3C8C4A596901BA2BFA74DD4B937547A82B7F5290BFB79E5651B2B4AAF3692CCFBA987D5EC778E61281B0B388A71222DA27A90776E66BBAD25118AFDAC425F15599176C5D5F1B491FA1FBBD9005A0AB93AF1C8280292AA468FF0B1218726C52E4AC8FA403C91D12EB1134D6B08ADEE2A065F191DDEC390A1232D63306AE1C60AE1908CA2294ECAC6AB5257644DA45D70E96C6FAA5E1DD02AEC276C5EE2A8D36A2A13EA21359934C8285498370460CCC2A4C886C72A9FF17AA214553F6826177630ACC2F70619D64CE3F04DF17A6599E9AE5D2BB97B731432421012FB229124CD52BB9E2EA7B33CCCACBD9029A69AB76F00CE84A0C0D2C80F54A77D6064AE85465FA74271BDC2C62CB940E9C32A67F9C94AFB7322B93016E31C4E34993C7A65D58117495C44A8EBCEA635AA6C29889F3AB1E39661925136A06BB269483C1D291F90478713A91A178193B25877D416C03242682E76071B78964EA626C6A85E4ED8A45CF573BE56369B9476A2FC76713AA11573A083D0A0B89BAC15228A42B9BE2F8617CF8BBBA21562FEE3313066A8E86063EDF365799B7EFCBCC11570196B535D40F65F59C0972E057E2C70048CC10DD292611028277B325791B865B9D863972AB1725B6BF1546DFE0030CD85621F92472CB0064CC2CD11411127231181E6745A3580F6E8383150C8C098A3EB455F5CD05725719D0F844BE76743F7D962261A5FE5C29E46D58EEBCAAF0C40C04BFA43089C6236AB1AB574CF28A9178A4634C5848259191C21401C05A00A48D0420BB2737816CC72BB3D5BCB5EABD5531ADBB2E875045E861114D2C5AD5997B104A4F3BBA26A6372EA6062C8D6229C196E5B7A572F898D94A307BA051F899C16A34981B818034CA84A14930AF2D38BE095BE4B304FA1BB69DDB72AD605294BD273FD314A4D1940161B97626B5C725935D358153B4A1318F1273C7C6A93FCB372196593D9655F3C41FFD4B7B72B7131D7C2607A8763778556EC2D3E09969A4C968E92240077051446375B2C4C9BA9CEE84563C4491673667C026843C1602A9BAA0705E27918A27E2B01B9E756A77F7A304345117ECC52E81823A0A8170086B89EC64A39C60EA6A78363FB79E7C0B886B1854C5A929DF98077F5AD847650926273A9495000E688124118F1D83CC93D0E4D2565D307F4CD0C166E9083E8CB47F6979CD0C6F05D5A", - "dk": "6F148AB8F31718811FA8326B85A430341A9CB4827004D5897659554F661B37551033D7B51D416CEC7921FFE4711A575BA6EB73643B78856B9C230768B6369A9D9C7C91B7620E4A709D38A73CD7A2CE48712EC03F0C94070B783A4EB3186051A56D469D01152D3799934A69C672600E0B223740F937607B8923768B20F7CBB9712BFC633654119B7299770C764C471399BFF2CE457918F3C3AB3A323CAB53BE1F491EEA526EE95C12A50C2A3D8C75589BB6919B97D37AC96753ACBE493109F60957E268F8CC27C497A89C12CBC7109CCDEA54E174B7AB6C4E9D68326261280D582DF8E976B2F67617B69FD2D58CFBC44F641C9598B293182939D4AB384C6B7920266E6C7BAA133A1A9E841AD0018ECF6010F0D292D7699177864D063641EE8BB1A2C7CCCD7C33C5574E9C499EE9E7417A5C072596C4FB76C2E56950B0907BD653B47966420E866FC3FA367C965A1D096FDA16C3CC1CB651DC693B960443617C58D13FC2595FC267720BB88D0633579BE84DC0232D973AAF92140B20CAB7D4444A96EB6A4235C0665460470994D94005B659BA5A6A345E51677402B69D378A0444B345340BE80230C7730F4342833543BA8079692333128E45B9DC48830C1892E69AB37C632771EA677A47B1518815E4976367888AE552A397576A6838B26426A587828B08EAC520E47463D00D1EF5CDD50838A961832647561BA75D6B1A5C93121949C46CBEE11938C5718013724131C18B0BAB806097C14445FCD303BC8BA3FBE2C0AA2C3FE45A74F5E22F77D6B405A962B1F95CC1E0620E6239AD57042E139955C97C359B09F6990D1C7747DEDB6F02313BDA02839AF16D7F181BDBD3245B272988432B35916144BABDB7F3CBB8A4575677484822B76739577CF945FC944C21D4956B0B2E3C86195B5724A03A896552BEEF5804D583BA6B2B9A67106A47621DBF911E62F677F933527A0095D6F4C0D5C3392548C23584CF91888A51269D15606542E601D8A7B915418F164A6AFEAA7AF60345D7A603A018838237861EF1C99194323773A8A18591F7539821D57856C44D3ABC334D266DFFA64AAD3B56DD7C7B1ED2B5026142CF508D9F25A2CA6199F7937E6AFB66B1C486D5512F1F12754ED5B70871160B8814986C078F006962C956404B6E5EE9C486E786C3C448B902B1841697F1208313F8543B40566E18746EF181DA1195711040E7268CC474A1AF4388A8FA11AB9A54B228A92E569415D12C06B246F8180F4B80395C708089DBA946B459ABB598F6F32708B8316AA73DBFE15D231C2D69627D434CC1674778B4FCAF23227527B2966F0718AC1C9D6D3B374829C46D063A4794C15A189DDA693FB6C08E46C0B7970B8AECB8B52EC35428E8826CF6B1FBC9A988E13ACD089E4DB2967DF64DBCA475BEDA31DA74C3BEE4BF74568EB257763C371BD252A525AC3325941C62EB68BE79701C11C18EFBB1DD010F84BCAF5EBACD35C67671C968A6B5098E0535D7932002EA7739C85F45085247032DE8EBB7109B9A522112DFB89C2904C1B611AF46762E4854AE2652B4A5580B6D902C12788E2F6C72A59A0A5C4385CAC77777C64D9920A5827568734370E891A2638AC12BD164C15C01A3DA0292F325DFA4069068329DDCC25A3964A845694DD6AA99F17AC9C12DADB4431C8707949CBE2E4B9764B65BAA0451146725B6A7B6CD6726E819AA8AE2971E334A66B0501F210C0A1975110BB8647CC8299C2F7D4C16DE4791B25A36B2592E3AFA0D059B9D4B3B50D9981160C23EB96BB1EA0A984D922C1D31A9C105CF5CE64D86222A12773E7ADC01C99B5F4754610A2B3F24C66D8E3212B8584DDF7B68128B215C600336409733049A54A719D0E5A657AC223136B1C9FC5D3F33545A051902AB0FF4B1CE5DA81BC8B3A78EA40828348210F953250211F85C1F3196418A32CAC6158850EA8B44A0CB72EA5C0B165DA1A0751DA41D58514439461942E478D3A3951E3273F35B938A842EAF331471B9B1417672DB5CA82F246B937448A08AA720060C5F2BC084D3157C25CA2F2BB02E2BC4289466C8721D7198B01F92C3EAB020BB92B318E78074218A48180EE799948501B84FDBB447FB009436CD20A69378E4BD87831630329AC0D76460E5134C60561180274E8C94B64C5F17BC4AB39625B49A13F1887B9AF06E3201469EC68BC7EB2BD457769C69C09F1646DA20B3DB7A8756962DEB905FE387084A58B069901A9FE1A0939C38E6E414E23B516FD0651E174DC0F6388DC2CB8D605D3D5B1F6AEA3425A03B9A903C846ACC128C87CD5A17A46BB474A0BAB64112DDF1C35355C58164B7C6F9B8A5879CE8E1CEB4FCC26EA55E4833A401B54EA5C29D92E03A8FD5AED6C51E2437C7A89221ED73B2BA3BC5DC30276A0692FFFA3E28B8CB9025566D54A3DD84A9004730B2009A73B354644045B44224D9D96B6A137D8F61513BF8555FAA8F61F00215C8C8841091F7647E53055E6762A504C121474120BC70BED5C4102C82813AF656B9248ED6F630BB269CEE33AF26D474C8B3CDD8D959D10A5D2AE221D5C20D9628A26F1A11EDE680F8C8333A54AF8D79B67AB0BD9DA1680927B0B31B1D6653410C4CC0C6E95164C33506D8CD19A73E1031C733C55EFCA33F76BBAB03182BAFECBAEAD364CE38B22B74A0A244A15725B232616EF2CC0A3010758A698880A23FD58BB2199A3946F5CCACCC2D61AA5985488C0EB60D465566B94C762057ACB163CA636B548254C26F139F51A96E492035B9D725AC16B94C537E2FD78B1641882AD20DCD6C5BB21B79921A59631130E7885340F5311F9973CBD31783DA443BF7566AB3BACEB88232F83E7077845061C09D425C7AA01733CC63D5B7C17C6B3309408D1FA31AD909BC1B0AB6535B0AB6064722D847B07811098C7316071A751623654605FA453FDDE8176B42B2ED07CDA4144640EB5984B301390C64D520071F1C66AD69C550AC41D74915DC2156F78127A704CD678A655C87CEB43748F0989AAE1730D3E4B3374A72CE364F1E2ABA2E5CCEBBA440FDA8AD50A749FD908AA1578C02B35342BB96C3350392C5C25CD71093BB2E87A3A466B697489A3C9E9C84805160A7396D001633EE00AE5641A893BB374CF5CF62417AFE67682C08A10E0A59B8346ADD006F2B40669042616D57936593A62D5578808A1E9D55B1EF4C90EB049987DBAB69B3C8C4A596901BA2BFA74DD4B937547A82B7F5290BFB79E5651B2B4AAF3692CCFBA987D5EC778E61281B0B388A71222DA27A90776E66BBAD25118AFDAC425F15599176C5D5F1B491FA1FBBD9005A0AB93AF1C8280292AA468FF0B1218726C52E4AC8FA403C91D12EB1134D6B08ADEE2A065F191DDEC390A1232D63306AE1C60AE1908CA2294ECAC6AB5257644DA45D70E96C6FAA5E1DD02AEC276C5EE2A8D36A2A13EA21359934C8285498370460CCC2A4C886C72A9FF17AA214553F6826177630ACC2F70619D64CE3F04DF17A6599E9AE5D2BB97B731432421012FB229124CD52BB9E2EA7B33CCCACBD9029A69AB76F00CE84A0C0D2C80F54A77D6064AE85465FA74271BDC2C62CB940E9C32A67F9C94AFB7322B93016E31C4E34993C7A65D58117495C44A8EBCEA635AA6C29889F3AB1E39661925136A06BB269483C1D291F90478713A91A178193B25877D416C03242682E76071B78964EA626C6A85E4ED8A45CF573BE56369B9476A2FC76713AA11573A083D0A0B89BAC15228A42B9BE2F8617CF8BBBA21562FEE3313066A8E86063EDF365799B7EFCBCC11570196B535D40F65F59C0972E057E2C70048CC10DD292611028277B325791B865B9D863972AB1725B6BF1546DFE0030CD85621F92472CB0064CC2CD11411127231181E6745A3580F6E8383150C8C098A3EB455F5CD05725719D0F844BE76743F7D962261A5FE5C29E46D58EEBCAAF0C40C04BFA43089C6236AB1AB574CF28A9178A4634C5848259191C21401C05A00A48D0420BB2737816CC72BB3D5BCB5EABD5531ADBB2E875045E861114D2C5AD5997B104A4F3BBA26A6372EA6062C8D6229C196E5B7A572F898D94A307BA051F899C16A34981B818034CA84A14930AF2D38BE095BE4B304FA1BB69DDB72AD605294BD273FD314A4D1940161B97626B5C725935D358153B4A1318F1273C7C6A93FCB372196593D9655F3C41FFD4B7B72B7131D7C2607A8763778556EC2D3E09969A4C968E92240077051446375B2C4C9BA9CEE84563C4491673667C026843C1602A9BAA0705E27918A27E2B01B9E756A77F7A304345117ECC52E81823A0A8170086B89EC64A39C60EA6A78363FB79E7C0B886B1854C5A929DF98077F5AD847650926273A9495000E688124118F1D83CC93D0E4D2565D307F4CD0C166E9083E8CB47F6979CD0C6F05D5AA184CD5ADDE3E9D68D66C7AD3ADAD382D8642BF03B85F068AEE861FA55B6340CDAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF" - }, - { - "tcId": 71, - "deferred": false, - "z": "4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99", - "d": "A491FF48028B67A407F1054D5B1CBA733B665DE667E22596EDCC31C227C2DE1B", - "ek": "3563BADA724011CA9F7154964DB8092AEA60242B273BA94ACD33B61BE47B5AC2115E95BDBE56B214E04166356496A698C81744C06B114E2B37CC441A9AD8C90B936E1D86B9E1D9B17F352B393B9A1DDA0FEBC548989C12C120C7988A460B151895961733F84111058116C427E75A8FB6798B9691626F7A5274F46BCF5A160F0BC59B01C5D5E634EE9C1FD5D665AB59A4B495030855C538C86BE779CCD8CC076D83407A5C9AA3757841DC30F47592233A3AA8F3A721A5902FF8225F51764D59087D5B928E34572C23C511E236ABA0CD710A7EA0FA0CBA999F22445AF63CA783205E4D935CC9304BE9E92364C97993A1BC4DE491C5ACA2932575C99153A0BAA814644DF6A4922F426268EA1F7D97AB7629462F0C8465900AF523CF2FA978CDA56F4FC936BDE529553B56735701FAB3453C1A8ED0492222022E7C799EA11837C952CFF9A059992B26CE774460DAC2D23803A913CDE96662CDD78B4842A09E3A09A8D6A5B4052A25D39F63A43D9B9473FF184EB9B49B78B7165C62141866C2D4D866232A952E89CFC422CA5E510390DB98DE3A5DD0E3728BD5076656941894BD2C85C1B4FC400A9365F744B7EED6637C694D7C3104329AB526193E0CB2BF5E9B8E5D34630C16B097EB027C33621F23BA78E4470DA48354C29C114C242EEB6C62D15395D40B716A6137CB5B5AE2C27CD49D176B5D70416E254753F1150D5D8807F07916330C69B5F236F0672709834523092746897CE489B3FC878FAB716042509AA96BCFB839544449280C7C1CC3F79A22A25BBF47A33228CF1CB619E2492A95EA5F3D12C80BEB2412B81D6EC7CF6147287FF36449205CAAFB3625CC0A6FD4AEE3898D8FE56F62B06F6A7B7F1325B83A30B72FFCBFC9A672767BB2659B1B6500B4A3629F00286B82F9597E6CB21FDBA9AAAAC5F24273B2AC22EA4023219C7B32FCA7694693A2208791E1AC33C00C0DE64E2241001DC04249CCBEB797A1C38CAE3DA81C07364374033917A04AF6A19BE424C07DF33237B9223B7C04890CCB57780126B9A68AEB5783993F6C08783DC254B14482AD37AC90609BF3B0CEC7B39DB4241E0D9502DB60AFAE068749A295BEF8AABF861EA1292542927F6DB939AB7365142A37962A46230C37FB9519642119E03C45CEAC2F0B40198D6211758346E2FB284FF807A4C06552D7B8DF604D2EC771D2F74D0A258261280C60E71C9FE66168DC9493539EC1F018A520C02E6B8562C55831C18900A1C55FCC6A772480BEF2C75322C1CD116483562E6B7A0D16D351E2BC58032B5267325183148CA61079B2E8A8AA293863E0946D6772716053DF4A0260E3A36ADABD19713B46E89ACD650EA7932050724356D1261DA37916E85BF552C8AA628ADB08383781245EDA4A82E27D099496A26B5C893927DF02BEA47742B3C40B0E31B5D621012D1BC0F3B085E5BA6228E9B5E875901F1711CD12516EAAA4FFB16AF44AC384E0AB5469B222666FDFE32B1F5A4F3C0C022F6B4ED770572DB6B9B7FB715CEBA1C0EAAA19FB2361D83DD2465375A2BBE2793255619592A6044B71CFCA2916B0C6C895A38D7A28245398465432878D96446BF71A6C21C0A62500B030BE6B528646C860AEAB7B28FCCD87381C61D7106B518E22A2A03F5B7F48729A50672A4B039FB67B9DB0A803D304BFCF83782BD5A10250A8C8D96A9EA993E692CDE5871C6BF79FED564C5834634B88280D3A4CB18025E332532BC65FBC169DE0308012C08A581A1A5C9B1A89C75162B990FDAAA768A35DBD9ACE608981D589116BC45BD7D49425C7B11B573B8F554976152C9A17C273E4A3CAC15D5DF6724C1605D9A77CE487438248178C10486FD7C7E1EA52BB5467B066245560A2C4523B53304445F956E968C5AFF602B7F9378CB290BA0B4707841D175C01AC0BBEB18435E03850FCA479C1E8B7CF0730A5F23690F862C1970A5E9A8DD3F51E0655B2CE7BBD4B38264929C9499BADB505625B7A7BF260597F1239176C4892E37C3EA0770068C49E14A8DCE526D64791B6E3A1EB70A8FDBA17FF8476CA5B1BC9FB533CE7B1F0373D760AC691DC598899A3798A0D6F967699CCA69420116BE625CFC8C23879215C320B354412DC7311E21A3784A3445134977E995282033BD0080B84487BBF23A499CC1D17172BD029406523707B671E25F9DD605C8473C42FB131B08A1E33F1E85055C2DCBA8B2B04F9B8C07D906384", - "dk": "385CACF0957318BCCDE555CB6933660544AFDAF8BC43D4AED82135F8CA2131201E03C7A42C7875EF309F227684284275F590CAB8078AA51AB95A133BFD9910AD0218260309CE43360ED01926D13255D37FD837462FC685F64350CAD95F9B757B56C79564C57C10B31F25514C570C1EEEC1223AAC91353971D915635E3A0A8F4BC5E1F241B3F31F457B3984CC160E13AB6C46B41808CB067C8396D4425FFA0C2E208E95522D65D0583FE2C50F40C9888066CF3377D494BBCCA2CF5DB55ECF711AA48ACFD6F859F859992E5B57C9C56D9430C6360B076A8C0EDDD544F8BB5B7950A7DDC006E705597FC08AF695AF0765331CC8913D8944EC4262E195B6FAEBCE2A3B7472D44A320B1533AC3917FA8DF7283D33E999DE4756FD37005104C8E2D50C4356BB35A79C021C45A05C05B10688F5A53AB52255D9B6BF8FAA036F09923AF89CC6F66BDACAB817A6C9F88B2339170FDD478A7C674350209C2D0773A413134D9709DA988F743134FA89AFDA3C94C4F75DFEE2656AE2312DE6A42A0B43910A4CF061922456346039BB4AC466B8F9AD7867103C165041220C23F09F264383D183B66C7BA90B93BFF8CB9E736881EEBC21917AAFC9067F8814C17AD8A302184FEC862083D1B39C810B92E3CDDF937773CA9EAA2C342014CF4652A5E5D2816AF4B9586467CC702A4AF342DB0B5908AC2F9B0C4490A8962D011BCCEAB20EE46DE2B6B08D473D79E7A10AA52211191784551E7B289C2FC85318017844674AED2917B3ECCA9C814F9F988CA8A927029AC5A6E8582078220FE44AB8A63EBAD736C4496D726BA3A1B422F1265212503B686A5367279E9661702D21887AE81F283966A5C91A8638C63608CBB59CA80A679F2ECA74D828AB15592A15070CC6915D8B6A1A6CD13723D410276B6F6644A9D0610869347386012340A4C6B1207B57903527C010FFC1C8B59599DAF124999CC4FAE39164A5868107C198519B59FC38E1229021A901F569A009987D76606A1F66C88FD88AA4D552E7C277510316DAD731727928FBB4495560958042773E1B8252BBB14F3328E5079E2206743BFB18A799918E241AF3A808155262A8F9A1CB46C60696763AB1206666BE2659BD1C78B6ACA15FB1F823C6E15A70930D21BC07F306094715A62805C486513837C56F332B97CEA067318C0C8E222B5762968DCA48DAE6C8297C2FA322913EA947B06418096C22D1EC3F2CEC48A7F850BF01B5702A8085108FA53127DE0B949E6352365336BEECA65395106BE79AAA91623931828436A67C0C3917160837532E0949503F7891BED485B5056B211A1E354105E3661AB7A1BFF354BBEC695204F2A8EF55073FF27A313662C1E7C7F4E8AB46399D29E2BE910425CE92976B491A1696CA56827F4571C98B328046269379110A559B463F1B9770050F1750262542A6C6BB728B4332C555CF45468795F2884F10303E212D333A0445EBAC52D669DA8B1BC3033081D0516F01CF22C5BE8CA020C8F671FC27A71A518D08B7A2C1C3AC62D874293A1D33729626968638C85761E78ED704CB86F054BE86C35F6A5233253C0F097B34A557C3A0B7B5D16B0266718AB7BB5DC27AAC3A96BD0B807BE5392FB0C6804739800206C7287C130B2A77E5045D5491FA50C1C68629C538078A3091E7B967B4767C3758A9A4E871C6129D78F0B9BC7963CC110641F7C8350A860B611C3DEC98FBBB8FE4F40BD10BA1F9F6C7061B12E7541EFB527B8E4349469987E4FA42D8F4958D6243A1C032EEB5860DD0BEC0C9A1E4D88967B748BC536020524BF5D06C594199DBD6B6CBB795F64B0F6656655B9B36B7E84316D918E094078D1C4E03C75617197306192338747E32F46551ABC23E74AB757B12C85899C28238FC74C089E4101F0A42BD440E28BB832BD523F03C070FE065D7B96652D680DE68223971ACAF5B5C29B8AF836C41CF80AACE794800FD944B6224B8E207BE27AEF24BAA4B2436B28B6A85AA19612A4F11935DEC482D7EEBB006B35860D13A7FFB159F57812B518E2F3161A9E35C5B272DA3529284DC278664AEDF05B0E1D602BFB60436F026FDBC0A30F2579F1C4252021A132C31C73249065C5BBCF03A5D418DEBE578E5F4A9074685C68491ECEA6DC9EAA7BC819DD2C43F42049B92864A001D533741515EA5090F0870F455B03563BADA724011CA9F7154964DB8092AEA60242B273BA94ACD33B61BE47B5AC2115E95BDBE56B214E04166356496A698C81744C06B114E2B37CC441A9AD8C90B936E1D86B9E1D9B17F352B393B9A1DDA0FEBC548989C12C120C7988A460B151895961733F84111058116C427E75A8FB6798B9691626F7A5274F46BCF5A160F0BC59B01C5D5E634EE9C1FD5D665AB59A4B495030855C538C86BE779CCD8CC076D83407A5C9AA3757841DC30F47592233A3AA8F3A721A5902FF8225F51764D59087D5B928E34572C23C511E236ABA0CD710A7EA0FA0CBA999F22445AF63CA783205E4D935CC9304BE9E92364C97993A1BC4DE491C5ACA2932575C99153A0BAA814644DF6A4922F426268EA1F7D97AB7629462F0C8465900AF523CF2FA978CDA56F4FC936BDE529553B56735701FAB3453C1A8ED0492222022E7C799EA11837C952CFF9A059992B26CE774460DAC2D23803A913CDE96662CDD78B4842A09E3A09A8D6A5B4052A25D39F63A43D9B9473FF184EB9B49B78B7165C62141866C2D4D866232A952E89CFC422CA5E510390DB98DE3A5DD0E3728BD5076656941894BD2C85C1B4FC400A9365F744B7EED6637C694D7C3104329AB526193E0CB2BF5E9B8E5D34630C16B097EB027C33621F23BA78E4470DA48354C29C114C242EEB6C62D15395D40B716A6137CB5B5AE2C27CD49D176B5D70416E254753F1150D5D8807F07916330C69B5F236F0672709834523092746897CE489B3FC878FAB716042509AA96BCFB839544449280C7C1CC3F79A22A25BBF47A33228CF1CB619E2492A95EA5F3D12C80BEB2412B81D6EC7CF6147287FF36449205CAAFB3625CC0A6FD4AEE3898D8FE56F62B06F6A7B7F1325B83A30B72FFCBFC9A672767BB2659B1B6500B4A3629F00286B82F9597E6CB21FDBA9AAAAC5F24273B2AC22EA4023219C7B32FCA7694693A2208791E1AC33C00C0DE64E2241001DC04249CCBEB797A1C38CAE3DA81C07364374033917A04AF6A19BE424C07DF33237B9223B7C04890CCB57780126B9A68AEB5783993F6C08783DC254B14482AD37AC90609BF3B0CEC7B39DB4241E0D9502DB60AFAE068749A295BEF8AABF861EA1292542927F6DB939AB7365142A37962A46230C37FB9519642119E03C45CEAC2F0B40198D6211758346E2FB284FF807A4C06552D7B8DF604D2EC771D2F74D0A258261280C60E71C9FE66168DC9493539EC1F018A520C02E6B8562C55831C18900A1C55FCC6A772480BEF2C75322C1CD116483562E6B7A0D16D351E2BC58032B5267325183148CA61079B2E8A8AA293863E0946D6772716053DF4A0260E3A36ADABD19713B46E89ACD650EA7932050724356D1261DA37916E85BF552C8AA628ADB08383781245EDA4A82E27D099496A26B5C893927DF02BEA47742B3C40B0E31B5D621012D1BC0F3B085E5BA6228E9B5E875901F1711CD12516EAAA4FFB16AF44AC384E0AB5469B222666FDFE32B1F5A4F3C0C022F6B4ED770572DB6B9B7FB715CEBA1C0EAAA19FB2361D83DD2465375A2BBE2793255619592A6044B71CFCA2916B0C6C895A38D7A28245398465432878D96446BF71A6C21C0A62500B030BE6B528646C860AEAB7B28FCCD87381C61D7106B518E22A2A03F5B7F48729A50672A4B039FB67B9DB0A803D304BFCF83782BD5A10250A8C8D96A9EA993E692CDE5871C6BF79FED564C5834634B88280D3A4CB18025E332532BC65FBC169DE0308012C08A581A1A5C9B1A89C75162B990FDAAA768A35DBD9ACE608981D589116BC45BD7D49425C7B11B573B8F554976152C9A17C273E4A3CAC15D5DF6724C1605D9A77CE487438248178C10486FD7C7E1EA52BB5467B066245560A2C4523B53304445F956E968C5AFF602B7F9378CB290BA0B4707841D175C01AC0BBEB18435E03850FCA479C1E8B7CF0730A5F23690F862C1970A5E9A8DD3F51E0655B2CE7BBD4B38264929C9499BADB505625B7A7BF260597F1239176C4892E37C3EA0770068C49E14A8DCE526D64791B6E3A1EB70A8FDBA17FF8476CA5B1BC9FB533CE7B1F0373D760AC691DC598899A3798A0D6F967699CCA69420116BE625CFC8C23879215C320B354412DC7311E21A3784A3445134977E995282033BD0080B84487BBF23A499CC1D17172BD029406523707B671E25F9DD605C8473C42FB131B08A1E33F1E85055C2DCBA8B2B04F9B8C07D906384861D9A8CDDC54069D3E53E033E2530CF83C284A49AD15019F061C40B2D00AC7A4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99" - }, - { - "tcId": 72, - "deferred": false, - "z": "4E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952", - "d": "7B2EC50C53A67E0BCCBA98C2E319F5AB46B6E593D2465F14B23FFA03D0E5BE0D", - "ek": "E8A65EF0C7C7D7391DAB233EB277243732CAA45B53315B645FF9721D8AB0CFE54FF717157663B9098C2267633EFE3544A88014AD15C7B10A4551CB5F9BBA3D74946371B1AA54E6419CA7B4611149B5F02C73819A8C625AC52618F771202338AFF05969ED670BDD0B9DB562B8055884CBEA7A208A2DA850A05484C6B84109A5C2B498E8B8640ACC6F7AA6E1D7A95415469CC1C06D17176146CEFBA58E2B8929770851EBD6CA5DBA444548C622673DFBEBBC95767BEE2B86FF5BB37CF306B2945071EC1FA80C7540C56A36EB684D71C5E8B90AAA8C2421E21D64E0638D63C96E2B0BD9457BD5062199A01253D240C712315778AF487AAFBE28C650532A493C1B3E0251BC0841392839905AAD3D12289506742073862E8549E7E87EC28102DB7B89EBE91627CB95C0928C921978CB8C94875A94F1557498132200B4B76AA3C3AC9755C3B6BC5E5C59C9B3C6F7FB2CBB5AA457904FEFD2C370E29EEB2417BC45977BEA02A0DB9DE57937372298102755BA5B007EC88340B28AE7B819F9E07182F76070043CF3AA7E9256CF1CC3A6442B1726EB889CAB193222BCD3D8141843C1EF9921B8254712C04529D38846F595BC011B3288BCE0231ABC96985145043B579BB0864F40EBA6A66144E0972CDB10A71E44A088112B3C7907E5591D6EE85B34D4AF8DC58633081BA1A0A6EFE133B4C70ED215A22F451A7117B8C5F6A3D3FC4455214F5DCB8C31370546B4C4BA365A25017A9C2296AA641CBC4745BCAA72D17C9EAAB0155627BB45770D6D259BDF5B044053B4C7C8784FC433E89942B5D6C807A0707842CA4FBB98693303C118C9F4952123582FC4E22BB853944BFC1584810153F3AF5DBB74BB2928785C542AB647E9321D724AAC9EB9091707B5075C700A4817CAA2C355D4C99B8C5037B5288FF5279725BEBDAA5CE23609E5320981F11C8A116501D5ADD2D2B057C41E469257057B7A9C508017245C20C13A0C104FE1A517EE4621C367CE283183C07675BBE5895FBA4F30CC406772635982CEBC3153D046161C7B8BC4D87B648236263A44ED50B92DEBB624528C7A984C4C5047737A8021665279E9CF30069AADCC3F4A9245700436E646AF721A612828A07DC463D61B70223C7658F22190C83405999D92889CB0E5020052C31066665C4A021643C20764C370B9A5D1975D47646E1329072335432A19A03590B071482A3774BCA0601D8DBCC35A63742CD127F6384AFC6A971EE8CDD3E13687588D84C358A5537E753B2736840FD4E76A1CD0C68F9A990E5644404BBA84491E5F3B6F23EC45DF91538BD54070A702E69B66BF6C88CBDB8FDE693A2487681379A2AF94C592472FF167BD17966F9DF67E8FC51152AC613512930BA2BC2F453EEBCA91399B6D8F12AE891B3DEAECCFF120751866369BF8902D439D19F77B264002E5901B1C939FD86CA623277E6B09A72A93B52AB00754EAAA74833B8E366C8F0752639437F83CCC00F92EB7057C43AB94A75C31D5F854DCD3784920A36CA0C2DE244D1AE3A9E578B98E0634635549A8932A6BEC1F2EB321572A060EB110AF473F3E04323FD868A241891227222414C663285B05777BE82585DF3AB0ACFC121A642C541B3C3D7BB3157302EF62A1229156DB3609678B3B3E2576902145E5ECC78B65CF69BC8A7E6631494B804C4C89A9B595A8D95C039A9BA356670A536220C1CB54AC5BFCB7CE0125606A40C4EB4BAFC4C43BECFBAC84812F70C66796D6407F887CB0DB41F0FA7062E255896582B2B218FD96B6E5581A6FC26ED40272836950CB348AFE78CB135ABB6D015F299377632C72A7BBB2CDA7CBEC689E7551168483085B6B7426EB6967F729AD695D4E09C49B7A0010F80EAB54CBBAF4B641C956231663DB83512C97067CC7BFBEDCA93CC9A739A813B48C4793354C2DC642F869307AA191B77C2BC72BB048300B54906DFBD45255E92D81A98CD87149FEC3A428540D4E03C757260F3731CB7C4743A37194054AAE5FD6902D48A911F661EAD29321722E8243CE62E75ED82657423163A86362CAC2931954092909B0082BAD382A013A5044FAE9A12BF300670CA5771042933764E700B43259B130F033B023CBDA36815E2C6BC7C0601CEB7586A95DA4033E80E32123AB86C6135222EBAC0EDC17F5549D5B66760E07B2B16BA4FD8040E642990128A39A636B19FD3EDA4611BC1CDFD552AD1DB338FE3700F0920D56F3", - "dk": "0CC61046A844640446F07C1683D649F1168A00F1C859798944790CE1F884B2A99C177C579E314C91B33E483B86B64143EEC23F1587C8E038A42C85397A47CA7600C772D492E4CA5F7DC815100B9155449E72A0A526D24035FB20074941F0622FA9369E79D46378E45D5564245B0C10D9D873420895059428965CC22E064B349A4E40346F77A84BF7734C598C5775D39E1ECBCE2A6BCE6FA5CEA4F41A05949ED766C1A290299D9BB47DDC2E7A782F386C42D2AA04C991304BDB108801AB6802B04259757A63A88B7492A2FB2E93A1AE7646267F434C724134154C407808CEE0A7983C32727E44766E5C34EFD16C52086519FA0DC6C7098282555C069F76832F7707477F69566280BB6D406ED1714205B73A5711C449B91B4F8A2C2638B65221493BD940B5370A4C661F6F9C27AEA6A69DD0B61CEAA861E78328941091A95300602878222290CBC67E907D6C4CB2BD6623CCC5A23E46322498BAC5945E6B28283D7401B30401753859A2D4818ACC8D71437961DA02F2E8B5BA94B494E7A215F518C6BC8214C57237108C6B183F1551696A909C828A0E076341A5C141ED62A9987932D002A714366D8621CCDB0272E7923C6F3461AD341C145A864C6655C8E02AC0C91CC0613CE7D48027206C7D4988D82A1340A7BD337B82FA26400A4B97B5D819AF154CDFA639DA3A522DAA0F524B2B77FB422B8216FA83B8D94903452BCF5054A5081741B2E93F40548793B39B7197AAF027907B763179269CB06671B0CC2820F6015FA158CE93770A1A51CBF033ABA1A5C4363A1AABCA93F2800DC011B19B952774C4F90991001C19F3A688B2E01C934A7BFA705CD093AF85BA5D20FCB498E5C91B186378B63C04123D19A8C2B5209D7D8799EA7192BC3876D1943F17FB63B8185D89A37483AB74E62BB03C27BA845CCE57309DA7A8055642B9AC51B820AA8F61F88B819804DCD8C3CDCA2AA816BDABE9725BF83C61796ECB069D183600FEBC41114182338C97B67618DF818DCA151AED240E36C1A0DCA654886C6CD3731A92E3CE81D7CBB4BB1CCDD238C54C44E89126641AAEE1145BBC378C92C56E400B5DE838A18FB66D365501B406287ED8AF6D03CBCA4BB617B42DBEFB4A0435319A00133F4AB70631C1045515C6C23310F50406780F9E891187FC96736296B9E7AB1609C51A103AC34667925901EE3A9116CA97FB46B8325B13A64B008A88B03E0C383E152D7F8593B6638BA7F9AB500968A830042CBB50638A58AEC5B6BBC1938E5C7A605A80B161BC18841873ABB5F38ABCDDE99464736D3505C9EEB86E8A95747CF9CF3B9A52BB115505B156928A79DC9B9E1F110987D4808AA2C27B806D7B746014476E571AC2F416AABADB36CF994813887195CB63C15C678D480443CC0D2C60365E358F1FA9897A12279CE928E2CA8D67006D48592F54EA4CDEAC2748940AF558356760C420EB71DE2ACADB064586C5C01A698330266DC78C95DB8CB51907C6DD94B507C107E9FA7210C60FA5D8888A3CAD7AC1B6FEE59159D6212403B2B21944D0AC35B0137989F002D4F13E8B873F8B53B3ACB09478F4C00A7486AF0B5FCBD42E21654FF3DB786F2307E7E60236EBC89C36971E2920A27C5E7125BA1DC77B4F944BFDA8C4D3E09BC8A00B3099B6EFEC5F7F59AD925B79C3311A7F02433FB9133F845B58E0BEEF5611DE6890E45AA75645C34F832B08B7655CD6424F733FEDB9825EF3340A010E72781D16F8180F227110402816E6524D8B341EF5CBD098A8CBEB52C02B715D1789B0D38250EA6730E506E569A9E32A5A35C7341181B9E0C46296E91F3FE9C5A7159F9126BE378BAC03D467C7A39AD1605DDB2A3C7FF930A85C0710114ED2094956E005DD770699F4CD50767E53C15D5251B2621336CD6974CCD446C1C4028C62839EB699D869758E502CA158A39798688D95B1C4509EE9C57383209D69D105D56AB55A59955F78A65E49B5A4FC4A5791AE5D79118CE2B22AA9BA2DCB963BD672A6861D78C30D6873893E15C62A428BA3E77D09C94822693166E39C32E32666F4537E70A641181C13609F1C3535A91486FC3ACCCB29A0EC0133DF7917B71B8EE4509264788356E967335942014213E4862AA8B7691AC207A996711AD1AAFC30BCBADC0A35514F3FFAB45E53197E89B918AC75B504647A3684E8A65EF0C7C7D7391DAB233EB277243732CAA45B53315B645FF9721D8AB0CFE54FF717157663B9098C2267633EFE3544A88014AD15C7B10A4551CB5F9BBA3D74946371B1AA54E6419CA7B4611149B5F02C73819A8C625AC52618F771202338AFF05969ED670BDD0B9DB562B8055884CBEA7A208A2DA850A05484C6B84109A5C2B498E8B8640ACC6F7AA6E1D7A95415469CC1C06D17176146CEFBA58E2B8929770851EBD6CA5DBA444548C622673DFBEBBC95767BEE2B86FF5BB37CF306B2945071EC1FA80C7540C56A36EB684D71C5E8B90AAA8C2421E21D64E0638D63C96E2B0BD9457BD5062199A01253D240C712315778AF487AAFBE28C650532A493C1B3E0251BC0841392839905AAD3D12289506742073862E8549E7E87EC28102DB7B89EBE91627CB95C0928C921978CB8C94875A94F1557498132200B4B76AA3C3AC9755C3B6BC5E5C59C9B3C6F7FB2CBB5AA457904FEFD2C370E29EEB2417BC45977BEA02A0DB9DE57937372298102755BA5B007EC88340B28AE7B819F9E07182F76070043CF3AA7E9256CF1CC3A6442B1726EB889CAB193222BCD3D8141843C1EF9921B8254712C04529D38846F595BC011B3288BCE0231ABC96985145043B579BB0864F40EBA6A66144E0972CDB10A71E44A088112B3C7907E5591D6EE85B34D4AF8DC58633081BA1A0A6EFE133B4C70ED215A22F451A7117B8C5F6A3D3FC4455214F5DCB8C31370546B4C4BA365A25017A9C2296AA641CBC4745BCAA72D17C9EAAB0155627BB45770D6D259BDF5B044053B4C7C8784FC433E89942B5D6C807A0707842CA4FBB98693303C118C9F4952123582FC4E22BB853944BFC1584810153F3AF5DBB74BB2928785C542AB647E9321D724AAC9EB9091707B5075C700A4817CAA2C355D4C99B8C5037B5288FF5279725BEBDAA5CE23609E5320981F11C8A116501D5ADD2D2B057C41E469257057B7A9C508017245C20C13A0C104FE1A517EE4621C367CE283183C07675BBE5895FBA4F30CC406772635982CEBC3153D046161C7B8BC4D87B648236263A44ED50B92DEBB624528C7A984C4C5047737A8021665279E9CF30069AADCC3F4A9245700436E646AF721A612828A07DC463D61B70223C7658F22190C83405999D92889CB0E5020052C31066665C4A021643C20764C370B9A5D1975D47646E1329072335432A19A03590B071482A3774BCA0601D8DBCC35A63742CD127F6384AFC6A971EE8CDD3E13687588D84C358A5537E753B2736840FD4E76A1CD0C68F9A990E5644404BBA84491E5F3B6F23EC45DF91538BD54070A702E69B66BF6C88CBDB8FDE693A2487681379A2AF94C592472FF167BD17966F9DF67E8FC51152AC613512930BA2BC2F453EEBCA91399B6D8F12AE891B3DEAECCFF120751866369BF8902D439D19F77B264002E5901B1C939FD86CA623277E6B09A72A93B52AB00754EAAA74833B8E366C8F0752639437F83CCC00F92EB7057C43AB94A75C31D5F854DCD3784920A36CA0C2DE244D1AE3A9E578B98E0634635549A8932A6BEC1F2EB321572A060EB110AF473F3E04323FD868A241891227222414C663285B05777BE82585DF3AB0ACFC121A642C541B3C3D7BB3157302EF62A1229156DB3609678B3B3E2576902145E5ECC78B65CF69BC8A7E6631494B804C4C89A9B595A8D95C039A9BA356670A536220C1CB54AC5BFCB7CE0125606A40C4EB4BAFC4C43BECFBAC84812F70C66796D6407F887CB0DB41F0FA7062E255896582B2B218FD96B6E5581A6FC26ED40272836950CB348AFE78CB135ABB6D015F299377632C72A7BBB2CDA7CBEC689E7551168483085B6B7426EB6967F729AD695D4E09C49B7A0010F80EAB54CBBAF4B641C956231663DB83512C97067CC7BFBEDCA93CC9A739A813B48C4793354C2DC642F869307AA191B77C2BC72BB048300B54906DFBD45255E92D81A98CD87149FEC3A428540D4E03C757260F3731CB7C4743A37194054AAE5FD6902D48A911F661EAD29321722E8243CE62E75ED82657423163A86362CAC2931954092909B0082BAD382A013A5044FAE9A12BF300670CA5771042933764E700B43259B130F033B023CBDA36815E2C6BC7C0601CEB7586A95DA4033E80E32123AB86C6135222EBAC0EDC17F5549D5B66760E07B2B16BA4FD8040E642990128A39A636B19FD3EDA4611BC1CDFD552AD1DB338FE3700F0920D56F3771F1733A4C185573FFD9BC77988A1458D28A64F15512217C7B95C24D7CF48904E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952" - }, - { - "tcId": 73, - "deferred": false, - "z": "7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC", - "d": "16858AA7C92EBD72FB8CCD0A99D0435EDB2A6EB1B936DBCB637CF43F25D221B1", - "ek": "379C74CE8940E12A1790659FD6C2431D7C1043A8049A3B0AC1000273A0A68EC34AC6435018C19F3A5A18CD28AFF1254C27E92E25149E488A5CF5C724873A7CDEE0182CB874E1564F6036CCC6E5C02FD19937D459ACAA589BC3706BB60E82C93047030524A73C3831232659565FF49DBAB60BC8C18E203B68DE7784D96B4C1969AD8F164EFD531F8A297F46425CBBD0C4E3C858A01982DD4686860B0253D1067AC66353F7554DF00A2FFC46858C6693F04499054458864A4A7AA82230A4B04C1EFF8A2B9C5B1A43F0038A027CCDF73EDA1B16CE878D14B27DBC2AA0019BAED2C86F9741A9DFF624071545A4CABBC2895D9E9602C1027D05EB1C70DC2365423A65740F777565503C53B31C9D7DD06DF115BC2CC1BA80D992D185C485A78FB6A0B725E2A93897CF04F1B421093FA098BAF4B829FED6CC07073F0D13502E430F892A5E344B431DDA1EC9270A0DB64CBF40CFDC78293826BF4701181594B89F8CA52F3168DB931E7242121A71747564AF2DF0312BA4659A8BA2106983957877673269313B953534824E035AB75A5007B7BB5832B37936683B23B563FAB86EB749819616AC467B42D4B11922A9719067039480849B13E125353F54179B5524C7B5905A673E54EC888614AFA7781B918951C2C30E89043119351965256B26CC5B8E1973C1E838C6297D1305D02351A1C2E394DDA666D918545BB8CB69CB8141645AC7CB606A0500E0F94961CC8B33A5250E191169C3B4CBB927438764B356928431A7D5E73067346C9EA02D7F687A9DF1BE9018473CC7442F801B43F2307FD2380329C5D3DB8802823864A8895C0262A97547682A61A1652F4611717C09AC6DF8886D67B1213739DCE29271F65564CC642851005E224D634C996556AE35E3CCA9A6C746F7609CBB526C9B9CB144CEF1F39DBCD11207F43FB7296193B12F1E7B043DAC724FF9A32581192E13166FC91F10CC5330D6A7C4F04BD3248C61D227E70543E041354D55B1E52AC1BDA0657ED3C6F5F3444B3775DE1B0C337409C34B75A5B9A58DA8B7445C2E3A6BCCF1E02A0C1A20DC619893E6370D35BA4CB615D5B2BF12885749865675B9A925B21EE138830E20B2BAD258349A44747A08FC962476A0A7A1676415539086A543A087737DCC8E2565161F8697043819206202AB240C00C496D5254E8B0610D6C55CE52B20B0F63D65092F95879736D989728AA6EC91588F60682512CC50BCAA756A12F13C6C502BBB6CF210A7877DE46831A1E91D7549B50AC391A439BCDF2135FE81C81B25874189726D77AF828876A4F34E19E33009B8217E511DB2A7724B251109646E112823242C964B933F8B4625EDCB1471DC714684045AE79811A56B113803EB272AAB94709421239B009C3D4CC8463906DE646E7374C865103AACD4190206C43BD2334D496005427FDA19CF31872A941C75A6B1663F6C57754CA0D9D8A23A1B9592A1B3FF76A035F89B72B29E6207D05BAC0C349608E71B2E4A3CB3EA7651A26B374CE516C787976691BE124AB671049F3B573905D19906CA6E9C5912F6311410CA3A7B25973895C0E8733557A463E311BA20191EB77B3EDDDA437BC75D5F358AC883B2E8242449834AB6F5ACBF0422ECB438AA4009BB678E88D033C701322DC01D0F9B47EC135A25CB2B491B7F45B33686788F603B28E0A215AA1AA49BC2B2B10906F70004DAEB16F4E5805DB455BD794861BA1F8D55BA6CE29591728CBA492B89255762B25DDB71557E8366601535DD38609652CF47506379673B0124796C3CA7EB384EA0830DBB318E553525DEA69187A2151A227016DC53684C1922A25A90107C64E04CE1C7AF8481A437601D7C4AA014D18CB397B4079C660736453B35A5BAAB9371F0B5D4F867CE15AAA8739F6659B12FB93667DA30ABA01CE923853DD26187BB20A845691AB48785B22767ACC0D7389BA260BF115873CB784CB4C715E67776759511DEEC2B565361B84A8833C7A16C16AA3F29750397B0ABAA9B73A580527100511686A19A7AE757833EF826F4D21E4C020618809A48B67156711E70D5171BCCCF997CC048BBBB2AE064FFB9143F66A2E81A9341831999D822AD947CE88CB153BA595D5B0EF5D08EB856929412B9D2E551C959482AB545B1A0AD8583B7C0D42A95A3A080B772C77424A1AA1852DCA0662BCBA7B96CFAC5B1B689F01A5CEAEB2A0D52EB0FE9BF752B36B37830846812FFB88D", - "dk": "2ED75F448A5247A0BDE73C1A09DA83F27512A9E1998A48C80A0962ED307C0F8C4D221584D3A90D6C7B003EABBA2A2013F4D74CEF9A84AD123E430B316C08AFB04A64EFB31278F4CFAF1156285679203A275B267AAF7786346B40566B5BEC24B122C89108683431D0A8E8531EC70116F648004A9BA3DA807E54755BB10B9DDE973DD1E62C1A6C752D09B18DC00178C52A6F0504ABAA2B3E54B1D1A495A9A38BBF29812C472D28A8386F04BC41F555263A8DF34536E1925434407B3F885F7349A2C20BA5F275BBA62039F77A0BDD236EE4A7205B660AC04A48D6EC0927EC8986C73539754545E96B3F681F461A5424B954C5C69F1899BB8301B0138BBBD934A764168951B0BB42043FC6A441BC329574C726E9D31286063DA4556C02087FFC473C3B4307986A59AA595139A46351FBAAC3E1664B5A4A74D5916EB3BCB0F570B330ADF4574A92589C782A3CA520C43C4BC7987367BC64B9EC1629C41C80223154FFA3161A158647468B8DC670DA26496FB53F1BAB59261B8B9A3A725AC992567ABAECD027856650A9D78FA4656E3BA89BFEB80F7007562AC84EAB2917E18432CC5A4BCB969DEA5C73F1AC620612574F3106D1646FC266959723004C425BEA6B8B8E6326365C540C2844F666A482116D16C1272D90A439567706159C90623B1A79B62B14860926568C32360EDC9C868211E0036C9A3979B6F39126A150A9259CABC8631D9214CB43A8564A6DDBF785AFD44EDCCC7D2428A92766AEBA969D9E065D05E772C6DA572F9B0A7C5A7C0E54020B331CDF321CE7E48EAD96C4EE5062509113E274578F50A7AD131641BB3CEC76CA79B39529F92886B40F22086A6F527623E37797F1009E082277CA420C3310C0F35F2BD61776B8C5FCE14136DA388FE6CC37F3A7496C0062D0ADDC91B8ABA38817F45A7996AE0F7BA41D32C1FC255A43A6BBD9DC6A65A6BB72A306A3446418A77BC58C1D3B1B05437C6F85D01A300C9FADBA40F8F4B8DEA2CC358547165A467AD12BEC5C80C4F7AD6F308550B419BB06AE54CA29011A55502215CB0397C005544404B9A413CF74F5AFAA532C909A3D00FD37146721FB0B35363B9C52B71511D6C45B719E33CC43E016770936BDF6D2056AC21FF65CC813321144B98C965530A80654EFB350EF973AD505791766BDB4734C3E1A0394A89902416C3DE269B9A99E4B6CC39D64BCFAD64A552728905882278A238B214B94F62856C14C6294B8FFE80F3E62B3C91A687503094C2849BE8254314B56CDD35617D61F27C9960388811C830290808F9D0B2DA6AA4728606F55CABCB92AA9384CC3E03537BAA41BE636C7EFB036B5114019E40C74984884DBB512D61CC8A973D8E6C8EAD45E235C7E6235C181C062E82CBD26A2859BD9B510514D83114847ECA0DB8554663B1D74E5084460C396E43F3FF47D379A4574C77E8F1C11CDC5974471663244CE2EC399AAE83CF96889BE7628ED028E477C0658993941AB737861A9F8388AD1309BBBB23EE72181A1EC7BF445B1FCC5527E9C0F7D278362548131CB2132691E232515CB5C5CB6640E01F8B75D96A9E60ABB6929A7582219A8A8CCDAB2C4A03A035B8CB416114FF7604692427B35C135DB956F6BA796145CAFFB066663293FEEB462EF5C4D8C521B86436F011157245A891F233AA122C51AAA0CB0D5100B01575EB04B9A1B86D6A1808357265DA0570DDCCA2766C5802333C64B0D9E5A254A8645328C394F85B337A447F17753BB465F584462B40518705094D891C6143114522BA327547B61C928CF50758FA5C0C6FB2255A51E13E9AAC37000053C180EC7A6E597BF57DC656123793EC0CB24E9306FC0CA5CB723C8F46174179923E819A1DC760229018D7348AAD75263DA565129A39006299CD979BC73062003D0773611B07141FF2265F8E5583284201A4111F5719BD4397909D892AE8AA438121C5DCBABB9413194542E6D98AF6655871DF23C6A7A43B6B6C9D0790F53705F419B226497BBE92A3EC6315C6A443878B283A252423B13505DA298AE100A6E34BDEB734DAF0588BD54B2D5C1198C653B34A8C4D0447C5B6B137D203BB2612E46AC4B82BB97931550F3F835B57B8521828718498A3405C36A345A1323924221505906723847571C6985B0A59F1FE15C961B5F11630D04CA79FFE22F371A96379C74CE8940E12A1790659FD6C2431D7C1043A8049A3B0AC1000273A0A68EC34AC6435018C19F3A5A18CD28AFF1254C27E92E25149E488A5CF5C724873A7CDEE0182CB874E1564F6036CCC6E5C02FD19937D459ACAA589BC3706BB60E82C93047030524A73C3831232659565FF49DBAB60BC8C18E203B68DE7784D96B4C1969AD8F164EFD531F8A297F46425CBBD0C4E3C858A01982DD4686860B0253D1067AC66353F7554DF00A2FFC46858C6693F04499054458864A4A7AA82230A4B04C1EFF8A2B9C5B1A43F0038A027CCDF73EDA1B16CE878D14B27DBC2AA0019BAED2C86F9741A9DFF624071545A4CABBC2895D9E9602C1027D05EB1C70DC2365423A65740F777565503C53B31C9D7DD06DF115BC2CC1BA80D992D185C485A78FB6A0B725E2A93897CF04F1B421093FA098BAF4B829FED6CC07073F0D13502E430F892A5E344B431DDA1EC9270A0DB64CBF40CFDC78293826BF4701181594B89F8CA52F3168DB931E7242121A71747564AF2DF0312BA4659A8BA2106983957877673269313B953534824E035AB75A5007B7BB5832B37936683B23B563FAB86EB749819616AC467B42D4B11922A9719067039480849B13E125353F54179B5524C7B5905A673E54EC888614AFA7781B918951C2C30E89043119351965256B26CC5B8E1973C1E838C6297D1305D02351A1C2E394DDA666D918545BB8CB69CB8141645AC7CB606A0500E0F94961CC8B33A5250E191169C3B4CBB927438764B356928431A7D5E73067346C9EA02D7F687A9DF1BE9018473CC7442F801B43F2307FD2380329C5D3DB8802823864A8895C0262A97547682A61A1652F4611717C09AC6DF8886D67B1213739DCE29271F65564CC642851005E224D634C996556AE35E3CCA9A6C746F7609CBB526C9B9CB144CEF1F39DBCD11207F43FB7296193B12F1E7B043DAC724FF9A32581192E13166FC91F10CC5330D6A7C4F04BD3248C61D227E70543E041354D55B1E52AC1BDA0657ED3C6F5F3444B3775DE1B0C337409C34B75A5B9A58DA8B7445C2E3A6BCCF1E02A0C1A20DC619893E6370D35BA4CB615D5B2BF12885749865675B9A925B21EE138830E20B2BAD258349A44747A08FC962476A0A7A1676415539086A543A087737DCC8E2565161F8697043819206202AB240C00C496D5254E8B0610D6C55CE52B20B0F63D65092F95879736D989728AA6EC91588F60682512CC50BCAA756A12F13C6C502BBB6CF210A7877DE46831A1E91D7549B50AC391A439BCDF2135FE81C81B25874189726D77AF828876A4F34E19E33009B8217E511DB2A7724B251109646E112823242C964B933F8B4625EDCB1471DC714684045AE79811A56B113803EB272AAB94709421239B009C3D4CC8463906DE646E7374C865103AACD4190206C43BD2334D496005427FDA19CF31872A941C75A6B1663F6C57754CA0D9D8A23A1B9592A1B3FF76A035F89B72B29E6207D05BAC0C349608E71B2E4A3CB3EA7651A26B374CE516C787976691BE124AB671049F3B573905D19906CA6E9C5912F6311410CA3A7B25973895C0E8733557A463E311BA20191EB77B3EDDDA437BC75D5F358AC883B2E8242449834AB6F5ACBF0422ECB438AA4009BB678E88D033C701322DC01D0F9B47EC135A25CB2B491B7F45B33686788F603B28E0A215AA1AA49BC2B2B10906F70004DAEB16F4E5805DB455BD794861BA1F8D55BA6CE29591728CBA492B89255762B25DDB71557E8366601535DD38609652CF47506379673B0124796C3CA7EB384EA0830DBB318E553525DEA69187A2151A227016DC53684C1922A25A90107C64E04CE1C7AF8481A437601D7C4AA014D18CB397B4079C660736453B35A5BAAB9371F0B5D4F867CE15AAA8739F6659B12FB93667DA30ABA01CE923853DD26187BB20A845691AB48785B22767ACC0D7389BA260BF115873CB784CB4C715E67776759511DEEC2B565361B84A8833C7A16C16AA3F29750397B0ABAA9B73A580527100511686A19A7AE757833EF826F4D21E4C020618809A48B67156711E70D5171BCCCF997CC048BBBB2AE064FFB9143F66A2E81A9341831999D822AD947CE88CB153BA595D5B0EF5D08EB856929412B9D2E551C959482AB545B1A0AD8583B7C0D42A95A3A080B772C77424A1AA1852DCA0662BCBA7B96CFAC5B1B689F01A5CEAEB2A0D52EB0FE9BF752B36B37830846812FFB88DD27339E75E5E384EBA68A71FE2E52EC7AB0C15CFE33BBAFC892DB62D84ED070E7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC" - }, - { - "tcId": 74, - "deferred": false, - "z": "4CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76", - "d": "F788F3E21D62E74090582F310BD4FDC8065E56E8D946142B9B9CF8F338F330E8", - "ek": "26160EB381AE1A868F10FA05934958B39790C5858085A82036224D2455823F11A3A5C537DB483A3AA7725ACA567CAC610B4618E3CC0381701FB60917F5DA63CF712618535210D102238A5768F876A17C4437AB8789662F426C5CE69258C3462D70636CD556AD9EF0A2CD9C1DC3C546A0B396CBE2C94BB24C40756815F796AEE7045B6082DCC49EA56849C639419871C480185E51E4AECFA1945DA10B43C366916531ABA8A01502881B76C6E6984F7EA6058DE460C1E3511A06631670B35ED6A8D5D7BC6589A62DE377BAD1582C085A3DB3BC47F176A27604035B9ED13853758A77AA1391E881214894013F1BAB687A699DF18B373A64073BCCBEE469E1C867D221C4675791F40102E1E2B12593152C87A47A9367833854EF5427DE49043308586673274DEA8C2AC8AC5EF5886D06205284831170BC6B9C0844248DF1CB40C5B627A29421AE900EF5F5666720304520ABD826AEC0476E0D32213D550D55442E863B0FB8ECB85A1CBDA002792F6C199838613780BA4CB22605B30372304F88897EEDFA09B6B0C4B4892C0A05746DB80F602C016230129C2B0C83351413D4C2197B92E608485301BFA2EBA2BC5C2E1EFB42109B0119F079560A87F01BC6CFF916E81A1AA4F520C0687C41C91A3BB5C4C1D712449C6E927C0490B2AB4B9422BF5655E332C4A1D1626E587F085A631C250C122537F5B213A0C231DC48CA7B88A4C21706FE701645F43A8A00CFA0F0A13900B3FB5C1B886C66F22520FD685AD0CC396991B0ECE81635BC27AD2813FC377E7A542D9A9602E22775CA34CE85B834ED755048286B82692E3F9AA15E89A8D8568FA2AC47AA32C748582B7889B447C079F404329FE03066E8A46412820EDC8B8878840DE54C80CC2851E08374A89FE8F7417CF90638726ECA61072C893CAF8C501D04CFD2F3BFFC094503234693C530A732324C0516E412137E2B39AFF1292B925205C972F1B6805E67A292B069E8CA73FFFB1DD2B1A5FB2057ABB67ED396494D123D05A579C23263B47ACEAC5862982B20E6BC5E32E03BCA175CDD8996044AA9D90B3A0488500DB340C06CC9B84749B4497AB6A3CDF05B58FD5850CFD911B5C58819D2444CB9386B18784762B16DF6BFBCE86BEDC9CA6EDC191171C88C5060648B419109C5BDDA9A7E98C48B1649B342B7ECA411959A9D62E5C0BEFC5B62F4BB6EE608CA18B43AF78784B8C7384ABC77426B5CD28EE70B93F808317230A686900C83512E2A83CD10749C3E5B7EE6826C1E01CC5FB27FC47B52DA462AE5EB65390A1A33CC9749941D530210AD070AB71487C2176B17621ADB11CFA1F3AA9C379C9FB0CDF00186608246C56584DB61AAA8C157A28B6161F23EDEB7365928C1EA8C962785C338E66FF1897B56154475E17F81C9845C4607E5294E21EA23EE0CC47E4BB9D3539D46D410A3149E098B539B196A2C90C06D5C103AAB08E1110D3F565AA8CC7E4F2167E6969BEDD5C3CC8A6F68F53E18931F8EF0723FE33A2789661C248B15A35ABD5919343AADC93BC6777539E952A3F49A3E34F51291709F6DBCBDCB65B4760B8795B7985DF8249EEA132A473CAB736E72D45A2A100FB560B70E600EB24AA596879F1B1A9DB705AAA489791A503E9463C19EDAA4ADAAADB77A6FB0BABE16973E63333F03B444C85C980D55727532765397B84870BB759469CEA72E28A75BBA8A5098B6A95750ADAB54361C802ADEA678FB6733D3766F7C50BAFC081A384A768E60AA2E6648ED81612778033C6038E7863887F19C1509518E61ABCFF77F1ED9459D10C53C0CC6AD60C95704138B9C579317714F393AE8287909ABAB7FA167B8B237CA52056A199D7558AD5F16821DD364B11B9307421D362BA42AA3002AD2025E347BCD7223EE4BA62C354C1CE9822C8C4B3B70A1708462453292C73ABB177949EA3106FE3075CBA15E2E143DD13A6600E55D801A440004621F6ACDC3CB8D53236FCCDC15B9F9CD321398AA230DA6722DDACBB98106367B3723FEE198E1AA7161C004C9BA1840F19721AA7D99B99A7057B1B33A28F2033904750ED1899551C1C8A9132D86B3781264CAC231C3A21440580A92F4C683CA90BC1CA78CE41B332EEA7D2F461425C9B91FB6867B4270AB785329218D74356A3B8423A044C3C6653B09E60821A1CA6032A0BC526228F18B9E38B3A7B69EA6C1C5C0C39DE56DA9763517FA3F65CEBED43C7B61282772DBC9", - "dk": "A0CBC9A9EB303971AE19D11CB1023CAE83B0578A8BADF6BBCFB444000041941120984930702ABE4D0442E79921D92CCD08364112D41433013110D74ADF2B53A8164582F56E2DF03FC1D283424A16603CCA86C8BB3211030574553A221A4236817DAB9935899201465FCED39A2E0845DDF09F2B346FD3FBB2B6EB72C7C6CB8EA1784A010AC17A79041408A1B7853BDA03161A478D48AC4D19C32F728C36D2CAC5C4784449A0BB5C02C4E506EDF7A7A1A8548F931FF36014A8AA651527A4AFF04AB5E52A29058DA78388192BA72D17A9F3428E784999C9F59ADC561CA971021C7C9DB552926D572F44F9B2B014ACA32A267EFBCB62D1962F48B6D867C12FA25723736088E80CD3024A2610C727CA96AA8C495A8688DD4C5F804C308D4A1693E6B2C676B3B44C127A4911F8522308E20EB5E816A8949D93303BBBA150744511A9C23259F663AB3444AE787FF766A3D76859637588C21634F7338FE98596911A92E1692E75D66CF37AAD1C02720DD47315B1AD9DA95AEDF383D6863D7F06214E626B3299A5EEA648CAC40067C5C271A81A8328C7612858BE4C736ABC35E3F982CD84C596685A3F974D61F450D130C1159993BADC5AEF7B71F9E1503BF2525FD2B191E95E35A852D65082928C47DD989646FC5FA9E92292EBB03FA4B52473B57FF59E52ACC2311844C59104F51147CB600D0DFB42205A225DB32CE6843557F61E3199BE1E8A237AEB1240B51113233C92E453FED3138501327948A68373457AD6271ABBB6CCF860DA15241F89C27D5074B6A7170407B3024708FB3689318AC024E0CCA2836D3D786737D298CA7559FDA75F38CC8CD3D4845A165E18EAA56547928B0875AF564F763C365839879AEB3962F520D37755A17983826843E55567CF2B45F2B59D716666528256651694FD4B5913D90A25637369779991E9246E6A59EE1437D7DBB62466A759301CD0F4CC551161C2662E0D0992DDF07CB4BC61EFAB0D4F81700C0694F971AF7CB0974367AA53A8A914770D03892B639746AF79179AB8405C08A5DF9525E5958D26C4543A82349A192A86D3529F660BFC49490B2147D9170FB5CB78FCB40863550E9AC42DD3215A2D86B3F3A4B0188A9F7F02949CA48A63DBA56224B436B2C22C085EF826AB521B0DBAA4A7ADE8355FA3C4BD708EA1AB68B1FA714D5841208BA9CF3611A9854F69A21E1B67C84903CC382B3663ECC2AA4B069A8639618536FB6B562CCA390C103645D9A06481666E92C1FDE91AD8291596286501B154C8E3AA6E0608E4CA6FB1512EBD25C9EB789E7765B342AABAC415B7B1E65FD38ACC880C61E1C01E96BB8FAC50972D536D49A20B46BAA303DAA481A39D68C71286495F248045B1B82020544B864C3E1951812D01169B4AB79510A284F058CFBC963431BA0FB7209BE995672A264DA3A6EF592EB121093D9B09F35A94BAF125C4F61508B1C339C6B58C5BA65A207571191253C3512503C400C70BEDD9859E363A7A1193CBB2C222782B77B62CDDD09F67BA9F4D632930E73E08F37F24279965C74BB402439E0A8289A43630983BAC924D0261BA07335B3F734428F538B2803DD47B26B2D5183533807CC43B67E79680E6C5E60709406B04548781CF497E8B890423F42186292FB8C988639C2F6DACC513014B91EA2D54393CFF768ACC42504DA84F21A21D372A2C7935334654856BD66C77423F10501CBCD39907EB7478FC0D7D0439C9739B43A363E324B319B219BD25BC1153AABA81B0F6A84B1D5A8C92885EBAC488099BCF47E91C8E4AA8EFACC0748B25B2969EDE004B4BDC3278B139C2445CDCA181FF8A3FD20777DA97CA9D182AC494336D424D87B53402596A0BA339611B5EF459B87C0163744007B008467387B44A680F3D916C8AD9352D7B6643509225874A05E03D2B0297739592AAA37772472162393CE7238482B51E8B6297E665CD9FEAC4B8664BA62CAB68FA25DA4459816922AD50AD06A347E40C4E5E55CF9A5CB738343DFE222FE46349E68A6526B1B1AA8CB5549BAEE622C2DB3C8806AB22F3C92449A67D3C7C5AF7A9C970839AA386A6D5518E00D8B11F42002F52C873DB6A4DB50047F815EE15C3D017676857023C57A017E431CE8555CEBA2BF48950F89095C2D278A1330D9F9416BE6442EC49A21C79BCFCF832677A4CEC8ACE26160EB381AE1A868F10FA05934958B39790C5858085A82036224D2455823F11A3A5C537DB483A3AA7725ACA567CAC610B4618E3CC0381701FB60917F5DA63CF712618535210D102238A5768F876A17C4437AB8789662F426C5CE69258C3462D70636CD556AD9EF0A2CD9C1DC3C546A0B396CBE2C94BB24C40756815F796AEE7045B6082DCC49EA56849C639419871C480185E51E4AECFA1945DA10B43C366916531ABA8A01502881B76C6E6984F7EA6058DE460C1E3511A06631670B35ED6A8D5D7BC6589A62DE377BAD1582C085A3DB3BC47F176A27604035B9ED13853758A77AA1391E881214894013F1BAB687A699DF18B373A64073BCCBEE469E1C867D221C4675791F40102E1E2B12593152C87A47A9367833854EF5427DE49043308586673274DEA8C2AC8AC5EF5886D06205284831170BC6B9C0844248DF1CB40C5B627A29421AE900EF5F5666720304520ABD826AEC0476E0D32213D550D55442E863B0FB8ECB85A1CBDA002792F6C199838613780BA4CB22605B30372304F88897EEDFA09B6B0C4B4892C0A05746DB80F602C016230129C2B0C83351413D4C2197B92E608485301BFA2EBA2BC5C2E1EFB42109B0119F079560A87F01BC6CFF916E81A1AA4F520C0687C41C91A3BB5C4C1D712449C6E927C0490B2AB4B9422BF5655E332C4A1D1626E587F085A631C250C122537F5B213A0C231DC48CA7B88A4C21706FE701645F43A8A00CFA0F0A13900B3FB5C1B886C66F22520FD685AD0CC396991B0ECE81635BC27AD2813FC377E7A542D9A9602E22775CA34CE85B834ED755048286B82692E3F9AA15E89A8D8568FA2AC47AA32C748582B7889B447C079F404329FE03066E8A46412820EDC8B8878840DE54C80CC2851E08374A89FE8F7417CF90638726ECA61072C893CAF8C501D04CFD2F3BFFC094503234693C530A732324C0516E412137E2B39AFF1292B925205C972F1B6805E67A292B069E8CA73FFFB1DD2B1A5FB2057ABB67ED396494D123D05A579C23263B47ACEAC5862982B20E6BC5E32E03BCA175CDD8996044AA9D90B3A0488500DB340C06CC9B84749B4497AB6A3CDF05B58FD5850CFD911B5C58819D2444CB9386B18784762B16DF6BFBCE86BEDC9CA6EDC191171C88C5060648B419109C5BDDA9A7E98C48B1649B342B7ECA411959A9D62E5C0BEFC5B62F4BB6EE608CA18B43AF78784B8C7384ABC77426B5CD28EE70B93F808317230A686900C83512E2A83CD10749C3E5B7EE6826C1E01CC5FB27FC47B52DA462AE5EB65390A1A33CC9749941D530210AD070AB71487C2176B17621ADB11CFA1F3AA9C379C9FB0CDF00186608246C56584DB61AAA8C157A28B6161F23EDEB7365928C1EA8C962785C338E66FF1897B56154475E17F81C9845C4607E5294E21EA23EE0CC47E4BB9D3539D46D410A3149E098B539B196A2C90C06D5C103AAB08E1110D3F565AA8CC7E4F2167E6969BEDD5C3CC8A6F68F53E18931F8EF0723FE33A2789661C248B15A35ABD5919343AADC93BC6777539E952A3F49A3E34F51291709F6DBCBDCB65B4760B8795B7985DF8249EEA132A473CAB736E72D45A2A100FB560B70E600EB24AA596879F1B1A9DB705AAA489791A503E9463C19EDAA4ADAAADB77A6FB0BABE16973E63333F03B444C85C980D55727532765397B84870BB759469CEA72E28A75BBA8A5098B6A95750ADAB54361C802ADEA678FB6733D3766F7C50BAFC081A384A768E60AA2E6648ED81612778033C6038E7863887F19C1509518E61ABCFF77F1ED9459D10C53C0CC6AD60C95704138B9C579317714F393AE8287909ABAB7FA167B8B237CA52056A199D7558AD5F16821DD364B11B9307421D362BA42AA3002AD2025E347BCD7223EE4BA62C354C1CE9822C8C4B3B70A1708462453292C73ABB177949EA3106FE3075CBA15E2E143DD13A6600E55D801A440004621F6ACDC3CB8D53236FCCDC15B9F9CD321398AA230DA6722DDACBB98106367B3723FEE198E1AA7161C004C9BA1840F19721AA7D99B99A7057B1B33A28F2033904750ED1899551C1C8A9132D86B3781264CAC231C3A21440580A92F4C683CA90BC1CA78CE41B332EEA7D2F461425C9B91FB6867B4270AB785329218D74356A3B8423A044C3C6653B09E60821A1CA6032A0BC526228F18B9E38B3A7B69EA6C1C5C0C39DE56DA9763517FA3F65CEBED43C7B61282772DBC9C49E09D937D24CFD29FF7B285F7B478AE4E219BBBD89A54C8B127CB0C65803144CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76" - }, - { - "tcId": 75, - "deferred": false, - "z": "D16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8", - "d": "A72608DF0F025B4FEE7D94BAE77BE94CB974F20DD55006A70FD39F3397A8EF90", - "ek": "44AC5FB94668AD165BC9B4B09C50148831B0BFC0563D97B66913AB32846C9206BD2BEA024FB44B6DF239A8A82AD42C5BB69A77A3195AB8A7BD5C3131C9079D05E248D84167B6F569C812CDB1212F0584AEF9C0251FFA0E23A407BD592C7829C5D2A673DF01696AF02DD2A07A9342157EE608A2A91241DBB3F8725CD5D8BDA020C9107747F82A0FC7A97AC30272B694257B135095B27481CC769BB0834586CF70CAA72C2696B105A4B6440FB4D045B61A3D0BDA48490B22CE215C985B313F7C74155015A7D079DE9A2EF4DAB3ADD1A1CB684CA377B428B90D2BBB0980249586056434E2088EE250D065951EF228362B1D8028BC793CC8DCB8805D86C5DA71B4C1396158C79711DCC2F56359D197ABDB890387FA795ED9288FD08851CC620D0357A3450B4C50CF61EABA54A44FD61203F557946027B36224148EB4AEEE709401296BE0B617604B6A48244938279D66CAC75F03809ED49421F518A3270F42273E37793D6162B626771D69C8A27AF27AD0A3B89B6C756068565FB65D245A88D180741A1AA507E116DC504C11358C7EB444180792D210438F96CCB3DC17D8E8B8E79918A106787509B8B570B093C325B8CB81A12A686CACADA32389B8207108E7AEF5447217843932559F1893B250DB8060D068D6D2B06999C36F412D47519C795A7284E3CDD42CA6304C348AAA96E72B8C64C37C92C34F78C56A58B32630812A95F53FFE4B3987B5146E0321AC254573933D03E7356628727F448CF3D9A328C1CA72B59B73AC3F0A3671FF58A604AA5FA7F63ED7C72965A833B5916266796757186784882CE8670CE4F717F057A1C08563B9832B89A759F2380C74821379B343E7E28BEAE6334CDB896587C2585508A78947A54B08055C3C6CAC9357102CDAE58748A337D511BD0BE93C88964720C3AB5367478A4BB82FC148539C1D54F54CD7B1605C113D4E526BEDC4CD8526892198336F344B1A59A83F3ABC890C9AC386954A6B521FC76FFC03B614C32E7F68868400142BD041347614A80A7A59F2511A28B1E6F74053842C8F0A49FA17C378FC0992E14282E394034081AA4164C2E9934E5C8246E334AC606B9BA723237144AB2AAA8E86B2ED33B6750CA239F82C9105CEC46888BD59B2AE6331F47501C01805BF867A63F1B211306009C7B60FE4AB7EC5982B1955059A5D69BB728FAB31681CB0418C033B676158501FD3011A3B6B44503378C2FA1C6EC254861532DCC16F78D743DD065C8F8781F798633B0CAE5172173AE78A02DA472C0BB4DDCB2EC88B70E69C24FF277837646802774C98D87ED20382E4A82C0EB905CCAAA977295AA085A26717578E04B27139B98D260155C0B6189A3A6AA77D0CA76B6409032D3868967C1A5B5AB747B2B1660715F15161E00C383B957062509C495C5B25C26B2EA26B3A74597B913D295728B33A9EC914A2E646ADF0968E07592E48BA1BF0817995B321F05A7DD8FA892A385ED4C052B0CAB7C84945FABA63F2099BBD960843F4ADB512A48991A38439B71D291512333483E8A511FB925A7A770E033EFE6A933F105DF2B5555BE5179F3B8DD8F216B0EC87AD297B5AE941BBD80BFB0A417824A420489CC9281DD1D545BF15C8459627C4E8684D018473EACB1C49C27564614417A9EF6984D708B1FDC03F08453A769C470156884DCC30C18A1970022B01CA2DD0928F50404A9B19CA41FC8C325323EAE97C484015289A5383B5A46DA19641A99DB8763B8E716DF656204616B07BA5C06EF11ABD428D9EC989D848A8CAF65B4CAA41A4F741A497A08EBC2FF8525149FB029FE867939255AB836DB23C87BE120559A99B64F4BE533C6F914149C45A221BE8A3F9C724FC9BB5782C9489346ACCF5CC69A94734C2AB332A272BF135E507163BB3019D9544151A56C1892706F86D40439BF311AC4A477BE17287F829015CCA7A2F416AA178493E9CC86E607C2266924256377E3171B1610F6CBC4654DB870E2A1A2F11774F6147810A44523036EEC6211410091AF54EC71ACC0212BB96CB3CADE37C55A67A3DDBB12FCB6E6DC758EB8B807F75CFB4E4AED460A67C9546C9D668E8F1A560A80D20707AA6A0CE9433BD8D283BCC743FCC9C9D23719C1A05A874339C80F079A5364842AC0F21F804B9BB5D6FF4387D19442C4BAD15A31FB9F5C9A5A0CF4C59A16FA309A69AAAC01C9F1F8817AC8B7DC0153478452C0A379D65A78BB3307E3CA4", - "dk": "275C73EE58A9FFD22DD3EB2B1590CD79407D35E950370892C6B2AAB97392D8200DA10AB7188B9909B191D32073926860F5F5A4D2C21C52F4AF2EF5066BF182A7156D0400319CB462CEA5A2C65126943158823B085B6118449401D5C17A67D9A0CE2C5FEEF515787A423C7446EE795C14B61D33AC8BD06A3D8CA5A78AE5A4BCAB1E5BAA336A4B8DF423A9072A511A98993DF205971C70D84CADF5ABAF5917741B34AE09D280375819059618D748AC48CB425EC54F7A7435C40442FD594EB1C081AE4A80F9D023FDC968968A482BE95A9CD03041CB8B8F3918A5B7957E5CA6C95053A55CB7DA014B15425C6637000C131A664318834C09DE92BC04172209D945C97AAB3240A93559569D03793560AD9C552FBC467516556E4A07A1DCF2A2D2C5332E5074128207E4E4491A8866D760791A18CBC7939835F02DDEC71964428D80AC730FCBB0F0C206434746F75C2A4D95CFD4C398507729845C257D17549AA2983290558453445C3CA35B6BB139B007B003A890996ABF463D5E12CF3DF0728B8259A7854F6A06999C92868AC16C9BB78F571972AA122975C25A68C31B73710DD2EC07C2103BDBFC1A67E7370444CD2394913218816AEA4E1043BF53B83377D4775BAC602871C79A28AD930316FA091E5678582A552B6A5CBEBE25CB6F9C9002469E29F1833FB049D2CA7040499170F4B6BE2915E7C10081DB012DC8B9A8AA2F1FA6A6D3FABFD49B7873C234A21B0C9B572401F80908D7370C4A5BB1D04CF9218CCC5C8BEE0660CB2ABC39501E3F2AA441168B6BC9435A9599EC571D39A35B49FBA16DDC4A3C88828D4B89390B77006026E85A46335354B2B422DE7AAEF60087E2F975A7453FDD6C56B75181F317969F95B7A024A1AE12B66FDBBF27186BB0C0896DE69C5DA5AE4CB638E43A8FA8C283B92687DA372AEF4569826803613824A5DC288E94345209A4D2B42DCF2A251917735636669C3AC06E72A835042504CB6A83026CA4B1A10DB29F9C229575599295881A7358C5949469ACC8B43AC80B4D0CAAB50846CC999B42E0299159049DD370A9B52878AC4B64547E3EC070B4D370B19924D90C6EF153232CF12E64D0BD04E124C55CB2B8D1376A46CE2B91A225985F7BD72D3B316767B3BD3206C5C8B311122300225A02F0E53664CB02B1350859D579A09710EAB927C5207256AC1128C6B0E09C7BBA408A2DC34C1160A8B13766BAC2A747A6BF20B1A6A22992451BA49CB5B97F7597F98B95E44B9B598AA993073ADBD6A9B5C81E10E21AAEA573A95A6716A3298412BE1D661746BB81C2F17744D587E3522143091FA215AC2D9B7C3C00397A1C3807F24AB4E968B0EA1A0E5A6601B7274469CD1A52AE5FAB7BAAB3C4A6D1A5D27A873E21A14DF52AE2C344BFE21B0F8A71A0511828E86F1FB08141C30C842538C61C7ADEB9251E33C73CEA9E7C02CF46E3C3E548355643000D3B715F339DE10745141B8D2A201A4D8C514185A6DC06375E35750E246D4CF1C8937955631CC7350CBC4C34C22B35C4336B95A12478419B8309E0137317B6CCDBAF70630BFD711783087967A93E1F95321EC319CA31004CF677D44359465564A889193FE04A7F8944EF30B5C0B43903279F07E2C04D116BE8322E9FAA4FA2562025910A264A814EA488D72CC03EB5853B40A406E1A7631933EC725D4E71516C751C3C0A3560BC0AD97078ACE63E9FC41A0F2B92B6E46A0836A39AE9B67C6B6F23A2A098987F3B6500ED179C6F14A0E0564166C5CF5C322A1E5654F8E083CD5B13ECD761B727020CDB5EAC5B9DF509AC0D9BCFD2A2976E586F90FC3949AAC845440FB929B9D5743723926FB2E6290EF3ABE663565AF1CC74587CDCB3034F7692D9488142231BE8651C5280A52EF048FD4C1C776210A39463CA0127A2F9065D6AB320E253A1A0C596E8797887844D8471A32795E6DA8D5774648AF25194C3AC8447C534B61C77F364D3136FB358861B05465AB09077912F536500F35002DF56015441A341E30D6458289F47B578B1BFE4C574228B0D16890108BA7D4DBC7EA8C9A5118AA6F6E48ED8E19B19F6629114551442CAB1E88541F09E85B79E123C912C967CBD4C273C47485EF552ACF2744AF83D72007137342D33A00F41EC9E0FE8AF0B641AC0F3BE42984D4D9C2E4D9393AB9992E78913A7DC3444AC5FB94668AD165BC9B4B09C50148831B0BFC0563D97B66913AB32846C9206BD2BEA024FB44B6DF239A8A82AD42C5BB69A77A3195AB8A7BD5C3131C9079D05E248D84167B6F569C812CDB1212F0584AEF9C0251FFA0E23A407BD592C7829C5D2A673DF01696AF02DD2A07A9342157EE608A2A91241DBB3F8725CD5D8BDA020C9107747F82A0FC7A97AC30272B694257B135095B27481CC769BB0834586CF70CAA72C2696B105A4B6440FB4D045B61A3D0BDA48490B22CE215C985B313F7C74155015A7D079DE9A2EF4DAB3ADD1A1CB684CA377B428B90D2BBB0980249586056434E2088EE250D065951EF228362B1D8028BC793CC8DCB8805D86C5DA71B4C1396158C79711DCC2F56359D197ABDB890387FA795ED9288FD08851CC620D0357A3450B4C50CF61EABA54A44FD61203F557946027B36224148EB4AEEE709401296BE0B617604B6A48244938279D66CAC75F03809ED49421F518A3270F42273E37793D6162B626771D69C8A27AF27AD0A3B89B6C756068565FB65D245A88D180741A1AA507E116DC504C11358C7EB444180792D210438F96CCB3DC17D8E8B8E79918A106787509B8B570B093C325B8CB81A12A686CACADA32389B8207108E7AEF5447217843932559F1893B250DB8060D068D6D2B06999C36F412D47519C795A7284E3CDD42CA6304C348AAA96E72B8C64C37C92C34F78C56A58B32630812A95F53FFE4B3987B5146E0321AC254573933D03E7356628727F448CF3D9A328C1CA72B59B73AC3F0A3671FF58A604AA5FA7F63ED7C72965A833B5916266796757186784882CE8670CE4F717F057A1C08563B9832B89A759F2380C74821379B343E7E28BEAE6334CDB896587C2585508A78947A54B08055C3C6CAC9357102CDAE58748A337D511BD0BE93C88964720C3AB5367478A4BB82FC148539C1D54F54CD7B1605C113D4E526BEDC4CD8526892198336F344B1A59A83F3ABC890C9AC386954A6B521FC76FFC03B614C32E7F68868400142BD041347614A80A7A59F2511A28B1E6F74053842C8F0A49FA17C378FC0992E14282E394034081AA4164C2E9934E5C8246E334AC606B9BA723237144AB2AAA8E86B2ED33B6750CA239F82C9105CEC46888BD59B2AE6331F47501C01805BF867A63F1B211306009C7B60FE4AB7EC5982B1955059A5D69BB728FAB31681CB0418C033B676158501FD3011A3B6B44503378C2FA1C6EC254861532DCC16F78D743DD065C8F8781F798633B0CAE5172173AE78A02DA472C0BB4DDCB2EC88B70E69C24FF277837646802774C98D87ED20382E4A82C0EB905CCAAA977295AA085A26717578E04B27139B98D260155C0B6189A3A6AA77D0CA76B6409032D3868967C1A5B5AB747B2B1660715F15161E00C383B957062509C495C5B25C26B2EA26B3A74597B913D295728B33A9EC914A2E646ADF0968E07592E48BA1BF0817995B321F05A7DD8FA892A385ED4C052B0CAB7C84945FABA63F2099BBD960843F4ADB512A48991A38439B71D291512333483E8A511FB925A7A770E033EFE6A933F105DF2B5555BE5179F3B8DD8F216B0EC87AD297B5AE941BBD80BFB0A417824A420489CC9281DD1D545BF15C8459627C4E8684D018473EACB1C49C27564614417A9EF6984D708B1FDC03F08453A769C470156884DCC30C18A1970022B01CA2DD0928F50404A9B19CA41FC8C325323EAE97C484015289A5383B5A46DA19641A99DB8763B8E716DF656204616B07BA5C06EF11ABD428D9EC989D848A8CAF65B4CAA41A4F741A497A08EBC2FF8525149FB029FE867939255AB836DB23C87BE120559A99B64F4BE533C6F914149C45A221BE8A3F9C724FC9BB5782C9489346ACCF5CC69A94734C2AB332A272BF135E507163BB3019D9544151A56C1892706F86D40439BF311AC4A477BE17287F829015CCA7A2F416AA178493E9CC86E607C2266924256377E3171B1610F6CBC4654DB870E2A1A2F11774F6147810A44523036EEC6211410091AF54EC71ACC0212BB96CB3CADE37C55A67A3DDBB12FCB6E6DC758EB8B807F75CFB4E4AED460A67C9546C9D668E8F1A560A80D20707AA6A0CE9433BD8D283BCC743FCC9C9D23719C1A05A874339C80F079A5364842AC0F21F804B9BB5D6FF4387D19442C4BAD15A31FB9F5C9A5A0CF4C59A16FA309A69AAAC01C9F1F8817AC8B7DC0153478452C0A379D65A78BB3307E3CA4D4F2CEEBE65173867CDDEC350D15A72CF1FEE868A9B819DD1DEB4E7478C00DECD16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/acvp.md b/test/jdk/sun/security/provider/acvp/data/acvp.md deleted file mode 100644 index 68e073b038fb0..0000000000000 --- a/test/jdk/sun/security/provider/acvp/data/acvp.md +++ /dev/null @@ -1,9 +0,0 @@ -# Automated Cryptographic Validation Test System Sample JSON files v1.1.0.36 - -## License - -NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. - -NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. - -You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. diff --git a/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java index 8be1b05cd85af..979d270d8a5a0 100644 --- a/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java +++ b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ * @modules java.base/sun.security.x509 * java.base/sun.security.provider.certpath * java.base/sun.security.util - * @library ../../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer + * @library /test/lib * @run main/othervm OCSPNoContentLength */ @@ -46,8 +45,8 @@ import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; public class OCSPNoContentLength { diff --git a/test/jdk/sun/security/provider/certpath/OCSP/OCSPReadTimeoutDefault.java b/test/jdk/sun/security/provider/certpath/OCSP/OCSPReadTimeoutDefault.java new file mode 100644 index 0000000000000..312435b002622 --- /dev/null +++ b/test/jdk/sun/security/provider/certpath/OCSP/OCSPReadTimeoutDefault.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347506 + * @summary Compatible OCSP readtimeout property with OCSP timeout + * @modules java.base/sun.security.provider.certpath + * @run main/othervm + * --add-opens java.base/sun.security.provider.certpath=ALL-UNNAMED + * OCSPReadTimeoutDefault 15000 + * @run main/othervm + * --add-opens java.base/sun.security.provider.certpath=ALL-UNNAMED + * -Dcom.sun.security.ocsp.timeout=6 + * OCSPReadTimeoutDefault 6000 + * @run main/othervm + * --add-opens java.base/sun.security.provider.certpath=ALL-UNNAMED + * -Dcom.sun.security.ocsp.timeout=6 -Dcom.sun.security.ocsp.readtimeout=1 + * OCSPReadTimeoutDefault 1000 + */ + +import java.lang.reflect.*; + +public class OCSPReadTimeoutDefault { + + public static void main(String[] args) throws Exception { + if (args == null || args.length < 1) { + throw new RuntimeException("Missing mandatory readtimeout value"); + } + + int expectedReadTimeout = Integer.parseInt(args[0]); + + Class ocspClazz = sun.security.provider.certpath.OCSP.class; + System.out.println("OCSP Class: " + ocspClazz); + + Field cto = ocspClazz.getDeclaredField("CONNECT_TIMEOUT"); + Field rto = ocspClazz.getDeclaredField("READ_TIMEOUT"); + cto.setAccessible(true); + rto.setAccessible(true); + int ctoVal = cto.getInt(null); + int rtoVal = rto.getInt(null); + + System.out.println("Expected read timeout: " + expectedReadTimeout); + System.out.println("CTOVal: " + ctoVal + ", RTOVal: " + rtoVal); + if (rtoVal != expectedReadTimeout) { + throw new RuntimeException("Expected read timeout value of " + + expectedReadTimeout + ", found " + rtoVal); + } + } +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/certpath/PKIXCertComparator/Order.java b/test/jdk/sun/security/provider/certpath/PKIXCertComparator/Order.java index b353a8748c930..77ed8a7b7b949 100644 --- a/test/jdk/sun/security/provider/certpath/PKIXCertComparator/Order.java +++ b/test/jdk/sun/security/provider/certpath/PKIXCertComparator/Order.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ * @modules java.base/sun.security.provider.certpath:+open * java.base/sun.security.x509 * java.base/sun.security.util - * @library /test/lib ../../../../../java/security/testlibrary - * @build CertificateBuilder + * @library /test/lib * @run main Order */ @@ -43,7 +42,7 @@ import sun.security.x509.X509CertImpl; import jdk.test.lib.Asserts; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.CertificateBuilder; public class Order { diff --git a/test/jdk/sun/security/provider/hss/TestHSS.java b/test/jdk/sun/security/provider/hss/TestHSS.java index 0af911f806be5..8056855cc1aca 100644 --- a/test/jdk/sun/security/provider/hss/TestHSS.java +++ b/test/jdk/sun/security/provider/hss/TestHSS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8298127 + * @bug 8298127 8347596 * @library /test/lib * @summary tests for HSS/LMS provider * @modules java.base/sun.security.util @@ -40,6 +40,7 @@ import java.security.spec.X509EncodedKeySpec; import java.util.HexFormat; +import jdk.test.lib.Asserts; import sun.security.util.*; import jdk.test.lib.util.SerializationUtils; @@ -61,9 +62,7 @@ public static void main(String[] args) throws Exception { i++; } - if (!serializeTest()) { - throw new RuntimeException("serializeTest failed"); - } + serializeTest(); System.out.println("All tests passed"); } @@ -88,7 +87,7 @@ static boolean kat(TestCase t) throws Exception { } } - static boolean serializeTest() throws Exception { + static void serializeTest() throws Exception { final ObjectIdentifier oid; var pk = decode(""" 00000002 @@ -106,7 +105,19 @@ static boolean serializeTest() throws Exception { throw new AssertionError(e); } - var keyBits = new DerOutputStream().putOctetString(pk).toByteArray(); + // Encoding without inner OCTET STRING + var pk0 = makeKey(oid, pk); + // Encoding with inner OCTET STRING + var pk1 = makeKey(oid, new DerOutputStream().putOctetString(pk).toByteArray()); + Asserts.assertEquals(pk0, pk1); + + PublicKey pk2 = (PublicKey) SerializationUtils + .deserialize(SerializationUtils.serialize(pk1)); + Asserts.assertEquals(pk1, pk2); + } + + static PublicKey makeKey(ObjectIdentifier oid, byte[] keyBits) + throws Exception { var oidBytes = new DerOutputStream().write(DerValue.tag_Sequence, new DerOutputStream().putOID(oid)); var x509encoding = new DerOutputStream().write(DerValue.tag_Sequence, @@ -115,11 +126,7 @@ static boolean serializeTest() throws Exception { .toByteArray(); var x509KeySpec = new X509EncodedKeySpec(x509encoding); - var pk1 = KeyFactory.getInstance(ALG).generatePublic(x509KeySpec); - - PublicKey pk2 = (PublicKey) SerializationUtils - .deserialize(SerializationUtils.serialize(pk1)); - return pk2.equals(pk1); + return KeyFactory.getInstance(ALG).generatePublic(x509KeySpec); } static boolean verify(byte[] pk, byte[] sig, byte[] msg) throws Exception { diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java index d6ec20c93d2ed..65311e9770154 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,8 +109,8 @@ public static void main(String args[]) throws Exception { } p.close(); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Djavax.net.debug=ssl,handshake" + " -Djava.security.properties=" + f.getName()); diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java index 57f61a6cd8a64..ff086e35a074b 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,8 +65,8 @@ public static void main(String[] args) throws Exception { sb.append(" "); }); String params = sb.toString(); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Dtest.root=" + System.getProperty("test.root") + " -Djavax.net.debug=ssl,handshake " + params diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java index f80270afd37dd..9a615f9b8846b 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,8 @@ public static void main(String[] args) throws Exception { StringBuilder sb = new StringBuilder(); Arrays.stream(args).forEach(a -> sb.append(a).append(" ")); String params = sb.toString(); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Dtest.root=" + System.getProperty("test.root") + " -Djavax.net.debug=ssl,handshake " + params); diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java index bff14113ea582..34c9cc940d5ea 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,8 +102,8 @@ public static void main(String[] args) throws Exception { sb.append(" ").append(args[i]); } String params = sb.toString(); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Dtest.root=" + System.getProperty("test.root") + " -Djavax.net.debug=ssl,handshake " + diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java index 888dba56a5023..645650674eadf 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,8 +60,8 @@ public static void main(String[] args) throws Exception { StringBuilder sb = new StringBuilder(); Arrays.stream(args).forEach(a -> sb.append(a).append(" ")); String params = sb.toString(); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Dtest.root=" + System.getProperty("test.root") + " -Djavax.net.debug=ssl,handshake " + params diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java index ea7f4895785f0..87db7eed2963d 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumptionUpdateBoundValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,8 +179,8 @@ SBListener doClientSide() throws Exception { public static void main(String[] args) throws Exception { if (args.length == 0) { - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Djavax.net.debug=ssl,handshake"); diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java index f0519a94249d6..fc26b60e4d45d 100644 --- a/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,8 +125,8 @@ public static void main(String args[]) throws Exception { } p.close(); System.out.println("Keyusage path = " + f.getAbsolutePath()); - System.setProperty("test.java.opts", - "-Dtest.src=" + System.getProperty("test.src") + + System.setProperty("test.java.opts", System.getProperty("test.java.opts") + + " -Dtest.src=" + System.getProperty("test.src") + " -Dtest.jdk=" + System.getProperty("test.jdk") + " -Djavax.net.debug=ssl,handshake" + " -Djava.security.properties=" + f.getName()); diff --git a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java index 5555363374ca9..57b16ed786223 100644 --- a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java +++ b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java @@ -23,10 +23,12 @@ /* * @test + * @library /test/lib + * @build jdk.test.lib.security.SimpleOCSPServer + * jdk.test.lib.security.CertificateBuilder * @bug 8046321 8339403 - * @library ../../../../java/security/testlibrary - * @build CertificateBuilder SimpleOCSPServer - * @run main/othervm -Djavax.net.debug=ssl:respmgr java.base/sun.security.ssl.StatusResponseManagerTests * @summary OCSP Stapling for TLS + * @run main/othervm -Djavax.net.debug=ssl:respmgr + * java.base/sun.security.ssl.StatusResponseManagerTests */ diff --git a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java index b210cfb26eaed..bdc1b5386088b 100644 --- a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java +++ b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,8 @@ import java.security.PublicKey; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.SimpleOCSPServer; -import sun.security.testlibrary.CertificateBuilder; +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; import static sun.security.ssl.CertStatusExtension.*; diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java new file mode 100644 index 0000000000000..50a723441a519 --- /dev/null +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Camerfirma.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.security.Security; +import java.time.*; +import java.util.*; +import javax.net.ssl.*; + +/** + * @test + * @bug 8346587 + * @summary Check that TLS Server certificates chaining back to distrusted + * Camerfirma roots are invalid + * @library /test/lib + * @modules java.base/sun.security.validator + * @run main/othervm Camerfirma after policyOn invalid + * @run main/othervm Camerfirma after policyOff valid + * @run main/othervm Camerfirma before policyOn valid + * @run main/othervm Camerfirma before policyOff valid + */ + +public class Camerfirma { + + private static final String certPath = "chains" + File.separator + "camerfirma"; + + // Each of the roots have a test certificate chain stored in a file + // named "-chain.pem". + private static String[] rootsToTest = new String[] { + "camerfirmachamberscommerceca", "camerfirmachambersca", + "camerfirmachambersignca"}; + + // Date after the restrictions take effect + private static final ZonedDateTime DISTRUST_DATE = + LocalDate.of(2025, 04, 16).atStartOfDay(ZoneOffset.UTC); + + public static void main(String[] args) throws Exception { + + // All of the test certificates are signed with SHA-1 so we need + // to remove the constraint that disallows SHA-1 certificates. + String prop = Security.getProperty("jdk.certpath.disabledAlgorithms"); + String newProp = prop.replace(", SHA1 jdkCA & usage TLSServer", ""); + Security.setProperty("jdk.certpath.disabledAlgorithms", newProp); + + Distrust distrust = new Distrust(args); + + X509TrustManager[] tms = new X509TrustManager[]{ + distrust.getTMF("PKIX", null), + distrust.getTMF("SunX509", null) + }; + + Date notBefore = distrust.getNotBefore(DISTRUST_DATE); + distrust.testCertificateChain(certPath, notBefore, tms, rootsToTest); + } +} diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Distrust.java b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Distrust.java index 18178f65ec116..3430a1b8276f3 100644 --- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Distrust.java +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/Distrust.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -198,7 +198,13 @@ public boolean[] getIssuerUniqueID() { public boolean[] getSubjectUniqueID() { return cert.getSubjectUniqueID(); } - public boolean[] getKeyUsage() { return cert.getKeyUsage(); } + public boolean[] getKeyUsage() { + // Turn on the Digital Signature bit. Some certs that we want + // to use as test certs don't have this bit turned on. + boolean[] withDigitalSignature = cert.getKeyUsage(); + withDigitalSignature[0] = true; + return withDigitalSignature; + } public int getBasicConstraints() { return cert.getBasicConstraints(); } public byte[] getEncoded() throws CertificateEncodingException { return cert.getEncoded(); diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersca-chain.pem b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersca-chain.pem new file mode 100644 index 0000000000000..f23c6dafeddf0 --- /dev/null +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersca-chain.pem @@ -0,0 +1,64 @@ +Owner: CN=Camerfirma Corporate Server II - 2015, + L=Madrid (see current address at https://www.camerfirma.com/address), + SERIALNUMBER=A82743287, + O=AC Camerfirma S.A., OU=AC CAMERFIRMA, C=ES +Issuer: CN=Chambers of Commerce Root - 2008, + O=AC Camerfirma S.A., SERIALNUMBER=A82743287, + L=Madrid (see current address at www.camerfirma.com/address), C=EU +Serial number: 621ff31c489ba136 +Valid from: Thu Jan 15 01:21:16 PST 2015 until: Tue Dec 15 01:21:16 PST 2037 +Certificate fingerprints: + SHA1: FE:72:7A:78:EA:0C:03:35:CD:DA:9C:2E:D7:5F:D4:D4:6F:35:C2:EF + SHA256: 66:EA:E2:70:9B:54:CD:D1:69:31:77:B1:33:2F:F0:36:CD:D0:F7:23:DB:30:39:ED:31:15:55:A6:CB:F5:FF:3E +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 + +-----BEGIN CERTIFICATE----- +MIIIkzCCBnugAwIBAgIIYh/zHEiboTYwDQYJKoZIhvcNAQELBQAwga4xCzAJBgNV +BAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQg +d3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcx +GzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwHhcNMTUwMTE1MDkyMTE2WhcNMzcxMjE1 +MDkyMTE2WjCB0zELMAkGA1UEBhMCRVMxFjAUBgNVBAsMDUFDIENBTUVSRklSTUEx +GzAZBgNVBAoMEkFDIENhbWVyZmlybWEgUy5BLjESMBAGA1UEBRMJQTgyNzQzMjg3 +MUswSQYDVQQHDEJNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgaHR0cHM6 +Ly93d3cuY2FtZXJmaXJtYS5jb20vYWRkcmVzcykxLjAsBgNVBAMMJUNhbWVyZmly +bWEgQ29ycG9yYXRlIFNlcnZlciBJSSAtIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC3ndKNpFufVq9v+15dRoT9oVkgwEfDdsPw0Ly0R+eM5MOk +35zEil/+hqEMbQmcvosAh6I8iAskkXasqh+SMbMIjvXbDyNILeGzsoP0uz3btHM7 +oN3yHXDhhd1NGNocP54Wehe9+RE3WP0yEEo+D2YmMwUHuv4KiXtveiPksv+Xkkz5 +auqppPMaYlD6y49AEsGY2zOEUI8PO4+tOxUKhvsiMuW817vH3VdmMwOjRe0SdYAi +YLQIiyqJGNdEo3u+fw8UXxaJSRXhmF+jUn5DvdzWWNAxxwAKy95EPlpLQsx/7t2W +2ntoELPHGJk4V+/yA0d2olLEqBADkRtP2HiC0wly+zp7OGmjtfjbqLrVjmo/mLP3 +zpmYbpUtubrHiY0rlW6wo5FZLcTUvcAxFjxLWVIELPjnTebOuHvoJTb97rhA1Oqq +woq5FWJHFI9idzXzFLO0LX/4ugI9LZWxmvWW0O4CePtnhp0aNE/GgAw6lMx7bjZe +DXxxQnUDEE/mAqOHRUCnvRUSKVbuBBE0oz5fz3nUwcWVVgrm/jkgqTX4EqnZe+yB +mKV6hFEYV+1oVh7kzNN4Hg7nzGuByS7cCuBEwULFhfUja1Bu9EqgndJ3CV0XCWIA +XVhJnPNPi6y4W11jLJ7XSGSz3sCh21g0Gpgi2pXHGDB65Jc/QJHZ5ZaHCrzFnwID +AQABo4ICjDCCAogwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUY+nw8FYA +aGWwIWwOXNcZCJ0INGUwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKe +FxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiCCQCj2kJ+ +pLGu2jB6BggrBgEFBQcBAQRuMGwwQgYIKwYBBQUHMAKGNmh0dHA6Ly93d3cuY2Ft +ZXJmaXJtYS5jb20vY2VydHMvcm9vdF9jaGFtYmVycy0yMDA4LmNydDAmBggrBgEF +BQcwAYYaaHR0cDovL29jc3AuY2FtZXJmaXJtYS5jb20wDgYDVR0PAQH/BAQDAgEG +MCcGA1UdJQQgMB4GCCsGAQUFBwMEBggrBgEFBQcDAgYIKwYBBQUHAwEwPgYDVR0g +BDcwNTAzBgRVHSAAMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vcG9saWN5LmNhbWVy +ZmlybWEuY29tMHgGA1UdHwRxMG8wNaAzoDGGL2h0dHA6Ly9jcmwuY2FtZXJmaXJt +YS5jb20vY2hhbWJlcnNyb290LTIwMDguY3JsMDagNKAyhjBodHRwOi8vY3JsMS5j +YW1lcmZpcm1hLmNvbS9jaGFtYmVyc3Jvb3QtMjAwOC5jcmwwDQYJKoZIhvcNAQEL +BQADggIBAKhqaZwalwf89f4wPqfcE/lrsHdx8+q9RG46ouBXhTJMqXjwstXOZSL4 +3Dqs3GaVuMPIM9OG7CK0I93mAt+FWtr49ACFTyPBxPg/knrZ4RHyEto+/6w0WZ9H +owNw0aUg3ZAkhIvMRPVou8PrVukqj2lGKIh3hRdrbHwYwwmKKNlWBoC9gWk3mTYU +zfNt/KTzQCCl5+s6YDa+XInMLWaGd/pE/e++a22vY24cv7kN3NAFMjAMELPwh9ic +zLoPX8B52r+GgwpKY0c0hZdVTii6psLQ+BenyMlh+6lHRBOlTCSRtNi16o7H8fRq +CY2wyQi7N+EmdY1DhvECCi1nLbOnIx1bSAW0cVwPVrjQ/vsAxPNc3SGe/Xnanm3a +zAgFspzeuAhxxG0VKOvtPBnPQNsQ0cK664+IrWRsfa6aYhEfKvfsn5o4HpBWDobf +zrtNbqjjOuiM6JkT+DxXo5UK7t2q75KCJiimTtAuPcZ5wErZISLvZ34BodIHL2xK +b3Vww7K2FE1QaNsuQkGbUk++B9/+vV3H57vzskObdFWeWKSCpxIil4vZwIIH17zn +WU+O2WIY1F0aO9zp3E7qwfmYT4MJ38NF9R7FSlxRlgVc1uUHu/iyUU4N1O6F3VdX +P2Y+tgLFZLYV4kApfXk5l9h94dgKyfVcIpvS6yVpLfONPnlCNOxy +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem new file mode 100644 index 0000000000000..b27d46c17c8cf --- /dev/null +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachamberscommerceca-chain.pem @@ -0,0 +1,48 @@ +Owner: CN=AC Camerfirma Certificados Camerales, + O=AC Camerfirma SA, SERIALNUMBER=A82743287, + L=Madrid (see current address at www.camerfirma.com/address), + EMAILADDRESS=ac_camerfirma_cc@camerfirma.com, C=ES +Issuer: CN=Chambers of Commerce Root, OU=http://www.chambersign.org, + O=AC Camerfirma SA CIF A82743287, C=EU +Serial number: 5 +Valid from: Mon Feb 09 07:42:47 PST 2004 until: Thu Feb 09 07:42:47 PST 2034 +Certificate fingerprints: + SHA1: 9F:36:B4:BE:9D:AF:1C:91:01:B2:D7:61:58:FB:95:CB:53:82:01:10 + SHA256: C7:D8:43:81:E1:1F:7C:57:46:77:1A:F5:B0:50:DC:51:FC:6F:DA:D6:F6:F3:5B:B5:3A:3D:E9:13:82:2E:A0:9E +Signature algorithm name: SHA1withRSA (weak) +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 + +-----BEGIN CERTIFICATE----- +MIIFwDCCBKigAwIBAgIBBTANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdDAeFw0wNDAyMDkxNTQyNDdaFw0zNDAyMDkxNTQyNDda +MIHgMQswCQYDVQQGEwJFUzEuMCwGCSqGSIb3DQEJARYfYWNfY2FtZXJmaXJtYV9j +Y0BjYW1lcmZpcm1hLmNvbTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh +ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRkwFwYDVQQKExBBQyBDYW1lcmZpcm1hIFNBMS0wKwYDVQQDEyRB +QyBDYW1lcmZpcm1hIENlcnRpZmljYWRvcyBDYW1lcmFsZXMwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQCjxnvvj01f36lgGhihRYVf1fAPEXsTJKrY4aLQ +cEUSh5szZE7VTtGiyMTMc2uCmnaXafjYHK8Lgmy6T9xxGEZ5OS4x6rgtuPyy13AP +tu3X3Y2kPVLu7ZMw5HoQC64wBj6YcnxTnBwmVW05DjzRXp6OyBIEKEaAB9vv2qEl +fh/Y234FG6Wd/ut1s0ScRZAo+6CSMNQxaY+ryXKD11uWkzWXJa9UZOasG7z4uPqc +Gr4/Hz2/CTLDTgp0xkMJYuzOztpUvOACrxlkS2utKUwVlAikJnboNwf/en94RbHN +zkKc5t0SAbzCf57ueawbzxSdPa+SAC25FNur64FKkfdq5PPjAgEDo4IB5TCCAeEw +EgYDVR0TAQH/BAgwBgEB/wIBCzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3Js +LmNoYW1iZXJzaWduLm9yZy9jaGFtYmVyc3Jvb3QuY3JsMB0GA1UdDgQWBBS2H06d +HGiRLjdyYOFGj1qlKjExuTCBqwYDVR0jBIGjMIGggBTjlPWxTenboSlbV4tNdgZ2 +4dGiiqGBhKSBgTB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJz +aWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdIIBADAO +BgNVHQ8BAf8EBAMCAYYwKgYDVR0RBCMwIYEfYWNfY2FtZXJmaXJtYV9jY0BjYW1l +cmZpcm1hLmNvbTAnBgNVHRIEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24u +b3JnMFsGA1UdIARUMFIwUAYLKwYBBAGBhy4KCQEwQTA/BggrBgEFBQcCARYzaHR0 +cDovL2Nwcy5jYW1lcmZpcm1hLmNvbS9jcHMvYWNfY2FtZXJmaXJtYV9jYy5odG1s +MA0GCSqGSIb3DQEBBQUAA4IBAQBl8KoPBYL//EBonqQWS0N+hLfxImP1eQ6nac+v +R5QfF/0w+VCTkShfKwHaa6V/W1dPlVwXSECuvXHkX6DYrtxFGGFB6qxuP1rkIpRs +sTkAlpvOx3REiFjIkhsijKd/ijvqxjbMbuYU+EFACK/jQIRoj+LEEZ+haiqbALZB +Iqq/26HTqX0itDosBj6M94YWcIpbTDefQNWCGsSnZcw2+k+az/wAOZT6xAxlnEim +HpDDlgRsmaLrHpDPDoIRYOih0gbJTnn4mKex9Wgr0sZ+XFl03j+bvcXL1tiuQnwb +9dMRDe/OdXABT35W4ZzLbpost65ZW3Tx+oi/bLbmu6pbKCgs +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem new file mode 100644 index 0000000000000..2ab3091439cb9 --- /dev/null +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/distrust/chains/camerfirma/camerfirmachambersignca-chain.pem @@ -0,0 +1,62 @@ +Owner: CN=AC Camerfirma - 2009, + L=Madrid (see current address at https://www.camerfirma.com/address), + SERIALNUMBER=A82743287, O=AC Camerfirma S.A., C=ES +Issuer: CN=Global Chambersign Root - 2008, + O=AC Camerfirma S.A., SERIALNUMBER=A82743287, + L=Madrid (see current address at www.camerfirma.com/address), C=EU +Serial number: 2 +Valid from: Mon Mar 16 10:16:25 PDT 2009 until: Sun Mar 11 10:16:25 PDT 2029 +Certificate fingerprints: + SHA1: BA:BA:69:CF:D5:CC:C9:4D:05:6B:5B:E7:80:5F:E2:03:CB:EB:5C:57 + SHA256: B6:8D:5D:9B:4E:A6:35:95:7C:0C:32:15:C2:0D:35:B2:21:7B:69:E3:49:C7:A3:04:C4:F9:7F:20:C4:08:1F:88 +Signature algorithm name: SHA1withRSA (weak) +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 + +-----BEGIN CERTIFICATE----- +MIIIPzCCBiegAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBrDELMAkGA1UEBhMCRVUx +QzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2Ft +ZXJmaXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UE +ChMSQUMgQ2FtZXJmaXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNp +Z24gUm9vdCAtIDIwMDgwHhcNMDkwMzE2MTcxNjI1WhcNMjkwMzExMTcxNjI1WjCB +qjELMAkGA1UEBhMCRVMxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjESMBAG +A1UEBRMJQTgyNzQzMjg3MUswSQYDVQQHE0JNYWRyaWQgKHNlZSBjdXJyZW50IGFk +ZHJlc3MgYXQgaHR0cHM6Ly93d3cuY2FtZXJmaXJtYS5jb20vYWRkcmVzcykxHTAb +BgNVBAMTFEFDIENhbWVyZmlybWEgLSAyMDA5MIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEAmbHxFEYTJmMdPcYiPlWUGZu2+tQo4voohYi3dwCwoVuGdHSp +kyoqs1B3YGx4u5KT4n0A7+Bb8YQ/QzbNy7UQ4JXAK+rT8JpNeKIvfN4lHnQJaChE +4fdn0KpvHWymaNq2k+EbQClquZB6OsTLvsivwSuSnyLcUw5rbajj53wq77fwB12y +phMjwz2AnD1BvHZd3vLOaH1jRQP3zzNmyjT/Oj6+jdux7SBKlJWgQEaKflwcvYyc +DPFPhGM4KPwEGX61PCrS+l8Lw0Kdy6K4lE+GrfgJrXM5m1Ey1R0c9McYQQPAtYcm +cOnHHgkJdEAFVDa76T9C+lcMP6DNckbJIyc/ENrmM2v4rq/JnsJKEEx0VLyLizQx +cGU3gp4ckg0ImQ9hV3H/DLWEqfrPuD++zaV81gpstnc9+pLg0Jibvwg3qvIr7nS5 +acc//qqxH0iJGYoStHW5J5HoM9HcBvhACq5rjzjrNLPYSJqbPJwBHKcql/uUjQ6S +SVWe3/CeJp6/vGuY1aRXAk9c/8oO0ZDrLKE8LsUgZesTLnWGd1LQcyQf6UMG1nb9 +5C3eZRkCVpKma6Hl/SUQNukerlbLOU9InFGNPdeEVq1Jo62XeEi8KMbTPdXou6Yl +rpe99dFnOUjVOdY7gfBGSgIVJjORqf/V70jwsxcYz7j6PKl0XulJs06vpSECAwEA +AaOCAmowggJmMBIGA1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFMgAD/zGUvyf +2ztkLjK5bi5x82V5MIHhBgNVHSMEgdkwgdaAFLkJypwe29NsOmuu7VTxW5MGNS5e +oYGypIGvMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOIIJAMnN0+nVfSPO +MH0GCCsGAQUFBwEBBHEwbzBFBggrBgEFBQcwAoY5aHR0cDovL3d3dy5jYW1lcmZp +cm1hLmNvbS9jZXJ0cy9yb290X2NoYW1iZXJzaWduLTIwMDguY3J0MCYGCCsGAQUF +BzABhhpodHRwOi8vb2NzcC5jYW1lcmZpcm1hLmNvbTAOBgNVHQ8BAf8EBAMCAQYw +PgYDVR0gBDcwNTAzBgRVHSAAMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vcG9saWN5 +LmNhbWVyZmlybWEuY29tMH4GA1UdHwR3MHUwOKA2oDSGMmh0dHA6Ly9jcmwuY2Ft +ZXJmaXJtYS5jb20vY2hhbWJlcnNpZ25yb290LTIwMDguY3JsMDmgN6A1hjNodHRw +Oi8vY3JsMS5jYW1lcmZpcm1hLmNvbS9jaGFtYmVyc2lnbnJvb3QtMjAwOC5jcmww +DQYJKoZIhvcNAQEFBQADggIBABNYG4jBwoI7e8pCuUyDc6rwpE9H6AgrUdL7O1xK +TgTjDGBrMOBK+ZPS4Si8J3yZngvSrL694a1HmiiblJ+CmCdNGli2nBBM+OPK3tQB +4TW6hgkIe3vSNg/9o9y6+MAJcm8Kn0nPCBkSRME87NwvpehtekuF1G2ng1KDVwAn +F+eCXfNanEwY++vWbJAuPE69Z/0+rCgNyH1PzihiNu6vrUlSlLWKaG34O1DEttX+ +SsWTpEbpH9w5y9Vmw6WQ/B5nfhPM551HaMbiGgSxT9jHmf8APYQ3iT8EktcdTAdw +m1miiyxfKG+WjPT7P/x8Np1spJZw+sNIDTLdZ0T1XQ6obVkBTFUDSULKW8949HDu +VSwdl9Hu9lkDzzh9tyVYwwjEWVFZOiD/4TPVLfphf4ZEiyHt5YpNd9kZJIGGDxdc +CdtzPm2dQODFpv72LnPQHbuBQPJ71zkoAmyeM/1Qj0DlrFsPcYnbRasck1VmYgDc +Xc0+is0wcgCd7Gpx1zpEeVqwMD96am2xZPzd6nsbXvo+6TzsKLRMJo6nOERwrzuI +F+/eq3WXxYMt2UenJsHqwSgPJRMdl3SFz0+SZN0viHeLuwb7qaHN74qC6GP8yHGp +2xe6Z11mJDPLDSrQQ2dOceSJ1LurJgLP7amYmFlWwVnmM7LnfShhMWMV+MDrICnL +2ksL +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/tools/jarsigner/CertChainUnclosed.java b/test/jdk/sun/security/tools/jarsigner/CertChainUnclosed.java index 7ec4d88d73a0f..d658dd9504c55 100644 --- a/test/jdk/sun/security/tools/jarsigner/CertChainUnclosed.java +++ b/test/jdk/sun/security/tools/jarsigner/CertChainUnclosed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,15 +32,12 @@ import java.nio.file.Files; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; public class CertChainUnclosed { public static void main(String[] args) throws Exception { - String os = AccessController.doPrivileged( - (PrivilegedAction)() -> System.getProperty("os.name")); + String os = System.getProperty("os.name"); if (!os.toUpperCase(Locale.US).contains("WINDOWS")) { System.out.println("Not Windows. Skip test."); return; diff --git a/test/jdk/sun/security/tools/jarsigner/CheckSignerCertChain.java b/test/jdk/sun/security/tools/jarsigner/CheckSignerCertChain.java index da409612efee7..eb3b9395b9167 100644 --- a/test/jdk/sun/security/tools/jarsigner/CheckSignerCertChain.java +++ b/test/jdk/sun/security/tools/jarsigner/CheckSignerCertChain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,10 +81,10 @@ public static void main(String[] args) throws Exception { "-sigalg SHA256withRSA " + "-verbose" + " a.jar e1") - .shouldContain("Signature algorithm: SHA1withRSA (disabled), 2048-bit key") + .shouldContain("Signature algorithm: SHA1withRSA (disabled), 2048-bit RSA key") // For trusted cert, warning should be generated for its weak 1024-bit // key, but not for its SHA1withRSA algorithm. - .shouldContain("Signature algorithm: SHA1withRSA, 1024-bit key (weak)") + .shouldContain("Signature algorithm: SHA1withRSA, 1024-bit RSA key (weak)") .shouldHaveExitValue(0); kt("-exportcert -alias ca -rfc -file cacert", "ks"); @@ -92,10 +92,10 @@ public static void main(String[] args) throws Exception { SecurityTools.jarsigner("-verify -certs signeda.jar " + "-keystore caks -storepass changeit -verbose -debug") - .shouldContain("Signature algorithm: SHA1withRSA (disabled), 2048-bit key") + .shouldContain("Signature algorithm: SHA1withRSA (disabled), 2048-bit RSA key") // For trusted cert, warning should be generated for its weak 1024-bit // key, but not for its SHA1withRSA algorithm. - .shouldContain("Signature algorithm: SHA1withRSA, 1024-bit key (weak)") + .shouldContain("Signature algorithm: SHA1withRSA, 1024-bit RSA key (weak)") .shouldHaveExitValue(0); /* @@ -118,8 +118,8 @@ public static void main(String[] args) throws Exception { "-J-Djava.security.properties=" + JAVA_SECURITY_FILE + " a.jar ee") - .shouldNotContain("Signature algorithm: MD5withRSA (disabled), 2048-bit key") - .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit key") + .shouldNotContain("Signature algorithm: MD5withRSA (disabled), 2048-bit RSA key") + .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit RSA key") .shouldNotContain("Invalid certificate chain: Algorithm constraints check failed on signature algorithm: MD5withRSA") .shouldHaveExitValue(0); @@ -134,8 +134,8 @@ public static void main(String[] args) throws Exception { "-J-Djava.security.properties=" + JAVA_SECURITY_FILE + " a.jar ee") - .shouldContain("Signature algorithm: MD5withRSA (disabled), 2048-bit key") - .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit key") + .shouldContain("Signature algorithm: MD5withRSA (disabled), 2048-bit RSA key") + .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit RSA key") .shouldContain("Invalid certificate chain: Algorithm constraints check failed on disabled algorithm: MD5 used with certificate: CN=EE") .shouldHaveExitValue(0); @@ -144,8 +144,8 @@ public static void main(String[] args) throws Exception { SecurityTools.jarsigner("-verify -certs signeda.jar " + "-keystore caks1 -storepass changeit -verbose -debug") - .shouldContain("Signature algorithm: MD5withRSA (disabled), 2048-bit key") - .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit key") + .shouldContain("Signature algorithm: MD5withRSA (disabled), 2048-bit RSA key") + .shouldContain("Signature algorithm: SHA384withRSA, 2048-bit RSA key") .shouldContain("Invalid certificate chain: Algorithm constraints check failed on disabled algorithm: MD5 used with certificate: CN=EE") .shouldHaveExitValue(0); } diff --git a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java index 69b45ea22930d..e81a25712a6b2 100644 --- a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java +++ b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,8 +43,15 @@ public class ConciseJarsigner { static OutputAnalyzer kt(String cmd) throws Exception { // Choose 2048-bit RSA to make sure it runs fine and fast. In // fact, every keyalg/keysize combination is OK for this test. - return SecurityTools.keytool("-storepass changeit -keypass changeit " - + "-keystore ks -keyalg rsa -keysize 2048 " + cmd); + // The start date is set to -1M to prevent the certificate not yet valid during fast enough execution. + // If -startdate is specified in cmd, cmd version will be used. + if (cmd.contains("-startdate")) { + return SecurityTools.keytool("-storepass changeit -keypass changeit " + + "-keystore ks -keyalg rsa -keysize 2048 " + cmd); + } else { + return SecurityTools.keytool("-storepass changeit -keypass changeit " + + "-keystore ks -keyalg rsa -keysize 2048 -startdate -1M " + cmd); + } } static void gencert(String owner, String cmd) throws Exception { diff --git a/test/jdk/sun/security/tools/jarsigner/DisableCurveTest.java b/test/jdk/sun/security/tools/jarsigner/DisableCurveTest.java index 353f82ad4b239..ee83c95333cc5 100644 --- a/test/jdk/sun/security/tools/jarsigner/DisableCurveTest.java +++ b/test/jdk/sun/security/tools/jarsigner/DisableCurveTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception{ .shouldContain(">>> Signer") .shouldContain("Signature algorithm: SHA384withECDSA, 256-bit EC (secp256r1) key (disabled)") .shouldContain("Warning:") - .shouldContain("The EC (secp256r1) signing key has a keysize of 256 which is considered a security risk and is disabled") + .shouldContain("The 256-bit EC (secp256r1) signing key is considered a security risk and is disabled") .shouldHaveExitValue(0); SecurityTools.jarsigner("-verify signeda.jar " + @@ -84,7 +84,7 @@ public static void main(String[] args) throws Exception{ .shouldContain(">>> Signer") .shouldContain("Signature algorithm: SHA384withECDSA, 256-bit EC (secp256r1) key (weak)") .shouldContain("Warning:") - .shouldContain("The EC (secp256r1) signing key has a keysize of 256 which is considered a security risk. This key size will be disabled in a future update") + .shouldContain("The 256-bit EC (secp256r1) signing key is considered a security risk. It will be disabled in a future update") .shouldHaveExitValue(0); SecurityTools.jarsigner("-verify signeda.jar " + @@ -94,7 +94,7 @@ public static void main(String[] args) throws Exception{ .shouldContain("- Signed by") .shouldContain("Signature algorithm: SHA384withECDSA, 256-bit EC (secp256r1) key (weak)") .shouldContain("jar verified") - .shouldContain("The EC (secp256r1) signing key has a keysize of 256 which is considered a security risk. This key size will be disabled in a future update") + .shouldContain("The 256-bit EC (secp256r1) signing key is considered a security risk. It will be disabled in a future update") .shouldHaveExitValue(0); } } diff --git a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java index c4cf1ef6a985d..bddc8c0e5fb5e 100644 --- a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java +++ b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -448,8 +448,8 @@ public static void main(String[] args) throws Throwable { .shouldNotContain("The SHA-256 algorithm specified " + "for the -tsadigestalg option is considered a " + "security risk") - .shouldContain("The RSA signing key has a keysize " + - "of 1024 which is considered a security risk") + .shouldContain("The 1024-bit RSA signing key " + + "is considered a security risk") .shouldHaveExitValue(0); checkMultipleWeak("sign2.jar"); diff --git a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java index 9b84f548c703d..3be1e74d97269 100644 --- a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java +++ b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -718,7 +718,8 @@ private static void verifying(SignItem signItem, VerifyItem verifyItem) String match = "^ (" + " Signature algorithm: " + signItem.certInfo. expectedSigalg(signItem) + ", " + signItem.certInfo. - expectedKeySize() + "-bit key" + expectedKeySize() + "-bit " + signItem.certInfo. + expectedKeyAlgorithm() + " key" + ")|(" + " Digest algorithm: " + signItem.expectedDigestAlg() + (isWeakAlg(signItem.expectedDigestAlg()) ? " \\(weak\\)" : "") @@ -1224,6 +1225,12 @@ private String expectedSigalg(SignItem signer) { } } + private String expectedKeyAlgorithm() { + return keyAlgorithm.equals("EC") + ? ("EC .secp" + expectedKeySize() + "r1.") + : keyAlgorithm; + } + private int expectedKeySize() { if (keySize != 0) return keySize; diff --git a/test/jdk/sun/security/tools/jarsigner/warnings/Test.java b/test/jdk/sun/security/tools/jarsigner/warnings/Test.java index 71d4ee144b99b..0683c03c10ce7 100644 --- a/test/jdk/sun/security/tools/jarsigner/warnings/Test.java +++ b/test/jdk/sun/security/tools/jarsigner/warnings/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -149,7 +149,7 @@ public abstract class Test { + "This algorithm will be disabled in a future update."; static final String WEAK_KEY_WARNING - = "This key size will be disabled in a future update."; + = "It will be disabled in a future update."; static final String JAR_SIGNED = "jar signed."; diff --git a/test/jdk/sun/security/tools/keytool/GenKeyPairSigner.java b/test/jdk/sun/security/tools/keytool/GenKeyPairSigner.java index 84cfcd7cb17de..113ff2859d549 100644 --- a/test/jdk/sun/security/tools/keytool/GenKeyPairSigner.java +++ b/test/jdk/sun/security/tools/keytool/GenKeyPairSigner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,14 +77,14 @@ static void testSignerPKCS12() throws Exception { SecurityTools.keytool("-keystore ks -storepass changeit " + "-genkeypair -keyalg EdDSA -alias ca -dname CN=CA -ext bc:c " + "-ext 2.5.29.14=04:14:00:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16:17:18:19") - .shouldContain("Generating 255 bit Ed25519 key pair and self-signed certificate (Ed25519) with a validity of 90 days") + .shouldContain("Generating Ed25519 key pair and self-signed certificate (Ed25519) with a validity of 90 days") .shouldContain("for: CN=CA") .shouldHaveExitValue(0); System.out.println("Generating an XDH cert with -signer option"); SecurityTools.keytool("-keystore ks -storepass changeit " + "-genkeypair -keyalg XDH -alias e1 -dname CN=E1 -signer ca") - .shouldContain("Generating 255 bit X25519 key pair and a certificate (Ed25519) issued by with a validity of 90 days") + .shouldContain("Generating X25519 key pair and a certificate (Ed25519) issued by with a validity of 90 days") .shouldContain("for: CN=E1") .shouldHaveExitValue(0); @@ -118,7 +118,7 @@ static void testSignerPKCS12() throws Exception { .shouldContain("Alias name: e1") .shouldContain("Certificate chain length: 2") .shouldContain("Signature algorithm name: Ed25519") - .shouldContain("Subject Public Key Algorithm: 255-bit X25519 key") + .shouldContain("Subject Public Key Algorithm: X25519 key") .shouldHaveExitValue(0); // check to make sure that cert's AKID is created from the SKID of the signing cert @@ -150,7 +150,7 @@ static void testSignerPKCS12() throws Exception { System.out.println("Generating an X448 cert with -signer option"); SecurityTools.keytool("-keystore ks -storepass changeit " + "-genkeypair -keyalg X448 -alias e2 -dname CN=E2 -sigalg SHA384withRSA -signer ca2") - .shouldContain("Generating 448 bit X448 key pair and a certificate (SHA384withRSA) issued by with a validity of 90 days") + .shouldContain("Generating X448 key pair and a certificate (SHA384withRSA) issued by with a validity of 90 days") .shouldContain("for: CN=E2") .shouldHaveExitValue(0); @@ -177,7 +177,7 @@ static void testSignerPKCS12() throws Exception { "-list -v") .shouldContain("Alias name: e2") .shouldContain("Signature algorithm name: SHA384withRSA") - .shouldContain("Subject Public Key Algorithm: 448-bit X448 key") + .shouldContain("Subject Public Key Algorithm: X448 key") .shouldHaveExitValue(0); kt("-genkeypair -keyalg DSA -alias ca3 -dname CN=CA3 -ext bc:c ", @@ -186,7 +186,7 @@ static void testSignerPKCS12() throws Exception { System.out.println("Generating a DH cert with -signer option"); SecurityTools.keytool("-keystore ks -storepass changeit " + "-genkeypair -keyalg DH -alias e3 -dname CN=E3 -signer ca3") - .shouldContain("Generating 3,072 bit DH key pair and a certificate (SHA256withDSA) issued by with a validity of 90 days") + .shouldContain("Generating 3072-bit DH key pair and a certificate (SHA256withDSA) issued by with a validity of 90 days") .shouldContain("for: CN=E3") .shouldHaveExitValue(0); @@ -239,7 +239,7 @@ static void testSignerJKS() throws Exception { SecurityTools.keytool("-keystore ksjks -storepass changeit -storetype jks " + "-genkeypair -keyalg DSA -keysize 1024 -alias ca1 -dname CN=CA1 " + "-keypass ca1keypass -signer ca -signerkeypass cakeypass") - .shouldContain("Generating 1,024 bit DSA key pair and a certificate (SHA384withRSA) issued by with a validity of 90 days") + .shouldContain("Generating 1024-bit DSA key pair and a certificate (SHA384withRSA) issued by with a validity of 90 days") .shouldContain("for: CN=CA1") .shouldContain("The generated certificate #1 of 2 uses a 1024-bit DSA key which is considered a security risk") .shouldContain("The generated certificate #2 of 2 uses a 1024-bit RSA key which is considered a security risk") @@ -249,7 +249,7 @@ static void testSignerJKS() throws Exception { SecurityTools.keytool("-keystore ksjks -storepass changeit -storetype jks " + "-genkeypair -keyalg XDH -alias e1 -dname CN=E1 " + "-keypass e1keypass -signer ca1 -signerkeypass ca1keypass") - .shouldContain("Generating 255 bit X25519 key pair and a certificate (SHA256withDSA) issued by with a validity of 90 days") + .shouldContain("Generating X25519 key pair and a certificate (SHA256withDSA) issued by with a validity of 90 days") .shouldContain("for: CN=E1") .shouldContain("The generated certificate #2 of 3 uses a 1024-bit DSA key which is considered a security risk") .shouldContain("The generated certificate #3 of 3 uses a 1024-bit RSA key which is considered a security risk") @@ -285,7 +285,7 @@ static void testSignerJKS() throws Exception { .shouldContain("Alias name: e1") .shouldContain("Certificate chain length: 3") .shouldContain("Signature algorithm name: SHA256withDSA") - .shouldContain("Subject Public Key Algorithm: 255-bit X25519 key") + .shouldContain("Subject Public Key Algorithm: X25519 key") .shouldHaveExitValue(0); } diff --git a/test/jdk/sun/security/tools/keytool/KeyAlg.java b/test/jdk/sun/security/tools/keytool/KeyAlg.java index ed5061949bf64..2fcf2dfb70e1f 100644 --- a/test/jdk/sun/security/tools/keytool/KeyAlg.java +++ b/test/jdk/sun/security/tools/keytool/KeyAlg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,9 +42,9 @@ public static void main(String[] args) throws Exception { .shouldMatch("Signature algorithm name:.*SHA1withECDSA") .shouldMatch("Subject Public Key Algorithm:.*1024.*RSA"); keytool("-genkeypair -alias g -dname CN=g -keyalg EC -keysize 256") - .shouldContain("Generating 256 bit EC (secp256r1) key pair"); + .shouldContain("Generating 256-bit EC (secp256r1) key pair"); keytool("-genkeypair -alias f -dname CN=f -keyalg EC") - .shouldContain("Generating 384 bit EC (secp384r1) key pair"); + .shouldContain("Generating 384-bit EC (secp384r1) key pair"); } static OutputAnalyzer keytool(String s) throws Exception { diff --git a/test/jdk/sun/security/tools/keytool/KeyToolTest.java b/test/jdk/sun/security/tools/keytool/KeyToolTest.java index 954951a1a78d8..793ffd6279350 100644 --- a/test/jdk/sun/security/tools/keytool/KeyToolTest.java +++ b/test/jdk/sun/security/tools/keytool/KeyToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @library /java/security/testlibrary + * @library /test/lib * @bug 6251120 8231950 8242151 * @summary Testing keytool * @@ -68,10 +68,10 @@ import java.util.*; import java.security.cert.X509Certificate; import jdk.test.lib.util.FileUtils; +import jdk.test.lib.security.HumanInputStream; import jdk.test.lib.security.SecurityUtils; import sun.security.util.ObjectIdentifier; - public class KeyToolTest { // The stdout and stderr outputs after a keytool run diff --git a/test/jdk/sun/security/tools/keytool/NssTest.java b/test/jdk/sun/security/tools/keytool/NssTest.java index 1ed2d4c3f391c..6f82da4b4c8a4 100644 --- a/test/jdk/sun/security/tools/keytool/NssTest.java +++ b/test/jdk/sun/security/tools/keytool/NssTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /* * @test * @summary It tests (almost) all keytool behaviors with NSS. - * @library /test/lib /test/jdk/sun/security/pkcs11 /java/security/testlibrary + * @library /test/lib /test/jdk/sun/security/pkcs11 * @modules java.base/sun.security.tools.keytool * java.base/sun.security.util * java.base/sun.security.x509 diff --git a/test/jdk/sun/security/util/HexDumpEncoderTests.java b/test/jdk/sun/security/util/HexDumpEncoderTests.java new file mode 100644 index 0000000000000..9ff08cdb19219 --- /dev/null +++ b/test/jdk/sun/security/util/HexDumpEncoderTests.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.process.ProcessTools; +import sun.security.util.HexDumpEncoder; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/* + * @test + * @bug 8349664 + * @summary HEX dump should always use ASCII or ISO_8859_1 + * @modules java.base/sun.security.util + * @library /test/lib + */ +public class HexDumpEncoderTests { + + + private static String[] getTestCommand(final String encoding) { + return new String[]{ + "--add-modules", "java.base", + "--add-exports", "java.base/sun.security.util=ALL-UNNAMED", + "-Dfile.encoding=" + encoding, + HexDumpEncoderTests.HexDumpEncoderTest.class.getName() + }; + } + + public static void main(String[] args) throws Exception { + + final var testCommandIso = getTestCommand("ISO-8859-1"); + + final var resultIso = ProcessTools.executeTestJava(testCommandIso); + resultIso.shouldHaveExitValue(0); + + // This will take all available StandardCharsets and test them all comparing to the ISO_8859_1 + // Dome im parallel, as this is significantly faster + Arrays.stream(StandardCharsets.class.getDeclaredFields()) + .parallel() + .forEach(field -> { + if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + try { + final var charset = (Charset) field.get(StandardCharsets.ISO_8859_1); // getting the charset to test + + final var testCommand = getTestCommand(charset.name()); + + final var result = ProcessTools.executeTestJava(testCommand); + result.shouldHaveExitValue(0); + + // The outputs of the ISO encoding must be identical to the one tested + Asserts.assertEquals(resultIso.getStdout(), + result.getStdout(), + "Encoding " + charset.name()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + } + + public static class HexDumpEncoderTest { + + /** + * This will test the encode and encode buffer functions at once, + * as they are both representing the string in LATIN_1 + *

    + * The output is put as a system.out + */ + public static void main(String[] args) throws Exception { + + final var encoder = new HexDumpEncoder(); + + System.out.printf("\nCert Encoded With Encode Buffer: %s\n", encoder.encodeBuffer(new byte[100])); + System.out.printf("\nCert Encoded With Encode: %s\n", encoder.encode(new byte[100])); + } + } +} diff --git a/test/jdk/sun/security/util/HostnameChecker/TestHostnameChecker.java b/test/jdk/sun/security/util/HostnameChecker/TestHostnameChecker.java index 162ed46de207e..63eb4057f8e6a 100644 --- a/test/jdk/sun/security/util/HostnameChecker/TestHostnameChecker.java +++ b/test/jdk/sun/security/util/HostnameChecker/TestHostnameChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import jdk.test.lib.security.CertUtils; import sun.security.util.*; import sun.security.x509.X509CertImpl; +import sun.security.x509.X509CertInfo; /** * Certificate 1: @@ -225,7 +226,7 @@ public static void main(String[] args) throws Exception { } private static X509Certificate mock(String domain) { - return new X509CertImpl(null, null, null, new byte[0]) { + return new X509CertImpl(new X509CertInfo(), null, null, new byte[0]) { @Override public Collection> getSubjectAlternativeNames() { return List.of(List.of(2, domain)); diff --git a/test/jdk/sun/security/util/Pem/PemEncoding.java b/test/jdk/sun/security/util/Pem/PemEncoding.java index e840929896024..b8e529b62c95e 100644 --- a/test/jdk/sun/security/util/Pem/PemEncoding.java +++ b/test/jdk/sun/security/util/Pem/PemEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,14 +21,49 @@ * questions. */ +/* + * @test + * @bug 8158633 + * @summary BASE64 encoded cert not correctly parsed with UTF-16 + * @library /test/lib + */ + +import jdk.test.lib.process.ProcessTools; + import java.io.FileInputStream; +import java.nio.charset.Charset; +import java.nio.file.Path; import java.security.cert.CertificateFactory; public class PemEncoding { public static void main(String[] args) throws Exception { - try (FileInputStream fis = new FileInputStream(args[0])) { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - System.out.println(cf.generateCertificate(fis)); + + final var certPath = Path.of(System.getProperty("test.src", ".")) + .getParent() + .resolve("HostnameChecker") + .resolve("cert5.crt") + .toString(); + + final var testCommand = new String[]{"-Dfile.encoding=UTF-16", + PemEncoding.PemEncodingTest.class.getName(), + certPath}; + + final var result = ProcessTools.executeTestJava(testCommand); + result.shouldHaveExitValue(0); + + } + + static class PemEncodingTest { + public static void main(String[] args) throws Exception { + + try (FileInputStream fis = new FileInputStream(args[0])) { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + System.out.println(cf.generateCertificate(fis)); + } + + if (!"UTF-16".equals(Charset.defaultCharset().displayName())) { + throw new RuntimeException("File encoding is not UTF-16"); + } } } } diff --git a/test/jdk/sun/security/validator/CertReplace.java b/test/jdk/sun/security/validator/CertReplace.java index e858cc7657c12..42885b73e96eb 100644 --- a/test/jdk/sun/security/validator/CertReplace.java +++ b/test/jdk/sun/security/validator/CertReplace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,29 +21,186 @@ * questions. */ -/* - * This test is called by certreplace.sh - */ - import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.security.KeyStore; +import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.util.Arrays; import java.util.ArrayList; import java.util.List; + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.security.CertUtils; +import jdk.test.lib.security.KeyStoreUtils; import sun.security.validator.Validator; +/* + * @test id=certreplace + * @bug 6948803 + * @summary CertPath validation regression caused by SHA1 replacement root and MD2 disable feature + * @library /test/lib + * @modules java.base/sun.security.validator + * + * @run main CertReplace certreplace.jks certreplace.certs + */ + +/* + * @test id=samedn + * @bug 6958869 + * @summary Regression: PKIXValidator fails when multiple trust anchors have same dn + * @library /test/lib + * @modules java.base/sun.security.validator + * + * @run main CertReplace samedn.jks samedn1.certs + * @run main CertReplace samedn.jks samedn2.certs + */ + public class CertReplace { + private static final String SAMEDN_JKS = "samedn.jks"; + private static final String CERTREPLACE_JKS = "certreplace.jks"; + private static final String PASSWORD = "changeit"; + private static final char[] PASSWORD_CHAR_ARR = PASSWORD.toCharArray(); + + /** + * This method creates certs for the Cert Replace test + * + * @throws Exception + */ + private static void certReplace() throws Exception { + + final String ktBaseParameters = "-storepass " + PASSWORD + " " + + "-keypass " + PASSWORD + " " + + "-keystore " + CERTREPLACE_JKS + " " + + "-keyalg rsa "; + + final Path keystoreFilePath = Paths.get(CERTREPLACE_JKS); + Files.deleteIfExists(keystoreFilePath); + + // 1. Generate 3 aliases in a keystore: ca, int, user + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias ca -dname CN=CA -keyalg rsa -sigalg md2withrsa -ext bc"); + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias int -dname CN=Int -keyalg rsa"); + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias user -dname CN=User -keyalg rsa"); + + final KeyStore keyStore = KeyStoreUtils.loadKeyStore(CERTREPLACE_JKS, PASSWORD); + + // 2. Signing: ca -> int -> user + + SecurityTools.keytool(ktBaseParameters + + "-certreq -alias int -file int.req"); + SecurityTools.keytool(ktBaseParameters + + "-gencert -rfc -alias ca -ext bc -infile int.req " + + "-outfile int.cert"); + + //putting the certificate in the keystore + try (final FileInputStream certInputStream = new FileInputStream("int.cert")) { + final Certificate[] certs = new Certificate[]{ + CertUtils.getCertFromStream( + certInputStream + ) + }; + + final PrivateKey privateKey = (PrivateKey) keyStore.getKey("int", PASSWORD_CHAR_ARR); + keyStore.setKeyEntry("int", privateKey, PASSWORD_CHAR_ARR, certs); + keyStore.store(new FileOutputStream(CERTREPLACE_JKS), PASSWORD_CHAR_ARR); + } + + SecurityTools.keytool(ktBaseParameters + + "-certreq -alias user -file user.req"); + SecurityTools.keytool(ktBaseParameters + + "-gencert -rfc -alias int " + + "-infile user.req " + + "-outfile certreplace.certs"); // this will create certreplace.certs which is later appended + + // 3. Create the certchain file + final Path certPath = Paths.get("certreplace.certs"); + + Files.write(certPath, Files.readAllBytes(Path.of("int.cert")), StandardOpenOption.APPEND); + + final String outputCa = SecurityTools.keytool(ktBaseParameters + + "-export -rfc -alias ca").getOutput(); + Files.write(certPath, outputCa.getBytes(), StandardOpenOption.APPEND); + + // 4. Upgrade ca from MD2withRSA to SHA256withRSA, remove other aliases and make this keystore the cacerts file + keyStore.deleteEntry("int"); + keyStore.deleteEntry("user"); + keyStore.store(new FileOutputStream(CERTREPLACE_JKS), PASSWORD_CHAR_ARR); + + SecurityTools.keytool(ktBaseParameters + + "-selfcert -alias ca"); + } + + /** + * This method creates certs for the Same DN test + * + * @throws Exception + */ + private static void sameDn() throws Exception { + + final String ktBaseParameters = "-storepass " + PASSWORD + " " + + "-keypass " + PASSWORD + " " + + "-keystore " + SAMEDN_JKS + " " + + "-keyalg rsa "; + + final Path keystoreFilePath = Paths.get(SAMEDN_JKS); + Files.deleteIfExists(keystoreFilePath); + + // 1. Generate 3 aliases in a keystore: ca1, ca2, user. The CAs' startdate + // is set to one year ago so that they are expired now + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias ca1 -dname CN=CA -keyalg rsa " + + "-sigalg md5withrsa -ext bc -startdate -1y"); + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias ca2 -dname CN=CA -keyalg rsa " + + "-sigalg sha1withrsa -ext bc -startdate -1y"); + SecurityTools.keytool(ktBaseParameters + + "-genkeypair -alias user -dname CN=User -keyalg rsa"); + + // 2. Signing: ca -> user. The startdate is set to 1 minute in the past to ensure the certificate + // is valid at the time of validation and to prevent any issues with timing discrepancies + // Automatically saves the certs to the certs files + + SecurityTools.keytool(ktBaseParameters + + "-certreq -alias user -file user.req"); + SecurityTools.keytool(ktBaseParameters + + "-gencert -rfc -alias ca1 " + + "-startdate -1M -infile user.req -outfile samedn1.certs"); + SecurityTools.keytool(ktBaseParameters + + "-gencert -rfc -alias ca2 " + + "-startdate -1M -infile user.req -outfile samedn2.certs"); + + // 3. Remove user for cacerts + final KeyStore keyStore = KeyStoreUtils.loadKeyStore(SAMEDN_JKS, PASSWORD); + keyStore.deleteEntry("user"); + keyStore.store(new FileOutputStream(CERTREPLACE_JKS), PASSWORD_CHAR_ARR); + } + /** * @param args {cacerts keystore, cert chain} */ public static void main(String[] args) throws Exception { + if (args[0].equals(CERTREPLACE_JKS)) { + certReplace(); + } else if (args[0].equals(SAMEDN_JKS)) { + sameDn(); + } else { + throw new RuntimeException("Not recognised test " + args[0]); + } + KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(args[0]), "changeit".toCharArray()); + try (final FileInputStream certInputStream = new FileInputStream(args[0])) { + ks.load(certInputStream, PASSWORD_CHAR_ARR); + } Validator v = Validator.getInstance (Validator.TYPE_PKIX, Validator.VAR_GENERIC, ks); X509Certificate[] chain = createPath(args[1]); @@ -57,9 +214,10 @@ public static void main(String[] args) throws Exception { public static X509Certificate[] createPath(String chain) throws Exception { CertificateFactory cf = CertificateFactory.getInstance("X.509"); List list = new ArrayList(); - for (Certificate c: cf.generateCertificates( - new FileInputStream(chain))) { - list.add((X509Certificate)c); + try (final FileInputStream certInputStream = new FileInputStream(chain)) { + for (Certificate c : cf.generateCertificates(certInputStream)) { + list.add((X509Certificate) c); + } } return (X509Certificate[]) list.toArray(new X509Certificate[0]); } diff --git a/test/jdk/sun/security/validator/certreplace.sh b/test/jdk/sun/security/validator/certreplace.sh deleted file mode 100644 index 79c9732809278..0000000000000 --- a/test/jdk/sun/security/validator/certreplace.sh +++ /dev/null @@ -1,88 +0,0 @@ -# -# Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code 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 -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 6948803 -# @summary CertPath validation regression caused by SHA1 replacement root -# and MD2 disable feature -# @modules java.base/sun.security.validator -# - -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi -if [ "${TESTJAVA}" = "" ] ; then - JAVAC_CMD=`which javac` - TESTJAVA=`dirname $JAVAC_CMD`/.. - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - ;; - * ) - FS="/" - ;; -esac - -KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit \ - -keypass changeit -keystore certreplace.jks -keyalg rsa" -JAVAC=$COMPILEJAVA${FS}bin${FS}javac -JAVA=$TESTJAVA${FS}bin${FS}java - -rm -rf certreplace.jks 2> /dev/null - -# 1. Generate 3 aliases in a keystore: ca, int, user - -$KT -genkeypair -alias ca -dname CN=CA -keyalg rsa -sigalg md2withrsa -ext bc -$KT -genkeypair -alias int -dname CN=Int -keyalg rsa -$KT -genkeypair -alias user -dname CN=User -keyalg rsa - -# 2. Signing: ca -> int -> user - -$KT -certreq -alias int | $KT -gencert -rfc -alias ca -ext bc \ - | $KT -import -alias int -$KT -certreq -alias user | $KT -gencert -rfc -alias int \ - | $KT -import -alias user - -# 3. Create the certchain file - -$KT -export -alias user -rfc > certreplace.certs -$KT -export -rfc -alias int >> certreplace.certs -$KT -export -rfc -alias ca >> certreplace.certs - -# 4. Upgrade ca from MD2withRSA to SHA256withRSA, remove other aliases and -# make this keystore the cacerts file - -$KT -selfcert -alias ca -$KT -delete -alias int -$KT -delete -alias user - -# 5. Build and run test - -EXTRAOPTS="--add-exports java.base/sun.security.validator=ALL-UNNAMED" -$JAVAC ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . ${TESTSRC}${FS}CertReplace.java -$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} ${EXTRAOPTS} CertReplace certreplace.jks certreplace.certs diff --git a/test/jdk/sun/security/validator/samedn.sh b/test/jdk/sun/security/validator/samedn.sh deleted file mode 100644 index 912bbcd40c7ca..0000000000000 --- a/test/jdk/sun/security/validator/samedn.sh +++ /dev/null @@ -1,86 +0,0 @@ -# -# Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code 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 -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 6958869 -# @summary regression: PKIXValidator fails when multiple trust anchors -# have same dn -# @modules java.base/sun.security.validator -# - -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi -if [ "${TESTJAVA}" = "" ] ; then - JAVAC_CMD=`which javac` - TESTJAVA=`dirname $JAVAC_CMD`/.. - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - ;; - * ) - FS="/" - ;; -esac - -KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit \ - -keypass changeit -keystore samedn.jks -keyalg rsa" -JAVAC=$COMPILEJAVA${FS}bin${FS}javac -JAVA=$TESTJAVA${FS}bin${FS}java - -rm -rf samedn.jks 2> /dev/null - -# 1. Generate 3 aliases in a keystore: ca1, ca2, user. The CAs' startdate -# is set to one year ago so that they are expired now - -$KT -genkeypair -alias ca1 -dname CN=CA -keyalg rsa -sigalg md5withrsa -ext bc -startdate -1y -$KT -genkeypair -alias ca2 -dname CN=CA -keyalg rsa -sigalg sha1withrsa -ext bc -startdate -1y -$KT -genkeypair -alias user -dname CN=User -keyalg rsa - -# 2. Signing: ca -> user. The startdate is set to 1 minute in the past to ensure the certificate -# is valid at the time of validation and to prevent any issues with timing discrepancies - -$KT -certreq -alias user | $KT -gencert -rfc -alias ca1 -startdate -1M > samedn1.certs -$KT -certreq -alias user | $KT -gencert -rfc -alias ca2 -startdate -1M > samedn2.certs - -# 3. Append the ca file - -$KT -export -rfc -alias ca1 >> samedn1.certs -$KT -export -rfc -alias ca2 >> samedn2.certs - -# 4. Remove user for cacerts - -$KT -delete -alias user - -# 5. Build and run test. Make sure the CA certs are ignored for validity check. -# Check both, one of them might be dropped out of map in old codes. - -EXTRAOPTS="--add-exports java.base/sun.security.validator=ALL-UNNAMED" -$JAVAC ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . ${TESTSRC}${FS}CertReplace.java -$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} ${EXTRAOPTS} CertReplace samedn.jks samedn1.certs || exit 1 -$JAVA ${TESTVMOPTS} ${TESTJAVAOPTS} ${EXTRAOPTS} CertReplace samedn.jks samedn2.certs || exit 2 diff --git a/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java b/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java index 20beb8db63922..60fe9775c82dd 100644 --- a/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java +++ b/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,9 +49,7 @@ public static void main(String[] args) throws Exception { byte[] ba = deros.toByteArray(); DerValue dv = new DerValue(ba); - GetAVAConstructor a = new GetAVAConstructor(); - java.security.AccessController.doPrivileged(a); - Constructor c = a.getCons(); + Constructor c = getAVAConstructor(); Object[] objs = new Object[2]; objs[0] = oid; @@ -72,16 +70,10 @@ public static void main(String[] args) throws Exception { else throw new Exception("FAILED equals()/hashCode() contract"); } -} - -class GetAVAConstructor implements java.security.PrivilegedExceptionAction { - private Class avaClass = null; - private Constructor avaCons = null; - - public Object run() throws Exception { + static Constructor getAVAConstructor() throws Exception { try { - avaClass = Class.forName("sun.security.x509.AVA"); + Class avaClass = Class.forName("sun.security.x509.AVA"); Constructor[] cons = avaClass.getDeclaredConstructors(); int i; @@ -90,22 +82,16 @@ public Object run() throws Exception { if (parms.length == 2) { if (parms[0].getName().equalsIgnoreCase("sun.security.util.ObjectIdentifier") && parms[1].getName().equalsIgnoreCase("sun.security.util.DerValue")) { - avaCons = cons[i]; + Constructor avaCons = cons[i]; avaCons.setAccessible(true); - break; + return avaCons; } } } - + return null; } catch (Exception e) { System.out.println("Caught unexpected exception " + e); throw e; } - return avaCons; } - - public Constructor getCons(){ - return avaCons; - } - } diff --git a/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java b/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java index a293e5360a9cf..2fa5eb6b8b525 100644 --- a/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java +++ b/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,7 @@ * @bug 8311546 * @summary Adopt de-facto standards on x509 Name Constraints with leading dot. Certs * can be generated by running generate-certs.sh - * @library /test/lib - * @modules java.base/sun.security.x509 + * @run main LeadingPeriod */ import java.io.*; @@ -38,75 +37,33 @@ public class LeadingPeriod { - private static CertPath makeCertPath(String targetCertStr, - PKIXParameters params) throws CertificateException { - // generate certificate from cert strings - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - - ByteArrayInputStream is; - - is = new ByteArrayInputStream(targetCertStr.getBytes()); - Certificate targetCert = cf.generateCertificate(is); - // set validity date so that validation won't fail when cert expires - params.setDate(((X509Certificate)targetCert).getNotBefore()); - - // generate certification path - List list = List.of(targetCert); - - return cf.generateCertPath(list); + public static void main(String[] args) throws Exception { + String certs = System.getProperty("test.src", "./") + "/certs/"; + validate(certs + "withoutLeadingPeriod"); + validate(certs + "withLeadingPeriod"); } - private static PKIXParameters genParams(String caStr) throws Exception { - // generate certificate from cert string - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - - ByteArrayInputStream is = new ByteArrayInputStream(caStr.getBytes()); - Certificate selfSignedCert = cf.generateCertificate(is); + public static void validate(String certPath) throws Exception { + byte[] targetCertBytes = Files.readAllBytes(Paths.get(certPath + "/leaf.pem")); + byte[] caCertBytes = Files.readAllBytes(Paths.get(certPath + "/ca.pem")); - // generate a trust anchor - TrustAnchor anchor = new TrustAnchor((X509Certificate) selfSignedCert, null); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate caCert = cf.generateCertificate(new ByteArrayInputStream(caCertBytes)); + Certificate targetCert = cf.generateCertificate(new ByteArrayInputStream(targetCertBytes)); - Set anchors = Collections.singleton(anchor); + TrustAnchor anchor = new TrustAnchor((X509Certificate) caCert, null); - PKIXParameters params = new PKIXParameters(anchors); + PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); - // disable certificate revocation checking + // Disable certificate revocation checking params.setRevocationEnabled(false); - return params; - } + // Set validity date, so that validation won't fail when cert expires + params.setDate(((X509Certificate)targetCert).getNotBefore()); - public static void main(String[] args) throws Exception { + CertPath path = cf.generateCertPath(List.of(targetCert, caCert)); CertPathValidator validator = CertPathValidator.getInstance("PKIX"); - - // Load certs with a NameConstraint where DNS value does not begin with a period - Path targetFromCAWithoutPeriodPath = Paths.get(System.getProperty( - "test.src", "./") + "/certs/withoutLeadingPeriod/leaf.pem"); - String targetFromCAWithoutPeriod = Files.readString(targetFromCAWithoutPeriodPath); - - Path caWithoutLeadingPeriodPath = Paths.get(System.getProperty( - "test.src", "./") + "/certs/withoutLeadingPeriod/ca.pem"); - String caWithoutLeadingPeriod = Files.readString(caWithoutLeadingPeriodPath); - - PKIXParameters paramsForCAWithoutLeadingPeriod = genParams(caWithoutLeadingPeriod); - CertPath pathWithoutLeadingPeriod = makeCertPath( - targetFromCAWithoutPeriod, paramsForCAWithoutLeadingPeriod); - - validator.validate(pathWithoutLeadingPeriod, paramsForCAWithoutLeadingPeriod); - - // Load certificates with a NameConstraint where the DNS value does begin with a period - Path targetFromCAWithPeriodPath = Paths.get(System.getProperty( - "test.src", "./") + "/certs/withLeadingPeriod/leaf.pem"); - String targetFromCAWithPeriod = Files.readString(targetFromCAWithPeriodPath); - - Path caWithLeadingPeriodPath = Paths.get(System.getProperty( - "test.src", "./") + "/certs/withLeadingPeriod/ca.pem"); - String caWithLeadingPeriod = Files.readString(caWithLeadingPeriodPath); - - PKIXParameters paramsForCAWithLeadingPeriod = genParams(caWithLeadingPeriod); - CertPath pathWithLeadingPeriod = makeCertPath(targetFromCAWithPeriod, paramsForCAWithLeadingPeriod); - - validator.validate(pathWithLeadingPeriod, paramsForCAWithLeadingPeriod); + validator.validate(path, params); } } diff --git a/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java b/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java index 487f5e2471ce4..cabb225bf1cc6 100644 --- a/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java +++ b/test/jdk/sun/security/x509/URICertStore/AIACertTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,7 @@ * @summary Enhance OCSP, CRL and Certificate Fetch Timeouts * @modules java.base/sun.security.x509 * java.base/sun.security.util - * @library /test/lib ../../../../java/security/testlibrary - * @build CertificateBuilder + * @library /test/lib * @run main/othervm -Dcom.sun.security.enableAIAcaIssuers=true * -Dcom.sun.security.cert.readtimeout=1 AIACertTimeout 5000 false * @run main/othervm -Dcom.sun.security.enableAIAcaIssuers=true @@ -55,10 +54,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import sun.security.testlibrary.CertificateBuilder; - -import sun.security.x509.*; -import sun.security.util.*; +import jdk.test.lib.security.CertificateBuilder; public class AIACertTimeout { diff --git a/test/jdk/sun/security/x509/X509CertImpl/CertExtensions.java b/test/jdk/sun/security/x509/X509CertImpl/CertExtensions.java new file mode 100644 index 0000000000000..f8ee13e8f511b --- /dev/null +++ b/test/jdk/sun/security/x509/X509CertImpl/CertExtensions.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8346094 + * @summary validating getExtensionValue and getKeyUsage with specified and + * unspecified extensions on the X509Certificate. + * @library /test/lib + * @modules java.base/sun.security.x509 + * java.base/sun.security.util + */ + +import jdk.test.lib.Asserts; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.*; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.*; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + + +public class CertExtensions { + + public static void main(String[] args) throws Exception { + X509CertImpl x509Certimpl = createCertificate(); + /** + * Certificate is created without extensions. Invoking getExtensionValue + * with oid must return NULL else it is incorrect + */ + Asserts.assertNull(x509Certimpl.getExtensionValue("2.5.29.17")); + /** + * Certificate is created with extensions. Invoking getExtensionValue + * with oid must not return NULL else it is incorrect + */ + x509Certimpl.getInfo().setExtensions(createCertificateExtensions( + x509Certimpl.getInfo().getKey().getKey())); + Asserts.assertNotNull(x509Certimpl.getExtensionValue("2.5.29.17")); + /** + * Certificate is created with extensions. Invoking getExtensionValue + * with invalid oid must return NULL else it is incorrect + */ + Asserts.assertNull(x509Certimpl.getExtensionValue("1.2.3.4")); + /** + * Certificate is created with extensions. Invoking getKeyUsage + * must not return NULL else it is incorrect + */ + Asserts.assertNotNull(x509Certimpl.getKeyUsage()); + /** + * Certificate is created without extensions. Invoking getKeyUsage + * must return NULL else it is incorrect + */ + x509Certimpl.getInfo().setExtensions(null); + Asserts.assertNull(x509Certimpl.getKeyUsage()); + } + + private static X509CertImpl createCertificate() throws Exception { + X509CertImpl x509Certimpl = null; + try { + X509CertInfo x509CertInfo = new X509CertInfo(); + x509CertInfo.setVersion(new CertificateVersion(CertificateVersion.V3)); + + // Generate Key Pair (RSA) + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + PrivateKey privateKey = keyPair.getPrivate(); + PublicKey publicKey = keyPair.getPublic(); + x509CertInfo.setKey(new CertificateX509Key(publicKey)); + + // Create and set the DN name for Subject and Issuer. + X500Name subject = new X500Name("CN=www.Subject.com, O=MyOrg, OU=LocalBiz, L=XYZ, S=YY, C=XX"); + X500Name issuer = new X500Name("CN=www.Issuer.com, O=Oracle,OU=Java,L=XYZ,S=YY, C=XX"); + x509CertInfo.setIssuer(issuer); + x509CertInfo.setSubject(subject); + + // create and set the subject and issuer unique identity + byte[] issuerId = {1, 2, 3, 4, 5}; + byte[] subjectId = {6, 7, 8, 9, 10}; + x509CertInfo.setSubjectUniqueId(new UniqueIdentity(subjectId)); + x509CertInfo.setIssuerUniqueId(new UniqueIdentity(issuerId)); + + // create and set the serial number + BigInteger serialNumber = BigInteger.valueOf(new SecureRandom().nextInt(Integer.MAX_VALUE)); + x509CertInfo.setSerialNumber(new CertificateSerialNumber(serialNumber)); + + // create and set the validity interval + Date notBefore = new Date(); // Valid from now + Date notAfter = new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); // Valid for 1 year + x509CertInfo.setValidity(new CertificateValidity(notBefore, notAfter)); + + // Create Certificate Info which is the representation of X509 Certificate. + x509CertInfo.setAlgorithmId(new CertificateAlgorithmId(AlgorithmId.get("SHA256withRSA"))); + + // Sign the certificate + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initSign(privateKey); + signature.update(x509CertInfo.getEncodedInfo()); + byte[] signedData = signature.sign(); + byte[] signedCert = {}; + + x509Certimpl = new X509CertImpl(x509CertInfo, + AlgorithmId.get("SHA256withRSA"), signedData, signedCert); + } catch (Exception e) { + System.out.println("caught exception while creating the certificate : " + e.getMessage()); + throw e; + } + return x509Certimpl; + } + + public static sun.security.x509.CertificateExtensions createCertificateExtensions + (PublicKey publicKey) throws IOException, NoSuchAlgorithmException { + // Create Extensions + sun.security.x509.CertificateExtensions certificateExtensions = + new sun.security.x509.CertificateExtensions(); + + GeneralNameInterface mailInf = new RFC822Name("test@Oracle.com"); + GeneralName mail = new GeneralName(mailInf); + GeneralNameInterface dnsInf = new DNSName("Oracle.com"); + GeneralName dns = new GeneralName(dnsInf); + GeneralNameInterface uriInf = new URIName("http://www.Oracle.com"); + GeneralName uri = new GeneralName(uriInf); + + // localhost + byte[] address = new byte[]{127, 0, 0, 1}; + + GeneralNameInterface ipInf = new IPAddressName(address); + GeneralName ip = new GeneralName(ipInf); + + GeneralNameInterface oidInf = new OIDName(ObjectIdentifier.of("1.2.3.4")); + GeneralName oid = new GeneralName(oidInf); + + + GeneralNames subjectNames = new GeneralNames(); + subjectNames.add(mail); + subjectNames.add(dns); + subjectNames.add(uri); + SubjectAlternativeNameExtension subjectName = new SubjectAlternativeNameExtension(subjectNames); + + GeneralNames issuerNames = new GeneralNames(); + issuerNames.add(ip); + issuerNames.add(oid); + IssuerAlternativeNameExtension issuerName = new IssuerAlternativeNameExtension(issuerNames); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")); + cal.set(2014, 03, 10, 12, 30, 30); + cal.set(2000, 11, 15, 12, 30, 30); + Date lastDate = cal.getTime(); + Date firstDate = new Date(); + PrivateKeyUsageExtension pkusage = new PrivateKeyUsageExtension(firstDate, lastDate); + + KeyUsageExtension usage = new KeyUsageExtension(); + usage.set(KeyUsageExtension.CRL_SIGN, true); + usage.set(KeyUsageExtension.DIGITAL_SIGNATURE, true); + usage.set(KeyUsageExtension.NON_REPUDIATION, true); + MessageDigest md = MessageDigest.getInstance("SHA"); + + byte[] keyId = md.digest(publicKey.getEncoded()); + KeyIdentifier kid = new KeyIdentifier(keyId); + SerialNumber sn = new SerialNumber(42); + AuthorityKeyIdentifierExtension aki = new AuthorityKeyIdentifierExtension(kid, subjectNames, sn); + + SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension(keyId); + + BasicConstraintsExtension cons = new BasicConstraintsExtension(true, 10); + + PolicyConstraintsExtension pce = new PolicyConstraintsExtension(2, 4); + + certificateExtensions.setExtension(SubjectAlternativeNameExtension.NAME, subjectName); + certificateExtensions.setExtension(IssuerAlternativeNameExtension.NAME, issuerName); + certificateExtensions.setExtension(PrivateKeyUsageExtension.NAME, pkusage); + certificateExtensions.setExtension(KeyUsageExtension.NAME, usage); + certificateExtensions.setExtension(AuthorityKeyIdentifierExtension.NAME, aki); + certificateExtensions.setExtension(SubjectKeyIdentifierExtension.NAME, ski); + certificateExtensions.setExtension(BasicConstraintsExtension.NAME, cons); + certificateExtensions.setExtension(PolicyConstraintsExtension.NAME, pce); + return certificateExtensions; + } +} diff --git a/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java b/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java index 2d3dbfd659c91..29c651164d3fc 100644 --- a/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java +++ b/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8049237 8242151 + * @bug 8049237 8242151 8347841 * @modules java.base/sun.security.x509 * java.base/sun.security.util * jdk.crypto.ec @@ -114,7 +114,7 @@ public static boolean test(String algorithm, String sigAlg, int keyLength) // Validity interval Date firstDate = new Date(); - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("PST")); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")); cal.set(2014, 03, 10, 12, 30, 30); Date lastDate = cal.getTime(); CertificateValidity interval = new CertificateValidity(firstDate, diff --git a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java index 7ca36d40a6f90..9e9a6c79c7b60 100644 --- a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java +++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,8 @@ public class JShellHeapDumpTest { static Process jShellProcess; static boolean doSleep = true; // By default do a short sleep when app starts up - public static void launch(String expectedMessage, List toolArgs) + // Returns false if the attempt should be retried. + public static boolean launch(String expectedMessage, List toolArgs, boolean allowRetry) throws IOException { try { @@ -81,6 +82,10 @@ public static void launch(String expectedMessage, List toolArgs) System.out.println("###### End of all output which took " + elapsedTime + "ms"); output.shouldHaveExitValue(0); } catch (Exception ex) { + if (allowRetry) { + System.out.println("Exception " + ex + " in 'launch' occured. Allow one retry."); + return false; + } throw new RuntimeException("Test ERROR " + ex, ex); } finally { if (jShellProcess.isAlive()) { @@ -91,12 +96,18 @@ public static void launch(String expectedMessage, List toolArgs) System.out.println("Jshell not alive"); } } + return true; } public static void launch(String expectedMessage, String... toolArgs) throws IOException { - launch(expectedMessage, Arrays.asList(toolArgs)); + boolean res = launch(expectedMessage, Arrays.asList(toolArgs), true); + // Allow a retry for !doSleep, because the sleep allows the debuggee to stabilize, + // making it very unlikely that jmap will fail. + if (!res && !doSleep) { + launch(expectedMessage, Arrays.asList(toolArgs), false); + } } /* Returns false if the attempt should be retried. */ diff --git a/test/jdk/sun/util/calendar/zi/BackEnd.java b/test/jdk/sun/util/calendar/zi/BackEnd.java deleted file mode 100644 index 10d71ff721043..0000000000000 --- a/test/jdk/sun/util/calendar/zi/BackEnd.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * BackEnd is an abstract base class for a back-end of compiling - * Olson's zoneinfo database and generating Java zoneinfo database. - * - * @since 1.4 - */ -abstract class BackEnd { - - /** - * Receives each zone's TimeZone information which was created by - * {@link Zoneinfo#parse} in class Zoneinfo, - * and processes it. - * - * @param tz Timezone object for each zone - * @return 0 if no error occurred, otherwise 1. - */ - abstract int processZoneinfo(Timezone tz); - - /** - * Receives whole information which is generated by JavaZic's front-end - * in the form of Mapping object and generates all Java zone information - * files. - * - * @param m Mappings object which is generated by - * {@link Main#compile() Main.compile()}. - * @return 0 if no error occurred, otherwise 1. - */ - abstract int generateSrc(Mappings m); - - /** - * Decides which backend class should be used and returns its instance. - * @return an instance of backend class - */ - static BackEnd getBackEnd() { - if (Zoneinfo.isYearForTimeZoneDataSpecified) { - return new Simple(); - } else if (Main.outputDoc) { - return new GenDoc(); - } else { - return new Gen(); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Beyond2037.java b/test/jdk/sun/util/calendar/zi/Beyond2037.java deleted file mode 100644 index af6f16067a854..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Beyond2037.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8073446 8262110 - * @summary Tests DST related beyond the year 2037 - * @run testng Beyond2037 - */ - -import java.text.SimpleDateFormat; -import java.util.TimeZone; - -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; - -@Test -public class Beyond2037 { - - @DataProvider - Object[][] dstTransition() { - return new Object[][] { - {"2037/03/08 01:59:59:999", "2037/03/08 01:59:59:999"}, - {"2037/03/08 02:00:00:000", "2037/03/08 03:00:00:000"}, - {"2038/03/14 01:59:59:999", "2038/03/14 01:59:59:999"}, - {"2038/03/14 02:00:00:000", "2038/03/14 03:00:00:000"}, - {"2099/03/08 01:59:59:999", "2099/03/08 01:59:59:999"}, - {"2099/03/08 02:00:00:000", "2099/03/08 03:00:00:000"}, - {"2100/03/14 01:59:59:999", "2100/03/14 01:59:59:999"}, - {"2100/03/14 02:00:00:000", "2100/03/14 03:00:00:000"}, - {"8000/03/12 01:59:59:999", "8000/03/12 01:59:59:999"}, - {"8000/03/12 02:00:00:000", "8000/03/12 03:00:00:000"}, - }; - } - - @Test(dataProvider="dstTransition") - public void testDstTransition(String source, String expected) throws Exception { - var timeZone = TimeZone.getTimeZone("America/New_York"); - var sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS" ); - sdf.setTimeZone(timeZone); - assertEquals(sdf.format(sdf.parse(source)), expected); - } - - @Test - public void testGetOffset() throws Exception { - var timeZone = TimeZone.getTimeZone("PST8PDT"); - var df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - df.setTimeZone(timeZone); - var tMilli = df.parse("7681-03-09 03:20:49").getTime(); - assertEquals(timeZone.getOffset(tMilli), -25200000); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Checksum.java b/test/jdk/sun/util/calendar/zi/Checksum.java deleted file mode 100644 index 93a1c8279038e..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Checksum.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.zip.CRC32; - -/** - * Checksum provides methods for calculating a CRC32 value for a - * transitions table. - * - * @since 1.4 - */ -public class Checksum extends CRC32 -{ - /** - * Updates the CRC32 value from each byte of the given int - * value. The bytes are used in the big endian order. - * @param val the int value - */ - public void update(int val) { - byte[] b = new byte[4]; - b[0] = (byte)((val >>> 24) & 0xff); - b[1] = (byte)((val >>> 16) & 0xff); - b[2] = (byte)((val >>> 8) & 0xff); - b[3] = (byte)(val & 0xff); - update(b); - } - - /** - * Updates the CRC32 value from each byte of the given long - * value. The bytes are used in the big endian order. - * @param val the long value - */ - void update(long val) { - byte[] b = new byte[8]; - b[0] = (byte)((val >>> 56) & 0xff); - b[1] = (byte)((val >>> 48) & 0xff); - b[2] = (byte)((val >>> 40) & 0xff); - b[3] = (byte)((val >>> 32) & 0xff); - b[4] = (byte)((val >>> 24) & 0xff); - b[5] = (byte)((val >>> 16) & 0xff); - b[6] = (byte)((val >>> 8) & 0xff); - b[7] = (byte)(val & 0xff); - update(b); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Gen.java b/test/jdk/sun/util/calendar/zi/Gen.java deleted file mode 100644 index 4cdabc55321e7..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Gen.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.IOException; -import java.io.File; -import java.io.FileOutputStream; -import java.io.DataOutputStream; -import java.io.RandomAccessFile; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Gen is one of back-end classes of javazic, and generates - * ZoneInfoMappings and zone-specific file for each zone. - */ -class Gen extends BackEnd { - - /** - * Generates datafile in binary TLV format for each time zone. - * Regarding contents of output files, see {@link ZoneInfoFile}. - * - * @param Timezone - * @return 0 if no errors, or 1 if error occurred. - */ - int processZoneinfo(Timezone tz) { - try { - int size; - String outputDir = Main.getOutputDir(); - String zonefile = ZoneInfoFile.getFileName(tz.getName()); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - - /* If zonefile includes file-separator, it's treated as part of - * pathname. And make directory if necessary. - */ - int index = zonefile.lastIndexOf(File.separatorChar); - if (index != -1) { - outputDir += zonefile.substring(0, index+1); - } - File outD = new File(outputDir); - outD.mkdirs(); - - FileOutputStream fos = - new FileOutputStream(outputDir + zonefile.substring(index+1)); - DataOutputStream dos = new DataOutputStream(fos); - - /* Output Label */ - dos.write(ZoneInfoFile.JAVAZI_LABEL, 0, - ZoneInfoFile.JAVAZI_LABEL.length); - - /* Output Version of ZoneInfoFile */ - dos.writeByte(ZoneInfoFile.JAVAZI_VERSION); - - List transitions = tz.getTransitions(); - if (transitions != null) { - List dstOffsets = tz.getDstOffsets(); - List offsets = tz.getOffsets(); - - if ((dstOffsets == null && offsets != null) || - (dstOffsets != null && offsets == null)) { - Main.panic("Data not exist. (dstOffsets or offsets)"); - return 1; - } - - /* Output Transition records */ - dos.writeByte(ZoneInfoFile.TAG_Transition); - size = transitions.size(); - dos.writeShort((size * 8) & 0xFFFF); - int dstoffset; - for (int i = 0; i < size; i++) { - /* if DST offset is 0, this means DST isn't used. - * (NOT: offset's index is 0.) - */ - if ((dstoffset = dstOffsets.get(i).intValue()) == -1) { - dstoffset = 0; - } - - dos.writeLong((transitions.get(i).longValue() << 12) - | (dstoffset << 4) - | offsets.get(i).intValue()); - - } - - /* Output data for GMTOffset */ - List gmtoffset = tz.getGmtOffsets(); - dos.writeByte(ZoneInfoFile.TAG_Offset); - size = gmtoffset.size(); - dos.writeShort((size * 4) & 0xFFFF); - for (int i = 0; i < size; i++) { - dos.writeInt(gmtoffset.get(i)); - } - } - - /* Output data for SimpleTimeZone */ - List stz = tz.getLastRules(); - if (stz != null) { - RuleRec[] rr = new RuleRec[2]; - boolean wall = true; - - rr[0] = stz.get(0); - rr[1] = stz.get(1); - - dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone); - wall = rr[0].getTime().isWall() && rr[1].getTime().isWall(); - if (wall) { - dos.writeShort(32); - } else { - dos.writeShort(40); - } - - for (int i = 0; i < 2; i++) { - dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number - dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone()); - dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt()); - dos.writeInt((int)rr[i].getTime().getTime()); - if (!wall) { - dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1); - } - } - } - - /* Output RawOffset */ - dos.writeByte(ZoneInfoFile.TAG_RawOffset); - dos.writeShort(4); - dos.writeInt(tz.getRawOffset()); - - /* Output willGMTOffsetChange flag */ - if (tz.willGMTOffsetChange()) { - dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange); - dos.writeShort(1); - dos.writeByte(1); - } - - /* Output LastDSTSaving */ - dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving); - dos.writeShort(2); - dos.writeShort(tz.getLastDSTSaving()/1000); - - /* Output checksum */ - dos.writeByte(ZoneInfoFile.TAG_CRC32); - dos.writeShort(4); - dos.writeInt(tz.getCRC32()); - - fos.close(); - dos.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - /** - * Generates ZoneInfoMappings in binary TLV format for each zone. - * Regarding contents of output files, see {@link ZoneInfoFile}. - * - * @param Mappings - * @return 0 if no errors, or 1 if error occurred. - */ - int generateSrc(Mappings map) { - try { - int index; - int block_size; - int roi_size; - long fp; - String outputDir = Main.getOutputDir(); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - - File outD = new File(outputDir); - outD.mkdirs(); - - /* Open ZoneInfoMapping file to write. */ - RandomAccessFile raf = - new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw"); - - /* Whether rawOffsetIndex list exists or not. */ - List roi = map.getRawOffsetsIndex(); - if (roi == null) { - Main.panic("Data not exist. (rawOffsetsIndex)"); - return 1; - } - roi_size = roi.size(); - - /* Whether rawOffsetIndexTable list exists or not. */ - List> roit = map.getRawOffsetsIndexTable(); - if (roit == null || roit.size() != roi_size) { - Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size"); - return 1; - } - - /* Output Label */ - raf.write(ZoneInfoFile.JAVAZM_LABEL, 0, - ZoneInfoFile.JAVAZM_LABEL.length); - - /* Output Version */ - raf.writeByte(ZoneInfoFile.JAVAZM_VERSION); - - index = ZoneInfoFile.JAVAZM_LABEL.length + 2; - - /* Output Version of Olson's tzdata */ - byte[] b = Main.getVersionName().getBytes("UTF-8"); - raf.writeByte(ZoneInfoFile.TAG_TZDataVersion); - raf.writeShort((b.length+1) & 0xFFFF); - raf.write(b); - raf.writeByte(0x00); - index += b.length + 4; - - /* Output ID list. */ - raf.writeByte(ZoneInfoFile.TAG_ZoneIDs); - block_size = 2; - raf.writeShort(block_size & 0xFFFF); - short nID = 0; - raf.writeShort(nID & 0xFFFF); - for (int i = 0; i < roi_size; i++) { - for (String key : roit.get(i)) { - byte size = (byte)key.getBytes("UTF-8").length; - raf.writeByte(size & 0xFF); - raf.write(key.getBytes("UTF-8"), 0, size); - block_size += 1 + size; - nID++; - } - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.writeShort(nID & 0xFFFF); - raf.seek(fp); - - /* Output sorted rawOffset list. */ - raf.writeByte(ZoneInfoFile.TAG_RawOffsets); - index += 3 + block_size; - block_size = roi_size * 4; - raf.writeShort(block_size & 0xFFFF); - for (int i = 0; i < roi_size; i++) { - raf.writeInt(Integer.parseInt(roi.get(i).toString())); - } - - /* Output sorted rawOffsetIndex list. */ - raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices); - index += 3 + block_size; - block_size = 0; - raf.writeShort(block_size & 0xFFFF); - int num; - for (int i = 0; i < roi_size; i++) { - num = roit.get(i).size(); - block_size += num; - for (int j = 0; j < num; j++) { - raf.writeByte(i); - } - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.seek(fp); - - /* Whether alias list exists or not. */ - Map a = map.getAliases(); - if (a == null) { - Main.panic("Data not exist. (aliases)"); - return 0; - } - - /* Output ID list. */ - raf.writeByte(ZoneInfoFile.TAG_ZoneAliases); - index += 3 + block_size; - block_size = 2; - raf.writeShort(block_size & 0xFFFF); - raf.writeShort(a.size() & 0xFFFF); - for (String key : a.keySet()) { - String alias = a.get(key); - byte key_size = (byte)key.length(); - byte alias_size = (byte)alias.length(); - raf.writeByte(key_size & 0xFF); - raf.write(key.getBytes("UTF-8"), 0, key_size); - raf.writeByte(alias_size & 0xFF); - raf.write(alias.getBytes("UTF-8"), 0, alias_size); - block_size += 2 + key_size + alias_size; - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort((block_size) & 0xFFFF); - raf.seek(fp); - - /* Output the exclude list if it exists. */ - List excludedZones = map.getExcludeList(); - if (excludedZones != null) { - raf.writeByte(ZoneInfoFile.TAG_ExcludedZones); - index += 3 + block_size; - block_size = 2; - raf.writeShort(block_size & 0xFFFF); // place holder - raf.writeShort(excludedZones.size()); // the number of excluded zones - for (String name : excludedZones) { - byte size = (byte) name.length(); - raf.writeByte(size); // byte length - raf.write(name.getBytes("UTF-8"), 0, size); // zone name - block_size += 1 + size; - } - fp = raf.getFilePointer(); - raf.seek(index); - raf.writeShort(block_size & 0xFFFF); - raf.seek(fp); - } - - /* Close ZoneInfoMapping file. */ - raf.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } -} diff --git a/test/jdk/sun/util/calendar/zi/GenDoc.java b/test/jdk/sun/util/calendar/zi/GenDoc.java deleted file mode 100644 index e9e6ebc0cd8fa..0000000000000 --- a/test/jdk/sun/util/calendar/zi/GenDoc.java +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.StringTokenizer; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * GenDoc is one of back-end classes of javazic, and generates - * index.html and other html files which prints the detailed time zone - * information for each zone. - */ -class GenDoc extends BackEnd { - - private static final String docDir = "doc"; - - private static final String header1 = - "\n" + - "\n\n\n\n" + - "Java Platform, Standard Edition - TimeZone information based on "; - private static final String header3 = - "-->\n<TITLE>\n" + - "Java Platform, Standard Edition TimeZone - "; - private static final String header4 = - "\n" + - "\n\n"; - - private static final String body1 = - "\n"; - private static final String body2 = - "\n"; - - private static final String footer = - "\n"; - - - // list of time zone name and zonefile name/real time zone name - // e.g. - // key (String) : value (String) - // "America/Denver" : "America/Denver.html" (real time zone) - // "America/Shiprock" : "America/Denver" (alias) - TreeMap timezoneList = new TreeMap(); - - // list of time zone's display name and time zone name - // e.g. - // key (String) : value (String) - // "Tokyo, Asia" : "Asia/Tokyo" - // "Marengo, Indiana, America" : "America/Indiana/Marengo" - // (aliases included) - TreeMap displayNameList = new TreeMap(); - - // list of top level regions - // e.g. - // key (String) : value (String) - // "America" : "America.html" - // (including entries in America/Indiana/, America/Kentucky/, ...) - TreeMap regionList = new TreeMap(); - - // mapping list from zone name to latitude & longitude - // This list is generated from zone.tab. - // e.g. - // key (String) : value (LatitudeAndLongitude object) - // "Asia/Tokyo" : latitude=35.3916, longitude=13.9444 - // (aliases not included) - HashMap mapList = null; - - // SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT - // offset will change in the future, its last known offset is - // used. - SortedMap> zonesByOffset = new TreeMap>(); - - /** - * Generates HTML document for each zone. - * @param Timezone - * @return 0 if no errors, or 1 if error occurred. - */ - int processZoneinfo(Timezone tz) { - try { - int size; - int index; - String outputDir = Main.getOutputDir(); - String zonename = tz.getName(); - String zonefile = ZoneInfoFile.getFileName(zonename) + ".html"; - List stz = tz.getLastRules(); - timezoneList.put(zonename, zonefile); - displayNameList.put(transform(zonename), zonename); - - // Populate zonesByOffset. (Zones that will change their - // GMT offsets are also added to zonesByOffset here.) - int lastKnownOffset = tz.getRawOffset(); - Set set = zonesByOffset.get(lastKnownOffset); - if (set == null) { - set = new TreeSet(); - zonesByOffset.put(lastKnownOffset, set); - } - set.add(zonename); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - outputDir += docDir + File.separatorChar; - - index = zonename.indexOf('/'); - if (index != -1) { - regionList.put(zonename.substring(0, index), - zonename.substring(0, index) + ".html"); - } - - /* If zonefile includes file-separator, it's treated as part of - * pathname. And make directory if necessary. - */ - index = zonefile.lastIndexOf('/'); - if (index != -1) { - zonefile.replace('/', File.separatorChar); - outputDir += zonefile.substring(0, index+1); - } - File outD = new File(outputDir); - outD.mkdirs(); - - /* If mapfile is available, add a link to the appropriate map */ - if (mapList == null && Main.getMapFile() != null) { - mapList = new HashMap(); - FileReader fr = new FileReader(Main.getMapFile()); - BufferedReader in = new BufferedReader(fr); - String line; - while ((line = in.readLine()) != null) { - // skip blank and comment lines - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - StringTokenizer tokens = new StringTokenizer(line); - String token = tokens.nextToken(); /* We don't use the first token. */ - token = tokens.nextToken(); - LatitudeAndLongitude location = new LatitudeAndLongitude(token); - token = tokens.nextToken(); - mapList.put(token, location); - } - in.close(); - } - - /* Open zoneinfo file to write. */ - FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1)); - BufferedWriter out = new BufferedWriter(fw); - - out.write(header1 + new Date() + header3 + zonename + header4); - out.write(body1 + "" + zonename + ""); - LatitudeAndLongitude location = (mapList != null ? mapList.get(zonename) : null); - if (location != null) { - int deg, min, sec; - - deg = location.getLatDeg(); - min = location.getLatMin(); - sec = location.getLatSec(); - if (deg < 0) { - min = -min; - sec = -sec; - } else if (min < 0) { - sec = -sec; - } - out.write("   " + - "[map]"); - } - out.write("\n

    \n"); - - List zone = tz.getZones(); - List rule = tz.getRules(); - if (rule != null && zone != null) { - out.write("\n" + - "\n" + - "\n" + - "\n" + - "\n

    " + - "Rules
    " + - "
    Zone
    \n"); - } - - /* Output Rule records. */ - if (rule != null) { - size = rule.size(); - out.write("

    \n" + - "Rules\n" + - "\n" + - "\n" + - "" + - "" + - "\n\n"); - for (int i = 0; i < size; i++) { - out.write("\n"); - StringTokenizer st = new StringTokenizer(rule.get(i).getLine()); - String s; - if (st.hasMoreTokens()) { /* RULE - truncated */ - st.nextToken(); - } - if (st.hasMoreTokens()) { /* NAME */ - out.write(""); - } - if (st.hasMoreTokens()) { /* FROM */ - out.write(""); - } - if (st.hasMoreTokens()) { /* TO */ - s = st.nextToken(); - if (s.equals("min") || s.equals("max")) { - out.write(""); - } else { - out.write(""); - } - } - if (st.hasMoreTokens()) { /* TYPE */ - out.write(""); - } - if (st.hasMoreTokens()) { /* IN */ - out.write(""); - } - if (st.hasMoreTokens()) { /* ON */ - out.write(""); - } - if (st.hasMoreTokens()) { /* AT */ - out.write(""); - } - if (st.hasMoreTokens()) { /* SAVE */ - out.write(""); - } - if (st.hasMoreTokens()) { /* LETTER/S */ - out.write(""); - } - if (st.hasMoreTokens()) { /* NOTES */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - out.write("\n"); - } else { - out.write("\n"); - } - out.write("\n"); - } - out.write("
    NAMEFROMTOTYPEINONATSAVELETTER/SNOTES
    " + st.nextToken() + "" + st.nextToken() + "" + s + "" + s + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + st.nextToken() + "" + s.substring(index+1) + " 
    \n

     

    \n"); - } - - /* Output Zone records. */ - if (zone != null) { - size = zone.size(); - out.write("

    \n" + - "Zone\n" + - "\n" + - "\n" + - "" + - "\n\n"); - for (int i = 0; i < size; i++) { - out.write("\n"); - StringTokenizer st = new StringTokenizer(zone.get(i).getLine()); - String s = st.nextToken(); - if (s.equals("Zone")) { /* NAME */ - s = st.nextToken(); - s = st.nextToken(); - } - out.write(""); /* GMTOFFSET */ - if (st.hasMoreTokens()) { /* RULES */ - out.write(""); - } - if (st.hasMoreTokens()) { /* FORMAT */ - s = st.nextToken(); - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write(""); /* FORMAT */ - s = s.substring(index+1); - } else { - out.write(""); /* FORMAT */ - } - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - out.write(""); /* UNTIL */ - out.write("\n\n"); /* NOTES */ - continue; - } else { - out.write(""); /* FORMAT */ - } - } - - if (st.hasMoreTokens()) { /* UNTIL */ - s = st.nextToken(); - while (st.hasMoreTokens()) { - s += " " + st.nextToken(); - } - index = s.indexOf('#'); - if (index != -1) { - if (index != 0) { - out.write(""); /* UNTIL */ - } else { - out.write(""); /* UNTIL */ - } - out.write("\n"); /* NOTES */ - } else { - out.write(""); /* UNTIL */ - out.write("\n"); /* NOTES */ - } - } else { - out.write(""); /* UNTIL */ - out.write("\n"); /* NOTES */ - } - out.write("\n"); - } - out.write("
    GMTOFFRULESFORMATUNTILNOTES
    " + s + "" + st.nextToken() + "" + s.substring(0, index-1) + - "  " + s + "
    " + s + "" + s.substring(0, index-1) + - " " + s.substring(index+1) + - "" + s + "   
    \n"); - } - out.write(body2 + footer); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - /** - * Generates index.html and other top-level frame files. - * @param Mappings - * @return 0 if no errors, or 1 if error occurred. - */ - int generateSrc(Mappings map) { - try { - int len; - Object o[]; - String outputDir = Main.getOutputDir(); - FileWriter fw1, fw2; - BufferedWriter out1, out2; - - /* Whether alias list exists or not. */ - Map a = map.getAliases(); - if (a == null) { - Main.panic("Data not exist. (aliases)"); - return 1; - } - - timezoneList.putAll(a); - - /* If outputDir doesn't end with file-separator, adds it. */ - if (!outputDir.endsWith(File.separator)) { - outputDir += File.separatorChar; - } - outputDir += docDir + File.separatorChar; - - File outD = new File(outputDir); - outD.mkdirs(); - - /* Creates index.html */ - fw1 = new FileWriter(outputDir + "index.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + - "\n" + - "\n" + - "\n" + - "\n" + - "" + - "\n" + - "\n" + - "\n" + - "<H2>\nFrame Alert\n</H2>\n\n" + - "<P>\n\n" + - "This document is designed to be viewed using the frames feature. If you see this\n" + - "message, you are using a non-frame-capable web client.\n" + - "<BR>\n" + - "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" + - "\n" + footer); - - out1.close(); - fw1.close(); - - - /* Creates overview-frame.html */ - fw1 = new FileWriter(outputDir + "overview-frame.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "\n\n" + - "\n" + - "\n
    \n" + - "JavaTM Platform
    Standard Ed.
    \n\n" + - "\n\n\n
    " + - "

    \n\nAll Time Zones Sorted By:\n
    \n" + - "  GMT offsets\n
    \n" + - "  Zone names\n
    " + - "  City names\n" + - "

    \n\nContinents and Oceans\n
    \n"); - - for (String regionKey : regionList.keySet()) { - out1.write("  " + regionKey + - "
    \n"); - - fw2 = new FileWriter(outputDir + regionList.get(regionKey), - false); - out2 = new BufferedWriter(fw2); - - out2.write(header1 + new Date() + header3 + regionKey + - header4 + body1 + "" + - regionKey + "\n
    \n\n\n\n\n
    "); - - boolean found = false; - for (String timezoneKey : timezoneList.keySet()) { - int regionIndex = timezoneKey.indexOf('/'); - if (regionIndex == -1 || - !regionKey.equals(timezoneKey.substring(0, regionIndex))) { - if (found) { - break; - } else { - continue; - } - } - - found = true; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out2.write(timezoneKey + - " (alias for " + "" + - realName + ")"); - } else { - out2.write("" + timezoneKey + - ""); - } - out2.write("
    \n"); - } - out2.write("
    \n" + body2 + footer); - - out2.close(); - fw2.close(); - } - out1.write("

    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by GMT offsets\n" + - "
    \n\n" + "\n" + - "\n\n\n\n\n"); - } - } - out1.write("\n\n
    \n"); - - List roi = map.getRawOffsetsIndex(); - List> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (Integer offset : zonesByOffset.keySet()) { - int off = roi.get(index); - Set perRO = zonesByOffset.get(offset); - if (offset == off) { - // Merge aliases into zonesByOffset - perRO.addAll(roit.get(index)); - } - index++; - - for (String timezoneKey : perRO) { - out1.write("
    (" + - Time.toGMTFormat(offset.toString()) + - ")"); - - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + "" + realName + - ")"); - } else { - out1.write("" + timezoneKey + - ""); - } - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - - /* Creates allTimeZone-frame2.html (Sorted by zone names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by zone names\n" + - "
    \n\n" + "\n" + - "\n\n\n
    \n"); - o = timezoneList.keySet().toArray(); - len = timezoneList.size(); - for (int i = 0; i < len; i++) { - Object timezoneKey = o[i]; - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(timezoneKey + - " (alias for " + - "" + realName + - ")"); - } else { - out1.write("" + timezoneKey + - ""); - } - out1.write("
    \n"); - } - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates allTimeZone-frame3.html (Sorted by city names) */ - fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "Sorted by city names\n" + - "
    \n\n" + "\n" + - "\n\n\n
    \n"); - - Set aliasSet = a.keySet(); - len = aliasSet.size(); - String aliasNames[] = aliasSet.toArray(new String[0]); - for (int i = 0; i < len; i++) { - displayNameList.put(transform(aliasNames[i]), - aliasNames[i]); - } - - o = displayNameList.keySet().toArray(); - len = displayNameList.size(); - for (int i = 0; i < len; i++) { - Object displayName = o[i]; - Object timezoneKey = displayNameList.get(o[i]); - if (a.containsKey(timezoneKey)) { - Object realName = a.get(timezoneKey); - while (a.containsKey(realName)) { - realName = a.get(realName); - } - out1.write(displayName + - " (alias for " + - "" + realName + - ")"); - } else { - out1.write("" + displayName + - ""); - } - out1.write("
    \n"); - } - - out1.write("
    \n" + body2 + footer); - - out1.close(); - fw1.close(); - - /* Creates overview-summary.html */ - fw1 = new FileWriter(outputDir + "overview-summary.html", false); - out1 = new BufferedWriter(fw1); - - out1.write(header1 + new Date() + header2 + Main.getVersionName() + - header4 + body1 + - "

    This is the list of time zones generated from " + - Main.getVersionName() + " for Java Platform, " + - "Standard Edition. The source code can be obtained " + - "from ftp site " + - "ftp://elsie.nci.nih.gov/pub/. A total of " + - len + - " time zones and aliases are supported " + - "in this edition. For the " + - "format of rules and zones, refer to the zic " + - "(zoneinfo compiler) man page on " + - "Solaris or Linux.

    \n" + - "

    Note that the time zone data is not " + - "a public interface of the Java Platform. No " + - "applications should rely on the time zone data of " + - "this document. Time zone names and data " + - "may change without any prior notice.

    \n" + - body2 + footer); - - out1.close(); - fw1.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } - - String transform(String s) { - int index = s.lastIndexOf("/"); - - /* If the string doesn't include any delimiter, return */ - if (index == -1) { - return s; - } - - int lastIndex = index; - String str = s.substring(index+1); - do { - index = s.substring(0, lastIndex).lastIndexOf('/'); - str += ", " + s.substring(index+1, lastIndex); - lastIndex = index; - } while (index > -1); - - return str; - } - - static class LatitudeAndLongitude { - - private int latDeg, latMin, latSec, longDeg, longMin, longSec; - - LatitudeAndLongitude(String s) { - try { - // First of all, check the string has the correct format: - // either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS - - if (!s.startsWith("+") && !s.startsWith("-")) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - int index; - if (((index = s.lastIndexOf("+")) <= 0) && - ((index = s.lastIndexOf("-")) <= 0)) { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - - if (index == 5) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = 0; - } else if (index == 7) { - latDeg = Integer.parseInt(s.substring(1, 3)); - latMin = Integer.parseInt(s.substring(3, 5)); - latSec = Integer.parseInt(s.substring(5, 7)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.startsWith("-")){ - latDeg = -latDeg; - latMin = -latMin; - latSec = -latSec; - } - - int len = s.length(); - if (index == 5 && len == 11) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = 0; - } else if (index == 7 && len == 15) { - longDeg = Integer.parseInt(s.substring(index+1, index+4)); - longMin = Integer.parseInt(s.substring(index+4, index+6)); - longSec = Integer.parseInt(s.substring(index+6, index+8)); - } else { - Main.warning("Wrong latitude&longitude data: " + s); - return; - } - if (s.charAt(index) == '-'){ - longDeg = -longDeg; - longMin = -longMin; - longSec = -longSec; - } - } catch(Exception e) { - Main.warning("LatitudeAndLongitude() Parse error: " + s); - } - } - - int getLatDeg() { - return latDeg; - } - - int getLatMin() { - return latMin; - } - - int getLatSec() { - return latSec; - } - - int getLongDeg() { - return longDeg; - } - - int getLongMin() { - return longMin; - } - - int getLongSec() { - return longSec; - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Main.java b/test/jdk/sun/util/calendar/zi/Main.java deleted file mode 100644 index 8078d7e2425d2..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Main.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Main class for the javazic time zone data compiler. - * - * @since 1.4 - */ -public class Main { - - private static boolean verbose = false; - static boolean outputDoc = false; - - private List ziFiles = new ArrayList(); - private static String zoneNamesFile = null; - private static String versionName = "unknown"; - private static String outputDir = "zoneinfo"; - private static String mapFile = null; - - /** - * Parses the specified arguments and sets up the variables. - * @param argv the arguments - */ - void processArgs(String[] argv) { - for (int i = 0; i < argv.length; i++) { - String arg = argv[i]; - if (arg.startsWith("-h")) { - usage(); - System.exit(0); - } else if (arg.equals("-d")) { - outputDir = argv[++i]; - } else if (arg.equals("-v")) { - verbose = true; - } else if (arg.equals("-V")) { - versionName = argv[++i]; - } else if (arg.equals("-doc")) { - outputDoc = true; - } else if (arg.equals("-map")) { - outputDoc = true; - mapFile = argv[++i]; - } else if (arg.equals("-f")) { - zoneNamesFile = argv[++i]; - } else if (arg.equals("-S")) { - try { - Zoneinfo.setYear(Integer.parseInt(argv[++i])); - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - boolean isStartYear = arg.equals("-s"); - if (isStartYear || arg.equals("-e")) { - try { - int year = Integer.parseInt(argv[++i]); - if (isStartYear) { - Zoneinfo.setStartYear(year); - } else { - Zoneinfo.setEndYear(year); - } - } catch (Exception e) { - error("invalid year: " + argv[i]); - usage(); - System.exit(1); - } - } else { - // the rest of args are zoneinfo source files - while (i < argv.length) { - ziFiles.add(argv[i++]); - } - } - } - } - } - - /** - * Parses zoneinfo source files - */ - int compile() { - int nFiles = ziFiles.size(); - int status = 0; - Mappings maps = new Mappings(); - BackEnd backend = BackEnd.getBackEnd(); - - for (int i = 0; i < nFiles; i++) { - Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i)); - - for (String key : frontend.getZones().keySet()) { - info(key); - - Timezone tz = frontend.phase2(key); - status |= backend.processZoneinfo(tz); - } - - maps.add(frontend); - } - - // special code for dealing with the conflicting name "MET" - Zone.addMET(); - - maps.resolve(); - - status |= backend.generateSrc(maps); - - return status; - } - - public static void main(String[] argv) { - Main zic = new Main(); - - /* - * Parse args - */ - zic.processArgs(argv); - - /* - * Read target zone names - */ - if (zoneNamesFile != null) { - Zone.readZoneNames(zoneNamesFile); - } - - zic.compile(); - } - - void usage() { - System.err.println("Usage: javazic [options] file...\n"+ - " -f namefile file containing zone names\n"+ - " to be generated (ie, generating subset)\n"+ - " -d dir output directory\n"+ - " -v verbose\n"+ - " -V datavers specifies the tzdata version string\n"+ - " (eg, \"tzdata2000g\")"+ - " -S year output only SimleTimeZone data of that year\n"+ - " -s year start year (default: 1900)\n"+ - " -e year end year (default: 2037)\n"+ - " -doc generates HTML documents\n"+ - " -map mapfile generates HTML documents with map information\n"+ - " file... zoneinfo source file(s)"); - } - - /** - * @return the output directory path name - */ - static String getOutputDir() { - return outputDir; - } - - /** - * @return the map file's path and name - */ - static String getMapFile() { - return mapFile; - } - - /** - * Returns the time zone data version string specified by the -V - * option. If it is not specified, "unknown" is returned. - * @return the time zone data version string - */ - static String getVersionName() { - return versionName; - } - - /** - * Prints out the specified fatal error message and calls {@link - * java.lang.System#exit System.exit(1)}. - * @param msg the fatal error message - */ - static void panic(String msg) { - printMessage("fatal error", msg); - System.exit(1); - } - - /** - * Prints out the specified error message. - * @param msg the error message - */ - static void error(String msg) { - printMessage("error", msg); - } - - /** - * Prints out the specified warning message. - * @param msg the warning message - */ - static void warning(String msg) { - printMessage("warning", msg); - } - - /** - * Prints out the informative message. - * @param msg the informative message - */ - static void info(String msg) { - if (verbose) { - printMessage(null, msg); - } - } - - private static void printMessage(String type, String msg) { - if (type != null) { - type += ": "; - } else { - type = ""; - } - System.err.println("javazic: " + type + msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Mappings.java b/test/jdk/sun/util/calendar/zi/Mappings.java deleted file mode 100644 index 582a9509a51c8..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Mappings.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * Mappings generates two Maps and a List which are used by - * javazic BackEnd. - * - * @since 1.4 - */ -class Mappings { - // All aliases specified by Link statements. It's alias name to - // real name mappings. - private Map aliases; - - private List rawOffsetsIndex; - - private List> rawOffsetsIndexTable; - - // Zone names to be excluded from rawOffset table. Those have GMT - // offsets to change some future time. - private List excludeList; - - /** - * Constructor creates some necessary instances. - */ - Mappings() { - aliases = new TreeMap(); - rawOffsetsIndex = new LinkedList(); - rawOffsetsIndexTable = new LinkedList>(); - } - - /** - * Generates aliases and rawOffsets tables. - * @param zi a Zoneinfo containing Zones - */ - void add(Zoneinfo zi) { - Map zones = zi.getZones(); - - for (String zoneName : zones.keySet()) { - Zone zone = zones.get(zoneName); - String zonename = zone.getName(); - int rawOffset = zone.get(zone.size()-1).getGmtOffset(); - - // If the GMT offset of this Zone will change in some - // future time, this Zone is added to the exclude list. - boolean isExcluded = false; - for (int i = 0; i < zone.size(); i++) { - ZoneRec zrec = zone.get(i); - if ((zrec.getGmtOffset() != rawOffset) - && (zrec.getUntilTime(0) > Time.getCurrentTime())) { - if (excludeList == null) { - excludeList = new ArrayList(); - } - excludeList.add(zone.getName()); - isExcluded = true; - break; - } - } - - if (!rawOffsetsIndex.contains(new Integer(rawOffset))) { - // Find the index to insert this raw offset zones - int n = rawOffsetsIndex.size(); - int i; - for (i = 0; i < n; i++) { - if (rawOffsetsIndex.get(i) > rawOffset) { - break; - } - } - rawOffsetsIndex.add(i, rawOffset); - - Set perRawOffset = new TreeSet(); - if (!isExcluded) { - perRawOffset.add(zonename); - } - rawOffsetsIndexTable.add(i, perRawOffset); - } else if (!isExcluded) { - int i = rawOffsetsIndex.indexOf(new Integer(rawOffset)); - Set perRawOffset = rawOffsetsIndexTable.get(i); - perRawOffset.add(zonename); - } - } - - Map a = zi.getAliases(); - // If there are time zone names which refer to any of the - // excluded zones, add those names to the excluded list. - if (excludeList != null) { - for (String zoneName : a.keySet()) { - String realname = a.get(zoneName); - if (excludeList.contains(realname)) { - excludeList.add(zoneName); - } - } - } - aliases.putAll(a); - } - - /** - * Adds valid aliases to one of per-RawOffset table and removes - * invalid aliases from aliases List. Aliases referring to - * excluded zones are not added to a per-RawOffset table. - */ - void resolve() { - int index = rawOffsetsIndexTable.size(); - List toBeRemoved = new ArrayList(); - for (String key : aliases.keySet()) { - boolean validname = false; - for (int j = 0; j < index; j++) { - Set perRO = rawOffsetsIndexTable.get(j); - boolean isExcluded = (excludeList == null) ? - false : excludeList.contains(key); - - if ((perRO.contains(aliases.get(key)) || isExcluded) - && Zone.isTargetZone(key)) { - validname = true; - if (!isExcluded) { - perRO.add(key); - Main.info("Alias <"+key+"> added to the list."); - } - break; - } - } - - if (!validname) { - Main.info("Alias <"+key+"> removed from the list."); - toBeRemoved.add(key); - } - } - - // Remove zones, if any, from the list. - for (String key : toBeRemoved) { - aliases.remove(key); - } - // Eliminate any alias-to-alias mappings. For example, if - // there are A->B and B->C, A->B is changed to A->C. - Map newMap = new HashMap(); - for (String key : aliases.keySet()) { - String realid = aliases.get(key); - String leaf = realid; - while (aliases.get(leaf) != null) { - leaf = aliases.get(leaf); - } - if (!realid.equals(leaf)) { - newMap.put(key, leaf); - } - } - aliases.putAll(newMap); - } - - Map getAliases() { - return(aliases); - } - - List getRawOffsetsIndex() { - return(rawOffsetsIndex); - } - - List> getRawOffsetsIndexTable() { - return(rawOffsetsIndexTable); - } - - List getExcludeList() { - return excludeList; - } -} diff --git a/test/jdk/sun/util/calendar/zi/Month.java b/test/jdk/sun/util/calendar/zi/Month.java deleted file mode 100644 index bab909f763787..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Month.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * Month enum handles month related manipulation. - * - * @since 1.4 - */ -enum Month { - JANUARY("Jan"), - FEBRUARY("Feb"), - MARCH("Mar"), - APRIL("Apr"), - MAY("May"), - JUNE("Jun"), - JULY("Jul"), - AUGUST("Aug"), - SEPTEMBER("Sep"), - OCTOBER("Oct"), - NOVEMBER("Nov"), - DECEMBER("Dec"); - - private final String abbr; - - private Month(String abbr) { - this.abbr = abbr; - } - - int value() { - return ordinal() + 1; - } - - /** - * Parses the specified string as a month abbreviation. - * @param name the month abbreviation - * @return the Month value - */ - static Month parse(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY; - if (name.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY; - if (name.regionMatches(true, 0, "March", 0, len)) return Month.MARCH; - if (name.regionMatches(true, 0, "April", 0, len)) return Month.APRIL; - if (name.regionMatches(true, 0, "May", 0, len)) return Month.MAY; - if (name.regionMatches(true, 0, "June", 0, len)) return Month.JUNE; - if (name.regionMatches(true, 0, "July", 0, len)) return Month.JULY; - if (name.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST; - if (name.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER; - if (name.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER; - if (name.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER; - if (name.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER; - - throw new IllegalArgumentException("Unknown month: " + name); - } - - /** - * @param month the nunmth number (1-based) - * @return the month name in uppercase of the specified month - */ - static String toString(int month) { - if (month >= JANUARY.value() && month <= DECEMBER.value()) { - return "Calendar." + Month.values()[month - 1]; - } - throw new IllegalArgumentException("wrong month number: " + month); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Rule.java b/test/jdk/sun/util/calendar/zi/Rule.java deleted file mode 100644 index 3098dc7e76651..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Rule.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Rule manipulates Rule records. - * - * @since 1.4 - */ -class Rule { - - private List list; - private String name; - - /** - * Constructs a Rule which consists of a Rule record list. The - * specified name is given to this Rule. - * @param name the Rule name - */ - Rule(String name) { - this.name = name; - list = new ArrayList(); - } - - /** - * Added a RuleRec to the Rule record list. - */ - void add(RuleRec rec) { - list.add(rec); - } - - /** - * @return the Rule name - */ - String getName() { - return name; - } - - /** - * Gets all rule records that cover the given year. - * - * @param year the year number for which the rule is applicable. - * @return rules in List that are collated in time. If no rule is found, an empty - * List is returned. - */ - List getRules(int year) { - List rules = new ArrayList(3); - for (RuleRec rec : list) { - if (year >= rec.getFromYear() && year <= rec.getToYear()) { - if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1)) - continue; - rules.add(rec); - } - } - int n = rules.size(); - if (n <= 1) { - return rules; - } - if (n == 2) { - RuleRec rec1 = rules.get(0); - RuleRec rec2 = rules.get(1); - if (rec1.getMonthNum() > rec2.getMonthNum()) { - rules.set(0, rec2); - rules.set(1, rec1); - } else if (rec1.getMonthNum() == rec2.getMonthNum()) { - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(year, rec1.getMonth(), - rec1.getDay(), rec1.getTime().getTime()); - long t2 = Time.getLocalTime(year, rec2.getMonth(), - rec2.getDay(), rec2.getTime().getTime()); - if (t1 > t2) { - rules.set(0, rec2); - rules.set(1, rec1); - } - } - return rules; - } - - final int y = year; - RuleRec[] recs = new RuleRec[rules.size()]; - rules.toArray(recs); - - Arrays.sort(recs, new Comparator() { - public int compare(RuleRec r1, RuleRec r2) { - int n = r1.getMonthNum() - r2.getMonthNum(); - if (n != 0) { - return n; - } - // TODO: it's not accurate to ignore time types (STD, WALL, UTC) - long t1 = Time.getLocalTime(y, r1.getMonth(), - r1.getDay(), r1.getTime().getTime()); - long t2 = Time.getLocalTime(y, r2.getMonth(), - r2.getDay(), r2.getTime().getTime()); - return Long.compare(t1, t2); - } - public boolean equals(Object o) { - return this == o; - } - }); - rules.clear(); - for (int i = 0; i < n; i++) { - if (i != 0 && recs[i -1].getSave() == recs[i].getSave()) { - // we have two recs back to back with same saving for the same year. - if (recs[i].isLastRule()) { - continue; - } else if (recs[i - 1].isLastRule()) { - rules.remove(rules.size() - 1); - } - } - rules.add(recs[i]); - } - return rules; - } - - /** - * Gets rule records that have either "max" or cover the endYear - * value in its DST schedule. - * - * @return rules that contain last DST schedule. An empty - * ArrayList is returned if no last rules are found. - */ - List getLastRules() { - RuleRec start = null; - RuleRec end = null; - - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (rec.isLastRule()) { - if (rec.getSave() > 0) { - start = rec; - } else { - end = rec; - } - } - } - if (start == null || end == null) { - int endYear = Zoneinfo.getEndYear(); - for (int i = 0; i < list.size(); i++) { - RuleRec rec = list.get(i); - if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) { - if (start == null && rec.getSave() > 0) { - start = rec; - } else { - if (end == null && rec.getSave() == 0) { - end = rec; - } - } - } - } - } - - List r = new ArrayList(2); - if (start == null || end == null) { - if (start != null || end != null) { - Main.warning("found last rules for "+name+" inconsistent."); - } - return r; - } - - r.add(start); - r.add(end); - return r; - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleDay.java b/test/jdk/sun/util/calendar/zi/RuleDay.java deleted file mode 100644 index 9cd81c1e5246f..0000000000000 --- a/test/jdk/sun/util/calendar/zi/RuleDay.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * RuleDay class represents the value of the "ON" field. The day of - * week values start from 1 following the {@link java.util.Calendar} - * convention. - * - * @since 1.4 - */ -class RuleDay { - private String dayName = null; - private DayOfWeek dow; - private boolean lastOne = false; - private int soonerOrLater = 0; - private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8") - - RuleDay() { - } - - RuleDay(int day) { - thanDayOfMonth = day; - } - - int getDay() { - return thanDayOfMonth; - } - - /** - * @return the day of week value (1-based) - */ - int getDayOfWeekNum() { - return dow.value(); - } - - /** - * @return true if this rule day represents the last day of - * week. (e.g., lastSun). - */ - boolean isLast() { - return lastOne; - } - - /** - * @return true if this rule day represents the day of week on or - * later than (after) the {@link #getDay}. (e.g., Sun>=1) - */ - boolean isLater() { - return soonerOrLater > 0; - } - - /** - * @return true if this rule day represents the day of week on or - * earlier than (before) the {@link #getDay}. (e.g., Sun<=15) - */ - boolean isEarlier() { - return soonerOrLater < 0; - } - - /** - * @return true if this rule day represents an exact day. - */ - boolean isExact() { - return soonerOrLater == 0; - } - - /** - * Parses the "ON" field and constructs a RuleDay. - * @param day an "ON" field string (e.g., "Sun>=1") - * @return a RuleDay representing the given "ON" field - */ - static RuleDay parse(String day) { - RuleDay d = new RuleDay(); - if (day.startsWith("last")) { - d.lastOne = true; - d.dayName = day.substring(4); - d.dow = getDOW(d.dayName); - } else { - int index; - if ((index = day.indexOf(">=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = 1; // greater or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else if ((index = day.indexOf("<=")) != -1) { - d.dayName = day.substring(0, index); - d.dow = getDOW(d.dayName); - d.soonerOrLater = -1; // less or equal - d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); - } else { - // it should be an integer value. - d.thanDayOfMonth = Integer.parseInt(day); - } - } - return d; - } - - /** - * Converts this RuleDay to the SimpleTimeZone day rule. - * @return the converted SimpleTimeZone day rule - */ - int getDayForSimpleTimeZone() { - if (isLast()) { - return -1; - } - return isEarlier() ? -getDay() : getDay(); - } - - /** - * Converts this RuleDay to the SimpleTimeZone day-of-week rule. - * @return the SimpleTimeZone day-of-week rule value - */ - int getDayOfWeekForSimpleTimeZoneInt() { - if (isEarlier() || isLater()) { - return -getDayOfWeekNum(); - } - return isLast() ? getDayOfWeekNum() : 0; - } - - /** - * @return the string representation of the {@link - * #getDayOfWeekForSimpleTimeZoneInt} value - */ - String getDayOfWeekForSimpleTimeZone() { - int d = getDayOfWeekForSimpleTimeZoneInt(); - if (d == 0) { - return "0"; - } - String sign = ""; - if (d < 0) { - sign = "-"; - d = -d; - } - return sign + toString(d); - } - - private static DayOfWeek getDOW(String name) { - int len = name.length(); - - if (name.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY; - if (name.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY; - if (name.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY; - if (name.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY; - if (name.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY; - if (name.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY; - if (name.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY; - - throw new IllegalArgumentException("Unknown day-of-week: " + name); - } - - /** - * Converts the specified day of week value to the day-of-week - * name defined in {@link java.util.Calendar}. - * @param dow 1-based day of week value - * @return the Calendar day of week name with "Calendar." prefix. - * @throws IllegalArgumentException if the specified dow value is out of range. - */ - static String toString(int dow) { - if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) { - return "Calendar." + DayOfWeek.values()[dow - 1]; - } - throw new IllegalArgumentException("wrong Day_of_Week number: " + dow); - } -} diff --git a/test/jdk/sun/util/calendar/zi/RuleRec.java b/test/jdk/sun/util/calendar/zi/RuleRec.java deleted file mode 100644 index e6e18773d1606..0000000000000 --- a/test/jdk/sun/util/calendar/zi/RuleRec.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.StringTokenizer; - -/** - * RuleRec class represents one record of the Rule set. - * - * @since 1.4 - */ -class RuleRec { - private int fromYear; - private int toYear; - private String type; - private Month inMonth; - private RuleDay onDay; - private Time atTime; - private int save; - private String letters; - private String line; - private boolean isLastRule; - - int getFromYear() { - return fromYear; - } - - int getToYear() { - return toYear; - } - - Month getMonth() { - return inMonth; - } - - int getMonthNum() { - return inMonth.value(); - } - - RuleDay getDay() { - return onDay; - } - - Time getTime() { - return atTime; - } - - int getSave() { - return save; - } - - String getLine() { - return line; - } - - /** - * Sets the line from the text file. - * @param line the text of the line - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if the rule type is "odd". - */ - boolean isOdd() { - return "odd".equals(type); - } - - /** - * @return true if the rule type is "even". - */ - boolean isEven() { - return "even".equals(type); - } - - /** - * Determines if this rule record is the last DST schedule rule. - * - * @return true if this rule record has "max" as TO (year). - */ - boolean isLastRule() { - return isLastRule; - } - - /** - * Determines if the unadjusted until time of the specified ZoneRec - * is the same as the transition time of this rule in the same - * year as the ZoneRec until year. - * - * @param zrec ZoneRec to compare to - * @param save the amount of daylight saving in milliseconds - * @param gmtOffset the GMT offset value in milliseconds - * @return true if the unadjusted until time is the same as rule's - * transition time. - */ - boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) { - long until, transition; - - if (zrec.getUntilTime().getType() != atTime.getType()) { - until = zrec.getLocalUntilTime(save, gmtOffset); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - save, - gmtOffset, - atTime); - } else { - until = zrec.getLocalUntilTime(); - transition = Time.getLocalTime(zrec.getUntilYear(), - getMonth(), - getDay(), - atTime.getTime()); - } - - return until == transition; - } - - /** - * Parses a Rule line and returns a RuleRec object. - * - * @param tokens a StringTokenizer object that should contain a - * token for the "FROM" field and the rest. - * @return a RuleRec object. - */ - static RuleRec parse(StringTokenizer tokens) { - RuleRec rec = new RuleRec(); - try { - // FROM - String token = tokens.nextToken(); - try { - rec.fromYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - if ("min".equals(token) || "minimum".equals(token)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if ("max".equals(token) || "maximum".equals(token)) { - rec.fromYear = Zoneinfo.getMaxYear(); - } else { - Main.panic("invalid year value: "+token); - } - } - - // TO - token = tokens.nextToken(); - rec.isLastRule = false; - try { - rec.toYear = Integer.parseInt(token); - } catch (NumberFormatException e) { - // it's not integer - int len = token.length(); - if (token.regionMatches(true, 0, "minimum", 0, len)) { - rec.fromYear = Zoneinfo.getMinYear(); - } else if (token.regionMatches(true, 0, "maximum", 0, len)) { - rec.toYear = Integer.MAX_VALUE; - rec.isLastRule = true; - } else if (token.regionMatches(true, 0, "only", 0, len)) { - rec.toYear = rec.fromYear; - } else { - Main.panic("invalid year value: "+token); - } - } - - // TYPE - rec.type = tokens.nextToken(); - - // IN - rec.inMonth = Month.parse(tokens.nextToken()); - - // ON - rec.onDay = RuleDay.parse(tokens.nextToken()); - - // AT - rec.atTime = Time.parse(tokens.nextToken()); - - // SAVE - rec.save = (int) Time.parse(tokens.nextToken()).getTime(); - - // LETTER/S - rec.letters = tokens.nextToken(); - } catch (Exception e) { - e.printStackTrace(); - } - return rec; - } - - /** - * Calculates the transition time of the given year under this rule. - * @param year the year value - * @param gmtOffset the GMT offset value in milliseconds - * @param save the amount of daylight save time - * @return the transition time in milliseconds of the given year in UTC. - */ - long getTransitionTime(int year, int gmtOffset, int save) { - long time = Time.getLocalTime(year, getMonth(), - getDay(), atTime.getTime()); - if (atTime.isSTD()) { - time -= gmtOffset; - } else if (atTime.isWall()) { - time -= gmtOffset + save; - } - return time; - } - - private static int getInt(StringTokenizer tokens) { - String token = tokens.nextToken(); - return Integer.parseInt(token); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Simple.java b/test/jdk/sun/util/calendar/zi/Simple.java deleted file mode 100644 index 0889155a99e97..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Simple.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.TreeSet; - -/** - * Simple generates TimeZoneData, which had been used as internal - * data of TimeZone before J2SDK1.3. - * Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance - * of old JDK release. - */ -class Simple extends BackEnd { - - /** - * Zone records which are applied for given year. - */ - private static Map lastZoneRecs = new HashMap<>(); - - /** - * Rule records which are applied for given year. - */ - private static Map> lastRules = new TreeMap<>(); - - /** - * zone IDs sorted by their GMT offsets. If zone's GMT - * offset will change in the future, its last known offset is - * used. - */ - private SortedMap> zonesByOffset = new TreeMap<>(); - - /** - * Sets last Rule records and Zone records for given timezone to - * each Map. - * - * @param tz Timezone object for each zone - * @return always 0 - */ - int processZoneinfo(Timezone tz) { - String zonename = tz.getName(); - - lastRules.put(zonename, tz.getLastRules()); - lastZoneRecs.put(zonename, tz.getLastZoneRec()); - - // Populate zonesByOffset. (Zones that will change their - // GMT offsets are also added to zonesByOffset here.) - int lastKnownOffset = tz.getRawOffset(); - Set set = zonesByOffset.get(lastKnownOffset); - if (set == null) { - set = new TreeSet<>(); - zonesByOffset.put(lastKnownOffset, set); - } - set.add(zonename); - - return 0; - } - - /** - * Generates TimeZoneData to output SimpleTimeZone data. - * @param map Mappings object which is generated by {@link Main#compile}. - * @return 0 if no error occurred, otherwise 1. - */ - int generateSrc(Mappings map) { - try { - File outD = new File(Main.getOutputDir()); - outD.mkdirs(); - - FileWriter fw = - new FileWriter(new File(outD, "TimeZoneData.java"), false); - BufferedWriter out = new BufferedWriter(fw); - - out.write("import java.util.SimpleTimeZone;\n\n"); - out.write(" static SimpleTimeZone zones[] = {\n"); - - Map a = map.getAliases(); - List roi = map.getRawOffsetsIndex(); - List> roit = map.getRawOffsetsIndexTable(); - - int index = 0; - for (int offset : zonesByOffset.keySet()) { - int o = roi.get(index); - Set set = zonesByOffset.get(offset); - if (offset == o) { - // Merge aliases into zonesByOffset - set.addAll(roit.get(index)); - } - index++; - - for (String key : set) { - ZoneRec zrec; - String realname; - List stz; - if ((realname = a.get(key)) != null) { - // if this alias is not targeted, ignore it. - if (!Zone.isTargetZone(key)) { - continue; - } - stz = lastRules.get(realname); - zrec = lastZoneRecs.get(realname); - } else { - stz = lastRules.get(key); - zrec = lastZoneRecs.get(key); - } - - out.write("\t//--------------------------------------------------------------------\n"); - String s = Time.toFormedString(offset); - out.write("\tnew SimpleTimeZone(" + - Time.toFormedString(offset) + ", \"" + key + "\""); - if (realname != null) { - out.write(" /* " + realname + " */"); - } - - if (stz == null) { - out.write("),\n"); - } else { - RuleRec rr0 = stz.get(0); - RuleRec rr1 = stz.get(1); - - out.write(",\n\t " + Month.toString(rr0.getMonthNum()) + - ", " + rr0.getDay().getDayForSimpleTimeZone() + ", " + - rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr0.getTime().getTime()) + ", " + - rr0.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Month.toString(rr1.getMonthNum()) + ", " + - rr1.getDay().getDayForSimpleTimeZone() + ", " + - rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " + - Time.toFormedString((int)rr1.getTime().getTime())+ ", " + - rr1.getTime().getTypeForSimpleTimeZone() + ",\n" + - - "\t " + Time.toFormedString(rr0.getSave()) + "),\n"); - - out.write("\t// " + rr0.getLine() + "\n"); - out.write("\t// " + rr1.getLine() + "\n"); - } - - String zline = zrec.getLine(); - if (zline.indexOf("Zone") == -1) { - zline = "Zone " + key + "\t" + zline.trim(); - } - out.write("\t// " + zline + "\n"); - } - } - out.write(" };\n"); - - out.close(); - fw.close(); - } catch(IOException e) { - Main.panic("IO error: "+e.getMessage()); - return 1; - } - - return 0; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java b/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java deleted file mode 100644 index 0b6570b74dc73..0000000000000 --- a/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8007572 8008161 8157792 8212970 8224560 8324065 - * @summary Test whether the TimeZone generated from JSR310 tzdb is the same - * as the one from the tz data from javazic - * @modules java.base/sun.util.calendar:+open - * @build BackEnd Checksum DayOfWeek Gen GenDoc Main Mappings Month - * Rule RuleDay RuleRec Simple TestZoneInfo310 Time Timezone - * TzIDOldMapping Zone ZoneInfoFile ZoneInfoOld ZoneRec Zoneinfo - * @run main TestZoneInfo310 - */ - -import java.io.File; -import java.lang.reflect.*; -import java.nio.file.*; -import java.util.*; -import java.util.regex.*; -import java.time.zone.*; -import java.time.ZoneId; - -public class TestZoneInfo310 { - - public static void main(String[] args) throws Throwable { - - String TESTDIR = System.getProperty("test.dir", "."); - Path tzdir = Paths.get(System.getProperty("test.root"), - "../../src/java.base/share/data/tzdata"); - String tzfiles = "africa antarctica asia australasia europe northamerica southamerica backward etcetera gmt"; - Path jdk_tzdir = Paths.get(System.getProperty("test.src"), "tzdata_jdk"); - String jdk_tzfiles = "jdk11_backward"; - String zidir = TESTDIR + File.separator + "zi"; - File fZidir = new File(zidir); - if (!fZidir.exists()) { - fZidir.mkdirs(); - } - Matcher m = Pattern.compile("tzdata(?[0-9]{4}[A-z])") - .matcher(new String(Files.readAllBytes(tzdir.resolve("VERSION")), "ascii")); - String ver = m.find() ? m.group("ver") : "NULL"; - - ArrayList alist = new ArrayList<>(); - alist.add("-V"); - alist.add(ver); - alist.add("-d"); - alist.add(zidir); - for (String f : tzfiles.split(" ")) { - alist.add(tzdir.resolve(f).toString()); - } - for (String f : jdk_tzfiles.split(" ")) { - alist.add(jdk_tzdir.resolve(f).toString()); - } - System.out.println("Compiling tz files!"); - Main.main(alist.toArray(new String[alist.size()])); - - ////////////////////////////////// - System.out.println("testing!"); - ZoneInfoFile.ziDir = zidir; - long t0, t1; - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - ZoneInfoOld.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("OLD.getZoneInfoOld()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_old = ZoneInfoOld.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("OLD.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_old.length); - Arrays.sort(zids_old); - - t0 = System.nanoTime(); - String[] alias_old = ZoneInfoOld.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("OLD.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_old.length); - Arrays.sort(alias_old); - - t0 = System.currentTimeMillis(); - for (String zid : zids_old) { - ZoneInfoOld.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("OLD.TotalTZ()=%d (ms)%n", t1 - t0); - -/* - t0 = System.nanoTime(); - ZoneId.of("America/Los_Angeles").getRules(); - t1 = System.nanoTime(); - System.out.printf("NEW.ZoneId.of()[1]=%d%n", (t1 - t0) / 1000); -*/ - t0 = System.nanoTime(); - TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[1]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/New_York"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[2]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - tz = TimeZone.getTimeZone("America/Denver"); - t1 = System.nanoTime(); - System.out.printf("NEW.getTimeZone()[3]=%d%n", (t1 - t0) / 1000); - - t0 = System.nanoTime(); - String[] zids_new = TimeZone.getAvailableIDs(); - t1 = System.nanoTime(); - System.out.printf("NEW.getAvailableIDs()=%d, total=%d%n", - (t1 - t0) / 1000, zids_new.length); - Arrays.sort(zids_new); - - t0 = System.nanoTime(); - String[] alias_new = sun.util.calendar.ZoneInfo.getAliasTable() - .keySet().toArray(new String[0]); - t1 = System.nanoTime(); - System.out.printf("NEW.getAliasTable()=%d, total=%d%n", - (t1 - t0) / 1000, alias_new.length); - Arrays.sort(alias_new); - - t0 = System.currentTimeMillis(); - for (String zid : zids_new) { - TimeZone.getTimeZone(zid); - } - t1 = System.currentTimeMillis(); - System.out.printf("NEW.TotalTZ()=%d (ms)%n", t1 - t0); - - if (!Arrays.equals(zids_old, zids_new)) { - throw new RuntimeException(" FAILED: availableIds don't match"); - } - - if (!Arrays.equals(alias_old, alias_new)) { - throw new RuntimeException(" FAILED: aliases don't match"); - } - - for (String zid : zids_new) { - ZoneInfoOld zi = toZoneInfoOld(TimeZone.getTimeZone(zid)); - ZoneInfoOld ziOLD = (ZoneInfoOld)ZoneInfoOld.getTimeZone(zid); - /* - * Ignoring the failing TimeZones which have negative DST - * save time in IANA tzdata, as javazic/ZoneInfoOld cannot - * handle the negative DST. - * - * These are the zones/rules that employ negative DST in vanguard - * format (as of 2019a), Palestine added in 2022d: - * - * - Rule "Eire" - * - Rule "Morocco" - * - Rule "Namibia" - * - Rule "Palestine" - * - Zone "Europe/Prague" - */ - if (zid.equals("Africa/Casablanca") || // uses "Morocco" rule - zid.equals("Africa/El_Aaiun") || // uses "Morocco" rule - zid.equals("Africa/Windhoek") || // uses "Namibia" rule - zid.equals("Eire") || - zid.equals("Europe/Bratislava") || // link to "Europe/Prague" - zid.equals("Europe/Dublin") || // uses "Eire" rule - zid.equals("Europe/Prague") || - zid.equals("Asia/Gaza") || // uses "Palestine" rule - zid.equals("Asia/Hebron")) { // uses "Palestine" rule - continue; - } - if (! zi.equalsTo(ziOLD)) { - System.out.println(zi.diffsTo(ziOLD)); - throw new RuntimeException(" FAILED: " + zid); - } - } - delete(fZidir); - - // test tzdb version - if (!ver.equals(sun.util.calendar.ZoneInfoFile.getVersion())) { - System.out.printf(" FAILED: ver=%s, expected=%s%n", - sun.util.calendar.ZoneInfoFile.getVersion(), ver); - throw new RuntimeException("Version test failed"); - } - - // test getAvailableIDs(raw); - zids_new = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_new); - zids_old = ZoneInfoOld.getAvailableIDs(-8 * 60 * 60 * 1000); - Arrays.sort(zids_old); - if (!Arrays.equals(zids_new, zids_old)) { - System.out.println("------------------------"); - System.out.println("NEW.getAvailableIDs(-8:00)"); - for (String zid : zids_new) { - System.out.println(zid); - } - System.out.println("------------------------"); - System.out.println("OLD.getAvailableIDs(-8:00)"); - for (String zid : zids_old) { - System.out.println(zid); - } - throw new RuntimeException(" FAILED: availableIds(offset) don't match"); - } - } - - private static void delete(File f) { - if (f.isDirectory()) { - for (File f0 : f.listFiles()) { - delete(f0); - } - } - f.delete(); - } - - // to access sun.util.calendar.ZoneInfo's private fields - static Class ziClz; - static Field rawOffset; - static Field checksum; - static Field dstSavings; - static Field transitions; - static Field offsets; - static Field simpleTimeZoneParams; - static Field willGMTOffsetChange; - static { - try { - ziClz = Class.forName("sun.util.calendar.ZoneInfo"); - rawOffset = ziClz.getDeclaredField("rawOffset"); - checksum = ziClz.getDeclaredField("checksum"); - dstSavings = ziClz.getDeclaredField("dstSavings"); - transitions = ziClz.getDeclaredField("transitions"); - offsets = ziClz.getDeclaredField("offsets"); - simpleTimeZoneParams = ziClz.getDeclaredField("simpleTimeZoneParams"); - willGMTOffsetChange = ziClz.getDeclaredField("willGMTOffsetChange"); - rawOffset.setAccessible(true); - checksum.setAccessible(true); - dstSavings.setAccessible(true); - transitions.setAccessible(true); - offsets.setAccessible(true); - simpleTimeZoneParams.setAccessible(true); - willGMTOffsetChange.setAccessible(true); - } catch (Exception x) { - throw new RuntimeException(x); - } - } - - private static ZoneInfoOld toZoneInfoOld(TimeZone tz) throws Exception { - return new ZoneInfoOld(tz.getID(), - rawOffset.getInt(tz), - dstSavings.getInt(tz), - checksum.getInt(tz), - (long[])transitions.get(tz), - (int[])offsets.get(tz), - (int[])simpleTimeZoneParams.get(tz), - willGMTOffsetChange.getBoolean(tz)); - } - -} diff --git a/test/jdk/sun/util/calendar/zi/Time.java b/test/jdk/sun/util/calendar/zi/Time.java deleted file mode 100644 index 66379d29d28ee..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Time.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.Locale; -import sun.util.calendar.CalendarDate; -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.Gregorian; - -/** - * Time class represents the "AT" field and other time related information. - * - * @since 1.4 - */ -class Time { - - static final Gregorian gcal = CalendarSystem.getGregorianCalendar(); - - // type is wall clock time - private static final int WALL = 1; - - // type is standard time - private static final int STD = 2; - - // type is UTC - private static final int UTC = 3; - - // type of representing time - private int type; - - /** - * Time from the EPOCH in milliseconds - */ - private long time; - - /** - * Current time in milliseconds - */ - private static final long currentTime = System.currentTimeMillis(); - - Time() { - time = 0L; - } - - Time(long time) { - this.time = time; - } - - void setType(int type) { - this.type = type; - } - - long getTime() { - return time; - } - - int getType() { - return type; - } - - static long getCurrentTime() { - return currentTime; - } - - /** - * @return true if the time is represented in wall-clock time. - */ - boolean isWall() { - return type == WALL; - } - - /** - * @return true if the time is represented in standard time. - */ - boolean isSTD() { - return type == STD; - } - - /** - * @return true if the time is represented in UTC time. - */ - boolean isUTC() { - return type == UTC; - } - - /** - * Converts the type to a string that represents the type in the - * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME"). - * @return the converted string or null if the type is undefined. - */ - String getTypeForSimpleTimeZone() { - String stz = "SimpleTimeZone."; - if (isWall()) { - return stz+"WALL_TIME"; - } - else if (isSTD()) { - return stz+"STANDARD_TIME"; - } - else if (isUTC()) { - return stz+"UTC_TIME"; - } - else { - return null; - } - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param save the amount of daylight time in milliseconds - * @param gmtOffset the GMT offset in milliseconds - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int save, - int gmtOffset, Time time) { - long t = time.getTime(); - - if (time.isSTD()) - t = time.getTime() + save; - else if (time.isUTC()) - t = time.getTime() + save + gmtOffset; - - return getLocalTime(year, month, day, t); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, long time) { - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month.value(), day); - long millis = gcal.getTime(date); - return millis + time; - } - - /** - * Equivalent to getLocalTime(year, month, day, (long)time). - * @param year the year value - * @param month the Month value - * @param day the day value - * @param time the time of the day in milliseconds - * @return local time - */ - static long getLocalTime(int year, Month month, int day, int time) { - return getLocalTime(year, month, day, (long)time); - } - - /** - * Equivalent to {@link #getLocalTime(int, Month, RuleDay, int) - * getLocalTime(year, month, day, (int) time)}. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, long time) { - return getLocalTime(year, month, day, (int) time); - } - - /** - * Converts the given Gregorian calendar field values to local time. - * Local time is represented by the amount of milliseconds from - * January 1, 1970 0:00 GMT. - * @param year the year value - * @param month the Month value - * @param day the day represented by {@link RuleDay} - * @param time the time of the day represented by {@link Time} - * @return local time - */ - static long getLocalTime(int year, Month month, RuleDay day, int time) { - CalendarDate cdate = gcal.newCalendarDate(null); - int monthValue = month.value(); - - if (day.isLast()) { // e.g., "lastSun" - cdate.setDate(year, monthValue, 1); - cdate.setDayOfMonth(gcal.getMonthLength(cdate)); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else if (day.isLater()) { // e.g., "Sun>=1" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate); - } else if (day.isExact()) { - cdate.setDate(year, monthValue, day.getDay()); - } else if (day.isEarlier()) { // e.g., "Sun<=15" - cdate.setDate(year, monthValue, day.getDay()); - cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate); - } else { - Main.panic("invalid day type: " + day); - } - return gcal.getTime(cdate) + time; - } - - /** - * Parses the given "AT" field and constructs a Time object. - * @param the "AT" field string - * @return the Time object - */ - static Time parse(String time) { - int sign; - int index = 0; - Time tm; - - if (time.charAt(0) == '-') { - sign = -1; - index++; - } else { - sign = 1; - } - int val = 0; - int num = 0; - int countDelim = 0; - while (index < time.length()) { - char c = time.charAt(index++); - if (c == ':') { - val = val * 60 + num; - countDelim++; - num = 0; - continue; - } - int d = Character.digit(c, 10); - if (d == -1) { - --index; - break; - } - num = num * 10 + d; - } - val = val * 60 + num; - // convert val to second - for (; countDelim < 2; countDelim++) { - val *= 60; - } - tm = new Time((long)val * 1000 * sign); - if (index < time.length()) { - char c = time.charAt(index++); - if (c == 's') { - tm.setType(Time.STD); - } else if (c == 'u' || c == 'g' || c == 'z') { - tm.setType(Time.UTC); - } else if (c == 'w') { - tm.setType(Time.WALL); - } else { - Main.panic("unknown time mode: "+c); - } - } else { - tm.setType(Time.WALL); - } - return tm; - } - - /** - * Converts the given milliseconds string to a "[+-]hh:mm" string. - * @param ms the milliseconds string - */ - static String toGMTFormat(String ms) { - long sec = Long.parseLong(ms) / 1000; - char sign; - if (sec < 0) { - sign = '-'; - sec = -sec; - } else { - sign = '+'; - } - return String.format((Locale)null, "%c%02d:%02d", - sign, sec/3600, (sec%3600)/60); - } - - /** - * Converts the given millisecond value to a string for a - * SimpleTimeZone parameter. - * @param ms the millisecond value - * @return the string in a human readable form - */ - static String toFormedString(int ms) { - StringBuilder s = new StringBuilder(); - boolean minus = false; - - if (ms < 0) { - s.append("-"); - minus = true; - ms = -ms; - } else if (ms == 0) { - return "0"; - } - - int hour = ms / (60 * 60 * 1000); - ms %= (60 * 60 * 1000); - int minute = ms / (60 * 1000); - - if (hour != 0) { - if (minus && minute != 0) { - s.append("("); - } - s.append(Integer.toString(hour) + "*ONE_HOUR"); - } - - if (minute != 0) { - if (hour != 0) { - s.append("+"); - } - s.append(Integer.toString(minute) + "*ONE_MINUTE"); - if (minus && hour != 0) { - s.append(")"); - } - } - - return s.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Timezone.java b/test/jdk/sun/util/calendar/zi/Timezone.java deleted file mode 100644 index d4890e8f58b55..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Timezone.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.ArrayList; -import java.util.List; - -/** - * Timezone represents all information of a single point of time to - * generate its time zone database. - * - * @since 1.4 - */ -class Timezone { - /** - * zone name of this time zone - */ - private String name; - - /** - * transition time values in UTC (millisecond) - */ - private List transitions; - - /** - * All offset values in millisecond - * @see sun.util.calendar.ZoneInfo - */ - private List offsets; - - /** - * Indices of GMT offset values (both raw and raw+saving) - * at transitions - */ - private List gmtOffsets; - - /** - * Indices of regular or "direct" saving time values - * at transitions - */ - private List dstOffsets; - - /** - * Zone records of this time zone - */ - private List usedZoneRecs; - - /** - * Rule records referred to by this time zone - */ - private List usedRuleRecs; - - /** - * Type of DST rules in this time zone - */ - private int dstType; - static final int UNDEF_DST = 0; // DST type not set yet - static final int NO_DST = 1; // never observed DST - static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only) - static final int X_DST = 3; // used to observe DST - static final int DST = 4; // observing DST regularly - - /** - * Raw GMT offset of this time zone in the last rule - */ - private int rawOffset; - - /** - * The CRC32 value of the transitions data - */ - private int crc32; - - /** - * The last ZoneRec - */ - private ZoneRec lastZoneRec; - - /** - * The last DST rules. lastRules[0] is the DST start - * rule. lastRules[1] is the DST end rules. - */ - private List lastRules; - - /** - * The amount of DST saving value (millisecond) in the last DST - * rule. - */ - private int lastSaving; - - /** - * true if the raw offset will change in the future time. - */ - private boolean willRawOffsetChange = false; - - - /** - * Constracts a Timezone object with the given zone name. - * @param name the zone name - */ - Timezone(String name) { - this.name = name; - } - - /** - * @return the number of transitions - */ - int getNTransitions() { - if (transitions == null) { - return 0; - } - return transitions.size(); - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Returns the list of all rule records that have been referred to - * by this time zone. - * @return the rule records list - */ - List getRules() { - return usedRuleRecs; - } - - /** - * Returns the list of all zone records that have been referred to - * by this time zone. - * @return the zone records list - */ - List getZones() { - return usedZoneRecs; - } - - /** - * @return the transition table (list) - */ - List getTransitions() { - return transitions; - } - - /** - * @return the offsets list - */ - List getOffsets() { - return offsets; - } - - /** - * @return the DST saving offsets list - */ - List getDstOffsets() { - return dstOffsets; - } - - /** - * @return the GMT offsets list - */ - List getGmtOffsets() { - return gmtOffsets; - } - - /** - * @return the checksum (crc32) value of the trasition table - */ - int getCRC32() { - return crc32; - } - - /** - * @return true if the GMT offset of this time zone would change - * after the time zone database has been generated, false, otherwise. - */ - boolean willGMTOffsetChange() { - return willRawOffsetChange; - } - - /** - * @return the last known GMT offset value in milliseconds - */ - int getRawOffset() { - return rawOffset; - } - - /** - * Sets time zone's GMT offset to offset. - * @param offset the GMT offset value in milliseconds - */ - void setRawOffset(int offset) { - rawOffset = offset; - } - - /** - * Sets time zone's GMT offset value to offset. If - * startTime is future time, then the {@link - * #willRawOffsetChange} value is set to true. - * @param offset the GMT offset value in milliseconds - * @param startTime the UTC time at which the GMT offset is in effective - */ - void setRawOffset(int offset, long startTime) { - // if this rawOffset is for the future time, let the run-time - // look for the current GMT offset. - if (startTime > Time.getCurrentTime()) { - willRawOffsetChange = true; - } - setRawOffset(offset); - } - - /** - * Adds the specified transition information to the end of the transition table. - * @param time the UTC time at which this transition happens - * @param offset the total amount of the offset from GMT in milliseconds - * @param dstOffset the amount of time in milliseconds saved at this transition - */ - void addTransition(long time, int offset, int dstOffset) { - if (transitions == null) { - transitions = new ArrayList(); - offsets = new ArrayList(); - dstOffsets = new ArrayList(); - } - transitions.add(time); - offsets.add(offset); - dstOffsets.add(dstOffset); - } - - /** - * Sets the type of historical daylight saving time - * observation. For example, China used to observed daylight - * saving time, but it no longer does. Then, X_DST is set to the - * China time zone. - * @param type the type of daylight saving time - */ - void setDSTType(int type) { - dstType = type; - } - - /** - * @return the type of historical daylight saving time - * observation. - */ - int getDSTType() { - return dstType; - } - - /** - * Adds the specified zone record to the zone records list. - * @param rec the zone record - */ - void addUsedRec(ZoneRec rec) { - if (usedZoneRecs == null) { - usedZoneRecs = new ArrayList(); - } - usedZoneRecs.add(rec); - } - - /** - * Adds the specified rule record to the rule records list. - * @param rec the rule record - */ - void addUsedRec(RuleRec rec) { - if (usedRuleRecs == null) { - usedRuleRecs = new ArrayList(); - } - // if the last used rec is the same as the given rec, avoid - // putting the same rule. - int n = usedRuleRecs.size(); - for (int i = 0; i < n; i++) { - if (usedRuleRecs.get(i).equals(rec)) { - return; - } - } - usedRuleRecs.add(rec); - } - - /** - * Sets the last zone record for this time zone. - * @param the last zone record - */ - void setLastZoneRec(ZoneRec zrec) { - lastZoneRec = zrec; - } - - /** - * @return the last zone record for this time zone. - */ - ZoneRec getLastZoneRec() { - return lastZoneRec; - } - - /** - * Sets the last rule records for this time zone. Those are used - * for generating SimpleTimeZone parameters. - * @param rules the last rule records - */ - void setLastRules(List rules) { - int n = rules.size(); - if (n > 0) { - lastRules = rules; - RuleRec rec = rules.get(0); - int offset = rec.getSave(); - if (offset > 0) { - setLastDSTSaving(offset); - } else { - System.err.println("\t No DST starting rule in the last rules."); - } - } - } - - /** - * @return the last rule records for this time zone. - */ - List getLastRules() { - return lastRules; - } - - /** - * Sets the last daylight saving amount. - * @param the daylight saving amount - */ - void setLastDSTSaving(int offset) { - lastSaving = offset; - } - - /** - * @return the last daylight saving amount. - */ - int getLastDSTSaving() { - return lastSaving; - } - - /** - * Calculates the CRC32 value from the transition table and sets - * the value to crc32. - */ - void checksum() { - if (transitions == null) { - crc32 = 0; - return; - } - Checksum sum = new Checksum(); - for (int i = 0; i < transitions.size(); i++) { - int offset = offsets.get(i); - // adjust back to make the transition in local time - sum.update(transitions.get(i) + offset); - sum.update(offset); - sum.update(dstOffsets.get(i)); - } - crc32 = (int)sum.getValue(); - } - - /** - * Removes unnecessary transitions for Java time zone support. - */ - void optimize() { - // if there is only one offset, delete all transitions. This - // could happen if only time zone abbreviations changed. - if (gmtOffsets.size() == 1) { - transitions = null; - usedRuleRecs = null; - setDSTType(NO_DST); - return; - } - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (transitions.get(i) == transitions.get(i+1)) { - transitions.remove(i); - offsets.remove(i); - dstOffsets.remove(i); - i--; - } - } - - for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one - if (offsets.get(i) == offsets.get(i+1) - && dstOffsets.get(i) == dstOffsets.get(i+1)) { - transitions.remove(i+1); - offsets.remove(i+1); - dstOffsets.remove(i+1); - i--; - } - } - } - - /** - * Stores the specified offset value from GMT in the GMT offsets - * table and returns its index. The offset value includes the base - * GMT offset and any additional daylight saving if applicable. If - * the same value as the specified offset is already in the table, - * its index is returned. - * @param offset the offset value in milliseconds - * @return the index to the offset value in the GMT offsets table. - */ - int getOffsetIndex(int offset) { - return getOffsetIndex(offset, 0); - } - - /** - * Stores the specified daylight saving value in the GMT offsets - * table and returns its index. If the same value as the specified - * offset is already in the table, its index is returned. If 0 is - * specified, it's not stored in the table and -1 is returned. - * @param offset the offset value in milliseconds - * @return the index to the specified offset value in the GMT - * offsets table, or -1 if 0 is specified. - */ - int getDstOffsetIndex(int offset) { - if (offset == 0) { - return -1; - } - return getOffsetIndex(offset, 1); - } - - private int getOffsetIndex(int offset, int index) { - if (gmtOffsets == null) { - gmtOffsets = new ArrayList(); - } - for (int i = index; i < gmtOffsets.size(); i++) { - if (offset == gmtOffsets.get(i)) { - return i; - } - } - if (gmtOffsets.size() < index) { - gmtOffsets.add(0); - } - gmtOffsets.add(offset); - return gmtOffsets.size() - 1; - } -} diff --git a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java b/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java deleted file mode 100644 index 7e8ce63644991..0000000000000 --- a/test/jdk/sun/util/calendar/zi/TzIDOldMapping.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.Map; -import java.util.HashMap; - -class TzIDOldMapping { - static final Map MAP = new HashMap(); - static { - String[][] oldmap = { - { "ACT", "Australia/Darwin" }, - { "AET", "Australia/Sydney" }, - { "AGT", "America/Argentina/Buenos_Aires" }, - { "ART", "Africa/Cairo" }, - { "AST", "America/Anchorage" }, - { "BET", "America/Sao_Paulo" }, - { "BST", "Asia/Dhaka" }, - { "CAT", "Africa/Harare" }, - { "CNT", "America/St_Johns" }, - { "CST", "America/Chicago" }, - { "CTT", "Asia/Shanghai" }, - { "EAT", "Africa/Addis_Ababa" }, - { "ECT", "Europe/Paris" }, - { "EST", "America/New_York" }, - { "HST", "Pacific/Honolulu" }, - { "IET", "America/Indianapolis" }, - { "IST", "Asia/Calcutta" }, - { "JST", "Asia/Tokyo" }, - { "MIT", "Pacific/Apia" }, - { "MST", "America/Denver" }, - { "NET", "Asia/Yerevan" }, - { "NST", "Pacific/Auckland" }, - { "PLT", "Asia/Karachi" }, - { "PNT", "America/Phoenix" }, - { "PRT", "America/Puerto_Rico" }, - { "PST", "America/Los_Angeles" }, - { "SST", "Pacific/Guadalcanal" }, - { "VST", "Asia/Saigon" }, - }; - for (String[] pair : oldmap) { - MAP.put(pair[0], pair[1]); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zone.java b/test/jdk/sun/util/calendar/zi/Zone.java deleted file mode 100644 index f1adbf6f938dd..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Zone.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * Zone holds information corresponding to a "Zone" part of a time - * zone definition file. - * - * @since 1.4 - */ -class Zone { - // zone name (e.g., "America/Los_Angeles") - private String name; - - // zone records - private List list; - - // target zone names for this compilation - private static Set targetZones; - - /** - * Constructs a Zone with the specified zone name. - * @param name the zone name - */ - Zone(String name) { - this.name = name; - list = new ArrayList(); - } - - /** - * Reads time zone names to be generated, called "target zone - * name", from the specified text file and creats an internal hash - * table to keep those names. It's assumed that one text line - * contains a zone name or comments if it starts with - * '#'. Comments can't follow a zone name in a single line. - * @param fileName the text file name - */ - static void readZoneNames(String fileName) { - if (fileName == null) { - return; - } - BufferedReader in = null; - try { - FileReader fr = new FileReader(fileName); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - Main.panic("can't open file: " + fileName); - } - targetZones = new HashSet(); - String line; - - try { - while ((line = in.readLine()) != null) { - line = line.trim(); - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - if (!targetZones.add(line)) { - Main.warning("duplicated target zone name: " + line); - } - } - in.close(); - } catch (IOException e) { - Main.panic("IO error: "+e.getMessage()); - } - } - - /** - * Determines whether the specified zone is one of the target zones. - * If no target zones are specified, this method always returns - * true for any zone name. - * @param zoneName the zone name - * @return true if the specified name is a target zone. - */ - static boolean isTargetZone(String zoneName) { - if (targetZones == null) { - return true; - } - return targetZones.contains(zoneName); - } - - /** - * Forces to add "MET" to the target zone table. This is because - * there is a conflict between Java zone name "WET" and Olson zone - * name. - */ - static void addMET() { - if (targetZones != null) { - targetZones.add("MET"); - } - } - - /** - * @return the zone name - */ - String getName() { - return name; - } - - /** - * Adds the specified zone record to the zone record list. - */ - void add(ZoneRec rec) { - list.add(rec); - } - - /** - * @param index the index at which the zone record in the list is returned. - * @return the zone record specified by the index. - */ - ZoneRec get(int index) { - return list.get(index); - } - - /** - * @return the size of the zone record list - */ - int size() { - return list.size(); - } - - /** - * Resolves the reference to a rule in each zone record. - * @param zi the Zoneinfo object with which the rule reference is - * resolved. - */ - void resolve(Zoneinfo zi) { - for (int i = 0; i < list.size(); i++) { - ZoneRec rec = list.get(i); - rec.resolve(zi); - } - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java b/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java deleted file mode 100644 index 3134a517979bc..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoFile.java +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.ref.SoftReference; -import java.nio.file.FileSystems; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import sun.util.calendar.*; - -/** - * ZoneInfoFile reads Zone information files in the - * <java.home>/lib/zi directory and provides time zone - * information in the form of a {@link ZoneInfo} object. Also, it - * reads the ZoneInfoMappings file to obtain time zone IDs information - * that is used by the {@link ZoneInfo} class. The directory layout - * and data file formats are as follows. - * - *

    Directory layout

    - * - * All zone data files and ZoneInfoMappings are put under the - * <java.home>/lib/zi directory. A path name for a given time - * zone ID is a concatenation of <java.home>/lib/zi/ and the - * time zone ID. (The file separator is replaced with the platform - * dependent value. e.g., '\' for Win32.) An example layout will look - * like as follows. - *

    - *
    - * <java.home>/lib/zi/Africa/Addis_Ababa
    - *                   /Africa/Dakar
    - *                   /America/Los_Angeles
    - *                   /Asia/Singapore
    - *                   /EET
    - *                   /Europe/Oslo
    - *                   /GMT
    - *                   /Pacific/Galapagos
    - *                       ...
    - *                   /ZoneInfoMappings
    - * 
    - *
    - * - * A zone data file has specific information of each zone. - * ZoneInfoMappings has global information of zone IDs so - * that the information can be obtained without instantiating all time - * zones. - * - *

    File format

    - * - * Two binary-file formats based on a simple Tag-Length-Value format are used - * to describe TimeZone information. The generic format of a data file is: - *

    - *
    - *    DataFile {
    - *      u1              magic[7];
    - *      u1              version;
    - *      data_item       data[];
    - *    }
    - * 
    - *
    - * where magic is a magic number identifying a file - * format, version is the format version number, and - * data is one or more data_items. The - * data_item structure is: - *
    - *
    - *    data_item {
    - *      u1              tag;
    - *      u2              length;
    - *      u1              value[length];
    - *    }
    - * 
    - *
    - * where tag indicates the data type of the item, - * length is a byte count of the following - * value that is the content of item data. - *

    - * All data is stored in the big-endian order. There is no boundary - * alignment between date items. - * - *

    1. ZoneInfo data file

    - * - * Each ZoneInfo data file consists of the following members. - *
    - *

    - *
    - *    ZoneInfoDataFile {
    - *      u1              magic[7];
    - *      u1              version;
    - *      SET OF1 {
    - *        transition            transitions2;
    - *        offset_table          offsets2;
    - *        simpletimezone        stzparams2;
    - *        raw_offset            rawoffset;
    - *        dstsaving             dst;
    - *        checksum              crc32;
    - *        gmtoffsetwillchange   gmtflag2;
    - *      }
    - *   }
    - *   1: an unordered collection of zero or one occurrences of each item
    - *   2: optional item
    - * 
    - *
    - * magic is a byte-string constant identifying the - * ZoneInfo data file. This field must be "javazi\0" - * defined as {@link #JAVAZI_LABEL}. - *

    - * version is the version number of the file format. This - * will be used for compatibility check. This field must be - * 0x01 in this version. - *

    - * transition, offset_table and - * simpletimezone have information of time transition - * from the past to the future. Therefore, these structures don't - * exist if the zone didn't change zone names and haven't applied DST in - * the past, and haven't planned to apply it. (e.g. Asia/Tokyo zone) - *

    - * raw_offset, dstsaving and checksum - * exist in every zoneinfo file. They are used by TimeZone.class indirectly. - * - *

    1.1 transition structure

    - *

    - *
    - *    transition {
    - *      u1      tag;              // 0x04 : constant
    - *      u2      length;           // byte length of whole values
    - *      s8      value[length/8];  // transitions in `long'
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#transitions ZoneInfo.transitions} about the value. - * - *

    1.2 offset_table structure

    - *

    - *
    - *    offset_table {
    - *      u1      tag;              // 0x05 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // offset values in `int'
    - *    }
    - * 
    - *
    - * - *

    1.3 simpletimezone structure

    - * See {@link ZoneInfo#simpleTimeZoneParams ZoneInfo.simpleTimeZoneParams} - * about the value. - *

    - *
    - *    simpletimezone {
    - *      u1      tag;              // 0x06 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // SimpleTimeZone parameters
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#offsets ZoneInfo.offsets} about the value. - * - *

    1.4 raw_offset structure

    - *

    - *
    - *    raw_offset {
    - *      u1      tag;              // 0x01 : constant
    - *      u2      length;           // must be 4.
    - *      s4      value;            // raw GMT offset [millisecond]
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#rawOffset ZoneInfo.rawOffset} about the value. - * - *

    1.5 dstsaving structure

    - * Value has dstSaving in seconds. - *

    - *
    - *    dstsaving {
    - *      u1      tag;              // 0x02 : constant
    - *      u2      length;           // must be 2.
    - *      s2      value;            // DST save value [second]
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#dstSavings ZoneInfo.dstSavings} about value. - * - *

    1.6 checksum structure

    - *

    - *
    - *    checksum {
    - *      u1      tag;              // 0x03 : constant
    - *      u2      length;           // must be 4.
    - *      s4      value;            // CRC32 value of transitions
    - *    }
    - * 
    - *
    - * See {@link ZoneInfo#checksum ZoneInfo.checksum}. - * - *

    1.7 gmtoffsetwillchange structure

    - * This record has a flag value for {@link ZoneInfo#rawOffsetWillChange}. - * If this record is not present in a zoneinfo file, 0 is assumed for - * the value. - *

    - *
    - *    gmtoffsetwillchange {
    - *      u1      tag;             // 0x07 : constant
    - *      u2      length;          // must be 1.
    - *      u1      value;           // 1: if the GMT raw offset will change
    - *                               // in the future, 0, otherwise.
    - *     }
    - * 
    - *
    - * - * - *

    2. ZoneInfoMappings file

    - * - * The ZoneInfoMappings file consists of the following members. - *
    - *

    - *
    - *    ZoneInfoMappings {
    - *      u1      magic[7];
    - *      u1      version;
    - *      SET OF {
    - *        versionName                   version;
    - *        zone_id_table                 zoneIDs;
    - *        raw_offset_table              rawoffsets;
    - *        raw_offset_index_table        rawoffsetindices;
    - *        alias_table                   aliases;
    - *        excluded_list                 excludedList;
    - *      }
    - *   }
    - * 
    - *
    - * - * magic is a byte-string constant which has the file type. - * This field must be "javazm\0" defined as {@link #JAVAZM_LABEL}. - *

    - * version is the version number of this file - * format. This will be used for compatibility check. This field must - * be 0x01 in this version. - *

    - * versionName shows which version of Olson's data has been used - * to generate this ZoneInfoMappings. (e.g. tzdata2000g)
    - * This field is for trouble-shooting and isn't usually used in runtime. - *

    - * zone_id_table, raw_offset_index_table and - * alias_table are general information of supported - * zones. - * - *

    2.1 zone_id_table structure

    - * The list of zone IDs included in the zi database. The list does - * not include zone IDs, if any, listed in excludedList. - *
    - *

    - *
    - *    zone_id_table {
    - *      u1      tag;              // 0x40 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      zone_id_count;
    - *      zone_id value[zone_id_count];
    - *    }
    - *
    - *    zone_id {
    - *      u1      byte_length;      // byte length of id
    - *      u1      id[byte_length];  // zone name string
    - *    }
    - * 
    - *
    - * - *

    2.2 raw_offset_table structure

    - *
    - *

    - *
    - *    raw_offset_table {
    - *      u1      tag;              // 0x41 : constant
    - *      u2      length;           // byte length of whole values
    - *      s4      value[length/4];  // raw GMT offset in milliseconds
    - *   }
    - * 
    - *
    - * - *

    2.3 raw_offset_index_table structure

    - *
    - *

    - *
    - *    raw_offset_index_table {
    - *      u1      tag;              // 0x42 : constant
    - *      u2      length;           // byte length of whole values
    - *      u1      value[length];
    - *    }
    - * 
    - *
    - * - *

    2.4 alias_table structure

    - *
    - *

    - *
    - *   alias_table {
    - *      u1      tag;              // 0x43 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      nentries;         // number of id-pairs
    - *      id_pair value[nentries];
    - *   }
    - *
    - *   id_pair {
    - *      zone_id aliasname;
    - *      zone_id ID;
    - *   }
    - * 
    - *
    - * - *

    2.5 versionName structure

    - *
    - *

    - *
    - *   versionName {
    - *      u1      tag;              // 0x44 : constant
    - *      u2      length;           // byte length of whole values
    - *      u1      value[length];
    - *   }
    - * 
    - *
    - * - *

    2.6 excludeList structure

    - * The list of zone IDs whose zones will change their GMT offsets - * (a.k.a. raw offsets) some time in the future. Those IDs must be - * added to the list of zone IDs for getAvailableIDs(). Also they must - * be examined for getAvailableIDs(int) to determine the - * current GMT offsets. - *
    - *

    - *
    - *   excluded_list {
    - *      u1      tag;              // 0x45 : constant
    - *      u2      length;           // byte length of whole values
    - *      u2      nentries;         // number of zone_ids
    - *      zone_id value[nentries];  // excluded zone IDs
    - *   }
    - * 
    - *
    - * - * @since 1.4 - */ - -public class ZoneInfoFile { - - /** - * The magic number for the ZoneInfo data file format. - */ - public static final byte[] JAVAZI_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'i', (byte)'\0' - }; - private static final int JAVAZI_LABEL_LENGTH = JAVAZI_LABEL.length; - - /** - * The ZoneInfo data file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZI_VERSION = 0x01; - - /** - * Raw offset data item tag. - */ - public static final byte TAG_RawOffset = 1; - - /** - * Known last Daylight Saving Time save value data item tag. - */ - public static final byte TAG_LastDSTSaving = 2; - - /** - * Checksum data item tag. - */ - public static final byte TAG_CRC32 = 3; - - /** - * Transition data item tag. - */ - public static final byte TAG_Transition = 4; - - /** - * Offset table data item tag. - */ - public static final byte TAG_Offset = 5; - - /** - * SimpleTimeZone parameters data item tag. - */ - public static final byte TAG_SimpleTimeZone = 6; - - /** - * Raw GMT offset will change in the future. - */ - public static final byte TAG_GMTOffsetWillChange = 7; - - - /** - * The ZoneInfoMappings file name. - */ - public static final String JAVAZM_FILE_NAME = "ZoneInfoMappings"; - - /** - * The magic number for the ZoneInfoMappings file format. - */ - public static final byte[] JAVAZM_LABEL = { - (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'z', (byte)'m', (byte)'\0' - }; - private static final int JAVAZM_LABEL_LENGTH = JAVAZM_LABEL.length; - - /** - * The ZoneInfoMappings file format version number. Must increase - * one when any incompatible change has been made. - */ - public static final byte JAVAZM_VERSION = 0x01; - - /** - * Time zone IDs data item tag. - */ - public static final byte TAG_ZoneIDs = 64; - - /** - * Raw GMT offsets table data item tag. - */ - public static final byte TAG_RawOffsets = 65; - - /** - * Indices to the raw GMT offset table data item tag. - */ - public static final byte TAG_RawOffsetIndices = 66; - - /** - * Time zone aliases table data item tag. - */ - public static final byte TAG_ZoneAliases = 67; - - /** - * Olson's public zone information version tag. - */ - public static final byte TAG_TZDataVersion = 68; - - /** - * Excluded zones item tag. (Added in Mustang) - */ - public static final byte TAG_ExcludedZones = 69; - - private static Map zoneInfoObjects = null; - - private static final ZoneInfoOld GMT = new ZoneInfoOld("GMT", 0); - - static String ziDir; - - /** - * Converts the given time zone ID to a platform dependent path - * name. For example, "America/Los_Angeles" is converted to - * "America\Los_Angeles" on Win32. - * @return a modified ID replacing '/' with {@link - * java.io.File#separatorChar File.separatorChar} if needed. - */ - public static String getFileName(String ID) { - if (File.separatorChar == '/') { - return ID; - } - return ID.replace('/', File.separatorChar); - } - - /** - * Gets a ZoneInfo with the given GMT offset. The object - * has its ID in the format of GMT{+|-}hh:mm. - * - * @param originalId the given custom id (before normalized such as "GMT+9") - * @param gmtOffset GMT offset in milliseconds - * @return a ZoneInfo constructed with the given GMT offset - */ - public static ZoneInfoOld getCustomTimeZone(String originalId, int gmtOffset) { - String id = toCustomID(gmtOffset); - - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - zi = new ZoneInfoOld(id, gmtOffset); - zi = addToCache(id, zi); - if (!id.equals(originalId)) { - zi = addToCache(originalId, zi); - } - } - return (ZoneInfoOld) zi.clone(); - } - - public static String toCustomID(int gmtOffset) { - char sign; - int offset = gmtOffset / 60000; - - if (offset >= 0) { - sign = '+'; - } else { - sign = '-'; - offset = -offset; - } - int hh = offset / 60; - int mm = offset % 60; - - char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' }; - if (hh >= 10) { - buf[4] += hh / 10; - } - buf[5] += hh % 10; - if (mm != 0) { - buf[7] += mm / 10; - buf[8] += mm % 10; - } - return new String(buf); - } - - /** - * @return a ZoneInfo instance created for the specified id, or - * null if there is no time zone data file found for the specified - * id. - */ - public static ZoneInfoOld getZoneInfoOld(String id) { - //treat GMT zone as special - if ("GMT".equals(id)) - return (ZoneInfoOld) GMT.clone(); - ZoneInfoOld zi = getFromCache(id); - if (zi == null) { - Map aliases = ZoneInfoOld.getCachedAliasTable(); - if (aliases != null && aliases.get(id) != null) { - return null; - } - zi = createZoneInfoOld(id); - if (zi == null) { - return null; - } - zi = addToCache(id, zi); - } - return (ZoneInfoOld) zi.clone(); - } - - synchronized static ZoneInfoOld getFromCache(String id) { - if (zoneInfoObjects == null) { - return null; - } - return zoneInfoObjects.get(id); - } - - synchronized static ZoneInfoOld addToCache(String id, ZoneInfoOld zi) { - if (zoneInfoObjects == null) { - zoneInfoObjects = new HashMap<>(); - } else { - ZoneInfoOld zone = zoneInfoObjects.get(id); - if (zone != null) { - return zone; - } - } - zoneInfoObjects.put(id, zi); - return zi; - } - - private static ZoneInfoOld createZoneInfoOld(String id) { - byte[] buf = readZoneInfoFile(getFileName(id)); - if (buf == null) { - return null; - } - - int index = 0; - int filesize = buf.length; - int rawOffset = 0; - int dstSavings = 0; - int checksum = 0; - boolean willGMTOffsetChange = false; - long[] transitions = null; - int[] offsets = null; - int[] simpleTimeZoneParams = null; - - try { - for (index = 0; index < JAVAZI_LABEL.length; index++) { - if (buf[index] != JAVAZI_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + id); - return null; - } - } - if (buf[index++] > JAVAZI_VERSION) { - System.err.println("ZoneInfo: incompatible version (" - + buf[index - 1] + "): " + id); - return null; - } - - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - if (filesize < index+len) { - break; - } - - switch (tag) { - case TAG_CRC32: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - checksum = val; - } - break; - - case TAG_LastDSTSaving: - { - short val = (short)(buf[index++] & 0xff); - val = (short)((val << 8) + (buf[index++] & 0xff)); - dstSavings = val * 1000; - } - break; - - case TAG_RawOffset: - { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - rawOffset = val; - } - break; - - case TAG_Transition: - { - int n = len / 8; - transitions = new long[n]; - for (int i = 0; i < n; i ++) { - long val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - transitions[i] = val; - } - } - break; - - case TAG_Offset: - { - int n = len / 4; - offsets = new int[n]; - for (int i = 0; i < n; i ++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break; - - case TAG_SimpleTimeZone: - { - if (len != 32 && len != 40) { - System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size"); - return null; - } - int n = len / 4; - simpleTimeZoneParams = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - simpleTimeZoneParams[i] = val; - } - } - break; - - case TAG_GMTOffsetWillChange: - { - if (len != 1) { - System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange"); - } - willGMTOffsetChange = buf[index++] == 1; - } - break; - - default: - System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored."); - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfo: corrupted zoneinfo file: " + id); - return null; - } - - if (index != filesize) { - System.err.println("ZoneInfo: wrong file size: " + id); - return null; - } - - return new ZoneInfoOld(id, rawOffset, dstSavings, checksum, - transitions, offsets, simpleTimeZoneParams, - willGMTOffsetChange); - } - - private volatile static SoftReference> zoneIDs = null; - - static List getZoneIDs() { - List ids = null; - SoftReference> cache = zoneIDs; - if (cache != null) { - ids = cache.get(); - if (ids != null) { - return ids; - } - } - byte[] buf = null; - buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneIDs: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - ids = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - ids.add(new String(buf, index, m, "UTF-8")); - index += m; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - zoneIDs = new SoftReference<>(ids); - return ids; - } - - /** - * @return an alias table in HashMap where a key is an alias ID - * (e.g., "PST") and its value is a real time zone ID (e.g., - * "America/Los_Angeles"). - */ - static Map getZoneAliases() { - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - Map aliases = null; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ZoneAliases: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - aliases = new HashMap<>(n); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - m = buf[index++]; - String realName = new String(buf, index, m, "UTF-8"); - index += m; - aliases.put(name, realName); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - return aliases; - } - - private volatile static SoftReference> excludedIDs = null; - private volatile static boolean hasNoExcludeList = false; - - /** - * @return a List of zone IDs for zones that will change their GMT - * offsets in some future time. - * - * @since 1.6 - */ - static List getExcludedZones() { - if (hasNoExcludeList) { - return null; - } - - List excludeList = null; - - SoftReference> cache = excludedIDs; - if (cache != null) { - excludeList = cache.get(); - if (excludeList != null) { - return excludeList; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_ExcludedZones: - { - int n = (buf[index++] << 8) + (buf[index++] & 0xFF); - excludeList = new ArrayList<>(); - for (int i = 0; i < n; i++) { - byte m = buf[index++]; - String name = new String(buf, index, m, "UTF-8"); - index += m; - excludeList.add(name); - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (Exception e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - return null; - } - - if (excludeList != null) { - excludedIDs = new SoftReference<>(excludeList); - } else { - hasNoExcludeList = true; - } - return excludeList; - } - - private volatile static SoftReference rawOffsetIndices = null; - - static byte[] getRawOffsetIndices() { - byte[] indices = null; - - SoftReference cache = rawOffsetIndices; - if (cache != null) { - indices = cache.get(); - if (indices != null) { - return indices; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsetIndices: - { - indices = new byte[len]; - for (int i = 0; i < len; i++) { - indices[i] = buf[index++]; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsetIndices = new SoftReference<>(indices); - return indices; - } - - private volatile static SoftReference rawOffsets = null; - - static int[] getRawOffsets() { - int[] offsets = null; - - SoftReference cache = rawOffsets; - if (cache != null) { - offsets = cache.get(); - if (offsets != null) { - return offsets; - } - } - - byte[] buf = getZoneInfoOldMappings(); - int index = JAVAZM_LABEL_LENGTH + 1; - int filesize = buf.length; - - try { - loop: - while (index < filesize) { - byte tag = buf[index++]; - int len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF); - - switch (tag) { - case TAG_RawOffsets: - { - int n = len/4; - offsets = new int[n]; - for (int i = 0; i < n; i++) { - int val = buf[index++] & 0xff; - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - val = (val << 8) + (buf[index++] & 0xff); - offsets[i] = val; - } - } - break loop; - - default: - index += len; - break; - } - } - } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("ZoneInfoOld: corrupted " + JAVAZM_FILE_NAME); - } - - rawOffsets = new SoftReference<>(offsets); - return offsets; - } - - private volatile static SoftReference zoneInfoMappings = null; - - private static byte[] getZoneInfoOldMappings() { - byte[] data; - SoftReference cache = zoneInfoMappings; - if (cache != null) { - data = cache.get(); - if (data != null) { - return data; - } - } - data = readZoneInfoFile(JAVAZM_FILE_NAME); - if (data == null) { - throw new RuntimeException("ZoneInfoOldMapping " + - JAVAZM_FILE_NAME + " either doesn't exist or doesn't have data"); - } - - int index; - for (index = 0; index < JAVAZM_LABEL.length; index++) { - if (data[index] != JAVAZM_LABEL[index]) { - System.err.println("ZoneInfoOld: wrong magic number: " + JAVAZM_FILE_NAME); - return null; - } - } - if (data[index++] > JAVAZM_VERSION) { - System.err.println("ZoneInfoOld: incompatible version (" - + data[index - 1] + "): " + JAVAZM_FILE_NAME); - return null; - } - - zoneInfoMappings = new SoftReference<>(data); - return data; - } - - /** - * Reads the specified file under <java.home>/lib/zi into a buffer. - * @return the buffer, or null if any I/O error occurred. - */ - private static byte[] readZoneInfoFile(final String fileName) { - if (fileName.indexOf("..") >= 0) { - return null; - } - byte[] buffer = null; - File file = new File(ziDir, fileName); - try { - int filesize = (int)file.length(); - if (filesize > 0) { - FileInputStream fis = new FileInputStream(file); - buffer = new byte[filesize]; - try { - if (fis.read(buffer) != filesize) { - throw new IOException("read error on " + fileName); - } - } finally { - fis.close(); - } - } - } catch (Exception ex) { - if (!(ex instanceof FileNotFoundException) || JAVAZM_FILE_NAME.equals(fileName)) { - System.err.println("ZoneInfoOld: " + ex.getMessage()); - } - } - return buffer; - } - - private ZoneInfoFile() { - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java b/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java deleted file mode 100644 index 300b7f13dddd7..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneInfoOld.java +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.lang.ref.SoftReference; -import java.time.ZoneOffset; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.SimpleTimeZone; -import java.util.TimeZone; - -import sun.util.calendar.CalendarSystem; -import sun.util.calendar.CalendarDate; - -/** - * ZoneInfoOld is an implementation subclass of {@link - * java.util.TimeZone TimeZone} that represents GMT offsets and - * daylight saving time transitions of a time zone. - *

    - * The daylight saving time transitions are described in the {@link - * #transitions transitions} table consisting of a chronological - * sequence of transitions of GMT offset and/or daylight saving time - * changes. Since all transitions are represented in UTC, in theory, - * ZoneInfoOld can be used with any calendar systems except - * for the {@link #getOffset(int,int,int,int,int,int) getOffset} - * method that takes Gregorian calendar date fields. - *

    - * This table covers transitions from 1900 until 2100 (as of version - * 23), Before 1900, it assumes that there was no daylight saving - * time and the getOffset methods always return the - * {@link #getRawOffset} value. No Local Mean Time is supported. If a - * specified date is beyond the transition table and this time zone is - * supposed to observe daylight saving time in 2100, it delegates - * operations to a {@link java.util.SimpleTimeZone SimpleTimeZone} - * object created using the daylight saving time schedule as of 2100. - *

    - * The date items, transitions, GMT offset(s), etc. are read from a database - * file. See {@link ZoneInfoFile} for details. - * @see java.util.SimpleTimeZone - * @since 1.4 - */ - -public class ZoneInfoOld extends TimeZone { - - // The constants assume no leap seconds support. - static final int SECOND_IN_MILLIS = 1000; - static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; - static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60; - static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24; - - private static final int UTC_TIME = 0; - private static final int STANDARD_TIME = 1; - private static final int WALL_TIME = 2; - - private static final long OFFSET_MASK = 0x0fL; - private static final long DST_MASK = 0xf0L; - private static final int DST_NSHIFT = 4; - // this bit field is reserved for abbreviation support - private static final long ABBR_MASK = 0xf00L; - private static final int TRANSITION_NSHIFT = 12; - - // IDs having conflicting data between Olson and JDK 1.1 - static final Map conflictingIDs = Map.of( - "EST", "America/Panama", - "MST", "America/Phoenix"); - - private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar(); - - /** - * The raw GMT offset in milliseconds between this zone and GMT. - * Negative offsets are to the west of Greenwich. To obtain local - * standard time, add the offset to GMT time. - * @serial - */ - int rawOffset; - - /** - * Difference in milliseconds from the original GMT offset in case - * the raw offset value has been modified by calling {@link - * #setRawOffset}. The initial value is 0. - * @serial - */ - int rawOffsetDiff = 0; - - /** - * A CRC32 value of all pairs of transition time (in milliseconds - * in long) in local time and its GMT offset (in - * seconds in int) in the chronological order. Byte - * values of each long and int are taken - * in the big endian order (i.e., MSB to LSB). - * @serial - */ - int checksum; - - /** - * The amount of time in milliseconds saved during daylight saving - * time. If useDaylight is false, this value is 0. - * @serial - */ - int dstSavings; - - /** - * This array describes transitions of GMT offsets of this time - * zone, including both raw offset changes and daylight saving - * time changes. - * A long integer consists of four bit fields. - *

      - *
    • The most significant 52-bit field represents transition - * time in milliseconds from Gregorian January 1 1970, 00:00:00 - * GMT.
    • - *
    • The next 4-bit field is reserved and must be 0.
    • - *
    • The next 4-bit field is an index value to {@link #offsets - * offsets[]} for the amount of daylight saving at the - * transition. If this value is zero, it means that no daylight - * saving, not the index value zero.
    • - *
    • The least significant 4-bit field is an index value to - * {@link #offsets offsets[]} for total GMT offset at the - * transition.
    • - *
    - * If this time zone doesn't observe daylight saving time and has - * never changed any GMT offsets in the past, this value is null. - * @serial - */ - long[] transitions; - - /** - * This array holds all unique offset values in - * milliseconds. Index values to this array are stored in the - * transitions array elements. - * @serial - */ - int[] offsets; - - /** - * SimpleTimeZone parameter values. It has to have either 8 for - * {@link java.util.SimpleTimeZone#SimpleTimeZone(int, String, - * int, int , int , int , int , int , int , int , int) the - * 11-argument SimpleTimeZone constructor} or 10 for {@link - * java.util.SimpleTimeZone#SimpleTimeZone(int, String, int, int, - * int , int , int , int , int , int , int, int, int) the - * 13-argument SimpleTimeZone constructor} parameters. - * @serial - */ - int[] simpleTimeZoneParams; - - /** - * True if the raw GMT offset value would change after the time - * zone data has been generated; false, otherwise. The default - * value is false. - * @serial - */ - boolean willGMTOffsetChange = false; - - /** - * True if the object has been modified after its instantiation. - */ - transient private boolean dirty = false; - - private static final long serialVersionUID = 2653134537216586139L; - - /** - * A constructor. - */ - public ZoneInfoOld() { - } - - /** - * A Constructor for CustomID. - */ - public ZoneInfoOld(String ID, int rawOffset) { - this(ID, rawOffset, 0, 0, null, null, null, false); - } - - /** - * Constructs a ZoneInfoOld instance. - * - * @param ID time zone name - * @param rawOffset GMT offset in milliseconds - * @param dstSavings daylight saving value in milliseconds or 0 - * (zero) if this time zone doesn't observe Daylight Saving Time. - * @param checksum CRC32 value with all transitions table entry - * values - * @param transitions transition table - * @param offsets offset value table - * @param simpleTimeZoneParams parameter values for constructing - * SimpleTimeZone - * @param willGMTOffsetChange the value of willGMTOffsetChange - */ - ZoneInfoOld(String ID, - int rawOffset, - int dstSavings, - int checksum, - long[] transitions, - int[] offsets, - int[] simpleTimeZoneParams, - boolean willGMTOffsetChange) { - setID(ID); - this.rawOffset = rawOffset; - this.dstSavings = dstSavings; - this.checksum = checksum; - this.transitions = transitions; - this.offsets = offsets; - this.simpleTimeZoneParams = simpleTimeZoneParams; - this.willGMTOffsetChange = willGMTOffsetChange; - } - - /** - * Returns the difference in milliseconds between local time and UTC - * of given time, taking into account both the raw offset and the - * effect of daylight savings. - * - * @param date the milliseconds in UTC - * @return the milliseconds to add to UTC to get local wall time - */ - public int getOffset(long date) { - return getOffsets(date, null, UTC_TIME); - } - - public int getOffsets(long utc, int[] offsets) { - return getOffsets(utc, offsets, UTC_TIME); - } - - public int getOffsetsByStandard(long standard, int[] offsets) { - return getOffsets(standard, offsets, STANDARD_TIME); - } - - public int getOffsetsByWall(long wall, int[] offsets) { - return getOffsets(wall, offsets, WALL_TIME); - } - - private int getOffsets(long date, int[] offsets, int type) { - // if dst is never observed, there is no transition. - if (transitions == null) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - date -= rawOffsetDiff; - int index = getTransitionIndex(date, type); - - // prior to the transition table, returns the raw offset. - // FIXME: should support LMT. - if (index < 0) { - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - if (index < transitions.length) { - long val = transitions[index]; - int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; - if (offsets != null) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : this.offsets[dst]; - offsets[0] = offset - save; - offsets[1] = save; - } - return offset; - } - - // beyond the transitions, delegate to SimpleTimeZone if there - // is a rule; otherwise, return rawOffset. - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - int rawoffset = tz.getRawOffset(); - long msec = date; - if (type != UTC_TIME) { - msec -= rawOffset; - } - int dstoffset = tz.getOffset(msec) - rawOffset; - - // Check if it's in a standard-to-daylight transition. - if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) { - dstoffset = 0; - } - - if (offsets != null) { - offsets[0] = rawoffset; - offsets[1] = dstoffset; - } - return rawoffset + dstoffset; - } - int offset = getLastRawOffset(); - if (offsets != null) { - offsets[0] = offset; - offsets[1] = 0; - } - return offset; - } - - private int getTransitionIndex(long date, int type) { - int low = 0; - int high = transitions.length - 1; - - while (low <= high) { - int mid = (low + high) / 2; - long val = transitions[mid]; - long midVal = val >> TRANSITION_NSHIFT; // sign extended - if (type != UTC_TIME) { - midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time - } - if (type == STANDARD_TIME) { - int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL); - if (dstIndex != 0) { - midVal -= offsets[dstIndex]; // make it standard time - } - } - - if (midVal < date) { - low = mid + 1; - } else if (midVal > date) { - high = mid - 1; - } else { - return mid; - } - } - - // if beyond the transitions, returns that index. - if (low >= transitions.length) { - return low; - } - return low - 1; - } - - /** - * Returns the difference in milliseconds between local time and - * UTC, taking into account both the raw offset and the effect of - * daylight savings, for the specified date and time. This method - * assumes that the start and end month are distinct. This method - * assumes a Gregorian calendar for calculations. - *

    - * Note: In general, clients should use - * {@link Calendar#ZONE_OFFSET Calendar.get(ZONE_OFFSET)} + - * {@link Calendar#DST_OFFSET Calendar.get(DST_OFFSET)} - * instead of calling this method. - * - * @param era The era of the given date. The value must be either - * GregorianCalendar.AD or GregorianCalendar.BC. - * @param year The year in the given date. - * @param month The month in the given date. Month is 0-based. e.g., - * 0 for January. - * @param day The day-in-month of the given date. - * @param dayOfWeek The day-of-week of the given date. - * @param millis The milliseconds in day in standard local time. - * @return The milliseconds to add to UTC to get local time. - */ - public int getOffset(int era, int year, int month, int day, - int dayOfWeek, int milliseconds) { - if (milliseconds < 0 || milliseconds >= DAY_IN_MILLIS) { - throw new IllegalArgumentException(); - } - - if (era == java.util.GregorianCalendar.BC) { // BC - year = 1 - year; - } else if (era != java.util.GregorianCalendar.AD) { - throw new IllegalArgumentException(); - } - - CalendarDate date = gcal.newCalendarDate(null); - date.setDate(year, month + 1, day); - if (gcal.validate(date) == false) { - throw new IllegalArgumentException(); - } - - // bug-for-bug compatible argument checking - if (dayOfWeek < java.util.GregorianCalendar.SUNDAY - || dayOfWeek > java.util.GregorianCalendar.SATURDAY) { - throw new IllegalArgumentException(); - } - - if (transitions == null) { - return getLastRawOffset(); - } - - long dateInMillis = gcal.getTime(date) + milliseconds; - dateInMillis -= (long) rawOffset; // make it UTC - return getOffsets(dateInMillis, null, UTC_TIME); - } - - /** - * Sets the base time zone offset from GMT. This operation - * modifies all the transitions of this ZoneInfoOld object, including - * historical ones, if applicable. - * - * @param offsetMillis the base time zone offset to GMT. - * @see getRawOffset - */ - public synchronized void setRawOffset(int offsetMillis) { - if (offsetMillis == rawOffset + rawOffsetDiff) { - return; - } - rawOffsetDiff = offsetMillis - rawOffset; - if (lastRule != null) { - lastRule.setRawOffset(offsetMillis); - } - dirty = true; - } - - /** - * Returns the GMT offset of the current date. This GMT offset - * value is not modified during Daylight Saving Time. - * - * @return the GMT offset value in milliseconds to add to UTC time - * to get local standard time - */ - public int getRawOffset() { - if (!willGMTOffsetChange) { - return rawOffset + rawOffsetDiff; - } - - int[] offsets = new int[2]; - getOffsets(System.currentTimeMillis(), offsets, UTC_TIME); - return offsets[0]; - } - - public boolean isDirty() { - return dirty; - } - - int getLastRawOffset() { - return rawOffset + rawOffsetDiff; - } - - /** - * Queries if this time zone uses Daylight Saving Time in the last known rule. - */ - public boolean useDaylightTime() { - return (simpleTimeZoneParams != null); - } - - @Override - public boolean observesDaylightTime() { - if (simpleTimeZoneParams != null) { - return true; - } - if (transitions == null) { - return false; - } - - // Look up the transition table to see if it's in DST right - // now or if there's any standard-to-daylight transition at - // any future. - long utc = System.currentTimeMillis() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - for (int i = index; i < transitions.length; i++) { - if ((transitions[i] & DST_MASK) != 0) { - return true; - } - } - // No further DST is observed. - return false; - } - - /** - * Queries if the specified date is in Daylight Saving Time. - */ - public boolean inDaylightTime(Date date) { - if (date == null) { - throw new NullPointerException(); - } - - if (transitions == null) { - return false; - } - - long utc = date.getTime() - rawOffsetDiff; - int index = getTransitionIndex(utc, UTC_TIME); - - // before transitions in the transition table - if (index < 0) { - return false; - } - - // the time is in the table range. - if (index < transitions.length) { - return (transitions[index] & DST_MASK) != 0; - } - - // beyond the transition table - SimpleTimeZone tz = getLastRule(); - if (tz != null) { - return tz.inDaylightTime(date); - } - return false; - } - - /** - * Returns the amount of time in milliseconds that the clock is advanced - * during daylight saving time is in effect in its last daylight saving time rule. - * - * @return the number of milliseconds the time is advanced with respect to - * standard time when daylight saving time is in effect. - */ - public int getDSTSavings() { - return dstSavings; - } - -// /** -// * @return the last year in the transition table or -1 if this -// * time zone doesn't observe any daylight saving time. -// */ -// public int getMaxTransitionYear() { -// if (transitions == null) { -// return -1; -// } -// long val = transitions[transitions.length - 1]; -// int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; -// val = (val >> TRANSITION_NSHIFT) + offset; -// CalendarDate lastDate = Gregorian.getCalendarDate(val); -// return lastDate.getYear(); -// } - - /** - * Returns a string representation of this time zone. - * @return the string - */ - public String toString() { - return getClass().getName() + - "[id=\"" + getID() + "\"" + - ",offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",lastRule=" + (lastRule == null ? getLastRuleInstance() : lastRule) + - "]"; - } - - /** - * Gets all available IDs supported in the Java run-time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs() { - List idList = ZoneInfoFile.getZoneIDs(); - List excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - // List all zones from the idList and excluded lists - List list = new ArrayList<>(idList.size() + excluded.size()); - list.addAll(idList); - list.addAll(excluded); - idList = list; - } - String[] ids = new String[idList.size()]; - return idList.toArray(ids); - } - - /** - * Gets all available IDs that have the same value as the - * specified raw GMT offset. - * - * @param rawOffset the GMT offset in milliseconds. This - * value should not include any daylight saving time. - * - * @return an array of time zone IDs. - */ - public static String[] getAvailableIDs(int rawOffset) { - String[] result; - List matched = new ArrayList<>(); - List IDs = ZoneInfoFile.getZoneIDs(); - int[] rawOffsets = ZoneInfoFile.getRawOffsets(); - - loop: - for (int index = 0; index < rawOffsets.length; index++) { - if (rawOffsets[index] == rawOffset) { - byte[] indices = ZoneInfoFile.getRawOffsetIndices(); - for (int i = 0; i < indices.length; i++) { - if (indices[i] == index) { - matched.add(IDs.get(i++)); - while (i < indices.length && indices[i] == index) { - matched.add(IDs.get(i++)); - } - break loop; - } - } - } - } - - // We need to add any zones from the excluded zone list that - // currently have the same GMT offset as the specified - // rawOffset. The zones returned by this method may not be - // correct as of return to the caller if any GMT offset - // transition is happening during this GMT offset checking... - List excluded = ZoneInfoFile.getExcludedZones(); - if (excluded != null) { - for (String id : excluded) { - TimeZone zi = getTimeZone(id); - if (zi != null && zi.getRawOffset() == rawOffset) { - matched.add(id); - } - } - } - - result = new String[matched.size()]; - matched.toArray(result); - return result; - } - - /** - * Gets the ZoneInfoOld for the given ID. - * - * @param ID the ID for a ZoneInfoOld. See TimeZone for detail. - * - * @return the specified ZoneInfoOld object, or null if there is no - * time zone of the ID. - */ - public static TimeZone getTimeZone(String ID) { - String givenID = null; - - ZoneInfoOld zi = ZoneInfoFile.getZoneInfoOld(ID); - if (zi == null) { - // if we can't create an object for the ID, try aliases. - try { - Map map = getAliasTable(); - String alias = ID; - while ((alias = map.get(alias)) != null) { - zi = ZoneInfoFile.getZoneInfoOld(alias); - if (zi != null) { - zi.setID(ID); - zi = ZoneInfoFile.addToCache(ID, zi); - zi = (ZoneInfoOld) zi.clone(); - break; - } - } - } catch (Exception e) { - // ignore exceptions - } - } - - if (givenID != null && zi != null) { - zi.setID(givenID); - } - return zi; - } - - private transient SimpleTimeZone lastRule; - - /** - * Returns a SimpleTimeZone object representing the last GMT - * offset and DST schedule or null if this time zone doesn't - * observe DST. - */ - synchronized SimpleTimeZone getLastRule() { - if (lastRule == null) { - lastRule = getLastRuleInstance(); - } - return lastRule; - } - - /** - * Returns a SimpleTimeZone object that represents the last - * known daylight saving time rules. - * - * @return a SimpleTimeZone object or null if this time zone - * doesn't observe DST. - */ - public SimpleTimeZone getLastRuleInstance() { - if (simpleTimeZoneParams == null) { - return null; - } - if (simpleTimeZoneParams.length == 10) { - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - simpleTimeZoneParams[8], - simpleTimeZoneParams[9], - dstSavings); - } - return new SimpleTimeZone(getLastRawOffset(), getID(), - simpleTimeZoneParams[0], - simpleTimeZoneParams[1], - simpleTimeZoneParams[2], - simpleTimeZoneParams[3], - simpleTimeZoneParams[4], - simpleTimeZoneParams[5], - simpleTimeZoneParams[6], - simpleTimeZoneParams[7], - dstSavings); - } - - /** - * Returns a copy of this ZoneInfoOld. - */ - public Object clone() { - ZoneInfoOld zi = (ZoneInfoOld) super.clone(); - zi.lastRule = null; - return zi; - } - - /** - * Returns a hash code value calculated from the GMT offset and - * transitions. - * @return a hash code of this time zone - */ - public int hashCode() { - return getLastRawOffset() ^ checksum; - } - - /** - * Compares the equity of two ZoneInfoOld objects. - * - * @param obj the object to be compared with - * @return true if given object is same as this ZoneInfoOld object, - * false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ZoneInfoOld)) { - return false; - } - ZoneInfoOld that = (ZoneInfoOld) obj; - return (getID().equals(that.getID()) - && (getLastRawOffset() == that.getLastRawOffset()) - && (checksum == that.checksum)); - } - - /** - * Returns true if this zone has the same raw GMT offset value and - * transition table as another zone info. If the specified - * TimeZone object is not a ZoneInfoOld instance, this method returns - * true if the specified TimeZone object has the same raw GMT - * offset value with no daylight saving time. - * - * @param other the ZoneInfoOld object to be compared with - * @return true if the given TimeZone has the same - * GMT offset and transition information; false, otherwise. - */ - public boolean hasSameRules(TimeZone other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (!(other instanceof ZoneInfoOld)) { - if (getRawOffset() != other.getRawOffset()) { - return false; - } - // if both have the same raw offset and neither observes - // DST, they have the same rule. - if ((transitions == null) - && (useDaylightTime() == false) - && (other.useDaylightTime() == false)) { - return true; - } - return false; - } - if (getLastRawOffset() != ((ZoneInfoOld)other).getLastRawOffset()) { - return false; - } - return (checksum == ((ZoneInfoOld)other).checksum); - } - - private static SoftReference> aliasTable; - - static Map getCachedAliasTable() { - Map aliases = null; - - SoftReference> cache = aliasTable; - if (cache != null) { - aliases = cache.get(); - } - return aliases; - } - - /** - * Returns a Map from alias time zone IDs to their standard - * time zone IDs. - * - * @return the Map that holds the mappings from alias time zone IDs - * to their standard time zone IDs, or null if - * ZoneInfoOldMappings file is not available. - */ - public synchronized static Map getAliasTable() { - Map aliases = getCachedAliasTable(); - if (aliases == null) { - aliases = ZoneInfoFile.getZoneAliases(); - if (aliases != null) { - // Replace old mappings from `jdk11_backward` - aliases.putAll(conflictingIDs); - aliasTable = new SoftReference>(aliases); - } - } - return aliases; - } - - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException { - stream.defaultReadObject(); - // We don't know how this object from 1.4.x or earlier has - // been mutated. So it should always be marked as `dirty'. - dirty = true; - } - - ////////////////////////////////////////////////////////////// - public boolean equalsTo(ZoneInfoOld other) { - return (getID().equals(other.getID()) - && (getLastRawOffset() == other.getLastRawOffset()) - && (dstSavings == other.dstSavings) - && (willGMTOffsetChange == other.willGMTOffsetChange) - && (checksum == other.checksum) - && equalsTransOffsets(other) - && (Arrays.equals(simpleTimeZoneParams, other.simpleTimeZoneParams) || - getLastRule().equals(other.getLastRule()))); - } - - private boolean equalsTransOffsets(ZoneInfoOld other) { - if (transitions == null) { - return (other.transitions == null && - Arrays.equals(offsets, other.offsets)); - } - if (other.transitions == null || - transitions.length != other.transitions.length) { - return false; - } - // if offsets and other.offsets have different order - // the last 4-bit in trans are different. - for (int i = 0; i < transitions.length; i++) { - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - - val = other.transitions[i]; - int dstO = (int)((val >>> DST_NSHIFT) & 0xfL); - int saveO = (dstO == 0) ? 0 : other.offsets[dstO] / 1000; - int offO = other.offsets[(int)(val & OFFSET_MASK)]/1000; - long secondO = (val >> TRANSITION_NSHIFT)/1000; - if ((dst == 0) != (dstO == 0) || save != saveO || off != offO || second != secondO) - return false; - } - return true; - } - - private int transToString(long val, int off_old, int[] offsets, StringBuilder sb) { - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - ZoneOffset offset_old = ZoneOffset.ofTotalSeconds(off_old); - ZoneOffset offset = ZoneOffset.ofTotalSeconds(off); - sb.append(" " + LocalDateTime.ofEpochSecond(second, 0, offset_old)); - - sb.append(" [utc=" + second + - " raw=" + Long.toHexString(val >> TRANSITION_NSHIFT) + - ", offset=" + off + "/" + offset + ", saving=" + save + "]"); - return off; - } - - public String diffsTo(ZoneInfoOld other) { - - int rawOffset0 = other.rawOffset; - int checksum0 = other.checksum; - int dstSavings0 = other.dstSavings; - long[] transitions0 = other.transitions; - int[] offsets0 = other.offsets; - int[] simpleTimeZoneParams0 = other.simpleTimeZoneParams; - boolean willGMTOffsetChange0 = other.willGMTOffsetChange; - - - //return getClass().getName() + - StringBuilder sb = new StringBuilder(); - sb.append("******************************\n" + - getID() + " : " + other.getID()); - // ROC is excluded by ZoneInfoOld - if ("ROC".equals(getID())) { - return sb.toString(); - } - if (rawOffset != rawOffset0 || - dstSavings != dstSavings0 || - checksum != checksum0 || - willGMTOffsetChange != willGMTOffsetChange0 || - (simpleTimeZoneParams != null ) != (simpleTimeZoneParams0 != null) || - (transitions != null && transitions0 != null && - transitions.length != transitions0.length)) - { - sb.append("\n offset=" + getLastRawOffset() + - ",dstSavings=" + dstSavings + - ",useDaylight=" + useDaylightTime() + - ",transitions=" + ((transitions != null) ? transitions.length : 0) + - ",offsets=" + ((offsets != null) ? offsets.length : 0) + - ",checksum=" + checksum + - ",gmtChanged=" + willGMTOffsetChange) - .append("\n[NG]offset=" + rawOffset0 + - ",dstSavings=" + dstSavings0 + - ",useDaylight=" + (simpleTimeZoneParams != null) + - ",transitions=" + ((transitions0 != null) ? transitions0.length : 0) + - ",offsets=" + ((offsets0 != null) ? offsets0.length : 0) + - ",checksum=" + checksum0 + - ",gmtChanged=" + willGMTOffsetChange0 + - ""); - } - // offsets - if (!Arrays.equals(offsets, offsets0)) { - sb.append("\n offset.len=" + ((offsets != null)? offsets.length : "null") + - " " + ((offsets0 != null)? offsets0.length : "null")); - if (offsets != null && offsets0.length != 0) { - int len = Math.min(offsets.length, offsets0.length); - int i = 0; - for (i = 0; i < len; i++) { - sb.append("\n " + - ZoneOffset.ofTotalSeconds(offsets[i]/1000) + " " + - ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - for (; i < offsets0.length; i++) { - sb.append("\n " + ZoneOffset.ofTotalSeconds(offsets0[i]/1000)); - } - } - } - // trans - int offset = 0; - int offset0 = 0; - if (!equalsTransOffsets(other)) { - sb.append("\n -------------"); - if ((transitions == null) != (transitions0 == null)) { - sb.append("\n (NG) Different trans(null) :" + - transitions + ", " + transitions0); - if (transitions != null) { - for (int i = 0; i < transitions.length; i++) { - sb.append("\n (NG)"); - offset = transToString(transitions[i], offset, offsets, sb); - } - } - } else { - if (transitions.length != transitions0.length) { - sb.append("\n (NG) Different trans size :" + - transitions.length + ", " + transitions0.length); - } - int length = Math.min(transitions.length, transitions0.length); - for (int i = 0; i < length; i++) { - // sb.append("\n[" + i + "] "); - // offset = transToString(transitions[i], offset, offsets, sb); - long val = transitions[i]; - int dst = (int)((val >>> DST_NSHIFT) & 0xfL); - int save = (dst == 0) ? 0 : offsets[dst] / 1000; - int off = offsets[(int)(val & OFFSET_MASK)]/1000; - long second = (val >> TRANSITION_NSHIFT)/1000; - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - if (transitions0 == null || i >= transitions0.length) { - sb.append("\n "); - offset = transToString(transitions[i], offset, offsets, sb); - sb.append("\n (NG) trans0 is null or < trans.length"); - } else { - long val0 = transitions0[i]; - int dst0 = (int)((val0 >>> DST_NSHIFT) & 0xfL); - int save0 = (dst0 == 0) ? 0 : offsets0[dst0] / 1000; - int off0 = offsets0[(int)(val0 & OFFSET_MASK)]/1000; - long second0 = (val0 >> TRANSITION_NSHIFT)/1000; - if (save != save0 || off != off0 || second != second0) { - sb.append("\n (NG)"); - } else { - sb.append("\n (OK)"); - } - offset0 = transToString(transitions0[i], offset0, offsets0, sb); - sb.append("\n -----"); - } - } - } - } - SimpleTimeZone stz = getLastRuleInstance(); - if (stz != null) { - SimpleTimeZone stz0 = other.getLastRule(); - if (!stz.hasSameRules(stz0)) { - sb.append("\n -------------") - .append("\n SimpleTimeZone (NG)") - .append("\n stz=" + stz) - .append("\n stz0=" + stz0); - } - } - sb.append("\n -------------"); - return sb.toString(); - } -} diff --git a/test/jdk/sun/util/calendar/zi/ZoneRec.java b/test/jdk/sun/util/calendar/zi/ZoneRec.java deleted file mode 100644 index f6bbeb3a199db..0000000000000 --- a/test/jdk/sun/util/calendar/zi/ZoneRec.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -/** - * ZoneRec hold information of time zone corresponding to each text - * line of the "Zone" part. - * - * @since 1.4 - */ -class ZoneRec { - private int gmtOffset; - private String ruleName; - private int directSave; - private Rule ruleRef; - private String format; - private boolean hasUntil; - private int untilYear; - private Month untilMonth; - private RuleDay untilDay; - private Time untilTime; - private long untilInMillis; - private String line; - - /** - * @return the "UNTIL" value in milliseconds - */ - Time getUntilTime() { - return untilTime; - } - - /** - * @return the GMT offset value in milliseconds - */ - int getGmtOffset() { - return gmtOffset; - } - - /** - * @return the rule name to which this zone record refers - */ - String getRuleName() { - return ruleName; - } - - /** - * @return the amount of saving time directly defined in the - * "RULES/SAVE" field. - */ - int getDirectSave() { - return directSave; - } - - /** - * @return true if this zone record has a reference to a rule - */ - boolean hasRuleReference() { - return ruleRef != null; - } - - /** - * Returns the "FORMAT" field string of this zone record. This - * @return the "FORMAT" field - */ - String getFormat() { - return format; - } - - /** - * @return the year in the "UNTIL" field - */ - int getUntilYear() { - return untilYear; - } - - /** - * Returns the "UNTIL" field value in milliseconds from Janurary - * 1, 1970 0:00 GMT. - * @param currentSave the amount of daylight saving in - * milliseconds that is used to adjust wall-clock time. - * @return the milliseconds value of the "UNTIL" field - */ - long getUntilTime(int currentSave) { - if (untilTime.isWall()) { - return untilInMillis - currentSave; - } - return untilInMillis; - } - - /** - * Returns the "UNTIL" time in milliseconds without adjusting GMT - * offsets or daylight saving. - * @return local "UNTIL" time in milliseconds - */ - long getLocalUntilTime() { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - untilTime.getTime()); - } - - /** - * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving. - * @return the "UNTIL" time after the adjustment - */ - long getLocalUntilTime(int save, int gmtOffset) { - return Time.getLocalTime(untilYear, - untilMonth, - untilDay, - save, - gmtOffset, - untilTime); - } - - /** - * @return the text line of this zone record - */ - String getLine() { - return line; - } - - /** - * Sets the specified text line to this zone record - */ - void setLine(String line) { - this.line = line; - } - - /** - * @return true if this zone record has the "UNTIL" field - */ - boolean hasUntil() { - return this.hasUntil; - } - - /** - * Adjusts the "UNTIL" time to GMT offset if this zone record has - * it. untilTime is not adjusted to daylight saving - * in this method. - */ - void adjustTime() { - if (!hasUntil()) { - return; - } - if (untilTime.isSTD() || untilTime.isWall()) { - // adjust to gmt offset only here. adjust to real - // wall-clock time when tracking rules - untilInMillis -= gmtOffset; - } - } - - /** - * @return the reference to the Rule object - */ - Rule getRuleRef() { - return ruleRef; - } - - /** - * Resolves the reference to a Rule and adjusts its "UNTIL" time - * to GMT offset. - */ - void resolve(Zoneinfo zi) { - if (ruleName != null && (!"-".equals(ruleName))) { - ruleRef = zi.getRule(ruleName); - } - adjustTime(); - } - - /** - * Parses a Zone text line that is described by a StringTokenizer. - * @param tokens represents tokens of a Zone text line - * @return the zone record produced by parsing the text - */ - static ZoneRec parse(StringTokenizer tokens) { - ZoneRec rec = new ZoneRec(); - try { - rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime(); - String token = tokens.nextToken(); - char c = token.charAt(0); - if (c >= '0' && c <= '9') { - rec.directSave = (int) Time.parse(token).getTime(); - } else { - rec.ruleName = token; - } - rec.format = tokens.nextToken(); - if (tokens.hasMoreTokens()) { - rec.hasUntil = true; - rec.untilYear = Integer.parseInt(tokens.nextToken()); - if (tokens.hasMoreTokens()) { - rec.untilMonth = Month.parse(tokens.nextToken()); - } else { - rec.untilMonth = Month.JANUARY; - } - if (tokens.hasMoreTokens()) { - rec.untilDay = RuleDay.parse(tokens.nextToken()); - } else { - rec.untilDay = new RuleDay(1); - } - if (tokens.hasMoreTokens()) { - rec.untilTime = Time.parse(tokens.nextToken()); - } else { - rec.untilTime = Time.parse("0:00"); - } - rec.untilInMillis = rec.getLocalUntilTime(); - } - } catch (Exception e) { - // TODO: error reporting - e.printStackTrace(); - } - return rec; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/Zoneinfo.java b/test/jdk/sun/util/calendar/zi/Zoneinfo.java deleted file mode 100644 index e125ad2cb87d1..0000000000000 --- a/test/jdk/sun/util/calendar/zi/Zoneinfo.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -/** - * Zoneinfo provides javazic compiler front-end functionality. - * @since 1.4 - */ -class Zoneinfo { - - private static final int minYear = 1900; - private static final int maxYear = 2100; - private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0); - private static int startYear = minYear; - private static int endYear = maxYear; - - /** - * True if javazic should generate a list of SimpleTimeZone - * instances for the SimpleTimeZone-based time zone support. - */ - static boolean isYearForTimeZoneDataSpecified = false; - - /** - * Zone name to Zone mappings - */ - private Map zones; - - /** - * Rule name to Rule mappings - */ - private Map rules; - - /** - * Alias name to real name mappings - */ - private Map aliases; - - /** - * Constracts a Zoneinfo. - */ - Zoneinfo() { - zones = new HashMap(); - rules = new HashMap(); - aliases = new HashMap(); - } - - /** - * Adds the given zone to the list of Zones. - * @param zone Zone to be added to the list. - */ - void add(Zone zone) { - String name = zone.getName(); - zones.put(name, zone); - } - - /** - * Adds the given rule to the list of Rules. - * @param rule Rule to be added to the list. - */ - void add(Rule rule) { - String name = rule.getName(); - rules.put(name, rule); - } - - /** - * Puts the specifid name pair to the alias table. - * @param name1 an alias time zone name - * @param name2 the real time zone of the alias name - */ - void putAlias(String name1, String name2) { - aliases.put(name1, name2); - } - - /** - * Sets the given year for SimpleTimeZone list output. - * This method is called when the -S option is specified. - * @param year the year for which SimpleTimeZone list should be generated - */ - static void setYear(int year) { - setStartYear(year); - setEndYear(year); - isYearForTimeZoneDataSpecified = true; - } - - /** - * Sets the start year. - * @param year the start year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the minimum year or greater than the end year. - */ - static void setStartYear(int year) { - if (year < minYear || year > endYear) { - throw new IllegalArgumentException("invalid start year specified: " + year); - } - startYear = year; - } - - /** - * @return the start year value - */ - static int getStartYear() { - return startYear; - } - - /** - * Sets the end year. - * @param year the end year value - * @throws IllegalArgumentException if the specified year value is - * smaller than the start year or greater than the maximum year. - */ - static void setEndYear(int year) { - if (year < startYear || year > maxYear) { - throw new IllegalArgumentException(); - } - endYear = year; - } - - /** - * @return the end year value - */ - static int getEndYear() { - return endYear; - } - - /** - * @return the minimum year value - */ - static int getMinYear() { - return minYear; - } - - /** - * @return the maximum year value - */ - static int getMaxYear() { - return maxYear; - } - - /** - * @return the alias table - */ - Map getAliases() { - return aliases; - } - - /** - * @return the Zone list - */ - Map getZones() { - return zones; - } - - /** - * @return a Zone specified by name. - * @param name a zone name - */ - Zone getZone(String name) { - return zones.get(name); - } - - /** - * @return a Rule specified by name. - * @param name a rule name - */ - Rule getRule(String name) { - return rules.get(name); - } - - private static String line; - - private static int lineNum; - - /** - * Parses the specified time zone data file and creates a Zoneinfo - * that has all Rules, Zones and Links (aliases) information. - * @param fname the time zone data file name - * @return a Zoneinfo object - */ - static Zoneinfo parse(String fname) { - BufferedReader in = null; - try { - FileReader fr = new FileReader(fname); - in = new BufferedReader(fr); - } catch (FileNotFoundException e) { - panic("can't open file: "+fname); - } - Zoneinfo zi = new Zoneinfo(); - boolean continued = false; - Zone zone = null; - String l; - lineNum = 0; - - try { - while ((line = in.readLine()) != null) { - lineNum++; - // skip blank and comment lines - if (line.length() == 0 || line.charAt(0) == '#') { - continue; - } - - // trim trailing comments - int rindex = line.lastIndexOf('#'); - if (rindex != -1) { - // take the data part of the line - l = line.substring(0, rindex); - } else { - l = line; - } - - StringTokenizer tokens = new StringTokenizer(l); - if (!tokens.hasMoreTokens()) { - continue; - } - String token = tokens.nextToken(); - int len = token.length(); - - if (continued || token.regionMatches(true, 0, "Zone", 0, len)){ - if (zone == null) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: zone no more token"); - } - token = tokens.nextToken(); - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict. - if (token.startsWith("GMT+") || token.startsWith("GMT-")) { - continue; - } - zone = new Zone(token); - } else { - // no way to push the current token back... - tokens = new StringTokenizer(l); - } - - ZoneRec zrec = ZoneRec.parse(tokens); - zrec.setLine(line); - zone.add(zrec); - if ((continued = zrec.hasUntil()) == false) { - if (Zone.isTargetZone(zone.getName())) { - // zone.resolve(zi); - zi.add(zone); - } - zone = null; - } - } else if (token.regionMatches(true, 0, "Rule", 0, len)) { - if (!tokens.hasMoreTokens()) { - panic("syntax error: rule no more token"); - } - token = tokens.nextToken(); - Rule rule = zi.getRule(token); - if (rule == null) { - rule = new Rule(token); - zi.add(rule); - } - RuleRec rrec = RuleRec.parse(tokens); - rrec.setLine(line); - rule.add(rrec); - } else if (token.regionMatches(true, 0, "Link", 0, len)) { - // Link - try { - String name1 = tokens.nextToken(); - String name2 = tokens.nextToken(); - - // if the zone name is in "GMT+hh" or "GMT-hh" - // format, ignore it due to spec conflict with - // custom time zones. Also, ignore "ROC" for - // PC-ness. - if (name2.startsWith("GMT+") || name2.startsWith("GMT-") - || "ROC".equals(name2)) { - continue; - } - zi.putAlias(name2, name1); - } catch (Exception e) { - panic("syntax error: no more token for Link"); - } - } - } - in.close(); - } catch (IOException ex) { - panic("IO error: " + ex.getMessage()); - } - - return zi; - } - - /** - * Interprets a zone and constructs a Timezone object that - * contains enough information on GMT offsets and DST schedules to - * generate a zone info database. - * - * @param zoneName the zone name for which a Timezone object is - * constructed. - * - * @return a Timezone object that contains all GMT offsets and DST - * rules information. - */ - Timezone phase2(String zoneName) { - Timezone tz = new Timezone(zoneName); - Zone zone = getZone(zoneName); - zone.resolve(this); - - // TODO: merge phase2's for the regular and SimpleTimeZone ones. - if (isYearForTimeZoneDataSpecified) { - ZoneRec zrec = zone.get(zone.size()-1); - tz.setLastZoneRec(zrec); - tz.setRawOffset(zrec.getGmtOffset()); - if (zrec.hasRuleReference()) { - /* - * This part assumes that the specified year is covered by - * the rules referred to by the last zone record. - */ - List rrecs = zrec.getRuleRef().getRules(startYear); - - if (rrecs.size() == 2) { - // make sure that one is a start rule and the other is - // an end rule. - RuleRec r0 = rrecs.get(0); - RuleRec r1 = rrecs.get(1); - if (r0.getSave() == 0 && r1.getSave() > 0) { - rrecs.set(0, r1); - rrecs.set(1, r0); - } else if (!(r0.getSave() > 0 && r1.getSave() == 0)) { - rrecs = null; - Main.error(zoneName + ": rules for " + startYear + " not found."); - } - } else { - rrecs = null; - } - if (rrecs != null) { - tz.setLastRules(rrecs); - } - } - return tz; - } - - int gmtOffset; - int year = minYear; - int fromYear = year; - long fromTime = Time.getLocalTime(startYear, - Month.JANUARY, - 1, 0); - - // take the index 0 for the GMT offset of the last zone record - ZoneRec zrec = zone.get(zone.size()-1); - tz.getOffsetIndex(zrec.getGmtOffset()); - - int lastGmtOffsetValue = -1; - ZoneRec prevzrec = null; - int currentSave = 0; - boolean usedZone; - for (int zindex = 0; zindex < zone.size(); zindex++) { - zrec = zone.get(zindex); - usedZone = false; - gmtOffset = zrec.getGmtOffset(); - int stdOffset = zrec.getDirectSave(); - - if (gmtOffset != lastGmtOffsetValue) { - tz.setRawOffset(gmtOffset, fromTime); - lastGmtOffsetValue = gmtOffset; - } - // If this is the last zone record, take the last rule info. - if (!zrec.hasUntil()) { - if (zrec.hasRuleReference()) { - tz.setLastRules(zrec.getRuleRef().getLastRules()); - } else if (stdOffset != 0) { - // in case the last rule is all year round DST-only - // (Asia/Amman once announced this rule.) - tz.setLastDSTSaving(stdOffset); - } - } - if (!zrec.hasRuleReference()) { - if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - usedZone = true; - } - currentSave = stdOffset; - // optimization in case the last rule is fixed. - if (!zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - if (stdOffset == 0) { - tz.setDSTType(Timezone.X_DST); - } else { - tz.setDSTType(Timezone.LAST_DST); - } - long time = Time.getLocalTime(maxYear, - Month.JANUARY, 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset+stdOffset), - tz.getDstOffsetIndex(stdOffset)); - tz.addUsedRec(zrec); - } else { - tz.setDSTType(Timezone.NO_DST); - } - break; - } - } else { - Rule rule = zrec.getRuleRef(); - boolean fromTimeUsed = false; - currentSave = 0; - year_loop: - for (year = getMinYear(); year <= endYear; year++) { - if (zrec.hasUntil() && year > zrec.getUntilYear()) { - break; - } - List rules = rule.getRules(year); - if (rules.size() > 0) { - for (int i = 0; i < rules.size(); i++) { - RuleRec rrec = rules.get(i); - long transition = rrec.getTransitionTime(year, - gmtOffset, - currentSave); - if (zrec.hasUntil()) { - if (transition >= zrec.getUntilTime(currentSave)) { - // If the GMT offset changed from the previous one, - // record fromTime as a transition. - if (!fromTimeUsed && prevzrec != null - && gmtOffset != prevzrec.getGmtOffset()) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; // for consistency - } - break year_loop; - } - } - - if (fromTimeUsed == false) { - if (fromTime <= transition) { - fromTimeUsed = true; - - if (fromTime != minTime) { - int prevsave; - - // See if until time in the previous - // ZoneRec is the same thing as the - // local time in the next rule. - // (examples are Asia/Ashkhabad in 1991, - // Europe/Riga in 1989) - - if (i > 0) { - prevsave = rules.get(i-1).getSave(); - } else { - List prevrules = rule.getRules(year-1); - - if (prevrules.size() > 0) { - prevsave = prevrules.get(prevrules.size()-1).getSave(); - } else { - prevsave = 0; - } - } - - if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) { - currentSave = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - continue; - } - if (!prevzrec.hasRuleReference() - || rule != prevzrec.getRuleRef() - || (rule == prevzrec.getRuleRef() - && gmtOffset != prevzrec.getGmtOffset())) { - int save = (fromTime == transition) ? rrec.getSave() : currentSave; - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - tz.addUsedRec(rrec); - usedZone = true; - } - } else { // fromTime == minTime - int save = rrec.getSave(); - tz.addTransition(minTime, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - - tz.addUsedRec(rrec); - usedZone = true; - } - } else if (year == fromYear && i == rules.size()-1) { - int save = rrec.getSave(); - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+save), - tz.getDstOffsetIndex(save)); - } - } - - currentSave = rrec.getSave(); - if (fromTime < transition) { - tz.addTransition(transition, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - tz.addUsedRec(rrec); - usedZone = true; - } - } - } else { - if (year == fromYear) { - tz.addTransition(fromTime, - tz.getOffsetIndex(gmtOffset+currentSave), - tz.getDstOffsetIndex(currentSave)); - fromTimeUsed = true; - } - if (year == endYear && !zrec.hasUntil()) { - if (tz.getNTransitions() > 0) { - // Assume that this Zone stopped DST - tz.setDSTType(Timezone.X_DST); - long time = Time.getLocalTime(maxYear, Month.JANUARY, - 1, 0); - time -= zrec.getGmtOffset(); - tz.addTransition(time, - tz.getOffsetIndex(gmtOffset), - tz.getDstOffsetIndex(0)); - usedZone = true; - } else { - tz.setDSTType(Timezone.NO_DST); - } - } - } - } - } - if (usedZone) { - tz.addUsedRec(zrec); - } - if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) { - fromTime = zrec.getUntilTime(currentSave); - fromYear = zrec.getUntilYear(); - year = zrec.getUntilYear(); - } - prevzrec = zrec; - } - - if (tz.getDSTType() == Timezone.UNDEF_DST) { - tz.setDSTType(Timezone.DST); - } - tz.optimize(); - tz.checksum(); - return tz; - } - - private static void panic(String msg) { - Main.panic(msg); - } -} diff --git a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward b/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward deleted file mode 100644 index e480a0083bef6..0000000000000 --- a/test/jdk/sun/util/calendar/zi/tzdata_jdk/jdk11_backward +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code 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 -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -# JDK 1.1.x compatible time zone IDs -# - -Link Australia/Darwin ACT -Link Australia/Sydney AET -Link America/Argentina/Buenos_Aires AGT -Link Africa/Cairo ART -Link America/Anchorage AST -Link America/Sao_Paulo BET -Link Asia/Dhaka BST -Link Africa/Harare CAT -Link America/St_Johns CNT -Link America/Chicago CST -Link Asia/Shanghai CTT -Link Africa/Addis_Ababa EAT -Link Europe/Paris ECT -Link America/New_York EST -Link Pacific/Honolulu HST -Link America/Indianapolis IET -Link Asia/Calcutta IST -Link Asia/Tokyo JST -Link Pacific/Apia MIT -Link America/Denver MST -Link Asia/Yerevan NET -Link Pacific/Auckland NST -Link Asia/Karachi PLT -Link America/Phoenix PNT -Link America/Puerto_Rico PRT -Link America/Los_Angeles PST -Link Pacific/Guadalcanal SST -Link Asia/Saigon VST - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D -Rule SystemV min 1973 - Oct lastSun 2:00 0 S -Rule SystemV 1974 only - Jan 6 2:00 1:00 D -Rule SystemV 1974 only - Nov lastSun 2:00 0 S -Rule SystemV 1975 only - Feb 23 2:00 1:00 D -Rule SystemV 1975 only - Oct lastSun 2:00 0 S -Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D -Rule SystemV 1976 max - Oct lastSun 2:00 0 S - -# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] -Zone SystemV/AST4ADT -4:00 SystemV A%sT -Zone SystemV/EST5EDT -5:00 SystemV E%sT -Zone SystemV/CST6CDT -6:00 SystemV C%sT -Zone SystemV/MST7MDT -7:00 SystemV M%sT -Zone SystemV/PST8PDT -8:00 SystemV P%sT -Zone SystemV/YST9YDT -9:00 SystemV Y%sT -Zone SystemV/AST4 -4:00 - AST -Zone SystemV/EST5 -5:00 - EST -Zone SystemV/CST6 -6:00 - CST -Zone SystemV/MST7 -7:00 - MST -Zone SystemV/PST8 -8:00 - PST -Zone SystemV/YST9 -9:00 - YST -Zone SystemV/HST10 -10:00 - HST diff --git a/test/jdk/sun/util/resources/TimeZone/Bug4640234.java b/test/jdk/sun/util/resources/TimeZone/Bug4640234.java index da555bbf040a1..553323fe2dc85 100644 --- a/test/jdk/sun/util/resources/TimeZone/Bug4640234.java +++ b/test/jdk/sun/util/resources/TimeZone/Bug4640234.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 4640234 4946057 4938151 4873691 5023181 + * @bug 4640234 4946057 4938151 4873691 5023181 8347841 8347955 * @summary Verifies the translation of time zone names, this test will catch * presence of country name for english and selected locales for all * ISO country codes. @@ -42,6 +42,7 @@ import java.text.MessageFormat; import java.text.SimpleDateFormat; +import java.time.ZoneId; import java.util.Date; import java.util.Locale; import java.util.Enumeration; @@ -49,6 +50,7 @@ import java.util.Map; import java.util.ResourceBundle; import java.util.TimeZone; +import java.util.function.Predicate; import sun.util.resources.LocaleData; @@ -83,7 +85,9 @@ public static void main(String[] args) throws Exception { StringBuffer errors = new StringBuffer(""); StringBuffer warnings = new StringBuffer(""); - String[] timezones = TimeZone.getAvailableIDs(); + String[] timezones = TimeZone.availableIDs() + .filter(Predicate.not(ZoneId.SHORT_IDS::containsKey)) + .toArray(String[]::new); String[] countries = locEn.getISOCountries(); String[] languages = locEn.getISOLanguages(); diff --git a/test/jdk/sun/util/resources/cldr/Bug8134384.java b/test/jdk/sun/util/resources/cldr/Bug8134384.java index eac8238bdd28a..f27b587ca9838 100644 --- a/test/jdk/sun/util/resources/cldr/Bug8134384.java +++ b/test/jdk/sun/util/resources/cldr/Bug8134384.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8134384 8234347 8236548 + * @bug 8134384 8234347 8236548 8347841 * @summary Tests CLDR TimeZoneNames has English names for all tzids * @run main/othervm -Djava.locale.providers=CLDR Bug8134384 */ @@ -38,6 +38,9 @@ public static void main(String [] args) { try { for (String tz : TimeZone.getAvailableIDs() ) { + if (ZoneId.SHORT_IDS.containsKey(tz)) { + continue; + } TimeZone.setDefault(TimeZone.getTimeZone(tz)); // Summer solstice String date1 = Date.from(Instant.parse("2015-06-21T00:00:00.00Z")).toString(); diff --git a/test/jdk/sun/util/resources/cldr/Bug8202764.java b/test/jdk/sun/util/resources/cldr/Bug8202764.java index f2c614b6df0be..6f3e40e620121 100644 --- a/test/jdk/sun/util/resources/cldr/Bug8202764.java +++ b/test/jdk/sun/util/resources/cldr/Bug8202764.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8202764 + * @bug 8202764 8347841 * @modules jdk.localedata * @summary Checks time zone names are consistent with aliased ids, * between DateFormatSymbols.getZoneStrings() and getDisplayName() @@ -49,6 +49,7 @@ public class Bug8202764 { public void testAliasedTZs() { Set zoneIds = ZoneId.getAvailableZoneIds(); Arrays.stream(DateFormatSymbols.getInstance(Locale.US).getZoneStrings()) + .filter(zone -> !ZoneId.SHORT_IDS.containsKey(zone[0])) .forEach(zone -> { System.out.println(zone[0]); TimeZone tz = TimeZone.getTimeZone(zone[0]); diff --git a/test/jdk/tools/jar/JarCreateFileNameTest.java b/test/jdk/tools/jar/JarCreateFileNameTest.java new file mode 100644 index 0000000000000..fb2b6a2e73286 --- /dev/null +++ b/test/jdk/tools/jar/JarCreateFileNameTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarFile; +import java.util.spi.ToolProvider; +import java.util.zip.ZipEntry; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/* + * @test + * @bug 8302293 + * @summary verify that a JAR file creation through "jar --create" operation + * works fine if the JAR file name is less than 3 characters in length + * @run junit JarCreateFileNameTest + */ +public class JarCreateFileNameTest { + + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") + .orElseThrow(() -> + new RuntimeException("jar tool not found") + ); + + /* + * Launches "jar --create --file" with file names of varying lengths and verifies + * that the JAR file was successfully created. + */ + @ParameterizedTest + @ValueSource(strings = {"abcd", "abc", "ab", "a", "d.jar", "ef.jar"}) + void testCreate(final String targetJarFileName) throws Exception { + final Path cwd = Path.of("."); + final Path tmpFile = Files.createTempFile(cwd, "8302293", ".txt"); + final String fileName = tmpFile.getFileName().toString(); + final int exitCode = JAR_TOOL.run(System.out, System.err, + "--create", "--file", targetJarFileName, fileName); + assertEquals(0, exitCode, "jar command failed"); + // verify the JAR file is created and contains the expected entry + try (final JarFile jarFile = new JarFile(new File(targetJarFileName))) { + final ZipEntry entry = jarFile.getEntry(fileName); + assertNotNull(entry, "missing " + fileName + " entry in JAR file " + targetJarFileName); + } + } +} + diff --git a/test/jdk/tools/jimage/JImageToolTest.java b/test/jdk/tools/jimage/JImageToolTest.java index b1006c896794b..d7d1ee35ba1e0 100644 --- a/test/jdk/tools/jimage/JImageToolTest.java +++ b/test/jdk/tools/jimage/JImageToolTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test * @library /test/lib + * @requires vm.flagless * @build jdk.test.lib.process.ProcessTools * @summary Test to check if jimage tool exists and is working * @run main/timeout=360 JImageToolTest diff --git a/test/jdk/tools/jlink/IntegrationTest.java b/test/jdk/tools/jlink/IntegrationTest.java index 7f3dc22346106..5a8d0bce15ad7 100644 --- a/test/jdk/tools/jlink/IntegrationTest.java +++ b/test/jdk/tools/jlink/IntegrationTest.java @@ -157,7 +157,7 @@ private static void test() throws Exception { boolean linkFromRuntime = false; JlinkConfiguration config = new Jlink.JlinkConfiguration(output, mods, - JlinkTask.newLimitedFinder(JlinkTask.newModuleFinder(modulePaths), limits, mods), + JlinkTask.limitFinder(JlinkTask.newModuleFinder(modulePaths), limits, mods), linkFromRuntime, false /* ignore modified runtime */, false /* generate run-time image */); diff --git a/test/jdk/tools/jlink/JLink20000Packages.java b/test/jdk/tools/jlink/JLink20000Packages.java new file mode 100644 index 0000000000000..865cf7ca98c2f --- /dev/null +++ b/test/jdk/tools/jlink/JLink20000Packages.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.StringJoiner; +import java.util.spi.ToolProvider; + +import tests.JImageGenerator; + +/* + * @test + * @summary Make sure that ~20000 packages in a uber jar can be linked using jlink. Now that + * pagination is in place, the limitation is on the constant pool size, not number + * of packages. + * @bug 8321413 + * @library ../lib + * @enablePreview + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main/othervm -Xmx1g -Xlog:init=debug -XX:+UnlockDiagnosticVMOptions -XX:+BytecodeVerificationLocal JLink20000Packages + */ +public class JLink20000Packages { + private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac") + .orElseThrow(() -> new RuntimeException("javac tool not found")); + + static void report(String command, String[] args) { + System.out.println(command + " " + String.join(" ", Arrays.asList(args))); + } + + static void javac(String[] args) { + report("javac", args); + JAVAC_TOOL.run(System.out, System.err, args); + } + + public static void main(String[] args) throws Exception { + Path src = Paths.get("bug8321413"); + Path imageDir = src.resolve("out-jlink"); + Path mainModulePath = src.resolve("bug8321413x"); + + StringJoiner mainModuleInfoContent = new StringJoiner(";\n exports ", "module bug8321413x {\n exports ", ";\n}"); + + for (int i = 0; i < 20000; i++) { + String packageName = "p" + i; + String className = "C" + i; + + Path packagePath = Files.createDirectories(mainModulePath.resolve(packageName)); + + StringBuilder classContent = new StringBuilder("package "); + classContent.append(packageName).append(";\n"); + classContent.append("class ").append(className).append(" {}\n"); + Files.writeString(packagePath.resolve(className + ".java"), classContent.toString()); + + mainModuleInfoContent.add(packageName); + } + + // create module reading the generated modules + Path mainModuleInfo = mainModulePath.resolve("module-info.java"); + Files.writeString(mainModuleInfo, mainModuleInfoContent.toString()); + + Path mainClassDir = mainModulePath.resolve("testpackage"); + Files.createDirectories(mainClassDir); + + Files.writeString(mainClassDir.resolve("JLink20000PackagesTest.java"), """ + package testpackage; + + public class JLink20000PackagesTest { + public static void main(String[] args) throws Exception { + System.out.println("JLink20000PackagesTest started."); + } + } + """); + + String out = src.resolve("out").toString(); + javac(new String[]{ + "-d", out, + "--module-source-path", src.toString(), + "--module", "bug8321413x" + }); + + JImageGenerator.getJLinkTask() + .modulePath(out) + .output(imageDir) + .addMods("bug8321413x") + .call() + .assertSuccess(); + + Path binDir = imageDir.resolve("bin").toAbsolutePath(); + Path bin = binDir.resolve("java"); + + ProcessBuilder processBuilder = new ProcessBuilder(bin.toString(), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+BytecodeVerificationLocal", + "-m", "bug8321413x/testpackage.JLink20000PackagesTest"); + processBuilder.inheritIO(); + processBuilder.directory(binDir.toFile()); + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) + throw new AssertionError("JLink20000PackagesTest failed to launch"); + } +} diff --git a/test/jdk/tools/jlink/JLinkTest.java b/test/jdk/tools/jlink/JLinkTest.java index c0fabe06a8c57..0b7de201ac9de 100644 --- a/test/jdk/tools/jlink/JLinkTest.java +++ b/test/jdk/tools/jlink/JLinkTest.java @@ -27,17 +27,15 @@ import java.lang.module.ModuleDescriptor; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.internal.PluginRepository; +import jdk.tools.jlink.plugin.Plugin; import tests.Helper; import tests.JImageGenerator; @@ -135,11 +133,11 @@ public static void main(String[] args) throws Exception { { // No --module-path specified. --add-modules ALL-MODULE-PATH specified. - String imageDir = "bug8189777-all-module-path"; + String imageDir = "bug8345259-all-module-path"; JImageGenerator.getJLinkTask() .output(helper.createNewImageDir(imageDir)) .addMods("ALL-MODULE-PATH") - .call().assertSuccess(); + .call().assertFailure(); } { diff --git a/test/jdk/tools/jlink/SnippetsTest.java b/test/jdk/tools/jlink/SnippetsTest.java new file mode 100644 index 0000000000000..ec0c94e3d264b --- /dev/null +++ b/test/jdk/tools/jlink/SnippetsTest.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import static java.lang.classfile.ClassFile.ACC_PUBLIC; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_String; +import static java.lang.constant.ConstantDescs.INIT_NAME; +import static java.lang.constant.ConstantDescs.MTD_void; +import java.lang.constant.MethodTypeDesc; +import static java.lang.invoke.MethodHandles.lookup; +import java.lang.invoke.MethodType; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.AccessFlag; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; + +import jdk.tools.jlink.internal.Snippets.*; + +/* + * @test + * @summary Test snippets generation for array and set. + * @bug 8321413 + * @enablePreview + * @modules jdk.jlink/jdk.tools.jlink.internal + * @run junit SnippetsTest + */ +public class SnippetsTest { + private static final boolean WRITE_CLASS_FILE = Boolean.parseBoolean(System.getProperty("DumpArraySnippetsTestClasses", "false")); + + @ParameterizedTest + @ValueSource(ints = { 10, 75, 90, 120, 200, 399, 400, 401}) + void testLoad400StringsArray(int pageSize) { + testPaginatedArray(400, pageSize); + } + + @Test + void testStringArrayLimitsWithPagination() { + // Each string takes 2 constant pool slot, one for String, another for Utf8 + testPaginatedArray(31_000, 8000); + try { + testPaginatedArray(32_000, 8000); + } catch (IllegalArgumentException iae) { + // expected constant pool explode + } + } + + @Test + void testStringArrayLimitsWithoutPagination() { + // each string array assignment takes ~8 bytes + testSimpleArray(8200); + try { + testSimpleArray(8300); + fail(); + } catch (IllegalArgumentException iae) { + // expected code size explode + } + } + + @Test + void testLoadableEnum() { + Enum[] enums = { + AccessFlag.FINAL, + ModuleDescriptor.Requires.Modifier.MANDATED, + ModuleDescriptor.Opens.Modifier.SYNTHETIC, + ModuleDescriptor.Requires.Modifier.TRANSITIVE + }; + + Snippet[] elementSnippets = Snippet.buildAll(Arrays.asList(enums), Snippet::loadEnum); + + var loadable = new ArraySnippetBuilder(Enum.class.describeConstable().get()) + .build(elementSnippets); + + Supplier[]> supplier = generateSupplier("LoadableEnumTest", clb -> loadable); + assertArrayEquals(enums, supplier.get()); + } + + @Test + void testArraySnippetBuilder() { + Integer[] expected = IntStream.range(0, 200) + .boxed() + .toArray(Integer[]::new); + var className = "LoadableArrayOf200Paged"; + var elementSnippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadInteger); + var instance = new ArraySnippetBuilder(CD_Integer) + .ownerClassDesc(ClassDesc.of(className)) + .enablePagination("page", 100); + + try { + instance.build(elementSnippets); + fail("Should throw NPE without ClassBuilder"); + } catch (NullPointerException npe) { + // expected + } + + Supplier supplier = generateSupplier(className, clb -> instance.classBuilder(clb).build(elementSnippets)); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 2); + assertArrayEquals(expected, supplier.get()); + + var loadable = instance.disablePagination() + .ownerClassDesc(ClassDesc.of("LoadableArrayOf200NotPaged")) + .build(elementSnippets); + + // SimpleArray generate bytecode inline, so can be generated in any class + supplier = generateSupplier("TestLoadableArrayFactory", clb -> loadable); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + @Test + void testSetSnippetBuilder() { + String[] data = IntStream.range(0, 100) + .mapToObj(i -> "SetData" + i) + .toArray(String[]::new); + + var tiny = Set.of(data[0], data[1], data[2]); + var all = Set.of(data); + var setBuilder = new SetSnippetBuilder(CD_String); + + Supplier> supplier = generateSupplier("TinySetTest", clb -> + setBuilder.build(Snippet.buildAll(tiny, Snippet::loadConstant))); + // Set does not guarantee ordering, so not assertIterableEquals + assertEquals(tiny, supplier.get()); + + var allSnippets = Snippet.buildAll(all, Snippet::loadConstant); + + supplier = generateSupplier("AllSetTestNoPage", clb -> + setBuilder.build(allSnippets)); + assertEquals(all, supplier.get()); + + var className = "AllSetTestPageNotActivated"; + var methodNamePrefix = "page"; + var loadable = setBuilder.disablePagination() + .ownerClassDesc(ClassDesc.of(className)) + .build(allSnippets); + supplier = generateSupplier(className, clb -> loadable); + assertEquals(all, supplier.get()); + + className = "AllSetTestPageSize20"; + setBuilder.ownerClassDesc(ClassDesc.of(className)); + supplier = generateSupplier(className, clb -> setBuilder.classBuilder(clb) + .enablePagination(methodNamePrefix, 20) + .build(allSnippets)); + verifyPaginationMethods(supplier.getClass(), String.class, methodNamePrefix, 5); + assertEquals(all, supplier.get()); + } + + void testPaginatedArray(int elementCount, int pageSize) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "Package" + i) + .toArray(String[]::new); + var className = String.format("SnippetArrayProviderTest%dPagedBy%d", elementCount, pageSize); + ClassDesc testClassDesc = ClassDesc.of(className); + var builder = new ArraySnippetBuilder(CD_String) + .enablePagination("ArrayPage", pageSize, 1) + .ownerClassDesc(testClassDesc); + var snippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant); + var pagingContext = new PagingContext(expected.length, pageSize); + + Supplier supplier = generateSupplier(className, clb -> builder.classBuilder(clb).build(snippets)); + verifyPaginationMethods(supplier.getClass(), String.class, "ArrayPage", pagingContext.pageCount()); + assertEquals((elementCount % pageSize) != 0, pagingContext.isLastPagePartial()); + assertArrayEquals(expected, supplier.get()); + } + + void testSimpleArray(int elementCount) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "NoPage" + i) + .toArray(String[]::new); + String className = "SnippetArrayProviderTest" + elementCount; + var array = new ArraySnippetBuilder(CD_String) + .disablePagination() + .build(Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant)); + + Supplier supplier = generateSupplier(className, clb -> array); + verifyPaginationMethods(supplier.getClass(), String.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + Supplier generateSupplier(String className, Function builder) { + var testClassDesc = ClassDesc.of(className); + byte[] classBytes = generateSupplierClass(testClassDesc, builder); + try { + writeClassFile(className, classBytes); + var testClass = lookup().defineClass(classBytes); + lookup().findVirtual(testClass, "get", MethodType.methodType(Object.class)); + return (Supplier) testClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + void verifyPaginationMethods(Class testClass, Class elementType, String methodNamePrefix, int pageCount) { + var methodType = MethodType.methodType(elementType.arrayType(), elementType.arrayType()); + if (pageCount <= 0) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_0", methodType); + fail("Unexpected paginate helper function"); + } catch (Exception ex) {} + } + + for (int i = 0; i < pageCount; i++) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_" + i, methodType); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + + byte[] generateSupplierClass(ClassDesc testClassDesc, Function builder) { + return ClassFile.of().build(testClassDesc, + clb -> { + clb.withSuperclass(CD_Object); + clb.withInterfaceSymbols(ClassDesc.ofInternalName("java/util/function/Supplier")); + clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> { + cob.aload(0); + cob.invokespecial(CD_Object, INIT_NAME, MTD_void); + cob.return_(); + }); + + var loadable = builder.apply(clb); + + clb.withMethodBody("get", MethodTypeDesc.of(CD_Object), ACC_PUBLIC, cob -> { + loadable.emit(cob); + cob.areturn(); + }); + }); + } + + void writeClassFile(String className, byte[] classBytes) throws IOException { + if (WRITE_CLASS_FILE) { + Files.write(Path.of(className + ".class"), classBytes); + } + } +} \ No newline at end of file diff --git a/test/jdk/tools/jlink/TaskHelperTest.java b/test/jdk/tools/jlink/TaskHelperTest.java new file mode 100644 index 0000000000000..51dea8de24a9a --- /dev/null +++ b/test/jdk/tools/jlink/TaskHelperTest.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.util.*; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import jdk.tools.jlink.internal.PluginRepository; +import jdk.tools.jlink.internal.TaskHelper; +import jdk.tools.jlink.internal.TaskHelper.Option; +import jdk.tools.jlink.internal.TaskHelper.OptionsHelper; +import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import jdk.tools.jlink.internal.TaskHelper.BadArgs; + +/* + * @test + * @summary Test TaskHelper option parsing + * @bug 8303884 + * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * @run junit TaskHelperTest + */ +public class TaskHelperTest { + private static TaskHelper taskHelper; + private static OptionsHelper optionsHelper; + + private static final List> OPTIONS = List.of( + new Option<>(true, (task, opt, arg) -> { + System.out.println(arg); + mainArgValue = arg; + }, true, "--main-expecting"), + new Option<>(false, (task, opt, arg) -> { + mainFlag = true; + }, true, "--main-no-arg") + ); + + private static String argValue; + private static String mainArgValue; + private static boolean mainFlag = false; + + public record ArgTestCase(String cmdLine, String[] tokens, String pluginArgValue, String mainArgValue, boolean mainFlagSet) {}; + + public static class TestPluginWithRawOption implements Plugin { + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + return out.build(); + } + + @Override + public boolean hasArguments() { + return true; + } + + @Override + public boolean hasRawArgument() { + return true; + } + + @Override + public String getName() { + return "raw-arg-plugin"; + } + + @Override + public void configure(Map config) { + config.forEach((k, v) -> { + System.out.println(k + " -> " + v); + }); + var v = config.get(getName()); + if (v == null) + throw new AssertionError(); + argValue = v; + } + } + + @BeforeAll + public static void setup() { + taskHelper = new TaskHelper(TaskHelper.JLINK_BUNDLE); + optionsHelper = taskHelper.newOptionsHelper(TaskHelperTest.class, OPTIONS.toArray(Option[]::new)); + PluginRepository.registerPlugin(new TestPluginWithRawOption()); + } + + @BeforeEach + public void reset() { + argValue = null; + mainArgValue = null; + mainFlag = false; + } + + public static Stream gnuStyleUsages() { + return Stream.of( + new ArgTestCase( + "--main-expecting=--main-no-arg --main-no-arg", + new String[] { "--main-expecting=--main-no-arg", "--main-no-arg" }, + null, + "--main-no-arg", + true + ), + new ArgTestCase( + "--main-expecting ' --main-no-arg' --main-no-arg", + new String[] { "--main-expecting", " --main-no-arg", "--main-no-arg" }, + null, + " --main-no-arg", + true + ), + new ArgTestCase( + "--raw-arg-plugin=--main-no-arg --main-no-arg", + new String[] { "--raw-arg-plugin=--main-no-arg", "--main-no-arg" }, + "--main-no-arg", + null, + true + ), + new ArgTestCase( + "--raw-arg-plugin ' --main-no-arg' --main-no-arg", + new String[] { "--raw-arg-plugin", " --main-no-arg", "--main-no-arg" }, + " --main-no-arg", + null, + true + ), + new ArgTestCase( + "--raw-arg-plugin=--main-expecting=value --main-no-arg", + new String[] { "--raw-arg-plugin=--main-expecting=value", "--main-no-arg" }, + "--main-expecting=value", + null, + true + ), + new ArgTestCase( + "--raw-arg-plugin='--main-expecting value' --main-no-arg", + new String[] { "--raw-arg-plugin=--main-expecting value", "--main-no-arg" }, + "--main-expecting value", + null, + true + ), + new ArgTestCase( + "--raw-arg-plugin='--main-expecting value' --main-expecting realValue", + new String[] { "--raw-arg-plugin=--main-expecting value", "--main-expecting", "realValue" }, + "--main-expecting value", + "realValue", + false + )); + } + + @ParameterizedTest + @MethodSource("gnuStyleUsages") + public void testGnuStyleOptionAsArgValue(ArgTestCase testCase) throws TaskHelper.BadArgs { + System.out.println("Test cmdline: " + testCase.cmdLine()); + var args = testCase.tokens(); + var remaining = optionsHelper.handleOptions(this, args); + try { + // trigger Plugin::configure + taskHelper.getPluginsConfig(null, null, null); + } catch (IOException ex) { + fail("Unexpected IOException"); + } + assertTrue(remaining.isEmpty()); + assertEquals(testCase.mainFlagSet(), mainFlag); + assertEquals(testCase.pluginArgValue(), argValue); + assertEquals(testCase.mainArgValue(), mainArgValue); + } + + @Test + public void testGnuStyleOptionAsArgValueMissing() { + var invalidFormat = new String[][] { + { "--main-expecting", "--main-no-arg --list", "--main-no-arg" }, + { "--main-expecting", "--main-no-arg", "--main-no-arg" }, + { "--raw-arg-plugin", "--main-no-arg --list", "--main-no-arg" }, + { "--raw-arg-plugin", "--main-no-arg", "--main-no-arg" }, + { "--raw-arg-plugin", "--main-expecting", "value", "--main-no-arg" } + }; + + for (var args: invalidFormat) { + try { + optionsHelper.handleOptions(this, args); + fail("Should get an ambiguous error"); + } catch (BadArgs ex) { + // expected + } + } + } + + @Test + public void testRemaining() throws BadArgs { + String[] args = { "--raw-arg-plugin=--main-expecting", "value", "--main-no-arg" }; + var remaining = optionsHelper.handleOptions(this, args); + assertEquals(2, remaining.size()); + } +} \ No newline at end of file diff --git a/test/jdk/tools/jlink/basic/AllModulePath.java b/test/jdk/tools/jlink/basic/AllModulePath.java index ba6cc08bd4757..a05f2d06d8658 100644 --- a/test/jdk/tools/jlink/basic/AllModulePath.java +++ b/test/jdk/tools/jlink/basic/AllModulePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,45 +21,52 @@ * questions. */ -/* - * @test - * @summary jlink test of --add-module ALL-MODULE-PATH - * @library /test/lib - * @modules jdk.compiler - * @build jdk.test.lib.process.ProcessTools - * jdk.test.lib.process.OutputAnalyzer - * jdk.test.lib.compiler.CompilerUtils - * @run testng AllModulePath - */ +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; -import java.io.File; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; import java.util.spi.ToolProvider; - -import jdk.test.lib.compiler.CompilerUtils; -import jdk.test.lib.process.ProcessTools; +import java.util.stream.Collectors; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import static org.testng.Assert.*; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.ProcessTools; +import jdk.tools.jlink.internal.LinkableRuntimeImage; +import tests.Helper; +import tests.Result; + +/* + * @test + * @bug 8345259 + * @summary jlink test of --add-module ALL-MODULE-PATH + * @library ../../lib /test/lib + * @modules jdk.compiler + * java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jimage + * @build jdk.test.lib.process.ProcessTools + * jdk.test.lib.process.OutputAnalyzer + * jdk.test.lib.compiler.CompilerUtils + * @run testng/othervm -Duser.language=en -Duser.country=US AllModulePath + */ public class AllModulePath { - private final Path JMODS = Paths.get(System.getProperty("test.jdk")).resolve("jmods"); - private final Path SRC = Paths.get(System.getProperty("test.src")).resolve("src"); - private final Path MODS = Paths.get("mods"); + private static final Path JMODS = Paths.get(System.getProperty("test.jdk")).resolve("jmods"); + private static final Path SRC = Paths.get(System.getProperty("test.src")).resolve("src"); + private static final Path MODS = Paths.get("mods"); + private static final boolean LINKABLE_RUNTIME = LinkableRuntimeImage.isLinkableRuntime(); + private static final boolean JMODS_EXIST = Files.exists(JMODS); private final static Set MODULES = Set.of("test", "m1"); @@ -67,12 +74,22 @@ public class AllModulePath { .orElseThrow(() -> new RuntimeException("jlink tool not found") ); + private static Helper HELPER; + + private static boolean isExplodedJDKImage() { + if (!JMODS_EXIST && !LINKABLE_RUNTIME) { + System.err.println("Test skipped. Not a linkable runtime and no JMODs"); + return true; + } + return false; + } @BeforeClass public void setup() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } + HELPER = Helper.newHelper(LINKABLE_RUNTIME); Files.createDirectories(MODS); @@ -84,60 +101,114 @@ public void setup() throws Throwable { } } + /* + * --add-modules ALL-MODULE-PATH with an existing module-path. + */ @Test public void testAllModulePath() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } - // create custom image - Path image = Paths.get("image"); - createImage(image, "--add-modules", "ALL-MODULE-PATH"); + Path image = HELPER.createNewImageDir("image"); + List opts = List.of("--module-path", MODS.toString(), + "--output", image.toString(), + "--add-modules", "ALL-MODULE-PATH"); + createImage(image, opts, true /* success */); Set modules = new HashSet<>(); - Files.find(JMODS, 1, (Path p, BasicFileAttributes attr) -> - p.toString().endsWith(".jmod")) - .map(p -> JMODS.relativize(p).toString()) - .map(n -> n.substring(0, n.length()-5)) - .forEach(modules::add); + // java.base is a dependency of any external module + modules.add("java.base"); modules.add("m1"); modules.add("test"); checkModules(image, modules); } + /* + * --add-modules ALL-MODULE-PATH with --limit-modules is an error + */ @Test public void testLimitModules() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } - - // create custom image - Path image = Paths.get("image1"); - createImage(image, - "--add-modules", "ALL-MODULE-PATH", - "--limit-modules", "m1"); - - checkModules(image, Set.of("m1", "java.base")); + Path targetPath = HELPER.createNewImageDir("all-mods-limit-mods"); + String moduleName = "com.baz.runtime"; + Result result = HELPER.generateDefaultJModule(moduleName, "jdk.jfr"); + Path customModulePath = result.getFile().getParent(); + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--limit-modules", "jdk.jfr", + "--module-path", customModulePath.toString(), + "--output", targetPath.toString()); + JlinkOutput allOut = createImage(targetPath, allArgs, false /* success */); + String actual = allOut.stdout.trim(); + String expected = "Error: --limit-modules not allowed with --add-modules ALL-MODULE-PATH"; + assertEquals(actual, expected); } + + /* + * --add-modules *includes* ALL-MODULE-PATH with an existing module path + */ @Test public void testAddModules() throws Throwable { - if (Files.notExists(JMODS)) { + if (isExplodedJDKImage()) { return; } // create custom image - Path image = Paths.get("image2"); - createImage(image, - "--add-modules", "m1,test", - "--add-modules", "ALL-MODULE-PATH", - "--limit-modules", "java.base"); + Path image = HELPER.createNewImageDir("image2"); + List opts = List.of("--module-path", MODS.toString(), + "--output", image.toString(), + "--add-modules", "m1", + "--add-modules", "ALL-MODULE-PATH"); + createImage(image, opts, true /* success */); checkModules(image, Set.of("m1", "test", "java.base")); } /* - * check the modules linked in the image + * No --module-path with --add-modules ALL-MODULE-PATH is an error. + */ + @Test + public void noModulePath() throws IOException { + if (isExplodedJDKImage()) { + return; + } + Path targetPath = HELPER.createNewImageDir("all-mod-path-no-mod-path"); + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--output", targetPath.toString()); + JlinkOutput allOut = createImage(targetPath, allArgs, false /* expect failure */); + String expected = "Error: --module-path option must be specified with --add-modules ALL-MODULE-PATH"; + assertEquals(allOut.stdout.trim(), expected); + } + + /* + * --module-path not-exist and --add-modules ALL-MODULE-PATH is an error. + */ + @Test + public void modulePathEmpty() throws IOException { + if (isExplodedJDKImage()) { + return; + } + Path targetPath = HELPER.createNewImageDir("all-mod-path-not-existing"); + String strNotExists = "not-exist"; + Path notExists = Path.of(strNotExists); + if (Files.exists(notExists)) { + throw new AssertionError("Test setup error, path must not exist!"); + } + List allArgs = List.of("--add-modules", "ALL-MODULE-PATH", + "--module-path", notExists.toString(), + "--output", targetPath.toString()); + + JlinkOutput allOut = createImage(targetPath, allArgs, false /* expect failure */); + String actual = allOut.stdout.trim(); + assertTrue(actual.startsWith("Error: No module found in module path")); + assertTrue(actual.contains(strNotExists)); + } + + /* + * check the modules linked in the image using m1/p.ListModules */ private void checkModules(Path image, Set modules) throws Throwable { Path cmd = findTool(image, "java"); @@ -164,16 +235,19 @@ private Path findTool(Path image, String tool) { return cmd; } - private void createImage(Path image, String... options) throws IOException { - String modulepath = JMODS.toString() + File.pathSeparator + MODS.toString(); - List opts = List.of("--module-path", modulepath, - "--output", image.toString()); - String[] args = Stream.concat(opts.stream(), Arrays.stream(options)) - .toArray(String[]::new); - - System.out.println("jlink " + Arrays.stream(args).collect(Collectors.joining(" "))); - PrintWriter pw = new PrintWriter(System.out); - int rc = JLINK_TOOL.run(pw, pw, args); - assertTrue(rc == 0); + private JlinkOutput createImage(Path image, List args, boolean success) throws IOException { + System.out.println("jlink " + args.stream().collect(Collectors.joining(" "))); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter out = new PrintWriter(baos); + ByteArrayOutputStream berrOs = new ByteArrayOutputStream(); + PrintWriter err = new PrintWriter(berrOs); + int rc = JLINK_TOOL.run(out, err, args.toArray(String[]::new)); + String stdOut = new String(baos.toByteArray()); + String stdErr = new String(berrOs.toByteArray()); + assertEquals(rc == 0, success, String.format("Output was: %nstdout: %s%nstderr: %s%n", stdOut, stdErr)); + return new JlinkOutput(stdErr, stdOut); } + + private static record JlinkOutput(String stderr, String stdout) {}; } diff --git a/test/jdk/tools/jlink/basic/BasicTest.java b/test/jdk/tools/jlink/basic/BasicTest.java index a771d4d000250..1a14e620fa626 100644 --- a/test/jdk/tools/jlink/basic/BasicTest.java +++ b/test/jdk/tools/jlink/basic/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,21 +21,6 @@ * questions. */ -/* - * @test - * @summary Basic test of jlink to create jmods and images - * @author Andrei Eremeev - * @library /test/lib - * @modules java.base/jdk.internal.module - * jdk.jlink - * jdk.compiler - * @build jdk.test.lib.process.ProcessTools - * jdk.test.lib.process.OutputAnalyzer - * jdk.test.lib.compiler.CompilerUtils - * jdk.test.lib.util.JarUtils - * @run main BasicTest - */ - import java.io.File; import java.io.PrintWriter; import java.nio.file.Files; @@ -50,7 +35,22 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; +import jdk.tools.jlink.internal.LinkableRuntimeImage; +/* + * @test + * @summary Basic test of jlink to create jmods and images + * @author Andrei Eremeev + * @library /test/lib + * @modules java.base/jdk.internal.module + * jdk.jlink/jdk.tools.jlink.internal + * jdk.compiler + * @build jdk.test.lib.process.ProcessTools + * jdk.test.lib.process.OutputAnalyzer + * jdk.test.lib.compiler.CompilerUtils + * jdk.test.lib.util.JarUtils + * @run main/othervm BasicTest + */ public class BasicTest { static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod") .orElseThrow(() -> @@ -62,21 +62,31 @@ public class BasicTest { new RuntimeException("jlink tool not found") ); - private final String TEST_MODULE = "test"; - private final Path jdkHome = Paths.get(System.getProperty("test.jdk")); - private final Path jdkMods = jdkHome.resolve("jmods"); - private final Path testSrc = Paths.get(System.getProperty("test.src")); - private final Path src = testSrc.resolve("src").resolve(TEST_MODULE); - private final Path classes = Paths.get("classes"); - private final Path jmods = Paths.get("jmods"); - private final Path jars = Paths.get("jars"); + private static final String TEST_MODULE = "test"; + private static final Path jdkHome = Paths.get(System.getProperty("test.jdk")); + private static final Path jdkMods = jdkHome.resolve("jmods"); + private static final boolean JMODS_EXIST = Files.exists(jdkMods); + private static final boolean LINKABLE_RUNTIME = LinkableRuntimeImage.isLinkableRuntime(); + private static final Path testSrc = Paths.get(System.getProperty("test.src")); + private static final Path src = testSrc.resolve("src").resolve(TEST_MODULE); + private static final Path classes = Paths.get("classes"); + private static final Path jmods = Paths.get("jmods"); + private static final Path jars = Paths.get("jars"); public static void main(String[] args) throws Throwable { new BasicTest().run(); } + private static boolean isExplodedJDKImage() { + if (!JMODS_EXIST && !LINKABLE_RUNTIME) { + System.err.println("Test skipped. Not a linkable runtime and no JMODs"); + return true; + } + return false; + } + public void run() throws Throwable { - if (Files.notExists(jdkMods)) { + if (isExplodedJDKImage()) { return; } @@ -146,8 +156,10 @@ private void execute(Path image, String scriptName) throws Throwable { private void runJlink(Path image, String modName, String... options) { List args = new ArrayList<>(); + String modPathArg = (JMODS_EXIST ? jdkMods + File.pathSeparator : "") + + jmods; Collections.addAll(args, - "--module-path", jdkMods + File.pathSeparator + jmods, + "--module-path", modPathArg, "--add-modules", modName, "--output", image.toString()); Collections.addAll(args, options); diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index f0fe3149247ea..f30adee80a3c6 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,32 +21,43 @@ * questions. */ +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.tools.jlink.internal.LinkableRuntimeImage; import jdk.tools.jlink.internal.TaskHelper; import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; import jdk.tools.jlink.plugin.PluginException; +import jdk.test.lib.Platform; import tests.Helper; import tests.JImageGenerator; import tests.JImageValidator; import tests.Result; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /* * @test * @bug 8152143 8152704 8155649 8165804 8185841 8176841 8190918 * 8179071 8202537 8221432 8222098 8251317 8258794 8265315 - * 8296248 8306116 8174269 + * 8296248 8306116 8174269 8347146 * @summary IncludeLocalesPlugin tests * @author Naoto Sato * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) - * @library ../../lib + * @library ../../lib /test/lib * @modules java.base/jdk.internal.jimage * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins @@ -55,365 +66,346 @@ * jdk.jlink/jdk.tools.jimage * jdk.compiler * @build tests.* + * @build jdk.test.lib.Platform * @build tools.jlink.plugins.GetAvailableLocales - * @run main/othervm/timeout=180 -Xmx1g IncludeLocalesPluginTest + * @run junit/othervm/timeout=180 -Xmx1g IncludeLocalesPluginTest */ + public class IncludeLocalesPluginTest { - private static final String moduleName = "IncludeLocalesTest"; + private static final String MODULE_NAME = "IncludeLocalesTest"; private static Helper helper; - private static final int INCLUDE_LOCALES_OPTION = 0; - private static final int ADDMODS_OPTION = 1; - private static final int EXPECTED_LOCATIONS = 2; - private static final int UNEXPECTED_PATHS = 3; - private static final int AVAILABLE_LOCALES = 4; - private static final int ERROR_MESSAGE = 5; - - private static int errors; - - private final static Object[][] testData = { - // Test data should include: - // - --include-locales command line option - // - --add-modules command line option values - // - List of required resources in the result image - // - List of resources that should not exist in the result image - // - List of available locales in the result image - // - Error message - - // without --include-locales option: should include all locales - { - "", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of(), - Arrays.stream(Locale.getAvailableLocales()) - // "(root)" for Locale.ROOT rather than "" - .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) - .collect(Collectors.toList()), - "", - }, - - // Asterisk works exactly the same as above - { - "--include-locales=*", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of(), - Arrays.stream(Locale.getAvailableLocales()) - // "(root)" for Locale.ROOT rather than "" - .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) - .collect(Collectors.toList()), - "", - }, - - // World English/Spanish in Latin America - { - "--include-locales=en-001,es-419", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_419.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_AR.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AG", "en_AI", - "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GY", "en_HK", "en_ID", - "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE", - "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", "en_MO", - "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG", - "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PK", "en_PN", - "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", - "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", - "en_TT", "en_TV", "en_TZ", "en_UG", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VU", "en_WS", - "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", - "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN", - "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", - "es_UY", "es_VE", - // CLDR's "hi-Latn" falls back to "en-001", "hi-Latn"/"hi-Latn-IN" are added - // here. Since Locale.Matcher cannot handle such exceptional inheritance, - // allowing to include "hi"/"hi-IN" resource files. - "hi", "hi__#Latn", "hi_IN", "hi_IN_#Latn"), - "", - }, - - // All English and Japanese locales - { - "--include-locales=en,ja", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", - "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", - "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", - "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", - "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", - "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", - "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", - "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", - "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", - "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", - "en_WS", "en_ZA", "en_ZM", "en_ZW", "ja", "ja_JP", "ja_JP_#Jpan", - "ja_JP_JP_#u-ca-japanese"), - "", - }, - - // All locales in Austria - { - "--include-locales=*-AT", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de_AT.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_001", "en_150", "en_AT", "en_US", "en_US_#Latn", "en_US_POSIX", - "de", "de_AT"), - "", - }, - - // All locales in India - { - "--include-locales=*-IN", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_IN.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class", - "/jdk.localedata/sun/util/resources/cldr/ext/CalendarData_as_IN.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "as", "as_IN", "as_IN_#Beng", "bgc", "bgc_IN", "bgc_IN_#Deva", "bho", "bho_IN", "bho_IN_#Deva", - "bn", "bn_IN", "bo", "bo_IN", "brx", "brx_IN", "brx_IN_#Deva", "ccp", "ccp_IN", "doi", "doi_IN", - "doi_IN_#Deva", "en", "en_001", "en_IN", "en_US", "en_US_#Latn", "en_US_POSIX", "gu", "gu_IN", - "gu_IN_#Gujr", "hi", "hi__#Latn", "hi_IN", "hi_IN_#Deva", "hi_IN_#Latn", "kn", "kn_IN", "kn_IN_#Knda", - "kok", "kok__#Deva", "kok__#Latn", "kok_IN", "kok_IN_#Deva", "kok_IN_#Latn", "ks", "ks__#Arab", - "ks__#Deva", "ks_IN", "ks_IN_#Arab", "ks_IN_#Deva", "kxv", "kxv_IN", "kxv_IN_#Deva", "kxv_IN_#Latn", - "kxv_IN_#Orya", "kxv_IN_#Telu", "kxv__#Deva", "kxv__#Latn", "kxv__#Orya", "kxv__#Telu", - "mai", "mai_IN", "mai_IN_#Deva", "mni", "mni__#Beng", "mni_IN", "mni_IN_#Beng", "ml", "ml_IN", - "ml_IN_#Mlym", "mr", "mr_IN", "mr_IN_#Deva", "ne", "ne_IN", "or", "or_IN", "or_IN_#Orya", "pa", - "pa__#Guru", "pa_IN", "pa_IN_#Guru", "raj", "raj_IN", "raj_IN_#Deva", "sa", "sa_IN", "sa_IN_#Deva", - "sat", "sat__#Olck", "sat_IN", "sat_IN_#Olck", "sd", "sd__#Deva", "sd_IN", "sd_IN_#Deva", "ta", "ta_IN", - "ta_IN_#Taml", "te", "te_IN", "te_IN_#Telu", "ur_IN", "ur", "xnr", "xnr_IN", "xnr_IN_#Deva"), - "", - }, - - // Thai - { - "--include-locales=th", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class"), - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "th", "th_TH", - "th_TH_#Thai", "th_TH_TH_#u-nu-thai"), - "", - }, - - // Hong Kong - { - "--include-locales=zh-HK", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Hans", "zh__#Hant", - "zh_HK", "zh_HK_#Hans", "zh_HK_#Hant"), - "", - }, - - // Simplified Chinese - { - "--include-locales=zh-Hans", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Latn", "zh__#Hans", "zh_CN", - "zh_CN_#Latn", "zh_CN_#Hans", "zh_HK", "zh_HK_#Hans", "zh_MO", "zh_MO_#Hans", "zh_MY_#Hans", "zh_SG", - "zh_SG_#Hans"), - "", - }, - - // Norwegian - { - "--include-locales=nb,nn,no", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nb.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nn.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_no.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "nb", "nb_NO", - "nb_NO_#Latn", "nb_SJ", "nn", "nn_NO", "nn_NO_#Latn", "no", "no_NO", "no_NO_NY", - "no_NO_#Latn"), - "", - }, - - // Hebrew/Indonesian/Yiddish - { - "--include-locales=he,id,yi", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_he.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_id.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_yi.class"), - List.of( - "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/thai_dict", - "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", - "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), - List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "id", "id_ID", - "id_ID_#Latn", "he", "he_IL", "he_IL_#Hebr", "yi", "yi_UA", "yi_UA_#Hebr"), - "", - }, - - // Langtag including extensions. Should be ignored. - { - "--include-locales=en,ja-u-nu-thai", - "jdk.localedata", - List.of( - "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class"), - List.of(), - List.of( - "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", - "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", - "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", - "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", - "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", - "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", - "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", - "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", - "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", - "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", - "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", - "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", - "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", - "en_WS", "en_ZA", "en_ZM", "en_ZW"), - "", - }, - - // Error case: No matching locales - { - "--include-locales=xyz", - "jdk.localedata", - null, - null, - null, - new PluginException(String.format( - PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"), "xyz")) - .getMessage(), - }, - - // Error case: Invalid argument - { - "--include-locales=en,zh_HK", - "jdk.localedata", - null, - null, - null, - new PluginException(String.format( - PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_hk")) - .getMessage(), - }, - - // Error case: jdk.localedata is not added - { - "--include-locales=en-US", - "java.base", - null, - null, - null, - new PluginException( - PluginsResourceBundle.getMessage("include-locales.localedatanotfound")) - .getMessage(), - }, - }; - - public static void main(String[] args) throws Exception { + + // Test data should include: + // - --include-locales command line option + // - --add-modules command line option values + // - List of required resources in the result image + // - List of resources that should not exist in the result image + // - List of available locales in the result image + // - Error message + private static Stream testData() { + return Stream.of( + // without --include-locales option: should include all locales + Arguments.of( + "", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of(), + Arrays.stream(Locale.getAvailableLocales()) + // "(root)" for Locale.ROOT rather than "" + .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) + .collect(Collectors.toList()), + ""), + + // Asterisk works exactly the same as above + Arguments.of( + "--include-locales=*", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of(), + Arrays.stream(Locale.getAvailableLocales()) + // "(root)" for Locale.ROOT rather than "" + .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString()) + .collect(Collectors.toList()), + ""), + + // World English/Spanish in Latin America + Arguments.of( + "--include-locales=en-001,es-419", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_419.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_AR.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AG", "en_AI", + "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GY", "en_HK", "en_ID", + "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE", + "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", "en_MO", + "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG", + "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PK", "en_PN", + "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", + "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", + "en_TT", "en_TV", "en_TZ", "en_UG", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VU", "en_WS", + "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", + "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN", + "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", + "es_UY", "es_VE", + // CLDR's "hi-Latn" falls back to "en-001", "hi-Latn"/"hi-Latn-IN" are added + // here. Since Locale.Matcher cannot handle such exceptional inheritance, + // allowing to include "hi"/"hi-IN" resource files. + "hi", "hi__#Latn", "hi_IN", "hi_IN_#Latn"), + ""), + + // All English and Japanese locales + Arguments.of( + "--include-locales=en,ja", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", + "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", + "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", + "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", + "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", + "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", + "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", + "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", + "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", + "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", + "en_WS", "en_ZA", "en_ZM", "en_ZW", "ja", "ja_JP", "ja_JP_#Jpan", + "ja_JP_JP_#u-ca-japanese"), + ""), + + // All locales in Austria + Arguments.of( + "--include-locales=*-AT", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de_AT.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_001", "en_150", "en_AT", "en_US", "en_US_#Latn", "en_US_POSIX", + "de", "de_AT"), + ""), + + // All locales in India + Arguments.of( + "--include-locales=*-IN", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_IN.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class", + "/jdk.localedata/sun/util/resources/cldr/ext/CalendarData_as_IN.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "as", "as_IN", "as_IN_#Beng", "bgc", "bgc_IN", "bgc_IN_#Deva", "bho", "bho_IN", "bho_IN_#Deva", + "bn", "bn_IN", "bo", "bo_IN", "brx", "brx_IN", "brx_IN_#Deva", "ccp", "ccp_IN", "doi", "doi_IN", + "doi_IN_#Deva", "en", "en_001", "en_IN", "en_US", "en_US_#Latn", "en_US_POSIX", "gu", "gu_IN", + "gu_IN_#Gujr", "hi", "hi__#Latn", "hi_IN", "hi_IN_#Deva", "hi_IN_#Latn", "kn", "kn_IN", "kn_IN_#Knda", + "kok", "kok__#Deva", "kok__#Latn", "kok_IN", "kok_IN_#Deva", "kok_IN_#Latn", "ks", "ks__#Arab", + "ks__#Deva", "ks_IN", "ks_IN_#Arab", "ks_IN_#Deva", "kxv", "kxv_IN", "kxv_IN_#Deva", "kxv_IN_#Latn", + "kxv_IN_#Orya", "kxv_IN_#Telu", "kxv__#Deva", "kxv__#Latn", "kxv__#Orya", "kxv__#Telu", + "mai", "mai_IN", "mai_IN_#Deva", "mni", "mni__#Beng", "mni_IN", "mni_IN_#Beng", "ml", "ml_IN", + "ml_IN_#Mlym", "mr", "mr_IN", "mr_IN_#Deva", "ne", "ne_IN", "or", "or_IN", "or_IN_#Orya", "pa", + "pa__#Guru", "pa_IN", "pa_IN_#Guru", "raj", "raj_IN", "raj_IN_#Deva", "sa", "sa_IN", "sa_IN_#Deva", + "sat", "sat__#Olck", "sat_IN", "sat_IN_#Olck", "sd", "sd__#Deva", "sd_IN", "sd_IN_#Deva", "ta", "ta_IN", + "ta_IN_#Taml", "te", "te_IN", "te_IN_#Telu", "ur_IN", "ur", "xnr", "xnr_IN", "xnr_IN_#Deva"), + ""), + + // Thai + Arguments.of( + "--include-locales=th", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class"), + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "th", "th_TH", + "th_TH_#Thai", "th_TH_TH_#u-nu-thai"), + ""), + + // Hong Kong + Arguments.of( + "--include-locales=zh-HK", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Hans", "zh__#Hant", + "zh_HK", "zh_HK_#Hans", "zh_HK_#Hant"), + ""), + + // Simplified Chinese + Arguments.of( + "--include-locales=zh-Hans", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "zh", "zh__#Latn", "zh__#Hans", "zh_CN", + "zh_CN_#Latn", "zh_CN_#Hans", "zh_HK", "zh_HK_#Hans", "zh_MO", "zh_MO_#Hans", "zh_MY_#Hans", "zh_SG", + "zh_SG_#Hans"), + ""), + + // Norwegian + Arguments.of( + "--include-locales=nb,nn,no", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nb.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_nn.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_no.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "nb", "nb_NO", + "nb_NO_#Latn", "nb_SJ", "nn", "nn_NO", "nn_NO_#Latn", "no", "no_NO", "no_NO_NY", + "no_NO_#Latn"), + ""), + + // Hebrew/Indonesian/Yiddish + Arguments.of( + "--include-locales=he,id,yi", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_he.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_id.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_yi.class"), + List.of( + "/jdk.localedata/sun/text/resources/ext/LineBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/thai_dict", + "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th", + "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), + List.of( + "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "id", "id_ID", + "id_ID_#Latn", "he", "he_IL", "he_IL_#Hebr", "yi", "yi_UA", "yi_UA_#Hebr"), + ""), + + // Langtag including extensions. Should be ignored. + Arguments.of( + "--include-locales=en,ja-u-nu-thai", + "jdk.localedata", + List.of( + "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class"), + List.of(), + List.of( + "(root)", "en", "en_001", "en_150", "en_AE", "en_AG", "en_AI", "en_AS", "en_AT", + "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", + "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", + "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", + "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GU", "en_GY", + "en_HK", "en_ID", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", + "en_KE", "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", + "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MV", "en_MW", "en_MY", + "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", + "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RW", "en_SB", "en_SC", + "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", + "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", + "en_UM", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VI", "en_VU", + "en_WS", "en_ZA", "en_ZM", "en_ZW"), + ""), + + // Error case: No matching locales + Arguments.of( + "--include-locales=xyz", + "jdk.localedata", + null, + null, + null, + new PluginException(String.format( + PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"), "xyz")) + .getMessage()), + + // Error case: Invalid argument + Arguments.of( + "--include-locales=en,zh_HK", + "jdk.localedata", + null, + null, + null, + new PluginException(String.format( + PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_hk")) + .getMessage()), + + // Error case: jdk.localedata is not added + Arguments.of( + "--include-locales=en-US", + "java.base", + null, + null, + null, + new PluginException( + PluginsResourceBundle.getMessage("include-locales.localedatanotfound")) + .getMessage()) + ); + } + + @BeforeAll + public static void setup() throws IOException { boolean isLinkableRuntime = LinkableRuntimeImage.isLinkableRuntime(); System.out.println("Running test on " + (isLinkableRuntime ? "enabled" : "disabled") + @@ -423,48 +415,42 @@ public static void main(String[] args) throws Exception { "present."); helper = Helper.newHelper(isLinkableRuntime); - if (helper == null) { - throw new RuntimeException("Helper could not be initialized"); - } + assertNotNull(helper, "Helper could not be initialized"); + } - for (Object[] data : testData) { - // create image for each test data - Result result; - if (data[INCLUDE_LOCALES_OPTION].toString().isEmpty()) { - System.out.println("Invoking jlink with no --include-locales option"); - result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(moduleName)) - .addMods((String) data[ADDMODS_OPTION]) - .call(); - } else { - System.out.println("Invoking jlink with \"" + data[INCLUDE_LOCALES_OPTION] + "\""); - result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(moduleName)) - .addMods((String) data[ADDMODS_OPTION]) - .option((String) data[INCLUDE_LOCALES_OPTION]) - .call(); - } - - String errorMsg = (String) data[ERROR_MESSAGE]; - if (errorMsg.isEmpty()) { - Path image = result.assertSuccess(); - - // test locale data entries - testLocaleDataEntries(image, - (List) data[EXPECTED_LOCATIONS], - (List) data[UNEXPECTED_PATHS]); - - // test available locales - testAvailableLocales(image, (List) data[AVAILABLE_LOCALES]); - } else { - result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE) - .getMessage("error.prefix") + " " +errorMsg); - System.out.println("\tExpected failure: " + result.getMessage()); - } + @ParameterizedTest + @MethodSource("testData") + public void launch(String optIncludeLocales, String optAddModules, List requiredRes, + List shouldNotExistRes, List availableLocs, String errorMsg) throws Exception { + // create image for each test data + Result result; + if (optIncludeLocales.isEmpty()) { + System.out.println("Invoking jlink with no --include-locales option"); + result = JImageGenerator.getJLinkTask() + .output(helper.createNewImageDir(MODULE_NAME)) + .addMods(optAddModules) + .call(); + } else { + System.out.println("Invoking jlink with \"" + optIncludeLocales + "\""); + result = JImageGenerator.getJLinkTask() + .output(helper.createNewImageDir(MODULE_NAME)) + .addMods(optAddModules) + .option(optIncludeLocales) + .call(); } - if (errors > 0) { - throw new RuntimeException("Test failed"); + if (errorMsg.isEmpty()) { + Path image = result.assertSuccess(); + + // test locale data entries + testLocaleDataEntries(image, requiredRes, shouldNotExistRes); + + // test available locales + testAvailableLocales(image, availableLocs); + } else { + result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE) + .getMessage("error.prefix") + " " +errorMsg); + System.out.println("\tExpected failure: " + result.getMessage()); } } @@ -476,16 +462,13 @@ private static void testLocaleDataEntries(Path image, List expectedLocat image.resolve("lib").resolve("modules"), expectedLocations, unexpectedPaths); } catch (Exception e) { - System.out.println("\tFailed with: " + e); - e.printStackTrace(); - errors++; + fail("\tFailed with: " + e); } } private static void testAvailableLocales(Path image, List availableLocales) throws Exception { System.out.println("testAvailableLocales:"); - Path launcher = image.resolve("bin/java" + - (System.getProperty("os.name").startsWith("Windows") ? ".exe" : "")); + Path launcher = image.resolve("bin/java" + (Platform.isWindows() ? ".exe" : "")); List args = new ArrayList<>(availableLocales.size() + 2); args.add(launcher.toString()); args.add("GetAvailableLocales"); @@ -497,12 +480,8 @@ private static void testAvailableLocales(Path image, List availableLocal + (len < availableLocales.size() ? " ..." : ""); int status = proc.waitFor(); - if (status == 0) { - System.out.println("\tDone\t" + command); - } else { - System.out.println("\tExit " + status + "\t" + command); - errors++; - } + assertTrue(status == 0, "\tExit " + status + "\t" + command); + System.out.println("\tDone\t" + command); System.out.println(); } } diff --git a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java index 827f7da624d30..1ffe1240d07e7 100644 --- a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m AddOptionsTest + * @run main/othervm -Xmx1g AddOptionsTest */ public class AddOptionsTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java index ebf5b060665fc..b0d2a2d66f5b3 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkMissingJavaBase + * @run main/othervm -Xmx1g BasicJlinkMissingJavaBase */ public class BasicJlinkMissingJavaBase extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java index 8cbd74e5ed1cb..b97ebff9b4906 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m BasicJlinkTest false + * @run main/othervm -Xmx1g BasicJlinkTest false */ public class BasicJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java index d6c237a173b72..369bccfecfce4 100644 --- a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m CustomModuleJlinkTest + * @run main/othervm -Xmx1g CustomModuleJlinkTest */ public class CustomModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java index e59d18bd6f05c..533a8db30d0cc 100644 --- a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m GenerateJLIClassesTest + * @run main/othervm -Xmx1g GenerateJLIClassesTest */ public class GenerateJLIClassesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java index a376d075ecd07..d923358aed90d 100644 --- a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java +++ b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m JavaSEReproducibleTest + * @run main/othervm -Xmx1g JavaSEReproducibleTest */ public class JavaSEReproducibleTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/JimageDiffGeneratorTest.java b/test/jdk/tools/jlink/runtimeImage/JimageDiffGeneratorTest.java new file mode 100644 index 0000000000000..0176e6d07a19d --- /dev/null +++ b/test/jdk/tools/jlink/runtimeImage/JimageDiffGeneratorTest.java @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2025, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.List; + +import org.testng.annotations.Test; + +import jdk.tools.jlink.internal.runtimelink.JimageDiffGenerator; +import jdk.tools.jlink.internal.runtimelink.JimageDiffGenerator.ImageResource; +import jdk.tools.jlink.internal.runtimelink.ResourceDiff; + +/* + * @test + * @summary Unit test the diff generator logic for JEP 493 + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal.runtimelink + * @run testng JimageDiffGeneratorTest + */ +public class JimageDiffGeneratorTest { + + /* + * Expect a resource diff since the "b" item is removed in + * the optimized image. + */ + @Test + public void testItemsRemovedInOpt() throws Exception { + List entriesOpt = List.of("a", "c", "d"); + byte[][] bytesOpt = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + ImageResource opt = new BasicImageResource(entriesOpt, bytesOpt); + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 1); + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.REMOVED); + assertEquals(result.get(0).getName(), "b"); + assertEquals(result.get(0).getResourceBytes(), bytesBase[1]); + } + + /* + * Expect no difference as streams are the same + */ + @Test + public void testNoDiff() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + ImageResource opt = new BasicImageResource(entriesBase, bytesBase); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertTrue(result.isEmpty()); + } + + /* + * Expect a resource diff since the "b" item has been added in + * the optimized image. + */ + @Test + public void testItemsAddedInOpt() throws Exception { + List entriesBase = List.of("a", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + List entriesOpt = List.of("a", "b", "c", "d"); + byte[][] bytesOpt = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + ImageResource opt = new BasicImageResource(entriesOpt, bytesOpt); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 1); + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.ADDED); + assertEquals(result.get(0).getName(), "b"); + assertEquals(result.get(0).getResourceBytes(), null, "Added entries in opt don't have resource bytes"); + } + + /* + * Expect a resource diff since the "d" item has modified bytes in the + * optimized image resource. + */ + @Test + public void testBytesDiffer() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + List entriesOpt = List.of("a", "b", "c", "d"); + byte[][] bytesOpt = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x22, 0x22, 0x30 }, /* d - differs to base! */ + }; + ImageResource opt = new BasicImageResource(entriesOpt, bytesOpt); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 1); + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.MODIFIED); + assertEquals(result.get(0).getName(), "d"); + assertEquals(result.get(0).getResourceBytes(), bytesBase[3]); + } + + /* + * Expect a resource diff since an item has modified bytes. Test + * for a resource that has more than 1K bytes (the buffer size used + * internally). + */ + @Test + public void testBytesDifferLarge() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + bytesBase[2] = generateBytes(); + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + List entriesOpt = List.of("a", "b", "c", "d"); + byte[][] bytesOpt = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { }, /* c */ + { 0x22, 0x22, 0x30 }, /* d */ + }; + bytesOpt[2] = generateBytes(); + // Change the first byte of 'c' in the opt bytes + bytesOpt[2][0] = -1; + // assert pre-condition + assertTrue(bytesOpt[2][0] != bytesBase[2][0]); + + ImageResource opt = new BasicImageResource(entriesOpt, bytesOpt); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 2); + // assertions for 'c' differences + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.MODIFIED); + assertEquals(result.get(0).getName(), "c"); + assertEquals(result.get(0).getResourceBytes(), bytesBase[2]); + + // assertion for 'd' differences + assertEquals(result.get(1).getKind(), ResourceDiff.Kind.MODIFIED); + assertEquals(result.get(1).getName(), "d"); + assertEquals(result.get(1).getResourceBytes(), bytesBase[3]); + } + + /* + * Expect a no resource difference since the steams are both empty + */ + @Test + public void testEmptyStreams() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { }, /* a */ + { }, /* b */ + { }, /* c */ + { }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + ImageResource opt = new BasicImageResource(entriesBase, bytesBase); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertTrue(result.isEmpty()); + } + + /* + * Expect a difference since entry 'a' has zero bytes in opt. + */ + @Test + public void testNotEqualLength() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { 0x01, 0x03, 0x03 }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + byte[][] bytesOpt = new byte[][] { + { }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + ImageResource opt = new BasicImageResource(entriesBase, bytesOpt); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 1); + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.MODIFIED); + assertEquals(result.get(0).getName(), "a"); + assertEquals(result.get(0).getResourceBytes(), bytesBase[0]); + } + + /* + * Expect a difference since entry 'a' on the optimized version is + * one byte longer. + */ + @Test + public void testBytesDifferExactBufferSize() throws Exception { + List entriesBase = List.of("a", "b", "c", "d"); + byte[][] bytesBase = new byte[][] { + { }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + byte[][] bytesOpt = new byte[][] { + { }, /* a */ + { 0x08, 0x04, 0x04 }, /* b */ + { 0x09, 0x11, 0x11 }, /* c */ + { 0x11, 0x12, 0x31 }, /* d */ + }; + bytesBase[0] = genBytesOfSize(1024); // exact buffer size + bytesOpt[0] = genBytesOfSize(1024 + 1); // buffer size + 1 + + ImageResource base = new BasicImageResource(entriesBase, bytesBase); + ImageResource opt = new BasicImageResource(entriesBase, bytesOpt); + JimageDiffGenerator gen = new JimageDiffGenerator(); + List result = gen.generateDiff(base, opt); + assertEquals(result.size(), 1); + assertEquals(result.get(0).getKind(), ResourceDiff.Kind.MODIFIED); + assertEquals(result.get(0).getName(), "a"); + assertEquals(result.get(0).getResourceBytes(), bytesBase[0]); + } + + private byte[] generateBytes() { + int size = 1024 + 254; + return genBytesOfSize(size); + } + + private byte[] genBytesOfSize(int size) { + byte[] result = new byte[size]; + for (int i = 0; i < size; i++) { + result[i] = (byte)(i % Byte.MAX_VALUE); + } + return result; + } + + // Simple stub ImageResource for test purposes + static class BasicImageResource implements ImageResource { + + private final List entries; + private final byte[][] entryBytes; + + public BasicImageResource(List entries, byte[][] entryBytes) { + this.entries = entries; + this.entryBytes = entryBytes; + } + + @Override + public void close() throws Exception { + // nothing + } + + @Override + public List getEntries() { + return entries; + } + + @Override + public byte[] getResourceBytes(String name) { + for (int i = 0; i < entries.size(); i++) { + if (entries.get(i).equals(name)) { + return entryBytes[i]; + } + } + return null; + } + + @Override + public InputStream getResource(String name) { + byte[] bytes = getResourceBytes(name); + return new ByteArrayInputStream(bytes); + } + + } +} diff --git a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java index 6fdaf5a9824b8..8094579ecd505 100644 --- a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java +++ b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m KeepPackagedModulesFailTest + * @run main/othervm -Xmx1g KeepPackagedModulesFailTest */ public class KeepPackagedModulesFailTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java index 777ce302ce799..443cbbaec3c9d 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesExitTest + * @run main/othervm -Xmx1g ModifiedFilesExitTest */ public class ModifiedFilesExitTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java index c871024f37cfa..619c67e01b4b4 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m ModifiedFilesWarningTest + * @run main/othervm -Xmx1g ModifiedFilesWarningTest */ public class ModifiedFilesWarningTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java index 0e2cabe7425c8..88f91f238bd87 100644 --- a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java +++ b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m MultiHopTest + * @run main/othervm -Xmx1g MultiHopTest */ public class MultiHopTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java index d276e80702b40..ef7030d2e62fa 100644 --- a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java @@ -49,7 +49,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm/timeout=1200 -Xmx1400m PackagedModulesVsRuntimeImageLinkTest + * @run main/othervm/timeout=1200 -Xmx1g PackagedModulesVsRuntimeImageLinkTest */ public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest { @@ -76,7 +76,6 @@ void runTest(Helper helper, boolean isLinkableRuntime) throws Exception { .output(helper.createNewImageDir("java-se-jmodfull")) .addMods("java.se").call().assertSuccess(); - System.out.println("Now comparing jmod-less and jmod-full) images"); compareRecursively(javaSEruntimeLink, javaSEJmodFull); } diff --git a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java index d4654ec98bdc3..81579e0754bca 100644 --- a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m PatchedJDKModuleJlinkTest + * @run main/othervm -Xmx1g PatchedJDKModuleJlinkTest */ public class PatchedJDKModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java index d0a6234eec0ce..fac8cac112d14 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest + * @run main/othervm -Xmx1g SystemModulesTest */ public class SystemModulesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java index ee22a55f3a751..6be4ad7321cea 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1400m SystemModulesTest2 + * @run main/othervm -Xmx1g SystemModulesTest2 */ public class SystemModulesTest2 extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jpackage/TEST.properties b/test/jdk/tools/jpackage/TEST.properties index a34532d6695c6..78f5fc88bc32d 100644 --- a/test/jdk/tools/jpackage/TEST.properties +++ b/test/jdk/tools/jpackage/TEST.properties @@ -14,4 +14,5 @@ exclusiveAccess.dirs=share windows modules=jdk.jpackage/jdk.jpackage.internal:+open \ jdk.jpackage/jdk.jpackage.internal.util \ jdk.jpackage/jdk.jpackage.internal.util.function \ - java.base/jdk.internal.util + java.base/jdk.internal.util \ + jdk.jlink/jdk.tools.jlink.internal diff --git a/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java b/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java index b599488b563f1..ff471f6b91934 100644 --- a/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java +++ b/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,7 @@ * questions. */ -import java.io.File; import java.io.IOException; -import java.nio.file.Path; public class ChildProcessAppLauncher { public static void main(String[] args) throws IOException, InterruptedException { diff --git a/test/jdk/tools/jpackage/apps/PrintEnv.java b/test/jdk/tools/jpackage/apps/PrintEnv.java index 251138b23888c..bb1cef800f490 100644 --- a/test/jdk/tools/jpackage/apps/PrintEnv.java +++ b/test/jdk/tools/jpackage/apps/PrintEnv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,12 @@ * questions. */ -import java.util.List; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReference; import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; public class PrintEnv { @@ -41,6 +45,11 @@ private static List printArgs(String[] args) { } else if (arg.startsWith(PRINT_SYS_PROP)) { String name = arg.substring(PRINT_SYS_PROP.length()); lines.add(name + "=" + System.getProperty(name)); + } else if (arg.startsWith(PRINT_MODULES)) { + lines.add(ModuleFinder.ofSystem().findAll().stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .collect(Collectors.joining(","))); } else { throw new IllegalArgumentException(); } @@ -51,4 +60,5 @@ private static List printArgs(String[] args) { private final static String PRINT_ENV_VAR = "--print-env-var="; private final static String PRINT_SYS_PROP = "--print-sys-prop="; + private final static String PRINT_MODULES = "--print-modules"; } diff --git a/test/jdk/tools/jpackage/helpers-test/TEST.properties b/test/jdk/tools/jpackage/helpers-test/TEST.properties new file mode 100644 index 0000000000000..1830ea05443bd --- /dev/null +++ b/test/jdk/tools/jpackage/helpers-test/TEST.properties @@ -0,0 +1,9 @@ +JUnit.dirs = . + +lib.dirs = /test/jdk/tools/jpackage/helpers /test/jdk/tools/jpackage/helpers-test + +modules=jdk.jpackage/jdk.jpackage.internal:+open \ + jdk.jpackage/jdk.jpackage.internal.util:+open \ + jdk.jpackage/jdk.jpackage.internal.util.function:+open \ + java.base/jdk.internal.util \ + jdk.jlink/jdk.tools.jlink.internal diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java index 230b14fd1eac4..fdbd30ac7e9e2 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,9 @@ package jdk.jpackage.test; import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; +import static java.util.stream.Collectors.toMap; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; + import java.lang.reflect.Method; import java.nio.file.Path; import java.time.LocalDate; @@ -32,35 +35,34 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import static java.util.stream.Collectors.toMap; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; -import static jdk.internal.util.OperatingSystem.LINUX; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; -/* - * @test - * @summary Test jpackage test library's annotation processor - * @library /test/jdk/tools/jpackage/helpers - * @build jdk.jpackage.test.* - * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.AnnotationsTest - */ -public class AnnotationsTest { - - public static void main(String... args) { - runTests(BasicTest.class, ParameterizedInstanceTest.class); - for (var os : OperatingSystem.values()) { - try { - TestBuilderConfig.setOperatingSystem(os); - TKit.log("Current operating system: " + os); - runTests(IfOSTest.class); - } finally { - TestBuilderConfig.setDefaults(); - } +public class AnnotationsTest extends JUnitAdapter { + + @ParameterizedTest + @ValueSource(classes = {BasicTest.class, ParameterizedInstanceTest.class}) + public void test(Class clazz, @TempDir Path workDir) { + runTest(clazz, workDir); + } + + @ParameterizedTest + @EnumSource(OperatingSystem.class) + public void testIfOSTest(OperatingSystem os, @TempDir Path workDir) { + try { + TestBuilderConfig.setOperatingSystem(os); + TKit.log("Current operating system: " + os); + runTest(IfOSTest.class, workDir); + } finally { + TestBuilderConfig.setDefaults(); } } @@ -100,6 +102,12 @@ public void testDates(LocalDate v) { recordTestCase(v); } + @Test + @ParameterSupplier + public void testDates2(LocalDate v) { + recordTestCase(v); + } + public static Set getExpectedTestDescs() { return Set.of( "().testNoArg()", @@ -113,7 +121,9 @@ public static Set getExpectedTestDescs() { "().testDates(2018-05-05)", "().testDates(2018-07-11)", "().testDates(2034-05-05)", - "().testDates(2056-07-11)" + "().testDates(2056-07-11)", + "().testDates2(2028-05-05)", + "().testDates2(2028-07-11)" ); } @@ -123,6 +133,20 @@ public static Collection dateSupplier() { { LocalDate.parse("2018-07-11") }, }); } + + public static Collection testDates2() { + return List.of(new Object[][] { + { LocalDate.parse("2028-05-05") }, + { LocalDate.parse("2028-07-11") }, + }); + } + + public static void testDates2(Object unused) { + } + + public int testNoArg(int v) { + return 0; + } } public static class ParameterizedInstanceTest extends TestExecutionRecorder { @@ -301,29 +325,39 @@ public static Collection dateSupplier() { }); } - private static void runTests(Class... tests) { + private static void runTest(Class test, Path workDir) { ACTUAL_TEST_DESCS.get().clear(); - var expectedTestDescs = Stream.of(tests) - .map(AnnotationsTest::getExpectedTestDescs) - .flatMap(x -> x) + var expectedTestDescs = getExpectedTestDescs(test) // Collect in the map to check for collisions for free .collect(toMap(x -> x, x -> "")) .keySet(); - var args = Stream.of(tests).map(test -> { - return String.format("--jpt-run=%s", test.getName()); - }).toArray(String[]::new); + var args = new String[] { String.format("--jpt-run=%s", test.getName()) }; + final List log; try { - Main.main(args); + log = captureJPackageTestLog(() -> Main.main(TestBuilder.build().workDirRoot(workDir), args)); assertRecordedTestDescs(expectedTestDescs); } catch (Throwable t) { t.printStackTrace(System.err); System.exit(1); + + // Redundant, but needed to suppress "The local variable log may not have been initialized" error. + throw new RuntimeException(t); + } + + final var actualTestCount = Integer.parseInt(log.stream().dropWhile(line -> { + return !(line.startsWith("[==========]") && line.endsWith("tests ran")); + }).findFirst().orElseThrow().split(" ")[1]); + + if (actualTestCount != expectedTestDescs.size()) { + throw new AssertionError(String.format( + "Expected %d executed tests. Actual %d executed tests", expectedTestDescs.size(), actualTestCount)); } } + @SuppressWarnings("unchecked") private static Stream getExpectedTestDescs(Class type) { return toSupplier(() -> { var method = type.getMethod("getExpectedTestDescs"); diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/DirectoryContentVerifierTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/DirectoryContentVerifierTest.java index 79af67d3e9a3e..ea69a525df929 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/DirectoryContentVerifierTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/DirectoryContentVerifierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,11 @@ */ package jdk.jpackage.test; -import java.io.IOException; +import static java.util.stream.Collectors.toSet; +import static jdk.jpackage.test.DirectoryContentVerifierTest.AssertType.CONTAINS; +import static jdk.jpackage.test.DirectoryContentVerifierTest.AssertType.MATCH; +import static jdk.jpackage.test.TKit.assertAssert; + import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -30,16 +34,12 @@ import java.util.List; import java.util.Set; import java.util.function.BiConsumer; -import static java.util.stream.Collectors.toSet; import java.util.stream.Stream; -import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; -import static jdk.jpackage.test.DirectoryContentVerifierTest.AssertType.CONTAINS; -import static jdk.jpackage.test.DirectoryContentVerifierTest.AssertType.MATCH; import jdk.jpackage.test.TKit.DirectoryContentVerifier; -import static jdk.jpackage.test.TKit.assertAssert; -public class DirectoryContentVerifierTest { +public class DirectoryContentVerifierTest extends JUnitAdapter { enum AssertType { MATCH(DirectoryContentVerifier::match), @@ -105,8 +105,7 @@ ArgsBuilder expectFail() { private boolean success = true; } - @Parameters - public static Collection input() { + public static Collection input() { List data = new ArrayList<>(); buildArgs().applyVariantsTo(data); buildArgs().actualPaths("foo").assertOp(CONTAINS).applyTo(data); @@ -127,35 +126,23 @@ public static Collection input() { return data; } - public DirectoryContentVerifierTest(String[] expectedPaths, String[] actualPaths, - AssertType assertOp, Boolean success) { - this.expectedPaths = conv(expectedPaths); - this.actualPaths = conv(actualPaths); - this.assertOp = assertOp; - this.success = success; - } - @Test - public void test() { - TKit.withTempDirectory("basedir", this::test); - } - - private void test(Path basedir) throws IOException { - for (var path : actualPaths) { - Files.createFile(basedir.resolve(path)); - } + @ParameterSupplier("input") + public void test(String[] expectedPaths, String[] actualPaths, AssertType assertOp, Boolean success) { + final var expectedPathsAsSet = conv(expectedPaths); + final var actualPathsAsSet = conv(actualPaths); + TKit.withTempDirectory("basedir", basedir -> { + for (var path : actualPathsAsSet) { + Files.createFile(basedir.resolve(path)); + } - var testee = TKit.assertDirectoryContent(basedir); + var testee = TKit.assertDirectoryContent(basedir); - assertAssert(success, () -> assertOp.assertFunc.accept(testee, expectedPaths)); + assertAssert(success, () -> assertOp.assertFunc.accept(testee, expectedPathsAsSet)); + }); } private static Set conv(String... paths) { return Stream.of(paths).map(Path::of).collect(toSet()); } - - private final Set expectedPaths; - private final Set actualPaths; - private final AssertType assertOp; - private final boolean success; } diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java new file mode 100644 index 0000000000000..7bf1f57a25494 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.List; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +public class JUnitAdapter { + + JUnitAdapter() { + if (System.getProperty("test.src") == null) { + // Was called by somebody else but not by jtreg + System.setProperty("test.src", Path.of("@@openJdkDir@@/test/jdk/tools/jpackage").toString()); + } + } + + @Test + void runJPackageTests(@TempDir Path workDir) throws Throwable { + if (!getClass().equals(JUnitAdapter.class)) { + Main.main(TestBuilder.build().workDirRoot(workDir), new String [] { + "--jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault", + "--jpt-run=" + getClass().getName() + }); + } + } + + static List captureJPackageTestLog(ThrowingRunnable runnable) { + final var buf = new ByteArrayOutputStream(); + try (PrintStream ps = new PrintStream(buf, true, StandardCharsets.UTF_8)) { + TKit.withExtraLogStream(runnable, ps); + } + + try (final var in = new ByteArrayInputStream(buf.toByteArray()); + final var reader = new InputStreamReader(in, StandardCharsets.UTF_8); + final var bufReader = new BufferedReader(reader)) { + return bufReader.lines().map(line -> { + // Skip timestamp + return line.substring(LOG_MSG_TIMESTAMP_LENGTH); + }).toList(); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + + private static final int LOG_MSG_TIMESTAMP_LENGTH = "[HH:mm:ss.SSS] ".length(); +} diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JavaAppDescTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JavaAppDescTest.java index a2cde44f00951..50f1992f79601 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JavaAppDescTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JavaAppDescTest.java @@ -26,18 +26,14 @@ import java.util.List; import java.util.function.UnaryOperator; import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Annotations.Parameters; -public class JavaAppDescTest { - - public JavaAppDescTest(JavaAppDesc expectedAppDesc, JavaAppDesc actualAppDesc) { - this.expectedAppDesc = expectedAppDesc; - this.actualAppDesc = actualAppDesc; - } +public class JavaAppDescTest extends JUnitAdapter { @Test - public void test() { + @ParameterSupplier("input") + public void test(JavaAppDesc expectedAppDesc, JavaAppDesc actualAppDesc) { TKit.assertEquals(expectedAppDesc.toString(), actualAppDesc.toString(), null); TKit.assertTrue(expectedAppDesc.equals(actualAppDesc), null); } @@ -53,7 +49,6 @@ public static void testClassFilePath(String... args) { appDesc).classFilePath().toString(), null); } - @Parameters public static List input() { return List.of(new Object[][] { createTestCase("", "hello.jar:Hello"), @@ -93,6 +88,4 @@ private static JavaAppDesc[] createTestCase(String appDesc, UnaryOperator assertTestsData() { List data = new ArrayList<>(); @@ -191,12 +185,9 @@ Builder withAutoExpectLogPrefix(boolean v) { } } - public TKitTest(MethodCallConfig methodCall) { - this.methodCall = methodCall; - } - @Test - public void test() { + @ParameterSupplier("assertTestsData") + public void test(MethodCallConfig methodCall) { runAssertWithExpectedLogOutput(() -> { methodCall.method.invoke(null, methodCall.args); }, methodCall.expectFail, methodCall.expectLog); @@ -211,23 +202,11 @@ private static void runAssertWithExpectedLogOutput(ThrowingRunnable action, private static void runWithExpectedLogOutput(ThrowingRunnable action, String... expectLogStrings) { - final var buf = new ByteArrayOutputStream(); - try (PrintStream ps = new PrintStream(buf, true, StandardCharsets.UTF_8)) { - TKit.withExtraLogStream(action, ps); - } finally { - toRunnable(() -> { - var output = new BufferedReader(new InputStreamReader( - new ByteArrayInputStream(buf.toByteArray()), - StandardCharsets.UTF_8)).lines().map(line -> { - // Skip timestamp - return line.substring(LOG_MSG_TIMESTAMP_LENGTH); - }).toList(); - if (output.size() == 1 && expectLogStrings.length == 1) { - TKit.assertEquals(expectLogStrings[0], output.get(0), null); - } else { - TKit.assertStringListEquals(List.of(expectLogStrings), output, null); - } - }).run(); + final var output = JUnitAdapter.captureJPackageTestLog(action); + if (output.size() == 1 && expectLogStrings.length == 1) { + TKit.assertEquals(expectLogStrings[0], output.get(0), null); + } else { + TKit.assertStringListEquals(List.of(expectLogStrings), output, null); } } @@ -237,8 +216,4 @@ private static String concatMessages(String msg, String msg2) { } return msg; } - - private final MethodCallConfig methodCall; - - private static final int LOG_MSG_TIMESTAMP_LENGTH = "[HH:mm:ss.SSS] ".length(); } diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TestSuite.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TestSuite.java deleted file mode 100644 index f9dda8514146d..0000000000000 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TestSuite.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code 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 - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jpackage.test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -/* - * @test - * @summary Unit tests for jpackage test library - * @library /test/jdk/tools/jpackage/helpers - * @library /test/jdk/tools/jpackage/helpers-test - * @build jdk.jpackage.test.* - * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.TestSuite - */ - -public final class TestSuite { - public static void main(String args[]) throws Throwable { - final var pkgName = TestSuite.class.getPackageName(); - final var javaSuffix = ".java"; - final var testSrcNameSuffix = "Test" + javaSuffix; - - final var unitTestDir = TKit.TEST_SRC_ROOT.resolve(Path.of("helpers-test", pkgName.split("\\."))); - - final List runTestArgs = new ArrayList<>(); - runTestArgs.addAll(List.of(args)); - - try (var javaSources = Files.list(unitTestDir)) { - runTestArgs.addAll(javaSources.filter(path -> { - return path.getFileName().toString().endsWith(testSrcNameSuffix); - }).map(path -> { - var filename = path.getFileName().toString(); - return String.join(".", pkgName, filename.substring(0, filename.length() - javaSuffix.length())); - }).map(testClassName -> { - return "--jpt-run=" + testClassName; - }).toList()); - } - - Main.main(runTestArgs.toArray(String[]::new)); - } -} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index 70b0e160d24cc..03914759f1662 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,10 +87,15 @@ public final AdditionalLauncher setLauncherAsService() { } public final AdditionalLauncher addRawProperties( - Map.Entry... v) { + Map.Entry v) { return addRawProperties(List.of(v)); } + public final AdditionalLauncher addRawProperties( + Map.Entry v, Map.Entry v2) { + return addRawProperties(List.of(v, v2)); + } + public final AdditionalLauncher addRawProperties( Collection> v) { rawProperties.addAll(v); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java index ad1e77b417152..4b6072c80b585 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java @@ -82,7 +82,7 @@ OperatingSystem[] ifOS() default { @Repeatable(ParameterSupplierGroup.class) public @interface ParameterSupplier { - String value(); + String value() default ""; OperatingSystem[] ifOS() default { OperatingSystem.LINUX, diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java index 23798f326fecf..84a9eb0288592 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,15 @@ import java.util.HashSet; import java.util.Set; -record Comm(Set common, Set unique1, Set unique2) { +public record Comm(Set common, Set unique1, Set unique2) { - static Comm compare(Set a, Set b) { + public static Comm compare(Set a, Set b) { Set common = new HashSet<>(a); common.retainAll(b); Set unique1 = new HashSet<>(a); unique1.removeAll(common); Set unique2 = new HashSet<>(b); unique2.removeAll(common); - return new Comm(common, unique1, unique2); + return new Comm(common, unique1, unique2); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java index 369ee337dc843..cb7f0574afde5 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CommandArguments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,17 +36,17 @@ public class CommandArguments { public final T clearArguments() { args.clear(); - return (T) this; + return thiz(); } public final T addArgument(String v) { args.add(v); - return (T) this; + return thiz(); } public final T addArguments(List v) { args.addAll(v); - return (T) this; + return thiz(); } public final T addArgument(Path v) { @@ -77,5 +77,10 @@ protected boolean isMutable() { return true; } + @SuppressWarnings("unchecked") + private T thiz() { + return (T) this; + } + protected List args; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index 7a0878d826b43..a8a849cb9e786 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -53,7 +54,6 @@ public static Executor of(String... cmdline) { public Executor() { saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE)); - removePathEnvVar = false; winEnglishOutput = false; } @@ -77,6 +77,10 @@ public Executor setToolProvider(JavaTool v) { return setToolProvider(v.asToolProvider()); } + public Optional getExecutable() { + return Optional.ofNullable(executable); + } + public Executor setDirectory(Path v) { directory = v; return this; @@ -86,8 +90,8 @@ public Executor setExecutable(JavaTool v) { return setExecutable(v.getPath()); } - public Executor setRemovePathEnvVar(boolean value) { - removePathEnvVar = value; + public Executor removeEnvVar(String envVarName) { + removeEnvVars.add(Objects.requireNonNull(envVarName)); return this; } @@ -174,10 +178,10 @@ public Executor dumpOutput(boolean v) { return this; } - public class Result { + public record Result(int exitCode, List output, Supplier cmdline) { - Result(int exitCode) { - this.exitCode = exitCode; + public Result { + Objects.requireNonNull(cmdline); } public String getFirstLineOfOutput() { @@ -188,14 +192,10 @@ public List getOutput() { return output; } - public String getPrintableCommandLine() { - return Executor.this.getPrintableCommandLine(); - } - public Result assertExitCodeIs(int expectedExitCode) { TKit.assertEquals(expectedExitCode, exitCode, String.format( "Check command %s exited with %d code", - getPrintableCommandLine(), expectedExitCode)); + cmdline.get(), expectedExitCode)); return this; } @@ -206,9 +206,6 @@ public Result assertExitCodeIsZero() { public int getExitCode() { return exitCode; } - - final int exitCode; - private List output; } public Result executeWithoutExitCodeCheck() { @@ -260,7 +257,8 @@ Result getValue() { return value; } - private final Result value; + private final transient Result value; + private static final long serialVersionUID = 1L; } /* @@ -372,10 +370,12 @@ private Result runExecutable() throws IOException, InterruptedException { builder.directory(directory.toFile()); sb.append(String.format("; in directory [%s]", directory)); } - if (removePathEnvVar) { - // run this with cleared Path in Environment - TKit.trace("Clearing PATH in environment"); - builder.environment().remove("PATH"); + if (!removeEnvVars.isEmpty()) { + final var envComm = Comm.compare(builder.environment().keySet(), removeEnvVars); + builder.environment().keySet().removeAll(envComm.common()); + envComm.common().forEach(envVar -> { + TKit.trace(String.format("Clearing %s in environment", envVar)); + }); } trace("Execute " + sb.toString() + "..."); @@ -406,28 +406,34 @@ private Result runExecutable() throws IOException, InterruptedException { } } - Result reply = new Result(process.waitFor()); - trace("Done. Exit code: " + reply.exitCode); + final int exitCode = process.waitFor(); + trace("Done. Exit code: " + exitCode); + final List output; if (outputLines != null) { - reply.output = Collections.unmodifiableList(outputLines); + output = Collections.unmodifiableList(outputLines); + } else { + output = null; } - return reply; + return createResult(exitCode, output); } - private Result runToolProvider(PrintStream out, PrintStream err) { + private int runToolProvider(PrintStream out, PrintStream err) { trace("Execute " + getPrintableCommandLine() + "..."); - Result reply = new Result(toolProvider.run(out, err, args.toArray( - String[]::new))); - trace("Done. Exit code: " + reply.exitCode); - return reply; + final int exitCode = toolProvider.run(out, err, args.toArray( + String[]::new)); + trace("Done. Exit code: " + exitCode); + return exitCode; } + private Result createResult(int exitCode, List output) { + return new Result(exitCode, output, this::getPrintableCommandLine); + } private Result runToolProvider() throws IOException { if (!withSavedOutput()) { if (saveOutputType.contains(SaveOutputType.DUMP)) { - return runToolProvider(System.out, System.err); + return createResult(runToolProvider(System.out, System.err), null); } PrintStream nullPrintStream = new PrintStream(new OutputStream() { @@ -436,36 +442,40 @@ public void write(int b) { // Nop } }); - return runToolProvider(nullPrintStream, nullPrintStream); + return createResult(runToolProvider(nullPrintStream, nullPrintStream), null); } try (ByteArrayOutputStream buf = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(buf)) { - Result reply = runToolProvider(ps, ps); + final var exitCode = runToolProvider(ps, ps); ps.flush(); + final List output; try (BufferedReader bufReader = new BufferedReader(new StringReader( buf.toString()))) { if (saveOutputType.contains(SaveOutputType.FIRST_LINE)) { String firstLine = bufReader.lines().findFirst().orElse(null); if (firstLine != null) { - reply.output = List.of(firstLine); + output = List.of(firstLine); + } else { + output = null; } } else if (saveOutputType.contains(SaveOutputType.FULL)) { - reply.output = bufReader.lines().collect( - Collectors.toUnmodifiableList()); + output = bufReader.lines().collect(Collectors.toUnmodifiableList()); + } else { + output = null; } if (saveOutputType.contains(SaveOutputType.DUMP)) { Stream lines; if (saveOutputType.contains(SaveOutputType.FULL)) { - lines = reply.output.stream(); + lines = output.stream(); } else { lines = bufReader.lines(); } lines.forEach(System.out::println); } } - return reply; + return createResult(exitCode, output); } } @@ -504,7 +514,7 @@ private static void trace(String msg) { private Path executable; private Set saveOutputType; private Path directory; - private boolean removePathEnvVar; + private Set removeEnvVars = new HashSet<>(); private boolean winEnglishOutput; private String winTmpDir = null; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java index 28b3574268142..44427d537543e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,18 +47,10 @@ public static Runnable identity(Runnable v) { return v; } - public static Function identity(Function v) { - return v; - } - public static Function identityFunction(Function v) { return v; } - public static Predicate identity(Predicate v) { - return v; - } - public static Predicate identityPredicate(Predicate v) { return v; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index 0c7476e863dc4..224a3f752cf3b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -351,16 +351,6 @@ public static final class AppOutputVerifier { this.outputFilePath = TKit.workDir().resolve(OUTPUT_FILENAME); this.params = new HashMap<>(); this.defaultLauncherArgs = new ArrayList<>(); - - if (TKit.isWindows()) { - // When running app launchers on Windows, clear users environment (JDK-8254920) - removePathEnvVar(true); - } - } - - public AppOutputVerifier removePathEnvVar(boolean v) { - removePathEnvVar = v; - return this; } public AppOutputVerifier saveOutput(boolean v) { @@ -403,7 +393,7 @@ public AppOutputVerifier addParams(Map v) { return addParams(v.entrySet()); } - public AppOutputVerifier addParams(Map.Entry... v) { + public AppOutputVerifier addParams(Map.Entry v) { return addParams(List.of(v)); } @@ -442,10 +432,7 @@ public Executor.Result execute(String... args) { if (launcherNoExit) { return getExecutor(args).executeWithoutExitCodeCheck(); } else { - final int attempts = 3; - final int waitBetweenAttemptsSeconds = 5; - return getExecutor(args).executeAndRepeatUntilExitCode(expectedExitCode, attempts, - waitBetweenAttemptsSeconds); + return HelloApp.execute(expectedExitCode, getExecutor(args)); } } @@ -472,18 +459,17 @@ private Executor getExecutor(String...args) { } } - final List launcherArgs = List.of(args); - return new Executor() + final var executor = new Executor() .setDirectory(outputFile.getParent()) .saveOutput(saveOutput) .dumpOutput() - .setRemovePathEnvVar(removePathEnvVar) .setExecutable(executablePath) - .addArguments(launcherArgs); + .addArguments(List.of(args)); + + return configureEnvironment(executor); } private boolean launcherNoExit; - private boolean removePathEnvVar; private boolean saveOutput; private final Path launcherPath; private Path outputFilePath; @@ -496,6 +482,29 @@ public static AppOutputVerifier assertApp(Path helloAppLauncher) { return new AppOutputVerifier(helloAppLauncher); } + public static Executor.Result configureAndExecute(int expectedExitCode, Executor executor) { + return execute(expectedExitCode, configureEnvironment(executor)); + } + + private static Executor.Result execute(int expectedExitCode, Executor executor) { + if (TKit.isLinux()) { + final int attempts = 3; + final int waitBetweenAttemptsSeconds = 5; + return executor.executeAndRepeatUntilExitCode(expectedExitCode, attempts, + waitBetweenAttemptsSeconds); + } else { + return executor.execute(expectedExitCode); + } + } + + private static Executor configureEnvironment(Executor executor) { + if (CLEAR_JAVA_ENV_VARS) { + executor.removeEnvVar("JAVA_TOOL_OPTIONS"); + executor.removeEnvVar("_JAVA_OPTIONS"); + } + return executor; + } + static final String OUTPUT_FILENAME = "appOutput.txt"; private final JavaAppDesc appDesc; @@ -505,4 +514,7 @@ public static AppOutputVerifier assertApp(Path helloAppLauncher) { private static final String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( "\\.", 2)[0]; + + private static final boolean CLEAR_JAVA_ENV_VARS = Optional.ofNullable( + TKit.getConfigProperty("clear-app-launcher-java-env-vars")).map(Boolean::parseBoolean).orElse(false); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 68f26bfb261f1..418d7377ec637 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * anything. The simplest is to compile test application and pack in a jar for * use on jpackage command line. */ -public final class JPackageCommand extends CommandArguments { +public class JPackageCommand extends CommandArguments { public JPackageCommand() { prerequisiteActions = new Actions(); @@ -593,7 +593,7 @@ public Path appLauncherCfgPath(String launcherName) { } public boolean isFakeRuntime(String msg) { - if (isFakeRuntime()) { + if (isFakeRuntime(appRuntimeDirectory())) { // Fake runtime Path runtimeDir = appRuntimeDirectory(); TKit.trace(String.format( @@ -604,7 +604,7 @@ public boolean isFakeRuntime(String msg) { return false; } - private boolean isFakeRuntime() { + private static boolean isFakeRuntime(Path runtimeDir) { final Collection criticalRuntimeFiles; if (TKit.isWindows()) { criticalRuntimeFiles = WindowsHelper.CRITICAL_RUNTIME_FILES; @@ -616,7 +616,6 @@ private boolean isFakeRuntime() { throw TKit.throwUnknownPlatformError(); } - Path runtimeDir = appRuntimeDirectory(); return !criticalRuntimeFiles.stream().map(runtimeDir::resolve).allMatch( Files::exists); } @@ -690,10 +689,8 @@ public JPackageCommand ignoreDefaultRuntime(boolean v) { } public JPackageCommand ignoreFakeRuntime() { - if (isFakeRuntime()) { - ignoreDefaultRuntime(true); - } - return this; + return ignoreDefaultRuntime(Optional.ofNullable(DEFAULT_RUNTIME_IMAGE) + .map(JPackageCommand::isFakeRuntime).orElse(false)); } public JPackageCommand ignoreDefaultVerbose(boolean v) { @@ -802,7 +799,7 @@ public Executor.Result execute(int expectedExitCode) { outputValidator.accept(result.getOutput().stream()); } - if (result.exitCode == 0) { + if (result.exitCode() == 0) { executeVerifyActions(); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java index 39e483f1feeb3..05510461c1657 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,7 +264,7 @@ private void setIcon(Path iconPath, Path launcherPath) { static final WinIconVerifier instance = new WinIconVerifier(); - private final Class executableRebranderClass; + private final Class executableRebranderClass; private final Method lockResource; private final Method unlockResource; private final Method iconSwapWrapper; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index ddbbee4aa6075..f97b695d98f37 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public final class LinuxHelper { private static String getReleaseSuffix(JPackageCommand cmd) { - String value = null; + final String value; final PackageType packageType = cmd.packageType(); switch (packageType) { case LINUX_DEB: @@ -60,6 +60,9 @@ private static String getReleaseSuffix(JPackageCommand cmd) { value = "-" + cmd.getArgumentValue("--linux-app-release", () -> "1"); break; + + default: + value = null; } return value; } @@ -95,7 +98,7 @@ static String getBundleName(JPackageCommand cmd) { cmd.verifyIsOfType(PackageType.LINUX); final PackageType packageType = cmd.packageType(); - String format = null; + final String format; switch (packageType) { case LINUX_DEB: format = "%s_%s%s_%s"; @@ -104,6 +107,9 @@ static String getBundleName(JPackageCommand cmd) { case LINUX_RPM: format = "%s-%s%s.%s"; break; + + default: + throw new UnsupportedOperationException(); } final String releaseSuffix = getReleaseSuffix(cmd); @@ -119,7 +125,7 @@ public static Stream getPackageFiles(JPackageCommand cmd) { final PackageType packageType = cmd.packageType(); final Path packageFile = cmd.outputBundle(); - Executor exec = null; + final Executor exec; switch (packageType) { case LINUX_DEB: exec = Executor.of("dpkg", "--contents").addArgument(packageFile); @@ -128,6 +134,9 @@ public static Stream getPackageFiles(JPackageCommand cmd) { case LINUX_RPM: exec = Executor.of("rpm", "-qpl").addArgument(packageFile); break; + + default: + throw new UnsupportedOperationException(); } Stream lines = exec.executeAndGetOutput().stream(); @@ -154,9 +163,10 @@ public static List getPrerequisitePackages(JPackageCommand cmd) { return Executor.of("rpm", "-qp", "-R") .addArgument(cmd.outputBundle()) .executeAndGetOutput(); + + default: + throw new UnsupportedOperationException(); } - // Unreachable - return null; } public static String getBundleProperty(JPackageCommand cmd, @@ -178,9 +188,10 @@ public static String getBundleProperty(JPackageCommand cmd, case LINUX_RPM: return getRpmBundleProperty(cmd.outputBundle(), propertyName.get( packageType)); + + default: + throw new UnsupportedOperationException(); } - // Unrechable - return null; } static PackageHandlers createDebPackageHandlers() { @@ -275,9 +286,9 @@ static long getInstalledPackageSizeKB(JPackageCommand cmd) { String size = getRpmBundleProperty(packageFile, "Size"); return (Long.parseLong(size) + 1023L) >> 10; // in KB rounded up + default: + throw new UnsupportedOperationException(); } - - return 0; } static String getDebBundleProperty(Path bundle, String fieldName) { @@ -425,7 +436,7 @@ private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile) return null; })); - final Set mandatoryKeys = new HashSet(Set.of("Name", "Comment", + final Set mandatoryKeys = new HashSet<>(Set.of("Name", "Comment", "Exec", "Icon", "Terminal", "Type", "Categories")); mandatoryKeys.removeAll(data.keySet()); TKit.assertTrue(mandatoryKeys.isEmpty(), String.format( @@ -626,10 +637,10 @@ private static Map> getScriptlets( case LINUX_RPM: return getRpmScriptlets(cmd, scriptletSet); - } - // Unreachable - return null; + default: + throw new UnsupportedOperationException(); + } } private static Map> getDebScriptlets( @@ -703,7 +714,7 @@ public static String getDefaultPackageArch(PackageType type) { String arch = archs.get(type); if (arch == null) { - Executor exec = null; + final Executor exec; switch (type) { case LINUX_DEB: exec = Executor.of("dpkg", "--print-architecture"); @@ -712,6 +723,9 @@ public static String getDefaultPackageArch(PackageType type) { case LINUX_RPM: exec = Executor.of("rpmbuild", "--eval=%{_target_cpu}"); break; + + default: + throw new UnsupportedOperationException(); } arch = exec.executeAndGetFirstLineOfOutput(); archs.put(type, arch); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index 9cadd419ca135..2256963999aec 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -367,7 +367,7 @@ public List queryArrayValue(String keyName) { } NodeList childList = list.item(0).getChildNodes(); - List values = new ArrayList(childList.getLength()); + List values = new ArrayList<>(childList.getLength()); for (int i = 0; i < childList.getLength(); i++) { if (childList.item(i).getNodeName().equals("string")) { values.add(childList.item(i).getTextContent()); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java index 5919d8361c432..439479a666ec0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java @@ -38,10 +38,15 @@ public final class Main { + public static void main(String args[]) throws Throwable { + main(TestBuilder.build(), args); + } + + public static void main(TestBuilder.Builder builder, String args[]) throws Throwable { boolean listTests = false; List tests = new ArrayList<>(); - try (TestBuilder testBuilder = new TestBuilder(tests::add)) { + try (TestBuilder testBuilder = builder.testConsumer(tests::add).create()) { Deque argsAsList = new ArrayDeque<>(List.of(args)); while (!argsAsList.isEmpty()) { var arg = argsAsList.pop(); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java index 51a8ade8a1d64..73d0a7fe495e4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.TestInstance.TestDesc; -class MethodCall implements ThrowingConsumer { +class MethodCall implements ThrowingConsumer { MethodCall(Object[] instanceCtorArgs, Method method, Object ... args) { Objects.requireNonNull(instanceCtorArgs); @@ -90,7 +90,7 @@ void checkRequiredConstructor() throws NoSuchMethodException { } } - private static Constructor findMatchingConstructor(Class type, Object... ctorArgs) + private static Constructor findMatchingConstructor(Class type, Object... ctorArgs) throws NoSuchMethodException { var ctors = filterMatchingExecutablesForParameterValues(Stream.of( @@ -114,6 +114,7 @@ public void accept(Object thiz) throws Throwable { private static Object[] mapVarArgs(Executable executable, final Object ... args) { if (executable.isVarArgs()) { var paramTypes = executable.getParameterTypes(); + @SuppressWarnings("rawtypes") Class varArgParamType = paramTypes[paramTypes.length - 1]; Object[] newArgs; @@ -124,6 +125,7 @@ private static Object[] mapVarArgs(Executable executable, final Object ... args) newArgs = Arrays.copyOf(args, args.length + 1, Object[].class); newArgs[newArgs.length - 1] = Array.newInstance(varArgParamType.componentType(), 0); } else { + @SuppressWarnings("unchecked") var varArgs = Arrays.copyOfRange(args, paramTypes.length - 1, args.length, varArgParamType); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index fd6d5e2da6bc7..f89bd0a60c82c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -446,6 +446,7 @@ public void accept(Action action) throws Throwable { case UNINSTALL: skip = (action == Action.VERIFY_UNINSTALL); break; + default: // NOP } } @@ -616,6 +617,8 @@ public void accept(Action action, JPackageCommand cmd) { } } break; + + default: // NOP } } @@ -702,6 +705,10 @@ private void verifyRootCountInUnpackedPackage(JPackageCommand cmd, roots.add(Path.of("/usr")); } } + + default -> { + throw new UnsupportedOperationException(); + } } } expectedRootCount = roots.size(); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java index 8aa7d005adbd3..4d85f82df9b17 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,7 @@ static PackageType fromSuffix(String packageFilename) { private static boolean isBundlerSupportedImpl(String bundlerClass) { try { - Class clazz = Class.forName(bundlerClass); + Class clazz = Class.forName(bundlerClass); Method supported = clazz.getMethod("supported", boolean.class); return ((Boolean) supported.invoke( clazz.getConstructor().newInstance(), true)); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index b58595645682c..d3473952cf8d0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -250,11 +250,6 @@ public static void traceFileContents(Path path, String label) throws IOException trace("Done"); } - public static void createPropertiesFile(Path propsFilename, - Map.Entry... props) { - createPropertiesFile(propsFilename, List.of(props)); - } - public static void createPropertiesFile(Path propsFilename, Map props) { createPropertiesFile(propsFilename, props.entrySet()); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java index 23fd5dd52a508..db4810ce5e2e2 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,13 @@ package jdk.jpackage.test; +import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; +import static jdk.jpackage.test.TestMethodSupplier.MethodQuery.fromQualifiedMethodName; + +import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; @@ -37,24 +42,49 @@ import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.test.Annotations.AfterEach; import jdk.jpackage.test.Annotations.BeforeEach; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.internal.util.function.ThrowingConsumer; -import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; -import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.test.TestMethodSupplier.InvalidAnnotationException; -import static jdk.jpackage.test.TestMethodSupplier.MethodQuery.fromQualifiedMethodName; final class TestBuilder implements AutoCloseable { @Override - public void close() throws Exception { + public void close() { flushTestGroup(); } - TestBuilder(Consumer testConsumer) { + static Builder build() { + return new Builder(); + } + + final static class Builder { + private Builder() { + } + + Builder testConsumer(Consumer v) { + testConsumer = v; + return this; + } + + Builder workDirRoot(Path v) { + workDirRoot = v; + return this; + } + + TestBuilder create() { + return new TestBuilder(testConsumer, workDirRoot); + } + + private Consumer testConsumer; + private Path workDirRoot = Path.of(""); + } + + private TestBuilder(Consumer testConsumer, Path workDirRoot) { this.testMethodSupplier = TestBuilderConfig.getDefault().createTestMethodSupplier(); + this.workDirRoot = Objects.requireNonNull(workDirRoot); argProcessors = Map.of( CMDLINE_ARG_PREFIX + "after-run", arg -> getJavaMethodsFromArg(arg).map( @@ -87,7 +117,7 @@ public void close() throws Exception { CMDLINE_ARG_PREFIX + "dry-run", arg -> dryRun = true ); - this.testConsumer = testConsumer; + this.testConsumer = Objects.requireNonNull(testConsumer); clear(); } @@ -168,8 +198,8 @@ private void flushTestGroup() { } private void createTestInstance(MethodCall testBody) { - final List curBeforeActions; - final List curAfterActions; + final List> curBeforeActions; + final List> curAfterActions; Method testMethod = testBody.getMethod(); if (Stream.of(BeforeEach.class, AfterEach.class).anyMatch( @@ -187,7 +217,7 @@ private void createTestInstance(MethodCall testBody) { } TestInstance test = new TestInstance(testBody, curBeforeActions, - curAfterActions, dryRun); + curAfterActions, dryRun, workDirRoot); if (includedTests == null) { trace(String.format("Create: %s", test.fullName())); } @@ -203,7 +233,7 @@ private void clear() { testGroup = null; } - private static Class probeClass(String name) { + private static Class probeClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException ex) { @@ -211,7 +241,7 @@ private static Class probeClass(String name) { } } - private static Stream selectFrameMethods(Class type, Class annotationType) { + private static Stream selectFrameMethods(Class type, Class annotationType) { return Stream.of(type.getMethods()) .filter(m -> m.getParameterCount() == 0) .filter(m -> !m.isAnnotationPresent(Test.class)) @@ -219,11 +249,12 @@ private static Stream selectFrameMethods(Class type, Class annotationTyp .sorted(Comparator.comparing(Method::getName)); } - private Stream cmdLineArgValueToMethodNames(String v) { - List result = new ArrayList<>(); + private Stream getJavaMethodsFromArg(String argValue) { + final List methods = new ArrayList<>(); + String defaultClassName = null; - for (String token : v.split(",")) { - Class testSet = probeClass(token); + for (String token : argValue.split(",")) { + Class testSet = probeClass(token); if (testSet != null) { if (testMethodSupplier.isTestClass(testSet)) { toConsumer(testMethodSupplier::verifyTestClass).accept(testSet); @@ -233,11 +264,9 @@ private Stream cmdLineArgValueToMethodNames(String v) { // from the class with @Test annotation removing name duplicates. // Overloads will be handled at the next phase of processing. defaultClassName = token; - result.addAll(Stream.of(testSet.getMethods()) + methods.addAll(Stream.of(testSet.getMethods()) .filter(m -> m.isAnnotationPresent(Test.class)) .filter(testMethodSupplier::isEnabled) - .map(Method::getName).distinct() - .map(name -> String.join(".", token, name)) .toList()); continue; @@ -253,9 +282,11 @@ private Stream cmdLineArgValueToMethodNames(String v) { } else { qualifiedMethodName = String.join(".", defaultClassName, token); } - result.add(qualifiedMethodName); + methods.addAll(getJavaMethodFromString(qualifiedMethodName)); } - return result.stream(); + + trace(String.format("%s -> %s", argValue, methods)); + return methods.stream(); } private List getJavaMethodFromString(String qualifiedMethodName) { @@ -272,14 +303,6 @@ private List getJavaMethodFromString(String qualifiedMethodName) { } } - private Stream getJavaMethodsFromArg(String argValue) { - var methods = cmdLineArgValueToMethodNames(argValue) - .map(this::getJavaMethodFromString) - .flatMap(List::stream).toList(); - trace(String.format("%s -> %s", argValue, methods)); - return methods.stream(); - } - private Stream toMethodCalls(Method method) throws IllegalAccessException, InvocationTargetException, InvalidAnnotationException { return testMethodSupplier.mapToMethodCalls(method).peek(methodCall -> { @@ -295,10 +318,10 @@ private Stream toMethodCalls(Method method) throws }); } - // Wraps Method.invike() into ThrowingRunnable.run() - private ThrowingConsumer wrap(Method method) { + // Wraps Method.invoke() into ThrowingRunnable.run() + private ThrowingConsumer wrap(Method method) { return (test) -> { - Class methodClass = method.getDeclaringClass(); + Class methodClass = method.getDeclaringClass(); String methodName = String.join(".", methodClass.getName(), method.getName()); TKit.log(String.format("[ CALL ] %s()", methodName)); @@ -335,6 +358,7 @@ public String getMessage() { return msg; } private String badCmdLineArg; + private static final long serialVersionUID = 1L; } static void trace(String msg) { @@ -346,9 +370,10 @@ static void trace(String msg) { private final TestMethodSupplier testMethodSupplier; private final Map> argProcessors; private final Consumer testConsumer; + private final Path workDirRoot; private List testGroup; - private List beforeActions; - private List afterActions; + private List> beforeActions; + private List> afterActions; private Set excludedTests; private Set includedTests; private String spaceSubstitute; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java index 871ddc2427784..ca9523d576067 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,13 +144,13 @@ static TestDesc create(Method m, Object... args) { return desc; } - private Class clazz; + private Class clazz; private String functionName; private String functionArgs; private String instanceArgs; } - TestInstance(ThrowingRunnable testBody) { + TestInstance(ThrowingRunnable testBody, Path workDirRoot) { assertCount = 0; this.testConstructor = (unused) -> null; this.testBody = (unused) -> testBody.run(); @@ -158,11 +158,11 @@ static TestDesc create(Method m, Object... args) { this.afterActions = Collections.emptyList(); this.testDesc = TestDesc.createBuilder().get(); this.dryRun = false; - this.workDir = createWorkDirName(testDesc); + this.workDir = workDirRoot.resolve(createWorkDirPath(testDesc)); } - TestInstance(MethodCall testBody, List beforeActions, - List afterActions, boolean dryRun) { + TestInstance(MethodCall testBody, List> beforeActions, + List> afterActions, boolean dryRun, Path workDirRoot) { assertCount = 0; this.testConstructor = v -> ((MethodCall)v).newInstance(); this.testBody = testBody; @@ -170,7 +170,7 @@ static TestDesc create(Method m, Object... args) { this.afterActions = afterActions; this.testDesc = testBody.createDescription(); this.dryRun = dryRun; - this.workDir = createWorkDirName(testDesc); + this.workDir = workDirRoot.resolve(createWorkDirPath(testDesc)); } void notifyAssert() { @@ -255,7 +255,7 @@ public void run() throws Throwable { } } - private static Class enclosingMainMethodClass() { + private static Class enclosingMainMethodClass() { StackTraceElement st[] = Thread.currentThread().getStackTrace(); for (StackTraceElement ste : st) { if ("main".equals(ste.getMethodName())) { @@ -276,8 +276,8 @@ private static boolean isCalledByJavatest() { return false; } - private static Path createWorkDirName(TestDesc testDesc) { - Path result = Path.of("."); + private static Path createWorkDirPath(TestDesc testDesc) { + Path result = Path.of(""); if (!isCalledByJavatest()) { result = result.resolve(testDesc.clazz.getSimpleName()); } @@ -323,10 +323,10 @@ public String toString() { private Status status; private RuntimeException skippedTestException; private final TestDesc testDesc; - private final ThrowingFunction testConstructor; - private final ThrowingConsumer testBody; - private final List beforeActions; - private final List afterActions; + private final ThrowingFunction, Object> testConstructor; + private final ThrowingConsumer testBody; + private final List> beforeActions; + private final List> afterActions; private final boolean dryRun; private final Path workDir; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java index 0d701d0ec6f55..8b92ae7ca462e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ final class TestMethodSupplier { record MethodQuery(String className, String methodName) { List lookup() throws ClassNotFoundException { - final Class methodClass = Class.forName(className); + final Class methodClass = Class.forName(className); // Get the list of all public methods as need to deal with overloads. return Stream.of(methodClass.getMethods()).filter(method -> { @@ -256,12 +256,17 @@ private List createArgsForAnnotation(Executable exec, } final Class execClass = exec.getDeclaringClass(); - final var supplierFuncName = a.value(); + final String supplierFuncName; + if (a.value().isEmpty()) { + supplierFuncName = exec.getName(); + } else { + supplierFuncName = a.value(); + } final MethodQuery methodQuery; - if (!a.value().contains(".")) { + if (!supplierFuncName.contains(".")) { // No class name specified - methodQuery = new MethodQuery(execClass.getName(), a.value()); + methodQuery = new MethodQuery(execClass.getName(), supplierFuncName); } else { methodQuery = MethodQuery.fromQualifiedMethodName(supplierFuncName); } @@ -269,7 +274,7 @@ private List createArgsForAnnotation(Executable exec, final Method supplierMethod; try { final var parameterSupplierCandidates = findNullaryLikeMethods(methodQuery); - final Function classForName = toFunction(Class::forName); + final Function> classForName = toFunction(Class::forName); final var supplierMethodClass = classForName.apply(methodQuery.className()); if (parameterSupplierCandidates.isEmpty()) { throw new RuntimeException(String.format( @@ -348,11 +353,11 @@ private static boolean canRunOnTheOperatingSystem(OperatingSystem value, private static Parameter[] getMethodParameters(Method method) { if (method.isAnnotationPresent(ParameterGroup.class)) { - return ((ParameterGroup) method.getAnnotation(ParameterGroup.class)).value(); + return method.getAnnotation(ParameterGroup.class).value(); } if (method.isAnnotationPresent(Parameter.class)) { - return new Parameter[]{(Parameter) method.getAnnotation(Parameter.class)}; + return new Parameter[]{method.getAnnotation(Parameter.class)}; } return new Parameter[0]; @@ -360,12 +365,11 @@ private static Parameter[] getMethodParameters(Method method) { private static ParameterSupplier[] getMethodParameterSuppliers(Method method) { if (method.isAnnotationPresent(ParameterSupplierGroup.class)) { - return ((ParameterSupplierGroup) method.getAnnotation(ParameterSupplierGroup.class)).value(); + return (method.getAnnotation(ParameterSupplierGroup.class)).value(); } if (method.isAnnotationPresent(ParameterSupplier.class)) { - return new ParameterSupplier[]{(ParameterSupplier) method.getAnnotation( - ParameterSupplier.class)}; + return new ParameterSupplier[]{method.getAnnotation(ParameterSupplier.class)}; } return new ParameterSupplier[0]; @@ -378,18 +382,20 @@ private static Stream filterParameterSuppliers(Class type) { .sorted(Comparator.comparing(Method::getName)); } + @SuppressWarnings("unchecked") private static Stream createArgs(Method ... parameterSuppliers) throws IllegalAccessException, InvocationTargetException { List args = new ArrayList<>(); for (var parameterSupplier : parameterSuppliers) { - args.addAll((Collection) parameterSupplier.invoke(null)); + args.addAll((Collection) parameterSupplier.invoke(null)); } return args.stream(); } - private static Object fromString(String value, Class toType) { + @SuppressWarnings({"unchecked", "rawtypes"}) + private static Object fromString(String value, Class toType) { if (toType.isEnum()) { - return Enum.valueOf(toType, value); + return Enum.valueOf((Class)toType, value); } Function converter = FROM_STRING.get(toType); if (converter == null) { @@ -410,6 +416,7 @@ static class InvalidAnnotationException extends Exception { InvalidAnnotationException(String msg) { super(msg); } + private static final long serialVersionUID = 1L; } private static class Verifier { @@ -476,10 +483,10 @@ private enum TypeStatus { private static final Object[] DEFAULT_CTOR_ARGS = new Object[0]; - private static final Map> FROM_STRING; + private static final Map, Function> FROM_STRING; static { - Map> primitives = Map.of( + Map, Function> primitives = Map.of( boolean.class, Boolean::valueOf, byte.class, Byte::valueOf, short.class, Short::valueOf, @@ -488,7 +495,7 @@ private enum TypeStatus { float.class, Float::valueOf, double.class, Double::valueOf); - Map> boxed = Map.of( + Map, Function> boxed = Map.of( Boolean.class, Boolean::valueOf, Byte.class, Byte::valueOf, Short.class, Short::valueOf, @@ -497,11 +504,11 @@ private enum TypeStatus { Float.class, Float::valueOf, Double.class, Double::valueOf); - Map> other = Map.of( + Map, Function> other = Map.of( String.class, String::valueOf, Path.class, Path::of); - Map> combined = new HashMap<>(primitives); + Map, Function> combined = new HashMap<>(primitives); combined.putAll(other); combined.putAll(boxed); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 9d289c565404c..48643463e0b56 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -72,7 +72,7 @@ private static void runMsiexecWithRetries(Executor misexec) { for (int attempt = 0; attempt < 8; ++attempt) { result = misexec.executeWithoutExitCodeCheck(); - if (result.exitCode == 1605) { + if (result.exitCode() == 1605) { // ERROR_UNKNOWN_PRODUCT, attempt to uninstall not installed // package return; @@ -81,7 +81,7 @@ private static void runMsiexecWithRetries(Executor misexec) { // The given Executor may either be of an msiexec command or an // unpack.bat script containing the msiexec command. In the later // case, when misexec returns 1618, the unpack.bat may return 1603 - if ((result.exitCode == 1618) || (result.exitCode == 1603)) { + if ((result.exitCode() == 1618) || (result.exitCode() == 1603)) { // Another installation is already in progress. // Wait a little and try again. Long timeout = 1000L * (attempt + 3); // from 3 to 10 seconds @@ -523,7 +523,7 @@ static String queryRegistryValue(String keyPath, String valueName) { var status = Executor.of("reg", "query", keyPath, "/v", valueName) .saveOutput() .executeWithoutExitCodeCheck(); - if (status.exitCode == 1) { + if (status.exitCode() == 1) { // Should be the case of no such registry value or key String lookupString = "ERROR: The system was unable to find the specified registry key or value."; TKit.assertTextStream(lookupString) diff --git a/test/jdk/tools/jpackage/junit/TEST.properties b/test/jdk/tools/jpackage/junit/TEST.properties index 12c38c2f5a5a1..931ff3c2d9ad4 100644 --- a/test/jdk/tools/jpackage/junit/TEST.properties +++ b/test/jdk/tools/jpackage/junit/TEST.properties @@ -1,2 +1,7 @@ -JUnit.dirs = . -modules = jdk.jpackage +JUnit.dirs = share + +modules=jdk.jpackage/jdk.jpackage.internal:+open \ + jdk.jpackage/jdk.jpackage.internal.util:+open \ + jdk.jpackage/jdk.jpackage.internal.util.function:+open \ + java.base/jdk.internal.util \ + jdk.jlink/jdk.tools.jlink.internal diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java similarity index 100% rename from test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java rename to test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java diff --git a/test/jdk/tools/jpackage/junit/windows/jdk.jpackage/jdk/jpackage/internal/ExecutableOSVersionTest.java b/test/jdk/tools/jpackage/junit/windows/jdk.jpackage/jdk/jpackage/internal/ExecutableOSVersionTest.java new file mode 100644 index 0000000000000..4d636f57b53df --- /dev/null +++ b/test/jdk/tools/jpackage/junit/windows/jdk.jpackage/jdk/jpackage/internal/ExecutableOSVersionTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.internal; + +import static jdk.jpackage.internal.OSVersionCondition.WindowsVersion.getExecutableOSVersion; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.condition.OS.WINDOWS; + +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; +import jdk.jpackage.internal.OSVersionCondition.WindowsVersion; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + + +public class ExecutableOSVersionTest { + + @Test + @EnabledOnOs(WINDOWS) + public void testWindowsVersionGetExecutableOSVersion() { + final var javaHome = Path.of(System.getProperty("java.home")); + + final var javaExeVer = getExecutableOSVersion(javaHome.resolve("bin/java.exe")); + + assertTrue(javaExeVer.majorOSVersion() > 0); + assertTrue(javaExeVer.minorOSVersion() >= 0); + + final var javaDllVer = getExecutableOSVersion(javaHome.resolve("bin/java.dll")); + + assertEquals(javaExeVer, javaDllVer); + } + + @ParameterizedTest + @EnabledOnOs(WINDOWS) + @MethodSource + public void testWindowsVersionDescendingOrder(List unsorted, WindowsVersion expectedFirst) { + final var actualFirst = unsorted.stream().sorted(WindowsVersion.descendingOrder()).findFirst().orElseThrow(); + assertEquals(expectedFirst, actualFirst); + } + + public static Stream testWindowsVersionDescendingOrder() { + return Stream.of( + new Object[] { List.of(wver(5, 0), wver(5, 1), wver(4, 9)), wver(5, 1) }, + new Object[] { List.of(wver(5, 0)), wver(5, 0) }, + new Object[] { List.of(wver(5, 1), wver(5, 1), wver(5, 0)), wver(5, 1) }, + new Object[] { List.of(wver(3, 11), wver(4, 8), wver(5, 6)), wver(5, 6) }, + new Object[] { List.of(wver(3, 11), wver(3, 9), wver(3, 13)), wver(3, 13) } + ); + } + + private final static WindowsVersion wver(int major, int minor) { + return new WindowsVersion(major, minor); + } +} diff --git a/test/jdk/tools/jpackage/junit/windows/junit.java b/test/jdk/tools/jpackage/junit/windows/junit.java new file mode 100644 index 0000000000000..38b5cd5ca0c6f --- /dev/null +++ b/test/jdk/tools/jpackage/junit/windows/junit.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @summary Test function reading OS version from PE file + * @requires (os.family == "windows") + * @compile/module=jdk.jpackage jdk/jpackage/internal/ExecutableOSVersionTest.java + * @run junit jdk.jpackage/jdk.jpackage.internal.ExecutableOSVersionTest + */ diff --git a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java index 5a460b39ed7fa..1dc8dee3c9768 100644 --- a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @compile LinuxResourceTest.java + * @compile -Xlint:all -Werror LinuxResourceTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LinuxResourceTest */ diff --git a/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java b/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java index a30c172461103..b59205783470a 100644 --- a/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxWeirdOutputDirTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ * @bug 8268974 * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile LinuxWeirdOutputDirTest.java + * @compile -Xlint:all -Werror LinuxWeirdOutputDirTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LinuxWeirdOutputDirTest */ diff --git a/test/jdk/tools/jpackage/linux/PackageDepsTest.java b/test/jdk/tools/jpackage/linux/PackageDepsTest.java index 1a69582fc841e..6e2a8af1e58db 100644 --- a/test/jdk/tools/jpackage/linux/PackageDepsTest.java +++ b/test/jdk/tools/jpackage/linux/PackageDepsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @compile PackageDepsTest.java + * @compile -Xlint:all -Werror PackageDepsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=PackageDepsTest */ diff --git a/test/jdk/tools/jpackage/linux/ServiceAndDesktopTest.java b/test/jdk/tools/jpackage/linux/ServiceAndDesktopTest.java index 581190ad341f4..e7f1463f7a35c 100644 --- a/test/jdk/tools/jpackage/linux/ServiceAndDesktopTest.java +++ b/test/jdk/tools/jpackage/linux/ServiceAndDesktopTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ */ import java.nio.file.Path; -import jdk.jpackage.test.AdditionalLauncher; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.LauncherAsServiceVerifier; @@ -44,7 +43,7 @@ * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @compile ServiceAndDesktopTest.java + * @compile -Xlint:all -Werror ServiceAndDesktopTest.java * @run main/othervm/timeout=720 jdk.jpackage.test.Main * --jpt-run=ServiceAndDesktopTest */ diff --git a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java index 01e890751388a..fc34d024a987f 100644 --- a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java +++ b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @compile ShortcutHintTest.java + * @compile -Xlint:all -Werror ShortcutHintTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ShortcutHintTest */ @@ -71,7 +71,7 @@ * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @requires jpackage.test.SQETest != null - * @compile ShortcutHintTest.java + * @compile -Xlint:all -Werror ShortcutHintTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ShortcutHintTest.testBasic */ diff --git a/test/jdk/tools/jpackage/linux/UpgradeTest.java b/test/jdk/tools/jpackage/linux/UpgradeTest.java index 4bf13476eb5a3..fb399cec12bdb 100644 --- a/test/jdk/tools/jpackage/linux/UpgradeTest.java +++ b/test/jdk/tools/jpackage/linux/UpgradeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @compile UpgradeTest.java + * @compile -Xlint:all -Werror UpgradeTest.java * @run main/othervm/timeout=360 jdk.jpackage.test.Main * --jpt-run=UpgradeTest */ diff --git a/test/jdk/tools/jpackage/linux/UsrTreeTest.java b/test/jdk/tools/jpackage/linux/UsrTreeTest.java index 819ea8f245a12..e33364c605d9d 100644 --- a/test/jdk/tools/jpackage/linux/UsrTreeTest.java +++ b/test/jdk/tools/jpackage/linux/UsrTreeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @requires jpackage.test.SQETest == null * @requires (os.family == "linux") * @build jdk.jpackage.test.* - * @compile UsrTreeTest.java + * @compile -Xlint:all -Werror UsrTreeTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=UsrTreeTest */ diff --git a/test/jdk/tools/jpackage/macosx/ArgumentsFilteringTest.java b/test/jdk/tools/jpackage/macosx/ArgumentsFilteringTest.java index 9b57cd7fbe56e..1a42a30c00e9e 100644 --- a/test/jdk/tools/jpackage/macosx/ArgumentsFilteringTest.java +++ b/test/jdk/tools/jpackage/macosx/ArgumentsFilteringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @summary jpackage with -psn * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ArgumentsFilteringTest.java + * @compile -Xlint:all -Werror ArgumentsFilteringTest.java * @requires (os.family == "mac") * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ArgumentsFilteringTest diff --git a/test/jdk/tools/jpackage/macosx/DmgContentTest.java b/test/jdk/tools/jpackage/macosx/DmgContentTest.java index fefbe229ec5ae..c670d111e20c8 100644 --- a/test/jdk/tools/jpackage/macosx/DmgContentTest.java +++ b/test/jdk/tools/jpackage/macosx/DmgContentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ public class DmgContentTest { "non-existant").toString(); @Parameters - public static Collection input() { + public static Collection input() { List data = new ArrayList<>(); data.addAll(List.of(new Object[][] { {"0", PackageType.MAC_DMG, new String[] {TEST_JAVA, TEST_DUKE}}, diff --git a/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java b/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java index 69e1cd6c42a9e..5c4a7ac0e8e76 100644 --- a/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java +++ b/test/jdk/tools/jpackage/macosx/HostArchPkgTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @summary jpackage test to validate "hostArchitectures" attribute * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile HostArchPkgTest.java + * @compile -Xlint:all -Werror HostArchPkgTest.java * @requires (os.family == "mac") * @key jpackagePlatformPackage * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java b/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java index 5482a3ea508ce..67a5cf6b609ef 100644 --- a/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java +++ b/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* * @requires (os.family == "mac") - * @compile MacPropertiesTest.java + * @compile -Xlint:all -Werror MacPropertiesTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MacPropertiesTest */ diff --git a/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java b/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java index ea95ad964f381..06da5a83d06d9 100644 --- a/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java +++ b/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @summary jpackage test with name containing spaces * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile NameWithSpaceTest.java + * @compile -Xlint:all -Werror NameWithSpaceTest.java * @requires (os.family == "mac") * @key jpackagePlatformPackage * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/macosx/SigningOptionsTest.java b/test/jdk/tools/jpackage/macosx/SigningOptionsTest.java index c5df2c1b31bda..88595c566dfb3 100644 --- a/test/jdk/tools/jpackage/macosx/SigningOptionsTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningOptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ public final class SigningOptionsTest { "apps/dukeplug.png").toString(); @Parameters - public static Collection input() { + public static Collection input() { return List.of(new Object[][]{ // --mac-signing-key-user-name and --mac-app-image-sign-identity {"Hello", diff --git a/test/jdk/tools/jpackage/macosx/base/SigningBase.java b/test/jdk/tools/jpackage/macosx/base/SigningBase.java index 15031bc42be57..254aa306b522c 100644 --- a/test/jdk/tools/jpackage/macosx/base/SigningBase.java +++ b/test/jdk/tools/jpackage/macosx/base/SigningBase.java @@ -98,6 +98,7 @@ private static void checkString(List result, String lookupString) { (line, what) -> line.trim().contains(what)).apply(result.stream()); } + @SuppressWarnings("fallthrough") private static List codesignResult(Path target, CodesignCheckType type) { int exitCode = 0; Executor executor = new Executor().setExecutable("/usr/bin/codesign"); diff --git a/test/jdk/tools/jpackage/macosx/base/SigningCheck.java b/test/jdk/tools/jpackage/macosx/base/SigningCheck.java index 4ba2763804f06..3db101f38069a 100644 --- a/test/jdk/tools/jpackage/macosx/base/SigningCheck.java +++ b/test/jdk/tools/jpackage/macosx/base/SigningCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,6 @@ */ import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.io.IOException; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Executor; diff --git a/test/jdk/tools/jpackage/share/AddLShortcutTest.java b/test/jdk/tools/jpackage/share/AddLShortcutTest.java index 5b55d906cf163..6430a55d784af 100644 --- a/test/jdk/tools/jpackage/share/AddLShortcutTest.java +++ b/test/jdk/tools/jpackage/share/AddLShortcutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ * @key jpackagePlatformPackage * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile AddLShortcutTest.java + * @compile -Xlint:all -Werror AddLShortcutTest.java * @run main/othervm/timeout=540 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=AddLShortcutTest diff --git a/test/jdk/tools/jpackage/share/AddLauncherTest.java b/test/jdk/tools/jpackage/share/AddLauncherTest.java index af0efc4fb86e3..5c21be712581a 100644 --- a/test/jdk/tools/jpackage/share/AddLauncherTest.java +++ b/test/jdk/tools/jpackage/share/AddLauncherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @requires (jpackage.test.SQETest != null) * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile AddLauncherTest.java + * @compile -Xlint:all -Werror AddLauncherTest.java * @run main/othervm/timeout=360 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=AddLauncherTest.test @@ -62,7 +62,7 @@ * @requires (jpackage.test.SQETest == null) * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile AddLauncherTest.java + * @compile -Xlint:all -Werror AddLauncherTest.java * @run main/othervm/timeout=540 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=AddLauncherTest diff --git a/test/jdk/tools/jpackage/share/AppContentTest.java b/test/jdk/tools/jpackage/share/AppContentTest.java index d33960092ee88..c14cd50cc1193 100644 --- a/test/jdk/tools/jpackage/share/AppContentTest.java +++ b/test/jdk/tools/jpackage/share/AppContentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ public class AppContentTest { private final List testPathArgs; @Parameters - public static Collection data() { + public static Collection data() { return List.of(new String[][]{ {TEST_JAVA, TEST_DUKE}, // include two files in two options {TEST_JAVA, TEST_BAD}, // try to include non-existant content diff --git a/test/jdk/tools/jpackage/share/AppImagePackageTest.java b/test/jdk/tools/jpackage/share/AppImagePackageTest.java index 7185e63145f01..030cca50f1445 100644 --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /test/jdk/tools/jpackage/helpers * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* - * @compile AppImagePackageTest.java + * @compile -Xlint:all -Werror AppImagePackageTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=AppImagePackageTest */ diff --git a/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java b/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java index a16ff9c18f96d..772370b0f8c05 100644 --- a/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java +++ b/test/jdk/tools/jpackage/share/AppLauncherEnvTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; +import static jdk.jpackage.test.HelloApp.configureAndExecute; import jdk.jpackage.test.TKit; /** @@ -53,6 +54,7 @@ public static void test() throws Exception { JPackageCommand cmd = JPackageCommand .helloAppImage(TEST_APP_JAVA + "*Hello") + .ignoreFakeRuntime() .addArguments("--java-options", "-D" + testAddDirProp + "=$APPDIR"); @@ -60,16 +62,12 @@ public static void test() throws Exception { final String envVarName = envVarName(); - final int attempts = 3; - final int waitBetweenAttemptsSeconds = 5; - List output = new Executor() + List output = configureAndExecute(0, new Executor() .saveOutput() .setExecutable(cmd.appLauncherPath().toAbsolutePath()) .addArguments("--print-env-var=" + envVarName) .addArguments("--print-sys-prop=" + testAddDirProp) - .addArguments("--print-sys-prop=" + "java.library.path") - .executeAndRepeatUntilExitCode(0, attempts, - waitBetweenAttemptsSeconds).getOutput(); + .addArguments("--print-sys-prop=" + "java.library.path")).getOutput(); BiFunction getValue = (idx, name) -> { return output.get(idx).substring((name + "=").length()); diff --git a/test/jdk/tools/jpackage/share/AppVersionTest.java b/test/jdk/tools/jpackage/share/AppVersionTest.java index 3fdddf56e2eaa..e81b1eae9cfa9 100644 --- a/test/jdk/tools/jpackage/share/AppVersionTest.java +++ b/test/jdk/tools/jpackage/share/AppVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @summary jpackage application version testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile AppVersionTest.java + * @compile -Xlint:all -Werror AppVersionTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=AppVersionTest */ @@ -47,7 +47,7 @@ public final class AppVersionTest { @Parameters - public static Collection input() { + public static Collection input() { List data = new ArrayList<>(); data.addAll(List.of(new Object[][]{ diff --git a/test/jdk/tools/jpackage/share/ArgumentsTest.java b/test/jdk/tools/jpackage/share/ArgumentsTest.java index 3be6c36a25c89..e3e0724a3e24f 100644 --- a/test/jdk/tools/jpackage/share/ArgumentsTest.java +++ b/test/jdk/tools/jpackage/share/ArgumentsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ * @summary jpackage create image with --arguments test * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ArgumentsTest.java + * @compile -Xlint:all -Werror ArgumentsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ArgumentsTest */ diff --git a/test/jdk/tools/jpackage/share/BasicTest.java b/test/jdk/tools/jpackage/share/BasicTest.java index c6e4e93015519..94e0a335d18ae 100644 --- a/test/jdk/tools/jpackage/share/BasicTest.java +++ b/test/jdk/tools/jpackage/share/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ import java.nio.file.Path; import java.util.List; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; @@ -41,7 +43,9 @@ import jdk.jpackage.test.JavaTool; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.tools.jlink.internal.LinkableRuntimeImage; import static jdk.jpackage.test.RunnablePackageTest.Action.CREATE_AND_UNPACK; /* @@ -49,12 +53,38 @@ * @summary jpackage basic testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile BasicTest.java + * @compile -Xlint:all -Werror BasicTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=BasicTest */ public final class BasicTest { + + public static Collection addModulesParams() { + List params = new ArrayList<>(); + params.add(new Object[][] { new String[] { "--add-modules", "ALL-DEFAULT" } }); + params.add(new Object[][] { new String[] { "--add-modules", "java.desktop" } }); + params.add(new Object[][] { new String[] { "--add-modules", "java.desktop,jdk.jartool" } }); + params.add(new Object[][] { new String[] { "--add-modules", "java.desktop", "--add-modules", "jdk.jartool" } }); + if (isAllModulePathCapable()) { + final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); + params.add(new Object[][] { new String[] { "--add-modules", "ALL-MODULE-PATH", + // Since JDK-8345259 ALL-MODULE-PATH requires --module-path arg + "--module-path", jmods.toString() } }); + } + return Collections.unmodifiableList(params); + } + + private static boolean isAllModulePathCapable() { + Path jmods = Path.of(System.getProperty("java.home"), "jmods"); + boolean noJmods = Files.notExists(jmods); + if (LinkableRuntimeImage.isLinkableRuntime() && noJmods) { + TKit.trace("ALL-MODULE-PATH test skipped for linkable run-time image"); + return false; + } + return true; + } + @Test public void testNoArgs() { List output = @@ -78,7 +108,6 @@ public void testJpackageProps() { .ignoreFakeRuntime(); cmd.executeAndAssertImageCreated(); - Path launcherPath = cmd.appLauncherPath(); List output = HelloApp.executeLauncher(cmd).getOutput(); @@ -306,17 +335,12 @@ public void testNoOutputDir(boolean appImage) throws Throwable { } @Test - @Parameter("ALL-MODULE-PATH") - @Parameter("ALL-DEFAULT") - @Parameter("java.desktop") - @Parameter("java.desktop,jdk.jartool") - @Parameter({ "java.desktop", "jdk.jartool" }) - public void testAddModules(String... addModulesArg) { + @ParameterSupplier("addModulesParams") + public void testAddModules(String[] addModulesArg) { JPackageCommand cmd = JPackageCommand .helloAppImage("goodbye.jar:com.other/com.other.Hello") .ignoreDefaultRuntime(true); // because of --add-modules - Stream.of(addModulesArg).map(v -> Stream.of("--add-modules", v)).flatMap( - s -> s).forEachOrdered(cmd::addArgument); + Stream.of(addModulesArg).forEachOrdered(cmd::addArgument); cmd.executeAndAssertHelloAppImageCreated(); } diff --git a/test/jdk/tools/jpackage/share/CookedRuntimeTest.java b/test/jdk/tools/jpackage/share/CookedRuntimeTest.java index e8bd034bfb4b1..28fba111c8faa 100644 --- a/test/jdk/tools/jpackage/share/CookedRuntimeTest.java +++ b/test/jdk/tools/jpackage/share/CookedRuntimeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @summary test '--runtime-image' option of jpackage * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile CookedRuntimeTest.java + * @compile -Xlint:all -Werror CookedRuntimeTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=CookedRuntimeTest */ @@ -112,7 +112,7 @@ public void test() throws IOException { } @Parameters - public static Collection data() { + public static Collection data() { final List javaAppDescs = List.of("Hello", "com.foo/com.foo.main.Aloha"); diff --git a/test/jdk/tools/jpackage/share/DotInNameTest.java b/test/jdk/tools/jpackage/share/DotInNameTest.java index 2617db26183e7..8fb2641a6f3c7 100644 --- a/test/jdk/tools/jpackage/share/DotInNameTest.java +++ b/test/jdk/tools/jpackage/share/DotInNameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,6 @@ import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.HelloApp; -import jdk.jpackage.test.TKit; -import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; @@ -34,7 +32,7 @@ * @summary jpackage create image with --java-options test * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile DotInNameTest.java + * @compile -Xlint:all -Werror DotInNameTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=DotInNameTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault diff --git a/test/jdk/tools/jpackage/share/ErrorTest.java b/test/jdk/tools/jpackage/share/ErrorTest.java index c14da0da0f076..f28fe0a41523f 100644 --- a/test/jdk/tools/jpackage/share/ErrorTest.java +++ b/test/jdk/tools/jpackage/share/ErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @summary Test jpackage output for erroneous input * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ErrorTest.java + * @compile -Xlint:all -Werror ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault @@ -52,7 +52,7 @@ * @summary Test jpackage output for erroneous input * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ErrorTest.java + * @compile -Xlint:all -Werror ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault @@ -60,7 +60,7 @@ public final class ErrorTest { - public static Collection input() { + public static Collection input() { return List.of(new Object[][]{ // non-existent arg {"Hello", diff --git a/test/jdk/tools/jpackage/share/FileAssociationsTest.java b/test/jdk/tools/jpackage/share/FileAssociationsTest.java index a06ea82bcbae3..08578ab802744 100644 --- a/test/jdk/tools/jpackage/share/FileAssociationsTest.java +++ b/test/jdk/tools/jpackage/share/FileAssociationsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,13 @@ import java.nio.file.Path; import java.util.Map; -import java.util.List; -import jdk.jpackage.test.TKit; + +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.FileAssociations; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; -import jdk.jpackage.test.FileAssociations; -import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.TKit; /** * Test --file-associations parameter. Output of the test should be @@ -61,7 +61,7 @@ * @key jpackagePlatformPackage * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* - * @compile FileAssociationsTest.java + * @compile -Xlint:all -Werror FileAssociationsTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=FileAssociationsTest */ @@ -73,7 +73,7 @@ * @key jpackagePlatformPackage * @requires jpackage.test.SQETest != null * @build jdk.jpackage.test.* - * @compile FileAssociationsTest.java + * @compile -Xlint:all -Werror FileAssociationsTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=FileAssociationsTest.test */ diff --git a/test/jdk/tools/jpackage/share/IconTest.java b/test/jdk/tools/jpackage/share/IconTest.java index d5edbc9324566..f5498500c0bc3 100644 --- a/test/jdk/tools/jpackage/share/IconTest.java +++ b/test/jdk/tools/jpackage/share/IconTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @summary jpackage create image and package with custom icons for the main and additional launcher * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile IconTest.java + * @compile -Xlint:all -Werror IconTest.java * @run main/othervm/timeout=540 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=IconTest @@ -113,7 +113,7 @@ public IconTest(BundleType bundleType, IconType mainLauncherIconType) { } @Parameters - public static Collection data() { + public static Collection data() { List data = new ArrayList<>(); var withLinuxShortcut = Set.of(IconType.DefaultIcon, IconType.NoIcon); diff --git a/test/jdk/tools/jpackage/share/InOutPathTest.java b/test/jdk/tools/jpackage/share/InOutPathTest.java index 46da5e9939b00..2d9fa1671dec0 100644 --- a/test/jdk/tools/jpackage/share/InOutPathTest.java +++ b/test/jdk/tools/jpackage/share/InOutPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,14 +49,14 @@ * @summary Test jpackage command line with overlapping input and output paths * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile InOutPathTest.java + * @compile -Xlint:all -Werror InOutPathTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=InOutPathTest */ public final class InOutPathTest { @Parameters - public static Collection input() { + public static Collection input() { List data = new ArrayList<>(); for (var packageTypeAlias : PackageTypeAlias.values()) { diff --git a/test/jdk/tools/jpackage/share/InstallDirTest.java b/test/jdk/tools/jpackage/share/InstallDirTest.java index 23539589bcc07..672a435d22054 100644 --- a/test/jdk/tools/jpackage/share/InstallDirTest.java +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile InstallDirTest.java + * @compile -Xlint:all -Werror InstallDirTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=InstallDirTest.testCommon */ @@ -67,7 +67,7 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile InstallDirTest.java + * @compile -Xlint:all -Werror InstallDirTest.java * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/share/JLinkOptionsTest.java b/test/jdk/tools/jpackage/share/JLinkOptionsTest.java index d4f7bca2ae42c..7c110a250148c 100644 --- a/test/jdk/tools/jpackage/share/JLinkOptionsTest.java +++ b/test/jdk/tools/jpackage/share/JLinkOptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,16 @@ */ +import java.nio.file.Path; import java.util.Collection; import java.util.List; -import jdk.jpackage.test.Annotations.Parameters; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Comm; +import jdk.jpackage.test.HelloApp; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.TKit; @@ -34,15 +40,14 @@ * @summary jpackage application version testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile JLinkOptionsTest.java + * @compile -Xlint:all -Werror JLinkOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=JLinkOptionsTest */ public final class JLinkOptionsTest { - @Parameters - public static Collection input() { + public static Collection input() { return List.of(new Object[][]{ // default but with strip-native-commands removed {"Hello", new String[]{ @@ -53,29 +58,33 @@ public static Collection input() { new String[]{"jdk.jartool", "jdk.unsupported"}, null, }, + // multiple jlink-options {"com.other/com.other.Hello", new String[]{ "--jlink-options", "--strip-debug --no-man-pages --no-header-files", "--jlink-options", - "--bind-services", + "--verbose --bind-services --limit-modules java.smartcardio,jdk.crypto.cryptoki,java.desktop", }, - // with bind-services should have some services + // with limit-modules and bind-services should have them in the result new String[]{"java.smartcardio", "jdk.crypto.cryptoki"}, null, }, + // bind-services {"Hello", new String[]{ - "--jlink-options", "--bind-services", + "--jlink-options", + "--bind-services --limit-modules jdk.jartool,jdk.unsupported,java.desktop", }, - // non modular should have everything + // non modular should have at least the module limits new String[]{"jdk.jartool", "jdk.unsupported"}, null, }, // jlink-options --bind-services {"com.other/com.other.Hello", new String[]{ - "--jlink-options", "--bind-services", + "--jlink-options", + "--bind-services --limit-modules java.smartcardio,jdk.crypto.cryptoki,java.desktop", }, // with bind-services should have some services new String[]{"java.smartcardio", "jdk.crypto.cryptoki"}, @@ -109,17 +118,11 @@ public static Collection input() { }); } - public JLinkOptionsTest(String javaAppDesc, String[] jpackageArgs, String[] required, String[] prohibited) { - this.required = required; - this.prohibited = prohibited; - cmd = JPackageCommand - .helloAppImage(javaAppDesc) - .ignoreDefaultRuntime(true) - .addArguments(jpackageArgs); - } - @Test - public void test() { + @ParameterSupplier("input") + public void test(String javaAppDesc, String[] jpackageArgs, String[] required, String[] prohibited) { + final var cmd = createJPackageCommand(javaAppDesc).addArguments(jpackageArgs); + cmd.executeAndAssertHelloAppImageCreated(); List release = cmd.readRuntimeReleaseFile(); @@ -136,7 +139,38 @@ public void test() { } } - private final String[] required; - private final String[] prohibited; - private final JPackageCommand cmd; + @Test + public void testNoBindServicesByDefault() { + final var defaultModules = getModulesInRuntime("--limit-modules java.smartcardio,jdk.crypto.cryptoki,java.desktop"); + final var modulesWithBindServices = getModulesInRuntime("--bind-services --limit-modules java.smartcardio,jdk.crypto.cryptoki,java.desktop"); + + final var moduleComm = Comm.compare(defaultModules, modulesWithBindServices); + + TKit.assertStringListEquals(List.of(), moduleComm.unique1().stream().toList(), + "Check '--bind-services' option doesn't remove modules"); + // with the limited set of modules, we expect that jdk.crypto.cryptoki be added through --bind-services + TKit.assertNotEquals("", moduleComm.unique2().stream().sorted().collect(Collectors.joining(",")), + "Check '--bind-services' option adds modules"); + } + + private final JPackageCommand createJPackageCommand(String javaAppDesc) { + return JPackageCommand.helloAppImage(javaAppDesc).ignoreDefaultRuntime(true); + } + + private final Set getModulesInRuntime(String ... jlinkOptions) { + final var cmd = createJPackageCommand(PRINT_ENV_APP + "*"); + if (jlinkOptions.length != 0) { + cmd.addArguments("--jlink-options"); + cmd.addArguments(jlinkOptions); + } + + cmd.executeAndAssertImageCreated(); + + final var output = HelloApp.assertApp(cmd.appLauncherPath()) + .saveOutput(true).execute("--print-modules").getFirstLineOfOutput(); + + return Stream.of(output.split(",")).collect(Collectors.toSet()); + } + + private static final Path PRINT_ENV_APP = TKit.TEST_SRC_ROOT.resolve("apps/PrintEnv.java"); } diff --git a/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java b/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java index b1f69c6395f14..a4c2a26944a5a 100644 --- a/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java +++ b/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.HelloApp; -import jdk.jpackage.test.Executor; import jdk.jpackage.test.TKit; /* @@ -36,7 +35,7 @@ * @summary jpackage create image with --java-options test * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile JavaOptionsEqualsTest.java + * @compile -Xlint:all -Werror JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=JavaOptionsEqualsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault @@ -47,7 +46,7 @@ * @summary jpackage create image with --java-options test * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile JavaOptionsEqualsTest.java + * @compile -Xlint:all -Werror JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=JavaOptionsEqualsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault @@ -67,7 +66,7 @@ public class JavaOptionsEqualsTest { private final JPackageCommand cmd; @Parameters - public static Collection input() { + public static Collection input() { return List.of(new Object[][]{ {"Hello", new String[]{"--java-options", OPTION1, "--java-options", OPTION2 }, diff --git a/test/jdk/tools/jpackage/share/JavaOptionsTest.java b/test/jdk/tools/jpackage/share/JavaOptionsTest.java index befc90accea13..e15dc02eac6e6 100644 --- a/test/jdk/tools/jpackage/share/JavaOptionsTest.java +++ b/test/jdk/tools/jpackage/share/JavaOptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @summary jpackage create image with --java-options test * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile JavaOptionsTest.java + * @compile -Xlint:all -Werror JavaOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=JavaOptionsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault @@ -58,7 +58,7 @@ public class JavaOptionsTest { private final String[] expected; @Parameters - public static Collection input() { + public static Collection input() { List result = new ArrayList<>(); for (var app : List.of("Hello", "com.other/com.other.Hello")) { result.add(new Object[]{app, new String[]{"--java-options", ARG1}, diff --git a/test/jdk/tools/jpackage/share/LicenseTest.java b/test/jdk/tools/jpackage/share/LicenseTest.java index b0eef94fa7c57..c9e3c8508aa61 100644 --- a/test/jdk/tools/jpackage/share/LicenseTest.java +++ b/test/jdk/tools/jpackage/share/LicenseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; +import static jdk.internal.util.OperatingSystem.LINUX; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; @@ -66,7 +68,8 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile LicenseTest.java + * @compile -Xlint:all -Werror LicenseTest.java + * @requires (jpackage.test.SQETest != null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCommon */ @@ -77,19 +80,15 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile LicenseTest.java - * @requires (os.family == "linux") + * @compile -Xlint:all -Werror LicenseTest.java * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=LicenseTest.testCustomDebianCopyright - * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree2 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree3 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree4 + * --jpt-run=LicenseTest */ public class LicenseTest { + + @Test public static void testCommon() { PackageTest test = new PackageTest().configureHelloApp() .addInitializer(cmd -> { @@ -102,26 +101,32 @@ public static void testCommon() { test.run(); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree() { testLinuxLicenseInUsrTree("/usr"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree2() { testLinuxLicenseInUsrTree("/usr/local"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree3() { testLinuxLicenseInUsrTree("/usr/foo"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree4() { testLinuxLicenseInUsrTree("/usrbuz"); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyright() { new CustomDebianCopyrightTest().run(); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyrightSubst() { new CustomDebianCopyrightTest().withSubstitution(true).run(); } @@ -266,7 +271,7 @@ private static class CustomDebianCopyrightTest { } private List licenseFileText(String copyright, String licenseText) { - List lines = new ArrayList(List.of( + List lines = new ArrayList<>(List.of( String.format("Copyright=%s", copyright), "Foo", "Bar", diff --git a/test/jdk/tools/jpackage/share/MainClassTest.java b/test/jdk/tools/jpackage/share/MainClassTest.java index a031bbc278802..7ac72c2c87b41 100644 --- a/test/jdk/tools/jpackage/share/MainClassTest.java +++ b/test/jdk/tools/jpackage/share/MainClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,27 +24,28 @@ import java.io.IOException; import java.nio.file.Files; -import java.util.Collection; +import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; +import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.nio.file.Path; -import java.util.function.Predicate; -import java.util.jar.JarEntry; -import jdk.jpackage.test.JavaAppDesc; -import jdk.jpackage.test.JPackageCommand; -import jdk.jpackage.test.TKit; -import jdk.jpackage.test.Executor; -import jdk.jpackage.test.HelloApp; -import jdk.jpackage.test.JavaTool; + +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.CfgFile; -import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.test.Executor; +import jdk.jpackage.test.HelloApp; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.JavaAppDesc; +import jdk.jpackage.test.JavaTool; +import jdk.jpackage.test.TKit; @@ -53,7 +54,7 @@ * @summary test different settings of main class name for jpackage * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile MainClassTest.java + * @compile -Xlint:all -Werror MainClassTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MainClassTest */ @@ -124,7 +125,7 @@ public String toString() { } private final String label; - }; + } private JavaAppDesc appDesc; private boolean withJLink; @@ -166,11 +167,16 @@ public MainClassTest(Script script) { } else { cmd.setArgumentValue("--main-class", nonExistingMainClass); } + break; + + case SetRight: + // NOP + break; } } @Parameters - public static Collection scripts() { + public static Collection scripts() { final var withMainClass = Set.of(Script.MainClassType.SetWrong, Script.MainClassType.SetRight); diff --git a/test/jdk/tools/jpackage/share/ModulePathTest.java b/test/jdk/tools/jpackage/share/ModulePathTest.java index 7d1e86f8ae2c7..9fd07a95c230a 100644 --- a/test/jdk/tools/jpackage/share/ModulePathTest.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @summary jpackage with --module-path testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ModulePathTest.java + * @compile -Xlint:all -Werror ModulePathTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ModulePathTest */ @@ -53,7 +53,7 @@ public final class ModulePathTest { @Parameters - public static Collection data() { + public static Collection data() { return List.of(new String[][]{ {GOOD_PATH, EMPTY_DIR, NON_EXISTING_DIR}, {EMPTY_DIR, NON_EXISTING_DIR, GOOD_PATH}, @@ -80,7 +80,7 @@ public void test(String javaAppDesc) throws IOException { Path goodModulePath = TKit.createTempDirectory("modules"); - Path appBundle = HelloApp.createBundle(appDesc, goodModulePath); + HelloApp.createBundle(appDesc, goodModulePath); JPackageCommand cmd = new JPackageCommand() .setArgumentValue("--dest", TKit.workDir().resolve("output")) diff --git a/test/jdk/tools/jpackage/share/ModulePathTest2.java b/test/jdk/tools/jpackage/share/ModulePathTest2.java index 34144907bdbee..b2cc674e7e9fe 100644 --- a/test/jdk/tools/jpackage/share/ModulePathTest2.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @summary jpackage with --module-path testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ModulePathTest2.java + * @compile -Xlint:all -Werror ModulePathTest2.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ModulePathTest2 */ diff --git a/test/jdk/tools/jpackage/share/ModulePathTest3.java b/test/jdk/tools/jpackage/share/ModulePathTest3.java index 118dc2e5ed01f..c3960c0d4c890 100644 --- a/test/jdk/tools/jpackage/share/ModulePathTest3.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @summary jpackage for app's module linked in external runtime * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile ModulePathTest3.java + * @compile -Xlint:all -Werror ModulePathTest3.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ModulePathTest3 */ @@ -108,7 +108,7 @@ private void testIt(String mainAppDesc) throws XPathExpressionException, } @Parameters - public static Collection data() { + public static Collection data() { final List paths = new ArrayList<>(); paths.add(new String[] { "", "" }); if (TKit.isOSX()) { diff --git a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java index 34962b77ca03f..d348b5c170dee 100644 --- a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile MultiLauncherTwoPhaseTest.java + * @compile -Xlint:all -Werror MultiLauncherTwoPhaseTest.java * @run main/othervm/timeout=360 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=MultiLauncherTwoPhaseTest diff --git a/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java index 870804661a7f8..8becb6f3dc325 100644 --- a/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ * @key jpackagePlatformPackage * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* - * @compile MultiNameTwoPhaseTest.java + * @compile -Xlint:all -Werror MultiNameTwoPhaseTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MultiNameTwoPhaseTest */ diff --git a/test/jdk/tools/jpackage/share/MultipleJarAppTest.java b/test/jdk/tools/jpackage/share/MultipleJarAppTest.java index 0726b131d69e7..a3a50b7c47024 100644 --- a/test/jdk/tools/jpackage/share/MultipleJarAppTest.java +++ b/test/jdk/tools/jpackage/share/MultipleJarAppTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,19 +22,18 @@ */ -import java.nio.file.Path; -import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.HelloApp; -import jdk.jpackage.test.JavaAppDesc; import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.JavaAppDesc; /* * @test * @summary jpackage application packed in multiple jars * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile MultipleJarAppTest.java + * @compile -Xlint:all -Werror MultipleJarAppTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MultipleJarAppTest */ diff --git a/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java b/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java index 3731997118334..916799459256c 100644 --- a/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java +++ b/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.util.Collection; import java.util.ArrayList; import java.util.List; -import java.util.stream.Stream; import java.nio.file.Path; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; @@ -44,7 +43,7 @@ * @summary test '--runtime-image' option of jpackage * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile NoMPathRuntimeTest.java + * @compile -Xlint:all -Werror NoMPathRuntimeTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=NoMPathRuntimeTest */ @@ -111,7 +110,7 @@ public void test() throws IOException { } @Parameters - public static Collection data() { + public static Collection data() { final List paths = new ArrayList<>(); paths.add(new String[] { "", "" }); diff --git a/test/jdk/tools/jpackage/share/NonExistentTest.java b/test/jdk/tools/jpackage/share/NonExistentTest.java index 4d50f2a5850ae..3c87d3c6411c7 100644 --- a/test/jdk/tools/jpackage/share/NonExistentTest.java +++ b/test/jdk/tools/jpackage/share/NonExistentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @summary jpackage application version testing * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile NonExistentTest.java + * @compile -Xlint:all -Werror NonExistentTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=NonExistentTest */ @@ -45,7 +45,7 @@ public final class NonExistentTest { private final JPackageCommand cmd; @Parameters - public static Collection input() { + public static Collection input() { return List.of(new Object[][]{ // non-existent icon {"Hello", diff --git a/test/jdk/tools/jpackage/share/PerUserCfgTest.java b/test/jdk/tools/jpackage/share/PerUserCfgTest.java index 2e62aa5c5d631..080df1f959d3e 100644 --- a/test/jdk/tools/jpackage/share/PerUserCfgTest.java +++ b/test/jdk/tools/jpackage/share/PerUserCfgTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Objects; import java.util.Optional; import jdk.jpackage.test.AdditionalLauncher; import jdk.jpackage.test.PackageTest; @@ -47,7 +48,7 @@ * @key jpackagePlatformPackage * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* - * @compile PerUserCfgTest.java + * @compile -Xlint:all -Werror PerUserCfgTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=PerUserCfgTest */ @@ -165,6 +166,8 @@ private static void withConfigFile(JPackageCommand cmd, Path srcCfgFile, null).getFileName()); TKit.assertPathExists(targetCfgFile, false); try (var dirCleaner = TKit.createDirectories(targetCfgFile.getParent())) { + // Suppress "warning: [try] auto-closeable resource dirCleaner is never referenced" + Objects.requireNonNull(dirCleaner); Files.copy(srcCfgFile, targetCfgFile); try { TKit.traceFileContents(targetCfgFile, "cfg file"); diff --git a/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java index 0e1d358dae46b..a415f0370ccec 100644 --- a/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java +++ b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @summary Test jpackage output for erroneous input with --type "app-image" and --app-image * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile PredefinedAppImageErrorTest.java + * @compile -Xlint:all -Werror PredefinedAppImageErrorTest.java * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=PredefinedAppImageErrorTest @@ -56,7 +56,7 @@ public final class PredefinedAppImageErrorTest { private final JPackageCommand cmd; @Parameters - public static Collection input() throws IOException { + public static Collection input() throws IOException { return List.of(new Object[][]{ // --mac-sign is required {"Hello", diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index 404cd3b6d3a47..c41ba92c74060 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import static jdk.internal.util.OperatingSystem.WINDOWS; import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; @@ -42,14 +43,14 @@ * @key jpackagePlatformPackage * @requires (os.family != "windows") * @build jdk.jpackage.test.* - * @compile RuntimeImageSymbolicLinksTest.java + * @compile -Xlint:all -Werror RuntimeImageSymbolicLinksTest.java * @run main/othervm/timeout=1400 -Xmx512m jdk.jpackage.test.Main * --jpt-run=RuntimeImageSymbolicLinksTest */ public class RuntimeImageSymbolicLinksTest { - @Test + @Test(ifNotOS = WINDOWS) public static void test() throws Exception { final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); final Path jlinkOutputDir = workDir.resolve("temp.runtime"); @@ -60,7 +61,7 @@ public static void test() throws Exception { .dumpOutput() .addArguments( "--output", jlinkOutputDir.toString(), - "--add-modules", "ALL-MODULE-PATH", + "--add-modules", "java.desktop", "--strip-debug", "--no-header-files", "--no-man-pages", diff --git a/test/jdk/tools/jpackage/share/RuntimeImageTest.java b/test/jdk/tools/jpackage/share/RuntimeImageTest.java index f3751c9ee472a..0e30d7ee179c4 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile RuntimeImageTest.java + * @compile -Xlint:all -Werror RuntimeImageTest.java * @run main/othervm/timeout=1400 jdk.jpackage.test.Main * --jpt-run=RuntimeImageTest */ @@ -53,7 +53,7 @@ public static void test() throws Exception { .dumpOutput() .addArguments( "--output", jlinkOutputDir.toString(), - "--add-modules", "ALL-MODULE-PATH", + "--add-modules", "java.desktop", "--strip-debug", "--no-header-files", "--no-man-pages", diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java index 0b505babcc561..7b0e88a5ae71b 100644 --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (jpackage.test.SQETest == null) - * @compile RuntimePackageTest.java + * @compile -Xlint:all -Werror RuntimePackageTest.java * @run main/othervm/timeout=1400 -Xmx512m jdk.jpackage.test.Main * --jpt-run=RuntimePackageTest */ @@ -71,7 +71,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (jpackage.test.SQETest != null) - * @compile RuntimePackageTest.java + * @compile -Xlint:all -Werror RuntimePackageTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=RuntimePackageTest.test */ @@ -101,6 +101,7 @@ private static PackageTest init(Set types) { .forTypes(types) .addInitializer(cmd -> { final Path runtimeImageDir; + if (JPackageCommand.DEFAULT_RUNTIME_IMAGE != null) { runtimeImageDir = JPackageCommand.DEFAULT_RUNTIME_IMAGE; } else { @@ -111,7 +112,7 @@ private static PackageTest init(Set types) { .dumpOutput() .addArguments( "--output", runtimeImageDir.toString(), - "--add-modules", "ALL-MODULE-PATH", + "--add-modules", "java.desktop", "--strip-debug", "--no-header-files", "--no-man-pages") diff --git a/test/jdk/tools/jpackage/share/ServiceTest.java b/test/jdk/tools/jpackage/share/ServiceTest.java index f1ff65d18b1a2..98cad9fc61094 100644 --- a/test/jdk/tools/jpackage/share/ServiceTest.java +++ b/test/jdk/tools/jpackage/share/ServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * @build jdk.jpackage.test.* * @build jtreg.SkippedException * @key jpackagePlatformPackage - * @compile ServiceTest.java + * @compile -Xlint:all -Werror ServiceTest.java * @run main/othervm/timeout=360 -Xmx512m * jdk.jpackage.test.Main * --jpt-run=ServiceTest diff --git a/test/jdk/tools/jpackage/share/SimplePackageTest.java b/test/jdk/tools/jpackage/share/SimplePackageTest.java index e3945b668e0e0..c28c1c17798ff 100644 --- a/test/jdk/tools/jpackage/share/SimplePackageTest.java +++ b/test/jdk/tools/jpackage/share/SimplePackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ * @library /test/jdk/tools/jpackage/helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @compile SimplePackageTest.java + * @compile -Xlint:all -Werror SimplePackageTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=SimplePackageTest */ diff --git a/test/jdk/tools/jpackage/share/UnicodeArgsTest.java b/test/jdk/tools/jpackage/share/UnicodeArgsTest.java index 6fa2717d15e7e..c168916ee7db3 100644 --- a/test/jdk/tools/jpackage/share/UnicodeArgsTest.java +++ b/test/jdk/tools/jpackage/share/UnicodeArgsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ * @summary test how app launcher handles unicode command line arguments * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* - * @compile UnicodeArgsTest.java + * @compile -Xlint:all -Werror UnicodeArgsTest.java * @requires (os.family == "windows") * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=UnicodeArgsTest diff --git a/test/jdk/tools/jpackage/share/VendorTest.java b/test/jdk/tools/jpackage/share/VendorTest.java index 4c3a0ffcee26e..b6974cb286a25 100644 --- a/test/jdk/tools/jpackage/share/VendorTest.java +++ b/test/jdk/tools/jpackage/share/VendorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ * @requires (os.family == "windows") * @requires jpackage.test.SQETest != null * @build jdk.jpackage.test.* - * @compile VendorTest.java + * @compile -Xlint:all -Werror VendorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=VendorTest */ @@ -71,7 +71,7 @@ * @requires (os.family != "mac") * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* - * @compile VendorTest.java + * @compile -Xlint:all -Werror VendorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=VendorTest */ diff --git a/test/jdk/tools/jpackage/windows/Win8282351Test.java b/test/jdk/tools/jpackage/windows/Win8282351Test.java index 17ea5e7d9ab1a..553574377628b 100644 --- a/test/jdk/tools/jpackage/windows/Win8282351Test.java +++ b/test/jdk/tools/jpackage/windows/Win8282351Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.PackageType; import jdk.jpackage.test.RunnablePackageTest.Action; import jdk.jpackage.test.TKit; diff --git a/test/jdk/tools/jpackage/windows/WinChildProcessTest.java b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java index 5565d3dc50352..a83ef8373312f 100644 --- a/test/jdk/tools/jpackage/windows/WinChildProcessTest.java +++ b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import java.nio.file.Path; import jdk.jpackage.test.JPackageCommand; +import static jdk.jpackage.test.HelloApp.configureAndExecute; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; import jdk.jpackage.test.TKit; @@ -54,16 +55,17 @@ public static void test() { long childPid = 0; try { JPackageCommand cmd = JPackageCommand - .helloAppImage(TEST_APP_JAVA + "*Hello"); + .helloAppImage(TEST_APP_JAVA + "*Hello") + .ignoreFakeRuntime(); // Create the image of the third party application launcher cmd.executeAndAssertImageCreated(); // Start the third party application launcher and dump and save the // output of the application - List output = new Executor().saveOutput().dumpOutput() - .setExecutable(cmd.appLauncherPath().toAbsolutePath()) - .execute(0).getOutput(); + List output = configureAndExecute(0, new Executor().saveOutput().dumpOutput() + .setExecutable(cmd.appLauncherPath().toAbsolutePath())) + .getOutput(); String pidStr = output.get(0); // parse child PID diff --git a/test/jdk/tools/jpackage/windows/WinConsoleTest.java b/test/jdk/tools/jpackage/windows/WinConsoleTest.java index 6a1e94a8e83ef..1244de080d996 100644 --- a/test/jdk/tools/jpackage/windows/WinConsoleTest.java +++ b/test/jdk/tools/jpackage/windows/WinConsoleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinConsoleTest.java + * @compile -Xlint:all -Werror WinConsoleTest.java * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault diff --git a/test/jdk/tools/jpackage/windows/WinInstallerIconTest.java b/test/jdk/tools/jpackage/windows/WinInstallerIconTest.java index f104abc9f5e6b..fe6ee650f4ab3 100644 --- a/test/jdk/tools/jpackage/windows/WinInstallerIconTest.java +++ b/test/jdk/tools/jpackage/windows/WinInstallerIconTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ public void test() { // Create another installer with custom icon. var size3 = createInstaller(customIcon, null); - if (Stream.of(size1, size2, size3).allMatch(Optional::isEmpty)) { + if (Stream.of(size1, size2, size3).allMatch(Optional::isEmpty)) { TKit.trace( "Not verifying sizes of installers because they were not created"); return; diff --git a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java index c6489ab68cf4c..7dcf025a506ce 100644 --- a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java +++ b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,13 +122,13 @@ private void setPackageName(JPackageCommand cmd) { StringBuilder sb = new StringBuilder(cmd.name()); sb.append("With"); if (withDirChooser) { - sb.append("DirChooser"); + sb.append("Dc"); // DirChooser } if (withShortcutPrompt) { - sb.append("ShortcutPrompt"); + sb.append("Sp"); // ShortcutPrompt } if (withLicense) { - sb.append("License"); + sb.append("L"); // License } cmd.setArgumentValue("--name", sb.toString()); } diff --git a/test/jdk/tools/jpackage/windows/WinL10nTest.java b/test/jdk/tools/jpackage/windows/WinL10nTest.java index dee1e42267d91..4f5a27f9ff096 100644 --- a/test/jdk/tools/jpackage/windows/WinL10nTest.java +++ b/test/jdk/tools/jpackage/windows/WinL10nTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinL10nTest.java + * @compile -Xlint:all -Werror WinL10nTest.java * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinL10nTest */ diff --git a/test/jdk/tools/jpackage/windows/WinLongPathTest.java b/test/jdk/tools/jpackage/windows/WinLongPathTest.java index e9e5ef8ce038e..8fe347cffda13 100644 --- a/test/jdk/tools/jpackage/windows/WinLongPathTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.RunnablePackageTest.Action; import jdk.jpackage.test.TKit; @@ -39,10 +40,12 @@ * @bug 8289771 * @summary jpackage with long paths on windows * @library /test/jdk/tools/jpackage/helpers + * @library /test/lib * @key jpackagePlatformPackage * @build jdk.jpackage.test.* + * @build jtreg.SkippedException * @requires (os.family == "windows") - * @compile WinLongPathTest.java + * @compile -Xlint:all -Werror WinLongPathTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-space-subst=* * --jpt-exclude=WinLongPathTest(false,*--temp) @@ -64,6 +67,8 @@ public static List input() { @Test public void test() throws IOException { + verifyDosNamesSupported(); + if (appImage) { var cmd = JPackageCommand.helloAppImage(); setOptionLongPath(cmd, optionName); @@ -84,4 +89,23 @@ private static void setOptionLongPath(JPackageCommand cmd, String option) throws Files.createDirectories(longPath); cmd.setArgumentValue(option, longPath); } + + private static void verifyDosNamesSupported() throws IOException { + // Pick the file's name long enough to make Windows shorten it. + final var probeDosNameFile = TKit.createTempFile(Path.of("probeDosName")); + + // The output should be a DOS variant of the `probeDosNameFile` path. + // The filename should differ if the volume owning `probeDosNameFile` file supports DOS names. + final var dosPath = new Executor() + .addArguments("/c", String.format("for %%P in (\"%s\") do @echo %%~sP", probeDosNameFile)) + .setExecutable("cmd") + .dumpOutput() + .executeAndGetFirstLineOfOutput(); + + if (Path.of(dosPath).getFileName().equals(probeDosNameFile.getFileName())) { + TKit.throwSkippedException(String.format("The volume %s owning the test work directory doesn't support DOS paths", + probeDosNameFile.toAbsolutePath().getRoot())); + } + } + } diff --git a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java index 7a915b5c123fd..d70cda7b26452 100644 --- a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ * @requires (jpackage.test.SQETest != null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinLongVersionTest.java + * @compile -Xlint:all -Werror WinLongVersionTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinLongVersionTest.test */ @@ -87,7 +87,7 @@ * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinLongVersionTest.java + * @compile -Xlint:all -Werror WinLongVersionTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinLongVersionTest */ diff --git a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java index bdf5cf2f0a5e2..64533b72c09e9 100644 --- a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java +++ b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; @@ -43,7 +42,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinMenuGroupTest.java + * @compile -Xlint:all -Werror WinMenuGroupTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinMenuGroupTest */ diff --git a/test/jdk/tools/jpackage/windows/WinMenuTest.java b/test/jdk/tools/jpackage/windows/WinMenuTest.java index 8bacaa054706d..a9240f611739b 100644 --- a/test/jdk/tools/jpackage/windows/WinMenuTest.java +++ b/test/jdk/tools/jpackage/windows/WinMenuTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; @@ -40,7 +39,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinMenuTest.java + * @compile -Xlint:all -Werror WinMenuTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinMenuTest */ diff --git a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java index 48fca9644ea98..dc68b63aa96d5 100644 --- a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java +++ b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinPerUserInstallTest.java + * @compile -Xlint:all -Werror WinPerUserInstallTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinPerUserInstallTest */ diff --git a/test/jdk/tools/jpackage/windows/WinResourceTest.java b/test/jdk/tools/jpackage/windows/WinResourceTest.java index 72e805d0a48b5..b34521403f30b 100644 --- a/test/jdk/tools/jpackage/windows/WinResourceTest.java +++ b/test/jdk/tools/jpackage/windows/WinResourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Annotations.Parameters; import java.util.List; +import static jdk.jpackage.test.WindowsHelper.WixType.WIX3; +import static jdk.jpackage.test.WindowsHelper.getWixTypeFromVerboseJPackageOutput; /** * Test --resource-dir option. The test should set --resource-dir to point to @@ -43,7 +45,7 @@ * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinResourceTest.java + * @compile -Xlint:all -Werror WinResourceTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinResourceTest */ @@ -83,11 +85,18 @@ public void test() throws IOException { .addBundleVerifier((cmd, result) -> { // Assert jpackage picked custom main.wxs and failed as expected by // examining its output + final String expectedWixErrorMsg; + if (getWixTypeFromVerboseJPackageOutput(result) == WIX3) { + expectedWixErrorMsg = "error CNDL0104 : Not a valid source file"; + } else { + expectedWixErrorMsg = "error WIX0104: Not a valid source file"; + } + TKit.assertTextStream(expectedLogMessage) .predicate(String::startsWith) .apply(JPackageCommand.stripTimestamps( result.getOutput().stream())); - TKit.assertTextStream("error CNDL0104 : Not a valid source file") + TKit.assertTextStream(expectedWixErrorMsg) .apply(result.getOutput().stream()); }) .setExpectedExitCode(1) diff --git a/test/jdk/tools/jpackage/windows/WinScriptTest.java b/test/jdk/tools/jpackage/windows/WinScriptTest.java index 98b4922826dda..45068ffd39552 100644 --- a/test/jdk/tools/jpackage/windows/WinScriptTest.java +++ b/test/jdk/tools/jpackage/windows/WinScriptTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @library /test/jdk/tools/jpackage/helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinScriptTest.java + * @compile -Xlint:all -Werror WinScriptTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinScriptTest */ @@ -102,6 +102,9 @@ public void test(int wsfExitCode) throws IOException { msiScriptData.assertJPackageOutput(result.getOutput()); }); break; + + default: + throw new UnsupportedOperationException(); } test.run(); diff --git a/test/jdk/tools/jpackage/windows/WinShortcutTest.java b/test/jdk/tools/jpackage/windows/WinShortcutTest.java index 1d2e7e762a533..6e6981ccf9b6c 100644 --- a/test/jdk/tools/jpackage/windows/WinShortcutTest.java +++ b/test/jdk/tools/jpackage/windows/WinShortcutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,6 @@ * questions. */ -import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.Annotations.Test; @@ -41,7 +40,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinShortcutTest.java + * @compile -Xlint:all -Werror WinShortcutTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinShortcutTest */ diff --git a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java index c48803cfb5f67..76f691aa84a90 100644 --- a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java +++ b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ * @requires (jpackage.test.SQETest != null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinUpgradeUUIDTest.java + * @compile -Xlint:all -Werror WinUpgradeUUIDTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinUpgradeUUIDTest.test */ @@ -64,7 +64,7 @@ * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @compile WinUpgradeUUIDTest.java + * @compile -Xlint:all -Werror WinUpgradeUUIDTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinUpgradeUUIDTest */ diff --git a/test/jdk/tools/launcher/DisableBestFitMappingTest.java b/test/jdk/tools/launcher/DisableBestFitMappingTest.java index 6602aae60a9fe..e033b606bc8fa 100644 --- a/test/jdk/tools/launcher/DisableBestFitMappingTest.java +++ b/test/jdk/tools/launcher/DisableBestFitMappingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,10 @@ /* * @test - * @bug 8337506 - * @summary Verify Command Line arguments are not mapped with - * "best-fit" mappings on Windows + * @bug 8337506 8349254 + * @summary Verify command line arguments, including ones from + * "JDK_JAVA_OPTIONS" environment variables are not mapped + * with "best-fit" mappings on Windows * @requires (os.family == "windows") * @library /test/lib * @run junit DisableBestFitMappingTest @@ -34,9 +35,9 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.util.stream.Stream; + import jdk.test.lib.process.ProcessTools; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -49,10 +50,12 @@ public class DisableBestFitMappingTest { Charset.forName(System.getProperty("native.encoding")).newEncoder(); private static final String REPLACEMENT = NATIVE_ENC.charset().decode(ByteBuffer.wrap(NATIVE_ENC.replacement())).toString(); + private static final String TEST_ENV_VAR = "JDK_JAVA_OPTIONS"; + private static final String TEST_PROP_KEY = "testProp"; private static final int EXIT_SUCCESS = 0; private static final int EXIT_FAILURE = -1; - static Stream CMD_ARGS() { + static Stream TEST_ARGS() { return Stream.of( Arguments.of("aa\uff02 \uff02bb", "aa" + REPLACEMENT + " " + REPLACEMENT + "bb"), Arguments.of("aa\uff01bb", "aa" + REPLACEMENT + "bb"), @@ -61,23 +64,41 @@ static Stream CMD_ARGS() { } @ParameterizedTest - @MethodSource("CMD_ARGS") - void testDisableBestFitMapping(String arg, String expected) throws Exception { + @MethodSource("TEST_ARGS") + void testCommandLineArgument(String arg, String expected) throws Exception { // Only execute if the arg cannot be encoded assumeFalse(NATIVE_ENC.canEncode(arg), "native.encoding (%s) can encode the argument '%s'. Test ignored." .formatted(NATIVE_ENC.charset(), arg)); - var result= ProcessTools.executeTestJava( - DisableBestFitMappingTest.class.getSimpleName(), arg, expected); + var result = ProcessTools.executeTestJava( + DisableBestFitMappingTest.class.getSimpleName(), expected, arg); + result.asLines().forEach(System.out::println); + assertEquals(EXIT_SUCCESS, result.getExitValue(), + "Command line argument mapping failed"); + } + + @ParameterizedTest + @MethodSource("TEST_ARGS") + void testEnvironmentVariable(String propVal, String expected) throws Exception { + // Only execute if the arg from the environment variable cannot be encoded + assumeFalse(NATIVE_ENC.canEncode(propVal), + "native.encoding (%s) can encode the argument '%s'. Test ignored." + .formatted(NATIVE_ENC.charset(), propVal)); + + var pb = ProcessTools.createTestJavaProcessBuilder( + DisableBestFitMappingTest.class.getSimpleName(), expected); + pb.environment().put(TEST_ENV_VAR, "-D" + TEST_PROP_KEY + "=\"" + propVal + "\""); + var result = ProcessTools.executeProcess(pb); result.asLines().forEach(System.out::println); assertEquals(EXIT_SUCCESS, result.getExitValue(), - "Disabling best-fit mapping failed"); + "Argument from JDK_JAVA_OPTIONS mapping failed"); } public static void main(String... args) { - System.out.println(args[0]); - System.out.println(args[1]); - System.exit(args[0].equals(args[1]) ? EXIT_SUCCESS : EXIT_FAILURE); + var expected = args[0]; + var actual = args.length > 1 ? args[1] : System.getProperty(TEST_PROP_KEY); + System.out.printf("expected: %s, actual: %s%n", expected, actual); + System.exit(expected.equals(actual) ? EXIT_SUCCESS : EXIT_FAILURE); } } diff --git a/test/jdk/tools/launcher/SourceMode.java b/test/jdk/tools/launcher/SourceMode.java index 20e8822856362..23f0b12e9b491 100644 --- a/test/jdk/tools/launcher/SourceMode.java +++ b/test/jdk/tools/launcher/SourceMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,12 @@ * @bug 8192920 8204588 8210275 8286571 * @summary Test source mode * @modules jdk.compiler jdk.jlink - * @run main SourceMode + * @comment Test is being run in othervm to support JEP 493 enabled + * JDKs which don't allow patched modules. Note that jtreg patches + * module java.base to add java.lang.JTRegModuleHelper. If then a + * jlink run is attempted in-process - using the ToolProvider API - + * on a JEP 493 enabled JDK, the test fails. + * @run main/othervm SourceMode */ diff --git a/test/jdk/tools/sincechecker/SinceChecker.java b/test/jdk/tools/sincechecker/SinceChecker.java index ebd946f3436f0..a7ec90d53f85b 100644 --- a/test/jdk/tools/sincechecker/SinceChecker.java +++ b/test/jdk/tools/sincechecker/SinceChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,10 +102,20 @@ of its enclosing class or interface, whether direct or inherited that were later generified remain the same. usage: the checker is run from a module specific test - `@run main SinceChecker [--exclude package1,package2 | --exclude package1 package2]` + `@run main SinceChecker [--ignoreSince ,] [--exclude package1,package2 | --exclude package1 package2]` + +To help long running projects still in development, that do not have a fixed version number that conforms +to the OpenJDK release cycle, one may want to use token name instead of continuely updating the current version since tags. +For example, `@since LongRunningProjectName`. The option `--ignoreSince` maybe used to +ignore these tags (`-ignoreSince LongRunningProjectName`). Maybe be specified multiple times. */ public class SinceChecker { + private static final int JDK_CURRENT = Runtime.version().feature(); + // Ignored since tags + private static final Set IGNORE_LIST = new HashSet<>(); + // Simply replace ignored since tags with the latest version + private static final Version IGNORE_VERSION = Version.parse(Integer.toString(JDK_CURRENT)); private final Map> LEGACY_PREVIEW_METHODS = new HashMap<>(); private final Map classDictionary = new HashMap<>(); private final JavaCompiler tool; @@ -125,10 +135,16 @@ public static void main(String[] args) throws Exception { } String moduleName = args[0]; boolean excludeFlag = false; + boolean ignoreFlag = false; for (int i = 1; i < args.length; i++) { - if ("--exclude".equals(args[i])) { + if ("--ignoreSince".equals(args[i])) { + ignoreFlag = true; + excludeFlag = false; + continue; + } else if ("--exclude".equals(args[i])) { excludeFlag = true; + ignoreFlag = false; continue; } @@ -139,6 +155,14 @@ public static void main(String[] args) throws Exception { EXCLUDE_LIST.add(args[i]); } } + + if (ignoreFlag) { + if (args[i].contains(",")) { + IGNORE_LIST.addAll(Arrays.asList(args[i].split(","))); + } else { + IGNORE_LIST.add(args[i]); + } + } } SinceChecker sinceCheckerTestHelper = new SinceChecker(moduleName); @@ -152,7 +176,7 @@ private void error(String message) { private SinceChecker(String moduleName) throws IOException { tool = ToolProvider.getSystemJavaCompiler(); - for (int i = 9; i <= Runtime.version().feature(); i++) { + for (int i = 9; i <= JDK_CURRENT; i++) { DiagnosticListener noErrors = d -> { if (!d.getCode().equals("compiler.err.module.not.found")) { error(d.getMessage(null)); @@ -402,7 +426,7 @@ private boolean isNotCommonRecordMethod(TypeElement te, Element element, Types t private void analyzeClassCheck(TypeElement te, String version, EffectiveSourceSinceHelper javadocHelper, Types types, Elements elementUtils) { - String currentjdkVersion = String.valueOf(Runtime.version().feature()); + String currentjdkVersion = String.valueOf(JDK_CURRENT); if (!isDocumented(te)) { return; } @@ -452,24 +476,31 @@ private void checkElement(Element explicitOwner, Element element, Types types, } private Version extractSinceVersionFromText(String documentation) { - Pattern pattern = Pattern.compile("@since\\s+(\\d+(?:\\.\\d+)?)"); - Matcher matcher = pattern.matcher(documentation); - if (matcher.find()) { - String versionString = matcher.group(1); - try { - if (versionString.equals("1.0")) { - versionString = "1"; //ended up being necessary - } else if (versionString.startsWith("1.")) { - versionString = versionString.substring(2); - } - return Version.parse(versionString); - } catch (NumberFormatException ex) { - error("`@since` value that cannot be parsed: " + versionString); - return null; - } - } else { + Matcher matcher = Pattern.compile("@since\\s+(\\S+)").matcher(documentation); + if (!matcher.find()) { + return null; + } + + String versionString = matcher.group(1); + if (IGNORE_LIST.contains(versionString)) { + return IGNORE_VERSION; + } + + versionString = switch (versionString) { + case "1.0" -> "1"; + case String v when v.matches("1\\.\\d+\\.\\d+") -> "1"; // `1.x.x` -> `1` + case String v when v.startsWith("1.") -> v.substring(2); // `1.x` -> `x` + case String v when v.contains("u") -> v.substring(0, v.indexOf('u')); // 6u25 -> 6 + default -> versionString; + }; + + if (!versionString.matches("\\d+(?:\\.\\d+)?")) { + error("Non-numeric `@since` value encountered: '" + versionString + + "'; If this is intentional, consider using the --ignoreSince option."); return null; } + + return Version.parse(versionString); } private void checkEquals(String prefix, String sinceVersion, String mappedVersion, String name) { diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index f5dcb44db2b79..5f74ffa6ea64b 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,7 @@ import java.util.stream.Stream; import jdk.internal.foreign.CABI; +import jdk.internal.misc.PreviewFeatures; import jdk.test.whitebox.code.Compiler; import jdk.test.whitebox.cpuinfo.CPUInfo; import jdk.test.whitebox.gc.GC; @@ -129,6 +130,7 @@ public Map call() { map.put("vm.graal.enabled", this::isGraalEnabled); // jdk.hasLibgraal is true if the libgraal shared library file is present map.put("jdk.hasLibgraal", this::hasLibgraal); + map.put("java.enablePreview", this::isPreviewEnabled); map.put("vm.libgraal.jit", this::isLibgraalJIT); map.put("vm.compiler1.enabled", this::isCompiler1Enabled); map.put("vm.compiler2.enabled", this::isCompiler2Enabled); @@ -140,6 +142,7 @@ public Map call() { map.put("vm.flagless", this::isFlagless); map.put("jdk.foreign.linker", this::jdkForeignLinker); map.put("jlink.packagedModules", this::packagedModules); + map.put("jdk.static", this::isStatic); vmGC(map); // vm.gc.X = true/false vmGCforCDS(map); // may set vm.gc vmOptFinalFlags(map); @@ -452,7 +455,9 @@ protected String vmCDSForCustomLoaders() { } /** - * @return true if this VM can write Java heap objects into the CDS archive + * @return true if it's possible for "java -Xshare:dump" to write Java heap objects + * with the current set of jtreg VM options. For example, false will be returned + * if -XX:-UseCompressedClassPointers is specified, */ protected String vmCDSCanWriteArchivedJavaHeap() { return "" + ("true".equals(vmCDS()) && WB.canWriteJavaHeapArchive() @@ -583,6 +588,9 @@ protected String isCompiler2Enabled() { return "" + Compiler.isC2Enabled(); } + protected String isPreviewEnabled() { + return "" + PreviewFeatures.isEnabled(); + } /** * A simple check for container support * @@ -818,6 +826,10 @@ private String jdkForeignLinker() { return String.valueOf(CABI.current()); } + private String isStatic() { + return Boolean.toString(WB.isStatic()); + } + /** * Dumps the map to the file if the file name is given as the property. * This functionality could be helpful to know context in the real diff --git a/test/langtools/TEST.ROOT b/test/langtools/TEST.ROOT index d816d5b096b79..9b1c5368e66a4 100644 --- a/test/langtools/TEST.ROOT +++ b/test/langtools/TEST.ROOT @@ -15,7 +15,7 @@ keys=intermittent randomness needs-src needs-src-jdk_javadoc groups=TEST.groups # Minimum jtreg version -requiredVersion=7.4+1 +requiredVersion=7.5.1+1 # Use new module options useNewOptions=true @@ -37,10 +37,16 @@ requires.extraPropDefns.bootlibs = ../lib/jdk/test/whitebox requires.extraPropDefns.libs = \ ../lib/jdk/test/lib/Platform.java \ ../lib/jdk/test/lib/Container.java -requires.extraPropDefns.javacOpts = --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED +requires.extraPropDefns.javacOpts = \ + --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.misc=ALL-UNNAMED requires.extraPropDefns.vmOpts = \ - -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI \ - --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED + -XX:+UnlockDiagnosticVMOptions \ + -XX:+LogVMOutput -XX:-DisplayVMOutput -XX:LogFile=vmprops.flags.final.vm.log \ + -XX:+PrintFlagsFinal \ + -XX:+WhiteBoxAPI \ + --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.misc=ALL-UNNAMED requires.properties= \ vm.continuations \ vm.debug diff --git a/test/langtools/jdk/javadoc/doclet/testModuleSpecificStylesheet/TestModuleSpecificStylesheet.java b/test/langtools/jdk/javadoc/doclet/testModuleSpecificStylesheet/TestModuleSpecificStylesheet.java index 48b4750573b26..68deacb0e4756 100644 --- a/test/langtools/jdk/javadoc/doclet/testModuleSpecificStylesheet/TestModuleSpecificStylesheet.java +++ b/test/langtools/jdk/javadoc/doclet/testModuleSpecificStylesheet/TestModuleSpecificStylesheet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8219313 + * @bug 8219313 8347058 * @summary Support module specific stylesheets * @library /tools/lib ../../lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -82,22 +82,22 @@ public void test(Path base) throws Exception { checkOutput("ma/module-summary.html", true, """ - """); + """); checkOutput("ma/pa/package-summary.html", true, """ - """); + """); checkOutput("ma/pa/A.html", true, """ - """); + """); checkOutput("ma/pa/pb/B.html", true, """ - """); + """); checkOutput("ma/pa/pb/package-summary.html", true, """ - """); + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testNewApiList/TestNewApiList.java b/test/langtools/jdk/javadoc/doclet/testNewApiList/TestNewApiList.java index bf89f377d2416..5398502bcd01e 100644 --- a/test/langtools/jdk/javadoc/doclet/testNewApiList/TestNewApiList.java +++ b/test/langtools/jdk/javadoc/doclet/testNewApiList/TestNewApiList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8263468 8269401 8268422 8287524 8325874 + * @bug 8263468 8269401 8268422 8287524 8325874 8331873 * @summary New page for "recent" new API * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -117,7 +117,7 @@ private void checkMultiReleaseContents() { 5 + Toggle all

    Contents

    • Modules
    • @@ -610,7 +610,7 @@ private void checkSingleReleaseDeprecatedElements() { other + Toggle all

      Contents

      • Terminally Deprecated
      • @@ -683,7 +683,7 @@ private void checkPackageContents() { 6 + Toggle all

        Contents

        • Classes
        • diff --git a/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java b/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java index 898a498ddeeae..e04135382114b 100644 --- a/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java +++ b/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 4749567 8071982 8175200 8186332 8185371 8182765 8217034 8261976 8261976 - * 8275786 + * 8275786 8347058 * @summary Test the output for -header, -footer, -nooverview, -nodeprecatedlist, * -nonavbar, -notree, -stylesheetfile, --main-stylesheet, --add-stylesheet, * --add-script options. @@ -118,7 +118,7 @@ public void testStylesheetFile() { checkOutput("resource-files/custom-stylesheet.css", true, "Custom javadoc style sheet"); checkOutput("pkg/Foo.html", true, """ - """); + """); } @Test @@ -131,7 +131,7 @@ public void testStylesheetFileAltOption() { checkOutput("resource-files/custom-stylesheet.css", true, "Custom javadoc style sheet"); checkOutput("pkg/Foo.html", true, """ - """); + """); } @Test @@ -149,9 +149,9 @@ public void testAdditionalStylesheetFile() { checkOutput("resource-files/additional-stylesheet-3.css", true, "Additional javadoc style sheet 3"); checkOutput("pkg/Foo.html", true, """ - - - """); + + + """); } @Test diff --git a/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java b/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java index 9c6ddc5616d4a..284b79577591e 100644 --- a/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java +++ b/test/langtools/jdk/javadoc/doclet/testPackageSpecificStylesheet/TestPackageSpecificStylesheet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8213354 + * @bug 8213354 8347058 * @summary Support package-specific stylesheets * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -82,15 +82,15 @@ public void test(Path base) throws Exception { checkOutput("pkg/A.html", true, """ - """); + """); checkOutput("pkg/package-summary.html", true, """ - """); + """); checkOutput("pkg2/B.html", false, """ - """); + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java index 292d82459829f..ba3f64cd8b29e 100644 --- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java +++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881 * 8181622 8182263 8074407 8187521 8198522 8182765 8199278 8196201 8196202 * 8184205 8214468 8222548 8223378 8234746 8241219 8254627 8247994 8263528 - * 8266808 8248863 8305710 8318082 + * 8266808 8248863 8305710 8318082 8347058 * @summary Test the search feature of javadoc. * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -418,7 +418,7 @@ void checkSearchOutput(String fileName, boolean expectedOutput) { // Test for search related markup checkOutput(fileName, expectedOutput, """ - + """, """ diff --git a/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java b/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java index 06663d2f4181d..a3dce5448f0f8 100644 --- a/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java +++ b/test/langtools/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743 8177417 * 8175218 8176452 8181215 8182263 8183511 8169819 8183037 8185369 8182765 8196201 8184205 8223378 8241544 - * 8253117 8263528 8289334 8292594 + * 8253117 8263528 8289334 8292594 8347058 * @summary Run tests on doclet stylesheet. * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -186,7 +186,7 @@ public void test(Path base) { // Test whether a link to the stylesheet file is inserted properly // in the class documentation. """ - """, + """, """
          Test comment for a class which has an anchor_with_name and an anchor_with_id.
          """); @@ -200,7 +200,7 @@ public void test(Path base) { checkOutput("index.html", true, """ - """); + """); checkOutput("resource-files/stylesheet.css", false, """ diff --git a/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java b/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java index a094ed4a86f3d..99457ea2ce6dc 100644 --- a/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java +++ b/test/langtools/jdk/jshell/FailOverDirectExecutionControlTest.java @@ -62,6 +62,7 @@ public class FailOverDirectExecutionControlTest extends ExecutionControlTestBase ClassLoader ccl; ExecutionControlProvider provider; + Logger logger; LogTestHandler hndlr; Map> logged; @@ -95,7 +96,7 @@ public void close() throws SecurityException { @BeforeMethod @Override public void setUp() { - Logger logger = Logger.getLogger("jdk.jshell.execution"); + logger = Logger.getLogger("jdk.jshell.execution"); logger.setLevel(Level.ALL); hndlr = new LogTestHandler(); logger.addHandler(hndlr); @@ -137,8 +138,8 @@ public void setUp() { @Override public void tearDown() { super.tearDown(); - Logger logger = Logger.getLogger("jdk.jshell.execution"); logger.removeHandler(hndlr); + logger = null; Thread.currentThread().setContextClassLoader(ccl); } diff --git a/test/langtools/tools/javac/6304921/T6304921.java b/test/langtools/tools/javac/6304921/T6304921.java index 51967b6903374..feaf568ee90a9 100644 --- a/test/langtools/tools/javac/6304921/T6304921.java +++ b/test/langtools/tools/javac/6304921/T6304921.java @@ -1,7 +1,7 @@ /* * @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/ * @bug 6304921 - * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java + * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all -Werror T6304921.java */ import java.util.ArrayList; diff --git a/test/langtools/tools/javac/6734819/T6734819a.out b/test/langtools/tools/javac/6734819/T6734819a.out index a3ccb07e67e0a..c29dbde637b29 100644 --- a/test/langtools/tools/javac/6734819/T6734819a.out +++ b/test/langtools/tools/javac/6734819/T6734819a.out @@ -1,9 +1,12 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] +[warn Z] [desugar Z] [desugar W] [desugar Y] diff --git a/test/langtools/tools/javac/6734819/T6734819b.out b/test/langtools/tools/javac/6734819/T6734819b.out index 0c9629006df19..61c1f31f179b6 100644 --- a/test/langtools/tools/javac/6734819/T6734819b.out +++ b/test/langtools/tools/javac/6734819/T6734819b.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A] diff --git a/test/langtools/tools/javac/6734819/T6734819c.out b/test/langtools/tools/javac/6734819/T6734819c.out index 1d4cff3212fd8..6ae56176acba4 100644 --- a/test/langtools/tools/javac/6734819/T6734819c.out +++ b/test/langtools/tools/javac/6734819/T6734819c.out @@ -1,7 +1,9 @@ [attribute Y] [flow Y] +[warn Y] [attribute W] [flow W] +[warn W] [attribute Z] [flow Z] T6734819c.java:15:11: compiler.err.unreachable.stmt diff --git a/test/langtools/tools/javac/ClassCycle/ClassCycle4.java b/test/langtools/tools/javac/ClassCycle/ClassCycle4.java new file mode 100644 index 0000000000000..dbe13a1bf9d40 --- /dev/null +++ b/test/langtools/tools/javac/ClassCycle/ClassCycle4.java @@ -0,0 +1,10 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8320220 + * @summary Fix infinite recursion in cyclic inheritance situation + * @compile/fail/ref=ClassCycle4.out -XDrawDiagnostics ClassCycle4.java + */ + +interface ClassCycle4 extends I1, I2 {} +interface I1 extends ClassCycle4 {} +interface I2 extends ClassCycle4 {} diff --git a/test/langtools/tools/javac/ClassCycle/ClassCycle4.out b/test/langtools/tools/javac/ClassCycle/ClassCycle4.out new file mode 100644 index 0000000000000..2e3d28750ab49 --- /dev/null +++ b/test/langtools/tools/javac/ClassCycle/ClassCycle4.out @@ -0,0 +1,2 @@ +ClassCycle4.java:8:1: compiler.err.cyclic.inheritance: ClassCycle4 +1 error diff --git a/test/langtools/tools/javac/ImportModule.java b/test/langtools/tools/javac/ImportModule.java index 1224a9d747071..a53bc92f1b03f 100644 --- a/test/langtools/tools/javac/ImportModule.java +++ b/test/langtools/tools/javac/ImportModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8328481 8332236 8332890 + * @bug 8328481 8332236 8332890 8344647 8347646 * @summary Check behavior of module imports. * @library /tools/lib * @modules java.logging @@ -33,12 +33,13 @@ * jdk.compiler/com.sun.tools.javac.util * @build toolbox.ToolBox toolbox.JavacTask * @run main ImportModule -*/ + */ import com.sun.source.tree.Tree; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent.Kind; import com.sun.source.util.TaskListener; +import java.lang.classfile.ClassFile; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -829,6 +830,7 @@ public class Test { } } + @Test public void testPackageImportDisambiguates(Path base) throws Exception { Path current = base.resolve("."); Path src = current.resolve("src"); @@ -919,4 +921,130 @@ public class Test { .run(Task.Expect.SUCCESS) .writeAll(); } + + @Test //JDK-8344647 + public void testJavaBaseOverride(Path base) throws Exception { + Path current = base.resolve("."); + Path src = current.resolve("src"); + Path javaBaseClasses = current.resolve("javaBaseClasses"); + Path javaBase = src.resolve("java.base"); + tb.writeJavaFiles(javaBase, + """ + module java.base { + exports java.lang; + } + """, + """ + package java.lang; + public class Object {} + """); + + Files.createDirectories(javaBaseClasses); + + new JavacTask(tb) + .options("--patch-module", "java.base=" + src.toString()) + .outdir(javaBaseClasses) + .files(tb.findJavaFiles(src)) + .run(Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + Path test = current.resolve("test"); + tb.writeJavaFiles(test, + """ + module test { + requires java.se; + } + """); + + Path classes = current.resolve("classes"); + Files.createDirectories(classes); + + new JavacTask(tb) + .options("--patch-module", "java.base=" + javaBaseClasses.toString()) + .outdir(classes) + .files(tb.findJavaFiles(test)) + .run(Task.Expect.SUCCESS) + .writeAll(); + } + + @Test //JDK-8347646 + public void testRequiresTransitiveJavaBase(Path base) throws Exception { + Path current = base.resolve("."); + Path src = current.resolve("src"); + Path classes = current.resolve("classes"); + Path ma = src.resolve("ma"); + Path maClasses = classes.resolve("ma"); + tb.writeJavaFiles(ma, + """ + module ma { + requires transitive java.base; + } + """); + Path test = src.resolve("test"); + tb.writeJavaFiles(test, + """ + module test { + requires ma; + } + """, + """ + package test; + import module ma; + public class Test { + public static void main(String... args) { + System.out.println(List.of("Hello")); + } + } + """); + + Files.createDirectories(maClasses); + + List actualErrors = new JavacTask(tb) + .options("-XDrawDiagnostics") + .outdir(maClasses) + .files(tb.findJavaFiles(ma)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + List expectedErrors = List.of( + "module-info.java:2:4: compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.java.base.transitive)", + "1 error" + ); + + if (!Objects.equals(expectedErrors, actualErrors)) { + throw new AssertionError("Incorrect Output, expected: " + expectedErrors + + ", actual: " + actualErrors); + + } + + new JavacTask(tb) + .options("-XDrawDiagnostics", + "--source", "9") + .outdir(maClasses) + .files(tb.findJavaFiles(ma)) + .run() + .writeAll(); + + Path maModuleInfo = maClasses.resolve("module-info.class"); + + if (ClassFile.of().parse(maModuleInfo).minorVersion() == ClassFile.PREVIEW_MINOR_VERSION) { + throw new AssertionError("wrong minor version"); + } + + new JavacTask(tb) + .options("-XDrawDiagnostics", + "--enable-preview", "--release", SOURCE_VERSION) + .outdir(maClasses) + .files(tb.findJavaFiles(ma)) + .run() + .writeAll(); + + Path maModuleInfo2 = maClasses.resolve("module-info.class"); + + if (ClassFile.of().parse(maModuleInfo2).minorVersion() != ClassFile.PREVIEW_MINOR_VERSION) { + throw new AssertionError("wrong minor version"); + } + } } diff --git a/test/langtools/tools/javac/T5048776.java b/test/langtools/tools/javac/T5048776.java index ff3305a9b346c..30795020c5a9c 100644 --- a/test/langtools/tools/javac/T5048776.java +++ b/test/langtools/tools/javac/T5048776.java @@ -1,8 +1,8 @@ /* * @test /nodynamiccopyright/ * @bug 5048776 - * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java - * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all,-path T5048776.java + * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java + * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all T5048776.java */ class A1 { void foo(Object[] args) { } diff --git a/test/langtools/tools/javac/T6245591.java b/test/langtools/tools/javac/T6245591.java index 7e51e37eab880..8b190dfcdc14e 100644 --- a/test/langtools/tools/javac/T6245591.java +++ b/test/langtools/tools/javac/T6245591.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6245591 - * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all,-path T6245591.java + * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all T6245591.java */ enum Season { /** @deprecated */ diff --git a/test/langtools/tools/javac/T6247324.java b/test/langtools/tools/javac/T6247324.java index ae971350c4760..264827d6dc00e 100644 --- a/test/langtools/tools/javac/T6247324.java +++ b/test/langtools/tools/javac/T6247324.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6247324 - * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint -Xlint:-path T6247324.java + * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint T6247324.java */ class Pair { private X x; diff --git a/test/langtools/tools/javac/T8326485.java b/test/langtools/tools/javac/T8326485.java new file mode 100644 index 0000000000000..ee4ec3e0b112c --- /dev/null +++ b/test/langtools/tools/javac/T8326485.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8326485 + * @compile/fail/ref=T8326485.out -XDrawDiagnostics -XDdev T8326485.java + * @summary Assertion due to Type.addMetadata adding annotations to already-annotated type + */ + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +public class T8326485 { + @Ann + not.java.lang.@Ann String f; +} + +@Target({ElementType.TYPE_USE, ElementType.FIELD}) +@interface Ann {} diff --git a/test/langtools/tools/javac/T8326485.out b/test/langtools/tools/javac/T8326485.out new file mode 100644 index 0000000000000..b3e28f10d228a --- /dev/null +++ b/test/langtools/tools/javac/T8326485.out @@ -0,0 +1,2 @@ +T8326485.java:36:18: compiler.err.doesnt.exist: not.java.lang +1 error diff --git a/test/langtools/tools/javac/analyzer/Diamond.java b/test/langtools/tools/javac/analyzer/Diamond.java new file mode 100644 index 0000000000000..cee8d096cbd2c --- /dev/null +++ b/test/langtools/tools/javac/analyzer/Diamond.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8349132 + * @summary Check behavior of the diamond analyzer + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @run main Diamond + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Objects; + +import toolbox.TestRunner; +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class Diamond extends TestRunner { + + private final ToolBox tb; + + public static void main(String... args) throws Exception { + new Diamond().runTests(); + } + + Diamond() { + super(System.err); + tb = new ToolBox(); + } + + public void runTests() throws Exception { + runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + @Test //JDK-8349132: + public void testMissingClassfileForConstructorParamType(Path base) throws Exception { + Path current = base.resolve("."); + Path lib = current.resolve("lib"); + Path libSrc = lib.resolve("src"); + Path libClasses = lib.resolve("classes"); + tb.writeJavaFiles(libSrc, + """ + package test; + public class Utils { + public static void run(Task uat) { + } + } + """, + """ + package test; + public interface Task { + public void run(T t) throws Exception; + } + """, + """ + package test; + public class Param { + } + """); + + Files.createDirectories(libClasses); + + new JavacTask(tb) + .outdir(libClasses) + .files(tb.findJavaFiles(libSrc)) + .run(Task.Expect.SUCCESS) + .writeAll(); + + Files.delete(libClasses.resolve("test").resolve("Param.class")); + + Path src = current.resolve("src"); + Path classes = current.resolve("classes"); + tb.writeJavaFiles(src, + """ + package test; + public class Test { + private static void test() { + Utils.run(new Task() { + @Override + public void run(Param parameter) throws Exception { + } + }); + } + } + """); + + Files.createDirectories(classes); + + var out = new JavacTask(tb) + .options("-XDfind=diamond", + "-XDshould-stop.at=FLOW", + "-XDrawDiagnostics") + .classpath(libClasses) + .outdir(classes) + .files(tb.findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + var expectedOut = List.of( + "Test.java:4:28: compiler.err.cant.resolve.location: kindname.class, Param, , , (compiler.misc.location: kindname.class, test.Test, null)", + "Test.java:6:29: compiler.err.cant.resolve: kindname.class, Param, , ", + "2 errors" + ); + + if (!Objects.equals(expectedOut, out)) { + throw new AssertionError("Incorrect Output, expected: " + expectedOut + + ", actual: " + out); + + } + } + +} diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsInConstantInit.java b/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsInConstantInit.java new file mode 100644 index 0000000000000..b7b91119bc9da --- /dev/null +++ b/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsInConstantInit.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8346751 + * @summary Verify type annotations inside constant expression field initializers + are handled correctly + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.code + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavacTask + * @run main TypeAnnotationsInConstantInit + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import toolbox.JavacTask; +import toolbox.ToolBox; + +public class TypeAnnotationsInConstantInit { + + public static void main(String... args) throws Exception { + new TypeAnnotationsInConstantInit().run(); + } + + ToolBox tb = new ToolBox(); + + void run() throws Exception { + typeAnnotationInConstantExpressionFieldInit(Paths.get(".")); + } + + void typeAnnotationInConstantExpressionFieldInit(Path base) throws Exception { + Path src = base.resolve("src"); + Path classes = base.resolve("classes"); + tb.writeJavaFiles(src, + """ + import java.lang.annotation.*; + + @SuppressWarnings(Decl.VALUE) + public class Decl { + public static final @Nullable String VALUE = (@Nullable String) ""; + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ ElementType.TYPE_USE }) + @interface Nullable {} + """); + Files.createDirectories(classes); + new JavacTask(tb) + .options("-d", classes.toString()) + .files(tb.findJavaFiles(src)) + .run() + .writeAll(); + } + +} diff --git a/test/langtools/tools/javac/api/TestGetScopeResult.java b/test/langtools/tools/javac/api/TestGetScopeResult.java index babc7a79170fa..533c640096e61 100644 --- a/test/langtools/tools/javac/api/TestGetScopeResult.java +++ b/test/langtools/tools/javac/api/TestGetScopeResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 8240658 8246774 8274347 + * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 8240658 8246774 8274347 8347989 * @summary Test the outcomes from Trees.getScope * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.comp @@ -52,6 +52,7 @@ import com.sun.source.tree.LambdaExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; +import com.sun.source.tree.ReturnTree; import com.sun.source.tree.Scope; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -73,7 +74,12 @@ import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context.Factory; +import java.util.Objects; import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; import javax.lang.model.util.ElementFilter; import javax.tools.JavaFileObject; @@ -93,6 +99,7 @@ public static void main(String... args) throws IOException { new TestGetScopeResult().testRuleCases(); new TestGetScopeResult().testNestedSwitchExpression(); new TestGetScopeResult().testModuleImportScope(); + new TestGetScopeResult().testClassTypeSetInEnterGetScope(); } public void run() throws IOException { @@ -885,6 +892,80 @@ class Test { } } + //JDK-8347989 + void testClassTypeSetInEnterGetScope() throws IOException { + JavacTool c = JavacTool.create(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + String code = """ + import java.util.*; + class Test extends ArrayList + implements List { + private int test(boolean b) { + int v = b ? test(!b) : 0; + return v; + } + } + """; + Context ctx = new Context(); + TestAnalyzer.preRegister(ctx); + JavaFileObject input = + SimpleJavaFileObject.forSource(URI.create("myfo:///Test.java"), code); + JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, + List.of(input), + ctx); + Trees trees = Trees.instance(t); + List> actual = new ArrayList<>(); + + t.addTaskListener(new TaskListener() { + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.ENTER) { + return ; + } + + new TreePathScanner() { + @Override + public Void visitClass(ClassTree node, Void p) { + TypeMirror type = trees.getTypeMirror(getCurrentPath()); + if (type == null) { + throw new AssertionError("Expected class type 'Test', but got: null"); + } + assertEquals(TypeKind.DECLARED, type.getKind()); + DeclaredType decl = (DeclaredType) type; + TypeVariable tvar = (TypeVariable) decl.getTypeArguments().get(0); + assertEquals("T", tvar.asElement().getSimpleName().toString()); + assertEquals("Test&java.lang.CharSequence", tvar.getUpperBound().toString()); + TypeElement clazz = (TypeElement) decl.asElement(); + assertEquals("java.util.ArrayList", clazz.getSuperclass().toString().toString()); + assertEquals("java.util.List", clazz.getInterfaces().toString().toString()); + return super.visitClass(node, p); + } + @Override + public Void visitReturn(ReturnTree rt, Void p) { + Scope scope = trees.getScope(getCurrentPath()); + actual.add(dumpScope(scope)); + return super.visitReturn(rt, p); + } + }.scan(e.getCompilationUnit(), null); + } + }); + + t.analyze(); + + List> expected = + List.of(List.of("v:int", + "b:boolean", + "super:java.util.ArrayList", + "this:Test", + "T:T" + )); + + if (!expected.equals(actual)) { + throw new AssertionError("Unexpected Scope content: " + actual); + } + } + } + private List dumpScope(Scope scope) { List content = new ArrayList<>(); while (scope.getEnclosingClass() != null) { @@ -908,4 +989,10 @@ private void asssertScopeContainsTypeWithFQN(Scope scope, String fqn) { ", but it is missing."); } + private void assertEquals(Object expected, Object actual) { + if (!Objects.equals(expected, actual)) { + throw new AssertionError("Expected: '" + expected + "', " + + "but got: '" + actual + "'"); + } + } } diff --git a/test/langtools/tools/javac/api/TestJavacTaskWithWarning.java b/test/langtools/tools/javac/api/TestJavacTaskWithWarning.java new file mode 100644 index 0000000000000..6f61851a43fc6 --- /dev/null +++ b/test/langtools/tools/javac/api/TestJavacTaskWithWarning.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8348212 8349475 + * @summary Ensure the warn() phase executes when the compiler is invoked via the API + * @modules jdk.compiler/com.sun.tools.javac.api + */ + +import com.sun.tools.javac.api.JavacTaskImpl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +public class TestJavacTaskWithWarning { + + static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + static final StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); + + public static void warningTest() throws Exception { + + // Create a source file that will generate a warning + String srcdir = "."; + File file = new File(srcdir, "GeneratesWarning.java"); + try (PrintStream out = new PrintStream(new FileOutputStream(file))) { + out.print( + """ + public class GeneratesWarning { + public GeneratesWarning() { + hashCode(); // generates a "this-escape" warning + } + } + """); + } + + // Compile it using API + Iterable files = fm.getJavaFileObjectsFromFiles(List.of(file)); + StringWriter buf = new StringWriter(); + List options = List.of( + "-Xlint:this-escape", + "-XDrawDiagnostics" + ); + JavacTaskImpl task = (JavacTaskImpl)compiler.getTask(new PrintWriter(buf), fm, null, options, null, files); + task.analyze(); + + // Verify warning was generated + if (!buf.toString().contains("compiler.warn.possible.this.escape")) + throw new AssertionError("warning not found in:\n" + buf); + } + + public static void main(String[] args) throws Exception { + try { + warningTest(); + } finally { + fm.close(); + } + } +} diff --git a/test/langtools/tools/javac/diags/examples/ModifierNotAllowed/module-info.java b/test/langtools/tools/javac/diags/examples/ModifierNotAllowed/module-info.java index 8eb25a864d7d2..02cb11f5ac257 100644 --- a/test/langtools/tools/javac/diags/examples/ModifierNotAllowed/module-info.java +++ b/test/langtools/tools/javac/diags/examples/ModifierNotAllowed/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -// key: compiler.err.feature.not.supported.in.source.plural +// key: compiler.err.preview.feature.disabled.plural // key: compiler.misc.feature.java.base.transitive module m { diff --git a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out index 11cc81304f034..e240208da72c1 100644 --- a/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out +++ b/test/langtools/tools/javac/implicitCompile/SkipAttrFlowGenForImplicits.out @@ -1,4 +1,5 @@ [attribute Explicit] [flow Explicit] +[warn Explicit] [desugar Explicit] [generate code Explicit] diff --git a/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java index 42bed1d1e4765..44ae29dccaab9 100644 --- a/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java +++ b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8304400 8332226 + * @bug 8304400 8332226 8346778 * @summary Test source launcher running Java programs contained in one module * @modules jdk.compiler/com.sun.tools.javac.launcher * @run junit ModuleSourceLauncherTests @@ -192,6 +192,8 @@ public record Foo() {} class Prog1 { public static void main(String... args) { System.out.println(new foo.Foo()); + System.out.println("bar=" + Prog1.class.getModule().isNativeAccessEnabled()); + System.out.println("foo=" + foo.Foo.class.getModule().isNativeAccessEnabled()); } } """); @@ -199,6 +201,7 @@ public static void main(String... args) { var command = List.of( Path.of(System.getProperty("java.home"), "bin", "java").toString(), "-p", ".", + "--enable-native-access", "foo,bar,baz,ALL-UNNAMED", "bar/bar/Prog1.java"); var redirectedOut = base.resolve("out.redirected"); var redirectedErr = base.resolve("err.redirected"); @@ -212,12 +215,17 @@ public static void main(String... args) { var err = Files.readAllLines(redirectedErr); assertAll( - () -> assertEquals(0, code), + () -> assertEquals(0, code, out.toString()), () -> assertLinesMatch( """ Foo[] + bar=true + foo=true """.lines(), out.stream()), - () -> assertTrue(err.isEmpty()) + () -> assertLinesMatch( + """ + WARNING: Unknown module: baz specified to --enable-native-access + """.lines(), err.stream()) ); } diff --git a/test/langtools/tools/javac/modules/AnnotationsOnModules.java b/test/langtools/tools/javac/modules/AnnotationsOnModules.java index 65019854360d0..291633b4fb240 100644 --- a/test/langtools/tools/javac/modules/AnnotationsOnModules.java +++ b/test/langtools/tools/javac/modules/AnnotationsOnModules.java @@ -804,7 +804,7 @@ public class C {} .writeAll() .getOutputLines(OutputKind.DIRECT); List expectedErrors = List.of( - "- compiler.err.cant.access: m.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.bad.requires.flag: ACC_TRANSITIVE (0x0020))", + "- compiler.err.cant.access: m.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.bad.requires.flag: ACC_TRANSITIVE (0x0020)))", "1 error" ); diff --git a/test/langtools/tools/javac/modules/JavaBaseTest.java b/test/langtools/tools/javac/modules/JavaBaseTest.java index 935ddfa1d437f..a888c430f5369 100644 --- a/test/langtools/tools/javac/modules/JavaBaseTest.java +++ b/test/langtools/tools/javac/modules/JavaBaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,7 +166,7 @@ void testSource(Path base, List mods, String target) throws Exception { for (String mod : mods) { String key = mod.equals("static") ? "compiler.err.mod.not.allowed.here: " + mod - : "compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.java.base.transitive)"; + : "compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.java.base.transitive)"; String message = "module-info.java:1:12: " + key; if (log.contains(message)) { foundErrorMessage = true; diff --git a/test/jdk/java/security/AccessControlContext/FailureDebugOption.java b/test/langtools/tools/javac/options/JavadocIgnoreSymbolFile.java similarity index 52% rename from test/jdk/java/security/AccessControlContext/FailureDebugOption.java rename to test/langtools/tools/javac/options/JavadocIgnoreSymbolFile.java index 2c0dd489c70de..24c24bc3eeee8 100644 --- a/test/jdk/java/security/AccessControlContext/FailureDebugOption.java +++ b/test/langtools/tools/javac/options/JavadocIgnoreSymbolFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,27 +23,28 @@ /* * @test - * @bug 6648816 - * @summary REGRESSION: setting -Djava.security.debug=failure result in NPE - * in ACC - * @run main/othervm -Djava.security.debug=failure FailureDebugOption + * @bug 8348038 + * @summary Verify use of "-XDignore.symbol.file=true" doesn't cause assertion failure + * @modules jdk.javadoc/jdk.javadoc.internal.tool */ -import java.security.ProtectionDomain; -import java.security.AccessController; -import java.security.AccessControlException; -import java.security.BasicPermission; +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; -public class FailureDebugOption { +public class JavadocIgnoreSymbolFile { - public static void main (String argv[]) throws Exception { - try { - AccessController.checkPermission( - new BasicPermission("no such permission"){}); - } catch (NullPointerException npe) { - throw new Exception("Unexpected NullPointerException for security" + - " debug option, -Djava.security.debug=failure"); - } catch (AccessControlException ace) { + public static void main(String[] args) { + String[] javadocArgs = new String[] { + "-XDignore.symbol.file=true" + }; + StringWriter buf = new StringWriter(); + try (PrintWriter pw = new PrintWriter(buf)) { + jdk.javadoc.internal.tool.Main.execute(javadocArgs, pw); } - } + String expected = "error: No modules, packages or classes specified. 1 error"; + String actual = buf.toString().trim().replaceAll("\\s+", " "); + if (!actual.equals(expected)) + throw new AssertionError("unexpected output:\n" + actual); + } } diff --git a/test/langtools/tools/javac/options/OptionsOrderingTest.java b/test/langtools/tools/javac/options/OptionsOrderingTest.java new file mode 100644 index 0000000000000..c1ba021525cf8 --- /dev/null +++ b/test/langtools/tools/javac/options/OptionsOrderingTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8347474 + * @summary Verify -XDrawDiagnostics flag is picked up by JavacMessages singleton + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.file + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util:+open + */ + +import java.io.PrintWriter; +import java.io.Writer; +import java.lang.reflect.Field; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.main.Main; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JavacMessages; +import com.sun.tools.javac.util.RawDiagnosticFormatter; + +import toolbox.JavacTask; +import toolbox.TestRunner; +import toolbox.ToolBox; + +public class OptionsOrderingTest extends TestRunner { + + protected final ToolBox tb; + + public OptionsOrderingTest() { + super(System.err); + tb = new ToolBox(); + } + + public void testJavacMessagesDiagFormatter() throws Exception { + + // Write source file + Path dir = Paths.get(getClass().getSimpleName()); + tb.writeJavaFiles(dir, "class Test { }"); + + // Run the compiler where we supply the Context + Context context = new Context(); + JavacFileManager.preRegister(context); + Main compiler = new Main("javac", new PrintWriter(Writer.nullWriter())); + String[] args = new String[] { + "-XDrawDiagnostics", + tb.findJavaFiles(dir)[0].toString() + }; + Main.Result result = compiler.compile(args, context); + + // Verify field JavacMessages.diagFormatter is a RawDiagnosticFormatter + JavacMessages messages = JavacMessages.instance(context); + Field diagFormatterField = messages.getClass().getDeclaredField("diagFormatter"); + diagFormatterField.setAccessible(true); + Class diagFormatterClass = diagFormatterField.get(messages).getClass(); + if (!Objects.equals(diagFormatterClass, RawDiagnosticFormatter.class)) { + throw new AssertionError(String.format( + "diagFormatter: expected %s but found %s", + RawDiagnosticFormatter.class, diagFormatterClass)); + } + } + + public static void main(String... args) throws Exception { + new OptionsOrderingTest().testJavacMessagesDiagFormatter(); + } +} diff --git a/test/langtools/tools/javac/options/system/SystemSunProprietary.java b/test/langtools/tools/javac/options/system/SystemSunProprietary.java index 0a16305aaba7b..a057972d73d57 100644 --- a/test/langtools/tools/javac/options/system/SystemSunProprietary.java +++ b/test/langtools/tools/javac/options/system/SystemSunProprietary.java @@ -23,14 +23,18 @@ /** * @test - * @bug 8331081 + * @bug 8331081 8349058 * @summary Verify 'internal proprietary API' diagnostics if --system is configured * @library /tools/lib - * @modules jdk.compiler/com.sun.tools.javac.api jdk.compiler/com.sun.tools.javac.main - * jdk.compiler/com.sun.tools.javac.jvm jdk.jdeps/com.sun.tools.javap + * @modules jdk.compiler/com.sun.tools.javac.api jdk.compiler/com.sun.tools.javac.file + * jdk.compiler/com.sun.tools.javac.jvm jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util jdk.jdeps/com.sun.tools.javap * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.TestRunner * @run main SystemSunProprietary */ +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Context; + import toolbox.JavacTask; import toolbox.Task; import toolbox.Task.Expect; @@ -41,13 +45,17 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class SystemSunProprietary extends TestRunner { private final ToolBox tb = new ToolBox(); + private Path src; + private Path classes; + public SystemSunProprietary() { super(System.err); } @@ -58,45 +66,14 @@ public static void main(String... args) throws Exception { @Test public void testUnsafe(Path base) throws IOException { - Path src = base.resolve("src"); + src = base.resolve("src"); tb.writeJavaFiles( src, "module m { requires jdk.unsupported; }", "package test; public class Test { sun.misc.Unsafe unsafe; } "); - Path classes = base.resolve("classes"); - tb.createDirectories(classes); - - List log; - List expected = - Arrays.asList( - "Test.java:1:43: compiler.warn.sun.proprietary: sun.misc.Unsafe", - "1 warning"); - log = - new JavacTask(tb) - .options("-XDrawDiagnostics") - .outdir(classes) - .files(tb.findJavaFiles(src)) - .run(Expect.SUCCESS) - .writeAll() - .getOutputLines(Task.OutputKind.DIRECT); - - if (!expected.equals(log)) { - throw new AssertionError("Unexpected output: " + log); - } - - log = - new JavacTask(tb) - .options("-XDrawDiagnostics", "--system", System.getProperty("java.home")) - .outdir(classes) - .files(tb.findJavaFiles(src)) - .run(Expect.SUCCESS) - .writeAll() - .getOutputLines(Task.OutputKind.DIRECT); - - if (!expected.equals(log)) { - throw new AssertionError("Unexpected output: " + log); - } + classes = base.resolve("classes"); + tb.createDirectories(classes); // Create a valid argument to system that isn't the current java.home Path originalSystem = Path.of(System.getProperty("java.home")); @@ -107,17 +84,54 @@ public void testUnsafe(Path base) throws IOException { Files.copy(originalSystem.resolve(path), to); } - log = + expectSunapi(false); + expectSunapi(false, "--system", System.getProperty("java.home")); + expectSunapi(false, "--release", String.valueOf(Runtime.version().feature())); + expectSunapi(false, "--release", String.valueOf(Runtime.version().feature() - 1)); + expectSunapi(true, "--release", String.valueOf(Runtime.version().feature())); + expectSunapi(true, "--release", String.valueOf(Runtime.version().feature() - 1)); + + // non-default --system arguments disable sunapi, see JDK-8349058 + expectNoSunapi(false, "--system", system.toString()); + + // -XDignore.symbol.file disables sunapi diagnostics, see JDK-8349058 + expectNoSunapi(true); + expectNoSunapi(true, "--system", System.getProperty("java.home")); + expectNoSunapi(true, "--system", system.toString()); + } + + private void expectSunapi(boolean ignoreSymbolFile, String... options) throws IOException { + expectSunapi(true, ignoreSymbolFile, options); + } + + private void expectNoSunapi(boolean ignoreSymbolFile, String... options) throws IOException { + expectSunapi(false, ignoreSymbolFile, options); + } + + private void expectSunapi(boolean expectDiagnostic, boolean ignoreSymbolFile, String... options) + throws IOException { + List expected = + expectDiagnostic + ? List.of( + "Test.java:1:43: compiler.warn.sun.proprietary: sun.misc.Unsafe", + "1 warning") + : List.of(""); + List allOptions = new ArrayList<>(); + allOptions.add("-XDrawDiagnostics"); + Collections.addAll(allOptions, options); + JavacFileManager fm = new JavacFileManager(new Context(), false, null); + fm.setSymbolFileEnabled(!ignoreSymbolFile); + List log = new JavacTask(tb) - .options("-XDrawDiagnostics", "--system", system.toString()) + .fileManager(fm) + .options(allOptions) .outdir(classes) .files(tb.findJavaFiles(src)) .run(Expect.SUCCESS) .writeAll() .getOutputLines(Task.OutputKind.DIRECT); - - if (!expected.equals(log)) { - throw new AssertionError("Unexpected output: " + log); + if (!log.equals(expected)) { + throw new AssertionError("expected: " + expected + "\nactual: " + log + "\n"); } } diff --git a/test/langtools/tools/javac/policy/test1/byfile.ABD.out b/test/langtools/tools/javac/policy/test1/byfile.ABD.out index dfa86a4413294..0710de49c867d 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ABD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ABD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/byfile.ACD.out b/test/langtools/tools/javac/policy/test1/byfile.ACD.out index 66534ce00c5f8..70cc4856557c7 100644 --- a/test/langtools/tools/javac/policy/test1/byfile.ACD.out +++ b/test/langtools/tools/javac/policy/test1/byfile.ACD.out @@ -4,6 +4,9 @@ [flow A] [flow A1] [flow A2] +[warn A] +[warn A1] +[warn A2] [desugar A] [desugar A1] [desugar A2] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out index 5b3b8faace742..3296547f0ffec 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ABD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ABD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute B] [flow B] +[warn B] [desugar B] [generate code B] [attribute B1] diff --git a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out index a29c0880de96c..767a9912a05e8 100644 --- a/test/langtools/tools/javac/policy/test1/bytodo.ACD.out +++ b/test/langtools/tools/javac/policy/test1/bytodo.ACD.out @@ -1,17 +1,21 @@ [attribute A] [flow A] +[warn A] [desugar A] [generate code A] [attribute A1] [flow A1] +[warn A1] [desugar A1] [generate code A1] [attribute A2] [flow A2] +[warn A2] [desugar A2] [generate code A2] [attribute C] [flow C] +[warn C] [desugar C] [generate code C] [attribute C1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.AB.out b/test/langtools/tools/javac/policy/test2/byfile.AB.out index 6d152c873aabe..63a51108f3646 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.AB.out +++ b/test/langtools/tools/javac/policy/test2/byfile.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/byfile.BA.out b/test/langtools/tools/javac/policy/test2/byfile.BA.out index 565ad13861529..3c3567043a0f1 100644 --- a/test/langtools/tools/javac/policy/test2/byfile.BA.out +++ b/test/langtools/tools/javac/policy/test2/byfile.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.AB.out b/test/langtools/tools/javac/policy/test2/bytodo.AB.out index 6d152c873aabe..63a51108f3646 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.AB.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.AB.out @@ -1,7 +1,9 @@ [attribute A] [flow A] +[warn A] [attribute B] [flow B] +[warn B] [desugar B] [desugar A] [generate code A.A1] diff --git a/test/langtools/tools/javac/policy/test2/bytodo.BA.out b/test/langtools/tools/javac/policy/test2/bytodo.BA.out index 565ad13861529..3c3567043a0f1 100644 --- a/test/langtools/tools/javac/policy/test2/bytodo.BA.out +++ b/test/langtools/tools/javac/policy/test2/bytodo.BA.out @@ -1,10 +1,12 @@ [attribute B] [flow B] +[warn B] [desugar B] [generate code B.Inner] [generate code B] [attribute A] [flow A] +[warn A] [desugar A] [generate code A.A1] [generate code A.A2] diff --git a/test/langtools/tools/javac/processing/TestWarnErrorCount.java b/test/langtools/tools/javac/processing/TestWarnErrorCount.java index 1ea2b803609c4..957bafdab7f17 100644 --- a/test/langtools/tools/javac/processing/TestWarnErrorCount.java +++ b/test/langtools/tools/javac/processing/TestWarnErrorCount.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) { "-d", testDir.getPath(), "-processor", myName, // "-XprintRounds", - "-Xlint:all,-path", + "-Xlint:all", "-AerrKind=" + ek, "-AmsgrWarnKind=" + mwk, "-AjavaWarnKind=" + jwk)); diff --git a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java index 904e4e78cad1f..f94ba461a4500 100644 --- a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java +++ b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java @@ -163,7 +163,7 @@ public Void scan(Element elem, Void ignore) { */ class TestTypeScanner extends TypeScanner { Element elem; - NavigableMap toBeFound; + NavigableMap> toBeFound; int count = 0; Set seen = new HashSet<>(); @@ -171,10 +171,10 @@ class TestTypeScanner extends TypeScanner { super(types); this.elem = elem; - NavigableMap testByPos = new TreeMap<>(); + NavigableMap> testByPos = new TreeMap<>(); for (AnnotationMirror test : tests) { for (int pos : getPosn(test)) { - testByPos.put(pos, test); + testByPos.computeIfAbsent(pos, ArrayList::new).add(test); } } this.toBeFound = testByPos; @@ -196,17 +196,18 @@ Void scan(TypeMirror t, Void ignore) { out.println("scan " + count + ": " + t); if (toBeFound.size() > 0) { if (toBeFound.firstKey().equals(count)) { - AnnotationMirror test = toBeFound.pollFirstEntry().getValue(); - String annoType = getAnnoType(test); - AnnotationMirror anno = getAnnotation(t, annoType); - if (anno == null) { - error(elem, "annotation not found on " + count + ": " + t); - } else { - String v = getValue(anno, "value").toString(); - if (v.equals(getExpect(test))) { - out.println("found " + anno + " as expected"); + for (AnnotationMirror test : toBeFound.pollFirstEntry().getValue()) { + String annoType = getAnnoType(test); + AnnotationMirror anno = getAnnotation(t, annoType); + if (anno == null) { + error(elem, "annotation not found on " + count + ": " + t); } else { - error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); + String v = getValue(anno, "value").toString(); + if (v.equals(getExpect(test))) { + out.println("found " + anno + " as expected"); + } else { + error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); + } } } } else if (count > toBeFound.firstKey()) { diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index db679915e08b2..c5d393a23b323 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public void overridable(C c) {} Path curPath = Path.of("."); List actual = new JavacTask(tb) .options("-XDrawDiagnostics", "-XDdev", - "-XDshould-stop.at=FLOW", "-Xlint:this-escape") + "-XDshould-stop.at=WARN", "-Xlint:this-escape") .sources(code) .outdir(curPath) .run(Expect.FAIL) diff --git a/test/langtools/tools/javac/sealed/SealedCompilationTests.java b/test/langtools/tools/javac/sealed/SealedCompilationTests.java index dee64fd0865aa..7cf63f5b2d5fd 100644 --- a/test/langtools/tools/javac/sealed/SealedCompilationTests.java +++ b/test/langtools/tools/javac/sealed/SealedCompilationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * SealedCompilationTests * * @test - * @bug 8246353 8273257 8294550 + * @bug 8246353 8273257 8294550 8347562 * @summary Negative compilation tests, and positive compilation (smoke) tests for sealed classes * @library /lib/combo /tools/lib * @modules @@ -41,6 +41,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -61,6 +62,7 @@ import toolbox.Task; import toolbox.Task.OutputKind; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; class SealedCompilationTests extends CompilationTestCase { @@ -560,6 +562,13 @@ sealed class C permits T {} """)) { assertFail("compiler.err.invalid.permits.clause", s); } + assertFail("compiler.err.illegal.forward.ref", _ -> { + assertEquals(Collections.nCopies(2, "compiler.err.illegal.forward.ref"), diags.keys()); + }, + """ + sealed class Permits permits X, Y {} + """ + ); } @Test diff --git a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java index 597d4b16e68e0..30fc23922bba5 100644 --- a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java +++ b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java @@ -22,7 +22,7 @@ */ /* - * @test 8247352 8293348 + * @test 8247352 8293348 8349512 * @summary test different configurations of sealed classes, same compilation unit, diff pkg or mdl, etc * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -132,7 +132,10 @@ private void checkSealedClassFile(Path out, String cfName, List expected ClassModel sealedCF = ClassFile.of().parse(out.resolve(cfName)); Assert.check((sealedCF.flags().flagsMask() & ClassFile.ACC_FINAL) == 0, String.format("class at file %s must not be final", cfName)); PermittedSubclassesAttribute permittedSubclasses = sealedCF.findAttribute(Attributes.permittedSubclasses()).orElseThrow(); - Assert.check(permittedSubclasses.permittedSubclasses().size() == expectedSubTypeNames.size()); + Assert.check(permittedSubclasses.permittedSubclasses().size() == expectedSubTypeNames.size(), + String.format("%s != %s", + permittedSubclasses.permittedSubclasses(), + expectedSubTypeNames)); List subtypeNames = new ArrayList<>(); permittedSubclasses.permittedSubclasses().forEach(i -> { try { @@ -726,4 +729,33 @@ public void blah(Foo.R2 a, Foo.R1 b) {} .run(); checkSealedClassFile(out, "Foo.class", List.of("Foo$R1", "Foo$R2")); } + + @Test + public void testDuplicatePermittedSubclassesDoclint(Path base) throws Exception { + Path src = base.resolve("src"); + Path foo = src.resolve("Foo.java"); + + tb.writeFile(foo, + """ + public class Foo { + private enum E { + INSTANCE { + /** foo {@link E} */ + void f() {} + }; + void f() {} + } + } + """); + + Path out = base.resolve("out"); + Files.createDirectories(out); + + new JavacTask(tb) + .options("-Xdoclint:html,syntax") + .outdir(out) + .files(foo) + .run(); + checkSealedClassFile(out, "Foo$E.class", List.of("Foo$E$1")); + } } diff --git a/test/langtools/tools/javac/warnings/DivZero.java b/test/langtools/tools/javac/warnings/DivZero.java index 2a965f3fbaf2c..3df7db166d7a4 100644 --- a/test/langtools/tools/javac/warnings/DivZero.java +++ b/test/langtools/tools/javac/warnings/DivZero.java @@ -3,7 +3,7 @@ * @bug 4759494 4986256 * @compile/ref=DivZero.noLint.out -XDrawDiagnostics DivZero.java * @compile/ref=DivZero.lint.out -Xlint:divzero -XDrawDiagnostics DivZero.java - * @compile/ref=DivZero.lint.out -Xlint:all,-path -XDrawDiagnostics DivZero.java + * @compile/ref=DivZero.lint.out -Xlint:all -XDrawDiagnostics DivZero.java */ class DivZero diff --git a/test/langtools/tools/javac/warnings/FallThrough.java b/test/langtools/tools/javac/warnings/FallThrough.java index 6e5a5eb8bc914..6185c3e0df92f 100644 --- a/test/langtools/tools/javac/warnings/FallThrough.java +++ b/test/langtools/tools/javac/warnings/FallThrough.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 4986256 * @compile/ref=FallThrough.noLint.out -XDrawDiagnostics FallThrough.java - * @compile/ref=FallThrough.lintAll.out -Xlint:all,-path -XDrawDiagnostics FallThrough.java + * @compile/ref=FallThrough.lintAll.out -Xlint:all -XDrawDiagnostics FallThrough.java * @compile/ref=FallThrough.lintFallThrough.out -Xlint:fallthrough -XDrawDiagnostics FallThrough.java */ diff --git a/test/langtools/tools/javac/warnings/Unchecked.java b/test/langtools/tools/javac/warnings/Unchecked.java index e64fd760a0764..7cd8cbfdfd049 100644 --- a/test/langtools/tools/javac/warnings/Unchecked.java +++ b/test/langtools/tools/javac/warnings/Unchecked.java @@ -3,7 +3,7 @@ * @bug 4986256 * @compile/ref=Unchecked.noLint.out -XDrawDiagnostics Unchecked.java * @compile/ref=Unchecked.lintUnchecked.out -Xlint:unchecked -XDrawDiagnostics Unchecked.java - * @compile/ref=Unchecked.lintAll.out -Xlint:all,-path -XDrawDiagnostics Unchecked.java + * @compile/ref=Unchecked.lintAll.out -Xlint:all -XDrawDiagnostics Unchecked.java */ import java.util.ArrayList; diff --git a/test/lib-test/TEST.ROOT b/test/lib-test/TEST.ROOT index 27576a2d04019..5908b50cb170d 100644 --- a/test/lib-test/TEST.ROOT +++ b/test/lib-test/TEST.ROOT @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ keys=randomness # Minimum jtreg version -requiredVersion=7.4+1 +requiredVersion=7.5.1+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff --git a/test/lib-test/jdk/test/lib/AssertsTest.java b/test/lib-test/jdk/test/lib/AssertsTest.java index 9acb6be98c554..62db122e67233 100644 --- a/test/lib-test/jdk/test/lib/AssertsTest.java +++ b/test/lib-test/jdk/test/lib/AssertsTest.java @@ -25,12 +25,12 @@ import java.lang.SuppressWarnings; import java.util.Arrays; -import java.util.HexFormat; import static jdk.test.lib.Asserts.*; /* * @test + * @bug 8340493 * @library /test/lib * @summary Tests the different assertions in the Assert class */ @@ -49,6 +49,29 @@ public String toString() { } } + // equals() always returns true + public static class Bar { + private final int i; + public Bar(int i) { + this.i = i; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object obj) { + return true; + } + + @Override + public String toString() { + return Integer.toString(i); + } + } + public static void main(String[] args) throws Exception { testLessThan(); testLessThanOrEqual(); @@ -62,6 +85,19 @@ public static void main(String[] args) throws Exception { testTrue(); testFalse(); testFail(); + + testErrorMessages(); + } + + public static void testErrorMessages() throws Exception { + try { + Asserts.assertNotEquals(new Bar(1), new Bar(2)); + throw new Exception("Should fail"); + } catch (RuntimeException e) { + if (!e.getMessage().contains("was 2")) { + throw new Exception("msg is " + e.getMessage()); + } + } } private static void testLessThan() throws Exception { @@ -216,8 +252,7 @@ private static > void expectFail(Assertion assertion, T " to throw a RuntimeException"); } - private static void expectPass(Assertion assertion, byte[] b1, byte[] b2) - throws Exception { + private static void expectPass(Assertion assertion, byte[] b1, byte[] b2) { if (assertion == Assertion.EQBA) { String msg = "Expected " + Assertion.asString("assertEqualsByteArray", Arrays.toString(b1), Arrays.toString(b2)) + " to pass"; diff --git a/test/lib-test/jdk/test/lib/security/CPVAlgTestWithOCSP.java b/test/lib-test/jdk/test/lib/security/CPVAlgTestWithOCSP.java new file mode 100644 index 0000000000000..c1874492a3b7a --- /dev/null +++ b/test/lib-test/jdk/test/lib/security/CPVAlgTestWithOCSP.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8349759 + * @summary Test the CertificateBuilder and SimpleOCSPServer test utility + * classes using a range of signature algorithms and parameters. + * The goal is to test with both no-parameter and parameterized + * signature algorithms and use the CertPathValidator to validate + * the correctness of the certificate and OCSP server-side structures. + * @modules java.base/sun.security.x509 + * java.base/sun.security.provider.certpath + * java.base/sun.security.util + * @library /test/lib + * @run main/othervm CPVAlgTestWithOCSP RSA + * @run main/othervm CPVAlgTestWithOCSP RSA:3072 + * @run main/othervm CPVAlgTestWithOCSP DSA + * @run main/othervm CPVAlgTestWithOCSP DSA:3072 + * @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS + * @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS:3072 + * @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS:4096:SHA-512:SHA3-384:128:1 + * @run main/othervm CPVAlgTestWithOCSP EC + * @run main/othervm CPVAlgTestWithOCSP EC:secp521r1 + * @run main/othervm CPVAlgTestWithOCSP Ed25519 + * @run main/othervm CPVAlgTestWithOCSP ML-DSA-65 + */ + +import java.math.BigInteger; +import java.security.*; +import java.security.cert.*; +import java.security.cert.Certificate; +import java.security.spec.*; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import jdk.test.lib.security.SimpleOCSPServer; +import jdk.test.lib.security.CertificateBuilder; + +import static java.security.cert.PKIXRevocationChecker.Option.NO_FALLBACK; + +public class CPVAlgTestWithOCSP { + + static final String passwd = "passphrase"; + static final String ROOT_ALIAS = "root"; + static final boolean[] CA_KU_FLAGS = {true, false, false, false, false, + true, true, false, false}; + static final boolean[] EE_KU_FLAGS = {true, false, false, false, false, + false, false, false, false}; + static final List EE_EKU_OIDS = List.of("1.3.6.1.5.5.7.3.1", + "1.3.6.1.5.5.7.3.2"); + + public static void main(String[] args) throws Exception { + if (args == null || args.length < 1) { + throw new RuntimeException( + "Usage: CPVAlgTestWithOCSP "); + } + String keyGenAlg = args[0]; + + // Generate Root and EE keys + KeyPairGenerator keyGen = getKpGen(keyGenAlg); + KeyPair rootCaKP = keyGen.genKeyPair(); + KeyPair eeKp = keyGen.genKeyPair(); + + // Set up the Root CA Cert + // Make a 3 year validity starting from 60 days ago + long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60); + long end = start + TimeUnit.DAYS.toMillis(1085); + CertificateBuilder cbld = new CertificateBuilder(); + cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany"). + setPublicKey(rootCaKP.getPublic()). + setSerialNumber(new BigInteger("1")). + setValidity(new Date(start), new Date(end)). + addSubjectKeyIdExt(rootCaKP.getPublic()). + addAuthorityKeyIdExt(rootCaKP.getPublic()). + addBasicConstraintsExt(true, true, -1). + addKeyUsageExt(CA_KU_FLAGS); + + // Make our Root CA Cert! + X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate()); + log("Root CA Created:\n%s", rootCert); + + // Now build a keystore and add the keys and cert + KeyStore.Builder keyStoreBuilder = + KeyStore.Builder.newInstance("PKCS12", null, + new KeyStore.PasswordProtection("adminadmin0".toCharArray())); + KeyStore rootKeystore = keyStoreBuilder.getKeyStore(); + Certificate[] rootChain = {rootCert}; + rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(), + passwd.toCharArray(), rootChain); + + // Now fire up the OCSP responder + SimpleOCSPServer rootOcsp = new SimpleOCSPServer(rootKeystore, + passwd, ROOT_ALIAS, null); + rootOcsp.enableLog(true); + rootOcsp.setNextUpdateInterval(3600); + rootOcsp.start(); + + // Wait 60 seconds for server ready + boolean readyStatus = rootOcsp.awaitServerReady(60, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); + } + int rootOcspPort = rootOcsp.getPort(); + String rootRespURI = "http://localhost:" + rootOcspPort; + log("Root OCSP Responder URI is %s", rootRespURI); + + // Let's make an EE cert + // Make a 1 year validity starting from 60 days ago + start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60); + end = start + TimeUnit.DAYS.toMillis(365); + cbld.reset().setSubjectName("CN=Brave Sir Robin, O=SomeCompany"). + setPublicKey(eeKp.getPublic()). + setValidity(new Date(start), new Date(end)). + addSubjectKeyIdExt(eeKp.getPublic()). + addAuthorityKeyIdExt(rootCaKP.getPublic()). + addKeyUsageExt(EE_KU_FLAGS). + addExtendedKeyUsageExt(EE_EKU_OIDS). + addSubjectAltNameDNSExt(Collections.singletonList("localhost")). + addAIAExt(Collections.singletonList(rootRespURI)); + X509Certificate eeCert = cbld.build(rootCert, rootCaKP.getPrivate()); + log("EE CA Created:\n%s", eeCert); + + // Provide end entity cert revocation info to the Root CA + // OCSP responder. + Map revInfo = + new HashMap<>(); + revInfo.put(eeCert.getSerialNumber(), + new SimpleOCSPServer.CertStatusInfo( + SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD)); + rootOcsp.updateStatusDb(revInfo); + + // validate chain + CertPathValidator cpv = CertPathValidator.getInstance("PKIX"); + PKIXRevocationChecker prc = + (PKIXRevocationChecker) cpv.getRevocationChecker(); + prc.setOptions(EnumSet.of(NO_FALLBACK)); + PKIXParameters params = + new PKIXParameters(Set.of(new TrustAnchor(rootCert, null))); + params.addCertPathChecker(prc); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + CertPath cp = cf.generateCertPath(List.of(eeCert)); + cpv.validate(cp, params); + } + + private static KeyPairGenerator getKpGen(String keyGenAlg) + throws GeneralSecurityException { + String[] algComps = keyGenAlg.split(":"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(algComps[0]); + int bitLen; + + // Handle any parameters in additional tokenized fields + switch (algComps[0].toUpperCase()) { + case "EC": + // The curve name will be the second token, or secp256r1 + // if not provided. + String curveName = (algComps.length >= 2) ? algComps[1] : + "secp256r1"; + kpg.initialize(new ECGenParameterSpec(curveName)); + break; + case "RSA": + case "DSA": + // Form is RSA|DSA[:] + bitLen = (algComps.length >= 2) ? + Integer.parseInt(algComps[1]) : 2048; + kpg.initialize(bitLen); + break; + case "RSASSA-PSS": + // Form is RSASSA-PSS[:[:HASH:MGFHASH:SALTLEN:TR]] + switch (algComps.length) { + case 1: // Default key length and parameters + kpg.initialize(2048); + break; + case 2: // Specified key length, default params + kpg.initialize(Integer.parseInt(algComps[1])); + break; + default: // len > 2, key length and specified parameters + bitLen = Integer.parseInt(algComps[1]); + String hashAlg = algComps[2]; + MGF1ParameterSpec mSpec = (algComps.length >= 4) ? + new MGF1ParameterSpec(algComps[3]) : + MGF1ParameterSpec.SHA256; + int saltLen = (algComps.length >= 5) ? + Integer.parseInt(algComps[4]) : 32; + int trail = (algComps.length >= 6) ? + Integer.parseInt(algComps[5]) : + PSSParameterSpec.TRAILER_FIELD_BC; + PSSParameterSpec pSpec = new PSSParameterSpec(hashAlg, + "MGF1", mSpec, saltLen, trail); + kpg.initialize(new RSAKeyGenParameterSpec(bitLen, + RSAKeyGenParameterSpec.F4, pSpec)); + break; + } + + // Default: just use the KPG as-is, no additional init needed. + } + + return kpg; + } + + /** + * Log a message on stdout + * + * @param format the format string for the log entry + * @param args zero or more arguments corresponding to the format string + */ + private static void log(String format, Object ... args) { + System.out.format(format + "\n", args); + } +} diff --git a/test/lib-test/jdk/test/lib/security/FixedSecureRandomTest.java b/test/lib-test/jdk/test/lib/security/FixedSecureRandomTest.java index bdebc9e0a8c89..cfe86bac49f82 100644 --- a/test/lib-test/jdk/test/lib/security/FixedSecureRandomTest.java +++ b/test/lib-test/jdk/test/lib/security/FixedSecureRandomTest.java @@ -35,13 +35,13 @@ public static void main(String[] args) throws Exception { new byte[] {4, 5, 6}); var b1 = new byte[2]; fsr.nextBytes(b1); - Asserts.assertEqualsByteArray(b1, new byte[] {1, 2}); + Asserts.assertEqualsByteArray(new byte[] {1, 2}, b1); Asserts.assertTrue(fsr.hasRemaining()); fsr.nextBytes(b1); - Asserts.assertEqualsByteArray(b1, new byte[] {3, 4}); + Asserts.assertEqualsByteArray(new byte[] {3, 4}, b1); Asserts.assertTrue(fsr.hasRemaining()); fsr.nextBytes(b1); - Asserts.assertEqualsByteArray(b1, new byte[] {5, 6}); + Asserts.assertEqualsByteArray(new byte[] {5, 6}, b1); Asserts.assertFalse(fsr.hasRemaining()); Utils.runAndCheckException(() -> fsr.nextBytes(b1), IllegalStateException.class); diff --git a/test/lib/jdk/test/lib/Asserts.java b/test/lib/jdk/test/lib/Asserts.java index 893f1a1a73763..517df45481051 100644 --- a/test/lib/jdk/test/lib/Asserts.java +++ b/test/lib/jdk/test/lib/Asserts.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,10 @@ package jdk.test.lib; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.HexFormat; import java.util.Objects; @@ -234,59 +238,58 @@ public static void assertSame(Object lhs, Object rhs, String msg) { } /** - * Asserts that {@code lhs} is the same byte array as {@code rhs}. + * Asserts that {@code actual} has the same content as {@code expected}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param expected The expected value + * @param actual The actual value * @throws RuntimeException if the assertion is not true. * @see #assertEqualsByteArray(byte[], byte[], String) */ - public static void assertEqualsByteArray(byte[] lhs, byte[] rhs) { - assertEqualsByteArray(lhs, rhs, null); + public static void assertEqualsByteArray(byte[] expected, byte[] actual) { + assertEqualsByteArray(expected, actual, null); } /** - * Asserts that {@code lhs} is not the same byte array as {@code rhs}. + * Asserts that {@code actual} does not have the same content as {@code unexpected}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @throws RuntimeException if the assertion is not true. * @see #assertNotEqualsByteArray(byte[], byte[], String) */ - public static void assertNotEqualsByteArray(byte[] lhs, byte[] rhs) { - assertNotEqualsByteArray(lhs, rhs, null); + public static void assertNotEqualsByteArray(byte[] unexpected, byte[] actual) { + assertNotEqualsByteArray(unexpected, actual, null); } /** - * Asserts that {@code lhs} is the same byte array as {@code rhs}. + * Asserts that {@code actual} is the same byte array as {@code expected}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param expected The expected value + * @param actual The actual value * @param msg A description of the assumption; {@code null} for a default message. * @throws RuntimeException if the assertion is not true. */ - public static void assertEqualsByteArray(byte[] lhs, byte[] rhs, String msg) { - if (!Arrays.equals(lhs, rhs)) { + public static void assertEqualsByteArray(byte[] expected, byte[] actual, String msg) { + if (!Arrays.equals(expected, actual)) { msg = Objects.toString(msg, "assertEqualsByteArray") - + ": expected " + HexFormat.of().formatHex(lhs) - + " to equal " + HexFormat.of().formatHex(rhs); + + ": expected " + HexFormat.of().formatHex(expected) + + " but was " + HexFormat.of().formatHex(actual); fail(msg); } } /** - * Asserts that {@code lhs} is not the same byte array as {@code rhs}. + * Asserts that {@code actual} is not the same byte array as {@code unexpected}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @param msg A description of the assumption; {@code null} for a default message. * @throws RuntimeException if the assertion is not true. */ - public static void assertNotEqualsByteArray(byte[] lhs, byte[] rhs, String msg) { - if (Arrays.equals(lhs, rhs)) { + public static void assertNotEqualsByteArray(byte[] unexpected, byte[] actual, String msg) { + if (Arrays.equals(unexpected, actual)) { msg = Objects.toString(msg, "assertNotEqualsByteArray") - + ": expected " + HexFormat.of().formatHex(lhs) - + " to not equal " + HexFormat.of().formatHex(rhs); + + ": expected not equals but was " + HexFormat.of().formatHex(actual); fail(msg); } } @@ -404,50 +407,49 @@ public static > void assertGreaterThan(T lhs, T rhs, Str /** * Shorthand for {@link #assertNotEquals(Object, Object)}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @see #assertNotEquals(Object, Object) */ - public static void assertNE(Object lhs, Object rhs) { - assertNotEquals(lhs, rhs); + public static void assertNE(Object unexpected, Object actual) { + assertNotEquals(unexpected, actual); } /** * Shorthand for {@link #assertNotEquals(Object, Object, String)}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @param msg A description of the assumption; {@code null} for a default message. * @see #assertNotEquals(Object, Object, String) */ - public static void assertNE(Object lhs, Object rhs, String msg) { - assertNotEquals(lhs, rhs, msg); + public static void assertNE(Object unexpected, Object actual, String msg) { + assertNotEquals(unexpected, actual, msg); } /** * Calls {@link #assertNotEquals(Object, Object, String)} with a default message. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @see #assertNotEquals(Object, Object, String) */ - public static void assertNotEquals(Object lhs, Object rhs) { - assertNotEquals(lhs, rhs, null); + public static void assertNotEquals(Object unexpected, Object actual) { + assertNotEquals(unexpected, actual, null); } /** - * Asserts that {@code lhs} is not equal to {@code rhs}. + * Asserts that {@code actual} is not equal to {@code unexpected}. * - * @param lhs The left hand side of the comparison. - * @param rhs The right hand side of the comparison. + * @param unexpected The unexpected value + * @param actual The actual value * @param msg A description of the assumption; {@code null} for a default message. * @throws RuntimeException if the assertion is not true. */ - public static void assertNotEquals(Object lhs, Object rhs, String msg) { - if ((lhs == rhs) || (lhs != null && lhs.equals(rhs))) { + public static void assertNotEquals(Object unexpected, Object actual, String msg) { + if ((unexpected == actual) || (unexpected != null && unexpected.equals(actual))) { msg = Objects.toString(msg, "assertNotEquals") - + ": expected " + Objects.toString(lhs) - + " to not equal " + Objects.toString(rhs); + + ": expected not equals but was " + Objects.toString(actual); fail(msg); } } @@ -609,6 +611,28 @@ public static void assertStringsEqual(String str1, String str2, } } + /** + * Asserts that contents of two files are equal. + * + * @param f1 The path of the first file to compare + * @param f2 The path of the second file to compare + * @throws RuntimeException on mismatch or I/O failure + */ + public static void assertFileContentsEqual(Path f1, Path f2) { + long mismatchIndex = 0; + try { + mismatchIndex = Files.mismatch(f1, f2); + } catch (IOException exception) { + throw new UncheckedIOException(exception); + } + if (mismatchIndex >= 0) { + String message = String.format( + "Contents of files '%s' and '%s' mismatch at index %d", + f1, f2, mismatchIndex); + fail(message); + } + } + /** * A functional interface for executing tests in assertThrownException */ @@ -640,7 +664,7 @@ public static T assertThrows(Class expected, TestMethod testMethod.execute(); } catch (Throwable exc) { if (expected.isInstance(exc)) { - return (T) exc; + return expected.cast(exc); } else { fail(Objects.toString(msg, "An unexpected exception was thrown.") + " Expected " + expected.getName(), exc); diff --git a/test/lib/jdk/test/lib/NetworkConfiguration.java b/test/lib/jdk/test/lib/NetworkConfiguration.java index 3532bb1a3ee20..a9e6821b2e698 100644 --- a/test/lib/jdk/test/lib/NetworkConfiguration.java +++ b/test/lib/jdk/test/lib/NetworkConfiguration.java @@ -39,8 +39,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.security.AccessController; -import java.security.PrivilegedAction; import static java.net.NetworkInterface.getNetworkInterfaces; import static java.util.Collections.list; @@ -111,7 +109,7 @@ private static boolean isIPv6LinkLocal(InetAddress a) { * was looked up. * * @param ni1 A network interface, may be {@code null} - * @param ni2 An other network interface, may be {@code null} + * @param ni2 Another network interface, may be {@code null} * @return {@code true} if the two network interfaces have the same name * and index, {@code false} otherwise. */ @@ -447,19 +445,15 @@ public static String interfaceInformation(NetworkInterface nif) { } /** Prints all the system interface information to the give stream. */ - @SuppressWarnings("removal") public static void printSystemConfiguration(PrintStream out) { - PrivilegedAction pa = () -> { try { out.println("*** all system network interface configuration ***"); for (NetworkInterface nif : list(getNetworkInterfaces())) { out.print(interfaceInformation(nif)); } out.println("*** end ***"); - return null; } catch (IOException e) { throw new UncheckedIOException(e); - }}; - AccessController.doPrivileged(pa); + } } } diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index 4a4b164cd17ee..682d9c906858b 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -30,33 +30,25 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import static java.util.Locale.ROOT; public class Platform { - public static final String vmName = privilegedGetProperty("java.vm.name"); - public static final String vmInfo = privilegedGetProperty("java.vm.info"); - private static final String osVersion = privilegedGetProperty("os.version"); + public static final String vmName = System.getProperty("java.vm.name"); + public static final String vmInfo = System.getProperty("java.vm.info"); + private static final String osVersion = System.getProperty("os.version"); private static int osVersionMajor = -1; private static int osVersionMinor = -1; - private static final String osName = privilegedGetProperty("os.name"); - private static final String dataModel = privilegedGetProperty("sun.arch.data.model"); - private static final String vmVersion = privilegedGetProperty("java.vm.version"); - private static final String jdkDebug = privilegedGetProperty("jdk.debug"); - private static final String osArch = privilegedGetProperty("os.arch"); - private static final String userName = privilegedGetProperty("user.name"); - private static final String compiler = privilegedGetProperty("sun.management.compiler"); - private static final String testJdk = privilegedGetProperty("test.jdk"); - - @SuppressWarnings("removal") - private static String privilegedGetProperty(String key) { - return AccessController.doPrivileged(( - PrivilegedAction) () -> System.getProperty(key)); - } + private static final String osName = System.getProperty("os.name"); + private static final String dataModel = System.getProperty("sun.arch.data.model"); + private static final String vmVersion = System.getProperty("java.vm.version"); + private static final String jdkDebug = System.getProperty("jdk.debug"); + private static final String osArch = System.getProperty("os.arch"); + private static final String userName = System.getProperty("user.name"); + private static final String compiler = System.getProperty("sun.management.compiler"); + private static final String testJdk = System.getProperty("test.jdk"); public static boolean isClient() { return vmName.endsWith(" Client VM"); diff --git a/test/lib/jdk/test/lib/SA/SATestUtils.java b/test/lib/jdk/test/lib/SA/SATestUtils.java index 82629c1a49d8b..cdb0caf84d4a9 100644 --- a/test/lib/jdk/test/lib/SA/SATestUtils.java +++ b/test/lib/jdk/test/lib/SA/SATestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.TimeUnit; @@ -203,23 +200,16 @@ public static void addPrivilegesIfNeeded(ProcessBuilder pb) { * if we are root, so return true. Then return false for an expected denial * if "ptrace_scope" is 1, and true otherwise. */ - @SuppressWarnings("removal") private static boolean canPtraceAttachLinux() throws IOException { // SELinux deny_ptrace: var deny_ptrace = Paths.get("/sys/fs/selinux/booleans/deny_ptrace"); if (Files.exists(deny_ptrace)) { - try { - var bb = AccessController.doPrivileged( - (PrivilegedExceptionAction) () -> Files.readAllBytes(deny_ptrace)); - if (bb.length == 0) { - throw new Error("deny_ptrace is empty"); - } - if (bb[0] != '0') { - return false; - } - } catch (PrivilegedActionException e) { - IOException t = (IOException) e.getException(); - throw t; + var bb = Files.readAllBytes(deny_ptrace); + if (bb.length == 0) { + throw new Error("deny_ptrace is empty"); + } + if (bb[0] != '0') { + return false; } } @@ -230,23 +220,17 @@ private static boolean canPtraceAttachLinux() throws IOException { // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH var ptrace_scope = Paths.get("/proc/sys/kernel/yama/ptrace_scope"); if (Files.exists(ptrace_scope)) { - try { - var bb = AccessController.doPrivileged( - (PrivilegedExceptionAction) () -> Files.readAllBytes(ptrace_scope)); - if (bb.length == 0) { - throw new Error("ptrace_scope is empty"); - } - byte yama_scope = bb[0]; - if (yama_scope == '3') { - return false; - } + var bb = Files.readAllBytes(ptrace_scope); + if (bb.length == 0) { + throw new Error("ptrace_scope is empty"); + } + byte yama_scope = bb[0]; + if (yama_scope == '3') { + return false; + } - if (!Platform.isRoot() && yama_scope != '0') { - return false; - } - } catch (PrivilegedActionException e) { - IOException t = (IOException) e.getException(); - throw t; + if (!Platform.isRoot() && yama_scope != '0') { + return false; } } // Otherwise expect to be permitted: diff --git a/test/lib/jdk/test/lib/Utils.java b/test/lib/jdk/test/lib/Utils.java index 03e5b798fca47..c4a42dc61ba20 100644 --- a/test/lib/jdk/test/lib/Utils.java +++ b/test/lib/jdk/test/lib/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ package jdk.test.lib; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; @@ -71,6 +72,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import static java.lang.System.lineSeparator; import static jdk.test.lib.Asserts.assertTrue; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; @@ -815,6 +817,62 @@ public static Path createTempFile(String prefix, String suffix, FileAttribute return Files.createTempFile(dir, prefix, suffix, attrs); } + /** + * Creates a file in {@code user.dir} and populates it with random ASCII + * characters of given length. + *

          + * If the {@code user.dir} property is not set, {@code .} will be used. + * This choice of parent directory, compared to + * {@link Files#createTempFile(String, String, FileAttribute[])} using the + * {@code java.io.tmpdir} property, doesn't leave files behind in the + * {@code /tmp} directory of the test machine. + *

          + * + * @param prefix the prefix string to be used in generating the file's name; + * may be null + * @param suffix the suffix string to be used in generating the file's name; + * may be null, in which case ".tmp" is used + * @param size the size in bytes of the temporary file to be populated + * @param attrs an optional list of file attributes to set atomically when creating the file + * @return the path to the newly created file that did not exist before this + * method was invoked + * @throws IOException if an I/O error occurs or dir does not exist + * @throws IllegalArgumentException if size is negative + * + * @see #createTempFile(String, String, FileAttribute...) + */ + public static Path createTempFileOfSize(String prefix, String suffix, long size, FileAttribute... attrs) throws IOException { + + // Check arguments + if (size < 0) { + throw new IllegalArgumentException("file size cannot be negative: " + size); + } + + // Entropy ingredients + int prime1 = 2_147_483_647; + int prime2 = 1_047_483_649; + int seed = Long.hashCode(SEED); + + // Create & populate the file + Path path = createTempFile(prefix, suffix, attrs); + try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.US_ASCII)) { + long remainingSize = size; + for (int rowIndex = 0; remainingSize > 0; rowIndex++) { + for (int colIndex = 0; remainingSize > 0 && colIndex < 80; remainingSize--, colIndex++) { + int r = ((rowIndex ^ seed) * prime1) ^ ((colIndex ^ seed) * prime2); + char c = (char) (0x21 + Math.abs(r) % (0x7e - 0x21)); + writer.append(c); + } + if (remainingSize > lineSeparator().length()) { + writer.write(lineSeparator()); + remainingSize -= lineSeparator().length(); + } + } + } + return path; + + } + /** * Creates an empty directory in "user.dir" or "." *

          diff --git a/test/lib/jdk/test/lib/apps/LingeredApp.java b/test/lib/jdk/test/lib/apps/LingeredApp.java index 73904b81848a3..13008e68c5477 100644 --- a/test/lib/jdk/test/lib/apps/LingeredApp.java +++ b/test/lib/jdk/test/lib/apps/LingeredApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -429,7 +429,7 @@ public void stopApp() throws IOException { } } - /** + /* * High level interface for test writers */ @@ -599,6 +599,7 @@ protected static boolean isReady() { * This part is the application itself. First arg is optional "forceCrash". * Following arg is the lock file name. */ + @SuppressWarnings("restricted") public static void main(String args[]) { boolean forceCrash = false; diff --git a/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java b/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java index d8be12d86c2ef..cac371b482b02 100644 --- a/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java +++ b/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ private static ArtifactManager getManager() throws ArtifactResolverException { try { String managerName = System.getProperty("jdk.test.lib.artifacts.artifactmanager"); if (managerName != null) { - manager = (ArtifactManager) Class.forName(managerName).newInstance(); + manager = (ArtifactManager) Class.forName(managerName).getDeclaredConstructor().newInstance(); } else if (System.getenv().containsKey(JibArtifactManager.JIB_HOME_ENV_NAME)) { manager = JibArtifactManager.newInstance(); } else { diff --git a/test/lib/jdk/test/lib/artifacts/ArtifactResolverException.java b/test/lib/jdk/test/lib/artifacts/ArtifactResolverException.java index c06f5d7b70fea..6cc010f3b637b 100644 --- a/test/lib/jdk/test/lib/artifacts/ArtifactResolverException.java +++ b/test/lib/jdk/test/lib/artifacts/ArtifactResolverException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,14 @@ package jdk.test.lib.artifacts; +import java.io.Serial; + /** * Thrown by the ArtifactResolver when failing to resolve an Artifact. */ public class ArtifactResolverException extends Exception { + @Serial + private static final long serialVersionUID = 8341884506180926911L; public ArtifactResolverException(String message) { super(message); diff --git a/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java b/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java index a66be9b482629..3d27709ce0306 100644 --- a/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java +++ b/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ public static JibArtifactManager newInstance() throws ClassNotFoundException { ClassLoader oldContextLoader = currentThread.getContextClassLoader(); currentThread.setContextClassLoader(classLoader); - Class jibServiceFactory = classLoader.loadClass(JIB_SERVICE_FACTORY); + Class jibServiceFactory = classLoader.loadClass(JIB_SERVICE_FACTORY); try { Object jibArtifactInstaller = jibServiceFactory.getMethod("createJibArtifactInstaller").invoke(null); return new JibArtifactManager(jibArtifactInstaller, classLoader); diff --git a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java index fd76df92ef63a..f616b22ef38f1 100644 --- a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,6 @@ public class CDSArchiveUtils { private static int offsetCrc; // offset of GenericCDSFileMapHeader::_crc private static int offsetVersion; // offset of GenericCDSFileMapHeader::_version private static int offsetHeaderSize; // offset of GenericCDSFileMapHeader::_header_size - private static int offsetCommonAppClasspathPrefixSize;// offset of GenericCDSFileMapHeader::_common_app_classpath_size private static int offsetBaseArchiveNameOffset;// offset of GenericCDSFileMapHeader::_base_archive_name_offset private static int offsetBaseArchiveNameSize; // offset of GenericCDSFileMapHeader::_base_archive_name_size private static int offsetJvmIdent; // offset of FileMapHeader::_jvm_ident @@ -91,7 +90,6 @@ public class CDSArchiveUtils { offsetCrc = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_crc"); offsetVersion = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_version"); offsetHeaderSize = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_header_size"); - offsetCommonAppClasspathPrefixSize = wb.getCDSOffsetForName("FileMapHeader::_common_app_classpath_prefix_size"); offsetBaseArchiveNameOffset = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_base_archive_name_offset"); offsetBaseArchiveNameSize = wb.getCDSOffsetForName("GenericCDSFileMapHeader::_base_archive_name_size"); offsetJvmIdent = wb.getCDSOffsetForName("FileMapHeader::_jvm_ident"); @@ -130,7 +128,6 @@ public class CDSArchiveUtils { public static int offsetCrc() { return offsetCrc; } public static int offsetVersion() { return offsetVersion; } public static int offsetHeaderSize() { return offsetHeaderSize; } - public static int offsetCommonAppClasspathPrefixSize() { return offsetCommonAppClasspathPrefixSize; } public static int offsetBaseArchiveNameOffset() { return offsetBaseArchiveNameOffset; } public static int offsetBaseArchiveNameSize() { return offsetBaseArchiveNameSize; } public static int offsetJvmIdent() { return offsetJvmIdent; } @@ -159,10 +156,6 @@ public static long fileHeaderSizeAligned(File jsaFile) throws Exception { return alignUpWithAlignment(size); } - public static int commonAppClasspathPrefixSize(File jsaFile) throws Exception { - return (int)readInt(jsaFile, offsetCommonAppClasspathPrefixSize, 4); - } - public static int baseArchiveNameOffset(File jsaFile) throws Exception { return (int)readInt(jsaFile, offsetBaseArchiveNameOffset, 4); } diff --git a/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java b/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java index 11bea44fa33ae..89c1ea9e4ac63 100644 --- a/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java +++ b/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import jdk.test.whitebox.WhiteBox; import java.io.File; +import java.io.Serial; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -45,6 +46,9 @@ public class ClassUnloadCommon { public static class TestFailure extends RuntimeException { + @Serial + private static final long serialVersionUID = -8108935949624559549L; + TestFailure(String msg) { super(msg); } diff --git a/test/lib/jdk/test/lib/classloader/GeneratingClassLoader.java b/test/lib/jdk/test/lib/classloader/GeneratingClassLoader.java index ee1089bac4d32..19dd4df959150 100644 --- a/test/lib/jdk/test/lib/classloader/GeneratingClassLoader.java +++ b/test/lib/jdk/test/lib/classloader/GeneratingClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,13 +38,13 @@ class TemplateClass { public class GeneratingClassLoader extends ClassLoader { - public synchronized Class loadClass(String name) throws ClassNotFoundException { + public synchronized Class loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } - public synchronized Class loadClass(String name, boolean resolve) + public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - Class c = findLoadedClass(name); + Class c = findLoadedClass(name); if (c != null) { return c; } @@ -129,7 +129,7 @@ private byte[] getByteCode() throws ClassNotFoundException { throw new RuntimeException("Class name not found in template class file"); } } - return (byte[]) bytecode.clone(); + return bytecode.clone(); } private void readByteCode() throws ClassNotFoundException { diff --git a/test/lib/jdk/test/lib/classloader/GeneratingCompilingClassLoader.java b/test/lib/jdk/test/lib/classloader/GeneratingCompilingClassLoader.java index 34e3a250cdd25..5e040b689f0ea 100644 --- a/test/lib/jdk/test/lib/classloader/GeneratingCompilingClassLoader.java +++ b/test/lib/jdk/test/lib/classloader/GeneratingCompilingClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -202,7 +202,7 @@ public Class generateClass(int sizeFactor) throws IOException { */ public Class[] getGeneratedClasses(int sizeFactor, int numClasses) throws IOException { GeneratedClass[] gc = getGeneratedClass(sizeFactor, numClasses); - Class[] classes = new Class[numClasses]; + Class[] classes = new Class[numClasses]; for (int i = 0; i < numClasses; ++i) { classes[i] = defineClass(gc[i].name, gc[i].bytes, 0 , gc[i].bytes.length); } diff --git a/test/lib/jdk/test/lib/format/ArrayDiff.java b/test/lib/jdk/test/lib/format/ArrayDiff.java index 1e0aedad94b19..67b75ef3dce67 100644 --- a/test/lib/jdk/test/lib/format/ArrayDiff.java +++ b/test/lib/jdk/test/lib/format/ArrayDiff.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,7 +107,7 @@ public static ArrayDiff of(Object first, Object second) { * @throws NullPointerException if at least one of the arrays is null * @return an ArrayDiff instance for the two arrays and formatting parameters provided */ - @SuppressWarnings("rawtypes") + @SuppressWarnings({"rawtypes", "unchecked"}) public static ArrayDiff of(Object first, Object second, int width, int contextBefore) { Objects.requireNonNull(first); Objects.requireNonNull(second); diff --git a/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java b/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java index d344344601d9c..72038191d79c1 100644 --- a/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java +++ b/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; +import java.util.Arrays; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -86,46 +87,19 @@ public static void main(String... args) throws Exception { " -jar Write to the JAR file "); } String jarFile = args[1]; - String[] classes = addInnerClasses(args, 2); + String[] classes = Arrays.copyOfRange(args, 2, args.length); writeJar_impl(jarFile, null, classes); } else { if (DEBUG) { System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); } - String[] classes = addInnerClasses(args, 0); + String[] classes = Arrays.copyOfRange(args, 0, args.length); for (String cls : classes) { writeClassToDisk(cls); } } } - // Add commonly used inner classes that are often omitted by mistake. Currently - // we support only jdk.test.whitebox.WhiteBox$WhiteBoxPermission. - // See JDK-8199290 - private static String[] addInnerClasses(String[] classes, int startIdx) { - boolean seenNewWb = false; - boolean seenNewWbInner = false; - final String newWb = "jdk.test.whitebox.WhiteBox"; - final String newWbInner = newWb + "$WhiteBoxPermission"; - - ArrayList list = new ArrayList<>(); - - for (int i = startIdx; i < classes.length; i++) { - String cls = classes[i]; - list.add(cls); - switch (cls) { - case newWb: seenNewWb = true; break; - case newWbInner: seenNewWbInner = true; break; - } - } - if (seenNewWb && !seenNewWbInner) { - list.add(newWbInner); - } - String[] array = new String[list.size()]; - list.toArray(array); - return array; - } - public static class Manifest { private final InputStream in; @@ -188,13 +162,11 @@ private static void writeJar_impl(String jarFile, Manifest manifest, String clas * @build jdk.test.lib.helpers.ClassFileInstaller */ public static String writeJar(String jarFile, String... classes) throws Exception { - classes = addInnerClasses(classes, 0); writeJar_impl(jarFile, null, classes); return getJarPath(jarFile); } public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception { - classes = addInnerClasses(classes, 0); writeJar_impl(jarFile, manifest, classes); return getJarPath(jarFile); } diff --git a/test/lib/jdk/test/lib/hprof/model/JavaHeapObject.java b/test/lib/jdk/test/lib/hprof/model/JavaHeapObject.java index b50045a7287b1..9841e1b01c573 100644 --- a/test/lib/jdk/test/lib/hprof/model/JavaHeapObject.java +++ b/test/lib/jdk/test/lib/hprof/model/JavaHeapObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,6 @@ import java.util.Map; import jdk.test.lib.hprof.util.Misc; - -/** - * - * @author Bill Foote - */ - /** * Represents an object that's allocated out of the Java heap. It occupies * memory in the VM, and is the sort of thing that in a JDK 1.1 VM had diff --git a/test/lib/jdk/test/lib/hprof/model/JavaStatic.java b/test/lib/jdk/test/lib/hprof/model/JavaStatic.java index 0fa3fbb06dc54..fbb794def56d7 100644 --- a/test/lib/jdk/test/lib/hprof/model/JavaStatic.java +++ b/test/lib/jdk/test/lib/hprof/model/JavaStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,6 @@ package jdk.test.lib.hprof.model; -/** - * - * @author Bill Foote - */ - /** * Represents the value of a static field of a JavaClass */ diff --git a/test/lib/jdk/test/lib/hprof/model/JavaThing.java b/test/lib/jdk/test/lib/hprof/model/JavaThing.java index a76c9cc3198c5..9674a413d2440 100644 --- a/test/lib/jdk/test/lib/hprof/model/JavaThing.java +++ b/test/lib/jdk/test/lib/hprof/model/JavaThing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,6 @@ package jdk.test.lib.hprof.model; -/** - * - * @author Bill Foote - */ - - /** * Represents a java "Thing". A thing is anything that can be the value of * a field. This includes JavaHeapObject, JavaObjectRef, and JavaValue. diff --git a/test/lib/jdk/test/lib/hprof/model/Root.java b/test/lib/jdk/test/lib/hprof/model/Root.java index 3e87eb22a44e7..c3b821be0769d 100644 --- a/test/lib/jdk/test/lib/hprof/model/Root.java +++ b/test/lib/jdk/test/lib/hprof/model/Root.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,6 @@ import jdk.test.lib.hprof.util.Misc; -/** - * - * @author Bill Foote - */ - - /** * Represents a member of the rootset, that is, one of the objects that * the GC starts from when marking reachable objects. diff --git a/test/lib/jdk/test/lib/hprof/model/Snapshot.java b/test/lib/jdk/test/lib/hprof/model/Snapshot.java index 3ea77b876fd61..dbb9c7fd1f3e1 100644 --- a/test/lib/jdk/test/lib/hprof/model/Snapshot.java +++ b/test/lib/jdk/test/lib/hprof/model/Snapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,17 +30,13 @@ package jdk.test.lib.hprof.model; +import java.io.IOException; import java.lang.ref.SoftReference; import java.util.*; import jdk.test.lib.hprof.parser.ReadBuffer; import jdk.test.lib.hprof.util.Misc; -/** - * - * @author Bill Foote - */ - /** * Represents a snapshot of the Java objects in the VM at one instant. * This is the top-level "model" object read out of a single .hprof or .bod @@ -637,7 +633,7 @@ private synchronized void initSiteTraces() { } @Override - public void close() throws Exception { + public void close() throws IOException { readBuf.close(); } diff --git a/test/lib/jdk/test/lib/hprof/model/StackFrame.java b/test/lib/jdk/test/lib/hprof/model/StackFrame.java index 0ea2b0e471663..851faffd67cbe 100644 --- a/test/lib/jdk/test/lib/hprof/model/StackFrame.java +++ b/test/lib/jdk/test/lib/hprof/model/StackFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,6 @@ package jdk.test.lib.hprof.model; -/** - * - * @author Bill Foote - */ - - /** * Represents a stack frame. */ diff --git a/test/lib/jdk/test/lib/hprof/model/StackTrace.java b/test/lib/jdk/test/lib/hprof/model/StackTrace.java index ecab592e3420f..b4a9c66781259 100644 --- a/test/lib/jdk/test/lib/hprof/model/StackTrace.java +++ b/test/lib/jdk/test/lib/hprof/model/StackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,6 @@ package jdk.test.lib.hprof.model; -/** - * - * @author Bill Foote - */ - - /** * Represents a stack trace, that is, an ordered collection of stack frames. */ diff --git a/test/lib/jdk/test/lib/hprof/parser/FileReadBuffer.java b/test/lib/jdk/test/lib/hprof/parser/FileReadBuffer.java index eab5cff84c83d..be7672170b69c 100644 --- a/test/lib/jdk/test/lib/hprof/parser/FileReadBuffer.java +++ b/test/lib/jdk/test/lib/hprof/parser/FileReadBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ public synchronized long getLong(long pos) throws IOException { } @Override - public void close() throws Exception { + public void close() throws IOException { file.close(); } } diff --git a/test/lib/jdk/test/lib/hprof/parser/MappedReadBuffer.java b/test/lib/jdk/test/lib/hprof/parser/MappedReadBuffer.java index d91c453a0f698..96da03a4057fd 100644 --- a/test/lib/jdk/test/lib/hprof/parser/MappedReadBuffer.java +++ b/test/lib/jdk/test/lib/hprof/parser/MappedReadBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,7 +127,7 @@ public synchronized long getLong(long pos) throws IOException { } @Override - public void close() throws Exception { + public void close() throws IOException { file.close(); } diff --git a/test/lib/jdk/test/lib/hprof/parser/ReadBuffer.java b/test/lib/jdk/test/lib/hprof/parser/ReadBuffer.java index 4b06b79a53b2f..03c9d5d4a42bb 100644 --- a/test/lib/jdk/test/lib/hprof/parser/ReadBuffer.java +++ b/test/lib/jdk/test/lib/hprof/parser/ReadBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,4 +43,5 @@ public interface ReadBuffer extends AutoCloseable { public short getShort(long pos) throws IOException; public int getInt(long pos) throws IOException; public long getLong(long pos) throws IOException; + public void close() throws IOException; } diff --git a/test/lib/jdk/test/lib/hprof/parser/Reader.java b/test/lib/jdk/test/lib/hprof/parser/Reader.java index 447d96e770edd..7732befe50379 100644 --- a/test/lib/jdk/test/lib/hprof/parser/Reader.java +++ b/test/lib/jdk/test/lib/hprof/parser/Reader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,7 @@ protected Reader(PositionDataInputStream in) { * @param heapFile The name of a file containing a heap dump * @param callStack If true, read the call stack of allocaation sites */ + @SuppressWarnings("try") public static Snapshot readFile(String heapFile, boolean callStack, int debugLevel) throws IOException { @@ -136,6 +137,7 @@ public static Snapshot readFile(String heapFile, boolean callStack, * * @param heapFile The name of a file containing a heap dump */ + @SuppressWarnings("try") public static String getStack(String heapFile, int debugLevel) throws IOException { int dumpNumber = 1; diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 77fe554c9baaa..0ef1b5e6d3f92 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -151,7 +151,6 @@ public class EventNames { public static final String ZRelocationSetGroup = PREFIX + "ZRelocationSetGroup"; public static final String ZUncommit = PREFIX + "ZUncommit"; public static final String ZUnmap = PREFIX + "ZUnmap"; - public static final String GCLocker = PREFIX + "GCLocker"; public static final String SystemGC = PREFIX + "SystemGC"; public static final String GCCPUTime = PREFIX + "GCCPUTime"; diff --git a/test/lib/jdk/test/lib/jfr/Events.java b/test/lib/jdk/test/lib/jfr/Events.java index 5a180659f9fcf..5676b7021d621 100644 --- a/test/lib/jdk/test/lib/jfr/Events.java +++ b/test/lib/jdk/test/lib/jfr/Events.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -233,7 +233,7 @@ public static void assertMissingValue(RecordedEvent event, String name) { private static void assertThread(RecordedThread eventThread, Thread thread) { assertNotNull(eventThread, "Thread in event was null"); - assertEquals(eventThread.getJavaThreadId(), thread.getId(), "Wrong thread id"); + assertEquals(eventThread.getJavaThreadId(), thread.threadId(), "Wrong thread id"); assertEquals(eventThread.getJavaName(), thread.getName(), "Wrong thread name"); ThreadGroup threadGroup = thread.getThreadGroup(); diff --git a/test/lib/jdk/test/lib/jvmti/DebugeeClass.java b/test/lib/jdk/test/lib/jvmti/DebugeeClass.java index c71e25edd9975..9025d5eefe87a 100644 --- a/test/lib/jdk/test/lib/jvmti/DebugeeClass.java +++ b/test/lib/jdk/test/lib/jvmti/DebugeeClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,8 @@ package jdk.test.lib.jvmti; +import java.io.Serial; + /** * Base class for debuggee class in JVMTI tests. * @@ -49,6 +51,7 @@ public class DebugeeClass { /** * This method is used to load library with native methods implementation, if needed. */ + @SuppressWarnings("restricted") public static void loadLibrary(String name) { try { System.loadLibrary(name); @@ -70,6 +73,9 @@ public static void safeSleep(long millis) { } public class Failure extends RuntimeException { + @Serial + private static final long serialVersionUID = -4069390356498980839L; + public Failure() { } diff --git a/test/lib/jdk/test/lib/management/ThreadMXBeanTool.java b/test/lib/jdk/test/lib/management/ThreadMXBeanTool.java index eeb4297f5009c..c42d78ad1770f 100644 --- a/test/lib/jdk/test/lib/management/ThreadMXBeanTool.java +++ b/test/lib/jdk/test/lib/management/ThreadMXBeanTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public static void waitUntilBlockingOnObject(Thread thread, Thread.State state, + Integer.toHexString(System.identityHashCode(object)); ThreadMXBean tmx = ManagementFactory.getThreadMXBean(); while (thread.isAlive()) { - ThreadInfo ti = tmx.getThreadInfo(thread.getId()); + ThreadInfo ti = tmx.getThreadInfo(thread.threadId()); if (ti.getThreadState() == state && (want == null || want.equals(ti.getLockName()))) { return; @@ -60,7 +60,7 @@ public static void waitUntilBlockingOnObject(Thread thread, Thread.State state, public static void waitUntilInNative(Thread thread) throws InterruptedException { ThreadMXBean tmx = ManagementFactory.getThreadMXBean(); while (thread.isAlive()) { - ThreadInfo ti = tmx.getThreadInfo(thread.getId()); + ThreadInfo ti = tmx.getThreadInfo(thread.threadId()); if (ti.isInNative()) { return; } diff --git a/test/lib/jdk/test/lib/net/IPSupport.java b/test/lib/jdk/test/lib/net/IPSupport.java index 9a630ea1831b1..31255e20c6a99 100644 --- a/test/lib/jdk/test/lib/net/IPSupport.java +++ b/test/lib/jdk/test/lib/net/IPSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,17 +28,13 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; -import java.io.UncheckedIOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.ProtocolFamily; import java.net.StandardProtocolFamily; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.concurrent.Callable; + import jtreg.SkippedException; /** @@ -55,17 +51,16 @@ public class IPSupport { private static final int IPV6_SNDBUF_AIX = 65487; static { - hasIPv4 = runPrivilegedAction(() -> isSupported(Inet4Address.class)); - hasIPv6 = runPrivilegedAction(() -> isSupported(Inet6Address.class)); - preferIPv4Stack = runPrivilegedAction(() -> Boolean.parseBoolean( - System.getProperty("java.net.preferIPv4Stack"))); - preferIPv6Addresses = runPrivilegedAction(() -> Boolean.parseBoolean( - System.getProperty("java.net.preferIPv6Addresses"))); + hasIPv4 = isSupported(Inet4Address.class); + hasIPv6 = isSupported(Inet6Address.class); + preferIPv4Stack = Boolean.parseBoolean(System.getProperty("java.net.preferIPv4Stack")); + preferIPv6Addresses = Boolean.parseBoolean(System.getProperty("java.net.preferIPv6Addresses")); if (!preferIPv4Stack && !hasIPv4 && !hasIPv6) { throw new AssertionError("IPv4 and IPv6 both not available and java.net.preferIPv4Stack is not true"); } } + @SuppressWarnings("try") private static boolean isSupported(Class addressType) { ProtocolFamily family = addressType == Inet4Address.class ? StandardProtocolFamily.INET : StandardProtocolFamily.INET6; @@ -76,16 +71,6 @@ private static boolean isSupported(Class addressType) { } } - @SuppressWarnings("removal") - private static T runPrivilegedAction(Callable callable) { - try { - PrivilegedExceptionAction pa = () -> callable.call(); - return AccessController.doPrivileged(pa); - } catch (PrivilegedActionException pae) { - throw new UncheckedIOException((IOException) pae.getCause()); - } - } - private IPSupport() { } /** diff --git a/test/lib/jdk/test/lib/net/SimpleHttpServer.java b/test/lib/jdk/test/lib/net/SimpleHttpServer.java index 312df96a64bff..1905091eac67c 100644 --- a/test/lib/jdk/test/lib/net/SimpleHttpServer.java +++ b/test/lib/jdk/test/lib/net/SimpleHttpServer.java @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +101,7 @@ public void handle(final HttpExchange t) throws IOException { try { uri = URI.create("file://" + rootUri.getRawPath() + path).normalize(); fPath = Path.of(uri); - } catch (IllegalArgumentException | FileSystemNotFoundException | SecurityException ex) { + } catch (IllegalArgumentException | FileSystemNotFoundException ex) { ex.printStackTrace(); notfound(t, path); return; diff --git a/test/lib/jdk/test/lib/net/SimpleSSLContext.java b/test/lib/jdk/test/lib/net/SimpleSSLContext.java index e8611fb007f32..3c26809f1283e 100644 --- a/test/lib/jdk/test/lib/net/SimpleSSLContext.java +++ b/test/lib/jdk/test/lib/net/SimpleSSLContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,13 +34,6 @@ * Creates a simple usable SSLContext for SSLSocketFactory * or a HttpsServer using either a given keystore or a default * one in the test tree. - * - * Using this class with a security manager requires the following - * permissions to be granted: - * - * permission "java.util.PropertyPermission" "test.src.path", "read"; - * permission java.io.FilePermission "/path/to/test/lib/jdk/test/lib/testkeys", "read"; - * The exact path above depends on the location of the test. */ public class SimpleSSLContext { @@ -54,47 +47,19 @@ public SimpleSSLContext() throws IOException { this(() -> "TLS"); } - @SuppressWarnings("removal") private SimpleSSLContext(Supplier protocols) throws IOException { - try { - final String proto = protocols.get(); - AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - String paths = System.getProperty("test.src.path"); - StringTokenizer st = new StringTokenizer(paths, File.pathSeparator); - boolean securityExceptions = false; - while (st.hasMoreTokens()) { - String path = st.nextToken(); - try { - File f = new File(path, "jdk/test/lib/net/testkeys"); - if (f.exists()) { - try (FileInputStream fis = new FileInputStream(f)) { - init(fis, proto); - return null; - } - } - } catch (SecurityException e) { - // catch and ignore because permission only required - // for one entry on path (at most) - securityExceptions = true; - } - } - if (securityExceptions) { - System.err.println("SecurityExceptions thrown on loading testkeys"); - } - return null; + String proto = protocols.get(); + String paths = System.getProperty("test.src.path"); + StringTokenizer st = new StringTokenizer(paths, File.pathSeparator); + while (st.hasMoreTokens()) { + String path = st.nextToken(); + File f = new File(path, "jdk/test/lib/net/testkeys"); + if (f.exists()) { + try (FileInputStream fis = new FileInputStream(f)) { + init(fis, proto); + break; } - }); - } catch (PrivilegedActionException pae) { - Throwable t = pae.getCause() != null ? pae.getCause() : pae; - if (t instanceof IOException) - throw (IOException)t; - if (t instanceof RuntimeException) - throw (RuntimeException)t; - if (t instanceof Error) - throw (Error)t; - throw new RuntimeException(t); + } } } diff --git a/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java index 0bb6db1602102..0873cb2b5d032 100644 --- a/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java +++ b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -160,7 +160,6 @@ private static long readDefaultHugePageSizeFromOS() { while (scanner.hasNextLine()) { Matcher mat = pat.matcher(scanner.nextLine()); if (mat.matches()) { - scanner.close(); return Long.parseLong(mat.group(1)) * 1024; } } diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index fd543d0c3b785..7d03268cac472 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -252,7 +249,7 @@ public static Process startProcess(String name, TimeUnit unit) throws IOException, InterruptedException, TimeoutException { System.out.println("[" + name + "]:" + String.join(" ", processBuilder.command())); - Process p = privilegedStart(processBuilder); + Process p = processBuilder.start(); StreamPumper stdout = new StreamPumper(p.getInputStream()); StreamPumper stderr = new StreamPumper(p.getErrorStream()); @@ -716,7 +713,7 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, Process p = null; boolean failed = false; try { - p = privilegedStart(pb); + p = pb.start(); if (input != null) { try (PrintStream ps = new PrintStream(p.getOutputStream())) { ps.print(input); @@ -732,10 +729,7 @@ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, { // Dumping the process output to a separate file var fileName = String.format("pid-%d-output.log", p.pid()); var processOutput = getProcessLog(pb, output); - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - Files.writeString(Path.of(fileName), processOutput); - return null; - }); + Files.writeString(Path.of(fileName), processOutput); System.out.printf( "Output and diagnostic info for process %d " + "was saved into '%s'%n", p.pid(), fileName); @@ -883,16 +877,6 @@ public static ProcessBuilder addJvmLib(ProcessBuilder pb) throws Exception { return pb; } - @SuppressWarnings("removal") - private static Process privilegedStart(ProcessBuilder pb) throws IOException { - try { - return AccessController.doPrivileged( - (PrivilegedExceptionAction) pb::start); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } - private static class ProcessImpl extends Process { private final InputStream stdOut; @@ -997,7 +981,7 @@ public static void main(String[] args) throws Throwable { String[] classArgs = new String[args.length - 2]; System.arraycopy(args, 2, classArgs, 0, args.length - 2); Class c = Class.forName(className); - Method mainMethod = c.getMethod("main", new Class[] { String[].class }); + Method mainMethod = c.getMethod("main", new Class[] { String[].class }); mainMethod.setAccessible(true); if (testThreadFactoryName.equals("Virtual")) { diff --git a/test/lib/jdk/test/lib/security/CertUtils.java b/test/lib/jdk/test/lib/security/CertUtils.java index c52d98c257249..e5bd3169c0b61 100644 --- a/test/lib/jdk/test/lib/security/CertUtils.java +++ b/test/lib/jdk/test/lib/security/CertUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -/** +/* * * @author Sean Mullan * @author Steve Hanna @@ -645,7 +645,9 @@ private static String readFile(String relativeFilePath, * This class is useful for overriding one or more methods of an * X509Certificate for testing purposes. */ + @SuppressWarnings("deprecation") public static class ForwardingX509Certificate extends X509Certificate { + private static final long serialVersionUID = -8453912214640985478L; private final X509Certificate cert; public ForwardingX509Certificate(X509Certificate cert) { this.cert = cert; diff --git a/test/jdk/java/security/testlibrary/CertificateBuilder.java b/test/lib/jdk/test/lib/security/CertificateBuilder.java similarity index 94% rename from test/jdk/java/security/testlibrary/CertificateBuilder.java rename to test/lib/jdk/test/lib/security/CertificateBuilder.java index e1b1211a9d595..60358c9a4eabf 100644 --- a/test/jdk/java/security/testlibrary/CertificateBuilder.java +++ b/test/lib/jdk/test/lib/security/CertificateBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -package sun.security.testlibrary; +package jdk.test.lib.security; import java.io.*; import java.util.*; @@ -51,7 +51,6 @@ import sun.security.x509.GeneralName; import sun.security.x509.GeneralNames; import sun.security.x509.KeyUsageExtension; -import sun.security.x509.SerialNumber; import sun.security.x509.SubjectAlternativeNameExtension; import sun.security.x509.URIName; import sun.security.x509.KeyIdentifier; @@ -288,11 +287,8 @@ public CertificateBuilder addAIAExt(List locations) * * @param bitSettings Boolean array for all nine bit settings in the order * documented in RFC 5280 section 4.2.1.3. - * - * @throws IOException if an encoding error occurs. */ - public CertificateBuilder addKeyUsageExt(boolean[] bitSettings) - throws IOException { + public CertificateBuilder addKeyUsageExt(boolean[] bitSettings) { return addExtension(new KeyUsageExtension(bitSettings)); } @@ -305,11 +301,9 @@ public CertificateBuilder addKeyUsageExt(boolean[] bitSettings) * @param maxPathLen The maximum path length issued by this CA. Values * less than zero will omit this field from the resulting extension and * no path length constraint will be asserted. - * - * @throws IOException if an encoding error occurs. */ public CertificateBuilder addBasicConstraintsExt(boolean crit, boolean isCA, - int maxPathLen) throws IOException { + int maxPathLen) { return addExtension(new BasicConstraintsExtension(crit, isCA, maxPathLen)); } @@ -389,7 +383,27 @@ public CertificateBuilder reset() { } /** - * Build the certificate. + * Build the certificate using the default algorithm for the provided + * signing key. + * + * @param issuerCert The certificate of the issuing authority, or + * {@code null} if the resulting certificate is self-signed. + * @param issuerKey The private key of the issuing authority + * + * @return The resulting {@link X509Certificate} + * + * @throws IOException if an encoding error occurs. + * @throws CertificateException If the certificate cannot be generated + * by the underlying {@link CertificateFactory} + */ + public X509Certificate build(X509Certificate issuerCert, + PrivateKey issuerKey) throws IOException, CertificateException { + return build(issuerCert, issuerKey, + SignatureUtil.getDefaultSigAlgForKey(issuerKey)); + } + + /** + * Build the certificate using the key and specified signing algorithm. * * @param issuerCert The certificate of the issuing authority, or * {@code null} if the resulting certificate is self-signed. @@ -401,14 +415,10 @@ public CertificateBuilder reset() { * @throws IOException if an encoding error occurs. * @throws CertificateException If the certificate cannot be generated * by the underlying {@link CertificateFactory} - * @throws NoSuchAlgorithmException If an invalid signature algorithm - * is provided. */ public X509Certificate build(X509Certificate issuerCert, PrivateKey issuerKey, String algName) - throws IOException, CertificateException, NoSuchAlgorithmException { - // TODO: add some basic checks (key usage, basic constraints maybe) - + throws IOException, CertificateException { byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, algName); ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert); return (X509Certificate)factory.generateCertificate(bais); @@ -437,15 +447,14 @@ public X509Certificate build(X509Certificate issuerCert, */ private byte[] encodeTopLevel(X509Certificate issuerCert, PrivateKey issuerKey, String algName) - throws CertificateException, IOException, NoSuchAlgorithmException { + throws CertificateException, IOException { - AlgorithmId signAlg = AlgorithmId.get(algName); + AlgorithmId signAlg; DerOutputStream outerSeq = new DerOutputStream(); DerOutputStream topLevelItems = new DerOutputStream(); try { - Signature sig = SignatureUtil.fromKey(signAlg.getName(), issuerKey, (Provider)null); - // Rewrite signAlg, RSASSA-PSS needs some parameters. + Signature sig = SignatureUtil.fromKey(algName, issuerKey, ""); signAlg = SignatureUtil.fromSignature(sig, issuerKey); tbsCertBytes = encodeTbsCert(issuerCert, signAlg); sig.update(tbsCertBytes); @@ -566,7 +575,6 @@ private byte[] encodeTbsCert(X509Certificate issuerCert, */ private void encodeExtensions(DerOutputStream tbsStream) throws IOException { - if (extensions.isEmpty()) { return; } diff --git a/test/lib/jdk/test/lib/security/FixedSecureRandom.java b/test/lib/jdk/test/lib/security/FixedSecureRandom.java index cfe8ccc212f4a..d6a08730b0e46 100644 --- a/test/lib/jdk/test/lib/security/FixedSecureRandom.java +++ b/test/lib/jdk/test/lib/security/FixedSecureRandom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ /// bytes are exhausted. public class FixedSecureRandom extends SecureRandom { + private static final long serialVersionUID = -8753752741562231543L; + private byte[] buffer; private int offset; diff --git a/test/jdk/java/security/testlibrary/HumanInputStream.java b/test/lib/jdk/test/lib/security/HumanInputStream.java similarity index 98% rename from test/jdk/java/security/testlibrary/HumanInputStream.java rename to test/lib/jdk/test/lib/security/HumanInputStream.java index 50e5dd0bcc8c4..c68f515881e05 100644 --- a/test/jdk/java/security/testlibrary/HumanInputStream.java +++ b/test/lib/jdk/test/lib/security/HumanInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ * questions. */ +package jdk.test.lib.security; import java.io.BufferedReader; import java.io.IOException; @@ -82,6 +83,7 @@ public HumanInputStream(String input) { } return re; } + @Override public int read(byte[] buffer, int offset, int len) { inLine = true; try { @@ -92,6 +94,7 @@ public HumanInputStream(String input) { inLine = false; } } + @Override public int available() { if (pos < length) return 1; return 0; diff --git a/test/jdk/java/security/testlibrary/Providers.java b/test/lib/jdk/test/lib/security/Providers.java similarity index 92% rename from test/jdk/java/security/testlibrary/Providers.java rename to test/lib/jdk/test/lib/security/Providers.java index b3e9f3e96b645..42dd698403649 100644 --- a/test/jdk/java/security/testlibrary/Providers.java +++ b/test/lib/jdk/test/lib/security/Providers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,8 @@ * questions. */ +package jdk.test.lib.security; + import java.security.Provider; import java.security.Security; diff --git a/test/jdk/java/security/testlibrary/ProvidersSnapshot.java b/test/lib/jdk/test/lib/security/ProvidersSnapshot.java similarity index 93% rename from test/jdk/java/security/testlibrary/ProvidersSnapshot.java rename to test/lib/jdk/test/lib/security/ProvidersSnapshot.java index 33c45329e3f48..cef02f814befb 100644 --- a/test/jdk/java/security/testlibrary/ProvidersSnapshot.java +++ b/test/lib/jdk/test/lib/security/ProvidersSnapshot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,8 @@ * questions. */ +package jdk.test.lib.security; + import java.security.Provider; import java.security.Security; diff --git a/test/lib/jdk/test/lib/security/SeededSecureRandom.java b/test/lib/jdk/test/lib/security/SeededSecureRandom.java index 305a91c41d22d..d56af1aee1413 100644 --- a/test/lib/jdk/test/lib/security/SeededSecureRandom.java +++ b/test/lib/jdk/test/lib/security/SeededSecureRandom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ */ public class SeededSecureRandom extends SecureRandom { + private static final long serialVersionUID = 4657031557630518194L; + private final Random rnd; public static long seed() { diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/lib/jdk/test/lib/security/SimpleOCSPServer.java similarity index 95% rename from test/jdk/java/security/testlibrary/SimpleOCSPServer.java rename to test/lib/jdk/test/lib/security/SimpleOCSPServer.java index 5b9fb23c4ef90..4e25467ca80bb 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/lib/jdk/test/lib/security/SimpleOCSPServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,11 @@ * questions. */ -package sun.security.testlibrary; +package jdk.test.lib.security; import java.io.*; import java.net.*; +import java.nio.charset.StandardCharsets; import java.security.*; import java.security.cert.CRLReason; import java.security.cert.X509Certificate; @@ -61,7 +62,7 @@ public class SimpleOCSPServer { static final int FREE_PORT = 0; // CertStatus values - public static enum CertStatus { + public enum CertStatus { CERT_STATUS_GOOD, CERT_STATUS_REVOKED, CERT_STATUS_UNKNOWN, @@ -69,14 +70,14 @@ public static enum CertStatus { // Fields used for the networking portion of the responder private ServerSocket servSocket; - private InetAddress listenAddress; + private final InetAddress listenAddress; private int listenPort; // Keystore information (certs, keys, etc.) - private KeyStore keystore; - private X509Certificate issuerCert; - private X509Certificate signerCert; - private PrivateKey signerKey; + private final KeyStore keystore; + private final X509Certificate issuerCert; + private final X509Certificate signerCert; + private final PrivateKey signerKey; // Fields used for the operational portions of the server private boolean logEnabled = false; @@ -91,9 +92,9 @@ public static enum CertStatus { // Fields used in the generation of responses private long nextUpdateInterval = -1; private Date nextUpdate = null; - private ResponderId respId; - private AlgorithmId sigAlgId; - private Map statusDb = + private final ResponderId respId; + private String sigAlgName; + private final Map statusDb = Collections.synchronizedMap(new HashMap<>()); /** @@ -140,25 +141,24 @@ public SimpleOCSPServer(KeyStore ks, String password, String issuerAlias, public SimpleOCSPServer(InetAddress addr, int port, KeyStore ks, String password, String issuerAlias, String signerAlias) throws GeneralSecurityException, IOException { - Objects.requireNonNull(ks, "Null keystore provided"); + keystore = Objects.requireNonNull(ks, "Null keystore provided"); Objects.requireNonNull(issuerAlias, "Null issuerName provided"); utcDateFmt.setTimeZone(TimeZone.getTimeZone("GMT")); - keystore = ks; - issuerCert = (X509Certificate)ks.getCertificate(issuerAlias); + issuerCert = (X509Certificate)keystore.getCertificate(issuerAlias); if (issuerCert == null) { throw new IllegalArgumentException("Certificate for alias " + issuerAlias + " not found"); } if (signerAlias != null) { - signerCert = (X509Certificate)ks.getCertificate(signerAlias); + signerCert = (X509Certificate)keystore.getCertificate(signerAlias); if (signerCert == null) { throw new IllegalArgumentException("Certificate for alias " + signerAlias + " not found"); } - signerKey = (PrivateKey)ks.getKey(signerAlias, + signerKey = (PrivateKey)keystore.getKey(signerAlias, password.toCharArray()); if (signerKey == null) { throw new IllegalArgumentException("PrivateKey for alias " + @@ -166,14 +166,14 @@ public SimpleOCSPServer(InetAddress addr, int port, KeyStore ks, } } else { signerCert = issuerCert; - signerKey = (PrivateKey)ks.getKey(issuerAlias, + signerKey = (PrivateKey)keystore.getKey(issuerAlias, password.toCharArray()); if (signerKey == null) { throw new IllegalArgumentException("PrivateKey for alias " + issuerAlias + " not found"); } } - sigAlgId = AlgorithmId.get(SignatureUtil.getDefaultSigAlgForKey(signerKey)); + sigAlgName = SignatureUtil.getDefaultSigAlgForKey(signerKey); respId = new ResponderId(signerCert.getSubjectX500Principal()); listenAddress = addr; listenPort = port; @@ -495,8 +495,14 @@ private Map checkStatusDb( public void setSignatureAlgorithm(String algName) throws NoSuchAlgorithmException { if (!started) { - sigAlgId = AlgorithmId.get(algName); - log("Signature algorithm set to " + sigAlgId.getName()); + // We don't care about the AlgorithmId object, we're just + // using it to validate the algName parameter. + AlgorithmId.get(algName); + sigAlgName = algName; + log("Signature algorithm set to " + algName); + } else { + log("Signature algorithm cannot be set on a running server, " + + "stop the server first"); } } @@ -604,9 +610,9 @@ private static synchronized void err(Throwable exc) { * object may be used to construct OCSP responses. */ public static class CertStatusInfo { - private CertStatus certStatusType; + private final CertStatus certStatusType; private CRLReason reason; - private Date revocationTime; + private final Date revocationTime; /** * Create a Certificate status object by providing the status only. @@ -745,7 +751,7 @@ public void run() { // This will be tokenized so we know if we are dealing with // a GET or POST. String[] headerTokens = readLine(in).split(" "); - LocalOcspRequest ocspReq = null; + LocalOcspRequest ocspReq; LocalOcspResponse ocspResp = null; ResponseStatus respStat = ResponseStatus.INTERNAL_ERROR; try { @@ -794,7 +800,7 @@ public void run() { out.flush(); log("Closing " + ocspSocket); - } catch (IOException | CertificateException exc) { + } catch (IOException | GeneralSecurityException exc) { err(exc); } } @@ -826,10 +832,10 @@ public void sendResponse(OutputStream out, LocalOcspResponse resp) append("\r\n"); } sb.append("\r\n"); + log(resp.toString()); - out.write(sb.toString().getBytes("UTF-8")); + out.write(sb.toString().getBytes(StandardCharsets.UTF_8)); out.write(respBytes); - log(resp.toString()); } /** @@ -940,7 +946,7 @@ private LocalOcspRequest parseHttpOcspGet(String[] headerTokens, // "/" off before decoding. return new LocalOcspRequest(Base64.getMimeDecoder().decode( URLDecoder.decode(headerTokens[1].replaceAll("/", ""), - "UTF-8"))); + StandardCharsets.UTF_8))); } /** @@ -974,8 +980,7 @@ private String readLine(InputStream is) throws IOException { bos.write(b); } } - - return new String(bos.toByteArray(), "UTF-8"); + return bos.toString(StandardCharsets.UTF_8); } } @@ -1052,7 +1057,6 @@ private void parseSignature(DerValue sigSequence) if (sigItems[2].isContextSpecific((byte)0)) { DerValue[] certDerItems = sigItems[2].data.getSequence(4); - int i = 0; for (DerValue dv : certDerItems) { X509Certificate xc = new X509CertImpl(dv); certificates.add(xc); @@ -1131,7 +1135,7 @@ private List getRequests() { * Return the list of X.509 Certificates in this OCSP request. * * @return an unmodifiable {@code List} of zero or more - * {@cpde X509Certificate} objects. + * {@code X509Certificate} objects. */ private List getCertificates() { return Collections.unmodifiableList(certificates); @@ -1295,7 +1299,8 @@ public class LocalOcspResponse { private final Map responseExtensions; private byte[] signature; private final List certificates; - private final byte[] encodedResponse; + private final Signature signEngine; + private final AlgorithmId sigAlgId; /** * Constructor for the generation of non-successful responses @@ -1305,9 +1310,11 @@ public class LocalOcspResponse { * @throws IOException if an error happens during encoding * @throws NullPointerException if {@code respStat} is {@code null} * or {@code respStat} is successful. + * @throws GeneralSecurityException if errors occur while obtaining + * the signature object or any algorithm identifier parameters. */ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat) - throws IOException { + throws IOException, GeneralSecurityException { this(respStat, null, null); } @@ -1324,10 +1331,13 @@ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat) * @throws NullPointerException if {@code respStat} is {@code null} * or {@code respStat} is successful, and a {@code null} {@code itemMap} * has been provided. + * @throws GeneralSecurityException if errors occur while obtaining + * the signature object or any algorithm identifier parameters. */ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat, Map itemMap, - Map reqExtensions) throws IOException { + Map reqExtensions) + throws IOException, GeneralSecurityException { responseStatus = Objects.requireNonNull(respStat, "Illegal null response status"); if (responseStatus == ResponseStatus.SUCCESSFUL) { @@ -1348,13 +1358,18 @@ public LocalOcspResponse(OCSPResponse.ResponseStatus respStat, certificates.add(signerCert); } certificates.add(issuerCert); + // Create the signature object and AlgorithmId that we'll use + // later to create the signature on this response. + signEngine = SignatureUtil.fromKey(sigAlgName, signerKey, ""); + sigAlgId = SignatureUtil.fromSignature(signEngine, signerKey); } else { respItemMap = null; producedAtDate = null; responseExtensions = null; certificates = null; + signEngine = null; + sigAlgId = null; } - encodedResponse = this.getBytes(); } /** @@ -1436,13 +1451,9 @@ private byte[] encodeBasicOcspResponse() throws IOException { basicORItemStream.write(tbsResponseBytes); try { - // Create the signature - Signature sig = SignatureUtil.fromKey( - sigAlgId.getName(), signerKey, (Provider)null); - sig.update(tbsResponseBytes); - signature = sig.sign(); - // Rewrite signAlg, RSASSA-PSS needs some parameters. - sigAlgId = SignatureUtil.fromSignature(sig, signerKey); + // Create the signature with the initialized Signature object + signEngine.update(tbsResponseBytes); + signature = signEngine.sign(); sigAlgId.encode(basicORItemStream); basicORItemStream.putBitString(signature); } catch (GeneralSecurityException exc) { diff --git a/test/lib/jdk/test/lib/security/XMLUtils.java b/test/lib/jdk/test/lib/security/XMLUtils.java index efc8f6d544974..e70a30d9b3d27 100644 --- a/test/lib/jdk/test/lib/security/XMLUtils.java +++ b/test/lib/jdk/test/lib/security/XMLUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -559,6 +559,7 @@ public KeySelectorResult select(KeyInfo keyInfo, /** * Adds a new rule to "jdk.xml.dsig.secureValidationPolicy" */ + @SuppressWarnings("dangling-doc-comments") public static void addPolicy(String rule) { String value = Security.getProperty("jdk.xml.dsig.secureValidationPolicy"); value = rule + "," + value; diff --git a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java index 9bffa1a240ff8..e103821c9b81c 100644 --- a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java +++ b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ public TsaServer(int port, KeyStore keyStore, String passphrase) * * @param handler a {@link TsaHandler} */ - public void setHandler(TsaHandler handler) { + public final void setHandler(TsaHandler handler) { server.createContext("/", handler); } @@ -113,7 +113,7 @@ public int getPort() { } @Override - public void close() throws Exception { + public void close() { stop(); } } diff --git a/test/lib/jdk/test/lib/thread/VThreadPinner.java b/test/lib/jdk/test/lib/thread/VThreadPinner.java index f77dba978efa1..c6b332d2791e9 100644 --- a/test/lib/jdk/test/lib/thread/VThreadPinner.java +++ b/test/lib/jdk/test/lib/thread/VThreadPinner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,7 +114,9 @@ public static void runPinned(ThrowingRunnable task) thr throw e; if (ex instanceof Error e) throw e; - throw (X) ex; + @SuppressWarnings("unchecked") + var x = (X) ex; + throw x; } } diff --git a/test/lib/jdk/test/lib/thread/VThreadRunner.java b/test/lib/jdk/test/lib/thread/VThreadRunner.java index 1b09e5e0d1222..3c1a076659a04 100644 --- a/test/lib/jdk/test/lib/thread/VThreadRunner.java +++ b/test/lib/jdk/test/lib/thread/VThreadRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,9 @@ public static void run(String name, throw e; if (ex instanceof Error e) throw e; - throw (X) ex; + @SuppressWarnings("unchecked") + var x = (X) ex; + throw x; } } diff --git a/test/lib/jdk/test/lib/util/FileUtils.java b/test/lib/jdk/test/lib/util/FileUtils.java index 191cb46f9c243..8b99d1e9d54aa 100644 --- a/test/lib/jdk/test/lib/util/FileUtils.java +++ b/test/lib/jdk/test/lib/util/FileUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.time.Instant; import java.util.ArrayList; @@ -48,6 +49,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import java.util.stream.Stream; + import jdk.test.lib.Platform; import com.sun.management.UnixOperatingSystemMXBean; @@ -266,7 +269,7 @@ public static boolean areMountPointsAccessibleAndUnique() { (new InputStreamReader(proc.getInputStream())); // Skip the first line as it is the "df" output header. if (reader.readLine() != null ) { - Set mountPoints = new HashSet(); + Set mountPoints = new HashSet<>(); String mountPoint = null; while ((mountPoint = reader.readLine()) != null) { if (!mountPoints.add(mountPoint)) { @@ -299,8 +302,8 @@ public static boolean areMountPointsAccessibleAndUnique() { }; }); - final AtomicReference throwableReference = - new AtomicReference(); + final AtomicReference throwableReference = + new AtomicReference<>(); thr.setUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { @@ -315,7 +318,7 @@ public void uncaughtException(Thread t, Throwable e) { throw new RuntimeException(ie); } - Throwable uncaughtException = (Throwable)throwableReference.get(); + Throwable uncaughtException = throwableReference.get(); if (uncaughtException != null) { throw new RuntimeException(uncaughtException); } @@ -364,7 +367,32 @@ public static void listFileDescriptors(PrintStream ps) { }); } + /** + * Copies a directory and all entries in the directory to a destination path. + * Makes the access permission of the destination entries writable. + * + * @param src the path of the source directory + * @param dst the path of the destination directory + * @throws IOException if an I/O error occurs while walking the file tree + * @throws RuntimeException if an I/O error occurs during the copy operation + * or if the source or destination paths are invalid + */ + public static void copyDirectory(Path src, Path dst) throws IOException { + try (Stream stream = Files.walk(src)) { + stream.forEach(sourcePath -> { + try { + Path destPath = dst.resolve(src.relativize(sourcePath)); + Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING); + destPath.toFile().setWritable(true); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + } + // Return the current process handle count + @SuppressWarnings("restricted") public static long getProcessHandleCount() { if (IS_WINDOWS) { if (!nativeLibLoaded) { diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index f68eb978912a2..be9bc646ce4b2 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -29,18 +29,11 @@ import java.util.List; import java.util.function.BiFunction; import java.util.function.Function; -import java.security.BasicPermission; import java.util.Objects; import jdk.test.whitebox.parser.DiagnosticCommand; public class WhiteBox { - @SuppressWarnings("serial") - public static class WhiteBoxPermission extends BasicPermission { - public WhiteBoxPermission(String s) { - super(s); - } - } private WhiteBox() {} private static final WhiteBox instance = new WhiteBox(); @@ -793,10 +786,6 @@ public native int validateCgroup(String procCgroups, public native void waitUnsafe(int time_ms); - public native void lockCritical(); - - public native void unlockCritical(); - public native void pinObject(Object o); public native void unpinObject(Object o); @@ -805,4 +794,6 @@ public native int validateCgroup(String procCgroups, public native void preTouchMemory(long addr, long size); public native long rss(); + + public native boolean isStatic(); } diff --git a/test/make/TestCompileCommands.gmk b/test/make/TestCompileCommands.gmk index 26a3913138d38..4673c74da79b0 100644 --- a/test/make/TestCompileCommands.gmk +++ b/test/make/TestCompileCommands.gmk @@ -1,5 +1,5 @@ -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,9 @@ # questions. # -include $(SPEC) -include MakeBase.gmk +include MakeFileStart.gmk -default: all +################################################################################ COMPILE_COMMANDS := $(OUTPUTDIR)/compile_commands.json @@ -49,4 +48,8 @@ TEST_TARGETS += verify-compile-commands-json verify-no-shared-libraries all: $(TEST_TARGETS) -.PHONY: default all verify-compile-commands +.PHONY: verify-compile-commands + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestCopyFiles.gmk b/test/make/TestCopyFiles.gmk index cc05f89db23a2..ff9a7aaec7220 100644 --- a/test/make/TestCopyFiles.gmk +++ b/test/make/TestCopyFiles.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ # questions. # -default: all +include MakeFileStart.gmk + +################################################################################ -include $(SPEC) -include MakeBase.gmk include CopyFiles.gmk include UtilsForTests.gmk @@ -95,3 +95,7 @@ TEST_TARGETS += run-test1 ################################################################################ all: $(TEST_TARGETS) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestFixDepsFile.gmk b/test/make/TestFixDepsFile.gmk index 26145d604f2d5..66c2eee461de9 100644 --- a/test/make/TestFixDepsFile.gmk +++ b/test/make/TestFixDepsFile.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ # questions. # -default: all +include MakeFileStart.gmk + +################################################################################ -include $(SPEC) -include MakeBase.gmk include UtilsForTests.gmk THIS_FILE := $(TOPDIR)/test/make/FixDepsFile.gmk @@ -62,3 +62,7 @@ TEST_TARGETS := test-fix-deps-file ################################################################################ all: $(TEST_TARGETS) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestIdea.gmk b/test/make/TestIdea.gmk index fce8769b239cf..4b87c8e5fca84 100644 --- a/test/make/TestIdea.gmk +++ b/test/make/TestIdea.gmk @@ -1,5 +1,5 @@ -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,24 +21,33 @@ # questions. # -include $(SPEC) -include MakeBase.gmk +include MakeFileStart.gmk -default: all +################################################################################ IDEA_OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/verify-idea +# Unset these variables to avoid having the current environment interfere with +# the idea generation script. SPEC needs to remain as idea.sh will call back to +# make and that call needs to have SPEC defined. +unexport CONF +unexport CONF_NAME + clean-idea: $(RM) -r $(IDEA_OUTPUT_DIR) verify-idea: $(MKDIR) -p $(IDEA_OUTPUT_DIR) - MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1 - MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base - MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler + cd $(WORKSPACE_ROOT) && MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1 + cd $(WORKSPACE_ROOT) && MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base + cd $(WORKSPACE_ROOT) && MAKEFLAGS= MFLAGS= $(BASH) $(TOPDIR)/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler TEST_TARGETS += verify-idea all: $(TEST_TARGETS) -.PHONY: default all verify-idea +.PHONY: verify-idea + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestJavaCompilation.gmk b/test/make/TestJavaCompilation.gmk index 039830241a98f..d0bd3bb9499a6 100644 --- a/test/make/TestJavaCompilation.gmk +++ b/test/make/TestJavaCompilation.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ # questions. # -default: all +include MakeFileStart.gmk + +################################################################################ -include $(SPEC) -include MakeBase.gmk include JarArchive.gmk include JavaCompilation.gmk include UtilsForTests.gmk @@ -345,4 +345,6 @@ TEST_TARGETS += verify-root1-first verify-root2-first all: $(TEST_TARGETS) -.PHONY: default all +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestMake.gmk b/test/make/TestMake.gmk index 3ff8a255e8e83..a017b573d0c3c 100644 --- a/test/make/TestMake.gmk +++ b/test/make/TestMake.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,9 +21,9 @@ # questions. # -default: all +include MakeFileStart.gmk -include $(SPEC) +################################################################################ make-base: +$(MAKE) -f TestMakeBase.gmk $(TEST_SUBTARGET) @@ -50,10 +50,12 @@ configure: TARGETS += make-base java-compilation copy-files fix-deps-file idea \ compile-commands configure -all: $(TARGETS) - # Prints targets to TARGETS_FILE which must be set when calling this target. print-targets: $(ECHO) "$(TARGETS)" >> $(TARGETS_FILE) -.PHONY: default all $(TARGETS) +.PHONY: $(TARGETS) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/TestMakeBase.gmk b/test/make/TestMakeBase.gmk index 78f2c1884c902..61fcbdf522fea 100644 --- a/test/make/TestMakeBase.gmk +++ b/test/make/TestMakeBase.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ # questions. # -default: all +include MakeFileStart.gmk + +################################################################################ -include $(SPEC) -include MakeBase.gmk include UtilsForTests.gmk THIS_FILE := $(TOPDIR)/test/make/TestMakeBase.gmk @@ -725,3 +725,7 @@ $(call AssertEquals, \ ################################################################################ all: $(TEST_TARGETS) + +################################################################################ + +include MakeFileEnd.gmk diff --git a/test/make/UtilsForTests.gmk b/test/make/UtilsForTests.gmk index 25c1aab2af310..125dabd15ef1b 100644 --- a/test/make/UtilsForTests.gmk +++ b/test/make/UtilsForTests.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,12 @@ # questions. # +include MakeIncludeStart.gmk +ifeq ($(INCLUDE), true) + +################################################################################ # This file contains utilities common for multiple test makefiles. +################################################################################ # Assert two strings are equal # 1 - Tested value @@ -43,3 +48,8 @@ CreateFile = $(shell $(MKDIR) -p $(call ShellQuote, $(dir $1)) \ ifeq ($(call isBuildOs, macosx), true) SLEEP_ON_MAC := sleep 1 endif + +################################################################################ + +endif # include guard +include MakeIncludeEnd.gmk diff --git a/test/micro/org/openjdk/bench/java/lang/StringBuilders.java b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java index ed5c0d30db866..4ef60d88fbf18 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringBuilders.java +++ b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java @@ -54,6 +54,8 @@ public class StringBuilders { private StringBuilder sbLatin2; private StringBuilder sbUtf16; private StringBuilder sbUtf17; + private int[] intArray; + private long[] longArray; @Setup public void setup() { @@ -69,6 +71,13 @@ public void setup() { sbLatin2 = new StringBuilder("Latin1 string"); sbUtf16 = new StringBuilder("UTF-\uFF11\uFF16 string"); sbUtf17 = new StringBuilder("UTF-\uFF11\uFF16 string"); + int size = 16; + intArray = new int[size]; + longArray = new long[size]; + for (int i = 0; i < longArray.length; i++) { + intArray[i] = ((100 * i + i) << 24) + 4543 + i * 4; + longArray[i] = ((100L * i + i) << 32) + 4543 + i * 4L; + } } @Benchmark @@ -224,70 +233,60 @@ public String toStringCharWithInt8() { return result.toString(); } - @Benchmark - public int appendWithBool8Latin1() { + public int appendWithIntLatin1() { StringBuilder buf = sbLatin1; buf.setLength(0); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(false); - buf.append(false); + for (int i : intArray) { + buf.append(i); + } return buf.length(); } - @Benchmark - public int appendWithBool8Utf16() { + public int appendWithIntUtf16() { StringBuilder buf = sbUtf16; buf.setLength(0); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(false); - buf.append(false); + for (int i : intArray) { + buf.append(i); + } return buf.length(); } - @Benchmark - public int appendWithNull8Latin1() { + public int appendWithLongLatin1() { StringBuilder buf = sbLatin1; buf.setLength(0); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); + for (long l : longArray) { + buf.append(l); + } return buf.length(); } - @Benchmark - public int appendWithNull8Utf16() { + public int appendWithLongUtf16() { StringBuilder buf = sbUtf16; buf.setLength(0); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); + for (long l : longArray) { + buf.append(l); + } return buf.length(); } + @Benchmark + public String toStringCharWithBool8() { + StringBuilder result = new StringBuilder(); + result.append(true); + result.append(false); + result.append(true); + result.append(true); + result.append(false); + result.append(true); + result.append(false); + result.append(false); + return result.toString(); + } + @Benchmark public int appendWithFloat8Latin1() { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java index a70861a0dda7e..4ae78d6d99e91 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,9 +64,9 @@ public void tearDown() { } @Benchmark - public MemorySegment alloc_confined() { + public long alloc_confined() { try (Arena arena = Arena.ofConfined()) { - return arena.allocate(size); + return arena.allocate(size).address(); } } diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/BulkOps.java b/test/micro/org/openjdk/bench/java/lang/foreign/BulkOps.java index 6a1dd05b615e5..60f36d9f1572b 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/BulkOps.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/BulkOps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ public class BulkOps { final int[] ints = new int[ELEM_SIZE]; final MemorySegment bytesSegment = MemorySegment.ofArray(ints); - final int UNSAFE_INT_OFFSET = unsafe.arrayBaseOffset(int[].class); + final long UNSAFE_INT_OFFSET = unsafe.arrayBaseOffset(int[].class); // large(ish) segments/buffers with same content, 0, for mismatch, non-multiple-of-8 sized static final int SIZE_WITH_TAIL = (1024 * 1024) + 7; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/CallByRefHighArity.java b/test/micro/org/openjdk/bench/java/lang/foreign/CallByRefHighArity.java index 417a7c39c1a55..51060e3ff6df5 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/CallByRefHighArity.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/CallByRefHighArity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @State(org.openjdk.jmh.annotations.Scope.Thread) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgsAppend = { "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=micro/native" }) +@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=micro/native" }) public class CallByRefHighArity { static { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantHeap.java b/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantHeap.java index baaa19097188b..0605db076ca71 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantHeap.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantHeap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,8 @@ public class LoopOverNonConstantHeap extends JavaLayouts { static final int ELEM_SIZE = 1_000_000; static final int CARRIER_SIZE = (int)JAVA_INT.byteSize(); static final int ALLOC_SIZE = ELEM_SIZE * CARRIER_SIZE; - static final int UNSAFE_BYTE_BASE = unsafe.arrayBaseOffset(byte[].class); - static final int UNSAFE_INT_BASE = unsafe.arrayBaseOffset(int[].class); + static final long UNSAFE_BYTE_BASE = unsafe.arrayBaseOffset(byte[].class); + static final long UNSAFE_INT_BASE = unsafe.arrayBaseOffset(int[].class); MemorySegment segment, alignedSegment; byte[] base; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverRandom.java b/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverRandom.java index 392ac6d667ba3..b21f4d72007f6 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverRandom.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/LoopOverRandom.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @State(org.openjdk.jmh.annotations.Scope.Thread) @OutputTimeUnit(TimeUnit.MICROSECONDS) -@Fork(value = 3, jvmArgsAppend = { "--enable-native-access=ALL-UNNAMED", "--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED"}) +@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", "--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED"}) public class LoopOverRandom extends JavaLayouts { static final int SEED = 0; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/SegmentOfBuffer.java b/test/micro/org/openjdk/bench/java/lang/foreign/SegmentOfBuffer.java index 25bfd44b063a2..973d800eb4c61 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/SegmentOfBuffer.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/SegmentOfBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,13 +57,13 @@ public long ofBuffer() { } @Benchmark - @Fork(value = 3, jvmArgsAppend = "-XX:CompileCommand=inline,jdk.internal.foreign.AbstractMemorySegmentImpl::ofBuffer,false") + @Fork(value = 3, jvmArgs = "-XX:CompileCommand=inline,jdk.internal.foreign.AbstractMemorySegmentImpl::ofBuffer,false") public long ofBufferInlineFalse() { return MemorySegment.ofBuffer(buffer).address(); } @Benchmark - @Fork(value = 3, jvmArgsAppend = "-XX:CompileCommand=inline,jdk.internal.foreign.AbstractMemorySegmentImpl::ofBuffer,true") + @Fork(value = 3, jvmArgs = "-XX:CompileCommand=inline,jdk.internal.foreign.AbstractMemorySegmentImpl::ofBuffer,true") public long ofBufferInlineTrue() { return MemorySegment.ofBuffer(buffer).address(); } diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayCriticalXorOpImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayCriticalXorOpImpl.java index 284bc64bd7ad9..fb43bf9045552 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayCriticalXorOpImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayCriticalXorOpImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; public class GetArrayCriticalXorOpImpl implements XorOp { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayElementsXorOpImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayElementsXorOpImpl.java index df48c2e85afbb..deb121e3fa99c 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayElementsXorOpImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayElementsXorOpImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; public class GetArrayElementsXorOpImpl implements XorOp { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpCriticalImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpCriticalImpl.java index 38d4c72a20a02..123e6d20b7ccb 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpCriticalImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpCriticalImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; import java.lang.foreign.FunctionDescriptor; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpImpl.java index d59203155cd66..481449c5f42b8 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; import java.lang.foreign.Arena; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpInitImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpInitImpl.java index 489255ad11118..6722f21b380f3 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpInitImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayForeignXorOpInitImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; import java.lang.foreign.Arena; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayRegionXorOpImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayRegionXorOpImpl.java index 9104589405a6f..937f9bfee923e 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayRegionXorOpImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayRegionXorOpImpl.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; public class GetArrayRegionXorOpImpl implements XorOp { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayUnsafeXorOpImpl.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayUnsafeXorOpImpl.java index 0b29f925c7c30..59079dc09d1a7 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayUnsafeXorOpImpl.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/GetArrayUnsafeXorOpImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class GetArrayUnsafeXorOpImpl implements XorOp { static final Unsafe UNSAFE = Utils.unsafe; - static final int BYTE_ARR_OFFSET = Utils.unsafe.arrayBaseOffset(byte[].class); + static final long BYTE_ARR_OFFSET = Utils.unsafe.arrayBaseOffset(byte[].class); static { System.loadLibrary("jnitest"); diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorOp.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorOp.java index 4b3927e28c06c..18b5f4de339b1 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorOp.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorOp.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; public interface XorOp { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorTest.java index 40ae114e8fa75..ed7d5115cf218 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorTest.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/XorTest.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package org.openjdk.bench.java.lang.foreign.xor; import org.openjdk.jmh.annotations.Benchmark; @@ -19,7 +42,9 @@ @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @State(org.openjdk.jmh.annotations.Scope.Thread) @OutputTimeUnit(TimeUnit.MILLISECONDS) -@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=micro/native" }) +@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", + "-Djava.library.path=micro/native", + "--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED" }) public class XorTest { diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c b/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c index 2ecea5f2b8324..b311ff0617bdf 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + #include #include diff --git a/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java b/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java index 46853ab698326..43ed83d338996 100644 --- a/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java +++ b/test/micro/org/openjdk/bench/java/lang/reflect/Clazz.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,11 @@ import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; @BenchmarkMode(Mode.AverageTime) +@State(Scope.Benchmark) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS) @@ -52,6 +55,41 @@ public Constructor getConstructor() throws NoSuchMethodException { return Clazz.class.getConstructor(); } + /** + * Get modifiers for this class through reflection + * + * @return + * @throws NoSuchMethodException + */ + @Benchmark + public int getModifiers() { + return Clazz.class.getModifiers(); + } + + Clazz[] clazzArray = new Clazz[1]; + @Benchmark + public int getAppArrayModifiers() { + return clazzArray.getClass().getModifiers(); + } + + static final Clazz[] clazzArrayFinal = new Clazz[1]; + @Benchmark + public int getAppArrayModifiersFinal() { + return clazzArrayFinal.getClass().getModifiers(); + } + + /** + * Get modifiers for an primitive array class through reflection + * + * @return + * @throws NoSuchMethodException + */ + @Benchmark + public int getArrayModifiers() { + return int[].class.getModifiers(); + } + + /** * Get constructor for the String class through reflection, forcing full * security check diff --git a/test/micro/org/openjdk/bench/java/security/HSS.java b/test/micro/org/openjdk/bench/java/security/HSS.java index c2f746d2449e4..6d0cf694f4aaf 100644 --- a/test/micro/org/openjdk/bench/java/security/HSS.java +++ b/test/micro/org/openjdk/bench/java/security/HSS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,11 +57,6 @@ @Measurement(iterations = 5, time = 1) @Fork(value = 3, jvmArgs = {"--add-exports", "java.base/sun.security.util=ALL-UNNAMED"}) -// Tests 1-2 are from RFC 8554, Appendix F. - -// Tests 3-10 were generated with parameter sets mentioned in -// RFC 8554 section 6.4; two with W=8 and six with W=4. - public class HSS { static byte[] decode(String s) { @@ -87,14 +82,13 @@ public static void verify(Signature v, byte[] pk, byte[] msg, byte[] sig) } } - // RFC 8554 Test Case 1 @State(Scope.Benchmark) public static class test01 { byte[] pk; byte[] msg; byte[] sig; - @Param({"RFC 8554 1"}) + @Param({"Test 1"}) private String test; @Setup @@ -103,119 +97,117 @@ public void setup() throws Exception { 00000002 00000005 00000004 - 61a5d57d37f5e46bfb7520806b07a1b850650e3b31fe4a773ea29a07f09cf2ea - 30e579f0df58ef8e298da0434cb2b878"""); + 0e975b10a6b33473d01baa138c155e81d7b7156b389b2a6a09d49f42c1ac4984 + 2d977e65fceb6bc80e06eace38ce0116 + """); msg = decode(""" - 54686520706f77657273206e6f742064656c65676174656420746f2074686520 - 556e69746564205374617465732062792074686520436f6e737469747574696f - 6e2c206e6f722070726f6869626974656420627920697420746f207468652053 - 74617465732c2061726520726573657276656420746f20746865205374617465 - 7320726573706563746976656c792c206f7220746f207468652070656f706c65 - 2e0a"""); + 312e20546869732069732061207465737420666f72204853532f4c4d53207768 + 6963682069732076657279206c6f6e6720616e64206e6f74206d65616e742074 + 6f207265616420627920612068756d616e206265696e672e + """); sig = decode(""" 00000001 00000005 00000004 - d32b56671d7eb98833c49b433c272586bc4a1c8a8970528ffa04b966f9426eb9 - 965a25bfd37f196b9073f3d4a232feb69128ec45146f86292f9dff9610a7bf95 - a64c7f60f6261a62043f86c70324b7707f5b4a8a6e19c114c7be866d488778a0 - e05fd5c6509a6e61d559cf1a77a970de927d60c70d3de31a7fa0100994e162a2 - 582e8ff1b10cd99d4e8e413ef469559f7d7ed12c838342f9b9c96b83a4943d16 - 81d84b15357ff48ca579f19f5e71f18466f2bbef4bf660c2518eb20de2f66e3b - 14784269d7d876f5d35d3fbfc7039a462c716bb9f6891a7f41ad133e9e1f6d95 - 60b960e7777c52f060492f2d7c660e1471e07e72655562035abc9a701b473ecb - c3943c6b9c4f2405a3cb8bf8a691ca51d3f6ad2f428bab6f3a30f55dd9625563 - f0a75ee390e385e3ae0b906961ecf41ae073a0590c2eb6204f44831c26dd768c - 35b167b28ce8dc988a3748255230cef99ebf14e730632f27414489808afab1d1 - e783ed04516de012498682212b07810579b250365941bcc98142da13609e9768 - aaf65de7620dabec29eb82a17fde35af15ad238c73f81bdb8dec2fc0e7f93270 - 1099762b37f43c4a3c20010a3d72e2f606be108d310e639f09ce7286800d9ef8 - a1a40281cc5a7ea98d2adc7c7400c2fe5a101552df4e3cccfd0cbf2ddf5dc677 - 9cbbc68fee0c3efe4ec22b83a2caa3e48e0809a0a750b73ccdcf3c79e6580c15 - 4f8a58f7f24335eec5c5eb5e0cf01dcf4439424095fceb077f66ded5bec73b27 - c5b9f64a2a9af2f07c05e99e5cf80f00252e39db32f6c19674f190c9fbc506d8 - 26857713afd2ca6bb85cd8c107347552f30575a5417816ab4db3f603f2df56fb - c413e7d0acd8bdd81352b2471fc1bc4f1ef296fea1220403466b1afe78b94f7e - cf7cc62fb92be14f18c2192384ebceaf8801afdf947f698ce9c6ceb696ed70e9 - e87b0144417e8d7baf25eb5f70f09f016fc925b4db048ab8d8cb2a661ce3b57a - da67571f5dd546fc22cb1f97e0ebd1a65926b1234fd04f171cf469c76b884cf3 - 115cce6f792cc84e36da58960c5f1d760f32c12faef477e94c92eb75625b6a37 - 1efc72d60ca5e908b3a7dd69fef0249150e3eebdfed39cbdc3ce9704882a2072 - c75e13527b7a581a556168783dc1e97545e31865ddc46b3c957835da252bb732 - 8d3ee2062445dfb85ef8c35f8e1f3371af34023cef626e0af1e0bc017351aae2 - ab8f5c612ead0b729a1d059d02bfe18efa971b7300e882360a93b025ff97e9e0 - eec0f3f3f13039a17f88b0cf808f488431606cb13f9241f40f44e537d302c64a - 4f1f4ab949b9feefadcb71ab50ef27d6d6ca8510f150c85fb525bf25703df720 - 9b6066f09c37280d59128d2f0f637c7d7d7fad4ed1c1ea04e628d221e3d8db77 - b7c878c9411cafc5071a34a00f4cf07738912753dfce48f07576f0d4f94f42c6 - d76f7ce973e9367095ba7e9a3649b7f461d9f9ac1332a4d1044c96aefee67676 - 401b64457c54d65fef6500c59cdfb69af7b6dddfcb0f086278dd8ad0686078df - b0f3f79cd893d314168648499898fbc0ced5f95b74e8ff14d735cdea968bee74 + a63c20fdbd752910d2a87d25c4ba6bb233d5dd363e5f44a25f766a477f13aa79 + 1474acc5f205d27f1f89234282a2f27205bb914efa34ea8bdd8d7eab6e748614 + 79b5e6088451c07b079196d0d897edc8974e3d2fa244e38242c6831b9124a298 + ed74872b0c6c5cd1c25fcc5279fb1bc30d4b1ee122b9292aedbcfd7e49d4d54b + a1a330d88774e6de909a81624c3440b687495758c83b0439fb104d9e7a695a9e + 62247b52162121c1a80999d11e4211cd23c374a1a23e57dfc49792427806276f + c03cc2d0958990c030e2f8c85e2922547e4ae4918833357ed8ff16ae189fbc76 + 1da5a2e02f824d4ebd8ff731f9c3a8268d3056c1917129a918981bb35079a73b + bac9cba7a99a4536ed4420def0d1ca3b9702be27c6d638fb3a8449edf699d349 + fbd44a8c80985d85946d31221942541143ede3b557929c7f2de6840b0910b6ab + c0dac975200be5f36fbcb5d0ebe0c79d7c8b1218e6afa1fb487399f53ac2a10e + e70113fdc20ab4e1689122568eeeacd0da903cb56ddfe54d386e6f7ab7971878 + e3dddcf7f78e31ce95c9aa6dfa26501027e42f7066ee5a94c4ccf6647d85776f + b244ffa85794e873a12634a5468967f05a9a5efc4276944ec9664aaf9b684db4 + bd417669f2e151f174ae1eed01565b563eabf8177fbbeb2ab61667dcb7423a86 + 2dbea29581cada5c0ebab53c0811ec8ebab234b7dbb30456837e82bd5e23e8a8 + a75f4331a4da821abc63d50b1bdc4bd861a0ba1ebfad6db2fd5d44e587ce9bf3 + 095f314be58411b4b2ea5f0fd10bf091c5038bb8290b5964d6f24edb2aecccf2 + eb81cbcecaf1e1320853e326a8af9bb1f456105ea58b42ae9d994e35c505a74b + 50e04e406b247ff34e3ba27ddb4d7d2a6ade1e2652c25da88a8c6a76024c7c7d + 7e879597438e608741ac8bd3f35c9212db9978d7d54fda331df3e302e3b59201 + 4be842a48a0abc58f5421c8f9d32e191aad082ac04bde2e3695e346d2af5e20a + 00c232def87a5a3dfca8809b1260a43403242b303197a5329b951632aab0738c + b45a51c76f1c97a6c836f40c5165e0c68c16a8ab50b078c2b8fe09f280838648 + c6c74d59fc2c1a46ce424e28bdc7c44a683902b06e9995c67e4efd3981f5424a + 3930100b11bf7ef17c99c5d27a661e8d366ee49441278959c59e7af1ae25bd93 + a504291b3e834c5b68c1e84ee885c6e0152c7cf015aac2065ec19ba3b16166b9 + 02621389a60efea12d8b4a5b5d59ab8145c804bb45694d443b09d4111faa2ba6 + e7e48d3bfa3d1c48b427f383b393c7d0e422fd1e958e14e5866cf6dfd06764c0 + fe384c6ae8e1650860dbc12b0e2731ece7ea40e11fdeba8ae7dff74375d7d717 + 2ab0fb15d6c40b1677a2079b5a4af563fc4c08363176ce4da74b1ef34b0b8627 + 1d405a442b60a554fa88d0320363e7b818bf532d3fbc52764479886d3f4d3d7b + b35d0402b17025abad9cc1525e722cca4c961497f784e55f46d8f8067e4705c3 + 6b62c260391575cfaa949ad99a98e9ca2a55d4e2241c33b3dd8b2505a804c6f7 + 67617d02ebaefaa6cd02cc93041395d1c47be820abc647bd531549aee307cbca 00000005 - d8b8112f9200a5e50c4a262165bd342cd800b8496810bc716277435ac376728d - 129ac6eda839a6f357b5a04387c5ce97382a78f2a4372917eefcbf93f63bb591 - 12f5dbe400bd49e4501e859f885bf0736e90a509b30a26bfac8c17b5991c157e - b5971115aa39efd8d564a6b90282c3168af2d30ef89d51bf14654510a12b8a14 - 4cca1848cf7da59cc2b3d9d0692dd2a20ba3863480e25b1b85ee860c62bf5136 + d443111b4f3c3e02ea3043a3db682e8720e10e67852a4331f55deaf62ff8673b + fc8e3fed9740f6cd4a276556c40de3ce8c7c0e60d7b2744f2a481a0d7854b703 + cc47a30d27ed823933e6d87c5573c135c0ced4c944f766de92f216756824c4a4 + d80b9d5337dee0498becbd5b248920283dac655346a847f93555d9a469c66858 + 51891eb06cdfa25179c9054ee8795477c4806df8790becc8eb9ea458656f82a1 00000005 00000004 - d2f14ff6346af964569f7d6cb880a1b66c5004917da6eafe4d9ef6c6407b3db0 - e5485b122d9ebe15cda93cfec582d7ab + bb8df6a42d2b9f29644c2c99967d2cc569b3a8470a960d6fa954aafe5e15660a + 9fa56cc9a583d7b1dab98da3e6c121c1 0000000a 00000004 - 0703c491e7558b35011ece3592eaa5da4d918786771233e8353bc4f62323185c - 95cae05b899e35dffd717054706209988ebfdf6e37960bb5c38d7657e8bffeef - 9bc042da4b4525650485c66d0ce19b317587c6ba4bffcc428e25d08931e72dfb - 6a120c5612344258b85efdb7db1db9e1865a73caf96557eb39ed3e3f426933ac - 9eeddb03a1d2374af7bf77185577456237f9de2d60113c23f846df26fa942008 - a698994c0827d90e86d43e0df7f4bfcdb09b86a373b98288b7094ad81a0185ac - 100e4f2c5fc38c003c1ab6fea479eb2f5ebe48f584d7159b8ada03586e65ad9c - 969f6aecbfe44cf356888a7b15a3ff074f771760b26f9c04884ee1faa329fbf4 - e61af23aee7fa5d4d9a5dfcf43c4c26ce8aea2ce8a2990d7ba7b57108b47dabf - beadb2b25b3cacc1ac0cef346cbb90fb044beee4fac2603a442bdf7e507243b7 - 319c9944b1586e899d431c7f91bcccc8690dbf59b28386b2315f3d36ef2eaa3c - f30b2b51f48b71b003dfb08249484201043f65f5a3ef6bbd61ddfee81aca9ce6 - 0081262a00000480dcbc9a3da6fbef5c1c0a55e48a0e729f9184fcb1407c3152 - 9db268f6fe50032a363c9801306837fafabdf957fd97eafc80dbd165e435d0e2 - dfd836a28b354023924b6fb7e48bc0b3ed95eea64c2d402f4d734c8dc26f3ac5 - 91825daef01eae3c38e3328d00a77dc657034f287ccb0f0e1c9a7cbdc828f627 - 205e4737b84b58376551d44c12c3c215c812a0970789c83de51d6ad787271963 - 327f0a5fbb6b5907dec02c9a90934af5a1c63b72c82653605d1dcce51596b3c2 - b45696689f2eb382007497557692caac4d57b5de9f5569bc2ad0137fd47fb47e - 664fcb6db4971f5b3e07aceda9ac130e9f38182de994cff192ec0e82fd6d4cb7 - f3fe00812589b7a7ce515440456433016b84a59bec6619a1c6c0b37dd1450ed4 - f2d8b584410ceda8025f5d2d8dd0d2176fc1cf2cc06fa8c82bed4d944e71339e - ce780fd025bd41ec34ebff9d4270a3224e019fcb444474d482fd2dbe75efb203 - 89cc10cd600abb54c47ede93e08c114edb04117d714dc1d525e11bed8756192f - 929d15462b939ff3f52f2252da2ed64d8fae88818b1efa2c7b08c8794fb1b214 - aa233db3162833141ea4383f1a6f120be1db82ce3630b3429114463157a64e91 - 234d475e2f79cbf05e4db6a9407d72c6bff7d1198b5c4d6aad2831db61274993 - 715a0182c7dc8089e32c8531deed4f7431c07c02195eba2ef91efb5613c37af7 - ae0c066babc69369700e1dd26eddc0d216c781d56e4ce47e3303fa73007ff7b9 - 49ef23be2aa4dbf25206fe45c20dd888395b2526391a724996a44156beac8082 - 12858792bf8e74cba49dee5e8812e019da87454bff9e847ed83db07af3137430 - 82f880a278f682c2bd0ad6887cb59f652e155987d61bbf6a88d36ee93b6072e6 - 656d9ccbaae3d655852e38deb3a2dcf8058dc9fb6f2ab3d3b3539eb77b248a66 - 1091d05eb6e2f297774fe6053598457cc61908318de4b826f0fc86d4bb117d33 - e865aa805009cc2918d9c2f840c4da43a703ad9f5b5806163d7161696b5a0adc + 3431bace4875824faf76e488612472b3a535893056745f0f20e615806d87ba36 + ab0935d2b080fd6281fa5fca325926ba219c04a02aa2e2faca7ba0f885cb90ce + 5bf07a6dfb60f55541092cbb9386ab47438debaed31b648cb3cab090ab2c3eaf + 386a2024899e4cb83e75340933c564a22c060e5ac792316123d004125babf59e + 082dc93d4817ab8a7cd772fe28a400060ca4dcecc001203a474f294031c44dcf + ebc3c73f672556cda6ad193883c5c95fb1587042b733f936dc0977cbc4aa13b9 + fd22794a7204968e0cdb73cc19061447617bfdcef141fb9b87538232d92b1482 + 54b0917f252efc8766d6b09b0215c675ab5d41c87630121e5e536bcfea3fc134 + f57de38eff427a531ed403d903c1c96b5fd71d8431c03ca8d521a2c686051e0a + 5a57e199d65b0a60a086f70a3e42ad6b343e5565e996e7bb678ebdc1e01f9041 + 289f45c3e0f56e5aeb269cfe70deca17153ee46388ac0d88b24ee7a32c607726 + 1664a5d10fb5f64ed925351b2475494920acb7272962da31c8db6f76baadbc83 + 9d94373f8a203ac3c62fad998913277153e1db8872f75cb3ab18f4b6ae785d35 + 54785bd261b66535f34a756e8749f6d2a6049c9bf8aa991b1c5d79eae63ebde0 + 99f853608dae24d68d4709c0898bf1e1fb44198a23fd7a7ecd653db67688153f + f2a1c399cb3379903e31e4c4f06ef50671eb071a2084d16b08270ff203d51c1a + 5334d777d169c331db8e3e1c6653649d69cf1a3853423c7de5e688b10d741aa3 + 5233ef53440db7a3bd6b9a613183820ea7ec1e7469d1743cf1d8aefb599f6f1c + 08865c99afd652558b73955734b36794351c246c9822e96bc276cfa7cd942f6a + afcdb162a361332ee79a128c6ccf67d0ae3dec0b0a80e716c572162e9eb9230d + 83c3d758d4efecdfb573864f7fc1f203cf0c64d2fc9a68029ea67d7e53885c60 + c7dffc6e1af3c0460a64a8b21c62107f7a3408b724e478d0018eaee33e60350b + 7e355758d236bf8fbaa82d43955a9df4a5073ab1eab25269e89c9278097ed20c + 0d46b0722c9a0ab613ae09a5220dfffb930f013f83262f524061fb47f16dde4e + 48ba37d1e73c5b63bfd3f80ea1b36ad690476e0338271555de0e8a88a2f4ec14 + e05ab9753633ee4b792a715c6c7c1d01209619c4a4070235fb1022781f5ee437 + 8514cf87b6b274bcf25551fec891fba127dcf09bbbaad957ea1e4f512b64d787 + f32538f53fdffe99e3914e9c9815c812b0bc6c1aee4d9d5a5cacd7f0d6f5ecc5 + 958a595788400787615d3ab0bccdf9fc94c6bcf7154c0975d90fb60fafe0834a + 1cd44979b52548c875094b1adc9c63b5de19f3e888db7a0b7a2c238b4090c55f + f57734c24e69df21697c650c1d8f5f62e067bda229e4ec3e9da93e6fa76a9ff9 + 48327baba8c7b8b14a63291fd7fd6847e20f6653edabbc21e257827be4089fbc + 39047197e40ad2553bcdc603c82a1b80c03bf5a461f31e073295a4cbbc02530f + be5a6c3092813f37ae9e2ec7ee8c0dc1a2379cbcfe2ad550e90f0a73f4e789a1 + 270a3332e277e7113ed38527c241817d391b5a2742b6a4cb789a407525f35982 00000005 - d5c0d1bebb06048ed6fe2ef2c6cef305b3ed633941ebc8b3bec9738754cddd60 - e1920ada52f43d055b5031cee6192520d6a5115514851ce7fd448d4a39fae2ab - 2335b525f484e9b40d6a4a969394843bdcf6d14c48e8015e08ab92662c05c6e9 - f90b65a7a6201689999f32bfd368e5e3ec9cb70ac7b8399003f175c40885081a - 09ab3034911fe125631051df0408b3946b0bde790911e8978ba07dd56c73e7ee + e6ffc1535a60978d93a81a64564b61821c7125542c0fe5996a93e0da0f5f8a71 + 2d2e444d1bd96837bf0354ca844e90b82bf08746bbc95189e2268bfa686e88f9 + f90f35a095a2ab26402fc87ddf3656edfb16fe3816ffaf99e983915ebbcf2f51 + 85f294d491c47fb90d3ce9046d2f05da6a723ac342a32154d1c18b465b49308f + 41ca2f0475adf5ed46413766a6057bc810aeb6dd593691b84752b883c8a1a422 """); } } - // RFC 8554 Test Case 2 @State(Scope.Benchmark) public static class test02 { byte[] pk; byte[] msg; byte[] sig; - @Param({"RFC 8554 2"}) + @Param({"Test 2"}) private String test; @Setup @@ -224,1604 +216,144 @@ public void setup() throws Exception { 00000002 00000006 00000003 - d08fabd4a2091ff0a8cb4ed834e7453432a58885cd9ba0431235466bff9651c6 - c92124404d45fa53cf161c28f1ad5a8e"""); + ff466afe664c2581845b2c6af92aeb6e5c4dd15affc86c82ef4e807ad3c648a6 + 4561666c975fd9cb150d6c7acd6e577f + """); msg = decode(""" - 54686520656e756d65726174696f6e20696e2074686520436f6e737469747574 - 696f6e2c206f66206365727461696e207269676874732c207368616c6c206e6f - 7420626520636f6e73747275656420746f2064656e79206f7220646973706172 - 616765206f74686572732072657461696e6564206279207468652070656f706c - 652e0a"""); + 322e20546869732069732061207465737420666f72204853532f4c4d53207768 + 6963682069732076657279206c6f6e6720616e64206e6f74206d65616e742074 + 6f207265616420627920612068756d616e206265696e672e + """); sig = decode(""" 00000001 00000003 00000003 - 3d46bee8660f8f215d3f96408a7a64cf1c4da02b63a55f62c666ef5707a914ce - 0674e8cb7a55f0c48d484f31f3aa4af9719a74f22cf823b94431d01c926e2a76 - bb71226d279700ec81c9e95fb11a0d10d065279a5796e265ae17737c44eb8c59 - 4508e126a9a7870bf4360820bdeb9a01d9693779e416828e75bddd7d8c70d50a - 0ac8ba39810909d445f44cb5bb58de737e60cb4345302786ef2c6b14af212ca1 - 9edeaa3bfcfe8baa6621ce88480df2371dd37add732c9de4ea2ce0dffa53c926 - 49a18d39a50788f4652987f226a1d48168205df6ae7c58e049a25d4907edc1aa - 90da8aa5e5f7671773e941d8055360215c6b60dd35463cf2240a9c06d694e9cb - 54e7b1e1bf494d0d1a28c0d31acc75161f4f485dfd3cb9578e836ec2dc722f37 - ed30872e07f2b8bd0374eb57d22c614e09150f6c0d8774a39a6e168211035dc5 - 2988ab46eaca9ec597fb18b4936e66ef2f0df26e8d1e34da28cbb3af75231372 - 0c7b345434f72d65314328bbb030d0f0f6d5e47b28ea91008fb11b05017705a8 - be3b2adb83c60a54f9d1d1b2f476f9e393eb5695203d2ba6ad815e6a111ea293 - dcc21033f9453d49c8e5a6387f588b1ea4f706217c151e05f55a6eb7997be09d - 56a326a32f9cba1fbe1c07bb49fa04cecf9df1a1b815483c75d7a27cc88ad1b1 - 238e5ea986b53e087045723ce16187eda22e33b2c70709e53251025abde89396 - 45fc8c0693e97763928f00b2e3c75af3942d8ddaee81b59a6f1f67efda0ef81d - 11873b59137f67800b35e81b01563d187c4a1575a1acb92d087b517a8833383f - 05d357ef4678de0c57ff9f1b2da61dfde5d88318bcdde4d9061cc75c2de3cd47 - 40dd7739ca3ef66f1930026f47d9ebaa713b07176f76f953e1c2e7f8f271a6ca - 375dbfb83d719b1635a7d8a13891957944b1c29bb101913e166e11bd5f34186f - a6c0a555c9026b256a6860f4866bd6d0b5bf90627086c6149133f8282ce6c9b3 - 622442443d5eca959d6c14ca8389d12c4068b503e4e3c39b635bea245d9d05a2 - 558f249c9661c0427d2e489ca5b5dde220a90333f4862aec793223c781997da9 - 8266c12c50ea28b2c438e7a379eb106eca0c7fd6006e9bf612f3ea0a454ba3bd - b76e8027992e60de01e9094fddeb3349883914fb17a9621ab929d970d101e45f - 8278c14b032bcab02bd15692d21b6c5c204abbf077d465553bd6eda645e6c306 - 5d33b10d518a61e15ed0f092c32226281a29c8a0f50cde0a8c66236e29c2f310 - a375cebda1dc6bb9a1a01dae6c7aba8ebedc6371a7d52aacb955f83bd6e4f84d - 2949dcc198fb77c7e5cdf6040b0f84faf82808bf985577f0a2acf2ec7ed7c0b0 - ae8a270e951743ff23e0b2dd12e9c3c828fb5598a22461af94d568f29240ba28 - 20c4591f71c088f96e095dd98beae456579ebbba36f6d9ca2613d1c26eee4d8c - 73217ac5962b5f3147b492e8831597fd89b64aa7fde82e1974d2f6779504dc21 - 435eb3109350756b9fdabe1c6f368081bd40b27ebcb9819a75d7df8bb07bb05d - b1bab705a4b7e37125186339464ad8faaa4f052cc1272919fde3e025bb64aa8e - 0eb1fcbfcc25acb5f718ce4f7c2182fb393a1814b0e942490e52d3bca817b2b2 - 6e90d4c9b0cc38608a6cef5eb153af0858acc867c9922aed43bb67d7b33acc51 - 9313d28d41a5c6fe6cf3595dd5ee63f0a4c4065a083590b275788bee7ad875a7 - f88dd73720708c6c6c0ecf1f43bbaadae6f208557fdc07bd4ed91f88ce4c0de8 - 42761c70c186bfdafafc444834bd3418be4253a71eaf41d718753ad07754ca3e - ffd5960b0336981795721426803599ed5b2b7516920efcbe32ada4bcf6c73bd2 - 9e3fa152d9adeca36020fdeeee1b739521d3ea8c0da497003df1513897b0f547 - 94a873670b8d93bcca2ae47e64424b7423e1f078d9554bb5232cc6de8aae9b83 - fa5b9510beb39ccf4b4e1d9c0f19d5e17f58e5b8705d9a6837a7d9bf99cd1338 - 7af256a8491671f1f2f22af253bcff54b673199bdb7d05d81064ef05f80f0153 - d0be7919684b23da8d42ff3effdb7ca0985033f389181f47659138003d712b5e - c0a614d31cc7487f52de8664916af79c98456b2c94a8038083db55391e347586 - 2250274a1de2584fec975fb09536792cfbfcf6192856cc76eb5b13dc4709e2f7 - 301ddff26ec1b23de2d188c999166c74e1e14bbc15f457cf4e471ae13dcbdd9c - 50f4d646fc6278e8fe7eb6cb5c94100fa870187380b777ed19d7868fd8ca7ceb - 7fa7d5cc861c5bdac98e7495eb0a2ceec1924ae979f44c5390ebedddc65d6ec1 - 1287d978b8df064219bc5679f7d7b264a76ff272b2ac9f2f7cfc9fdcfb6a5142 - 8240027afd9d52a79b647c90c2709e060ed70f87299dd798d68f4fadd3da6c51 - d839f851f98f67840b964ebe73f8cec41572538ec6bc131034ca2894eb736b3b - da93d9f5f6fa6f6c0f03ce43362b8414940355fb54d3dfdd03633ae108f3de3e - bc85a3ff51efeea3bc2cf27e1658f1789ee612c83d0f5fd56f7cd071930e2946 - beeecaa04dccea9f97786001475e0294bc2852f62eb5d39bb9fbeef75916efe4 - 4a662ecae37ede27e9d6eadfdeb8f8b2b2dbccbf96fa6dbaf7321fb0e701f4d4 - 29c2f4dcd153a2742574126e5eaccc77686acf6e3ee48f423766e0fc466810a9 - 05ff5453ec99897b56bc55dd49b991142f65043f2d744eeb935ba7f4ef23cf80 - cc5a8a335d3619d781e7454826df720eec82e06034c44699b5f0c44a8787752e - 057fa3419b5bb0e25d30981e41cb1361322dba8f69931cf42fad3f3bce6ded5b - 8bfc3d20a2148861b2afc14562ddd27f12897abf0685288dcc5c4982f8260268 - 46a24bf77e383c7aacab1ab692b29ed8c018a65f3dc2b87ff619a633c41b4fad - b1c78725c1f8f922f6009787b1964247df0136b1bc614ab575c59a16d089917b - d4a8b6f04d95c581279a139be09fcf6e98a470a0bceca191fce476f9370021cb - c05518a7efd35d89d8577c990a5e19961ba16203c959c91829ba7497cffcbb4b - 294546454fa5388a23a22e805a5ca35f956598848bda678615fec28afd5da61a + 8b0b372cbd26c8e43b5feee870169c7c8345f7d353980ec3f6f6b81c696c672c + 7d0cfc8f74de7a0950f30151ab06c218c4ca0dc425a713060e1f14a3009ed09f + 565b6f6a07d6fee14a618a34fd02dd43745c7c11572f3e2c9a7d7c80d1d16e5c + ca11706861fb5359bb1a8e78d2da42d528d913cc593b414fe8ceb03e71171fb6 + 6722dd5677c5bd6446c372356e8d4dba0da50ce696b80deeac51fac231e59241 + 84706f9dd5820a430a1d0404071a3ce75f14a8fbee1573ad893cf2f5dea0fe21 + f899305b15fb971b785cb7432ca8a92b13fe055d7a1ddc46628b9591291bceba + 0c9c6d76d8c24b919c2c1b6d5c1dcdcfc177e6c7ac67ef0af08222d6780bd686 + 439b78a5575494330d824b8b6962652b15b3d5d4f8ce2216033741f51b6e3aab + c69817097649124460c9ddd7ffb14df8ed1de436f0958e193ba118334fc12859 + 68ae32b6c3d1af8b8c95e4a620e442efb221ae5eb1953c7b8dfe645587916a4e + c26f60ca2b088accfcf5f8f724b558c527f31cf3ed9311315a629d81f2702704 + 56f237d745ea92ba6777d934df150ed9b3e10ce5a8a16011118081287463793c + 3818c2448b10e1ede5bfa8da646d9417a97ae70db9aa8df030c6019dab6ebb18 + 6b9d4db14b3d9b33d1df3b23169963e371e2ec25bc3d932b8503ccbbe85d5675 + c433e62b5926de825420727da4c6bd70dd93fc4fcf9062d4f2acb96699b910db + 9788ffd122d88911f98e12fc57551b8282e5f296cc0dd075121c88e1a5838c3e + 239e2968af2eceec9ee4f7c3433d3145f2b7345d7c418febd0839fd45771debe + 52c0cefb71a38b55ddfb9b8386ec6e7fb39047df9e963d056d6e0b02a2620ba1 + f58264de9b09347ac0320919df80e5a66ebee3d6e801792b19a31c07cf28fff5 + 85b4788aec445d4d04ca005f6a240d8e90c6bc2398df5ec6a9a1858549b67026 + b6c4a91d10faf47fcc7afa56d228d0518fb7a786d2f24decc476203fd84150e9 + 165f11ec6eb168934bb7055ae2ae0f499ec8205565fcd397c6cb1c8f0bafa90f + 6c61a08a4657a19009085217ac255081bf280c726f2c818c543bde5fd2a67549 + efccf9e0d35144f5c8af2c69dda3b01b7333a31d6d6210475f0168db67c22940 + 4d36818b6d530fb23941ae4c63226ec6135e598c879d6ab88928f84da104ee82 + 30d96494b818b9d7004b2f15c7565dee0f611d1faf2ef538c70f2c08919e7919 + 25b81e658743cf8903e40a1323bec2530288820f2c46e85f0622e50eed0a93fe + 5cf92db7d672d2d3186710c0b7e509afd1d498cb21936befc8029c936f9e1f6c + 587071dae0b5999e407929199f4bf03dea05bded0ddc6ccba2a8e880e972f876 + 142c99fbefd3a362b27416cc2aadd8c595ab31cc53af7cfd87362118e9cb409c + 32cf3600eecd314073e8393fe390e3ed60d105a7d054143227874e96a1a16ce8 + 1f9a17f03aa647ef08670e5ba7e561c025775a574ee84bd294b808c2908b7112 + d02f4d6462be588bf27d418545a64dc6fc472e743c913bf7f702356872166a4c + 9fcda456ca69651832c72786546a9e9011511bfdf7351f2333f944ac82e5f14e + a1be1ad7b0b01caf273c9f3ef540cc79c47c7b32a8febcf8e3c34a3a0641e09a + fbcb9a1c6bbf594e44faad8671d6e4c9d8bc053db2ebdd2e22ddd8a154462b23 + 6b47d1fc2205a4e7405d8e883189d8b863b31152459e602bc6c30d0baed658a6 + 4f2ac6858ea5e11ac3fae173f1a251cd7e5b26693bf994a952cc12a9b684a919 + 77510077cc11002a325697eb0a7f86f7b45275e13e89d959a593d51c98cbb48f + bea795ac5d5e61c4360431bb0712096c1e88a03d2367b2772f34ca938a4c0180 + 68aa0f90314b6b23ae01437178bbf812590e347a7759581748d877a31c94a7eb + 9e839b0f2654a354faae234a819fbab9c32374f3b99ea7deb42e6a169e03d59a + 0ff3a6b4809059fcd4e5c426e5d580f6fff8e49be1c9a1baacad5b1cf0284060 + 6969a2c6d04fbb30952ea3f792a60e517cdd3cd8f427c335b9a66ba6ac321657 + beb77de5e2b8d4a8f5c425665b9cadd6a379b7ef5ba513cfb2b2022d8e057637 + 38d0edad6a24b1e57d7ebd11434a1e6fb00c1f5f9228bcdd2f24c468b7b4408c + 35b54e09fe59ed0dbab9760b3fe415c277e39a0bdd74783d7d0feb4d7428b609 + 319f8e667899fb52c822076dfd07286d8c6058c2fcf8618cb77d0ba1077f49c8 + 8f8ef55e980307dfa8d9a3076d8a7ba32f1c822e1c6bf7beb997e03181bade32 + b0b69507210466acd24cc9e13e4913c7e31dbfcf84021fe947e37f469de19488 + 097852097888f11de144fc03606c68d63c7309c054853e1c66ca1b499898fd8b + 5edc934e7f368022c2576e18db909b88a8f9c6caa5fdc00f7da47995ad2e21f9 + b9e3133321ec6e7f6d43ee30b5376b846ce6390e1168b0543e4a50d961f82588 + 58569f6a98e5bcad0dd90c4b88e982f34e7ad2897d8218aaa9284d947ddba4eb + 25a1f02ea59504d82c1e570a2804dd9fbde7dfaaa40996e9aeb0a3d65c27e3cf + d81005ad070375c868ac754bd849700c52b10828deab05eefd2d0575a3ef7338 + d7ae9fe2c1c6c0f38abb7a63381a6903035ce87b93e0c4927e6b15a32d8bf86c + fd9f9bd21366a2a264ebf96bb1213ae8bf7e193bd3eb041a7beebc8d5c474b2d + 1a2afd2488dd1f5176e99b11d6986bd8a30f2c4de7abc0a8b9d18e591c2e7deb + 05944d7661cce336f0c08ed3283a8500d91030e2553b1fa7839ff232ac8f70ee + e1656c964a627bec73bf015b10b59551a38cc0a7b95b4cce2f8292ea28c85c20 + d51a97d0e0c59f99b9af2fc7585cb97999c298885522e6bd8a102cbeb891eeca + a7d3a2402c0a00ab85f66f0267fbb707ea1052f1f926e4328bfc31cbbfab6689 + 5f290ffb90970a62e506ef39513a7d3792c0c3f8d7cd285db8326c6b0d5d4323 + 261ef9ccaefb1fa8e68b9de82345578729904ad9de4f2c5640fddef0c4f54ca2 + e12115befeecd8145be43d3ade502970e255cae2af3cc221569592056eb9f61f + fe511566f235325bac531d8b25bcbf31429426d002f265a4971927246efe218e 00000006 - b326493313053ced3876db9d237148181b7173bc7d042cefb4dbe94d2e58cd21 - a769db4657a103279ba8ef3a629ca84ee836172a9c50e51f45581741cf808315 - 0b491cb4ecbbabec128e7c81a46e62a67b57640a0a78be1cbf7dd9d419a10cd8 - 686d16621a80816bfdb5bdc56211d72ca70b81f1117d129529a7570cf79cf52a - 7028a48538ecdd3b38d3d5d62d26246595c4fb73a525a5ed2c30524ebb1d8cc8 - 2e0c19bc4977c6898ff95fd3d310b0bae71696cef93c6a552456bf96e9d075e3 - 83bb7543c675842bafbfc7cdb88483b3276c29d4f0a341c2d406e40d4653b7e4 - d045851acf6a0a0ea9c710b805cced4635ee8c107362f0fc8d80c14d0ac49c51 - 6703d26d14752f34c1c0d2c4247581c18c2cf4de48e9ce949be7c888e9caebe4 - a415e291fd107d21dc1f084b1158208249f28f4f7c7e931ba7b3bd0d824a4570 + c3aba396848a87900478ae558564722df671d145ad178dd9ef736fc5c353a8db + 82e4d9999c4c2e0fae928a66cd3aaf71678ff745d5726d65b0dd6a0ee5f85ca5 + cecd79ef77e4aa47d284a0bdb71662148029d8d891e2381bb7e6045efae1f641 + 505c4b31a8d5acae51cbef029b047e52a5b495aabeae20ee94f8c56ae9b0ac6c + 2d01207d212698865cb0a47e73b6247e777118a617c4b49a558dd4f1d0886f19 + cc2344598bf5cd9039bf7879d37abc66aa3947caf939425adc599d3d1190747c + dce7f61a12f92bd2c1ad95eda9a3b2af26c8ee652b9be2f36e1f80b2ef37bd23 + 2a0d94cc605402848df45afd8ae36d729b25f00d1a09e8fbac6e323669227506 + d0b7b2bab0b320bf58e69a6879e67880c6818ce83f8630c91ab0e82a3f54ceeb + 1053a66d540d800956b248e951695e52c4290014c4fd7eee8c93393e593cf54c 00000005 00000004 - 215f83b7ccb9acbcd08db97b0d04dc2ba1cd035833e0e90059603f26e07ad2aa - d152338e7a5e5984bcd5f7bb4eba40b7 + 0f5cf24b2d72360a58d71392202a49fbef628a53b11e3617bbc1723a879a89e4 + c64e0e5dea7faf8cac58d4e7fcd71774 00000004 00000004 - 0eb1ed54a2460d512388cad533138d240534e97b1e82d33bd927d201dfc24ebb - 11b3649023696f85150b189e50c00e98850ac343a77b3638319c347d7310269d - 3b7714fa406b8c35b021d54d4fdada7b9ce5d4ba5b06719e72aaf58c5aae7aca - 057aa0e2e74e7dcfd17a0823429db62965b7d563c57b4cec942cc865e29c1dad - 83cac8b4d61aacc457f336e6a10b66323f5887bf3523dfcadee158503bfaa89d - c6bf59daa82afd2b5ebb2a9ca6572a6067cee7c327e9039b3b6ea6a1edc7fdc3 - df927aade10c1c9f2d5ff446450d2a3998d0f9f6202b5e07c3f97d2458c69d3c - 8190643978d7a7f4d64e97e3f1c4a08a7c5bc03fd55682c017e2907eab07e5bb - 2f190143475a6043d5e6d5263471f4eecf6e2575fbc6ff37edfa249d6cda1a09 - f797fd5a3cd53a066700f45863f04b6c8a58cfd341241e002d0d2c0217472bf1 - 8b636ae547c1771368d9f317835c9b0ef430b3df4034f6af00d0da44f4af7800 - bc7a5cf8a5abdb12dc718b559b74cab9090e33cc58a955300981c420c4da8ffd - 67df540890a062fe40dba8b2c1c548ced22473219c534911d48ccaabfb71bc71 - 862f4a24ebd376d288fd4e6fb06ed8705787c5fedc813cd2697e5b1aac1ced45 - 767b14ce88409eaebb601a93559aae893e143d1c395bc326da821d79a9ed41dc - fbe549147f71c092f4f3ac522b5cc57290706650487bae9bb5671ecc9ccc2ce5 - 1ead87ac01985268521222fb9057df7ed41810b5ef0d4f7cc67368c90f573b1a - c2ce956c365ed38e893ce7b2fae15d3685a3df2fa3d4cc098fa57dd60d2c9754 - a8ade980ad0f93f6787075c3f680a2ba1936a8c61d1af52ab7e21f416be09d2a - 8d64c3d3d8582968c2839902229f85aee297e717c094c8df4a23bb5db658dd37 - 7bf0f4ff3ffd8fba5e383a48574802ed545bbe7a6b4753533353d73706067640 - 135a7ce517279cd683039747d218647c86e097b0daa2872d54b8f3e508598762 - 9547b830d8118161b65079fe7bc59a99e9c3c7380e3e70b7138fe5d9be255150 - 2b698d09ae193972f27d40f38dea264a0126e637d74ae4c92a6249fa103436d3 - eb0d4029ac712bfc7a5eacbdd7518d6d4fe903a5ae65527cd65bb0d4e9925ca2 - 4fd7214dc617c150544e423f450c99ce51ac8005d33acd74f1bed3b17b7266a4 - a3bb86da7eba80b101e15cb79de9a207852cf91249ef480619ff2af8cabca831 - 25d1faa94cbb0a03a906f683b3f47a97c871fd513e510a7a25f283b196075778 - 496152a91c2bf9da76ebe089f4654877f2d586ae7149c406e663eadeb2b5c7e8 - 2429b9e8cb4834c83464f079995332e4b3c8f5a72bb4b8c6f74b0d45dc6c1f79 - 952c0b7420df525e37c15377b5f0984319c3993921e5ccd97e097592064530d3 - 3de3afad5733cbe7703c5296263f77342efbf5a04755b0b3c997c4328463e84c - aa2de3ffdcd297baaaacd7ae646e44b5c0f16044df38fabd296a47b3a838a913 - 982fb2e370c078edb042c84db34ce36b46ccb76460a690cc86c302457dd1cde1 - 97ec8075e82b393d542075134e2a17ee70a5e187075d03ae3c853cff60729ba4 + 4849cdc5ce9923584e66bda4a1e96c856ead6a30672d94cab9ba1dcffe30843a + 646bd1ecba04f13bf7c6d7d8aabebfa8cb9a2190cd93d65d921ab7035cc81951 + d073609e5dedeb6ef7d00e2ed4c2680772077a9ce3f99ca74eb97f91339a81b1 + bb1c0dc10ad799ea594d4e7760463b4e441661c5f8e09ee9cc82c461dcfdf13d + 391db836b3d30fb42d33cabccb8ef9c81d054114e298a8100ac8ba9bcee4f518 + afd7bd2a158db134dd5ed299435ab7d2dc32db8b7fe35b24186e3c4b6114f7d0 + 46ba7de17e65ce9e1c5618c308c650a828d1c0f786a3d6a69ebbf04e51449308 + 868ecd7a5ce8f87f796396dc4837d08740376205249d8517a47c2ba816ab6c9c + 8bd8fd841ba4667ec53d353a661ea9e5ffa1769d981e4a31178e4f5ad3d99623 + d58c0ab2514b3c5306f3c83927f1b11a3784a384322780b100b44369f80b340f + 8212ad7f5092c44178a22a54110da8f8d3e8ac473aaa687587ea725806f44eaa + c1e340bb7aa801b455914418c1cdd6b59007f4ac5e9d519f2158762e40957507 + 3d6f30736f065bb74cd2c5d60b917cbad94af657ef37c1b92938c959e21d23f1 + 6950c38c2f6eeede9b1675dcc4b4985bf892f3a2a0ac601bcde4acde5ccdf71f + 0a850d9813f92f7279482ae2697fed0722d456d8557ab5bb3fd49421f8d2e71f + 06769fcd695fc186ecb0236051b534bb6a6641d859fd013afa975c0bf889b900 + 433581712b4b04c758fc121deea327817456f70135c3db767e16041f933186c4 + 081fe52635b917bc809c2063d035e14fb512a452c8f443f2a66362ea6b08ddd1 + 6d3a04065611cc962ccad06598fce7821837302ba00d57a83654130f582ce62c + 3266cae361d7db6f2b740ed7f90dca1ff4bf9ec4a0b7cbce226390bc2c38b3bf + a27a40508139f985749420e6fc4ebafcf4799248661e1134e5442f1ef8714739 + 1d589b45ecb61ac90ad6f82cb2bc3f006b62c40dcda5c362b5d4a8c56e42f672 + 1b8598de29d5d6c1293b3751d48ccff5c5805a59a41c00a6758913c86861f2ad + 2400f93fec76e1062db46e4e21f70d7881b7c91bafb9cd34afbfb05ce072fb3d + d4d9970ea49b57ed3ac73a2d75973f8d2a29de6e963d10bc62b695359d5807ed + 7ea0eb6908207698d08e96b619755872e840248550f053cc2597a65df404577d + 828c4604dc143cd42df691daae06a50502d7ad26d577478a00131fb4de24e780 + 39b56b4fb1408a26fa72a9f5db80fe39e49e414a27d57ab3abef508628812bea + 6f61e9e182148ddd920efb7493d3b68a79c3946c8dec31fe6963e8c2dea92dd7 + 9f789b20036b493bbdf605f45654498b93493181b71f261194f1faa6180f23ae + 6417720055d0b966a650e5f217bbfb1c711470fc9014874f8283d6efcabed894 + ec72f5887580f5fb9eb5e9be81a9e1f8ad650acd07069d499720815d052f4e11 + 8d14be427742a206f275a1b6570f684feb8c4cd62cbc89d0a93de601a7f0ff40 + 4125b7d29c1820d0b26490efde697f1699f4490a8b5db33a07af8df86da46817 + 2ebb99d63c45a3786d2be23395d5761f1c59ee591e5ecf35ba5cf2b5d39e8615 00000005 - 4de1f6965bdabc676c5a4dc7c35f97f82cb0e31c68d04f1dad96314ff09e6b3d - e96aeee300d1f68bf1bca9fc58e4032336cd819aaf578744e50d1357a0e42867 - 04d341aa0a337b19fe4bc43c2e79964d4f351089f2e0e41c7c43ae0d49e7f404 - b0f75be80ea3af098c9752420a8ac0ea2bbb1f4eeba05238aef0d8ce63f0c6e5 - e4041d95398a6f7f3e0ee97cc1591849d4ed236338b147abde9f51ef9fd4e1c1 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w8); - @State(Scope.Benchmark) - public static class test03 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h15_w8"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000007 - 00000004 - 0dc6e2060bd57f6893d7934b26515ce751360f93dd74a648fa015aa79c862407 - 5ae5daea402617abb48a1f6b9e2c9f28"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000004 - 96755d5f8af0aa32419be743afe779842db52a82387fedd67881aec7172db8c0 - 70734189eadc76de06e2fc999e8ce42e7ba68c942515b4547abc8c6659a42fd1 - 371b03ef9ddafdf755b4ea374bfd00b259baef59fd87fd23b1ca5c254ae54fdc - 65eec03046b0ca68e8168f82c2e7d28f456ab4f3c69c67ff550cbabdf0f25437 - c890347db9d87e0fd243a0341bd6d6cde5190d3c3e7a249bfb757228fe6353f7 - 69ce313fdaaee88c0416622625f3b6206c2302633e81c23f81de067393a3e3c8 - 537d3b6b800e7ccea2d90787fb8b7c73cbdf1e778044786ad3b47cab75f9238d - 4ef8913fd5ad1e9f762200a649c3e42915f66210c6674a9c0f5a1dc780607b36 - c20ea9e299b2dffa4cd144d0715d18cc7130736ebaa67db1c69336ac3c4295a9 - 94c725bb75a5638a569399f4905f39ccf87999e053fb08ac6e3c04dbbb9c9196 - 121306e02152603817a574f15dcf010ae68401367024a62ecc4c0dc68bbc76df - c604978101c1ebe4f5fbd8b0bd14aded6740c60b3cb18f8d166c4857940ae8b9 - 25b707b56637499984f24194cdb2aa66b1bb80a679a8a40bba732ef19b80c301 - 91bde4b32c6ec0267d81dc86a07ab30afb24b422e99285faae17e8679cf3a6c3 - c1682a1d91afb678700fa40fabf03e8b795bd06c4b0b2f8f124ee6790f5aa410 - 5b8eb7b845efddad84488ebaae01ba7f28e9c670bdf4a142305f3376d13c1a55 - cb3e8618e05c11bcf244ae51b825d221e372f45b9c0f512a8ebbeea9a01f213b - 75f69f8090f50c11f13ab092c947ded0689803c834c2bbc8b80310be3ad15972 - b745678270a0a670806ff1dfb00c65bf661356634bd9466946d79e7e59d4bb63 - 008f22127172f54c7c15531003a7d31dd949ba15a401b6e8b574f462ee296fba - 00e523fe2c54b4b763eb18028d49f5fe60fa88c7c26188710a2ef040c2641c1f - 0499a41352ce2c397bee4fa7ffc84a4834419bc571bcfa9ecf17e5e30e14042d - 424d0651e85b826e8bf592285e83d01b8b67eff87caaca112fd67a1ed4d5ae7e - 2a587d4390c8fd1ef366ff80b83ab02973bcce0be3352656c7e07dfed0df04df - f886adda121035831bf24c31a47157fa19f1e29a7c329a8c0647365886d7914c - 969f5477211713dcfe40883c9e00037b200190aa8bd6441e2e9caf895b9ad8d9 - 52dc7e2ccaaa1d5181b1554c90da50f53bbc993e9a04caed8aff848b72470d1c - 7deb858d9baf393f63d8f85cf570161d74a12c93de618d0b1112d5c73164358e - 92ce5e4d344b0c9a20e045b47f7ba00567b49cade32612222a5178e5868d88a3 - 3ec703145ba626a497a716db4ef391cd6c4061dbb904bcbf6ce0e9010893d15b - 991b3b0b1d48e2973a19bd94ce2de05577e3db8961dd40c2107ad39aca37e101 - 66a1788260c7cd125e615b0f19493923a17c0bdba2c982a6ab29fc28689e2b55 - c6460afe1e49332835228ea102e9bebf60fe64e44dc1643eaf49c569331e8ca3 - d4c7a8206d4b088d786aa514322d9030266fd52d5b92170a112c36b86117f8e7 - 37520d176ee71b88a13e22b74afb78915c8516bc2967b46b350c6cb5462cd3fe - 00000007 - 7547b8dd925185bf123233ebd5d6efb5b84c25f193ccc96f3cf5746053054d09 - 274b10a2e41c5b137cc6e3008f6fbe13a32b41ba0ca3d5b95d2ca2af3a7791b4 - e4e80d0a837cc7ca2660105679d28c7230bacf244b74e89c9d1a00ec30a96d12 - 5ff86a045d8d1ce2cad8df211cea8053336b35a4ce75ea9b6a3693c906486a2e - f978e4bc95d39450ae4c44b5204a0f463061cecf2f4b5a3182b40305b57d9bf9 - 130d38397d257fae6eed3ccf5ed8739738f948aa1e99ada7da70e2f4cb090758 - 21323fd7b9934344bb47a53196150b88c4e016363132e798a5949a2b52e7194b - d4babc9dc13749f7e69ed462f42de21e03186b6e13aa496b73784d071f8f8292 - 63b37b71c24b1316bfe5dc48d19cfb4a3dfab112311cbedb59de0fc6d139676c - b5cca0ed495ce2251895447f4983d8147999a9e8a3fbae038e0d3c941b81bdc9 - 6a80dc3b8569237837940d148150c400d2a93ffe7f2b62aee591498b6c659cb3 - 1da85478899ad1bfce0803419a4b5bfcfb0ffc27481c351dc594af1146d1ba70 - 127968e379d34fa22c03a1ca9f2cd8d2f255e9ee2058a6b018cc464d758d633f - f4197291b1ad4257f8f76e1633c19f77fc361767a7a3804d5607931d975d3b19 - 5182fd0867719ce10daf0f0c0d52b16b8088ca9a26a22aa05224a1765fc82961 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w8); - @State(Scope.Benchmark) - public static class test04 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h20_w8"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000008 - 00000004 - c8568f619f0d5429eab1e63c80e058d1b8a326640a6ab457d776c52eec545dd9 - 7fedc7e225ab0cce270d961ff9b1615b"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000004 - c89e20317ae8d2211c381fe7354bf382a750e37c307588a30d1bb9a5868e0fbf - 414378b30f8c59ccb95a603f03679a417c01bcb191677d629c37a396ffe313c7 - f27f1553e993102d1b311b92fd7669c2d1ada6cc808c11477c86fa928196028d - 3855d6a39fb56a73ac8eb812fa1974778ab1a7838eda03e4b7ff32d8faad4574 - 1ede66888334c584ae4086d6a5446772c3f18041126e1972d5acb593261a0a5f - 2685e71bb75fae408c4d8dc359bd723d97b5180d96d57a9edbaa7a74f2ef4aa7 - 316bf4b8232bb32b32bfd3e6c4b7e1356d5822fb90b8c861e8ef9a1f7cd67b32 - 2b632c2565a6ac6e3635568f1c2cda59cf4ea6a83ec622f81dda9db0b91fff87 - 080fc8b29ee5514cb25c943a714bd298ea0bba527decdd546c76151b0a9b6c60 - ef9de9b8aabc3c979f08fa1a613682eec4c564e5c0d87e932bc618b6009ad575 - 59489d25a58a4338a03c9ed4c8a89eeea418d5b4a7f813eaf163e2530a40ee84 - 9b8893f91a2f5aeab8ddd32ad8bbb8e0ffac69d0f1b5333d5211d11f32cb89a9 - 9f7f346aa5f3c68447e831dfbce57a0a90ac32cb59066f1e5a0c7eb6bb5ef4d2 - e941f0a8ffe6e8e944cecdb7124a866e4282ecd848bf53f94f0323828a2250f8 - 9a59dbc5a0dd02fc90fc433219ce64e982d86c5ddf3bc8bff3ac7f2c6e5dbab1 - 50a2f4371ebab285f70e25fb0f64667c5805381ff1031321e6f8cb1c85250393 - 5db51e0032f2da99c0bcc22cafe3abd1d7fddf676713a7fcf2388ed13d60a8a1 - ccfb996d9d0accf2be789b949f8cb8ee895f870c4b0c4280a99713abfa29377b - b22a6cfa5f3e0bfd7b6b65c395ac40f8e88980fce0c4ea54b55271a6b3a78a15 - 957cee33a498d237cb0b6457e7b539591b4c3c01b3ed1e75308cb2d85b1a5d46 - 40086d1f3c01a244516beb5409175179cc112c16bef7041c92be7e25843703b3 - c9fdbb1e9e2d880f9e2c54b8cec53bff94d15406cdac5793dad36af28abf8f16 - d95606410d7a8b2af01ddea64572d77609bc9b1f26e0f61ed6115709edaefe5e - c3c44e62d93ffb3dd868f799de31fdd82a5ddbf9126a5271fb368624ecfcba8e - 859e9d644063e2d016f3bd6984495bb67a92295a7ba6958d09fb3fa5415cdfbb - c25605e991a5a6d914199f50842357226438c5d757cf1d0bbffdabd32cdb1559 - 3167d8e672bf1653c2c7466ab7a84e4b587e62be7fe73270cda64513e39966ae - 71108c4d187175ae14d9d36dfe6754770febe70c88515b108a20e4fddc240531 - 3a47377388104fb2597ab1c6ba6aeaf96bf9fa3ef7aa8fc61fdb46fb4c99d401 - 3ec90362b3b2df6b9be155ffd520f696950ac931d1d32c1fae4d0da0ef76065c - 5070edf2043fc9b03ec3c250594f92b8f80862182501a4cb2637d79d347cc2cd - 966a3d20415bc34a870d0e9479da62a820f7973e8737a3d1f1cb04507d70981c - 5f30c0319443ba0a03cab8c8460306b5a66dd1efe29956995ab4488ee20ceb83 - c0891c84eb01761ed74d514d483a51e11a938e89e1f1e6b4a23ebc71150b9381 - c01faf71b0ab4f2842f342b80d6bb58bb410091e314127d1c33520e5f38f02f1 - 00000008 - 44feef16ea19cce8296b02d3955c58a873f2adb5672f5408d2a1c404c0a955a0 - 45f483df1000b0cd4dbf5c7918b5259866135714df5fe538b26c10d19b29c5bd - 3e6d7f04bf4544385f9fac1e216e371888f866ac840a83518f940f1d0c77487c - eca40d5fec7174006e7255ccd1a85fbd745c0d17797e0425edf97a92b8eb3b79 - e524988e3aaaeff9ae4762289737a39acf87e381b5cbe4fc2a0ec29bb3fb5dfd - 77c4ae959b46e038e7150c7bb26613125728dbfaf900aa6696c6f2ce0f590c30 - 14d6b61f70897b732564baa09674b12ff2412eae3378a15ca8ab7d79af7372b3 - 3dad3878699eda11cc5265d591a2b00a5d948c38fb4e9c4bfa2f34328d590c19 - 26396c9db7355037bb9e7fa0918e9d2467d358898bad77ed3fdd2cb6f0d14f92 - 67ba57212ea080200635419bec21ac4163aa41209865b212c5f4b000968e2837 - f55c5dc8389f44824427b4e6cda1917e73f7fab883717a0304373e95a7118909 - aa1e7854e2546c766823e2f2f4a52f001763692bdb45675ee65101f10007fdef - b5205b6f2d74c42396a7de0a55ff47855e50cea65f46549f845ff855ca6bceee - 450eb11b7932b6465736893ca654e1faf280ec2da99dad0b833f5c4e7d805af1 - 0e95359ba4e23b2640e2768075815adb2298fb5d1dd3552b0e868c2b69a92da3 - 8b83713af275e933354c5a02438480004d26d0667c3d31236f2e42e594b3108a - 2631d63f6b0d6abfa0cc338294019b38bed8da4b49b0ff1a64871ff648687c5c - 97b863b78eb60844af1e94d6d3ffbaeead48a974e65fff24776553b3dca6c7b3 - 072a39cfd09a8bf9c7591c605659c1b103288486475f54be0fb80c18717a944f - 51b6d317fba486e1e0ab5afea205335836e717a185827ea4cd47d557be53cc4e - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test05 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000007 - 00000003 - 7bce4db5bd53cb23819d0fa2181e4d441453ff821284c9d83b8ddace22581469 - 593d6dd0aa2c99feddc84f8242f6a002"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000003 - 92f6ada5a00376437675ae462a5c40d4b1123d97352fdeb3f0b6dd741a3e4db7 - 60ec956306dc6f2900f5e70e427265deab2d979ebef270cb61fac22a6b6ddc78 - ec265af6ef86c9513f3de135f674948c08e5cda0cb953fc6846e2720eb669fd6 - 2d7e1fd5de25ea3491a4d018782cd929f8df2684ed20c2f71950ac606e86a475 - 4f60cfca6810ff34233425f932bef13cbb334981f71d54ea71de3510ee52fd31 - 85cb24191f426bdec8c10caa831e74498ee52dece68f886e9b157b68f2f521b2 - 17e5907d824bca542126b9d79c70ed4cb1431146025e42ecf8f12b970f109f79 - f74e4af4511d966b032976f93ae8118cb4cd3924e92bfe5f508101b0abdc53d2 - 6f5c1720448e2efa4b97aea98e2069eb4495e2c093601fe70193ed469162e976 - 4ca3cf64866c59189a488a9e7a510149e0e9b92b0fadcabf22140841946997c4 - 51410e4954faed09bc3e3e5dfdcfd598e5e70966356718230db6ea8bdf22256d - fb337383d342212b6fbe4be731aef548e86e628fb372971e20d878d3f003b06c - b363799967396381c34252b306a67cfd469710aa9664222dc22fe41008919439 - 9394d75ffaeeac3b621b0643de2e98f723a761ff6e695f673c3d70918247ef5c - 39f222ddedaccc63b6da7ebdfef33a1aba8df3e2444610f6c7b72ba15352f783 - b1cac31841e58f6f22a78e2f8521379e226c6890fe41682f2c2a74a44f619f05 - 84a343deff837d809e41e82cc6ca0b568eb4dfaf5df71de6ad488a3733d07db9 - a1d4137cb10244167dada62b3300e5329f886bcf2d35568f39ec759ca82687d9 - 37fc2b6c7b22d0016f856d9ab353503399bd525298a460b5e5b748942affbe5d - 5f562145c6018f53175bfb1c145e512baad481193889f487eb6a007ab3fe7d0f - 3e7298c3519fb6d6f6f1c493f5e18bf64e5d421ad60b5c01b599aac05355e674 - 1966c4d95f3fe002fb936c948121db57a921baef1d9aca2aa918641705a7618f - 59df64211e2a0043088af6e970e6e87997a7f9b1fc85513dba92dc8d1f990ada - a8694c4b408341d2e1e01e07ff329486d322ee9b5fa7c3498558c503358f29ed - 7abf96c1928b3d21f5262517800587d01517a3ec8fbced7d3f0f7523e6544d7e - 2cc5afb15b709fac35301940ca8cf4ef09abe8d1b175cdaa84caba9dad175890 - ed9f51d762881e16cec7fed78fe9324bea6b372c09e1ec8078c73192e6869830 - 5f16d35fdbe5ce305473399014e15c1011329723df62e3f39d28b9e9576e16a2 - 1199b8eb076017b0500ec5da3e33789a48f6115856a586923f23f167912a307e - 19cc96697a4c3198211e95defbc541b797718b0a59bd330a069a3eadd2c285e6 - 275dfce172e1a109614f0a23ca45fe29dbdf943710176ac138ca10e8a09d87f0 - b59ecc4073fa253e0b6707557d075175a167bd0390e089b300d3106c21e83aa0 - 0ab384f9b301da07eba951294252a421e373def9205711db8326e1558bbd7a79 - 3665e5663ecc7a552223edabcc6333f07095f274d3e3aa8ec114b8e124aaac0a - 4e99113d1950ddf46edf9ea8c8af0d9fd72146885e381a9d899b84d404906db5 - 6f7f3c209be9da130b0011de9916f7d63c3172637ad83e9a9566d7938559fae3 - ac94602daef9f18a8d908e55dc962c48aeaa49c29b4fdb2a3ab38802f650225b - 8e6b3d25d3590ed13c3d22e3f1253d385fb02b1feee7770b0f5eb66df2558d5f - 3fa6a247e297e96b8f8263648f5f469c8e5313fb929c801e61a16ebe10286010 - 2c2e9e1a759b7b1f4b2586f3e916970479a0d836c5465c1345314d3dacbe5ee1 - 074d3a15e4bcf37051d9b1ad76ffbf5bc2826c2311e53caa05d22a7d0315f096 - 51be069f7903a00b3a1b38a632b00b2e26d3946d151c6a7413cdd7a12593ee70 - 6307d8dc0d822da33b7e335bc674d287f944fcfbb12af664ef889c9bf9e1175e - f4aa47736532b9a79c489e0130fb2f49456f189cdda60e480ff0cc8435537374 - e7619db6a06a6e2eabbbf861483003673f5998dd31c722a6c7d17c7e43d94acf - 311e726e12c51805db6837392abcd880b2c5ad035b04bfca7b16ba9b82212c7d - 6920b91da7c1e6eaca690756d9b0d403c67ab0f258067f1ae537ad794bb2f2ac - f1132d35e83bc8de5d542f100ea092c33499c5577617dd56399448c6e0719751 - f322e16abf3e792ed0014b49354e697f3d4d78b19431d92cbc97aa12bb9f339f - d4be05c666b3215e8450f4f27e5a1a705eaea74c312bfa7d76d4ab39d957fb33 - 1badfe1cda019460c5011897430e14ad9e8101a5b25fd3de752f47e97452f8d3 - 2170946b4c905f613953b6a7ea03b96d67b9bee3651bdf1a33f63d2d8bce2867 - 2e90ef39a066557e991c78201353aeaa47094542581506a5ab258f8cc7757738 - 9f3d8fc5c19f91b5e7ec60e88bd8c6665b649ac696341229cc1b2cc2224c5da2 - 7f2c57a53f5824aad8198d9cdefd13753ce10f8cc14f1b764b19d247e6872fd1 - 99624aaf8a3def3cbb72ae940868870cfb29edc1354532df028dd61414a107ea - 83e5a86aad58f52306ada8c12e6817a870696cbec7f5d4ac6a8c5cf63a0494b5 - b51617e04794cdd195a1dbaf105175d0219b97fb15efcd172cb3084dff951a69 - 0b2a0490f8641f245b03a67e4cd75783a8a668483789a3386899d888806633d7 - 023ce6b77ee7b4c011be72d52eba18cc5f87fc702c9bbcad61e829c78b8faa6c - c6882cfa49bc6ce98f8975bcd88c5c3213c422f20294b4bf960c79911744e18a - 1e54b91c78ab7de3f2f5bc69b20a68d7c76f9b0ac029355c523db8348e9bd854 - 5bc86e1005eb48819993dc2eb96712a71528cfcd69b38c44f668b2ae1e74d985 - 2303619ef5f54d927d41db399f7273a8d42c85fac74705880b50aee227dab2f4 - a2c96d9d6a0cd66ba0c062796c085b0d351b203421f0c1b4ef61330faa31c5ce - f1e91688a35b7c5feb455d467c275049ec330af627d90ac89c7696d9ba06a402 - 69c347eb6e9114d0f95f0b7a0e3058282988cb2c2cf33ac135d3b108670b8ca0 - 90e8a770cc1b522fcfd3a777e6efb2e658743a9e65f8dcf218828556626d87f4 - 00000007 - 8f421eba67cfd61a355895a87fae815f4531f5ad25dd1832a672321836cbf772 - 77099b27748d0dcbd08bbd4dd5bc67ff64d630c41bebbd7bf1072910745fcb42 - 867b9b5e07a6614df38dda0a0f4c89b393b27f42e0a850852a75e9f178e0ee70 - f490bdb5266af9db46a2ec1e0fcc6ccb609808cf460048df6a5e8c8fa864ecd8 - c87266261ad5e79c874731e2c00a9efc9649895f30ff4a46cc860ebdbeba90fd - c47cdd5e8bb67584f2758b25b032e1462caca6e1f026ecd855856765ebe87f04 - 4e749f257bb5defbfb826cbfc5de07baffa680e520ff8663b523f151bfb772c2 - a6297ab5a9977fb15367eb960050d4c23e42bfc89ac812c1e6cd9ec37668e37c - 1a594e0ce90de5cab6341b1e77ea447521645632912a0682fc60de7f7831d0ae - 72604756a4416573c0cf6a52e0868b857b76b1faa5bb7e3607a339dd32f33263 - 4b210e0e31da922ac6870ace1a068f3418588071996ff816b95a1a478488f82f - b54e27fd3f7037360b20e1b3e8674325253ffff578dbf8108927a966cf4163b0 - 40aa99d98df801f0e241c1607d9e8484c9755f6bbe299a6efe96ec0836e9d53c - 213db6d352863854781c78c4cac3083210f979d3f7884aca69fa83429c1542a5 - 51b8e95ffad4f89b506bd31ba613fe66a375434114dfbdf11741a8d86a239ded - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test06 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h20_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000008 - 00000003 - fe732f6abc16f3b1c0d1b78d9e72fbe118904abe9b33f2e03d0728ff4cf15b3c - ebea5149fe955d36f911e528d2aaff42"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000003 - 4da59d6dc70132d671114d7e3fafb184a898a603a60119dcb55148775618754f - e4d35a9594db68ab5003f967e968b97101307219d000d16dbc58bcc2285ddb23 - dd983189c34e7defa68a7682e26c50668bb20c6d1340fbb127d1d5b805454a66 - d2a7f43d2a579568bea4187ae180cd1038d80655454c5dcb9700821d55db70f3 - aea2d5f8e1b1b99cfaa86b253e13a72af3389d33bd51329171d666c260b71a66 - 7f1f7e4256906c0247ac361fd2cb11ab9f3d8d042bab28fd5df69f14a54f88f3 - 4339c81c02a0a9256292566ed753d2f4312d4103bf25f7b310a86f96301143f2 - 47c2291674797bd1088920eb5bdc049b8f9809c3c6d96ebfe49084d1021aadef - ec3ece50b4b42e4af022038c6b5363c2dc24522a2e641e352363d9149d68cac3 - 5bc3d973071e6b7aed2f4f96ca91aa22e162ab985baec0e56df59d3e8b37fe89 - 59c00aeab5f3713093105cf7db782fa45ea8ee2ec8feb56c529e6b42f18043f9 - 79d8c4c9d56a4255ec9747d31cc62a7bf70cd8777ffb75ee43dbb2c394e36525 - 71ce27770f6ea480e89f05ba3cdc633cc3ed269eb2ca0131268fc0579d738334 - 504b477e8fc2264c421e2e551b1a93713281858ba2cb588a2adcce4d11c2700e - 31d7ce6936b267ebe96b4f9bbc4763cccb4f245d371177c258c6d23c30bc5dca - 0f6d8fd8194b683f2ac4e0f3ddb7ba1cee1c47e5eec239f5a6b661aaafd2960a - 5d1b3305e53d9bbf8f6413368b7656723bcd47e7ab18b41d7e29b511767ba267 - e662ee59a004264ec2f88b8ab6fc778315ebc2a08144503455b8b2c1bb410eec - b767ee1eb779f9f2bca35184fa4ff7d8d36a41a9ed3a76fec7fd9a68f8bd35ec - 2dd1aa14e7ed9c41db03de868b266f8cfac7fcc887c78e1aa3e085cf0883eddb - 74d483dd177f9168ab14134a5e2272bca7e6e31185c34225e05de4545a99a4d2 - 949a75f970b862aa3b8c9218ac34ad1e3b70a64be25005fd248463606275b9d7 - 8d96725b39d8b9ba08acb91c3103c7e31f7970f937e176a34f4f4bc601dd8f5f - f83caff6c72b2e7bfeefd49c93cbc270cdd4d442be431b8e9b68e011975708a5 - 60095a8b784850a3c5bb3bdf2778a8aaca9064b6f1d424f4b41047efc7088639 - 73df9b861320e66779b25d134bd4528920b64c79c9eed64d5a01e39f8c2e1a62 - ad2e6e68bc5de644f5f28b09a9479abe5f96bc6d3e0d77763e3cf61feb31f152 - 98864c632b450d37a04e6aa4a2fc67406acda826ae98b7c52cc82da5da333ebf - 8b1c771dd994f6c650bf24cea6f25963fcf11a1aab7574b888dc89f92659fcb8 - 1aadd497eb6676243eb9f65e66ef97ab8da3fd9678c8166d1b2aeb724211f4c8 - 4e72749176f5d63798fbd16b0006dc8d92db7ee411a8ac90eead5a08f89a89bf - 295296b8d1d27e97d472cff51787b67a3d6d2a29b66e672647f395e21c9c83d6 - dbdda3d3608968288224494a815103549960155b1594d36580ca1db90c54b783 - f9e732fc2b14d58726a17bf5869a296985058318adccf6e56672e8dff8beddbc - dbb4bf30d2c59bcb8eedc0e713cd39ad9bb748e5abe75e05179a856c686d1c6c - 764f8422372d6f2dbe76f277a21c75c7f778a4056a1ff3bb9f0022d931612411 - 819c5a8a7b2e360c0ccaaa910e2af0d7ec87e9ba4cb90e85a18ebb8fafb4eec3 - 40ee8cfa4b9d9a92fbe07aafd07c58e06baeeb5c587279c2b2c344db5e43d5ae - 32547dc5f45bc855a9dfd6c8d3ff174d0fb999f4819e3b09ca53cb328689486b - e715f148dcbeea8f46ad00db30bfb087b8ad53ad6e1cb579ed51007289dc5b0f - 691188592e1beb23243ea4ab09771552fd03bafc9619dbba025764a5290a938b - 3c61ceb22c480a0985cc89a790e189b9e0022f772b30daaa218978208ff94c4d - 2f357f74fb93c961de0c97e95efa3a11dfe80caa3fd04051a717bdff5f5cd9ba - 36170cbb14defceac5ce20479b564e0d6a3b978a16cc48ede540212af06de08d - 300290cdeda5a9eb4c35f6b38cdd04a959370a929bb7c3372cd2a3130e1ae19f - adb54c2389079bd8c7f0249a2b53bf23687cec51b529411fea705fee52504ccb - fa64f7185c6f3601967d30a644a5fb4051517c8560b64009f6de5993c85516d9 - 2c81e47c076a679ce96435939352d67d11fd5bbc94e6e90881d70311cba88a55 - 83a7ec14f853f128da2377d14f95b947d00219638e712573223ff1aa2762d1f8 - f93d421e70dfd5ff040eb8f2f435d487e2d91d6d9cc0fe2d9066a01eef8a6c92 - d3a437a8ef5d8c8c5ea5be932d2f71b4d04ab3dacff9508e7dbbba3a01ea63ed - 4b7eb611e35e7d70f0e4ba82ab8a86719bb0e28fc9b3ad28bfa91f227a34b005 - 418ae4439814122d5e79336d63e1554e1137642a98e67654ee73031166c34726 - c4e78848a55ae01b1398338217771198db5973527a82ada98aefa954edf09f55 - 9f4896aa3b6117592599fd4301dd304d73ce8859509782bf60e8398ff311bcbe - c26cf13b8a6448f2aebd0ca29d06fca7ea09f559aff3a315b1ee70bff8038b06 - c381c9630896666c83d14b7bc3b07eb153efddc2b09568c0ea3260c26106d1d9 - 002ec640f4ed596991b51c20e9d4bb78de99588a33d0a64b20f8ffb2c18b250f - d5f7ed0a4a5e2a9ff94f62b8e84cb4e2ee898b85c11db384a26e9bddbd300128 - 2d886b7485166c7fc982be8c417f8fcd1a7fd98e529f2fe88a46f36d5091af16 - feb75ace51927a339c79cf79fb222b223e845126c73e4e8103fdd04786de373c - 9586d13460949c080ec557345dbb88ff1ca59701c889dfbb6492bb9086f05ccb - 330a2bff05ebba97a5358702a8d2aee46bf1d7fae1b934405d652a05e532b65d - d7ef2e6599af8683bfe4644ae2fbc77424f31bc422ab791de730e4718d080603 - 8dbb78b84c5df001047502acc3efe437cd46b8a0a7b4198d5598dbc343db47ad - 9c379d5147a5d4bb3c8b962a7368a7405a580f7daf312327141cb5681e198795 - 3ea2d2d95c7b9ecd6899428a8966203a9ce586357c631f7af27aaef3ea3a47bb - b8a81a7b83bde6f223b270576427c02f0fbb8e9232b2d70f9a0af16ec6544eaf - 00000008 - ff48f2d9fc8998f7cb6685a1d980003da426db35481323c56195cd5142148269 - 5b064c6f98dc3289b8244a5a7cfedf3c1c9a96ae48c79d6c9b59e713e91d90bb - a0212398645f8c55bbd03832e57397200b8127d6f38570e15297489040fbe0de - a21d372dfbe5098b1491d8efcfd2389e506039bd49fc976ae940b5e6bf3c394b - 189c63af6e799ed580f999ff02a16a5915f9b2ebee58ecde057345f4557e87b7 - 8828c700ec978f41e9b9ea78cf8dc961b0ac33c54d0f91a1d05b4910e981a050 - a2c319c8cf5470b427ab09159fb17e5393176683e6e0b3fcb11104e357d75d66 - 6b13356454c5bd0e70c18ccaa775ca568ae50d924c2ba2d74babff2fba05ed25 - 4d9e8dff7d8770738f2e666f8db461fbf0ba307cd638950692c65254b03d739f - 72ded6f48b6a9a37de6cb2f3c4498626586ceac37a2644e5fdf9b7794fa4b472 - 37bc4d45381e5bcf6852d15fd572e0062c8b1fc63a31312737f2347ea40b2117 - 03f23f5811b7ddbca4a3f19fccaf4860773bcfb872000845166c61243b05b033 - 4ce5faaac3ab1a7e950403b952e0b0ef4396e5f12abd08bb1354c28afb9bdbc3 - edb94b15aad3a85ba3444caa1019262ab6e04f343284bb5a21320440a95edb16 - d3317c875cf0187f0ed79b676ca45203c2d4a83233229f0861c58164b2b80b30 - 0c13ce8899b0ba1e470ead23836fefb921ab6a472beb63b655a1238a5b8f039b - f1c2916a44168e288d4c4aff2ec82c8189a7f7b70837e0a5756db0d38057c9d4 - 5927418b9fc50048b6ae0f16a9b3e3399d9b08b67c41c84bbc5f8bb9b23f08ca - cd742fa9e1225dc8e6cc32b86d6f57a3ac4b6d733a0655cfcc036c4b4c004a61 - 1efd58035b06ba03b4a701a68f5945cd90bd4d69d702fb43f0ff10a5879ab709 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test07 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h15_w4_h10_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000007 - 00000003 - c56e39882736881759e92ef7a37a1953322e3e9742a70e3f401e9bd35c973ace - e06d7f77bd11b4a6082bbf7a5429dd4b"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - c94b744512be0c92aa45ab245dcdb53513877236830106ce43f09a2a6fb083b4 - 53d15c7290b92cc2864d0780ae105d535de9f9651db43ea47f91a1334bc215e1 - eada1413a30a5917c0da8a5ae8256a0d40e98f33d6bca2d93579a44707a4cf0f - 6cab795d4e332685898ff004836490805f3b7eeb675c89b46f6d0d76467ffceb - 18f41176ce105214f4d57d1058aa1468cd1c2a894b62502b22ecf0b4f73f110b - 4b9726934786d58ad59b57ef1fea528421968ef136fd2ca7131c83ca9f03ece5 - a8c81765c769d79e8fa4093235c857d3e2864e2614be9535de95a09f60f2c033 - fe0125946b47bf09ecbc92123d486411c3c715f313b178818e00a81f02c8b7cf - 6c9f6babe65218f5caa8b0c38785fcc9dfe8c35b59077db5084c49f99fa7fccf - 5d3dca81c273f72a8f3e8777ffed035edcb9696f9a062a7befa59741abdd8952 - 1dc585d1f8b37141c6d07974d768ec338ba71f98581fddc7db7f6b11602f2bce - a4168f7959b621d7e298936a981e041092ebc13e944ee2150b91dee55a1f6724 - 66fc58e24d8d1844237dbf4ae6d5623001afffe971174541fdb7bdf8695d8afd - cc56ce99cd603ad02b700983e6b97b76b9d95715a57baaa5804dee2a02b88894 - 0260b58e99c05f05bb5b2280e242a40d1f443f3a37ad051dfcf3e1888107c067 - a67379ba8716e167b862fcde469ab62a4d84162f68d74a6631ab0a7c41ba7519 - 096b72110d7a9561eb8bed3d7a87b383a5085c99c54149b56d5d40c747ca28de - ffc08f627609600d2e8f40bd7104bc99a2ec73952b857eda20475530c1fb969a - c79c062c6a687bd2e008b8574260b822de26c9e7cbf32338348db43e4130026e - c2dcd20b79e4b1766762037af058cdd89a9bb2ee4148d09653f0366c7e0b018a - 2b72a195a6b1c422e5adc23fbca25968f7bb97e51e01a83b7d1e83b22a118b76 - ecc8acac709b3e5de5cfba07d8e81b2dcac4a476359b1541adb24c2e9fd68a38 - 32f2ae30b1db83470cb50a9f36777fb02b98f63818a078449de16c3108c0b724 - ce49b7f5f3beeee04ffdad3cd5cdd2e7955008d6e3123a42a46574a8237f2d54 - d54b3f8a6e01185287b167237ef736cef9881ed8478466124d72ac30a3caeb2a - 18fd68be71625289e05e076b7c290876dff1a95fab3503533be3ef0c5ad356c9 - df59630f3eb5fb6be37c61171243c0cf72ba2e2b83c4d84ef6ff9cac6b9790cf - 09eba6e0dc76664cf957c91b09b67f0e5c0f933d503c7a6a6be06f78019eaad0 - 302e68f499e87d84627a7443bf1e2a8a2673247b1dc6aff3ac940d5f0e3a3ad7 - c888cb961d8adc05a85cf2c9af4ac80eb0109b7ae822933ddbfbbbb36e05bf24 - c3538c645e22946197d21091192cc2ece6f866fa2c37ce1f4a9be52428d23913 - 3952f89286f88a7183ad17416360e0143d266f730cfdedd42437eb4baf9c3e7a - 1fe7a3e084c2ef4f50e2730ab9fe44c90b1d0167fbd1b6bde2f1457e2a7521be - 7bbd3bf2fc64dd111c185062afe4b90830747c68ad4ba890d691bd66d95fde6b - ff7b1b1c4d13c69d4beb23ba90309fa17633ac5c6d3c0571530ee61e48eb4e65 - b2482bca9bb230d3fbb6a6e83145a8c918059befc05143a5145ffd4fffb38114 - e4026f262038e7d24d5f9dab453899daea13fb4bb07f7c7fa875ff4b8c1600bf - d05be8a945f323243987db289a19bb29250a6a2d8d53c26e4cd5319324676f38 - a2adc2fbbedb324a5dd7ef804dfaaba33b4d7fbe17f134e1883400072d5f30ab - 86bbfdfdfacabc41b80749abb2271f903c71b383b5779aabb317db34ac01424c - 174cacff3dee16cf50e7ecb99d50afead31ab13363f49050463c25aea4d65235 - 0797d491ebace80bfd2074095f1ab5dceea9866a62c1e7e3c7683c3d7bb50272 - 741afac834a1e48ffe3e3dac6c168a33f40febfe4ede57637653c7731b4f5d81 - ac275de086acfb63133ae49b40cecf3e8a0333764957ecb1fbad30d80e0486d6 - 5a9727a590494ef7aae57f40bb0d75b05fc8a99d98b28f2294585234894c3f58 - a1064bb824afa73938feb5b96b279dfd3f9145ccd4a8339d2be01a62ea25efbe - b4bd970ba21c53d31fe66efba0450e8c5edf46c7116701b52954a11baf31727f - 7f845d9050a6a29759850af2d55d47be9646dfd6321af2677806335ecd6812e4 - a2ee84aff5aaea12478c36b822335db52a6cc0bac5b59c79f5d947fc526288d6 - 585abd23a071c6a98bcc6909cc3e45b15ee4244f19fb5e91b9c408870a37741f - bff097374f1da1ac712561ed5f908926f9c05748291de93690cc863d998640f0 - 963a92ec0b5246745477c83c600e52fd937d4a190d621a114c185a0a84b5ff3e - 782113864ccce2b9acf86100bf188d9a00de08bfc9b1fdfffcc1f2ba68420bbd - d6df840fb782a21cda9f051610663e8eb0d1e3e976886fbd98134101fabe1ba9 - 33b2546f1a468697d453d94716b157dc8dbab7052424b095d3dd7a19ed709da2 - 60d7ea9df24170f6feea4712c56f82158d1870b1380e7dc4313a4d419ece9ea1 - dfd7b3df4ede21f29e050156d5089bc0cff7e15c7983476e890b41f29a2bb373 - 26dd2da928dca53655602886fd1c4a9c8153cbe50652741ba398857e37ad2231 - 973c24653ab47e413ca95097a984e56f3fe7fcb3e8a7621d8cd710dcbf8faf0e - 2be05dd70a0e746a010fbabf8dc45963673f8e009cf146688852ff02eb1c00b0 - 5c4adc1ebe2dfcd31a15f37a4ee935bad87bda3e27df9724a7b1564b3f251602 - 50e722a50869d1cd39784b362bbee70c3a917f18bf92b77a5322e8b5c1a7d101 - 77fb7a50f3d1b10669d570f7cfd4d5ca1401a4da432d4f68137986c456507611 - a050b0ae0b7b8ea295bf78ba9b8b3acceb14aafc82385928ee544ee068171a2a - 34a7e2e5b37a19a70c0251910c0966cc6b8a689cd6fc8a00f73959388624f9af - ee57d316054eb23ff1aa63879e13519f416a8449942da592e727073bdccbfc72 - 52baf02a65ec66bb9504199a147a3616ec20e7c57ab6a4f4c7def3eee13dfe48 - 06372b85bf3d32cb6b3407a59af02c5549f29a76c73f43566b868e5f1092bfc9 - 00000007 - a22f82a1ca76d4b8fce179e98c2b8f53fc36a1be0c8ecc5ac22a6c65b02101e1 - 0da5ee071fa5a641198ad237ddc7b03f50612080ff3867ce11df78150d06c9be - 35bd7d0befbf473bae9f2f8e077e9358e8bf2b4ca45c7a6af889f56564a22470 - 43b4b86db63819c4f9d024e3e09b96e731e315d10c3db8312e9bd33d477c318b - 3a5f886dc3d8595363de2e2d4053aef8b722f7fe4e092c1c9de6942c6597babb - 91ba0b88467321a8762daed53a5e31bd91a76085d559718fa3368aca9c5defbb - 6402193da3e293fd7d5df6c0d0b36e4696dbb0e6683dab1e29740b2625faf976 - a86910e194b46ca4857c3a1fa37b2a932ee300fd69ff2987fdb6e8ec7fb0a57e - f50448510f72818c87f0a51be0796e20d9fabb66244ec5e99d6fa786b7524992 - bed245b61066371a4d0b3b91b64ec0e4e4912b5064f4e73a684de396f73b9531 - 397506e10da845520a724a419003445e4b3a02ecd83a5fbfa392725054acc609 - b9d66d83ca4981ab5a826ac0c675706a0db4ea4f4ad55b3c3a9cad8ebdabcbb0 - c1526eeb2f678c0782ff98858241abd90104f0a89767cbfbc8584062ec2f7fd3 - ac911a09b2188c85a46b71ed13f71c740cb8f78513476f33b7157b49422e2710 - e4ea2efd66b147f1e94f512d5bf7ec40fbf020094c03626fc71053c6984d8b15 - 00000006 - 00000003 - 6002a704915e03814410e7c4a86744b6269cc17650b33496e73414170f642ad0 - a5a308f58beacc5b39af6b988b906c8f - 00000000 - 00000003 - 4958d1fa4dce4ace05d93d530b008131b8c01191cb9c6248842e503676f89c91 - 12431e2d9276492e1dd36fbdcbdced7dac7a4d86fc64cd8a1f6761d6072eb0fd - a335e5a374b7139a62537af2d20747b199f32b97aa98b7ed722e651b4ea2e8b1 - 6741525a4adf245446407ef3a0f8da6a374245bc5796fffad397d33ac887ef8a - f1eef9ef53f9bf5ad79d0ca617c69bf8d5687551779762530a71c15a1a833cce - ba629d85f03eb30b065fcf401282632e97cb505e41993ea121aabb93c5f5188a - ae98a85213bfa98bdbe14d2b53fdbc4c00b1826ff9b34ce84293eee25a440622 - 677e290239095d199a3776d2208ff1dbe2382657e83d1e29f8da4cad0dc2fefe - 2d17350229b945718f71d17c646c881229a4fa47e2dcf7485e9096b47c24ee1c - 4f051855cd19d787be09ea221bf827f6c2e648435f4d66d2028a011e8536dfc2 - 66fe9bc6c4d342b95a692567291e6e2ddff81179eeec69fc135983fb550569c0 - 4d90c040c2a3ecf2b81a55f5368ac0a7a3d9c2bfdb8aa13568c3147f56b0a504 - 84c4a00b2b1c795e784498d4bd1951eb5733cab4a7b6103a4823f2a94f890c62 - dc83c57ac233902bda5440eaea0aa553e0528458b39e8b58ef98e157c95a723f - 7c074b5e3c4b2d2c15ded5582d2774c71173be7f7ecbdc659d8d5a132e39f64f - 4ae6a81fd550d8dcf7a1e695bc985d059892567fc502399123ee3f1131d113f2 - bdcbe027fbf6ef0738f78762982ab379547eee6b4276635d1961b7cfbf1bf6f2 - e9c9512fb4699468d882b382bfe6c479878824a52fd5bc0ffbc5cd857d1b96c4 - 18ef6c59e799b93f14bfe5b769ee28aeee86ff5caae4e7cf19491a00f084b818 - dd61b0f97675c85077bee6ce5a44d9a47603491ba1d5e690f311037d7319bcd5 - 74542337ed91eb7d65a01987d32f17b08d62c9b2cd326fff38e3a6e280c31255 - 950b7911c262a17193bc9fbe9c43da2a3b69e61a5f09d67f667f64a12e91ab8b - baf00cd7647b9fa8ab76057e5c2dbcb347c26ba18b03c25af8f1bfe18491f962 - b537cf3b24078dd8f45a2b3f707657592872d4c3c050bbb69dddc885399e068c - c4d13709c8533f650e48780663b28218bc4e81ac3265b505f4d4ed6c8edf10cc - c9db22b1f92029727cde22f4cade608fcc64372da7367886290828c478ab588b - 4473c2e9bfb975368fe6b53b71953eedc62980b60f3da18acbbd292b723d673b - 217d17366586344be60802ae9b4bd945c27e196317f9b8aa91299863a6dd336c - 9a321b7445934edcfaf6dc7f107a06ec6aacf3c4e7e04d83a938741912a9a34d - 6d6cc6598ad635c8299b4c5adb149f935f39a1cae255a8116e544306330ce49e - 6a46452ce0420c655ecaf659b8723780c9d2a7946f9b7781ca0ae983dc68c0cc - afbaad6792d3b31b728668d91de0a7927780c78406521bcd483d3614d20a4265 - 62c6435a924b998e3824351706be646e2d530a2389f6c09a2d8c443611e7c092 - 330b56ef2672ad807f1ea8e249b0a15a57881048f91b00c4fb374201f8b92259 - 739e521e10604eb307d3638090c0a4e4eefcda271a5387cebe0fd48d9a146232 - 37b9380e40ef1108f00a980c4cf9abc88b3edbc7826c48508e02069ab34578f9 - db6bc3196dc806e0b1659577ff34d138e53cf784dfd03e3d8289b0d8fa9ab004 - dc35ead8fc1433b8c2b1265241f17d9629829c658513051ad7feea28e1d72a34 - 05a2571a4af94b7ec6ab2ac4cbc810077aeed2237831eb42e303511a3b79475a - 9f9284f00b3baaed51ee50f3ec7af02effd2dcaf7abcb9e4bdd639c28293c8f0 - 63d35b3f3934df46eb853a2b8f9e1e8e39abd9f22a7992325b9965ccc14e7910 - 829b503007fe5a521c03ffb48f154d908a7f145988de3d35da8710e8b42cf0b3 - c9197a9d250dcb5ab5ac724e0eddca2f1e92baa61c2f2862087794fb6aadd837 - 229c58b673f4a682b6f16178a8bffc71e696a29f9116cb896dfd05780afce77d - cba573170724b067964901112baa343346d2c82e705b842e8be9e5b56577015b - f86f9b27be99ae333bff689d93c7e4ba77be967cf8e6328284c76a2e1a3920a5 - 515bdc7e5b65e6041aca2268ce13c17195274cb0461611421521e79a2d53af61 - 1728b35b71db1b6424b6382aaceee899b495fbef4184911ed1877a3b17be2276 - 571a2347d613ceee0c9de7e0d2f0bb5e18a63ef05f424b1ed1353409f926f84b - 4ebafa712f5ce1d36de03c6c90559a60f80e2b4915fa57d08222f6735a6201c9 - 4931dc8a50f88b537031855c3824f617334f9ca13a9603ac1038d2cde3dab425 - e5a3ff1a7fb7a7c25b315187f202eb5311d078cb2e2ffcb1a509cedee7c372b9 - c06c6cee6b66b6bae7bcb158e4a74769805a88f5c9cb7c581e12e1d05ece3865 - 4b5261501fe414ba395f446a846bf736e1eba29fb30fe80ee174677eaab90e1d - eee16dec7a31c23865a38ee8c052a757abb91b104d1b5e0150e535b1c4669e7c - c6b23f57a8dfed44b3f853049596b7f149e5d21be66ae72df95d1e969b054cc8 - 49f2bc06a1d6bc5565bde1093648ad2581d691cad46237bb920deeb5facabe8e - 52e1e02d07903a17332198526a9214b6d4d4bac9f13994f6ae01ee74e673aefa - 5aa33ec67c4e0fec44bbd163fc6c317c0db4ce0de479115cd2a9474c7b222a81 - 23cb5c784e3579ee3805c8a606d2c5d113fcd12bd83d03a9d72c8f72d6c577d9 - c891542cd3f3e59abaafdd2b0e9195f57e9c826039647506f0fdda125a1403f3 - f007d6db2555125c33de5b3a90ac9cd8485e48bf1db995708b697b5b47741108 - 1b83dc7bdfdd8aa5a3506cf5a828c0e9803320af6a8b8949edf8fcbe65226beb - aa2930c5502dc34b4ea9588ecf3e69edf41ec734be808b3e39c85a54a7eb5ce4 - 33994c40209f02eef0e43adb560bdb26a969216b521812c6364bb336d004c56f - 91bc928887ae8deae2ea6bde44ddd39135222698c491759ff20dfb6d7686c284 - 2ffd232c9544e3c39d37e9ce8bac185d58802050284a5fe653aa64e16c9b1777 - d011e2ab479a85d33e041423e6a50e5dae059eca94b6c99015e4b65047ae8c6d - 00000006 - d67b98d51d77fd23841bef1a34fd81e4c561c4f085b02c791553ed46c7644b51 - b6b97076d18c3ff64891f63784cd38c9fd1580656d4ed635023f4fca45bd49ad - 7958c3201c2233d8e1444a58b1f03221603f1c3b59b72eeac085fdccb79e07b8 - 37451bf427cb58ac9234253ac0c56906b0540fe5bdf35b47b73f04f56b22c8b2 - 1ff441f59983c2763a021e6d8f0ee5b73a16ef63d89168563b086698507fa56c - ddd5d64bb968b0763191da92171580f9c404720254cad5c7d6900a4997fb0570 - bb9fcd4d249803c3ba2b3e5758cee761ba4c2df21f20ee2d36a547a0cfb216fc - efcf58231cb7d6112ac2583fc1e52f3062c1cb8b14df921eb4b702eb703082db - 7ffe104cd0be40b96a04048def98caffea64e25ecfdd3566d3775200c5eb9182 - e9a45d41023db850048e05f200a4e7ed2e0b48c532e10c1628503d5b7f394cde - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test08 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h15_w4_h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000007 - 00000003 - 31b6c6a3b78feaefaf459a33e2acfa66a208240984abbe18996896c0eda7b999 - 9d9786e59e41179854928ed5c5726bfb"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - a3e30c30ffb7b27a99e1e53b030fbbe5f901b7fc38b059190b9ccb9612503d10 - d0b0266063d5e234c985b0278428e147ca9686e3540e6d51964e27d0334c0043 - 3564dc02fe8b1f911667561445bc9e61773d4ea4fb7b5c8e637ce482cfbb69e1 - 15e118eb5dd28ad2db03ad6618af5a0a919aefafb46d8ae5ca011274032445c9 - 7a49502e49064fb41fe28aa76c103f0d98edac1d71f51010d7e89d04028394a6 - 87c98d1ba0b07470add461bdbc5dc553cb7225bc12d6925319253f50e8b8b1ad - 1d5ea6304ce5e69150b0b2953e38ba7bf75b5900e1b4e84e81d1ba177c7dad91 - 956511d74a5b79c22aba2b821ec31021244fc4ceed9b1d992382e7f2e188eb68 - 841b09301ead899c0857194939576e830cab8fede0f14eace0755d56d144eebf - 1eaf5f228f3c3a915de564ffd8c50b7a0e95834eba10737082d38f1c459f2a5b - 6479b129f77f57306bc9888a469ea7a7f69be2f4784c472d90b3a84c8a10789e - 5984c01ca390681ef94b483be22c2559222a3c8505055fdfcf3c1d5dbc22f342 - 8d07178cb2736d930313812c30cb9fed3c083e3319208ed600d449df46106898 - 1f7b3201a9f1760f388aff82eeea616ff89301ed98de1fc9d3a820c7b3e8d5e7 - e7a97f3eb819f4f5a08ef7e435d9df748d631539205204f269000d423bf195f8 - 02091fc8f25e186da3ac3b63f7fcdf832c9a8b849a3efc207dbc39b7d6e67184 - 4efa7ea995aba735be8d69ea2a7fa954f23d9cd548aae96068e4cca1e53f5fca - 2940cf78a43865ff1ef52ac1ed6c347a38b217537ebb6052a094ab8a7d5d67ca - 0ea8e46f10be7f07e4f5859f6f940c308aa156268a2378e36b6f642cda1a0e31 - dc3eac909426d8e9ad55ee21971c60f58571877e3c9e41bfec8c50c5775fb8da - bc78c18abf1e9c3c9d6a1fdcbc42bb613e5019d95cbd12bbc820df6304240a7a - 0aae87df42881ab1e5df3906453ff32acc16a3bd5c01c4bfbe28240a05621899 - 104994f21e87431596a2c43a336be790cc095ab7fea51a5f957caf3f221dd875 - 59bad735356ed5364fd9f034ae53c1ae7b7a3672a5d7bc0974650923dca467c3 - 0f826ae5bfaacfc381469b93825cde82e5f631936bfed860a786d35f29ee326b - 18e215c6e01630e811683da0d8d7b9fc24131da9de35a36d5e541896b79bbbe0 - eb15ade43e39134013b0de86731d17e7ec7c7cc1cb46d925c211e23f427ddc10 - a0d25b18c397a83b3be64eadf9106d5ca75286f599059b2cb0c3cfc892ae5e88 - 6fb873326634a5231f555a4dabed9fd3370706c6e4af23e5736f5449883d446a - 593bbd6f36749f5a71a49175ba562855635511fe9005ab1fdbaa224f55b95a03 - cd08a215b8cb400a02896138900273216402241caff7398067b0f6c18edff0b3 - 3b5e1350ee6157b2d79065ca0beb45feaa67795a821d783d3c566a0a130cd310 - ddad078aaa83a319ee6ffba73799bbe3f14a406be25b3f989c316256ae0120ef - bf3593dcbfde8d1f1dce1fbb1cb1c6c8258623112a05b70389b1e801e17fb17e - f10544099ac788eb4cf045ed1fdb9e5e957d7fd930bd927f4c15c253b145f848 - dd1ac985fee170307f56d34dae9926d67d1f97fa014fa3ad57c10d76d27dfcc0 - 0a088a043021d5b053b6d69e912d3cb85b7c2cc029ecec40089333c7c9ec45b4 - f9c3ec3720df8fb592f5c71d7dc230f90439ec1ae12643a8f4a30dc96e798cba - 269bcd463116dd9657c89c569b519cd061816150e8c39ec3e798574610cd13da - 83b52042a890b37d10797ad80f74928a96b697bc810867a4e0e96e98585bf386 - d0df41627d76af70436258dd3ed1ae49554d8dc5a2c7e54d477af70e2a407747 - 227fdd0bc0b5a9019c4df9fe95dcd8ea6251ef1bac071771d364fd428c3db3cf - cb4eb26b7908ed96d30eceffbe634c0184e8cc2b807376d7d5fd9f4d9579f148 - 8f085df80f032c6c382a48dc80b07bdeca6085aa59f97abc666c1a73d4aeee34 - a35e3569ac357a84fa1a9fcd84af37b388dae14e03be6b5e088891060bd69e5f - 419fd7d2ae50eb97bfb24c7dbd602de5db1f05c84f1f47fc7c6d40c0fa4c95d0 - 464a18d0b6338ce123b46188492df786abd9075a535a38de4b42d8d8bd6691d8 - fa9dcd8af407d5f20a59cb959802735c2149c18a067367ab9e457e93e569ec1c - 42741ac055420fd531dda33faa9f179e272faa5b32c1e6d3029b55e21140f4f0 - 104a89760e5e038c07a770bc85726fc57159089cc3a2ca2b8a14e9f040b41e30 - 3e2c57f64dd7579eb094e8deb536a45bfc2840428617117a1b2ae8259764e860 - efc03fadfca03511a370256420fbda932a5ab58c98d0df2a9aabeaa7d886ccd1 - 59281e77e7a1c70094722ec788212885674e90a3134c2471c399bef65cece979 - 0ef61cf83201cc137a09115b0fa06ebed4de9104974f80fe00b54367ab267483 - 35e0f8fc02d52e4c556ab748a98aa161d4c9cb712c88155b0177699f5fc4d037 - 02560279c2be7db70603f03c0c2ccac7437597c79da01ef70d84ae5ab2e0ecc5 - b77e9f6a4c412569589d97bfda88efdffb626dafd24408eb79919cf48a619744 - fe4c42f3c49ec4c1f94ec8e79366f036aa1366ad559553d102efb9b3a913bb06 - feca31ab71949e4aff7fe00be4bfa36e7d6dedfd349c0bd0d8a895b7f8fc55eb - 09933f061f0c4a756caea8790d134c58cd1469ce78edd16be26e0208d449556f - b02f343493fafaf615585320902dc4c606d3ae2fd4df7619817b49d47a672121 - c18da014aa89309814f49d2259540aa4897cccade9eb94351950a21ef3aab45b - 90caa42e3e41f39e1da7b341cacca50a8978f1dab0a54becc79c9501c9ad7c06 - db29ca593441ea36ce2d48aa5ab2455efdd70e558ad9f208c2f26ce7c716ef96 - 44a12f904f4cecae04cb68a433db2d3aefc192009355e6f67f7b565c746c42d7 - ed6645ca837351fcc9534c66451e8e1fbc327999423aefe4f5f620c8e15000d3 - 2c621ba53d572da4d4871d36173e83b1550cfa40a3a8fd7248d351a703389122 - a4b070ee87b44ec6543adea6921c567be95a8034a06a00c3fc102b8d2fa4e6b8 - 00000007 - c792abc23c442a9822041aa5889816e9e127ab2323bdf2636cc672b47d055dac - 698074f11a96c53449a1ee30e1bc27fc8be61d85f4e5738725457d4cda5f7d62 - fc2e949005146d26590fd090a3c50e4141c63b8cfb14087affe86e9ad5207b4e - dedd578be3e0a969d10fcafd1ddb134093d026a9055615e07ec4419786a82aef - 0afd2ee68e706169d7688ecfa37c8533d9f7af2bbb02adf614c680db745af017 - 1676255f9e319f00501c43e4787e8349c9b04bf6bb3e7763fe6e40d6c21e6ec4 - d4611c5480aa2f8ef0f6ce3208748b966eb5d1c5945c54f8421ea3c2bf7602ce - c1dbfc1c8408f84cbc3a2b7932764baf9c45e60404f60736cdcb8bd3397398b9 - c0e64e4555efd2c94f04a87ae037fd685591599d5c0b1a7197b6886df17c5225 - 5ad8fec5950668c3dedefbe53ce5ede382633962be26da09260ee48b5d8ba67f - 900b54dda5630094a9fa85ae4217faf60801fd315f1f0dd58d30190fee4ef279 - 51fc2c5633cb46f70e9ee9678e27ac8482a2e48415b14e5d1d3bfa6a86d5b972 - 93f2d0a32d0c567002b03df6cc7a4c36129ecd04f9cdbc53cee787a344f305a7 - b1e61609f7df2745c75a88e07f071d1e93c868409b67afb114cdd539562046fb - 7d85f590ebe6969684eeaf7b42547139b50d64400bfe76c687658bf7195c9791 - 00000007 - 00000003 - 052aa96293117df09356c119dd4b9edfe3d7c53d62d9855912682d1c502d64f2 - 3b298883ffe67153ae1a23d0c6ca41bb - 00000000 - 00000003 - 9058ddc450f6e1e7b9ddf5fc65edb6c55d60cfaa3b3b1e62fd53d7286903b9c0 - 63656485ed67b07407c84e1c4a34841d6e88aa0d6a22b262da4265063f3a84c6 - fabdc96e1c523d68043290d7d689e7bbd572880f0fb2a1fc2d247c622faad758 - ccf2f8751b983a86c29d721002f14050150227e594ab05b2f6ef605140511290 - dc213ca6db06bed09f33baaad9a0eb840c7b510bab2a31f7bc039f944b5b40a8 - 1f047eb423d306a8a190dc1023c6433f39edfe68f2a11357e70356703d15a46d - 6df90861e10f84cbffb6efd1b3917e38f6baa2602f4a3d1b4bcf6ff6fc61e22b - edccb0831a655474d5d701fce378142a307819d5a1e8156d655276f1f0b7d9f6 - a250c938935f86a2f12410cd5756526d70bfb17e0f90fb440e3e8c760b693ce0 - 5c5cf7af31049ea0144f6ccfa9a2ca892df28504391c3f1e7fa053fdd29c9767 - 94ee174f23267131aa62d5346150d9f5ed14867d86b55643ba6ff94b8065a85b - a33499a09fc620e81a57a5d059e37458801464aa461f07ecb15cbd0239272919 - aaecec880c2f5bcc5c73af198324d06d9ec48d8a75a0d7aae6fa704bee98eb62 - 77204af01e13cd80bb8ca5f243c67b02d2eb535041b0b41713c155fc5d5d2ea3 - 61f27770cf31264a034989896edab335be1ec9b2c5df0106093162af112d1d7a - 9913a2edcb1c2fdf732b25c003ebd9df617cc5fc47d8413c2b3b34dd542a217c - 32e4aa7a283809f8011dcf59b639e4ca7baeb9b408a100188bd719446c77964d - 4865d6b138e9ef1c76d13145218c7de1827ef3599f8c9883ffc2d2412e48ef13 - 4ef821e1d426748803ddcf325df9b49cd61257f2b2d3fe2bdc960b5140f5ddb6 - 4696063fcaa699de790947a4ddbc8fdabd46f45d2640a07b434e304d00fa8310 - 8667fddc1e04a671548ba468ab83dcc897ffc4b776d1694618ab131118cb7830 - ec1cf9e432d8f04cf48d8485d58c51b18d5a0bd795588bbcdf65a583f7615e32 - 4d4a76cd5bfbfec3a0c37c97f9b5b1c5d8795e3149fb11096ab600cd9f77ab37 - 0fd5970b641fefcf83870fea3d7deb9a4b0d4cc53a9d28330c07802d52635ad4 - 3cb76a04b6fc09a7129da5a3d617935d144ca865c4a958d4592dd9dff080a696 - b2c7301fd3d2974df382562eaab239df41289c7a2b9b55264a879b322d693acb - 52c38d9a31559fae7592bc29b1a83e35caef47d793fdab943ff2e3f98a898c80 - 73ef087f8d4419f1aebd705d2e0ae8fd137f7a46912c6a0ab7cf33f76d523cf4 - d27e5c2a22783974134846d923d8d966041d88f113451b439db3af3c90747739 - aba2de8ee7e1a7f1f84c6826cd405404c838eb387cba680b5c8f62ce8376c23d - d7bf26386855df8f8d554445987bbee37597171f7849590db96281fba0cd9055 - 92980b85e0f29f57cc6536e2172695607dee4f53fab7b123a34a97e12182e13c - 623f3ac68807718ec5d7806072dcbbf087e6f1e5b834cbbf7d8e85c3021213ae - 4100af501e8f77f57fd68c7b339fd649357b396a45eb2826fe06373928cbfe51 - f1de9fae833492e42f82d01ea9da9f4074ff22f5b59760d776241c73ebb0f05d - 6856dc9e07a2af219e38998afa04ac953dbeb0672b13277bca76ab02566d3f42 - 2c6763dac87898373b69a1fddd92ef198f52388644be117fd8192b592325039f - aac41b147a73162a5e297f82e09604eab0e06866450f8cebdffa2ff475e83daf - e5eb9296626a895518872a97608ffe04f454a9e0098add3bf581f53490a1e2da - 324ee87fd47b7ed7551c0f222f475a57fd041b6e626979434d119525da68fbbc - 1e23d8affef88ad8542bd99f981c29435a3a7f3b40ad86426c6bf0a0948a15f7 - d8dcf09f4d083cc3c3ac77191afea39e3852f2b679bf2b3028a551e91bb41272 - bf59c1bd443dd6c71ead77700dfcdc2a9c686859b12ecfc1f75cddef50ed5eec - fff75007bb26c09b836c32950104dd417ac60622bc57df8e55815204a75d9c79 - c13cb605dbc321cfbacdcdebb24ed3fbcde6d7d5b667262a89346598d9f2d9c1 - 6e6f6886a55caf87221dc27a911cf4c389503d7715b1a791bdc17ba5bffe862d - 138b52768c1608f356dd8c88d5b28903a2295891fa139e4cfb16dd22ac8a755b - d496864c95288aa4197ceaa54112e60ae999a8aeca4bef48602298b906c673bd - 93bb62da2d0cc7dd0951d304fb878513d2ed70ae39d1f56bb2c665281551ab74 - 0c1976060bb67bd898868a2c245747a58ea6c1e71eeca9d1e196024b8df0314a - 96c278e9387e817caafd11c0cbd517b7cd3b1f1ca9c38a5741b7a46cbe180a9a - deca3d975759eeb165354ca2ac5aa5bbd15841673f5aa25313009e570dc1e70f - 58d5d5eea6b10c36f0d5d09fd02021ab10bad7ea9dbd04ed909c7f1b6632eb03 - 827d67ee609b96079824394bcb3e8f99d7ad77e27c5970fdf56f33097cd38c11 - 1a095a7cf2ed76014b32a5a73e6a4bbfd86755d2b6e403671fe65ee3fbdf5c30 - 3b261e3bc613468a46a8c04fb761fcf8b262b142ee4fdcee6a1a8c7baa76f442 - 2880206b06d406ca77dbf75bf5c0885405e9446e6d0cc8251c11b2a9bf12900d - a45b2515e240afa6d6091cc0618125839efd0e0cf55368b10f9ca04d9e18830a - c0992ca32b1923c1b950215e3eadae1e3fd102f64cb7edf371fdf743ed553048 - 7e7cc35827d94b7a2462fcdcc7e6eeacbf3626498d66ea1e7d98118431c7b823 - 5ff390bc68d3063cd42bb63daf5db50edecfb9ce8a83cc5565f1d3ea2d843df8 - b899deca8a36e07b79a38be4c064af92b908658743c2808b94f8113490163669 - 4b50d40b246e3f87930684ebfa0feee96a150e74d3e9150619ffa8c12db5d951 - 2e55dbd4dc21e09d0262a3b4c9ebe995ca12941e0bc32091891c68614df8ef12 - bf34b0441c2204694236631cf4b1992daf2f4511f9f3adc29858dbe1100bfa09 - 1a8343cf5987fd8175ede1a11e6a5e419d48d1fc834cb83e71e2d2b16a4d724b - 0768682f72e83797757e92a04fe738db302cc39622b33ff37a6f3f39503bf229 - 51af13e28a4f1210f8b88c5279464dcfbfcfb8c2cff3d2ff11321b7f5f1e188c - 00000007 - ba78a4b874ece30e24b271f4f1a44db792a841a7405e270accf650a793961fd2 - 09499109aa03394808cab26bf07cb44a856b76a52384c2c8cccf3e343a724d4c - 203d131c29a5060c9d518b60ecc1754c52c7abf223683192a40a6831bed6dff0 - 80a26b30e52b268c8a9184857153af60266b0eb40b0bc255d0e96649c63ec359 - 6686c1f11ac84488c6ba20f76649b257b6a3bc60d24d6cece4f8396716455dbd - 9b9df1ad3ddcd6db59e41d67d52d6648b5da92929d61a17e5b8c9b46246c5101 - ef8f4e1b64c8fd471deab9356fb1f5679ae5ac71059a1d54f7a1d72705128c50 - b45902f8da6e82e2851bbcd51d8dbb8f824a222596648dffbd61a1d6c95f9885 - 68500d1d3b084594e0a5c3f3150ed15c4ddf484f45f1a615d63be1d7aebca110 - e80efb7a86132d6a57d296343d7c784f50859c9072fdd30c08d71bff9667caab - 65b044ecf87e90d7943acb7b5f26a26562ebb6b0a2aa31514c096125ea73c2a5 - d17cb68392d92e6c1ac7805a57466a3738256bf8de6cb3c5ee944f45bd4f1d6a - d9977f46826deab2abf93378819376fdc7b61cf344d2265b9f8cd22a1632f738 - 244569171a23d6d593bd19634758b7ff9c8731720e771023fdb0a6241dda4f61 - a4385d3b9c5b6f6bb018324528aff429eca9c1264de9ea434a1a90e07f69015e - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test09 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h20_w4_h10_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000008 - 00000003 - 4f9fbdfc21ece22a13965cd32027f6d4e5706e751440d214da485f202309a24c - f90dafc3d8f09f797b1b6cfa3636e18c"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - 7d5dda179d7f33bd79840ecd9c46c0274f93453448b4b3c8eee74440b900b7e9 - 9da9eaa94691fda7716fdf2354ad1858df27d29b79c91cf30423c32d5e093b71 - b0a141ae160487d8a4451622b5ff1488167cbbf342a876d53671eb0272c6d1b2 - ab8d8fe4b51d50ecaa977f379903c9dab520df31beba6f6dd2a310b8514d7a3e - c78e2fd0a33369da3d5e8fde5a3df3669474ada32db4854eeddccb9daa82270c - 9f1f9d7d0f45d6b59db36355ccdfff8a08ce7c16cc5c15066b86fa955c7036fd - 5706b8560fd06fc1612fbd2aa9866eb40d962bd12585885321fef67dd80c3efc - c0a9f620276038b0850e9598729efcec780d56a67f98d1392426308adfb4d8fb - e4128ad38aad50060186b40fd63eae216d8761ad4b66600f90ad39dbac2c4771 - 6986754a8c505c0d33906b8a66ca740f68edf3ea55c9e0df72e7f5f1c3b6fdd3 - 67d8b0205a880a3ac1c9d2a9e48616753a0b9b34d63a8ee4b7f908cbd0a8eebd - a55823c0abeb1911d369ec16414ff39a2d1068ae1331af1eceb6ffdebd3bbc6e - e9ce74dbad7e6fcb362d111a9992b875d4f993a413348d91d7f217c0239b52f6 - 0140cf51777848ddd04fd1b481033b9ebcd8e4b129db0bb801d99d05ac2490e8 - 1f858d6f35ff29abd35c40fb650f97a0b32061aa7983822868119dca5c2c78cf - a4f76d26ba91a56bff8c6e500fa35aaf89cce3ca8dc5c9de98a89981cd9283ba - ceaef88dfd5a177d2c71fc7c1131c6ce74be3a2a7a673acaa731482cc4bd4dd5 - 8f0de26586c2a8863bd96d505821b7e78f88a0560860d022961e6d0ed3cbe9d1 - 22dd27f77208ad85d12dc33ad819e394841ff0055ce1649b20cd00af1942c76d - 14cb6b645d459caa7707f081f47b7a327b3596ab1e3af5b741e503f4888f5261 - 83d0607e274c4b544e72417aa98326de9bbf51b035bc70e75211b084a947119d - d7929a16d43cba2663a8d2ff8934ac0ee157f01c13fad772bdf15c52bc1cfed0 - 24aad7e06e3fb72f7ba7bd03860b804ebbf3a78b40cfdc46c147a393d8f88ed3 - f921398995697a51b5e3cd8a3b363d03f60f531e3f2d7a8205bdaa4e652f8dfa - 42a17bf406580fc7d2240314bc3632850352a9212fbb56e2c4055634ddf76f30 - 3c9818d2e806b3474587c3dd95d871b7b7b9987108d837efdbafc10735285f3f - 3613cffa7ed61e402e08cae00dd43aae21cb70c03cf1fd0313c365075a2927df - a2af481b3026b81aaba7652b8c27a1bf64df4b079ddabc4e142678e86021cfe8 - 35347ad78e3877a35bfa9da1325935bfd8ee76437c95e95a9199db1949a1d034 - 2ad2e61b7459e9cc67832093240540d8c1c69af238f5ff9ac49829c5a06db24c - a0cea539f2c58a52e256f404bf0123d03979c32da4b35847f01b253105d71a87 - 86972babf78052003d2f1183c5bb1f986de6b443ad2b8674a8a88cc6dd1c658d - 4efa74da693e5194a7c8eb68a7ea8313e7d42ace9ab5f15e2c536eb4c0da7579 - 5e50ff72b351c773c603cb749d6410608fe64e191715276fb36a97ee81720d98 - 06209e53f728bb3be9021a5ac2aa157616b6c9f4f587916732cd682359c8b616 - 84d3f0ad309c03a3d168f3927601544c622b99a3ddf5291e2500126278122794 - 5dd8244314b972e0e6c303089055a449aceeaad870a1171b3a93fb329cd777a8 - 9768b54671a3e87c9861d2c4fbd68971da747e0e12a70211574f5cbd8c98df42 - c7439886d089c3515f30ff5c5fb9e1e5a7f0d901ef76a8b5b290e0236caea5b1 - bef9f583c7d7b07bf793fabf560ebda31d56a19707fec2a476842dc8171faf3e - b572452a092de32ce195160efe384e7f5c6c5ccfd3201dc34d33fed0fa0fad24 - e13053dea01c5ef210e1d5c2d77a94a6acc3fc7d2bb7ead6ef69c5877c1d1587 - 931fef54754681e96904f5c24050b8d7617843674f4b652bbbcd19860da98aac - c1e00d9c6cdf4a209c8b530b243b7b8f1646b55f9c4b0a35b0133c67eb16b7c9 - 05834f2e392299ca1c61863c89e333f4530c25c7765379b69fe8ef30a644e746 - f09ad8a6090c2548e9294c1ea78695b90639e20de1fb47d3f378689254780b7d - cd4bd7dbc66b62976a5e5df5fe72eda740fd4e38382283f1b335ed72000f8e30 - c0de5eb9256808cc5082611a10395710c17861bb7513e52ceb23d005bfb419da - 440025643128f9d074351a7ac35e92e9d9eb1520eecc78fd7a8de4919d428642 - e1641c269261d4eebc817c82d5b59b3e34bad0a081aa549c02ad7c7c1e8b936f - 51eeb581e9a27104a1d210b49c8882234b2de3a655ca4b69b3f72bda9e910875 - 8cf881ffcab37b11ccd7991b3e12493f4a9e237c3184a838f029be09ac3d511d - 12dd84068c476afcf6d18c9516ae5800547b26d0a7d366af96125775f5fda02b - 9ac818f4d2209610d48e86c1f57bc71e31519363ea8bcdae791a88b50a84420d - 020b627b80424dd377577f0665503dad7d16d2f7532ac51b7adfe5704592dc76 - dbc6a32081f3435723b51a7c61ab2b8ffd27179561a8debafff46f1f6ba6a7d9 - 79a12962352728770024f016cc28caa3de3e7d9695c3c0d2c53d45b7b57e797a - 10d1b64e37fa8dd2981d010e95fa9c75619606aac70dacc633d7b415f440d4b7 - 37fe944f936990afa5f0149776483ead9759af9984c0d37a710735854f526e9c - fcc200c16bc62b6c0a7d3c18189f721eba9b90a29fca15de8d084e44c97cff27 - f28af689a7670286687cdd40e60a9f68e7eca10568d5a02561c3f437afc57ad6 - 9dd6505b04690530c9ed30c5278299a58057b7a24581a0eac0d26166d3f6b49d - 796f516103f61ec8f5a6e4307f97b77fed8898190b744c66eb661706fa71606d - 5692cb08973738cc0ea9a247590f23dfa8f2c0d406da850c8fcc639b0070c2ca - d9d4c42a42255611b781104068ae3d09e94a7b2b46df774eba4dc6e712509a28 - 2735e898bef0675f988568bbfdcd09720fa6e2afdc5590ecc9676faf12986f10 - 9eb838e4e998968dced593c337607f6190b1f32a3cf5aefda5043cbc57e0ac09 - eed1660ccaac44af2c55b12ab13a7ef3763eed79cd5ab1b754cf15883c0ce966 - 0000000856bbc3dc1996d6154a8847e9800276e50ab54db3c75f879f03c48c91 - 7cfad26d2199acb69cccc8149332d3fcb94f076e55818aa59dc477ecf1bd16c8 - f362695da854c55030e90919b40f9aad3d43ead32e97f596c066eafe89d4a8b0 - d228e9ee47b531dcf1337b4e45c4ad21ceda14ee10f5f60ad341ba84bda14500 - f4c6a8f5317bd98da8713f1d76508046c62decaf44c61d752a9ddbb539eb5844 - b4ce4a5ddbc1a050472236a437713603e34fa0eafd713017b932814b6b24a74a - 1ff7a6c5d47b4153e2007d87dcaf47573425647f7e6f5f032a934967ada85b7a - 8e8934b8aa5395988a6fa50261b8ce6b7900bd6a8bba2d2ac54cf7ce04a0718a - 5eccf4551ae37c7b136081189eedbc1793ae7dbf368361f00b1df0cf236bad37 - b87b7cec97715aa6daabdb2b30301c376ba7ebb44cd9e2366411aa3b3a1a351b - 46c45cafd23213e5c6aabfe59d622904bcaa84d90fa9da47d522bef92a523a84 - 28e1fec7cac1137532af968d413345dc3ef38b7d6e5f83594f31570ce12c3d8a - 2a046604ec433ae94cdf82eddd28fcf603fe605007420fbf34c917e7104fe1ad - 1ad45d346c2ac6058bed0f4c44d003e093e4e686a9dd4d80abbb716f7363f204 - ede2d0aadbf882db09bc75284fc29b6208b3b8d7110cf847e1cd9a1e04d14cfd - 23accde55a2975b5537614fe1809bfa01783c0e3bdc821eae70a5e4ddcf66b4a - c27a3d76e12189a03eab3cd40feb892257213b1318bed0efeac00396546f314a - 97b9afc7eb3ef845b4d53bc8593184d734ec19c93fcc0431c5d74afc8f9eebae - f12c7f186a464b0d1b6bdf7ebba592ef9f6d3b3af332a7f100f82619535d7ca1 - cd99e4134b50e84ea167948c244f928304f6d008bb7f8a10b218f46c227f5255 - 980ea31a - 00000006 - 00000003 - 5490b78c72751e0485c63a1bea5313f0462907f953a8d3ce7e585426c07e608e - 33cfd90fa196727a43edb3759b712afb - 00000000 - 00000003 - 0cb7dce4975f968cae1c1affad81ef53fc2d68bed7d3c9bc83d85204a209e24b - d73256ce79a2e8d2d0ba728a526248518d5201250ea5f831a58c2d03e7aa2fd5 - f4eb1081f5e8a7b49ab360caa46395d5c48a527cc84a2db4476194c13e6cbfa8 - c11e825f438552014a816e147410daa4ee0ed43c696e78c704f36e924a76008e - e231372d7f50586276da32b3b340d5714d3d1ad1e12e12de00d0a67c61fb6226 - 5b5a22baf87d2f22d9cbd79b2bc7c9cb0f90a034dd861f50cde7b41ba64df79d - b6c288947156685454739621b526565851d66ad7a47929a97bf82932664db663 - 550b4cea602c3afd0691cb363df0f8f1858d7296bc99d490df0ca5b5bc5d2a69 - ec20f1f85634b7a87b82b4d293d6996fa02678af04e42801871aa56138465452 - 7f699809d424f62b3d0e4a4e106c3dec086854ba3f61d0edb799612df24ea4a6 - a07a7811abd4968500e344948d1293baf4d6a194905d5c526b16e4c4ff28bfb9 - b9e03d7a9f184c06441b0631f781f56d5a51f62f3fbc7c3769e32f68d623f406 - 94fe7179b89289c24493041f4e2c653173cf3a8b2051453d31422bdd50af4a81 - 2e7bdf63d04765a1ea6a397797a827b7c5ac38d58a7f6196ba5db478dad6c031 - 143f7684b771a4fb7999152a69106c72642742d892233147e085f5e4793850bf - a83660db5b53df4e67edbc37b4a6a076c419e02ed54b923d708f16d8561c5abb - a10fde6c6043f88137bf80672273924336a81be63d44ec26a4afa761164a0c09 - 640b1aff3ba0f4dc43d16b382d1135a57936a150323ea3587717a3dd0a8111b0 - 0b875aed7c7be5250fd2ef9bfb968293ca8121d227efb07b8dff9dc819e6a5f7 - 459fa5ea01f62b2a8e278e9ef2a7029b08df3a76198de1e840ddc15533195403 - 197be0c8d1a086651e4dc09e3c59f4b3352662800af531e927b9e52e8a1d0631 - 1df831a487760cfd6e7a713bdfb2a9326bea28f59067a989d1189889b8a6b9c4 - 011f0d28113d9f6c2e506bd120bfc78223f6415cd657391dc3f9259e5d9f44b5 - 4eae3ffbe634eb9880c16f6d67db25f0881fd59e5796c9152efc63c7cfd4e3df - 95b98f5aa6a9bce0615a34bf15114dd65e0f44ecc7835754ad6ddddc0f2b69f9 - 2c41470fb6dbfcfdd1b61292b353665c6fe8601e120ce412bd643049802e3903 - f25504f80be1778e24d9166545e2da6552d4c409093a781e33447179fc260164 - 8598234c932642aa4c307da2670c70fb4dbba29a4aa21fd2ff302364cb13bced - 84c0da69d60ce846095ef042f7213be8ff94c23b12e5e5f7bf4818c461355383 - c6fbb50e0988f992d82f75db4b98246aa6e6d50713c3b436add3b95670df646f - ebe742cf69c6970b93c7acc86a868c979980e2dc313afcaa67d31ce5dd0c5d97 - b20f6fbaeaae2a1b2126e259c2d0b3268eaf96a6a42e3eb0dafb9780ec17c01c - 40a85efc413336bcae40324924a311b8645e6554004ac20d4c6334a505ae5c7b - abec7871ee593d9ca8cfd9760417966892d916d9125a81822f96d3d3fb5ed343 - a6a8ac47a863dd3bdf502d9d5ffa040398788c446037b82e00392a00ebcc7c7b - d81e85e5986422735ff38cb189dc7c24510a7287714d58aa7b3e645a9cd5bd44 - fe4a3573844f5df0ec015c83a15eb3c483b2570de8d105a1fdf6dea1edebd26a - 1b4303814b30f16bd064051d077f07e97e825372ed93a10d2022d2a8d93c085d - 862ad6006364ab5742fd3e3451ff62c1e8c966d200e18f3f55d79d1ea49d62ee - cd2e2a6202cda533761451e34b691d45b5a6b2227856dfe27cfe777aa9069717 - 3341aaa79f07975b73cf8c5a26baffaa867f1d41e7d866895f1ac652c19db1df - 3124d5d89668032c62c6862aefe101158705e3c735bb1f211eb5faccb167a11f - 5f2e043d8c7ae469a28759f25cb477fbd237c44a33a74dd89723aae046ae56a0 - b15d415184f0bdd947961a7d3e66480cc3b51d0ca2c1db86c327b0d3270ba864 - ed76406b22dc6d107bc172fb9df3513e07ca6365389e41f4a746f56240b921fc - 464d1b28d047026abdf970f2767e114da3ff0355a9ab0932f3a9a3097520f9e9 - 3bf3b03e9b460a7846afe5f316188fe17751857d3bb43ea3a506c974f5d0270a - e519d5ad24b407372f0323730bedcd660f9abb0acc1221ca9e2b0259b1cf4ed8 - c64b74776399928598a216ce6ef437056bb752d437347978369b7a578bc41077 - d57a6aec7258aabd4c623c03b1c03f5c73931e675667d0c10970f5c620fdaf4f - 80d59b70908b30c7a40114d67e92eb93ea34944fd12d6cc7df10bc0d1227999a - 200d3a9e92a01a8736ee839d0e72e59a709581e58c6bb03ff7585171f534b97c - 4a88937cb7c6a6bb9b1572fd3c2312057ff5986fbb4119a440600496497a91d3 - ab0e2b5a744eab30325471539fa9116fae25fc74fd17eb1b75329850ceeefc05 - 20fc7dbbb35a679cc0c813a19abd5a5730d5b9f0c0bc08d2bbcaffaca6e7b670 - 1b9f5dcced66b888e93f27c1586e3eb3637e75664f8b88fa2ea8408cf5b90a0d - c9fe016cb773fc85e0b4c5e37a4dd9320fed177e0718862be9a1535274b70668 - eeae69369e3746dbea3e3b459f4d20d4fdfc534d5c79517b9c74d4095e4388a9 - b3c7ed169f83a079bf4a883cb2bf5d88b9196667f3e2eddc26ea24f192e5ee3e - f68712a78d1ad086eb776a9be9b0301e50e019fb78c70ada132ab3a5bfd6df92 - e8a78d837f96ac5e7ff5ae5284d4add69b857bbe06312ac0f579d7f1d537ef5d - b6cb3f775f6a40c85a57ba0f999196368eb0939e68fabfc913d29ff979a1a3e8 - 74706d3448d12c2eac1f520d5c833138c67233a6109bc3f13d1c9a763c795cbd - cf94a0682257a16401deecb7dc787be82ebec9938df10b1d7ffa147661b11a13 - 2ed1a432ba87fd76a5be4ac11ebc04e7c151d37b9031e35a9cb7890c2dccaf88 - 786f3186acbc3fa033ef3fcdf1a670453b07bb1e4bd96e0bd77749ba9c1ae577 - b5499b24430d7b3d3786a4dd04c7d69fd052f4a192bd58048b4aea01ad7a14a5 - 45301c513045cffac021dd9a8640b184b86f915b5967a0996cd6e706e776da68 - 00000006 - 180968d5c2d73bddf40eb18e436c809891d2689205550e01993e1b9c0c767575 - 2dd3d8c2c702aecf34ad3ef16e03b398f1e3d66e490c3d6e086bfbeda5efe599 - 4cfa5b469a145858df60fed7c71fe8c1fbdf5fbbe5dbe85c9a51016bd9ccbe9b - 6bea3b494da9d308c8a85db2fa6848c7db1881615a99b452484c67f96be55785 - 7b43336be8ff52c5ce5291806e2118337f9a25b26029ec4d1d8023961a5424a5 - ecf2b18beac1653790736e6f6a5c7a95ab77caf54ea06c0c11ad6981a2af0b7c - a3e964dc09397caf0e78a63d57aeb5c3acb9c65894b134092a2643d992d53107 - 5c43c911d5577be8fe88fa023a3e36f32f9333e3c6207ca1b0018c0e0f389827 - a7a4cb92d8b054a206adec09b35ea6615069fc7d49132549bab5548b9e1fe61d - 2b7a9ba0d6d3e0336f17f3caa18e0ea19d6cf0a9c0e48a83cf325369b6a091ba - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test10 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h20_w4_h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000008 - 00000003 - cc453a482bbabfad998dbbacf34c0d89151995177fd38cdfa301b645fbad1675 - ff8083187b30a36242b11bac4bbb7e0c"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - ae258cca017619f7c85179c0dde1f48122fe5b3adcd5ca14475308c6d6a87c8c - 6cbbbca7a2dbe83a7fa7a0814e3d692b66bec046ed590831e695e0391c0028c4 - 9cd5e4e561c983d1640fe534964a4e5725705a4d907f5088b265e329011b8047 - 330fcf0030724ce62edb5382e59af394eee06b0fe84d95ff8d22b0ba06c31876 - b85d29135bd4291f49db0f22c1a304ecdea5137b6b59c49cb053c6ec32b276f2 - 9dea3ffe6c10f3e99e84b00221bdf587f703e81ffa90e9835839b693fc3e2b06 - 1cb47c8e3392750c4f53461e419e151004df01da6d8bf8a7998e88089d18c487 - d1adabe4050214ae3c5aff0b2e7de19a734d6cc06ff060c5ca4ad5c68178fc7c - bb66b7de65987ce1dc966f1a2f9fbe301f43e6790df0fa452884b3b9ea30fd33 - 689cf76ae7eb4f6c79f6fae9e89cd9d0349928757dcdee074eacfeb3e1860d0f - 1e8f335be9d0ad131da1932730fbe5997a813439920d53c4a36c6ebbc4a2b8d6 - 96fd511a6b92404421674f1b1b79298243c60bd524cfca71057377b0d0c318fd - 341759a91f4b47f5b0df61d1eb1533982707970789297a1af0bb2fedf8fbd582 - 87708cc4c3304246313b323df92f36fa6fa516c333197253c860b2ea4eb92cef - aa33311f2b9b3af958d67a9e466357f671a1255530fff1c2a7d976c26837bfd5 - d7d9d6ea5f87c81abedf1e1b83602250e2226f54eb8f3f1e00bcfcf241e655e1 - bf79b0d57b947c196f6c33360d303735d323406411416cd1fb2391d3adbbf0e4 - f0ac38767fc2e9ebcec97a5c80712bef5deeaad9c85fc4d024ffe7cba0608c98 - 90b023852af96a6dfca090187a4f07447d89b1162d0a65e4cc7e2481b057e199 - 0ed2ee333d2c4f26c6321e2b98017fedc0b42202caf469405678a63108359387 - aa240fe210d833914423e02d892fe26290dc2ba89bebdaa2273fe265b5d518dd - 5b406c33656466f865c1ffd671b46e2b9044c256798afb1e1d49dfc025aefc06 - d6cb1a968c5bb3e200944de6a81bce2ee450559fa3e302effeff2b4e919539ff - 3bbeca0575eb8abdc635fd330c1606b1c810029ed55d8a71253ca89587762629 - 1aa537e4b0c155e7acbac37d1e447586adc56ad262b0ab2421291a28b4e664c1 - 70750274d82b7850fdf745374c2c2eedf9828300b3b2b9f8d2d774063658ad05 - 92ed8b8a26e8021ed63f413996d1c12c6a5e80a4fd1f6ede5f431974147d9116 - c356e49fb7cda7d35bde52b1c0efdab1dfea8db8b13c608a5545723ee3611456 - b21da6a343ca0c432a2353dbf926e2f3227e9659618cc6b46f46da614666f33f - 1d979c6d838b678fb027a2ea5ae601592cb28efe10918509418476639bfd1f0f - 7dd8bf91f7b28499dc72039218bfe37595e1741942e4a2f640a92dacd809521d - df34aa2b549d2b666089a9df02d963347d565cc5fa1af7f700237db8a57f0cee - 4be997ef40f8ae0631877d07b71a4a76d3f6f53a737f14e2fb0f2222e8649144 - c3f8ac33595fd9290a2a0345eb1e4c06187ca4b5ac77098e473a07fe0cb58d88 - 1967f7f645ae144a289744b0801165e9c47d5137f79d3538d6f3a45c962d06a0 - 13248d125cc52ebd2f3e4ced0d7c1e2429425da6b6aedf96db2c2524522e95a1 - dd83db37e92f782b6db3c84ed3f55f32600003d9602c17b6280fc735787f8381 - 853d02d4b03a97a9404bfe6cd4c58c1a67a70298f29094b454aeb1bc0d59e0d5 - e24015f9257d28554905003a687444ce51b19b7e46f4e56e899e3ecdb9415119 - 924b0a28f383b7e8f817c6430dd9c7b13b6f93179f77c5678fe51098e4c0425e - 7d44cd2e82c07bff8b8e99ed08d86982ef7680f8ac3ac2228dd286a1acad546d - 43fed64175190ecc62f1662a2f2c29cf2effdc9f9a18e681e96cce1bfb41de22 - 5b3c02ba65b4c5cc5591d5b17b64a3e8df530ea10627ed29d096f30934d10954 - a642548ff04651c9f24ba9c0496bdc1a8af76afc27eb3dc9e28247ab5fa7274f - 0cffad5af2cf50ecc35f0b466fd7b8c6973d1ace0cbde0d793cac473ff151aa8 - c9bc3d26beb8d819f21ed0ff1fe6af5be4cb4c61e1ed6897496fbbba14f2719d - 721742fa7249dd251e501b98936ab43d0fcf4b7a2d551471d3e663595e19e235 - 674d7d525b6a5ae14ac45913cbfc51e80a7fe351d0cb24a8af1b970d309517df - 7a7dd6b12c6edbaab5addb1711abca1c412eb7270e9a8aeefbf7cc5ca22436dc - 75b0b5989e1c25f578f8d0aadbde0175e67b14ab05a4c5a5e061a030282f5415 - 4eebb5a717854b02877ac1fbbb732e52b18dbecaacf16bbb74954f83c0aa470e - 35d099b7efb1e17beeeb87ec0b9e706c331f1b20f0a903dec2b7ca1c196b1d63 - e804513d3f474cbe6f9bbd2900b79b073011004c49d20f7420a01b7745d490c1 - 0da63786119d895d58b44eb066d80c88907aaa211dfd82681634be98400099db - 8cb82b6d6172478cc2e63d4ea6dd48b47702b24b6fc7b49e09d87b61d15b59d0 - 39a6d49b3e4896ebe0c83c70ee6926d498ace6148ef3449a7830a7ed4923866a - 3f479a708a7dc319c1161d0f29cf425682c389bb173f7681c193ac982c1e4012 - 6a122b2c6e3fd20906c2921987b2a20d21c722c5fe899fc15089e7b7ddce4262 - be8acc27fc4b4b5176740f8f3adcf44240fd1d92c5b1db869bf0bc957175fad6 - 2d8ad0368b9b47da61e5afffc4ed80ea49890178232dd021d94af7b15bd45059 - 67bd91eaa2844169e89320c92914e27eda9800cb81b8ff11a52043439035a275 - 53cf146c9c765b3d5f13bd348475a8bf9b3021168364b7cf0b35b4a2df95adda - 7d1d386021d0ddf9193934ae4f0958d2ef8b15a0278e5234aaa976a8ac6acc45 - 7fff27c4d64da9d374ddccc55285069074ad79bedfb606c95a5d294e97a49571 - e4b89696b83a69b4c65568e7ba4b4da0903f819a75ee42f6539b4edd45a53dc4 - 07c7028834837cb1665050f13b3f69560dec7f042d3d8979fb170257bc024764 - 627d369086f127e1f5a95f45cf49817c2c699b8d0b20113259ed141e6c01e23e - 41a7bb7415f324ba3710534126db40da893b8df672bb16a752e873bc3203dd83 - 00000008 - 24bc09be9c410f127964bbf6430a7b42f53ffe22f04cde135d46a847de0844ac - c15c1197f938dcb5adfdcceeb52f95ca113148d07192ab76d83185054df0b38d - 8f95cd789b916bf8f7d4b7094802df6ed52cc0573756df7258f12e439cfb1037 - 01dd72bbdb60753be01822a1ea210eba7fdcea2c9736e79e11ce2e3b50f21a4e - 0d84d9c578bfcefb4087146a40c95922b2dd69d29103d9f50fe3368b19015172 - 36922e837fe8bd50e8063e5f0c2d4a961f1816bf7a5b3eb7ba63761368cae83e - f2fa4e03491acbbfd6d0a6048e3f2589e67aabeb32b3619085ff2d6a810065b0 - 5a2f5526fe1f188ee80bdb9788f68c1e93cc2ea104e404faceef91fa6a28e27c - e6c2a6a4b03b81c7ca9ce94f06ca7762cb344bc738add901e6496a3fe739343f - aad8396b832ac93f039adad869401a2e590dda2d9c571e136b55053e8bd17af4 - 2e5518ef8b8dea3d9fefb811e7248961af4f67921c5812bb87c27b22d1384109 - 85f1f48d40e4c86a1cf7b1d47cb2c776aab2b980a8a1a5e14f6a6c3e823f8b91 - 9d7de7705ba30357aad9b1d5e7c3404aee1fca2706bb97e94ee56ce826d631c0 - d03a93e676a557af5b3105c9cce0364907f1c7520a3a9d70ceef18bc86584df8 - c707e48982dcb6221aec3bbe75151d0c50662caf1b401466f089f464b23e4b10 - 77f4c2ff6efd0ef42202fd51494093459329eccdf895e038c3f7e2325775c399 - 4ee435f799d7cf0ba8308d018a1c748a5b96786d4b1090547165d30cd9e50c9e - 25122424b4d89b5f13949af9eadb7e9bfb95820bfd2053e339dd154593c8912c - ede4bb64b3dad525f55bf6640d99876654d3a9666ab81b38f1e7d41036a2930a - 3b4ba370e6fb1cb4436eeffb3a1f4029eab69d47e328e3e50034e3facd1ab396 - 00000007 - 00000003 - ff29b4fe1b544b372b2922adf63187d1a8186efd415d82a993a79ecd884987fb - 984f03f786948f53a3632e75f622a334 - 00000000 - 00000003 - 9818148e2b3f0b1b92424b8df20c31aaaf4d2d49997d481a2be32680e62eac63 - 4dfc4d390876d14599c23d59822e0d6f525a9afbc8319f75de7370043d33e413 - 7b9f1fbdaeb3e47bdbe29fb7e3247ee5a1c637bd739be597e5513b81e5b717bb - 593037bf97b4c1f216566a944bb19bdac86a5be82fc34eef1799e07d7035692e - 687024660a3a83fe17d73c919513c12660edd8af23975ba3816d027b7cff5e5e - 675f5375bb1eb6eed9e5cc49b962a97b1cf41d79422f2d8e290ff119d1cd562d - e4f65dff4a7408b2eab21093d096707cbdbb70e8bf6394969e1e51700a500a98 - ca1fa371d96eb24b359db9af3d2a5e125e33b87edc22eca8764eefce39dae0b6 - db5504c256375a7b6bd8ffcaf48a1fa9b246bc9952f8374d8d65cf22439668b0 - 3c02ef6fb4a1512dea8d7c38cbd8946114bbd57a0da2ffff326bb83873f4ea40 - 09270671b0d9a88e10c9552ac580160d248daa7bc3a10cb393a1a2aca8ed55e6 - d6983861830557e7001d65d8656c07fa37b459a5bc3ff26c2109be9f395d1307 - 8e27e75f85f388562f555060fc040650be7c5a4984bfb41fdf0ebc2da22a8719 - 563aa522fe36af768d95d49da30c899f3409c8a6587403411eaf032a84354039 - 1b136a795a0b3da15351ece2f62b7cc15d8f9e3bbacf29bd73e96c9761fd23ff - ed75c8131721899b2b314c61537e3d324706de6dbb4adde305943ac6a2000e5f - 6e193f83b9381ade4d61a9ecb2591ece400ace7735eb6e0958d7d1c9b0ef4990 - 2ec4592c935303c71049c44a518d65537cd903c95c37811501028a20b4aa4030 - 2857c970a589260073ea093eb913a11ac42c67034d27fed38b300eede2ccb18f - 7df10d09d9cbeaccba52471fd01d42361343889e5725a7f2d23c723517337e94 - 2f53fcefef8c4f091fc1a02790db7a987bdac6f67382619a84c003fb76f27e1f - f070bb8b7786ce47d4455de311230a0e1dbccbb8bd37c45f36e84e3f15c1e4e9 - daa1b4a082f85a5c2c71371e39661792284357a7cc40451e39444e8c352185d9 - e7aa1e7524a1eff33b5839c2247b1430a517db6ef4963b23a1579a3803c0d2ae - 3568e0d83d551eb68dcd301e75f4cf38792cc504a94559c1b1a929975aaa38d6 - fee0aefd1aa4c99cb1412736b2f5978c21987e651e391c5b1e61cb84d92d3806 - cb5fe46edde39efbce75d0db86414e82f6ce07b6c304c7f7fa887d13a02e8f59 - 57b8f07ae9b80a10b3f050902a230e5b33230473691af8c7c2630d899c8efa1e - da5afd1db629318736132466c1970f9753200e05a30ee13e38b4a60e15fbac33 - 986a6e7760c5805b4f488580db0008e574e173a34cc62fd52c9cd56980249a2f - 0c12238a0df04a06dc9895413b31fd0aa0d9eee50ce7fbc178f8719bd9df399f - ce72a57e8571fcbfa4f174f0c37c053238bb9225d480547b34eaff09d00fd29a - d2daf5b694ba4ca8a25e42f14f2cd7c10477ed29b22936989cb7135c8034f81e - 2552fd1d15f54ae69054fa03a36ff48d1ccec9c45dcf642dd4bd0e2aed42d4bc - b3df5f9a10805347ec0524c13d49014ca1d983d7de40031f530a34ca1e8ba45b - 5b304303a71942388b61779ec6ecefab91cdf705c41d6c2fe72a6be231acc3b5 - 496661b0d9f5908d0f39463b785a98348a0f9fcf714255e6d9c9c33549541567 - 55980f2d96686e98f5a990f821504cf2a1c32d2b654f0071dfd85981d59da1a0 - ecac2d30b1e2833ea108982aeb059d8c2b7facbcc4391bdd88f900cfae20cfcf - 99fc75fd68a85bee6a75be7cf8f4b8a66d9bcab17094e51e745c9b8980b69cfc - 4d9bbacf338fbaddad1fbcee745ce30b8ea8316e597350bf1372353d38274c31 - 34c9e3ddb3affb1f5d5b30a51c3dbbd7529446f4bba26eadf4aa53e7641f70ea - 60710d773b02d930a298f8c6957b71f6841a6391ae9d5d2ebee3600061c57244 - 7ff9e16c211a5b71ab1e7ee811f70a76aaf8617648083959b327a8f15698ba87 - 3387b492ae7a7ada5d78ae4fdfce67262cacdcaa0717c4e52d7ecd85491903db - f64073dbc2a0f77ba5489f0af146ce8d4e1544f60cc51d2a9db84eb5d8b3da91 - c10ad2437744c8b3077d592e5b42baa7846d4250df4c98112b688813988a6759 - 2fe7b707276dfbcf7cbe3daaf0be3c8c13917d4f2c70c6b6945e05457ce7018e - c167bebefce80d10502f5a2164492a8602ee7db978c51f79612b5b9d69013105 - 05bdcbbb66a385ed2702a630303fcc30900b8d9c345229f7d539185cd2cca328 - d40dbdf3511715cdf195c7565bfcd7ae7830374d4c77acf746874068f7f0ec3f - bc22fdbd06fbd4a4bc018d6a81bdf9c5f3ec45c441333cee36e2f3d28f4d4ac4 - e45299a3ea7151e2f314ce1d8c7f8aff7be4886bf8ab8de2893f17baf2969125 - d4b8e4f036b3b60c88e0c08450a8e7ed005831f2030760d4a97c419a859ded43 - 85e855bed5b966d1a97845fe8a6dc7467a2529ea005fbf0da3fd3efa28142c92 - 058dcec7ec1e1f199ac8c777857295b34a33e2b678c04475b7dfeda7656dcc5c - b948ff2368e989a4688c16ba02479ccb107f6fb27dc30f0e49b9641aff149d07 - c6afd31db92c8a5d0c0f4234aec0c0e1e05c7336378b387d1a70a4176dee6835 - 74811cce4b20f0730ef92932d1d790b6cf73081da8c51b75ba8950579b92c117 - 567f3a1fd8a049685a7aacd9cbb997a0aff7e6a34ea7e70fc8cf24b11f96d2f9 - ef5327eba013bea5cff327f3a5aece1b8a2fb45f80c2454a9cba86a55a1ef63c - 7862d07eb1274fb68b69db5a0cab9b5aba53595f6e0cf643efbf38ed33e7bdb7 - 3f887e8bc0e50c003bb8523b7aa459bd0517fd3b502ad4fdaa22010cb6ac5bf9 - 7d6ad67c2317a9d18fa8efc4c02345bba30bdfeb788c001ff4f9a899b0d11043 - 454b52fc2828fc1891e149b42ef897608d95f568f3eb301023dbf18f40da3148 - 45821078487199e71a6b48b2105851702fb6319052ca642ed6338c41cc8b3d95 - b101a08835e9352f71938d24f8789d32add82e7ede0fd1858330a451015f7e87 - 9c5eb59c8e534beb771aee8b0fb2bf4937fdc9cf07d891ccda61ae4aad303282 - 00000007 - 2e0e7708bb0e589d2d818a8c0e2c53b3e59b9e43c7a194fd18d19ab1554a9f85 - 90b31f08e2fe1b38486572cc3b36ddaa9d85b795fcd93acd531283688191b5f5 - a744b89faae49989127685cdc000e001a0d77df3a5c3061e312377b1050e7371 - 24a68d2a00a848e141d274dccb8e4740d33ef7970494ed316447f8381ba06791 - 001e90b7f36ef24e1dbbd68f7074ddd233d9e15cbd4efa4a249cb30fd3095c3d - ed096e87d6c179ff8dbadb1bc6493bb6f944ccee2cbf24573017817e586475f0 - ed51bfe889b298a2fb76d16dde0c966a70a284dafa980442f870d640e11079d0 - a4f6834a62ba0a4eac4d7334f3c756ea6b0bd8eafad227b5b8eb4e937c32412f - 201780dbf5eab317f3a21293e653115bbffac4899830eb28e6e43c1a77b51884 - 8f68887ccfa366175be2a88d3fc178e671073736bd94eb4e16720a6b3ee119b6 - dcba885ecb46126614c7a677c1662c4cadcda742f27fc01a8bd5af474ee4a29b - 4e25721bb931b8bf898afb3cb66d3fcab70b80005e737ec5bd88d5ced8941226 - 720dd43655a9ba1d4bf0a723faa4bb3651ed2ea7e0bd08113e524777e6ec592a - ba5cab16b084d208d20bf25ad9a7ae31bceb00b07ef20cab7d1f6883ac331c75 - a2aefb8230ae97dc34577785b123af406040d01fd072c493228d7583cd023c25 + 2510a21e43c9b53b86557646b2c891ba432813ca61fffb57c4a8e598753542c1 + a179d3af5254a37c01eeb4393d626771858d06041c76f1960e754e9e04aeb91b + 1d9b7736193f49e15c47f44a8f1c8aca6133c34eeb682fdccf94886fe80d971a + b4a0bb3b72197d2d5b2111da8647be1675983e8ed1c0d8ec7cada282dc698656 + 95f1e8806c7892b65fc17103ee3b5366b3fe31e57e653336be283962f488eaa5 """); } } @@ -1844,78 +376,6 @@ public void setup(test02 test) throws Exception { v = getVerifier(test.pk); } } - @State(Scope.Thread) - public static class verifier03 { - Signature v; - - @Setup - public void setup(test03 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier04 { - Signature v; - - @Setup - public void setup(test04 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier05 { - Signature v; - - @Setup - public void setup(test05 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier06 { - Signature v; - - @Setup - public void setup(test06 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier07 { - Signature v; - - @Setup - public void setup(test07 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier08 { - Signature v; - - @Setup - public void setup(test08 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier09 { - Signature v; - - @Setup - public void setup(test09 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier10 { - Signature v; - - @Setup - public void setup(test10 test) throws Exception { - v = getVerifier(test.pk); - } - } @Benchmark public void verify01(test01 test, verifier01 v) throws Exception { @@ -1925,36 +385,4 @@ public void verify01(test01 test, verifier01 v) throws Exception { public void verify02(test02 test, verifier02 v) throws Exception { HSS.verify(v.v, test.pk, test.msg, test.sig); } - @Benchmark - public void verify03(test03 test, verifier03 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify04(test04 test, verifier04 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify05(test05 test, verifier05 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify06(test06 test, verifier06 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify07(test07 test, verifier07 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify08(test08 test, verifier08 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify09(test09 test, verifier09 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify10(test10 test, verifier10 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } } diff --git a/test/micro/org/openjdk/bench/java/security/MLDSA.java b/test/micro/org/openjdk/bench/java/security/MLDSA.java index 2dc33e2b2985e..36b616ab599b3 100644 --- a/test/micro/org/openjdk/bench/java/security/MLDSA.java +++ b/test/micro/org/openjdk/bench/java/security/MLDSA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ @State(Scope.Thread) @Warmup(iterations = 5, time = 1) @Measurement(iterations = 5, time = 1) -@Fork(value = 3, jvmArgsAppend = {"--add-opens", "java.base/sun.security.provider=ALL-UNNAMED"}) +@Fork(value = 3, jvmArgs = {"--add-opens", "java.base/sun.security.provider=ALL-UNNAMED"}) public class MLDSA { @Param({"ML-DSA-44", "ML-DSA-65", "ML-DSA-87"} ) @@ -195,639 +195,636 @@ record SigVerTestCase( static KeyGenTestCase[] KeyGenTestCases44 = new KeyGenTestCase[] { new KeyGenTestCase( TestUtils.hexDecode(""" -93EF2E6EF1FB08999D142ABE0295482370D3F43BDB254A78E2B0D5168ECA065F""") +796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -D6A5D2325B94CA1B993A0151E24AB95B396F415831DC14A08404820AE58A2AD1""") +60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -8A5E79B82DC81553BBE821EE367F0ADFA54F59A3E8A71CA626F873F638636DD7""") +c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -6137CAB1DBF57A5CFCD0079BA87FAF2C7141EBB92DABBD45FD8B478D24AB8946""") +ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -B9E2F48349350D30A5342783C915A608C905E0DA4BEBE2067FB62C714207C62B""") +78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -2241FB7005D1B26A1735FFEA5186D08950B4B12CD4FF51BD263C6B8A2A2A18D0""") +917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -32BA0BCE82AC978E5932BD14B1AC1A9319BA20412538191E2C7B1E0BD1D01CBE""") +df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -0BE86B084CD4B31D855EBDED6DE39326516D4BA6770B76B1D4398FB2C9C75196""") +d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -68E203AD881ECE7B354F6A760C87CE3C2F7A62EF1E12C71DC2A965517F0E196D""") +865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -F09E23ABE72DF75EE36DC1C952F56564FA4213A987A0656FF758F3991BF4E1B3""") +741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541""") ) }; static SigGenTestCase[] SigGenTestCases44 = new SigGenTestCase[] { new SigGenTestCase( TestUtils.hexDecode(""" -C1623CC91C677078CAC1FE857F7DC40809F390BA0D51BE7BFBAD9B55306FB2E1C5B3DE04C3E7FE3E3B24A41F45F5FDD3E73A72EAED3B3F57356483D7CC102953873F519C79E445456157FDE4EA5F64D613E5ECB8C6258484AFA36AC4D31AF313FC17A5835184087F04CBCB7AE63D41AB1685FA02D1A64F5D0F844F6FB5213DB1C0444190B48DDC04111AB824DC342C19164CCB242803018284C2416206650A280D2020900A83314CC62DE1824C128489E0844518A22D141628D19290D01805490010E284500CB409E11429D2220118A30D10B561249449C2201213B525CBA020DB148DC3280853B0498B34262045919A424910098C89200553A00C12430060C060E33869C4428CD984648C8009C3C844E1886520478060264601140EC1046ACC4045E444921921921AA15023074A022444903470C33250C9384D824249444042809060842811021660C242251C102EC034060BA74D81224C5C286C50A861009388534062A32671524268D42225D9106C08314C231385994608CCA265E222685C804904080013236994864C23A03014184DC0063114488C5AB0850922080A396DD29045242588890286CC18858886700B474CD02461DC86511B932CA38031033764092446811802503671E44624A41632C9868CC236700CC489038910601670428811414042A0A224D92831E344451A2548A30281C024701348224BA06003C38DE1184C59A64954A46810348D4B34815A00215C24018442685B088E920002DB42508A3071A39881811871E4A069A0180603203022C68C8212824A180561A4311402301494691840619A482919868051308414A30C01350D94362DCC220820368624280E623200531045A2388C1039498004465AA86C892682E2C601CA14652340704A246502882520B56508025124248EA42408018270D036804940211834681C862490241018239023406841384D1028718C4226D1B04099249214219140362C0B216689A268A23280014545A0320C89806492466DDA0802D0326E9BC808D2A249E0006D5A226A93B42020364E413669A1124C10A2901CC66D99B26C92442600004A1AC36C9C4221E2B66C58120409850420884D19A930D3347159128D024271C0140603A790D1806C00296D58B8011A29441A308124A58C82B070D2B60021270E48A809248709192585593462A4460C13160E8B844C4AC07154946D22235003244AD0808D83B644CB066289C250C8486811407242C409138268D0B66980B46D52097202586725A9DD16DFD951EFB6F6FE3231A2C471231B53057FD316DB0876691543D51B66FE1CD1ADF7A9A73C97CB74056DEB19AAAE8DAEC4EE2D512F19B5521DF260609A5F1DD23CA4EEBFECAEBC9CB0DD9D612D0AF491655C6B22A2AB52C6BDF09B8C05784D2BE8832EE184F7D7EEC0C15F06052258A5DD658C74DE50D9F351979A1B0E5D4C94832DEB34A09F08422C53BE60568F81F379B76F5C1F85A0E74434942DC524D85C26A8489C273643CDBE8662EE0D7EBE56C7E4AC93D84016D99C0C180D24B6B3A9234E60A01A83DD64446DE5DBF8AA770BDC66097BAD4261AC8878450653F21EC34CD3E6F1303C44A4D29C9E801D6E87DEF63D4D35F7516A992B788913829191A09E9526F8CBC361D6530EDA7EC9013AAC629177CCB744CAAA8ADAC376F0222B97997F273BF7098FC39A63B899CF35D2E9D397F0D2A49D320B03A9FFF21D98D307DFA94A328E04BEE9D58B77C53303779973495E3EDEE49BAB18E3634E23E363E1F46F087D8CFBBBA8A210661C6E790A6A6449E0CC2738DE05A034BFEDD377C0AB454D4F39FA6F4E91FDFCBE621D0AF8F84197B4762CAF6D5992643A16BE5626E52CC0ED24895F629B02D3CFC92E98BEFDB1DC80475FC9EA7A40EFBEF650355B03B76E7887BDBC2D4EF8FBCDD6D95E260FE6561F17C44E1E01F6712DD0E5F7EB89766AF3FC9370A7C168F64746FB8F744D146CA781C6C708A963EB90858930875223CA379428A71D8008C70264C87E420ECF17DC963D3D7E3C8F280A8716EB636FFB857E8AB92847CEAE7C77FD2970DA98D08E001AC9605BDD6A07885B330F04AF2DDDA3EE6E9314C012E3FB14358D67070014A728B6ED5006622052EB43B77EA3E5DDAA0BB1C1C6A973C8A455786A76A673B5F4BDD339258A7218F4A210F0BFA65B4A07EDBB199EE755B8F60CC001026107163EFCEFA41DF85065D46FBA9471513268517F06B5914F0C625F3C40DCFE428853BB58B10FC19C2685007AE56F42CD6730CB4A6283BA4AC4B40AD9D9B2FEA1C2916111C39BAF1430612E569227E2C6AEB11E0451AF81E308F3BD59CBE29D940E2CA1653F6D6C70CB1D3358392F2A97A34FB9BF05203FF507DA2041AFD85E4643A77CFA441963E282B7B2A5A2B8D293D036CB5143F3E01722E589840DFF12186B7D9799A3D74E99288FBCDB6D2CBAD2E5FD4B449AABE16A12924AEBD33AE5F61856EC66F44C0B09FAF4D0C20CD0C59D760368B335CDA9422C695653E06C0E839EA7FE946237B222F61F9F02B3AC916D030560B8ACD07A41E7D54C402FA7CF6983F09D3E46EE6A7F786FA39DC369E0EC4A30BF734C636DAE26D756AA781E40BD1530A0BDD4040AC17329DD6B90534491CB2AE4D179C2215CEB1F466E7D871D42FB21106834D72BBD656D836F09FDFF875B0029D9F3B50BE25BF05D6A2B0EE322E969247609E16D321CC928C3C7F9CAC3C9F53358D066EE23B52837FFDA6CE77D6235DA4FC06869BFFF3FBA209E8255EB6DE7DC40D0C89969DE0D33B5E54151378BD3021C2A8879BBACEF98AC7F542CEF27F8C639FDD3BF0A0194BCA92E46D6AB5C44C7CD960B1409A088304D807AE67442712E3F72171E06FBA8CE1CE2A6A15562F6BD6968D15339233C5BDD9A5A9796C1DF657F08BD90D1EB5126314B16324A63ED2E8486716B38DFDEC3B14BFE21B2D710BC4DF2ED5A45993DFA197E5B190BC11275E5D9B2BBDAD69E819E4FB4EC859B8C6D32D6F21A7CB35E62ABAC2892E0C6C76D6A416FE3E5CE80361204CDD30C584344C3E61BF91A239B626D8C57750CE0FC4BEAB5743F93083BA01FCF2A9B4CE04BB80AD8B3652C28F4A81D96ABF4716E8EB090817710AB2D052366391F1897C7512F221221B2EEAE39D36C24B919CEA2EA7EFC42CA4FD6FEF946BC241106F12FB82B12D947527723E32BF5029EF8E6C6EEC47C54FFA329D8832F43811EF85FF1B2133FB6240849D7435EA99DFA76EC12ACD6E7AD590889441FBAF7278F019849872D9F4A281764005CC34951CA11C2CD1CE31E51CD2C9EA8E4185274188718D56780DA3F7D234FF14422697B3B4B3936BB1607BB9F048A69A293C7C9DF377E380C9EF8B39990E6D7FFCD4FEAD58C1E5249EA58F9ACE95BEFC1A904B6BDC284577D8FB618278D1F132DE15E55A09FA1A558999298A02B3787C5E53B34EE7D017599CEAEFEF80AAE2953E1CEC97E880349C2AEDF507B3AC853EDD5C0D8081500DAA684A20CE3462E1338917748A2869C9708C5A282FB7D66CA0AADA519FC56874D158D8951BC66EDF57EAF987044C7349CAB7C91BEC1655F22006182084F1A65C356CA2AE8AEACE36D3C5EA966C23F047EA10F1681B679"""), +8109bb66b04ddeddb48e77501a8b1e2431fefb69da28a572fc535be604e351cd9301291a5725ca7d7f76270174b0db0688bcb93ecfcf0910b31afe84d7f16ab5782238b7afe42480fd01964142f634d8d50924dee8016f381b69cf0e6f9606e3c2d68b0929c489a45eaecc40008d64ea69676d454115d8d2f1413962db5eb800db36210a246581384eca982121076083a609c4828089424511996c5c164c183669841624e016259334021b123003840920b6854c984921b760021666943849813442c8c84dc8820124829064460c5a4430828089da381253b665898290e0086cda86802428721a244c9ca41108c550dc868120b93121052210134a93a4284ca485914826d3480a59124e63944464223161362e52b824e1346ddc34511c084523823192c29084b89100c92819139294186ac326494224214a0821c0382c9842504a8884cac2882102865c366420080614b330e4380604a820c390450ca48d63062561946c42947014972198c2094b422dca06015b000cda468edb00659a18712448840ab1814300900bc84523010802b240d08865a31262213091598024d908081c89051a1502db3850033666030521c1b489800070e3048061a25058c6091c318244244dc444300b130cc8c401d2320a51a26c88226a01b4810015711a2840631629624866804202a3440d0a160ec3204d0212481b406ccc4611418200030781049588243822621200e2c24c1a19682224008ca46844c608dc288cd034411c03520c0050501082d44885d2b66d50088103160c22c964db2484c84290dcc801a3227254322e14030e189808c4385122a69111266402182a210172649240d844248420210ac9414b80448ac669e1c664c3808598020948982d01450660446424264c09122ad2b04c9c4691211832238841c0a66d41422a49a20022204ca0360120968c18a088dc142a9042082122640c2649d014048c90280300700c40822420229bb285e18651c0a86c94b0218822805306250800111212008440224028728aa60ce2867114354264a409c2228604385282428e103422e0c0480a968954966c20c87181382894463003104cc4462d22068dcc180ec400911291644a926c9ba26908b9411ab08082966d03026d9a16422244419bb49112a06108c71112b625010202c90862201646212731db144113152521c22199322c10832522495010250ec3844d4cc6658a24129b24001b020c91c4105b88710c44851b227012278d138871d31ee0376e3631e0a724ad187fe258ba1af825ab5c3a8bb76a3ae308d11580696408ca1d21d4591311c3d6fbc0744aae0431c7c70d40c7447f5b9f6530c21f965022b9919db9f553dd1cb74faef7163c83b219533d3c2fd3a8204b55cee8792de783358f944c2674fb79230fa808353907f1e56aec8c39e9e6e64f83b4552d76723f41d44ce494483113c6f63e3fa0a8868fced1433adb004b8cb502a9998671fe73a914adc2c42c64cf9eb2e77ae709229bdff22046d5018a5193c6de49fd45f15d151e1c0dc4473a9948bb5bbcf29489a072ad81200c16182b034e29654f9da3d35d7b1f3cb9bbc4e6acbd97836ec4787a8b918509aeb811bfeb242be7fabebe5bdef46aa405dfdf36811e1cf980acb00eb323493b260a542dd2b0b46a3d571901216369e58e855c18a6276db360b0eab396672ad9635bba154b1b4fe0490818b17039da441f055a87c65d902bfbc2a39e94729522b69d4e47c4122b5b19b87e6fb85a1bd682edabb0772e74ad9eeea2e0758e2f8d3e4dcec752e88e936bcdced768911cf6c33819a5a86eb6fcdc4efc375c3e0a21e49cd4ab4827442c96bc176de8b294daa0f41b8ca536e6e12b915750304a71a1b3983b6330289f646e98b3c7fc38af5ff63a988564d85f0608ae9937d2c425464a59150e83daa2d049c1c80205acdc18f65187ead4bc78fbf1416c00fe0960355649786d83520cc7e3f4779b212abd329c4d4093d07c9e0082267a0abfcd6a391645eff624e47137765df08c924abc1a52ba8f4067c3073e7b2d48eee5b366db9e960a6e55aa0e4b48e4695b880dceb98912a18f671d262703541c8e5e4bc16b9362bed20f58d5f5a1818800308b1922cca258e8429490ee4fa79ac5f654b67993933e983c5874d696a8aa46ea0c27113229387fc6679cbda800c4a934625ef3102032db2674b7123cb748521b0a67e83aa906bc52ebe7f222b118661a3980102711ff679e4b6242b9010e8a894ba5c93188d03ad8da548a9e59e0d9f1e08c27abb8027708eaa8899495bb4b289ab03f562e821a7b97118cee1389ca5257efd73cc53a5c5ea9d2588a3e835acb268159434c09923ca92f34aaa22a7f8cce15c800fa385f49a7d15772f81277a8ac2238fd34c0eedf75ed2bb6a983f45d27d9b972f4796923274c588f9d1e6366c805623255528cba1500c88870395207f19d39c5eaa80ee5bd9e776fe73017ca32ba0b0055da4452bd1f96a162ee32edc587553ea47fc3bcc10e27f9a29ef9deba54150032a2608cbe2ae2b8f597fff99fea769b76d090f5922207f17aac49355c756ae802a50f7f5f6990cdcb0b31d8fd6a9b4915d91f0fba752f8424c4aa257c78f2c378364fa6b6892efe4744e2d77d0c5f02c2cf7ac28ba757d96c2c26dcaab0e9f2371ce6e1e7111cc5209a0e053924bd5202eece6d4135ea05c76040ee5f2c195fd76b4dabc10eb03a9b4b36c8e0b723110b1a5ff8cb4bd3f0f49f7dd866f8803c84c083171b1a3ccfbf1bbf90b524dd69acdb9ee7d0928cf484f90d442b815bc91c6b98368bdfefe0e63b5e9039959e7c369b38cfc78a49f596581282f820609ea8e76b2a15d78fd3cfe70cc933af7e8b5d1b28aa0ca8f14479c6bad013d93df59e237ebd3c4f96be20893577b8e98b875e40fb96da3fd0b69b2c4a9803f92d7443db64b61c5bb8f3493b7d3d7115e97c83448a17170364d7342b19f7f1eb8a28907ae0dfc62ea5b17154d4ca3a91a3b61db1bed25dd2b9436925d4de903e559441a7cb80b464ad873227230295676f2ae7822ea85f30c88596fa988e05a60b8d53beda03e203432428bf799561186b1fc1d2c499daef45cb555556ed52fd8ced0864814bb27616171e95239d1dcb3bbbfd91e5e1f0d876cc6ceebeb8be145ee063ce49faffd41145db908b13dee8df37f8b01d1a800f10bcadedb5e8f663a4af4c37a0b09f9e0b2e42dcd4aaa901b6781f5ed8591ede5613241d67c71a077da204ce912a4db8d5d083e405abc3e6ec6d5781a9499eb8e2427e7a928fbc0feb403b797f1dce6c7a83dfba45ba76af2a3231d751bbc9e1f7d0750a998b3b39df2cd0fa485523b359b93ca56de28087830cf984559a899b0d55a9ef696cc60b0fb2217da1f7e57fca279b7a4d5e948d1cdb7fac235445950b0fa7dd9b1284fb09ae113ab9fb4b03f130114f1091a471f185384a0913da65c9153a239cf69e5977a387ea9a3f1c665acb9130e7256d40f8a8e029554c047ad63eb9bca4198b45f7b03e8cd22d1ab05fe4f30de749d97fcea394482cd4c2116870b009d1c890ac6f5099d45d0c37909d9ae58b0823fed17137eb7ef016466c1cd06a"""), TestUtils.hexDecode(""" 430B1F46E87DDE9A3D055A7D4D6AB1277B2DA6EDA642896412126391AA2B29AFD81C246EC839929F5C06749491DC4D81D58CC989D8500B6879E8807B1C3AA0B199EB599AEB86B344B77E3DB1AA034C938D80CB4BDCC29B31B710F57C7E491D99B71E97DD6FDA01A0D8A54C7481C2786F64FFC53AD358CF31C9C875ED278CEA03F2BF732372B19252BB9FA4ABF465FA2CFD1C08684D10582B410A8E012DBD407C5140D97CEE768C6D68124B2C84113B58C9A2AA67093B44CC3B6199FF1EFA6506CC28BD30BEC4CEA88411A491DD948DDB09ADFB92C40CA50E709840BC1F107E0CA428C111EC4505C5346E74AE4AB5647C1EB80F9C07092F8D39A975C4890317F9C0EF474110AB941949029BF39ADFB8E65CCAC0360A3EFCEB69D2BD805E4FC8D0620F8E039BC046DFEF1ADB03F5995FF62AD41352D479084EF3E302578B83332506918CFAD6E3BA701C94B0138DF0CF6C2948049274CE61EE0A64E756306273A02D68F3C405883F2F668820356812B2DA3A32B9FF23608DFA559183151221F83DCA18253FCA099FE24728F302C8B7808D7AF978299F3EB853A8BECDA46B8657598BE9ECE8A02DD4B25C593DDCB436B82335EF9C6A7B8426B701C66C9EBBFB3C8405A73881DAB57D1664F3AEC6F5BA19155D89A0A80B5D01C46BC79E1D4338A50B203397CD4B16ACD597A7C77C49917E9FE4B0D761065CB89C758498868B14BE2B6FF758745AFDC535EAA605C3F97648034D2A320264150278A7F1CB114B977C9D6BC1F29295CCCA16B23B7709D5608E4095E41D08B22AEC6289ED402414787062B0DA2387B6DEE76B32E42C51788B65E815E089BCF92D778F49A9707D37FCFBDF8CEF953A48A4201FA0173529BA360BFA6A77200F57FD5245146C2CD7FE8882670EE6878386D06036F0E1BA4B728CFB75806F05BA6409C514731B0BA8DA11015A63A8B5B5AB8C69703185191D12C5611F1407E8FFE3E50FC39C3310EF4091BC09FECC11D3AC107C696EE89F74CD6147830B4B3A971A0027747B62C528F6D858D1F9E67F59496C6B4E9E03FF0A598B26625B06C79863B5F07E265A40175E1A6D6EF3F900F3C4A28AD3E49D4D0B7E4ECEBB79244264474CCBFADA43FCD33F4FEBEB0F7E5928479F869D6A0FE52EB0CAC1232D7F674A057DEC4C2248934A40F5E2C9CBFDD53F71FC3BE06E48E13398ED426D8D3CC82118B7E8E5BDCA248380F4E64C427D1BF2384F60F6A07F01EE62AA1746CB143F26412547E7EF0E8FD1F2DC606F3643DEAF330D81CD6309465F9ED7F34D9B175FE1641D90212D4FFFB91CC300E7DFA0C555F7B35D2AF6A343D1467436EEC7AB95F2C34010FC99D66391377770A7DB8CD4D5C6BBF931092322741929F790E037318D6ADB74B4768C11F0E4674D18185DFB3D051725F93800CD38F58688AAC747F885908804D6CADAEDECB43131D75B18FBA2D4BED8D9BCC2156FB23F8F6378C622153EA8301300D0FCDEF1E2BB4E6F807784EA0171E95C372EC19B05A6C7B8DECE7080A057D29CE5A445A83410EB83B174590647424736A3B6967BCDF8A416A51202CE3F00E4D97DCC2C48A78D12CDA98E94A9BD6CCBE09DAF8085304F6911ECED3547DE9512461E16721322E4E6233BC7CA360A9004DA5AE064514603EFF0DF4E2D8EB04E9574C59F3AC14726C10100C688203F4960197CE696730AD7E558D7B939E3E6E7EAC4E70A7F6AAA80C1F1546E282B5CC7AA193213769B137C7F450AE5410817166F29F2E4E7E962932DF282A9F08A1DEF3E19C251F95611DDA9CFF4E2FED873439B45F8451B9AE06C6B2C698778BC4C742708BDB54CB35B686F0E7FC856CDBF977AFB663DFE44F7FCCE0E0555BE81EB28984BAFBD6FED3F0182F78A1396AF7B7081280864E5E4BFD7C52DA28BB5DE5FFA211678D13D41BF825F4B21BE1CBD29719ABA341E7B0C3F101CEDFE2F709E4DA4B5A6D0C021152AB546837024F4DCC4C45C132A038315A0F1D69AE768F70606D070169AE0818685C4BDB7341BFE15AA0455F535766FBEBB50875246A6DAE86C7B9F6F3A9FE01AB9928A99C13E6628431D41C1506381A63FAAB57BFB3B180F5D7FF59A434233EBC5A659B71CAE6970CC838D5FB638676216E3B16E8BA6C01349A7482AAF32ABD17DF7FAB8C69789F0194022BC4E62B6A6AAA4CDEF13B1E3BF5E1F4FA69F82B1EE3FDCC16DDE1106E3D2C41F6E661E33984DE7AD6021EAAD3E64D8C9CD7B5CB538AF88DB82FA048E5705EFDAC0EF479827EDCA0255BA60771A5EBC716C690CD3AC840FB6FF462063503D68C199050BFBD64533D94E093A47658822A25D54CBBFC689DFCBEB1DDD5BC6190B8F02C6FF3D001AC63729D35C8C50FAD3DCA2E67C5CCC6A8799420B159C7C5CACAB958B423964C489DAB1982A4E2222D700BA5AB772C4A11A44FF64018AF477D054217EAE28FB8E37595941FEE7AF87FD44960A144DB0CE2A44B33DC79B1EE31CAF80DAD620666D0ACEA76841EEE6CE81C6FF1F6D1027502EF89F1595065CDEC19B30E4B5314EFD64031B3B9DDFC6C95A4943247ADF7E4C93350C241ECA71260A454707B84017C5EB7AFFEB5DBB863A1CBDE0062C662308A2E824CDF6397863EF78F62319E2873B506F8A9EE82135B803025D962E609E006961EA3F7B67347518E70D9273893D79530F67CB678D6A8D28A0342BAF904BFC0A69AD575CDA4AB73AF22B52AE5D58372E0C26795CA96A16B8461AC61E6F68433ABCEFCBC16B857A89C475D1A322D34266539A17D485B8FA356EC3E154D37BAFC4CE75829FBE8BC823FAFF15A49F847C286F999A1F2C12B03E8F8A4C34A97588D91971279FFCB100EDB943E636F78ABFBAF88BCA5C55C935F6147E51BF798267E1350D2F5E3F74B339F6EFE86208C5BDE149C5B71056BEE748D06614AFEAF6DDA2A6EFFBB56B0880AF9B201B3C12055D292E3BB556240DD031C29A67BF244F59112BFB6865EEEC1DFE1CDB1E27F0A9E3372638FE4407099D0E54E9A188079C8BB9470BE6F63C83612D80BD60C21B251B64236E5CAF09A11C12F1A5E94F199DBC7C9E394C0B0E07A583E707E5241B8FB33E39BB26C31929F39316F4FDE206493566E17B51CE635420493176D8FD353206EF87F0994F039DF8F008AF602F50D7F9C0051B56227F3A2ED20B29611219FC4376234EB900093A81389ED00991272B739389F1F978A92A3E41F0A28985D697C01240875AC46A82B2FE94004CBD7B1E7594AE38A9DA0E84FE7E122482BB391538EB8E85AF9DC022CB32CC08FDA7A95165725EC29A0F824F97F0251BE636B57E0791A7F50EE190D45749472B29A674239AF95B373A40A6E0E09C674071186B125EF5AF72CB434AC0AA990341F063EBFE30963451491474B603733959A23A6D5B8A378F15A5A5B9CE4BA44BAEF6AA531AF5097ADE73F64AED0A541784119665F548FAEB447DE108AB74A74893017F0A1AF84AEF0730B555767B0CF6AE502E7693374D2E01C54C64E411AA93C96DC5FA010267B387299D4376FBB190E1C51A560871B559FC800D82ABD119A5732B50270BEDBCC8A636E7499149AE0E47F736FDB71EBF1995D1E8BDCB0EE96E732E8C2509F98717C3D174C78A4A2BE43DD89195408CD300505A219305809A1BFE7294BC2EECE6D98C768A8A1E0F74B665EE3D652AE8E008EBBB11F0D2148E4E5C93D7FE0190D27B3EBB7D2194BFBB624AF3A894CEF7AED571954D006824950A981F4ADA72BEAA0D820C5DD9BD519D39BB7915681F266DA66D49BDAB9E55879B953A7332F877DC5F5CC7BB3C9E1C1F2E41EB55EFC02A450B5142514F1E06D43E48FBF5DC80DF241169D5936432BFE9BE99DCB17293CF968A17F3111C884635EF2BEDFC87DBB80BF25EE9BF57B55CFE635FD99554F5FF2B4482D1948BD282FA282C48C0302348982E30A772BF14195CAC7FE39F836E6238EB1E1FD074E63B9AD0A8D37111087E47FE5D04B62DEB496353457BC76C53A2FC9D5AC9AE6A47F632E6D45E08786DA128464FF2266BFF92B5CD89176A19226F2EB14CDEB331C497F1836FB6C0A117ED6BAF95E9DB8254487B0DFA7301397AA29D95FF2065D851BD302B747AB47BA0AF408B51E4BBBF042ED1B2B604EEF4C266FE243261515778BC9451A8DFB025FA3212E868C3A078C7CFF65077DE94E50ED90A259FAFAEB398A94FF15C838EFA7F49904BEAFCCECD8C9ED4E014EA00C7AEF1D437DA306E8B7DFCE536912C169BAF0A3B78A643D6E210E5550E3B2BAF7EDFE01E721E3D05BAC1378EC1DFDEB2E2AC0F0BC368E0A8CC64F375DFEA2FC20CBDC515440FC2ABBBCEA3584E103BD686C5403EFE376D44F5242D35C9F9D35E1A869FFCB6657823EA0D4331ADD5CCFA99BD6EB3494A48ABBA7B7ABC32ACB8FF00512E1B0AD493F579898847E328C06FE05FE282F8D4AF48A1AAD0495AF1AC7354275A6D45AD5A7B3F6787F893EA558BC5D4ADDE1F0D265ABF73C86550D25C00821C3138B385448E3E02901E2E6EBC6A0F211CB6F22F8F865F0DF3893B987DD086B6674F5464ACE18B9F0EAE948667B2FC04FECEA3E2B7EA6B869D5F66D02D4DB124A59621B96E0DEFBF99A91AFA0CFD6D5A5968E62EF42B4C8908C3719BA0254929A9A183D50C566CE4FC970E047474490FFB07F576765AC5286B2E0FDBF1EC56A8AE8E6F560C69614FDF5C89BA53B8B7189E6388F7CDF7B819F78F3E6EA54C40865262BD2C8CE87284FEC36E2E73BDB8AA9CB5283272A90A6BBBFC3F7FED5F124E8BFD770B6254CDC695FBA0D8627315370E2CCDB89BCC84C96E20805AAF087F9E9BD1A189F4C6D66A6DC3FEF773788B3B57EF876CFEAE1F2C876CD239BE3B8A94F21350EDAE6C269698CC66BAF90B3641593F96399C71B2ECBE50F61B5D6F37D47DF702A9B9E47BED2824DEB19ADE7D7D8830A8F610088CF4BD0AD22A5A4FBA767D01987688BE710235A74129666FF7917B506A18E6B5D6166E8B682BE6B1946A4D4420926FF8CDF2488EABE71EFA7F2536B9DBEFBA08BB9E94086F55B1B991E18E6023E6952D4A563F2420A1536A1EDDE119E5779223CB712AB5C0BA4F0C176830FE523DD8603F1B316E128579E65454C2BE62C922C1DFE09DFB47D4497CC552AA9987A8BFE19C44E207397204686C718A0936145FC102B8A7111F74A421226AE016EDE658DE5DF9D3C28A247A87F2BC6FECF66CE7A6699880E0871CDB6F066D2CB3F9F625DC5E80751DBBC85982982E2EFAE3AB8F4F1EDA0D13C3B65FD2178E8AE4A712B521B7539785BB058176AB4396E6EFF2FD9052D4C6AF17DC30F50630233C3F05C62E151EECE13CE124E58A25F0F3AB65033ACAC9EA6E41CB3FA435D367DFEB0B9C9B37414CF32DC85A3C43087A578165C86D100E47DBA1FE7061111AAA961E67ED057C715974D3144912A58B6DB22D51BEDF6A8646D810190D91B61F0776DA00C8B0BAA7A83F4433F357E758F5AE8F278119908497E717A7AD25B09EA7C76B306A9A3AFCD9AE6B4F64016D5E80BD3FBE2F5EE673A7459B03AD9356148EA83461B66716346DBE85678C37C932EBC53B033A3F46DC28219880CFA8BB5E15F8862D345923BBC179FD763A0F943FC56BAB69F26C0C15D668BAD923D7AE6B35C07621768F9D972E2D6F46551D45E3FBBB577D13F01E8C1AFDBDD2F052E931C0529380F290FA1DE8BF5A11F82612943BAA2C0D086EBEC84069B271AC8656883F686C67B1808E27C860ECD1B95FF6CC6E6A5846DA29992CBA450081B8C37DD4911470EFF281FE94F10636A29B790E41EA6A342A5BE79CAF575FE9B0147F2EFE02874BC8A0E136A395B42E77D9F18CA4F61501E6C1805CDCDC10D0292593481F7E0F93281D0456EB51F6ABB7C379C028890F445D9FAC0D96AF68CDF6CC879A406CF2F0991916B33A72A193CF170B45AA079DB1BFD4B4126FA9AD3ED13FC98CE4C6C3C30923C8C53BCE1812B21BB644ED3A0CC0596C60032FFB1462DF5182528553AE865BF87FB7C7F61D1FD8E40D830B8D8F54924EDF934D1EBB88DA90BC59EEF1F6BF9FC2D17D8E9E0E39FFAD22EB84EFF39BAA70447B124E492D760E55D6301DCDFBCF9173FE293AC4D6CAF2E1964B32973067EC76BBECC65113C1FAB85375D92CE1436E1D1B205A88202B304264620B282E62CAAF5CFE1169EDAD9459B15BF0060C5744A17460F9FB164974CC55B3FFA71AAC13437BE58325E5E27E151C71D195F886F5630925D441A54695DF23F64C6BC3B0CA83F0E88D01BA4DC748A29F42AC2997C2A21EC258E430032C09E73E73AC2B21B55E1DFB2DBA281426620A0545D2507D1E96A3778C780FE77F1DA3B615E1B0D14DE8729229472E6619AB3B67CCAF21CFBFFD1F237E780927F147425B2142BF62CAD6B467A10F7B3DB922F095A0012EC179C4F8D5437AA8024F13A2A485E8890940DB69FB719B94B7D2629D277B593B94ECC744AA4CFF3D33D2250236C74DA057496BEFDB961B89BD6F44D581AD7A28524A6AF2253FD27530B7FF16FB5804FCA7E44BA2A3AB85FEDEED837DC130F533E8215B3AC3F584A2EC0E9B6194F97741EC050576E16349AD852DE8AAE2BF83CB1894107299F101AD5A2C05EC590B2CC698663C44FC0DC7F893F42BC5A2DECFF2FAF46CC1C00FA7294A0184A85CDDA2B1F38A89B1B17EC08555D082411A4CAEDED562C9FBBC1F512118EEC3BC931CC91636461151BDA454C4F029E01231BF170EBE17C526F3D8F705DC46560642B1AF36E3B401325A6CF59B88BCD4B3242D676FF4066E4252ADCA37786CBDB340DD81C5DD0540992F0B142C5A18D3BD1070719AF996E3C3768C3B234D303E6E9850B35C7AE52496C76106D7CAE4CF8ED01767B6DB5603F339FBAA019B08FA35E3DE1129A6A4D578264CF1FC8A1DBF218DD72B4865214DAA795A00505D4AE2B85E90F589065D65FC60CDD828007D4D3A4C084C7EC159C5D86817860CA03545FF74F17AD8570B2ADA55ECA12BFAB5C10067A086A34A57AAD8694C953137BBE901F8D3DEC27DB5DAD2AC96D56C312E25FE48BDC889373ED252B4F88D32DED6702B58D35A1FB40ABE2F2ABDE21CAA5FD0F67E7407A8"""), TestUtils.hexDecode(""" -8C94308B9CAEA02AAFC29AB18EC01929A029D49F06F3BB4EA3110B1A9A415C77DF646A68302FFB4D853F8B9AFDD4D46B30ADA30213D763551A2FB98F690296DA77F08B3A1C2363EABE33DB1A891C331932EA22902277F44D68A0001D339C1108C3815A68DD0F7396119FB1DC888E10E3A95182E5A185E9CFB0F76CE84ABC199F7D58C7DE375F74EBC6B3338E3F6C51070336A1D513B3BF6FF4250313A52282D32DC616EA4B2B83A1861024AF9ABA17FE0159544800AEE0534511D9359415A66A6D79C2B3173B6281BFC3C96F07F944CEA0841DDEC3BA1ED9B337ECCBA219C675A13A1466463C128FF79E5C8F1BCE22220E1EBD1A071AEAA32E5506B553176309E1EF15AE7C15BD361EF6676046996132716B5391E9C0350C248A70A3552540963858FDDD3456FDA6707B99C120AFD925A47E4DA492DE65DD041E58A881A8E4125C3CAB474ED7D172F05FFAD0655FB7729AAC1C951AB05892198D713657936808A2E9795488F3F6E3183D0AB6B69B3484AC7B9F3C2AD65AAB9901992FAE9DC1E585D9CF7C71B4C7CEBB47EA07D534F9C869B114E3B0BF29ACC2CA60B91055E98643E7F16D3B4FB0477E3AF62C9BC5535565BAE2B8B276B33DFC50C3A14A62891435DB43DA2861154C654A4429ED865A373C28FF41F0C0ED11A1AB963838FF975EC9754C5FCAE3BAACB9ECDD920E365964DC321147A39653FE4B2F2D1EFBAF8D82B2198376C814FBCAEE96411B9E2D958D64AA731BBC1D6174D6EC139FDC73C9F3AB2886A92E0E82C700DD5A83F5EF0912ABE4CD30E0E3E9C8639C4B329B639DE189D8AAED2250F3BA74C381D6A4D333EDBEC2D1511B20A8144B42F0B5F674F4004F39CE1091BD431ABA3719D994893F4CF798F3CDFAEA9ED0AD5A3BF7DF0BF7E9E716CF2D3C72B17870780C724A0A0A2EED8E5CB4E8D15597DA311A4923BC8F6FDB64B9CCEF2C95BC026994ABA7C743F2FE83D5E771ACC2B6F8AEFCF6E1C7360767B9BF995778F95390C303C88FB81447EE993DDA266F031B9E4907811E3868F883AE4175D95C0B4C61092FDAFD2A41514408811828B3FF30150239C28C1E3E65631B178FA56D019BA08822C038F718BAA7A12FEF65C08A84E2E9D6E292774859574686AB024E2DAA6DEF1BED248EEAA02E0D28C73ECF803A250123636E6B8C642A10C3B8B3DA55706E17ED5EA96B80AA9D99E450513E16ACFE6A587896BF17254B4F420EED062775BD74CBC09ED7F925D10D34FBFB9EEBBEF6DC29ED87BDF01DD57EE8909BC0889BDA2AE430D8CF80E211EEA8C41DFCCE7DCD197352F60CAB92363FE4681DAA0C8F62ADD5FB1874151E1EBD8BC025A8341C46D335DED5293F012E7E9C2A8CA2234E1E5970E6C51C6711ED16494472205878ACCEEFC98850E3AEB99F10B6A07CC3A31CA742F1F93B4104496EEE8DBF0480AB395310ED09D8C7A117AD8A9F5C4A3050807A600613723555189F22ECB98F01ED8E69D113A03923B9C0C8889F094B30BC16792565F3CCF427EE9F0BF24AD436DB5C40E6FB66BC416009DF2F4D422A9C719585D47B95BF274063B64540B672A373073FF87291A62C7B9838446321B71356E7BB5EB096E9EB13B51A50EE891A2412E2117A5275DB0265889D74D9AB9FEE8AD1B039A0EF471F1410AAC97323E30DA2F91FF22D33DC9C8379211A404E32EB01786EA0CBD618821F710F093DD276F52A10416648E52879ED2A7FF6821EC49768D687984397D532C20B7050ADCB4330037D1EA1108B3A98ADFBB5457B05C8027E1E9433BCD89ACA8A84B802634C0759BA1AC6C144097E0EEB0A8E1A3A64E3E66A09D443E49ED53FA8FA8A295AEECB459D4CC32109EB999A4BC3CDD4D744EE7D9A73F07D763B8F80F4BFC63002CA3EAB87319EB69DF4A25FF1A7CDB72A74CDCD2E49B5A9D780ADDF902B9FC31F90AE788AFC954074E010B495885153DA0CDD15B26C6436D077A040165B6454A24B2E2162F9FF31B9C4B9199934A7A1FC78C68704B9BB784B0FA15A84AEA9E70D51000D7F335E450A026AA935533DF695F471739D9924D452B3C3D84DC597442A92E9A5C950C72B80138BD6154214720D8F19EA7E99328770A48069506F22869FC67129656E26E8E85242FB6E93B466B5277E8FB8B235A221A86A1191801B6B2EF236DCF910CE2FA399F8CEF28F148E977B762C8A828D57ED48C95711A479090255308196CD168B3C6C49777FF0E4D2319B1C44954E9A20C07E23F79CF1096DAF01ECEF4D47BA517554FCC1C6D139CD2F9F5754B61963DED55FA7638FE20041D4E689E6256A305AE0BF096EE9ADB9A76EBA46F5183575E8CF70CC6F69E5AD1DE54159E5339D818EDD92A2B9345AD759DB829C6BAB42398922788DAE97AF3F12A4354014F147A27E267495208978D736C632A5F0270C561353B27BE23CEAB57AD68D02F9AA94F301D3FCEF3E6E234BACE92F5D8BB1F975400D0D6B22F1347DB350CDBC71DB4519BBA4FB5C243A91BD0DA06C1155514E45184581815C7229AB66C921F2BC95655CED4A32D128FBB6B8BAFF83708CB49F69502D90BCEB6BD55DBDE19732098D1D1C1A26C74FE56DB0470C5E76BC6F4927A34D6BD84E57233E37127146295E5F19AABB77F9A6F90D702A58CB0EC0648AA54753AFE9140A9A60EF9814E43A916F07043819F09BA02A7A84525C34D3492C67ACA7C5489B72084CA7D1D5CF2A061394FAC77DCA111DAEBB9CF6C1B270A027F8D2EE04E0BB68D6BFA136640D04366864213F9EB3406A747B81EAD497416880A0CFF50F95784C044E58BC0839E6D36FCA9A45374A4059C812EC2B47AF8FC3A99540A62EF1C4B6D75FED8AFE7DCAF37832A02B3BC0339CF41A6F42733A584DA80A8CB328A5E6E59848DC23A0C0332F529853B138ABD0D3F2A8D2FEBC1D71E249E1FFED726E4664FC3020566BB769D4F3CBC8A735FC7309AFF545C3F87560BBE3D5016FC99CCBA9F5410030A86858F320DA5058DB5A188E68164E2349EE036B6904E5229920A7580206D3B75E89A8EED7ABF650D69494A13E83F37F841A4FB2A7F1BA538D40F84F25DBC0EC78DEC1B5F29F1A27198291365257819922F1A42104C721ABC95B2D610B0DB4576401E70B1760184DBC285EDDDD0788DEB108E824A21B8E98F0CD8A60557D183D16162F32C3D7C7353C3DC402A8B96EE8C5408A4D525517F76EF11238DA98E8069402FAA2A9A64350C4AE80F033A52209E66FC36F1802552292F706BB6B703C8E1FD66DF7DE25B4167EBF2E6F8189D8AE114460A1B0C0398CEE7BCE10D022833BEEFCA70D5BD174446CEA2C23DA0426303D45535C5F7E81838F93979DA4BFE71729373C426366787E899CA1ADB1C8D1E5EBED05315F646A798795ADBDDDE5EAFC1A4D6F7884929ADFE4E8EC0000000000000000000000000000000000001225333E""") +d3bed8aae32df74803b6961baa9a2266122e26fd3cfdf1568b460abf5ebd475e1764c7814c6a48cfd6d4df272ea9790c8ebf12fcf5836b0926d593e90828bd49ebdb997e79b79ea68e66f48dad497fbd3a6c3e317162a3f46a4dcc45616be6cefa68210b11fcfc9a906945d30297d1714ad28b1fc7b4c6cec5ece1f5d20729918070cbfb25f285a6fba5e195d2dd75a8c62f581be2d75607b5a8740dd2339682f31230354ea03d0e7cf945f167937592a2d2dcaecc5cb0d36217453809886151073e5d15e6bf7763cce81da19738be3a3bfe96788a56c47d2d166efd18250ad525b4e9e5566c19287ffc277d26a888d0b1073242da5e92b23556552b841ec3355e14173090649a14cfc0134b7714dcbe52095d759d0eaecc7d26f3f12494e4247435d5a6eaa9957aa503f710f8e2844905664905de2f30285e774b46270c58f45d267e850e1a6f711b00e5153040ce090660c97b14432c27d0dd50c0585a8f4c4e1e15d2888a90c184508cb400af2f5d3dc0af3eda99a5e97d0836d079eed38aa6e3e4f724cc63adab509ea5f28bacf3181cb7617a3884407a274824742623eb441ffe1ef15bf6509e7b2305b5341c7a3d73e5dece5b9ead5b99f7e65169ed1673bdb925b52a6b8d524ee37e8538e6917327a8237bfc3ed3f729cef6840e75ef1cef707fa10009e4d5c72561eed18c06e3be94c579f6629373af6a55019c3faeed00abc22deabc59dcd87ecd40e9dc0a5f4b7fe1d711990fc8c03ae9fce980450739c0a441e3512ab7602038dbd1352fe0da554176a58c47c29111eda3d2b9560b3fdcda292c31621e22bce8695748fcde6c81a1270a1944790c174de8a18a505543b459932c6f4228a00984166ddf33e981c2d3ad2e3cd9ce87aadc57e1e437029223e729a99667ad87ca718db5b133a930e73dcfa2d37ad7580373da272e54f62f3d13db9a4bdafb1922145a1624fa96921c0b6bb1b3d7a115ee58dbb2872db79f4d38255c11f160397052aae3ec34921bdad97da72714f37eed4765769e996e45974961e7439352445147dec09b1bd02a776c2c22be612a723b8711f8391e4918a95605fdc866ed64cff6cde9baec4eb42bd880dd0265befe1a33f4d2c0900627f0c7727228aad47d0922caf2a7c86d70960ac2634cea63dbf5d33af04cb149eb618f9ee97adeeb0df8bf599358a82ceeeca582551298a63cbac754b6975cebf7d6e78b6d5ee24dd6c78b51b022f857e230fab176446cc2cbf6986caf8e76734f5280f463641bbda5137fab4800c58f0e1c4dfd45d5813df3f917666bbadb3547c7381eb33b00fd569d58dacdc95a25962024786770aed94d97d4682f9e94d34ecf09e9269993f547901d0120e5e969e3f12a5ac219158750ed0f381dd72a91ffce01f2b612decbef0fa5441925195b813e1273dcd9988457214c9cc503206eb4756e46f900cf2011963e761e12a3774381b877d93aa1c7892f512fc0eeeb225ace5dd7816b919d1717b6e4a34dbd30171a1d036d9ef9d37ab821bc03d881ced0f2aa94eec2fe0b1ca72b7049f749c9e86ba4ff44afdc90931029fa59538014c519f76264a2a45bdab759da02761303ece94fdc2654cc9c818f4af979dad60a9506dd381d150a66e5b0fbdb6e734404f4cc71e6b4e7f5690556d28158cf049f8ce6e4043a82d1ca3c15e480ebeb7e211b2fb00b4bde2733f03f9cc705038050769f9aebb5a1ffc1c9e3d05132ec1ac7b55b6b3b127ffec67cd6e3a1649fc9313e3625c01ebb600c30f622f8bccea15d6f0388439fae057fb1ca54c7aaecff7b1316e74273a2c66037926b246626ea2321c311aac3b5b907e551d7b03f069ae354ddca45d1e5ed3023c576fdfd1c1bce9d8edad78acfde17c9e4d83ba9087d889dee4bfbcd8908a41ebcb4738861abb6b6d8e65251dc4b7c26de398c687b30efd895069410e58d7bc2a105640866321a83dec80ba7b47cd64b002300a9fdb7e7648c2d0f9784ba55f837904df1fd1db46ea82802d4c3e925d4c3e3cde9b9b6063d303d410f3e917f10aa0a18fde5849d14d0a79d71a983f9b09a41e9a3f80dd36e46bdabe65a1d40d7e53b94aa9677561a549aefd98826cc32f6dc5961714d9cfbe913dd3bc68b8891017915066792cded38946c0316fb0eb6d89c10b84df01e0f910a9ce8fa1cbde71edb210918562910cb540d3eab21c8c8e43151a333c516239370ea3dd42294712d6cb920b1f5469e74fa82d4bd7892cec246db13f3f37ef0e980e095faf06e5aa417f5e16de83c8c1ee5ba8340d10785e1b10aa7573dd6f77fd87eab89a014449210e285fb17d0ff7cc3a2c61e6485c2f2e81fec821abf0c694b77f71a91790037d0f141cfb4a74caa4125dfd7236251526a44d4ffaba4589d5237fe647a4082ccd708e27e82bd28597081fecc184a5ecb2d19d115acb18d9d463e3f642e2e606d3f6d496fbbf19149ccac758dcfe8eb53378b65608940925c23754e0f1a390d520f26c4cc088c091e55b3cc475565c0d166265a0396c50d9983e3433bc5527e9fce7fca2bb408b39dbf96bc183c3659f6e8fee0f23e4230c0eef54ae9581b3a38436810accd7c37e83326e3fe7ed1821393a11127027821bef0b96f58a66968271915c1cbcdbcbcd8c62a54bee08b3cf143e859564b798892fbb9c430a6645bb4c8a2be76c37afaa67b7b5a621f987034e88b1608de8a0a09384d85b0c2c872cc2a9f8ac348c5f864d28558f6c6e4523f408586490a78ef95ecffe5b8fdbbc264944869aeaa3ef428d5cc5fcd363d1003239a6651532a442935e674e3cf1aec6f8b32e32db762bf2512efe763c88b9bf4413ea3344835b96fdcdf71c83afd75ae5925c3e76b9afb9fdc72b17f41ec516ab23529e73b9639f5ca42457c5afcc0f2add498456e1db6b3e775ce48753a9a70840c45dfe7cf396b627fad775acd051829f409bd37046bc4cbb57938cb490891c3aa6a04f60769e04685ac1167c9de32fb20cf43f730d8d09b0d74e7f80aeac659509d7941460018c38eda19de38967fee38f7e9526babd21ca1be031dff0591d765ae30361fd8c2a33bc1dded2c43e0e43533a55e72bf1015f5167c8d6bd5e6a19cd4e2ff19f1d47cf42fc361649a669e4524c731bfe7bd11c2e4ff599724de173dd6990f30db8d3b2084d2d3aaa0c0d8b648667b951d510480a28d40c938b71974d749e62d88cbc686eaa31e7f89cb86dda1e778a167610e7bb3cc97cb27f37ef9121ac1baec0a10b40211cc314b02b5df4274acfcd13de277e470b63c0f0fa387dced40050607517a979ccadff817383b404b4d627d8e92b8c1d8e9ecedfc2d344c4e85878b91a4a5aeb2bbc9e3f5010611121a23333a42546d6e8e909aa3b6c4cbe6ec000000000000000000000000000000000a1b2b40""") ), new SigGenTestCase( TestUtils.hexDecode(""" -D9C4374117AAD1691D8CF8789E3E9544C379C5021B04E4BAEDF25FB2BF7225CC5530437B7D76D449CF4749DDDD18BED539BE7661D0803A4D7F379DFA3FB293A0B1A5F48C7818986FB379E41A921DF4726396F2DF788606A8C8C5B4E973968545A66B1467245A5A9140C7ADD5083090B658C7654630272C9A25C1CDAB4DB6521DD49641491664C1A06192B68420970153A825DB263249429018088C13289121236A0C022912276604194109360D52948812C93004209092142E22B52C24900DA086248C940D01A62D1B948D84A8300B868541902C00316D8A306203C47003B4440BA6201382515CA42489884403204A00338403B72498142A5888681C12611B116A18C16D5C8248A316815C1630898464C4320403A731892289602424A1464A490868E2B64101146E8B884012270A4A242C020522C320411028124A868C04358902B6259A244A8C008D0820882202320A3442E2308E9094900CA730C44046911261191708D0126A81308DA2204CA2165221134498063264046E23B461A1162A1383710323421C042A1C840D840886921070C0160E03198AD4A2811A484C53200919079080C49009400198A885583682931882A4184C530805D8C648E12272C3C80944348ECBC650523610D3A481D2244121412C8C028D52B4210A244C44B8641109099C440AC2380E9036082016645C30314220725C48440B3306A2C24CC0B689CB26801CC388D3306E1C9261223108E282680A1852639224E3322A093260C8C2842085485B240603830511850903246E61880509A851011500120592DAC8419B826D4832660C2121C3166882084221359059389020C20801824951808D101406010431938201CAA8858C44504B4680A3265022470ED028500CA60520928113232A409449103865DA808DE1208E40B401C844261B808501294651922403490452124090B48914294E21858500A565DC2012193584C02668544608DA82451346055BA808894090A346708C4410DC349049A86D110742242288DA388094364181188C4C086C09150E0BC4290C070083422841342D122508C40865C8B004121631C43430A044900C4822D8086EC918815420214C8821A49088CA320E209361C8B8605C04529228900045501C0829CB0646C0180A03232542004C11276E0B448D02A7110489005CA021881071D9A201D0028CA3B08C01252064102652946401116E8A002E0C05465A186D1418405C464C1A0732CCB820D28420C224710000628A1088DDBE8BE20BD3D9163E7CD8E081F70C5EA00959FDAC57B0D8DC10873C27E22EE17981C4E689700036D682BDBA68454F9B7C394C50CAC4DE6A8CC734850F95764B228134B9AF1E0BCE16A593EB6CFBE451620DBBBE3666E3B248FEB4E5306609AEAFC331E92965C0479F86FA1AD47F1C4A793B2904949ADC0B4FE939DBBCF05066CD0E230A8E485C26F41533BD744AC8E442CD1358991B0C11A90CA17697CA7130FBF44DDF626B7F4D2FEB954FDC64B1D3EC0B72AE26B90B5100C649BCC89172FCCE6558F28EC5B764DB91EBE971C7E881D879956210BE220D6607BD9EAE2C72C4B413D8DCEB01F386C0EB8A1F8EBCB4053B6BCC383303DA64635B9CE7892662F8680905429617EAE18C58DE9380FB69F558FA1B706733A1B7B324B92FCDAB07438F020F0449A70B8F602B5A9702C771B2B3A4A906B2D27CBD824AC5A207A2FFFF1FF1FAC38EB85DC30F3F17C799A1B8E71D7A69D1D5046C73AFC04DA3D1F6487D1CD41C4075E7A6BAA11048273A416B86578047057C6027F89E695C66A6880AC8053D5FC6360353F336F282281C32484840B3D7779A2B59DF42467C42100D382530A74613E147EF863FAC5CEE1522871427739EDD9E089C1327E10F39ABA9F27E66E074200DDCBD31C7CAEE7D4967D8DAF612AA0B5123A1FFD4F8EB379CB8097C3A49E7F45ED5872AC1A579F41D1A8B9AB4F1D0946A9AD6C2FF429385DBFAAF002E96D85DCC93978115CF1BBD5F69A54B3AEC88FA74EBB175ED930A5E47EF09138C0986811946388D4452AF4A07A1E8983333340F9FAF033A87C56855C8975471DEA335CE0E0A57D36E43E1FF5DAF699A5258DD22FBEA92C7F7D7DA258D250717A6EDC2082DDA972A36CFA6552F4397F502BA040145207F874D4E5B07222581646132A5CF5D5DE59F347056F5A52BD89C75B7EB3D48E2326C02AFA1822716A4B4D109F0DA405380BCAE4C7C673ABEB898DD21936195D3F3ADB1B3F042016ABFAB2670A977D1729A605F201DB816606DB7D73B1906C9C4A49C1687460E2093B51ED68F7C548F84C01372CB97FA557B2D7514355E4D0F77D22C0F245B6DEE89982F7C2DF3EE89AECAD428C9C6CE962BCF6DC898EA7AF0A0065EB4477771E97DD30DECF8F41B1B0BCB5DD84C20F502D894710F97B8E93A6ED694AC69A43B6E20F7FA885997D23DB912F1C5336EE2050A96EF1F4CBE9BB50F977C9035FDA05E063928069394C18393E988F715E64F02CE6C3A70AFD2403E3606721EBCA72E9D4A63E3E11707604587301CFC4D461EE07D337A9A1C74870B67457C22D9E4EFB60A5F6D405A184F972BA07CA8D702160BB598104B35F0C0DBC4105E3714A32A789C3C19E3CE8D19AB71FF69514F2CD7C488D6F999625405E9702C38EB3C5B50F53766BF51BA14015FFA2EDAF83B13CAA06060A30C9D3D44BDA226905C357384D027E05B3C0837C246629A070AECBE608E743E330ED18BA3F8DEB7F09F61808C527C5695C4F3FB8DD5F376EF656EC4AADBB21234E85C39CBB37910ED7A9E12D04AF813D3D87A7FCA55CE6F86A53C6432F9C99DD23AC297B217DE1079EE21F467EF700965A326C82CDC548084EBC5F9D0C3B48F75771ACC1C3C45A70388A0C65764829274062989F7A209B71D4051F26897C8FEB6AC847763463A0858B0B2F9CEC93454C35ECD5CCB9AB987B1957849E1EB610D2636FA7BBD08193A69227A34FF2BBAE787DE0F9EC719A3DD04018D3F4DAA2047C569C6B5BA52785FB44F24DC548BEFF25B3E51C24880469BB9D0749121C039BD7FB831D098B8DDF213023476DABCBBC778393F02B4077B57D392AFFA2215587D934025D148F435C1B49998C937BA3D0E7463C526D08DA8C67A2C305934E82B648D4A8CC3EC162E56A42575E944CB711C3AB0474EBECD829CA8E678C10782A284485F3D96A1DB852FEB36BC1748EAD20A342436FE63124C161183DB1BF5CDDC1436999764010C2F57E55BAE6788A7D653ABD03989A6F515DB7A76A77CF3E282E83FEBAA8326B9ADFA176685FFA1C6F9ECFEEF97953685EF2DBE311BA25E2D76F3950E005E4117585709447FEF5F1ED198B98DBA256B4BD2A430D7CDE4052A36D87905A8124AD317ED4DF338CBD1CF26BD02680944226BFAB3DE9149CF19C2519F639F9068825C0BEC1A7572C70B948BBCC290B95B0BF5106A8B2CA8FBF9CE34599E633EBA37254C250438218AB1D2A3EAA0C148AF2CBA48DCEDB11FA3B5D873BD161D24C65CF7DA109D1B8CA296071FF706E5666D66ED10E5B1FD78D2F993F76DA41EE8A9299D33C2ADC8303EC322449EEDA11FF245D03048E5701C7763D545EBCF540CC2CB0E3A06265F380C622FECEE4E"""), +f7dca662f79909c3ddab57a31bf75b9d925ee06460453ccc8687ed15f17d9b3de688567d9057463268b74002ea5a1ebc35df84945f296a52665eb737350da32513ec98468356bd8519b3518b104422594072d906b1e37392310e089acd08eadba8e647a2bccaa8ab65335bba2d87e7ac2f1ac90996724fed92021ff93acf1797dba20442942de3a04824454521350e08858124186e04334562082a82b451598451c2020842341218878510c540193060ccc071011492218320c0a21022182ee3a28021880024a7050a9631dc2832118471242430121866d0800940c865cc006911086a23c72dd8c068103028d9040e144029131989a4468e139268091492828630c0200648142061286d00a61013492d5c302a6044681892880ca589a0088691486410463210314044868dd4c228539489422432c49650992831dc3626e0b8311c816d0bb404233291a29491a342711b838122a268cc8845d0008adb4872d99229c12804a40200993401200571e0987014c34cc0026148166824451190104c8980858c366894486422b6700b2324e04626241192a1900541146ec906520835828b366481462cc9106218098e04b951a4309284b628a1122a0c43050b28850b210c5c30501900811c096e83964581c28459b80414858d530031209130180664400802243904e3284554280452325219312a133364c9a8251aa2680a28229480600cb5054ab88109a52912360c200261031142d89251db062119126212a320d9b24d0b391164a20820374c6498908b362ce082290c174063246e811828e388455b20261c264508162288b0890113008cc69164146c13c7855c40852225294b969123a0886184110205888ba41144182259a271cac00d491081d8b229cbc02480a04c4300424a86419116100a976401850d24117009216400924048440ce18248031406c9004a110886421465cc9090d1424c124370c342452180281a150222426590248a613810c28050e2b4259b204e413281a1829193184d981244180684d8a26592a269d4100e90a2241c0541604409cc102d99287121a1210ac2610399500c156d0bc72919320e1a86699a4249c948064b2668492840c4222100400a03c67164b091c0286901470dd0221011a12d91448488886c084464ca0662cc384a63460004396c23c1650a090cdc06325396800242614b3249cb282d44385004889121a48100a78410476de40232c9282519077183a0691b23224116091c088080240147916415573a7a76b6e004d7d3fe8a894ad12949d2c0aa943f5a7210f31077de2af8e27d10ca043ddb29e828db0c39953bd50fddbbbf839d5e242f2623aee99abcec0edaa8893b5c79f1a68387d232995823eb46a1968173ee79bda6e849e254b0e5c63499b9c8e07edf0bca6f0436a4fce62b7d57bd80f49fbf2b7d4ab1bbf1ed004950616ab009ef6e935d4447e287d834106cf017746340e79c317547d051a8026a31c8868bdfdb6ee50c1645ec8e0aa9f716f42502d9eead700f29a60058821504dc6b0bbc9512e1af92ec73b7582676d2ac13f2c9cdfea411fca42f2fa5d286bda79ba0739b0522e18b22d831fc29ea101e835932861b705803a2abb60fad2185c076a8dd469dc8f80522fc546ff0226f8916bade8e2763f3182e431482bec626b2f18d1c046e19a11d79eae753640ffcde6345531dd557c7bbbaf8b727aaa3591abbedbd5f9afb8cf7ad0f645db4de84d91be8b52cb7a407624a0b13a2976f42aa40a1a28a1559be8c539df3d8124c5c111880a8aac2367c312a8914fbce07838804dc956763147fec591eef9961a9c71f11c71512355234c29b65d8a5b232116dbdcaf72d00c78bee6f8c5508b83b4981cbef5b21430ac2bfbb892817254e20c5c3d7611dbcc101b4fbaccc4856b37bf06fbfb231c587ef281cd7bb99f5bb2ac8681d05631c61c3e31f506976e90a130aee0416fad01b68c760d54b5f63231f3d118f18b4d04f44c255d95e1f8bdd7cae7ab36b68c62a353a8f85d70b6f78a9dd7429feaf4626204cfab0e267bfc9717eccc4b2a2849ec803975b1237d01c1acafaf02bac8e6cb84408c327de940107c067c69e481822581056162531b120cdaa067a7d65a3a47a7ae35f507a9c519f7be179be822b1dcbb8cb7561b9d7822e936e5913dff73c3c02f74e419f8185661e60ce39c411295c346d692def165c38ea53b1d61b08f9d6830fc3c13f0b8edd1dd56b1cca3c18248cfb43313c7f91a5a7f0bbf24e0c0b26093eea6779d93fe128cb19266968bba07f75eeff77ef02b509045d08098cb00af145d1ab06a4e8065b9ae3c208a1556237bc2a269c030238d4fc2e0661c6b1cd2c1dceaea81b837cb4c7b032921d8e77a2304b70d1e9b1140a0866284c50389f581c5c733afd3d18651d84c0717943b86c3c8438defa777f0215e270c94074e1458cba5e0e51d3fef04fa3c51b150068f8daa4ccf533ecb075782104436a1333b2d9e71add8a1684b8a98d5050b62a56df930515cb50567d678cc782c3f72599a8e348c753fb3eb1e01c36a74d3e8ef8c82d92cbdd9f759fee568525f5d1b509907737b595aa2f77333b499896a877ed157d230c765da0e0597388d98eaa4c6a49d2147c5fe963abab12ed3e00fbf0e09982e7c15651ff87b3b11596a95c320e495277963dcb1e621bcc4f6dc81bcdec747a879569c1a99f23f2613e781abb0b3b330d5271f25e780560fd5cbc06f859de47531b1b8ca0c6b60b6c668b59decd66a395e6f6d7b170bbda9ad458b8832ed1e232de0e8f973af0f0e2c5e902c7253f22310740cbebf1830b428d5eea36734db9a83fdf8ec49e91c01f0edeffef4327195516e2dd062caf366209f99802efd1fa460b6122ae840d2ae809cfdd27eb403f4b6e26473936cb11fe381caa01ad7565d682ffc2df5617d16e36cb1debcd2a6c42a2d8588a5186ce7bbfac7ccda8b00b32af6e265f7b9dfad36d0f98fd5a70042f40c2e4649eadc95f147122b437bd91b3a0749a02bec4b0f31f2a256a3f59344d192934a4c41bc4f02208a967a096bf198e9021de7aa8bf646186c1c8e42917c1b6ba03920ebe1c6eff205d027f7ef7e4f8a17e87ad83a7bf706d16115aa66deb41bc486d932bfc14b4478b37e104467004ea19e5d91a0c8128a0c0df11f7e76f7febae4368dedec4ec34eb1c46a45d671850b95340e6fdcc1f69fa63858f5c9e94935431f0681d2a81230e44675db413a8b475a29bd1102febb27ce0a60f265b767a91f67a8c7ce172694f933c856b3f0c4f4a5362222c0fbeb16ddfab6bdb62293ace0224baadd06248173cb6a3c3b31f0dfe2969d42b28cabf0600f220fdfdfb126b459f8f9b1ea285bb7b2899b3352a452bd1ca3b807ae648d2fefe4595537f4f8f285a37270b96ee31f8381b96a54ee36df081bfab2b518d6cbb0e3848bdb8ad4b9bc74544de21b5d4f04a847cc88076ad7124aed1ee2014ee352b69373f2a300acdcccd58c622d55dcc95672d62bfbdba992d1c8db3b686856742de083d664880d9804b7e71002e1b76963d3d5e32737db07698dd8d67e1b1c0d89f37d62be3dcb27df8aa39a12060060645486252ed"""), TestUtils.hexDecode(""" 8F69A33C4CB9627BF27401D4A1BC131D28AD0E2E5A317CE983BA2CC7465861A414FB72745E4DA31C0E04576DFE0D0EE834A1EE323D5A0901DD0189EFD6718049E2FFE1AFA548BE16E04B8963325AEB0CA90238C7A243A3F6AA17BC1D63836898688AC8E919B8EB6D689075E050B4189A1FEC723E0AE8D4AAE9FB6790B527A7552CDA174BF40BF91C4142B076ED8CF112A871450AD994737FD5BCF513D42DB01906636D42C6C10B64F74BD37D68A966DE0F3BBE6541AEB9991DDD0C0070F16715C01820546A014E66D786B8922E905DE2BC65053C42703227B7D8431427E3EBB0DD010DC58C2343147700D673D5707160F234E35BA24516CEDEAC77AE15C667AEFA8E029FF14F169FC0A781593E11D42E8659DA8E91E53EE0A1FF15A3C203BBF9591584A99FF8BACDC37541E126B8CDF3503AB2D1BFC0C37F38A298AB1DDA150288A8110C052469382A9A4F5565778339AB327DD80644A26B218ACE0830E56813CAA658A9F17826CD12B815612BE40906ABC89185EDDFA8E05102842CF27BF040FC7B396E7E2E023CB86AB7AE25F36DA6B6C0842126658E0315D6D8F4B5DF38CA663B55998ABFC72FE9B7EB7CE3BEB72AF73A0B2A45577C5215C42E465EECF4A4E69B6DDC1E65E0C1EBCA"""), TestUtils.hexDecode(""" -3639297077C2F61950A09D4AE55408D1822CBA6133C788347C1881F8E02400B683B012EF2D9EEBDB65029BCC9EECAD9881BDD4FFBCE8FB50242D9081E2C8C791577C800986BD7A03A3817A06E4D6609E288B3849AEFA840EB7B69C589AACF26B6332DF4210F3AB0E8DF14F918848B907FE9B09CFB91F32871B0ACDE0ECAB8915A0621CEDB4A591B1A6EC4B4B9F83F432A9B576D9E5D40AA57D24D408135E72C77281515A3783C8F3397C9E7D26B4543A528BFC1FE91965142D52FFFD2A26470EB821435914D346EC8765539D39083D743320FEDDBE31E08EA0E4ECCF74B231934B5757D460E5B79D16758F4A56E59C166C7F9F1BF6C1DEAF5478E97C8F55000475D523456724390D94AE9F5C4B3F96E86F1932412D740D04D1851560476D50D7B97B080BBDBDB7A347197F2ECE6603B0296C8833B5DDB95BDE239245F1BF27A7584F5B9243D906E4880CDAE82E5A7F1A71A7DF8AF9FC41C0FB4B63CD356CF5F36F94D20592BA58D1FCA9D354B358AE5423D7D5FCCEB05B831024EDC7DB64D6C9E45454790F8B4239BEA02983C5827E4D08E8DF3F795D46CBDE5D4955A6AF2A6E0D101CDF43F43D7F5DCB829A5A79881EC903C1B8522CCA5D8D4722FE29B36BA0C571DADDBAAABFD48DAC4D2603D768A92D8ECFAD5264A9081A74A2F7FD635220EC8A95695F2264075DCC05F69084EB8336588CDBD58CA028E02A2756C8A3081E720F281172F43194D8ACAD2F61F2DD4F01C235694FC20921EDCAFB9AFAC8FFB1A234FF35E68AD90086CDEF922C47C84ABB31112C6AD6CFFE0DA11C1999483609EA98573217C28B512ABDBA6F7A7E69FB8944D0B0C4B9CE7AAB52BB558A5411671385FE36903D148D11DE00A9007929094C54ADE5E9BA60AEE35D5014C7293FAD0158D69FA08E2CCFFBE2AD99C66A2FD2382E6D1C355481248F53A5130EB4743DF24EC048196CE056A7EB032FBF6FD07D12C153D06BFAC06C1AB23147F8139DDE1C00F9A9C6347456C148245E3C94F2C012284190CC3EB04ED006AAC3DD2F08D6D0AD54EF507D7E80671F12A3E4DE2136B6ECF02EDD28E75B985F73841F600EEB64F8E5CC101756AD7794DC14D187237BC82CF6531583DE7B0F60275E63976296A0A02E67298C20FC64A1A8B1CCECAD1DFEAD996A47E9B6DA0079AEB435FA40A53A4C0D565AF713DCDC8D4F16CAB00263058A9CA1F276A39172FABE34FD75422E64F23B2715B395C73F2335B6E4EE7E5BA8E2DE18EFA39FF1B0CD8C0C6F5618C971213E94BF2B9B18E05BDFDFD9DFD88CE24B392BE1ECAB51B95C0BBD9513F881DA789C57B1EEC8C53EE9CD4FAD5E7526B1F1462AD88F180243774B91A9CB219D4CF9730E682E2C6C8EB160131D3AED3D3B3E64EF6A1AD7ADE7048A0CCCB67852971330A62223A89733E06615508029823D397EFE221B35896C18E9BB08140C464F8466190CFD8B0F09E6EF46BC14753974AFA2CE926EB6B02F4EB25CFAE70C77A865CCAE8FF2415C0D81A82F3807A4BF61F6EFA9BA4A16D14E3169C2ED86B50059880D07897A67C882E9B10450DE3978ECD78EE2A3C2B2BD51544FE65ABB7909FE439355530D44244052F2154279B6395E77FF1B288103357C5F83177794D517B0D8A368C9B008838AA4139F1BD10E3ECAD45748804F45122F3384A1A2D541BB8B9FE3C478EC0AFD81EF69FB2A42CC9059CBBEF42633139C342627A604AD07D09AB962E7C1CD2E1F1FBAA633E00AC1EECD29B5324DDA5F273154E7E9D0AD3F78C6AA08E92C77BBA7CF202B94377872146C60E9384830DA573CD7E3BE362267CB74BCDE63FA708E15F5933E27117037F6C35F91D03DA285222FD3F29C440DE820C89F6F37C250F82F0B20E69D728A680095B59AF058A06E46CA75B6BB1E2B0E14D2C9C4705A080B9B826E2F1F96CAC70A902894B416C68171B7388F4FD6BFC4BCF7A6745F3AC83B8A31F869C64F67C5600F35202D3F45E697F46DB1991AEA695443C79810796CF0C0150A83E24B2DA00DC72364CD34C2BF6A9F1EC4C39BE42F8A7E9DCC3BB6D0BB6198FC08C9743335262D996C489C460DA87FF75D4B75367C17A466AE08D24D736EA63A6B0087041426C03BC94BA143264086C94B4C8A3F6B7914CE40EB7FEB876CF16A2F12C66AE3EC3B57A93866F63E56666AC7B59D3C78536D77F73E9E9BEF9899EF390E8BDA6E2AD5CAC671153C348C804F65408309A08B2E78FE79F014ACD99766B383E5869F3A3562B4A312CEFB3D8F5B90FE769365E1640520C817B6A3A26734F406D104CB7AC9B6DCE371AE3D7D10E265EA370C0C78D0685F9BE4B3E9E097A334F53E47C016215719A5A25EAFCA799BD13F5B23C63CF372972F5588B8A125AAC58A0ADF961A6D0A2646F9520DF6699B67293ACE799C784CFF813CD508317ECF90726D638A13AFE574BAF3D2E9F39103DC199510AE4B28FED016993FB16CBA627C820F4B76227044F39AF0B8222E1D387C7005080E5CC216E22AFB8F591074938A3510AEF62D18D8CBC9978A8284DDEC00F7BD3C75F724540174416CFEF71D5BE602FEAAC4EDABCB72F7252471F4A3D01A5D1BD82F98A7BAF66CD6193E17499741810B68B1B066C827FF18763CC557946FE1B60C706606F7CE607047F18D93593A7859BD669642FA74EF569C31F811AFEA327962E02FED620011AC0B96C6CA3AD9120EF1C3DB3C9EC43E7C4E1A255C822EBDBD71080C103EAFF847973B30AD88C40CDEA8E19750BAD8E298D8B0569CF6D3F99DCA585B418355ED039B585F9F829DFD4460A748083ED38C6DD9A93C34447AF47B339C5621D908838469326D318C41ECF288B16C62040EC628DEA4C29DE18F6BD3793BE057B52BD0AE44EC5AB575383FCF35EA91E74ED011792C415934B16CE8D4E9C2416C1C79C1C8B09DC94E005DE0D9B8BFDD07552140D3EAC45EBBBE9E164BFA885940702281DC14142E236AB3307EED9A2F4A88AF5FB61D771ACC92B2306B08F5D8F740C3F10BFD5368A744BB6590AC29295085EC4DA93C508AE62AB59E2390C1EB5B2D5976C55DB166B9D1FCA8A91FCD234EA2B5895DC5228CA981C630195FB832938ED7BD73353EA9771ADD724BAB7AAB17CA622F4B9FFFD6878E7759DC98C0F5F57A5F59132AC552FF4575104CDAF00FC6B73F460AB4F3E06861EFDF5DB48345F35A00F5DFDEE36A49C2150547036544F0DBCA21FC5B41D36D4823B2917432366F97BC0B0AE524715293C6FFF6DC57FCC9A7806C7ACEA749193CA1FD24266CCF42402C565F488CDD0794CA7BE9A78E9DCF4A2BC2C83024C0C58876B2921A1A5203152E4F73757A9AA4E4E9EEF103273C44454D5069737892B4C8D1111E313637445D7C8292A1B4B7D8EC060B3B444D646B6D85888A969BA0DAE1F20000000000000000000000000000000000000000000D1B2A3B""") +f0fddedba6482c562d0ea6791254b7aa34da8b70ca4f0a7cbdfb0e4fa31f902aa37484c4167f74093f5ebd508e4b89966aba03065194cfe3376066b848da8faf1768c397a0e3797bf09e1dd02be5f1e77703ddac9063901b52c9b4be73daa5d44da1a59510b25a974d9c54f8f7889587c6f69a17989ea8b69f4dabced9e23442f337d015ebcf84cf8c5776f4863275532c4bad840d314797e07de00a9c7fdbb60f83392efc382220ecf3f9d60b5594da6fcf00580df29a378a9cc3156bac8ec8bcaa7de1d8d48d2a1f33ea8a8f4956e3c46f386628ca96e009852405b6333710287e376aee2ee7c6f67b1adf07f76fec3688201bd3b152e202c192db41d9bbc0d8411ca019f9a1bf1268b34ce82a7c037fc63d9c63a561003d8247c645173e01c8ef63853e4451185d45cc2d5d2da4261eede504c6da88a55d7cc7bb8df33eca74e9f4b9f9139b9f98964aecc5278448ff9f2a032226e908b32d741037ae689c204bc1f3bc07850debc3fbc839580e6ae1fcfdbd62257ad64c2d6f6945a6757242d1473e64f089c46fe050d79a082e43cfe656f09d01ea219eeb7684188fe80ad59c4bdb57905cba37fe0fdc1b205f1a5a899ab55a37c7d3e003f1051bd3b322b37289df3d350053d6ec8ec1c9cafb49fe147c01f092dcdbd9ffd2b7900205334a077b2ad5c57a53410bc5b9f32930fc6f6a270d84d4436d8c716344df877f5e523ec9e1ecdd43ac21e2c4cb8706415be0ea1060c7127d6a327eca92956771af363c03ec4a0ccdf958bee76803208191946dea6e51a85dd071f3711555cba324e5a7d7459a7662fa6cce043b34845fe77cc651883c478d0d4b2c09e76bf401f0c12721d21357546dc78d2f054b409b6a702328d720023096e911144b7bb724f1d799b0b446954a305bf46944f122867cea17b9798636498a8393bc2dd328b0b3ae78b44ae35cbabe62e0f0d3ea4cd6db0bfce87c6e9fb3364c2ee27b5edbfce17c8df592882dd057dda81855abe0d0898961ace81b0ff22b4471bf96ce814a45f7c6b3e07ef1f18c9eb238b44dc6a50d7489a1af58d2dd1ea2ab2b1a0b4b661e55bbe6dbe9314e76207ec0a02edb2fe7e8fad8141401d1f1a80237cf5a10604ebd26ca46c0ed5d8bfe96c3a1d6ff5b7d2de69402d348e5db561e531deafe29b0767620d7613b817d4d3a6568911c291c3436b40043cdef83a8b7f527aa8e9ca89dc923c2bee6e41312af6ca1530ec7c6aae798e25a6a31ecd29f4ddd56d663e430e5c1ead28a23d424148b1a8aebe9ad7faafa4e295215962d294edb7b1f994ccf43238038ff1af9597d24ecfb68aad4e4d2be280c6fda0cb88b4a1b0deacf678857d83c955115c094980ef8fddfa5045a3e38e733bafa243a91e89a5676312db195f1fe7c0f7b0262628a68c6619db1fd85d84a02b9e7da8234304192aa3db15a294dc4e9e7cb32f8662ff0a49fc4309700e0dea871edeef3df09ec78c3791fa604ad69bbd8c211f136dbbfd49009fb5e4fcbb2c995bbe361c580a3aeb1c88dbb2f148cd05fa9ced0d826e24c268b741953c8ec804add66a9b8dbda05a9296201d0f447b45a4bb7271fbd3359a29815bedd33ae87b52bb270cec2369dbac94528eb48a1a66c129793a4365212f1cbe7e24c87a805ec0f41cc2f36bb2f2423ce6904406b1362c46d51d6d5685dcc06915636e20ea3649d6d1da39c6177630d1d48f393d7093fc12415e5789b15e1ffd07e1f810057ab6545b22b24a93f9af3ae254407f9920af8a48ec40412998dca523ee1e122a5e1107a1121cad25652c1e00f6fa115c58b4a7a60cb4e3b219d9828f2c8efb04a443717e73146a89fe1a4f887b564010eeba3695164704c517d3597ddf34dc51dc460773394d8cb4d562498cd127020973bcb2315c25ad136dafcfc0d674341045ab1de0e4230ec91d579ef1a42ad69892f17dd271e9eab28097f8f9c5e78c50c36c8a02f1625ec41132ff1731e3c59ba20cafacc9ea890db35b8c9606bbd5457262d0c44c4659f933adb64fc74a884e152627cafdb20cc64ca10ed9ee16d814b506415cd0141406b0286124e37f777dc810d70d4125a72bd98a2b73bb26173494568bec76350b2b3b399fde1e3c115f1fbc99929a58a8ccc2b9cc1efcdffd210d88ad48c54a48e837cf841c9f1a350531b695c6fa08ce3148682fceb9fd17f121fc1e3275f65b5a8cd93a25d42318bd21e94ea8873744f2ab530c58dd3bc1109a5c872e61887bddc455b1bcdddb91c0ef4437a49a9f6c73fd371bc6c6d2fa594f78224646f2b8cfee3563c57149aa3a6995dbcf0e6782c53694b39b8812dd069c0cbe713fe44446e44beb4ffe38072deebf3ccb20134168702fc023c4ddf9aedd387a8bd6fcb075850cf1f29f2bc283f5731b75b68169dda2289ac221217bee3e2ed479fc5ea8244a99cb27a015d7a3ebbd1f7acef07b63f17011c5e39ccd0c025d0bce5aed7c482685c39f1fd82a9b08c197f9cc18da457ad0ad55250ea935bee50df659b2c7a501a348b8759643881a9c5555015799adafe10130d6107e0b964b48d23c909e55843b62b9dcd1dd3b235c487968c2c3d87fe29b2fe3ec7a8fc1c1666fc8d2b6adddea39ad704cf5eb6c22f0a5aeb80e2bb04f6c2c6bb9ceadcdf7945140ba942581213dba8428a8c06155f200082f7faf357ffaa653245e2752787fc1598e000eb567cedd49b98d5e4fcbcfd5c4ee10793c16a4767445fcd16ce4201cdd005e95cf5a714a9e0f648673269b5fcd8ca0cc254b6cd2fb428075a12b7ab2bb07a5ddd82e58c04676563b11dfede4daf13e1362a5171364a2f556c36130c1eadb59dd966622f8b86502f379e0dddf69a1f73f58ca6867b4612f28e67c7dfc49dcb56dcb17a79aa0e56a08c14e1e909fd21d05003ea921ab717bae0ce1f15a74a71c4d7e6936d20c7e661806d5f8a5f4cd93ab6720775057d4c0450a6c9e2211af47c57a7127f59983d824d35f48848043aaf3e76209a6cb6f34b15e5099b2c3801bcdca3a5c626bec9b6e92a67189dbcdad0d59d2b30a1f9cf9de45084ed6d35e32722b6642ab870247b42eb8f5fe39e97709141e36b5888fbf496199675274d840f15f5ffe40d74be3bba8b4dc51425f839ef7d041a4232ccb93b754c524ba141c75ba94209f9e76a0d7c8f2aa3e126e6eae35f19de3fbe38f17143d1a83830a2b9b4c8a8b0bbac29363ea9ed0fb1001f67e1501b6f4d6406e2335a61f3386c9e6a2447e3249d3db8390158af9b7e57d81fcc00a4210194ef6f872821a8cc475187780d658903040b0c0e172030576772769facc1d3d6dcec001c30335b5d5f62656b8f96aab7c4d9dceef3f5051b2240435b75797d90a2c9d20b1b1c585d89919ce1e5e6ebf500000000000000000000000000000013273441""") ), new SigGenTestCase( TestUtils.hexDecode(""" -B7682E0C424BE42ED48F21AB5AB57FD47BED455A6853B3C166D2AECE055EAAD23EA1D186FD4F24BF1F8D910CFABA719AAF8714606159023E27B81BFDE79B4C21F2E28722215C01B06BE6835163253464EFAA9CDD2150EC59085A32C2BD5D840DE568E12A825CAB4E5CC6CA768D632BD6780CB532522953FA3D774AEE03E2D76748206C49384D81406A9B82201334601346214CB0419C228089C88C5C16690A10022006715A308510102210B44C0A042A8802425B202064042D1BB2850B3292C93461634488D900111C092ED42884CC484D5440440A318AC0B08D1B024D04164DD9B44CE1B01124A72004A671E3106514A74581062C193786E04291600242CAC40C93124E981010A3226262982990806099C88418398019018A2140828C066D13B929C384659B82451405910B114058484A00210663942911358AC1420DC8A484D8344404908921C408123160809000494010CBC4911C041223384E14364D633806032720A006524924850A410693A804E4968CA284510492609482242214640AB20D89A44821294A8C246D511666048949D02685D38688A2100E0CB028DC3889C3C88913B540401012E3C48992081241A608E43425E31645603022E312691A824011412684286DD1A6811239825028692200249908401B124908056D0AC58111352A04A1909224095B34281A2408DC984DD300300222724C145182C8241AB040D1B849CBC26DDB9411D8020E0B2708A4266490A624C28085140726C342819842068A0092D91600CC224A21B20C53067100A37121C14C98B42021818C99004242086E8C964C03086D23017100004CD0B61049385191A6040941261B2891C396704C0646E03421A398010C3784C31248D1C44DA22029E0366E54846D230862608404C3A88CC34021C9A8605C94518B16309BA0499310891B87856394854A24918C228CE4388802434424346910A948C80288E0A68D613081E00269E0440A2187919A082809A165DBB24852080E2180711B16250A338802368004138CC018415A020591B8699B3250989611D406525B820D50B46DDC884809102EA0284D0300242031640C382042180D91925103C5291145109C98315CC80D60108C10220511B12CDC366492383183444DD1802521055153185141328499444C2390505494201B830DC3168A48A29064880019A18CD42208520644992245E2360AE404851C4648C2B8814C2822CB38218124084188884802409CA624C184699B360E58B64181046501E3E9D13414F71537E2AB58DE666A17ECB001FF8EAAB0141BEBDA328E8C7EC44F552DC00A1261A83DAB59F8CC4392EF5F14BD88386694EF93223BBA9EC78A67D5FC9A01AAFB16F4E1C80BA31229514DC1637CD43ECBDF85BDE63F6A2A17E6A1BEBEFA27EAFF596624B30DDF797120E52ED396371C1B143C27EA83BE66C9C2BAB70EB1FFA60CB818B9D159C0C7B02734A91200C2282403D316F6136B0BD3E6FFD328DAD5F257B316BB76D6B3317FC3D7808CA0A8C3A7BDE19A2988B994CC13C13D1E3C9790BA3239FF91081CA6F21AC9684D4189BCD387B0E70EFBCF09B8924C5D9385E1006CA7E153B7CE207B920671065FF7A9AFAEA91DC64484A857563C9E90D74237DC453A554D7ED88CAD9EA30F0A49E0B835560B4D7741FD1B96EB6EDC6BB7201DAF2499623683B672956FDD51E14EA62504421AEDAA2C3527BF7AE8DB52D35D673F5E45918C833FAC8482DB27001C766DA36B3E8B0B24616E749E38807F3E646761E4C998E04D53FC98B7D636871D5719EEAA6BE67D20565D7C120E210A67C12B03571B9BB450A710CF6986D961BAA5A9F92FB33E61D605CF0E4FF4C689D535DF5FEECC5D5BABBC22975256B9834143A5DCB903308B18D7503A2EA8CB8B8ECAFA6BE70BE6779B9FCBF3984830B72C513CB150C5529ABE6EEF29E24291756BE46DE9796714A940BCF0AD21721247EA5449946D987DF5E70326B15CBE2C439388E64480CE84EB9063A4213B58C7223FC06A5B618C3BFCA18A4E46205DD963CA8E2C86712D75A4582668E955D821AC4A7C136D7F31C7CA4E7B8AF187B2C6F4366CD11996BE298D71B9E6C3D6C9DC47826F58935CC8EC353C27B3827C3065165B3645032D3013036690D9232FBEA4FDF57D035D99FA9CDD8697BEBE97D2B9DA476BCFA7BF167A1FC66BB1C5F2348E86F3F61432600D231A593AF2FA3CEEDF7F4417CC0E75023054E21841DD19D53D3547D3481D76401E66FE238D68A5381F98E0F6C455B852CF09A1B17343336FE25DF426A0FD29CDC00F207402C7F96668881EECBE43A4C1DA9B86AC50FC6B3E2C74D244848FABF414BD7B3BAECDC750BF2E58033010B8944991D6CBE7E5468C168FEA69B167B566078673BB06A035BFDE64F66C50616E9B3419394E71F8AAAA636634F51F588D3E012A40E1C9A787044596C51A82D77EBAE4FEB448C919601A183E6A847E605CE142B5D56A0417F20356E7E1A35FE18E94188155E3867BBDC7CD04069D1DC4B3EB8C9AA64F7F955C7251667441E77D7C818A8F49496F1141E829C51074D3D38AF41FAF4C77A56D05296B034913A253536702A21B77DCD3137BA26C413461CDCD413296C9291F1CA056EC0DF02FB888654DC54192EA30631F8F9C8B4921A1DC2AFF4CA8C350DAB4234D9151078DB0EB340CC3754E48012E8C21C84B410FBAB3134DBEC37805E723E5C08F1AB371624AEC29A1885AAA7915497220DA11EADDFC7D9FCFD51D0765515C16273F978BE26CD6D7F8627587F82F3BF4EC25C4263DE24B3D4A0839F7AFF0C4D16A3DA89D1F23678FBC23F475B18B523F115CEC9D59928ACDC7772FB39B0F44A77E15C7D786317CFF38DFA9222FD53470AA15061EC8A9D6CFEFA5C32A60B29FD1265B10C78625B2634158C3131727688D7837AC25BCD90FA8EB272B7B3B232E8259FDE162813ABE082BB0BA76B62DECB230310DE5AD36BF3F1AF145660FBAC027D58D86B03E2E1B5ACCF81B6252B90E1B9E85FF41FCAF60E308E5FD114B63CC26262B4A5031E654B673B23464318FB55785C5B707D901E2BE7A3C7E2CC4BE5EAD3CCEA165A577680183A1E05A2FBAC4EABA9022F9A43A53CFC61E3236652842ACE2C8B4249523BF57D6404EA8B247B0058FF1AE98CDD79164B6445A80F31C427EE1BA04256F0833E752DEE5B5224317919242A7E8CFD0791637D3D3873768FACBA6DA65BD8B4177E6F634CBAD83A94F2CC6500A0A5829C9BDB3849FBCFD517A80CE0D8411948791D0E5927BD13EEC09C4FA2B2453D9CE1BA10769B067D8D92547E8BA2F6103D066792655BE8C05AF1628099D2617BF2BBC2324DC6E3E36C9F32597A13FC45C1E974B00FC53009716EAC9FF0FAC4C6B87DC59B4908631A6A21FD5E156D476E438872D93FE112AABAF99A6952959FD9FFD7C3C25E11AA011333FAED86DA99A6BCEF75E4F341BBDC0E181B5A2A22E9CA06BD4F9EDB955CC44F11C6D2E23378B94BAF0509DF55E8D05C4F8DE0B4FDA82AFE7450A0A3E5D8DE82368F1390D5696FF19D1C4F265EF051CAA0E68E336DAF98698FCE2472A6B580E1F30BFA7B385D8F4DBF063FA79E412756ED83668D5C3EFB0FF4A59FE6189D1B70EC45C7B"""), +8a37e080550701795416f5587b977446898ac8147890840db53ae4c7a65508bbecd64901b484b1e1ca4764c26360fef4654b49d61b9b180ba16c6d346251b630e2b21822a4c2d9409a025868c3dea90b7eea36f9dfd34822ce07865fb847d73e1c6e9755cc9cd520d6120fc21ece975c4f2cbd0cdf71c565f3511cfddc2e711210192dd40664c21805c93229cac8219bc609d9388c20498e839821d390881bb58081400c000345200485e3400e489851d34468400025113051c1c821a0c08499988ce3400e1386690a022da2a051d8a2605b9611a4a8092293308bc4450b276ac91269dba648c33484d2243163246d0804660b234d4428021b004110a0641a0870c39811c4100164240019a46dc88811c306656342048c0040119289d3a8700037400cc96423896804119203196c5b120a1b02461c1428db464c62080ccb006de4286ac80621a3388da0406124123019c449e030521280642306888384281cb40c412692d3b80124117191c60d201110049060da949004974409332ac11472584069db1431d1322a243289542628809431e30891c8a84d131960082171c1326800225119002c51006658442d40b02581268c429088cc102d8ac68153442058a689d980485082281ca86c44264a5ca2686130641a310209b38048360e4a9285a2a88c02c6250889214b30094a101104382962b60dc830614a2205a0420d8a880511b09022356884062982026550446ad9424e10418408b5710093491cb6844342854b02321937410931502296655044618b08869b006a09262ed800412190711800091c33660b1785c1c04012990454b01081440819204e5c3466daa484cc3491d8143218174092342288281048a8700b190c91a0850ba771214022910241889808c9188ad4a64892b48ddb062500310643328964a20d82288c21304112394619218818156d51928562984c40a024633281e0022884b24d51948124295010934c18295281a22d60a620a2324a0a13059910880a083101990c1c102d8110054220868ca6080039115b2822d8c03004076623084898346289b24d483890db848d5100811c228c00b8240cb8209a344d4c4420c1988194b8694ca86512318d60167152820c0a012189142ca32231491824a106281a2904988450241160e2124c8b02812214221c316cc8442a12010c8c325121290222b14048a60508b201a1c2811045050336619b32220b8089203352a29049cc12900c124019a47083b66c63a8057a10b245a52f0ad7febf3d3801447b8222ba342649dae8395ca98831880c859419bf766393ec97f18e26b6e6e29718332b2fd9486ef5c149fc4f49ad1d2a2f7ff7397b44771f3e9d90c38232a6f30a2278527df3ab103a952fa94621628537a3cd9dc1a1b770e6ee8a62e0f72d187e9ba284ea8e264f5aca8d6ee3b566113310c813929129a04354a7ae12a1e0ff6a9282f776fe56b6cdc159da1f5dffd17631c84cd5fba7040450b924b93000317fe80bfc062e1f4cf7d991f5aafba5db5928850684d3d5c719355854f0ff74e42d9fbe4264e29f5cc74e717d5b8f592cb9e070b252f1514e3a17b3035f10168f86d688956a0461e0369aa2f7d3fd7840895b56f2c8b9bfe0347efc370d6bbcfe1c885c5c906934c1b188d3183443133273780dd187a066df1d1589457fe2f619265381f50bde9758cfac5fede514a2ce0861d297f1f47d512ca1fb15cea7d3a4582a4492f8a5c6dbaefe67c314fee1ffdfc251270f69b2cc654b2a77ec0219e85b5814c082dc618391d8a0e5b860ed1391a2bc99493ade19152c069cff589440481aebe4cfa286b9e15977405cfcf944c115a8866f88733d9fce246357652e7861bb3c9024e49e3b9efd99316a4eee4156422ede4fae9221334e2b4763bbe7fd7f88ef7f196685e00f4fb99d38570914e257c0f6b5da76c84c9590c418518f0825aacd131ccb8667abe7cfb428b27e4732290edbcd6f207609a71162e7eb4f9c370bab3de6dc0e531fa41dd63ce11c42bdeb4cd1a6b34ccefd8a9e78bf0fc924070e0281dcb67cef5ea3f4da04b9bfe85c622919e7de5fdc1cef8969a7484ee87bcfdae4d329d4627cda2a05a4334a1b0a326e1ea8cef839bd5317b7a2d84ba7737f4274e9258cbad6d07cd611a4276377f74b1f238b5fc2fef9bfa18c8196e303388fccd2a582b431b50de50a403b7560f31eb3b22252fc4558faa9a3a46e62469f0536848516e820c9c233ebfe1ace57b42937ae2ab801c5e9ab16b2dc06edfade1e86b5385e8b11a782ab21765279a5584122fbc8e85eb9d08106f8702a31d434e44dc780a05d2f47ea8ba5e999096bcfe20dcefbdaea955b08506fc3c7e4a912686d4d0ddd96e3db254f0585405ef8472336129d348a7c98be6ae4fe6e15068e76926018837e3d330bcea69233a6b07eaa5e0e773b0090c5068c79ba2457d23f7ac0f70a4ceef3323b5d4bc10b840b2b7a58444d00212f9fe767a00ccb3b740fd4f7502f12ff86c22aec43f1571c907b6e317ca9fd25a4f10bf5d1e839809742b0f116625735343f6337a77c1a9b63cbad92877a910830e0336010b8794f28f7073f5f7193aaa68f5923cb3700cd3283e912633a8e406067397e84788f067065d7f21a265c8ed878df6e0373c32a2aaeecf51d97418dc8cd77999191043263ea1caad2f23997e6cb400aa1fd54a968fce4d69d44b37632220e25df409fa2628bf17d39c4a2fa90ce1d39027177aa445a352344be19cc25ca0cab87a456ceb256d0928890f638d3f8fa046ccdad16b49ae0e71c9b9b947a5866671a029c8feb90a23e8273f351eb407ddd7dda03d30ddbe9750a05a6158ae14b84330ffb20666d17d73255c5bafa6a02d9bef615b9925aa716d20368eab7550328dd2d251d5a127070b1317ed7ade82e4d49ff9c7069dabbad20b2dbd9fab0978e1114f50f9ff10474906c3be4118103b8d4a2a576d5291685c37627a55fcf9187e9385a76429726646edb07ace3e02843212ef78f91dbcd9c54bbf5b6ad234834ff8647905a87afd41666fe007c96a2315c3595ee2196091c0ef5e0d1a3749d7957c864642caa2b52bca30fb62e455ad102b830800d1e01ef05acfd5677bbf4030a8800ed9afd9fed444dae96e85ceb9bede5b34230ba8030e887b27a907ce533ad40294cff8baa73483f0a6a346372172b095f435eb9acbcc2f6568d9f2e9f64decc6f0c584a71fa128de4a1f5d7ae55f7243fd83ba7449d4f5d1812dbfb7d1e49a5d027c240fa71e5d5636b07a4c0e65a168a0cb17a9fe088c86ad0913de787d2cead5930b4dcc2d097f8ffe8a04a078bd83ba6a6282663e0d821e432e3574861191aa82b1322441402120fe80fc5f60f05f4bcd242693b9fb89f0856af628d69a21d5a046395092c20c5860941dc4d129b7a2ec51fa56149112f0af7c3afc121ffe7caeb41370642ee8b4c3ad7f0a1970fdd0b37d13377a52fb4db0fffc71a1726e63dc9b914bace81506d320a26c8fc946cc68caabc990bf611e2cee065e55ff11c44d95d819c56826e61c088e24b2e01a697be804a8cb82be56b097039c57a854497015eddfc1ccdabe6cb7ac7b3989bc1a51ba9"""), TestUtils.hexDecode(""" 5DE75924D05BBEF6B34CEB195AE3349EB621187051B1EF95A779B99A3E0F729994BD19C7D1172418BBD3E015B20699DD09D8BFB0A343F477AE2A3BF5737AC994619D1FF3C13E7676D1BCB446289DBFE36E2D1508A3D437B4B0DA06478DF6D4701909B272E9070B1FE06385DBF8A552B471C8EB48EAE39D141009FBCC5D57D95697ACEB7B5231AB5976FFEC41E947BEACA7639F664C6C1D058505A49561811ECDA46E23B651F918112F38B407E82219B49E5C4E7C247DC4BA633C746B42DB912B07D56302FC5C08F5E0C3E311268041F970E670F3AD26A207701F1359EEF9D4134ADB882A1C899B0E4FFBA2C68535D97796636417EEDC0790FF808C976B57F0838A694700F8D75DD4FE5ECFB4B6A188FCB77FB1DF7C5F7C91DC81017A5E9A6D1EAF59680D3291F74743E1776A6DE31101FAEA31D876A0DDF3777A91EF1EA0B575C83C97C7A283E7E958287F5A52F30B6E70201A1410355B47210B911A7A4F6FC23BC95D7951822115FE410ED2E7FEFE08940B3F8E63F13F26B6E949C498E62A66FA675850FB9F7AAFAF7D054F5C12306ACF2900A5B66A29931A5919CB31D19304916AE41869CE3294B0F5F88D845A7FCFB57B952BEABCD1DF7FC11E2D342AA5A70A8AA9DBE1E6E66555EA618849A95439864DF6D7789D8E3B46C6FE4F33877F127D4136D993061DAB530EC979F818A57E1052B5B33D22E941643DE2FF9239741F6459A0EE28658C3C0033FA62DFF37928C59189A7A7E36B1E305F3E1F421EDF4D71A96C71406A0F9AFA5C96A9411AA1A35D241D7186E5C8D0CAE15938FF869897DC3B7D8196D64DE202108D6FB436FF89983EA6DBB5BC88EE2A02488E4D12AA87CC4BDF41A339E10300D32E0FD4F3D3136FA64BA90D64E2BC7C20BA77DA4DB5311F616288496F2FE3E7B3409879050FE57A23DB0344CAE82ED329B0D31DC9B7406CA715E3D84E364BA98F73F693B6E62DF4D741928D21D934453BD67FBBD9725BAAD34E5F3204BDBBB569251DFE2D69A9A96BAD90256213BB0747E7950AEBB4CEAC7224FD5F8F99A16866F5A1DCE07C2CD1E06B70A81FCECED0AEEECBA62521AA0A01FD7B5A3A8A14DB55AFF331E469F5138DBB2B96BFD0AAEE7F38EAA375F71759268546D590BA8C0C022F78CABC4E089992409D3D7BD19048D30B15C796170BCD7AAF7FED0387542BF8A6674F197EF994FF81BB80C59208A572495DE4E584B36A7E9149B5E2081A4DC162CF8376029231EFFB4B4981895FC36562F51DD5158DC82ADE52ABB0E98F4BCB3C0A24566D07686732FA734CDD48D03DF99F7253E589CB8725F17E6BF964E96F9827CA5A9DBD04D448025EE014EE1B5DBDA514D3FEE4F20664C11371DCB16991DA883BF9A68EE30D727137D7902F4839635B1C63F6C4F7D42070E880CA774680DAEF105D277EB8D9090A98F6B813774D42DEE922314480EBE562775F68ED180B67EFEB077D8B174C7D4DA877B0DD3698CF506EE382AE6FC6F68EE93ECA3627B28248D3EEAC469EB0C26BD1A10A7779CEA142958F9F9A533BDE974E1B3CD9B74FEEB2EE29ACD7DB65E00D7ED6E94E5E44A925188285166570727FC687AC7EBE4042BAEF68BC23F4B9C51BA5040BC6BBA41FFA9AFB1AFA09DE1BAA4DA091A08086128A9CA5F27D3F4420327C8FF4801BBF2057282D05D1CBDE60E1E6FB6715EC41AA9A852686DCFC47279FCCE5D86ABF02A6B5B57DE22B2097B12381EEC567E4ED1855F9B482C174D6D40A5825687C02E1D0AB634C020497A44E07E8FBB2D05280C53562DB4C90AE0901B88179D06F9F991E33BF17E7A9227A30454430CB768F56842995081520158FC34BF5257EC8EA9338B3714126D6A95A3D77FB61207154F6DD0041BB03D84D8F75E6EE910460F22CA765A2206D6C56C6E498E063B08B76B1DDF98571F492F9DBD3DEAE7D9C8EF21EDBABED962331F06371364DFCB3216E24638A20F77FCDD894FCC5525DD0C8FC329494841EAFD93CFDF0053FCC27F5A1263C7F4599C186B35FCA9C6F5F2FE169B00275F15447AAA3A823E27E322CA2316B25823F3A79FFA785E9CBC953815FE06F376B6F5860C6A87CB9BE98690C9C2A93EFF1BF1050A01C72CD521BEF265D66BC4B8ACE5736215DE59290DA957175D704BBEFB0E81C2CF906C3A579BEAC3A0C945409DEE4A1E683A0DADB3C4AA7E0174710C72A33F1BBC62A6E6F3EB9C138C0CEDA817688BCE8CCE523A2A4E2566775015F3BF66C09E716CA929BCC6DCBA7427EBD93B21CE276820734331B078558C63ADD096004B67E618D9E58FF3FEF00183EAA293A1DA2520BC03FADEB6A74B52292DBBC6EE4E5ECA8F8B0556FED36C2B41F9D8FBDA8EAA1F74BED46F05E7712E20E463502A420B6CE67D125BE999EF906300C627C57C468C8DD608F9AB354791E6FEF0EE63DF3C1821AE78111B27E57DA88FA44D89581D11C2C72F565A3D0B5E8E2D83DF178810075E5F8FD29E1953BD2C6326B693C5CF6ACE086673D69A67A181062A6ED511E0CF36381358C2DB2A394B05E0C1EE9C54B89C68E10857463F71A842BDB8429EB31D250542F88E6BD3BF10BDCA160C0FF44EBE7D0D982F15C4892091B4A69A3AE7051BECD1D2DB132599F1101E2BCF60136CE947F339A3DEF9F6D81E1BA3F5D4CF2ED989861F7CED86B1A6A167291CACA74C45BA7B5969C09EA20C4EB061D4CC4B68392AC866AC591764A16D0A42710645988FE070314D0859A1F022789442381EA0E3E83F5245272CB5FBB861C3729EC484D2F299F37D2F50688D1D8DD91F131D03207CD1459B289B19E3ED609D70D6BF8E0B97A75F4B4F1DB52DCA7AD03100A36C45D2AA221CD01C8A51D5328AE47E3307EDCEE9B27F62E5DA9EEE15B7A2FCFF1678551BB3DEAD4CE54A16C22119BCA343822DCD20271BB1518688CF69B566A123F65C4787C1C525BAFF00CE20C46C536E47DB1E4410E572BFECDD7904583BF61847868D7D1AEB1EA071EE15A9CB9E3EFF8D17A5BB7EE8BA83C95272E065979904AA99CF036BE085ED869D3CCB694C025FBDEE9BE140A0A21689F95D90D8A54DAEA98EE5DDFDFCEE2908E65C210F347D26F35B95B34642939067CCF04A098ED3E2CE3C0FE66305BB5391E223E43119D38A33672FBC980BEAB96558D3A940700B3CCA9D3AD2CEA08E23082DBF30FC08E94B6640CA04BBAE80091ECE96F128B37141131FED2A5549CAFD7BEB5B180509880C49FC6CB1C11E4CB7C7901C89ADFA0E5335C43A74053347D3028B23085647993B5844FB2716B7154D93E25DAD1CCD889EF3B16FAE34D04145237378D66BD09A254D395736990204A5627F5446787B467B619EE8F06CE664BF7B94392B5C77BCE828D6186348EA2DECA1CC84999FCCD95C9EC55E28C8C2FB559C9020C6EEB661F708E40351D7E530BFB7B1C3683BF15FAC5B17D1CE7EC5CC3C27E04889A9E59E6534C08AEF6934747083CCEE84FF2345D519CABC7D2BA6B783D36C864C65C47CA636B28B71D6797717950D652659AFA8BE3CAE4E269BD527C0425168D04C097DE8F34834A7D1728367F148524366F9E53C4CC255D3BD6FEE7B5A6CF459E1685FE740CC203EDBF58082820B967A40822D36BB4A489BF0CEB51387009D5205056387C292D584309076956E56926283657BF7CF096F54E0128A265050DF528AEED9247E19EFCC79EC301A9F38BE7AE5057456631840EE39E191B25F4F7070BB15CE2CC18777F7CBEF100FE7993681D4E965D0C19A68591BAAABE601BBAB89FC27B3C5BA83545AD645F0DB716C98D5C7A37E0AD97C986EDB88B025D25E3DCCCA816C707F0E2542E44F4D69F943E1DBD08E344F88661B68A822C3EFD648AA23AFFA2F533879540BE2F670F4D53091AF68867E7C71EDB6E9E494E9D30A1839653422AA8AE34A525EFAA62D3F5FF00D91F5DDF80FBDDE464A8502AD9AC85EB21025C0E4E2C2877D50962C5AB8283BFC823FB221CC285F3629056D1260AAF87B556E556B4C723D44279A106EE4075BB79773588333B42065811D671016AF177105106203EFC36FDAB2F5E5EC8DE043902583C1782BFD8BB772353EBC5CF03A0D869E5F3797713B58EB7480CF7B92AACFC9C41040BC9E1F5447F9852B2C5B5F33B5517F28A01D5435C47E063B41D3B0F7605B07AC33FF6F05C6FF44EBB70FD6E1AFC2A32C9A0B1AC17044401B93D6439CE53C3B033CFF06688E1933CAEEC48A04999A01956096339B5E44AB3A57FD1F0ACA23A03114708BB16803C2CDA679061B8E9808A2E11DB0957D4F73C8A06E6C50D6DA43E4D008ACA23CE2A3213BA0DAD20D5BA8B44DE5D50E188039C112B8A40B250E7E815B1367375C5698B61BD915A70096815479916F455B9EF837300908C5A8BEFA5157EB688EA02245AD3B309D10C769CA1B8E5CCA2F5FC66CC3920759A203C3F6B8E9ED10CAB20FA143B0BF0BC8529A4E89AB0C99AF77E43E68B61A9E4176066C4708FFAB05F3652817FC42039E2F22DE2058CFA8701AFFA894F3143FDA27AD85C45D3AEB30CA9759537CA4AF2079317CE5F4B5EEFBCAB981E42065AD5CB8A4CC9B628CCFAC18D2E637CB73399CE3D90A9060F88EF438E8511CE6F403A0CF14C6B641830983C1EDDE73BA27E41BD678E834167C718F5B1E2E6C109199F756905FAF9F0005CC1D110CE277DA02675461AE70EB6A412EC455B6575F16A4DEC0565DBC8F387D84F9D3AE67AB35E511657D82B5606A4DB45CEEE81C94FFAFCB88B8185CFB67E4D7171EEB391E9E1DAC625B56FED22D86E8A34924740F94A3D50CBD05B8E2476CBC7C54D2F742F0FD7162E7A138D4AC788E710AA45824513BEA162E2A1C1F709413942BAB5AABF7E347A148D53B8EBA0336D91539766AF0E827BF8EFF36389ECA38232FF2D7E341A3AA710F590C78EB69156462BAE9B8B73386F38EAC4FA26456FA555E26E7DF679983FEF23DAE87DBA66BCEA19A9F991F864A17C23F7CD592ACAEADE0E82F4737B70F0243F94F015B59330B71E25F1304DB3D8D7E2F96669BD7F8313EF9E10EB1EDB0F0BD94745D03C83768A618AD9ADDEDA7C1E6E134F8B7BC96B84652C982B1D9242F8D2CF0ACAD146EA3185E2332904E84088CA2D7D60D3E2DAE411171726B5FB6C95B3DE961E62474CEC73226E55AE7D9C7C534E278927F5D669EE6D111E325D54F338E2A6A06493D6F1B7A556A94CC9512235498409EEA477597EFAB239380491C9CCBA1F00A0D1C5D758162E9F4F5464A1A64A22C32721AE57E246722A6B2E07E544A5FEB06AF86C580DAB2B9DFB5AA0F0251E6840EAD66FCB6B89F80C2AD38383B329F9EF4589BF0E8A0C9996EC19E1DA539CFDEFB2BB0F3D9544392A06F765A74218B7DC34F38D230D1AFCF9130410A4B4FE038F7AC59B6B062EE2D2ACCD288606AD9AFDBE95D9572B78B54D26166C7817E6F72F7E6C55DD1576720E4AB99CC26722107F7C278BAC2D82FBD0A3B0E1793C2D8B498F90A9172D17244A4107D9274958FE078FA8A5A33087BF278383F439C0B41523E0E51A662A9F2822CBBB34EDA97F5398EAA12D52506C2EAAF6D4B75639EF0676F482A69DF0E8A9BDFBF6105E32B6FB3ADA2E29C62A0AA687820B4ED35C2418DB1A67A3A5B92DC61368585CF7F3B1B644A8137A52CA21DD982760CAB7FB111558ED0310E9FBA34E5480F4E707A2CEE74DC24AE5717C06DE2B509E4807824707505FFFC5DBFF798E8D85F758A94C2D3770674DFE03627457B2DF10628A31D44BD89D3435D93E4F9BC14D47E6D4B9BD3BB2287ADBCE1FA58495D9032A9A3ADCD56CCB116787E060EA431C1EA9E60A30B609AA9C66064017EA05BC16392992B7DFF62EF1046FC7E64F8F811CE50AAB40AC122CBD5119D3045ED0812F6E30EF6B6001285427B643E3C6FCB6390A9FE76B342A462994F2B9074B56A848538DE205C98BBBCC75DF6BF23CC1AF0B201E5A0618D4BC5035B9F71BCE9D3493A97FA47607D65865A5FF3FF17A7CE28C0E87A57FE951C8F804EADC21F161CCB5D1E66F1E4DBE92C69D4358E0CCC13A12DBE87C9B530579189EF2359A9DF5A8FDE00CB2B58EBD748B23F884626A66EA39847917995EADC1839BFEDCC24AB6BF22A5C247B6FABE8CF382DB48148915167BB47F505C184EC027C3AC741BB0F6676B0D0E7781E19FB8D4D630E71ED4843010198DB9B122CC301D432856B393632369FA1C99BA252F086E317229486C034F1960087ED4606288A7C89DB0EA0DE94700785322249E901897611913AA74F8BBF412639DDB639CBD1C41374A3EC66A87451D9E4127F7627DFDE4E1701D7FC9DE13DC7754952F659EBA7B1A861B8DFC78D1379274530B976C66F9CC4002563837C852D83B3F3BBFD892F14DBF64C976C924E3C656B69131EC17B7905507F78F073A7E509157215C988D490685F8AF23F64ED338915E72B518E4305C9CD44C219876456E87C0C59C5D7524C86CAA161C745364A12890064CA9061056F37ED1BD56B5B09B1423775BF0FCC898AB1BBC283B23DB6E91A3D749125992FF1BB598260DCFE428D2524050C1F545FFDA18A63B052C0C8CA4DF8C3BDE83EE5474395135FCA2B05157C25548B0804D1EDE"""), TestUtils.hexDecode(""" -CDBC27DDFC61E219B3448514C2DDD3D8A8199E8F4B49C7E4E73178708F40D30FD66E7873D6BF716588C97559C6C4998B2E43A58575F4854C6637784055A0C147AB1CC54787C73A49FB8BED952D2679DCA79EABB65926DEBC4C7D25D441C56ADF09C409C9FF12D2C43468CA67E45AD07E58CEAAB0F35ABB7F3D236DB2849DC0EAC34448643D7183055623A7B9BC8A08033D3B5939958E90DDDF6C9A7602A44F8516C78386905270FB047C354303AFA6E2A387A8832DC8B436BB178F713C70ECC12E98FEC4D5B28A3E072116B9D2F0BB95BED447861C56E6160170DA93030C32E41288C1C06794F7E6341DC4D6031051E51A18B1D7A9FD1A84A5DB0A1F1FFC93E0976F7077A83FEDB7B085CD366B67820EA9FE232C77B54BB368FC6A530DA21605249B3CEAD87C3E8B4CCCDC776F0092069679FA63DD91C802A368C5158718BFC115BBF9D45B7A87D4B03040A1E4DE2CD0343A318A04092EBFC0CA2BA1B94552DB961D42B1E638234617DBD18B4EBDA761CD35D12C30683428C83754D8FCA43DBCFD3B3D486D234A21D3563C8396E8AADFA89D1D79F01E6A139504441BEF37209F8D5C5495146A8A1951EBF17F7317D3594A54FAA220E3A73DD7EA3D193801C0640D6BCE9FD57F16C2F749B3E96B2071F5A36ED9D038F97616EFE62C383E69C3D70AAFC5FE4890D827D26CECFC0AE1C8BC96841652628D318F424F50915EC65E9DC9DC43E19C08CB4011818C53301CE8A292165DD6249A8D796B257481089780C8895995F7672F1B2124AE77D38E825F72EA07E0B7515AD8DC615735268A417C25944B33513BACD93C3502688130862E2307BA77BB74986819A152A3DE627401B268587FE1FD45B373CDDAB5C4D6B593D07A8421394D97C564F7F373C2D90DB689500E67D9C7FD52B14F7F1B20F27CD97BDB06E04E13D702B92B640F6E20DB82F0455DDB9C2420E7A51E063A00962C29B4273030A01EB60690C48660F552D41D7EC955B70379EE13E390D421F032EDFBCFD3E958085EFAA573E60A55961C2E390B50F85992864EE654007CA0DC6B2CC7485A558F5909C58D701F91895DCE90FDAB1069B87BAF2DDD822DCB61ED44DDEBA48BD257827F0D1045FC7B482F462ED3ADC794C2974EACACBE3577353586955ABF65538C942CE46A3B5C9A3255BE71DD5C8A572A86095BF4A1FC36BBD3E65E7AA536FDE6A31069BFFB676158664B1BB87144D3E129156E8A22CD757BEB1495A5C9740B0F0B271C920EDBDABB208BD544AE20B1813198605042A38B40969B0D6D044D4804061561ECF8AF816B7EF6B4ECA3AC0EDFA4C8699C76080CE3EAA5E2CABACE5FAA150E5D233BB694BAFF02D6825FCE4412725DDE05DB5F521B9E17DE3C719FCCFF0CE174F369C2DC497062991B157FB2FF36772C084A226D577E9E451BCE364E0EA32FAF6B366CD5E02C74D8907ED3DC54925EE10B3E97CC96DCDA7067DA790409F2B422616C65CF3CB26A7C6C8E9240C9235BA9B7A67BD21ADC729B102FCDF7329ECDB2EFF495122E265D0F749EE7414312532EEACF600C62A15A18172FECFA2BFA62BCA47CE794835EBE25557A61B61F6977BB7ACD04BDE30C2425F68785B3E227106FAD9E5ACB26BAD47FE1AD461EB2445560904CD6DEC4DB091BDE4CC2ABD72CAE258BE07CA0A8634C72DDF75A06B4AA84DD16F9E9FA2D2DA81B5553C598E10E9FFA7E80AEA8131C16775C1DF3E45950AFD77E9045A419A7B52D3F3B1C1309EEFC00B53060FDA34B95FA6347305DC91F477F4D99BF4A1BC5418CBEDB316FC83B090B0015BB6D0EB1AF1EB32EC962D2AC089D92BA915A8F5693D04876D2ABCDBDF675B8A871B837FAB190CC47D93C2E00DBEC028A26860DC39678B188C27E8E776C7C8C72CA22FEE2861725C7340D4B5B6D8D0FF63A5C439A1CC12137DBD14AA540C10EF6993CDB9D5F6D1C6A8980F48818AF7FF6DC75A2AA1987E689EB10BA40F2255BA2BFD9A36C629F02A8CBD4A862D9D6B0E6D7C25327CB87F47799ABED84BD3B4BA60422B5491FE512B0A689E49FC2D037B8D7B9FD5895C13A40C14525A6A1AFB1DB0A6747A3FA1E7CE023F290757BE19309154477176011100160232AF0C5BC2CD425AC5AED3955CD7E1A700FEB09ADE5BF281EDA1DE0FD91B072F78AB77EDDF7C7E47343B5184FE540DBDF6BD617719550B8658C29A276A704E500C379D03F60A2A977676F04B0249AF27FF58F09275AB99C1201702EC1B5AB7CE4F08096C561CE2AF0A373B2C797DE10C017D1D65821312989519173A8F901E9832C210729A48A58DE10E7F4F09453A02E656B629366846C5AF57CE17C889C1CF30FAAAF091EC80A831991519580F80770037F1775B534612F5B7D1FE5D161BD3E38CF00726779792C17E51ABD013D7A9989EB9A136EC7059B8BBD5E3013D03110326299134B2CC96CADC3995FAE8EAF9466D7E502AD3755058612C083685F9355DAAC4B43AD138C6CFCD100E463D17ACF63C830A899C2187E85C2BAC006D9CAD1276C2154FE264EC6E607E178BACB3290DEB1FA077FB3843DDC0FD44707096CC54BBB17F1238A975A536BC00BE8BD625C930147EEF5F110D5B2B3B3E303D44B57289A00D1E047314BD3A206B55AB72AC676C4B26D004E23E590396B52AE35E3ABAFF7E5C965404714D1ABE9D69CB6F780EBBE4027B8AFBCE253EA7D7503887262673AC0132A0E4689DD45553AEB1660A72D3AF71D85E94EE92E478BE68253B48F2CB40F88C35828274F04676CD22996D6A7F92175C733C06E0B71F077F0B7E122314B771A28786DE8D2DABC94F720BDA3980F0C97BA6849919F469A3C6B0FC12263B5BA87B8BB5F01BEC53A68E5A1CDE4749223CE118CD17EA6F2743B9ECA60DB616BF30C4FC3B15F3F43352D72B8094C47064EC5E6869BB45EF803B51DB512DE5AE26A90C3EDD184751F9179B14D8363B7EA74A27463EB85846EDF89D38CED01BE910883239B51D20C60664A70156C89D7031DD2BB0E51E1A520DCBFE8F5099490F3C1477BE812D0EA2AF032F1E628067998A671AF4AA84B694EC2C6193359E8B43404597F4C3900979EDC4CD7435E95A66DDFC704CB918CDA3541FE63355C1CAFB19E9277C7B843AE4FBA7B7AD8873BD54E4324714D80D906E8BDEB17272B722681A2BF2467CAB68C5DA699CD1EE5F1DF3849F7AA1F2321F6D34DA719E2A93860EEFD441F25442B01081511401648C778F3E081ADAF247FF8BA3F2DD2E70294B094D8C4F73292F0A28936273710E6BFAD532ECF02EACFB6572C0EAE5B5A258E12A112E1A22AC086938857D189DE0912313E53757B80A3A8C2D3D4DFE4060E1D23263A3C63727C95BBC4CDD0ECED0B1D334349858A96AADBE00F1A3D3F6B849AC4C5D4D5DADDE100000000000000000000000000000000000000000000000F202B39""") +0692e4fa67413edeabd602bff25ccbfad2e3402aa7399d8a9f7d0d6d389532019b7d3e63229d12ade7d487f1cade7f9533fbe2eb22a810c94b814a923ea83d7bccbd975af424bf5535f235117afa08156650728d96283a92d6276e34f864c37f8c11674307d653060d8310c0c7bba86515e051c3b1193087df6b22648ee59d6bc7a8c1b509b71620e3f7b5a0aa445f628e15e0725fb49e757cfbfd3dc5fe92a627bee707e33537fced3489e58fa73b49cffb2df08cd45aabaaaa491e77cf205d5be4f86f5a8d4272a5513ccdedfcc210fba346322ffeef9e11dfece2cfb7b854eba1ab581cc533cc6335b2195a20dadb86fae9efea0ab0c7d17710f8b0d8a157272509803c3b49fde1063e9297920bf245fe6502d8bf0a9a1f064d5a58b30b5a14dda6698ae37127f8d867f9aea40e93da3f4af04b91caacd66031d03c0c7e229ebeec8b818f4c970acd5c4dc8e17a3ce618ca96f4ca29f46f5e4059becc5f16ee43df8ba2ee1706c41621da8530689b42136b8a62dab7c691e566b9d48a28b45af799af56bcba07bc6044b64253e9a80e9b5ee01e8af0ca627a84d1a2a7ca9b0659dd1a60b788e5f6538a8223973476e9466459fc4f20cf2d1dab3ab137c5cfab433c436e7f3a6a681f675358b6721dc2850ec7b43aafbda90d13254e4ace6016175bafc1bc28dbf29541639527f246f6c007f41ed1fe6c0329260ce2ecc19395489b5c39d66543c0609120449037f321db95a85be51f1d01a485939390c47b53d82741edd3a5febac17ae6a8a4ca45df32fa6875b4e907d544e529ad26f29b6f923e21acd7964fe739fc1864d72eabe0859ad5e98142ead24c91167fc072a2c2673c7c5bf6da83fc7d662283347388891ca575f275907d06bab987ee5081c2ec808c81c563c902203f8d525243e20b5963967bbbdfa2e8ca9ec8ed703d8dd66c29c8a550c4676044703bc93f969e35f77194412bfb20441bc5e89b5e3238b766940779217af090e0da162e0f95761f63e05a378d0424af4c899a0a68060d9d0e5a035f6ecadbd550961850ee9345111491140810e2eaeff08d8a817700ab4c148c95086ee0663c4261b3cd53f8ab5b5841ba8cb9be8c5ad146d8549f21750be69951fffcca492624e136ed58a5e81cfb01a2147cfc5ca07a0721a38adcd25fed771411c75a5f7ff37457cab19d866b2da0fc45bc77e122143800546bc49f44909042d96bfdc63ac60f09bf4a75e171ece95bfffdfa73b4e509750ec6579996d0c83d59afc88ce9af26715be98cc8e6d05a14188a0fac6af1e96fdebe8f10b994d50ae6e84be257e6392e78d70441bdc5de30a1a4a5cfc7d5637810651fd471e162df2a76571c6d3df3b227e89cebcfec352d0f1af41a29e993af22514960c64dffc72a9819a6092150bd440487108024f0243db54ea68881d1c99b529ab529ebca98ea690046b1e37f6f1110686f6d9a7a725aa115c5e9be4189eba063d28801ef85973d0e9eb15179cb64378b6a5304cce09c82864bfed361ffe1702a9ff8e51a214b584247b967e5bb7f64b955acf25bd1073179776d9c03790d46f828342b90ffa2a45081184c3be0caf7aaf6c354b698e9256421ea3688c6fc18132d4e8d956baf9b821e64a579b1462ed4e990259867899ebddb19a861b24c20c2b0a6c274a064e1d1db366a293673153752847a2a5acc23b573ce0975655b79fe1a1ccb347773e3b1c5bb3028a1508687d17f9bf86ebbecb3086db5ef2559be02a68f1cabb47eec1671e6d3d35b65371fd5487b413fee14691745d0eb260c9008f07b5ce629c6d748c452c3131225f8c7586d99b2122202860f6e73c7def4401919e02e18471d1fd874b7c728296648b5ab571c517dea55be9f9ba65ff2cb349576a76030789dec17102a375ef8d779f2f2ed17be8fc41b84b1ef69ed18cefe28122127f211ee1abaf2a4044a3b1ee653395141da50db99dd3f73f85b5c0158a74f6f9707c7f62beffd70c068db1d6ef686cad7bb859c98049935e73aa4ea76c3225d4f19b333a4290ed0d723c6192034618fe3214306536741e20b066a6b9190972f4c4722534bf760a07e8d3a45dfbc67dbb8a5874332a4fc0e0a0640ca3999b93d34e4d8731957465e213577bade1f9b371540dbba188674ea205db7b244c77b6a772caf69f8b46b7b05439a852232348ef6d437bf7c6c79a4c0520a8ead1f3c00de2a063eb5a1e162f4db1ee94f1fb94f56f62d951da29f6b3018485c4a5c2c5f8573691aa096d8cd2922b66c8b7fc828d49e92a3d648cfa8ef524199b4bf5a8f15693960c5f59862825ccdda554b17e9c35f7e6a24365508f5a23c6ae211e3db71740fa444f92159c8df59c4b073f362cdb658842466efde20e9ba0472e2f682ecb655961ba8ad7575e8b02320ab6fce9188321816968a15789977084409d89b487253c778ef1ea1a1f47c750e37138735bcd58f6956ab7c8dd1c8a7ad35067c0ba0940b3b091c362d3165007df94167f33e0c660cf02ee5d6ed90c8ab4655ed47655d810751dfb2f1e65c890ed24c976bba0b8a998102d660a05325261b38fdfc82ba300683df5d561f73a11fe6f06425d11ef4c6f32e6de2ee6081a9b772e07614866f54e63ccbf7b1d9a1c3701ccbd1d9087241d8e2987203dc798d9431b8ab1fde5ad788db13c2e996a1d21b1559cffe3f7132e1aa83acf6c517d8e8d719076a36c08b2c6afbe5d23dfb9c5272ffb2af2b8febd51946199b90f98e7d49358057fb881f4e8641e0524c3471c0f6bb4cf59bccc7dcf09ab2c2d8a783710c982a35e4512c30e1c19bbfeffd992884ade3dd2a90039ebef2c23ab98fdfaaf6ebf34ae7fcb7fe742798c50a49d740244e65c49b22144c05047061e592b32ab61733a73b55ae04c9f36273dcb2eeb4872e7b7d009d4a54b867613ca0f69c4e7756a48ba7f9539048d495a578b8a76cac198d77aeb6c3a7dd474390f91faea384c94cfd73486ec226319946fd829c3ced266ab11db84176c7f67502b6d50ddf46994d6bf748f118045457e3ad7192f0b03c2bcb2455d018bd0ab1306b473f3761fee60d941637c562cdcda0dd5d5e86af9e95bc22570c07c25d5bbc6f1ce04be9e7bce5f7f095afec8b7c4cd930f9bc106e85eb8620668b52c9d09897460b1c8d74febabd73ff9b730c291c28f1410b442d91c533383ac3f2f41f0bcfebc9121b00015d8c506b2183b7d183751636da9226b795eacb2a1223004ea8a18a805b272384ea239ab86b41c556591fbabb783a6f909d5a181f3563ff1f9abe58cc921c751f3340497d94b1b2c6ced1e3e4345e73879296bfd9dade021b25436d73a3caced5e2ea070824262b5d6877aabfc0e8ecf6fe0000000000000000000000000000000000000000000000000000000000000d172332""") ), new SigGenTestCase( TestUtils.hexDecode(""" -ABCEC4A46E695FC6EBE64A191389F0D0AE180F911D5B824F4ED9111728FF4F9493EF3A7512DACF766D576898D33C4C8F4001B777EE5EC2E2DC1A8E3E181B43418AF45100B92A3835D02B9892E609B2AA8C6AF7661CE0BC8362AE0DA172A79E84FF4CDAD8607E4924FF41DB6EC28DCCD09B8D1F5657BA17C848BABC71BB242A50C44069A0200101914D130822C114288436508B0422D83004E23848032532CA902509A0009A848440004CC3304D04C0601CC84889340950B68918C81103410D631870DB444AE4224D8B96491B0224C2802904365290222D424626E0060613B12DE1187203B18442228144027159186C22092C012751083160DC48061045089AC444601609240224DA006623945149C200182232CA462A0BA16D22B2215028700AC108D1828C00B24014083221B5810C4501240225E44291984622C90826532650DBA8495B226294B049603050242382DC0429D2260254262CC3A868001546089168CC067184B86C518285DA221110402494149044B8102220299AB40190824D523050229668101072913411CCC625D2880D1B1951C3888C222509DA20322003209106028C188000B02D92421111B92DA10890A228700B4464A1B01153966800B925423860884688630800C3C2910BA9511A1902C2B229532052D9906DD9C080192400249589E004914180600022440908012435624C48864BB46123C900588869C1001251248960B64844322513C5318B909118A8691A850449B800A3B02598A2052293455342701B3722590860911248939221D9024E2042601439410937318346851A836D192751C93686111749A0B4649BB285CCC049C0C4611A066203C304A032248CB861A34408CB4852484866244610A1068909280C01810C028531232102E4442C0A988C19C54192187223B168D844862295405824408C322222C27110170A910668D438529B025212086458185208078DD388240C1092C2C60D549640031989093530988425D104524C146E62A06C5AA004CC126AC3284490268A43468021454460B249A390681A4745D2965188220E6032249AA6280A034A9CB6888B180CC1021012B70D0340480CB3444C0010011549E2B23094064504378441B2401AA3884AA885112229D2402550B0048C2621180872912851481842499020C9126D1A1289A4404C4A82710301228920449C48624006920813819CA670D0C808D938721A118A1BB589111150C3C6695386851A0204D2426D19116419A38152C861403A93CB8575520D2A3A7317CAE1963E2705B7596C8E5DBF0DAEAF8755DF38A5DF16297CFC84097B480D9729E4CC62170739A1A8A2057EA7FEFB06275344ADB6934E1C2DA7E7F3E831FA35E6A4B8D8DEF435235CE957DF5FA1D842962711443BEADE91070833C84264B45E2380B094202E079A0A7C6058A54E6F552F202760230F6D95F5EA873709BE4D7603AC010CFBADAFE229CADA1F2BC717F877856D8B930D0E215C4BA2212D66E21A2D1F09B1F1A9BC8C298CFD65B318FE91847279F204201203E0922E82BD298D9BF18B8FBCF72070F7C7C51D5480E60674341CF263FD179862F37D5665FE35ED0B2A86B7115C90093F5785309CD56C48BBC50570A0C2D066BD0ECCD3C86E2A6C8B098AFD9C0E235CEB920D58F0B913BFB633BFE21BB1668D9C45638F5CE9650CAAA83DB2D9B4B24B1F518B19226ABDA06239698A90F30A50AF69AE1D20FA00E3D88FF6F2C2466E45A39A1C946FB695888383CB6A59A7C8395082134A82DEA3DA7FE6D9E6F76C7E86A50CA04990C70DD5F9AF062ED14CC661F453BF309DA08056E19F2F7B34A15235230C15EC6859D7DCF0ED892DDFF4E5096B36B406A10CB35AA81F72827C5982E3C5BFBB989E062CB4A7F0F76B008AB8CA5EC1CEBDABCAA1E97809B44C5F49281415337978184811ADB8131D2DFA2477D27532E92409493D46C597A6886250593FD58D305D0760CE8F772337D42B0F7DBFC483A941E8CDF32CE3E97309C3C404B6E4101678F123438853FC8A71C835D1AD0C7712460DBE83C1ABC6BB0834C0271A6627E7DCB93EFC25F78417BBC801488E5A051455343757F6BFAF923867C45ED5BF37304B11E012EE63A3B8D84DCE7A15D5AB940D87FE1181EABA3C97BCA702F5DE4DF74848A99D2B1F34FE2B03633D6AAC900A09C278556172DF5D9CDE361A8ACD779465CBAF50DE5C8F4CA0D15DF3F74347C6DDF7D9B3E3E5E197BFE0AA170949FB42B78364A72B1B106156EC09A6E4EC72F3F814781D3CE7B7AA2B02E49CAA25AC36DAADE0FD570A61589553A0CAE582BA2894C82C0380A713B0B74924E006A6B341F21AE2AAEC2016D2687F1AB696337F5A268B3B6F3730F507D6122DC92CAB36107E864BB3EDEEA6FC1C5309A9B51582CDFCC1A899929AD7CDBECBCBF9D38121D58C3B3E6D9BE001B117E4A7F762816174B761EFCF291A1CC5DA354029962EB8B0F6166A9C9EAF26921D1777E621C50C41614300605B1EE2A0CC41BC666CE90A15733C69A82451FD41F23EFAA73A2482C4E3D476CCBBFB59B25140FFA0C1CECEABD3B036F2611C83AA834E6CFE03963941BDAD4AEFB11D01EC43293BCD22ECB8784EF5CE2A6042F200F1B9D6C595EF920C3CACD1C1C3CB61B6B46454A3B28A472AE0203038A5602CB9B001620C98BC09BC2DB5621C8DB085D88561058AEA691AFD199C6D4BB1511137ED2800722A81670B44FAC51DFA6683675BF34C52F6EB7EBA35D22C907A207AE5CE6C3C40AB0A26B88DAE777E10B4FC33AB38C308CA2532032A7F306E9ECA723B58119C3BE662817A1EAB6069FA05C3B0ED31060D5794121A83FBB152C7FC05BB753C9D29BC329E745D7C7D493372C26C0336AAB37B884FB41741B344EE4D247D6B5D049E5E322CC97EC6647EC7551824C6AA9CD249F49FE1652ECFD01C3E7EB026FDCE7320D21EC9E4D460E50D6440C7364A15AE3C107CE8EE1E8A33EBC9D2B5585B8F69771F687EB6940C21F45750079D68D3DD6CE1CD7CA8D91A64D093A25A96628169B675CDA9F14FADA4AF3D11B6524465B89DD4EF93A9A159F8DF2A134FEA301110EB77E1ECA51166D26CB036BF92F1655167BD32D12BE04A91FF0B3C52C69DE376856FAB9B4E14524E5858717ECBD0865719BF1DDEDDF8CC141396F9F0B4ED38B0CAADA08B64451AD8BD38557660CFEF46EC0059B4AEA6A7534A3DB767C537E60210A1AF84EC939413FD7EBBF14FE96D6EE82A0C632EDC63715C0C6654AA4FE298F43ED5B47AF7350C32C8D7F696F9A96B81E9832F486A66D9B304A6531139561FE5A967061BDFFA4793EA986C3A2693C21DAD4428FE98F168EB928FCBEB8FE0A611049C1F430CCD80F9181D276AFEDAEA40261FE1B038F5677AD507EB48B9768964BAEC928197AC26ACB1A89CDDAF51C4336B6F49985C13926E76AA7D69F5F0844F23E7B2B977565587718903B39173F7F18AF84264370BD61020F2A76ED281687419E334443159BF6A21533F41E030654F6876AABB21025B6D2312304FF8BEFFB7AD2E225BF79F1B6F8C33AA90D9DC18B369846FA06548E72EFB2EC4FD6BD833F1872DF9659F62AF040345CB5B8399A4836F7F5A9F920F0484009C1F6871D2"""), +a15c38cf5d89e1912b7ecbd269ebc6ac156697942a3b2557f5cb631782ee2ebfc52465310ec4700da139935b04ecf37bdb69f0db1edb595256837cacbbfa9188a2a46e985e6b1f7342a1f663244570c6d67dcbcbbf4ea86cfbf98cfccb03d10c2848232ba97093e393ee4db23cdf7791f1adc46d9de05a91791d4702f9ac41bc5002645124910bc6404a1451e130285a025160a629084850d2c205d324401a963003452194488848b61101436ad2940911a36d04a90c1b05708986881a97051249291c22325a948dd1462c19b36d03c74148c08822377263082c6038450c28889bb60da240285130248002685186601ba46942266ec2b484d30206db041203301193183261c42519c2290b0152e4c08dcb2011d1889119a7450b2548cb222e49882c4aa664a13848099851e2026d54b2219c800959381122010924349053224220060859406009274ce1164dcc360cd1b810d94032c24662dca84d43122a11424c180122838811e014060349814830320b132e2285699244895a36504b241102954de2a0109ca6495ac00dd4264a511222049440d3460cca2229e3321108054581902d6036900c826cc8880843000c64384262326d1b408821842dcc264c1399089b48690b3970c1481282142613206252226208389112278c4ab02dd8c2604a240c53a20508c5241cb48514c869d2324a19318a59022459106c02c929e1264ec380009802125b16529844010919410c221098c69012108d20002cc0346e031091222131908020d9c22400278421a98820938804a4894446859c322d82287262940503094aa0c22c20820c22b5855aa42914850c20c680c09661db126221324a19a2694c12025a1291911629122171c0406a49340adaa6091929714bb405e1108e1a448524c420d1244164302c00432acb3024a18225cc0869520024d2186614846dd2b66811c311e22866093225e1b24902c14c131165420070a032715b848cc032281a2068da226a519641e32464882631124952e382910ca06411456c84b24498384923a66488b208e198088a364408288cd01401e41400d282318b00469bb24410432541c668cb4426212910a002260aa8450b262893b6444ab0005a4801e4444e81c830cb8490183931841820813285023951c01824914289c40406c1304054a831d4b61018998d1a368911b765e24465cc1650a41251dc0812e1c00c00b5650b1229c4284104c84588a271e3188cc48608001349d8368280406514b045ae75b458c51bf83c97926488b9319add26f6fdc0a6e6b427d7dba22425aea8bdae2838ce001237c886d3ff6d54cd7c7e3e6af667c824a63e53772c5ec84d83519391755e37b16b80fad2ed94725bdddc3486bafb38e521839fd4ded253cdaad925e61e613f1aab1a448212259009260fb80e0a7d0ffd726c7a40d462a1a3fe2f3e4717429bc8dfb40f332bd927d064ea025e002aa2210eed1a457ab68bc0248b68325537c328af312744d16cbe8ac0b1c9ac1a3a79afb3109aa934f2a21f45b0c5d6171ee1cf71db9940d186be0df7c9d8149aacf1f01d46ae77e41635d2f73202393f73e7b2d14ebd62662c94d65f1320f8802d9486388ecf6b6a93732646c8c043d39dc1b5efa33a72c1fe0bb345598724325d3f921694d0ffe115aca5347f73754d5fa7f601efbc5217827abcbb2ff39bf453398e896218f821cf5a0eaa60048e1329f0ba4db933a2d6aad7e1de6d011db3305a8d6a1893a55de3073a5e4cc381f74805d163f238e81b55cfcd3362b774a3ab1f99823abc8d9801c90d8597a8feb3be962b9552145401b81a4febf84a269bec2fc81e1e77aca7db60f18fe3e42eac782247cb617578863120284bd8874f798fc1c427cd2138a8b5b6fdee8a3b271ce23e45dcb71ab8e63040274338179f60729650a245fe491b25efad8b000b91cf551afeb7cd7ce185de74a2e79a57fbc10f9afa86a869a5261e555a39e814b72bb251277ad9fb91d8d1565b3b0929f043cc4ff692ff0b1dd92530904521a56d6d2916f1516b09d35cb7b03e5b40a1ce80a9077ca6c2159c8eb5b259d5edb6d800463fedf135748de6d2adf32eb6be0637d567ea71acf992512ba6493ce3f318bf7089cbb195526c4b01b43752de84247c38a7a26acc2de492fe300fd19759c47e87b4587e4a6f6c92c3cb78cdd20650ef3d2bbd33388129cc01ea69dcabfcad0bbcab9757cffab601b6058e0424036815cbbd337a7fdf4b5f10f345ef80b3f357dbccdad0c6661adedb7cdb49a796379face0861a1c3ded98b63042bcd670eb19484de9f7bb5219e48eb89011ef3ae9973de2c95c84f6cc92c09b84d32da39ea91b9990f1e5f39a9e0380769d5c0b6434d1a687d6eaa0c199ec2f297f47f160370e22bc8dbcb127ef9e40316fc5d6fe7ae17e0b4a5a606b3b717d2ed49cea5fb905615380ab861e051aa98b6cdba93b5687755ea3c94dca0dd3cf0a23a88b2e13126931afe60949c3fa2ee88b6f33ebdbb1dfe2c4a7b09d154d01edf95f93fa4adb187f8bcbfd736e02357f5bfff2c393ee27fbee56402ffb58aa8fd9cf0d51d6dadbea4ab97057ed0c7308eb93c7734cdd5c1bbdeb97e57ccdeba01a8c808403a4091f92c6f296cab71e159e71b7b7b0b38ace2c4129f8d2851a8ed353cb2eba0853e2d3b80f39646a6566ab1294eda5f39c211a130d6fd5fa66372c96cad36c4664fd5b6c43ace7913c4babfc343dc99b87d67e1d4644524e5f62573b44cfe62fb9718be0ebbfe9c2924c0dff234898c5378565bee676ec0cbe2b50abf191ed15f3125987af4e0d78a19e5208f1cbc8c73d8be34be57c373aade97ec18dbf4dbbfc06b976261cf9b1e0395997eb8773a15dab297f71afe40d8baec46a96143d8104b7385669f23d1497f99a525f72a278ae4ef39add1ac5ae5c92c1fad9473229779cfb9440a2412ff4ca5ed6c2abfbedd16bc9585c0900861464c8e489089102abb0e585352fff291fd6a52aaa187f4d977b6fe3d3429c9d46d79e21508e400732d318cfccebfa1f6f5fb0f2063179cf1df2bb59323efa12766e81a572ab221a06e5a043808d43a2275d9d51013f91a2825e084bf9dd5e1e3c2ddd5c149c0fb66f80b2c90dc09d132bf834156e605f33f0091983d600fea8cb5710414f60536a3f9efba209b3eb06b597a5eb6af3f80f92b12c9ad310dfd1d7a3e3cc23444542d351a3d4b6d08be61ff43756bcdadef51bd4aa335a174073ddc551b661ee1c211866a52bd0ca197c72078803325956d78dd38a9247676890f46a1a38630048d266e059df2b9051b17f8c453c532a818429296bd71c91c446142313e399d08447610e941a9bc7d225770a075a955d8ae027ae0bf880862ad81b3d2b6cdd9839a7bc9da8ecfd6c6d56140f0cdbc8fff13d8fdfbd8ba47d93fdd75df792e8428460523fdcfae6e4419f38e797bb06ddfa896576a4693bb8046bb27042f3899cb36da3f8650828b99b6945ffd6c7e31595ef679a1277be4e627abe37216515afa2b4599b7cff8d493601abf2bf09ae9df92a04d34881ed1efb5bfcd7a7e1afcc1e40b5716b3cd36d98c91730b795df899c5c8c26a7d74cfa8b1aa90c1648"""), TestUtils.hexDecode(""" 22AA98C685E1552B525B4302C943037F668279C224B6270DCAF2B06C4F4AB1254C48DE253829FE6DFFA9CB6BB294F054711BAE3FBACFB900CFD1F0844E55D51EC6F697B998759B14C13392DDB6F7DEBA77FFC22468781CE402"""), TestUtils.hexDecode(""" -0313B5DD1E344BF95EB5D825837F570922337633494F8F2EE3618AEB906DF766F5ADDCCB8EC1C5CC51AAE0B9FAD876FCFF5D6814357E8C63FE59FD72DB3CE4D1650660A0CF64339D8B7C6DDB7A7A3C8EC6C88F2F0F70B377D9D5E21F0D40E17573F07C94CDF844CB6794CE2CB8E4A11254FF0012D562DCF4D9FBBD18348D13E1B69395C69DCCBF618D7A38EA6A51B9F1F8CC70CD36D087682A558A1EA9BF9DE6ACE5B350B6EB977F435CC46FD43F155B29822D68D1CA9603BA43F1DB28BF4D3CE284523BB440D1E2C124CF92DC74F19B74CBC177DE9B08377B0E363401D23E97AE967E13AB77E9B7C7488E49B45E835136EC2874A24CC79059DE5B0A67C842F2E09B37B3039DC186427F760CE60790A9FB58AA388880EC720A783EFEB4E11ABD817A7EA884E5EFC279AD9E8AC2C58A41020C7468A749933348EBF78A0F0597B29B00A126050FA40F532B0F4411B733BAA5C80CA1B52828CB236268989EA2641431A359E6595F49B4FEABFA85ED4BA85443E2D7B82DC7523FF627D336DA1551897438100C20F0184A963D0B9AF7F7CC9FD64A2878D8FC5ADE2D0D928445EEBED286F2B280AF573EE62E70F698BA0C14381A5B4E001C53C49A77E9F181EC65B49E6CD8BBE30B5F309686F7DC80176F654771DF17FDF136D6C05498CC00C476E71608A39CB29A19A986297CB9C1E3FFB4BA08ED42AD12908287F018D49A0E1AE89A9BB3F932DF98CA91E691AB5F3BFADEA9A233350A9EDE63CFC45427CAD109468FCE4ABF7FDB83C6EC83865134380D3FFCA4D94C5604DD9DAFFAC204C14009FE06311B81310940C43FBFCF049F99F5DEEA649A333F6A3AE6232EC7CDE62C95338C23085D776B9B8F4454E03BD0FB28046618C33A7CCB409BE7BCBC0906B5A9424B41998A3A1E65E5EC667A14339E3BB44354047A2868D64B78FE5FAEDDDFFDE497368C3CC130D0821C1DEB2C43119195C6C4CFF1D5A778965FF97685DD93775837EA0852284C670DD418DC9FDC9C44DB7EDA60E58030D8FBDF86D48B98230E6AD19E97D21D7358510E20EE374B8486341302EFA590B96C1DC253226A12CAFDB3B4A31EE2270F764B74F17BF9C5681B6578777739FF767D4E094CE80AD9804261767097BDB163430332C428CB3CCD9AA881316B51556C718A95816797CD5C8A2A640B85DFDA520D1A0129F0E9DE772724EE8B74B4DF6793EBC0A801B6F77A2647CA2A5F564D336BC23ECF591327A8DC4214953D99EA3A9ED9943F07809B4C36A8BFF093721949A2AEF2CDD9687934849CA35BA1F38743AC663E48B39A2A32122B6951CF6F1BE17FA96628D8DEE8760CF7F2699045DF30484722601E7A45DEB277CBEB749F5CB4383C8643241158EF13D8723B9B00C98F8BC68C5F42DFC4A1B8D95F4652AEF67798A8B3C0C2AD40CB7A2B88A23650147E32CB605324A99370BDB640EDAC9CE57EC22689DD45D1922811584B01685615520DBB0FFBB028E43B77B54AF4A3EBC6B9F857E9100FD9C64028867999BB9C7FF05D37704D41C94CD63DFD1A7673F817931A4F2C42CE572B24FB5E779897FA4E6E2191524783C710A099D1A6BB9EAE47E849187432A2039BBE1D37D0E7C797907F99BDB8E7FB33C3B2FC9E06708312BEEEF2935D443F29B646FB5AD52C99EB71559571781A4C86250D262329FF3DAACA18A5E7B77C3CE593CF3A92B12B9AE86CA3AF05EBBBD75B6BEFC368982D96F2E5FBC128B6A8D65FDB0B0F7859689F0B6F0A3D1EFCBF1915DC61C7FEEBD077F71122E77775B4279F4F57ABA521BE4682DAA5B836B5B4D44CDB726DFF3AC9CDDA9F0D1CF4E79BC9E90DFF7562CF206E756C38E708BD30820A14C595288730F42C8ED99A7C1F2FA6CA9759CD31B8F28FD35B9E0980ACC3432F462CD9CB4C594AB63FD250DDD4877269056677EA7E3B0AACD4757AEBA398688423015D952D0CF67E5027BA4B6B376F6380B5823717D64513EFB35015FBD20FB2284E1E340C9B94F87CFBA24310325D7597AB34BACA6753215AB994390C2E5A82EEB06F338293E72C5D0FF786666FF2EE2D429461F1112551AD0928844D7698D3AB0C4054881A623525D728E514E12550AAB227389E5F0C2341A6AA34BAB5472BC9E465DC24E9910175B2B968F2E7883CD22CC07B3D203CFDCDD877CBB28368DBE668F561E3FA1C5D3391D4A408A71E0BF0C32C1FD6494DEF7678E58B829AB428509C33F2491725959485928B2E7FA96EC7AFF12BA3196087D3C83DC242E5EC95BF95C8581693FC0B744E758E1E85959AB63E9B4B0A4547BE5ABD7D29BF9DA2D192B4BCA491D1DC856EC80AD6C3C738FB775F95A217D76093852AEE0CC203DB1316C6253BB75CE2D92906B47A5B733E4A8B0C28B1283419249B5A05F6302CE110F85790EB46DED7109B0DAC58A4D25255B6950F3B2C3421140E4825B6AC968091EA7AE9790BC8D03F3F8F4C1BF1006E821E5DA2C65C542183F4230CEC934ACB81FEA94D959FB6A21C7AB20652C9B247EDEF72674FE915858795A9A00564F602136C364A6D9638CB1BBD8A705B90429D13A19DE93520229282D5122EE112A32A68E23577E358FB28EC45478D05F64513A9E814A5F1FC7CDE4D03EC51ED41D29ABBC0F60292E2F7D0AA4490C38B583329E2D5A1E61C73D6033CB73A7A4F75ABBB29A31E52CD1EEDC3DC4F0B9152FAE6B29DD1F9739456AC5B1890B3BB00415027C634F1E6374F310C95E680086862B8BDEA0833997746814FC602F97999A2309D4CC05362303F72BBE2EEAD04D566579A00A8265E238FC578FDB2A63C57250B5714F2C6485BC6247752853F75ABF066637645A5A6AC0E85459EC2E24D704ED7DA4BA0FD23748D1D853BCF84D4D00EB4B6DA6D036B8F29797882EF5400F2F7D6EFCDA0418CBC5752AE5431B59D2D518FD752467B7EE13F699CEE1581AA1A305B2ADACA12647FA8FF00B427F28AA33FC094A374521437E3B4A109113E1AD8AD23E2AEBD69EDECEDDFEF0B5AA0A484AE32BFB2B05F8F7F65077F5B35C99B61EC28060437D9CB982AFA28FFE8AD4C02BFBFB071CA8E9EEA15CCEED97D47BE2313E3C344793D40B45F709C8A2C639C09662A81F117839AB62135B6715FD57F7B0368C6EE1E3234655EAE94213D24D92989A46CBD5C7EF116243A085462C5454949D41D2D570AC810B54C727FA5E187D0D9F7FA7DB3682D99460F5077AED0A90D513C0D833E5F5A91A5A26CF47AD134C074D658AC0164ACBAAE8FAE161E00C7F8B043FFF46FC5C900C9ED14C44C98ADDEDCD5F3BB7038868F8460EE12472DE2A24BCD0A611D9E039D60000D131D242E3C436E808FCDD3E2F55667698D91929DA3A4F0F72D4B58636C6D9CC9D9EFF0141C233B3F4A53595F696B6F848AC2F7FE00000000000000000000000000000000000000000000000000000F1A2536""") +5129dae7c620ef4c5d6b0e0f7b43acd806adc035cfb3901e162be14f2371bba72674649e2004b4d055ab533316dc520afa8c80e5285f40f7ea4ef876e68b0aa4a559ec2363032efe5fd5a1d5050be8221c24b23c403ccf71bde5410b7e5ded038255dfca9439992fddc4fddf96654c78098c84e0182d954e204510bc7e5635ac29cfef21042bd52dde771a500099c75311c8657c5fc5bf303b7769ce8c2de7548b388224e727505c42e6bb69d48d845d9a43e845e7305a098657385307ab23c6bdc70de07868ecc1470b98e2da98fde4636af76fddbde6af2b60b4f27e38d4a86bed60e6f995533261cf91a618c07df0f659561f61bbbd70dd2b020cb04ac1fb6ee1a31ee4f4ae5d0bc2af22d60701700a44f2e8d11b72f4d03b3a96e2fa491e6e61f8dfd3ca678e4eedaac1e6bf418cc4a34b24bddfce3975d84740f7fb92ac2dd7aea450f91bd6ced924f7204754026f649868ccb103100b79d3ab2fdd2f916a76a6212bc583f1f5e541dfbbfb10234681c42ad56a95331c90f5e8b3be82a5b82ed4292094d9d60569fa760628e082740bb2da0a14b2516dda632c007ae3089a2068d2ef48b3f713999a699ab180ca99d7c49c4a0f40b908dc51d9a17db286721f8541839d6acb5eaefcaba5b1ba21e5ace4be0924eb0246e4d195a6eea6e962bb07bef9001a23dc0be7497a1ac79da047ed45b4c38196100b7ce06f466df295655076d14308d94d55103d36799a0683573768bb6baac4a10bd3120e9d47d7798121ab46521d7de8d1c3cd9618347d8947c47676c547231e5be77153f02a3eccaa99a75230e45fd4c1e6a6f951d1a5e6c3be098caf4a16ea3ee88473b1a8d91c0886685409ba9a099bbc0438fedd280f459de3c9c57c92609a865add4cfe76eae9af088680f92a68ab78765f7ad0b95aadfc0a91e175f07ab1f0887b1f448530866f002fc089a63a2e2d33ba63ca1985737ab0b9a73d23af11420d62a8b619dfec0830cf62757ae7f0402a4c0f209d03ed8f1731db5079dc5671c19c5bef712d34479b7f879dbe694e1bfbabc9c05109c615be763dd9ff5ffba888f88b62128b09475527d12203ae67f1ee8da83678b8a4b7b16f7700f919874eaaca48c10cef50a0f447baa17dd19eda59a1f71ad1cdc88e91fd91424e8c668fc93690b9b5914db40ba677a3c71a6d2cd05f42321463c12d55de1a717f69c132dc35e3bddfc23064ee2183e175e1ead1d075c7c1115c8cab91677ad6b483d7151010a7314ad558eafc3128c2dd590aa4e32e8c86cf769ff58ca5f37ee3a4ca0c9f9b2c4a9cdf2a8ae52d1d09110245a8884ac52c597e97b0b0304ee706795abed33f2f1885973253da8728742b54d4e908536c93ee11c1cc36da21d8ed4956255c0a28262baf50ff4a8df767e71a2d920f53b25084ed2cd8069fd13c0d1ef81f6989c0e93609038e9c6174d2a9333b3676ba24886917f32b7316d45dc6e99497f813b599d0bacc432ede0584c654551d3217c63911654b21e0631a5f7abf66d48b2cebff62cbf41ded241a59816fa9ba99cb29a9d000873fff81c689ee95bb9fd31a31863e1bf08fae8b27169c7705344b7085c917bc4434c9bcbaa27423f634233f75b82ebc7adb307f6cc3310ba95478572820973732f4cd3d1f749b728605ffdf23472810d01f6f9580b3852a5c2c7be4f93615960541eb2dc4d5557dffa8646d916370f89e09947e4e14092073357283fff846bd6b83d81092639de3b6ee260770b21275491a6300c12d5ad261f19d8081c9a659bb3f45cff2dc6c04313c7f3fb1b2d4ca96a603259310628356cab1431bee201ef7181f0f9d35e13b6f89a3698a56c3fe08a76418b6ea10b70bb2c0649f7b506f4b15a2578902d6df4065d4c3e79ed26a0d965e97b5ccb47110cf3317b7d90abcc9c7567ad4f2c11c5ca6617e643ee55096894c793d18adcce74c19620b112ab80152984de200d4e4a6ee29ce266b47d662accbb42fc74e7e088138faeb06f32e469d019979cf0b55aec3f420f97029852379417498605cd513fae94c5a5bdf3eec29c54634b94c6a96b0087ef2c8b2e32ad49144a70d27026a5900f9bde658645190ad83583ce8d4a174bf3956f3a581d7e4ee013a4263172d09b3e888299a06a0dd4cdd7e2a118fd753791afd91e0acc9eb1e4d3322feb169e47ac2e9e3e47908f293cb7988387c956806bc4e5bb9f65a84cdf2df9376c2eaf3ebae6a9a710da2083af685a8de79e9e27143c6894a847aa9134cb184b7dc7028b664246dda558891bdbcff3af3a5e0ca8ed06c1402d31cb5afca6260f4cae55fb6a6781768e6a1fbeedaaaee620ec0b7b964a38bf46651de29e4ad7247359df1cf4e50e71f691b73092a2f75f4669a145ffc5a51d51187f42dba767d28a39800789c88752be0c0e0b5aa2aeb3737f1028db4fba59dfba974f9ed8734a57f1f2db29d14f708cb83fbea9e4889f6bfd6f09d714ffe825056215be601bb8b6168d787a6d17335b87986913ff6aee38ad38f571435195b439cd82930a3386ba6e304b72fb5cf04b1ad8d64d8334f5ce0d14718232c613cc12ac1341706f829fa50a5c3010f8d5daf04c3bfde5ba88fc873a2e018d274bcbe85a9559eb224f6c23df124263772aa1262d9932ab813f50317bd7d4a6b0cfc207d8dad53d193d7330c9330d9bf866047237df5baedc69ff546308d2547b5c7f9e0909ff97da474bd3075413b94cf97fe331201f2cb565438182f13acb95529fa6cbd18ef92dab1bd8522f332ab5f375fcfbe01a83e38eef6381a032f9adb60b59e5eb54786f5dff4f5e003b79c7e119663c38e7e9baa0199d3ba32235166936a850c57227b1a16561ee407f7bf09cf6671ce0d0ed0f9d7f916a0ff7f41d8adff8c42b8f4640f1488841cd3cc1e38918dcadd752318080b4f15e58dc7f79aedf3805e1cffc25bb01591f15f54155c59a798a8bb9d5247eeb5d9bbb3abfd65f0bb65f119dc05cc0105475fed4f006e61a1864a29b53770e5b3cae2fa13b5a0d1b05ab9db868a7b1349c9b31d1a1abc19250be50627e8f7283af7d12c57a1c110cbf4acaf5990621d5c04729d475a97cf21c5fb252f5f1514b8d3090cf6e4e22a0146fce697d88d0637b3a60e77b9cbf527c4269adebd5eaddf12633c53f1ff09d869a846d3121371aca8252a5ca1f4fb1b7afbbb3256e53a9f25a3dfbb3a95e9beb67711d27689a28aac998b3129861d9acc72122d43c300bd58d934bd9aaff2ebb55268b94fe7013aa8670a89b19e1cc5d201ce2e73f6bcd8649a18f8caf1af021d374570728690a6cff0f3fb04050a0e17344e7483879798adbfd2ec112325282a3b5d6d72868c95999da4a7c7cacf141a1e2c5e657d7f939ca1a4f3000000000000000000000000000000000000000d1d303d""") ), new SigGenTestCase( TestUtils.hexDecode(""" -3820A7CA1DDF6D374E8053628E628D142C4305EC1F3F05C66908FD5A1720C7F02EDD55DC8D2252C7E3FB5C91BBA1C615E23C16AD39B4FF5BF62EC0E22F081573D22DFC983A88CDB217F422AE9FEA6F82BF0E72EA8E6193E9DEFA584C29A9873CD76741016481CCB01ADA6063BC8BE27A5887FABA7F701DAD4114DBF31357508E54982900B391C1A42822330C82485114330A14A3601BA310D2344D63368904368293100840B42991C2405C22290C492C52084208A788CC266682148180300E10C330928021E214499C904812A169A13009A4908518882420926919A44D2448612217821A358019B2891245619A342A2132665B362994220E942812CAB6300A9251C910295B160848486E9A90641A238D0CC52022B9318A3266A2B82902440463380A0C373022B22C0B3152D40410DB100011265150C245424622103792882691D8207221088C8C246623044E1845698AB8886192004A244C0CA46518206C8A342C12498A1034455B200D02184E98420D09A30DD94028CCC821200150E4B02981466821434880C46DD0480E14884152829052C08CA4B26DA2C401540850A3828CA0A248A33240044032231041A3C680D3042DC9884DD1302A93202A0C250A991408E3160548464C64A2319818122308865A926814B7219A2071C214640028509C806413996D99002C1008909B925018266AD4020453026001950500953113A385829820C43651C30004E010269824660B920109362E500889E0326C14378C181589DCB864993271A00260C1A425A3C8718B8829CC946558243080C204583465D1B01088A82422120219244A02388D1A295244446E10320514488C13814544427052129182308A1BA14C1AA3119A163200B53049322AA14061801885D822520BA091D02422222112D94409D944215C84811416641BC40940088A61C40DE0162120842CE19000E024654110721B364A511085E398719A448223016C12A12121C4240A346520A850A332815A2051A288500319421B2831D4346C24A06082140C0211889BB009C424001034525A482AD91252CA96090101611892604016040B91214BB66910024840C40D00828D081161A142310BA424522612C3328820300D18C705243505D4320E94C8841C406253364811A061214669589611132001D8A430400431DB18120294281CB0291C374564A88811824810236C01C2500A24094A842D9936688086284330719A280E04A24C091312D124718298100C297123324843368E17AE9DBEF07C60FC5C871DAC487C6EEA46F0FB8B88470DE3D6C3F2B75C615689DFAA98540F2A9D1A3F8448947B6AC7D535DE9F3019C60901BECBADC594124FB4C677CF4341088FF2085957DF9F3837121DF75F92D40EB77D6F4B0AF61B2577E432316D09DECD949F1A31EBB1E4B51E3D412B5CC66BC65D4B399EE83AE52F558994F5C0C9D15617E43E9AB83A34C16D097A3690677B35119EB33D80A88F1A8A77C2343A29EDBC9B3D77E52CCCDC1977E09BD3EC6C8E05085D23C063F785B518E49EC3BA8AA156F16C760DA4787259398A9D343E5B37602A5318DCEB6F27BDAB8C143FF882993E80FAEE6707B26263EAC39E22980BFD23C61ABADE42C22549D493B23BFB6449FE242EB61986E5AB99832B161EF32CFDFEF5221C2710F1D316D12B170F4C9EC71DDE912EC7572DC0B25BE911DD536CFE6C6EFE9B7ECAE861E5D3DD28E68FFC7BFAF7CB38810DD8DE12B23DFCE3A69337FC423BD82764263669295023F3BBE4E48DC7A3F17337C7BFAABA2F7B57459C3572881EA0BD39DA3C2CF160B6C032F81A6AB8FCD5B94A7F2014F0AE904B4346994CD4C54EE678E23AF95BEB21A3BA062E1A9DECC2A983475641A66550FB2892F732437302F19F1B80F034208F6E4250822868ECC32F43446028DBAF1A910B923ACD44CDBEF856098EC10171A53B89DEB2488F6D4CC4EBBD024668EC570C00E335CA9AC4C031A3BDE783B093DEADCB5D6DEC107CC35591AEC160549D7263D1D3B6CADEC6D6DD874CE9C73E61804173F07E4F20F5B7A5C3698799C30E9489D1805F3A5DD6C36C70D38A573CD425FB89A928061ACE86F065F04D2C14AF0B8C9D8CB4F7640DC5AFBA3EA426FDA628B72A4CC276BE9DF0844ADC526BE701BED18843F001A88570BAD4181BB66E37C35230E2DCE7DE953D1C4C8F7CB7C46E1C57FB7F32BE90F65ED059ABB9250B8D8046AB35CD9098A49F81B5957B830FA47184DC5D10B5176142C956098C7410F3EF6B0CC092CF5B0FBF73060FFC9FC612767B95D1FDF018216F8CBC1FDFCB5A97B21019C0694231C34783D519346BE304BF1217BC6BEB5B2126CA975725328ED5CD6542B8E41AEED52FC50D1F99C35C755E207BE22A7C5904A10204BF0B583F486CE7BFB5D6CEC33370CC02654A6837F4A88E6CBE64C1930DCA4905DAD35DDEE0F8D4BEBC17A04BCB086D3C44BCFB68394384AEDF39D27471C422371FDD80BC72FBAD6C392285EDDA04A0EF4CE9742C020DA2F528E183E634ABEAE41785EF3C69FC8527F7334B6C7278960364AADFA66D58D8F7AF4183ACF3323EBB3505BDB84FB4A76B2CE0B768CC8BBAAE17FC2B637DE77E107ED1C6314F94677A4462DC03B60DE122E5AB843893944E6902724A8C4CA0C00D88C3D08D6314B4B07DB39C4EA413BE9E0DA58270EF6A949AEE60804A78EDFB0D4FC989C02CD7E48D116DDA1E91E72FBCBC9E90172501871A7E444449EF65F639BFBA5D4F297FDBD2A6295B67499FD853B4E26A82B62975B07945CCF29BFED8BAD16E67D95B8A485B9756CABCC8C99A11A577C50FB6D39C49B53B309907213D9E60983EB820276B2416C8CF8CA98D9A9FDC6CF3F122A81901988DE195DDF69D9CC38B36BF74BE8D4DA4C1345A5FDBEECAC4DF62B2146AA5BBA74AF45D2B736BE08593466E85AAF96FAF3FE9E5E6FCEDF7E3C80D1D16BF761B73B5C5EEB5F01AEA31153A5618404AFDCF85C2FE38E370B844FF850E1EFBE759779211CA7C219E2425B2510C00A653D32A1238CF423067A309E5839200F6C5AF42BF7EAB25A685D9965037C61047155A7B33BCA049ABB15DD4E869B7C9E525B607861EFBF250C83F95ECF3593484FEF1D49FCA407088A3B1B9CB6EC4FBD9CF8F2C1A5C98E667A8027C38F51299B6442B6188963262B14BB71F6824189FE8E372C6BE319147B719FE723C6861DE89A95FB61BD23A61BA04A6751033C5372E840B29C6F04951D3FF7FC559A3387DE0D582FB059E43FC5C230B8352A563E05CAA7DDCE8E068E5910F490706E8E6F58C6AEC45C6BE781AEEE0FB9AD868036E5314C44D2BE4DF0D4E47278BA9FF6418317088AF48347602D58B8F4CE43324CC9A053FA1AFB622664E8DD5020E4A6333EC1418E57C26CC3C45EA61600DEEAC5A93854D39F60315E99357BA88F58BD6136E96DA043825C7C17BD246054DCB99438E24DBAEA048666F15158D71C1543C2A550B9D24C5A24A9B78BFDBCBD3495D25449DCD76E8BEC2A65513C8EA9E729D7E1AF990D323A6ECF88E206C94A685DD3A4A9BBA3DDF153B7D98912B130C2A1C1DAA0262ECD8E43B5B1AEC483BE373EDEE376A866D51A3A6662C0AB3A062CF645FEF874E97CCD2D6C5"""), +85c8fae58f6c8a7690e2098cdcb1e487e83a1ff669b31724113a0d9f796a68c860945d21c640c54b863814c3ef5a180dca61d3cd000d610ac6b0e25ca8b73b33df1d991902efee947777975b942d55d9af67fa96b7e45dab6fd52248361f3197b26baf40426b4e05c81d1138e78a7c907e39f7c05d0f3870b4a0cc9ab408d0052298105b8040e3c028142926488888a2a4101b2081d14266a1404c11032e5c1864a10030dc144c012509588604c9200403152284204e99a4119392111ca66cdac0100a086a0c086ce326261398489418889ca8715b262d4090881b2944e238065a9891c1300944262643a888a04826da3070ca40464a8851481866da28468a346d1bc48599a4700c305110b60088266560465120180e59927091a685c346528996309430320a38118a94714b340454108904326a09944ca2c640942492509270c0926090366a403832098648c032801908646394291416685c822da2366d0428841cb2501c99218114041b0981c2104a9c02040ba05122236e1410045a304419460a10184ecaa470e2180d81022a04186122a241891828ccc82c04212d110186d3186880b8651c335211c34499a66903a50c840062d3a23043440602c56108357110234121c561502828e4480221281084c84d93948002a32521254c22b730e19048914065c4440408118e0290892407211820119b828ce3205299b00524c78821a61150c20d80a650110012cc262aa4244642126543000d8242288c38016124601b072d0143088c2450a018241b212ddb4032cc94412416504b14404306061ac54544b600e1404218b141220405432844d8c641930652018881c2a81124b405d39821211450db065211c26cd41621631884c0b06c9c366da1240913134558a00818409241222452280120838d0b22449344210910904392715bb02922252a04c38c8a10904c047264484e01952122994c0a2166d8326a211522019540611866a4a80022b70dcab00d64208a1c28841420891c18124934320a330a0420804332921b476c61800da2a80d14c8711c4844c3966512900c08093243a08910318062144c8b948d931648439684c206288ab810da202d1b384e4b364e4b2461da886d6424691c348e8b98115218859b2669d04800a2449089240e9302121b4765a3c8841432040c8808649020023428a2c2049b461294166113106559422258144d500408221401e11822d4b210dc482c1a064ecc900400210ce40632113530040620d8d109619eb9c8ab718f85d404caf02e2be1703a4b04070f4d1261a153069f796c9295b1f6c405c47034bfa4fdbf2840a939322858cee0056ea8d7ccbe8c58dfce601cbd113bf5e8213fa32a73f07430012ac8ceff89c87907f6101e21c8dd4617a83509cbec27c7be57f9394e067489755087407fa69791c3c2aebeebebbbf43e8345b772b451d213135a0572316f52008fe4ef5812bc0c1d78e7660986b337eb896324598b19de9d6d3f7a2d670223fdd4ad7f41e46ccae6955132bd34723dc8fcc37ca79b9b8111f1461731214a158ac65a2a2ea9cd5a856b6713a1e07107f6b11d38320d4e51c1144e91cfbc89dbf4fc56023da26530e7614ab1c7c9eb5e2491c1f2a0abcff2e4d4fd3c1e39b061d390a60b6adb103d1ff198e70f945018cce7af3c25e58935b340a94423171cf610c57ffa775172c0fd3d4fe30c33c894e8b634f435d47300751def4d8f20aba4b2ecf649e52ca40562cb7807e5f43718567fdf09e92d444d0bef10961e4141faba4ae1359c49c0426c6f05b89c93270b1cd8dfe77fa865940d5f2e33ff2aaea1da3165e3cc38ab8c3149079ff747edad263a45f5a0dd55de409b611c2da6fe5b0ce3740064e5c9dc65ed9facb892e970af44646287812611539813aac695a1e0466a12c6c0912c492270e9f19728c9d8b68dca842d462ad41d914f8acb729e37e43693c39db2057c457b12ea78e6c4cabfd0cf14089523a60a5a223b228f8c64163b003e6af0026a7cc947856bbbf38ba43226e4857bab84d143477a40bbe194ac92ab0bf2282fdee0798a5827e2d82662e5744333ae9fd9063310a1c5f77438789e7cfc96c3ae961cda792d572d07adfa814ea068df14782f5dcaf3173a5246250d0ee9b4fcf3b145f2eb3e3a4371228af90f7737053496307704db71ee0eed602ca596a994a7de34ccaaf15d987afad5318476b826051c482965ced549f49ff07fad9001ff081fd49d903e18cffc6c824d60613bc4e8433f3eefb0ec666ce7d8a0f8decc80139c77b18e60c2d8bcbcb4060cad940665f9cebb9537ef55c18fdd474da07b3333e0cc6144f9069fe6496da1f9c60eda3ae7ffaa851d518634f8e80fe1fed6ab797289ef2d36910a17e3e825f7fd91629c411b7747d4e64b751540321c1b83e5146da1cb94bed6c063e26522695bd167d0fa5c455c1d3b7544b1b3ae6b5a080bd140c2709caf4394207ff5a08ea14739af0199328f5ce29fe31314eb169c6569d0197570ba2cc9eb6519d70d451efd270ea6caec116f43c5295d6504422b0efc8e16740626239fd20b815af715ebfc8e552737f17fade233f9674ab47d35615518b17d2b5f8677245295d6d79520ca1bb2a4ef675fae5cf719c99e86af39879c576dd3092f6a13471b248b10e3d19ca8257a4f2b73ae373f37fbd7eb79b97e41820dd8d048bf77d6487576aa0984c399b8eb247a0a416a50f615ad80fab612b532a2126d47043abd20198c49894b9a265e87ec93b519793fc363f2a1028123bd72a25953e2402b7bb6912945cf8b540821e173c2a606c448707f3b7a6a2ed692cf87588e26e08a6667cf281638a1d6e3858d96563b29058988ee461cf1f1895cca095f116b7cb35cc1b49ea3f94189efb5ed82e1d52574d269b4370cc235a3edfd4ce0d4e945b3cc5f316740954be77796d54a12b1be196706639de8851fe42643a22ed1b8c640dfe5fbcc15b402c7ce42d4038be2a0f8fe5a340a5492cd65ee3af3a03ed1e25452663d195ac43d696eddd08d47a64c63fb8572edce217f894917f30035c5c8c1065a2ca39a73f7c3172e7c0b4387cbae9123437b0c55ce5401b4a965362ddc86b4ff3e3b433ab15cb2edabe5aedfb8b9bff2e4658c875755fdd0d0a615499ff59adae936f0f04e086f9adc29e47b7e4fa8b94828df077a73d8a3651a23efd8def526e1a8e0a8a8c1ea4abc5983ec20ee7c530269fb1f23554d79092c24c4bfbaa7bd60e271b4fff69f48d3ddd4ddf94ce3808135034cbc78a2cd31488a4a5e25a81bd41edc5999dc1fc4767c9f82144934eb0233044407becd09e0aa0e0d5b531c1c010ca35b97da6cb9709b78cc0d96499cf229862840bb1d03f561addbb3f8f0f1e6d5c8de369dff715e57d21cd095a316a640b6b077c4aa6149167f11412a42cac3da1a25464752e24e0d1047c361b2ee9b6e6ccc58a683cb681eb116df43c9133f4ad39d4377b38b89b2a1abd6505044860e8ddea6332e79db6436fbbcd7f94ea293dec7f46e6c8096a127db1bc7f65ef2ceeb372fc66c7d8ccdc777d3d88cd1d65d5110a9b197d17ff1f2bc8515206346825795cc3386c9723be137b2d2a9479d"""), TestUtils.hexDecode(""" 0B0F604B53752973C4A72EF940C3FBA910AA9AF2916D673D69C4AE4DE92A237F271E84921C309B59B92E795BD26C5C015EC5176155DDAE8FA17D7BEFCEE3A23E0201669CC55A6F270CF0D03FFC09BBE4B47D318B6926808EBB49EC8B57A849896E76648D51117E8F518088D66B69D88E09D298186C10B5678EB8AE43E9C0A794C63CA9D597C4B74C959E9C1E8E0F46698CD64CFF3C0FC6174CFC51095E142DED9F16E5B2D3656555D2D42832280164E0C10C5817AE47ABACEE7C3BFD198A21BDD1C420F2EF0776E5EEFA46E8BCB49388FA6B937FD1FEB2BF09D5B9494A534F19BDE4E7BB8A5E4C558C2A166006B481A7C5865069A3DEA2B880AA503B5C020F045A4D9C3E5C590E4AD5375E74B732695A11164B5A57AA665922431498A9218CEB9ECD92700E92BD11E0A8140938C4FB9543FA5DE8EDADD1EDBDAAD11A6AEFF2EA409638B2C7AD546EFE390729982304F35D7F889C0CCC81D67F5A1D6201BC4BE8D1AD2D3CB85815CB9669B56F845148DA0DD2D6B5D7C4986DD3F10BDC78EAD8B4A88B7AE1FE11C634355F60A43A55C88B37954CDA71F4744C8E2B4D7F8D4A2BF60EF0C44CDC7F7059AC48A94B10279921709827A3E1E7A46DD857616E6B737CDFAB71CBD47639245E392DC116614CA3F099B8F2092AD667DAC43B8501DEA9876E5E0B98B41733DA63A2517A49C169A95E583F18F2E1DAEB4425E307509CC6B0B376827F0BAAFC2FB2ABD4E4151A8DBDCB8C22C78F5DFEF0DD1743B047E58537866795D67E35358020CF75F0D2B80287D62AECD6D34D18494D01B4412B1CFF279CA69C18A263E7B862F514A7A64BF192586ECD460D22DD2280373A66ED987635761C3CC34A5BF6A370F9F8B16F98808767A2D9A1517544D869E674980758B15BA7844027D3593432101FBC51FA4709F4D041BE9FF31DB9B7430F1D7F8E06C22C4BF3F8798D50C92641CDBF0B2C88E88666029FC985FD4E9FFDCD779C7F7600D02AE8D9E3CE6FF76F0B449C41BDB785BBAC9CF58ED7ED1525D7C7E885C0D46ADD0F7CC3B14394235B9176B69A222567E6533870EA540F4DED9A1D78F2CB89E6C1DEBE67249ED8F31C87499E24DAB0434FB9B40EA695499C76A1618A37B1AAA5309A914B6574209A61DE0633F086EE4F2455299C70B981532A23DC453939D223BA3A25122AD498795624C727E973C052E69AC40AD465DF55ADBB20FEEE76BF2906EFA7B0D9D5EAE860FE02500E2E0F4A21CABCF963D91262EAFEE814BDF9775874D656F8BDE11DA29327E3E7C7C95395D0DDF766CF34005CE86592F6787D1044E5CA1962C4DF2719308B2D6335FAC77DF46092CD3D5D228E381BD7E5FB4D2EC18B19E18E4748F662AB34C3F2C33877BF4A8D43A63F9B5DC75861AABB42D34EF37EF19CADBA110A3807D1699B247BEFE3D61AB84941ACB227C79CA05180FD3415D0E76EB31B4DD903D78553F2C22563F9B22BB876E81EDAECA4B8FB9415E2BD5AC32CC08775A20E8F90A1681C9957DFC330B6343E58F841906EE3562ADD6AA53FA1EC4AA2E894AFE769116E29AF49D0FBE2D8FEBA215E470ECEA81B258977A0FFCB17666953C29B2F70559DA00610398A08E0A17D69705707569D6484C4203C06B17439E9D4D9DB8456682A79659DAB332DDF45C67E527304013A422E46F2989BCF033DB143676A4EA720D0DD75584298CBAA765CBB0B09EF267D503F2782A427459FD2A83676DEA43C01D288429A82527A69B1EB19DD3BA1AB7428220BA74F79A81377F7ABBC027D96903AF6ADB4644E9F5CE676FC4D3ABD977D6438F4743476F77F3DA6E822AE61E0AD38549BD21E0FAC1C963F1D47F9E6BA6019591DE22BCEE5D5C9CBC4106A369C04BDF633F41EB1D6821B1F43194CC14B02B753584A659EA46C49B983F592C83BD959690845E872B471A38381CF3B2E8F4DC157D9A60FF56EC63B1C66D2227A069CEE7E48DB0E0D5991F96740D364DF89B08BA67098652958A14516534103ADD9E457E6AFC4DE1AF332EF3ECF6897B3DC8E5D6980FC5E5D829D4326F6023F48CFC9D0D787416EE61A0BA3CFF5E7C69BC83B18928AD277AABBDE271EABF8269701E526960460EEF521E83CF7A61A3CAABBEE1F1C99402EF55FD438753790CF56034AEA3292828AE858B2D3B9C8D77FF4545FAE7B4F2AE1EB17B8198F4846A8F4A105CE250F900969696E477B2C46AE786481BCDF85715BD270F9C29BECF4579F2DFFFF7750E375113E33ECABFC52E4DA5405849FE5D5F4A17C1F0984A1479D561943CD1120037EE821A2B57A12D7F1797E64E38A4B71E2FB10207ACECB96B3F3ADFF82EDCB633E388FCF11C8D105C1F6EDD41B553B4B559C3199745F3B0EB7326B867FD4CEDF4E9ABA1FD6A10E1494847FB5DC83C91F7A2DD351CD1AFDF95865701FDC658A41ACCA58E574B67929EEFEB371589374285148EB09157AA9A67F2FD54FCAFC1248F6D84951AB1A676637E9CB76C17C282DB53B1BEFAD8019F51B0400DC1CB012B97575ED81C129636C38998A2E6FC5AB7F0BF1FFDDB588BDE4590A7A0F879FFFC1183A3C6CFB341FB518D0786A6473FF9614877B1B722AF4B2E1E9B5E0DE7C3DB004EFA16F5CBF07870D7208A93A9FCE0EEB598CC54F04B1BAAA992C02BB2D27217AB20A3381EBEFA04CCB1F23E59E4B0DEC700E069DB7620E22235A4C5F54522D96ED4785ADBA7FF95F2A7DB212D3DD05E58C560E5ABD0EC238B7ED01E54ECACA7D32F7C2A3309A437E68C3AC7A9BC51025409A2A1ED05F8DB0EBB647FEFE6222D6F74DD8E4034580B675DEBA4BBFADEFFEECFF4771A0C1CB0ADCC6E9B050B85D230F6B288AC3FC24880CCBDF9C6A6976D46797B75B8532411FD89BE027CD8C81547B24B535825695A35BCDA4E2E0A3A6BCEDB73DD10DD847C4A0AAE059A07F56B0ADC0401026648BA469C534CDF6E2CAB8F581A7233D2F15BB35DC990EFBFE688F9B9AC5AA5C9B3E95DA7B0122947DA03AB9DB58090FF14B736B9CAC65F966206AE7C84B971D83944D8AB61589A28058E14193751B685058E632E32EF1E8C94BF005A3A2EC5EE2CE2FF6C05A67D87E56998E952E4557250E8AB5A979ECB28B0EE41DEE07F919E67670D9CC4077DB0D90ACCFE17CF6AE69DE0C9DBCD3D552A7FB37383574692A267B0A8BDCAF3532AB47887FCC94AEC3461A9257322095F1024C880273222295107864903F3DC8FB353FBE51C4D89F30FEAA5A570979A38B0B4AC9A4AB6B7169984C576BC4AD6DA1719CD0D5ABA03BCBF1336DE48CBBE167E4293DADDE3997061469F200A391646C8FE712EBE087B448F7A7DE437186D38A4CFBFC2919FC888487B15C60E93373D076DF6A60452E62E05256AA66BD1FB771CADB331661DB4BFA47581A4367069FA20E9C6229F79D6680125D0464F7CFDCA1F5C46688D5816CD90862FDABAE753E56BAA1369AC1AD3530630998CEB4545C4404C8B9A65D5A43443624D62DCEC989AA2CB8B85414E06AAE6BC4E219C5A3FDDF8FCC75381F6A0F73F54A7A2B5BA0F546235E71B233EC107900D8116CCD398FB14F32CEC310AC089D6BEC40255A6A877C30B05355544D115E8F85E428087A5F3670D596E31D25F676B3C6FF444AA0FFE5011AE62D6FFF86E615EBE80622BB646A318BC65950889616DEC254DB332649788C07E46CE590C2362EE66BB33BD43807A1336B94198BECE586CBBE3136B5CC809F24DB5BC3069E9C1FDFE53C6D1DE29DF48A9000A7E89D6862A773832DE2151423D9D11D722D923233137DB6F34F8DFA4EEC134BC9EF5A70424D895638D1B09D95D98CFA17308908D65AF00259DFB5ECFEAC55DD7FAAEEAFD4E94EFB36698D2315D795A93B8BA6A3CA93F6B79F2E599149BFBFC6F5C5742A83C886BDD4539BCC128F30B370FFABBE724AA3F3D571785AA6234FD2359FB3468A06A8E74918EE6E87CB29178900B49891F565A80BFF302BAFD0D5C2C123973BA7B9B425973CB3D7F2AFF3059D272A7CE611F5CDDB5AFF3E2B4024FDF0E01D7AD1C63FB47D9BA986C341030B3E5C6CD3CDC6A3DF9D6901E76D31C141C37619F5BB316209FAF8428AF19236DD426D70EC81E77309D5D9AC33CF3AACC0259A19F91E4579AE49EEBA41CF79B9499CD1211AF1E6DCDC70383A35E0ABF7B53A1203AADCD3AE638862D35EC4E441100E8CDEC7F0E6D22845F6CDCDA801111C4C7F261189C7D67B981101C40F21D33D05E336F1C7443560238C72B34E47758927E37F972247F4457EA60B2546F6B5B7A91B151E8B3800CC1748587E0D5421A43648BBC5D87C591B01C229C8104CA87C0B7F0770ECABD1E2A858147B62F607A86E1C71EF73C036B18C01CA5C1BA8242BC4BB7414FC90C0A8372F860F2EE51DCC1E457135776C377F940400AC5309112E6742617FC226EDDF51E95CAB40CAB58CAE1E662DD78C6E253B373BE970129193DAC7DAE372CBEA847248C2E69273B7CFEE70BEE59DECF64126D44BACAB5F2813CFEE1EF89AA3FD6D030319CDCE94FA86E4E64998266082F8BF74877038ED888C16907A8DF99BB53809E54520E4B5B6AD44849A33EC3FA44A7B179350DB07524823FE8384413F0A7E1936D8CAAAFE1052C462778B36AB8A9A14BCCC0319CF6EE2AFF01EF5077A10BC0FD0DF76D9B806481BAD1F49EA013942F38BFE52FB194EF8ACB283B1462BFFE4AC618D6FEE7E25130EC71D68C81A9532A16520075EBC1E9C3FCDF5FFCC150F3815E8647F34DAA814935D0E1AB68EC6A1B14FC7566415CC11E0C14A9693B8711DE2D3F78EBC468269BC851D2ACDFF5E8A6388B73E33F20C0C7621C6B644649AB088DC191418292A698EFA4871224232A7788EFA2D69F9F9FBE80FB8E6B0106405F6406D00A6D6185EB521372CEDF51C2E0876C7A86A90F1F5DCC0EB3187DF8BC62736663F713A1D403665BD5AEFD6BCD3413FC63CD68B3C5C7FDE3AC4164FC3737C2703AAC85E6ECEB29E34A6ED70D4178402814B5207ED2AE12E9DE009D0DE6A0BABCBC4ED41D5C28B1943C4B61D8B1DBF4395F5BACE1E47ECF0EB9E21F9E7F663EAC3788E935A1AF73B19714ED91BCCCDBEDAF1C74155CF235A58485BCDFEA58A929ED1E959DC99345C36109E42A14438466B1F9E728801BCADD16B2D8F762E4BB8B3F01E531339DE79634F43117DF5C585D7D2FB4A5D3E82BC25FD92BB1298AC79211B3866CA1019666AFCB10BBEE1AB63263F2823A86DD3EC57E8632C9F4975155A01F22859EBC400F5A3B8302ADAA5892A320487AD077B144392528F100F0A222DDCE5636AD5962AC6D62A2382167EA977743CAA6BA2F140655DFDEF168BD620C73A47A8831DFD66DC6F2A9F47E0724081681BE62FD15C74846980683B729AF1757203F457FF12925B6B7BC81775A9E5C53862B07D4B93CB2E9FA896AF58D258384115F1C63779E4189832C29C8B142DFF30C00DCAD2328A63C92CD1E42B2A8D2E18542BA3A81686452C83AFD5F6955A708CC1DAE500718C6DB89ADCBEBF119C4707B931E685BAC00AA60E3B5F9F42FDA6EA90F5C77295E84A3AB05D69212C5368E24F18F43B450181884D7AE8BBC61E1603FDEB13797F9620AD6C2B863C495821F7F726BD5801A3D5A36F4609B595B7653799B3794E4A60090D71F5DE1AA5F0CF562F7E722C55AFB676395ED988A491A34B462B2D18AF517569531308B8190F0148CFAD463802AC62C6CB289FC0C95C207AADF82AA7399E0476B774D9B876829ED91EA3E5C40B504370D266B7B3C72DDE2CCB7F3AB8E820ECB5715289451D352D83DB67EEA889EBF9E8B012C8265376C841BAF6EDA4067A400D4C6FB00539F3839A8D0B29906F9923B9244132282E38242257C339A0D0BA8F05F75D41ADA51E29E33BF65F78981F04F397BD5F9580376A8D1C552363D6BE90EC83C2AF748CBB7783D6B26098C641777A260F5F60A712C7A7D1CE681CA1FF969B8F25B90F9A2B03F71E06A848DF3C5C8571C5626D5A1F123DD14A9F90B3958A7EFB3FD522C7E83F897CBA80B95099F1705E1CB22C7E91DB644880F7DAB480B29FC0F8E1D0ADBAA123F1E1FE36835ABEC924531065354B77DC1082DD690B316A7BF104140F6316C46E81E777F56EECE625EA030C1FFBA3A4D40745E77129230A69D76C226A80A8CD31720B08D9207F22F8F3068C169B41E7136F94B73047377A8AC0987490E4DA2B7619A760E3B61369BF762FA9A3ADCB014CFD0644AB1FE6D8D3EFBFEC893E98289DA93AE19D8DE41AB33FD717200B6949AD21B3290C77D5B1FA44EEC7D0C6A9978D50B40DF77823FF2613BC80D0E11DC2B790B332D5267851B6315AC08D0A2D6FC0A8F93DCD20DA6054894F84C88CE254057CD2FE36693F868D812DD1D978897597840CB336223F8A8EEA9C15AC05D3E40333391680C4F4CD5C2F600CAA684BF09EFC8A9B71E6883E9353C22B379BB6ED8ED83A2468287121207D9ABF61D2DD5116D3B163F262BD3D57A23EF2E6154BF6EEC1DF88B961C4505F7CFD2E23E0E0D245A9418292A5AE6E60F3852D78D19E1EACBE9F42A522FA57554308A1D01E31DDCFB7C38534F7B48E0384AAB4B81A93681ECE4C55BEB089092E757A4633B2F30BA83E470B3ABDEDF9135DF22E2B29CCD0893C54C329DA1B16C2FE4221F1C7EBF6B3D6DE84EA1DA57392762FD9C64C0771966B0E1FA9A6E286C23128DF317F704237B97A339A623C985BFD6A0C60DE48EBDD73A0610A22B02D0978E626B50171FC8390B80F37E5E536CC184259D4ECFFA958DEE1A27CF3D2EFC9B218809909B19D573EF86087A1C9BE161C54DD1279E022F98030669FC93A7BF03FB101A3FB5321F654D2B40EF8298844806BB66EC32F7AB3BC7BED2AA7F22AF20759B12A0E3F82D3C3A141F393DE746D5A0D91F32D8249F0DB0FE37D27E49795C648EC6D96E352115FE4F10D1F56C39FF9140E3E87F13AF3C6480D6150E1B7B4AE614A577D6E81694C19E468761039E970335FDE9945F6119F6ADC184C9F2A434C681D593F34D258F2A8847E02DA5EA2605A007B25031DCCBA8A8C50C77411D197E742D4B3994471AE84E2B612B09B2BBAA38C5E71C22A8E3DD1F284A681DDD45E962F9D061846EDB9713D4F925A9DAC0E32D2A4496F68C68448EDFA87FDE3ECD47411AF5DA95D8C48D5CED988AFD72BCB7A81896EB1496F468D4664A58EC3874BC6FF6A85692790BB405592DFAF53CBAC93884A842EB2D3DE9619843919CD9D68AD89DC7A84BE54C406B8208428066011807D722C2B34D4A279EE43BDEB967360D9BAE50F654B2A06B576B803544DCDDAD670CF8D2D7723929842C6AFC4093BBFBB75D1F5E03682500AA0A34FC66CE4409D08C726552ED5ABB0C646E89B35A659C67F6F398D6BE39D9725BB0322D458DE2A62E46B62013F2BAE5E60C3D41975C6A4C6231F4B0EA2827329279459840911891B0111FB4B1FE99FBB482FED56C7BFBA15882CE5E2FA2C73E0B682EADEE6F68E4E1A9CD92FDC2CF30902453A16622AAB1273407B985FA4B7DB40D87812F2A10183464F8173D22D5603C44586B107B4B82E94DD80E87AD49E9C0FAB5C3330B74E89F742CA1A5940F0F329F56DFD40C6869D0BA8CA412AF9C5116ADBB3C22080F93142C7778D52C4D75F1EABE13FE50877C26D7DB429E991506ECF1DDF30A00F9E0B355306B889F41BBFD1B4D27B67952E4A0B53D1BF8B2E84497F00826D84A913F02649D5145383163F3C3F586EDAD06F518B64D9B300C4540A67593B9F3358FF2A22AC4BD7E7B9AEE507D184E039ECA3BBA0B5C584D3359D7121BCCE01691E11C120925A7D8B100751E8ADE99D3676C7355BA4BE451920BC7D2AD6E8EF0A9693F16FBB570122FE5F5FFBDFA490B3C84809ACD898FC0F807C77937C7CEB6F03308D3E9C657F80730EF3A1CEC6959850FAA6C158F23B23D28ED53BD77531F1012DC1753CE1AD6E0A629E14BCCE9D56B74E09AD6EEC9DC4A5C92049D48AE21222AF706B1C4DE65AA814AEF5B7E1EDF2D8A9C5B98853A17199DDC3233C5583B95756F5A9C175FF7D0891010F5D36A268ED5C9F58433A69185931E11BCBEEECAA240C2C5A4ADB4E770109F3F16CFAA37AF98E1228FFA7C584B13F850FED0187FB836E0A01B19CF700849EFF09BE1A57DE41CE1D52EA6F182E0DDDF741DBD2150113B10CC3D9E44917E0FD9717D6D361A88060E202039AAD8F31E4E6FBB4D7FD1BB5D6DC20C3D83F23D120EC98FF4912F3D9AB18D8EECBD7EFD1CF9B19081B38CD959660E8C63A539939D0CEDA897F5ECDFDEE16ECA492B216BEA35A167178F4A0FB76175D160FE2EF97BD6BA0E296922CE60D91FCBB3343ADF477F8A92AEB56A471B0711CAC45DA8EEBD21FE83FA68EB74C8502C81C65506C92C4A3F19ECDC2B7A5AB47704DDFB2E8D5AE620CA0D67197699677EDA3FC4FB821BFFB5F2DB03D4DDEC0BEB13EF84EC372A5C56C1E712C8D23D1A2DB1BA077645C85689CA2258E9B1B807DCC6394680B72938E1B61AC3E8A5B9E84BB4B58CE5C8C2246A604C05701C026185CFB872BA78CEE33EAFD0486A22C6D5CF9264EC134DD79548F3CF5FAA67D8B1FE74F6AF7B897AB0A0D8CABD5E1B2829CFE66D58CE00E68C6F23FC35397FBBF96D2E63825C96BC3CEB22FCF9CA46C93538F8DF566145D06207533627B665E39DD284F4275051229F3CCE9E9E62EDDFA55BB2AB1D1D8E8E6145B3E38F35F90B89C15FE799EC14F7E415FCE4EFA72615EAD26C10C1FFA4FDBA2EE04C4845489C21BE45C478D8B2116C84AAC21B48BD4181FC28C7C21AC9CF95D8B04C0D817C8ED8083D9CF8B81213AA2E3B8BBF4AD66A7AFDCDC4C420945F5B3E8C8AEC5C4F98005A0CE1B3283F5FC0FCF8567A150E12639CA85D298CE8E4F9E0C53817D3009284A5A0BD5D3A07234AF751AD059E301076946DECFED43DB1176A2BBA4B8A571299FDE4AA3574B6C189A721674E004F259B00B26EF5AA90794FD622040B80CA6C5E9FBD44B3DB21290353878F4D8D87496E374B05E6A5B25742A885569DBA2501367EF4C549BD5CE6169914A7F1D311D52CCFBE2091F0DB436506F210C137C2180B89626F52B4192C67ED06C1F9175E44B9468E6FC2208A98DE577962D9B4C31D5B0DCF4017DB1BBB2F80512C89B9AADE69DBD584452D25CAC97A4A7E6F48BCB909907B93F5B8108EDAD38CF7FB541328C5E8AB867DDCADD6A1B5083869E68EBC785C80ACD260C715624360F2F3D78FC1B2A464FE0525059A3D5E04BCCD72D23BC680CF7B25C5CD2AD6A0BB8366DB24B671D5BB3C12554D37C7A662AF9B9DB61DC6C7DE288DF1976DE08743426CDD30AFFDA05A8390A8F3A4A94D7CCD33BDB229E32850A77B2256CC595BE515F9E6854463966D4DB7A946276F594AD4BDF0B9C59D4D38E211A4465AEE023CE6C062FDF4123ACDED834F672C1A724BC17D44DE9632A588E7EAA77F3183E09D2ED55099BB1AC8198C96EC7B1635139980D5CA4B8B3102375A2E08BC3BC754D9FE659C3FA403218BC8C00FA87A0FA6F096E336865DDF02BB05049CDC9680E99C4F567ACD25AA7CC76C182A8DFC174BF6FAAF4D2553A4207922C1EA10CA8DA3E35DFBBFB5F6919FD4088A3A8E48358CEF25576A3A6447980F1C716EB58E755196A672C378F6615E54E9A16CEBA33CEA918768961C244A561164B61754F679856575DDCB32C70447BB738E84CA590CB523C6553F13EAC77461A58A7D4E1CC1E36E7BC5E85860B0E6B67C70D398AC0BABE1F42426D9E7F12B5E362BF3BDBAC42C572730C5F4EEA957FD3F17050625BA9D9938380249290AAF31BAC"""), TestUtils.hexDecode(""" -7C6B47263ADC85F69B12955F66743C08E52EA89E18EEF82D6ADFCF8CC1B1A13D386305F13956EF20C02C65C64BA0AE526CE9EAFFDCD44DBA07600C4563EDE57CC7BE708C057BB3716AE33D09FAEEBA0E9B71A8E24D03DB2ED26C85754A25856F054410E286BD70A176095540559340F1CCABD50EC5E89B36F97783D35EEF716A910E6ED934332083F0B49B9B7995489BAD905E86D54576447BA6254C382732320D1ADEC8B75C85EFD00217DBE6F386C0C02CE4822AD52B72AAD0FD00F74BDFE62F2182FA1AEAD069074255883B08434E20886923086D3083864DD22EA3469D56A8A7F4384DCBB04B819274399346544F08A14E5E5E7DE0788854702775DCD8C6A32CCC85C1CFD78D5D27BC651FEE0E3EF0082DAD5ED0399F33C179AC987A2B933268A07BECB62CFBF4425609161E1AF5E706CED78857F3D1561A4615A058635C6D4F73E60ADC5E5567528A63B60D26AD8C8607BF09F4C8C96A6183AFA07C63CC19C25EF43AF3A21FF390185B5EE30904988DDD853F7F3DD4E09F145385FE52358CE2C69E3B14F7A2872AB7455EDC06A5C448298813D7E0A2605EA911A03D6670D08631BA4E11EC4CF9959C38071A959DF07610C3DE964D82FA9C5C37821E4A3FF7E0EA642370DCC4EDA58F2CF264A8A87E21260B4C0B84C5D5CB5633AB0AF0A40F9E4BB3D5A05DCC5FEE2D6C1BE45EF44099F740D35E5A515C6CA1D578E1A0C57BCCCADCEF80FA42089C055F13FFA1CFA8163B0C338244EAD2F473831640ECBFC4F7E244BA5A00FB366C87646A8453F44BE68BF5EB96DEC1B1428AE0C224F82A0CE6FCBD5225F1C0EDB502344066B191B81069ECF87088A81F8CC6710976C65C9C12CD4FDC0964B77A7D79A055A907AAD424F6D0B951086C3583963D823A2F2244741277B15171AEA99A691AC76EAD489F25FA84A1EE6DBFEB3E1827E828B8A04A87B8174F5AD43D0B59D39E88321D301B6506724042FC1229F60BC0D3CB2E923AD72D4F6F1B416D6E83106B042055C9F92C79C97FEDF1DDEE892C080521FA69AB735F91F369595F5DB09F03CC917F4AC29EC03E893D3EF6D536923B9DDA78C04489F020C4EA18A144E2BBE1B5686A1D8C8864AFCDC681632BCA685F5F391F07192F51FC9A18F0A05ACB47F818A12F3BF654A892D396D3BC54BCB09D877FD0D98ABC76BBB3F184BCC3BB294D7BF6F548720C6B8BDDE604476A876E7789D6584B2BB9EFF13FE32113250B6B15EED1C6BD48F54D2353E15766CF4AD88921E66BB2B17AFD3D8C0CC18A2DA69443F3F4CA9109BDACAB0CDC704B835F6992B96D088BB3C7D86F072675EA1C259A4A11DB96B9557F60461F33C06264E3EF6A405BE4640710A36835AD44CDA5BE55F0720313A5BD39CAD155F33261076C1211930D23D2202E8DA8130505E1B18032A743F293111DB0ABEE58CBE2D5FF413CEBCFAA1BC10EEF60477B2ABE50D598247D00917F0FD2C9122DD7EED52403364B14640EBD6525DBEF7AF9EF7051D85C7F80BFF2CDBCB61E0708AF53B2FBA4B6D5D3751D07115E693D68F4C6A0E41270EFCE43D9A888E83A6006703BED0622F5CADB57F6DE5F3E5DB74AF934CDC70B31ECA0751540F255EE3D29DA18069330CCAC2E49BD2E85BAD2B43CD6F39F6601FCCB84A5F47B94BFCBED53536FC7DB0666E0D50A9A567D78C2F6FCA01D94923A6373743C00BE3FA1A1A62C24CEDB2440AD7645475DD6D7D7D616D30EE0E35E5912ED4055A895848094895329F07AE1E201568061E27ECCCBD78D564C38F1681E7AEBE51C02F563DCF77FDC4F32819FEDA21F0812067FAF1FDBA95ADAC178B92A4762551C669057A483453B49209A20A52DCB6F5266E1A8012580B65707BE63DD5619413B56644BA6B5036C68E2E66245BFF8D6A84D55B37A497EB16D01724BF3790931AC164DEA3CE1952912A938924F5D4DFCD5FE398E0727A79C0EA11DA7CF1DD406AF37D91638ED36D8C03404359BA719889C8DAD452A98AF1538CF1316CE669AB2468BA3CBDFB76470525214D177DD0BFFDDCAB4C82E2B1D1764CE850209E37EA76E8CAA553BFC42CE5D2DD483A34502E73B0F04F497B8AF26A188FB68902A8B2F5DD8387D71350C77E7FA50F541E45EF0F68D623298A88DCE27547F83150C2E679A5F8A3D28EF96C229253BBD5B60F2BD7845E354B3D7329179C1DF91626E7549FFECEE116AB6A7EFB4C8B49424B68BE363AAA794BCC68E751B3A3F203E5A9495B440649F9E3DE6A8AE4817CFB738875FFA75CEEB6ECFEC6EB555B65493234EFC90C5203C6312B7EC954B444D706F4A572342059B765DF362FD07C3B48150476D5DC08D3409A79BEE44634D0AA92C6B70EE7DAFCB38252D91EEC63164EF7555786437A7F8A282E56BCC13511D71142FFFE35E6F3219555766A0A08207B2DA4C894CF35206485C2B0EE6B28662A64A37C5C1A9D4C0B366CC6D99E92ADA28792CC10E5AF605FBFC638C0A657054A0E8760118307EDCC7384C9DF458C3C64150925B22EC3E1A1720BFC967ECB4EC5BFBC314852CC17A2269479F1AACD60DFCB1E415EB40136B7A6A027C782FE7D7F7C6D19507D8C2D0F6C250106DC0A72E4448D0585225F9E735A8F126FDEB81192DA13BD806DE1482AD570BF016DAE36928EE49D735F91F059EDD2750D785BB14A44019916BB8BBA2B4F818637BA312D54AC37257FC9E2853C086E95EEC0066782713C98C82F582C0431C531FEAB552E1C1AF0B82D6034F04C85171FBE7BC0818E8BE09C5033DB552FDDBBDF5DA0A048F920B7FA61B7D5B38D1C85F3CDF837D90F64D31FC5EE79209C45A4670849C70C82BA98A7EE2030DDFA50E6952BC73C71A8CC49BDFCB0F10C1304B291221D56895D47C9FFC80FA25DCD12B40C96EE3177E9B6B78A2D9F59D2C2481143D3C70605830E3634931A3027A8FA3FF22EAFDEBBEE16AEDE4D8712EACFB58EADE2E5DB35CF01BE532C2631A1EABF4B5F373E230BC8765737D1F1DD529F10D2FBA8882E62C74937DDF93CF6B769F84872F779D974AC8ED13A55A076790C032D8367AAC64C944426D661A87BB24A5E4861D0EE60D07A600D4D15404EE920573F2F5A3AF5D31209548624B52D1001D2477097A25A0D480C1A1A04E7E1FAF0754E4DF5EDBC0E5BFBF152F23B54B90C55A8900F4091BC9C7CEAA1C7200C017D5F99DFD5FF5D7DC33168C4BB834AF29F3F651C9657D3E1653A7DB02D7E61BC48A13EC743F3107240F53FEF424B864577BC4E6D78E8634AF636333063B366F0AF833949B0770B3E545C563E3B3354D87993940A47128185D74EBE823EE752375264143555E6D7F8897A7C2CFDAE2013641586A91AAB6BAC1D2F3FE292A4C51595B6A7985999CC0E0ECFE0B181E2E3046477D8B9AA5A6D6000000000000000000000000000000000000000000000000000E1B2A37""") +d90e5ad6ce804eb56c37cc30b96369f19a67ee324697634f7a40b3d150ba7891f9d8e5a7499781b5ef8f462ce1626eba1213bdf47ea40203aa7b9f6632a02c172826d96683de98ef1fbd163f817d6b4c71ed7fc9ec3a2db3d0bc692f94812d69ddfa81c15292b507d7aa3642b100472acdd9db20f19b60d98e10f1f47fd8f1498cc618a00b8c23ddf109957b78ebb9f5a7d6167fa907f52e312fb333b224c2e1b9b45ffe6027a90efea98d854ab6c6de67a5f24ee28d917caf0014774770989a4816f39fef30dc70b7e068bb306ab404611620b9dcfd40e1cc72400e398cfa342a616fbd5eb075d340d9f1d095b54d01d190b055f21d4de73ccebaec652f982535919e8ec7df3ce42f6e0807252f88d4fae025c68e5dfcd9ac0af5af610608011c630beab1b1bc760c550e79696333b34eab93fa7afc68e900686d1828bfe2bdb57332a9dcb84c66f12638a1ca4ab413efb847078b79610c51ae1cd81fac71319f8e43d356baba173c9775f9dd2569c3699a2cd2e9accc5ff725bc951b6c007e7d7b16b5f3efbde405d7d945dd1fb38724c52958427cc14d7a1f913c2c911fbc50e61a1aea400383561c78d32a38677ee62b201067c6744500f27135fd789e6adbafcd841a2796bedebe47059a8917f5eddc09eedf7aa6187f7f9e91e3893a3870b307a47da4366f767045390e1df69909d50e57ce6b2656a9f9eea5222cb8a05142c09ce230dc49edd7c4107241a4f317577c135a656071335408b809a18588f7dba155bff5acab476e99e62b0249e362d75ac201772552865f91eda373f722d19eb4e4f66c94627667af033c4d4f8e6eacdbb2a6abf47c931527c66da42f8ac3bc1a9c38e88a9d862beb1785ef9e1edcc3aac6477fcb78bea88b5a7796bc6e3e33ff1e0ca1fa73e66307e409365ccc8cf5a0cdba2bc96a7150d030b1349b15469ba21c7d53c641402776d61fca08d0a6268b43c063f51f110b8708251030cf393eed4898e2fc4f9654c05e700ca3e9d9b68274556f88c61c35860579ccbbfbf3dc367a88b076a4618772cac1c225069ed77168bc9e50737d2502d6b102a8904cb3118489e39c31507203175b35a295980cce3f9653330307583e3cbe2ec1d6e5578db4e5fed4bceb20922036891dd58b00e0e98a408f2212c5cebc7faaee235162bcfe6e482d4d1ca012078aa78bc9001a021c14e2ce86e484ad41ddae6c256f05cbbd64d99d20ca4fd0fa65d3565bd749689ded6c835d1370b047dbf1da76cb99f43ce660654725a40f7e8dc99716bd12bc3b3cc140eac2d230ee9177c8766e3cdd8d83948c98ac97b28826918a8835b5b563e887fa2ae18fd47d2c56e7a213d92533f05bb608baa68518ffcbb15e6847a776029809450ff9c0d4fa422fee078fefb04e860f5edc713412436e836f873bca3515842f70841f400db22e21c7a9c1ae25727a39e7e00e29abf256cfd8817115303a40c61577ce6e914b8c6e9481165f554be7a58c22c6a66266222ec80f1af4c6455301cbd80f5cb42d69f524d9a121699eca6d78bfc4db7bebdd8d03f83a638882aba3967f377be4f54295205b8f284a341796b4a00ce517e41ad2ac1d1dec2189a702b957a4d5d67fa1625341266585a220f0c276e339c29f58b13227021b6631cc37701899f0d7a761e13220ac0c39b5f98c688571915c38f8d0a23811d11cea0ff0e319e2bb06ff31990e00aa254e671f350bb9be4a5c78a992ea5de9276b0c542e2544d6a9a2e0339805ab40a9066352e2cf864a102406c4a11268b0ea22d029bdf694cd2ae75d9184920a9a707ab649a8f422ce4a85fd30aadcc07d3dde5b3b753668a303267aa1e43c81617b6aff5c7cdfcdb66eae646146903cf84a014c696473d0c52e19fc5da06bafc475ebbc367cd775676175b4268b42132f2959349a39e73ed553fbb50c8b213e4ae9d8682b837a3d8d938d4a4cfa72b564a39f5137afaaa442b562ff09bbb5c2faa2197f227979a9cf580dcbf01a07da6239f709fa91185e1a0d0847d77a50a4825fc0c2a6dc7140de2d4789b1fb4587c2e9b24f33d11728071548ea967622a1b97af44b51b2300c2c87d1f05b8d0e710a2ea5e123e479717cda447c0d4cc2ccfe753e6da45c38f568a8c2a82418420fa5de3fe08e196f2e2c6691b7774f4d4351c37e974721d4c505a6ba037969034627d05014a543e96956cc991e583abc9125aac8324f46e71345811f7ed8553bab0d166cd8bfe2fc21aa96c1ac168b40c61aaa7ff5461cd2c1339e8ac3c54cb1a8abf0ca4e7edd9e9842a01a91eeb6f3702be5e81936d53f11ae7d191cc6b8afbbf1f78dec898a0c30df889f43a8cfa8ce1d2a324c15b501a0ace8076b26334fcf03bb3db377d285a812f3ad76c0ecd7aa3b76f9072e40b272d514fad2d661d168b00c2b27ed394d4cffbbe38ffd1e7b84bfac69b4fca99b8f316471fd37678e4501f16ae1b2acb472c065aad5b482cc893fba258f29a90e1faa8f4c5235f136b25d1e451f20784e6b761dbe4fa68a41285baa9634f7d87807c407a9e7be6e483f3f224367caeba42f0df19b5dce47630396ec6ac6ff1b5c23e02f599cad3ef117ff74d7331facf763c39ea70c2071087774ef8a2ff268f27d06b96e50bd52eb5ab55a9f5530339abe6f07d5a27f64aa8015b5d2a768452f8ca82484113420464d06d7c61ec25c89a422b788f3bae8e79c0020fc93122f53356a9e678087f80b1938e42fbee9efab604f959b7f4d8c52d900d71b24c39a1cac0831c22907ab3348ad20bd6818023a72266983678edad084a13ee07196fddeb52c79bfb925e3ef4bae2ac564b04956c0097800546e965687584c2738a2009b0caa15183ba1b6966488fdcca6937bffdd9cd6f51424a83cb6324d2c845dbcc9237bde7126516ea59d36cf2b63ce239db57c01bce472886eff29ca612510ca318398aae4618b8d6fd9f6c6e8cceb4b3dbe5d059038b9a6b81e07f3599cb1febf3b0dae4eb9d5e3b6a3e11b24aef1377cd941f94a56f7c7f1fd85807d9d97ea0aace9d94516dd7ee271880f4a7bd18b4266c510e16f95aead24a9d3202ef331028b0f4233023aef2d18aefcb5dc66eea08013463c008b86faf617fcb6929a2bb78ee0459788792c9e3b5d3cf92371f4555c0955bc746264cf6f56edcd8bc8d044c170610fe76edf0e875f9d6d12eceeafd955e0130805963455a348ce41788cea9e2601decc02006907f5e092fa70d2f0f21945a5f24edc734da33efef7efeb22c8b142d86a47d9d5c13f93258eaa396e3ce55b8f6ce736a5010a347b7f9298babcc6d7e4fb03192d4e57daeaf7fd03041d262d47676d8b8c93b0b6b7bfe4e9f9fc0a161e3368a1c7cce7f200000000000000000000000000000000000000000000000000000000000d162933""") ), new SigGenTestCase( TestUtils.hexDecode(""" -0672A2BA2653D9EFAADFB90DFBAC95F77BE8540FFAA866671AF76F7CE585A21A5EE3BC98E969B2DF5F910F15A109DC09B91579F8761F4145771C80666362EAFE59CE336D877D8C724953C5738F65F3E1C551C1FFD9DC7E627DBE0BCA5174F200E8CDCBB1D8B0F84569DDB324562C66B5692C9069EFF52A7E4ACA9E293B26C1BAC3162A43808DDC4248A286401248649AB208E020462106815128900A984C94988C4CA82090926888B44D4924495A426E83B6050038500BA38D00B96902436E9BA484D1B88CD8A42D043208CB4089E12032613210D144491148258B08694BB00CDB280003C70C98883041A40CC20612982402DA06498C362C822209643089A34624129690818270A3108554206DC2B66001426A212222198204D1248660A065D0482214372662384C809808248040C1A44C1A4692133430C88808DAA650D812920230518B244CE302300A114CC4246A4CC44523B044D0B80C633800CB062EA4304E103051CA084D1BA349DB4828D1464D9BC484D0042CC9B60103A64443941080C66999100181142403050293264C9B028E53180D8A16411BC0290C47259C482553A405538401CC8868012882E1980C42440208A32008836D042292882800608408040289820812D0B609D992248C022C0C482A13920D1400244B380081188C0A9328220808E1460682386120196059441151A80D8C12321A07881144116338255C340050A064C0266DA232308CC684A224710CC72D5B323111246D944011C2B87108054C48184E49A6910B451014816CA0480A222588E2203050A80551366E234820242932D2C40C9008081A9750221345A1304D14A088CB06111104095B928891A001C48848E4264C0BA2499B022523160100924DA006908AA481A312481C9281121842040152892846D0840513374419B9911B010D19912C42386559466D802428E3068A24952411C38D0A1491498400C082655C448C23476889308253300224186E08414202248210846594288C1BC1210A246693A8011C041204308C9C486A0C47460AB50D8B288C58162100354E4C024E14B05112C80D80C40CD1484A1A36720B372419440962048D48424E91028103B405134082184520DB4288E338019B460299B860D8106D13240AD0B08818996503022A00372012079082B04559A485D0266290822D0B324E218291212006C90270803681544092D034640903011A90510CA2085120229BA009D8120452028820315184804C5492000403810A4809FB030EB7ADE0094AF6D6A78EF4A30D8A22BD35A79B413822D86A8ABF9BBC04D838EC1F2150FD86A245498E76DF32DE661DE605C76757DA5FFDA3082DA464400EFB1393D92A3A53270E0F144D255B5825B05BC72C287634A16EDAB6AB4422CE3AB84E45DB798151B1697FBB7CBBF0FA370D1F57D887E5026226CDCFABB2D502F7A82E983B03BA41D643DA93BFA387620265DFA80DF45E82C74C14963392199609CC59065A7D4C26646A87C04C31B34B2A70E029C24EF993B30EB53EDECBB4FBD6FAD614C581B3C04A15AC777006B0293183CA9DCD587960E736F780B1BE219928BEAB8EF5DE4B8A03449F33A65B2B08DB13F4B7DA0B756153A322282AD8F8D8F64EBCC6D322D519D6CF1A8F684CE469B9B9269759944CD1A863E236C856441F6C2198B73999AF6EF8140C9D23095847D3DB2518113BA8C96D6871C4BEA7067C0BF6947FE69B3FE12081BF58DE113C2B487759511CCE1FA48D814FAB7F0AB1B1323827A8DA71454578F1046CFD395E3683C332DAA81867B112E8865B6E2405D5AD2E57E8EDD695C3DEC48A52BB39E590ECC8F32B5F80382F1D444CBAC5FC7378C4D8EDB275CAE3DEB4C298EF20E6E4E25DFD2996769361ECB2C86AC0D28287685219F60213722CD172A2A2ADE055B515955E2D982FFBC13C2EB17CBC96371EB69C35BFBDA0DED49E6DD63021F38BA0C7E30A655401B6B8A9796A675FBD5044E64F6289C69248AFBFA217B68A5499E605E1487A07CCD60EC743F053731CAB8A2EA92C4BCEB56560FE3F55B21FDD604E6AED8F2511F0562B6F1AEB40B70C116BCD8DB842E26EA0B325246F4B6580559F26D6817D6BB4FBAFE4B144B26DFBC52D45C3DE758999834A642E871AF54DA2C86D7D4E3DC6BA54F5ACCC8B6D74EF7AE1BBD0C82D76A8E837F47BD53B8DA621FFD51A05F17FA88CC3D7143DD4B36F0674548FB886ED228BCC53B33998C3094258ADC3E05E24C5A8BEEBC588ECF45178D246D20757C287FF45149371931C75A7C59955F5BD1834B6738DA57D4FD28CBB11ADBCC6A11692021D5AEC5D36D6A992E7321C9FEBEB0A8544ABD8DB5CDBFB40889219F893FB4F543C22CA29ACA96B8E4C48E3FDDD763D5AF7C4A69AE763926F6F687130CCF2A2EE5EA746C3F1AC9772306A01E378845F568D3D885D4C267708B2C352C45905C7523A3C390B89F3E034D4EDAD9327785975D7286B755CCC9D9D4874B5A9DBDF90544421D7C6B2CD2876C4301FA891A2836E1C078EB7E4C31837DE4B8A38D270024F121DA31F48021CA533ED61FAB4B5C08CF3CE5DD5300722CBC6D1A11D068C604967D525394E88A0920EBC56AEF47FF4807DC5245345CC7CC13F5BD929EDDC183D10F83E5AF32DB1F7D87B2B27110B4A6D0B3AB5252079D4FA1E5FB3D667189ACC70193C1CFD4D7E3FA9BC93CBB834DD3C8854EEEF5FB471D73B3A35689C8E04A1367FD191DCEA35A661D0AF567DDDEECFA8AC62C34DDEF14BF848B35C9D97BE3978B055CF895477902B40CC35F3A7DEE7900F5717073486E8C995192619F7BAEE5EABCA9B314B4D0F3F602CDEDC8084CE573A6C7BB59E4E0048EE367D7FC40419199E0B104DEB93B9E36BB510B8E40A00AB9AECE27D5FEBCAC6134A303CA9B07F332DB85A8A03A56995876A74699A8170EB695F77395341355AA8AECFD30443824F7BA6A07034AC1638F4C6B602C48A0F11EFCF4CF765F886DDF128D16518F2E7EF3B4E6BF799D0FA82C152832FEFE7BDA434EBBD1C81128ADD704A749D46B8D5A4BECCEB7AD6E4959F8F4F191002A43FA609299667292332BED76228613EB5AA536F15BF7C2DBD73A002B133E7E780DE1F0A3F49FFA1E32DEC1DC496A0080CE85130FF9622882A61CB392D3233AB3AE81458517ED1A65AE45C6577308FC98B31D74B008056B666E70423816151EF5881812AADAF241B299222AB9F6F0C0178196846958E2C1B4536E2110029F1E2D7B8796B049EF697EBECD35E467704AE9248836634194BCB51E4F8474FA7699A1125CCE9FB62F16BF5CE11E422DDE6323CA490086F2F9D41B7659943D455C90BC978726707CBAF0224613828281276672CBA3FD13CF37609CCB8027FB026A8211DF8E13252AFB9DF7F13423BD9477A0518D581326181498DFE98D30248DA71F1DEC92E7453DAB2CAA2DEC15E1F73A249D9A8DB45D503780C94DF2985E339612AE8D9AF07E96E3B54F233636E180867619700CEB0DA7C2362496013D14F904C30594D6DCC3FC5424AAB9A4605B34808E22C697DE85453D4E9E55E0B7C04E5CBBD8F3530676B09ED3A0D5870042940C900514D9361CB3E3C5FDD687FA90F51C0A21A0E27CB420CA68356807DD24F"""), +c298f170b4286195747d986e0de1fbb602feb53b5f242a12bfa2b7602b22358a8a23b61c155fe3630218b5ef74b2273071172cee1ff382fb09b779728674dba788475bd8daffacda50631973d3a038d986fa56e33293538d828f48d4292fae5487dff146e3e3ff99d2ceefe847f17e0274f2e9edc0c3b7a6b184d2c7d771510259180c02294d08c021e1128c01b9004906315b180d1929411895259b3285082964e310414c920c4b9611c380101aa86d1cb12c611286a498699a385019018de13882d0b8401c340a824689a21640612886022028d3166d1c328a18b06de0383164b46588487243069202900858226e181428da4640e2c4694118859a044e0301041bb4411235011195415a962499380e04c72110458523824101a929519029082064932669a2102160360e0c860112312c44a28c0b2272e3280ac3962cd1844514482a4cc26d04a1110c834c8a026d43b83113890113c60d49461014408a129725d8369020b325138728a4a44904814d1a324edab810248590c8406423c22849c265d1068de3865104a2805198298a126964084604b07043346519c1916204080a27608a144e1b2270120731c4a808a0968ce3884d2210682231481ac49180a80c582031c2120adbb4441b82641a94080aa5659b46711b15445bb81113a360203660443608a02432d922318c22054138605312220aa700ca441290946d5c405223264588b80864c4251144240b051244200a09c4101b938993261118c08d9008241b364660022c18060e5018864b40051888418c806800152610c30c91162dd1360e0b491014c18da44212a4844d22193164a04503b70c212690032661922862201106434471da324890389258b260d32028d096240c074610a36413c24494888c0b328a4b320a9ca691dc284240220d23b671e3121200a16004938c5c3288c1469121870511912d8a285114354012b86c4200460a350489a49164048d001405cc266143a82d2048061a184d0c056ac2a06d9914710c26251b33218b144ec932685a9221134541042770c2227213b909db0001010485008000c33640d2882924355122982da1322e1a280021246cd8a451903464d8144263260d9a080ad220111031258914890a1951cc043209028d11392151b428dc3628a406119ba6009194110c912913206e5030850b10121428419a04450b1871082581c22601183090dcc661d04089e2400a23044190a64401116093166090360e14859108368403414d7fe04cc3486ee59a1d7e5ceeac111381d6bf881ab59d8eba528410c1f10133a1aac55b4e0c69407bca0aa1efa29ed38ae018ac2f892be5d6f4d6099421cbe1328b07913fb0eff2be86b6785500416f14777de98d5129d4bbdc1e7d0c2dd161c3b53568ec0710fb80ff1407927b82261dbc6a301a5ab780b88d080d7e8a75e5253fa666e6499718ed9135d2658235755a107f617dbadd6ebeb40906bf2c29dfedf24ca3667029f642770fe012ace1dd503c33e0e033fb90e0e8598870a92cf3b467d667f6747570da2c86a328b1b4c769f4bd99a90a46000018a6a8126b61b51f9b77d66d91704c5431a2c5e4a7b680f053e7e1f5505d74af6a79ec08e7de4d45fed1888c790e2473e716c7b1cbd1fe9944fb56fa502b5685e75bf23ae5ffcc4d5a525b91575fe8baa856a445d7005a2cc81d0442e4edc3fc19e4f5bebabe21a6c1f2520c38d1827874261b5e802514b5df1816510f894eb6d5c493c82ee8f3d2e7b159da2022586525548037e078ee6a1ab31803b0595f0ebf07870051aeb5582702d9755b98cd30ad128e455c15a05f48ef20448f395af79a5127c4a9c4b04c29764ebaa3116b9fd10bb6138750eaf6a300d7f3294522fc92e2e95644d2fc35222a08a51e49a53ca180cdfceeebd5f6cf0625862770b338246533d35d31c78395206145f88cf17e80c13ae5b9f3aacac15d526e9561e5608dedf8d2163b9b283bad1a58d08b14a201bb0fd91fb659296bf847ab47a85cc58f5a8e9c9a5c132cabe71fe3bfbd899a60fb98b84d962607689c1295470c23df93f60ba2162dee0893230ca5bcb4dfb2ee08ababf98992e27ff92d5569cdbd77dbaa44dd2fd21e8b398525a5ea3f2632a581e7d94675a2b51148afc18413c9e39b489a6155f089cd1ea205e9b650be0f1d3befd1d8189fe94793965cbc0b118913a1b5e4de66d969317c2fe4f4c289070c663db3684b54d8b5c29d84cf1ca9b77794ed6171c945e42e808ec0709d2d284e5e022495c7bb67f215c023f97a0f248ddb6061c7f68cb0c6f688f785cfd352021ad700d410968f389a17261bd1cedf8be5b623fab823d5a27e67e68894d533742375ecd6d41f124a39fe2e3e548f3c041b61179ae7961c248a05e7ae1b3023890203c95b73e70c65413a8f2d97272dddee2445220cb6f1f69e5d47f9f8e6f2feb116d688f7ffb9afae3a6a7b7335fdcdf6c1b2f28ce98e1ee76ed2b0303f242cdbca4091abaa25275e98faca3b16d3293f165d5e653faf20d6afa94ca6f899008e31aeac9ded97911c1fbbc3de8ac9e16b20bc91a13706b427aab96699f46e5815add64be24cb3484e20fcc9b113c8da4be3b0f39dd183a483f8f6f233a3b7d41008ea66c1b0fdd111847e0abdb4dc1a73c22500b39035d78048b2a7b1b537f4009656cf7a2744737bc7066f99d7b23d0d109a2e9e679742edd3d89ef423c5c57bd2947fef985898dc986cbe3ce2e9d57dca7d4fd7d5095728822d687f22a3d7d291856451a5aaff706b4a7f68f36a753da02562133be2e3a30e0f5ea8fe18b2602ce263c6065aaf15719d8d45166216d37bbb46915da50aab9a0f7900784e7547a0c90658d5af3d8f4c88e5790eabfe578976c8157fa0fb6db133394c7f16e79b6854900fdd9b6ad0b35a877e336abb0c484c8c258d165c83fb72595978f7b2c01b05a34826202cb73d88f5e8cc879e9994be5b3eb47b336287d7c3c036e5666afa557c834ef222a0e8768827c6d56d315a61630106a4ffa250e3bfe1de6a6cfc311d3f3e48165d8fea2afcb14247c2da102e88d726f4865bd848d87c01dd6fed84e0623d564bfbe8bb90963d6bdacf36df337f00afa83b1eeb5309cd6335e4156d307a28ae3dc791210b482e9a0504895dcede6dc951c3c7ec8098de79a51741eadef5fc2800ee410bcdc2999ef9e38e33dc3bf0107af5d32236f26c31d1ddf62b6ab6628a5bc4136d9bcf62ab95ddacabd6dbd3afddf7556e83931035a6e737915f1f8dcc217e247402745af979538c28f91de1375056f0e369c648482877518ccc1c976e21abb3c8ff30853d5967655a0f7d4ab3fa1de5736d80024b34f940aa744bb427a2350e72e2abad49cb6a91a066efabd87d286da00d9c731d8348d4b094e089da1938c74185df1390646ce73c0687e63a417c0681cc4438ea446fe36496fdf5a808a8354237f4838b51182dd9f062ab6143985524f01ed273db2dfde919865c1a5d82c67c1feee76609fa9634e0056b7803dad0015a27445028e5e87e439f820042888b489b0de499cc3ba6d5aba0260a0cf24f718b013b72918909283fdd28025c011d0abe811e6f484d58b27dccf5b5fe"""), TestUtils.hexDecode(""" 0C39B65F4C2094AC626652CD33CFE44EDB2667CF722443514CAB443DC398A8EA009277BE397E1C1E7ADCD1B24376AF0F19EA50E56C90D683F8EFDE693F0F8834199544E2DEFE392B0BD46048A83C412A14834C4BCDC180457456BC72AA28F2DB247AEE84A1C49266361DA7EDD54BD9B562889131EAADAE071AE5A671646F49B2C1359382F1A3B2A6B437F87CC99A2A1BC821E1F3DBB311B8FCDF28546A479E2F9970870066A2D6447B6CE4FB65ABE7423910B9039EE3234836F924C8E82E1299335E27B0DD642B812480D6FEFC47B121A710827DE1D18DC12064649224FBC4526AE14317CC8E53BC8E9BD42BA444AD9B8B48C3AC807D7A7675F43E3021BA1DF9AC7A42A9E23D696BBD03FB5C4702B55F95854C41F470CDAD8A255436F910C089F71C2E59A44221D78AB81D4E2B059CC92A3841E1431415DAD4E6EB0315F423DA512661E4CCE098D6678F560A4BA19475296A2A1DEB12AF5900FA3A3C188867E0C268EFBF7AC53455552DF4F36E16D50E23048C7DD4E64341E6DCAA0036EE045B82C42121B0B779B5E7FF032F549536ABFB702B1CE4EAA5E389A077F47B1B55595D4888A4C1D17F4E21706779C9CDE25DD1261C8B4761A40B69E2F22F069A264E79CDFD36F307D117FC737D88F50EC67CD07D8FA269CF265A7E7CAC93E97BC29EF95C88904AB2DB61C8865A6EBB23871576DBABC83920AA015D47E8CE699A9E57E139AB7D233C577B46C9C314D084A1674A152D87D2A3D8A5D9ABCDA22E212B8C9A2BF25D8AD22AA3627E6C12C684AD2BE917F094263982D396364F4DE0BAFAB2DB89997DAF8B7E3AA953C055776FDC29F8AE5C28D4071534A9A2E9090CD3F723D3E381A2ADA6D9463FC49B3C6D2B76803F5C21D8DDCE965D2C472389D2BEFF448F2D81EDEF1C851A863AF66B64417BCC2CBBC70C18875055D171BE32C06081362FFF7DE8F8A23B076839602E2368CEEB79E4EA53F42F440D167A902A23ED53E6691AD3332DF5B0160EBC3B5C9567CF619BE2201447EA500332ABDEA9B849C3A395F596F2C96ACD9AF8313E453277B9F4234874E791E9DCFF0C9D9DFA8FA9474C026DD34E5CF3AA10CAB1FD23EA5DA0D0A66E520096C6116944F2E5747A974BF55428A3D2475F6276490AADA25220F2F2111892DB9E9C75A5401BADBF69F31B77535044DC50B1E93849F19C0B6C5184F1B14F68960F9F469805F3843198AC68E51619F3D712A34279AEA27BE4357A99C44C456BD2D9319147285680922B98DBC4D6D2860515D1371D2141C7A1E76EEF8586AFC973713EB89C1F09A84AC064BB7644625224FF1F7316B9DD1091CEB151D1A040F7E60F202728F7862589E7F1FA32D39653383F90C67D96D9949967AF234592903CBB968E0D979B92B5C69D09EF4E767741F1F6E361DCFC8D751CB8C3BAAC4CC393D63F71AA1488491CA06CC20B0BF54C5C225B6F0825677C2C40A395E1B7322288A815E59AD2999D61FE09C95828CE18B2997AEDCED56CA8BCDA4343B1E948256AC5EBDA23A8E6D7102A4474CE23567084547F2ADD9DE77483398D81A9A9C7A573D7EDAF99536D31C3588BB649EFE1495CEDED788EBBFD5775842D91DAAA2F9BE08D63B06DB35E72CD0EE5DBF45DF9B0CA682BD944A733D6875A62F8C53A3FA9337F13429FACB288C73220C29285B2D87DF2CB1A54631AF3D0035C1F3B26A5EDD07760A63576A395827F3D5F9B03D9E47A9E1E6A271021942648B8424234080492BBC56C692C769B5DF32A75F7403C88469E54432A37A895E3CAD3AB110089ACF534A0D78C2083CFE149A2D0A5055EF9F4C943CBE1FD393292518CECFC57E4FFC4D07A563A30528A6A3540636A3BE770B7CF03F5004D7C6F8ADA08DEAAED0422AC0C0C8D7515C9F8BF44195D6DC30D9B3036DA007A910BD05DF06B032812CE8393AE2777D717A691D07E860C1EDA60F6DE31F0787097D0D483E3A51CA7997646503738CDBAEBCC21AE4B984B668FB4020C139D9F581EBACB7BE263A33955DD68C9ED9BD2DD6C0A7BD049972B624CB7E787DE7184023F33EC0A1539C4679D6B4677FB971D763BE17D989FDF8C0AC4E0B5A6CB40A49B5464610A110EBEE9A21BB0D6A2F043015EB2C8820DD966A13EFD18D32367834D41E8673E997B2803638A710580CA08DDB4D90E4E8EE584BCA2FB853A122274142130A1ABCDF7DA6C0056689195099CC3382AF6987BA47EE294353674E7295ACC1C070F1D8E4107AA7189F20CC818F1D86F6D646CEE911B304E2FECD5A14CF5F36331AA86E10C319C96E52996D4CC12810AD7C1DD1DBDFDC78DF029BFDE9E8F9B1FC7D9DA99FBB0304A8129EC58A82177EECB7330E715BB3C0B4482923C7B1EC0D1823FF643014C7D08A8F2D9F9090B0F83663AFC5E601E5FBE1DDBE678B9D93C5A23F564B8A4DD29C8D19106747959E72AFA4B16B879E3C6E7F79A212A144F9AAF665253F1360ACF7DF37642270656583E06FAC85389A3AD76E69BC2735B1C3E13B80CCBD298EE25C29F9F5C275AAD83BA0E7C47526253BB3125EBDF5CCD6E1C4F9D9CD4891167BB4E4D2AA644D5D362C6F790E2776BDBAF8D96DC3A543C72ED46E431FABD737B4BF0F4B32E12E0520E60401CCEBBB40180985948045C58B0017C3D8797E433A2E2C64B9679EC7409D59B3992053EEF2ACD7B152E5F564196876EA0A31CB6ED47F2455BBEE6827D96C6B99E46F3DF1FA21F593E842B26E83D843118F6833BC273E12C7224E00E840B0041544893C6C8A06523DEDE2ACE7365693BCC6A8D7DD81B01310CBB8084C5FD3868539F8B5179519CA6745B56C4A5EEE8F2A8A60CBC7453E1E0990D176446D97F34A2D0BD5C5712E2D82601D0B9FC9A3F2420C65E4532DB3810FBE3635B2AC3A84415535FE41208B907EB3E97AD63DDC4FD694127EF1E948801B5CF651119CE17BEAE3396C098A86548B67DDABADCEEDF60F57D2941815778AC14F78C78516F84C5F9749B433DB97A9283A94697419CF94248B6819D9310324977D47A133AE9F1FC141B56D6302817761BBD52B4A1EF808E0AC761426C99E0504ACB6B552F9550D55DE787C12A0409A9F9EE3674617D15E229AAA98BBF4FE49CDC81DA3AD110645132B332B6D2AA38B35320925135BDD225053D6594E78389909E596C63B85DCA8B3F6C3233A31A1F8F3E900E49DF83F649E592979C9CA4BE65E7D6D1F23A7744626972D52B07B7B89CD90238A5E871666F4CA6DAFCBF34FE15983AEA5BB7F9917736F7BA46F342F0C08F56D19AB9569FD23288EBCBEE7B5924B8C86EF77748F3AA9CF2FB884398F83772C9771958B6DD063162A3AAA42E6A3280FEDEEB7A628A07702950975CD135D6338FF959ADDA2296B3E85A024F63D4ED8A5859786E2BC76C2325F37B4D91EE8B64F30E781BF48ADA774C1641CFAD2D63A59E294B5D99C94108154E38B499E3CA2A29AF7CC77A8BB3A3B712376CD081715EA715305C18B51470D5F3A6A82E9189848311511E8B0ABACF856312AE3916FBBCF6664523684D3C7ACE08D2345A3907C9C07183CB3E68C5EC3899A95430E278A72701E2355A4AF606DD8F8750F7F3682FB84290B2BE23BED99CA06D5E54190A5558C927C369C00C512342EFFC41618CA6F8FE6E3A38D1714FC44BF5679C1A49CD8BC8B28499602E277DC8832F738225920709799DE6961E0B4EC12397E7891AA772627F66F494AF719C55D056DCBF10E8E3DDF1B6C1BB2F0B2FA61949D1CA7D4E1F60EF836B086FF8C03A5916A14EB2670AF56264D7390761E6EB6F638D6FACF56B72A48F271ADE4541C8EFC91D15F69E0AA6B97EC0E9C0C3EF169E4A4DB1C1AF04762B98ECBD0DC374224D98FDF7788435BC154E1FB06C970A914C34DE52678F61ECC1969A2C5B1FF4D82E2C80CB543B4B7C9DB541229CC50CC6C448DC029CA24ECE635233C401D3715671BC75785DCFD929377AF5B65EC43EF45A9B00CC766695A4A5DE9A2E6582F7936B9FE7DBBA6762C41453683146F4ACFD809847F866DDF559972FE0C093EE7C9FAB3CAB0BC2BF8DA19466A96BBF2DD4859E2D1CE122A3CF16AAAA9A4708F72BBEBE285E1B794B2B9C7A699B36F39F033277E8B7BEAC3BC70A572556EE5C070A309D9D0BC35F4B6E55ECC91CE9AD273B0098F64E1327C85CCAEBBE67E8A118669653495D2FA09C29C6FCDF870905B2C8BE0DF806C29D5E7AFACDAC5F89116A3474D2229C76E649F99EB9EC71A2C229764A477853D68C39B8F0BF4378993AE2B26E814A337CFC103760CE92FB564E3A3E4546996CC4D8B6BE069E99861DA9C731B543BFDC006FBDE3B33D2C8C4A3F5789466122616C98F52E5E4BA239E0C3758C5BDD3BAED8809F67A70504BA061409A9D87A499236230EF0F1985DA0D765E9B7F733A154E8300490F458847A89E7C6BBEB7A9ECA7B6CBFFC3124DEDC1093C02C808DA1CDCFF5237745C5FFF51F3F15CF746D3397916A45990070490CA74A55F34EA4BA9EB73A281F123035C005BF6C7B30852665860ED13A2B5808F81435A77A8504B58CBA45559BD3BAA663A571F108685E414FC4DBF8033075E30CD6FCD9B893DA32F7C8D5D971D5EB417F1201B00F65DEF4EEED3B55B7FC7E6194B72A861439B865558157E65D4C2F8A1A93F48192099B375D111370F830B34EAF3225A16006D4749494B9AB9D3B05015E34866A4A2D94B9588A8DE8AD4CF90F2CF422634E8DBFA0FE3FAF27C3F3C2EAF9C1BDF23FDF43D196732E1FA6D2B343BB7D9F5F26FFC31B26C64A8EFE2B2D86AA34BB618FB58CCB54486211A8E66648CEAE52F07A6C1EB5234DA7CCAA971AF984D6050D1A81F10E6D19CC44B5E668CE92F4251924B25DAF41D5E381C3FAE4208D18F710B5F93CF3C776A3D81C608B06CE6BC68FB8A8117CE7BA065675B88510F2E8A440EC363A5983DDC1352E446A482C593A490AD6093258E447EF52BFD189ACD11C87A8B75F08B5D166C1DA69602EAA5916474131E20F704DF84C3FEF2AE99F9B9E8F7315A143A07C7AEDE5797F503086DF7DA971244A61909C4AFB00842FBF4C3A59B991B58AD6C0B8667C449F0D97F34CC41FE935D9F55821299F780359E2F631858617437D4AFE67DE4A1AA382B93CC3FF596726F0D1C071FD0E00883E9E03811FC659495AF2A62B45DA079A66552F2928B6A25C6416F8DECF723623764441E5E581F9B2E36479A1B6CB3DE9B090E3343277CD7F84E80219793CAED4945DF782C4B72B498A62A1F5362745662F711A7E47CB816EC7069D10CA8314845AB0C9FC326C5BCA0E2AFFB4E6948522F8CD9C8DC008855E592AEF1F8239748916878ABC493E33CCFFDB86CC2ADB99B6251F493F0D2A0BE56D133B66395AA695F6298F7F4BAB41420CA9B8CCEDF2719590287928CF6BB3A506D6678B814076B7A774BE9B7029DF9F4719AAC1D012BBD49EBCA6AF124D0AB5C5FFA92B4A895CB76B88DEA9C7105136D78B76D92079A5B001B214DDF7E140861D86ACC260B72ABEF2CB3A75C2BC87B39A9D9052D4283B71C10AE275474E82A5FEA1654EC3ECD468DE4A015CEB67BAE3275C2C79863E2883D46FAE351F0908F42825DC7D9FAE0FC7171791FCAB10E16F3F027E5043AACBDB1F05FCD2B3EC7F6F46AD6DCCD6F9E6A6AC702451194788D14261219F794EA195F2B3778654BB373C68AB4333E224D161A1F89FE440BD8E968B518EEA28E81B89E04FF1A85B879E4B54650FA8DD1322D14B4A87"""), TestUtils.hexDecode(""" -947B02936A53FABF0009C0ED2E82970B33714BD4F15DDF7BC3A895DCEB96F9304811F783F8CC627B5B80868E23EE36CB98E6A5F9AF020BC5DA891E898BFF4A5AE003268A74BA6088E920511F5EEA54A5338D03356EE19C79E7BEA43AF809BD763EDED9D639DB0CDC790BACEF8983CB91F1087682A4E707E94B7D00EA8EDF04B57D5117F84589FA045A7B4A75C62FF9A344035E8B771D66D82156E28EED855DE1861023D5C1CD356C225AE03EA0A11BB1231B784CE9BE0D54DD6C4EF3128C7E14928CC0DB36DA5F81CCEE1924064403E964D375B071FD36CE9595509DA0BFFFA4E4C2DE1DAE201A55EA124C86F9B963221631AF131D2C4DA034A7798817D2734AE44282DA3BF2803D4DF90B718329F31317E5D585E323DB512D2036B74812C11B219729214B485D05917C913E742402ACA2127782534EB2DF176C5C25C484ABEF24A969EA2EB524FCB54A7CAFF7E6F464D8E716689810A2A02EC899685A1E28C2FA215572D188D3F39184D09EB93AB30D507DEDA6D6049E5345F989E071D26D909170D7AB1BD6CC35AC198EC7C0B48FA5679D24912E9EAB38FE594F1FFF5F2D97ECC84D8C81B81B2AD476CA93E050E550887D017E55B2B5D15700542E90A4639F55A63EACB727CF1F6C76D1DC7B6C0FFCDCC1086B7D8EE1C6624DDEF545082B4A4BA6637F8B77214914693DEDEFA7E62F5342548C0264206C30B631486CF5522D3BFEC6936AA961719984B84C43C49F2399EFAC02020613E97E16640EDFBA2D74ADFF5357A064FA43BEF8CC7D03AE781859942111E4C14CFEC01C47DD9FFF9D3D97EF92B4AB04C571A0C58DCE3BF45CDC01A7E09F7C89C81BFC06B5A4A46C88FF95B7FAAF3576D53346D18A0C179E73C4DE8501FF6B49963E2683951FA7E55B49056CCB0BB6759494AFC8A14A1D5823074E0C17DC279540D29C2329635189397DB8EC9F8327958BB00DDBDA507E1B54C226E7C02A680FA84E935588A435AA1CC029EC15CBFFF5B3AEC29034332C917882709A95266ECFA14D4459D5F7C60AB739AB428CD967CAE7D1D925BA66365A522F4F9D559D3268913CE7F0F228ABC49D4CA872878D7902F7A202A58FFC7D54FD7AEF88E31FA605840E510C639D0D568D7BCB1A72268162576717A238CD3416E89B3A77163529A816D613928C2CA18D2B2C6728FD622432E54A9085185042034D4DC8EA8E9F100BA7629201636CB87B2E5DF1F95FDEB407DC330716AD0D6ECC93BE38E497E1B38B94DB5DB6A5C067C6D0E1345AFBD7D2AB9646B16C531A96D4B3EAC2E540D479118F448780E15A3C17FC34051B4137C8E52C84495CAB2CD93420FE657743180C93337E39306874F8D54DCE702D5729F82710ECA144F040DB9A0907A3CC4DE9A12DD3958047C157F826F9C054CAC044567CB71A727CC9FD94DD0A388DF0A167DB6F9F16FB00DFE96968C463CAD7617587E5698DE7AC658E954D94AD94A1A3E6A5FFDF9B7E49429C00212839005E29803DC4CC4FF778CC331DC060E69279263005685494F686838DA7930805AD839437056C62510081D276EF676739C0D689B2415D3EC4C0BF67BF52C9A2845E7361BEA53111D6DE6F5EF65A22A62396BDE531886D71B925D91AB1F916AAC97201CFC477B694E898AA52AFDB46787BB85F01917B06E34342D2977E78A5A82CDA3C93F34BF9A99F7AE9ACA24D4BFB2C57485934EDFB7123BAC3DB085DB5B0F2FECD29AA6BBA2EF2C2B04F66605678BEAF90F448B19ACD4918A337FC9ABC098FCC804AA1E37E22C9EF010A9FC40CA42CD270ABD9E56D31B12663A984513AFE3917F3982F32E42FA9D67BA2E5C149FC2E6562E7EBC24DE2E1C475D05028E69AEE688EEA60155346843F71F1F99B3D4BA69DF71ECC4AD75FAAE1921EB47EAC6C4B73F31220F1993665ABA88F5C504CD7F6D0789B1166E4CDE2CDFEB140356CA5FF1B5074661A90958E940B8A7F80CF298B8366D81C4EA232DB4A8A4153028F9BC9B9758BF1BF27B7A4887D48A09C453E3F81A8D7D92ED7DA35B3828463C4F2AC5BFBDADB70FED3E73BEE26CF0B973FC6C00922C2BFAFF53842BC71294122CDF7E057931E46790356856930EE6D653A70F68E107D86CC521232ACB62F86626DD626E1D5745EB26B91917D11E68A6BAB09B6BB0BAAC327A37504E3B10037871BC8D92466D2EF236552C1F3E80102F8FEB03BBCFC4C51039F17D5490FD61A6E5BCB4BEDA507013CEA1C810E933CC805E67C1AAC6DBD9D9B7204FB5560D691148F7369996B48D370F32739ABD5E1DAB98BDE86FDCCEEE4459E3396C8ED7137BF5326322AA7A41B2AB74CA5D76ED91DFB678C66874E7C6B4C6367A5BF256DDBA53BBA20AAC90C4855CF1C608774896A974DF5B1840A83B2FEDC619D707AE30B186F9FB75BEA7531035207AB889B92FEFA6D9802E6D44598F534390178F14E1F629629F6E120C1DC8F5C14C392C117A239E539A602E521360CCE81F3E70D94FE371A13B7A42CCDB29709428D3EDD96CAC31BA34B91BB2A92C9208B7C81AD8300905BADFB91DE8632C7E62C4D4E4C32616F712BC4A50858FDB651AB486B6D0D16A0BA10D128D539E3729F364E628A93DF73DB954C5D8A1CB6935E1D5D3AC2F905DF189736539298F7A20B3C705453CBB0E991ACE069DE62A2C89CB956E8E0110083C344D971C61101DBB2978E1831885EE7C27A6CDEE29402552D701663E5579F450C4788D46AD794217926CAB7EB351E93CC7D3771975A969A3A06E789EFB410FC829123BC00776E6940D8C15CC8773992C0FAB5CDC59EC4AC6A8889EE8087C26AD7702A8672F711859A179CDEDE22D1A77D8693395575ED4E023B903C6F14FF4A2191E49D4C21398E484B3189F50853B0B20B2BBAD0EBFB75528B4B6FD5C7B7B71CA9D4DF36E67ADDBD7305839E7FB2A25AC53AA1622F13B3B4C4E8CC8198269065717451CBE58B8DBB1F448C96D5940EB94460618036398172A2F22CCFE2B31DB2DB562EEA7415AEDB81D65EBADD8D2CF04C69D870C898D05353D8C5CCB2E37A6EA9EB3E5E9DF32175888E07F4472A80DBEC699210A1E6B8F4BC7968C3FCD9666AC9D1CC81C3428A26A3A94C96292F3A8341FB90350FC79DA7E0D947751C6E1E17770B980EC325E0E87D8A283F0BD853F221873853DB22213BFD7A7D621F64BFFD73115B48C4B06DC11F307538CC86B351CB23E199E15733A2B5E3E2360B42A203F632A8243B1557C64773D72EE1D3E3E25AE943AE3E9F984D116938D39005D4556B76A793AEAF0A6397691AF7386F509668B435DCF7B10A8B810FA55190D56DB430E0061026292D3E494C707C85E1ECFF151D1F243063646C7D8D909CA2B2BFD3DFEDFC08173649595D667C8598C5CBF10A37456575839BA2A3A7BBC0C2F6F9000000000000000000000000000000000000000E212E3D""") +c2112c791ee26987cafdde1bc02fbb99d5b97ad71d4c75cc36cda559ba853a351b3088a5727856774fb3a100640034901b886b9aad882c879f7f7a50090b1b4372ef71a124563aaa22ed2b227f76c4c5ad691499766556691ac72d3ed717eb83c06951bc8ba4c8829b225aca7eddd999e9e6e9cfca939ba21d2f7f79c750f43719c520b344252a283cc677fcf1dc27a4dfb396541c97d7e948ab873640d1a1a0d941d2677878360eb2b703f727a00cff03547f5516d5e18b07d904e3d978a905c83b45a2a58f407a5778d6e6da955705f0e55931fb31a1b1be5196b6e80574b8e37022d4e7778bce58a817aeee7ce13c07196dfd6c00a6604e40f3d12a46c11bc6295788be5bcb2a39db2bd64780b966530496a23f9e60ab9c7a4a48a5cfc3b1f657e00aeb99eaf8ae38e723cd14191f927ebd7944da428584b23da5ada543d3c071cfe95910aecd65f7be88aa6c7bfb6e52ec3c925fcb0fa4b09d7612a8b19a4156f44d07c77eb229edc08d78b52ddb7bb3e42e95faa1b013d4861ce5166fbd0d0822baef9bb5d1f41956be5cd1efef4bd3f92beb656957c0ba51dfd4d186e4804b71e91bca6f3341ca585f0c48c3cd496a1f1736f513650fcae2379bd1d127641f1a92c0c394d2c02301d29116b3245ccfcb6ae3b55b29503a49fe6357d3f027a20c30528abe22623c53c73970090b12d994f1a69d5a9877ef15f3475cd1b9d58cc38a0289e12a09ff756c7e93bd675b2354d78ec79492051751db9b3f35a58eac539d4c6efb259de9383d5eea913c98a6daa6173b113f8d7bac440e1bc4652d1645b96c4e3ae6697c9e6e7a1332d27f28704b850cccf469f829a6aee604e0906d1b84fe104303cb9e187a19b9ef212dd334f134cdf6256dcdd39e91283e6d7f3f808fa5cebe6263fba31f766bd86fb271a524042d3b42b9d1e7729c00c6e4104eea77934fb44fbf7b22ad80eba63fcf1ac416429df3c012afd4f42984b8006e5ab52b94fca1f54fe91ddd2ba4f8366cf74597dc4c2fb1554c20ca28ca4262888d70f342b55916f6eb5a2e6df5a9d0299f2c15ca37f5cd688792a5c255e2f684035770cf4a8894b750f1f97f9c226f9c451ce0b5701a4486b9feabdd379ad31f1164706a137aa487a25c088882c282b5f67599f8f9488b3c1b0540cdd48ad57754d760880478b686914cc7cbb3f478baf3742382749edb287e867d5863fc40a5f57805d1a7006a2b45046698ce63bf85fde10d9171a618a10da3b20d97052fa9416e56ebbfc9b1cbacaafdbfdfecf18d23df346f6838d90d2f0a45aa650d08be2360ad8b3259541f86946fa047ba2cf05e9542e67307dff451a0bea83f3acd2a328f0e9a7c870dcb1b3ef6a387c208f5128951b4115aa4f58193844d54113a5d13cc6e58cc210cc4865613db00c6c515720de072a9fbc60dfb50f48fc9ee71072e14a2380b62d644dd49c7c8f5b30233434f56ebb4c00bc1106f2f7b89d6f4076480fd24857efaecb3a3921a3f9d9bb84353792bbc017ec91775660c21cc6b7c2c5b629258fe1655afda4bde38fb66d9f5b90e0f70419d06b38de8bf050e7278cc02b9b7d762dcd32245c9776da3fe15af5bde873bbfd1d84e8083a06ae1d030a7d32e9a50be599ed816e47b54ec7b686f5e8c55c8edb7d7f34302f343ae7027234205c8d3943244f91ea9c2e6f2f33fb56af3a0ccc1c101608275ffd7a18201a0cf3291320e8c1e397684c604dcb23953aac9cbd65fb8fa615dfe77dd2b7033195030b57e005e28f14b316e63c6a62d81fee131d3ae71734e90e3ca43c6516996fe169bc279e3b398e8ef8929760da3389b29c0e7139a2d889403b823b3361c310ab668167eed34f3ff6e32542619d7d5298bdf4c9e7b4849f0310f386faee38f5e94f5455ebbfce87a34fa93b808d5eac6a62b1fdc84d3895d8c78e211a7074c78262c24c5153234882a4bc043703d997a1b8ea707712ed46f6fb654758634d1591ee3d79804c8417ace22343bce4d0754f4e72e2f518bdcdff3bad1313b974f7f2b7100e6fdbf2fcc34f5eccddf570905659ace5cecd78ceb88f7fffa03bcdb71a77f975f3d13146422c765a228063cd9cc92f0031b8ba6796025ecd4caa8bab5c48b0e6f164739150ac00bbfba4ce69cd212debadd620242fd5610f3fab75e7a0eb587e4ccdd010fac040d8c0b71673f6a6165b188fb59293138048805ffaa283b9539b947efc6382c929295769bf9d5e434b9eac6d1b9ff9ac26c0a1d1f0efa3108401e4f522579e1bd504a64d1359e44fa59f4f33ac4cf3e7508aab3388cd5be219937185ef7459b9c565034c8d4920d5fc62080db0f0930630d14c285ca11e360705f8ca5786e394842230636241a461966252d634cba8f68e0fc398b4298f4ecc907f5a1fd9795e427e6de785d7bc87130d986b286afcc646723010b329e8cadbafe1a9ee23f8010fa6ae67d1bf950c5f0e6fd53d31ad52ca81dfc5225f61de691d868130bf71d6428474215c9d5236a796c29f983064a2c9f40e69efd090ba55c47313f13b52b5d9edb7206ceb0eaf57198f32a722f9a60400bf550d5ecbdb0e460c791c44e56a1301f6f6bf0d9c1ff04ef6d238c060bc10e75114f7d055b5c3c0ac2961ff42c1145a8505e5d6c53389f04b20d2cbdc56759b861c803897be3eebf932a4877b1c4a0b63c96ef9369445e48f4b0ac34bf1799075db6dbb7d18d28f15f58152b0e2e618fb4551a85f5d1613a0a908a2edbc40e4d7e9683ebf5f9f8879e415e070a8eb52c71ee5451f95f0d351c3013e160d55c1207883c8e6fc20a4aef495c4194a7bfc8afee6af3b82bbd0a32aeab5023169d0361a4449af7a19318d063e4f2ed690b28f5d0786bd6ce5f72b9a6e411d878abe616767fdae52cdac529eb07074ec518723f8f870666211bd427b5253a67e40a318563a8b2d8916a746fc47e3ce26103c437e07db67ef057bae6a953614ee7acd16532d0485ad02b4bec1b84302e1e28c41e508eac18f33f76c150c3142e1c383c28ed902dc79922749842efc4c91c75754ea5e0678a117612dfc7ea07025cfe2e4213780734c4f18e191cbd815619b41b0f2e9965499ae19666c4ea34dc1af69dd60dbbe78c6f462a20699b58f50682e9602e7f16580149797067d0ed1b0b36099a0c5732d64d1efc1f370d4c71a6e77c5d319571c3d9274444db155b11286edbb625b77d1294d6dce64ad7fe58a7808b7c9edf7699bbc0e0342dc74158ae419c01b64c07bafb6452f131bd0f889cc40419d3dfd9c7c4418a37763218498c29f19a0b0d2b3e404b525d707c8cb9ecedfd22303a597091a3c3cfd1f8fd1d252641799a9bb3c4c5c9cedee10e172b2c33393c5054777f9eb5d9e0efff000000000000000000000000000000000000000000000f1b293a""") ), new SigGenTestCase( TestUtils.hexDecode(""" -A7DFE40E0A335C3B287EB94E97BB6875F589EFCF7FD841EC88F9D03248BF26C9EC8E7F8DC376270F7112B52DB67CEBFB8A5FCBEB0A2273FC3CB8FF1CA1DEB5C581335B8F6C53E0F8513C42D5AE82B193BCB8BBE9298446ED79D278DFEA201D0B2667E3806972F34278B83138432AAA10065DE34B24303A4E5BF1A5E3DB90825684A0205948885094459C3840C916061A284A8AA40CE0A828123369E2208254C66C91A06C64426AA1B44508418220379218170803406C5B384ED3224A48A2519A840DDC420294A82C14C105118070592009D00405C8B08DD2222920B8880A39511086805084910A098AC3A84C5824080912698A486401182C489804CC14051912250832855A202942382252B8880A814119032D1BA5214A448492366A91B84C1AA528513669DA240E14820C08A0244A444E83B48C22224212C985D014690422824B882913298918A1201293306400201806451C8051D2A870D1444D13268A1C376D84186024C6081A262D011621C3048E02A06C832446C2C20599826418B86459B0618B240422B58CE3080A0231229C244DD4C88448202202868063B68543A68D1A132E51862911B929918868D9C828D4320C0149498844105842269CC265D1165064A27049A029C12641D1403100262A51828DDC2401C14670D3C0484C962909A18CA4A485889410D00030C9808C8814501C234E91287218490248828D890005D4222D0BB26C21020018A00098248960A88D8B921062B251224282D8B02853A090A24268CC0651048940102229140988D1322A12C95023C68401068889B62819180E10468D03A7500028051286248B9880D3242C0B172111176D5C048991888C183388D2268DDC42450208300B302253148CCA888D89B665111482D1A029E428315B462952B221DB126A01B90C0A3361A3420D1A3528A232498898802011285C200EC3284EDB283120264550C04903298021004A1C347098360E11A04914390CD9046408100D09202904A52D524400D01488E4084823B4110B907103440C20425021085212994CD1A8290B4229DB1229D3360513256162340814B24450068002C20C22C98D4B968520962480402C51B26C0922424B8041984809E3346E24829024930C0A1348533440843004223826A2042C1C9484001860DA864D14331204118E030144E3240263C029E288291291019AB22183B29153222051380400A244D4066E19160E08183120388C14B88420152C19A02C22192E448468D3B048D310612181EF7DB8F0B9A7828845B0CEDCBA94F60B86C183E48327BF5CDF316E9A8F55571B452EF600C2A1AFC57A159F501016FCA48627C1FA9D7C3DDA58BB4D41EBBB6B7F9DCBA591719CC4B9ECAC146BF8788B48C911600FEAA5683EF2D12C45A3C14A0A5A62839944B427439881DBCE4481DA951B10D81FC7711D64CEB088DB4A70B5804ED577C30356BFDA58D5426DFDEACC6F7CAD7C30E718E7FFF4AE006BD98232417ACA13359A05F8B389FCBB29E9B670B28CD8AC24F3ED55F70D8BACDE3F144E79312D8298FE6AF01996E00C5E8D940A408D532CFBA872B461F538E0C7583A73D8C93E9889E251EBB4C7B1DCE6FE013DAB5AE565DC3EF4F4F5429930F1A6DED98A66932BE3B985E4DEF769609E5EEFE6EBFCB6FC56E9542FE4ED8A121ADFE9E19B8F9EBC4B9C1F4AEFB351C2D3840499D0D2227B157DB138EE62860F2963D6F3D6458F457057E4A03A72ECC52589B74E12F4EA37D8E0D9797EEDB246B88744602332EE0886AC9630D876BE34D9FFF286B5CB06498C60CE53A558CAC63DC5626DAEF14F702CA476E4C08A569DBEC1763DB6C5910B8D2352C6A648B2A6F27F9E248FA4C42FD48E7E9CBF37F318A8D4362C1B53741B41E4231680A6F91122520306325C2621EB87A1736FB79098006E83E17E7E22637688CEE4BA8A399EB1583CB8EC9DF3B8C284A230AB6622D73F590D19331783CC2C921EBAE23DC5605F4707CCC96A18924BC17952916A97408B4715FF3F9ACEF8FC4943BFF6C9F7F5E7DE18B93E679D49D04366A658AB913EA5209D22D72B62992383C7EAE704259B5932FC09F76A12FFAC12605D8715366167DBE45B272EE7EE27817128EC94E1C1299DA8F58E4206D477AAEB8BAA8634107E14059E75C90926189D3FC06C9D38799F3E00BCB87637EE24705551A797899C9EF7FA41F61342E9B2480508D9D3401EFBFD12776EAD4CEBB815F505E1347609AE7527C81AE892C841F0D21C7F97003D5F9F3843DBDB89A4E55E52BF915B92F0F2CF0345FBEDA99C322FE7BE34E0E08034078FADADFBF0661AE573EE9B664C9F05A8AD3F02B1866D24B8230D20FDFCD358BDD88AAA4C3E458CEBFCCAE2D65C64F6066C7495B571814F714545E6423D322848459DCCCC2120D8BA7CF672F37C5343085045FE3037070310E851508A0D5605249AF5D911560D308C81C7E2F2538A0A7EDD6DE341424ADD8249D628599953F857913F5767584A7420A669AF08AD060281D536C170F383C450CE8C61DCCD534AE64B91AFAEBA4742808733AA718A13BF0A55B1BD4AD618A932F84F8039754E1E316C560AFE646D98E928C28D39F5BF2F0D0E079C6BBCDBC5843A5FE72E99642B0E297F11AB5B9C629BB4601230F33837975AA2C81664825216D8821B79802C0C3812D1C0140AC676860C565E7775ADCD2D41865B23DC61BC5BFD3A80F56561DCE6F2A79D37E85629FA6EA952289FA3AAE5DA7D4E9238942684EA932F89AC0AEB15263AB2D5FA4D3D181851E38BB2B3B5702E6E8DA5CA981D2DF3A0A7371A75EC897A46205D9F05594DC169333158F929E3421220EFF6204BDFA75E41481A3E70BD4EC1D4502D902698C4FF7FA6D69CAC4A8F67EDB414FE5EFBEE8A6B695B218AF6FCCA45CF900550681B124CE36D2D9CBE8B2F179B4A4009281A559A6C5B30D4B6DEE9BDABEFFCA70446166CD353D8905641EF072F00571CEFBEEF7A296E7F49F5B112F6F0A6F1576468C75942609484DAA448F4508EAFBF2E9DFD2F83860831D6EAB17B8FA73E493E3D8B71530719209FD2D24637D6323FB03E3CAD1FD601F1FBC7B408D3AA6B90C053BAEAEDDDAFCBEDEB3CE0C6A70FB83AA450A9968CC458C18CC9571F74FFE1ECA182ACA2C4EA57A60BAA4D922AB6B006EEA433CF69448AE44A807846361F5E09D565D89410C3CACBC284DA15BA53860450E28843A662BD38E89C0AFF23ECB50B85C7069E44E211DF89CB12E6CC211036B0ED7EC5C098027A8C11EEF0898B785DE421C8212EC9CFEBDE72463F3856831FA209B8C21E63CADDBCFCE247F0D831373B7AAF82B676FE9C7E3CE70752AD0C45FBC3C11B157834103B74597644E095C386C6FDD7C9DB072EF20AC511DB9D4CDCEF85330E1372512336D5CC951A7424A8EF7FA4CFE956B6926DB9E1969747B814EC682659DC28A088A37B62D9E84485FB3B33B6F69BDAE3DA0C7D734713632B9926421B7941BB44D141AE72819281CC405F667772D68837B58156BEB2E2EDA6A51D9B9A5DD972E70F3F2B9DFE660884250CBF8E539EA6E637A693AA3B7E34467ABB697AAC4FB376048621F2DEBBD94E1DA4C9A1D2AD21DEB16A94BE1B0DBF0B5DA2C38B618CB3323D9F"""), +53a902d7abe3103058efce7d2beeea878d48063b6dc8aad68420073c43fa51732003aed7006824b025934e1c8fc76d0afe681d830c45802205474b5de6388748ac11a6112123d1cc78db7b24bc040fdd3d546fe3bab7663bd5ef49eeef652e200b8f9745383522cf74a481e2b63b4f55fd245f2e9648a24eb158069b1a0a29759b0686e184310130408ca61062344a01b04954b068932848c834408c804912a5200bc9298b00509a120ecbc86808a62d10254a5208450c842924336510a069043809c04444a0902d98102e22a95120332a24000cd9166ea3c86924401203380ae4426d82146a98a88550185201b6485b068ed9a889002391d94292dc900c19222048968421b50cd88411c2966022274813928918c8480846505b1651a4b26ca08804013960d18870491251c0080a8b086422024ec2a865d3b24c1b492204190290044a21b92882a800c000860822058a32258c00661202601b4200044104d1344683c00023382800218d24858d8090400a057052946c242200e2a628123904da362adb106961481144468e833049d8a45021a46d5884092023860ca849d002001bb22118146a49240921398c0129240c42848bb064120632c3322a2386254a02520304299b305183108c14267062460ae39409a11411a00002c3b6099c0845032509084932038200e12200c43492232621918685d224245b003123b04d0c218622c04d0b2665db309108a708dbc07108358d08b4848aa069a0282519318221332a1a284603a40091340a91022842126410466004922819b47058b89101b340092000a39465241392e10229d3a0219a364d14880d132762c9446aa1842183a40111284a21200890b82093300d082562031001e2b44c4226005994000cc14c01302142b64d19c26490a08d1b328e91302e93308243104844c05059084d01488cd2b20108978d9a1209123751d0b6809890810ac104e100400b02261011492132249c4832d426904816648b488c93944c42982d10c14c02a64cda1248ca26602004861228301bb269c3b4694130229344105b442042304021293149268c44060402992c20a780d3488a0927218c068dcc202084362823916958a08ca1b60960b660c84884a33221c80408ca960954b811949209842208c9c670a4c42093222e20a849a308609130605812919c884590006d821001d0b431a344501ab48501024911476050022e63266241362ed4362611b360d002461130451141701341681296092d2abc12b905d68c3f7eb17d160fa397ade12d639bf6fed96b90ff181d3b3cab8c3014eaf7e666aca774de4a4756fe41f540a66a61d7c48de0e5efb6b64dc7495416c50c7d9ceebbfa166e65aa83dee366a6f946173e87c14d85056fe473eafe0ea81226f568e81c6b2fb2406e2c7a7dac0dd4e79efb77adf9721a4803b56d5363e263da9f7915921778fdc9d7b441ca49f0f196db87362a7243ad8b2a2b292e1fcc34d91bb8b985b6d9a3c324cde93ff97b2515ddc90b1e089af7431d8756414ad15ef8a383aa4ccae41c56ff103ea19f4461ae307c511854db39ffd0b97ffdd773b6dc6ef6bcfc62cc46eca01364a7b10c1189e98e34a360aa1e28d4a0fbb329fcf318d382699e990d88304a96a1b520acabf3acafd5c2a8dd28d22a956486a1df040e35d9d1b6b66d261f4813b9785561d1e32f7b62b703d066c151a6795744ae6fe287d75defb3cf9622a6a98753bdd47854b12c3d919d603f2bdf846dc2200500c13caf8357ccc9b2a194d55777ffc9ae29395d9cce2ba921eb07ba57fcad946459d3131cf270e7eb9f2bc13769d7534f3b5fee9abf73b4923d635b1d40b4a953b9f8847574bfef1adc4c79d12b21316ded675e4c02b043c2a4c6c7ed17e0dd68b0be4d60dd4431e96f290477b3a058ff1dc4d3d0fb547dd2510a442b72dae5b3fd6a20fc10f31c60414c7187e6ee85e3c1c0349d15d161a339a91271823f3870188b75b5fd628a2b89da504bc6ef6bd9e15bafd49726722c90a50505fd44ec7704e9c6dd0c1ee6fed3802086d724f23bc11d0f1bb0604add497d4cbc2671c9a9c941a19eb3345a90f611a45f7faaefc88c5e9dd65c736285f4429d8c57048d59d88b395b39c517db477486b7b5f32cd9b3286d59a70762ff2bce191355ddfc1846698bded592107d99825bb6e74fe914eeaf61632d68cfe952adc627054ba70606086ee16e9d07de9645183a853a71656ae4143e2b52e1b72161150ebbd2a80c071b8f68ff67ac7b78b8df1792298ea58e6e6a538d0f73b58edeea526ab1be7d51d3b77919697dabf7de38165b016f5baed1c6379aeb31ad94e20c70b38fb04b15ee8d3f53d6a75e65072fb160177b8abc26024e74e6f620b62b321105cc65ae44d4d309137da386c493428556ccf43a53c1878621d2f4e77fe84eedba5f26f4b9eeaa151dc292f9ee1000612c64d71756523627dae08762c121feab8b81576bde8fe3a3ed682741cb5ada7b7d9037abc35552024e074957df2e48e361ae2a8e707a5f16072d9144ca4339f2f211ef6ae0a81fd4e261e61bac97a47e52ee08a8883947c3be9bf942f4fd625ab2765f0a6f9f50734bdf1f8f185d73d62902ea45ffed411540e745c9f61adbe829f7b46a453473746de0440b29ad93e17c967d767a486eface4ffaece84f9697674ab4b4b136702c93c5da872a8d4a5aa2bbb095e0734d3a7fabc5c800fa77ec325d6ef7875a57617300e938b13d7aa4e9bd41f253560a3a46f479dcc0a72c0923d25551e90f80c34a89fb9a0fa0c2947f50ba0526c61dd4795f72080881ae7a9fbbc0543c895e12bb1d6ba8a486f53d12fc694c5ed63fdf7c32a5cf8f096a96b5a0f679f1fd12367600db4b9ae01d2b3cf4e54240a85cd4f36367967646e4c0edcd6c6f81d674a571fa135221bd48d26744a02c9d1e0368dc772d8f391b985f76a91e657cc970a2acf2671c5df8b9f226b49df5db806b2123fa1e4ea83c5bdcfc2d1eaa64814ec5872b339cdbf4db240148982ca77e3b411bb02f798a22e08d7fd49a1bfdad6839d511c9a8bf2f28c6b32b32f13370f2e7270ac2c84919f0a7522f0aa53c3cdf3059e7beefa7c98bd446e79213520f2ccf91948607365d020a25b27b01b2e8304dea9a42bb111ac822d33e3bbc3c106f21a5ed8cd0c39856dca0649f458ec122a00bce59b1be66281ffeb07080e5e746c3c2ba813307207b5066dae808b944c30b4b8a039ee85a54a32c11ebb0c06f148983ea8d684d434e6200a3f713eb713804780ef113823f759c72227f85e474fa90091a9804241a647cb32778d0bd71bef5f59d55dfe18efa62ad701312b023a920eb53e92b486af3d14471b1f0bc706841328d34883c1717f94244002317dc6e60bdecc68396c016fe647c0f9bd146472660a67fd251171ff4a5e4b4a5a76b2ef0ec2d107449200e5a4bd600946213cbf10f1e8ee23cd3c34857acae9d592cdbcd1fe17f2c61e8e3dd60086bd3c79aad928e34d13c263f49b099d0ab3afd734821399207902b2bab437ca6aa478151473147ca0605a34bf9be2b5284d4484a842386dc7bdf0c15aaba8a043fc571839d78b09be8f37ef34cb980"""), TestUtils.hexDecode(""" 214BC54C508E63F77B261DC59588A87CF95C233C22A339E7158C47931C1EFEF775EB3C91A32C56E888214F9F68D7CD2525B23F695871CF5EDC6979A677EC19CBC5859C63ADCE2E38C67CAEF20116508F33BE8035E9C47D124EEA5FD1651D64371451B6B96601E4A6E8292ED6841E483C3ADFC3DB242D1D7B3F036492741661F45232104A528B6FF79AA4630740BD16B37CD3E7C711B76A259C0845D6F87E4A4B306E939AD1C41022A7D5938E52B98485D95D11BE629263E6CDE20F63AE16CC2E32B6C1C442EF108D92495A759D3707AB6CF3ECC5AD7C02F133D689E252A26C014A31C65A65F079C622BE3B648496BC57C462051B17175FF81126B5BBB5324CCEAEDE0B5A8ECC0D710F04DC0C751318E8913F149E701AE0568B5426736288CAFECAB1779C7F4E96D9007635F76DEB4D379918447F30167F257B8BA825A50EE845FC4AF7C34AB200D5BF45B5F0405BE2347ACC814BCDC648C274C24F8024561FB66676534F1FC8041B63114679D9F4E8CB0BCD7BC4C54FBB4F9A178B4FCE64E705BF8FE42826EE01F691479A8815E2DA00111DE40B5CDE464A9F7A3D21BE9562FD9A5C5CB3F4F9E8F0D8D8A20B9A5AC9D7394AE4316181621B43D8220FDEDACE345234E3DFBA134BF54E458DBEF98923C1891CFB8DC9B5317E3B16C740EF373666969C95BD1C53F435D7ADE792FF9E310A191246154064D0E8F20032AF4823A335D88D5C2A943CD4CF313CF2999E237F6EC50F63936D0FF3F2C729FAF0232671C94785B67E0CF71A7CA5B32434579711EDF155D5BAEDEBBB8F0C6922AEB9798356714931AF1070C49BCA507E289F005BE9D8B46AA67CE2137935C7EFD192E4CC24DBC434B381E9A15CFC529D0064F057FC3AB592869E5F1AA5FCB299B2CCC0ED6750E318F6FC969E6A3A08059788102CCE79BC92804B1D08F3BA30492054DB6401EA251191BED1B8CD35DEA3A653D5D546D2EE8D31C2D88D6275D6C7B463D449DDAF586D5E57FFBC07ED5558D87F7DCA82E4ADF49EB9135A578468907BD8A6228EB723241D58BAF3C78C46451D2F11CA0552A05A85620001D376C6194AC6494E337388EA49821C233F32579FBAE6D11E9DB257C426D99516A16DA63A7BFA261F2B012CEE4EAF7C5C16C6331B79A26E79B1421371E574505F61D699C6DF33EA734ED14129608260B1233C387638F7ED3A34866D656D74F06C2B8D70AE60A0994F3D6C1267DCA2001EA781E5D6E17BECD284F967788227E060381ECC60A10832091319F225C972349BFEF08D4DD5298BF7EE11B693AAAC682F91DCDA113EFE0F35CFBAFF6C73DAE43B8C1124EB57713C122F0A5FB03D02C4128565FFAEADC0AC23DBE5BF123CBA024DC2F3956EBEEE95918B87D2EB22EB1A8ECC3B267528A62F2280E3DAEC02C89A01F5829B5891914DAC"""), TestUtils.hexDecode(""" -7D337573A06A3698B8631704D2D6A1E529B45BBE47236936D0BC13A6DA8E09ADAC5E60E2D0D2D5100ACE99EA411D50C77CAE43BDCB50B330412EFD99959E562100822C5F2B932F7D43EB8015878C49D182EB968F3B12313F6EDF5056FD9518FE09EA1CEF89411D126346924C0B4EEC9D7447083482C12D6B98F0EF74913E66A018319143A5DFBCC3C21D1AE52FA19FCFF12E4730E4510B90EE9F9727C240A145CF34A01A5BA058CFCD26611D7F729F742610AC81B94E931A47039027F81377C84CF225763F68A446B63D64A3D375E1EDF67C1EB3E997A43BA77F108CA3D16BCCDB6CC451308146348C33C9485F4320E8A7ECF3758128B929D4E8CE07B3E84999515A0E5CD7D7D6C5B3EE0E712966D91666AE5C2FE8E30F22A83A1A7DA0FFAE83531C30B3A0B49029239409F36D384C888AA82F86B6D00C0D6D02FB75BC49831489161BE918EF91AF79D031DACC7CFCEC51467F5FE59095C1E8FFFDA2970D4D5EF2B72D519AB0F9919BF046A19BA279F64A084627315938EC50A5B1ADE46A4A2E3D382BE747D895E0AC6926EB6ADBA0E845FA49903B83BB56520B809B034DC7A4B7F292CC7167C51969C2C8E78CFA42BD342B78104512AA4003C48FD059AE0735F78F4837802E6711B35BE35DE93B86D9EC82C9303B732CBE1B16BFC3E718C65288810A5510410CA87DA489A71DEA594F993C7B45FC00CA68BEECCA107FF4723339E15C49F7839725AE5643BFCDB2B98C443DCB6CDD5169465740FB9959F2B17B4BF31D0704FA48ECAB5BD0F4CAB954AB132D4BB0014E558083F1ADCC81B9B5ACC2987F57A3CB069187325D5F5BF5128185608C464CF9534755EDAA7404E35F6182BC83D016C8892E63A7ECA6406EB369FFA55AC37963946038E3F74D9E18F3F40FD190DD510B07D2FDD244D74342A2DF22CBA0835B5A5183A4A9ADE24D82D7C988723031FE07BAB95F4BF96CA393BD58E74CFF56F916B8D3835F833EE658C788E9AC56E408A5A4E98F05C2379F75A82514AD1A42D9A90742C7F92D982B9C789A862259953D9D88F1BBFB1BDB345E966577226C87C6AD8DEA26F75F0C3715225B5297FA7C5D375C1BD8B5D6DEFBBBEA757E6A504E83B0F2FB3A80CBE2FE526CE76D799135497C498A721AF6EA8443934E0D76266ADB52ABE212AE58D7F52458901AB3CFB8A1EBE9AFAD9203EEDC9D1BA66ECCA41D8C268541A83CB49243FFC534C9EE8E0279139989FAA602B668669AEEE6E00EDE80F60CD41929A6BE3800E53677056C7D0ED1AC4D80AD357D96B7B2C2F1B35EA9B9CA397D23A2928245F7A9A0BB4AE0569F16C4445EA9CEA3094364A40E8CB5D06E1F624DF1929782CC33FC322201525CD181CFCD4A5D4201693D0EB249E9967095F73A35F4ADCAB9279C93E0F62E533E121F3396767D409CA80447A4208BB1D83BF7688A007B5402B5F0BCE4ED4EF51847B9F036C3BE81EEC6A6FBC6980D5505BBEDB99FEA87140EEB4B3AEC965108B48C6C808414512F04B5DB3D27FF450D54D6CF5CEF9F9B80D60C0C9A2F2E33129411013599A1ADC3B7CEB410CD007E413B463C1E08EFD1AD51B08B21A08163080450812D6B020A299BD8BF3C8B5E6AA69BD5ACA973C625D995EAC71A81B31E75B4BE92A773E9C10E7686EAA978791E0A68C0C5371D6FD12DE5A370B09F90CF140B7D1B63E381919EF326D0F58A21F04BC24B5623713C0F42E56F4727278C1AACBA51CA553CA46F7B4A3651584897B5EB99BDAAB90966D971AAB0768C96CBAA0D87EEE1DC0E8578B2A8416157BB7BE74F1D815EDFBC169D2D848AD00CED03966DA2E6BD5F98B230D26C3979EAFB099A07CD5495E623238EB46C62F62B748CD97491F0CA8C9A91FFCF617649951C6C61EFBA868E240A2B754C4C920B025BC51278E5239A7EE1F1223F4B8574AAA9E8EECA6B65356820F8290D336EF57A7E6F84280BB7179C6B919B2D89450DEE63BB4DB6AC77BEBC00D0D4407B8D6018C3D878DD74D27D3C01F555B7768859E499EF742251CE86E7ADDF7745C4C2931FC872DAE54060CB6B930F9483D0634613DF19F9AC589C39A666E00F8627B234B95BD77A88C93572FAA2CB38374414E56BFCB9FE30E55F85F476D08C6C6680468F6E23378795435E6B974BEAF4EC6FBFC49A3C0F23277C29EA4822D36A081EE3AF75438A99811AFBF54BF9DEF686F26FAB9A8618F6AD361486209CA84ECDFC3960F47C61BA603E09BC3AD5048AA4D52842C3B9A9C79B49AF43AA952A972B86C485CAFCF2DAA0D0D1050F66E4D8DE1F1732D9C88C0837A83EC78F033C762E950E25BACC1DD6B89C1D4C05728D6EB03E7435523CFDDA3AED8FBB4E131A494D11C951D88490625800E35E594924D84864DB441CF17C5A5E70E0A338D2F5774FA6DD8E3DA2478D6860D032C54A95990FDF5BEC5083552A386A45A81245EB75ADF99A1A6163DFA3729308F310C8C212322F96B08BBDA9ECB239CDE74E75D324F61CBAF7F1A40657B86E83E896706624E51B3730680C574872AF46BD84D5761105CEDCAF29ADB1DC24A1C8B74E6F762292BC03FA07CEBBAA430648BA27E9023ED7C7A2B61BBF1620514CEB508742328AEE012939543D69E0D705BC57903A4E8183286CAD8579734FE35811285CAAEC8BC0EC14F126B10022E0EEE54766B221B6682854EE9B16E53EACB6BCDC989E47190275BF19B3D894C8AF56A4D34D61CC6C078A04B70A69DB3019A5BB0D3E349DD21C101AE2B42EA29950FA164FBB86871597F2E64A84BDD281F1B3538F51F01C0E87ED962640F18DD3C429CEE89B017AD485F188A3A1803D053E7D8F22A47B6A04D558ED17BF0101EB7E1D7D0FB1A1B6082D12398F500B2F65363912B8D8D94FF8F73F1246FDD4C3E6F7C4E372842301583AE8CBD5EA185FFA685E21AF074E3C2883774534D8B449A5DCB07C46F36FFCE4F56222073806CE59EE5BFED172E5A252D214ED2642207DF742AE7A62F8D9A4EDBE70182DC277E09F6826C8DE5B103AB17A892DAC844EE7B2019881DA549200B76AAFE5B9E92711BBC36A3EEDE9B24E44AB42883E2BC7B9109B70EDA772642317B50A4D307592120485F6C1C7B29A0271D571C7DF5F0438C8B725FA98AE2147556D38A295C373B627B732333A0961A45A20EED30B4AF3A95890A12E932B1BF934754A0994154C814E114E9D671306FA257AA8D2FAC90C5920D2E20FB35C5AF0259F7F69607C29075B8DF9B7DE0C4059D62BAF1660E05EFAEED41091D3B6323E32538CAC3D88225B9C683B69C415003CBB0A770A0530F2738FB14ADFBF48459AF82D5D43C7ED0F1E2131535C6266757B9398A6CADDE9EA000621252D373C4352767A7B939EA0ABB1B20E17717E8098B5B8BCC3D3DF152A2D3855565F606682889DE2E7EB00000000000000000000000000000000000011232F3E""") +8ec19a12690fcc4af18b44a46b33caf661ff986315472e2fb9cbf0db6b11f596b5d540572ff4b722d39e5685205ae44f62645ecb6a4f319b1dff9c685f6bc65a311cdd61204bc23da3dbb96f71ecb3922ac19580212e57c121abe10baca724b0acec03dbb6de182f1bf5090131eb5ced5b8cede5444055d33838272afbf8a9d9752c0536f5b544dfd0f20d4994638157e64ff51ea35539244dfad50261f282ee2fbd5fe3b90607a4b2590cc24e67911927ada6cf9b03fd482df572e6cc7441b6129677f3d3d0c0f5e7212bbc652bf53140630bb0e3236d09943796ef92e7916a2c4fcde8c9af522d9661feb6dacacce83e14a6384afaface04e3c8c0febc6306445b84df88cd91f34235c7351048c0d75b6039a102bb0ef30f6e5fae78718be6412db19dbf7536e42b0e5efd950e764c6a80f70839d356f55d607ef58eb366a840706be8f79e8e2ba251063336c819ea3fc60ad76665cd7fc8ad9e404847e0a8ccd5aadf3fc36dd091972959e3de4a5c49bf799c97fe4ac5e993fccd03994e6afd1562a564b111c52860f564e1b335664d57de6fffe5cc93885bc34ac7d278dd28efb850f3e67e810285f47e170243454ac65a18807dca131c99be1f85e34c1c6c3bd3c1f2a13c0341ca961d871e92a2353d813c06396dd29b835971551cdd4d7fffce4d32facc1026b05ce3ac795d54db67983c5bf4aa269cce8470e535bb2555096769215d3df109e2e21b6ffeb6b7461481b80d4894300400851118abb4253b9b86c774522d544dc6c6c2a3c75ce8fb5c3ff2564b9a696ad05b228b8effdf6f54506e2afd2c284d3a988857e4aa22d9d90feef71eceb135f7d6e9462c7302acde68bbc9a813521293d515e8f36aa5ea94a7727837aca76c6fcab11013eb18921091002701166c586abac8f20770e6df05bc682a19c65dcbecc86bca8c85c9175d5f0fba67b33a383987e7483366793ba7b35942b3627a33c23a9172807b578b536fd0faa8c3d9f3d90b6bad5d2b582634b44f9ea81f3cde12ebcf48999d1da8651cbc89e87e0cc049c4d1efbe3eb625ef4e09c2f879ac1eb7e20ef58544332a50953643b02a73308cd481d0582b4edec16c4f31f8ad1ee6d3575ed3e318a8df9a0bf81eaf7bfc720268c1955033bd16fc652cf68ac5289488532665c4b584fcff68aa04b1d4ee55556973eff4d8713b2c3bb6dfe6614b9e6138ce9799ad65d824159e1cfc1519a741cce18ad822de048f19e01d40287494822393bd6d321b8ec3cfe0f402aabdf03743ed8343d442871a6a56821596144f9005f72f5bb36841975970caf6df22724959ff6c8b57049c88176f61bb1b08543d03a7c872b87ff2fb7a66ac64954feec8343f99dc5a84ef8c207033bb837bdeb64c5d4674014ec3ee792303ce5690f2d47d176037ba7ad21b8d4fa2b83d6bafce3cff48e12e12066be8ec16bb2127a26516afba6a87a1f7951ad2ba40b76a800e2c27aad75f883343ca988862a6dc4e481faea5a6dccc8fefcc79f4970bb831fc514cb993624cb7eab874af102ce5e06dbaf57d37cad159541791afb1a47f9c838db9168b27290633e0cef4446d8765ab5e70c7995d437d1128c0a3b0d5c6da7bb7b3e450574018687549eabb5122a89ebda3de0763497658f160fdf054042465eb25174609f26f4755a50d2df918dfec074aedfdf151645b73461d3eab7234aabe1d19ae9896029b57b44b90654666a2e8847d1aaab3b3525952eeb5f0f8cdbc8e3e54ebbf6be367d689e7140596ba674ba940baa5b9637c685f1a1228acd893478365ce039a0a67155eabc02ccfe8f7731d8ccf754cbfa512e604682bb1be083feb424114da3d7243498be28857f19468e5667f59625902b9cd228c366b684154a47acc23b03ff98dfe0c2d02502f6c5e7a5dd212722f5c06793b86d43494003e88818db45102e790ed30f20eac90be73df9b92f5064827fd43c9be4423f61c23dd661a6fd9856f41a2f65127d555e509919b17b0be2e27bb45b07e39482877651ab5e4222875a988a9f97a6dbf9cdccad27576426927153dc4310583c9bd8cf6fb5d50a2d2956986c7bfac0f552693355d8ce9c4dbf4dc5fd6523cf4d32ff62b4e8d9e281eca16ac706b3b737c0d2c977ce4cd4bb41e5e1e2cc16e63ee0c408713ce2831e68e271b52a86c2b8bd7a9d0fba9706a55a5b62ef3eb8a29c793f7a66e182ba4ea249a90ca8988c00396c2d858e3ad362076a97ebfe8d9870a339c0a12bf997b66ff5367b4591c8b0deff659c133e4f97740802a73fb1cc6bdb46b3f9cb31086efe81f62bc087786d1e984773aa976ac597537ff1b1e84991be89df4c1ec1e29a2d72c2dbc5449af5bb95090d1159d6b80e2c5936db148aecac22d39803cead75e78a05731f382b09b51b9a9b79ca9d5bb51b78e591bde312625e52b4ab6eaca92e95edde3baa07b8d12588c7bcd8c2ca4a7e6e5a776eca1168694da493e96fccfa6f68e25cd4d441a111d8de31a0914e19900b218ae50f21ae0659f8f8dbd7f301a061b80add0697f6201ffb0d8c6d42e3926dfd98897d967e928802c9ea3cc2d3c3b9e36b1a29e95fed603f46d990db7034d53159e5a5cd7a72f08e451b5d7dcbe0437a2f20ba5cb69046e218cd3a7b491d1eb47fbb22e2a3b103396bc7273c218bd0eac9f272e6d01a7ded0595b02694981cba45020c10aad67735d5772078099136786401282c850448fbf27e71c1233e5a992a47cda05c1946c6f3cc6cec3899dbd435a1d016b3c771153f44e46bf55fa7fb3c39d8fd1bc14244fb70d4a5b8823b39e449e4d5237e0d99e49e88a85813efd60296b8bdd24d27725f993850b2f66825b9c469f212d6ea131ad96a089350cb76f434e1d2054fc083571f857a36a93f0e6f5fb80ab74f9bef3c5bb7df3f47885f3d136acea283085b4080dbaa5b555faeee52948e6a5e0b0d7c202fd036108998704022d7361ec72a89ca5008f48d11814e8420b453ec202cd6ddbbdbfeaa03ebfbba50c508c5c1a81f6f4367a9f817c39613713c6ce439cca013e1b645854e10256f48ed38c50a7e4a76d01102782d433e612ece1aecc1f48ce45b1da41962c89e811e26895a4a953c38efb620d2285c05a99c27d8e02ff419924c99daad70827ba815c68b0165fd7c4b6ca77d3db1a61f8f95d2c5e93ed860f90abc418791dcd1f95f29f4a45a8bb637889c16c7bbea2ed4a87eb11d4c2d8a7ddc6a68d1f83b82f0d206ddaf76f796c21e0ba9dc3179e85dae4d7b3fa40da3c65c0d499b38362e179e8306b1361f3212b0df9001f325a747b808991969ea2a9b5c5d5def00b0f3139587d8890989ba5bfcbdde2e3e4e7eaf8fb162326354a53f0f2fb080c1c25474f5355627b868a9fa3babfca00000000000000000000000000000012273041""") ), new SigGenTestCase( TestUtils.hexDecode(""" -55FDD4E2E182AC68535720F7EE49C2C48266568EA967FEA7CD50AC62663043EA16FCBC7BECCCFD1E71594F6608124EA79CAADB039A303FD25C820B2186E801CBB5E715431F30363F908858E6927537FB74E7EF9D094790AFF50F5E88AF6139E20933274A7D4F3EEFEFBD08ECC4AB77DBCD0CCCCC17BCA0357DB699BC2424F1A99A08128B20486334062116120441525C3001E206460BA77082262A18314D63106E5AA669D12229083746129584DB30001132049CA45058046E144021982228510681C1C831A39244212162CB200CCC444A200529D23860D8288441024D44188D1B39460BB391088010091790C222491B378619384000126A5B828C24B600D1C4091C3750E39681A24031C1A28104344060C8691AB88D01150C24375260C44114274152462ED3B29124278198244920838198C250C1906D1B0788114885533890624871C01291024902D104729A26521B2012D124051B146C4C382D23465261442423C451C1388508480D14428E9B304D239330CA266A2385050192040A826819030824069061A469512845A2044841122819A9688B34664B8471A3808C844031D030460A31018B102D98A249440821018281009585D80430133288DBC04C6132820AC645CA240018384EC1048A0CC72911294940262941205202B430638090081685432689C324821A0850212149814031C8485212028404106522240810450D001830431081E4281048B850008545D188108286658C04252445044A204584863113460851260DD0260923A7911C4761103861DC226423C96492C03110B40C22B3012023648A0480A302601001509AA86050180C442270D1184DC49231DA464619438C84226293C685E2260420084E53240C5AB605CCC44110B951898628DB96216006011A4045C84448108601621461C2106904140050284AA2946123834801C64D981068118409C9C8446186445006100A26264182714138720C43091CA90851A40518418090B610CB429103B724E1800C63060022908953244D0A094962B80894208D54A46C09C09064B084002205A38689182905E12065138551214648191362989881C42428C330618C386CCC186A89A0891C246E5B489108262CD1242D6086645122855B1441DA105083006109088613868921B5480CA131A420319446408A060C480008D09029CB06255B1852C496109B442508260158B60C924229DB248504A840D4326C443080E44810C9A260DB060E91841009468C5B2249232425B4DEEA430C8E4E98CCD4D270BD4B96248155DF82B14BDADB0241D93D57742771D73368AC1C839621783F161524178734CABF900B0AFF404E4242826FF4FDA48FC5D09CF0C54110C688430DE63F1A16560D4A4F36363C00C8865616B178243B4282879D0E90576D18C4ABCFC821CCF87DD19DF99D8C341C3A7E6AD9B1D936D83EC1C2756616439D59688709FA7C6ABB3783963F1DA6A5BD3F3C391A3D50B65EAA6C1547B3C8CBD9F3D9BBF2D828E18756A35933D217682E527F68E0935BE2EA5CB8F74DBA51EB3A9BD4DE3294B962E74D76BE40ADA71B8B5D30DAFDC34490A91D1A7302097EB7C1A9B75FD018CCB0FA8FE4AA8C95261C837922A08FFCEB669D7A4C4D97F5C657080FEA40933DB7EEE691FA496D015799B72A2C6D48BFD8D43A5AC1D4035AC92860D3C58E52134179D459A9E7D34A069E99C702A7E3683AE83B6EC19C322C5D794DC1977C7F8C75C3B1477AA4553E7CCB49D17A6DC6418ABE9EBB80D1329E4471DE21D2944B4041A6DEC0B3A7C38EE411946B9FB552DEEEB4C1BA2F6279BD1DF088C3F5B24412AF02F8F28FA8BE2C5D8098C8BFE4008F53448C28420CFF19DD3B9CDE0AFFE43293EED189CFBF2CBF141EC1DF9AFB5C3678B36DFED40868C8C73D0BFA7BB6B6C6141A9226FBD5DF9D8CF485EAC66803932D2487BE19E5F48F8D34E175D0A24EEE880B4C6EAA0E093691E7A6BFC912F89AE07A4613D1A5136EDDF15A3DAB94626C36143FE16558867BD43E5EAE022011B0DFE75610CA7B6F220AEB7BA46BE1A6F1CDE340EE5C6D915AFB49223CC34D183142AB7E82A922D6669E15BA4A316B9282FB6FE5A1F310B294910B04174A955F40D82CD5517437642E91C41451051F2D063E492AF13EFB411454F90BFF85BBB8B0666233CB19C2DAD4A192AAE440344A9CA97F26D504886030BCACDFE72C87EA5785AF2BC55C54C641BFE7861ED3F5AF1F1B430B63C872FADB6C5FE4B446C4823B7AB7BCCFB20652358611DFA20466A176CEB3CE1D7336C34889A6EE4BEB96563801AE9DADAB2DA8AD03A256FF5BFCDD8BF0F65AB942678391862DF6B3EC81385DE7721B6B650C8A3B6C59CDA6B2A799383309D4176DBD7F9A91952298600349690A6FA57B02196BB2483E57907FB8C027849228B884BC33D0D0B3D49C6FFD11EE219D6379592AFF909862ABA39C0B0E4B2CE259C4C77F51E7C7833A6FAC2FF2AB30F34A54522EEB3EE52F0DD3FFC1FC3E0EB51311CA66D47C4160918BE13CE1946F27F56A0AE6B647A1AC04E1148608C4D35E60E95DD3FC887C812710920004B55027EDFD5D77396BCE2E43D696574DB561E4FF9F475609898E32650E9A18B7E22692ADEF2848E1A0B26F3990A5CE03305EB6D90228D4735F97D008AD96C019C79186B1994D8210052C432FC145D280C6F8AFA51B7D52E1F0151E266EB86CCF02144C4073FC01C32DC69234250953718CE1CAB03DD64E5AE07B3BE21BD208B5A76E2A990987AF5DF07DE6AA059DA7AD6FD1186B99223EAF0E8096EE716705D0033E8BD8172A732DB465284850B41A7C3303116AB487D03999615CF0B43AB8070364B7E0A50364947C92F48422C4EA043D33A31248D4ED643BA3314B9F42C380A1319E18BF300B3F247F334DCD78D1E917553318DCCEEC91D1CEC4A9AAA0685EAA32BE2F214F7CBEE8CD3CC60AF330187F7F688AA009D453E21FB0D1879D39C6444FBEFD02C6547BB6EF70E61F7D3F0A3337C157ABBC4CB598B8A750ECDD2DDBC1DF4CE5E1CF6F2A7657BCE25377F46CAFFB9FC0DAB2D42C590DBABD7147DBF56C619479598F62FB5DD0769AB4F915990BB524385AB946C3266C95870F199073A81B172F23F7DCA7B2A9A9B3B6EDCF5DF718340EB4C10CA61FF4FB969F736028372795EF6AF711FE9AE752231C3F9C6CC789B6DB5EF2086D91FE6A22027C83B5719DC6FC87FFB8F0113DB674F4E23B4EBC7F984136C79EF8881E0478B8EDD289237044D7FC11188C753AFE34664C680902A2066A2BF8BD48ECD2ADC23389288ACB70117EF8031D332CFEAD3ABA3B3A8C8115762AA9E8F8B46DFF5D97B6441489CD8A5F53E0FEC9A105FA7AABE36F1219469717C510F5090BAFE13506BF7E82BD30E5CAAD3D64537B047268CE62C325B89184D55B92A5788B2D09C1E7F9B7E1D5708A0C2D47FF9C79CDDB958F7AB25FADB4078B1E4C45093B8674E1E605DCAD367D2CB72D7009B9FCA95C55B91081F0A689D7CC3A7616BCEB070D49DC25AAB7F7F53C0CEE24E12F97327DD511B21DCFC004B123B2D8BE604D1F57A490D7B2A7A6E3CC3270D41DA5E2C02FC1920BCA7F1C2689D20C4F0310081E3B3D7BA8D67489E00A285561"""), +8786af4f2617911e937b31037e66d478136009c090bf4a971bc2f286aa31c252c1374f612e7f68634201e3eb5857631d0bdb0c10237831abfde8ec3a0707d79a6823ed6d5b5dd176c813b4473c92173db04935e42a920636592188cd4cbd733894485d415a6b7c095e7edb84998ed6f8ac81b9d8d7d3463d3d5c9934c1fa9484e2428a5902529bc47011258853205284080ae14412ccb60c49068c5142424a366e49305182b08c63362e0bc505e31841cc188d63b26d4a484e10306c8aa62d08256ad82030c916299b006d914052c0b66044b88493407112294042488da2048eda08841a098600265204092004c89024902c09a4284000801c173284942823362a20104690c62811c9640b064601304e21122d4906894c926822036cdb8880884282891689e0c248e4b431c02650daa0040c9211d1008020c86453160618024c10a92103466de2a448d8486a8ab66c09c584dc44224848011b07315046081800205832212082288b1092d246499208491c184aa03889a3b204120845429228011641d8b0011ba5515482614a22312126691c39004a86280ba62c40027221308484284ac818241bc41103836403086d99266210254644b669d0827108c15114952c23868824a30c233900d8442de0086482280dd1b68141b888c842641b896521988924b43010b16963209020114118828dc18670c42811e31442c0146ce340424a2670ca00456424615492250200251097001a3084121912800206521650ca180903c9250a454090160c13350200056424891152362220012d1ac110d4388ac39420232329203710d3428ec9864900078c88206118240201a1510433491c9751c42232d894281a3851534292cb2691d9325008226e6482601139069b3651c010010188804882600c089048360e198830d8008890401020c72c59c85108942d18b20ccca66d09b125d89820a136888c96098c308adb466923202d94a68c8b8061e3b6110c225101a025c116889cb865423030c0026212b0241cc68c102609e4306221a45122371060b63003156982b200e402085102329b081113346edc366811104d4b9041d900915aa42594920cc21246c8322104433160822dd1106642200644024edbb6605ca66cc220208b182a0202069b804460a0008c282dc446012046088248804b201151966059304801956461a80949a26023b52413976421468c033431e21009c024680bb34514a8090b048a93006e5a8471528004c0228499828470c8d8a0fcee58e3fef7ec257174ae39ec4d8e78a56f35e87a388ecd2a2e145f77b6a83b61d87437335cc858b8d74ba922ddefe22c434bc8c82ae545a194a19d67c7e3b857b2f2d42a70ddd90ca9503eb7da05bfea7e9dcc9f02158982bec07ca961fd8e288e07683c9ae97a5cc8ddc6e8356ab44827626a4930c683df67aa55162947ae38c88681231901927e8dc6a6f5c318fb8dafde698796c11e799cdd13e24cb6eab09209c71108f0920e5c9282f7b5d5585cf1cd70feabff9a98786ab90daeac9040bc2243737993dcb7a1338fa8baefc0bb6f9aed2511275dc008b8de75bfba4747999f032d4fb676a5b8344eb4d6ca29aab4d36fd99def5baee9a6920129e1d15d2a227352940b7d4129401c22578c2126078e85ab4ec15874047fb3ad53c9a7e9e92e30fc059d92316cc1c992bfc3171455639d6262cef30745958c3ea541df6ab9414b326b7edbabc29e0ceb6e4435c49eb07564a08cb611d30ca9603de65327ecccd20a8207fbf4c89d2914233180dcd25cd5b6325e23d591af9618ae1ec1f33908983e686456de3c6d030991ff03e1e3fd43402e723ae17c9793fd8203e041dc8ced303127161e296b73213242958552eed804e0c74b8c2d1f72043dbe02e0bb984a533647bd7b8625ee85119ad3ceec74444c87ccecf99a11ce5a382cb7b20b4c1610e9f12fc6ba5887bacb9c6e46d4fe49c86c61337c18a93da4d33a7cbdb0a609935643ec3b561a7d797261f61d085abba60874eed0f97fed77609f13d56a60edb328a8b7f3c93f270ee0e96f752713549a0dd055f07e36c1fbea98fa85be51e9cfaca9531cce28c563b67dee766383fef8c3b1fb56592f936f164fbeb09ffe4ba44da30af06a2995803f64cd90ec912507446624e13377b83046da93f373373b5f8b62249f477206f0ded335be688d9494503bada0e7bbd80cc14def6934a159030e50ca9a2d08cd6b529669a5ea6e92884dfd515f58d3e2e2969c6732a8d28a30951929c9afe0db0c41a13dd7d817514f3aaf2e8bed5b6b5d7c5cdb8587a51dd78204669979c845ba412072b925cc78c8041b7c35b9b9c2784e70329103dd53bb4b42d97fa5e4ad73363aba999152b37079f64cbfa9d4fcc48280e355b4c12df212cf806ee7e4c060c5eabbc2ea493ebaef3f3363539f2a19413b19c6c64a8fba77047b4c43531cb0510abe7c9f476c35fc8cb5a5cc1b883847f9938e8a48a913fff14ce6f4d04e1314b39acc919602a2d013a8c59fcbec8955b1ccc236eb4b03e304cc0440eb5444d91eff5f9f2fc8c08984eef85fd550b76948f2a48368a6cc84bbda74510f9132539f75abc6992a0423645cba1ccdae50d78e10a2291144c814bc056963f8cfeca4cc81adf3f2629b0b687adc55dc86ec6af5e390307b89821b6999cc62067ea0aea384cfc8be76e55d1c893e306b2f2812c6793bfe8945b7d121e3e760f4dc7fac172f5b398d066bda33ca46a35e0a24562e7516e645ac2e00be09dcfd531c39955be696ff7eaaf7192c50f3d1601dc2fe47f9ce3ef9084edbda8ea81a4fedb37eb2aa3869cd78aa1b1a3293317f748f8406fd83f26c581d5f139b9145e1538fa71bc30b8f9e3116592cff2b1ffb8288d87ae9af70330e57929dcc8982c7320cc7f48041fad10522d96851112d6bc80e71133000d125aec57bccf6bf96bcf0d08b557c67fc33a8fb627f4fdf768c83692aa8b5b6baae585b404f3863e3cbd13c1ec105c699124fc569edc3c68da55146e52ff0c0fa831003a13c50509597a361613fb6eb30d881eaa4c7371eb6ee2dac3527577b8dd404ac55ecd3c11ed984c2c62cff35b1c5833eed91c4fce2684e694ac53e7a669d560b631a898c38d40d99f112c58c3ead838ae8461d5c1cc6e3103890b3650563eeaaa1bcd0c4808809fc9814fd8364e4b81152ef67a90a2bb6932c59a2833e89f2749959e49ead34556b430855913928fa26bd6a3fe74571519a2c2352e27023ba2ce62da49dd02441218c2f7f492dd465fb496bca836af0fe47e96ab5cd04f6e3d27d61b2c3a1ca3b7a45681456c427a1f752c7b8dd540ecadf8621f125bd910fc755d349a00e64a20063ccb3d2c27d2808c86ca8d80d6edee233ea88f6a4cb1484670fa62e7fca366ec6c1bbb227f2db5a2ab9f68f541353eaadfdce5fab49dcace06203cd43db0617530c109a3c9b8885a972c7db25d489cd816e98da33f2b742333fe88a839de2e364346fb47af793b639997a0e2c6b5293c14c97964faa65656e6f624b36a7dd00afc5cecc8b9bb5a1c79525f0fbdd568c4acd72678ed26013d3d6aed9696e4272dc1293d224b83893a83184966c25a3"""), TestUtils.hexDecode(""" E742D452F392CD3CE405908EB380CB0225A4725065AFCB0C91C5E4823471376E6424AB24D57FC4265B24DEF6CA73E28FE20468B6E26BCC9267AAD2B7B82960C3FB5A01960FAE078D5A54BB324232B6647C9DAB943533C865BABBD3DC0D1E7A1756212980D75F2C8E999DE9ABD1874E3A86DFD53340B6E424DAD9F53C3CA02B44FF8DB9906D3D4352D0EC4B1A57A33FAFF7107D38637AA410B196BD1BB1FD7AE4B7414E1037454A031839AEE4C796BA98F4A739B785E3854E9EF0D5B7415C8B7ED012B0123C335730C7021CE8C94200874EFE783D7C4BF768538A448E76120635217727C81D08976CE4B5027D4BD9D9E27E4BCA4791ADF6F8DACD1BD3A03BE5CA7F68C2A2247FD3184609EB7243D2366E5EE4C95CDD869DE41A4B47F021DE76CF27464F814837C648A7A7CE2F91104322BE3CB1160A0D10CFE90ADAEBC87BBF14387C8387F4F5AA10FBD469ED5587EEF537106CE0F3AF4CABCD4476F248C21D119523B680067B332A1CA4C657B9DE1360FD23ADE58C5538EFFC8902281FC7B5C12C22CC69E7EB18E5F6F8352B9E4935D06C96BAFD834934618D9E6B1F60292352D064A0EEAE80F7B721312FC1B6C58D68A96351431A8626CC117BE9DFA33A1625BAECF12CB1DE33BEDAD584A91546DC767D0E59764FDE3FC29052CCE23ED28CA5DA4507933C0A7702D9A1225A48B71FDE5D27B12FDFF16AC2802E3629E10D5FFC2FCC6135243A9E2F3E3867BAA0C0F0C77BAEEF9DCFBC723C7A2BCEDA39B53B415BC21A397F9A8C4DC580EC512DE4EE4E0870DF1C4FBABF4906E0CFB08863AF2A89949F8E0FF9385ACA3F588E05781C49DC563EE9E0C5D6FA512932B7F5568C1E0FF1C9492ECAA5465ABFE125B511723998C4071481BF1C53DECD59B440931AAC640D9F78B1B40EE46AC0A8FD18B4C8AADD734B0F03F02CAF6A7BFE3DAF100703BDFADA7DBB50ACE3D40A05AE6E87CEDC0B08C44796D7A63E8B5BC95D97E3EF706E1684E791D3B3A2BAE1E7A92FB70A33D896219E80751A41E16B506FF266C4BCB4346578BAA7732CA745BCB01988AADBCBBCC45C9FA3A5D38F3F8E04005AE777910032D992D5EF9DF2C0422548A980707050CAD9DE56BCE60EF74EAA4465EDE96B055999F81A2C9596A2B35C8AB3CBDDE9D26AED44527DEB9A2AF3BF6A853FA51DCCD913876A43DA3E0E2C5B42571101B7B930840B0AB64419E1043CF56AA3C2FEF5B39CB582971A5776F8FA9696CD9F67E9290E483E9BD1698E961E849A513608C3F20FF678EBE0C778C2A6DC1FD3AFFF89D646A1AB85F005AA14A0635E92191CD41A6A46CC283D2FCABACD2FA07B7E2FF97D17B36E0B222D39DC1EB61BAB8146F147579D02A87DA08AB4ACCEB32AE1C8CBBB0EE0D90A642BB76DEF4AC8C7E477888159824349EB075DF0BED236DA9B2826E67EFF220AC84AC99BE6EEB0DA904887E3A84E5208AF49BB31EAA1552EC79E5BA02458106B5A31D0AC8AF392A63947911400FE78F6C94B3F8E6B7C3B98F6548E7894EA22215C87E121441C53EED726AE26394C825517EF8A477A6DF33B5315C8DEE16ACCE76ECA60835390E65392B9FC5EB88EADBF336FE361D190ECBD0B35B22A6FE6A8D48466B5E70BB6C5FA515CD8672BFE70054038C5893E514E23B16C39198B37B06B21275C2994EDF7F9F921B320B39E29444E3D621F52C9FCE19049D403AFBF1C047C8B065543BF43A25817533A33DE6C866FE9D8A73B2CF7277CA0E8D78F4F104C5CE6FE2025992E26E49D4C49F0798278216453C00C78EA7BAC2BEE71E5273FA46044B4B5578EEBC2A9E42025A8A3526B11CEFFCFF47191109C56AE105CD70A04C3F4EC43E49346203347319D8986D15B3C4A49F02C02994D8798499DAF1E0ADB81A9AC79FE8EB55ABE2BD18EBE18A9E5F35D2F66B38CAD6F6EEBD29AEE054C05D6F0B5326CC5B86BB0FC7CDA720838593238A2FB24E0CC36DB193FB7FA66573B064497F771DB1D965953477FC28989AEA2CC004640524A6DE8270E8A5B12BFF87B3F63FBB7DA25337EE34E6E4EB45DE9A39BC9B95ED37A6A404ED2970F9C79A7C2953420732C496B855F19BBBC8ABCBABE1D26D5BA828EB060D7280046AB93979E0BF90B6F1C07CA70833BEC83DB41684F1842A23417B3BBA0A33D7AF7BAEEC14C9C96FDF30BD201C05AEC6D3D2F539D511FBB356DDF333409EC16411DC7255DF0791BD67892880A4DB082684BBCA8B7E55B421C17DF3B68720E907C1620B142C3382AE6E738F8943CD214A847A6439A682D62CF0AE8961B5F020E7126C5DD6258CA0E8F5711E5472A4C05ADFA9A6B8180B741F382090CD1C781F7CC7F23E041800F42B228C351AA21E4D916BA5D9C56CF8E9507065D729B7C3653A8BB062C0463BF0B97F13A1016BE4851F5A489081A2AB3D2AC2744008BA734ED38DA10F372D97EA0C278C709A23ABD4B07E91ACF6A6F2DB9AF7806820381845FFBDC4BD30A503A0F74F37748E3624BB2AA478210072FCA83AD1A43ACE9F2943AC1AB6CEDED67938AF921FF34F2DAD4F224EF7498BC450A67CA383A9DDA333073286A22B85570A11FE03F55119794BBE8B81EDF1966BCA5E363C15E8E8673C94E3396C9AEC28D110408DA5561296E2928C6C111A4826309F119E5456675AAF935A17E80C0BD82A9CAC2627D6FAEBEC9A928D33980A86ACDB35686306B57D466864A0320F21751FB0041BA0F4F1660774A519D3ADB304438C1709711B982EA84D1B193D026081A4663AE69C5E12C3E4A683FB356DCA618191B29290C5DB4AA6A069C3B8D61C8B7FDA779E1F34A5F62EB7DF5C563ECF1200D3FF499DD06C2BF44A2B4254318BC402EA3A047FDB3570EB40630CF1DF84D1E2BDF5449A1F65A9DEF76954B5814691C4C12BEB10A1C006189968F37A4B236D9EE0D39AC340852EC54AA64FE15E1A4433ED48153D23B2B648C8852F3E3AE485474AB2DFD58A7F0CE6691ED36818DEADC8973E6ED06AB841B0A915425D7B87E41E1E68B00BE2EB725C287FE575736F6E1AD2AAC61F02A3A00ABEB2C0FCDB35564E8446C776E980636D5D61740AB2F0736A021D82C1D66864E5DFA98C4648CFBD9C7AA865F6C97038656C9C8767898FB43B0919BC98C1D0F6FA4D90F711E5D009D4C8FD8A773B7C73CEA654A2CD52A276C6CB62265294869A052FA1634D3EDEBA1F69DA09F0568F9D2F6C511F6BD6169BA0DE25F09FFF63AED2FDD0F6D89BD01FC5B088D3EE5344FCCC0215B6436987D6167A0F2D5EA47A984DC86D45534BAF35129488F3BC2D05BFFB84A51A87A1774033244277D0F2B45EA43500F4034081711CAD67BAA9CB0A58E1D01013032EDD5EBC7095D4BCCBD28A5F32BEB685F7901BA7A839650023B0C908FF33B37D038162FB96EBA35C2919560267EE5A94035825938D168481D8E59813E20DD611E4E23D8D42C9DE1D2398CE3CCB3DE5CBC4BB16D555985F411EB5B56508C6F4E75621304DBA2F4F1A2D8B2BEC5793478E5AA0DAE6F52C43253FE7BC91D3FBA84F8525D002CC307CAFA20BF198BD8F28CB579960A1168A1D26340C8E26CEF1261F23E97B806E9F27BB51F16102527721BE0E8B930A1ACC38F0A63EA1F3FBCEA1031E441FEF4D3746EAA37B7D4F8AB354D5F079E56FF4446333C8B8B7B589CB36DF40EBC5A75D2237F3FB874E7E0FF1B96DE43BCF229DE1FED3FB6D01752B3271E1F98D4134114911BFAC8351E3186E90DA3DE2E7FBBD305C822FE6F06ED1D4774D7A66DCA0CBF740DC277C62FA641ECAFBCBE359A28FEC48D62E1D3B6215392C0F8DB601E35A6CBD978567E806168A9F5B4915A80DE405038C4A370D898ED6441F727985037A040163F14DA78378931D3B96BA486958AE8902C98BE75BD0AED53CFB609923C63615917EF0BC6D07CD183192DE3854133F701B9D4B499F958064ADAABF4080C4A019DF1E5B98C8CA265E031B8CEC355C8FFC3BE16DC3D01533ED17C9769365D023CE7F0384D40F7B6179612B5EC382982E244E2510B4831F2D53F26B142A33877961EF1F845370CE115CA5F0D2FD6926482BF3BA1AEF3212DDF36705A210D8076A4428C7F9CAC411DE590452C761028469947BEC31ADCBA229D8EA58755F2715AF6D51E581D2CAC4182557E6815BFBB84BDC54C9368764CC29AA9AB49EEC37364F85AEB3295E60CE6DB2639669F55CC49D7934BC8566AB5E207B33F29128868BCBC1DBDE1089317088EA3FE1D595376DAD3BDD156802F82B63CF4C5ADEF9A89D94493BA152F9F07A9E9CBF8D821F1D6CD602EC49B61AC4F7633EC810F3D01D4867B1F0F3021D70897593303CFA6B5A3BD0303AEC32105F854C3DBED373760DDEC9B9E8EC4AFDAD00FF2E5A05A0113522024B86F1AEE6F250AE3BF0AF1E6FB7DFA8E04E3F9D5C876731D9C33460FDC13CDCDD433B45A6BF17E98638C264DEDAC262BB03714E020F4576DCA85DFEEBD6D70E557DF9321A8AAC519C419CA20E33DA37C22047D4CF925AD67545D04300A42B22DAC098A912848302D830E06CE5BACCACEB6E9316F9B1DEEE271BC6AD9D74927CAE725CCAD0C596653731869E8071E23BF"""), TestUtils.hexDecode(""" -39F0B36E2780F8D81EE231CF85B28930B0876F344B4EA32F8CEF086931EE1E6B9382AA19FB650AC81A2BFF86453BEFB33BF8F0FD8E0FDA5737D7C56E4D9427BD1E802930F500594396F98A2C574073FD570D30666F5C067EAA3C88610A52FB0F6826CD12BCE739EB685B3800B3B4E3833DD2886CBF4587CF0704B2E72B128E43183F5A5613E8A5342C123AA38FEDD3AAC513432A96AEAA598AB9DA0789B440A4F4AE37EC090144670E8E876D83A39E0569A1F38159B8128317216ABAE8C5988A396F2964B6BAC4521E1E35B4C1BE3A4AD1745F718A1C74B260F462567146394C5190A3B6F724BE2804C3E8BB3FE3587B09F22F3227A2E69B651F52A32F62693E212B502A5F7917D17BEBF20BB261D554C966418273C6BDFC51C8947BE2704116BFB1D1657D5D82E676DDE05A580F048F7E111A3D632205FA52911721CB22F937E6241E1248F1A6E10A71C34932DB75A4878BEDF3EA3E6EF5508E5CD691114192DD4C44E6620EABF1DEE4D09448680D84C6117773D240DDACE06A2D925920F61A0AF12B6E64DB0FEEB2274EA1238E22BE017579792F2EF95BB55F6A23D18CCE1D3AD209B6463370CFF1F8278E779A9A943B5779A99C971F8A3794CDB3B04773C9875D82D9B72C39368B1FD4FB0A661BCD31821ABDCF4CAFEE9FD959285FF15B9FF8211619638EF4EFA138E44E4EA9F1FADB550C13EAEE9828A34BA911D4027F38FC0B9D0A1E788A6B8648C63A9E4D6AF974F87170333BF82233C199598D7A7CA1F90816CFC72621DC36FE881F25BB86C67B9B59DBB02D78A1ED003193ABB5470A89C8F958FAD2D6491ED121AB9A02EF470099D42FA37174052E231D4D988707567F319D964B4F0551EAC4CAB4EE069EB8FAD6BBC4A9F1D98DD8BD73A5647F64D4535E8FAE71B53902C917A9D286E014474E4B126AB17C29DE31ABBD58CEB1C12669FC2EE50042CF30BA29F08E97FBEBB6059A458A90EA6613C7F76A5AAA9DDA66D266CE0514B0B0442694252AEA4ECEA14CF5C90A8BB60FDC56F865447BF29769F49E79751E8AEDA70CD78E29154D688558D1F831096C660FAEF3EB1850DA01F2E929A6432CFE9DBD342D1CC234551D6301B6B61819CC487EACDDEA62C2CB8766E2C7066698305CA924419C8E83CB1D68527E923700EF7C5A05DDB511DF15AF11F5BCBA557C815B95001E0F57E6A7B8798133ED1AAC2819B10A8E2E4BA69606BB148881A2C23D3EE0E981551E02EB1ECE320B6BC15AD1EB0EB2FF3FEAE63DB0AB4C2F315E54F047734833CD380DCA1ED68FF1838B09495083457B07D93B8607217913D678D409C1ADCA9C7F496FCDCE029F2F4D254CDFFBA036CEB59D15BB40B4215397DA55B5480EC2DCAA221D4CED195DC440BD0B84EE2BA5108F46B7E24148EFAA6C2AA728F6CFF1391B46C36DE741C7C546A0EC22776B9830C3165D2ADA141F97C05D03D93557BDB24012C336CDACCF8CA3630064460C12251ABC89AAD06478610B8A2BAE5380E65A2C449632EF9A79CD9AD8857BECA18552DB913C0C79CAAC8AB166A1ADD7DE272A796E72EA53E23582DD8A00F554849B9EB9D77390CA41B04F6A0C9BE3C3D0E94F9E3DC39BF1AAEE34E910204DE1A2B3A92557A67089B912B676F93884D4A6411B89740953E1F79ACE3407B2252DFDDBAB75276C10EDD534A9F398E51CE9E36469C1DF0526ECDB84B07308A0D5D5C520D028A8E30A193DF746F0402D160A4E9515CEBA20655979124B1D6F5EAD8892D9F1F92A0E1A1DB0B4BB90892F569194E088E98C0C5FB93A108F05507B29A595CDA161BF4D97680D6B0D4428D6A74B016509CED3B635B02183222B79598B6342A20DF2269E881C7B121889C0751462D76C5ADB628D26359D56F8876CF14A71D330D03361F63E90C85CBB275AA78C15293EDA0356E9DE2474ECE7C49419E15ECC5EB8233DC8377D88316AE846BD464D292B91FA8B3319A28EEF4D678F0DBC04687C7C59CD98B694BB15DB7E18F4599D4F2806D0D78E80984C4136EF605FBC268221E7608ACD24004CAD8F533DC1BDE1D3CBE0605A69E828AA13210A07001D60B8EE2DF19D5AB8D792F3899C39C9AA1B82F1FDF9222264F7C3EC8B756DEF951F20D1622B23CAE013DE6CC95B0F39721FD46A64B7134A602E0D9B6B19299A5521148AB61ACBB878686C2020663EDF3652CDB93CF4E24C8FD2AF8D0167573333A7DAFA1CDE08C253D523AF9F944680B97BD7BE2196870A754894334A029A870F8FB342E53BD3F080657A4C5A2DB603C9F0F3BB341AE936A2B9356A73DA67AB54AFAE131C8FB0CB73EA10832D2094D014C01107FDC06177FC3884E7F788384E8AC89C689B2A2BCE8D6852C8B5BE520671DBD8447E4D78049E1EE50663A609DA79725A3822DC899CC87224C115D129702C7573B45ED58188D422C510381BA3C77DB099B87C028C895DDC6F60C148CB1CBC60CF56C15455048AEC096CE78B0E70F8C8F1694CEB365DB8FDA1F01897247E632B30FEA0F888EB49D5487482B367ECB413856E8630841F811BB1AF14CD26DF29DFE7238AFF1D169804445A74BA5F9F96D9EED27BA70AA516C1BE7DC46C015704E1BFB42F0CC44456CAD7FFE48B62BB8BBFFE5C97027BDDBA1E83C027DEBE20A908486A351F077E627464F6BBEA0AFE9230FACED923DD9DF215AF123D8089B467FBDEF42C4174156687ECE49D87C0F9711592D2469BA2100A5286B086C2FBF47A60B864FC9628CD1977D7D8D72B411D2494BFDBB77543DF4B39664F7B22451B8C7244008A3D24DEEED0C9CA67DAD2D56F1987313B4AD33A72CB4973B6125257BE3295682A3D0418A2251D71510F858F65840149C8335BD999C55E51181914DAF055DA97746FA5A80A7019D9424EF0087F38EF1491A3861A19C87452E05BCDAA61CF148A84507B043AE4A42FBAE9359842B0CFE70FC17DA78A754E3D7A768469C170DE3AAD692101422C00C0F8315BEF3BBDF887E75E5DF7101317CA4F8C4D365B56A63A1D833B5D79BBA1812F3659C377BF9CB4A913CFA504E0CFDD1FEA0B87BABC132F81E9A2C7FE0C6E6D8467BE84EC5E21E0A46E4759A5267E6EEE4266A4EA8718F8D40A1594CADC835306F88E2100AC444379E9EFA4B3FA0E690550CAC00EE4633687DD1FFA748DA3882ACC6CBBB2EFDC0513A25B31361DDBECF5ACB3C488AAB788E63A48D556ADD74B607CDB8DE11C7448DED000E8665EB75BE788AAB14C3E958CC969FE353C0137924941951BEE553FA392DDD5D7FBFB8A2A8DB5FB0EE58D08FB5ADF617EAC526044962C599523981AC06B60E1A6A34ED97B80949DABB6C9D6D8F1F4FB11222632456068798995B5B9E4E9F1F4F8FF10161D2B5D636E9395A1B2D0EBFB1419202A2B383A424B578592A0B4C2CCCFE9EBEE000000000000000000000000000000000C1E2C40""") +a99a8d52ee69a69d91581ac798a7b34cc594801ad2f15e8769de6761048ad79b7dfebfc6f97cb7694d14fc315c879de9029b2b5331f64ae72e36833d3e5bf3c4ab64b8ad225d7b17a146f4d15f05ff72a7ce975e6558d11e3dd0e24c5b8d81ecbf96c732ddc2af021f62ff48719eb70ecef5e65a3acd389afe3ebf1fd6bc218dacffe07c78ed1ea343b603e61d5af9f6399153572549b29f88139d08ac0899ef084a847ec0fa58d0ee3856dff6262fb2355873cfa1426eb3f80ab52d3f6cfac2bae2a1abb12a68e6476f7593f5e5694d541d7d09b02a39832450c80eb785fd1cc13b441a96f22910a886aaf3ff61df7ff9f079cebeeeee218495f5307da9ce916bd86698560f758896675af604a3bfc2721e8e3dd4bd6664950d7e8575a09d439ff54086efa2405dd362f03c6df688120573884b46e45970e65934b5baa1255d6344fb115ffb51aa25b1bcdee1020e754bcce521ef28bf26d7bdfa498a5a182ec8d202d7dd0c0926b71c12eb74ab4b541c822f399bb4f4a50411ff28784930e8c9a6e77afa420a958528d4848f6255067d19496a23b39b21b572158178fe1e4749b3292133ecedc0db2038fe2eac7ad1fe02f426af8391988e46bdc8b621e2c17704360decaf8d6ed08ca825b1b3b8ff95024f174949c7a6f9d8a4a079f2fab1fa0132c01f09b7f7abe7d6aadf9c53d58a97d270a1f9065b295b5c524f3bfa0de09ae02ea5b98ce4403418af601e5cc876b4f0c95ecb7c1b8bb2f72448f721d81c13cefb99106251d4f37e47dc57d9449b405a132d25a2f08ddd8dc77f0eb905d6f6eb0d0cce96b95068d669286c02f1cefdade77b3dbadfa7cb912c62279d0a4530cc5c52941b19de495e2a2a3713537b584b2f7b76e3952ead9ca20b7bc9bf26bd36176521f4347cc8b3c2553d37ee02066258dadf33306a2743917287c09ab07cef7bc4435d582e3cc2fe79c272d719f133e6e5ff1341cfc139257d5a7eb146327c03e897b9668567b6cd9fcb74711e73df074ee139a57229879b903e55a04c5c9fe9b6cf669998444b93963f85ac7176a3f021d7c9409d7ee827de8a11cdc431521c96ed22fa6f13759eb03687d997a25a9bd60800f3f534b3e9c9dba97206b7c2f326b34a087be1798866d1914e59c8eb2c77414be030f8dc270c6ab76a6e1515fc70ce50c497364fc55f0ee4f49d3d22a08c6b9348042d904ec2f8862ccf5ee0b3d22d2f1a99579d35a916748ef608406883c53f18ef4caeddcd780e4a44c872bf2dca063aa11cc715e23cd996e4e3874463a1b4711bbcdc2418e4df10667930cbc7af5ed9b629ed452c240e02b58ef61ee4f1429a6d9aa57471781887f2e1890e70f7589f8d8b4e5ad223ba9d0f73d3ec74d8249b82596c8ec733881fdd0c96d2455ff5e340298a5a6fc91cbbc1ea5a8a3908f6da6ccbec88756874de1518602557d2df30505dbdd6d59469a6f2bfd240aeab1099c350d6730892585c577936181bc9f7fa6ef3dbb0c1d39a082b1a35a86899cf26261927d52b373120225752792f02cd2f196b5540121c3f9c0fab27b44b9462f6396195e21f2e1f736095554de7221f3c9ba23b72b480852c86b179c0e4778441c3c5242d4feb9851165dad83804c7ce5d534dcf918d27ab36ea1faa48149307b95cc3bf51a6bca256f115e3c618b9787a21941b58ce52abe359eb1a5a19aaf67dd56950a6d0179637ed0ea5421b899325ba05a26771b9449ba0de0b3e674d62398e30363d1d885f424dbbc200af85c87d28ae8a3054d82d4be0196188089d180acc7197f07033cca984e20732e9029e832268ea405cadb00dd002e3506e621d3fa7b023454329abe1a48f7dc35730f5f352c25694eb2a0650f9505866d9013e8b88b19b0c5dc12ce799ce8de35caa4b6552f399f8a7b06bf1e5bea54092b504d9ce81fc3fa2a40dd9ba5a2b8711d02dc46ecc222b14655b151499f4b537260b6595a89703ff56ff4c976a4592dd53d12b6fa9a4a775acba17a1b3dcc5ec0a4e03db9c9402ef6380e62d7f76aacd613a482d31cc17a7ae99311a01916a3abffc336959a491995183f531ca9ed0af40131a28da068038649639155bd12b9d3a06238cd3c4b754905b56dcd52cd213a2ea369623f32ac7877e6150d0f5ee25de926829beda4ef67cd3c4323042aaf3deecaa4d404426f234fca778826dd3f29b007d369ff1a0af66ccbbcf20d9f33565b7ed745c160cbc5242c683588a67223d81409d77611cdce68a0478bc50422da24632852862319f20b446917557588d19d8add012137959e6791aa7ae19597a8a2f875bb8b78b17d6f5d5b10c1996414ffa08e698c7789343487a62a98474a39cac820ecb1a855dc825d1d7bb9c302f9945b4ef5ecf2e85d22fdb7f440018181ce3c71fd8a6493c7e0ac2d38ae115a018a3583eb45abb5542e66cf77587ae2e1da41ef8b98b2c2616f6b62d3e2c7e467955b0ab3431d1f5ab617adf90334d87b2c01e450c5750347c1c98fd4fd4109f13482e11e2a6ebc4a362d26c6ac9e4d112d18c1e90726a2042ea3d5543c33d32ac108dcc34999db8488895315f18fc0d359714eb6c10b0dd405f6baf03c0c7a3b89d6ec2593c317e359488ab2a1e85a722b2ccfeafcdca2e22718a17363634036af5aadae7bbe6f48ea36ae216b827aee084696c7094dfb6e4fa563b51cb1fe41f8e72db7cd527c363bb00bf8d22896f438ba637bb7fe64054d69b628254a4cdce5ad92f753cee7889c460af2fc4cb10ff6458bca2547193ee76e816a39880f48fd2e246b66efb3056cffc0d233a86307e13e7fe87e4b4c8408cf7bdcea51d189dda4c4cb4fa44b222e4d0ed51a18abf77b49fa0280dea06852e864431c1b4473e876e2fe4f00d423aaffac81b95f186467e409583252662a0761a63ac3511058b4b0028d0ad1b760994c98fd7ae64bbbcf8e615e416bf0c1a594c0fdc46f760d5dc394497cecbdbf06d7db93d2a711756a3534f7550dafa01954f291bbbb511b652b032eb00b804d654698127e2ef480c53f47efb10c949f50168b1d888c62c9bbc422dcd07ea4005d751dc31d374357c10af8991adba9e139e75e3367bd18c7e1ac9753b2241960999e6a0ab795c475f5a330baba955dd34fdeadc193d9a6ea7015b44a04d0d5fea544c140c2a419c86f89ea54e4cc2ed8830938b171514a189e5517949c94ab77a5e9521a38560f3bc4e389c7fcb0b49da3f037ad53f75a85c0fff2c43945bb3d3ad65a197c6db5fa9fe3c78293a2a499ab553af3756ddcca3892133c1ee40a7b73bd19262b33364c575e7492a5b0bcbfcacdcfe4e9ec0e264b4d52576c727d9a9da3a7d0d4e3fbff2137789499a3a5b6bac5d4d7dee0fe0317192e4144484d60626f767a7d8c99aab4bee60000000000000014263549""") ), new SigGenTestCase( TestUtils.hexDecode(""" -382FE71D7DCA3DA9138076E84FD5601E999042CBEF87ED4A8B5200087B61564E433A8E49F18104C7A7158AB1D83044AAA46F6511B361326218771C3F99094F9624AD27D16068D01BC7BBCD0B5448338C2A81FB3F83B2799A81EE2610C5534CFAF09100FEB0913F2DE35DD5C21DE040A2E8B6FD99848AF401BE6EAC45DCDAB38AE1442E88B24C2233621A187061C4606390801B272A133450042331A4300994204D11464404242051C48DA14649DB4428C0084C84304DCB8244CCA84C13B39018150DE3C04122160400A6252384511A28221B136E2049715A04222112724B4889993210E3A42C02147004B06920110918352EC8B681614400E320324124321CB47083C60D0B970451B8101A3268E2A84951C06C20926824B448C9902922122101252C13B70099B02519A6410AA049149069089751C8006A1A233142168A620428D3C6900BA544A234251484605C48324B384E19296661286450A409DA162A9C10100306019088410A0006C9283020A44808C04920B78DE2886809A64C1A030ADA180DC1088962384D61842C91180D61A649033672C2A24DC2B02449260540006948226512C50C08C36D54224D244368418230D3402114285050366C4A446D989604CA90605A162ED2422241129048827013A2815C8025DC12264396499292281A042D8C800100262C93025192A288C2B29183080E12382262406D14436923112E521480A4187280304961863182224C92486C60B84808C30104280152084A1041520939664A328A99960C14430E1AB46C44C00801C60C128024A390104C0046048069E2C260D2360EC9C82963962D53C870203311021568E3222453466C410891E0883008266E5B386510A991A1B88454888152444118A81093004581122C10224E1BC909C04406A4A00414C401DC0286CBC645CBB889800885244945100871990804CB382512359244067011406550483240A009E0C20020244D82A20C81360514460E21C1494A442D9B343120C85004256502B59084B445542489C4A224122225643862D8B02584A005024828E1C625E03462E19221E03452DAC2219B38311C113293C80D612466C4024DC8026E240582630248D1140A51342960A82C2093891B496C519010E102654CB0251C096C4B18860B35421829658028696080296012250A417081222990A00950C041C0884448804D1A182820A82C22806D099501088670C9120803272DDB208C1BC92C62128ED98681CB067010C7498B386D9C8005F34E25F7A1DA3F630CCC7317F25ECDDF9ED98A9E07707DED49B04D35168D0ACD1EC48A4A92EE0A9B2AB5B84F7F3FD38F399E54FE65FE2EA64CDB121AEEB6EBA1C0D52580543B76E82C799F8ECDCEA58DEE9CF8E24C1B08C271B805BB729C7060608B6564F93CF8DFA6FDAB6F7B6F483E81C9F35E07C061F88585B86F7DD9E62CB027AA2DAE58ACB5C095B23661FABE88C717A46223395B94A972E3CCA2FD131EF052F7C8C75EA9B93784893E354BE0E4DB252C36AD03285A7FCB33A3D53269D20EEE2C3E6C0D74C91A2F1B35510AB2E7C4D12F0C564FE96090081A76B9163DFF22815EEC4B7AF398DCAF4AC6A39D31EB3C4674F7D007D6C04C95AC37C4E62182B0448CF3D10CC25823463A9808F97640E378BDB17EC0A2972F5F70812625EABBF6F1F93B566E36D2CB3FCFDDF94B3DEFC1AB168DAC4371398DE157EFA4B1998D2E19B4E9536038DECFB279770CF87FEB7C0904DDDFCBEC1721AC33D837AC7689676033D6D556DC70CDFCE1940CE25D69A961C6BCFB4E16CF42636B5DCE6C0F736DB467C39D0E4BBD0577F3535E7A47D3A80010A5A96CCDBA9C89CDF7894C43B19EEEE86D7B248E6FE89F84D73F76DDEBEDF18BF3AB9F5D0E69BDFB35AC1AEFD64E64488711C95D132029440D3573F1DE86EA10B9CB85241735112D992319FE5C28EFD072D2808BEBB97A75607F2BD0D62CA3223819F2FF26F047A5E1283C39317C1244CB95CA3C91C752DA2B1B36D185FF6B6FA6E779860DF82DF8450A2B131459E5C437B0FC44E49A9C613F8CCFFA188850E520E166F73BE0F978C8E770E88312F8DEB9FC4F93962AE579B2371484A6A7E09C68DAF0E00DE46749AB332791745294C3AD193FBC533E56A723D230BA35DCD4308728014FA998C4036066238B50D5A4381A1E46BB6CC2EB3C4AE4A43BA3712462D7A842598A1E5A7076320194C57BADC732197DF4A8A1E9455201AF865FCCAA674E2B427F7B3D35F9E66D1FB56CC690D61C7EAB983D3F31EE3066D0CAF61455B185902DB44CD2A85D6BA2D4B97DB516AE75CAFC855829E24160ABA921528CE718E10023D84EDAB83D42CA84E4E3B078218C44BFBA356F1815F927D61F2EF8C46C4B5521D0F8971D54E81BEE1FBE150F3B303D8668C9328B61D68ADF26AE20B4A38C4A0DD62A5B432ED1A3DB945003FFFD37870B5A514FED603B5EC54668FFD29D6DCB5A593DE0852CBBE4376B161BD7FCD8CCB8F60D453B68510E5705549E25149A1271A8093F6084759F47AA3B5D32ADAE32173B7B0DB4DEFF645D172BB02F5D2BB776906E1118167F3DCF7CB8C0AE2866344A59A9F6C3687CA3ECF74884E632CD63B6AA193DC56E087A67782B69699525C53A35DAB992F9BAB1CB098723BA2F1027E72BD20076AECCCA2BCEF8EE76ACD195380A34B934B44E642BAE00DA4C1ABF7174CF0C0A353F96F27CCC2B6281B7CBB29222E9F7067646F0D915AF86F90ECB3E9AF2B1D7FA2A233A5EC015C6268981942E0DB8E1F3667DBCE020907148E61B353D505A3077626E56B8FB108D90A5922E5259387CDCC49D03D1D47E3CEBE87A752C7562C219C25F502A8716722EF7CC7B4AF8C33DB33EFCF2B31A076DEB28A410B8162A9D3F1042E1AFCD5A9DA472393CEE28810C853DCD94F5590F2F5D9888ACDDF1FC78DC26221CFEB3EBA97D0AC4B2B2CABE0BA52E6D7BC29738837B7DFE5A2236AE31CF61A449186080519DE388F1211F6BC81663D2AC7A4BFAE83E9E64BE6EA7DAFCFA7C1DEEF73DC6F9F9714626B9F67F292DA66D19B6A5CB4DEF0E870AD09CADEE4DF12C873722521D191EDAB644CE9EF6AD93CBC951B8AE64F741B6497645E92A916605137CF73C5E30CCBAE5DBDECAF908C16543310C592529819C926885DD3C8DE66480FAF7DB079BAFB47BB99341EB9091AB9E9A0CA721A8144882154C3D4DF29427042F41810DF2BB8D59C5FCE38468AA8328A740068843F7E2C911990C9B2CC9C8E3597F03502ED2813587980918E69D4C482F040A8B7A09733BAB73E581E7DE74899A5EC59369EC1C112EEE0073E1320B189058ECF06DA8E1B74A7F4FAB3C77E2CB93066DA683BF9C6DBDF4E673F11F446DB7AADDCABCCB6AD68BFE43F5AB8EAA5F8C737AB144E33ADA994E5F38E1184A4CF2EF21734DB0CE019F114D02316703CC86BC12550C1CFB863C1249D9624591ABC9661DA47E2972231378F57D27F5C1A6B0ED2303DBCF69A8E98C6317929C6B092E1C0973AE4DEC65C3F3B59EBF6AFAA60C5121500EE6B4027480BBDFABBAD8FBA8ACF4A23AFDF667EF95B6B60DCA6A39C688BADB1DE6F3795DB7D4D31E882D001087E81A0B7846C7D0B383D6E85DD516E37409"""), +194345a0607b1df8fd01f58d30010604261e15d712806f9fb99d3dd6afc994a9dbdb0934a7bee40434598e9fad7e0c7914ed8f127b35ffc7d25d5431d9b6f7d85c5015968ebf6bd70ee835d8da55ad1b9a9147db756e7ac35cc3fefbb3a83586e27cd96dc334a6ddad65f8e4c907bf243d46949290f68bd7ca9a3979131629b66028008c9850a33229e3b841a03244c8a20d4b183251a8209084115c1608cc9611d916095cc6040aa76c14b54822054113a2510c178492b82cdb12408a082d141481114300089090c482418a322258104d4036260c0446c9488c40903199488989286e59c48c1c464608b7010b234d99286c9246010c2765d48860e2a091dbb01002067108348e03466803c52904c84101224553089118022ec90665e2006111021108258d63102482c009920652d324820b361198b40418b7851b184ac2083192426c24448819926821286c59b22c03033184b00091b6059102086000060c3491d1324e18c4094c923009456261b07061102818328200a92de08869cb12848b944c04190840048cd1087054306019197108810848c6841aa94952c0010c442151a0602009516088312243059c0486431629d2064e494420d4484523b64823288d9a367214a39088b04101a4095bc46413276ed8c465103450448010db908d5912480ba54824a18cc0366dc48690d3c48cccc82c1ac62c09c684c80489621451e1044e022704e2124514916c893288e0c480899249e2204408966c4c402da1884dd1145040140409b25024a805043752202369e02225c1464000178da2b291a41646201832d2066a21942484006a43c00420c349d48011132168a2380d4a4848e2c889d1a065c40849083909802480d0a269a39625092204c13805803844090471c0920c24300ad8126623a5310008501b814819446c13b61110a80cc0b871123885819671089669cba46c0c8525489211e096090a2640481644240322d0c851d81452c3128a9aa0611a414d11334a9424520c062e81141263984810417298460d0ba64c98b81024a76d5040320b427083b8044c88050349116382214ca2014a2445e3922020c76d22238a59b849cb0250100946a2484e624490c920228134018c088224b78c03a20524862404178a1101464046880b460e8b8640a3b6514b240d24443104082d22a265da98645240059c824ca21640ca266843006d41c6519046449b82405b226020155048044c59a41163888944826c5bb40124914c23366cf182345ebc795b4629109448f210245d70b278c08f9ba6a8fe4367262321945042fd365c70fd042e81b3c244cd92fee3289626e175cd20642852cfdc1e72a16d4537f85c1dbc25d69bb8dad510dc259e5d7ba1575ac940431a237806900b8fbedf88594c69ea597d4b3dec2328796b644604e63855770dec3d439ede08c27e01950b3bdead4a0b546bd0e6bd2b6b62f10335f9356dfed825fad33fe0a81c0dffef21effa8960cf65c22282ab77d66a351e4e1c56a4318abdfc6e20229b14a0d3e8de682c50e9f26c9bab44ec000a8d78dbf63d5bbada80089e6c3a300eca7949f554511f647060e23bbdbe9cf77d68ed3cdac0ea0b491768eafd65ba35cc29194a1e0349fa2ab09c920c2cb87199cce638a15010f3b235e7f46357b5ca7372b6e1cc172ff2df92179062b47f78a977040418fb79a4dd9a48dfd7024727376e254a64822002e7060d297a9d081ca39f148e1c472cec5c34c39e84526dfe3ef6153d21720266de887bab12a0f37fd0a79f8402e1fe9f2c149789b25057cad2d4073bb54d56982ec23c541cd3e6f7727ecac5d075344402ec3400401be314b4b4428f0d7d619bb2b8c3d0b35ee824ff079a3431acbb8b644dd841c92cfa8610aa302da74f2f8c91ec5b91a3b19c10a5d3bbd92b5dd1112630cbc606e0ba22db2b71f6b3f24aa171ab2efa4de7151e1fc879fbcb5828f232083d055507930e7bfd54f34aecaadf28a4d0a3220abd4a7c03b32e635223f963337ff7f048d7465116fd149bb0d1ecd112f32f38de619b50544593e1b23f661a56f6abec97211194f03c03697c4b5a8ca1ae309629a6737347f23307aee2886ee24b46f8ed8d0f44680a0e9d2af553cd154a2c2812a8132da51773d20c7128057c5db127b271a2453d7e5bb72ed1012dc88f37687da5e721b6848cecda1984df797100dc57a7ddb8d751b9e16c3755f85ad8adada51b3f13a08c93701214cc26b33b5e763f9bf8c3e793cf224f03df1aaa58e95333015904f2da7526482856560022bbea43626953a375dbf8d0fd6aecd506d6e9e6fed3ea6cd2313f57be0c0939a82b95e9151f9453029bd4223dfc55f8f609ed52d78d114373d6a0ae370f5a28e0ed6d29dce7f2b7f00a02eeb31b76ab98c432873705a43ed9194f5ed014874b019116b63c9408673cc4812594b682098c42c69b70e2e7b29c2ce0fde2a19190bc5a36de97c3d6ffa1bca253f2344ac9c0373f0604b0d08377469f38e7ffe86bdc130838452a1f790efde6f8aff903c837b0416507dc69c61d39c2009f4913c0750f4b3c16efdadbf755401c455d9e4d3169323414251e6c80257d75870e4e274a2e7b042ff8b6b80270b27d999669002e811308211cd7c74f566080f3cf591656810fe1ce9ca2af33825c9526531c34ea29f13327990e42b45595153ecff4489c1c25b6b5a565432ccdb880534189485903b4b3c05504e8b8ae71eacd12c57cedd28d0116254c725d79529d17451ec12e05d1e468effe2641f5d7268c9ab0db2663505d65ec2c02959937c95d3a531a2fa91f99bbf527c4effb4607f140fe0a0b33cad4fedd87e5702eef7933eb05bbd42c853f022144ed5886ff31ff633f8a5f8f88ab32c925deeb8d12e72de7e92c5db2c4a7b32fde5a7a5a381a631ac547aa3287183371f6d81ebf5432cfb0d93ea3e8fa981bdeba4f5e81d60ac6ece3d26ab9a12b311b21685bbb9917acef5d43c9e4dee2e98811d6866f008b159ca3e43e849d9097d8c74d1ee28b8c6700fe5c2175cdd004f9a4e6b7f25fcb61f562f38b0b3a82693052f023ddaf9c88950a379a0651b23791722f4600d6bafe33b364a0c66495d9f360cc66b80df56eff38261835ebaaf3ec8ef799b54030c9abbc0ad6ba83a366533683a9db29170e074eee296efaa38fe782064a0aec2bef0be52c780c16981bc8c6bcf748c109349e7e659ad14e6c8ce6d35ac6f1cbaa938b39e869444aa08643134e5871d2676d11d205441406e378c26dd1afbb2fea274c5b718d4ac16c077d6e15bc0dad0b3d9dc81e2a1c9089130eaf417bc50fe35e8724bc420ffa1f761f6cd83bdb0bfaa6d0f399026c6146ae4d5d580f4cf490a464461a430d8f40c60f4aab01fab0e35ce12b0337253c54ff1db1f11165b315565be66ce094fc289e6d4b72189d4551df40c6c86878185db87cefdedaf24be22922046674805df74111c3cfb89351e92c01d207253841afced4c5daff0df1864d8e22bcf81c17565f2226d3ae2cd929c234f376205a6962e024ff08a3f00bc71a3d39d67fb67cb94e9f3d7ef78a5d8a7b86585eb8999af3b054d5523b9e4a4d944c7d195d41c286eb95197808"""), TestUtils.hexDecode(""" 7EBAAFA6D04129716131907EAD0832AD490D09E97D865B4AFC5D6B0FFF4EDE6A52E961ED88DB60A325AFF2675DFCD6A87984884AFB8680DFA7378130E44F205398ED7B83B1AC32D2580570FD6603827E8E4F5E20A27758CE6D1299BAADB8A895AD586BDF7B64F8D7A52BC15455EEF240F22FE98CE4CEAC03CDF7E8A983D7FD1A59C5EC594474AE77DC43EE4E7B25C556BC1D91ABD2015B99B1AF5329DCD41B93793D791A44AF5D83DABB8E40675EB32120C57D9E6B7757D3E03008A2F788336B8355AD2E47E61B39BBFC2229D53BC9BA514BB20F3F9EE9266BC0015FE81980FDE5637B3018046DD3D4BC3D549EC394E190F1BB788619CFFF86C532B4B9F0F6F951C0ED691C59AB0CC438290E9D6FEC9E75BA4FDF12D2BED2CD988AC411310BFECBDAC48A61099CE0D0CE4B44EC9C97108A44E5C5EEC1D3154B4E72B8397CDB0F7D15AA358076E25B7F3EA1E6E80A214051C440EC4189137610450144641B1E71B5334F0DDCE9D5CA30274E0237E45B4D92D7D458ED9142CC23871E56411382CE40D9CA4358B417261C2E7E845637FD2E9B4357E7EA5F4A8076A7C2F40FF1F8AFABA5393512F690EABEBFB73811B974E57C2D473AC22E747A0EDD39E99FD6E5D3668F3DCA1C795CE27D1A155ED9595EAF9061CAF5C55F3EE97056AF6ED90E05D41E90926F69044746230C990118E4D0BE4C12F7A4AA0464F8FFA7CF64C07FEF171B2E43A917AAC2880675F929583E9040BA6FEEC8262002613AA91A2B8D4DBC1D36F23FA9248A2D3ADB1DC5AD669EA219D35DB17C9C25095AD7673445E59DA6CB2260C8FA57639D6BEC8AEE307BD9C96EEF00C93318DF7DFEED970DC1F61AC5C94D4086300D91199C90C95C1A24F7F1E4292A60AB67F30BA990D58C71002D3548A412276DBEF3984FAB312723880ED479080EEE2B636ADC75AD4423A6E0C5CEB7EDE528F871FAF21855C3164469B9EEB47B6D37CFE4222DCD0B9867B00BEE12C27590DD77C24FE640DDD34E9138E70D15F52E94F3874447CA5CEB48573ACFECA3554E2B76CEE4E31060BF132CED8AB953F0A280F7916810A107AB5BA66047FFF0003B1CF13BFEB77526265B98E54E76B891A89F3AC0ECDF71406674865A0936BC57F87B64424BFC8FDC41E471D951077C32B5AF960457E97CA05F3C378D94B60A9735E9EDCAA96E413FA391AA687FD07D9D021B1014CDF241E5460DB08D3B336DEB4CF0AACEA57E4DC6C464F698CFC2AD10CA72C102A25787E0B89249F63406A39A2A792B2DE04710C41DB36B55D2FA789004E593DECE9865771D8B16B5436A792FBAC9934852B1F55D518F9A07CFA56BCF488D61AE355D63BDC27DDED6A56154B8BA3AFA3EC9C01D6593C83C315527F5FC61BB169723346AB4075D09701789268EC1F02EC4A1CD8A5F2584E29F126B1ACBEEF660CBEF16A8E9FF9C0B542042EA76684F9D70F2E3F3C18606ADCB1D695112B129B301008EDD5E6121A8948E1165D350FF09647DCCF4A1F8605ACC750A0AA8319A6685153A7672B31A3DE785EB22E1D223D6271282AC18AEC83C760190799F082D7FB0F238F627271BE62AE5A36A34D65B5DEEAA12D6B14B59BD0C619D8D9A44238AEF1FF83C30118039E834F7716CD59E138E2ABEC2921D9FA92F6808A760031B2157103FD2EAE988AD6CA4F350F488261409FE91B5667A9A2EF1E226B8BFEDDEDB84ECF993E9A71220E0253D2C4B918C5521C7953FDFA00D50A32879FC0A68D2AAD13EE181DD47DB9E3D715574CB3D566BDF30209297B01A666DD7DBC5464F913599086AA2FC6C8541592CEFFA067B287EEDBF4C9B9D6CB23CE1DEED628935CB2D6B5CEFF3BC442B2BCBBEFE4AECFC455A3A64FA117CFD9289FC27E6289750005877DBF64CD562E2E7D1C99830F5AE63C70685B3898D420862A8C4569F2CFDF564EEF4F94FC34CDFEDED8854855F3A4E52C612258DB5EE4D702BBA98B450D070264FF86A440129DA2C126978DAB3341C4079A66F9C23445C5938FA799E78F157656208BA7C7BC7F936AF49D11148856BA55910A6A736D32E0974E50BFA608975E37AC0601FDA7551204EA66F524DD03F44F5DA28EED5D126C32794F1CCE747DC1E9B1FE287CA607F81FE7C795C96569E66B2F3413DA810035D472B7F5AF74F9CC70306A8EC36F1383617D0FFD92F6DEFA7EFE91C840EDF24430B197802979752FD55A8CA85FD8D4FCE774F1CCC540F77C02E16F1494DF170CD8BA57A86BFB086349D53E8A62E1DBDE03369757EADB0E985A038B31DCBEF513D4FF9A3BA6E8338EDCECA7C3E9417F9E133BC399F2EC0C72E60E809F79D55FE1A917CBE28FEF19D6D08A43F74DF496EA9305072C90AE3BA0D21A1AC0BF040920D3F5B8703C12A32A6864382E9CEE8D00CF4F93830623E76197F7F52309824B08B8E0D5DAF5662A36981D50880FD3A8D73D24430A1CB201A9D0BDE656593B37B8EC47F235B5CA251249A04507DDB81F8E5E4E5E414B3750AB168BA51A8873E6ED153E302F61F7159B658E316D6D183575D87ECA30185CF72C67543CDB658AA07B1DB220032DF80D287E769E3253C80F43570AA538EEF49F45316E176F1F9411F3C085257C6B8C708DA7B924B792389A7EC34C7F778E6100333E8B9FAE75A4D1A32E306AEE36D29FC6823399FF37CDD0D11C8D03F14740342B736C4EFB5302C141A86C857309A70BD74DB6C7C29C839F8D86F2A136F67A0FB3A3749542A9DD8D4A062672C75B67D3BDC3FA6B56F3E79008AEF8D8E04CC7781B23D0DAED64CFD1A91DBBAA2C9C4E765FE2FDFE6E8533848E51FA027B86AB05A0530F15C1B7B6BBB268F09A7865E202B1645F8B4267CB1A49A2929410823AA9B834101E9EFFEAAF6E406639AF7D2710E60A84B6205339B0719E05BC6724FC2892A017AF86D80D361A7FEE8C284CB84F5F09B90CAADD49CFD396E6AC36052F5CCC8E7667CC762A9F173F837A231D57584A3BB19671B8B71907E415A1672475ADFA11998F94F28B00903AC551E651A3F9485DC0ABA3297E561E0B5A5786BAD9EC8169CBD706AFA60AE764BFE01EC514623BAC6C4100F707C5E8A02F4B0D6265502AE4170AC3EF95B49ED1A2BAEF56F63D5667C9FC0AF4C0A8648FB6AC5444EC8A1FAF4715027AC9F5987735D1AF7C55AF4C838FE9FC84FF71F929758DD52E2BD4A34237350642C0E641B6710A66C9C1EA1D9BDA80198FCC56D45D67C3511BAC0971AC9B6166633B1713A969B8DBC3CF60FCD6998137AD713EA3ADA84169D49FBB7F5CDE362ABEB0B71D022D9ACE7FF48C9EC1A7E0C72B564FD2C620272A482941443838D0506E2294B760AC9DED5404D3C4D2898315D3E3A82D2E944D537817B9901AFEC343B95F2844CDC4AAC3836E7713739F4201B95C42FB7C99AF8667628C1B60115BCB185754148B3C7226DF14B6DE1AB4C6043329B176C9DB9B1D73B3814FEB89E84A4C91C84993752B7AD30CC707A71339E8A277A5586BA85CD090F799A6B75523A62C6DF1549D787BD8722D1F26BC2C150D6A38951F3014B83DE665B21F5D9D97F2237333CC10A4114796D56D13D643364306E7445F475729602A11F8BEB002BDDF30E579E26F2BE4AE87DC666974E24FEF2462120B6CD8E79D65A2E80542A9240D4EE1F616326AA528E2A1282EF49F0312174B67D40FFCB1370BAC5D1444D75FBFFB6B0887F4573A8C4622082E1FE349B2C73CDC92592F684769FA7D7CE6FB5AEADF38023E51DA4EE3EDB10368442B218919341FAFB22EE80DA96A52434B184D499A4C49317C62F6D6DC9EC1413D01A1CC3DC8853444E52718798EA158A12B72AF023079E5E76F41AE685494E947618C4AB3036ECDC74F7A043230A0BE116F2B617818A2C94C54CFAC964C73BEF969591A3CB2B7DC9CFAC7B4F9B64AB70BD7FAEC138E42908BC90D6ADFFBC88EF473CA8CE7BC960C4B3EFFCAB92E8259CFAFA85EDB7832B3E630D6D2CF031B8CB570E38C101A56B426C654464228D152ABCC6DEB888DFFD7FFDA974E60CCC2AF7531F38A813E263D9B20DCCB50229E7D8F379F81A280CEB90B64BA3657F1E50381B468D0A6608A4B5E107C4736FB4CAA10FF3045C05453EE12A9FB0B79845E077803C69CDCBF7CCF7D6FE6067ED152F67023CAA6095D1748414580232007AB3426FB2889E1BCDDDBA539A2D79CA523A2CD1B1314C87502909DA849BA9B11F9104772BBA27410018348832B0BFDA4F09AF02B351927F2B6D29D9CA9F330266EC035908C9D4023CDF2343B177F57903D37AB89D0F9E23EB0C4100BC6421235CE5FF2729C2ADCAC24D1151757D8C6D6DE53DEBC38FE866142D1BB593974F4D3198C03DE4625F41BE3D488575B25007C2D5970BB152BC1C23E48A88036C070BD38604C5844E4205F1EF3D7FAC0B4B9FB51F229BA322D3355E458C27685130FCBDF591C0520626E5703A2E85871A62AF0CF2DA3468C401644656CCAB33B2402074C59A0EBB57928F548B5FA4871A8B2AF0BFD9A871A5C257044C17E4967B70D0DFB59F1345526FE59B4BD92A1C06B15E3A6226A4821FD614D8DF612A3D2DDB2DB67BAA3878C68C16645CC747BA9B366677541171A9264B89EE18D9D169D341629393C5526C28B24CD4CFCACEA9C42DB2B1CAFD7F906FC17CCE16612B1261E62E2A700CE74DE73174D3A1E06AA31AA05044EC324F026CD39F7B13399D9D86EEB53A6DE84914719EE31AFFEB630F3D8F08B4FFB10016209C13BA2158ECCB4B74BF04EFA73222554FF5EC49709F7F8DC1D40005E91245F3A5E2A00B9F64678B2D8A9E6BF1D011900D9D12F7F3BB023D1E5985BF78F8D6132AF5C0B9C330F361EDE00473DC9EE7469478FEC02670E8659B643B92C5546C32FE7B0AD816A5080B5E3867DC209EA15AEB4B14E42AD58F34CED65ECB3B519A54BC25117EF8D392A85C2895B5A4B73CF93077E360A828570FFA02ABA84D6534F3EE0C935D97D1D1CFABBC0D82E48937797FAB31704588605082A950CAA23D6569AB793FDC31BBA561E729E80979DAB84ACD4EE6B2CFE06D2EE8C4183D33B9F894C6865D9CD405C7665E0150B2B649159BE684839BD12CF0091614E1F821046238DC9F538F769FCE51E9B8DEC0E98442CABD3A4296F1D4331A16D33CA356B11E3DC13937F814D3D6281A746F054606DC52B737AA40422471139867624CC8E9C559BD25C7C6D7F902677A84BA63E8CB817820048C1C0ADB6288000EF2163B51ADD4D758D1C87FFD574354B41CA5AC72228A7E9E9E75BE9DB18FED47C32E3C561C972A67D50A560017BE794AB9BB6B50CFC43D2F6D57E8D73CAD6227C896BCD18E0D7087F57C365FB9EBF5864DFA4A13B6B5DD7FFFCB648C1E1FE40B6A10EC0C45C74504CF2105AD443DFAD1E306F720B9CC37B4A30198D3123FA9FB2A7A9DB3BDD98D441B03E0EE6A8180989E76CBC71B0E8607C3A9E5D20B6008B010702FC5D59847AFCE122F3FD4FB5D89D3A3331AEFB96B593F724C04885B574A43B5EAC70B543BD191BB818768C67A10AD6E2D62AA4C65FA373A19116AD86A4F9A97064E0C0BF80106DE6654B4A3945983B7DDF3AAF1E14A04F6D3035542B0F710352AFC20FEC78B61D8548B9669F10B3D6E531AD07A84C493264DD49759D95A6AFDBEA5AED1C7D7D2AE6D2FB6747151CB6A5C2F9C1AF5CEDBD9CDE8D5993ACF080A0008BABC759A9DF035C648609E610F226ED128E2656A057862246B65C70774B68F54D68073393B85110285FB463DFE394D9DA0AE85985FD6882EF5B11FAEF2BAC18F9D9D9B5CBF0F80AE7AC4418EA658D68B14BAC135452DF271DD3348BC338BC6C789ED95D5C5625762E4CAC6514866613E6D533AB9814B7C337260BF16716478401689F4079644DF4F734281C16164D19C4ABA20ACCCDC517EF42C19A5B1CAA4658C27B61902ABF88EFF0795D2C971608B0570E016CA0568CCA3F7B38FD3DF5608154A33C1F0D70C2AD0EBB134A8F475A8BBEC8408D3B9B0BFE8A6F10FD6C979B13C3EC73F191B788A79B4D07AC45172950689584C909247DC8A4CDD686186DEA16676851B8A7C311439149B1A963B0CC60E5395B56ADF27C25A51BB4A2FB19E14CE66B6D11781E89B3EC22CB854A12D46970D1A009AAD071C479D9C731770D666CDF0BCC381A3D328542F6371FC6F5FF7C4D3BB06186C048B2A3774EAAA3CCBA1342927B498F2195213326C9E393153BC8846AFE2120B8FF4A455B59AF6E65BC0CE9CA3502BE73D74B6CD12A760A9E0E0D26BD105FD993DD879539CD666CF2025DACD481A122627594CAD7C4FE30948412C1C6A160C358E16B6B67653418A22321DF5B1A9EA0DFC3C82DE3B8CB0F48EEFA7DD6188023D1B8B7632270E63AA38873A2C4472F9EF1E8DA56D5328C00548DDC4D9FD79115C5F6168AA98099BA1AAD606FB92F8D253C9A55773E5629E84350F3BC3B00D803E83CC2516C6C29476018ACFF2ACF61584A175E67EB8952885772E6C2D7F9C2B79C8B2F2A77C73C8B0230F080DE716B2A13DBA5FDC8648F17573A2898E72B8850997B6085F98523F00516DC7A90B9C2701BDDFE505A6C330D1118AFABC731A1DEAB813AA0E17708122C0069FB61A02FF6D5EFDA990A23E1D42C520CF1975FF06F123E1AC0B0A86FE666F8843C406F5F1E1A36FBB7A0B41CC641EB49416D6F0AB03CAA6AC0CE3A3DD1977B4D16EA33CF75A37A6092003D097D0ED8FAEE89F761B40F7E600FD502887AD90BE4BA311B9F4CD9D348DF230A2EACBA3FC356B506ED8C357E228970A948FC4983AC3ED9C3ACC22FBFF56783A73231F7E0B91DFED20E754ACE7DDDDDCEFCCF3ACC76554C269D634DC228B38C284AA35C00487D7873C8CFE8E8657726FA845863719FCE5A9E32406E2191B791F76DA035A4C862176040DA9AC0F37E66FB84DF89CAAAE9D8804824725FEDB95E5380DC66CC72BBCA1E131E6B785EA2B2B4A05BDAE01B22C3D47CA85092802A8EAC42E963A62307476FCF94ED7EBE5538A8C6F28A6C65914CF48299D3BA2B89B3008D29CD874B79A72AB840815827566E50627C2C332B1BC60060BF2FDA320FB040FD14D52CA59B24E325B5783BA1BDA3B27415C9DBDAA01562466322706CDCD0307C3305DB08D2663C57F6D3307E1C73832F8CA712402C7402EFEE0F1BD77CDA08F5F6582540D34F1B2809F84EB2F540558EF9ED46D5C636C45856AE57FD9E4650359635BE72028D1CD37CD876E0DC598E360CAA1DCD1F9F2BB4CA27CDE012980080E91B1C7376622907BA6674F1EB9E80148E6A959EC74950A2B934D42B84D739F1DA528F5C6E1C90A238E5167041D4E9AE5352B74C89DAE368778A90170461ECC0D6B6C6C53CE36745A72F79AAA1C82D494BD89D719800A89127BC3FD55247C1A29FB8387F1E3576E0C45F4D327C0B24A75FE25EC6147C890F25E50AB3C43B94F451E5B5D67F8D3BAAAEA1FE211FCE8622600400F73C1398459EA7FC59D02582C2806D01023D84BB50E99AE9ACC217B7223EDAD956FE155152E7F35B2AEE1535885EC048C6E0C50D395B0F1C9D767048E9D2DA7F15BDE192C923F1C74ACE06600628602D1B0189FCADE0873880EE8544AF3E29314E2B5DF87BEB5A50ED72FDC093800B12CB2F870304289A73A65D7E2384EF3A388EA9F0013B2B5C92149E2538542D95FF020A23E976A7DB3E2C9913D87D6EFF12BB51EE298F1D2CFF18FDBAEF56B70CBA35EB9273F1E58A6CD38F1E682A759FDF8D8BFF60E7CBEA948E25DF0114BEBD4AF13E4E0D4E7C9EAAC2C5F579A1AB14E7FECF9E13F20DF873F8D0E090905D32C8F8C0033F5D8E9F1B9FF17EE04FE3656EB66F5E4777B60B047DAB9BDD883EAC31A6455D1719CB475D1715CA0D12762F94AE78CF3C8EE90E55E71D0AA4EBA6216A0E81566F7813E7759BED30860BF22178407783B9A8AAC30CB4D53AF140E33A47ABD60F33EE700C323277E751E5B32B221E4B9815FDCD400DC544DF845619FD733F164937144FC3D89D8186F8B898418459811B3E66796DE51D1373B248A9B3B9609FEA374784A33989FE9F5BB26D2148F7282E09C35E13295D90BBC7795DD72CDD4955E9D148BC779AEE9C7992BB85D8EAFD102FD690F2C679CB7003FC4E182678320738361C361747F49AC6149CF4CDA4B80581844F5EE4818BF61750047C35A4B10697892A80F07E946F357574527FD2D0187873BCE78EC99062C70CB4ABB72A104A770CD7ADBD20894E7BCE2874E45302DC0BCB9645EF28136F36E7B179BD003D5DFA68A572BEEBD40EB9AC1F9228C74A788671BBF4781AA31C7F8699813F32EA8B60414C3ECB894DC7B01E50924482E5C068F0BCA79BAD9F469770FBFCB3942D1A3E54250E87B3693329479217514A8D7B734D256C5D28EF854FC3F234BC671F5225B1DCC20E590D8E5D09C07B22EF0A89A5B863C2E652CC0B1623579541C63CE9C2C4F66BC43323D7000BBF2923F5B8A76933FAF950D2172C1D90F522301D9A0C22F470EB8673CDA0A1B494FD7EE9AC1B4597B2DBC26FEE33A08CDF91E3C59BA4F93E02D010FE3F1C1FCD694F05B7A8FD32D8E7CBC2934A25C481D9C58FED7E0AF3AAB527D6DEF43D53756F0C95B2B58A426F7F61D09F4FBE55D9AF053B92818ED9FEF1CB41FB5CA23AC85B0241900F73971558116C5809F565F71333713EF5BE87B0AC95364C9FAA80DBB9EA84B5A5790D20343141093F86942817D195ED8DF4A2DFC7F7090CA3DB46A92AABEEAE2D7DD8B9110F23A89E4FA7B5A1DA27D643BB879888A2238E221E2F67D9DF58E73C46023FB7E999059D3B81FB753B2AD333207873831AE42FAD8092AA04C0E4103B1CE0DCBD6B06CC2F0AB37CD1D10EC4C83428CDEF84041D12BF9ABEA5C80050A853CC73FFF3076BEE68078737F6EF483F486215118C640790D0CFB4C6E5243691FB73B1294E0D3A494A4A538B94FDD2746193D9FEA24C1C04F5B20D2D40B638CB932C35D953A9D31260B76DA878FD52EDED058D1DEFD9CE214D14C3112FAB00B7F2DC88F7EBCF79EEB1C9C8607D6919B8D32CC8416E2B981C141198DD9884DC3927EB0192B6361AB556EB3977E5E242E5E26BA60BD42892F46F3F2DF684D0D9FB41BE42C04F0C248938AC79F110075B42181DAE62801DF76AAB50AEDABF4361C0EC597F31245B0390CE2629DB933E450E09DD39E6A1B644B0FF672B52ACE2AF52780D3F6505551F52045028C4DEE6D1C6A34BCD5E95E9DE1BCE849643BD07E0E6FAF8B27504F859D73BDFC07FD2034595AAD85A9DD9AA5B3A72346D6F3C4B21C4CFFAD8247C8CAF0DD9A708E11450502BF3C28EEEDCB0E1D32D3EF1A3F6237E34C0E4D0222F496839B7374EBB7D786973E85392AA8FF2A9901D076DD4C65635286276698DD4388F867D1ED18650FEDA9B03C80A3B5BD0AB3A62A45ABECFD55898BDAFBA58137D4BE29EEE8B3B3D1C4467B63DBA1EFEF2C81CDE7CFB101B1E65084A0E92955690C8CDE6F93E23FD79B76DB475CD24DD92A7504510F8DC3B22EBCD0288B4E479F8DD835297B196531D2DC759364306EB6780FEF31C9E34142B55988F81312B310093F77CB89C6E819A7CD3450D0790CB7B5E33A3E5E51DF05A3BFEF63320CFF072D450D71E7239AB24E4D83A8E8E501A5BDBB041219E15517B15EEE237836672A761D36D11EC973BAF65320B368906392E2689A9936752563172B3A5ADD90066E01EB394C77E40D57553B883F446C42EBB9CCB47FA56816B06AAEB62C21C8F57F926420AB7C1D5E97E73F024C259011CD585C23D30F99D22197B569D67BF5965887AECF553A9B48DCA0C418778AAD65D4843221B8217D2D61BA5A46C4F9FF5B00B78CFA8B6496007A1444503DFB8D7CDE7A63D5D7F54EE5823A33EB3A155C20F0011304068CE0385A09170606FF6895A6955C211AEF5D13BB93866C9CF00A911A4A50A59133113A9C7DC53409097808A6D0DC44A7776B41A7A43818C77CB51F3E20107F080F6682D90399853104B8F3AC4DE8521048B22BCA58B5F7B5EB3E3503F638C1FD24568F23EC8C59A3359A5C9CED0305B1B81677E20EA35F9E896E665D3CBBCB6155E1B0539A0B26BF95396DB8548124519B71BEC19A17DFD4AA2A2E134BEFDCA352B01E1255A12377D811FAED7809C9B881B24C185F1D1273F405F5BE82FED08F26E6C11D39A604E88A1EDFAC8AD3DA9FE8B1111C7E038A14CE58B9598AAE96B7BE84C153A9B26993CECB1CE931E0CBAD5F7F6C18B68E14E83A6BCFA33AD2B3A707118D56803A1E55CAC8AA93EBC47F9EFB"""), TestUtils.hexDecode(""" -626A3DE2BEF13592E52829D91DD5CCE8E679AB2384C317DD721C3D90C9FAC0DA9E07F5F329FADB83A1C3C1A06A6351AF25496EC7FFC232D060982FE36AB460A905E7E5BA6FD1D12F17E4C4C8D34F531EF6AEFEDF5F29E4F6D24A8C9BCE0F803B47777C78840CCF9AA4BB798D7429EC8D9BC547F24A203D565A012BF17903D75F021E2FD41B8128320C274B95BE21F795F0D13F1096E59D92B85AB447ABF603DA95488C8CD4EA2DB181D9B66626168B765A6D7E922AA9F2F79631CE32A6DEFD4151C4F0EAFD26B50FE8007518280A647B8C4BBFC48B75AAE50C20E988BA863EBD36465487C72385C16DCDC5EF409911FDC9FD9F1F69236E18813D7688B64F8735805AD8FF8494DA36F42133FDE81539CFD1C430DE02ED8B88D5B0DC2F411E7192759971E4AA68E5546F14CA4E3F43ADB3070A8EAC4AD82383FCA3F8FFD6A80E1984653968EAC57BF55BC14765D91101302AEA86B3FC599C100549F80B75ACEBEA040AEB4FA0C2B4EB4803BA549E0D873D99DBFF0C8992CACD6A2300B46F5F4F61FBE05EC6B203F6386F57F49223550406F6F4CD9E31C889A9ACE17D9A846F7590F8EF0A3FBD6E4E4E3D940EF78A9B0B2975A5B442F141DB9569F993C6398AB98A4C5C5B3BFAE5D00C53AEDB5C6376A7C72387481D72AD84F96F7DC59DDEBC41D062455CE042B573F62C98C0B580AF3DCA8155841FD66736706FAD04D9A518E96C0A1C92BFCB82A78A696ADC70A518B25DDB30EC97E8DF355F87C322008ACA4151E57274C2E219EFC811A538B8BA26DD44DDE9C429C8566C30AD085C1569EB163DE705612951F8C022656A2462F92344329FC40D59EA66C07D44145F54A8CAC1939A01F359F54932A9E8B691E0FC3D01894198ABA75E851DAF35CA562DD5340DE311F091E2C65CC294558FC1326856924533A46F754F90F51569472C9FBCE63991D95B43ED76453707DAB30717A874D17535C94D880164FE89B014016F1BFCB971F651178351885034DE97FE94021EAE46FD5624E2C501C133D56D359904F9E0F8A1ED887D975CFB4461923FBA3AE566A27198BCF6938A4C80596396A2BE7755AEA803F4CB7075DF5A7D70788713DCE543AE2280989166EBAE4E7DBAF3DD6C92FC4792F0F11DFBB9B4A465FF9AB96701D5795131D71285A74FB93EF20C8DDDC705EA1992C1CDA769D2F43C5EDE7214823CD8F2C7219C482A6B07E88C6DC3186E04FDE3254DA0E9767FA69836FC509F5A9D9CBA41B12F948F163B2FE487CC83BAA5986CF84D07D171EF9F6944B5DC9FA7866FA72E7CACD7B4345164E4731971C8A75D96E9EB0C61B4F1F3F32CEFB9453615929408411F118A6DE1A9FCBE4FCC71AB730CAB4BC28B61DB6029A788437BCFE5AEAA41CD90418F49766E20D91E0E29714019CCF304371CA4C498EE48C5584FBBF146B888E2C3926FB5BB12CBD0D1736BE74EB533A7C34C06349A26C3ED86DE52A37E4B8EA2C1108BBF3E6773267C5B5C3E50EA16D56B24DDB32FC7F9BBEE75DF88181AE97FCFDAE2CDCD5CCC2E141A9379820CDE613E9FEC61212D23763825D94FA1102BD7F7EB1929A2538731A7E753A7F6E6BE57172C9B8349D8EDD698D1DC25C55D7F06775C4B9534BDDCDFF33DE2F1E9BABE78DC320A202ECF94037801F42ED1344091A132A24B875535322FCA82282D9AE2C0E1E926A2E9E1A4D2BEB6A58B85D65A7847A57E6336C367F8C0812C055B18E8A0AA987599531DB98B8ACC58F5DF9D8E7357888594A188ECF9A805FD767A1CC04847BE22833994784B545C4895B18D06F157F3B75BCD922A8894E2D8E3D174A3C3657B4D4A7B7318A4864D7EA59478E49B0C8319375DED55F93DDC5A51C6048D028195D4DF04206678644A2A6A488F605228E4120FA97E271758657FFE34F0AC5044F8718C3E184EEEDEB62D0C29670250D491E1FC3E59246EE06D3CA31C167BA3FB52A77E1624E34652EBB1FA92DEB762FEFA87AF0CA5872AC6E2B6429ABFFFFA10A5F346F032F753B7075B7CB32E9E899D371C7AD8FC070D25D6C919FA478FFEB91EFB62BC331D0A975157653D07E3202452A05303C9616CE9A647FD4C97E1E0DBD9D8470ACF5D5DB77780A5D515FC7BA795A071B67F7F63D8A4C6E05BA2A7B31AE16EA31D8252562F44DBB447935A3EE504DD135AD6DAC43BB01EB0C5CBA939AE446FC260BDC488E3991D1BFA5102E262C4E31A034B8BA12C1E0AC599474DD98CC014F387B719AC06327BC5F157AB80D424BBD10769BBBF97964DEA127FC52F418DEF5DADCC93724A725CA47300A31F5B1D2D93AADF5FCD59D5F30BECCCBDF34AE458C50A5B54FEB305EF1C3F42556C2E97DA0327629DB5AC8532D6E4AFB22DA1687F536C17D7153D8791805061FBB31ADC0AC2F15FFD764E46DE3AC541B07C55BD67C7A5A972E0370620FE67449C58769D269E160C772C1DE53C46E880D5DA7D58EC100C6810B1C6A051F73B42F8682F166069E6D0D06D2A5894E4B6F74C42B31DCE09281EAE9B1DB21B521D6F910CB8BEBE8F7C09B137C7C1B7B185CFDD91E2A0D9503C35C99EBEEF4B3011A1E5996393FC21E972AA0E6F576A426141699AAA0487C686C1E14E74CC697F4E21591A75F5DEFB98B5D649EE2AAA85391D25FD8E2A20ADBA6523C26713165ED207CA3EDC7F0CBFD5468F4346A209D7A8EB2F63DFB6255F54C062BBF2C90631B539BED1A557A16225FC3DFAF9B6EF2BE10C0CB279644AFA74A03E66FF4FD965184B9571D4A8EB2357A4EEDBAB71275E3D5DD8635C53D29516E98F74B51051752AB7D1954156A906144EA4E54A11826254529835A80B6A3599953E012D4953F4B610A85AB55860C305787D00BD61179F369579EE1277406A3F55DE431E3E7EA8DE07FD4484DB4FF458CFDA28A2307334A41DB55E31CEFB5EFCCD922E475D06979E690144F77780BE1DF0667F746FD0B2F72F87399AC11B9417568D3691AFE1671E08FB2FF508A68AF6A3E0CAC6A9ABA02A4E8AFEC4B7F41CA03EAFC31CEAE5C523703FE41C1CCB6D021678EA00B6AD24AC63ED1F6880C4585E4E85BD975EC84417E8C4D4C2A4B6C10E11853C9DAD6F07BDD25387B66AC3DEFE166D6F85576DBEC76943B87E7C91293D51CB2542B63828571408F893CB541C8A69AD3054FA9EC6759A173E82B55D78CE64920548856A664E21844E97CB264F42E11754FE5B17AB60FA85897D65881207164AF2307376728D738EADD4F486BE0E5CD0F1FF2B080C8D966C28579DF5592AF1E2FF39EE0E318596B26CA5F48F789CA0712A7573BB6ADF3706D53E644B70056FEA3C7EA90D0D1621314047545C738E93A0BBBCC8CED0DBDEE2EAEB0709142630353D434C50657D888A909AA4B4B5CBD9F000061D2C2E39464854575964747D859BA2A5BBC1C3E0ED18415379808394AAB4CEE3F500162C434F""") +551742a530ae4d15d68f1e222c8865e6fa59541a5e4b6e137197b52a5cb84548c099c3328b28865c34e90095e8959c65f68d8e4ef9e9cab97590736dac647c93cdec474c3e6d1c934e2eea593479349b6e56b95dc356cab1e2a2a7a94dd6490d9a186879ab75f16e0bb792863a7a8a19ed88d74d22f7c17f3b55b4d6440fffd4c24d814d3c09cd80b3d3d137882439f628337061253522775d68c1072b8df9403ff65679d24b06f1a2779ed76ca3ce153c264a06cf04948eece4f06243f22898bc815a90344479a8edbee87d0c5473474b1b588006f6dce5be82c7bcc2db7b50fab4c2cf06eefed93110aa634f6691e9b757aa8a01ca52912040a3ca6cd6f9c596eedc0a9d49f1bbee32eceb2374336f07e74b425d6a894f8c3e49a255068d08ddff453dff688f9c74a2be872e2a205018fb3e0149113ce438a7b83e60f536ac616d748fb2c590f3ec7e4c81629a4fbd993ced51995432cb8b3778f7d4e375fa54c9511e8e97323ac021b7cb2184bcce98f87a2712740ea1bf33670c4a718b475b31249ddc1a9c2b216efa7b5bc01f792cdcbd07f3e7719f71b81c3a31d8cfb7dc07efa06e0740743c9bc515c0983c845b1c7b2cfe7745c8d0e6967156cd36e88c8e3eaeb3c96ede6f94a53eb05abbd3ce8abb9f4d2c350969a8d5fdd673188cf5f8da51704b7390d8de842a18f5d900da6f0de22b9b4836947acd4d49de53e6bf96295c3f89a01070fa3742ca5070b56afd534fd4bcc280bfa5233ba58e3bcc46cdcefb5a07904ead0092cc088e8ef1de2ae418a8f977dbba6b23a634b93abf5135504ec8adae1647042210be6e6e0c9b333c3f1d0dc906ea63eca4697823fa06cbaf999ffa6894353d0b886bc89b6d8b80d88a80b570aabd37e8bfebb692a61ef6e344b4bc5d10a4d4d7aa2b2c47935ce37c1f2143be5df3d55f9a947c1d7244d80a74e92822a7e178229d703ed770a3a2e8e07cd465d6b4fda758867bf09dcbf050203796ca9a6926196f13d8a5d034f566522954999ab327307189e0791866385a3eede8b8485d6c673ca69452d0a7ed6a32142b74115cd39c797e48f38111b309a3b5a122fff1c8afbfa7eac2dcac8cf225c971b88a49e845447ccfc634341e2eeb214ab57de15ec8de38300871207d8bf98a4b9a44642679a67fc1792a46bc051cbdceb15b4355f56233ea87dd6613afa535b333104292e946ac29b73d04be3b83a0a6afd275fc02d99fa0a0b1796275b45aee6fbf801f5394fd5bb2670d18bba553e533d39d0e66ff194a7555bd23ce14ecc97ebd99facaaeb8a0d0e088d2b9bebbc48b4fe32da39a310e28150936dc5e86bab264baed9721beec5a6ab21db810f1bf539d4e6283b7a382984595eabb42b21aef0a1186d66c988132b0fcd17ebf0bf9347d64e334e165d1e8107f6b49403d77516f55e973469ec6d3ca2ecfa2df3c7a82d08ce5875e4a0997ab9c4189e1b4c37b5567fa7731d6981d96e9fdc35abe9ae1a4ab30c5b329cc617a2f92cb91109738a7a41da00c48eeefd6e003d3e25de538bf85d83a4610c0f86e7af160703666e6fb525122ecbacd13242679cb02298777001fa2ae853ec73eb581229400c93408644bd64cac57854113aff1fff6855e2632e1e47bd145865a142c9ca2000b2595fd4edc7a4b4cced9dd87a596a9e245c25fc87a91d676fa0b02a237f895df9dbf2eb099a60fadc4b8829bbf7aaf94d1fdd10dc560244f0d6f5394318497eeac7cceef0bfd8316914f766396d9a5a7cf907866f85ac6e188133614490e1031dbb8abb003b2fe2995a28fac84d07dde5987a981101087606d6b4d4fc1bf7b3cf56f667ffdfc28adfefe6dfce01579859b662a189306cb048bb4b8d66fa9861e83fb28c325b89abd6838e71e5ebeead3e014f40b48a36f1d468a4a24954f571f4972afdce0d6f9dfea1cb500b6212bbac96e7a3193691eb0823a48e6f49b63eb4b571dc1b60654b6a882d84ec4a10b5faff8c0e71bf1548578a8bb4b772a9dbd1a76792e4186ccaf692a5cfeed5414be448da61b1abed7d58acf60c60022d6f87f25b291c226bd22c9445d15e2dabcdebc6fc91d780493865f4dfe420932d9a106e81f254d97b91d00efba45517edea7c8dbf369a32c9d04a5d141d3427c68b19f189af86b3e2fa8ff622a14947d4a5c4dcd12d3e12c714b32075dd9a9c35e8edd715901559efabebda589fd123d0a7ad33bb67f353bd01c4ef51b26a187986edf0ad892b4c71b2ceace37f103dfa8e933bc422a2799dce9b7ff3de92b578e065b79a8e7d4c028002f5b667886bb783bef181f4040c5b03050f9ce2b9cda0787ce21675222dfe20c40640a37058910069a0cc037ce13a2bada74027901a186b5f194792105708877eecf678aba0436c2dc304e8fc040996e488f764f3d0f52056edc69b5a6e901bb0dcc75acb8acc9f22249961cc5df3d10992a32d724699120a264cddf1450504feb09d82b0181e0148f7ea9ba61e99bcaadef0912e1c545ba9b97a93c9cf5a8c29d3ef2a2608a32684b30ee7d43e6006e81c37b636616e736a019e26079d3025b1c5a3997fd9021634627964a01786891218711daf4812cda28892fd4803dc5ab334f18355cae65eb68924ea9fae67b74ade42b96ebd43010dbd0536f7224fff388433de015721b73c60d4dfbe1101100efe6e69965fcbc8eb442a233654b94f79ac0dd967612fafff60141e1fb714a3e88147072c2b44ac434421eb5295a9ea7752abfd6dfe4e10760f0f1e6e486172d8d4b092e043d085c800a58f5c6882e37099f21565a04ff5c12ad4d716b30164d8951f6cfa56c93388fad772ac2fcbb80276a235fb4369f01c77266f2286b61510eebeccf4a610f995c850b2ca952c27875801b692f8c1ebb61758c44f97ca4628837ab1f6807b57ba56c1b2e39e1a002dc724f06a3fb1510f18b37b0b48dfc21d453ec3a576fcd3302ce89f313ff2aa895f0103e11b3c01291c112a4d9b5f67b48767dbbceb8e1a0393dc8fa7b0b7304a02e30612cee891cad631778726124860518fae5a1b162aac95a6a3aca66e1dfaded70547e4d934bb01034038a23f63e2695f554cda78d42808c750ea5dd3c7c34e74fefaa93a91ca66a472f2c1f8a1de3c6e876fb7721105685639cf82ee003704637125e9177cfd964acec7bc1474ecbb0283e317a03696bcff64e4bf6e58e3893c7fe4d41886690b29c2d6f32ce57ca25559c3739e14af58af1d96f581e469f146d727ed4ff89425f4be0f5384ccfd5941f6c859d6d532126dcf4529564be166d880b4d5b5c617173778197afc8d3dddfec020c17373d494a5461676c7b8c99a3eef2f3f52c2d304160696c7a7e8384919a9da1a7a9ddff071016172229405d707cadbedbdfec000000000000000000000010233645""") ), new SigGenTestCase( TestUtils.hexDecode(""" -2EEE200F329D7A51E31290AA8C6581EE83A0B6F215ECAB93D0F0E4D0350B4548999ADCD8E8E40E7BAD4ABDA6B7194C206595C2747C4CE24E6EB6BDF0101CEB17716EE0336E6730404E8B6F8F1022F66C791D166DFF04E6A18CBC05966306B34745F4E213CD668E079A0DB2762FEA5A1CA548A026120289781B847A96A070F43F10280A08252564A48818052C6042280A4989199005CA826940382891820149121204024EA4240512974CC092859A122048B82812B881C9360D4B001090B60C0A398600A5100099710BB5201A196ED10612D800251A418E1B3321DC404D20C3404492055B1248102500080468C1B611D4C2100C94046442204B361189885022A08561208A23B64C43286413027121488900300212A33109B32102A561C4A80154185203010A00108D2230801B1760CA406283484E00B949022622001765CB020213B90D9C368A83A2915220465C82898BA09182203118B30112B240DB026880200610112919948884222AD0808503324A583231511646A14445A0A64598B80CA49230C9828D138685644864813669080460E2422C60204900B50113496604C06C631285E1C8295348614BB828E0182A634881D28881C1984444867089369208434A19A920182088182940A132514432688BB87113226D132051A33031C118220A450C9840518234010903929A1226D28691E3828DD2B26810094E039728D8402598243208938492468543962192982563322102A291A494318C306CD4004009874521B284D1885124274C0C410D61402D8B146283A689618808D9808464862921994C0A990454207014B3608A168D09150C9C38305AA68C14118A4C120A9AB03109122018328AD240492294650B23121847060A321061980583B8300BA08D633426D14260D1886513C6685B082E09B9601CA48D519861481248501431E1B811C41082D344249B424D1B310D99105084468DD832851B14864B102C221211DC908183167008A770C2440253388112C68423184952828DDC408C8B4884A11060CA8000DB2089C2805199900C1B044D22874802378602C040591484C0B221220790C4804C48068EA22006109489CCB60CA04226CAA46552003050B608A146914A007221C711D9088483103143C009E3086961204E239200C390611A3529D808421A422DA4208120A351CB080208495161144164B044D0A6400C4081124025C9B631501870942850034868E0B22DE3B86062486C0C336D0899305AB845003991109040B90DB8DA1A76D8382906AC6480001D09B8B836B9724779F5333E5CB7EAFBC9BE79ECAEEF30716D5B8198957F201320D88030EF5C82C56EDAC3E6E7CDD8D272EB421CAE9BD5F07FD96EBD3F21C0171EFA28612807DBDE1BC11587A52AF2DD2A9AB7F24267DA67ECC77585BDB335DD29E7941DF37995A7680E71C4E688B840A19455E569B5A777BA3137384E0FB6F2CD937FF55A389758E95A4F145416EFB0EFB094BAADFEC3F91EA5B9AEBA8F461F4B2A451ECAE68B50EBB69D358C12227E8995FFE00D9A3C6AB4E00B58AD99C9240B4D2AE6722AA144E27B6F91732C06A86072B69001AF41F30CECE4869C334EA78126A47FE2587BC76B587E25E61B1EF8CE536C0AD109033B14DB41B9F2F3E18D4F812428E9E9AB88E6DD01E8C2474F6F5B1BB1FCC3BD905F1B16034D9EC562E65F06C14F5BF497930D02565EC9A458BEAEAA5CEE6C93207AFA1C934961D1A0F6D726A4395D4730575BFB09F41B21FC5A816FF6503A0ED308D693EF4FBEB88C09CEF42B1B1982218C3BEF1E81B63DD0D9B1BFFEC50A5782D00B9EAF42DE3561E47F2EF9B3882665328D17567282D1B1B91FBDDE4B64A5876BDC61777FBEADE3144444577D591CA0CB5A665251DF22E055E25AD7543A21566285FD3D3C85E7A4849DA65A28658FF631DE44ACAD7B066E2D88944BEDAC4B220006B19F5F15805DF64F320AE38D05F0DAB0E95E02D1707C23279F3CEE21FBC0D921B334E2A41E7D07EAD955FE5D530F3EEE696248568282A4CB03C3E017FD959560DB0B2F2149F2B01FA4ABE1FD17C0321F38E77460C29E93D88CE4301B58A493C1B29C1B81C0C6B720ECF408EC4AC8BB744A79418531BDA100236268C257049D84598BE897D804FA13076BF9E426D700101D10460E1A97FF32974E1B981893C0022C1BEA990AD92C2C52409C05330FBA5EFFE835A2D57025BC8F22796EB42E6C3CCA9240E3B5E098873F45D5F2B290C93DCC1485481D3689C835EC613A5EF5C6EEBB21AF65403023EFF15867EA26E400FA648AC02C7BF4FA9EEA4FDA649DA80AFEE18A660C6C8F09FC45CC6D0C1941829488249052FE94E9E782C49174B680D7362E41AEAB16B797A05FB55E66A2A0DF069106B3E28F1CB7E90B5C0AD18936208AFE951DE9BDBC1EC66259C9D80C9623C68E95102EB6C597C955B37C510BF421FF5B38590564960AE172DA8605E01396992FB918EE2C107D5A13AA1F8601B775BD5B9226AE66F28FC62FF06FC2ACEE4ACEFE64C3234E4FD53B76CF0232D5C9D7802A040D4E529616F0F43F118CB678FFEC23BD92CA08B18617B4454CDBFEEC86E9CDCD80A8E918B73C3C3311D258C6E2F7ED1890FF0D4F28E935B41FEBD17A41048A35B9AA2F15D1D32864DDE6D8A82E65C17615C71F04A2750F5D9C5D62C24694DFFDF1C900733365272ABEAD17DB695B5285DD16AB83751AE3F63742C5F87806950EAB68E35DF9DB0FB4ACC7409BB896AFEA9C49DCECFB9C933AF12DCB7723777D0059460A02309E9794B04E7CEAEC0AB433311BCF42AC636B71BF73AE439EFC3C4B793287E7F2C8FADD81B2C2A9A09FA1C956DE94423BFC76F791AC88E9BF0EE9493BE031603BAF103BAE535B9A366DCD45EFD324A5087FA6D214772FEE650488F83EF201E9EBB8F60B86B40B2415BDF5AEB0E20EEA5153534F93EC093431850241F7BCD4DB2B5ED441FD8013F14566F6B4ABF725B3F966E0C3BFEAFB5D0C2B6D819887985CFF7DCD647E0B5ADA53D895D14F0361A8E83A7945A99A833EB3AF65D6C9F2FF811F5245A629BC646F3E31DD9D7810BD4404A1301D11D30DBEC2DE0163953760A6C5C7F033BDE8763DEF5D396BB141788D239B720590A79D73BD46EC7C3280BF852A451FAB4392630E071ACBCF86236F7C07ABA6C90BCAE4C18338308A08C1760879A8C2E0D561981B39A4694DBAD9AAB1E4A752F87CBE6BCC9B1BFBB314EF3671E95C654B619394123376DBD4823F5498991DE817B82FDAD2C06AC74CD2F0FE13897527ED8056CCF315C9983031A10E226A2FCBAE1FA327EFCE9F7241218ABCFF7F3934D45B82DB6124897DDAC45DC241CBB42569F926A6740ECD74A9EC6DACEE48CE955F9B3B296E779625A6514AC5D586BC407300572B3693C1272609DCE114A1484F09BD7201C285C2E8CB5C394B88A1FC9A0B72F491A7CB445B3D7F6D9585FA0AA6FF2B71E32678C8B94625B69B1F008F248DA1FE9480C653974BAB0153B78AA642F191522535138C326864C4C9FC895C092C1D05659F01EC7AE7FD50C9E30C7C2E4785E2EE1A7042D6A1AD17A73996B8ADCACE9888DCFA120C8DC527860734EAD355C47136CCBF738B3594860B795ADC28"""), +d7910e2ff97acc1d1ab59e023ffe199ab92906dfd6ab2e463731ae484d0393ed5e0870cc0eddc5d81acbe1f76adac417fbc11eb77d0c7e4921068792f54c5aa194aa933197110060309ab597bd1c5ce33101ab6e50fe871d4ec627437694d6df728d21ccfda87d828ac5950e846a311e48103071ae5b66f3155d87e68c0a77d70c964008122590b029e1346d60820c40480c0c428421424a1c364d90a06dc1004c4016895b940c94108d5bb820ca420ca44208e32248024722e2202dd4c444da18814a806c54167208126591a2500a012a082284d442284ca86814098c5808281a830188b88c0a076683344662268c21122890b04891204059422dca96650ac44c1a426e02a38d021944d826208b107111024103a44823906c64021049844803c9499c326d82c04da100651897214a3685e3844cd4464e8148651c430d1bb1901b067121434e0a864453c46cc4466d10a2848ca46d0a022d19c76113c311d4188011879124086e422221c1904850369022a40411396043b08001c904134146013188d1248e91408401110e903682e2a2459810661b858902a50cc044650920494820318c388dc488001c08611c07225136068c466994360e0c200622096599346a5c8824d4180c63961024c79153c428c204815b948913212049922ce2822518c12d12994558a881990871e33432da442dd2342518274d622630981248a2805064a491d8a0480a25511a03458a30865b848d9b8850a1b69008112a1226441b9324a2146124107023a20c08233004b16403490a9ab86519a105199464943249482441d2b025d008891aa629d0a48491940989284044266041182858124ce440828348251113694b908552366663342e1119281bb2010b327209364e020142e32066232661a3248a20910820989144b6311a30020b994810836809290a0431300c954c50808091306501c325c83241a014044b444ac80852c22649c2128a18054c14097213092edba60de4220d0b2751109760dc1466a2c45189b26994384982200e84466dc4848dcc206908130ad2a44152b0092380210c121209820ca282314a282c21c7850827248a062c2195648326668c2031522020e42250c3324153180613836400c121d912808a94414ab065e4a809232190c2060013362e59128d238930081968c0040281048ae1206a0a290400466c0b3885e2486d48380e0a412e1b932422234993a8655a3824d4800c2042512199090c302aa2a8211b471111c38414b90dd546a07aa699e317ddc7e720d95e02563ac6dfed69d7b6f0091060c20f3dd65d9ae0463516f8ddac070d5c8f9cfc446f7a279b2b6b10329e69194903eb9ce9aea7b23784d6a267b62edc162970ef7b885ecd1babfe34b1eef17cece401a53b3c0a48c906a35020632709159c48bad06c7c1845ac966e4bb4c549ea4ded612acd9369a8c8852688718548f41f7c36a22325ec219b94e3ae3186b97508fb004848f1eab5f4510322b634d92bb5ca846ce8b691b2b0e242a522a745089f29253a5b3f812a054e2a4403ea7da12597bc66261bb6e2ad226e91d543fb40dba3f1dc7abe57858ad77c083c1c775108b1f2779147808d9cfc0eb56b76e129525cbc143124e7ab4fe9dc1ec8f9ef61e37de3d7fd0ae9a1980360ad141453b8be2e1b845b9f6ba64533f532420ea769fbfbaa4036b7956e971a9f71d32c0854aeb911069f2486ec8a52e575d53fa0f4bd6b87c3d6bf364f1531a3531b04db09f0b2344640cb3123a05eb8edc7c23474114c3663897e3022d3c1c49e44ee6aa0da201b6d7480b0a4fe496eb3d1abb932e7b246ca9fcee9ca2de6daf873f24a6928d3e1e42ce415d205fa4d0e7c44d29e728b845dc0d6b3719c171b5aed9d539f94328a23ff125fd5a4c048d6b70084ff3a96d5433807cd011ea4886669c2875184d644d88e9224cd2c78c3a6c5450082aba8d25c86d3a183bbca15394a965fed396568c0a11557c87b8bf7f797be047a844593267ea7b81fea58cc0ef9241a8ceda3fb2c93a28616c8aacd5c22e652c58720a2ee810ac91090ca53a10d47c055f5753373e983c457b914eea12a78a55d7f9a37bec0a609337ef580aa434e41f9030a3e9e69c8bc0eaebd1a987946a6ffec018eba885994fd64965b9be87b59b13083ce43a5d86bc5b2366c90254f0a598fb5b78044f67703bbe49657bd8da1f1e853381c05fc43bde6a0d6a952d281f3efcf9db89f8ef00d21b9630e604d27ae41d09d3e4c02953329c31829cfbcb3bec32935f68b9d466320d7af551ef29632f38d2c80360657572bd76bf26ea1515b4f31494a89c06b487ed546aefafe5620785a2654bbc15da74487898819ddfa07f648d4925626582e244538a0c3932d5e04d839c008e5e3538dc66a9ba917df7f4ade6d0e13cb267f15bc6b2dec78666a49137d13464f8707f08d525e5a70e3eed15aef54e9ad1d96bdfeee080d7eb022d79d54f9c194d41f626755a36048edfe6dc9aec7adcfc099adf527cd46eaa3e3371d7c17e4f34c6f6e0cc4e63814b148a4e8d9a60e76648111a8056405ea4060d0f6e042c3280d0480aaa3e92bab91085bfab153a1cb9a5639ed18baeeeacdce1ba2677f4eb60933111d28f8d09a558add70c6a62cf9b665227f6de4c19fa1b5d7f8bcc3a48458e67432ecb12bc6785e87f6b4838c2b1dd87aa56716dffd7857ee6155ebf64cf721b40ec05d2829a79d4d3f07a818c3e615369e46c6f475748d254ffcbd8f971523211a86bfb96f51bc6d7443f2cb2fe1ad567f8e41dc1a3a27455197dc3d8f66592497826c63b7d12f489c167c400a38d45a9ece1b579462850a3a04087b974cf0f6aa4f2e86fc17132ffec7ae947a4b0274bd54cea6a12a1225676d21aa7c72492a510947198f5c9f5ac22f75b368c74bb68736fcf4c688a41e09bf3bb06a721b71eb1edae90c93434fedbead5b1d76e0790d0f99140d328a338f99fd788c719ebdeeeb4a6fd793f7c255ad076b5bd2bc59fed6699b39e0e5f8a03bd1ad76dfecd16bd10324f1b0fcedb3030d09184899ccb6aec4ce031cf0b10541c114d56b760dd6fc630d7a77dc98095239e2292416fafd9a2cdb7c2fb6eed1d971c39cb7efd7ab31f353255ad342e9129534f769640f6808a11b173231679d244880a8541c299cd0caae9bb61b90ffe01f93395fab1fd65a0930d285d1ecb510e8de8ff93b2b63614b0389d7332f6f20b61737c29769d0a05e472759dbe68ab17cc9586f07d4c2beb47e609dfe2a00a27dff3db68a65784b1d9b4ddb1b454bd49b0adcf63155c5c7979762c2248a0dffa7d31c8486e1ed4bdd01155ddd4a5830edabc74c509bb79ae6ae3c94d34e4fd1e6944d41b8ef5de8cd11774878bede8aee51b87303a502abb5394c8dbad7636f0c71aaf4230772441f0066094421550d4010cc2f71bf055b263a0b53bcdeee45b7517eaa4e3b4801b09bdfca83b45c68c52d8f0dc7f8aff1aaac45e1e86be07e61a6fb65c65f1ce21e508ec0ba3477c0bab7ee1c211e071b4449f3ae379e5c46fc4ed23c99de77e5675a026c71a90696528dc29998285f6d9a411cd1bbbf3fcd522713e0941f92468646dcafe9db8a"""), TestUtils.hexDecode(""" 3F1B179FA452CFFC1F4776B275BC9DC61A4448989A5C74AA4F6A42748E49DF12AA62C5DA238BAB9F4309D563EAFD739B54E8957C0E91DB05F63B2A50F11205F5AB60B0E857F1AEAFC0562A76626AE579BA3387943E8B735A4B1CCBD23A6CF56D7F38CDCF772ECFDB7CD40781EC2622C10D65BCE780852D7930281726CC2B83C8D8179D842CF3DE761B071A6B04A383624398FEBE34CD841CBDF9C256A5EAE3973F0C256F89665A0B23F0B505A2EA73F37EBC11AFC2C3D4FD8626EB86FF0267D00DBC567796011E5548C08208CB0B43A880C1590CBBF0549683BC71A8BBA2CCA5F98011E592F3B5D7C8CCA0165A58BAF8CEA629CBA860511EA2E86B4CD9E721E8D7DC608504114EA98D016C0C0EF67EEF084B8FDD8BA4825A0615F7E09C42D935D9AF0DD847C2435D84B4702ABA573499C9088EB21CFB97E5B5A847476FD25EFE2C2763429048F797FDACD8238937024E5D66B3FB40055C3DF19E213E5941095CD8FA62BCA591007D03CFB879388983D6E7A189782F36F88EE409D490C5FA66B62510AD0D0EE9EFE6DFE23139944046C62EE639C0F82E6D850770A69577DF6034084DB97E4FB2BD206281A79CBBFFFF8A9E4B70252F6F03DE8FFDBFCB0A5267877FED3893CBE5119F0C6930FC0DFD82C63CB1E7DE66DF2141E184646151CA8A927DB49A3EC63B3B862AD60551B0E562F35E109594E4E43B192BFECF066B3C7612BAE0E170F0E1D7D246CCC3A2F94D3FB08BCF9DC7DC44735E258B1F9D0D8152EE79FF9EF095EEC3FCD872D9584361A44B9BDC88BE2AEF1158D1765EB4DEAF441F2407039E98DB8D148DC8B7EE9C44D5833FFE4C52A077F57D9E36CB220251C58F61759D18E4E449E72F29351F6CB08F9D996005A33EA695C21FE883E1C3BC3DC3E8239F2BE16FE445A18AF83639156521188EDF3F15ADB300A17F88C829EB72275F6F35D2D1A72B79A01A50F1A63741A8B1ACCC35E49D331DF670D30DE8855FF27C9F6D7BBD16CDE4C4C4DD48CAA971758D714E89DDEEC7CCEBF2E89F8CF03D7E631B9A18ACCF19FF35AA24AB6A1E10DF105FFE2603C30E16B7194AD615038FE96F4767DB8882D48C97514CEC057EE636C9FEA31BDAADC5CAF6239A805BB05081962A2A5054D9DDB47AD9D3C98D053A5199A687668425139998BCB466364F656B1AD9F13FCF7FDC50652841EE475D86AB89D0CFC01C6B5B876AF9D0312A43DCBBC71B2714B0C3226967A3D1E0AD7E9368EDDEA9120B2C8641EEA203F2E943F43708EE6CDBC6748A33E3DBEDA2AC492A6DEBB9751E7AE4AA33F6ED893AF7054454467E29D7EB7F2163FD24F7B5607C2E77DDFAF72E983AB532C6585AE8D78757DA904D1FDBC10768E3E70D582F17708B51D561C24EE0D5A26559EADF5463097155540F26EBCE03D89F49D7033AA00E1DA5ACBDF148DDABEAB739EDDF99A6B2BBEB48F83E3516380FC7AA9FFACA8DDB53388485061EF5B94E92443C24DDCA823E44A29116F346A22BB3DCE7022C3E2EF35ECAA91CE5F65D7C5EEC85D741ECEBAEACCB39F881391EE2A06BFD7B72173B171B7D11C8792F0A7D9A125011294296B157591A675649716F92234BF074F78EAEFDAE1AD79E4208C6338F42F2A9B105EC5C717301C638C63555AF0A81F63D0CDD04F9C22E2FF223CA5AE1A01C7FC61E9DA4412E80D493A7C0DD49CAC10C62A7D3ABC1B9C74EAA2D8AF248946EF8A37F1F7017E49D11B89EBEC111D85D7C1512EF4F99BFFEE68FB588DF3F39735169D1B5A647D71F52F76C6BC09F5703320DC92BBBE6D7CA592566483636957D235F5D18150B6A4641CED6276319244CD8EBBF74BC5DD3AF82E6C1118D19ED291ECF84E4EC2FEFF28286898E9659B01A37F4612460B34DA8444A4805FDEDCCCA5D6D8013335B4139101F28090517FACAEBBEFE59E44A969FE3B8402D690012AB908EA590249BD9354D456EF65331608478B2050F985C5903FDA5AF0D918E7F7E167C3A669B727DF0CE96B63D4D944493C5D2BCE97F2827CAF54103A18CA8CC0483BC8B98C42657349B8438C0274E4401463CB55E93023BA114FF8CF3A718740756DD8C92958BD07A304FECBACA3CCA8135AAB901AF23E1104E202395A08784873E03FCF2D07AAB003E6581741389C238942D7A2B9FB30B53CF5D0C408C0EDFB1C4FF448D745FAFB0D659B4BB76B16D5B61B0A38039488682907151802A815AF220F82680E523E838ADB47425369CC421DD36C2E60100A9EA7F29B05D985D644A7FEA573BD24B922396A481E33306AC41CEE9DD8ECCD9DD7833F8CC77477EDC2E97A72CE2DD930BBBC58FBFDE78DDE34CA1F8DC758CFCF2ABCD35CEDE0657B35583F9C016524D3AAA5E698BBF85AAAD01D7D3CFFAD4602858BD7E2F173D6A24504E448926DEBA1F70F3B0D5B454B02AFC4D0C482BA8019A0C209ED071BD2D5B341EE06FAFA7FB0D1FFE77FC6F6C49F78EEFEC44999E4330BDF33021EBD91DE8EF2042FE4C3F19E992A5E66FD9BF8E3D428AAA8FA51C7C761C2CAEC8908DB3066D50BBFDA98B82387E92611514605D6CBCC0AF9FE08B39AA1DEC89CE77987BF3BBFBCF362B4AFDF12A8A1ADEC69962A6FB26610C816F023D87E648A77DACC3997127AF770658921DCD300EE2C8C0916593067B3B31ED1B6B73D68EBE68CB22386DE39E57FFF6AD766193F99CDA751316A5B0729FE5307C107FAF6DB4CEF4B1C6CDE957DCD6361606A6606BAEFD9A1AE08A5DB21991F022C4BF758D16FD53D6CD41F637F5569D7357CA048F07F53C850CC56A07A4C2F3BD04DEAE79498EE10B366861EA82A7E04B9202750D4FF4017239BF1BF7088A3F2E2C79DED5A12F75CDD754840868754428BD7392E4F01F36E3B450A9BE5BB95FBA71C960C7D09DBF24E6662C86D8B5C3E37D76B16845B0F88C40AE7360545B3304DA5CBD2B58C29F6EDBD794E9AC779227B0FD198EBE3A172FF4B8896F0C9BFB7A4FD9FE6ADC73E097046FA25CDFEC45CA1E7FFC4FD582DDD8C79A9F3959A4DD7E3473D6F242B0A6AD4DEF109C12DEC994F2E313EA1930ED25CB401B82212E86150BB53BA88138AE3269157FC2A7A919E21CC068E0B9E934701B572AF0E20FC2CDB2B7452CC1E5545AC4CDD34EA0097CF531FD92E3FC38CC50E1FC8ED59272FF3D631FCC239E4AE0AFA46419863A166DAA2CBC63E24C26ED7EDAE476A194F8BFDD540D640DB3A8B294E0DF0AEAB7A735589E23CE524F534AC82D80CC51DFC08EAE4FD02E6F6E0BCDFA0FB23697EE1AFFA735566223A70EAD827DD31881A3C2471677F905B64E6AAE00467561FDD6C79B45016F1326D705A854877DD91D0B147071B00C5F8A600116487D39284F6334FF56F124951333F723D68465B765B32B396FC4C432D51E8C6A9782461EFADC2CB93EE38D4945833435E2E27E17CA98998F9B33057B1C73E2E43B6A184868DA05559B3050FF42C76D7440E1A5B803C8D4B0CBAFF9FF31C7E98FE2D011B3F87416889A81DF9F48643E943336430602C5B44C1D11BC7F62A0D67BCF9964815CA0AB83E7A87DB714F2C1872E5B9F0843B82846516E54A3F7FE311839F4910AEC6CF0D23F86BF2B0B05BB71B5B47E93B80F7060A350EE4D73EA09A6D489BDD064763CACEF5818B319CC973FBBC78E01A505A2F6C4F6812819E02A573AD8F7A345763943B623995B0634562479072D9E42437FCB2D02479DBAF2D088B31EE870F11047E965D04524D0CFF90B943B1BE969DE752249E8B48C609F14FC48692BFF40EA6095F1967DB766C8B4E18FA73DCFEF18F2DE1D295B51A63880E288ACED85B188B3D10A0B025BBD934BA43A5AC5E1829DA836EFDC88F4BC6BA0F4F23A4AB16DEF3B5488BF6C974EE1BBA51D17BD472C731DD35D5B74EDDD3C9177A3503D783968BCF8A1F2549F70069164C965304DE2434530B3841A2AE7DD47DC5FDD9DE046840B4D65A08A71A3D15778865CCA2418F154403183FD44B622982C64F771C87E18C09489493E378476B3B1C8D14C8009ABD3D1A51CF806189496A4D70FE857822049D3DCD4CFECC2F95D2A8A16D94DC6703B4C4EF3E8C7EB9D6859350131E1A03EC8A21E13F045F822C48EE3E3A481EECCA508F189954AC267E6CD19C80F8688410E2E97C71A6C792DD6E33EAB2FD16B82214588B923AF6C6069387F6A72CE06033913B50F0310112DC2143802AA2CA066388C96158AC154C33E9BD72C993B410FE5E9D7CF37A30EB85A127A7773ABFB416419A5B4DDECEC10E2EDB312C86C3F3C8BACADA66D057FDD40740176D137B1F1ADA098D978CDBB938F45D4B7814F2C5B894CAE249CA8E1FDF31E81997F7C55B7A43461F5C7C9893AD0494F4F0272FBC20D80F327EE55250F9560A301078BDCDE94D72A7D113ADC7C739D7AC2B8775D961F89245C5AEA8ECEB1732FA345FCD84A0C07C65F091B4B32DC4E117D24D782C404E8FDDFD6E9E65B3633985D6DB8CA841B9F9A3B3C617F1D69FB454045C5024AD09C5C1080F3EAA64202C08838B42E218F56422722536160F97ED3C08F285EF7BCD1119BDA59DB5EC6BC8E9DC1789B3CBCD469A4BCBE1CE237366A5B51B062D0A08201D4F0EAF6F8FBFFE53F35999763DA2470F2F9FE79BDA60285D052D65DABFBC43659DC76602DC662A3357BC3E4BD07BC32AE5B5E94D7DBDE4B5117BD5A9E3461021A569E200CD3CC518ED6559BF2539D8DAD74920DFEDE8DF8FD8333FA17F0798A17B5385A9569A640685D7365D3DBCE8411D44B17BF79B852B1348AB31335AE013B2877C1D8AF62F88C5186B7313F2C8736472FC5F2B4B38F761009F7623292EF14A4A4006305CC419A3ECC73082F63BB2CECE6A624C2A6DF29DBC6A4F0FD3658C58EE694FA58741DED54889994DC6A3DB4FAF5998B577EFA399E58D822B99623D76050736C17B5218671FDA3BCDF7E81B3E85D87200DB9150253ACB07AFA8FEAF74578125E1E26128116A7446C804DE54FD2D2B1A48E684F73AE91932A37372DB66A230AC4CD54869A0115895D2CC494E6D6E8B12845551B4F3DE0B3A4C114979F0471311434BB3784FAF7F9A9B88D536235543ECED732289B383E8005D98192FBBF41EA8026CA3A14B6895A6EF0548EBEE58C25530F56E0EFF157DF6ED0ED0D5565E9FD474B38EF5BA74D24B82219F317AD51F3E7D6F8E4BD8836B91525E162DB417C87E36B3C0FD874FB4BF4136926AA6D045033C94FD1EDCD69835A116357F341372148C4601CFD84BC36A8E5B2260B90CA797CD5A41362C44B4488399394AAA431A63A74B774E68025D7DCB1963911F2BDEEA60DFB24E87196FF38479D235C98E83F1FC419C87F708677F98C84F9C4848B255DEF2D92E3506A533D36E56DF81F6461AB5BBE9D171ADDD39FDE7552C5D4351DB59543C0FA939ADD6130E25D4326566FDF49CDFAA240BBA0B027257D2ECB83209329944E8F44AB785560DED2BA8EFBC55CA31E48F4C94749E4D205A50BEF3E3F039DEB3EECB213FE92C1C3E98A9F72B6CC316D6C0B87BE7F688000A2433E3A184A68722D44C7F6C90F2AD0B248AFC9E57448E3450888A875CB3006E27C232963740B985484E7FEB07775F4B4FD89AF6F627CC56CA1AF23E3BDF61443786D3F04DECD3CF71E2C6139B584F52B6B656CE0737F50BB270830B102B781E621B3356CA16019696A23EEB238ED74D160269A3EDD35F7ADD9E065F836A61A0CDF99272956555106A349166B2C299B8D0066581DC3608048DD8BC2F267BDB2808E1ADCD37A7538B9435E9E5D7ED4389BD2CCB6E926A927BC6DA19E8E0E946442A6943F65C56E5AB7507FC6EA1DEDEA7C1AD087CC005914CE80A241D42C88380A49BC4B6850536C5A99B6423B77A75FAF76CB17479EADFEF1FC90B832C8F36D92BA3E927C9D60473117267AFE4B115E39D50AC7991BF248DB38E8C99784848013B48D4CD6E034B93E643239E78936DAC6283DB748062220071473B0579FAC64510D033525D786778C53CEBC3BF95C4FE9406943E9D68E17EAB3245C57C00D0C206E3343D8201A2F6C278DD61D0CD42B71CB7064ACCDD38551DC554007F29E1929EBC81025CD1A5AA41510BC5CDFF340F42C4FF6DA37F8E97F5911F37ABF457DE3EAB6114DC858C0C14B9BA5B652DF63D0CFFF4D6F8103E0FD15D87D8EDCA53FBBC70E3B42C410F379BF77DD17F6FF57D7A0D01FFE0044F226F8D65DBCD1803928B29CB6AAB703A0EFFE4EB47329D9D373954F0F15CEF2577EB8F34665FFF2C774EB07F0CA72ED27AFE6EDF158C3AA193F3B5CAF99F52430A3662997DEB386DCF0A6781E42180ECF44E9043AFE95BDA84FD1F9EBDCE26EEC0A4A08D8423111B320EB87156BFAEB3827389108E12E7AAB3F6CC8EF67A7C877BCE3192E503608D6F1E5697941FC1418C16093A55A2ACF2378590F4B0702998A65C8127F13AC98BADEEB32B152F3054EB7D0F200322E40CE632CDAE8F0E6C22497BB6D464ACBE9B461C5D39AF9334F5342FF31C9273146D20F5D4BFC61F980B1862BE4A147474DE89A1A3278004F2CAE293CE2709748507C5DB48D98B484CE933DD3E925E1788F2470C91177ADA3869DF6FF81308DBE846F50C51AD66CBEB2AC91DF1C86EC22ADAA6C702F1CB7A141778BF957663060725A5AD6478E22FC959FE5C918EF1A11964E66B1910018DF4698543CD3015E9876AACE37988370135BFD7047FBFD3996B45EFAB6FFA70A4191F259B8A27EFA05E7E1C75285CF70910465589B41A9D29F51F7BBCE06457A3DFC540608157479B499B2F0CD9D8A8D6F2C01FC79E5079597FB6E2D1C3394B8D8AF65DD133F9D9300DF3DA3D740CD0E7E13EF62BE1D29A3DA6745A5A87558F23D89319BAB09A15F8FC01AA388E1FDDCA117A27426D142094A11E6B49E2C541A82C685D41D6E2520881534012774B4C01CE3D2FD8FDAB8C25E4F0AD1292974C4C141173CA219C07314314FDF94A05955E210DE13F0165C990227EEDDE23A52D7F4C8A181C996D0FAF6C313EB74BBEA4C2CEC0B7B01698C63C2E1D37313B637271DC49A7EED8542EE8BDF7C7D791F7BD59A029419616F9C8F478F060B855CDA73418D0AF090844FC0066DEA9DF8D4F3C9ED58CFED2A78B427B42B033C46485B767D75526DE8682D6AF0BE91169650BA4ACC4D54E0D357E993FAF358BEEE3F7F988381EDB31FBF174239A345130BAE1B0DEAF27BC5E1DFF86B29712CFFAB670D35D19DC5B25DA43D481336C0CCC2120427F30326FC74503548344B585C082A78F96F072510D50E1110EEF01617282CB681CD352A23607C3CF7AD9AC06FB52B38294DE8F87894D25C1D278678B048E3E3F4BA0D884154C5E16780BAE2322C389667A15EFB0B21718F56767EE942E4BCB190CDECA74C92DA8848F41AEA2328D29B10C95C6DFA74B0E162591B1BDC0ED6826ADD0B04C7495FC30E586FBC03D4E871915AF71866278F9CD1B4F1AC56E8E1B7B11DBF0C9A64F608E1C3958910829654057103BEC687A02AE9A568BE514187A3E27F3F9928EEE29519BDA0065179423A7242EDDD8CC337F0B7E7FB7CF90FC682C9E60253BD0997F34F9081FD785712E52262CD17C3508AE4D2FDA3BFE232269ABB185E635E659D405AB12E17A80AEE5BA7DDAF1FAA819A284A60B85B49F1A57DA72A0866B2B9C2D28178995E79D4458B58EDB187B0CDC5C37F111D20371FB8F410A7EBED95474859645FED6F451A396781EF7A02E6B52593189EADFB1226316FE8DF79B23CC67BD2EF973CD561DD612D0C3047698EA0D3895A28B4111938F0A0354E4DA7484697C85908A3BA3E80BCCCAFC73303C767BD3587C1F9D48FD4DB93517A561DAA10F53F330ED14CD65B4A54FC43E5F5CB421B8B6CF7B83D86CBD72A55791588D4B81094BDFE45E3F32A2C3FFE809F66FF310D66032AD6BAA5B33E79F1C476029A49D49CAAE427D8A81EB642B15EF0C544C9EECB7CAFD2A854BA79E4D7EE01A96CDE9EEF45E430EEFD8A16D5D22B751F981667F36DE2E139391980DAD22462BFF4896D277D89DCACBD5CAE5EE90BC2D5954C083AADF632D9051B782190ED4AABE8FFE195000A6BA05115EAA0BCE755B23B10C81DCF4BBED61E6D31E9292DC1A7FD6B453EBEFDE55D6AD8866CCD50473705A24F519548172D3D9F92E668D679D782B7F1041E5A558A625D65E679FC75B15499BFA304435FEE6F6498138848BAD0BFFF6942029BD0C5465395F5368692D6B21B2E22A638D6EBFAF3A0EF1F9BDEF8529C6D0BD328CC82BC66DCDB2F5AE20F53B8AF66400D6C2C0A3C6BCE1E8D2B222FC54F1896E58F61816E301365E12866C1BE7C4BBE0DBDA2B504F0628A4DF1EC7942BC58C0A4CED0046D73FEAF2231FB9FF61C0F7AA564EC1E10BD65B693CFF56DDF3596DDC85CDECDF7F123F9DCB27269A7F65A435ECCAFD89A211C829BC7F5916DDA61959AA296505F6D46543D863F2D3F007D8960634841CB317F5EAC3D3A3E4561801CDFB269257FBAA6A60E7A0A1980C9BFD6053BF2EEF7414704C7160A051355CF48A0C0F6FFD683C453513F8212364775B7424D9315A920DCD5B140A8440EF7E5908D4061F580022399509C0ED416F945705A19FDF8E65C8802B67701FA1D15F06013990C7BB8D0D0404679713222924DB33BC659FE58F82A99BB1AC551426A13C2CF316664AC8037B41755F110F6441C7BC9446430D7BF917AFDB8FBEF84E895388A68763E0E16F89FF630BDE9732852B70A4A3AD8A29D2A4670757AA4202DE5D53E653848FB26C6031D07CD010501F0785D1B1D69BED49DC3B07265D51A15A7C432C3EA63A0B0D228B4F8AD4060DBB8D54B94BAC7F2179829C8D9F9CE4F7BFCCB472EDCBED73B0D18E3108156FE659CAA40B45016E0EFF20F81C29EADC8B638364FACA6FC85F98A9BAA9BB7E5261AEC6786C18487B14B77ED2B62B762D6B8B39AF5A870EACD236CC53C016158DD1E71382475657C512EDEC0977320F1BEC79D0CF39403975210DCEC3ED5B58F"""), TestUtils.hexDecode(""" -0E27A9CBDF2D81A93D2B091B79F926B66598283ECDACC0D1F1FC71EEDF8A8CFF01741193BC4A5AD7E14CAE78A658DE7655C93D50F88FFC5E4FC993B7D936F7B7E3A7A0BC50C84190D300032369A74367D1E2165307DA61D4255CB55B12448838C0783F61210E9E8003814366A50DCF6F7F504AE587598FCD32D00A026723A34F040E5ED07F849A6884C1E96D6F15590BEC3E3134C48FEEC6AA56A746C218C7B40D5CBF994FE3DC3EDBCF546DC46907B64B3A438785544F9E33C78772F568B206B43DAF1315B0A6CFDB4797C127AF6F47F605763EB9FB0547976FC486ADDA2597CC86CB461A3B1A2C02D600039C2F50AF91BF47DD8FBD791155FBDBF4709825C2B5D302F5648CA842D6B9021938B6569DB7ACADE0E7A13661BE3C50C15AB3A4E82193BA5A342AC17A24263EC52B02857BB78C3B7122362C22FF1787DD9C3686DA382CD8BC5C70B2F16C8917AE820371D813D8367176DC993F72AEDD28181E57C8E0CFEEE2C81BA538655D888875E7F6831B1B5178F3C2D3FBEA81C12AB19E507F2F4ECDCD91D1CBA519816B87F16CC48D8132DB8F042057E21C635CC5FE3BB7D695CAAAE0A2D35591614E9FE2D1C47FBBFCA82EC92E05182D392011A48BBFA4788298AFA2F5ED2A4B2E933776AB1FDEB35C6EA224A69DF604A2979E826D00134AE1C13A7F2A17A0B3AC498804F0EA2D545CE3E37092D672277C4CD051B652332CFB8D1DD8ED703080032E4A7776A19828903A857C574A954A93EFEB26B0CA40A6780F331EE5AA78EA847EF4A624AA0B37D90BC47964B114E8F570BCEA25308CFC4E13F478861851E08E70F8188E147C1F17A769C868FB37A10638CE2D95F8490D2B4145C302993459474AF385794E4097D1E6B3B8BCF29480B25CDC9E8127C07F701A03452FC6953A16E864D6DF32B2D746E173EA181F2939AEE6354A940454F946E9450751864BC74DAE264FABAFD2449D7E51598BBA2D1816B3E912767C1DB51601DA9515DEAB9D34AD7E5F4072AE029613CD5975786FA16A7443F628AFD31B5570DAC44EEC0D41E9F2740502A2B2B6742472CE59E900DF6EB15A3B8D37D05EE0EB56F1558A2318D40C6B7AFDA5CE952344C8D27ED5E22FB57A5B6629D2B901BAB796ACCCE5CDA605B5B9D276F082F495D65EC4E96A962B4D373DE2799F5F4AFD748B9C2495440FFABD7C76AC29F0EF930FAC787873D0DC93158325649821D6F5BCE89C0F46EC9EB43406EF0F2F63F5A9CB90E542D0A3BBB219D2D174377D60D845677126DD80B62464ED3DEAEE110018B29D0354662E1BDB4BF07BCEB8DCCB73F631385617C9A9944B9E6BE8FFEC492847554B1DE4EF5514E5E8E968F69C98133AEF51A75E0FEF2C60A1CB5F1F8CA4855C5F6CCB4ECBB696189948973EAB694004BD998D0FFF5E0B5270C71244D57011835CA161E18928D1F03F515E5A271E46093F2D43052B9266373D06D040C3C735665941B9BA15C9ED03D0941894D521B3518C970C0ADDE281A863F1B09076C9E7B377CAA8D5A3813D7E9316B3E8DAA28268D53DB57D2A1E4A64758B548CDEEB8DABBBDB81740386412B2D3CDAAD98B0E90F98CF39860A11C3016FDCB87D8F83155EBB4623E3F57D1CE98B25FE024DA73449441416EBAE515FA4CB1139C6975BF953605FB1B5CF9FF952E674CEC3FBE66AEAFB1E5D3EF0E3AF3FF9FBBE2E9DF971E8D6AA5A79C0C3A4D8F4D18313EBE0E00DC7D5C913A879C448AE8D31CFF3901F14FA7D1C1C1517BBAADCFD2F6144B2FFFD3440620594CC5DE9B96B3F509BF13F98098187353094EC60D93A57EED58CD91701451C86A7D96ACF611A57F212E27D2EBE0335FE030E391DEDFC2CDE76AEA4643BAF0F4545BDFA7206E14D4146FD203F9E0ECEDEFFAC0363E210C4777017927A4871AC70725A3FA8F593BB9AEA1B048E07BB6BDD718B27F2D375B6690BBA1FA85FE48E8D85CA3B35ACD83B568B286D19CE7C5E0356FD18C203C91485E2B921ED491E59EA5A85796EEAB8208A75A57E0CBA190BD93721022C0303463DEB4D149044FA1E220CE7B253AD5564191E1CF998535050EEB66823EFC455AC058325F1AEBB3EF0FECEEEA8A9DF5022411E04FFA1AD7FC67692E76AB3E9474D461C815A77E0B08CA7FA5940C18BAAE2A7C93C7501138A7E071EC321B4BCC684AEC1546195261F2D07676E8E4F36AC2355D44C8412DCA71BB769AA2B459F285819CC9F19E53DCE686E24600344A32BAE91AB109F01DBDEE0A86AFBEDB1689900659388F2D57FE151AC876620A4B270DE0F9AF057A06FC9A746377F94FBAB3BEB63A96ECC1D26B055102BA7781F7EBC57F48D1221DFF5AB33F9B954F89B1EE348E4809219572CD379B833D690249F70C22D28036A82EEF543926922365643A92FCD478171AEF25B31CBB010164326E680CD247B85B1417992ADFB613BABC7B0B19707D9331BA1328C9677E4DEDD041D2259BB4A296C338130A397E003C34AABF3142DC4DAE8F862A9A9D7A5B8D39647AD00EFFCEDFA93C8831551A4C5FE1A6A32397F8ADE69557EF57C88D3A7EB14F4E43789148A31BD2E8A39F89BDC2E02DEB4DC2B337CA72AB3E00462A1ECC7D212EB18B25E88EB05897A3F29839F840909552229718B725F9FA2F23A4BB802BD9835CB4E765F422A10336BCB804EF6E5042ED3CB9F52EDEC95B0728B117736A0722AC389BEC0A0E593CA4196B857A7B89F23B219E48AD233481BAFD9691A35D929BED17CB12CCABC4BB101B8B413ACA50F2CAF472BEF9D3FABDE8DBDCC9531F8FE67FDDA1CA3E9B790CE4B0A0643A58B48862EA3D6FAE5972CFDB0EB6BDCC9EC1245BE418B2CFCDF3CCA609A132542E68805BB2987A7962E54D95F370F7AA9C869EEDF525E6DD9465A0A1B2B93C033CEE24C849FB41F0313A98FE766546E430AA5AC928741D19D39FFA404D070D401B5C26FF44DC9C7F928D51AE42E1FAC8AEDF8EB71BC96F05C5886E47F8970F071358B534D073380AA2037C42F69982E89B3B76755F7E5E1DF981370467B7E0ADDD97C69B21E37CA263F2BEE9CB46EBEAFE7C02629D31DC040187DC375C72040F5A43B35FBF0676417DFFA21F7BEEA23D0545D9C6FA337976F0E62E25647F7A377A965EF2C5B7EBB6D074308F93BABA96A9AAE838C16EE7DB31A64A4E3F6C416EB9925A3AB70757BACD418983A9D0E23FB8AD69083A98137D640B440A68594C65788968D3D3092B319DA8560E6748190D8A07B76F70D0E3F44F4557BC2B604A37059F0A544F184198C4C22108315DA78F45AA217AA485691CDC82AE5B06EB6D787EFD0A366DB7F1B2C2F404F50757E88A9ACB7C3CCD4DDE3ECF1F310121D2E304771727E9AA0A3B8D2D6F9051537396B7475808D95A1C00B233336383B5D5E65788082839CAFB7BACAEBF900000000000000000000000014243044""") +e870f21e348b630a1326a0334c872302d0a6da460dc9a0bedb6daebc027b22b9b332c967a2f5991252bccc646e484b83d4fbbaf2887629032de5b3e1b86002cb089bbc58e35737f8c07a694b5cfd38ee3976fd25244e6acb2ccaed20d926af4c9c7526475cb89a72a26ee9b2a25c29128d53446f797344d3eff20d91eba8ba9d02f939d38a775911604124896569964fe5f835df7cbf044f2565a32e017caa93a8848f7c4fff257b885374a6af0df150b79488551200332d176955f304d86340a6df8f98cf93dc12909e1693ce62de02192e63b8af668a0fbb2c345bcfb9b5151131b7b4c7d7eeea48666a8219d5f8b0cc430443ea3d531dbaa6360e51a842fbe1e40ec5fc9ecf9bf172570bf8b31399ba8f12f3b83c40205953414caf7324182657e0fbcc2fffff801c52259294f0b23eeb5ef14c34d955b92ae782739a9f9dae5eb03af4bf4e911c7e758cba1a0f1d0ac1c7256e5d5fae242312f18f6747c5b56d907a49151080485999605246550a6ce8e6341bbd1ec122b179b3102a2673c163ed7174089c10b29cf33b9b5fd1ba22dc73a164404804faed60958c6faa6a09b03dd2eed0fa8782212f1da486543ffc688e37bd43621ab857aba0b13c1e0969a482ce92e00d62ebec1870188734135b0419cb3b9f3a9fcdd68b5b4a53169ae0bc4959462b8eed39264c0b0b34e0595c7a719672abedad01638f3ebfe9e4a460cec890339595a9699db82819723ba08c7bc82080f8989d3d8709386ed1c9fc791ae0cf954e3a897a93d8e235eeb69ae131a912736fecdbe1ba34eb03206110fdb1f81e71dceea673fbb98886ee0d94cb4d76e1e94278b8f2501fea2718466802d3d4a068a2ec53029018df3eb088246b767043f843f79b5ae5537924a9b5e5bd46b19bd7dcf7f14d4c9f4dd05b2c941377434cb37d80a899ee97a5d68345cdec8a43cfef1f286c0102c2d8c9b0d07adef966992dc7ce8b9606917e238625707393552ba9c01c4e72f6e3b533a734c0d60e3a2aba08a823a12a45263b61402d8e62da3e5f5a5c12e0cdee0d255551b8af7d500b547699f72b31a91519891850e4109f4ef380757013fd57a0fa0ec0721dbe825d4cce624cdd8b7f7cf64fb31332f374f6c470b9b8a5171f25d005da4e184665430e7ae553caf2ef9eba994f34b04ed6886c1b768f03868522959fdb164e8ee825f08c4a4dce01de6686695b5dfe6102c7463ab54b084c7fb1366a0b292898c0d7499a3a6ae1995bd2139f7d7c84a0f96b497bb2306028389b983f2e02a2fcfd3c5f8a0b4d2e334d4f3a460829efca41806ba82f2e5ef585531a3f1ff67617ec112f613acafb8420a1cf6230468601cd8b0807d975065fd36aefe77111a5a72ee622da403a51194f8467a122e408a0c3998a3a7f18c2f7774915289a1522f5670527e63e6bde7ee0a84750099d949ff87c6dde67de9cb220518ccda5135d3bf58a42b7d96d14dba0ab87e79547888f6e87b4bb9ed754133d16444eca15045ba54026767e93114e8a3a75a1ff65d0f03c667a8222248119fc8994a84fdf73817bc2d61d6b764d86c69d68b7ca3ae85031181204c39085af1c7efd687fb91d00255dcc934d47228c714cbdc66d4b418112ff0ddc030dab0f4edbcb0309419120ac944e15ddedea5cd3a1d62abdfd8729edcf40d43231e378b2c69670c59c30b4218e7b7f2dcc0ded133b585ad673bed77194b98965fd4a04d93db53ce26128e481de6053a14f40b34f60a169e26e99b4b29979c03e4880fe84474f11627620d196369592c0cdd88c3639c1346d3ee265e550d470b8440c5676387769382ad4b57fac799926cba49f042833301834033d668a4f0e95e2bfdbf295ee9732e30a75b1a76d7a4f0c12029514252d98bcc4330fc2a3172bfe72c8f8202a308de53c4587a17c5e149c92ffb88b79d8b07962cdf91f0310d457c7eff09485a01481313b2aebd081c49b47558c252202b4639dce456a4e786db6a91a24a032d47d1cf9d37969d07e2acfce0067a20994310948821510051ea1ff97f0a5e88f0d36825f7a9b71d5c64d42dead04fed5f6b63dd80bc0325bef6d413644c1b5ac212bf9da2edafef2e6b6d99354470e25c5050703e524dfe08af14dd431e609be5809012ff5d0d4dc260f10fff302168b9d73c86ebc71c21d76ed34f08b12a6dc7ea174ba1c2790ad34a7b5d2e55607ab26eea6289fef0886187f43d5b98b7687b227b58692d61e6a8b9bd04a9c3a5df88e03b20c66d618a6d5a979cc0e33ca400f55918a0d2669c19817e9bc0126a406fe4816a24d06e072717435576868303e961abdef730d973768373b4f413b006c137d63fd1a7937c0ddce317078b610a5fcc1a49d83778260c088cff2cd6e35f58263d43edcb81692121d737960b77b17275765218d0b686907ddbcf0f681bd2662451dfe012db5598c061fc03920011a245c3d8fd3a8b0ee6291959a01e811957dfca6351df838ad3cffc5f28926042c1919a446cdd525d0a1b56591ee9574c16f88557d54b97cd4e077289ee304537176c4cf21e63e33203c076b00642665431183c8b6ea4c58b2d11011d1a1fcb3325a1f7cb148e0a0c70484ebfc6a460de38392761da4f101a2274b21dfd8a5b6870cefe3f1ac9fab09c49acd26de288d43326cfa68248fde5a5d0c2adf5ee4f7a87a570374aa40c904bd3052836b275feca785d29a5cf3af7df0ea226d5fa5aa33df234354a84ecfbc2e2a3d2b3cd2630b765dc0d6a7ea00884d7e805cd5b4d7219b7f5452e27b761d2734bc68d6da9b45de8b69007e6a961a73aa42eeeea30700474cbcbafb4304fac39b6dbbdd2f2a9eb5b959ef1a6efd9a41661265c70db1828f66147fdd9a7865dc9f0a605081ef41202c731184d754e499c95c19af4aaa7a018c8f1bcb1bb3ec4357bb7ccdd227f37179eadd63b10c2c10fff271a3765e9470e06fbfd3e5195ef39a52b20041507f3cc360c37608e976bc29797183feb75e61d4653e90c4a82c744b952efa874c92a675191ba7cac12479bbbe83b5a4b2e919b8e318869a9da789be9a8ae806081bee3c6376f54e5f687a2900a9e610094b6d21e4037066f9c85d65fbcfefaea7f2936aa95adf632bb83b1d5630ae48a2b8c3ffa79e44296a60125d14a5ad30e70f97e072da5b00e115313c0f3e572da51faa8741e98bc2741c8c44ab6d4d60fe0a145eec8bb91c742a0a8eb133a688d322a836a2cc4663ebf2eecfb80fdf1f95e83115d10364baa9357e1e133338b01d6ac2fc08910f7ca44ef8cfce5f5d675346417a40010b2c384a58626378819293aeb6c8cdd0141c3c404a738badafb8bec8d5e3f026405b5e6b7e99acd1d5d8e7e9fc01092d3031536062646a6d747879829295a7b8c0dce2eef5fb00000000000000000011202e47""") ) }; - // Only three are expected to pass, so I repeat to get 10. static SigVerTestCase[] SigVerTestCases44 = new SigVerTestCase[] { new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +8109bb66b04ddeddb48e77501a8b1e2431fefb69da28a572fc535be604e351cd18beb9691c57c1187703ca63921cf5df53c1a1d8472c844298cc59b0906ebf085a85a174ec9cb709aa81328db8a3b3d95ae191e334b021c966398fe2d975db14dade081aa77ad15d4aca49e87a2c376a64258219c1d72c50ca2354d78c5444ba570125773e9088d0275de193b402909c9f1e9754adade9e8103bf8d41bd81d2eb5587e4039b64bbd41525a2c2312eb17e0c47071af5bb3eab2627e92ea39cf6babf0a5f4d55208649742c847cac30a2af906c688ee987d2b9f103fafc9e86f59584e616b15ab231b64402c2c98f3fcc95cddc447741f2dc3ab4302b863f32b4b5071158bd66258343f1d045f1ff297cb287e3164593462d56df6b0705ab71e0c75ed1722611ba541254fc381f064f6226178d1354cdaa9b47c13b1bfd54a41d9bab19929e25aca0ea68d8ec2f42e816a9784293919fbb01bbefb93f77e3dcc89cbad5bad43b5358207d36d98a74626c33d84524d0263a188c3da78c9242fe1d7819bae24012800d11fc5068e351272f12ca8b57f4a6365268e1df64e4d5dcd2cb7a04e66de16cbd8092be8af5dc85c9300979525b507600d8590ff68a61290d1f4d29cb3c39a462c16f4fc3365835d2b172d1976ca92b6bf7d28a803151c47fa8ff00243864b60d80872cba15e20b1a0bee3b7ab1fc2aceb4c87c2e69616d1fc8e1bdf5daa83e9b297b3b744d1a1528c9caf12c459f78c0a4d6e62da5cb8c06a504d0d68a05288822874891e1b8bcde599eff5dc2b8e7a5d3d5e8ef1c28ce2e2a8c56f2a3911a82dfb2178172808fb81f4c171f73b10e29d3c8923d2377b64ad9c56d0cac35ffa23fe98120f1760afebd25b26bb4fc977306a829cd7dbc90c7f05a76948bac0428f93463e0c04e8d00326e57608e66fcdfbf91d4dfd9caa1452a2d91cff100538f6935e054d679390b21e8e45260cabf1acc2fbdfa27142b25c4c2e3bdc6df8bc30f26f2558caa5b68c34c87f2054cec383088bb5147791652192b936e1aa27ea851336b2e80b1ad9cd8d6412910b1750fe471f9e7aaef8cd21e1e53fa1283f0a32b3d2d17635ab1f965b8a4c052cb0e90d624b832eb2e18b5fb19c504d4b999850b03a4828913878dc519644d570a7957bd571021ddb29aae7043e18c8acd95e5a0c3ba4da989ae53422abf52e386d476d444ad15204110fa28bf28c6ea2e896b3ff5a2d58ecc0ca5801ec916fb59e135ab3e8e05b83fcb2bfa6af62c0d05719781bbc7305005b2b9a790ef912c0fbcdd9df52806173ac6d5d63aee49e10fd03191e722e68450247a7696ee3b3de8c325762795239084622abb2ac462dd4e57532335a51756d5e8e56095d21925ff3ff0f6ebd1a9bd1ab13a23607de3ceb409422a6bffde90b5d3eb5ed2b06f5d29fe146c7a3401e1741730dc5ae0ded6a98f227ca625e741a1b2e5b0d7c92bd9af5e12e09f792c5a3e45c24dee0dc489d2ff1e1960aab472c820194e3aca1d34fad159e5a021353b29be8624c6ce946687255bde401f4ce8161ae901ece6da3b9c69bf3742b31afc4258c79c8492bf6155439c787e63713b3b277e093a95776004399a075dda189b84b3a3e219f0df2a1218ef6778294920e74f1c59ec86fe1d4129c84d6dc428783364788418a83c098ffd774b13b830b3e9e5882a73e05915692134624d2a79df7b6a88f301aa200ecdbbafca0a9be8d981ca4340fa808b7d8bf862e9243cb94dc2659262cdb5b0a7aeb497d0ca6a2d1977bd375c9d9f977068d0115d4a552ae364f46a558ad29a0eea0f10ebf629e12deaaa40b916a435b3571663d570f9605129bfe9c"""), TestUtils.hexDecode(""" -3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), +430B1F46E87DDE9A3D055A7D4D6AB1277B2DA6EDA642896412126391AA2B29AFD81C246EC839929F5C06749491DC4D81D58CC989D8500B6879E8807B1C3AA0B199EB599AEB86B344B77E3DB1AA034C938D80CB4BDCC29B31B710F57C7E491D99B71E97DD6FDA01A0D8A54C7481C2786F64FFC53AD358CF31C9C875ED278CEA03F2BF732372B19252BB9FA4ABF465FA2CFD1C08684D10582B410A8E012DBD407C5140D97CEE768C6D68124B2C84113B58C9A2AA67093B44CC3B6199FF1EFA6506CC28BD30BEC4CEA88411A491DD948DDB09ADFB92C40CA50E709840BC1F107E0CA428C111EC4505C5346E74AE4AB5647C1EB80F9C07092F8D39A975C4890317F9C0EF474110AB941949029BF39ADFB8E65CCAC0360A3EFCEB69D2BD805E4FC8D0620F8E039BC046DFEF1ADB03F5995FF62AD41352D479084EF3E302578B83332506918CFAD6E3BA701C94B0138DF0CF6C2948049274CE61EE0A64E756306273A02D68F3C405883F2F668820356812B2DA3A32B9FF23608DFA559183151221F83DCA18253FCA099FE24728F302C8B7808D7AF978299F3EB853A8BECDA46B8657598BE9ECE8A02DD4B25C593DDCB436B82335EF9C6A7B8426B701C66C9EBBFB3C8405A73881DAB57D1664F3AEC6F5BA19155D89A0A80B5D01C46BC79E1D4338A50B203397CD4B16ACD597A7C77C49917E9FE4B0D761065CB89C758498868B14BE2B6FF758745AFDC535EAA605C3F97648034D2A320264150278A7F1CB114B977C9D6BC1F29295CCCA16B23B7709D5608E4095E41D08B22AEC6289ED402414787062B0DA2387B6DEE76B32E42C51788B65E815E089BCF92D778F49A9707D37FCFBDF8CEF953A48A4201FA0173529BA360BFA6A77200F57FD5245146C2CD7FE8882670EE6878386D06036F0E1BA4B728CFB75806F05BA6409C514731B0BA8DA11015A63A8B5B5AB8C69703185191D12C5611F1407E8FFE3E50FC39C3310EF4091BC09FECC11D3AC107C696EE89F74CD6147830B4B3A971A0027747B62C528F6D858D1F9E67F59496C6B4E9E03FF0A598B26625B06C79863B5F07E265A40175E1A6D6EF3F900F3C4A28AD3E49D4D0B7E4ECEBB79244264474CCBFADA43FCD33F4FEBEB0F7E5928479F869D6A0FE52EB0CAC1232D7F674A057DEC4C2248934A40F5E2C9CBFDD53F71FC3BE06E48E13398ED426D8D3CC82118B7E8E5BDCA248380F4E64C427D1BF2384F60F6A07F01EE62AA1746CB143F26412547E7EF0E8FD1F2DC606F3643DEAF330D81CD6309465F9ED7F34D9B175FE1641D90212D4FFFB91CC300E7DFA0C555F7B35D2AF6A343D1467436EEC7AB95F2C34010FC99D66391377770A7DB8CD4D5C6BBF931092322741929F790E037318D6ADB74B4768C11F0E4674D18185DFB3D051725F93800CD38F58688AAC747F885908804D6CADAEDECB43131D75B18FBA2D4BED8D9BCC2156FB23F8F6378C622153EA8301300D0FCDEF1E2BB4E6F807784EA0171E95C372EC19B05A6C7B8DECE7080A057D29CE5A445A83410EB83B174590647424736A3B6967BCDF8A416A51202CE3F00E4D97DCC2C48A78D12CDA98E94A9BD6CCBE09DAF8085304F6911ECED3547DE9512461E16721322E4E6233BC7CA360A9004DA5AE064514603EFF0DF4E2D8EB04E9574C59F3AC14726C10100C688203F4960197CE696730AD7E558D7B939E3E6E7EAC4E70A7F6AAA80C1F1546E282B5CC7AA193213769B137C7F450AE5410817166F29F2E4E7E962932DF282A9F08A1DEF3E19C251F95611DDA9CFF4E2FED873439B45F8451B9AE06C6B2C698778BC4C742708BDB54CB35B686F0E7FC856CDBF977AFB663DFE44F7FCCE0E0555BE81EB28984BAFBD6FED3F0182F78A1396AF7B7081280864E5E4BFD7C52DA28BB5DE5FFA211678D13D41BF825F4B21BE1CBD29719ABA341E7B0C3F101CEDFE2F709E4DA4B5A6D0C021152AB546837024F4DCC4C45C132A038315A0F1D69AE768F70606D070169AE0818685C4BDB7341BFE15AA0455F535766FBEBB50875246A6DAE86C7B9F6F3A9FE01AB9928A99C13E6628431D41C1506381A63FAAB57BFB3B180F5D7FF59A434233EBC5A659B71CAE6970CC838D5FB638676216E3B16E8BA6C01349A7482AAF32ABD17DF7FAB8C69789F0194022BC4E62B6A6AAA4CDEF13B1E3BF5E1F4FA69F82B1EE3FDCC16DDE1106E3D2C41F6E661E33984DE7AD6021EAAD3E64D8C9CD7B5CB538AF88DB82FA048E5705EFDAC0EF479827EDCA0255BA60771A5EBC716C690CD3AC840FB6FF462063503D68C199050BFBD64533D94E093A47658822A25D54CBBFC689DFCBEB1DDD5BC6190B8F02C6FF3D001AC63729D35C8C50FAD3DCA2E67C5CCC6A8799420B159C7C5CACAB958B423964C489DAB1982A4E2222D700BA5AB772C4A11A44FF64018AF477D054217EAE28FB8E37595941FEE7AF87FD44960A144DB0CE2A44B33DC79B1EE31CAF80DAD620666D0ACEA76841EEE6CE81C6FF1F6D1027502EF89F1595065CDEC19B30E4B5314EFD64031B3B9DDFC6C95A4943247ADF7E4C93350C241ECA71260A454707B84017C5EB7AFFEB5DBB863A1CBDE0062C662308A2E824CDF6397863EF78F62319E2873B506F8A9EE82135B803025D962E609E006961EA3F7B67347518E70D9273893D79530F67CB678D6A8D28A0342BAF904BFC0A69AD575CDA4AB73AF22B52AE5D58372E0C26795CA96A16B8461AC61E6F68433ABCEFCBC16B857A89C475D1A322D34266539A17D485B8FA356EC3E154D37BAFC4CE75829FBE8BC823FAFF15A49F847C286F999A1F2C12B03E8F8A4C34A97588D91971279FFCB100EDB943E636F78ABFBAF88BCA5C55C935F6147E51BF798267E1350D2F5E3F74B339F6EFE86208C5BDE149C5B71056BEE748D06614AFEAF6DDA2A6EFFBB56B0880AF9B201B3C12055D292E3BB556240DD031C29A67BF244F59112BFB6865EEEC1DFE1CDB1E27F0A9E3372638FE4407099D0E54E9A188079C8BB9470BE6F63C83612D80BD60C21B251B64236E5CAF09A11C12F1A5E94F199DBC7C9E394C0B0E07A583E707E5241B8FB33E39BB26C31929F39316F4FDE206493566E17B51CE635420493176D8FD353206EF87F0994F039DF8F008AF602F50D7F9C0051B56227F3A2ED20B29611219FC4376234EB900093A81389ED00991272B739389F1F978A92A3E41F0A28985D697C01240875AC46A82B2FE94004CBD7B1E7594AE38A9DA0E84FE7E122482BB391538EB8E85AF9DC022CB32CC08FDA7A95165725EC29A0F824F97F0251BE636B57E0791A7F50EE190D45749472B29A674239AF95B373A40A6E0E09C674071186B125EF5AF72CB434AC0AA990341F063EBFE30963451491474B603733959A23A6D5B8A378F15A5A5B9CE4BA44BAEF6AA531AF5097ADE73F64AED0A541784119665F548FAEB447DE108AB74A74893017F0A1AF84AEF0730B555767B0CF6AE502E7693374D2E01C54C64E411AA93C96DC5FA010267B387299D4376FBB190E1C51A560871B559FC800D82ABD119A5732B50270BEDBCC8A636E7499149AE0E47F736FDB71EBF1995D1E8BDCB0EE96E732E8C2509F98717C3D174C78A4A2BE43DD89195408CD300505A219305809A1BFE7294BC2EECE6D98C768A8A1E0F74B665EE3D652AE8E008EBBB11F0D2148E4E5C93D7FE0190D27B3EBB7D2194BFBB624AF3A894CEF7AED571954D006824950A981F4ADA72BEAA0D820C5DD9BD519D39BB7915681F266DA66D49BDAB9E55879B953A7332F877DC5F5CC7BB3C9E1C1F2E41EB55EFC02A450B5142514F1E06D43E48FBF5DC80DF241169D5936432BFE9BE99DCB17293CF968A17F3111C884635EF2BEDFC87DBB80BF25EE9BF57B55CFE635FD99554F5FF2B4482D1948BD282FA282C48C0302348982E30A772BF14195CAC7FE39F836E6238EB1E1FD074E63B9AD0A8D37111087E47FE5D04B62DEB496353457BC76C53A2FC9D5AC9AE6A47F632E6D45E08786DA128464FF2266BFF92B5CD89176A19226F2EB14CDEB331C497F1836FB6C0A117ED6BAF95E9DB8254487B0DFA7301397AA29D95FF2065D851BD302B747AB47BA0AF408B51E4BBBF042ED1B2B604EEF4C266FE243261515778BC9451A8DFB025FA3212E868C3A078C7CFF65077DE94E50ED90A259FAFAEB398A94FF15C838EFA7F49904BEAFCCECD8C9ED4E014EA00C7AEF1D437DA306E8B7DFCE536912C169BAF0A3B78A643D6E210E5550E3B2BAF7EDFE01E721E3D05BAC1378EC1DFDEB2E2AC0F0BC368E0A8CC64F375DFEA2FC20CBDC515440FC2ABBBCEA3584E103BD686C5403EFE376D44F5242D35C9F9D35E1A869FFCB6657823EA0D4331ADD5CCFA99BD6EB3494A48ABBA7B7ABC32ACB8FF00512E1B0AD493F579898847E328C06FE05FE282F8D4AF48A1AAD0495AF1AC7354275A6D45AD5A7B3F6787F893EA558BC5D4ADDE1F0D265ABF73C86550D25C00821C3138B385448E3E02901E2E6EBC6A0F211CB6F22F8F865F0DF3893B987DD086B6674F5464ACE18B9F0EAE948667B2FC04FECEA3E2B7EA6B869D5F66D02D4DB124A59621B96E0DEFBF99A91AFA0CFD6D5A5968E62EF42B4C8908C3719BA0254929A9A183D50C566CE4FC970E047474490FFB07F576765AC5286B2E0FDBF1EC56A8AE8E6F560C69614FDF5C89BA53B8B7189E6388F7CDF7B819F78F3E6EA54C40865262BD2C8CE87284FEC36E2E73BDB8AA9CB5283272A90A6BBBFC3F7FED5F124E8BFD770B6254CDC695FBA0D8627315370E2CCDB89BCC84C96E20805AAF087F9E9BD1A189F4C6D66A6DC3FEF773788B3B57EF876CFEAE1F2C876CD239BE3B8A94F21350EDAE6C269698CC66BAF90B3641593F96399C71B2ECBE50F61B5D6F37D47DF702A9B9E47BED2824DEB19ADE7D7D8830A8F610088CF4BD0AD22A5A4FBA767D01987688BE710235A74129666FF7917B506A18E6B5D6166E8B682BE6B1946A4D4420926FF8CDF2488EABE71EFA7F2536B9DBEFBA08BB9E94086F55B1B991E18E6023E6952D4A563F2420A1536A1EDDE119E5779223CB712AB5C0BA4F0C176830FE523DD8603F1B316E128579E65454C2BE62C922C1DFE09DFB47D4497CC552AA9987A8BFE19C44E207397204686C718A0936145FC102B8A7111F74A421226AE016EDE658DE5DF9D3C28A247A87F2BC6FECF66CE7A6699880E0871CDB6F066D2CB3F9F625DC5E80751DBBC85982982E2EFAE3AB8F4F1EDA0D13C3B65FD2178E8AE4A712B521B7539785BB058176AB4396E6EFF2FD9052D4C6AF17DC30F50630233C3F05C62E151EECE13CE124E58A25F0F3AB65033ACAC9EA6E41CB3FA435D367DFEB0B9C9B37414CF32DC85A3C43087A578165C86D100E47DBA1FE7061111AAA961E67ED057C715974D3144912A58B6DB22D51BEDF6A8646D810190D91B61F0776DA00C8B0BAA7A83F4433F357E758F5AE8F278119908497E717A7AD25B09EA7C76B306A9A3AFCD9AE6B4F64016D5E80BD3FBE2F5EE673A7459B03AD9356148EA83461B66716346DBE85678C37C932EBC53B033A3F46DC28219880CFA8BB5E15F8862D345923BBC179FD763A0F943FC56BAB69F26C0C15D668BAD923D7AE6B35C07621768F9D972E2D6F46551D45E3FBBB577D13F01E8C1AFDBDD2F052E931C0529380F290FA1DE8BF5A11F82612943BAA2C0D086EBEC84069B271AC8656883F686C67B1808E27C860ECD1B95FF6CC6E6A5846DA29992CBA450081B8C37DD4911470EFF281FE94F10636A29B790E41EA6A342A5BE79CAF575FE9B0147F2EFE02874BC8A0E136A395B42E77D9F18CA4F61501E6C1805CDCDC10D0292593481F7E0F93281D0456EB51F6ABB7C379C028890F445D9FAC0D96AF68CDF6CC879A406CF2F0991916B33A72A193CF170B45AA079DB1BFD4B4126FA9AD3ED13FC98CE4C6C3C30923C8C53BCE1812B21BB644ED3A0CC0596C60032FFB1462DF5182528553AE865BF87FB7C7F61D1FD8E40D830B8D8F54924EDF934D1EBB88DA90BC59EEF1F6BF9FC2D17D8E9E0E39FFAD22EB84EFF39BAA70447B124E492D760E55D6301DCDFBCF9173FE293AC4D6CAF2E1964B32973067EC76BBECC65113C1FAB85375D92CE1436E1D1B205A88202B304264620B282E62CAAF5CFE1169EDAD9459B15BF0060C5744A17460F9FB164974CC55B3FFA71AAC13437BE58325E5E27E151C71D195F886F5630925D441A54695DF23F64C6BC3B0CA83F0E88D01BA4DC748A29F42AC2997C2A21EC258E430032C09E73E73AC2B21B55E1DFB2DBA281426620A0545D2507D1E96A3778C780FE77F1DA3B615E1B0D14DE8729229472E6619AB3B67CCAF21CFBFFD1F237E780927F147425B2142BF62CAD6B467A10F7B3DB922F095A0012EC179C4F8D5437AA8024F13A2A485E8890940DB69FB719B94B7D2629D277B593B94ECC744AA4CFF3D33D2250236C74DA057496BEFDB961B89BD6F44D581AD7A28524A6AF2253FD27530B7FF16FB5804FCA7E44BA2A3AB85FEDEED837DC130F533E8215B3AC3F584A2EC0E9B6194F97741EC050576E16349AD852DE8AAE2BF83CB1894107299F101AD5A2C05EC590B2CC698663C44FC0DC7F893F42BC5A2DECFF2FAF46CC1C00FA7294A0184A85CDDA2B1F38A89B1B17EC08555D082411A4CAEDED562C9FBBC1F512118EEC3BC931CC91636461151BDA454C4F029E01231BF170EBE17C526F3D8F705DC46560642B1AF36E3B401325A6CF59B88BCD4B3242D676FF4066E4252ADCA37786CBDB340DD81C5DD0540992F0B142C5A18D3BD1070719AF996E3C3768C3B234D303E6E9850B35C7AE52496C76106D7CAE4CF8ED01767B6DB5603F339FBAA019B08FA35E3DE1129A6A4D578264CF1FC8A1DBF218DD72B4865214DAA795A00505D4AE2B85E90F589065D65FC60CDD828007D4D3A4C084C7EC159C5D86817860CA03545FF74F17AD8570B2ADA55ECA12BFAB5C10067A086A34A57AAD8694C953137BBE901F8D3DEC27DB5DAD2AC96D56C312E25FE48BDC889373ED252B4F88D32DED6702B58D35A1FB40ABE2F2ABDE21CAA5FD0F67E7407A8"""), TestUtils.hexDecode(""" -4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") +d3bed8aae32df74803b6961baa9a2266122e26fd3cfdf1568b460abf5ebd475e1764c7814c6a48cfd6d4df272ea9790c8ebf12fcf5836b0926d593e90828bd49ebdb997e79b79ea68e66f48dad497fbd3a6c3e317162a3f46a4dcc45616be6cefa68210b11fcfc9a906945d30297d1714ad28b1fc7b4c6cec5ece1f5d20729918070cbfb25f285a6fba5e195d2dd75a8c62f581be2d75607b5a8740dd2339682f31230354ea03d0e7cf945f167937592a2d2dcaecc5cb0d36217453809886151073e5d15e6bf7763cce81da19738be3a3bfe96788a56c47d2d166efd18250ad525b4e9e5566c19287ffc277d26a888d0b1073242da5e92b23556552b841ec3355e14173090649a14cfc0134b7714dcbe52095d759d0eaecc7d26f3f12494e4247435d5a6eaa9957aa503f710f8e2844905664905de2f30285e774b46270c58f45d267e850e1a6f711b00e5153040ce090660c97b14432c27d0dd50c0585a8f4c4e1e15d2888a90c184508cb400af2f5d3dc0af3eda99a5e97d0836d079eed38aa6e3e4f724cc63adab509ea5f28bacf3181cb7617a3884407a274824742623eb441ffe1ef15bf6509e7b2305b5341c7a3d73e5dece5b9ead5b99f7e65169ed1673bdb925b52a6b8d524ee37e8538e6917327a8237bfc3ed3f729cef6840e75ef1cef707fa10009e4d5c72561eed18c06e3be94c579f6629373af6a55019c3faeed00abc22deabc59dcd87ecd40e9dc0a5f4b7fe1d711990fc8c03ae9fce980450739c0a441e3512ab7602038dbd1352fe0da554176a58c47c29111eda3d2b9560b3fdcda292c31621e22bce8695748fcde6c81a1270a1944790c174de8a18a505543b459932c6f4228a00984166ddf33e981c2d3ad2e3cd9ce87aadc57e1e437029223e729a99667ad87ca718db5b133a930e73dcfa2d37ad7580373da272e54f62f3d13db9a4bdafb1922145a1624fa96921c0b6bb1b3d7a115ee58dbb2872db79f4d38255c11f160397052aae3ec34921bdad97da72714f37eed4765769e996e45974961e7439352445147dec09b1bd02a776c2c22be612a723b8711f8391e4918a95605fdc866ed64cff6cde9baec4eb42bd880dd0265befe1a33f4d2c0900627f0c7727228aad47d0922caf2a7c86d70960ac2634cea63dbf5d33af04cb149eb618f9ee97adeeb0df8bf599358a82ceeeca582551298a63cbac754b6975cebf7d6e78b6d5ee24dd6c78b51b022f857e230fab176446cc2cbf6986caf8e76734f5280f463641bbda5137fab4800c58f0e1c4dfd45d5813df3f917666bbadb3547c7381eb33b00fd569d58dacdc95a25962024786770aed94d97d4682f9e94d34ecf09e9269993f547901d0120e5e969e3f12a5ac219158750ed0f381dd72a91ffce01f2b612decbef0fa5441925195b813e1273dcd9988457214c9cc503206eb4756e46f900cf2011963e761e12a3774381b877d93aa1c7892f512fc0eeeb225ace5dd7816b919d1717b6e4a34dbd30171a1d036d9ef9d37ab821bc03d881ced0f2aa94eec2fe0b1ca72b7049f749c9e86ba4ff44afdc90931029fa59538014c519f76264a2a45bdab759da02761303ece94fdc2654cc9c818f4af979dad60a9506dd381d150a66e5b0fbdb6e734404f4cc71e6b4e7f5690556d28158cf049f8ce6e4043a82d1ca3c15e480ebeb7e211b2fb00b4bde2733f03f9cc705038050769f9aebb5a1ffc1c9e3d05132ec1ac7b55b6b3b127ffec67cd6e3a1649fc9313e3625c01ebb600c30f622f8bccea15d6f0388439fae057fb1ca54c7aaecff7b1316e74273a2c66037926b246626ea2321c311aac3b5b907e551d7b03f069ae354ddca45d1e5ed3023c576fdfd1c1bce9d8edad78acfde17c9e4d83ba9087d889dee4bfbcd8908a41ebcb4738861abb6b6d8e65251dc4b7c26de398c687b30efd895069410e58d7bc2a105640866321a83dec80ba7b47cd64b002300a9fdb7e7648c2d0f9784ba55f837904df1fd1db46ea82802d4c3e925d4c3e3cde9b9b6063d303d410f3e917f10aa0a18fde5849d14d0a79d71a983f9b09a41e9a3f80dd36e46bdabe65a1d40d7e53b94aa9677561a549aefd98826cc32f6dc5961714d9cfbe913dd3bc68b8891017915066792cded38946c0316fb0eb6d89c10b84df01e0f910a9ce8fa1cbde71edb210918562910cb540d3eab21c8c8e43151a333c516239370ea3dd42294712d6cb920b1f5469e74fa82d4bd7892cec246db13f3f37ef0e980e095faf06e5aa417f5e16de83c8c1ee5ba8340d10785e1b10aa7573dd6f77fd87eab89a014449210e285fb17d0ff7cc3a2c61e6485c2f2e81fec821abf0c694b77f71a91790037d0f141cfb4a74caa4125dfd7236251526a44d4ffaba4589d5237fe647a4082ccd708e27e82bd28597081fecc184a5ecb2d19d115acb18d9d463e3f642e2e606d3f6d496fbbf19149ccac758dcfe8eb53378b65608940925c23754e0f1a390d520f26c4cc088c091e55b3cc475565c0d166265a0396c50d9983e3433bc5527e9fce7fca2bb408b39dbf96bc183c3659f6e8fee0f23e4230c0eef54ae9581b3a38436810accd7c37e83326e3fe7ed1821393a11127027821bef0b96f58a66968271915c1cbcdbcbcd8c62a54bee08b3cf143e859564b798892fbb9c430a6645bb4c8a2be76c37afaa67b7b5a621f987034e88b1608de8a0a09384d85b0c2c872cc2a9f8ac348c5f864d28558f6c6e4523f408586490a78ef95ecffe5b8fdbbc264944869aeaa3ef428d5cc5fcd363d1003239a6651532a442935e674e3cf1aec6f8b32e32db762bf2512efe763c88b9bf4413ea3344835b96fdcdf71c83afd75ae5925c3e76b9afb9fdc72b17f41ec516ab23529e73b9639f5ca42457c5afcc0f2add498456e1db6b3e775ce48753a9a70840c45dfe7cf396b627fad775acd051829f409bd37046bc4cbb57938cb490891c3aa6a04f60769e04685ac1167c9de32fb20cf43f730d8d09b0d74e7f80aeac659509d7941460018c38eda19de38967fee38f7e9526babd21ca1be031dff0591d765ae30361fd8c2a33bc1dded2c43e0e43533a55e72bf1015f5167c8d6bd5e6a19cd4e2ff19f1d47cf42fc361649a669e4524c731bfe7bd11c2e4ff599724de173dd6990f30db8d3b2084d2d3aaa0c0d8b648667b951d510480a28d40c938b71974d749e62d88cbc686eaa31e7f89cb86dda1e778a167610e7bb3cc97cb27f37ef9121ac1baec0a10b40211cc314b02b5df4274acfcd13de277e470b63c0f0fa387dced40050607517a979ccadff817383b404b4d627d8e92b8c1d8e9ecedfc2d344c4e85878b91a4a5aeb2bbc9e3f5010611121a23333a42546d6e8e909aa3b6c4cbe6ec000000000000000000000000000000000a1b2b40""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +f7dca662f79909c3ddab57a31bf75b9d925ee06460453ccc8687ed15f17d9b3d5fc251767fd178116899bcb8d29b81a71bf5fcd021349f4d8b9f99edd4c737300e23b29f425671f66fbf2d51e1a668961ef145edbedfc6d1749a5cff043c58a433d4469a3e1f956bffe2142fc6ba5e86c8e326d65ad16ab4a8d0af6644dd046a6176b92f147a04ff674b572b319b9fff5a9fbcd7ffc68eae3197d9b3799e94e18a7ffa1452f1b41c7fb7b98ac7d30f6f371233d4170fd10e95cba9905eece5e06dc153340436c1dd34ceb8334369e9ba4b3c14e9ec3fd29a701fa8baed707a7d51dec96e43de8f4b3b30fa1de919da643d138e911d5bd800e336402bc74fdb6522125a8cd1b252bfa663cc1fc4462a017ca356a0f96bdcb3d54462ec5994fb32c2648361f6230159c74b4869d98c048562eb5837d711ea29abad6d99f8e95613e0069770ba7fd265c555b010dad0619199a44db46e9b362998bd758b882ef26d90fe04b8b18a8887945362c025edfda0db7a750670397a5c9fa8801399fff8f67f071a8a2d8abcbf548f0393f93c89a28dccfcadbc204d108a05c3ab07249d5d4e7afead91645fa7396368622bd2ad3bf3ecfef493dc235365af7f42abae241b7e0f9f52a66acfea9bfee57631f1a921ab1798834d30af1d58bfba62d4818ee30826e0b8b620b885f55dc08b346e7f868e113fe9bdd60b974812d5991b3b9beefb4802a4c1f759e38736b2f4761cd608128887e88637fb5f4d5bc548e9cc121e3fce98a415c64a28b901d26e4a406979511fbfb0d8c1bc02e0533c2ec33e17fc2cb5f430a029d69950a980bb7ef7c1911e28b355478e348dcf4be4d3b30b1279f0e3f0238277fa32c2ae9fe12f1ac3ce5d94a8c1d641ff55458a1fb9b450b0475476dfc41177bf65ab97b85b1064a6b40005ebe1d537515ab664f3c42c61986a11bd93a806f7336b338e9dd8cf5717157aed7ea3747517fc91e75ee9fde429988df68362b4bc31c7a464b07f7a0dc8e91f8fb34679a3d38224c4ef7b7726ad7a17fa68b9d417be3d66ec95720b288f3578ab366ab1e569f66117db15aa5f4b0019cdf305b3fd2297acaf1404e944f9763179b613b896c5be2ceb56c854cddcb3c8fd71d2a62526c1a1d2170c9303ac4e74ce34bd04a28fb5e53461e5ea9aef756b189aa0b5f311cee714ac8e7aeb65693b8c77cbea41bcc9f3bd3387feae9f000abbe7c3f6966c07b5ef0c926e53206cbb2118b3817df8a4b254d03ad98b6c0d86320a9fb8af7d6f6a1dc827e78ac28fec3408e142fb114929fefd1f5a613413462b5a9dd244d820165c87f0c5ea2dd13a5aeb3bbd19c9563ba2937701647edefb1b518fd4b2f7f31055933715d17263a798de2025225212d41e3788d3f4b7b6653071018e35366d2cd39ce7442c70105cbbbb261dfc73308a443f613afa4aab199474ad2f2647f9d94acdb8c11bcdc2c4f8e93dc16bcf9b40f3fbf0130b2776175a3a0370f6dd7c1c84a55057e95848fd3d040a820db1d32229f38fcb790585bf6d896798eda3d27c1229293c0751d689f67dc6bc4e2f973fb6b62355538947fab1b1f6399b8e13faef7a2ff8a20e03faede7d95416854e5e6f1b5ff4a77b24c74fdac038bc1a12e6890f9c5a34f3ee6ece510f1a536ec613ce47173f09d4863d86158b7042bb0df99322bf55c6d5dc14f7f766b43901e77fe6281d5e5e6d722ea65460444172d91f0f99b3140f4a75585c1fe21ae8edfe3862539bd6ceb398450caca1cbe6ceaf6ae59e961cb0b106541bd7eca3ceb2e367921eb4566dc3d0444b766b0cf2a951171dd73b02f668ca8a4221d933791ac84cc6c73235ec468b"""), TestUtils.hexDecode(""" -0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), +8F69A33C4CB9627BF27401D4A1BC131D28AD0E2E5A317CE983BA2CC7465861A414FB72745E4DA31C0E04576DFE0D0EE834A1EE323D5A0901DD0189EFD6718049E2FFE1AFA548BE16E04B8963325AEB0CA90238C7A243A3F6AA17BC1D63836898688AC8E919B8EB6D689075E050B4189A1FEC723E0AE8D4AAE9FB6790B527A7552CDA174BF40BF91C4142B076ED8CF112A871450AD994737FD5BCF513D42DB01906636D42C6C10B64F74BD37D68A966DE0F3BBE6541AEB9991DDD0C0070F16715C01820546A014E66D786B8922E905DE2BC65053C42703227B7D8431427E3EBB0DD010DC58C2343147700D673D5707160F234E35BA24516CEDEAC77AE15C667AEFA8E029FF14F169FC0A781593E11D42E8659DA8E91E53EE0A1FF15A3C203BBF9591584A99FF8BACDC37541E126B8CDF3503AB2D1BFC0C37F38A298AB1DDA150288A8110C052469382A9A4F5565778339AB327DD80644A26B218ACE0830E56813CAA658A9F17826CD12B815612BE40906ABC89185EDDFA8E05102842CF27BF040FC7B396E7E2E023CB86AB7AE25F36DA6B6C0842126658E0315D6D8F4B5DF38CA663B55998ABFC72FE9B7EB7CE3BEB72AF73A0B2A45577C5215C42E465EECF4A4E69B6DDC1E65E0C1EBCA"""), TestUtils.hexDecode(""" -279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") +f0fddedba6482c562d0ea6791254b7aa34da8b70ca4f0a7cbdfb0e4fa31f902aa37484c4167f74093f5ebd508e4b89966aba03065194cfe3376066b848da8faf1768c397a0e3797bf09e1dd02be5f1e77703ddac9063901b52c9b4be73daa5d44da1a59510b25a974d9c54f8f7889587c6f69a17989ea8b69f4dabced9e23442f337d015ebcf84cf8c5776f4863275532c4bad840d314797e07de00a9c7fdbb60f83392efc382220ecf3f9d60b5594da6fcf00580df29a378a9cc3156bac8ec8bcaa7de1d8d48d2a1f33ea8a8f4956e3c46f386628ca96e009852405b6333710287e376aee2ee7c6f67b1adf07f76fec3688201bd3b152e202c192db41d9bbc0d8411ca019f9a1bf1268b34ce82a7c037fc63d9c63a561003d8247c645173e01c8ef63853e4451185d45cc2d5d2da4261eede504c6da88a55d7cc7bb8df33eca74e9f4b9f9139b9f98964aecc5278448ff9f2a032226e908b32d741037ae689c204bc1f3bc07850debc3fbc839580e6ae1fcfdbd62257ad64c2d6f6945a6757242d1473e64f089c46fe050d79a082e43cfe656f09d01ea219eeb7684188fe80ad59c4bdb57905cba37fe0fdc1b205f1a5a899ab55a37c7d3e003f1051bd3b322b37289df3d350053d6ec8ec1c9cafb49fe147c01f092dcdbd9ffd2b7900205334a077b2ad5c57a53410bc5b9f32930fc6f6a270d84d4436d8c716344df877f5e523ec9e1ecdd43ac21e2c4cb8706415be0ea1060c7127d6a327eca92956771af363c03ec4a0ccdf958bee76803208191946dea6e51a85dd071f3711555cba324e5a7d7459a7662fa6cce043b34845fe77cc651883c478d0d4b2c09e76bf401f0c12721d21357546dc78d2f054b409b6a702328d720023096e911144b7bb724f1d799b0b446954a305bf46944f122867cea17b9798636498a8393bc2dd328b0b3ae78b44ae35cbabe62e0f0d3ea4cd6db0bfce87c6e9fb3364c2ee27b5edbfce17c8df592882dd057dda81855abe0d0898961ace81b0ff22b4471bf96ce814a45f7c6b3e07ef1f18c9eb238b44dc6a50d7489a1af58d2dd1ea2ab2b1a0b4b661e55bbe6dbe9314e76207ec0a02edb2fe7e8fad8141401d1f1a80237cf5a10604ebd26ca46c0ed5d8bfe96c3a1d6ff5b7d2de69402d348e5db561e531deafe29b0767620d7613b817d4d3a6568911c291c3436b40043cdef83a8b7f527aa8e9ca89dc923c2bee6e41312af6ca1530ec7c6aae798e25a6a31ecd29f4ddd56d663e430e5c1ead28a23d424148b1a8aebe9ad7faafa4e295215962d294edb7b1f994ccf43238038ff1af9597d24ecfb68aad4e4d2be280c6fda0cb88b4a1b0deacf678857d83c955115c094980ef8fddfa5045a3e38e733bafa243a91e89a5676312db195f1fe7c0f7b0262628a68c6619db1fd85d84a02b9e7da8234304192aa3db15a294dc4e9e7cb32f8662ff0a49fc4309700e0dea871edeef3df09ec78c3791fa604ad69bbd8c211f136dbbfd49009fb5e4fcbb2c995bbe361c580a3aeb1c88dbb2f148cd05fa9ced0d826e24c268b741953c8ec804add66a9b8dbda05a9296201d0f447b45a4bb7271fbd3359a29815bedd33ae87b52bb270cec2369dbac94528eb48a1a66c129793a4365212f1cbe7e24c87a805ec0f41cc2f36bb2f2423ce6904406b1362c46d51d6d5685dcc06915636e20ea3649d6d1da39c6177630d1d48f393d7093fc12415e5789b15e1ffd07e1f810057ab6545b22b24a93f9af3ae254407f9920af8a48ec40412998dca523ee1e122a5e1107a1121cad25652c1e00f6fa115c58b4a7a60cb4e3b219d9828f2c8efb04a443717e73146a89fe1a4f887b564010eeba3695164704c517d3597ddf34dc51dc460773394d8cb4d562498cd127020973bcb2315c25ad136dafcfc0d674341045ab1de0e4230ec91d579ef1a42ad69892f17dd271e9eab28097f8f9c5e78c50c36c8a02f1625ec41132ff1731e3c59ba20cafacc9ea890db35b8c9606bbd5457262d0c44c4659f933adb64fc74a884e152627cafdb20cc64ca10ed9ee16d814b506415cd0141406b0286124e37f777dc810d70d4125a72bd98a2b73bb26173494568bec76350b2b3b399fde1e3c115f1fbc99929a58a8ccc2b9cc1efcdffd210d88ad48c54a48e837cf841c9f1a350531b695c6fa08ce3148682fceb9fd17f121fc1e3275f65b5a8cd93a25d42318bd21e94ea8873744f2ab530c58dd3bc1109a5c872e61887bddc455b1bcdddb91c0ef4437a49a9f6c73fd371bc6c6d2fa594f78224646f2b8cfee3563c57149aa3a6995dbcf0e6782c53694b39b8812dd069c0cbe713fe44446e44beb4ffe38072deebf3ccb20134168702fc023c4ddf9aedd387a8bd6fcb075850cf1f29f2bc283f5731b75b68169dda2289ac221217bee3e2ed479fc5ea8244a99cb27a015d7a3ebbd1f7acef07b63f17011c5e39ccd0c025d0bce5aed7c482685c39f1fd82a9b08c197f9cc18da457ad0ad55250ea935bee50df659b2c7a501a348b8759643881a9c5555015799adafe10130d6107e0b964b48d23c909e55843b62b9dcd1dd3b235c487968c2c3d87fe29b2fe3ec7a8fc1c1666fc8d2b6adddea39ad704cf5eb6c22f0a5aeb80e2bb04f6c2c6bb9ceadcdf7945140ba942581213dba8428a8c06155f200082f7faf357ffaa653245e2752787fc1598e000eb567cedd49b98d5e4fcbcfd5c4ee10793c16a4767445fcd16ce4201cdd005e95cf5a714a9e0f648673269b5fcd8ca0cc254b6cd2fb428075a12b7ab2bb07a5ddd82e58c04676563b11dfede4daf13e1362a5171364a2f556c36130c1eadb59dd966622f8b86502f379e0dddf69a1f73f58ca6867b4612f28e67c7dfc49dcb56dcb17a79aa0e56a08c14e1e909fd21d05003ea921ab717bae0ce1f15a74a71c4d7e6936d20c7e661806d5f8a5f4cd93ab6720775057d4c0450a6c9e2211af47c57a7127f59983d824d35f48848043aaf3e76209a6cb6f34b15e5099b2c3801bcdca3a5c626bec9b6e92a67189dbcdad0d59d2b30a1f9cf9de45084ed6d35e32722b6642ab870247b42eb8f5fe39e97709141e36b5888fbf496199675274d840f15f5ffe40d74be3bba8b4dc51425f839ef7d041a4232ccb93b754c524ba141c75ba94209f9e76a0d7c8f2aa3e126e6eae35f19de3fbe38f17143d1a83830a2b9b4c8a8b0bbac29363ea9ed0fb1001f67e1501b6f4d6406e2335a61f3386c9e6a2447e3249d3db8390158af9b7e57d81fcc00a4210194ef6f872821a8cc475187780d658903040b0c0e172030576772769facc1d3d6dcec001c30335b5d5f62656b8f96aab7c4d9dceef3f5051b2240435b75797d90a2c9d20b1b1c585d89919ce1e5e6ebf500000000000000000000000000000013273441""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +8a37e080550701795416f5587b977446898ac8147890840db53ae4c7a65508bbab7a2ae6095c3238547f76228d5527b3cf1a6f773c1df211fbc5c754b69e27dee951eeadc89246b2a5fc047cb04416c905d36b9aa8f449c2198aeaf57a7aee84b4cdee17f94e1099fbac56e943298ffb574dae6d616ad7e13788d56b841acd970b4c14d9842452175539e3721ed4b00fcd9585b05915580593421fbb449ab9be941f0d91cff4c6756dab0cc6ea5266d8dd8e79e86a4401a85112d3c871de6e96c86472022c9809b8e1e648adea7e2c3166a7c1529c2ccbef40397051e17e53d0000c6dda30386bcc82254e6126247cbfc19e3c4f2f94db3a05a8fcf608feac3f3eed55fb53724e97ff20e31ba8ed2befd52259e3a3eeb8e7bd80fe56f9e9806e26bca49f0e28be54ce1cd53e75c2c9346cf4d585afe8f9c260ce6eae3649d1ae093becd4220083927ece4f17557a5af9bbb6477d3b0da0dd23f0896a663227700df6df2ce10a0b268d5762696fd9a9ca3ff22eb28b8f999e9f91818e29459c46c3c6a5b6c5eda8b880da621d9fc1792539cfacd58a1b7eb3a54bdaecf96b37d16752659ca51525e6e9dcb06fe54242ae65b9ac8ac5c749c09c12c310371915ecb7ea3cf46d2bd13c66ddfa2b6690e885c469ee34351fe07b749480be85515deb9b70caf055ff56ab85e33a029edf98394d94dea7bb8bf3373de77813233fdcab6377ad20a5dbd3144f2a6243d4f73710c97f9e113d70aa9771b52f19adbd074a790af5d3ce83c74855334161be8d572ce59f1ffb5877f4c56eee62336c7e690295fe8e0e1c964d1938cfaa6ca8f93896716605858ebd9a3c6ee3dcc8a803017f8270df26f7aea45df98f4f3a88f6943e3cad22a79b057d7b3d13554c2dcecb040172eca89ac6d55add4da96165ddb336d439370e71f56dd67612427be4fffaaed5b9f6a4a30884499dac7b82d536833db4480e050089c766120635d9811e0873863d0b1d355592aad472a3f18a1cd217b3d2c203f24e795df30db4350647c1821ca7995883d6db4aad4c141e49af64989e85cdb398968de223f80ebab4b3deeb771aa7270022983ee63ced61fbc4daaf578ae25bcdac546f4e2335f4910f1f5f58562e7ae7b4cfe50ef5e30de69d637da2e50fce483adbaf75a5a7ec6d796432e5ae95461c45ac74c024d4a515b81d18d702b49514e16db48944da5a7b86319c432a84bbd3898007d515620665ba4a5fc83cbe7e060bc9203d1cd971fa73b538d949810e7cde88d082eef96c72c2c0cc6aaa883ba6e4bb92f90f72388a7814cf03c86fd6c60bb92b36a072cd81ecc3bc8952f313e71f981ac53e9a9afd2d996e88fa7d0ddfc9eed0ae45c3665c60ad92e509a183a95aaf2989e9eeb92f09f5b9a462a9a3d5acef6af41ba5c6396d61008d0edc1ebd3e998849fad4026fcd4901448ae94d66950f7939103d2392ec78c7b9ad4fcecd43be503eeaa5763b0d03a55e052051c79f8ad82ec98d24f293b1e339e5093845f37b76d33c74f37f17093124dd18ec1282d0b42a10155da458ed0ec68bc4ad35884abdbbe9592e5e82c78a19f413d6cb41fb1c896246ed4e043d08da02f1f3706427e2d963c6c6f9181f4057a21e2d69597a84b54b197f42caa629b99e20e28a9d2d1905309245dd7e0cd5b5fdac815acdfb64b6128b3ba8d10c83e61618a7e8558715ce1f5430db60fe6e6f0e01791dc734dfaf19d48e813fc1d5fe1f353f4dcaf70b7fac6a170e97c6c541374476c4db1220a4712b1e285d2f91a5fcc4057e6767f1fddf4fcb83e16258b93419d7d25ddb3e36eb7837629253adb7c79aa1fefbe81b2dc59cb93f5390fe"""), TestUtils.hexDecode(""" -3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), +5DE75924D05BBEF6B34CEB195AE3349EB621187051B1EF95A779B99A3E0F729994BD19C7D1172418BBD3E015B20699DD09D8BFB0A343F477AE2A3BF5737AC994619D1FF3C13E7676D1BCB446289DBFE36E2D1508A3D437B4B0DA06478DF6D4701909B272E9070B1FE06385DBF8A552B471C8EB48EAE39D141009FBCC5D57D95697ACEB7B5231AB5976FFEC41E947BEACA7639F664C6C1D058505A49561811ECDA46E23B651F918112F38B407E82219B49E5C4E7C247DC4BA633C746B42DB912B07D56302FC5C08F5E0C3E311268041F970E670F3AD26A207701F1359EEF9D4134ADB882A1C899B0E4FFBA2C68535D97796636417EEDC0790FF808C976B57F0838A694700F8D75DD4FE5ECFB4B6A188FCB77FB1DF7C5F7C91DC81017A5E9A6D1EAF59680D3291F74743E1776A6DE31101FAEA31D876A0DDF3777A91EF1EA0B575C83C97C7A283E7E958287F5A52F30B6E70201A1410355B47210B911A7A4F6FC23BC95D7951822115FE410ED2E7FEFE08940B3F8E63F13F26B6E949C498E62A66FA675850FB9F7AAFAF7D054F5C12306ACF2900A5B66A29931A5919CB31D19304916AE41869CE3294B0F5F88D845A7FCFB57B952BEABCD1DF7FC11E2D342AA5A70A8AA9DBE1E6E66555EA618849A95439864DF6D7789D8E3B46C6FE4F33877F127D4136D993061DAB530EC979F818A57E1052B5B33D22E941643DE2FF9239741F6459A0EE28658C3C0033FA62DFF37928C59189A7A7E36B1E305F3E1F421EDF4D71A96C71406A0F9AFA5C96A9411AA1A35D241D7186E5C8D0CAE15938FF869897DC3B7D8196D64DE202108D6FB436FF89983EA6DBB5BC88EE2A02488E4D12AA87CC4BDF41A339E10300D32E0FD4F3D3136FA64BA90D64E2BC7C20BA77DA4DB5311F616288496F2FE3E7B3409879050FE57A23DB0344CAE82ED329B0D31DC9B7406CA715E3D84E364BA98F73F693B6E62DF4D741928D21D934453BD67FBBD9725BAAD34E5F3204BDBBB569251DFE2D69A9A96BAD90256213BB0747E7950AEBB4CEAC7224FD5F8F99A16866F5A1DCE07C2CD1E06B70A81FCECED0AEEECBA62521AA0A01FD7B5A3A8A14DB55AFF331E469F5138DBB2B96BFD0AAEE7F38EAA375F71759268546D590BA8C0C022F78CABC4E089992409D3D7BD19048D30B15C796170BCD7AAF7FED0387542BF8A6674F197EF994FF81BB80C59208A572495DE4E584B36A7E9149B5E2081A4DC162CF8376029231EFFB4B4981895FC36562F51DD5158DC82ADE52ABB0E98F4BCB3C0A24566D07686732FA734CDD48D03DF99F7253E589CB8725F17E6BF964E96F9827CA5A9DBD04D448025EE014EE1B5DBDA514D3FEE4F20664C11371DCB16991DA883BF9A68EE30D727137D7902F4839635B1C63F6C4F7D42070E880CA774680DAEF105D277EB8D9090A98F6B813774D42DEE922314480EBE562775F68ED180B67EFEB077D8B174C7D4DA877B0DD3698CF506EE382AE6FC6F68EE93ECA3627B28248D3EEAC469EB0C26BD1A10A7779CEA142958F9F9A533BDE974E1B3CD9B74FEEB2EE29ACD7DB65E00D7ED6E94E5E44A925188285166570727FC687AC7EBE4042BAEF68BC23F4B9C51BA5040BC6BBA41FFA9AFB1AFA09DE1BAA4DA091A08086128A9CA5F27D3F4420327C8FF4801BBF2057282D05D1CBDE60E1E6FB6715EC41AA9A852686DCFC47279FCCE5D86ABF02A6B5B57DE22B2097B12381EEC567E4ED1855F9B482C174D6D40A5825687C02E1D0AB634C020497A44E07E8FBB2D05280C53562DB4C90AE0901B88179D06F9F991E33BF17E7A9227A30454430CB768F56842995081520158FC34BF5257EC8EA9338B3714126D6A95A3D77FB61207154F6DD0041BB03D84D8F75E6EE910460F22CA765A2206D6C56C6E498E063B08B76B1DDF98571F492F9DBD3DEAE7D9C8EF21EDBABED962331F06371364DFCB3216E24638A20F77FCDD894FCC5525DD0C8FC329494841EAFD93CFDF0053FCC27F5A1263C7F4599C186B35FCA9C6F5F2FE169B00275F15447AAA3A823E27E322CA2316B25823F3A79FFA785E9CBC953815FE06F376B6F5860C6A87CB9BE98690C9C2A93EFF1BF1050A01C72CD521BEF265D66BC4B8ACE5736215DE59290DA957175D704BBEFB0E81C2CF906C3A579BEAC3A0C945409DEE4A1E683A0DADB3C4AA7E0174710C72A33F1BBC62A6E6F3EB9C138C0CEDA817688BCE8CCE523A2A4E2566775015F3BF66C09E716CA929BCC6DCBA7427EBD93B21CE276820734331B078558C63ADD096004B67E618D9E58FF3FEF00183EAA293A1DA2520BC03FADEB6A74B52292DBBC6EE4E5ECA8F8B0556FED36C2B41F9D8FBDA8EAA1F74BED46F05E7712E20E463502A420B6CE67D125BE999EF906300C627C57C468C8DD608F9AB354791E6FEF0EE63DF3C1821AE78111B27E57DA88FA44D89581D11C2C72F565A3D0B5E8E2D83DF178810075E5F8FD29E1953BD2C6326B693C5CF6ACE086673D69A67A181062A6ED511E0CF36381358C2DB2A394B05E0C1EE9C54B89C68E10857463F71A842BDB8429EB31D250542F88E6BD3BF10BDCA160C0FF44EBE7D0D982F15C4892091B4A69A3AE7051BECD1D2DB132599F1101E2BCF60136CE947F339A3DEF9F6D81E1BA3F5D4CF2ED989861F7CED86B1A6A167291CACA74C45BA7B5969C09EA20C4EB061D4CC4B68392AC866AC591764A16D0A42710645988FE070314D0859A1F022789442381EA0E3E83F5245272CB5FBB861C3729EC484D2F299F37D2F50688D1D8DD91F131D03207CD1459B289B19E3ED609D70D6BF8E0B97A75F4B4F1DB52DCA7AD03100A36C45D2AA221CD01C8A51D5328AE47E3307EDCEE9B27F62E5DA9EEE15B7A2FCFF1678551BB3DEAD4CE54A16C22119BCA343822DCD20271BB1518688CF69B566A123F65C4787C1C525BAFF00CE20C46C536E47DB1E4410E572BFECDD7904583BF61847868D7D1AEB1EA071EE15A9CB9E3EFF8D17A5BB7EE8BA83C95272E065979904AA99CF036BE085ED869D3CCB694C025FBDEE9BE140A0A21689F95D90D8A54DAEA98EE5DDFDFCEE2908E65C210F347D26F35B95B34642939067CCF04A098ED3E2CE3C0FE66305BB5391E223E43119D38A33672FBC980BEAB96558D3A940700B3CCA9D3AD2CEA08E23082DBF30FC08E94B6640CA04BBAE80091ECE96F128B37141131FED2A5549CAFD7BEB5B180509880C49FC6CB1C11E4CB7C7901C89ADFA0E5335C43A74053347D3028B23085647993B5844FB2716B7154D93E25DAD1CCD889EF3B16FAE34D04145237378D66BD09A254D395736990204A5627F5446787B467B619EE8F06CE664BF7B94392B5C77BCE828D6186348EA2DECA1CC84999FCCD95C9EC55E28C8C2FB559C9020C6EEB661F708E40351D7E530BFB7B1C3683BF15FAC5B17D1CE7EC5CC3C27E04889A9E59E6534C08AEF6934747083CCEE84FF2345D519CABC7D2BA6B783D36C864C65C47CA636B28B71D6797717950D652659AFA8BE3CAE4E269BD527C0425168D04C097DE8F34834A7D1728367F148524366F9E53C4CC255D3BD6FEE7B5A6CF459E1685FE740CC203EDBF58082820B967A40822D36BB4A489BF0CEB51387009D5205056387C292D584309076956E56926283657BF7CF096F54E0128A265050DF528AEED9247E19EFCC79EC301A9F38BE7AE5057456631840EE39E191B25F4F7070BB15CE2CC18777F7CBEF100FE7993681D4E965D0C19A68591BAAABE601BBAB89FC27B3C5BA83545AD645F0DB716C98D5C7A37E0AD97C986EDB88B025D25E3DCCCA816C707F0E2542E44F4D69F943E1DBD08E344F88661B68A822C3EFD648AA23AFFA2F533879540BE2F670F4D53091AF68867E7C71EDB6E9E494E9D30A1839653422AA8AE34A525EFAA62D3F5FF00D91F5DDF80FBDDE464A8502AD9AC85EB21025C0E4E2C2877D50962C5AB8283BFC823FB221CC285F3629056D1260AAF87B556E556B4C723D44279A106EE4075BB79773588333B42065811D671016AF177105106203EFC36FDAB2F5E5EC8DE043902583C1782BFD8BB772353EBC5CF03A0D869E5F3797713B58EB7480CF7B92AACFC9C41040BC9E1F5447F9852B2C5B5F33B5517F28A01D5435C47E063B41D3B0F7605B07AC33FF6F05C6FF44EBB70FD6E1AFC2A32C9A0B1AC17044401B93D6439CE53C3B033CFF06688E1933CAEEC48A04999A01956096339B5E44AB3A57FD1F0ACA23A03114708BB16803C2CDA679061B8E9808A2E11DB0957D4F73C8A06E6C50D6DA43E4D008ACA23CE2A3213BA0DAD20D5BA8B44DE5D50E188039C112B8A40B250E7E815B1367375C5698B61BD915A70096815479916F455B9EF837300908C5A8BEFA5157EB688EA02245AD3B309D10C769CA1B8E5CCA2F5FC66CC3920759A203C3F6B8E9ED10CAB20FA143B0BF0BC8529A4E89AB0C99AF77E43E68B61A9E4176066C4708FFAB05F3652817FC42039E2F22DE2058CFA8701AFFA894F3143FDA27AD85C45D3AEB30CA9759537CA4AF2079317CE5F4B5EEFBCAB981E42065AD5CB8A4CC9B628CCFAC18D2E637CB73399CE3D90A9060F88EF438E8511CE6F403A0CF14C6B641830983C1EDDE73BA27E41BD678E834167C718F5B1E2E6C109199F756905FAF9F0005CC1D110CE277DA02675461AE70EB6A412EC455B6575F16A4DEC0565DBC8F387D84F9D3AE67AB35E511657D82B5606A4DB45CEEE81C94FFAFCB88B8185CFB67E4D7171EEB391E9E1DAC625B56FED22D86E8A34924740F94A3D50CBD05B8E2476CBC7C54D2F742F0FD7162E7A138D4AC788E710AA45824513BEA162E2A1C1F709413942BAB5AABF7E347A148D53B8EBA0336D91539766AF0E827BF8EFF36389ECA38232FF2D7E341A3AA710F590C78EB69156462BAE9B8B73386F38EAC4FA26456FA555E26E7DF679983FEF23DAE87DBA66BCEA19A9F991F864A17C23F7CD592ACAEADE0E82F4737B70F0243F94F015B59330B71E25F1304DB3D8D7E2F96669BD7F8313EF9E10EB1EDB0F0BD94745D03C83768A618AD9ADDEDA7C1E6E134F8B7BC96B84652C982B1D9242F8D2CF0ACAD146EA3185E2332904E84088CA2D7D60D3E2DAE411171726B5FB6C95B3DE961E62474CEC73226E55AE7D9C7C534E278927F5D669EE6D111E325D54F338E2A6A06493D6F1B7A556A94CC9512235498409EEA477597EFAB239380491C9CCBA1F00A0D1C5D758162E9F4F5464A1A64A22C32721AE57E246722A6B2E07E544A5FEB06AF86C580DAB2B9DFB5AA0F0251E6840EAD66FCB6B89F80C2AD38383B329F9EF4589BF0E8A0C9996EC19E1DA539CFDEFB2BB0F3D9544392A06F765A74218B7DC34F38D230D1AFCF9130410A4B4FE038F7AC59B6B062EE2D2ACCD288606AD9AFDBE95D9572B78B54D26166C7817E6F72F7E6C55DD1576720E4AB99CC26722107F7C278BAC2D82FBD0A3B0E1793C2D8B498F90A9172D17244A4107D9274958FE078FA8A5A33087BF278383F439C0B41523E0E51A662A9F2822CBBB34EDA97F5398EAA12D52506C2EAAF6D4B75639EF0676F482A69DF0E8A9BDFBF6105E32B6FB3ADA2E29C62A0AA687820B4ED35C2418DB1A67A3A5B92DC61368585CF7F3B1B644A8137A52CA21DD982760CAB7FB111558ED0310E9FBA34E5480F4E707A2CEE74DC24AE5717C06DE2B509E4807824707505FFFC5DBFF798E8D85F758A94C2D3770674DFE03627457B2DF10628A31D44BD89D3435D93E4F9BC14D47E6D4B9BD3BB2287ADBCE1FA58495D9032A9A3ADCD56CCB116787E060EA431C1EA9E60A30B609AA9C66064017EA05BC16392992B7DFF62EF1046FC7E64F8F811CE50AAB40AC122CBD5119D3045ED0812F6E30EF6B6001285427B643E3C6FCB6390A9FE76B342A462994F2B9074B56A848538DE205C98BBBCC75DF6BF23CC1AF0B201E5A0618D4BC5035B9F71BCE9D3493A97FA47607D65865A5FF3FF17A7CE28C0E87A57FE951C8F804EADC21F161CCB5D1E66F1E4DBE92C69D4358E0CCC13A12DBE87C9B530579189EF2359A9DF5A8FDE00CB2B58EBD748B23F884626A66EA39847917995EADC1839BFEDCC24AB6BF22A5C247B6FABE8CF382DB48148915167BB47F505C184EC027C3AC741BB0F6676B0D0E7781E19FB8D4D630E71ED4843010198DB9B122CC301D432856B393632369FA1C99BA252F086E317229486C034F1960087ED4606288A7C89DB0EA0DE94700785322249E901897611913AA74F8BBF412639DDB639CBD1C41374A3EC66A87451D9E4127F7627DFDE4E1701D7FC9DE13DC7754952F659EBA7B1A861B8DFC78D1379274530B976C66F9CC4002563837C852D83B3F3BBFD892F14DBF64C976C924E3C656B69131EC17B7905507F78F073A7E509157215C988D490685F8AF23F64ED338915E72B518E4305C9CD44C219876456E87C0C59C5D7524C86CAA161C745364A12890064CA9061056F37ED1BD56B5B09B1423775BF0FCC898AB1BBC283B23DB6E91A3D749125992FF1BB598260DCFE428D2524050C1F545FFDA18A63B052C0C8CA4DF8C3BDE83EE5474395135FCA2B05157C25548B0804D1EDE"""), TestUtils.hexDecode(""" -4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") +0692e4fa67413edeabd602bff25ccbfad2e3402aa7399d8a9f7d0d6d389532019b7d3e63229d12ade7d487f1cade7f9533fbe2eb22a810c94b814a923ea83d7bccbd975af424bf5535f235117afa08156650728d96283a92d6276e34f864c37f8c11674307d653060d8310c0c7bba86515e051c3b1193087df6b22648ee59d6bc7a8c1b509b71620e3f7b5a0aa445f628e15e0725fb49e757cfbfd3dc5fe92a627bee707e33537fced3489e58fa73b49cffb2df08cd45aabaaaa491e77cf205d5be4f86f5a8d4272a5513ccdedfcc210fba346322ffeef9e11dfece2cfb7b854eba1ab581cc533cc6335b2195a20dadb86fae9efea0ab0c7d17710f8b0d8a157272509803c3b49fde1063e9297920bf245fe6502d8bf0a9a1f064d5a58b30b5a14dda6698ae37127f8d867f9aea40e93da3f4af04b91caacd66031d03c0c7e229ebeec8b818f4c970acd5c4dc8e17a3ce618ca96f4ca29f46f5e4059becc5f16ee43df8ba2ee1706c41621da8530689b42136b8a62dab7c691e566b9d48a28b45af799af56bcba07bc6044b64253e9a80e9b5ee01e8af0ca627a84d1a2a7ca9b0659dd1a60b788e5f6538a8223973476e9466459fc4f20cf2d1dab3ab137c5cfab433c436e7f3a6a681f675358b6721dc2850ec7b43aafbda90d13254e4ace6016175bafc1bc28dbf29541639527f246f6c007f41ed1fe6c0329260ce2ecc19395489b5c39d66543c0609120449037f321db95a85be51f1d01a485939390c47b53d82741edd3a5febac17ae6a8a4ca45df32fa6875b4e907d544e529ad26f29b6f923e21acd7964fe739fc1864d72eabe0859ad5e98142ead24c91167fc072a2c2673c7c5bf6da83fc7d662283347388891ca575f275907d06bab987ee5081c2ec808c81c563c902203f8d525243e20b5963967bbbdfa2e8ca9ec8ed703d8dd66c29c8a550c4676044703bc93f969e35f77194412bfb20441bc5e89b5e3238b766940779217af090e0da162e0f95761f63e05a378d0424af4c899a0a68060d9d0e5a035f6ecadbd550961850ee9345111491140810e2eaeff08d8a817700ab4c148c95086ee0663c4261b3cd53f8ab5b5841ba8cb9be8c5ad146d8549f21750be69951fffcca492624e136ed58a5e81cfb01a2147cfc5ca07a0721a38adcd25fed771411c75a5f7ff37457cab19d866b2da0fc45bc77e122143800546bc49f44909042d96bfdc63ac60f09bf4a75e171ece95bfffdfa73b4e509750ec6579996d0c83d59afc88ce9af26715be98cc8e6d05a14188a0fac6af1e96fdebe8f10b994d50ae6e84be257e6392e78d70441bdc5de30a1a4a5cfc7d5637810651fd471e162df2a76571c6d3df3b227e89cebcfec352d0f1af41a29e993af22514960c64dffc72a9819a6092150bd440487108024f0243db54ea68881d1c99b529ab529ebca98ea690046b1e37f6f1110686f6d9a7a725aa115c5e9be4189eba063d28801ef85973d0e9eb15179cb64378b6a5304cce09c82864bfed361ffe1702a9ff8e51a214b584247b967e5bb7f64b955acf25bd1073179776d9c03790d46f828342b90ffa2a45081184c3be0caf7aaf6c354b698e9256421ea3688c6fc18132d4e8d956baf9b821e64a579b1462ed4e990259867899ebddb19a861b24c20c2b0a6c274a064e1d1db366a293673153752847a2a5acc23b573ce0975655b79fe1a1ccb347773e3b1c5bb3028a1508687d17f9bf86ebbecb3086db5ef2559be02a68f1cabb47eec1671e6d3d35b65371fd5487b413fee14691745d0eb260c9008f07b5ce629c6d748c452c3131225f8c7586d99b2122202860f6e73c7def4401919e02e18471d1fd874b7c728296648b5ab571c517dea55be9f9ba65ff2cb349576a76030789dec17102a375ef8d779f2f2ed17be8fc41b84b1ef69ed18cefe28122127f211ee1abaf2a4044a3b1ee653395141da50db99dd3f73f85b5c0158a74f6f9707c7f62beffd70c068db1d6ef686cad7bb859c98049935e73aa4ea76c3225d4f19b333a4290ed0d723c6192034618fe3214306536741e20b066a6b9190972f4c4722534bf760a07e8d3a45dfbc67dbb8a5874332a4fc0e0a0640ca3999b93d34e4d8731957465e213577bade1f9b371540dbba188674ea205db7b244c77b6a772caf69f8b46b7b05439a852232348ef6d437bf7c6c79a4c0520a8ead1f3c00de2a063eb5a1e162f4db1ee94f1fb94f56f62d951da29f6b3018485c4a5c2c5f8573691aa096d8cd2922b66c8b7fc828d49e92a3d648cfa8ef524199b4bf5a8f15693960c5f59862825ccdda554b17e9c35f7e6a24365508f5a23c6ae211e3db71740fa444f92159c8df59c4b073f362cdb658842466efde20e9ba0472e2f682ecb655961ba8ad7575e8b02320ab6fce9188321816968a15789977084409d89b487253c778ef1ea1a1f47c750e37138735bcd58f6956ab7c8dd1c8a7ad35067c0ba0940b3b091c362d3165007df94167f33e0c660cf02ee5d6ed90c8ab4655ed47655d810751dfb2f1e65c890ed24c976bba0b8a998102d660a05325261b38fdfc82ba300683df5d561f73a11fe6f06425d11ef4c6f32e6de2ee6081a9b772e07614866f54e63ccbf7b1d9a1c3701ccbd1d9087241d8e2987203dc798d9431b8ab1fde5ad788db13c2e996a1d21b1559cffe3f7132e1aa83acf6c517d8e8d719076a36c08b2c6afbe5d23dfb9c5272ffb2af2b8febd51946199b90f98e7d49358057fb881f4e8641e0524c3471c0f6bb4cf59bccc7dcf09ab2c2d8a783710c982a35e4512c30e1c19bbfeffd992884ade3dd2a90039ebef2c23ab98fdfaaf6ebf34ae7fcb7fe742798c50a49d740244e65c49b22144c05047061e592b32ab61733a73b55ae04c9f36273dcb2eeb4872e7b7d009d4a54b867613ca0f69c4e7756a48ba7f9539048d495a578b8a76cac198d77aeb6c3a7dd474390f91faea384c94cfd73486ec226319946fd829c3ced266ab11db84176c7f67502b6d50ddf46994d6bf748f118045457e3ad7192f0b03c2bcb2455d018bd0ab1306b473f3761fee60d941637c562cdcda0dd5d5e86af9e95bc22570c07c25d5bbc6f1ce04be9e7bce5f7f095afec8b7c4cd930f9bc106e85eb8620668b52c9d09897460b1c8d74febabd73ff9b730c291c28f1410b442d91c533383ac3f2f41f0bcfebc9121b00015d8c506b2183b7d183751636da9226b795eacb2a1223004ea8a18a805b272384ea239ab86b41c556591fbabb783a6f909d5a181f3563ff1f9abe58cc921c751f3340497d94b1b2c6ced1e3e4345e73879296bfd9dade021b25436d73a3caced5e2ea070824262b5d6877aabfc0e8ecf6fe0000000000000000000000000000000000000000000000000000000000000d172332""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +a15c38cf5d89e1912b7ecbd269ebc6ac156697942a3b2557f5cb631782ee2ebf3158452ea076bbbf6eafbea078f2da4b969380c279ee4c5133ba8b1e9e3243c30e9085c353bc1210717f47b099d405b0878e0dbc24cd59c6a5181cf07355c10891059c18fd085f9b2aec6df7e6a21ab24094d8357d1b86aa6bd15ae92e9b0929d7bace3d73160d312dd7bb5af9fcdb0cdfd91dda2688d8e507ae12063c22128c69514c8d61a3912397d031549003dc5e2974f6db4238a8c5f1e5ab7d53751e5165f7c3d443a3fab54af972f7f6cb2b154a215ff6b410f45ae17d654fdfb58d0cd19fe75b61aa0f10ee1448d850fc7582b16a4ee6876ef6cc3663921607ce6da3709bcaaa92f15dad54eb8db0ae01f6e093663e0748c33f1ce041bc4566545c0b78dd606991d43fc76a9a1e1fac2c1765bbfd70eef0ef941763f0e32e83258bf2950dbfe8a391aeb927959447a7930dd5a006bc449091ffad53a3c725d5e3b01870cd5bcf9bbcd0bd33de9cad5407ec36b69a7bbb9cb0eadd182b9efa59c1423271217ccc268690ecb7c82c5f8df1df4726bb67ad80b04d3658a6dd1e98201d7c0062bd2bfeab30dcdbaad3b0bad393f1baf3924814ccf5bf6f4c8fdf5976f7b7dfd6242890a7306922c347547d051665c6288444a2bdd918f7346fc7cc8959ee3f8b936011e7e96b2a255af38158cea9df1faf6217d1bb989b09a8de3741d95ee834fdd2ab3962372a2879cfe93b1db989f9503da17e4c4294a6ecaf99a48ce2c79e2ee84c093cfae7bbf2dbbb9373ed2ab1c4e99da39d2b2a25633364c3e08a89b18b82aceed6a77fd805ec3b924f7dc96db19aa0737bf3d5606ba6e95808844a9395995f3a1341f3178159ae83b06b816b73e6e403ce72a93bd60ed2cd3c82863410f1d8e43d9f4c85573085ac80721344bedcafeb14171359a4df9486c844d17e38a4e0006e8c7196198ea8466007ba4e98d6119af88eea0925cebb1f998f988b42961c44f74e337cc693223bfc34142268d33f30e8bdf8480b44bfad1e3f8266d35dc1b5bd6758d0a8d66c7c5a1b93e49f6e0134d49f437257850fd8a6af26fb31b9f7384a7275bdcd69aac0474dae9778f054673bbde6e9dbf441368cef3f8829c45bbfeffbf8d07d7611abe67a5d55c8f2edee611fffacd9b8e1139d39c152a461232c972a8259a8bc7131d1d8b04709dd16e9a2771c95a7e57f7159c723bbf154771d34c7eb85230c57ba06e031da4be80202d7d12ccc74ec2ffcaea3dcda60259b6cf894b9af179f9f627846ceefd4088977911993b49b225fd886185a2739c44b11915896b442ba1ae53777ba23f21cba23f78aaef5a881f92d87827e27990db4de004d17891aeeaf1f91b86dd3f7e1a956f960131b78b3d7eb9789e7a914c4a635ca5181e1396f25b4fd71a7c3da7c1406337390163cff9cd04d74ac34d4debdaa4b4cc212fd5aab3031ba539816be8ea7391ecaaa467041590f36d2a68905e3cf2f5c33ecfd2fcc982d536ee9517069a05f4d6c7fec442dd12fdffb0b6ff021d2f981b44c22d9ea74d2f49f34a43fe96713878f9f0ed43b7864d2b8155dc48a377f93f07a0432c2594ef63c0ec8d26276962c91898643674cb1b11420991deb3fb49650d5c009586519e166fdd0e178078db1554b9484be3313629a835548baca23beafc403e15b89be58810f1eb7aeb302b94d7ef6ecdaff0866c28a98a3d3d283946bed126396f3f3f3f8738e7b69ca9c7c5e856b8f91f325c342dac913098e775af449f0655b6dff597a74ed92187a0bbada59fdb2e23c1c76ddeb19eb017f9c0b0302052db7c6edd11ae1de302f97a4f0f0d95dcc3c2c3e58"""), TestUtils.hexDecode(""" -3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), +22AA98C685E1552B525B4302C943037F668279C224B6270DCAF2B06C4F4AB1254C48DE253829FE6DFFA9CB6BB294F054711BAE3FBACFB900CFD1F0844E55D51EC6F697B998759B14C13392DDB6F7DEBA77FFC22468781CE402"""), TestUtils.hexDecode(""" -4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") +5129dae7c620ef4c5d6b0e0f7b43acd806adc035cfb3901e162be14f2371bba72674649e2004b4d055ab533316dc520afa8c80e5285f40f7ea4ef876e68b0aa4a559ec2363032efe5fd5a1d5050be8221c24b23c403ccf71bde5410b7e5ded038255dfca9439992fddc4fddf96654c78098c84e0182d954e204510bc7e5635ac29cfef21042bd52dde771a500099c75311c8657c5fc5bf303b7769ce8c2de7548b388224e727505c42e6bb69d48d845d9a43e845e7305a098657385307ab23c6bdc70de07868ecc1470b98e2da98fde4636af76fddbde6af2b60b4f27e38d4a86bed60e6f995533261cf91a618c07df0f659561f61bbbd70dd2b020cb04ac1fb6ee1a31ee4f4ae5d0bc2af22d60701700a44f2e8d11b72f4d03b3a96e2fa491e6e61f8dfd3ca678e4eedaac1e6bf418cc4a34b24bddfce3975d84740f7fb92ac2dd7aea450f91bd6ced924f7204754026f649868ccb103100b79d3ab2fdd2f916a76a6212bc583f1f5e541dfbbfb10234681c42ad56a95331c90f5e8b3be82a5b82ed4292094d9d60569fa760628e082740bb2da0a14b2516dda632c007ae3089a2068d2ef48b3f713999a699ab180ca99d7c49c4a0f40b908dc51d9a17db286721f8541839d6acb5eaefcaba5b1ba21e5ace4be0924eb0246e4d195a6eea6e962bb07bef9001a23dc0be7497a1ac79da047ed45b4c38196100b7ce06f466df295655076d14308d94d55103d36799a0683573768bb6baac4a10bd3120e9d47d7798121ab46521d7de8d1c3cd9618347d8947c47676c547231e5be77153f02a3eccaa99a75230e45fd4c1e6a6f951d1a5e6c3be098caf4a16ea3ee88473b1a8d91c0886685409ba9a099bbc0438fedd280f459de3c9c57c92609a865add4cfe76eae9af088680f92a68ab78765f7ad0b95aadfc0a91e175f07ab1f0887b1f448530866f002fc089a63a2e2d33ba63ca1985737ab0b9a73d23af11420d62a8b619dfec0830cf62757ae7f0402a4c0f209d03ed8f1731db5079dc5671c19c5bef712d34479b7f879dbe694e1bfbabc9c05109c615be763dd9ff5ffba888f88b62128b09475527d12203ae67f1ee8da83678b8a4b7b16f7700f919874eaaca48c10cef50a0f447baa17dd19eda59a1f71ad1cdc88e91fd91424e8c668fc93690b9b5914db40ba677a3c71a6d2cd05f42321463c12d55de1a717f69c132dc35e3bddfc23064ee2183e175e1ead1d075c7c1115c8cab91677ad6b483d7151010a7314ad558eafc3128c2dd590aa4e32e8c86cf769ff58ca5f37ee3a4ca0c9f9b2c4a9cdf2a8ae52d1d09110245a8884ac52c597e97b0b0304ee706795abed33f2f1885973253da8728742b54d4e908536c93ee11c1cc36da21d8ed4956255c0a28262baf50ff4a8df767e71a2d920f53b25084ed2cd8069fd13c0d1ef81f6989c0e93609038e9c6174d2a9333b3676ba24886917f32b7316d45dc6e99497f813b599d0bacc432ede0584c654551d3217c63911654b21e0631a5f7abf66d48b2cebff62cbf41ded241a59816fa9ba99cb29a9d000873fff81c689ee95bb9fd31a31863e1bf08fae8b27169c7705344b7085c917bc4434c9bcbaa27423f634233f75b82ebc7adb307f6cc3310ba95478572820973732f4cd3d1f749b728605ffdf23472810d01f6f9580b3852a5c2c7be4f93615960541eb2dc4d5557dffa8646d916370f89e09947e4e14092073357283fff846bd6b83d81092639de3b6ee260770b21275491a6300c12d5ad261f19d8081c9a659bb3f45cff2dc6c04313c7f3fb1b2d4ca96a603259310628356cab1431bee201ef7181f0f9d35e13b6f89a3698a56c3fe08a76418b6ea10b70bb2c0649f7b506f4b15a2578902d6df4065d4c3e79ed26a0d965e97b5ccb47110cf3317b7d90abcc9c7567ad4f2c11c5ca6617e643ee55096894c793d18adcce74c19620b112ab80152984de200d4e4a6ee29ce266b47d662accbb42fc74e7e088138faeb06f32e469d019979cf0b55aec3f420f97029852379417498605cd513fae94c5a5bdf3eec29c54634b94c6a96b0087ef2c8b2e32ad49144a70d27026a5900f9bde658645190ad83583ce8d4a174bf3956f3a581d7e4ee013a4263172d09b3e888299a06a0dd4cdd7e2a118fd753791afd91e0acc9eb1e4d3322feb169e47ac2e9e3e47908f293cb7988387c956806bc4e5bb9f65a84cdf2df9376c2eaf3ebae6a9a710da2083af685a8de79e9e27143c6894a847aa9134cb184b7dc7028b664246dda558891bdbcff3af3a5e0ca8ed06c1402d31cb5afca6260f4cae55fb6a6781768e6a1fbeedaaaee620ec0b7b964a38bf46651de29e4ad7247359df1cf4e50e71f691b73092a2f75f4669a145ffc5a51d51187f42dba767d28a39800789c88752be0c0e0b5aa2aeb3737f1028db4fba59dfba974f9ed8734a57f1f2db29d14f708cb83fbea9e4889f6bfd6f09d714ffe825056215be601bb8b6168d787a6d17335b87986913ff6aee38ad38f571435195b439cd82930a3386ba6e304b72fb5cf04b1ad8d64d8334f5ce0d14718232c613cc12ac1341706f829fa50a5c3010f8d5daf04c3bfde5ba88fc873a2e018d274bcbe85a9559eb224f6c23df124263772aa1262d9932ab813f50317bd7d4a6b0cfc207d8dad53d193d7330c9330d9bf866047237df5baedc69ff546308d2547b5c7f9e0909ff97da474bd3075413b94cf97fe331201f2cb565438182f13acb95529fa6cbd18ef92dab1bd8522f332ab5f375fcfbe01a83e38eef6381a032f9adb60b59e5eb54786f5dff4f5e003b79c7e119663c38e7e9baa0199d3ba32235166936a850c57227b1a16561ee407f7bf09cf6671ce0d0ed0f9d7f916a0ff7f41d8adff8c42b8f4640f1488841cd3cc1e38918dcadd752318080b4f15e58dc7f79aedf3805e1cffc25bb01591f15f54155c59a798a8bb9d5247eeb5d9bbb3abfd65f0bb65f119dc05cc0105475fed4f006e61a1864a29b53770e5b3cae2fa13b5a0d1b05ab9db868a7b1349c9b31d1a1abc19250be50627e8f7283af7d12c57a1c110cbf4acaf5990621d5c04729d475a97cf21c5fb252f5f1514b8d3090cf6e4e22a0146fce697d88d0637b3a60e77b9cbf527c4269adebd5eaddf12633c53f1ff09d869a846d3121371aca8252a5ca1f4fb1b7afbbb3256e53a9f25a3dfbb3a95e9beb67711d27689a28aac998b3129861d9acc72122d43c300bd58d934bd9aaff2ebb55268b94fe7013aa8670a89b19e1cc5d201ce2e73f6bcd8649a18f8caf1af021d374570728690a6cff0f3fb04050a0e17344e7483879798adbfd2ec112325282a3b5d6d72868c95999da4a7c7cacf141a1e2c5e657d7f939ca1a4f3000000000000000000000000000000000000000d1d303d""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +85c8fae58f6c8a7690e2098cdcb1e487e83a1ff669b31724113a0d9f796a68c81164211555e9d9dfec48b46c5eec597bac9fc1fd484cefa07338594b3634b8b58639a8d50a12f76aa7db8ae4c68e733d0903eb94ca3c69012c0b674f198c4f8cd1ed5c345efe6e94d42cdcfeea184fc0bd8986611968503a96f0f2dc5dfd56b6880f211f64d23d4c4e0451381d0a5b917ee0d31a6f782de660381b0f791b371a71506a12b8ed520b9843a34c29abb0795fd661daa226bad6e21345f93ac59aabcef6b7404ecdd11c52fd7c76b5d7e588562489b2a27d039214f41be58f9dc89a6e1daf1d47d6324d96f9dd35e15d83fe686af8f3a65f99a45f918e43d404b481130a1039df8f453e53f7df54ab4fc70006dcc578bb2b2ee96c4816856142de04e43215c0b1f33cb3381ae07062a2698967e965539d435f9b010a38336c303ce8a41591e9cfb9b5cb491faf8b60890a313dde19616a200d844fbe125a25f61495a48af66ae3a490c415fabe05794c841e5e8b27c39e3c05fdd2bc44baca13cbcae569998c172e5325b3f89464d8240273e7a0da097ff7b4116ef1adab1b436d80150bed523682c9ceb8e308b50761ea061b6aa23a0c9e22ab02502f8482183e13cd90a0826698ea63da26d60dd3f7b6d514efba52f351822bb7b2373c2a33318a20f4d74b5bdd17b68e7aec62d80b09278a051c7c769db9a3f416cbc9ba411af50d9ffeb6665cb5b40e0cff170460a6a26e37725f49d1170953a4be705d4fb88086decc49303e761b7bfbea9f289f49378a793bd58be0a34ebd819fd40ae07edb975414dc4e61ef23e5cd503dadd7250e50ab8c6236c3f1b0d836129d735122b6c7a30080347a8140185da8a899fcebf6d8d76387feed318be512d00e9ead0c2d5f8d14fd212019bd68d5084fc4781089d867678fea30c26788f1e724f1a989d542dd96f4d8c30d30dc819eaac63278334a44b4d7b8b91cfe9e3b3999ad77d72605ac293c135061613991403c2fb84367ad98efcc1e793dd717e2ae9e24b8f7ef98f1739f46cc46b7d4226ce5c1dc03b5aa14ddb72725970df13bbf9c7dc607361661d311fec0a6e44f36e115c18b78b9d1949ce5eb36dcefd33c23c53c05b2d17289453fa359d2bb1f1ec04c604b6b356cb86870215c3e474cfc893b1141868958e3707e3d64adf77d4a3c637be8bd7909f0260d91a48f5bed9bf42bd00fb9262d9fc1d40af8566ae13b4043d274ab0a87e9897ec1ea945b88d9eec3beba831999a4acb35e42a3639cf0e8d506b61dce0f0df241326f9892cb93eb1e0dc9fb57ceaa04004ae2a1274aef2596f3daee8ffc4c07df06b476efbedef82325e8adc14279dffdc43592fc8e20ac1f307383defea6e97ae06d96272f4ff56fcd97b15f7fc48b499ab625dde351ace7b3aa8dd6786bb3f376407aa7b1d11aab9a587386ba98fc3a255ba62f00191b464b28cffe3806a0541ddb97308d1172b62353c8e724aa2358226b11480e3d93644bcb552820b86cb46f4379b1f51ef09049c43ff0b97ae65f44ff03380933d80e733f11eedb8001f6ef3bbfc4365f7e1e242f88047f7089cef1385bdc0aa723b1a7acec932884b9df3637bd9218697b91370462ebe8de16163d2aed8a32c9af887f7b282e13fb88c0b062fe2c819217495fc63e81c7b26cfee142ca9568bac3dba7edaa0697976cceed5963697248475aa311a17cea8a24819b8245fb1073de9f13b24804caefd25502940d24f40b5993b135decebe4ac0abfc611185bdc4749646d72f47326b2318c5ce173499a189fad25a2d2e830a381730d5e8c43d3bc3862c6324f8765413468a39abc37631e98bb79059ed"""), TestUtils.hexDecode(""" -0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), +0B0F604B53752973C4A72EF940C3FBA910AA9AF2916D673D69C4AE4DE92A237F271E84921C309B59B92E795BD26C5C015EC5176155DDAE8FA17D7BEFCEE3A23E0201669CC55A6F270CF0D03FFC09BBE4B47D318B6926808EBB49EC8B57A849896E76648D51117E8F518088D66B69D88E09D298186C10B5678EB8AE43E9C0A794C63CA9D597C4B74C959E9C1E8E0F46698CD64CFF3C0FC6174CFC51095E142DED9F16E5B2D3656555D2D42832280164E0C10C5817AE47ABACEE7C3BFD198A21BDD1C420F2EF0776E5EEFA46E8BCB49388FA6B937FD1FEB2BF09D5B9494A534F19BDE4E7BB8A5E4C558C2A166006B481A7C5865069A3DEA2B880AA503B5C020F045A4D9C3E5C590E4AD5375E74B732695A11164B5A57AA665922431498A9218CEB9ECD92700E92BD11E0A8140938C4FB9543FA5DE8EDADD1EDBDAAD11A6AEFF2EA409638B2C7AD546EFE390729982304F35D7F889C0CCC81D67F5A1D6201BC4BE8D1AD2D3CB85815CB9669B56F845148DA0DD2D6B5D7C4986DD3F10BDC78EAD8B4A88B7AE1FE11C634355F60A43A55C88B37954CDA71F4744C8E2B4D7F8D4A2BF60EF0C44CDC7F7059AC48A94B10279921709827A3E1E7A46DD857616E6B737CDFAB71CBD47639245E392DC116614CA3F099B8F2092AD667DAC43B8501DEA9876E5E0B98B41733DA63A2517A49C169A95E583F18F2E1DAEB4425E307509CC6B0B376827F0BAAFC2FB2ABD4E4151A8DBDCB8C22C78F5DFEF0DD1743B047E58537866795D67E35358020CF75F0D2B80287D62AECD6D34D18494D01B4412B1CFF279CA69C18A263E7B862F514A7A64BF192586ECD460D22DD2280373A66ED987635761C3CC34A5BF6A370F9F8B16F98808767A2D9A1517544D869E674980758B15BA7844027D3593432101FBC51FA4709F4D041BE9FF31DB9B7430F1D7F8E06C22C4BF3F8798D50C92641CDBF0B2C88E88666029FC985FD4E9FFDCD779C7F7600D02AE8D9E3CE6FF76F0B449C41BDB785BBAC9CF58ED7ED1525D7C7E885C0D46ADD0F7CC3B14394235B9176B69A222567E6533870EA540F4DED9A1D78F2CB89E6C1DEBE67249ED8F31C87499E24DAB0434FB9B40EA695499C76A1618A37B1AAA5309A914B6574209A61DE0633F086EE4F2455299C70B981532A23DC453939D223BA3A25122AD498795624C727E973C052E69AC40AD465DF55ADBB20FEEE76BF2906EFA7B0D9D5EAE860FE02500E2E0F4A21CABCF963D91262EAFEE814BDF9775874D656F8BDE11DA29327E3E7C7C95395D0DDF766CF34005CE86592F6787D1044E5CA1962C4DF2719308B2D6335FAC77DF46092CD3D5D228E381BD7E5FB4D2EC18B19E18E4748F662AB34C3F2C33877BF4A8D43A63F9B5DC75861AABB42D34EF37EF19CADBA110A3807D1699B247BEFE3D61AB84941ACB227C79CA05180FD3415D0E76EB31B4DD903D78553F2C22563F9B22BB876E81EDAECA4B8FB9415E2BD5AC32CC08775A20E8F90A1681C9957DFC330B6343E58F841906EE3562ADD6AA53FA1EC4AA2E894AFE769116E29AF49D0FBE2D8FEBA215E470ECEA81B258977A0FFCB17666953C29B2F70559DA00610398A08E0A17D69705707569D6484C4203C06B17439E9D4D9DB8456682A79659DAB332DDF45C67E527304013A422E46F2989BCF033DB143676A4EA720D0DD75584298CBAA765CBB0B09EF267D503F2782A427459FD2A83676DEA43C01D288429A82527A69B1EB19DD3BA1AB7428220BA74F79A81377F7ABBC027D96903AF6ADB4644E9F5CE676FC4D3ABD977D6438F4743476F77F3DA6E822AE61E0AD38549BD21E0FAC1C963F1D47F9E6BA6019591DE22BCEE5D5C9CBC4106A369C04BDF633F41EB1D6821B1F43194CC14B02B753584A659EA46C49B983F592C83BD959690845E872B471A38381CF3B2E8F4DC157D9A60FF56EC63B1C66D2227A069CEE7E48DB0E0D5991F96740D364DF89B08BA67098652958A14516534103ADD9E457E6AFC4DE1AF332EF3ECF6897B3DC8E5D6980FC5E5D829D4326F6023F48CFC9D0D787416EE61A0BA3CFF5E7C69BC83B18928AD277AABBDE271EABF8269701E526960460EEF521E83CF7A61A3CAABBEE1F1C99402EF55FD438753790CF56034AEA3292828AE858B2D3B9C8D77FF4545FAE7B4F2AE1EB17B8198F4846A8F4A105CE250F900969696E477B2C46AE786481BCDF85715BD270F9C29BECF4579F2DFFFF7750E375113E33ECABFC52E4DA5405849FE5D5F4A17C1F0984A1479D561943CD1120037EE821A2B57A12D7F1797E64E38A4B71E2FB10207ACECB96B3F3ADFF82EDCB633E388FCF11C8D105C1F6EDD41B553B4B559C3199745F3B0EB7326B867FD4CEDF4E9ABA1FD6A10E1494847FB5DC83C91F7A2DD351CD1AFDF95865701FDC658A41ACCA58E574B67929EEFEB371589374285148EB09157AA9A67F2FD54FCAFC1248F6D84951AB1A676637E9CB76C17C282DB53B1BEFAD8019F51B0400DC1CB012B97575ED81C129636C38998A2E6FC5AB7F0BF1FFDDB588BDE4590A7A0F879FFFC1183A3C6CFB341FB518D0786A6473FF9614877B1B722AF4B2E1E9B5E0DE7C3DB004EFA16F5CBF07870D7208A93A9FCE0EEB598CC54F04B1BAAA992C02BB2D27217AB20A3381EBEFA04CCB1F23E59E4B0DEC700E069DB7620E22235A4C5F54522D96ED4785ADBA7FF95F2A7DB212D3DD05E58C560E5ABD0EC238B7ED01E54ECACA7D32F7C2A3309A437E68C3AC7A9BC51025409A2A1ED05F8DB0EBB647FEFE6222D6F74DD8E4034580B675DEBA4BBFADEFFEECFF4771A0C1CB0ADCC6E9B050B85D230F6B288AC3FC24880CCBDF9C6A6976D46797B75B8532411FD89BE027CD8C81547B24B535825695A35BCDA4E2E0A3A6BCEDB73DD10DD847C4A0AAE059A07F56B0ADC0401026648BA469C534CDF6E2CAB8F581A7233D2F15BB35DC990EFBFE688F9B9AC5AA5C9B3E95DA7B0122947DA03AB9DB58090FF14B736B9CAC65F966206AE7C84B971D83944D8AB61589A28058E14193751B685058E632E32EF1E8C94BF005A3A2EC5EE2CE2FF6C05A67D87E56998E952E4557250E8AB5A979ECB28B0EE41DEE07F919E67670D9CC4077DB0D90ACCFE17CF6AE69DE0C9DBCD3D552A7FB37383574692A267B0A8BDCAF3532AB47887FCC94AEC3461A9257322095F1024C880273222295107864903F3DC8FB353FBE51C4D89F30FEAA5A570979A38B0B4AC9A4AB6B7169984C576BC4AD6DA1719CD0D5ABA03BCBF1336DE48CBBE167E4293DADDE3997061469F200A391646C8FE712EBE087B448F7A7DE437186D38A4CFBFC2919FC888487B15C60E93373D076DF6A60452E62E05256AA66BD1FB771CADB331661DB4BFA47581A4367069FA20E9C6229F79D6680125D0464F7CFDCA1F5C46688D5816CD90862FDABAE753E56BAA1369AC1AD3530630998CEB4545C4404C8B9A65D5A43443624D62DCEC989AA2CB8B85414E06AAE6BC4E219C5A3FDDF8FCC75381F6A0F73F54A7A2B5BA0F546235E71B233EC107900D8116CCD398FB14F32CEC310AC089D6BEC40255A6A877C30B05355544D115E8F85E428087A5F3670D596E31D25F676B3C6FF444AA0FFE5011AE62D6FFF86E615EBE80622BB646A318BC65950889616DEC254DB332649788C07E46CE590C2362EE66BB33BD43807A1336B94198BECE586CBBE3136B5CC809F24DB5BC3069E9C1FDFE53C6D1DE29DF48A9000A7E89D6862A773832DE2151423D9D11D722D923233137DB6F34F8DFA4EEC134BC9EF5A70424D895638D1B09D95D98CFA17308908D65AF00259DFB5ECFEAC55DD7FAAEEAFD4E94EFB36698D2315D795A93B8BA6A3CA93F6B79F2E599149BFBFC6F5C5742A83C886BDD4539BCC128F30B370FFABBE724AA3F3D571785AA6234FD2359FB3468A06A8E74918EE6E87CB29178900B49891F565A80BFF302BAFD0D5C2C123973BA7B9B425973CB3D7F2AFF3059D272A7CE611F5CDDB5AFF3E2B4024FDF0E01D7AD1C63FB47D9BA986C341030B3E5C6CD3CDC6A3DF9D6901E76D31C141C37619F5BB316209FAF8428AF19236DD426D70EC81E77309D5D9AC33CF3AACC0259A19F91E4579AE49EEBA41CF79B9499CD1211AF1E6DCDC70383A35E0ABF7B53A1203AADCD3AE638862D35EC4E441100E8CDEC7F0E6D22845F6CDCDA801111C4C7F261189C7D67B981101C40F21D33D05E336F1C7443560238C72B34E47758927E37F972247F4457EA60B2546F6B5B7A91B151E8B3800CC1748587E0D5421A43648BBC5D87C591B01C229C8104CA87C0B7F0770ECABD1E2A858147B62F607A86E1C71EF73C036B18C01CA5C1BA8242BC4BB7414FC90C0A8372F860F2EE51DCC1E457135776C377F940400AC5309112E6742617FC226EDDF51E95CAB40CAB58CAE1E662DD78C6E253B373BE970129193DAC7DAE372CBEA847248C2E69273B7CFEE70BEE59DECF64126D44BACAB5F2813CFEE1EF89AA3FD6D030319CDCE94FA86E4E64998266082F8BF74877038ED888C16907A8DF99BB53809E54520E4B5B6AD44849A33EC3FA44A7B179350DB07524823FE8384413F0A7E1936D8CAAAFE1052C462778B36AB8A9A14BCCC0319CF6EE2AFF01EF5077A10BC0FD0DF76D9B806481BAD1F49EA013942F38BFE52FB194EF8ACB283B1462BFFE4AC618D6FEE7E25130EC71D68C81A9532A16520075EBC1E9C3FCDF5FFCC150F3815E8647F34DAA814935D0E1AB68EC6A1B14FC7566415CC11E0C14A9693B8711DE2D3F78EBC468269BC851D2ACDFF5E8A6388B73E33F20C0C7621C6B644649AB088DC191418292A698EFA4871224232A7788EFA2D69F9F9FBE80FB8E6B0106405F6406D00A6D6185EB521372CEDF51C2E0876C7A86A90F1F5DCC0EB3187DF8BC62736663F713A1D403665BD5AEFD6BCD3413FC63CD68B3C5C7FDE3AC4164FC3737C2703AAC85E6ECEB29E34A6ED70D4178402814B5207ED2AE12E9DE009D0DE6A0BABCBC4ED41D5C28B1943C4B61D8B1DBF4395F5BACE1E47ECF0EB9E21F9E7F663EAC3788E935A1AF73B19714ED91BCCCDBEDAF1C74155CF235A58485BCDFEA58A929ED1E959DC99345C36109E42A14438466B1F9E728801BCADD16B2D8F762E4BB8B3F01E531339DE79634F43117DF5C585D7D2FB4A5D3E82BC25FD92BB1298AC79211B3866CA1019666AFCB10BBEE1AB63263F2823A86DD3EC57E8632C9F4975155A01F22859EBC400F5A3B8302ADAA5892A320487AD077B144392528F100F0A222DDCE5636AD5962AC6D62A2382167EA977743CAA6BA2F140655DFDEF168BD620C73A47A8831DFD66DC6F2A9F47E0724081681BE62FD15C74846980683B729AF1757203F457FF12925B6B7BC81775A9E5C53862B07D4B93CB2E9FA896AF58D258384115F1C63779E4189832C29C8B142DFF30C00DCAD2328A63C92CD1E42B2A8D2E18542BA3A81686452C83AFD5F6955A708CC1DAE500718C6DB89ADCBEBF119C4707B931E685BAC00AA60E3B5F9F42FDA6EA90F5C77295E84A3AB05D69212C5368E24F18F43B450181884D7AE8BBC61E1603FDEB13797F9620AD6C2B863C495821F7F726BD5801A3D5A36F4609B595B7653799B3794E4A60090D71F5DE1AA5F0CF562F7E722C55AFB676395ED988A491A34B462B2D18AF517569531308B8190F0148CFAD463802AC62C6CB289FC0C95C207AADF82AA7399E0476B774D9B876829ED91EA3E5C40B504370D266B7B3C72DDE2CCB7F3AB8E820ECB5715289451D352D83DB67EEA889EBF9E8B012C8265376C841BAF6EDA4067A400D4C6FB00539F3839A8D0B29906F9923B9244132282E38242257C339A0D0BA8F05F75D41ADA51E29E33BF65F78981F04F397BD5F9580376A8D1C552363D6BE90EC83C2AF748CBB7783D6B26098C641777A260F5F60A712C7A7D1CE681CA1FF969B8F25B90F9A2B03F71E06A848DF3C5C8571C5626D5A1F123DD14A9F90B3958A7EFB3FD522C7E83F897CBA80B95099F1705E1CB22C7E91DB644880F7DAB480B29FC0F8E1D0ADBAA123F1E1FE36835ABEC924531065354B77DC1082DD690B316A7BF104140F6316C46E81E777F56EECE625EA030C1FFBA3A4D40745E77129230A69D76C226A80A8CD31720B08D9207F22F8F3068C169B41E7136F94B73047377A8AC0987490E4DA2B7619A760E3B61369BF762FA9A3ADCB014CFD0644AB1FE6D8D3EFBFEC893E98289DA93AE19D8DE41AB33FD717200B6949AD21B3290C77D5B1FA44EEC7D0C6A9978D50B40DF77823FF2613BC80D0E11DC2B790B332D5267851B6315AC08D0A2D6FC0A8F93DCD20DA6054894F84C88CE254057CD2FE36693F868D812DD1D978897597840CB336223F8A8EEA9C15AC05D3E40333391680C4F4CD5C2F600CAA684BF09EFC8A9B71E6883E9353C22B379BB6ED8ED83A2468287121207D9ABF61D2DD5116D3B163F262BD3D57A23EF2E6154BF6EEC1DF88B961C4505F7CFD2E23E0E0D245A9418292A5AE6E60F3852D78D19E1EACBE9F42A522FA57554308A1D01E31DDCFB7C38534F7B48E0384AAB4B81A93681ECE4C55BEB089092E757A4633B2F30BA83E470B3ABDEDF9135DF22E2B29CCD0893C54C329DA1B16C2FE4221F1C7EBF6B3D6DE84EA1DA57392762FD9C64C0771966B0E1FA9A6E286C23128DF317F704237B97A339A623C985BFD6A0C60DE48EBDD73A0610A22B02D0978E626B50171FC8390B80F37E5E536CC184259D4ECFFA958DEE1A27CF3D2EFC9B218809909B19D573EF86087A1C9BE161C54DD1279E022F98030669FC93A7BF03FB101A3FB5321F654D2B40EF8298844806BB66EC32F7AB3BC7BED2AA7F22AF20759B12A0E3F82D3C3A141F393DE746D5A0D91F32D8249F0DB0FE37D27E49795C648EC6D96E352115FE4F10D1F56C39FF9140E3E87F13AF3C6480D6150E1B7B4AE614A577D6E81694C19E468761039E970335FDE9945F6119F6ADC184C9F2A434C681D593F34D258F2A8847E02DA5EA2605A007B25031DCCBA8A8C50C77411D197E742D4B3994471AE84E2B612B09B2BBAA38C5E71C22A8E3DD1F284A681DDD45E962F9D061846EDB9713D4F925A9DAC0E32D2A4496F68C68448EDFA87FDE3ECD47411AF5DA95D8C48D5CED988AFD72BCB7A81896EB1496F468D4664A58EC3874BC6FF6A85692790BB405592DFAF53CBAC93884A842EB2D3DE9619843919CD9D68AD89DC7A84BE54C406B8208428066011807D722C2B34D4A279EE43BDEB967360D9BAE50F654B2A06B576B803544DCDDAD670CF8D2D7723929842C6AFC4093BBFBB75D1F5E03682500AA0A34FC66CE4409D08C726552ED5ABB0C646E89B35A659C67F6F398D6BE39D9725BB0322D458DE2A62E46B62013F2BAE5E60C3D41975C6A4C6231F4B0EA2827329279459840911891B0111FB4B1FE99FBB482FED56C7BFBA15882CE5E2FA2C73E0B682EADEE6F68E4E1A9CD92FDC2CF30902453A16622AAB1273407B985FA4B7DB40D87812F2A10183464F8173D22D5603C44586B107B4B82E94DD80E87AD49E9C0FAB5C3330B74E89F742CA1A5940F0F329F56DFD40C6869D0BA8CA412AF9C5116ADBB3C22080F93142C7778D52C4D75F1EABE13FE50877C26D7DB429E991506ECF1DDF30A00F9E0B355306B889F41BBFD1B4D27B67952E4A0B53D1BF8B2E84497F00826D84A913F02649D5145383163F3C3F586EDAD06F518B64D9B300C4540A67593B9F3358FF2A22AC4BD7E7B9AEE507D184E039ECA3BBA0B5C584D3359D7121BCCE01691E11C120925A7D8B100751E8ADE99D3676C7355BA4BE451920BC7D2AD6E8EF0A9693F16FBB570122FE5F5FFBDFA490B3C84809ACD898FC0F807C77937C7CEB6F03308D3E9C657F80730EF3A1CEC6959850FAA6C158F23B23D28ED53BD77531F1012DC1753CE1AD6E0A629E14BCCE9D56B74E09AD6EEC9DC4A5C92049D48AE21222AF706B1C4DE65AA814AEF5B7E1EDF2D8A9C5B98853A17199DDC3233C5583B95756F5A9C175FF7D0891010F5D36A268ED5C9F58433A69185931E11BCBEEECAA240C2C5A4ADB4E770109F3F16CFAA37AF98E1228FFA7C584B13F850FED0187FB836E0A01B19CF700849EFF09BE1A57DE41CE1D52EA6F182E0DDDF741DBD2150113B10CC3D9E44917E0FD9717D6D361A88060E202039AAD8F31E4E6FBB4D7FD1BB5D6DC20C3D83F23D120EC98FF4912F3D9AB18D8EECBD7EFD1CF9B19081B38CD959660E8C63A539939D0CEDA897F5ECDFDEE16ECA492B216BEA35A167178F4A0FB76175D160FE2EF97BD6BA0E296922CE60D91FCBB3343ADF477F8A92AEB56A471B0711CAC45DA8EEBD21FE83FA68EB74C8502C81C65506C92C4A3F19ECDC2B7A5AB47704DDFB2E8D5AE620CA0D67197699677EDA3FC4FB821BFFB5F2DB03D4DDEC0BEB13EF84EC372A5C56C1E712C8D23D1A2DB1BA077645C85689CA2258E9B1B807DCC6394680B72938E1B61AC3E8A5B9E84BB4B58CE5C8C2246A604C05701C026185CFB872BA78CEE33EAFD0486A22C6D5CF9264EC134DD79548F3CF5FAA67D8B1FE74F6AF7B897AB0A0D8CABD5E1B2829CFE66D58CE00E68C6F23FC35397FBBF96D2E63825C96BC3CEB22FCF9CA46C93538F8DF566145D06207533627B665E39DD284F4275051229F3CCE9E9E62EDDFA55BB2AB1D1D8E8E6145B3E38F35F90B89C15FE799EC14F7E415FCE4EFA72615EAD26C10C1FFA4FDBA2EE04C4845489C21BE45C478D8B2116C84AAC21B48BD4181FC28C7C21AC9CF95D8B04C0D817C8ED8083D9CF8B81213AA2E3B8BBF4AD66A7AFDCDC4C420945F5B3E8C8AEC5C4F98005A0CE1B3283F5FC0FCF8567A150E12639CA85D298CE8E4F9E0C53817D3009284A5A0BD5D3A07234AF751AD059E301076946DECFED43DB1176A2BBA4B8A571299FDE4AA3574B6C189A721674E004F259B00B26EF5AA90794FD622040B80CA6C5E9FBD44B3DB21290353878F4D8D87496E374B05E6A5B25742A885569DBA2501367EF4C549BD5CE6169914A7F1D311D52CCFBE2091F0DB436506F210C137C2180B89626F52B4192C67ED06C1F9175E44B9468E6FC2208A98DE577962D9B4C31D5B0DCF4017DB1BBB2F80512C89B9AADE69DBD584452D25CAC97A4A7E6F48BCB909907B93F5B8108EDAD38CF7FB541328C5E8AB867DDCADD6A1B5083869E68EBC785C80ACD260C715624360F2F3D78FC1B2A464FE0525059A3D5E04BCCD72D23BC680CF7B25C5CD2AD6A0BB8366DB24B671D5BB3C12554D37C7A662AF9B9DB61DC6C7DE288DF1976DE08743426CDD30AFFDA05A8390A8F3A4A94D7CCD33BDB229E32850A77B2256CC595BE515F9E6854463966D4DB7A946276F594AD4BDF0B9C59D4D38E211A4465AEE023CE6C062FDF4123ACDED834F672C1A724BC17D44DE9632A588E7EAA77F3183E09D2ED55099BB1AC8198C96EC7B1635139980D5CA4B8B3102375A2E08BC3BC754D9FE659C3FA403218BC8C00FA87A0FA6F096E336865DDF02BB05049CDC9680E99C4F567ACD25AA7CC76C182A8DFC174BF6FAAF4D2553A4207922C1EA10CA8DA3E35DFBBFB5F6919FD4088A3A8E48358CEF25576A3A6447980F1C716EB58E755196A672C378F6615E54E9A16CEBA33CEA918768961C244A561164B61754F679856575DDCB32C70447BB738E84CA590CB523C6553F13EAC77461A58A7D4E1CC1E36E7BC5E85860B0E6B67C70D398AC0BABE1F42426D9E7F12B5E362BF3BDBAC42C572730C5F4EEA957FD3F17050625BA9D9938380249290AAF31BAC"""), TestUtils.hexDecode(""" -279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") +d90e5ad6ce804eb56c37cc30b96369f19a67ee324697634f7a40b3d150ba7891f9d8e5a7499781b5ef8f462ce1626eba1213bdf47ea40203aa7b9f6632a02c172826d96683de98ef1fbd163f817d6b4c71ed7fc9ec3a2db3d0bc692f94812d69ddfa81c15292b507d7aa3642b100472acdd9db20f19b60d98e10f1f47fd8f1498cc618a00b8c23ddf109957b78ebb9f5a7d6167fa907f52e312fb333b224c2e1b9b45ffe6027a90efea98d854ab6c6de67a5f24ee28d917caf0014774770989a4816f39fef30dc70b7e068bb306ab404611620b9dcfd40e1cc72400e398cfa342a616fbd5eb075d340d9f1d095b54d01d190b055f21d4de73ccebaec652f982535919e8ec7df3ce42f6e0807252f88d4fae025c68e5dfcd9ac0af5af610608011c630beab1b1bc760c550e79696333b34eab93fa7afc68e900686d1828bfe2bdb57332a9dcb84c66f12638a1ca4ab413efb847078b79610c51ae1cd81fac71319f8e43d356baba173c9775f9dd2569c3699a2cd2e9accc5ff725bc951b6c007e7d7b16b5f3efbde405d7d945dd1fb38724c52958427cc14d7a1f913c2c911fbc50e61a1aea400383561c78d32a38677ee62b201067c6744500f27135fd789e6adbafcd841a2796bedebe47059a8917f5eddc09eedf7aa6187f7f9e91e3893a3870b307a47da4366f767045390e1df69909d50e57ce6b2656a9f9eea5222cb8a05142c09ce230dc49edd7c4107241a4f317577c135a656071335408b809a18588f7dba155bff5acab476e99e62b0249e362d75ac201772552865f91eda373f722d19eb4e4f66c94627667af033c4d4f8e6eacdbb2a6abf47c931527c66da42f8ac3bc1a9c38e88a9d862beb1785ef9e1edcc3aac6477fcb78bea88b5a7796bc6e3e33ff1e0ca1fa73e66307e409365ccc8cf5a0cdba2bc96a7150d030b1349b15469ba21c7d53c641402776d61fca08d0a6268b43c063f51f110b8708251030cf393eed4898e2fc4f9654c05e700ca3e9d9b68274556f88c61c35860579ccbbfbf3dc367a88b076a4618772cac1c225069ed77168bc9e50737d2502d6b102a8904cb3118489e39c31507203175b35a295980cce3f9653330307583e3cbe2ec1d6e5578db4e5fed4bceb20922036891dd58b00e0e98a408f2212c5cebc7faaee235162bcfe6e482d4d1ca012078aa78bc9001a021c14e2ce86e484ad41ddae6c256f05cbbd64d99d20ca4fd0fa65d3565bd749689ded6c835d1370b047dbf1da76cb99f43ce660654725a40f7e8dc99716bd12bc3b3cc140eac2d230ee9177c8766e3cdd8d83948c98ac97b28826918a8835b5b563e887fa2ae18fd47d2c56e7a213d92533f05bb608baa68518ffcbb15e6847a776029809450ff9c0d4fa422fee078fefb04e860f5edc713412436e836f873bca3515842f70841f400db22e21c7a9c1ae25727a39e7e00e29abf256cfd8817115303a40c61577ce6e914b8c6e9481165f554be7a58c22c6a66266222ec80f1af4c6455301cbd80f5cb42d69f524d9a121699eca6d78bfc4db7bebdd8d03f83a638882aba3967f377be4f54295205b8f284a341796b4a00ce517e41ad2ac1d1dec2189a702b957a4d5d67fa1625341266585a220f0c276e339c29f58b13227021b6631cc37701899f0d7a761e13220ac0c39b5f98c688571915c38f8d0a23811d11cea0ff0e319e2bb06ff31990e00aa254e671f350bb9be4a5c78a992ea5de9276b0c542e2544d6a9a2e0339805ab40a9066352e2cf864a102406c4a11268b0ea22d029bdf694cd2ae75d9184920a9a707ab649a8f422ce4a85fd30aadcc07d3dde5b3b753668a303267aa1e43c81617b6aff5c7cdfcdb66eae646146903cf84a014c696473d0c52e19fc5da06bafc475ebbc367cd775676175b4268b42132f2959349a39e73ed553fbb50c8b213e4ae9d8682b837a3d8d938d4a4cfa72b564a39f5137afaaa442b562ff09bbb5c2faa2197f227979a9cf580dcbf01a07da6239f709fa91185e1a0d0847d77a50a4825fc0c2a6dc7140de2d4789b1fb4587c2e9b24f33d11728071548ea967622a1b97af44b51b2300c2c87d1f05b8d0e710a2ea5e123e479717cda447c0d4cc2ccfe753e6da45c38f568a8c2a82418420fa5de3fe08e196f2e2c6691b7774f4d4351c37e974721d4c505a6ba037969034627d05014a543e96956cc991e583abc9125aac8324f46e71345811f7ed8553bab0d166cd8bfe2fc21aa96c1ac168b40c61aaa7ff5461cd2c1339e8ac3c54cb1a8abf0ca4e7edd9e9842a01a91eeb6f3702be5e81936d53f11ae7d191cc6b8afbbf1f78dec898a0c30df889f43a8cfa8ce1d2a324c15b501a0ace8076b26334fcf03bb3db377d285a812f3ad76c0ecd7aa3b76f9072e40b272d514fad2d661d168b00c2b27ed394d4cffbbe38ffd1e7b84bfac69b4fca99b8f316471fd37678e4501f16ae1b2acb472c065aad5b482cc893fba258f29a90e1faa8f4c5235f136b25d1e451f20784e6b761dbe4fa68a41285baa9634f7d87807c407a9e7be6e483f3f224367caeba42f0df19b5dce47630396ec6ac6ff1b5c23e02f599cad3ef117ff74d7331facf763c39ea70c2071087774ef8a2ff268f27d06b96e50bd52eb5ab55a9f5530339abe6f07d5a27f64aa8015b5d2a768452f8ca82484113420464d06d7c61ec25c89a422b788f3bae8e79c0020fc93122f53356a9e678087f80b1938e42fbee9efab604f959b7f4d8c52d900d71b24c39a1cac0831c22907ab3348ad20bd6818023a72266983678edad084a13ee07196fddeb52c79bfb925e3ef4bae2ac564b04956c0097800546e965687584c2738a2009b0caa15183ba1b6966488fdcca6937bffdd9cd6f51424a83cb6324d2c845dbcc9237bde7126516ea59d36cf2b63ce239db57c01bce472886eff29ca612510ca318398aae4618b8d6fd9f6c6e8cceb4b3dbe5d059038b9a6b81e07f3599cb1febf3b0dae4eb9d5e3b6a3e11b24aef1377cd941f94a56f7c7f1fd85807d9d97ea0aace9d94516dd7ee271880f4a7bd18b4266c510e16f95aead24a9d3202ef331028b0f4233023aef2d18aefcb5dc66eea08013463c008b86faf617fcb6929a2bb78ee0459788792c9e3b5d3cf92371f4555c0955bc746264cf6f56edcd8bc8d044c170610fe76edf0e875f9d6d12eceeafd955e0130805963455a348ce41788cea9e2601decc02006907f5e092fa70d2f0f21945a5f24edc734da33efef7efeb22c8b142d86a47d9d5c13f93258eaa396e3ce55b8f6ce736a5010a347b7f9298babcc6d7e4fb03192d4e57daeaf7fd03041d262d47676d8b8c93b0b6b7bfe4e9f9fc0a161e3368a1c7cce7f200000000000000000000000000000000000000000000000000000000000d162933""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +c298f170b4286195747d986e0de1fbb602feb53b5f242a12bfa2b7602b22358a3334e7bc913d08f6457753c611730936fabf6e8c5863a0ad142f8b4fa0f1e68ca0e588749fdc255de072dec16e7d62e2b4fc1a20cedc7879c6fad196e4f6de33df29dfd6df65470515f6be6c9f9273473a6a6daf1d58c279e81b578cf5192b839cea97b8fc3d54048772ce1c009aee0381e37f39f82585dae69d8e03ac9d0b2d9a772b0e4a8ac46456c2f98820d1111a4db13eb26a33cef728017a0d9793d880b9d06a57b8dbb41270cc203a0f4367e52abb424533a426034e6e746a077963aba533cc54004e7a4d17a0ca93904bf1dd4da52908cec4df9abe86ea50290d3c792bbd1d629610669975ec9682a4afa4a06a37b8c90a4bfc407161f1ef6539d104c39b14ccb6d7f36ccc0a573d79c70f5b1d1f049893a31a228e32f20ea84503a1b7f2115a74089e61ad991022b11757f5c361b8bda665bc96d6fc2b999e546e48e431457016de365a50163a53ccceb193fd80e4bcfd658aa2b916bac07052d9c17c6d0c8c94017fbaa1a1f4638cc7351dfcd4b5beeee945f5ccd602fea693a105c0834ac9d730fd0bfb83c4ea5d137bbf3cc7a6ed840d5f6a22f4891d29e8d0ef2146f2785acc3404117f606b20a13bd0912e46bb3e7b707f1cb348055ab50da962fdea841bba33d43fcc2a3dc4359b0f7648f648c2600e3c84a0c9cd58b7e05cd041aea383eb7f0b6e078bc425bbedd4a29d09e095e0e44d4778d6f5733581c29231833871ee121aa2c09e44bbd3c3b8411643b67b86494859623d9d135aad0153949af237eab32f50e9cae3a6c30b2c873a5416e2c9d3cf00cc03f29cacf723f9340810c632db0801a8d8de3b7ac08f6313800f7fe501a5ec92b28bd06731fa1b95023fb635c02aa6822d88a28d595068603def2116fc0405e6d936e327364f78329f194e1d9651d7bb607908089eb25d9dec4e56991f4850a32843f10a245d2c71b58e5b5954e75a00e276b03237b23e9ec3ff258c501710e1f7bc4a03b88754ea03d84adf76b0f5e20f3fe76b5fce6eb355941a2875e2ed797069dc9f4ea3659b55fa3eeba496a153befa37fcf3004a6502717f61754854855f7b3e6b7782099603754f201bd1f49355974bb4276c70a59593e44733cb1b5c99964d4ff89611a55a1d82a91b8ae03ca4a3362cadd29ce9207c9c836f989c09b590f5f070becff4c35b318a974a923216385b6b57808ab3fea3bdf6f17ac0e4e1bc0f18473bc97a89ce5358a8c4fa04859a915f15f9a06725c77517ea112ebad0a4913af1080700b8f700af9fee59c3067ba30fbeb995b0b88eb59dbd45a1971240f15fb40e0a1084c482a01bc773559b6b8e83bdb4ffb70df25cc30212e8f22c09abb514f8152bd1affa3c7856c90bdf8b4024a1a8af3d70c3de23999f36834659eeca8bf225e16f0185409609ae8ea5d861794481cfa5b75a275d9294543c4a257f3dfdfce9c91e46468b2235bb161850bcaf76fa405dccf9918a0e2903ffa5433412ff09ba73d3c3c342525c9f653feec2d5b1596d2b8e79612d913e2c371384d1376f56a2cc9268d9c82e80567f1f27434aef775163a8b162801bef77f299c58a3363df141c63e86c717a8091d7a079afdab2835b11be5f216116018d70b0512747a066abdeea688f82d859a79a5cd2a839a907caf5469d2758d5120d4f9d7f4445f0107645e63f6af7b9078842d034ec39337f17f01fbcc31ecc4feeba4588f567a6a467f8a7870c655683c46eb776853c0f1ec4c890cf408d2e3f808673eb455bb9f333a982e7f9f393a65dad51974b1a35fad8e8077a8ef3971bb823d6f9ab494868"""), TestUtils.hexDecode(""" -3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), +0C39B65F4C2094AC626652CD33CFE44EDB2667CF722443514CAB443DC398A8EA009277BE397E1C1E7ADCD1B24376AF0F19EA50E56C90D683F8EFDE693F0F8834199544E2DEFE392B0BD46048A83C412A14834C4BCDC180457456BC72AA28F2DB247AEE84A1C49266361DA7EDD54BD9B562889131EAADAE071AE5A671646F49B2C1359382F1A3B2A6B437F87CC99A2A1BC821E1F3DBB311B8FCDF28546A479E2F9970870066A2D6447B6CE4FB65ABE7423910B9039EE3234836F924C8E82E1299335E27B0DD642B812480D6FEFC47B121A710827DE1D18DC12064649224FBC4526AE14317CC8E53BC8E9BD42BA444AD9B8B48C3AC807D7A7675F43E3021BA1DF9AC7A42A9E23D696BBD03FB5C4702B55F95854C41F470CDAD8A255436F910C089F71C2E59A44221D78AB81D4E2B059CC92A3841E1431415DAD4E6EB0315F423DA512661E4CCE098D6678F560A4BA19475296A2A1DEB12AF5900FA3A3C188867E0C268EFBF7AC53455552DF4F36E16D50E23048C7DD4E64341E6DCAA0036EE045B82C42121B0B779B5E7FF032F549536ABFB702B1CE4EAA5E389A077F47B1B55595D4888A4C1D17F4E21706779C9CDE25DD1261C8B4761A40B69E2F22F069A264E79CDFD36F307D117FC737D88F50EC67CD07D8FA269CF265A7E7CAC93E97BC29EF95C88904AB2DB61C8865A6EBB23871576DBABC83920AA015D47E8CE699A9E57E139AB7D233C577B46C9C314D084A1674A152D87D2A3D8A5D9ABCDA22E212B8C9A2BF25D8AD22AA3627E6C12C684AD2BE917F094263982D396364F4DE0BAFAB2DB89997DAF8B7E3AA953C055776FDC29F8AE5C28D4071534A9A2E9090CD3F723D3E381A2ADA6D9463FC49B3C6D2B76803F5C21D8DDCE965D2C472389D2BEFF448F2D81EDEF1C851A863AF66B64417BCC2CBBC70C18875055D171BE32C06081362FFF7DE8F8A23B076839602E2368CEEB79E4EA53F42F440D167A902A23ED53E6691AD3332DF5B0160EBC3B5C9567CF619BE2201447EA500332ABDEA9B849C3A395F596F2C96ACD9AF8313E453277B9F4234874E791E9DCFF0C9D9DFA8FA9474C026DD34E5CF3AA10CAB1FD23EA5DA0D0A66E520096C6116944F2E5747A974BF55428A3D2475F6276490AADA25220F2F2111892DB9E9C75A5401BADBF69F31B77535044DC50B1E93849F19C0B6C5184F1B14F68960F9F469805F3843198AC68E51619F3D712A34279AEA27BE4357A99C44C456BD2D9319147285680922B98DBC4D6D2860515D1371D2141C7A1E76EEF8586AFC973713EB89C1F09A84AC064BB7644625224FF1F7316B9DD1091CEB151D1A040F7E60F202728F7862589E7F1FA32D39653383F90C67D96D9949967AF234592903CBB968E0D979B92B5C69D09EF4E767741F1F6E361DCFC8D751CB8C3BAAC4CC393D63F71AA1488491CA06CC20B0BF54C5C225B6F0825677C2C40A395E1B7322288A815E59AD2999D61FE09C95828CE18B2997AEDCED56CA8BCDA4343B1E948256AC5EBDA23A8E6D7102A4474CE23567084547F2ADD9DE77483398D81A9A9C7A573D7EDAF99536D31C3588BB649EFE1495CEDED788EBBFD5775842D91DAAA2F9BE08D63B06DB35E72CD0EE5DBF45DF9B0CA682BD944A733D6875A62F8C53A3FA9337F13429FACB288C73220C29285B2D87DF2CB1A54631AF3D0035C1F3B26A5EDD07760A63576A395827F3D5F9B03D9E47A9E1E6A271021942648B8424234080492BBC56C692C769B5DF32A75F7403C88469E54432A37A895E3CAD3AB110089ACF534A0D78C2083CFE149A2D0A5055EF9F4C943CBE1FD393292518CECFC57E4FFC4D07A563A30528A6A3540636A3BE770B7CF03F5004D7C6F8ADA08DEAAED0422AC0C0C8D7515C9F8BF44195D6DC30D9B3036DA007A910BD05DF06B032812CE8393AE2777D717A691D07E860C1EDA60F6DE31F0787097D0D483E3A51CA7997646503738CDBAEBCC21AE4B984B668FB4020C139D9F581EBACB7BE263A33955DD68C9ED9BD2DD6C0A7BD049972B624CB7E787DE7184023F33EC0A1539C4679D6B4677FB971D763BE17D989FDF8C0AC4E0B5A6CB40A49B5464610A110EBEE9A21BB0D6A2F043015EB2C8820DD966A13EFD18D32367834D41E8673E997B2803638A710580CA08DDB4D90E4E8EE584BCA2FB853A122274142130A1ABCDF7DA6C0056689195099CC3382AF6987BA47EE294353674E7295ACC1C070F1D8E4107AA7189F20CC818F1D86F6D646CEE911B304E2FECD5A14CF5F36331AA86E10C319C96E52996D4CC12810AD7C1DD1DBDFDC78DF029BFDE9E8F9B1FC7D9DA99FBB0304A8129EC58A82177EECB7330E715BB3C0B4482923C7B1EC0D1823FF643014C7D08A8F2D9F9090B0F83663AFC5E601E5FBE1DDBE678B9D93C5A23F564B8A4DD29C8D19106747959E72AFA4B16B879E3C6E7F79A212A144F9AAF665253F1360ACF7DF37642270656583E06FAC85389A3AD76E69BC2735B1C3E13B80CCBD298EE25C29F9F5C275AAD83BA0E7C47526253BB3125EBDF5CCD6E1C4F9D9CD4891167BB4E4D2AA644D5D362C6F790E2776BDBAF8D96DC3A543C72ED46E431FABD737B4BF0F4B32E12E0520E60401CCEBBB40180985948045C58B0017C3D8797E433A2E2C64B9679EC7409D59B3992053EEF2ACD7B152E5F564196876EA0A31CB6ED47F2455BBEE6827D96C6B99E46F3DF1FA21F593E842B26E83D843118F6833BC273E12C7224E00E840B0041544893C6C8A06523DEDE2ACE7365693BCC6A8D7DD81B01310CBB8084C5FD3868539F8B5179519CA6745B56C4A5EEE8F2A8A60CBC7453E1E0990D176446D97F34A2D0BD5C5712E2D82601D0B9FC9A3F2420C65E4532DB3810FBE3635B2AC3A84415535FE41208B907EB3E97AD63DDC4FD694127EF1E948801B5CF651119CE17BEAE3396C098A86548B67DDABADCEEDF60F57D2941815778AC14F78C78516F84C5F9749B433DB97A9283A94697419CF94248B6819D9310324977D47A133AE9F1FC141B56D6302817761BBD52B4A1EF808E0AC761426C99E0504ACB6B552F9550D55DE787C12A0409A9F9EE3674617D15E229AAA98BBF4FE49CDC81DA3AD110645132B332B6D2AA38B35320925135BDD225053D6594E78389909E596C63B85DCA8B3F6C3233A31A1F8F3E900E49DF83F649E592979C9CA4BE65E7D6D1F23A7744626972D52B07B7B89CD90238A5E871666F4CA6DAFCBF34FE15983AEA5BB7F9917736F7BA46F342F0C08F56D19AB9569FD23288EBCBEE7B5924B8C86EF77748F3AA9CF2FB884398F83772C9771958B6DD063162A3AAA42E6A3280FEDEEB7A628A07702950975CD135D6338FF959ADDA2296B3E85A024F63D4ED8A5859786E2BC76C2325F37B4D91EE8B64F30E781BF48ADA774C1641CFAD2D63A59E294B5D99C94108154E38B499E3CA2A29AF7CC77A8BB3A3B712376CD081715EA715305C18B51470D5F3A6A82E9189848311511E8B0ABACF856312AE3916FBBCF6664523684D3C7ACE08D2345A3907C9C07183CB3E68C5EC3899A95430E278A72701E2355A4AF606DD8F8750F7F3682FB84290B2BE23BED99CA06D5E54190A5558C927C369C00C512342EFFC41618CA6F8FE6E3A38D1714FC44BF5679C1A49CD8BC8B28499602E277DC8832F738225920709799DE6961E0B4EC12397E7891AA772627F66F494AF719C55D056DCBF10E8E3DDF1B6C1BB2F0B2FA61949D1CA7D4E1F60EF836B086FF8C03A5916A14EB2670AF56264D7390761E6EB6F638D6FACF56B72A48F271ADE4541C8EFC91D15F69E0AA6B97EC0E9C0C3EF169E4A4DB1C1AF04762B98ECBD0DC374224D98FDF7788435BC154E1FB06C970A914C34DE52678F61ECC1969A2C5B1FF4D82E2C80CB543B4B7C9DB541229CC50CC6C448DC029CA24ECE635233C401D3715671BC75785DCFD929377AF5B65EC43EF45A9B00CC766695A4A5DE9A2E6582F7936B9FE7DBBA6762C41453683146F4ACFD809847F866DDF559972FE0C093EE7C9FAB3CAB0BC2BF8DA19466A96BBF2DD4859E2D1CE122A3CF16AAAA9A4708F72BBEBE285E1B794B2B9C7A699B36F39F033277E8B7BEAC3BC70A572556EE5C070A309D9D0BC35F4B6E55ECC91CE9AD273B0098F64E1327C85CCAEBBE67E8A118669653495D2FA09C29C6FCDF870905B2C8BE0DF806C29D5E7AFACDAC5F89116A3474D2229C76E649F99EB9EC71A2C229764A477853D68C39B8F0BF4378993AE2B26E814A337CFC103760CE92FB564E3A3E4546996CC4D8B6BE069E99861DA9C731B543BFDC006FBDE3B33D2C8C4A3F5789466122616C98F52E5E4BA239E0C3758C5BDD3BAED8809F67A70504BA061409A9D87A499236230EF0F1985DA0D765E9B7F733A154E8300490F458847A89E7C6BBEB7A9ECA7B6CBFFC3124DEDC1093C02C808DA1CDCFF5237745C5FFF51F3F15CF746D3397916A45990070490CA74A55F34EA4BA9EB73A281F123035C005BF6C7B30852665860ED13A2B5808F81435A77A8504B58CBA45559BD3BAA663A571F108685E414FC4DBF8033075E30CD6FCD9B893DA32F7C8D5D971D5EB417F1201B00F65DEF4EEED3B55B7FC7E6194B72A861439B865558157E65D4C2F8A1A93F48192099B375D111370F830B34EAF3225A16006D4749494B9AB9D3B05015E34866A4A2D94B9588A8DE8AD4CF90F2CF422634E8DBFA0FE3FAF27C3F3C2EAF9C1BDF23FDF43D196732E1FA6D2B343BB7D9F5F26FFC31B26C64A8EFE2B2D86AA34BB618FB58CCB54486211A8E66648CEAE52F07A6C1EB5234DA7CCAA971AF984D6050D1A81F10E6D19CC44B5E668CE92F4251924B25DAF41D5E381C3FAE4208D18F710B5F93CF3C776A3D81C608B06CE6BC68FB8A8117CE7BA065675B88510F2E8A440EC363A5983DDC1352E446A482C593A490AD6093258E447EF52BFD189ACD11C87A8B75F08B5D166C1DA69602EAA5916474131E20F704DF84C3FEF2AE99F9B9E8F7315A143A07C7AEDE5797F503086DF7DA971244A61909C4AFB00842FBF4C3A59B991B58AD6C0B8667C449F0D97F34CC41FE935D9F55821299F780359E2F631858617437D4AFE67DE4A1AA382B93CC3FF596726F0D1C071FD0E00883E9E03811FC659495AF2A62B45DA079A66552F2928B6A25C6416F8DECF723623764441E5E581F9B2E36479A1B6CB3DE9B090E3343277CD7F84E80219793CAED4945DF782C4B72B498A62A1F5362745662F711A7E47CB816EC7069D10CA8314845AB0C9FC326C5BCA0E2AFFB4E6948522F8CD9C8DC008855E592AEF1F8239748916878ABC493E33CCFFDB86CC2ADB99B6251F493F0D2A0BE56D133B66395AA695F6298F7F4BAB41420CA9B8CCEDF2719590287928CF6BB3A506D6678B814076B7A774BE9B7029DF9F4719AAC1D012BBD49EBCA6AF124D0AB5C5FFA92B4A895CB76B88DEA9C7105136D78B76D92079A5B001B214DDF7E140861D86ACC260B72ABEF2CB3A75C2BC87B39A9D9052D4283B71C10AE275474E82A5FEA1654EC3ECD468DE4A015CEB67BAE3275C2C79863E2883D46FAE351F0908F42825DC7D9FAE0FC7171791FCAB10E16F3F027E5043AACBDB1F05FCD2B3EC7F6F46AD6DCCD6F9E6A6AC702451194788D14261219F794EA195F2B3778654BB373C68AB4333E224D161A1F89FE440BD8E968B518EEA28E81B89E04FF1A85B879E4B54650FA8DD1322D14B4A87"""), TestUtils.hexDecode(""" -4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") +c2112c791ee26987cafdde1bc02fbb99d5b97ad71d4c75cc36cda559ba853a351b3088a5727856774fb3a100640034901b886b9aad882c879f7f7a50090b1b4372ef71a124563aaa22ed2b227f76c4c5ad691499766556691ac72d3ed717eb83c06951bc8ba4c8829b225aca7eddd999e9e6e9cfca939ba21d2f7f79c750f43719c520b344252a283cc677fcf1dc27a4dfb396541c97d7e948ab873640d1a1a0d941d2677878360eb2b703f727a00cff03547f5516d5e18b07d904e3d978a905c83b45a2a58f407a5778d6e6da955705f0e55931fb31a1b1be5196b6e80574b8e37022d4e7778bce58a817aeee7ce13c07196dfd6c00a6604e40f3d12a46c11bc6295788be5bcb2a39db2bd64780b966530496a23f9e60ab9c7a4a48a5cfc3b1f657e00aeb99eaf8ae38e723cd14191f927ebd7944da428584b23da5ada543d3c071cfe95910aecd65f7be88aa6c7bfb6e52ec3c925fcb0fa4b09d7612a8b19a4156f44d07c77eb229edc08d78b52ddb7bb3e42e95faa1b013d4861ce5166fbd0d0822baef9bb5d1f41956be5cd1efef4bd3f92beb656957c0ba51dfd4d186e4804b71e91bca6f3341ca585f0c48c3cd496a1f1736f513650fcae2379bd1d127641f1a92c0c394d2c02301d29116b3245ccfcb6ae3b55b29503a49fe6357d3f027a20c30528abe22623c53c73970090b12d994f1a69d5a9877ef15f3475cd1b9d58cc38a0289e12a09ff756c7e93bd675b2354d78ec79492051751db9b3f35a58eac539d4c6efb259de9383d5eea913c98a6daa6173b113f8d7bac440e1bc4652d1645b96c4e3ae6697c9e6e7a1332d27f28704b850cccf469f829a6aee604e0906d1b84fe104303cb9e187a19b9ef212dd334f134cdf6256dcdd39e91283e6d7f3f808fa5cebe6263fba31f766bd86fb271a524042d3b42b9d1e7729c00c6e4104eea77934fb44fbf7b22ad80eba63fcf1ac416429df3c012afd4f42984b8006e5ab52b94fca1f54fe91ddd2ba4f8366cf74597dc4c2fb1554c20ca28ca4262888d70f342b55916f6eb5a2e6df5a9d0299f2c15ca37f5cd688792a5c255e2f684035770cf4a8894b750f1f97f9c226f9c451ce0b5701a4486b9feabdd379ad31f1164706a137aa487a25c088882c282b5f67599f8f9488b3c1b0540cdd48ad57754d760880478b686914cc7cbb3f478baf3742382749edb287e867d5863fc40a5f57805d1a7006a2b45046698ce63bf85fde10d9171a618a10da3b20d97052fa9416e56ebbfc9b1cbacaafdbfdfecf18d23df346f6838d90d2f0a45aa650d08be2360ad8b3259541f86946fa047ba2cf05e9542e67307dff451a0bea83f3acd2a328f0e9a7c870dcb1b3ef6a387c208f5128951b4115aa4f58193844d54113a5d13cc6e58cc210cc4865613db00c6c515720de072a9fbc60dfb50f48fc9ee71072e14a2380b62d644dd49c7c8f5b30233434f56ebb4c00bc1106f2f7b89d6f4076480fd24857efaecb3a3921a3f9d9bb84353792bbc017ec91775660c21cc6b7c2c5b629258fe1655afda4bde38fb66d9f5b90e0f70419d06b38de8bf050e7278cc02b9b7d762dcd32245c9776da3fe15af5bde873bbfd1d84e8083a06ae1d030a7d32e9a50be599ed816e47b54ec7b686f5e8c55c8edb7d7f34302f343ae7027234205c8d3943244f91ea9c2e6f2f33fb56af3a0ccc1c101608275ffd7a18201a0cf3291320e8c1e397684c604dcb23953aac9cbd65fb8fa615dfe77dd2b7033195030b57e005e28f14b316e63c6a62d81fee131d3ae71734e90e3ca43c6516996fe169bc279e3b398e8ef8929760da3389b29c0e7139a2d889403b823b3361c310ab668167eed34f3ff6e32542619d7d5298bdf4c9e7b4849f0310f386faee38f5e94f5455ebbfce87a34fa93b808d5eac6a62b1fdc84d3895d8c78e211a7074c78262c24c5153234882a4bc043703d997a1b8ea707712ed46f6fb654758634d1591ee3d79804c8417ace22343bce4d0754f4e72e2f518bdcdff3bad1313b974f7f2b7100e6fdbf2fcc34f5eccddf570905659ace5cecd78ceb88f7fffa03bcdb71a77f975f3d13146422c765a228063cd9cc92f0031b8ba6796025ecd4caa8bab5c48b0e6f164739150ac00bbfba4ce69cd212debadd620242fd5610f3fab75e7a0eb587e4ccdd010fac040d8c0b71673f6a6165b188fb59293138048805ffaa283b9539b947efc6382c929295769bf9d5e434b9eac6d1b9ff9ac26c0a1d1f0efa3108401e4f522579e1bd504a64d1359e44fa59f4f33ac4cf3e7508aab3388cd5be219937185ef7459b9c565034c8d4920d5fc62080db0f0930630d14c285ca11e360705f8ca5786e394842230636241a461966252d634cba8f68e0fc398b4298f4ecc907f5a1fd9795e427e6de785d7bc87130d986b286afcc646723010b329e8cadbafe1a9ee23f8010fa6ae67d1bf950c5f0e6fd53d31ad52ca81dfc5225f61de691d868130bf71d6428474215c9d5236a796c29f983064a2c9f40e69efd090ba55c47313f13b52b5d9edb7206ceb0eaf57198f32a722f9a60400bf550d5ecbdb0e460c791c44e56a1301f6f6bf0d9c1ff04ef6d238c060bc10e75114f7d055b5c3c0ac2961ff42c1145a8505e5d6c53389f04b20d2cbdc56759b861c803897be3eebf932a4877b1c4a0b63c96ef9369445e48f4b0ac34bf1799075db6dbb7d18d28f15f58152b0e2e618fb4551a85f5d1613a0a908a2edbc40e4d7e9683ebf5f9f8879e415e070a8eb52c71ee5451f95f0d351c3013e160d55c1207883c8e6fc20a4aef495c4194a7bfc8afee6af3b82bbd0a32aeab5023169d0361a4449af7a19318d063e4f2ed690b28f5d0786bd6ce5f72b9a6e411d878abe616767fdae52cdac529eb07074ec518723f8f870666211bd427b5253a67e40a318563a8b2d8916a746fc47e3ce26103c437e07db67ef057bae6a953614ee7acd16532d0485ad02b4bec1b84302e1e28c41e508eac18f33f76c150c3142e1c383c28ed902dc79922749842efc4c91c75754ea5e0678a117612dfc7ea07025cfe2e4213780734c4f18e191cbd815619b41b0f2e9965499ae19666c4ea34dc1af69dd60dbbe78c6f462a20699b58f50682e9602e7f16580149797067d0ed1b0b36099a0c5732d64d1efc1f370d4c71a6e77c5d319571c3d9274444db155b11286edbb625b77d1294d6dce64ad7fe58a7808b7c9edf7699bbc0e0342dc74158ae419c01b64c07bafb6452f131bd0f889cc40419d3dfd9c7c4418a37763218498c29f19a0b0d2b3e404b525d707c8cb9ecedfd22303a597091a3c3cfd1f8fd1d252641799a9bb3c4c5c9cedee10e172b2c33393c5054777f9eb5d9e0efff000000000000000000000000000000000000000000000f1b293a""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +53a902d7abe3103058efce7d2beeea878d48063b6dc8aad68420073c43fa5173338893b842805ab8c6b94060698d44b066b008a8209d8ddb3c4c6c0b69ac78166bc97b52b4302e8fcb4a30d102f863b67cc332a2fd4d3f1858613b126a6416e528f2e7a0e12eb547acd956914391edfb42fba61dd2418ead4d0297336b75ce069e3621f5e729d2974afaf595291030a557f5256f63d08c0b475fd47a05299e29f4dd0aba10ecb6a473af5223445faf46c2d06c326d3e407061c4799f8eda4ee8a1958a16ca8a0b8f3cb8658c77429a459a67210cc325ef0b361a8e226ead6a8675f9f97be9556ff40817d169a95cf026b38afe7e28836fb14ebc9aff7c02254ab5256183312e450646885f6177110daa1675d2b2bbc722391b7e55e6d6e0dedaa772715dea46ad23e03d6b11000a187cf51f8ce5154883f80dcf200197b9b9bbd5fa870327e2d173f2ce1a43d89d7b75db2aed4d790e6e452584dd8f525a7d2e8375dc70d4a85520981d36e5378a429ebbbe858f8ce43d6a24623d7b145d29e9660b36b3ab1729b53806ba0fac817109448422f5a7bf366ce1f424ff8fa8be40855af63753ff59dd1063d39314a95f171c72c42a6a9870d09111f2ed626ede30e58074cfd938fe3eb334cc90d7ff7dfa03d6463597b2a882340ff39d018a698a16126e796e93eef162e215daa91c08106526dbfe79a7837743ca396777300f56c3e969757300f2627ecb95a0bbb553578a679652d0a2ad07efc2a55eb6f5baa7e992e6d9c2650970c6e93ca06293b7482416605b176571b1f516e0c9a2dad7fa54c0256f469e98cb1e82ece83bb4b70ee8750aab2927cba821d53f3425677ac92871d0926a2f1ecbc1dd194eb61b408acb43c712f825e153e1a996a833b199a9436384a2007678dfbc76083d51af71e032c42d4d8998a5c0ebcfc43b1a69f8b1c78c98fe57cf0d56a051fada6148d5ae7284a882ca1e912673b6b5df84fc9e6d8a76a7f57f6aef0ddc005e56bb35cd88597a15499cd55cae68ff75c43e4651d965037e4eba881adfafcabf85efb416d3df34f16372a30c83bcc56663a8439459883c6ea4776de4ae02c1f8e038525ee9a862aabd0b4465ab3c0e352ab5094ba58719c2373b3d34f11d1eb25ac268893fd511a49ca86fe7442cac88af7f2571c512817c3f324fe5a4cfda13a02659abe2c35c750abf9d39cde64b81987a177d9ba5c0759d264a1fa080b4681987bb5e5e04a3460a7c8bf230cb26fe9ddd6a97f633259affd1aafa54ccffb39e5da6241ed98a9e95d3388456e7342cfbc095dd2502456ea067dc640eb421b636fc6da7110ab35409ab52a8597f3bae8d34fcdce772c78293c2aa62c940d806dac0e67737e7480fcdd0c7a9ed9e98a7b1bb70c60df6546b5508c5dde0f75a744802ec5bf19fed717b2a878a80ae472e1895333532d7ed13810fa158cb66d93443a6baf8765db2a18e5fa35cf21001215e4ad365f10c38ee777e9cb38efc319ebe4eb106accfcd8182d9673233403f2b55cff98617a1b8be9cd65ab4c79704f082b7ca9f208177fe25a5d79cda75b4b5381b5ec55ddea73c5e837081e34aa68ac01a1412ac438ccd96f763845d58ea897ca67ced998934e310281c3a60c82140413fa130356a7d7974860ff08948bd955ff8b954a03a3d072fdbd1bc772e5a93ee4c9ff1ba44bf47a5e15de0c9746577a21e7e1c16e41c07780969d442ba5d95ceb93b05b9b5fd6993b090ecfd4b75f18d03fdd5589c830069cb32093aaa556f5a8bc49f1c0eab930899e60401ff4503d6aa56a09abdd37ad7b9536de631b0bd0b2d6eed874cd5774394560d0bdb1f5237b7d332bd"""), TestUtils.hexDecode(""" -3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), +214BC54C508E63F77B261DC59588A87CF95C233C22A339E7158C47931C1EFEF775EB3C91A32C56E888214F9F68D7CD2525B23F695871CF5EDC6979A677EC19CBC5859C63ADCE2E38C67CAEF20116508F33BE8035E9C47D124EEA5FD1651D64371451B6B96601E4A6E8292ED6841E483C3ADFC3DB242D1D7B3F036492741661F45232104A528B6FF79AA4630740BD16B37CD3E7C711B76A259C0845D6F87E4A4B306E939AD1C41022A7D5938E52B98485D95D11BE629263E6CDE20F63AE16CC2E32B6C1C442EF108D92495A759D3707AB6CF3ECC5AD7C02F133D689E252A26C014A31C65A65F079C622BE3B648496BC57C462051B17175FF81126B5BBB5324CCEAEDE0B5A8ECC0D710F04DC0C751318E8913F149E701AE0568B5426736288CAFECAB1779C7F4E96D9007635F76DEB4D379918447F30167F257B8BA825A50EE845FC4AF7C34AB200D5BF45B5F0405BE2347ACC814BCDC648C274C24F8024561FB66676534F1FC8041B63114679D9F4E8CB0BCD7BC4C54FBB4F9A178B4FCE64E705BF8FE42826EE01F691479A8815E2DA00111DE40B5CDE464A9F7A3D21BE9562FD9A5C5CB3F4F9E8F0D8D8A20B9A5AC9D7394AE4316181621B43D8220FDEDACE345234E3DFBA134BF54E458DBEF98923C1891CFB8DC9B5317E3B16C740EF373666969C95BD1C53F435D7ADE792FF9E310A191246154064D0E8F20032AF4823A335D88D5C2A943CD4CF313CF2999E237F6EC50F63936D0FF3F2C729FAF0232671C94785B67E0CF71A7CA5B32434579711EDF155D5BAEDEBBB8F0C6922AEB9798356714931AF1070C49BCA507E289F005BE9D8B46AA67CE2137935C7EFD192E4CC24DBC434B381E9A15CFC529D0064F057FC3AB592869E5F1AA5FCB299B2CCC0ED6750E318F6FC969E6A3A08059788102CCE79BC92804B1D08F3BA30492054DB6401EA251191BED1B8CD35DEA3A653D5D546D2EE8D31C2D88D6275D6C7B463D449DDAF586D5E57FFBC07ED5558D87F7DCA82E4ADF49EB9135A578468907BD8A6228EB723241D58BAF3C78C46451D2F11CA0552A05A85620001D376C6194AC6494E337388EA49821C233F32579FBAE6D11E9DB257C426D99516A16DA63A7BFA261F2B012CEE4EAF7C5C16C6331B79A26E79B1421371E574505F61D699C6DF33EA734ED14129608260B1233C387638F7ED3A34866D656D74F06C2B8D70AE60A0994F3D6C1267DCA2001EA781E5D6E17BECD284F967788227E060381ECC60A10832091319F225C972349BFEF08D4DD5298BF7EE11B693AAAC682F91DCDA113EFE0F35CFBAFF6C73DAE43B8C1124EB57713C122F0A5FB03D02C4128565FFAEADC0AC23DBE5BF123CBA024DC2F3956EBEEE95918B87D2EB22EB1A8ECC3B267528A62F2280E3DAEC02C89A01F5829B5891914DAC"""), TestUtils.hexDecode(""" -4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") +8ec19a12690fcc4af18b44a46b33caf661ff986315472e2fb9cbf0db6b11f596b5d540572ff4b722d39e5685205ae44f62645ecb6a4f319b1dff9c685f6bc65a311cdd61204bc23da3dbb96f71ecb3922ac19580212e57c121abe10baca724b0acec03dbb6de182f1bf5090131eb5ced5b8cede5444055d33838272afbf8a9d9752c0536f5b544dfd0f20d4994638157e64ff51ea35539244dfad50261f282ee2fbd5fe3b90607a4b2590cc24e67911927ada6cf9b03fd482df572e6cc7441b6129677f3d3d0c0f5e7212bbc652bf53140630bb0e3236d09943796ef92e7916a2c4fcde8c9af522d9661feb6dacacce83e14a6384afaface04e3c8c0febc6306445b84df88cd91f34235c7351048c0d75b6039a102bb0ef30f6e5fae78718be6412db19dbf7536e42b0e5efd950e764c6a80f70839d356f55d607ef58eb366a840706be8f79e8e2ba251063336c819ea3fc60ad76665cd7fc8ad9e404847e0a8ccd5aadf3fc36dd091972959e3de4a5c49bf799c97fe4ac5e993fccd03994e6afd1562a564b111c52860f564e1b335664d57de6fffe5cc93885bc34ac7d278dd28efb850f3e67e810285f47e170243454ac65a18807dca131c99be1f85e34c1c6c3bd3c1f2a13c0341ca961d871e92a2353d813c06396dd29b835971551cdd4d7fffce4d32facc1026b05ce3ac795d54db67983c5bf4aa269cce8470e535bb2555096769215d3df109e2e21b6ffeb6b7461481b80d4894300400851118abb4253b9b86c774522d544dc6c6c2a3c75ce8fb5c3ff2564b9a696ad05b228b8effdf6f54506e2afd2c284d3a988857e4aa22d9d90feef71eceb135f7d6e9462c7302acde68bbc9a813521293d515e8f36aa5ea94a7727837aca76c6fcab11013eb18921091002701166c586abac8f20770e6df05bc682a19c65dcbecc86bca8c85c9175d5f0fba67b33a383987e7483366793ba7b35942b3627a33c23a9172807b578b536fd0faa8c3d9f3d90b6bad5d2b582634b44f9ea81f3cde12ebcf48999d1da8651cbc89e87e0cc049c4d1efbe3eb625ef4e09c2f879ac1eb7e20ef58544332a50953643b02a73308cd481d0582b4edec16c4f31f8ad1ee6d3575ed3e318a8df9a0bf81eaf7bfc720268c1955033bd16fc652cf68ac5289488532665c4b584fcff68aa04b1d4ee55556973eff4d8713b2c3bb6dfe6614b9e6138ce9799ad65d824159e1cfc1519a741cce18ad822de048f19e01d40287494822393bd6d321b8ec3cfe0f402aabdf03743ed8343d442871a6a56821596144f9005f72f5bb36841975970caf6df22724959ff6c8b57049c88176f61bb1b08543d03a7c872b87ff2fb7a66ac64954feec8343f99dc5a84ef8c207033bb837bdeb64c5d4674014ec3ee792303ce5690f2d47d176037ba7ad21b8d4fa2b83d6bafce3cff48e12e12066be8ec16bb2127a26516afba6a87a1f7951ad2ba40b76a800e2c27aad75f883343ca988862a6dc4e481faea5a6dccc8fefcc79f4970bb831fc514cb993624cb7eab874af102ce5e06dbaf57d37cad159541791afb1a47f9c838db9168b27290633e0cef4446d8765ab5e70c7995d437d1128c0a3b0d5c6da7bb7b3e450574018687549eabb5122a89ebda3de0763497658f160fdf054042465eb25174609f26f4755a50d2df918dfec074aedfdf151645b73461d3eab7234aabe1d19ae9896029b57b44b90654666a2e8847d1aaab3b3525952eeb5f0f8cdbc8e3e54ebbf6be367d689e7140596ba674ba940baa5b9637c685f1a1228acd893478365ce039a0a67155eabc02ccfe8f7731d8ccf754cbfa512e604682bb1be083feb424114da3d7243498be28857f19468e5667f59625902b9cd228c366b684154a47acc23b03ff98dfe0c2d02502f6c5e7a5dd212722f5c06793b86d43494003e88818db45102e790ed30f20eac90be73df9b92f5064827fd43c9be4423f61c23dd661a6fd9856f41a2f65127d555e509919b17b0be2e27bb45b07e39482877651ab5e4222875a988a9f97a6dbf9cdccad27576426927153dc4310583c9bd8cf6fb5d50a2d2956986c7bfac0f552693355d8ce9c4dbf4dc5fd6523cf4d32ff62b4e8d9e281eca16ac706b3b737c0d2c977ce4cd4bb41e5e1e2cc16e63ee0c408713ce2831e68e271b52a86c2b8bd7a9d0fba9706a55a5b62ef3eb8a29c793f7a66e182ba4ea249a90ca8988c00396c2d858e3ad362076a97ebfe8d9870a339c0a12bf997b66ff5367b4591c8b0deff659c133e4f97740802a73fb1cc6bdb46b3f9cb31086efe81f62bc087786d1e984773aa976ac597537ff1b1e84991be89df4c1ec1e29a2d72c2dbc5449af5bb95090d1159d6b80e2c5936db148aecac22d39803cead75e78a05731f382b09b51b9a9b79ca9d5bb51b78e591bde312625e52b4ab6eaca92e95edde3baa07b8d12588c7bcd8c2ca4a7e6e5a776eca1168694da493e96fccfa6f68e25cd4d441a111d8de31a0914e19900b218ae50f21ae0659f8f8dbd7f301a061b80add0697f6201ffb0d8c6d42e3926dfd98897d967e928802c9ea3cc2d3c3b9e36b1a29e95fed603f46d990db7034d53159e5a5cd7a72f08e451b5d7dcbe0437a2f20ba5cb69046e218cd3a7b491d1eb47fbb22e2a3b103396bc7273c218bd0eac9f272e6d01a7ded0595b02694981cba45020c10aad67735d5772078099136786401282c850448fbf27e71c1233e5a992a47cda05c1946c6f3cc6cec3899dbd435a1d016b3c771153f44e46bf55fa7fb3c39d8fd1bc14244fb70d4a5b8823b39e449e4d5237e0d99e49e88a85813efd60296b8bdd24d27725f993850b2f66825b9c469f212d6ea131ad96a089350cb76f434e1d2054fc083571f857a36a93f0e6f5fb80ab74f9bef3c5bb7df3f47885f3d136acea283085b4080dbaa5b555faeee52948e6a5e0b0d7c202fd036108998704022d7361ec72a89ca5008f48d11814e8420b453ec202cd6ddbbdbfeaa03ebfbba50c508c5c1a81f6f4367a9f817c39613713c6ce439cca013e1b645854e10256f48ed38c50a7e4a76d01102782d433e612ece1aecc1f48ce45b1da41962c89e811e26895a4a953c38efb620d2285c05a99c27d8e02ff419924c99daad70827ba815c68b0165fd7c4b6ca77d3db1a61f8f95d2c5e93ed860f90abc418791dcd1f95f29f4a45a8bb637889c16c7bbea2ed4a87eb11d4c2d8a7ddc6a68d1f83b82f0d206ddaf76f796c21e0ba9dc3179e85dae4d7b3fa40da3c65c0d499b38362e179e8306b1361f3212b0df9001f325a747b808991969ea2a9b5c5d5def00b0f3139587d8890989ba5bfcbdde2e3e4e7eaf8fb162326354a53f0f2fb080c1c25474f5355627b868a9fa3babfca00000000000000000000000000000012273041""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +8786af4f2617911e937b31037e66d478136009c090bf4a971bc2f286aa31c2525c8f9b56e09a9fcf16fea34672f563b3155acf083bd828ebecf0efd3e39064b9711f3211e1f39634a3725df3096e7569d1ddcc691b199ca2c20e578ad772eff6cd0d68c97043e2530efc0b1905e48a3edfdb51afdf8a6b2742b63784aaf511e29bef9c39d5fc9b33aa61e95acf13a7109e8a92825f7fde5171ca31b0b22652f90325f96817697a661ffc0b42180be669d2065a0196a2a857bb7a3c79fda83533392b10b9aac11b0ea53aff7c323a7291fea59cd8df052f2d3b22fb268b8cce4e081bd2ff05c57f7434b09d26d222c012bfa3329da7d6fc00f69fb1c162ceb12e4b6af61ab58b0f8ecc0ac3aa1d87c84ed60afd0711c550a29fb13f4e9388dab0cc11eb0e2bec3da4a7e80aafd7f94443ace3ff4aff51c12b79dab5f05f736bcbe3dcc4675a5f339844671d623bc4964d6d771e1696ed85c5749f3b2c4face72cbe8b93d500dc6a056fedd1798f8b01798c317b5a977a4b9e79f8ade91aee8b73c0af3c06e9347b18d797c642303572e168848d60a84d3343fff120edc804fe79bb34065000e316bcbd0c925fa2487e8f10ec89cfb986206f1c6b2d6aaec470b2354df70dd5ecfc396f108b78e0475f2617ee65fab93080dc0eb31a0e12df889aeef18b97417ab5deea3215b238b2413f8d53b22a61388a5364c898eebcceeaacdeec1af995be8f32942797a9863a5ca675864f563616fe52b4c349360f4a9b823d0eeb22d3ae744306f84442e75586b6b1c1f9c205e805805f2055d4d7e836a957de5dce2677256a51b7ab6a30aaf660344c7c2927f180d231120dd9540c968da520105a524a2b141ffc96eb9039bee53da2cacaf5b9b5a750a95fe2b32aab89236a4eba885042c97c61cebbe18cbe34ce20792674be6e32e605b4b2e7461e1e7a95c67c59a7da8e8b0561164f4b8490bb7255ad58951bab2ea936e6446d115de213893d27ed1282304794fe889a6b7a523a051af7e577271ffd0a532e056f7c22b0899f8802868a2932f3d4b3697e769a406e0568fd3f3f371833a7c89cfd035536b766abb9351c2d3a09ab9abb6138f0cea3defb6001aef54314bcb1567cda06cb68565967765474ad31631d001312cbaa60ee16794e26e1c27bbbbf2bf6f2d08e48c0a910f3d79870d6de87feef4915e52f65ed6893d82e03a3c3c9f4d22deba3d9dd8cce4685f16e675d95e2e4254e46bb8d72c553f114ff041a1534b34ce7eb9bdeafbc3e1d3271ef774a8154ca31b068e89bcc41344be537226b57ffb5a7a4e3b905b377ecbe87be3aa51ea17e3eab7561e1b71f40709f9590e8b3fbfb8a89622b495a6356ac1a7d002bcf63ab4774db1ac1e257af66a6ac4175894d3b637d23aec12f57d1004b7a7a8df5766bc78a5ebbe1eb1ee9f84d496f83d6de920503d03e7310f401e6862e63f2b39dc2c899ac5e014a90e574f96c7abfe7a08475d34c4bd8053883a379f362a34cb062eef2a1b2207e50facfb47d97fc111dc887b23df7022186113aaa39caba060f58bed427107de9b05afaaac1fd09c5e86a799d975e3eea727082106b14516a06fc8fd4563c7f7255be155785d3f3ee486b15fcbe0d7feb27a0ef0468ccfc447fbe04e7d4cdc2a28ea98dd279689c1d5192c95db184c8bcd657c436387e816170d8f1b8d0fd970f3761539e29f2a41d73316c6a6ad5b6e1f59804237821a16800072f7bf113c7f874761874223412e533cd5f0d601e18792c17599e535a9accf340de625feee6680ad14b84f33efaa35ef3e57eb11b4fdaa855b91314ec966380e76ea352b4967f4c222dad5a9dbc456a9c"""), TestUtils.hexDecode(""" -0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), +E742D452F392CD3CE405908EB380CB0225A4725065AFCB0C91C5E4823471376E6424AB24D57FC4265B24DEF6CA73E28FE20468B6E26BCC9267AAD2B7B82960C3FB5A01960FAE078D5A54BB324232B6647C9DAB943533C865BABBD3DC0D1E7A1756212980D75F2C8E999DE9ABD1874E3A86DFD53340B6E424DAD9F53C3CA02B44FF8DB9906D3D4352D0EC4B1A57A33FAFF7107D38637AA410B196BD1BB1FD7AE4B7414E1037454A031839AEE4C796BA98F4A739B785E3854E9EF0D5B7415C8B7ED012B0123C335730C7021CE8C94200874EFE783D7C4BF768538A448E76120635217727C81D08976CE4B5027D4BD9D9E27E4BCA4791ADF6F8DACD1BD3A03BE5CA7F68C2A2247FD3184609EB7243D2366E5EE4C95CDD869DE41A4B47F021DE76CF27464F814837C648A7A7CE2F91104322BE3CB1160A0D10CFE90ADAEBC87BBF14387C8387F4F5AA10FBD469ED5587EEF537106CE0F3AF4CABCD4476F248C21D119523B680067B332A1CA4C657B9DE1360FD23ADE58C5538EFFC8902281FC7B5C12C22CC69E7EB18E5F6F8352B9E4935D06C96BAFD834934618D9E6B1F60292352D064A0EEAE80F7B721312FC1B6C58D68A96351431A8626CC117BE9DFA33A1625BAECF12CB1DE33BEDAD584A91546DC767D0E59764FDE3FC29052CCE23ED28CA5DA4507933C0A7702D9A1225A48B71FDE5D27B12FDFF16AC2802E3629E10D5FFC2FCC6135243A9E2F3E3867BAA0C0F0C77BAEEF9DCFBC723C7A2BCEDA39B53B415BC21A397F9A8C4DC580EC512DE4EE4E0870DF1C4FBABF4906E0CFB08863AF2A89949F8E0FF9385ACA3F588E05781C49DC563EE9E0C5D6FA512932B7F5568C1E0FF1C9492ECAA5465ABFE125B511723998C4071481BF1C53DECD59B440931AAC640D9F78B1B40EE46AC0A8FD18B4C8AADD734B0F03F02CAF6A7BFE3DAF100703BDFADA7DBB50ACE3D40A05AE6E87CEDC0B08C44796D7A63E8B5BC95D97E3EF706E1684E791D3B3A2BAE1E7A92FB70A33D896219E80751A41E16B506FF266C4BCB4346578BAA7732CA745BCB01988AADBCBBCC45C9FA3A5D38F3F8E04005AE777910032D992D5EF9DF2C0422548A980707050CAD9DE56BCE60EF74EAA4465EDE96B055999F81A2C9596A2B35C8AB3CBDDE9D26AED44527DEB9A2AF3BF6A853FA51DCCD913876A43DA3E0E2C5B42571101B7B930840B0AB64419E1043CF56AA3C2FEF5B39CB582971A5776F8FA9696CD9F67E9290E483E9BD1698E961E849A513608C3F20FF678EBE0C778C2A6DC1FD3AFFF89D646A1AB85F005AA14A0635E92191CD41A6A46CC283D2FCABACD2FA07B7E2FF97D17B36E0B222D39DC1EB61BAB8146F147579D02A87DA08AB4ACCEB32AE1C8CBBB0EE0D90A642BB76DEF4AC8C7E477888159824349EB075DF0BED236DA9B2826E67EFF220AC84AC99BE6EEB0DA904887E3A84E5208AF49BB31EAA1552EC79E5BA02458106B5A31D0AC8AF392A63947911400FE78F6C94B3F8E6B7C3B98F6548E7894EA22215C87E121441C53EED726AE26394C825517EF8A477A6DF33B5315C8DEE16ACCE76ECA60835390E65392B9FC5EB88EADBF336FE361D190ECBD0B35B22A6FE6A8D48466B5E70BB6C5FA515CD8672BFE70054038C5893E514E23B16C39198B37B06B21275C2994EDF7F9F921B320B39E29444E3D621F52C9FCE19049D403AFBF1C047C8B065543BF43A25817533A33DE6C866FE9D8A73B2CF7277CA0E8D78F4F104C5CE6FE2025992E26E49D4C49F0798278216453C00C78EA7BAC2BEE71E5273FA46044B4B5578EEBC2A9E42025A8A3526B11CEFFCFF47191109C56AE105CD70A04C3F4EC43E49346203347319D8986D15B3C4A49F02C02994D8798499DAF1E0ADB81A9AC79FE8EB55ABE2BD18EBE18A9E5F35D2F66B38CAD6F6EEBD29AEE054C05D6F0B5326CC5B86BB0FC7CDA720838593238A2FB24E0CC36DB193FB7FA66573B064497F771DB1D965953477FC28989AEA2CC004640524A6DE8270E8A5B12BFF87B3F63FBB7DA25337EE34E6E4EB45DE9A39BC9B95ED37A6A404ED2970F9C79A7C2953420732C496B855F19BBBC8ABCBABE1D26D5BA828EB060D7280046AB93979E0BF90B6F1C07CA70833BEC83DB41684F1842A23417B3BBA0A33D7AF7BAEEC14C9C96FDF30BD201C05AEC6D3D2F539D511FBB356DDF333409EC16411DC7255DF0791BD67892880A4DB082684BBCA8B7E55B421C17DF3B68720E907C1620B142C3382AE6E738F8943CD214A847A6439A682D62CF0AE8961B5F020E7126C5DD6258CA0E8F5711E5472A4C05ADFA9A6B8180B741F382090CD1C781F7CC7F23E041800F42B228C351AA21E4D916BA5D9C56CF8E9507065D729B7C3653A8BB062C0463BF0B97F13A1016BE4851F5A489081A2AB3D2AC2744008BA734ED38DA10F372D97EA0C278C709A23ABD4B07E91ACF6A6F2DB9AF7806820381845FFBDC4BD30A503A0F74F37748E3624BB2AA478210072FCA83AD1A43ACE9F2943AC1AB6CEDED67938AF921FF34F2DAD4F224EF7498BC450A67CA383A9DDA333073286A22B85570A11FE03F55119794BBE8B81EDF1966BCA5E363C15E8E8673C94E3396C9AEC28D110408DA5561296E2928C6C111A4826309F119E5456675AAF935A17E80C0BD82A9CAC2627D6FAEBEC9A928D33980A86ACDB35686306B57D466864A0320F21751FB0041BA0F4F1660774A519D3ADB304438C1709711B982EA84D1B193D026081A4663AE69C5E12C3E4A683FB356DCA618191B29290C5DB4AA6A069C3B8D61C8B7FDA779E1F34A5F62EB7DF5C563ECF1200D3FF499DD06C2BF44A2B4254318BC402EA3A047FDB3570EB40630CF1DF84D1E2BDF5449A1F65A9DEF76954B5814691C4C12BEB10A1C006189968F37A4B236D9EE0D39AC340852EC54AA64FE15E1A4433ED48153D23B2B648C8852F3E3AE485474AB2DFD58A7F0CE6691ED36818DEADC8973E6ED06AB841B0A915425D7B87E41E1E68B00BE2EB725C287FE575736F6E1AD2AAC61F02A3A00ABEB2C0FCDB35564E8446C776E980636D5D61740AB2F0736A021D82C1D66864E5DFA98C4648CFBD9C7AA865F6C97038656C9C8767898FB43B0919BC98C1D0F6FA4D90F711E5D009D4C8FD8A773B7C73CEA654A2CD52A276C6CB62265294869A052FA1634D3EDEBA1F69DA09F0568F9D2F6C511F6BD6169BA0DE25F09FFF63AED2FDD0F6D89BD01FC5B088D3EE5344FCCC0215B6436987D6167A0F2D5EA47A984DC86D45534BAF35129488F3BC2D05BFFB84A51A87A1774033244277D0F2B45EA43500F4034081711CAD67BAA9CB0A58E1D01013032EDD5EBC7095D4BCCBD28A5F32BEB685F7901BA7A839650023B0C908FF33B37D038162FB96EBA35C2919560267EE5A94035825938D168481D8E59813E20DD611E4E23D8D42C9DE1D2398CE3CCB3DE5CBC4BB16D555985F411EB5B56508C6F4E75621304DBA2F4F1A2D8B2BEC5793478E5AA0DAE6F52C43253FE7BC91D3FBA84F8525D002CC307CAFA20BF198BD8F28CB579960A1168A1D26340C8E26CEF1261F23E97B806E9F27BB51F16102527721BE0E8B930A1ACC38F0A63EA1F3FBCEA1031E441FEF4D3746EAA37B7D4F8AB354D5F079E56FF4446333C8B8B7B589CB36DF40EBC5A75D2237F3FB874E7E0FF1B96DE43BCF229DE1FED3FB6D01752B3271E1F98D4134114911BFAC8351E3186E90DA3DE2E7FBBD305C822FE6F06ED1D4774D7A66DCA0CBF740DC277C62FA641ECAFBCBE359A28FEC48D62E1D3B6215392C0F8DB601E35A6CBD978567E806168A9F5B4915A80DE405038C4A370D898ED6441F727985037A040163F14DA78378931D3B96BA486958AE8902C98BE75BD0AED53CFB609923C63615917EF0BC6D07CD183192DE3854133F701B9D4B499F958064ADAABF4080C4A019DF1E5B98C8CA265E031B8CEC355C8FFC3BE16DC3D01533ED17C9769365D023CE7F0384D40F7B6179612B5EC382982E244E2510B4831F2D53F26B142A33877961EF1F845370CE115CA5F0D2FD6926482BF3BA1AEF3212DDF36705A210D8076A4428C7F9CAC411DE590452C761028469947BEC31ADCBA229D8EA58755F2715AF6D51E581D2CAC4182557E6815BFBB84BDC54C9368764CC29AA9AB49EEC37364F85AEB3295E60CE6DB2639669F55CC49D7934BC8566AB5E207B33F29128868BCBC1DBDE1089317088EA3FE1D595376DAD3BDD156802F82B63CF4C5ADEF9A89D94493BA152F9F07A9E9CBF8D821F1D6CD602EC49B61AC4F7633EC810F3D01D4867B1F0F3021D70897593303CFA6B5A3BD0303AEC32105F854C3DBED373760DDEC9B9E8EC4AFDAD00FF2E5A05A0113522024B86F1AEE6F250AE3BF0AF1E6FB7DFA8E04E3F9D5C876731D9C33460FDC13CDCDD433B45A6BF17E98638C264DEDAC262BB03714E020F4576DCA85DFEEBD6D70E557DF9321A8AAC519C419CA20E33DA37C22047D4CF925AD67545D04300A42B22DAC098A912848302D830E06CE5BACCACEB6E9316F9B1DEEE271BC6AD9D74927CAE725CCAD0C596653731869E8071E23BF"""), TestUtils.hexDecode(""" -279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") +a99a8d52ee69a69d91581ac798a7b34cc594801ad2f15e8769de6761048ad79b7dfebfc6f97cb7694d14fc315c879de9029b2b5331f64ae72e36833d3e5bf3c4ab64b8ad225d7b17a146f4d15f05ff72a7ce975e6558d11e3dd0e24c5b8d81ecbf96c732ddc2af021f62ff48719eb70ecef5e65a3acd389afe3ebf1fd6bc218dacffe07c78ed1ea343b603e61d5af9f6399153572549b29f88139d08ac0899ef084a847ec0fa58d0ee3856dff6262fb2355873cfa1426eb3f80ab52d3f6cfac2bae2a1abb12a68e6476f7593f5e5694d541d7d09b02a39832450c80eb785fd1cc13b441a96f22910a886aaf3ff61df7ff9f079cebeeeee218495f5307da9ce916bd86698560f758896675af604a3bfc2721e8e3dd4bd6664950d7e8575a09d439ff54086efa2405dd362f03c6df688120573884b46e45970e65934b5baa1255d6344fb115ffb51aa25b1bcdee1020e754bcce521ef28bf26d7bdfa498a5a182ec8d202d7dd0c0926b71c12eb74ab4b541c822f399bb4f4a50411ff28784930e8c9a6e77afa420a958528d4848f6255067d19496a23b39b21b572158178fe1e4749b3292133ecedc0db2038fe2eac7ad1fe02f426af8391988e46bdc8b621e2c17704360decaf8d6ed08ca825b1b3b8ff95024f174949c7a6f9d8a4a079f2fab1fa0132c01f09b7f7abe7d6aadf9c53d58a97d270a1f9065b295b5c524f3bfa0de09ae02ea5b98ce4403418af601e5cc876b4f0c95ecb7c1b8bb2f72448f721d81c13cefb99106251d4f37e47dc57d9449b405a132d25a2f08ddd8dc77f0eb905d6f6eb0d0cce96b95068d669286c02f1cefdade77b3dbadfa7cb912c62279d0a4530cc5c52941b19de495e2a2a3713537b584b2f7b76e3952ead9ca20b7bc9bf26bd36176521f4347cc8b3c2553d37ee02066258dadf33306a2743917287c09ab07cef7bc4435d582e3cc2fe79c272d719f133e6e5ff1341cfc139257d5a7eb146327c03e897b9668567b6cd9fcb74711e73df074ee139a57229879b903e55a04c5c9fe9b6cf669998444b93963f85ac7176a3f021d7c9409d7ee827de8a11cdc431521c96ed22fa6f13759eb03687d997a25a9bd60800f3f534b3e9c9dba97206b7c2f326b34a087be1798866d1914e59c8eb2c77414be030f8dc270c6ab76a6e1515fc70ce50c497364fc55f0ee4f49d3d22a08c6b9348042d904ec2f8862ccf5ee0b3d22d2f1a99579d35a916748ef608406883c53f18ef4caeddcd780e4a44c872bf2dca063aa11cc715e23cd996e4e3874463a1b4711bbcdc2418e4df10667930cbc7af5ed9b629ed452c240e02b58ef61ee4f1429a6d9aa57471781887f2e1890e70f7589f8d8b4e5ad223ba9d0f73d3ec74d8249b82596c8ec733881fdd0c96d2455ff5e340298a5a6fc91cbbc1ea5a8a3908f6da6ccbec88756874de1518602557d2df30505dbdd6d59469a6f2bfd240aeab1099c350d6730892585c577936181bc9f7fa6ef3dbb0c1d39a082b1a35a86899cf26261927d52b373120225752792f02cd2f196b5540121c3f9c0fab27b44b9462f6396195e21f2e1f736095554de7221f3c9ba23b72b480852c86b179c0e4778441c3c5242d4feb9851165dad83804c7ce5d534dcf918d27ab36ea1faa48149307b95cc3bf51a6bca256f115e3c618b9787a21941b58ce52abe359eb1a5a19aaf67dd56950a6d0179637ed0ea5421b899325ba05a26771b9449ba0de0b3e674d62398e30363d1d885f424dbbc200af85c87d28ae8a3054d82d4be0196188089d180acc7197f07033cca984e20732e9029e832268ea405cadb00dd002e3506e621d3fa7b023454329abe1a48f7dc35730f5f352c25694eb2a0650f9505866d9013e8b88b19b0c5dc12ce799ce8de35caa4b6552f399f8a7b06bf1e5bea54092b504d9ce81fc3fa2a40dd9ba5a2b8711d02dc46ecc222b14655b151499f4b537260b6595a89703ff56ff4c976a4592dd53d12b6fa9a4a775acba17a1b3dcc5ec0a4e03db9c9402ef6380e62d7f76aacd613a482d31cc17a7ae99311a01916a3abffc336959a491995183f531ca9ed0af40131a28da068038649639155bd12b9d3a06238cd3c4b754905b56dcd52cd213a2ea369623f32ac7877e6150d0f5ee25de926829beda4ef67cd3c4323042aaf3deecaa4d404426f234fca778826dd3f29b007d369ff1a0af66ccbbcf20d9f33565b7ed745c160cbc5242c683588a67223d81409d77611cdce68a0478bc50422da24632852862319f20b446917557588d19d8add012137959e6791aa7ae19597a8a2f875bb8b78b17d6f5d5b10c1996414ffa08e698c7789343487a62a98474a39cac820ecb1a855dc825d1d7bb9c302f9945b4ef5ecf2e85d22fdb7f440018181ce3c71fd8a6493c7e0ac2d38ae115a018a3583eb45abb5542e66cf77587ae2e1da41ef8b98b2c2616f6b62d3e2c7e467955b0ab3431d1f5ab617adf90334d87b2c01e450c5750347c1c98fd4fd4109f13482e11e2a6ebc4a362d26c6ac9e4d112d18c1e90726a2042ea3d5543c33d32ac108dcc34999db8488895315f18fc0d359714eb6c10b0dd405f6baf03c0c7a3b89d6ec2593c317e359488ab2a1e85a722b2ccfeafcdca2e22718a17363634036af5aadae7bbe6f48ea36ae216b827aee084696c7094dfb6e4fa563b51cb1fe41f8e72db7cd527c363bb00bf8d22896f438ba637bb7fe64054d69b628254a4cdce5ad92f753cee7889c460af2fc4cb10ff6458bca2547193ee76e816a39880f48fd2e246b66efb3056cffc0d233a86307e13e7fe87e4b4c8408cf7bdcea51d189dda4c4cb4fa44b222e4d0ed51a18abf77b49fa0280dea06852e864431c1b4473e876e2fe4f00d423aaffac81b95f186467e409583252662a0761a63ac3511058b4b0028d0ad1b760994c98fd7ae64bbbcf8e615e416bf0c1a594c0fdc46f760d5dc394497cecbdbf06d7db93d2a711756a3534f7550dafa01954f291bbbb511b652b032eb00b804d654698127e2ef480c53f47efb10c949f50168b1d888c62c9bbc422dcd07ea4005d751dc31d374357c10af8991adba9e139e75e3367bd18c7e1ac9753b2241960999e6a0ab795c475f5a330baba955dd34fdeadc193d9a6ea7015b44a04d0d5fea544c140c2a419c86f89ea54e4cc2ed8830938b171514a189e5517949c94ab77a5e9521a38560f3bc4e389c7fcb0b49da3f037ad53f75a85c0fff2c43945bb3d3ad65a197c6db5fa9fe3c78293a2a499ab553af3756ddcca3892133c1ee40a7b73bd19262b33364c575e7492a5b0bcbfcacdcfe4e9ec0e264b4d52576c727d9a9da3a7d0d4e3fbff2137789499a3a5b6bac5d4d7dee0fe0317192e4144484d60626f767a7d8c99aab4bee60000000000000014263549""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +194345a0607b1df8fd01f58d30010604261e15d712806f9fb99d3dd6afc994a917dda45b8e4e58058632273a75c00a98e026389b18ba7bfb412cfb510a335d5f7bcf8c192d6e4e643404f1fba8094a76c16682fc7aa910a572be4500a034440dd666e6c1a4f0ec33c699720a44ea8ba52eaf34dab236ebdeff18516606215c8e8071d7f40443253752f9e7593c754ac2891a640633d6d0b1178ef8e52a40f840d78c972b3040eabe17b5d24f99c75b7b949ce2b4d00802b1b0c14c786483310ec86a6fa24d47283c8f3ac2033ba4745830b26751897e121a0b190befe243f034a40f43817308f9f4d37264e99f43c9a6e5ea7c5d03787a0f1e288dc24d93cd0354b32004c9891a11845d07dbabe68ed9505beeda51ce431b38a8fe8f1499b54116956dc11532c6598e0c87e7dd57422c0490f74cfa1d084d9893838b115b4241cd55ad6eb382b0c287d2135d8df9b5d026fdbb4bbba19fcaadb38e26c3d14f844e22f870026f7bea480eaff61bef74ca4d304a5b49974de22951f069744df5cfcb0b8d13d2a8e2682184d79bff6e492ddd04b51014b205a4814e2953f8c94b080b071209187678d9460dc1ae115c83e6e597035dc3578137d781d4ed549f8d66c855022069a86cc91f0ae27974cff924ea9c5e8032c4190a384f9e1eaecb7821497cb44c4bb411e107e6c507d23c877e6417fc313695c99bb71e7ff5c3f8a6093d08228b8342ae11fcb09fdaf38698b98895f519f5c87e754a4dfbbc70867661c5a6a8e6034f1b3153e779406eab5681f7697cb3b2e95f0473405b0126068963b74a08c5810310dd41058fb7180119b5138e44ef42a3debca1260b60c65daaa004616ca73d59bfcc24b18a96d72eea6dcfd018d3234278b56e398cc24367ad598cb1defadcc6e1949cb7894e7dde1e4012f432cd3d3d86e7a8ba4c96dc49002012655a11ddd17d4eab510d4dbceabc40c8bf2879e7e1fd5ae4d6d3d16840b026803e1e06116bbd74c3e3a864a2c72f4b758392377038fcf436fb83aae85c0e56676ed444248f0004d88cca4ecfb96fe1e4ad34e723a5d4a33ddd433c848cef1a65cc0bf8b16cea1bba4660af54555b48c4b1eb89d189419c2bc65b6681c1673d5998c2e51436080d3173229c84ad475b1552cbe0f937e60c4fadf3734683347216908e93cf2d41594a41b703fe7005c6bd7b1762d2ab3f0fe7e69dc5ec4f53e6460f7e924950584ee44fb3354edcf1f971f4c05c8a7be858f601d70435603f7487c9d7f51e4644aaef76e9748d8f2ed2ff6d03b4df231d63e563726eba99e549b5dd3cdc811093d255ce0b59b60e68d89c38bccbf5d37df816a286eeeea5eef12ed8e04f2222d71ae0fef9d901042b22131d7f788ab9d53a6f82f3c0fa46c9ee90d2b5d7187885fdbed61247cd44b80065a543f9806657f0e61d8e27050f817121270e7871c038377b97d3dbb26b6f935a0eb001eca6800cf4bddd0758373583e78e7cbb26db88ac874e4e183e7a0d7e4664bc573728744faa48d83c7f8fb56c06b91adb52c419f7d73446b9ac7c7c607bebb424b7a86a3a8ccc2aad419dbf7999163162facd2036ad2267e34293b710da6e6fa31b904fda337847b83f179a5936cfeecc03fe121964642d6245e63a4a5d264631d7b82278a4a689642fbcb9cfac6af2e9d81363fa46e1b71725779abd771eacfbf0d6d92e59d52b485203d568b2a6b55819a73bd129e939b1095770861a43d0f6cc44b53f50949c755c6b274612b611d5418bdb7753c337c48ef6ec49045644d875960beab7707ae7610c1382bffabefd20eef4c68eecd2c17f1bce375048b236ab98f1fe1db575475db6e1bb"""), TestUtils.hexDecode(""" -3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), +7EBAAFA6D04129716131907EAD0832AD490D09E97D865B4AFC5D6B0FFF4EDE6A52E961ED88DB60A325AFF2675DFCD6A87984884AFB8680DFA7378130E44F205398ED7B83B1AC32D2580570FD6603827E8E4F5E20A27758CE6D1299BAADB8A895AD586BDF7B64F8D7A52BC15455EEF240F22FE98CE4CEAC03CDF7E8A983D7FD1A59C5EC594474AE77DC43EE4E7B25C556BC1D91ABD2015B99B1AF5329DCD41B93793D791A44AF5D83DABB8E40675EB32120C57D9E6B7757D3E03008A2F788336B8355AD2E47E61B39BBFC2229D53BC9BA514BB20F3F9EE9266BC0015FE81980FDE5637B3018046DD3D4BC3D549EC394E190F1BB788619CFFF86C532B4B9F0F6F951C0ED691C59AB0CC438290E9D6FEC9E75BA4FDF12D2BED2CD988AC411310BFECBDAC48A61099CE0D0CE4B44EC9C97108A44E5C5EEC1D3154B4E72B8397CDB0F7D15AA358076E25B7F3EA1E6E80A214051C440EC4189137610450144641B1E71B5334F0DDCE9D5CA30274E0237E45B4D92D7D458ED9142CC23871E56411382CE40D9CA4358B417261C2E7E845637FD2E9B4357E7EA5F4A8076A7C2F40FF1F8AFABA5393512F690EABEBFB73811B974E57C2D473AC22E747A0EDD39E99FD6E5D3668F3DCA1C795CE27D1A155ED9595EAF9061CAF5C55F3EE97056AF6ED90E05D41E90926F69044746230C990118E4D0BE4C12F7A4AA0464F8FFA7CF64C07FEF171B2E43A917AAC2880675F929583E9040BA6FEEC8262002613AA91A2B8D4DBC1D36F23FA9248A2D3ADB1DC5AD669EA219D35DB17C9C25095AD7673445E59DA6CB2260C8FA57639D6BEC8AEE307BD9C96EEF00C93318DF7DFEED970DC1F61AC5C94D4086300D91199C90C95C1A24F7F1E4292A60AB67F30BA990D58C71002D3548A412276DBEF3984FAB312723880ED479080EEE2B636ADC75AD4423A6E0C5CEB7EDE528F871FAF21855C3164469B9EEB47B6D37CFE4222DCD0B9867B00BEE12C27590DD77C24FE640DDD34E9138E70D15F52E94F3874447CA5CEB48573ACFECA3554E2B76CEE4E31060BF132CED8AB953F0A280F7916810A107AB5BA66047FFF0003B1CF13BFEB77526265B98E54E76B891A89F3AC0ECDF71406674865A0936BC57F87B64424BFC8FDC41E471D951077C32B5AF960457E97CA05F3C378D94B60A9735E9EDCAA96E413FA391AA687FD07D9D021B1014CDF241E5460DB08D3B336DEB4CF0AACEA57E4DC6C464F698CFC2AD10CA72C102A25787E0B89249F63406A39A2A792B2DE04710C41DB36B55D2FA789004E593DECE9865771D8B16B5436A792FBAC9934852B1F55D518F9A07CFA56BCF488D61AE355D63BDC27DDED6A56154B8BA3AFA3EC9C01D6593C83C315527F5FC61BB169723346AB4075D09701789268EC1F02EC4A1CD8A5F2584E29F126B1ACBEEF660CBEF16A8E9FF9C0B542042EA76684F9D70F2E3F3C18606ADCB1D695112B129B301008EDD5E6121A8948E1165D350FF09647DCCF4A1F8605ACC750A0AA8319A6685153A7672B31A3DE785EB22E1D223D6271282AC18AEC83C760190799F082D7FB0F238F627271BE62AE5A36A34D65B5DEEAA12D6B14B59BD0C619D8D9A44238AEF1FF83C30118039E834F7716CD59E138E2ABEC2921D9FA92F6808A760031B2157103FD2EAE988AD6CA4F350F488261409FE91B5667A9A2EF1E226B8BFEDDEDB84ECF993E9A71220E0253D2C4B918C5521C7953FDFA00D50A32879FC0A68D2AAD13EE181DD47DB9E3D715574CB3D566BDF30209297B01A666DD7DBC5464F913599086AA2FC6C8541592CEFFA067B287EEDBF4C9B9D6CB23CE1DEED628935CB2D6B5CEFF3BC442B2BCBBEFE4AECFC455A3A64FA117CFD9289FC27E6289750005877DBF64CD562E2E7D1C99830F5AE63C70685B3898D420862A8C4569F2CFDF564EEF4F94FC34CDFEDED8854855F3A4E52C612258DB5EE4D702BBA98B450D070264FF86A440129DA2C126978DAB3341C4079A66F9C23445C5938FA799E78F157656208BA7C7BC7F936AF49D11148856BA55910A6A736D32E0974E50BFA608975E37AC0601FDA7551204EA66F524DD03F44F5DA28EED5D126C32794F1CCE747DC1E9B1FE287CA607F81FE7C795C96569E66B2F3413DA810035D472B7F5AF74F9CC70306A8EC36F1383617D0FFD92F6DEFA7EFE91C840EDF24430B197802979752FD55A8CA85FD8D4FCE774F1CCC540F77C02E16F1494DF170CD8BA57A86BFB086349D53E8A62E1DBDE03369757EADB0E985A038B31DCBEF513D4FF9A3BA6E8338EDCECA7C3E9417F9E133BC399F2EC0C72E60E809F79D55FE1A917CBE28FEF19D6D08A43F74DF496EA9305072C90AE3BA0D21A1AC0BF040920D3F5B8703C12A32A6864382E9CEE8D00CF4F93830623E76197F7F52309824B08B8E0D5DAF5662A36981D50880FD3A8D73D24430A1CB201A9D0BDE656593B37B8EC47F235B5CA251249A04507DDB81F8E5E4E5E414B3750AB168BA51A8873E6ED153E302F61F7159B658E316D6D183575D87ECA30185CF72C67543CDB658AA07B1DB220032DF80D287E769E3253C80F43570AA538EEF49F45316E176F1F9411F3C085257C6B8C708DA7B924B792389A7EC34C7F778E6100333E8B9FAE75A4D1A32E306AEE36D29FC6823399FF37CDD0D11C8D03F14740342B736C4EFB5302C141A86C857309A70BD74DB6C7C29C839F8D86F2A136F67A0FB3A3749542A9DD8D4A062672C75B67D3BDC3FA6B56F3E79008AEF8D8E04CC7781B23D0DAED64CFD1A91DBBAA2C9C4E765FE2FDFE6E8533848E51FA027B86AB05A0530F15C1B7B6BBB268F09A7865E202B1645F8B4267CB1A49A2929410823AA9B834101E9EFFEAAF6E406639AF7D2710E60A84B6205339B0719E05BC6724FC2892A017AF86D80D361A7FEE8C284CB84F5F09B90CAADD49CFD396E6AC36052F5CCC8E7667CC762A9F173F837A231D57584A3BB19671B8B71907E415A1672475ADFA11998F94F28B00903AC551E651A3F9485DC0ABA3297E561E0B5A5786BAD9EC8169CBD706AFA60AE764BFE01EC514623BAC6C4100F707C5E8A02F4B0D6265502AE4170AC3EF95B49ED1A2BAEF56F63D5667C9FC0AF4C0A8648FB6AC5444EC8A1FAF4715027AC9F5987735D1AF7C55AF4C838FE9FC84FF71F929758DD52E2BD4A34237350642C0E641B6710A66C9C1EA1D9BDA80198FCC56D45D67C3511BAC0971AC9B6166633B1713A969B8DBC3CF60FCD6998137AD713EA3ADA84169D49FBB7F5CDE362ABEB0B71D022D9ACE7FF48C9EC1A7E0C72B564FD2C620272A482941443838D0506E2294B760AC9DED5404D3C4D2898315D3E3A82D2E944D537817B9901AFEC343B95F2844CDC4AAC3836E7713739F4201B95C42FB7C99AF8667628C1B60115BCB185754148B3C7226DF14B6DE1AB4C6043329B176C9DB9B1D73B3814FEB89E84A4C91C84993752B7AD30CC707A71339E8A277A5586BA85CD090F799A6B75523A62C6DF1549D787BD8722D1F26BC2C150D6A38951F3014B83DE665B21F5D9D97F2237333CC10A4114796D56D13D643364306E7445F475729602A11F8BEB002BDDF30E579E26F2BE4AE87DC666974E24FEF2462120B6CD8E79D65A2E80542A9240D4EE1F616326AA528E2A1282EF49F0312174B67D40FFCB1370BAC5D1444D75FBFFB6B0887F4573A8C4622082E1FE349B2C73CDC92592F684769FA7D7CE6FB5AEADF38023E51DA4EE3EDB10368442B218919341FAFB22EE80DA96A52434B184D499A4C49317C62F6D6DC9EC1413D01A1CC3DC8853444E52718798EA158A12B72AF023079E5E76F41AE685494E947618C4AB3036ECDC74F7A043230A0BE116F2B617818A2C94C54CFAC964C73BEF969591A3CB2B7DC9CFAC7B4F9B64AB70BD7FAEC138E42908BC90D6ADFFBC88EF473CA8CE7BC960C4B3EFFCAB92E8259CFAFA85EDB7832B3E630D6D2CF031B8CB570E38C101A56B426C654464228D152ABCC6DEB888DFFD7FFDA974E60CCC2AF7531F38A813E263D9B20DCCB50229E7D8F379F81A280CEB90B64BA3657F1E50381B468D0A6608A4B5E107C4736FB4CAA10FF3045C05453EE12A9FB0B79845E077803C69CDCBF7CCF7D6FE6067ED152F67023CAA6095D1748414580232007AB3426FB2889E1BCDDDBA539A2D79CA523A2CD1B1314C87502909DA849BA9B11F9104772BBA27410018348832B0BFDA4F09AF02B351927F2B6D29D9CA9F330266EC035908C9D4023CDF2343B177F57903D37AB89D0F9E23EB0C4100BC6421235CE5FF2729C2ADCAC24D1151757D8C6D6DE53DEBC38FE866142D1BB593974F4D3198C03DE4625F41BE3D488575B25007C2D5970BB152BC1C23E48A88036C070BD38604C5844E4205F1EF3D7FAC0B4B9FB51F229BA322D3355E458C27685130FCBDF591C0520626E5703A2E85871A62AF0CF2DA3468C401644656CCAB33B2402074C59A0EBB57928F548B5FA4871A8B2AF0BFD9A871A5C257044C17E4967B70D0DFB59F1345526FE59B4BD92A1C06B15E3A6226A4821FD614D8DF612A3D2DDB2DB67BAA3878C68C16645CC747BA9B366677541171A9264B89EE18D9D169D341629393C5526C28B24CD4CFCACEA9C42DB2B1CAFD7F906FC17CCE16612B1261E62E2A700CE74DE73174D3A1E06AA31AA05044EC324F026CD39F7B13399D9D86EEB53A6DE84914719EE31AFFEB630F3D8F08B4FFB10016209C13BA2158ECCB4B74BF04EFA73222554FF5EC49709F7F8DC1D40005E91245F3A5E2A00B9F64678B2D8A9E6BF1D011900D9D12F7F3BB023D1E5985BF78F8D6132AF5C0B9C330F361EDE00473DC9EE7469478FEC02670E8659B643B92C5546C32FE7B0AD816A5080B5E3867DC209EA15AEB4B14E42AD58F34CED65ECB3B519A54BC25117EF8D392A85C2895B5A4B73CF93077E360A828570FFA02ABA84D6534F3EE0C935D97D1D1CFABBC0D82E48937797FAB31704588605082A950CAA23D6569AB793FDC31BBA561E729E80979DAB84ACD4EE6B2CFE06D2EE8C4183D33B9F894C6865D9CD405C7665E0150B2B649159BE684839BD12CF0091614E1F821046238DC9F538F769FCE51E9B8DEC0E98442CABD3A4296F1D4331A16D33CA356B11E3DC13937F814D3D6281A746F054606DC52B737AA40422471139867624CC8E9C559BD25C7C6D7F902677A84BA63E8CB817820048C1C0ADB6288000EF2163B51ADD4D758D1C87FFD574354B41CA5AC72228A7E9E9E75BE9DB18FED47C32E3C561C972A67D50A560017BE794AB9BB6B50CFC43D2F6D57E8D73CAD6227C896BCD18E0D7087F57C365FB9EBF5864DFA4A13B6B5DD7FFFCB648C1E1FE40B6A10EC0C45C74504CF2105AD443DFAD1E306F720B9CC37B4A30198D3123FA9FB2A7A9DB3BDD98D441B03E0EE6A8180989E76CBC71B0E8607C3A9E5D20B6008B010702FC5D59847AFCE122F3FD4FB5D89D3A3331AEFB96B593F724C04885B574A43B5EAC70B543BD191BB818768C67A10AD6E2D62AA4C65FA373A19116AD86A4F9A97064E0C0BF80106DE6654B4A3945983B7DDF3AAF1E14A04F6D3035542B0F710352AFC20FEC78B61D8548B9669F10B3D6E531AD07A84C493264DD49759D95A6AFDBEA5AED1C7D7D2AE6D2FB6747151CB6A5C2F9C1AF5CEDBD9CDE8D5993ACF080A0008BABC759A9DF035C648609E610F226ED128E2656A057862246B65C70774B68F54D68073393B85110285FB463DFE394D9DA0AE85985FD6882EF5B11FAEF2BAC18F9D9D9B5CBF0F80AE7AC4418EA658D68B14BAC135452DF271DD3348BC338BC6C789ED95D5C5625762E4CAC6514866613E6D533AB9814B7C337260BF16716478401689F4079644DF4F734281C16164D19C4ABA20ACCCDC517EF42C19A5B1CAA4658C27B61902ABF88EFF0795D2C971608B0570E016CA0568CCA3F7B38FD3DF5608154A33C1F0D70C2AD0EBB134A8F475A8BBEC8408D3B9B0BFE8A6F10FD6C979B13C3EC73F191B788A79B4D07AC45172950689584C909247DC8A4CDD686186DEA16676851B8A7C311439149B1A963B0CC60E5395B56ADF27C25A51BB4A2FB19E14CE66B6D11781E89B3EC22CB854A12D46970D1A009AAD071C479D9C731770D666CDF0BCC381A3D328542F6371FC6F5FF7C4D3BB06186C048B2A3774EAAA3CCBA1342927B498F2195213326C9E393153BC8846AFE2120B8FF4A455B59AF6E65BC0CE9CA3502BE73D74B6CD12A760A9E0E0D26BD105FD993DD879539CD666CF2025DACD481A122627594CAD7C4FE30948412C1C6A160C358E16B6B67653418A22321DF5B1A9EA0DFC3C82DE3B8CB0F48EEFA7DD6188023D1B8B7632270E63AA38873A2C4472F9EF1E8DA56D5328C00548DDC4D9FD79115C5F6168AA98099BA1AAD606FB92F8D253C9A55773E5629E84350F3BC3B00D803E83CC2516C6C29476018ACFF2ACF61584A175E67EB8952885772E6C2D7F9C2B79C8B2F2A77C73C8B0230F080DE716B2A13DBA5FDC8648F17573A2898E72B8850997B6085F98523F00516DC7A90B9C2701BDDFE505A6C330D1118AFABC731A1DEAB813AA0E17708122C0069FB61A02FF6D5EFDA990A23E1D42C520CF1975FF06F123E1AC0B0A86FE666F8843C406F5F1E1A36FBB7A0B41CC641EB49416D6F0AB03CAA6AC0CE3A3DD1977B4D16EA33CF75A37A6092003D097D0ED8FAEE89F761B40F7E600FD502887AD90BE4BA311B9F4CD9D348DF230A2EACBA3FC356B506ED8C357E228970A948FC4983AC3ED9C3ACC22FBFF56783A73231F7E0B91DFED20E754ACE7DDDDDCEFCCF3ACC76554C269D634DC228B38C284AA35C00487D7873C8CFE8E8657726FA845863719FCE5A9E32406E2191B791F76DA035A4C862176040DA9AC0F37E66FB84DF89CAAAE9D8804824725FEDB95E5380DC66CC72BBCA1E131E6B785EA2B2B4A05BDAE01B22C3D47CA85092802A8EAC42E963A62307476FCF94ED7EBE5538A8C6F28A6C65914CF48299D3BA2B89B3008D29CD874B79A72AB840815827566E50627C2C332B1BC60060BF2FDA320FB040FD14D52CA59B24E325B5783BA1BDA3B27415C9DBDAA01562466322706CDCD0307C3305DB08D2663C57F6D3307E1C73832F8CA712402C7402EFEE0F1BD77CDA08F5F6582540D34F1B2809F84EB2F540558EF9ED46D5C636C45856AE57FD9E4650359635BE72028D1CD37CD876E0DC598E360CAA1DCD1F9F2BB4CA27CDE012980080E91B1C7376622907BA6674F1EB9E80148E6A959EC74950A2B934D42B84D739F1DA528F5C6E1C90A238E5167041D4E9AE5352B74C89DAE368778A90170461ECC0D6B6C6C53CE36745A72F79AAA1C82D494BD89D719800A89127BC3FD55247C1A29FB8387F1E3576E0C45F4D327C0B24A75FE25EC6147C890F25E50AB3C43B94F451E5B5D67F8D3BAAAEA1FE211FCE8622600400F73C1398459EA7FC59D02582C2806D01023D84BB50E99AE9ACC217B7223EDAD956FE155152E7F35B2AEE1535885EC048C6E0C50D395B0F1C9D767048E9D2DA7F15BDE192C923F1C74ACE06600628602D1B0189FCADE0873880EE8544AF3E29314E2B5DF87BEB5A50ED72FDC093800B12CB2F870304289A73A65D7E2384EF3A388EA9F0013B2B5C92149E2538542D95FF020A23E976A7DB3E2C9913D87D6EFF12BB51EE298F1D2CFF18FDBAEF56B70CBA35EB9273F1E58A6CD38F1E682A759FDF8D8BFF60E7CBEA948E25DF0114BEBD4AF13E4E0D4E7C9EAAC2C5F579A1AB14E7FECF9E13F20DF873F8D0E090905D32C8F8C0033F5D8E9F1B9FF17EE04FE3656EB66F5E4777B60B047DAB9BDD883EAC31A6455D1719CB475D1715CA0D12762F94AE78CF3C8EE90E55E71D0AA4EBA6216A0E81566F7813E7759BED30860BF22178407783B9A8AAC30CB4D53AF140E33A47ABD60F33EE700C323277E751E5B32B221E4B9815FDCD400DC544DF845619FD733F164937144FC3D89D8186F8B898418459811B3E66796DE51D1373B248A9B3B9609FEA374784A33989FE9F5BB26D2148F7282E09C35E13295D90BBC7795DD72CDD4955E9D148BC779AEE9C7992BB85D8EAFD102FD690F2C679CB7003FC4E182678320738361C361747F49AC6149CF4CDA4B80581844F5EE4818BF61750047C35A4B10697892A80F07E946F357574527FD2D0187873BCE78EC99062C70CB4ABB72A104A770CD7ADBD20894E7BCE2874E45302DC0BCB9645EF28136F36E7B179BD003D5DFA68A572BEEBD40EB9AC1F9228C74A788671BBF4781AA31C7F8699813F32EA8B60414C3ECB894DC7B01E50924482E5C068F0BCA79BAD9F469770FBFCB3942D1A3E54250E87B3693329479217514A8D7B734D256C5D28EF854FC3F234BC671F5225B1DCC20E590D8E5D09C07B22EF0A89A5B863C2E652CC0B1623579541C63CE9C2C4F66BC43323D7000BBF2923F5B8A76933FAF950D2172C1D90F522301D9A0C22F470EB8673CDA0A1B494FD7EE9AC1B4597B2DBC26FEE33A08CDF91E3C59BA4F93E02D010FE3F1C1FCD694F05B7A8FD32D8E7CBC2934A25C481D9C58FED7E0AF3AAB527D6DEF43D53756F0C95B2B58A426F7F61D09F4FBE55D9AF053B92818ED9FEF1CB41FB5CA23AC85B0241900F73971558116C5809F565F71333713EF5BE87B0AC95364C9FAA80DBB9EA84B5A5790D20343141093F86942817D195ED8DF4A2DFC7F7090CA3DB46A92AABEEAE2D7DD8B9110F23A89E4FA7B5A1DA27D643BB879888A2238E221E2F67D9DF58E73C46023FB7E999059D3B81FB753B2AD333207873831AE42FAD8092AA04C0E4103B1CE0DCBD6B06CC2F0AB37CD1D10EC4C83428CDEF84041D12BF9ABEA5C80050A853CC73FFF3076BEE68078737F6EF483F486215118C640790D0CFB4C6E5243691FB73B1294E0D3A494A4A538B94FDD2746193D9FEA24C1C04F5B20D2D40B638CB932C35D953A9D31260B76DA878FD52EDED058D1DEFD9CE214D14C3112FAB00B7F2DC88F7EBCF79EEB1C9C8607D6919B8D32CC8416E2B981C141198DD9884DC3927EB0192B6361AB556EB3977E5E242E5E26BA60BD42892F46F3F2DF684D0D9FB41BE42C04F0C248938AC79F110075B42181DAE62801DF76AAB50AEDABF4361C0EC597F31245B0390CE2629DB933E450E09DD39E6A1B644B0FF672B52ACE2AF52780D3F6505551F52045028C4DEE6D1C6A34BCD5E95E9DE1BCE849643BD07E0E6FAF8B27504F859D73BDFC07FD2034595AAD85A9DD9AA5B3A72346D6F3C4B21C4CFFAD8247C8CAF0DD9A708E11450502BF3C28EEEDCB0E1D32D3EF1A3F6237E34C0E4D0222F496839B7374EBB7D786973E85392AA8FF2A9901D076DD4C65635286276698DD4388F867D1ED18650FEDA9B03C80A3B5BD0AB3A62A45ABECFD55898BDAFBA58137D4BE29EEE8B3B3D1C4467B63DBA1EFEF2C81CDE7CFB101B1E65084A0E92955690C8CDE6F93E23FD79B76DB475CD24DD92A7504510F8DC3B22EBCD0288B4E479F8DD835297B196531D2DC759364306EB6780FEF31C9E34142B55988F81312B310093F77CB89C6E819A7CD3450D0790CB7B5E33A3E5E51DF05A3BFEF63320CFF072D450D71E7239AB24E4D83A8E8E501A5BDBB041219E15517B15EEE237836672A761D36D11EC973BAF65320B368906392E2689A9936752563172B3A5ADD90066E01EB394C77E40D57553B883F446C42EBB9CCB47FA56816B06AAEB62C21C8F57F926420AB7C1D5E97E73F024C259011CD585C23D30F99D22197B569D67BF5965887AECF553A9B48DCA0C418778AAD65D4843221B8217D2D61BA5A46C4F9FF5B00B78CFA8B6496007A1444503DFB8D7CDE7A63D5D7F54EE5823A33EB3A155C20F0011304068CE0385A09170606FF6895A6955C211AEF5D13BB93866C9CF00A911A4A50A59133113A9C7DC53409097808A6D0DC44A7776B41A7A43818C77CB51F3E20107F080F6682D90399853104B8F3AC4DE8521048B22BCA58B5F7B5EB3E3503F638C1FD24568F23EC8C59A3359A5C9CED0305B1B81677E20EA35F9E896E665D3CBBCB6155E1B0539A0B26BF95396DB8548124519B71BEC19A17DFD4AA2A2E134BEFDCA352B01E1255A12377D811FAED7809C9B881B24C185F1D1273F405F5BE82FED08F26E6C11D39A604E88A1EDFAC8AD3DA9FE8B1111C7E038A14CE58B9598AAE96B7BE84C153A9B26993CECB1CE931E0CBAD5F7F6C18B68E14E83A6BCFA33AD2B3A707118D56803A1E55CAC8AA93EBC47F9EFB"""), TestUtils.hexDecode(""" -4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") +551742a530ae4d15d68f1e222c8865e6fa59541a5e4b6e137197b52a5cb84548c099c3328b28865c34e90095e8959c65f68d8e4ef9e9cab97590736dac647c93cdec474c3e6d1c934e2eea593479349b6e56b95dc356cab1e2a2a7a94dd6490d9a186879ab75f16e0bb792863a7a8a19ed88d74d22f7c17f3b55b4d6440fffd4c24d814d3c09cd80b3d3d137882439f628337061253522775d68c1072b8df9403ff65679d24b06f1a2779ed76ca3ce153c264a06cf04948eece4f06243f22898bc815a90344479a8edbee87d0c5473474b1b588006f6dce5be82c7bcc2db7b50fab4c2cf06eefed93110aa634f6691e9b757aa8a01ca52912040a3ca6cd6f9c596eedc0a9d49f1bbee32eceb2374336f07e74b425d6a894f8c3e49a255068d08ddff453dff688f9c74a2be872e2a205018fb3e0149113ce438a7b83e60f536ac616d748fb2c590f3ec7e4c81629a4fbd993ced51995432cb8b3778f7d4e375fa54c9511e8e97323ac021b7cb2184bcce98f87a2712740ea1bf33670c4a718b475b31249ddc1a9c2b216efa7b5bc01f792cdcbd07f3e7719f71b81c3a31d8cfb7dc07efa06e0740743c9bc515c0983c845b1c7b2cfe7745c8d0e6967156cd36e88c8e3eaeb3c96ede6f94a53eb05abbd3ce8abb9f4d2c350969a8d5fdd673188cf5f8da51704b7390d8de842a18f5d900da6f0de22b9b4836947acd4d49de53e6bf96295c3f89a01070fa3742ca5070b56afd534fd4bcc280bfa5233ba58e3bcc46cdcefb5a07904ead0092cc088e8ef1de2ae418a8f977dbba6b23a634b93abf5135504ec8adae1647042210be6e6e0c9b333c3f1d0dc906ea63eca4697823fa06cbaf999ffa6894353d0b886bc89b6d8b80d88a80b570aabd37e8bfebb692a61ef6e344b4bc5d10a4d4d7aa2b2c47935ce37c1f2143be5df3d55f9a947c1d7244d80a74e92822a7e178229d703ed770a3a2e8e07cd465d6b4fda758867bf09dcbf050203796ca9a6926196f13d8a5d034f566522954999ab327307189e0791866385a3eede8b8485d6c673ca69452d0a7ed6a32142b74115cd39c797e48f38111b309a3b5a122fff1c8afbfa7eac2dcac8cf225c971b88a49e845447ccfc634341e2eeb214ab57de15ec8de38300871207d8bf98a4b9a44642679a67fc1792a46bc051cbdceb15b4355f56233ea87dd6613afa535b333104292e946ac29b73d04be3b83a0a6afd275fc02d99fa0a0b1796275b45aee6fbf801f5394fd5bb2670d18bba553e533d39d0e66ff194a7555bd23ce14ecc97ebd99facaaeb8a0d0e088d2b9bebbc48b4fe32da39a310e28150936dc5e86bab264baed9721beec5a6ab21db810f1bf539d4e6283b7a382984595eabb42b21aef0a1186d66c988132b0fcd17ebf0bf9347d64e334e165d1e8107f6b49403d77516f55e973469ec6d3ca2ecfa2df3c7a82d08ce5875e4a0997ab9c4189e1b4c37b5567fa7731d6981d96e9fdc35abe9ae1a4ab30c5b329cc617a2f92cb91109738a7a41da00c48eeefd6e003d3e25de538bf85d83a4610c0f86e7af160703666e6fb525122ecbacd13242679cb02298777001fa2ae853ec73eb581229400c93408644bd64cac57854113aff1fff6855e2632e1e47bd145865a142c9ca2000b2595fd4edc7a4b4cced9dd87a596a9e245c25fc87a91d676fa0b02a237f895df9dbf2eb099a60fadc4b8829bbf7aaf94d1fdd10dc560244f0d6f5394318497eeac7cceef0bfd8316914f766396d9a5a7cf907866f85ac6e188133614490e1031dbb8abb003b2fe2995a28fac84d07dde5987a981101087606d6b4d4fc1bf7b3cf56f667ffdfc28adfefe6dfce01579859b662a189306cb048bb4b8d66fa9861e83fb28c325b89abd6838e71e5ebeead3e014f40b48a36f1d468a4a24954f571f4972afdce0d6f9dfea1cb500b6212bbac96e7a3193691eb0823a48e6f49b63eb4b571dc1b60654b6a882d84ec4a10b5faff8c0e71bf1548578a8bb4b772a9dbd1a76792e4186ccaf692a5cfeed5414be448da61b1abed7d58acf60c60022d6f87f25b291c226bd22c9445d15e2dabcdebc6fc91d780493865f4dfe420932d9a106e81f254d97b91d00efba45517edea7c8dbf369a32c9d04a5d141d3427c68b19f189af86b3e2fa8ff622a14947d4a5c4dcd12d3e12c714b32075dd9a9c35e8edd715901559efabebda589fd123d0a7ad33bb67f353bd01c4ef51b26a187986edf0ad892b4c71b2ceace37f103dfa8e933bc422a2799dce9b7ff3de92b578e065b79a8e7d4c028002f5b667886bb783bef181f4040c5b03050f9ce2b9cda0787ce21675222dfe20c40640a37058910069a0cc037ce13a2bada74027901a186b5f194792105708877eecf678aba0436c2dc304e8fc040996e488f764f3d0f52056edc69b5a6e901bb0dcc75acb8acc9f22249961cc5df3d10992a32d724699120a264cddf1450504feb09d82b0181e0148f7ea9ba61e99bcaadef0912e1c545ba9b97a93c9cf5a8c29d3ef2a2608a32684b30ee7d43e6006e81c37b636616e736a019e26079d3025b1c5a3997fd9021634627964a01786891218711daf4812cda28892fd4803dc5ab334f18355cae65eb68924ea9fae67b74ade42b96ebd43010dbd0536f7224fff388433de015721b73c60d4dfbe1101100efe6e69965fcbc8eb442a233654b94f79ac0dd967612fafff60141e1fb714a3e88147072c2b44ac434421eb5295a9ea7752abfd6dfe4e10760f0f1e6e486172d8d4b092e043d085c800a58f5c6882e37099f21565a04ff5c12ad4d716b30164d8951f6cfa56c93388fad772ac2fcbb80276a235fb4369f01c77266f2286b61510eebeccf4a610f995c850b2ca952c27875801b692f8c1ebb61758c44f97ca4628837ab1f6807b57ba56c1b2e39e1a002dc724f06a3fb1510f18b37b0b48dfc21d453ec3a576fcd3302ce89f313ff2aa895f0103e11b3c01291c112a4d9b5f67b48767dbbceb8e1a0393dc8fa7b0b7304a02e30612cee891cad631778726124860518fae5a1b162aac95a6a3aca66e1dfaded70547e4d934bb01034038a23f63e2695f554cda78d42808c750ea5dd3c7c34e74fefaa93a91ca66a472f2c1f8a1de3c6e876fb7721105685639cf82ee003704637125e9177cfd964acec7bc1474ecbb0283e317a03696bcff64e4bf6e58e3893c7fe4d41886690b29c2d6f32ce57ca25559c3739e14af58af1d96f581e469f146d727ed4ff89425f4be0f5384ccfd5941f6c859d6d532126dcf4529564be166d880b4d5b5c617173778197afc8d3dddfec020c17373d494a5461676c7b8c99a3eef2f3f52c2d304160696c7a7e8384919a9da1a7a9ddff071016172229405d707cadbedbdfec000000000000000000000010233645""") ), new SigVerTestCase( TestUtils.hexDecode(""" -09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), +d7910e2ff97acc1d1ab59e023ffe199ab92906dfd6ab2e463731ae484d0393edabdcd6ede796a718c4421fb97c22ed9634ee00dd4b97beb6045c3239c48027aa536f568fe384526ca7595031d0a9f254a7059f5f9654d6bb94535445cac6b0d0a55e26160f6d8dd8bef00d1bfed6c333946e5a23ca8ffdabde68ffa4ae1792cd8debce255f99a305d4cb77145f929d4fda712b0f595486ab1b2efc45818923fb11c1d96faff901f631dfa41a112e042b57f5ee2df7a8924888a22de6000d749babc1662c29901acf7289c893694bc3b09d4148438f8bb532faac79f335287c54413924682b3ab01c01082187530562ead6ac24b7a2a1e91f1f3ebcdfcfb233b22a2f250d3aa97240ca78e21be8e8709807b2c7ff115e4e1f5cd5a899f3466dbad9bd1ed59d305f5cd4d84e4904cc9f28d9930e799d745c3e6089804182e0c18d6a3db171812f8ab1ccb08db164f43893477f6c3b056dbb043b9b3e4e6164688436d6a9384d6aa09ec8005db3e5e490c2b8a8445d8b85b9afa01cf9985c17316341b8f37d2a35aa5239a4fb41a4b1564f7b0ab44f01915e1db94ae448f20f295fc3c3aa5fec745f434d1b9990701fa54f2a18395b15602952b18a10a1aba1e02c53dd9ec4e736e9c3289452f0c179c15ab49ad63c87bc1d74a1ac5405bfa70e21bca11904991bb37cc3e5d4c6efa43f6e697cb761a85e3c0ee987d39e2250a5c09428ee71957575a468dff29301ce72c06c5893eeed5d3128e8dad4f880fb0ec59ff3df2b0a8321b8a3015cb55b52c38ce16a8f49353ef4731c38ed0e747ddd63348e89763b91bc6b4e37616978777a5f57f021868e0c2a75dbefa8eafcffb53fb9732d3439c2234a913cd54ca5d973ac9f07086b45c62ab7ca99133932f638226e31e6aa59f458a45ea8f240e95546b069329c2095d9c9b182094adfc99a1f800cf3894c9a1e034bd00a635c5847d633b6e4d99b7ebeef00b18ea44a90809676feede9dd62ad8585cdf4f8ca5e9c5c236d88c9d19a9c5bef612bb815b4c10b782b40cfc59768138b3336ca4e5a9de60d20280212e17f674d524a51a5018dbc2991599b6547661314c1f38b86b6eef5f1de03a86d95bc919e6becfe9d2c0d646eaaaf173938b7698f4cffc9cf33c189f6174feb11073b4314ed0cf5154c5813c353c06f4f18fb36173f7fb543510168bdc96a47f0c088b9de3d43e63f13e4be4d8e351bb3e27da62c37df0c5d461da8d30b1350d7615f591205d3a0308427498da258658364408e1e59849058a1708f7683a07b8f6daec05142ed4c5ed5b9f59cf6fdd74138702a8d799ce3331b996770873afcc15de2a546bac34f866483b418207ba6e5f1ccf126cbc0456def3c1cbd2b5ebbeecb61d37c8ab2cd413fe3e42cebf8b0bd903426a682977a7d81f117cfbe82a75381af76a58253dadb8e1f2d3e2fc20f6b2b3bd106950ef08f8cfb140900cc29d00265797ac8dd7727e354c8caedbd2f305139127b3d27694c53243a25ddcd67c2ca83f9753acb061c1a0ac52295c28732dd1c4437b6b4fe3480b6b8e3b15e2bca16a7a51492105256f1504718a1954492f6e340177a71989bf5b77f24e608674b550287aa8200a96469a8fae17147d802e6efccaeae8195d2cb5b88ed045359df4820326e5238e376d42f69600b9a7ab03fa9da7f8e32eac544c51aabf8524a108900b8ed928d36742c3ea7824bc2f8f25ed52da46852b728d36c017462b337f4a21ee33d7ba0e43fdef3aed3bd07ccc81f36c62dc3495c22134eabdcd3ffc75ad8ebd59746497eb32ebbb964f50112ee4cf76dca1f467585d372dcb37132770291dfece7be819cb092ea229e"""), TestUtils.hexDecode(""" -3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), +3F1B179FA452CFFC1F4776B275BC9DC61A4448989A5C74AA4F6A42748E49DF12AA62C5DA238BAB9F4309D563EAFD739B54E8957C0E91DB05F63B2A50F11205F5AB60B0E857F1AEAFC0562A76626AE579BA3387943E8B735A4B1CCBD23A6CF56D7F38CDCF772ECFDB7CD40781EC2622C10D65BCE780852D7930281726CC2B83C8D8179D842CF3DE761B071A6B04A383624398FEBE34CD841CBDF9C256A5EAE3973F0C256F89665A0B23F0B505A2EA73F37EBC11AFC2C3D4FD8626EB86FF0267D00DBC567796011E5548C08208CB0B43A880C1590CBBF0549683BC71A8BBA2CCA5F98011E592F3B5D7C8CCA0165A58BAF8CEA629CBA860511EA2E86B4CD9E721E8D7DC608504114EA98D016C0C0EF67EEF084B8FDD8BA4825A0615F7E09C42D935D9AF0DD847C2435D84B4702ABA573499C9088EB21CFB97E5B5A847476FD25EFE2C2763429048F797FDACD8238937024E5D66B3FB40055C3DF19E213E5941095CD8FA62BCA591007D03CFB879388983D6E7A189782F36F88EE409D490C5FA66B62510AD0D0EE9EFE6DFE23139944046C62EE639C0F82E6D850770A69577DF6034084DB97E4FB2BD206281A79CBBFFFF8A9E4B70252F6F03DE8FFDBFCB0A5267877FED3893CBE5119F0C6930FC0DFD82C63CB1E7DE66DF2141E184646151CA8A927DB49A3EC63B3B862AD60551B0E562F35E109594E4E43B192BFECF066B3C7612BAE0E170F0E1D7D246CCC3A2F94D3FB08BCF9DC7DC44735E258B1F9D0D8152EE79FF9EF095EEC3FCD872D9584361A44B9BDC88BE2AEF1158D1765EB4DEAF441F2407039E98DB8D148DC8B7EE9C44D5833FFE4C52A077F57D9E36CB220251C58F61759D18E4E449E72F29351F6CB08F9D996005A33EA695C21FE883E1C3BC3DC3E8239F2BE16FE445A18AF83639156521188EDF3F15ADB300A17F88C829EB72275F6F35D2D1A72B79A01A50F1A63741A8B1ACCC35E49D331DF670D30DE8855FF27C9F6D7BBD16CDE4C4C4DD48CAA971758D714E89DDEEC7CCEBF2E89F8CF03D7E631B9A18ACCF19FF35AA24AB6A1E10DF105FFE2603C30E16B7194AD615038FE96F4767DB8882D48C97514CEC057EE636C9FEA31BDAADC5CAF6239A805BB05081962A2A5054D9DDB47AD9D3C98D053A5199A687668425139998BCB466364F656B1AD9F13FCF7FDC50652841EE475D86AB89D0CFC01C6B5B876AF9D0312A43DCBBC71B2714B0C3226967A3D1E0AD7E9368EDDEA9120B2C8641EEA203F2E943F43708EE6CDBC6748A33E3DBEDA2AC492A6DEBB9751E7AE4AA33F6ED893AF7054454467E29D7EB7F2163FD24F7B5607C2E77DDFAF72E983AB532C6585AE8D78757DA904D1FDBC10768E3E70D582F17708B51D561C24EE0D5A26559EADF5463097155540F26EBCE03D89F49D7033AA00E1DA5ACBDF148DDABEAB739EDDF99A6B2BBEB48F83E3516380FC7AA9FFACA8DDB53388485061EF5B94E92443C24DDCA823E44A29116F346A22BB3DCE7022C3E2EF35ECAA91CE5F65D7C5EEC85D741ECEBAEACCB39F881391EE2A06BFD7B72173B171B7D11C8792F0A7D9A125011294296B157591A675649716F92234BF074F78EAEFDAE1AD79E4208C6338F42F2A9B105EC5C717301C638C63555AF0A81F63D0CDD04F9C22E2FF223CA5AE1A01C7FC61E9DA4412E80D493A7C0DD49CAC10C62A7D3ABC1B9C74EAA2D8AF248946EF8A37F1F7017E49D11B89EBEC111D85D7C1512EF4F99BFFEE68FB588DF3F39735169D1B5A647D71F52F76C6BC09F5703320DC92BBBE6D7CA592566483636957D235F5D18150B6A4641CED6276319244CD8EBBF74BC5DD3AF82E6C1118D19ED291ECF84E4EC2FEFF28286898E9659B01A37F4612460B34DA8444A4805FDEDCCCA5D6D8013335B4139101F28090517FACAEBBEFE59E44A969FE3B8402D690012AB908EA590249BD9354D456EF65331608478B2050F985C5903FDA5AF0D918E7F7E167C3A669B727DF0CE96B63D4D944493C5D2BCE97F2827CAF54103A18CA8CC0483BC8B98C42657349B8438C0274E4401463CB55E93023BA114FF8CF3A718740756DD8C92958BD07A304FECBACA3CCA8135AAB901AF23E1104E202395A08784873E03FCF2D07AAB003E6581741389C238942D7A2B9FB30B53CF5D0C408C0EDFB1C4FF448D745FAFB0D659B4BB76B16D5B61B0A38039488682907151802A815AF220F82680E523E838ADB47425369CC421DD36C2E60100A9EA7F29B05D985D644A7FEA573BD24B922396A481E33306AC41CEE9DD8ECCD9DD7833F8CC77477EDC2E97A72CE2DD930BBBC58FBFDE78DDE34CA1F8DC758CFCF2ABCD35CEDE0657B35583F9C016524D3AAA5E698BBF85AAAD01D7D3CFFAD4602858BD7E2F173D6A24504E448926DEBA1F70F3B0D5B454B02AFC4D0C482BA8019A0C209ED071BD2D5B341EE06FAFA7FB0D1FFE77FC6F6C49F78EEFEC44999E4330BDF33021EBD91DE8EF2042FE4C3F19E992A5E66FD9BF8E3D428AAA8FA51C7C761C2CAEC8908DB3066D50BBFDA98B82387E92611514605D6CBCC0AF9FE08B39AA1DEC89CE77987BF3BBFBCF362B4AFDF12A8A1ADEC69962A6FB26610C816F023D87E648A77DACC3997127AF770658921DCD300EE2C8C0916593067B3B31ED1B6B73D68EBE68CB22386DE39E57FFF6AD766193F99CDA751316A5B0729FE5307C107FAF6DB4CEF4B1C6CDE957DCD6361606A6606BAEFD9A1AE08A5DB21991F022C4BF758D16FD53D6CD41F637F5569D7357CA048F07F53C850CC56A07A4C2F3BD04DEAE79498EE10B366861EA82A7E04B9202750D4FF4017239BF1BF7088A3F2E2C79DED5A12F75CDD754840868754428BD7392E4F01F36E3B450A9BE5BB95FBA71C960C7D09DBF24E6662C86D8B5C3E37D76B16845B0F88C40AE7360545B3304DA5CBD2B58C29F6EDBD794E9AC779227B0FD198EBE3A172FF4B8896F0C9BFB7A4FD9FE6ADC73E097046FA25CDFEC45CA1E7FFC4FD582DDD8C79A9F3959A4DD7E3473D6F242B0A6AD4DEF109C12DEC994F2E313EA1930ED25CB401B82212E86150BB53BA88138AE3269157FC2A7A919E21CC068E0B9E934701B572AF0E20FC2CDB2B7452CC1E5545AC4CDD34EA0097CF531FD92E3FC38CC50E1FC8ED59272FF3D631FCC239E4AE0AFA46419863A166DAA2CBC63E24C26ED7EDAE476A194F8BFDD540D640DB3A8B294E0DF0AEAB7A735589E23CE524F534AC82D80CC51DFC08EAE4FD02E6F6E0BCDFA0FB23697EE1AFFA735566223A70EAD827DD31881A3C2471677F905B64E6AAE00467561FDD6C79B45016F1326D705A854877DD91D0B147071B00C5F8A600116487D39284F6334FF56F124951333F723D68465B765B32B396FC4C432D51E8C6A9782461EFADC2CB93EE38D4945833435E2E27E17CA98998F9B33057B1C73E2E43B6A184868DA05559B3050FF42C76D7440E1A5B803C8D4B0CBAFF9FF31C7E98FE2D011B3F87416889A81DF9F48643E943336430602C5B44C1D11BC7F62A0D67BCF9964815CA0AB83E7A87DB714F2C1872E5B9F0843B82846516E54A3F7FE311839F4910AEC6CF0D23F86BF2B0B05BB71B5B47E93B80F7060A350EE4D73EA09A6D489BDD064763CACEF5818B319CC973FBBC78E01A505A2F6C4F6812819E02A573AD8F7A345763943B623995B0634562479072D9E42437FCB2D02479DBAF2D088B31EE870F11047E965D04524D0CFF90B943B1BE969DE752249E8B48C609F14FC48692BFF40EA6095F1967DB766C8B4E18FA73DCFEF18F2DE1D295B51A63880E288ACED85B188B3D10A0B025BBD934BA43A5AC5E1829DA836EFDC88F4BC6BA0F4F23A4AB16DEF3B5488BF6C974EE1BBA51D17BD472C731DD35D5B74EDDD3C9177A3503D783968BCF8A1F2549F70069164C965304DE2434530B3841A2AE7DD47DC5FDD9DE046840B4D65A08A71A3D15778865CCA2418F154403183FD44B622982C64F771C87E18C09489493E378476B3B1C8D14C8009ABD3D1A51CF806189496A4D70FE857822049D3DCD4CFECC2F95D2A8A16D94DC6703B4C4EF3E8C7EB9D6859350131E1A03EC8A21E13F045F822C48EE3E3A481EECCA508F189954AC267E6CD19C80F8688410E2E97C71A6C792DD6E33EAB2FD16B82214588B923AF6C6069387F6A72CE06033913B50F0310112DC2143802AA2CA066388C96158AC154C33E9BD72C993B410FE5E9D7CF37A30EB85A127A7773ABFB416419A5B4DDECEC10E2EDB312C86C3F3C8BACADA66D057FDD40740176D137B1F1ADA098D978CDBB938F45D4B7814F2C5B894CAE249CA8E1FDF31E81997F7C55B7A43461F5C7C9893AD0494F4F0272FBC20D80F327EE55250F9560A301078BDCDE94D72A7D113ADC7C739D7AC2B8775D961F89245C5AEA8ECEB1732FA345FCD84A0C07C65F091B4B32DC4E117D24D782C404E8FDDFD6E9E65B3633985D6DB8CA841B9F9A3B3C617F1D69FB454045C5024AD09C5C1080F3EAA64202C08838B42E218F56422722536160F97ED3C08F285EF7BCD1119BDA59DB5EC6BC8E9DC1789B3CBCD469A4BCBE1CE237366A5B51B062D0A08201D4F0EAF6F8FBFFE53F35999763DA2470F2F9FE79BDA60285D052D65DABFBC43659DC76602DC662A3357BC3E4BD07BC32AE5B5E94D7DBDE4B5117BD5A9E3461021A569E200CD3CC518ED6559BF2539D8DAD74920DFEDE8DF8FD8333FA17F0798A17B5385A9569A640685D7365D3DBCE8411D44B17BF79B852B1348AB31335AE013B2877C1D8AF62F88C5186B7313F2C8736472FC5F2B4B38F761009F7623292EF14A4A4006305CC419A3ECC73082F63BB2CECE6A624C2A6DF29DBC6A4F0FD3658C58EE694FA58741DED54889994DC6A3DB4FAF5998B577EFA399E58D822B99623D76050736C17B5218671FDA3BCDF7E81B3E85D87200DB9150253ACB07AFA8FEAF74578125E1E26128116A7446C804DE54FD2D2B1A48E684F73AE91932A37372DB66A230AC4CD54869A0115895D2CC494E6D6E8B12845551B4F3DE0B3A4C114979F0471311434BB3784FAF7F9A9B88D536235543ECED732289B383E8005D98192FBBF41EA8026CA3A14B6895A6EF0548EBEE58C25530F56E0EFF157DF6ED0ED0D5565E9FD474B38EF5BA74D24B82219F317AD51F3E7D6F8E4BD8836B91525E162DB417C87E36B3C0FD874FB4BF4136926AA6D045033C94FD1EDCD69835A116357F341372148C4601CFD84BC36A8E5B2260B90CA797CD5A41362C44B4488399394AAA431A63A74B774E68025D7DCB1963911F2BDEEA60DFB24E87196FF38479D235C98E83F1FC419C87F708677F98C84F9C4848B255DEF2D92E3506A533D36E56DF81F6461AB5BBE9D171ADDD39FDE7552C5D4351DB59543C0FA939ADD6130E25D4326566FDF49CDFAA240BBA0B027257D2ECB83209329944E8F44AB785560DED2BA8EFBC55CA31E48F4C94749E4D205A50BEF3E3F039DEB3EECB213FE92C1C3E98A9F72B6CC316D6C0B87BE7F688000A2433E3A184A68722D44C7F6C90F2AD0B248AFC9E57448E3450888A875CB3006E27C232963740B985484E7FEB07775F4B4FD89AF6F627CC56CA1AF23E3BDF61443786D3F04DECD3CF71E2C6139B584F52B6B656CE0737F50BB270830B102B781E621B3356CA16019696A23EEB238ED74D160269A3EDD35F7ADD9E065F836A61A0CDF99272956555106A349166B2C299B8D0066581DC3608048DD8BC2F267BDB2808E1ADCD37A7538B9435E9E5D7ED4389BD2CCB6E926A927BC6DA19E8E0E946442A6943F65C56E5AB7507FC6EA1DEDEA7C1AD087CC005914CE80A241D42C88380A49BC4B6850536C5A99B6423B77A75FAF76CB17479EADFEF1FC90B832C8F36D92BA3E927C9D60473117267AFE4B115E39D50AC7991BF248DB38E8C99784848013B48D4CD6E034B93E643239E78936DAC6283DB748062220071473B0579FAC64510D033525D786778C53CEBC3BF95C4FE9406943E9D68E17EAB3245C57C00D0C206E3343D8201A2F6C278DD61D0CD42B71CB7064ACCDD38551DC554007F29E1929EBC81025CD1A5AA41510BC5CDFF340F42C4FF6DA37F8E97F5911F37ABF457DE3EAB6114DC858C0C14B9BA5B652DF63D0CFFF4D6F8103E0FD15D87D8EDCA53FBBC70E3B42C410F379BF77DD17F6FF57D7A0D01FFE0044F226F8D65DBCD1803928B29CB6AAB703A0EFFE4EB47329D9D373954F0F15CEF2577EB8F34665FFF2C774EB07F0CA72ED27AFE6EDF158C3AA193F3B5CAF99F52430A3662997DEB386DCF0A6781E42180ECF44E9043AFE95BDA84FD1F9EBDCE26EEC0A4A08D8423111B320EB87156BFAEB3827389108E12E7AAB3F6CC8EF67A7C877BCE3192E503608D6F1E5697941FC1418C16093A55A2ACF2378590F4B0702998A65C8127F13AC98BADEEB32B152F3054EB7D0F200322E40CE632CDAE8F0E6C22497BB6D464ACBE9B461C5D39AF9334F5342FF31C9273146D20F5D4BFC61F980B1862BE4A147474DE89A1A3278004F2CAE293CE2709748507C5DB48D98B484CE933DD3E925E1788F2470C91177ADA3869DF6FF81308DBE846F50C51AD66CBEB2AC91DF1C86EC22ADAA6C702F1CB7A141778BF957663060725A5AD6478E22FC959FE5C918EF1A11964E66B1910018DF4698543CD3015E9876AACE37988370135BFD7047FBFD3996B45EFAB6FFA70A4191F259B8A27EFA05E7E1C75285CF70910465589B41A9D29F51F7BBCE06457A3DFC540608157479B499B2F0CD9D8A8D6F2C01FC79E5079597FB6E2D1C3394B8D8AF65DD133F9D9300DF3DA3D740CD0E7E13EF62BE1D29A3DA6745A5A87558F23D89319BAB09A15F8FC01AA388E1FDDCA117A27426D142094A11E6B49E2C541A82C685D41D6E2520881534012774B4C01CE3D2FD8FDAB8C25E4F0AD1292974C4C141173CA219C07314314FDF94A05955E210DE13F0165C990227EEDDE23A52D7F4C8A181C996D0FAF6C313EB74BBEA4C2CEC0B7B01698C63C2E1D37313B637271DC49A7EED8542EE8BDF7C7D791F7BD59A029419616F9C8F478F060B855CDA73418D0AF090844FC0066DEA9DF8D4F3C9ED58CFED2A78B427B42B033C46485B767D75526DE8682D6AF0BE91169650BA4ACC4D54E0D357E993FAF358BEEE3F7F988381EDB31FBF174239A345130BAE1B0DEAF27BC5E1DFF86B29712CFFAB670D35D19DC5B25DA43D481336C0CCC2120427F30326FC74503548344B585C082A78F96F072510D50E1110EEF01617282CB681CD352A23607C3CF7AD9AC06FB52B38294DE8F87894D25C1D278678B048E3E3F4BA0D884154C5E16780BAE2322C389667A15EFB0B21718F56767EE942E4BCB190CDECA74C92DA8848F41AEA2328D29B10C95C6DFA74B0E162591B1BDC0ED6826ADD0B04C7495FC30E586FBC03D4E871915AF71866278F9CD1B4F1AC56E8E1B7B11DBF0C9A64F608E1C3958910829654057103BEC687A02AE9A568BE514187A3E27F3F9928EEE29519BDA0065179423A7242EDDD8CC337F0B7E7FB7CF90FC682C9E60253BD0997F34F9081FD785712E52262CD17C3508AE4D2FDA3BFE232269ABB185E635E659D405AB12E17A80AEE5BA7DDAF1FAA819A284A60B85B49F1A57DA72A0866B2B9C2D28178995E79D4458B58EDB187B0CDC5C37F111D20371FB8F410A7EBED95474859645FED6F451A396781EF7A02E6B52593189EADFB1226316FE8DF79B23CC67BD2EF973CD561DD612D0C3047698EA0D3895A28B4111938F0A0354E4DA7484697C85908A3BA3E80BCCCAFC73303C767BD3587C1F9D48FD4DB93517A561DAA10F53F330ED14CD65B4A54FC43E5F5CB421B8B6CF7B83D86CBD72A55791588D4B81094BDFE45E3F32A2C3FFE809F66FF310D66032AD6BAA5B33E79F1C476029A49D49CAAE427D8A81EB642B15EF0C544C9EECB7CAFD2A854BA79E4D7EE01A96CDE9EEF45E430EEFD8A16D5D22B751F981667F36DE2E139391980DAD22462BFF4896D277D89DCACBD5CAE5EE90BC2D5954C083AADF632D9051B782190ED4AABE8FFE195000A6BA05115EAA0BCE755B23B10C81DCF4BBED61E6D31E9292DC1A7FD6B453EBEFDE55D6AD8866CCD50473705A24F519548172D3D9F92E668D679D782B7F1041E5A558A625D65E679FC75B15499BFA304435FEE6F6498138848BAD0BFFF6942029BD0C5465395F5368692D6B21B2E22A638D6EBFAF3A0EF1F9BDEF8529C6D0BD328CC82BC66DCDB2F5AE20F53B8AF66400D6C2C0A3C6BCE1E8D2B222FC54F1896E58F61816E301365E12866C1BE7C4BBE0DBDA2B504F0628A4DF1EC7942BC58C0A4CED0046D73FEAF2231FB9FF61C0F7AA564EC1E10BD65B693CFF56DDF3596DDC85CDECDF7F123F9DCB27269A7F65A435ECCAFD89A211C829BC7F5916DDA61959AA296505F6D46543D863F2D3F007D8960634841CB317F5EAC3D3A3E4561801CDFB269257FBAA6A60E7A0A1980C9BFD6053BF2EEF7414704C7160A051355CF48A0C0F6FFD683C453513F8212364775B7424D9315A920DCD5B140A8440EF7E5908D4061F580022399509C0ED416F945705A19FDF8E65C8802B67701FA1D15F06013990C7BB8D0D0404679713222924DB33BC659FE58F82A99BB1AC551426A13C2CF316664AC8037B41755F110F6441C7BC9446430D7BF917AFDB8FBEF84E895388A68763E0E16F89FF630BDE9732852B70A4A3AD8A29D2A4670757AA4202DE5D53E653848FB26C6031D07CD010501F0785D1B1D69BED49DC3B07265D51A15A7C432C3EA63A0B0D228B4F8AD4060DBB8D54B94BAC7F2179829C8D9F9CE4F7BFCCB472EDCBED73B0D18E3108156FE659CAA40B45016E0EFF20F81C29EADC8B638364FACA6FC85F98A9BAA9BB7E5261AEC6786C18487B14B77ED2B62B762D6B8B39AF5A870EACD236CC53C016158DD1E71382475657C512EDEC0977320F1BEC79D0CF39403975210DCEC3ED5B58F"""), TestUtils.hexDecode(""" -4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") +e870f21e348b630a1326a0334c872302d0a6da460dc9a0bedb6daebc027b22b9b332c967a2f5991252bccc646e484b83d4fbbaf2887629032de5b3e1b86002cb089bbc58e35737f8c07a694b5cfd38ee3976fd25244e6acb2ccaed20d926af4c9c7526475cb89a72a26ee9b2a25c29128d53446f797344d3eff20d91eba8ba9d02f939d38a775911604124896569964fe5f835df7cbf044f2565a32e017caa93a8848f7c4fff257b885374a6af0df150b79488551200332d176955f304d86340a6df8f98cf93dc12909e1693ce62de02192e63b8af668a0fbb2c345bcfb9b5151131b7b4c7d7eeea48666a8219d5f8b0cc430443ea3d531dbaa6360e51a842fbe1e40ec5fc9ecf9bf172570bf8b31399ba8f12f3b83c40205953414caf7324182657e0fbcc2fffff801c52259294f0b23eeb5ef14c34d955b92ae782739a9f9dae5eb03af4bf4e911c7e758cba1a0f1d0ac1c7256e5d5fae242312f18f6747c5b56d907a49151080485999605246550a6ce8e6341bbd1ec122b179b3102a2673c163ed7174089c10b29cf33b9b5fd1ba22dc73a164404804faed60958c6faa6a09b03dd2eed0fa8782212f1da486543ffc688e37bd43621ab857aba0b13c1e0969a482ce92e00d62ebec1870188734135b0419cb3b9f3a9fcdd68b5b4a53169ae0bc4959462b8eed39264c0b0b34e0595c7a719672abedad01638f3ebfe9e4a460cec890339595a9699db82819723ba08c7bc82080f8989d3d8709386ed1c9fc791ae0cf954e3a897a93d8e235eeb69ae131a912736fecdbe1ba34eb03206110fdb1f81e71dceea673fbb98886ee0d94cb4d76e1e94278b8f2501fea2718466802d3d4a068a2ec53029018df3eb088246b767043f843f79b5ae5537924a9b5e5bd46b19bd7dcf7f14d4c9f4dd05b2c941377434cb37d80a899ee97a5d68345cdec8a43cfef1f286c0102c2d8c9b0d07adef966992dc7ce8b9606917e238625707393552ba9c01c4e72f6e3b533a734c0d60e3a2aba08a823a12a45263b61402d8e62da3e5f5a5c12e0cdee0d255551b8af7d500b547699f72b31a91519891850e4109f4ef380757013fd57a0fa0ec0721dbe825d4cce624cdd8b7f7cf64fb31332f374f6c470b9b8a5171f25d005da4e184665430e7ae553caf2ef9eba994f34b04ed6886c1b768f03868522959fdb164e8ee825f08c4a4dce01de6686695b5dfe6102c7463ab54b084c7fb1366a0b292898c0d7499a3a6ae1995bd2139f7d7c84a0f96b497bb2306028389b983f2e02a2fcfd3c5f8a0b4d2e334d4f3a460829efca41806ba82f2e5ef585531a3f1ff67617ec112f613acafb8420a1cf6230468601cd8b0807d975065fd36aefe77111a5a72ee622da403a51194f8467a122e408a0c3998a3a7f18c2f7774915289a1522f5670527e63e6bde7ee0a84750099d949ff87c6dde67de9cb220518ccda5135d3bf58a42b7d96d14dba0ab87e79547888f6e87b4bb9ed754133d16444eca15045ba54026767e93114e8a3a75a1ff65d0f03c667a8222248119fc8994a84fdf73817bc2d61d6b764d86c69d68b7ca3ae85031181204c39085af1c7efd687fb91d00255dcc934d47228c714cbdc66d4b418112ff0ddc030dab0f4edbcb0309419120ac944e15ddedea5cd3a1d62abdfd8729edcf40d43231e378b2c69670c59c30b4218e7b7f2dcc0ded133b585ad673bed77194b98965fd4a04d93db53ce26128e481de6053a14f40b34f60a169e26e99b4b29979c03e4880fe84474f11627620d196369592c0cdd88c3639c1346d3ee265e550d470b8440c5676387769382ad4b57fac799926cba49f042833301834033d668a4f0e95e2bfdbf295ee9732e30a75b1a76d7a4f0c12029514252d98bcc4330fc2a3172bfe72c8f8202a308de53c4587a17c5e149c92ffb88b79d8b07962cdf91f0310d457c7eff09485a01481313b2aebd081c49b47558c252202b4639dce456a4e786db6a91a24a032d47d1cf9d37969d07e2acfce0067a20994310948821510051ea1ff97f0a5e88f0d36825f7a9b71d5c64d42dead04fed5f6b63dd80bc0325bef6d413644c1b5ac212bf9da2edafef2e6b6d99354470e25c5050703e524dfe08af14dd431e609be5809012ff5d0d4dc260f10fff302168b9d73c86ebc71c21d76ed34f08b12a6dc7ea174ba1c2790ad34a7b5d2e55607ab26eea6289fef0886187f43d5b98b7687b227b58692d61e6a8b9bd04a9c3a5df88e03b20c66d618a6d5a979cc0e33ca400f55918a0d2669c19817e9bc0126a406fe4816a24d06e072717435576868303e961abdef730d973768373b4f413b006c137d63fd1a7937c0ddce317078b610a5fcc1a49d83778260c088cff2cd6e35f58263d43edcb81692121d737960b77b17275765218d0b686907ddbcf0f681bd2662451dfe012db5598c061fc03920011a245c3d8fd3a8b0ee6291959a01e811957dfca6351df838ad3cffc5f28926042c1919a446cdd525d0a1b56591ee9574c16f88557d54b97cd4e077289ee304537176c4cf21e63e33203c076b00642665431183c8b6ea4c58b2d11011d1a1fcb3325a1f7cb148e0a0c70484ebfc6a460de38392761da4f101a2274b21dfd8a5b6870cefe3f1ac9fab09c49acd26de288d43326cfa68248fde5a5d0c2adf5ee4f7a87a570374aa40c904bd3052836b275feca785d29a5cf3af7df0ea226d5fa5aa33df234354a84ecfbc2e2a3d2b3cd2630b765dc0d6a7ea00884d7e805cd5b4d7219b7f5452e27b761d2734bc68d6da9b45de8b69007e6a961a73aa42eeeea30700474cbcbafb4304fac39b6dbbdd2f2a9eb5b959ef1a6efd9a41661265c70db1828f66147fdd9a7865dc9f0a605081ef41202c731184d754e499c95c19af4aaa7a018c8f1bcb1bb3ec4357bb7ccdd227f37179eadd63b10c2c10fff271a3765e9470e06fbfd3e5195ef39a52b20041507f3cc360c37608e976bc29797183feb75e61d4653e90c4a82c744b952efa874c92a675191ba7cac12479bbbe83b5a4b2e919b8e318869a9da789be9a8ae806081bee3c6376f54e5f687a2900a9e610094b6d21e4037066f9c85d65fbcfefaea7f2936aa95adf632bb83b1d5630ae48a2b8c3ffa79e44296a60125d14a5ad30e70f97e072da5b00e115313c0f3e572da51faa8741e98bc2741c8c44ab6d4d60fe0a145eec8bb91c742a0a8eb133a688d322a836a2cc4663ebf2eecfb80fdf1f95e83115d10364baa9357e1e133338b01d6ac2fc08910f7ca44ef8cfce5f5d675346417a40010b2c384a58626378819293aeb6c8cdd0141c3c404a738badafb8bec8d5e3f026405b5e6b7e99acd1d5d8e7e9fc01092d3031536062646a6d747879829295a7b8c0dce2eef5fb00000000000000000011202e47""") ) }; static KeyGenTestCase[] KeyGenTestCases65 = new KeyGenTestCase[] { new KeyGenTestCase( TestUtils.hexDecode(""" -70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C""") +796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -4B4B71C5A1BC1074F2167A1D68729CDB9E16ABA3651FF02A0A0F4C883CAAC827""") +60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -FB27DBBB4ED8F4F7D2700283C2B092866694246932EEACEE72DB730EFD172576""") +c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -334ADAD056F76D74941FD87E5263E449D97C06D748A82018D0C794154C20A870""") +ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -06C016CB8566F5B81F8457F56175AE77DD05C35EB37B687EAE89147DD7ED008D""") +78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -AF5A2ECF442AF8C0371F89C499ABC337021992F221C1D3A66B551DEC917F1B1A""") +917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -D85D7C2928288CD0B90D7269619F8D8B4EB3541F7E084CDE0E39CEFFECE9AF80""") +df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -62E511A6731C2FA10DFB5F68A538CCDC1BC578C16E7EFFF458A82627438E78F2""") +d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -BC4EF6C46CB18061966CD872D2CB9826B0220173E42F11B451DFF93C0577CDF5""") +865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -135DF872744277E90019BD1E904DCBED63741D863E82388B61A2B069E509B25A""") +741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541""") ) }; static SigGenTestCase[] SigGenTestCases65 = new SigGenTestCase[] { new SigGenTestCase( TestUtils.hexDecode(""" -3E935D3B7DB7EE991CE774FA5B93D9BE0D108BE397EE176568296EE7F28786007CAF1156280D770245611B2D346A65FFC735A3A2E15BB20C05143D9256691B2AB41D75A90BC5E8F3B30B6F5CD05FD18992924A5B59A65AF06C0F000E74A219DD3E7604B58331DB0A0AE901C29391794417DD110BC8AAF7F62CFEFB34E00E1D1273224608140352203374007875256171864715361476150443076135107682417565754553623586606381220842166273341313626571127738336004603326033470801750142613464376064342020345044224040084303114570820783867267616511300688505780160364878830103711055618008111745151375375768600743812137557362365733331614323120366135554251746566185186844142405008812716203287601083143716200564576635047520177022180063752520164642714415327778151052008642808573380026883457436064234122618236025563058541674201723048788640112813150654403774841424453305303221148753008688031332254082078242584840286177301607176788017121684433040173755555750683651813041566084354588662418642250064747473031812374021673282486827605038055324710254455817626100000230664826103172488176531134306846024723448311740230680042148850536837730552571345643370461544610780183773451078171180104582147807556873670047488518654385284874451381580620113757112803083074314684320237100037477766105712118241161456212245656034186154017004464176334326740402832764308766445851504060640576124400281353647323214821033857545523610774625068106122683180221678260362521201302863406712350682475271635857220571525343258836275054827741877621326432020580784710353875772868341878363051856158443044548840053168838728704486521268772477031031715632770125821827468281545148686412467356360106478786427517182848466386616460707311675654327102528646248552175050554380133130605483627138568443074022187057484232375461550120577463002814013083534021237475850308467047435262471236266305063408115274535542164420053544842843632328232763503405306865145032688402018882073027571768370605424427643718688264801531460682254320658441480417081480173221048303526715882527870543270488733275488344414828021760801815571212201813874340356543310486026422086826301213865460574551547165833464571331342333324361541770188154256776002570452822671053622286151572588871378618203862708670032872331727751130056133838855585607876011010676275632625203121158641326875854128131672382381020353185780015705112326025800226563074580444604700207600183643031776082661220866111632103107372146823046820244455412421580875043257154231387817356100882747432501152565307267161430120118507744308574866233700326827552338466067211465546257660701674221148284153310844242634735382144183225241003471575543715561843716168715856042071108301012801652345045255016735805665612203238088225555235253071116306808173433031610572882372184860154863135212681745772538311183131358541040558574735410488454426065881446470864680188026246287815664520033268207530852644720764714770741540141065754171222385408035558637684376620487744584745736533387425473434280735546766515087150306388383873763030720286231050777658256536078013373573731543008080540837532054265732725301403185681580340556182751534152216780045272761136256556858461150186753280004488820172321265430428278876741152805304254EF2D2B2351896FA881A5F6022A2BD420A3D39B3B3C4A138A6F299A621979031111515B402D9040361D5C6E2DB187204FADC47A8AF07382C437E85536EABD12B61F0E50679A42EB886FDD3ABF04BB7C16FE949AEB66B30B685A0CBECBA90EC1340CBB5FE2382A534BA58AFE4A8A293079D51D7EC7C9EC515697726C23AAB9815DAC184696FF52AE3C02FF716081FD07AB10B653C3D4B47C32BFB5392D0CD22D5B99264C5B58F65A5E52C8D799C17A0473A962A6842CFD255CEBC0F20E9ACD7EFBC8A7226EA998F014C3E71535A6D8ABBEA5E8487EF2A4516A4B8354B19C03B971230BFADAE6C80DD3D234564553E2493153FD09AAFB5F06DB57B388E000D149C8AE52CB42886141316AA57FBDCEB78F815E31630C8A557FC5F54CCE95E1CB5F25AE1B62D2A1F390444FCD77EB745785F5B36CBE1433E55521165BAC3B2B0046224EBAFB4C9E74E6343AD94AA37AE932BFC770803786687392B26CA7C47124E88B8B99713453FB22C210EB6EFABBF4F07D47C01543564F6D3C6233B913EC4553E8075C97A6DEE1CF8CFEA5C167DDA8258CA69FEEDD8D46C52F3A51055E890B2351CC3A1898CF6FDF51F85F01453E64B1E6CC83E28A6C22C8BED80FB7B4D27D475BA41B9DF56EFDF8FC4EDDCB453F65D836F3BC96E43F0AC0B5645B4F8D306D7272D54F86C90FBBE4CA897DF1F56748AE6D0B0DB3277A7385EE7561B570D270C9ACE06D2A0044BE7C8BD01F3CE08EC36561911F0155922432E9045486A602AA4F06A02C300F8A71504A134EAFFFC051F1D4D42D881E30FDD5DFAAFBF9E9BF745AE0F70FC26FD404FA797D9EAA76D9065C649785F5FBC134690C7D8BD6392D4EE99C488B9EE15DEF9227868A199EF358BF08EF8DDC5E45365217A4ADE0D36AF7B0D3D744C3EA3BB26B56B9CEB374710F758BC7AA68BB346EC2DB5B5E7FFDD5F0B4CE9F25F03E72A9E2F5DB15E3B4E922CE09A57E2580CBC287903703E165BD7F42D4274AAB820EB71E8420CD47F87624727E79AC507B093D22C9E6E761DF4A3082AECE1095D3A5F101EC019F2B84ACD4BDD1F5379CAC8D7B8808485C6ED1ACD5B1A245595108B4836004D6A6D61294C1C8EBAD65A0E742B98CCC7D1D2760536B6EBD19A88D17C3598E86E5A22C0EA07BE671DE3AEF096AAE6D3B71AADB38839ACFA559818EB43A3418576F3B42DCD0E128AA022234218E616169F0BA3847F0EF62FFF4EF7D4DE803682D40A5C3B7D8F4D5FA1444470F1B66DE187B50FE42698128AA93350C20E7D37F619537C220D78C5EBEF89CA0F11C7C7A93D83F28D83A17216ADC450E25F3EB00D9F365C9F5ED69DD08B68E0BC9780F34D150329E4906D30A04E47B6B6D508DF9A945ED83E39DBFF9B0C136486D01A91D11D37B5ADB8A23D305B70609F126588C8F77B6D0614DB5364CF36EBBE9AC59D4AFA18DF530AC5ED8B58D68D0CB7BF91D65B0F392AD4B408992549F8A8FBECAF25652F0F6C4AB6F32D5B147E8D85286EBF96A5D57B17A9899E854EB4544BFCE30362F7BBA0D2FE40102EDE08EE9F43D0709CFC89B8E33FD5F3815A771C56DB8D7C788C49EEFF53AABC5E341F184F92ADAA225122D2D95E3BF03A27DA0C104C6F44A3E6EAC0CBC2F2066D17AA74A584644EAE6E2B69C32EA116C91D8D6D59C9744FC22D38EE5CFD0910DD305788BCA661463AF04090B57215E702850E85AA1C66075B15B9C9D6E9325A634CB04A6C7271CEFD9DEFDA2D4292EF1535998E5A6E65C4E51DB49E27FE2986AF02F4BEAFBE174BD75E8998651E610958188820845AAEB239D2D152B2C2597D04D7614A4439F6048D2B361FD9C558F40CE0D2D86D7F76846EB81DFB4E833127C87095DC2AAD0D7CA4FFD189C5E24A0F9CDAD4A5598F3273514703ADB5D12E7966E51A856A688CB6E25CF8C724BD9EDDCF555B90C65E28E07022BDB2D7569CC46DF613EA1E7FC1D88B02594A464387DAEBD0462A5F9C8BB46D525F9BF8B3AF7FC0D0B84DF55B2AF9E3E82A1305726B1C6D60396FD086B01BE69F91C752C5D0A587540C919FA8EAE2F5D3D72A14AE9D5E0B4DD4C8EE8084342033C93A86052ADE3A2A68E4C7B5DD599C568C9935BE59AB38ABE3556FE81306358D5F13C1C50C8E5D32F230242CF52E30C43D88C50FA030CA5FDFA88DA869F31B29A95299ECE1E4CE8575B6A633120EA76B43F30E9517728708DE1E73A27699D451C143DBF335684A643F544756B94C546593972C3543EC65EF687CA3F07302E675FE0065C1526D1353D027778E2BD04EEA31D4009701AE7B2241E32E1F9427BF820CF55A465248993114A7145615384CFB4A237C0C37F5C2C1B3AF7A62867F0DA8E4614DE7BFF6F00034AE628E64DB9FD96528A788D98FBE61211D1F22E37B978873EE78A6E871C52653D1EE0E0174699FF71B0788E7561931AA70939FE1D585D733509303507801B87189CA17BA3060A4BE85F9ABE6CCE142F8E16451EB3C51A4333827641A9361BF679E665F0E0E11F657AB9277D5E3A9EBB8DA33BCA8D37259166DC8C68A7A692B570883276450A56D984B774A10AF0BA766971DB3755AB5EDE5BB8CD6292555208B37872EFA2E7E42746576F725CA9E9FF5A6903945CB08E715D4BF468AB847210E30CD8B289D2FB745726D76A5802A4C74DF544E835D61DFEF680846EBC5F715F071FA0CF2BC3AD0B0F016C9A67162B4F926C32EA6DC7C548E859B72AB73C7A29C4F06D609C3284C784E40CD460EC149BDC17E614603F26BEB2E8AE8A0CE21E00EA3D18CE1865BE6EB0B9E9C79C170049492418CE009BAFBACD4B8AE55537D8CD8839EB42FA6921282B32EFD2A76B1A965DE1BE3CB0001069D4D80D6715F8E173BC8BB972F23020E0BA2DDF3A2D390F11F1F5BE9F6134F4276CF63C5DD6A154E133D9E1126FE55C5113F5E3485AD051B4C613E32AD3BC0793B0D955FEE79B1392AE2EDF048753BAF82EB4B739746C075CF84729A90EF60685C3F7833BB0D00895924E5A8BCBCB7BAF41C78C3705C48C28559968C947BC6FBA0E9640F8845A45C5AAA018842FCA46A25D68DCCBDE8BADEBA341F8969A3C83337EF3A6383CFA4CF9B093F7C81CD8947059CC6DB350BE20E8080A32C356BB813A714557AE66E6DF110AFFB7B11D95A82F4714D09C945554DCEE53B3A06F0860BE89E7B19459CD061154B9F86ED770AC271D7272A8D0F40BAC2BE0F95064DF20246FF3AAF3100DAA75F68CAA6C532E1181D670D94A68639A4557D5FA10AB8A016EBB94B3B367058AF40541FEF88F497EDA040B6D927A3C1F034D6C2472F8A90EACAFB61242E96FFA47D1598D6107C1B4B6703E83067A817EFA9640A6A1277E59FDAD28DEB29A70E31EC82BFDDF96DFBF7756FB6D8368F9E340065997B55B00B22057E7014CA555FBE5563EEEDD4B039835F60F753E9810B5410ADF699515080104AEC812C3EC299928C66C498B0E26B1719C690BF5A42415A6F63A9278DFA430380A821BAD0A2F8377235A260A0BC9B33E49FB980EFD770BA97FFE16183D6B1C24D0D1C3F437A1"""), +36fa0dd4a24ec6fcb09f2302dadf25bb8118be5ada70e1eb7f57b93fa96b1b84a7e94374f9fdb9452e2748558e6f5a787b2dde0cd9d68747ac506baaa454bfb065f1e500ebc68dadb6def405dad689f5d7fa5772765e8576d5edc6babeb42a69374bbc305ba09b1ab4f9820ce3a63bfa30f237af73c551924bea0f171231a1c7138517400832116516721081381534111864540573008215505304258180167218805633031837711834125446757374064802656602288551324300464424570070430775604467700373727218654382113085402384714385137710073132881352767634653213083382164661807507572063084014331381071513408847516228741575401075645618078474251072366778856403233687514470818323256487352405414024741457321505602326684655106051751226763771126438165164374510847344324473582005510013087276273103305247274346862062415125625613058163863147647838223024704832800525016847583411847321486547525343755162746617268246640865568078283725452875420148460064305561603552781415016532336383827535812536128531582855048732745734304562153661720882314551774378733337650373165711441772228701657277386017735824150430521336520550036374316583310125155614734342460731628214452004760130486772345084803242082312015236540131133778828125485315367333404602814074230332231645775734006082655405074336518265056780405423405171643707672231357803711010227186374560188573728767460207070474058460834711808584073145111570274757730536084417433361080031773164730537111576081735558366046746463012324065660876052137008052508762676453141806072122540753112240128218525337055738681721237286528627580731113241785778878812404656335421440725752111111156405682027841442788638820213821775468455868881572107124844588501722102737751182078020774402721847287133760733436178462865784183457884478713270388562378112101074746047443670038258180805476134351522560745400142355780715532180431550238645138105666571424718347700224316576316240153341251132303832382487412204627864764456730060500534645228115033152663747635135007237347168666208148716707533808368153357853523066243657213114358240560560762242824400720503468848503214451133047326042414766776505632362566828364757557628727414157415555332465830353045707545360708480663616301475251681455722668010152887031873716282756337882326408515168141310476348177234206113218677788287661680051776170836537302227562814480456821237427740234145435547342505460352122655426431817848535455552351110307364674577347661170167232588300102408838001733245265836505674067103567726335661342615280304861068871308556030576265263455076841315203671823018446077528186184441157454628072317228030475837445608207541643840387761867421333788142240721568555218641850673185763821882055574358025326482476866447683505537318274722216107033672426311407351407766566165264047443754760608262846715247610402653383732324630537084112247353840248444247113603737643465255683685837537448132411273502758336260275317671716402152714475531868478637736432604357116462758307044401162120081820772432707307585501206687567887071026881271434401570353027344416280106317363532310068331157303265448711314613062006813077352761435726341110116125784437040253348451460505741467381411200515685843585007382002820405613751758033727624146204482040301733053d1bf1b1a1af54c10411e25eb7b0de530b1e7173975fc197ef3a8a750143bb963c1e63e8442eed45f9d9d52c1cad3b07f6ef7b0b63c9ae6bfac1b846a6cd055a7fad31424db4074dfd83659df20fc75650d6300abbf78efcf70e634d1a172707520b52dab4cb90361801bb2eeb5d29c0d9f3c7679c2319fb7cb91213061bd97f48c649ea13ce226fcb0673be270f7169583ace40af1f03a14f4d16f64ddbcc68f6301ee523477248625f3293f5422241eb08ee7718bcc25a12b923b9825779f1f4f240789fd47a484e319d18008d465f5fc08cc504af12f4ce024030e148423e46e3aa78ec7ee132724d003304848675b7251d500380a613c31945cb3355761902b15d5c8a0ff5503af2587c2938f793ce14521347a2cc4be9bc8d723e3878f0e5df30801fb98bd95724eefa5c16ae55fae1d93b1a14d14d2fa3ebfd811078bed68b485f30f05b66507b20fab2b00dbc9d776bae1b3edce5d99057898491629d6d5b5229f76cdd1b3fc466d322743e43ca3b002a3d4542648155a71e274b42ccc9ea50a1199d3e72020c86c8a57d8a1e3798fd27bb505bb23818c9289d847097ba3c83c54874f2abfe416b14942623de55d874317dec351d88d97e163d729a08e7edc1be5c66ab0f4505dd3496b34271da51a8f8595591adc55cc13bbbfa9683948e511f4db8bd3a458150aae844c72bce87dffb11dd52279598f9750091a3af472666648f69348d457e60cd4d46d900a75bbe9bca3417a8eea32eb8fe46d92b6181b093ccfbc7598289641df2bc0bac8064bddfc801bd1cfdcc8e2b37edb726e1724a2c98e3a4c71ba8e389e30e68a92b50ffe7119c8c6948864f24b3a64669bbcf515aedbb4b1702147aa0e9302de84e0a9536d9528b74dee3693c21f3744c56936bdbf7cd8ef7541dc3afbf58cc3c7638762a09cd88a3a8684bd3af99640db653fef63994e6636cbe2eca91ae3943aba282b24c070b55f8a7326db2161ae3c9fc784be0ea8db00aef4eec5a468e700de2db247e98566a690e56cc8607c29df308ac4830dfa98eee2918e387df0e57a62043bbd35517f4b4c3d7fd5890b8c0a013f533c53774949c7003549211e34df5c1a97f393321b8fa8d5689c3a973c01ce454ef59a6a65b4a04a2212044c69aab73d0ecd69d81a0a275f8fa07cd50f53944e416654b47061100e89542bf9bae7224e098f934d90790296432d53e59cf766839ebf6607e712c8d4fb07a620072d4974e398194f099ea90d1a8cb78286bc6b3e9cd996f03be3ce22c3fdc96a0e01004f5df6343c84a910d5b11bd8ac6778f8747c85b59ab5db48d31cf256f316f0c9d851816e2d55661926beea6c7b5547153829a1d2c1b5e8b94d824114f7beb05780b68ef086218f3ffba3f7a471e6dd89ad3b78bc57e9d43b467c7a82fb5402013e8d99ab99fe7a63fca0e4304059d2c7906d72a546adf05294ad33d1ffefb733bf10c5bd5728ee38a645f433a7e8993c6d56f168117e428318fbb591c07cc0d1eafb990dc9a004428f4cda912bb1892ba329bd00bf7db39f2e3deb80d0cf4d3a875f0852e50dd1f6d06e440e69aabb4b0857f1b4496a5361b721b28195dc3b5db38339d7fa2c2b702269f87cf95f65194aa4de80241eca399fe71afe2e92dd57ce509f3a152036b42d058a5f1815d5764054155ff2ea857dfe894b987d9b38e59ea112a35f9618b43a7244d6006527c740563733203b6cf80c3b8aa13ef9863bf88469c1432bdf582ee1934e31d9b88aa8a195b0e491115a30b2d87df76c4c0357d37f2164db21ef1f7e4a70275499d215d2a8e345cfab9bddb5b66dc2ca37f0b5e2ea828a140ca7a4a31f5ff145d6a5be068ef2163bd93913cf837a6729f1b3009bfb3ab1fd45212ad12e2564042d9a7c27b7be2f2607b84acbb98619c5142c6f4aebf56274c1c6991a773f9170704ab0a0e1e214c94fac9fee3f2b4afd09dfbe57bece690b7849b8f7e6ed6c8dc9c031c97deae660382656d5d9fc03549039e02247cd237954380cd6b958b1e4e4f4f2fd06092810835e10ba9f1cf0f9f036445491191fe580c307f17bb9a3c9e50b8aec761a13ce38aa0271d7338a699bf5b85caba825a45e37b405e247c7cf6f0db6ed834d0514272ae00d25c70aa18d26e70e3ef19b1b9cfe002563149b4239732b9a1d3cac31183f7d588aec578b9b816e698de982da0bcfef2c2998ab639938186339119f2fe89f39327f7a77989d7bdc93a12e26e9548bc2fa14cb455baae40d96baf3749c387e1b7c297dd4c179298c5eaf0c5dd02f6febf37fd0ea45a505d9df9d32d21fe34d8bf119cd77fd469ef396180947168daa54a317bafe46e57399ea395fe8ec12a636d7700d882306a2cced9ace3db9ff5a0ce8d422cde201441f7045637b9854b83094a9b61b92202cec7cbf0aed007330e59bea1d641de6b8a0b72e175d11c32333e85ea0534d6b7316a8726b37ca55d0b66456e926d43e9396861f5ac04a6d235537d940cd765b67abce6d600b58b542664ffaf1afba5750182ddf1e965a70298fc01f2ef1b6d80132650762fcc2da1502a97784e84e9cc0096c86de42c51a07d8a20eb1e92a3e545ffca4500e1a23c2bfc220c7e02592d6cabef6652870de97c7e5dae28712ebf9361a74063320c8d90afc4b9d65ae6498010364c561816b249267f829e8eea99223f2a91ee9f30260e11cba163142f736526b97c70d7317ac2241a82befd6823351efe822cd632d1bf26cae52794489bf681420415cc70b201645bc8e4b04bec1f8420a7f13e838c50ea122fcd2f0b39aedb50a42ac99121f99db7ae23a43f00d91545c7badcc8e23e8acd366f71d6a22def8b4d031b6aca1cf59cbc8101650950a3acccecc2dd308479d7303b814ccda9b72c885b9b1f8d41bc381a3f4150f59802d24bf58b2fb6d176f4a6b74b35e4fdccb7e3e4d04430896f0c9170e422c4fa2d5ed57e83489e777ab1083f4835af038271bbc8943ba53a5247083519f21a5781b64f9d29ff49324f302dd71d28d2c02e0be75671082a31a9649512998b8d5ab1f9db850c664c878ba4dc67ea99d715e4b1d5e451d186fb51e1e57b9dade68e92e61782761ba17fcb69e522e9febe22363c617298e76d7b6e575d177e1ed0ae4391b9d5dfa4fe86c3ccf6994cd51473185cbe666919d27aeaa39453018008a5b10bf32ef08993e1ad3e27bdb643dcb9f9021567868c90749d31bfc229531779c90b695b97151011e0340a165295df9a339321ee4bc1e14c459c45435c2cbf0605b975299c6a29974cf6f6236eb5ff6c39b1d497cb030987207e3ad3e681edd3b16a91c9061cd8068436da3b157ddbc1888a6580fdc1d856a2b78f73565e7fe68b2f2e083a93966151149619cd43947c4e849e2ad613e222c394dd7b789b86370a040bd039fc95e246ebf175d45d8c0e07bf895562cfeb44a33c2744b8d52424dd0377aaa1777d0437ad04ba425552ecdb294b610ce744faab39c4e20fdd8b53ffbd66a8af0eaf265d23f9f8a"""), TestUtils.hexDecode(""" E3D54DBA675DE7530D3854C8CDBD581C6E392F69CF9793D8C0BBAFEE7334C5878BF13B3BDCF1D993A47A7E8EDD4B6C3EC915A5E8FBF2071F112AAC41F08CCD8CC731143AFC223213212A5BD6B6A4026CFC9F7A41C08CB99F2B375D0E04FBBE00503533DFB869DE43566574B49232566E38B13CAF8C1EC1FA11CCA3DB66887996DFEE090D133B1D394F075F8286CA6CCE13C3977D929DEF5943461BD5A22D4BB5E8FB7EFE016932D02ECF4D7B7705412CA14508B13E61925EEC0B77460C4C089C83D687C8F70D141C75D6DF24FCDB64BB8C2721AAC9CE8C6FC4750C1686A7A70DF34957DCC0CE53C3F0D280CBD056D4F921FDEDB35AFCE5DBB348964AD105EEF5A1B07BD0D586B87ADA7CA7AFA93FB75AC0DE1C749C48BD6F192D6279482D3F9781290B88B095D73E728AFC186BFF0816C1DE78119D701FAD382C65ACC42B04D69412AEB255793839EFB9E5BBF6F69B7FDA27A44C04D3AA2FDC6101E9CEC6F75745F20E077EE23D652B7DE547A0FB0E3A153473BC824AC8A31A2C9493DE64B6D40185B60431B1B34EE32797CC77C45C71F4E04E849BF8DDFCF640B83130208DC2495C0CFC6C031B63B80FB45F47BFE3D25EC5B36C2700300D8223074C156C5D9887DE8C5A97BA36A84D7585CC065F20FE8DCE9E8EB814A1D5B7A3B7A3AB68D93EDBBBBF67BD70A0FC536C81C8D6E8B139C6B3B5EEAA3953464549CB38B78A15CE3D5BB4B798E6B142BC48C70C5BE61F82DB6E2EC03616999073574E6FB35D441B78DCAFF56B8CA8F473EC0543C9C69E93B97F95FCA58DAAED511F4440DB252EC18C90D2F97AD901716AD34EE103EAB0B7982994E21ED1AC4BD62ACE6DFE12C8C2CD092E7A7E37BD4E61B4CD51D980171F8D4253A4E7FCCABA0A513038276325372527621B0A3DFAECCD7CDFE98CB79C0662F5D0234AEEE9302438B778238BCA409D5908768779155D659E92D12CEEF3C2C954C3F1A4C2912E9EE994209B608A604D0CD87F79665A25E774E6DC1D8819B85852D9ADEB174C75D982DCE29FFDD24B7AAF5946A74C14A301AE09F1386AB17ACC341D6DAC040FA6527FCB8E095CD4F1651E47CE02E6ED76C085B2FABE9FF5A510E63E73EE386AC17D5C2C94C2D528B3A9C8902D10C1610BA70BA616C58D037F148E6332107DB9F64C579064F19481669C7888C21F0A3374194FF1A72FB6180DC01D29443BC52C318AB03843357A5A98B3D5CDDE9BC49D3ED29EF73CAF44A7849AC6DF4B2D353B6A562386BD480512108CA0ECD63BB3D3A0695679762F8254116D8049488BE6389FAC08916E6407944B1526BF03551504E40E6A3266D4E773E892EAC4DD5128374BA341EB4097E20A9BBD4E5EA26BE6FC325D9B71C232DCE1974928516EA2519974C82AEA5247627F802C6442B67FBC10E359672EEB9DFF768E9333A2166336FF0004DE5E7BCA55998C860FC1A86B75CBEB3FB5A5A2519D5227A6B5A7E0EE058FEE0CAE2B4AA75099FF098089F0261C443B13911CF3250CAE2F2906CB6454A20D0FFFE8C5AFB1DE7C5BA8CAAE00CD7C2D7219FC83FB158FD6D15EDC2924AB41C9B881566C538F5E38978C3182FBDD0C0C532A77A61E5B8E666B3C540DE976098D2BC68C0CDACF57E9BF1BDE8A7BFB13256BC69F2E386D8F458D303BAB781E537517AD7D0F0378D2F258B013AEA01C97A7E8CD2C3DEB203AA8D59084ACC2B09AD3C97EA613A2FBF297038B4E721665D512DDFE5C13F11DF4BDC0200BF610D57EA7232914752F75A544E01D5AE0DEFBC9E18695824058BDFCDDF4D5884840D2B55D6C2D6EDF475CA75F3EB4D0EDFAE99349684BC9C533EAD591085BD1D6D4E4F9B00A54C97244322D505AB52B2D4E0438C6AC5D2C3983BFB2359FB21174AC02156AE11EF233AF40A695854C84E620754419CF7ED9EA4FDACEFC8879B2EBC7B29CDF9C4CA2921E084486477C1452BC3BAF529DD92748E2B1B684B1103CF4C6EE11999E4121CFC7E2F3F6C7BB9C055F800DC46D78D9D94C3B20BD1B697411FF0B41E38173D2C9FF1CCA77B27384026ED2EE25223B0007D2930D700A20EC9159A66A4BBE0BD84DA52F006D7FAC6D59AB2BDE08FBCEB76A57FFEF59C077F9008A4A231FCC302E4DDAE9F3DAA55707C1EDCDE8042176DC7DC6377BEC58B236990AA6C5876D5A27942FFF7FD74B7DA1D2EC470CF71103A64FD2917AF4C45D4C59C13F58472AF408F9C5F907C7C6AE0F402B404AA40CF8D962EDEF7B7654EC8E36C645855BBECC1337EC18F0EA65933F4D07CEE15294139F479A16133D2BF412B5E46D5B06FB170F0C93DFB8AC3F7478002CA76B67A272A3224C8172CDD8A616A4C52F5FDE946CF5733583C53835EBC90DE3ECE34299D7E5434BF072F08A44905818EE9708815CED10E9043E88B6EF12BE72FC1169FF2F925C38E03B827CDE77740C7C2848AA3B09F555E2712B341E248772EFCF01B99CD5403642448B5243F35A3073A6DA7685AD42FECB05D46FC99F7D6B8EC56F39A7E7B3579FCD587E07C05BB7E1F5D49B9015375E09A9A14F2CDF049AC392139EAA3C2547426B8CBC0C4BA76C55014FCD3940FEA2631A75CD2FF5C22B8A65C9AF2DB1B831C30EDC8EB79B797E76D045EF0B8EFF8D41404F626DE8551FFA445885CA1E3C9BF05B5C39CD40E3B37CE3B58514BC70E2EA94CD694CA88C1F47AACF9B4FF6622C555AAB7C71EA210FAA9C0BF9089DC9C9DFA77C2C4A92F59BD7CD24EF4F8D5088DDBE22DE854F8966C017FB414464ED6B991E289F7E3FEA783831CCFB51E227A6DD4F5EF50963E80847FA6B350A2DCDA3C875D176342ED73BB42B416E58D1612C4D066F1207B6E16A955DCD557A9EA37A9F24CCB20E74AC4D6166ACEBCD7D651450E5D4AEA86DC89528DFEBE07B39A160160FEBBEE5B11122B4177FD04B0A49803E498F1BFFBA898BE3B26320966165E136F7F517FEA35EDF01D36831F9AB478CFF8241E01AD7570C26EA62439013F61D48797B92964903802AAAF356C6AF7645F5F4338C7EAD5AB2898C600123888AF42A2FE06FF03D81320FC08E7589E19887EC86CC1B08204C29E86CCF187B1240B81F7D375F3762CBC10F3BADCAD7431E59A4DC136440AA72628E17D2BCFF916DBC8A66B8A83A3C6400EA0CC57A82DB41BB28CEA9E9CECA1ED826719B9B62B6CED5B52FA518FE47274DC6E22E5F8398D42AB23572CD6623EC307FB7EF61892AE3196C48125605F4F09B9C0F0DBBFB9D9015D325C546CF3B1DC886AB0DEFE2C35CD39E2AFD13AEA74F787B410883EB72DB8CA7D225E6FE8143695BC0FE556C6CDDA493F92ED62A38E8F90CC4C713A4798984007A5CBF68F0CDCC01274C96A15C3C4355ADFC75F7DB0603918ED6CB4E4491A8569FB1A9AF32528F6E26B2303C7987E39015573521E024B2230BF1BB803BF2B358880F2840CC58ACE31E551C8E2A0F8349570741F8E93066C8F17608DE35AEC342415A4BFDD13A9757501F5246ECA49913D0F02EFF35F4B3D40DF97A64B0FD02709C0832C423543A850776ED9C0574C26CDAB8DB371F5F4B731E6F510BC09FCE3DBB58BBAE1074CCAC284D5F8068D2435E053A037E3ABDC957B74339EF0063D367F7556E49D2C7A7DE3616F5E8B703B7585F526E9306C59329A18E76B85303C31E3616831F2AA2B173CD0A43CDE76AE52EFB8CF3C381097D7A7598EC833A75E97AE4DD539C31B3E45216EF9C844008C28D12B12D3C7EA7FB89B3B5D20EF5C7636A8E83D6A9F8F7DF29C9716B7D92313048A7E14B9EDF77FEBA874B9410DCAEC4816D2FB57050696F5D4F0DB47C6183D447C5AFBCB948D09944F4271368542E377DEECD006779F6F7649B946E79BBF2E19AB4E93F142BB24E6D962F6648CD0BF1BE876F6F431E883105C3E86B973E30735A6FE17346ECBEED5D101EF0AAFBBB4C072BADAA2F4D517C272F2BD2190F5F8C87D961041A121D6B319EBC959AB0603096017BF7CBB74DBC74FB866358EF8C1AA5B9A10B2C524E822278627C0AC577AE9383C2A529054528E58D56699540E4931BC65A125EF4B459A7A5FC10E0324ACB641BA33C83A7E100CB00FFE0ABF6281F8942AE5490DCCA37BF464D0B061028E46E025FBD5F6DD6CA1BEBEE282B749FF5B002210916B9CDC4D903A95972FCECB9292A554AEBD821AB4CC50D5EA0A33A699FBF07F2CA520FC44D4A9581182290294A8FCC66DE3FB5B7F5EC5B267D1A0E6F84C27C02253649F5903389A0901797A7EC8B78AF12BF2B1CC22D291347A0F8D6EB2698AFCA7CB4C23EDF250A5B77E51EFFA3C675F1FA951D72467EDAF987D5B63DE4177535974BB2006AA9A8DD9E624108229B1C5735BB039CCE47162EB52DE88703A8BDB8ED409BC01DABADFD31EBB95CAD9026705DBAE5A2D06376320BCFAC17A7DAC957BFEE98480C7A111B5ED300447A21FE62448F62CCFF7DA68689A73A2EC70BD13130337EABF26A00BF86E52077EA00DA46FE7323780CF98B3E998BB30C3998017F4BEA455568FCD567086EC68ABC40113DB474C6C88B1C1C7588E7A8C8D2082D4C70DCB8FC3D8FBAC53CAE95286F13254253861567E4715B03E682E422C111169D96359EE18265C3CADBAB3AE61F03F86D096ADAE9A6C4820EBE3B61015995707695B42B67802FAC2D6FBB2B67801A3E48843EB83288AB52C29C1F112F9233860612BA015D4B7CABC19C6294F8871E2ECF6AF334DF9C8330971277E32CF1488F04B4B285AEEAA83BB81D54B6B8426439804B027822373AB99868EC068735C816521BD75DC19F79D2E2166B1A551C998318FE19F5079BAADB12732528BC8B522438AAD252C57D3899400913CD124D2DBE90A891D95900C0256D9DDBF939BADCF6E37E6783DA2A2BAAD872F6C8C11878ED6D5EE2988135A39F2DAC7CF127100C36D2D4E58B3A9B1D7341120FFCA0EED2E98E020A46F1AECBC809A21EF79E6DBCE76F96B6930107F078A5D4464CFEAC414CA41A5EE4F87CCD8868E7922A14C247885F0DA9E23A7604EDE703C2BE3633AF9CCC32B9E5F51CF51978F10A06F5D77C67927D80AE480E7E5E005401ED95467972ED87029029DA05DFBCF2F0B9D50441E8F15804B0A59D23CFC2E3C0FBFCB10B69AADF0B37C06DBF972E264C6CDE4142C04FFD9FA0AF2451F8BEC3FDE9723306085ECEFB17C591E691F9B4D4F796E293C0CD322F02B96938A5F7D1C8A7FEB94C031DE24E71020FF37E00590AE7CA48CA876AFCA2BE3723EAAD40FD27B90FE6EA039C9F3F6069FDBC70F16626A41678A31E8AD88DE9BCE8A25D43B86EBF80E5E426FE21606E67545FF8E55FA7D9802D65AFBDA79EF40DE924FD0DA7B5C8F6A2CF993FA6D27B2861C629CC9BD2E1E6AF04F88065614F7E24CDD19C88CF2D7D2B93B7408D898525E5141FF71D18DABAC186DCD432F3895A1027C92CF8613C80BD46E4758CA26C8CD92B74EEBC5FA5EDF9C9FEC54FEAC40F0944E3FA165E515A03DB57C205D383C04B2CBFF703939EF321DF8A49BC3F5B1409EA491062B7B9982277825B52C6CC8313BA05ABFFCDFA525445B1CFF773D28536A989D257967B50D7BEC4FDE5F338D2AE81BC8EC592BE93BDA0A7DD089057E675674E8B997B05D049CA3DBD60B7F3FB23BA5F4E5A48ED8535234E5C66C41B157C25B5D9EF5C8C0ED016D6B217F4B60BFD0DA223A5D40C2A403DE8268AD5E6207C54B217C2F009C5DD052266722DC21D4AD8314DE498692E3C77C9F8226A14F27D49E0DA1101E32E5B86BC0F0348A20A360A919EC863695D2EC318A61F654C9A1526AF1538F928DB76F9B14EF598F2551EE85D6E0429192C5F18D339DD5A280DD5B1A8F59EC1F2947996C7E190C87502FDF5004772224BBD1C4DD62A8DA1723EDB41176A9AF04B1F30D09050E73579364360DB4F98034FEC1B43E6E9E0226409E6AF1609FEB862D845994BC20E67010237B74DF1AB59EDF14B1623FDC990B87B929FB7E837B1ED905286A886F59B023F40B07A989EF7A99E974EBAEC49B45FEE1F405D11A641B2B150EBE854F7853F06026CB1287FD8BCEFB15D2AEA623D7C3ADAA00B35A105ABF2D8F9715BE65AFCC1381D29C5EF398F2B76FE1651348BAAC147CFAFF34778242B32A1620E0332EEC7AF5E750DFEC30A899452ADC530DD933A07748DD522AC20AE2B2889FAC3237D23C4472FC8C6B236D4A4D19F67264F54BB9B25318156B30EDF273BBF3598AF5B34BAD41585982F6039F6E488308B47EAEA5D21A91E5838F7D9CCC8F726EB2DB82D022BAF103AB2DD444489B94E8DDBA71E62AB6251DD5D5F69E44F377674A5C2B032150C32664C96C072867BB7A2DC29033E6BCCAEDDEA430E5E155DD0724FCBC0415B2AB6DFE68A2E59403B206BBE7F421FAAC53F66040C5CCCEB19F17BF000AEA7E775211E48AE04AB32B2EA470FF97707D9C073FE72A7B77D49FF8DEA36610C2A83306435861BE01DC4B20DBB8AA6CB780328DCFC2A32D74CABA83929CBC85E406E74EEDB727A2FB5BD9D304AF46225832858B295A17B9E710BD7B0B5D19DBBF4FD021EAF29F4D1B6BD7E78C8A3E3235B5D0BC687BD5B428D2318CF4330EC343566D42D17BE838EEEDF70F1E409C189DB1AE0A205D222C92A1ADD33B8E3B126AF62818A2DBE3E3C001098A986865C6B57D0B2F5579B97B6F101EB56FA839F8789F6774074185A8E0F383E9D8813CA1670D8B7586A3A1C27A3F5A3874C4E743EAE21BC519DCC430E281D2F73C23BAB948938A46FC24DA94647150DB72783AB3FAC01D834A8544F144779A51480643CB1ACCA0BF88D203F865664A5ECE18A88CE31B0D8FEEC585F9531329002D4FFABED01EF42AF52DDF08400C58D07E98046D77C7A142B513DA0EE795DD57EA43F4CE36C8F6D2862044945DC293C8D47D9F207B0344220E3177D6E17A4B39B22CCAE3C53D4E0DC87F70CBE9BF743CEACB8932DF8F84A527C9FB84C6CF5206EC2E43D1FF8E846DA06EBFFFB87BEC09C63E9633713768060ECA6259AAFE7C787F3947D5B94A6B80FF0A7A4785836F9A1396833347C13034040D1C6B1F83782AA6458328160FA04971DE04A16B6C031B2571DD131912CDF2515DD56983ED6EF3BBE5B3989E951BF0B99C5605C38181E96690487E87240059DE21BD220059E5D7E3C832FD4569BB7DF06437197CAC141E8FE5B369B542CBEED2F9025A030C54F0B5D2B1E79011CF2A0A0DB14312E352D07BC03E654AABAA95AFD30F1483B57BB1A74A0CDF8C9FDEBE4B0E156FE86BB1E21D861F8EBE0C4AB2B23E776EC01A281F6DA9BEC4C560668B4EEC71856E6CC41741DF2EBBD4E95B661EC24FE31B1DAABC9373CCBC82F3C13C31E478097259850221928C7AC6BB933A5631C896ACA87FB6F5E3EEF36EF5B9CE59F5676813A1A7E768FC9B8AD4A0A072672BA23CC21B21A95C9BBB1A40FDFEBD2D611B773DFA55F87E9AB1CE51CC42B0FE2FE15DA2D73F656CA56279AA16722ABAED5727519EA258794503F1808E4EBF056530B318B99A74886D05D042DF4D829C425C908B58162EE30A073D4BB7D27275B548E7A90E6D178DD27F67CD955270825FB96300C4645E4CD9C175C1185707D4D365955FCFD245A55D64EFB66308A47FC85592BFB755EB4AA8B78B541274E2C225DAD649C248E7F2792A56BFBEF704551588460B192DAFB9BF6798B7D4CECFA424AEAD675DCA081E60BBED670F9AB2316F5012E2290770D3323403DA5748BE6681565A713873A5386A6F1299F0E1EDB341FFF08325510A7F2FE5EB0302727D7355EE48ED5DF4316FD34833238690B91D47165CD4CC0454DA33B87569D38880AD92A92ABA0F24D99ED4CC977A2B4E37954FBE9B9320101C80A858122793062C7AC26E71BE2608DBD2A97CF4E884FD3255D008700FF3531C045750B2EAF7730BC9A51C675D94179DCFCE9EE63C1473D15B4319AA9EDFD19739CC05C5C3C8AA618FA9096C6648756F8AA74FD18A8CD81A2D248B856902B4D30182BFC2F392450F902973043EA0F5E6C872AD43A2D319F99F095808D83A8B02BD380D6C3F3DD227EAE2B4A4867713853D63CFF405621B1EEEEF00D5BA2FF254CDF97B4226334A9866A2B5BDF1F8E8AFDF1238DA9F48FC388A339F79D648CAA0A0A69D6F16E297663E5F4CF1AA95427E68D71E74C0A2FB6B689224BD9978F7A3A4505334774176FD87097D8AB454CABEE138F2CDFC6EF0F3DB14B09DD02E7FABE9F156654433B75B951AE3C196D670192004DC1924D1950AC597682EAD1C087ACB1461247DFAB3CD42279F9169B69B33435DB9D8994AC04B15D45007F0F98334AC5D783219B376D9ED7553F52CBADF159F69282050A4C843467AE7E4C4A142A61CCC4C48DC3AAC6B8E0A8D618E06C60DC924A943AF9000F896446CB62EF4E47AD6D1FBE2B8984A48ACD7C0519D6E87A33106E9A91C298808BF04E1267349334E6C2AC015A9F704B2DDB56D27A8B00D876AD00F62434095A6F7A5E9CD4B27FE09FF69019AE5F27330792CF9A1C07FBE98D23C4E615332A77DB5B6182D277DDFD7572DA75748DFB3B9315294EABE4B6D0FC3114B2AFF5537A6B05A7AA9ABB4930E17B7FD3D8F81AA2D674DB69AD967C8306FC3E1CA8BF78F446B26D8F2FD1AF6F7FD7E52867BCCC3B4DBD7227EA992DD995D77C4A2BC808C7A3E68FA433675F489BC503DB70115A824669E4B1861CDBD557A1F78F1A4B3582B2553AC23F12A4326EF943C56F847B8C679695614BBB1DDEA9CFB7D799CE42DF8B735FEB9DC119DBCA306DA4FA84A50F79905E5C2AC1F61241D88359EE6F62DC9D3E4A1593F41CC5F3C02241CE5EB62C28A547FCAADF1DD688F3DFBA870D9BED723B02B0B1CDB4C08D093C48977E0621930A668A5CD517A0EFFBE248B4AACF3009BAC0D47F49378F30A3D2C2800CD16B3C9464563DA4A7321082FAE95DE5645FCCBC5569E942B5F860A32F04082723E9E53F2D18099BEC5E23A916354198325FA8DAEAA3F6B7AB6AAD6EF12A03CBDC27B83C818F44"""), TestUtils.hexDecode(""" -80A3AA584B532C5098947755BF88B40612446DC7D4CCA500DF34D9A91804FED988A4EC0F7124A5C42B7298D1784A5F6D364F7445E5F9090C0CA2C84902722A800B930AC58C45A46066A0D613DA411DF5511A5401183E2EB6B6C63486D3E2976D77D3319CAD88F01EC4429BB8C69036CF1BD891DAA369DCB525D33E9803485F666532CA7CA8321F983525E52AD2A3E363E30C7D7AC7ACC1F9A7EAEB76B7290B2DEE7C681C125AC33E9EB2B8EE080EFF7E8D3751E3C35FDB2CF58C2C9BF83DA0756A75BD92FDADF3E9F3E1637503C923802D7843787A6D947BAEB26FE64D0FCB52C2C29DDDCFAF2BFB4968E5938155F652145D00B410CAD920BCF74059908DFC0916637EE248E63C3EA0CDFBFE1B28388357206C6DBB8C0D9A23942938EB523A51774245567BE82401E8877048243D343E0D1F3F4503F8A4BE59BAAD3E76B7E2D1C2CB4234B62BAAA10642B903F5A644DF2B37E740DE63C82617C405B563BEE0008F70A33A59BCF17A38B0170F736D3D617469D39CC99E3FE9A49B94DD5E1ACD03877081658F4D0300CBD5E50B0AB094E4502BEEBBE4840CD5DE6FCB891203117980FFB033474E88AA07ED44A306115FB08440212D943C6E8896370D8FF97DD4E29ED631F05CD72B343698B8078DBA5523E471F20F4EE58ECDC30E3D4E0F0E130378B42E5521AE16088C18874703CB8A38D382FC89957F592C051749FAE68C14EA0B6E11677D65D7AFEA3516AB9B75D5F464B8E119E97ADC22CFC48729DFD3881AC6422A11E0FD883F44FDA7A7370F85FB80EED1A4D35AFD4597C173186BE56C94F275E4F2AAEA096AE8FFB8E5499DFF2A00AFAD19B40A0EE428EDBB3B64F34C4ED401BA5772D647DD20E4BCB393D053DFC6CBABE37D7544727DCD40A42E83AECC1BD8718D7B2F0A8B5E3E98A568F055A6EFD74E8D81851D745634AD5F7FFF96A5C832859F92A92E70249F38052CBAC2BE7DDD217786D5FEB80152DB1210421D53569B07346AFF582129AF9E35DE9C3A4CF2FBA7B6EFC9552503EA94A722F6F9A84E190C422883C71D60F4059F912CC773AEA6C52B2C5CDB496B056697F38F4EA2BEE6D5150E92650631DC3C35B7DDC063643F65726964575D34E0FBDBC3B144A829674BC26A21C3D7D873F70BFD2BE1F71D5BA2593C221DBD6A245045256738EE39251B1F433F4C8E0C1AEAC740952A677F72D11A0437A64188A5A8CE69A4BD56D98021B3DB19481D606BAA7263EC0ED9529B242A366B76C5EAC589BE4A3EE50B0A49852641F9102E2F63D75FE2C295D2CFF1554C77C742979F1DB719FD14D1FDD0303F5FBD3C96763CE56563D05EFF726FC1BDCC4C71257A8920A8D5777DEF74D2E175A7A2541AFCDB51249EE6010F19C9D428C774ECC455D23F7EB770B8F2AA09EB278A55AF0BE2EEF172FA12365E0D539C60FD5A5EDA381620C1775EB2F47146F1E2C5B854023C8711DDA05FF78E393D1273641CE6DA638006650439C5F32A45BE179B4CA0C4DA02D908BFAC72E47CE4A2E277991EFBDCF86BF28456A6FE93E671884EE309DDF746194369B49F76476830B242DCABB07203AC83CFF067ED83B74D201DFC633F63BB2039C82785C3A80AA6E79D303F02D134B141156C5ADC941F477E955C83B2EC1938DD6E491C1D5EB0E262F62589DB9F9BBB14856AB4AD10D450923ABE90E53D64667D87046B81CA2674A266A4F43C35A5DD0C8CA7BF90D9B8E7700970FED98BFC65D22F1D1AE7DA37709E291EDEBCE413A636FFD8FBC55D921E2C043401D68E837049C4469CB7542A3A4E3CAD8272301CF07EA827C7FC18766D43D5DE67C32CD0710963188A744B70D3EAB6950687EE42A9FBAD7FB7F1ABF8A623E0846CB9D3BF8FFE2C5B1D650E3086C809B08A01E0AB08AAD8808320B2E43F4EC80D71C1B1A9935C6755349AA3E723324FF334BB9BD2D6DEED275A1F779227BE29CF8D6302DE79776B2B59BC42837EBF82CFE344AEB2CCDBBCE412258ED39C321BF78E4D7F1350AD7070892C47A656A9579015FBC1EE340502E6592D0078293C79BF17F189F8D46AABE90C54FCBF3651A43B99A004D1FA260D7758413015EC3406B8D7E5C8A3C0D110F79A883CC13C2FE40047095A1E5D0DBF136A2D33FC04D1D5F7ABAC0D43FC083F87CEF760B4A278D90E1D5FE74E999A1A58BCE582B22807502A3135700688F8628FD12AE152A506038462F6A8B45E5CCB4440577374CB6032B75E9B92B8A4FBD2D080E2DBE7EF640370AAEDC4C75829201E17797A25EA8ECF81057F3F3BF50227ACA6B4039378BA480A07085598F249C890831A4A44A5D24AA33009A0DBBBFA5CE269F345876C7FF4B55D5ACA860DA86FFDE4EE9966C44A18A5C3A1FDAEEBE3BD0B3B9C2D92041BEE72990348993491C73BB4A813295422B4129595B359B3194010DF21F4D3FAD2CFEF725BD089AD68A2001B29D6DE815B9519850C99C5F0C8FF573B2553A4330DAF4CA5D4E98804EFD6B0D4642FE94D5835CEE0987209218E37921DEE6828F29C730AD5338B2C8550FED699D266E99651ABACA63DEACA113EF34378654EEE36D53846E5BC40C189073E85DF689612AC27215C7FF655F23273FA860CFDB866B7A40AC33A28A261BFF4434C3490292DBFE7DD54F54950ED3BAE86FB6C7B05AC2DB2D26946D0285BC571F4BADBC7944B9DC667133CD308B034B24BB5177306B73DBD7D506225ADBC8B12427E691F63D4DE76EA4C54434A57FE92FDAF6249D355D5E6F303BE70BC850520314755BC500E9C1AF6186FAC1522CF527158C491371D7596C3743A94E8ACA236600D6682EC7ACB87BEF47078722D8B7AC7EA48EEE37007E766214C0C27E97DA933913D33A02C522B26800C113336312D86E0FF38A67B09B344205062FBBF576532D22F027B79FE5CFCC50C3CE52CB6632190AF1406AC18C21183D61569E14981312744C15207124F410E8B769AE628CAFACF5CFA53421AC5E0F426D62A9BBCB8E275573941F876522085775C8B03CDCD3D67CBB50F4EFEDEC473DF28D2D881AE8CE3C1BF09F2CE9188035948C4A3693A05AFD3374EE58EAEDEFD90CD8C4FF0AE325AD8E78C38EA6EBF95D61CF46203DB6455176647D1A12CB7D7423E3871F42A8B13B1BB9C2C2D10FEC92C3F9E0B792C837C07C10AB815A359679DD22584E4EF1BE4C1DCB918A9B130C9A5E6023E6763FB8938D511DE761B7A4236015422D30C64BE39079EB5C66FD3E0BA97FE1FBB0F9F61CE878052C90435307112A2F83790DDD3C2A420ACB56C8E0D76753E3FEE5D73DFE901935A2313DCAC424200606E704F305E124A28FBC0E30E38AAF3F2ED11E27532C15664376741F70F59830D1ADBB56042F8C87DC2C989FBA6CD94AB7543D0EA696F74D1421F489F070C9A2C793CF48DB7BA4FC951CB47272E450017E3849BFF1308D3CF74D9515C04E889E424CF87D0B368DE99D9C31AA1A217DE12292040ABDF61AD972729B6B1892F72AA71A1803905B75CC61C87775BC4C721D94AD74E9916BE5758BAD7CB947CC9E250B42C9525829F070B0B0DF812B89A88ECB874E0C81F7B1FA95FDACF77C916CF8E72ECF00C319BF4093EB114465B321FD086B79832AB16F83E7253B031531288F70D94BD5C9531DB6AFD125A736B66EA40EDF68D020B49D2763B016B328D8959B08370C37CBCAAC5B12297C1F3320DD9885718B4B00DD6B10E2652A69360FC719B55723DBFA38749CFAFB440265DB48F5DA31A056A59428D3284F600E9CD497B1378451569BA3F8F1D32091642E65BB229A0E676E3A80B1E18C3A36C4D17F9901909DB8E5E2203E7DF5E02F152B1D302C31C91D8ECC3E13FBF864FADBA37AA645338597001F55C638E668A6E36794E83247DA88C84441EE126E43DEE6F3F1F201738E25E859118050647BEF46D042E14DBE46E2B189CA03245A7848FE104B08468220278E230FA454EF065BCB26CFB93B19B3B35A2C1D69E301300F50DFA168C54BCBF8673B63A7DC6AD7F56D33CACA83C1C77678777BC6239632917ADB4000D229E0ACBE4A8A243E6C57ADD4C728527A7051DFA5FC4B995A3FE3F3A6E5BB9A9D6FBEEE21CB1DFAD333F6C958C675126667F0C1CED9739F2499E79AEAEDA15DBA5C8C31986564E962FCF789608949F7FF91AD70B3431CB86D7F1A3E129BCEEA58BF56C5815C9E44B60DBF7D104B8C5D85CF05BFFD603A2F20843987A1A5B34B1182A014C5AA7F5EEF615F677AE07FD093E77CA4DE721B67760306C7565D5C764D2673E02B266921647BB5D16AC34644183BA29F3DEB5D494D063A41E7615F8DE9D8F300FFBC156B69D375D8C3881F873A98EA7F8759D5B287927D5F3EEE9A242831B7342CD495FAC2E76F25426D24BEE831557B622A3F7DA57759CB2DC91D107053CF2C3D81BF1F85D75FA9B8E6ABEBF976F9ADD4BB7F788F8592300F36AFBF1800DEC01FD44BE822CD2071E328C1F0E23F460EDF2ED9A6E6B68CBBC011A86439D8D110F56C57EF270D25C5B588BAF25684BF68CC02827A927F9902283D3F76DBF53E864C7B9E44A193D119B563385A603C3E89A3ADCC9B7B9257EA51F697E14F708419E3CAF455385585E461FBDC32C921D47BB7DC8991D01062E833A41535A6978A3E016585FA9C6E248676A7BB5BAD5070D149BC3C9DD1A5C5DB200000000000000000000000000000000000000040C12192024""") +7dfa6f43cf7e66cb9e8830871ea48edb07de9845daf9433d74ba10cded10ae8fb4955732aa5f11581322d945bd5b0c05ca195e5373453435602784c9e386ad0766d81c9c954614533a0ab7407d4eead99582655ed634e9a7db1458e3f91bf0c4ff63adb0b62c4e813c396d8a640d0464aff2abc80dac7a5d0329e31eb34d00c2d90142f47e1dcaa203f730de8723ff5f6e9db3dc53923c1dc413ce54f5049496cb69e1280ba7ecc7cb540a62e441c97743e196a0144db65e3c0022c9a6ec621eb1ef79c93b4b224c4a1df88afe1c4513988a9aa4d6aa2a440a9d2b3946dceb5954b0f5634af19cb9de528dfd8bfe857375a8c903b124fe6b9584fa68f56dde10114aa62aafde3159db334294c06b2774fd660a13e997403f04f5027bda9745e16684edbbdcde4155adfe34e0febff14bb05057ee9188c2f7ec829389e7fb24c24d3ceec6f37e53b592b40fbfde40cec330639e585017f79fc86c68de2d24e49b33b5368fd1c7d027503f12b339aac9a4dfbe711918e9eda6bba049154d4f3aa0519078e9ae18f5a94f31adbcc199a72a7b09de94c7a9ca94a04d016fe4051e5b778d5de31f3fb76fa68a71574fdeafcea5e72b563e99982ffcef751e8422d2750809786b57850b832c34a1ea88176861a4176a6623159d63535b5897ef1621564c1882e2ab954455cfd5eb080f9e979a580fd8ed7b02bd504c6ce24c55c1e582e524b6aaa8ef66c666807aaa994d22df7bd5c1a01b128a408b9dc762f2a5fae6a61da1ff4a2feb7e4389bf3fa4357c61acefdbe386b6e55eb3220eecc005cc0047b45bff02e87f1f55177c78c16f142c27e6e9c3ef81a5c5cc77e70695a7ca57e93da2b5c0b32a8df6a77dccb47f3c9406ac58bcac1ba5aa511e417648c4160979d7cd710d35f4b405e7b3d09d229d011013e7c84ca8d0693696b4028eaec2993755bddee22be25b4ab0c5541d6379a067b9fe755955cf11f7f83399bcf28c331c69e2f9a80431da37b14c7e854232037284e91978ef928fe68021138649d3cbc669126910cd648e39cd91efae120eb275b114d33629bf451416ca9affe96d67ddbdfea590b7babfbb49a8e6fada738b0f2bb907e34a856a835e09a8c9076ee222bbffaa25a30aaa21309449c4cd0a7fcb6110a1c82fa8d4a737bab8d92e4bdde60827442e9f74d135f3834073da3867b5094f4653d88607e8551f0c2951595fde2880f0407b60146b5f83ce3e589ef16368b7e058db6b3e8b98d6d459428635f1fe23fbbae5e96d5afbbded8dc22010c58d11e84edaf7ffb8c6598d15e8d3800cdde92ba519f3773ae13219b7e2b967f360162431f50b0de5c634dce2a361760bf2c656e47f8d10336c0c8a0694c148d43dcadb3f84ba52a2f8a167732f106df835e50af089652c7c806b1f51ed4dcdec2cb5d97b5c06f6c64c2be83ec4c1b228fe5615b7531921a5ab4e2357deff9d75e04586f0d325e0bc6306cc22f59e26dec56a2b0ac627f95be580a8efc9d7c27104a852df113d443664a9fb27c0a7e9181372eab430394ef71bb5327e2ed828b60a7b93a42b054cace4b029a8f4fa8fdbabd0b728971ba99c641ce864b627f9fa17c33a6f50d3df9c97d066546a37ecc518b6eec761351240ed4ac606e498daffcc4cb2ccb061619377d33d791938a32cc3640f45549f625e8c2c284a7fea4fe1a864417183177f9c914348d7a693e2d53a95dff9fbe6b26604ae005bb1244176ddb2eefc07942edc0b0fd336f267006979bd82c4499460185d7ad41301fbf5b17e78491a02b8df328aa35eca2346c1f37ca775d11facf01e26d7473956f28551bae4afa6039faf145ade0da17470beb6857ff7435b7ecfcfe51417282095d7a83316d16bfd0a209bddb52461fbd14a74bfe06183c01c40cd6086c6594921073e6a49580aab6b28c71b960ad575471fc6276b4df624870ed01346e3a6252b8e9ad82b40cc88f5627ea5d8073efa300eec86ea921cde8cec9e172314081eee5f6cc665f2b0f6e5a0e56a9d55d8fd1079ce1b5ee10fd69b1a1e8fce047cf7264edb9c44e51443387f9d2fc54b3ef09055f819fbb065d6f0f09e53b3d5536f1c5a98c1778a5a45755894290e45d27f93fdd72e948fb5a1e4b2b97798eb030933180e8aa5bef5d89770c546320c9e2080eb7a1ee3c03a424891517c3281a0f2a7865a138e7cdb1b417809c3c3f62b12baf9b02f9156ab6c774c03d698a9b52380124d863008bf3875dcb7a8a80191c288fcd856e138783a0fb301e395ade94de2193b7f316c63fafeb388a52bb934409064aa9822f5582f632324e11b6e4bd668c0c3d57267d64311556bf855524191565c02da543f1cbacf62a1d5d9839990ce77590f138e7db0641e51ad911c3c116addea6fad97243e9ee4efa3619e8809d67e8907aa0d63f4d9ed863999212e5edfc8e7c761795792e7d9c1d05af67f10645f76ef119c6ce384e92f1f91003761c9203f2e2e6afb3ed4daa3c24d74b9cec3526159f7f88b6df5354db2e7eb0dc1240cddcdf076b8b8f4567eefb4b27e07aa3a6dd9e17695f58a647002283b2f853e9c5abf16b5c4c1f4cf6dc67e14e2ffac3ea0e98830d8613fa7a149109d054ad4858fca3ee6bcef6bed0ed48a877ee4d0c758cae7394d1fa4d65e6fead01c555ed81e9757641d48ddf8ca28e3a6448e67eb0daf3dfdcbe10a376db16063c1a3c48abf242a5ce4e65ab7d3e535339e5689017337b6051820045bee408764b4578c6d0d7e1e17b9bf537912925cad18cda39c8402e3897ed04ca387dad9cc68d049350c2b9d8440f4195144c5704251e5164cb969f08a4ab01d230dcff7c769a026ae57fdd36abf805d114716a8bae45c099994eef19abaf515a0963633763fd2c42f4fce201ec61da3b5dd9d2d89c62b9dc8dfe0ae91fd52b67822cddc9e4604da09865e3a5f9db7e19f1c13420b07afbd84725095ffaa7f3f301937842ea821ddba3e138a0e2ff251d03830a885b5efa7f38492e376f610d89af18c7878e0e179c587d33c2e17241a570496e9ff8e0e980d8d7eafdea8f6cdb92ce8479f21d0a45855a41f5f20103389d3edcae037113c6777bea02de2fe919c021476b8ba937d1272dbdf038cf74e5bc7c94f25e85a8314ab2c1ebcb0db37daea22c2411c77489425be5a37509fb21dd995badd07c3c0cb55400f3df5253d856068a0c643ab1599a30844664e0c1234663f447a1d6eed317b362ca8574e724c263c29221231e41f980c8a773736572f282b5818220e34ee47ea2266f9291cc5ed376aba26385a5252e44d05a49755b1f7b0856f855070ab9ecb1a9de29a5b3920b3ceda55c0aaaac031f935e563c50c840f9002b49dd06fec768a9a258eec5b6aebb997a9e2fade8a95fb824c9fe7332528e62b23d82f99cb9e13e9a339f1f086a7a60aace5f34d2502a715df1d1ad9ce421ed1802f6acfcc96836e481a9f3963b0f28f5ac8381f83a7447e2cfe35f3f95276d54a8143b458bd195cfd4a2b474923791e8edd3ce383e80c9a87a258734656d7e82cc26aa4f038bff3d13512ca976408466f32fe5202dfef7a8bb8aa0b24d798191d8086b5a3ba1742f2c105439c58ce3288d19aaa535818ebcabf73678f27856da1507aea1df0202b01965042602c582bc9a3642ce2b04d4b0bb4fdf3d82fd3c4f4c99ac960530b04bf5fc3b885b0a5fc6fea3103ec3649f40ee24da9d140ca64f28cf0fe98d57f72fdedd468b27601cb5e34d34beee6151ed6e3c452925fdf6b9601d69ae3c36e9fff6d6a1b6af87b9a09c3f65e121e21d6b5d02e068098dd1394894e472ded09f085396a4a71cac238a878c215e7a955cda7f3742fdd1e2dc4348f9abfc46df4650e82373f08e08dac0a59ca8ffd419ca2886c891e88e41ceb85e10c57a915f14c79f5820ed8dac9a6bde0ad419198efaa1ce3dd2f30bfc82fb37103e7091d75c23ccd5b7d7fdf1ea49aade37b3e7fdfd9892597be68b47c912470b518667c28e7c8ed0fe339114bdacfc4b61ad2268929c0e3d49e77ea2a3a4469b79977e928b4deef31617f8d97d879293318ceb5c16ed2df4f1c0a7259786270836ed39ab184a0390e0d0d084c5313f9cdcfab7490c0f8df7f9fb8d2ba658aaee470524d96d90fb51f509ca6db5b0193f817707b6afe3faf49779c95976d57eb710498d9e7d4e1dbc7026a19d079bd8175ce4f98d07462f1ed85fd34101b213cba0cd73eeaca9133dc380031f6ebdac8f05eb29a4f22ba34e1a6fc29e5aad9fed9a74ad8ebb6463858bd894e390499d715c5140b5cb342effdc7184c53c33624fed2f9aa05e085cb7d68e7e3d425e6a08f91dca36e18c8061453bd980f41d85df2924f3903b1ca62841d4545f8ad8a4949166990499814a3db50a62730c88ab592be1209aeb8d2d5bcb3597d5160ebcc24e8601900010fddaf5842745be0b72359e5b90e6c11bcf5cad521bb23fcf452dadc00d83a9cec6f24184e90a3e35eeb3ec473cb0a9ece0ddb5418734231a399728a09387d82acd1690a66acd28ccde630704ca4e7d232ca5d37eec3925a3874581d181b7391af5d0adaeea556515a2a8e3b164a7b85adbf667992b6bff10356b3c3e085fd3d676d90bcd741577f000000000000000000000000000000000000000000000000000000060c1113191c""") ), new SigGenTestCase( TestUtils.hexDecode(""" -F392F98C9CDF8480C41F34A3BA6EECDAB55B7A7413B28B05B6D8DA29B455DA20C13C7ADADE697C19BD95F4181D9BB87ABC896C07446CC52B62F7C2883B3CCC61927D373DA98BB6B1463FCBDBC7C3A676D25788AB26706412FD08C05B130F826130DC142EBFDD884EB8FADE304455EE978A72A3A123A69246EA506F92140A8AAC301826517220457575500718444602606702737036246348057773753653026737530327720617356636110021487182406485883783500307652062837008037623504275143575413277805241337630721014485311207126464251365722038703047777860484650222507051720537247120624820142650776607686280727735633154433151782223422704163680716278603431812174820280568464342510822713206812416037802546378526410045560675630237304285416623454261283085572045668858060866837604282874804876254654326261578215675122020866578445072761231803362336526243078878567202715767743383861568417748622625301333140772280730350454860126812584207355072774075606603733422242068425724752175886643765751536756230433665412301147080035348337144751803325188375752442131056834846104747661738815140077787317821773203565820682216027654224806146185675613323671341833128465031767087642306567758113743515665083376682071584772645080206870431383757154651308356136765831320760126350481621267663254431456810768528220808107371083873767157585238851353083212225832367378252330145547815686824158782844746478735016774465466740401333310057727005121237645614476264226362084266800020031025007113888434744843115873163067161007831303825424463365517676765688324200684513347206713426521057202461184363017881817403710703264672680236531845142531570466384473731728758138705644753855655816742241364617142126084780008354140654801776325821685208137803465245450505341523100083408734674154335414845701708522128274506836754076625206872353746311412316312855531504102358752662137808638173521823133750654348485071110586741851463345337506614254157164306768776078885708514685148238201860867238133581485532340048788405422353860218008258548436878687253828241261050821015817420278763365687765514675058675166754736381757223055720684127776321362551252532374142887160764038838183424628018841887374712515033240300045651318782786054437184283851251186686603270668845482075874631015013706514675820635143655714764714156053721845140813850420508700657763114833577580426428065023467825688868337142277613856181714827028778062057570322170260362422631028183028112073851046204428683517685558417500601725657238741370857627730181360274563088823835144601056210101460602232722700431633184040618846384113624585660727717184113675546163610607728213513133205278237138625783833077538572741625110451321533127067244638480483667304517823113154663264021760688615102244052321747321612302751435786674345144462326132726376720328244761422741627313648020611868614763040681674853246228406044610051800751763205151834303188718047635724013221728118711424128888062074420703056187033803211250204407771300451054423223354033358307300448270140765437102400745208838204164114740002455888478168313785353187171180330311056851418840303151441514865342313468076524833442066721446046807704220124510652483242431018436830414063580815564337474054060760627544438122721145213236126348660A82C6DE4E1250965D63B99CEFF0EE2BF66C76EA5BD2275E36469F4F48A5C59613823B26EE15F377DD9AAED3625E4C402D971B2B83296DE5A8D861CB951ECE6BB06F787AA4275345917288245199B56E7F3093180FEB6D09F62FEF524E49F685082481B42648D09F71E623477F4D9E98E79386C060311CE9C063717B3F69C36391B555ECF819637BF03B370EB3B47B8F56EFDDAC66893EEA7DBA70BD28F35D1223829F0FE82FCBE7B0D47EDE3C72D9454CD323271ACD902A883811175068522C068B9C4CF6A819E6A141737177FA90149BCDE0E38221CE7508D32BDF4CD9605EDD630C5AB530DD0F36AF49EA3FC26BC6C0743EEB48581460BBC7836BF163E819671E821CEE4DA76177343369B9E48C73AEB48AD198E958303449D6FA0707BA74BCB777F8E9EEF95B782BF00AFF9114DC954AA6A943EBBABB85A486902222AA990E5CB09323BE672F4E96A1F0F97302300EF6B953425DFB55E8B12740E91C0684D38530B65B9D9D4A48795DD27F166860115831266455A4D29A2A928A11D17F42F56D5344C9F50BCD5066EC1B469984FE4F8B538825A016A029BC3FD608488C78805C3EC39954CB1B9EE1182D416E7658E038ED6D76099E8D9BC68E0149520AF9CBC6BE7B03F85A39726298195C58DD5DD70987ED894DA457339C0C9AEE5B1062C0F24A99DCC9D4FA5E426335449DEB5FF6FA03652EE49AB4091B79E83AD0B0F62D0392AECB0AC4C5FB3DB71E057588D4F777F4D21E3E5AA059543780A80294751338CBBC7566298EA8F067A919869BB321A09736E9DBF1EF1B825CFAE09CE2A0B0660D04B2BD78A69B48073CDDA437BD3F21B00CEE21D1B87BF3D731083CAEDA4D0835C5828B036E6471E5739DC2A7F874F8E5E2D0F66D5B01183A1AAD731B11414B304AADE217028C2D68644551BB1762D5400800709F13DB2B28A5203F0634ECFF934DF3FF920896D26FDF4D4EF9808F835DACD59BB5C44ECE1BD80034437786334910F23F208309943A3189EC42115A05CC2EC8C779F6FD9621AFD581423C2A6AD702A5A9AB15D632D9071D2E104A551218F65A44AA075B02DF27077A91C91FC1A19DDBBF4F793513AE1CFA323E72B6A01FD84FE50A27D2C3F02AED8AEBFF2D1FDCB1A16108D5655BB77C8B1D982CDCF19F82ACEC7EFD6921ECD285CBB2E45C0DE0D585A8C932943BC21160F34D7BFB6CA14CB0DBBBC9F2775ACD252E5B1279CAB1A4119B816F79BF0E46BC648D2E0FA569AB23B10C2D58DDE59C0494A9166EB882D66F6CBDB186A611F4C668F6C964453D5AA9567C48DEDEBAA84D295E46B1CB7C60462C1A9606521664F49E4DAEFAEE15BCCA53CF8FB9A16A38449F000D597072607466C4D7A2144DC520451DAAFB2CEFE1BEBE13B873409B1ED34E995E34BE5C345D408A421CBE8789D267504C923F8AD9EFABD6729FD28C0AAF9D34219C9E9E03D604335CC3224655CCB4E4DA0B60044C10E25584D6F1C434BBCDDDC2F98B2FD6D18640140972FB1D00C1F29929DFEF2822E000D6334E80CE73F453E05A13A80AECA16754A85AF59869635CC9C8805543557DD7D5081ED8C5DC0D71FB935CF8D2896915B406055B349811677F5370F1DD9B179E88DA3D6D43CC3D83220F3C79DE3817A070879A0BBBD5B0500E87EC15A2974C38997A4EAAC9967EE2DE66FDEF9CA9D340AFC5D12AA0A3287D8C9DEE1DFE957346EA23E40DB7625E8584F2F2FB610DBCCF1244646E31ED89EC62CE8FD792EA52DF83879925205F13D79CFD590C291659047811D3F97F9D1164F6087CF5A53EE97C1D7237885ACAFF30A657127F6480CF0980DA55B5FBD5E70F7F4C621F02025B1CDDAF1DCAE5BB6A60E046AEDBFD07F9B45C833039DF8F8E5FBAF5F8F1C1D7C9A3312298B557D49423C814F58D8759B53BDCCF4C34B72BD105302D23A1DC342FEC033871BB3C049826790373BA6DD72CF0EE7FACD730E801B47863D7744DC7E5EB38833134CE433611F333CB89C8392689A2CFA95792237FCE981F4C03AE35D6D8739091A0653521F3CC03B4CFAC824B6D2FF13C91C754758827ABBC642053F293F79FB04542A76DD0A65365B0AEC5B4D74D0E73E57A6CC8B4E29200A3115886185BCD42AB969D392CE9375BBBEA8FBA59AC8C4332682ED331F23BC1EAA9835318B9DD58CAD9C34A73B921EF8CEE4C33639490BDA62E12717D553745463124D5D8D71EFCE17F73E5C8F01374DBC88D5E54FEFB9D9D26070DFB675E01BE95C83D82313AFEB303F82E9AC49408D5D92B6B435570A809E0C286BFB7C18215C719D3E24406C067F90F3C20CEECFF1571781D6355A48A46235C31720631F9C8E30EB9DA0C82F7F9E9F4C58DECF6C5B3A0B1D940747F27AC0478A9B6C1360A5CAD9DBAFF568BF06C5084521EC5182CF156C57F85DF79D98AFA0F3385F01A5BD1863CF836D132DEAB0F1D0DE0BC55B66040CDF41866436C9C4459FC1921ED90D3D07965CF48AF319BAEB13F0900337D77624BF0EEF80BC93DA74599CB74AA4F921AA1AD522187AFBC3135B69866C26B7F197E791D2873C7C520CC3D8B9DD248BCCA4082FC1AA98F2E851A814D4C39FDADAF5F7FADEBC2E6CEBD684C86D82AEA07B6237E320B75E873B763E1D5D36DBEBDA522B361A2705B2CDF78BA8C5019D2DF67C41EF22A872D71CFD91F437FBA0D89FDDA36E0EBF588EBABDED491FCA8C5D0AC5F6E14FCD7D6B132CB831D1EFAE21B51BA867589AFADAE45D77054C0EED8025A4D53B04282FEC01E5D23B148C12EEDB3A5972381987BFBDCC44B0A00B35A33A546F9B05E6D77891C6FB299185017653D5673A9738666D596C83224BEE68DB80BD3519764FB0B3BA7117F17EAC1CF2F7DD9A145DA4EFC006A5779E7D66E69F9958B3D16E10671C1A9D2EF491F2544FCA21688308DFF9F5DF029CBC75ED44F0F8D2ECFAC218C498D4C0638B97F8D514B9FCC2F3ED943595F489F564C34C2AAE9072419983A15389612328648ECE830010293A281CDDF9AAD3688B75DF17B10D8836EEC5BABED4918C4E325322C91BDE46655630F45F33D88D224BC3B6C3040C86076E82C1915EDD39A00C8D38EB064D3A50E410E5A35A8415DDB0C7C942DE119059CC1ACF2A375AD3549F3C6453F1CDFB8F491512865EE8FB5A04AF38DB4F772136954FE156C98C81450396653980096676364F53617CF6740631C6D80724187EBDAFB593B48F9643A748DCAABB7E8E247CA1AB65540FEFAA6FADCB31AFEED56E7AC7B4CCA250174CA4C37F7A457171FF7BFDC2C0F4A76F159157D46DAF95C7792F5CDC668175F857121A405B595338FB04F8ECE42FE7BC5B0AFA27380AD56FA7E168B9179F560F08BE04E6F1B1F09C90FC8A94A1C6D70E7A37294D16D11D73F4BE278A99057D349D6E9F0438F037A06AE3956E3EC8B33C8CBB04CAD6DE4D8FAFBDC37F192A3EE01A10A4C499F7BC6ABDFC383EACDFA09C5451BD99A21A79E2041330C8936D17FBB8BE322DD81358AB56D858EFF712E3626319C25235CBC357050022CAC0A6968CF5FB29E9"""), +f91692cbc904c6920af9eff6f57b6134b45bda6ebe9ae873a39c1e0f4330b9bf72955189bbc843cd72a944b95833371e4c06bf3eb2a665b4da4df5b987edcdbd5ab0e7c5823abf0bb6bff471837b8a002bd65bf7fcd76328e6fe6f15e57a8ec933a72cc3ed112ee597fdfac91601e2e58582dc4b609080ba634851b25358d0c9754350281637262521374777556415104864154860206041352465214453553137345236775358075282056885647303768587045030113278731814115881114551057578670817173873534401000711068401828428263081481017277750831465187625833523810016354580868548401441857264083372314878161522270727064333711682546124068264412643840758358838408447627025338300737308371266614001014336245214783358451307745761748303240644786363764736471825520567742255620673034736885603143848540366770518635837224344520418782013854701432613146461232406724061145508623762757104474481846413463435761547477850512744612861336161462154873852416844183351672874258434175215466573313077127617803725473868377265620842720484140613811225841166435350043412651265702675883751576272877822642382142060654556010885518346603814832385350857032673022330504364602345802637766037480027500017672070832862507221411804200675641531481158012220062173320173332478120312762320104164307572211150304777112577368026515022475227221526237672850742604350673830034371436706872072077285850737337730722006562010420468188176586122488432407536587767541380746858122020430172573028068160420648031447532653223555442726570477084433678280835588627680013544120740664444462067616224381176624820425675553845610766215101372521016340175780778380183351722838167847841251851220785205763271604276632836107100703635177680045501506353524230801541453041757868356061560200675564087263218478015205085086217587120816787626038643588882256045332002685650850864406716310262225785367023646170404536861170031214215780548215656682163386848637204727003614771133743560622307402732767066875005724512425272665757480306650470488674004187536675155577445440765742464370661551864815504156136385586564574816703676147564638005517426348048822375856871184345217602738766260417585746271507507570510040056317530803348186642144653053831678540337242413885416064200831201636480323423582817278526413532750432252553652348063287644833408001231444005103050185162038400434420347056323560663011208233834176232267471065573612368558534828568744114127618310560854752054526264330215157680613584083161688058026515337171512715422432583342201257422527403383585446750778640127544781836365130507331711865536268214184662407615508115011054020552746102778440301043766846753320370386223010231318077850584875767675687354456847801617844783652736474218216364370170532852111846533242685183301345366137533712315337353808163275816037073475315320481278357032512385723425657218052577281508084872030258232370206340126045035642787353202504281812581273174383414764882523037835526007680523372518155181435704877226072110817710451470716262037413701434382786533247683254721230801265816050461107728147240545711084436157023770440121161026812170048186872204082147300617864005286020058133765464066235461034572838713356310701101481833843686614643073413362213303431440568171734005681464884814c96a6419af7dd18e6a547708560dea1bb476c511c946ef5f593f69649f9ab3123a5ff302107bb4367f068e2f66ef0cc9a16a69a10c91e003811c76aec82791918fb00f736573bda22f517252c72da1f973386e41509e46131701e690a9717053661d4c1ce3dfac2d14427f63bf6f9c53cc3d946a83ca34e09242abe5fffb63781bd21ab2ce57dd687f3f77e1edfacab5014be6c6d742e7e91792b489e8cdd932ce6777cd412729be11248dbc8c31a6f13e430ad1faf5f0d99c19e5e5bd26827f2d4bbf4b7a5ca2fd4026507b81828d84a56ec69485d011bce465b461262ae6aada92a67745b696371145acb33cac858c4b48039d6fb1ced29e3bf963b4530737eadfc1e7d9ece7d24f442f6e0f2e47576def5008cd01e85128e211fc27aa80c558a0bddae7cdfa6f14a9de7c68ee5d611d9527ef9e3feafac55f11e748e125d2fbcad6373338a579ecb332b99095bbab9b2efb3b4da9fad20b48ddbcae17cc05e530c5f8910cca285a23eab49db9b9a052af08307a634b3b8e38144800b32260e0f33ab2fb0ace0f4325b9f091cf99c80de5cf88d62249b68596c5cee719e34cac3bcb25f3f1872d8c358c2f93639c5bbaab0d41f75ed11cf1b98d373c855cbd254c2b3487dd779ba6f28f8977fe1d470531d5efb392bf3ccaefb1c33f5ca462465d79b32aa2ffd9c98bb455b3b306ca41054435b727fda48fce34b31f81fcae6c07296ef8a4a5acf37ccc14384f0d31d21d31d7131827cd0a16e112c7572e291c67bf1900c647b3c1b5872110b9c411b15f7acea2a7aecb97a671e4308cb77227c92333d2d24a0db6945bbbd13c86cbedf46906cf41878f0c3d1e1b304aa9a3cb36549d6fb1c7559704d76bcab57b2b06d4a52e92e1c3cdfd200423d33722671279f9698f23dc56139258c02cf9f44d5c7d9ffa67b0060911084a464485280428481ce1ce470d96fb8d336b9a4d548140607c37f2d1bd3f4645a96519e50be01d3912471254034be81b9b627a3c8f60c70edd394776a7b9506f7886a1f76472674c5c93221babdb60100a379db220963338221c6f811e47229d1116c1ca211131500ba2dc0973c16153e28180f03721f46e2a58bcd521bff6967612bbd5b70f6039e5849534a3789fb5d80d498f91a7db68ceefb7ec802be752c3c4519968024eaea470e33723376dcd7d1cf0cdf67363b805c65f366d5b1d8e967f86347c16bc3fc70b7222de5b5593f65f9b99d8ad8ac8f5a25630d4202c59a8029f240747d2ab784d3a8d20182e0063b8b8ec64217a05abe4960b265c72a75052dbe5e4bf24dbb5db6e7a0ba448b3c8da5797f15fec696dd82f0a2a9eb867d1a65d95f3220a64226ab0148cd67fd6ffc95063cdf7207e015487dcce5dbbb841de6f2d3cbe3da332ad75d8a7b6982e5cfd28aa7cc64947050dc40ddcde3f77f304a7d5342cc332724e19ebf36d083da2289d4536b47bcdaa31dda127dbd90c41868cc81ac638f116f9cbf5fbfc787a1c1f7835d7efd5933ca85965f419c16f3f4d5a618c6af610055667224119f9f869aa618ab5e2fa10e92cacb53c9b4abdd62dc1bd82e8854fa7469b7f4621245ca3c7f97067d40ace3f7e48a3bd6f1006d89047f3e4ca07848b72ff50d3b1de761e8381274f25af3ac755c3d29c1bccdf810933ea9fac28c596928014f07d654c786e61bddeb97bd654a36cc757700f988d3a27b023c889489bbd1c70ad863aa7a8cdc7adf720940d57f24c52c6c83821bb84589a7fc30b52f954da9d69d9e41b046dd3e8b37b4b6e2376aa0e7f715212dad754bbeb64a0a2a0160584f18646ab4c2b19bf1d3c3c383d7b6efaca49e5101ccaa64667e1bc29af611fc94aff9da7334984431e0e4397a355d1c8f9fe76635492aa891b90531b7ee9f5ebf87cddcda8b060d09cf85eb4e7859b93c7c56af470b908a3b31462ca08bdf66ad9e28a7b3e438d967df3c7c844a6da2d57a61fe85adf971acef4bb824ac9a4a9bbb8206e5ead3d96f539325647114585aefe1752e405805b987650ef7fd2ec8aa0069f5dd64e9a3541d43dfe09c96a83bab1c9ca6799cd4789d082d620b4898212288a7a92792803d204c6b77042634f2daec62bfc7b282cfbc80494fa2bce24493f0795d0ca8bb21d79fd5d1e4a53fd695fb8def7786aab4d8a6e6b5a1c48ba6461134ce550f1ffb0e0fe236284789dd3c10e63a748b6b9966518f641c5ad3346c1a6be1437dd06232111fa2045ba2a7521c6662b9aed1397509e7dd10e3343d9d439843af2f40fd3a9b6ffc8dcbbe2f89e3e718e83043fe84e0847dd9276bb20800ac07a6a0ce94e9c2735cdaa5dfc5e626f25b902ade09a1bab18509d1b0e075286272fd99e469a525523f1ef103b71b9870380324c64f4ecd0e1b40f6c2142c49cac8629941cf68318440ccc15933954ce61e48006b9aaa466b3c69a8cfe8519a21aad7a9c04e6e3571878ac468b72f09ba30446d95cc7ada23d7413061224ce2ed10b9a626e3014710444e13101cb5b2eb3e208ca67a755b7f0bc166b53bfdb7b08476c42e8f8123d295cc07d5a7b74df3fcdc1447ec23a5f1d7ab98a965caa69e466e80826696c1f46e7be9cef62f7d82d448bc5a5fdc6f0b3e355db9230b17ef9950356af47ff1f24813f8fc9b667d375b7897d2a7dc0d84c6c7ebb82e3655f1e84ca5f5472d230ed0e2d1ba71bb99af8092fa7c6d4ea037913cc4b265d29bf9d2a2cf9593ebb6448f6c43501da30dcb7cde661a59c9e45bd694f30d3549814f52f3e01733102f48bbaf0f48a3684b37293126abba486d0dfdf8c075262bfa6d9f095dea8ee9328a5bdc0db76498d6ca91d6314f1e3c9ca11018c551785edd5d90bb6e9659f117f62854fc62a0c707c25a42f5be89aff9daa67f0fa026df50548e8c2086d919da914b21f1f907d146e72a286863cae693f1d2022344e67acd3d70357957dfb3e90af2f829427043b41a3b52b1fc34e0d80ce1a47dd5b12877326437f9628eb25386c51c59d0bde81862035b185dbaf7c574ad4abc0d50e86ec3e23c6f51f9c871f2f55db0c4a6fb9a0756b61f86bc3b2f0c9604bbe4a495abc83bb1a07ce7e9d9d60546b53523328104b66fab69db63cd6ef2f44e405276b45dec335e1762aca37f3e348a4c4a348442453cde7ef103bba64269e0152f6e292fc54bd7a84d015e809def97deefd6f24042d5be6bd1ef4b105abbf567ca98ebc8a2a93d0e1fdb5c1027f639fefdbb34a062d83f6b9155171f0ee7133782b6f742071cd2b727563b7d6114360f9c1d5f208b34ccea4a9b4762192010f698c2f160828ce9fff3aced38db4bb47985cdffd3f089128a789696386f07336728380133767e1955595375caefdb9d3c6f13d427f2a61b6a0ad529791f095f22c77c1937cee13b419ce545a82dd1d7f5a79370a2bff47ad9cf0b8da35586da8333ef7658ae73f284e147f78f98eb0f67fab6f588b446c43204edbb0d01344c50bd496c5223318c7dbad4e24ed7dc51e559488e8df5b071fec03b"""), TestUtils.hexDecode(""" DBB70175E063054DDA24BCFCAF671F820D674F1D09CA173D4A1440AAF50F1FC8FADC1810F390286AC101D60507DD285275C6F97C0D2B2CF3C7F50609CEC64EB029C3DAD8B9954807E35D4836BEDF32501D0E7143BF488CD5B4D1A53C980BC70A3794E4392E4560E609B9C49900E1C56D319E1495D085440DFD081D1A7C52C0A8F64917834C64EF32A441C9045689DDD2EC218F58B3BD534F18309E1D780528D3BD1B23DDB3B18FC1F7C85324D45C3E9B25961FA5257EC31927CA35DB25E6FAF7669D60952502680BC7B5D777D77B194D0CC40372FC8F711EB048E01BBD5676CE3F2A9FEEAA4B5F29081C34969C746208E6F2329CB53A22058C0AE0852B7127FC4C74EB3A8300403F60B8AD1F95FD2991CE0C8CE452C2432B6422EFEA8AC0E1B53BC994C606301473D7855EF86687287BF56B450D2762C5E03AF26A987317C4BFB013A6BD791EFD141AB34718A37D1DCFBB63014F7F92C9E2870DE503452E271E9D02768357E3DEF6BAC5A0F0444DEE1FF5AFC79B3562C12696FEA15815B7D9BAA38C66919D137F82FE36B140B960E02966FABA1EE9CBAA04941396D665DD2C6B0559502577541AB0CEB066E066553A2DD407354123DF14F4B1DDE6B8C34E3264161796F48DB5319B3CDDFDFDBF5CE17BCB5924984143839B4EDDDAA8F0568ECCAD253C48D00687F9A07785A67B62D28B86D70E511AE08A525F66FB15AFD112C184785F91E76852DAAA3E78CB96E20249F38979031712440DB723B022E1323818431B897DACC51400DB25635EEE41761089DC47E8EA56DD0DF60B56FC682D000E9D660D0CF38C263B716359F41F3B190D201950E140D67F50287C09D2008664341A829A074F9629DABD88BE69A6058900DE5782CC621A91376E5CA31C66E3C430CD00FAA83BF765A2E6B2FCD20EEEACCB996FB5C4B63235142BD5FFB4390F8CB95BCD5853D0226F931C38FE972FBD0D6E10DC2CF29D1FFD2653CACBAB8B81DBE44A2B8F1C5DBDA7C56252E4B35888DFF7808B3514F4D7E5EAE9B51078E8D2E600EC57200FB48EF946F021CA8209E7DC6443B37D7281C73C6A3B43AA570398E62CD5ED9A34ED23AAFEFDB7DB3141202D940C1411CEFFBCED878C0D325E8CF7FDCC520CA3377BE97855827D2E6F4EC8786EA1374E006539387924161D65782C7B2C262AF9BA8FCFCB5B1477083836129DA973AB8B082324F74BC6320646448DCC8AB56582EC72EB192D3F72255D85FFAC2B5C62F245B73191A9176BA5A9FC0ACD3AD48D37E23EFA0C65F0423AB5CD0EB76BDC035112C7A118ED47C0E67E510A6F7A28F26C3D6A882EAE74BAE6CF1FD969FEEAF6B36C85F62D40CAA26B6CA98120D612598F360CA2628F6FD608F4E1E290B32C90FF71E181D4B72978DFCD189D857DAFC7B2AF8C958EEA6894ED59AD56B9AA6F83092EFECF9EC4091BCC9B8CCA245C30B54B9B8DFF3636BEFD417F46DDD2F6136B983CFAB532FB623FAFC3CC4CE8A91434377F4DCD1607BF04E431"""), TestUtils.hexDecode(""" -B6662CABCD010DBE21D9C8E04A2857E7C78EF2AE1D5D583D2E292257F5CF7ADFDA5AE6574FC79E58F254DE8E41D988D2EB72FFD336856AE6A0FA1BB06CB2A8A1BB588F1201B31E9E62996097FC84D41DB9A57112F3F02B2EBB572602F054551D313172B84E90E907EA6E293F1FF7446C5814CDFE2425D61F3DAD02BCC6262F816C73B87F68D2D4BC0EF41D3C659D9FCA7AE921547E442B3D0BB2620208D12932CA6F3232E98BFC2896B8FBBAA7524FAB1236298C6F743146C758AE32109CA3A1F77F96D18D7A87B608DEA8D1C83F705989D50EFC5BC2228D61C6533663B1FCE85669D0A02334831DE3F2A770D2077D4C79A5928B21596B464D7EF0ADFD463491458B1F151B2EB5A6BF87D5CD39C5CA162CB8B111336417910448CD63E074282E51E3DFF91342FEF98BFF2E40C055B57FB2BAEF5ABD42085AFD65E14B3C60A00985F3B4758C0DA6B43A8D54DFFEDC07A298F4CE70BFFB27967EC5D59B91A3F8DC79B9846AA5255B3199FA422694B9C5E6F1A1C8B494D1B2D6F093E6CEE2768B1195615DD350E9072E736911B67FC83BD6ADFA60F2DC9BAB479CC0BEB914A0E9F064ADCE261909A25DF629CD56BD3CBF8AB8107AF1E3DE33D772A4BD8100F83C91934FAAB8776CAD460CE912EE635672D3CD3B14210250BC3E742D34448F8EC576F502276549BFE3D46763875F701BCB01975FEE50157F16A652524BFA5BF6F69EF32AADC43430C7711029C88EACD391423693513127C0411E08D7B4952AD5075A09D1F14287E94B885A43A88EB3D602FD122CC1507EA88ACCBEAA3E939305C0092834F30D486FFF47D373A68B55A01934B2254FC911D122343BDAB0F2AB2278EC4CDD7D19565CFC62CC3D5937C12D313D77A5BA20A6708A43BD11480FB1C7598A55EE706E9AC6BAD2641A640B3B0DB06171E3E9CF2E4FFF16AC1719DD97CE3C21564C2410E9B03CC9792661C39677FA20757F53B859655052B6DC8923A172E1801FD2A5B309CE97B3DF50031130AB05C9A0A7E6985471BA8A92698AAB7F4CD35976AB007B4A43B8D51042514621CE3B8AE764E997C18C9E62E68C4340B03DC4C63C0C7472BAD4EE36FF470E1DB5F2CB6F136B51692A1836AE0B5A00CCBB7B81450BC51605EF4AB1717438DDB7C5F1543A59BBDB7A1C13980C227DC0A412B486481A24BBEEDCB379B1979EA058ADE841258A372AD0A25E5C0D11B87585119282E9EB471D1E944A07859B43A65396A3252F9DBDA5C5C5E52C38529EC4B9ABDBB936CD7146AA90A6E1B35864516CE15123C030853FFFCAC8E65FB30696A0D64C170A6D60918DB28B8DC763A7F31BF7F55D31C6C42BA2187E07BF8B25595435BCFF169EA715F31EB11DA382D6D1D1C20B747EE14F69C8F9D27C353EC651BE930C05AD02502AA296F01B11DFA4EAB1AB6B9E99A59561E8FDAC25DDB432890F9E383F54CD7FC530AAB05BC61500C5738B058F2DF8D789F51922A66B015BDA4420051C1E537390FC4F6C3F790329C963D907B67229CD75641F8B00D2AADE441D47763682686928AB0AF9D94736DA210B4D74259442D623058D3E8DC3B61731A9A3662182A47848B8CC7A8127826AAC45D2C03BE0B1D2697D7B2F85A774F891EB45AD17C58F532074AE1B70C3689401575C33D57CC2EC0C00B643109834D5A57D1B546DE93EBDCEBAD143D5C6AD7498335B45AAFF1AE6EEB4EEA739642A8F68E703E827DDA7EAF6FB674CE8638F50DBE7E4F1B2AA8B3300BAD6F802E3F0358F0BA8C1881104EAA8B4C9887B065EA7B0CDA8EF2354E2EC5B111750827CEA337DBC55FC88C6470FF87A8B7B50BAC4BC7CC5BBAAEDDC6BD1E9F22663602811AF94F49021C86F383E1C9E64C465D78F1C42427894012FDFBCF90916A3D38AE0095EAE52FD539FF857515EA396280099CB36167520B1EEA47AB0B1EBE680506ACD029B4DE61C7389500A5906BC56C30919BD753BABF4E6F822885F13476F1DEF4BD444C39CDF1AFA28558BA48A6F99CD0F065A18DA8281D94656D94736809EC626BCFFDDD1A777A1FA67C642D08FC30461AD69C1332FAB84B400161C3802F19E89C1E962D698C1AB1C8D61AC99987E3E7AC28A8FD42696928712A9E367CE28F48CC9D17D69463A81670E2AE088E0BE21E0A89EA9ABF1D1986DEDA702919A2C9C1CD6851B3356908FA62EC2DAC2817D5C6C874B8F6D5F92FE7617C9CC2C3C221AA2434E156FBFFE8B7C27646B93C866E2FCC1A32D2BFD859B432CC0EB4745B1145F482D03A2B22BD026BC6B37BC802D8621906DDE752AD414615296A403F9F1931EA80BD8B3928F25396166562E62C06B946853C17E30C93F67577B35E81E456952A4086907BB6049906D9E2F9D1927D0055AB0CBE11C0D82D899269D145255EC8F2DDA1FE481E3B15DE0A719391088C1647F330DA8AC990FF06CE0C957F8482C88127B2B82F68D115FFE880BBBE9D4C6DD2D9C872DD4B91A4B52C217848E38805B92507C9899484973EAC5A47C78A53A58E4219B86818DD90F5483CBBDA8B56E3A12739B7B287F29DB9ED987CE4E93079B577AB4FC421885E7951098B1B036AB3A93CD7F2FD65B75EFCB7007E8378D2BD18C13AF5CD6F8B0E5443A87649C2463BEDE2951FB7A963497668993A9ADB3690B9969596DA62549F0E5B597D3BCADA83E66F565E44A0C0B88DB3EFD076DD011141D8FE0348889F0455E3E1AD8FA47F5C8F28005C63FA4562C88AE0405A95069BCF1085909198826EEE7C86D379AAF244A7BACCE44F93D1611142421DB3C82860736016C36C89A3B6FC87509696C708C0DD2A1161F6748EA33D1989ED65D1DDB8878EF158BF1C1973060C00BC132E2407D1A4696C6CE911DD9BB4B231C961B7FB427E8577CB28960FB519C9F977B627B8A59400E72FBC12B1A207CFEF4C2D34592E0D2267D30BCA0AEA3E22C8B7A308B02652E726B2CA97179AD96C8165FE64F230E87923086431D55D1FE4208A987C61E9EA8F38CB56B7DC086A192FEEFA7AA0FE2B3975296B1EBF6604DA709B8A7169A3C610061A4E85EB42AE122A162275256DE631A54E7EC4E55DCFC3FC58FD0273333CD29731AA0E18FE0CEED334427EA9220F5E6401C68ED8B0A0BA69033CF6B9F1960DEF6BF9E5978AA7C1FD480AB685E44227A4B64651DA47AE3B27EB6029D59B2DFD1118A64A218FF7DA3779A1C0227A9E26F92DF3A7EE73382A807B71ECE108E5E46075981A2FF5152BBAE895C9B0CC66D86850DA85FA737E2F1AB80F8C2741190000793DBDF6C54482514704D09055F65F1730B05925CD1773D57849EEA88DE4A3DB8BBAF341BCAC5CCD3B56FE163249334861DF702729EF012659B8AAEE1E8D4E785767C3CB64D1319E23533164D6E789DF1501EB9A6FD7F0F14DCAB73875D4F2848EBA3329D6FD40F60C626406BAABB2B81C95DDB127D20F0FCA2422F74DC6BC3AA5256F3F9F5C80B81D1CE07D62712CA54662205B58E56B3E1684D69323B4E73D6C4F29D9F70F68D5FCC3D89965E5A1702523CCCBC08B3F6427A616C6DDE12C374643F3C7E97CF9483036835D4F928D00A673C6C22F16BE20AEA0E4DFDF88DD4172D4DA21D4200E3DAF7B3D7FDAA5659180BBB6CDA4AD79A9FCA6D5D2881826B40030314EEA07CD45539BD0BA04525DC79326B5AD649B343C23F2887226706D66899881B7CCB4CD46BAEB41E9D047E87AB8EDBE95E02672AFBEA25976319BF35C13C2C1BD042D3DFA527E69DE13C84DBE8410DDA13F38B3FAEB479ECA09F876095E5761ACF0144DD946D2DEB7BB70534E85BD2E23E1863DF685C7E873E9CE29930F3C2A8F78D77F16D4D34A91F1060B6F275DC9C57BFB49A6E5C547B9CA023E418BCAF73D8BAF604E91F5AE69F8CE08B36EC91CC920296577A83C32B07B56776E5311523C346D9590D57F036187AC1CAAB62A4ACABF360D6C4E49517E30726F26126AB405381E02F4C7CF794F8979D54E87B6FB082A8B8A0B1D0A26090A16F09E94D0CDD02886C6545F917D905A7EBDDD1EFA8E5C7763A32DECAA87ED7229C774DC4287B065D04218695B3142DB41AE748912797DDF08A4F8495334E15094B51B21734CAED59D5D2E6635DE144897575B5DD00D51F98715C220CEF67CB08FFA84AE2EB8491303D41F5EE405560930F93EF7A5D3420D203629AE0FEA310855EE7908C1346672C669025E49BA520C471FF6DF9D34FE3960A5A3957E5A007A636A457688AFECB68572B0F55EB90435578E1C75A30A18A17018A7B753E479C677995AD162E7D04AF4D4743A186031B37D9FE4FE23D274DE278FA30BC2C9EF5A5F1DBB431DDD23D8D908722350C3136D26382087BC7399C1CAA1ED4A5508AA0CD3FCD89A45119EAADB689B1D94B5F58DA23A650D52E5C77B739125E660D9836647D7371BC635690D77CF63500085A2FAE7C15ADA7654208FC88629307A2DF3916262523A61C177A7E1F8FBA729B6BCD401F8033302F83DCEF604B4C3F9A5F389C354AA4B938DD145B54A00994FCE1ECEAD40F8D819F232EFCC05FB812A764486D21295E56C4627BCD1F3EEE644DA4E32A8EA4EC4FD405B74BF49A238411AC85E15E4B6755E2EA566F2C38E858641B3486927C6428CB030D1E394A4D4F5B6B79BBF42343A74383A5C3F8FD2373C3FB2D31626ED8DE1C2B31637386CA00000000000000000000000000000000000C0F15191F26""") +5c796ec117395c38a9d7fa1a02d81e3b51522aebf68f3fff55cbf7d584ec75e547d413562c4c87f28f57433cdbe7c96644619b9f03d119c7f87f0a970a46075cb8c29c506f67007470bb4843af6d3dd1c91bb3c2c62443eb18a69e675e3711a08dabee5cc1a03d35a1399755566dd2f07084a9039c7710ab57b380712b39cd6f3cd2098225785665bbb94f3761d5a8d431cebcb533cbee5afeba6cc877fbb168009b3f05f9829606055e71638b50f4c6a41b0b226134391ae0efae4cb1d2e31c782b55035cd9e2d0bb53fd72749de022537ad8f8ec49a297f9bc81d1ee0f5e6b96470d30d6b78f48266eea5d3d4805028f90abbe90232fea807b50323e722a42fb455f02cd2c6f5d932b9bc606f9509fe2b1c133eb12de12db0206d78b49154c34adfe204fbf5469a0a50301be999015c5798c567729b60b2690ed93db0eac4021d38665a3a7db7b5ad55d94b8cdc9171a00ffa3ddbea750e83e495f7db132fc253c82b6b901bcd00fe68f0277988a1b0b2cd1d051d10ee189cf971f79ab6d1bb641b1f3b160b4a4d095144d1f9ce0dbadbdf6955622a8b300c69ae67dec7f1b777f0266e71413d57b454cea0dcd8cf3c32b9bbccc36e1eaeb17c87734afde3feec5432a18ab9a7c6a1fb30e2e84af2c367b4f47529bf4e0782a26d41520df8ac3cad44d4e792af7f427c75221e4a5230e282bf938a6072574e23f4cd35aa49758829d521360db34cadf94f9ba90d5139179f877723150d4d6f53a5300ea3e26392399adb258bc8075cd19517cb70ed48ba9c61e5e5f3d245d45f44f5e6e033334dee3a95bff8dbad0a1f8ecedb431cd52530d7c2d06ebc8f1b80e5e30e746f9b3b3fc192e359119170e2216081dd908d0a5b03670cef41420585653521ffbdfa58957d06d7a0ed23088a5835690df344473f44b6213fa10832539197afbb410556b8046e06d814c2702ce1c50fd5677de3015575e42b78aea720270aa303e3a6539bf343c52ff933aa238770e7fda2d0d0702c1c7a829e798b0677c1044a7e4af1df817c4167909c158074a9933f364a1800e76234751e7463c78255c3d5189c2a3cce7c2e55dc55fe97131cd4255d92b3f9f5c888029d4b92ff3a544e25b80ac12e73c9a65fcf0b755ffd0a497c6113897ee8bfcff0dc8c9bd583af6fdb71523be596bf0753b25b47766d5be895dcfb63d7c7d9f6143efc509629d310dfff428a1d5328b5307edb41822695f56a09ff2202567ae1b80318f827e0bc29c5df5e4cb075f1d7c1cf2df62dc258544e3dea90239a1d997e52e568632e259def0bcdcfc6f9306c76558dbb30a880d41fcb4f99988e6a9186296e7a5a31c7b910fb2624a0400bbdc6fe0657865a6537131f0b0dd2f56e2d6e2201a843bef51916226577e6bb0e891247f93b5bc36c49fb37e458d363762c12b4b95ba75ac1b38f177fca6515c240c40007eeecea8dbef687a77d3c09f9b5bc5450231ee83294e5a8d0fa79430fc2e701ab39d3bd891e73a695ac6559d8a8b4dc4a6ceb7472ad032036e4aeaff3154099a6f2e8297c6e4bf121631b545b472ab316aa0a3e1192874793597e0fa0cf173a78507ea55b2ed0c13fb045a96acd9d9bf8cd5197f968efdd359bc4449458ac42e2efa187190790de076f56445f92a79be0469efa11c98992ec82e3a2ca311d76e282e91665f5659be663a33139e80952b444914fab59910ac08daacb6cfcda1dc75c00077391e2b38ca54c1e056968c4c41fe7201a3c637b37f48be5672828d5f20c06bbc818332f48e0a4c0cda579d4c114d0446896b60392bfb66ec8e4eb5c3e8932259c423025da0611e06b34209f35413be186d98f8494d18eb0b2d56aa47c6d72c5b57e2f68da8ec1039dc565dcd5c5937ce1d358d6c83ded381060647ddb52badec80e92a98dcd4be27a5990c85192e2989dc2553e3606f6e6ef8353202671a1f2dab2d3130946254a686121a26a29ac8553ef5a58d31f9607bf3912fd4340562ff48b38a12b7f4d8ef2e058c9c721467e0787aa0eb2ff53ffab5c2b3c40f52524d8ff1cd0df1edba1dcafcf983a9e8e9840ef269f9648d3ed8e7778e086bcb887c54e49c8848d21002ed58f163a6888b171a945a9269f410b3d541b07f7c83c0e6b80dde9bff6c3f6da1f780f52ce0da11c196c0493b6765bf01aaff22e44f2b538672b4db58a616e2d2a36b1a20a618acb6e7523546e61c8ec4b593407d0ccaa0ca85d2db46a6cf188939ed9583f591499fa436443287fda7e49602dd8677f171b487e4fd6229de805f4693fbc8f27b52f283fb0384a2994755c5a6c0ea99a8be6f6f743d05b75405f9e70d68d4904b258d0f5f3ad0b23d62767d54ec493f15bda17b34c31eb50210788d38ccd4490e0b65ed46e50875da092c35b0100aae8bc387ad595be005bb52ad0f3281ac662305e0a62ec6254c4e091b1fb0552398b9cdcf2c12069b90b6ca5d67ebeb22b6aba91a7ddd85ba31addb18ea61d98429e633e5296eda442264dfd6bafdd3f26c9d6cfa7d8c89f273c4058c7b88ddcf79d7cf5c8bedc4ccd69c4b545a0069906c12c0b5dd5514cc1d45a50173c4f51e0cb89e2e56025539394be823889e0b7cd3b2563f756bb6d95336a22a1f84215915507708fa18e425a6de61a7ac74689bd85bef8aee1a48226a96ac318bb3d8fe95be46eebfda3662e04741f93995e5c30b1b3864feae3b476f341c473d449f3d675c3335617a201e992e9e96d35640d0152587c7edf50ee5542164e12d268c0bdd808ebe067e4891172a4d765650decb3e9baedae4c39834b5b6df1c8252a9b588c30b25167c543f389f4d4db14fd1319161453311572c85bdb5fba5886325b5118b6bdf774c76fce3de923761e22054867a19a06e2f84463a737ee6b4f42cf97e062db911ef8dd2a6cfa15a4698ab96c9e70c7823956665386aab0ae235b485391542ff57967b67274a4a308818ffad47b82051e674ae13ff73a111c5da089500f14c7d05af77d777c612628b157f3a921bf8b0cac0fb426866833ee35a2176653dace88dbd03cbad446bece7c6177373db768d561aba1d86ef2a5680f5d71e2c4e35832e8ca69de760893f3e6dca2e9b39dfbfa2bd4e1f3c2f5ac06e7b07c9c3c85de16244a273385f9014263614cecc9ba3bc1679d8b2721211b7fe7fc96612abc39312d8d05dd530e9e6f00977bdb27b0632eff254f54213213f608177334ef02f79cbcd5062c9b50f9c3ab14a8fb019d0c2b11ed1a5f93d769d3fa14eb3a7e2a96c738d1a3d62dd49a5dcb34ddf6944c066ed1d4c662752fbc961eedf9606c40922c43c543f6c79cc4e91432d652c6ee492679f84ddf1e1e6fb885af725a63168a6c6eac8cb180fc2b71f8d83112b81b168e96e42d3f069b69995c351c6b2bf1344f98c5fdb2f3fc503dd6ccf5cbc9a1bbe111ba2380bcc2392cd3726bba4afe7dc66a103a2defa50516d7d0d5bd058c7361bc6a81379a6c48fe76e81cccab97af3cc2a96d4abd8d5399c8ebbec651320d66019aeee16dd9e126a4f6b16ddea40a36f2ddc9e5d91bf8d5a39cf7069ee917c23770c18c54a5d2ca8f23ca2c9d21f9003b7381c077b7607dd3e3b0c34cb12c77ef08547501085370c6225e45c40069c87161bfb45498397c5d714c86442cb1489accfb34531a14199cf29e0e611f4047f22d40db532956a20c8f5561d9c6120a80507c525dd8584d60f41e999686096454475a2c92bef5880e554a09cda2238323fad2827d9ba6cac319b01d2f89d708a593d660f9c19499328167c5843ff20a17bf0ba26c8418fef3ad764a865f471099708048a624c39bc7ac317badb19226d8c0943e0fb8aeee9789c0ab6e43f932621e89c424da8a6eda10b936218264161433976904836c0c913b5a0f2fcd701ae18ff8309f583f75946a02b930c897aa85ccd239ce2edfc7dac8689b8e678b620cc853e5dc57fea9221f3c5ece3a1484022934d9457b6d3a34b801baf8afa4adf307a8c7b6092168dc5fc35393f772b576345b2f6e1fdd9ccf27452174b8ef6bde9cfb37dfedc43755be905373f54e13a1a40c3757a15bc36aa21657ae4a64a16bbd4463fbaaf69cf4778306876b62abd4305d753da808f0728c3f51f838b640be0c093b732595b153e2615da3c0d5ce5801322689ce85f91767bcaeb81cabc3baeb76deb7154b79528766282bbea6d026687d2f823fc25b97ae523e1eecdcbebf460b447b1a2e677c0215fbae2da1dcd182bcfdc912b94c732b793588ffb0d1e118d02b093a3cffa510d159ccc74ceea63ed881ca79957dda6db1329c22c10a082baf48fd6a2b635b3f1b896e77087734528d0943da51d31b1619e549ee1366e9df05d0a356aae84cf8f3d0c8fd5ab534a3524be784eb0208501f17e3b8f70a52de886bc691db2bcdeb63f7bd739fa3dca52e4d44a7b6b57564f17076104da5169b46d47bfd01d2610a9fe55129e6249956233a911eef491d9c5877e55585f62f1d17a84bebd25738d11d830c2bbc5b55d7fc60894f4db0bfcc6639277d290ebffd8a02e4d0593f65223168240e528822a90d4fa94febfd55e5562fec1f279af1bf7333d5b8b8eabaec3ea262a40586d8ea1e12b3b417789ed00010f333a787d86ced10a233e7385c3d4de1c3450557ea5000000000000000009111721292f""") ), new SigGenTestCase( TestUtils.hexDecode(""" -9BA12496D2759ABB2CE2C3FDB3FB71FCDD7C315B4C7C5AE5C6B4B4F6A97D2335B07CFC9C4B33D9147B6231C6B33CD876DD71889FEAE5C8875128BF0D75F72E380A1C51E6D56CCF1BB2FF2453BB7F09EC9E1FAD76A07CC6A4CD012726CF9309E9EBEC279BA77B159B515A954FEC69758F40EC0C3B3836B661E1FED121F712889B77512258675704133806066748826547111521115868474531585416005713338105507070205662844057632638535166351741357313537883572686500540128261085411603366201318374814306288785181752828400800470585613434710704510035385872517651333585207787188184062530114384673018530063727426246401400773237530844578751387817248277471125878621454431146683341406818333868760704701502761143473707860535758187372162868573323826480416420733630025672348726538053525024423653243546423514553071340770645158747722387267847757250586600731582661356526504140404107264574637750025462020601372686055328846034067308301012344312705314305867783080470360821015418216663460502701754763838654027628220553546644844707313784544085501508364158844217135802560352218345288786203528513537552882486255033112148517000583211241325641064030340235323380524631220275268447538464445758352140612704781828086872330585810217000036008674504425701420181180377803350424765338285178682720218181012520214517830318082227120513518322554881166140214761423438151247072168382748504452500004758363227304767704161305584642720280148873012060716368664714384685145586365736257431288024173772381536807648611435052307322366547752204377446868057638617731102741825234125865523273560843152782032533880776282206451272477621267326281383315581785515642825006261045510323376338070785444022023713881268480640885038174347552814543067652828245641383354501751610445443231755333835224563515134301511513821681374734335016003216522571455880410230421326311811338146248236660357671633348772574361832403770183010531215541634647651601211557845444264232368206771167634647778401370320484608854756652513571656277447284614256054125825545667871576431852286416638036374180758183634577548265761215082800487735370570835434878138206660513012214466631044531375060518448334384743777234256478821032557054374186280115238364375612238562440815877116541472770062087278326687024403300345343640711805831336621255213741538544438567453332843754315440442730654367534363248630360146213140072646271447800025357255281341257570554320245275102060221620818717848621585406508157876043725614243441752316510561605237486301154208628170146326444636374671281028428888054302763653254651680624433732312785052851001186422542016363135628821440082566635447837137437567738250604600438461732334063187876327123582736038000542537210170133043240437625172228545888471831032816233708717083020220534823336673537346268102842456807765246230548276186624233334504072552008188226324457005707040616360473678536233682028686415232708258156535400766767114686043413232745516072208330587043436465427087756584440822673872786114734048782500067420780002787748322508678107138016507217573854055248812267683351608427542745123578836475638204547465316772773558376364227627315732325112263147154784743851852416083411402663045461736077851483201053723540300740062572041704370051846EC468CE48A91039F26B5E7756BFD4A483E0805A91A1A5F54C7AB9507CC918DA35CE125C51BBB93614253ED63D269380A50B1804345C810218E0DF6EEF453AB0CD7BEBDC8AAA364E3C458E6AB8DD9E21BB72B0A499AF42763E3DAF541E0558E5E3A154C4F800CBFBB451CA73A620B3748B04C7D535088254D6267A28291CAA541EBAC426BAEB242E19EED2786BC26A40841229F2934DEF2A73A5C6F3670E681F111A3A1732CDC2813DF8772596A7D6FFD5F717F2EFAFB6BAA793C345FD4ECDA18B9202309C27D00BCCA6E51FDACDD9832A630340DA5CB703F2D68CB1C17EF8242B3F3D60579616E6102B08ED094C1D0E725E2985A0525CCBA21704364E9031E086EF875BEBD0D31A922B91E9B95F6E57985EF2948D9A7638A1C0C76145CDD9577C5585B434A790D6A87809FF6339388938E2283FE1552535DC30C3F073B7C8BC80EF42553D30FBE79BFDE391D9B7F87BD1F809FB671F49F159E4C653654239EB1E94B757E9D81E2809EFD283BD9BDE81A2D316F66BAFEDA9D4A524BB270EE43451434F5F61D33C6DCA6CE3194A3017B5DBA255E905302091D5F341293D20B89F1E5F81D5731014AB1A5EB022609FD6018662EB2EBCF6F3F823DDCB86A5C82B9BBA5741E1909CD60C1AF239FE3B930D0E8786F6ED24A6A8A26E03A05B0BA51AC54F87F845D680A1FA09291405E758712C00B9C0C8D4D698CA82641040521FCB063D5FBE2271965AFC1F4995EF47E4E307D8CF97D9D22A6BFDABCB726132FA7BBF5258226B384B7C06160AF1D0CD8CDAA4F16F68D618F417FD3E78DC8B5611052D2F9E770878D7351D52FA00847A426C9CF845711318FDE114934323D02F2C5F37B9FD93E22BC9433142095BE1D6DE07C7009162F4BBF057466E04DBF98C4DF770A2DB27A5735A4733604247E2C3AA1AF38B4D9D267EFAF31D2A3162391AF0284813D1184217F93221342D28CDF90F85F94D2F66024D1FDDFE6B95774128548611196000DEF8681CDA4555B626CF2D77A2A638AF6FFD0DF73787B955DDF5B9F0A6487C60D09A466D2F97C985CD58E4A8154CDA4CBA831ED2E386854B8EE5523DDE4D0018BD17BF03F02BE38328DE99F9424C01E6F2BCF9DA3C75CCE87558B977F5CE91C9CD3FE49A1DE4A45B162D7C4EBB4204FFDFA5A6AF4CC2DC14B7423DD9C819876E42A75709E72B18689427324ED0621AEFCE11CC766858D46ED7F1783949A8C5618AA1ECDDF332F2B6C92E5EEA5D5E7DC87908547656B65E26D9FB5B2068EA5C39CFC01021CC11C0845A3797541301E6B6C998BFFD7EB03F8B3CD7189635FB13A4E42AC5249F4398CF221C7DBE68863A8E05D3FEE54B905A64A4CB6AD5B9856081AA953D2F51C049E183C47EEAAE60F980B29680675867405F605B5FE8E13C0D3C5955F801F941CEF618F62AC6739A92A818A0F6F2B1D8E259040D190F371577AFB2289D13389579452FD1027E4CDD2BAD5F78A4E6ED722A5984665FEE58FC209AA232B38F45392970F89ECFBC0690785D87A7E54E5DF49EBD9175F530FE091624B281AB66535197122765DF0378ED4814A3A4FD60490C82517C98631C51BF9C4F0AF9F597BCFCC1C25866D2E9038D02CE583AF9D564EC7A7AC4AB7ABEA8F86269B6DA84050070CFCA06862E03039AFABEDE496FFF556031F083255CD1C46F3F94119FDB8414A6E80CFF99EAF2C5BDE4794C119D5F4A8DEB2936C2C4E249E3DBA13C0D938322A91E860D4C4D8C17AB6DE6271ABC5E4F99CE6ED0D728585A985068A0A388A51759CEA3B29CAA0FEEC27A2DB3A252AB4A18E8E477004F5522D308329197229382969DE75AA3BB3C775AB0F74FCE5E1051DCD2C2624A8EBF1F447F7417BA2B5E85EA0CE6678AE6FE0B113CAF257C7BB73D1A5D91AC0529CF7DE38792CA229D1CC519368CA4DB063FA95031F4EB0A5A647E092F59CF39C9A255957DE2EE92AE1FCC4D041DAE51BB04C6B8E5BC52CD73F31AC745DD79F27908E054A2E3906A84113FD7FD4E764AB0F21C97617A82197D1A4EF7E73408B667FF71138BA727CC26A400E5E5BBCA922B104D588640484EE4867EDBCCBC45AFEA42AFCF277A63CE6661B57B00ACC1C2F76D8C203FF2123F9079EAED0B0602BB1788595A9198568006166C61806B5D6ED03761C874E9788FBF180880F9853EEBFE2A933AFA6BE7CBE917C5919F9F17777F55A29E7CCA1455E38EBBBEDC83BB062E914F4A4A2CF1E7E32362FE97831FF33926F1CD9E99C80AAA205AC365173D5DD94B8D8F3922FB192F277A09BB7A92A5166C2CDF7F18E7DE7189ED838F7850B306576D10FF014774588865CB5EE3B161E54529B8E45B2FA435E36846E80D46CEE9BA5413BA950A448662FCC5A8BC8E42AD3A75326747A9C02A6A6C676266B580CA91AA4E9F892EC00EA64065D38063881024F5A898451623FEB3746B2108A24096F2290F98C9DAF9A4DF9746EFD5B5D9FADBC67C9C06F920E5042050CDD3A1B500764E7936124B4C742677300DAB0B2C56BA69B7CECA73A6F97C961AF46648381064764F48A5D16CFC82D9766A35171CCAE17F18C82B81BF91847766FA1C361312B0E532092F9CBEEC51A55E460B67E47E91C90013501CBE9C00E1D84985D6161691E0AB8FB540207991B3DC4A8B444F319235F3B22D03640A98C5DA08DCC417E0FC232316511447752044FDDEA962915109466284D94F7965C37F5E9518826C1BA1A94371B28DE026962AF755AA44035126E6CBDDA35A746728D6BE15618180C3EB460404696D59ED13BBB60BC71298659ECDE17F0264971C5158264D9E9006C627CCB58AC9B5AA5AEAC12105EA17AE78C1D9AA9C479917149E5CEB8C22910305F5CCFC2AA90012D2B6DFEADA3FDDE35EF41CDE929B88F7395CC6CEB401392DFAFDEE51B30A53B67969DF6AFFEACFCF455825675CC2A6F6CCE9BE60D23CC0D6ACD35E9C833A3C82CE16ABCF9E0C56A2C18D1C1F9C159867C933B6179856B9050D5AAB4A547594FCA0CFAE4969CD0B50875AD6476D9EB70674434F36935378BB00B4E50711BC0BC375449CA9FE75C0871063E5BC55567D4E082BD0B07043F9477EFC5F8DEFA13CDA03D3EEA1DEBC996B88E9F60B4909A7B3BD2DAFF53CE6B6046AC2F1463ABF3BCEF4C112AC1E625DEFDFB28BC0E0D67061492B0F64B7C66B89CD1039EFFF0546EDFFC69D14F7CE61FEA845CE360D8ECD01D1643AD4C9ECD76125CFB693DA425D877B7CA327261A0CE4AE49057C622DCFF48C6062E0AF24FF8280AAC3F21010C05B789D8FA371F48F18A2144FD1F8423112DED4DB1035B2F5E39329E680BDEEF5A37B3155BAD91DAF7B0CD8346917859D7CEEFDCA7E7C6983E09D789AD7EC35F9848B639EB1F3A1B44D78521CDAF980D6F52FF981C30605E8F5C0991A479EBFD92DBBD6CEF2FE4B0C70015943D2F1A072FFC126CFE6740DEC7DBD9DF059FA1C03A51ED2EBC7B892FF0F0D34C2DBC4C1561788CFD18F0B4A3E2C0B3EB57215C26CF7E28C544EE7372D7841D349F261660A3AD42968D98D0648975D488C2"""), +775194fa9e30c689e7302d8c2fc00a7f00841fcdae64e399a53e0be6954663065429981a74f61454a21dc8dcdddf4c4066ddce8e5468b7bd5b26dbd4283fa7a877923797381790c1713da02709968ff0832d6c4d89d20eb3145a7c15ac09eacb033a7da76730e09b3d046aa5af01efe52e3a0f027fba5011fa546fb5fc0cfab8123354588821124761125462867143201068176532572015662021787412776133663461662516613127305076874123764663443174716886480125868463106558201008703176818888335470841078863525124780848221402401271324205864713506180015021080561066460302752630337573872578318172800670886377121683873150166316433017633687422041072550783123188513067875320218141887780241707861057474220312532464675542836737678404710137071730427208884644822180077044878772244308013004077287021731285122144771457608441245004186732638806268712328246273182373310817212362101711217128744356367251232358767873630286444004265228015852545234702853700543220230385386347720606804853040270356121170354546661117884006288624425424261076447101017261433632246067153565133005185584112568087530887400354165514575612710107518105111212880423160320776164322663187851666826475266514506542017236133470881016371558026467184825281620822370012506573522580870410800578835360423727437546187382604545324437380583851840368564484147868560247314316431274136074313628586112642714347270355050863242834182541260623061362670072443286601140011122260170704886474038621622106223074831064667433402301675534076201486620401610182475848155741838435013666012256742055143062248642370042501004404201220472422713362532468454186164808851065576017668724284048886510873771246805247433731476322167183106422148886801663744886227641807258575643350158780032653053403277082020512364842215836461740846432310100831764051262516215812253404208551486515827351162618003733466066543352780177355410552035840806874540435161826802664586320781278338035028133718746822122511552230063508641532268816678453680866581380828033615673280874678758324088400275448388454607317108875831531354227470725076141144534686412537824563825722877183411550677700373524533067445807141178142157871184851387873106405258723664717374150224651476366210256351366353505453335354526742522767451684323424516401350610873104848665032166533585003470786668323686852545850637165171575158723631707561800080148548322850210080726687771640233236848368300075578486270244466218706477857038331816632104585010604237368056736578088326582476813804678062134825523128202303334241720070686472747774265138046574103501028660081182563722570666424860667805087485053108754536312327142124803354804743005550286355268320427431215730548114172563283722026208424375640424116413408624467633266482015723581236203131518862113064822005608608433723653237120352587004423311474456472088471536172214481065711267885838858351122324414845814341224441731416501101677844383118405826224634471523326237030353065105122703137580526125512333342624572870570653773585614446713440410767104157105715385272211378045570506026334811377158286601313708787117102676024340056353641642212118688236601230400305723181867775275010672436885537146518804123060448460341683143361006382558285618843318316025426272581550022725e3ab52ad317a7288f7ef740ffd3fbe62f1a96ddcb6d8bd300d46f4f2cc1cad162d5f0bc4a1c0d46f8c0f567ff3a962f5037da119a596bebad2129918de11be09cffa73a7026b1c4a94ab98184f7f6b214e37b06843bc197f6e54084cd03f427691ebba03207bfc412133b8f73dfee78df80421a3c30b30962b6d06cf8e41520e8c9a7975a48e45b9d6371e3029f63b7972072cf5c30ecaadb3d763f2acbce180c172836e2f866a894cfb2193268616d8bc36157f48d7846b317c6adffad1f4197d5151b1f60f65762de9ab5244a5a7ad8d6feb6cfde27e5adc7e48bbf7f37e7db6d8b42324c070be778426a242e805dc353b88916bf2c32158512be8d0a62215a4e9ee2535a1a123661cba33ad1fe6f8e61c62b34dfc7edb12e9aaadc76d6633315fe128cd6df60830057d5769008029be02154b385bf1daa32633a8b73d39549f2ef157b00cc8e347257c9c409113dcb0008d0d9f9a68ba9c0e2cdb1c5585c76498365e81717906f6e2e6fe9153813500d447c101ad6ba8c0ce13803396cb44e6ee31cad12e9e934b101b9c4a4e18f9a795e270ed2305552e43c74c6f9673cc78e8d88eb2f30674367415944ec31fc5976a09fa62750125d609f5af9f06e4480922100d8031aba6ef774bcba84a1b3b1805787efe2af85a7e592eedc320bab69cf52a9467b45d9132e45e54db62c53154fe963293c252b4e4e29e832016414f4dae7f2e9d0f87d050abd1a72ca7348bd4ef25f9efeb7b4f25795f8f15ffb8b5947f7f99eedbe22f238cebd8d747f50547ec451854a363c726796c9adffee62ddf079b8b39d4d2b9c77ce9a629c1fade8f4a9940aade74d3f6194f72c3af20deb8c5e4588cbd9db261704df134b3b147b526a50dac889551c7c866147e1cef784eaa27f940327f713e4f0e1c2f77a09160ca8cb6acca67778c6f9f5cf50723ad9edd8ee2eb93bf784a4e6ba07c2bfbc581bb80cc4525594e98baacda06999dbfbb49609481c9eeb1082a7f05cfdc95a43a0d309e6d3315ea1a98e658f394f239162c8b417635c5a100687984a3a458e276f6cf964a87c72c275e35771ccfd9293a13aed45526352421447064ad00a5457f04ce2066c92cbc2c287056036cd8726fcfc5e9dfbeedf73493c95be8f260db775d5d733577893d871a0281cba27f93fba8e5520361c5e9108299666179e3f40313e0c6ce6012abe07f2dfe2171f4da5358733188bba4b1059e516b0a2a00493e9e7386b9f00bc402f6986775bd2f1d5ab7455aa574a0576117dbed54e8bd7173a9afe2b5428f1576ba498bfbecb42e6f86164dd5d69b744dfdef0ecdae1ce1c9a03da3e02d707f405ce5cebf694671b41f034bb8757ff3f403d4153573fe46cdf0a91b5e0f34676f1ccdd8b37e12a737e0735cafeb5ba7a086639a7298712e67c56c71c3c81fcf2667187b7c5487a0fd292e1a836dd576d177e01a24949ca3c7251e9c522782dda331ab2008a77c55616cbb163233a45b7ff45af92434c00a590aeb1f4df607077dd9e8e1eeec4efa64fc1b51c15759ac1c3e7c6389614e657d314066ba3d84a5020ab46006424914177b19dbf6ee27a3ecacab4e2779ce9be2651dd4128f1a3c5acd58c3106695eb403d5fc7a8dfdf625b4929dd6903c7f4a27436d3ab1ef51f74845a7ab5498a9e5b10e57714864383bbe2d6584e7da26ea0ca3059ac96fd8020fe4d67d8442d91f3fdfc26cdcc9ef55877a460944251115db42e7470f80784aa8b7e4fd21642d9d91282e52221d6fcd04a9b7acdd23f124149e6823c250281eb1b0ebc31bfa8ba142ae0bfdf6097b14408a9e61b9c2b0f0e10efd2cf3cc1079119e7c23948941de9f927ac5b2d718c19ae41c14802f0675f3b75f084f622daea75d65b05c0e17098b402f05923b9011cc96e86a103fbad491faa1b8be68f8f5738b199e14086da38ce13196e3b2f4b9c038b93bbde1fcc3f277be2d37b4bba08fa8e8504760f63cb954e511b89d8dfef063682502417759885b1a48d93100d6eabf14cbeeecf2ce6c17903ce588036e4e499c22cff789f0d311fee8e4127819679730893009d46abbf837881e26e490c437489437408b64d12114b7201abd6b4591afc083402e959bc9c510930abac67563759b95415251db053b68a5278adfcf26cdcd18463226338b46b07900ae532488a1a4fd172163e36e3f7c219b86292c92d68d6d0123314ca3a75487e920f2b1b12c0d605f153f65eedf3d98a587bf6eff36dd53ef6686a88a3f0265248c5ff91a4a1b755aa1597d1c2cf37174dcf082c3f89148ed8d4852ab2120a53697e9538d4cf661968d6d8d71861b32efbabd9778bfb75607432c765dd3aa2f026f38a477e65958b9e3c2d1d8eb0533b1f9f939279d687e4398d2ba454c29c420be58c3054b3cc2054a4c064f3702a409bc47abbcb70c59a1d6af84719e067805599502608645563c4bae11644415f1b82542feef87605e389d8c9afcc191472fba3987e4a0135f78f97b34cb10889e11bb9ef1149b57735ad77f841650448775dbac5d82ab0294b35dab15eccb5cf979021f59e0cf02bdac2b3533d2cb56543d9b1896ce9e774dac74f647674dfbb9ebf78b9aa02eb756182977a8e5eee876d2fcd9a943fb38850c1de8e8a831249d2c3ab9e3ee4a25c4e37bec0d71bc2a5a06b04706ff801b5f0d0ae9220f667f18480db1df8fbf38be4c3d5bddb133e102c4ce030713609819632c472e85a01262c1e2286897208c3f9871f8640a171bd4e41db5852525ce5a8da599e845169cf140f33f105219e7d03cf4a1aeb90341902a2010a172955983a252c32f0a5e120b099541145b8cf23a3f5a3839d5fa649eedd624a19a2530f570c7ca1941b112749ffdf96717c73506639eb3a96677fb97c66a613aa21bd77a5302be163d726ee5741c15bfb187bec0c0c1052a1715a2cb4573d4c3f9c3618d2c433f38145ff88c8b0287650f6a50d2ee661e699ca59b6385f10e250dc70dad3a5e12c5e002cecaaec22ac8b57f5ac5ebed502a8e1e6f2ff2936d8eb7294aa89778361cf9b325ec79197ca4e67b5836d3d025e5cda054186c214f9b920bf2132d403cd8dbb24573055b775aeb18151b1bfe53cf1b71f58a9a33a62d5431e3e0513cb0b0790f7d4b167b91ddf78e00f988ae84cb81b724f1981cca7f78e5553fdcd93059664fc84ead17b59f5832f67966d93e3dee2e57c25174d217f4c054206e53bbeb341ed71f6fdca79c55bbe8ab26ee08007ceaccb99884400e1a4cefbac6858012419903397f64bcc9949fe070f02f227e62c563887b68c0b1b3c2c2854c4d4e828736faf01c5354fdb9c8a7806ce33047d591d80d3af33cb455818b228627f57b1973fc396f3c3711603b286c4379830044e3982c93ea0e8a9cb1b8a16595f442bcb11b9a51fcab5b37047bc114daddc06d03ff76af94ced219201585039f0ba8a95bfd17e5a8d24cd7c34a99284db28bc54bd2d5c4540451e1858805f188dd41a70be6cfde8ba28d4ee999d3fdf8"""), TestUtils.hexDecode(""" 5F8F32FE68B556ED1D2EB8D2BC20AA36DEC7900F8E5D4BD3715419B28771E5B0A080DEB2F3EA6CF415D40EDA46FCF8A439954471B7308D3E4226E9D5A96BC22B08FECEB4C5E3CC2239473F1C9B8DFA5A29C31D499CEEAF6E34A396BF0DA53B54F1AA674056216756DFE15F669FC2E1D8E6F67BE5BFB3D5703F25D62D3AAB0398AEDEDF7C65E051A4A8DDFC725EEE940BD0D06B103EEA32D027CC20A8C61034DC54BD5533CDB1A85107B9CFF283FC3C5FCD9C3D6F8857560311AC2E0E31585E77D0806F9A4E61A70D3FF36895ED447C55DB52002488045CC358A39475BFE8456F4FBC36005218B2CEC1C573E41BAFA7A622EDF776C8AD340680C1B3002F69D3B3D8844494EA9F42D2C9C9D2BC0BDD850BA3C4DE929C1DF49351219F95EA7B9794827FC1A1BB4A6A00809393BC41852820569D7BC6FD55339925FFDF55A0C2655C85144234FDDCA91E8BDCE8CFB7199330763F5750D71CA8C4B3BF7E6469F5DD68624BD6D5B69E5FAEEE53E3A61AE659A364484B7D2BC8A85BE9F8D35C8B97716E8202B610BDF878C1BD83187F7892BD861C09FCDA64606A185B93CD2F601C3107D35B38D76D75AD6023AFDD95E103EEB7283379BD9E44CABAD923856A599B719A18FA836749E5BA95C79B1F2F1B443CE1FD26CBD2B74A0156C381BC270B74FC42DFF8D91DE4ECDDF3053007A09B8E3C964B90DE55DE5193F218685327D8C0C6CE3BBABD57DA8772DB7CA9234A3D19BE16A895E7D14337FD9D50B4A556C75A9D287B44BA5AA4E52C3262218DDCEEE3A7BDBE1B8175E84113F515623C07BAD4FC0985112DE4D77D31290BD013562D12FF8CBC5F2BC463223AA82991D7D60E38037578BBEEED70631CEADFE49823EA3D87EC384B3FBD4974C474FF9D47F467110EA4F3FD94B5FF38D8FC1C75392896394671853FE71DDCF7730C70ED26485F395F180D2F5C31AE0C2C20691CB4BC81356225E6A72DC72A1CD3502E42C22B594118D131BA5EF95F2C18B3061139B047A24E32197F89780B91D36B28BB5EC6C03232A3CDFC5ECF687BA5701F3958FD87FC0C8D09825E8BE4E5CE9089C674049C38EC5E0FC1AD542F57B4770B6E5DDA215D319DBFFBFEAD9141647A508E271CF3B0DE7C137A5AB999CC88082FF0CD495F1F1FB1E367B57BB400D8697B4620B75FE467D9B8BDF9400E14047576B3AD6AABE0C0714686015B8A963A0DBB68CE9E41FFBBDD5A792920916538E4C33F12EF0E93D249E562B71BC1C252E1DD8AA646F8C7B489A2BCFE7D29A6D3FDA2C21DDD78179861AFC766F6885E9959F753C66462DAA6E01C8B06A6F581104B583F7A5B1B4935A4EF08219FA8D114A963F3FF3AF22C3D1C1E3927AEBC886AD0670FC89C08FD4DF68EB990A0F7C51A4439C32F5F51785B20DC82586940C35D80A91865C3154D6C925250B24D4C1A9E76A267711A0813E8CCD2DDE9748FA0464006DDBA963BBDABAADD377239442DFEC6F7E8098604645D63AEA080C1F749CAC589F77B4AE0955FABED757E6576966D539FE1BE5965D03882279B2C9B6899205C9DE8D0B1819DA8B5426E573CE785FEDA3BE95A18A667AD5AA8FCE7894BA11A44B266EB7571A93CF9FA64C1132AE07F0F24773C83DED2C2885D415ABD96A21A0381811D66952252786C39EB68EF0B9B03BA7E2B66A49BC6CFCD8097C321A932E5CDB11EC6E43A8E50DDE01EA5A28F08F5047C67C988E8B4A04701A0237330598ADE8EF8F801A07F2148B44E593B0ED16DA30BF37A341073C6A92066645BD7042C3A59B374FDAC00F7F69BDAFCAE5EC0AE65FCFB785C93E49102F5A5029876BC23B0FDB7FBBC376A9E834F0D19A276BC4E22FEDA18FAB529F15570AB674B844703B47D726AADE3AD4015F52D86843A01AD5DF086E07A71A0236765DE6A777F94B1D69253A424193FA9DF54899AD9915634DA23E6DF351E9608219684EC8C8C949E900718DB6FDCD144D0BBFE1079C1BAEC516BF60C1E24B8EE6DC380F55E0F65DD64025C937EA89FD12F0404ED0C03CBA18CE2FCF169F9A1EC9B96830FAD0149D4A90B13446347CE4E5C6005BF115385F1D22EF6A7E40EE87847BFDA4CF7FC3135C4164091F49DD08389E1005271E9AC76E27B0CDF360EEBEA9C08E233CA58305CB276A8BEC9686CDE0E2DB5CFF9858029F3A5A42759E4AC6DD40AF9617CDEB03FB1F9D7F112A01B87A265C4E27BBFF596695F127A97E1558A68BB5EE4EF0F44D20F318FEE1CE988051F3C09AF6E142932EFE970C1B0C07040E7F3DB9BA53BC4AB1433F7A4F1E480D920C23A07223D7E43570320B3BA590507D580D29CC3A8C85A442BECED5880350F9D2B1AB5C746C1B9909E446D9508D701204F2427F41E043A78024EE3F60EE19B71B5BC925A2557FAA8C7BAC7E3405C920FE3FB3A1BA7C559BD75DB1E4169804B6627AEF19AE6E41B8A40CFB977C1AF53208F4D775A48C220A756783F41E13B7780328992947D215C5B5682DEC76CB035B41C007CE1017EEFBA426EBC423F710C1E962528F7636F200C2E79D8377D621513BA7EB3EE5A0DA55B81F6039D2E8BD42EBA5B2A82C3F033CFEED6EFA7D970B1460CEACD13A0C67AC0A7EBE7963F0FE21D20B2A82EA922FD889253B5D4CE4D47698D43AC11A8F4E1638AD3A4C179C522A3ABBDF420DA3E89B9FB7608822904944CAD615C62B28EDB15D3826D33DCF9FF9BD5DFD8639AF4CAEAA55F9F8409B4E5F70681BB7861F88283218E15A4282E199BFA12360FFB9BCD68D9BE5A3411FCA4E8279562F595FAAE0CEED4FE675DA4A8FF94B180AE9D0C8C687650730F05715820F67248D02EAD4C7BC0D41C880444B94CCD60A66A1C9B5B6F6690A2E1766EE10B5D03AC16F175603A1B9D49F97CF3F91932E97DE67CB523A38839468EE7681909CE997BFE5EEB364B472220403EE4A9AC1F8A4A8F78AFA4D9010A0127C0A75D3CDD87DD269F19A47C78F696218F25AE8A61073644A4F791ABBF1B180267AE41DD44AF65EC6E0AB356CFEE86095B64F4190D69D60284A1EB42744C31536F736AFFFFF186833EBBF43709BBE6903A06F7F06E8776D2AE41CFCA33A3A86342BD11B67EC10F525563A1843C8443546C1EE61DAF7310802AE9C00F44DBE7E04030BC4D0F53AE2023A7647F08A0BC6F5013A61A84E994FE0A20092DE133FABAE3AA24F8F3946812396B0643721AA13417A2423F96CA8A6529B0E17766E88B2AEBD79AA9D4D31193533CE50E4EBDAEEC976F156D5DE5917D54F9CC0527BB4F1F795401210739A42D10A0242748DE5FF6B50932B507057EECF8A1E37800223378642DEDADB464F5CA251D73DCD28A1E3772CC285A33B34C6701B585FC03C94A847CF7B16616D1C3DD646669546D80A27E9DE6424AA7AF6F1694037E774259308E71E15D7408BC1EB517CF0AA2C9E16B802CC8553458BB66D96CBA233487DAAD6E093235D901CF46F31B9A060D88DBD0B7380652EFC73AC1A6BB5E434EB0394F1EDC937E9A99A3867EB71D6E19622137B009D36ED7F9890187CCCE7D884DFE118AB3682EC08CDA8BA6DD4B79C9C18E7438E6914DC1C403870A540B74244964CA31E730A7D7591E42569532DA8094559241F2C7EC182FF8BB5A3F88DFCE3020D8B8CC0D1F54CF67FFD3A97CBA7F5EC79333D9A545221C963E0685763E59F1EBD34FB2394727896CE638E909AE6DFF41D17EE1D0BA036F8AF11335A8C1B5A0E9DC58EAB9C12F46740493A8B5AD0EAA73AF462BDF43CE44BD0973688D9C8DFF8FED961758E1AF88FD5D249FFEC179FE5AA1D135C0448D80F4B0CB68492CA399A3916A2EAB684B44E407706CC3C2F48972BC9531353091F91B427FA32693906DCAE862F34AEBBAEFD30666523EA9C27354F2FCD99A6E810685B51965571E4B4B5AAE158636497B6F952FA0B73617AE35A8D7C272DFEA1CE06E983CC65A501F73BE9D69EDDE6A4A1764DCC4B74EF09EC27C74B677920AE8C49CF4F18160E04B5AE7EFA8D5D92BAA5E4E547CC8AFB9D55F1A9DA7A6AA06626673431889C9996BE0A473702450B960231A617DF4705B07B47DBA1BCCC0EFCD5713F88F394EC4BFCC49EC24B76D531A356A6796785D755F027C664D8966B5CDC82ADE776BEECA8AB0D9DB6ACF5E841BCB4381828DB8F7358A637D04D97598A8B3BC823B891F5EB6ECF54E6F9200C380813FC3210E68894A656796C9A5B780FF486E6A93DE055B8F658FEA17035D9C212D23BB5974E1161E4F6041E5AEC446D70D52CD2F21F1A33C9938032487D9ABA74C448EEB8F8D51169E8B848242F5C769B471F0AF04E965BB0F4AE7C6F7B4AAD4E283DA762DFA49FD01D21887ADB28781FEFBD931AD8E2A26BBBBE5D88B52E8B7133134CA76C6648EA39E3D2F102177F4237219E06CBD05174D503C9288EC9C3E0128A824A7ABF418DC45EEB3A67777F74D6EC52891EAE0BB56DC756ADF40D39151E3A68719C563E99BABCA4C785BF4C2BB1BD25C7EEE22A8B0C1E90B948FC3A691670E9A3A331320CA4416B492907C3FE70AF9A2E765F9607EE1BB2CE52D2DB15F5DDCF59BDCCCB5BEBAC2784FA0896BEECF38C24022046E5DAA7607E8D2DB8CBC65541CFC6A0F20CC3AC5EBD4560BF5E9A3FFC0BAE917B479D960ABFC99EF84A696CE5A95720FED90F3AC58D77D48BD5573A0D85681238AC0EA8F0B58A01378929C691C146068897C5642DE74D79E08E5B94B101182200FB3E2BBFEFC8B44D2D1203075862D77A184B25A7790D76D7CE88C979D73E599C212F04A8B01EC3CD6CED3B5E25487957C56BEF6AB4433FFFE6DBDEA396212A6870284FD1BAACD5F7A5D9FAB90D5DA39D3C5F9AF196D9C46100BF45861679A7679638BBC8E5B5A7606D863478B430BF2C61F52D3D88B0913BF12597620D337DEA52BEE9CC8A1592698D23B23815C596981152C99453FA16800545EE781F24841FBE5A3E5AD8D08F2B898127AF40A681DF9DB68681533C349109C29D19311BEAB4C2F2DE97A5345EA7E41CC0988B2042925F1F9409D947128CE1D38F278863385A19B2CF8338D0FF31B06FD865B9167488EA157C7965F4679286077894660F17BC7289BEFFA93CB7DB990A0E40D998945A77E536902FBAD3C8A278CFE0AC883BBEA0B20E5D70EC6E10B59C2449CD1A0B55F8252C91CDC87E70E72FEC175D6D67BD43CB5AE4EE9C7F9476F4589E2BBAF89E801D5E14458F8A0B96ECF9F080E5150E2A5004C5A89B735639621157C4056DD1106CFC727B921D5890F37051E2B906885C1CA3999C18FB8C9FC9B652D82AFF074EECA9976D612ADDE990DEA418031FEFC4E972B31CBCBDCA0469E3966FF6F97F9788650298DB71CEDFC04659D30FE673602659C19A869FB3EF4262EF3FFA9E3FFAB1A3FE7670061EBB0D49BC60AD0C774913910E26E4213B76DB72AEFA3CCC197CB6F6DF773F86F12480B5BBC2068F61E16D1C0C141AE6F1811B2E0D713AAF60B90BB2F00EEDD4651FB5191DE5A246A4D8F3E9999D85253FA705CD4B94A6A64D9E9B6E18BB6855CAF6B991494A8DF75E56C2A427883E0C27246E5854B8DB2EB0FE639BDD00AD678D1B61D799AC59ADFF6A8616B357A4B12A786EB612E5613CDE533D92E87D51D47D860BCC39687485EA814DC5F5A971EE915C193ED52AED98D7AB301E32342F3D207BC03546460D33B733E1008E48D80E716FD717BA82403DBB520246AC3BC9CB91CC0ECDB7E35E6863C3C11558A8EAE9E1DC49FBFFC0F92F397828A4AE7107785939B96932B9EACB6BC6D8B3A189B5D3F6B0C7A3A413054B25318792AEBA3F4C77629F1E8CE1AAA98FFE1EF50C2E60C11AD76EDDCD8EEAF858364ADD637AB97ACBE4D2124AC0AB559E85229F1B5D81701EEB1D6834FB215984E9DF3847392EB29D2A428DAE7FAC283F93C8FED86FD2377E8216922D46A51E628091F6F8EAF967740B0EFD84F002358D3ABEDA0993DA16D0D8233090A2CD9C27D78DA0A53962FE7DD282B276A30F91C2B734EAD2CCE5E03137205BD97739F6CD75A08491D4ECB22591A6FF840B5DF123FCA7DAA98B11C85C1F8591EB988024C206CDC4A4239E7A91DE75F49541FFB6D91BE4699C0C0D8B4A44A8204F7E90AB863C3183C2270D185643D6A7165C1D043FC5108C340650F38A8FFBB13BE4BE68858C50A2463F7BE998286FFD0F981B45F5E414FDE71637D6EE77B33E10A530C630D63F21A212E844C2F7A26BED4F7B4DCE0C566CBAEF4EB4BDF2B53E743EE13A845D3C7AD5E9525C50CFED35DAF5D993B6377CF1DFC5236D51151B046F4904A02D7D51B6E331754B0E3621DE4CAFC9D8F7247788DF0EA7E6141FAC4B24608282AE29D594CEC0C82DB05C0087AB377D0D504F64F1CBB2D9F3121087AB6F35A70ECDDD15C9AD2A185C16333BB901CA069BBB0B80CB6F505FB3F382CED72CDE60FC050241B1D32818D11AC4421B66CD85D0F7B479C021AC111F8EE8F1C60B2320585EA276879AFE4034DBA277806FEEACE548CA0A5D36CFAE7B99ECB0236CF4838254A20A13A2DEAAF201B09FD027BAFC3F0C5ECA9EB5850A58C6196645F051E57B82AF4B6C2DA9441358BFD2412864950022A07542601631A00E27BCE6E203B1D3F1B844CCBB2EEF71A12AA4E725188073004849A225D733C77C068B0D2AE53E0DA6F759A8E7A5486C529B29A3EDADA69924E7DC200158DB4B612C62039B321CDACE8294DBB1A56ADC685B0B0122A4F3DE0A264F47B00C903BD30B5E4281B0C75DAC5C48E18BB0BF642F8C2CA194AE56CF7EF3B4529FB9271774108C61198A6894FC9FAF896472D1CE78DF00E714045C5F7C77DCEA45B3ED5BE5AD545D8F3833206340A5E10DD3375BDE0A068D050CB4C87E0BA95CBACBE59280BD5CABCEAFC88F5C05E3D8DCDA6B15C487B62B467E093259230D47B79F36572972BB78F90BD384255CFB1E4F1DFB7B5360EBE1230F154C3645A7A233FDDC472432F6C845CE86B078D93A5BBA3F8800C5313593D66A8A103B01377FBC5C6D5FB8A55DC71EB0BC9904B24BAD2F505D6DB5640E914D84FC71FA058902578B72C47659AC07AD4D64C3D28328D2DC8425C4039EFB2F20E3B954BD0B0483848F2C2D9528214514510CB0932F7506E9B98D0E891D8183A907FCA7AEC068B9FDF7F3479A128C6982BED19512A4271D8B682525B5028B77D6B6301181B403E5F62F64BA3CF06F0EDF321114855839E9198E5BA2A65ED952B2204809215B9BA3C366FD5C9D409BD71ACB748E653DA82EBF617D2D57C74CE37BF20AD8D789DA53C086423D86F94A96ABA379F3425554BCF92F82FBBF5C2A15947455D7D7478A84BEC6E3B9FAA14E425D2C8971DCD157C1D9E210620E891AA4304CDEC54BA7B3352556C49A172EAF19919184CA005A526349918F9A7CBFEB83510AD899BAEFD3D1F689DC3F449153597C8D21FA1C7BAF18E689B51F89B9BEF196193B7A781B96B38B9145AF7338FCFEA109542BB1719C9C8540B551A35F733C394F7831900452C0B8D36BB90824699BDB587EFCF5E8410E4ACB8ECAEC5F96E74A5DD3DCD4C85720064A14028FE768041BA1A13A46CD8A0D2C4D09E724591ADCD5EB907038853D8C92C5BA7FF57D5B54B2B324073C7CD2EACE0C521254E9E5C0CA197FDB3C1AC73FA8EDA729A858098E6F5EC11A19D4F655C6DC9AFFC4E67A49EF62D80EFBCAA383DD3DDC22C2A9B7590C16F8CF23D52392186B95EF9E947D851079C35FA11595682DF4EF4D770EB16CBC3994326B8AB3B2C279149122D178BC7B53318406738290596449D797F61B3D0CC8B11750F8D841FDD9D333A5FECC67CC7733824BBE257D40E53B43CCA19C95ACCA8FFF393533AED57D423BE0C38584A81689248BC7F78CB7FA4C94A7BDBF3015B4072B83748E55ABBF4A334AED679D89E2F18BE1B249B3F61363C79AEF6E1FB09D1948610F77A9927AD6D57BEDA02BB1E77415DD7FDD3EFC683AFB1E20C08284B620EB091974FDF8CEFBCEE1461C210E81E86B61F2D5D1882261D60D60689E39C81B981EAEBD9A42E608A34155516E4E385B86BF0A4AA05E3F99B6B3B7E401724D1442A45A696A189765BCA3240111E9259DE161DADB4E0ACFF27818C631A8A2ABD752773A83DC29CD619A58556040A7B27CF56086BD499F8B8D283683377A21BE120374B8D4561AFE781F246AD987E828FB40306366B4BF4C0B4B909ECA91DC85F521ED5869A2F2AD58C74B6C959AC71DB6F11503F026DFFF6BDE6BD70363B5B38BCA0590A5AF2A1054209A36B41B2A671293F2805568400AB282F783C356DDE30E0F87C001D9B1B9716A7C4021928253622F2DD156B3C3038A077A5768AB8AC070BBD9467E9C9630754934186BDA122CEA503F5E274EAED746065CA81A2702B582E82A33CF6CB3917D451FF59B0909E6BF847E6B610DA89AFF98B3323E1385954EDF1175C0C1B158CB905BCFD9AE7FF9389ABB9FBC5194A45DEB0570C58F31D914F9941B0242717B243ABCF5A20676051978C16FFCAA8ED2EA23B8323CD58388860DD64FA39971F9FAB83A4B248EC8161D32565917B7E6EB4937B4743C6C236E75E1747A1C83377FD1D927D385D81A9EA7F4AE5034097A0A77E2D2EB1943D3128BC0134F2D600ABB929A5281C26EDE1C12CDC80F8EAF2E893091EA274EDA1A246AEA3263E43D6C60043CFF6282AAAC620A21B523783E0CBE33F78C89D00EF8920CD53C6EC0E83DD7E1303D9B6D5280BD2BBA26376C17099758F34C22054DA031C86CC50367C81C3059114A71C565B1702981D77040B0FEC1E89436ED1896E93BA202F11ED2BA4EF33A76F86AE8E23B8FD064C8FE894244C97BA7BDA6BB56B7517C236400F591E4F28050C2958A7A79964AF233CFF8655F1603F6A0C7ACCF440D0C82D5528876721434C163D86858B02C6F6A660F53B3E45185FC7777A629C3E4392AEE4A96D900B0F19783DCB6E5028B6E56E160A37D37FACD7C3B992773ABC8AE1ACD6AD41E7340CB198C9BBEA1CDC185AEEB51E2620F0695C2691A29CBCA8E23328E84B6882A59A8C3C2A273CDBD26965564F1F1DF0B2CAF83F30E782C049DBC00596BD85426EA90ED30ED8EAE8A88C0D1363E69868E8CAE56E8DD62CB36D9A15150FE567DF7DC93CE78706BA983885155C9AF05B5FF1D0EBFD9D020BAA9196D9C871236DBEE8A703BE458938D3C882719881BD49476386387DA3508780878271C0DA821BAA1E9719E437BEE6294D8E4E2483932D0257B44B8CCD8C55028B3B7D2BB3866216A7F52CAEBFA0FBAE120609F95213BC05AE24473C98C29F4A46D985336DF8305787A0374098DB279EF0E34E6DD79BDB106EEA24E4DEEAB6DF35C58AE73FEC926174E0942D242AF0D30825274FA1D510D1C0C41FFF59A4381CCE5C6B89AF30C41733EF42E76C9CD58DEA7E881706843BA04E3A170304C551B6C801CAF9B8DA52913D2DD4DC755E0BD7C723C4AA5B001D9855236401C1014507CCB84577749DB1AF29E318241D91C4B23BD80549CD1D6E0D793E966A8A7B755552F16D3A1146B0CC6D92C8C90E97D7EC8EEE7C365697F93AF257BE24691E41F2AD26BCF47D52A1B80F5BE1C658616537630088CB6E227B0EE6EB8DB2FEC0284E58202A73CF3AEC16BAEB59D2A6E0257F0ABDE5926D9A13D89A8B2F69695BA3682E87A77DE06FF54892F56581FB16991654F60EA22856D6FF9E0BE2C4837F0C1F6C54E840F67A75185F0DE9439AB1E37D4FB3E9757B0FBD17C89DF8568755567C390032DE93E9C93E6C89B2E66E9E9D96616919D9FB461F9F33"""), TestUtils.hexDecode(""" -E2B72659B75C1F48D3ECCE4E6543C8C79DBA860CFFCBBEFB69AF338A4816ADBA6E6673112627712B5370954A29F9C896AF05012B290C6171DA9E894EA53A94F6C87D096F6DFDC0D77ED5BBD368E4F0CA642DCF6C89462C1E694F8B9C67F641CC2859EC7289A85FA82CC1984B5FE045DA7814CA6F693D144DA720D33F1619E74E9435DAEC3B4D64888CE2525FDB063FF6C4578A3C783B364C80CF09B10D2868DA846858E742E7F5E5845C49B4694E812C39D021CFBDEC8172A6F489C8D0A5D57241A8F676CBD02446725B6B2C0A51AEC4EE63339477F0D7B7DA74B7D343AC283B6BC38D79DE45FC28E20D4BAE6D7E9DB775E4801ACD3FA93E05818031BFD882905962BBAF1A6CB0543C68A6A1232E6BFC1B820C53DDB53CBD62A849FA24BF289589C860F32F35C42F0C04C24750A47307B07BC610E1B6D7BA61FA2DF526DD836A656FCE196A8FB708DAD7F85CCDFE288E2DF71F3BBF9C0CC6F48ECAAD507AEA35FFAEE1E7DBB53FA9617583EE72DEB3DBADA8208E19C584F034D75B50F0927DA9CF2793A1218298434C32726351A48428F94A19A7A286CD99141F97301024B6CB6823A199B3EC759ACC3A7CC20D43072A5E8112ABCDDA6A17C1D9DA1FEB4552B07575FCA4B697EB8165BD0DE2403AE19DE5CBD60FB21059010C3C4D2B0DCD918321DBD7F94D59E0B08825872083FF50847A3457ABB30C5C32E4DF9735553FECC558412A22D46A165AF38A07CE0E2E1F888A5DAA2F9D39870F008E38291208F7D2FE2D75BB4E5B6DBB16662A1DEFBE0C4145CF91BD2E66A670DA776993F60A4757CA5BA0C55BADBDB1C0BE86D290D3F00EE241243CBB9CDF5B3A93DAF95840C55320B931C6E3EC9389B117E7BBF23EB6192965AF97DFC89EA6D2580A9CA0C699A66E22FB7354F203FEFFDC4934251A8488A15C3491C3C6E5DAE8C828EE56D97723C83164AD15437B62F4B06133402A3F1A261D08F6091CC5C46C517DA95717FE632FCE49C659D93BE9417AD1507315915F1C48F20A66F5F08352C83E75775D27F76B1DD73961D50F289391FE376977817D12D7C9591FA2832AC84EB00A8286841812F8C120EBEF5FA71F79AC3CE6C77862D2121B4B21A33459566998CDFF4A0E614CD6CB72F5AA2643A3A61D8104CCFB041E94D433AC6D10352049B4C104005191284CC9B23942D90F3C53D05DF898394EEE9E041B735BBC85F20D454ADBC84D3769412F5E6B06303C503BF1C29E43F93AC993BCFC20250A38BD862E7348AEE4E693B1F99FAAD7B7E8D3F5AC1CF8A192D894AA3BDC356106F4C212954B25D86EDF4FE97ABA3030EB20A9DD48CAAB2955F830523745B0208EA35AE42AE06383F8CDAD8E66D5A988D95D1DCD310C9A6AC53DC448AA80B21B78C2CCF3E46B447EE9E9E0E090BB6DBC1AA4D5A6444283CCD5E01438CD92226A4FEFA67EBE63480AA072FAB17BFC0FB0E0901B5DADB7C29631B3E3022574889681478E02D5C81B7C676122A1E7AE441D16E090D5EE64A17033D0D0C6953324C5E476C652922FF1F1E47F833C3FB1705E5CAEC5B57AB93D192CDAF9CA712AC0BA70F36D71A37D366BD80A7BB3E382EA87EC5A1F6B281C01F8667C4100906D713B83DB6A50C8C527846EB728B173CEB9B6791845C7749AFFB6C72F362CF602D70452512C76DDE9D1E76988F3C6EB14B43EF02D1081E6FD446576CE727DE20F6B25214DAB404B4D77ED2DA703DFC0E4219D44CDE16F596025C9E90BC0B52649AE81E95990EAA115368A9C6B16F64099C8B928EA42168CFC544445847EC42FCFDE6095FFAECFEA31515FA4970B27649C81B49B4AEC86D1329EB1F5B5AD04851651BAE0236C267728F1B0B8939B0849D9CDA009535E066990C664F160F5B8387D93CCA6DC94C8AC8E5A161F0D4E71417F43775F7AAB83550BA7DF60AB7D58DA72205F6F52F98A5B73C6608EE34ED7758D15AE7360832F929B73E8041B35D4D428FFCA023781B26EB65C8D3A5394B8EDB1A23EF228850F32C19E8C8638F6E3E8D64BA7346AA7BE8356CD61C0648F19FF1E959951A2B92B635588FA51CFEDCE28FE0EFF9B00EE81675223A8EADE3476EDF74D688C57C68E78FE3557D97198D74648CB71FB218A056165590A03E4AE830E8DAE1FBDE2B65964A2A9DFDD75E7FEF4C11842DDD8DE5B7ED553940AD6C74EB10802F5607668192FA7138E385CA14C99DE873F48837FF593F5EAAC30FC7AEE7FD0CBAAE64447EFFBA244AA0DB2CF145030EA2CB6738D95DF990E8B6B981675ACF4C4CA0DA779BEF86116AEB5CA18010CCC8F971151C5B61E2C106C5DD38CB9F7122AC17222163EBEEF8FC9DB9FBFE8F9631996537DFB7B7080A466CE52EF5459315ADA3C8E8D748CE5BBC02D326D676247D8F6207AFCFF6B9877B4ED1082C283A27B8612EE26C9EC76415C14393ABF8FF2F8E54C62CD56AFAE745FA698EFAB0AE19C4F1BABBAB440B71DE8510B7B664A9B9F8F80C4DD125549C0546D4D42CC39022D1BB599BCE77D24B4AB8EB1392C7B0160C9BD376B3FCF822B3DB1DD6E61A3EA2C5369C7C1DDBE7238015196154B94201F935CDB203D8D82C29DB4846ECD7F99E8A8FAFA204C5C800D7A6D0E15791E197E86AF298116E2E4BBAA7365A51CE82AB819B2343B05DE001EAD2E0939F8D21CE2482F65686E5B1DB274DBD223E97F0D094CD4E69A198751CA2AEFA95C937EAF7A52245D560F9126EB4B9F5EE30A119584AABF46AF32D0507E1F7D78175A919CE7678B8A120E169D502B02D9802C02FAFBBD5437EBC4EC674E21DEFA246A471ED242326B523917DFE2E41C1D77AD867D64C09E711CECDCEA9028BA620FD799209A93BFCB7E36EEA2971F977E99326F2F54387752BD19EA29C90CA3C09D9A02740551EDA36D7687CEF24A6D35878B44235E8147D1B752C2BC56BDC86B41588522881E7A9E290B0B2D2B2EA2F56A3C770C7BC2C144F0CAC497C181B0823BC6BE8387FA22A448A9EA92BC4DF5F6CFC946705F20D4C1091CD96C67206DC804969225C0CB11A4A1B476EB557AFEE3AF5A18E763080E723A60359325053C16BADEE646244148DBED40C598A8DE738F5546CDE8ECF09FB14ECD37E7F9A5B622701D92147C32D324FF9525BFB30E85305D0A4EE82DE52BAD8AD6A5D66BECE7002C115B954DEF31F9DDC7E87AF4C37552CE4027606044AE792882750C8ADD98B6ACFBCA0C087ED65276884642FED7AA393B7ABB5C35EB7F3A4922D97EE16AFC0043A21495D1D1D269327F9DFA44195E205F6603234B067C20D09229772354041771CD1AFB30F11981B6027DA1B3A6F465300AC5C0E41FBDEF7D0DDB432DE67C814B76A7733C5A84637E56D7D620AB3B37EEB81DF16093B5612D784873F84E6AB6E28827625F1981AE31E3F78BC4F68F215F4145FFD9530DDA56FB1F67BFC6ACE5C647F0D3CCB2A8255449638A65E3F070FC200B7CEC52C370A86C02188B3F8BD809227F08021C1CFF8583DC561EC62CAF8C2CF878A25C8C62004E4803C15837F2A8FB76A2FF611CDB597B793363F9F1A02D2026E2A87FF4BAAD424D44B24BAAF7472E36ECCEB0AB87359AB317F880E5E112EAB060D8B1A6EAB5C135D5458E628F43F054C8CF2D19966319A9894135FFBDC0E5035A1D2B4418E466C8556DC71348A34082B07C6725B8963F97D2003BCC9E4208F4B28EBA007973C582E9FB315BA0AE288332B94495E2436CB94CB705C8763FFC696894CD2825ADF31FAEA196F6C23176FA6D2499944131F09F07A6F86B1518092B51DCCFF01969F669F5FF0F8E16FFFD044C2D2DCC0E76E7762C0A0109F7C9EEF834F1584220FAD95FB4CA00D649683D15454CE7E797B6F28F195878F5F42900EAE1C1B339489141D39EC56411AC205AF6B4E0D00A58AEA1B43BE74B5B5930ACC43BA774032E7E3868F4208C9420FD59D3CCE11AF933F964AF0A703F7D73A568C89AD1AA9297D82A606E94350C13819607711659F1972611AA5EDB0B061BE6E1C0FE17BED2D0A3AC80963DBA3A28F0ACFB9DF8852573B35EE8975364A9DBF85A32952488CE99CAFDAE4584ED43E00668E531C5CE7D69DB910CEC52DBAF374A73CA22CB194984F1BED01224372675B892A8FA7426BD2EABC723ABF439C15C1421357BB3296C5B4027A4E2873D5CDEB60176B299AA06A37A9E86B96C91EA0F4CE7A32D1A13F453526C38163291B7D1EB78A7C7509FD4AD09EE2B73EED7B48BD6B8864DFF71861165F7141DD3032EF27312753EEF75AA1CD075FA76756D54F1049B3FC7E2B6CCC5A40D8A77E38D1576CD95F9CC7CCF8083CBD348CA2C50DEEFF4D6BE391E49C8704AFFF70B0FD6C978B1688E000A254EDA045A682B27166645B17803AFE2E794545A7877909C584D3D8E58BB6B0BAE76B4700B9747AAF426266A65891516A276485EE9E0A570DA8AA36C5879B0E23C9D3B3165F46648ABFEBD65F1F82C6D8891D1FE47D51E777AAD299BFF8F5A636C30CFBBACDBE423FEA9D93250C6207121B0D7D2122C6D5E8F6877A6C05DDB2401E997FD18DFEA68993ECC9522E1D9FA0B2F4CA779B6B11EDD658A6AEC05CEADBE69CEC2792669F180558B235C295082EA9E20E65AF03638A50C000C657B8E919FD7E3F1F8265E99A2ACB9CDF93F4D72A615454F6D8EBBCC1D5D5E6CCD447579B2EF000000000000000000000000000000000A12161D2227""") +02dede66fc74f94ce000d6c4898fcf4464b834b848d2bb2d98d3a5862ec632dc9636201321c793ab26e4a42ae4f13debf105d087b112849946c76b54b801382b9727d65bc732a5620e8f4f158f0c1737b0e4ab8e7404383f76c848b36f58f5f9d70ba14a8ebf622bc848a9bc3e116fd7b2627c41ccaea47d493ebc6d3dd167f79fc6ededc36c809ac87e77ee1b006e96ccccafb88d965bc1cc15388e6410c68a74d72b6632487c284fbfc10135da29f29264cbb9ef620c2668066a2fa80fcf2132e93a29383e56c8bd89b3aaf8a905d4e60c6f8002132d38abc3d3c3b6fdc6cf508c8f6a7cfe9f78be8445f00a13414e41c27ba31efc46d0e028b778ca57b2326d624e3af6be0d4cb2a80e44b3f1b83bf572e8b7516b8e4715376e5da06bdb7d487d6a2d268afdf5654023ef4a13aaee221fdf7b9a668b2f4e1858da3c1ae3a7a7279163ca9c1407e8c0fb69f0ddf75cca64f4b0f277acf9c469dcce264b8f37f9918626dcb4252391526ccb4f068879809a2b115ca1d75d7a1ddbe5c8261531a98494ff634dff81515fe3ea4e289d75631ded8b8ada415f6438ada0738bdf9f89e986dee9c80d82ec13aabf10849dad939e81441fb063aa627c4e316461fff15e61c85821bdd55b2cd1545f810c1f280e7852604be73963b75e33eda2e2300196590b9b77cac44d059016c0b08a2f18f18ededd8dcb1474b3e088a6e84c12eb0470cef4b409214eb47de0e277de2665c661ae7766de5d05bc357a2db50ce51d9087a66b1d3715f5be97a9ac56ef866fc3bd3025738d4310e4761b57b3f901c5165df95385cf70f064a760b37341fe2c8466aca8258fe821308d8be08f4d569e27365dc4be8a2ee4e5e13f9d467d8b6ea272e407386e9f448c1758858d038c18f49dd7f60874cd4059b5950b8e969df6a2400a628759d6d7839488674bc128e947594521a998a7e9aac9d61ced0aa7629035bdcdde11a82ebdee6145af1f9c31ab104219beeb4f222e0f0e155e6b67160f09f6ab6943a589bc4ea4a1eb3231bea73f16da8998af58b8f71d3aab3e2fa736f3307180e6d777bc5ad02be4d7c718855177d7c1826bdf9f3848c1b9b65c6a25a93af48c728b6485ab765d36ebe3fc82104d043238867683169cf120dcdd016156283a7e6171167ed19996ac57e4691ca3f49b43b03aeba25fcb3d5d89cfde475eac580b58291084d8f7d554b463b3620a63bad5c1fdbbf98a5d8200f0e0ff1aefab7754e70e4d666e0b31ba193fbc70d4dfc601464a7642c56385abe64df8f377e2e7b7c451e903a13df6020d3cc7bd73fac7f95dccc9be71af4facc9edd60e9e5cc5c99bdee1339fdde03b3342a4c0635c71106dbcc4ca3ccaa8ae7e0b9ce740fd9a6fce8cd805937b3daf103c246d3bf61a10eea6af21bc42867e471991459ea895bd74d6899da56c22ba33294cce17b88b39691c493d7ca312776dffb953720f02fd814e6b9c96e4e4a9aa6e2d255735ada1d02ebdefdfcb74573c77b4b19f751f55e20a5229a22e326ac75858d7eb4c7fe9a4ed48dd49be353269223d3021365569da4c2cbc3dc6ac620056c5aa7382a363f93b894c0a4fb1af983d90d8127115837531e9ec7ade4a419051d503c1501afdab4d9b9b9a741810693e256e3f03415901ca0eb9eb74083d88d7a1db546c4436e3b19f3be3da87a6e4a7033d0cde55ebc2f7123b750475886244bb6444ea293fe498fb1e98d9ef7b31a86cf05cc660841f0b21a3ced89cffba8cc08112fb9c20a8abaf1e9eeb7fc7c678377ff2edd2e4c4d3140bfa4106f46a8b137c4d68985dbe4b8d67342f409f75a3027dc6a71acfdec2b723a4e1b96a12e42e49eeef5ca77a8961c77c39d5542d5be19511d6bd5364ae79cb254da944281ded04e1e06b7d4de33e40b1086de49543e56e5d7d4ad2e224f31337351707819f96d36db4d3a29018403556995a098cde94138f71cefad7d8dace8a6e08008b22aa5d257508cc4f6a9811f036e7715c67ac369b6d80c425c79a8ee97c094c93dc18771394a56dd527a676d660472b9fcac4fe783500676a9aa6b0322752a73ab982fb28e5eb4ae639033340b9ccc8ba036ef1164d293627c41e094bba0bd851480d2f91ed8ec8a1d4a229f4d08dc25b5b7dadbcdf22b2269cea9c7c6b886ba74bc156590e440a9a0e128a35ec8aec4eac360fd9bb61e9804dedfdbed1e17454394ddaf851c73327022da9456ba7c4edbfe7a0031458088f026830c3695c5d89a60810c2cb6543880b892d8d5c93214ef78d8e7538028419592df1f630144856ea1ef215ef6658c350a50e018cf0dba35fda2694e1efa93cca66931d9560d90bb434501f5f420b8bfa02a566126dc2bbc9f4e0fb929e2c42637de5e2e77e07659ee590fd3b8facbe7847b9400df4bcd858925c15cbf1a385fd395d50b9590c154928cd95798b735faa3acdb4a8874672041d585e45318ee942b3e36711dcc706bda76966cc0100f14014f9ea47ed9c924035e2138107f52dd26bc5d0312879505d7ddb3b468765086169e24a6e1919de2eb169acb18267fd0ab0c468da0ac6436acd2c4e08fb85f134e648a992a69cb871173675e87906f30e7cedca148c00ddae418e07e1aabb8f82f53127635e09cd898b348d4bc5c575cb6656d4bf33af7414bd26a84b5184b9be5e15c384902b1c66a6bf08b16172ed8084de06331119df75913d29ddf181de3bfb9de1242183ee797309ca14ebfd5f8ac368aa72ed7403fbddcac4077d669930d742240dbffc1a2b4a83b043d904285ebc0937c087c9025c0472a2b6e546b6629cddad4b9e60d64c01e0ed4d4bf8e580013e2b215d24893b3dd7629e71cd6c9f906205ac2a1572fece8a7d95adf21ae18f530a6bc18291f22e1b05349abf287d50f1f6724f01d0cb3fb7e0a576997c3cd9c013ddcae7071a7edf496605715568407f86ea78b20e66404676f2b34618060e180e4f9dbfd9a70a1f96acad53deca1db22d87342ad2eead7289c7e481d2068a74e62f9c9b90eb02aed47b57352b23009adc93787eaa74c7b8981525eb077fd502e6c476f6fade93b53c29cea27cb4a7594b55e4ca11b66f94ecd43187fc23d27bc72d0f48a23987fe95b06940a360e9026a022d2ee3a11eb72c8573eea76accc0fc2acfc61fd9e1655c77bd652a5dc40de7dd0182ff371d5a8d3047bd82a69a4b75452dd2f4409c5176b02488b9ce6e8b5c0173d96e1a83e5889ae16b4a07b09afd8f11b9b80f812c9ce794da70ce46cc3e31e24325f5358cc0c64deb9305941c0511ebbdc302c2e362123dc4bb4c9579c6ae2f692949e92a76f9aad182ab69549702421d94c5625904af24a42620f331b8ca6f8d6ce59306517ad93fd6d1fffbfbdd16f4f120540753a630c0f56b178b1672504d1cc0a20bef9d93c8777c036d881a42a72dfaeb14a1a0b60990a8c27f978c95ce44edd72e677d3be62dbd26b3c9bb1ccf1128f79aeb2a41f6ba6d021300f0ccc1ad36169bf63e36b6da9b3a9a6e54815d3445125a2d5078ec0eebd58df4487919fadd4977129aa61ac337f347b3adda82072d758925f4ce6a5125b9e4f87dfdc5cc4b3af5f9589a9cc4969afe7c6b99edd05462d1da3c40d785b8067c4c866a8579fbe4d94786e0fb0b717c6fb96e2e3ebd72b6901acf96c0fb174c272f3559898019a3d87ebd6d9ece260ec913300392b541a1efc0811c10af0671206345b46a588abc932f58be6149ae6591250a8740dde925cb9fa12150c9f8d191163ecb613418058769c54f883e9c0b533f6d8f568c6a907c227d16054af09c6c73676f5b9859beeb5a762ea323eb76853f4a3ecb113ebc42f9c99d89e5869777448a26c40407362a45730621c700e3710a65ef8a49d9c19a2692bbb37c1fb4573498126522468f738da44bbd4a719383582244a284645b318bf7de280d1b9b9829af334d24c49c50fad08a3c1c630a8e682ed700682998fe7b121bce47bbde010fbc9ab70494d5d0b300b846e8987efee9ce09cc1bfcd828f18ea2bc4f40440f89ed48cfb103a80e77e26967b7ec56740d18ee40bfc9fbc6ae8a0d7f46f3bc09b7dfcc590b55e3d8fec26e7f4dbd7806f550519ba3ad64c15b657fc726001b0644054aa24f9b1dad492dadbea8082b176c5fd819a8e73665751578e74ef32779127616a28ebca4be7270c195ac077fd71627faf95fd02f3b6dc45a9f47d3f666c318d752ae08c17d2385e810408d90fe0aaffea328466c5fa82958e840ea6b7ec4f2bc6980db0f3a86461f51cb55dc262ebad5f326533b6bbe0d9c4b283f564949f9cb05291ddd5371af7713a088fb9033bce4436d93190fa742dda242d725bb1fc261925efed8df4b6e3040b7e4989384a464752833f83a087ab09eb0d2be8320ffe552741a5a6b90ac91150fe3df65323ddbfee23f6237c623eb57a44f7dd67be498c97bce8a03dc2f695d0a41e270663a06c67819f4ba401a45886d78853efce02a00335cffa3b47c29b5341f43756fc5c180edb367aa43f104be106d233224623da7738147527e42a904f5a1fcf1d35261139752f9bc38dc992095ac84d03f889024bc8dc211a1b41979ddfe455f696b8199a2e5ecf61625293a6e8f9e36718e9097badaf37098ace700000000000000000000000000000000000000030711182024""") ), new SigGenTestCase( TestUtils.hexDecode(""" -C76D6626F120F0DC3DC1A840BFA94FFA317233CE5DA1323B24005FB7EE273AAB58D8935C11BA583F58DC10BF321EE6A9C86C1290EC27382858306C4DDC149661245F19CAC304C002479EBA3FBE8203B10F8EB866F84C4BA964C33BE17DEB9A3F70D0BEBB6D69931B7A5C8D7F4F453D4B7583D6648A2D9CCCF3BA555790EB3BD1367456382700517316272745263777343070578043772431812488504440335421634222648265848838121837353786020831856580712415333215302208147066378168632077260742828733501307547176277560372528436054511866171224212737853618516810286575524353052360560431827317050484274631523727443076623201205630176106647063024526654105775786876227221382811315183175187688715152251718801634644008352335346173270831466732388742751781744268285136885233676618075730644567376260056046801283118368127378730400864858860423178431432174024128156430042136886878305255512578456815567452271245453668030586055385062026711530033343383475108202713263083330656287828016636402607650813442327778368023726478448081481213123878572853738681808620411477010631062247480543800734826263723435866084563460834818022430110577037880375342662814256421633255877085434152814408536434148614146707002044162035858310133662324605536663662033473105060631775853077483602002225412581468165821865661211467268147103283132171232547477287443230241240757844153615762424741301722062267472747003826503885544682608118155735313865325848302455485634756018273820137345741727418745261488050677330138546833853508746107616788711375147727451830073522165114147383877083481400123163777662262788355285502510077451133068444362310516824714022346257785811584806148226560441060227752554564772478727583156451406704238688634583166663607688238257518812813555154445780176360300350404665741672685880004215010272888675646851148358423071453520360300388050250721351241676211305457044364015801141683044422561272606177463587455738363783408862388284722643833723114756406862376370330214001874826214622708084084002025636767831375160242480502832474732411157747428683178362313332364104274857216211278653233102730780172388640555127240368788380054832243460744682438112304407528808054840554628757808453602377264441116235321564084234171882453426885776378241812475187760357460162405285166613408735655768736813085162678146372876548208588416884845602213600238752455130070756438507443718730864058241676520223100778537466617861873171267335652236024385153037355153660707083178885813007345133271161552764051576616612614573437834476747524844652344312488386640172186252053064230424402062806207278026457241843213823223578630525753080343552186870662772512780561337726815780880748104546146704251635867710255085600275752004733518051655028507656643504277361001831655542464863821714055377458781574581878347750535822404730758788652635060486802627610003565431211741182688234752636126335334361107773262121051470658880873527267780287051622324420455244182713745723520882604160088777146578781102532430655862124224627601834385720032400151863686860466774444313130150443305816566373132477054681352205101436236160183731116027810540738716405756418031728372050026377227020873522458211520648153707830512024387354646073575114450322344315407165806830058732AE7BFDD687A48F0383438F5D34FA545227619047718BB592AAA4511C13CB8B554321352A460C2EFF5C24A42C8A397E0BFF652AF19AE7C99F1EACDA43AB86B4F77A6ADE00B473C7F268E999E76BF3B5355B2309CD95776C48D7E25EFE74BB83173C3B81BEBCB724E1315EEBE3D5DD2BCC834E74E411ABA98F9F0323AB583B41E42ACE6205B48BAD7CF266F639DD2C82208AF0EA64FF0C1EE76E13309140A42B755C21B8AEFB23C4FC79AED0B81DBB4031886982D1D9D218E6AA8C547D117B8B2C477318268AF238687527D4E30D7414E10922F58D7C71ABA68ADDC54F34DF14F7A405CAD7E407DC42113EC1B4161FFAC3CE571C1828B287D55A0FCAFC14C2CF1A0645DC8116B55E34BD9CA049CDB60C27D914D676D0869D33E0DDBDBEB7F31DDF7BEEB59AC7D6A62F7F42DCDAC5C0B20D1E7BB4DB4589E21089E541766C4BDCCCA807C3825AF0EE7AACC7390F7A8B689A825F9AAEC2F644E24920E95FBFB117866D67387C0A46A730423A80CEFAC3D164A3AF5EE17D84FF2E7B783D1AC74362D483EDB69EDDA4365CEC01271172A08BA2C88FE98D47F52684CD7351ABE2958AF5D3EF796AEA4A5B5EDFBC9BF3081E4DADB42BCEE2A6477B7C599BB40051532EC96D0FFA2930BCF1D6B077F619C4247FF89842BE8B3D72E62C0A1B6702ABCA1C1656F2BA66EF804207EE0DE06E1E4299198ECDA8E5A96A245EE9B717D5A79F5478AE5B5BCCF8B8D3629EBCA8258A2F00D88A12A34FD0B0AA5EAD5A74783617E9109C8596F605DF1038702966175AD2367B5B9B1AD40B4D49ADD943FFFC22717BB13AFEBB8CBEB3A7B769A5BBEE0891E03916507A0FF8297C4A91F73A9D03774BD41ECA62701B0A1D15A20CD5B4E9C156A004047A0D1E57F593E6C5C3DE54FFB17A60912AF5A5659339CF9D6969D3AD72EFFCC3160D8B4039DD6143D8C77F0EDB668E44991E2819FB01935BA4DFB5D48E1D8601C8D4D8A17F7A6007C92D95565369A88E1E1CCF781766CE012605607A7F75030E3829CA5F0774BA2F5F57C62FFB9A7522FC152F64C4862CC0C9E49A10B0013F19205E3DE1BFFB88CD76228B101180429B2CD679872E53C573BAACE27610F291FA2C021B0E5D1814A23ED34BD3190E3F6A2B6CCFFEF42EE2F0B5C669B6D23E7BC699D8E785A8436A852D6E8503C8165C27362F246BC26546D5CDEBD5E5C9C268ADA0A3ABAE1D7CD250BFC59CBA4B500D9118356AB49316D7C24AF1E1673E4970834132C5134F2F1B59C45ADD894935211F8026C714B0DD6B2C2DB08D3FFA5A347A3206BFA8D9F8F49A332912FA4DDA18B1301D004BBD6DFAB19DA9FB4F851E6622F99F62FD6008DAD1C03353B619646CC869A8396914D7B7D0065CC4A3539CCB833CCD62507DEAAE15A3A49D1ED997E53A86EBCF08C64FA9F724CDFA0F4D24DC8890F77793DC962BCC4EC48E1C2DB60C88CBB23E5E9D046AEF98341EBD2D30260CE8B318894C1E276EB7849FD777271B6471E716642DF70BDEAB121B03CBF901A171127E448F7E34C161D015BC661063156B702A5B08FE53A1899DC650C37ABB75F8BC4F0E2F03E84D6A7A2E882DE68BB78022F771EC6433D540912358E185AF67DBFC36713707B4DC0FDD6FD2EC615BEC33BE08C8C9E9E436BEB31FFF5EACA3F2661E64A0AB24D0D8B80271C5C658F5D224F98DA322FC68A21D3E547F0F4EC78566C172BE2683993EE8AE09920A412B04905D54AEDB5D92CB257E113AB3D4C4C1CD47DADDC09A00417D2E4A9923E5BD8EDAF73E4B89831ECDA7BF8299AA149383082CF1B0AE388063E115836AD8B1DFB9E6A1C9D254F02DB05D5099D6994EA253605DACC9A5AB52324324AB3B645CEC06C6F57514D2D03A4DB3474EF58EB37C86D27D2598DC58CFD2371A18D0D5EF241F1E5F5B100FEDC33B5677CED61B3DD091C5AA1252B1E681CBFC124CBBDBF5CAA841235296009AA08CD067EEFB12E403027DB735AC59231D6E1C068D180ACA2F3C8BC0D2ED552BC4F0AC5B5A401F52C7D66BA6D7E50EA96E66CFBFAE392840870720D14A4698E05E741605BFBE7EECD1B03657A10B180E253D23AA6750F1EAA6328F40A6864A30D2082C8CBB4AD86113C205CFCFBB93BB80108D63BF2CF7432EB1632D37441A92FB5953813CD740715C2D14EBB2B6D569CECD0AA2F3D4D681AF6EB9CCDFCA85E72A3B8DCAD00960154D350FAD1046F4A1C3893B0AD1B261BF669650C62A0EC134DA899B0136CABBCEFB31D9DF32D51B929148836200F9D51AE7EFCCB7C113B2DC8891F0593A464CC9906DCD18436366DEE53E87BE3153A241742FDF35EAEF168961400E150246DA42F8BF9804DEBFD51DEB5B4FE1681E44FFF181CE44D71A6204BFAD321B3ECFDDABC3DEE87D2C33C7AA2AD6B9C78E034A1E19F255400FC032AB7AFA02A002B9603EF7CA090117108183C49D5436FFBC7B471754915F5D9CC154FBAE4A9A9F0928A50C06020181DA8ADFCF371EF51903ACD6FD56EDFE624FEE35A63BDE5CBCA7DC3308176E599E3B95D7F137E9DE519B417661AF3DF7568FD76A1D34A8EB21038A23B9C62E5E46DA52DEC95EBF680CF8BE166CB674D65682BEE3FE368F082DC4F368738F83E2D333EA1DEE7B2A6F815403897F5AD6C1E710BD46EEFD5D743B79EDF135B0451A18FD60070278D852C302D0D026C2F2BEDE0EBB9D016F9B817D90914F1E3F875259B80D1DF60C28AC231155377D3A2341C4AC4A871857263B0C2DA6FAD157DB9F85CE3ABCD6F769F46249BAB9753339B2076C23549A68F5F29F8A74BA874DA2806D7E4EC1F61BCA6E11C2E15EA64E8728D9B9ED08246A31DF3087F8394A9D925551F4601AC957DA056FAD48919B10951E5CE56217B11C6DC89C25F2DD06095A820BF63E4B53CF80EA8C836062822A59BD726A19BE405854E232BC0D6DF7F9315793B89E9E10D00E9C48698328B170B9A7F95B2ED96CF0CE99E0D1F18D1C73E6545C8E9F717F722A07286025AC8DBD6C2567E21DB5968BB4D7F33A49079B2D4C3956508E58D812F687A7E4FF07065BA76846E70FB42733C56D948559E50CBAA00E1503D1EF447117994EB8FF0BCACA06F91FF312351632CD6755D0703A7E3B0DA03C37B98159078DC9B8F4CF17659B0773F0501E2BF177F882FD017FE74CF9C34A6F013D44C7D2986E9CD29D444B98E26584942747EAA79949EF3C6724A218DA9D820E68C62B64293EB1468E5CEF3A9BA007D5345EE1E5251E7075B84EE3B060B1E9AF2843AE46B4681753322D7906A6E849368EBE27A3C98F9BA0FC74D3CB472D511A78B50BACA9850C4E59620B35318B8978F697D79439E2E2A30BC41C67F41BFAFC6B9F8D8C2D8FFE8EBDC3910EAD15F01CD2B1A9571C02AE0FA9189A50CAF1D6864AF684FF0C9F05E0E8830A49BFA0872C92EA8F6D9445258EDB6FDCB437601B4EFA9CBE3AC1390995FE8BDC1D54073B16DF60018E904F2D23E029CEC4A4DE94A356CB99A44F2F314B9030683CA19AB7402701E8C4225BD284BA1166C3B181701F9A47B6C999D69AA5AB0"""), +02b250a84d15d015d65daf64921d441de7eaced5dae8d5ed5aaae0780710cc6f297bde76b46a47751c9af90b775ee5fb60558c3223e3eb5732b02721aaf4b2c571e7ef940126874e4da1e3caf1cc2ad7e27ce78891f1291341fdee7cb3956ab7ea4619840bd86c7f9dfea16dfe4183317150514ae0802275ffa49f6024b73fe8647141425335708465313201426464485346242381251600248884382713606716557375714102105768868264738542155467388816816356812542627664178831841037254605688411724580237205731280866143526825234680318656422704153533366183723757466871843688178028881525836875501828568435457286665223064636185645230082113325530524164585450807060828648444577380467366336754361347002616478552715650545343028378024652505823347436461673212376362234025530852856734378445453462845284101853812575565581884827462217026026422104812154576826272426053254068887115864026255272878171100133062131322881708327412284661110206142314411622224337587412032420350668587700242526761482182726675778500830622782044207773116013105023034233776328272350126302720568518583358656451354230083043841277280712565820402201860064335052181175517311735442231750885473485037215718385878270138340154607044703158207867761262843151363863357713438131822607823220673301000044571035402768713538116316681661333581683446254512203172240767614876605304851065554516305534873744587532285306102132174272346747240832551816548184855245064521871825764413883184880638014732810482403611487478652300457226475201288323730148184350722032842227130834781121602654604023710282810767482168615127440306717714253337676650252810422380412017358174362723207845211345873075406185684783381847626578275162801521336142056152170155712241310876237617136086741136380504866038451845470225151278835071185512660605346805647733377213630110431352442082411744260720818165866163256467725736467210364865838535371781843306701265611455343258201250377030186530054148020488730682653287712420076332033632152360007738566311722306842342001442552108785228736068105822832556448320553027240817753888583045860088518418735447717834455361718663826710688326265670546627753121815634362520041561353322020182806804003170603630646666735317632666212644884747232226042203107541782711326203571075272838712027837538612884105214213440255641088764071225378263327161071701133325304617456360706381304876424815454081020463654588185224521206112700043112564040383368163743670720762520847703261453336085324624132272682450408103756773710773186063277457057200638057521356383470147541687564530335405582586576663835354166674556028404827843742364212470042005558685247530877324355223572703600740553684760470530433178478246407657755282728728664872333848341350211277700011176401760584128238436637505138325505065217756818608062404186640767275603751648614303125612236426720624257485313257806504351724443061164254862845182170346255843504017541208163705313707842235716441111165511437066602366003214233060621717318057200645070765311025637234215854421157547802133221647713605385536202724237457842541827665838172167350548151224528361420224511555686218886503218704567755513515188462180482327014724401365004608425761256824684371031461705077834160654441852347634061406138085734353c75788bc566b064f5526de67e27b5f64a800d39cb62e3aff6ffe4617aaf109673efda26bbf69d235d5ce4a5b9d07c36b392cb04a53fa09456c88242b54e4e96f3b72447d6216178506c1f380b2dc277ff6d09613d7ee8aba57fd05a35a69b850ee29a90c857e06b63e904e73bcdf2908c8940598f4bd78b1b642879c8f635c908f7653df743c94d8482f2f727f9fe18bc78a590bd0985fdd040f7b879e2fe8858bfb442890e584c3fd5234529e2852ef752edd0e24dccffd1ecd9f78e3fe754339e1fea97d49652dceb41d3b7209558c860d82f25df260d8a482b3061dc1161ac6b181a4c2bc1a5b54616d0b65744966636ae1ec8bd61c7d7432cf5c41ddefa21b2d84b3b65208d13095cda462cbb08a9d4cf071fee7b6dffde22532405dad2e96e6b5066af20abb7a6a58c5d656774354dd504cc795552f8c2677730e31ee16f39f9a19351be7fb01716b121298da000653be35f50ddb3e7babee81b455eb30e7cbdd4319ea1af95c5ca3980dad25fa11fd69561ac94729e63d2878209ec3fad599a52f742b1ad9fd58dda60ea1ad7b4df59629a6559cf2999b7138510e14a55ac0bd242e92d12f989254d5135736653be42f86c004ad17025a0a234ba21c0e9d9721b46396d5e9a9b95d3007e59a5673d28d3935bad4d58fed72920f160af1853c624181ae74349a914cbfdc01a50e6ec008263f70fbefe9a939e1ac02f370545237a31abf3edfcd0bf395066a1349a99ea2c1cee48d46ede993a300253634820e60cb6340aa1da98a83178696d21c1e701f92133ea8c1ecbd7dd199cdd7e6809197978f40da4c8d22d1f459a8fd7baa08ccc7c5e16951bd523c84181e3d7fee55c8b1544068af3d3cfa6bf545cff8b7207bc288fc6ce3e6db3404a2e5c85005a515881f4103084128e29858c3fe94fa2f01cceff445d7b57f0d8cd12a983ebfa0b5c857c9fc1e37220f82a2df00043867c6fcaf3cd16cb549f4239fc42da69fc35ff58affeb5d4013ef14531e7a6fa437b910989e7f5a75009023702c1380467854974acf722090a7a8b7721941501a34365fb1baeb02ebf3b9c27c04615c2cbe5ac506c69d0c581681d2bd3f8b8f8af00e34ab4e64f21b75bb443c41edb3909c0f5b899df77ea4d4e0d9f3bf12cdc91c010e94d74e1636b0e90c47f1adb2e6f31dbaea300bc9e3604e81044dc4c00a0ed3883682415099f8297a0499fae7d26a0c7017e3abbb8211b5b5dfb24bebb37b1e1dfb9c3de36eb45bf2e0e9fc6faba5db70adceb53ed5ddac5e5f097e6b97a8a1f328e08e0f242316053b163bc950a065b2ea29996e1978dafe0d35263ed72d3d2748f0e289c41d0245a92acc3f06fe4704fd5df117d02350f01cebf300fd19be1c710b85b956c75707840c24183e28a4b455a3bc804b1cf4e71209086efd7f4ee877f341df27ea2842be106bdc8c57b86e127a359b3a26fc148f754e8ca99823d9055b45572f51417b0e89ef34c1e36d4c6d9fd2fdbda0c2d084760583b8afd08e5f25944fd3133fe0fc6a446b2bcf51e7d3473f498ddd4d50c4929c164ada3149236e0d9ad31bd14bc0ffea2ca972c3e7cd2339eb727fdd73b00a958729b9ee58da1a0057483268d5c0992bd0c49a5272695fbdabea68860b4ee535ba1c94fcaae8d74df85fff8e8e5f8146147fb7d0cf1c267981019661db028779578d772c5d2bde7574db97569b9cadcf0eeff8d4226f687f5d1e65b209e5a9ac2941ce6c26c2c0dde60a8dd76dcf124fe32f7665af15d86ce0db8aa4e0e662c6d1f6d319869f1dc7e51a4cca6f3af028e11a837fc4aea7b00f2cfc52e71cb126944f1a7599f3945348a828c6106fffb5d88ce5a234cb6e83f0a2bd3b63a7680f69ab58970a32275a2aff8dcfc9ecb1e1dae60c3d57dab0f9d5ce5420d5af282e025ce51e7130b86a88a209ceaf9a351ec039c9f1948521450ade546aa06a2a7f77c59dabd381b688980731d4fc7754bb9ef99ab175674ac3de181d5c5b21a22a1d2a54ef81566f2c2d157e68b0cd76a1c67896a12a933c0839c7b1ab3dfbc042e426be112b988752cee46cb78c746f0f2f7c5b77a229441b9f338fd34c7e882eccf38c9b0107b9409bce97194ac94c5e26f5c3b09a9ebd0d6ba206ba8a06291b4e4dffc1511c7a8b8e15afaeb5f3c96c0473d23d693b07435d6d2668d67ac57957def609df4ec6e40edc6fdf2251af26a0b023e7236e4c9b1b5b8340c19d791301dc06611c988e8f1d30dc62232c7ffade76b31efd49c978c2ec271f1a2500e5d48b056c3dcf367fb3ef7d4574154c9e51001fc0428ebe89180a68885e0e3ffc47e273bd802874d876c9b8bb1da540e3779b1a1069880fc2b5db177cac551d70a780c4c24fe90b9f252734d0df53559ea363f88101d584dab86977bd9e643dec35a6b98127aabddbfb60f42dbd5fc83e0ea6fe8dd3974f140fd5aebe7f96afaab7f16c49518aed0711e8dbe67b222029c3ba237a9058d09cd740c91e11ae8fb0a343b85d3330ad680080e52f9c7a67cb27c3d6f9f2a8b69c0a65b27870d23987414c968652475896d420f13ce0f511d394774b92a09dab3c89770d0e30fd56055dcc88b6b25b6f42a30f72e37fe2990c4b2faea18bd9f77d0bb712ccd2635ad98d5051ee593f82b2942c520b64997c2271621c335df8a36b4564ca3f80b02b3b6aa0f5317f7d4062b8c890ffe003be32db5607333fef37fd415a37fc7e987ffbb305d96a6bd856d09eaf7978b9f8343c340c477927d82727e91110efdf462132ae09b40101a3c26e9657b777e74ecec165986fd1f392e5c5ef1500d5e98cbb3440075734d0fd38d05ced139589b1a42a1d32de2014cfcfe5b32ac85473d7a877978edf5535c93a2e447f76972ca0d9fa1011d6eb55953ad22e67623cf59ddb2e1acee6c0cd762b565d03e547fe26eef6eba891de2599c1b0825fe70f2b0806959947ee2e956537b7840d982492aa295cfbcd3668203a3d02de4ef54f44e82baadfc4efc50ef42dc005b3dd186851ff44003b74bc48ae4b8c8a431d03af1cd23198e4a8e2da45d0b134133dbd124dccd3a269d64439e79753c4b1074b27a6b99b0339f5630158641c07001493864268ab8409ca6a986f8e7353f0e1cab155ffc60f6f8a70db47ab74d16e271c0e669c2c8c4630470d1397aa40c3040f93fad09033413d96ccc2b1f8b933c7c4d215000e5c4e7c6dcfcb4519e59122a80506b96a4a00dbfc7c02fc29a3360feb00e1f5cbb999f773c1de0f6da976c62b5ef787a3c08f07db51ffceac046ea9dd8f5cdd22eaf7c2ca3be7d410dd87a477df1a8838eab8ef72ea38e5d99c594b57c2f79a831db704c393c29c9659db0dd1082c8df0130b8b0760aee0685a289d8dcdf526f3bac8509cacdb96625af6339664dde755e74fc8acba8b6dcb57d79beba260446e6cc33ab2c27263232db07ead25fae4b2548f652cc193f8a0e93ef835e15aeb18e401e3875ba4b82fac32cab00b3b4abe14a8bdd235971fcfaa8b5852152f0b"""), TestUtils.hexDecode(""" 320D1B2976A4A4673900C7B75B23EDBC25B9AE867FBB79B55B29B3780EAE8C159A3AFAA47CF1D9E452CAA8EDDA3304BBAC47EFDCF96CE92DB1981A5088F731E1EDA1EA5FDE9A031595A8F268E92B4D75793C6F408F79B78599D93E80066F8C4432911828A87EF71C877F55B1F18207F01820C0153B647205CA93DDD6B78B94EB59E3EAF01B66953951ABA4027F811877B0F60C9A5AE6281D82348E3EB749C82C81D53309F9B7E624BB1BFC6382F43A58D1951F7FB716C08DEDE4A8028B50544D0F26F7B9DAEA0CD075C3B11B7315022A37198F0C96D752798E0EF406875CE86C367079841F717261A2B6570A8F4F9BE1EA305E73BC8BBD88AB162B4D4BAE86CCCD406A0FF6ED5A968D4C985460FD8FBA5B3FB40E29B6ACA07F70717A0700AD3A0BB7081E09F7219F3F8829692C3DF91C90334DF9E89284D65F7406188C9A1EB7B5C491591A20EDA9399DA1AE8C0C158588FE1426B763FE9D11223FF7A05A3DE036B67541C2811AA459045CE73096F89E6BA672CA7A546D2B0554DB35C547AD9585D14485AA812BFBC88F7B248E03F2EC57043F4DEFC2B27A3B20C2EE7CE334D428EAEB228350A3ABF4628C2DCFA84BC7435818F91CD67F70F3C7D54E2C205E55BC4ACCDACB354470FD5C246F32A542106EEE0EDB38F01FF5C4B657C7C1A00718D2BFD311B8BAB6523351E93CCB44274B8F96EE343830148F5C8594818777C1E798EFB45AF1D2A75D22470B4D7F7C7A5938DF3F8288A0088719C4E36018D9993F9E69B8469E5F2ACF1977D441B82E5340E5AD5B21B66051513553BA1BA1C1D5F788C47CD3BC60079300F6E3D9F13EDAD4DF8521EDD022031A3D74A6A5F32AC6FC51C67F920233C5079A2B44BA7B8EC6DCF9AD4667BD26BD07567E078267A1BF44B15E68B71AD38226EDDF138D2A599944F70D47B26F775BB97D9966845AB3E6AEB96E1414D3BDE94160B6DF19E03BA1BD0361354E5078B3C5733B740314E2DCCCF8F4C9CB179DA62D5C982B223CCEF5F29D7B673680DFA2823A2BB279EA45D98CD91BE7D52E3E386B98B62DF3FAEDF025B55F49EE6FB5E8DFC9F70A4F093EE3898B25102CF3AA52E669D6EC69BF6C79457BBBB7CECF65B1E948DA808025A242841FEC6073326BE16C2D1953209F31BA4A772FF24BC30376EB994398D4177FFFBCF78C9A79B7F1746D077AD146514A2DE0AF9800255F3A11BA661765A7D8E8E7FE5FA46BCD1269E278555186D4BDDD03FEEB70BDFF7E5F616259ACE39969CABE8D4F8F23544918516C977F84C09D6A6749B1CE719676378E82F9B4E563D67AF7D911233F2527B5CC5D0733360CE15A173F10B91360A3CFB08EB44A09157559A0CE8B661AB4A97803C52F156627C642CD02CA5BBC7648833F2CD7E99D2A7AFB736E5AFC4FAE5DE19ACD2F5CE3E3FC887852758411E8C7FBCADB1578964445332113F963AF3E944286DC448471125E55A46D2DE35E9C0F6DD10A3BE4F1E4BDDE51A16F4239A1F6A535D3202055990606C0065C542297D490553204A6E3CA16A7FC9A1D77191E5C01C1507A332C659FD6B11FAE088BBA796F18886195A2B8F5B0064D85F56FB7256F0FE70E9C06ED18B7C8A75ED97A1DF482908D2E3E8D6BE8D0EC8020451C687D10F829257F3D09FC47C7EF008B89E2312792A25EEDC71E9835674CA50235E0A6C832E7BBAB458725EE7BF65D26A0501C91835625C330B0F8B4D46A0762F7773D2415A0DCA573B47EB8658F9EBFD26D9F6EAE9D7A7304BC690F8D2F60C33F8A7D19B52F9340BFCB2FFDC92A7F9ABF85E3352E46ED7591F354A9E19B70A3B247E3E4295E45B6A2CEB59B120B6758654BAAFED2120B226FA778FAE5350E756741093083E4E56A84B64739695C1C09EE39DEEF11D7E5BB7866C90FC9C96CEA071FF82F145592443BBCD6B7CE848839B641C4522016945F711E86152820275A6E16BDF296D34AB38CFF06A63756DAFF7BF230F024DA00C4128F025F091F4341620E0EA883042BE731E82D21DBA6EE737D90346B6189697CBF41F7C2BA7C9CBA20E14D26CA578FB05E92798D57C0060951BDDCA5D96322AF35D80013B48A79AB7684E1E1B040315A350DCF84389E54C054AC4C3428123E01C2FD66FBB2C5BE2D16B22BAB805AB59DF205B71764E4AC9BD4B2D872B8905DA230623C65DD235FEC253468E53928722D1F04C486B46E63FE63441F11B1E3617E9765D4F388D4A2B68B6C86C8E20FE0F3C48A561A0FF5070455C43A7FDAEB58ACFD4BF51A1C37B7751ED37BBC73B9C29DC4FAFD0A8F5FC98C7FF02B404AC08A0728FA82A5ADA4EDC195E679D88187F58004844065F281A67FF0A2BE0AF94D5C97ACFD43683AC721045FEF8C36DEBA2E3EFA248DA65837046B62BD6CCEA84CB1211C5893B0C5F0A5922A989CF7ED093D5D706657AA6E79EF3FAD0959DF594B9CFBE779"""), TestUtils.hexDecode(""" -84D8CFC8120CB598A6A1CED91FEAD8FFC224C59781A421E85F7A3309F74877B526A3A2576A41A17D71229A5864953B5591878A53BA64C10E88A4F77811D5641E03E445B7BC3AAD9526EC4ED3604A371D1170618F672520C76B18148D3895386C1B9ED1746E0977C32DA44425B4737668BAB427F516B4552F5F11EC62A824FFF1EE50F0F03E01E7412CDE699F8A135D9845C7F1C4D33B806527574920AF2381C4AFA8F7E0673D1D76F6D03BBB5C3BC027ADC84B7D34DFB4DAF2D9BAAA9AAD4D443B195F350DD83A96CA96DCFD2673AF4B3425FEF1928085FAFC728DAB0374CCB14FA411A5FA2F77308BD43D44DF732E0984F7076CCDF6C2C42D0876166CC47050983FEF8800160933B87733C0B766F013947382A3593DE93F604A9A5DDA9BA4EF09954EFC9A8E6C0D90454B7F5C79140206204091D82923054A5D7BC76BA2D8BB3B17A7BCD027209965E125CC8DA21C4EBDBB4E84C342735F4C15705261CD9055FB4FA98309B45C91B92DBE2872D6F95B83243F6F92533C8E52EDB05147AD030A7ED059A3D6E6645EACFFBE84387C88AF178EBBA7ACE86F8BED1F18C04B1DB3F81721CB005D92DAD11E3D03418D3319CFDC4FC31E41917D3B34B3ACC7DB8E4B1D77884F97AAE2D71B202623F95308609A890942936E0740F53A48D036CF3991047F98CAC74E8B753779AA1EC926CF23886E0F7088EC0F1FB6B0D3F8FE587BF56B00116E84FC8D50D663B542B096186CCDEE2C04CFEC253EB84CAA2CFCE5104B667EAA7ACC31FB1D91C16DABF1A5D60704F46AC26B2E6EE4F93817824714D472FDB8407B32622562757F2F845731F5525FDD975472829D1D98C47B8B2A74BA72756B807A0DF17F4095508D4944F4F5CA1447B056E952B0A49AC3FBEDEDB06967A27E452966A6EC426EBE72BCE9D73FEF60C2B7BE7427DA1890A56F2D88F744DCE406BBDFE360D7C08F71016D2A84607F655A862C0C9020550E1FB87C45B85FC1501EF062DBEC20A7256904F9D5309191536A8814E4DBCCA28C40F34897A49A98AFB645F3EF246E2CDF4DF43070E8E61377B6D70B146F955A4EFCC98BAEBC3F1C621810D796D7B1BA0E9A441E56DCCA92AF85CA2834AE49207ED3B36E10178A7DA4921AD35DCFE3C4FA522D138E015D2447A3DCD35A25772C3B1439C871745844E05D5A266AC1C7253935FC43B6EE1DA7988C0D1BCB775ACCD20DACF4CBAA0671171337BB71E7D95A625F1BB66E3298BD5B8130BACE336B34C3756F62A0932FACA9AC3BAECE59D77D79F85AC4582E527D3AD47D230B1AF26833EDF2968DE208553B3167D7185CF60B4B4C08A0587496B56D9133BBF3513C20EB29A334290C46FB8C4461E81DCAA82D2413F8522DD889A4189306AE720736C875EB797E794839DE3619DCB6AD8A548CE43EF71AA16559350CDDE6218D044A059A8BB4D9826503539306469BE45FDAF3917B0A3A6450DD11BE8EF9F59DB8BFF8A337155A63CD20910EF598B208C14A2774D2FC55301F9CD3C8FB73DC5C1D30CB072D7E098B92D6ACE1BA78B3A10168CA4E8C1D44D95052AB5C1A7439A99D98C50A924ECEEECABD1437E4DEA5E7BB83AA5A3FDE2C98E019749EE0AFCA2681EC2C799C69F581859B28D2D346EF2FB97102A69F030B6F53F21FD655EC0F5CB34B3D363586148C443167C6CA47DE98835DBA80A092B9410B26BD023DA9E053981898215FFA735599AD0DEE853D374D6BCF0A0171FA56459C4536A7D2FF8DE6EA0C362C157D594101F9A860B800E5307DA8411E0E1468BF025092CBD1C607D9780CA3DCF070F5D949BFDE60E0BCF8267AFB9E04D5C2CC339CDCB1876C818CFE60F89F78681A8E82D36F26FE6260AE1A9E74355C0049C84C39A0333C01E77D1AE8E87F6BC96B0EF90B825188F784859F5390989C212E5CC5B829FA184E5BCA76B0B402195F4EC532931C788416811A029F492CF5B2D633F06ACD8104155D947E88AC08CAE86DF2F64F79E3AF8C82B9FF3834875DF69F1D381971003E0771F64FB343FFAE807C9C0D4A0273EFC11AF203EADE2D9F2682C918E2662EF2D6AE1B6E8A397B3FB62130BD629E315C59D1F0EADCA1BAC8CB6F067F10F6B13D70F70C3881E8382F20026746C6175F14A2331FAD83ABF256734FF7A970495B1F6B5B1CB2505B621D406B944BB5CDCE22BD9E88FBFD41F8B49C794B0022A456493D411B1B8F59D6A52E7B9CA786814F215C39F0A4D53285FA10097C151293054632C326E210110CE3CD03B7432CE2B1133FDEAC806CAEFB45A37CFC12F98AD0BF76ACE2C347ABA12A77D5DFDF6658C2228304FCD265653894C6696AB17E8103A8E23C397DB684BF632FAFEBE420B3EC111C08BE7DF73A7F763A82F01B120D326A98E92EE34144CB6C7ED15472F2C860D25A6739D925734C2CB6EE02198E96DA851860489A5F9C056C5AA2B5A90D31E7E115F32EB8285339D96124D3830F60E2E91715BA1C12856C1E25B8C59AFBE7B446F43F1B4154F8F786935E5402DC55E7BCAAE8ABADE43435DBD01F78BB882418BE11FF1893D54B5A83D6220F4E86D7CAF49E1B2EDFD6CEB82DCAD8A982BACD2DB15A66E7D0FB4652A920C339DA25B19D37715ECCF886D900D785E5E77E9AF53589DC5E785B2D5279AAE870F86E4701125FC316EFEC0D5CBC411D5ADAC374124521469ECD10832AA4257E2D8906358BF2788654DEB5D9E70798571B965376250C33706E78441465CC2563A9D2F70DA579FF7C4C715296F72562DFD9951120AEBD94D4F08212647F08B4871B6C4E31CB869A8CE1301DF60F88A517356E56189D61ED484C32718A9D37B6BD1FAB1FA39AA1147735BABEFD166712AAA617516D8CE2A984D90C73565ABF5DB9A46346FBE7AC465C81934F5D92735D30594C71AE239B2FF5C2DB72920E7A59B487DB9E363C594E34D9F250D7FA3E8DF4F8A07FEABF07D7BE68D6E03333B6947B1EC087F16C1DE3B0C5596043D4DD62770605DD89F11360A10F2320170084EFE8DA7E10E128D0E90D25623324F8B32839A96690CB33F6FF05E584C860251AA02CE00825B9F775F24E75AA788F98FA5BB7400E31362534EF1E8D310FDC0272F4E84C820E799007AA5351717BE6B06711BF9DED0CC7F96A0AFF9DC4BAF7F1F2D19BED2F24A7DD8DD1A171649F19B134C0F27CC458AEB79274DC155A9E3A267E200EBD328C16AC4892EEDC748BF522C0964E003793C0A6283528CD09456476677FB152B6DD0EBD86A410231191D86A0C4C19027F79F4615C665A75E7350CBA43D5A43A609F9C4155B7D2991250A6AA4912532B2081AE7ED0E72CA8982A5E16FAF25D622E060FF7C7639A1401B39BBADDEF2D1BC3E600ADE38A5540015C6D99769175DA7948C1636FF28B8D739E65B0E3DD43D5F25853309CF5DA4722DB29184EDC0294BB966D023093BBB10FE6A9A17F8A37608FD3FEB1878C02068BFE295FB809DBA10046D57C50D1A5515A3F4099F98F8262DA6DA7E64C0A2B662DE9F58C7F0CBF6B95AFBF75708F3B70A73A7D30EEC7B2C897ED420275B1D3DA2B0D94D689E21166E3B42B942DA7566966C9C78BFA7C64A7D0CC3CE47213B2C1D3D0E75EE00AB186CEBF88BE2C1C042253F48E2642DF054EBECCD82A02DACF3CA849335AE09789A705D23C1B49ABA88BB60ECC05F70BF02B067470802447159456D4DBC7451E41D034306F3A40AA9280C63DC86D5ABE401B64B48293B49C3A4119A966F652CD00B32342CF603A3D02E8F829E97ABA53B035C3C72D2EAF8F9DBFBB83D61B5E13F721C719B3D6E963E68CD0A6FB792DEABFD08ED01ED50A407B4C3EA558BAD59A9EB0CF8D5501A75A11053DE46D2899323B2AEF99A6308D64ACDD681A256DEF931C7E5F488D8878950F0637D478BD665B9C8AD85816E3B8F9C586034E1DD2381BB2F8130CCAABEC2F43D455F5150F83F160F9E43DDD4247424ED273F31F07EA12099B0E5FC35998A6811C8CD1825F8A1687AF77836165DE0BA2438275DE291B65C90DA0CD5880F95C8C8CC0F256FD0B1A9F9209C659A031AACC5D0FE8B0DF5A4E9D9EFEF76ED7624E9ABD6361F0772ABE1CBD5F78FE6F872CE769A817F4F3195E65CCBC3FB2F9BA021023585EB4F43F471EF4307AF047142D79BDADC744EEAB4CFCF8FDC682462985F828A5CB69483076EF94D6C6634000BAC9B75529594261E3893F832DA297FA448EEB8D098166732671773CE215F777ED8B16C6511D47216BA200CB3082540D6323F9726BC4CBDC1A89D9698A49EFFC5B3928461746597F24991A5212547888DF1AA6F6BE3D1AB887190F3EECC6DC4E9B0B4E4672CED38B5DDBD3C00DF9461FD62637B3D7FCD361C41EEC7641024382C378F15BA8A14C1BE3E47C4301624C354EF8D10CD26E354385B7C477F355FFB8998E9AB2E2C0C2FB2E3E466A1971ADD49B31C6A6F1E9C0ED9348A337D995A08C65C1E58C950558A4139D3274872FEDACBBBF77B4EE9D2C54F9A6142AC8A2058C2EAD0606BB37A6B141CFD97C9780DDA16D54A5ECD9EAFC53576A00CCF909F3484B64E37AD1F63334F39B94EF033B647B68E1FBF3A0BFED69FD8877FC22C048D4C15A8282FC2B602D3B1021CA6B9A7E844B065C62B0CBD7FE328F9FB5DC23BCF50A11558290A8B5C1F642586C7A859194A0A7C2FDFE0F4352555C60637A86A6B1D800000000000000070C0F182430""") +c344d3409be7db98ef0a349092d4bfa68e022cdf72abd10851fb824519086e7cb35ae13a93132867d90ce67d9c99315a3c548f7bed393d9eb71231bd9cfd951c53cf8a7555c2e8899d7914549a5565d8531685c7a02b82f3b95f38fcfe9c24118358f4dc4b0bad89c5e169e8f71e97e5f874bc8dea40c70e9fb2322131eced692b164c011d04844f0cf95a663a90e0409f2b36d8d936613343f6078751a082056d1c077fff3c3e0bbf5a9edac10d8ee0be319df29a998e5a52f06dfd12c47eaf72a457b18c73bce7931b74f28e2b3ca2037f0711b8a4755a860fd79bff06218b965a1e1368128e3db4401bf37185421d4b080e20a017f9695feb484b7a4ec6623cf5f82d99d1e0a3873d380cc5ba715021cc8b24f0839d10eb2b1679098330d772a081bcb20ba8613bad19841b411cb84e4f9bce9449b5d1b79922733e0acaaaf3c518d316c63a51ec49f4a5f30671df7b36e3996201fc625c91ec7cb621b54f98bce47381bc062be82eebbbd2196fc8fb1f26405a80a1cba591820c6b90f9374406c97020e0d8bbc4cf71d5379d54e3412f69d19b59237669e1751355c1721d097f07a218214428348ccbc0c954ea7029dc6aeb605ed6fa8334206e230c39ed5a836664a6c0b848de5c6a219a63ff24264ee44ee5d9f068a41cfe62cfbf885a2bb4c71f17863f5172b9b4203e9e9f21e0e744807277cabd3094d2727d78f930ba8779af85026e45b809b8b3ff259dd8511981e7955924bc29d448a5175c7742b7a1bd7db170c55a9831631267789adf7952fcba1391fc4eaacb7c3429f43a2b634553d8fe47ad9f39f81e54b0461061f6f67ab6b72a25e99801616737e8687c738b45a8ff6f05f6b5a30c8d87f6bb4e2d4aa82ecf9f7ff4d1a6d6b5ba61661e8a75d4dec3daa6ac96c0abf7ac09da08efe3eb73ec0de8ff231078bac1cf98ee9ac6aff210ce15f8cdabb143ec77860bb090463c0e6b63c0b12249633510404cbedad4eb85641630cd131a7897b46443008e79edbcfe471d37159a27a9622bdd6e34c1943e0b5ccf35d8885a9d584f6a54cfe7b1b45162360b573fc19055f6ac05df20662026072faa0f0fbdcf4f9b7d89d77fa0a3ca7ea0d857d0d9b94e95a406bc039799ed56e076114dd9f7c8c028c97e2bb813d8862da972b069d7c1e251487472c291baa0c0a9c9f349f29091d8a4332a56084e11296d1c72b7014045ee584056e9822b113136ca9fc27b1487f64e4fae57b31df3e6e2728fdeddb4437a8257af982cd08fff4c4e6e9aa82067182290da938b3b969e5ef0d15717f0c34130cc2d9bd29d9a4ea6707c9a45830c66a2598d8678581d9a389bfad0e34c3cf45c3596aa986380458c5cffc1dc06c5e143952a211288ef0d67c7375f0d9f59ef10a55623af7b6d2faae4802882d09cafc9da95e7e0254b147fdadd9b8b28498d625e9b0603c9e7e0a710d34134e6b4d2e31003ba30acb30df03a913851d5191adde83fb0278aec64262de99b7ccb1c6ad5358651f336083f59089beb924db5af90be237520b5354ba63393c2514f2f5c815b694258cbd56cb7caa5de34986f214c566305163782b9a67db2f1e51c0172f757e3c8d9804cefb63df98d4297555aa95781e8c1114d5c53b06491b2c4463790030d2d28d159c071c081286071d95cf5fc624b69eda6b2cee5d84ba30ee0b4357eaf5429c26fbcc455357de8730f0b50aca059334ac5af33c7169208be3b060abad80a41d5a720e262075442b1f514958120dfd51927363fb0b43767f3bf4ba7bd2669f79d9ae38c8b244c9a1334f802e7295c1a5b2d236edb5ef8eab028dd2bd8fec9f0ded1dced5a352f55f4b502f5aa12a3131bccbc88a2dfe990cf2cef02ae787db30e8bfe26079bed383e363576ee704e2b2b3b6dc0254ed4039bd0155fafa471919703f632bd8623350cefdcdad074337d5ea637a95f995141b21fef74b93be8fa18ada82dca3bb6ebbca0544d790ca07c42086bc4908a4dfded5d0c09e8c8d4382dd30fd6c586d5c379fdfb11f69faef1dbf46b0b03432c0b9967e6c7417b2488aa22682c5ee0fe6a08e90d6740af02f131c5acb53fed64329f8f108f53d762736519923ab734654f968783dfe8d13d715e9db219ab7441fcb739fc75913b20334155dafe6b85f28512d71a02e463e8f58162a2075d301d4215c61164b5143f096decc998b006051752431e1d1d7d109f92c986c40d2a8f17ce6fe1c32c33631974e47c73b5512697f5e3fcafcab2a4f8b462685fcd5c19decaea96d45a7c3d35eb6b81d52d3d300f4f94f2f831e3412b12429b71b46253c83d849250072c035003b8f4c0c7376e502183848ab14ed9f8b6ed1c87d554223fba1bc99d1d065cbb945de8968fe41c161c301b3cfb9c181ef3bbc120cbef645da02c295d6ed66925802868bc8ac6b437550637e5a16d429dfa4b124c1f1045174507f706d3c01f9343ec58bf79e5611109530e2543ddfaa2fc0641c69ec8f3947b4350bef318a55998fbc25686a5e115c35db12a12e77c8dd43863c2c024745410a0fcf1560f1a902bacc961d931f793238684944140150a99f2894748d03a83e030ca52fd83fe43bb9b7fe43a9451f3850f92df5e242a1e75c3a101efa727667ac45164c35fe7143b4ca2119d76980506e8981c4990c8f391a0c9416647554db2c46256f3e56963bd4f7ef309914dedbd893fc6855caccaee377d70cdd54c64ccc3e3d1c0e197684fc692e9d64be1b07af246bf6d2e4f38d2e8844e01efdac0b24dfbaf32f08492a99b38486a8db4661dac565fd847d83993cefa810c42cabd357b3b1d5669afb73274be28d637d8c2de41305c33ea3569f865834effe4ba3cced51fa00ea3dd7f442894bb2ef9a92378ea447fa6af9ab8b3fc01ac45c7221981471aa121d59e77a1d472906c437004ebbb168cca7f518145494516b1d3a1aaec164e5f73a96c244afe367943eca32c4e61bb5766122f1f19e9768c4eec5d76f3b10376191c5d42005a99eef0fe332cf5cfd4ba59f725bd50916348b5704943cd5d14bfa826630a9529744148d9ebac15a84cbf6490be826ea51fd42e505fe9e74a13ec9a1ad546c8c22e8d498ee7a0dd75387240c3d166fcce4d957fdaa53d0573ed995a229e2744bd8493d44d774910625310b4edb8e46ae665c40599c7b48058f104199ea6ce1070a37fcb383ce4e2af436185c4a3f20e186a25b8dbf4dfbad8304125e186eb76b6f6ceb7fdc51ed324272945e44b0bf11ce27b5b6b683fb4efb7e168ff13e46f1f0f4a136827d8d56cc6fed0a9fc8a2abc8f5c06d1dc0de33042c5b840c6d66a8f27331645a87fa6710f9f057685fe00247cb7f12b229a43f539f9c4a6727a8897c69d8ade9c2af6538c594699a9f428a998bc1e8d11adacba134649315ad51f73c1bdc11d8e5eaca86a138ad934b30b376d754bafb3fca13963eb800818592eca6807867d9bd23ec931a343776da195c8d43830028cf4328701faf124a19beaa44293e797c2bb89b2c9db45c7d3785a0cf5c9fc783d727da3a3f20f5366d9f39bf49bd1ef9811dcd74804716f82c0afe9a73c88138bb23babcf5b7acc87f5dbdc0ce1e39540a5e5979ced0aacc221362e2a18a4af86f34f9b2c03a21dd21f70ffd443be4bab058acac295aebc452b4fd32ea5750f4a2fe6260c30eea5bff0fa17f25c3dabe3b58fa72f75cbfc18a84e2ea3d568cf6e66e401ec82753652f44e9410bbc435721a10da1eec613e71f04023f3121df6b45316795f110c81ec9124b9a5568c08041eef364ee59b4eed261f3edd834741845ece57fc5ad1f50d183d03c0aadd61eddb2f13c46093082182b21d4bc5832081fee8c81c1d9a77f132e8e5e9f5a94650222dbe47f5d7f846b1e91d52f62609cf0420446b55ae4a96c2bafdab6a8793beedf7a7ee9f678a099996b6d6f8221427fc86e1a260d7426ebbfd7b9f3e0b9029907b00cf77409b24f73b7f21fd2030cdd4e36fc09322ff6176f49b6f3492076eb9de2d79f41316a202994871bf7ff96ab0cf94ea11ab959ebb4fbdef3813698b1c78e13f2422efa15198dba6af17ca9b2ad199f133076f9ffbe8496fd28e003575579d6f62c69a237c588ea8bbac99b32c43393b20112779db5f9989c04e9530af29a7cd959fa4eb1276c69d46a67ebe363d635aebe19452416e01db478ab32a32c6e95d43ed4693d51f4ded754c62f53524d4179dd05a102acb6e7057c63aba9c8664d9140f866a359f755ca2bb4b0e66b3794206bfb311535810a24a6256a8c0c79c4a87a8fd40bcb9bc23321fed6cef599deffa6994cad1bdb655eaf85d082cc1c626727918e63eb27521b6de4ef5857a2ea372f64409d4c6885d7eedc15c95aea623bf081991890b8d5673cc9ca26483d6b7bb88fa61b31a13f114923e7332eb2a52b9c42b7b341ac6495d1c4fe01f627350089daa8de8cb8b4c660ec9bb065ce689d965e14488e67976502337f1de27d825cb3e6f563312f1a3467e1d2b2628b5a3ebe401b6533f549263babe79b0ec66132bbde277a1b4b8d913b1c378e864d3c56820b6de08e3462882e72573e8ae08c64861669ab8e92b575c6e7fd5db3a698895d8dfef064b5fbfdef1f411373a788082a2bd0000000000000000000000000000000000000000060d141b1d23""") ), new SigGenTestCase( TestUtils.hexDecode(""" -05F78DFB8DD95ECCB19A4E223909896CC6A32086977EF3ED299269E51878BE84D29086725EBC30BAACD7C10F04AC9B3037B7407C63D36864E577A8FFBE89D9174A2ACC4183D106E7F478109F5ECC2160C0583253D7287E39F2BE1E1FF6DBC0127A322CA8E2BD20BA4419405CD8950831BAE2E4F854DCE2828025369A1FB3F07E77878741641453852638027541273502161744187110423466885282676035866631880680212377455761475822537381311428256306028053075841275812862151082114225553333632208035118820600216464008332253350051356421018671288648082042327826524064231463461787457445340458144872151441075521254341210228484201564136088803605035560122810660262424606074018703052055371555875382226471026530180032600112827753232300073074181386480534164225448647716638448527736082708564276203618062484286666008357240756656266712700838805173838263510506272540177577752234807311255185168734122463815356405123855254518275503443802574060346470206813526234734131654288881363708638820352751020216175724418860014818114623484543247618186431467841145500584206376100245427354377078068051005766127458621211151260165633001348137530712602370312371232020175626206103837672301778747622163741706566121434014071278363537881306583436007681866270754208381518840617617808075330388482526180736260681245127862565373032388826478887465858427858051220613172202211345601088467637001415045874412557332067277484377551504066843600063121066341371643283786784761068601064575354243720165161606071462467454388636873636233778021648671534367133507427605374074416722337133601751734478484212371667138687221813155227282016661347012087060844717657163652206587018728132833730304737025362757761315052144646422630627111723456313173844406042412780701303413724368817117576255854668574228750452553070204351788025621430144242371001323737372064343217801782040275037004610781844438384742255584167536370662184616027251211143638677564508151383860530708048252122840866600333828445206788217648545821445206684478670700853248527254603327501006210154518503008755220176074648684464420077608424316613061505360032376774670110586687775170411382701487278646233746321110574082140788743715263036142246810378474651821327267878687767558532332766770770556676145510857677602768584841218228625328357130763700187376638323351202458842267224561707545685515711742787471041306204421583620103716561184185104727138066730485156405743817162476012062163020146660802807525251031404783027088628746507335166655450455814243664167181412115564530746315868643783184442146216216845873256853767015455878677678280687482518218081546136488640838635431565180552472320787367186616811775854673275284425445068256835580334212418571666556783641407770327517431140237301214478304666154718470055040784840142143820856651337364886780162504570540561687240205801871073843068104004486611083157177770070276412274284501525030180108545680011733761885871352405735268564864488888408546532680830132441854774703851551130551311212088487888340480334438028463403314317118862855268314010187431362037387131230675578024177157366237440614241826465088416751852758868580542326571477612173575680005143247771436458011248538443205703184858134812623530080474087351382103253482864316815ED9377443018FCEB94C82DAFD2C91A64AA5FA118DFEF2C915FB5C1C06E09A9915755FDE25B00C2D6A8382A8F9BD031F4F9CB0CD25CC035F5D38EDFF23E27941C7F38A6E958A5D7569D234DBD2A94B296446F553CA82466AE1F49CE4863D68462FE22DD7CA41E3B5223878FA372DAB34237763BCC0B9BEAED3FD27AF301D4BF779178571DDC3EFCA493D98DC24DFE77536701B08DBB76E3759B237EA3A0F9496E8C7587288EF7192DEC95A60FC480B9E1F533592962DA075833478222BE8B378E63506364B78ACE0D27A5017D15D58C018EC843375A5B07887FD25E1C30C0075F944A9762E59C94359728B04C38E9997448263150BA6E69FE461EC1AEB5FA47AEAD3AE1848CA696060462D29F331C02F80D22D8E3BA79E63924D2D4D3BD901BD79076852FC0B02FBF48BE9F772FC3332BA583228E55EBE8EDA94884CCDF80D17654E27FECDD237C0EE61E8DD35B1CCE3C388DE759B1FB7C3D143A153DBC41D2FD2E9D0F754273C21C19F5F13A63A7DFC479FD64D5F5FD008DEF079292629032111D2B16AD8D61566A73DCF219397939669A3B219F648DF45D541E47FA70833A785045B71A606DD4DE82902DB7C1899D44FE0D2413F886374FD1C19EAC8132F37A3AD31F8BC6F9582D58A494DEE3372DBE3C32E10B18B787D8E4D3B6E9679EC94CA86BFC2B23B9B4F92C1BADB21D5E5A58A9ED0FAAC419B51C1993983B5A7F6694FBFD5F1AF15A10057C6AC46E7034072A1A5D26D63B67ADBD3771B7E78DE3BFB9F6D5CE594B285991BA243BA22B3B54453E6F5413A2CA1D9AE75FC1FEF7E31A7A3B7CB087CBCF3F08FC9C34B1670E7F6D5C32F165D3796D1C369E7C50E9A122C116A8279997B0578625912829142D95C43DEA2165E0D3F9313592C8982FC1E107052DE326109433DCFC45A1BF14846D1F8F146D154CD5AAF417449788DD7E6D470E7C70C7DF7D8A1B62A503B1D4188AAA5C32BEA44C9D849D3F8B5C91D1BF97F47D83DC0D063639F79B9F08DB24A13A06C1ECDBCF73CDAF7510CABA36B890BBF7DC241AFAF317C24026A6F6CDC8426D99C0F90A2F1944B797DD68B792AF00B15D0C78F8528F0E055FF01E73E455BD5162389E0FF178312AF5DABCBFCB28AA2C0091862A010484C0930E7D9B6D703399D40B4D83C996E4CC415525CC895EB460EADBEAA104D6251FADABAD74DCE9FBBEC08F9D0899BECB3D6FCD573FA9FB94D9D18C59C724F39F0157AD6C8C01449DD56F37110F68BCDE8C3F66CAAE7968A2FEF4B0B20A7CF41AD9D40266EAEAA0C21951ADB946B78A3ADF6E81AF6DA0ED92749B119936AC4C7B798DFAE058A5F509D90ECC08EDDC2ED7234D3BF28ACBC7235AA971E4A3744AC9D47221EF2730A18A5411C85B6AC8DFB2396AE770A5D1D960D7EDD4CA6D0F9FFF6AB257B22FD5DBB3835D05D060369F01C65E58E2C143AA4FAAA554928531B9BE2D0E2B6D9F0D32AD9C9A12DF38F72A21D2906AB17AA5934F08EF87B42E40E46DC1C35DCE85B0501F256DC439C2B3A332E37F3A4E400304A6ADDB09153A7FF7EB8760AF870C252EB258EB658512BD8EF92A89FCBB50CF6F76BEBC46C97AC9DDBAA7450CAB49B4190A8B39767F36597F89027EB3C09DDCFAFDAB286863890EF528EDD073AEABD6A7C9C3D04EBD1A3CA3197249E7DADC74CE737CA5CB5A3C010FDE6267AE82BF9B8AC6210EBDB68BC5597E10D98F6B5DEA2777512710C58694785F544E4D886CD8CBC8E6875BB61DA19BC7FCCD76547C4ED44A935FEDCA88155AC0E428EE506B1BDAB6F00063EC1EB0D3D91B6D9EDFB85E8F90C42D9B058EE1FE208A54A5A14E4983E9C06A7F549647EB8EEE92B3C9A0B54912DA9185C7AC272C2DD4615C07140772CCA6CC3044FC59F7271259491BC9469BC1DD07868D6463740387DFA7D2ADD1346D6BDA59435B84F6AFEB3BEF20B007F8CBAB2DF46BD171362B7F7AD541A645EE4E62A520324617DD097622EADD7DA6939812673AB6D8E5A25FCF00EDB519ED4877B13EB0E57E9AEFC8B63F22C0816E70CBCE0383D689706FDB45EFB6474A7F194D6603B745F4D85577F79387733EB0975D783D7DD3864BC89111E1273D6CF9122B43EDF7F6757E2CBCB6C8AA3C9923E3E6870F9FA92AC02DB2B52491A1EDABC9600CDD515C665DC88889762A2012332035055C896145EA883A5D4EC485BB24B1F659804B8F10FAFB1B4C619742EF4BC5EB665C48BE5F5C5093ABF4E9E6E43D8E4D7E15F7D38DA74B567E4017FDF540BCB9492CD35C2A3ACE4CE579282837A8B55ADA428C1D190BC77764A4E44369BF90F24CA2CF566F7394978F28E24689323FB8C5B2D688578A9E5A34305D0EFB970490CB172D6FE786F5565CE921D92A2573C302DC9CD0431F8ACC8E0F1A44B586257080347F933387385429199F4A53851076447C6D2114CAFDFDD13C92D8C300F26CFEBAE984D7A021E9B462D30D19618AA72C58FAFA0FF74CA67699992B502BA0EDA7C6CD2FECCE6B51D6C704308ADB4B86F2ADF28FC43F03807C5B7391B3163FDB66C6EB76A78799682BE26C536059BC179E8F89D87469A57899C1E18E03F16DD6B5AEF7420990DF22CF4D3E905E1B5B1027DAF56DBAC8E9E3A54BAFB28A8FA5A51CCCC0872AB53884563C0B7876F68A48F1F51B1AA350C93A23FAE59B6BE2F8088F58FB9FDD432C10FEB6C79F9422F0AC6DA4F8288A23D16546715EB6104CB0499E5FEB2225C97287C19BEF3279B3871D6AD522B30DD96BDFE4BACD75CB108BD622605FBC0BC6F2212D76D8B50E22F98E34B6C53F53AD9E48F11FCB77769537756D20BFFD1D775B42625E6E7C4EF65D7FB3EC718B5FC0094273B29487759E8010FC317CB0F9AF34836426A4BD2B79A3F48E0F38447D96DF0FCC545FB51DDD3C6B849FF33BE3F9A9EBDEE04B422B6E032E134B7772C6D3D4430C67BB2B1B0FED7C801F5A58F23E08E1735DB1AB32D66A66A7F60E2F98B811950CEAEF309D6A2476105E165A673A4F9F49A94FF751DDCAF839D58CA66A78FB5BBBDD80C5B87A6817D329E5747EB580A7B1670B3B7F52CB5FCD6AB51D48E7F0D91434F6ECD742DB8286C2134713E6FD638891DAFAE78DFB0550E76A8A54DBB1AD4434786084BF17BABE7711BC40943A6BE4D6F9886802A078B00937170AE765CB3F5F71BB792FE3F0DE18085C3F402079F491B14CF2DF6AAA588DDA39B69A5DD267C95465350B261064AAB109D1D8781B399F0E0885BF2C646452D54504BBF5D5322C6F4A3C25F4AD945EBF079CB58A84B9309C32EB6FC35E92F526179DAAAB3526382B8F02EE2AB9D102AEC8F250348228437DBDECBAC81776D4F4A0CB88E1F19CF6A10F48F72BACE1D21BB213014280B788D4760D8FA471F9C35A2509D3BD86C1F0E3E92A74417BBF01D1455B64DC6ACB49001442C55D1105874773ACEB0AC4839BFDB021E1B653BE09EED14DCB9216BE75F0E2B8E9BB3D2804864BB92A618926D568DE28952354A7CED0384A9D21203A68111929E0B0F34191162D722A01F8B55DEC3F9DDC9D0DFB3E"""), +2bd5cb469bc4c91a3b3064b58eac4e6e03a617650702c0d2d7a74874743bd42ccadfd0a0426a18eb3bd2cfd8725609ec1dd664876ea3166bdfa5661bf98aa6bd4dc43c4310e2e2aba9342cc140161769ae9a63b145fb51948db18bdb445b795e36e0b1dafbcea3f1511748327d816eaac6223285317767e6662cfdbe74165a1f837627263848874756877165276577221012676651444137680132351130784766788147465478471367074350475415218011258206321522104032260216358087115052487816640447746366553266721274514170003637258758343506047250725516568524230380681128162115337361701040586852051744264103454573305535062334537784484077656163074677272568625252463165155875317358360146115625063886554172373584244342527435771442357733353661235042676104117250321606683502032000304787780284453048403518686437812433703270542350835714767753404446076203235271085334487676035830264555553820638166783022256245427730457125514514141754877787346727386770507351017331511724787024054365575235864224380446106330453668340626638555373327516062516306886475621371718244701207532814635187371248030251086845214367337305121680057762817347221343477236268755411121538120032625527387087820444367451140486361827338170805820871463737404481676878720218775500220783387826711830344223526751174102542172057377317130427127801480471835257171264437133768081188782016312740871764452200326044135076454347426856278612352770234227783765776357757573058200813686182602844752021610350156033010746466432146177667445420481264340135175072877232526365606487634201345884304360040750110731501650471000248242232213628325476255740664880703348565832321588525453628717041246764467867301880535846172546126865811071742130263724618348008631416206332005206121853267247108855712233132683424345244848303807538204405258230042874387023163681814017812032137307221648277008410212678058052583746378836842645158534814724670837823578171856506780408155350888617676567180531567033882322162555145138678874828584823364454732222602030751015404558527231541350450340703321417116030531380476526278516178561184083623485516537445054173805185443648434260361525335872750562508727141471515701062834537455105224861345443200067381243725158316423820424705434846600327113226176138138454231433663300613423772776824764225234116254171433001668148037672821722303011538105181471258064724308067107564661085382384052651662161671371345002406584155285674885115884255623875833515644444012106045031335230435125421350485781633764533072382585016230120814462005013470878246287428846070527816201075813467457643587442707224786278733035472163083440581148234114732088143538867042226061853513505227741830721305557406052855436154702188382365521173365277022316072781138710386701325360744315647482770676701727178207307406733252332236826413631243466755010000556060201513176671172088364088733451430652141371747471387788002657666744184645502366471414202007085075162567246527800734147856021313101363062687280452240370150345431545834251037064708377637257784423423561853746000277450201775363821445037005416848448528210732571687768775128345304188263680432021232840435830262414877006657477861158627541208278123144738555315743158402874328317821771457820661201658137582861032041e31fdc3c1b5655d9e975489b7d89e8323046b49a6cf03abfbe1536a5ded60ff7c2f6a4623e6d40fcc62dd75bcc3ff33da3dbf4f21aa7cf1fb38ed42e330891963d504b03020f68a30bba4e6bc2a91d0be9a1a48553ba44d362ddc405f46c426c7342dd4f72694f49bf36fb98eea3ba0cfd5429733aed165610815437adab5aea371c1c82e9231023d2770da62d93941374d5e130e5cf7f57df615313fbd2fd93399b62f09d97e9b055b8cd8c179836416d27e6425c888b64d5d4343c6a5837740cab52c9271c928c3647af1a120e567f3b1c312eeba09002f3ae4e90e96f1fe80c005113d9bc1a1b7e755936a9fc22e670bd36a9077b263a7e286e8b0c57ef594927ab23d88441ce3b2a62ba3e95ca800bd30ea65d0c8a443bd060be70b49d2a1596f29ba16df338701ab6da24c06da858d8be565606e6b579ec8c1ff30a4819b04c83ce8b84018b26695e3e5715f11f9fe2427d0974ceb701b9695fad3cde0aed6d68c8649387cb9eb6ed4b7814e4ac262e44dbae89845e28b58c2b6372f74e8dedb43c4e68717a3d3007fe0e678e1627b3e3ff2a5e1cd2a1f6dfe2a43c736effb67060c08b2b000dc995cff9d47a8463861d088cfe609d21baf712adabce3a30c5c4eda380e61eff53a5341aef7fb5be2fef6c9ff5a03bbfd314eb43df88f20d40c8bf8ec86f4d268846e34585c2c7e7983d28a6136d1ef222ec3754a1ef0d2a155463275ab103bdb2d1a1087646ac0437b15b838c883f2b870fb1e324d20bcade9a80c08f306c2e7fda542f34a3fb242649203df14083cc9cd801e4a9576c60df4e601a477dbf9c1417deef0d0e8564980ccea153af41baf6c68ebb772a8377b222851a015351a748f5ad260fcec7bd9e3bd4651d08ab9475173c98f5846702bb68514d4a5e486e65b09f163b11d29b2293b127fad2703bc3e95925186b6c439c35e979a0163608900df4dc83f28d15582f20a7dd8b4a9c3fdf6cda6cc3c6b98b9c09b9823fe9be87ecff183701781933fcb4e1b877d2e722a2647b8e55e6adf0a498ccc382a27b0fbddb6bce5242ce1f1b0e47ae3f0a1c2a4c49898c56a3e9c49f4d53d3825e0948369f36b4c6b81be9b1c5bede763653f7a3967c9466a9b4dd0cc826d1ff276181bb770b9ce59871e906b5e3102ca3f6e567c6c275958442d66407b5f3a899814d07a0356d168596824db9c84850291cfc7cf119424949a778275deab8a5cba7926d07b82b6c6b296cb433bba7fb45b679c15a6f177562158f8c1a9e54df79cafcaa7bb6e002952250fe2d533bc27a9479bc03db36919d90ae4f074bf88da84e651cfeec8715c918ff605bd60c4bf3843816c7b30e11bab3537f14253f100646c7d0072998761d1122485f80b28bbd24fa0d53aff658202c42efe00385c778c611351d152b353e3265baf90808737271337310c0e8893fa16e9725386737b64ef5e41fb080b65102ec6197910700d309ca7f7643885163be8d9bde7580e591480f0de498c00b22b810f76e11b4b656df3611183c36d17c204e34c18f1d2e2946816506b68647b5cb4222b27499c4a66d3fbab7700a7e1f1419921a19f39a24dd5a905921e7d895f1289a0f07338cc2a72a50c95b2f8bdb3912929354d4945d4c327e6ce0779dd8b126ec891170f073fcfa03daef28f0e3a214224e683141199b25c31b0f47ad1c58e1b47994f2801829842b84dc5d583efecbc528181a39857dd19be0d3cfa07f3e63b358eac6c2786a1aea7ff5ead542985f42149a98a1ddb89ced1279dfbe56363946e27e8ce0046ac2244658c4ed3b97a18bea6c4e1caf48eaa7536c65b936af37fb3ae8f78adadd1588cfb42cbf14b9e30e0a9761fd8701953b3842da1d567b249a1eef29fd29f2d73e15b34eb4d1f11e0db7286303ae426ac2f84dbedf6ce07c1919f0205ff59f369132e27875a2657e6d560e74f8c8f3e5af044585f0272c1eaec7972aac43baaf68e884dd3f88d4ab66a471e4fccfdda4658068611e5f5c33756ddd38ee0023ad2faff603cb0f86659560d10e7845d5175a88c1eed5fc9f7beb33315d2eaf0273829b26ff6f3b99e31adc4752dc5cb651e8de0974ae5d07e38f08d7dea694b56a83c47731b0e14269b4f68cdfb66a5cd33b53fa01bb3f15660b7f21ac6bf82b69d8eefb52b75242e7a2879802bdbcfc3ef969ea12ea287a7a3cc17149b2271012b58d760e00e7b36269560a29cec00cef0d979366fac58fe69bd30e80c051d65268c7e8e50caf51edc9ba36825d7b3f9edaa2b2314bb62d0c244d78a52c4d5e2f3114fd1291bb25355a8cbc250931aacfc716617c884f74c2360fb383a04d5172ac24c7bb01ffe26801c7e20e4c35711dc0d4e9a22de14e047a45aee60d5cb4589aa53979b51a73f720966dd1c1d714af9e5179cae4e760b7a4598d8d46988777dbcc759effacda8075393de7403ef5c1d405572f8b49641799b26db4efd1f2c821b453c0704134a1215cffc835b5a63104cd0110d455902361ba484127cc84ea642405e73904b857e4c94467fe322108f5159eae46449c125ab62bf864c0daca0cb5ff09067b520c69c81ca2fcf59d2bb924ebb443296126198a0615867ceab2636b98f87495cb6f732868d29f27b6e1f4859aba4a83f172ce5e73385f075ff3c37c166cb360ea16dcfdb53c8d29159a65bbad099394bd63a5d3ebb2c46f003424eb81889090876b6ff0a69a18a438ce6989c465d5e32ee545558b75a28f51622831cafef18822100f2bc5b8e45e495b13ec7ee150c02112b70cbf245310344a6341072e48784f01cdae1cb885b1853de04c43121910ccf30c9c24f491e56db7538e99ac00bf0224eaee2e50fa9cdbd0679a500ca1d835ec1a129b42e88c11dd90f84e413d0db6a22a21d7c090d641c34807145bb0ee35fdd8348b75e045fd7e2136ae8bad14feeb2581e862d9ef964280f9ffdd2ac55ce4935f88858da06e683520c9be9aa447691e3bf37c0652b944f1b1bc458b6e67e3b760086e274089ca9177970a5906d45cb50862e5c30620be6943cd075c7babb86a2aa0bbd9fa06d5388239c2606edd34e729fd78a76b597af751cec41ca553300d0db0ee933239487493f606f6b8b5e2f49d87e061d56104444e23659da7a65e6bcfb2b767643183efe835889452e94149017dd16271f78d50cc74ca7e259e128f02f6beb925a9cd8fea3d11b105c11620c10954a744c65df3ed7ca978994b85d6ae53a89c675d58e805ecab90e575a9b553e3b85507a190a62b3e59389892ff078b0d5196469a2c4ef1edbfbf64ec4a917fff3f7361cdb7a31b360cd44a129db7fa091c3b87c89028e49d62dba7db65326ff9358dac88745b1be5975a6d519be7c9caf432cf876bf1463632bf4a9bdb67b1d6a16a7c89e2845af39e1a92c73aaaa39a917bcaeb3cd7b7804829a65eca1a885c08d381e4bbdc6b8792404e8bd273b2940c60613467e6e2756d4035681de14cd875ab004b4df747c4f6e0ae913717ec7054c37b253320e8991bb9a"""), TestUtils.hexDecode(""" C9ED9B897C34D7119115A0758332FE70D4A9E11FFB2D6A800AAE33F85FAC59E715AAD93BD79DC8D958079F3B5C2422F8FD1A1AF9406E8DA3297226440E30183051FC9AA52AFB8BEEA2228E88D193F231F2422977DDABE4AF4F0437628C6AFBE68F70CF4F56153A2691F7A4241EDCA760D4B3AE0A17A8A0214BF1BA65221DE64647AC6578F4C7E4A14C401F7DCC30A10A695A7F72B04393F4E9C4163AB68667B1757154BFE711BB54255F4DAA9D8AE6622C71EC8ACE5BB79C6B4C8AAF1B0A0099EBBD07B292CD7B55E44ECD68DFFF4173743145B71F536E7D23E78C63679FA2F3C72CAADEFD5A9471280CDD3DD8DB83F8AFF14FBEFDC8C5969B050D263EA462C28CA64362F7F165C3EF427FE5E90A83310DCB07C9612E9A0B8EA1D0631D84B4A7F1C7485B0C91C3B7BBB0EC98D353376B692BAAF24C5389D50250F3BBA82173DCDB52382176EC5CB8BD531DEA049C5B815D788491608FFA2AE8BF486849810AD89BF0352ED595E4EDBC0B81467D72944AB83C3CB2F90FCD10810EB65BDA18C43F9A9A5D98E714BE992B7DA02E9F7C389F1A22810DC0A473F8891C43932E0F6B5D3A21C3B611AF6C394AFC576C07572DC4A1E56B4576FE615E516F48544D099683EAA886CD41DA848567F70C2103C467D271919CC5935605C0EF05909635D431571E5A316E299E553EAAFE9C7CBF5063E2057D297F60B5DE1C17AF6B97192E840474CB7266A76D509A10FC7A71721D705A9DAAC5BAD8A52290C1D8DC7938663B24700F992FAB008CCB3801258245A0F5F329A4FE5553F4130DFB1D673338889B357FBF11681099FE9BFF18AEEBB31DAD290C1401D49CBBE38277AAC8A99C8BE4E6EDD8A0F3C901082A789A1037768AB7C3C704BF1C6E890D20B3DB6918C477350F4F25756BE1742DCB31705EA9DC975DE0C38C21D29B340C63438268F6CC399BD644EDCED36A7B50E8D65A507BEC51A31BD136525F4E7AFC1EF9E0E6325D032682EB4AFB7FB22F1716EC6F4C9852054429B5C5FAF3BC86213F6D800281913D5722F3A380307B59E1CC290EE66FB9699FFC627770B52619256C7B76D993FB4024D2DF0602F102A6A1257A200DE1F39DB54614FEC2B60F3728F59482D71C7E5BEC36F0D90D6FB0B4FA252E7FEC4F0FB9EF539257EFE87715ABEC75B2A5FCCBCFA5666F1C9BE2F0489E04E63ACBBB239EA8397FA2EC24C25C538BBBFEB74EB8E15FF93B0FEDB7F36FF67F7CB244CAA067EB2C005EDD2AC9E0765DD38E51E7C71AB72B056B230ECAA8985DCDB50439BA261A0DE57E68700C64655E1EB8608BCCC33480ECFFF1BB75D0AB69CEEA8F2E3E9515331A1EAAFB9BA32AF62798DF761267475DE343CFCF5A352C907A0314365B8CF6FD2E72F2142018C4BBCE4CF0A160266DE320EBBA359344A60D32CB135F5FF943173A3F9C7F4A68489E78621401425E5B8E6273309FA3313DCBF13D7C69B63C1EE34D3200BBB4CF57518A5E66D010984AAF34CA9B7DDC914A3AFB514FA1B9D3FCDF3324998D0D9058FEF10C30ED6B381C41DE363CB31C5107E7C00D4C0CCE485DBB4CD2092CD929E5717DB8CEE4790A48475E1DE9178E49B13C5173B6F301D5B7BFF1A9F8B3807A5FC84DCAFCCD8D585B77014EE285074E64448589A738F1323C7A865C3DD482499640A3F166F38E37C6F9ABA8263E4F3D1C2E7D7AFD16BB02B9B4BE8A055452071F278C32C3247DE2BF83A0633BABE7FA048BB18FDBA27022736615"""), TestUtils.hexDecode(""" -2BF99640D1E8D1E76A3CFDE44072BB410AF19920F9FCA9F4EDCC534073063A5D196360CA825E70EF3574000607834DF6770604757CF5FB2E9F677530030988AE35E32C2AABA32FAB3E38B990CC1EDDE319E77E78A554161EF485FEFA16506826AFF3BBE5AF4A248A1ED0BE5049317E8148AD899E970A55191B2F31BEB20D0DFFFD774A5404026E95A04874429B59FE1FE29453AD21790F1F520657D657D175B8E4B8C497D2D271D904DAB7B93EE744B745BB50D310645FEBE6BA084686263F92A6550295822E84C3771010B4034602DAFE05447A858FB68A8B3F17B4539FE2A7839C7F2218888BB8FB8DFC54AAB71CC165B335C2F266984B1F402AC09F963016DCDF2FAB74E77D24B31CF35A36E2003228C0EDCD4E0639049C168E9A06D5646657D0580297C60F2F05318D039698482AE9F34501719251F82FE375D237D964221CD95CFADD4A3724A0C23DD3E860ACFC0637BA76159727F58E0220F31008E789E699C93593F2DBBEC88634AB2474B644699F90F56785F04044ED6FEBDFA8910A286919FE4A7B5AB253D578099152031E4EFC75094DCBDABCA8072443756B536E87B87114B354E4BA4452F540A9B197FAFA7C054085340F6358DFFE0FE4FA4C9ADDACF68C619A672E841117D1728EDEF147E797A9B3DEBD9D4469C71CBB684D134B18EF7ACBF66D52D2AB45CA47C7A1F7861E3EB59FE4CDA18A29C7C635E20CF68CF8C869A372866494C34F703E85B9F367E44D4AE42277BD8BF805DE61D988C848D6049DFF914B2CDCE4BA147127A9DEF6DD79BFEDAAC5AD4653C14D086A7CA154CED8860D12ECF86F351E558CB7C6542017E233005C1A7AF959D7E83CA03F3A07F1B9B7DCFE30D66D81B8D5C36C6BEB651D5A36E9330D2D585E36547F88A32241CF28014CC96A3E234ACDBA99ABB541FD370BFA65591EACE4D268D3EC17D86F4A37A359FB95CEC77A8BD4DEF36D23A46AA72906759A8F46D78CAC6D160F277E4C9E82F7BC3B48558E1607747D7BFBC8DE7E50BE365E62D003246F429E67340D1949C950957D7EEA52096B584192D935AB88E00F8AD54B0E1D7EABFACBE81E2C1282E9F5685F37A54EA44596516D9F5CC24AF26C88C91047E70A53CAB06A33D71B6E058ACF6FD7BB045FBA386F0E07BAC67A3EB256528680E4A0A31F91957FCE294C7EA84E7492CF8D265962164325A6536DC8AB542DED323FD2049930AFF783C466AFE9FE811716F6FE75ED28CAE3D768E7F73EE9C09547C40C3287ED5584AAB2BF801A3DA15CDB3D02A7267B131D22E6F1CCD23FBAD9D2446AB8B303E3B89D7331E8127E3BD909A6FFEDA8512057B86120D02F0AB0D8663AFF465451A4C8E29D8AAD0BEAF00B51C96C09A0568AFC3EB9C4FDB78E372669FDD78A296C6919602E4C9F60513E09F1F5D2BDC6D73AD9E48FB2A5DB13D6E935AE49DCFD455F017A41A0E70095A55DC012F15E94E438C266B081D25EA275FE2EDF7ED894779004063921AB3E84E44CD2638CF2EECA02BAB9978ECBD62D153FC4390A6F2117115508F355349603BF1DB25096D00C4E4B4296632F78C655BA6ABFFAA7B72292A1F71010D6743242E553D6326BB361364B44794164019ED114876FE166F331400EDBC665EA23AF4A178765731206A9F63950B3EB5B89922A565DFA8A23E47ACF14DA53D2AFAC6F5AA9FAA3DBE216E9AD2C07A32CC2A690B2CF1DE943000E87EB95D906C9E52FC103574C5C50548BD9EB8DEA4A0CD0BC3153A2193E30CB6385756FB0224F6392AB526CA21326B065C0C9C74F5203AC313B25F584491ED20C32F40A896F99088D07916D4F84396B67EEE7182B3600E418D353487083F58AEDEBAD6B9C73042748D2F3DF695A579611A41F4865329EE8E807F184ED2528AD1503A61B13D4EBF24D7A5371ABA6A053A4DDC63B0FE95462FAD2A62B9A23D50676D6F1B172F0E59DC0B77EA7C45E31CD89CB8B8BFB6AD07017B5E76D6798E08764B5BD293B27B48A392B382554EC877783099148E4C81401665AE7DAE8CB36716C56D0047BFCC5F57F5C6162ABF8700BB394CAC55D33E50FF43D20D2A1C27A1499ED068E40ABBF855213BCBABC2BBC71A3C7F8D11AED8CAB07C0BB8E5F10C5E46E726A353559265A0E511389C05760B4A6815EC4FD407486AEA685B37015BDB6E8DBEBA29636FD23DEF0BEAD64F38668244C56CD37517D586E08159F518512BA72CD86684768A42EDE0241C0EC6D286CF3DC133A64DFDB52E1E6C59743DA59FFBC28BF3C989A0B49248110871832DC53280A250D8C7704CF6D0A965BF74EB1E7610EF67C514C963DF6ADD4932CD7B6809F725FC65F32E5A8B7341C4587DB20A79F4BE0F42035B76FC1A7F8132A5C5D0CBBEA2E98006CC2847D11DEC848CEFEF19C29B45117859371166EFDFD9B1202BAF4183CCA16C2BCEDC391A01973B63AFE3389EB1E2520FA9C88063D038E9EC6F2A9429EAD33A559C79496A3DBC52E2CCF27DA58AD1A840207E7762A1F10F5ABF5F158B05FACA08CF40630E36E4044B69299835CB1EAB4DB06F33EEA1E1EE9692D427A04947FD1BA3D9A24C0C1ECC9CF203B25C11BC196AA12CAE8F8E1E2D37BD51002024F51BBB136EA9324B80B02A1D43B188A8334FAC96FE409CE4D056885D0AD5922F065772B895ABF623DFB4B0D956F68E65ADC37F34A10A1CCDA07A2603991F29598FD24D2C409FC1A3086892CD3EC9B22D7F01086BBBB12497A1B3EFE60E88F6E26FB4E2DE03B9FCC1856CB46B8D6617C8F6BB67993402A6AA24E9CC42A0E102BB46BF5D33F84A13355087B9B8B080FB8E82153ED8587F56A08226628178BEF5C7F139024B95D2854D8F37DE6068B4A717F4A8DB54E2CA731603E3AD6FFDE96E21A60A66B5F9F5F9B024116A999960D2893CF7CB3DF2781296E6B9D30FEB57842EDE5AFE2441AA32C8DFA2D3FA7BB1A3B0557AFA82B0D0ED8E088D587E4CC1CB6AB6C2FCD2826387FC289EF4E4B3D884A9D5DD354EC742D52962797AC5928A7419947699B10A46B69BE370AD481B2DCAD7ED5AECE4A7CF04032AC1445F6C867794ADA0FEF34E18FE0503A89619DA244E7FD4AEC38448147B49B8A312D3A6858BFC3AB91CE61ADD9456F4E231A55D0C134ACE6D43E142A40E0DD75D31C6EBEA609D2CEE42BF221B6B83176CB79AE6BF46181893DDF1527DBA791723752A78949E8767A194F6FA64C386D0B00F7EC3E22F2E059A37569B4B95ABE43A911D1AEBA678D9A15AB025B0171D48F17BDDC8501A04F907B9E6FD8DA942C728BF87A3EBCF82564ED11796E25FB861080A010DD2F0EE1CF8A7146520FF66F034479E2B8120E4A28FFCCCD0E4FA1E6A5E9E87A6B8B87DC8A3EF2D68D73F2317F294FC7A15A3A4E90564BABAB922B210878B64C20AC1F8BCB23756611BF042C201DA4D0697DB25E64C688572A3DC62C236555522127124608422BC9141BE17386F6423579697AF73CB0ED14513220AE13AA49A535AC241097190AE9B4AB6FB24E8200F75A7D3848A16DD3676E3E11BE281E04A9B642A1DB504948A56EA9A1C8D0A50F97F292560B12395A1B1138DEC127DE6679CBA8B849E33F888B1F595795321BDD543EAC2A28C4D89CFBC732E7CA6A7A04F66BFEBB4745D489A44FC4A5E255281AE35735D85DEE377AF98751BA4CB8835732DB983635B656F24FEB594F0C0EF5846B854BCED5EC137D8FC1471A41CE845D486E905BD247EE250E766A7F8624181263F2B184D07DF33614EF3BE0E0BBE3ECB0E3EEDE05AE25E2861269E0B0ABF9884A9DB377A360D9D3BF7E66EBCB490F02D0EB9B9F95CC59E7049C8F96F80D05B93AF90753930643422A047252B93FB9C0ACB4B88B0090AE098D1F103239C03D569DCDDD4D3E20EB00BED8F1C67F1F2D3A3A4F5F1E554B2E462564C6C1F4780007272ED5CBCCAAA46165B7978B206E3E099571DB7EAF27237B837884EBEC15DD26B40CB665CE45B29841B2DED76D9B0F1C9E3A0AEECE530A8A16F7FA1F45F9B9B7610A393D4580C5DB025B78B02261F5E4FB307AB6689934F3BFAC66ABF1C9FD202E07F20A1D82747E4ADA8EF9D5CBA6956434E94C9BEB21F32C74DA98F796C575B3B58F43B493D2D3568964580285CFEFB2E62B06588379EB296324ED06A7F1FD4F8790DF96D4A773E892AA0D9E17095D7329D9B31DB6FBE956D5061EF8611EBD39AF2E5903F2F36A75EF2BC9FBD833D8E8D2044D33B44B6B744FB66D0BBFD90CF7702567E92B9FF18A41582BEE4A15DE30290CB07A5E3528A9A27FE160617C351B8BB362A22C37F340F4C3B6FEA6289D7E4D637F6A1EB28A7D3C0EC52686D5A9AB790FBC2809F7F06F4871C4E3A24758975FB37C3D1733367024163EAA8F98CD93466FE9D53629E519176F349685F0E61D093801EC9A026648E72A13B8E4C05F906387553681D00719E572B06D304BD71DD1F5B36A45073127CAA88E68036BC26F9B6BF7265E86803373277BBC5BCA7762F7AFDA314949FEC84177FFBDC696A5497FB40C79E70E566E391F1BFC2B324D2B310A450D9807A5A72E0647DA940FA6BC3BFAAA4BAAB81245DBDD55942457B21DF8BD499A2E819A16BE59A6F7E6676CF3BCEDB9C646BE387279985182989FAAE983879BA0F0FD0ECDF712326A7385A7FC1B2C3F4F00000000000000000000000000000000000000000000000000040A10131A1E""") +6d9ffac759de540cb67a1d3ed0e50afaee62c1bdeae34e94e8c88d8fa0a86e22b911655d83e0197987aa1151adbb629f7d130a143a3c0f34ea817898a86d76f54ec5fbcf4d0ddc93ce671516be812b1eaa2fe2da29d0381d9d5cb8e702c038b8b8e51d3ae18d0837fe459be7cf6e4967233344749fea70a74f143fde0a0a9582366710648c4f1b26152ca0b56bb6bbb6011264960f9639ed7239881337eaaefd07908359dbbea6dca1834f03a753dc02ebf67371af2ae1a82183f654fe20ce6212eea1aa256b8c1366b4d13ed800e116365e8f3277eb522f2793812329e730f56f6af17cfde3273045aae0ec8188cb956a0058dce1c4d481ffb1e114405fab0a5e9a70af8d438a2a266d9a93332e621231c4ca1d2aa02e417a327a6feda50ac402263e797fea04579ff60b9f026bf7a97fc3378790e3dbc9e7b6cc12d1c01813367647bdd5f8b867c9e1b2d05c870b5935e5f19772fcde0d8116a9ca9d84cd340ed26adc1033a8615ddcd29f86659f3e742e7c08cbf197e4c2f680547099b364fc67b8140a22eff4119906322ea1badd4af4bd008bc46d335569052cf26520938e417c8a8a12c72cf0a451ae2f209532e214bfaffe20414b4243d9351093215ec3ea78a5689e4f89397c7d309abc54d55d3dbee907ebcc6a8ef921ad61c67c2094081d901ba8631745ca131a302fa813c7137c1f3fd66207ae753d0eafb1211ca4e0d247182b3155e12a42e1cce1c415f74677928f7db645889ea70928679c7fdc7e36e43231ec831a6a6b6241bf54466bf530553c268cf5d63b22d755fe9d341b0ac7ab830a303d3f74acbba37de4c109a63a6457e9f79955232e368e9b4aaf27c6c5d3984e7acbb9d19d4cce1b8d53a04d7e137811f10ce33ea05a0b25f0f5ad1499e39542a264ea0830cc2b20646c170495e71a428d35ce3b726ccbfa1499ea716df3a01186e776586d431b90978be9536e5587555aba18ac6f7aa3bd44867d85b6fe9727496d6e0c8e8e776cfe346c5546bd262d30492cb480040c42aaed646969120db4dcf7c3adc8a4e469680e1d5d1092594436655355631bf037a3cd4b9dada49c259e0c6998d466d6f3df582bf86cecb7f4c874f392806cb1dd3b08d3759792875a08d589cd8f8dd8bcb533accfe23001773d6b9ac4dd6686b4ec3ef8cf4335f70d86bd155e5e473666c3ab5b27f069616c6d87f3969a55a80e59825840feb3c82816ca0e7c544eae787ced30e7e5d0b911273909ac11c5f0407848a96fe139887569491fc82b02e70134a1325956e65f02cd97254d4f469455f5ddadb32d99b851020ffdebfec3c83fe99ac4143bc4de6e2341948494dbff83f13603bac25fc5801cd694eefa4439afc61ed048a811b355b75ca4f7f7cbe88debd671657bde2840e95032129f2f40fcdfd160a13c7c123fbc811a7759e86f914288b417a6051393fb564a8a2473c3cd5216b31848cae14dd935b79647aeb287a262a59d37da18b085a86745b2090a83b6796203baded78332e5a76ae6d8920473d268230c00a442af276d11c5179e0b776719f02f4d380861ef73ef946dd03cedc6b7e19c812cf6367d6fb847f0f00b0ae2d5296122bf26553bff501afe0d217628dd44a8a39b509fd5a50c2b991d70eaed000d85343135c8e1f9a4bc703559e08da575ce134e07a33e3f3214d75f959c85e28329aa2242d8dc69b12ea2c95be537b8d1de119a7ce7d7a672c7172bb7f9a5df91ed8e10adb5ca072a493f4199f1135ac519484678681bbc88135a766490f99c2b3d4c6951d3e5da5e169b908a60ea803227fb870510c1963196712d0283102d6883b9164d9c30f9853a799696d488ad8834b6903602d14565faf6be82e911ea41d2cdefafa2506b28f1ee5a77eaa115b91e1ab44b7123ec70114d0c4a13846bb046bfcbfea6097220fa91d1e0605017f3849f9e2be6507fa4b7bd4239ed56961e70bef8daec13fb486d458c7186b99adcc45ddddb818e4947c0e6c5eeada18f564bc664f51efac7a8f12a259956ffb2165f450d728ed5a3c9b4cd6dfeb2f90a7711620374a66510fb3c2b3fc316e15e52a5f91d3e38b3313b7f9b5a80b6b181e4c4fc036ea2574d219f179bc1afa98fc918e33a52cfbc95e20c09b4140367c978532e6be246c8cd1d2c5508721eb298db406a92e77d833bfa7c5865c997b402cd8c09df2c5668cb38b03eb0e86da9707853b20f1ab23e11b6d38421ec2d6882a9121b847f55923601914a11650f02f99895f9920e1df904c6f45715a4c0d7218933149297191f72eab16eafb816d5dc1f59c30a249b8545e6947ad81d5b8f562f42c016ad46f19f5ba10fbfd2a1c22974669c376f496519525bc7ffdd937da7845efd848aa2431344c7314d6eeaed5610ed1ff144794091ffdae46c31fa9e7116aed7dc93c4765b9b72e021b825107e248b988d11aad8a9d466b4b109ffb874f26d6d7f1a12dfcaba5093d60179d1cfd2b435cdac23f6b64cfddd536c55354aaf6a76d738bfc12ccb003a14d19b54e6ddba35dedfd5e4f7f8a18dbdb4d7a8b34acfa4ec462b9a9ac8fa962ae9bfe353ba9ee19d576a320e0f9e22347a84fcf58c0ad61429f9a5f22809b72e91574052534e96832a99db4fe9e22e20dc2ea8f5cc4cb70c844ca9a0334f92ee2703b58b2b09e77c71e27851824c78bf3f4d177237b212f73d6681c6bcc29f12116bae1a25666035313ea2af3e4e98af8f6cac0236c392c39516b610234304b4e4d1d02d8d8e349dd00db7b8acbcaa4c79aa99f711ba693c7e93c9a71342453add96a124e3d06e46c503425a311bc5249034ce01fcda3c5809de83a87d4eeca01b26f92d9ea61616fb5383918e87522bb636110aec1d2b43afdb4258a51f06ce0af14a8687276d67033d922026dd190346844df0974280d56c22fc76fca0132615d1d61bed3facb80f8ccf45ab82121ac3cdd34c425f0efc86e1546f35cf470bacc1976e8c8561b086c52dc71d9fca01223707341c9af7ea6791bb08c2d46a578ba479fd36a2ce79558387afe1375090a53aeb2183294e747043eff104374f6f247591860028a49ee51c5327007d08bda15dfe2de5109683f0c10b620e455d265411a460c3474c3c2c9de9e72356bdbd7309b6e6dd2fd9260131b595630932f46c372a3da2563f31fe5dbe9faac52abd5c842eb8eaade71500f235fe806fd906ae53a2b65a906dda24b3839a0492b206687931dedcf96c57f05c28bd3e1e97731523ee0bfb74cd9367676f142f73d861b070843e772fa18a80dd641f430236a96b294c68ec871f957e4f04546a0610b727b4bc9d46433434e43e9d6c0421997701c5464fd62d7f73768f92645b251151bbc11a9a968b863a2a25de9b1bf547cc6857bb65c3fdc38268b9a89d8a4e49f1c62190812148e2c2617a92ee7003a3de676129e1f6b92b81081f1be2d9715bb83c31fd3136c80a0b23b902a9a3e5f9383b1206d2d8638fb0a5e5c0e2df646235b6a40b5f4f2bc4a13041f44850bb8cb1ef1d525f2ced545246b830547136c8fcfe69c86d4846391d1b8d78a63f50a09ca62ba8c1578eb7ba182ed67975889ad92458caeddd358dbeedaa34e160051b2346ba269003fccc4c3f58d511bc74949b152ae37ef64d0ab0560b8c474d3a1f78b04de729c9f0c4ad7ad2812f037195c85f3d3130559a336610541de8dbce1c91ff95b4d73ca6e4f4023378a5e4e49c8a907cf89b3b71ebc5729b783764a8b9f998e5a299c877cad7bcfd34252ca87de197343c01249c205ec4057912afd681c5062897c79b272c9977af12ae543570f2d8c4977684a2689c627ea4f97a8dd9600a17b6bc10a71a9cae8b18737e3d4e070402d8925d8c81d49854806528d5b03fb90a4a01c03cde8213522cc3372e49fb12adede707ac55eeef0c72a1ce7793925ea6416728a2afd328d2241091049beea09b93158c0835f9e28d0fe34ad0e6cc4cd82651b3c9524e50b6e6e509fba04dcd311b679dc7c82d96490b2f3f7c48604860afd25d38786d7adee7dda54acdef35bf58c2fa5bb0c226b535a9f6230c9428175ddc939fbe2f2191adf27a496644d1004c05c06e4a2e8b82a1910665062c10e6fbcb6d4e49df3e6d17b02cb891f89070288c94ce4faff7709cf88994af70a256059e6bc4df8e2769f9d2871aaecd023d11b44c7ccb0b0f40f4bca202dfb1db1890c89c4121c3a221ca70592742c1c624f9c54ffa3ddcfdd40864836184cfb075417f28a6d5dd5ba9eb4fa2a5fed82c86900dc96aca2342d29dd7208270bd4d6ebeba516fa6d8809eef26e6e929853df5b7b22a66628d9a728170da4a4eda26af530fa05778698e85f02d979a76706b2daa3d154db0872ea5c8b06ca7235305b1d5c1021b0334dc8df6b267760e652a0e1a1fcbd0039d6f585879c7b53a2dd3f664e36fca174322e93989f78ec66ecb613b0a694f13fe2715a930b2ac5cc4ee65a120c3c309b97b8e1ff856857cd88c0ba77aa5557f4184002fb96b35f367bb62502fd6fedea2df3ddb6f4015b018fc00ee6a79ab78c25aacfef26b1d5b1fbcd372b296f320c3cbd02128827678f54ff94c2c5a677193999eb2c1d7f7080b1d4667828e292f373b47696f7b91aaccd4e9ebfb020a58acf20a39586173da2d737583d10000000000000b1221262c31""") ), new SigGenTestCase( TestUtils.hexDecode(""" -A4ED7F80956F1A44672C9030C85547B54619A313032627687F1F158976A2D28907900F84E3B9D5336FB661CDDEB5DA32408DDCCD61859AC66D5E623EAF745E858C1D51E75C98A689342747AFA7C22CA287DDFF2B30EE9E945EFC4FF74BD00914687AC4136597D0DBA2AEBB464A55C00007A397971F11CF922E5108F20B895B7941207013811437764076602057327650014846512521051134044721728840471240468158620851514470636303001350088771812801531688000733466441861513742525412601875458731315486847771662050347316344525702707057377764035718082720307174511475224256283107861781131553717714042076114552115453832756862775232773050805741536122157711646367700242428287222761460706108640730202305048004271137750473622514020882603385871776073866148241884265850313425124232184264815577340717562333801724206311260451483381762216524703666716683462381156603313541080053820757730826678818322826883061861335148373782208061718105775375826777672423588433254824486101823767282154027254361868335678543353805617821481162730652045145287554024323481137013167450247203075702807580765272817733061138110138050742533065402722575387148728268663883012058511436440708755322742756705443143872727618411601186033417307153814781410058448267271130100732602686516231834311238647026760152547113031066482361633044416843658581330423061736710024767084324838453061881648523633073145626613485686817505362474214104803222606853556234224865753748040484665857228745563151400065331467076364034001854708148516718643014448254581642662324580472540817760016334875431813615733342068658625221436633877448827353301133165100217143140503533081867240242288376423706818517408834337781383674383187725187780523321864245136772216405236663621124437888768426042072813436208810360206554680333862732263101403067212832824174614502520062327687743605156465476282370734160232624636614258885304101344844586018105357847251401285316763376185064183603001641775527412116344815872823276550347785718752750352857227783051142305354808613116667716627278876620522410851068428786657414384410663404801846405041631402661336873256432535608683333558305507630406032814477633143263257074135750334036686836723317701210415018766018220628550711780864682005421263438423340416413353070086841488211041250620327222208657643663862137722367033353738671553527108308134351574435151103425678758048472876854021260323038826835101538487847208802126638654312684104325807876770077436312012363386725511475331337542627020144121211014663122140658514307281185501024006018177482712312474614161700446687886722647162278322132585863401702314217876006468328164146581047085401421760440321582542441117553056048835224066102526308431765121152602773303251363080350616883864358271348413640038283567734581504521116644336856306352571210550150067264084884453428240000533610751625013670107040138826466331222242287483473037278656425874000521127357382325247351023460401842120860208858010418511736611802200174883450035706425872070364332078257248857812267664537025601262182676445510008434415815140885773555147384536274812741577500878000523602141344148306644333741235746141117460853768768473488606543427458420223345786350554613242521843216282474064647007816386531203354608282C7D03FD47511B27620F8A1E8CADF4475E865E001C554F08A3C8357B8D71825BF62A6312D4984FC343B28C5C2BFB5A945C0EBB5394EB69054F3FFCDA20339C801412E8F06680CF79416D0EFFE1A4A7568279FBE35302106FB0A2C7A991FC66627A0915DCD8C344D056A59846FBB72DC0F407B60E25ED5B855A70694548E4F89D9CE64F56D41F1F905F485D5ECEDB38A3921EBFEC726FC9DB03608BD182DB7D8E07A674929C406CF7151AA2C04A3BE99AF5257AB2A178E07820A15C69302A78314E804EA86D2C2E16761CA9D4D781CB18E5DAE5B671E48E9BDB2DF6C75F07FA0F285256007A891A6F50C49535C19D838966BE3A6195D3AB635E038312F222D164522B744A1BDD080CBB76B0D3F3F864CBA93AE9A8FE4FF6856BAC2E5E7B7BE9ACF80BA79ABF25DDF14F84355FB4C43EB83A532863B46E6E6E64BB64CFAAE4170C2498A4E61E8B270F27559D38EB709F2ABB04AF4DA3A4093400D5D79D4EA004C7DB83461F3C10ADEA1D25CA002DF5F238E0C1450801A700D0DFAD0661CC10AB6BCFBAE0DB95DE9F80F59B7B28D9C02D11788AD52DEF7F4A10A0A3F6C7DE7655371C5C4148B6F8444D4BDAD3AF25708517E4530CC22C4790A9BBC34999A2B186B4C8AD6D522610A3FA43766C42BECC3F9D32ADB22FB75DBD152E7E1D8D39F35F3DCFE8CB2F51C5537E16D0D231F6BC75BB925F14C2295437EEB2DC6FB906206B4AEFAD0CEB91F33BBD3C0E773B61984B781C39ED2EA1AA55D039BDF859B93B5F5618F565F6011EFECA254E516F5EBA19DDAAD7120A11591E81941EC42801B37AC0C362FE593907CF0C99AC6479646EF6C7E4093C38DC132C288F1C0184036652A7DC583B2F9FA2330155014E3E8841F659F910E93ADC4CF082C87CE9D5DDBC89593A99B2E4AE6C43565FBBAF606AE69ABA8EE6EC61FBB22FBC715969F08DF203CB83CA8EE911410A56AE22145211637D5BD82260C7FE5CC6CFD9CE9AFC86F1F1A67A129556E3E989694454C57D5BB6B24F33F5D81386187B0BC6F33734E5EEB3A2E148DFEEB5D3A0D3B771F77A010948BA781BDD7F75DF23123D0165BB263D25271FF6FE747F4DC953AD2EDEE4807A698BD1F1229ECD00714E18EF445279FBB1BFBE0FD7F0F80255690718293D67D27919C482FFC5CAD430FA4011416D883C3C3AC9E4B3DDA28C3BC0DFBB2D2C03BBD196CCF7BB896B5F0A026CCC3D9A36A41BB9DBC8F7C4887CDC64E8C6ED97719B03686C1F1A2888778584CF7702E74AA4730E1B56EE347118EE07CECFBE43555C77CB20F2519576C6D67665F3DCA0A3C436FA52DDC964AA0CB9EBE79E8BD5A2A0EE66510F40E53DEEC226A987C5219FB639A07C52E58FE5236BB4613CE4CC53A721C55BA0D5125ED860E340D882B6F2B0F68AA1EE6D2C1ADB9925780C153F58B8047B7533FDAFCA8CD67EC95B6FBBA84E94806220ED4AF1A2861F4B3FD3122591706B8B3F5519FB51A7A63ABDB03B411746A6E2351C499DEB6E023913BA4E2682424752C17610EFF3296E7C71D09AFBFC4E9921FB13CE3169331B774B322B1925FA1DFBBEFD745825CF01B9EB0A03F760C4343AF3AB8EB8664D7D04298CAABAD39845132763ADBFBB42D7779724BCFBD8A387466C16A1A4CCD9B40569765EAEA58C2C74B0BF2D045C57C267CF9D57D4B1ED237793B45BB947BB83D9EDC3DA763EEA702DEB209591ECA2B3B53CEF1A2C2C09DF4F3CA377857EE30F81C17E098C37AA6A852E759FDE07390973B41322E6F45E552D98309B6EA13E1BB53A0D0F4F6577C0E94AE96DC0E9B5FF47F7C0E57970C49E103F4880A3E9F3DC694FF4DEC024C662F42D44EEC975C7440100F09AC08F5AF04287D77C409A261E735A109AEEC92127991CA582ABB9C38AAF556C0BD7891F1D3E9F76756ED0F8641418204F5BCA432A3E15C446198666F9CCCF6320964A19D1A992570908B826AC75C67E1D877A1EF3522AE5952874377CA0C0BF6083EB8D3550E00F019DC7A909802217A97C7C4564309543326567FD57722DEEB12A3A6F37063CC5882825893B636B6959DD2E6CE24B2F762D59E473429F40D05579A66FEF7BCD812867312ECEE3DFE08691D7DE66DB3C9F6F7B80013FF92F1986CBA42A31EDEC08E3D71DD8F104A1CA29FA8CB4A7D46434E572CC6DAC54D73CA6C86AD04B948C904A14196D00DFAB1CFBFD366A594E5C8A398C849CE8B1E88BF37C09C48C89B4264265A7447E86FBB8DAC8EB39894F80C18D8E405FF15069EA8DCA779662993DA4C0C60537448A39DA002BA14E56CF148783D6F9A97E166A2CCE8A01B67DBD891F7E75A70798FECD48CBAFB97558CF2643E4CDDDE7380E6BA2178677C9A8F1352E75718922C97B1399A84A602DFFC5086DB40091F825467833F1BCF99B7A8EB719654BA1C7D3C57AC0C1E2A21B6C16C548B6BB148A3C4624C648F27B168E534ED0198FBA6D8A335FDF8CECD1E762412BCFCAAF484738982CDCBE17A2A4515E9152AE926BABF7023806A7208560E6C14FA56B06A736C3AAD6AE686101B0A09AF7221F66919709F37837F1DD496E4567EA2A7983179E9E86E252B67DB29D1899AA33953F71FB4A0FF655637E4C125FEABE278F55DBBCA569EAF05C2CFC9926353CDBE609A3325BE0B9934344B6EF5BDC26A70CC1796F594F74CC858F38C2435D692226131BB627DF3DDC507E50C6CA9E8270FA43833844A6B973D078653C1B2CE63E5DD83E888292CDE058CD57E9FEBB432FC177F0E5D7AA96557D0B6763F8801E04CEDB88BD9DD73B72372E309E89F8230FF1DFC1AF767F564AB6218910C9D8101601EC2E108C04F72467CAD035B8288F370720CCD840E5294962B6B8C34C8393AA2E84BDEA310B0D8C32C41A57B40B64F1761901171F958FD17A469EF879F566FD1C786E8D40F47A1444095E831ED353A754604B570F7D87430507A0DF27FCFB4896B503CCE146F4000FE5F20E7E48560B053A64B2ACEAB204EC523C13FC73FC857799F92AAAD7F66A8CC5C89C5685A31C603700720550818CBE3ECE24C0CB47A9B90E0EEBB36053B75A56E68252E95DDA53B876187EE2B1F8E273B27D0A955BFFB67D76D291D4160A7BD3A516BAD136E15F0428E01705941C37619BC4347CA00C5E5B7606D5B52721DCB5C4D167EBAEB2D2F33443B073E7C9AED9700D5B382D5F61281BE2F245F6F7323F6F449C4488BB8F3253E1DF2FDB709DB2484C03BA27E53071BA7C7B510D607F0548454026F960DF5C97A727350E0DBF51E7691A2A2175B57D377CF206E1A38EFBE2A3E81E688684C69B9F7847736C58F0526BBDE9AF4EC377DC8DCA89B97BE3A29A30B820DCC0C6FC54420A5F7553C62A83F2540E5AD504CDB15955034B8A850283DEB9FC413FD746797CB846025BFCF721D03DE7EB576C083D0597304102084DEBE13C73BA3EC43F1110510C7E135735364C181990A18E501F9B60D249DF5A97E9BBC94BCAA322A778D112C4A26CDF73DB7A4B5C195D4DBD8BAE251827F38E652642D12729B1C8E69E8B1C2282DAF805746B1CD"""), +c80f02072f243218956d3770dfa0eee288f8b5372ccff67c93318ebecefcfbdf18881d022533b778eb8b65b8881dc3c5a2fef36a869bd5cf304c457305af5cdda268b9cec761d38a2314eb1b8317184e325be289861c3518cea2a10dbb70a66f2c5f67c71d0ae6320e319afab670774d6f34ff4ac770a48ccfda9b1d8dfeddb5057025530050677416582278274505667301351576466870331032351083264716862836432486031506605800101361627684822632826581466212345526573758007433333477862751355246324087300847423142180181328073136142622170774306280323704618416477570515142514130455832022610134088876138124058114320611080670118018464085050380678730326046531300536216285206033762276762775135456675305781306813144351058438878403307687115162445758762435444306181475864556088114581615805216153138726620282135405184773253214002763042432742285182025418687637550727618630446721381621561150288271788350383608014736387120213568217622652045405551120320576502871101420474433680435304327652662515883127565314215370838830033816150283507766554275413064230572085558518426058845885530120407528323186266567602237370105201014564604774882172584373620026546053363771278173628600720520652860065382001123825403357873050136310704810102517285164840568604863133864655787425780060514544323632362181675425103051333048832104182222534843223257707062722432431888444556263685673774854726073818648517112141628084551561504640265646442511001786808432003757262538078314515135755137018852833864121201105007256358100857612560813851383702108482160852481266481713382031618845286043105732050857858607353564132122344423377458771167748115086680288573474886275656287884524782738240452330508132453212563243264052512022138236723506415274361568172077584546563246848741847227366113853277677187003120672803312751338731535378660130452317062527513307208683812056457672618347100420828582478354158351014326870707345131061078405044837370213315684511333215646478872283027464677328772837066376715434438300243146756128411654274728230883102040147160236612421547335046566446706883215132525265735424774111734410163874662657464330762111581252861488544800081145110813466088381404533445272646402333765551273564033557176722630105714613135526825771388525741752552048313468426860581660618780270076873311738236518776476873827573031770438878487513011411361583071301445561663156520265240035804757477167382832424463451480481240152163665000582805647367208703027114876055755766242113201847066246108435208437356368155043852753534553884800410550611352563613328277231178785005471510106804217363330510438775850050201541533244435247577721612262085330353712227748025886768140455853781817167865520612743051656428875760637056123627868651516386807077756848254735200340838355075611101746703364144574811707376411548585113884075077423148765742857850822700384480233506021262883121710116835788133723704346757345521270442111754166000801666758036038382282534825367627860280876821686044258467073362032026126470206571804580600827540023301101145187820771648116401787587233440067756345560263886241380357614771073381647234280567584172010660461051813086315325671588023055102007554535774637007241602270404175218044451787766283416771207805266403201725203a5a72c38850214325e10e875c90dee2ae6991fc05b67acf1130453620aa0f16b3eb56700a11ae3340ebb059808062a52757126da288c4d6b913956f99c53715f2b7520caa18f15695ef52294bdfd7ebfe3d668ee773d7b49e7fae905b8e16aec6e314362245f4978fa92e5fa66906f875b74ed5705e4374e90ef2d4dafc3348d49c17027403ff6e18d4576e61b21b540f9b89f5604db87721ffc19a6e58e4582cfe90fdc3c8f1a06467125fc6b133619c19a299c2208ac729a2471152f58ab9221fb1f8b8ee99bc5562295e136c1d7491fe4a3272012e7cf23db42474500a6c3fac8f9fc80f5464feb32a81bad914c1034fb278bc6223e09a3b3a5d891540ae563116f2ab2719368627d70100c7156e1131f8778d605ee6da8b78a7681f79e681081c94c2032655ecbc5c54d813d1d3e4c3875b90a5bf28424d0f3aa44ea16709455e9d8b024f5cd288507cc5c4207a85b1780a40421c996c1e385c96b8a168c27fb7dd18b80ddd5cb27e815cc3456cfd285e3a451483ba46f8031e66bb2f26e3b34dca9229fc737f60e3bec555f749be2ce66967f842f519df636727ae2b0ad8fd7054ab44b3e676bbdc087c5e744ed20ee4d70451a3f991a2e11df9309307848714f5c5173234481528041f5c4cc401a59812652e7536f944a124359e24fe0e915a605f8f8cb656e6e29a2c62a58df629548cc7429fc016953c5c6cdfff738359f156f504d514c501cfbcd63c012e6e4a98a96abd0265a8cae4c287e8d44e9198d53c16fcc50237e227787adaac3e53097aae470812d7885e8a9fdec4c683178fa31699e09b66765e643eb3aefb034c471cf83fa6f6b900d8e9b76a25941356886d8bef84444a788103478bb73ec2e0772698f8d05c859dd7e37eb065e3bd9bf54bf30a37bc784adb358dabb075060e9777c74898d576ffb8b352a576252d203a0fd11b24bd73919ce83271e5ca576cb1237f2df574c65cce4051f89ba91e22e9c1e1e3d981e45597488fb23548a0c6f555a148a6f5b520293a2dc1655b62719d4defb596b613be1a131b08e29d3cac60bbbed0fb11a6bbefb006e6aa7fddd6667323a09ecd9d6b39073092c1162682ab5ed6fe878007609d361abc09f61d156eaeb34c4c01d660458c0e31af7f43e6ee71ca77564bca40f39e2949008afd9028e6bad1cd2fe320971e2cadc9d79a2c860a41c658ea8aa2f8842938bcdf8887cca5df17750722c135f92da46d749c43eda79f966449948fb955a39d90a725298566d8d010c4706ba4137aee184bbfb74650ba401a7d08410d8d8634765868805032b2605714f866c169ee247efc2991c6dc62e5978b787352011e006bbabda578ea283f510906b6c641e999c263f53fac8c00213338f021bd1c07ffc4184050a3c07e926d99e10f53b6017d297c29bc5762ff0eb64fe011a2296810a52c3dc0e0d5a44a0f576bedcada7defbd51595cc7e9d223acef03ce265ebc8e47f326a672daef305df9d8137c93786f791452842837ff9db6c480770edd3c1aab4577527d669d3a656b742f89d153036de73628f6d27c7816b105646cc9ed77d602e5fe2cf1d203aaa9cf8585d576f4a73ebcc5185f541b8dd3c0a42c34899d2350132680f1e95a5caa76cb97ca22ac2d149294eb0cc8a53d597fa77a686cf5699620c393073fcb41636d52861920ab80b8fc5eb1716389991a6517481c107055ea08c341c9da52ec48d44e80900038d0fd105bdf79be232a2c2b3c7d66adb018977cbd762c0f2feffa3aeab21b2ed461326b22ff1dfab712903ffd798c819b493ee7651e179873bf28167d8afee704450e826d7cba86a119e044e52a80b0ce31f1fa95e67c7dcba3e78d0569073e38508e3c2327a429030ea59a4384c8c29561d410dc24630a80673a7068aa518b8274c68cf4355db661804b5b44abaa70390dabce2f16b51537956b7356f46194b5056feb47445756d32ea2b853a3879652dd5a77c4c93cdbf5dfb3c94254071e0e054b49e85149b12b8d0edacceab8f4d8d8351d2c2929d3930c1d684ebd797e9a2528b01b249daced8dd27669bfb184de5e3d007a194a310314dd50489ac49bcd5e0648311a9489ea505a3eb26fe6eefdb5859e479c8ff00b719e0ceefacd729dcb9b00be0c1a5688b192594f5b9da5cda8745b925a6d768ad753c3006e644a1b790ea8906f791f879e1b9c90a124ae504f80f0c17ad9d823a794bf0db57a8240e982d9f99cfd9195305729a279f39dd2b1821fe09d757e875d6e9f162612fe0dfa08be5ce075bbf6845623ed468792a8a15e72deb7f3b7f2b44b903b5170e98f3691f32faad1b65213cb4198dde740b87ce9ee43da004160d773747d7e2506d7c41f0b6ac80b1f0a3c9666d864db66c42b8b4c839a2f19b85e3978807a2b0d8522ed3c6d1afababddfc0a06c6d5897daf6a72f62a49243012daf2e6f08e4077312fee54b5ac8f7bb9932c06b8dca2ec95ad741861bd12cbb87f0ad8e2383b2c1aadf8f9786585ec65d61db5f66d5caa23d86778d5d186537b6e65667212709e7dce06b86d88ab40ce21ec3c75320b08c9f92e216d2e3480e7cc9442e73eb1664e081ca56080c3c4570eb5cd51b0a0d7872c95798ab6f027c2c32044d937d05dd72a0ee4ef973dcdc2623cbfaf0925f375cd22878b2f28ab048cbca8777a6eb52def28d90c5327b21924492ab7d1e24fe6a24b37404e8de633fe6185aeb2cdf1093420b847530601330d914990d764b33bcfb7d3fa90ee25197fa585992c9d0726e3ddb72bb6b03f7ba66a888fb522e33a6a8132a6d39b7b83e255e84be3c6bd55714d0d0146647d7484d5737ff6dcd5e9f128434919e0259f8766d814d69811a25a6d36ded06f7a6ae919401383a87fd451fe1d59ac85205efa636ceedb523d39c048f45c36aa6ba72eaf527bfdfcc4d8e99264455274335ebe5141ea71803e7e2fc66d041848847717d37a4f7656ce2de0c4a23acb5214b78009259eac4ef77980e80ad76442c6df57e7507008d51dcd2b49c28df2bbd66f8a6a9d99c946ed37561384f1b981eff93a64d8282c71fe39cacd5cd8b087ffa3e52eea33d88c06944a025edfce077795525d33c75656fd4f314a0f6089375d96ad2bd29a62df58a45af0a03c7b9d917ec56f3b3083da68aeb20e034e113ef67b07b58bd7e49705fa600fb36be0f345390deb3d82286d4d04329fa60ff76958214775764c7874cff5287e435442aefb809fccdfdb56adcf00c5f420e70ffaa04c0f768750424f16a7b25533ce438ca89e33ca9afaddb2136e6b1c68468aa9e7434adf614d0e9d07a729c2aadeee1cc07db336d3bc2083d0d87f0e6b13659184da03434e93028c93123aa1be5f0ea0d41a1fbc6ac2b7987a66693c46b9d4539b3020d5422897d4f2b5c33e802df1de3e65fe7840b793bf0ae4aee817152b00a9f3ebf6a2d7ce5df3e4ffd5d0e35e958f59fe742d052f8119b4cca8f0f7605b2f7f9fe15f95cca1f59b443005bc97824c3f64d835b6326669ef53c12"""), TestUtils.hexDecode(""" 258FBC2A94EE48B415DDADDF470F14FF8DFC069CD949BB88812CD27B2BC3D9522E00F302C0B72533C9A612A251BCD292A291F3652695D318927CE1B922125B287FFF9B1AA2B79180622C32AC624E0463E5F48E86EB5952CA1A95BA51388760FC5374F0561FB8873018DEBF785FEDAE4CCD1A41820EAE9D7056BBD329E7A95F21A4919A109BD27D26779C3588C9A886EDBEA1FB97A8048DED858B299DDFFECD4D678820E5DB6CEEC8B1EA879C9C22FB7F59B227B4F7C6AAC577767D899B2F11FE39D1ABC527DFA0E656F25E53CA05630215C5CCF0FC071F124E48C57C5344BB103D51A1FF24114426A324BB16D8F80D3CF2D0CE573F4E50DBD1CFD66C05430A1109374CD84156D2E31C0C3F4DE2F1E225B5CAC05D56C4478929E356F7F46032E2719E07BB1EC207B32D241C87D87ABF28C7CBCD38267CB011F26A9B49090008389417C7A219A9F18203E6D907D63AF4C42C60F7FD99C7F9394021640F450A9A072BF2C1CC3EEC88BEC866FF1FB5F032567AE053A408342A56E3068EA168B9E902068EF808916EA58004FF31C31DDC3FCFC2CCC92E0DA09623FB523AE46C8CBEF92A1CFCF4C0F523430E60449E5825A81DEAFB2E26B3131F0383B8FEB4B1B4E1499E89E9C5FA2ACAF1F37C422CA41ADBF907EB984DD65D8314E2F71E8AE616C0518DE9B8331FB00983490483362802FBA242E4CB71056E3256BD097504AD13F577B36A2F9FBC1EDDD25D9DBC09B3401D58FBCC9DDC8E74BBBC897552FC826620060D3777455BF76EDFC059E5C02BBCCC0F05F86ACE1903AF2BB08A962BFE9E2C435EE8C580502351669AB7DF3D9F6B4720A0509BAEA97FEED3B8C769AC5D0997A097852C72DD6D5FA0A7144E08D667F21936F434953EC3C88B5BA2EDAFC4F87BE8BFB5A592847D15D5E5D972710A4A75A5772DA4D9F156563C17B1F0F242457A198658524B0D6A46DBCD26EB9400DF3C4C942FF53E1102411101B2FCCB58E3FBD16E725147960AD56C6CB6DB336857EF137C49D53D16E98CD7A0E856E2D6B391A95954ECEFF3B9956A6D0C279DD9E1FA5895D37EEA8C54255A6244002C7542789453B41463B084E7FB3361923C43EE1BA115CB254F47E55E6EB79C74DAB4C9CCFF486B8CF5830F23BA23C5CFEAC2DDF7D71EB5F54141C100E0AA9873D43F0AC1034C54193BC63A560A0C661047C508062A70B3E575CC185462A75230D91A3021330D95F3C807688B032AC15A9623A833DB718D04603ECE983F1D21A4513E80CC67FD34EFF8E377B775142344645872844BA46F5AE6971E68FD8ED640BFDE9F276E26B208A8F3D74ACB739C7EA6CB26165EE182F165EFF21905DCE3D02E432B1193CA108B6ED066CE95D549D9B12445E05E0583EBEF32F17EB121D80EC26C1F154C4DA2ECAC841BE1CC7224576EA43ADEEBA53C4D58785F36B6BC0F8AB23340B92CB87DEB0230869A52DC634F68A83BC1AB8A4102264CCDCA39A51C331F6DBE30C18C00A966E5692CA86399264399DBD3F02FF8706302462D62E4D16B5C2FFEEB02A7E8447C2CF1A3FBA5046C792FAE0B1079621D59C1D7AAD17CD6578964D1ADCF1256F2A4EB4D534C51313BAC17A9383B5BD02EDCCDFE59998D2FCA7F3EF52CE0B1842368EA66E0A83FEB581A7137004655957E91B25F5435BEDC0ACCF69238AA4CACE418F08ED0D961E13B2234187597FCC012769F798D969C13F6BB4042897B0D8C32E6CFFC06680B1E0A40F5F149B5974B0E7F0D45367E93B415F7F6DCF86C2131137DCD0DE30A3F1FBCD5F8214AB20BEC9738AEAAAC200900F4B2074688C8F3026140A354A22F83BC2ABA66407F87671C3E7EA4EC6F8272B6D16F3C66C76ADA231677A9B1CF496B3C241D2D1ED7DB703119CEB162EB097A0AF2729D0D6CA8DA57D83E1BEFB880EBEFE090F6E98D64296F7CA90EA1C2B26131676232BB394BCD1A06BA83004BEDDA287073154D3BE16C242DD65839C2E1125B3E66DC93A95C62F5DD31CAF9895646D5E2D183D40EA09843F5DB189B41AA4CD1B40C5792C2BCF9F44823EDD4246100457299E30EB2C66896F89F4FA250AB19CA06EF5B899CB96FC5E0369B773691E3447E68475A7552C10F96F44B3282D92AE49A246508A67EAEB9F4586074D6FE8A44D2D27C7B8FB4EF6BF701084B73641E41AA7275C1D6B517FBE3D60F64BEB9119F3FBE96A11AD45610E63CBDBD79929003BD1F2DE89DCA036973974FE5C5D5A8B5BF82DE0368DC60D75A138CD91E8A9233BBD439666ED1211EC2FE7D7BABB1247315DC480CC64CD8F7859BB9BFE8C668F112FA96EA48BD91088EA44F40D3E57314D3759F867BA52E52BE822400D9B0C2123F50601EC5F8E8B562C4B1F49F9779A99C926FABD8A74173195CE23173F4CC4098EED74C8E0FA74320772EBD1847AFA1B397F5A6F05A00179DEF2E6C3B092D9182CA3C4E382C4092396005D8BEDF6248C81D3AA0854F0AD43C1079CFA1E0A42650EC9D7B9077BEED377BF5FB2F3D2717BED04CDF2F7E7D1F45CCC6F71A780D2E5C3516E5F6211815FD691E036E4FA002079448AF0E005B67D2939CA88CBC57567F634BD0402EAB06805ADF8BE550B3E27452B372CF8C92A7055714A228986FDCF4045421321555BA06173CA0A761BEE635C541FC984C5BD3857DE696E9B21EBCFB87ECA437E9A7B54F4CBE2A601824EBEDFD5446556B64E1A88B0BD9CBA507C5419CB8CC4CACE48A0C9668FD2D045E9057B13BF0785F59B35338501B73B44CB749EC2EBEA97C9D29EECCA6AE1FB719F9A67E8E175D50B2705B6149E9D5D257B34487B547FD050FE5C998412AD0B4159C2225EECB67903FFE332CC3B86266C22FF7776334543C1E954AF5A89C4FE59C1F1AAB5097024E2AA7BC09831C9A5ADB713591106CD3304873BCF11A9138FB08B7485E123DD8F7C107E336659DAFDB866487E197589DE47D2DE8298EC3560EDE21A633F820BE6352CDE9AD51515D309C4BB4709F171CAFEB407ED1A02BC4AAB53588C2CD4C273BD527F8B4078925FCFF8954536E0B4366E474801F5B938A4B81F037764D5CBAF19F237CE37D00246C60DA652B76469BECABD51F873DC75E520A75B52BF585D664B4CB9A09F8EF3C03FCBDE6B9E595C1371C2CFC24C16EBC392C75D2BA04212947944BC0377DB718A7FAE0F6F9008AC7DD30B94C1FCC6BAF750217C0119736E4F3B7E744AD72F1F0694BC88F71E4BE51ED8669F0E814E12FD9F833286E2064708951DAB852774D4620A26100FB44A8A92B86E17507C036CE6F3ABCFAB91193CA4BC4D4198DEAD7CEFB71B01FE2506995F2ED3A02EBB0355E6B67A2294648B8D1C1445164D99B966588CC253D1EA1361163024372E2550E9D29AEB4234F5F9B20AECEC01862CC98365F1C57FA4D5E0C1F8BF189E169669F825DB43172D1F682DFC7729B2AC0C103ECE4ACD982D86C515A208519D23F62934AF981DA66B97DE2389F2F669EB92CA4A5C4C844FCB19903371AEAEFB32E210F2D1155576566C7B529A98A1CDBA36B450F3948F34F90A49F50E7412E6EA68BC3BB0B0A0AFE3BDDEDB718D5A150EAEA784859953FF1DD1B371C539243547FCDFF4ADB06C61CB49EA5783AD06BC8C1F3E32A95AD3CA6D69EC1D226BF9DE0562888839E6243CD150EF6953C158F9FEE5EDBF173997D08509EAD1ED4DC2AAA33E18DCA6F59269CE457C412B58C4483BC96AF5069D1C2E3F2F8DCC5FE2825DA21AB2280984C359DAE44C2367D6F002D64AB47F9B64B5656622517A5F7D5E1A78D4182B6BAA82E0490659CBF2724080A9ED39BDFCFB21BA362DC29C750C5034A04EA5A85799E01FF8B16ACD2EFB8328BEC686AFA20E591E7C7FC55BCA8BA1A3C388B785AB0F57208CEBBC5619AE3A0B799D1816B013BD67D440A7AECA7D0BA517846B68F70CB5D6ED46C36F663D6F242E8FD8C620C9383EE1BE9250D63467504B229378D2589B525348DFF852AF1676A18DE321DD46D7AAFD3DB1825F192FBD3F160E8CA400B201B1A61D0864257CA340F179F5F1967659AF4789846A4D086041441DCF4267681B83D4C8539086E276C21BDF677961015CE550E41C2C45D67A09AD8F56AC3ECF1058F366F2E35BAA9353A5CA40C7021DD09AC9FE0187C10EFAC7BBBF3B1A462C9C6C96699741AC16D3526BED3B30AE25B8E8A9ACD8CB2BB6C28AB89F0A3F0D0F40D10AFEFCCB067A37A2C93D3E8399A366B5FE4829870DA75B93249DBBE3C9AC9FAA70C4E414EBA720C323E6627759E7287472C3DB9CA9B1A5FF03E872374D6B893BA4887AB227E989D9D4D348B3965F7B96C5094F42D84432EB771BFE757105966C9A08D6C58DED7DC216B3D0ECAD2D0B025DF33CD3D813348B5E08AF95BBA08DB5BFE5D0A151C98A01ED27661CCF80F416A1AA260EBB56526AAA289F17FF5AE97CD0907D9143BCAC73F1F83A2A8DEEB3ED209EF0952D5E463D87145E0E4D8BFA1741E3FB737E14B5924F436D0183D98EF836DCA3F9623B50CC13EBB5F94EFBB76EF9BDF40CE6EAC9C49852D08E2A5A193D1DACFA04EAF3C545E0E25E37E94DF51FC1976BAD069CA530E19EED277141BE62239F47441B88F6555B0A998C1BAB53758A41CFD8CC4CDC54E1158DE15910408A6E79D33CC37F61917027E9D2F186466F704647B1CC1CEC06DC1AC37D1A668D44DD8B12621AC3CBD2039BF5A843A86FA492A847D6552E1570DBFE008F51652D65D03D8B613AD917B81CACDFD19DB7F4DC9A14E237CC6D7268FC5D3B228BD88ED36D8360488509C974E01433D78701CE07108C67D0489AE94076106B045DF7CC508466D35BCF156901E53AD2B5ADF8795751891A5839033A40EF3F5DFE0BBEBFB2C9D1C000691F902AE490D382EBC87FD40E76B30DAA963254674C7B6F304DA2C8BDBE8E1DCC87DE0486B4FE6B57A18D5A9E9E4BAE776D6147FF9C98372426EFD30C3B2479231E624A253A7B0BEE31E0FF739F862010AF03E227A12C3ED1F33EF1C0DC9D48A100FA24CE5C5D8B5F88F92BDB6A3A5328B0AFA983D57A1D3320A682B5CA94E75DCC69BDF2AED0C05887B791CE6F6F8885E4CC55C3FB050ABEFCD3AF2CA603172AC78B3AF2B047E506639498D0391A06DFD328B8E1BFAED8F76C6E4A93E733ED1097DAD8663F5BAEADBE1562D40C772D376786509323BF059FF17A5E6EF5A31BD668954766417E6633BBEC90B53ECA61BADD4037030A55A5EF4129D4958F6A8A5ECAA1AE7E220A87AE996AE8D9AE46B9C60FEDD98FF1E67807037970C92CFF9EA4B64F0BF8907198A6C038F9826CB968B1F301952E1F409DD6AA4EFFCAB157E792ED45830708ACD7A50BE8C08FCD12560344221104827BFA495604A57826A49F90B8B694B2BCACE4040627AA0989E3DB4FB7167F50E8A04982084FB3ECB0DDCCA5F24A7398620D19B37309A4DC0DF28909E16645F35A81EB3C5EF6BFD650571DAB03A7FC02FDCCA5FD09C9D2D3DCA888B8261433DE88D05DEE5D6165080A237D55ED718486AAAF1E2534CEC3A87048ADB40EB9F9DDACFB2C883EA6B20BE1EACBDD72432C7A6C97721FE1E0D9A5589C951F7D46F2C5F0FFA909FBE12E1CCF00161E741C4505681B0B018FFACD460528795CC3810BF7F94FF9B75884956798F21ABF36DEDDC1F95890894EFC15EAA6F19E9148C71EE9BF4CFD41EE3E5DF8A449FD95E5744793B9C223D26ACB44E691D7E5B68D49A19687F0237E7287841D3B0B4483E2A7C29CA81BDAFA5D96D9D2CB6FD9724B9903E8CDD03DA810EFBF94BC7179349E10566B5A314F81327F76C5A8346E222C408EA43FE29439132CDDE79D0D69C45C7217399205C2DA4D33DB521940C4EED74CA22645D5B6A549E8712D0B8CC50DC180067D13457ECE66D489F687DE218449D974620B3B5462FF3A7F00C439AEC73A53303AC51EB84BBEBD51AA48A5DFB8F93556BA540F5101CADB8BDB912D7BC87EC2AC67971AB99093C8616C4D1F3E7B06003E4FF22D99E6CAD7558EAF5C1410199EC97720E5C9278548E7EDE62BE9105A2B27A54D95673849CD5D60424ED97BB64798263F98A63DB58BD55965D3A4283797CD88C7CA67B1C4F90FC7237EA35AA24DB18A4420B827B3FF7FA5472C31499480EEF5A97BB967D1EC46E7B05A3D25212C75972D48A9269D67048132399E1BE0C02150A3D48717E4DEC2ED47458EB870A1EEE5381209B5D182DA2093AE46A4D99E3D4F12ADD71001BDB936FE8AA96797982F88EE67AA2E0F340E7AF498D5AE05C177F0BD2650A02ACD4CE23018F9E00DCEB9794C5C76418EFA65634E01ED5E9FF94FF86AA73641117BD554A9391874A75C7CD1E7759755B9D2A7F367621C0011F61B588D913C7AA0A0EEE3A2201426EDDCD56A020F54AB41CD899721D6E1F05F8774CD5FF6417CB68EE14C20D9234369C9CA59627B8796C37B4ECF1DE2F981ED0FBCD5737DF0B82637D599A61826909C978A2B68CEF01C5CF84B50BE77B49C1887544779BFEAE3F533286287E48F0ECC0D36C27F1209314726855E61E5EB5E9A5D7E3516E29DD369F94D72004742E246AD4699C64EE996BC7B2A079344ED32A528A9CAD6D5AC02970D0168A8B5BC713E28934F2880774418550AC2F534D06B61E627BCB8711AD9FC6F2A4D9301EBB74E1F3C73B05F28DCE5623BE1BFA871C14A947A947CFA806AAC43AE515D6CA65436BA6B66F62B0FDC8AA4A748DBB72D9AB087AA39561271A986229EC02BA3719CBB1798DD333248E4DDD0B6EEA4169D3B03C9F4DEF9616BDF97AE993F0FEDAD31834B6F78E23164B556A39AC1F209581F61AEADD8E504E81A808B1E97F79F987892A8F7FC35FED9B1A2E9D3E17BFC5AA64680DE98664FEA7B479567CBE307AF2A8516BE4CBF9EA030471428CF802FAFF85701AF96CA1D8F50F5A79AD63F20C5CBB954011BE4B1A7F627A8B5F5A0D022D27BA6FCB8D3587E8632A2FE5794C7E8FD09C9AFA3021B9F43BA82EF48A3B1F3E40F2FAE182DDF9558F7033773F5627906E159B794C4220219BF1A9878B175996A16F3CA1DDEDA56B16E63C504354E5E42FB90CE4D2C1AE7C93D8CE27480F3BCCC076CC253B574A7BFA6D3BFABEB3FA6A19F196C7E31A0D6E9477F828689FD951E0FB033DBEFED6C680F0FEDF2F43F48C0136C722601CC7C4B48B24121ECB6BF84D6B3DB240FBA1E014F7E3ABDFC1F9B98A16F4D39826BC1EAE44385FDFEBBD649BDDA129FC7EA3F50A5F481D3B7508EDEB04FDDB3006D6EE943930E3F0AB405D151F21E8AEE5BD87F225DA6E155158DE27290B2048D384BCC54F0EB905961AE4CE5E6E93543016F62445AFB5C39C3EA2F3367A0B8F0FBB83B37518C5DBE1CCA1DA9D0B54F34B15A1349A2F03563732DE14EA9BD238F481D9B262DF69D24A91534805ECF57A538D8F08B2FF11E96EE692DFEB106D3515A7C69386A781DB1D5434AC18713CCA12C92557D1E7DFBB15605AE3BA86267F3E6CBA42B6084478E460F092BA2649C8C94D66128FABA2D0EA7D9BCB20663B0DE6EED2623A061778DCB40373B8CA38B02B7A49F6940D6D11CEF549CE80212CE8D3A85CF2D774431343FA1FFDBC71C5334B1CEC4D4E0EB643E1AAD67D1A5B73FBB1BFE47EFD83CD17C798044A504FBBA5726429F41DDEA7B7265A76A48B0BAB4845704C771638977511092BF6C6DC9D574E6288C6A3B96BFD37FAB695F8DE20F28ECB27EDA70A07FB2ACDAD88DBDFB2DDF06E83ACFD3A136C5DF4811D34C242BF9206D579BA8DC6D20E8600B726C9F1B918EA573B9DB2F96444E17B6EDC15822B85D452CD99CBC847AA205EF79E574ED9625E33B6EDC793E5"""), TestUtils.hexDecode(""" -0EECF0C5C5646C6C01CFCE8A4236C503F9C21F7A3FDF1B708851290611FCEC8D28234E40B9061C15212969D6BB647797B77E3CD2AE88051929E75E9A0D8EE4491E6E709DD1E43225C545CB3656C0F84520A56BFE0B3A26E2856A1661CC2BC5BD289FA800CE140070BE31080CA1245114624EA0C215E76C32921E54F83796F9CD9B5F0FC621AF39184C4857667414EAE4A2A7D18AFBE427B48441A99E9650344EBA609B879C42CF4DEB120FB5C44D542971182F83C87EAD8DF96ABBE1A7CDF1A75C538ADA01C1EF73E99F80B792F61A548D3A2154008B20AD71CE0C8AA42480D8CED5EE8099590057D15B339A8D22CB86E0E3FF8B9E902EF7603098B356CA6A3E8D8826B1B02376825B82420239F04AFC1088B16255EBF6030E183FF446745EDFC94B6DB334B4818F5421E58710703493859503559DE0AE797A4194E46AC916428FC84944B9F97BF2BE5DF2C3DC0E918F8AA58C73D92A052E59DA75AF1E3E30896AAECE657CC427857AC6EE80438C849B7D129726D27DE10043457BAC8B6CF88E91DF12ED3DD04B930ABCE64F4A140B551720FD7122C0C201D61F4856FD901673B59EDDAC1486563A7807CB94DA76A89E3B358A78BF8054D7657246200685FF47BECF5AC5852CF2AAB51CA8215CA1EDD6EB6B1B7CFC6D1E79E00692103FC124A48AEA58D21C1682761EC72712D2FAD386AD3153C1A07F40135F38D6E3BCA30F387DF057D4E26FE94E1B89FD1C63CAE97B0E0EB18D53C45F5A1C0332F35FEF2BCCF9192758BAC873D3C48506D23427332C89465C8A08516B1E0511C56DEFBDB891B15DE0A58771C31F398FB27BF63F3CBB9AC9713F75EDF32323DCA0D2CE330340B2B5946846AC0A0961CA3DF970B827C311F4E7D04A859BE995ED60092BB8FECC2B0C5498E9B0F88B4B70DCC50B6C01286494C91EA3390F162CEFCE4B83A5486AEA9FA866350A3A3EB411A601623F9D77585ADAA9DA360B0900EDF684095A9A581DE3949F85ABCBA9525398CD58A81E91AD655649FCD21CD40490A5892C0E8CE4709B1E8004223F8B842389306CD9640A3D32412B4DC53E3BF04FC39424156B3E797E7CA688AE6DA5A4113C8CBA7290315D6A6DEAFA09680857C18B696094FD67DEEDDF1D69A1A53F73696733CA54CF0BD144AF0873249CA50F897CC5B487247A1DD5AE8E7161BCE9C5723DCBCA44796CFCCB5D16B42A1EB3D2ECB6108DE4F2BE18AB41C287C6B4677E56802CD919EB1EE762306902C9D731EC5F0773F7CE7243BB6A9A832C4052F11E5E56D20BB6826AFCEDB7DBF9B4F72460BE0C45FFD628EF44F0BAF2CE179D9627E5CB1D10235D3AB21206EFD5E74A823DEEBAB0DA04BE8D9EAD7487BC96EDFB71737A15A27452792CDC237305E8537619930567AF51EA8E5848DFCAC9871C7B260695A340F03A48CCA700E60220A35A01B2E195BC3D73A5A8C6918567BAF8EC47B473DBB487F77CB37EC6E37D2D6F885208AAA845C5ECFBD2F128CF2D5A16C167D26B00CECB517E753A121CB4CA8EC8B3A5F735FE28BF6E0B988E03E6FC2DCE9569721E1A03D91760C0EC81B4C1DD31470DEEC860469DE3A74777B5A8148DB3E7BA6AF995BC8BC14F30C7567886CBBB1C6D40433D93D52D9D866D897727F55558CAD5871D461ED8756938048C877C9183AEFF67132CF8AE015F59BBD60DDA63B1C2DFEA4FB19ABA2019BB52A135935F73BA5FA359EEA99BCB8254B3A3D82BC2A8AABE2A653AD58B2F13609D762F2D7E89370BDD46E46E55B9B9217A5157BD696ECB992809D1DFB607F1E66B77E417CC0EF7F3CAC38705619BE39FA625EAE2615D9137C0F702A5206D95A2DFFD7ECBC308CC453CB29507B8582A1B200A33C24F6FCF9D3E37814D029DF14D9D7E8D6A98B36BB75A1FE45FEB1A61F212C03F28E9D45FFBCDA5796C2FB2B9BE9AA778BBAB82F9C2BC4DD45B64DDDB6FB1C71F57E11E49246606947A4863434C8CD23C0080F11B31DC7BC0FA92E45415C57314661C1ADC1358AA49EA4D69ABB9A230BCB0D85A8F2885D261584392656B15643323B270C68ADE3D7727B35FF8948B1501B8458FDBD59282E713072F0799C2EE69EBCBB441CC1200047A23DA61DDD7F73D59008D9A802DFF46490DA652B6EEB1BA3D3B38FA04FC2DF2235380B026AA69EE90DF21FC5045895581D27AE6A6D8F99215B116CEB03F9C667CE8DCA4B63F1B875A2B2686B30D1A59297CD7A491178E3A81C83B907A1C7850092C355E130C3C41BDE7839B115E8A51D729D252AC62CE03E8B9EA488338E6ABE1A1151FF037C94350FE5B89964069FFE68C238B901B72847385F937F148519C0653F932048D6B0E7B57092625A1B4BBD72DE1D16E7D96A509F39B3A9E50D1FFA7EFC5842DB79B8C15F2842502278F5125EBB082C5EF78BEC9E872DCAD120FBF2A3D544F15EB51E7C14155905C50503A3B12C24ACC6A37A051D54C6226E0FBCC5DBABEF1C0CD4A89463873379CD95B3708C5E56FCD03C71B3E5788AF19033DA37771AC10373544CC25696F0A342307EB92F58D95353F45B5B5791EB3EA3DAA88CF74B3331C21DD448D00A1DD026A0DA7443B0028D1E35A304B0D7DEF9B74C09C377A9A5B1439D64E7D22C687FE420E1E037D0C1AE5B2DD33093C1E130B5D8428AA2E430CB5FAB92B316439CC9E7593628D567D7055428B7E6326E7A004D0820C22C1CD015DF8F0082F2FF4D39A05A66382107C8467F00344639CD32F9A4BAF3DE73640F06344D64BBA6E4E830FFB98BB23C02D0DD9D1AF3B2E9224CFFA7B62CF7CD552DD26128DB065C1CA91083D7426195F9DB63061C20D9F8ED337437B4D69BD7AD9DD13349708FDE783E86BC1F81BD2A317F3B484DF3912A2FB97E8F5AC62D14ADEC7A7D1029FCA2DCD81EEE23CA87D66BF43E21273D57DA057B35D8FF70404C230989B15DBBF3B057367C005B5ABC61533C623D2D774546119AE87B2D5816B5E7D5039F2D1FA568E338D4EA9FE809126B46D2EC92EDAC8717FFA55D678BB94F0C061B0744F7006E8A0A703156E8884A81AC0D8BD86EA1BB7E682E43F99E2482EC27697293A00792676042A660598B8B54029E00D5F0C7D10B07E4275620C3D193D5323FAD46AFC4B8F4AC825618E872BC184AA97DDFD96BB395ECBA6C3D42580F4BB877E5AB7D96D985811B580417D6B006B1E6FCB3C14F84AFDCBC38D495674B8AA6976B036B5306EE593A0584A55DF7FF214C1C6930CAAE7AD69423CEEB46E95D0DE88317052C5C62B77C43CEA863AFFB22F0201E5C451BD9ACF2D8746346E776174BA21527EB5A32AF89F12F9E26A99F15AE8017FD9720E3CF71741C5D7A23DF373B0F229B89A1E1849D569E0461267267BFF654CCC010F135AD41EBFBC63A3BF4805405F3308095A90D4C541BD82BD62D8EFEDF4B9097AEF796C199521931156A3E7A59A7641F9A0D6542C05EF29CDAA28F5B733C7B30376C975FF08485C8CCE4393B5A8D3735A13FF6704544901B22FF2A239BE8EE2C8CC56175FC928E3676209A003DB9D7BE5DC0FA7C6B3A5CB92F2BB9EAAACFB740A8AB47A509D2BB76060196F26D54690794C5BFA48435B79C854E79A538F1A796F1D4323C016A72667E85DA2FB595E5F8B98E5BCB30FA0BD14EEA3055BC037B2D11B6C4C8522961ECF541E3F2A98185ED50E9EFA20516B0353B0DB96A6183AA9EA9C2C8CB7175158FAC07B08D5C01089B7E835D10ED00D7B3CA28C22FDBF1E0821297DF5EFEE9AB47BD245CC29ADE18C0D0529F9070A2F961D558012908E824B89D95474D0201612B474F7C2E4CF4D66AB165883089013A4A60DA26EBE8D7FF70AC279CB81A22229BB098FFC26EF456B49878913A354F66B8D8F730FCDF1FE01161E606FB890B9923ED849E6DAE68BB3364E6297B66682BA3CD3F0FA7EA4B41B8C96C70B16D606DE17BE72119251F6B64DC78A97924CADB77C228F4118F2C93CE007A4A60BCAC6950FD2526670A9ABCB6436F8239DDFEB8905B69E7CA52BD6FD1D3669B24689E4CF050C7760C0001B7875F76A195E043ACD6AEE609E76F1C800FD0ACFB96D93BCD5A0FFF5F979A96CC82A376DC443D694AB9D190A96EE34D6083702DA6FD73233AB5DC2CEFCBEF22B5B32F66565D0DC948297D83FD04E919CE4705C26506E896943C5B1CE8055434180CC62086FA39A12DE595949C40EE564E5010E22838ED76DA6CB72305F5A160B04777E10B24D7B502EDF16574484DF1872BB115FD6E91E0C0B0AE2FF35FF01F8016D8EFA6D5033E7EE3138769D88A96E20637AF1F435FAC584F94AF8F9C12E3DF67814EC28CB50C5C8C473EA39AEB6080E127FED93AF5CD75677003754C9E31120FEFDE2B23EC17520063884FA1CEE1D4C0FAF3EA7139CDA87C050CD26A349C55362401D311029BC2F21D29793FC8661DB90DC18D96079AFE00EF88B007DDA214BC8800BB7BD30C942CEBFBA0DEBF1E68E9903515C990C49D323A73A804B0EE4EF439BC5B67F298D63B9932C201634AF618DEB8C49DCA06A0FC865744501BF3804668F3331155CF61DB1DB6CDACDBA1119D3558F1A0BA05633AD518C563BCEE51937C0283F3516B812AB2CF2B80305F5DC15437811EEDCBA7D236E7E9AA8BA295A7E8412494E683F5985B920343891E4F44E585A6785E2E6000000000000000000000000000000000000000000000000060A0E12181F""") +d645f682a1b7aa2650f431a828463cdb131c1c317bc2d9a92477f9ce4a7190d287bd352213726174bb967d2538e6f796698924d4808a15377e3d05877a560d2cfbc13150acab39cc6ec464ae5fe51ef788aad862bdce80a3c3669186598ea3f01dfdf9479caf10033fa89d5bf164b454b1c909edc6a85793b2f3662ca4dabc42bf621b2c5f55b357d2b7c97b21a1748d6e6d0cb3c2e1d891b057f0c3bf482f04add99ecb92d32a099443987c25b1a5e26930082e9719fe2ca845343c3c0208d35cada03bf51f8952ef49c18c916c03417e217342ebf7234cf9270522b3f6bf7dbf5f7aff8b245f1833b8cb314f86b1e407f4e0b49f2f2917bde67c9ddb7fe39a64ad96811980b530df51645a89c365602dc6a6b53b67e56c74951d72e0cc2a7ca5ca0c1b32c3c9700fff54c317b3bd1474cb3cb402a85ba80def7b994f84018b9241ca20cc5ebe6cb24b26b4ee21904b658954fd9716004a009b762c5eb5afccfa8f6153d1cba1358653a88c0b87dc6478578929baee5bf33065aea3dc0bf333453ed0fda613d9a35e00eaef91ea96d87b676b66963d2affec30cbd7dbeed1f36dc93527db0a082d494afded3ac6df843e385a53d8a7a0dddc2a38cab1a92a649072768608fead5c538d8767a75f46bb73f7971a41401b8fd50312aadc6fc5f2096007d6002013ef9fd66be15822ca3b001540652636a8dbe65b2b6324885504ce3233f6fab6bdb5d05a10d85ca8b9934a5fe39d7c3a095530554d058f2f99f9c2775a0822ceccea548a35fcae73ee931ca01ccaadb226f91f0104743c423b220b9c76654c9baa1a1e60310673fe86e8c71eba544763f94b80dd075b3fcfd82956da9ffd4d4a0364e26cf4c4d7f0d2ba435a4e7b51b01e9cf55251a5f8fb4e32ed1fdfb6dffac187bfeab67b7bc06fbd1d623c68823d45d708ab29117ec17fb2df9ff17378ca7a021b504e678e4b7371f2aa05588d710f292e547f719f7d2e66ba39d382807ccd3cfa8ef2d33516053e6ebdb2a8584982efb880180c45480939af7b3d72e71d046fc78088c16aada249506b079daeb16056bcf49d495e5f5bc9b64125f66c809e02282e26a8b8c9656d19b75eddb4310daef82ff90bb199142ce3ea68dd6ef33cf4d0f2e7981f2d6d78beb9aa10ff7421804231b02b39b3e9c4be9363c49fce0b5a460f49094389ef2c28bfc45c805a563dc2202bd9da12485eff443013dc8090be20ba1430eb71516fb36926db06d59f5313d43294d09a5c242edc04ca7f1f69b3f87861fdd572385ad400f66ff9bf127e866957b5b7ef7e16f0cf93cd10d77b87894fd8c0f184f0a359cadbfb5fe6d91a06bdb000720f202f077cd4bf5c8b149565c43b4a07cdc5a3dae7599d26f3931d101d086b9546be593ea0bb85a1807eebaaa798e57d88d4b042aa3e3f621206e22f66335792b606f419d1dc63367d73dc462ebb177d3d9d4532ab6c39341b447af8a982d24300226fb367987aa37ed10223083e4db66a5a344628310d46174e0c8b466fbc0809905d416e1b742f3749ffe7ea56ec6c28b085d71d4e315b4e49d6ec945d23ecf5dcf503c59b839446abaa0ee57179a6567ab4d02fd1025b671aa5a464e1892e9e2b96248107fbe5fc4b792d1b6f62ecc6195be7acd19d76eabee8e8deea2ca2661a382f06e4ef90179a4fbe255f4a617bf6c1c3c564e05d1eac7cf110759364e7d3045b2330a52bdbc8ab2307e876df8b0011bd2361471c6cfd7fec98dd4161bd7f7517fa6bdd2d678dd4dedf71dfef7eef7d28d03131aa2db37f163d16818aac1e4daa94c6fc8ac8d76f03f981d98166431fb42081dc565049be93013f71832aea1c20dba0112222bd1acbd7e7c112ebfaa6e264655950a6fd78da09d55838d2f79a87a311eee67f023af189511c7e215cf8bf5b8f47ec397ff8ed22f5825814c86712c289977998dc8c7ac8eb60cce95ba56efe213043e7065d8c6e6c1c6b7c4b87f807e6375fd93e8133b9ca61735d2399bc2f0cd4e6d28c21c4172f26808a70ec7d5502449e335abfd7ec5e45fd298cdfc8699b2607745c30c89803cc741b1c74fc6698fa95c1397b59ce6a08a19d3572fa395af1f913af021cce85d40f53d511b2d6ca6860ffac07dae4de99cec54b0608ccefa3395e327d67aac3f8940c03c737f0066da5435ff060320aa68868b2fe309669a014e0ce7eebcb3e9f3d27684c0d14be48ef4d8de1f0f541c2dc22160aa238f736de0f31996fd1e554ddfd33892e998180e4a47fbe34f6e9f2004d009e83fc55e7c921a73390f6fd44a7f32122968e174fed54ad1117344325897482707ce6cb45121266c870f3f560c4315f046e3798073ee0ca7ef718176458c761825f7288b6663bf48b6efcc50e35a5ad124772fb64967056ab6a39658973471ecadd3d666e6f0377fad3b7390dc9ea67545fa030d1085244082ac60d0ba4d6f0ab44167571324e40ad664fc95c25dec94bfd59b32332ca5efda8288965284c7f88fb8045af9169eb63e98405e2aa3e949d4ebe07f3450ce6caa14e2b399e26a347d88b2fa8a301032c39bbbd945ef5d213cd4b3418c25cdd175a3ab8ffa41679cf6359ea3c28905309af59f0f92cb1db581e21da648f096171953fbf62d53da61da8eee1d24053270ef6911539a7ee93c6ff45a0b465ca879498e131d37d1a05be88fad8cc28a3026c7853b9a48bb8f1680889ebb3978b738ac7c3c54a0bbf1ddd79819a70e9d083775095e1daff66f72df70cf17e746c70f3d291a343d4530b6c9dbdc861816ad799b1a63f807fcf791fb1ca2e3160543abbd10e4fab61c18c3c4f150519d9690f7d22c10bcfed5c211a6af6f438737402b425c5ae274ca98716bf64b127ec0c7a6cf3598e9bac44149b93310ef5de9fd8381a961d5b9c166b7a687072a1aa27a8ecb2d9a023d353bdd29870650e0626931654ad80a995d6c5ce63ed42ec35444ee57444ef7edf45afe7255739b7ea731dd4c48a1497b5e6c135f4ddf4cae02577920f795809c1d00a391f15e7e376271c0cc0a09ef69efd28f6a44b6d2a9577ab7fd2198f81b92cf4094c7186e72fc3a379ec9e31b7bc12873a0008f40c14a81180f4caa16aee8ed827341c08fa4c98d3be393d524abfdf5546999acc4bb74e6d72b7db9c443bf8bc300fbb0d19ab0a716001cc87dd27bf2605930cfa437c08b0392e8526a26dac97e1e692baefc515eba1b82fec70c5eb4fc950386be3a5eb3379537100649cd192d611dc90e5787dccc69a364afa632abb31de145279e9d736ac1f6185f332b75875006f01eab3a48ad573d4e9b6849cba181d1aaeea5120fac5da72d81e7a36fd0847fdfc5f7f8f589b98511bc086a107d1ccc4797308be5b590ccfdab138078ca19679a5bde6962909491e1df2b048924a235819a7a28e3e3e97105a1a400c0997376ed9ff34b48d6076fc8d9668e6498171b82d7dab2418146610d80c2c7be50f614c6d5adf8511ce282d2175ca5101bb18dac9207813b9be0510a2195cc2c746d2bb99d3049f29374664d74497e0372994583c788765f3ac918db9a4d4d1f2c2482f50d013e7e93e0a5228cc03f4db0cfd14aacd90ed05b7ff5cca2b00f577e0ba47e7a0eda068f1aebbe688f167e3af3bcde28b3bcf0e89c63389564fd60be1c8919ac245db3cab86fef9d0bd4e365c1edb0472f4ba23b22c1918a399e3e08933031b2d0ada07b4c89abeff516f06b67e2b5c6bfe4fb6671ea4a45c375b9310f07278f0594e4943f4e45098e3c68c2c7f8b4eaec3b3d49a21c077469c84407b2ecf958c7aa3ccba4833a0b8c6f6cd8475c4d239608b9d25bcd9324326b4251b89579f2e902724f26943ae92b95487b215d719236f69eafc46070695e8d4a93053e275b93cf87723bdd589c15f722c093ca50c1d54121bcbcdff8c4e306cd4f11fcc681d6af09cc0de076a252bc8583b5afba1405798756432a729b177906ace7f3b8340f3526e7688fd49206e6853b4c72979469a30c584786f2b8c75cadea9eed04cfe68dfefbdd2ed5e1e2b3397ffab7c5d84e645a4049e50bdb9cb2453092354e0112cf00fd214e22681e4111a7d4563b84828d6bf6450facbdeca5137699c551f2b0c7a0bd5ce147dc71dc2bca5b0abbeeb109e6e951115c9c8448d455bf723b8e18e31b480e5b17c8de45d3f73ed313b9bd6a8f5156cabf25eea4737d4dfc8ffe042c6cf665bb346d89477d1faf60ace914eff5db92d82ab2da4e08de466f532d1f7c639d71e6c3dca9bff0c5a4948540cbecf4aa65c4dcd7caae9cc3ac56c04511518c1ebdd02aa8285b05393ce9fc2d2a3d8fcfcf79d4f1811d9073346d67f4f9af28d15706d577f8592c653c315a396e03f3dbe81c339c220aabd4f654239b14dae453dbd213da8819df690f38ab52a1f67319dce8ba5cd33e9bd8f5e61c0e0107e97b7bdc384269d410cbb77e19f2d89e38305c6e7dffb952e331bccdf884956c9c67ddf2d56c048b31ecaadea55e8efbbc94ee0a19980cd30edfc85d6b3ebfbeaa51ab1bb01008554717bbc6b17ce9b8b255707f95b7302d63b0189aa4e9eaa966429c1c1b9d2aaee73460a2335455f8e9df22a2c3861cd354f5163b1f1fc212f709c040516172a63acc5e6ee051f5a8a9195a3c0e3000000000000000000000000080d1418222b""") ), new SigGenTestCase( TestUtils.hexDecode(""" -C8C32C98B4C3329B1E9F9B8B0A06F728FEC8DFC05CD45B51C28273061A7C84B44D03DEAA1D3D423DEF8D01DF94252EAFEE18AFD0B714F246A2AA8B22919F4A64E8254BC8DA58D79694F68A8B33FC23190C4D19E3D686EC528B46E14D752CBE218D0E18B655AA5332AAFFF4EEB5CFFD2BA6A03F60DC018CD23EC259AA4325EFCE08852158642851628354014253336656040034734085244624702650458046023414141653265662553257528848144434538583171237621870046622542527580662760688425754461883673651187381743864383543514734285686547356774154037857147010824422821820372371434640278657362264124415854343344041688413722261224658655223800244426352431335075843223847830638802787087632058358458134612063704650052330674634702657828852755171178100888071574872500003761125174467551513406085034688414064261281865718534556361580681066615474883681774570757571780007105873237730643787603255741251882778647716627735424330287653567230817703068376113812788174132853265501737207541765673284844633087711520768836556152784146844502445608448350455765277306601008336883210200716413782342871820515037658772672513172866057305014605013778856128828263337372405472843534375648655082510264478061188683265047702226038855710017543066112306303885632257413744062041317752202814804005205448814280410780017846728458263376183744528251332866682020484544067715461251381023268133503550626017320763011688141043558378413875642643444584351184365058376728644264005672381788337041681643525641530354046426331448556436657662128333156784163856374755524078102415500647382668666204378324674242332458875560880870446801506724870770075377623558535018066536113077736557373140121445368728505234510843712443083486066118634707435307287834841377048724203643811402168118565240877002038527641833114558786071676284684057368570785252016484650654480760442014125342136012513131513754542527403415643546752574520100488478715505263884185412513443846738708103777317714028531710677723682545550823825506760431583105357435861166168085225017870015035876442236026623862112188700714876376877706235072035840614340577178021553082422411251301420001307586123370726600337582487275247806637312456726385287223783713615774466050881878126110710021758600135101147142066365521572708410557043546161410781630038172422202645550360675605422888073255353264416833160257185872065350608713265217047530036306438828400667786630573535515217683235415121861604404228766416241310412807607544783206736820630303115444301271607246665073637418272420826411083048741645574851556481310322648258642846872020371271453707105300457683437487543257460657574378450022804404154248422852870054400115704171748041775074284552866412884625787625020238334401546627850511538557453800533335000553567035164313872271652448031663187004542613853645488711616002127354808730021575550780772055654173636682015662428213111586672337018624237806607430261432561653583383546454223153687813363744535756030611834227116883466042873648850082482071801637617701364885353218608856781116835784815225000572468806855765577805768462876401546171442778806140835684815656874817750328776567238860658770156531530633503227851364168542031232554515285878430550188057083146685505544383510160372216041617018142A2055798CD4A9FAED4129F4762117C2F9FECB68F55285D58DF9B1D97319AC4966C0BCC41CD28E76896A2CA0C448C002E606702A1D2716B18F92F3D248C5E576EE28DA7A4928CD072E2E06960D642D78C34A55DB793D4C6C27D68E2E7C2E05F3E997DB884F02DD4E294C0A37EF6655A74F98B3D118D63C8975645DD28E326540E289BCC194695E2962EB6F573FA010D9AE6DBC9DF30344189F87FA5A12E7F096B409CF4905A15010DD6CEF55A88E3A39ED196CF05DC1FC8A5B706452F4E49A2D07DAECE812F69207EB3E4D86289E956731033D6F0B90E9442840DD8ED3D4D7298836D086D4F171C0AF60644B7EB187EA185FBA5D04D6C42BAEC690B6F1D68764FFFEF1C719F690A2BDC241EA2A145A7B9193CDD67C671D14A676173F352AA90886919A765B2D89F46E9C13F35243982F81CEF10680967CA1D5AF9331BF64951F1C48CE1E0A24918FB07573F3899E19D3BB2C386C943D2732F5D287996C78C67DD2031BD6C635D53C51DDFC4B71A27DFEC7A308E568F2805F667B1A85F6436413A186571F99CC842C9CF43146B588DD7B0283C5FD1D09CDE662B510BD85FEDD31E3DDC957583FD08A1F8EFCF2CEBE014652E64E558EAA832822D089A3D82911D671543FE6F31812A435C1741BC2AC8C5B33CE4E3F546B970733BA7384152FDDE245FDD7989E1CCC430D134E36049DB88A3817AAA482BAE3B53D9A448FC536AE8F2D01919588A00A2A2CD1F1F48710F5FCA8709286B4B7E3F14FEFAECFBC830D3DF005FCB6612B782AF5DBFE7C2436DB6385A0F2C929849785ECE26D52EC9CC70837FF75C7E6D280CC9B3A61C8618C2E047BE4DB9A6A89E22EA3AEB8E2953B5336A388E3837DF09BABC71D308298D735D37FF4EF3D0D65247B72DC04E1B7A61BFE131E4264DA5A46B664FF4C44279852214BBF4867FE3B8AA274ABAE01EFCD237DB8D41F71DB2B386F596799C670C042149E289FBC3FBE0045994A5263E710EC3591C770717F5D6E4362ACBF5A2C133E9896AE4B59553353CBB626F854149A25728C4113686F16D0A6EA7BC54C8DFFBC8D7AD3892AD37048912B09648814B415D74408AB3868D6B1114FBF9739517D8AF886316E19BFC66D55AC4F76C6814E96C6A8F846961CFF17C8D6A1FE362D071D5013B2349724BAFE710D990C8CB0C6438535C5AB62AD3948140C1DDE116B7E552E3677C001DDA26E3D8B53BA7506EA0069B90A26FCC35FF94272C1C90B3D910FDBA5FE8E2AFB5B955847CFA4DF8460CBDE80DEE5DDADC25C00418C126F7D0C5B8C1B9D8710CD3C995500AA245C63D9497F6279130B23347A95A9D5694B512D4BC088290620738CA448B08ED871DADBF1725D2348FC4DD6FB64003E044B67595F64D3514B4CBEE61E9E12F1163B56C105EE952616A331B263330B29DEFF153306EF9CF27C9B178F671E998C07DA69C9D38B750308A7D78ACCD69EB30E1F04D86417B76360805576DFB5BB9022EF9D6FF249EF9D66255A03535CAC6323B084C5550BDB703159F570F47196115BD67DE8BDAD32C9BB29B7C6FF96EDF4313B101E28ED28C37AD1DF54FA6147F3CCFE8A890A423B047A2613CEDCAF70C0FA123BF1377482C1EFAC44C483539F54D3D54BCCF3CDA71AB23A7E27417C317F5B1DE41E99CC1F695CEBDA3A2ABCBACBBC7E87BD1252DEA50853F4C47053E10AD30490FD3244B0AF23B7F869E13F96591A363E05574808FDD2536E7887C0F621600B2352E3660FC80B7DBD09C4D06375CA6AD8227D60E19FD9532BD932A15CE6A79EE821447D6DCD26367CFE447C3FF99A408C2EF4E1EE16C0B63EBF1101FDC0E66C5F5F4E99D277876C7B007F26AD220741967A0023342B09CADC11C0821B4E3B42F708422E36449C37D197D4652260A29BC9DA316009DFD9DCF2FAD8E7C66E0856B16E2DC625DF9EFEEB36D17E56A97E85BD00988581F28A742A85D6EFCBCA370FBAF39F1AC123922CA40EC5B180D40F5EF9EF892E66AAE5AFE52AA7E0DFE6181A0565CA6FC3FA284DA2DD4F6FE76C5F3C89C38F8C635AAE6B006829BCA1EFAE1C06E35446AF3D64009BDD36C17E5B12B5A03A64E6BC2E83BBF6E6C3785933564343950D229072F11092DDF65DD267C9685574D6D8AD15DA4B9C835164E95215045F7BCDC7315374289AF7EB80D538F6484F5BCEDDB3AAFAF69E1A74B177DE4FFC6A869B9BD98F7A3E7109C9DEB78898FE57BBBBEDA72678E7035EB555478BA70E405BF2D3D8563B3AC065627BE1F4419E716A62095E6A7C5A54B22327ADA84530EB5761287967E6D6135F523F01C20349E337AEE6AB7D57379C4E919CDABCC46326E09EE6A254C08440713FE744CEE9BD8773783F27C28F657F277FF4D96FD0A1E0842529D1A55D1120E0B0087DECC8244A655C43D33019A9BFD54ABB232739A6D21DB35D8DB48B8F854E82FEB295005F55D9626532A8611AF392B67B0191530FC64422E02F9B99BB0E337C663230B5D7C92CC34EC68ABD6D9A32657247D4F4E90139DE57CBB0CA2AD179F75E244AD5B4D6A4A21179D5F423A125F3A52DC6E7E99959F3E3DAEF1C56EA39ACCAEE0B4E0EF1549763CEC5E1A138CE4A2B1375A370E04259E67ACA9E833C2D969934F9A494E03F10F3B843C1A24615BBDCD322DCD2E633960393DFAAC490E69ED03E9DA0E748EE1C30683034389D6291D6DF8ABEEB363F5323A20B8E09715EF0B406963FBD178D5F46954B356BF20B90C670F7946516A7EBDF67381BF26E5AE7AB0BB69084B3663E980F2C0F8E5180AF4897C6A0DC2DD052417CA772DB1F48F1336B49345759677AB31980F037FC4B6EB7546942659C5BB685FB2C862C7CA37505BFD34DDF9AE301BD9296F98C24E110E410068916F98D5B1F320D7D29B125FA3601A77DEC33458BE0875ECF4049996544D2A5B35C628CEBAF0370A8F8502FD349A3C431D4D8ED56281184723B569EB08A904CDE35647929AE39E6A112365058D618CD44DA7685D331B7A16AF87D735C6766E47EB49F2D93E05E9F0936E923AADD01DE901B70555FA8E4E16970D4272B29CBC34C1E3B57ACD0366DA6B3D0BE72DB205F8BA635F0B32A3A38B44E257382665C354DD0182C0B3956042A87F6F98ADC5A2E1E7CE21A4E21C8750913DC0FC955F2E482D41DB96C35DFFA5417233179EA6245BC10B69050B4074847C89DC5E8AF80747E9B4A44AD7ACD06D6D051A3EB7B0CB3D8383950BE581DA314518C85B9E5E727FD3136C7A1E5B35DAB57F4B6331F565C66A9753743C93FA31E8BED38A489B16ED62FAF78FE5D69FDAF311A1CB7FA4AA4F0F1E56E3797802AC6F2885CD7A1D38B2C944C47F4F1D937EC11DED2DC2D8893A651D1144629781BF77E94DBAFAB247B4955408FD4983CF62F106D93D49738DBA52AED82FF67A984C749C04CC1383DE98C0AFC8457B9B134B18084549B12F7C50949FC2E5C136EF2CD2A05B81EE1DADCA5658873E65D09E0DE3F6CCF51DC6EC5157EAA10BE575101D83614A4B679B196D19F351B4727DC4B67C5E32843A4A2FB41AD38741847F"""), +8ee898ba956b2d9173be3179771f705dfaea460258d89ebb97518aee95f7560af3a7aed5924ba5d41fc95d1e38a50f933d02fdd280aa39c5afe63c3d9d1794d60cd72286b030b4148763878971ed0b5148ed040f91506cc5443983ff03d71e76f9f9c56b1aa8cef53b23b78dfadf10a4c5a1644dd5b2a2e33818effc45eddc2e4335271321448822403470047324138804438087588843706214268172475025276564145746423461361702544370526584123688122766438025344681178752630841205185142880034051070654535540731775307511227772152582388516212136381805636674882762427882403274050386855208724802323635371166346386078303506483716037112661182682653125854143637634378471542132612773664523401452863833035254314658307485600331255344301038588760626073667657566824783054365633462288132682748533875185444862162254814415860001373078718255261684106327781124677850673185831163442273852312501053226141146222163634824506148584236864562146634065825411836882440250464233048824316504534284448710354356011222712187424043071220737224254741123321834651238540136100320462350627487576313802878824634827083482111278134020462438040464126408725167702172738314238282431041864706527654420367467388153108253278207884852246535046221737521426013710361237422631134378231064331038366647860156765065640638568152013685218854640261823187005008782410321125585430133008257133230477257543211558420767576103710054360341783614605248464771084540585787050215372485563434880427653241876310603860874544450548477278031034433603287642374200174807130835462067337683542725204412564185801303727563151045102036044470344241431513253750453344181068301323415742204353382058206486112246730432277510678825603044373307002101505886672800331788627547508848481601812208166603083203168784821438117303781442370283147018313617430171084244275611261755507351877717165262323632087124473071680850882748858017077344541605881657867251885383643636341482257133852421828175577536553188518014245127151435848786816878767508827008813446037762050021601433060112405756553576443238728042504312434387673134061740013051122052603863687228884263102734303648422212081046737102202224817233883384451275044472426612740355787867625181118451686770774617255260137575557073363187168671736888138141114578031460423674014223161125708738168365636487634115108663062235075448825402171750743877411053310363480603171263331785410245534061202488708057726864521028558241854255843757183423680846382543841745715138847777161848558266446618833657585682227476126378777007712556452110415211151557863105527250341262385616773256816580020285012073863107105853065263780724346221555084082217168843148616386286504840733176160868120580618151810200358586663211701312313183338517302461622880660528360255424478558281645501247851806440186653100125027022143448400050752276372082722240442876067275785022216006585466382364038365267686378250502150410212655602182568087652266441770205884064038705815040665563873705223720346716224782001233877143608776246446162061440454784430547646856536083466603722577250585160465535136334037007631745875388337766277366743877607052036743878504071126007836356552360764414077761063784001337335478033158818132673068800873836568074230378648445702875646304c0271d6e8c228b00eafc0d3759106302375985b74ae9848bbc6737ca0e0004e600a1208cca1189f40a7e02deb82f24343ce1dd15b6edf8bfb273ca6b01a29b9dcb7ccfcb3603564612bb0278ad176a72945dd9537ee8e61055db402662736e6d760b2f48194cd3c8f64b7157c0c598231e4994a50d837e29c7153a2ad127735672361e7cd7c50ed7e9466a3794c388dfa6ac647ae4fc7b4fe23e4ebecb77b54b382fd35c9d462acba17a5c143b52df0e5fc607cc4a5c5c504cbe12b8c226a0a954f69139cc1ba4a050c754773e38c5d43524ab7b76179d51ea7cbb54edf38fe67b71031273eb8c38cecab0ef49418716fbd2f2977fb1747e9818db3a8af81bcc4f93531f0e6f1a96666d32b2f5faa306648cb48c670e1597981643cc703056739317310728d16f6b0fa1ec0c27eb3897a76c85a8b33cf7fbc8dc5577c96de4c012563f84e9eb255ef38c2f3ee893a514f854ea1032f9d4ab2f9c12334f1fe48fbd71b6b115f33f6909f154596a3eb69ac7c91455c8097f5ebc088f1f7970f61e62bd19f825e54547c9ffacb0be763f8d85e4aebcc057c4a21d87b24a93969dca10d8ef3d8cbe138dbc8142fe9b25d3e14889d9ebab76b1c578757992eae0242b4fc7085041472ceb93e91ada06a75f7fd0d65cf21535ea945be4c96e6861da836b0a6bc8d524fa0f5559e28de32f5683d83e8359bc1dc63c579612c0b8fc621a7574b360a825e5cc74f24e03f171ef6d1f46e9fa47e2b2b97e377356eb0221a29a0c807c43988ed87433747039fb3757bf45db3c8767136d495e1422ddb72773b6839fa9bd028d9be2ea8af7f2dcdef13fed5f0fd44cc07f6096b03d6d4e7649b2f408b77f77156b7a52170a778e595713055dbac83b783c18765bb7dd90a6de2ff459f71f8171b5e33342a3aefbd500c222bd1224f1a3c3cd659f982303eb76c1a85a54c14c076ec49ff14021d84b51409729358d658e94becc1e3eb1c11bbfe79ef4837e9f0ee82bce0141f6ff8fe89567014c5cb2f077ca957e5d0c8cc77f2c2991f9bd50bfa07de7f5257845b5155e64948f60082027fa48a4e573a5879442420d39868dff08fd4fd4be01f0f4029c1d248bb5f0460cf9ddfbf16ae8f0bf845e472afb0c116f442f65c08f5abc517d3f001c2f6ea767d0ed5392bbb6d0a5183fb9b49410c7cde2fcb06a388b1df37ee982a8a07f0855b19ea4c2debc518b22d2347a1861a253d71cb980da4d9db62a982bba68b5d7b67fcab2d59a12b4a07fa5d720737d3729ac05a017ea2a6a14b1e0d708879561559da4f96721043fb9e525f84a4d5b746eeeb29c786b7fb0067c313ec6c3e1b15babd04503a437fc65f09be43f52deb92afd83c409c3c844d69354c9bc1fa3e4b57b9590efe6c64f185975a82a50f4abfcac043b2fcfec6992c1b0584306d0f6cf87654afe94559a06ee672c0d8650ed629311c63305a9b58679276faa5370a2ec225b693527452edd3a654eae692178995f0020a8f98d0438dfee350430b8a32639adbed99dbd89a32e3a1aac453735fc706369e477c7c176d446dd2a75e39e116643e3ed043d8c1a653a5a6804f5cc5b2de7f0fea5a9dc5b1593bdb481f0de3e4ab6881c81b5785e56a4a4c4651571a063df331bb7171919017a9594334e9befbb31b696a43a50a5768cb523deefc30c681296ca22c6a7d29fe07cc3ceb8693721af0f3d157348b22a7f42fdcb480aee1a878e476add1575e6196ae974075919e7ce786b8ce2b9122d88888452bf8d7d152643dbd3a2ed09d82324f0bfb16322d4cfb5ccbb0ad9a5d6b00a023a2a0a131c8dd26bc8c6ed0af34522c49cb7c171458cbaabfc30d3663bcb5091cd82f5a9564d835cff8362dccd71ed1ce4ff4486faf9f7c1d4f7f4a97f7f6e39cccbdf894828c9ceb0480e1dd8803ae0105deada46ff07bfd10f78e40ac8f6c024df3730f9125895012ce82f4141c1d57d25709c43eda091d15c0516bb88570f85f83ffeb0bc566d4babc7cb000afb3acea4151fa6872bafb8f161959a48bf1350c2de505174ed12b1c8ff13cba9fa06208269efe0b7dfec049990482fbd5e0befc66e6cbfd4a51247777b186fc071d16b6a097a026629d9ac25a8b19c4d792fa83676aeb4095ad170b0444699656838438f44e99e9573843775a513ad2d410c1b75e8387b0f43c85a7a47de8b178c997df7caf16bd0447e58add034c4d80acfc35d028de6cc5bb629b1246ebb814e162580325ea90f11c45163cb54405910bbe326019db6e01a46584672c8d890e1012244c75adbf85427ea5f3ca3885d7fe1bedff5181c4710b5291e9d40762c4ecb01ec87f4c56ccfbce91c8cf5a30cb07971a987379a61884221d5863b8ac975db6cbdeaaa9843a0536db58d10dc69fbdd40d50a87330e69b2f37f68b56eaeef9c954e2ab82ec848c9836877c2626a1e827ffb3e9306b2f5177580fb08796a8c84f45eeb9ec0e39e71323dd29f2cc3efed0e3b45347ad0aafac1a55f27b85a097ff3d472e3433a713fdbb7ade4c5be07db18549d6a8b13e679e5afa6697b7dc09b173582cc2cbd6070947638e5a6ac3fc55395f1cd9d3e721cad91c561c2c6f1702576c164764e5681c2b3b743a69fcfd6f0f83e21b695eb602f0f1c93ee7df80b4bbc1bf9ae1429733a052a232c3e3783a59b8eed4fdd2f3901ed0e0d160075c08c687478ff1156d239e0c21113c9281854d9afef67e2cbb6e41159124d217c57ab53cf667822e7dd01ba93af3e5948541d2e837172ae1623a07ee6155dbde9d2a576df6186de1c2aec399d22682603e7909610e463cccbcdad8addde5a3b37b7ebdb7bc7c2852bc6603568edae193fa204bdb5ff53177d1498b4a6d8eb5ef0a40528fe207567e070f8315fd4a03dc968e3f74edc11a3d2373821d38b074793c2b4bd3a39005d36a787ea2ef9d355fdb535d118af4897c4428d5e9150378e464ecea9a43a791070b64a455729d02565c6ab91771a483375158f24a0780ac7b42226367cca45d1b605d7e60467b50ae7a70d87b3b5020fd4e191e651878b509f5b5fef74fc0cf137ad6d93208a6794f17241fb462833d223a3dff1f179c69d7afcb9d19d803d4c7933456beef432fce5d642f72fef9b0e40211a660eabc4df8354968394a59fab78c44e36e65357e6a5963d828a2e801db6b266daa51de44ba2ac6bfac4a6bd0ae41c8704e290d7515adb26867c4530564bfdc76d98d4250539dffb46fbeaf7efbce573e177378745732dd9325ac98a747abcff929413f73e27502c433b589f879078ea826823d4d418660ea49457b21eff272778b240ca64a56e2349476dbeabb27c57bd51af02cda5b310a0eea25d2910c75784be6910418ae30f36bac9e78f80ea3fb68c681f3556d3f59b9516ecf88b4c16fdc9c5a8b8cf14e496741413903ebd4500b6812e4c3d2f7718d4d0a2e39a316b90f546a5b9aec24606fff6559cdf9ab48797a60ebdd5229a62dc872ec0d36f9f2afdab779b913b5a2dcab68943bebd5ad57a"""), TestUtils.hexDecode(""" 7C29C0B8E2A111F457E2384845E7698DE4BC9BAEF093F15EB03828664AD31C387B247A525623282460D60290FC479A928024CF62571A57F77B17DB0AC572CB59723490DF79E9B1B31EF2C9488B6D758C43EDD9162D8F6C0B03F43B08D646172A1F8DFD71D4DD805A3AFCF1C4265BEBB71FB251DC9DEAE670A664BDF943ECB00FB7EFA37624953F94CA760013FF1270C1EE7FF58756CE19C204220713724AD03B10F1D6961CDA361539A8AAB6ADEA92AD782F441428C0018D85C0505BAA793C752DADFE92BFE8F033931D47575C9F83547DB18DAEC0FEE90E83967E0D0DC93281000755303F0F5F05DE041211CF842404CD5E24DDFA3C7C83DE3EA21EEECE37A52E16DC80A350B3A18E88EB3C81C74D25B56CDB446F6198DC88F981F2B1ED8DC94194D81CAAD971A9A3933E9319047C5F31530C7C98793A0633875A14FA5635CD1B0441FE267E79C1E874BEA968CB63E20E7C48E7BAA9CE8393FF9A239B5A1D613DA65F7DE78BDB793AC72566FDCD06CDAAF56E18B773737A82298902F7B4890EDABB766E990ED87C94005A2E2450AC1D0192D72468F81DB414F88CBF07707A95F549B7A9EA0760821AD710D52787730EE8917272497E5891656176F991F254A5D582B5975F95AF740421A3C18A82158AF11DB15C154F17ABE1163F997C64A3BD989A573D12642B9AEE87C1612A39A8A4FAF25E35AFED3F2DBFC8FC8A2F9DFBC683CDFA3227107C50526149557CD773DDA16E36782A278A93CD7F4D8FB47DFC37DC3E389D164913316A885C3A800DAD0C57B1082BD4D804BB6A117C3B41E7D8AE9CC9622AE3CA8EAA9A0B502FE3F5A449BA8E768D2C98013F681C68A5F4AD3CBBB83F302457679BCD3F35C4D6176DD8D2B670E87EA291EDCCEEB9917F98CDDF5EE1689DBBC85BBAA30D191F1965EFF8FA9B0073D30B1E2456FAF880110BA9E75E4E29C6106874D32944F49DC7E7E7C56ECB9D287F2C2E87A779052F9B84FF97AAE007012A5EC497C4809F0193C69E5B29940510A354C866505424D4FF3853C94687636543115A73DC407C47927EDBCC4E0567EF4E451F0E464A1385D2A0D740C7327F6E92EC6091845356C2620EB163D9F774D7781BFBC6F6F652A4A2DEC73203DF5643E1B4C3C3DCDF0B4A0B160598EFB56499D2DB1F1E76612356AF3D708F9D61D968A6A0193D9146B2983972271A4C02E2136E6593DC47FDE4FAF2540A8F7744BC3230529AD1C9D2FF65B7671B5A5B16AABACDE8D45A940ABA4171E21090AC6AFF54CD8230F7BCAFFC42C028E6023E55DD02E4B7F976998AB5614A5681C615BF8E9E6959B038188F71C75F6DE44A6B0498F2A9254F3B0968AE7DBB49872D775CB0A5725206D648862734F202DF470770AAD184F822C56400F16F30F8BE40C463CA3EB5ECBB15D51CEBCCEAB43BFAD7DE7679894B90419B65912D67DCF2335212E82EFDB6267EEA331C1439BE2AF62E584C222C1052AD91C7F5DB6AA649F230248A14AA6A532401A28ADCF822089140FCD3B1CF2358DC26939850DB2721750F1537424F6BF2020A1B4684ED79402917D1028C1B59076867DA809D6C5D3F47277755384C20624388EF0AD68BBFB6A63005AD1B6E48ED654E8362B2AF7BF114F2D144A420712FC4EC71D408BE55EBCA8C2F185E7132196B1B76AA7BE44EB55DF7C82C768943D649631E4D87B408DCF8FE470164D9E8DD1F48CEE7F6BA93E239F889119A4DEA118D93F1474E516139036D640EC788AEE708637A619BD1693BAB6C9EE9EE0C495C0D0F8912C0F14199AA69B960F53E4FD8E2771DE4AAF72117A5B2388FEA0CA3BDCD594D1760905F26482459BDE80EEDE3FC89F592CA16B65B27E9A21F1789BD0327A26EE2224C61D80AE8FA6053480048D15019A80FCB5F3B3C6F64C168690E4384AC05E856BF341531045D2952F2CA8BAA0B8926CC41AF2D8BC5A1576292DD67114D521DD4AB535A77E5E9BEF8EA01DDC7C65446D11F90D6CADA94AA1AACFB1BC3551353D09252FE515A465C1879071F6FBB035DADA0BD25A022B026AAA5B5BD420237FF097099CA2402E68E4530F97A003E50CF693D1DFB551DC4695C760138E88B8D11F3075DBF8A6D9BCB9B1242648C0C9DABDD9D49CF132B0766302437C0CD81A0889585869DE92E6CB30C31265C84F58E9437CEBA891422967AA546EEF720A8FCC16EC7591AA0D47998275DF1AAA5ACAD1E1C5868CA430F4FEFA0277262C69311FEDBCC083114AAEC9F99FD98631137A117A9B48B32A6D88E76F96DC58D741395BFC102E147C456D3A78A0FA3D186485D65B4E6755B53D301BD13CC88E75277AF3CCF1EAC6E9C56FE1F10DE05A796A14381551705234F65DD6E717E9EC275E38690B73973C9CAB27DB909C5C13041723BB18EFECAD808667643E87620191008E4D10F471AD153D27F1FF00D8AC6A8C5E59197AECA5AB496D8D10BC79C49D16DC7948C6AF62703D36059587F6EE038820A84C0F287D79C713B066E1DA5B32BD89E5FEEC248B34AA5841E8666CBF09C47EFB17BC82170CCB557D41D40CC87F2E6C0246F0B272733854CE162538DF34559473BA5979AEBFC0D6A16EA7B399687E672145A1149E382954815B41E7E37CC415057D7536E65FA1A35B8EFAABC7B9B0000E08B593496B01E8F14FC950632C659C0A7F7D59787C7FE6E8FA7FA0211A945ABBA5044918CE8482C6EDB366368A9DDB2F2BB66C146BB50251CE61DDEDD8D6A4A60FEAF0F794B7B0DB91C52D7ED1A54AC85D7907BF3A5A96A60BDDD08F60148C0B3237DBD56628982375A67F025B0E3F9EE13DF254E1D6DDDBB057203CEB267200C7788D01342C064FDDE996183646FD3C1ABBA5D2155383CF391FF16C78660D0BBEB549483A4A4A971017A8659616FBB1C3A8A2E83230B610C0C74B8EB32667765F3C2F31F8C0D4BDA3D812DB64448684AEB482DFEC5C37EDE742091EF7EE6F22E31CBA2C9B9A6656888F446A1E9D52D9E6437D22594A830958CACC6F175D4CE8423178B71E7CC81BD6DC2A7F6580A8A3A1207C34D6A1646BC3D89953A63D22A30EB9FAC74103FA527843D3BDA656D1F22E729C3A004B923D08C9CB18CF406FAA89D0D63782C7264D5A8C8078EE6D259EE168A415E7BC83E4F17D9E674154DF08CCB21ADBF5B35AC28883F6943083AA97210C6DAE492C6CA4ACCBFADD99AED15110B10C9904469B4F06ED32546130B0EC4B281622A5EFC9C94B1F2280F251AFCAE857C4E17FF5CF472F038E02E5B7B3CF5CFD2F3969B9B8D5A27C8EC38DCA4284F0280C24F01DD97A618FDC5EB57C45D9E2A05B44E69FE2E47CB50F596030C70B62437F2B91A67FB84205D95CAE259AB1D5FF0454C5B4D87F439DCB7FC62B704ADC7A84502E1BD8E6F52109BF0F36824834D574E07B9375E693AD477A9D74E94BC4E883206DCF875AEF7FE84B9B7C1C9B1858E4BF6735235FAAE21FA566C866ED7C952B1BC19A911984EC25AEE310D8A342AE32F46255E0E00444CB0EE90C37152EDB6C741F5F394B5D47154825279465F0F8B19DDD85B8D9194A7AFAE5FE609A245AD68786C9AC044C008A1B3EFA3A8F4FA0FD49A65B6FF562F33DCB63754BE76244326FB6E416EE3267F93D7B2BDC4705EE7021D5D2EE66BA8D7B9DA7EE6C354E05470B31406DCFD2C32C94C22A72DE90E5A9DFBA99ECA95F73A014A3E9B15EFCBB67FDFA6D3CAFBE3ABBB28C4DEA6AA21F87693D68F0A60331786DE02BFA9E85A8D2AC8524EE184EE738BB3FEFEAD7E19030AE883707DF67ED12E8757B86E6E5FBA26715DBFAE2BE0F90453868931629FDE97712E08A280FF8888007AC27DF2C7113C30604C5DB17538F026F17C7F07D2A94AD5AB367F9CEA87BDBA712363D11FF5CF0590030BE9B342A7ADA48C08BC42F923DE939DE79616CD346B3511F41CE695B3F939C101F687DE7292CC96691EF3F3CB653F4A67D2EE09C791F993C726D574440EABFBB00E5E6328FA70D69FDD5F2EFFFD37C9902AA45EF4E9D06059B0D8E3686C74C94CF2F0032ECF740B31E3F297F15343A0093EE0B8D7F8EDA1118D329D05A1B992755181429D410771E37B56E28AE2ED8C4DDE8422FFE91ACE348E443640578687C57D79DFDF917F8E60E0A2F1C6223056C373F58C297F0FEE3060D31DCF6851856D1D05BB38B1FF426BADA10FD84B2E08AC149F91DDF4A5CB38B290DED4EA3B02EF7A3DF42BDC6B6205D281CE4A48A1C13FA8080B6B4100AA123097A4140415EC7CEC57790D6EB0B4200AD3DD9FB7FBD056A5E3E9D7B7EF47F44A63DC908B6DD8B020854618F7662391DFC35A88F4F5750D282F81DDC50D0132707174914293E3655BD2942C09F88627C0AFE4B921B766BEF41E246FD23482B5B14F117E8EE340C47C7C405BB3692C4C9E541148C2B38281EF0274835860E19C2D48953545247BD1F7A76CA43956C069A17CCFB4D0B0FD478556A209B5376BE9207AB174D2CEC96E09E1F8C0FA07D8920B2ABAC3490216DEBC67030E9285B3EF6767AB11E8CC935C4019B7E68FB9AF8864358E6927D350CC8B9A40662A0987C1C8877AA9903CC89A93E1979ACFA279FCCD2E171A467B76E1103C4EB166273ED7B4878908B67DB77C4FD4E49DB46109DA4BA78D69E03B48518F302647B8186F787F4CFCD87CC5A45B98F7558ECD0612378306C9D69FBE23B06005CD5AD84F73A563B1A3C7988CE0157D2D2703ECA8575D8BFF972CBED32A231395655DDB2188BFFB413624639D361B3388A9C9E13645C563A87C610F6FE79AD50765CFA8149E27F7083A316EBA050860A69BA56D002A78640D71794980C83573A5DE69A697C2CF2E17C90BAFAAD3D421C6E1D8A55B3FB4700B666AE3CC3EC114E9DB428F27CE427E4101ADB49B84CA7855458841DD1F4FE76D9074D940102FC47EA633744C2A664E22B5C5AA2721017F3FAAF4FB033FBB1D508EB98E1D643406ABD4D69C030A2349408C80993D9F75271F913D7417DA995443377E6F73A7DBA24E034A9C4820117D1F0BD69C93FF55CFFD2D36F8078209F5711FBD1587435517291498926E7354558945F721D00A73014C06B2C9BF04B7E695B9109D769BC2172CA7A70700A1D5AFF6F5FCBE699FAE81BC34B0495A82BED01B983444224B4B860360C07F8C3035FC4F0C4B7DD4D37ECAFD32E8C121C677ED263338359E25BC4173D191E869ACB4A5F6D20FD16FE50454CDD269DF8CBE5795482A2B40D52BCE5FDEBA62D9274C9C67127580795BC01752740E606D849AFCD6ABB8340613C61A764B6B92863779622E40EE7A8994034E7D303F07EFA11ACB70419A53897ADD558CFE157CAA3D47917CFE0287500B3D70FE42AFE36853188BC815CFCEC9F56030C83E85C60401912C14A75A082DE2E0400F6348EAABA59312C51A7E3B6A5B39D606306A304B4DD3472C5B89FC65DDA54650392A02CC6761336FD114D848BD889DA4BFE6D32931793A6515510CD802E3D9F2C6F8F2F9DD96ED039462C587395C7E6861FF48B7980D492C23E0635464C7D1969C12A43BF0FFA3089E6B367AA65D4678A571A0D47A75056B34E3F8819F8B6ECBDD6BE580D423D902D3C22D9D787E0F1B6202DFD392AE028292795FCA0177CBCB09AFF8B579A87A854432827CF797E494ADF9F96A56777AD6215F284EA91D35563F25355D12BD155C6C364B0C8423E1BBC809E736CE0BF03E0C0B728F04E6BC8F3F07A0D952AC9D9530C77547B687E193EE2D3565AC755DDFFE880AB0524624E17E019466B7D0E8FD6E94AC2BEBEFC617BCC5D529C83A90D36D57A93BAA0C2ADCF360377C9E9D58C456FE9F3D49CA37A8C3B5BC7C231842B57D320310943FFC0ED2F5F622988ACC7842F8410BEF0E0671673E7BA61AFCD2EA83CF066A169BBD97098F4B4F3C9FE73F5CD779F502C584849D1AAB52D7059D1D4432C27FC9284FBBEE43D07493A38B139152ACB71A171D454FCF936656ABDBDA03DEF3C7B27891088F940C200AD454308001FEB2DFA0FC38FA74F85A30DF4FFA64DB48E7D40C158F058B58174F18BA482AC445A6A63FB54CC6C7D4C8089794E8AB5B38C41C7FF4C6A8A5F294EDC3FFCE3C01F2C5C7FB569CA06567C8D3BD34F82046DB4EE7F7491D890DA1FDDC55B12D90A7853D8FB52E86AA1FBC669C7ED349A2CEEA9EF18F76C23E817AF58101BC5CCB0346A607D6C60BE5CCDE5DB9889E040223FE98B17D31D64E8C1456C01353887D75EE3B82D66CA0679B1C2366C44E52D73B09D48A39D1BA3FC87D73772DA601EF442208DB763F0BF888D28338709FCB008B83671442CD9F7ECAB2C1E26428391E559306904FDE5BA21E1757D94F84F18A5FD8A067C556834AB257B9D2E1290FE0ABD3BD622A2AD92BEB2C6BC61852D58384A20B7409E4F212F630BB280A46CF89DD702B2508752D6A4DA94BB769797B6E7FC318B0B3ED50D7F8C5D8579526D536E4D43F93C055479D53BF6159BCEAD8CE87504EDF7DB35E1D03EC7B4F13802AAE0207A2414802BECEA39664110A54C37415EBD7BFD5D73E871587967F24EA34B7D06CAD805EEDB95F1023B7BC3A74A59A6C9F3A4737FA1BB087012E0162CFF15A539E86AFEE30144F320FBAF088C6884489F84F16458755561C9CB0723CEB6ECB134083C3B82E93BBB57FCE8D51374D38746BECD09A059AD6623EDE82EBCACE009C0C27D5FFFCAF76C9E91BDF5EB895FA1E9C3C0AEC0BD73B1582C067A45CA5D15E2D45E7316CD4B176D9DC7241B05922A682DF919B2D2DE2F45942D3AE254FA55C5D90B8DA3C7DFE2DD8381AEDCC9558566E8DF302022FEFE51F23AF6A018AAEF3C93FD608B0903376E193CB1C13021808ACD538D3426F9B3399686B6FF4DFC0A4552DEFE49D042BA76136719D62884D8B93A349C22E0320B823740DDB3794AD53312DA5608DABACF69767D76327BEA7A644A304A132F2D2FA8E7C8F4AFAC30E389A995C0A2F912E98447CB400FEAE35B3BE089F46CD48EC8E38D4F2BB44F1734C67D5125D7266AEE3E9D1E91F800ACF8038D43B6E10750DADF6CF70DE75176A2E9C340BCD2F6D87F976AFBCDAF5E35DA9B268D3AE1F0F8172A342CAF9602593A5ACDE03DDB482E80B825A7E91E8B0EFC1C8D00309BD170D9F12BF5017780A54F440A58BE4A5257AB67190C62DAF9332F3594303B419D44A38C3A8032E38599B49872D241AA44905CC851DDD0750D04815ED88711353DC2264C0302DAAF2FFD34E9716FDF8A81F7CCB5757913B380A68F153F62E0BA8335F8525CC3A20145C2416581612B9C29C0B1B941946B2624731FA50420716162C64AACFBF94B43B10E59E0AF3836A05B9335B0C44370CDD2E45BA817631FAFA2E0ADC801772F6F71860CC2623E1A802B370823D02442108E5C142B68CCC9CDD0BC2EB9B861D763C715D516540F19E70FB474E120F06BC19A6629E8DAF67556AC60D17C252A44901839143BE5EC76B834FF11DE13762EB23843D3FCF1FF9CEB41CB02DAC74ED6219288575FA294157E532BD877D1B711AF3B98CB0B4BD7286F88C6C00B6AD9E40D66F38525156A4AF35F2FD42A5F25A201C66DA4AB5C4D1517BD6CC9FD9764AE2756379D73C8D81CD044174860FEE5DC42B4576008F13A3504674E0D224A9F1AA780C3003B7856692676A5E581418C65BA9F049CA20C3EFA566315DA220E837639A899ED54A07B5741097C47FB90A81A41700BB5C0D8C3317E27A0A6CFA77292BE9186396BCDE5C654C565754DAD120719E571A4A14207CFD205BB4A66C02CB68EB9E50DA7B1FFC324AD07D8A8A54729621776FC5DF15CA39F3DEB6B810A735CAE0E1A84C6842E80D1CF95FDF5A6FDCD613C54DA1CCAB4994EBB81C632D192CA9AFD7FA662A865C6F193B7029A9B6F21041E3D13D50E5A1DA47D3D3C4B101488D2308954C801DBAE5029E866E869167BE7DCE6476A64FB245247A84E46B5F0D9FA9F7BB10756FDEA659788C032AC654CBB83F23BEA1F285DE190BBB5EC4135E8FA1B134DB5D1FFDA08C06682C2DCC51E0D848F8CAEEAF51DED21830730F6BACC2A4BACF7BA62D14B009116EF2D157F64A7ECBC971D50349712DDB0871D007B2FBF83A832416CFABA2B9CECD37207EB9DB8A017AC266A5FC28DFE64B52D0CD7FD7498F718B32804CF98D2F17D22C2957782DD83F4FDEFC8A6AC5B6A562C939D2D0A0FA6078F7E6B4C95159BEF010C1DF8448158BA29E1FD1AA076972E64A9D534B1F27930BADA08EB87BDE6FB0A691D4379DF0001D84F2F833050E18869F2FA7C00A6481E4F87C75483310949653D6B91FEF1116F25E5EB0A10C8C8723E9C1C80F75C2875FB0C448B3E25E7B359304C08C310148683E1D8391C432A8413057A7AF45289B1363EB203779550FE1F074D3B4CDB77B90700E3710D6EB4BD1FCC209F2406CAA67B98E44AC91B876762D597D0F03A404394AE81BEF8F54A1A898B2F0F0CC3D3B6D84D759D1F1C5788BFDC7657794E384ECB2D5307CD92F3E135F35720A44743D93D111F38791B60E7A64F51ECD6801DE0ABC356409D00D7F785EEB88FF3FDC801C94CD7972EE402217DF018958A79DFEE835B2E7C591D2604B83E2C8B3CEED7BED4DC66B66EA13BDA4FBF5DC3158035A279F57ECBBCACEE3FF346386ABE41D0DBB32E15B02C49D3F216DB19474D295AE0A8DADD1DBA9AECFA9C92F0429352B558F69AFC7070DE8D47032956A9978AC2F388DBBD63AAD776BFAE969EB990E72B7D74A0D2002CD3CC664E77E52"""), TestUtils.hexDecode(""" -81D31B99FCF0F04C0B2292A8CF472AAE17A659C205B067FCDF9FB4158C42955886D10F4BE022BC564230D2CB21D9023DE837E9ACECE2AA7EFD77E8335367E9F43A4D4526F36F336293FD0D372E81669B04DFB4ADF2091D18C1B2649B751E1877BF3AE489862C22108B02242EFA218828F53B317CB6537B2794E9559D2F93E3BA9ECE302BA948DC7C6596FE4BABDC3CEFB7F750C8B4D041204AC0F185CCB264A76F81A1783FAB19EA236D41842D9DDFBD2028DB890A652FE07836FAA7312A287A920543B8C393000E03F82FB712391915D75DC5825D9494C6E64122202D002BF7AFC234B334B12C164911D63333A2060B8D44DEB4B7E1B3E24F8EF98C09872AE4BECEE4561316B16A90507B25A20769A7CC25DAE276BEF51364499020ACFF97E871AFBBD68854CDEA120840FA1BDC1AD62283159E19938BAE5B2CAC8A607EB2ACD1B77FCFACC7981E5DAEBA3986B2E918768204D2C0B61914FC6C14A5C36090E52084AE245D9C6082FB8C3B5FDBEEA0CB779A656C180A01C0F188C2B4C11010B562711C5A4F10CCC39BCF5F09509BAF83D98C61E3A35FD7F483342115D41D8DB382E7E5D161711B8F718A2730D73ED7EED07AE04313F3D29D7FD68A92A0706936565924473CFA0125CDB2A2E22238F28ABECFBC0BF8F5E6852E45F24A55E54B2F26C5B9D97A3FFD4CCB09AD244D2D0072C575CD59D01EAD49A55FC2AC8857375ED477BD9287AB0F03E83BB29F19A6C1FB8A6D4B510A55C57ADA1B108785A16C52C71549162B7ED916B8309EE880B9B203F8E24B16E3CB4C774353D9CC9AA100BA200F5D197640DF6E0C0FEB9361B6E59481CE285C3CF2A54489A48B568D115FDC3B182D8341AEC078BEB288F0916C651BAE7ECB5EF165686819CFF2516AA90FFE3FA621D24F43917C218319456D58B5EB1F00437CFDBB66266C15B85CF5C28B29B1C2877F551E5A0B3FDB4852AA17B83D93183E82280AE94DF3136A82BB09D21DA75C6228DFA56AC2E538050B1155DE4133B40EAF22C63DF128E5324B4DC3FDE208ED528D4772C1ECBA1D11107CC3B8258F2BFB9CAEBDDE1B808D1F909D834D3ABDB08A2129B15A81DD01B82CA4303902AAFC1FE21B7AEEFCA8AF1167205142C65B41A8124C8E2FB6978BCCEAEEB8C701A97A311B87C9F46F6B23F8547EA728D46DD907DDA37FB143A191E66906B9715E6FB4D027A6F2B4DC94A38DAFB229642310FBB0CB28BB8415A9AB0B16E78F9F77737D0BC377F6E39AC869743067A7CC49A0E6974D86346BD5F91BC3D747A659F35FC133B02907E0E0442F948E2124AA25209E61F5209680B2E2D8DDBDB1A7BF0B8F1D17726D21C8730875255A401C381157EFF65CECD067F05EE56A9CA6986601A0FFBB473228EE9A64EF04196A78D4B5EC68F9A4FD438DB71E9A8FA5D0AC28D35087ADDDB4341C25AF1A0148D50C5041C87A508BC0894F073505880A550C17079B255C3BA5F58447C51603A599AA7EE288299551D339611935C5EA7F07D51BA76A0A9873635CD7AB35F8EB5A25A2B4453A2EE917E7103FF62D9476AA1B0C64777F4D05AAA5240DBA6956E1E1DE3C0EC1774DB2742D5DF8A6BA8E287631AB41B948954C594A63B7156218EDF19680D863879D79A8E58A1D5F975A35D589805B734C6ACD3E23EA920C8C1A9D8389B739CC3EC34776D2E816CAD3D6AE89B29CAD96D707E7D31BA731749BFAD67FA376E743920E119C11E29421ED033A1E73F2F522EC23D097830FA05CD62C432C70B10B9843CE2D49A544664EBD22213EACBD40922F1C3EE99A3E393CDB38DAAE81027F64FCF273846A9A789A76A50C79FA50A436D84FFF7DAA38DDBD5D40370B02ECB6F202261C5B284419F06CF4947A319753B1132017F46890A129E13DFC62DE2AD552F0931036F5296BF394311A7347702EB998A8DD6643EAEACEAD0DAD94225623F8652BEF131B9D4B0A6F5E7F4ADE344AA1D99C764DD9F9BDE6CC040FDA976BEFF40F8F4B0C5E6B20497E209F08290006DA5DD81AA46C5A0DB7EE7241E2C11CC411E4953942E2BE4CA6A61FF7C21DF482C8737012879C2B3AC90DA6EFC2F27B8507D4393D1647C4331F307C41038755386C53218818A255C2632A6DCB9F589BA53ABDBB4F7A9684D8C622F0B5DBDD8BBA59F92F5AAAEC121939263810535AA0D61A67A344B7B98568C8567ADA14B09BD6E021B1F8A0CF9B6DA08F5A1D66CD1CA8B0641FB300F11E3C4B7236135F4B01E5A50416B9BF3B7D88317315D35FF88A1663965CC183E4E34E4130C3AAE8DB39F3491D85B38C68C1F818DA553FFEA24595F5897071C84EE46FAA74FE240225EE1E325D3070665EA89F70BFD998F080C330E4759B4E79018DAB231BEE7BC73C20117E77A76BBEEDA3578CC2B26F03591E314B0FD26DB529BB0E6D747058DEA808B45064B832F3B1008F675CA2A92B5D38B464C5CDE4E570029891F83975E063EDC4A9B1A731C36B5EDA5E8F5D7ACE5F0A9F9BCBCDA5549203A9268B156DBA17E38BDC3D964CF11373DC778A24FC27613D39E4ED6311AD3E307BFFB3A1E45FA8BD2268C0B674368FC583489473AB3D4CE941177A3EBB06E6273F3C90FC5734514C4D4284954F5ECC0853523DCC3681257C1EB15B3F7AB7FE42D70899418D43B0198C971F9B1C069A2B443DA2C8E463CE510EC8B40A366B4DE82E2A206D7812A9EEC1AEDF669A66AA4F76364DF2167FF1416DB7710EEBDA11B0E8065E8D8BACE915C5282E742E0F1969E8A2B3FE29DF8A9034A2C2172B234E39957E5BF6DD55EEC3C4EA1C694827CDE661870E4C858FE91AAFABEE9E28AC3469B156DF911E00E31B44C2DBB43FAA617DE7782E14566DF4A744D8255BB741EF9C5842DC5AA275C73A7BBC254CF6E9CD1ABEF1AB5427CAE5FC4867BFD1D55478C29510493BF720C03256FD7F10B9095BE2AD621D8C2A6A667EA12DB50A09A4CDF0EC604ECF6F73A371374059F00FE8F84BEB0EE5E45ED467F44479E7761A20A06ECCF795017D46D4F554E73F3B79B4BD7DBF44217938BAB271A50F40871C6AB4E3158B9BD4B12861E9865926D87D79508AA23C085B616938970924DCE2F403F0297420B3B8DD6EC376600B1787AE8756B5CC414EE213DFDA291C4C94E4C36C9530305BA904EC6C61EE75E5C4EBCF557DCA2F01643403B5F25611CFBF3DB4D64AD5FAD075DF9BC3C317E0E4E6BC398C6EA02C58F4CBDAEEE9C66BE30A0BBD3F23F2C9528A54C080129633AADDAC8CC27CBEC1CCDA9D6C6A5D6E1C15F9F59AD01BF1003913185BF93B398BE28269D04383A3EE314D69A07AE8BC1E036DA3430CF772EC00C1AEF7D7B73CBD2D296BF0064A53C75C24ADA36D60ABC93CB271EA846C950BE8A58126DACC14295629E08403DFD9479AADE091C5C71BD234DF9F35B411CA6107724BC00E6837EED6526AB76D3E1AE0EE47FECC134AF895235F5E5C42EA2FA02381550240ECFB60AE9A37D77FE8A057F28711D25C0BEA2550B32EE8E926E539C499ACC781F9C3675E2D6A0D81E10FA653635CBCDC6686A8B842718E327A50CFC15E68DCDEF46FB3137A6F867AA63F97F489745E735B1215669DE7388AAE461A01F9DF1EC3DB31B7588D2A18650C60FB08CFB59F11283321E208823597E9AE5384755B1D106ACAE8A1C3151E9AF98E252A10F068BAF2B6116D37BCE404910DF63DA5891B00F5C8968D1EA70E54F1BF8E495707197B086D0392EEDE6AD60C5D4B9B108467435C9E0ACAC31A7E590D6A36B22EF1582FDEE7CE7E378C089AB6B8588325AAF6063D075005AE65B09929F41DD70B45B53A50C53D779BD37923213AA91A2AE0CB6D979588EE8D0DCD15E89929526574A5F8AA538CAADDDDA257F15B1294E6C85A2BC8DC3FE08F0D87963341D630238F25516990A79E27F2564439EED4C359FA83C3B7519928EE4268836D8D45DDBF62E4A9A0DBEC3470261EC5CAE7D0791C0E976C287340724D88E676B79B33A035D93C5BDBBBCFC0B6BAB952DF2A1A975C8CF7380C98AD3428C795AD3DFF70E63B5792F993AB4642BAFE4EA0771BFA24020F0D17A65E2E6F4F77A0801AD4C59FF3BF6C8F837A9430BD76CA46EF919CE743F685570B95667EEA2BE078AC45C46A54FF51D89E01A3726B23B5158C914B7B7E6B33AD8242B32514F251873DEC8FDC8BA607D156440326D4B5A5C5D676D0098A73E2A25C84F09111493727FE5D04C8B1FB9554AC71A3101E4CF44328553A23DE7BA2AD3C2FA9E9539DC47A58CE3CEB6E51F20C87AC6B2B14CF803DDC55A2E4B5D37A322A49FA38BE1B8A562BA7D314FBFE2BC2F58B04A3722EBE4E90FA3AFE1E80E4A5602BAFB9EC70739F3C6CC223B790C603FDCD188CC5CB3853DE9161A2EFA4CF3553BE3E23C386C6AD5BCBB7C7E497C30A0BF906B6E35585A69E327ED95D25107911902A3024C8B404034450B19254CBD832DE3E6FD46B3C2C602C5CF5A93D8E966DB63D111938C3BCA92D98D40B6B023DCE484E6E958EE5B2EB5AC0275824391F54E424F4C46B7E572F263E3B727E680556AEF3579E1AD6A0A43E764BF519711B60CB41FB2B85E34BC970BB3F98DACE7C8C1CF3F7254DB18B5DB18AAD3BE4B098911484D323427F8897CBFE41508DB7D501818EE418690134485A7DBDF4177C82A8CFDBF00000000000000000000000000000000000000000000000070C10121920""") +98b2f93395be5e131e0c5fb8a0792062513dd8be0e820804d26f937064f5c0bb3525d053e16da6567186dda337dff3c6f30c8cf96891ddbe0e15b349c03c6d53ea00c6ad4f6bebecf17b32a6b57c9ec32ab4397ec8062d9e8cec7e747a8d9fac7fdb897c43003780ad783874c2fcfec8a0d86ec519c07531a8f0008fd88395e44adff523568e526d190c65ba17b2bd7a383bb3f5df73cc2b646b40c49d2b87486a368d43e6d616e45ed0d9b3e772c7261faa5e5e68ceff3b6abf9ab7677949facd2690d6c88f8ffa3e05544603fed81516a829bd3d9bc55e53f85f31e98b01086c31995834d4fa0eb82ed75d3d510e4210ea4dd3cb8f2a8b446ea8283fb5cae01f7e733d3c60356bfb1411f8be5a6d0b6c20558f77e7c101e99419f94711a98b121fb7f953e0c19f91b3897baa245a62c7f3336fddd02358fc3d2672e9147dd3c7ea8cc3b1813ef8045fa37786c83f387731bc9e3e706468fc99a88917499d8603589e5d8b6d028d2dc2ffa4f03d6359bff057763ba7c106b4ff4dda55d9f1b71ded84896d844e44c9f3b1d174f368f220d7fb6dbe0d844f5b10c29d26ec169dbe54967e00f70fef69096bc8354a8bef7fe0be76e5f95758580c93ac8d9a349ceb388df4cc173f4bc2d1fe054ee7c649d238a656194bf77d5afac4a6115ec54278d17e93f73f9a4658a8f9f9820a31222f327613a2b66ab471132565f9dfe0388e622f784c7e09c0218603a17f83f246fb36a40f3b1d4e2a1bd2a49f388d3c4a7a06de761825b8ba7c580ac8c5ec6f44d371b43af52a62c31968155140e3903d0cbbd19397f80192e356e94523f7d4ecd4b2c55f7b88892fe94c0589a01807eaa594ff962ebad271a1f1998c517dcc3b98c5fc4d73b6efe16c4c45fbfbd18f5eb489ed9e1212bd07bce3e486c1264a595496401be6a914b2238d5f39f5b17a60886228e5e9b2d841cba626b26640edc619a444cfd036c54dc610a2102de9dfee18e18cf32a74245501cca7e49d987ef34f7a9adcdd3567e357244c012a7170b0d375be8a445e5b8752301d7ea633485974c30232fce5e6e9ea1be14f466d3a8241943872a1a881cd4ef436f1ead2ad9227143be6792406bd7c07d925091b51e5395cfbd30b8208eb6103a45fea3dcdd7ec9f478d303132705f3126942d19626d5009ed347db6e75e6a5f4f5651f72265f14a01fd48dbce38b2ebf162d25c4c3b0665a5bb30da9321f2cf070e16fe7b12f7ad39ea6b92755c4ff0d988ac561d310f6e492694ddd4c35c48c13d62848205ff97a58a12602c5575a1f755eb14e50f409b90924030ee3b58964f58dd8c600fb999bbd5daee8addbc185c52d7151bad1aef8d83a3a6d80137cea0f9b731249fcfa996b421b046b7cdebccd240b871a8dbd5bc072e69968f482538fb67b40d13f8bbd2341428d5a5d6bf50c19f89d54d239a0adea5bd89c12e548b69a19ccf9f9402316363aa7959fe3ab63f350f3fca1350b892ca634bda0b6656a44ef5995acee1f355fae403b7e05900cc4d6688bce46227c941400870a3e13bdf468646c828a39a072cbdb495c773fecddde1f37b1643802f565ecacfa1ccccc2a2829a68d9594af2cd44503ddfe823c8117f0cfde7c77397d7da69b37bb765e2e7dba9ab70e3b802a009f511bf762820a8c491c6c19ec72965508a82d199b34f17867be0669b4c792434e6e4e4c1efa395f1c4bd83a1414a51d71688544d57c2d5167a1929856076f7310c768a1919392171a57821109ac3e9b1bf7cef03088d98bd2dad5b0290072d7e5db27ae08e4bffe11d359dd5b58468e8d86d787c9adc8717986408b2d67c9e0e53cfebae82cb27f0919c62e89a68ac8903e80a7a11b7bd56ae232081af3146927271d3c2f2f7247a3def6de720917b014d6f03eb6ef9dceb771cabbc645f2cac7acc3f8d6dd40f6fd2bbe69ffcc5a083eb3a10993bbf6edb5872e001ef31e2a0e86ad58f6829c0f1f560fa7ef734de2e84857e3ef86cbbd0c1ef2fbcf282116297b5de572d10968edffa402de0ef9c4273f793598d94aef6e294d4ace8cccf70acd9f86ae774d15e9a1714ac761af94b446e4f0cde48748cc5db05ab4fd3bac0a1c43bb8f73a7ef7285866ff80fb41dc837a0f9d3ecf93ed0b79bcf6e94177d34084c597abd2fc46fdb4acd11d543f8c0b512efbf63ada213b2d955569da12b88b2d6605fc99c76ebef188881c7dd195e6ba6d5e55f1ca19202ac94c360d76d0359c3cb1f801414d97535313ab2ced2db1ecbbc3cb68e81988bff134138cc393b8ace18e20ee4e0f04c2206df124e4cc496c2acc185489cca0aa1f9848382a55d991fe5b1228f913ff81b7c564bc779ab311e9dcae58e7009eaa806896b1f7cb6718cbc8f8b6c4a65738a87e2338c6ffee4cdcc5ac060e0021a5836c45732cd668d2760de9597f719d26bdfd2403f795b8e7d52e657ae968d027b0da9e5e76d2fba34f1de7425b780bfe96c05f817dd8f0cfe176870201da00deb460d12a84f8bbc43c713793530062dc78e92dbde7a9f53e08259333253a42f5f7b1a7f35fb89e69efb700f7c6c465e80cf47efb8b396ae3455af4fa48b45a1fa87a110975cce3e92bc2394a456eab040c2fd333f70d8165e2b6431677fa28edc67dcae5f0aac65f879ca9c690648689c94d6f657065aaeed5dfae5658f4922439437c65a2ae5bb0853478178b890561a69a24bd0419e2a089ceb0196b232c45c7373938c51591ba527df1f21490883e62e99b0c4b914bc5e7be903824fc12da0654bb03d3c15261691db25a6f6fd53e3d4e9d8ece3d331f42d2c99e9f1fd9af4d68a361922b897ea6ab23d8c896208bcfa6f2c3b06ce3c88fb86994befac763586c2f0c37f55edba60286a764e4cccc5ff915739c510a5d45ead80d14465af87377ea019da46245597bb6af0918654596365f20c63c074c8a896e5b6efa0d2ba7318fb5a42c6eb52806ab9c6dd8f3b160900cd4d71be8262217b9877739e8344ec1a90511a23f38c5b5c2f23552743b953168de2bbb3a993691d0d87aa20cc70eda60839a20eb3ddcbd6abad31d3ea359938e76191507f298dcd7110e0ce6216bf9ffe2f361c8246a9299a1fed48aff683ec8475fabf36126ab166601981dab806616f38bb1bb93c335fbfa3b250e31560bc8d0dc53957da03da2f80cdf04764f2e9fa8e7d2f7a89724c74471d2bf713d4a4adfcb4cb178a492e64c1711761f9eb9d0e65e04b64f9b94f918f4ba6835f68aa523d147414531b925d3d9e7d315e1fdc533ee0c498e9f66bf813a25ff95873de22448924b36e6172a87d7adfffb9abc2bf2272c270b83cddece1cf189ff52e209dfb78b8a952142cb72c969c4ad7cff67b1ee5e5bb40caf0dd45cd37673908c430d0d776dc2519dc4984170ee7ca6365936369df16c4a094b86c1b3ed3d3cce82b2e56a5681c204e0acdd4a712b5cff260f4c27ea6c32e23c227dd8e1f8e99a67df32e7a24e0aed3dc9630b4b3331cfd625072c0024e96e79c4cf2ee92ea18a5e9182028d39b937029a4700d93deacdd4933cc31e93cb234214d334e1dfb5c323c964d90387ea4bccccd0e4386e4d770ea889aa480f0c8f828cd2185c18a49ce112c70d140e18d9aa6ca9ca2bfdc12003a63f67eb31f0699586ea8fb50d44fe9da2d01f0be10d6da99783821c07e892aa6fc6b190d9639d9249492c154b12e45e2009adcfa97b86650649599a9ebe07bbf8dc8d452071bc4f0e8203f81671e3bbe599c76589764c0c1923b141df67e260f7ff14752d7a84154dedad28c0bef90c9aaebf5d2b248e2e20a4ae9373e692bbbbd20c408f0ce99cd7435a4610fc51f051b1d17509a34d4804529a877828c0c263b19f84cc0b8d24b9910f6ad8006bb84e1a4c8eeba6e165efd50e5a444bc342bb8ebfea30385fc0c69f53d04286ca24c0a0a402668503bc94237daa53d1b41242a13050232772ac1b2c6ce9f6bcbb53ef6b94ff5d0c8294bd5a4b077c5ad5144b44a63ec630d84fa559ea329d0dc27dc7b8ba68a96777250244066cf1b8971261826d29f18bb34fc37a6a39e4870878eac95503dc5799dc8923a15a7c063f2e4f362294c1bde18d3289e67cc883f56ae5f56fe9ccc1e5101d67a552be55e06d54df6e97b49b33ca50ff15dfa8b7436e5ea540aea188dff17c3c657544d600fa5a3e7b783adc2065f05ddd72e65a69c7619a0bdd93c731afa3336d3e408e9bf09650b66026a6d691447db90e08800d2aa08fe312b5ed3ca2dee411bd17d7239f143259d697216e2f74d7980dc8ba3ef2ca2c95af10f36d9b28b1bb464155ffb6807e15facbad8b3ab23403bb9ae6546b183fbab7d4fe2fc507931fcfabbf868c6e21d23b0e02952db97e610b8857d84c777863f820978e29efc1d9c5ced05bb8e75b1246aaf401ff1d0d777ca6eb8d74c25821fd9a5dde41eb13d766c30345965553af361395076029184d32187e82dd7aeb73cc648893801441476a6b7a2914ab77063878d53a539f7774abd4fc9d19d5af3b143dddad76ba439466d646752b7ddadc708ac9a0751d9eb72559ab30043f41bd91fee7947106bc185f0406a7adcc2327517988aed2eb5bdde90e2779b5e3f6042757749da9c811162a93999f000000000000000000000000000000000000000000040c0f151c22""") ), new SigGenTestCase( TestUtils.hexDecode(""" -8BE522B4E26631EBD3EE598B51CFB44CC1BCE4693E87BB76EF1B3DBFFC2762169025689CB13EC243DCDB536B5592EEBA1C9FF9D3162BA69C6C8445C55561A1BDD5DAA73A89A567873FEEA609BAF57AAC39B28C9EBF0DB477CFF938EA069ABAC4C134644525C179B81B69A61400FC131632F9389409EFB2DAD28347B6E9DBC50333478537234180110216703713666267407332042117167285231861686761441210671057343688833122224741016000006637280104670885810336860677835038360856671708501706307554348172486017384536610442118411464278512074201323472226152744306444283276447347407701534240455752818374185812151275332674783343510375328081677738151215483531374201701647010142025428074334717432007611874182847823042007734883110521200373123872310064376640658218187215811731015263781030348654333721768352476037106520857001157228053468718674413501266737641245546154041643241410501404202331467303823172738661537631326412120620535147074330475675267385001422576156865466315087754081624344371427068152314726807147108662880315204371650357351315826372165054702134004232425418802463830782403784381115563683351588142725828012118040033543738720206011440856443223582817212677271158874776566724605581535176600567745870103826357027573672874654377285231557526888232382155662024100070470030473727043681088635050714638852408071501850808072334837044106823681822708546272403308813276035006162706663335231815226264468284147368331351772564002623064338284502177258683770086532412113081781761102623530322278262028713438163458525017410602014725837473653188830358083120808408517263643700355801282287367867716818464087758327804282311206361315488554266670483253832715616163087472867038811365080210210237462345637776788467178451732482673618811867731483512036158155276111185373836686408334604023734277527830555045716275074072450108113304336412220335448801703313347077660185246467603160827384258610827786040227788358515276647106422642717356782036318301654248323637160122662488623837433257521667160846766448032050502541655122882873257375732786387202663327831411364154328330125623422884575626558307557713473653281565632108110853544346667326373177215875188880426237318478516556653371343073506220865321058770816713770387242752781203737258042510133435774100138260342867165785468418463736503584203606438045376454072080283716557465775044371518453200301088283116123715262003810840120273260615472300483880225411134203712750473122131553667405410661065824344668381608711445062248365838180162845050471728814083565587567605831314536481816873614238866537046728070145831458843035350778852054744668616084188465173248757877750305585700014307233313471722355344716426435421467416072887431031342617388642656086537070667614703030736144320532164032037145102411420812042582084583621280125835662622287314366231327281824842763423073663418856204041328103787818034738187202808802170064570017265628525011080747850142683771068084483578052255237768183672270141750243375737386806347814658588856114864068441442642086057430676653065800650578614485827138703358681848874801543363582130444225273015665625525034606073587464023021552772813060801271401248635688136384706617355687552587855202183037066184600586417823285581816200837FB03CD1DC103C479132483591620A98B17B885473B466814BC26F9F52D1AEDBB07645BFD9D05B02CF3D37CAEBCB8DCE34EF4185699343A4DC07D7EDBF603AF8D3F4C79EF169BDDF5A0647F9D71732FF65A8142780E5ED3EFDD4FF8D496EA676516529564718CB376D9A8C922E038D84995A29661A54184BD3A32D2B962B3DBC167524DE2C4B07765B6BC71CD4A5510C646EE0AB6892992E341EB0E54160A8939AAAC4C424BE9D7D1B4CC1FB50B5731950D19B96E5EBAB09398CE0E476AD189004829896E131F1C0231CFCB374895A47684F063B821FE0C8DCEE3B2BD5DCE499422AE0C668C267A65735F7A21106FB7A584CC2D89A097DBE549B3FB84AB8351B6A5F61ACA27B4C38C3755BF1ABE272030333F976296E482776FBAF8DAE13A0BCB7FB2992F74F178C4CDEACC841B74A1A7355F6E09B0F58F9DB2461E26CE24DE7F8FD744AECD3A6053C49C7F23C8F7F34B35DA5D60B16B81AC9C9FCC14A5DC5DDAACD10634929E6540A5AE3BBCF8BF7A04F1ED438CA536279B58FB02E1BD481D9CFB6189BEE8FED30D46AAEB34F7C4DF8781A38B2C40A7C7C27347DF54728AD8B91C4B09CF48ABC5B392DC723E95157F1BD0DE34A76ED0C89905F4333318267E4BA6EECB1FF87F8AB78AEFF5A494B7323B34A019440CDAD40165146370E23928BF831BF0DB4A498AD2FD15A15EFC1A56F656E8CB58E93CAF38EAC61F3E030EB00EB2F9627514349C583E1E2D93CDF6775DCB56517F92D89530D29A55DF17135AF8014C34645BBA8D9DB19F28064B55AF5520841E3DBEAB3FC4A4AEBDB1C431B2F7A83D4968F120DF098B808DCC94D29D26B8211E489B8EDBB87A4CEA0750296E802796D1647A97093F5988024F92FAA1E857AFCFD5E43021B0AA190DA6D581D654DEE6B9223A31BDF5CCFC54178AAE8F4F72B6D9B43D758F95DA0E4E6EDA271E2C03F1BEC31924B827D933BE6634AAB033AD507ABE2EF144A9629C2CADE0B491042AA23005A25B163990CAE9E3F03F2B994CD1CF70716C4B0D1472185AE2630DB3A5A6F154A60FB7340087C554011D95300323AB37681931724326309355E5E767BCEA044DBF1F2BD2645A62D68448C1E978FE1AEF1A178D743DAC130CF4912F16D113C229764562FB8EB2D8496C1891487FB9985208E2DAE8EFCA29DB5788D7A623856F14E41F3232B048C794500DD52836C45AB7CAE336BA311DE88E1F108242DAA925FCBF4801A7D5D400E9E98B15323E7AF30566FDFD118011D1A6C8F795BD263BF38CBD66EE93F0D7DA35C276EBB3C7A2A511AA852C35E31D0F7EA0620214618B92A48A50262107D875DB22A5E6B33B7189F6F6918E036FEA3E7A918F59046B9ADB01B074DAEB58A775E9CF56E5ECA2D521298B355A8FECF7F8EC1586AE72E3F8AF3578048D735D8D750A28EE0EDCA3E3FC303613177DC3F9DE2DD92C583AB35866EB46DB11A4EFEBACF3CA6B9F87CC6C7819CCA4A3E2B7D6C5E9A61FAB9185B91CB90631051CB64E61EAD02D98F4361CE57A5BB54A21FEFEDA318CE8F384464374C8F4FE706CE462A38A2A340ED573E5F703B418D1EE2F71539A1339FBF89A553D4E3D6E309FA50FA08F9A3CA504E8A0066E0AFBB5186E5B3E7418DB1F14E73FD481B984B50595BD937E5AF3F735BE67B2F8E3821EB5B28A4A60A27B382B2D4E84C20F6CAD8DF9A200F819A664B560086BFDE6E6C0F76A651E286C4B0DA27DF31CCCA6D2101501250F251EF1D034B256BDB4C75ACCDD7E4A31EB13A71CB44187314EF2576383BD8E8AF0594E9FECE0738544571D241F7C0EAE00D9EBEEE2B63BCDCE13037CFD515A63541D93B3592FA483CB4E4121893BA48608C109358DFBE317FC21724FFE6F862EB5687A76F56A5DAEB3AF226DA6E66EDD79294595A7BCB4A1FB4A54132B8CD7EE4FBE8658355DC420F08B4C9412CB0A4ACC24CA5E174316A8B5692CA8569ECDFCB37452A48ADE1956C52FDA1FB81F507CD8654A716AAD3C9D8416B99390A190BFAFDCE5D2F054952795E13639CC0D509557793E64C2FDBFE16B19F28A67FB0787229D5BBE5C7F85BFD2D257415C4E024D72E7F7598DB32E61F91FD68A8ADC38D558D2AB6C0F748E7D0EC81BC0B3ADCAE6F9D098A1F43C1450581C2B084DAA7850ED84C76812DD7EF285F6A530EF7DF815A4BC54947CBD146296D615F5147C38EB5CD2BA842F1261542B5D75A41370860E8EA881E2E88FEEB020AD954420AB03ADF14DCF24E62DDE75B19568F06D9D418AD71E881613CC755FF3D11BF3DB0C0DEF57AF0668FC38F3FC9256DFBE28BA606441837B5B0EFCFEC92E6F658908CB4326200175B7388411EAC613A3A75EF8A1F856F3BA32DC777C668228232CC04F4FE6E9089C8B3EB9B4A74A9D4740AC8F14B5FA73C43B3ECBF1D37B50F89855DF3E899A2B3D277E6C72D284E075C3FF09024C3E5FB3B7349656197A468E75047402ABAE724094CD92170F4809160190D1F3844A0200E42E80D27A1A67DE1E2B8F2E10FB0B076D7827C0116E6A2319D99CC38E53A14F4B31BD4B2BF694AFD629C0B12F41744905C24886F2A7D1C23B6E3141632E1F1088A85CD9F6AF9A005576593C9CF6CA4F94BBBFE860D4F1C2388EC112961636CCAEF5D84157F8001BD3C156BC93C5B2FAFCFBB67406201FDE2ED395A83117E2735373E07C0BBA838ED01246022DA61299F080588E58CFE32BA6B0FAE8BA9B4B7C3DAF383EC14335A4CCBB7B1F2CA795A06C02BE537FDB9DEE0B46D54408AE45FC77DD54EBD248623E403217DE8C67B1B3993B23E14C5043F310FD87410699FE704440EB35903ACAB6CCD515880244C184EE43BCA31EE2DEEA3A5454801EB3BCE0255E85F6EFA63877DF43116EB900523AC48F662E61F7971F00CC0EB44D1E6F33EAAE274B8A618B0C0A402DEA2BC835962EB45A60DBABF55744B890301AD6FB863E84513F7022D52C9ECD758261C58525BB806FEC444D7BDF7D02C25EF70F9CC429EC33C7516FC84281684F6A9D63909A6419EA190028F20E301A3230E5E7CA25E86509DE71962E7BD91025E18B194F07DA2D32424AA734E94D8AE3E6F2099802700F37DC29405D2B7BE4CBF35FD58EB6C8DC6EF969114CF45DFF7B12FEB37B16DA34D133A95A6309D1CF28CC96D8D3D581E95B2CF94E737A757A36FE40EB11AA0F3F913C1B7506C11F59E046082046C906F5F25F310DCA23442E8423BFA4C977295509D6C8B2FC30C282CB561C60D44177A1F73E01A8E5F267BCA5A5C652F09E16C35AFD2655AE0DC738D70571C4E48EF34DBE632346F804DFF6D565A542BCAD86D0F6E52FB7F9771E850A39786689E1DD8E463E75D64E41456DA22D44D1BEDD3629D0C93143A1D67718C2863CAB7B63A6823BA00A6BBAB6C6089982D780A944B7455148D7DF8976D31CD9D13FD39216182453CE38B140AD2B621A71390CBFBEFB55FD66B9CEDC8F68C9504C0F28DFE00315A591AE709DFE9511269917CB4A89F89DC1E4470A162F89C45561A362A7A02F5FB4A8D82317CF61B533243BA755418729"""), +ab36c995c472d4212dacc8ea95f1ee25ec693ed8457bc6a62ed291a979b6a6e1c416d7e12a3146ac339866453960f2cc24f111573619dda31c999b213756e600bcb5a9d8375e25785b3c7069a72665195ee513f97cc8e28caa640266d2608fe2ff226de704047cf464619bbd363a3feb73e2d47df01f349cd7625d0b18db432b75565336477487553267568843606205253515824068244711850114744643273532787341658558327430044333402256081587535171344517634807008807633370820620716546413274855846856252544627040674022028836536373827541383208773875186683648348251757680728801003125128261155712544258157561003783166005674620687157083581564877088627841842774555801327868575542204308434338323004214761341056456765383014204440531581435680561577131503777667672352532047844617684265448124123648660177808165135746172300650565522412255582600451666165313587027165521854762330581587085455114053121351480023751688405763412618786711845681776135402575773758344478047280051103556627734803186240861770021185247176527722616358816145814811514060536870221854621103182625663607180318144650624216546754871047354164624168153471233044805141080414748807425068851107065574334428366872837263077015337257003145080344316436144048521253116726263513728883204823510034774420126602825342667117084583176238806802150804442282673267271486472381037062547008151325781823217223485168630253776236628044381354407638670266448373507274370405422728852575225681247624224047810183611221407283627210041154333112305767268423663105344701776876275776517745683745418040746282736048644080338088807621666361225348583347786063141187736408336260660304704562625306077687181373631777676838530485071857324430785113302862380543075448275258445010873417527535411864322146042506652578588203571265358102874051054007007776170787482703271464817538581744672845563458322856648331004411805884263244442853851516248334713570062784255773680035331352808764851703537003444265730315085260866221186817288644666201567677688523466252680113168206560036818856824456538181826060511868565280840760317143604778433077304400237144626857286674168627055580074352625485506271072107874512276371843427885818413042213077704005342270702186026772188022317550666001372885810325505652365822465535512370066430047748068806757050035812872642027575531211007684233425471123235162013764134784547815023440552134372432253283276337435244242126148441271544135651721106665301008825258874607420268833040324132761306885310670370146287074551022775376248768550262631878346375634603880661215657881831633748677608483166410002275602835021486452601600514087467338762747001627354482273888861763812343484084480461145702461577820200710217152348451601811752115404520872323133341274887524408314117823537425067462227764805412734655554112853716412560146010777511244114304537730212331208586841302127078636408840851673413682282356472403680742643508655605151500267084283273334113430051706200026602181421815041272467830421155788883212025787175681764014305848564807130860788478271203230488154661057461528415230351078146182662384624808617877187200274648170028523531546858533027676641325203473546874864283376606416207307326881524723857216011843510612852412265535601518443563181343067be4e4e886f61b24e817847be9d3ad4b033e1f03e2c698f42ffa611d25621991861248d97c61f318726b3eb116bd545400c2f5e1c08294e3bc8c4d4846c7fc5bf23759ba32c95bae32b756ab1ffdc337e7d23e26fe601589ac97b74ea1dab26669d7f5dbdfd017586ebfdc10dafa5c641ed6b8d4c4293d0f76fba4e19e83d843e00922c7b35d9cf4f657e832f2ea4878288288e479ea2988e62e27dbddf355d08f5298c763a23f65b0b9edf84eb7e2090056d1ec21a7f666fe933db5a8413748350bea0e5c49530b18529ae94663b12277cc2fbe2f6ef372a78abf5e3760f036e98562ca5c1ed862337cf8ff8e37c1178b4eba53e50f74650d084541357dba684ec0c63d8b7be0e38793ef4085d6e6a5167536cbf29d36429580c7e9b925de24d11a48cfd43b6b199fbaaea0846c890db3825cf8868f0ef75bed833494583113093347b2a3078686a39d0e0f27900771d252f4930f1d9b5a57cabb712f8c6342f01b61b8cdfcce1c61d02a64f70dd01fce50df23efa5145274ed73cb201247a99997bf7996ef04ac8063d1c9c68e714cfeafc8d0ef261bfea3f88f90c573a4ac7651d441f3ea832bb1b648b509e290a94b11a1341cf61d81bd94b3e2f6bdbc4c652b87d98ac250ba30c7e14850cc92b8d97c67d31fd6c6426c9b53f0de6cfc2d2ebada0d2b8524a1682b3ac360084f5e8ffbe980692d988e499aa3e2aa0a7ee16f7180c29994474a01406fdcc9551c3649854beba55ed18c1707e3ed886cf286abdd07462c25e6d54bb7a66a0d84181e93863fb96006c2900f6c88cd090fa606848da29dd5eb8b0becf44bf6f5e519ba99d68d68d3e158dbf604335d8328fc28a52b3a58f2d78432716f474cd7f6a1030db967e4752d55f8bac1280f7ca3aaea99fa77f8129a5dba6963cb419fcfad7b2f174a83210f86c24c824e7b3209e2d0f52ada2a7e4d5ea0a1b1ba9c7b177869f80ee8a279a3a6d76e7dee2e3550471db770fcad139f03db4b99336eff5c3fc01adea008b7c482b04fef014120ab90338ed94c5b333383c07f180d86114484d7e4616533cb4174aaf7b72ced331b8d57a500f5d73c2e32fef18ba2f0999b6a053878f50115dfdb51fd9c8ccb0aaa78542ade15909466212d6059da9e3105a81e351d44d2aa6a8dabdb7e00bcbd32cdb1fa6f362cac5ebafc3c672aec57a6bda2e1f316e83112271fa86a084942214d869e4dcec2b3f09eda04e488d388c9635cd2c780901eef2b9ddeec1a99d3270b37dee43e827ca0252abf972115637c8e6f67ee39736ec00f08c2709ba7d715a5f1fd5f29c470829a9587db239fe562a8210ef12bd2ef28f8d9385da3cfbb555a09d51113cc7d37d4ec2f73ba3d9c3a8ad9b3513839ccaf0be054574b9ba5e230d866ff5238e14bd43bfeed4d597b4e29ca9cdf3a93cba7c1657ffa5bdee1633bb24c81df0fac649ad231db891111762630df8a7b83545458ba0fe51003c17822d1811a033393db4bd4dcc8c34269a2098b144f3f1251fbde8bc12277817ac7e6dfcff9b1dd7350bf22f8b4f8a5e2f4c79095b9823c995a6a2aad82de004a0a0e5838d2e3361a1f69bc3bb6d425400d3470723d80eb9ad97f159499885cd93d0d317d8ae9c6e80781874ec8b023d9db11e1ade79e3e5f78d4ac2256820fa2fe82137d909800e43bf00a83ec73c050cb4fce1d3fc5a18f88f8611f9fe3de7b4ab1415bc18955c02e550b00dfc6c4b14177d7c9fdc5665154a2563450f892f131cb29de6fc755ffe71e7cbb90a199c46c01b5f20a9c0e177908d340433b0518442897a5f00bf6eb8dbc6d46aceda6fd94fd42f7736941f633f6406d4dab88f2eb276b332f3dd19b641a3abe3a2d095893114a1d1996052ac689b059476e19495df304535d4755f3c8b5367b9d9c6201d100622f4aa48c20722a2a1b48b2df2c7f34695264434755a9cf52326705a44e38fcf28bee00fe9a91c06dc6172926183ec2d6963cc8c330d0bbd74754c74db1d5df618858bcb2a6d31671aa72cd8534568eab19ea67edb2461866c12e409695f41314d6bb6609a77625c3799c1d708e38d387f69d738e88cebbda49cce3e76f9cbd727f65d847408ca65ecd8c2adcc349ab559969d82bc3276ab9ae90e827fccec87b549c677597a8e3bef7e9d93584c5295abd6c8b761a56123ec2c75c5d44d23c98bc0eca433e715e4f745cc8cb0acd056675365406aff32d637d04f3591858993ed26f72d5fd2f51ab35757a2b71491029f1e8d7516697902097b2e820a56b1f0d74bd59dba71927c3d05a741b9227a0dc0e80ab395e9d5dda03a4fa22fe8b9fa5222aa682fbd954def3245338f97f8afe2a02c4f049d7c0adbfb4a80a5bb45660757a41593aa1c70bf5c4d49bc70d0d00893da8cebeee56c83061f4ee4448d1e4d0469d397708898f8d435af0ff9b7aeeb81e42d82a21e1aa02de748715f30c5eeef03c95d758612daf29c5553ac143030e0c7c6d003cd7f83f582c34f28d9003611ce06dd96c4d0a29c6117b3d9269435888542adc989ac164868b2eaa7202ec17ed70d4d45f5d5f5582753b66ce243cc3f5039dcc5f309693d59520c2e02b6b0d67d11b3dedceeb13e6d901bc086372462c97d20aa7519f1c3ec1abf680d111ecb51a40302f5ff185226f4e46ce970d83c1271ef7d3b7ac7bdcf7474a169d76f02deca3d60d7a913e79c8c03c81c6050e974a6b2cec76e2d4673a83c606b69f17767b60da6a4a4d659dfc4e962b212cde0b7fe4f0505be5734da9095cfb6e9aaf0abcdb48bf7997f49fb38b5c9cc366f16eded384ccefc725c5cd36e0d4623500a5badddd0c31d9aff05a15ccaee106aa20b481d029f9e9d502094dae21e651740efe441890124dd9908dff0894ffbaa6dd8a56bf30cec6d0d433bb6540162f6f52b8c121294f7d662c3c36b6caa40970b09e1f06d7942c6872c92fe354704f3a38d5ec1036bbed80b11ca3558490c59858599c9a04c06a4cc0e943c12df6e673f5e704ebd4adfc7a2c2c7f3f63b79147edb224782e85d89b6c4bd119bfecc46ff40ddfa36afb45fb6681e1927938c20325ac0a6862d1ef291d63f7356d67c7bdcfd11629558f96d15dc8e65554bbee419a99f96b5dced87c43645caba673b2f66b37466841f64df734b4ff0d20110eedd3b6677757cbd020263ba85c4466a16bf299f263091598b2f3f6b9eb152c2b51e8adf36fc932d4804d3d4d1e398857d5a0b7e0acb7dcb6dfafe0041bd0a8552d649769bd6a3b0e3e6d4cb6afd0f7f2935e00fe09e518c19bfb5668d38417136f79a5665cdef97b109d1ea03df21cec5ee116cbd8b9d55c6962bb452f8f9fe618b267a8883776d237d1175b51140bff60e0eb1c0911250272612976661964e820312cf9d2304f97207ad71cc46bcf4cb4b396dbcc062eef8d891d88ba38984bfca2c6054ff31085f3525c16fb80dce23e4e13415225cde498f84884b5d768dc2cbc517c4a00139cae2ffb60a4906c3fd0a097816d5b9d84970669bb39762b"""), TestUtils.hexDecode(""" F55B1A381D9258CAC6DD7B5A57899867FB659A56873F31F815716075DBDD56D6D0D1480AE1242A17485AD259BDA2533CBECE28A906271A3E65FB5D48AAA124993738FDAAC65736230FA07EA27D96F372B90A16FF778D0ECD7C0F62174839B8C7FC50F0B0150D47D5CE9F3715F5964DC712A681626821EA27E912B80D2D04C346B67439CB5E06193B6D7F2161B4F8E0341D8F1C0C7F6E3B351C4EB62E48B555EF00EC0DD5CA6A572FB201D1A4570676A04000C382F4C332C34A0436B535CB3C3F2378682A982034E01211CFB23285395204ECF985F478686817A5F6FF4B694082B3032990597A8C3A85B7FB5C2C49694103811F754DF0434D09C1A5245BBA980D6EFCFC9BC63DD42362477537C6712ABDC952BAE377AE7EAF9FF0CE2E9EEE82FBEFC1CE56063293BE659624CCA0E23DD7EF4412DDB587CF3C5302CE5AFB39BA8613151A04491901DC30706B46EBD1B26D4ACA67587595100AC51770080FC32ED0DC109D525088A2579D8873C6929554C30BDD1E2A0A9797B1676A8CEB719F64A336FDDC3F95BD4A68F472F00C4778745203E1A7736764CEB94F33109AF197C98D94BA3F07E857A5B251858ED850E7E578057E833A2CF95D7505C4973B709CEE834A40F32CF07AD1861CD46CC4DAD37DE66F8037DF1B14CD88E62F81B9DEC286BE4968ABCDCE54F83C5E9E4FFA8144A5877D75FDF75A38ECF60DC180E9B72F256BCEEE087F5AFA5C6D779117070ADB4A671839E8032E55AC52E806C82AC16FCE76A659D6CBABBEC066782C4C068AD4FCD5EC425885A5CBC5A4BAB43D1A60D499C497A2DC06B136A971BE8ECEF3FA6606252029FE5B33661883608702542F7EF44720466D91FA1CFEEB9D8CEBBE4E252CBC096D99551BB90A0534D723B02146FEA94D1C1926221092B97F1A143E6B4D5A8438239B2E2842633A6D90A18DD67D05B2CB560BA8A964E0A49BC1987FF47895D664F92E27F8C90059C5C38B02B42D7A179A09B70023BF7D664A94F7289B29FEF89356BB51959FBB82562F6827CA2A3892E934A9F271282C204BC3C6B34C57882EEB552DEDC0644B43FB28284FDFC82A1148447F2457E94EC0437CB5E0E3B6AB7F7E48F0F53C80D7695801DBC0E96F9C00A4A96AF8D60676DC4A6A6D97CEA344D7E911BE7CC9CEBBB23C562BCEC6992AB1148384278D94913DC4BAC4F73313BF83CFA2591420B18429D1F88D68443B960F61A1AB8E2713794225DF2D4EF88CAACABF6F095DA88C52C011AB3A07D7B71CF209BC84DEDD7FF2D8FF02A0727196D50CFF6520602D9FCBE57F890D19EB7845C6529EE5CD98AA2FDFCF37FD7472D1491FC5267F1D7E6E91EE891D880D5EC20FFC761344BAB59A327F829ECFBF8E550208976BDCFB75BCD996599B68CB29B27D9EF68BC975DAE08AA121F4D95805EB89F2E8B2BFDC61058740881E9B403C54745CF6D4AA1747EBBA56473D00FCFC62B5F5DBA4209E0E7473A0A311619437D2DF22F1D5BABAE064970850CD51D4A62A51E9B3D3121B766632B18F8B7CDEF40B249812A6274D4C69C9EEC096044026022B1FF055A05B6BF1C919230723A952589F540E77D7D24A413F542E7E0D3F7F55B8B335CF3693603210E979718E8CBDF76CCED68396DEB561EE27E9008D7BDB428BB293E1A1BF2675D8A4568D3339682854BCF9E8820A084C94D78E5D0938D66676ACAAF7B411B466B6588E9E2B4A387D84F23963E252EF36A948F25625DCCE664281D76BB6EC1B8E20DB3A7140B194872DB439D89F18E74E1861E3CF9FD442F1CACF4FBFD16532BECBD97CC9A007978D17922A68CE98369240A8D1E8AAE6679CA5DB79D83EAC1A571D0871D5AA28F6EA4A8EB60770E8CC43A78E6BEBBD4FC63CAE26F297F1E21BCE999A509BDCDD20AC938E38702215C398726ABA5A7AB3F26DA34DB3CBD58A7882FED91C33803FAE62E9E69FAFBD698962F2C7226A641AA7B6CED1DA8A400992333EF5DAAC77B55F94D51F74226AC03F7ED8F3D567BEB678D98694E9E0D483815D080A70FCE76255C82FE020DDF32D4BB7B1AE0EC1679B3DAEF2C20FCD7D8F74F6FC684FB678F02DE6B53D03FB656A9B9562666F49797EC658C0E8ED14480A0532DB85478FC2AD1E21F8883F2EF3FD97DFD757D883C1507C44F812639711256EF56BF6F8FC4A73EC3AEA3099F6C2BE6B2380FF3AB7007129D4829103AFE70851917E02EC5F2117DE110FD8F4EA25FED6FBC24BA063B7ECF7585519132884FC12DE1BBEF498B92D6E2062F1A4F7C97FEE96BA87ABFAE76C50729AA68C8F374102B3CFBD69139491836E4587D0085F92FFE2A94B6A87AFE29C84D289293D9CB4A733F90389C96198E2250F5BDC83F123FCC4E42844DF74FCB65986CBAB77B692CA210AC22B5B56E30BEE2BDE84663B22507E00E0D066D5B1F5245EDFAC6D860D0493C218A541A1FCA4B48F1A916921153933383284BA268C3AB003CD58FA979A08BC48A57C755688B0859AF7F21061F9F1B7DA44088ECA4D393E8DFCCA52823FAB812AF36212CD137741C14F0860CBC7ACCE1FDA39431C32AFABB84989CEC971D4A257BDD70EC71192148824C17AF8F18816CA94C457E1023E01012A245F28FF6582C9015153DD7662E4321B465B33B1D5DCA9B1CE2FF49EA3A811B5852AF5C42FCE7FF42BCECD31C798C3B8F685AB50B68654192357CEE577F5CF1F85A50F269C28A1F2ABEA382AF5CD089C146B9473C8965A945091ECD1C02BDF64F9C3FFD035D8238AF974E7111BA4AB10288F105659C9E2847544FEC0B29B6692FB53CEA0DD312B24C1ED3CAA1BCFD94E529F6C27BDDBB7C764DC0161FCE578361E02E0F5F3FDB095B6CD311190466177A5FBA62BD18595DC49C29E8EC7E1F2F3FFCDF17D477F4AF8CA3EAC53B7018A026BC942EED87704108027753DF67BD36221E9121B49CD40E8EA7FA2D6961604BE0095099A4413DC11E93B4A876834776D144269BBBF8A9875648702B589ED4CCBAFDD726DE8E8A58AA5D1A6E142A470EC342BC3E2E1B49C7203F283E99E81E38F1D8D2CD820AC98D8244A705BFD9B67E771A0366C7C6958DCB6921A81C0C9D5152DA37CAA8CE18D6B97404B399052051D7343B3739610329A37B8BAAD173018708400AE02B8DB2A2414CD7DAF038F94714031B1D83A5A15DBA53585B606A13814F04FC925C3454E251CEECEABECD8CFBD6FC04F504508C04E25724807004612E2796987D34D04318F82F7E1FBA83A4DEE3C86FD1884B17E77231629F5D5D11CFDE976E639C60B436DD9D302C380E3654E671ED81D44FC595FA34EDF90710A6384BB62DE0D89B50C14A44215DD1121C602A79A003955D860C88470EFD320E8AFEEB114E547E50CE967572DF5A5C4DED09222FF7821F91598A0A9C41A731D64429AE7D9BCE1B4E90120BBF94EED78098C9EE30C38628297C86DF59930E72CA561A61B6EAE517DB39F5A61FBB8C1838E3ADAAB46187F0B5D09962A39955343631B74BBD17BB2E338E5FC8C43BF8B2DF3A78BED744A481A1D789721928962AF2B9E2187E6B52A19274EF68F329C83F42A28B49C447FE284A25B71FC95D9322E752E28C7B4B656A743CF6C56CEEB758E742CFBC4B8D8DE5465D63D3D5D6EE993A4C47AA72BF82126ED6C7423D3475AE098CE6A7E6DD6F3EFD654BFD5DC4414B8F23F9E29CB0D5DDFAA689BABC7B5A925AB19817226DCD242EE46B588D7CB8E88183CD87C6D06FA1A40915A3F19E2368CDD97A16ACC2DF4CBBC0B30C6289D7004A8B48EFE4186BC4D844EA01BA78E4D1F0CDD2648D0363CA73A19032A537F68E0AC01CE6701426A03E071A109D42EE5BF358445907E1D05761B8F41AC8A9CBE2657754A8C4D83A3516EA465D5AD57367BC58DC712A5C055F68D1CEAA494D9A845474F610BAAAA4CFC96EB51D41493930534D58533E20575B980F4379A80393DBF797969405D6A514AC0A9171B79D6EBC5B66ADED19821BFB090BF76FBF50CA6AE07CAAAFF584A7013A71D54A2B60678F6F02DA726E7448A2379C28BCE7DF968154CCD22F1CDDBF25D91C616234539731B8DF4F55E21F37B29BC77DB4BA802D9BE419ADC292105EAE58CC81A636D479B550D33D057B7AAAF28F743F7B8C17E26AB2A846AE08E804E5D4BAC09D11C736DB32F9DC9CEAD0442AB7B6AAA70633692959A36D6DAFACAF2D7027E5BF9562A93A1B35AEE5313C1E2015E65AB805850DCA7A65FFCAF14200E1EF0DD8F8F05A11126EB02C13FDE38F496E5EBFB09E9E2B4920E619A67517FA4749ACD8B0857C7EC5A6E94630CE3EA0841C64D2EB895A9EB7CE5E757F2FB80BB4F0FA429E779BBE314A491B2D45F9A79655396E70CCEB319C3B405C33BDC91EC2169C3A75C4F5CD7AE5AFD6CAF6C9F81A9223484E7A12512B600794351693E1111401F74E1439C99D77E8932E069193DF7562C79EEA22C41DEA4EAF9E93456378CDDD6C8AA97D8D69C222614E203B6A1FA6377A7A0CAEFE709C90CB91939BCFE926B35970B13A06FFECD44DD8A360AEB5D0432A532E8A3C275E1DC4A07D6A3E100B04AEDEF14A52C09AA90438D65C8E6141490BD1ABCAFDD5925ACB040A91A8E11D242521C1F00EDC14D62E1C6FCE721921DF42164B4B34203660DEF02677A6B8C564075865B030936F472CEFFB3446714AE18BA14A6E45247C9AE1F2836E2341B61940A63FCCFAAD809C84906FA0CB1863625E59B96CC2161A4715606DB12FE3E79C90B64CB9D3A93B451E1C746F6B820B4FB3B3521ADE56DF9D50136635F29EA908FFDB32C6582715B06487B391A36A6A7B96505FD8ECE767C38CA4D0F9599FDCC1BE27C9C60D9190139C4F02461A5C42310CBFD5CF506720C9A13067F83AA1FF66CDCDFDF59B673B6C1FB0301DB118F3F49D1BAB49069A9FBC2D653D390DAFC3CC5CB35F0E50EF4CA808DC69F0134E3EEE697597FE7E5C2A2CDC5ED4E81F344879A0536BE0076D7A351A199530C77C0AF25D5C7D5629641FC8A3567BCB1456C1AE1D216C1E408C3AD6CBC1629E14DD834819F94EE0D255AB1C61BC7C324445F67CB7BA0E5AC424EB9C3D5FABC47081752F98B0011AD389581B8C20333C2878367795E31F99FD2C082B04126A3A61273C94E894BA7ABD8C6FD743FB76CC4FFFBEA78A1CFBBD266DB4432ACEA74350AC06F2EC832BD71FB09481A045F7A17F22F9AB65CAE6782A2928147BCA3B521E001D4BACE5FF499B1462709525D64E72201D5620B5537DF7A3E8DBCCC6EB822129B7768469D18C891A60B948DE2C12F4E4DB574C6C8BC586A1B57E727853FBCDBB4EB148DB234D8759B2AC8ADA2FAD225B5420C2B93D7FEAF051B7B768E64BC6EB83688B5E7E59059E1079DC66C5D8696CE758B42AE75123CA0FB72438DB97D39F1340B2891A19A4084BAA1A5149FAA785F09300B9DADA3C45F19568226151382ADB16617D5E59FFE8029F0513A7156F67D9859A13C2BEA574BE10E319F1B69740CDB176A962810B8AA6C368805EFA56E4AF69E908A205DC41CFC3FE69E4A6BB7B1F541DFE0A0EC1B29E3C199EF07538BC8AD7B0BD31B6A4DBAF70B83443A9C6C06268F597A6D1BC50171ABF56D18BB277F83203BB671DE404FBC4DFC66EE8DD4D92FB1AB2ED20FE8E9327CB15CB90908F37171D10E759BB8D1BE2C895604F87E2307AF7720AF99F0552FB15229B0FE7B45A3005E6CB0DC88A6D15AC7C364189A84A6615A344FABF4D0DD82EAFD42892C86EFEE6E9F7C248462E4C6CCA369CED819AE94B3DC856A3412A0DB90353E6C6D9DFE31913C3249195A3EDF9F84BE94AC6EB82969AF272AB8802BA0E8967EC342834B8A38163C90431844DB073DEB60B388710FF880EFB8283648CDCD75615D35451D8AE4711C1D7DB1AA59675061004EF8164AF3B4095F0E2FFC5433BA41ED72AC2C683D3959C9D265C302E0FEE7258B7C870F62D40961AE5AC43D3BEF8241B38A574F75EC7CD608781EFC16B7B9D36C3844B6FBF477CAFBA155B91061"""), TestUtils.hexDecode(""" -B3AAA36B5B5A4676F1DFEAAE36203D94EC2E2092F4D46070C5C03089AFE6F991B0AEA0528999A8151E95DAA67815DAE9F7C21956CC4AB73395EB4B87F82FF033BA5BBBA94E238F7B6C184B5F2B1098ADA6FCAB8CA0206DBB3BF6548F932E522D5E17B2EBAB6B4A0A2AB6D25E86A071EB858832C2B8D4D718FAF28220A9801583DDAE046314A9A8D02EB15611E74994E87D555EA1BC1D10DB200A385AF09D1DF4A8D460189EE7FBCAC70862816A41B307F6DD179D990BF03C634E103E37CD9E254AA378602DECB325919E6C528F90D1EFA69E1815F481F22A3D0E58C9AC8018350304B887AB7F5509545E35334349C910C4B7CA7841288879CDEF8F222DAE22D5E18589DA715A5E35CDBCC9E79D3B6F6151B8F5972631EE4F015ACE124311355EC29CD3D4B9AD445E4B88BB961F9DE36DB01B1725AC1F0215DF909AC68362ED611E9EEC491BC6C01B3CA43C0C517267FA44C43FD4F195FBEB882E09BC2A0E13AA71706298AB6655408E8B8BAB108F772B6054EC543EA36E9382CAACE0EB62A5653B43C6868FA8AA6129F902310C6BB228941FCE346586A40B156E8572F6AD4E300F74F6FCBB9691C351B7F5E9BBDD8C6187085193DED352EF786AD96525E3B73DEA31E5468C8101190F57B9952B4D8CE57A3CB1A89A91C766785D6987E90BDB809A32B8EE7BD284C95F32173FBC55AF1EE56110DB65C2D6DA456659BF0B54184C348E6FAB7C397FF05A182ADD25345CC5B3B40FDDDB65F107F1A5227D93D6CC4AC4ADAC5720E5D3D801342FD06916229C61581F39A7FB0903F90FAE6F7DCED0F0804E003E584B51520A7A8E4232368D7B555F5A5F4AEDC83C408696CE2122CE6C8D42EEF94C6F6FABF71B34321B3C457016BC576F01B94410742B52A60634B6F57427F9B7508BF9DFF7665B8D8DF8D4F5A4EEA53F9A7DAF5BE52353DF441CD839B846FCE51338B74AB01149667AF5A74C42C6D9B324BE5338C69FF350292EE69DFD42D8D186247EFBC72423DE170753392F9EE3A851FF2C01E3E34C399163BC611785303DCDB61894E6E32DC4287C87782EB136D1B865A7563426D23FB354D373869F0F13A058B2F626951A2C5F4BAD5A14FEECD94A76DB50C69F434064682509E46C71D5076F00BC058A89CB669E253FEBC72AB42BCBAB6851B5DF111A06381609DF87972EDBA0F9A77EC972923AD6F49CE0F52F3309BA7E614DF4C3424473EBEF40EF15588D728F7609C4C2D4C691E54A09E6AD00DFAC07E69358A5C01EE4B9383CCCDF8E8B7E14DEE51D8B3B966F2C1BF547E1C58756FEC20278A8C4547250129516EE0EC1CBCFAA8C3154AE3AD9135D15B957174C1F380509065B035B1807FBF48196801831736B168E009E023616A73E7D709579676B0BF19AFF259BDA7F1313A46F15526B5D1048D853FF83A6BCB6F446F18BDA693D38A313C445FEB6C5979AC2CDBB750C536076D0E8E7EB728C3F01F9E4498671A34909959EB82A974BDC0AE784B6B514BB435D2FFA7B85416E56A4610BA354C3FC1118BE292B6799D4EAC3719AB8EF6040BE4C6BA12AACD9BDDA672452A04432FB09447C6A125F6FC27A589D3DA986152A0C3CCB72AB00ACA16885CE3A2E7F596706C7A81060A29A3DE21170BCFB1F6029C859489D58EC47B78717705795D5EE92C3504F4B0A5EB542D24C9F4A07F5FBFA1F5159F845997138296A18F9BE82B7E756E075F60D794243606BF1ED443B207816C854291CF3E2085957D52D6991345AB1150D46E62C6FE96F802D21D2A15D1266973FBF540570F0564C97CAF5F54CDC812FCD5C21C8654193376EFDCB5E7A9CB60BA929E00C933B685B9A789787212D1DF26C8E87347C923523190C89C7B20320AB9C1004B8148080954CDC8BC5D2EA91724C4284C21A289324EBC3F41438336144D8C8BAF5476A9AE92B522F88759F2774D9ECDC52960FE0C1A20B32451F4E51A1E73029572CDFC5E6E6F6CE2C0A712D4C4A74A26D7D8A14CDE65A4D277F8617A9A8BEE3F5EACAC1226B0C1D73609CFA4C937FD4B133ABDBF5357A771D80502A46B57A430F6BE8746F67448634BA215C7452011A62AA480C6F2464B1DB9F2096DE42C5E2EA1CC50A460D88B5F10692D29D9BFD03B8B8743CD0500C61BB7F7DA4CE336D25E68BD9A37841F5558C67AE45E3FF719F70E3CCEBB0128AB619C23AF8D82CC7E43041E7F6270DD8946987A090955B30C6152B2EDEF4269732C0D89817B9BDE594AE9E44945F947BA87C769F7F632AD3BE05CA6A749999027172230A8A36571534D151E0A0E3B99968C47F8FA9FC2FF4703789A15B363D40F57F2FF7CD3202D98E47ED13BBEFA9DE66BCC5979D7A57C91EF186DF2F2C8F02B474624E8F4729653414F6DEC7F763165164944BF7E9876686233AEFFA733426D63A3C4D31A4DFE5A6A4BA49CE45F0C9B0D85ADD85DACB28D4B75779F8A14B415F478E84D48A797F0C2AEFF842FBCDEBF9B03EA1A48760461DCF60592D8876BD967A1018FD85BEE5A31112628A0C6ABE9135C43757C2F1F70CF69C6E34BD5327E43838C33A2E01CF017EFFBE6C5CD676B7C2EB4462CB8EC2DF4810B759B5660F221EB8AAFD11E816E4EAE234AB54A4BA67F26C5787952A9CAA9504A4F26194355EDD7D7CC0755E70DF38F323603E1CC8738306A4FCDB7E6E9C5AC26F70EDC1D714D80ADD9628D1CB0F50751FBD7C4B4FB9987756248F7A5460B7BD30982CF3E60EEB075DA4C2054EFB0ECF972E67CB8350A1B8A836E285680BF8B59989E0CC9B0CDACABD8D4527940ECFE45E00300871992C69F23BCB4BB5F79295FD520E4E7D89C448F2FFA69AA40590A11F7F856FFBD486B53334B6537568D43039EE2FFCC2A0A840A4BCE03BA507DFFB7CFEF8762B8FA40E48390C94F4DC6B74960BF9B67801F7C461DD9DB9377EEC32753555BDA4BB5043021DC9C4FA543AA3F58CEBD08003069A8698CABD428C091F0B06220708EFBAF640975E09A58D6CEA83A719E49E9053BC67923951C4117108EEEB2C0818D988FD73697D14C2145734D6C65E0688F4FB65C8725D58BCE41C152D292BF9EEFA242AB204C77D7BEB511E62E893E255FD4DBB7C537E79B2DF6A445CBF67DAE85F6686807B356B7DC2AEE18F92ADBCB5D7CC4C80BD2CC2FBC2FB06436B1B088938BC7C7022357F51EBFD466AAE707D75186DF4D50390B1A3BD4FDADDDAE17D17EC36961799621BCED05C06C142094DC22D8AE2C70D8A2503FD7AA71E08E9726E1FC486B97AD3F2C490AACC6361CEF13400D34502E0CC7187BF226F35C09B784F5432FC44E0E6A913FE34A3E11EF957E668381AE4024FE33C264004E36DE439194DC5961EF2B8CCBCF0A2DCFD77366649CD20D73AC577898D593C1F769858CA8467E00C783597A49A70320BD6EF3EC56BF7F5BE745204D6EEE2C702860D6A4E8AD77F5B23EC389CA800CB4DFF1DFC22E29C1F4599EF131F5B993B8F9256795033309F8F3B73DDBB3280BEB2582D81FB9466CA18C5A028BD09F90C4A1A725C10E49856E07C2EA752FD019E7F4AF0CDE66B9A2FB9E22F4C962B81BBCCD218E916FCFD83A5CA2BDC582D0B2090F2172F581200BD0122FF6EE52BDB61EDE5DAE73542AB3C38E85B8F871AB1FF6C5FDE0EFB25ECA17C1D6F6777F5F9020B1826F0E309FB7476967A317A7D7BBD9E4EFE871E80A55F267D6FA3CD631250B594ABA0EC0D28619DAD9DF904F46098B5935298CD0B37EE80A58FEF57284A4CD061E093840C9D4CAA6DC3D2C1AD09AF739905A4CCB12CDA458BC9ED96774F49C5F9A1C43781C2A08BC99C0884BFD9C25545CF6B9F0F343EA84E8270C97BC47D706BC56B8E39B0DDA66D7A9E130E572586B9F1715AC35A4DA378E7B10CC998021593DBFD027001D2288DA1A6D72D9A66AC8930317E5154CDEA34C87980F16D1FC4EA87FDA2D47267CD5330B39FE941886FF642EAB1953CCA30ED21279365844C4F5043205D482485E45FCB6E52AD8B31A7076BC96FD88583B34720106DE1158FABD0A4F4422FEAA65B1C828A3D4918A36A99D34B99B052C7EDE5A9F6EDD59E1FBD2B2A025DF5457A9A3641EE8F65C13E7969911F5AD7C520F3C9F7357BFF13626262340429AEA5DE00798D73FB517185B259DD44BE7AECA1187D14F161C0D68FD44A272C38EE1686FF56F55202283714B763833EAC7654D3485509BEA34A669333AE9DB252DF82BCBB65E85ABCFDB0B23FC44BF4527E9C123AD4CFEF148F49178984BBE8DEEBE0BCD4564A333310F8BFC436810BE3BE1349371F35DEFB9A95AF245D92EB0DE9E44230C85ED86280493715F540ED2146EB903ECFBDC1AB2BD66BA8744B983EFF9437673A1D32DEFFFEBC94FF3E46D25B3565B71D7428C1C9E28FE9E191B79B490654762994D98EA1F75808914FA6D93A1CD216D17CAD2DCC519104244E2E9EC3E607A84142528FADACCCC6AE316A8BD0818413BAF7A90535EC2CDFADE973B1044FEB5568748C1EF7A1DF8A35597D2C8D86A159A0C9B88572569C50820D9C85C8FF52C072A81B8684C4EFC7900048FEFF31B4D4F144264EF77488CF854523303E418A5C42A1A0AC90AC5B6D4E84B51C9EC73E2ADA8EE053E81D629F5A5EE992B86B7984DBF7FA031A6BADD3D6191E266872B6E0F4154B7080BFF2F500000000000000000000000000000000000000000000000002040A10181F""") +5bd74b9ad4b08f18b54784c7c6952152a4f597cee14d967851ae2d781f249d926ebb4f4490487d1ab299a179928f69811f39a8a019bd808c500010aa684ac9954aaa005c9319d75d6049ecd99ad4a3dd535d881e8eaea118635cc5dea0ff3d4a7d8bd9d2bd00b78777f6528b94cf8de6ecba3829e8fdbaaafec7a16106457f0204192d88bcc76271fa31718e6ab4be525b04e547f9774fa47a8e4a88a4fd9b058412f92b27a2e191d32f015ee31cad4321c62ca55e572cbb7c2872615e5a2924d7945f1ef161e407f415b4f963d4cf6272d954923da0db3b04649906ef6e2da18592227b2b301a36298861e793b88e7fd1de2957d8a92c727b492cde702ef2b123e9968774604b71323cc4e7e58114c3ec7b59c94d9a17453795f426f706d98235c99ac4b4288d894e480efa3dfd19b14872fcfea1836ca639fc7242a55a0d01e1e21301f39dcc9aa94d2d83bfdefc26cad8614406c70bb96c149ea652f66f8d26ee0455c6cdc8e648fb20886334d512fd940fef6d0d52a14fd9c33e0be6077a10b4729a8f6200ff5a5669b3b533d366b81cb6fab41dbb9dde1581e4f3bddbbbd5f18cc00123c82e9f82412b5fc8970b69bf2e68fd5fdd17b7288949e1a7a6eab8986ba2e7e2f98b5bf2a561ddbd935802fb59a20262a77137c99274f4597d070c0c7ab5eb82aa445fcc882b1dd0a825a1f0a2c8181bb6c608a53704b9d587e555d756333bea70a5e73ccc5ec20260c8ba150a44232aba5ed55f49281b0e697527a59e4cb579d27183921dd55492cfc2abe640e1aff9147927ca2a1d1ac594c52502536d1942fea6b3e52793e2a410fd6ca7dbea45a5a696695100f53b9fe1f28bbc0014ea9fa3b134f2cf0c0a2b0a74525468bccc4677e3959d62f2cff8119e5895211316b448451fee29720a74d0e09bfec52913b0a26d1a60e404b2c2ccd036d73a2cd4dfef3d9a10549287d70bcb561a3d466c8933668f69d2e3f1a90951ae4def67d49fd09dc61342a15d1d576ab41b7f145d73a99faabd04b9afbf8491a28c5483674e9f95f3e4146ea0d9b1ca61359c604b0c821a9cce85e53b5e666cf1786100fa4c4f14dfc178b63581bf502b7909c68e4587892188934c0472412667e552bd32184a306148019d56236fe38b03799c2a8c748c0b969d9d6de27a0b842be7580ec8e186c76eadfdfe4222628448abca620a246214d2629b2be13cfa9e9fa3c26c24b03da758d5870c4f79f68c3be2bf16f97a7459795e1e30d0706f33c4f865348785abc4e6feaaeff79b1b45527357d31ccf575785390c35b2a4c87cca14fe7bbbe6ba82d96cb9bd6f47d9ad73ea3b061e030bc03a670bec41615f86360a01a37a3ccc307e31aa6c32fd558d362142fd5668e948441275f265697e4700d87853b4d1b8f50c1c9eb96d05b96992daf7e9d3dc5b78a62867ebd7b901fc37ff34b67af0ece5fe7050c94a43ca96af0463ddeaebee931bfa9e14226b2c7bd40cc99cb7b3791bd57fbab3d4961fbcfa4d9fac748d73b2de0c7eff554699cee1a72b197d6ad5343aa72d7d0bcfe6c3b458d24e7e75d00a90628100d635f032f24834a3dd0ca0f5fa0d040b98ac6e0ad4a3c09445d91d929ffcd5424800bbf06a747c7a05eb87cebe5d64a383cd77a7cf3dcc80300927443692c50c7aa0d12e1482f071ac1d9acd625f6e8c59068f1a08eb163a11685c7699493cb28b1fcef193aa1151ae7519474629485b7e6fadf01f369f05a1c37d157be7560b38a59643ac997b18a16dfd211e23c1c02f936c773b8b3440115beac0fee20269302ba0ca35d0838799ab67bfcb300e89909e2fa63d83b035d855bee14c47d847ec7f7ed15bf16130ab8fb33eff281407f376b3fa4f6894e1681e6eb025be02de783b22680e6ba9c4646b88d91e18a48f751fbe168096bbbd16a2f4b2a13085158d55c5283a069362f83c9247b0c65639aa21405f343a19dc877843bb72e39e6cda5b7ea3f198cf59c9607e1c5f09bf8962bba657f609f4e9d3ca99cc58f6283689c9ca4d0c4f659831abd54e1f154b26d4b7a103d9ca6b6112cf5bdf0e70103c8147fa7f5223665f75bd153d9e5aa982ac475413083d9baf3cc20584c792ace31ca3c3ce87cc16fde69df770f717bf9b0f10a097595ae2bbab69dce06d1973b01ff9922d8199735d6e16dbf4e7b94493b1106fc938ed093eca657e173b107cf995a251e5b6b7c97daf07bbc2ff89f5f52121522d175ae97cec1e98183f646defd2b15cfa13107cca9ddd0cd9912a23b139f84a2265e35b7053cfb7be23b79f28fddc9e3190b0355d0922543ebff420493a9ee7bc1c18d36e2e76437404301180bd3695d7d059601e204f46da1c5224966fe6c099f0ebf6a2f8c61ccfecf12f9dd4f1a197138e013654280a7c5bd26ab1743e40d8971c8b6e4908113b84537a410faa756251faff8fc8bf0fe8d325dbe0c1a6f7e099535e08bfe584b232a36401d9340ce323eae8e8eb4fb3fb57687037b7b98c6ac8fd7d919b71beb9273f4234028ac2f034685c81e630d57a83162aec955bff545d8d0a9c24d4a023988890301ffd37af5824f59384f596a4c242fa8378ba2b09908c74c8144ef1a6a4ef0b9a6738f8ec52e114b9aea248a8d2d3733f71649222c8737764fb440c9f2972390d3d4ad7467cf238f48a0a299c891210a60deeea020e4b8a56d2b5fa61aec1b341044fabd4abda13c6e85fd70170d18295538bc8da2908c103a799448441c50250455f5481f7a4f6eef5792f97cabeaa99936557b0ca845bea86234c1de788cf2abc1f32a80b13573dc2b21b110fdddefead44d94f01ec772078b1175b0297b0b6de6d6097e8aa3e5278944fc9e7a884d3267632917bf56bb53dc074ea14a8dd6e6c1a73d9959a5d2ae385f5dba4b8447eb451dc441832a69c1c0a3ed41b0997878c966510dd500d61666827435b7dd7ccbd125f157a419ac5b614ba6d65438b6c99e4d8e5e6776809edafe8fa6a76e11f5f400975df6e6769f2c2c1ffe3d40482be08581d5e79088fbff8da514abbbca7b3ccfdfaa1915c373361a971ab7f5c1c09e9499592dccd610f14ed84db0a2be1c94e5bcda339e14ffb27af1ba66c7130f45942c687ce96ed553ad7776dd532ccbb0faf1aa41b7765023d56c9068d56c3c405b8b2890c4fa6bd79466a4a146657d9248d8a348bdcf41e3388993e8ff2be2fc8b8dae8d15269fdcc040f7e72872539205992444a4d19552ddc5e51b778c5b5786f2d7b79036b73e738d7200aafe96850887c44c982b0347c7646dbcbeb4b6b55971004ade87ff20adef58d3aadb40d320d43585e7e55da08344dcd9fd8345a2c612f656ae178c914b5662d088c3437a6e5928d3410cf65dbe2ad31f1fc3781d6a5006ca8136233814be8d655b94152ac70df8cfc6f9e9101f5b53cd5fd37176341e1eaf25f2fb477d1d212333ea200a5e9da88b19db4163a44cd4c9d3ee1af413fc6ccde64a9cedf21c8b8f113d62a63df2233f9a195aa67803d632ca873fa11069b5998c1200dbbdb9647a98acfb4e3229185b8c220a6079c72bd4645b04f32ffc85214bffd8ef2cf27d8459eea21069c13bfe052ef92a070e63d05c9a9a82699676ea5cad84e508d7e811073e17bf943516fd4512d53c7b3fccedcab36921945a19d0ec3d9303bd479a446ea1a5d5e4adc5a97b92db843b54de9498592c4859011bd4df412a6151bcaaa703fcd97e702d96b0ab14d7fb0ee225f8097c174b517ea051f8f8b8af47a75a93fab99ebfa84f8ba8dcc9c9927e24f6c99b66f34f86c2fdc88755154f06d9b1ff731411f35377e14d2375480b688108212f75d74695008a61fcd452b6dd23c4d910c409d9edb69d294a5bb46fbda29d6b31b24613e751b3aa8605046cdb449ba86f27d226e91757a242ec2e9d241aedcabca88269dbda5fe8e5d8bf4a4cf1bb1585f1166d36a388a47241245d0001e35a790d6d201a92f34ea315933c67aa26b4b22ffa7d87482c7a63b7544ab511644b9e95152998af887bdbbdeb6f2218f8936d5fa50686216e30db9686ff1e924c850cfa31ac950bba1cc1124a892fa1c40f62a99eb452a344f65a1410f500ab650f9e91244ce5e962caa13832df55c4b41f53509d13d1765063380b942a5d4e718b9fbdfdf31259b879614b2bcd5c7a637c0868abec9be94a132be2c62111e5f22f420630ca64031ee7f43df2f8709e9b200f0f459d9f0b4bfc370f6faebb0345da46aa11c975670cd94ade1781d56a3ccf2c0729a8238e9cfdb1ee2e575c524661d089f894a1502bde21465f430561a72b835a39a70c60d64f371affb8ea30849956b767a5ad7648be643e0071cf9f08e880f6926ae2fe97b8fd9ba02dfc965b3ef7c102eb207555f6037c634496fe8de5cc8ae0184b6df1201e8ebbabfabc4dee1df3a15a46414e5627c7b99982acf3fcc7806d0e8b9e9356f21f15366d6327a3fe4d332eb8ebd410407b1b57220ed702dba8783c1d7088e66ff9bea1af5794c964cc95c415b26598d39f448a428c575de927e7eb129539a267c3e9d2c7b844e80b1c396810f8b703c2f6f141339bbbd34938cc12ed634425b7d80829a9cb7c8d1f3050f1351587a898c92bda2e1e366b5cbec034750b2b8c4dc00000000000000000000000000000000000000080c16191d24""") ), new SigGenTestCase( TestUtils.hexDecode(""" -0297C0FA60D16D4A0D17A019F55A3F08EDAE88B98ACC1C7DFEF6BD42ABC7F9B95BDFACCEE817B390524985E281177E1F58D0D332D88A53ECC69D36CD3F2CDB5DB5165C52C2CE37612A4CDD2B62BA83BD66684F96B835670FD22E8ED003408BF9D1F52D90CF1D2D3EAE66D7D85DE8FF119E46F27EB01A4A88666B02B2C5CD7ECC71475126233751606406113524782512715333860324438760638762734863482074003581724563351353138370627434260445637442177740371643224671617725441344250077330875181226586513706860871721017807300117550675284633706413607083013276585716370368050360711636355585577030632744062432341561238384284175207553145658474417404154724103855270733216724328004787058212163440458651245376828170458827746751653134524478840643478264478207475568815633525051308106624207867342115378165346422073070271412006802582227512715153203088321004847547556737460264581323568705360343334431146566351401314880877404717661204337656538731582228565331786427057033465157483413750216317745537626715720244052725853713888388134843772034588472347173687745730066205583284724450000625141552705674515631427087434751825444380103432251711865645505836042741704560123523466822474632315045847723202654748142365813273005127174240207784056454887672623315657661530444776343656142117642778181763467027344577108463016407222826446461136448285450720774714430371008081132006480153606526463888054500118888003781136213148822370121275828340188141732881861617164087530333608831350247480601478725271843745774177873867312067462502403637155718413362531502661247285480024810234235400373287583667573412665140207568763110311725216005676866080753252314482804083063666176263420837737160682227765684481183417033821367724774461317852010100623286300633771066431466481720800788057135404721823251208256681603522737022068184055137381511425223830770027241631858506536650561586474834248364664527764288258583362258253611711468120685118836063400130368635701515801213185810606620114471462062014451636631838874230368660332432366768312320537254065462521272660077350618508423570831123312654084175610472468372463383236355463060552050638703827717733247850374664833535811821007341633446035721564215452045174715401058443708781470787635660678122871062520772570612807708024277164210323003680110227842476577255318133076620664182015776421146370080642876232368544572781206873058413012137383478200823323051100107156883162232725863430855777107357615856648065557274370204175012652058202246626757621404800874450550038325336061484681482363078018181432130234117583142652832864715748075227663747166702378321453044770646634388835406301744345204662683538438062348531701370655844554268761343776785460263714566588627783555812231322607824008010540740805513544233266705274246487108817323774438713754288718083217056316548462085815377128322036330530628018007677542067157424064876784444558815064151587171085581181235145012554740075736440276116856220542332347645738730270817668064813705460748025865533377527104018483583800012175176185223246188313570514482238856512801400078072461421870713162071176227243553400204034625862157643623617203115234046563256232806750543822670848323427755448215870168576404750227120773663868780623554673551445E94254DE0F4BDB570C48E4A4B84D39B8B491B4B272EE7207E36529E757A3EA9B5276ACDFE4AEA3CC6A05CABA81A46731C132A2EBAAE20587477129304990899FA1D512C5CE65287A6F8C0B1C8C27B44C21E70BAF94607D74A425ECB282990C7C05C66413809E6FC4211DDCD4A3DBB34B55359C85CDA312B23FC57448C8886B74B9DE589433DF4647066A32C4ADAB91470151FA69CA74E696575AC9E666B94568C1932554DB63A48FA9A44E9A34B0FD6C006148ADF69409885A99E32AF63FEB3EE8B7E8E25D207BFDE31CF17C2257A6100112B0512BC42DE1D38A9A292723CFB7F4ADBFA97EC6DB138F916CB479BD30617C74872E5000DECDE34884086D2640BA4E26A21FE0FC02F13F029A317D2C28BCD5C88323BB73C41536393234015DAFC26AFCEE2C42D8641C0054C6F8BD69CCC8EE136DFC1432DBFF2FA5239E032DDEAEB6CE6741D24DD87ECAE126A7B54DB76E505F93A6352BF154259AB84E0B6B3268DB1EBA038849E3C1E1A638CBCCD8C255BBDCE05E5A12951BAE8EECB62C4D8F69F89AFD2E57A216BE5FE914E82FF2FDB8DC8180FF798979766F95E06DE29907EA2BBEB325E3794773E1A1647F196F2A0D35778B1AE8F34B02A9851D132A0B6C349B3718231BEFFAD69739BE1CA60F863A91CB312AB3D9C3EDBA8D2EB3DA894FCFD91ACD00F1211239CF8922C5F970352B754C92A1A69D3B0EB1B1207F1E02487EA2CA8D1FC41578566E6760B9F65A29B77ED07491D9AFCA386CAD30B940BE4237115B4B335B080B77956019FFE5407081981C1A62ABE21EB27E5A74318021DAC60F710B5C310EE59EF7C4065C5B97E44639A1736A644A32AD09535B94A9E26407BE3DADC4BF50D27576151BFC5A57179EDE6DE8BB2A8E83AA215FAA3EADA0993FF66F2569CB5446C73BF3C5451FD3A0498579D945F23A26980426A3B9E8AA23FD26F9651D1E06BA56DA1F85B7C4C9408A6F074062DCE52FBF9C6A8147F86B793D41C09E3FF4317D68DCF0BA7A1104B30A2930CD8E248D3DA02AA931F4A3A6E46E20BF4E9B3EF671E0D5CA23BEB7527DBF6E36D622356867A870EE5D36F1496357897772C89D1D2C11F8CAB88F26F7CA6C941190DDB06C57001B70534F1092E23D43AEEE40483E4D3C4286AB6F51E07AB71DD86008F5B0268D8F3507ACF6FAB2C2650F1B43EB4B3E32A959CA23B2C1EEF2646DEAA03A81042B20B9A03A0595C86C5D8D85DE2DC31900E983AE122DD679ADEA13AD7C1820EB1D35E2237EBFE5E00A5ABA5DCFEF82E52E8AF34993D30160FE3866856BCEF955EC731D99B1962181A31602FC7E6746F9869F747ABA49C1804D742D6B072CCFFDEFF827E9F66B533173743FAF5D88798698BC2466D0AFCE77BE660CED7B90B43E4C81ECD9FE5E3CF23B27AC363A964C1EB4D2B75A60D439B6CA95E2F9DDE270FD722D4E14199EA6A5EF69D2D59446E8F2C8BC072C1488FED4C7CCE0B547B70F629E70FF7EAC26A56DC35190019BC5A141F2850DA2FBB79C847C338350A72E556B349CD82C2562D93C273A62815F6E17CF7D731224F9B4F0CB1CA6FEBFA28707A26A37A1CD6CF8793E34FD55865969AE291A23929FBA90EA6645AF179D92D65198E30AD5D7FDDA597FC097A021DB3CB85E1196F76A17AE1C8B907056E7263924400105359DFE7099C4BF08425F68C513714114CE9BF6505D4AB1A4C31743C62E11AFDDE423C9C4394731B892373B156BF828978C17D833867AED249B609C4107A43158C2EF607789922B6F72AC827998F7738D662E9A15CA66A1200D7F6FC9D8523E4D40BC70D8DB762437800114A6BD2E58F841B53DB842D345969DC31A8003402E6C2BDBB8782CA5198170662662C3701AC0F6C7C9E35FCE3DB31D363C594C7E2C98206F280DBDA61503CEBC145F73EB541913007394767E8FA21548FEAE6F29E3CEDB09AD37200D082635B3D87CCB2DBA9E56E00A50C5592EF3574D7F49EBC1DB5CD33A1DC46E5A26D80203A3AE44D346283217C72299370B254345409122A187F099ED7734863615F91E083CECD1D74CA49F4CD8142361C2378289CFDFDFFC5B54E837E41DFC9204D4905956312214EF384EC9A0D907F07A143228E3B950FFD27B85B43A1A5DF06736D57F91EF4CE7533B5DE81B2CF21006855FE5448E0071D40CFA25FA76C9482E7E59D09FECAD3FDC45BC640D36EED01AFEC01FEFBCA2E7EC71F36689EDD0661465F97628E817A9517311C5BCE985F40299148BD7F6187590E72FC8D56960A0886D93510D660AB96805E160D202FFF3752D6A1AFB68A5F06624F9A2127EB5C008DD5C43B3C6B4095A40F035BC095941CE8F89905A3C6AC8FE51879D9B5AF24847A52E1A5AF4548F3A70EEB3369E84558C16450CD9D49D2AC5CC6E022721F1420B93ADBE9FFFE2E91926FFC4F4E443CA2523AE8E7A96F10349D5792EE079FBED9E1BF96E1CE5F02FBB5F41AD564EBA9EBBA08C74C96132304FC0895DA7E6E34B5C99D333B97C062F343B249CE8A42C916C1E473AC763D0643063AD226EB9ECB4A51BC7B8291D58F8C1E1D331375667F0F80B71543B052A7CBB8B95BC267620FAF7CEA80D8CECE430BF1E515144817CDAE07802F5BF8416E41A179AF840A27D7E0449D8E7AB71D6A361E56DD57289A8638C16A6BD4C6B946D60C75533D343567107E67D12D1C7FEC1628F9C75C7F81033766162C4E3AE0635801EB74DA2EE0FE14B3EA5385154AF110657E7080A21A5CC50FA7ABA75D6C68BC002ECA08BDF02CE3A2675066FCBC846917365B988FF162866F19299ACC1E79EA08E36742B31953ADB3F7E1D38AF6D8B2072B35EDF4789639694EF82B0323743CFA075D839BBFDD66B6B6753D5EFE3FBDB97FF00F7BCCACDE4BA8EE392C4996FFF9A27F5E7EA34AAAB868983F2BC2127A3083CF3229E15D0CA9628D6F9CFCA04567434452594B5047767AC031CDCE5C0745340543584724282BE058DA5306D986C8A20CCF9229D40221A66CEA47E3FBE5B85E5989F464128F7941E29DFD73BC85D470141DD8845344DBC8A66F45CCAEA192B0904F58AEF8D78F39C4CEB4E289B75F2401B8036853188083C60AD910FEBDDC8FD7EF70F007B4B7EADC1F24E72B97AB441DC9B20323BE021C61C4708075B571A30D7E8C9A08FED5DFBCBE215345ADEFE946F44C9BA0F19C3D4D0589495864BBA958AE84888AAE853A59E274A07FC2452B082B84153888A5C15A5896EAA0CFF52BFC525DECE99AA476C465D5B53D175108A996812E21BEB615DC5EBF7AF1F4CA7DE7BCFC49356DD08224D08363EB068DDB19AC2A4B37053C0C347925AF4B5CD05C35413AC450E344A149FD32CDF9E37B38AC4230ED4D04232A21942780665C97F6BD893E438558F8A1A4865A9CD7DC0100B5DE099B163A3640B8DAFA75468BC0A93FF75CE9F58430810345124A8D4FA546376E8E56DB2610129A845F5351A31142973810DDDE9CAF498C7660BBBF3386C3AD4EEF7C3B5DB7AAA2C406605B60DC8710B94153884CA47A99D64DA2DB26D658C9DC3AE5E6CEE"""), +48862a8bc5235f5337a82329e949240dade33fc7d17ace18be0227ec719ac4f772476711c39ed4d858cef667f47b1f58122e3439253b354ffd3d915c4bdd94e14e1437d30cb3ca8309258b6817c6ccbffab6c0a3ee80a7f9fff6ec3cb6ac304fee454d34bf07d0dc401088d8e24c52088a2ed7532b1d1132cc318417a77d907823576447516518710576715261823080317441353842046341354050886265582772661606782518508611552437807857666558606283636012283372443712522471787143475036431221671374672177808348236368861183147027640303725752144220330577506201512281522412264744467558561844471460507113285137145681843753253233607103662808040646312553435805068686713021651551288186147173278000431232842530725086636536773248376333615710033580724287113217601158383102361765586225028003127168204582787754742332377107533753763435244134327846130710212236212502511434853724442254425760443666601728131748563348431443881772136248213437648571843333076605047807073574052864732182876230740017065188788771270704823801338454355646476150321745651674118477033827545476526811583337650082472640360778341752532318807731320471123877320418483134405327185031072657067505600530116026654376786484528715283751501655402235447554314302138750568000710650360358713328803146805241243333606411738065128618661601325618272020045460442876423666675125470876321815280508701035085287150558773181677875461325332283334727340248486766321227570432481736758471138718778336553655678374617640076187623705748317870051465306308631471164143125864382210850207037600801483176770823170512204183673005287714683025272251861111883335402830333124682817107801561558206108211583307868462172333836188447073517304086124212046766573468260178581350370628407538556485260427522413086381780024171423115611318634706688173315285184218216530827364657525801602715121163523751110241061654623125368751825650235250504687050676307022630474870177551460272562683173561881600018327858345460086545888832362730652277030632381537043054430486562858656784006651831205857461151350742124275134228231555266425448144823577652200562843884080828074164108067807813048034752063108461004688565567130111503260414200662701827228631380277228312536583180231613518706187317673565216727460305500638601142676751668444553816121742080426160705368816025138664265303251756273518518730862720233072246811417507756553878850845757381845611611422648644164086485286238466162363344057001121677343220818506083371862137010661622364338330831553574200538183745361417458005568372756687548621686745287630528168882410633428605048633053118632852608812837104176254134662751162608810027054020624335538722216288583065164064022144016266843214800315064071387443667213588713004105783804025667840388024407076618450445474568131706508618522810713016468684712241576080034862203542207230705607763336537074655487503315215184658500108525582024400658005247070468306680407777644277626555608647187201348840567607555587763581721687238845086303878721607273784881465433510511023765272770875070743787323471685410337833852203753384551444805788008435488871070137354718580371634437430075140476153835584426742701702300124680652654464582223832650777543526458673251282420373030035772844807176263355c300aa552835b4adb640a708d6c7fdcf8276730c8d30cb56df2cdf1fcee402cbcac2db33776f7f917458b10a470c1857d61131fb46e412a18569d4b8bf289e72bdbaf3eebbdb5fa6586c2b06ee55c39b2bc31db5dcf959366eabe602be533c08ae39d64ce46396bb1e4a8be9ca49afeb48a69e0084b4aa124ed85548ec4e1a992126bad1b391b49b3c711623e17544ec5afa38009bc99696dc6c1a749754adce3573aefa80f8a8586274159a2ac3119b4a8ac94d3766fe22f6eae181c619ec2fd487fe71505e6abbd6424f760b085d44ba33ff9d1a4f4f3de4cc1aba85b44ba77bb5545e9d652e264899e52d91a6fd02fbea09f7eceaf4837d74c8048c18bcfe4e1e0b9800d5c9ae5bd36ecf89ce860fcfcb0ee2f53feb79b1befc511e08fef900088763b959c7f497356c89a23436a98f70404c2d8dbe04c6fe0f82f781fd2e86c20464720363d4b84ecb44c5c282f665f28e0255fe98f260f711619c4663978dd9aa860b768056951ba1187a2c89436b89a161f14d693a230a5b6a65e10d8976f08b30bba4c59969a571216a470a04ef29a19b28b346093349e9a1e1836e1a9c911db91e73636592af1def9a5d6ec2a1b92683eaec682a4746cbbf8c6d5f72d724c41787cb5fe344fa20bdae6c890df2427d52f7bf6bac0234a763053727d24f580c68e890fd0157cc671f686a3d119996b3d3dc93ae2174c4c0883d2fa3edfaaa510b649db5b7d4a927f71d577f45dceca495f031898eada50604d9e7858ef6ebabb6f6249ec499194b5943488b010bda13ae262cd13f587c8ec42eba297e0f76ebf1be24f727071ddae5e32234742343fe63dd4cf59ab948a32beafb14335cb6d0eb60618ba5dac68c83639200408d90f5238ed455ead4851b71f21b7b9eac2d2e63b54ffd813c7366656100e3ab0f7f2491e3abbcaf07fafcb145e5ec677608a3a3c02cbc5e33d9bfc833ddb53d4da04fc3bd9b518b9c604a93d87a7535473f44c050bc73ebc62ba042c47d9c384b3de5e043181246f9bf792c385201173a5c759d18f138e3535e42f540f50c42664992425f57212bfb294d102a1a4094feabc90b27bab69ebb26ce4f49999cc217b7bec571b8c8b4aed446ea4ea105a68e48b9b73e4213c9f7355424fb40f78ee68901947fabe7e8c8be7ac7cf15eb7f6c93d424f2695b272641f83f028c8e13e0f9f2708d319554491fde76759b444681a6bc006a5bbf1bf9f115a37fd99e7686cdfa1312f9f22e915fe65501ba51df73e403e12baa7093088c27adb9da489ae95aec3ecabe59da3fc9036a801fdebf5ed75ab072e6ce1c4ba60bce26a3a4bbb204a22e1114883fc02471931b9aa472ba85731d3218255569f3f3938cacc9a0a9c86130bfc6c50a8574aba9dbc0f1423ff1c195dae72fbc1d2b43eb8bf59033ca66ea7de3968e1e21c3f1e8123a8e9696b2512693e5a2a29346ebff481192f268497b5133854f906114abb48efef96fc4d3d085236dcf5182287aaca94dd75e8ca0d1cc27fd25f7f7c238e8ef0c76d9bce030369e03af39b667a87044493c28a5e66ce15df046e920763e2c892b92216a563e82aaa93410c69cf06b32d76ae9c5c8be300c02fec3c7f4c578a7d74861e4d088670d71de16e56b0e2fd10c6449e877902dd324754e831472ff2559653f1a4a3d00cbef4c3c9d78d93fb121a69f3e1a0d569ef3a339c9f22e2fc10db1fe26e009016a7af39600f4524fadc422689de41fecae27ba755f39974acf21532f94b47cdab45b42ae49e89e80be15287d8f63e8b5cf075055209743c7e848cd1cdc0c24b913768ee317704601a258f31c46a8b20c1740e4f3b2b672b4c5771ae8218c8ec253a1644d1f36549aececb79fb169b31aa0c941da99c26dc4b6e3310ab69fed8358576332c82f3276118b23b609437242ae6b4f0897f9007a661167662b7bc381df4bf1bbc0f2df58f854ffb42d9735003a4fe0380e479e3f9ac63be1daee8adc35326206dd158e8c574f3292207fe4ae5d0500b7ef5a8d15686d2111a040a010691a623e4734d3ea7c2f813a897e81d1d26bb40a4b19e896294bb47602cb0cf1acdb97892ef3aac21b35c5c7cc111a437783550388aa97537a44e700eecb4d5a090c929a785ab5c1318e731c93378ef929e153c6f5ab343da506188480e502bbd2dbe9053df466d011e7c8a29a19eeb71e947286ed418618a6fcdfe157b4dcf86e96c665dc7714f68f0c61c88715f9826b85cefa4788aedf6489dfe53e26db0dcc35521ec218940935e9d02214962ba9c826a136e8043c2e4287eafb348f427ff5fc56f3b0370e5e2d0384f195398e88cbd3817479750b1aba1bd61199623623392d19e21a2edd0887766183567e087889e546971429180f0564a91e4259306a73baa9f12e142c4107c167293ae7bdbc13dc82b698d729bc9816b266edc814cb4f7e844b30e4fb6f5424202977a7220f11e8065c872e63a2545bb12d109f162c8dbb4ab9963fcced90b1735a4e2de740968a6f9b2ef93f9166a94809e9abd21d79437821766afa021909d075741f76c6412a7af8f05d03bb28a30064eb6935838bfc848046b214f43f17bcca2290a8e769f51979bb7c2c9ec7d5fd960a0222194e147164ba3e0552c4c225d31aa053b3c5d3927910769d40c26c300c8ae8b133266d2d9a4ff8a2141fc77863e3130e755c156a1c672475f4b091f956307525357a7f894950c8deb0fdb5c6700c2c6558ae00d29aaf17daee47be70be6a2206d39b04d49fd2b27e9e3b95ea995a2c721ea172d3ebf3ddde306942a030a5acb5b25b4ecf0f9f42d172a7863a12df9ab3015b5a7bd4b370662285a55690f05fdf3d66f7f924df032cbec839c0142917b4321cc8546a6ca0f32e983a102968c2fd2bfc150d1e7a2a61b8f6584beee3617e2a287f26293687596ca6378d7cbc19b45855eb8cdf16985c0eea06acf12a3080918748659fdee069f88310275f606f5232b5b41471aaa6e59cb2e534ddc4839cae92291dedc946a16ed408ab5cb607264b8e789d7e0cc8b693a148e0fd3c22811d8474247bb90c6f70f706cc58213d5d56b875903f7ad767ee3d0193421e69d88b6be7da34736fb36fd53b9566ebe0394b458a1780d1f20b0c155de48e58afa27fc211526d2f4ecf4f1f0165488cc3ecdf15c102c9eb7a22cdcf062c41664302deae6a3c48a6e1a1faa659dfabf0539c47c9245fcc4f8f356d325a36aaaa401486ee1a375725064423a5d9114c35b5e753cb8f6162bcf3fd071f26cef612017f5648fa0764faa4b805724e798b3285a6a93d8226de734cdc63602089f84fbf2f09bd8fc3c23d1e57573b0da75fcfbfd0101a7921d6d6eea998c6659444c0c5ad15460906b653adf7ee831206375dfa8611c4ea5a0c429253bc6cee49f69ceeb4ee700fad3e43cfe04177a4838ff2e4ffed9484a4c949a85268645f2494c01ce621e39c3ee9d168d76e3dc596fabe4a4067494b9ef6308b74cd7c578da7bae4bf8ccf566c2997b583a1266d8ca9"""), TestUtils.hexDecode(""" DA2755DCE32D07B6D2C2DAD6BBF7CF5D4C26FF0C9B6FB9E064B51829A1ED51A712E26DF8047B487FF0755CBBA8FFB60DAC3C45E238608F48205A582BADF82C2E7E83D672057B9A9209386D2AB8D93BBDE0C522CD1BCF2AE95573749E0D51B85EA01494E3BD97D3CE0A61B26249E4BB94F9667D6556CC4313669409D94AA4F3BB9AB70F736D34245E2A789A5FE2917D5F4CBE43010C5215AF880118E1F5FD47A4C195F3C74307523C688AB76B7CCB157F75FFD79149B5508E7E527ABF718CE8E2E4162BF810F35E234F8CB65DE0930202C1896DDDE02BBBEC8D03BAA12AA1C91EE798FF7ECED608E3DDB7BD04A1DD9139F4A5613AABCF7AE495F9CE18D73BDA0C91583B72CCF6A722C319AD5B1051E65C1B91DD05AE5A77220BCC7576F9CBFC8A12CD55883AADCAD1AA109522F286B00B70C8E3D4C6EDDAE7E1752097C85233583BA0E1C05C5624FF65A3F3894158982B633EC92C24382AF48EB2DF5EAD30759E99D67B8BB1144939F4080DF0E1689AC0D4CDC73DF1CC2FB72B92D5A69019087294D5F2DB196CF82B7BBAF953F0568663596F78B5A309738BB294F7AA3FC5F3ED5BFD4768CCF3304C836B476458E14B233C156C8407636FDB3EBECF49B97C96C31F51353B79C378C6F47F1913E5B14A82DEB126D688133F9139C12C45BA24CC9C7E2C16A26329D463ECF59746F5A99C6B03896E851815EF36F499654E2764BB8BC60EBC821C4D0B4C363EEB7849332A9F1053A975B092AA3AAE33F06F760BA1D76DE07A1F48ADBEADFF1E17C34F9D69E409DC5AC83C296C402E042FDBFB0B6B4E023B15B318337B6A1CE69F1CD3D93FDD0FEB7AE259A41383939253C317DB949E3BEB9C8F7A79D083BFB46C50AC00D382C846B78FAAA7399ECB902CE8B73A1E89374B1DA65B0723C67B24899342DF13C07A0BFE3565CBEA5892F8979E404BA84847AF30BFC04D8EC77B1C5B9400CB97622E6D3360836639670BDDF4E9CF9FE3D6B98A5FDA42422DAD6C829B9E33F53686E2663D232162D3A78A7202EEFBFA4917BB8E89375279C96C9054C2570DC3D90DCCF0E418B69E6443C1B2540BAEBE022ED9A9620C030377C67FF4C186A59459DE7DB1ADFE2923C01D9B8D3AC940486052DB67EB67A257BE7AEE0D3C77BBFFD0FC7C94540F11DD96C5100463C27D65D3BB6B7D867590D573D1C1BEDCC0E8D122FE4FB82F1404CCD061DD7C3D15287F39CBCD2448DEFE1FB4ABA858DCE13F74414E1A8C41B730A1DFB45B859545811C2A9DA01C342A1F3C8B916F60B5E4802BE672C2BE31531DD9E7014E681A8AB1240B5E3D5C0D26E7040D4CE05F9017A32E1C760F466A8D7A68FAAD421B2E2D886BF0007858129DA2F6B92C4CACBC1786291D7C95A3F6A12483B750FAAF1DA03059F89C761641C0AAB21A05E78E1131B8F45C60BB5E8681086717B918BD4FBCFCA1BB5DDD740BE289D8DB1C24FE083B3DCF0E496B1941ECB7D51182F9CB9986CF3F04F0CA4E01C63EC879FD4A3D5619EA1085B1431FFC019286ACDF3B4AAB03D6265A7B18F24CC2815269681BD37263B44DCCA5CF6FAC2ABB1DE317118219A73095D1BDA10B66B6B55421F049B71E759DBE6154F1DB98A7E3FC877FA90217A242B21F39490F2116A2BE8067168F26439C8D1928255B5A50CE1ACCC222087536BC37806FFABA03B7E787B04C2C67C1B0BEAA871F39D3DAC2221AF44CC7089E520BADCFD840E5EE24AC53FCFF1E7D6AC26694CBC15B80E48B10C054E8DEB00AE387CEC9972A28448A6BE3A01D5EEA837703D2FCD1EB2521D444F900846F59074D715AEAA2F46E956365B7E67C5528841145C442E6FD7B3D7171BE05BF8BAA415260F645E2FBC93C46B9F94D2997929349B88C2FB1AC6743B73DE66B30B44E5DB3E07E0FE9713D9D7575EE4E40327A58DCEFBA0EE95E22D06FDFB720993EB134073A80A4F06F8303C7758DD37CD7236E5D80AAE2E9569834846E7F6C75051302486B2564A1D8D987D1A3648192A63EEF4C2D25AD41FAA02C9F227CC9F655A72CF7207ABBC66F9C822EEBDC89833757013776C11C310A22C226ECD33E5B0772AE2DE8B8E9A876650D4A57B863BCC6197261D7D06903D414AF0922312B7DE6D9E64F99509CAAB8D808DFC5F046BA2CE55817512535EDC2477D8462A1817E45D33B9D7390A11E30C3860CBE2C4B519812ABA3AF7050227759DF3B6FCD6D3EE5C60C1042DFCDD7880888A147AC47A282EC51D0DF664451E37D7C40672A27B965CDB805CECD3EEAE38A0AF4C2349FF39947659686D30B9ECBDADD80C9B06293FC4BD5E7A0E1E9E883D7A4EB05102CC1FE45F1C9BE23043BB458E6B8B6C1C187761004EEF59E398B1124B98B0EC0F7B29394418B38D8A3003ACB85D96CFA0C3C63B2ACFDC2BF5540D029A261243E06393253B2C3FE253A220DC7AE4BDE0AB4B386DECA15FA2A05465740B072FBB0C8E81663E320AE931A2DC7A627C805AD80819B9D12EC271D9D16736156195302C93490B4F85E8B4F5199CAF233974079A7AD590374C4E5589D0FC26F70FF2CE51FFB3E6742AD5BD9840F62F745C42D6085E46182FF73FD079BD2625338105FB39110B660F8C55D0830587671CC802AFF63FA7FCFB3BDF6D65B362CA0B68B31FB802E7870C3905B04B41440F549583EC87218DF6A0BE0E209807AF053CA121D704DC0C90A499D1742658BB096C776514C89F6B2D3FC7FBC4A38C10DDBD3C08F64AB076C9BA4C7BF24EBDCE9C82B1BCB8E55C4135976C878B95B6ED108C2031F4E53DBB19205A7109C50289C743818B90ACACFDEF20EE33F5C9A7142B5640F4D875122E0E5"""), TestUtils.hexDecode(""" -583E9A28CB7C3FD65D84170B159188C12E7E77E0F39C678C2ADF349676BC5A4336041A2AF283D3A0F61BCEED4255E2A04749CABAE6811FC2471148869D81C708E4B56FFC353196CBE05205F737C91C80DB8FCA7C243DED5BC6113AFFA87E14E0DD0D3E7A70B2EECB847762F5521D372C51317C95B6EEA2785B552D9AB045E48C03321DD041053C328A0081D86323CB37683CBBCB3A68A2F850E5C7A4826E88B1AD51D6C1677DC2B081DDECC66A01D3D3CFE26531B4EF89528735A8CE75D4B710C0F3FF05FAC74C99585695BCAA1D1FEA42D6D5EF176B90649FA92D1F089FBB63882AB9CD539C88028B380E610421D3C09314AF44F6BAD1129107AD1B84624AEDA7F3BF3A7698C478EF5DD2639D9555E53F60F327CC66143438C589285006552FE249B3DE8F4768B9774591672541385018FB6683CF04C85CECA1A9FDB4F44EF31AD9B78B70296CACBB35A600C486202BB771C75E83E1A0429A31ABFB75558ACCF835FCB68FBA01F5B766F3BF18C23B3DDE511087E8AAE570979BBF17C8C1FD69953823B4FEC56EAC6AE11FC4292A40BA01717F3A6CD108BF94520955F978354D78347ECD4A0222D89D1D7D93ADAF7679AE101106AC49791B3D17B6391B85E55AD4A12ABBFAFCF1D50667B37E49CA69D3CE3AA6692F85420B246355ACB51848AD2EB94CBEEF5E32D455FCF42FE73562B5B149CCF01236BCBFAF656E85C1D9775217E51D4F650FED78D8BBF2B47C67BE41F69AB2C2B1904E86506A371602A8B84A50BA179781215C0B061522EA66AA7CCA390055D0A461805CAC87ED7AAD205777344B7573D76690B5B46AEC4665E36A9173D7732F5E67FA166BDDCD56685EA1A41D440E469B7B65D7869744B1776DCEA504B03F6057F9A2D916BBBE6A5032356F4C3D48A495455381292C52E78F8478A56FF0EE7B94B83F1EE690F7173729DED18DD712BDCE3CBD887771B1D87EE2946F1ABE293F3D7A7ED224F6969D31D2E1F71F4D45607D7EF59AD25A40B4A43EC95FF0C8691D4C41E97832F345CB50890865AE483A163966F5B45291556826DD061C30C8CEB552EF8BC2E987BF6C8F629370A72941893F549864389CBBDC3D38D9FE7AFF8682EA318BDE62A2D11E543051A88B01547728E30CE25784251B73B771EA65259E90C4A859828A65A87FECEAE332B9F51A986CABF15B622AFBFAA04C19678DD200BC0B338C29B65CB121B70DE6EF964360F2D54C4D34BF7270212452BECC9EFB2E225A6007B35C000D276D34AD19A966D49D98E140DEBE503215D716B243CC9387CE52DC10C5B40BC765C2E4D3CBCF8E1617A1F0133DF0C98D0AF71E18DB6362A6E4EA9E454E1D6D986D1DC50AA580DC7DD131E66EB543833FC42A575A84B652E63164BC3FF383040E6EFF2B7550C2AA0905FC7BB4258176585544DA49F48A844A13052B06676568244CC66660021FE78053CD4ED1118C05E517107F614294B97CD4ED6685D2FB44B8B01E538874186E6F8D27D1F8829243016B1D505D42204FDADD54BD985BD647EB79A1BAC18086FA8A3568343F58A8D46A6A35C28DF1575CCF1700160EDBAC0C66A406A26DE724E1CAD5AD52554CDE52EC6B5063918C4A137D758C08272E4C2ABD41B7EACA4C44A3A7CE60F8628F3B13CFABF50F16D02B375A7FAD7460C53A8008BE19D982E9794B060CAAB1AE6FDA80320EAB2E02708063F4721DBBD8B9FF951BB6129139E90E7C1754D4682D029DBFF5FA9E713330AFBD9DC2FD1148BB388F4F857B4E4C63FB107386DBCA20AE196CBAA995F522D6BA4D2645F724269CA1A5AD24D4F56804FDD9A305B30C46901B484CE8D23166A5036ED775CD192BD47D9AB6612CB6D9181C1472A1F11E02E7C82470E8C685E92F21996663B18F8738469D61D98336D7C53ED2670A8DC26C21BF0BB105F5C905D2AD7432681AE8EFE5D868ED0BE906474CDDE2BE7BF5B617463EF59BE4A210C3D5682AD4DE5C059F1136D2C455BE02AA1E276F135C5001388600FF2F6BC6DA8AD0B72D1F5301DA9A8410FDC410B54AD0BB2561B01D646214C867726D82D3919B4C76600DC065C5933F8C7D3C916C374A06D7F062889CECA4D0A98FE843F8BE1E724D88F6B6E8E066D7B660B0FEE10CE8E36C4E60269CFC3745AA960C8BD9F7AF8788C4CEA7C4BAD51A202162CED055B6B60F8CAF85ACE6F60851250B1BA0ABCF9DA2C7EA2BF074EAD9BF81D73ABEA3966D63D1E60809050B7249B7969AE420E40387C36C4757AEC7CB328466D118E3794903C33F230114AF1C0AEE0112197DF6624123146FB3CD30F6020378040A8546E20767B8537812D0941836A0651AC90E084ED6673BCBBF18348D0E4E52FAF06FD1A42DBB1EACA550553595A388BF27735E85FC4965E61CE82E96430F40EA3B35B874CBAAE2612A714BCE0DDCE94FB0F4D93DBD7F6B03C7099956710E5EFC5C996F8A7CFAD679B496044F5204056D594DE05B61CC143F834BDD5D8B9F89557FCC09702848EF9A391CC4C3F07F1CFAD203B172CD1F44E4EF08C35631DE23B8E0CEA4C4848663FDEA9C9ED8B97B5C7F9E94AF6A90E5079E40A791F1262BDBA96BFABDC30643E2C3159919EE5288FC75703FD0D03DAB0C36D0CF06F0450A5E6D710764085D0BEC8B26FEEA7E5C2665C7F514AEB5430F9C307E7D03B30401646A0D93561FADA21975D8BC4EE1F20329FFB4625B3A484CA08DA09C61B45E2BA9C88C29B14E9B650869EAFFDB7EA3697F4DCE2A72752B2459601E044B52F0DE99BBA5510128944C00357845F374D60E373CB35FC2868DB5B948EBF9BDD3C66C1740F00711965AD9549347CCB3B5221301159472AC8CE0B3186269FD1CE5CD0DD456222F10264B117BA250B391C840E51D8680BB622769ED264148649D3B954839AAB5B27546B8BB58A20BB52FC8772FACC04101148C99DE07B96BFE58CF2F04DD5541CA9D24873557902F0BADE63229CB8658E8E5F815719A73F29F81208D0EA8985BF2DD770177C4FA88CBABBD0C9181C0DDEF7CBCA5A6EF12367882621E64ED026A859C60D0B8690924EBBDE0C0E3562E10B63520D8C801A6814CB1AF9F03C3907FD9A7AB8567FDDBA869D7200E9284933A414FE681F04A45BC3D909267FE62FAE7A52F2F84D3C02A10AAD86A1C7A9686A2B7A81DEAE6A1289B7A0792BEB805A620A38F7610D9C3AD1CDE838DBED11A760F42A271020761BC41522EF370726A4683DB705C7CDB858AA8A8036DF1328AFAA0A4B31839DB7518164B11E6EFC15755D1E0D477EC004F5593CF7F862AD24295569E3D5095B8B0F1AD427C1CE7039DB9D881D5E6AA570144255939C22AE7EF4BBF9CE36FDEFE30E64ED373AAE944907F5BD02B70312F7150CDF487099468B19B94703358505F7A5DC9317B9B17C44685E5D609A0F5156A1D4EE517BB681CF5657AAC2A1A678687E9995F089CAD494A6C039774FE62AAD3D2BEDEF62681AD24884D1630909293B54C68D7CEBEE284EF9E70049748558DE03DA23B478566B42B8EB327DD8BDD473130F1D967BC0F6E4501DC64836EB877BA0AEBD241432C503E41DEC7B264E08006C006FCA366EAA277CC9F5FA6155C9E48E852B718A071082FEC580B4AA599CA7708AB4C1995B6DD0679264D8372B5CD0EDE9E40B6CC0C3DB14D00B2C7D2E9433F08C23ACB77F991A454A3D1D71379D08640FA5074EB5364A531587907607FACD9AD9036C8AF221650F01308F53B8D0E432E5529F435F40A40E66A5483115FF438107F88FE5F1D541C500F8B12C9DE69CD5B14C3FCC5B462153F9DD49974C34EB1C5604606E56C746BBA8D90E3DC4556DBC3BBC656A54E08ABD3FE1C39F24E99D3D022828F59B80C4DEC6EC1CFFAC05E388D3F62510AFABA69C5E3EDC898CC8BB842F3886A88AED03739C85DA459E8329D1AE249E26EB60BDD2EE30191099C96C397D88FAE9922C72A275BEC1C7734CAC893D906E976FC7C0AC8A090986EB4F5FD7E94F8B2694AFB4170CAD4F1896092A7F6EE01C300DA97538FD5FBBC6EC28D158D3AF40D3598753883156B0DF2143131C2751F2B26DB6FAE76773E55AED9D115E7FA60267DEDDA65F41CAC5FCB0CA296EAD1EC688C742DDDEC5292EBCD47B0570ABBDC2CB6EA301E58778E1C3352E393598470D2FD2C45BC3A611343ECFE61AD64E71033B6B7C053DC52AB1CB246682750E330560F15B3B2D83E63F33BF4EAF608393C1F5811B0D12244184F20EC0682D236F583CCA8C8D332318AFBC50C03873D68AC44CAE4C2826E966E35EDEEDF4B232DC4B3BA87F3478FADD0D8EE55B408AB929DDC85FAEC0AB503C2F8192DF7B719594C7706B98C593C598543565C27BD8A0A0CA7E802B86214889D8A08337C65BA31BA08BEF281FB69DED0B30AC13274E1D98FE3F2CADF6B6FF28334B338984516877D3070F379991A078E1D0D25CED600D2C52CC335711826066976251DD11AD21B1C852E05F3D9EB0D37E95F767108AD378770DFF10854754BDE53F8CDC14F6A48C66463053F8DE46B722EEFC6F2BC2495CB107F3ADB39BDB2AF497FA6AA2CCB4F9801964FC6B88C9656D76C0FBD9A436D1AB57D763A8B814D2957E6344312AC137B3B6FA74AAEA860186C02156CAFBD455E8B999AB52B70DD05112E5C94DF3352AAB3E2071C343F656E959FDB000000000000000000000000000000000000000000050B0E141922""") +1fb3b6053f9518cc51b4a20cb33d02a7abcf1cad4ae7806efe9fbf8652e3755275a641f27879f163a1b265e886a1b21b129d48807bc4933df0cfee53f26305170c547145f3ff67fc6f317c5ffcd94f96fcc4453ac3fce38cbe41b6dc01c2146ea3d1e7a0bf001be3136362d75aa2785efafce667640dafb1b39d555a106b8cea129c5432867e0eaa493c43d21ab388aff1b6037621c1f134adab6093ee7e5760e9f33a0d8e8c63cd70c86438d3f94461a2d4bc9f41243e362bdfb4c809fb28157a6e5ab2f5c6e16a7336cdc4183ac4272920485fe34fe03057ae7b1440aaf99f28ba89ef1b0021cd863ba36e8deea60aa14cc7f2dab46dc401f12f5b61fb82a195781e337c195160fc474e52aecf4c6ff277908c481d51adac39219b29fa7ac703027354491b869e3ec404b4c35b214196822828079ec85ed0edefa0ed2a426ab9bf4c3784238390e8eec61cf7fa1c4a1ea1308e0815202f1109250fdcf69309ef634c4f0b134ad6d33ccb4a5e30c0472bd292c42de895de1c5989922bba6004283fd1376a0a263ebf74e414da5c058ed9788a862408de4de14b54d2adc7fb5e36f827f53b779e549698c8ae7fe4eccbca4b41b81e7239114720147851f0a72cd3183e33c6e82c557a5eecd4d07a824c6ea653168bdaac37a444fb63b29cbc35bdba265c5718421dc104206d224ef985992786180627df4b2f3ec5e6c200c2e0cbb6fad82db3f54d67f5fa7a9d1396c3b8376b3d83af731fbe8eed49bcd99e4fb693c87e259f20f61a6d67c8d87c967d65d03fe81e5d5f14021f8deb4d1a5d25902065e4ef707205a8159f02b4469be4c2094aa73580572a3568481f63e470bc86cfdf7b809c17801918f2a6f742892aaf696e2cbd2bc617f92efc482dc6bf8640a91582e988112cdb6161a41ab879e8c3c15e48bc2a7dd6b4fd25b5e7efd7388e6f3959bbafe518db3b73df504a6f6cbc6086ff160b3e7391845c9797a494000a23a9488008a595334b7b92db4b2f9a267869ee63b8d3b83bce7d57b9018bbc858943f0c7e8fe0c94cd0718672e4473692a2809423b2df248b2e61dea545b2f1db86b7246a345ec591083f4662b64664bc9200c3ae8ce7006cd795cc146aac8315129d62eb20e940aac6430165476742a19c17d906c3fd94a543b453a2f5d3c880ae6a1f64125efef20d7a0091e4bd66801fab9f7a396c84c4ed28526fc1b0042d4245d3f57731d56165e26e1ee72976cdc40b3574801255709cadd4361e7984527e6b9168a8f1b507b1a3f94d20b76bd4a0fd5ec81274207df86ef1b18c09e4f77d0670534a6ac9eaf076052d6d037ec469ab453404749c3c15cceef412a87301cd438c1e5c8d016a2c125a296c4deb4a12b4bf04d9593bd9d66814dff60549ec0a91acc5bb00a2f445c7989af4d3ba9d35868f7fd8a3687495f2580780f8a4c3e9f012f0cd07cfdd7e513c9a84bbf7dffdbe2934480ad3cb241a155248e9c30ba5f5d1574d73488beb96ae47913ef87530dbc9c941bcadc6a69b9acb06be7ceffd8cc7745a4fcf978c1fa126a22864e912e9c14fa73914ab1b9ff31988e6c859bf069bd1f912766680111d9996ce8565704046ceb64610f0c6162f74de87be26889ba868eaa8e3fd8c1c4eac20deba9467f4fe5427c06192a5ef0e84d2a063532131a366ba13b48a3735b7ac98d5d800f6ec7cb5b8bd604f7d3c72dc56e126ae14cb101afc3f5832fed4e94e5e7614e1232e970597997cfb3b9e6c5bba771552c38c9d6729ba0ffc2bd146754a3605c64718e9744e4f7c1ea184c477de17208f7baa9ba1913598889ac44b1d30f5b81aaa06a42c8f31c889737a8d15e6d473e0eb16fcb57a56f2fa9169a56a4d5b687b50e77bff964522f14530608fcb7f405cb5faf36ff235869b99b08765fbc6e21c91833a5c5e6e85aaac997fee4e800dab3c8fd5b35e1cd639931690f656f05b325ed80bccff2013c683b0419b5f43c3c14c245e40f537b55d20165a92e7b6bf8af9c81cb4b205f327b946c39a0ff087915b015c77930f221bb6c2c8d6500a521ea549f2d7fdb4108aed7a5aa6217450e238f1727535b3635f7e1b15b583743ffc9a2436e99c8f6e2a46bce90434f345090a76c422d778ebd3d9f4364af2c89d1353d64ec72d691d414f56c7a1747c7ea3ee8b284d3aa6612fcd30a08eb7eafc3dd42f221200fd0b394c99235ecebac79fe467c747b3ed5c09ebbbee5dc240287cceefe186f0a5b5f4fbddb0675f0159c750d715d0b01978cdd4e85ba77cae57024c6e6348155071016a96575e5f9b227c87e82db0a8470124b6572da0cbf2cab372d85708adadb04165b6cbe6950253e2c1034537ade941ab6633c1ee634371764ded5c131cd57eb9d3a794a2d26750d01498214ec9b78ba4c9400cbf7b910643a6ee5fb12fe1f2cb348d566e63dba6c1fddca6a0a6644eb7187a53d0b5d8bee99d31b92981fd81cad326a8c107abafb623a0d11e861177a58f1e3307fde29d63a3924bbeb0e946bf7f667599b92d98ab6af9d896e2ede95ca65cdc98b07456bdd037aafdc4c91bd387204ba7ea14dfe387430d290ada9a8296198e89b746f0264ef95c45ef3748bb9806f24a61565624fa84326594a572c701602c7317fdfa1990426ef70a5d3434e7b1ffd779e13b23bea25d63dbd7d9fcb713bca6c203d1b2f337a6e768ff8d5a1b1fed4d69f973f0e0a59f3c3527c30a1942054d3cfd04443d4611259b63c14f8eff56d17465e29a824afe408168acb215b5bb0252bb7c705280cc003311303373f30074bfa769676ec7a48df2d9f68fdb043b035fc1807fe7457e01e794a5130a857c56e92a8dc234f03c5c7fddf0f385f63b4ee438a2ed5a027af36eadab17dbd7eb9eb541e6ed5af00e1415622b083855f23d1c4639dc7c5b95c71673a2580e88092e446c29236900f685219aabdd06720f0e50dfca6bdf53c09ab3477833bb835304ffc65f1d6513acee999682bb70665806deb596566ac785afebd6ae7227ea882941257ebb10809923ae562cb34be2acde2b8b0de3f2a8b81c53d47a80a3b1d360c9cce2b484cc5dc62b948a6f990aec5d9c34b745943ba361e14de27232dadf5c72ad2f47e24d0872b2517843f3c43d1f348fdcb5fb589c4b304ddacd5451771ab0c53c03a33dcfd13e2720ddbca5fcd3f112eb81ad6bc1aa059e2261d7cfeab30fccb952a0254d92ab6c884ebe18c878adeee97721267393bfc85a5a4ebb7327c6f69a71a864e8fed0665b0ef302f16ca3d6ae033bbdb9443bc40c78eb7b3c5af66ba91ecd852e4682ae25575cd7d09adb3b74798d14bffca4f5bd837e80afbd77510ee78c32ee219f4156076dc6bc9ce87971e232aa4d034366a3e079e21cd17ce42c3f60f47225ec2407147bfe01eace5552956e6697a0a64eaa3b02ced7a39d1a1c2eefee96c2f8bd2c122ddb0960929e57247fa3a85fca43f63de635ad5d4fad02565aeb7f00db0c55c5552fcbbe5889b6495c59541a77a8dd20503cdf916b3bfc8f5e87b217134f2fc7a6cd13a736059348b3106bc431d929c09d4d6c0e39a93759953ed35f1df0ee90366e73cf0ddaa03bd39293e95929cefe9cfd06079b592b42c6e9f47ad6c4263233123092155047ee7c48e3e4e62f531d3810011a76f477a8650bbd7be790606775e1f932dba57e5d4bb2b2401a01a20b83b69ed97bf1ad8c765c93d8d4e1bdce3a524eebd6e54734d568711804d4da19fc69997129876d235fe53c78408e78081da0edb8d9c085c863c6603c06b8eec7733dd5713d79830b8debcf6d3e9183852502fc9bce62e85c20cc098cfce099d0a810df722d67932c2e3fbaef6efabbb67a83afd4cf9514598f316b72551abff34d1d13c93dc679bb58868148fbd33628d8279fee785dcc605073a000473e8ea9dd6646242ca2dc3c4863de1d0f8ad955682a9ba9fe52317c2e5d130892d5b6dbc41bd0ff3148308393d717ac0e96fc1f45e0539bb55eb50549e508da7db93d68f1711342a9d6ab64e178f55cd6eed8e8c28a497336fdee128df52ec475e46cefe3651ab9935ade5adf0b29ba5358d35d3b6516c8d3996aff1e2cd06363de48eab1bd00120a0d407b092870c2e76b276c70d4d7ac85366f60f2343241200253f92de66b037fae4fdeb1db275b7ae6ec196902ac69e9783fa6684584dc9067c7cd4a68405e0aeb2a4eddca1959cf788c0a516eb94f0824120ea24b9fa2354028afedbafff79917820d4d15b12def7f9efe49899c715c7b500f70980a8c799b93db838ca2859a06cdbdd5f84ced9987e1dbbf74ecf24d5f2484950dcd57347da8b8aece55d4afc7adcb0b232082157b0bbd455ca7ebcd0ebf257b184b3eb0d1ef736dc7d02681624622947c4f31f0dec5b430616a19b1300427495088898be15f27cbc4688ad4a93fa208ea20bed26e94984525db33a34b7631018e55d1b8ec54dc75c85e0c9a95c4f212092801e1578ea2e1a8a7850952a1bbd2642d7328a558c0fba8c167eb38d105d31be1cc497460fdc3973b7f004f1aa58fab493d29501e09568b3fdd7b1c8447cf154bf57356fca7c412c79417dc20e2d34485e6c757aacb1d7ec1c6d7bd97374b2c2d0132f6e749fa2b7eaf3ff2b385c6df71c232458babc000000000000000000000000000c10151f242a""") ), new SigGenTestCase( TestUtils.hexDecode(""" -7D9BACA9C8D5E302BF5CE4C85B7685388CECD82D72EC259976F4CB65C360D74B7AA8B23CA3C9D786FA3D949A9DFC1600C821B808F0BEB38F815D7688928159D7D9E9C1F80FBEAEB0718B4A27E5AE16AF325F2362539164D1B0F282131684089E9C61442C8C6EF03818E4FAB383498A91F1A6BA3D1138FA2E6863E7BFC37C768B80881102106834535885567854243344502211757522267523162088466534441253602763327188226627581385652565414151784380762722456634142628231458738808653824328765256787544665871806531822248171715644617852253306323676053473565268176586832213365052846420073311447520430470886788436502856868764754304758685773064126124086602270614670066264160503303628808800428371124331158623773024150040258466354242631322182837265206682145238541377758026231302173751556168744863422724538416543335044260014140700080223635662746130854042515087002685102861285410486525326637353184253282228015078475041117212844878141825033873150751831805782170351465068071671207478634401484255326350633185463351180560737581677164273148337620650506318728817625581311474587143474200631175767306836700454673165201446440552351405570370765020236227650155735776370575127458246010022264663462424423213765310260018843165528661703717074062347113507035301545373865105171508624854887346415101230182053334304844180245311205556878267210221681707671130563111227840346163445346756381740517462567744211002860288204613256541014522561605650738111510652486113003236284705828187520165420710141265210772323357340165116445210432428531411538578270768734622774714255868725625185866516828826288225225382481362346231732171642643803148671271817471106245053755183045102417242701340831385358686761031752488155811285174784301446783814603452746400881104301515340323411220606187382848113531273238682142164176684773160428640811770836021008816722262735542177425024011656734742220208177654327651838237731115676205078445837425763855715746545685101718301140056042410640767435220144420781045324711834710612775235483708256718366036056834856355047187872866251726612854101127341052403064311315244428128784365157205414785337848650728144772332137377841026231712784787072708207440534642352015738400562513805485583235012405755534737647887617687056613236528823413687622035830161327666432826703008462403420246788067276833355848330825352627051271045102466531806664112101702762667023185287441052104507353315241367611074381635451018347836601447556273501604602706013545264275427561702133764222721520838326555538771678808754764612652255384672763068833424642760475458348132214166041671261184323442617226644673580125123380608502007202213714484438825036152616448882228853238503436651346737426226137454116521806224384547167800842813436447366152212332813016632406320458758564571656076278257144143508780111883350040472187651326241722885506068843614384407717837823233334577603583138607157753607181603248844021525518610382536002436628707660830482135508327523234521413058137640267365080463880375267721714644672516818385618535542842438636753417412616738466876353522248666700120623351178721720464482820874272415685137628481655455861246778640761403677012083646508583110082074453101204426410178432288412156182720465184485112240375BF8365FEE3A6C811138E1CF73BF1D0EA525F2BDD4988CC157A976B949022FFBCA93B2664028F9D0ADE28005C84CA7CC39EBABEA9C92075734D9F83990353AF6D72693CBE38659C9305C804B8A75C8BB1C5FFB6C5A681155A2A65F85C8DD4A14C6B61C45D6D2BE9411C00A29DAFDCF3D9F1EC1E2EF75214043AC120DCA4F22AA7354AC2B6443FED11A086B22630C1B45B2A372FF2F1D0660C41087F5CF818FEC1FF96F18CD710FA09F66589010708CF8D299EEAC86E1E989C2DDD60A2F68DEDB62B0E6421D4DF285AA2A32F442E35688826E0A9EF9FC32C32F09A28419F37DE7747DF9C86B5A54A558D374FC1C083A46321E7237BF37491214F54973CE3BA8D7229370DFB27DC68F33EE68BBEE33DDB63B3AC4E4346D6D96A6A300F49ADAEF370C98AB1A44A4D5E98C1B19ED433AC13C5A099894CA3481A36820E5548A04C632B0995BA976A359DA6F029DE8443D7AB197037AAACFCF2F61D33B604DD3BB09B26523B103B0AAD0D2163F09294A48042E8D23599DF7095E009F393C4CF5F295C3F5E49F2AED1F29926653C48FCD8D93DC39422405C38EA9E28FF5ABBA4FB699D158DB7F70E30716DBC1627A27E6A93F594F6241869332D4F3CF41731B84C17DF195B7C7CA7E4563AC9EC1CDAB2D1E52E5C6D38B4C63C3901BD860C038A34284E71834247D1D3854AEF49E2BF6F67FFE4256869A41BD44B0FA2E0CFE0345EB3886BC4356AEE11A26838D4F2279AC13D6CAA53F110ACBB1F6764BBE47BF3C4E1F0B9B99B00B6B9E0C50053FB32174BE392321A3E0A69BDC874D3F3A42AEB79C4BAB2753713A5DECE419E2BDBCFCAC6CB741425A64CC7D3180E097B5285E0B7BCBF9B7D97DE81DF3227C2DDAA369C87BBF3F876AD8B81E9208C2EAE363C3A0434BAD92F49EE7B6B805BCA9CD6C0A2C3E21E5D5DD9AC4F427F62EFC96C13F6EE1EC761CAB24E61DD6F509D08E8E5AD4EDAEAEF0679340677882BCDFCB6928AE7C2052DE7116CDBBAC3551CE0DAD8AE909D795393CB8A6292C7FB2C16EE62B8B5F05CFD5553A7303919D563B7612E65EE69C97AE80D3E407A448C88D508191B98821F03F3823DA8793054FB0D051D9BD12D090E2CFCCA4DB20C6AD515E5E8658233C095781D5BB1D40BC47D3BDE5A6379CF03511B2A3C06A2C315730A0349F83512778A5123F7CA9FAFC44F73B1259090F8746F1AE868DF6D158636EED34B8FF85CE3C07F7378ED5A3E7577A6FAE7CD3EA0DE0EE3576C48008E2E4F8C417F3606BB1E9DF468E40FE74A3C69A672B758F1C3AC570E44E9A08936788B44A769B28DCABBD3266A82CDA0CB6D2014B73BEACB33801007C40BF92B647FAE6631648F7E91DA022993A9198153B7B3C31B487C863A639ED7AD4B235FF3D44E3AD573036902E3C41A53D34704237304D2E4D72A3F41DB6BEFCE9DA8945CF5A9AA2217A2B36DD2956C3F4C811B3D2A95E1FA88FF2ED95A0950CDB1A14DFC89ED6E996C854C1FF056A73D7BFD1E8F08EBA003E3E834C71598E42430B15BC0F1FFF6791D639BD40923A28FC4B72636AFF01EF4F01C4894BC78A3AC69BC595760BEE8A227DC88AD1E633401B4EA43BFB070ABA4DDE38FE0EE6BC4958F1E6481BF478A9AEA4EC2AE56993CFC33975C06B571450DA0026DE58B99B6D44F2AFEDE582920436230A6E81BF051BB54A41AE6E6C34BFAF1C7F03A44B85ACDDE1B44DEAAB8299905FB5AD961FF224C717E96DFEDEC50D5CEA646D2FFC5F7B6017EC540924D1C9FDB8013F2957F271C85027985FD4184F22E790F91CC7C44C1890AE83932483AF25FBC0A9C740BAE467E2CA24AA7E86C41A9250260B3A4F805D6421B8772691F172FB63939606D50D03F7C4AA09EBCC2E5289BF4B9EC64A1307869CB4EBAB5C0ABA222C86E21D6EF32B82B7409B10C67F7A7D54C850C277728C15230C56E3B0AA375440AC0B55DEFFAEDE52C2F84BA5FD49A5AADA5AF6C9EADC0E413006F4149081EA8B06A3590E55D55051AEE474E416C7C76F0C41C372B593A5A22CF9D520C59F98942B2870408FDBFA063FD14B6615EBDA85ACD3020382E696B84B4E6E6E28B1F6E279EA4C5AC3444E670F5B1F01ADC3331B4E13B1387A082251FE63E391E3AF0FFC8CD5A77D2B77DDC75066E04F9BA89B65E62F3F74B5EB53068449A3A59A3CB8351B5F8012FDC5B3F7ACB10AF933DD9FB5C094BF085FEF0B27D9B01AFDC95B3B96633C5082369F03BEFA13D53FFE31836D1E02ADEFFEC0CAA084050CD5CF34E1362D4BC422418536A4F5048639A0F168743459733CC11EE616D810DC92B266BCB0B78F32269BA68F264B669302E8FC2E35F998E2B0438EFA2FCA0B14F0B337701A4FD5057AE3F1105526EB726381C54D605D21E9A1887DA4F8AA09C3D4CD0E617BC072F4050E125763812D4621F1AD8001AA027546E472F8317E9F37C27BFD4380D4A5A8C77FB426C3F13E462E06B6D7C59C8DAE7EC747E4C08822569421C70EB62DB7C3F1EE9CAF7CE384ED0B58A122A2C0C669DC843CD21F63E01CEED8CF7C63918CC7CD04B80556561582A4CA24732956700D5AD7E65E1F7D770EC84C6A8B7F7737F4B597E305199C8DE6F73F3CEB730CBF6E87E53114D931024DCC1F3EFC56BAC8BCB374C92E2D687E735DA892726B2E7B30135D1CCDFFA0F81B8986A9E646B9D875487D960FE87360C625557CD5ED7FD45D18CFDA97B410CA62BAEEE3C90C9EC02525D74606EC7EC1169B250E8FF4B94DE08AA95150E52715C18DD6A03F2A399956F3308B8CE72A96D2F41E2CD901D4D507F336354AC24DA68CF8F83B69F12E54BAC40F9A7BCB1D1165E456DDE5C60F5BDA4F8C435550B492B14642A329C90732E6618CC73B5A32C71CF306BD89B074C8174912556C3FB05DBD4216B246239B096CB8928162E3544FC40EAF652CC91004686FDE0A3FDFD80BF2770DD4FB79A7029B0DA6B01C8DB069414B26A05C180CCDFFE049401A348990E0247B542C7CFCDE012F3D6840F406F7BE782DBCF4F6080BAFC7BBB201EF6087D38C211727C15ECA30F003AD52CD540D8BC4DB81375F44E0E092A06F9E9891F6AAA178FC39B3E2868284330B3D2508B486836D9F1F5AF0464AE1DD2D696AC0EFAA4D9DEF2E5CD28A5E1D42E813D3F16DB85BF565EDEAE869A88D082EF43A33F936533D151E0BD06457135FA0450AAC65438C729AAC8598399FE8AC0042E3220E936F88295E45BAF653F405B12B2FA9D386BBCE3B46137253E7C64BCE7E998DCB4916390FF7E2F074FB1754B60C3418DC6C5728E2FA364ACB2C8BF63525849F2CEC268DAB24CA73C429EC350DA2900583D9C8B2BD0AA7F5458B00DE9E44209946F70BEF1C7ECA26CF08DEF56CDBD6C1816D52A373F822321468770A6C5D8BE130E6C752D63A72688B786168480AF505D914C13EAE57905AE47E10CFBD62C2097A7482432CFE5500B804E3715411AAB787FDCEE2F644F38EE9A0784E88DEC94FB9599A68A0105577162A6FD575EDBFAB3D6DA5D2CA2F086A8D55A325F8EBDA84E79D96D794097E62413CA"""), +4253129ba04cd46ebdd117f477bae35bdc6eede60df6a94a580b28abcf8bca383dcd4aca34a318f090c2e236534f4553838b273b1e19dae5a0a6e70df38f33620e3f56d4771ab8edd27ecbee13b41307dea5ffc221ced73da8412ebf90f75e2aa93345937b9904a2ed07488ba7ed7e4a81090fe062407bee215ebbcee51da2e828261181076284017672316008373864314512556411366470351751143502866044174407124820856040124488104747272515157471031535270113332160138362452220861568703310713026080445200335431724117012102776173821368242414322435313184718783246033107615466525681321552700103062228600000840774147702724033480557386354023651330688348535523803036286522510808766140743508450507325777827878388653358828424230141362086225062486351844571254365553532888807256428865656187770583403731862707663306640370460154257323706150367768487752435420042742000513678740407626635145864204641386338346560256308062427383571700177385585843713267024345387573110261418834745377370755318806263742534245857530816728343281562502028178701327753748533284210485466764187235630784126521676840661086401264013631703807186376500638136763122620442512142676466534030816270880344503216655687600047664410317731124621554758747218007662107353206105566073663637081672051334882604615032232175024506440432064120430260450083670328621582421263218843557281084706151204677842415170883722854410034757158564146427433758348366115784744267072344336485111151074443578456122766023544273207851855377881232551654715102510021504036666050106505181807202727601475270388715857665482658610113502167076780287676474561852324234606005157113274325186444642470880201270443712501306260351304114821810185605303043238284024437451570501376818478325118637534878857561622073620761344171515046664327007668000250703168414702270712204854655478324382503648846018628324746162773268200331863534240746136243061806136513225515463704681748620517137525684815620567421644267582106184168262077744160744640345713287127475166803710860415216047606452515703723634771387073742473032414765016712438084131313707771744375662530042820602754771770732427347323015241056073588430468326642327633874772054784104288772127348184355306138573334063016081114262046005810176822754772155254184315401382566282513565023308512153305535166000375507505468255224611413162316477215685285240584136066250035404431257447544533343721406440410427154285517050886855413301515367856571818385181216353325456801442712220023633562061334384508683454077205058063306076017652740557282608146518640164805154524586314027143055784545430125532435466675334181613266512656618060266525616044526063355534408344640284357448206104624813586486385052737045107351812257722833754030787678053325738580428316055350681501643208864705287440678342323163267667345570457764846348710225558572315558323425473721125854230718764686451881373313105016726435620741154216770706556760718055054212814415730370754160475426486577163328361465582221712086205043168328155862243642470841072233880412735188447232451728835468422631647766377207132637428468083840544508143008035708525281067178685206541635074543234105443801377662237826630832273024730474837626134806557367081725831768171583080066473638657717e70bdfdc8bad9d0d859850ac3d18cbb32b70bcba14d4e918230a54a8132484ece197ae8a2a6311d0966f800594271dfd7859fe7b49e9a8a0afaf0ea5a4196428683334fbed3b2925023da8c6db5f6dcffe45d237072acd40f8c75f205628f6be070a24cbe2f41d1d4c08d2fdf9576e08845c31fdb9041f70dc18add5a64d548cd0706d8180687d15b98bc2973944f951ce63765f9a8ba439732a76554223408b658118fb347942439a2a1a38f9074b64b9df696f245b83029e59b352f5811a11ca86a46bb6a84c6eee2baa3672bed15876f1ac1c7c90d3aec56ed2907bb991843b6c2421b4ca6e503bea965671f85dc5afdfa79fb5e512496ee8b096e12cee410c973aec9673ad11fc802972195af9395042c71ad560ee16476b56c12c94786985928874633aa61c5396f819588d8d8d59b0b7b507c371060a974fa1afc142116a1fd7cd6923a7234050edec5c3096d11c9ff9c73c374d7a8e2415be0f277716ca566ac3760c87a98b2b7ce7b2f4932d8f8f2ee9a20a17532934642f39712948c8db39c9a8d1de46a4bfd6db147546db864f9bb95bae22845079577b771f7bae4ea6df336ae203185f9b08803f2fd4c2f0c56b3924b9f3328ce242ecfa31c5841125d5c16f975087d98dbc3f8141b1e4be6c9ab3f3cdff90a6104d2ccb6bb6e4ae7db2519432b728ad46308ac1f81e96568f60dbf4d36e45c663a29c4963a0c51350cddb77d8112ccafd4ce2ba45eef4cdabe7a83c53d5d4c98ed9999666e71d2cff7b07a9a65e35670f23e7eceaa04eec4ad1db0998ee5cd9e03496af5c174810266f7fbb2abeaf568944c7dc3f801941304d72f3644dcd8e2bbc034374750d328ef5e8a52d13936d7147af311cbf9b43c36e32df55be0f19cca9356ff9217bbe7ba2ac63af7d33c43702edd8aab86cb24fd6debe0678dd230dbde3fdbdc2d0d8ad74229c377201b794cfe1fd38bf0ac11f59c765aa3ba2eec27f3bdd2f6440b3a93392030e7338ac012622e4cbcc854d52fa39314ab36269d0848b8cb7b84e491de5bc55f42f147588847b48d62d72b448d112d4f7efa2279bd970bbf428a1ab9b21558e1234638237607adb6c74a01c4337cacf5ce2148c8b8fa9406c57e2c817cd810e552ce2f22d7833d1baa56c791f20421ab96f4b1786edd225b1d1b86a1c71d069c56d67da303aeb30aa7ed170370b04da8a325860eba8d88636861afe173b48deba835f04bce8c723da490d5c01ce033d6f360c3f13c07f77b8841362a69ac1884cad08871cb6b5b6d44b3aa8a6379d52c3d313a38f55408e6373d67d90ce7aee2da39a5f4baef11cb029f6185c4095b9ebfa0c21e3868b048a09cef166ea4998baa869e7bfcb38c4f21a355f268ed4ac94622654992d81f067556f20062186b7371aee40c2e2039d328f4055fcb89ff3ca2a386854c33187d924b5b2759c115c5c2db629ce439b336d84d24e3757c29c2cd942443b2d25d82ac88593da79a9e94b8f2cd730a9b11b3a3b4c95ee312ecd6252f3cb75642e74047f0b9091704d62d79478b199346dd49f3ede0264942d9c407b0e1d7f6351ef62ee2c4a88e0a33ee3292667711cff0f8fdfe8ebb97e06d2cca8a2b1539922f076e21656be5313c37da55a032b9c63b39076b365369a6774e2c3912573f6074a9d53202540465622f98efb447c57dee9d3d9be834824f9a01272293b5623bf062eac9be3a36e94a30df6631e5192194cfa4598699be808ab90935625dbb76e49e868328c19aaf6f6e0627e52b2ce30dde55da986579772370d3a17d2fb7e996595d8c2f8c8c66e97a51dba18174f4bc91ba39de6027318dfec5b083e2e931c420fe04b33e590c2010751013aadd0088fbd832f4318026362963e9e74e1eab1b7634f427040ffbeb2be690f0f36b55ce72be3465f7bab45f0b0861871430f0f063e7b3c3ed1fdf5f2eb2ebaea3763d60cbf578899a76dec331bddb4bb8730597c2fd13c97192b03d2d9199e3589c90e48042481f5169129c52f12469d8d20cecb8cebd5539dcfbba31bf02af7aa6656335530c51c2f9685aa9a658da2cdf3db47d841dc3eacf9ed9374cf07a02adf76cba9ad3102116cba090969a4cb3e2fe0ecbf73c7742645e718dc141d613947744970fdfcc3104c99e742e1a2e54c7bcc5e4530eaf55bf64c4b8d5639026dcc181f68ea40c5ceb84af301e9552474fea73695376d6c2e48104e61f8a9e0c5dce582c50433c583cddfe4ca40fa5b3de2a49b18680f0b07d1f1b563517af97ddacb984ab391a1d1c6848594b68d13389fc110a04551bfbb6d937e300d4b2d73013e052b215189ba0c11523f9c1f80482fccbcf438dba0a68e9fa6ff9b08b966ce916bf46951dd2e03e9eebb47adf1db15abdef480ac1b5d4adacf0142d3d8c33c0c959157bbed6c7240b48cef19112f2bb1cd98e84a23ba46c494a802b194da40aa5df2401c1423ec0a14cfab7728805c407413031a6d6b1998e7c6624343acdd90ac56a3f158883babade104802037b531d8b763050816caea682b0484ff0ab5be3692b1b59e78648087abefccd2314ead501a9f5928d42b64ef5fce259c69d2208143384b7740ee96a4aa1407cbbc4a6f191637168f0ccd8e7e2c21ce2aae1b363d7ee66e44cb53ffd1ec9093650b1f436e311eb16605b22fb1b3bf2e44e165f1b16c526ff0121af634d36a3fb594046f4ce5c9e4f3282a3cba9dd859fb957f20195d591996db6c55308978c03b7e241f7f0ea8026f5d324b859e5a4f0312c7d15c694be788b89d1bb2bda8dc12cc8591a1f32ed662fd3abf7c46be3ba804df0d3e17693fe1702ed8f360f1f92294e73d4ab2e4fa003a8104db60fc88252165272a1e9d1fed431727b06907605e3cf92bb60631ff5b94675883e37951323623b49b77ba5d477908d943f3cfb6c82c1e32a17b0dbdd3ce0647cb47a483e2f036ddef6c8361f15acf6fed93b751e6bfaa7b7a06493aeded3d1659945fea951918c0f2162a0f56934dda177f745d5734b4ba3503914ed460e56cf844bc82abb4be5ad413c0b4891ea5eb16e4bb8ea9984b20721231a7d2d3242b9941bda7df08bfff643bf9683f50b130a194d53808cbbaebd350532e07f2ac5857464240b066655717af04e3e9e5ec9d39351c8a5164055b28b411f4baa88540f8fbb0184eb8994181691e20cb4c79ff2a470262da05269f08a8e6c48fb2071f8c38eae0debf788b6dcf2fc6ff15f6a6be15450652089486d9e4fd0742c83ad6f7898baaa5d7197268c1498e0a426dbd32d2afc73cb44f7917391cb5ef2888cb46516d7269d098d5d63e3e59485337ed26fa18b9a54712e555af1bda8c1391c131f9d0113d058aed3c20cbf0348c65f110766b1a24bc9049ca9fc8b780b964b941065c66d4216d3c78462e6999c360f50709fe1de08ef86d42e1a9957990ed615d197fb77aa1f30b8ec6cfec3de1e3580acd7b57006140e680f3a3b9cc22db2d7d15e9f52db332df876e3d9f6b4340f6e1d84130db69e2a31cb8fb33"""), TestUtils.hexDecode(""" 5870BB288AA6130708F7BBAD9FBDD6D41E249D620495ACFE90C61737B57DBA890213D4741718545CCD8B3FFFC2DB33C39AD631D5B5CC902DE4D340DF03E09248F67E89D28071AA50FA532E94C391D2D1A61B1847C6B1088BE555E5C2694EB0FC1F029095ACD9DEB21EF886BE577682CA96AA2EB3DCB24B871336AC5F23C8488011860B455B687BD4CEF5FA11381BC292B4098BB2CFC1822B48ECFD28AEADA71809BFDA190836D3215CFE755FDD9374115E5A0CCAE15240EBA0147C2F89D8D24454D7A5AC2D20ECC0D46C040FAD233FC51C870080F1FCEFAE6C073AF5F7A78D610E23831D5990985FDBFDC6D101ACF3DB0A74D71739E0"""), TestUtils.hexDecode(""" -4795C93DA899DAAC44BB2F2CCF778D14AF2687E26D40A5A962084FB54F037362BE239723AFB994A15B17B6B779A80CA4C88FA1EB57DC4BF743734929201969C7DBCB295F9D5F994BBA406E24C4A0EEC73368785D9B2C8CA45CBD7AF0A772442692E69FB79AA17FDD80198870BDA0A1F0DD2C89D22BD6660E62802F0D5183A7A9CCF5136E6BB33AE991EEF920FD80EF911BB94AAFE0BE9CAB7C0AC60A8E763242C3E8B4099C7B8B1661E63F756A0B743CFED12484E70151E39CE81320A687286A3719ADF712D006AC81966286C1ADCBF874A359EF391B892D4A72FAA7BB43DC894D0BCD7B77BCFE845677DAC9252046C2578F15C5AFA19ADC9B5D5D6DAA9910F3DC0187F1B12F7F19ABC6ED9AE0CCEC15C76E6003D7F9040F2F6C61FB568C16FA69BFC87E228AB08092D2132E3F50D07FF7020B400601C603BE610F10F19F1014DF1C56D4953B9143BCE64809426F3643D37C99BF27582E4ED66ED8987CB16853148712F82C3E49A4B2C763C010E74347F816DE015F8568024C1B6272A4F0691CC4360ED0B4BB81B576F46A8AA38CDB39972C930CF0774CB5B59871EEE17821B30F58A25BB9702C1A4868CE50FC3C7102E23A75AA751556DE1BD3266084645C8F6AA90B2ED743FF39CBB951A64C5235F1255DA9117630C150E1870066D5DDE4721D2621417AEED53FC1EC5F89D5EC9BD7A6FF0C98E4A2006B0118B2848312ACF3E25AE401807B0CAB45BF54C186A85D096C71C4D14948547792C290212269D8ECFC79BC0FAA3D37F6364E3FE33B326C8135851B20A7D95FF10BCC765251ABD53F4B98B0FE2BB89FE5E15E06D130F35871B5492FFC3A1DDA21E7C6DF0392C714907B7CBB0C977880DE4BD44E3BD1C2B72729D071CC1FC0CC93870EC8996940C943C0209D3008B90F22A8597320B201100F131214CB43E6922168E574BB7C6E4F4A85CE11BFAF32256A649E5C95BFF1B83ECD8825CBE665C6FA98611EE7F4977512476010015DA2D3302F7CAD95FD70910974AC858006DBC3AD8F8995C99C8FCE87078CF218985CE6817336E501480B53F81C1058EE0F7BBDE9E212BB1B067FF34A3F8B55DAD9CD0DC963F8C8B835DE200C294EC402D01DEA0540F5CF92B55252EE651A4190714581ECF2C9617E4AED4BB0230C23AA16FA9502409B03E6A3FBA7D213BE13180EE2CF63B73D0809225F59D2FD14A12119F0A531D250BFF575DAD676F692E21604E2C83AF932BBB7DB4F3A4B15BCBB45CE3C52C622B14561A39BC6582BD2ED428FF05A50B57DD355469A5B36BD5CA04E731F688BFBBF30C450D35FA94E74F7E9172D7F66DBBDF13FA634F3BDC891CB49CD5B33DDE0FD7EC8C7E538ADE84B446781918DB26D363598DD54345FE4CF3673F69CF2A368EB3F6C6FC98E369D9A514F8359CCAA96C8E8B9565945D7C8894B6BFFBA4CB0FE2B1317C424A080A189A5AA8FC4F09E94CC90F3CD74626C519C2A99C39734F26E3FE99DB512896F881034580E2882914411AB3581D8DB80B46B4ED9B22FBAFFC29EC1DD88BCAAFF56A56DE5055245897764C3A45D511245C3523AD1DC7898DDBFFA290683412E8B7882514372240CD523908B0C92FB26AC669327F840A9496BAA63D1915D3D1D8BDBFE63BDCA662E1AA2F4BED11F07A4096A348598BB1E9A239B2DF0CC2C1A7D62F91A6D18B1175CFEC5B74D63154FF2141F82EE5C7DA9BBB4523001BCD174EEED70225F16C73F2F443079E9BEE77205D4928A05166CFBE014A2079661D8B609EB4E66F992EACC830D0FC61621D65E34DFE8EEFA5D782C56426E9EFEB253EB8233B08A3A6CA4AA8D3916CFFB7783C9ECAF0AA859CCCA99AA460DCC193D878D6643492C10101CE59809C5186E3459444C395B036390AFA2E75416EF6F04939710CF080790BF2C6E626BF9E872C7D13CF642E9D9C57EC8DC106721C04F13A8BAB6FD151C8416F523D4F2EC038A2525096EF495273976F3D1E7DCA57D5758A213FE5872F242A67F1C2065083B1BD0214642976155FCDD227265B6A4EB47E6C44F56179CF514CB6D0BD33349381CC4EE48CAA16318DD5DF500E7BDCBF5A46DD24D0A5D5DE106B0B3F66DD75D210379C47FB5CF11523CC42A77CD80423F41364D064427CD016565FE2F1F7F2192670FC6C17AB346DBC50EE30015D353239116BE68967C1ECCFB9632969B848C2C7A768CFA771C8557970D77EE918ADF6208C9D803B41B184814A3C99178E835D89BD47403764EDB366E6050D9B342B3B3D6409C577214BC7CAC261C989906A57A0B4BD9BC9778B1D74076CADD4ADC43C7E79F2A0CE5F2E81C36AFBC66B526D080B85E0372859D64C28DF6A7B60D3A066FD3DEB847DD2775A6636F4693F61361B9D84D19A40A0EFB2C8861D9B27E43BB504EA6B082AD62CB4FC1B6FC163AE7DAF8D6A54CE4E9D33B509D4D7936267A0D32389987DC33DE09ED37043816463DFB828BBBB3B6E4E5286C091A494ACE782507BE750537EE9F2E609AE4992B8FD53E0A38CCE7EF962B75F749B74103477AECF55497CA31741D70B1F207CBD694A8911653DCB4D1F919B728EB2C03177675136C11BC2B772C5E1C5F4BA0FE431BBF4C1755E8DBF54A6A111733E855925296C09DAE549E5AEC0B6E0D9DE07E077825941D970BBC9B7DA939DD2CBB373F75530CA30446F3DE199709A5E68BDE9D92C6A323933F214BD4F3826860A131F301DA7895F34EF35642926FBA61A8E1C17492C31D2D13C20DB60F9C6E90FC0152665A21100E034065A67E2E676C33DAF403218848859342991888DC47F12A2E7522B62B1845A123723639593543CAFCDE6D9FCB2547746C2A7DE5182FAFA8BE1C794E8E1C968B70C3BBD84899AAD7A2231706C108406A7BDD6931A70BE7441B57E70AC353B9E8127DED14FEEEA41124F0AB57C6A0A857E022BF717439A11919962445A480D18B2367AC9E483C3A0CA5C3AD667E7A1EEA7D50335950997959333169F8E76E07B051A89B1755AAED4C49E0532E9D0DF5C9AF99EDFEA49B83AF8147440CF93C4056551873EA11887DD9FCDEF04F7CF1F5EEC712B1E70124C6155975ED419F206F5C16C3D7CBB13321599A4DAB457848974B74087DCBBE990542FB6F7F36D22469E3F68EC189893452D6F4EB180E9A2D1D1F010524A1F501F8DE4C484B35E47E517E166D1F9394DC6CB394C1FB1DB6685F07ACD0D25AA4CA1E3BAE21588A5C9B4D229A4C399854EAB3AF379E3D4456102F021019A8097B06CCC6B6FF912158C3DDD27DE33AC093EE6EE76CA9F8A90C2AA8E07A61221FD9DDB6EF440D6DAB8FCC2138B396BA43DB70CDFC90031F424D4C917F4F4C04D6B7ED87FD103FD195F39C755500B8C4120CB62D3818680EFD3564D5626D6486FBF8CF96C3C179AE85E573D1CF858252DCAFDB03DDCA86FCC65DF85E5A10AB4C549E1289FA57EDB1B2899469701678810BC8E709563B4F99AC7943684F4C56056E26C788B3C8E87DEB10319D56A52B3D25CC491C6771496F4A94E5A67FA60777E899945E2F58C9D7D5759CE41733E6845D6247812B11336062C88FEE525C44EE8F73EB1A0BD66CC64330356C7F2DEA6D3465E2C6EF0505AC68502165F1701FD40E0D5F7DC41583C076A81E56775034124910BCEFF7DDE4A2FA0072D6A6BE8695A8440BCBCEE4A3FE9ABE0F0440A9090ADDC40915D2D33D88F1489888729BA0FD0433828257C44E0C4D46E9EC6C9586D5BA3B9D772ED20BAE620E8D4619E9C720632FC92E153D7068E67A6BEEE16A01731EDD5AA48DE29B083820DE5B1171BAF4E75262353CECF8E2C2174E530D4E3B84F12F2729CBEDB10B62902ED39156C32E2C68C7EEACD2DE88C50E9F6BC117707A0E931311EAC9F836CF4DBD7DC289ADCD4E8A536DD3C7C5DB082FEB4BAFB6B7A48FF9C129CE97FDEEE396502319F6CCEB8B5FA38478DF2C0619CC74E43BC22992A526968AFA9D147CF6A2828ACCCE98A97BB63AF3576670C5B61EB5EF7D30BE747E1668C6CF3226B5DFC8FEA39E9D1648003AF4EF2EA6DF3171F7C2230B9717939EC70E53CD9230BA1E77A1C07D4E6A3CA26455CA7B8B6096C49DDA4A9BFBB2E03C3B6F5D6EAF4C78B87FAFAA5B82C0CF7321F5B8B1D9FE67E765A2C073C844174A21E9E8E16656C0D3D888BE6EA17CD1827AAED796B716DB2B23473472A574BFDDCE1D9F92E179FFA2231E75D63DD2834C792211B4AF030FD4010DDFBA1109F1292C3063A65F612A6B40849717C6B35176A42FC5DE4EAF90943B398357AC5ADECB7E77F460732B712CB0EE509D880E2B6419C2E365EEB36477BBB110240F3B20A66CB39722E9986997642396316E7A23532B2D75389B4E39EA49DF5EE29FBB5EE6E0B4035CABC3ACBA0D85AA7214553A9E3ACA04C0C8B800495220A8E0BCE1D0EB6E650EA0FD8334FE24C5DB224F5CE49490F0EB8246183F844705CD75CFDA3CEC386BB2EEB63F14BA4BD86465C25C97DEECA55D14803EE1ACF6968D8820474F86554CF8A1DDA9209CD5162B158031020277870B55FB8BF5B7A961238546E8BC5FBEFCF4E004413AD9FF4671CBEFDC08EDDEA1690D37D29786157C2856D3A2D3D2AFA5CAA4AEA82A0906A4EBF88E661BAE0A1048687AA1A8ADAE0D1A1D4349526DD40A3A3C667791DBFC13344A6568B2B6BBC6DFF3F81C42638E8FE8F1396B8AA800000000000000091119252C30""") +4211c0fbcd62764b125a8c5263404d7848a1812dad1056f3368817cab3cdc97f852487ff9d2bf404029ae58f9ddba2fcf1cf5006568c2f424aa647b4024ef30a1ac57d831cb0eeb85414d3b9069918d92e0fd933b640f0a6a777637245081aa0d27b2fbca9deb27ca1d1338189124269a14120101f0fc279ecedaab6b5006ca4c7c0baee72c5d44f4c330c56bb4a822ffd3e9c3f2602ada56da71ff40a712f115cbb4bcfc484b9e778bde49ed7df2d9f233ce065d1a9b3eca2c494fb8b7ff6b35d64ce62ca335c27a3c157c801ee1988dd9c7d0cb0b6d9c2295b17f88ca760496dbdc9f68910fa07e48986bab423f9059ed8d4ce90b8d1943d1231c8442dff36a63d28e667bfd075a66a7d729a2d852e89d8f580ae18d6652d8c06e02bcdd48970a658ff1293b6eef87108f9192e65001a21bb2e5dbe932a524cd0a44155e52ed18e1f09b9c5d46483774b49a6559fa78377442c9652b879597b0569cb791731007d556a6a26efcb57910692925f041d4d55a71c7a221f52cc578df50d0b5176a262250f55bfa3abefafef82d31d1af2facb5b6d46c554f67d27a143fe7ad83d4529183a02594b584baf860c1141d50ec50db36ab24adf208289635a7106c3b0bfcf48c6ab881b75f379779fed7f1dac26a4698d1ab9334f88ffcbf9a96eff8e85b34a6ae4d2228b7ba474bb2bf32706ae6d35409477269baf4a8effd70f98fe8aa791bc49b7fda540d80d31d699508d3f9a502f90ced18fd6512aa02a22d941acd43e3ff4fc802f05da84ce5c367f9497e165ed4c5de86fd284e0c181a2cbd1f16b66bd3221fd07e368b1e00193020162ab47e61d05f54be7354b497cf7b6e8d77b932eb0f8161cd015c089ae62d604b647193819b21171c1f493bf0fc7f67407045f56e022ed791c17606633967986c9d93219b7db49f3ba21ccfd1bedaf84315a770d978ab657ec5d4e3e39d8de6a163ed199b5d713d206c9eaaaca1ec4415b015aed58797e4e116b366081825dfa54c25759212f4485eec2cef8f455109e893b4732b437c301db78978831edc4154a1be9972d4facf9137e59e2b04b89fce1b6cecbbdba092518d1d78d7086e55125e22edbdf53dbc67f38eabbe9e76c69554fab97dbb290192f1a5c66384a062c974df996b618fa8478fbdd0e30f11549040643d583ad80480c1fd0106c1f2367cf2ab8eeb641917381815b064905ed6e900b7be712d3ccdb0b1004ad33bb6e8a34b94c228940afa09623c85e490c32023e157b451f02aa6017c1656ae1dbb4e795aba6198e6b6abf66874acd91ea4028e3a9e1b68321fb6e707a72443a0a4749ca460cfc0422c7c6b2d322ace8b51270514d0fbe36d6dee137a89d32e2d55610a60dec2266fd7218ca4d925f15a7c84edeaefe84cfe9a1d672b551f5f2e32308d0a456d59c26b7a1689ffb0a3e4817c5e385a0f4658868814272451015ace5bce4150306621cf53e232cedd3dae72eb1a240e625de8556f5cbee438cbd913b3cd744146228535ea23f310379ab18c24ceebb685d0f61e5c81a2c3c9b4f4a7a533a49c8ef32ad14f2e77e210eaf1eed44cd6c845aeb78c63d7c12c6e5f91b59489fdcf68c4c0948a858933604033209a9d5a2bfb68b101f604f6f10bd9703fb9768c2aebca6ed5b00e4974bb348da101f7f2653d55decfd624a7d79c13c05a7da0ea3211f7bdcf7bf1df8d21ab5f4130f67d5576a4c8a927b7c7890fcf42e1a431c0befa7b86a5c56b283ec96a2f27309ed629b8bbacd4eeef278d7775d1c5ec5bd331cf622298a343cd473b905abd0904803d72bd2463d9a88cc11d62068f0d7fba61781fbbdea6842bcc58385c4f3493ceaf5d105a2ec7764030961546d89a8aa5252c117611c8313ee2d7c96cfa76b1f3daa4e9c885b2d271781c654b52ae904f5ddb3d58335dd81e2e6202925268eff4a6676b80f9042c1e1971fe8a9d6b7c8d88ea282e1696c70619a1baa29584c0acd26967b4dd0252fdc8dfb645a255d32b6065951e7c3da633b92017bf381f1788cdc24b205dd6a7db1335440d62d81ae8afbf2640162cb92095270a8ccd65ddf5fb667fe2b5d33fb1bc5014a6af35cc4e4232fe052014cf4bf2ad9b46684704532f33a0f165473ed2850293f6bad8fa8cac3d74a995b02980fe5275aefa92374719e218185a5d62a6347f64f9e64ee8d06cd9d509294f18542d432ee24177a0af0d2374b5e29735abec655bc4aa1eccb6b8c6cd5d0602b8de15ecf20dfb64f5b0b57cd4bf2e88495da925e98f46799d344c070d95e7527ee7d2bc1e5da7e7e857b2c3c91489d188b4b43477082773c95479290b13779c25682dea8fbe6c8d7cab9b07342894eea86e708d1e1e7f3ed998df17cd752e947e5d2cf4b4c3fb9adc9049bdbed6badc20124a694dcff1deab7a33fc3f7c8a9c7fda5ef59ba4ed3f3ee925aab58cc74b789103500aface7eb0311a90c13b1740a54541e95ed0982c9409800f89c9519ebe0f1f8017d639ea1f9cf33a70633ebe2abcaad745ef5edbbd50442265b477a2eb61e89054d50c8956e6e2743c23a387d316cc5d0b02182989c1f01580b597e0a9f578d3a3aa6d5f0ac1534497c5e8312055e434c7719567be933cf6d213be58ac37527999a9260e7a0850cab48097fd68175d24c6f1b1ad8e104b3578e4fe746621a50bbac09fcc3a0951cc968d708bbeea3e7437bc269416d826e8ffa279b755abff5bfca14e90d791ae0357d45a301d166c19dee82f2c2e6035895b294f0ef30d003c60422f78178c5305996363dc281f8627ac75bcbd28c2a7e1ca918d438c88cfaa57766a372513615592861b9872ad6fc4639e885bf03e32820a49687e0df3598b45a2f81e33fed4e91b9bb458fb55ca35d99351b20dbde76038188f01935c261f07b4287aef1158a5e2db5fb136446cf1ac6bc8265f84a1314f41cf40e283ec5da03269307a31cbc5a3a80b723b63c0366febd211a0a448604bd7e56d4d5d9a7e6d8a1247f098f01bab54f27e598fbe6483744e3bee936adbe1fa4869ed81931cd1d7b4f9ee02ede169104f910cb6dc75e10358e1ddb3f2a661595eb44cb851c53c3f2835f5434ed0945a354483203564d3377e78e3959b93244e836ed4475f82fc829946037bfe7300742203d35d55cbb5c18eff04f30bb9ff99ff1b45858d5a46774088bf295ccb5e03792779dea64d4318f800e10029995e3bd7cae442a8d9ab8cde1a26c1de7aea6a9a70bc16597e54e93729fe27d938b205a0edae98eb80c95e6ac8770f5a2db81bf1fef6fe3063e4681751e9003db29209d1f84851a0afcf62eb0e6605fa69da74650cbc4fd7347743075d9cca143a8084c15d4372a1d325adff6f2b945ac8f7e9bba76b6869abbf9704ccfa718d6926562dfc899c2498b073184ea1c6824a245be772b9276f279e2dbdf62fb28d3295f364f18032361a5db82d16cfa57b21b4270af55130c029b573ccceaeb81293f29c1ba5c0cd6292307c9f0c88100ae57ac1892e422891039541287499d3afbc1d3c68e93a14d5a3b0efb6ff267039fa3aef140953b23cc1d7882023407e7c77dc0924f58529e18b41b2f89747d8f1fb6c166807193100ee0a26b57beb8da3c34fd134a28d5df3cda61683e0ca0f9d92266cf0675081dc18946586e5b9e070504d6125fd485094f3df2eff6d9197b3c7953303f62e276df391c8abf86aef1931d60488556e412ae00f7c201e8d64070aa72e291e804c209c8dc3fe968d06311d569d726fca4a094c7d4dd4b16014d4a1cebaa97131ef1ee66d734b9f85c9a6e70afedb26e7ee8d150d611b852b0bdb34513ee3db302395492b845affb16680f5bea4896b866fc13081eb86f509970b69df9d7c023c160456eb94d7eba2e9e2e076c10ad52b9c966ac387f808811138b9f7416bd0a9d21dfe8b706ce321f284342aa301f4d8361bf20bccd478386673d2afbab6288b8aff15eebfcab25406864842b7fd6bcf6c42fbd8b2cd526c5dca80e46a04be95cd7d63d936eb8f5430415b9b1232e4ad3dda1abb1b1c0286e4d89b9750fc67eeb22342a2aaaf83766ffd72efd993dec4a06dcfbe5dc3c067dca721d41b14f8a3536e69923d34bab47021bd1a16640da14fee5e587a833f2b415f4c454b80c700a4d9bcad4c94b6db9cd969d199f0a3f4fdb7225d445cefee5c67b1d6ac63e8e51d80cf32ae75247436bef80affa4b36096b19b1dff52a88f7a3f2e29dfdb9c5dd994f3bcbafd976f318fc59e3d1ab60e92a2c0ca7eebf68da24253b4bf1bc99c98ac429becba641fc2642074a07a9249ebe6508dc5d0d460f6c7bb873cc6a2ad7b91f03edcdc731507ad451ee3d9a4527721a5e76a55dc008f438014fd0797066a51910e958d5a0d92ee2245c853b4c9a7b2e7efb1e9e749b420b126f0a0240c516882686660b38c60007f45d7648eaa2d7b1c6b1bdba8aa5ca140e8c38b0cb6d54e3083e903f7c3f6ac97d95293506613b3a35f1c2a8d401f66d917906210c758563e4722d30b05d375c8ecc41d898574c3a20d218b581db4c85ddb2125e56c4918d021f96bac324ff9e9789c921cc5281c0f0c98a98fcf218232a8b99a2bc34a4b7c9d9031b1d408bbec6e3e633555e8fabcb0115324e000000000000000000000000000000000000000000000001080d161c20""") ) }; - // Only three are expected to pass, so I repeat to get 10. static SigVerTestCase[] SigVerTestCases65 = new SigVerTestCase[] { new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +36fa0dd4a24ec6fcb09f2302dadf25bb8118be5ada70e1eb7f57b93fa96b1b842b748c1f9ccc78cef5d647c28fe8a346ec60afd8a79dcf46d5a9666b0e50816972701861835ba933a4ed0df8b13eb32f07761ab2f9fb622346059777c7c75b2f370fa623cf1d71595827294cf14bfc36f0ccaeb3b9162825737481012d4547d1843873aae1a2ac6f262ec5d4b2403ff7cbb3e6758920a6dfc12f48396f8f96e144c1afa6f0a150c1a05047e35e95a3530748c121f953682cea77ac0e4dc7cf205cd63e8aa64e278cd6ea2726519fef2d0180931cb2e06739ccf01e2bc1ef7cbfdd6bab7b9bf82092e18440945bccd91ec8a703765615cbc42492925b3515a20c8e676593d0a4492011a3cfaaa78a21ee10bd266e27faf13ea69691bf5bdb89bf7bd13642fc757af3e5217696b6d0f25386a8e2e2476742b5b050813afda57377141f0fbea06f83544f14b1f027a05d9fe5d431ab6adc86623824c466f3d37b9f70a9318b52688d209a869c78a1f063742380c18961fd3cb19b3e0d90898025fc8d7785791d6ee155899e1c0c082657dbe848c1c03ef6ae62ac00e1ee2a71527338776085554a3929db26d61d842c15e24a917fff823ac1bd9deb37af188a6584bda29bced6401230efeabdc5e96bc2c77c23347e5f60ba29c581877edb9eec6831a9db4f93c383a5f2f770055a50c9d4579e69a22899901d1c9f2c5b892976d980ba4ad0864c0a046837791ef23540b603a5f7cb074d94620661e924d017d29d6fe6b4b9168cab2325a6f35e7d1dab818d4fca14f6af4b0eef66f869a0e1d7a8ed15ebb9b1d3cada4fcf106ce5d0c740c9d8eb5771933226ad5af16f8364d506cd700fb5270cb26dd0b17e04d7db7e5f503c9ce3c44d0b8297e619dbdb382c29d7801a9cde6cd5e6f8e4ecd6cb9e8e89ce2782812496a0948788fefd3fa8172df501475cb6d68cde63edce6b7b989281b2b95d60a301f10f60fb23d8dbaf6e4b4b345b0249434623580936e9ddb6440d7ef60fd96e1115585d16725e224a4c86356bf5275ac911864cf1631c6fa8e6ca3f093914638f40517a2102f23505a571e8578d4b5a7b97af3a0df8ba735d6e53bd6e0563dbb21c37ce4ce99f45752d69322675bd522046a89dd447a34fe781095126c774bba2b26c9d7cfe4df858e7a5304c5183d24bd59f41d7f22414dd6ad5865dcf10bb42857b738d11b2d6712d76bd252615e68c91aab09c8de5cc36cd9ea66a8ef4b65a91e86cc39bd107ba15b1e5be3f7e856070026827a16dfccb6943877ad4d3dafdf5afccb3ead3bbe493fe4d2928c335a9ec128f11dbcfffb8d439a7807cf035c01ad29d90f767d7f8456b4511321919e0a27220c411d94639de6ee232da1544671981c200642de22f01a8b14e8ea8ae91cc05f2a41acd085239ee00dd3e31bd21673fd2ed5a5692b3d163d99b1c19539445a3aaee990daba896e67ac125007115f126bfb6902fc8f53501656ba204677dd4b6132813d9064000d024cf0b2ad70168c8bfd6f78ffe6d1e6ad8731e880bdd52056f2bd42c825ff5dcad7b4b42275adc52b8eea33e23178ca2361d55d829de69edb56bb2a9ec300a4691cbc1fbe0b8f8f999eb6259fe49d6fa63d665722e542fac9a2ab5f203d1403ef328ed290fc2bfa1da1240076123d425e485589eb6c7ba701658fa6ceebe2fc2d211d0c14160ca5518aaac2c7763c4393e41c31a8b62b3af2ab12bce0f2324ffc1bf4d1cacb245da239406fbe105310f494502d6aed8fabd2042c7b1e4bbcc8b44d22f34850db34f8d8134ca2d7a7e7c57e447d66660c83001a54aadbf616517867f1a9a127a7073ab120ef4f6ebed8b66640dbab85f7e4f6c379d6962ea30b849b1919442aa6cd3defcddf35cfe6e4e9443b5c130503fb37dfbbaec995cae8b2bee478b99cea9a030368aa1070b17909d27024bff039dc4e1916d8006480d83858c04f22e0876e9eafdb67688d62c94252a74c1275c135631e162e4588b3f6d9f8140f28e8ab98e11cd96c7d5a528dc8af32ac90831bd74f2481983c62ef4111057b02621f89c85731edbd1b17f525f0a7c732fe8738df6f20912159a3a44b9b1518017e59e02b418dd08d066642c120af3ce2d22e7925fa7d811aad41328c66ec31ab05e1185351ef5cd3f88d931e70e4d60175634a8df275a96b669024f2a5d7dd9e8fb09ed16d5a754a25bfc0148b6b690ac7bb9e44062baab6f2c7e2dbda94a641a07fbfce7856bdd329ffda4a6ea637caaf36d1776ffbbb17241c7a69533adad3c242dd98168f0dddd11df24c0e2ad33db04cce7d8422d7211b6b04a93314655b7999093954674341f25989b19c2cc7851f8d3632543e5f706c1a4a71cd37f9d9aa06bc81220e8792baf65e69a75b9f1f9d709cf73f4819300efab7505f3f2a3ccf913cdea82c65a446817b316fe1048db8e7158a80ec221497a243a16b6292131573a6374c68deab40bcfbd4bc955778345eaa8fd9c8e405a9cb2ef79842bab9f48bbec5764dc6159cf34f4d6729e1451dff16a92b9920301522650ec397c4839857a03e991185fad483898e37485b7329a74929e7b865d1805ed02158b209fbc0661d4f9324f3be701928d65a04784b8fdae59666d70b1ed2d5310a2a66a3d7b948b160e16dee03a694403b7e10f4c9d860ab54c34b49dfc4789118f0bd4141158be72d710d9812f66f2070f5542064cd9fb7030e9b8a82e2ea74c2cfffaa3ba0046a59f4cd06ce680f5a9f2"""), TestUtils.hexDecode(""" -C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), +E3D54DBA675DE7530D3854C8CDBD581C6E392F69CF9793D8C0BBAFEE7334C5878BF13B3BDCF1D993A47A7E8EDD4B6C3EC915A5E8FBF2071F112AAC41F08CCD8CC731143AFC223213212A5BD6B6A4026CFC9F7A41C08CB99F2B375D0E04FBBE00503533DFB869DE43566574B49232566E38B13CAF8C1EC1FA11CCA3DB66887996DFEE090D133B1D394F075F8286CA6CCE13C3977D929DEF5943461BD5A22D4BB5E8FB7EFE016932D02ECF4D7B7705412CA14508B13E61925EEC0B77460C4C089C83D687C8F70D141C75D6DF24FCDB64BB8C2721AAC9CE8C6FC4750C1686A7A70DF34957DCC0CE53C3F0D280CBD056D4F921FDEDB35AFCE5DBB348964AD105EEF5A1B07BD0D586B87ADA7CA7AFA93FB75AC0DE1C749C48BD6F192D6279482D3F9781290B88B095D73E728AFC186BFF0816C1DE78119D701FAD382C65ACC42B04D69412AEB255793839EFB9E5BBF6F69B7FDA27A44C04D3AA2FDC6101E9CEC6F75745F20E077EE23D652B7DE547A0FB0E3A153473BC824AC8A31A2C9493DE64B6D40185B60431B1B34EE32797CC77C45C71F4E04E849BF8DDFCF640B83130208DC2495C0CFC6C031B63B80FB45F47BFE3D25EC5B36C2700300D8223074C156C5D9887DE8C5A97BA36A84D7585CC065F20FE8DCE9E8EB814A1D5B7A3B7A3AB68D93EDBBBBF67BD70A0FC536C81C8D6E8B139C6B3B5EEAA3953464549CB38B78A15CE3D5BB4B798E6B142BC48C70C5BE61F82DB6E2EC03616999073574E6FB35D441B78DCAFF56B8CA8F473EC0543C9C69E93B97F95FCA58DAAED511F4440DB252EC18C90D2F97AD901716AD34EE103EAB0B7982994E21ED1AC4BD62ACE6DFE12C8C2CD092E7A7E37BD4E61B4CD51D980171F8D4253A4E7FCCABA0A513038276325372527621B0A3DFAECCD7CDFE98CB79C0662F5D0234AEEE9302438B778238BCA409D5908768779155D659E92D12CEEF3C2C954C3F1A4C2912E9EE994209B608A604D0CD87F79665A25E774E6DC1D8819B85852D9ADEB174C75D982DCE29FFDD24B7AAF5946A74C14A301AE09F1386AB17ACC341D6DAC040FA6527FCB8E095CD4F1651E47CE02E6ED76C085B2FABE9FF5A510E63E73EE386AC17D5C2C94C2D528B3A9C8902D10C1610BA70BA616C58D037F148E6332107DB9F64C579064F19481669C7888C21F0A3374194FF1A72FB6180DC01D29443BC52C318AB03843357A5A98B3D5CDDE9BC49D3ED29EF73CAF44A7849AC6DF4B2D353B6A562386BD480512108CA0ECD63BB3D3A0695679762F8254116D8049488BE6389FAC08916E6407944B1526BF03551504E40E6A3266D4E773E892EAC4DD5128374BA341EB4097E20A9BBD4E5EA26BE6FC325D9B71C232DCE1974928516EA2519974C82AEA5247627F802C6442B67FBC10E359672EEB9DFF768E9333A2166336FF0004DE5E7BCA55998C860FC1A86B75CBEB3FB5A5A2519D5227A6B5A7E0EE058FEE0CAE2B4AA75099FF098089F0261C443B13911CF3250CAE2F2906CB6454A20D0FFFE8C5AFB1DE7C5BA8CAAE00CD7C2D7219FC83FB158FD6D15EDC2924AB41C9B881566C538F5E38978C3182FBDD0C0C532A77A61E5B8E666B3C540DE976098D2BC68C0CDACF57E9BF1BDE8A7BFB13256BC69F2E386D8F458D303BAB781E537517AD7D0F0378D2F258B013AEA01C97A7E8CD2C3DEB203AA8D59084ACC2B09AD3C97EA613A2FBF297038B4E721665D512DDFE5C13F11DF4BDC0200BF610D57EA7232914752F75A544E01D5AE0DEFBC9E18695824058BDFCDDF4D5884840D2B55D6C2D6EDF475CA75F3EB4D0EDFAE99349684BC9C533EAD591085BD1D6D4E4F9B00A54C97244322D505AB52B2D4E0438C6AC5D2C3983BFB2359FB21174AC02156AE11EF233AF40A695854C84E620754419CF7ED9EA4FDACEFC8879B2EBC7B29CDF9C4CA2921E084486477C1452BC3BAF529DD92748E2B1B684B1103CF4C6EE11999E4121CFC7E2F3F6C7BB9C055F800DC46D78D9D94C3B20BD1B697411FF0B41E38173D2C9FF1CCA77B27384026ED2EE25223B0007D2930D700A20EC9159A66A4BBE0BD84DA52F006D7FAC6D59AB2BDE08FBCEB76A57FFEF59C077F9008A4A231FCC302E4DDAE9F3DAA55707C1EDCDE8042176DC7DC6377BEC58B236990AA6C5876D5A27942FFF7FD74B7DA1D2EC470CF71103A64FD2917AF4C45D4C59C13F58472AF408F9C5F907C7C6AE0F402B404AA40CF8D962EDEF7B7654EC8E36C645855BBECC1337EC18F0EA65933F4D07CEE15294139F479A16133D2BF412B5E46D5B06FB170F0C93DFB8AC3F7478002CA76B67A272A3224C8172CDD8A616A4C52F5FDE946CF5733583C53835EBC90DE3ECE34299D7E5434BF072F08A44905818EE9708815CED10E9043E88B6EF12BE72FC1169FF2F925C38E03B827CDE77740C7C2848AA3B09F555E2712B341E248772EFCF01B99CD5403642448B5243F35A3073A6DA7685AD42FECB05D46FC99F7D6B8EC56F39A7E7B3579FCD587E07C05BB7E1F5D49B9015375E09A9A14F2CDF049AC392139EAA3C2547426B8CBC0C4BA76C55014FCD3940FEA2631A75CD2FF5C22B8A65C9AF2DB1B831C30EDC8EB79B797E76D045EF0B8EFF8D41404F626DE8551FFA445885CA1E3C9BF05B5C39CD40E3B37CE3B58514BC70E2EA94CD694CA88C1F47AACF9B4FF6622C555AAB7C71EA210FAA9C0BF9089DC9C9DFA77C2C4A92F59BD7CD24EF4F8D5088DDBE22DE854F8966C017FB414464ED6B991E289F7E3FEA783831CCFB51E227A6DD4F5EF50963E80847FA6B350A2DCDA3C875D176342ED73BB42B416E58D1612C4D066F1207B6E16A955DCD557A9EA37A9F24CCB20E74AC4D6166ACEBCD7D651450E5D4AEA86DC89528DFEBE07B39A160160FEBBEE5B11122B4177FD04B0A49803E498F1BFFBA898BE3B26320966165E136F7F517FEA35EDF01D36831F9AB478CFF8241E01AD7570C26EA62439013F61D48797B92964903802AAAF356C6AF7645F5F4338C7EAD5AB2898C600123888AF42A2FE06FF03D81320FC08E7589E19887EC86CC1B08204C29E86CCF187B1240B81F7D375F3762CBC10F3BADCAD7431E59A4DC136440AA72628E17D2BCFF916DBC8A66B8A83A3C6400EA0CC57A82DB41BB28CEA9E9CECA1ED826719B9B62B6CED5B52FA518FE47274DC6E22E5F8398D42AB23572CD6623EC307FB7EF61892AE3196C48125605F4F09B9C0F0DBBFB9D9015D325C546CF3B1DC886AB0DEFE2C35CD39E2AFD13AEA74F787B410883EB72DB8CA7D225E6FE8143695BC0FE556C6CDDA493F92ED62A38E8F90CC4C713A4798984007A5CBF68F0CDCC01274C96A15C3C4355ADFC75F7DB0603918ED6CB4E4491A8569FB1A9AF32528F6E26B2303C7987E39015573521E024B2230BF1BB803BF2B358880F2840CC58ACE31E551C8E2A0F8349570741F8E93066C8F17608DE35AEC342415A4BFDD13A9757501F5246ECA49913D0F02EFF35F4B3D40DF97A64B0FD02709C0832C423543A850776ED9C0574C26CDAB8DB371F5F4B731E6F510BC09FCE3DBB58BBAE1074CCAC284D5F8068D2435E053A037E3ABDC957B74339EF0063D367F7556E49D2C7A7DE3616F5E8B703B7585F526E9306C59329A18E76B85303C31E3616831F2AA2B173CD0A43CDE76AE52EFB8CF3C381097D7A7598EC833A75E97AE4DD539C31B3E45216EF9C844008C28D12B12D3C7EA7FB89B3B5D20EF5C7636A8E83D6A9F8F7DF29C9716B7D92313048A7E14B9EDF77FEBA874B9410DCAEC4816D2FB57050696F5D4F0DB47C6183D447C5AFBCB948D09944F4271368542E377DEECD006779F6F7649B946E79BBF2E19AB4E93F142BB24E6D962F6648CD0BF1BE876F6F431E883105C3E86B973E30735A6FE17346ECBEED5D101EF0AAFBBB4C072BADAA2F4D517C272F2BD2190F5F8C87D961041A121D6B319EBC959AB0603096017BF7CBB74DBC74FB866358EF8C1AA5B9A10B2C524E822278627C0AC577AE9383C2A529054528E58D56699540E4931BC65A125EF4B459A7A5FC10E0324ACB641BA33C83A7E100CB00FFE0ABF6281F8942AE5490DCCA37BF464D0B061028E46E025FBD5F6DD6CA1BEBEE282B749FF5B002210916B9CDC4D903A95972FCECB9292A554AEBD821AB4CC50D5EA0A33A699FBF07F2CA520FC44D4A9581182290294A8FCC66DE3FB5B7F5EC5B267D1A0E6F84C27C02253649F5903389A0901797A7EC8B78AF12BF2B1CC22D291347A0F8D6EB2698AFCA7CB4C23EDF250A5B77E51EFFA3C675F1FA951D72467EDAF987D5B63DE4177535974BB2006AA9A8DD9E624108229B1C5735BB039CCE47162EB52DE88703A8BDB8ED409BC01DABADFD31EBB95CAD9026705DBAE5A2D06376320BCFAC17A7DAC957BFEE98480C7A111B5ED300447A21FE62448F62CCFF7DA68689A73A2EC70BD13130337EABF26A00BF86E52077EA00DA46FE7323780CF98B3E998BB30C3998017F4BEA455568FCD567086EC68ABC40113DB474C6C88B1C1C7588E7A8C8D2082D4C70DCB8FC3D8FBAC53CAE95286F13254253861567E4715B03E682E422C111169D96359EE18265C3CADBAB3AE61F03F86D096ADAE9A6C4820EBE3B61015995707695B42B67802FAC2D6FBB2B67801A3E48843EB83288AB52C29C1F112F9233860612BA015D4B7CABC19C6294F8871E2ECF6AF334DF9C8330971277E32CF1488F04B4B285AEEAA83BB81D54B6B8426439804B027822373AB99868EC068735C816521BD75DC19F79D2E2166B1A551C998318FE19F5079BAADB12732528BC8B522438AAD252C57D3899400913CD124D2DBE90A891D95900C0256D9DDBF939BADCF6E37E6783DA2A2BAAD872F6C8C11878ED6D5EE2988135A39F2DAC7CF127100C36D2D4E58B3A9B1D7341120FFCA0EED2E98E020A46F1AECBC809A21EF79E6DBCE76F96B6930107F078A5D4464CFEAC414CA41A5EE4F87CCD8868E7922A14C247885F0DA9E23A7604EDE703C2BE3633AF9CCC32B9E5F51CF51978F10A06F5D77C67927D80AE480E7E5E005401ED95467972ED87029029DA05DFBCF2F0B9D50441E8F15804B0A59D23CFC2E3C0FBFCB10B69AADF0B37C06DBF972E264C6CDE4142C04FFD9FA0AF2451F8BEC3FDE9723306085ECEFB17C591E691F9B4D4F796E293C0CD322F02B96938A5F7D1C8A7FEB94C031DE24E71020FF37E00590AE7CA48CA876AFCA2BE3723EAAD40FD27B90FE6EA039C9F3F6069FDBC70F16626A41678A31E8AD88DE9BCE8A25D43B86EBF80E5E426FE21606E67545FF8E55FA7D9802D65AFBDA79EF40DE924FD0DA7B5C8F6A2CF993FA6D27B2861C629CC9BD2E1E6AF04F88065614F7E24CDD19C88CF2D7D2B93B7408D898525E5141FF71D18DABAC186DCD432F3895A1027C92CF8613C80BD46E4758CA26C8CD92B74EEBC5FA5EDF9C9FEC54FEAC40F0944E3FA165E515A03DB57C205D383C04B2CBFF703939EF321DF8A49BC3F5B1409EA491062B7B9982277825B52C6CC8313BA05ABFFCDFA525445B1CFF773D28536A989D257967B50D7BEC4FDE5F338D2AE81BC8EC592BE93BDA0A7DD089057E675674E8B997B05D049CA3DBD60B7F3FB23BA5F4E5A48ED8535234E5C66C41B157C25B5D9EF5C8C0ED016D6B217F4B60BFD0DA223A5D40C2A403DE8268AD5E6207C54B217C2F009C5DD052266722DC21D4AD8314DE498692E3C77C9F8226A14F27D49E0DA1101E32E5B86BC0F0348A20A360A919EC863695D2EC318A61F654C9A1526AF1538F928DB76F9B14EF598F2551EE85D6E0429192C5F18D339DD5A280DD5B1A8F59EC1F2947996C7E190C87502FDF5004772224BBD1C4DD62A8DA1723EDB41176A9AF04B1F30D09050E73579364360DB4F98034FEC1B43E6E9E0226409E6AF1609FEB862D845994BC20E67010237B74DF1AB59EDF14B1623FDC990B87B929FB7E837B1ED905286A886F59B023F40B07A989EF7A99E974EBAEC49B45FEE1F405D11A641B2B150EBE854F7853F06026CB1287FD8BCEFB15D2AEA623D7C3ADAA00B35A105ABF2D8F9715BE65AFCC1381D29C5EF398F2B76FE1651348BAAC147CFAFF34778242B32A1620E0332EEC7AF5E750DFEC30A899452ADC530DD933A07748DD522AC20AE2B2889FAC3237D23C4472FC8C6B236D4A4D19F67264F54BB9B25318156B30EDF273BBF3598AF5B34BAD41585982F6039F6E488308B47EAEA5D21A91E5838F7D9CCC8F726EB2DB82D022BAF103AB2DD444489B94E8DDBA71E62AB6251DD5D5F69E44F377674A5C2B032150C32664C96C072867BB7A2DC29033E6BCCAEDDEA430E5E155DD0724FCBC0415B2AB6DFE68A2E59403B206BBE7F421FAAC53F66040C5CCCEB19F17BF000AEA7E775211E48AE04AB32B2EA470FF97707D9C073FE72A7B77D49FF8DEA36610C2A83306435861BE01DC4B20DBB8AA6CB780328DCFC2A32D74CABA83929CBC85E406E74EEDB727A2FB5BD9D304AF46225832858B295A17B9E710BD7B0B5D19DBBF4FD021EAF29F4D1B6BD7E78C8A3E3235B5D0BC687BD5B428D2318CF4330EC343566D42D17BE838EEEDF70F1E409C189DB1AE0A205D222C92A1ADD33B8E3B126AF62818A2DBE3E3C001098A986865C6B57D0B2F5579B97B6F101EB56FA839F8789F6774074185A8E0F383E9D8813CA1670D8B7586A3A1C27A3F5A3874C4E743EAE21BC519DCC430E281D2F73C23BAB948938A46FC24DA94647150DB72783AB3FAC01D834A8544F144779A51480643CB1ACCA0BF88D203F865664A5ECE18A88CE31B0D8FEEC585F9531329002D4FFABED01EF42AF52DDF08400C58D07E98046D77C7A142B513DA0EE795DD57EA43F4CE36C8F6D2862044945DC293C8D47D9F207B0344220E3177D6E17A4B39B22CCAE3C53D4E0DC87F70CBE9BF743CEACB8932DF8F84A527C9FB84C6CF5206EC2E43D1FF8E846DA06EBFFFB87BEC09C63E9633713768060ECA6259AAFE7C787F3947D5B94A6B80FF0A7A4785836F9A1396833347C13034040D1C6B1F83782AA6458328160FA04971DE04A16B6C031B2571DD131912CDF2515DD56983ED6EF3BBE5B3989E951BF0B99C5605C38181E96690487E87240059DE21BD220059E5D7E3C832FD4569BB7DF06437197CAC141E8FE5B369B542CBEED2F9025A030C54F0B5D2B1E79011CF2A0A0DB14312E352D07BC03E654AABAA95AFD30F1483B57BB1A74A0CDF8C9FDEBE4B0E156FE86BB1E21D861F8EBE0C4AB2B23E776EC01A281F6DA9BEC4C560668B4EEC71856E6CC41741DF2EBBD4E95B661EC24FE31B1DAABC9373CCBC82F3C13C31E478097259850221928C7AC6BB933A5631C896ACA87FB6F5E3EEF36EF5B9CE59F5676813A1A7E768FC9B8AD4A0A072672BA23CC21B21A95C9BBB1A40FDFEBD2D611B773DFA55F87E9AB1CE51CC42B0FE2FE15DA2D73F656CA56279AA16722ABAED5727519EA258794503F1808E4EBF056530B318B99A74886D05D042DF4D829C425C908B58162EE30A073D4BB7D27275B548E7A90E6D178DD27F67CD955270825FB96300C4645E4CD9C175C1185707D4D365955FCFD245A55D64EFB66308A47FC85592BFB755EB4AA8B78B541274E2C225DAD649C248E7F2792A56BFBEF704551588460B192DAFB9BF6798B7D4CECFA424AEAD675DCA081E60BBED670F9AB2316F5012E2290770D3323403DA5748BE6681565A713873A5386A6F1299F0E1EDB341FFF08325510A7F2FE5EB0302727D7355EE48ED5DF4316FD34833238690B91D47165CD4CC0454DA33B87569D38880AD92A92ABA0F24D99ED4CC977A2B4E37954FBE9B9320101C80A858122793062C7AC26E71BE2608DBD2A97CF4E884FD3255D008700FF3531C045750B2EAF7730BC9A51C675D94179DCFCE9EE63C1473D15B4319AA9EDFD19739CC05C5C3C8AA618FA9096C6648756F8AA74FD18A8CD81A2D248B856902B4D30182BFC2F392450F902973043EA0F5E6C872AD43A2D319F99F095808D83A8B02BD380D6C3F3DD227EAE2B4A4867713853D63CFF405621B1EEEEF00D5BA2FF254CDF97B4226334A9866A2B5BDF1F8E8AFDF1238DA9F48FC388A339F79D648CAA0A0A69D6F16E297663E5F4CF1AA95427E68D71E74C0A2FB6B689224BD9978F7A3A4505334774176FD87097D8AB454CABEE138F2CDFC6EF0F3DB14B09DD02E7FABE9F156654433B75B951AE3C196D670192004DC1924D1950AC597682EAD1C087ACB1461247DFAB3CD42279F9169B69B33435DB9D8994AC04B15D45007F0F98334AC5D783219B376D9ED7553F52CBADF159F69282050A4C843467AE7E4C4A142A61CCC4C48DC3AAC6B8E0A8D618E06C60DC924A943AF9000F896446CB62EF4E47AD6D1FBE2B8984A48ACD7C0519D6E87A33106E9A91C298808BF04E1267349334E6C2AC015A9F704B2DDB56D27A8B00D876AD00F62434095A6F7A5E9CD4B27FE09FF69019AE5F27330792CF9A1C07FBE98D23C4E615332A77DB5B6182D277DDFD7572DA75748DFB3B9315294EABE4B6D0FC3114B2AFF5537A6B05A7AA9ABB4930E17B7FD3D8F81AA2D674DB69AD967C8306FC3E1CA8BF78F446B26D8F2FD1AF6F7FD7E52867BCCC3B4DBD7227EA992DD995D77C4A2BC808C7A3E68FA433675F489BC503DB70115A824669E4B1861CDBD557A1F78F1A4B3582B2553AC23F12A4326EF943C56F847B8C679695614BBB1DDEA9CFB7D799CE42DF8B735FEB9DC119DBCA306DA4FA84A50F79905E5C2AC1F61241D88359EE6F62DC9D3E4A1593F41CC5F3C02241CE5EB62C28A547FCAADF1DD688F3DFBA870D9BED723B02B0B1CDB4C08D093C48977E0621930A668A5CD517A0EFFBE248B4AACF3009BAC0D47F49378F30A3D2C2800CD16B3C9464563DA4A7321082FAE95DE5645FCCBC5569E942B5F860A32F04082723E9E53F2D18099BEC5E23A916354198325FA8DAEAA3F6B7AB6AAD6EF12A03CBDC27B83C818F44"""), TestUtils.hexDecode(""" -E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") +7dfa6f43cf7e66cb9e8830871ea48edb07de9845daf9433d74ba10cded10ae8fb4955732aa5f11581322d945bd5b0c05ca195e5373453435602784c9e386ad0766d81c9c954614533a0ab7407d4eead99582655ed634e9a7db1458e3f91bf0c4ff63adb0b62c4e813c396d8a640d0464aff2abc80dac7a5d0329e31eb34d00c2d90142f47e1dcaa203f730de8723ff5f6e9db3dc53923c1dc413ce54f5049496cb69e1280ba7ecc7cb540a62e441c97743e196a0144db65e3c0022c9a6ec621eb1ef79c93b4b224c4a1df88afe1c4513988a9aa4d6aa2a440a9d2b3946dceb5954b0f5634af19cb9de528dfd8bfe857375a8c903b124fe6b9584fa68f56dde10114aa62aafde3159db334294c06b2774fd660a13e997403f04f5027bda9745e16684edbbdcde4155adfe34e0febff14bb05057ee9188c2f7ec829389e7fb24c24d3ceec6f37e53b592b40fbfde40cec330639e585017f79fc86c68de2d24e49b33b5368fd1c7d027503f12b339aac9a4dfbe711918e9eda6bba049154d4f3aa0519078e9ae18f5a94f31adbcc199a72a7b09de94c7a9ca94a04d016fe4051e5b778d5de31f3fb76fa68a71574fdeafcea5e72b563e99982ffcef751e8422d2750809786b57850b832c34a1ea88176861a4176a6623159d63535b5897ef1621564c1882e2ab954455cfd5eb080f9e979a580fd8ed7b02bd504c6ce24c55c1e582e524b6aaa8ef66c666807aaa994d22df7bd5c1a01b128a408b9dc762f2a5fae6a61da1ff4a2feb7e4389bf3fa4357c61acefdbe386b6e55eb3220eecc005cc0047b45bff02e87f1f55177c78c16f142c27e6e9c3ef81a5c5cc77e70695a7ca57e93da2b5c0b32a8df6a77dccb47f3c9406ac58bcac1ba5aa511e417648c4160979d7cd710d35f4b405e7b3d09d229d011013e7c84ca8d0693696b4028eaec2993755bddee22be25b4ab0c5541d6379a067b9fe755955cf11f7f83399bcf28c331c69e2f9a80431da37b14c7e854232037284e91978ef928fe68021138649d3cbc669126910cd648e39cd91efae120eb275b114d33629bf451416ca9affe96d67ddbdfea590b7babfbb49a8e6fada738b0f2bb907e34a856a835e09a8c9076ee222bbffaa25a30aaa21309449c4cd0a7fcb6110a1c82fa8d4a737bab8d92e4bdde60827442e9f74d135f3834073da3867b5094f4653d88607e8551f0c2951595fde2880f0407b60146b5f83ce3e589ef16368b7e058db6b3e8b98d6d459428635f1fe23fbbae5e96d5afbbded8dc22010c58d11e84edaf7ffb8c6598d15e8d3800cdde92ba519f3773ae13219b7e2b967f360162431f50b0de5c634dce2a361760bf2c656e47f8d10336c0c8a0694c148d43dcadb3f84ba52a2f8a167732f106df835e50af089652c7c806b1f51ed4dcdec2cb5d97b5c06f6c64c2be83ec4c1b228fe5615b7531921a5ab4e2357deff9d75e04586f0d325e0bc6306cc22f59e26dec56a2b0ac627f95be580a8efc9d7c27104a852df113d443664a9fb27c0a7e9181372eab430394ef71bb5327e2ed828b60a7b93a42b054cace4b029a8f4fa8fdbabd0b728971ba99c641ce864b627f9fa17c33a6f50d3df9c97d066546a37ecc518b6eec761351240ed4ac606e498daffcc4cb2ccb061619377d33d791938a32cc3640f45549f625e8c2c284a7fea4fe1a864417183177f9c914348d7a693e2d53a95dff9fbe6b26604ae005bb1244176ddb2eefc07942edc0b0fd336f267006979bd82c4499460185d7ad41301fbf5b17e78491a02b8df328aa35eca2346c1f37ca775d11facf01e26d7473956f28551bae4afa6039faf145ade0da17470beb6857ff7435b7ecfcfe51417282095d7a83316d16bfd0a209bddb52461fbd14a74bfe06183c01c40cd6086c6594921073e6a49580aab6b28c71b960ad575471fc6276b4df624870ed01346e3a6252b8e9ad82b40cc88f5627ea5d8073efa300eec86ea921cde8cec9e172314081eee5f6cc665f2b0f6e5a0e56a9d55d8fd1079ce1b5ee10fd69b1a1e8fce047cf7264edb9c44e51443387f9d2fc54b3ef09055f819fbb065d6f0f09e53b3d5536f1c5a98c1778a5a45755894290e45d27f93fdd72e948fb5a1e4b2b97798eb030933180e8aa5bef5d89770c546320c9e2080eb7a1ee3c03a424891517c3281a0f2a7865a138e7cdb1b417809c3c3f62b12baf9b02f9156ab6c774c03d698a9b52380124d863008bf3875dcb7a8a80191c288fcd856e138783a0fb301e395ade94de2193b7f316c63fafeb388a52bb934409064aa9822f5582f632324e11b6e4bd668c0c3d57267d64311556bf855524191565c02da543f1cbacf62a1d5d9839990ce77590f138e7db0641e51ad911c3c116addea6fad97243e9ee4efa3619e8809d67e8907aa0d63f4d9ed863999212e5edfc8e7c761795792e7d9c1d05af67f10645f76ef119c6ce384e92f1f91003761c9203f2e2e6afb3ed4daa3c24d74b9cec3526159f7f88b6df5354db2e7eb0dc1240cddcdf076b8b8f4567eefb4b27e07aa3a6dd9e17695f58a647002283b2f853e9c5abf16b5c4c1f4cf6dc67e14e2ffac3ea0e98830d8613fa7a149109d054ad4858fca3ee6bcef6bed0ed48a877ee4d0c758cae7394d1fa4d65e6fead01c555ed81e9757641d48ddf8ca28e3a6448e67eb0daf3dfdcbe10a376db16063c1a3c48abf242a5ce4e65ab7d3e535339e5689017337b6051820045bee408764b4578c6d0d7e1e17b9bf537912925cad18cda39c8402e3897ed04ca387dad9cc68d049350c2b9d8440f4195144c5704251e5164cb969f08a4ab01d230dcff7c769a026ae57fdd36abf805d114716a8bae45c099994eef19abaf515a0963633763fd2c42f4fce201ec61da3b5dd9d2d89c62b9dc8dfe0ae91fd52b67822cddc9e4604da09865e3a5f9db7e19f1c13420b07afbd84725095ffaa7f3f301937842ea821ddba3e138a0e2ff251d03830a885b5efa7f38492e376f610d89af18c7878e0e179c587d33c2e17241a570496e9ff8e0e980d8d7eafdea8f6cdb92ce8479f21d0a45855a41f5f20103389d3edcae037113c6777bea02de2fe919c021476b8ba937d1272dbdf038cf74e5bc7c94f25e85a8314ab2c1ebcb0db37daea22c2411c77489425be5a37509fb21dd995badd07c3c0cb55400f3df5253d856068a0c643ab1599a30844664e0c1234663f447a1d6eed317b362ca8574e724c263c29221231e41f980c8a773736572f282b5818220e34ee47ea2266f9291cc5ed376aba26385a5252e44d05a49755b1f7b0856f855070ab9ecb1a9de29a5b3920b3ceda55c0aaaac031f935e563c50c840f9002b49dd06fec768a9a258eec5b6aebb997a9e2fade8a95fb824c9fe7332528e62b23d82f99cb9e13e9a339f1f086a7a60aace5f34d2502a715df1d1ad9ce421ed1802f6acfcc96836e481a9f3963b0f28f5ac8381f83a7447e2cfe35f3f95276d54a8143b458bd195cfd4a2b474923791e8edd3ce383e80c9a87a258734656d7e82cc26aa4f038bff3d13512ca976408466f32fe5202dfef7a8bb8aa0b24d798191d8086b5a3ba1742f2c105439c58ce3288d19aaa535818ebcabf73678f27856da1507aea1df0202b01965042602c582bc9a3642ce2b04d4b0bb4fdf3d82fd3c4f4c99ac960530b04bf5fc3b885b0a5fc6fea3103ec3649f40ee24da9d140ca64f28cf0fe98d57f72fdedd468b27601cb5e34d34beee6151ed6e3c452925fdf6b9601d69ae3c36e9fff6d6a1b6af87b9a09c3f65e121e21d6b5d02e068098dd1394894e472ded09f085396a4a71cac238a878c215e7a955cda7f3742fdd1e2dc4348f9abfc46df4650e82373f08e08dac0a59ca8ffd419ca2886c891e88e41ceb85e10c57a915f14c79f5820ed8dac9a6bde0ad419198efaa1ce3dd2f30bfc82fb37103e7091d75c23ccd5b7d7fdf1ea49aade37b3e7fdfd9892597be68b47c912470b518667c28e7c8ed0fe339114bdacfc4b61ad2268929c0e3d49e77ea2a3a4469b79977e928b4deef31617f8d97d879293318ceb5c16ed2df4f1c0a7259786270836ed39ab184a0390e0d0d084c5313f9cdcfab7490c0f8df7f9fb8d2ba658aaee470524d96d90fb51f509ca6db5b0193f817707b6afe3faf49779c95976d57eb710498d9e7d4e1dbc7026a19d079bd8175ce4f98d07462f1ed85fd34101b213cba0cd73eeaca9133dc380031f6ebdac8f05eb29a4f22ba34e1a6fc29e5aad9fed9a74ad8ebb6463858bd894e390499d715c5140b5cb342effdc7184c53c33624fed2f9aa05e085cb7d68e7e3d425e6a08f91dca36e18c8061453bd980f41d85df2924f3903b1ca62841d4545f8ad8a4949166990499814a3db50a62730c88ab592be1209aeb8d2d5bcb3597d5160ebcc24e8601900010fddaf5842745be0b72359e5b90e6c11bcf5cad521bb23fcf452dadc00d83a9cec6f24184e90a3e35eeb3ec473cb0a9ece0ddb5418734231a399728a09387d82acd1690a66acd28ccde630704ca4e7d232ca5d37eec3925a3874581d181b7391af5d0adaeea556515a2a8e3b164a7b85adbf667992b6bff10356b3c3e085fd3d676d90bcd741577f000000000000000000000000000000000000000000000000000000060c1113191c""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +f91692cbc904c6920af9eff6f57b6134b45bda6ebe9ae873a39c1e0f4330b9bf87aab1b9261fba98fc8681bd292e3e83cdf26046b01439457225d4fe957d9fa30e2edcbe49c1e920e9b4e1da4144a7918c575673b5728a3317247c1c38bbf42ba2491adc298d3f93d9061053b72d2677a5b168927d1739bb0540b3eba64ad0ff3869c7ca75bcdef3e697ddd18282f7e31622773f49cd2de94e93ee48f947c537ab55ae7cf18455a3b0ca3a933b562c51515beee14324e51416669fb931e4289e73ad6180f11994f5202af25df3c01dc9d8aad259c310e8bb17a77787b6492316c1b38785e127683653c33df908bcde08f4d4dcd56f70d44f3e37cc978019d04ffe2b2d940adb6e12197d951ee44b1c6219d4633f750066e86d3cbe36395ebf0e41f124522a6bd13f6ba9e95271ca11e4f6ed4ff76c08b3d3449ef64585ba266255b9f331d0ef2d7ee81cfa9918cd806b88cf3d1eb2e2e8444238d78929c3bb8a7a46b54b346bd0597d9bfefedd0d9267cafd84b11dc0793dc4bc9476fda6f1ccfb0c07d494345b50859a686f39c3aa487b6709790fad1688703c27baa9c783b77a07686c98b66063efbfa5a8de3ef43c59760607ef2b775396f096e3d9e4bd4bdc30a28bb62dbed11a0f9b02c64c1b43d98c2da2efdee1edf36dd2883a67c619204f0a6317899ea0269bfe5c6708920401e78a658dc4dedc7b35f5249d706f70c8b6e835093cd9b7dcd3afbcd8a94cbbed4600d86d7019a9b96d10a7a0bb4be62169195ace3dff5ddaf4c18815789ef97bb91023a33c3044f14068553913af1726ab597c534ac7011cd018f4a85b6d78648a3a1e5ddb20bbe862cd31b603bb275738801de06fb2133af9eb60a38daf9591c03a6c74c56283f658ffe6e0758c3e732bd7c0dde78ebd95d71302f3ac2d8f362cb8dcb5e8df32924e4c508c2e0166524e9f183df5933623ad00019730d2e8586a14776daf9d72dec6e3643aa32ae33fa5657bb00ebe779e4e9489abf8f768b181826617893321310b72e58f751d7a0d85bf68ab81daf73389700b65f8d16c2b075d1ed4e8db23619e960945978bd2db49ec1e17a9b7dc62c8037f20c45090d7482c0f66a1099cbfaa74669a2b7ca33e009d2a74db56453bab247a5bc28454435ae4196d74749904e790bb9fcf0108a471278debbb1002c5474040be81778077d02595a6b55123fa463a84343bf3501405b84fcf3921ee4e58aed85b623b14ca1b921494b26cb1bf53f5129e1f2184dfbdcd6e33675c09b4b1af71415849ad88c8c8a39f28300aaf8eb394776dbe1f2663014521011e41ed7fa1300febdbb59923bbaf121bba4dd42f3811e5d785c5512cea5e2fb787b26238a97845a9a60402484939932a183995fbe89b34120a839a91732bd0e7ba6864073967bce180af23f6ffb12b7e47cccfbd32a52d28a4acacf8e7abffd727e8c586c93e72e246f36060e88bef41c42a4ee0fd3025e24e739b6a648cbf2211d7803f9c94e3fa4adda936e30813aa9448dfed56b8c06695ac3605fa8754b4e6f1308cbe5237e0706358e1fca470c60757b9880f471f6655d138cc1dea586fb6765b6e0c2aa4cdaff60a6b2a696aacd5cfd433fcc6331d2cbae3a0f260079b692055012a1b684996ab5fe9a12ddc6b6a04437311408f938d634be38437928406ce2fc62d000e92398e8b06ce73def5fbe7d9f3f0e63854bb65269c9fc96590cd312d150d8447444c0581a4f6f35aaa90e1370c6b676133f2f78f151f223ca2131f2d561b7d08f4f83b255d1b33b9845284310ed342bba58e1f3ae9b5285803c7575b0e8c9c3be2fa58ed1025d9e9ca20ef203e9362222ddc0009a7e33dffb4de33bbd0a0aa7187d583cfa935ce26890f63f97caf2afcb8aaa482b5b6dd0ad1570e6e008b28bd9679046b9118d187be2e7f7f8ad6fbe10094b1fad46f78f372f68fd870566afd524e39216aee752ff5f9fc8a9eb6f5adae11ae83da416b982408376a99530f1bab6119f472a1d45864e611bb2a474342000938b5f9612d876b4278596a00d3db2351ea296fc2d606ba494b07b0dfe846b04f9899af02f9116b415279470e35663fe7e32d3ff5a2162e9f10b1fe42a5d04b14a55fb658e86eee8ac3a2ad85a1171a9e001a7a3bdf834db3192c5cdda3b08d31fdaacd3667d3577d40e0f79f037f4538de224dd3ddc62232e50e61b2f3de62823d58437a7c7462fee714a29b5cc366617fd12bf924f86a3308f8e57609dec2031fba77b52cf2888df554f814ee984f0108e55cab728c7af61d1f4e4b12ea7d027788ab973ecb10b7d668c3e77f7ae1b4b05ab8cdd73b0722498079a246ebc7eac75e831aadef51153d9ccc0cf5e82f7c57a5c57d95f2e0f623c24e05a3e8497e3937d9b8d095745beb6dc6c7a9d20d57f89864088a1bfb137726742e2a82ac544428fed5725b4e78ee4a9c66ba91eaaf4dc7c6c7cf23a37ca8db3ce626cd0c3fb086aa2866b6ad8113e2349908dcf155426d1c208467bcf8eccbfb74ab2e84a9de986b16a3a4bbb822f5dd6f9fa0ac93c4af7b4b332b0efe11e66482215102e0ce72617c1ae45d6f5fee32b27cd5bb18416f3f6f11d13c75be821dddc55df6c5d736f44371456b3827cbecb9d06d19513b8ca24dd0ee4dd31e9a6ae9d1b1a10b10e5bd7acbcc562449da200aa2ad9b3c4663b1be48fbf0b79cb7ac43ffd106699301c4412aa7ada34d1166056ab6cf9e0daa73240a3b0bd1267acdec0b04d5eb48"""), TestUtils.hexDecode(""" -C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), +DBB70175E063054DDA24BCFCAF671F820D674F1D09CA173D4A1440AAF50F1FC8FADC1810F390286AC101D60507DD285275C6F97C0D2B2CF3C7F50609CEC64EB029C3DAD8B9954807E35D4836BEDF32501D0E7143BF488CD5B4D1A53C980BC70A3794E4392E4560E609B9C49900E1C56D319E1495D085440DFD081D1A7C52C0A8F64917834C64EF32A441C9045689DDD2EC218F58B3BD534F18309E1D780528D3BD1B23DDB3B18FC1F7C85324D45C3E9B25961FA5257EC31927CA35DB25E6FAF7669D60952502680BC7B5D777D77B194D0CC40372FC8F711EB048E01BBD5676CE3F2A9FEEAA4B5F29081C34969C746208E6F2329CB53A22058C0AE0852B7127FC4C74EB3A8300403F60B8AD1F95FD2991CE0C8CE452C2432B6422EFEA8AC0E1B53BC994C606301473D7855EF86687287BF56B450D2762C5E03AF26A987317C4BFB013A6BD791EFD141AB34718A37D1DCFBB63014F7F92C9E2870DE503452E271E9D02768357E3DEF6BAC5A0F0444DEE1FF5AFC79B3562C12696FEA15815B7D9BAA38C66919D137F82FE36B140B960E02966FABA1EE9CBAA04941396D665DD2C6B0559502577541AB0CEB066E066553A2DD407354123DF14F4B1DDE6B8C34E3264161796F48DB5319B3CDDFDFDBF5CE17BCB5924984143839B4EDDDAA8F0568ECCAD253C48D00687F9A07785A67B62D28B86D70E511AE08A525F66FB15AFD112C184785F91E76852DAAA3E78CB96E20249F38979031712440DB723B022E1323818431B897DACC51400DB25635EEE41761089DC47E8EA56DD0DF60B56FC682D000E9D660D0CF38C263B716359F41F3B190D201950E140D67F50287C09D2008664341A829A074F9629DABD88BE69A6058900DE5782CC621A91376E5CA31C66E3C430CD00FAA83BF765A2E6B2FCD20EEEACCB996FB5C4B63235142BD5FFB4390F8CB95BCD5853D0226F931C38FE972FBD0D6E10DC2CF29D1FFD2653CACBAB8B81DBE44A2B8F1C5DBDA7C56252E4B35888DFF7808B3514F4D7E5EAE9B51078E8D2E600EC57200FB48EF946F021CA8209E7DC6443B37D7281C73C6A3B43AA570398E62CD5ED9A34ED23AAFEFDB7DB3141202D940C1411CEFFBCED878C0D325E8CF7FDCC520CA3377BE97855827D2E6F4EC8786EA1374E006539387924161D65782C7B2C262AF9BA8FCFCB5B1477083836129DA973AB8B082324F74BC6320646448DCC8AB56582EC72EB192D3F72255D85FFAC2B5C62F245B73191A9176BA5A9FC0ACD3AD48D37E23EFA0C65F0423AB5CD0EB76BDC035112C7A118ED47C0E67E510A6F7A28F26C3D6A882EAE74BAE6CF1FD969FEEAF6B36C85F62D40CAA26B6CA98120D612598F360CA2628F6FD608F4E1E290B32C90FF71E181D4B72978DFCD189D857DAFC7B2AF8C958EEA6894ED59AD56B9AA6F83092EFECF9EC4091BCC9B8CCA245C30B54B9B8DFF3636BEFD417F46DDD2F6136B983CFAB532FB623FAFC3CC4CE8A91434377F4DCD1607BF04E431"""), TestUtils.hexDecode(""" -051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") +5c796ec117395c38a9d7fa1a02d81e3b51522aebf68f3fff55cbf7d584ec75e547d413562c4c87f28f57433cdbe7c96644619b9f03d119c7f87f0a970a46075cb8c29c506f67007470bb4843af6d3dd1c91bb3c2c62443eb18a69e675e3711a08dabee5cc1a03d35a1399755566dd2f07084a9039c7710ab57b380712b39cd6f3cd2098225785665bbb94f3761d5a8d431cebcb533cbee5afeba6cc877fbb168009b3f05f9829606055e71638b50f4c6a41b0b226134391ae0efae4cb1d2e31c782b55035cd9e2d0bb53fd72749de022537ad8f8ec49a297f9bc81d1ee0f5e6b96470d30d6b78f48266eea5d3d4805028f90abbe90232fea807b50323e722a42fb455f02cd2c6f5d932b9bc606f9509fe2b1c133eb12de12db0206d78b49154c34adfe204fbf5469a0a50301be999015c5798c567729b60b2690ed93db0eac4021d38665a3a7db7b5ad55d94b8cdc9171a00ffa3ddbea750e83e495f7db132fc253c82b6b901bcd00fe68f0277988a1b0b2cd1d051d10ee189cf971f79ab6d1bb641b1f3b160b4a4d095144d1f9ce0dbadbdf6955622a8b300c69ae67dec7f1b777f0266e71413d57b454cea0dcd8cf3c32b9bbccc36e1eaeb17c87734afde3feec5432a18ab9a7c6a1fb30e2e84af2c367b4f47529bf4e0782a26d41520df8ac3cad44d4e792af7f427c75221e4a5230e282bf938a6072574e23f4cd35aa49758829d521360db34cadf94f9ba90d5139179f877723150d4d6f53a5300ea3e26392399adb258bc8075cd19517cb70ed48ba9c61e5e5f3d245d45f44f5e6e033334dee3a95bff8dbad0a1f8ecedb431cd52530d7c2d06ebc8f1b80e5e30e746f9b3b3fc192e359119170e2216081dd908d0a5b03670cef41420585653521ffbdfa58957d06d7a0ed23088a5835690df344473f44b6213fa10832539197afbb410556b8046e06d814c2702ce1c50fd5677de3015575e42b78aea720270aa303e3a6539bf343c52ff933aa238770e7fda2d0d0702c1c7a829e798b0677c1044a7e4af1df817c4167909c158074a9933f364a1800e76234751e7463c78255c3d5189c2a3cce7c2e55dc55fe97131cd4255d92b3f9f5c888029d4b92ff3a544e25b80ac12e73c9a65fcf0b755ffd0a497c6113897ee8bfcff0dc8c9bd583af6fdb71523be596bf0753b25b47766d5be895dcfb63d7c7d9f6143efc509629d310dfff428a1d5328b5307edb41822695f56a09ff2202567ae1b80318f827e0bc29c5df5e4cb075f1d7c1cf2df62dc258544e3dea90239a1d997e52e568632e259def0bcdcfc6f9306c76558dbb30a880d41fcb4f99988e6a9186296e7a5a31c7b910fb2624a0400bbdc6fe0657865a6537131f0b0dd2f56e2d6e2201a843bef51916226577e6bb0e891247f93b5bc36c49fb37e458d363762c12b4b95ba75ac1b38f177fca6515c240c40007eeecea8dbef687a77d3c09f9b5bc5450231ee83294e5a8d0fa79430fc2e701ab39d3bd891e73a695ac6559d8a8b4dc4a6ceb7472ad032036e4aeaff3154099a6f2e8297c6e4bf121631b545b472ab316aa0a3e1192874793597e0fa0cf173a78507ea55b2ed0c13fb045a96acd9d9bf8cd5197f968efdd359bc4449458ac42e2efa187190790de076f56445f92a79be0469efa11c98992ec82e3a2ca311d76e282e91665f5659be663a33139e80952b444914fab59910ac08daacb6cfcda1dc75c00077391e2b38ca54c1e056968c4c41fe7201a3c637b37f48be5672828d5f20c06bbc818332f48e0a4c0cda579d4c114d0446896b60392bfb66ec8e4eb5c3e8932259c423025da0611e06b34209f35413be186d98f8494d18eb0b2d56aa47c6d72c5b57e2f68da8ec1039dc565dcd5c5937ce1d358d6c83ded381060647ddb52badec80e92a98dcd4be27a5990c85192e2989dc2553e3606f6e6ef8353202671a1f2dab2d3130946254a686121a26a29ac8553ef5a58d31f9607bf3912fd4340562ff48b38a12b7f4d8ef2e058c9c721467e0787aa0eb2ff53ffab5c2b3c40f52524d8ff1cd0df1edba1dcafcf983a9e8e9840ef269f9648d3ed8e7778e086bcb887c54e49c8848d21002ed58f163a6888b171a945a9269f410b3d541b07f7c83c0e6b80dde9bff6c3f6da1f780f52ce0da11c196c0493b6765bf01aaff22e44f2b538672b4db58a616e2d2a36b1a20a618acb6e7523546e61c8ec4b593407d0ccaa0ca85d2db46a6cf188939ed9583f591499fa436443287fda7e49602dd8677f171b487e4fd6229de805f4693fbc8f27b52f283fb0384a2994755c5a6c0ea99a8be6f6f743d05b75405f9e70d68d4904b258d0f5f3ad0b23d62767d54ec493f15bda17b34c31eb50210788d38ccd4490e0b65ed46e50875da092c35b0100aae8bc387ad595be005bb52ad0f3281ac662305e0a62ec6254c4e091b1fb0552398b9cdcf2c12069b90b6ca5d67ebeb22b6aba91a7ddd85ba31addb18ea61d98429e633e5296eda442264dfd6bafdd3f26c9d6cfa7d8c89f273c4058c7b88ddcf79d7cf5c8bedc4ccd69c4b545a0069906c12c0b5dd5514cc1d45a50173c4f51e0cb89e2e56025539394be823889e0b7cd3b2563f756bb6d95336a22a1f84215915507708fa18e425a6de61a7ac74689bd85bef8aee1a48226a96ac318bb3d8fe95be46eebfda3662e04741f93995e5c30b1b3864feae3b476f341c473d449f3d675c3335617a201e992e9e96d35640d0152587c7edf50ee5542164e12d268c0bdd808ebe067e4891172a4d765650decb3e9baedae4c39834b5b6df1c8252a9b588c30b25167c543f389f4d4db14fd1319161453311572c85bdb5fba5886325b5118b6bdf774c76fce3de923761e22054867a19a06e2f84463a737ee6b4f42cf97e062db911ef8dd2a6cfa15a4698ab96c9e70c7823956665386aab0ae235b485391542ff57967b67274a4a308818ffad47b82051e674ae13ff73a111c5da089500f14c7d05af77d777c612628b157f3a921bf8b0cac0fb426866833ee35a2176653dace88dbd03cbad446bece7c6177373db768d561aba1d86ef2a5680f5d71e2c4e35832e8ca69de760893f3e6dca2e9b39dfbfa2bd4e1f3c2f5ac06e7b07c9c3c85de16244a273385f9014263614cecc9ba3bc1679d8b2721211b7fe7fc96612abc39312d8d05dd530e9e6f00977bdb27b0632eff254f54213213f608177334ef02f79cbcd5062c9b50f9c3ab14a8fb019d0c2b11ed1a5f93d769d3fa14eb3a7e2a96c738d1a3d62dd49a5dcb34ddf6944c066ed1d4c662752fbc961eedf9606c40922c43c543f6c79cc4e91432d652c6ee492679f84ddf1e1e6fb885af725a63168a6c6eac8cb180fc2b71f8d83112b81b168e96e42d3f069b69995c351c6b2bf1344f98c5fdb2f3fc503dd6ccf5cbc9a1bbe111ba2380bcc2392cd3726bba4afe7dc66a103a2defa50516d7d0d5bd058c7361bc6a81379a6c48fe76e81cccab97af3cc2a96d4abd8d5399c8ebbec651320d66019aeee16dd9e126a4f6b16ddea40a36f2ddc9e5d91bf8d5a39cf7069ee917c23770c18c54a5d2ca8f23ca2c9d21f9003b7381c077b7607dd3e3b0c34cb12c77ef08547501085370c6225e45c40069c87161bfb45498397c5d714c86442cb1489accfb34531a14199cf29e0e611f4047f22d40db532956a20c8f5561d9c6120a80507c525dd8584d60f41e999686096454475a2c92bef5880e554a09cda2238323fad2827d9ba6cac319b01d2f89d708a593d660f9c19499328167c5843ff20a17bf0ba26c8418fef3ad764a865f471099708048a624c39bc7ac317badb19226d8c0943e0fb8aeee9789c0ab6e43f932621e89c424da8a6eda10b936218264161433976904836c0c913b5a0f2fcd701ae18ff8309f583f75946a02b930c897aa85ccd239ce2edfc7dac8689b8e678b620cc853e5dc57fea9221f3c5ece3a1484022934d9457b6d3a34b801baf8afa4adf307a8c7b6092168dc5fc35393f772b576345b2f6e1fdd9ccf27452174b8ef6bde9cfb37dfedc43755be905373f54e13a1a40c3757a15bc36aa21657ae4a64a16bbd4463fbaaf69cf4778306876b62abd4305d753da808f0728c3f51f838b640be0c093b732595b153e2615da3c0d5ce5801322689ce85f91767bcaeb81cabc3baeb76deb7154b79528766282bbea6d026687d2f823fc25b97ae523e1eecdcbebf460b447b1a2e677c0215fbae2da1dcd182bcfdc912b94c732b793588ffb0d1e118d02b093a3cffa510d159ccc74ceea63ed881ca79957dda6db1329c22c10a082baf48fd6a2b635b3f1b896e77087734528d0943da51d31b1619e549ee1366e9df05d0a356aae84cf8f3d0c8fd5ab534a3524be784eb0208501f17e3b8f70a52de886bc691db2bcdeb63f7bd739fa3dca52e4d44a7b6b57564f17076104da5169b46d47bfd01d2610a9fe55129e6249956233a911eef491d9c5877e55585f62f1d17a84bebd25738d11d830c2bbc5b55d7fc60894f4db0bfcc6639277d290ebffd8a02e4d0593f65223168240e528822a90d4fa94febfd55e5562fec1f279af1bf7333d5b8b8eabaec3ea262a40586d8ea1e12b3b417789ed00010f333a787d86ced10a233e7385c3d4de1c3450557ea5000000000000000009111721292f""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +775194fa9e30c689e7302d8c2fc00a7f00841fcdae64e399a53e0be695466306a8c2bcff2f1de6a5c7b2034f2581179849bab2b4166de1c203dc8c85878e9309eecca9cc75283fc90ef0e01e172630a1fa8075644c31e94da3d541eee7e08a1c3bcaf746798113c7a7d70f4eac26fdc630b692bd734e5a65b913133dca7d9a432e2f1195d4a76a6a011f2577a1699ae37852fa0ece9f007a429411282115ac4d55d1e7f073758e8dce2d93e2e81a857985a6567d28a155a0cc1dde48a3abdfbba3e562acce270827c77421780fa60556ccf9764f636cc54d094e19155267985d066b8af7a7cdbd0e76e18324bd77d92aa27795ad2f9abb5d68d0f768e1b124189b2078d133ac72cdf4d9d697c24aeab5684386c81dd11f5bff5039c0da8fbd0143278660abb563248fdcbe666a708ce2988ac38891a4e953913fe544014b4f05f75a92b14e29de39eb008b6b23875bf02076518036aebe85bff546d326d9bb9f7226271f5f6b655a8824029acdd548c075107e8316c839d9e4f94b71ee49ee62101c3dd49960eac7c6bb9f113bc7ae4975f50dfed974dcec3bcf3b90c77211bc4304ae5a73a277732ea37247ae7410858cfb053316ac2426bad05c656c6fae3f3c762b384cb6a3626dd14006e9621d3615249a61e39d665f516ae5720ca55f5a52aad68e5217a0ea27a8a02a4c502bcce7d9f80d5ad0ef395b9e55bd2b6f0fdb12cb7817908f2907f8a625e65a13d7947f15fab77009aab91ecd20964af49d008d32fab27589f393a36c088578f7b8207298cd028731b614ffe2fadf0b25b940cddc8b7d80c3885f437789d5bfe7668d51cdcf0db684fb4afa7506b828aead4fc51964af184c63e94424520c99a44ec01c1d7074d09ff0bc8408a7a6cc9b1d6af804794c4d81f71828e3ee97901f92d4a8ce677744492e15b2499ac9424850bf89126d8e7e895fafc2581ae1b593f9bdcd1eff97ada3be693eeb7316a6b41ae9cd719d7e1b0e9f41ae109a15ce1dc9407d01941826b7523e2ca34e8ca07ba1e94ca3ae63207c6185378dae26e4c675a676406eff2e89eccdb516059edb647c79aca7cde5a17f592d3334346b3148b34fa723f4a005a0d16864128560e805db41c6eae80fa1d8f0a07ba509baac7a10d0d34eee421a01a4d752853bf8cf5474109dc49d0a2e25b08cf36481902f911031fef980c5cdacea31f22949009c540e033e21495e740b559b3065a1ea6cb602979f331000dd442124ef0b1be09a4bad6668ca435c34c2a20ed8b254b12bf84992b43159efaebb5bb34a8cdd692c41be6c88dcb42e802f01d3a1ecddb061ff829487a3f5055c6aee621a811100ab764c7a20d662af257bb0def598e59b5d7c3f8729e5dc55535ad77e611fb20662a30f8267d20d8f60614e2a71585dd46b6762b93696bd012ed319e7c8f65c253bdcb977c063499672901214616d8f699ff0b04fc074384c648014f15225e5786fa1534cc85202db0213bcb1e494fe0da6110cc806f029b27625275f9b5bd783e86e494795fae430a042f90485cf18adaf974344d43dfb5ad13af1144e85ee57836702b2133774451a7d51007370b8d621f155980a417789537f7e1012ad2f9c5e70a579f7affb84e3a41cbbf33a1dc197776f816dff08e2e0f7e0537f4fe16589c66fd28e36feee9fbb959e269fb919f07ac55cd424f6570a55bf0514b86db71bf626786d6ec56073151b97974ae857eb651bc6a3866ae5fd61fc16ae29db7996d277b7f6c85b3d78928f4c84f0789348bf122768e7b17577667ccb5b7bbbbe5373e1b5aad9c3c4f7f3f1a96d6d4e42ced4e18760068a4a667550bee909946e57d5fdd66e92cf2bc195b5a2b2bf0214210640891a71f7be9aceebcb9cb463dd8b02190ad9aa006413c2784d468a2730ec70225c2a8eeab4c12bee8cadaba579c3db5b3f4dc210994e1bc26c8c548b9ca340a658368a405db1efc98114e24f2cd20fc8743261a262fd474ee6c7f254f89f0cb6c16161202342a8d1aa31e7d8a829a7e1c980a62306e7a3032f4addb96582966b56b37818875a14aa80457bb281a87ce72a5f90b0b30ed57cda8146f9dafb2d7e8ae79e8b0067f3323337c799aa849779ebf718ab52b8bca6a660795ae5a4adcab49f9f5555c1241100962d2d8f1c78a330b5ddf49bca2e06baf77d8480fe32570dc55cd009e94106de4cbcb6f0efb3f9b41308a5ce341c573ef085735667ab20ce51320df124806e7afbaf9cfeb57ada0aaff578056993aa5fbfdca313b1b0142e9159f89f25def669c8846feb01d2e06c6a1c1c4faf302330fa223ec9b52ccb85e284a98007e61f889bba87dd520f2f9d836741d01112928363a1e968cd77108fdf0b8624d5f01cf4af2354377e70c61da9ece5c40e8bed1b62da6a3c9840975bf8854f075812ec58c4d814d7c0d0686438b5d9a2bf273a54be6930e336928fc04657a17865a073c6ec72f8eac813b9e944edeab724185c75ab2910ec4a9b47d7abbdd41865936fe5cd7778bc0fa0db378c73e404c96f093123b183e5d9da04f157990bd3274892681d40be1387f96776a272300f2b3ce6d581a8faebbff01e6e0d5aaffe8f4412cd7bf3e593170dd0e3fb42cdefb4201e4448278571ade12a62f6ec6240951ee8e731a0f600c7c008900818bf46a585d64fc47d9897abad71a258a35e4ddd78607b175b60e3732ea47ec5e06b1cd47feed7f4116cee6e0c815bdd06e72c9206700e10a60deb5f2a7c03"""), TestUtils.hexDecode(""" -62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), +5F8F32FE68B556ED1D2EB8D2BC20AA36DEC7900F8E5D4BD3715419B28771E5B0A080DEB2F3EA6CF415D40EDA46FCF8A439954471B7308D3E4226E9D5A96BC22B08FECEB4C5E3CC2239473F1C9B8DFA5A29C31D499CEEAF6E34A396BF0DA53B54F1AA674056216756DFE15F669FC2E1D8E6F67BE5BFB3D5703F25D62D3AAB0398AEDEDF7C65E051A4A8DDFC725EEE940BD0D06B103EEA32D027CC20A8C61034DC54BD5533CDB1A85107B9CFF283FC3C5FCD9C3D6F8857560311AC2E0E31585E77D0806F9A4E61A70D3FF36895ED447C55DB52002488045CC358A39475BFE8456F4FBC36005218B2CEC1C573E41BAFA7A622EDF776C8AD340680C1B3002F69D3B3D8844494EA9F42D2C9C9D2BC0BDD850BA3C4DE929C1DF49351219F95EA7B9794827FC1A1BB4A6A00809393BC41852820569D7BC6FD55339925FFDF55A0C2655C85144234FDDCA91E8BDCE8CFB7199330763F5750D71CA8C4B3BF7E6469F5DD68624BD6D5B69E5FAEEE53E3A61AE659A364484B7D2BC8A85BE9F8D35C8B97716E8202B610BDF878C1BD83187F7892BD861C09FCDA64606A185B93CD2F601C3107D35B38D76D75AD6023AFDD95E103EEB7283379BD9E44CABAD923856A599B719A18FA836749E5BA95C79B1F2F1B443CE1FD26CBD2B74A0156C381BC270B74FC42DFF8D91DE4ECDDF3053007A09B8E3C964B90DE55DE5193F218685327D8C0C6CE3BBABD57DA8772DB7CA9234A3D19BE16A895E7D14337FD9D50B4A556C75A9D287B44BA5AA4E52C3262218DDCEEE3A7BDBE1B8175E84113F515623C07BAD4FC0985112DE4D77D31290BD013562D12FF8CBC5F2BC463223AA82991D7D60E38037578BBEEED70631CEADFE49823EA3D87EC384B3FBD4974C474FF9D47F467110EA4F3FD94B5FF38D8FC1C75392896394671853FE71DDCF7730C70ED26485F395F180D2F5C31AE0C2C20691CB4BC81356225E6A72DC72A1CD3502E42C22B594118D131BA5EF95F2C18B3061139B047A24E32197F89780B91D36B28BB5EC6C03232A3CDFC5ECF687BA5701F3958FD87FC0C8D09825E8BE4E5CE9089C674049C38EC5E0FC1AD542F57B4770B6E5DDA215D319DBFFBFEAD9141647A508E271CF3B0DE7C137A5AB999CC88082FF0CD495F1F1FB1E367B57BB400D8697B4620B75FE467D9B8BDF9400E14047576B3AD6AABE0C0714686015B8A963A0DBB68CE9E41FFBBDD5A792920916538E4C33F12EF0E93D249E562B71BC1C252E1DD8AA646F8C7B489A2BCFE7D29A6D3FDA2C21DDD78179861AFC766F6885E9959F753C66462DAA6E01C8B06A6F581104B583F7A5B1B4935A4EF08219FA8D114A963F3FF3AF22C3D1C1E3927AEBC886AD0670FC89C08FD4DF68EB990A0F7C51A4439C32F5F51785B20DC82586940C35D80A91865C3154D6C925250B24D4C1A9E76A267711A0813E8CCD2DDE9748FA0464006DDBA963BBDABAADD377239442DFEC6F7E8098604645D63AEA080C1F749CAC589F77B4AE0955FABED757E6576966D539FE1BE5965D03882279B2C9B6899205C9DE8D0B1819DA8B5426E573CE785FEDA3BE95A18A667AD5AA8FCE7894BA11A44B266EB7571A93CF9FA64C1132AE07F0F24773C83DED2C2885D415ABD96A21A0381811D66952252786C39EB68EF0B9B03BA7E2B66A49BC6CFCD8097C321A932E5CDB11EC6E43A8E50DDE01EA5A28F08F5047C67C988E8B4A04701A0237330598ADE8EF8F801A07F2148B44E593B0ED16DA30BF37A341073C6A92066645BD7042C3A59B374FDAC00F7F69BDAFCAE5EC0AE65FCFB785C93E49102F5A5029876BC23B0FDB7FBBC376A9E834F0D19A276BC4E22FEDA18FAB529F15570AB674B844703B47D726AADE3AD4015F52D86843A01AD5DF086E07A71A0236765DE6A777F94B1D69253A424193FA9DF54899AD9915634DA23E6DF351E9608219684EC8C8C949E900718DB6FDCD144D0BBFE1079C1BAEC516BF60C1E24B8EE6DC380F55E0F65DD64025C937EA89FD12F0404ED0C03CBA18CE2FCF169F9A1EC9B96830FAD0149D4A90B13446347CE4E5C6005BF115385F1D22EF6A7E40EE87847BFDA4CF7FC3135C4164091F49DD08389E1005271E9AC76E27B0CDF360EEBEA9C08E233CA58305CB276A8BEC9686CDE0E2DB5CFF9858029F3A5A42759E4AC6DD40AF9617CDEB03FB1F9D7F112A01B87A265C4E27BBFF596695F127A97E1558A68BB5EE4EF0F44D20F318FEE1CE988051F3C09AF6E142932EFE970C1B0C07040E7F3DB9BA53BC4AB1433F7A4F1E480D920C23A07223D7E43570320B3BA590507D580D29CC3A8C85A442BECED5880350F9D2B1AB5C746C1B9909E446D9508D701204F2427F41E043A78024EE3F60EE19B71B5BC925A2557FAA8C7BAC7E3405C920FE3FB3A1BA7C559BD75DB1E4169804B6627AEF19AE6E41B8A40CFB977C1AF53208F4D775A48C220A756783F41E13B7780328992947D215C5B5682DEC76CB035B41C007CE1017EEFBA426EBC423F710C1E962528F7636F200C2E79D8377D621513BA7EB3EE5A0DA55B81F6039D2E8BD42EBA5B2A82C3F033CFEED6EFA7D970B1460CEACD13A0C67AC0A7EBE7963F0FE21D20B2A82EA922FD889253B5D4CE4D47698D43AC11A8F4E1638AD3A4C179C522A3ABBDF420DA3E89B9FB7608822904944CAD615C62B28EDB15D3826D33DCF9FF9BD5DFD8639AF4CAEAA55F9F8409B4E5F70681BB7861F88283218E15A4282E199BFA12360FFB9BCD68D9BE5A3411FCA4E8279562F595FAAE0CEED4FE675DA4A8FF94B180AE9D0C8C687650730F05715820F67248D02EAD4C7BC0D41C880444B94CCD60A66A1C9B5B6F6690A2E1766EE10B5D03AC16F175603A1B9D49F97CF3F91932E97DE67CB523A38839468EE7681909CE997BFE5EEB364B472220403EE4A9AC1F8A4A8F78AFA4D9010A0127C0A75D3CDD87DD269F19A47C78F696218F25AE8A61073644A4F791ABBF1B180267AE41DD44AF65EC6E0AB356CFEE86095B64F4190D69D60284A1EB42744C31536F736AFFFFF186833EBBF43709BBE6903A06F7F06E8776D2AE41CFCA33A3A86342BD11B67EC10F525563A1843C8443546C1EE61DAF7310802AE9C00F44DBE7E04030BC4D0F53AE2023A7647F08A0BC6F5013A61A84E994FE0A20092DE133FABAE3AA24F8F3946812396B0643721AA13417A2423F96CA8A6529B0E17766E88B2AEBD79AA9D4D31193533CE50E4EBDAEEC976F156D5DE5917D54F9CC0527BB4F1F795401210739A42D10A0242748DE5FF6B50932B507057EECF8A1E37800223378642DEDADB464F5CA251D73DCD28A1E3772CC285A33B34C6701B585FC03C94A847CF7B16616D1C3DD646669546D80A27E9DE6424AA7AF6F1694037E774259308E71E15D7408BC1EB517CF0AA2C9E16B802CC8553458BB66D96CBA233487DAAD6E093235D901CF46F31B9A060D88DBD0B7380652EFC73AC1A6BB5E434EB0394F1EDC937E9A99A3867EB71D6E19622137B009D36ED7F9890187CCCE7D884DFE118AB3682EC08CDA8BA6DD4B79C9C18E7438E6914DC1C403870A540B74244964CA31E730A7D7591E42569532DA8094559241F2C7EC182FF8BB5A3F88DFCE3020D8B8CC0D1F54CF67FFD3A97CBA7F5EC79333D9A545221C963E0685763E59F1EBD34FB2394727896CE638E909AE6DFF41D17EE1D0BA036F8AF11335A8C1B5A0E9DC58EAB9C12F46740493A8B5AD0EAA73AF462BDF43CE44BD0973688D9C8DFF8FED961758E1AF88FD5D249FFEC179FE5AA1D135C0448D80F4B0CB68492CA399A3916A2EAB684B44E407706CC3C2F48972BC9531353091F91B427FA32693906DCAE862F34AEBBAEFD30666523EA9C27354F2FCD99A6E810685B51965571E4B4B5AAE158636497B6F952FA0B73617AE35A8D7C272DFEA1CE06E983CC65A501F73BE9D69EDDE6A4A1764DCC4B74EF09EC27C74B677920AE8C49CF4F18160E04B5AE7EFA8D5D92BAA5E4E547CC8AFB9D55F1A9DA7A6AA06626673431889C9996BE0A473702450B960231A617DF4705B07B47DBA1BCCC0EFCD5713F88F394EC4BFCC49EC24B76D531A356A6796785D755F027C664D8966B5CDC82ADE776BEECA8AB0D9DB6ACF5E841BCB4381828DB8F7358A637D04D97598A8B3BC823B891F5EB6ECF54E6F9200C380813FC3210E68894A656796C9A5B780FF486E6A93DE055B8F658FEA17035D9C212D23BB5974E1161E4F6041E5AEC446D70D52CD2F21F1A33C9938032487D9ABA74C448EEB8F8D51169E8B848242F5C769B471F0AF04E965BB0F4AE7C6F7B4AAD4E283DA762DFA49FD01D21887ADB28781FEFBD931AD8E2A26BBBBE5D88B52E8B7133134CA76C6648EA39E3D2F102177F4237219E06CBD05174D503C9288EC9C3E0128A824A7ABF418DC45EEB3A67777F74D6EC52891EAE0BB56DC756ADF40D39151E3A68719C563E99BABCA4C785BF4C2BB1BD25C7EEE22A8B0C1E90B948FC3A691670E9A3A331320CA4416B492907C3FE70AF9A2E765F9607EE1BB2CE52D2DB15F5DDCF59BDCCCB5BEBAC2784FA0896BEECF38C24022046E5DAA7607E8D2DB8CBC65541CFC6A0F20CC3AC5EBD4560BF5E9A3FFC0BAE917B479D960ABFC99EF84A696CE5A95720FED90F3AC58D77D48BD5573A0D85681238AC0EA8F0B58A01378929C691C146068897C5642DE74D79E08E5B94B101182200FB3E2BBFEFC8B44D2D1203075862D77A184B25A7790D76D7CE88C979D73E599C212F04A8B01EC3CD6CED3B5E25487957C56BEF6AB4433FFFE6DBDEA396212A6870284FD1BAACD5F7A5D9FAB90D5DA39D3C5F9AF196D9C46100BF45861679A7679638BBC8E5B5A7606D863478B430BF2C61F52D3D88B0913BF12597620D337DEA52BEE9CC8A1592698D23B23815C596981152C99453FA16800545EE781F24841FBE5A3E5AD8D08F2B898127AF40A681DF9DB68681533C349109C29D19311BEAB4C2F2DE97A5345EA7E41CC0988B2042925F1F9409D947128CE1D38F278863385A19B2CF8338D0FF31B06FD865B9167488EA157C7965F4679286077894660F17BC7289BEFFA93CB7DB990A0E40D998945A77E536902FBAD3C8A278CFE0AC883BBEA0B20E5D70EC6E10B59C2449CD1A0B55F8252C91CDC87E70E72FEC175D6D67BD43CB5AE4EE9C7F9476F4589E2BBAF89E801D5E14458F8A0B96ECF9F080E5150E2A5004C5A89B735639621157C4056DD1106CFC727B921D5890F37051E2B906885C1CA3999C18FB8C9FC9B652D82AFF074EECA9976D612ADDE990DEA418031FEFC4E972B31CBCBDCA0469E3966FF6F97F9788650298DB71CEDFC04659D30FE673602659C19A869FB3EF4262EF3FFA9E3FFAB1A3FE7670061EBB0D49BC60AD0C774913910E26E4213B76DB72AEFA3CCC197CB6F6DF773F86F12480B5BBC2068F61E16D1C0C141AE6F1811B2E0D713AAF60B90BB2F00EEDD4651FB5191DE5A246A4D8F3E9999D85253FA705CD4B94A6A64D9E9B6E18BB6855CAF6B991494A8DF75E56C2A427883E0C27246E5854B8DB2EB0FE639BDD00AD678D1B61D799AC59ADFF6A8616B357A4B12A786EB612E5613CDE533D92E87D51D47D860BCC39687485EA814DC5F5A971EE915C193ED52AED98D7AB301E32342F3D207BC03546460D33B733E1008E48D80E716FD717BA82403DBB520246AC3BC9CB91CC0ECDB7E35E6863C3C11558A8EAE9E1DC49FBFFC0F92F397828A4AE7107785939B96932B9EACB6BC6D8B3A189B5D3F6B0C7A3A413054B25318792AEBA3F4C77629F1E8CE1AAA98FFE1EF50C2E60C11AD76EDDCD8EEAF858364ADD637AB97ACBE4D2124AC0AB559E85229F1B5D81701EEB1D6834FB215984E9DF3847392EB29D2A428DAE7FAC283F93C8FED86FD2377E8216922D46A51E628091F6F8EAF967740B0EFD84F002358D3ABEDA0993DA16D0D8233090A2CD9C27D78DA0A53962FE7DD282B276A30F91C2B734EAD2CCE5E03137205BD97739F6CD75A08491D4ECB22591A6FF840B5DF123FCA7DAA98B11C85C1F8591EB988024C206CDC4A4239E7A91DE75F49541FFB6D91BE4699C0C0D8B4A44A8204F7E90AB863C3183C2270D185643D6A7165C1D043FC5108C340650F38A8FFBB13BE4BE68858C50A2463F7BE998286FFD0F981B45F5E414FDE71637D6EE77B33E10A530C630D63F21A212E844C2F7A26BED4F7B4DCE0C566CBAEF4EB4BDF2B53E743EE13A845D3C7AD5E9525C50CFED35DAF5D993B6377CF1DFC5236D51151B046F4904A02D7D51B6E331754B0E3621DE4CAFC9D8F7247788DF0EA7E6141FAC4B24608282AE29D594CEC0C82DB05C0087AB377D0D504F64F1CBB2D9F3121087AB6F35A70ECDDD15C9AD2A185C16333BB901CA069BBB0B80CB6F505FB3F382CED72CDE60FC050241B1D32818D11AC4421B66CD85D0F7B479C021AC111F8EE8F1C60B2320585EA276879AFE4034DBA277806FEEACE548CA0A5D36CFAE7B99ECB0236CF4838254A20A13A2DEAAF201B09FD027BAFC3F0C5ECA9EB5850A58C6196645F051E57B82AF4B6C2DA9441358BFD2412864950022A07542601631A00E27BCE6E203B1D3F1B844CCBB2EEF71A12AA4E725188073004849A225D733C77C068B0D2AE53E0DA6F759A8E7A5486C529B29A3EDADA69924E7DC200158DB4B612C62039B321CDACE8294DBB1A56ADC685B0B0122A4F3DE0A264F47B00C903BD30B5E4281B0C75DAC5C48E18BB0BF642F8C2CA194AE56CF7EF3B4529FB9271774108C61198A6894FC9FAF896472D1CE78DF00E714045C5F7C77DCEA45B3ED5BE5AD545D8F3833206340A5E10DD3375BDE0A068D050CB4C87E0BA95CBACBE59280BD5CABCEAFC88F5C05E3D8DCDA6B15C487B62B467E093259230D47B79F36572972BB78F90BD384255CFB1E4F1DFB7B5360EBE1230F154C3645A7A233FDDC472432F6C845CE86B078D93A5BBA3F8800C5313593D66A8A103B01377FBC5C6D5FB8A55DC71EB0BC9904B24BAD2F505D6DB5640E914D84FC71FA058902578B72C47659AC07AD4D64C3D28328D2DC8425C4039EFB2F20E3B954BD0B0483848F2C2D9528214514510CB0932F7506E9B98D0E891D8183A907FCA7AEC068B9FDF7F3479A128C6982BED19512A4271D8B682525B5028B77D6B6301181B403E5F62F64BA3CF06F0EDF321114855839E9198E5BA2A65ED952B2204809215B9BA3C366FD5C9D409BD71ACB748E653DA82EBF617D2D57C74CE37BF20AD8D789DA53C086423D86F94A96ABA379F3425554BCF92F82FBBF5C2A15947455D7D7478A84BEC6E3B9FAA14E425D2C8971DCD157C1D9E210620E891AA4304CDEC54BA7B3352556C49A172EAF19919184CA005A526349918F9A7CBFEB83510AD899BAEFD3D1F689DC3F449153597C8D21FA1C7BAF18E689B51F89B9BEF196193B7A781B96B38B9145AF7338FCFEA109542BB1719C9C8540B551A35F733C394F7831900452C0B8D36BB90824699BDB587EFCF5E8410E4ACB8ECAEC5F96E74A5DD3DCD4C85720064A14028FE768041BA1A13A46CD8A0D2C4D09E724591ADCD5EB907038853D8C92C5BA7FF57D5B54B2B324073C7CD2EACE0C521254E9E5C0CA197FDB3C1AC73FA8EDA729A858098E6F5EC11A19D4F655C6DC9AFFC4E67A49EF62D80EFBCAA383DD3DDC22C2A9B7590C16F8CF23D52392186B95EF9E947D851079C35FA11595682DF4EF4D770EB16CBC3994326B8AB3B2C279149122D178BC7B53318406738290596449D797F61B3D0CC8B11750F8D841FDD9D333A5FECC67CC7733824BBE257D40E53B43CCA19C95ACCA8FFF393533AED57D423BE0C38584A81689248BC7F78CB7FA4C94A7BDBF3015B4072B83748E55ABBF4A334AED679D89E2F18BE1B249B3F61363C79AEF6E1FB09D1948610F77A9927AD6D57BEDA02BB1E77415DD7FDD3EFC683AFB1E20C08284B620EB091974FDF8CEFBCEE1461C210E81E86B61F2D5D1882261D60D60689E39C81B981EAEBD9A42E608A34155516E4E385B86BF0A4AA05E3F99B6B3B7E401724D1442A45A696A189765BCA3240111E9259DE161DADB4E0ACFF27818C631A8A2ABD752773A83DC29CD619A58556040A7B27CF56086BD499F8B8D283683377A21BE120374B8D4561AFE781F246AD987E828FB40306366B4BF4C0B4B909ECA91DC85F521ED5869A2F2AD58C74B6C959AC71DB6F11503F026DFFF6BDE6BD70363B5B38BCA0590A5AF2A1054209A36B41B2A671293F2805568400AB282F783C356DDE30E0F87C001D9B1B9716A7C4021928253622F2DD156B3C3038A077A5768AB8AC070BBD9467E9C9630754934186BDA122CEA503F5E274EAED746065CA81A2702B582E82A33CF6CB3917D451FF59B0909E6BF847E6B610DA89AFF98B3323E1385954EDF1175C0C1B158CB905BCFD9AE7FF9389ABB9FBC5194A45DEB0570C58F31D914F9941B0242717B243ABCF5A20676051978C16FFCAA8ED2EA23B8323CD58388860DD64FA39971F9FAB83A4B248EC8161D32565917B7E6EB4937B4743C6C236E75E1747A1C83377FD1D927D385D81A9EA7F4AE5034097A0A77E2D2EB1943D3128BC0134F2D600ABB929A5281C26EDE1C12CDC80F8EAF2E893091EA274EDA1A246AEA3263E43D6C60043CFF6282AAAC620A21B523783E0CBE33F78C89D00EF8920CD53C6EC0E83DD7E1303D9B6D5280BD2BBA26376C17099758F34C22054DA031C86CC50367C81C3059114A71C565B1702981D77040B0FEC1E89436ED1896E93BA202F11ED2BA4EF33A76F86AE8E23B8FD064C8FE894244C97BA7BDA6BB56B7517C236400F591E4F28050C2958A7A79964AF233CFF8655F1603F6A0C7ACCF440D0C82D5528876721434C163D86858B02C6F6A660F53B3E45185FC7777A629C3E4392AEE4A96D900B0F19783DCB6E5028B6E56E160A37D37FACD7C3B992773ABC8AE1ACD6AD41E7340CB198C9BBEA1CDC185AEEB51E2620F0695C2691A29CBCA8E23328E84B6882A59A8C3C2A273CDBD26965564F1F1DF0B2CAF83F30E782C049DBC00596BD85426EA90ED30ED8EAE8A88C0D1363E69868E8CAE56E8DD62CB36D9A15150FE567DF7DC93CE78706BA983885155C9AF05B5FF1D0EBFD9D020BAA9196D9C871236DBEE8A703BE458938D3C882719881BD49476386387DA3508780878271C0DA821BAA1E9719E437BEE6294D8E4E2483932D0257B44B8CCD8C55028B3B7D2BB3866216A7F52CAEBFA0FBAE120609F95213BC05AE24473C98C29F4A46D985336DF8305787A0374098DB279EF0E34E6DD79BDB106EEA24E4DEEAB6DF35C58AE73FEC926174E0942D242AF0D30825274FA1D510D1C0C41FFF59A4381CCE5C6B89AF30C41733EF42E76C9CD58DEA7E881706843BA04E3A170304C551B6C801CAF9B8DA52913D2DD4DC755E0BD7C723C4AA5B001D9855236401C1014507CCB84577749DB1AF29E318241D91C4B23BD80549CD1D6E0D793E966A8A7B755552F16D3A1146B0CC6D92C8C90E97D7EC8EEE7C365697F93AF257BE24691E41F2AD26BCF47D52A1B80F5BE1C658616537630088CB6E227B0EE6EB8DB2FEC0284E58202A73CF3AEC16BAEB59D2A6E0257F0ABDE5926D9A13D89A8B2F69695BA3682E87A77DE06FF54892F56581FB16991654F60EA22856D6FF9E0BE2C4837F0C1F6C54E840F67A75185F0DE9439AB1E37D4FB3E9757B0FBD17C89DF8568755567C390032DE93E9C93E6C89B2E66E9E9D96616919D9FB461F9F33"""), TestUtils.hexDecode(""" -9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") +02dede66fc74f94ce000d6c4898fcf4464b834b848d2bb2d98d3a5862ec632dc9636201321c793ab26e4a42ae4f13debf105d087b112849946c76b54b801382b9727d65bc732a5620e8f4f158f0c1737b0e4ab8e7404383f76c848b36f58f5f9d70ba14a8ebf622bc848a9bc3e116fd7b2627c41ccaea47d493ebc6d3dd167f79fc6ededc36c809ac87e77ee1b006e96ccccafb88d965bc1cc15388e6410c68a74d72b6632487c284fbfc10135da29f29264cbb9ef620c2668066a2fa80fcf2132e93a29383e56c8bd89b3aaf8a905d4e60c6f8002132d38abc3d3c3b6fdc6cf508c8f6a7cfe9f78be8445f00a13414e41c27ba31efc46d0e028b778ca57b2326d624e3af6be0d4cb2a80e44b3f1b83bf572e8b7516b8e4715376e5da06bdb7d487d6a2d268afdf5654023ef4a13aaee221fdf7b9a668b2f4e1858da3c1ae3a7a7279163ca9c1407e8c0fb69f0ddf75cca64f4b0f277acf9c469dcce264b8f37f9918626dcb4252391526ccb4f068879809a2b115ca1d75d7a1ddbe5c8261531a98494ff634dff81515fe3ea4e289d75631ded8b8ada415f6438ada0738bdf9f89e986dee9c80d82ec13aabf10849dad939e81441fb063aa627c4e316461fff15e61c85821bdd55b2cd1545f810c1f280e7852604be73963b75e33eda2e2300196590b9b77cac44d059016c0b08a2f18f18ededd8dcb1474b3e088a6e84c12eb0470cef4b409214eb47de0e277de2665c661ae7766de5d05bc357a2db50ce51d9087a66b1d3715f5be97a9ac56ef866fc3bd3025738d4310e4761b57b3f901c5165df95385cf70f064a760b37341fe2c8466aca8258fe821308d8be08f4d569e27365dc4be8a2ee4e5e13f9d467d8b6ea272e407386e9f448c1758858d038c18f49dd7f60874cd4059b5950b8e969df6a2400a628759d6d7839488674bc128e947594521a998a7e9aac9d61ced0aa7629035bdcdde11a82ebdee6145af1f9c31ab104219beeb4f222e0f0e155e6b67160f09f6ab6943a589bc4ea4a1eb3231bea73f16da8998af58b8f71d3aab3e2fa736f3307180e6d777bc5ad02be4d7c718855177d7c1826bdf9f3848c1b9b65c6a25a93af48c728b6485ab765d36ebe3fc82104d043238867683169cf120dcdd016156283a7e6171167ed19996ac57e4691ca3f49b43b03aeba25fcb3d5d89cfde475eac580b58291084d8f7d554b463b3620a63bad5c1fdbbf98a5d8200f0e0ff1aefab7754e70e4d666e0b31ba193fbc70d4dfc601464a7642c56385abe64df8f377e2e7b7c451e903a13df6020d3cc7bd73fac7f95dccc9be71af4facc9edd60e9e5cc5c99bdee1339fdde03b3342a4c0635c71106dbcc4ca3ccaa8ae7e0b9ce740fd9a6fce8cd805937b3daf103c246d3bf61a10eea6af21bc42867e471991459ea895bd74d6899da56c22ba33294cce17b88b39691c493d7ca312776dffb953720f02fd814e6b9c96e4e4a9aa6e2d255735ada1d02ebdefdfcb74573c77b4b19f751f55e20a5229a22e326ac75858d7eb4c7fe9a4ed48dd49be353269223d3021365569da4c2cbc3dc6ac620056c5aa7382a363f93b894c0a4fb1af983d90d8127115837531e9ec7ade4a419051d503c1501afdab4d9b9b9a741810693e256e3f03415901ca0eb9eb74083d88d7a1db546c4436e3b19f3be3da87a6e4a7033d0cde55ebc2f7123b750475886244bb6444ea293fe498fb1e98d9ef7b31a86cf05cc660841f0b21a3ced89cffba8cc08112fb9c20a8abaf1e9eeb7fc7c678377ff2edd2e4c4d3140bfa4106f46a8b137c4d68985dbe4b8d67342f409f75a3027dc6a71acfdec2b723a4e1b96a12e42e49eeef5ca77a8961c77c39d5542d5be19511d6bd5364ae79cb254da944281ded04e1e06b7d4de33e40b1086de49543e56e5d7d4ad2e224f31337351707819f96d36db4d3a29018403556995a098cde94138f71cefad7d8dace8a6e08008b22aa5d257508cc4f6a9811f036e7715c67ac369b6d80c425c79a8ee97c094c93dc18771394a56dd527a676d660472b9fcac4fe783500676a9aa6b0322752a73ab982fb28e5eb4ae639033340b9ccc8ba036ef1164d293627c41e094bba0bd851480d2f91ed8ec8a1d4a229f4d08dc25b5b7dadbcdf22b2269cea9c7c6b886ba74bc156590e440a9a0e128a35ec8aec4eac360fd9bb61e9804dedfdbed1e17454394ddaf851c73327022da9456ba7c4edbfe7a0031458088f026830c3695c5d89a60810c2cb6543880b892d8d5c93214ef78d8e7538028419592df1f630144856ea1ef215ef6658c350a50e018cf0dba35fda2694e1efa93cca66931d9560d90bb434501f5f420b8bfa02a566126dc2bbc9f4e0fb929e2c42637de5e2e77e07659ee590fd3b8facbe7847b9400df4bcd858925c15cbf1a385fd395d50b9590c154928cd95798b735faa3acdb4a8874672041d585e45318ee942b3e36711dcc706bda76966cc0100f14014f9ea47ed9c924035e2138107f52dd26bc5d0312879505d7ddb3b468765086169e24a6e1919de2eb169acb18267fd0ab0c468da0ac6436acd2c4e08fb85f134e648a992a69cb871173675e87906f30e7cedca148c00ddae418e07e1aabb8f82f53127635e09cd898b348d4bc5c575cb6656d4bf33af7414bd26a84b5184b9be5e15c384902b1c66a6bf08b16172ed8084de06331119df75913d29ddf181de3bfb9de1242183ee797309ca14ebfd5f8ac368aa72ed7403fbddcac4077d669930d742240dbffc1a2b4a83b043d904285ebc0937c087c9025c0472a2b6e546b6629cddad4b9e60d64c01e0ed4d4bf8e580013e2b215d24893b3dd7629e71cd6c9f906205ac2a1572fece8a7d95adf21ae18f530a6bc18291f22e1b05349abf287d50f1f6724f01d0cb3fb7e0a576997c3cd9c013ddcae7071a7edf496605715568407f86ea78b20e66404676f2b34618060e180e4f9dbfd9a70a1f96acad53deca1db22d87342ad2eead7289c7e481d2068a74e62f9c9b90eb02aed47b57352b23009adc93787eaa74c7b8981525eb077fd502e6c476f6fade93b53c29cea27cb4a7594b55e4ca11b66f94ecd43187fc23d27bc72d0f48a23987fe95b06940a360e9026a022d2ee3a11eb72c8573eea76accc0fc2acfc61fd9e1655c77bd652a5dc40de7dd0182ff371d5a8d3047bd82a69a4b75452dd2f4409c5176b02488b9ce6e8b5c0173d96e1a83e5889ae16b4a07b09afd8f11b9b80f812c9ce794da70ce46cc3e31e24325f5358cc0c64deb9305941c0511ebbdc302c2e362123dc4bb4c9579c6ae2f692949e92a76f9aad182ab69549702421d94c5625904af24a42620f331b8ca6f8d6ce59306517ad93fd6d1fffbfbdd16f4f120540753a630c0f56b178b1672504d1cc0a20bef9d93c8777c036d881a42a72dfaeb14a1a0b60990a8c27f978c95ce44edd72e677d3be62dbd26b3c9bb1ccf1128f79aeb2a41f6ba6d021300f0ccc1ad36169bf63e36b6da9b3a9a6e54815d3445125a2d5078ec0eebd58df4487919fadd4977129aa61ac337f347b3adda82072d758925f4ce6a5125b9e4f87dfdc5cc4b3af5f9589a9cc4969afe7c6b99edd05462d1da3c40d785b8067c4c866a8579fbe4d94786e0fb0b717c6fb96e2e3ebd72b6901acf96c0fb174c272f3559898019a3d87ebd6d9ece260ec913300392b541a1efc0811c10af0671206345b46a588abc932f58be6149ae6591250a8740dde925cb9fa12150c9f8d191163ecb613418058769c54f883e9c0b533f6d8f568c6a907c227d16054af09c6c73676f5b9859beeb5a762ea323eb76853f4a3ecb113ebc42f9c99d89e5869777448a26c40407362a45730621c700e3710a65ef8a49d9c19a2692bbb37c1fb4573498126522468f738da44bbd4a719383582244a284645b318bf7de280d1b9b9829af334d24c49c50fad08a3c1c630a8e682ed700682998fe7b121bce47bbde010fbc9ab70494d5d0b300b846e8987efee9ce09cc1bfcd828f18ea2bc4f40440f89ed48cfb103a80e77e26967b7ec56740d18ee40bfc9fbc6ae8a0d7f46f3bc09b7dfcc590b55e3d8fec26e7f4dbd7806f550519ba3ad64c15b657fc726001b0644054aa24f9b1dad492dadbea8082b176c5fd819a8e73665751578e74ef32779127616a28ebca4be7270c195ac077fd71627faf95fd02f3b6dc45a9f47d3f666c318d752ae08c17d2385e810408d90fe0aaffea328466c5fa82958e840ea6b7ec4f2bc6980db0f3a86461f51cb55dc262ebad5f326533b6bbe0d9c4b283f564949f9cb05291ddd5371af7713a088fb9033bce4436d93190fa742dda242d725bb1fc261925efed8df4b6e3040b7e4989384a464752833f83a087ab09eb0d2be8320ffe552741a5a6b90ac91150fe3df65323ddbfee23f6237c623eb57a44f7dd67be498c97bce8a03dc2f695d0a41e270663a06c67819f4ba401a45886d78853efce02a00335cffa3b47c29b5341f43756fc5c180edb367aa43f104be106d233224623da7738147527e42a904f5a1fcf1d35261139752f9bc38dc992095ac84d03f889024bc8dc211a1b41979ddfe455f696b8199a2e5ecf61625293a6e8f9e36718e9097badaf37098ace700000000000000000000000000000000000000030711182024""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +02b250a84d15d015d65daf64921d441de7eaced5dae8d5ed5aaae0780710cc6f6478e91ececa60d2de17019195875bb3bcc202adda53a06e8b8faef1dbb67e391e8c8e7145908fbed14602f4cd5e8c5c5024cb3e65fcd88368454b7fbf8b08553c0abd7dea5834b8ac4da6968cf7d4e4a6771111de335b8a1ed45a18a20d7cd4e9eeaf18868950880600a531f49ab5a53deed6c37ea1c22fc0769d8a8ba5a3c49134a80a649b0435e457314c10b7cebe346a822a005b4adea250c449c4025db99c8cd8a3b44a3582e8fe2c1f37dc64503f90143a4f60df3a0e123917d68ea2bd0ed734718e38a306e64516e7a30eff69cb22956eb3fcfca07806ecd92d31ccb06d2db525118fc75973c04c3ded11f9425d2f89e3442e8a4393f469278cad14b61b6a7b15931d647a867f2753b69b22f3ec80dae692d7cc06bd82249da6e24570831ee4088b052687d8277385fdd1f88b4291db8736884928eb2a3fedc6b57e0a4c9db49962ba32d0b75b0c453e63a17a85932e18853bb860869a022dc48a96d6ceb1bb78d262ccafea8f05d61d4f9131efd3683e371c60781e36219ca5648cb69e65b11c2f2035f26827a123ba43e86de7f3f2d91f07f0bce7bb833634fe33d094b9c0ec790a8560e7475f9570fa638f104b67a7c0bfb8ca02df96596a4a7c41b5d192c44c9086e387f6a868b8600aac16fab9582c7db786d859348d66ed769ab476f69aed6513178d594e268d4a2edd29e684ff71aed82504281589da608904bcfc3e21ae7ebf53ae4acfbee19324cf10bd49803a2508cb0d80940840a9b8c0d7ccf651f134e03218b076d5ba213491163bcbf407e42dda28aed332d455395866e6d5e11c08f4b76b25844fe2a44c28b13299a0f924d6b541492977c6d779a06f8e7d19a145f70b42a55f4d200d6bc97e052ace5af0d2429d752046f25a8d51eb43c13faa172d4a9553d0ac05e6655c57be3f232329c97c97f7315016a80e6e1c79d12c269129fc89b9f859d298933d7b0128a69508c6ff454fbb56a502cb740acd4623b23382f3b3857d1bfb0776c3f1405271c551cca1b4083a8059d755f2a55c39c2ea836f8992a1f386800627f30fb3ab6998d3b644855a8ebe7c92f45accdb7ddbc2ab67932cc4e75b02c78fac8edb89d5e68cd9bce2187eae5f612e7e4e80ebb50fc63abacb76e0f317a299d72088253308f8c5c1b9772f064c90496aee1282a4e3a9de98ef74a2c3a4899d117376aa2f5ebac04eb83d57eb887ddb6419bb266c94578fec097ff2ec3f06230430b1fed1262992f0172ccabbce8979b5cd43c87c2cef2144270561c6823a9dbdbc408b81af10680f1c6939f7c8f2487418d7eb696f491957a4ba1a9a261eba8d234a958c7ea2766915a3d483019d83daf0b4e1e8059e81c3894c4280288179700b0eb984a401d80bc537e979d3a50543e6865eb5b73e4dc0ba55514f22c034cda20874124d95ef6df0eb7e37d7e425dc53d0b0b81d6a3b222b6c066af30e1fd6d04b732e4ea9be724bc115d49e0ec3db841db81d9e0405c5005b475a1ce6f84b8ae38019cf2c21fb9ba58a59e983b55aed4b758851dee4885127c5655a54e3a79eac74256c4928274147d61a4c6f1347f4e3f49fd25b154caf3db3cdf7f885bfdbeb24ffc02226569ce08127fb17701bd8ab0c792891d0433013bbd62a359852c5f90bafbab1ecfc0b74d6937320b9019a955c05d9e121eaf87d08c4f55068f3b2973a2f4d1cbbc74887654d6ef8ef201d2b0c90af205f15bb460c4a01808bdc27911342a476458504c01de66877b9acbd8c015e049e37fd1f90c0b4e50b54bd83db0f87011f5d56e85eb4cc75e9bfd9e92b739f833119590e409be30bc75adcacfd0e6f31555f86bfe4436b9230e519d0983da0138f31278e6b7ba165030855d433fef12032855ac24d7d8148a2ce54f3ed2996bfbaaeaab3595ec02bcfd0c77480e87252f2ba6874d713a61849d303794d940deb31c1306963111fcb6ae6e1db1715c1ad5b49b0ba4262abe8d7c8227ac428d51ab503d12caafbe0539711c956cb5a19adb5cef22bd1c52f8a297913403d8bde655af805e96d20f277fe873c463b0bb747342804a0e74657c6c14d53049f3e42eac9e945e50d771c7467774a755a2209a1182a7f7e5e131c61f792e4fd962e40d5cfcedb4add6eb476689c508ad8dfc5552d65c937e39018b151555d605075023598fc479dca05d227fdce3bff4e2583dc972d3cbeb3b2d6d2de7e6ec44c00ded46ca34b8358842d0415f7332bd032b933be3b758b7ef285354610c0abb9d05ad104d44fc8e057f6585c2a1844cccd3bc394b0e097ff09da8841ff7e3fe82aef8cb8af844e70a1cfba3d7b88cbe2a82a01f49c06d00a8a44ca2ddb0d8080faed34fd0da509e80361ab110170631d00ca8d5d8c85cf788f105aed5e2d90f870d47c07d08dc16db01440c671d1c7f880bba7a69a76c3bf64ead43c3b7f0477c5fa030f93286a2781b435778450b4e73572423671f4861419c8057a4d5672877970e9121fcfe6b51ec469a0f71b5c69718c54c3165041d177480d761152eb05e2c3cd49a063a25b05f5e75a597c840235fd599618d72f99f088086cbda1a2a655aa528df1d694afbb5e27f910449863c01cbec95a297c5f89ef2e67fd0064ee5fc2449098a43e2bf86c2943007ddf82708326d5fcbdd6e8a5821f9707b6a7a509e27306f8808f5c0bb85b8edad600f1bb4d58cb4b9cf6a74767f9ff52dc"""), TestUtils.hexDecode(""" -C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), +320D1B2976A4A4673900C7B75B23EDBC25B9AE867FBB79B55B29B3780EAE8C159A3AFAA47CF1D9E452CAA8EDDA3304BBAC47EFDCF96CE92DB1981A5088F731E1EDA1EA5FDE9A031595A8F268E92B4D75793C6F408F79B78599D93E80066F8C4432911828A87EF71C877F55B1F18207F01820C0153B647205CA93DDD6B78B94EB59E3EAF01B66953951ABA4027F811877B0F60C9A5AE6281D82348E3EB749C82C81D53309F9B7E624BB1BFC6382F43A58D1951F7FB716C08DEDE4A8028B50544D0F26F7B9DAEA0CD075C3B11B7315022A37198F0C96D752798E0EF406875CE86C367079841F717261A2B6570A8F4F9BE1EA305E73BC8BBD88AB162B4D4BAE86CCCD406A0FF6ED5A968D4C985460FD8FBA5B3FB40E29B6ACA07F70717A0700AD3A0BB7081E09F7219F3F8829692C3DF91C90334DF9E89284D65F7406188C9A1EB7B5C491591A20EDA9399DA1AE8C0C158588FE1426B763FE9D11223FF7A05A3DE036B67541C2811AA459045CE73096F89E6BA672CA7A546D2B0554DB35C547AD9585D14485AA812BFBC88F7B248E03F2EC57043F4DEFC2B27A3B20C2EE7CE334D428EAEB228350A3ABF4628C2DCFA84BC7435818F91CD67F70F3C7D54E2C205E55BC4ACCDACB354470FD5C246F32A542106EEE0EDB38F01FF5C4B657C7C1A00718D2BFD311B8BAB6523351E93CCB44274B8F96EE343830148F5C8594818777C1E798EFB45AF1D2A75D22470B4D7F7C7A5938DF3F8288A0088719C4E36018D9993F9E69B8469E5F2ACF1977D441B82E5340E5AD5B21B66051513553BA1BA1C1D5F788C47CD3BC60079300F6E3D9F13EDAD4DF8521EDD022031A3D74A6A5F32AC6FC51C67F920233C5079A2B44BA7B8EC6DCF9AD4667BD26BD07567E078267A1BF44B15E68B71AD38226EDDF138D2A599944F70D47B26F775BB97D9966845AB3E6AEB96E1414D3BDE94160B6DF19E03BA1BD0361354E5078B3C5733B740314E2DCCCF8F4C9CB179DA62D5C982B223CCEF5F29D7B673680DFA2823A2BB279EA45D98CD91BE7D52E3E386B98B62DF3FAEDF025B55F49EE6FB5E8DFC9F70A4F093EE3898B25102CF3AA52E669D6EC69BF6C79457BBBB7CECF65B1E948DA808025A242841FEC6073326BE16C2D1953209F31BA4A772FF24BC30376EB994398D4177FFFBCF78C9A79B7F1746D077AD146514A2DE0AF9800255F3A11BA661765A7D8E8E7FE5FA46BCD1269E278555186D4BDDD03FEEB70BDFF7E5F616259ACE39969CABE8D4F8F23544918516C977F84C09D6A6749B1CE719676378E82F9B4E563D67AF7D911233F2527B5CC5D0733360CE15A173F10B91360A3CFB08EB44A09157559A0CE8B661AB4A97803C52F156627C642CD02CA5BBC7648833F2CD7E99D2A7AFB736E5AFC4FAE5DE19ACD2F5CE3E3FC887852758411E8C7FBCADB1578964445332113F963AF3E944286DC448471125E55A46D2DE35E9C0F6DD10A3BE4F1E4BDDE51A16F4239A1F6A535D3202055990606C0065C542297D490553204A6E3CA16A7FC9A1D77191E5C01C1507A332C659FD6B11FAE088BBA796F18886195A2B8F5B0064D85F56FB7256F0FE70E9C06ED18B7C8A75ED97A1DF482908D2E3E8D6BE8D0EC8020451C687D10F829257F3D09FC47C7EF008B89E2312792A25EEDC71E9835674CA50235E0A6C832E7BBAB458725EE7BF65D26A0501C91835625C330B0F8B4D46A0762F7773D2415A0DCA573B47EB8658F9EBFD26D9F6EAE9D7A7304BC690F8D2F60C33F8A7D19B52F9340BFCB2FFDC92A7F9ABF85E3352E46ED7591F354A9E19B70A3B247E3E4295E45B6A2CEB59B120B6758654BAAFED2120B226FA778FAE5350E756741093083E4E56A84B64739695C1C09EE39DEEF11D7E5BB7866C90FC9C96CEA071FF82F145592443BBCD6B7CE848839B641C4522016945F711E86152820275A6E16BDF296D34AB38CFF06A63756DAFF7BF230F024DA00C4128F025F091F4341620E0EA883042BE731E82D21DBA6EE737D90346B6189697CBF41F7C2BA7C9CBA20E14D26CA578FB05E92798D57C0060951BDDCA5D96322AF35D80013B48A79AB7684E1E1B040315A350DCF84389E54C054AC4C3428123E01C2FD66FBB2C5BE2D16B22BAB805AB59DF205B71764E4AC9BD4B2D872B8905DA230623C65DD235FEC253468E53928722D1F04C486B46E63FE63441F11B1E3617E9765D4F388D4A2B68B6C86C8E20FE0F3C48A561A0FF5070455C43A7FDAEB58ACFD4BF51A1C37B7751ED37BBC73B9C29DC4FAFD0A8F5FC98C7FF02B404AC08A0728FA82A5ADA4EDC195E679D88187F58004844065F281A67FF0A2BE0AF94D5C97ACFD43683AC721045FEF8C36DEBA2E3EFA248DA65837046B62BD6CCEA84CB1211C5893B0C5F0A5922A989CF7ED093D5D706657AA6E79EF3FAD0959DF594B9CFBE779"""), TestUtils.hexDecode(""" -E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") +c344d3409be7db98ef0a349092d4bfa68e022cdf72abd10851fb824519086e7cb35ae13a93132867d90ce67d9c99315a3c548f7bed393d9eb71231bd9cfd951c53cf8a7555c2e8899d7914549a5565d8531685c7a02b82f3b95f38fcfe9c24118358f4dc4b0bad89c5e169e8f71e97e5f874bc8dea40c70e9fb2322131eced692b164c011d04844f0cf95a663a90e0409f2b36d8d936613343f6078751a082056d1c077fff3c3e0bbf5a9edac10d8ee0be319df29a998e5a52f06dfd12c47eaf72a457b18c73bce7931b74f28e2b3ca2037f0711b8a4755a860fd79bff06218b965a1e1368128e3db4401bf37185421d4b080e20a017f9695feb484b7a4ec6623cf5f82d99d1e0a3873d380cc5ba715021cc8b24f0839d10eb2b1679098330d772a081bcb20ba8613bad19841b411cb84e4f9bce9449b5d1b79922733e0acaaaf3c518d316c63a51ec49f4a5f30671df7b36e3996201fc625c91ec7cb621b54f98bce47381bc062be82eebbbd2196fc8fb1f26405a80a1cba591820c6b90f9374406c97020e0d8bbc4cf71d5379d54e3412f69d19b59237669e1751355c1721d097f07a218214428348ccbc0c954ea7029dc6aeb605ed6fa8334206e230c39ed5a836664a6c0b848de5c6a219a63ff24264ee44ee5d9f068a41cfe62cfbf885a2bb4c71f17863f5172b9b4203e9e9f21e0e744807277cabd3094d2727d78f930ba8779af85026e45b809b8b3ff259dd8511981e7955924bc29d448a5175c7742b7a1bd7db170c55a9831631267789adf7952fcba1391fc4eaacb7c3429f43a2b634553d8fe47ad9f39f81e54b0461061f6f67ab6b72a25e99801616737e8687c738b45a8ff6f05f6b5a30c8d87f6bb4e2d4aa82ecf9f7ff4d1a6d6b5ba61661e8a75d4dec3daa6ac96c0abf7ac09da08efe3eb73ec0de8ff231078bac1cf98ee9ac6aff210ce15f8cdabb143ec77860bb090463c0e6b63c0b12249633510404cbedad4eb85641630cd131a7897b46443008e79edbcfe471d37159a27a9622bdd6e34c1943e0b5ccf35d8885a9d584f6a54cfe7b1b45162360b573fc19055f6ac05df20662026072faa0f0fbdcf4f9b7d89d77fa0a3ca7ea0d857d0d9b94e95a406bc039799ed56e076114dd9f7c8c028c97e2bb813d8862da972b069d7c1e251487472c291baa0c0a9c9f349f29091d8a4332a56084e11296d1c72b7014045ee584056e9822b113136ca9fc27b1487f64e4fae57b31df3e6e2728fdeddb4437a8257af982cd08fff4c4e6e9aa82067182290da938b3b969e5ef0d15717f0c34130cc2d9bd29d9a4ea6707c9a45830c66a2598d8678581d9a389bfad0e34c3cf45c3596aa986380458c5cffc1dc06c5e143952a211288ef0d67c7375f0d9f59ef10a55623af7b6d2faae4802882d09cafc9da95e7e0254b147fdadd9b8b28498d625e9b0603c9e7e0a710d34134e6b4d2e31003ba30acb30df03a913851d5191adde83fb0278aec64262de99b7ccb1c6ad5358651f336083f59089beb924db5af90be237520b5354ba63393c2514f2f5c815b694258cbd56cb7caa5de34986f214c566305163782b9a67db2f1e51c0172f757e3c8d9804cefb63df98d4297555aa95781e8c1114d5c53b06491b2c4463790030d2d28d159c071c081286071d95cf5fc624b69eda6b2cee5d84ba30ee0b4357eaf5429c26fbcc455357de8730f0b50aca059334ac5af33c7169208be3b060abad80a41d5a720e262075442b1f514958120dfd51927363fb0b43767f3bf4ba7bd2669f79d9ae38c8b244c9a1334f802e7295c1a5b2d236edb5ef8eab028dd2bd8fec9f0ded1dced5a352f55f4b502f5aa12a3131bccbc88a2dfe990cf2cef02ae787db30e8bfe26079bed383e363576ee704e2b2b3b6dc0254ed4039bd0155fafa471919703f632bd8623350cefdcdad074337d5ea637a95f995141b21fef74b93be8fa18ada82dca3bb6ebbca0544d790ca07c42086bc4908a4dfded5d0c09e8c8d4382dd30fd6c586d5c379fdfb11f69faef1dbf46b0b03432c0b9967e6c7417b2488aa22682c5ee0fe6a08e90d6740af02f131c5acb53fed64329f8f108f53d762736519923ab734654f968783dfe8d13d715e9db219ab7441fcb739fc75913b20334155dafe6b85f28512d71a02e463e8f58162a2075d301d4215c61164b5143f096decc998b006051752431e1d1d7d109f92c986c40d2a8f17ce6fe1c32c33631974e47c73b5512697f5e3fcafcab2a4f8b462685fcd5c19decaea96d45a7c3d35eb6b81d52d3d300f4f94f2f831e3412b12429b71b46253c83d849250072c035003b8f4c0c7376e502183848ab14ed9f8b6ed1c87d554223fba1bc99d1d065cbb945de8968fe41c161c301b3cfb9c181ef3bbc120cbef645da02c295d6ed66925802868bc8ac6b437550637e5a16d429dfa4b124c1f1045174507f706d3c01f9343ec58bf79e5611109530e2543ddfaa2fc0641c69ec8f3947b4350bef318a55998fbc25686a5e115c35db12a12e77c8dd43863c2c024745410a0fcf1560f1a902bacc961d931f793238684944140150a99f2894748d03a83e030ca52fd83fe43bb9b7fe43a9451f3850f92df5e242a1e75c3a101efa727667ac45164c35fe7143b4ca2119d76980506e8981c4990c8f391a0c9416647554db2c46256f3e56963bd4f7ef309914dedbd893fc6855caccaee377d70cdd54c64ccc3e3d1c0e197684fc692e9d64be1b07af246bf6d2e4f38d2e8844e01efdac0b24dfbaf32f08492a99b38486a8db4661dac565fd847d83993cefa810c42cabd357b3b1d5669afb73274be28d637d8c2de41305c33ea3569f865834effe4ba3cced51fa00ea3dd7f442894bb2ef9a92378ea447fa6af9ab8b3fc01ac45c7221981471aa121d59e77a1d472906c437004ebbb168cca7f518145494516b1d3a1aaec164e5f73a96c244afe367943eca32c4e61bb5766122f1f19e9768c4eec5d76f3b10376191c5d42005a99eef0fe332cf5cfd4ba59f725bd50916348b5704943cd5d14bfa826630a9529744148d9ebac15a84cbf6490be826ea51fd42e505fe9e74a13ec9a1ad546c8c22e8d498ee7a0dd75387240c3d166fcce4d957fdaa53d0573ed995a229e2744bd8493d44d774910625310b4edb8e46ae665c40599c7b48058f104199ea6ce1070a37fcb383ce4e2af436185c4a3f20e186a25b8dbf4dfbad8304125e186eb76b6f6ceb7fdc51ed324272945e44b0bf11ce27b5b6b683fb4efb7e168ff13e46f1f0f4a136827d8d56cc6fed0a9fc8a2abc8f5c06d1dc0de33042c5b840c6d66a8f27331645a87fa6710f9f057685fe00247cb7f12b229a43f539f9c4a6727a8897c69d8ade9c2af6538c594699a9f428a998bc1e8d11adacba134649315ad51f73c1bdc11d8e5eaca86a138ad934b30b376d754bafb3fca13963eb800818592eca6807867d9bd23ec931a343776da195c8d43830028cf4328701faf124a19beaa44293e797c2bb89b2c9db45c7d3785a0cf5c9fc783d727da3a3f20f5366d9f39bf49bd1ef9811dcd74804716f82c0afe9a73c88138bb23babcf5b7acc87f5dbdc0ce1e39540a5e5979ced0aacc221362e2a18a4af86f34f9b2c03a21dd21f70ffd443be4bab058acac295aebc452b4fd32ea5750f4a2fe6260c30eea5bff0fa17f25c3dabe3b58fa72f75cbfc18a84e2ea3d568cf6e66e401ec82753652f44e9410bbc435721a10da1eec613e71f04023f3121df6b45316795f110c81ec9124b9a5568c08041eef364ee59b4eed261f3edd834741845ece57fc5ad1f50d183d03c0aadd61eddb2f13c46093082182b21d4bc5832081fee8c81c1d9a77f132e8e5e9f5a94650222dbe47f5d7f846b1e91d52f62609cf0420446b55ae4a96c2bafdab6a8793beedf7a7ee9f678a099996b6d6f8221427fc86e1a260d7426ebbfd7b9f3e0b9029907b00cf77409b24f73b7f21fd2030cdd4e36fc09322ff6176f49b6f3492076eb9de2d79f41316a202994871bf7ff96ab0cf94ea11ab959ebb4fbdef3813698b1c78e13f2422efa15198dba6af17ca9b2ad199f133076f9ffbe8496fd28e003575579d6f62c69a237c588ea8bbac99b32c43393b20112779db5f9989c04e9530af29a7cd959fa4eb1276c69d46a67ebe363d635aebe19452416e01db478ab32a32c6e95d43ed4693d51f4ded754c62f53524d4179dd05a102acb6e7057c63aba9c8664d9140f866a359f755ca2bb4b0e66b3794206bfb311535810a24a6256a8c0c79c4a87a8fd40bcb9bc23321fed6cef599deffa6994cad1bdb655eaf85d082cc1c626727918e63eb27521b6de4ef5857a2ea372f64409d4c6885d7eedc15c95aea623bf081991890b8d5673cc9ca26483d6b7bb88fa61b31a13f114923e7332eb2a52b9c42b7b341ac6495d1c4fe01f627350089daa8de8cb8b4c660ec9bb065ce689d965e14488e67976502337f1de27d825cb3e6f563312f1a3467e1d2b2628b5a3ebe401b6533f549263babe79b0ec66132bbde277a1b4b8d913b1c378e864d3c56820b6de08e3462882e72573e8ae08c64861669ab8e92b575c6e7fd5db3a698895d8dfef064b5fbfdef1f411373a788082a2bd0000000000000000000000000000000000000000060d141b1d23""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +2bd5cb469bc4c91a3b3064b58eac4e6e03a617650702c0d2d7a74874743bd42c097727845d5a69c2146cf89053741be3476ad6a7d574fa59f868e30f5d4d1f78157b0db9753ed7e6687383c367d9168806c52d5ee1cd548c65449576ca155cd2668aac7faa7a692f3660832c4e3d65ca6e31b1fd5f7a1ecdf76d4eee120d353e683b67760c52ddeb28c967c5a99cfea6a74a1bbbf468d8a6ec400253b81c6780292965478d5b1d90c37bb6a42cffc2d086d2bb03845e9f1f1d09b0bdd27a9c0495b9a86a4d0535d84c3c2748c7345090c2cb6d4fd1dd330bfe860d1f666567e0e164602073d427c293046ecc8d62d50fea16458e7cc18dfdcc76a01dfdf5a8dfef558c94e6200f65220f67d5831809b2c17911778ee60e724b9cb8cf7d54f3fc8717b2067c17926c69d7d05830ccb3d3d3ef910b622a95127e0b017eef9bb43823f977e904c7fcac76aa44b08ebae23f8898409db11fc2697225d06ea646fe78afe6c6c5861f361f15bc3008aa194250b3d2d14232535bc612afb523d4967370021ea8b6e4a8406b4e933c6f96c244eb363b38b65c35a3ae906051d2980f98483653c03a8e36490bd8d5bb80608eeca2ee9e8e570262ad2e0c77850eb8bdd1099de5aef34aacccdff2c152c3cbbcba38980f227d76d563b6ab1b8f62892e51d24dc2e648160f4cee0b095f9d9bd406ab0f1dc4ba9706611d9b5eac5fab8e246e2686b3ee96bfe4ddaeb26d0b1accde64707406572898cb41ecbf927794e422fffed966a0247a76dcf13d61c3fd256773ac41466befc8aad6f6c26d7a63d0f51efd63fe12274e0952c0047af384e7ce9bf7d7cfd329dbd9bce351290f9ec015cf784f49fc31648147bb46bc9bdd59418f998eb36636d82c5f6acd769ac965a04119aeddcb199f055ec3770c19329926830226d12a990057a2c60d4fccfd4fb20350b54ac2e7b3822cb6a81b0c2928a95c37ad33fc7760018c1a09c50b5e0ae0ac0fb0f89b3224b5c21adb473df9a1aaa9a338256b54cc5eaf2883bd282ff8c406aab2b67575fa1f6039d59bcdadcf4306f1e6b3f28e843205033101f7839b63b067fc1bb727ea98f9d2d30e874d2f825c1115a6b24623e0526246d9a4b8e8436231a9c815df3689596fead6c7bba5e739ae08b59be3c01241e73c1a7a2f9f0cf3feed564f1a2d5f045bc550707c52b367bded98e00d91190830024c28a3fa944edbbd4f292dddab123fadc3b14166e55c8eccfab9fcad135acb7bab9d00510d422232d5eef19ce46d742be4c2fe83cf6143028b8e0bb0aa4660564df0d717afb305638553170116ca5622e73fd7f92ec1a5a702ba0e26b0e1980c4eb38faa56ea64711e0e2a141e9e4062e6bc9bfcc387b100677a9deb0999fbc064a997b3a0c809b11456433ae9220ba1b0f4029fe4da9be24e66124e48f9edc05e9e86656fb7b1033cced41d50a0055be663e9bbb8a5d161b78226ecde3d7cb6e5b1995631cecac52be9c8986c0b22e3e8dcaf108d09ef484c579c6a207598aab00446b0bc847ca42e155b730570c365033498f0105023ca8859421aa3b43b37210eda50ac4d9ccc6aa69580fbec6d775aa2d31d6f97d3a079e0a164b5b5d48b5bbfd7ed8eceeee109e051f357f658bb41623120fc116bb202154def1bc1c11fa9956ac89ac065329d00dd0390e2611d244377a7b2aef7f00911fa3a464f68c88fe01e1dd5ed2743c11802af5a531f0956ca860f02009fb4dcb3034af02c905147038e3cfdbe401ba8998a91be1e119f9b1c674846bcb10c6c294ab4ba9e8732a01c1b8a0691753299c7ebc20e888e232cb56842aa9cb232dd585d52a1a46e7537a4fb271adf102b87e65a7694198ddbec6a697237a06091c81d33159a9b1b09af04fbbf368d6b44fe6ff7948977d339883821132959cf9f4c7b01eaa18c7bc0c38ef87e5c782e2f5de44316490e4c94621fb6a967241c49307d1356a7770eb5d0489e4631a159e4559516e0ff342bc093d2bc3bb4c4fd27ce3d21bbbc906c12c8060d11202de3ab3cbff4488676531bad3bde099adb4b547b8e916ea61565b6986325c7f2fd8649d79f42ed035104ceaea3afe21caeff7941a5ab5728c070ab717b675dd9ef985cfc0a9103d89ce52822aa532429bd612a0c13f65d24cfd27ede804411f81665fa13e08f9a1e39efa23821f2d21209bd02a05a41e6b5a9847becd791978fc3d90b78c57b5eb693548104f959822a78c097cbd1c12a09bc175ef97ae954c738588590517f6a7afda7732d2864845316d17121ce00e889843b76fc250b3c865e4509b1811cfdbeb619f21f6579ee26ea37e35198e59d416841876785cf967ca9d17ae1e31688035eca51859296ba364c8bb88f28580a75e195c00a036c8ccdb6f13beb393f4f5430479516c98efae15f2124a46a6b506830e50a8e37ee6e64a6722d659eea4a52d2d6def30d6387fe820ca189ce3c3ba7f45b0eec9fda6c18448cf33ec43906d6bcf98e20045c7b30967b6b28c988ec7e9aee979f0a310046a48641f982a7d9997c7f0bbe386f05458ba7dbf49647708ef232b3ac57fafd418bcef724ed3bbc9f540f2a186df0187b1e49bb0853acdf9dd18b95331ec1d5628a51c352a0f10b63ef512fdb150c63d6531b0811d9a4f071c76446b3aeba7fd2f0fc301e5f56fe5386ecf5c1759530a88e642b4b45ff7b67d7d3a234532890ccd8803a851adee2aeb35f6b4de938da6b8bc76668739a63da699a9b731bdd5a8b2f"""), TestUtils.hexDecode(""" -C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), +C9ED9B897C34D7119115A0758332FE70D4A9E11FFB2D6A800AAE33F85FAC59E715AAD93BD79DC8D958079F3B5C2422F8FD1A1AF9406E8DA3297226440E30183051FC9AA52AFB8BEEA2228E88D193F231F2422977DDABE4AF4F0437628C6AFBE68F70CF4F56153A2691F7A4241EDCA760D4B3AE0A17A8A0214BF1BA65221DE64647AC6578F4C7E4A14C401F7DCC30A10A695A7F72B04393F4E9C4163AB68667B1757154BFE711BB54255F4DAA9D8AE6622C71EC8ACE5BB79C6B4C8AAF1B0A0099EBBD07B292CD7B55E44ECD68DFFF4173743145B71F536E7D23E78C63679FA2F3C72CAADEFD5A9471280CDD3DD8DB83F8AFF14FBEFDC8C5969B050D263EA462C28CA64362F7F165C3EF427FE5E90A83310DCB07C9612E9A0B8EA1D0631D84B4A7F1C7485B0C91C3B7BBB0EC98D353376B692BAAF24C5389D50250F3BBA82173DCDB52382176EC5CB8BD531DEA049C5B815D788491608FFA2AE8BF486849810AD89BF0352ED595E4EDBC0B81467D72944AB83C3CB2F90FCD10810EB65BDA18C43F9A9A5D98E714BE992B7DA02E9F7C389F1A22810DC0A473F8891C43932E0F6B5D3A21C3B611AF6C394AFC576C07572DC4A1E56B4576FE615E516F48544D099683EAA886CD41DA848567F70C2103C467D271919CC5935605C0EF05909635D431571E5A316E299E553EAAFE9C7CBF5063E2057D297F60B5DE1C17AF6B97192E840474CB7266A76D509A10FC7A71721D705A9DAAC5BAD8A52290C1D8DC7938663B24700F992FAB008CCB3801258245A0F5F329A4FE5553F4130DFB1D673338889B357FBF11681099FE9BFF18AEEBB31DAD290C1401D49CBBE38277AAC8A99C8BE4E6EDD8A0F3C901082A789A1037768AB7C3C704BF1C6E890D20B3DB6918C477350F4F25756BE1742DCB31705EA9DC975DE0C38C21D29B340C63438268F6CC399BD644EDCED36A7B50E8D65A507BEC51A31BD136525F4E7AFC1EF9E0E6325D032682EB4AFB7FB22F1716EC6F4C9852054429B5C5FAF3BC86213F6D800281913D5722F3A380307B59E1CC290EE66FB9699FFC627770B52619256C7B76D993FB4024D2DF0602F102A6A1257A200DE1F39DB54614FEC2B60F3728F59482D71C7E5BEC36F0D90D6FB0B4FA252E7FEC4F0FB9EF539257EFE87715ABEC75B2A5FCCBCFA5666F1C9BE2F0489E04E63ACBBB239EA8397FA2EC24C25C538BBBFEB74EB8E15FF93B0FEDB7F36FF67F7CB244CAA067EB2C005EDD2AC9E0765DD38E51E7C71AB72B056B230ECAA8985DCDB50439BA261A0DE57E68700C64655E1EB8608BCCC33480ECFFF1BB75D0AB69CEEA8F2E3E9515331A1EAAFB9BA32AF62798DF761267475DE343CFCF5A352C907A0314365B8CF6FD2E72F2142018C4BBCE4CF0A160266DE320EBBA359344A60D32CB135F5FF943173A3F9C7F4A68489E78621401425E5B8E6273309FA3313DCBF13D7C69B63C1EE34D3200BBB4CF57518A5E66D010984AAF34CA9B7DDC914A3AFB514FA1B9D3FCDF3324998D0D9058FEF10C30ED6B381C41DE363CB31C5107E7C00D4C0CCE485DBB4CD2092CD929E5717DB8CEE4790A48475E1DE9178E49B13C5173B6F301D5B7BFF1A9F8B3807A5FC84DCAFCCD8D585B77014EE285074E64448589A738F1323C7A865C3DD482499640A3F166F38E37C6F9ABA8263E4F3D1C2E7D7AFD16BB02B9B4BE8A055452071F278C32C3247DE2BF83A0633BABE7FA048BB18FDBA27022736615"""), TestUtils.hexDecode(""" -051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") +6d9ffac759de540cb67a1d3ed0e50afaee62c1bdeae34e94e8c88d8fa0a86e22b911655d83e0197987aa1151adbb629f7d130a143a3c0f34ea817898a86d76f54ec5fbcf4d0ddc93ce671516be812b1eaa2fe2da29d0381d9d5cb8e702c038b8b8e51d3ae18d0837fe459be7cf6e4967233344749fea70a74f143fde0a0a9582366710648c4f1b26152ca0b56bb6bbb6011264960f9639ed7239881337eaaefd07908359dbbea6dca1834f03a753dc02ebf67371af2ae1a82183f654fe20ce6212eea1aa256b8c1366b4d13ed800e116365e8f3277eb522f2793812329e730f56f6af17cfde3273045aae0ec8188cb956a0058dce1c4d481ffb1e114405fab0a5e9a70af8d438a2a266d9a93332e621231c4ca1d2aa02e417a327a6feda50ac402263e797fea04579ff60b9f026bf7a97fc3378790e3dbc9e7b6cc12d1c01813367647bdd5f8b867c9e1b2d05c870b5935e5f19772fcde0d8116a9ca9d84cd340ed26adc1033a8615ddcd29f86659f3e742e7c08cbf197e4c2f680547099b364fc67b8140a22eff4119906322ea1badd4af4bd008bc46d335569052cf26520938e417c8a8a12c72cf0a451ae2f209532e214bfaffe20414b4243d9351093215ec3ea78a5689e4f89397c7d309abc54d55d3dbee907ebcc6a8ef921ad61c67c2094081d901ba8631745ca131a302fa813c7137c1f3fd66207ae753d0eafb1211ca4e0d247182b3155e12a42e1cce1c415f74677928f7db645889ea70928679c7fdc7e36e43231ec831a6a6b6241bf54466bf530553c268cf5d63b22d755fe9d341b0ac7ab830a303d3f74acbba37de4c109a63a6457e9f79955232e368e9b4aaf27c6c5d3984e7acbb9d19d4cce1b8d53a04d7e137811f10ce33ea05a0b25f0f5ad1499e39542a264ea0830cc2b20646c170495e71a428d35ce3b726ccbfa1499ea716df3a01186e776586d431b90978be9536e5587555aba18ac6f7aa3bd44867d85b6fe9727496d6e0c8e8e776cfe346c5546bd262d30492cb480040c42aaed646969120db4dcf7c3adc8a4e469680e1d5d1092594436655355631bf037a3cd4b9dada49c259e0c6998d466d6f3df582bf86cecb7f4c874f392806cb1dd3b08d3759792875a08d589cd8f8dd8bcb533accfe23001773d6b9ac4dd6686b4ec3ef8cf4335f70d86bd155e5e473666c3ab5b27f069616c6d87f3969a55a80e59825840feb3c82816ca0e7c544eae787ced30e7e5d0b911273909ac11c5f0407848a96fe139887569491fc82b02e70134a1325956e65f02cd97254d4f469455f5ddadb32d99b851020ffdebfec3c83fe99ac4143bc4de6e2341948494dbff83f13603bac25fc5801cd694eefa4439afc61ed048a811b355b75ca4f7f7cbe88debd671657bde2840e95032129f2f40fcdfd160a13c7c123fbc811a7759e86f914288b417a6051393fb564a8a2473c3cd5216b31848cae14dd935b79647aeb287a262a59d37da18b085a86745b2090a83b6796203baded78332e5a76ae6d8920473d268230c00a442af276d11c5179e0b776719f02f4d380861ef73ef946dd03cedc6b7e19c812cf6367d6fb847f0f00b0ae2d5296122bf26553bff501afe0d217628dd44a8a39b509fd5a50c2b991d70eaed000d85343135c8e1f9a4bc703559e08da575ce134e07a33e3f3214d75f959c85e28329aa2242d8dc69b12ea2c95be537b8d1de119a7ce7d7a672c7172bb7f9a5df91ed8e10adb5ca072a493f4199f1135ac519484678681bbc88135a766490f99c2b3d4c6951d3e5da5e169b908a60ea803227fb870510c1963196712d0283102d6883b9164d9c30f9853a799696d488ad8834b6903602d14565faf6be82e911ea41d2cdefafa2506b28f1ee5a77eaa115b91e1ab44b7123ec70114d0c4a13846bb046bfcbfea6097220fa91d1e0605017f3849f9e2be6507fa4b7bd4239ed56961e70bef8daec13fb486d458c7186b99adcc45ddddb818e4947c0e6c5eeada18f564bc664f51efac7a8f12a259956ffb2165f450d728ed5a3c9b4cd6dfeb2f90a7711620374a66510fb3c2b3fc316e15e52a5f91d3e38b3313b7f9b5a80b6b181e4c4fc036ea2574d219f179bc1afa98fc918e33a52cfbc95e20c09b4140367c978532e6be246c8cd1d2c5508721eb298db406a92e77d833bfa7c5865c997b402cd8c09df2c5668cb38b03eb0e86da9707853b20f1ab23e11b6d38421ec2d6882a9121b847f55923601914a11650f02f99895f9920e1df904c6f45715a4c0d7218933149297191f72eab16eafb816d5dc1f59c30a249b8545e6947ad81d5b8f562f42c016ad46f19f5ba10fbfd2a1c22974669c376f496519525bc7ffdd937da7845efd848aa2431344c7314d6eeaed5610ed1ff144794091ffdae46c31fa9e7116aed7dc93c4765b9b72e021b825107e248b988d11aad8a9d466b4b109ffb874f26d6d7f1a12dfcaba5093d60179d1cfd2b435cdac23f6b64cfddd536c55354aaf6a76d738bfc12ccb003a14d19b54e6ddba35dedfd5e4f7f8a18dbdb4d7a8b34acfa4ec462b9a9ac8fa962ae9bfe353ba9ee19d576a320e0f9e22347a84fcf58c0ad61429f9a5f22809b72e91574052534e96832a99db4fe9e22e20dc2ea8f5cc4cb70c844ca9a0334f92ee2703b58b2b09e77c71e27851824c78bf3f4d177237b212f73d6681c6bcc29f12116bae1a25666035313ea2af3e4e98af8f6cac0236c392c39516b610234304b4e4d1d02d8d8e349dd00db7b8acbcaa4c79aa99f711ba693c7e93c9a71342453add96a124e3d06e46c503425a311bc5249034ce01fcda3c5809de83a87d4eeca01b26f92d9ea61616fb5383918e87522bb636110aec1d2b43afdb4258a51f06ce0af14a8687276d67033d922026dd190346844df0974280d56c22fc76fca0132615d1d61bed3facb80f8ccf45ab82121ac3cdd34c425f0efc86e1546f35cf470bacc1976e8c8561b086c52dc71d9fca01223707341c9af7ea6791bb08c2d46a578ba479fd36a2ce79558387afe1375090a53aeb2183294e747043eff104374f6f247591860028a49ee51c5327007d08bda15dfe2de5109683f0c10b620e455d265411a460c3474c3c2c9de9e72356bdbd7309b6e6dd2fd9260131b595630932f46c372a3da2563f31fe5dbe9faac52abd5c842eb8eaade71500f235fe806fd906ae53a2b65a906dda24b3839a0492b206687931dedcf96c57f05c28bd3e1e97731523ee0bfb74cd9367676f142f73d861b070843e772fa18a80dd641f430236a96b294c68ec871f957e4f04546a0610b727b4bc9d46433434e43e9d6c0421997701c5464fd62d7f73768f92645b251151bbc11a9a968b863a2a25de9b1bf547cc6857bb65c3fdc38268b9a89d8a4e49f1c62190812148e2c2617a92ee7003a3de676129e1f6b92b81081f1be2d9715bb83c31fd3136c80a0b23b902a9a3e5f9383b1206d2d8638fb0a5e5c0e2df646235b6a40b5f4f2bc4a13041f44850bb8cb1ef1d525f2ced545246b830547136c8fcfe69c86d4846391d1b8d78a63f50a09ca62ba8c1578eb7ba182ed67975889ad92458caeddd358dbeedaa34e160051b2346ba269003fccc4c3f58d511bc74949b152ae37ef64d0ab0560b8c474d3a1f78b04de729c9f0c4ad7ad2812f037195c85f3d3130559a336610541de8dbce1c91ff95b4d73ca6e4f4023378a5e4e49c8a907cf89b3b71ebc5729b783764a8b9f998e5a299c877cad7bcfd34252ca87de197343c01249c205ec4057912afd681c5062897c79b272c9977af12ae543570f2d8c4977684a2689c627ea4f97a8dd9600a17b6bc10a71a9cae8b18737e3d4e070402d8925d8c81d49854806528d5b03fb90a4a01c03cde8213522cc3372e49fb12adede707ac55eeef0c72a1ce7793925ea6416728a2afd328d2241091049beea09b93158c0835f9e28d0fe34ad0e6cc4cd82651b3c9524e50b6e6e509fba04dcd311b679dc7c82d96490b2f3f7c48604860afd25d38786d7adee7dda54acdef35bf58c2fa5bb0c226b535a9f6230c9428175ddc939fbe2f2191adf27a496644d1004c05c06e4a2e8b82a1910665062c10e6fbcb6d4e49df3e6d17b02cb891f89070288c94ce4faff7709cf88994af70a256059e6bc4df8e2769f9d2871aaecd023d11b44c7ccb0b0f40f4bca202dfb1db1890c89c4121c3a221ca70592742c1c624f9c54ffa3ddcfdd40864836184cfb075417f28a6d5dd5ba9eb4fa2a5fed82c86900dc96aca2342d29dd7208270bd4d6ebeba516fa6d8809eef26e6e929853df5b7b22a66628d9a728170da4a4eda26af530fa05778698e85f02d979a76706b2daa3d154db0872ea5c8b06ca7235305b1d5c1021b0334dc8df6b267760e652a0e1a1fcbd0039d6f585879c7b53a2dd3f664e36fca174322e93989f78ec66ecb613b0a694f13fe2715a930b2ac5cc4ee65a120c3c309b97b8e1ff856857cd88c0ba77aa5557f4184002fb96b35f367bb62502fd6fedea2df3ddb6f4015b018fc00ee6a79ab78c25aacfef26b1d5b1fbcd372b296f320c3cbd02128827678f54ff94c2c5a677193999eb2c1d7f7080b1d4667828e292f373b47696f7b91aaccd4e9ebfb020a58acf20a39586173da2d737583d10000000000000b1221262c31""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +c80f02072f243218956d3770dfa0eee288f8b5372ccff67c93318ebecefcfbdf44eb324573f1e7cab8f0bf2c46e14121dfa84a543892c7c90dfd5a6e2d9e97ebbe6fcac50f96b1471833441ea67805670c91d070814d14ed96d43d8478aff217c5045047e832a55914de5c621ce927144a790873ad5bf955e6b84650b6dbd479fd99ff33fbd0b58a9d057cd6ca317cc9e47a830badf04377d34768ab32b7316f2fd1e40b3a413370c0d64b360f3f46f447e9d3bd66a5207c73415add021ad7a32c0229f1b12d70f4b4bc545e8f56610ed11db236a139ff2eab8d38c2c39f258a94d52c3c947f0a3cf7acc0be3b0bed7d63f046644f28ff966c4f40d499c9350d74a81f76248603fce5692a0db585ed18c2d0791baf6eae4e932e2476e56f7b59c73acb881279ed46adb0116820456d9f4cc2fcd5c0b6bed1f1d1f5a83af213dbd244a10c1e3965526261481c4512df81faaad7f730052ee184841140f0f2002671f4031412a31117fcdf55534435fe123dcd0374e331d2136bada30418330d67b747ee45ba7b47b917257db42023048219635d07694064b5bb4b47e4a3950c50d15ef318eb4fc532ff7a2a455dbacdf04a3389b2d11e403247c84a6cb66cf9d2441ef0c453aac1d69f45be2291d4870dd91345b516d0243c4a76956a6880df06f9b527b32b6b05b0acf884a58b4ab42b4d4f92bafaa3d2c2bf9fbf6fd4804f884ce38c6f4501318a3efa1b0f9f7dee7d573a86e3108e3ce93f69bd35888cd0f0f98d3eb11c7571cad0573db31a692f09189eb5020d52196aac39a621380679a246868554e9f6b85eac016c1fc0847784ab92ce22c3a033892c09a834f68f03275d7b4e5980fdb51098d3fbb951e7599600e36f760d202f7f76f9f61a6e04a974b08fe2e6c2fafde4ee15d97d7c0c6e049ee9f66a4fc4e11fc65f29c91e31fb63a667dfc3b6445b56e7cad1aa237c56b16b6cf6d82349fe3dfb9eeceb332f97cb6fead2c791c846275e389835db39abd041ec91726b93a81bf3c45b948ca8dab2f98773b33f9e1ee1bf8bb0971c3dd10f2eeafd84f391f3fcbc481a3f6b87efb5756ca9699aae68f6effaa27b5c78a43b5c64411c7923937e7e03b0c9a39c125d268106e2fd2fcc1cdcf6f37e02a0848b46f169d65a184213f7d65026c57ba242a093c6f651cb7bd47d4adc50cab9ed9e9aec5da84210c7671e0df9a620fa27c43e44f3e0f8a1e143eb6fc1c120c4da0e30bf9de21f0a973e796ec08fb4d01976d9996af6c8bfa33400978ad16810faa80723b4e3748734891ae6e590eb411dd291efc808cadc857f64cbcf7e5f66f1a0fe7a687e1c83228722f3d111dfe2f9b0d992ce32795d3ad43f3022cb635234d7dd36320bb6dbb5289a03dd9e7a68febe91e6076e19eb979601199bdcd0239bfc9cfa43958a05c7f3185564cc457a088d0b02ee953e7c665e2eb53d709cda597d0fbe25f7538611086a5f42e1b8756906eadc43ec6bdc3d813b5e3e08fa7f8d9ee200bc098a16b5e5c382f500b45232dbff31a632b5fbb846b65a5a2829b4692b192569206ddd0d8b972e5273166919915c7bc77d5225aa75132bc115da4399b05009c258539f514005603c34e83d1a7ec6b277354d7128f09c5c05250d4d4567a7299bcc30e2a4475ca3a476cb61e2f994bc481c30d24bb11139ba0aebaa4dc48a229f3e6abf570ac3794c1117eb9b1fc682ecba28224274f63baf26bf1fb25be6120871958e81ab6e27594e15bbb06bbdd5b05d727f9e31328c7e60d5a069cf22eac5d4d617f3be9ad78e78b10c37b4ff083085230e23f8a57c4eddf6930bdfcb9484759310d62c4ed02cca6ba7fc3f5ebb23b65dffef3c1d5d020570865f7d2e13dc090c8aea4f6f02f666abc01d2b17623fd5c9bada469ef4b70f74011e494eb040357acf588aa2cfbb3ebdc4d0c087d7692c4c39be0bda4894c834dfbc11083586a641133ddbdf87a1078a73b4187f75cafeeafeb674a64b83cedf3a2d65e9a494a6c01df470c5b46f3581c36462301c9ae910daf7a8309d95f39e630f8f53ac368f51c7fd77dec9cd73069b392cc5929269c0a2eb82bd29e8952a27e03ac427498b6310fa2e93517b1388d125330a9ec3431b95f1f724bc6711b3e9b7cc111ee39a485281adb05d422f0833d6cdd5a9ba3f8b29796a8706024ab87f8f46e459bd6e8db00346d356d8d9ab9b7ec821fc8d962c5373f146243036e3c859972985f574874094a3f76cd925375485113778c4b4905bf8a50268781b96acf0539baf9d2a05d75ea81142198feb5fe2743783c83a8c80b77eda68e353d18cbc07894c460bca8f1cf96eb73cf39a300c9ac13dae0995423f19ee40665d6277014b9266919455bc2a1a7f3589c426593ba3138cf7fa976fd768db68e86356b7606b1e713b3c41c065ce17dee516b673689b7520dc4206000c5c5f47d64559ead4134b74a6ece8eca619dcc36fc61c825e6416dbcf4821db0eb38496d0e2ad86786e3176cefc73909023c4b50e60f1860d3b9436c20c5d91f1471b95f82df96825deb20d84c8a3fd053c3e20b8567c1694c20ef4a66f5edc24c07f511f1732427943414f601c9b376629a2bd307983834e167bc6552ed069517680bb2d3cbda51986c5331ca35806bdf327a9c262e8a26770c84d227e1cf3cb785429960f145e2ff4232d5f80388f15916cdccf82a44b548605138c5312b087aeae0f2712cbd61d3557160b14d4abf04317fda74db11186f0"""), TestUtils.hexDecode(""" -62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), +258FBC2A94EE48B415DDADDF470F14FF8DFC069CD949BB88812CD27B2BC3D9522E00F302C0B72533C9A612A251BCD292A291F3652695D318927CE1B922125B287FFF9B1AA2B79180622C32AC624E0463E5F48E86EB5952CA1A95BA51388760FC5374F0561FB8873018DEBF785FEDAE4CCD1A41820EAE9D7056BBD329E7A95F21A4919A109BD27D26779C3588C9A886EDBEA1FB97A8048DED858B299DDFFECD4D678820E5DB6CEEC8B1EA879C9C22FB7F59B227B4F7C6AAC577767D899B2F11FE39D1ABC527DFA0E656F25E53CA05630215C5CCF0FC071F124E48C57C5344BB103D51A1FF24114426A324BB16D8F80D3CF2D0CE573F4E50DBD1CFD66C05430A1109374CD84156D2E31C0C3F4DE2F1E225B5CAC05D56C4478929E356F7F46032E2719E07BB1EC207B32D241C87D87ABF28C7CBCD38267CB011F26A9B49090008389417C7A219A9F18203E6D907D63AF4C42C60F7FD99C7F9394021640F450A9A072BF2C1CC3EEC88BEC866FF1FB5F032567AE053A408342A56E3068EA168B9E902068EF808916EA58004FF31C31DDC3FCFC2CCC92E0DA09623FB523AE46C8CBEF92A1CFCF4C0F523430E60449E5825A81DEAFB2E26B3131F0383B8FEB4B1B4E1499E89E9C5FA2ACAF1F37C422CA41ADBF907EB984DD65D8314E2F71E8AE616C0518DE9B8331FB00983490483362802FBA242E4CB71056E3256BD097504AD13F577B36A2F9FBC1EDDD25D9DBC09B3401D58FBCC9DDC8E74BBBC897552FC826620060D3777455BF76EDFC059E5C02BBCCC0F05F86ACE1903AF2BB08A962BFE9E2C435EE8C580502351669AB7DF3D9F6B4720A0509BAEA97FEED3B8C769AC5D0997A097852C72DD6D5FA0A7144E08D667F21936F434953EC3C88B5BA2EDAFC4F87BE8BFB5A592847D15D5E5D972710A4A75A5772DA4D9F156563C17B1F0F242457A198658524B0D6A46DBCD26EB9400DF3C4C942FF53E1102411101B2FCCB58E3FBD16E725147960AD56C6CB6DB336857EF137C49D53D16E98CD7A0E856E2D6B391A95954ECEFF3B9956A6D0C279DD9E1FA5895D37EEA8C54255A6244002C7542789453B41463B084E7FB3361923C43EE1BA115CB254F47E55E6EB79C74DAB4C9CCFF486B8CF5830F23BA23C5CFEAC2DDF7D71EB5F54141C100E0AA9873D43F0AC1034C54193BC63A560A0C661047C508062A70B3E575CC185462A75230D91A3021330D95F3C807688B032AC15A9623A833DB718D04603ECE983F1D21A4513E80CC67FD34EFF8E377B775142344645872844BA46F5AE6971E68FD8ED640BFDE9F276E26B208A8F3D74ACB739C7EA6CB26165EE182F165EFF21905DCE3D02E432B1193CA108B6ED066CE95D549D9B12445E05E0583EBEF32F17EB121D80EC26C1F154C4DA2ECAC841BE1CC7224576EA43ADEEBA53C4D58785F36B6BC0F8AB23340B92CB87DEB0230869A52DC634F68A83BC1AB8A4102264CCDCA39A51C331F6DBE30C18C00A966E5692CA86399264399DBD3F02FF8706302462D62E4D16B5C2FFEEB02A7E8447C2CF1A3FBA5046C792FAE0B1079621D59C1D7AAD17CD6578964D1ADCF1256F2A4EB4D534C51313BAC17A9383B5BD02EDCCDFE59998D2FCA7F3EF52CE0B1842368EA66E0A83FEB581A7137004655957E91B25F5435BEDC0ACCF69238AA4CACE418F08ED0D961E13B2234187597FCC012769F798D969C13F6BB4042897B0D8C32E6CFFC06680B1E0A40F5F149B5974B0E7F0D45367E93B415F7F6DCF86C2131137DCD0DE30A3F1FBCD5F8214AB20BEC9738AEAAAC200900F4B2074688C8F3026140A354A22F83BC2ABA66407F87671C3E7EA4EC6F8272B6D16F3C66C76ADA231677A9B1CF496B3C241D2D1ED7DB703119CEB162EB097A0AF2729D0D6CA8DA57D83E1BEFB880EBEFE090F6E98D64296F7CA90EA1C2B26131676232BB394BCD1A06BA83004BEDDA287073154D3BE16C242DD65839C2E1125B3E66DC93A95C62F5DD31CAF9895646D5E2D183D40EA09843F5DB189B41AA4CD1B40C5792C2BCF9F44823EDD4246100457299E30EB2C66896F89F4FA250AB19CA06EF5B899CB96FC5E0369B773691E3447E68475A7552C10F96F44B3282D92AE49A246508A67EAEB9F4586074D6FE8A44D2D27C7B8FB4EF6BF701084B73641E41AA7275C1D6B517FBE3D60F64BEB9119F3FBE96A11AD45610E63CBDBD79929003BD1F2DE89DCA036973974FE5C5D5A8B5BF82DE0368DC60D75A138CD91E8A9233BBD439666ED1211EC2FE7D7BABB1247315DC480CC64CD8F7859BB9BFE8C668F112FA96EA48BD91088EA44F40D3E57314D3759F867BA52E52BE822400D9B0C2123F50601EC5F8E8B562C4B1F49F9779A99C926FABD8A74173195CE23173F4CC4098EED74C8E0FA74320772EBD1847AFA1B397F5A6F05A00179DEF2E6C3B092D9182CA3C4E382C4092396005D8BEDF6248C81D3AA0854F0AD43C1079CFA1E0A42650EC9D7B9077BEED377BF5FB2F3D2717BED04CDF2F7E7D1F45CCC6F71A780D2E5C3516E5F6211815FD691E036E4FA002079448AF0E005B67D2939CA88CBC57567F634BD0402EAB06805ADF8BE550B3E27452B372CF8C92A7055714A228986FDCF4045421321555BA06173CA0A761BEE635C541FC984C5BD3857DE696E9B21EBCFB87ECA437E9A7B54F4CBE2A601824EBEDFD5446556B64E1A88B0BD9CBA507C5419CB8CC4CACE48A0C9668FD2D045E9057B13BF0785F59B35338501B73B44CB749EC2EBEA97C9D29EECCA6AE1FB719F9A67E8E175D50B2705B6149E9D5D257B34487B547FD050FE5C998412AD0B4159C2225EECB67903FFE332CC3B86266C22FF7776334543C1E954AF5A89C4FE59C1F1AAB5097024E2AA7BC09831C9A5ADB713591106CD3304873BCF11A9138FB08B7485E123DD8F7C107E336659DAFDB866487E197589DE47D2DE8298EC3560EDE21A633F820BE6352CDE9AD51515D309C4BB4709F171CAFEB407ED1A02BC4AAB53588C2CD4C273BD527F8B4078925FCFF8954536E0B4366E474801F5B938A4B81F037764D5CBAF19F237CE37D00246C60DA652B76469BECABD51F873DC75E520A75B52BF585D664B4CB9A09F8EF3C03FCBDE6B9E595C1371C2CFC24C16EBC392C75D2BA04212947944BC0377DB718A7FAE0F6F9008AC7DD30B94C1FCC6BAF750217C0119736E4F3B7E744AD72F1F0694BC88F71E4BE51ED8669F0E814E12FD9F833286E2064708951DAB852774D4620A26100FB44A8A92B86E17507C036CE6F3ABCFAB91193CA4BC4D4198DEAD7CEFB71B01FE2506995F2ED3A02EBB0355E6B67A2294648B8D1C1445164D99B966588CC253D1EA1361163024372E2550E9D29AEB4234F5F9B20AECEC01862CC98365F1C57FA4D5E0C1F8BF189E169669F825DB43172D1F682DFC7729B2AC0C103ECE4ACD982D86C515A208519D23F62934AF981DA66B97DE2389F2F669EB92CA4A5C4C844FCB19903371AEAEFB32E210F2D1155576566C7B529A98A1CDBA36B450F3948F34F90A49F50E7412E6EA68BC3BB0B0A0AFE3BDDEDB718D5A150EAEA784859953FF1DD1B371C539243547FCDFF4ADB06C61CB49EA5783AD06BC8C1F3E32A95AD3CA6D69EC1D226BF9DE0562888839E6243CD150EF6953C158F9FEE5EDBF173997D08509EAD1ED4DC2AAA33E18DCA6F59269CE457C412B58C4483BC96AF5069D1C2E3F2F8DCC5FE2825DA21AB2280984C359DAE44C2367D6F002D64AB47F9B64B5656622517A5F7D5E1A78D4182B6BAA82E0490659CBF2724080A9ED39BDFCFB21BA362DC29C750C5034A04EA5A85799E01FF8B16ACD2EFB8328BEC686AFA20E591E7C7FC55BCA8BA1A3C388B785AB0F57208CEBBC5619AE3A0B799D1816B013BD67D440A7AECA7D0BA517846B68F70CB5D6ED46C36F663D6F242E8FD8C620C9383EE1BE9250D63467504B229378D2589B525348DFF852AF1676A18DE321DD46D7AAFD3DB1825F192FBD3F160E8CA400B201B1A61D0864257CA340F179F5F1967659AF4789846A4D086041441DCF4267681B83D4C8539086E276C21BDF677961015CE550E41C2C45D67A09AD8F56AC3ECF1058F366F2E35BAA9353A5CA40C7021DD09AC9FE0187C10EFAC7BBBF3B1A462C9C6C96699741AC16D3526BED3B30AE25B8E8A9ACD8CB2BB6C28AB89F0A3F0D0F40D10AFEFCCB067A37A2C93D3E8399A366B5FE4829870DA75B93249DBBE3C9AC9FAA70C4E414EBA720C323E6627759E7287472C3DB9CA9B1A5FF03E872374D6B893BA4887AB227E989D9D4D348B3965F7B96C5094F42D84432EB771BFE757105966C9A08D6C58DED7DC216B3D0ECAD2D0B025DF33CD3D813348B5E08AF95BBA08DB5BFE5D0A151C98A01ED27661CCF80F416A1AA260EBB56526AAA289F17FF5AE97CD0907D9143BCAC73F1F83A2A8DEEB3ED209EF0952D5E463D87145E0E4D8BFA1741E3FB737E14B5924F436D0183D98EF836DCA3F9623B50CC13EBB5F94EFBB76EF9BDF40CE6EAC9C49852D08E2A5A193D1DACFA04EAF3C545E0E25E37E94DF51FC1976BAD069CA530E19EED277141BE62239F47441B88F6555B0A998C1BAB53758A41CFD8CC4CDC54E1158DE15910408A6E79D33CC37F61917027E9D2F186466F704647B1CC1CEC06DC1AC37D1A668D44DD8B12621AC3CBD2039BF5A843A86FA492A847D6552E1570DBFE008F51652D65D03D8B613AD917B81CACDFD19DB7F4DC9A14E237CC6D7268FC5D3B228BD88ED36D8360488509C974E01433D78701CE07108C67D0489AE94076106B045DF7CC508466D35BCF156901E53AD2B5ADF8795751891A5839033A40EF3F5DFE0BBEBFB2C9D1C000691F902AE490D382EBC87FD40E76B30DAA963254674C7B6F304DA2C8BDBE8E1DCC87DE0486B4FE6B57A18D5A9E9E4BAE776D6147FF9C98372426EFD30C3B2479231E624A253A7B0BEE31E0FF739F862010AF03E227A12C3ED1F33EF1C0DC9D48A100FA24CE5C5D8B5F88F92BDB6A3A5328B0AFA983D57A1D3320A682B5CA94E75DCC69BDF2AED0C05887B791CE6F6F8885E4CC55C3FB050ABEFCD3AF2CA603172AC78B3AF2B047E506639498D0391A06DFD328B8E1BFAED8F76C6E4A93E733ED1097DAD8663F5BAEADBE1562D40C772D376786509323BF059FF17A5E6EF5A31BD668954766417E6633BBEC90B53ECA61BADD4037030A55A5EF4129D4958F6A8A5ECAA1AE7E220A87AE996AE8D9AE46B9C60FEDD98FF1E67807037970C92CFF9EA4B64F0BF8907198A6C038F9826CB968B1F301952E1F409DD6AA4EFFCAB157E792ED45830708ACD7A50BE8C08FCD12560344221104827BFA495604A57826A49F90B8B694B2BCACE4040627AA0989E3DB4FB7167F50E8A04982084FB3ECB0DDCCA5F24A7398620D19B37309A4DC0DF28909E16645F35A81EB3C5EF6BFD650571DAB03A7FC02FDCCA5FD09C9D2D3DCA888B8261433DE88D05DEE5D6165080A237D55ED718486AAAF1E2534CEC3A87048ADB40EB9F9DDACFB2C883EA6B20BE1EACBDD72432C7A6C97721FE1E0D9A5589C951F7D46F2C5F0FFA909FBE12E1CCF00161E741C4505681B0B018FFACD460528795CC3810BF7F94FF9B75884956798F21ABF36DEDDC1F95890894EFC15EAA6F19E9148C71EE9BF4CFD41EE3E5DF8A449FD95E5744793B9C223D26ACB44E691D7E5B68D49A19687F0237E7287841D3B0B4483E2A7C29CA81BDAFA5D96D9D2CB6FD9724B9903E8CDD03DA810EFBF94BC7179349E10566B5A314F81327F76C5A8346E222C408EA43FE29439132CDDE79D0D69C45C7217399205C2DA4D33DB521940C4EED74CA22645D5B6A549E8712D0B8CC50DC180067D13457ECE66D489F687DE218449D974620B3B5462FF3A7F00C439AEC73A53303AC51EB84BBEBD51AA48A5DFB8F93556BA540F5101CADB8BDB912D7BC87EC2AC67971AB99093C8616C4D1F3E7B06003E4FF22D99E6CAD7558EAF5C1410199EC97720E5C9278548E7EDE62BE9105A2B27A54D95673849CD5D60424ED97BB64798263F98A63DB58BD55965D3A4283797CD88C7CA67B1C4F90FC7237EA35AA24DB18A4420B827B3FF7FA5472C31499480EEF5A97BB967D1EC46E7B05A3D25212C75972D48A9269D67048132399E1BE0C02150A3D48717E4DEC2ED47458EB870A1EEE5381209B5D182DA2093AE46A4D99E3D4F12ADD71001BDB936FE8AA96797982F88EE67AA2E0F340E7AF498D5AE05C177F0BD2650A02ACD4CE23018F9E00DCEB9794C5C76418EFA65634E01ED5E9FF94FF86AA73641117BD554A9391874A75C7CD1E7759755B9D2A7F367621C0011F61B588D913C7AA0A0EEE3A2201426EDDCD56A020F54AB41CD899721D6E1F05F8774CD5FF6417CB68EE14C20D9234369C9CA59627B8796C37B4ECF1DE2F981ED0FBCD5737DF0B82637D599A61826909C978A2B68CEF01C5CF84B50BE77B49C1887544779BFEAE3F533286287E48F0ECC0D36C27F1209314726855E61E5EB5E9A5D7E3516E29DD369F94D72004742E246AD4699C64EE996BC7B2A079344ED32A528A9CAD6D5AC02970D0168A8B5BC713E28934F2880774418550AC2F534D06B61E627BCB8711AD9FC6F2A4D9301EBB74E1F3C73B05F28DCE5623BE1BFA871C14A947A947CFA806AAC43AE515D6CA65436BA6B66F62B0FDC8AA4A748DBB72D9AB087AA39561271A986229EC02BA3719CBB1798DD333248E4DDD0B6EEA4169D3B03C9F4DEF9616BDF97AE993F0FEDAD31834B6F78E23164B556A39AC1F209581F61AEADD8E504E81A808B1E97F79F987892A8F7FC35FED9B1A2E9D3E17BFC5AA64680DE98664FEA7B479567CBE307AF2A8516BE4CBF9EA030471428CF802FAFF85701AF96CA1D8F50F5A79AD63F20C5CBB954011BE4B1A7F627A8B5F5A0D022D27BA6FCB8D3587E8632A2FE5794C7E8FD09C9AFA3021B9F43BA82EF48A3B1F3E40F2FAE182DDF9558F7033773F5627906E159B794C4220219BF1A9878B175996A16F3CA1DDEDA56B16E63C504354E5E42FB90CE4D2C1AE7C93D8CE27480F3BCCC076CC253B574A7BFA6D3BFABEB3FA6A19F196C7E31A0D6E9477F828689FD951E0FB033DBEFED6C680F0FEDF2F43F48C0136C722601CC7C4B48B24121ECB6BF84D6B3DB240FBA1E014F7E3ABDFC1F9B98A16F4D39826BC1EAE44385FDFEBBD649BDDA129FC7EA3F50A5F481D3B7508EDEB04FDDB3006D6EE943930E3F0AB405D151F21E8AEE5BD87F225DA6E155158DE27290B2048D384BCC54F0EB905961AE4CE5E6E93543016F62445AFB5C39C3EA2F3367A0B8F0FBB83B37518C5DBE1CCA1DA9D0B54F34B15A1349A2F03563732DE14EA9BD238F481D9B262DF69D24A91534805ECF57A538D8F08B2FF11E96EE692DFEB106D3515A7C69386A781DB1D5434AC18713CCA12C92557D1E7DFBB15605AE3BA86267F3E6CBA42B6084478E460F092BA2649C8C94D66128FABA2D0EA7D9BCB20663B0DE6EED2623A061778DCB40373B8CA38B02B7A49F6940D6D11CEF549CE80212CE8D3A85CF2D774431343FA1FFDBC71C5334B1CEC4D4E0EB643E1AAD67D1A5B73FBB1BFE47EFD83CD17C798044A504FBBA5726429F41DDEA7B7265A76A48B0BAB4845704C771638977511092BF6C6DC9D574E6288C6A3B96BFD37FAB695F8DE20F28ECB27EDA70A07FB2ACDAD88DBDFB2DDF06E83ACFD3A136C5DF4811D34C242BF9206D579BA8DC6D20E8600B726C9F1B918EA573B9DB2F96444E17B6EDC15822B85D452CD99CBC847AA205EF79E574ED9625E33B6EDC793E5"""), TestUtils.hexDecode(""" -9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") +d645f682a1b7aa2650f431a828463cdb131c1c317bc2d9a92477f9ce4a7190d287bd352213726174bb967d2538e6f796698924d4808a15377e3d05877a560d2cfbc13150acab39cc6ec464ae5fe51ef788aad862bdce80a3c3669186598ea3f01dfdf9479caf10033fa89d5bf164b454b1c909edc6a85793b2f3662ca4dabc42bf621b2c5f55b357d2b7c97b21a1748d6e6d0cb3c2e1d891b057f0c3bf482f04add99ecb92d32a099443987c25b1a5e26930082e9719fe2ca845343c3c0208d35cada03bf51f8952ef49c18c916c03417e217342ebf7234cf9270522b3f6bf7dbf5f7aff8b245f1833b8cb314f86b1e407f4e0b49f2f2917bde67c9ddb7fe39a64ad96811980b530df51645a89c365602dc6a6b53b67e56c74951d72e0cc2a7ca5ca0c1b32c3c9700fff54c317b3bd1474cb3cb402a85ba80def7b994f84018b9241ca20cc5ebe6cb24b26b4ee21904b658954fd9716004a009b762c5eb5afccfa8f6153d1cba1358653a88c0b87dc6478578929baee5bf33065aea3dc0bf333453ed0fda613d9a35e00eaef91ea96d87b676b66963d2affec30cbd7dbeed1f36dc93527db0a082d494afded3ac6df843e385a53d8a7a0dddc2a38cab1a92a649072768608fead5c538d8767a75f46bb73f7971a41401b8fd50312aadc6fc5f2096007d6002013ef9fd66be15822ca3b001540652636a8dbe65b2b6324885504ce3233f6fab6bdb5d05a10d85ca8b9934a5fe39d7c3a095530554d058f2f99f9c2775a0822ceccea548a35fcae73ee931ca01ccaadb226f91f0104743c423b220b9c76654c9baa1a1e60310673fe86e8c71eba544763f94b80dd075b3fcfd82956da9ffd4d4a0364e26cf4c4d7f0d2ba435a4e7b51b01e9cf55251a5f8fb4e32ed1fdfb6dffac187bfeab67b7bc06fbd1d623c68823d45d708ab29117ec17fb2df9ff17378ca7a021b504e678e4b7371f2aa05588d710f292e547f719f7d2e66ba39d382807ccd3cfa8ef2d33516053e6ebdb2a8584982efb880180c45480939af7b3d72e71d046fc78088c16aada249506b079daeb16056bcf49d495e5f5bc9b64125f66c809e02282e26a8b8c9656d19b75eddb4310daef82ff90bb199142ce3ea68dd6ef33cf4d0f2e7981f2d6d78beb9aa10ff7421804231b02b39b3e9c4be9363c49fce0b5a460f49094389ef2c28bfc45c805a563dc2202bd9da12485eff443013dc8090be20ba1430eb71516fb36926db06d59f5313d43294d09a5c242edc04ca7f1f69b3f87861fdd572385ad400f66ff9bf127e866957b5b7ef7e16f0cf93cd10d77b87894fd8c0f184f0a359cadbfb5fe6d91a06bdb000720f202f077cd4bf5c8b149565c43b4a07cdc5a3dae7599d26f3931d101d086b9546be593ea0bb85a1807eebaaa798e57d88d4b042aa3e3f621206e22f66335792b606f419d1dc63367d73dc462ebb177d3d9d4532ab6c39341b447af8a982d24300226fb367987aa37ed10223083e4db66a5a344628310d46174e0c8b466fbc0809905d416e1b742f3749ffe7ea56ec6c28b085d71d4e315b4e49d6ec945d23ecf5dcf503c59b839446abaa0ee57179a6567ab4d02fd1025b671aa5a464e1892e9e2b96248107fbe5fc4b792d1b6f62ecc6195be7acd19d76eabee8e8deea2ca2661a382f06e4ef90179a4fbe255f4a617bf6c1c3c564e05d1eac7cf110759364e7d3045b2330a52bdbc8ab2307e876df8b0011bd2361471c6cfd7fec98dd4161bd7f7517fa6bdd2d678dd4dedf71dfef7eef7d28d03131aa2db37f163d16818aac1e4daa94c6fc8ac8d76f03f981d98166431fb42081dc565049be93013f71832aea1c20dba0112222bd1acbd7e7c112ebfaa6e264655950a6fd78da09d55838d2f79a87a311eee67f023af189511c7e215cf8bf5b8f47ec397ff8ed22f5825814c86712c289977998dc8c7ac8eb60cce95ba56efe213043e7065d8c6e6c1c6b7c4b87f807e6375fd93e8133b9ca61735d2399bc2f0cd4e6d28c21c4172f26808a70ec7d5502449e335abfd7ec5e45fd298cdfc8699b2607745c30c89803cc741b1c74fc6698fa95c1397b59ce6a08a19d3572fa395af1f913af021cce85d40f53d511b2d6ca6860ffac07dae4de99cec54b0608ccefa3395e327d67aac3f8940c03c737f0066da5435ff060320aa68868b2fe309669a014e0ce7eebcb3e9f3d27684c0d14be48ef4d8de1f0f541c2dc22160aa238f736de0f31996fd1e554ddfd33892e998180e4a47fbe34f6e9f2004d009e83fc55e7c921a73390f6fd44a7f32122968e174fed54ad1117344325897482707ce6cb45121266c870f3f560c4315f046e3798073ee0ca7ef718176458c761825f7288b6663bf48b6efcc50e35a5ad124772fb64967056ab6a39658973471ecadd3d666e6f0377fad3b7390dc9ea67545fa030d1085244082ac60d0ba4d6f0ab44167571324e40ad664fc95c25dec94bfd59b32332ca5efda8288965284c7f88fb8045af9169eb63e98405e2aa3e949d4ebe07f3450ce6caa14e2b399e26a347d88b2fa8a301032c39bbbd945ef5d213cd4b3418c25cdd175a3ab8ffa41679cf6359ea3c28905309af59f0f92cb1db581e21da648f096171953fbf62d53da61da8eee1d24053270ef6911539a7ee93c6ff45a0b465ca879498e131d37d1a05be88fad8cc28a3026c7853b9a48bb8f1680889ebb3978b738ac7c3c54a0bbf1ddd79819a70e9d083775095e1daff66f72df70cf17e746c70f3d291a343d4530b6c9dbdc861816ad799b1a63f807fcf791fb1ca2e3160543abbd10e4fab61c18c3c4f150519d9690f7d22c10bcfed5c211a6af6f438737402b425c5ae274ca98716bf64b127ec0c7a6cf3598e9bac44149b93310ef5de9fd8381a961d5b9c166b7a687072a1aa27a8ecb2d9a023d353bdd29870650e0626931654ad80a995d6c5ce63ed42ec35444ee57444ef7edf45afe7255739b7ea731dd4c48a1497b5e6c135f4ddf4cae02577920f795809c1d00a391f15e7e376271c0cc0a09ef69efd28f6a44b6d2a9577ab7fd2198f81b92cf4094c7186e72fc3a379ec9e31b7bc12873a0008f40c14a81180f4caa16aee8ed827341c08fa4c98d3be393d524abfdf5546999acc4bb74e6d72b7db9c443bf8bc300fbb0d19ab0a716001cc87dd27bf2605930cfa437c08b0392e8526a26dac97e1e692baefc515eba1b82fec70c5eb4fc950386be3a5eb3379537100649cd192d611dc90e5787dccc69a364afa632abb31de145279e9d736ac1f6185f332b75875006f01eab3a48ad573d4e9b6849cba181d1aaeea5120fac5da72d81e7a36fd0847fdfc5f7f8f589b98511bc086a107d1ccc4797308be5b590ccfdab138078ca19679a5bde6962909491e1df2b048924a235819a7a28e3e3e97105a1a400c0997376ed9ff34b48d6076fc8d9668e6498171b82d7dab2418146610d80c2c7be50f614c6d5adf8511ce282d2175ca5101bb18dac9207813b9be0510a2195cc2c746d2bb99d3049f29374664d74497e0372994583c788765f3ac918db9a4d4d1f2c2482f50d013e7e93e0a5228cc03f4db0cfd14aacd90ed05b7ff5cca2b00f577e0ba47e7a0eda068f1aebbe688f167e3af3bcde28b3bcf0e89c63389564fd60be1c8919ac245db3cab86fef9d0bd4e365c1edb0472f4ba23b22c1918a399e3e08933031b2d0ada07b4c89abeff516f06b67e2b5c6bfe4fb6671ea4a45c375b9310f07278f0594e4943f4e45098e3c68c2c7f8b4eaec3b3d49a21c077469c84407b2ecf958c7aa3ccba4833a0b8c6f6cd8475c4d239608b9d25bcd9324326b4251b89579f2e902724f26943ae92b95487b215d719236f69eafc46070695e8d4a93053e275b93cf87723bdd589c15f722c093ca50c1d54121bcbcdff8c4e306cd4f11fcc681d6af09cc0de076a252bc8583b5afba1405798756432a729b177906ace7f3b8340f3526e7688fd49206e6853b4c72979469a30c584786f2b8c75cadea9eed04cfe68dfefbdd2ed5e1e2b3397ffab7c5d84e645a4049e50bdb9cb2453092354e0112cf00fd214e22681e4111a7d4563b84828d6bf6450facbdeca5137699c551f2b0c7a0bd5ce147dc71dc2bca5b0abbeeb109e6e951115c9c8448d455bf723b8e18e31b480e5b17c8de45d3f73ed313b9bd6a8f5156cabf25eea4737d4dfc8ffe042c6cf665bb346d89477d1faf60ace914eff5db92d82ab2da4e08de466f532d1f7c639d71e6c3dca9bff0c5a4948540cbecf4aa65c4dcd7caae9cc3ac56c04511518c1ebdd02aa8285b05393ce9fc2d2a3d8fcfcf79d4f1811d9073346d67f4f9af28d15706d577f8592c653c315a396e03f3dbe81c339c220aabd4f654239b14dae453dbd213da8819df690f38ab52a1f67319dce8ba5cd33e9bd8f5e61c0e0107e97b7bdc384269d410cbb77e19f2d89e38305c6e7dffb952e331bccdf884956c9c67ddf2d56c048b31ecaadea55e8efbbc94ee0a19980cd30edfc85d6b3ebfbeaa51ab1bb01008554717bbc6b17ce9b8b255707f95b7302d63b0189aa4e9eaa966429c1c1b9d2aaee73460a2335455f8e9df22a2c3861cd354f5163b1f1fc212f709c040516172a63acc5e6ee051f5a8a9195a3c0e3000000000000000000000000080d1418222b""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +8ee898ba956b2d9173be3179771f705dfaea460258d89ebb97518aee95f7560abe8e02119cec52c27d34c28ef28453699fd6ce193970443d211c471db1d15d60c59facdf1e49a57e03e2398a1e1375ba9f1250828cab80097369832edbaddc174c175033649f9dcaf8cb0e3bfcea913eb47a34946919f79809194df8daa2c4ae96c85bfbaef5d2519e3248b475b1e3f99cca049afc80599e671eca3ca8db36163dd4356d03929fffae072fafb039c2b091e89294083573550f5f7a5d8eed887e26379856a771f65d31a70a74db83ffe8814b7b52ae41bbce25aa4c33082177045d6d2acdaaef17bb73855f42001469c6b0717ea0a1dacab68372d25b575abcda54cc68db475132d20cd722f2e9eb7c2de6280ec574ece4c921952e79833f1338307d468df5cda8a70441b362cedfe524f2e9167070d475eaf2339821a1a1d576574b986d20e82d69e91cc84ce00cc82f4aa1c9907f6462119997701d9bca1788f1472c03bedc490d840301dba631eae8c1113274faf8923ab9ebf52cc80bce16b1db45d2ed8e4a14c4d63a74cd8d91a48b1663f8246312624c125e3abebf2d57229ded63f422e4bb0f126f9e47f5c301493d4c63b0ef611a7b141b74bc4971e2b16d8156dd759213ec7febbe076a8a534535353d01617b2d119f912d112e4f53a06b9f267b1b4d2feb6688195ff5d57065f54b2a18cbdd8f9d57a3588acb5822291cb8e01e2cca5d74547db3cb84cddc2fa2afb9008af15aba2409662989772108283c78b6a745b3f8e311998de25c880ee8a74f2fe99e45a7ab3db69e7849accfce7f8c5b726a888dd2bba623ab26145c933db5ccffcf7dad6fb7ad918f93fdef9f710fafa54a29b774d1ebf7f21c339c56616fa1c3865a0d57b45d0c4100efb16f8f62972cf5c9855bcc537270dc50c354c324462ac1c71d671e0bf37db744542e4ea766cd5d96c9e6349f64046d8c402036372d43705b33fbb3a261ee63700f79e1c18ccacab0d351c697ef40029c08a76c3a7c2bc185e03589a91d4851af6bdf83e3711aae0037452a2495d7a88d881504d4d251a24dfa389721c52afbfd0ecef34ea2458acf120bb122e614658fee8af89dac06797ea2d74ec3ccf3a1ab4ff120d5d69e0e6b08caf9ece5c58d0907419107d610ba0a61359dcf3fdb6209c6ace63e9442e67b7e8e78e94cb21143386eb5d5011ab83cc9d5c5bd03af2e1131e18433f0372a29c4f187049f7d58b18ddef1fad39c46c433268ae6d09ace463a5e49a130376a0dd89b38b3728161b14ade010f532172b71e887487e9ab4eb97f471f6aaf1e61b9e7c6742cc63d6b96443d67488746a69fa23cd89e977b891c2b57351ff75f2e0fd0316a561fbd37720cac1bb938ecc8fb5f5a96b97fffc1029dd1ffaeb87b20ac792e96294eccd88d2e8ec625e0fa8fec32b1592eac7f63c53320653dcf54ed35a05809ebabc6d382fd6eef515adc3e47319052278fd2f6f2aa22f6b85a71294e9d905228090a70314287802dbde42cd94e06747d09371e9860089f62c2ffcde6913a7b01880ef254ce9f02e6817ca231053d1578eeecb88c5afbd1cc23d5e8f10d983bb9b653f03c21fed44c3a327b967fec03ddcfb6fcd6ae38f2b0e1ad455c772b5628f2db1a9928a5be2e782871dc99c5e53d47a7adffff983ddc0768a52a4ffc3295f804bd06271f134c3d54b7539ec4431b34c7ff5dcbadb2cda2dc2934da8c153df98ccc225df28998467a782593225e7dcfa86f51c65777fb79d26473353a871d82341bf9685ecfb2a10a8525d7962247c399d19fdfcd24da464b04e3e312292bc7749f15fc3948b1b49c592f0b5ad01b0d01cc63c3274a16c1ca68b27ecc446a440895009251245a0989d2a643293ee17569c6f8551125279d3454472c8697914d22dcf5c2b0da92466fb66f08710957cd1d54928de436409760d481e9279fe250d3d4f2759db8fd7d7702e552cf5cb8aa30acfcd2af2c0546fb2aca0c687570dd398cbf0c1578b39c1b20e433f0b8a96d9ff715cf72b09b78f011f9c0c05ee2112074b7824179be2eb9099748fcd2d79919399e16c31adbd4decbb52bafaf895575e0c7bab7688f237cf0e0b88b714a3ac1b7742257d5ffce53f92c793f5c06b6193e55fd4dfaaf05559e2df4e12e5982c3679520db10dbb04f88a2a643d6ea0d96a0cae9b45c9d185d2a896083cb2c002d56f4559cf2aaf8cab564e7a5f14628b22cb8c0e2818f2e7da1ad694f9164228a773113fdb0c3734932d9c845fc694ec3c8b0237ece02ee1675e26ed57aa28d932caf8d31f9f6043b326211161266ddbd61a9c8d241ab049713977d1bf2d446f3c0860270a401095620db0f6faf43af3b1a6b1e33fd0d769501a27229e4195a138057befd232417282d9e65754d2311e5c547e5a85fbc34900edca8cf487ad2e3e7fea9ca7d88fdbebbc2fe736353df14221accd45de5ec983847d37821b8456c687eec93ce790e1a2cb6c84dfa2fd9aac2bd669d23c02ce78abcb1de43c4f3ea879b8b73123c00b48517b3de903922ebdf51fa632bfd4debb845113ed4ff66f9f20133a3f2a02c933a16ed747668313bf533bed5515b3058e86ee68f0d3f043e797e54aecdf7ccdf5d771613b000b7ac754a4ca6f2e2227d00dfb5231799698f12ba2975f842aff5f7252d49f05a6713487cebded694aa861bedd2fe11fd0fc4b4dd6a54fafcc6934aced6c75680042cb4137b669786219c197803f34b27ebc00c13"""), TestUtils.hexDecode(""" -C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), +7C29C0B8E2A111F457E2384845E7698DE4BC9BAEF093F15EB03828664AD31C387B247A525623282460D60290FC479A928024CF62571A57F77B17DB0AC572CB59723490DF79E9B1B31EF2C9488B6D758C43EDD9162D8F6C0B03F43B08D646172A1F8DFD71D4DD805A3AFCF1C4265BEBB71FB251DC9DEAE670A664BDF943ECB00FB7EFA37624953F94CA760013FF1270C1EE7FF58756CE19C204220713724AD03B10F1D6961CDA361539A8AAB6ADEA92AD782F441428C0018D85C0505BAA793C752DADFE92BFE8F033931D47575C9F83547DB18DAEC0FEE90E83967E0D0DC93281000755303F0F5F05DE041211CF842404CD5E24DDFA3C7C83DE3EA21EEECE37A52E16DC80A350B3A18E88EB3C81C74D25B56CDB446F6198DC88F981F2B1ED8DC94194D81CAAD971A9A3933E9319047C5F31530C7C98793A0633875A14FA5635CD1B0441FE267E79C1E874BEA968CB63E20E7C48E7BAA9CE8393FF9A239B5A1D613DA65F7DE78BDB793AC72566FDCD06CDAAF56E18B773737A82298902F7B4890EDABB766E990ED87C94005A2E2450AC1D0192D72468F81DB414F88CBF07707A95F549B7A9EA0760821AD710D52787730EE8917272497E5891656176F991F254A5D582B5975F95AF740421A3C18A82158AF11DB15C154F17ABE1163F997C64A3BD989A573D12642B9AEE87C1612A39A8A4FAF25E35AFED3F2DBFC8FC8A2F9DFBC683CDFA3227107C50526149557CD773DDA16E36782A278A93CD7F4D8FB47DFC37DC3E389D164913316A885C3A800DAD0C57B1082BD4D804BB6A117C3B41E7D8AE9CC9622AE3CA8EAA9A0B502FE3F5A449BA8E768D2C98013F681C68A5F4AD3CBBB83F302457679BCD3F35C4D6176DD8D2B670E87EA291EDCCEEB9917F98CDDF5EE1689DBBC85BBAA30D191F1965EFF8FA9B0073D30B1E2456FAF880110BA9E75E4E29C6106874D32944F49DC7E7E7C56ECB9D287F2C2E87A779052F9B84FF97AAE007012A5EC497C4809F0193C69E5B29940510A354C866505424D4FF3853C94687636543115A73DC407C47927EDBCC4E0567EF4E451F0E464A1385D2A0D740C7327F6E92EC6091845356C2620EB163D9F774D7781BFBC6F6F652A4A2DEC73203DF5643E1B4C3C3DCDF0B4A0B160598EFB56499D2DB1F1E76612356AF3D708F9D61D968A6A0193D9146B2983972271A4C02E2136E6593DC47FDE4FAF2540A8F7744BC3230529AD1C9D2FF65B7671B5A5B16AABACDE8D45A940ABA4171E21090AC6AFF54CD8230F7BCAFFC42C028E6023E55DD02E4B7F976998AB5614A5681C615BF8E9E6959B038188F71C75F6DE44A6B0498F2A9254F3B0968AE7DBB49872D775CB0A5725206D648862734F202DF470770AAD184F822C56400F16F30F8BE40C463CA3EB5ECBB15D51CEBCCEAB43BFAD7DE7679894B90419B65912D67DCF2335212E82EFDB6267EEA331C1439BE2AF62E584C222C1052AD91C7F5DB6AA649F230248A14AA6A532401A28ADCF822089140FCD3B1CF2358DC26939850DB2721750F1537424F6BF2020A1B4684ED79402917D1028C1B59076867DA809D6C5D3F47277755384C20624388EF0AD68BBFB6A63005AD1B6E48ED654E8362B2AF7BF114F2D144A420712FC4EC71D408BE55EBCA8C2F185E7132196B1B76AA7BE44EB55DF7C82C768943D649631E4D87B408DCF8FE470164D9E8DD1F48CEE7F6BA93E239F889119A4DEA118D93F1474E516139036D640EC788AEE708637A619BD1693BAB6C9EE9EE0C495C0D0F8912C0F14199AA69B960F53E4FD8E2771DE4AAF72117A5B2388FEA0CA3BDCD594D1760905F26482459BDE80EEDE3FC89F592CA16B65B27E9A21F1789BD0327A26EE2224C61D80AE8FA6053480048D15019A80FCB5F3B3C6F64C168690E4384AC05E856BF341531045D2952F2CA8BAA0B8926CC41AF2D8BC5A1576292DD67114D521DD4AB535A77E5E9BEF8EA01DDC7C65446D11F90D6CADA94AA1AACFB1BC3551353D09252FE515A465C1879071F6FBB035DADA0BD25A022B026AAA5B5BD420237FF097099CA2402E68E4530F97A003E50CF693D1DFB551DC4695C760138E88B8D11F3075DBF8A6D9BCB9B1242648C0C9DABDD9D49CF132B0766302437C0CD81A0889585869DE92E6CB30C31265C84F58E9437CEBA891422967AA546EEF720A8FCC16EC7591AA0D47998275DF1AAA5ACAD1E1C5868CA430F4FEFA0277262C69311FEDBCC083114AAEC9F99FD98631137A117A9B48B32A6D88E76F96DC58D741395BFC102E147C456D3A78A0FA3D186485D65B4E6755B53D301BD13CC88E75277AF3CCF1EAC6E9C56FE1F10DE05A796A14381551705234F65DD6E717E9EC275E38690B73973C9CAB27DB909C5C13041723BB18EFECAD808667643E87620191008E4D10F471AD153D27F1FF00D8AC6A8C5E59197AECA5AB496D8D10BC79C49D16DC7948C6AF62703D36059587F6EE038820A84C0F287D79C713B066E1DA5B32BD89E5FEEC248B34AA5841E8666CBF09C47EFB17BC82170CCB557D41D40CC87F2E6C0246F0B272733854CE162538DF34559473BA5979AEBFC0D6A16EA7B399687E672145A1149E382954815B41E7E37CC415057D7536E65FA1A35B8EFAABC7B9B0000E08B593496B01E8F14FC950632C659C0A7F7D59787C7FE6E8FA7FA0211A945ABBA5044918CE8482C6EDB366368A9DDB2F2BB66C146BB50251CE61DDEDD8D6A4A60FEAF0F794B7B0DB91C52D7ED1A54AC85D7907BF3A5A96A60BDDD08F60148C0B3237DBD56628982375A67F025B0E3F9EE13DF254E1D6DDDBB057203CEB267200C7788D01342C064FDDE996183646FD3C1ABBA5D2155383CF391FF16C78660D0BBEB549483A4A4A971017A8659616FBB1C3A8A2E83230B610C0C74B8EB32667765F3C2F31F8C0D4BDA3D812DB64448684AEB482DFEC5C37EDE742091EF7EE6F22E31CBA2C9B9A6656888F446A1E9D52D9E6437D22594A830958CACC6F175D4CE8423178B71E7CC81BD6DC2A7F6580A8A3A1207C34D6A1646BC3D89953A63D22A30EB9FAC74103FA527843D3BDA656D1F22E729C3A004B923D08C9CB18CF406FAA89D0D63782C7264D5A8C8078EE6D259EE168A415E7BC83E4F17D9E674154DF08CCB21ADBF5B35AC28883F6943083AA97210C6DAE492C6CA4ACCBFADD99AED15110B10C9904469B4F06ED32546130B0EC4B281622A5EFC9C94B1F2280F251AFCAE857C4E17FF5CF472F038E02E5B7B3CF5CFD2F3969B9B8D5A27C8EC38DCA4284F0280C24F01DD97A618FDC5EB57C45D9E2A05B44E69FE2E47CB50F596030C70B62437F2B91A67FB84205D95CAE259AB1D5FF0454C5B4D87F439DCB7FC62B704ADC7A84502E1BD8E6F52109BF0F36824834D574E07B9375E693AD477A9D74E94BC4E883206DCF875AEF7FE84B9B7C1C9B1858E4BF6735235FAAE21FA566C866ED7C952B1BC19A911984EC25AEE310D8A342AE32F46255E0E00444CB0EE90C37152EDB6C741F5F394B5D47154825279465F0F8B19DDD85B8D9194A7AFAE5FE609A245AD68786C9AC044C008A1B3EFA3A8F4FA0FD49A65B6FF562F33DCB63754BE76244326FB6E416EE3267F93D7B2BDC4705EE7021D5D2EE66BA8D7B9DA7EE6C354E05470B31406DCFD2C32C94C22A72DE90E5A9DFBA99ECA95F73A014A3E9B15EFCBB67FDFA6D3CAFBE3ABBB28C4DEA6AA21F87693D68F0A60331786DE02BFA9E85A8D2AC8524EE184EE738BB3FEFEAD7E19030AE883707DF67ED12E8757B86E6E5FBA26715DBFAE2BE0F90453868931629FDE97712E08A280FF8888007AC27DF2C7113C30604C5DB17538F026F17C7F07D2A94AD5AB367F9CEA87BDBA712363D11FF5CF0590030BE9B342A7ADA48C08BC42F923DE939DE79616CD346B3511F41CE695B3F939C101F687DE7292CC96691EF3F3CB653F4A67D2EE09C791F993C726D574440EABFBB00E5E6328FA70D69FDD5F2EFFFD37C9902AA45EF4E9D06059B0D8E3686C74C94CF2F0032ECF740B31E3F297F15343A0093EE0B8D7F8EDA1118D329D05A1B992755181429D410771E37B56E28AE2ED8C4DDE8422FFE91ACE348E443640578687C57D79DFDF917F8E60E0A2F1C6223056C373F58C297F0FEE3060D31DCF6851856D1D05BB38B1FF426BADA10FD84B2E08AC149F91DDF4A5CB38B290DED4EA3B02EF7A3DF42BDC6B6205D281CE4A48A1C13FA8080B6B4100AA123097A4140415EC7CEC57790D6EB0B4200AD3DD9FB7FBD056A5E3E9D7B7EF47F44A63DC908B6DD8B020854618F7662391DFC35A88F4F5750D282F81DDC50D0132707174914293E3655BD2942C09F88627C0AFE4B921B766BEF41E246FD23482B5B14F117E8EE340C47C7C405BB3692C4C9E541148C2B38281EF0274835860E19C2D48953545247BD1F7A76CA43956C069A17CCFB4D0B0FD478556A209B5376BE9207AB174D2CEC96E09E1F8C0FA07D8920B2ABAC3490216DEBC67030E9285B3EF6767AB11E8CC935C4019B7E68FB9AF8864358E6927D350CC8B9A40662A0987C1C8877AA9903CC89A93E1979ACFA279FCCD2E171A467B76E1103C4EB166273ED7B4878908B67DB77C4FD4E49DB46109DA4BA78D69E03B48518F302647B8186F787F4CFCD87CC5A45B98F7558ECD0612378306C9D69FBE23B06005CD5AD84F73A563B1A3C7988CE0157D2D2703ECA8575D8BFF972CBED32A231395655DDB2188BFFB413624639D361B3388A9C9E13645C563A87C610F6FE79AD50765CFA8149E27F7083A316EBA050860A69BA56D002A78640D71794980C83573A5DE69A697C2CF2E17C90BAFAAD3D421C6E1D8A55B3FB4700B666AE3CC3EC114E9DB428F27CE427E4101ADB49B84CA7855458841DD1F4FE76D9074D940102FC47EA633744C2A664E22B5C5AA2721017F3FAAF4FB033FBB1D508EB98E1D643406ABD4D69C030A2349408C80993D9F75271F913D7417DA995443377E6F73A7DBA24E034A9C4820117D1F0BD69C93FF55CFFD2D36F8078209F5711FBD1587435517291498926E7354558945F721D00A73014C06B2C9BF04B7E695B9109D769BC2172CA7A70700A1D5AFF6F5FCBE699FAE81BC34B0495A82BED01B983444224B4B860360C07F8C3035FC4F0C4B7DD4D37ECAFD32E8C121C677ED263338359E25BC4173D191E869ACB4A5F6D20FD16FE50454CDD269DF8CBE5795482A2B40D52BCE5FDEBA62D9274C9C67127580795BC01752740E606D849AFCD6ABB8340613C61A764B6B92863779622E40EE7A8994034E7D303F07EFA11ACB70419A53897ADD558CFE157CAA3D47917CFE0287500B3D70FE42AFE36853188BC815CFCEC9F56030C83E85C60401912C14A75A082DE2E0400F6348EAABA59312C51A7E3B6A5B39D606306A304B4DD3472C5B89FC65DDA54650392A02CC6761336FD114D848BD889DA4BFE6D32931793A6515510CD802E3D9F2C6F8F2F9DD96ED039462C587395C7E6861FF48B7980D492C23E0635464C7D1969C12A43BF0FFA3089E6B367AA65D4678A571A0D47A75056B34E3F8819F8B6ECBDD6BE580D423D902D3C22D9D787E0F1B6202DFD392AE028292795FCA0177CBCB09AFF8B579A87A854432827CF797E494ADF9F96A56777AD6215F284EA91D35563F25355D12BD155C6C364B0C8423E1BBC809E736CE0BF03E0C0B728F04E6BC8F3F07A0D952AC9D9530C77547B687E193EE2D3565AC755DDFFE880AB0524624E17E019466B7D0E8FD6E94AC2BEBEFC617BCC5D529C83A90D36D57A93BAA0C2ADCF360377C9E9D58C456FE9F3D49CA37A8C3B5BC7C231842B57D320310943FFC0ED2F5F622988ACC7842F8410BEF0E0671673E7BA61AFCD2EA83CF066A169BBD97098F4B4F3C9FE73F5CD779F502C584849D1AAB52D7059D1D4432C27FC9284FBBEE43D07493A38B139152ACB71A171D454FCF936656ABDBDA03DEF3C7B27891088F940C200AD454308001FEB2DFA0FC38FA74F85A30DF4FFA64DB48E7D40C158F058B58174F18BA482AC445A6A63FB54CC6C7D4C8089794E8AB5B38C41C7FF4C6A8A5F294EDC3FFCE3C01F2C5C7FB569CA06567C8D3BD34F82046DB4EE7F7491D890DA1FDDC55B12D90A7853D8FB52E86AA1FBC669C7ED349A2CEEA9EF18F76C23E817AF58101BC5CCB0346A607D6C60BE5CCDE5DB9889E040223FE98B17D31D64E8C1456C01353887D75EE3B82D66CA0679B1C2366C44E52D73B09D48A39D1BA3FC87D73772DA601EF442208DB763F0BF888D28338709FCB008B83671442CD9F7ECAB2C1E26428391E559306904FDE5BA21E1757D94F84F18A5FD8A067C556834AB257B9D2E1290FE0ABD3BD622A2AD92BEB2C6BC61852D58384A20B7409E4F212F630BB280A46CF89DD702B2508752D6A4DA94BB769797B6E7FC318B0B3ED50D7F8C5D8579526D536E4D43F93C055479D53BF6159BCEAD8CE87504EDF7DB35E1D03EC7B4F13802AAE0207A2414802BECEA39664110A54C37415EBD7BFD5D73E871587967F24EA34B7D06CAD805EEDB95F1023B7BC3A74A59A6C9F3A4737FA1BB087012E0162CFF15A539E86AFEE30144F320FBAF088C6884489F84F16458755561C9CB0723CEB6ECB134083C3B82E93BBB57FCE8D51374D38746BECD09A059AD6623EDE82EBCACE009C0C27D5FFFCAF76C9E91BDF5EB895FA1E9C3C0AEC0BD73B1582C067A45CA5D15E2D45E7316CD4B176D9DC7241B05922A682DF919B2D2DE2F45942D3AE254FA55C5D90B8DA3C7DFE2DD8381AEDCC9558566E8DF302022FEFE51F23AF6A018AAEF3C93FD608B0903376E193CB1C13021808ACD538D3426F9B3399686B6FF4DFC0A4552DEFE49D042BA76136719D62884D8B93A349C22E0320B823740DDB3794AD53312DA5608DABACF69767D76327BEA7A644A304A132F2D2FA8E7C8F4AFAC30E389A995C0A2F912E98447CB400FEAE35B3BE089F46CD48EC8E38D4F2BB44F1734C67D5125D7266AEE3E9D1E91F800ACF8038D43B6E10750DADF6CF70DE75176A2E9C340BCD2F6D87F976AFBCDAF5E35DA9B268D3AE1F0F8172A342CAF9602593A5ACDE03DDB482E80B825A7E91E8B0EFC1C8D00309BD170D9F12BF5017780A54F440A58BE4A5257AB67190C62DAF9332F3594303B419D44A38C3A8032E38599B49872D241AA44905CC851DDD0750D04815ED88711353DC2264C0302DAAF2FFD34E9716FDF8A81F7CCB5757913B380A68F153F62E0BA8335F8525CC3A20145C2416581612B9C29C0B1B941946B2624731FA50420716162C64AACFBF94B43B10E59E0AF3836A05B9335B0C44370CDD2E45BA817631FAFA2E0ADC801772F6F71860CC2623E1A802B370823D02442108E5C142B68CCC9CDD0BC2EB9B861D763C715D516540F19E70FB474E120F06BC19A6629E8DAF67556AC60D17C252A44901839143BE5EC76B834FF11DE13762EB23843D3FCF1FF9CEB41CB02DAC74ED6219288575FA294157E532BD877D1B711AF3B98CB0B4BD7286F88C6C00B6AD9E40D66F38525156A4AF35F2FD42A5F25A201C66DA4AB5C4D1517BD6CC9FD9764AE2756379D73C8D81CD044174860FEE5DC42B4576008F13A3504674E0D224A9F1AA780C3003B7856692676A5E581418C65BA9F049CA20C3EFA566315DA220E837639A899ED54A07B5741097C47FB90A81A41700BB5C0D8C3317E27A0A6CFA77292BE9186396BCDE5C654C565754DAD120719E571A4A14207CFD205BB4A66C02CB68EB9E50DA7B1FFC324AD07D8A8A54729621776FC5DF15CA39F3DEB6B810A735CAE0E1A84C6842E80D1CF95FDF5A6FDCD613C54DA1CCAB4994EBB81C632D192CA9AFD7FA662A865C6F193B7029A9B6F21041E3D13D50E5A1DA47D3D3C4B101488D2308954C801DBAE5029E866E869167BE7DCE6476A64FB245247A84E46B5F0D9FA9F7BB10756FDEA659788C032AC654CBB83F23BEA1F285DE190BBB5EC4135E8FA1B134DB5D1FFDA08C06682C2DCC51E0D848F8CAEEAF51DED21830730F6BACC2A4BACF7BA62D14B009116EF2D157F64A7ECBC971D50349712DDB0871D007B2FBF83A832416CFABA2B9CECD37207EB9DB8A017AC266A5FC28DFE64B52D0CD7FD7498F718B32804CF98D2F17D22C2957782DD83F4FDEFC8A6AC5B6A562C939D2D0A0FA6078F7E6B4C95159BEF010C1DF8448158BA29E1FD1AA076972E64A9D534B1F27930BADA08EB87BDE6FB0A691D4379DF0001D84F2F833050E18869F2FA7C00A6481E4F87C75483310949653D6B91FEF1116F25E5EB0A10C8C8723E9C1C80F75C2875FB0C448B3E25E7B359304C08C310148683E1D8391C432A8413057A7AF45289B1363EB203779550FE1F074D3B4CDB77B90700E3710D6EB4BD1FCC209F2406CAA67B98E44AC91B876762D597D0F03A404394AE81BEF8F54A1A898B2F0F0CC3D3B6D84D759D1F1C5788BFDC7657794E384ECB2D5307CD92F3E135F35720A44743D93D111F38791B60E7A64F51ECD6801DE0ABC356409D00D7F785EEB88FF3FDC801C94CD7972EE402217DF018958A79DFEE835B2E7C591D2604B83E2C8B3CEED7BED4DC66B66EA13BDA4FBF5DC3158035A279F57ECBBCACEE3FF346386ABE41D0DBB32E15B02C49D3F216DB19474D295AE0A8DADD1DBA9AECFA9C92F0429352B558F69AFC7070DE8D47032956A9978AC2F388DBBD63AAD776BFAE969EB990E72B7D74A0D2002CD3CC664E77E52"""), TestUtils.hexDecode(""" -E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") +98b2f93395be5e131e0c5fb8a0792062513dd8be0e820804d26f937064f5c0bb3525d053e16da6567186dda337dff3c6f30c8cf96891ddbe0e15b349c03c6d53ea00c6ad4f6bebecf17b32a6b57c9ec32ab4397ec8062d9e8cec7e747a8d9fac7fdb897c43003780ad783874c2fcfec8a0d86ec519c07531a8f0008fd88395e44adff523568e526d190c65ba17b2bd7a383bb3f5df73cc2b646b40c49d2b87486a368d43e6d616e45ed0d9b3e772c7261faa5e5e68ceff3b6abf9ab7677949facd2690d6c88f8ffa3e05544603fed81516a829bd3d9bc55e53f85f31e98b01086c31995834d4fa0eb82ed75d3d510e4210ea4dd3cb8f2a8b446ea8283fb5cae01f7e733d3c60356bfb1411f8be5a6d0b6c20558f77e7c101e99419f94711a98b121fb7f953e0c19f91b3897baa245a62c7f3336fddd02358fc3d2672e9147dd3c7ea8cc3b1813ef8045fa37786c83f387731bc9e3e706468fc99a88917499d8603589e5d8b6d028d2dc2ffa4f03d6359bff057763ba7c106b4ff4dda55d9f1b71ded84896d844e44c9f3b1d174f368f220d7fb6dbe0d844f5b10c29d26ec169dbe54967e00f70fef69096bc8354a8bef7fe0be76e5f95758580c93ac8d9a349ceb388df4cc173f4bc2d1fe054ee7c649d238a656194bf77d5afac4a6115ec54278d17e93f73f9a4658a8f9f9820a31222f327613a2b66ab471132565f9dfe0388e622f784c7e09c0218603a17f83f246fb36a40f3b1d4e2a1bd2a49f388d3c4a7a06de761825b8ba7c580ac8c5ec6f44d371b43af52a62c31968155140e3903d0cbbd19397f80192e356e94523f7d4ecd4b2c55f7b88892fe94c0589a01807eaa594ff962ebad271a1f1998c517dcc3b98c5fc4d73b6efe16c4c45fbfbd18f5eb489ed9e1212bd07bce3e486c1264a595496401be6a914b2238d5f39f5b17a60886228e5e9b2d841cba626b26640edc619a444cfd036c54dc610a2102de9dfee18e18cf32a74245501cca7e49d987ef34f7a9adcdd3567e357244c012a7170b0d375be8a445e5b8752301d7ea633485974c30232fce5e6e9ea1be14f466d3a8241943872a1a881cd4ef436f1ead2ad9227143be6792406bd7c07d925091b51e5395cfbd30b8208eb6103a45fea3dcdd7ec9f478d303132705f3126942d19626d5009ed347db6e75e6a5f4f5651f72265f14a01fd48dbce38b2ebf162d25c4c3b0665a5bb30da9321f2cf070e16fe7b12f7ad39ea6b92755c4ff0d988ac561d310f6e492694ddd4c35c48c13d62848205ff97a58a12602c5575a1f755eb14e50f409b90924030ee3b58964f58dd8c600fb999bbd5daee8addbc185c52d7151bad1aef8d83a3a6d80137cea0f9b731249fcfa996b421b046b7cdebccd240b871a8dbd5bc072e69968f482538fb67b40d13f8bbd2341428d5a5d6bf50c19f89d54d239a0adea5bd89c12e548b69a19ccf9f9402316363aa7959fe3ab63f350f3fca1350b892ca634bda0b6656a44ef5995acee1f355fae403b7e05900cc4d6688bce46227c941400870a3e13bdf468646c828a39a072cbdb495c773fecddde1f37b1643802f565ecacfa1ccccc2a2829a68d9594af2cd44503ddfe823c8117f0cfde7c77397d7da69b37bb765e2e7dba9ab70e3b802a009f511bf762820a8c491c6c19ec72965508a82d199b34f17867be0669b4c792434e6e4e4c1efa395f1c4bd83a1414a51d71688544d57c2d5167a1929856076f7310c768a1919392171a57821109ac3e9b1bf7cef03088d98bd2dad5b0290072d7e5db27ae08e4bffe11d359dd5b58468e8d86d787c9adc8717986408b2d67c9e0e53cfebae82cb27f0919c62e89a68ac8903e80a7a11b7bd56ae232081af3146927271d3c2f2f7247a3def6de720917b014d6f03eb6ef9dceb771cabbc645f2cac7acc3f8d6dd40f6fd2bbe69ffcc5a083eb3a10993bbf6edb5872e001ef31e2a0e86ad58f6829c0f1f560fa7ef734de2e84857e3ef86cbbd0c1ef2fbcf282116297b5de572d10968edffa402de0ef9c4273f793598d94aef6e294d4ace8cccf70acd9f86ae774d15e9a1714ac761af94b446e4f0cde48748cc5db05ab4fd3bac0a1c43bb8f73a7ef7285866ff80fb41dc837a0f9d3ecf93ed0b79bcf6e94177d34084c597abd2fc46fdb4acd11d543f8c0b512efbf63ada213b2d955569da12b88b2d6605fc99c76ebef188881c7dd195e6ba6d5e55f1ca19202ac94c360d76d0359c3cb1f801414d97535313ab2ced2db1ecbbc3cb68e81988bff134138cc393b8ace18e20ee4e0f04c2206df124e4cc496c2acc185489cca0aa1f9848382a55d991fe5b1228f913ff81b7c564bc779ab311e9dcae58e7009eaa806896b1f7cb6718cbc8f8b6c4a65738a87e2338c6ffee4cdcc5ac060e0021a5836c45732cd668d2760de9597f719d26bdfd2403f795b8e7d52e657ae968d027b0da9e5e76d2fba34f1de7425b780bfe96c05f817dd8f0cfe176870201da00deb460d12a84f8bbc43c713793530062dc78e92dbde7a9f53e08259333253a42f5f7b1a7f35fb89e69efb700f7c6c465e80cf47efb8b396ae3455af4fa48b45a1fa87a110975cce3e92bc2394a456eab040c2fd333f70d8165e2b6431677fa28edc67dcae5f0aac65f879ca9c690648689c94d6f657065aaeed5dfae5658f4922439437c65a2ae5bb0853478178b890561a69a24bd0419e2a089ceb0196b232c45c7373938c51591ba527df1f21490883e62e99b0c4b914bc5e7be903824fc12da0654bb03d3c15261691db25a6f6fd53e3d4e9d8ece3d331f42d2c99e9f1fd9af4d68a361922b897ea6ab23d8c896208bcfa6f2c3b06ce3c88fb86994befac763586c2f0c37f55edba60286a764e4cccc5ff915739c510a5d45ead80d14465af87377ea019da46245597bb6af0918654596365f20c63c074c8a896e5b6efa0d2ba7318fb5a42c6eb52806ab9c6dd8f3b160900cd4d71be8262217b9877739e8344ec1a90511a23f38c5b5c2f23552743b953168de2bbb3a993691d0d87aa20cc70eda60839a20eb3ddcbd6abad31d3ea359938e76191507f298dcd7110e0ce6216bf9ffe2f361c8246a9299a1fed48aff683ec8475fabf36126ab166601981dab806616f38bb1bb93c335fbfa3b250e31560bc8d0dc53957da03da2f80cdf04764f2e9fa8e7d2f7a89724c74471d2bf713d4a4adfcb4cb178a492e64c1711761f9eb9d0e65e04b64f9b94f918f4ba6835f68aa523d147414531b925d3d9e7d315e1fdc533ee0c498e9f66bf813a25ff95873de22448924b36e6172a87d7adfffb9abc2bf2272c270b83cddece1cf189ff52e209dfb78b8a952142cb72c969c4ad7cff67b1ee5e5bb40caf0dd45cd37673908c430d0d776dc2519dc4984170ee7ca6365936369df16c4a094b86c1b3ed3d3cce82b2e56a5681c204e0acdd4a712b5cff260f4c27ea6c32e23c227dd8e1f8e99a67df32e7a24e0aed3dc9630b4b3331cfd625072c0024e96e79c4cf2ee92ea18a5e9182028d39b937029a4700d93deacdd4933cc31e93cb234214d334e1dfb5c323c964d90387ea4bccccd0e4386e4d770ea889aa480f0c8f828cd2185c18a49ce112c70d140e18d9aa6ca9ca2bfdc12003a63f67eb31f0699586ea8fb50d44fe9da2d01f0be10d6da99783821c07e892aa6fc6b190d9639d9249492c154b12e45e2009adcfa97b86650649599a9ebe07bbf8dc8d452071bc4f0e8203f81671e3bbe599c76589764c0c1923b141df67e260f7ff14752d7a84154dedad28c0bef90c9aaebf5d2b248e2e20a4ae9373e692bbbbd20c408f0ce99cd7435a4610fc51f051b1d17509a34d4804529a877828c0c263b19f84cc0b8d24b9910f6ad8006bb84e1a4c8eeba6e165efd50e5a444bc342bb8ebfea30385fc0c69f53d04286ca24c0a0a402668503bc94237daa53d1b41242a13050232772ac1b2c6ce9f6bcbb53ef6b94ff5d0c8294bd5a4b077c5ad5144b44a63ec630d84fa559ea329d0dc27dc7b8ba68a96777250244066cf1b8971261826d29f18bb34fc37a6a39e4870878eac95503dc5799dc8923a15a7c063f2e4f362294c1bde18d3289e67cc883f56ae5f56fe9ccc1e5101d67a552be55e06d54df6e97b49b33ca50ff15dfa8b7436e5ea540aea188dff17c3c657544d600fa5a3e7b783adc2065f05ddd72e65a69c7619a0bdd93c731afa3336d3e408e9bf09650b66026a6d691447db90e08800d2aa08fe312b5ed3ca2dee411bd17d7239f143259d697216e2f74d7980dc8ba3ef2ca2c95af10f36d9b28b1bb464155ffb6807e15facbad8b3ab23403bb9ae6546b183fbab7d4fe2fc507931fcfabbf868c6e21d23b0e02952db97e610b8857d84c777863f820978e29efc1d9c5ced05bb8e75b1246aaf401ff1d0d777ca6eb8d74c25821fd9a5dde41eb13d766c30345965553af361395076029184d32187e82dd7aeb73cc648893801441476a6b7a2914ab77063878d53a539f7774abd4fc9d19d5af3b143dddad76ba439466d646752b7ddadc708ac9a0751d9eb72559ab30043f41bd91fee7947106bc185f0406a7adcc2327517988aed2eb5bdde90e2779b5e3f6042757749da9c811162a93999f000000000000000000000000000000000000000000040c0f151c22""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +ab36c995c472d4212dacc8ea95f1ee25ec693ed8457bc6a62ed291a979b6a6e100ce9fd5dd70be6f21f54ef6648cb4882ed6eb92916a7ed3a4230ea9e92f8a3d03d7587ee6bedf6721f6d053cdbb9a487e2fe5604e0dfd0cbbe7679ddb1a4a27eed08d07da3e3e0c99fd7b3a50830effbf4502422264648ebdfd319664aa8c044f0a66e1ccce5a4b16cb7b180040b981191c751e684df289ed95f0974f82601aaf29dcc4d76ab93a3db4db5b4776cbff98fad420253968639c02b63da7f4659e9174c6abaf1c8e83f6b266a6df25bf52e3acfec600361ab92fee2590327e8879477e85d6f58349eab0ba292792ce6769affb157c05e79df66a498c4d312c55c292b7d6cf25d5030eab40eef294c36dbede934d32ca45a6a9fccc5cab367521c60fd1d79a7513812c9fc9698480a7d7a2add5afe1e24fbd2256b760c91f0cff0db3817ae4952ea7df13528987bfb441777a85d9e36df043a3182a07c410f4b6bc23b28bb860c6f0ea769db2848fd7b21459e08f10141b4fa63e52d92ded8fb54983bbcf1d854b87f4bf025fb5a0a09df89bd3f725da9bfdd413d1dc131d1ea5d54f899301c2c68afbff488a54122eae136cc38ac30b105273a8a1f89e115ca8a57b52e8b9fb1f85e4d126aa968d3125918355716a8ebab72e51e79678251f64f5d3daa326dbe96bf5bbc2f3f78659da5317773e379aa31457f446d84319da92caaef07d82d4c2a5cb2c6a03f1865be0fc1808862b46d30ee13c855237651844fc45a13162aecd01c56231e01507deedd06d432ef7ecfbe123cec60359df65bd276040eac6d7a4375a38bb62abb4e5121670d94f74b31f798459bd195006f8ed8b9319b572e74dc82842dbd403c0a8a63f7f7a2b2f48f71d13f96f37b0dbac0829ae5b6380d64cd468278642120442a59784ddccf85464e783f3d99a2dd613fc301521c0cd9d38488debaf36e47c93df341a50e4f1a68a2e615f91969f196e3f969f36119397fe59eb9332c2097d8e7501dfca1d1ea7499ea5f602cbbabf826a8b16cdae05a700f50212d62d781fd393fa238c83294b7ce60e0059523d6337b473bfdb80f9fb655533d3743984ffe028676519cb5d2a4a1a38f139a0c6c896ed9ca988e82c16c5088e8d15c2243bebff9c20ff059cbc91e93b29345f783658071f4be8277ac27c6a9d394749ac3edc77c9f3a93964e3463f075cd0b91dd6b5045fd6767447104e78cac5c0675533ca1deac92359d1fe0334902fa6f6619a52df272dd458552f1cc6f27c7c0274f49a2a80416b3a99d5666516cfc630f9c28280b3b522a93ba98ff91f08e8c1988e4aa32b965c59d8c8a6466912d351648065169ab873678ed25157a8dde08c1a2181e84d1aaf4f98bd5f3f7ed46f68ede8410c543e5a814305fc0cdbf82e416392600d29dbe2cded9938c086befd7d0adcbad5da5b4004b962109928ca5728fcc4ffb28e4fb337329217e31e61b99391a37340b990e4fff46303576899a383d663aa17cb212f98ee01276c071e84e6448d93513bd1ae775d448496f48508752732df8589e5dd030e1eb521ab986c4a3dd0f58269c3a74acc144396a6a83b9700d58c760d8b1af6325cd3f11136e45902283146c031589cde05c53568e14eb06e9cbe3e1c2ca20ba15226e6eda3ad9d274d86bfc8d3deebd0fb6b30da0aad3142d45ce40d8c531b928a5f7eda470f2ef443f790c649645264b35f1f1af690cc80b591d02281ca979f87a1e09c1b2ac16100178be5dcaba6ea4cc4a45dcc77f4d4f6f7be8fecba275047fb572c5ca4cadc7e3016959a16cdbd241b4adde01100ea0e3c7994b90a16e590f2aeb9de243be0614520d41a70fbce0ffd3c85a18be640cbdfcb1379318791f1cb50bf51175592c88edd4816833083f2b7b5554d59a23e4cbe712d2d49cc1a9f2208756f050f8120cead2cd8fac0e1f65ec5ad6ec0e06494217acff5219860233a65dbd3e2b1e20916137c0cf4518090ee4897b5fc90921279ec30cea06d116ccd8159403f3d2197ddd95c7e21a9ed25404a658c64437d98d9525cbbb223d91578257f0e63ba8f78c217f985390206e01acd31dda5cb260367cb68233b85e4bb72d82932538f50efcaa67f97284833f04058576656e770840ccb72f2157be55a6107b8ca27b12a6cabaf45e70ed6bdf077022bed277e1259e12255504777b0cd961a9d0cec2b985977893c43b6c22e4bacc99180eafbf1e59fc1532aba2ff9bb0418c80fc9d33ebb18531049ce73541fd96bc1c92d94da2e7105e2e2471eeecf32b1c51c1e00a9d3701b73b57b9e406d700ee4ed9738e0067ee58f2ed871252599e01315a168d452f496e8efb0ea455537806780f83d976e7e9b839590568f1f799f4c1282f00cbb571d934de2a610df4ccab317648ac384d32a5959ecad1f65f31932152a8a66aaf7acc9dd597db79c85a76f38ace97807fc0c8c759d1e58b9d4a061f62cb8826417ec7c7dd06608568bfa5d8333ba6ced03e9f06044218f19222ef5f79823b5e015f965ee9a17d25c09095cbcdbf08344f4d0129c44fcd509c8a76355aaa09cd726fd085f74b321069e53d151662fffa8bca2274fd35d84694fbaead2430652a60129f9173dd7877f01e21c50965895ece33bf904523e10765174a69986669ebf95d1515c605f1e38c34f83ee28aac1e362cc052ac558e1d5c9c24f20e447b12d25c81f75c4cb2f55a6f1522c21ab8bfe5c18f76b460ab41d202c47a9cc02b05c7ffb07"""), TestUtils.hexDecode(""" -C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), +F55B1A381D9258CAC6DD7B5A57899867FB659A56873F31F815716075DBDD56D6D0D1480AE1242A17485AD259BDA2533CBECE28A906271A3E65FB5D48AAA124993738FDAAC65736230FA07EA27D96F372B90A16FF778D0ECD7C0F62174839B8C7FC50F0B0150D47D5CE9F3715F5964DC712A681626821EA27E912B80D2D04C346B67439CB5E06193B6D7F2161B4F8E0341D8F1C0C7F6E3B351C4EB62E48B555EF00EC0DD5CA6A572FB201D1A4570676A04000C382F4C332C34A0436B535CB3C3F2378682A982034E01211CFB23285395204ECF985F478686817A5F6FF4B694082B3032990597A8C3A85B7FB5C2C49694103811F754DF0434D09C1A5245BBA980D6EFCFC9BC63DD42362477537C6712ABDC952BAE377AE7EAF9FF0CE2E9EEE82FBEFC1CE56063293BE659624CCA0E23DD7EF4412DDB587CF3C5302CE5AFB39BA8613151A04491901DC30706B46EBD1B26D4ACA67587595100AC51770080FC32ED0DC109D525088A2579D8873C6929554C30BDD1E2A0A9797B1676A8CEB719F64A336FDDC3F95BD4A68F472F00C4778745203E1A7736764CEB94F33109AF197C98D94BA3F07E857A5B251858ED850E7E578057E833A2CF95D7505C4973B709CEE834A40F32CF07AD1861CD46CC4DAD37DE66F8037DF1B14CD88E62F81B9DEC286BE4968ABCDCE54F83C5E9E4FFA8144A5877D75FDF75A38ECF60DC180E9B72F256BCEEE087F5AFA5C6D779117070ADB4A671839E8032E55AC52E806C82AC16FCE76A659D6CBABBEC066782C4C068AD4FCD5EC425885A5CBC5A4BAB43D1A60D499C497A2DC06B136A971BE8ECEF3FA6606252029FE5B33661883608702542F7EF44720466D91FA1CFEEB9D8CEBBE4E252CBC096D99551BB90A0534D723B02146FEA94D1C1926221092B97F1A143E6B4D5A8438239B2E2842633A6D90A18DD67D05B2CB560BA8A964E0A49BC1987FF47895D664F92E27F8C90059C5C38B02B42D7A179A09B70023BF7D664A94F7289B29FEF89356BB51959FBB82562F6827CA2A3892E934A9F271282C204BC3C6B34C57882EEB552DEDC0644B43FB28284FDFC82A1148447F2457E94EC0437CB5E0E3B6AB7F7E48F0F53C80D7695801DBC0E96F9C00A4A96AF8D60676DC4A6A6D97CEA344D7E911BE7CC9CEBBB23C562BCEC6992AB1148384278D94913DC4BAC4F73313BF83CFA2591420B18429D1F88D68443B960F61A1AB8E2713794225DF2D4EF88CAACABF6F095DA88C52C011AB3A07D7B71CF209BC84DEDD7FF2D8FF02A0727196D50CFF6520602D9FCBE57F890D19EB7845C6529EE5CD98AA2FDFCF37FD7472D1491FC5267F1D7E6E91EE891D880D5EC20FFC761344BAB59A327F829ECFBF8E550208976BDCFB75BCD996599B68CB29B27D9EF68BC975DAE08AA121F4D95805EB89F2E8B2BFDC61058740881E9B403C54745CF6D4AA1747EBBA56473D00FCFC62B5F5DBA4209E0E7473A0A311619437D2DF22F1D5BABAE064970850CD51D4A62A51E9B3D3121B766632B18F8B7CDEF40B249812A6274D4C69C9EEC096044026022B1FF055A05B6BF1C919230723A952589F540E77D7D24A413F542E7E0D3F7F55B8B335CF3693603210E979718E8CBDF76CCED68396DEB561EE27E9008D7BDB428BB293E1A1BF2675D8A4568D3339682854BCF9E8820A084C94D78E5D0938D66676ACAAF7B411B466B6588E9E2B4A387D84F23963E252EF36A948F25625DCCE664281D76BB6EC1B8E20DB3A7140B194872DB439D89F18E74E1861E3CF9FD442F1CACF4FBFD16532BECBD97CC9A007978D17922A68CE98369240A8D1E8AAE6679CA5DB79D83EAC1A571D0871D5AA28F6EA4A8EB60770E8CC43A78E6BEBBD4FC63CAE26F297F1E21BCE999A509BDCDD20AC938E38702215C398726ABA5A7AB3F26DA34DB3CBD58A7882FED91C33803FAE62E9E69FAFBD698962F2C7226A641AA7B6CED1DA8A400992333EF5DAAC77B55F94D51F74226AC03F7ED8F3D567BEB678D98694E9E0D483815D080A70FCE76255C82FE020DDF32D4BB7B1AE0EC1679B3DAEF2C20FCD7D8F74F6FC684FB678F02DE6B53D03FB656A9B9562666F49797EC658C0E8ED14480A0532DB85478FC2AD1E21F8883F2EF3FD97DFD757D883C1507C44F812639711256EF56BF6F8FC4A73EC3AEA3099F6C2BE6B2380FF3AB7007129D4829103AFE70851917E02EC5F2117DE110FD8F4EA25FED6FBC24BA063B7ECF7585519132884FC12DE1BBEF498B92D6E2062F1A4F7C97FEE96BA87ABFAE76C50729AA68C8F374102B3CFBD69139491836E4587D0085F92FFE2A94B6A87AFE29C84D289293D9CB4A733F90389C96198E2250F5BDC83F123FCC4E42844DF74FCB65986CBAB77B692CA210AC22B5B56E30BEE2BDE84663B22507E00E0D066D5B1F5245EDFAC6D860D0493C218A541A1FCA4B48F1A916921153933383284BA268C3AB003CD58FA979A08BC48A57C755688B0859AF7F21061F9F1B7DA44088ECA4D393E8DFCCA52823FAB812AF36212CD137741C14F0860CBC7ACCE1FDA39431C32AFABB84989CEC971D4A257BDD70EC71192148824C17AF8F18816CA94C457E1023E01012A245F28FF6582C9015153DD7662E4321B465B33B1D5DCA9B1CE2FF49EA3A811B5852AF5C42FCE7FF42BCECD31C798C3B8F685AB50B68654192357CEE577F5CF1F85A50F269C28A1F2ABEA382AF5CD089C146B9473C8965A945091ECD1C02BDF64F9C3FFD035D8238AF974E7111BA4AB10288F105659C9E2847544FEC0B29B6692FB53CEA0DD312B24C1ED3CAA1BCFD94E529F6C27BDDBB7C764DC0161FCE578361E02E0F5F3FDB095B6CD311190466177A5FBA62BD18595DC49C29E8EC7E1F2F3FFCDF17D477F4AF8CA3EAC53B7018A026BC942EED87704108027753DF67BD36221E9121B49CD40E8EA7FA2D6961604BE0095099A4413DC11E93B4A876834776D144269BBBF8A9875648702B589ED4CCBAFDD726DE8E8A58AA5D1A6E142A470EC342BC3E2E1B49C7203F283E99E81E38F1D8D2CD820AC98D8244A705BFD9B67E771A0366C7C6958DCB6921A81C0C9D5152DA37CAA8CE18D6B97404B399052051D7343B3739610329A37B8BAAD173018708400AE02B8DB2A2414CD7DAF038F94714031B1D83A5A15DBA53585B606A13814F04FC925C3454E251CEECEABECD8CFBD6FC04F504508C04E25724807004612E2796987D34D04318F82F7E1FBA83A4DEE3C86FD1884B17E77231629F5D5D11CFDE976E639C60B436DD9D302C380E3654E671ED81D44FC595FA34EDF90710A6384BB62DE0D89B50C14A44215DD1121C602A79A003955D860C88470EFD320E8AFEEB114E547E50CE967572DF5A5C4DED09222FF7821F91598A0A9C41A731D64429AE7D9BCE1B4E90120BBF94EED78098C9EE30C38628297C86DF59930E72CA561A61B6EAE517DB39F5A61FBB8C1838E3ADAAB46187F0B5D09962A39955343631B74BBD17BB2E338E5FC8C43BF8B2DF3A78BED744A481A1D789721928962AF2B9E2187E6B52A19274EF68F329C83F42A28B49C447FE284A25B71FC95D9322E752E28C7B4B656A743CF6C56CEEB758E742CFBC4B8D8DE5465D63D3D5D6EE993A4C47AA72BF82126ED6C7423D3475AE098CE6A7E6DD6F3EFD654BFD5DC4414B8F23F9E29CB0D5DDFAA689BABC7B5A925AB19817226DCD242EE46B588D7CB8E88183CD87C6D06FA1A40915A3F19E2368CDD97A16ACC2DF4CBBC0B30C6289D7004A8B48EFE4186BC4D844EA01BA78E4D1F0CDD2648D0363CA73A19032A537F68E0AC01CE6701426A03E071A109D42EE5BF358445907E1D05761B8F41AC8A9CBE2657754A8C4D83A3516EA465D5AD57367BC58DC712A5C055F68D1CEAA494D9A845474F610BAAAA4CFC96EB51D41493930534D58533E20575B980F4379A80393DBF797969405D6A514AC0A9171B79D6EBC5B66ADED19821BFB090BF76FBF50CA6AE07CAAAFF584A7013A71D54A2B60678F6F02DA726E7448A2379C28BCE7DF968154CCD22F1CDDBF25D91C616234539731B8DF4F55E21F37B29BC77DB4BA802D9BE419ADC292105EAE58CC81A636D479B550D33D057B7AAAF28F743F7B8C17E26AB2A846AE08E804E5D4BAC09D11C736DB32F9DC9CEAD0442AB7B6AAA70633692959A36D6DAFACAF2D7027E5BF9562A93A1B35AEE5313C1E2015E65AB805850DCA7A65FFCAF14200E1EF0DD8F8F05A11126EB02C13FDE38F496E5EBFB09E9E2B4920E619A67517FA4749ACD8B0857C7EC5A6E94630CE3EA0841C64D2EB895A9EB7CE5E757F2FB80BB4F0FA429E779BBE314A491B2D45F9A79655396E70CCEB319C3B405C33BDC91EC2169C3A75C4F5CD7AE5AFD6CAF6C9F81A9223484E7A12512B600794351693E1111401F74E1439C99D77E8932E069193DF7562C79EEA22C41DEA4EAF9E93456378CDDD6C8AA97D8D69C222614E203B6A1FA6377A7A0CAEFE709C90CB91939BCFE926B35970B13A06FFECD44DD8A360AEB5D0432A532E8A3C275E1DC4A07D6A3E100B04AEDEF14A52C09AA90438D65C8E6141490BD1ABCAFDD5925ACB040A91A8E11D242521C1F00EDC14D62E1C6FCE721921DF42164B4B34203660DEF02677A6B8C564075865B030936F472CEFFB3446714AE18BA14A6E45247C9AE1F2836E2341B61940A63FCCFAAD809C84906FA0CB1863625E59B96CC2161A4715606DB12FE3E79C90B64CB9D3A93B451E1C746F6B820B4FB3B3521ADE56DF9D50136635F29EA908FFDB32C6582715B06487B391A36A6A7B96505FD8ECE767C38CA4D0F9599FDCC1BE27C9C60D9190139C4F02461A5C42310CBFD5CF506720C9A13067F83AA1FF66CDCDFDF59B673B6C1FB0301DB118F3F49D1BAB49069A9FBC2D653D390DAFC3CC5CB35F0E50EF4CA808DC69F0134E3EEE697597FE7E5C2A2CDC5ED4E81F344879A0536BE0076D7A351A199530C77C0AF25D5C7D5629641FC8A3567BCB1456C1AE1D216C1E408C3AD6CBC1629E14DD834819F94EE0D255AB1C61BC7C324445F67CB7BA0E5AC424EB9C3D5FABC47081752F98B0011AD389581B8C20333C2878367795E31F99FD2C082B04126A3A61273C94E894BA7ABD8C6FD743FB76CC4FFFBEA78A1CFBBD266DB4432ACEA74350AC06F2EC832BD71FB09481A045F7A17F22F9AB65CAE6782A2928147BCA3B521E001D4BACE5FF499B1462709525D64E72201D5620B5537DF7A3E8DBCCC6EB822129B7768469D18C891A60B948DE2C12F4E4DB574C6C8BC586A1B57E727853FBCDBB4EB148DB234D8759B2AC8ADA2FAD225B5420C2B93D7FEAF051B7B768E64BC6EB83688B5E7E59059E1079DC66C5D8696CE758B42AE75123CA0FB72438DB97D39F1340B2891A19A4084BAA1A5149FAA785F09300B9DADA3C45F19568226151382ADB16617D5E59FFE8029F0513A7156F67D9859A13C2BEA574BE10E319F1B69740CDB176A962810B8AA6C368805EFA56E4AF69E908A205DC41CFC3FE69E4A6BB7B1F541DFE0A0EC1B29E3C199EF07538BC8AD7B0BD31B6A4DBAF70B83443A9C6C06268F597A6D1BC50171ABF56D18BB277F83203BB671DE404FBC4DFC66EE8DD4D92FB1AB2ED20FE8E9327CB15CB90908F37171D10E759BB8D1BE2C895604F87E2307AF7720AF99F0552FB15229B0FE7B45A3005E6CB0DC88A6D15AC7C364189A84A6615A344FABF4D0DD82EAFD42892C86EFEE6E9F7C248462E4C6CCA369CED819AE94B3DC856A3412A0DB90353E6C6D9DFE31913C3249195A3EDF9F84BE94AC6EB82969AF272AB8802BA0E8967EC342834B8A38163C90431844DB073DEB60B388710FF880EFB8283648CDCD75615D35451D8AE4711C1D7DB1AA59675061004EF8164AF3B4095F0E2FFC5433BA41ED72AC2C683D3959C9D265C302E0FEE7258B7C870F62D40961AE5AC43D3BEF8241B38A574F75EC7CD608781EFC16B7B9D36C3844B6FBF477CAFBA155B91061"""), TestUtils.hexDecode(""" -051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") +5bd74b9ad4b08f18b54784c7c6952152a4f597cee14d967851ae2d781f249d926ebb4f4490487d1ab299a179928f69811f39a8a019bd808c500010aa684ac9954aaa005c9319d75d6049ecd99ad4a3dd535d881e8eaea118635cc5dea0ff3d4a7d8bd9d2bd00b78777f6528b94cf8de6ecba3829e8fdbaaafec7a16106457f0204192d88bcc76271fa31718e6ab4be525b04e547f9774fa47a8e4a88a4fd9b058412f92b27a2e191d32f015ee31cad4321c62ca55e572cbb7c2872615e5a2924d7945f1ef161e407f415b4f963d4cf6272d954923da0db3b04649906ef6e2da18592227b2b301a36298861e793b88e7fd1de2957d8a92c727b492cde702ef2b123e9968774604b71323cc4e7e58114c3ec7b59c94d9a17453795f426f706d98235c99ac4b4288d894e480efa3dfd19b14872fcfea1836ca639fc7242a55a0d01e1e21301f39dcc9aa94d2d83bfdefc26cad8614406c70bb96c149ea652f66f8d26ee0455c6cdc8e648fb20886334d512fd940fef6d0d52a14fd9c33e0be6077a10b4729a8f6200ff5a5669b3b533d366b81cb6fab41dbb9dde1581e4f3bddbbbd5f18cc00123c82e9f82412b5fc8970b69bf2e68fd5fdd17b7288949e1a7a6eab8986ba2e7e2f98b5bf2a561ddbd935802fb59a20262a77137c99274f4597d070c0c7ab5eb82aa445fcc882b1dd0a825a1f0a2c8181bb6c608a53704b9d587e555d756333bea70a5e73ccc5ec20260c8ba150a44232aba5ed55f49281b0e697527a59e4cb579d27183921dd55492cfc2abe640e1aff9147927ca2a1d1ac594c52502536d1942fea6b3e52793e2a410fd6ca7dbea45a5a696695100f53b9fe1f28bbc0014ea9fa3b134f2cf0c0a2b0a74525468bccc4677e3959d62f2cff8119e5895211316b448451fee29720a74d0e09bfec52913b0a26d1a60e404b2c2ccd036d73a2cd4dfef3d9a10549287d70bcb561a3d466c8933668f69d2e3f1a90951ae4def67d49fd09dc61342a15d1d576ab41b7f145d73a99faabd04b9afbf8491a28c5483674e9f95f3e4146ea0d9b1ca61359c604b0c821a9cce85e53b5e666cf1786100fa4c4f14dfc178b63581bf502b7909c68e4587892188934c0472412667e552bd32184a306148019d56236fe38b03799c2a8c748c0b969d9d6de27a0b842be7580ec8e186c76eadfdfe4222628448abca620a246214d2629b2be13cfa9e9fa3c26c24b03da758d5870c4f79f68c3be2bf16f97a7459795e1e30d0706f33c4f865348785abc4e6feaaeff79b1b45527357d31ccf575785390c35b2a4c87cca14fe7bbbe6ba82d96cb9bd6f47d9ad73ea3b061e030bc03a670bec41615f86360a01a37a3ccc307e31aa6c32fd558d362142fd5668e948441275f265697e4700d87853b4d1b8f50c1c9eb96d05b96992daf7e9d3dc5b78a62867ebd7b901fc37ff34b67af0ece5fe7050c94a43ca96af0463ddeaebee931bfa9e14226b2c7bd40cc99cb7b3791bd57fbab3d4961fbcfa4d9fac748d73b2de0c7eff554699cee1a72b197d6ad5343aa72d7d0bcfe6c3b458d24e7e75d00a90628100d635f032f24834a3dd0ca0f5fa0d040b98ac6e0ad4a3c09445d91d929ffcd5424800bbf06a747c7a05eb87cebe5d64a383cd77a7cf3dcc80300927443692c50c7aa0d12e1482f071ac1d9acd625f6e8c59068f1a08eb163a11685c7699493cb28b1fcef193aa1151ae7519474629485b7e6fadf01f369f05a1c37d157be7560b38a59643ac997b18a16dfd211e23c1c02f936c773b8b3440115beac0fee20269302ba0ca35d0838799ab67bfcb300e89909e2fa63d83b035d855bee14c47d847ec7f7ed15bf16130ab8fb33eff281407f376b3fa4f6894e1681e6eb025be02de783b22680e6ba9c4646b88d91e18a48f751fbe168096bbbd16a2f4b2a13085158d55c5283a069362f83c9247b0c65639aa21405f343a19dc877843bb72e39e6cda5b7ea3f198cf59c9607e1c5f09bf8962bba657f609f4e9d3ca99cc58f6283689c9ca4d0c4f659831abd54e1f154b26d4b7a103d9ca6b6112cf5bdf0e70103c8147fa7f5223665f75bd153d9e5aa982ac475413083d9baf3cc20584c792ace31ca3c3ce87cc16fde69df770f717bf9b0f10a097595ae2bbab69dce06d1973b01ff9922d8199735d6e16dbf4e7b94493b1106fc938ed093eca657e173b107cf995a251e5b6b7c97daf07bbc2ff89f5f52121522d175ae97cec1e98183f646defd2b15cfa13107cca9ddd0cd9912a23b139f84a2265e35b7053cfb7be23b79f28fddc9e3190b0355d0922543ebff420493a9ee7bc1c18d36e2e76437404301180bd3695d7d059601e204f46da1c5224966fe6c099f0ebf6a2f8c61ccfecf12f9dd4f1a197138e013654280a7c5bd26ab1743e40d8971c8b6e4908113b84537a410faa756251faff8fc8bf0fe8d325dbe0c1a6f7e099535e08bfe584b232a36401d9340ce323eae8e8eb4fb3fb57687037b7b98c6ac8fd7d919b71beb9273f4234028ac2f034685c81e630d57a83162aec955bff545d8d0a9c24d4a023988890301ffd37af5824f59384f596a4c242fa8378ba2b09908c74c8144ef1a6a4ef0b9a6738f8ec52e114b9aea248a8d2d3733f71649222c8737764fb440c9f2972390d3d4ad7467cf238f48a0a299c891210a60deeea020e4b8a56d2b5fa61aec1b341044fabd4abda13c6e85fd70170d18295538bc8da2908c103a799448441c50250455f5481f7a4f6eef5792f97cabeaa99936557b0ca845bea86234c1de788cf2abc1f32a80b13573dc2b21b110fdddefead44d94f01ec772078b1175b0297b0b6de6d6097e8aa3e5278944fc9e7a884d3267632917bf56bb53dc074ea14a8dd6e6c1a73d9959a5d2ae385f5dba4b8447eb451dc441832a69c1c0a3ed41b0997878c966510dd500d61666827435b7dd7ccbd125f157a419ac5b614ba6d65438b6c99e4d8e5e6776809edafe8fa6a76e11f5f400975df6e6769f2c2c1ffe3d40482be08581d5e79088fbff8da514abbbca7b3ccfdfaa1915c373361a971ab7f5c1c09e9499592dccd610f14ed84db0a2be1c94e5bcda339e14ffb27af1ba66c7130f45942c687ce96ed553ad7776dd532ccbb0faf1aa41b7765023d56c9068d56c3c405b8b2890c4fa6bd79466a4a146657d9248d8a348bdcf41e3388993e8ff2be2fc8b8dae8d15269fdcc040f7e72872539205992444a4d19552ddc5e51b778c5b5786f2d7b79036b73e738d7200aafe96850887c44c982b0347c7646dbcbeb4b6b55971004ade87ff20adef58d3aadb40d320d43585e7e55da08344dcd9fd8345a2c612f656ae178c914b5662d088c3437a6e5928d3410cf65dbe2ad31f1fc3781d6a5006ca8136233814be8d655b94152ac70df8cfc6f9e9101f5b53cd5fd37176341e1eaf25f2fb477d1d212333ea200a5e9da88b19db4163a44cd4c9d3ee1af413fc6ccde64a9cedf21c8b8f113d62a63df2233f9a195aa67803d632ca873fa11069b5998c1200dbbdb9647a98acfb4e3229185b8c220a6079c72bd4645b04f32ffc85214bffd8ef2cf27d8459eea21069c13bfe052ef92a070e63d05c9a9a82699676ea5cad84e508d7e811073e17bf943516fd4512d53c7b3fccedcab36921945a19d0ec3d9303bd479a446ea1a5d5e4adc5a97b92db843b54de9498592c4859011bd4df412a6151bcaaa703fcd97e702d96b0ab14d7fb0ee225f8097c174b517ea051f8f8b8af47a75a93fab99ebfa84f8ba8dcc9c9927e24f6c99b66f34f86c2fdc88755154f06d9b1ff731411f35377e14d2375480b688108212f75d74695008a61fcd452b6dd23c4d910c409d9edb69d294a5bb46fbda29d6b31b24613e751b3aa8605046cdb449ba86f27d226e91757a242ec2e9d241aedcabca88269dbda5fe8e5d8bf4a4cf1bb1585f1166d36a388a47241245d0001e35a790d6d201a92f34ea315933c67aa26b4b22ffa7d87482c7a63b7544ab511644b9e95152998af887bdbbdeb6f2218f8936d5fa50686216e30db9686ff1e924c850cfa31ac950bba1cc1124a892fa1c40f62a99eb452a344f65a1410f500ab650f9e91244ce5e962caa13832df55c4b41f53509d13d1765063380b942a5d4e718b9fbdfdf31259b879614b2bcd5c7a637c0868abec9be94a132be2c62111e5f22f420630ca64031ee7f43df2f8709e9b200f0f459d9f0b4bfc370f6faebb0345da46aa11c975670cd94ade1781d56a3ccf2c0729a8238e9cfdb1ee2e575c524661d089f894a1502bde21465f430561a72b835a39a70c60d64f371affb8ea30849956b767a5ad7648be643e0071cf9f08e880f6926ae2fe97b8fd9ba02dfc965b3ef7c102eb207555f6037c634496fe8de5cc8ae0184b6df1201e8ebbabfabc4dee1df3a15a46414e5627c7b99982acf3fcc7806d0e8b9e9356f21f15366d6327a3fe4d332eb8ebd410407b1b57220ed702dba8783c1d7088e66ff9bea1af5794c964cc95c415b26598d39f448a428c575de927e7eb129539a267c3e9d2c7b844e80b1c396810f8b703c2f6f141339bbbd34938cc12ed634425b7d80829a9cb7c8d1f3050f1351587a898c92bda2e1e366b5cbec034750b2b8c4dc00000000000000000000000000000000000000080c16191d24""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +48862a8bc5235f5337a82329e949240dade33fc7d17ace18be0227ec719ac4f71fad5a97f5d2cdf1c20dd6ef13760d4e0a1fc9535aaec433e7cf198e9b538d0a4a6482d60a005b195667769b820f677dd046b2b21af2c092abb4852bd66cad25888946d501cfc431187b25f773911ffb9e82785ab72df779f415cd506e52ef5b1828e20bb1ed742fc434ab38f3129dd3c50bfd1db5dccab13f2328740c5fd9f48da27f3f13df19e576fde636ab53f3c4ebb08681e288cf42b8bcdabeb3dc6c6c4e1a43e88e63d4e3797d7e8ad84835000206ba20f003fc90cd41e8b0230a1d80320d1a14d4a04788094aa376b2cfa10b72c66764fdc83223c39f8876407a05a5307f7748339547ef844012b48bc11799e72e67f993c601c6bf9bee389af261cbd8d07532a9d53888c543293e66e9149d8ea8862f69213c3421cfa0c2f121b5145cf9c4278b8dcf8facb6c5249837cf7c67b41c491a3345ba1dd03e6721b63ba12953055d5572dda5e34c0af2bccc6c4a0f98484108caa81d595ca4b23dd797dc814e4d724763cf782a531791873941f9873d7f6c0ba62080059cf0c3eeeaf7f04cb0d21ffb7608d279dedad1fade567e9f4725a98f041fdef9370cf1a1680feba08bb8205bb95cb9aaa16b7d2a818c3c3fcdd5bebc63099b4c4eafeca407e16678f3f15cad13c11275d786c033dd6fd280e263c83651e094bdcf87499323d179a383cdcf99fb8953228ca51382f81fe110c20265639636dbf562bd51d6398eca94e02daa1699a72c8d9ad005c4f4e21bcf4d1d4d935d25d02e0a672d419307cf720f65e11f0f1c45a0222c4583d94072381e8d5cafb06debbc117bb4fecdee6161e2a72589ed6da1b17f3f1d3ee85fba69993a9a7e389969de31ec514c1dcdb7ea4f2a5046ce463fa79ca665280cbff802b611ffe9ec0d63324626a83ad99535ac565ab42f17802d8e6f1f72edd03344d865270e374dac7e4701357ffdf256b185065521084319edcb56a55cdb91ba16c6ac647c8bdd9739de7ca426544ac9c0c59cba79897420531e1e1858f715cada8ae69d48d95cea603ef3569b98dcdf3497d784929aa0428a190908f796bba2e88b809c21385dad8bc18a05736efdfba2a81cadc11d06774c1a976d42b11367dda0a7daeaa1a271a54217a38acf3bedfa756eccfeef5ca121e4ed57eb006a103c471b5a104554e2f66d93f0c7343d78a6ec02dddccc2aee0d045cc9426fe6fac1e87ac8b2bbd6aaed7022d36719cb2d5324a1ae7d58ed779d3b33a4226b2156863a2fae4dc53725217751757a25e487be29a2507dc078aa0c45fd275ba4cb0874b74cc77eb516fab1bdc83cfca42c77c23dee74bae46afcee27d99f3035c67ec00bfc9d55f5317890bb744c15c5e2c871298a76413795d3af7bbcadfad9d1bb14a2aea340a08aa26c1c29f297bd31e40c5be7020fe29fe6f2dfdc86197389ac2b67d8b78ec6943b561dad1cec3324e7d7809ab3f6dca3e0c3568fec588e70f3ecec53112f6e7d3505eea1892a4fde381a2b672db39971d27a6400058a4b72bb7c51648ee3acd8fb1bf0b85f44fd20fa0e217ee9b9b92dca1e3b68e50d8d7415d08eb4d711c1dd7cdb3f43c87d60e8af1f2a6722fbb50c9d242674937573d0d9fee8a3f16aa781a1bf5df9cf8541a00ad026c2a0be05b3113576b6b84365f2cfcb110760ce7ff47d2e152436c8cf245c8a54da42062e072f9f90a83c73be236fa45d26129ec0791bd91fb5c389abf9315e27a0535b26e761e4441bcfc2b3b9a5dc0509affc072886852afdbd0869e18ca80960e8eb3cb77b2bd635a59ab0990a2c32e905288928f8063084c3ec9b53d31231cfbfe06bf15c6500d10ee110817f42253ee753c57cf5871929d9b512ee557cb4f9b8fda70fc43d1aaa7584842c6729cba6253c70faaf15f322434f39eacc0fe52079aabc00693b49d73223ea9341fecbbf5fd70b09bb2b5fc4e7c638f63d4eb4113447f8afa3766e3d39b0c507413c488dcdb53e5ee20118446684daa4e3f74e4b2297077f301151b06879e6ca608af5759c7b1297af86543755290c341442c61fef8c4b04a8579c9f321f4b8bc744c1f9d8ce90534a5bf92d780a222b1d452193cc6c25ecb816a3f4edd4a3a961ace14577dc824baadb5bbd363b3a426d8161c463538c5a6b15a9108024f4bf64e32e1cfe96e44063b27917501c87f10a7524694473554dbbba8f29a572846e54a16e6fd895a15b106ede3aa5ceae9755bad27a09b0fe67c41e8ce9006ffae11abd1b9b3e359b65f4b6181fc8d8c512fc22662ce71890335d9811180e329553dfa037a8fb0053e669d5d870b0d2a5100c4bb78fd297520bbad94d67471741bcf2e1c2ca4f6304e35663399f67840cdeeb9edb621c8ba854de5c52f306cc3d42e1c081e1debc8021f972549b8a9cfa033c7901da060e17f982f6cd2f195c87614d8bb787cd1b10ed6d31c5d4d561c1bbabaed7ff626a312470fae5ef2e51a05972b905b9c5bc284d7053d0585f1a91bd403769e8cf9bde215229259c43e02323155b13b5fb0d542aa625c0d6628579929f7040644e91ce4fcd47a895bf3dde0d0097bb42647807d7008caca01304f403ca8f49cf5c11d276d115d000fb2f220718649fb73dd06ae38fead76e80c20932444cba2a4aeccedccb7a29d57214d72780e38921a0d50879a014f52ca2604df524bc5fd650fef98cfaa1eba14d7380ca1f6c303c0aeae7cb9cf0cc2e3acedd6f151d"""), TestUtils.hexDecode(""" -62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), +DA2755DCE32D07B6D2C2DAD6BBF7CF5D4C26FF0C9B6FB9E064B51829A1ED51A712E26DF8047B487FF0755CBBA8FFB60DAC3C45E238608F48205A582BADF82C2E7E83D672057B9A9209386D2AB8D93BBDE0C522CD1BCF2AE95573749E0D51B85EA01494E3BD97D3CE0A61B26249E4BB94F9667D6556CC4313669409D94AA4F3BB9AB70F736D34245E2A789A5FE2917D5F4CBE43010C5215AF880118E1F5FD47A4C195F3C74307523C688AB76B7CCB157F75FFD79149B5508E7E527ABF718CE8E2E4162BF810F35E234F8CB65DE0930202C1896DDDE02BBBEC8D03BAA12AA1C91EE798FF7ECED608E3DDB7BD04A1DD9139F4A5613AABCF7AE495F9CE18D73BDA0C91583B72CCF6A722C319AD5B1051E65C1B91DD05AE5A77220BCC7576F9CBFC8A12CD55883AADCAD1AA109522F286B00B70C8E3D4C6EDDAE7E1752097C85233583BA0E1C05C5624FF65A3F3894158982B633EC92C24382AF48EB2DF5EAD30759E99D67B8BB1144939F4080DF0E1689AC0D4CDC73DF1CC2FB72B92D5A69019087294D5F2DB196CF82B7BBAF953F0568663596F78B5A309738BB294F7AA3FC5F3ED5BFD4768CCF3304C836B476458E14B233C156C8407636FDB3EBECF49B97C96C31F51353B79C378C6F47F1913E5B14A82DEB126D688133F9139C12C45BA24CC9C7E2C16A26329D463ECF59746F5A99C6B03896E851815EF36F499654E2764BB8BC60EBC821C4D0B4C363EEB7849332A9F1053A975B092AA3AAE33F06F760BA1D76DE07A1F48ADBEADFF1E17C34F9D69E409DC5AC83C296C402E042FDBFB0B6B4E023B15B318337B6A1CE69F1CD3D93FDD0FEB7AE259A41383939253C317DB949E3BEB9C8F7A79D083BFB46C50AC00D382C846B78FAAA7399ECB902CE8B73A1E89374B1DA65B0723C67B24899342DF13C07A0BFE3565CBEA5892F8979E404BA84847AF30BFC04D8EC77B1C5B9400CB97622E6D3360836639670BDDF4E9CF9FE3D6B98A5FDA42422DAD6C829B9E33F53686E2663D232162D3A78A7202EEFBFA4917BB8E89375279C96C9054C2570DC3D90DCCF0E418B69E6443C1B2540BAEBE022ED9A9620C030377C67FF4C186A59459DE7DB1ADFE2923C01D9B8D3AC940486052DB67EB67A257BE7AEE0D3C77BBFFD0FC7C94540F11DD96C5100463C27D65D3BB6B7D867590D573D1C1BEDCC0E8D122FE4FB82F1404CCD061DD7C3D15287F39CBCD2448DEFE1FB4ABA858DCE13F74414E1A8C41B730A1DFB45B859545811C2A9DA01C342A1F3C8B916F60B5E4802BE672C2BE31531DD9E7014E681A8AB1240B5E3D5C0D26E7040D4CE05F9017A32E1C760F466A8D7A68FAAD421B2E2D886BF0007858129DA2F6B92C4CACBC1786291D7C95A3F6A12483B750FAAF1DA03059F89C761641C0AAB21A05E78E1131B8F45C60BB5E8681086717B918BD4FBCFCA1BB5DDD740BE289D8DB1C24FE083B3DCF0E496B1941ECB7D51182F9CB9986CF3F04F0CA4E01C63EC879FD4A3D5619EA1085B1431FFC019286ACDF3B4AAB03D6265A7B18F24CC2815269681BD37263B44DCCA5CF6FAC2ABB1DE317118219A73095D1BDA10B66B6B55421F049B71E759DBE6154F1DB98A7E3FC877FA90217A242B21F39490F2116A2BE8067168F26439C8D1928255B5A50CE1ACCC222087536BC37806FFABA03B7E787B04C2C67C1B0BEAA871F39D3DAC2221AF44CC7089E520BADCFD840E5EE24AC53FCFF1E7D6AC26694CBC15B80E48B10C054E8DEB00AE387CEC9972A28448A6BE3A01D5EEA837703D2FCD1EB2521D444F900846F59074D715AEAA2F46E956365B7E67C5528841145C442E6FD7B3D7171BE05BF8BAA415260F645E2FBC93C46B9F94D2997929349B88C2FB1AC6743B73DE66B30B44E5DB3E07E0FE9713D9D7575EE4E40327A58DCEFBA0EE95E22D06FDFB720993EB134073A80A4F06F8303C7758DD37CD7236E5D80AAE2E9569834846E7F6C75051302486B2564A1D8D987D1A3648192A63EEF4C2D25AD41FAA02C9F227CC9F655A72CF7207ABBC66F9C822EEBDC89833757013776C11C310A22C226ECD33E5B0772AE2DE8B8E9A876650D4A57B863BCC6197261D7D06903D414AF0922312B7DE6D9E64F99509CAAB8D808DFC5F046BA2CE55817512535EDC2477D8462A1817E45D33B9D7390A11E30C3860CBE2C4B519812ABA3AF7050227759DF3B6FCD6D3EE5C60C1042DFCDD7880888A147AC47A282EC51D0DF664451E37D7C40672A27B965CDB805CECD3EEAE38A0AF4C2349FF39947659686D30B9ECBDADD80C9B06293FC4BD5E7A0E1E9E883D7A4EB05102CC1FE45F1C9BE23043BB458E6B8B6C1C187761004EEF59E398B1124B98B0EC0F7B29394418B38D8A3003ACB85D96CFA0C3C63B2ACFDC2BF5540D029A261243E06393253B2C3FE253A220DC7AE4BDE0AB4B386DECA15FA2A05465740B072FBB0C8E81663E320AE931A2DC7A627C805AD80819B9D12EC271D9D16736156195302C93490B4F85E8B4F5199CAF233974079A7AD590374C4E5589D0FC26F70FF2CE51FFB3E6742AD5BD9840F62F745C42D6085E46182FF73FD079BD2625338105FB39110B660F8C55D0830587671CC802AFF63FA7FCFB3BDF6D65B362CA0B68B31FB802E7870C3905B04B41440F549583EC87218DF6A0BE0E209807AF053CA121D704DC0C90A499D1742658BB096C776514C89F6B2D3FC7FBC4A38C10DDBD3C08F64AB076C9BA4C7BF24EBDCE9C82B1BCB8E55C4135976C878B95B6ED108C2031F4E53DBB19205A7109C50289C743818B90ACACFDEF20EE33F5C9A7142B5640F4D875122E0E5"""), TestUtils.hexDecode(""" -9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") +1fb3b6053f9518cc51b4a20cb33d02a7abcf1cad4ae7806efe9fbf8652e3755275a641f27879f163a1b265e886a1b21b129d48807bc4933df0cfee53f26305170c547145f3ff67fc6f317c5ffcd94f96fcc4453ac3fce38cbe41b6dc01c2146ea3d1e7a0bf001be3136362d75aa2785efafce667640dafb1b39d555a106b8cea129c5432867e0eaa493c43d21ab388aff1b6037621c1f134adab6093ee7e5760e9f33a0d8e8c63cd70c86438d3f94461a2d4bc9f41243e362bdfb4c809fb28157a6e5ab2f5c6e16a7336cdc4183ac4272920485fe34fe03057ae7b1440aaf99f28ba89ef1b0021cd863ba36e8deea60aa14cc7f2dab46dc401f12f5b61fb82a195781e337c195160fc474e52aecf4c6ff277908c481d51adac39219b29fa7ac703027354491b869e3ec404b4c35b214196822828079ec85ed0edefa0ed2a426ab9bf4c3784238390e8eec61cf7fa1c4a1ea1308e0815202f1109250fdcf69309ef634c4f0b134ad6d33ccb4a5e30c0472bd292c42de895de1c5989922bba6004283fd1376a0a263ebf74e414da5c058ed9788a862408de4de14b54d2adc7fb5e36f827f53b779e549698c8ae7fe4eccbca4b41b81e7239114720147851f0a72cd3183e33c6e82c557a5eecd4d07a824c6ea653168bdaac37a444fb63b29cbc35bdba265c5718421dc104206d224ef985992786180627df4b2f3ec5e6c200c2e0cbb6fad82db3f54d67f5fa7a9d1396c3b8376b3d83af731fbe8eed49bcd99e4fb693c87e259f20f61a6d67c8d87c967d65d03fe81e5d5f14021f8deb4d1a5d25902065e4ef707205a8159f02b4469be4c2094aa73580572a3568481f63e470bc86cfdf7b809c17801918f2a6f742892aaf696e2cbd2bc617f92efc482dc6bf8640a91582e988112cdb6161a41ab879e8c3c15e48bc2a7dd6b4fd25b5e7efd7388e6f3959bbafe518db3b73df504a6f6cbc6086ff160b3e7391845c9797a494000a23a9488008a595334b7b92db4b2f9a267869ee63b8d3b83bce7d57b9018bbc858943f0c7e8fe0c94cd0718672e4473692a2809423b2df248b2e61dea545b2f1db86b7246a345ec591083f4662b64664bc9200c3ae8ce7006cd795cc146aac8315129d62eb20e940aac6430165476742a19c17d906c3fd94a543b453a2f5d3c880ae6a1f64125efef20d7a0091e4bd66801fab9f7a396c84c4ed28526fc1b0042d4245d3f57731d56165e26e1ee72976cdc40b3574801255709cadd4361e7984527e6b9168a8f1b507b1a3f94d20b76bd4a0fd5ec81274207df86ef1b18c09e4f77d0670534a6ac9eaf076052d6d037ec469ab453404749c3c15cceef412a87301cd438c1e5c8d016a2c125a296c4deb4a12b4bf04d9593bd9d66814dff60549ec0a91acc5bb00a2f445c7989af4d3ba9d35868f7fd8a3687495f2580780f8a4c3e9f012f0cd07cfdd7e513c9a84bbf7dffdbe2934480ad3cb241a155248e9c30ba5f5d1574d73488beb96ae47913ef87530dbc9c941bcadc6a69b9acb06be7ceffd8cc7745a4fcf978c1fa126a22864e912e9c14fa73914ab1b9ff31988e6c859bf069bd1f912766680111d9996ce8565704046ceb64610f0c6162f74de87be26889ba868eaa8e3fd8c1c4eac20deba9467f4fe5427c06192a5ef0e84d2a063532131a366ba13b48a3735b7ac98d5d800f6ec7cb5b8bd604f7d3c72dc56e126ae14cb101afc3f5832fed4e94e5e7614e1232e970597997cfb3b9e6c5bba771552c38c9d6729ba0ffc2bd146754a3605c64718e9744e4f7c1ea184c477de17208f7baa9ba1913598889ac44b1d30f5b81aaa06a42c8f31c889737a8d15e6d473e0eb16fcb57a56f2fa9169a56a4d5b687b50e77bff964522f14530608fcb7f405cb5faf36ff235869b99b08765fbc6e21c91833a5c5e6e85aaac997fee4e800dab3c8fd5b35e1cd639931690f656f05b325ed80bccff2013c683b0419b5f43c3c14c245e40f537b55d20165a92e7b6bf8af9c81cb4b205f327b946c39a0ff087915b015c77930f221bb6c2c8d6500a521ea549f2d7fdb4108aed7a5aa6217450e238f1727535b3635f7e1b15b583743ffc9a2436e99c8f6e2a46bce90434f345090a76c422d778ebd3d9f4364af2c89d1353d64ec72d691d414f56c7a1747c7ea3ee8b284d3aa6612fcd30a08eb7eafc3dd42f221200fd0b394c99235ecebac79fe467c747b3ed5c09ebbbee5dc240287cceefe186f0a5b5f4fbddb0675f0159c750d715d0b01978cdd4e85ba77cae57024c6e6348155071016a96575e5f9b227c87e82db0a8470124b6572da0cbf2cab372d85708adadb04165b6cbe6950253e2c1034537ade941ab6633c1ee634371764ded5c131cd57eb9d3a794a2d26750d01498214ec9b78ba4c9400cbf7b910643a6ee5fb12fe1f2cb348d566e63dba6c1fddca6a0a6644eb7187a53d0b5d8bee99d31b92981fd81cad326a8c107abafb623a0d11e861177a58f1e3307fde29d63a3924bbeb0e946bf7f667599b92d98ab6af9d896e2ede95ca65cdc98b07456bdd037aafdc4c91bd387204ba7ea14dfe387430d290ada9a8296198e89b746f0264ef95c45ef3748bb9806f24a61565624fa84326594a572c701602c7317fdfa1990426ef70a5d3434e7b1ffd779e13b23bea25d63dbd7d9fcb713bca6c203d1b2f337a6e768ff8d5a1b1fed4d69f973f0e0a59f3c3527c30a1942054d3cfd04443d4611259b63c14f8eff56d17465e29a824afe408168acb215b5bb0252bb7c705280cc003311303373f30074bfa769676ec7a48df2d9f68fdb043b035fc1807fe7457e01e794a5130a857c56e92a8dc234f03c5c7fddf0f385f63b4ee438a2ed5a027af36eadab17dbd7eb9eb541e6ed5af00e1415622b083855f23d1c4639dc7c5b95c71673a2580e88092e446c29236900f685219aabdd06720f0e50dfca6bdf53c09ab3477833bb835304ffc65f1d6513acee999682bb70665806deb596566ac785afebd6ae7227ea882941257ebb10809923ae562cb34be2acde2b8b0de3f2a8b81c53d47a80a3b1d360c9cce2b484cc5dc62b948a6f990aec5d9c34b745943ba361e14de27232dadf5c72ad2f47e24d0872b2517843f3c43d1f348fdcb5fb589c4b304ddacd5451771ab0c53c03a33dcfd13e2720ddbca5fcd3f112eb81ad6bc1aa059e2261d7cfeab30fccb952a0254d92ab6c884ebe18c878adeee97721267393bfc85a5a4ebb7327c6f69a71a864e8fed0665b0ef302f16ca3d6ae033bbdb9443bc40c78eb7b3c5af66ba91ecd852e4682ae25575cd7d09adb3b74798d14bffca4f5bd837e80afbd77510ee78c32ee219f4156076dc6bc9ce87971e232aa4d034366a3e079e21cd17ce42c3f60f47225ec2407147bfe01eace5552956e6697a0a64eaa3b02ced7a39d1a1c2eefee96c2f8bd2c122ddb0960929e57247fa3a85fca43f63de635ad5d4fad02565aeb7f00db0c55c5552fcbbe5889b6495c59541a77a8dd20503cdf916b3bfc8f5e87b217134f2fc7a6cd13a736059348b3106bc431d929c09d4d6c0e39a93759953ed35f1df0ee90366e73cf0ddaa03bd39293e95929cefe9cfd06079b592b42c6e9f47ad6c4263233123092155047ee7c48e3e4e62f531d3810011a76f477a8650bbd7be790606775e1f932dba57e5d4bb2b2401a01a20b83b69ed97bf1ad8c765c93d8d4e1bdce3a524eebd6e54734d568711804d4da19fc69997129876d235fe53c78408e78081da0edb8d9c085c863c6603c06b8eec7733dd5713d79830b8debcf6d3e9183852502fc9bce62e85c20cc098cfce099d0a810df722d67932c2e3fbaef6efabbb67a83afd4cf9514598f316b72551abff34d1d13c93dc679bb58868148fbd33628d8279fee785dcc605073a000473e8ea9dd6646242ca2dc3c4863de1d0f8ad955682a9ba9fe52317c2e5d130892d5b6dbc41bd0ff3148308393d717ac0e96fc1f45e0539bb55eb50549e508da7db93d68f1711342a9d6ab64e178f55cd6eed8e8c28a497336fdee128df52ec475e46cefe3651ab9935ade5adf0b29ba5358d35d3b6516c8d3996aff1e2cd06363de48eab1bd00120a0d407b092870c2e76b276c70d4d7ac85366f60f2343241200253f92de66b037fae4fdeb1db275b7ae6ec196902ac69e9783fa6684584dc9067c7cd4a68405e0aeb2a4eddca1959cf788c0a516eb94f0824120ea24b9fa2354028afedbafff79917820d4d15b12def7f9efe49899c715c7b500f70980a8c799b93db838ca2859a06cdbdd5f84ced9987e1dbbf74ecf24d5f2484950dcd57347da8b8aece55d4afc7adcb0b232082157b0bbd455ca7ebcd0ebf257b184b3eb0d1ef736dc7d02681624622947c4f31f0dec5b430616a19b1300427495088898be15f27cbc4688ad4a93fa208ea20bed26e94984525db33a34b7631018e55d1b8ec54dc75c85e0c9a95c4f212092801e1578ea2e1a8a7850952a1bbd2642d7328a558c0fba8c167eb38d105d31be1cc497460fdc3973b7f004f1aa58fab493d29501e09568b3fdd7b1c8447cf154bf57356fca7c412c79417dc20e2d34485e6c757aacb1d7ec1c6d7bd97374b2c2d0132f6e749fa2b7eaf3ff2b385c6df71c232458babc000000000000000000000000000c10151f242a""") ), new SigVerTestCase( TestUtils.hexDecode(""" -6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), +4253129ba04cd46ebdd117f477bae35bdc6eede60df6a94a580b28abcf8bca385164de3e24f7792faf3d87c7eefe208adcca6f711f57d4860bd6df7f3950fdde40ca14784f71a397f300730072cb47d82ebe5c2360b09201e54b0e371efea2f1602ce195786dbcbd291a787e9fad05bcc548c4a8149d69b1b600f1111984774aff6083ba2dc1d1aee5d0d34483f9bf970229d87c858159225c3bb28b406f060dcd62f95770c78fba88f99e27093908cfee69b3d71a12f2d165bc8ed692209989f37c6bfc194a1ed596a38c4dfd284d734777864199cffd431d2479b24b3d77d6f33d92b684685e04dca571ca860f757c6cbadf7b1a96bcaaa2d349fdb057e066c613ea88c59c656ca5c10f521fa8bd770d982d7f042701146e16434dfd174a7ffa4efbe5845b6640763ae0b8df89e19beb0f3b21dde514da0693dfb0918ea8778ae0bb668b306a842b9c058aa8b3d3128fd468e4cd88e76e6f7cf737f85a36d52a1a8f3e185c455f57ad8fa5b1ca0e8ddc6548dbb6b217d1aed1e3fd82a335b8a41f2276c07bf9b08d2dd4e56ff71e22a66c7727f0a6a354c4c97826c9226b3de7931c252d11e098279f5a2b81117cfebc677ed05a2a81a0d74382ace17dc6a42e98df023115e03412b55a0e9edb4f1c7ea91841678c5c5cabaddd8fa57b5f1a5c1570ec341628d2f56268fe48ec9ad88f0cfe1a0b546bd10da7d81c39036c6a852841b8e060da573c61983502aa36e2874127f6f2c3461c7bf96119dbc5e1ebce6f33aa62eda8c7363aa842cc21cbbf2c1151d009226ed4f1b3afa65b06818805e41e7e2e63ef2a816f1d88f53f80963e9918136f84b1114bd2472c351816c4770722d797b6ed610526f8f27642d13bd31eeed3f8bd5cde13edc38c5d288e190fc7eeb5603ecccbf2e97ac9222cc7531dd1736cc6e93abfcc5386d1ba9f7143bfd369ca09f5b959e7700805597dae9eeb54194817c1b29d7f0519c39282b4ce257b191a1dc287ede4bde95f22c3f3b49c33a2f939c9dae34375ccb3d8995b3ad06af98d5b7370ffb863dc321c12d49bb94597ce00ba560ee60ad72cce2567c06f1d3fb5e277d252b6fdd2e291cf57438a015ea85b4977bb4766b3e439be35576718ed67a0ece1b590967082d6b813add2790d59ea20b088d30da760fc054f9d0d798c2c477d81a3d0bdc2197b74d41a9be185048c7497e8397b6881b5acf15090661651cd27f5ce524b326301221c06233f49396781dbc25f72caac8f26dcb17833647a4c704e4b1adf084bad42e041af26af4bfd75182fbafe5e6450a774548ef7f3ced7f4ce107f4c0e4044cf55f8f7d5e09974c79e36a85a6e7caf60b3693745ec9e09b047c7de351074ab58cbba84b0d93460086770d7f59d5e1b6291cb44a62e90ff7732b0d7d1e238ebbaa9dc8328012e1520e6a36ec864a769cbf39788db9a95a78e2d29f40b673cde57490ffbc36f973e7b13f0bbc977e43dd16716ca23fb865ba1b7c8b02d5323c166275472e90e6c72de1f08101084012706309c4aaa95c7b5c4165e7731782b508b085b825f2dfbb5017da0066a7b17fd22b7b71f9cfbb799589b633dd6de11f156d7aa0ce4278415b6a0f896e33e055f40e4c9f5fe63e72cc0d623100137a4cc43e90776d58ecd533fa1fadd505f416b65d528a209d29af23e268d420e67627f88fca6b019115cfc5d4731f793c9a7b7c8627e801d2644425e8cb2735361d4fb7866a460dc12cec76a4d82f1c2c0174b585b6a51f5aeae8e90c0d17c02f85ca2548ba685b1b04031fc82a12b55b00fad79e494f6285708502e3e387387e8ccbafe1907f33aebcf2662a4ee6097aff44a9117b3fb14403eeb36dd779782341527d59f5e7ae04f18a242c907927e27d32c46b5f0f6e2f097ae2f5f817dd66b6ed80c7d97aa3828de63df8975c4e83dd69d30fbca2164c61dea8d1c553c20afb3061ee242d33dc5c53fb0045c07d837ed97c77756b7fccb948dc89bb4221405f7d65388d62a52139b1b489afc181ee209ad37afb879488e14e286005dd4b3459722c5f2234cd5125b627ac46716d5f0e92712da986e95dc8d22fe9681645e9d7d2ed93fc223aebeeed8b1bbfdfde8c932a3052b6e45f49f85ee1561e455e96f6dafbb9fb89f2a64631e0757172172099a8b9e43965f014684b527576c72f6cb5b7d84df202830989d4ebc1160ff9e170f6b36d7136621611c725758b1e5713d99732014e6ae2b6b30c1ad4ed1d529fc3e4db71b16c03b0d12ef8f2fd2d5f9a2a3c369d4250472e5fc8d8987f9334a5b54adbef49ba79bc9e2249e2a2b726a354b596a957e17e03e4f3dd7562f6f7c3d8f8ed1f93b026d4f77e14cac27fdc6f5e567ddd8ac4ad88aba3b418bf03041ef47f4ee2e29ae4bcb0c4d0a40cec26a808d4e9a8fe90d4df0c2aecb9c713b55220306b4bf58b0373e7450388922f2ff2adda092a11127f6442a8e358914b9a9eb48196e3ffd9dbaa66c9730682b84c048a4023dd220b80d7cb185cf35e21369eed4e92d3c0ad70a33c409aa20402a2f0856f87e562befabc8ae292d720686c2ba269847ca0f1878e43056ad20807d1433e7e1e6c0f97bfcb6775505f581ff8dbeb4d11ba1a8343c517e472b631e6c325df855ba0a8b0a7b1cd21767375a34f60c61a72667e8bf2594c6f21eaead5efd2159a3a116a8dec925cafe3adbc050bde5a64292f18f0ae2a38a2206f33782b51407104a733f31b4922c531f6f6b57a626d97239e698"""), TestUtils.hexDecode(""" -C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), +5870BB288AA6130708F7BBAD9FBDD6D41E249D620495ACFE90C61737B57DBA890213D4741718545CCD8B3FFFC2DB33C39AD631D5B5CC902DE4D340DF03E09248F67E89D28071AA50FA532E94C391D2D1A61B1847C6B1088BE555E5C2694EB0FC1F029095ACD9DEB21EF886BE577682CA96AA2EB3DCB24B871336AC5F23C8488011860B455B687BD4CEF5FA11381BC292B4098BB2CFC1822B48ECFD28AEADA71809BFDA190836D3215CFE755FDD9374115E5A0CCAE15240EBA0147C2F89D8D24454D7A5AC2D20ECC0D46C040FAD233FC51C870080F1FCEFAE6C073AF5F7A78D610E23831D5990985FDBFDC6D101ACF3DB0A74D71739E0"""), TestUtils.hexDecode(""" -E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") +4211c0fbcd62764b125a8c5263404d7848a1812dad1056f3368817cab3cdc97f852487ff9d2bf404029ae58f9ddba2fcf1cf5006568c2f424aa647b4024ef30a1ac57d831cb0eeb85414d3b9069918d92e0fd933b640f0a6a777637245081aa0d27b2fbca9deb27ca1d1338189124269a14120101f0fc279ecedaab6b5006ca4c7c0baee72c5d44f4c330c56bb4a822ffd3e9c3f2602ada56da71ff40a712f115cbb4bcfc484b9e778bde49ed7df2d9f233ce065d1a9b3eca2c494fb8b7ff6b35d64ce62ca335c27a3c157c801ee1988dd9c7d0cb0b6d9c2295b17f88ca760496dbdc9f68910fa07e48986bab423f9059ed8d4ce90b8d1943d1231c8442dff36a63d28e667bfd075a66a7d729a2d852e89d8f580ae18d6652d8c06e02bcdd48970a658ff1293b6eef87108f9192e65001a21bb2e5dbe932a524cd0a44155e52ed18e1f09b9c5d46483774b49a6559fa78377442c9652b879597b0569cb791731007d556a6a26efcb57910692925f041d4d55a71c7a221f52cc578df50d0b5176a262250f55bfa3abefafef82d31d1af2facb5b6d46c554f67d27a143fe7ad83d4529183a02594b584baf860c1141d50ec50db36ab24adf208289635a7106c3b0bfcf48c6ab881b75f379779fed7f1dac26a4698d1ab9334f88ffcbf9a96eff8e85b34a6ae4d2228b7ba474bb2bf32706ae6d35409477269baf4a8effd70f98fe8aa791bc49b7fda540d80d31d699508d3f9a502f90ced18fd6512aa02a22d941acd43e3ff4fc802f05da84ce5c367f9497e165ed4c5de86fd284e0c181a2cbd1f16b66bd3221fd07e368b1e00193020162ab47e61d05f54be7354b497cf7b6e8d77b932eb0f8161cd015c089ae62d604b647193819b21171c1f493bf0fc7f67407045f56e022ed791c17606633967986c9d93219b7db49f3ba21ccfd1bedaf84315a770d978ab657ec5d4e3e39d8de6a163ed199b5d713d206c9eaaaca1ec4415b015aed58797e4e116b366081825dfa54c25759212f4485eec2cef8f455109e893b4732b437c301db78978831edc4154a1be9972d4facf9137e59e2b04b89fce1b6cecbbdba092518d1d78d7086e55125e22edbdf53dbc67f38eabbe9e76c69554fab97dbb290192f1a5c66384a062c974df996b618fa8478fbdd0e30f11549040643d583ad80480c1fd0106c1f2367cf2ab8eeb641917381815b064905ed6e900b7be712d3ccdb0b1004ad33bb6e8a34b94c228940afa09623c85e490c32023e157b451f02aa6017c1656ae1dbb4e795aba6198e6b6abf66874acd91ea4028e3a9e1b68321fb6e707a72443a0a4749ca460cfc0422c7c6b2d322ace8b51270514d0fbe36d6dee137a89d32e2d55610a60dec2266fd7218ca4d925f15a7c84edeaefe84cfe9a1d672b551f5f2e32308d0a456d59c26b7a1689ffb0a3e4817c5e385a0f4658868814272451015ace5bce4150306621cf53e232cedd3dae72eb1a240e625de8556f5cbee438cbd913b3cd744146228535ea23f310379ab18c24ceebb685d0f61e5c81a2c3c9b4f4a7a533a49c8ef32ad14f2e77e210eaf1eed44cd6c845aeb78c63d7c12c6e5f91b59489fdcf68c4c0948a858933604033209a9d5a2bfb68b101f604f6f10bd9703fb9768c2aebca6ed5b00e4974bb348da101f7f2653d55decfd624a7d79c13c05a7da0ea3211f7bdcf7bf1df8d21ab5f4130f67d5576a4c8a927b7c7890fcf42e1a431c0befa7b86a5c56b283ec96a2f27309ed629b8bbacd4eeef278d7775d1c5ec5bd331cf622298a343cd473b905abd0904803d72bd2463d9a88cc11d62068f0d7fba61781fbbdea6842bcc58385c4f3493ceaf5d105a2ec7764030961546d89a8aa5252c117611c8313ee2d7c96cfa76b1f3daa4e9c885b2d271781c654b52ae904f5ddb3d58335dd81e2e6202925268eff4a6676b80f9042c1e1971fe8a9d6b7c8d88ea282e1696c70619a1baa29584c0acd26967b4dd0252fdc8dfb645a255d32b6065951e7c3da633b92017bf381f1788cdc24b205dd6a7db1335440d62d81ae8afbf2640162cb92095270a8ccd65ddf5fb667fe2b5d33fb1bc5014a6af35cc4e4232fe052014cf4bf2ad9b46684704532f33a0f165473ed2850293f6bad8fa8cac3d74a995b02980fe5275aefa92374719e218185a5d62a6347f64f9e64ee8d06cd9d509294f18542d432ee24177a0af0d2374b5e29735abec655bc4aa1eccb6b8c6cd5d0602b8de15ecf20dfb64f5b0b57cd4bf2e88495da925e98f46799d344c070d95e7527ee7d2bc1e5da7e7e857b2c3c91489d188b4b43477082773c95479290b13779c25682dea8fbe6c8d7cab9b07342894eea86e708d1e1e7f3ed998df17cd752e947e5d2cf4b4c3fb9adc9049bdbed6badc20124a694dcff1deab7a33fc3f7c8a9c7fda5ef59ba4ed3f3ee925aab58cc74b789103500aface7eb0311a90c13b1740a54541e95ed0982c9409800f89c9519ebe0f1f8017d639ea1f9cf33a70633ebe2abcaad745ef5edbbd50442265b477a2eb61e89054d50c8956e6e2743c23a387d316cc5d0b02182989c1f01580b597e0a9f578d3a3aa6d5f0ac1534497c5e8312055e434c7719567be933cf6d213be58ac37527999a9260e7a0850cab48097fd68175d24c6f1b1ad8e104b3578e4fe746621a50bbac09fcc3a0951cc968d708bbeea3e7437bc269416d826e8ffa279b755abff5bfca14e90d791ae0357d45a301d166c19dee82f2c2e6035895b294f0ef30d003c60422f78178c5305996363dc281f8627ac75bcbd28c2a7e1ca918d438c88cfaa57766a372513615592861b9872ad6fc4639e885bf03e32820a49687e0df3598b45a2f81e33fed4e91b9bb458fb55ca35d99351b20dbde76038188f01935c261f07b4287aef1158a5e2db5fb136446cf1ac6bc8265f84a1314f41cf40e283ec5da03269307a31cbc5a3a80b723b63c0366febd211a0a448604bd7e56d4d5d9a7e6d8a1247f098f01bab54f27e598fbe6483744e3bee936adbe1fa4869ed81931cd1d7b4f9ee02ede169104f910cb6dc75e10358e1ddb3f2a661595eb44cb851c53c3f2835f5434ed0945a354483203564d3377e78e3959b93244e836ed4475f82fc829946037bfe7300742203d35d55cbb5c18eff04f30bb9ff99ff1b45858d5a46774088bf295ccb5e03792779dea64d4318f800e10029995e3bd7cae442a8d9ab8cde1a26c1de7aea6a9a70bc16597e54e93729fe27d938b205a0edae98eb80c95e6ac8770f5a2db81bf1fef6fe3063e4681751e9003db29209d1f84851a0afcf62eb0e6605fa69da74650cbc4fd7347743075d9cca143a8084c15d4372a1d325adff6f2b945ac8f7e9bba76b6869abbf9704ccfa718d6926562dfc899c2498b073184ea1c6824a245be772b9276f279e2dbdf62fb28d3295f364f18032361a5db82d16cfa57b21b4270af55130c029b573ccceaeb81293f29c1ba5c0cd6292307c9f0c88100ae57ac1892e422891039541287499d3afbc1d3c68e93a14d5a3b0efb6ff267039fa3aef140953b23cc1d7882023407e7c77dc0924f58529e18b41b2f89747d8f1fb6c166807193100ee0a26b57beb8da3c34fd134a28d5df3cda61683e0ca0f9d92266cf0675081dc18946586e5b9e070504d6125fd485094f3df2eff6d9197b3c7953303f62e276df391c8abf86aef1931d60488556e412ae00f7c201e8d64070aa72e291e804c209c8dc3fe968d06311d569d726fca4a094c7d4dd4b16014d4a1cebaa97131ef1ee66d734b9f85c9a6e70afedb26e7ee8d150d611b852b0bdb34513ee3db302395492b845affb16680f5bea4896b866fc13081eb86f509970b69df9d7c023c160456eb94d7eba2e9e2e076c10ad52b9c966ac387f808811138b9f7416bd0a9d21dfe8b706ce321f284342aa301f4d8361bf20bccd478386673d2afbab6288b8aff15eebfcab25406864842b7fd6bcf6c42fbd8b2cd526c5dca80e46a04be95cd7d63d936eb8f5430415b9b1232e4ad3dda1abb1b1c0286e4d89b9750fc67eeb22342a2aaaf83766ffd72efd993dec4a06dcfbe5dc3c067dca721d41b14f8a3536e69923d34bab47021bd1a16640da14fee5e587a833f2b415f4c454b80c700a4d9bcad4c94b6db9cd969d199f0a3f4fdb7225d445cefee5c67b1d6ac63e8e51d80cf32ae75247436bef80affa4b36096b19b1dff52a88f7a3f2e29dfdb9c5dd994f3bcbafd976f318fc59e3d1ab60e92a2c0ca7eebf68da24253b4bf1bc99c98ac429becba641fc2642074a07a9249ebe6508dc5d0d460f6c7bb873cc6a2ad7b91f03edcdc731507ad451ee3d9a4527721a5e76a55dc008f438014fd0797066a51910e958d5a0d92ee2245c853b4c9a7b2e7efb1e9e749b420b126f0a0240c516882686660b38c60007f45d7648eaa2d7b1c6b1bdba8aa5ca140e8c38b0cb6d54e3083e903f7c3f6ac97d95293506613b3a35f1c2a8d401f66d917906210c758563e4722d30b05d375c8ecc41d898574c3a20d218b581db4c85ddb2125e56c4918d021f96bac324ff9e9789c921cc5281c0f0c98a98fcf218232a8b99a2bc34a4b7c9d9031b1d408bbec6e3e633555e8fabcb0115324e000000000000000000000000000000000000000000000001080d161c20""") ) }; static KeyGenTestCase[] KeyGenTestCases87 = new KeyGenTestCase[] { new KeyGenTestCase( TestUtils.hexDecode(""" -38359FBCD79582CFFE609E137EE2EFE8A8DBCBAD18BA92BB433AB4F09B49299D""") +796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -29B4987C62218C19C77D695EB904AFFAA1BFEF6A52F138604CDAB1534E66DC10""") +60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -9B54B9C91E0201251489E07D1442A42D0BF32189D0C0CA8A2D4871DB25F531FF""") +c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -A5B67695D7DBBD6A7B25146E30DC3F577240AED2E4E20158D1E24143698D1178""") +ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -1B87631F6ECC4BC8FFD14B2792F3D1691A46C22A26BBC98DEB2554D7FD2522AB""") +78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -5C3E3EF0278EA9197F30C4DD9C4C06425C05401253E77DFB3E1D5315CB00915B""") +917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -E3B2350AF8A1817D936FB7435C4C0CC758F79FF4696C46E4642670C5A78B30EE""") +df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -75E70362235CC7CC4A08053BD887CDCC4E3D88F77E1C7DACAC972A9AF83C0CB2""") +d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -45CCECBAFEAC42F2D9166A879175A6D6263C3F7F9B5F39F27A1578C859CECF89""") +865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba""") ), new KeyGenTestCase( TestUtils.hexDecode(""" -4A74BED90EF52CF135555B622A50D1A4F5C53D97D3176A1B184CE55380DE6FDA""") +741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541""") ) }; static SigGenTestCase[] SigGenTestCases87 = new SigGenTestCase[] { new SigGenTestCase( TestUtils.hexDecode(""" -13FAAC5CAA1C92AF31DE6C25B147014BD7FE589A649FA0089AF0D606E4B869EC1E4519E3AEB57924B329B085EE7C80501241FEE198F3F41A94AEED9BFFCFC9F7250182F2FB7F56C145635D81FD4981B541AAF62A572520FE29FCC0AD050545BCD377EDA950D1DF476FD2B85C8C9E749807ECA53A51D6D0F4F42A339AA7C48181C83851A0A830D080651C3741E1A805D4324624272D21366D403652024250188488CA24804C842892360462109258844503326E13390E02928CA038044C348A52A46054082DCC329204822D5C9869E2246918914462A86560080A0C372010B9890CB92D63126D13986C21B02D20C52560340918C641A20872048684824026DCC26418165219223158928940A8408A3646491061E396690A2690CC042D41302119C06510872141400C83120D831205109905A42844DA06201AA30502150C04282521A430E03601CB804C1AA2618AB621610410649450E3C630C4226880343210C09021944589248118C7458B904402126250B400E2866800A2041BA68558080ECB228E59803192847159262A04216D13A00C0C452D518845834402C42846199345630069E2060E084528CB1271239484E2386E93446D1CA26D21C60561B228DC1406D19870DA9211CAB48DE1A20503376262B6014A284259948D80225010108C18354D13982912474DD3B8209A40120A398A88026A8B2280D99460E0A80491246D5B060D02012D13272D04154240860520948D9182215890688084115C0248C12012D0B68DE438666306258A884C9B0801DC087083445222404109252AC988851AB7491B899114244A8A043103408ADB3680593488410690DC084AA04830C9441198142E1B038124B06464209223B484A49631CB82648A9669A1C230C9A484A18420D9226A99A26513C168234404CB224940926C61066E83C8418332254AB48002067102007213A57123842908326E54828101920D83344A5020251B84718A182C64B064E31049E4C090243592A196308CB89109C3109336812399415402101C196153A68000022C8B10011018914318705AC20C1801665B341109836811B78998C6618C40910A430683204421284E41368C94202ADAA66541141213B9605B442901102499904C41342E24C28DC9082E11382E00018A9334455810009090316348610C2860D4262981280DDA10519C140C1B2308D29208C8464E10322E44A848633490810022501845DA420E24097162A04908194453C06144482622C42188320A01C00952046A1B25511BB185243809C2A86C603689608684448065D1226223C98DE400468CA0504800804A283044084A220640D800724A0062810425E2A22804C04C0A408E891089E0868DC2B4850C274843167291220C498061640488D1B605121721D1C231D4C2811B8271A4422A414212D9982589069110220C99886002B7219A1262D2C0219BC28412496A4B089022824011106603A749C1448063A65160380D84460CA4A28C9B162A09A388522426C3A25119A6802410860BB3888BC66C20A028D2A664A416721B05119CA42113932C1C86491CA30953380C92A67020C7244216280492714332221440406492514C448C8AB40188308611346560100CD0302D24B460A03870A0968920842924A88D58002010286EE1204C14286DD3402DDB38251C1381E4B465CBA645E082015A022CA01612C3322A14A36480124A01042A0895250C8440809051A1282524B86D08318AE0220E210692DB966C83124ADCA0692127065B1828C1882D133209434411C9462049C48481146C18956948C4480C492603080D18942000130901436118A60120474819111018A50023019022882818054213069191062509480E11456E8A00449914010020122092480B8320E4321210B429C290512139049BC411129890DA14661245048322049B442A942291C9A845CC408203C77181429223B670D924218BB08422392C4B2860A012905A807113462992C068CBB68D1C8064840482D9B82152202A1B0565018545D4462DC8B620D3404003C42051380AE3228541086C04C62C8B20051B091008A420E0906851B685083825E4428C504866CC98281B1171D2208E4C324E13424E02044984B20513B9059AC86500472E9220710A300CC13620DB8808803840188810A1A84D043582E404320B048061345208C5201B92401032121C426A231904949090CB9810B0D16BC03B32C91F22E9DC32FD1369B126053CEB625567AEBEA42D32F861AE27857C24814177623EE402427442714970674EA84BD573741F3ED9C297758E0666F718D5E61117BF138734FB56E3348CA54F05492294F52FC90C243BD836DE2D5B9797A189C7D38E6E35AD95E1533A32B5B589AB56941904BDE66124FA6CDFAB90C80A05A4EE8E50A5DE061DA6E11D3B40F218664631444651497AC3AC3E9A9114C9BA1E92D2FCEEEC9168E27296AF943472C8B4E251F753EF79F80948F2ED5BF690E0C0A074E8E0E4503410E8FAC6D8B022BCE3FAAD1C29681FE2223125F43FCE56DE461BA8264DC83CA1E690BA638E49052D0D05EC5176D12458159F2FABCA6556F15914598E014A4582C678C0F6ADD2F2AEAA330E816B0AC0BD5457948FA49FC4C954020070451143D8B4B4602BF9616BBD1D9F76B0EDD63F186BACCA0C0F861822E6AB56F771C6742106314D54EA9D0F1BDE66F4A504C6902D86B815F46F47E6D69A9DC16F290A8A9EFB06695670196D17E096543CFBB6927E25191B9538BDF5858B54EE4F69D35CFD511FAA422B6955F0EA87EBE5506DB4E7871C7FC5A2F974C736FF12AD545CE507AF4E430270E47EAD8663361CEFC3FFA2E3CD85982ADF648DE6F899056672D6CDC6841B1F2668CCEE9CC630AE9A91CEE7648AAABAFB09E4AC7ED0D7ED8165D851627A01919AF56FAD39CDFE838B5CF60E8FF5A2A7C91EE43F1AA3F81CC853B178E3481C32C2D6FD40B0EC924CC1887FC6DA4039FA0BA82D0A57472C9D6003BB3D819A0533D3FDBDE2CB06BE052AD7E56B92B431652D6D5991BBA6B564C15C1BAE95360A07DD76F0ECE8532376D0B71EB865933D3520EE7B3B35B7656ED684FBE914D01502EC4BD7FF39FADF06F6BB002B882213C4D42E6CA651BEEBA228BA93D825D618084917ABD3130C31B3B935A253D8D28BD45C5FAC4B05A42BD815B9CBFB6198DA4FAAB4DA6E9E95194E8084D66CD6B52BE2DE2A86DFEB25C254F59C4CB168185E00074E9CBF060639CA6ADDB7DE514CAFD5D1D3C74777C11957416932E8745C2B01AB7DEBE2E20FBA37476C0626140FCA24D3EF4F53148C51CA78C935C6C89233A6D4C57C317A19712A8040C1C4D3AAD221C1D375DB372FE07250FC3C1BEA8ECBA24D781492425702F35CEDE709AB063EC0804E71B8669B87DAD1563606E89EE0DD2A0B11B8836F5A2D375AC4B7F85FC5F80268FE26121210A4E1CD24BE3FF9E6D92A5437BF9019002140A42C317906D61D862200117FF0F8B8EE8D4C289C3950D083B5E5670D4ED32DA5C691F20CB648DDB715977ED6AC69F64DF8D5C99B4177E8B98876E7A5D29ED0C0F972CAE6256528233E15B13C69AB592C3AA260C77BA41BC608A57CAAE46AD240DDD5C2232E2297ECC90CE628DE5B83A551B06BB68FFCB152785B5AA6D1702DEAA8E92F704B0D31498692C537249D71DC6B1247948CC07413726DFAA43F53058807B77C4C73874EAA526EFDDFDD9116C98B0E2C5B7CAF9A25278761E2EC3B34B766877319243E138DFE6A3A03038D357516D9BF64955EB8B0A4975E026D0915BCB8637C769530458F242F65A68DCC78157CB30C4632938AC32781259BAA48F11B3949616E06C4D4E63F15B96E203D4B4A8110307D5CB3552810B9E1F3F4DA4209CF1BA98359F40E7055C7538ADD0AFB326E5F865B3F69E3D6C9F9F18358C0F6A47777B455B8CCE6C514CEB2235A7B376EF92482E2E86F42331511FB94A9038FF41FCFACBF353F3A43F3A79997167306DDC94A6D0628FC346B06166EE9D857D4B0C63990259AF271CDD8479F4B08633139663A1155340109B5FDAE255D1E4E21539C07249AECFE8E6AAC44A772B39596946BC8080D84453DBABF1E62843D179C1C38F1AEA5CF15BEC4A61810299632A2F3B9422DA99CB13C852B1CC6933DD52EA336A5A09D7D9F568CEDEF14CE1AECA48D92996CDB2CDA36A3C8E95F62DEE742CFF293037273E51F77BC208D5B345331E72C26BDCD0F51C9711BD899EE82128F834BB0B2A3DE473358F47EB2F98FBCEB2624A5D2697B86C7559FF40D14744C93AA2DD6570CC799C4B5669ECA0463AB0B4E1228032DC19A42E4F6C64D9EFB26E1B4E622AC06FD0C47B5A39123FF8F1085E4EADF768FBE9D5E12CBC5F380DBB414775E2836AB19CDEB19A0F653E7CCA9DE567D18020D19D24364E03C762EB54701E1893FFECA6D23A2163AA5CA9FC2DB681DD6E8AE2F42985C2D7E477225AC2F9C5274A5584E0FD90579B32D2143B89F9AD9576DF10A8E82D91C4987AF05F3E720D8557093A1DEC1D2699C2305651CAA0FD621EB48190751D74478381A499A61732B917E84B749A0465408014D249DC7D5C247AC0BF404B4311A25A55B2EC1301350B76E3F953EA2E67C90F1D5B9FC29BAAD30D07946AE1C2976A4FD32BEF26A2E93818913B36B237BE40EB7A907595B27E7BC80039683B3D28323F53B5521D244E3C87798478A8F9ACB55EC09E97BC5220F955057A889E7003B9DE288ACD5594AE65777F36D6C73FF5A17C7A8FAF039F60BC9E3EC54284384429C62EBCABCAE2E78F5B58DC7132994DFB16602A54B444B9A9C0FBA6F7AC3E357308CE2570743B8D2B5DE5F9FEA05A46307623E579195D6B5C946C47C57A14D5A6177636025FA555F700BD61FAE9822ED336AB21DA9E67F9E81CD815F2EB79F25AB194E8AFC564C43CB4CD8D681CD8F1BE41D9376668E45EA7E707EFE2E58BAF0CBC091DD427009B0716B819B857FE9841EC48248AA49EBCFAE706E5F8FC65076E6E871D6958EB1C7A357019950146CA8AB3821317C289C744450C293D3DB4B3006EDD727B5BFE7541F6817CF5467AF94232BAFE06E5AFB845C0216491DCEC3D603B32EA59AE651739D0E26138408A5E37A6E0BEBEE2956269A722AC36D7A3D2732486EAE6F8100C9A278988554895424EC080E282EAC6401129F51148DA16ACD7BFF0C1CAD9516F189AE1D1F4EC79110B942C026C6995A0AF85445AB9DADB1B2FBCA7BFCAAFE884AB6BA0717D3D7BAEF75D9A4507FDBBBBDBEA858EA7975118B94AF78E250F494205715B0EBC31755A38C1AA944F0D80452AD54639B2701462B2D82E522F8752110F44BD381E23C1EA52C15BF9A7DDEC0AB0AFE725B5993A0351737C1DB72989F48FB41AC479C777FD2E7808FDA72790640F9F741D643CCD0C1ADFDE90B9ACC84345E0B0739768ED8265455AF008BC09970B18D52D188AC387CC1DB7E47EF83A0108D39F7057BBC02E611DC34F9DE364B7ED9664A9C5C9D691DEF8E8FDE6C61484A097CF8A937FA55F353D439C380357BBD108933B6CC49CC5C5042D6E5FDF8F85BE9E4315E094EE569C5E3F38CBBED68948FC95226CE06ACF6D0C88408F3AC265B6B10BE10EF0467E011A5EF8F10026C7C54F8466E9E574FBAFF13FE9988E783BDCCD4B02BE46EECD77443F4CFE8969BF3551F2829FF2C0F8630DCF7B088C5BF1FDEAE2E81143D1573854D0D6D6F70FBB5ECB7C6E60F91B241E5543BD4F316C66A7F3C91491320587DA5CAA6345FC0D2240530BFC19AF88B43773FBB4A6369F540486BF74E3DC4DCDC4CD265C7C0D37213037CCCC1FA81D21EB4081C254C4096E044EB6BE48D07CCE2F460718164AE3B68B7298BB1B267FCC0AC3D0365437ED45C742A3FDD746910C1610E6CFEA9A17225DF2B577E790EB870F5A2190ECC166EBA09C171BD825D5E8EFFB3703746817908D299426DE95D605B368AF04D27B01FF5CAB91515096DE2986A0C575D14CF4224AA9523B661128740F19DF8072C917483746547EA422F8A3B40CB67FA87A7989A13C49262089A80B1E4113BB1EB9B469275D8BD336DE344318EB3310B3ACF8201A6F5F613CE0F2290AF5A8B9DD9A5B64AC8BB94AB56C36157C8EC8DBA4125321F30F753D489FA42C4881A3450DB8720892A8D3F52431B960A2404A748220A7305109A2E80EAD78B8D5C1F79D265B00C771129A2117DAFF0D24BDCEC32D53DF76A56CA24B6CFA0775F67614186D7513528FCBF2F7CC47D60C52580BE1797A62C17778DEE9FDC0B6D32585BD35C86276B363915D3D2E5A4BF58AA483891025522B572F4B635CBE94FF014ED19A017EFE0088CA05C54BBB6953BFCCD8D6F867769CFB02280ADE6C39BEE714EBBE252AE5AD84027F8F9C2CFF3FD01ECA4F051591B7FD9164C3C64386D177A74E17181CDD3C55C98AE89CC2C1A26B88D6FBD16DFB76742B631DD8F8D78B308D606B486071C30E81C25AEB864A822402CDDE0CF27FAE8B6CA16500775AD44733FEC8F10AE6677114A330E59FD52747B992113C53EC9A09AAC1C3646FC3760CA6024BF39B7DA597F8902CD605599779509E3F8CD8B03AB66C1993AD4B3317949578351B74055C7BAED3D7555B315765F1065414F39A7848DBACEA596C51D10BB0081381F7D5601DCD07D719BB9CA9A294E092376F6D4CC32B26A9A8FB5297CBE32CF4356EA70225CB302693A6DBD36C816AAD475815E9543F7DC8064C34870A799C32A6BF76D472797F1DCF908FC994604407B59C824AA76BAB6334CDDFE8D0227A383B0CFA2158CBC79DEFA98BC93A38DC0A0420C99B920BBA64DA16819A78F8BAD42355EFB42B4BF17C68AF75F7428B687334746245F7C5145B5272B9C504A9A0A3A985A9738BB1B42FAEEBDCE7E7962CF0AC6EC80F77CC5C9733E49DD1552812957E1FE30C4129A702E23DDEC09FD"""), +f72a05ee9f7d9072a579e3743771e12eb5c748904b15ff67e6a82e1bb77cafc30e16139c1793315fa0b9f5947c2c5b423ef79dda9a5608d73fab61fdf5ade1b323042a98cecd925d9ab15eb79da754237d157db7937297373e8a8df9ff72bfbbc7aa2846a0afd39f61b35ee1e3b3bdd9aca2400d1b007a8d84264e688731d0714a068440100e923048082749e33491c4c04458124e5c4261098480039344043208012760a3a60098200513420952180280042264262288446a52348518374204162043a829a49220cc2626e3b430893430ca2481caa8610014090a842418b488e0886513278c812221002412a1b44913b9614a160c12322098242423370e1b028dc9a86462160d200202a0106a5a3812032108910230114801d9a0490bb148d8122e23464ca4c600581432d8002de3c04d410045e0c2641134448a1012c2464e20484a1ab0689a4265198840da284c4cc00523c58c24204293388614b56d0b170e4ba46820a66cc91600231802d4b2644806828c96485026244a428664402e8c92481214415a0660a18481d18245cc409010141082267018378d10406a2283450a256012314ecca88d53c80148100524a92ce1284e23412621a405613605ca4832d1845043c62498c041d804281bb2718c948c101345a18645a2084891a660e2964443183240b60420c710624662d8c451d34245243428c1c0299c82311a496d9cc811a142040c160a08412904c941634208c286294c988d630409c440291c39895bc0609c02714108291ab345dc843122342208280604364648220da34412dab41124b40d21c7011bc324ca8250d8146c80c08d60b20c83124ad13666cc46259a00880a07484aa8290b8204024862dc203021862154981003304409b96de42420c2962d88b46822c06c1841016118100b2449c14449984206e3206a60480652828513118888b2681ca549d0864ce4342a1b929161802dd9440000964d2310461885612119660934684a080098067122c32111b8889a146d244944cc1485c1828852288e6480410c870da0c010e2c86490c87158424c9442618a984420254e0c84898c28098a4805114089e03846e024040ac190dc388060221119018cca422489204da40085104350e218614338915b408de24411a32081e4122d53c43003b06d13458a1988218c1686511044e1c849a1260e1306481c46520900659aa630e4228eda209113036190888d531851c3b664028768009941a448269a4044d0944dc1a844e1c028c2980523b48d64186e88a4641a058563386dc9804c94862502271110333204a9604426665430459a98001c31401a330d19c98509036940005058062d0bc26114168d1ba111a2380992c2709c308910c830d19071d4926540388609148e00278c4c92890438051c038563920810266948b62492b28190b44014a0211433205334709a2051121389c33462d8986c1a42221bb188dc243049484d1ab1640481601b06500a936982c24823280c03c9504810661ba871082666a00692cc12840299100342029b266922a56cd2088803417009138862124d41140042342ee30200e010491cb025c3202121b990c4a80520802cd018280a39469202205144401a428d9a441040264260246153882c23316e14a241093549048424081652d1405299246aca10060a15660a31250a47521a052813b52908252d010802da04055c9681a4180983026561a22d10958d180146a4b081522080c026414b287100c53124466902015103b370824482243661c212065a1832d9427100088e0c279204076d0315804026111c175109192554006d4ca48514494d8b1689e2120a19016da0386211306e82c2240c932d44a86404028dc9464c02b50da318420049458b220c09c02814c30918a56420b58480984d4ac60411c0700820494a488ddb3611c9002c642081da48504b047120180ea3068219346e949065d9c42d03a9899cb64ddbc831d1342694206619860091b66001014e5948705c288523220c1b81200488240cc34023c740c22045d24250c33681220646c1c4685a306193a6685aa22dcac6210909264906290a992c4c42714c224584b004dc0072a228690841419a3020e4042a888071993244643662cb106409398dc2927058884123352c41180ca31804dc08246132201a1064c2848c12372c611201641604e2388a1c3950d3c8019dac3259917e5cd5cedc8d8305d2f2e16c706b20a3165c635370df6083a64be12031114dd323be97ac280053b276dc5f65045a54c13712955917ed389f5b46e884e256af84a5e957183d0cc38a6c089fd764521a78a244e930eed89a632702849993a7f00c501e383bc265558313637a7b234ec6f3d1543071d61350603efcf9004015f5048415cad1f297a9c9d1b15f7542721222b50c30c26b87db16aad438a2b34ba750d58f48213e351a472e48e54996b421952d00ec579ec39bc0b855389c837f2963bbef650a986cb0f32ce660d539da55193389014130cd102f4cfe130f537721585bc2327cc7daa3cade515981571060c46c015cfe52c9008628228486f880702f97ade1a5e6320eeabf4e1ac3f72776863c8e8a3e89368385173a509c2d7cdb9d07777cb60fc42d0210570c2e8f59a8e043e3343f2086917dd317f62750d310a51744842752bd1a60400a2c3389a874b88a66d2ece5a9b9c864c9d3d4ad5fd79e95955ae3e48bfda369e8fed4e38764a38193481bb5c79a054085ff2b762b241783dfd2d9072d0352a726c32ec38233831585e021a0c97fd1114b7182cc6babc319984bc5a999450e595e03a88a24453c9d926a025b80b53a4a47c58ba9bf5e5fa69151391294bb5004d6e5bd1c730a4b07f0402a15dd600ee13163a5a63902efd52861520197986b7ba28f988a420e6c81fb0afd647873d724683ffae1d6c9e65d001fc1e22f68bd96eaafce4c2041b13b02e0b3d3ac6885cb44e2c254d9ab56ee42189d7dde62cac7c74ae5b6175f430735de71a047ed245ec77195163737d5bf2cf880d1e42d6ffebc751708ddd43a60bfaad314e69208f140ef140a2435d3b64d3e9e3339b64c303564f92384fb9d132072aa2b53239f2022e211b7b023c503faa1f886f4e0f21f814811b0020c2a31b857dad723ffec88da75a4705c08f7c3a28f1ce7680e9ff66d47cec632abfc98fa1c7bdb9e5709e1022ea50d54c7b57e25d13c5990fdce177a198fe7e401e7b51cb73408f358d91b7ca3afb2bef8af7378bf07ac21bcd4668b99591a433981d0d8412d758873de0f12a6de4a37ce12cfb7e5ff8e32dab15a8ad9830e188390d0d8ab109b662c8b61372873d80f2a24f7bc12021c73384d2c38c4c28d8055a85a5df24e6167c0c6ea24ccb4d349c35355b3e924423ca06307f78656b7c0279cd5a25000e7c501711e5fea3ccfa049f59bd9702e6b5c9675416d16aab1e58a878e21242447828c29327bfef77594d4c52c36d33b83f66d81c53632268d2db050ae37a86784ef62ab14939aeb3a8567ce95293dbc155afce0664630b9aa76a272e8db240c736444975b5031c9f7676c7fcf2af3066197d87af0e1efd8c6068ed8bbb387cb359d7e05b38b3d04a4ae7d944d58e8db3b100ded132ea1dc3e3241c5dea374cfe691a050a7de51eb807158319a6893f1d141fdb3094450817c8af9ee50e44e65934d5a1fd039a7dcbc0274bbe98142fe6f50b69cbc2f5c105c0150ae1cf0df64bd7cf73c2714130166c35ad1b5bad3431354305ffbd354bab3e77274bc933c110bc96cddcda6986f0993dc63cfecaf177b8343ff937fce2978adc74b36c8ea698eca417b91548155df19163748121b31f1f075562b2aca99c89459641da7106831ca0a3aec9603597b1a7bec843fd7dc50f644ed6e5fbce214c0c7863bb47a45fa73c884db1d440d3da5c1a7599a73dedb6a093dfe8ae0c8a702d1f37a6cea458a40e8dccb8b4f667022ed84bf613b3f10ad57bce248d2569b11054a43fa9e0152f9bdf331ee7f0b051b3fa90f3f411b719de22c3ba7b2e78481100494a4aaed9d321885b395a63d9db18bc7412ad9704cbcca305b3b04da6b47cb3b8382a7c2de112c46f2d0b870ab38cab5bfdf23413af1b964bd68868a34ed8129d522e0255660a6b717d450c2ffcbf467177e00e5c55acb1ec853832d00af31e8d36b58df62bcfe7f95831fcd9cfb7f51cf7f1a12b84d5cc6ce6d818e7201fb15c2217738d2de405301f0ee1f3f8934d13dcb34852afaa7e0af86a5d31a85c6bb02431be3e0b05fed5209d3f1c51c618d8d261a20043f353d30cfcae57e8662f7d6ad92278cb988f85363cfb6fa2e0f9efccb6c154d0385f2e40e57e82c814ba4903971df4e27995f4a788c36329a715b0b2ff58ef48ee65925c557bb4ac45e2b3d0e1b0a23f9120d731f73c8da7c52fcdcfbe02edc0afdad6f3e7af6b2ce0a29c2ab8ccf775ba2135230ee0a55f9b39e9f392fc66039434c47292bfd4cbe857dc12418442996b90155373167a5b84a9fda96229610bec43d32f403b816e873cb39989e2ee3a885c0fac0bd977546383270acd725904d08623b984c9e46707b9c5a934c624b3b7c817a37cffc9cf093ec52b2b00d33a96d6bb9132673a39a5684c6efe1d1d11f9ebb7dc17c36d40fabb33e396276343c8a2a94fd4c6c8b2415ca91e9be9bd89b31902fa260ae9495d3562316bef4735a830ba7d20fa6e22aeb80b09fa07c9d6419e6dc3c23623427dda2bdfdd5269758399012fd6ce62a57b819c5dbc227ed99a06046fb7137ec13950ddcd577f4b528b34fe3b18ac114d5da5bf7871e13e24a5e38cbf2ec211fbb9698ae59577f66746f3dec2f04b48c68cd0803f0a9bed8d3a54da72d787d5419c8f2bc7ff40be74147ac1b2a471d5fc5d9a135508f203bdd28948a6b2b06ba41a33f598d208e5d857c23342db274ee63cb7813a3c863c8e1bad529f5aca98ea4e9b602497ba913b98e9d1c21510b02e388d958032e5cbf1ab0475b3c3bdacb02142eef236ad34ef9d011122173910767a691f55642fae6b762e1242341aaefa38ea2744ee67bffa470c7b32d87175b5c57ddc1a16aeddc915ac1835c6f0040470f6d3ca4f2611a61f4cbb55570f91406d0f3e0abebcd8abff8b344e582b8d17fa651c89f82181f75d3c88e30563413915255430a29f885c4e51f054da4f304e2ddfbd7f41782f1093e8268fa40d02e970abda862beb0051ea3ec3068f1e3958696ba329c62670a582670834047bd433bb2485c434172f4192b598f04cca6d36f7bd83247bbeec937f1f6e1cfd05f5af2c5f0bed0467a5c3697ee7772051492f8e7345691247d0a151791062062184427801423b398b098043ac0db62fbbdbb76be4c13992d33aa0b8525ba037b76c7f2ee0c76144fd033003ea6720f29ba9ef500c8d78acc27ede081e88766a4f368d87c14d900b45b65046e3652be033c1c83f6ef86c9e003279a798fe58382209a0005661ce13e53afdff6370d6b6c782061016e77f3d3f705b25aca287d5b634b0928d39949bf68bf35e7a1917c26fbfa38f73300a6e849b3fd8f908d37dfab5664ec3d379d6a4eb0ef4554b0f0bc5ffbe85dbf7447c9c5164471dc580494831e3212472d3d2f84189854c98762e8d3ae016425a3418319a8f186dbb781c89feb8ff09fa8f173bcb60b2b352bc2aad3d1c7086ae269ef37e92108285a815b1c1e3517a5426c5d94c2888c10cbdd815c9a7c1f83b4d8b0774377a1e7c799e8c652fb35389f283ebe142a1a2dbe6574ae029194936ff61db61887d4103cb1e2bd21f2a0de551e6f9e1e423a0ef516ede1abe694a97f82decf666708aa8672a3f9b063bf4fe5606a76b3743b16c1381e3e5f4208b9c4f8bba582bf60b3b5d3fa1a90648db008204ea56a9863365c4e478cb9f1155357be84d1faab4db013e49aa46bf050e3f0de60b94de01704c26268b9342a3a33b8ace7fcf9bf80c23fb912fa36765a41bbdaf51d6ead90097176c586f65be9857fc6b07b721fbdf788129aa979124692b9b1b7851fe236a4098d45679d3cce0e4c7aa723259ebf101f3202088f4afcadb686475444bf0c7d38bf7fcf909ccc6c01d12e2cc53823bf9adda6c8138abe27dc835ca7588d9093b1697fe156a6efbecbce0c3115fd1cdb985621f4836cf27835239b24cebfc3b26b0e0b9f9346360e2428c8d7210933c94abc05ac01e7196dd3de6588a3189d7b2fb7efed84d6c53428522a4763f110429d5995ab83de1443560d942becf1d2d741db6fb6d37ad521f8f1426ba8e3dea7d14e3750cfa17f10e8d2a04c01a34185c9113587288349a8c6a70a62539a7f3851e03f74186a3354f83f358500318749e1c34f35bee080d25879a44eab7f28765345e10493bf266607a977e2090d366d07eaa0fc887d4b6c574e9f215748e746ce9c52c46421aac960b014591760f4717eef1b2359342fda9b810a821698afe5270aeaabb9eaa621706497dbf6cd4cb5b4b6b32f870f05b1dec64c67077c8db2f80c1adc1bd5faa31f932fd4c993118733e7a9f544b2985deeddd39670a7d1562d95e6a4746a6c255b8f74772c8ac313726b649bdcb7f7e8b83b558f7352c8524837768f10de5c39dee63f348c25964b1902daa8ded48e03a1a07acb72f0738d42595a4cdfc0c10120ce027175a3f86ee51a3880dd1f470b24d129fbc2921ea1073472ef9d0ecdb634121bce9dcea720a115871606fec35e970fc0ccb626a8ed2962a7f4a7eccd3c93e73ab8aa3d75a3bb0a66d1f7d947f5ce23fc505bf135fa4e6986319299fd6d93ddd12f6f84e191eb04d8df4da1198cc98414640a6d70b6fb2d65fa37d2c7d61c175578bcf194c73143755f0e69375387aef20c27e58d9b870e7b6d6279e55be1a0eadb6de09bf35a79b7"""), TestUtils.hexDecode(""" 67D7F4FE3CC57FC8BE9A3D06BCA0FE4A39F39E3A6158D3E4ADA9CCBABEB542CA67CAC48167928336993C569AB5AE55BF95C8291AE1A1AB2B595C90C0FB19041435F3B411609412630D80DB0C832D413D69C8D3C3CA78BD1BDC24167AF590B67449DAC7F6ECBF87698BF3929FBC874F6FD68551B28E4EEEFDE9A0D0E7FE9E569F1F9893D39C17C3BA7A6211B875A7BCAD0C14194C30D60CDDAD640EAF7A02CC9DAC074779345B83F0D282899B2B9B61F8504BEACA3C02A76611C82F2007953D04FD3C54D7A00DF8F6DE554FD83D1EA5DC841645B706C9D900DEE7862D526245215AC6B9D178E60F9602F1931503864D97F582834DB797CAB60DCDBDAFA3FAE8726B525E8BB69B5E0763FC4ED17FE7CD9C9629273AD5B073B9516F6CD7EE729351C213FDD122E3C11DBC58FD2A501B267AA4AB21364BAA856823816E77B81B6061279FEDA6617247B86073E55B19973BC0E725F34ED4BAF0AFB95E436A9B2290A2B316C18CDC0D9F98F9F6F13C5A3FC767EC0A9A49BE1378E92BC9B3010B41AE52AF409AE0FE27CB816EB2614DA41C796D5F4FAC4A743FE34EF7C0B3A78E0E4A5B439659D4AC27B698550E89A1626FAADF71420F559DF2E808144707B5C02090F754C3BD4EFCEBAF6FA4493C5D48F895FE7674C81F069E1F00E455BF5C965BE2926BD19AF76E20533A6115F4BCF2CC5DD3A49E10A2B3FCC9EEBB2B6E4F25118599062F2AA6CC3A9D86167B1BD08DDB2C53A5E46E1BF4E8C1967866320BA66AB67CE581981F2003B812BA058B75924254EE3715BADB8E6B1B9E4F4AA9844D578CA2F0AD12E1C964685FBFFC87108711E022EA7F63330CA72AF86262838863780F4115138672643E6D9B48C782B8637E01D3D20CFD5C98A1B57720762037FFB12742B4EA8E89E4B32EE7DBFCD5C11E4A6E839A83398ABBC32BA39C6A25922649971D88A102D1019B560C96B820C44551E14509468196CEAFE3B7BC8F253ABFC59FFBC01A13008F77C91B19083A9E7BE733C1A5E558C64557389CA19249CAB77014D0569BAC7812862A610DC6EE074C844A055ADCAAD496F6976C932587BAD9D7E2080F8623C5ED8D9D4FB9EFBDDCC4CCC1284D22A2997824577A619905B0D6E451CAA3B2D30DAD9728FC7623F9ED71F80599D65D9F2AA285BAE393D05C15891472B2DD2ED5CA669785EC4D441F3308EB4BBDAE8FC449962EF9787C39A533847540965601D8BCB6B4299AA636589BFE371D3904E18BC9AAC9B3B6EB8B7E8F322C22A6E01E6B26244F9E39586F124AE4E504FBC9D860A61B20B4C127FD0C55EE810AB9803D810233E6126488A6E95F8ADBB3F8E06D113DE6A3E361209E0D36B326E042CE9D2698DEE469DA15464AFF82D5603434C07CCFC4D956A7D55FE79CC127AAD2A56B34EB10E8B85C3CD5163C4BB8C1083BCE5E5EF986AE028837809641A6AF2B8295B743DD9B03931E755673DBDEDE56F6294270532D685DAF1187137CD7D29248F21B290EB8317E3EB28B62E45E140F4AFC6D1438F81E9EBFC6FC0F1A4146AAD83AD1F0EE2952643E7B6872CB2823AB21A155C281ABCD19E20A52611C6FFAA724578A070935B1A0BFEFBF061101A81227187E14E96B016242DA269FC91253FD827A73743A4BC49FB63E2D830D0FF409AA1C73706D7C2297CBC552CED567DFED72CD15060A522F9B88EC910B03CD2794A9FC07A8FFC5CB97817DC769E64D8C474A305035A49D05B1C572363913A315932E391B62AF291DC203B9A40F04F40EBF26A4AE186056CEC45EB7D21D88CF50258DCB5EF40CB2ECF949B18C72626469978FBE0964C8A25E8C2D27149C2266748F2B06746E8C9E7E2F0977BBBFE3FBEC7353F583FD5F7C2B0139EA928AE1F67004706F6D4ED7BD8D13BC68E0F4A49877C0B2F692936BE5FF99544B2B19B23A97EA6B5F585ABC9E69E689EFE25E15804C650444C479E0DC63C9CA2AEC41A316039EC7F675F1FD7C0476707370CFAEC9C3418CCF30B5D85FE0E15056D6C015DA59F9BE9028D9C2D93434F99DD8C1BDB41FA1EB021BFD0FC12EF0D038CA32B0FE1449342D83CD6BAE43A8CC4077074FB1191A8887BF29238D27415D93880682017470A42872D6CFA729AA2B3F8B37038C83583E4C33256FB871A704527594596FE858777A93D3095767BCAD2FE295352C93D227E1766A59ECEB38FB7C2E3664D6DA0DD4C063975FAB3AB4B68D125AF16D233389D96A337DBC18DA11F37F430C1E49BF8AD30258601CAC9215F32771C6FC2B7BC03B55AE9664E0D719C3B40C3E4FA7DEFED8571CE8E46FDE8701975D94319DC5FFBE93B4FC4898E2EFEB3CCFFB3494AC50BBA364C22A3953F052F62E46D0C35692AF40D2FBF899A23C1A4721375F307E2FDE2E588830753F908FAD96EBD5FC360D742E2CB2C38A7E142C95376ACAE29DE8E1034207D1CBC1DBF2968677AECED152B1EC1AFC195F3320352953F2503227152444BAA74EE8F98F2B4512F7ABB43D7F87889CF1F8C12D9BAB91EFCA5AED21058E322CEB4E59DB4DDE13BE46FBDFB225F4AEDF7137B548503008002A36D7A3E98C0ED65ED9322D66FAD4A741125EA4ABBB26A2FDD7AD136590061E7BC0D5228555D1A59F8A6E4B97ABB61F4B1AD9564E84C000585DF8BB31AE61CD25C9D91D1A1FC21A69AD286CBC7E00F592DFC1C65E2BE755DDF041486F3B52C8F72ACA97A149FE0CE1378236D99EF099A668F6847659F7EF617B66192CA452ECE3010AAC18A65D8964381F561B48D044096DECC22736C902D7E23EFFD26245018D9D7EA9E2F907932A1EBB405BCFD29F7A397C71A5E08962ABEDA5203988A81F787B25EDE84A7D85DE92A2B19974EF7D0378877B82BD7CB28B67F45F7EE625CCD054B44B4CD51802B4FE2E219315CA9F4C24065F5578732DC671C3004D31830DB435C763143CA209D7DDF3F5EA42244E68429102F4D90297B7C987EEDFF0DFA7F31964B76432E1DE27FA38570F2BF64D5FA3F12DD9772618ED2B95F51AC90410350320E19084F1596F6B791AF1EFC24DBFA2B7E30015AB14FAF43B568C5149A1152A47D278B5F01786F242858C210D28812147646A1A3A7CD69996809B784BB2F0053CFE18446F060622FE3B9181AE9175D6CFD8033AA752296016E7BBF639842DD4073AB282FF50F94B9E116C63DDED805277D4FD7987F740EF8118946851A5336A9F6F6E2FE3ECABCC518B31E741AA79AB500D9C6DEFCC437569966EAB1D4BD6CFF8AD0E5698D15F1342ED46CB6DA986F0C4B2B427752C18ADC5070043FFEEBA98569E90C79A3D5E0434119A077A097D69DA6E9AD7E32C6E8875A893F6D69424DCF4C0D4EA12605E5E8A9853E4B58E5659FED6D724CBAF582A89A228F99BE89D88F55095D0627B40B29365863C57F82B9EA22FDE731D1A2D8A9037665213F2C410D4AADCE12CF888DD4AF53FF839E962F0F53BEC60F97133D131C2C8EB588AA7D25EC025B9E821DA8E8FD8E550EC5E4D5923BFDDBAC522D1FA64C503078618B52F452B57874285AFD3F6B182CA6C979734C94F040EBAEDFEB547683E98F4D13F12A252E8839317A827CD97A7C3D81962A25DF7D8C62B57812EAFEA9EEAAD7D6A9E755AE4CF3AF42CA2152F663C1BADA0E653EB165F6FB56D86212378C0B9BD5733D4C37178FFB58E7357487B98DEA35127AB58A804B13E61E6D3E385C96884EA91C744DF6CD44B3EFBEFC79ED19C406AA6ECE144A44F1E78B33046C33EB17E3BF61A17D849493D08F0FCF8232AF2922D96213647A47A05A9A08D28AADD3B3BF412F29063C9D78CDD3385BFA9F8BF06DCDA23FF79A5912D867EE1B0D526718EAFA6F0E231CE6C51959BDCD8D201838A50634F1C6BEBE2E4F5235FD01A6D27B90C58C12D8210692BF68FEA5B8A8651E64EFC1DFCE07EE670D473F29AFA63E080F7675F23E7D2866E5F2F9A525BB657E8BE5933FBED1E206C7BA9FF097EC95B91E14612E16F0F4082F70A1B01EB6219D47C716455F4C1C60948CF3228557E787A3186B4758AD35922AF28BDB328693BAED15487F7448D1796BB9DB5C931EFABB4BE436B2710EA280368A8E20C5782A7FE986417003236BE9CADC560B3D7C2CA92341536CF67D412E855B92D0229C45B1C518D8BFC82DFC9F413D3FB23D37EBD96AA0CD0B39EF88B23609AE0FC2BD16FA9E934329558759F05C8D4C8F3F8728335B659D3986E44508322E47121E592C9DBC6F49656B473EF7DA53FF8EF7BAE07D1BBC68EF4AC369D7F8BE60948F34444C0C443A100443EFC444E7FCF0BC4DB6A2C2C64662A538D1F68F4DB95B0B83DFD744ABCCBE5DA343621F0E182CB9E915B2097C186F1B98E7D8F297C347B60EC26D04B6D9C1FFC01EDB2551FB8D11D49E52956F69CDE0E49E2E7DCC8E7C8E78C41A9B2A01483BAB11733A0943A9B765A5811451C07A195D87060F157D114358E478FBA2F2B755A2A455E9831B77EA9D33FAEDC1C562E1CFBD8DE156FAEFF10AF655713E36FB508342D9B4A239D6DB786CF9F57E1C39AE65A7329E434AA88C68F82359E6F057873968F9FB63D898F24BC13C0F7748F92E404C6185CE24C98D4E4D8D4B3C129CB46C614E773A89EAD73CF0C30CD7E6C9F6435F7C83A4C3F877E034755EAFC5F30ECE03F6413F4C7DCCD01649B6ACA9C1C3AC3D112F216AB852A27DB3B846CAED86B76FB699AA7623548EADFE6D16AAF5A3ECCC298D5CAA7E84ADA0B75290FC6ACE736051924DAE8FC5BA6DC9AFEF65F369D054A4A18950E71901F4483A4BDDB2584DEDC31A04C5F8916DA2DE33B37078E5DAF3304344A8AC368A6668464FFD7898A18D10685BDE6D0097F95A3587717F6A3A8827B46653D56E461EF861D6908AB7D865B532DAB37E02A7A6A72A06F25572D83ED6DAA540FE56BFFB2BC9D104A74F135127ECE457991152DD0564BA955971E8C9767DDFAE190052A98A63C4C0DFBD1B51BF60643E4C5EBCA678CE5150F03A6EF09AB0B1C2A0D2C19C2B30A645C7DB9B56B5AACFB862837A38407070DA9C7DDA20B99CAC7B03D10C8F28D6B1C686FD26F9A8FDCEDA6B188D472BC593AD51EA62DCF73D32EED5444484853AD0EFCAA60DD42DD2C50F5AD15DEC7B71BF585581B9F9C68C7C94C154CC7E0D19ABC90508C8EB2DE93F0BE4295973C1F443A1B2419E20F3D5F883912BBD5CDEB938A4452FE0BF2361A9E3B2ADDFBF000DB07EA19B2735CDF0E8E5C7EC5CC7CCE1A9C3E869718272E54CD9875C21DCCBB06FEDE38A4E787D111DC6A253A4604B314FE47A9B6F6FEBA3F8F013A456DBB78B497C4CA7F90CC6145F47C96D266BE5507DEE27E968052CAC85EC87049CDC68D723D8CF89B0C91F67CDE2908C0C71808004A070CFA2EB6408F5FD6108749406FFD3D5DEB6FBEA00FEADDAC4CC0E22A9F6F50B9893CC4CAD028FBB73C1B7BD4292AEAEBEB668859BAD444D0C5FEDE3C469CF28C5C726B59E828C473C8787453BAA3AB2BFC29C691FCAC2CF496ADF3949CC42FB16F3677D456E614B1F88406E6C9DA7DB9937B00764D61C3D347C140FDDABDF8CE5E3E2D385C3FA6FD9F13F3BF8073B5D6AACD5294938DEF9C6ED414FDE4B3C5EC43865A7FB02787E50F94033CFE32A85BBE24B09FAA3B55B8BDDE60E325B691A350F2F128CF74FB5B6DFCD0E946AC7BCFB839B3765616DF35AF29F3AC82F4E2DF7D4AE87A016094719A07B5897105E2B08AE3D807960FED396CF38863E69662238541EE295C06B290404985444F4B28388DD942E51867216C734580B3F1D5BB204B05D4993D6F8ACDC8F16FB77B607FEDA67939A2B6AE285ADB2C98E7D37A81AF0101A5CE39CEB2C67CF99441C1FD980C2C542E7284BD21F1D30E68EF3606C65D3230B5146DAB41D4ECBD5FD89FFC68441BCFED9AD8B4E0B616127A7AA39E84DBD1343E2A41B4DB1AEE0627657438034E890C8EBAE19791705BF6C948C630DB1423D310A34BF151AA8ACF3269253BADDF5B40AB7EB3A7AFE2D7891B925F65EA206F4CA121175E8F348B4162917A68FA768928AEB0504A60C4F42802DA25DCECEC60ACD21FB236080AF1FCC9146BA30AD964416F4B524ACC416B5357206980305555CE3485425EB8F87401FB1D8CCC184C486B5B563242BA9531147D6A2E7C0BEC1A56E083F05344BF97A18D0CE0FE56E8BE869C746D4AAB365225D8871D4F99020DDB1CE2B5D7D2E5DFC8A0DE780CBA0A9B9ABAC87F19C73639965AC2382488387F06199A08F283794E1B8D3580E5CCADE811ABA6881908277624D5395021016DFE21C345B9A21B474043E187403E5B0ECFABE43991865A424BD33D233AC4BD30A3CE73DCF49B58CC4A3D2CE25C54FAB3480FFE0D51A43B71FDB7E1126E66856D263DDC3BF1A31DCDB935DECCF858FA2CE5AC89BF32E36D8009657F11691201290A243B5680E060D2CE30F1BF2444D67DC94A24708F8F9261945D1B5275ECFEAAF40311CED5C3770A1C194EC44501DD25B7F5FE67BCF62D1BF31119F8EA7DEC1CF536C1026A8E72C7B2E167BCAA8673AE5506CF6208F3E1B6057B5D488B29EB84D6F94AB8AF322B8657075B9EAD3297505AA521D601C21540EE71349614CACE0E7F14EF42D6CD5377DDD0241E34CF273A1171135A376B98C53B218503A908577C268F6DD46CA9C26DFF5942998851627474DE9E6B46F49DEDE85CEB993A52D01F6AAD6F96439C18B0DD5A4FD559812227BBC0567A28C1299626B171855AA0C74E2F9B1AAA781D34CA58C72C708AC49F5AE1453902A1FFBB8458E8B4786771780ACAD999F8DB036CF4C3F77AE345817EDA2AD8F7D2AA9228C994F6AEE512F7C2D2AB72F2099EC932D818E495CAC8507B06CDC6702944237DBCE338C20EDC84D958C14233C1884BA09A023BF5284F0B0157048B6AEB508415DF337A553F6435140D0CE5D5CAA77F9137B2C1AD5A02B13738772743F192E53E970DDB401983535CB096F7D98644797F487CFCD18F1B22BA7494D892C1E5AA05E66B1A4326C70E348350C97DBC26CB110AE8289C97CCAAB150020827B7D7AC7913B4FF515583677018949D39CD73BC7DBB90696D5EBDBAE6BD6FC78E3826C8218996F079A387A17456875952B268211891404E80F8360F042EA3D9F7F7BEF772E64FA1EE8B4EBE0A1162A46EC1E9899766BF4D3099AF712A847CC86291B3D6FBF51B3B3CFF87D7DE71E73069619480F6056AAACDB9ED8E228BA075622C2FF242CB050342DF8F02118D071D27D1FDCBFADFF49184F5A100F95E1BCB019864E58E0F02672C8F5FEB97EFA06FBAE6EC3D57A10EC712BE0144323292A2CB27F1B1FCC104140F556D09A6074F853AD4328B00E6F2F24A61A7932311BC999805F2E774DB44ED72ED244A945928B9512556EFCB2BA7BE0E668C41AE7601339F0162CEC0A1AA91C3FEB6A8A40158D7A3560924455B9AFBD4B3881F6C08EC2895C84CEC30CB0F5B499B4A66267C719785F94A9B9F96FCEBEE939AD0FCF42D0E65DC241698DED0EDF1A9BB4147898E6E83851499175105BADFE4CB00B9000404DC92EFB4EBF41D9A9262EDA550DBD0B99353D001F90AA05591100BB678634FDE4E0B1C174222C253870DA3B8A797CAEA9B446309DE5210F9A932D6AD48A4A7361A943C1BC66BFDF75CAF5409034A8768BD535B20996A728A26E28340191E03DB17A7032FFF883EF664FD7351DD37DC2D72F0CC4B80BEDD1DC33BA3046162F5D0003140DF78FA588A9FDBDF778836C6CAE7E5A20FEF030C57867B295712DED14474FB87A301C31214FFBB4F8D166498ED93B6E233A669CB88D441A38A0E5846EF68F5DB20245980CA184878BA8BE1992A0638B058CD3A3A501CACFC818D2B5D7876DB6EB08E9F26430FB06EE0B9E834D1C331B66CD0BCCAD7A66ABF4A9D8F7A872932A3C0B25C5BBCA480159711E0BADCF69A1107B286AB199B210CE95BCBC4244780C074C42B6BD43869F27BD666F9B2541B1561B4C207E9A667EB1E31942697FCEBFD0B920EF80CFBC5CABA6F528187403D7E8262C110458B5382BC376799032362CE57ED39F0D29D7822C408923C29242385CA9749FACA43EB4483E095851E89D24CAC7BA5AAC60815CB5C8C5331CFD66352BC8623D5700F49FD98FFF9E869D5AE173961138D76E00CED6DBA09144083437CC8FF5ACDA10BAEC0081C8BD2F5838666A093B412532C521753C4E11ED0521923D1EE6BEF3B4FABED7467B9C8F75FB24FD8D96759A6146B34EF951C4DF92228C2E58231A8D25E3F08ED5A27BF6041AD7011DB41F815FEA503973D4E7B5798489B261A0AA4D0C32A19D17C584B1702713D1174E542BE4EDCEF27016BFC78118445A63FC1D17FBEE5F71DFF46F1EDCD050239C68DDBDEEFDAE7EB8963B5BB4819186D45191C05AA049E50C4319936C8788AB72744912AF28BBF5CC77C835C35BB4F987DBA6657BC2A7E58B7CE69AF37AF680DC0EA7797B29528AC70D92F295C561E2EE0D0E530854AA19EDC43C01A383035F6A5DFB354E9306962EAECA25EC85B9B78E8A1DF6CA50EEC733F60C81BF812981337F784F8CE07D0C03D8B3E72BEE1FFA55FB92DD0446CEE29D8825CBAF1A6ED295E613FC700FA31167224D99338C4F59B1BB9C1E63CF77476BF84F2001D42E4161F7737B47C1A5F219F6AC8B8E3ADAECA827AFCD6BC0CA09615BCE15F1BD0803BDCBD41E68F781517907EF3DD8E8A33A1E30ED09D7EC1D3605DC72C9232EF9F92475743164E92D953177B98906DFE5E414E134EBB63C79220D4907869CB2D93280F60DBECCC81B532CA336510E2A7F1D631F7BFC517AFF223430F9804C4A4877D8B7A385ED48F390ED9666A56EBD62F6C943D0E52AB1EA247BFB07C05908E99358A51E6111486133F4A6BE3BAF6B2D4C01529925ED911CE728B4CE4E8CF8379BD216108BF964496269BE76379912E94A4984B890A4BBB9692107D56AAADAF27ADE475E98A566C0C9E33DD1970A3DFF0E2F79197F6315E320BEB5E2CA3E3C904B557075981118B363042BA687DC682F13D213974B1647FB43DF7FA168C9D4F599C5BDFF2941C111C6C43FC75E69C290601EBC9F23D665F944A9B75932DF7792CB8A005A7CC83DD071376DB11F9C950B38B270E06C907FAA102AC76722325934755F53F3650B42D0FF293FA37086241C00E99B9C03FCE21F8D7555CFA93D09A0EAEE3733A8A5E4C45E74DD5EBFFD2F75EA60942BE34412BC82FC9959CFA155DC87FFA0AFFC1E7CA5057EE016B9751C16DF25610F1981A08B8E3352254AFA433E9B86D3CC13FE9B5B7FBDAD83CFA0FFE511E44412DFF1636BCBB49E9769FC52B302AFC7A96A3DFB233831007CFD6C302CCABC119DAD45EE63303DFA1F11C39C702AAAE00FCDCA913371F158BE5493A9B5C3B06AF66C8D5DE2BF9563FB617D1490FF6510971203DD25B27E1AFB289DF894396B8C26548BD53B320203AAF053B19CFC815C5D37E3115FD6CF8231B88FE4C330545F131A01124BB2487A3363B3E534BFD38B1D5138F8887EA63776D78783AC45675ED598617077AEAD86206B9FF61E3669C93C3C3A3A8F39E7848A88C0F94878E5D359C22BAE891FC7478BC8227FF320B047D0DFFC8218C1110136FA803EF6395E52DB8326CE8E3AA928CE42FBA04B1E7F1AC7B73296CBC1567090B9E92238859A87686D8E623B780F0376B8537F41B1BB102CC8C480C0B6C069F562468D4E1FE111B24D51F63E9BD38C47F35D8C2B5BE2E737274229974CC4CA63BD0E1F0446F6C4448EDB2498F2376EE26BDD8581242703715AD434E425908D61EAF865FAC5E82578EEB0525F54320B6C264F37DA36B55C2308D4FC6C7FB2F4D12A88CAFD93953193B7CC46804A0C464740B4972A71B7EAB5F6098FF78BDD452540AC5BAA894C10CD69A992217B422C88CC7849B4D8357D86234449B452AB4D49EDB1D2769512CF8A797F5FFF4E1E0A3FBDE292D91722D71322F0BD48C68A3CC998D03F7581EA7B5F5150E7AF58A076D09D103E9F64E61A2D375461007210DB511EA89FC4EEA75FFC71F7BF31400E7783F12F69A1EB5B7228952E2CD1D6FD57109237BDC024780006C229EAD71EBF4B543647FDD9216D98DC78B43CFEAE12166CDEDDE09B52BDCBFF089B1F7427EAECC21CCAF3FD5A35EE72C3107DF0670891E1AE12C1FB81581F3A45480F1FE06BECE6A494074FF3C47F90C961E371E8014707AB0FD004D19166140AF7B1C9D6B7E4B6826601AE104CE18E17939CF77C2A31F711D5C7D5126F4CB642178CE542973466696FAC1A0858ED62E4F2741E47B83B97DCF4610B1E4E262E700A06FDBFC6709BB1D4AFA7C20EFB72E0D623389DCCB049054CBBB322E63B09176E2903DBCE49083B01EB07F140D498B793E149573D8CA91DD2BBF8DEABAD9CECA0F896A7B306C22F8A761A65CE2BC1358A6ED07327AA0FF4C0B6E2906882A12C50D61D021A1316646461013D8169C4B54C61614CC9EDB2CE0AB0BAC96B36908BA3ABDF92D11D96EBBB9A60DA780AA58B804DC6F91E54D82068FE2FB10EC1FED54B794836F54503135A7F91921E2BBC2A61C99B6A0BDC04FBD2D4E7E430F16B5D3C7F06243517452BB7D2D51340BAF550D260A26A2F3B5451AD7D4E3A70CAF63F92E25D137C9E9B1433CAA5502DA269211F58AF2720FE3F899282C2C02B78E66D3302C5B9DC04B98197D3685EC4E6D4603D79B357282932689C2928361022E79C197A470212A69AC2BFC7505366CBB2BAB8D2E31314FFD77A04E85076D76948E836CF2A87918D43208CD856FFA33740FCAFFF9F690B2E6B33F1D89F65C71"""), TestUtils.hexDecode(""" -6AE10E0133138AE0D51C77B5667D4C9180E04D0935EB5F282E696BBE794C8B96EB6A21A232C9366518132BD8EDFA9AC38142BB9CDCBA77C729BC4D1127A13933DCD44630D3CC6D1CF0242355A0DE121D15D7D4618F501E509C4E0BA296BC956571AF19BA6C8C2A75110DB6ABC3E7C682E87EB280DC29066E5D45C5D318DC3F14396AD3EE29A772117429E28A7B423B54470508A48D67CB6395190855A0D92B30E71B34CF7F508658E7268A27E2545E6B79E48F7C69ACCB09DCABF5BC5CCDB8CA8CA8CAA2F2869773349C666583702F3BDF94C40204514DA2B43A91443B119EDB0B421100AA587CAF238A87F916281435AA6FBF00BF16AA7BAD080D60B35C53792C438CA39A4BDC72BD7CEFCCFD877F82AD557B176DD5C28E78563D1DE719EBEA1099718B0F4129A493C11CBB2378F989D18A97074A2E0F3338CCB9A8A36C1B3749E7A99E7A765C70E5D60386C71BD4CAB64BFDB815509166D5F55CB4A380C8CF24E6BBF61AF3FE7BA3529D84B11FCD6BA6E18B87121857B00A737B0F3D9665720C38BB54C09C8D3917C5AD646E3D01359724534BC1910AD174761D64AE6F796900655E0B13AA3EF2282DFDCFBFA5B0F6585D33455D7D86DC6BDD252B040B66EC6A03FDFB4C06E54C734145817A20C42E408E7571FFB9D6D258E585D5904BCD45D16CA6E44FDE9A25E06CD3645A302EF8F3589D897181450C178E4DA1663F2F5960B4755A0107CE43A265E6EB0C9C267929CFB1A93ED1881798E9B8A1D91CAC83E63537FE0182D022548B60CF0BA47B6A7F90CBE86E1E5D39101C0D2FB333A82E2E99E9E0C1AD46DF3FE876D144FCD3B1D78424C6C5CF0F6E0BCB447A6E9CC337481F5C14D4FB74D764FB38B8EAA511951A50F41A4CE248E13E4694704A0554853A0AAB9405E2C274A4FCF8B5928667DE041E668B17AC577173B0F4CE34363A7C2AC9C3E0A45A39A46F0248BF3D45DBA806A230DB1DC7B0BEE80EC18BA8F042BD6FEE173177FC0194124AEB21BB06FA079A1BC80758B347E4B129D69EC6E8416BD89062BACE16F2288076469237231B6FF4902FEAC3BA7D884DB747DA6371E792827017778E43708A421931115EAAD9E4CA316814904009F1CCD36763FC63038641BBC4F6F93235E16884F8A12F8D71621354B0AE4A9EED64DC5462917D4B35370AD9EC8057ECBE3A6221FE8C39B11444D4BFC380F1F4D5AD18091059AA5089E109181247DE78DFC231401A3D517E9DB655EBB914385BAC1B2888E3837FDB08A9E7AEC206406B848D045593BB837DFC41DC283CAA753D8CB64CEDA3041B2330BAEBA2F1450F646BE15E0B2A46578B1F54A73FA4DE57FA1D632F3FD410C0E8B17C11E197B7A17C522EAC6FBB78001DF9F96CC5F6116635D404AB454BF4450D536250B80E813C8F397E038590011C66C5164E05FBDE695482185F02C4B6B566BF3FA564E9232F40594AF96C96CAEF18CBEABB292BA546EED3A1AEC1476A8418B25DCE79F12D7B4F89303688539815E05F96BEB3B1818472C7E4DA7435652DEB5FA4277F2A810831F88098899FE2EEE35C1B0E6F74DF159D0631C5683C2D7B86390BCECC534CF69F3AF74FEE59EAB25B634333470A55CC49C28C7252B1CF4C293EF500589805FBE5CC056573A10F188A02D050AA34289A21D8B7D587C0A288114E47F346DA3772FCAC58CBAC669DA616C9976C56D87CC275AD463F2131DF95460A151123C964B01A2B908AEEEB7DB3E2FE12EBA46321D7A3FCAEBDEA0FE11B78605E3C8390486CA5D484E6C413847BCD8C6BA1B00BD2322BE537B173647BB63BEF929223C6AEA687F8ABCC4A8B81C44F0FE24588D2C40BF76590AF7157E2E4409804A28AFD25E36275C34A976D22213D457C162ED9274BF52E20842ABC94B2A1D6A4A3F9C2AC544060974DD687C2BB96AFDF8C27522C0C438E7E0DD4DAD7AD640A4B3ECF50CB6250C0A97FDDF15D8865421E490F84650144AC489AE7920C4941895D7B2F1911513E428127562F9446BB706FC06F07BC6C9922987A970D4FC21937BC09F072BEB132BDF8014281BE75BBE6F8C74E337EABAA16A064EBC956C188787CB34A83D5698438AD22CD4FC80781AA1B66E5A2AE0180B50B77FBC07EB6EA60246DAB074494CC9381F6011C2ECE64F97B2F5CDA92FE91B5533518A7DAC9828FB33ED428890A7FEBD0906095094576CFBA1048665782B07194839CB86719DC91EE8C2F64D4576605C2B55804299F314DE8571D0C58C78F071FE810B2FDCD3D7AF0C635303B6ED0774637B1E563855D54D2A1B0FEB5CBF84E693E512F59A13A20E5FBDB77510E3356CF211DB09CB471DD1043D9940DC1BB6A26CEFFCA03F48BABE03C15226EF29E0DEAB6108BDDEE6462884F8708E79709775AFFB39303D78BC51C8B9EAB5D91A56F8BD1518708EF243AED01A637F525E25F297E0FEDE03F3136EF23C4B33DC1D256CC92E3B6AE64C368542AAF553B1605C94C255012D605D1291098D1F0B855D137BE49D198CDD3EBA0A9D9E7519B8A5BFB4DC3F338219CEA7C97251166B5004CEEC23606421A8F9248359E5346594080FAD04EEC15C56FAC9D55EAF4C399B1FC8D68501B88002212FC0E36DCAF5016371696AEE5EBE4396C36137C535B13F09D490564D38D1E0FFDF13902F7678FD06EBF8E34E81BF712D918348728BE21965F5956EC8AB1F5A8D8276E6A72B4A69FB7C5AF658C5DEE4C8BE285ABAFFE0EF41529AD44B31EA310C3665F2EE61B5817C1191549DA070A2BD4BC790E283BF81C11EA05A6E4652823EB3FA05283E784C4143F4C029A6A7D485A1B892F7462CC26B1879B4668D133DCF6B9827D3A91E069B25DFC72EF00FBD6FBEE4970E26222D81874C748C746DC5564732CABCD0FD99983034E4F5523A43831ACC1E6F3989FDE186D4BD07E15CEECD8E68375A5EC130AD93C0837A27F5EC5810F6C87CFD8E37BE6117496F7C283AEA1DD30A5FE5AF6F8A94867A5A7B336B4070B1B5539608BE8D10BF765F6984FB2D0AF376A7DD4E5E25922078782B77C4E5D5E086669D265C6306CB40BA5755E6D83D93D33C89F548FABB20DABFE7086B9E658F4A8BC22C11C8A12A106C534EAEA38F46FFC84C2A4D96C5DFC31F6F21B3FA32F988FB86A38D7103ACBCE69C5D143C33D1186C1FCA80A13C642487D5B221DC76556249EC81E42AD4DFF51EF86F2ABC45274AACE72A79A7B985412A3E94C92CB824E3B54F328FD2F06B49DB12338284DCCB5E03D063CAB73B939FB59A569E4E693E53B446279281BEF3637B55FA1C77DB77A389F43CA7E00B8711B32F98C9FFB2FA30D66075DA836CB528CDAF3FCF65B6EE3C0355E05A46DD0DF6B3D71E8C705B6C14514A537627FFCAF805F8545A86865D9EC83B243BDD4A444D6E09A7F26F5C30D824C39C65E1596BD506F70E793CD5E703159736F7A7C1B1A08A88E348FE12D0D74A190EE4C8CF1E2FF44B9FF40A28DB611296835E251E8451068C1016A3EDA063242D1DF3DDADE57998C1FCBF7B9F988392916D4D405F82ED894AD693FEB4206E1131911E3617F5A5325701D01AACD591469026E10585C1A73ABDE7ECA706C97F48B125A8E101E55D0262334750AB98A8C4D33F98763684402C16BC7BEDF35AC349AB471E3EEFF92A79AE0F11F3CF17EA1406FB6DB669537CC0E46F0A7C42695C4595FA2F0E604F048357125EEB01AE824FFB63B70F10DA410EB93933398C13B485493E4DD5AC42744B00D2F81BDB3C7030C3DEA36BDA258AD26D4540D1FB83C7E651E31C0A2F7D06A328820D85321B24E4B798153885D80111D17811D5ABB97C69B24E3E82B44649CB8C5E828A3D532DC8EF2C317890BCDEB43571EEFD97780E68E03C1F751F5EB823D75965ED7714397112774934F465F61C25271F1AB2EE80BAAF7049D1E0C78EB59BBC3594202F002E883B7B579B98D0D4865ED783AA0ADC84A4A37E73C3CFDB5F464812AEFC6081EF899B5F4C9F903279E77D39B2DD0939329B3C5060990BF8E0BBA6CCFB6F7BECA77F48585F44F8CE7293D121335939E3AD785BC66AB2C9DC955941EE85DB9D2A4F404B3F45C7A68452E6AD108530A1FAB8E35C9EB0AC7F647DABE0E0D50358A007DB71B6D76B9922797F9CC377D675E70D9E166B750FF457A5D3D649153C81CC1B659ECF3656BD864FDDB3C430AD6FE44B21DF23D0827D56899D8F0544472298FF1E12FDA44466822409222063A8BC27A2C2DF44B1C4F56C47062E7D717705967F8C10E0F1A35B0C4F1EDB14B4E3A2ED44163651179FAADB643E602F2C92DC144FD96871AD3CD194BC83951F18C77B92518F8F3013BCBB49E57A4338FDCEE5000EFB89A3DC2177ABEB2DC34C094476A8844CF072A17FECC8E87F8C3D85B776972CDD5EA7F8ED6DF4A123197F78150A2E9CF2E3CF88617E82FBA29410168DC261EF9516AD01187ABA8E189D59DE5E243CB019E5B7C34F5BD158B5E11E9D7BC75BDFC71B040EBFAEEAEFB7639355AD3BDD27AB9DD799BEDFA24D2AC5566DE15F46CF601E08A702B133D391B0E236951AAB4BBA409C5B8C49EA0D1E2DD2EB9D6EC67F76D12571C002C1E3448FDFD0FD6D5C070E6B749E9C3E6A86DE347E34A72DD2B19C51F405B8A4F4DC04E7A7F3E0BFCB51EDD253EBCF47171E0F57E7DC04C0B1ED1054D06B7DD2E8E6FBEDBB16D086E1975676B0B3D34F3D290495051DD8EDB5C6FD727C8A460668FA7EDDBAA5AC776727EC2A155770B5C98297C45F192C5817C0942C62FD9FF9BBB5085F7B197AAF21173E1B2313FD94DAEFE9B76E068E8D6A46F25D6E81E09F34D0337F22086EB2F32D4917A6B5D685E3FB94D919BD8D513BAADC61643AFCFF3B1DDAE63FD0562C3F60228C951217142269183F4D9BF65F438D86739219161F9C6AEE0F65244E85758C0BF3B137B30536129FF7557E5C52F05AF64883FEDD419DF69DD8B9C9EA6D4A6B018CF676E91855B58B37120D84D3ED06C7173BC3BFC65FA01CA02A01E2893FEFC9E0E708506C84698BE652909F0F9793C443635A032CDEC61C5ABBC097997A62BF2894133BC991A19567C9F4549B30EF4C081FE2FC52724CEA974DC6CDCD4042D3118AFFA2A7EBAB82ACB14BE405FD6A764C8405CCCD0D1BE12410855BDF950747EB26E948C7FADFD2089D26824F7100FE574815B487865090CA8D8307D27276C8C5FE813A22636672026C72B81290AE9917FDD5A314029D02BC37EA1C39B592EECD57883952907C4A2A4203CFD6498C19328E55500BA395947B0CE523836ADD259F92C358026CA86169D73D17044AF5F4B7EB42348764488FFEB8D34237F17BA80D5AEE6F5DB8977898B2BEB745B065FC20DC567CB4090D65D82003B466C21921FCC13C6291CEF5B18E6F6F77B8E07FE9F803F40EB4A015A76E18C03B40CBB8C8095AAD7AE64B52D6A1AAA31EE00C5E4EBD04597377DFF1037A0B12D2585E8C2FF784659F3A57CEF7732CFE93DC4A7F11E5124273A656CA234AAA7503246EE53F430A79A0F9ADA4B6C0A5AD6DF6054883339C013FAA1B6BE863DADD11B5443B5E4686C5CA6CC2BC43415A116D2B908F8949FB594A470B2D6017FAD537F066B8F2BF20AD2F376B33633F90BCB9D262EB23B399E8CC8D7632E17B49C4792B2217BBC020635CE2ABE63B1039463C7D069B2B004D0CB650CB917311A049B97560768EC46A793F19FEC3ECBF9493AE80D16FE24F00953348E522E28B2668FE430454AAAD914C385490786CA7D98E6A1CB345ACD0A67A6B57A175D8A51C2B51F8763861B027D29181655D5548E2B15986DD3835404A9A282DE523A045E5DF42FF092144ED9392D589DE70678FBDCACCE10C956AE96987A266AD001EE70422549F7F27BD92748CC06E7D24483CE0B83C3F2067D522E789D849250E7F7588A2DB9BA9D5F439D9369F04CE59A12474CB5FDFB08C2AD9E0889CB0F2056A7170428778D3BEC8F9084072D6C0FAA922400D8239119E44BD7266A43C55A70CFE0984F60A482D08F9E77426AA875AB50748161B48390A43DFF04534054C2A2D5E4A84C804C03128A0D7134BD3AB8E0A2BC7753F458A38B9B244FB654F9DA3C2784CCE6958DE3DC806DDDD84A8D2AA24A8382AF4D11E52E1F47733FF61B79895A9AA426BD060B4761EE687F1134A23EEC3EA828134C4B8108A6C5B9E3AE6913E955299DFBCE6488FE32036662FFB0CD451A98D97A1538F5BC34D527ACB9CE6D1DFB5862FA889422FF32319E35AB53102E566C710D4884BC3357280112F2C694D957D26BD3372D99CDFD00CF55098238994610D18A247BBA60650EC3AD7FCDB208B15C4AFD35A25735844D66A929037EAE673D66159185E4B2B79B48746BD9F046BA5828595CC6820EB8A860EC9C458E7AB183489C3ADA179C40A386B1F33F2D41C8B1AA5D571D1E7088B0ED0372C95824E870D63A4B95D87222C121766B270A3F5523BB6B69284B676C81F20D0F37418FB0B40240414E95B7CCD6E110658CC41F343F4F56BAD2D31A495D6BB2E9141E374AA7B2B8EFFA3E41434B4C4E6385BD0000000000000000000000000000000000060D161A2228313A""") +a7a908a5bd14b14de2439fdbaba72b5ee9bd54df9c52b17b2e3561949f4739205c112010edf1acd95513c740e1a23beab2269f5db9b432bbbee5db53bddc1fd355d8ee23f018cdf3108404b0d1ddd3b815dfa8b1c724bfc8f9e0c0e610a8b1260ae33ed202e1e270cb27755f10404dd66d3d32c530aed7963b5ae36aa4c1d0ef442b149b71a0756c9e016b7ff63fb4ed25c59edb578d01a0dcf04935a4b5609f4018a32d18f9a59f0edc0d2e90bd7e0ae75b5402652dfa30cc0938c7e35b3666093157f1c2f6ad80024539443557db996783056c63730cfa60c46c86b79ce446e2e66d2b279c192cb4773409fb8cb918e363220c0c1ed95e9a7524d0c0ac53c172eb3fe311b14d16c2460d0e583aa3ce251057b5ca59fee59f72627fb3b1c8e74a8920f10ee9f96a080d6f0a143fdf029c71f20451757b2519fe0c10e006134a2ef8d51cff472dfa63f934e13fa2d9f9705092712bca99be482313668f52a5e996a59511ab9bed2a7a4ec0ec1f17a3df944d4222b32e7c4826cdeb3abdbf325f7f9c76f5b7de28b1d5208ce9e19e853b90c9c7e2a26cd1590152fb61ae4fe56238b5e52fdaa6a17afbe5078d4af5403b620acc4942d01a432849fb5a6bc19bac30efed04e629d3caa74fb0d7c2873a3609c0b6f8c41d88d394bce13f3a144f0fb3d60a5ed31225badb206848c13c156a2b7be5d9df517d5d71ea3b578f90cc85fa72c3057442c95571dd20c9c9b1424566a408f6e135d74728b4b1aa1918aa38dd2108346a3189f54c9ee83684b1630a29a69d6280e47099ef989c3907b95fa9c1119152d97f9d9181fe2bb89759987a7dc16556223bb0738d1a10ad7959270bb737fc7601f2552a322181e1730228c4f0889cf196bb570002cc439ddb83bbea27f5ad9db5e62ef69290368544e271dad0e880a032a188cf4ae1b290f6576ea5c20ff9ac3b3950566fb8081768a4bd804c22539684572105505d2d2507308e5e50d05ddf24655089c2cfa4185265737894310f66d29551e842e9df5dc36d2e1a894d10504099511c68a0a81900c70fc6c2b32e84587d6e4654c97ada0ac1b7493a8efb756a4aa0278b773cd302f0746a6a18e3b1aea24ffcb32a57844955bab9abb85076ebbc568b4c5ecc898f9a1d9e65c6852c64a1995733420e0ba5a61329b191e750e212a68ee37717ca8961593f146e0093d1b70f07cca6b6f2805f48e66c1b3d6405ae5f6a95fe27d427482fcc5bbbc2c5e0e0449c73eadbdc261ee9636bfdea73a13c0a9ad432b4b7037432c799cff8051a331b261028739bfcb17544732bea4c2c3ec1d42685d007740bf49d8f8caa8bc31c7e59f9ca033f27eeb57f03af68b8ca30a27f78c06dd3a7f821f58579353c325982273415975b03cd8649c9632374f25bf010aa1c0bb82eabba168c3e2ed17213734718cff337eafe9e48b6ab79655e98a38bb1f74519aa07ad10529370ea2581f99c59a824a5ee0747fb6bce34396514a6a3dc4755e913304a28f4bf4019a42acda382a7a7211a30b2878264c4266043cbdbe2c711fd0da53106b0b5b16e78bcd1a075b253c98cb0aa9b980af82425751a7192e42f5057d5e5e71a2d0dcc9404035e63a905133c7724ffa110c942c54e8970dcbcf99fe1987931a5fc14e83b731aad5f2ec0a29f6872e43f18a94f5f9f11e2b7508ebe29a803fe159aabe2cdc242a6ffe976044feedd0b5826c129dec3c05764451feb8b99953a635e7250e74772da18755e819be7db6560b5ebe2de9eac9fdd490a6aaeff8bf568a38f70bd0ca443d336ae6776212e0d99593f4123d91dff7ef68222d497d1799ebe6decd2f7acc6c363e43dfdf9f72b88c25e9bf740cd1207421b476ec3b68843cdd285e292986409aa4ef04ce4b6479c95e52ccc8b5b0247afb94f43af536ad9ee79b58b636afa64a2be3fb22fd128f1f1f05b949921bb050892ed61cbcdf66b11ec042eaac3765d7aa524c0cb022d386032ed7449262529d2a6eb8c5a7a539deb3d1db814f0284e9dee64661f8cf3906a9802efb7fb5c4033502eeccdafd77a6d0f6ecbbbd39aa21f14afc3ec5def48b48afcf5ec99acefeb3007a90a54da935eb5d4aaa68502b1c469acb166646a3af67fdbb51d1338085d2798174db7ce74f2ea9c61a50a6fbb718dbf62ac33dcb7fa80aa982924f4310adbc07b2b672438c837d1c58eb8b9093229cab0d6047091b4152a75beffe7b17e44989dbef1c68feacf11a47d9dcbb230b9b180f9a7d10036ccad63454f3da00537078db225cb746466f1d56df35fd9380620e37f4692aa0b9b5bb1784a4cb80a53a25bd9cbd7ffd2d3177ac7023ebd1127adc732ef7d4963f70b130af5c33a824c3b7ed6d2e1bbced1959560cb753917781af33478ffb947488c8372d227e5efc9f5db11bb010c278cb40ead48ae49b2df5f927363a9e78bc125072929ef80efee18c7592271393b6f29cd1e339e512b1214fc5757b1ddf0bd1b9742a0a11ce469a78866b24035d8499c42be66110a624c928641e59078bd1cf6771c7446bd1977578c165695c4d6aa4ba9383ecd2c41677c3c5cf9af096f4c8c9f5f244e5395ef1db825d2593554c7c741ff0e0540f0ec897a1d8cd88d2f86a1aa21e5473b1fd21a8065d49d682d4dce206f4b511f4d466a56be1bd99d1335b17f4170a08899c2015e687f1caf70140770dddc885cac8c29dffa7d5df823b3b8d64e96008f5aed8d52ed710375e34a7743a98f714dbfaf70e78b177156634c0ae931f5082d2c6b7e8d7b1f025802ad9f74c711e218955938b14fec5d0983bd2f44d9288edb72bd1eb41839297ba5915e518a1e57e28a4ef8eadbc6ac4e14b4f61ff5834b1fc6f21a8065f7e84cd99e1d86cc9fb8582fd40eb4f1f1f4e05161cba9e54c823e77f882cdabd8ec501be12e855e0f492fe572311a01e2aa73c9c0c0ef43df7256ce9a41502e15d7fc76a3786dfc2812ba4451ee9a4d159d1052e0fcac791df2027258c5f0ef51d23498d0ef333c59eaba21765783f7fe51db331be068ec4e3e779eb5cd47e036a5bfb6634dae1e4fc719636a3e4944b64af890b1ec70f89b73b33b626d5b3f4c33e45ffae3472929818e1de7eae0f0135937f4e065b2b1dd045ba8372820a294d4a4c9d44af6e321ff565c69ffe8babd43d095509163bbf8a503ec55588ac3c58074a96f3e32499a6845387f9f8b4520cdd3ad129165501d28b68339c1b0b43dd1dac6d02fa89b3c381373a94c1a59ef4839a671b7fcd08c61cb12b6c66edb631988fdead1a818f843f070a66ec46523f8879d43c98e3a4884c8683f9eb73a4d186fb43a343165202bbe8e1735749b64c9ee36f062f2f8129e227ef8d38a7f35677b01f68162d9c5310aec1a8f8ab1365546ae313c90be351030641004c735c2ffb07d7edfdd7434ba984790cc7c3c843c23531593caf985d63c4eef255962825a44a2c9a5c73d1878b6e149fa754a46b77239539851b2adaa293dc29cac659a0d0840bc545401984682144d7b651b125dcbc3ac272edd7e8805e086e7e33e2367beeee06458dd2dd80deb7e36ae6f9d10f84459a9b828aca738136f2dfdec4dddb3dc6c0ca72e2bf19b5b87ed28ff661de8ae64d7dcbfb71f17f362897e12e94f3197e58b2d62eb849a169524ab78962b25288f87321a753241b123b2aee98e60e2ad7341d8e1796a160932c51ab8c6a0c97b188ab05dab278cb64f025a42ff8e40a424858f7e56b27d0eb08746def560c8dfd11bc359b8afb1a3b922bd34dd1f4588572d26401074e4ef4f37500d39456e458b6a9f30b94003fd110987ecec56629a013245b48be1f8df1b2ad80b3097552841186ee787be2e8ebd555253f59e12c255db9967f8f506746b8fa49203e4b2bb48d04bc117338c40a6badaad1bf8f100b8420aff9231d20bdb2e78ce173b12a87c83f0b594ee7225d4d0b975a60ad615f8a21f3a4abf819bad041fd01c740233cbed5e690e6061998af1f0fa406862025feddd62ee72ef314eb3b12d40227d92de05a960cfe96707f9c9fe8d51728fc8258531ad38cb8206d978283436f6b7aea2282cf63b27b639c78abdaa21be576a55388febd14807625391dbb8689896d08ca7d41d28d6cd342426dbcec96d6d44e78739818a757a94f615cfed9134e38c4d34569242c51b8992aa6419c24b4a80c9593ff77d8bc840e6bc7328b69a95354606602f0f8f13d480166c4c69fb5c74fe5874ec7d98a9170f47096fab89d9ada1285aa2ffcc968ba5dab962248471b2de8ac7126988362b845127bee0edadac224e552b0bd83f0a0d9439bf24de27d54243f8106b5e95716d835a7813fe504f195b6f2d28e12dc041f50e31858cc79ed3a143d9c7f4fc8badcfc3a8b756150168ec302ede64999450b0359b368e3acf00bbc9608aea9c5714dda27888d63f60830cfa1ce2b224b854136a204dbed8e034cb5c77f9b86ea2d342bf3a0b37a2fe3978e4a9c7d881655014bb23d8617ff04f6bdf39c01da6a324ac58805396ad35733e42629ef4ceaf840fc83ccdb66e96c6e148256059e3b9eb1e8de429c77f8fff51bc994fe35900059b044c1ef5b336031f3b67d3bd471db0b7c8138b36ece1f56101e9298d7f222fa9f48b9f195f1dd87a869bf8cd0810e424b82cf6841e686f91fa3c443c7e7e547f7b920b774207212de69e7e4ac8d79b45d076b82d8d8d78c9c55aa6f57a7fbfa48e03005bb65fce5548f3fe6ba2af580f5881ff739a098f7c5841e4f1351c5afb3258c39bb39f96e751c043c98b46f218b44aeb90947d291cf6042aecf045cb51fcd687769eb88f07099d3718de8a836f7af203028a5560544f170099475f374f8cd296e4daaf3963d3ac620966584659600233838d0c5c62796df7085b19d42982315cde7335f73178cecd12708124004b937fe29ee2b72fc91b94e2a6a433b2a35449bbe0bae6b866e1a10b4021357e7dabc76c6b9eebf238473e953abcedffb63b4dcf4f73dc21a2beae5036cfec91e22dba6470d2ce404a7b22883b8735567dca179df3d908a725e2e5af4201b6be97f11e9dd58ec44256e2fc223156a07040bb3008aa633a70c76879a4311918a748c98c9f2e485ad45b90b9a59defbfe2741b96904f1619ae66a70180a1c3b550cb2fab06f80d4fd2ec44cfc09ed26da85163f7c51e8357ea149774b77c41a11dca2b70ea2a6f82375f61a4e1815cd019220a8ce7a24b6f94eb3aabab0241c8c585c1d35422268a3c9bb9ef43d3a3490bb231fab37a466723ee47366d71f6131f52dcdb19768a911ae8d9b11e31c946e0a663171d53ec51688603bdea9d2830bc87ebe860c8f7bc1ee1d18980f95ded0b462764d840b70d4dba5e022110993cbf58888ae3bd6dff8f4b2e1acf367df31d03375e45379e33defb73b2a605f402d364d8b9f7e48223c979239ed5b2b9707555a698bffb93200ba565b38453c9452186300ecebb1294db3a092b3ea1ff78ee1bc1f85a51f50d1fca7ca0d634a027ea705ec6cbc10ce51fa13afa4e7e756eed9d19e9c0b8a9daa9f00b11d2248ef3dd74bd01ae7a93ea2ad16fd0f0a8321a67d39b07eb49418f475513075082fd9e0fddb7d225d064d354c2b3f57343220211cfce889e69149b5db154054dde2736df5efc993e743ac1445e676d6401b5039834fe10c49011e3f03bcae6cfc3eb2ecb8f8055d6a17de626ce8caf8d8061f7addb6fc9c229a2b3152bb17e6c40ce3ff89acee7fb5ec800fd18ad698306e2c25146f22aaa62aef8e054ae7730d2dc0477c51b0efe2148ffd7daea402118658bbe0cf265e29a046258d3b3977b0305d30bb496e24e0ed6d997b235c310f36f4cc884abf0fe62b6fd3f164914e6d78c6d4abc9d130a442163b4f2b3234286ab7b361ad062c6d6d4a2908e3033ae5db787717a6a4abbd5975faa48ad91738d0b29f50ae36d0712fcb86ed1820d9bea175e295c0e9213be5226414718842d3539d7eedd89d6459eb50cc34a058b8b453d38890d76893be1de65d6d2cc8d23156e2a414073aebea846bc157a92feee6f6a256fcf4346ea061041774103be4161229c079c5a529e3f375256f9731a60d7c106aea032927baf6b3991c2bfb69433a3f21bdb0271132eb43e027b404cd9a882798995351facc5acea7b2b006b649fd1cdf6628fdca1e4fbbc71006743ac2767501b2116567b911deedf5936175edc26a65a6fcb29dabbc3f8db466a21a08fc34267c557e6371f23b7ab7f698565d9161b0a658cdd82278c7c0f9728f5a63d821260d2b33428f728bfdc32e3f3d3050d2b87e19dfc9603363b2718c039751746396eed60cb7fcf3f7b965503d6ebab7e04faab921a143c37b8fd68260f3f4e6e0ee396876c2df262e5f55d145e410294d1da139ecf80c792e12f121862b6edf6cc5a9de9403a0d141a1d4eb8ca2e8aabb6babc44cad5fd4d647ea147d00e122633575f94b2d0f10a1e34570b0c2232505e7a898bb4bbcf0000000000000000000000000000000000000000000000000000070d111517212531""") ), new SigGenTestCase( TestUtils.hexDecode(""" -6639A514256A8CA2D510FCACD916BDEC6245D3AC11A035B7C7095BA4DBB92C62A8D0C518807AD496B31228F96E1A2A23096EEABA09D37E615E24E5965E1073DD0192B175684B4F326189549EE36FE38AB2CB29380675306AF7FEB99B2BB8A07D5BDAA761EB9409F46E70EAE199F0B3A72568BF6964E6A58DDC6CC223FC89E27C104004C328694148109306900C0085913042D4B211E2922D60A80C91008512101118C04492344863824C81C20DC8200819C051640444C10470E42286618424149040C2344292161009400ED0203012B10991A404A4B24011A848191800DA128D83803003182C03A5201B4066D9462102442484880C09A20C1047689B140914B70C84B068D4282823885081128222326CA24882024150A4B04C44264059320498926924496950C0841910840C136E1AA10954A2889006864222665C026122304A20A36D12486181306992368509304A1416210B064EA3320403014D918885012051023701101411D33840E4206CC8A888582484444486D8A06C03C6499AA67140804518216024850001896522483222932D18052922344954900DA49890233351C434852025420B230122044D9A26604B266E8430011A2889C120240819461AB76503B50554B2605AB429091591E2122E1A320EE43808C8880D4AA264D3960042C06C24C92959C024A220208C942152B06513286D11B440DAB20104B84804A50D088650A4386049988488A28108490A81328442388EE440021BC811A1B204A1482E13B2842007501B288A24A9092109629BB465002966C44682D140459BA8400381108BC8051B826820466C40301111C77140C89112394444B60020992901178D624202549405D1320502872D02164598104249A0114A182ACB3802D0944552A441C11641C986255AB864D1184EE4B44D821224E3086A0CA30C5A18100BB3900C022C194780DC126264248801B9880A265110272C142025C4328659124423262D0BB590E28090A2385010042103876D61284618C38D08A10D922684D906501A33611B8468098830E3844C0A4424222640CC388A1C05110B460A24004C02132408067224C4611AA62409358AA4C6112322629C464E20964D580430CB388603B44C64C42C0000095A220DD206655040415A2864102510C4300E24A46DCCB28D89180D1407714AB8451413409B323011396C5882005890911293081122850BB94012050018C905C3248520B34D08964003852D8C220D109270D8464ADC34301424840CA480522282D1346D8CC810D4000C22850491B224D84688C084450AC30C1987111803618CA6644A384D09C8012092040301121A4722C1844823A1858AB24DCAA841A4160E8B34889C249280208849A0851C46290B1260D804604B4451C1C2911C0729013381E2C44019962062C28CE39220031824234202C24006C82264483466D2B630DC90880199054C242804424A5B0628D3866C1200896424492025050AC680192921E088812413204988448A368C20A36519006C00410E23304A18A04C0CB96C8A46210194105B82251B05840A15840A185059420E93C289D04611CB0242118100004606A4C28D1145114C186A922260093921A4941154C669534625898208C0080E4848061197411AA36CDAA80C0890655A2284DC380823A44CD04680011370C2840C8092249B1648C134801401445888215B4620A1A84D0BA04D4006061CA769D9380C1AB78D0019669212911C020E91A0909232515C224D243662113242CA081104A950E4C02020C069E3242E0C3109E4188518427261B84C840422A036605B1486120022D29881A3900542480613A54914228D4CC44D1B112994403112C6894C06665A384411499083904864C82D8B002DA3142CA2320261303044342CA2322E83464A923885C424690CC60C0926528844300416600C0741D0126244980888228CC214704B9069C1C84CE484440093449A226108850102C2212342282234650046698938660B371160840D58120C09102110B4451847480C434D1B33111C990459480D90260C0B464259B82C9A200D4416062139310BC38188120508806113396604318D8A928509372698380E21C925000384CC4228933031D2982C5332461BC10D5894451A47118490691B386083482D0A8921D8B82941928120156AD212414A90250C248202310DE1346950807101106864808004A5604488712216244FCA3DC070EAFADBB8E253BE1E85890557BA06F6FE596C9EFA6CADB19A6FF51D64B2F169E1FCAAA7761B8E4E94A6DDA9B390A96D7C0BD5AB3282F4F4E310FF1A7745741B15A80D1DB35B18090B1C35467939147179082650854D3481AC46C4D5F372ECACF58B439D2C8E9BE32AF5F647C4D1C8C06C5FBF01D95D35E4D7EB2D0D0FBA5B152CF08525006714C6A1DCC41281FEA9C16F1950B66DF989AD4671296C9BA6E565227A47EE10536BCCE94ED83E57092ADA82578FF23FE0C01268FEEDCC0953EEBEE12BE828BE36415712733E973D6A984747296AD5D24CB48002483869BEC1AB4AD0487BC6AA09CE9138577A5CFFAFE08119E3142803CE2C88D83CC9A102560B8A2BD01684F0C7FA1480421F4372F88CE04C3BDEB9A09FD541C17C67BF4D06781B6B8AB45A7C1DAF153B5CA37C1736A12B7999E05D213A2501AA67ECE2B92710749BBC902E550C33FD2A265CED7D3A88A961503E8C4A586867A9A2AC605849FCA19DDB92ACF22D481FE8A16B6BEA0E916119A83B8826B7B64EBDB9A8D7F5517A8812B9369EF1AF29818940FF4C1A41A8193BEE2685866B887E48DADC162929938202BBDA46D7FE090A185883192E45464E88026AD24C12B37FADFFC15956F0A2BC1AB5E4917EDC664D3B35E3C9E2CE2A73E9CF319AAE5A1EA8161B747989D2269B80E82086B677D417FACA39B64DE63AF8DEC028ED2713E7EA645A9367DBD8A4BF6E52BD45082712BD30A12D639DFF1069EB150941EB3204FB5F7D12C655F22594A70AABC428131168179AFD776579865A2BF65988276B9337B553EF75BCDB793B67FB602583A879747CE0169B72E2181C6BC1569A7353BF0476F7DCC04F7410F1C94C6C1E164E2ED651E90A3288EF61DC18B89BD8746C0491F680EAABDC51B68139E8EA42ED4CEC08CD60093D18EF38E26B1615789EE6206F8996B34EEC3773C098D61C0B4E4ACD835C98C16B0F3DD0A8145E1A74889297FDAF7FF20519A6184013E9773BACDE0705496D3B4103E5240759EDB954C9E77A05B20E4833F446F4CC447CF862778E97A388312D7AD5E0D2626B298BEAB7D27F5CA67EB73F3CDB03ED0239912590C787F9C3F4B04B170C6582DF1FA489C7F8FF48E78C3AB63EEB5CA0CAD4BA17AD57EB6181FABCE3D00D31602FC3ABDB1231EA961A5F64558D2678F963E603343FE35B4B97B60E102B95BCE07BA525F4122692A28F891A77A87F07C6444AE92C621875CCB9A973961C55D920BACE5050C42938B6FB81663DEA18FAE1625B13FA3225CC80FE23D557C35619214E140A55CE2ABE8BE2D82122BDD702B5263498B9C2957CD3B2D933F3C62A0696A0CC96D99BC106872F0E2B6E70BF9429530ED9B97E68C4ED660456D7A79E37622C0C854187985C9928850A15FCAEAB8D8D9A3A7CCA7C13C400458DB650B0B37C858F52B04FF135B6BAF86E4D91DBDFFBFD6CA957B3E1CBB1381AF4118D9FA13B70692030AB19C8D068ED620D8E7E150236B8B988C38B6D4002A3B4FD078F58B96A3C4A996A13F0C6190F783C6E6AADB8D69BA275D7045E1646C56C8024F8D1CDA3EBCDC42877674E480A070BC26C118504525595F034B4485CBB9C4C48E5B5AC4A250EE8A98A8D0448B5581F9AA1F92BCC10199A0A63AE5AAF39D6C2F82D64E6165C9878B3FDF4F3403ADA84A57202B94F4B65B4EFB551477FAC6338DEA7281962698CC54110B8F15D4BEB4C091B845306024445EE008933A8FFBE63AE3580E098A18FE33681D926D46AA99F5DCD9E9C6AF4CB2737036BE094EF63C0310A42DE5CCBCFC75AE57EDF5DEF3304BFD6854405781FA983BA2B582B631E4773A62CF8E3B222F9FB0C484653E7DC89851C989F62596377E35BA2A05F544D6C2AA1FFB71365BE259FA6AFDBB797D70C2E40474C2697A510E9C277133B26C2ABC03786589859134F5719314F392093125F15EC2334A2833BA6F4E634DE374AE5EE93E7C6FF37D978117122A19F5522E63D637E6109BBB80C95AA807B205B78821DE56BFD0BA9949BBF0A58E2D3803B89AC37DF91955536C5381D81377AE430C261992EF2501AB8FD653D715C93F63A98C7A00667AD74DE5548B685BAA6D301D4C6BD9E40F7B50434D8E88AFA19F73986CF55E5F318BC5264F909F8DCE692637FC09F62E9CFF2AE21FBF37698736557ACADB9E782B6E60A214216FEA674815507A12933B0A9DF9165180579072283F7351FD9696B1C7EF7713845B3EA3F618A0E52ED23273484EF1307E7082818903C5AE7A5EF2F11E5D1E813B8B2796D2E134C43EA733DEA8EC94CA03E64B0C06D7A52C38FD63658F549E49872BADB78020B9DD64055EF006D5D92FC0642EBBB025C44F436B9586C9453FDD9DF65B94ED020A5F647717881470C0C27C266AB56C3115E4336633E492893DC34359732740E954B74606232D2F6E988CE1FE565527395CDBF66F1CA04F42B34DDA2937857589E3DB5FAAE2B0CC97A68408B2D73089AD0098CBC66F03BEB12FF72A00AD72C5150BEB7760D700D634A0823988D20BBE9237B9E1E60737CFC7A97CA65AE467026E3664D2D2242E73C3D43AF26D33828358670BFB69A3480CC4483114FF22D93B452578CDEC1B93C732910438B66E30CEB14EF03CD044EB6D51E5AE1242EC49F176A4D888DCDBC6036163160D404B5B17F194BEC4A1A8FFE396B6A1E3500D2C1B17CC8CCA3F105A397D62B4462D3C09638B01B6A60AE76D93A4D7A204F8CD381C7ABB9C06F9B4F835D89A69A5F0424052C19D5AB4FED48B4CE549976F68BE60C54BBD5CD80E8A0DBF80A75A961332ADC8377CF2A286068B8E4C7F9BF85B2FFBC9FF2B9307BFE33070764C49EE7B2DA597BAA459C4C0C1D5BDA7DA4EDF5DF2ADE76F44A2C64576CAC913BBA0059027E98666DC03610189BD709BFE88F0AC93224DEF65D86FEB422563A83BA823F9F312CD13A7707275E3701369CB009EDBF95E966DB3DB9645F493852DD1F71B025102D2B5CBE6DC315DB57D4E47C9FFC1B65E0CFDA0FAFE7937459DEDBB5983FF57ECF7E1D38E9B67A0CEB91FD7CE01DAB9FA9CFF2A4DCB19C8F74A4DE51DF1D466A44FABFADED4CDA52FBA424B312A873D29DC420F8FF3C94DA1C896E0D54F8C882BAB83573716DEADC439904093EFB720A1120A7CD9E18DEE7B6674466737C36948A4EA961AD122E3C461FE6D5A3843262A3845CBC97E37EF41BA9274D0EE4E77CAC71DE5AA39E860959E353AC28D1A545BCDF977BB4BB7BCDED646BEED12A6E03ECDBD2FC3C1D845D5C9299882D15A295AD1D39888EC943216CC0175AFCC605938A2F72EA01F1B7BA77A954FE1CDE49A7B7E224D1807E81BD09634346DE0ABA64C0F5B3D2E6A9C47C497D28CD231A70347DC9B9713E1FE77CF42DE2AFECDFE081395AE1E2198E2C8D5FC05606D648F18D3B5E0D96BA194C1D9E4985506F6A96C48F1CA647D478EEDAE301E86DA2D916A41832D28A6315A2B95381632A3CFCE232621C8477680D4DC096A57163E4B570DC6AA475577A60166AB550437AEBD5810B523E4053AAFCA5D5F702F26C6FEFB18637B23606568C43AD1047AAA51E84178814319C6FE2CDA8128B7156F84ABF9D11D201390283801BBB87FC2AB6B050539D1DF5511893F809CA261303C54A7C8BF4D433E330ADFD495E3D36D61D469BACAE8F1F8814777B3D20B4F98EE5727C1826CFBFBA2E5BC624C4ADBC32519B731A666EC67D082570B1739066312284C1F560A9CE45EE0E576F5269EC5C325667D13C3A62EFBF24236A0598F973CA99C53DA3E5D4130FF8F4791E5A900B0B2FC93364B234F85926BDA82286AA1B04A2EE280357CB6D2A464E8DFE9AD6780BB2A6937F008DCDB8B64A904E9CAF6B75A4A3341D068381D6C8646992A7AFFC4C2749940FC7A51D4C7195F291F8A1E3C4E0C7AC189669269036A2996B9A7A1D696C35CEB82DEF7B4C19151E1DD8AC8706E38FFB945907D2D825B06F65EB460A5F51CC9B17310FB878D73A436788DDB87978BADE32BDDA761EDB2CABBF9D44B9E7112BD8D158B502AA34F7326244E2FF83C778B5AB05C2A8CAFA7E218EA97045C658152A21D8015B4A62B27ECB39B72CCAD51F52D3F323EF61F35304BF52FF7940642C38A0643181A6DC6042F8E4D87BBF40D04770899AE2165B39C2ABE3D00E41311FB1B3DD865567F9C60F5FD03AFEEFAA9EC299B50C1F378EBBA3700DF56C4EE64548C29A6ED299B8392DA122204FCB5CB990E898379DC6CFE26B6C37FA4F25066BFF6E296D1EDBDF8578A5E939CFB07EF8D5040DD3F46AA3152D5CD76285F9F864664E465FA66E338CCA55557467D6E7B443478CA00900A6E14FB8C7FE7F27984153A3A1CF070E91C8E520D1F6DC0D627AC966D6AE8B3B10B61BA99F642C0945174E3D62A3448A0F90C3B1F7104409FEFC05286B4AEC3BC389698D500E199F70F8374AFA60D2B4F83A22813F8121FD99E37BF310733F61635E4690B0C6D0498563287FFA83F2D677906A4CB0630CE3A768FA827125B8E37A5F5C855192762B8ABDB0DE0C94538E441620CA1B3F24425B37F7C13A9A55EF08117B8E5D2624A670473741449647E2997BB4F7A1E08A2D58ADA29E80F453C271BE545F2939E2F95342131C2C9C3E4FCD52C24F25D3D3C6B040BDF0B8BB0FF47B0E4A6EA11A3F3B10B68E4F2225D5A5E4946E6033926EA55A21531F7C344B06E42B49908C8F3D43439E949FA1"""), +a12619d8176840867fd76c85b14a43f92b39487e19dc0bc5078a6ad5bb20ca92ace50ce68a6bb9ba3da7e58c2a40ad87729bf63ac51a2d4a58b9481279ed7d7a4e6fa5cb2f0e044555d05a83176c203f85d02157a149565b329a18d0963ffc378d02874aa78fb009073a6bb453d992a240eb7ef84149d000acfc8fe56af5be9390062e082991432664122412a2822114b6810bb581cab4650049894c824892824c8228020a3472909271cc28208a462a0833129828301c83401ab2849a48322097055a3628a028488c285194824d624282480206042281428624e49265822440e1084a5b42015c183163228192b4295ab82983b63101816d490004d4480e8184858cc805e4c089c9a05122348ac4b26801a9480a2902cb9829db108623230250488e439461d4204a9028699b960588286c94200c089484d3a864018604540811c8a449a12001e1c46d002106d1248d0c36848200819038210220128926280341495ca66c20b9880a1224dca6911827059892514c16919a06000a090d13128254140892406c11a76452c27054164408440051449289020020017209178d0ba801602869240865ca8464ca44652022218b082859c210219120c1b24c594441832660c30611e4326c53c40d50340dd31405634852e08409c218514aa021110366d022715b80050815708aa401e4302114b68541b004e1002e0103200402601a252858a22c8430685bc27001096511050699482ee03424880440daa42163062d944011d8328922a9310235210a484a54c02481c8681bb825e2448624c821e0384e1b150c8a168681c80402922981046d62444d8c08600c0904d0b245c092480aa930201810421028cc886992c870da00081423601812481b3322892652409884548285524089a136292326402028681001309018429910405a484d114692240860d1861108122d53b211c2c24c24c42019214da3c4500c2410e1262241a450413492214665d94091d22840d9c84d580426dc8650caa68412282a01a71188464a84a46021c38d0c390a8b081222846c1cc48444228642120accb26493328adaa41001154a94108e891406a412458c9680a0082260b208813882e24011244011000464482612113064622872e0068493004523012218b40408318d584280e31844418891c2228208098d1ab7852244804346261342861b36094c046c62040219362911026d24c6094834521a878513208a141065d34211e2486e884860003305db340492201008a12864446501936c50880c1b324c0cb4809b3086810224d48221d0b2844c020813478e0b874051342d238969db148124a4884380701c104924002913174223a5404326111c3382894465e410304c3829242610433690a1c8900cb4241933855b9490140364198949090269c2c04004978d22100e0cb8881c003193240c11022ae4a225e1002a62200dcb0821c9064d80104018a70c5024224182708382285aa4448c044a09160d48a42942442a04092a03174213059158b85040006a112724011726a1464dc9c605c0807012430ca4106400a245e2804008282cd4b20c58208688922824472893b829243520891812d3880ce24288e1888891462d82925050962d12448809954062c648081006132270211549d8806520431111c48c82b8085248210417451a94458cb86589882c9bc6488c206cd346828c0490522885a2460c1b08258018818c1262d9108e41a80523b7719ca40c1202425816724c4610038068144308082431500411193861a4306e14026ec49445a3a489e1125221141013b8800287311aa6701a398423a56de2142619032ac3266953281153066a90b66462028444b290ca04860a312e9cb2300a492080162d5122908c180204274220084cd3141151262d1807840b3608448824c3840d1ba2088c822008a2891ab62414c81064908012c6492093284b02615cb82d4094109a3060dc220064c86c8ab45123348da3022d00c830a3126a044668e1240619b9642328680bb105922809db302450180a209188801062a3b8116298319a266263288a11892d41289283844918c82410c1111114220bc88904859191286a143148a4828c51c480c4042659365001862422870c5a969119308d00a665e13830ca384910a00c0c923153c685d2c410499465a3866441801013262e6316000c49811c160211b92cd0c0497cda1a2038e94cc9434a919eb67de0c9982db1508cbb8471e4c0a2409980bdd2c41d4ada62f2f6a8a783ad512eeeab3b46f501b0a0f9a5c6e3572d1ec107bc431a95f7321bd2bcabbd951b2a544666141d24e2c200fcf2eac7ac8170e137971121862e74a9929db36472e42e1d928ae6ac4c15cf130b5fc7ca39c87dae2327f58bf048591416996bceab419a1dbf6d64bb53fdfc4c9ba426a6b1c20a21005fe2a80ee053814a44ae6f9c5a2af37785f5360f7f9e89e0d4d9df1a3a6d37a5b32017a7ea1196a6891c46ab6050b8e3af590d98eb670607ca1f3d8069200bdf40cbf61981ea4ef96392d56e2669e65784f57fca0e0dece5897fadd854482bc47d4407925a98750fd0a5a94a891b6cf66508e70e8971ae4b8382a7bc93613726eb26fe38931e4c5f384fdae6014d680451d723cf65aeef4a64609aa7d1df828ae3d8bd422e20e2b5cd44ea45d27a0c7223d72f1f93189a5eb39d9e3b622987cd57be3231ec5d6e9c6d73b54db0a9430c203bc6424c9783941bcd85ad59089dda8f71b1e0f620cfb7a24c0e16dc68681e6fc7060e28d216e5211de4c405b321ac0f7053a3eadc7bce05b34afbdfddbd30fa79abb5524a2600e83c935d70e0e31d31f30d14ddaba909fd868414412fa11696cbfe7338dee676f146e5032764e830897a022ca3a1d5e0fd78f360789d50a8f885ffd6ef62e1ef686f3020c9592d675280f9f99b4aad173e57a8ef11ad450c367e220dbc1f76f1a549954cf319cc859b8fe69b90aa0f63033e93a454ab569c570dc99fab2a5b42ad091904c31affb3569103545dd02e14621ffa97dfa373dcba17d970dec2fa02d99638348202b06b82fa65e75c2bab28a85ef546e760921acdc7421925aabe2f5af75bf7c361f326e3521d95763fa507607c43b2056f16e0375f3d742367ce49b841178a6f99c32fe99db478d78fd4607c3cf02823a6fef86fe2f77017b028f3518ce40eac99a80e0556b4de6e79c26c1bb5369f6ae01bd86e485ef4e45dcbb795af382d151db6b030c4d1e7fd35e3f7a757ad89a7577e65626da96a8a778763a4c764291b88436b7f731e62194f59cdbb60089b8f09c938e1b0055d489cd35567dc7748fe2e4dca6fd24005841daa87cd2a9403a869c93316f7acc22ad87ba0b8bcef3c0e270fe14dadcf6f95306fc2caa8086046ea8f1c6c11f304eff5a60a3a3c3390c9cc91616f78d72ecd5d9cfd2cd63a745433c3d96f3b3492df5e301f3b9576a8ea6f807e19ab3b75ba9759e6d325300a76ef7a8df818f43a2949c40f2c71ebbeaf5a21e2acb0b3b493349c82e7846e8740ec0ebee35b3e73e197d4128802abcfb9c4d5f48e1296dc13e868ee67ad00ccfcb0b09ca4036187bd5bad3382bc54d85d9b375bb27255276c2528fd2dde64770dbc59c49b4e000d1ac54ec66bce72fb50048073748462141daa2765d237612317fab755f83f2e83d3f7d20cccbb5b7c3f16a8d56e061216df7c1827591c3b75a46563be548840be63781d929bc08aef7ad6523d29e84bab02bc9c7eae34e760319e9ebda2fc6e1082489c8493693da37868ba7ef00b4048d555065bee64dcdbfea9d1aed92943e7a437fba543675e749790098da3a0774abd3d7bae399bb68d283c02032b0f3f39683f66eabf5025b870a16670f5c1ee4efe3ffcbbc3bf0da235ef4767f4ad8557f348ef0b49ae214a1ae4ddc7d95b74620c8c4d838cbd842b40229c0a0636513f78d8aac02f5862cfa8026acc57157cde593aa4f5da5e1a7293d4752c5a5e3e8a4a2789b759e392ac4261bbd6eedec10d496d874b8be5df5adc9819ce72305a4164d59122d59739e789229941767ee2e3137973264a9d15dbd151ae6589f497cb7d5d89df571e7392bd452e54e3bbf8376665e0a6ea8495410dfc268910f240eb2296c547633d86b0d67f4816ce21f50f771d093c81850f3fd0e08d2ae9ea659f636c13931a386d9f26091f47becc5d3a9e8cd7d7608f34eea7353d92dfc8bd73938e616eadb59c9587ec2dd946dcc71558c1e1b3bde7b3c576dccdc787687dd3a6e82f03add4cab5e703a1b49d348f6dcb270d59ca35d4192a4a2f4d34559996566db8ad704f8ccf5fd993d6fd7cfbe95e23d4832f37d59174c29ed5f6e81b0195392a6cd8e6d98c5f07225df8e9845bb019876971f6d7bf9c65cd14aab830db62bdb1909007f6e6a3e3f83cba9b2b1dacf01158923f078cf0f00b1c7e2a6fb0d58ecac00ba84b06ff99bef03109d19db64f641620c8a9981f670db917c4bf0957283547cfa55ddd7fe7ec05f1c3b3d11c0708e961a6fcc2e3dccc3fdd72d7345f51c530d22f3f8132f117de2c515935175107d93865f3c785109efc56bd9a7a8f6bbf2e0b7b79cc9b1b616b937b6d85516e48b7acf6106419f5845a751c7dfb247d8c8d93e24af0e5a85706a7d0d40ad1bf7e7d9c118f9748c40ded2543f83059922dca232968b88ce0b1755a693b5c57bd572477be7a1dea9b119b80830832462ddb89aa3a641199b15b067930bdb10b7ca4959019e700f065630ac1df5b8b4953847462ec1e9ae3d7152506aa92f2109b90a7ab2fc016868f627b5dc5c7e3d37da672a3ea4c3285bafb72d4db33373acf9d46406cca5d8823c3bfc0aaf8e91a9aadce204e2c10124e48d9482b2c254d2f221941e619d45ca9c2c7dd23c86c22112a59ff851648bf891d12bd6a7822470a8d934b3550c7fd8a1fa622c0da69ca2d36d8c5bf85b1ab20bd286f8c0c50fcb40a3decbf231a111a8637a7a97311ac3f620d7ad373965079b7a6b426173abddda12aea3d5daf9071ec87379845335886407b9d1a5740b5905ff06a0d0ea48934828ab8e80a28ef06483965ccc78dba14c1dac75d63b0b636131d43d6be22a7ac1e6fcdccc36229ab90e1e22e48d61fc6f52d177804f7dd47131fa7d3452fddc77b873d97e2d107ee6bd610739123e92496f0ede1532dfaa3d1dc762369bc76b202ca19295c5fcc02b59d8a744c487bf4ab50802564c1fde84678a3fd04fb21206e3e72ccc64f617b675a394dc1ff13cd220f09add174c418aeffe992a623c5cbee9aac03bcf5fd57d0520bd025b3332feb1fd4fd60489c391accfd32a83fe60eeab20590f3d8d8a4b5425df91ef0b7aa9414ae253896f05cd076f0fdd7954056d1b06aa5d35eb552422b9f77666cf477939f298476fc627c5e053fbfeb94aed83794e85e43aefdef8b6eaf6e2f4615af9e7566b9326f71837c423c91a98edf9bbba43e48fe49440a3d3957738c54e1aa6f5293e7ff2969d046111af130280745eec959e69703f77e9ec6906f417e367b3d7c093e15a6413eaf1a461dd00b5e0866114099d77ad24f45ac13e2d4870cf764858e7530cafb5b9d23c1e0ed0992fc0817d93628ab47eabdcc1bb781c4a5443ae20e053bfc58342396c2bca64d331169e316b3df073cadc87b4c9742b26e7c9d9cf9493e48e148c89d9639551c2ca98c843b27bdd9b3ea6821d26572dbda3a6aace7bf6102f11e91a64bdcfd83bb75ff6fbcbcdf33f82d026ad8d4eb189126573fae906f4104a668d0754c231fe0418e3644f64c1741db1a4c9a45554a12a924bee0c513076268421ae2621938ffb41394c80737a890ffa44b236329caabdc3d162af0beb93c3900c5bddf154f53f29f6ca9d3c04d60de97d8fcd314eebd93731677f52236793e423d37046188e9753fe42f475e36b2b66b55757958082b4ade20e47be6ea790ddc1d40f71a01adcfdf6d09d9db36707c13a66475e00bb98335eae6f283a7626c03ed45d5e2e910c0f83b3697ac58a7ca1db4076b1f8e80d88da73d6a0f786fe7b34104c335aaf53b9d73b89d517a62337729e99a7945aa32b8fc6772e735a649a27e6bb6065012ef9514bcf29bcf15581dbbf52d144d254328ec6c1030f870478b20d9fa844cf5db5111924f294ecc4039ac8e594942f2e60ccd62a244e224d487741218fb169e49ffcc48d6639ce66409e1f9638ecda661c871ad7a7752f8ec9b3af5a33b13fd7f816e97f300a506360dfa894e97428f8dc9ad64e79c1537945fea2b821d2fbf738ac4c126031e5b40d846dc3ace19ff3a46db533ba71a09b986faebb61ee77a709b45dca1b3c4d650e801a94b992485b5eaad7479631127c5b5a77a6331f8b2df656fd3e30badec74a0c2e2fd505147d3aa24ad26440cd7d724b7fea346476176a1002be8f4eb2d0f3b65f17a8050f77af6bbe2efa2d18c9be5fdc304f4bdd5ddad9e5c8fd4c4c9ce65529aa846205bb1531ccaa83bf9fd02de6bafa089d73a795c0d7c084f4d8c344eb1f00aaef38c53e0616571e4b0a46f5606fca5a9448b179c889ceacc444b33d6bd01dcfbcb09441222dce92cbd889790671fb536aa22ccc73ec34fa3fd63a2b2b1fe770bbcf758d9e1213fdf4014edb30eab83de89ed535947f34112680a3c85f18ff5ef055dc45403eafe35d22c741e1d498ba0014a2216c6b8791828c910ae231b717d75a61e07a0da4abdb846bf407d56cec5a54501cfc78e960532d3c440fb5c082a6d16c47b0a9b1d2cc7c415361ef20456c798689d457314378ca7bfa7812539481594a26e4cb0cbce956362a9e751272026706f95c560ad41ca190534d734486ffaa6182e6995d09543c538c4c7e066c3366fd7824a87ac587a9fa7994a7306acc560ff602c565c5ba028a624db4d9f"""), TestUtils.hexDecode(""" 36DC7A310D995379B796EB8F9CA346EDF60DEC7F6C00AA311B3E09EF96A6795C4B077C1D371DD8D4A538AEB78B81927D08008E817A6FC6B3F9B14FE56EF9B2664E76112F214EEE848E67EF33B4A4E26A2378E9480CC7D25C369E6C25A2673B946B635B6EECB5F5F1499B484DCCFD5165D6F14CAA8E1EC9A9E4FDE417403720D7B4BB30060AB95C6F227767D671B75A1BB5AC5CC33EF0509C69652748251869B072B9042618071233B48A9BDEBA330F0C450A2FAAE79291B9E2480D1CED11FABE56210A80C39F25E5574356CFAA32E57782145920D6C0D27C3AC7C63DED6A770A5A45119FAA92209F2A066AB90FCB81A886FB87641C550368C1B412E43F4FECC2FD659B2BDA6B7309797575DA2893314DAB058DD92C7470F570EC0B1D9C9A149FE0934D40182CAD14D5B3D98C4B7454CDD2AE7E54EFCD554AA5B458888048BD5201C04E7D6004FC2A597DA781BF15AAC9748B6659EC16602F10AD44145607917C3599A1F53DC95839086A6A4FFD66F8EAC8AF8F11C4F2EBA3B58C46B93D0494C4CDA4E8B8FF7278049D2B4BD7BA16BC57678219EBCB5E211D51A168B5CDF66453412565B9BD606CE29A5A70E60F3D451D4214B0A258D6E9325EA5196C55125F0E115B14FF34FF6B172471C2B4917FC36B0DBDC82D0475AF56249AB9297790535C0F0265D2A853DB0B41B418072D0ECC17CF91FCA86F6E10762EBC520F0AADCC3C79EFC25E9692FC0A66389B15ECDD1377A9C3D744CCCC4BD160FC65A45D4144DDCA04E5408576DBA6D5C875BB4071729361B0514E8B96405E2F48D47138D2D2DCF4DC865F717428FA1262DB0D2B7B1A356E9E76301D38BA506456B4AD70ED09B0D5A1375AA6E132D7E06F8745E7A5B5E4F6455F4282A87D2B372C40A34C09699AA8C2B2E060107BCDE0F9D99B64F17DA5FA01B6DA87B1738882976B21AE12D1BA0AEB37644AAFE5AC20E7F3F631FFC2A24EEFB61DC37485DF27FD9045BD9BB5D3F00B9B2694CB94B01E7A4F0D909B8612DD28BD64E6C1C5A612CB30DF6004276FF58491B8129FCB0B539CDF891A97AB58DDF04AE40BAA5781C3AEC65FD7E84DFD0369A53CF36303270DC80E3E428854D82B08C7AD022BD99AC0851B16C7D8D462DA21126F70D661A59E4D0FE4441806DEC48E37AC4A271F15D916135408A2751CAD53564967196763B512D52240B2B0D3D924B83CF482B5316B7988D73A16B773705097F5ECE0027CCB2C2EFF598B8F61ED4D6BC015E56D4549432A6A95328FE3122EAED0149E2144E4CD2262C7FE7495E41E0AC9FAC9A11E21AC940D25E74AED8EF6FECD21747FF8166589B7038EF1DD504F51E01F1ED911FCCF44949638AA6E8526F0B9DBC5E536FE2AE7D4DA9DEE66402A45CF55D0137FAFDA9207AA7E22FE396455F2F43108961FA6B0339D89EB8ED7EF13B936E3D2DA18E5EAE45B05DCAF5D845DC62CC55553E37CB328AA2C649ABEED0D862E8083962B81B84A85EC12D3CE5B600123AA7CE4764139BA7AFE5CD02F70D06DD9AB0BBE868070A9AACB951D362E2606FD940A8F5BE632393E0A179C2A62151A094901F5625D952D39D7CAA87B77C4919A8633458AD9B6DAA16D1B1CAEAA8075741094FBC0C08D30D9956812C1D3A75926C546ABD78A2B9D44C1B6EF8D6EC2A2EA8B7C23D0EA57E1320ACFB576FB9C575DA98B714D6B01F03364E618A2C03BA84BDF0E5D2A0403B1379416D87B5E022BD958B0C9170E82F8E9A727D39C8F7549E34A14792776AF0D72A27FCF63EA985B3882A717091EF35F5835D4DA127554B6637AC313BA3BAE8170B9E70A6DDA2DBE813A49F045D8C3A65ECFB4D5F71FC75AADEDAA91A81A958273ECF0CDC4512F0D0ACCF9D9D001A30D0B6B2D50BD216D6086AC5C9DE7388A7B1319F2E9E6CE128B1F72F765804E060A8A92C93295A99C66D6D79BD7DD4F7F02317927D60B2E9FD59EC3F95A874337228339EC673BBBF53BF0FE1886A4B14F19CD7FA9B771894377F904EE8BE48D64EE5D40882C684C81DA3198604FA599DA8D4EDEE8EC3294620B6555B3BC9627D4514DBD1F7E3E9DF7B56BDB4CD395A8CCADC184B2B8DEB2AC7CBEC6C96001EDB67E6CF6F872469B110097C69EDE1121D22FB5B5AA4CA540474630651A4F9E8F7B0ABA5DF568D882626BD158F925F8DCE1D81668EF7CF770DC615ED0F5A807E25991EC97BBF2F9E997A532A1BD82A2A616250D2232F72067A17550EE516F28940D8EDA9CCC0E02EEFA496010E499E62C50B03F1D3C1571342DB8A5BDE1F432F7B6163BA3AEF35656434937A42C4E1F473331E38467DEAA483189902364463832ED8C5E04E0195D3435A6FCE75EA3BDBDDB0A0319262083141B1BBC0C278CFD40319647E90BFB51374B0AA5EBF3C564EE95B7AF618669C935756AFF3150A93EDA92F0ADC29253758A6C8A83EF55F97F1A4C0DB566668F30DE59D93D8185BDC1CFFAFAE472E0B0FC4B1E16F0B748220EB2EB85EF127838D576638E738E9F93A05D41CC1264AC6BA03B202D9E3B06946CCC68DC15261A029B0C5E91DD81EC1D79BC51F74BB5EF778F00AC091513443308410F60AC1850F2548C8101DB3B6B4D453541E36F0ED57C2C14F465196F8F1D0D3ACD49CE3252BAA0C10521311B8B8366C579A430526ED58BDE92FED3F0B359ADB31D67BFD212BEDA7236DEE4615ABF13C856CCC93DD02AA28D1CE1F12C2DD69FEA828BDB9F4CBC9242E1017D1063A7BF842B00C75243303EF9060C8EA501BC73B3EE470919443EC91D1F0D6D0F23A899AB86F2E8A0898D318BA520DD15D9B24F4F10A1B9FC52457714A151E075BBE419E4216857500B8354A8445B5FBB526A6E008229F33D8DBA14DD42F424DE3675E704DB308048B2D17904DE46B76622BA08C62F17EBA3E9F414A1B10921858832EEFBC282755B319E176ECCDC32A25CC5E76479AC112570AA86518BB1E6CA3F46E010E8132C0A1E8273403C5C4D7046A05398D461CB6843D70EEF8C94DEA5DF53CA1A4C7842AF5DBBC6451554FC7F9913E56957C51E0A602D882BC389C5E5C7899539DBE6832B0AAB5EF26B2C96CB03D1795179A62F748CA501CFA34D5ABBAE3271AC1F005112645F10863AABB062FD2C781E4573173935B5392CF9E88A1A31989E1B8E94F77CEFBEC591DF6529C6D2FAB72E678C534C4EFF40177C41D02AF0EFEB6371835CB55AE0AA99C0653876CCB56ECA127A0A1DFC0F9EEB49525C9A5786F618DBF57C41C5CAA971A9505BECEA8969D9DB28B0E707C659EDC42280035254E91C522300368F49F2C36211E455FD620DC956AFEE41A2493BDB2B0B8AB78E0B838DA6584FF753BF88CA6A523042A285F84ED90E0FD5E28F75A21B53F618145C16925486DBF6B1E7D76585D0D117EC562E22239E14A49ED714814F01DE2B250E9B3B6A1C99D1A71CEDEEB3ADADF611C4A4F97E1B26AF9780AFED5783129FD58B1232C7E2DB9050AD3D494EAC254DC46B0461A1B4B63840621D45ADE97EE5663C9BD8FB7261152545AE35536611B5C65DD6D66878DB71640EA429F801D6FFE291B06062EBAB9B416DDA7D261A46E58B154684E86176169CFDC4A60EA38300C3D44F9A4C9DCA0CE1BF37DF8F786F28B5B3CC7B0199D3322CFDFD2CF88C5B794C69F59543FB985890471DBC93A313992ABD33691CCF69B96A9396E5F55B54FF7BCA82A31199E5E81CE94B6B523EC5C3E2F2884D8BD744CF0C072E29E4B542DBB370FA5966F68CB20ABF40619E76C099BC7A9A373707707624E8999D4CF0A75D4AEAE113D7823D7D2ABF54FB4E68B8A6A57A198B128DC69584D2DBA473B6725FBB8EC9561D6614D606ADC4FD9CF449008C0D54BE4F62EC1441FF79EB59442AEFBDF1F0976844B4FA3969EEFEA10794FDBE35E89EA52F50AB26319BD1604D3FF5AC660431F1073575ABFAEEA00E1246DCD1D9399939D655C222E19E9DBA5FF42709FC11E7E365D7F7CE2274FBF1738DC5CF5631547549F2BD4DE896C8FE039720F5E0149BD81533022DAEE22B93A3AAB9AA9DA15180EA071D98E9FD176804A5B04D089E9C2D386271A8B13E7D668AA74BFFFFCDA3B4E528937C41D43A87DBB46C2B49B63BEEAAB978415536A87D845F6C2484F21D71D0F904438C46E7B0A3C6DE5ABC01C6F7CBCFF21D3E74AEE96C20C32884DE4EBA0F282C0FAD06BD9CD6B7B5031F149E4788F102D2AC2C99FD09B14A4AE3BD6859CAFE6F5A494EE8CEA29F49D871B79BB66AA6E6EC3718B97E83765E96D5603B209027BBBBCB09EE6FDE3AEB65AB1D73684820AB1FDEF88086B93B6338BEC7088E04F5F6E520E3D715C6C5E5B79E73B9E7AE1C5EDEEE4015860CDB9FA21FB434C3F28AD865042284A7FE9A5FF47E8C6158DD83EDF28BFB18DD5AFA07A48BD5AF25B9644400CC976A9B0FE9D9071E708113802A78CFDAED28378AA4FD6FBD9390D8A17D6500A0E1835652C7E0B332A382576AC4381CAD51A31E64E5E24FEDBC62EF9D0CABA0C8EBD8B94625207D0C8C1C6DF4EA2B20832EE44D1E2DEB799BC97B7245EC404F10764296E5BC4A919EC24B4F5F7D18692FA8DCDD5BBC170A81BE7590B7BF4058DC7BEA0C545BC85F0B3F0936386C37115A333285451CCAFB8397F1AE1B56D0A8F884BC968E729D622D21FA26B89BA2726C91E6886838DC9912797FF2BDF6800665C1D1DADFA4A240BB9BBE21B6DD750389AFA49C5C366ACA5E9C3B31B358FDEC42B0032D9E2C22112E43BED2023B364DAB334BBBE2C3B669EF700702B5D1837A6EC15CEC2B2036D56B8760129F593A669FF00237D26BAD9F9C2F4ED4018D998E555D2C3CA1D53EAD6A1E27906353983D4408904E5FD9D79AFEFEC26ACEA1F39218C36637977F6E2F3F6211AA06AB9D5F991C76F420B152BC95C4BC10047E107CC82E3B00B2325ABBFDB0FFB2966D5FBA0EC7E8DE1DBCC053C4186AF23A6BDF3F14A7186665AC2682FB94B0E10516D500B7F67BE4BD2523E194A1ADD8B5564FAD9105C86B6D16B08AABA604419D55F571F11F4989197144DD12867D1636D12800D54D36FA88C620008095560103366711B8E3AADD5624FBC7FF51318D17311F02A807770466AD559CFDA0AE1439442E4413944855D4D0074D529CA8DD621DA02FA98F46327A7BA600387EAE5E724D64A82E94ABB760C891EE39F27F0CAE8D1AACFE20629DEC5DD9BF4CA91E65BF413FD2A9566B7DCA9E500C2C328F533AF2A957E46D9FB11F0DFE99127656B1D4BE20C946BAFF58E5FE1A9ED282ABEBF6EB35A35AF324DF0A858CA8AF507CE43D228ED81D863F7096044A084DAA37ACB6AEE98E5A94D363963D4F852B955C2F076848092E6199E07990372E56BA1D590BB83D0C7F834C852CBC39B666B801CD32A0C36B034264F3BA6911A719001FD0F4B63D2D628FD0CAD34B4C9355534A8A38512E758B110F48E5A09B504D20D178508E09B1423A1E61164E7D138B4A9455B95EC8EA786F5FFE67806781F1E619505FD7DDE9A904E9003CA7E5EA1077C94C228D36667031502D78B3B52C3B5A09FC398D8B5497B6E3F0C5381BC99DD7B11DADA2DCFAE352DDEA2C749F8CF5AF39587083C2C19576EFFE871AB94D1C7CA2183FABDB74B27A80FC4F20CB86B46B0B7F86384540EFF1C888168F74634F2C0BF7FB54F7002EBF90B6C4B2B25DFF068DFC7D087A27749D6C36AB0A33423044AE027DCA8C42678987005FB9DE5C2774924AD2A5A8FD2E89C288975F89B5C0EF70A20EDAD1925060A12606A9B03626039635BFF332A0E6BDDC4F5DDDA209AF8DAA0FEF045FBEA9523D04458FBB0BD81F65396938436AFF5FA66E997AE58D64E7B5C1B589558B3DFF6D035E31008D2C76CA426B07F1644F609945909DBD16559B36461CE882A361D0415A9D93CB98A5370C56913A299B2DD1AA372CB75C7E590A9629CAA6C439CC5C7D94A21F36F998C6FDEC1C1721ECC500ECE1214EFFDE65E479D38C635EA223286DB326EF9B19B3CB862C96C162D3DE238C2948E7613A0FA4843E39EAC51EF293AD7EEAFF0F522934C982890F83E922B2BD52815136D0A758B33641C54E7D4E0F3B19AA85859B750E7A7FB80892C3DAC5048767132E2DAC5804709B8560A4B3828B1CD25DAF263A2466AF7FE328ABC84EBBA26902FFD92B0D765AACC0C0DCBEF962E1B35B1195676E8A67ED593B23B2B0305B611F9E16633E77E3F31794C58C5309BA07DB5CF9AA1CC108186318A3F16A7141854C2FC8B469BC0F54BCB22976A3CA05FC2C8E23F1B6A891E7527F204ECCA0A5400B68565906E795FE4DAF52ADA95A9883676F9110B14CEEA389CE9BFFBB5D040E60D3D03C4E6D6CBE9ED53EA44B1AB6ED7EDBACD0AE0613DBA5A5C673A534D48B539DC85F48175F13404016C5289348504141338FE958AC28331853AE80ADFEB49A6637936BF82FB26B95295B2E46F4F9534720A4E86FF18B31335877C9CBA96A9B450C1C8C9C9862E51CFEDBE3DE5C8B901D792A179AF9A782C330035A14CE6A710D398BD28416CD72373FE216744F6237B38B97351A77D5D0DEA1A26A0A9A24FE15503240933E1CB5AF458E6FCA8624669A0DF439CD7FC13F7A1F10A0CC7DB8C6AFAD9C99B5FC45A7C565B5DCB74FF0EF426FE7C260D3ACB1E9E83DD8E6E11A642145BFBB7566D582D0540D7931AA28B7F8F682E6E2D90B6E6812FF8B7F15FCD3DEE686DF06E8E6C456C99C6B4215C4E874BCEEE3B4F94BA825C6A45C2A2B4C6DC04F8FF5939C74E7DA37E02D8230340C6E2AB7CB82BD226DDC1A7C7BD0C0FB36F71F9C772233132B8871A0D76728C2A141741C2662438C5CC7B129A6C8FC587A0E475545D176818B51190F0F19E91E05C04477283A0A7D4D646EEDA3BE64459780BAC1862D83E6B99C5731DF91F0CAB454E70A0D94D934D0CD83C8B8301DE282F9A1FFE49E73EDCB520C016FDB4AD02C261DC1A1E73E38809E60F91A4E38C69EC70D2A621DF0D21588F24CCD59D331C69E16F0F6BCAA8F24031DD5718875BD9EDA5B420C116E4316137D4B77623C9D73D182900BD7A0F90A193CD16107E692D469AF09F74702492E22C796B6B4A960D47FDC571B4A264EE3528A0F5A9D66DDAA33FF20C3101D50299EDA3225834C9429976EC8E590C6D48A721A14972BE70955EC1A0348D2F84347C1E8E21EB0C1FE67223B42A6BCCAC43648F3BB5464121180F8E3E682B4B664D91584AF55FD1C7D2E6F79A93C680238D29CB7FF36D259CB703DE03B2EEF6DE0CB77AAA8F49C61EE482A8DAD30824E603411D5F09482DC84BE794BB6EB65A7BC1DA92C8BC8364AA88D4B8212561745BCF3CBA0D6AC8B8AF80373DE3F44EE39CA3CE4C5763F422CD4E8827B1E7BDFF79DB990A52530E4A1E21F6CCDF50A322A086AFDF24EB5FE4D99F1D1BB4D6DA965D168E9726FF7A4C82F327A748DDB1DA5A3D0E9C8E0B060872B009CC9F913D35D94FAA912B0D6FBF233DEA3AE3C2A4E35BBCACE21CA3E5F7A7B9A486AE9D7A7D2E0B79FDB11D87072F1B307402BDB22746B86A1A0E6B41433D5BAEB2048ECA53A1ECF895E9EB9BC5D6AB5D5DF72353566BB90578F12C6A16A163E95CD35DA27C79379756141DD05C315B466871E2B726B8821FB6FB439B49430CB3CA47CD211D03DF40AE4A0BE87B6000BC9C75AD23552E2129F47AB64BC9E5E1620C99405CEDF7BC059547D547E2868A6D470D813AA5095D0AA4BB18D91964988391EE6F05DD47CA1DA0423CA238C5E50D43CFB0527973506B9F1DA4A8055C47D1FA1E0DC783CE3CF75FFAADF574EC2849631E2551368291AFB5F2C40A4F1A184E37A19E511F482B7920F6D51B13065E6327F3C21DAA7F73986F2D1FBF375DFE2505C0FBD35F403D253BDFD0BA1B00CCC5A20B683D4F1E1F2374FD914C7D674901A0F01BDFDC007E8021013BB9A2F885F0699D16805F9F2511A0C7D3CDC06E36679983A2A0F12662C88BB7DC643FBFFB58CB51AAB3CED28553910D063ED8FA37FD756B79AE4151521450E552E4F2B62EB6F6BCC8086BBBD30331F3F2534AB3ADEEACCF2A6E66F205935A167FA1D5C747936050E276E8E4CCAFD9E0A056E4AC2AC08738BC3A598F07E933B0ED285BACE3D24AE6FF7574351758F983FD7EEB3944473EDB4EC9A9828A5FC656BBF04DC623C75F8B8038F3699BD5F255CCD3EEDE4FEFA12AFE8F64436DDB1FF2DF100B09BEC657DC5D2B18E5722D5AB30D075D9A52A576B6F9FC8C8BA3ACA6A92E6596F688FF5D2A7E3183B696AB277B0B17F004843E58760683F90BE0C61DD0D1BF9099A865CAFD1BD1D8AB1B7D4AF2F86D51C18D7868BEFF3F6C53EC68FC46EC9F23D1AE1FE85CD97D8CECFD57A562E7E574ED1D0A7005813EB980C2A46A98CEC602C0E022E87D4A6EDBFD7DE9FDA8C02EF85701BB1CEF6013F4869D32CBA56B0AD6EB007591D03C76A839F9D01985C546C39E49D59395B10346820324F3E298C5CD977FC2FF83BD422CA550DDF2A69607BB8125647B389246ADF0095F22692BF907EC86BF8D70D7E8F2C50E35DC6EF34FD1258E1FEBA0B254470D43C77CB0073AEB2D4CE5F6772D49A101052D8CE943E1C7760F2994071644D27D26BACA88EA07F29B2F2050BAC5E05F2226F1F584D17DB80E4056B7F9C60A5D9DA0CC577C6BC802FAB26E570BF017DCC7236A1173E273397E373640ED02B4F9863C40D2A2A7828C3875D8081AEBEF349143BAAECF9089EE736EFF0EF80078D2CA7942FB24A92071D229A1FDD0F6A87D362E5165D57F62D927757BC31964B5DA63B90EB3591552F2B9902E2269A163FF221863ADEADC9BC92CAC0087ABDA02004C0B9F34E5CA8599DC3C4261489F7527FD27AD2B6501E602FDE47DEEBF3F3EFC0166B1EED95116CF43C8AFC0EF89BDAA9ACFB6DAC613770DEA78960C99C9628C0D21FAF63A0FF7A3F2733EDC0FC07B83F107A811BB3C1DFC6CFBFEC105193272A4BF915B1DAEB232E16216E40FD3F9D9399B15CC4C073BAE8D08A4EC42D91609574EB009A9B52F06D3F428F6EA9B0511D8319A1B1299C154C94B103CB586370A58F18F04F5D21AD3B638660D6C04E99D356A7289E37EFAD643A5EBB488D54F4A0194FBC4283A8C4ABB8D9A1D70150AA50F991204C038AF54B5B74F722CD6515045D62276A9E936476F42B282C3B08D9328089AEA259510240B95BD5E81FB9D7E006DCE0DA832BD9A833799E05CAAFA6305D16DBA4461BE13D3CAA95773B98F09230F2DBE13936495C2DF5BE3A8F3EEB4FD211810F4B07D3E2BE1A11CC87079DF1B32D44B6FE7942DF2627AC19FD9F584E771D7ED98AA4C074A9DA5B7C156F83D90EBBDAE78D636D51EB0CB30C7C7CBC1A96273C0AE0ACAD8E15D1196BCB2EEBDA332896BABAEF76B4275F863732D646C24627AB014AB602A47594D6031795B17144E6E2C23F0341422886C1E2512222ECD530017DA02FC015EBD5BDFB319F3AE942D75A55C21BF347A44B300ACCED7A339007A2527EF4499E3BA5DE334BE58D59918DD0CB55B2F478837F71E9CEFCBBC90808E0BEF8CC7712A3B008B69476C61535FF0787B7833B70C69B1EF506EC4F445B72AA12FAC2589815874E9123BA13A17477D61E41163CB21ADB8151658C99F1422C71A8183B8D0B1D489EF436564C47ED8482A0DE9170CD1BC34D88CE76E1B47B84E770020125F718B4AFB1E4587668634FC7464114762A9D74A93E33A5C0CDFA824CACBEB097B5CAC3B554BC0D41C402812D8E43DB37C730A6219AB6F0BACD096BBF261C78E991DE0A2278DCA7D1BE0E5F2FED72CA38BAA86924A84275BFED3B91FC8DCC5024316EA0587C96E030544F631076DEF65F05F98C7641A958313686B8580CFC20221ED50DE4D2CF32461FAACD0174AC46A6949EF8ADEE6FFA3F537228AEDCFFDB2250D7BDBC848AFDFEA67AE53CE9ACA45F349557E81F70F9DB92926FD0CED8C104E6B7AD180C7B3BEB86171EE84A8DD2C243F6869E04C2DAFDF0C938C0768415C56330C9BB6EE756BB335BAAF96EEAA5CB52E554E39E2435B0731B0062376F4730108DD2F05824A798DA24C239724D19F12C6F2FBDB52652352021E0167F31E0F5941C4687DCD13A81A20A0AF05A55D2533280941865DB4D5715AEC293A64AA2E5151C8F44A14B72C0879499027E67E4E2B487612216F6122361E8D34E92C2163B0C88583E3887DA93A3AA0E77FFAE3FE8FD5455BC86AE6D6D5AC7CB7BDF156A960C98B0BE50E1370A43E7D183636DEB2C64B264FC5922D4BD46A8206F911E7A742E72E4EBDBA39B6151AEDF5A6CB4157B375D9A59899808F1838C61EB4388B923423D3879E8228AFE0CEE9561135849A89363F84B41BCB166EBCD0E65A2A74FE710F2B3B55CA9DE2FA9DC163BFFF4BE91F10493936FCA15F5F39422C75233DB22299456D1EA3BAC26F6671557B2A5FB0E9460997DCA797C67C49DF109CFD597BE34C8E0FA0353F28B815D0CEB31DA93E49EF29CEAF20FEB0A8F5924DCC62E830353463245899900304A8C8DB5830BC0E97AB83853D8EB05660D6A9303833D170E138FF6F1C30D9DD64574D5F875F974225DA81ADE3D97924A38F552276F46A5208403AEF82D1E92959675EA6B353E5C6091034A295D9C12C288241055A2334C30DF0A37D2590626A7D1787A4F591A6E494BF55ABC76842BBBD508FE54C5630D11C54386A487A756ECBFC0AE8957E7CA8678D5B9B044117365AEBE79AFF2E6678001D23624"""), TestUtils.hexDecode(""" -58BC36248443BED9F1FA12DD93EF6FE7D89828D96315A0FBEF047B5D57BE38BF2BBAE0DF7E983151E879479E00046AB12BA8354A6F51F9C286B83560DF391BB7B1B2A495FF27E582D3D09412950CE565F2A800D18454C0C17181153091B57657ADD3EF44C97FDD8DE557FA590474BF804E569EB7FBC36357710A307F3D540F3457FF382730910BC41C20402449A0CBC5A93B5FF47DDA2D39E59DD58A862079FD60B24E8FD43BF8750AF3A463FF810E43CC4E84D9B54B716C8EDC3B00BFC0A8FA7210E30DC6FA7B8668078782643404736A7FCE53A870491E3CF91C38A9E761426FFE7ACA6D1DE13BA213273E899DDEBD4E0BAB8CA084525DBEAC382D0155421B800A1AA921BC4EA1990E19CE090696E081AF1D4145B5C6DAC1277FBC483500B80F1CFCF40F49F48D2D86531E98EB3D14D1F54E435E976F0C123B14A4D8111927C2B425A43316FB10F9DE9BAEC23D49F7CF37D2369ED11FC3801E84C981472DED8DA4D1AACE2F6F4050EB94A483F79F2551CE179B31D753072D02642873DFBE5C7E61C9FD32701C10847C6AC35F41A2DBD695DACE401814743B88C579BA7B188CC878150C71CB5C8AC5763A805801FDFE267D812F65FF31D958B857C41B06A738646E93AD2D9D0AD0E1678697C494FBB76CBD41FA63719A3331A96A4840F0DC65F890F7F81BE3D22CE8500CDA8E3AE5A6482DDFD749F363882353D2EE9BE0784BDA8BB2AE75A011869108FC9736E6E6B08D9F6F42DD42F4C06A561C5E8B585ECAFAC49BE7B17299BBFB4B74398D8A300C6447108FAEF5DB463454010217F01AE45F0282D4A3B9EAF23FE092EB750EC081D6EC0329A9A537A5C270C31B1499983A7C293EF72F0A4FD91CDBEA3F029DFB35FEA766C475A07BB4EB7297A9592A20E3FB15119F5A7A9E658D18C4EEB3E35963C122A1397456DCAC9DE8EC08DF9873C751A10E189B9C8DB3F63721910E930397C4CDE3D475AA7E5C56FA2B139690C20418DC40F9AC14BC29B419A45ADAD66AE2790EE4CF0233EFEF06E75CDCAD7A594BD9D64F0A030EAB8FD2C77B3AFC4E4737FB5682FEA678FFD75A794DA8E2A0348088A48D1321C9828E0CBE6F15A746DF22248B360F51B501A9BEDA1F7263D5BEE948C72C9ED854EEB7DB56E5885F6892BDBE019B8FFA9CA30DB9D1C82D3E13AFF7D75B0D0A713FCD4934B559A80F4F32062BC4883CBFE4B4F905B8B8E639A203D69AB8CF33B61A3092B38F03683EC64605DB4585C1E30021294BCC7C98D8DFD80940E82E65DDE8621A38638D6EFFA26E19CC215FDD0A305E6BD731ABA1CD14BD397ECD52BBE7CE7D84F88323A4C2D709D28333BF97DF22D24BF792EDE7B5F5DD1FCBEB169B625E36D2DFA95539188CE7B7BAD539C2BE1BA1971648478468AA3413DD6076A213EDDD1AB0FA85076B6D91DBFC858F1F935EF31DA87A24E3171B30AF8F03E8DF50A1781FAB6E3775E5D14B3025492B4E0309228AD41B68B278ADAD656EF83B0F8B1ED030835255A4A07C94A35D27B256AEC0381C35E640C1565A80D55D8905C7DD3BB69801DD362AFA95EE532714BAA8FF701E8F8F30A6165DFDF4FF260C6DE1135E66DAAA7EA771FDB07E07F818E4B2F7334850789F8FD0E385B23641F0D8A7C754A60B35A76389F5920A4DBC0E890A7207827F2B6368CA95241DB5C6664397D5A294FE3CADE660D80F69F0458171684A997B68E6CAD05417DC192638F9275DC093FBD4A72925DF8FBFC7B6777CD28F13658B4D3745DBBC82C88E42A16C31766A9ACBD13DE946054131FBCFF70677F2FE91078D9593F12423A3ACCCA5761830297971F6AD925455B9313683F01541B53543808D1E8C6ACBFB93D3B4C715880545B77AD0E7F1CFD6A3426815BCCE1F3E7EC720BA259046B06803110F12508B33D7C04C567BCB2069DAD995C590A2560C766185D7F2A186AD1B336A1A5BE702F6691F90978F1EB6F3403E00A2464F19AC7C76D2490CCAE4C0D117DB7543BDC73E6DCCC6AEE86D74984FBE575C10E6AAAC0028D61BBDD001BBA9186065A7BD1E7A8C13CDABB33F6F2FD03BE5E950793212CEAF82829142E7BC7E97CCC4F774892456870B23A1D6CBC5E1D2B797219AA1D4AEB332F2B38DC3B230E0EEDD600935523D9C05D7C750B485F32DF4BDD932676E6FA4A7AF63E12AA149AFA49ACE37B03DBEDFD502B97B36238DCB412E5D9C6AD0E8209119DD9BC5C22ACFB7FF53827CD2CBF259DA76D48CDC11C452FFE69D73354BA70D9CF566872011AB6D06D027C9B1DD93B97963F964B33F8F4FE51EE4E1F4436E5B3AA240320BF3CC6FE63B219553F6923A134D843C9B49F913525B4FDBB87F5F3235461E8DEBE849449BBDED39DE58BABF6BC66DCEA2115AED2582504E5FE394B9C2C346C5251E9F058C6447526CB3786A8A66E86747129EEBEA89F6F27AADACC5A97D6D9EDAF5533218C46BE6C8A108F8723F78576133FEEF95920D3B92CFA38B2547CC48B97087EC163FF9C244343F51683E8B1B7D29968A81423EB1346DDF5C4E638D796C8FFFFF6C482E47227327FB87885F52EA0840B06252E5DE252577838D869B074E6D0FEF4811866467B82121967283C2E47FF209D9E3860FC43681E0AFF54E6418443D5B3F769ADE3EF026F7E96762E1018326A0CBBAEF233996322E495DCC06693729D7C744ED8B7780161EE1277AD7C9C4B40481869AC463653E1E7F7F60AA5C352BF1F1A9CE483446F13DC6A26239A6D784B9F44DE97299ADB3CDCE3896081A7C93445C45D9ADDA1ED9FDC49E63202FA99D02B240C46DB1DABFD69AA70822333264064184BD583FC949B5134902767D003E6ED1D05581C1D6AA5AFD9A119B15F745E835CFC832011829AD48530C7C51AD17785B06748230985E77E2A2C4AC40313EF394052AF472A74044B8542261BE57136759FFCB1F42F349A464066BB4FF963D9517D4D82181B1851654B73203B16E302E7F7875067D2198E33F819270183ABC0AACAD3ADF227AA20314979F296AAE763E9934F15A6544FC5CAEBE33B6D51897ED5DD4094B377C51C931E9E62E5C05F340507C82C4E2788DC84E6B719F0C1A729AAECB019946C9DA7920DD20A7E7DF89EBA8BDC8E8EC1B03FE6ACC18E855C02408FE1EBEDB17066DBCFFDD0B1948FA53A45AB7A892C071EE692454D94453E2D5E8DC33E7B6C304154D3843C6FFACDCE3358F8D845546E2DE5C1E9641646702E6CB83AE5CBB07B35E9CD28DEE1C6CC88D8A614F262681FE0AC38B86AA792CFD0509A76928FE196ECA25D9A8A231A1DC659CB37C2D7EB3B7702443D879D6725FC633D503841F43B4EA7AE7155074B4DE876E2918339CC2BECA755F757183748F1E9FAB045C3F22DD5DC2EB5752A4EAF055F64F9BA6B3AA65EABEA3F585B72D712E40FD2B9BBF5F62ED5E9343D613A59A81B8D4172ED8837137DD07FB77C3D1B2095B9686F9ECB15E37C6C1B19267A5C0D299A1DDF368559F615733F451532554D0250D52E4C56242FDDCF6DF7F4C5E0F372B04AD24248687BF21243FFE82ADBF602204E9281C2BB4F47D5E3233A6CB0FAC7854BF4B298EAADD9242C085856126A1806D7B063C38D2D6F13CC617D22626BCDA228ACA22B798C0BBAD8D3BE108DBCF6ACAA304EC51C78BF2D06CFEFCF9B279B7677F78AE5055F77E0C8BDB8DEC635290D154F59E13DD6E45CB81BAA882A54B26D2447C8DCE935FD0A9E5EE20136C3FC643ADCD342EB901DD8A0C9A652DE28E552A73182616FD7AD0F662A465EC1D947A0442F5583811B7A921FE210DB41614A01B880C0F811BD74325967CB5361235E92C6941B4E5EFEBD38DB1F22A084C2AB64308BA1E47AA7223962DD65E7152C840AEF3B0607827B6E99F6037FFF6749A9B871ACD998F719A222F8ECFF7B060F586CA9CDD6D9ACF769DB558352F7ACA2A2CD8BCBD91915835D96F0B1770A88097C234D5D46AB064D9AC7B3A387280C9C8A16FC561A7585F6FAC747FA4091BDEB5AF963E9AC134B948FBFB32805C80FC5DA7798061D0B26CC8675E2FAD9AE52DB944FDCBCA68870B29E270D9D51A113B064FC6273CD3F86AB72CF31B20F0B72E1B964A2B2E42CB71129481AE61536DCD409B431E2859BCFA5734A47A05F149FF91181F081846D376730E4D492250DF165A2B542B39781977E96802A4AC38F450AB89EB87BC19E5F8C323F29F13394228C985DFE60A185728ED95DD62D764EDEB4F46C6D5F24EC9B105075ABECFD0A27A24D52DD0826B18F89BBFB55C27A42496F5408D283376C20807922609616B07425B4E180CC6E33BAE22186AC37E3775A6786BB6E930B928CD682632D687A2915094F520D76CD439DD125B3DE7295C5C3D1D1367C49954CD0B2B944F5CAC8CF765F39BA61B89B007CDB7D46ED1AF4ABB6E219C67534DF7AD50C422A0A34B2204633E4763A386E7235DA77CF46CD2388062028FF8832FFC74A4612886B0AE4554BFE6D82E604978101B413B5AB9478FF79B39F49ECC91FBB639DAC7A72B97B7693DC8647FB472AAB87CC9B28C0CC91AD51C557ADDB3B6D864903B98793C0E80AFE5F02A2FAD2CEDB1486BE609832DFD285D92E67D46FE19AE445F4FFD7C166EDDEA185666FCF0B4B9F75D169B440056DEF1E376B0F6166FBE07BFFB1925B69A2E85C25C7737F9FB48B87E7F66D2E1432E12BBC585E3D4E6C5ABD5E65326A67D1C944C67DCFBCBB0A017666187E71D2B1CAEDE13DB5A4576F2F0606E892B7C57296B95B009CB92137729786672E11E66CDAF1081E167B0AA0BE018711C8CF7D285359B6961CD04F79F95559801D1DFFD3AD1E712AACB0C121BAD5604C9A5B95782BFDE6F1A2DFC110579197D1C6E6686AF1CF312B95621C6B72B4A57CF8B1FC47B773EAC6392B6CE10F6ED1D9A0C2827A0B12D058FE72F99EEEE750CD4D41BD4A3D95B1B7880535F78E4942A7D83D3E2FB8C1892DAA7971E4A0092CEFC9786D69D689AD31D7AAEAD2CEFEA23E0CE14305BC745A472AE0782DD31F8F5484EB129696950B2CD00A8F401C19441FCD6A16BB2AC5A9AB36DE2B75EDFB5BFFEC0AFB37886F415D79DAFA24350BD01FE8B0824FBE6FDBF6B34DF81F0A75B5F5F87D94011014AE543B1B7F5C1F7BA542BC3F4B134E1D9EA6345339F4606D132998969FDE118BB0F305F2753D1D63EA33465199C5D04D2ED4889C19E180B68D2C5CAE8511F9C69A6539B1BC24EE28DA9C9C87D7C46887D01740262F7F2E76447C5CED2C8E23A43CF9B5A9EF603C14BF4FBF4578A1A316029B0C036D085EA7AC855516CFBC6F658923D54AD182AA66F6FC62812C49E0A209F5FCD343B1BEED407C74BD4499024DC312918B45FDDB307A8DCACE261D070F84CD26458B62D7F3E9BDCDF3946384AC7AA1C32A34A218EF6C9FF835FAE4508485D2A3F4E9C94425A5B3FF0422EC098A34CFF4583C722389ECCDED9ACC397D53985F362DBD0DD401CF830E206BC956439BAA66981F2EF63C30F9426A389CF72F144DB8FC4F7A245A7DE66F1594629FCBDD6CBF44CCAA2C4E3D45C0137F99CC69E08FF6BA2E835DEA3D9DAE61DB48E684BBAC10562B6587193DEB0E6980EAC9877A5F954E1AF915D02C8C394483DF6C8AC9840DEF57D7885E0A38E14E9D3B85EAFC94BBEC68BDF2CFE33C08CB3CB7A8530E8759D27EFE663724FAD3F23F6CB10655C0AED09BFFA78FB3C671770A2A9B928C4DA2B0852836730C1874F7A027C861A805DDCE2CA765D091ECDB3CDA874165B5B0B87A6D6B64A73A47DAC6B255AE65BBF445E1633440FFC2882D487CD30D5BE629A4DC58DF086A4C62116A64AD799E34BBC46CDE85EB71E7A7B279B6E50A13EFFB00EE7E86FB19541596D7CE82F028A26DD5C9D0D807F686492E0DD3FCEA572A1D1E544EF62C282A904803CC2C7B2CC0FF7804FA14060A1B7D8E06A61F5DC2FA43179286B4DA6EEB8065C3D6397E6CE850562DA4E614A44BF81C3442D00AC3AEBF682D5B1A9625BA462556CBDBE75CE951C3FA91F83105887C24AE3EB3ECCD05B4BF4D6C910A718C6BAAF44BE750CD008C2591638CCBA780807D02BC462B9A16967D2A5A927FD75AE048591B5CB40B3DF6F092469BB30B2939CE425A190847B904B631E08323B88E11958BC5C6FE6F97DEC18B7EB94D14089F9EFDECA3D20958780998A7DE03881BD99B7315465BE6CEDABA61F0D3935694D1FB6610E00BAD93E96ABFFBE51F653FAFD2353F3ECA0A65FE4CF7D5583A19D99CCA53C11A5E8E5450A2383C7222880062C1315D81C705F85ACCFED53B9E46DD9CC544F588BB7C7594E4EA2B7720984C23347BAEE26C015C065F732ADB6B71C772FF539D9AB8458917BFCD3D8B8F6F9A495A942DD429A91DB1BBBAA2CBFF201086B14B8104D6CD77655510EC4EB8C995B95B1939BD0602A893F631499C81B0DCF7D02293A839483BB697E7AB5B364B8A386D481648557206AF32F4C96DD05232B37536793BBCAD81B515E6E7D92B8C0173A5D8186DB189BAEE053B0DD4B4F678FDAEEFF14295C719EEAF1FE00000000000000000000000000000000000000000000000000040E161C20232A32""") +e8b08c99776fe554292851f9d80f785b8109d6edcf9d30b4b3c8c11fe8b2e024e333272f4d72e697aa20953d03f013c0c3800e840aba56daf36846b0e958f7e1a465deee3fae6e45931424ac278b6d1916dc71760b7518643185cdc7b06b1dc0a54c83597e6a2aee0894c2066b5fb1e2439b2782ceec63aee1742d10f4c36793b845d5b86db9d22a200e12611bbd102cabaa00ed5cd47e6cdbfc06d7bee55e65e4ebcae019ab28f0f05ff2efcc3c44a5c89a5e80fc8758d774ddb3554975346aad922319273ea930b3718562c3a96602645c58e375e8b78f38cf636b42e674ab4c5e1a8da59c64100984605035e1f735d6ebd2948b556b056a07ab86f8d07f8cbc72cb7251543ceb39a9deea50b8189face6b5ff23bf62ea3686fc0f97598f36ca445942cf3c2acc5258f9a870eba919b99c75bf598031edb693552c086377ab84aed818e795b70a62c14f84d5d01fe9257cc9df2f4cb2f40173be7d11592e9289eec23ad30a8e5dfba2f6a779464e79cb5b07e6e5a19dbb9a829eca1ff64c0a672844ed2e636903bac6edfce1315cab8751e9f12635160df14cbf5ddd341824e8033507de1f6cb7dd87c5496342a27a8746e94da455ddbca610c7990ed01ae5dedc90cee503d525ec5033258465e282cacb2c0e0ea7457e62d06c194a958322e64a5433e4936292fa700dad6fb7ea4d5689d4e3efff132d61493859aa5436c9087fa9ac5b67419a836460fc9bbb4d53d0c9b6fefab2d513b76f0600d097b0c3eb7d7a82e01ba3abed5354fcbce02cc7e85fbeedefde5652187fceaef8e6c05b4f37c33a752fea5af6160a7da084e41dc7134534fda67c4e1c6b8dabf7bf05d25a0ab7e05c41c4e0070e8add04f20d8c72bf941ca284eae27cd9568e9938adf4f55ab2c40d03bb49c58c6fd8d74245cc3b4922891b865dad534e256ebbcecdf5227b39ac335005bdefe1be10c2b7c969f4dea6f581c278f8479cd7a40a6d369bc5e1fe5e074230d01795dc664e488e4e360b169976b99a0b9d257badf3f397ac914b15b8ce4b3c38e6c758a169ca015fb6fd339c4255c51013e7430c991a006591fd69a069cc2f966c24ad78b8c0a4f4601ea08ccb683e8d427d1a0db844308e86afb0e3f6965af9ccca755b5e2a8358fd2417b46bce7a69b2edd6e9b3fb617dc5bbbf2803a557e33c907b4ee7fa7a9cfd9f148730d48e471097526e4330515f3dfd5e4f0e6c6dd2c2db73c2c0913c82559032c15b3e580e3b11f5c319db8b04ee4a3dcc87a4251e8ca8f77a8e61d67a5586f2494c3be2d70d95076e6470cd3c3ed1b780ad9217153fda872911bb01edf13c13143e4082cfc9fba96f14e7844f3ab040567faef1f03caf66eb10d92eada39afc6d70d16325008f628489ebd9e80913227e270a8c272709658aa843a486039a21951467dc1e5df0feabc68c28ae9e9cdf95f7db12cff0167657328985f19595b5aa33f44701a8f40242a0f33ff9829078abc53be36c002405557c61b9c5585f7d61d0fae020b2ad18358a278aee3250b12bc7f0887d8cf42137f26ca12a866c35876bdc737a22b8a722e71ef500ce958723728aea23748924eab3552a7cd4142dc7e138c84df1251a2ed8f94c939bc7aa0ea4c0ebb4cbe817aeb65ee5f0f9cd407899459e719f0558f8f40d73b1226a004b910e26648852bcb3b08aa5340f6ac6426aac89acc4945b180dc4f401d97a6fc68e3fa4b8ed65ac74727e3ee5da732b02caec13b88cb167b15e4c7da21dbd937549685e8068c3eccad584698291b9c3410aa8314762fc838f9336b6b09c191409d1aa2dd5e2a075b070413c805f116d42f90af6c7ebf8c322bbaa14a5692ac0749ec7df91e5eddc7ded2dd873907e07b01f14fea1e0efe6d7a1a5ecb95f822be8f3a2f65224c3d801284de6f29a25725c3784d7bccd1253706e107fb9dedbec4620c87c615f4458c4c7078a1e69a0f5178b318fcec51e73995df8dda6ece7b7267d28daa1fbe7f36680fc001974577e4a128282b67819227e5d100baa5101c5a1422f096083b3b522a6b71f8943b536d7798e86e18129d1484cee60ac63cd849f5c9e8a58fa42c0298e3d595c3c4f145aef17f79fba8d7424e5ad7d6831321e51ac88eb1c54c6c1e2f3263c899550b65cfc52da78b7ebfabd474851b3a2b5457f4e646c15ff50efee6a8ad5c99e91853656255fd429e8982c56d65d005cf3ee1a725e224c768e8c92003a72f3060cb088f7a8cffac0d526c028f3dbbe84600d5a9568f03b2304ef37d5ed28941169f8e204a1240e6d910dcdb901932982a6d45a7a10b1630587d31551b6e4424fd929b5a7fee3c4a20929102f5791062acb3c53a6edc93ab5ccc703b8cdaa39857ab06b7f818a59d8324dd1ab342aa1c3b0a32dffa0512b92c1ab9a4f66e57e9bd27734ce2b2788058637cbf94b03b7a1b640f03735f36bb36052bb461c22fff6c0580b6eb4bc572fabc9a141c1964d664168116d9836f7c7581cc9537bba32d1e3e5519e29858f889e282c805084fe3a64db0234bb3e1dbf57956ce4165795648f4865c1232e24a6769e24c0b271aef1146425a9032884393d275fb68e3b3c91599ee82a4cc34338715a8590f436e4185246df9bc4c066ed975f502b967a5761c1b8f5aeee302f96aae3dfdb6f4519aba3e04cfe5c9b2d342048a4c2721484e9b311c9a18ee5f726a512c93a8d37cdaf6ee96928fba315a4680dccdfced6a13f46e06aa162a7ae445bae5b1134f1656a2d700dcb2b5138c780b428d346feb98be8ed911de7aa5ebd72e2a6a8592a81ad4fd6a6da64edd2f5490cead76fc652998181018457f1cc0ec4f4588cb8f418f1b6d801635847914c3f317369027b4c4608e65457f949e08110b23dbb6941632afc1d1292c55c169965f0153ec72d93498f5a68140ce2c8282a59b1011ac705fd5f0a8ed1ecdadd58d4a1fbd4b09e94802a0c67f2f5faf905bc4a35471f886a8f2366c25b710eb43aee8fea692d12b4f94513337b0ea9fce3c255188ab7b432ae37383470eb94abc2554c6f165bb356415a1f8d8790e1bf76f4411c8f32fc550e38a0ea7b8d37537855724c08eff4730484e55accb2f975637b74f29937c19fdedb5aab7d5a3bc9ee1df2c83ae8d0e59782fe18b3a17c82cf649a4299b74f022012e189f19d88b06387314b65add0720aefd0018a09bb3d13cd63f98fb73b8a57564137e89811d59f1c74a047e264ce816b01e942038574a9d1f4fa5408ad1661c31bef7e97742aec79b74df757065e8e1b059b5134e53cc8560bd87e9a68003b124b15afb6534cc6181b6b71eda535ae7a3c107abfd2d8e5886cf8a7d67a4b723ba794c0c5a9d1a63f67a6c42de3e3632b8a9e7bc7eb9a5e404930265a7d04c1e16ac17a7b5e1535e1bc80ddd1800a7ba1b0d73ba053688137e1db64eebfa9b5dd8573a51db93aeb0c6c644c97ba9dc87efb2a5d79b3e3ff396a45ac1f0aab064dd05c1e6ae48b2686d662b8bff1e87db3745c7b3126a091e688091d84d3caa1adb471df496e79e42b276088a600a6f8d2aaf3d31b22f7e7efd2b894fdef314f2258d32371fa022e272760c704997b2a605b0e1a8d0602ad3a134357b0f2785d79c557cb04121fb054354608655afa7a763c8276170c13f9e76dfa711e26ceaa999fc14c686e2ebd61d18e74ed08fa1b872e09246856d9e0477e5e21a72c7869b57785248aef0d516f670978ba4dbac563b77f365cd46cecbce0b7fc7c9fe7373d6ad47d094b3669849dc21084124999ed55f13106d4be1e52433d86ffafbad0e4f221c305aca71063037b7a26ca73ca37129aec69e665cd2e70a94dc5aa8d22e1a425853645a3eb05f8998c6d766806087f14f08fc95ae3b2b9190721bf536ac20cf49222f5a0dd03307995adadefa43a205fe9dc839b5f27447611a93012d3abccf3f5d7a766756111dbdadf6c5920782545c853ae1a550a08b14a87bf296ef0aba7669fabc13a8d0d85d67e36abb24a77bf87bdebbcec1e28c1f82fcb95e82ee936f0c1a60a38ca3ab846eb39cf27acd9a219abc2c6244878ee25efc38a6552773b7444e466c24a15458df3cac856201a12c3bba6483d886482d58112effb0cd72c7aba4df0c11474a41e1fac0419495166d5b88b7e5e169c96c9ea6ac96dc5c2f749c858ad524e7f3d32177aacbc836abbea91ff9dac9d313a8004a186ab52083662a03d42518199bb2b81f9b03501ed8d1e8a8069e6a4fcad2657d4e69c0cd8e4ee56389d026717c72c99f13b2d21780c122bdff75c0469f32a1c519afc5900855539b1c75a3019342b7d5fd8ad7fb02af96fc94ec29583a48b964c65586a6f17af9f268a6cb9bbff237ddf393dc40d03b69ce5925a5fa8af87a6d0f497ae82d6468726714f7b53bfcbb647253c9db17a7bd5e760531ed90d7cf044ec0bdcf9724b640a201f5a08e223ff20e818e16e88fd92300b07e89ca333bbc05e8fd01d847bf9d7ce85da9478833f5566662888c8238b70cc3481ce0b8fb5c5e144d05ca8b8952c4374b261e48352bda2bd2e8de39b6318a0cbcfe3c36e6dd924e52d82928e964930ea6526aae08ca596fb732dfa02f2f6da72a05a227648e1fbf49554117aed210263cc6f5ebdfe2ba852d1c4c4af8f71a8a6501927109026e544432504a5bd066d7c03d443a191629a2c67b00f634023bb07c676294159db4df69555ffbd6c4b5a6d4726a54f9a0ab243cac6ff603e2ffa3c4acc6046a849b099654d0d894ae6536deecfd326aee5164eb1a59838da8cb33724697c17d6735687c860a13c8b8fbe497b99c98b58c8a0f0c67e1239b5a0880c1d4b0e2cbfe268141d035c02047d0a5c64c4fc79f245e50c43f3f64130be4b8def3085330461a12b1cd047afce58b05d2d75ac4980376a2739821149c95e17dee53f6da1afab57c02c7cfa3652784caf90f6f66a93966c636a29df19b2ed5699ffa1aa0cf5de784f5b57c15ccd22f5963924fc55f997b8a508f10d8520c5498f3408daa04028ec66b3885c5495e10666f8125f4761cc09071717244928ebcb985cc8ec8ac777fd411b8a2aa51320c60f6c71bdcbae9f6e37eea62c1f595ed27bb83b25842d2e26988d48217862afade93f152155166ca55c13c143d6c176208157fc8a836ca68ad5094de00d82665b2675baa86a6012fc36593e1c9aeec4da750c5c747643072dea8fd786738f5e788e36767bbd29a87ad1731adc579396eae378f8c4fdfaccdba49304649d108b19dac8caed2d08f116cd33af7bd22091330ff4e99936dec531ca9d735430cb4a0cbc4652a9c1c43168b1ee012a46b1cb92d3035714eb4f7f4d6b63b60589b946e5a47e961f3c575d13e1486d9a388dff8c8e9aa4663e5ed91cdd8d3d59f02deb394ba37ee4a05df162208286c19bf0204f4d609b229087351981b6e62fc580ab06ff34474db029a16466d9630eb263de0b76e8b53239a044f15f90c4836aee8b2203d6db413b583d62c8bbe7d657b2c1185a5720457a79f621bad76674112e28c34ac65abbf65e73f54f918d0b912c429b29c5c32a370ec1810cbb07375a85df5167b32a321844cc54c34ab54b87fa6378924e54a874ab871c928d49e704dcaa40b88d7a7c5774163522a6620abf5d73643338be36e5b2e30659d0e39695fa97a6ff8cb8064e370eee36c5a3b57de7d218fa325646cfa4fa2e9a0622bcf139eca8acc28de6f0a5d2e37dd2b0d6f6b39989eda0de372b20e2cbbde73857ae39b7f0cbb2f4337e04a52f1549bc4daf89e484b06177bc9cd6b199906b62789431e4a29251cbb4539c62ea6fdca9c84721c02b8af585f64e8420a7ec91e6387a897196685ebb760d1b4276cfa36b51f4d3e840e2c5e074c69ec7f6557afad4ef6774dde534f88cd7683a6855bbbf8d43d520cbe0312c9e189f710c75ad64926a97ca0e3b2b575e3aecf7b9145c160c415f8c90160aa5208744addd8b52580645fed9c66a2f6d8b0afe577ff63e3fda7e9a25519f0d2fbc3bffa9f45c40f70452a78b903d923e4f0fa9475659910f75455d144295e4091f8a760e1e68460227d37fa6220b4f0322d61b8fd7a40275c4d9446255862682f775176c67d294ff45205726eb733e5d21302f4df66fec98102611e3bf8084035b42448e86ff9225935ebf7db9a847e8a0f72ed177fa3812f4f5c0dfb7e452acf0e1a23d781607de22bdf31177d5eb5e2840bad442feb2f8baeff6f17bd63ed9495b0351949ccbb6337d907831e22ed31cedaff7cdd13bc3de40421ac6afb536ff89bf041a3026ce04316b6a082c06e0437440313ffd36ff78d6e31a4f5652c52e53f06fbeac2a7f13c64c061dca9ce9dc2e7598ed90a12307e5125397629887f0a3d3bf8d24b675db85ecfbcdf8b3fceb50e96b0a863d30a7791db30ce4cafe8d85999ea1282ba61f667497a8c52a2fa3bfceea070b2e8a9cd8e51a244b73a0a60a1e4076829c1a4668717495adbecde4f4fc0323325d71aae30000000000000000000000000000000000000000000003090f161c222e35""") ), new SigGenTestCase( TestUtils.hexDecode(""" -5B62D37A8591CFB588DA48B3B1AA1570C3491210EFCB877AE913F5C98D06C5853C78D526C61C387FC6E15BC8E612762899056F844B324E4829E5DCE6E2144804682D4F5D3CEBEFA61305B64386107BAC5022DE119038F94F656ABE41A61717532E374C1196780C888EF1F7455BF502420F61FE9EC389C1BB6B75397622374EE00AC0856130828C806CE14840D9322440B02923822D53126A0221108B988822A191D43231D82831E2C80CD4A8705B086D83B001A0A64183180681027040220D223269DB940802958C8AB6500C056E2222311C91491B9451833064D4280A112750232610CC088054222ECB344511B90063128119C04CCC942914C36114C1049B1290A414460893242316665B184262B211E330868A280CD9920504009162A4605A926C1B28100C002E1C4491C3A869C246860200050B1888588664520625A0102158409090022288A468484685C3844CD428919BA0300381300C372191B2001C086C13142ECB30710B3021840864E44465A4B061E2144184808118B70DA4161201398C0436810C2970DAA029D840600282411290898C106A19140A6394711C256D18C08DC488249A881123418DA33491CBC801D010680B865090104161B0511A15501C0104C01605D2B825E02226D1A0708B98248BA22040426A529220941080D34006D3C86458B4651C1440DB168DD1A66DA0B67108325109128A92C869833400CC842004064ED9340502132D1992800424309B260E2319105AC669481061994028C3A29163024C52462A5030221496846280250A300862B26523282922292410436C10B11001120D993884A34661830430D0100A00318589444C5C28802330884C22445148248A083223C02C442682E3C86C5A0088622224C2444C0A854554B26D18452214214898464A1886610B26205330310A9840443669C3208424380D94C62911C445528249DCA431DB4211C3824CDAB885D800655C462E238288221980D93468118441E42609601488204486623445CB02411A266DC392514C142D1AA8515CB60DCAA22819286522368D4A0630DC44491B036641C231E0064CC08430918460142670E0000CDC10624036852348819334308230458A38300095319B082D608268911868C2C2109C048D9C084120B16C82804C14C61120C071D1B850930245A48420D8142A4C302663B29103932521466023094A0A076C14012190180E901012C2B62458C809D0A004429885834010820629D0102462C624D844021C054CC43841D4082D0A498C2425600047621B90001AB78C63A228A1A229121126828820D224028344285448640A3104CC166411A52520B0205BB61052422509C62912474CCA226289261222812D4A28428888210CA9210A0965CB948518929002C56D59C04DE0C04C54360063426D62206420C8815C484511037209100C14122964008508A225C8068E80062A84C89198A411DB302613851023C6681BB54D49066041268501B970E3B005C424458C8425DBC469A2A45011914DD1064261080212C9010AB1240035658C164A10358621A38050284021196543000C03174800394108B448049571912481A4982D1CA669511090928845194642094226D4B42842800021028423294A51284DDAC690D0262401B26161C0250C8265199290A136680B0689C9B84D02948002227053386A0C08885B962899988419060490964DD8C86119370C21986D8848515CA6294C042A2208441AA93111C2905218220C454EDA1404C42488C8280C20433259C668803891DA8000249301C094089A008C53321220C468CB928D623881E30426011505C2145181488D008244A4468011C38499A090E0A425133510D14088E394000A271108C44822362D8C004D4A86512430242405818C4624C9348598882CE0B841091612204968A1C830A096108348106332068022610CC491803062082301D88045DBC82510C18C6486601909910BB3480A244A8A9870813031532881C494111A88605B828C0315022017901383641046890103668BA451223840C002458A8011A032101C35514A481091488021990CD8949148B29112282A224440C3127281920C12B889524024C3B0655C8209D104712143710A326112389213042C9B00820431000CB344DC1010E2B82859982C032602CAB00CCB843113C6200331280AC061D2848C1A4110911430D3388CDC005262C0858AC660B6B814546CB4270B543A708AC86BC1CE481601287A65C59BE8D90379B0CAA51F6D98723C5BA4787DFF8F095CE307869084EB4783EDE6ECCF369F923E9F435FBC1E5AD11B5E20159EB53B41A0596BE86945FA60133274AF288DEC348188C166BEF153321723169E4BBB7CC6CC2DBD6158374E10891EB82EC47383F1BF3A103B912FC2A929461137DC00FFBFB8D5A8884B1702D329CE3EB967FC0B1847DBBD06C3CEF44CF4EDFDD34E9671A3B51572A7510174D26968B869F044919AC6CF766250953DC9F4F3D0B28FB6D7D0F973BD3944B6ADA312044A09EC59E008EE8F92329776708916B1301D2CA52F9F571EE458AB13D13EDB882305351E3A1B41FF9BDB54D1BD5B768B7AE758EC8CAC4668582073FEA7BAE86D6ADDA4A4F582E7C4C298178DB1A5038D9D337B1AC18BE442865444D24B0D2443D6200A6C938963A812F1600D3689D8EAE1D668A7A0C2A3745CFF5484D0E1AD2B25A9A70CA3FB16D423DB83318BDA289478A5C44C5F81253AF25A7EDC4B35BD73CBDF3C621B0DF2ACB9B1D9C5A87CFF528D0C04F77A31818BB36492F3445E250712BCD2A0C2D3CC3B1BEF6AE9D1F4653EEC35E2C34F14CD872172FA46ECAA5824507EDBC63A5D5E8222308044C6A0647924F9D1B8AD7584EF56467A4531004AB4AE1D48203E032A1B83CB53C8BABC556AA6163E7DB321E71E55DE72EA992BF47E0F70C2180325559C33F6A0F9677BB801D99525CCCD1738C19DE9AA91A85146761FE773255D8B6BD41DB2515C23444463616F14459536703096F595E841B93AE455B9F37AD2E1A5710C83042689944C5C4A39F944E98C07D898C59F4BBB9DC8A4AC6F3789286D8B61382994EEE1C7581B3F2D12309FAC0A1F5B5F02D0C4978231D52D57D3D56D8F12075F4145270A3DCAA543A008F8A39D95FB555E1EE9D2C9F1FF557FB6C38BF4050B6F59C51C02203046ABFFD51745EDEE1B5BBFCF7A9BE1017839CC6A4638F4316DC6CD63009360ABB2B6B02818C542124B280E18A74BAEB9273B3F2DB8111CDA487DB87A18DFD16D380B037DDC8E60B5F1874D37F704E1A8743D51259D9A778DE571EB1962ED8A07B641B21C274BA9D1385B6406CC3D8ED00B697FEA1BD10967FE481EDD332EA30619655E0A454D58E59672293694DED52C791ED09E2BB3126EF1FF977931C0116B67C91E038FC70C382B28DFD692B1ED75A3B3753D5859A46AB0159C7F9FCB7E6CE9CB91C13A0A3D243D53956E444E7EA734724D45EDA455ECC7C3C74B2A2C4214C7D2B6B66B1BE97C7D6057EE64794EE0130001CFB597BC8B5C0C3E4D159E76F6409CD2C8D6ADA7F8BE816992B191B80FBE9835BD3EDD60CE62A79141DDEE46673B189A0F1CD0B103A66A6B42A3D9319B92761BC8A54F416AA8942E780BE5B70262426B11E3AE9EF12B3FB3BB884E3E230471C020DE7FCB92091396817AB83B9A7C40D53F580AED146CAD8C64BE7E0B5F84F0CB35A2731B710A10D784874B5CA4FAA3FFF38536890F3E48C5B6BA96BDFD22A8C02FBB2668D16AB52BF742D79ACAA94893C81C108622AF5B4B0D1DDAA009A2B1205B02D1B8F754134AC4A92E0669278A0FA2119C62F9F75763FD76CD4712D04B00042C00BD8E4DF2176918F97D83C03DAEA19FA30FDD16E1F9FE534B444C7C4A3E01C2779135D773AF35ECE0A3CA8CD3F3530760059580980DCA09DEEE0740F5D83D69DAF36A5A92D9F4096CBEECAED0816CE1326EC1804C54584E8C28355E5D00795838907B20CDCFCA4FE18C0D3D6E0DE96EC0A6C502057AF96C61A265DDD8D874E4D42289FD04F9DCDA6C270E7C53C3A2B23B20AB13AA8E3FB8B0DC77C0CD0F00B6C2FB8A36D935356E10D51A20E53739A5BDE93F96B49ADC09AEEC0B35EBFEC815880A56DF5B1D110839A9BF7946576E33C226964F6075987489DF3A7C0B574E21A219B670E074713ADCE8E401969B6D1A5D2EDE0F725C0FD829AA435EB3F4B9E689061C92008547F4AE3430B259F557E1A2DA041643FE2FDBC8E03286B50EF73D6DCEF0B9C6C75AB40F1D2F8D4CCB6725AF56A37044A3933923FC2F32378855CC0FBBC0327F25C16C59285BD19627CEDA13CE715E35A689B67DBF61C3B45C48FE507B02C4C2689ED5CA3D76418E3C2FC5269E3525A7C122A0FDD0E00CF4F960D45513C049223084BC5519B028F17F94A3B7CC1C407618935F248C3FBF0678F2A7A05E8A1911059264409A8801BBB80A3AAF8E0B6D86CFB3775F7F9AE87152371C6216947E89BA04EF44E8AC304B876028DAAFB54C3FF067029F15AE768235BAB8F854009110645AA801B2904F6939014BD76E5AA510BAB9D5AC17BBD536FC32CB2B4505A47D8679AE67DA0304E4982F03E22E77068A23B32192A24569D40356FAD23B1D79E40F17F5D2B0DF23EA437EB2371CE2C7278653A884FE38AE0CE9D9C60F97CC88E3CFE5AF1AC3A1D22079BF9FC2B42435231F110DB596581B44FA7E31265BEC9FF7C86EFAE208B898F36302B66E409184EEF82DF40FD60D6A4796C071C088BCD95E8F8AE857047BF83CA41EC4A845B48E5631F85192FB998067B0B7172E575D6671917363064C08CDFF23CA8499F240738D730DED8A79CF015FD9FF34D53A0B6BD0D1DD38B32AD0B3585FB99AEEB5C11547B8AD365269FE96CC855E3E7E5508930A639D82BD105867396D6074A6C2330A35967B1914FB52AB94F44E3DE354D8349DBC86E444B5165ED20376B11DFC9FA5F51F6069FD743804BD04222E22A79B54603AB0983530E1101227F8BFFA3A24E084D452E1DBA5B5FEFFB23B9842395658C38C7970405E17E0E8451AA188BC920887B35917159F83D7B187227B26B659D168EA4A2C8FA6330D372DEAFACD8854852F313618DC847C56832CB2A3C8029C5770F7D7D63CD3109EFD2725F24016232028CB1666DC9F407040806AE63115BFE51D2BD2D74286B205557C7F58F7EFD4755C53E2BF24F3D9F97E48ED86E2B7689B385BE82849DE6CA634963F2782436ECBD35F58EA3CEAF50A452EFB16F6072FA1E9A10B3E948E5F2959C4DDDD89921D4CB0214AF3149B7FE5E2DACBD9632720CD06B4B210350435F663C4562424927197703D7ABCF4F278C4335C623C55D8021B7A5766854DA7AC210F25A326F84E0BBDA83495D44BB923FD32AF32528A68F11C7557F4DE631DCFD8C233F473ABD54C6ACF3B3E935CD6942495FA61211CC158B7C2FEC84F923D6C4F902A8A19B46A931C68F420260A477A6C3A28B3B4133634EB5751E3A7CC46022B706BFBE01A3E062284C2D4A8758ACE690514B137FA480676B09EDDDD309D6F52F94B2D0287270CFEB1A6E663B762080ED4C4769BAE6C168CBA07AD79B1A1690C5FBE0D9A05656D4E52466C906271CB7C023A72A2F015BF869446FF35E9BC1A59E23D9928CBD1285512AECD6C904CA47F63A8747FE79AC8438D6C26F13FC4549453349441D959B66DB25037127C036AB356C8CF79F99F10BE8502734CD91CA6ED2F543F2C2D5412CB6D16DF798204510CF5A17E6E33397B38BCF4BC57546AF7824C0B4DC7D107392B97730CDC0F1528648FED45BCE3443A44BDF1B28B31FC8FD17A1B4A737CD28F927559FE2564A3018DBE808D3AB4A4440527825D2013D487293AA875E5E911510CB8B56B04099F96CA23C62E72C2156EA08B6C7CF5E45C869BD2468AFA718C7E3B73C6D02C7FEAB0AE69C233F0E46E57945C4D4EFF7796285E8988B51280323A8E89CE7BD8C068B0828CC0BEB77C0F44E28C5E75A21853AB9D8159B0E2255C5DD8F5746F924E237A4A8FA3745F5CA39814EE64E7EB1C94DC7B4A2889CFE7A01690A89285DAE12AA6CEF45805714F05BF0FFF97ED82E51842B099FAFF2F0C0F2C608FB3CB6E069D276714A21D1AEF73A870159CF5C56CEB3403D96F4AD1D413D03583985068349F73524D66760A17AAAD749931870581BA8C576FF6549661A43529A2145739AFCB3BADA0EA472AEA14986670A97FEF749F520054CDF4820C191E5D94599D95A9050CB45B6E8E5FCD28816D331F21FF06EBA6C0DDC495AB8F1BC645386AD1EC65EAC1FB4C4AA5FB8A301BCF5A04A7D61A8310804475CA128824C767426E55EED148C766181E2F2573149C2AA36496563A4497DD9244F9B17791AF92489B0BE38BB5A778E679B93BE4BEDE0C06B60A048955A0F598FB16256799ACA1CFA818863EB852A7329FD13BB9177B8653E3EB32D6C40601AC61F69FC91468737480C6C8D422755D2AC35E410D7504E07DE414A7FAD9A00CE495C84452ED9EEE7817066DF613156995D4132CBE14F1607FF63BDCE71849C7E3A20B5F728EEE14DF98C950706E97F6C2E340300431EF2A6E0FDD9B2EE45139C2DC66FC4FCF8231A86B9F498FEBCCC3E87F19DA17D09FBC476C8CDF0870775891CDF0C94411FC686FBB54C9EBB8AC22BC43AB8A72528DBED5AEDFE87CC534E3127CFB22784BDB2811B39D20C29A0FE79061A0CD54787EE228013EFA979413F8BE983F7D9EEF5508DDCFBAD3F4AF8526291A1840BBBE247969C8EA5218778571891783F16D84E517B7CC7F1A50999A23085AEA463EDFA3AC16AAE8ACF4670C69437821C57349A12F561A87218BA746065666A7B76EF92EA8ADA926BEDC8F25F809F4E747F92B7F16FAE68EA88BE10542DB5ADD7042E8B26115E2A587C5BE310684AF723C6BA4BAE47725FA641BF4C0218F5315E5B2EA0D89F0EF"""), +f5e15972ad2246b58dc056182273172d39b05662b5048af41a6516a04e042cf25c9c233ecaf6416295430b3e77e8bc81d1939c0c6a6304ff1b750bd145a18a2a85e53116f2d3ae39e39afb5e342b59e66196b1155c886ed149278db268c22e7202ebd8ff6da2768ac4d5fb15b1f3307ec53dad5e6ad6db55255e7460677ed6cd8ac2446414600185000ab66d1292600b8120ca1611c2486c628828099929c2a6640411651c164684364adb887021348c094182da0664c0386263020e40926404b8410336228a046292421111956800032dd0321014832001122cc2042113100d6048650b108ca24428020865e3022924c28514c34580a864c4308290c86181982912014c92308d04901001852c44402a59b4414b022c49822100329199b00dc204915a082da42245e11632c84044ccb82488469022b66098288ea2a088da4432c3124ea01469233546134708c8a66dc02825120084cc868901a5311bb8500b0046820088218804a236481aa9411a0351d1340900c62861384109b081d1208a9a282160448818996859c60d011829429485e4a6900b9129210368081545240522d44444a002121294048a3840932852019590410870cc068ce4380923828512090d44b20082b8651ac42c22922dc2c03119a7259048208a0286e4c24c1c170224c58c02174a5a380811268a19298a08232a01010502b361d39270e2b409e40830a11629099821c222059c3661a3b050d3844dc92431c03029d4400d2443468ba4645c36054cc828a1b4201c4706102648a4466d00a86848b26464884914454d23b1644a3440a446525432521000911b4580a0b4219210311b802491120d1a16110c432e92122a1b037012111120096d1a252189c40d8a2849e1168d804602241170cc842462b08d890068d29004022884013421dc8401a2328d58260e49140244b081140946e2383089446c1a2946e398459b224c9238000915401b956523098ea2081208937021264903210621c79198026c1a4869c3424219908dc83452923650221571c4125101866cc3829058a6480c442a1305066338919c422dcab431a030298108110b425120c42010b28c21388e9990491412105986495046441cb405c1b8501897840ab9240b3260e2c6059c30628c48211ac78800182c89408881484de0260d1044108b920820166c12381019b78460286ddc328e4c04099a8450c396659814814288214a4405948484a0c8045a08040c3529c8488e8aa66d183890d9b46101394941a64549986c9ab20484c4110431914b002508330683487090c251224006d0c84121090544348622b345e1960589009010344eda02515948468c0462882491a28830010606c0b4008c24292436508c14662046085822244c90610c066dd8b20054906d8300919118259a04001a014809c42d0c088658b28ce0984ca3060d8b162563002e20340613b93183c624442884c1140512354e58028e8a8849dc4266a3b0210b3690048988da383153b6105b124e99182c8924918bc80ca1c48d194751c9c42da3a4911439241b19819a28868b320e48c26483c42143c6690907215c30660c086cd2b88c19c9004286054cb28d9a00295ba2401b3409c028129b285003a96c20146aa2044a60486922170ee1b6308b186cca085114b524643800c210055ab48112378c12420423c98dd0a82c90309124164e2496840b1924009300181160e4466219a620d3c04de1c04510301193202e60086c2189851131309ac84c9bb230244001024384ca245003c44158a06021b761882091999805d4926954a201c0a4288ab42d81a80853086ac8002614c12cd30825849024d3c40023002e08276d1c270d8ab86861a62118a648e230248c862024a584598804d2c849a4048922394c13000c11a310c9b08014016284448911b841a3c24d62a0890b861123146524006199200e520830940890c0c001c436600ba791d98601cb268292c221c8c668e01864491088520865e0062c18882ca2006a64c28919196c90220514178dc8000a11a6851aa8841213440b176959c02590804899260448b670c0a06943089212170554c02522000d1b360d01068e23376c1905648bb481c42202c824080a002e11064c2335725b1222132969cc2030100725c010821c17500027880ab70443a68123a82d0b8149584621d2c8215086280a896c233282440648f7997f3a4a02dd96ea05f99886e7035f7b872fd07fa322f21a3dc47f787d9914bee7c696dc22a45366e839af8eb0bb2bf61719b225d0d53ec79c27dbdb681f325d0a4c58d4e86f7dc0767a4d3f20e19025679b924d3953b1213ce7b1a08fcbf127dfe860cbecb06b90ff62d704fcfbbc0b7478a4e63e14ead7ee05634c7278f7d659a8706b0f16c40bf909b18f01bec20e95437aeb585899c0bb0af3328015af0aef1f14029b01f3a7d9cf188022296ac5501a61a6145b1ae36eac142b5c75fa314fec0a1d482690fe98c0895a042e2d893f42fd446cab8fea7b6f2eeae767abcf521aeae0620a7d5c6d8693371ff320af03cde468166b0b592d9cc188efa31b42b0e7eaff7356436ab7382e0a12a57aecbe989fc249f6c0dbdc11441e63b1dcd707eee1948df10d6a2521f8abd525ea05987867e9ecf3a1cce6b978ef0fd869c8d0c0539b58f3355f0dcd6ec6016d276e38455c67638572c6738d90e2877a6bac552cbbc596e474d403d8ab8ab69f40b7c694179a5e7db3664d4107de70c5ed848012af5edaf718380da6bb3eeac6250bb50d1b994bb96524e580cc3413c9e7bad19065c0575906ba4ee7b582be8048c5126ff2c45f1be6eabaeeee090c1fb716e16477cd029bba2ab1085fa4afab3481ad0aefbb216086c6c4d82986ab1f5d4695fd2f9f2488f741346a7fef2574568d0632a7d1b8ba706c849e524c0cbb397e18f2085c5ae5cbe2a829b3755127e35c2db720194824dc40e75144d764d7a2ff253a6f1b109a455e319c5ab28578121d641f41af2beb6bb71514a84efabcd56c19319e1bd3468531e8a4ce78c4f1b89164ba170123ff8efc61f01a92dd9a19027e11e2141ba7b4211e47ea5206608fa8fd9abefe0995a6857dd0bd3ed0cbe96cafacd110cf3233b67e8daba02a1f28c14529676f9902a87bcd0b05fd183ef4ed1cce31527cf25a30ec2098af07d8658e789c2b94aa9169708ed686401b73d828bfbdc8e943c259585da6ee392853c1f7fdb65ce2b5871f67b38aa35cbf851d4c721ba59b3a49e251e533f92c40128ffcc3403feb3d66b342e3fb58ad621e86ae4ea694e33c24e132ca123be19bf33f933edee5ed9a5ed6eaec769815eeffddf1892f9e76ea0893efbc9377366eabf1e32a628e26a0362451e4db704d1445f4aef183c43ae37d9e96af9702e5287275d2fc2c563f6a03528be62cda89cacf9458eb4b336ee78c814e52222b503dee582fee523473b97fc08a41b4f4068db2ed9ff94527c38b3e4369b702983539aabea9c88aff8f7c4a424f45634ab5258e3959681bdf1a038777b7525e53748abe024d824db279ebf2534adca871fe186b3bca61769c065486cd8c289c9b88cf6500fe7d691e1aaed1579ddea5f149ee1b4f5be1ec98b2978a82b8dde4a79b799fe6c98c7f0a7ab2aaa4d103e484014d6b989f560dd2ea6d9e6df9b1b267ffa1ed895ae6bdd5b13f9f0a4ec1a5d65180119abb4a841ac1d73841d481c37ce1b40b9ddb5bf36f0fceb9f33e98ba0cd4b57fe9c36cbb07a104c2e0b3481831ac2da6824edb76277e9c06e48347184208e4137498864dfaef57b45232afe4170fe85e7dab426b8f918d34ae28043f81a914062cc5e35d761c701ad6891ed3d008a800f1c63600690f14ecca044373648a0c1e7f15bb7655c88abeca60883f275a23e50de845f594ae839dec8cf9676f3abf2e2223aadcb68815d4519343f73e551ee7fffb015196728977bc8c6addd870e96bf439b37ed849f42ae9ca1d850b601c74382604d484c742874dc35ab740df13473b5bd55e61adaa012c5dac04696df0fa2ca3df9943ecfb6a76bd8ed39f185f45503b3dbaf7d4582fcb7a3825f3125e1c804488474cff917eaf61143750da50136311663a4fd4e8a9addc415ffd694c4cd7d4998c057aba4adf6c07ec5b1f6d622ff3f8f8d77deb65bd6c088a47caca00d551c38a55b6b2ecc773be718719a6355560d00686a77c68cda8efeea442026d99badbaafb6a861f222d6f9d7edd75267f5cfc87731801ca22a863afd7f4b394d90af2008fd2e799659a0843584bc6329b6a84f7ebdb3c374cde50f6bb5f9884b39830c4409c967654f5a64a6b8d7e0e316c7936fb84a3651eb5bce7ba80f3ae6093273dbd3ba337484720712caf9b3cbf191c8a49968c1e5e2499c4ade3cb350fa6049c491d52c2ed697d2d70d62aeecce9ad561547090b7e4ea7ffa0f21bed61468686f75303721109b440cc8cac0814c293bd9b219cd86843e6d3ed498203e7ca8f4ff82c9cccd229a2210c7f32e7b0a6b0646b8e4e9617707183f0f5edb0124bd0201588baf7e8b23fc7bf2d7aae16f54b37c963b3660a2c3257bc889ff9d00de92e1c2da98e25ca31549cf854d58af17fe346f0ea6ac4bbefb393f5908f1b64254e6176cb28fb9dfa70b7a0462cdb263a2a46858d1f37dba969e0226ab9af0b22a141e52bf8c0ce9f7234194a462deb924ff4771a5beeeb6d5686121a5fc01ac1ab9fcf701d7401373fdc2af3d8810a6783d3fc175f23f85a113bef7027057a967fc94a5c93b60f15b1d87d1be3d74d1d377b1604536720af47f6a7c2ea931a9fc6a0d9de8c2cd4c9b71c7e653a67b7aed5a8c2d0ce3c4e3c51ffe12357ca08438934952de8de66ea836a90b644e6a4241da70a15c08ca9f74bf3fc6d7f5eaa7cc2e8abcce78c8a19aa597980603ddff36eebed77f658bbf3d5e7498b16668bc8956066f3f5c64df78c6b9301834c91943be35c6e4f860e7662d1f6d9b36fa30a4b23322e6f7b328bd86e92da8937837fde1766adbdf647d7a2718f5447536280bac48bb1b53d884327b7077e17c4de67e6ecff8e89f18afb82f5e2b2e2dc7d78f8273affa55efc33e73935ca0016933259fd09e07d183ff884298df3aabf7e7907b08e457403cb99e99ba95eb854234f5593003cfe661daeba368aa456f9408b46f7ff92fbef9886bb93fecd778d09c4f43ffa5fe88f32dc4a404fec7a6d4b368403c38efff8d1758049a778af5023e626a01046f36e5c569ecd3859781caf50558cc8649301d0fdf323042834d7ccaf212ee8a4955fa9e4cf65ebb2029a0835e5db69993956956545de4cd1715980ff554a160e1f3e48c323e35b64274ef64bc7106c15e2f9d41ab4a92692a9f6edec8e66a73c2d4a6ff1a881e63163764fd3cbcb3f5601a84d4c26bec4fb978a3e2473d50bd561c08d16af2542a49851c8f63e0653bbd6b489799736fa39d8707f477218d918fb283218619bdd569e52b63fccc6e3c859a7febc7196326a69143af3da337cf0653a5d6370a5323f6c31f8791b1d5e55032261c5df8e07b8df185a31a9b398abc345b87ed8198555a0841e0927035f5f3cf5da4fb2c0ca18b1bbbe3a9c3b3df9d1d448e242513f5d0dd481d3d586ef61d5b857bbf2d1f771a2aed0ef2bced9a6d0bd576c1c8bd2e3ea9ca6a6b6f9e8296117012d48af013b1a607dd70fb2edbf409a0a9d5fc0a438464c773e045b8d124a0c2ab99b26f81afb2dd5d11ef44aac1eb1242de61af723667d1d25a349b4d842544fcb4e3bcb45e0e9563039bed3c0f25f6e3584c80a5c19e4f5c83929549ffc9f9c2be16c4bd36394ff69634a1550eb60c53d7b17e08f21121e10e2d792cafe97cfacc8ac6728d3d0950d3c33c5ddeec089e979598c6839cf981e48b5dd11003e91564f8bf52d2d20dd61001d3fbd329c22a89b6cf70816c268afcfc3576a29285c9123fbce1f0f6bed472a23d9b09f7eaa7be73451392f9130c7264ce87b942e679af7c91954cfe529869555a4cba8485f9ff3a9419649477ba45c1e7e852c3dcdb637cbec5261c94df5ccc30e904bda8413c4570bb978abc02aa0e909bf74bba0549ca34377ccbe36f1e132c074244926f0008671c9ca6a04aaa8f8466eab60543f5a0a39826aa231c97ee6704d685caf2873d918ee42ca7454dfc30746b8078829e8c89c831dde2ef7a6b2e5d6038ceaf4e24bab7b4a54792b58cd14548979e0fbc10114fbe23804eb997b765bff34b162a354a4d9702f4acdbf46d11b679e0f423b5c6e942bf5567cacd39053ab5512bd6e745c9073911f5735be1e5289cb7239ae1c784074e76d9364ae0f6482c1a31692156cdf4cbf4c140745cbbcb3b213ab1d8eee1370e9174e62bba205659507b195bda05b229d00be377c6697fc35cbbb14f9ddc32ecc66357321c915041dffe20be5a6d71d5236fff001ecc4b69fe08bb4533498e00695f6dffd34564e5c69a63ce0a0492b40a7aa45d0a6c90d6fb86f8ac006a1df480eae6adf7c78ae447ba7a771114345972d2cda9a0af25ffc15ddcc243fc2e90fdcaad91a216bcdd35a5f7d735ac4048a72dd510c6824df4098d9ffd7d71229ade24c5dfdaeb09070c99bb6b84cc91d1bb754e963e5a0d88a04282620102a5266a5f0ffb43a0e41e4370d66474ca6bb95144336a4c54bfdac1e59a678706f6bdddaee602c9bd3c0081c13dbe1644a755928f206a9e28006b3db33b6f265815e666ff3403d118d41c099c5be988332141bb73d2ed7ec71b3c2c4b2541b9ec06c3cd563c5e7ee8e6ed289be91969ad646b1260b4490aead12ba8f206e438f9260914f9c79549157455cda2dfbba3b4c1aa48de004bf002f366afa46573acce2c54d863c865415e887b18f31fabe9cb109c222f97097891f4198776cc8d710526956"""), TestUtils.hexDecode(""" CA0104B9DF99E87474389167359968A307F63AA32F0C804A96B18FFBE00C748B1D6894CBE2B7BA06EF17B6947ECE31DDC9F614348F01995FCCE77099A0D88B2BCD1035667631991C2BCAA4C86B4D31074A2FD46C38429B52CF0BFD7CD3E5D194DF22E2B0D57C0C9D624C772B54686AC963447E716C6B4DAFC00AE383CFFC69A2F6F931D616954BC9A140D785F15C5DB28ECC793D88C78D11F8F8452046ADDD3AD26988B21BF895DC810739FA7C45A8062B2931AD363B0C7EAB4CCFAC71CDD0DA3B54CA9A6388DCBF79AF799446395DC7A5B7ED1788188E9D03EB3BF7B80F8CFB9B7F33DA0D4DBE1840B9C6C5D80F6AE64487BBFEC86C596E2ED8E721A11D783F7552A4B01FA24F60B5B683E287BD75EA0DDC15314E014D402F527C5DAD74CFC49B4D824EFA77C359B90AFF15AC89C1AA35959570E2148DF7A09E27E2FC096AB5CB306B4868AB80A24DF745DCF9EDDE57357866182A9AF50796EAF97A1A1051FFE6F9038BE1F6239CADBF0BD81B23E2991941F34D0851AFCEBC4D3F8B472D6259CF61FFDB87F79928C66E69D969B254D57541A87C692160E5D58A837A1FE90A1799758A70F958DBC1BE5D6E6836845940C75E745245FBCE59D1F83462B9578534D7A05DC3F21C34EA93ED78387B32DE09ED3CD2A51EE2B8F7387C8C2D426EAF3795E99B158D467D9A039234FDF207D65D2577D1688E1B1E72B5EB096FB6377DC8EB6B3F51900380BEA561C03D546EE242EB4264C0369AA2D53B2B190E0422FBC4CF896CD549C2A08A37070331F15A9ECFFA0E91B1FC4D5157418914308EB8C6A992B197F33DDD517DF4610E88F2E35E505BA7C7CACB8E76677CA9B39A4094EB4590F6154FAAFA76C1D95D4072B5CE01F42355C47AFE569FA80142EDB49E2ADB34D3C356F4D882A52021C5216B3678AA6A5D52C51CC8BF09E7EAEDD2501A9886FAC977EA5F385F46E8718D39073D8995D392074C2525A4ABBE228F531E6B16AD5BCD5EF5CC4C3C71AA77EAC1747E2B763D0B3D66C7F35458BE43369BAA0ABED23202B733B3C7A111F9CF407A7D62EFF5BE3A5DDC3E49AF130012BC6D5D3641EBF268236473EAB09BE87BAF7707546B7AB194D2ECF5B03A56662B1D6462898DA94747CEE9DDA08A9026538D799F163E1E771EF7EADF8833C0510104FE7AD7EE75F44F8D4572E299A87FB17429718C576B29983B50FF81F8D48D41CC764809429A7CFE05F68168B6B36FF66CD75DC0021D774D07BC716A74F9450EAD2995089FEB89D1EA73A9CEB83155ADBA737B3DE33B6B617EE7F5CB6C6672AFC439990B612A6AE71540FC6D7FF535FC88DED0E6A80A484735F63209D39F12E6E129C4ED2EDD8C8B5A24472B83A058B0F1C86B7F4C53D88927C7E9EDB5C40C5D6C7F0ED8A626C5F35E1D3981936F0F1FE4E8CEE0FC7F66F0016B14F3D1EAA993A5DB9B92C03D99C0A867FEB343D9F43BBBBBD85F58B2380811CF153FE66E5B5DD07D5A87ABCADBBD472692358777BF17AAFB622D487A100062465D9BFBE0E63B9D862A02F09E371EE820D969B29B4E6F6A1120CDA9F9E3FB804B26E2E9C3DE219044D1D6E62A28CBC90C262B76914B8929465FD901777F6F5C112D196A002A0F4C4FFAFD2578B5CAEA21452968400DAD6490E313D32A708A42F64E9CF412EC0E358F6B833EB0190C5933037202C266ABAD212B570E609FB7D338AD3F850EFDEE9347EBCFEBBBCE90E7F27372E244C3F035D4ABF1008055215E573F0C4001FFCDA5E6B6C5B29B7F59132CD86481FD0E1245EE4084DCA3D44A0C9E6B6B14E1BCBF56F470F15609DE76588795D5CB62BFC9C253EEFCC155C116D70CCF9112D8E0A801A3C640C7D16634EA02DA9DB9AC57DC2F7D43F48ABE631D3438C2BD3EC97832244E81223EEE47054878BB2472F64E9ACA0D5A8B0B04F783C5052E0ED6AFADA5274C94084621E989084EF9814128226346996CEB6FA07FB957C7432878505442FAFC4D945A953336F9C92B8ABE4E4A092DA65E2BF1A7A274E1EE9D7958E35334D9B7CF8B314F0AA5C45E93111460A8F5409C0BCB842DF9C9887FE4643BF8958CDB40EB66438BA53972E359EB712BF4C553D871ED702F74C41D1217D7887C891E49043C0826FCCEB2897BFAF9F217DC9F566DE1C416DE9118491162113E2EB56CDD4C024DCA4A33359D88CB0247BDD6802455063DE9666A4C52075359316B3B557D42B7C99700F55CABCB2B802AE4209C6B937C798433AF94159A4EC0A7DE00C809F6E6675A4213A1CE8A7099FB7FE6A0C7FB383233444B64AA120BABA1C4E61C6426001184E897A3C6B0BDCF9759A72146EF848EFA65EF09076A4FF2E6DA518C5A08F2A2A12D904C893297234E53CFFA04F285F350412456C9A13E153421D65DD30B236653AC13CCE3D5CF1EBCB8AB46808414BD3725987D6E464EB4F97321595153DBF9994F7E19AFBD19E9BE929D18563789567B28B1AF05BDB5D2C5C289FCBE8EB159D0017E09DA8FE5E9D49D3A231814778370DFE703ADABFB175859A895A6ED86F9B6B52CCDBBF936622C5E5A01D50E2B6D5730EA4588680EFCCF390211F211472F9E10314482CFB45A24706BBCA8CB515B6A9AA6EE1D2509E8F9AE9D6F545BD3971A02CC26699608FE1F076A925008AB6CA8576CC5A962326A369BDA8ACED3618F02BBC55337FAB2D66050514F904083D4386B43B6EAD553DF5603201C6D684F7156FBD2D3DDE3D7EB0D569AFD42886E57B747F21D44B88AD58FA2370FE6BF2DFA4D94D8FF983A1C2B89876E75AAE3828D1306DB9A639D052EFA6A0EFA0F61737CCC45E0C516815E92E256BA49E7853F9E9D4670593BF9402E59EE80F6CDFF8244D156FAEA8220D483601794A3CB5E1D7B60DCF991A545D2C72F62E5EA05BEAA77FA86A80400A07B97D8159F0EC170913ED885B578767CCA7A5BFB8BFDB7AC99002555145D9DF5011654700D6FBF2EC2BA609C969EBECFCC0EE346FA01B6CF07E6855F3C832BF1DB6E247448438BAEC055FD41CDBE921E5F62D93F4E7964258A9CB3991E8084BFFC2E5B29BD1E32A64E32BF5E27416CBA7FA3DFC143281F3797E1927AE9D9E07FB424833A7911C23F231D676EB0FB061C179C72FF0038E48068D43A805D56C3B6A16F5A2E5E8457F1A3E0F927A8880CD261F0D0AD8F82EF0E52E1BED003661F1D4510F7BCCE680CE84A0181F046366126A53EE67C7309C6982C28966B6CA1F324D03F5E09AEB111486C44B6551B1C36E84C2A72F78AEF5CA31AA66EDFB0792C00579C0C7C1FAE501735706CCFADE03E9A0847E498A24AC1DCBC7DB8FFC946B8D914633559B63E3031C214414BCC1921D2A53726695340648CF6C2BB4FDF132C77BC39E9CEB2E4D22EB138D807D7B79F78CD9713F5BE7512FD32E73E886DE16A9B1B19026B91EE6AB92DE4DE663D9774344B283149AF4890BFA57ABD1C9DFF128F9F169E4CECEBA0FEE1C33D4E34B877EF04DC887F7109B2BA65EF5732ED4B7C6B33131EB5867811D4A8A3536102F5AEFCACAA681A6A45A3BDCB24C4FDBF49A134244044E2B424996CF6F3C514C77EDF2AEC177B8F80A1AB77F6D3D920E508C76EB71ADFE2209A132839E9BB16BD9991A545AA0587B7594E0422647DC84CD355B20983AD582324D4F19E33E9CFA5CEDC739B26F43BBAD1F165720306F48CB15B23B961E5990C2DCC39E5BF58A9BFC10829590A7AA8F60E13EE1DBA85EF5EB9B1F6DDA891ADF7357E16CEEA4ACDC00E20F8F364AE3EA838CB4A0FDCCF8B439A242F8D18B8E0B9FB8E074922E0C25922CBEC46C98A82E93F0E95884BA9853CC738AFADA3F08BFB66C17DE7977EB7CE5495B8620B537B49D1D37EA4B3477B79759EC7D9AF17EFDB2EF89945D453BCBDB349CFC623FBDB8F125EC492CCBAF30006523B543B6A17245CDC5EE7E28EA895654A5EA74781CCB0F30343C73B4BB88CE07BD37DE9220712F11748EFACCE925626FFDD8447D37BD9CF2476437C093BA4CC0AB674E4CF9543CEA67BC25B9BD56946C0D077F0849796EFB74C7F66D5B86CD9A38B8138D816F677CE08DE6A6A911BA4DD1834751548578CEE4CFAC50C11D685E52DECB77A475FF5468C38DB23853BB2118C78AC3D52079042FB7F370B3D0406E402EFA6432D3055C572C81DD999876E8306021118BA87D5D430E4AB9C24670EAA1274ABF4BFB8149D9067C427DCC026A61C5B724CAE1858ADE366FB42CEE52C36F0F99AC02E8BDF784EBF311334B83B2B277982519DFFA3AC35D97F9F30635CC17BF8E017EC4E209EAD104B52C58E8762052CA62BA7A82FD011860E4F298D889A11F6A2BB1B4157CDA42AF9CCD0B5324329A92CB9FD6EB81DB3FC58431BC5C9A6DC1B07F7D2B00B32E5A39960C5E2CD69CA2914F23365B518ED746B27733D713E8ABEAF9D1FFC6D3D9B601FB386A6911F24CC818C0353658CB826F43FEEA792055720065601F1364BB6184699F16E3EE2B359CF0642C85E9115B18E55482356E2F91121C5884578F3D2C45462E47A3D477B3D63448A8C1679E68F9B7AE509100B7B2B142FB6BA20179E599259414520B02B745E592FD10D0D40D780A95C164D651E96A7052B69BBDA979216989A57506638F891336E2EA123303F997194B7AAB4F22CB192AB59A8BDA7CC88D0F43E4DD949146006CA3F91CF28535ED42662A61F630AD6E7319A7B98FF5C7200FECA768F14BFD43BD60DBEC814E22C26F1A8191ACC869A6BCE61991E4F36148908A5B1557A507C407D73A6FE75A548CBB8CACF13E57BA6B01FF0DF900051AE7C0C346D5DADE5F1C1BBFF967236BA5BAEF19A70FEB320BD76035F3A6B11383F13E6DCB8D1533A6529C98334A3F2A9105A5CF1C940659459C405C197130EBA44F0A2881B4614B7A0BBDAD5930DE5C3389A7349265629E29C0123CC89F3F540FE5C9019662A4383A38248F22201967D908EB48D530D17D50A08B35FCAB73AE8ADFDD72A8A7551EC28C7573E2B33EA4F61EE84C3DCA33DD5861B8FB7176C4AFBC174250D51F86B1452903191E39EF099C0CBCC15B3FB5DD30A2822F68AA37D59583BDC1CCDAB1B2E0337BF397647FEA9111A5B94C6A3369E90F3B86C266F4C11C9A7D9E24802B31B5F93B8EA9AEDC6C2944965D6B54601311D251E81C77AC1BB2159263D0A92F377F111DBC8D554C3AF747FE7E82A6E6BF0E4E3743B7AA42C3B5B8D3E5D9C3B427B3290452136E61592609826F4B61D4960B7C3784D0E2508363212AEEAE624489B739D0573CE23B35D30826182DB5F4D09772582E4D6B61938041344EA434614C21B01530327C08539A84F03275D0C4A77FDF230FBE6639CC7A12C34545C5CAD34AABF8E25D64AFCA8206948737DBA643867A146F17ABF81A926294E2368A5A2F0C381E2C244B21843E3ABBA680CC3F1F0509DFAFF4C70B68C82D3D7EF8EE053DBD154376FAAB5D561A19362314B037CFE18DD03BB817444FBF08D771A13B9D745DC066C89C10ACD53597B74916BA719F9EEEBA865252FE13EDDF97978092FDD1524CDD865FD6AE9C14329EB62B322F46905804AF1CFFC13B46B6AF4ABCB107D44DD27B460101F7A38DC786239E34CA9D1A444898673BB3DD92EE88478A3C539A563CEAF5CF499AE8E07BDAC0CD5419DEFE2977105B5E0138D84A8F9BFAD82F58884377B803C8B68164A3E678648C18127A832FA994EBEDCDE4FECE85DAFF8CD6F44F4CE57694522DC30BFC492BF62796D05A9B87BF13A7D538EE5C55E6898D50ED127E8C12F87D160AEEBD3CB126BC4144A51F685079E962DB6FDDE3BA6D0C8038BD6FD8377C4BEFC2EBF1A876833516D206C2E309C61E4CEAB5F86ED83FF20C8723BFE63D8E480798292E6EC6D418D3CEB623AC6983A3F8A3AD568F73E408F15AB88C8F56F3CCF5B32C76BDCEB1FA41357C42E1215CC503A316EA0A83FB341ED6ED20B1154E5001A754F92E97570F9DA7EA8AB7F2EFEE7B79A1DDA705645ABC5B1E04CE4F922BB03435D11FC83EB580CDFF7EDEB78F2CEBBB6053410E84477864C16D4CD7CD9D16B932372FDB99DBCCE2DC3B5CDCCF7DB86AEC9BDCB8E4F27B65ACA9A3FB985CF95C5BAE253797C8474D0C25F0FFBD151E6558E524C6E96267677EB7A3E128C918CD3B09F1DDE311401152C62B4C59EA1D408ACCC4A12A34664D7C0858D7E99A0327724AE9CA55A9322D865EFB4FBFD37FC79F8D7B2BF08B1824D44777153ED6604E05DB1FC9B1ACCE05F8C53C32594A84F32D97AE49E819029204AB7713AF2AF2C281448A34C69D5F3DC76345031D2CC05B6B26303198E182901FE65710EA95793DC8495F1995F0196DC9473B7AB922786BBC61A91868BB0BE05E2034EFFB288502DDFE2595887CCD144E98ECA4D1E0C044C642396F98473BFDEEE796530467F6B5EC0D5B79674EBDF5D1416F94A8EAC7F4833947F1DE610029779CD436729E55AE3D959F99D5438E0E4407D0A870A38AB31E08F16A06345B7BA730CCF55CF1FDA1E9D04833ADE5FD74A34E2629DCB75A3482312860404F7E75D94D7FD2C8215C6A21BD5FCAE81CF4467931A984AA24B927039526B95C2F5F39AB2040A23C76B64CD2D04E95DE6DD9B8EA849F9F7919A619EFAC498E7E3F4A70432E28B1C5DEDB08D122AE503E98D34D13A4E8A69FA267C3E20671077F977F71308D3EA1AAED5DC33B3F41E0ED981050B3B915EDA07AFD71CFD3AF13A2063813039BE85EF98706399299118D2427A7912A131DB7BA731D18DC2838A116E05C4CBC660895294A73D170C060CD83C9AA0884C5F3FE52F4891C2101997D688709F356A556CE202C571E1170BC339F3E2A75A5A13810E3A2F2133438C1705895523D03F00BBE4F4FA9BCE6D7A14517BD54E281F202BAB40DF35253961DC9E94DF5C2C5C3F0E420AC67A85BEC2ED70545B94202AACE5E58180104E42C5AA6F7F59915BEA69AC10F678D40506AD2B502D77EBE4D05CF8253B4795094F04BBDFCC8033EA131BE83F3F647D22D1212C16895F52FEA576EFB344A476D2A8EC74739BA62632C4B5B08076905BC0103CC9B2193EF6C4785685F2B3F79FC39B5ED09B258E5E9BD346557F24CB542B69A3ABE367123179879A02F941F9781935D44BCABCC563BB1F31C44BB77D5E7A4FC7EC2C11D597E7288C6088497DCC97910CFD8245A4F255CFBCB8FFF95905E8224B770E910A253356916EAF1B3277D831BEA5BD6681C6C7D57D363608EE78973B7BBBC156FE5536C963030B6BC8D306F3C1EE72F14163DE0DCD0CE741EF975A9DDA77EE386B991F3096FEC95FD394E26578269F491572B36AF42CEF1D86CDC82D63DF00AA397E1960378763F5CED239BD2A6D0EB7C5BD7CDA2228B684FA57B7FAF497310D510CD386DE6406924CD592ABB1E9753EC8BCC594ED52B70C04F7C53E19B0CB607DEBA79FABD6748A52692CDA34BB7CBF95D1ABBFF8AEF8F8AC7E5D52EF58FC79B0C7662DA90A0F737CBD42E64B648B624AB497162A7B27E41850A9BB4AF0489550773EBF1EC6742CE8D53A20921149563AA74337ED4CF1EE8685F41D36F748B6DED5F894BBC50A8DEC84621B6AAE690D6EE0B392A7266A480CF985295361B14AF0A5CEFC1EB737ED3AEA5E5894FDE80CAE477FE742395CACD1174CF2B345774BDDF71853BA1854EDC8F5CB03D33C5F58EC386ECBAC8E4209F8881473A4FFE306ED3194F455D4441D132B7685425435E58AF1F2964B657C71EB6E28FE3568183F7A0E570821EA49DECFBA3128002E77208749DCBD3F5E15453AB6DE9EB313D7445377B3BA74BD2F67AE31F560ABB628CA0DDB120CAC6CB62EC9CCC65051F70FC41BDCDF29F885FC9A558929F58CDE1200072F96C3D8F22032A0AB3F705884F0D827823FBDB62FFAA39EEBFECD9F57DA083D1ED541CF36465A999558F2299A865456C94D67E74F1EDC7166F91F4CBAC8F89E680BDED946A174E9260DD50C6B0A980A4B886850797149FCAF8871AB3080A76B645E333290A0DF319DE058981B8CFAD7A54FCD62345DFD9C3E6F7A26D212C97FA6F09866E23D5A19EB9CAE760E876B2AAF43BDF9004D5CFDC41570EABACACD4B57662087B6A91B6249CDAF905BC2B1AF5934F1A05D20E6C6784F0FFDA0A3E79A2C0939BF36C55EA0E31B1AE614D44CD413118EA165FA549026574D1549FF7D63B4C464A896C5C0E8D5569AB2B10D1DC56458FD1E069B5F91B1D084F7AE34F67ECDCBF33299B12C102F953CC48B0661AB4EFB493F7E4B2EA8F6FE59C3D5EF7D121B26B912B86BC0AE987B6A3543558F0B935AE62B4711A586DDAC9E5960C48B99CB80191B11F4053527905123D20C549457BA87608948933442CB06BEA0E73FE99E3C4198E9E7C51BBB7074DA46E752E46B3E419FAE2AD60D180303D710C0A59C6B980B24F0BFD39959368B5F56AB3845A2167F4683AA82A9613257BC801F5146CFCA857F2DF4FBEA85C54930D4373F70C083F661077567F1173819EBAA585EA3675F97951CF8C9997887BBEA9B99E17A1E0215DFC2B9A66760A277F68E747141AFE5CAB6B25D73D562B91BADDCC7938F2EA75F1C990E88311549F38FCE2C52933498B22E2810227D1EAFED4BEABCB153324622E107A6D96214F3C6D5DB91855005056A8D1BC5D5518867C373709D24DC1FCE21537C58999E26CDF4FE61ABE5E1225DE80F98D02253999F39A145FF3008F12880C173A7ADEE15025E3E186FF0C2090872A0A51505A09094FA2946AFA1840B0D6D526DEEEA95FD8E259E70B2E794C97F50E7833B165E7BEEAF5D3CAB7C3AA1CEF00003B94159F0F6DCBC74808E3FF237D5C3E94353FC0E700CAF48DA8BD94B991EFFF2DACC9E423A2AD63824CF879EF838C784C7D4C0CEE3DACF5884941BCC14E043082D382AFF598BBE0321DFE9406434DDF558EE2BDC272C2B04CBF8CEF92EF8180D0FEBD3D62E1F73F3B1E7FB0EDF9B50538D49C52CEE53F3000E581FCD7E6FEA1CEEC9DCB4876B3F1D1B1A301A2D395DEAC54D68181406D7ECA05A416D3D8E0EE10228483D8515A0F662D933C53F945B50C65C5B8D51EC45360661C92761A1F74EE06FAF8889244620DABA05593DDD4D6A82A30F34DCEF50B1B1D261CC357AB0673370A38DFEDEF3D591377CA29DF609682EFFA212092ABF84FCAD677DFAD758575CA35046467C6925B6185F9B734D5E194F5CA48DD10D0B84B7E9096703A9EEF0D3EFEFFC0F58C4D38D741F15AE766D06156B26E9C82B464C9F609F0A4FF699D52E0E11E054738476456CB81859ABE457F3595E9D7F1CFEE5D0437094CF093F468C79C093CD615F7409A505C610169010F46E148F3D264FEEA1DF42B3E78D1C4B33C92EE9BBD9C508E89BC4CE0BA0C412F75821EB54730FBB627C6C93694810CD741167D5288768165A68034CE2B16B0E73ABFBF75A905C9A9E577024EF2070EBE8A68076AE37BDF3507C7CB10EAE13D3A05BB3DA33F873F488150CE67AB892D61A11FAF5850B6A26862FF0CE85E4B0AB3EEBDC81F68BFDE39B0582185E4322404A0195BF5951BF7CDDAA6530DB0EFA0A2E6B2A9CF8DCD8B0D15447448847D1EB5FCCDC80EEDF166988D55DCF3BCE37E24A0A5F302F820C2782849E70BA47523A7AA1FF12F144148E9B5A1E05035A346FC4028BDA824B8D5FDECEC4036EB2C3A7DA612A703EFBE4D5E5E17CBCE1EBF546880C227EEE2D9CA4113D0ED61AFA70171700F0F9A1BC7CE7807A081EF09E9CEDA5DFFDDECADAA7CB5ACB2DBBE26550ED006C5B7DD89A2585EBED5995F8F76F3EF8F13B6AE77084727DC894C74268D4D91000155FDC94DEE049E54F4E4D2494EF926F23B73E60EE16CC3711B67B6F6B3A3BA6BA8CE602AE1BA87ACAD58650AA8F7F0F36AEA21080CA8DFC618AAF865B14BBD69FF7B413FFC81DC6C8BF2A7B122EC2C13DD7832610DB9E6EA0E5CACBE1703AF551997E6C51BCE7BAD4B3EB1F392EE12C5691F795090C6F1D6405D0E682F279B3DE64A9F45B1853346D8D337FF8037370CB4DBE5B241959FB8DD985A4F154470833E422AD9EAD7A14EC1CAF6308FCF7E9AAC13ACAFAAD98011148A2D52D40511CF13C7CF0ED1E320617B908BD1A6A442FAFB2E543703844B0D40FCBD1B392CDF5DAC9CE4C2CA69C8F04AA033F5D6D11DC1A5667FB352BE6BF88A9978AAD37B01BF8652A2C475E8516AE1A6E56F8CD596B9A780864ADC65A04F615ABB2BD4BA97301FB0CB7D9AB5423BB14C29030DCD5345C54D556ABB116051C04D79C81402B70AA9F32CD01B6C06FCFB416C4CB7709CEB12DF3E8BC541333C90E6D991B24D7D1D98D0839AA86614F3D91ABBEE5DF138A9DF2C0591204FEB3D9DD546305FD017B72FCA4DF01A7C1728606EDBA07EC101D7172971C9F4ACE7D6D09E06BF9E8552A4CB3ABF6FD84FD350F60A3E1826BBCBA484D4B5B284E2E1EF2A164FEDCD0D22AE77026C4A6596ABCCEBF6ACE68C11ED108BD3C"""), TestUtils.hexDecode(""" -3F1A9B8C87C0A08481C482D90D252CBC687B25E613C6BDC311BED7FC59BCABBE5353E8094DF52017277C5EEF17A07D65A7DE47EC40E127A745EBCABE4E77AC5781ECE95BBEEDCAA01914F00B98F04A6147222843A4F9A4F4CA0DBB5C26B530DE04D304FEF6AA5F3EB1789858760CBCCD9AFECBC45E02EC93827149960F8EC0867CE9D2F2E46F6DD8AF4F959DDF9DF7177BFCD67C43CEBC559037CC88772567E6279CF261CDB891631CA68FC3B88F7A5EE03C964810E29943607F890FCD81F4AC0554EC8FD304741DAC4A0F156B66DDCDCC7D12BD563B2D54411891CA94CD44F6EB127A7BB3C0FC51A06597639C97FA4787D4C819817A8100D9463FE92ABC339426B7C57670962575B37934E890F6924F95CAF81E62D42821B1B4E669320B4DFDFD8D213C1CA405F9540D3AF7776A3265A717468685F0F3A08A22E60517C6DAADED6AD1365D90E7D91DFC8F0415810C7F98406CF0C24A583B13531B52F3F492969B198B4AFDDA5340F059D21E8F5A830E1DE4DA51E17BEBFE8BA1E3B9F6C5222BFE154516C1C1143B96A49E04DD99F56F047E781FE925171D83B3755DAD89C361CE5D4A11A7E9C37C245BC6B3315723EB2DD15DF385A108C719EBE636ECB6529D6B9D4817EB011FD6127270831A097ECDA206519842148B029A1505849118CA06FD01FCFE100B1644C44379AE47442DABC2BAE7F342ED79B26379D50C0E61A809EEF8B7EEED4B403407B44FDB7E683EE3F85881BB715266F87A96E6E3DC1FBAC1715D1581CC3691729979E97D577D8691A9AB21769AB550C258A15F4A432EDC1E18669999051A7594950EE013D95E269973762E66808BE560D9765A104D4351F118653BE7F425D0FA9D3581724604028FA8A4D35C6AE687DCC0B55C915D75E5C590366713AB78A2AEA5C1515F36651F85B2997D6027C8AD330D914F3DBDA26A1ECBD1A34125342A32B5F432ED6E8EAD0E1BC5796108F5784CAE34A3207973A13044699B496753D7CD4420A8F45D71017C2439B773771229633E08E076F1AE5092ABBE3461DE11AAFAF154587342D3CBF56939B19DEDBF0A612FD3880A5B6D2EC518BE04D81B9F183250D9EB3949EF4B7A7EEDC4021B1A4DE20AF1B5A1633A26F3D1789C1DB42F379E4E16F1C87922B095B5751F8FCD4E9415438AC7F546B1BC000927A06A4BDDD18AD62B2E829C5C2E464F178D1FD9CFFE82083FE84CD61F5AF373D10B0DD30B151BECDD8FAAB9E185EAAAD459EC55E905B56417F5AFA8024B6D5B971D3F070F5CD513E85712B171D7DAAD6A47351279D4D204E33D6479BF0747F7F895117DC9EEB22552CE829DB8AB67A44E035748BF41C5663A17A1AC141DEEA02C990858508C62BB05D8ABB8825713C954C509B67D7A56259172F25E3EDFF8EB356A818233DE470F543152FC9AB0C0F2530FAF9B1B0CE6BAFCE2FAA46DDC76FC90F6B658DAC93263CDDA34294269AFD2826B2BB6F71E1608A6232D3CDD09BD5201FC7589AF0059ECF3F0EE167289A6C7EF1F414532BC981AF7D44B1F8787C4446D9619505B11E6F60C0C861C66291952A054DFCCBCFBB0DD75C9A74B0CCB3C0AEDA3A6D1C1C1DE0E494FF26133CE52A64B397A7DCD547F88F4F327750039B2EC77AD56E4D1A793A539C0EECF501B8E8186CC5AE6DC5CCF0A14964D2CF1BB83A974780972B2AF75545B9266DB1B3E2F052E15758086BEDFC5CD42DFB3E1F2DF6DE49D9CDFCC990174F52C66993AB07E66B2658C9B430E92838E38ACDD02CB9302756EEC3CFD74D92B0D89C90281A93ED479B7A37AF9D37A47F8E04B5B261669083F97062DE23B6C52EDFEF09CCF65B8F32920E5586BDEC1634009D42EF43640C26CE938B2BB5A5E459B74ADCBACC76A2BF7712509553DBC30F9D73EFA20F95B225808F22101CF4A068D6E1C1C64EC656EE535C57785296755F757722E897A53264E63A0311A13C6E47120C3850992EC703E98AB8029B6E29EA7246882D9083989C093382551663C570012FD42DD97EB86FC434D359B85716D0084844D185A1FE8AF8C90F17510F0E1264EEF6709A2C0E9A840F49C6E7E2984241DE2A50DB152AA9D43CAC0E7C6707B55BA44D18F36E2F5F89BA46A5C1E195E0860CF5B3CFB1C4C71A0A53AA1A1A83DE888D8EB9CF7354B361EBC37DAD4F9D0F96CDD62D108DA793BBC84761C5F29F24910D736C8C9A70DD467DFCB46A53F880414CD2634C2E8AC379F2C29F52167894B6E9BB41636F93653FE4371555E061B711442BFF93D04E0AC20D7B4E92A23D1BC77387A7679C688436D34CF37132FE336FE29B57F8D792BCC76C9B4F2CF048A2C8F9B3AD2EBAD9DFEF954A55978078AD5DD59189C25411717BA0C59AD2C89C7D58C6758019B3A134EC32B8DD5A7C90DEF509DF31AC9DA19BF136DC49CC8518CBC0B193D2A8D7681A1A8A6E1B4FD96896CEB085374A81C082C3EA606C4113C85E78C7C72945EB436497E5DEF79340B64DF13AC56123980C2B4985AB0F3DC4F1AEC2CBCD47B4693AB4DBDBB270F5FA2B7BC4A69D77B96164DBD43055A930FE97296034718569D3DD151CE0440B94FE8A2656195AB1082BA64881CCB1B196BFFD86584BECC610F9751DD29B0985BAB0DDC4D0583C2A12BAADE088C6A021A437989BAC7B72709340B4BB12E6FB9BACEC05EBEADE26AEA86ABFC225121672F2687B08E8C6CD87C744C62F65AEAD52EF3063F8492CC7DB1FEF69CFA96532001430BF131064FE5B2EF71BD65FB69F2E1187B34EF659AC499FA178B969E49F494A9FE3D0B3DF5BBBEA9E852D4A9587815E199474DCD774F5A1A4922E9F403EF9A56D79BF8D20BFBD3D3296757A29EE30F3A8DAB3CD909E8A50A775EE2BF33D136DF4234E7D44A2F5A4B8EEC945C6BAE494D35D24BA70122CD9071F3F7B3B217BB4B0C1035301D4BDFA7FCABED5E223CFA7C5420376B53EB97FE945BAC67CE84DA6E9E3A6BF44DCF46B5FB35957A30E922793FC47FB59AEE2808BA559D422208180F437108128C741F181E3ED84742A122F30B420CE3063016D0B8B8EE07293DF269E5B4A427EBC108EC22FDC33BCD7F02230A49B6433BC4E981BA5C72027398085E36BF72C868D3FCCE0CB15C8AEDB801254ADDA850EE2AC97392E36084A8456626131441587F72CBFD1974C3780875EA246CE93FDBA8757591A30F00900B9B9E07A77469D03897DBB6F52F8D6ED02F77469A825BC1F1C276D75DAE5307C3A72F09825C761CF44A9F78A2085B7F339549F0905DD0413211BD3A82961C5AD4FE88B9CD776640E38434392DF1510FF9F416541502FF9C81D0B92E5F6A6265A982DDA7A457D943F05238F3EAF3EAF88A6C300F1E6F800BAD8FB08CA1EB1C5655A5ED869F3BB7DDCCE5EC591A2D19A043342D554EEDE81242A9A3F0FA55887EB621684235398C15C5AAA9962361E94C223BDAD1D69C87A684390771364A87FBB854371AD33E80AD569753A389D7496A1A7682F1265C77DF9AC5B629FB576A4C0FB7954EAC01F5A94E213D1ECA6389D8F4FF9C4B768812E675A38870729756A14A7A17EFBA62981F03BBFD55248E515BA5913B770576652CE2836471C0A831DB7ACB9CF451CAA0CBE56F6FE0C84EBC5A551FA3C68C9C444D19552697E65B7A5D9535E7A6E5B1D322CEEA4F7DBFEA175EA716E750FE8BBA057FAF26D03F83011E92672E4BF4F1336FB883CD21A2AC3AAE4D81731DB30D794B04A25CA4EF2E389C54C237B1B142987383AB6F6FD7C527E8D3886ADA4F3DA08A20F33E252BF946424F058BDD055338E9DE72068D5BE75A06A0371102C429E980233157BB1B0B5DD1DB65248A9AADB3DDEC4EC4563E6353CEB01B8991D7E9A6B8C80519CBD8B06380F61A920395E4D2AF2910184870619F5CCF4E8D4E05F81068D88834CA0C64D5B91147A876A569BA0E23D430DE76B1A0CFC70B22CF4110423328196D2083B03D5791D7D967A82FA7DCFDED446518CA4D29BFE3A9B0CDCAFBBD4C74A5AF9445721EA1798C0219E9041A2543F31D8CCE862454F0BD361FFE6BD0B95D51C777C430D78E226E124C7A0908895C78A55ED6B0E841DCB6B42C8093958699DFA5F0B82F0C94697BDF822B7A94E1607FE85A801DC9626117E3D2FA3D9D828706AD8FAF1FA130B65400A5256EF7A174953D2855BE3FF62633E0C3C533A322729D5327AA103EF255AA3FE75A173224085BF3984A9C0E1DE30D08B04FA841BB0CB0C2C3C63BB3B8BF8310673200F2881AC80A621AC51DBE999B8561164A3883F022DE646A95DF2EB6ADC8A773805A009FD8BC5F72A758A109E4C3A4841BA80F27789C29E23FDE6ECBF23DBBC3C12556BA32737A2D625045550536EDBBE859D02279DF1A8DDAB731E1B2AEBF3F84588B21D109D9351BAF83E1AC61F990C564E34768025FD6124B0D8007E5D4C0D00521684EDEB739DA51D3A793C6DB364CAD8AE59C8D479E66843204675C8A6A76193D5BD690E349A27E6E55FCE7D20BA1460DAF762A0033CC54D42F1F387DEFB6D5108A3153FB43E425471092E882A06D34A226EB259667D6C85AA63421048C17B2E4E0488F5E4038EAE9C5D4198ED477470E4E4C4D4734AA77DD93F7172009E4583857501511C9E40C6D22ACA8A16A968F3C037ABE0E31437A82150EFBBFD7251EABAD03D93B2DE6159CB2B432802054AD2615F96552AA978C8F8F5CCD0626DAE79BE0BEEC69BD34C6988F6056F4FFC5DC3989F14EA6A486BFB4ADD7DCB960D25F71EF515B024CC9898EAF414EF07744A98F0DC3C3CFC91C4BC381238DFD67A29BFC43593D3A38C245E5E2077034BA8A646202AE547115BB40A4B4CBFB7D47AA6CD628243768F2E2A4A3B47B96ACE2E8C3E23A646C129C9F8885215EF0F7D13AE8E64D613E84366653A5DF27A55D606F95B1A44C56F40BDCAA60405E1C02D42D72F391E7BED3C7455CB3A26519DB1AE24D99BE9DEC4AB2119A6F05405C026AE30FE263AE13623F9A81F746DF4A0563DB49C14BD19BFABF1FBBBCCD6B05B565D9BA16B86C1F61B24CFAAEF2EAEB52D92CBF130FF5E49D834244FB34D478BB20899FAAFDB97C8901B11E906263A3F353AA2F87D66BA6DD41337D2C1D05819BEE7D215CC2B3ECA5E0A3A3A71F7FC9845FA2751F25FD292C37EF96B0017101E3C250AF43DC4307C449069E9257BA1BDA5B823E2343A7B1AD61EEB1BE94EAC4E410D7782AE9E8A75BB54849C5764C45935C6E4B2948BC6F72C620574096D57C14508719C21B02F6F75291A669740283303DF20ADE6A5B3038E82DCB3EA9508BAA297D8E39C56E1E1F98A20D57AC893DE4C1B59DCB35F1B15D2B923CB2ECDD2D793DFD3254B4CA3F8878E04CD301A1AE8177103E2012D17314D9BA9DCE0A05FAB6A7E23740E713DDA18574C8BF8AF2D116A16BD17367D5FE9C0C6375260481AD70E31FFEC9F8B9F63E5BB0FE6A4CDEC6782A5C62779B0B1ED0956865D963F89541D0508EB31EE26ED55557687934D2DC9A1093A5ABD5D2357672578D1E914E9329BE8CC1C6ABB8F82F1A63044C3119AAB980C1659FC7CCD04041EB8749AF7222E4626A22DF729D0B878A9FC434F7AB431041EBF49963F7F283BB5CB3FD433BD75428AD445B281524CA08E5ABD1AF6DB75208F70B06036399AB66BA84A014377685275BA2672A5016CAFBEA373C6176987232967F81E97156E1057F45ECDD86FE18BC95C10B3EBC7665F879B100ACDC4989427835F9E1A778F3A1E39B4FF2BE81E9B30B4F605C4144FBD8312A879436C532A72E6308BB794A2D69B4A6ADE42EF39C484A494A624909AE942BBC0C36B0FA7EE3838459B3C829F8A636FDD8750793ECFA500D04F10E9075957EB063776CEB14048861912D60DF85E43FA2FEDA98BE9FAD55E1B5A177D82933AD17C5B5913816C90FEB8509C91BFE8199AC75D66AE907430CCAE09CB2BDFFDAF40FF4341EDD45F7EBB55DB6A8691632D06D1DF6AF6974110322BDE9ACBF7E07DA4FC7D6C6D300B4CDA1AF21CF5EF780053BC38C17D418411AB6574D4F3F5E9426014EDD74DBCE26C76A53A09C6666B399DF95307F82B98264E45A6C158C7DE95567E74D67E8AD591E296B67EA01AF48C01FF3A7141F817C9B12C2A73BAD5B36694DFBD15F7D98DB91848A373946D9A1CE2955BECC1AB0801FF4B2F00256E3F62AB684B7D5F251260454C97FF6979E8ECA36F2956876009F7FD24A4FFE9276544C40044CFFD26C7579734AEB496F4E10DB0C5664300684D5D8B84E7466A4F857560F0AA1ED6916EAAC996412B4CE27DF2D877CD899DB377276E500E89533A9B70934365850CCE9145811379B924846C45627521E34AB03366EE128EFAEC353C695A1D4F13255D1393722CC03252B814890F7281C5A4BEC52A39AE4AA2F07565BC810DB4C32606F6864618E549E496F8712D45BC2B289200776958040B6B47F8A93F341DCB375994474059F46767F34021E3F424768DDEE1D2C3F949ED5EF3D42568597E8F309171F2046B7CAF00D1F2C88B2B7BAC1EBF61B36484C71AAB9D6D94C4DE4F900000000000000000000000000000000000000000000080F10161E283135""") +a3426182a616883300b2c714932258a288d6f9d23c8339e1639f0cb6affa7245fcd901acc5612dfafe3e4fff1171e24db746e388f629bf6ab0e2090deeeef36a3b3c610ef0570193067af930c98accbc0d6830173136316ac7d5459e4a2cdda6f26f6509c35d1232af44470fddd0142b6d584766de939dbfa3edc9c905189e0c861eb16667d53576a9d4a7df0073a5d54058500e1f54d3898faaafc08b116336669568d1d18004d33c2b71acb0686472ad04b23a667d6d3d7d0d9e3a434e34d505d63f17b26933b4427931701aa35f2f6864465b650c9a6673397ff4aeb6af2730206f1049febad306ae06f30c856ef643c8c8ae9e3cb249a10a4646f9b7d985bde15103d57630cdbbb6716f41d0b7b1064346ec31907531bd35fff03872661bba13bba7d9a03031ee4943fb2aa549a208709a528555da3a42020a5c5827b06e7c917eb07c02732f7f559c122c545fc36cd006f33bddc2ec1a2dd67a60355c971e699d400110aa001a442fae92e24d05d1d091eef447f643aaa825d974f4b049e6e0f988ece4d510e79db57ccadf9b5e1a564c64b029cd265845d41474868afd6554996e7dbb2b3e92fa5f544de6f8840e841e886f7a5b77d1afe3b29f74dbab86a3f68cf223f9cbf41715e6f1f14b91146b64475a336fdeb668b27ea28fb87321f340c910b1814ec7305e11a0dfd0eac1283c0d0131092267de75cef5b2586399804afe72f7da133d04c02f19c2289c17bf4a2ab1d01bc2830b34bc77b15edc8fddbd0359587fb9316c3ea1ac8a146fd5229f86c38920907d77eff0b1c581f6925a1bccac2d234c52d159ae44f6d93a11d133edd6d0f6683f5165abf5c7197a50827fdaf713eb3bcd562ee9055be72e879849b7e4105755d0b9052885195e100ce302d3372fa4e41e3ab9e48f61a2ca054fea7132ee7ef77b62d61e02bd8acf7bae2b56cbe5f0224d15c3ef29fa051d2f27d56b0057b846fefa044ec57171549c81d7baa27e59e134c28cf6326d49fcbef62af5937d42953bf5662b60729ffcdb8471733c44cbf34765996a58430c02dacb23c6dbd9d8550eea2dfb669e1738fde0c9fb34f0051fb99cee29bf5ffc1ee95419580dc56c9b2118ea80a7b34c1a2231074195f45dd778dcb1426aa7feadf475e065f9ecc00333d05ec3ca0e0cebb2940fd7ee81e8a18821b59341582acc43ae576cf850f8e7cb040d4c4dab557b2a80fb3891669f86a00879c45c73e6a363ebbad67f99df0c5fadecd53494b5872f902e20f3d41e4be6b7ceccd89783ae2464feaa9fec596440fefa3111bf3efe416481f5e739fff33e3b7ee1c90064acfe18528b8ad3a9f3dfea879308521416da9f6131a3279def7f9ecf8a46373352cd14a0765f4e28ea8f313a988dd751d0a15b525c3f2b19ef0d098298014230bd7c8a042afc6d6eb6886e22449a36ade8b5c8e114cd408dc54ca4554f291882272645f8c1c10eee4ee4d6206525d0656867c0d2b4a134a40ea26019897e6f2bed4b325ada4af846b1db43358d140d54bf61bc8ad585715345aa2fdfc6ff62453bad6d00ba9ea11b053e776d72e0bc28f54056c7e0feb06314b3dd0023b257eed796bfd594d2a2b0ef19ed5eedf68a6dd19558fab24c9a751021c5fd964872e4a8eacbbe9406dbdb98fd505870ce79e64ed57c83887edf6ea916b29ad0c1c34d02f115e9a81b76d70ed6bc0900ada79fb5f7dc069fd7fc2f87ef9ada6be01f3e5c2e87ce02b38bb4c5372fe69fd7cca02898618d952c6706c88bb7a8b05a3ac163baf9deb64a0c5523ea486825f00cc298da63274b4d085b7fc6324b984d86d9e39d2cfce97c2e2a3ad8c3c04399e23af07f4e4c8a49e58971f8c379c88258e7ba25f6c6e9bf8c090eaf06424ace3e91e3ae12bd552193057f2542c6bb89bf1d16b7039395a8f8f54bce4a67caf3baee88af88a4a34ffd0d3673710dad8b1a98aa7a7678675f87da138971b0446e868fe1a39ef268252fb06366eb194d1f69c7a86b7e805761ee0de00c7113a2e1c5f405cea7207ec634cae3a43308d6d3caff7a9baa0670c9256fb90c61a116abb81910fdd638075283bc76928a82074255a4375872f02cc9ff13b75240609fc44125d46e8071a94cfe1e8fc68ec03665daccfd0dc385687c79e5537661bfdca8462d3fd86ce26d599f5add12e57c49c0ab1347c2fd967cd62b6e88613051904a975051309d5a43f9782ee31fdba8ca641f8d5a27c8cac9131e33e24bf5a1425dd771aadde8bf0fb7a0b7b896dceba013aa5c0687e327c27106ffe79e545f2249eaddac393a6e062dc296aaf4496c4936dd0365d3d248dd2811a95b2789797fa05e33cae686819789fd2b1315aa90395b0afb2f6084836ab2c78216b27ba6a65f09b23006957522679a4e372369aa65a3bbbb8c8af19039ff0cbd191ba65c0d7e0acddfb468a253f631c4495a808083e945496432a10195fc221535e240fead5672421cc1ab3010ffd3faa39f818ae105dba8d6a6fb621f0b86ba9abb68dbbeffc24b26e55184d4f21d8ad733ef0fecd4c6cfd5a403e551c91000cb9b6a26c3f6a246eace5717c784921cf154bc7fa61da54cd0eb55846c086a6a134716dcc49f44b55994217d5e92523a07a28733a95efdb2c6ecebc6d3ef790ab10ccd113d4fe96144d0e4caac971370d78331fe91648d32c2373c595ae848ef70a5a786c36c61d5961195b8a2c287608b9596224ee165c22336c07643b08d3c92aa5808bdef9c3c35bb3a5004f386dbff06c9dddc925fceb7f10ada52c9b5e100ce0e45fc23869f18ac4b3ca6561f98c148a86ae197d17066da6421f4d73ff4c16b489e84c4b09afe4c1e8f728f9dc4e4563c36ea110870a341632a390981fc1d114052eacffcc06d550c329bf38d7460c51a3ee0342d87157450989c43788b508e9537d08ba1017bcc0dc4c5a8d99ae5591d82fa8b258cec35a1446054aa449b48371db2f04f25cd618636309b5a40b7a32e589c80b69ef5cf19bfad44da6687abcefdd35603f32028fe079c1e541854e5b0b56998b4bb02ad89b3ef22229c9a8da7a381fda304ecbd458c625c779d7e52c8c44fcc45322a21e7a78d896417b513e298700389d0de1a50c7a3b653c87006bff64fd297a54fca09a4662d9710132d16e2e38ff4eb2a4eee0bf9b9d59da5d828da4cafe77262af02a279fc22a1a83aea33f9887880542e274c950d707e766eafe8610b0cb8aede80cf900f6a36432019e4d1f561f33ba1d273573cf1908a9dfe9922804f9e5ac279270b21d3b5edddd51c1fb2e8aa8789d0cd75c672eda3b06686ff6e8c7f5cc3fd67d2fe91aeda8a22e73aa9624b7b18d0060a64d6ce2ec77657b1d1a878672d5bc033aebbe3b9a7a224b74d859d47d89a360e2f7a1b03a4bb1ae92c063ed85d5d60391d9553e4d3776c5d4628146aac13c22eadd0ac57c46e65c525775ed3edbf0b41a01f83a2758aafb5324c1888a284ef0d47c12b15c6c5d68affe6c330110e0e8bdfc2b1a8f2fd67617e76f975a7d72630cc24e98eb45b5e9c8c442a5af3ebe4b3d3809db4abd88e49004d339a36265898c5a65bf5263d062cc9a307563081ec6b0c46bb45b92eade67a15449e0ba26e280fcd403cab8c29ffa15d306285b4052611ab63ea0549e8aeeb037e29cf23dbf5baaec582754768b2e357187343b3186bd6e1128ff92bd7c707f8b5f7dd9eb88915229eb0c8437d715f1b59d1e478b696da3ae27fb756db092c885b6636f6c11abd70ba3f0bcaa6340aff1acbf2182186981e74490f679c6b619522a85441902f9983231c2319a1420a2c3e050fd62433631a7d9b6947b247571303e22121d25c30c130e90b73fcc0367d4b7747688ec709079d9b28b981576e0fcf89593be1bc2868d12cd9b2159244286f46d3c270ed38bffe97bfd1d51e0254313703439c148f495dc73c6e534d05d0041c3a4f02ddec5fe88842b4ee59284a1cb2dbc3ee0c4c5ff17a5fd6b9ece5b23f8f9548cf537c4dfb6d231c0e8ae2fa7352d2c6df9d78865418415fce33cb613593071d83bbc30ac710d2c313648543a762977d43979b5f48c2608a68769b2abc933046762736a42a9b319c78e98be5500fe55b9dfe9976654e95999eaa2dfcc090500c8155369f49f3b9d296db180268de2bc26e3fbb428803d9075a20582e075330aa8d84fbe36417f9a3ffc3204583ff4d2731c27ae4620cf065acce9df4e8c728dade6eddfd09acb726d27a7abf9409a49739f84044d6403f5b9d1855da0daab9d54e2ac26e4dc9c71e63da692f60a755902e9930c21ed5c3ba5d1afeeb892794c5c948a236a2e01066892cef70267bda3415ff51a404207f2f681bb72fc0a14e2720277558dc201958eab0acf7157cc78ef8a9c12266932d2548a559c401cb4c63b36600638a61cce16da6005fe9d59f6a7ef14fb2a4b860fd7b79f0a27b8a7d631075f6ffdb9fbfd8d2764b069f0e10b78605b25fdfd14bfa6825db8c46cb6aa0c976fde81a5929c92240e0b5dd8d664013e561cfdfc59bc7f09bd499aeb45b8623698ad7242808e50f568d830cbbe864aa4bd403dad6a4eb67c33d7db2180d7ef9df51b91bb946bfcfbe0d216673ec34bf2dd72b2656344311191b8b24b263aa6852d1fafbe14b45e803c2b6d0b6293d4f58de21f6ea849f3e8fda46111416eaf6b8284de908f28e7f07eda6d42e4f6196af945fc41301545a848d76201cb84b3be2be65d14425d7cf0822177be934488a439bcd1120f3131d5c78c213df7bca4f92d39bc4274bf0b984fe7d6a35af08362f07250d98e8941d7859fb19a2fda77481d13563eb44b0ab019801d3535ce9ee1b8c24170196a8d42549345bc4d8af3d7a12f66b3dbab325ba4451c345588878c697f16fdc7c75a0077c31b2542407d339a90db740a9f2f3f696ed9d8729c61d296e0eab52a95eb5d3d6f1a9207cecb9b85661128ce3fd6f53b205783c95b11f3d599639d66967729fabf5e0dc1d4e24d7126c73ff941d6d996592cf26a6f124b5a08272b88d6f9f3869b10a7adfba87cc683f2a99e695bc29220b611203e82f67d80ca3275a79004479802182431d2d7d8dc4859820d17c483cd94b0ea11c286fddf5766a048456390ec48b2d5a94d2a59a236ed193f14a9d65f30e82d3df3571bcf7883da9bfb2d95dc6549cd0b9dde70ac082efdef59beb75299ad178cfe7f00679b9fac03adfd44677b8991f9b2da8e3a74b47b4f41f9a063886073a19a43408362497250e8428cd18ed437643766577306975a566ea499ccd3b78ab89382cd5b0bd9b84edead83285a6954264ab6e602e018e69754776070566408719e16ed075d9129fee670113899015690b3696d55b95b15ce290b2a9e8aaef3b869c215de4e1775a480a05be21e2a699717c7c568a755f4411bc2f05800841284939d08bb3bf552c2630f541cbaf3f5e12a12f907863afc72172bc56166c0ebed4e904c05a767dbf47683af7f8b98a16c859180cda8ee3d92b143aad733bdcafc7fd88fce16c39667e9ad26b73a496de9f5065eee7fdf2e7babf2ec58ce83d3762fdfcf44f76aa8c48a32d546761c1011e785fa09bdd5b9b08acf3e5f407b1c733270d495005d5f8709fbc3b3eeaf3b4845e437ba8d2ad2c20faa5c7f4de572ec1357e9c8ee7fa2987529a72572b59bca31467a6b77720acc272529b0e00ef04331e143946287d0ac080d80240d2b31297687f56a7a199b8f49a727d40cd14b61643b6548aafb0d760f3867829bde610960df12851e32c8ad61a507ce824fffa4656e92ab12dec825104c5a19379e11a2eca89165569d0de12b25a9083a355172c34e4a0e26b32aea3ded77f04bd2a6df6f951e295a6544871a06c4554a645b2e29216b3131832b4291230a0f85af29c1a5bf84e38c0753d8bb381bc5414b458c9c5568837885431d5db43edb64d81ef9bce7c20d89a5e574f376600d3e9b356fb1a819b73f6bc16491f7f0af200b787359e5de299f35567888796ae99b3a6c82e2b579c8338da8ecd499cba4a1ea92dc8090487145ad6965e702f3d9ba5a09f32e18a507a2ba1b40342ea2e3c4e02c908c99a2ac2c4a25d08387d8c444f78a4cd6237c047bc605afedea209df85ed0924489209a3da321dbe671041d827e022dd97ced029b73f6c8bb503bdffeb6d326c6a4cf5bd3716fb01a0d3cc43ee43dbe5692049591171209b47b86154d91cabcb955646479ce9d11ea660c39d7b4bcf1ad8b459b4f1589bcc7e1683bb4966cfdecb626ae1379fb66539a3cd5b28e24a0ebd290d2f214307f3d39c64d15e45d5aa17d339fc6a09a14db59e1dc2f07d16c97b117712c468b1beae5037ec65ccd569262fc9b8e250f6951bfaa7ec3b0511eee88d13001c4fa091efe03e41be5eb09e2a54d56b166ae26b4cea5869937801359193aabe0d17313460697e82b2cce51936393b6ce83167c5eef9131b2f7d85893a464a6bbfe7072fbac1f74c5f6579ebecf3fc000000000000000000000000000000000000000000000611171c22282d35""") ), new SigGenTestCase( TestUtils.hexDecode(""" -B6A445DC4F4638D109DAAB0B266BE84079A7536E8CC0598C04202D52A38D74A2663D2C880ADA729C99379BA01136A54B662CA0448D19740139F17FCD3D713992C3545BEA8BF149CC7EF5555BA739C80A9323261BD623B40C7844CC3B513FCE137AC51138544AF6C55F90EF757EA51472036D12F01E5D7EC3109C3E04C91E4F78209808DB8285C104884884019802924A9690DA0046C3A064600631212700E22264CB008191C42552422E100671A20884A080458288511CC66411B4315BA05121232024968192069010124859202583C6881132651B991041A668091871132322CA4449DB38021338622222869AA41113A73182100C9344808C107002A429CC1251191220591800828268093711480230A4221009271010B741190941C8924000822D88842941846490322CC8B840CC000C5B28908CA85124228CC416908A228ED0C445082760C9948C53C44C40480E8198515C8864C9B6200C172692063000004ADC8271C4304A0CC9250A098043040923002899A291831266C884640205000B94859218905AB0081C81491B156A0BB8401300119334011B26050A445092100D0245091000924A168980182E14244504446A143366620849A01400A3348583904D514480C39864483446122180A2484C1488095BA400841484D2248C649425D188690BB4519C181224992823316E194320110706839809CA30850C960150464DC3962CA3A471CB462C9C448E59C230D9C40C18972008C41018C7300238921217911CC3445C025220390861482164A26911C18853C24121130544482110306DA3A4904A462D20352CCB264A03985021B3055942681117262120716288705B024888940D99A061E44091888051E0B824CC086C2140514C10449C04002236820240104A082CDAB28D8324408C007120C589E4002DD8C08C9A24045382298A328060445122204C814871830628C416099AC289CB408E4C9801E0468A2011451834240B0790CC1406412882D146311B398ED3108C12A221DBA6201908861CC5400B090053367119A27101964D1C857012A605C83232A33861403490D8C2108B122958248154224693022E484060D24672223552C8120910264913802998926519458EC81864118688423022A14232C1880420454089288644064680C28DA3C0800B078012428DDA200E1B2080A4B691D4486A5BB4004BB85161B44102B32C0440724A209023822C4C46695344219844049C367019C1111B904814C605884289DC820D50946122B591D91009CA164ED3406C0C936D4C181001C4014B8824002112CA042809146A1C920C6244842034255920458BC671E4043150948458A48811C38D9C806504C9012016521B9821D93051884081232201D3488812014CDC9221C2183120006012995104B00993824123158120960C80C02D5B062108382219C72002B10099C424C21402D4000660306E0CC32DD2383113C9840314024C06490C219040262911382182A048C222724C28898334220C2846E30802DB4442221229C326111BA808208644E41620D8400013C80D83044D20283260080401074611018683442EC31804581206132342C998901134815A44901B26415A480A8430480CC89014B7858B002CDCC061122611C1422C44363199360420A9804A04605AA285E2B431E3086251166191824D41C02990046218B270404608221381C3B03064A441412292A3B0680CB80C00256AD34686919240D88029C41681001380D1288C1182811048690100301AB5901B0406D148425BC26523B08110152543006E8C268924A28CA342701140800C0126004406D026465C882DD148914A420E9100500B02318CA8008B38521C21520934121A498640B2210C9991222308E4B0314880699A8630DB40051C41259A32049314815400529094510A396811A68083160D830001603664CCA6242182850CA7600306661AB84993208560444E51948442122AE312100C0472E2184002B921C916464C868990B42420C20D03858519A068CC34044B308943B20913236524178548B060D42662DA0642604604110070D2121013C750D148716100099A049294102C23146D9BC86C848260D0B045C430222289695BC24C1880091B322D91A408440682A410641A256582C070A380298A48285A406C62140180486E083780249284A10042808888922082C9808840160551406423B16D24896DBCAB7827992C8BB6CB1790EFE735E25FA69A53857EF72C747691D235BDAA8FFB682A2A5835AAC37E5190412ADD9E5B91DC9513D2DBB8768978D32D3743156EDD38082F2C93C1C82994969F6719035478DAC4C0CD00380FFF08A9321B2E3A14B6A4CAA808A562B0D02AD7BB4DB593B318E55DE21EA3EA6828E15F150C0780097D0C576F3295C2E27B63139127E4302D7460D6443E1D5AE1B9B5B3B806F956C78606809347647DCB91331BC57D9C81B48C480138EC80A7EB9D623850C96843D604FDAFB611EB92201771CC4AF621C4CAE9A8D0CED827C6936BCB0CEE6E82C2A097CEECFFA25C62E713C9D9AFB571E42F1145E1D618B0A1395DFFF5F07291627EA5110185EE11B1DA3EB2DA29EC38596B47A70F34430C373E3A947E8848DAF8C269049C551FB61B25C704E5B98E44B39D34448E50DA0522F290328EFAC7BF9AD912579AFE639221AAA177673AC83563770A1DA92977DF8C7AD850437F0E77DA98747DD9968E965D5C1EDB47645907F0AB59C4374C0791C60A8BF3C447017E45A9BD4F2705A9598312B5AE0DEEB5C4F9011665BA56B733A2743EFCE0C9199D575EEEF740AE78C1254CC6D486509A26711742B5022DD0FEE1F440DBFD5C71C11FABA95006FB234E648395CB8B7F047D4112E08CC773043B848811E916520056F19198904B38831ABC6DE68D5E67AE340C08C1BD05E25E6325F5D0A38523DD12731F9FB134AA252376E24EF10CD7348BF0C2859257BAB1D09AD45023CD569C8ECA23C0E8C8F9159DA852A9B09407457F3AF0714C849D649275CF166344E6CD4367812C1ADB0E11F3DFE6A28FBADCA7AFB683E47A8FEFCC018FCB4D51061C8854E07EABBEAE2E0CBEF1F8D6302230982DAF37310E9D21F84C2D660C9D3C5D09DA8777634BDDCA0A1E720B8DC8132DAE59C3CF64D7EE262B49888EDBF98602E55F5B5A3D2CAD14438EBD8752D6C93579790860D47D5EF94567359A77E56B866DD04B77A86CD4A2EE6A21A476ED56B8A750B47907D65DE6F0FAFBCCA5397F125D519669E55BC5D03445594217141ECB649B0600FC257B8327F4389ADB0D6EB9080A444713CDE66D2509D9D8AEBDB3D6743580AB42568CF6D65D4F26F494D9F12AA89E5AE3146FF08A4EDB569E77CF7E7D238AD9F5FFA5082CD024676B010B245306582999936E9CED1DC493D8DF09F553A7F4E71540F10F75339E63EF17CCD3F9E857E17FBED81485C5F21672194DB806A66E4CEE58CB4BA9CE150506A8D139B044BFC1B985235AD526445F067BB4B458DD652475CE873B16BA403F4D2357825BF8F98D45DAC29376670C925616FF8FACBE01323607017A48E6D3CD18C78505BD0FECD7934D7448B5DABFD7C48D70A21B89CABA42ACF2FCF1C3EDB44A9E9C3CBBFF2A0B11330CC5E03BF8244F04F97A1014677BEDE221EB0E5BC64A8ED93224D517D8F525340DD0E2DB0227A56A3BD803E078285BFCB40B53F2980E3004ED1284D60A604D0FD420B83638020987E42433B52A31F052E5530029FDB0F52858D41D2DD6DFB85613D7BFC3413015CF544494A4EC1F21F5DE05EBFA829FC6811544F4B38E04BE93378F981006EEB92DFD62C58F2B8E89A8FEBD5F26C58B4D638D404382CB0084AFE425F056C6CC44CECB80E2247C51C20CA4AB9451060626C594CBB3CA5B1C3506E8D52906C0B5C064D35459B1D17CDE9B0A3A55DE2DCCEA8B71D13BEB28FAE7122F8F92355E247698FD95F5B954945D4DD7A80970C443A9577BABBB8886D7E08DF0EE7CA01935F46396061B3CA9126BFAE452235B04358E9574263FF5F0E052CC87095942C556C8C03A04FF808167780CCA0F0D9DBB9656BA066ADDE5BF6BB87DDDB4BB86E7CE778BDDC9CF467D621C529947DC47740AA21E275186F4DF83EEC4126590EE026C4874D67C60CE074E0F6CC3817965BE4BAABA2D4EB77D42DF37B792DB71882F5B10980F433B9DB158DA15E5EB9587AB568256342D82C1B8BBD4366730CE414AA25F7E97E4A0D27089C3A53EB451E51484C257F65D82A7F64D72267468E45EACA3BB5180694F842723E17901D4846BD5138F2F88DAAE1C79D84AC7C24E3CB72476AADA1AD0792DC4B031FFD4A35FD3F23960CE912693C67E0A3DB404979ECEF172CF8FE7D13D03D29CE3D57CC8D1C51690791682F68AF6ADDCE013D085107BF2674580D44E88D47B052576B6769607B7C285E85F5C4A18A3EC2CDC93C7C74289F769FE703D0D66231AF23631EB88411AB57E21FA1CBE2766B1DB69A6618DF0D9E85CB0D4D0AB001B47349FE49A23AEFCF72783B6FD9AF26F5863587CFDB320376F094D5DCBD6CC32631C9C564AA6A585C7F1CF2B4FB30F8ACB2A4C433B896D1FE2236584DE464BC17D680C1D4EEF6B561BE5516911299D7C7346228A41106A3DC9E5B4E75C8F04EEBA3D36227494B22B06D578DC99F8ED068220B4C4C791F6FCC4C8D9C2B94A7B3FD9930735A00675549E648CBD338157FF5163002E99CF94171849FDE5FF7530F552AF54A95E6CA4061A6556B30FB1385621253CE70FED7BDD09872165EA8740BC1E303E34F69ADFBA16CEA146C7ECFFD12906DE24947CBA94D068DA7F51B5E854CCC6DE513405A28D9CD3E409D33B70731040A7079CC3AFC2E502B3AB1C4EF1B2D514EF445EC99A530BB049D4F8AD7F58D55FA3909F76608CC23FF704586AEE0AE9050EE5F2634767997FB39D44688E949B9C82C3B605DB878D7E51941F8D9AEB66097FA206462F5CE7F17093389800B239B86D0ABD79B66DA99FD0C65E3A3183A143FE9B45FB85AFB57F2A101C9713CE6C4DDAAD90BE6731679DE7C72AB1EAD6CA954D350B9361FD143159B45C803420AE88363C327EF31BDA33D2B869857403615F20117AE708DB5235583E06B82B9A5E7B81AEBDEF1E696FA96D76C3F6388C4D1EB88EF3F9F7A95D5B9F446AC7C27D1915717FCADA4F22458FBCAF7D4377F2E743AEFA5246E840A96F017E139125851055A1B98A91D9217207DCBEC227D23666E76BCA0266566EFD0E2D735498A2102E4D52C6FD758568CEA164E0A28B67E2E2907BA6F63CC049DE87E61771B2095C6BD2D58D4A36055FAAFB51B63C3F9BC06F3B27F5514A9663950A6804A5D34C8E1BB6C924C8BFF44BC217423C5FAEC7CD56B61B746A0AEA7C37EF6C6351969AEF292178B75DC8922DDB935717C897098CC41E150E7633C91F6091969F19525FE257268AA74015EE2AC93163799B03785E14E69A87FD0776A438C01DD829348D6FB825DE7D2B01815C115ED418E5C132074904ECF4FF06775ABA0A498B1627CF49D8ABB68D3CA440517FF4B08B0C4B4845022A2462A0C1C5B706B061F406507094311D311ED0A5184AABF03B0B0BF06C3FF55D778F280E9F3376504DCEBE4B9FA4C4A55D93D7924EF9CB5849364CAF92DC3C5E198A3D1DE5B139C13AA39E9545959D6D738C1D88288A908A1E7DC3ADB26DCBF02D9F98BFD8FD61A6A96FC4534A2D212B208C48DF6BC95BB415932AF801B5519E8647AEADE54B68539484302C9B5A416848C2F10952D1A66078997E56AEF14FA8078FC8E35E1BF3BFEE35C3D91C31B0940E8218DD83BE1E633E649712241C61DE8FDB1B84C0BA60836F95444EC81A48E591BAE36FE7CC449C9B88F6298F9E9588FAE54C40F661A6914F001A75D4BC6280E05643F0A114C2DD71EE8FBF3D7D4FCE18CB8F61A6FF8B08FA1D20378922EDDBD2175A2F2920F434919F0F9F1AD7C6ED5E0FB13EDC924410708F7973270A03604A0043AADAB8F0368871040B418E74158CC4E7358BEBCDAE696EA38ED155E3599D06F86552D9556C39F6A435770AE62878C4FCAC7E8E558BB85EDA22D0DBA818AA3A6BEB5958D05520AEB2ACFB1BD403047DF27BA63B34A42ACD3CCAB700EFF0B6906D18672340F0B6E2842E8750366885E148AE0E5546D013427ADA215A4809C11590ED8A7547131880460A3179BED70FBED4A1C304452C1AAA8B0F6C5575C2F60B6E0AE93E0D7ED699A3B039A61BD63AAED95E4822D8D55452056A266D391E444819970CFB4BB767C6613CD0C65B259DF532D58B2E086BA9A36BE37537ED0562515B6AB8AF615ADDDFCBBA355363DCCA60F5EA2B07E59174053D6F29892CEBC4A44AAA4971D19171D2029854FDD977BD357D54E8DEB4DE463F251DC566DA73AED7170C402D3F4DF466CA5BCD8BD47AD1A499B176E39F4EE2FAB9C7225A3B98700787B73CBF36C42E934D0EF96B3859F980020679FFD83F106D609278C3DD780E2E5DBC262D9DD8250D7F4A24DD27F3937382B8E7B2C3269B6CA09B522D0DBE4CE098418E95C17FF32EF99F016AD4EC8EDFB7028CA9F85ACE4976A6D11E90E2990C762E7E4845CC7C447ACA8907C94E81CD6E7664755D378030DBA0208CF039005F433083E1E904F541B036E03F7C2686630D0E5F8785FBB33E03566E8CFD19056A4E6D1D277584EB20C8727D2C79D910F12610C003F90899CB6B5231D2B3A5EEDC0355DFA7FADBA5C949E9B9274E9DC69579C10DAD85552CABF32E90870D9D0CF579348F46874BBA064E918BF4A279F55984CEA32649111EE86059406CE0B0D50E4F52C7CCF110A5E34E01C414075CF5B31AAC9F504E9499BE75CB3EC35C2C19F7794769BBF34039F4AEC85C48E772075B887B63A5C81595EB4D17F2F25912C120623439E93482032C20F7CEFB0CDE27B2799EB945DC28EEA9B94A0C4C5592"""), +b5ddc2872c67aee1328b8becc910a85ebc35da9cb9ac8d19f282096d0022bc51e742ef864c6da6116ca688a707e1f4bb86b77749f35d50d0f196d788539cc83fa9c2066c61d643639b246a346f2ed24b2e585f0a43b16277b8d4a17f68c9d0f8aad05598b904ed2de85e7dfcc478259e10b452cd33c058d477abfdb4e97e5d13102944211091984860443421d4928944105182b82c99c65118394222292583183118b305231584a3164e08886504488089b08498b40500380508b148dc022114872c1a330001044619134c10c9011a36829a407240947060c4689190045b9600c2b0514a429009a6811819658a16854bb090413492232690c048488cb68d4a0664da1082c9b080422852a1860c21a18124b590921042a484480c900d01154111213062c80de4c00022849003094814c1092034800380311805481122702325319206861b93114148048438706110620932620cc60480a22848020658348201866920808d60085084c84420264c0a1272893881c246889c947042442a13b420a190305c420e5208714034260183258c064a1918655882700902601c148cc2340a931204c89265c2468188a2849a8880530472dcc008d122410a014999104a90442124373004372a12c37112002d10b180a248929cc2250cc8042396681c004c09c46420a92c09974013296214054e61942d18210e809631142284cbc04d8ba681030321504426181531030882e1120961168604186824c14d91268d01108a80444c53a02c6392655c264d1110510b1665d9b8490b336248242808852c113462129591d8008c843884a33671c49640639428ca406e53c6001124649cc000c34290a38690d9060c24c3011a8350504246093784d0146609130c1c39101cb90589923021a0845c90840802511b9924c0982d1407018b262d18099021062813900cd9288858a6841c480120081260906449087099a00ce1386920a42c21b56099020942808423460d133089642622e1c44d88a28121814092b42cd4a40003336588246c443429898641114981d010515ac40c123420c1c86189442a144771110632180102a02012089965021081183989819489ca40020b282112074521a84813834509398299146051368e01480841042ea2a80d24a680d04065c9222614029122a9298c8624c42470014086cb406902036e11a2251037640017088c988404496154269049a070249861d8408e2106094a122d64224d0cc59114441299c070124931043065114500213765e0b240a00071208140c8826c13880949068e0030021449258c26269448045b026d0c842de3368189446cdc40450cc48c90206943422843106cd1168c4186804006915000891ac148c4202ce3a429cb8805cc4262e4166582882413c3401437401b3204909640d09044a2308a63268e51b22d0a1624ca9224d2186601118149b8048c30895c0822990005e208894c000e01a24c0cb57040c82163840441948818802914b130c0382a8bb89002220010c38d8cb22cd8284624a7701b4741184461a2028e0915869408480ac96dc4440a0a927008252902064c0c346592946c4c4801c004641b170c4c022884b6512125611bc90012c184981251d4968c13404c523868e0344e4332645220914bc4515b8609d4c841d3260e0cb94964265140240461482e8008820a3025cba29109462a12010e019985d39425e148800bc51113b92018437209188ca10662433241c8c871d4346d64a04d9c360013a300929691922621dac0891a346ae0c6641823511ac080a1888498a66800244c5c8868240501c14861c2206e092865c944029a486e83080648a00552c04c09396453a20803115103290223c52482824cc2b86924178e02428a94262d82a46011a705249860e3040994c41101904402b101a044285ab4118cb8092437429138009244240cb925832809e1c240e0006ac1282498b0405c406d504445114342a4c63061b408d49865cab80854b620208741cbb04409132248848813206c81b85002146012074a1946491c420a0337050cc42520b351601062501029ca1422c9a06c0407020b90618b323102038404404a03024404074062228619930d541011909240d04806c90252944270110568030830cc0612c3c085442280da408992b0650220614186294c404d91343160144a4196691a154d1904214b266660206084838bcdef36d832a9f7ec4fb59f74ba844968c5b6af5fff4aaace98c3a72fdc15ef08d34c9408502f59947b051408b44e5994c7f9690f1c62ea8e9d28c28035b015c5686cde3cf6701b222877ea972204e42e6122927b89595b79d347a63b98d54ddd0174e4b17ee672dec0b36e3d10b849eda667c4e6fc973a56d2e2e048451e27aad10ffaec0b7cba07a1c1600b78b25c0f5057798f8a394a06a95bee4265f900520855fc268eb18907805f48779076e43f9d7377f109292f932d3539f41ce74ba337762ef193d2e10a26cc96b89c53c7615ca39fdcfbac0b7e98504bbe2b63e1b12f851002958734a742cf4fd4d623d557fcf5bc4c30a44234e76fa15e8d151cccc190d1d41546919304a284c8aa13e7be101e628da63c014e6208c0ed1a686ed261f6df4620d47abcd375723d3bdcae88bb5b2892828636030e55c65b152b45a93c775f597e87965b06fd357c0a1b3f626524fd54eeca30854a79a9229fa3655235af6cb282c359be16c38115d3c56429cc9f06c69615e745fc331d1f22154b393aad861ad2c32f84bb86d191ab2c3061886d8d19d98f61ec8d7d367c4b49e0bb0e397c357d03488e61c839482112a5f048e459c1c17147f3b86ec6084800a1e76b40bc93015a8a970fa303fe0a14611f9b56f3ffc158a0a56d2fe88e79e3d7f6b081e45101685e1d39508bd4e12885e528f2851373b098a6f194d3de6e9691f7c6da983c851d57a3fc7f880eff8763b442f259b7ccd1b8512efd92cb5998e34fcb66800d262750ab5a48b06302a6bdf3e5db99295bfab4495e3b000c9560d1e0b47f3b09c8ac152aa3ea2beb0baaced4ac848dd0bca3d469e7185ea8ccdaf3a00dfc5b94d8cac2e2808a124ddebc0a9cd8cf149b0667bfac04528036dbb4f712119bc16d64a3021b2224b87d71eeec8c7bc76fcfe73b379e88f3333de4907c37275f687716d9a800f20daa4c997d31645c607d68675ca11786fc0ef0661dfd86999f8f74ef0a725eeb0542322c8d93b44e88ed5f5c14cbe844298883328e3a308dc45f5f1621acbcdf07d6d9d50046ff4b9291c29da17ad852e6c9fff7fc079744c43f5e15b09dc936c2e0bec0b193e46fc554eab6141edf6ebb6f1c2850c2b86d7de1328168d452e7e5579c5b073a644ec6a7fac8bfa84395a61ca58ebeae4ec25904e434fddabc46b5f20995e3c9777b00a596ff5941b5a314f107ff6f998498b3105c4af87e4ecfcd8028f45f1bd153e755a5dad284d9378831eb7adbf77fd9aff89ad3103ae36a15c1ce0e0790779b831d41f1b46c3debb9cb0de31014b256bff1e762648e8281cbfc14d9d112ab09bc0797edff3e9091891dd1d3d4793a5b3e3bbff48c547c4f85ca692a119dfe7441c391631cdf88bb96c87b604bd07b0fb8371442a00184fb25a5e667b3941bf2efac804846f083ed3da56822580360053820730f2d2a5e1cee420d6dfe4d332c1247ea5289723cb85e388ce90282100589800d3cbca235188ecb2d5abfb570c7eefcdf22306f21bb4da8c43a15ba12e9c6fef7285435b27cb68220bac84e391cfe771155d76765029a419fffa8e816e5ff29a68bb06a7f47cbcdf1a26e906244fc72c386e659d19df4eee6d367160ffc2cfe817f29d7ff909da9409c3299e234f134d9973925f36629a8782bc9ab3512d8728bfb5050a5869224a5cf48bd69d2872aab8ab5adddbea766fd0232f4d356db56e8b160cf96d6091bd5d778e168799b324d9956eacaee57addf8d248651e818510e84e0c4405fc142619b684d7a877b1a38c0185e4e6868f2fd5127e053787df17b5c395912f398ed3bfe4cc71266f70c03669e832ffed231d0205a80338adf332aecbebd18f144d49d5f4a56df53125293588ae01b0759d89f9065892e34d2a3249b8b725578f0f3cf714dfad1974988c4ca3773b9645f4b3042aede71e7806583a6c99a23034a30b11d9781cea44ff6682169a7674707dbb1ea2fb116e040147c09b136a659859982bfd823ed02d1a0d76e31881d04d4fda5abd11ac7c1e940e47862d97060a19f6ac1d1e765f3beb1b1b2dd4598cd7919f7532b809a6868f1376a37775a878c70893151dfa0295e26b28d02fab07de2230c655b93b3ce9a100edff4de288ec6342696a19cfc94cc2050b7f9a31320746b098d58eb1ae658b9498ba464e22813e0fc4857c6859dbb25839130eecf8739088b15922b58b2b313d1485d246d45b01604d24f824520f8de195a1be7bcb091a73da2dd24c9b6ed7f7e37b457dd159a42d2ce3b583ed58a9101af5952049e13a48cefe3fdbf2742ff036bde3033903e4ffaec611e56930111fa57de20491b27aa3d0a4b9d49f2edb4b2cb5b2158e5d2afb85a120c7571e302ba8282c72a642dce90518040852855e0a5014104afb9ba59e99694a3115684d584e53c6b7e4b91da922634bdbd39989a78bd1a78a0b704d19efde686e0335a4b9a336377a61defed1df47392e3a7d8fb54e9cfaad9152f151ee3becb9d2cc120694aa7226e31297f075aab8ddff85b9e8d2432b0aa1b4f566c1d5450309cd04a87cf7fd98d1c32798e20ccf5186ef04f6855d1ffdd007258769cf503426181c0db43fc4475b15d0fbaee1a108caebd0e45b61f4f713f0930d4245639bf5a280ec5f9117107352e40441f55384d65219d0bd16581d84b66db1ab08ae02fe364143c487a792fe25ddd943c79216f060b26722213af273a77c71b116d472c1192ab17476e14329e91b97e628c0fe31cdab79776743d1b5502febaf7b4997c5acb7f972e4c14f29404729503c2b777798107436654ef7d587109a7c84cf3446e9acd6e02098470ca57d362666807d070106fe0b2dd8b5ae2df7df00af2fbb16d1c8b682c2d78cbb30a012c61381bdd4f4bb40e782be5f298b238a78daf7d7b9fee2cf5741fc874143a3b2a23009fe9c393fb07b9eb9bd47c81da68cf36ea55d026513e8b24e32256023bc25c04ff1012a53c391e0e1a9d67d9c0534ba3851658bf5aab9358e1058d0cf765a5342c1a22ff844093170c98a8978cbfe9fdd66ee2f0a5212402fb671ff514176b6e682476f99c52a3c92415b16bd0683f5934a72c5896f0ef8e66641bf57d8a3c32d439df35daea00233156e7bd0e0344472a5c61b12f0f56d685a2a33a930f01abdc5486afbe88acd708bd1d91a8ad67ff790bcc1c5182d90b3c773888abed5d40858a6772466cfdd615c939a5d05751c31a840f8527c92b1610199f8b805f49eb2f6357c3514edfe1408f15d80a279acac7b81bcb0573929efcc46028e010fd63da182b275f782b440f97ad406fc7874fd82fcef86e66474e495da746b66761335c5c4f91ea4ec4ef1e0a6e7c1d2b387038c9c1ec2f0a3d43723ac87a3dfb11fcec3f5237711eb51ae05e922bf191bedd7195701ca7eb4954e0ffd4b5847aea2b2371a1190655877fb3f6db2b2b711e7d78f94bebe7a13c80bb60fdf39ef3ab8a41f2320d54afa737544fd4c15676f3f233d66fe0a15d3359d391e8c3459a4c7d45832e3bfe9ed84d259322844b1eac42c4671c4c83682ee33fcead04dd9f7071e0c05141ef4696a34f04312c33a422a99c38c908ff288c82c615ed6547caef3ad525c159304ef2ef0d43fae4931025616592d52e74abbcd29c4f70e5e3f34bf518812f856996039a5d935a83e50c8fbbdad797b3b8f7384e32eeeae3311914b4c3af5ab44f571b951d93b4223535be0710107b179ff0ed2e54ea1a1ee0c1f16f9fd0bfb49067c7d1131876047372b088f8edae28743d1ba88db1446766ccca6da5920d8906e6efcbde6900e7c1258855c8beceeccf688c0fd33c662e299ae99d6893808a731e153388d34f9800fb79962ca0ef9a74a8436027f9e3f7e675acd04f7a229fb90a8528ec858f54f27d86470d41be50e2d0b7429287585650f8fd4fb8d6e59330a48dcdf3006fe6f42df93daa5895c58b88f0aad85750d3c334159b28f10d2789fc7b6da5151495b351bfacba9d93e095312fdacfd4ea0820f01862fa15eb854a0e6b35555e175c9943774f597db629bd819b7f9fc2739d0d05d7d4c0597d0f47559d1ee568d3b46636e84bd8655bdcc860b8bd83b0224fbe0012e65807d11f32dae38386ca685f7e29293597898652db252be08133dab4e135cf51f8b0d673d3044c609745ae0f2ee1be7424ad13b7c9b1a4cee828ae9e42e67eb6d788434332ddaccc39461482d2735794e83dd84a3a06c79c5ce6890c6edc46a5c659526ac61918080ba96aeae6aba17f6a7251abad39ff239ce1b246c1633c7c3cb23baaccffd2c14e8166e592464bd52af8692854e18398dff5dcbfc0b13bd5354765083e7f5512ae0944a682c874c85b4daf0bf4284d1192523b43e31c138d8d539437ffac9ab1f7b87554de81b2d0c6ec325da31dbbeb0a02bfe7aded25961d104401c59625f4527ad3c6387e98289a2ca2ece960d8d17d3ef8898753f09242cc7cf4d5e1c012efe7c2941a884c974138981f4459d19f2bad9e635d80d4c5155fe0da12e712406861fb8347af5dcc60e58867b860ad3824f713fa41022747387d0da1f4f973fa1bf65ba4fb4c805b9ff38559535c40acc74ff0cd8d60534257c668017bb041944e37096243ecf3e79e479938175edfed4a14432773aacc5a245a96c1e5fb4e5735bb07332e6774a36fea31dae9f471c1ec818677345c67"""), TestUtils.hexDecode(""" D46F4482D570F26C7E9F0F74A354174CA145033097CED3896350DFCE8200CB9448F522B118698DAD51F6C672E1B12A412DB6B7B95CDBDAF6205DEB631E44634412F026CD95440258FE5F0C72C5F3E64FB3FD13E545DD856EC2B7F51AC28C0D5D698C66C700DD3E409BFD96E14A9DAE1677ADEF2CA2CCD178B826AAD3859E569541561073095EFCA329B5B216563D956D8B7BB918224FB479FF7025FD8168F54D14ED1FDF0B399130C6117B5645D0E8DD242C3C7AEC6A8361361CAD9A8FC3B5A40BF7E73F1BBA9AC7F5A583A5B0EB95AD0AB4C1360D0145FC2C3A9AA50186D649B72B41DB7EF392E663497B3166AF9BD0C1AE21650D6CD04DD36532AEA0FD1071D6E9554CBB575B2C1ACEA3DD4E18615FE83AA211F8AD330C78FD32D920ACB40627CA4AC80F840A64C019124079484B053F525A5403383C21B164D0C6BC1B462C0E1C269A1EA0B2438FA64934CEE47149C4EFF566D9C2234E656969C1C89A0B0A4DE124EB920FF534B934172686A18A1A269960C725940D3307B8A913D56B78A6CDCFD559FF97E225B61AFAE7F62B060E7D3E2D4040D8D9233A24827434AB4EB31B0D528CB0085953D9A1A0FFB748588A2DDEBF241F93B41F5C856159EBBBC6571AB12F4EB534ED3C624CD3F5F836A99C7E6E2FFA0369654A5C07C19D44BC9FAD96983660E4D6F95DD9C38D84DE11271D23A6158B685CF050121425AF91C6FFEFD0B2061F54CC4393F99857F3B9775F81B6526444AB705F9CB88A2D276AF2F530B646FC3D93DE7087EBC1FBC7F9A8DB3F3C8FA186F7B636CCEF99FDC4532E54F560519C94B79B1158D85BFBE23D4F36B64F8056BEE7558252DBB3D9A43748E2E6A338162F5E2BC0934E89DC79091180C93D340D3615F82E7780FABF782E5FE2B5D504F3BD1874EB5DB76CB616CC034D9B2B080319FEB8EB97F62FA4498878FF049FA97C56ACACD2414E0BEF018F25A6254448F02E64815E525AA06AEAB53969A66D453B732891E31C36679B5C0A4637611A5983F21F6D4ADA1DA5E890C909A9E968F947C686C17EC73A0F9BAE5C7BF7433133F35F22D2A0B40CC135A7591E2CD216F7D8018969940EB9A5C4BF21579C524C41AFF5DBC0E141FBD02F1BCF376DFFCFBD06F9CD4384E128CF1F03139C853CDD04DEC61EFB8F1DF1A6450E4ABDDDD8A9D85BA79479562A08CDF06BDDD2E740DE7AD9AD1016D72A649A73246E8DAE183AFCD6FBDC64B6B6B2EFDDF525F3B764CAB39BF8D617D47FD3380B4A30081AE6C3165E9437B2F37A73AFC5E596AA626FE5A32D8873712F99910DADD0DE296577D4749F88639D07F83B0F6A05B1668D8008EA749580EE5A629FC2313FAA2F8ADDB5764B242B6B595A39AD76CED4CE5BC34C580069071BED1F98CAF4BDF740A5B1DE3FD30C29DAD808537CB16D0EF22D937F297F50E1681C898375FE0374ADD6EA1B84C10261DBECCCA8E1D224A4709497CE696BCD2BC1369F4135E815A781EA26A055DEA28AFCFDEAF6AB1117085EBF6B8AA6845FD4763FF9274BFE5FC6E377B9F9DA8263DC1F3D53C83F446ABA5EEA4095AFF91F3BE30022B9BBC2C74FC52A3B15CC76F29E541A84C5BF42D499F9B5EA134E24F01E8D866FCD20B7F7A302120B13DE636F48FE8EB99F17ACC153CE4371B266CA61D13E19793CBEF12C0EBA9C728096A3DC6A6750DDB0F52E3807C22EBE4DC6B2407593A1B7BBCED799DC3EAFCE50B483818D903765A63FF572F5D4481357CD6ABD89EC260417306DA1CCF71DA568240D4FD6858BB7833B2C9C98B9E7286FA491F9E318F25D0459071848BBA0D3DB8D2BDDFCB7B8E9C64ED67B4A2B5E1E49B55C6DCBF93394010A078E6F52065AB777C7F6D831DDCC115CF316ACF3680BE8766B4E15574AA383030EDA83CA45B965836FB2374695B50472C4159CB7980FE48B58B40C6CDD2629FE3C6DE6E13ED6728FCE45024C96402B78BAF37E74A1C071F4BCC2A1B84933C872FFCD87C02DBE65438A3E770903A04DF96C569FA69828CCC32D13A0A419FCCE454F06EDE43A97CE5A9A169C6E849F075C66BAB418791778ECB2C158FC19FF5927ADFCA90BFDB3B4216E19BE11157E858610BAA373237B42F811EA97EEB93D735828B2ED092518160A2ED894BB108AD74AB0113A8D5882D99A06CE2313BEE3F902D5CE9CECC835974A47FCF6FD1648C635FE56D1B2404927C49EB53FBD625E0624D5AA04D6C0D5A082C37BD67F477850458B8672C408CEADD9A55CC268B75BC51D7B3D75668D52BB701BD980ED22CC20611EF618277B82624A1192287B46BB5C4468F94C68D96F3CA3ADED476A18BE6CCED70924139F2E16C8A54FD6C9F6695E624499AC8E9AF86A430AB856924A0899E75C1FE4A51DA0DE1588E66044B2465C04809272B2A5C8EDBCAE42B47E439FAE06938810526DDFF4B64C515787B41885BE369A31F90E2D6F6C71528412572A67DF6E155C3705929EB28B80DF15345E0E32540BA9AB7E1D1CF0C015E50C9180372C678CE6C34BDACADF45B0172A1D3082565E16938F57CE6B55D9A711CF72E362A2ABFD45B7B56D48E89A0079E973F597D2E457EFF423E229AD439C3193C264E0BF9A8A1FB50266AE4E0BB671817CAEF10A3BD43452A2FD2DCBB2481D63BB539E0C81F6986400D3A619AA92F250ADDCF661FFEDE7617162B532EE2088A87F58E1FD071F5D720FF1F72335A5B4582F1BEB3BF19DBC9D51A62CDF68A855F7F6DBBE5FEB226C9918E7FFBC8A38079E411EDB44177F843EB8CC1F73B9765A0EAD825B3C43F6760B5F03BB75DC7469701AE555C2B7037952180255612DCC9CD35DDB31F3A9218397E1924791D29C410D2E4C3F5549B7EADF75045EC78D579EA7948D121E8297BC5A3A9F7AA2E2EF5776CAE3B9CB73316170F9B48B657BBE365B352A8129130BF1E718B386AA27E493016ADA86C4B3D3D116B7252A747FD50DC14AA28676F1C25150A86C9F4547189523280A3A897F80FDBBA073EC645C9953B7F8CEC3BD08BC0CA5640545B08F728AA38A860ED38C068F0D"""), TestUtils.hexDecode(""" -216B7639BAE886F93D92D1BCB33B6014E962751B281796AA6DB6724C8B546AB7D62CDA401D6B651C4BFDC699EC03DF4018489EA99B8BE6A2D2CE3E442AAB604A02FFA0641523F3EABC9BC8EDBF7C19CF9DDDAB6A81E4DD5EC6754DE75CD071CAF48AF49CAB50FEDD7218564A02EFB0224957FBA6115544ED19FEFC7AEDBAB4832C60B454564957C0CAFBEAB5F71F4AFCB68458A503E800D6807155E5D61D78EA973FBC45CDEE09F5503D428F547D0CEB07E42118D0537712CB2554F25F0EEBE0C5AF76F9A5E88B9966D1504B92EECFB267121F1A988EC42E675CD605D6E58CAF7E9588E7306F64C6F81BBCB0D7CEE234AD2595932E723123EA215AC877FBECAC9D096BF307F487B0C7648A678CD608FEA23162D9F6FF44DB6D953CA947EB16CB90AC9D156A8A9A60EB7781837A71FCA2F9D9835DB909368A5252C050051BD72BC5056797E866F041EE2221836D4BF341683977FC992270D3ABB95AB3665EF002467A136CE28077C9868680E4005EDD8FE15BB499DC2E95846A9266BA44ACCE9E425E6176149F17EAE5D6176651D2ABD7C1B6538A8F26AEEE04840EDD165C8114CA55D500E1B260B2F469D3AB5FB90F9E198ED5A5A7845BEC24C3DBC48B06D6D211941BF86018EE634B3CC7D060A1FC3A38662E704338A197383526D4E55F5C09B78FB7DDB9A38424130D0D9BB3487348FD9ED8D0181BA9DE43EA5B5701C5F9DE3FC88EDF84846C7733651D5653F75B7E6A5C87C4F236F64147C3361E790ECEB6E20CD2482DBE6F2CCE55437828F4F8E1AAD0307947FC33850E27FE568761AEDE63026C167830A20F247CABFD0A2AD01E5799E0D68FA5BC25F0D2F9B42A2B8411B995636D472498990C549E538101D0CD0E29A29FDD5913FAC1B40F8D9B7655B250900DAEADEB417FF471D5B52DAD310FACA606ED22E4C98868BCA788DFA0AA030EE3637B39B3AECEFFABA6B14C733E997C2130503349E6F4A5CC89431B063819DED0C718BB8F78FBF763A64B28D315B6B0B90D48F94B306F0B42A41242CF27315FC69A83DE094D2CB11FD307E1268F976FAEE2053AA41CC2CB6A8B878407076E237FCD378699F5E65856356FC9363F4202EBE78483C4B2C730DA86473CBE588356F353B7AE64AF874B824B8060EF6E4CB302AF8FB027A25606B68CC4B3803EC2FAE996E8FAF2A6D52FA226E684D1EF4E950FEC819515CE9EFFCAAF7B277C5247ACFB57DAA0812B2477B4A18683B98D2BD11143504BC181397ABCAC048989ABF0386A17B79BF73A12BCD2DF5CE96BCF5FB6904D7BFD5283DCFCBD922EC508FD8C591EDC5B34A123857EAE97FE3665B8109E4F29F5625F475199B57F425947F37069CF30017935FC68272A1B18DD7502DE0798CDDA5A0B21E0C24CC9D8CC15F1F774057E77A007BE721343DED110C56E5E80596273BC9507B392051CF19ACB15A3606C452DEB350056CEEFC12A4467813A37386B99C966FB508D0C2FD757E9C10DF490CF600DB6FB3CCEE68376BD7092C03A3F3F60DB1EDBA925FB5FF7802D9C4618E53DE0DE1D8397330D1167D63AF0545534DC5644C16E6531ECE69579013D51C7B98497100308C1750629C8DF81B45FBFAD69F37102D36308AC63AB2D78D2F711DDB691D59BF4C3483652C260CD1A7EDF1E01FFD4E5D8364C69CE247B9F0924E6BD35D358B63B18DBACC7CA1E8C786D1437A730CA2D24FCC92D59E90F4552D490D19A06E11B1AEDE338A3A8D3207688FB27D581FDFE28C42B66240B6C8F5A24D50403FA2FD34DAA370F0504A87F28A4DF44AA86AFBB6D67C9614CE5CDF5C599CDC2C6294B25B641DB59DD7D73DC21923EB8AD68EDB4D0B16B7C16F3161F7C8C0EC493FA9951251D1C5394678B656B332A9FAB7477F32BEE65407B3D2EF6EAF70C1B430B45E104142FA2EF72209FE29558485DD26BE8E1B526B7098F252F58046B6EEB17D7F0734201AD865E7A6B838980707AAC9A05DC8C34E5B36AB03CCB74570670967C3AECAA9800106ACFB0B8EB38AEF82114C2036677118317E339D19CA34BBB68B30E46DF3136481AF7EBBF8C45951C8733C0CAC97E518AEA69A41C641C14EB71D6DE67A5F7C5C77F75C98906A3E5F2A6E875E2B6D7C8BD2A54554E19616FE3E8C39FC7360749B5133650508E8254601A7B33B82C1BA537623D6DAC9C4C3006968EAF3EDB233453EC8DF00D02D022B6A552FBCE8F3694EFE49A7C6088F3080421D45DE8C2F06C312150FC0CC0DA4DD35D25E7F446932406269D45A8358CD1E2736FE2E1C366F24D5A6DC11016FE6BC73447B1562B1C021AA9BAEED212B0AC8AFC337E1CEFF1609EE3F0A7AAC747E185E3D860D1D828B6EEFB93B31C7D2386155612A9815DDD2411541D91B0F99DE4D762F69C91C527F6B5A1BBBF6C8D65E7437F0FE9CCC669EF9D1F36E6E0CC47B682449258673A02B12248FB784AA2B7F15FECC3753119AAB9F77B3C5C677EE4BD54BE29CA5722E37D744E145F9E08A8F8015BE8A56057ABADB987538C0A1E02A9DE66B7666A0F4061A4DECDC2179E3613DCFEF4AE67C66E8F6114AC74CD9464EF29BEB0830CD2E64E9E5D8B547C0DCD1D625FDBC87E8FEC987C5F5F5E3D0AF5BEB341D62789F77851BF2D7FACDF815E101F335944D6EBD0F06BBEEE92B5DA5F8F98B1F41A2463C6569834ECFDEEA395D6D26B6EEE7EA08D261970D2493B86DBEA68663C042FF7791725A58F6B062697AC0724F09660E2E630C39FB7E0568785158CE9A7EF643CB93026131A9EF900E16DBE4E5E286AF8CF89C69F75C6CB32F3BA9D3B779DEDA8BB75193DED6651F452EA9124947EE70D43BDE04965F5A64DACA8CAF2B5885FB75D1847DC07B4C631E57843EEF344FC4B7A3AF886209D77CE5841BBD664E898F939704B7AF6AAE6D55BF3243E7E85991BA8F0C40E843E50CBF16A34A4E67B0C115542D93849F3C511D977B6B916D59F2DC7FEF38542B6B24EF7D6AEA82263C02AE73BFF5DF8110BF1DED037CE296AC8AD076642EC79F76AC62A1B3637BB4F3078BF453ACB2BBD3A9F30A77D01574933E79EF3C64A316935E8B69BAF22FBCCBCB10A2AEE120FC9F15FF537E3C73F2B3E561F5F470311BA00528AC575DB40E162DC23B9BEB3BD1C916D7E83860557DA21EA6C0E55AFD0903FC9AE08011716D67EE6B879EB7395B6F791B6E946DB867F6E9B1F11EE9BFE04D6AB7F294D8CDC6055AF46AC33BDA8808785DA377DC45BF488A7257C1E7AA193438A67E3C667342FF120FA076DB4057E8AFB443C07C72610BAFF2359CA8269C1795C622B7FABACE8599D039593832B46473E8A823F79B973C67183C8ED8F9173604CBCE4F6964265B93954FE916940E540949950B72DB4EEE74C5EB386109C99537D1B0E6DA10F12977320CABCB53C47F62E89F2C275C8D310E078FF098E4D6550CB80BAF8DF93DD77E5B3D32D94E13889C2146EAC717C7FD4231406391ECBC51E9161626186D475AF3EEC30A3FF8D6458D01980BA72AF05F03DA6DFF245DF4D23D976DA87D1B92663B82EBE0DF8A104ED77BD121357160AFF118D76D5A232E92AA1FCBB93038DF7FF9319481E03B768B68804B1BFDFD0DE0E1C58CD7FAA6FAE5D0FDB51E594BE5863303216E65D27B1EBEF55B77E08B4B485576A1A8FFEE4FCF29F71783721B9A4D8BB50D26BE513CBC62C787C7DCCBF0E2601AFB6373C69FB4CF3E50F4542844A266CF19207389C833AC3A03728A4E70C5AC3B4B099482B1999550BB8A1D25DBB941B51B872422FA57DAC6035732CA3B2F30F947D7B8FC5EB53808795695A295D7BA74B558BD0175A8AD7F46CFD6BAE928DB33A9E3B7D0AD554CD8FA09088325E5620A06C824A809461C378823293E0E7CA10A0A1B345EE60780FC1559CA354126F30FDAA421DE4A3A21DE4F96D8CCAEE2E1F2F99F462470F8215A6BCEB923409CBE4CD24D37252A6950C4B12DB6F2942F547F8C646E0B5F4C1E614C5B6F8EA0E23B249ED920DB9DE3E001CCF5F99FB3B88EDF9391833B510DEFA73F26F9155909773188557E57BA3C5268B45933DF9ECC4381377F2883FA121BA0D11CA20F989E16B43BAE6FA5B0D9C74F8563CFAEA595DF4C887E7970CD883A95D9017C08838D81559A95490FAE1C3CCCA7381EFDACDDF486D158704BB8EE0D9A388487566712736FA9EC72ECCCC5F88348D39D07D38ADD76788B96716C5008717C0071C413C3618727C48D0956DDD43876B50BD63FEEBD2692A01A1494AB26EC9B76E428242973AC66E6221D7404223F8AA8DBF1075E703C7C002B67FD49BDC253D604FB7BD38E27A56B9D27E96301EFA75AA02309336AA79D83FEDA510055C21D3A167458E883D260E11ECB2FAF4468D7D648EEBBF4C48397EC3058C163B76C49729BBEF4AA88B37D9989CEEBF3FFF400A1B05860D921440B5AF5B58554E6367743CF61246302D2F0A1EE3BC26038FB52304EE8E9BE69A3E50E7076E17E2462B44F76D3EBAB9761013371436F2564B23BDACC1134499DA39C276ED99603288D6A0FB997882C3257FDFCB71304B942D77987919845437F7BF114D6FBE9992A5B38E4ECC366888A9AAEED48504AF753CB88EE458C7FCC54045D9B9165D2E052DDAEB3AE8F8633174A22231C0013135D824EFD8D4DCA97A86A46D4A64C9E046B6DBAF99C3047C06AA8C53F19283BF3D649819E8E86E749D2C74C740C0BA0251D3C77C6EC2FEB3153D09900C7198569E66D96F40B566FDCE24B09964671E1B150E2C4C587DC97D3DF2F03AF69D9F13B3A387D1FBCD8A4848D9136BAA520E4CD55D36BF78CBAB778FC8DA179B7E8FFEAC21E3A3BD2ED16F332C2A39841A825EC138BBACAA19AD846A01F15B07431DC989F3B870FD27FAE7DF63EC34319E95304CC86EE8C978DEA85A8ABD84F839F2563C7FA7D1C7198DDE5B40FFBAEE7627AF62D7F57E2DA0C08CD02A5DE110C7FC04DF6B493D4656FD03B80E86214AE5DC00D9BA1F34EC1CF95FDC16732422515CBAEA1051879B87C397B10B08BDCA1CBDA9B10A53DAD9B8A13AD05478A73E88A107C0AC73F6C4CC08E7038AD4E2C7F918CC0BCED92AD77D0CE9C7543B6BB8539D0E3B99A7C6BEBFB4F90094BE399DA1ACE5668F5752859388D796B0FDC2161EC01E64EC17FD22C52E6FA14E5D057C78CDC060A06D0B9DE3A4E46E7EFFBA743AB83C14C3CA19554B1AA7232B6724048EEB80A256C7DF100ACE744CAD137FFC541D75FBC0EC762DC9BF26CE87A52FFBC2DE6C079A50F4BCC209EF47A53D6CE5FF88E90DBA6BDDC707EB93501701CBE6263CB7CF6A6A2B69E25B23658CBC94889AEE51D6A16EADA5C84181CC35257ECC21D60D8CBAE2B46E3C69C48325E4785BEF9A119BAF392CB0469B23C75BDE002898B6896ACBCDA44744081479F99CEF23B70AAB1378AB9F98F76564D81565B380D8A994AF696ED2B317379227C28F880CF58ADD23F0D49F829C5D23865AB87A237FFF17DBD23E34E13848F5F0B4AC551D4865A50183751419B67F30E3292F96DB6821D1B788B21880B5D6F0F88C1A9098C5F07F06474B9AADD76733D329355EC6E4A4658C81D4095B8E1094BE2B1EA4D1DADD7B4877F144EA45D102AA0AE7B9962F7BC5B11CB3ED7E9DBF83BE020EBD4D733C448426E7549A5225357C0319F8A690E2FB2FFE33B73F26DCDD461BDA2EAF1CBDFCDE7CC90A5F94769DE9ECAB066CDD158E55F10C1CE3A9B3793417F85AF871AD9BFBC8B02E3A94200F2510C0E61F5DCE3638E6B87F2B299FF627F121CF8DBCC94479A2CCEA282597CD59BDE0294857C98BD6D9066741AA6E4E8BDF83E00911B1BFC947778826022F6AD5377ADF7495F483FB01D7B83C7319E08BC13E6F161A534F5337395477FB7F03B5051C90FDD486B4B6FBE0C963E9650047E32F666FC3C4F9C9B391FDB4FCCF24EC379639D65F676BD686C0030A5946F0193C11759275F23F4AA242F6BEB1BB7C6FF4176F589AAB96C1D8C2A8F73F1D87213CC2AE134DBE1A5EEDBB6155DAE672A01BB621CAD4E32507D00DBA534173F6207441E65118459303DC8510E996A854015C50CA5508B3D3E9596F242FFCDF2440AA7DA52BCDB0CBD6B9578E0CC2FDF1B880C0187E280C4E2FDE44F2365A9E858D6C5197B56588B89131387ABA1B4845E1E515B4CF3C92478B50933F3CFA42553011DB91B47B16B2151DDD6014787F7AB7DBC053AF93468DDE606965BEE41FE7ECE2EACDABBACC069E426320AA26353F6CAF896D024AD9C5C94FBADB6BC93C5579CD1D9F4CB3F195C919D985E61B56B58953BC69DD6DD3D27B7A943D6BFBD86F41334D82E9262F86FA58006DB66433F02284796DD668D27E0E6B4C97D8A6442502603CC859210CBDECA85DA3CAE4D7CF080F9AD820C6CB8B54222A71A13864754518DE2CDD0E168DA6E601AA863FE4C05B08B4FD4DEBA3508552AC014FC3D2C35D264B58871B92A5551A033E40A9ABBAF2066580EF080D2B49899411393F556583869BF11D2E7BC2FC0C263B4C7FB9D10104353B5E6D9BA4CE0613535DF50000000000000000000000000000000000000000000000070B111A1F262F34""") +4e4fc796e18a11fe191e08e2e59c8864e0040297897b07d4f62d8a003c50f26e7a6e3d6aac87899b27b308c206efb435b7d48b32a6384e6c733ff5f47bb86ab493d403027cda502831dee50a116708aa01dafa83fefbbbb7aa7411ed417620ce6b035cf27cfa6ad1cbe7e1979f024a436a39fb6a6db40dd21ec16b90a42f61daab8b86efd38ab87121c17fa77bcc761afda7d9196de6d6e4a9b45f32d9cc64ba40aec6c9ec42a4350f841c1e280d60fb1382540f5ea25ad4e7c72333d4a6a4c911a9bf142062a50c2c7f61329ec502e4b4295409392facedf088c321929be05caff934dea89cf0f13b771bbb7832b956aaaa329c666e5582d3e4c51c53bfffe1502559c542f5cd0c6961f1a8a6f4db4e109818519c85f781fc8b81ad4db1a2444016523d79f33b9deadc30030a453bf9c9f48b8bfeac3a563038544141ae621961de26af46860e0d80d4b66bb47607a559dfc34cedbdadf7903ae4271ced072c49c8b91aefac658d1482c913559325be77794481ef2ee6007b643a27a3eddcf29a89237c340867dd3a8bdbbc0a1c8d07586fbc8c3bdba699f08afb44d728376d12aa7547912fd9b8069d5d699773e426f6aad6256853c65a896b5266475b283c17e60dde89a3b79f6b8c262d418b219a9aee8de0718f171d31c24a632e0f9db87dd6ccde3e295241a1f85e439f09a8e17a8cbc8d2e2c5f68147c3cb0138a6b386d42652efcc71315ffcf218630f96734f0c93d0f7ae946a71ba6939401b7d60f9fafab00021628408c3cbdc4c25e2eeb9af29a16871843d124551a4437af15a6042a9b2ccc227190eb7b22eac650a5ff9bdc1bbe867e0ce4222b2ff68d042772f7035ba911f2c4e3f8aa094290584d3902e4e1416f11c313efe437128761e2c9bb160aa58be7f2e3b821c128d69849c6fbd2a4ea4662477491e48c482051ef8f9e1c62fbcb03ea8fc25134e59cdc995575570056cb57fa0460731f3a82af5441759ac4f7c1ab5f2b2f5207e9d1350e1d47cf338c7be3aa05bb9ea4ea2632eac008ec50d7980d681bf91d1bcc583332c949674cf42de62632fcfbed112da44fae1845ee2490801528dc5a9f14f226d18db70a744e5bfe097ae1d17d6e557f670998317d64b45be39b9fae81adddb53aa5c451fa9d525d8205adef6bf5a500adc87a0af2069db0da6dc56a0a8807cbf19172bf8f96992c3c0d2b4e83722463e6f6a702abb058c0f868e9d9080760f2c80a1f85e30018642c3c88b1489145de6d53d27ce3c9f1765dbb459e865d3f8c05afa507d6421f303080c77647486a0611dadaa0a9a58d83d0859dd57b492c941d47f97529d962863821455e52415a231e3704e8d208c15ccd4a1e5cd0c2b434bcf9f82495f0d94f3c91d1cb74cf5da019d0c2a42fd45580db8545366a56febec804a944ade29a2cf87fe5772b3c969495e304c6a7ec148651ee93e2d894342c830849db83f40d9908d11ab2c919704ad55c74aa968501a38069ab310945f0dfe253d1f58fb8dabea9a8160a9fd2b5a0455b6d899a22386c8e814cf50c0aaa35e4b0420c59c339b84332047c9f193de73a9cdaa6463ed2bbc81060a36dec8b10f002161dc56f2085ac03475a6ed6f7ce9695f8a0f4fc044d2494d632598d778afe58221e5d435491ebdc30c2a719f90ce17ec6aad77df11b50232bf1d4eed0195765e3d1c636ae13f0cf95984581fc24a699640ec5ec9374588f8d74baaebb831c219b4df35b73eab7e6e15bd5a17a2803152c0053f3f3aa8096facd15a4ba1d2e0d90300f548180cf9b9ffcacb0cab9d6e4877f7a63d2ffda4d9697149b61f8ccef1daa976f92889c3090c7fc5c69bd87cd39d02d2de8ce16c6eaef9ca623872cf4f91fd426eb23ecc9457ff881da1b25373f1f6959dc4986cb0fbab15f7ed3497896621dd6b45bda78b7ed75c7d38cf7e74443a53ffd456ca84ee9070421b796285e023b5165020d3dec38078e599ac79ab1eda37a09b67d4e20fecf31c0244846fe3ad9b5ff9ed2b2f1400b7647a1a12db22bc24a2a5f1becab6bbd4a911e0faa4f4758219c19d970d07c90efcf8f3de432f526082f73b4a6e6b9b048e00e9887c164a62f3758b8b2a7d0ae30ade451fb5b405fd3a7aa2454a70ac22af75b986e03d8de972814b25ca0ffc3335206d30a7b748a10ea20149477610874348c07fd45ddf69c65d1e1854e3eaa00f6e6e0018c7238c7c311285f1ab9c876c52d212781006a8300bc2ce4c3729121b8b2edff63b99a29a8bc8166351b84ad61b66620fc7d0d5760b6409e42450d5fe58ceeaae5abfe937091d2d2d022057b2bdbca1ff2c6f1413021611e09b3a79455aaf2512c6a3d2a949e45db154ad328ef646db243a3242440159f05ec72ee2f5cd2eead4885f2d6dfe23ddc70ecccedab451645e61b17e88cb39d6bf1f1600b2272e3fa523ee9b570e515d59c8e04ccda564ed5ac3651d206695a0b8eea30a097bda798645d6ce20164a2cae126154fb5d50ca5749ec608db68396d9b6ce620cd8d78b701d6f9dfc701a7900db628fc9c25f06e41a70ba6e9745c4be3c0c9b0913d2c584fb2630582cfa1d74fb598515a104423124ed855a9a900cd6985eca4fe1a921a43188fd87cfa5e9defc046000641f58573a70222f6bc22462fb959df93d1d5c2a2266dd4bb01ba465e4e301c26cb9f49ccd87f92b5d92a30c4e7e4583d95a38ba2fd2fda90c8beb60ea9510a43608b817a51b3c5f05275dea1a857e581cde0a5751a334c9e233353a213bf3f7fc38d6843c839cc06df3c6e76b4b6df73c9aa90bc24196f9668cdc2df584aa10dc8ab41882a532bfe758cfcf16f2e6d0e7ef2fc900a3e5f3e261b4062b1fa3aa49422c7c6baf56d0120710459b949ce7b21089c02a14d5907ffc10c53557477599d59d83f368d5ba349c3f3693da678f2764dc4caa11a669e5b703a97a908ea7abb18175b1f208e448b1b05f1cb3deba9b4f244c5905f4659c51f0152aff9cab8bfffaa61a98150425f14acb154e4db9aa03d73860973750377284c275405d726dd615802c8f4738799fac49515f8c04a9b2fd693d083d3ace8b5e872413767114fcfd32436181f30c25621bd6e808919c0abc67fba98af581aa4383133b47d7d8fb67de035f65d507aafb8e1908c8a3ab305b0b40ebb2f70958cd69ba48c3d0f94807f0159f3c3205affad6b2e48fdd54be8e5a7e5bfdb3f1599f62a52c11819b0a7852a3bc1a424596c4da3b1ea7e6e7989d3c403979263424397ebb5b5a739137c1b3d1566ead912214341ddae970955904d9a5e79a002e3cae156694cd895873fa5559a7a9d21f090ad77d09471d0d00f3ea2238043fbcb76e5ed947a3384b05b838a796410b87971f95910bbee1c6815dfc9b3752382f980d48db75e28ab8efd094046de4725c802e1c3de5fee6503d383acc450ca7d637a1b5a68d7f099ded08791a3e845b0a8f6dbad10395b76745a4576bbb66fd6a8750a83616fb5dcedf961c2aa6d90d602d0526974a93ea30b26b01245c74ad5d060f8cdb3476e2a6c155a676ffe0e4939790daac867517a48271501a702568e7b349507db9383f6001c596077f82458291ec65813d6d7306e8a83c36d76ccf76e7531823e8ba7becaccfce8ff2e25504fe2cf86434d81a43b28daa7d479ade72e302f82030e240bd61a52b84b372d460d606fb4b2f649bdc51ff2cf379274e1c6bad82b5407516b792d7c3cb6545557fb2db306945dea8092e7ba6d033afe77833375214c816a4c463374cf36cbeb77a12ff095e9bc4631a3b459273bd3494b1cd49493a712bafd08c6a4d2c866958fbb773eed52f7398275128622b7436a39eb724c28d70f55694cf22fc3ab311653fc7c210265fd6eee872add33250ac495a2f54c9bb856d1ec8704c1c9fe0208a312ef3a08445ce3e9b4db2ea1c4b1ca4e79aa5ded13ac3c7fb69612e74255e0e6cc3a063d28b8e883fcbe3fea5db704e674497fecf7ca75110199434d79ed8102c510d732e612a18a8ddb3384b60f19aceb88e4cc35cc4af247edde5c8b26101db84dff825f9878761a6e96e104303441b9954091e5406aa9cf5d8e4010b4c075c374cddd31f471f694b3b9191a1f3d7e399693e235898bedc55628de4fe245e59fb02ca5fbf1944ab74e2783d9c9fe59f0e6f0de1b2bd70ced8f5e87c732c82bdac560e714546afa3836b73ad16373b72eae416e31b2ef999b2f3fd13f6f52deac065d0de6562cce840ba490d7fd1121d8fc66a53a27d3cab9db374e5b96d44f64b11232b2859df9468286f268bd4f186d434ed3b3c807cff498d1140d7d4b018a03b7b2b86be6c6b3a76a49c94a821989d2372744b1ed2e93e6e978c9cdd5564104d6ad141415ebd06a2559887af6b20f6b664e0bf7582d0dc1ed3e66661ceab0533f4758ca9d9c20211adfbb18a7eb7ed460539a48a131c59ead08680e8723276c1926a35081573d4e0c057457047e0a8e031861e5305e04c0619a06867be34f58200e4504919916c0f85945d19c7d2b2fc20af7c058e5f99fcf83206607f561e9619219da8867c73c933896e24f55363c0deb0d258c3f05c3ad71b3c03e2005145a6d7aa4546d53dd24109f20f902f7b77c8c475538788d3c0d0cd7cbe07706e144ca238c08b3f95672b90076ed237212adac8751d335320d2ee0ae94e95bc7f5c27af3c8da67b8b5d3630c7c6d006ae3ee184b5ff781ee470b7a2a9fc87f5d64187538100fde4bbd67be7a2f9c25c4a6f8e0301595963c280457395883a80ca695e98af29f0ecdd33dc3b417d09d0b2d01c5e074cc1abaf544ba9048649525f59ed02df6b9baa0b61871c4605678124cf5fd1dad07e892d2b8c0b14c0a9bf031493aa304bac36ea200f8247305394bef54f4608efad7435ef3ed5d5f5393225587e1ac3123dc1d92ee383e17d74f0ecb1bb025fdcfdbe7f2d41d0708f1ad2f766ebf69f4933ec0f8ef6f65abed4d883a38e0127530e8fd6ea36bacf454abd510b1ec49dc1d3bc31bc7d2b76c949a24cbbe7f676ba4677e19198d86ce72628e26f56b7c595cd07daaec87602c78a7838ae0d7d03a8ccaa8f90fc2f9e4cb9555d096bdfeacf4619eb3562d91a5414d2a5ccc90b565453f03a0f08d4ab41e6542bd2c687f62a9f41f348a7382bde0561e7c03700b0102962314b014b83980eb887783858a0c2e7818e7c7435a02c21a004360f29097eb414eed5ad78084a1f3cce2112639ec7f9ee6efaf166b3e31aa4af7925e6866743ff8c22d865f28ca97e47a3c979d0c2ba32eda8f862db63e07acda1757c8c7aa4b61d6011f5169f0fed9638b3662af701e486fddf0d599892d4215ef4252dc3248d9fd9f5ba3b5fb3fdd9ed601ee2a1b2192a5e01373441004841190d4a3b44eb80ead8bfa9c541939732913eae7904374d288645f4d5832691e338c82e2fc2ced10cc75e353103f383cdedb81e22ecb341ee19e400451ad3bbf0d10181a796c3063c66b1db825ea00e197d7b41558eb05a18c8e2accf0592a331055d5d09e436983efca0c334919d44f5cf729a26dc9c2abaa4c9086c7c0bded5814de50b86b86408473172e0e90d5d32fd6f93621a37abe618ccb7dcc2df0573d4006bdc0d832156c82735bcfe95527dd6b10e71f38e8b46ecddaf6eb7175879b7f843d821c7edf653b776cde1d389db91c3333a1c733dc45ead2f72644e125e4e2c7694dc4a80b4bb594cd052b470afa7323c5d9de044e9de8fc307512df126e794fcda65d4906ccd8caa5607eb203d4d183569d9cc530bf8db3989b331c7b4372ad0514614de405634d8cd1dc603189bce42e53584dbd7412dc3a7c9fed69f194bc753f45e24a289db30970a9a68245cb62196cd8a36a02dbed39edd9c40f4f5e6412ea5d9ce4d92505112f6dfc1fc46d0e83916693a35e01deb29b5c0d08c9ffe75aabcfb9af18c35e04611429e52285c5936f782c11f2b849280f009d83911bd6ed58b7c0ec9f8d822a538db8492e5f410020973536cc460861e41515c2e137d1f373e6687136a5057903e1afa8aa7700d5e39a23be933e972dcb1cd67ae7edd452dd3d229d957c5822fc1846175d48a5dd25adbe1963048bdcb5ebbea8bcac5498e7d805a0746a95f6ba9a8386c387d4ef863c424d62276a90c847e9019eb752ac6d844e0e45d78aaaaf567af013c3bd313ef23e06f4fc751537561ba52f7ec15cd460d8ab9ec917e1e33f175c3c1f38ec99a09da921ac62dfa458ef2d0d15d4669aeea8d797ea057ccc86431b4010f56fcaf4e7894b97d542bfe0321886333608e9d56674c8eb885086e9f312c6926713ad129c6faba2b764e4646500b72ad52f4158a071e0c0697dcd50bbb17b4689092a36bca28b1c6c02d39dae78e2484ff6b00ef8b5311cdfbfd061884d23dd65d1b0ca4a9aa491939e13202b515d6c709ed4eb0b86c4ee45484f84b2c8d5ec485686999bcbe0e746acbce53977aaeaf400000000000000000000000000000000000000000000000000000000000000000000020c10181d202429""") ), new SigGenTestCase( TestUtils.hexDecode(""" -2C242C2E0E18E6E587ABBF3FEF52D5156E92A73F58F15E88501D7F6DD793D6513627423FCBD68B62D99650E4D4859A8562B9C868E08F2836C1DE1493CBD8E24937874DDBAB2564E8B6D5EB098B1A53F1117594BCD26FCC8A464843135BCB424E6AADEFE7FCC8DD6B27A966D7408C51872CE114D58FD4DC0F31EF954B71C322B8D2106E604801D8320A54B004D480500B179144B864590245C236660C064C924042E0904514282CC34482D82245D18290E01640DB428D1B1781233360D3026C12462501230A83084E9A088D0C299019388019366081360A14266E540648934206D1A28CCC300E04352018212224334888282C4832481A1272DA86519C4289118049C2C0411B484E43082D03934081400C01333153302100116E4C402C49268ADCB28022955140240614090188A66801A60860C46DC3A20D9B129299108A8AA668D8986CD9042C1C276C0A16259C4226108569D3866422A729A0240C9AA04804428189C00802C74014C75120B24122A56509058241B451141749882411E4A22118A40CDA306591C28419442D93B481934064000729CB86898AB06920148C0841520B3412088190D2380604B380D0186561904C802045E0400801A07008250102C90D82C4081221620436088B3845CC20664190402429821A458CE430051123251B250220A16D1CA53003244C4C84410033684C984CA120520986481133249BC271513682A4808084346E60004D2194650146501044611815029102405236904A3649DA168209364E5B8889CA120800308040221104A629DA30650C2329499829A0444DC0128E0A106A019028613850820611D9020D13C190184149404430CC226989A24C99343122082004B6098320296098891C30620909880BC7650B847021A0705A928198B05012261120290D2146281930460CA80844B049C0202684C04480A611C248924C140D9C260444244D50A408C8265281B42118A22449204598B8009A9848233400A24288A2360240368044B26981A24D58101043902543B4919CB60D1C414A94902D4428228B368E64048AD4188A9818281BC830A4402A1B0308CA8611CAC405C2C69121204D208460C3180E22264653961119982000988011A51160286A23037109A584C39849E0188DC80651E3127112A88102158CD3868D50020DC8422842C809D2246EC83888DA82812101609AA28DA242651C1205C2042E08830884A26D420608D38888C8146C90C4440B076CE1824C08394618C63181046409418D0C002A231041A23482003408E32051D2C26904B249D1364943C6840AC2245802319934495C106208310C232384C1B26922B781414641E1860CC4180E2349260A094A10031103926CA2A00018130120968DE3366518176519284C50126203296841B0211B04920497116388099334448320880B444E9B000CC2A6518304650428205146898812444BA68C54882409088454400C8BC20D1395915C260918328552204D91B0442029299C920022208662C6810C95291A466C9AC871A1B02D2049098A123118A20C9B322E5388518B387211820109022010390019337249C04113305061046410094420C568C1C48CA3C2489A342D9AA460CC326E4C30450AC90193462ADC025151268444000993A08100C784D80262510206A4046EE4A6481C29609808319328215A289283222524378449B66D64C4450C179101B54191226582824804A024018329D2004593A64064202513B42510200D4C8410DB901099466ADCB845CB46114B208210802DDCA28821A88921920500000AE4A84810B66D18A269E484814434728A244E82322204C270010324E234504C428111220600460101218A20274D1A39259442098C1405CC8660A2B84802300D093490D3080A0080688A2029123008D49891CA48828A82411C002120460CC0B8214232818C482A9308800C928C89082920266419116210454E61104CA0348AE02404A38410D9007080104CD2464921B304C4B02C9BA80583304D8094711221506420925B244944C49023207243202593C60521234243B04901232E5CC60CD3460252C669A0A04D193809101130C9466D5B324A09230A4B168522056612B97004C96C08178D13916CC232001C469082143183220418A76D40C4415C1001C8180EA0A684E2A2411128918B02450CA6098AC48C5A0890A1A801C1428E04B041803452D9A22152B86CFEEC2BACC5DD2E71A2B1C8A14D54A95430380F6D2F08A08E638EA94C74186CCEC154CE3B78A6B0E275C08A5979473509BB06EE8FA6A81AC2995E8373933A5BE90E0BCCB82D192BD1847A7319F3D61D040C12327370BF046773DFBDA9943C3B35CBEA6AA0FAFF2CCCA040BF38616ADF6EBD43D5DBAE2929DA15E0E26EEE338FDBF503D5F6681692C199A67F29A5938CF32E69EE7516B0C57F73C8C4C686B2AAF8350FD84FBA13AB611DBAD7728353276B0DFC78022BEAA249E4EB008447EE55C47492F6ADB6FA22CA3F924CDD0D2AFD8E4C5427DAA832192A3E36EF85808836AB4FEA9E5544461625A956CBC30B086D0FEBF21609361E0E690563DD39BEA5FF7138726AF93D868FAC9FED7866EF2AF190F7D3173ED949A76152993DBC8FBF3DE466A0C56E0AE069B8666F02EB5D7146718769DD2481E3BEF3E5F54B9F900AE8533090C904CB08633CBDB01054D6267954A315BF0BF748824BD7865DDF8C70A6BC0B47D4667C059F75C758AE56DC9939AFC7D71C2F7D12C4AD0BAF3CCDE9BDF0ACF2739FB0311BBD22B3D62381C64C9337EC0A735B7A02EE3E92939F63ED1A290F3D4A495682A3804C3587855610D2DBA663FB73E220952B6C1C4024E4A9163C853C4686C508B600C6022A4CD7793DF69F3F323807E4623302FF751ED61877221FC25D763A18574F1E0D11ECD755E6883318187D621932E0B30627E023CB5EB88C50D8642D1EAEC03F8FA7FC0179F602AB147522F818B993EF6938C02834E8D328B88D304CE8BDD502045888D337FE490CDF2AAC5237CFAFC3308DDE202F593FE3816B95561BD774F25A7EB0E302D08443D100C28B9EDA8995E5FD9C739D348C01FBE2A4DAD5038C052549010A8C8BC4CE40D76DB2CEA946775C5E46938AB65199ED491FF7F57956AC842C4EEA2A19F50E13FCC7F7A5B71247FB7C6B58F1B244EA25472321ED86A5498F914B243C135C8438E26859063201205901F45ECACDC37105ECA9606164D44A6EB2C9E26FD0017E7B6669C08BEFE43EA0F0A737D2A2F375B21E076BE884689477DE6507211BF8C34BD92D54738E7A41F33332B33E6655B66E4EBF48E415F6D6724272A232F85F59AA9B58F3B2E6F43DA613AF54872105FD116F4E24AB77DAA2D91994B45F89B7B79454A0FA77F1B369BFBBAA873D7DDE82562854CC987B45B3AA38B746F05E30301DE0B9E799B4976446D8D08469F00E9D64EE9D7A38854D9C9A6E6A747E77A9D2C526E6FF2678920B8F35C80BF488A87CE9053DDBF829E409A5375A4DFE0AFCB9D3D4CD8555E66E8FDE5438C234A579C631C7190D875EC6FAB628374018A31DB01795761401B45DE5744F86AD954474DD783B37E4942F5D90364DFE365A38F0566322743313F3E75299635E70B7C02EF7A1D36CAAAB4556C26AABC654E9BC194DE867C3DD89F8EFD710ED04AD115F5EF4E11BE33B67EC709DFE2D4ED3BB257624C463DBB5B24F0653ABF18736C6275E716A474F2E48271A5623F80F89EDFED811E5D0F807B3112B53D3E8D8BA71B7AE531A005B1A1BE3CBB87931E7DF937B2A78AEDC30E9543156074434F390BCD8DC83C43F7858750AC113F360DC1B73C7BC3D61BFEB2BA1D417E2A4774A166F3AE220417EA7DF29CC53ED50A1477EB003D3C00F95EEFBAD9D0EEA92AAC088AF47A94D847F79C5E43D999AA75728C9D80A0BEA59AC3407F1E41A0D46ADF15E51AB89A43056B1F578B31FD389C29936246266B7CA17706BBD0DC7678B26C199ED792E0D8488C5E79625018CD65564A77E6A9CD9838F066E431C312E17769875CAD6B77829E39D42A7A0AC220BFE22987D8FB3FABD9955F94965DCE2F5E534D87A1C2CE9962A6B346953651240A005E6D7A3919DDC1F34BF3AEDFF39FA895C842D33BC9B3C86636516F6ACD063FF512121E4F175F4E3F7C5E3449E6CACE385E05814F0B80831757A93C2C680F5682D0441892CB440BD50443F2EB3DDC6C76AFE8919D0DA754FA617F4BB3F07375AFD8BCC6D06E7249D6EABAE6F46226CF9FA61AAEDA3C85E16835E65556131B103B7CFD32FC1BDA2685951418FEE53FE2D0E13452E912F5E53812642DEEE6043C1390D8290D01EFBCD6E49C860BA552F993902277EA1A1C276005504FE5FAA377D4BAE7A41EEBF2EE689A7176E64D3627C8E01BECBE180629F63625D070697F6140F175CB4D61CFD527D3205BDDC38C2E5E3CA1C64C8F3023B172EBDC9C43B228E521584EC2319567DF0736A2262F1E4987981494AB775856D9E382B6A011B61F1FA4C14F4A063D725D5EB1059C3B10DD8108A689268B5A29780BB72499D758D70ED2548879F3223D410F098127179B3F8AFDEBB8C92E7E2E9F5BC3CA594752DAA602179E25524550D55CE8EC4B819B54CED54AAFB27231FF1FBE701CADF649B4CAAB181F786DCCB6B6F9448CCB080F47B58FB209B135B96B34A95A0F29AD629315205EAA1510BDCE86F3588E981FAEBC2476040B2A255917347FEF6BD984163360DC13BFA71642715CB6D75E3B06EF05823F827591236ADF211FD12EA3E9EDF7C33B95266BB4909EDA767B4312DDF1085E3E687E2A5210CAD2F1BFCBBF9D1098D4843B16597D914F2D17807D4743ED9530FBFE3010D834A552146A928B5142C427131EE73E8C1AEF179E70A05B1214BEFC391287E1D2F63F8FF12A5440129FD97B11FB4263CB92E54DACBB6B692CFC93ABA5D281DA468B81A607EED89B02312607648D35767DD52A031FDDC3787660DC772A3B1CD888AE7775E10A483AB1815C6CC07F7C4D959594B2B81010153D242AC9E9E77A4CD4A14A6F2E2A193EF320AD28F718745E3B68B32B97492D1D690C7494430F24EBF7DB4F1F18F94546DAAEB9CF43A2695D420582EA5413A57E2E03C6A276CF2A6E65CAE1D338E3945BCE4477BB8A702F584EB5DFC68EEAA082950878AD334F63FB91107D7763651622179C732B067E1C31B8A48559CB70FF7C31A7BA0A75671882D8831A925289E394C8CBF0AB0D001ACDA20D010CF4FDE387995D4151EB77309B7A6B6A1BDAB20113803046A48AE6D94F0C5CCEEE406315B4CA43D5418777E3C76DDA4F2E7C7A987977107E26F15238220BEB5EC511E749A6296C81DB3442C6E404E085232FF5B412357081251321337770C376F6919FE30C25EEEC062CA4EBE571D81B2A8E5E531971B7EA917C739B81658BD70F00A7A0F19C2CFBA5F2880CF9A311E4E67B3C54C0652D0834C3CA7924DCD9B82AB4A4B3B2FCF87409E547FAF41F40B95D7310CA5ED638E1CBCEDEE449934B222F189D19A653D9FFF4C567EFB366D614AEB8B4B885E401285154BCFD9D3207F166962C25475184B432837E698C4E4F6E7683485291B1E24A0D8A7F3316425BEA502F4DC9D9B4ED205699C92BAD86AB07D6F94A07D9DFF43F6AB0048942DAD6007DCC146DFF6B54DF61A21C77DC01E1F5C06E8B0C72C72DE39ED01F215F7C2A4D8DC15EDF2C26A7D5EF41876DCA11690032A756CB240AEBF823052E450415A957970947536D08A4481FE2D59507CC1A875F3DB2A1503CAB2E10D47AE301B86EE4872DBB814CBF04A536771EE820590434D066CBA98F05E04F067C12C5E04215CD68260383BDCC210C6CF84518BD630C2690193D69BEA8EE69ED4B1743B5F9E9AF874B37B6890E6A0A7DD660F4701E726D323A77A324F80CBF3800AC10A4CEC4AE1C67C65F5AA31E141DC3B4BEA82333F8A75417BDBB8590BAFC66384574DE632740E5DD2B393A4DAD98AA275D14751B7E0CDD81A651403F6B8BE9ADB0B5E6B1E02EAF0A6C0D9AD0CB7D2A3044872B124CC826834427951C48AF0C81488C046F7668528C7F53A322A9285C93F9B2E15D1A988B213827BC607FA79F6136D4A17BA580D4F16ACECFFF037B8C692B32818F5943479121189D2C8BF01674172B7A709E798FB5D903BBF93827887328865FBB40F247EC85D953714315EE33DA40BD74C0BD805E0C3A180FB5D039493730698178BEA7E4E7B1DDF9017835D8F00D5AB81B9F4C81199C5672E54F0FB9A81004F4E7C3FDD51F5852F72ED8F7003718178657A1688200375E419B47021221F6C0DFE0670DB8D6A9094C9D74A1C335E394809ADB6C101CB7A6FF49B894BCAC5AF8F5B866AB8BD50213A2D43F4FB1606AB30642546D071F38AE5DBFC348A8C8B9B606D493FB6A4B0E3833A52CE308C5E0E659292DD69BAFCC5FC8BD480A53306E9CB8CE71FFA1EB96791A18DBC6FB1DE53A3CD50E70225D1E5A386226F3A83D0630DEB8BC954DFA6569FDA606C51150D741B017BEC309E7B6BAB57367DE8CE7526F19C2FE78BBD4091E7419BBF7CFD94606B6C89FC9ACFA3D8D9E1A404CD93CE933A45A920AED24562CBEDB34D3C117361E7ECFF847D61BD8B46E351569B2561BA7EF25E4C9B2BF562A0A97B1105B8664F6F5408D4109632F23862267867E41CE805A1CAB1226CBE7535D1C7A155D03F3885BB1077E8013EB8B685291CF3355FDBD2F1DB43FD6D8E33320BEC59C6C7AB34FFAACDB152CC01899713AA5B6EC98743F8BEBE45A095B0C67F1FCA064C6727A509C79F2FD46F91972D17B52A192186F7F1E6E58654EE8585D2DAEA8CAE2E8900C598A8AB10B56D66A34020D291F21A8A41AFAC85BB5FB10F10B991F772CBA37F7786DE37172ACFA8EBE6C57DCE0A8DF0C44FA5968E2295B5154922C142CA5E2B7B45CD102D33C260D6CCF0DFEF41C26070"""), +dd746786f61c3e55ab5c50adf85106c1e6b427fcd102ca6495b52558626a21a47f456ec45fa057d0e1aa9010416f9d3e8481ed052935217b3ec0baae80beb73688b4f772a3c3ec7114072a3a9ac5e19a0c32fcbe7331521bb83ce5560700240420fedf21d515a4b69121325116da94da0ab9b51f0c66fdaf466baa0ed1d354a51b41685942056304820103911881001a1480e04251814632c894804ab80121166d0ab64d04a36cd984508a462503458a20873059a02899c06c510268da865140982859c48c0a106ec0c42092b86508363022126cd144254ca2095c0062c3968cc9a80490029103128d19288dcb1448184784633241418670c434925a322e9ba228038905dc1880a0322dccb22049b80861a00c819044194680092345a02231012221cc00122316001480401c46400142268c027198b84004024ce098692425895c440999a28460182c1b898d83b08d10a50c120466c99004e2860949080d1c08410b49219a022e59c42d212770818664c90624442440d8a448a4c8400149655cb24410c9081c4664c2a284001668a24644214404814825c90021e4801044368ad2b00559a82524b391e2c229d4304524838cc9162114206989100594009121354dd4045012a86403418ca21865a44421e196309ca44c0aa210238984d8b82c229600002041db328214c02560124609c985cb32115944891a13429122048308491cc621d9c829880245e3a60990802554042cd80465da066d03060a01c10800173200206a5ba4315412254bc2240b089000242d83468e243105a406658b285103264ad1b42c5cc04c09a18180226c9c98910a35840b868d44106204b52cc8482441100c01846004b065c1a86960882ca1288d94b265a1c20123c369214721622042981489212962228500540072594029cc0622cc342091866902c889643025e1242cca406c84a48c1c1321c1924dc89209e4148908b121d8a4011a957048166d01190951320c99148d18150a6314688b44260214469b140d922822c0208941a86d191220492806604209898888541085a122484aa28dc1846008110414c60199c80509088951440e84a04d21a271a0b02c03282c894880c43011e220881b1846da36241a499220a061d3068048c00488a0299916042123402411690222699914925c262c48963192044c08304e8ab67104216160266c03456e2290618140051c049223354d0b42500407924a306551c470d91012133385c40806248640e202498a8289cb08661c3650049844a3a20c0944250a872d01c6485ca48c11931184464222018018a145d4120a2147605910209b9605e1288213854412a28d1c930004c065e2362062b4601282495436704ac245a0a801c4b631ca82282201921b922920a925d8348658464d110449809668cba484e398500b470288020582a82cd4b820d34231caa08d6222890b236c0b87211909281925128c40709a2808e3c851ca867059148aa248729210285a0812c89450d1300022b8654884202490082396116128001a460dd1b0280aa14104044840c045539401414832a19421dc2686e0b01019184888324a09026da0a045119429238005e028255c968082087220a3910b0452c0b04124b505d8380148126898088c6406301a842c53c24d112409422264cc0602d00869c4468d0b366a218649a114301a95704440128b286cc0388edba648119881a2b2702244690432685484289cb2451008720005101a881002250510a2500b35724ac05050a2811a1688cab8205882610c152523166a93107053348a00438ddb08328308094a10080bb98103c3851a16319c0461e33809d8268c4ca041012591d9925104a6688c8024dc4886142310c2386a843289c948450c128ac3826c8448221c09801c108d19048804373022308401285024c561e3108e09322111b404d102096148128a866513a02562162003194251122024324d183666e024614116888a46910bc24802368de0341058046150445150b689a3a091d4c488d1b0059016329b48654c100ec9b84d2096809a088aa3168a930084a3102418c54599808488841118a7699908604b108cd40608a4c82044a0415410845cc06550424d10379104360083c4404b448d9ca8400a876c9ba4609b0211d3b209d410891319058212060b2551a3c86812a69140b6005c862ce1882044920819b3101bb860ce18425f2c44a094f3f95c4b2b11bea59d00c8adcf72931628dbe4a8b1c4aadf1bdd97e0db31ec98e63b76a8fb0cbc0c9487e76ebcb198aa0fcb2c82162ef9c980e437810129717ee8f285a8b6fd0dfbe360de8a006966c495c560a1a57a41cbff1857dca6efd5359e3b31f5dbc8a3d79c6fb73de995b77fcd5cc359321b18636392ce1a9aa47b7ff9fd4deb6996471ffb7d34a1afc3cc59a1b8ed15cf2b1cc1862de68d421a7029d79adfa9eebeeaed25237344b0a05693e4a61370ed3e08c4f2fe844674ec64c70fe2fecec799e3ef09348b6bf74de004098e6fb5a8351f4749fa43a2035e443e0b5f1bcb0db0ea30958c417def6e6111a68f101ad11441a758fb8ba2212044b7524041fa12a417793a708b31f7e4ebc8850616143efbb9b1db20e8e306a05fae31afdf6f1a5a389cf8aa3e17befa6eada3d231186d7be8e076b3dd72345fe539bed1622645b75a7cce268753e95974277f242d52f70e61daa57a630311d7f709d59b782445cc3be2509ced95bc4ed23daec3e130684d9ed85cfaaa457b877a940786ce854e9cd0d0f87b37f3683b2cdc8540afc14270a5c661d3d99f8dc978e67b57b4792d4626202e8f61be355aba47eefa5a3e55a17b49eb124be57836f27e5cfc0289d28b2c3960eaa9d677a0d2698bb5bb9d3b53aa48eed8a828ccb71987bf65e443c6e38f5f5bd143bfade0a1b48d60ce5f0ecff2029c9122bfbae67cb74f956dc36d6fe9a722b24e6aa2cefbf084141f725c7178ca5e7892c076ea64ead689efe46c7bb64d825c1cb567e00228f1ecdb84c9c8c5f49508addffe58830981f2f57bd88a3c8962eb4b22195bcdccf42d584bb878d10ce5bbf38ecefe75f285f2ab3a594b8a3a12a889162d6a45895db914e99e35884c9b031612b2cc1e0bc552f49142666914454b1069ccb13cfea0e30b7e4c978aaccc77db7049db19a58f0bedc857d869ca91bfe2dba2fc8495d2c557419b7f92a1db1084321a3791b3811d7ad096a121b338c15dbf494dd703f7ef85b44c445f6e93847039da73409ef04c75ccd4bf524238f4cc2ed1da38198ce8a20a1a956eb078cb59309d11eede544c36d273ad18ff32234d906ff357f4ad6f5d85fd8628d16114cbbea2810f3af8c484681354ff6bba268d5553d1a2962672fc2eed27f2e77fe47b96e11903af01c96d919322f533013dfabdde8a3e94f56bb8377ee3be1a7583142655a49c52eee7c7503c65be61ce0ec04341a71187acfe329b2ed51678a7c63f750ca2932bef1bb60dd7889f4e0565e0afa105b19918fe47e57eaedd6fbbac2706a2de315416d54874b065958df969d7c1dade1e0b615a90c1f2708cc6dc27ca66b3d261f933407baf18bb51736941628034dfd1fd1730421dc92ccc7e29b87067c17a03d12a921eeb642a7705d9abcc023fed08a34b621a265262f706f13b7accd54017acab57b2bd7813c5058abc6d1c3e393f3cb7c6c2be70c27c3bc2f7cd01011d71a9a682dfff4f7037c2db2006bf8c30423b3e94298075f7bf7ceff8453143109202c93f1dca8d5d60bb276aabb8ee2dd07e30e8a720abc5ab9957abc3af8c478e8b5ca2520d81b9d1f6bdcdfc588862deb4c67071f18d90a95f3d4805a8e1d44b8590659096d4f7cee1df9f55f137f05a316b293b36a06f4a2b66d428ba141d45cc0d85abebfac417a56933313e9faffe934c9d930de5b5b1af5df86881bedc6691fe899ef9c1398f0ebe790e5d7ac055050f7bfd319e151aeddeed96f368035f82114a85aaedf5068f81e6daef4430d4e4a1b30703278cb3f72f370108e78649706da8003ea913ad4586ba821e313aabc5fb4abf57aeaa53a641f8b9ef2c1153efa20916d3a1ede4580e20c93b50dce1bfb4d08ac6c4f1e7a0e1a860b809700cc42e2baa77bd691757c7766a61d535e2710d2a61f25dbde1c08fd373400b733a7734f580c53e3460ea4ec5dbd7a628b237032888f665758c38a17380c4f29f848355fab6db832e48f1c64ace6d227f783748da451d080a58bd4edceac5c1318c17c9780a3d7838c9977dae07a24f5414911c519a52659640d3ae703cb8ad7a8f3ed7b43e862608a4fd54e2218acf43b1b8c0d0eacf4e019c38ba7474ab4f614d3ee034b5907159a9a37c07f74381f66efaabb51af473a271361c6654cc60f3f992120f9072e466b0c0e99f95efd64c9b56d02a138c66f558efaf6e7118659bf14137eba0e72149992e88689db0177e099b3eba33c4ea14c74f0366ff699a45c80db076a16390d64b18168a03afdaa0e028aaf5e96d9dc9e300c2de01471dcc3aabefc758676895609fc53b7d49a3cf7db81d314f295955d3a19dcf279fc8ced5c4e101df8e0d4c40de7fff3a1eb6811bec0c88e0daf9306547ec320acbd1b2221ea016a4c21de0d6729174fcd2939ea354f16da58f69a911cccc60bc9189d4a98991b20a3279aa560971549f8406d7e31bd393730b7cc2837b228144876b8327f4bd13c59f46ebb23acc80f3763decc027542f9b939331baecc47fb979e8044ed740d5c3202df98c46b387da579373a9e454260d96e6c6f40f8c080506a08c891ab9be829b309292e8d064297ff9aa1c1360a3821317666bc8ae7316e12642836e17e344c063ad9c5686bd6dbe41bf87f2987cbd75c0ac83ce63ea7241f93e413b78eb69278a062b99dd6dbd5e76a77f47eec2a024adc31f50a2c76049f93bca73caf5f4956dca7f52e758299589a1b985008ba07d0691e6fc6dd430dcb099b0549d3ac09a941f89f5f5f6e9e45bac41c197229c757d1d56d3515e054074fdab808377b68cc1a2d5b115411df06a8e3a0c8191c2b078d3ec29d1e17c2ee657e7ee63fd9bb120aa97e5fdf1b6b01b5026007d7e65934280b43164a9cc408281d2e91c330f49aee15d5e5b2db0d579e897f80d1cccbad5014cde2e1987e3b5766a926f875457088ceb508a59464632a798a47c3a2a2dd15f7558f26b7c750405f90ce2211dbefab598da23da68f00820eed189eed8ce73ae9845ff79be89e3f42228d53defbe2fbb8de0df315e6d96632c81f6f455ef87e0d2079f6aebab3f5b318e178157d5ae0de7729ddfaf8a17c1536ea9f05bcfd01d7d8992cc7ae7be182c8c7c6529f381615ceb8fc4cd39e3630445a65575159727e56bade8c331b9579b42f9c92197a239969825ff6d7bbc1afc517efe8fb48b792e823b2c2a34507b137d8d92675ba19ca752fc102c652536755411f40b2b135daee04bcc34acbb428541ac894e52d02b29b5b33ebb46ff4a499b1a5a143181f8b143ae0f0f7d47666c0ba7c058477c1e86d030a384c1a4eb670aa4e1a979cae06b60f3f53bd69d7cabd28554adb61666e1722e17b32cac684ce514b8b8f497899a27423c97efe80d8d0c157b2d34ae04d632cd7a5cafdf3ca06be5db51b478dcaafa0dc9cd0c3da2cb98af35361f8cf659fd73af41f536c8e50f940908507ffd8e99733831e1858eb6046348cc85b1067efcacbb157da93ea757af2b9bba0c22178ce1001a57483e30774bfabe3116225613eb5291936c48b2d0b5273c5be7863b677c628dc3636da5ed2fc4acca2da553b2bd0f2cd4ebdbfae4b5782c2a9b0f62249d1c1fa04b5b641aec8faf451a1f342a430a0b2104064dff17c85cc7ad8020cde6bcf3fc4d414c2a2e98d468a02f4f4a060223222817cf2013e24404c441e448b6e88cb8fb7420281aa007cf980cb7bbe1d9bd49f3e832f5ef6e8af20b1ffc9d63d68862ad5582a23b2a568daee6a3aa368e441a477e275d917d53db06285c56864d9e29ca08e34ec9ddba84b4b02fe11148fa01471cfef24f37f697bb9ea0f81449bb6f81f3c860a08efaf658c5bbf049691e08f5be510d88f3ca1ca6fffa4cf0890731e865811f21d2daee7ea57ae7cde041963091d7a8ea7d47ac649a72a9d1e1db6d428acf9de800bce90bd097391d281ff0d18f6faf4fd7e1f47411da694f1ae6f38e68a561a7d7a9e8bd7dcbec874e5946c63b5dcc707db8a32a7e9d6e6a642430402304a7acc5b4cfc4a7981f2187f7988b78601d9e45f767f80c7af2bc102d8174319ed108745f3ab7bcaeb6d5e8ca7d1c466d214871ebccfb1386d4e5e7a30be8b85a447273f6f14f9d6c2f3931810bfffb1648514b245f25ae4b1c2ae3df9dfdfea596ba3784e937f4ca2d1cbbfe09111b753d55c22149dd41efd2807c349f80f18aced772b3178f1c6ae4c03d36319384c8bcd061e881df41114d5b26d4145514d52800fcae2e72eed53a86164a69b72bb48e124916e3648d99813a7ae05f446373a1a582d21426c3533f34503c70982a15fbd9602ac997f27588d34ad16821e6f11b4903635099c2ab02bfd6dabca6334560bc6e0ead7b2205f483b0b032ffdc8af9332978ad9657917897e8666b1835938553188280dcaa2c704a5eef827209a1089c99c8869f23db2c102589963a70e85fb0f8ce503a8b9f5e0aceb65acac58acafe6d82d3320a5b828b49f9f21061ef74dea4262fed180b5f88dd8d8c1794c19e01e3ea26bd6c31f7befccbaa422138809ebda613d145ea5ad67008a794db89460face27a1b0b715be9b21abb14128d7c7aab6cf2c646ce2557f692c0d063a265e3e8e91f0ae9e4a8615fffd8c2d84d8585e1927bc50218381a8df3e976e73bf8bb3932598c8d89d67b70e030e0c6ad710a3d79e449ea1470"""), TestUtils.hexDecode(""" 78A2B7A4C8441C36E0A9831F65D41773FE6B81B3FA6259A320AB03D460D7E38F4AAB2B93C6142FB0F9584E4D47074670B07F3CC4513675A4367EB8F7F4168F2EF7CA26AC45C8F23B2FD3E970068F21D9A3F7EAF005DB5A7157715CB94F5E83E3C955DD68E0EA689B6F419FACA7CD159237085678FA5883D5330796AD64627CCE7F913D1C2259E1F970E44988B08E78ED1EC01CCC2D0274067100C1C1E3D880B9CA4F3A1FBB345354D4837A6E5FF4D5F5C87985E51C471EB9B0F85075ADB57DEB53A87D85834167A4A538134CBC24FEC2756F7760C3D46248D5BD6022D8F88CE7D037935DB74A6440DA49B97E8FF376101B296E3A9D4D22E70634CFE88142EE5FB6A33F323519EBE3A915AEE5BB687DA4A5E264C657438B0F6AC977A22D0E56882F74E70D981CF37FF0C57D285D8CB07ED7FDF6D7CB1DD39EB0D84F2999DBA9273E0B716CE754A29CBA2FE32BE13BE8B9F2117DD7359494A0E0CE623AB9ADAFD3F15F644545A39055D42C6C5FBDB46D121308D649AF9B86A350B70F77A977C8268FA1E04F4EFBC2C95A2D72BC37E558F0460BB281D33F75D2AEB240086CEB8246E8A44416A5B31EC58AAA88246D355591BF7C622CBEB1CAD3B785026CC04C73E352DFF28D77186CA93870339E132D57B11F0154E0CED426DB31BB2E125C5635BD489B52C5E77593145D3100E48CFC8FE6975FC3F60ABC7FA4A4D9030A2CCADA3854BF9AA213EF11E2F85E9D4E79CBB434C65ADC378F8A7DE33E66B4F8588B73FA7F79AF4130554173975280879FBE0A59D25B969FC45AB20401CBF85463A83578E63D0C8324878F5CFAA191428E7EAE37BB17A18D0459378CFDD4C8C0B23B1429950F054DF5C67174E99AF9FCE6B0D8C98BAA9078D2CA87EB8A014995FB79F7F49D78F2674839E14C8F74588B45C28E4769C439A930B2A187764D87D71200E841263EBF74F7428EC554C12A7352FD3912D95C96E4BB1D325DECEAA9D6FE360DBAE7AB897ED467A300A8F4C6630F8E721F24860D1FBBCFEDAFBD94DC9B4237B91B243A01C41D5E98E67B52B4A8CDF0F1C985EC0EB85131F5E970A6DD6D4E1F525D9D94530157F70B333F5E50B1B95D569A012ABA959456AF773B59BC2891D745CC036D06238AF3F34081A20F00A831422CCF6E4593EB56CAA3B7DDF44B388CD54E5EF9E3FB8A260847BEA5EB5FF9665530A4F4B56726A4C5E669904A933AB1E56C020967FE61E72185D56B38B03D343302712FFC1DF9D857C6F744E3ABABDEB3F65628932D69C65FA112AE3F7D6ABD2B4C3CF572EDA73C959637D0C5C188343415E9A26E698170F8E31CA45A8E6E8E96BD066BDFDFF49C98C491149D61AA7C456D3DAE0C017A32B81CD5668A400127ABD4316F3DCEA171C3F6A3E99B398CCD4AA7E45BB51963C82C43398050B8923CAE2D4E2A2FF5232AC8F2C770C9A775F29C261E1C7DAF54F9FF606560F869638B666C90112B29F469C3620B0912622892A432EAB443F8A93E3E7953235EE78CD3FCDAD3F1391A2487DA621526EE92735284C347853D5F65395ECA2B50B0CFCBD988F99C86B5AC56ECB82813A93208096ACA04F22AC015CD9860889E9006DDAFEE0B472FF7FC3D5677EE089B0AF7C6C2FD5A322D60BED621B8F099C30C2344F453320B6FF405639CF764B101E1CDBD312495C2D4FB30E2FA7B3C345B9935BB28EFEA69C829EB57BF2E2E5E42B8515DED4C32F9C84C33DEBDFB345A4BC592CA56A769533FBA0A631D5D0E07DAEEDD2FD588FAEE648B6391422924D28D08B4CE36084C20E827E6E73A97852BDD7508E1CDC1630094C9D3A2C8517A25A244FBA388EC7DE2CFABF139888EB7372E2BE3BC4FC71788AC3CBBB3EA1CCBD9616E76F2CEB356C13257A8E5490F3C4F7DBEBF942BDB941937C956DFADAF3A78903B49C5DE34F5EDBF0E98E3E04E51021B686325955C14AA335427C4A116CFCB3B89349B1258B8E0E354F13F86C86E5E8EF8F57D7B7501C5D75B1D9615D942B04E1FAC4EACE0FA10E6DE9B9721EB0651EB3C9DE4C61EEAE7D7E17C0D699EBF7EEB122B8C1A599A2CDCBB9B665DD9A653698735D5572EC379ACC6A8470CD7CC8245F871C83E6FD92111F5128A9797AE802889E4362104775CDB69FCF37AAC22EE4532FD0B5ACFDC4DBD56D9CE8B9EE2A8B923F42FC512B54204CB971BBC9677EBC49D287A3F68A31DB8AA49D6477B287285B88AF298E68C6EAC3C73FDEC94F7062D204AB310686144168C155281627F78C883AFB49DA50C0F5139E2A0ACB9A9CEFCCA39C6F4F0F5356D2898A4F5DEA78FDD20B79662F4D066E73EA4069DCE6CAE300B3028F15C98801912A86E0CF34DF53F7F6E1868DAD92DF22A238C710F471596A49843D3E60E4C381F713C21C3910ACB1515E5E30252C94F040F00A9D1A08A4FCA329DFE190B5464521BBAA32932022BCC5E119A96DFC941965CDF3B739F53DA156553C6BCD72927B07CC3CC945FABE44B7348257A9FB41EF85AD5423304E016E74E03D5164D9F15838C3A4BFDC29C6B9F134054B53B29183A6A145CECACB3EAC7C18E31CB4BF78BC8FE60A3B8EF880CB6C1EFE7EFA8D77580CE200ED96713E32FF23B86CF532D8EFA2FFC8DB1A9E65A78EDC30090E3DC02475D84F8D9F2BBC48B114C9E4A01FA79C17FCACCAB1FD304C7F901942B9EF57C918588C9CCEF0DC5FCA7AC84ADAD547982EF9E855F6E88D02751E8E7B8B76C3796F94C9F7B7C6860042A3A33EFFA55AFE1B94C97D68B76DD240346355012F036DA9C7E025C3633CE867510D54CACD36D8638FAA8EE47D315FCA9D5AE4BEFD6150086DFC368DCE8DC623ADEAAA07287F9B291252628F1BDBA5FE6DE45129509651FB048D3A686FFAC5F2299AB0133FCDBEEE8445555F5C649598649678847FFFCE6E0DD9C4E75E2F6E77B1CEE3A1740A94E678C1191EF46FC4D9648887DE6277B11D4C242DC4A427AFAD5459BF213E0A20EC74EB0C210D0A922B9E690EFDCCC2C160E011AB94F709C174F22629969B6332738654A133E8A13EF7C914CE75ACA1C37DE05A84708DA741161EE4D23C025B405CDEBBAF9040A1CB7492294C381FD069C4622BE1EBB0113F25F4E1D5A415C121055CDE5616662599C2364481BCDD35F7E498E80D2350AD3B34C205C5EA73F1B923E6197E07C502BC6F4F4288EB46013BBACC49A5DEE5071ECAE62B192294E904BF3FD7BE08F0C43E3EC6E23A7F68115FEB285AD388A0F8FB94126EDC0331834179C1F10CA5EC54159FC256D7E0AB3129B22E5AA5D662C6A03C7D9A6D066400859EC2D5B091C37E35DE31365F5125793E7F653013C722045F7292C014123246D611A7FD59E9B09EF24221C7EAB249330C91BC9F4D3A223D9C2CBF7130C5C057961BE89894221AFB1EB27A4604BE310EE3C395E479D852CEBA4C2F74D4DF416C8836861BC13D0692863667AFF8EC89BB9194407222589E1C27B9D59AC49131765273228E79C2933445B83D07E48A789FD6E406064593EFBAC4FFEE64614C5AB34E5C2A717C50AFA79A96161203531C161E46D71F447FD28CE4AEEF197A3DCA6BCA306AF09086D6BDF35A861820C469A40958923BA824F3A95CCAF8531E930210BE46D66CF7156EA0728F3448292F47ECF20DAC7C5E78A2A0AD5215FF37594D37A2AF4778B15BB1B5C4E0A44AD5910B62CA3FAC5BCAA4CFF5BF97C8B8CB239126CA09E92492121C9E6977111E6E5248661AD122C87007318BD3D98ADDFA1B2CD60F12AD1E072643FCF82C630C2093CF4A75B2D3F809A0496727E04AD60F14CADC7331B23D9CBE28EEC92C68C97E597C2EBF99F2B"""), TestUtils.hexDecode(""" -9DD91BA5CCF4431DF756B1D23F47C0CCF24F869A2935340E59CD015E04D6F524A0F40C05247F5C8E4E0EC6DC0237B948D25679FB1BEF9435F248A20B4C2449409FC6E7AB855DE8F42423C83192DFE5EAEAE504ED4A490BC1FA3A84E66EB522327AB8741605348BE8C74040FAAF4F4B63D17B2157C3B216F20774412B70ECB568968BCDA52B6D3823DA6126FCDAC3837395CB0A22A6F4C704828ACF0E0B48A29400973B9C3567A0B4C0453F875A3DC82ACDDA5106895EB2B7AC33CD2982B1407E0259EB05E0DF60EC4AFC471D9FF5A4FADBDFD82FDEC3A3832A8F2A0776D650620B1DC4BBA31CD1EA10A93AC38DA5E22D9A0BA83FDB8C8E0F1C5751A11866E5C3E7BE5FB2147D7F67FAE52278BB4FF1486CD3BBA2FCD0544C71C1A5717AAAF6D1BD279CD97530BB1BE3D692CEE23A0069138D1F7AEB88C6A7A136763C132CE5C6F036E703D91FD76F3BC200656B61912576CD729540616FC49754E3371624137E39346BCD74990099A20A32FC20E7C2A8E23A3C0B3FE200F0402B2F79B825B3636C4746A283DBA0072B8D77CFE67B9EBC45350FD96B6F8C94247F98B90645A06166029C4B8F44DC998C0FA8DC5A0915CBC0EC139DCF1C75FCC68FA18DC365A198F46FD5B6C6FB69C9CF6D57586A0586511A16E4E1F94474337D31F97AF17C49E2283BC610F65E3AAEA08FC8DBAAE8A7D5D9573C46EF3445E46207536F57B7D69D5D0B61FEC95C883288EBFDD33947145FBA259B9C2947F7B837113303CA88DB7E0B8945F0ED413658CB0B1A200991D28D69D138A096803D964F2BE8E4BA04705F5F7E8F805871B7CBA8953B24DAFB9C1E25C272430B7F514DFAFE7A5194186AD8FD464015E09BE097F257DAEEDBE5CAC479E517A011E7059CE0FF415B42524F7CFEB49A5EBC68B0A44E54AFD136CB6EE143A2C6E8001FFFCA92AA4EF2579DCC06BA93A921DC261003C6CFBBFE4A8FFE70442C5652137FFB849B383022702FBF3A6197E13996C323D385234089234634777A9CED6A9E97DE805E78FEE580BCE6EB074B1174952608E05EFA173EAE7E929DDDBDB68985040775946BD70223D404E427ECD91188AA0632BF107EFD0A7296C4E100DBDB8EAB415181A4C12B43BAF42EF14A6B6ED171CFF05F96F919C0A5AADF18CE68381571250E59630C0D0967CE8B90FC4E075F03CAFD851EC009630001034D81B1CF2CD864D6CE6B4741B056E1E3769C34E82296B4B856B8523E5372DECD8FF62E289EDEB8368280D74239FF203BD4EE9A1D05438BF325408E199D28980DC8D3847B412D0CA652E419DCE0C42ADB52E5F33691304C0CA16551A4224E9ABABCEC514E0D183230937ACAA3125688F7F47EF9FC7BAD92DAFEB157EF880DDCB4BD1E1F8AB5E88641B1C087EE49824C2EFE263F149D353DF8FDB8B784438E74A17180A66792E02D84F1E7BAD76DAE2C5EA63E76C31CDEF083524912C73430C21E2A8E04509621A612FDD5DAD1213424FDC2518D116E93795F726210AA627AFCCFA7CFE3E563C5B97E5B0C276001325A13211EDDBB19017A0E8F0DAB523B5ACDD88D4FBA45CEA00ABD38FCFB98910A3330438BE4944EDDF55C9F2A3AB31406A26392340BD9907F1CBFFF78B320B1F9DF7150B215401B65DD46EF1A5912EEDD90ADD53F43E44FA8AC1BF010BC5130DFE9229FC93F36E4121D0E2767A88591001408D60C8507AC3315C74B72AD9CA05CA4CE9B81DF98771693A6CA084F8FDA0BD556FBB15F76D179494892EEEA3F961EC47BFA0826CC936451E66224045C82ABF55875F02658C82AED63E486941D37144E1CF3386844E2CA24C469B4344775C0A59FD2CE6091F575A260260395C52B3CBB0E65F5C3C540A8F9F8438370B57435A1F2FB465C66797B0B03F874FDEA6700C0831A18A7B50AA7B18D424BFA9887B3AC955E97C80FE176DB27EFB6E8FF0BD4172EB49D984B12A210C30F5D4A6AA3B28460EF2A32F8AE7D057D76E7A111F8CB2116F266F3070EDA1BC98AA52BE181903C2882F4739DAA06C21B4031A732375FBF23BC51A4E9695118113723BB1BB1C351E8D72D9A847A434467B90ABA082556980B92A146BCD3E13D9BEE551C14863AEE87CB56F7002BFF857AC9BC5E2156CCCE21724DB781179564290392CB47CB3148844F3159246F39665B69CE6F52316D0AFDBECBF8BF2B2A5F9CE79821B2E7471E97748D190268E8BCBEFDADE82F3D5C8F75768269EC41A4648C5BC86B267E680156D41163BF787278F3BBD9BD2AD483CEEBB9624FE531F76906C12AD16D151FB4AD5F08BD277C2B55650A86C060D38EF3C54DBAE10B65345BDC4CAC61376A5D052ED0D930E6BD8E9F4C08F257AE7D2ED672E82DD8FEBE17CAE8F3829D353638B2B104D49B7A7E62DA46C642CC3646CCA36DAB8D9D65AF695BBFDBDEB65DC07FF7F6599D5CAA6BB1F6694A8FC62BB3479D1889B2663CE704F4099C99186D504C3651331CE06E627FAB29B1B254B159435AD6A8CB6A678F6CEFFFA7988512328D8D868CC439812FDC8C4BC7D086A1C6532A62AC517D0EDA6005C16EEC0C93BDD9223AF2CF5D3E272416DB60561DD0B106AD25B23E00232BE30B9EFB7C82F97DA6C564AF92E5E16227CBB94EBD50E06CC34A2D22C948EF264E5A1B4420A36AE83901C346792FF99829A40714454757FA1CB0D7681798102AA90BA5D37FE7C29C64B86005713711D5890279CB0844536C0F974A46802320C33431588E42CC0F35D5BAF2C828441538843B185C4D93F57BB90ED1261B980C6B33B121D5C8F1B87C2D05442C34AB56512F40B06D326F8F7EBC5FB29D06AD907E687856D558AB423C72CC3B85D683814824DFD9CF34B810861B4E33E41F15569159FD4C6622A6FC797CA97E8D0B0D2824B199A2EB5B6FF06976A92775FF8B66763C1A430DC452F0CA701357A00F3A7C1A29412F1C308EAC4896F55EAECEF88D89F6BCAF7A02714F68E8D412C591A2C5F11033F7FBD2F29A0DB8B4171AA8D4C7E4A708B9742B51F80DD6F9DBB7242EC438CABE48E39F1C12AD886B7750FEBC9C3C4CAE1F6D016C412EB6812815267590F94794C90FE793DB920A4C6C0ADA4E80D2B64B81F04084B65A8251076073A84C2B4B1209655847420223A0A87C7612CE67C1B9540C8ABE46A0EFA9312C0C1FE5AD3165B90E6973F0FF8DB7FEAFA2E01EFA3ACD58AABAA0DDFB30AE7AA819F5D5E9FF72402117FB8CD9BA3CCA0BD2B8F52AED5A435E1F705ACE8E18D60845B8F0B13C967C39AE8D1A6D1EF3BF875BC32B21839077DC0FDF2A4D02A0D1554C2128E55A370168D0698438B21D02DB8C3A5691712B439D4E51E5E31DB45148977A8B184AA5FB63F41C2EC48A7C9C64EDF88E6B480956D9B0A63FC1149D85966D045312A3BD3AF480FD4A3C3F09DCAAD041427B3355B4C1F072A6A12301A1F91880F16A3B3B425BF150E01C6F369C84655D6F167E94613C052D73ACDB2A04CBD4EDC141E9633568485603E5D0339743E030066AE49FE5AF1BC28CFD6F4053348FDF7356EDA04AD72F17376339FF0F7AF432EFE60F3B4325E7C692A79C5099C29405ACB84DC6C991F70E73E1F93B4DCF749B5776A8D5E4A34744192D48E6450B39FD74F162BDE7EAEE2DB13061547169B627F3209B4D06E2C0F71C8D05F64A6245C9097FB0931BB838DDE1F26A211C27710900DCED962114CD51646E5DE093C7B4A3D18FC99EDD501DE8EA5695DBB9581322F903BA408E74D859EF91CB1082EE68BBB997ABC44BAAD87C51A82FFBADB819743FD0D06341666624FD88EEE897168E2EE35CA6DC71FACD98E754B7AF4FEE2B77E4B49E718877C5EBA1706EED84049DBE7019FC42698BD5E0696732C61828FFF5D15DB72654595C2F2B90D12E79691B69F2EDA1C137D2E69E396AD1862F1625AFB9ABD111D495D8FF41CA4896D2A83AD8D00D49B15F1BF0D160AF3CDC637BA2E32015ACB2299A13FBF43D054B420CE97361CB38022C684B695C4164D0CEE286DD1E6E34C483BFB5F91049351762D9D2609580B64425C06084275AB7ED3C3CEB8863F713FCFC091F460DA2351D54CD4A59261BA01B3A0D5F97C04A4A598DD6BB45CDD6049F2BB52D68A9B219F6474751C655F404DB8F75DA6AAA2609BBAF77E7F67BF27D721517A7E128DC4180F0612EA7FFC343501E048BC030A85089BD2F2542FFDDEF0F4B98B7A45376D9B33EC082C17C8815042C5DDC3DCE0CD64CCBD3E8AAF9AA70475E845E8FB4C0EDCDAE5CF67C2384737D602EE1CDCA0238E5F2F0D676E3C9564F9C1D4D9CCAA85BA8B1621C8E3161714256D6200A61642C1E3034A2E072E6D32FD941B87BAF22DD2715FDD8B50D0D366E20F1E9ABF312F989930145FB158D4A1CF607B507C1D3C43C6FA130F36B2355F24DDA2856149357AD1FB9D608E6F25C57B61CFE450EE9393042952AD2BB04EB4C1E7EC92A19BAF7FFAD5FB4CFAC804A0E18AC98AD1462E384DDE80F22E457FD9DDD58615FF9FB4A731F85B1510FD18FD30FFC74F56CCB569002B85AF3B593B4B117E6927E8475AE2C9406C383F686B8E79F22CC4DABA9759DDC9B1CC6BD91C13E451D5D30FFD1AD0D1BBF5F888AFC54783CF930DFF4EBFDEC0B1D0DEC4F781966BBAE1B9D0358F23BD5A83F0DC43699F30ABE458C7FD2E1B3B5B04DB570C598EA1C9FCC0BE0E607418FD5F2B375DDE950CC9E416868F0D582268632EA4F6777AFD49EFEBF7DF61B1F6AF5B8915A3DA8A4BD5D7501426AF0C99795BDE3D65317175FDD10BA8BA957824D45EC0B2653FFAB6BF4207798833D6CF875A87A181CE8B7188F09A69A8987C836EA923188D59B02C0CD2483B03654120794459B92228A8E029D149D6854DA86AA59C7C906F06E314C193C5BB1E94FFB4101B2AC1AD22F520F6E2D1B877E2CEF0CEE8FEEBBCEAC4DC6E66E270250FD77ACDE3E05EFAF41029645891521C0A471F268173EE36F5A6DCDA14D1F5D30CA8C2F772AD1CA92A5AD9C6B111793F38D62FD5734DD9148308344C5EF4D2D7F524576D3DE03543054FE8AB8E317660BC23513D4100FC1F3479984E1F8BD8D18F2097640A1CA2DE7956BA400AA5F06BD13AED8D54703029E7B927AF48A1FEB1317ACBC7DA9F3B0421611252ED708515FED233615C98943B9B1D4337EA182CEAB73B704C162812677B9F96B41922479DA97BBD7C83E6A588B0EA87B53FD80024877037FA98C058E3CCE7027A425957F87B0CEB5129DC8DE0D14461646864B7E69C862B9C4EB1C2240F35FCC0FEBB3E24F98A182737515BCC65A95E53ED42CD15FAE2F3329D61BB0CEB24FAA956A33F358C8E29BC610D02F1F9F3B92C5A6B2B4F1E00B3494DD37814CE79956CF2706BD3B1F92D6E262CFCA492FE20C2DE75D1B8C20CCA8146237536BAC89DBEC536F00B780A906BCAB0F3669CF0CEDEDF8314E3ED4811B2C8336A7CC94FE79D97E4B65CB6240820C88B785CA79D630C06E9575C9A2EF67B49A150B481BBC873BEC1F07769808953695AC1B4A2F971233C9506827E439C37040FD31FC49E76EFF585E9157F83798FF4C7CA1D95258BAB04AF860805C554D44584A478D3274E0C564594EED9343E3349370D30164EF7B2E2D104B7978E8CE758CE8C086D8F108BD3F925040552CAB65853B05A51B3510743B70F4120150E062773071EBA75E5DFC774CE13261DDF18FAA0A7741FCDBC1618D1874C8F7876B200F8A8E5158B65F8E015970B0C3C3283778DCED0E2FA6255BC5E0BF24CDA13F6A47CDF2452783C46209623A7C425DF9845EAD1E854BB810183512043A66046996C19AD1D89C1E32C1C3D9C697E7405E6CBC0E5642816F8D9C72E9DFD7222A6FEE81C9971657B6F06F9A0C8E9550CEBBC44C2593C60B1EC54E5DD2D93501FB9EE42B8CFD29DE790CB8A15A6BCA3F61163D39F186E771769D2B7BA9ED1DC0FEB03DEE86834038116C5B00D117B2EFC56C283436EDBE48A61C2C7DABF5DB3CC638F14D28AEDFF375AE638A3E05FD871D56D86413477BFB8D902DB263ED841367D29C4A95B03D758CE9F2E4781915755990A4C4D5CE8AF77376F7F2CD050CBE42BAA3DB923CD90665FACE9034087F56115858441C9E060B05542053324A0722FF12E6DFAC3330C12F20679466CCE4C4A24D7AC09A04302B95509A42F5538EFFD1BF3DBF1E9537614ED865CA9390854F286C243F2E7AA7311B40E5B3DD2208156B37FCE086CF064C41593BAC8C6B00DCF6386BED761551315BEA7F4E1600FA1FDD2D0B20B26613A312E1C03D82D3FEAA24D3B948730698C1342B4FE97B7085B192573FAA393BF62437C57362706B17B22ADF289BB31B32079C9D9DC9AA1E8FF63B25C8EEF97F13A628FA5CD151596E67AF80A4B1A71443501F6B6C8B6825F8AC7B5A6520F056D589E849949E93F0C2E52AE89CB81F3EB7C31388A56D15B25EAF35F9570379EDF4E8923B4F1C6666BF646DE202359CFA3C8E10434A5A8DC3DEFF104298B3C0FB507EA1B3C9D8F300617487C3E93CB6CAD5FF4D535E92CCD1D8E3000000000000000000000000000000000000000000000000000000000004060E141B21262E""") +b9e56f9dfe73c5da4ec32b02af5fddebd5c84e216deae6a4f8611a876fa4993b9b333360ee00007dbb16bdacae8af597cc2d3a82359d8dca6582fbf9546b31867497b6cdf6f42ed3b09cfd094672218c40a24c8905ea468ba91c02c677a45abf5aa0421bf5bd398fad978fddc4634f6e9d36a03cb3d6eb64ee2c35f85481b1c4bed1b268de1483ddb4896a89bd9853c8f5beaee8b760c8202d17af8012a859f30c3023507d6bd8e41476174c2fb24fb1c944fc525b35c6e81d090c69713836e236b12106e02792ad51000aac32cea27d42c197e88f500ad336bc6feb4b79dbbd29a90c6e0f30011821357d111ec1cbb395212cad14b339a40fd9fce06bea1397369188c0d79e112f8c453605aaa3e28afb24730578eb8bc738d1c8e699fdf40438a16100e30d023b5d5be050a934d84d735a5650e2f599a52d36d1f9bdd91e46316bd62e774bcbeecdc7f43a89fa59241c12d2788ffa8e7277707c7df292da5141167d130aff17369c49d978add54af557dab19e746391c9f67157a58b4efc7463ac0615368006fb12c3554ecf35902e5752dfd7c34c97846547c3da9020ecd665487607c084ce909c2b7719acd1c3768ab6464c07c17e1329608afffe63a4ca07f6c9ceb74605c02772615de81364524121f8ffae29360d69f8900e5e9fb628e9ab0af8200fecff1ba1bd01fb6f1470a3771ef57d9b8e8103b3c2201d233de6e6602d490ba822b8eb4ec515c46b7b7dd0bf95cb7eed44573cfe11c168217e32961180d74e4f10463a5f38404540afbb48b21c878f1e7cecc13d664b03fddd6a33bb4d8c89023bc54602acc1cc434f5886906b5de13e89b5a414ba0f75d8253bbe031f2d82863e4e2f85f882a8a64ccc90a663ec9b6abd7edf2e8992f9aecb12a24acb52e0b05dee0803f521f833d0c0f238b06dd530c14bbe9a64a38198ce98a91f80358e6af37fa804710f043e7fb8cb5562f0c093d40c57f1b2c476520ab60782702d79423c64c874ea0ea0f4d9bbcf029b54b11bd114d50ffd80f38b21b4caeb54e9b83e0fd4551b7d56aa89ff0ea546433abc7e2b71a1a73897c803709a85b9f2c45996243445b089d8b3a75fce6decd0c42d622b52dedae2dbcc83181fa23a9d7b813127d58457f03b5e0cf4326188ed9bb894b9d468044897ed7397bfb6634808687937c8dc0d9883d9926d1cd63e0755ab868ab1de5a6d8cef72f72ce4e183d626605d6ceb6da8bb821161f3ad12eb124a1f09789b67f71a7b5819c3a285b7a8027d1cbef580779444dec21bf6509f27e7286c9d8274106cd3ad0baec6fc6f40fa3bd30a96c27d48280b8f051ce1679ea89a4981d270cf34eec5ca1ac399c422ff114232e68601d328f4a4c23ad3d52843c963b21f106f82eb38a379442b0ac389c59992c4326c9a54573b54ccdf1358389346df8c5d8c4064dd216f1d5e8f5ffe31205da0724de69187349a54b916fba25bbc4fc9b4518c57d5b715bbbfad14e50f8f48c81baa2246712b02cbc6f83cfb0e033ea90734495c9f82d185038a843a1f2d0a40666168a4df0b8e7c08973f64c4af66006109fe69a016242709877801e73319e1b2409825f9d827fccf2001b4dd0a4f455a92a58d13886f5ce9efe226dce7f3b4e817fb4f2185eb328c3b20192cb01901d5563b83fd7e13d0fbc3cde890cfccf91abfcf6c93a8c9ff31bfbe12a592e6337a0451983fedeecb6ed9ce67b6a3628fe15d9d6e8281097f8200fbd8742eb1138d3e6c70c1ed95c18d156bd9bb879610c28e5087097dd4a40a102a400b7ccea6babd3c419436024052a8a3c6c4233627d967a91bf700e10687a30316b67379fed8f4d208e27cd811cd27021abe8a295245f865655d2956d60d8564902fac029b65a337aabe99073b70162027995799552e779aca9ae9de29a458d6eec2f8d2fee0102786381b4ebe8707bcf9400c0241b83a4724f81e776b996c112226b8c7e1f5c1d090e9fa9b88c26445367935ff26c8d3c08a2347851a8f40b677b6fc5503a48f99782bf182a177fff9f28b5f2224b77454b545f018a131f8a9df7c61f35ac74edd7481a4bc18492cde936d5cefe03c96fe2f60be3edbe53d7b5d3f8b883523ac6235fb777f1d7a41906dbaa1727d1defeb67504a482beb8ac2ccd9261aeb746f422b5e9a11cc21ebd22dbea164c46e59b09bfb5213576955089ade4ba711d4f03646ae86df0c5495e0b5b5356d55628f40089d4d78ee33ba6f0f4080aae73fb20b47e979ad7dafda20c69925ce818ae62d2a534727d146d8bff6276eb02a52b2d56712da8cba1c0b48ed1f3e180d1bb4c365d6f14946b5f76147aeae4c55fd8be9d11b4633659df5a6a2e6dbcb56d32c7bbb88fd102e8515e959f322db8b6ddb21bad4a5c345d43f1b9a244a24578c75c626dbafc3f10e65e023783394a8357a6d5e005962af2e2f8fe8757a7cdc45823b50a0bcbbfcc6a46809d46ad639e918c97d1f038d7a3d9d87fb67ca95023d40793f96aa31c4bd3431d997746d305579495e41fd4d5b08cba5176924025bcdde3e36ff0c7b04b1b157021522d76e61ac37cd4fd8afb8c86609afd86a521f42b6e1892cf64cf278b02a7df422953e45c49cd07b9be6a0694e977d8e38b582c353442e850d488e26403f42fc2b533247eece1bf8dcc3808592ca51e100e71b50ea0714652f15c308b59d2b5936168acd227cf1a069e607fb6fe0fef48d582811106aaa4eb93ac836466319ba1597dd6a21ee2221bb0a6c068aca48b10a71ed42814a5273347e176c860845445c6f3e8dfd85ec2da37cb08fb2fba67bca6ecc5616e937e5f24464e22e4a699f27ca0aa321162bc5dcb799d4eba8f9725f9240dd2a10e1057e625f286bb999db6bad91f53c7abf54ef8e8a7741d5528f1adcff8783e69c535d79f279cd046373a012da01a3530d65c5aa3d0772e773dc7e692d0b8e17892e4808a24188c0bd48dea755b98a92ed4d8bc9046c81c9bd9800d8ebb100baa447a3432c4de07a68f666177230109c733be367d73c724a118fb665c858417512d91e993d83047622a9f5594a9e91467608b62c27bc07988be98187ee0ecaa7120d0ed54531fd9ccb17329b033b1b9c771c32a2bf99be223271c91feafc475656cdf78b4acd5226236cf50e9a4e79d7b4b4d9cfd14622a2638fd2c634acd4ee0b91977802ba013a98fffe5d6744d75d1a20a3cf3c851387d08c79d9b6b4dd418965eaff722b926c02f1a06563f0d963a2e6e99f10228152fd2a6bdd6468fe97955d4e81d0ad1f0ee301b1fe33c6935c3f5f8d4f7cef773550d32825b7ff05867c76e9797c71aafe5fd6da4767bf4f8c1a62ccf588521157c252c6d5431c5d4b1f15fe45ca0780989a9e99b7e1ef1d73cab9906a27f7d92609388d11b6381a9c21da36cd5245b2c9193dbc1c74e7967ef694a0e928720646b90a296dcedb5de5d90541641220e03e2abde8c2cec28ee3e7b04ef380dc913ba595c7c3352a5edde20b85c2d2a7525035e5f6db59d82a01768c7c1be0c57ca4eb389d958e0c96443e60fc6ff57a1e37c3bd0571215097fe26a87b835da2ea03c83fdf607ce72e5c76ec4a89e1378cc042bd70effa1e823f2129feb64e5ed7ed216c0d37fdf8d42a5320dcefecdeb28e99ec636f01973df6610767341da3233f1d2d50a7d922e93b14dd5d713049da206d3f31422f9f8d88014aa6091820525b50d1ba5e1f9d33f084bd2b5b65210c37f352cac249bfdd0c9d38d4d62e6c2bbe3541bd692721458b3743f902ca8ef6a150e8538d9dc348b704475d45ca3480bafe55265c578f3cdac8c0b0e281a6827687f391775f05979791d3e673b2cfb1bea5dcbb1cebec43a32b34b2e3ad97493c179abec83d02a249d52dd10edec00299704f0daf869d28c2bd29597215aced1e184d5e587caba773461499b46ed8c7a036ccb433982cb89af1a7e243a3466b1b2a9243770e427feee9dd64a96a3a8b526bd2df6ce6ce3425a59b7147c86997804cb109f862df5151e94a734020be056df7769e3f164de280bb45d7a5c43da8b8dccc48d4b4bd3400f31aa5c04a76e863fcf9c7d7e7eb04f5d769aa3cce83251a40e3e32f0d437ea9a279fdc21b4331286441faf0e0e18abcf11318b127daab6c8e2a8c2d67aebd6fac6139e5cf996ba502080dee6cb6fa55aed98f8e28211ee175702e9a16a2cdee3d08a7150881ba3b44f785ab768cc857bedecc1ab8f006a1377043f731ad801b23e6f18d6404c58c0d738cf5fad7cfa87cfe6446eceacf44ca811e1a48fdeefd940324c904fccfaf2a36b2bbb2c2383fb8c995051881a7e9d96327ee92ac43832f98932997069b21bb0868403c6c586f986949a43a42fc982d33b5039acff3d3dedd48ef05e61afbecc2d113de784925a101552d5084f05720230b6fcc357b63a72588317af5fbadeb229fd1221c5bc5f7a53efce19ac146d677027a87e0d49876e12830b43392f1f68069d5702699ea0321ac7ea78c18e64af520c333a8f3f591a1835d4b34b428abe29d1f0377c9305e0aca4f903e5127a397149d4be75369cd42135c7415d0298610572c6b95cffec5b0ae2fff70de6e12386db711ec9b676ec483be1cea8ddfa0df57bc60d2c8a76fc87d273c6ae4b724c4d8d3dfaaa11ae2da40f7990f8591adf689cf800ceda9ef2c8faa96de3290a3bedb2b73350846de4b754d3f7ef20c4defed3d9cb5afeaa6e1d686a3d16c4f1b2e65ed51b505dc3fcad64aea1c491338c4a33292088b60bfe491e1e6ff0314252cdd6767e983b53cd660dcaa4fe83bf0433edbc28b53a5efb2f5e6793ab1177f29be6cbe572619c7d191117a7bc4dad806dc102aff25067eb47a5bbb1d492f80d37c5968c2e40e9d600e7910ec77a0bafd7d8fd938ec3e0086d84926a75f9908392764c8dd8a76439f0adc99ffeb7af9d0966bad2b0a924184a5e9415c1abf791e15c700a69c0e7a62a854886797fa0d5c7a42519a6c887a23165808a608d9bc625f7775fe7635b537b5a35eb94eb5e81fd9a7c0b1c74b27d0af81938714761081411cb484ba7387c6c233bf7ce09091ab8673a3f10aac3f126cbb090f55336caabbe31d05695185635fc85d2ac59ed0066e51b023350083b2b2408ba874b19b98bd360c12885d64634d3c8c2f19f0feda4bcab389038ace498af6e2824c101fe5b069f6679044aed84ca5dd4dc2817b3c3e6fcd4e2f1874f6011ad05fe9e6a5b474b6c082e7ce64f3ec5d276074af695b6d3ec3b158a99d6de3f4237592abaf05a460ed2437e66a78fbabb0bacf03aecf9b96b3ea916d96db12d7cc6f8bbee54183459748a9c8837824d5f7c6015b564b146c255cbdf16ca894186566185574273344098aa03acdfcb8679387ed2c98dbacb6f2e6150306ea35f1bc05694110d83394fc1a7b4b93557a969131b70890933c530204ffc2371cdfddb7c6342a06d87c2229473654efb2b53f0826a349ee93d90fc4d4ad3e7e3ff8c16d74ebff6faea4b07dd5e88999bacdb1b51d8a9d9c0b5e5276153ac0483b96ca76dda17b931c526c7b5858bfa793c166bb680a44a0c0c66148f81177d8e9bcfdbfb64346c9179bf45390ac550db7af5d9a9b43bcc168ad29546e0b168cf9a5b44747a36b9c4e1f630c832883f9e6d10e2f89fc436de0c59f3b8e23ee0c156cc395de1c135a9de0e24568cac9c2911b21a0a9cff405a8ac222a3ffdc0d9ffc47aff2a3e89ddfdc6a8cf60cf28b3c7cae78b6bebea7bff5a8a47a3b707f24b8b6c4441718ef88108ccc26034ece28f80517991530273a5888eb1e36352d45e917b0283534830e914c5f083704e87e3c4c4f2205d99e1480d3ccc44f66a5dfb0607ec052a5a114c73d7bace17576b9345149325614c0076d7f044ab3f34482091be999a269a266f86a95d11baeb907e636f85fda7439cbe8d31839816ad20fa2fbac9b9ed2414a28d7e70cbcfa80f8e4e059ed003add7553056f7b94cdb4459f3ac54cc2c003fe60d6a44a7fb6fd0520c50f5c226a2bdae8b6e8eb7f18f94ee1b2692675f1b52c8da3141e5f859f7468b88e25a7d556fe1598137e893ba1c07ddd1af840e7f568db4b139f1d9f791451f76261f3948ba69354b16187cb77996848b629fade50a4d33e5760673e7b7466633f5426b17157e7165933de8547163903aa002df55a20a1a90a5c7c93c25bfb53f3f57e0045dbca341b9f14fbe2710532947e3e1bbf9d98a2f46bc526db5455189fd359f4a9c52dd5e5350650b010cc58b6ba0d5d11bebcd9b6e512d3c2faa728456b7053485f24fb351de898dae7893f08aa5509f808e6d0cf2b3bc46d3a9d3fb73633de694a0ec1d73dcd22e818b61558be653590663c3c66cf008ce3f74f0cdb241a9b54d59e426ec1a0436ed7e7fef471fc927432c09c8a65591531726723e0a46527cbd28527ca0bde9165860839dfa2e405b71728a8d96a1c3eaf516327895fd14476265777e828792a4b2f230638790afdc0312214448b1bac8000000000000000000000000000000050b111d222e343c""") ), new SigGenTestCase( TestUtils.hexDecode(""" -CBCA46632F51931999369241A839BB7E57DA0237BC70ACEDE33B32FD3A66B20FB4EC73B8DF3E9EEB22782E3359A9CB10EB8CF52422CE70C71824C705B7862DDD926DD53A787E5B80EACCFC8BFA1BDCAECBBCC0F697558C85BF745C0741CE0C818A1A2159B5E2D645CFD5FD8A7914D64095C4B2EC86549121848871229F27D91D58847013928851224411090690A28493166A994460490891E4065221B98942B44C03850564C071C92472834244E086650B377010102924382922458601B224149085D44622D43231C3284010182DA2288C1AA10990082A542286D4042680400103196A019780D2A86DCC062AA422680B492854327123C36440180C61B070DBC02DD2300A644009A2922548262658200C14912994464813046D0842008B989144400511474DD4180598C67142B42880C62163C020143265C40241C21624DB420D03068A8A382448484DD0A40DD3924489306D09A52012856C1A4450113125412820421692D34012583481092912028684C094040136451C200C84B48C00932512190294A07108A388838064CBA88484022A13418299C48D5386848A4692188890233820DC88519B16469398000B046D10A45012B14D81A20454468E9C240ACCA028DC420611295102A4608A968DA2264E0C2931C13272614280A2A28C9A285288B40150A28118024919970814A7110891680A8644E048921BC68DE3C04923C261DCC00822C08840A030134972802844D3920C1C304620012500C64DA33485134140A12406E1226022130648006022C309543491A20881498425804240C240640A456D04226112106983C22D53344C42902120048192B80020238D23022ED094901C33685B16500CC7440826720081481294200A9148C9C0050C13109130650924300B0889110461C3908481B06C22044AD1B63181021091362C54C60DE13691C106084146508182240B20020C416A53340A132822440026C92089C48660D4300962B0600A274100C664E4A084098788D11646E28010C0444924444ED32471C4A851D9300DCB884C81488A1B3025D8802464982411C42DCC022A5C38869284311A1610A2164A0483601C33510B336020180D4394441B07480A21104940321C28804A402A81C840C3106E12C8456288819C10654294715482082045892048461439864C068A0AC585E4148AE2B02424400288342052464C53064A84226C932850C2187061244182487011061180A668883649C22220D4982054420E1C070194C04814A72D9226268108810B03651A210ECAB44D0020026140122202308AA48D24B74C0986416388804C1871C8226624C249003971A0164401246002810DD4C4845C32701999919A90702297712348019318025AB429029785E4B4080A300954B80923434E232888909268DC92440CC525508680621069143989C4282E919248E298059C308564201208B520E43225524668488809C12868D928442193045140401903095AA84C8148288B224A04B369C4028452360043442A004800C40445CA304418181292320888C690C8284E20B101A310268A1490E2464DDB260609498E1930260BB58D5A3866A0C60D4998619BB06864300483226D194071D048520AC829D4903004246010258AD428860A320A10C3091C4661E3C0806428686480815A12024A4610C8360A9C2442909489140401190409142721D8020998128C5BC84DA29409A28271CA322DE226825B16080CA00912384E8C84891B3748C08848DB980D04A84808982C24A59094246C2113669B102611162A13C96890485220B96513394CD2A26CC9320D14952C0202651C3980A0B62C18988483242A623269C20202C8446A82062A0300255294880C18259A128618C6401A310684066D18430D88C06024416281C06000380622378D02096E83440621372E50C629E148819C882D03400C5C48301B0384221061921490D446858944110C2431144051CAB421198444CCB284538050A1006C23418C8896298C300C50A60C8820848CA2509CB43124356D0C21120A3749C2C06014B44844108A41146E1281045B32080181088400054230900B344E03A048C834450C3290CB88044BB6844800901C946D1192100C1600E2366AC04866504890C34892A31830118600528871CB26400C44684312665B380C19852010228C8B928D8B40308A900C03C90D1C036D1C2652922032030120928248EA7FD68A0C62DB31279B2CEADE3F558AE9E6AFD3849A6FDF95B9F0C219B6155FB29921A667B0130D8B21493847393DE153BD4ADEEA031270DB812F827F974A2CD6520E7BDB2ECD99916FDD5C439EEB41514044ED8F02361EDEEE74F03C183B6E3F3194FD522321188ABA2B3D8C7B6BB4B6F2473ABB3E5337BCA906E716A6DF660DD51B543F02D35CD9A78B9D58312F62AA96635B8B65844500413B3D52BAF6E671487E6D882ABB2473AA4F321CED5A1F57072AEA093A6D51EA0C701FA0B915B14D5EC6F16E4C559C85FA9DC465044097ECC21498E3D6F919D75F8C364BE6371753D2CAA90166BEB726118266D8D7C5C3AC81307E74C0F796E1B038F7660E770D1707F10EECC95694A2C17A6306F661855DAA243033E624D208268461860E39936BC6915A86CCEF098B4D687AE1C1B22BF476C2AB753C8F5F528C7F749749372AEABF9724FC7E3F554B483D10EB78F3099A7ADF6CC4CC03E4EF1B6D0219DECDF5AF99FFE4B2D4CD18BA98C2D62B93555A2989C753BAB1D4BF34A982A71E0B10328E165BFF69A18F494F5F40DD2AA52B23CE544F7FE4B5632A0FA4C879D221A84CED7E097DF3A17F4E4731F87EBAFA97428C0CF9B51200A0126ED983C6FCBBD52C64E109A809C1353C3ED3A214C07A29BD3047D0E69D00B8BDA5242BCEDE709961CE83D1112F19BFA1C6C68FBCBB1B3045FD681E3EE1AB7EA91BD5F501F2D9CA88F9E6E040516D1DD238ED79A84C3E4E8318427A41ECDEA73CA4E12E575403FE4BB9AC0CC9FD8A7A1877F09612B8C8746274117D7930A0DB55EB493907822208DD541CF3BDB71635BFA364B01F293A3439AA6DA458ABA62F063500D2222A6CFCA9E545BC61624E1097031219D61DBCBF8C8D32E345058DDAFCE284B23BE63B5F3AB979C35F4B5AAB9BE0CC37DCFECD168298B744C37D08CCC0DF515AFB01461ED24850BA5D84977D4352E0838EEB9ADA60BF0862971A83A0DE929C06F4A4513E3E01F93EDA9CA7408233ADEE110DD0E1270AD957A296F8842134178893D39C0AA07496EDDBEA015A1E8F42F4CCA571D1AAB376556156863FB00BF1F4B329964B98505B0FF71D39D35EAF9D23A8589188F872D555A55BC37E364C0BC41468130B2ABC8F43EC7F3C39BF0579692CB04DF4A29C4E71AC4921A79B7D722A005C226A4CEC49967AE22E2FED24CABA43D915522E59778BA66F5D2E3604AFBD076DCB7ADF9CE9CC26711EFB4EA190A6660F5F7BA77E2A165912E2AC8C6A4756B5A305EBB92F00294F771B75F1B005E7E042D4FE23EF90C564E385A6968B0A61CA8940E8C67ABFDB4B57F16FF6EAB60ABF48866479C6B891C5A7787AF18906B528F8CCA98EF2D1CBBB5516B95033CCB060B8C66FB1B0049AB88CA15776971FAD4903639A1B354923E13E1322DC220ECC967C581334F8FC2FD10B7B8EA6517427637FD2A967DE71C49F24ED2FF2A72A43CA839D8893472CFD453AD66864AA73C002875C4A09F631321485D3E8C3403406E2462030EDBCE21E7BADBEC4774CDFB7914DA8099E846D69C6A7D58451864F5205D1854EE420B2915B84A933DD381D9152E4FD6C0795CBB90F506A4234AC4128A4AE863D68B06DA74EE36BA3AF8A35B30AD5AC6CD7DC29C467A088CC733AA88055F2246B3370947687E2F6A825555C5E8C6B6577EC2C3A9777882BDEA26F8F8E1871E1664F702DA4B580DACF7DDCD6E29763F5737B000BA424528D197937EAB91CD31504D626A3C33ACA17757DC65C7311AFFC35731272B18AA49CD9452C7497958089FFD021A8D234F80CC693B286C12AF252C9B32C8884CAA75569DAB60F2E3A0CC8CC9ED8615FC67866B54E2762B69F3F81DB13B510208974897A62EF4192BDDC9A7B8AA27DA597C5BD59131195D2FF648F4D13DA5E25B2FE99F1604FAD38759DBFDEF52D8B5E93706C0BEBD16048A496C8A95609A4D370F131B3094C928F650311FFF864AC94F6A2AA18C7E203DEA188B9DBD20FA08EBDC4A2A59095CF7E64BD16F1BDCB44CEDF7409DFA209B1698E70F0EBE387DC40B45C47B621961A34BE1F53A7CD634A538740799A3CC17B69579B34168D1D7C601CCA733B4774F3BA611D38DC44D3A7FF829577304B76B3A2A3BB5A3AB0FCA3CEAE0C4E50B985C7A18CD37D517C4C53F91C8BAB32B90A4F157B09CF14A0536E01BC382C55DC83DC27289EA546326D7F7D91DF5F9145C4590D1A83494D2C3B29AF79844F0658B453A8C3E44EDA25198B108703584DFECC3686C0BABD1078E26FEA2292591054A5D9B555D4B056CA7536CB81F8F7D7B5A2B6028540E9CD21B2458F1B2A5572C373E31922408B26AB3D5184038A7CFD9B506AD4D3CDB5B6AC8DCBCF56332C042441C79B9CFB71D057303BFD6DC98AFA0B312B04EFB0ECC4479CC1A35D53C13ACE0D77C600D43BB79319ABEF7531FEEC9E42270DB58F8692A51E023614D8ABE7744E5B822DC883FFB7C11E2CF2B9CEF5A1E0EDD47688B653A0B2DCA55A7F46BC2355B0EF5981C1672D09A7A74B93E1A92C8D8797322E67492C2025D6EF89A2DAD153F261BD967D5D63A1285F134077FA25E1714108444F76F1212C11B4EE73E448256F93470A44D1E0F7D9941BA5689D3121A47546C6B40014397927720937C6FCB50D283BE16EF175BBA7E1759A1801CFAE26E2D00D0CCB9C155FA15D9D269A880A5B1A769FF4C74005407BD7CA73DD3DCD09F0E940B7D84A1876ECB65F0D712993B5F2EBB9BE0699F6C2F79DDFCCA8ABAC2C88B0A02BE72065AD98C017ACDB90FF3F90BBBCC7C8C34146272CFB36C2D04D073049AAB6BE66266046E975FCC31C6050BAB10243F774B75B12986F97BEB30E659B2EFCBD53001654BFFB603B6B9CFE03ECC41F1B46571688D33DF1932AD1B82DF9535D12FF964618A2F76C6FE4153D53264982466D1EA1101B3A4225387330289EF0ECE4F11A8F2CE5643DBA7089BC1482A754A000B53BA46DE6F55C13B4B4C858C0D494ED768DF9A366A2021157908D696FD95750AEF985D7A7A2C56766BFC1AF0DD3591A63068FA1C6E1BA9F13B0C08FCC71C6EE02C0A2AFAE2A9C7C35F0DCEDC5E9823F28D5C1BE4E1B656469C2551704DB934E9FE139C2E9897553424AD74D68AB31CDAD48ADAC6F0C89EAE8BFFC8C4CEFA2F0D09E2C96A134FC158CDCF62B1CDDBB072F62BA0930755C9759047553672FE03D21270CD5BFCFA6F30E9BB67CF9FA9D02F8A30C5B977BE4E52D71AAFE6D3D1223F73EC5481DA72491F7C906FF6642D9731B396C4F26BE506B23084421A527DCA74AFC6BE1F15084078DC1DF2D813AE5595F40A94C15A7FBBBF4EC05F0608B28F283E29F8E730268981DAF3AE4CFC111F57CAB46588F4E58EF2C1536B0629021D6A599648F8A5382EDE2A4452E9EF6F5A7A221D35E9C2BFA134D11D5C5DE65F5F0500A1DA11B0DC055D0C2C2789F14F8002A487478D1F989578AC6961E262A08B31D913042410A39C4F9F71D1E70C2B1951732346E79A0CBACB0D63FC4D78D45A0D17A2BFEA3B81A7F14E3C680B4B9B967447B95E0F4E06DEC7226BA245597D2A39FCE4D1CFAC9B204DF917CA3CB8F827AB9718EFA69DDE17458EF3B0C0FE1CC611955FBC64A436B77C33C28A690CDEA44E0EE82B346E2461C6A1A1DBA39A12FEC61A892CB27027C57C1F72CEF1F190ECCC686DDFC043CFB2FB0EA8CB280928139731D88DD257A7C5554EAB6279EA0D0B819595DFF68E1612B71304D007633EE49100823E90EB41211848ADC7A0821A4B3A9113383E8217F16C11B331867AEEA9CF4CBF8310F0EA0A477F5EE1B2CED3EEDC4D0B300BA19BB95E4455EBF195F5E12374D5B6FED2A0E5D6F98C2B187B03E6B4CBAC7C4B446BA02D057D20CB3FD80CE79CE0D74856834228FB07273F4FD4446B8350A8D7C8AA11C64B89329886FB1327253FA162E4757D9CE08968A5C31612328D24D881F8A9E81711C7778B26EBA4E93AB00F3AB996F3BFA79269BAF026F33F5D616A4B306A100BE5899609BEAFCDF981C9EFBDAB444AE7A5982BD925E6B82603B8F9388D7AF9474B8AD18348121AB3E5DF4E7A9151D91F7D724CB2D6AD60A2FEC17D29DF3DD2628D6022711E7D4EB486F90419E66EA2C1479BCD02D2543807ADB8D75226E8B7386CB4C4057590B466B4FF7A244759C5724910A7CD569DEA50E8520387BBFAC32DCED5575B6155BC66C82F6132A780AD670A8C91A6813C89DB6D900F17285DE4DDF110579FB1E28B323CFF7164961B014C82EC825B25AF70EDD5D0BF74331B8FAC3A69913D7030DC1A142FE2FDA1D4CC5C83A747024DE772BBFAEB89CDC880851020A9D4C5D03267CBF996691A7FC1399BF265E985BEDBC9BB5B79487B97E9BB2DA935579BC5AB555EF633F2FF85E51392FAEA07A664F329CD923D4460423BB6C74BD63A4AB0DB1E3BB7C0EFBDABDB95AF5727CD5DFF90878AF51EAA0648845AF99A2286479E7125F867B31B3166AF309102A05F60158A968484FE5F1C0275E67DA8A84AF33A1ECAC4D49DE5D925748FF1E7A5BB442DFA88E5A3797A10E4CB044EDECAD83324986DE44A5A3896FA6EC6C71C646C2B4431AF55A3C2F325C6A62460C7C9BE6235A503A2301333F0261D97AC6692BA5B9B8BA375149685F85A443FF8BCC240409B6A959C1045CAD6EDF0EE593F8C3FF535B46125E00EA4C4A96446BB3E261429BC6B656B401598BB83E365C438EF16C8CB2C25017"""), +846d5071be9f3c8a2a99cb9490b9aa8c794e568b4c2da75439df54fb42f618280fc24c2b6d37d4a841f700c29115645a056aacd102a508bf68446b00ca392f0da08bd805296edfb26d8b885fbeb00743923c30b75f74a6af4be86b02e83c7a5fac80ec7fff129e338d766a4c75f8d35a18819b860306c6d44ddf230cb26718e942308810322d90263120890504422a5890242004850b3648c9465090b06053a40d48c48483920009a23124c20921307262103201a4304c248d520231e24630da262dda382962446d21484d8132885aa8405c326001c74104004684a86da3c41141b60c82002894184011114d51983019234118b3001c356994282261a688d83450121608033705001506220746cb467262a46c12212410478ec130710106725a1640d3482ea3a289c9a40d5b340c484426c3980443b24444124092c290544251c924300c1705cc06849bb26914234dc90611948669934092814421c9c0019918861cc5618a802ca0922c5aa04463808822156409b69082c02cda2606428261e3426491c21113157221196ad2067091164adc3085c49091500440200611d404121a862d041672e1b4052101320129611b991064880c51c281531408d0c80c2344010c45511c126921c171db820040108a9c48620303299b060a01078e0820919b304cd1a2054ac2286240865900641417411a836943a46d00473114424092c88140044a13a951c0264801058c24b80d9246109294684928241ca3289a9209c4389259c6908a3652da089100390458c290d0129160846184a4856120021195891b941150a209d4140194402e94102153329108032c830022539004230386c816254ac04588b81094403299a2681a3672d04240a20285482864ca20100135520bc36410176c04c02d81985114100a03c370cc30041b421154b60903a4405116891aa0405b044a42a63099208c10074503962882868508273003a4110c4431cc846c132570611448a326621b206ecb4664420228a12290991646a282811b95319c122451b8319c46319842284c284cc0b0210c990991002da1a86958348d22168114318a1c8691a4240a24256a50089104284ad236019008045348800cb58c51166618c689a2226419094a1a4385c3c44dc3b82813130a04c7290ac74124894194c86943b86808a30c4ca4299b243211b9880c9228804449099431c2a840189630d8368d54a64c21498c04b82c03174acc063243466899320a51866043284c00461124246662a48dda044c132985a1264e18b044182188834009c4a8500321469012910848444a1669400845c4306d81222c19283110a6059a9069d0a88de1340cdcb664020146ca2286e132911b1702cb167222a650809601143531a1a600d2242801845198368501062e0b0105e3008822b7850235414434891b333022374a800885c8142554368a9020055a442682c244c8241100262e0114648a064ecb8811d38205a008401c348d94a06900386022424c1240020ca8699440821a140083326ac0284622c3501bb740a100505b9069e2040409924d19436a43165224174d9bc0904802055aa20489b42d9308911248298210500a432d13326a9b341224246e828604022862143184d4b281502689dcc8009b02700bc344a4840120436583b23108134a1021680037255b207013a20882324823414ce04240598481e4346902198da4440c60b0515b2431d82825634808829268d0044c638631cb4630244021421260848288d200024aa0218c242a0a022d82026c9a144c9396914ca88823143222a5655a920c4a24319b324c19c60023a341ca96611c112920408e54066c21260521918902160d4996510ac590a0328d9210259b94441ba69009884509156dc100509938091b33501c460c1c909152304424c440ca8205023426a3284802394e62000a8c04900c021220046ce1004418a06418a951a10645132546c03461c48431118524da166913934409474d81c04c49a660c8066d9214701a0291e1221283022e22b389ca022801a0019bc8450b446d13486609c28c192090100128e1b84c1129820404444234310c4428a04609420649d4c48dc914221c264e54164e641230611292e496094bb8840b098cc80808a21630809490a3104e22350044103040146809a9852317225a480c22120ca112645b1630128440543066193006210926e6c23cad48453c6e03f5c98d6c20db81181b02581e8410ab820fe98d518d35181824493ec940daad34d09bb90374b3763a57cb813ba4caa9b3696d793f6515dcaa31a1f58fb85c931c8ded334a20950bc9a82b3a6df9052970c09033ca0b5c3fb95410b28fcceddd5cc4ddaf0f313c5db025077856a4bb9d04b3459171c68b1e3f7a233ead36f40f1f20c8d8f4c478a5c73e26aac5e9aeb0aba57147031df73106b05ae4159a5e9ff514620a7919f360c3c94e4965e48d350f4492675d6c86bd5eec098895f657c036182f8e3ab3dd467a23fa4a5d6aa775319f86d38945a415bbd2ae6166fd619e5461560af8241c585beb7f15564d0503adaf4ad6b6242f698768b70f306d66487959ec26c3eb7d2bf074533ba3f99ea291b51d72fa15302c74c03c2ef2d58cd241bafcfdc081398bf85c6f9754f699d602bdcbd789d415631cbced0b54c35d19f79a71410c828d3840de9131b607000f1516420caf078dc85fcfd087c8047235c878440a07668996c149a5980974bbbf4dc32f82139900c5246e002d5a211c63e5c3d873dcc966bcbb48ca6bcfc8d8f54e3a7055f5efb3cd8af0b46b3dd5dc26d5b70d249e0073647f3ae84d835675e871c5222f317b5c243e3fce32017ca9a03891acd4c986898e174f80a9436be2d4b0a99ba4511f8ee21dbdf44689d085846f8d8c2ee48faf14d8cfe6cd7ceb6fa1bd61721492f1ba5ad52dec7b49dc9a23d939152e4042a0096c5556174da9a589a226b6f5dfe5448b73555b2110cdb09cca3edea2c7afb6f38c6432ad7c6a0405a41bb570f0570e5a056820b5dc16e80ff419ad7160b98a386a7427dbd4b1e26ad0839f542c5e71534b6c5285fa5f4b12f75ea94b9272eea21e163bea4c0651fd59b0c54262f70ee81303e3b3df93a8bfd1243f1a1b692110de4a5e2cc5e75dc201c491d8a1336f1e21edd5b9d20a59fbb89cd6d4715a04a0b923155ad110771c0ce326fa4c9e3d2e62e3baf9ddea1d3f0c2d0432b8073611058ca545dd387267bd3fae1ab362ecbb952625a9cb2038c7feb192aea08c6a92d141f06e888206330bfdfdb552ac5ebc6c2fb7ad2619fd1f149a93cad33615958e064f0eb89353b82cd26e4a34c518983e882f171d91aa75c62a6b4b318d732b063e8ab3862c97e40ffe20571f065901bea3e2d9e89c08e22a000b76b788cf5442add8495b63545d939a18de4e1b49821ead033c7479602b0c2388e3434209b00db520a7b16f22af9d3e5508d6d848aacf6b3055f82384e637a0981b4fdb68a61d1a845154a65c4287cf8da9159a2650bba6ebc853e2b6b32df16d1588d8f5b48732c6154efc55295cd8a5b765e35f88a9b4025156963aa7ff2e414af1305af3ab9aa9723881005ecb1188f36d21d2f7074c74f17c4c37eeb959a602362443c62e40d628a5c47682a4ca3346ad90a8499dd28d7d10f72872b7e0b73eb3041fc2de354bd3fcf962f0589a2859c8ff71b0146af27bb66d3757a6dc26ba7c5bb7eca491bee443c8d48d6df9f24d40e81fe168b545a34dc298271920fc97546f6f304c505fe43d6c8e75487c04640474e3943e34945f30f7ed533855c716c5ecfe6481167e50114b784ac3860fd606ae4e7fcf4b01f11f7b48523c81071e7c9c234a4eec5c329d83d38e82deb37f1f18dc7cab2241507795674f830e00681ed9cfb2765a6e81193be5a8cd5b832765eb814539f8522fd9b4802e26049aad26ec3c5feaf9203e65d5c4f544b8f214cc5831180fbc2c096499edc37ff51c44b3dbd826777596ef0da35bcb38daf077e2fb717910e5b68ca8a7c5e70c400c107a972ab3cd13694c5c21f7ff2e4293e5cd8278e37806a19c053947df531d843aae717dd2f5f7268e9b642900324993cccec5fea04db7778cfa203e6e9781daf9f53582f80c8ccfd5f0d32bb627a12585c98b57ecafaf7f00217dc99bc9a0148009e0fdcf9c2cacba1c1a7d3aaad3f6dc969f7363ebcba222fb3def7ab17d3a28dd4a16235e64bfd4843956faf04732c4b226f25fd831865b3f17cb1aea0fd409feac59ad100a37020d91f7176c8b6e11c3957c6b8835c4c0ef25280d321c8621e72100248bde7bb9c1b8d1eab666414aaf9a19ad34f97fb68e68f3b0e58d29cc01ab09b8b73ef51813427ae84662bbd753d6864f0902f02b1f2f52abcbc0d580d971d13feb60b949befc22889aaf7223b09b22883884ed491b527a6dd7c420d8990bff759ad5ba9dff47631abcda7396c75e3f420a295ce38a1d3109c85571a69fa5ef7488f21fcb02cc20765e09a9cc2928925affcfb997111da0fec5d5e3f540822afe153b1c55687f7b6463e690ef816160707effdf743de401494504d28c8706fa70aab284e235e6b576f84c9f8ef70f0cdcc1a21f091871f146c6dcbef0f90baed20096c1d94ebdd6ad568fb97fe122df75b80fc3180b76c25e9852e94ae7394cdec927ac17011d43959d0dd0c5cf4c8d3b7a69f2bd311ddd7cfa202d39524b087b10a7e6c970f3698c21c0a18d639a56ade76f22e192f3ba2a50e415df716a3436f82de8318ab7d82f3ed86e3e9138a53b82da653f768183d653352436df927ac92a5e21adfc3647d6a3ed7ba9e238f52b5510b31f61591d89b2cf468c9d1594589ad2e7922424fea97b04b012153bdaae7f0e5ac84f2277a822a0e509d0e5f05eee5b5454b76288537c348003a9ae12bf01a4d747bad04b3f25cc776edce8e0d96ce9cb6082d7ae639ccfae14872d76710a9559f478e876bf0c3e1081bc64881287441eb3b79eb2354cc8703802267d5fe37c68e9410fcef8072a73ab8b9fc2e8c088a1de7c6534a38d7ba422fe79966b4bf222d9387d01e83856a02b6d0a985b0c496941e78a9e6f49e27590105ec1390a0eacd09eb3c8b828dec970c9a060c7031693dfb8a3fc3b44756d780f3399b806a8b0a5802f553b6085916fe619490a8158dd8b0b4d02af33d9d831915b5245d41c0474c4113a053860c75e8b36d9f84d5e5341d8361efafa2b0acc8976d74a568443f70a87d00ff488437f5f76d15d3bda26ee3d271a5178e0baa0f2ccd2927fea5e351aad15f71da838d210bcbec73f70f084887f4e013af4bd0cfd44d775b0f02421dba1356e6c83bc88f1c917c5f4dcb8f637ae36e425062a0f7b5b4a31c5a16a366c8fbe1da0a2e5b6d83379db1e8d1cebd9749bbff7d66806c0982878bd9b54b29ff158d4a1f36f515f27322f9ac4119b88d723cd37a66901e4f45a64cf3272169f8dba8a57f83d1ab0762d3b7e679432572dbba5946f9014a803f8dc823781a72334933a10d59cdde09e1248ffdd493dde94f9b07e933ebc6732c0a84ce233127ffbd4e6d136adbcb45ee02beaa6c0952d364ee33a4a0724db751f99719d1d52195d78e363aaead6e2addd8b04c174c3aa5ebba2a2ea395a314d6b85be9f391e4d13c586ffc63f9f4532c003de1b6fd07a549cc3b72220ca39ca73fc447d0fba82c42948b42cef9e88762fa5d5f00d7c3f41789640f1a70f57a9f8313e0085af505272098630b0e6d7ffd601d887e48220f323acd9b6f6c71d49ae9d7d325424f94a7f537e775b8c6b3957a1feeeaa2c4977477b12752b21a219504f9c7cd030ea7475422c810049a9eaf9e2e838881d67aa8491f41334640f941ee966f370d0245b7d7c90b15107c9a2ca9b5cc4df050f57ad3b9ecc10f41b501f6041c52c1b2d82b65ed49f4cf69df483e62ecdb8d33c14d9736ab11e560b443a5704bb023a71a814bf3711562362af9b89babc229181ff804e5d0d0315b198939377574aff8054ad079e4ffc18d77c4b93071842a2907b0dd8f6d7c3910403b34848bb030b16e6e57ac801f2cddd7202cc99192f810dbd41428847a93b18c2a5cb72f1207a2caf341e9e175162575f3649cc2f64f7d86367b87177c7317f86af8d14eb411272feec8693cb1745c94a1850d726525b563b2625430e9545e6ebc5df8a7bc44c5d11ec4e7c8af86e12e0dbf9a6dfb23efa2f74f612cddf04d3e696fb0e15b606694bb5412472cc2f29cc9c2ad22f48d6c3f270fb94116278f6f6f37525752f942f71060d41622970dae6b7f2b355f619c509b62a17f61007495e1e33053fe776a3022b34710ad48e81eb1a7aee5c8acbcb9e97c9fc1469973fe5a0a5b119fdd39658a56e8397f358898c41e44638362829f5106557ab81b0504f9751a2d3dcf2da9a88869fc04278cdbd68e6e5c0c8135ffaa114f16c68245ecaa9a1a105fb5c9630579016b975fbde1d6a0567224da9c32b3e1b42f2bfbe4828d1c3c2bbcb3eaea5fbf19ea55d86a58948150bc0a8c126487adae8906432369d93412481501bf32b423d5db70cb3413b52bc5a586faf82622d5331d1e1138045849bc8e1eb9fd02d3e713bb9f7e2a2a25c5cbecaf7b2463b9f42d33d52e17521364178c046741a408265ff0c95a2a1a61fef9667b17225c90169e991a101eb71e428bbfe730a8b3fd83370e7436dac68a81e5c4c42e8474fde53fd98db57ef79bdd13721b6c7b4e8ff982729c14b04a653808ce18077bdf210bbfbb7fd07fc39b8919500da55c0ba13c21725c7edc69c3f4abcf07b047f63397f3afab2b1c4d5918bb6328c3b522eb19a83af43fdacee087955b734c45266eed1cdb112ff8612db42a2da0ccf3abb22f198fd38f234ace12e80c0dc3edcf3d98323d0cef04e91987c"""), TestUtils.hexDecode(""" B5CD00AE06396DEB95C9BE213BEA279AF0D10F1423B5A71854413E99F7216D9EAE76C8AB884545496559B14AC9A69801EE3FD2EEECCC557D7988F34B82D244461388C7D4EB16DAC3C0FCE0783321A1488DC16C3C688126754BB4C26308054545D2E46C6BEE26C25A7C3B701341A0323BEBFC50C718162B7FF3B6FAAE7156FE300F2219655D8D44DE89845393011A2B466233B907355467EC49C9F832044BDFCFCF722D6DE7946FA503861C80037549ECE8FFF95026CDA33C9000FACC334765A60456084A0614455C83E0D5D991F7ED43952B7A69F1E326D7BD33822CF1F286D85FAE78F0B8DE186368EB334CA56070122DEBBEB920C5547C46C1291E78AE48B72C7A39020A1A2E54E59A2E46606C99E652FADB39AAB25399B0830AE733FDFD973294B93F47C30D0824686C735E05FF51A95C1C76467A4BE6BA80C5182353BD510E8D4B60BD43436F7021B3F5980D1A769B2E3BF04E0C257EF577828B327E2AD85E0581787B9B7FE44D6B826BF8405D3D0BF8974D2B1C569006C7FC3D2891DAF38DAC36F64A256E337B660CA59D2B45F1B4AA1C0C72B78495FBCC9EE9CFFA4B5A101F973E3211E728040904B0B2515DA4B1CB3774EBEA1324EB6907324E733C7F17BEF6FAD0F6BCEC1F08F785DC6FFE02FFED5C0B7A631907196835EFFD0730FC8FE020B0545C920DD7B2D705F22D8D205804397F6FCC60386F4A576204949EF60DEAB269905707396CCCD8DA9B895270CB39839BFD3EE64149B0085B96FEDAAF8C738E449E585ADBA037BD560EAAE978A6ED61DF432B6A9C2E50C2EA33A8702A23E6848401F85E2C18C7C767DB15920C9B3B030728FD9511F8903DFC8572A3679F986CA1B684B3AAF489DCD93C622C6C4D475DD60F10C390873B09B5A352B6F5A104C90782E053F8121317EB8D1D4C0145E04E3B68446B69A0EF81097CC6BD0B756AF78963724D9C83C61B7B79647F0844867B605E2B60988D2D7AD07CD6BE2D8F904F0D269187C141AC67C9DCF9961BBFFDDF3BF34D9CC5781D1BEA348F49EA8FF7750F7F3E0624C16FAEFAF1D8B6A818AF5FC5C04E2504A0CF4C2DB54930EFA759A292A2AECA1EC3A08918513D95C44BD133657FF043318A17BE4A5DCAC54B87FF38869D017A4B14DEB60480AF1C5F19A9F87B94B8EFE0DF3F931CFADFFD7AA50AC86D9CAF6D434CC81E6ED123711E34B8295A446B554F6DD5350B44C614324D8727F1CE501743043DE6EA085DB5154AD8E30E114A02CDFC96BEB4F2718033B227CB8638BCF617C73BA4473851E62C8A287CC4F9C659190E60AEC468DE7EA8841E3CEF893F3DC79DDDD56B63102EAA5B2793711A0451EE1655C6768393F59CA6085866FB41541D9997C94BB56F6ED5D731585E7B25B1DC853830DE5DD75F66298BDBD2E505DCB3850F96CCE0D7274633234EE2FA1E2782DA3D6CD8F5DA2C3063A923DCB6A2F82614527CA2A88C1AF21025B88A08C3104C679175DE2CF00602B13E58FAC9376BECAE56A60A6A8F144F1C98C8FBDCDE6FBCA4ED13228FA77CBA5CE631BCDB368AD9219568777FB4397BB40485A9AB63E9E3FB343154108D8117CE25BEA30BC854A241745FC6C26AF0D64124AF10BE4BE01B8A3D842FD9CC4D805B2BE26F8B7BA0631443F48C7F74207F640B215E0DDC42B1954A1EAB2C68E63601DE3AE3EA54E16282BDED00FC7665A9E8B098BF034F5E950ECDC46CDD22210244F102E41E0930FDCB24AD6C72507E5AB6FCCD4D6B2A2703C358EC1B51AC87302A5F507BD01CA6B5FE04EA2A5322EDFAE8161965524C61956CD201C4BF2F01B54F008F5F4B6770D0622099CDBF94D6C41DAB4A5362D630B9BF9CE240ED08D698D1AABF29E60BA533697C3C830521314F13EECD95C7D2600E2A756AF19AD94D9EA39FEEF0E3EAB3EB401225C2E55B2F2A8D7D1A3AA77A38BF9BA31399F6E6458F3F21DE354BBECC2E29740FFF91FBB23E0F61D7E0698CBF82D439AFB018DC5F5011B7BE98993E8B655D83C666FC0CF84A532C7655365746FDB97874D62329B1EFDB0B0C8A46056A85B60E38AF8979FA4910D2D9CACC3B5C1E42049D04C44273953350E0F756081D2DF6429193768802577C381897BFE540BC036293643360C848A1AE388CD17781296A99AF0CF75F81D568D0648C8A15436BDCB16FD83287C6A54F88F2F75E6B28E1C5A3AC03501D6D723AC5EBF90517D194A596F7F95947CC169CFF2A65D2BC9B54CA6AA45BA9E901D4AAC81FFE9E62A479EEC5B3F9BFF24C69FF56EC52F1183B5AC48A5BAA90BF595990B6EBA5B1CB6D88511C7D0D165FDF2615351B0343918B966ED1CA0CEBF6956BD2CA599E18619E1A5930E47CAEA92B8E9647A0262A2B24E955040750E6C7B935982CB742EE756DB65B462F677AE09A7521B0D3A42C2E97890C47148618FA6089975F5D491F4D3F69EBCD54C2B53130698A1F4A47505194F675D68F2DDF5983B008E498AB4A25956CF724F5C1250D5F9C75F3DF9BAA696E300AA86FB4B9378EE18E79D015CDA55D6ABBF5B0BE819F9EE58B49656D3B112AD8FA6651A8905061A8E37760C3F2EBE6DA611BADD44268975B5000051BDF7158EE3DC200B47FBF8568C9F22719FBEFE5906444DE9300689BFA1AD167"""), TestUtils.hexDecode(""" -B2E661C2BE985A4DAA72B12734EE09DE1C78621F91D7E247553F39BFBEF28BEEE7F11654775416E4694086B0A640960D1DF784E8F62E16FB831097DD07A1121B00251D35E4275ED3312C22B41CCE76851A48D9BB0C46A64243110A4CB759675CA7D1B724CFD94255F11EEAD5AD01C88F70E2CC02001D6F44357BFDC159C4CE44E042FB429CC7D32968C5CA8BEED69C6C3769BF2A83AF75A7831B76232BE271B33A43A8B69A91D23E762280E2880559392B4752D29BA296BCE607AEBC0771AA0A92A30B72282611A693E828D068B04C34EC01634488AA8D1862239015BC437A23807FC2BB1B27CB9EC45DB5BAF866858F1D69A3005D4D5F210E0C25092D658CA9224B49FB147CF891C5127FAB6674FECD864A1C26E4881803BA3F8E6394BA98D70330F5D1221DA1D1E966EDB682FE3BC4F7CECBF7326AF5EB7C582B085B4B7F603212C3C8C6E59524A09227DFA93A44D532650F617470D9D250689538ABC832F38503392A96B0E7BFA01323A85696F3E80AC0A860C685AB4E248CB646A107562008358B53842123593E5FCF233951D43D33B110FFE33EFDA0D4A0CCA3F112F94C85F967F0C6A0F7E20B6836664B70522F962C395971692B29F659F0418FF753BD862966D10E44B406F4CA1DB909FE01B6F9F1B60715360D4617E7C0FC4B37692707ECB68B50D38DEB8F40B8C304080D81B84F60D49B7E4EC50B02E36E063FE28BE9A23E6BF17693B8B5C909B5B136BCBC6A3832D53E83A29ED9F933A8BDC8E318BDCEFBC10113888C1CBF39464AE16E2B30FD7F94AE1A0FE8B965CA8DB4667BD41B52E497D60C31277AB70C19350B2C410AB302754BBF7C126C1C9C8C298927AB39E9B4A024C0F47691880E11C0F8F7D5710D480FBADE860D72F43D1C676118E3F83A76FD6CBC7093B7BC18F851CD93D81B0564D4BE4BD39135BA2ADDC6A6DA8AB8F7B15284794E935A339E234E8452F766DDAAA0532DDE46FE6E4C727856CC29D7E78FFEE115147769543175546B8A838A0F831CBE16BE864C733C63F37E6FBC1CE2A36123BED296103FFDCF8F3BC36A7775A9C17F69193DEE0ED7C1423FAF6AE7CD99EF943BA174A6262916B78F9516B0464E8BFBCF512B80340C489B9857798EEB539062F40E39AC8EA3649E787C0A87FC548F0CCB801AF8C2B2156FE3FF69BBD30574D8C11D887A98231B7C6F24C662A48329DBD3DD410A019715DBB61F72D14883FE891731975DBDE9BAD0C2A85FFD773297E399B55D78C3A2C25C27E4FD0BDBBABAD85EA6BD6A3EC8931E0130EE4D068ECAD5BDAB22865A537B3ED2312D1462EA6E36E14D5E49F742F2A232E5216FBBBB1802B5ED89E361CDC0D2FBEA4555A895FDDA03597F2B8966D147FA586BB53316DAC62568CC823447B24052680CF67D8BC8D6399F928781A682A8BDDDCFF8785163A3615809D1D10E14ADF471CB1D93052434CF9D98F9D0D849283079FE431B8114EE9292E52F49C9868A013F0403A20BE45A2E157803CAB01F9C93701402595BBC90132E9FFF845165C799443F8B38E360F660AABB901485569D2B0081D00978B8A1B059BE9E4E98EBC19B027592E453FCA390F7C9DA085255D6A7436C8F1A857C547545FF0130A9F1E6A1B2DCD1EB03F7CDEBF39CAC153817CB450E501A62A1B93C450FD18CA956659D17A31310D517A81DC62640D8102DF1F79794CB7C096B5E37C2AE352E0BAF1A17DC8794D597A258BEFC66F26131298FAAB9EBD6AE3FBFB6DAE24AD74496BD1F077ED87BD1728D1809E96F70AB8254A9B8E3D30432700BC61FB747141609D4B9057BED02338233EE71B26364DFB9492A08933A2D3392C6453D34F33940C54B956BED2C11D9D1C68DD135AFF9165F3F2C801E0FD1480EF0BF99B95C68773CD2D765C1ECF04E1CCF68E659FAC8CDC03B44B5376EC888A485F7F71EF2E24195D75016CA6A9229C2D0FEAAFCAEFE07C46D3DA5942A15AD5EDFA8FCAD9A46ECFEF23A31F342071DA70A138BF5AA5003B70FEE1C00514EE0A3A2D5988F5EC5C279D7BEF153844DEDED0222DB3EF8A4579AF641444ADEFA07AC6CF37F58513771B8C7E406585296A7A2B6649B2FC1619BADF31951AA902EE48D5A9AE8DFD14A160538FF861FF64BC8E577C6E77F79672BC0273549D14AE1895479F8941AB0BF3093C5C439591F8A4FA453A9784A1F76FB792732405F05A8660740D329F2F68CCB6167D12958CC58AD567746667048C696FFBA426D40027820C4C740E66666E50DFD07C0ED76DD4C2080FF1C29794D6F17570A1B9D3D9AEB90AD34626B94A08202289A6409145D820C962183C58CB0345B287BE9EA15C5C443CE113270ACD15A075399DEE56E95E4DB23EB19E87C3E29BEF00D00A5442E67A7EBC5E12A096090C6AB5576DB5BECC84B8000D382540F98C41EDFEEB99D3DAA561FFA0C7FD6CC16FBEB6C514B45A70B2358EF4A53268612BF022FCFA354A80697225BC2AB988322DF31640FDBD05EE154F7C79A89463B2BF0C218749A454CA38DC8B5D1105183B7108E64EF8DB8FDDFA6BEF048C14CE5620A456DA5CB576F0BFFE4FFEB8333A9211707F5617628C2459A2104F8D5FB7B9581EDDDA27AD3BDCAAA7D037A3F996EB765237CF1C42B090F3B0453DABF26F9C92DBA120BFB577350705736EE295BE77CF70A7D3CC6AD388A526CAAFBDEAF67614224B6363E14B3DFCF2B6F4A0E8E2A8947D64437FF0E90DB68DA40D87AE431C02E9BBC647814C60F3CE5BE422C2BF3AA8529B8D706A5F6C3512979BA6E54401F405E6A8097CD0156A8B9D4C434014C2BCCD0DEC4559A87ECA3CC06200D77C02718330CA621F4F1B58ED3493B9126482BC941CD34A5BDC4BC3268C780479453CDD932C421229246D9BEDAD0B734F8B4D06A3780155FE9A88DB8C540FBB8677DF962FD0E0E4C39197479A68E42D9AAF4D1A1F56071F994B1C0FB4B9E6D150220DA7FDA2205E4729FC5517DBE0BFD9256EC717F0CCCE43C2862957E8630C10061D36AD371629912E9C1FA2A01B45AE331508D42630B39E5DAB3F141DEA254F1C6EE0A934B4CEBC4FEDB5B1BF6EDAD35810B836AC2A76EA9233D12E39553D77D1AFA964F8B104C48BE49A65CAC8EB3C352EE1ACD5EE14127340D6747886FE47DCABC13CCCB3410BAC0F96C718CE69DAD106C3D6F3565781EFF03812306F65C82613DC032F10ACABCA0E560D5A673F427FB231362D46BD40BD0B811903C259C2622E893DC4B91F21787BF0FDB976C4A6286D799EFE8269F9E8DA6870C9CF1A3A29897AA5C9D2C75D7C9FB29E467DAFE12A414398C6CE08917BB2A322057FF7BACE20782256624C1B7DDCBEC3AC680429497E06C022578A7D8CFEE14D20122C955005C0C4D3851C3D9D009334EC9B036AD7E1B08CED43DF8D148D5F6C72BB87F52A458910B0829B2848D082E3AAED3251818F7991136BF2E9433E025DB193C2581D1BD438F180CAFFE618CA88E677D0798DDEE55C4CC1776DBAEEB564770567432D34BCBAF6BFABC62E75C714BC76EFB785A37F91446E338546B5A1CFD83BE448405705D7F86B2E56F10FD54E6B3A047EC215DEC3F787EAA157D317C309B37BBA666810167EDC9079A4303D7402B8ABDB03383EC7A37964AF35C3C18D7713F22CA9D278A3F49FFE6C7D158DD97FB23AF1F23916E88539DBF6176F76A4DBFE11CBE3F914880AD2EE49FCA530E483859BF41DA5E42F01B0503A39D9C7A8F0A86B3A8184D87AD5F5CDCAD88BDBFF3C66907E7A448CE0C98260507CE656DA3316186A19B902DF6D1EBC77693BBFAA8121F2D679394772A7A1D127BCC51B140867EE4DABFF35E303BCDE2493D5CD02D302833AC464E34EBF202542AD81F38855BFC1C369F25C1AE2B3DAB609461BF7870D68D2E96D78176C2875F0C277D2493F5653CBA632CF655125D01CF48E2773C67EA58AADB857EF6CB50614AC3D1925C016E9112F36A28E142DCB5F2C1CFECEE0B974D254C764EF65C496D9489F65C976ADEAB8A21C2FB447FD7568C7E7D76617C67C812DDE31108200E5FD20182A393F2E2D6970195F7EE3C57DCF6392755991951F5471E402F88AC6200023E4B9E4EB49AE838F2289039664EC744C544994EF66DB2B86B970D20317C8A853AE532FEB55C5B3C09239435E1024565FB50B0C91A9896B2369F9CABC190C3131BBDA5C8673BA8C748A5FC49EA8E671C424F39E0162A9E479C3C611B5F5940C297050122978FCFF573100FA891CFD64D9825319EE01086D12A81F1D10FE77C8422DEE9E518F37A74FD8D1AA0070C99647B758D7EB8648618EEBB22A2049BC18A6FD41D3D9F712448AC3322B4F9BA2330E61AAD6FB3048AED745198ACA0598A97DC5B7A8BCE9803E0A62E19A2F54BB2C3EF80472AA5E27EE039B7B4E722358A242BBE7874EABFC76FB3ACF9D7F00C7AE2BC5B841DE02A8388DC800855340CD4B0A861B4E7C04FC5F50DA66FD845BCE7CC8269D81D7FB5D4968566A7EB7C984F71B9B5CB3B1D5AB3D6669472E92CDFA16B2C6B5E67BEA9FC54ED393121BC887BF0B099BA46082DF688126891D06808D2F2905B4F1607182745975A5752D890C4023BAD18A5FF8B4A4FA529B4EBC1244D715F186440EB3EFD5B6930C58DEDCD071384A1519B73F2EEADCFAEC130FA6DD6A6F0233BD1FE25AE7CB268405457EE6507DED9202544E0B5ACCCC830180D4DDBFC65DB3E32C16FEF0C1CB73949C2FB02ADB9A22C5727F911D308B3389A520441D5B5A7CFCCBF1656E6CF5B4B1D10B638E3D84440BFC32E45A74C0D428FB9517D765166973D25EB5BE2A5385AA6335975A4C8F3E94421E7DE1DDDA6E9BE97857C70F8C339485B5A85245180A317302A2E58404A1DA5D5583A806E8A7C8CF766F29A816C25BFE9EB6DBC2567C0D1D4D971FD95B7CECE133B6CF6B98CCC6C18DDB84B4B23FEE7BBA2FA00EF32110AE0B525F39DA0B0A7DD8C7DBF2A7F8B3CC90420B5EBCDC46A2367D236BB993ECE7FB1059453D08DF84ED0E1CB17C357BCD681765F8A6126C36ED49ADA5C82273143906B8FF421EC0B4DF20E9012B896DC3EF63FEF1DD1ADC09C93FA301C906FCB38F28A36EB13B4CD4FF9A6AC5D2E146595236047005814048A31226CB80E2ED09DAD75F95D5981AAC594B8C2EEE9D02D9C7383CB7EF4108EFE0FA7BED68F3E4B0972F2FC78373D7FBDFA91BA0A1982D47A7E6FFCD7DFE17CB23EFDF20B10460676EACDA5D46EB5EE83BD48B77C4F4559C460FB78CC3D7EF8D3016DA618D1866B69A99882812BCD6F2E72C679D894C97465EEB5EDE357FC34597F2490EE3CA813237AE80C55C86AFDB734627D188819E56C884286B51C5609C027D9E410B5B7ABDF45E539FC23B71F9068DD1E51C6A1DC922CB90716862B2F60532F34ED97627B43EA6D6D6A770DDA98E53C9358767B364386B549DB2B91219F17632BB02DD407969CA28CD8412B7FC8455A9C028A63930786FE41FAA360D240005F915EDA9E68B559113AD23F66541EE22632ED38187D4BBF77C15CC9F873105A749711382E202B5B66E9DABD165F3B296CD2A712C82BCDF9C3F0B9DA1C9BC0A34D6E9EC01397008492BEF118B3771BBD5756B42817BE46166C4CD13C8BD6D9B75D73A147AAD5F4863D664CF84A84BFE465855D7F373FCCF6EA3CFCC0E28BD76E5A5EFD85EEADFB15E7AF47ECE44DA1367C90C30092271964FF524909B97D2592742832933A0B04DC59CF62387AE581A2D7E13756C1D93855B8839F7965A46D830A083036FF30E42FC5F32F9E0021F79DA5C62E16BB2BF0AAE7769270704676A9257F62B0956EA742D8A3D176188029358F90BD91373ECFEE5B46AA23373CE75627B0C45C9A4F15D07425B5C1C1E1A3882499F030775A3CC6B5E2C91F48DA0BCC98CBD74691D7513E3817798AC0AFDF0C6B349829DCA9B9742ED77B4EC779366979829555FEF4BCF7270328773C850BC9348542113EF19012168BEA1BA4C1F607FC941A1B9BAB11F89D5033FE873D302CE0AAA51BAF328F74448E70907C302690385BC3C5E32AB5DFCDD887294377CEC6E1BA90EBF9204C28DE77CA85C7E870C3C74B91DCBC88CB30D07847912100B081578CAAEDD44CF9F79736E91EF4F0D8C3555D347ECB2AD272607AFAC189D3F8AD3C7594A66F2614133658D9FEA2DF536F6A11AE1B2DA795EC55FEA5435761F7A2E8F76563AA346F00CEEEB41B0E5D43A99BBBA029988D792FCF7B9E085C1052D319B5ECFEA85E84D354B832D84E370880D0552AB9DD31822D29E6476873E22E98EBE74A14B72437F5EF7E36987E905722B781B451053DD5A5D3CCDCF5ED40BFF1AB4D43921DD019C1F41B0A9E75CF740B6646380DA9A1372C4771E29C4772F67F0EDBA8FFA3D907ABDCC881F5D76E68EB8124A45478E9B66B061CE302D1605B708224A7DDFD25709F4F28E803F0E9FB3E90739CB3BC84CC84621A19F4050C4E93CBE089A2ADC1CAD12894C1E1000B6C9495ADB0B1BDC6DEE4F21B20689FF0F70317181A475F61626E717EC7DC48555E63A23C494C5D5E5FE0F60000000000000000000000000000060C101D2330353D""") +fca242816e6b98578837b5592bcd66732c06ac3794932640ca3b71112407c8a4c0989723966ef76b5409a893b8c2981d6b72a1f5cd92d81c12b9cccfc75547f44c27a56431f324a4f73ce4f91da398fdbe6a97ce171f4483fd0c1cbab53fb80c41963798eb10dc422ea82719a0770ba82e1491512bc40d726b83b3cc1887b5648204b00e8231a654b4a796d7c1c0304e93579ae6ba4f0945afcc0812b86cb8872842ee8782ede142087a46dccc78275aa2e52f2e9344a81c4a0ee65d4a9b8ce1ad020ef6fd1e6cbdf8d5e56b1751e67be662b90fba01a983df891eb2eef4886a1da0b6bc0cedc4b44f33df8ad946b68e5389104b46e213690ebad5b50fef7dbf2aa6f51b125657e779d9718244aaeaa55ad0bbacdb76dc66973e331be8aa3e6a13dad7d227121e5fd1edffdaadc6bb667e40d49c1d95c6db663b4cf374a3b93e5f270139c28e98fee799a3ea015ceaafb881807058b199dcf0b447f46d263bd43d02cf232ad1c27c3ca8e0cfc1c07541aece1980c9240e77b9f134694be94bbf05eb6710797a2ea2436cd6c10b18a260bdef24530eafc2618d17f86922e91c9fefe7528de98bcfca9194e53affc13da5787124dfdaa0e95f3924fcf6fdbca78a61aed2b5125c6b94733eab6a215856185ab31106fb293d996c9a8e80f9bd1bb2287a88df24f7f127c371d5c8503622b3986206acd99395bed7633e5f73a918a45362d58c921362053a0d2133a1989516cbb8bc29dd2fdae2dbb94669a122e81ddeec46fd04ba600d149cd728285f2836a3023521ab1362736a8d33635a6fceaf6f9684af304a557225e4a80ca403583b637c4db7e9185df6bb77dbb3b09ff915400bca75a645a8ebe36b99948369cad683c56f0030f4f8b8f6610d20c7662f538c855bd1d08b719df8b34873c4dfed8046372063ef58800ee7abd99ba66b60098e0004395c2646ffb158411526dede3d9c9e1b481a2dc5298f27538c6ed535fd0e7374ebf2ebf214eb14bc3c674f61c1baddef4435344ddbb08d6fc8240ff5e41b817e9795670f399965cee0d8a4540b795580ceeea3a31c61c81e3613331f21b496e8dc833ff7494f50e81f0366718622602759d598f1831042a5779ffa9ada2a00c79b0419ecb05d3ceed113160653bb7db0d06a40fd272afcf7f20fa18dcef490387b84dff70e761dd1bbec5e1b25eb30fe2c4d18135b3c5f315da29a98855f81f9b1e01450557ce6fde5b2471dfc90da07207a6f6d181cd71e33af713c0dc353f7166bd6aa7b90f82eba2c03423144fd12883e80538de76f02a0e12cc65051b981eff9d25a36ff79b4c6c84ea537075886e9be23f700570e43e76e8d61f54b49a576a99a57b464f2be6dc8c993c78a1330ff3580138964a6cc2cd46006ee1a72a268ababe373646674dfb4bf33126fbb8f5dd24f4c79596c783fc88b393a75355ccaaaf698a45d678b01f175bb31bf7d28bd44a766a60dd8d2510f55bed7fed53f6718578fde622c49d17fa64926be1a084dbdff206c025ff726ddd2adeea11a021680f3e75b865bc364dd7d752d3b62b7b240838c5645f5338326897e751e968fca1b99c0baec1c9fb227d6f1fe61abddbe26613e5abdf6bac54d658b22cbf8cd498114019f712027aac6e7b1fab7016aa96ff61bde12a44d540e33c30bcec417f11fec1a0536f61eeba565d4faf3b624eb1205143e3b6e6d22b8a0ab3767739206a89eab990bef3f3d763a816cba5aba2b2d8390235a197362382c2487d80f9f47f0714206b1aa9f40840098c6f94d920fe21950274f7ca9d22a506a76a328cb28a50ba569909897b15ac2964a111ce48ffe137d86c5aac313050e25f43b9c041c93dac0293a8694f76845a7a83b8e14db7fb2a724df1f4e64a772e6c3078e465565e1eacd56c0c4f13a3a90b53bcaa0451b44ee94be4d6d23707057b4eaa6879203ba81ea953090eb450408eb6a9dab8c5bca27c87cc302f286e703be7022044e0ac4559d4e861f4e31f8915831cc9b81dbe937c8b0abc02b61c57debcfd0f5f8ab3d7bf0b05a5eb7fb0bb587de8c2bdc41299e744db3c6f92aaae2008a14f965023f17ea55fb0a5ec6c884c478cb3a95722844dd823be55f15a363354634a1b3171e349ad6c69f1342bb3dcbf0cb44efaa6d06932e064311057a97fccbb1430aff5509d0f34aa57a7cebcd5eb5e9fd373960065c79f52a414d16ce959c97c1fe0101e4bea038dc6b27ee847335073f62a91d1d74ebcdab4965e1cc501c07cf4a6050c406028f6250d24796fd4736144ff84616a63a2136fe4b8ac9652d95965659d55b67355f5de40f6f11e08fbfbc2ef005b3937204345e03c07e67803a8c378368a7cea377f53318bb140e0760bf79fae16f4132bbc88d8af335c07496fdff21e36ca375889ed56faf2622377126d399fd76ef9b2746e1ab666461a949c06727d1ed191e197418ab7574bfe292b92ca61e7972e4d0fbc6001dfc5438f95b54c9f226bda6968fe5e5df06e915fbb58c6123799f6c8624a40b18542c18cf82b89b606ba532584b1542f0b0684be46457fd6f295f0a3e79ab8634b8fd747d5bb87ac0b33902804f691c16874f881a3acc4b1f88183dfc3defe276968bf7f7ed53e59e2e5fc0db0f13dbc772286f6d83cbd47617bd067035c93259ba9daad2f229835f7c9ce8759109bd1db0e71b9d015c55ea94325cae586fb1b50f4792bc4c57569c83c26ba4cd7a809e799b5a45961ffa5387f91d9d653fe2cef5783312e12fb695a1b9d2004bf5d73819dfb406a7d3243613356b851370fa34bc32aec270984c77cb373cbf6c65d1774ef95539d4b4142d50f3cdfc9695e96cd1a0a3844ff8507ece66c2ea7bf27bdf020ea8fa95c6a7cd0dcf37a591f2cdf7a6d7a04de5a89583a094a53f68636bb57fc83968ceb47a53d37aa7099c76633e23b5eb1b828d2efa427fde9cfa24df7518886af10ed7734aa278bec197a60dd8279df60fd5012852167e9038ffd1388f6753af0b75800aec92ccdc0feb08684c28d51ad1ba8a14b33eb0a13ed08020f8416c9817a63dae74a2ad51bd9c9db0c187ba1df3deda995727ee0e8d78c9a3d70d2bbaf759fbde9226646a412500865e2391189e46a671f7a9b2281509c412e5ae2cd89ef17a42414fdaa90d12e39b07ed4744217e4a461a48aab8e427eb7cd1d07cae97886ca0f4b8d2c88c397c96436b0540aad3e6962c78914b3ad092b1a46cd1aea2cadf236c9d0d1e7669bb3035bf8354ccfe5ca70e7e6e6acea47396800a8407017d64c4199cf13155bdf44b06e01b92628836712d34e2ce4c8d635cdf1c3ce21b7a2ff1268c9ee9df0792b79d35e466242f25209bcda6f68f07d80db030e244c479c66cfe823220075e9c08c2f8406ef7a5600677f4a0673b0b5bac9d5e388dda323cf3e2d967cc0b3a705a456cd194c1833855af620952dfa2fd1f147d6a58ac35231377956e4b91ac100e3f9d8b966db4861ca45ccaccc6ea63b0d2d71d4367bfc0911e106ce7cd73f31887536754c880b54b5a6abcd3913c505c2145fbed44a23dd7b04280410cd648b59e7ae00b10099ce56a3d615f031f9091ff00c2248ce6cff217fac3158aef781b88603ce37e9aeb4efabafdd59f0a460859b1f1a1b4369043869a27cbde6a8914d1d3d88e440927af82083950eeb3bab126e9507c8baadc1fe98353f01022df09d8848142ccb7429a5b4a7669c1008d61ac50d6373b258f8afee8d830990853b9cd18b869544bff788f5cef93a9e3debae6afb138bce6ecdd9b071dffb5d629e0fc544bd909bb7bbeb3597d0a285e447eb49f7ddadb510dcad32807d3d0a571a731069e22aab4e730f50e295357813cd46ac3f34c4fe2d5029fc19a772f7e647cb18635fabe67f1588b18a7cd0ebcb6994cf4334316f6a538370887a0f009adf3348257fe9668b7d784ea64e8e9931fba22bf2f673b222196eb5df852ae2715b58cb9b737583c4b8c1003178093fc288736c246fa0357daa68e89150cf7876928b9525a264625991fc403b1b5edcf4f9a58a570925044c669a3f1960c06f35a21b826603086e7e889adae25db3eff02f990af85efb01e1bcfce2eb1520d2846c5de1ad3caa65c968dbcd8af5b925a13871f19524f1db6c914827c818d76b1e05df95ba322ed03061eab164cd501545d3b4ad2c4f9b5d7abe1dfd3d92a422a114ef56a4b2b47d31f5df38fa7e3853ba5b1c1e9e955dd4a294119c3c314fbe4ae14362a6522e34b7fd467d22aef1a31bc8bfda12025701df52ebe6fcc52c1fcfb8ff94d62d2a7b0f1b8db243391320e7fdcc0ec40576caedd0f327c5a0a950ddb2994fc389fa77e54f569217f4139b91e545432cb7ed0d11e1d27e9c4536a9012509d9043557051c01911393c592f36a4f162f131af522f978e940774aebc0b672fe88c590ea572f39dd5c87828d3d9d16e78b9433e54da904418c5ab6e8db7851f4807d4c93c60503ceecd837bc068aad6813206e382e84b6e64510f64f1346b9fad25c37d77be5292f1fd9d5463c640baa331ccd636e7485b752db11ebdebefab0cd9d8b9ae11f724439525661fbce8341badfc03ec2375536876a954a0c553e274027f9f53582bfb7d20520e1b8ea9322fe0abc9179711768bb2e78554eaa5b0be9023e6acd94f5eaa7b74a98adafcfac88fb21d810feb9f38dbc0c8cc006618c771c31fc82aeffd693497bbbcdfba2028cbc73e49ce074f425ca33585c891bde72455606aaa252ed42e2edc7ad7aefbd9ede2a51217f2c6e1ac300f6868cb8d0fb6bb5ebcdab839d4f63255b7079ad483a6fb383c4f0acb7128c500da9fcf7ce9e28068f265d3e266dfeca0e808c0cf8e98de0f61fe495eb160888df53bd872bdd9a7b8c89ba1a5517ae69c2b49753dce1fa1c215d6c1efca5d241cab5229ca657d28a57d34aa16c6fbd829b0aabb4099e472b922387022885de324ca45a8eb9245ad53923beec04f245e4fc6147895e7e0fcd457a3786db95174d8480701e2d659a2131d89ac98c627357851bf57dace645a1d00b3636c45374a5c2229b002a0ad8c9aa148fb6521fe35dc4ed09e3e0d5cc6bcda45925ef6f5df442f1ec4da7583f63bb2381fce6a7a9da4fb79d0ccaf2a4bdceb6cfe584a33b9cdfd6c9f3c4a8b71d4b3da17f174d6fb3b8c48a6a6f6cb78289f3f217bb377d7d210845e09ba7543fae4de9d397bc76b3a46bd7aa47a93a891775898cf4e865c5587746b353ddf1edbd0b6384512e558a9f346ceb265cc3c4d7d37ff83e6f60899f3768c495f49919ae6e80aeba85c4cd34b7d90d311f03a1f4356188df30d402031b916530e0e9da31b17ce87537f0b0b8d918fdabe536ae6bb6b903173f834921f5c998b39dc5cbb74a7ef677d72aa4cbe88a8823a8a0efc7de88713ea127c7e8fd10bfeff3e19334c7fecef45876f89a6800de74276920fcb6c248263b850b5c7a945e1a3a5129e774309c606f6585d037c15e5f824dab8fb74a9cfd49b659c98fb1c66c2484761cbed75343db437eab18ed7b56e5a3c0cc150ea98447c3b5c08c9f9d1801bd6b6ba15fc3be608aacb92c4abe8f3f506e75714b6876f5b2ec036a1456627e567c6e488cb6ace2cf54e42ddd41b6810bc93f83270b40fdbb79be84ce8e60cf527a1d04f89f22c4b936353015a8e05c23799cfbfc7fa58405c07ced8fc16d50004e364a6db3d3d11afec9f6f6037bb7061ae0b0f4f4ba3157728d24f819a3d12e237421a22c0efd8ae99651437bfa486c033e833e360935dd433a1d5aeafef73c71b5326b65d6df9994f988d00a03898d2354f58e3308b3c73b149c8a2b0165309d64ffe190a4bbf89a8633f30d674d73b1910811951b25aef8313e510cebc2f8e4a5c4286e2dd4db0dcb40b1745358f511c29645a0cae474954fbd907345b30203a32ed6848f10b5489f58914397046796e143bd412a2ea5feaa811e0a7ac8a756ce752d75eab8b6606d8d3da0900d621fb42b90e94e3aad05e0c42f9daed64af510f4846a4f66b1782d9d76dce9ac84fa2912808851c9bd23656465a64c5fa582e7bd1fed8c38e7200b601d0504f2578497be90818e69d1dae9a86fb5c2772e891d699f002bb4d579d3023df87651ec9dbb06ee3bd4a9ced0451a1c5e0a658712d704a92c2bf21527417278c8c105671e68b06aa838ead92c6a8566ee5912a18b995e9d1b6f9978fb6e378eb0924143da6fa15198686b8f5620b607e25e0540827f3454ca9dd085adc6e2c10763a20d6c70c5bfe0bb1d1b773bd267ce33a2b9c08a04a254d9c844475cc013c4276f947ceacad1c31976898d198c91e5ebf2623ba825e762665caedf1674775d15310972ddded3c75178dc3fb715d75ed071a292040223fcddf82a3e29af547a18633434534b15bc10334bd1c8504e210b104100c3a4e596573b2c8f11c304eb88ebebfcad0df1b2f5361676f899eddf0233b5d6f80828410172c36397f9495aff2001f4667a209394a585f607bb8e0000000000000000000000000000000090d131d242e333c""") ), new SigGenTestCase( TestUtils.hexDecode(""" -8411ECF640CB9A3AA61EA95BB60D5A31B099D67046A1A1953EDA3CC207F8009EB1C0CA1A40A71137B98854F470CB52EF825FC9D08CCAB2A406388DD22421DBA0A99CCACA95CE95F9E32BEA8AB715A39A8271B7789699217B8452188F4AA078C4F481339C532A2C2DE5535CC7665237D357BF547A7A051B0E1F47270231F00029A1B204049189CCB20923322024468D5C086052461120334D4A06461BA9518C148922933190A460D9B4852107929220310B31061A284AC2122894A2300A048D1A9609E444319000269886681244841397006312056118219424602142868AB86489C2218C302EE3C2611A366DC1405093304221A24409B1901C20821A8624A12800913430C816860B49614A44090AB84DD2B25100948CCB040442040911407108812909886C442082C22401CC2209E194484C263040082660422A03C08D12B90D91220220172820474981806020B27000018518C90C0A95051B224053A040233830123246C0908D990201C4426900954594A070E218112409251AC5908C2602830225D0487124B90D9C024689B08461146C62404D1B45440C886DA2080A9826895AA46980004E8A308E19032DD8C88511394549948101B225D330690B440C52862D12979048206A0C041163C808D8A60189B0691A858118882511158E0337108B200D82B229E184718304300B298A00A4610A1522091748D13006DA262560342E133461A2182A12B885502810989408C3941118A10D0A102A91162849906924348AD9C441A004010CA521E10610110968DAB28D08A801C4A24421C37122B570D394710BA700A1962194886D0A1802A2240C10900910A57020A86D6130918A04290B474020C6288490204B4648518420CAC404D186440A257010460282A6101A0166534804E1A04CC2423208C54148C07080160093B220083382584440D490648234868C04309244628120620A154198122803340520084AE4122D189349149565A4C8015B184299800502A330600486DC026C8A488184085103298188928DA2480D624065213371C0088699822CA332920402821244649A4260100131A34040C3B8291B130142801022C2200CB131142885E390858C24664834451CA231CB1408232506D0982DCA166A1A982950C26D128065C2306824174414496400B36CC9022A0C1704531225E32808C114021B18049C340D44488904302D4A242E1036325B34104B401044A8881080290AB16C1C9871C44606CCC81042268062248058B08024476189A43020C67093042C94986523496689C481A1446EA3866C5B46325236509BC28C23248622B39120228D13040E98B28519B02D1440681A230E03C92D521829003170D410441CB760C132490385305412058336021394911815204A106A6218259A883143064C839028D9B06C42482E4C286CE4C88018148D4B06514B8280DBC67001A8280A394908B86DC106451C0866C892091024521408621A27901200691249658B4852C1140E24488ED4446CE096715A347241800964884D53A4708A36890CB964244391082305098325A0000652965010054DC93671C1B0444338824C42914C16901A314101014212232A09882C9826300189440293312484281B8525A3468448141081A065043169811872910402A4364C5B348821354982209083C02123942943282043A8092437881B454D48880840122521004A93367012840D14A0055A188A43168601828C11352C04312A00046409054D1816300A0849A2B67124128410B545DA228DDA380E44B44C61002452A46CD406122484604B148480428EE14400DCB288C200915C141011334151980158084ED1887058B02904810544C84449B6881005310C132DD2145114008959282D63404204042A84160D9C1245481091A4482D9A1032E1883101302E14120409B25109B084E486600B4429D4A88003932CD822001CA721DC8680921849D80242021844204601CB2090C43428C314500B18090B9061424426CB288DCCB845839431C010304124319C304ED4C82CE3440E24427201230D23C80524216C8CA48D528669C2060808140A0098201B13684218655C381004C31121B5715B242EA216698B1040530490030441A4164DCB483049286860200DC84412030324CA060D242202DC3082132511119411DA36905224468C286421C3505324859A462A13C72C403272DC9260508240D20624E833A3104705DC227A3AD315484B9EC824A82F500712D61D5693BEB0E024505429B4D136758D53F67E6A5C66C247B3D03D763B77C17CA1632E2B0FEA3CBAD528695E70753FB16A0727C6031DA837CE9D9F7AE12A7F091E8E246CFAE2955424255667155384E6BE2A03689BFCA5E1C58C7F16187AFADB4CE28E2F9432F2419173A4CCB0154D7F3443A15DA2687E608C02D6392EE3942159C2996700070C00A194D27BCB61945E04A94E95F60709E59DD49CE955044CADEDA9EE37FC28ED3F3EF89FB5F03B77C6EFE685706B85A1ED1E810195507A55023A2D1CF2A0A9E78801DE90E1C7B80133B0A7AA8E17C022B574B3D9503EC2E152A4C04564C9CD4F84B8B8342359EDC28A7578F5AA73F5A480DAF80F9831E3A1C102BFE8DCCDC4621AE89409FCF986B53DF21425C9CE4C9744B65F706AD99B975E9907F2C8B5228E072241CC1C25111F5455FDCDE4D72A28402C2DBE6D730F588387E7265DF3E8B3B6C78E0AC3A5A2839F1E2E021843BD0BFF9C71C47A0BB0DE3AEB0E99845821B10949EA2C72447C64BFAA143220156FB54C9A62F6EAD3D534CA9568457277AB8EBA9E8EE5F3F42849C8E661AF178461663FFBE17F78D41C830F3342EF799F97C6B0E848A96C4606F4B404C382F5CE9B36E3CE90361C4E8A7665736E0C5ABD625BC4E1D1F3FAF90A366E3D3D9606C8FDBFDEE49DF2CED8FA268E6CA4CE20E3F4C962CF85E37BCA06F6385072280E5F5533711B2E676946813083FEC5D6E2CDCE4F4DA6F58A6BAA13FB159C6D8F33B6FA8ECDC0E792F72F64766027DE385C3060F38466BD93C8ED981CD3F7EF7B81FB78D76E6BBFDD565DCE1B018372102D0BB8537C1E60B1BBB564D6D98E45108D45139C71A96AC788CA14F08837E200DC1F593A19337E518C18E40C4382ABCB486677804D44B31DAE664959D908C4611ECD2F657D46B72F009AFE3501AD50BC49AB94EA2CB36A07FBFE8E87D5337841BA123FD8AA72CC9A4AFF0235F4EC2B08796DB4878A9F3939834C324E4E0D37A9C5C59153811F21AB57B260E9E57441298EE7032C819DCC475236ADC4EBFC1C5B26778B7156C3D37667C8EBEA75477F3FAC495FFFE7651627C6C87EC7CDCB60A3692EF2AC72A8820225DA85A5161B4C7274DB3698F5F1A92E197F99689B8FF5970DAD8776550038EF55825E4E0C00CC148DAEFDE552BE9BE94C351069153A3148B30C1FD9E9FB6E962A9A8824A1FFF238395B61C422CF56013BEF428638F961BCA565E5F4BBED2831769EABDC0BB3F5729BA331CAF666DBCB7AA15463A4D0CBCB26132F598789C96314F5B51F34B9A0F48DE75DDA95E2D294589EF30D43E7C44CFA63865123DD3ED045038A8ED261007374D096A46758138B7E112A58482BC3F7B14A83B7CE7B5C219B8A16ABA3514E779DAD6BF06A3B530E6C2A2E5C81D1C6152A63AE3D1159F4BEEAF8D57F6670CB15091CA10200D7A76364D1A48582DF316B7C65FD0816096FE238360B291772F8EDDC6380465261108B53F3C7EEE33C5950C76A87ECC41E86432AC231966DAB8A0C1FF9FE593F98FE34625901CFDF163E113730232E98F00FBBFC068028CAA132F071A828BCFE78F52713DF0F7EF903D5EE10F272CA06EF94BB1AACEEE6A9B89D459B48A5D580B085E844AE3DD20B866796492B526FAC2028DECC362A7FF42CDF73A827E2EBC3712A15DDAE09EB26E57CE61211A7E108B8C588EDAAAA165C2AD916EE80162024A29B6546AC6CA73FA09EC898E93FC399ABFF13DE4E4DD22227105E207DB1C50855079FD96383B3BD50C32C3D1E37B8BDE972683453C3F9632749A84A93CB34CC130070E51FC0D00CF504D9FEB9A8F068D4A1D7AC648C8AE47DC54824A69506189861E6838A0B08E13A13FDEC95F9148F2610084E4BD56BAA4E30B39862F86CA9600B9A3A945A7499F391879390419782D2934D45636013AF6B23A7E072B393E6F4E62140146AB55C9766B872050E085C152C79DFFE2240CAAE43FECE88B4C44791ABAC91635CD3BF47981B65215F36AFC2ED63F6A9F56AF736C2A0651A6C9208C3720C8D5F48A0B42C7ADC7F6161DEE6EB2AF5270612932F7ED33E2EDDDC61C4F3B291D42FD90D2F28B64D26863B07E5A2C445167C7EA3CA8E9D07FF0D44795903416110051D4DD9C481124A99ED2DBEA7F59C714AF50A15F6FE518277A3C9B17D71B4265BFD2ABE06FEE2E27109BE2E53D1D5C9D287B383FE32500148C5158CBC6932F6684B07FA33E122D1406A1E313C0F5A9901E82CE5224E31CCD04D31058B4BF53D2E15322C0C8EC177C6D15A250FBD3474EB9D255F548253505C979E65E671A6B7D1A60876254314F1329BFAA0E5E8BC8882F6BAA9D5442C38E0A5C15C2A61F92D2063385827CF052553A352922F9CB6C035D1CC5E15E2625FAAA6FFA2E4954F31CA10B18A3ACE08C122F826CB33F9D6995C12CEA96766CAFAE5F32A381958EDED4904C12EF43D66BFC7B08CE8FD61D42FA3F6F91ED1453AFFF2819559A385B932C484530D33BCB406BB87BAC9EB3F338D77B506CE59C6CD59CEA376ADE92B9D2587D8987FAEA9F0C707900BD649C5B81E0D46C17D467928A2CB9C53AAF0C55CF27FA09673BC6A6A031402126A163C4EDA10AFA09477F8ABECC81A49334B14CCFDE2FE4759EE15FF7D7D0D60111269ACA4ED68FAB56DE7B6F10CFE2C7A0E6DC968C8F90444D535AA34C1DCEA03C84F1DDC7C392868EB07289C4DE14CD53D5C7A1B768B312F6E238E2FA6B93BBF14FF286DA3DCF9CF95583917AADC02DDAE785299907BBCB06D559A04FE1DBCC75FEDAB0E42231F6225C9C5761E4F7603F87DDCA8AF1CA9424D36324659E2D249D7A83FC187B41434CB7FDB08F7AAD100DD2D29E66CF8188EFD1B3ACDE47B281BE8974C255FDA49CBD06E55596CF3E387430FC67F8FCC4B82101CFC11184B3E16E62F18A4355AC5C6F84BEFF3AFC12075B3BA48ADDA38CD6FBC04346EEA24AC60F2B527AE8F3B61EC32EDF64D273322326C2BDFD441BA40ED87852A0E8FD197A7E7E05117AAA639692C35CA5AC4DF9B590DABB9806122B31047AA33B30BA68CB405E539CF9927B6F942465DADB9F4F70218FA95565E2290FFCE4D77D122C1148E0AFACF3C1CF89AAF85DB4F06C48566166AAD370EFA52A95FDB52BF5E55FCF577D43B0C2C5DFCEBEE16BD4A0A426E84AB1FB018B6D701EF4981DE257E2D1096E206435DB0E52DDEC81CA2F8E16DEF12D411329A1B0CC3C3E5474F452D20C2EBE9B219DA00CA07B8FE5A14E56E8DA3EFEB1539EA9F2ED9C7474DB12B93C744322746AE42D777F22E1435D5B9C867F29C2BE6316A0941BAA39BCCAB41C9A7B5FB4C918F6BFA1FA76FF242A2514AB5E4A7B8D65CF15BD4336D151BB374D7906DBD3A187D02C4BDC33BF26448085F7D66ACED1BD6E8E67F4B3DA551CC68A4C493AE35AF18F7DB09133EC0692AB08D6DF34F1FBE23491467B5457BD831BE4F76830774BCA5131CD539F47FBC5E6F041B01EFB6A7E586A02742D50AFE17986A3AD7B20524F9C1D2825BEECC5A2AA757A299C46F852D46834EC67AA048832BB46D76C7D752150854B8689A5D0A501D419E5269E34C13464F37FEF2613BA45EAEF5083F7F699213121456E5AAD50722E8965B78843280DBD07CE3267912BA2FC59AED7540CB9C6B464B1F983892C34C1E2149ED712F8A56B2C6AEF7996D45A4AA3A6EA833D5DC471BF3E9A47E83572EBDAFA3D3DA7D930A05501F0C9B6EEE0FBC9CDF86190C52851AC7961C36688F8BC11A39251ED1E2F1528F98FA360CAFF6C1F2DEEBD712DC1EE31A4B5BC819AE169338E4DE7BAA00224CE4F460E25D2586BE63AF29705D98705840930E64EA0A9D7FFFFABA09869D78A0E3866A137A412AF4FD5A5E671B735FF456C79E24BEE529DC0706C065E0C6D8BE32535DBA578F36630E6C3EBC3C69B6FAB135A530B4281D40CEFF4FAFA364CA274CCFFE3F8D16DCC2AA7835C7F7E7A376E16ADFB940A2725B64EC782FC5F0C36E5F990807DB90E6D1C6869D6406A07CFC0B84A2A3C1A4E1585D854BDC2B506EC8427940299A9B19B2FE3116FD4A0BDEDE83EF42741262E7A9CF4393C2DD8A7E60297CB76157C861ADE284D44E73447186AC00B064B5E02568716565648CA88623E16EBB81C00D4377FDDE04259AD5CDB9C8FF75C4C8AC2D4F96485FBD353130548637235D100A646FADD5341927CCD114CD6095E97C622F02AADF7FB634879DD0614EF0ED2BECDB5A15F2B05100D97BFB128407FD8D54A6FB35DAF2B206DCB2634C2B14B33A96F7DEBC9925052B075340F48A096BCEB99E4A0DD1F9A35E8CC14EC724AC3ED3EB512E1CCFBDE1D755B1B3A3F63A66573946052022A89838A61DDC0D4E2A34F3C2067BC51AC14DB95DA6EB7C31505C7872620DB5C1B623A92C91B895A65EAE4938D3F823DF37FEF1964A71DFA1F6EE034F7C07772835CBB43465AFB6EF5BCAC326FADF26F762DEBE12432EDC8E53390EA89334E9BE32E535C5077D6E77684A1F51B1BE2F28BA4DFC42FDD63E88296262CF0C66220DB4A88169CA24B4F8F1135A50F9696C0ACBF3C2D3B345010E43230DD4F3044B2C39B91A242505EE5B2F690972FEA4526A3F473839763021A620830384645B9BBA9947BA6BAB37A1727DD94BA14AA9EF039023BBB46DE81337011DCC78B8BA6F9BF3F92EDBDF55B0F9C7B0942E397EEE1EC85719C4"""), +a163f0cce9b86d8807e6ed09b486e1aa12807f2370f2cb6d886eb2ba3978ee8462f903c8c43e7c35ab95413dc49c9cf6598e255ac8a4226e38764e3ef4cd04fd408ef017e7b8d3f418422c71e12a228cf65ecff31d2ac2334c9848425f63c9594b6644a26861997faf2b82aaef2a804d3c9114b4c64db479c8041cdee8c8fe1d63164c081221923408db142684084183062212076148c2906082898a1410d0b62d61104180488da3800501004080c648d9844d63466d0999111c440493448ec82482523068901862222686a2368a1c424840800459b82d9b448dc8a68004c12092a88c4a3869c202715c324d2415646404109208050cb26cc11062011689dbc4459ac0901ba8494328080a10619a462654026910432e4c8660d2300543c6459b127123490419285084882104b74523279114b9098120305a8484e22464994262c8c00de2a28564c4680b0251501691a0224054402c12a689248321c216610ab95013b285da306922482c19c90d10c6918a46818a260000986809c10014b9710cb368c812081a285019808410102050328d8092081132520b033211a32918156e042629a0a011cb124a1922801a042419154591384424230411346288a66de4141150328c09c6205bb2290446089a945143042e1bc18ddc828d48c04512039253986820182a82102243464589a444123402213162a03264a4b2718aa40181900dd1869014930010c865140570103544d2a44983462123b605d1440e0b36281816329c2850a3084221a56d1b148249908c8c0889cb444213310e0ca16da18890800202d31404c926501a14429a0671cb4685501488d30412090865c2c6440b3622dc022648305281986dc8a4880b286a50348a0ab7451ac969201726122588101384102061a0120521a1880b410082048a5c042e233984db224ae3060c20877012a0210042718c888d889449890620614064e148480495811a2132492801a1402c09b03102811192122491c22950188813174a11a06122a601042492883668d1024204236482246a0b07869440051b3862d88090500209a4243281b440a2420940b291883232c29805c93086a028694a40204a008540362dca44450a207224c58cc4204cd18240d1a6609934220c35820a2405128251db220903438ce4122a02912c14186d62184c82069241062a43388500b48899168624a784241349882870d4181143c6258aa284e2366a024261c8c26088b66d5a844d931246c84449a326108c484c219928e4b84540b04d9b020919908102142d424040c2848d0cc41192b84dc94824c30846430664d9342e203849cc2050c0202d08940d5c369263b02009b551828440642665542264c20411631401c2422611974959340c9cc4704a246619066510113249284ce4c884048945c42021d9b660d21069c9a64c5aa62c5ac0840c346e18104500289124822821442c91486ddc34649c9610d902440b142149444c12c10c881408c9244a1c034d53062112166024185063c288d382054b004188a6680b176ad9382823100d93186a49082ccac028234328d91262e2400583460dc43071a33620108421d2c891a4466c0986049b1280180511e48031c400320b9849141688818400c3c62c1b462641080901050003428090882d9086642016411820699b2225cbb2504b028084882c639605db2028188540013282e046608b2291219605409884a1880419086110055110264e00308d20a74d0c884c033080030825a2087208284d18324a1a96850c80710447484ca86994406da3843189228101405143226d9aa84c02b364c9986418062921320d204861d2987023138c43a8244b82908246205396910a380ed0a02411996822b7718b368d0a806902c67144a02912350282b4040a91314b2404182228199640a2426e904809020160083041092352643621d1064504b70114b04d4b424902086ad0b4305a00311b438458b80552142e1c2301229684989625501602e0242e014162149440633829a4b64c01354aa4106a0413111b854050969101132214b88520810d21856913202c8494010a3812482842c3142684162581927151c8051a9008d8442c01186e13034423b73050843091344d5bc65122a700820222112720141404c31864c3180483962c222132dc848c04a76819164c41228a4316518b840000b0705b424920b5815036108286941d2c20b22a5d79c004deb5dc374c0bdb539556c4b634d40da50855be06d8d36b11059aa84db6ae3f4d1c2167d07081a11a7f53a15c35494cf79319c17d6d9299cd94bdf976b0c944cfcce53d853bf421e2384c1b613d49da392012b100c05a190450877f0721f5cf930a81736eaa2098ffaba84c274b2a3e8abb8b5091342963674d95c46911db81fed0db546c97252415bc8e4d180749bec73dbc34f819dec3544b0b64e44070c225a6171342a7f3d9c35c4a2cf01f6f4a46fbdcaae316e9b946093058b7217f5da366c6ee69db19168bcb2f485370e0e80ad094d81c2061bda7362473c99e26dd4b7213c58e8a66bf6378aef003d90e0f74999fe0ed315f61318e2f09cfa31c3b77962cd3a98e65c1a39d703849d719ce1085c99e0df37d215227da4c2987d63cbe5cab98b1bffe0c6f0c6402fd44b27586ca19a4cc594fd9f3faa1e0aa8fec1b790cf8ed6cca095c457ebd57d0a89071b8371b7a6f65ed35f6e90b51731c09c5ee8760fce61b81cb37e7f82fb8ea45682d065aa6fbd17eb7f119a8bc3342cef4b9afcd225437b8bd9110dfa7a5ceeda7657f651211c09cd314ea63f3c8ef8624429fc4caeb94cde59ac6f63528d4990af5c4d6238aeba9b933aefc6911cbaa5c352fc2e0a31771b8479462ef3011865da42521da4f28b5cd3b564c52d5110382199f149af1d0968ef6d009ac528eded9b75f05e1c1fab84793cc5fb8eb734e8f25ca337676b8ecdaefc7f828a41a71691f701cdfd4b0c24d19b9a8a2ac7195af559e0b19a18e25a4f369e442a7104169473a7eece2b82cf061a45dd73b6857faa70d98739369e64ced1abbc600f63074b6270ea2025abd90844f4aaa226c92871a6e47a2ade36f700b5c56e1899f27076eb37406a39f4c5fcc8253e9777f84f847211f6a665fbfb7659fe160287342074b9de16542c1d1cea4fb6f2e8e53e7a097b384a4281e48dccf3a9c34ca5a18bcdd67f046b703b144ab3f95a18498da217fb0fbe38c429a04d92032dc5d1f70559198604a1ab55986d5736f36c9e6a5e0afc487bed3fea09d580ed55f3ae240f4c914ebecdd866e839401da3450547da22b3706a626570d2cb13fa68c7f248b635aa6a87b819b2c56f3ef34f2f8cb786e3d7a07d53cdc3396611961c289b52c4fb7b1b3802d0efcb20bffad9c11b3015a23f8145015b2905f83435e9570a123bc37e8298ea12f1e23c4ff4f4eb9f07bd3e1fb6b33233656ca4745086af7578cbe377e87eb8265e80b12eac8c142230d040a373f58d758626e3d7db31f40c81c974e82f806f81d320539d1c26c22dcef85e143cbc22f0ddec442464e1d5b68fcf18b32b8980ddad469fbaa75c9f57f51c7ec36f7f641a3dffa45477e28ac254b414030e8efb55984d94d747cbd8c6f5613e814449c5c41d1b816dde3fc0a8f298aaefd6c3f26eb1406d57d8b644461bcc7f108fcee5ecad8c0e554a5178d68bba842e1042648e76f5ba7e70d44acdf6c1ed0e993552ec8b83dd0885e3a747500eb5a23bd9577c418b2fd572becd5af7b6cff842b38936f8350db784b34e601f9a548be49bb79a700f858bc1b8f06bc50c288e81df024aa93337e0f0dc1316b23779a84a3443b47985c118792950b1161d4c498317b6a84b339462c3b01b504fe093063771171027c37c5501f78d01a291a3d4c3bfe2b8a4e375c5586b2d25650f54305bb00fb9e950c2f18fefa95ce61aa70eb9657ce6e003f679e274035a2c61c8f2e9f33cbaaa86f5aa619c35e3398babd960d4fcc0c8513deab5860be248bf171080187ed76a420417223544475c8941e9b040baa988e1a9a327130eb281d1a7c06bb9eb5de26b166a3eaae1c226dcf781cc86c717ef334d74ec79de525bd97eb9f9558c652b758c38b4fcaf1ba0c3d15f9d3da495dedae25b8e9e059ae4c347238b9ba355ad4fd5bae85b85cd47d0a67e13f986700b1e5ca919350364a2d8c72f97be3b0493d02a0266c1fe806d520da5753585abb0f3d39ef5d464042d39119de9a7f3ffef132611e47b69e6c1250b8214a40c8b701e2bd5bde16651b550ef0e75a13598a47d2a33be3ead32394d88c3d799785fc70dfbea2dc42e5e77534250410558d3a8f5592164e78accfabe2e040967c21d3d8d30490133d4a9d3981df7c0777f49fa8671e449ce5dc445c2def7d7c2704067d28e5d85b5d39ddfcdbe6abfa4b19e7f7582863b2e636b0c9451dceb0b959ed38c8f85571e567278cb872abf78ce645769308b2df27d13533912c969757a1e540f90dd3f6c9a5e768cbf2dcb6ae6eeb4d7fc0a82e8db38f4b8283f0649fd00d1891b28c79f0df11d749bebb6fa0b1c084286a2c74add86d82b1513237e134dc1b44b2a12323d84a11799dd980c87e18a54f223c476527345b55b8fab4485fb5522a98ef8c8f3e5339670e836c8d54631f741fc4b3d4cc30d646a4983c45d5b3bfa09bbc87e5b3c22a0332886ebeba1453b4c002b1b8be06a8be16be13b440eae017cb90a61bab9e3d3dfcdf5a0836e47669832d827b88881c99c1b1ecf8085344522a4fdb5ca7c3393e7df89ac3c89f3b9757cd476fe15af14341c2bccf47014cfcdc42a5b72222f466ca2b324a7c3b2c9ce0c1abe933ee39159e3f4b502ebde7c1dbded5077cbd69f66e3d23d358e0b207150526f42ff0862058d928ca604db982f4e41092bed105f7d288617d55bae32e96c44f50c9955af0247eb3844269f95834e28d4e0a37ef5b03b79455c0ae660e32941ac675cc8d7e2e036353cf615b45be3fd0029121f72c68280f5353d1286bf10cc0cd378db30e7f8c0bd0fbde1cfdee548ec7faa55251f07d8551432cf572569836baeca30db5bd194be89160f449857799ae7e765a99bb8e468127f65c7e9a1f7de9cb961bec1026455f503ce5d199dd07a6012d74efd44403fcfb246eee1fc6f2945867f37507feff0b641eba4e94c532a4bce063503add362874523d88cf1502ec6b1f7b64fd267e754018152275f3465acdac0c94ce28ee844d93dca47686675deaa3e0492870d3c7e2c5271f843a7c29b952d0536ca961ee0d69a2a4fe5a23f672e5aa920112cac08b771078348197d381ccb4d2b9c2001fd3bf042a44bf8de877ef7c0ebea6933f23657cedc368f9a51ea8c1e33f4b52850162bab8ed40d6e01e0ce3258cc28504f1a594aba83969230a3e4655f85756b4d835867d7cd6c0b73794fc894bdb0e77d4397cf46bd81050fba18ff6f168b7cf09435243fc635727bd5f600e45cc157c7ac9a328861bf8e9c49cba350147e1b861948800300710abd5ab3af61f1303bc46243656a64f4ecb655be8614b5e4d6ac5da50472a3661891eabb731524a31b646e6998317ec4e46f62c3c946a610905cbd83926c907be48a15d7f5614b0f7730aed5cba25a684c3178caf93fed05baab1107f0512f63f9636fb001026bd2e7eda3cc1dc31a7eec5c5d14e206bfa68e1ce5fcc956a65f98878e09e5304b481d2db018873dee5aa6d2855e596c8e8c388c64fd7ee42435894c5bf62e7c05f554d471b8fd10184d7cf2b4a8abe84942915b3eefdbb38bba5a92b2a5495bdb612c31770e5ae46c745e609263dade6a873346577f9c3a70a1813f57e35ae2fc248d563229ab03b81f3ff5e4b0c93ad944851e99daf551e2c1f685a0d034b198a7a89d75c05399443c5c46f1c1158da88132a1f116b387eaec5bc7d6e5bc55657a7dcb7312129e1f2f78173771e58349501b63c7f9e5a41b51cfb10765190a3c0d328fa7a205dc7fecd8544cc14fa1a0f26bbd12560710369ca3fc995b4524393d700e42203f3c33731cfc71a77a22e197cb595a6e2a3d197fd299a2bbb32fadb8b694df8bf11510764b9ab7df1e1a3c398de2b49683b84cfe0ed9e615d8ff07b55762c495bbb784af37f737762b952eac37d9d894861b33c9ae075d0c1e8e8d9d85e4f1d99247727edb6c31a0202ab85be0a3bc550d59d699961fee34d2fef1c975256366f99429a60dc411eab31ea5d531769241d4241a7e482899745a3910ed84baa3e58d1e0ccc311eac6ac45a5d96034fbb4589ddc4035b8911472bc579473d9091b15fad1b5112887b32e8d2287f82d2c6fe6a2d37931244cc25d33fba2e3e00b47f5c8d5ae2aa53535183b72147c65e0dc4052c6a38466b777aaf404a6c8a5522427afda01b4d7140c9f7f057b47491af06a557b9b4443ed9c4625d4c817d7a128c97289349f9cdf14371f7bf933c4654f0968df4f5dc0cceced0f305a5efc0d8778977a9e549d09a6efeb3034aca5d5f1d1f04170c8da622826ce9fde2b05e1063cfe1b0063af1bde69034dfdc7c1a912972a35b4b3def486ff1546fca7193ecaa8c9aaf1355368e9c143f59674211fa7cbbc64ee2a7a51ca3c3e9d8035e0ff0c5889453777538066e6d122fee1d332f6a41ba0130400c531952f23256f5443d75d718355d1497bc522f5b0b671185ed21b4dd6bbf7e91c27a0384a4d7216ab6a29675cf07de1c67eebdf31b491251591960d28570f00abe45353c26c61ebd9cc30036f4297d9a1cbc4c45a8f71f0a860179270beb3707bcff3ed7d86a7713b9e4a1259cf4f351dad881d1a40f897d661c32721ab409fd87ef2144c2bf03b763267d137224d11ccc9c5b94fbc4118732d1df1c1a5729ba934a5e9181f5c6778f33a7a72ab931647c40d8f788ddd3259"""), TestUtils.hexDecode(""" 506462786389055DE2E4AA2A7C80388315711A7B5DCC73F2039DB99380D48D9A3DD8CC8B929B0AB224DAE74EA90808C302197EE9D847261DEFF4136D3B2A37CA32533384443B9D935AF2C384EA63E7160BF4BEB89EC0EE705D10C72F2F65A4E75ED2B1901F14B8C1D21DA9C6B8842DB62443D3DF12969CE4E45298FCFD6FB103B87B0817190C5ADED4D04E3BA4D2C3F60CC49FE0695D6366EACB9C79F28C9121584D997B7A3A7AC3243C3C75FC86AF81CC8B888E90095051F7825294CF7E1A11464BC153548F8195522FEAB9AF5AE93C5F6CF80D9ED76C19A0ED0BFBCFCDF30FF6EBD0E5C20EEEC4992765FD23F13F027E2261C38D11FD1631846142541ABCB82C0EABEE5D675EC130861F9BEE9D9E02305F168C85201DA1DA2E4D21CF1E4BB8C2539BC1F3706194AEE7E3ABB2D7447EA531619FD27F0CC7D09E5FBFFB0DA81432D173321C433391FEE90B92E8EE3F39ED492E78327D8A3586B7052602607EBA79CC9AF21132C7D3A9931D5DB4937FD5C5611F79C722E0CDC48564E416DD251C46C02567C4059A0DC2F59A124A4EBAEB9B1B04277CC47A9F345FF8AC3F8AC844A668AC6F7E1BF1C9889C3E42C1142CBC31A46EDE21CC84F230A483B5CE23A901375B27770BEC8F0AFA25F301B7AB43B714C6D0E98B009FCDDFB75C0E26EBEF7C9DF5ED04CB4183028DFADFC09963AA8CB3A9A1BDA047F62460F2B88FEE1C05D9E68D646137F660B68470308225FFC097474B2B2BC5D50A025724FB2CF70873BE7D04C05AFBF1D7DED56693AA4A4E495B1FAF9762DB83DDA6E75F530ED5351D171B7BD06E5ADF46DEAD06AEA37CF262AA33D062141F8E394E731B3942D084E583090F9CADF87C2B81C4B7F114D150C221A12393BAB92727B828C9EB86600B969E1B80F33E1304CEC68A1B3B474762175EA19A4D67220004FD4EB0B2C643B69C00FF3876E9AF63BBEF8AB6BBBE247668DA8F2E3CFD0B95D6926AA3A2CFF4587C45DA60BDB03DA78DDD9758FCF9926FA1F080A61FC0FC7660BDE9B4913C40534887B04E2DC666E981AEEE38746C52BF46FCE0E2233CE02C9307262499BE567C150CC54FB9D96B81D3A3E200EC8F7E87E28272E7B956600DD7692799473A8C63AEDBC8F3F43542B9E399398349B896BBA16E5F26210558DDFFB984FC924E1B0D272CB8834B1FF641A894EC113460C65C66BAE86248B48F675F1313EA76EB4DD0AB6EE41014FD7589D1A7DAB16CB8F113A3FBE7E01EC67B0B3CCD81C0A8C7E9824658C926736A574E9A0729C3BFCC34E0D4BCB1606E93287494577A6C4B1090FA6B997DA098C6CF555B5574473B1063B739CCD139C2541CC3F962EC42BFB3A40F4E64D322836EADA5F574B48B5722D7809A3A20EF1FDF5F3EBC000E466BC4CA10E0CC6A1390FDF159BCF0182293D9C408A8570789C485DBB977642074C869960E9648641C2A80D8A1C4E474FB98D7A3DD75D7AF01D2605945E89493699EB53E30EBB0F936B63ADF5859D9EA1DCAC44D0BCDBF2A069982BE907F1B560AD8327BAE013FBFE6E2709C9FDD498491F1D8603F9F6C9B1A643F6FAB97DCA752D9BDA1DD6BDBF52B03ED7768D98E46092D556C266E30C77A10E68AF76AC3D359D8752E2453B2E75DFECE6F66E6AB00EF37DA6E6A367FC808E1F4905339F4FA73545D13DA7E7DE49CC0A2A63639A96EA039C4EB643627B7EC4FACA1374EA800A505A80F554B3AB3233FA492ED6C17B5832BDEFB3A99FF1C64B35F1531A023415290124EEE2C9A7E34FE8563528B6A4B64DE425A8FFA91B753973CF0C96FB2A8A3F71D58B77C93C5866DF5CB5152B3A0A32884E349C63870E9CACA82F121EC2ACAD7B6052B0D74E9C28B20C76A7A821D192E11B59A7C8059FC49662C655551A7356046D46FCCCEB4DE1F5FC91F35B950F630D743C8218A10AB25D2FAC25308225540FC24CA794EF171DAD7258C2B7FCF43297F6E77A6E83184114DBDBE408EB644ECF49E04FD79769E4FE9B0530F21F8E3913A51094D0E49DF012144EFEC415B8B2A34AE2462607E7B89BB86F0C733A5553CAAFF9B19E0799A1901657BF4FF5AD6DA7886B477358E90D56BEAC6A963E0669C38EF47173503B0E9255AF1F153E673813053A899418E2BF217D01D9162C073F256CEDB73DC062D201FF6056180A8A6887B286AD6D3BD6B1462231D6223D0DF2BBB7299FA6FEFAA9A297C56ACA28E163533406141EB2E65F0C94A6286A0579C76A3A8EF96DDDAC9DC6A550538AD345FC4AABEBAC04682D4AB0977D439CB14F02FB504E10252C1F3ED01A7C4BFDA6E689D842D9B9086517A84AA4257D1C8CB842E15DFA615D2E3F2464E4012C0067EEE60489C044F43050E5B1AB3E54507422E1368CB3EC8CFB03A887DDF9695AD95378F875F14F7DEECFA54A775C60C6B7025E5D6C0563E0E76C05C93E33C3E5AB6D1E1C051B52D2805D3BE0A4D3E8F0DCE6BBA1DF04C7F76F7E13D8C3CFCB2AB04A1E605D4DAD72A43D5223FCC36EFB34D999095E742FB9DD7B69A28E070FD28138B403DF1DCA75E00A160ECE9562C92091DFD3A24C53645DED8E17B39D8CCA4C20C96F9C9F9D14AD3B45A1E87DA75B831D400AC14BF34A9840936C3277A135BC0E8C65E0F5E670AC912FA586FBB4E149B09F64D338C8C886BA65730039B5DCD0DCAD9D6EF11C228213438A1489F4FDC39395E8447212599BEB570D186883E02B442F8BF97884EF98D3D6E59254B3DDB77DEB8429D110F0689715F3E0A4F65908E5EEC867AC7BBF27CFB965727AF0A1EF37B21EC18CD60A1C87287527BCBF5249596083069315699CAD10FFEB2D87810C4DA090074FB26978E56B7D06186C48BFA4830A0BFCEF8FC7B95E73F64EFF78043E8D93F57EF6DC636C8FF612ED22FB21174EDAA59BCF89D1A60F0E1C15C5F8EB8E6A39139D500E8F28A5DB86C125C6C76A99BC47DAF66E679121557D85F5093806B748B3EA65CAC386B59C0A372AF2FB7C84111F0E0FA2C71E137958239534C4A012B1B421435B7BB8CA577DCD8C8B0A798902BAC9B95AB87B6A0735D1839DEE336996C2357C748F4EDAD858C81E2115595ADBC173782E36D4E720A5D29A5681231F9BEE91D455554A8632F7F02FAFAC0FD9D03804B10DDF4828A69AC1CF0581D2C88877BA30EF2982E0827147766F8B71E264E82C3949BB87562F810DE835CCF78A7E5FAB219E64B1FC615E7C952577B9B482F78C0D0C512833994895A125F43EFF066CEE293004E9E0E5288A61EF209EC52233EC64BC0DE76C78EB2678559724FBC05BB5B43CDBE86F6C481AF3BDA11EBFC0FB384AE00F4ABC212B0518644638F01C38030DD05FB06A7EDC6406CA18878DF38ACE8E974123D3699613ED46673BD04ED51C352F124A8F89DF8C13D2B44245084B7FA02677D5287D22102AEF4A4A0AE046BB1C6D9FC9733AE5066C69A10589B0F33780622C1709F179D4E8857564804BF5C4D83E03484FDBD1CC4D71C6A2421AA59043DA85F0B51EF91FA5DF9555072278331BF3102F5147021662D135F3011FA48DDA7C97087F01B7F86D549F41E244AD7374C7C1F698801CEAD305026D17666435217799A4A5FD0ADDF9B8BF6E31E51B654E4D697554D5F574213CF579EFB1B11CB2C136FDB9EBC0DE4D16DC9DF43E17D88EE22EC88326F65875439066CB47E4C656A3AC59BD9A576D05ECAC5B3E7AB7B1A3C0C1C48807C06F1AE4881158D6BAE9620B08BBFFCB9940B6A6D04396014CFD54E93D863156D16F6F9C1556DB1E13E630326C8B681CAAD146F32B6977200B204B632F6CBCFB2BCE9670D89A9CE043E2004773913188608455FA715D1577E03826A2471EF0143DB3C39E03D890F0CBC85040D1675821D282822F80EAAEFF5CAA49699B68B89422D1BEDBC3041AE2A3D6D5205C72123991B21AFFB312F5EC8F96922EBB44D7A0F8ACC2E390F9E3FD82353276D73E85FEC904AE6319B140E5C54FD5B6F19D17E65DAC5EE270DB3E402534B0F408BB3C554D93BBD32B255D478F33BEDF4A192233294B320393D38284D7D9987708C019742F2FC023C041219FBFE2B603501629BDABB9C4223F5B751DB78C144CC50D3A35370EE563D6DDECFD6D715F08E14A00FC265D8433055083048396F1BD4E9F010EFB974D6102401B2FECD972C26008A4B94952EBC61C35DC846FF7B3E20DD9C6E033BF1185F35A5F02139068E1D4F30C4778FF87057F34CE1D2D40BB61423EC055BB57B56C502DB8D0685B0ADA42F9C52B590610CE2F8237F92B71B3AC2AB75D2E6ABBDBAA1E554D99CDB687B72DE98ED0FCD618AF5D2B0196F1D3C19DB77686F01228C3D1DAB1F171A56DF9311939CCED0F7B22A1B77F473E8DB65C0FD6E307B6F7A0F0FAD69E5C1F87D01EA4699F4D5DE39880CF2D8E910313AA6026C17941C41252C06687A085903A502048726AE8EDDD2D8918B71A19B807889B6C2E866FB818810F427D2A7B6CB137D94746A88BBF068EAD31216A5511A54D81031D36C8139776E0FE29EF7C8A5EAA730C3BBF05988BB892F699F72F098F2931F9B4DA17243404F64C311767A98547284063D44AE74735DD246B0C189DB322058198F1D176EAE6E076965CDE68DD0DF2B284D23B94BADAFB8650F21B148B9C990F7044A777F9BD229F7905B242CC2E267610A42A5C3185C64079DB340D86598C589F9A96F3741356BF3E6D2A811B6551850F917E07E5289A07382B8B506C510C9396DDA81DB336179EAC1F84DB9D0E7BF52B906E82FD132647A84A299BA202DEB338B79F976A8D257E246B2B1B60425161C72D534B04355B2665129AD8A44C09D73AF51DEE7043228EDB62B858399B5A4312DDD7ABDA09A846A60FDA8D0C00E0ECC364A6CA95643FAED93D44BC8BF1264FAFA6D98528CD3BD1BFA352BFE1FBCC202F44496FDAF9F9EC53007915EB67F9F8BFBC88D82100210CD471C48F5092AF4253302475F9E60C287F0A8549DA00538432A342814E1F6043BA4355D72268F6E84A43264EEC3CAC024DD6E79143EB502A58E6F8478AE985797F00A295E84A0F669BD9252A3AAC6B2AFACD7AD398DF546"""), TestUtils.hexDecode(""" -C1023740D113A2AA12CAC8BC94DFF2FDD05E5A70F45818FE3113DA3D727C8F99F9268FB99F75F98D3F9487A4084175064A4C06548D37E8FB76ECAE0B8613BB804C9C04ABC54570FDDFA0C938A339F5134C5C37D7FAA2037118ABB9D1FBC522A334AFE43E529EF3DA76AEE24B27EDCF98430CBEDB46EFF55E9F53FA479F60C95ED0FCDC31666CF15AF8EB6D4B870BF0FBED290860ABF033C9743CC8544B02C8F85BEEA3817909B39D3D68049E6383EFF3677D2B94830073AAA44EF9B056FC1C316A2B9B94D347EC2A551F65F540068D6F787786BFE45EE254663D6B99DC1A8E32620451A839C9C7B6D637B993F2906287EC8A0F270EB23E99263510BBD7364561D56FA3E73D87F0C5632983B63C9915CA85A6C38970CD6EE1041E7307A797094EDEC1F84D947EE2E4542B3865237C60AC5125F7515C805730F07D2562D76EEB5DEED5E3AA000E38D00A64E754163A42CD2508E496E02F7FB7C1078AEB7D673680EF47EC7D8F1130E4D61F631D6B6D43244345322F3766F1E246DA51438C265F66BFAD6C20A4FA0A462395BF7408B14A0791C21BA5C307FD38414B2B8DE07D4B134342A9C12CF170D3DDBA18BE378D52963514ADE5F9EBE135D86F0AEEEDCCED7729E2AA25456CA85ACBD18BCB8B79E97DB56AD29D94BC295F1F89EB9D8E71FA14B1BCAA46B8035C4AA25D14DE7C35BB5A02CABEA4EDF9F090873906906F68A13396CD2124410EECADCF085D5925BF6308DDAC2242CE240893CA7054C4B4C19332F4ACA897BE8F998D83E82944DAB9D65125085176CF5CDBF60EEF8954428EA0ACCC6A7FBBBAA9DB34AE72B93BF5D3A709CE3CA346644D5FAFAF3FDBF9D9D7C504E86371E0DEC5B3E2EE120E064CBF4FCD455E99207549D27E233D06FCAE3699BD34D5D7F195509601154044EB3EAA0527DAB3F9BEDBB316023AD53FEB71249F0BCD3A08F0CDB9878403C1812D36883DC444089999FAF16A40B75679E2F053E6EA2B835DB463C1202050FAE236134BCC8703397E1CC344CA7901295D3AF28B39853758D086561AB9A6A9904BAEB37C2AF4D973B702850BF0FCB08CDC48D582238A0FA0AAADF832AE76420439BF29A9B32FDE6D67D3D6B25EEB521218B013AD3408AF36C466F67FC5722D4EB2E57D0E58D045D46592BB1FE907D56E0B378FF59DF68B2819D21BFC686364DFE074764DB8613DF0BD35A919048A2CFAFDED34CD3331124E8C5F8811D730803845C7CE568E66F9E50A1EE2DF92450321BA09AD2C4D75D1D92CACA21A2737672559B1B1894130472F40C177F1CEB1C348EE8AAD47B5D1ABFE148877C39A0A46B8F9E4D3FBEF95B774AB5D768FE130711A9DD9EA2B8F4DB4E7F938352772ECB46E9A00A9479C409A4F9E4526DC307BAF5C3A0493EC9E1816D11CE212E0054501D2CD9865F6E942856D32B971E83C81D94DA4F584B230491D2013E84C898386F55C8F224BB09FFE58CBD0D9E9D7E21BDC2AC4335E2FF94EC95CE2D509CFA5EE33BA848D75D046D8F576237417701A7B11B3E67BB9740B7BA3D7A37784E6CE081D3F41E8AF21CB46D46B083796A08721B7E80F0A157E86BE0F08D3125A12F4733F8C27236AA898E6E950BE190A931D07A08597633F5187767D3CFC095D1886769E1CBDF6C20FFE471E9396476660DCD21877D799A124A2F0251128F08F9D45AD45F0DF38FC9A42CBF4EC4BE10ED87FD86B63DFFC5246239517690696EE839A501EE221C16A153C0800E7D6B4385F6ACFBCDA62981CD22F06A12497B97D13C6EC1F39879B2432BFE6FC7CB3CFA78DEC8B3B800916CE777BE327641DEA9E7F156EF6E943161F78466C0300A29B1B5EE8CB68F532176DF4FCCF606738A95B3224573D5DC26F90DA69146BC8FA37D1917E3CF3336FE8D444B606979D9650B2649B1F016F6B9543E31C6E9F48594F538CBECE25C4EB8F78955BDC88EB9540BF7AA4AAF1E51DA958EA818A8DC9008FFAD91529B4D8AD5576EE1CB21216136A0C85BA87C01B8A0E8B9B31F7826537A0F920F335CE24053500CCC4EFDFE3742B9403ED950D61BB27FABD1E397BCD6CDF885DA0E3559B21197BE6FC71B25DAE1C4B51DB765C154E4F313A6EA4BD79144CDDEAA94AAA9AD40D0167C5779F022116E56154F74F42D67540D8D0988A5869FB30ED2EAEBC4B0D80E1A547551BFA5D77A695094162557B76D52472A1601884331C9A0EBE0405FA61E5F5B38278EE11A315B20633F534115C02114B24D07A343003E2730BC17BE1F4432B617D0BC160BC2249E7B87A4A4C0B8DA3C6F082C8D515DA2E90FEB30852FB35D2A19A0A39C4C44561703C97C0B660A05FDC553DBFB21271011BBA5D4ABD2C8B757BF022C6225D401A56A33C901961DC765626B1607443368D2BC37886EA65B35A9378923B9F6D2962B1DA2A4DB3250928E2DE09DDB7C2B6D27EFA33A21FBD7C3C38B6B193A1AEFCEEF9AF68FAB8F87D20E1FA1DE0AF8E40BD00AB5C88573F2FB1FAE76028EF40793EFB36D92091A353F6B044603711514C4E5288BDA0DFE9BB6E10BE6FF42705FAC7C05DF1E49C7C93B464C4F3571821378B3AB9BF020999B2421F6BDD98DCAE5F976EF507B9E0A02E1F7C7BCCEE1849403F2FA5851D8000AB7933AD568313771A436CDF40909360A33D83D42ED1D2D5DD1D1BF4AF704646DF4178D83B3031D9DEF090CC6271DF522FC4013E049D031DD504856D217E9E79F5359421EC1D3F77138F3E2CA07FC83FCF72066AD407C27A80D48A484285ADCB8114BB6D98CE6863428D3D378E5C1132E0139CF6DD841230AC0D5F0240C589FA66D6EF1380C9C2F5D9482C0E387DFDCF966EC364FC614CE707EDF8E16C783E22F8FF29A31791861F70B3DD487B4C72D5658D436FA5B3426CE337214E705489798753666B47CF8591B608A28871239BECF722BD726C0029DD7B8C72BB2F7D60CA8D2A8091749686B62BD642F55AEC9777AFA52BE3ABEE6FE5ED2258D6FA3A9A1B55B7A263287A8A52EFDAA0A817F410FE325B16A1BE3B70CCBC50EEC72A70C27CFEA321005FD982EC093D87286FE7A46822D640893334BFA932BB62AD41B4BC88D87EF1890C24907BCA4136C5BCCE546B5470038E5D70D177E7F33B0571FAEB48165F94AFF353CFD315C303CDE5098093BA39052FB1ADF904F1C117503C58A7A991F9FA1422190E0A4952374D624C7D9ADCEB0F124111000047CB5662EB71B6325528C72C1D82F0459A2BED71982CCF84DE2434A4A7DEF2C1210308DC1FAE705360DE9BBE42E9F9204044C99EFE50361BB84DB15657E3B85C7E7E4D298A34933FFB5754CE06B2CA1F6F7599790962B0E77641567AD3DFF95DAD0315DC6CBB3D29EBC8F3B68089140BA87063B21E45C3B1AD5DC6972A7A65C711301C05AB5E48F31F031EE939740EAB8CB8DE627445EC5219116D3A43FDDDD91A967A400F149399B9A82FC54C0D629A349C84085A3D30EFE9AC4381B7C8B24501BCE8F827F27CD507BE20018DFDC9343DC5282F61D74E4B4CBFEDFBE33A3CC67A210BE8E012C8277FB202608E96C355BFFD3B4FBBCECB65B7D4A61C1B9463A7F6F732B5F73A51B01596CC650EBAEC8DD40C7C3ECA3F95AC010DD275D6CB419BE78CC107B6D0DC2C060F57A8D7E4BCD53289CC57F5FE0B0831F93024148D60CB87201335F4DDEC3EAA0D749C04D08C345C0ED169DD4AF598169990CC2C8CA3986660712D615C084331030FEAA5078C0C28D3432E9B1DC5B4F48F508417D588A5CAB2DEF9DB601E0FB6975FA0E9D681C84AED7B5364E192F4847D1090924E6463E527B1185DEBFC376E0EF221D55D0DD556C6468E56D09609484391981DFAA3558CA8B35806E4CBF48489EBE0D23A9A035C52BCB4839DA20BCC6939463E4B03FBB7382E435B97C7A53A48183AAE0A8095D9E04D750535292E6F5293B5E75E6065510537DA2E919E2172D232586865070551EC02ACE7DB95E75D3B321CBC233D5D48B5EEED7E93D9FCFAA378DA92B704F9FF3C992DE34713BAFCC3C38D672194D314A3CCE47DF297C739CF7DB273EFA474D436CFE109BE692E1EA8786F703D81ED2928CA69F38F45D819B08FB8BF9213DDCB2AA24B9E50CE9421ADFF3FDA75A95E3948803FEA3AF80E59C7AECC594B2E11F35A37B9B9C684B5977E5A4A0F9DB7C89772DC17B2D2902DC6B409937934CAF22C27FC38EA4E35F2AA64D6193AB2B340B63201C82F91C20E4BB631D684321C0EED29925FFE916CCE3F403C6364F827497350274F12B405D8BDD2E9FA56F088117B1F682D98AF2A8BFAE4F4B3B1A0626632F55E747A40B1CDD8DF9665834BAA353413DF698C5AFA6AD56EB8AFA9EA22E6B042F6016F803201E974E8E1A19FB5DC9B6210C192196C97B2B4FC0FB24441A6CFF898691E948D0082DD19F72BE037BD4F48D553280708F41A7DF37C6C6130C9C02D540DB3F6CF1AF3E1878E57F267D08F4E761B5DDD7D0276726FA942328A4393A2AA9FC25F6F4B531CD5C32E92D1436DF8E1491283318445D4F0BC81830B3A1B016E02A885751C65044610D24771A9E5F72BB3B62AF913B923DD1FF09DDC7E5077F6B91B19B9E7D552372E81C05B34799814E839C4C62FD8F7A010073DFE851F273E1AD4516B4D8F8389951E47B10BE213B553C76F6BAD8F19EC88A8D6D098F7CACA69DE23B9BA40AE8862981F3DE150207A55FC474ED195A596D96C64FB3A6CE439A89F350FA24B93EC74D4AB8793AA28C3C7701B0E6A301B00C4B384B49CE713F439F853CF204CE46A330695D640F1243165AE0721E2499483E879636CD5C6126EFAF822A21A4BD77FC6B067345715D879F29B41D53B3CCE27C21B68B2A46D14D99B34AF1A6317439E52C8BC1F3A6A83B108381BB2EB80991A1EA80687D61ABAEC2895BFD9DCFBD45E3B34FCBD031446AEBDEA38179533EA7E3D15C579D3B485EDD7778105717DCB70A727A572A978DEA742C0BD05836497AD40A39BD5AA945C942512654884015B32B920EFCCE1EB74BE65B50FFB9FEE543C953A8D586B718746C4214F0544E66D60E6E78F8C3EF6FA35344E5147CF861AD2A928C451D00B35FB6FAC2CB3910F214FAEEFE59CFC099B8E020CEC68ED87957512BAB2CECFA9AE8D5244A6637CE8B2ECC60417D674C10665DE5DC64392E3E0E525CE8CE3877E9C0C9A34B2768AD41206C3E172671E9D89556013CC22BC06B74BE25C6856E89EED22D7D9BF8E3F6AD3B43D9BF966EC521BC6424A9F45E5D459B5D6370CE73312EB766BC89B2C283FB59FAD9F857FDD67F599D71E78827834AFE8CF5A002659CE0B4CC03609321C8398B651C6D1EEA2224A0E54B819C9C867116D5C7E00C588C38AFECBBF35CBF5894130F9FEA689D6389CE65D77B16DB62AE9B8E2E68AC9299AA3AF4DD65FB70F2DC3F01B1EDE3D75D61FF92F8FC3E0FCB6C2F3D06A401AA67C445CB80F045B9A7B79DE15BB997A5ADE3BCFFD8F70738E61415A252E91FEAD291303EDA176D9B9004A6107F8C0C4CC29AD478099BBDE92A5C95B35559065AFFE7B5A2D65E7A85E95FD79302B229EA40A516CA45D320DF15E7F835B0A1F05813A5706B6B73E50121758259DAA790DC21EBFC25C45934717792B46215088AC8CF99857FDB20D985C3DC1BF052F4183D895A55237C34B2F0893F091BBED221B68902A469CD505E6F3EC768823135666DBFAC1CCAD86C149D68BF8D86CF9EFD6007EBEEF7973F6DE09C298637C7FA4ADF1A2159B07425B1636DC4CCA613278CAAAC7B6071C8ADC69DE93DDEC276443C8B284B7A0BB8B38B648171A9066CB6A7F868B6204AEEFB10C26D3774DC290C39CF87E7E9B9FC164E4D52CF5E3F48381C0E9E606FD0B2EBEFF0888F94B3EDCF2414F9D922AC26C75894E61721C18B6C381CCFDB847419CDAB84F3FD033ADA263777F36E07C38EAB79C28ECD65C3623E25479E3E3CCC109F7AB3F1FC3FB2D3529D722AF9A14B3A1D553F009364EFC462B3629E077E918674DABB948CB879430010E829AB6072C25CE6FA44439173026D0487D6F89337C40CFA28D4131D4D107CD8A44D677CD5256CE7A18DB338DD8FDF2159B5F1AD1E980E76DC0FADF27A970449A5059F4BDD6BF1D16A22F11062974AD2F8B267AAC4A3F2F1607CBCD91D0B55895825016E6D721B51DAA94E49BA45C1EDA32610ACAA0E5DDCB146C72FE55964F7CF76ED809749741D6DD1894C083BFD787FAC25149C0D9F095A9383B0256A4680A81B4BC4E86997EA0051C8805456D572ECFAA60E868A58F05B6BE4DD28BA59E64143CBD7FDF75C33D545F2845DA1496DF3BDB3D76268648245C00D8B6272F1C4A986649DD66574BEC036588508519F4ED9FA08874AC1561F7A54BBE7E29DCABC1499FE71467CF0F278E792CA6942F145011BDCDB73C63541B0C9CB7B005EF6243349471EE711C2D086C3984FE00887A408015787522D0037FB7AA0774F946526DF6FC0D1925325B5E67AFDCFB113D42A1ADB854717283C9FB020306262F3C718B98BAC1CCEB0F535FA5B5C4D4FC03151D46556E7293ACD2161B336FA2AA0000000000000000000000050F151B28303A40""") +fdec4bc58e167745f07a2c4e30f8d8ecf9c7a6eeee6793f77c27353dab270398dd811c611b6191d597edf44df73fdc14bdc440529b77ffeaf18ed94a613fc3f340c55dd156e8d56769d509416beb75167dedc3fa35281ba7913e94ff5a374e0647a7f6bc99ea6ac30c3e477e69823f663e8748e8b5fc43f1728612d109a2947019331c718ac31e663d44041f88b7861e074f4e1c12ab2077dc59587fbc451aafd29e9a7d584b744d83d36f794ad034c014bcee229b847e8bdb120407201121f9f58fbd0e17ae318dc1674f1c7d9d3481629cdf02fe819de516854b2819cd6a9e97bb92662757a9861c113f67ffb191a086cc6cf612d13f0147bcda5fea3c05fd29115359bbe08a25c33a58a3b38c3214f8e4379b64fbabb00a7221fb01181c7cc2dac81e6271550bce192958a93f2f5a11035b411a00b610728f704d59d7a7e51ef2b06a2000fce618a6f82a06d18a899f7c59a3d12141979e8ba62aa4485caedbd6b8ae8f2dadfe21b7e27f911daaa80b6e22b91012ee5fa16164c5a734265b81aedcbd820b8fc5c8802a5e7cee4f50adc824dc0f0ffd626aed8fc5173b51ec373dfde19973df541b031dcc238a7fff8c01b36f8df74a0a5705a13880f1b49bb82cda0faebcdb8445048ed05cec1fd95011316a53712241f837f7a544c99c631422072ff58f579e5148885f5df4172044aa9ac4bef20e852b46ebba4410b05a5a8cd5993203f44075b0b96901fb73e1e561fe40b0decdc4b719c16391891957f97bd0eed0ce3c3b82f83d0afc9658d84d5e64bc83b2b68762b00eb2a0a474c2386fbbc87ec8b2dd03432506169f3f58f69f0dc62f140d437ef524700ff0e55e39264aaeeb3fc62940bbddc9fd1a13b9d291d82705ec87507e28c1ea90e15c8d3d6e94a66adc386b10a07c81daffb2b8d1176b958f61370ef1f0189285a49058a31c2257939df230e1218693f3dfdd9820407b509f7307cbf02b1dc1f182f9b3aadebfa7c73a6d6fe4aeffd3aaad272443df14939dd94af7543aae1212bb24dc7962e9e96d70f85a17464639f2e89344cc9b6867a6bdcd4191c91da327a003e62c1117af999f2f027ae14522bfb753bb93def9153c2d6c2a6fb8ffbe7923701e516c6a9c67ca2b2b5f66cee09864b6414716a0684fd2e3c2ff1f1d09731237dddad175b9debb722728049ae1a78401b7dcce662fa33fefc2c647b116467f25a42a932abe1742b1f486df764075ee8e765dd139f58762f3c61564b5fd52d4e511c900eec222116d27ad9dca25517449bda55b1509569677b2f0bc99c4d22de9114a8469a4e401f33e7576057d4f735e1c7661a8e986a5aad28026f6af030242535fb87372ef76023761a2b46fe30002e947a0b208f95663b34f8e92f72f8c6b58a9df690426c3c7352b8100c87b48639c072f0ad37f66d2b0e6c84fdbcb7ff506b911425a260f2a4e3ce3d6abf5d42af4fda4f37d0d4d511efd204c09fdc42d868cb8e036ef79b2425780df904fbef6e22f5117434da776e99253f0d444d1ef9cfb10f4e0782d3a5ae10b1627f7b71b040f081c6f5377dc927e65965bec75a5cbaf4eabe36c65ce71c75476c0b962a278077bd765600330570474fb68a30e9e427030825674408c0534eb2db8dfa2e986d45f06072cbbce4b3a2e03a1209fa8a9eca591128166b40bbb20419d31bb82e30b2ee7962c9fef7e788b55be7b9bac11cfbce39259ec32bf200d0b490fb540e1d218b52d04dbed8c3f650c8310e257d887c472e24ea02d3108712fc88de316657cadaa0d8ebc417da228dbda1ec98a61d1d1989dc7f10a0b4fca9f6dd2c614755bfbfe26586fdf8046bde39a2f8130d5bb9f55f67db1c9d9c7e626641a97b09d4dbc3178039d78e92b5049b7a5cd637cfe35d6c6b86771db2442040d15667c256c6beca875675a5106ca68ec6f7a01257c9c7b3464e01e8146085cc3a9aded04711d2c363cf7f262ef90f17c8ea28a0c15fc2eca9d970b33ab22fc43619cd42839f7ef53660e9aa88a32fbdcc5a74f370c6696922c4981048cde02342bcd5182f0d633cdc90b383068178de2499d41159d32f6c22989d230e0802ef40823a64625003c29b0b6c1d9eb39d15baa69947508c141dd169caf1c617a2ef16149876a56c6b2c4a92be4d48b3d277bb5967fa9931611a57893486fe3b8e8b92a8cae0496b0808b49b712cc6473ad44216ce3d1855d704561abf8988ca52cbcf7cf95d6b071acb061f03aadf2c50c4159380262edda1827050675cc375a82010e3e3299911db2d93727497ca0d75f5e539cf75d412177469afd91b1a8c8f36a2e4ac5484020eb0c7124ec570f94778e8a43e80d8fe145205ade385ea279d4bf6c4ce8998b118147edf888391488596f2737bb381cf46c939db876de724e141dbe7066f4a13c35cde58c718bea1e2b75f6b6d9600fa08835abd0863f2e3fb8f7d776b1604fb068f0c8260672fda6062e5585c595b087e399f6a6d1d26857425f600ab13113528bd2de7b8b78e933aaf344880e0aa06facaa7090627b4bce3b193308f8c152eb82e13573770e3a9171b2177e9593911ef00efee1237166261a38111f07cacd74f6a0c2283757f182a508ff531568cb05572eedc6e5b706c5ee3b3e8139b7ff6fb42a9b87cde81b21ff2e6e48d0f89a8adb77aa4be8db46ebad82b4033e857f6575c1bfc0500ae6b95c4c43843cbe7d83e8684a1275ee586e50b7241ddc72c017bd7d4aad25e468b824a043504ce3950b79a5dd2919fe3411dd250ea82ce01477306b09d0cb9a789bf24d22288e73909a57ffb7a1a395be080518d4bdb46e8648486ca8af29cf0311548690a2800648cff58534afbb5226c2e860178308236beee319c14811354b6b05a324115dbe53ea9bf37b7f8284f4b39dad5ffa4ea97ebd9bdf35d593d63026667da30e0df76941822908f6df732a8dc018bd2a93be0a21d64e33da01292fe3fdb5370a0fcae68f860af88dd8a4055960621524ceffc2391dfc237205efadb78f1df769e070b09431fb7206c2cbe3319312668eedbfdadd9cd246d3d5dd648d20758882ff7f3f156412394b7568dba0150e27fd442b6217495d2c42108e9f16e9167684caa81366cc25a31766e4743c49eeabe051cbccf225016f067939b238fa3e9330e4a7443d36134d7df29f8b260d0b7a3e14345b497de4816cba4921e18dc9dde508075da67ab8c210c730abeaddb040cf4e673ec03bd8d803fded05e1256d90d3c050aea4c223c174dc9242de76e95fe9ad0970c3ef6eb5e7afc8725c77c5fb8d265699779f9cb2bf8bb26a095472c939bb3356bdd218f0b2d99b29f0475a4858dba236123ed647e94ed485a1aaac64b7c2ed19d98f2d24019055c5c7ecc88ed2cca17019388419b3f9819b489eb837bd3c7daccff555c7daf5e5fb5c75694c96f566aebc5ad5a48c6f272f812b4606e21473e295c006c190a6430f7137c9ac20727e68b0eb6fbc8255cbab5cf3832938b7d85e6a4c46e7f7051571981bc3f6f86b9a6b149ae260360d21587485ca40dffc6e93c78e15b875bc82d31e04538863ad8bb8f736c23bed9a9698b51550f91caaab6731bd6feef0226fd3e08b3dcccd33cc6f7c8d8d36e8ac344f851c3596fe6f432017653df0030a64e73b1758322786694613bfe06cf75586e12b92ab563b583161292f328b56ef3648b050f75fb108102f0e28be8c4cb7dfc4283f68eb6bede47696b1c9156194c7152b79a96cd36639488215ec9d49f8abcd5264d89b51d72c447e31ac2011f7223789a82c702340a4ce59a298713aa95e17c6a3e92011f5ec81a3a9b6537f1331ae446965e58c2e1aff4931824fba76940c5f0abdb079f4ba8b32e169e3947594173832dc34e824f296e93099ae8e20437ef564da9fd48d6b6a2cb938a9cf884fcf3327e1ad935257157d0e8e379971cee3d5df59135207930ec1212b7f38b324aab2f172726712a9d60e40a0054f26586d5b3a794edf8f33819da983c209f9f4b514875975e40f72cf9ac1ec28811cca5896e9b4cccff414650d00e71ae2e37c4bb03274df43ea5edb923e157ed3adbfb79b2410b088c6ae9f78b10eb87b0d336c5adb19db50093a7b26fe1f39cb7c6b19001e4baccce386684acd8850cfc64aa0e16ac6cd15625e73b798651fd44828f2d6c4179b21af6dda2262c79322f41a49b9327f8ff0381fddcacc5d1444f449b54d8cd0103140c292aa49bd3a807e5af3fcf33a0176a3bf32ae337c4e187cff519a2589ec5a75bc531ae8092b72fc906f1d82735070b76818d0d5ca9266e7c0f4b9506f8adad55bd8f04f5b9baab4662d20eb3cfab00ab81bca5926b6909b5fd30b14c5581152aa37a3a275642f790913aa9f44f95161bb00c736eae908f7b3c0745514b595d947f97e67758cca97f754cd359d5a4cafe7884c10f379c9233e8f9de5e1a4688dbf92d92a256eccdf06819d7badfadc0f5235b3fb9c66cf65c6d755c5aed48610cea135d8e1bd748fcce6fe74cbea0cde943ef57d26cb7d0699f9069ea14ce1a66a5b57fc442c123409b896535283cc724c27240850ea8b9014d01d4ab2d8d151719f3b2421b60e2ce0792345f88bc26f2e3d4f9cd3a69777a114014ab481459d5c5d74278cf1c0ebbbac2919fc1a77e0997aee5ed24560563448b471e5679b13adf445634742ac1acab6fa5a0b6a0e8e285714c12fc05031c0ee83ed821bfeb0bafe978f785ba36392aedeed53e4cdefca5f4026b535d7a1a1c4ec9155b42f79c8224d286927c8af6b24c0d87e9089d2becaa48f11365e40df4810dc90e12ea6288cbc3cb2b84ac36af1867843be343c3c734eea10a54519d9c6bc0f04cd978360d5eef8c5fff75a3e4748d4dd37735919a1d6c7c4c48f5aa34567737d3084686b1fbe2f23e4a639542cbbe7f99c18a80f97033795a81c9ea029d51e2111e59c7b66a2c78629a1594db70c5ca13f3a55cbddf56f1e66fc9f3176bd073532db09afdea26530bbba27ecac9d5c164ac88f7fc3fd71781dee0612ec04b790d66bef2f748e93a6215408bfab48c4932277e3052dacb3384588456dbf15fde73c3a2036123e99d698ac5785f7027bdc21a130e875870513c1acd7802959f29cc2c3a27c1d9b97256e48666efe178bf7a1b6764cd25a4e8e97f0f55089af7fcc40ac1c3174f9e9d7c2601c8ccdb7c62930ea25e3ad4b63af9c2dcfed98ec7360e85327622f01fdb3617aa4c47ceae1dcb3b64471cd1d810d03540685d2a34cdf58ebed79b81aa1b0d2157f68ffbccbd4e617d61eb23c4c77c5bab60c1bc66e021c67a26e383aa01d3b9f53f20b9ca367d1e571dbff0bc8baf1baf9a934f7cfd06103aff1db525bcabb83b254460909151355d60303b86bce2a5d0642e951a5f1b356fedc9f6cb84fdc9c30e39231b15ca1d5e26730cb175803f4f9df3521e1f15ec7ad77fad4664cc1f96813c119874e5390b2b3b04682bc5ae2a81788426b185f57b308e3b061df87c9e69b1629dcff9b4104146c063143a40219e4c0844a58d2f91cc58dc9012de1b4c7ad6afa9ad0741fa13c651be4f27b09ec40d8bb47196068ce43e9585b1813ac01825dba7b02aded59d3df27ab5a18a7100b5df7f68b51d0557a5c26d794cbe0a63539a16e1c3f612d8a30965271ffc16a088c9b70967ee3229e2404d793086ca6f378cfc5d0c560f9de81493cfebd6349b7923e16980d2f04c5c48f7f85e56853b11f78e21900b9d9dfdba973b87c1db5c860a4c890292c4aa4760cf5aa9972a1db9ebae714c93e29af2d9b3ecea7e9777e6d4fb2550f3f952666686cad6282e0dee72b88d1b68bb1ac9021d89dac8a56a01c0c2138fd71883c7654f30117019dc70c85fe42cb57c23a2a37060402a37f8fae690abd43221fdcc23d992150de4ab217d35aa5752c3bdf2fa3fdca3202f7b0edfa83d6a0938a3e2349c51d6ce1680654c38c8d6bf2659c1885f8ead0bd687cf56144f1fa6f32e90e08f059bcf34e3493f42a85814c24cd68103230430567a960618dc99cda88cadf09e854acd79a2a54dd70dcaa5510e0cc3e4bd32b86bba8f8cef4e08867fea37a14d3412ab5f2c36c61e6e96eae2a00ae94dd5f27d7a914fcc2eb6f88b8a73fb0ecdbef7a4e2d15b7e9263a37880d242f8c230afafda5a7e919260b6e14a8d65381d73878858b0001a581e7add55c06ce1d8e30caf6802b33805e2b78d4b8eeeb20c747f7cef3a27cf17e3c1be070e8fa1adf20ddadf2e46e53d8702d75c637c2e9d9b244e12faa41f1ecabc5d98979dbaf2f0a00d061f1bbd0231c94fa5ca97a75b93a48bb3d2babc9cb0a589df0f8cc72265971e49172b588490752854f599ea4a97e71b0a6d415d058dcc875ef3f09c37fa7e4c0f45045a7bfea8fc0bd9e0c1eb36a0d3e7e03240baed7cb5d3e6aa8ceda0a0b394584bde43190bbd0ec6ea5fb3973799db1f0fc11232c3e588ca4aadaf4f7141831468183a3aed6fa4caceced00000000000000000000000000000000000000000000000000030a0f1219242e32""") ), new SigGenTestCase( TestUtils.hexDecode(""" -823FFC401BBCE83F04D9EC178826A5BB4894DBCEE86C43B44F2D9F93DEDF2A58F1FF2BD5F907D42D6C18DCFE32F644C301C36F572570E985327F49254E9F4138562EAB80024CD250525C4C7FAAB88132E1BF3141E5CE354AA95574F75C48FEB3B742B08859BB4462738E5EA9ADE997A97129059FB937F7C5CD57884AE12AD95DA11289A00206CB068663C804501851D834812226451B4912C126048C281192464850900C18B54024B08823C02552904101B8280139664840882410015C9620D98001D40252E44811089601E33410C2A60108120212108A9012919038655B2431422065229468E4306A9A988C543450C8284160C28109251191064DA3440DA0B0499C182550A891A1A24D1133681B16280343504A2248CB28106498098212322423604300299B0869D8B80414890C0417721B18920A05859B14884B0071C3126184048000190C8B244D001349C13688DC046D2139068432305832905C828D94466EC93446C9282D48A00C4248119B806CA1244D100861C9B640C4127124337201260C02A241C2029113962C1CC16C60284E0C382C23190D01A22520836552B291E022800B3442DA2066043152E12846442024C1404558204A0B974119132A0BC3294C38000B21525B140A2319221A428E40124444362248A27084A048934891E1088E41020842C45063146020C12104A1455C228909108221012E42C0250B0569E1C68193B84089B605C0B6081016810199101B28204B386D04874C14C14912419000A58419900CD410110499250992005484010447015B3248244771A046214914640B024D084140D10022A0404604C4002037441825059908641C310DA2C02D23436221A76419B3455B261103C64CD1824818C420618051A024485022064AC09108338E1A92454C986C88407011403120410541089019B38C5A3284C92045132452998468C3422211B6914CA2450BA95064380862168A54040E4984100CB78923444104364A04A9110207211A202922034D888830604049C3486150984518801092960C18B22D24828562188453443088C62DD2B041C1202204312A02270D0821095390440A475088988121A04051426109C18983122CE3C49108496808172D81A6282235040220294C928818940911A9881A210AA3A44D0110890B4544523480D04085C8189011B2905A84058A92895CC051D9C42C94304EE126719242860B312DD3100821804120196EA4460D4B12101C002C92308A219961D1440AE3A00C9B206DD3B688DB4045634621D3C04084986102942D60420E242609CC424608C04C61900511308160386C438070A34209A3366D01850CD3144102C205D1C080A4202CD8A65142484D9C106E42C4091C304684C42D621260C33044C8A6640B043094448823B6711893655B30095A028E84A02D82204481066A1805301C082A20B1685C22298B46221C9204DBA285132622DB460510415180B60D249171E3202C04140A13382C9A8410A2140699B2318B207002B35002B080E20632901025513631641089982885DA4430113048E0024CD3008623916952C24D981824222185A33690D4948D9A028DD91888E0882482086DE2486502972C1C962519428519130A03A82493088613458808306C0B030EC1B828E0104AD1C680613826081588620805234588093781622028D2B610C3204283086D1116702481250C324124258411266124028A09158E4B34108A949092C40D24997084B48092B600C100641B292890003289426CE3A0299332701C910544028414097293900D1A424522434A04978512C22021156164226A00B9212439508B1492D9C625232449039201818690D208460016681A364209B3905C06268880701B166E1420281A03601B45618282908810091C258512820C83144ECA146022A080A41226884652C04849D13226C9186C9A2481124021C31881981048A1022188164D54962553222118C548E49610239509D03050221681A134284AA824D81022C114494A2681E2184E1A444401A64D2048848980410B820063A66D4B46251A96299932464C464003110852244519292A1010068808411B114824228404B30C53A08884967002342120A929183049603446D4846049829010954510B22853C01002020E00A00491286E1319258C822C19330E0C874D130610C0164A91160593C609E44072CB18709A02620A170994A291666064069F3922967BF867A52B7F48CCA1475730371BAE7D3CA391B017ACE1FE2B9E67D4F8EA687910569EF4CE84372DDC13FDB1DA2EB9E2634F9AA71E87CFFC9E28F1BFC862E08671CB976A54EA31AAE67F4EF5E7391CCF4F6614920057B8617E6B7743F7795E3D8FF767D908614D9FB5FA029AD4B9289CFB78D4A8084DB261F67F281523C1E191004FB18D7605A5E1B61B2ECB0543C153173C981B86EE4B47602D5478FA02DEF589E0B4CBE9A95ED74E25253A882E50C64C8BDD131487E02AA035B47E2B11CF723971CC44DDFEB02C6A112E2A5BC929E53D6A4C8A197C14C2995550E9CDDDEC38E9E09A5C4F8AA97DEEAF1BE0A5DF604230916128ED49ACBD9F59A4E0F4144391A8D718D3F7C0CEA8AB31B04CB0E6E5415AA6E0F2111601EE1C98E6A6B670B265EBF325208036407D3E768B7D68C0D9FA7DB1830A95BC2E41D60273CD0E0E9C8DB63BC1A3ADC3F126475596DDC43FC64C9FFD82B92E2D7BE1E095DFC89B18BD5DB3E601A1F1033888730CDABCBF13C2C7309E4B14E687236B11CAD4853D367B146DAA251CDF595858F4190C01A95292A94F43FF7BB3FB0D7E6747029BED764134CCBCA8C517DD44A0DBF59D135C9E7562A64FAED25AB711AA7578DB087BF8DD5EC7DBB7FBE54B6F7EE9E0C4D0625DDB0379D1949FCDF2F93B49D7949E81A1DA000461FC3F5DB8152E63F37D3DDD885DA6CDABFDEE4DC620159DA78CAD3C9E407BAA84226824C142A893D7A44B73172BE3D0DE12CAB4C247DEB9575EB2040A180E7C8155933396AB69E5C1F6995A3C85D1FE0FFC3F09522ECEC1CE40B033424CD27E22C8DDCC9BEB01796524CF433D9DAA4895D0EF1FDE770446EC32C2DD87D3B42CE75F4146F7528EB68ED027B9D789405C41E4B35B3557967480909696E00B6BF1AD7903D97A58422EE4A4DD9F2EE8AE163C930530CE93DCD6DBF475A245932F0C7EDA1DE3D7BDD6CBE66F93C0BC79250606AD329554F94CEFBC7C1DA08C4B1FBBCE1C4C68F36787F730262CFFBCA4CE3794178F08402890FE3948E0C9CD5DFED68C83D40AEB2C05BDAB5EEDD980F9783F6E29DB2058D3ED5E6D1952FAB5BB9DB63BDCD1BC2F02B81A7AC09FEAC6716FE18120D48DBFADE9A919AAAC8757488B2CB53CE83AC2F9A3DA3549649200F2402F574B1A636A40AAC099E8F25E22CA2949380F53D2A8AA9DBAA36088C6CCFE95B453F3CB39D147E25836B789A33031A850E16CD99C11CB8856D0ED82CA8078417D73C1C716672030257EC839D379E9095FCB0E83406DA139C9F93C0546B476899303B333609DFD11AB6788C650EE06BCA3948651C315F12EB518D843E8A718C04C53C968B2A951085E0E5A28037427C72C851467C8E737E72AC2156E4FDDF491097062126BAF36CDF7ED41C8BA4081937567618BFA869C2A21B0046269731BEE0BB1686B2966E3658651E259151A6A98B1958C5F37DD8C5CADE9504D1211A77773A78DA9E9A60070250443773B7943E0FF672C77219D5F76ADE6625802C9A7221B10A5DBF9F3BF5019983280ED3AF23BE20721564CCD7868DE7DB9A83A80AAAEDF357B215DCF9095F79F0DA5D4C3BB98740E6BE09070829C33767A52CDB97E3EEEDFE6E43199EB09881C2F3A18B43EDB5BC835AC7C3DCAA7D3E638C07E0CBF68DE1E6D14A2C3DEC77F26D890127EF9C42FBBEFD04E9C74D4B9C80A4E4B3FCDC8C8D9AB2CD4875DEA9D5AEA72BDE1E5C558B4753E480ED410FDBF2946104DCEF40525BB445EBA4FA77C4C65B0507FD0C9542919B3B367EF4F4ADC5A1DEFBD3092188758B4437B7F7B27D8D2285C24E4DACAF513391A8CB6733DAD32EE0E00710E278072DB19A2330ECA56D923DAB749A671214E812B324161DBAFBB2ADCC33C96ED14CF04A300255DF22ADFC618C405B718988E5DFA30255B75F8F0357A57761642811E3180C18D7D167E5DDA6D05B1FE2392240B62ABF2705DE27360061F10F6F98A0ED9CA604A3F1494AE66E4A8D637472EC8674BCD95B4915511BA70F5DE8A26EA034388AAC5BD8990A99FC3BCCB61612F99708A307C0BB966D198F603A777109A6416565C9AF7D06F620F48B44A9B2F32E034D2E5EF6B6CC9012BEC98CD1F89ECE7B3E5B3A1D61DEC92FBFAAAB32D668892BB315498DD208016E7AB0EB95B6FFD2059DB926E89053D78293E1F17E07D8404FDC24B4E2B4C3B3BFFAED8539FF095CF7B7BC97A4FB06B245E0D2C0823BC869F935CBF844AC346F0E3D5976D815FB6A484D7F5E72A1C1A6E8FB0F0BC209196B0F016E672D17771E04EA919EFFEBD317604A0FB5D4327D74DF07CC1AD6165733ECBB32623D0FB6A3B1EABAEE89100FE1B7F2185CE041E030A4271DF421D5FFDDC55F846F670498B59B4397BDCBEF252EFEA81BB4B3E4EFF3756E8B2A46CE51A84AE69B774374B1995DD2D9E5E656B0573D16676397BBD9955EFE959539080E11268B071F33E125BF2F6F90FD8BD166567ED9AEEAAE0D47F5CB9BB2262EA1C07943B4413E39470B97A2B5E8C92C083AFFD1BE622C1A00B436CACCD75C81ECE9262A737E3BE3558058A330C7C570F85CCDFDAAD6962503B91D16AFC1DBCA076F8023127FF0BDCBE1C343588B60653C6BD695E954EC4ECE6D034B4DF63A92F2D7FC212FA36C88E8137B3892DBA87C2396A9FCF539098F73B043C09AE38D0730356A0E90516DDF0300FEDE1FDD0B4C84E61616F9BDA41F50388BE8D5BAC92DC42759023679B05D02A536777947E3D1F24A91D935E2AE76B9AB5A865F83E2340DDF3AB0B9A56A5B08FD648B7900A48D2D65954F51D43CA39925A75E16F32DC1ADBD22301B0EC93DA01F06ECAA8EDA6F770D4DED24D512BB1764CC515D69D87966F0BDA86769149D38DDA1BDB3EDB7EED89C603235CA16890189F560A0542455E8E4A09BCB02DE7D5FB06DF64DDCDE70F0381C98466BA48A69436DA9BF3DD713EF802B214872A397CBE53D5C573890F9E9D2212FBEB99231D1DFB98241A9B10F10704C91E313115BCA7F3663F7203482CF6696E04567DB6AEA8E8D7B29492A0EBDBD4A97A7E6F0965A84B37D55E9F88777A968BEBFCD4A3C5C94A732F5C74BA11C7B4A57648909610C89D27A3A273A0D5DA2B3331E7036161807F1162B602EA5D7B83984C0EF08868571046673112D4CFA652EB927109DAF76A728DAE6437A6DE15027514983FC1C1CB08DECD7B31C609B0F7AFAF8D183F2588D4F60A1C7E80BED6D0FB64F05AD8C7AF5B6B5E861666761D53A6109310C11AAC7CCFCAD51CC54222B88FB7644C2625397D5745E4B282F8500AD496CDAC91078124E5416C3CE66FA8C82385A3DFD549ADFCA317A3DAB331D203EAFCC3DFCB7536FE8981FDD6C00912DFDB2B0D708C162440C5CACD1EE593F4FA891DCBDDD18EA0BCB1987152B3FE0CFDDF75DD31751E8F74AE01231BF3164D4917A9EA2372D5AD19523F657FC24C4A6D0C2BBCE794D2CC270B6585A4F7E2153E6E41CA9BE747D0348E68D7269084BFE188E4324E4FFC55AFC7D8DBDC2A47B6923556C9BE84CF29B1C6A3AF1B82B723D79F65810C767C140430DFAC14968F2581259CBE74475BF427A5012F93DAD6846B976846EC308903C489DD1733BE7193431EC09F70CAF0C14D539584F58E23A0B93CAE93128D1B52A68059D4D3FA6C4F7568C991B3FEBAB081498EC59EF340F91C2640596C7C8A69230354346C1BDD89DD99CFAB4EEDC3C2B0FB8A70C5391BE2D533D26F6A3BEAD450C05C93A43D07162068DCAD467FF6EDCCE1E1C594B01717E8345EAC25887EDB71A221BAD69E5F3E9B62A7C0303DC62CFA8CCD93659FF50F2A446A797026C0DFDD5D1D50B0D0297AF09402B570196DED70CFB7088E2ECC5D474D7D382E4C073130F12D4C23A7071D93BD7E66E2D6DC1FA98307C44D013F6C1335D321620591377FB5622AD625AE9AF030BCF3F6F32608AB45E2C15E78ED195488E5995D933FD54ADC6C73A02F105CC03D19EED13F3733389CD42F07F7D900FFEC6179CFED21C5AC4CE31691578805D2E6BEDD06953D0EA004CF9B630CA71FED339FBC6D465E69397919B3FC508A3CAE49A9B3276D1B0A75C78D8686DB7184BFE2878C0944256F98AB6C25DCC67C90F1DA7720ABE159C8743C15B3BD3469708879FE4C915A63AAEF01E5407DE35B1772513CD33D2678A9A34F430ADD7B41623DA000578A24E5737DA976DBA5C69569296FAD87A5E6E8DF5C7C2C1EDBB7085C046106C50FF4B4A3500A00E7E730D8E9B0627E10ADDCE06C296A6F5BEF4E99C411BB8218F6304311FAC1218ABB847D8FBDF5CDB74CBDDEE983FAD3A9447BB80C60C58AB0CA05FFA8875275C6E973EF9F80917F11B4C76EAFD58AAA34650A438B18246A4D87ACDFA57DCAB2209F65AACAB4730D6DF6CFF2E87FBA14B720B16ABE927590EB015D288DDED8DFF500FFA2E0ED288CA86CC76DD7FC7F84F5F926CBBF026C7E6D5D85D3DDD25EA103B7FA98946E4CD8D450D457E85ACA4311F8B52F27B4EB8AB2F993CE5C81583021CD385C2589073F997A21BAE447D3B4D3BEA154F188F7FA7A19C7B4E9315BA358F5FFF6D9FE9023C8EEEF0A240F10E698102A19FE48900C304E049C5A5C3C476D224815AE298520CD4CD889B44E5DE0C052F76AFC2F7A9F068D5A81E38CA8FD5D4D9ADB47D9D385E5B5C4BA54B8DFB42DE493D5080B326AAD8D41104D7EE98F51A147A9DD8130ECFD817A7A"""), +89ad3b5244d66fc84f3dbb02bb51be6fa25bd2ea3deb3bb6d964448351d9821ff3350a0923768e299160662ec5f29db9d9591e3b6730565c74af37804e43d888b6ce506ec5390c18b510f7f40702ba377ecd3e482c23f10ddd8e2dcf132ff6caaa6cbbe799d88e81dc0465de420f7dee501868661eee9c9a2113091bbabd22a2d10692099725cb201163862d88c4845944051a414010460912c764a0066a081666e3484cc4c440d8a408c4466ea3460509170909844ccc2822da9481901449880831c0c20c9b106082c6601c9871d8320ed1942161246c91068201386dd21811183131c108282091450a248d09329219277222042891020ec80228e022429b2011e1922004b92c204440044329e3983110435118232d19b761448425d918901347614ab6084c8428083229c4206403b364d246856230721283000ab94409086188c64d24164012c281182186144632143825c48281cb9230dc162219414820432e1124221023124c1068e086640883811884210446525810725348485a142024119101166c1a8011d0244900934dd13891828470e4260919b06183b649d3b488819285123692d1b685d08261c1080e21b78c0a305013408d0a101098208a81c24d44102143202d0845280208264ac8700b342cc2186102394423280c40369208047020b948199951e420204b464e124066e2c06522202d10236dcc246a89926040281008c1119cb28898a630cb0464428045d006909b8211192646da90241b824c2212892005861b9451013165e21604c8347200448952124c1a290d21a74581942812268048382240400d0007301a056ec1244c1219822088480c4829d930828488048c40489a064c4aa40061308d1a25314c348e58822093a204212268800684d2328211244a1ab96512092440140a91166e4a845019057120178559426c8aa41114c0651b98654b9609d146480ba24c99024142344222024042480504883022426984024d23205244006ca1806c14060112c2251c289052b66452b82808b30d9308094126100b8749c81285483429c922019924450bb16d000460202742c1162590380622b5050a4060c0b24018266c89000964882d81320aa3b68de328250218469b34899180894c20012419469104611bc931a04052d4400d1b04300933648a0031c4a8500c430802252cdbb631c1482e00a92954a850a43804a3006ddab88820078ad03880904620cc4846a0960d10b5211c373289346503a2201b88084482805bc644d10885929208da84211292841826329ab43051904141a844a044120212311992290949244c4428c99251620820141244508404d1049112262902b620603208a3a270c4367241422593882c18a00060a24521378c4b14441c222061366e249641e3a86d59c201a292700a0006e3405021174e090942a1348dd3a0299a96219c924d1421520b430e0812129cc868e2b04804b94108b64c24016d5a868c20c8459a082d5096689994101aa5608c0091088950a4b4484b24654380211a266411968d80a22049369118c6290aa16c62806cd4a40d8cc201e4324619261008122924c42409a10c10230c01c609c010069b84699a14240404814324620a1162031548203191418209c4165220b72181a20010396163b86814374641a06d98344a9314869b92459c044ed03805980249a3b041d0960c5010048214060439249c02498c4220082828e3426d2228308b3451a3046463466a19018c5bb24022a30454146403221210182689044e53828804a72193b840c0c06d0a8144d9100440b20444900181a664843825c386812394645b806059080d08c760922262e1b2501a41721a3100029111e01065900000014669d8021122c8401b1192cb0850e0166a22812c601261c41649613442003089a3a490e0c009e3b8289ab42820242a0aa6451a073264482d04362648882140002ecc168503286e99b0614c342c802260e0b0080392110c841018130a19188a9c36610b465041b88d22a129db307083008423a124629661e00465c400681b28451b444dcb802c54c688db4265d0121119038c0c036a0413115016048ab2090b09260c050954486163a2640c281092800c03804053928508004904b9845b186144a85194186ddc92040a4904a00811c8b26c548645189544121685c04265c38860d4c42d61844d11b52c42228400b611241a129dcefb764c1653d46b842bdf5501ca1428a8af384c3016be82afe02e5a8c299790705b58a1f23e130b87ee9058545ca4762cc1fc1bbb0b5f9e7774e12c40cf09d64146aceb54d786746a48974aa907cdbe16dcdd77eaa11f1d6681e810144694fa949a4342b6b7511314bce155af629d90a93a3cd10a6b2ef2486634aa06121a8f1c1595e6e0350f470c0f44b37724e8bfa4773ff0c6d76d9a597d4fe2ee9f388ae8dd477beba96ea6be86e026468ef471e5135a5350d72e7f82d775eaf3d797c89ae0b90bcdeacb6752e775d7e90a3095cb725b5d6a82b994b439d0df25115cee06c9d0369f237684178860baa33fec3248860483389b8379e53c6eb16fbc8191603197c63f0419e9a98e833f4691229dcd5d94c71e37144efdbfd3a3d27e31d29d08abf2cf5ad55c3d93fe29650990f00859d0d2b6ab597246e7fb071a213c7c9e6090eb450a1e3fb1dc67c1f82fede9a3b84291930bd18975476dfa714ec3a2abad61a3bd4ec0210da3691d40aeac169ea03d9252fe7676d6d9262505e560796fa073a55f8c08b88e050dbcf80b813c55496045e2c8c45fa6da9248e18f5ddc1c3f1578a65eae7406d7cf41e67aff1e47520a1a208b6cb98fc3e6efb11c735287cc64dca777a4a9d269f40f77a99bff4bf40c18ff417b6ff9c4bc4927b0faabe301f6d98a52a9fefd655ae1f25d1d39d8a2963a8dcd54d3a9a6103d676727dae68e774ab301989f4d8f7ce36f0eaf5bbb736305ae2631e783799354d4124c75eb03973aefdbed89b6a91578eaf23a57cfcbafb9bd453320eb6e7dab046bd83629778226190ffab199abb162768975a6daac7a899d4586aaacc03497bf99e4ef318ec68e08d38b19d71a5c637941494fb428ac8273ac37b829bd8c9efb230e1c5925251f0f5e97913ae05ae2b9a94a06c3a3f50e720615766d2996625376d1c3837e587a9a6bfb7b22a52f1239d137dc5f82b4003a082e1afd13ec71f0177ffb29b6c7ca1d029a848a7a51615dfd49f1238ab7ecd99a4c247c6521136f713bd607b64d688e028ff223f4abce8ba86ccf2e467819556f7ca046046c3745211de9619087cfaced23db4d37c4d01756df82f3b2abe99ba612d222e5c013eeb0b75b4bbd55bf94201cacb7c6c661eefa52fbd8a1fd06567695a07fb596b13222141f7ffc72cf791d5773dcf847749859c27aaa4b5704c3b92031af9f527076dda5f45de8ab53bd023c3816478325782cb71b5d17335e235cd6386a816a10a7ed30f8dd9137cd5f66e76b6fd8862a8dedd5e6c388dfc4f73d060c6a19a6bb792ec2ef5f96fc5e470fc3d3895188dd051e59f43094ee61fde3f7b98ba1bb22debdf26acceb87ddaa01363f81beeec856ef25902a3692d0f46b3a37ea4c47a72aac18d77f3417a901de6e5b5117ac810017c280c37c8e0f19b157d84087ea8f74e817a1c647c699fb8ee25c473c8932cf723ac4df3d96475cc77fefc54ff6cdd8490519c97328abb27bf387c78274c42bf6beb338e07dbf954f37da0964a36bdd7740a93eb2a15b553e0879bf08ffef6f48a6983d3a419bab890f0fe797ff96aea354fdd4720aa4a80d81f58ce31039c4176dd6894f19ad915bc52645f4098c6a99306e9f842ee21e735a4092ea05fca13d63c6d41c9d799965124946dfde3108f45334af1daadff53ad649654c176d3d1239c7433da7a383b09d335b1219cabfa72faf74aa4c9ace7d7c35e3ef24283fbc33d52d9f9ae369edd9ba948c6a6e0c8ff652c5dd3249ba4ee9190548df9d44553ea48fc35521eaa19e5067015ffff30bdce2378c22493d4ab73678173a68f5c28e9b3b08de6ca1ad3feb47ae9b95708ad2abb571099faa68c92d2f64af1d3ac55301e71ceed47c9c21738397cfb834b6441ec1b1ae9a96f326590867cde1375634f74a42b5fe376a1856d9d3b4370407d99edfe986235f62e8862a4b2c25d37f15aa1ef6420fb7a9c41f1fc59e9e621084e8babeb2164dfbd0c8c27de2c938896dc918afabae6af451e53fe3478e41a9fd95a339bb010fa98353e5f17e07fe1581386b0d860991d1b3ce8be86c9eb0f6dda114448f42bffa2467a4ce338ee2e41d5fda6af91a333345d904a8ac8d1f9cad18f06a23b02d32c480fabd9982adee870acae3fc0b018bfeda93b163255814cb7a874ae669070ada5a9ba584baa3737d7729ea50d233c7e4a002ba3a5feb7b738fe176193a628f165204fd147b1f8d48c39122cc2987eed7f5f059c176836a28333fd5cdc1547a62e647e17c29e9f5e55c7707211dabde4983ea5dc9b6fdc600fcb8e522953d2bc3ac7d14c3bdcf1bd2ffb62db49c0c756875016adf31909e9c7a409279cf074e230267a7c30d07cba46652e6209e3be8a970af8c8ba6e0abfe8fa53340f06ab556be351cdb6df4f88a892a569a54bd3ecd71391094f2805f6c97e2c4dd8ef01caa44aa0bbf01e5f6b96c37c6f59f2aa8abae86cbbb01ab64afedf832772897ceee3c1a8676c25eb2d306ede14b53dc4b131201196c6eaaf52e5ccc1e38c904fd00951fc0f5368792841384091d47ca81b2f9b15c5efdf13524e97101911f89ac3065dd6888253f9bc6a13464c822791a240f1867dd92a43bd5f2407cd2c85bebcae207acd4e18630dee496a926184757eb76d6567e2be02f8e1260f4b996d689bbefa840f69bb410393e6eb1dafd44d9e9b5d16df766ec1acfc36c7cb0393343d266b1f1038c7a93e96912f5ab45c4152f5c41e5146f94d363bf7507ce873a9e3aae23f2507c5593cd3aba4329b9cc282f51a25fb50e6a8c87911f36d7e249603fd8aeeb7075839b4cf6dd2a39d19bc4d6a3e7c1864d682700d70972fcb47d614df7697685ed768bea835dba162c720c2f4edf2e6be50af9b198cb46ac8791a4b86e8c677a572ec142cfc8aacc8fdc655654c4afa8fdafb3bda9bc8c9d719b9b47da3073ffe1de8e60621c4e98372252673abf4dcddd2a48b9c431ddd3fa156c16fac044dad53e30bc38bd58d7f36a9751161acbaa04861a3fcdb3a3b6d92217f9d43f093198de2ba201d3fafe8f8b9501ec822335d3e38ddfe2f85259d29df67d6a6b54a4ce9b42950d4879db4d5e2fc8619ec15737f2a986ce120160fe68100eb4997aea3531948031445f0f0c1047fdb41e09440bf5655e1a72becc30369ec37729967fe08e75c6bbe07d7a9e25016540f3a1902dab57d8ac90fc4ffe079e0c4e42f9ce69b201f878e0b63a85702ae51a27a0fa5ac968eaf676e2759bfeeadadab6b70cb54510b8d0c5d9fcfecdb5047cd333872d5754b3018b5cca68d78114bac87d37bb3afa465e3e7dea2cc023b56e729d7df130c9161911ed1d56e5eb8617596dc4c1e167f4a976d63339bd444c31362716554c7072c65f483a3bc44e93b3ab41f177dc20cf32550b7346d42d28421b23eea1a3b2c38738ce9803996369b3dc44b5042ab7ee5faba539c208e65562757242dcb1b9dc34c453be1869fd575b3b32336beadc238a3486e9fb9f2c13c3c4688928397224e06294302d158eac9405b11f607020d8f410410460b2b54c4612dd992daaae186d130d2cd6cb59b3db055449d4293d0ec7459f99a5c89a6bbda86956b28b372f2e4b330b07bf280d2b498c785597536fad5c3e5bd2ea1061f036ad4df26dd7a19e3a5ffbb61831761b622877b0b61fff288d340a5bd9e67b32a3b1a182f2334273ff29ddc92c9af073280659c5180cc38eccd73417ddd1250ad04b7c241e41c993518dbbc9adeb525b102fa52d6c5c82da07d09364e14b2722eba04681408056e10c3cb95d68905ac63512c66da44186edee4db51d2ead4af3ba930ce11bfcf316b007a3eaaecb36f99aafa98f9eb58aa4be48afb11bd9ba5bb0c11ed31f2f221766204796aa21a6be78afeeb2bc239602be1c4c5d37643ed6847b3396a3e3f541493a6d038531b08d3ff3bc9b0bae0d686612a19c8786af55f744afbd0400f79381a4949a4918f9dfa67e7428b7449edcb13ae371fdbcce79a2e09d5e43f8f89511ec74482885bd2606fc5a50c46a57ff5f9fa416dc163e47e5e55de6e15e91c1ec9da4c424fbc7491c5863affbc4ff8a3e70640a4a200c8c332fbd6438adcdd402bde5cd2ca3f44365aa1b5bf6a4acb87f953521bd04c4dfcaa108726a9143338ea67a60543a383c2d95c6810e96f75202cc13664fc60df2e278aa81dc7309cae1c0bab58ec267e39dfc01ba3de9af0713d2c7882a6787b5d2cec943a5925449b912b5e5f9f2ceebdc723c375ca5fdbe49af7fcb5546bf3c741e1e1decd8f537a9aa7f351646807e6b6f2476913c1868245a1bd0a8421869feb3bf7db2d19151a7e918a0aed4ebbb3199e3fd7af74117f51900969466814323ed64a3aa9c817178c1a6d7dbc465bd2301d9e6f9878fca977dd82411807a747f5f33c4d4ab5e7bd6cf3d361292c7fe43ee50bf40ba8597a725333bc4505fdc08629feecad7eab499f6ee6fd3033986779920c7056fc7f8c01223efd7c5bc52d65a51c5d3fd5d96db44ef6650a26ddaa20bba2565d753e5667c4e883643c02dd5b7b62cd590ed41a2a970642c3be4c427347539e4b19e8a8ce898d014caac039cb822cf49bb225ff4ad402827e7784570ad6f5a99be49c167de94cd81a3acb72be029b50c072b03906c0e88e26b631034c9279fa87bf75a1ec57f87f5af302fc0cdb272"""), TestUtils.hexDecode(""" 701B8AE25CD8187095349A4D41A067D4FD48732E62547E491D38845B3507A7A6AD8F8AFC53D139E47FC5AF2723B1BB057FC797519AC93CFB18DEB496BD9735455CBDFFFCA5E69C95990EF89F509728D1CE41F36A4C0364AC8C30E3EF67D3F3776400BF4C838A477231E455FF76C92CFCCE1B69B00F99451B0A8287ED59CD79EF0D6E697C93F7ED38F20204921E6E2F141D3DBDE1C201E5CE7C524370C339753676746DA5DE4A398CFC2CB1F568C16D4DF34A27CF04F0637B1447C6CC83E965A3F86C538CBC235E440CC2D1257CF916421EC75928DD6DA3CA002AC93C8F464ECD522EEF7E048C154D73053DA7BB63A5DD845512D2B6B7D1E7EB5818D170D14A4A698C8922D69A98319A10E0AF558E2318FC390ED990B75ADB50C6199DBEAF5D53B49235DE7CA116932EA38A109322AD05F5D681CE25FFDC9F6A05C4ED2EC6D4242173D2039318EF7D0733D86D57C4E114B3476392D47FC68796C9F66B1F1EC70610E1D57436614D5969564DEB8673686170E40BF5CDE506F7E70964E07258D4551F5EE0BF2651F8BF3D3177DA76AE90FAAA69C4F373E664F0A1FCC62F208A8BE130C499166D13CB34D77FDB32D5A7F3AD38856BFD3A0419B8744DD2F186D03E18634D826A5BC87F1566FEF88D9ED93E74ED4C005EA3EE2EB22FF5DEED283132D00C7A0B131BE1FA38E30EEC68B748AD533BFB23B9A14A936F609D4C560163235367B0D64C2C796F1106A1A9365E8F507B4BE0514C849A81E2C7388C8AF300D98D444BF808C4F9338C47A853222D5AA8ED283F57DBF0689E5FB89A456005B6B95AC3D791077C79BAA2BB42B423F93A7D0D999241AC5B9D64D65274817F9BEFCEFBCB4D5CAA67427F69ECB279553EF0D33A19E14FD4B284A72081F949FBE2A7543497F314CD7496EEE866F33102BEE5CF9C706426EF2365EFDF1AD141552BE65D1DB4373B0E8D449F3FD1733AA164C1F2C24F74E240C5096CD201A11113D6BF5CA19595C4B0A81E1153A4EBF88F38F1812BE517158787F2B378E8E32C9F97432BC9027292E5EDD7DA64FC6A32788154B62E40A85701895E13287BB18883820DBDD7647AE4EE1FC1D43C199EE69B1A2E2A7067AFAC541A8F44E660B2A7C114F402E2054DA7ACC41DDDEDFD7291CD4573DA22739C7785EFC2240B27A90BFCAFD1AFAB6C2B0EF5509D0DDF349C173E9A6C906BAF5692C39F6E0D1442F84AD2FC118A14B12C3AD5DF8A79056017F4FDD76603717B080E3AE560D7A601EE7FCAA36DF7289AEEA59EDD0B73BE91782377150F03C2C2ED40F33A250356CA17E153480A7E848F090DDA29C65FBBFB495FE9B7A2BEE342C7D422F28631A8C9CF643DC76F07F162DA1AD3F24589971032796BCDCD262F55A8C34FFCE05FA9DC001FB35D6FEE75B42DB6DDD2138C0517D003512F0EA8E982C2ADB5E5BC1F19B8ECE67E4AA1681383A97976B6A8F2025EA80B1BFA1796C27F6A54C583711E2EA46D85C515EAAD22ECFD68C5D02853D688302704EAC4863DB1FC69F8C35411EC6F4A9F0A7E7B3385ACF6DF805447BFE863181A945E8E7944770340496F5A19CB7DBD0D9010B7EEA3C585926408FD40F245D852DD208EA97CDAB0C16C1EF80B3E5BE77D953A04C1B6F53A23080B54F439705E417B9874B3FB524794D26DE3DDE88E9DB9FC36B1508754EB51D389FCC46F822F50FCE199DC14E4B4468B8B15A2460EAD05D0C47668C05A2315748897AF99D320E70F2AEB96936D7D739F72ABAA6960DA6A3996988F6A3F7AE7772D49915753B936367E022179E69B6853E1A83B429B42BE19EE03520A5666124B657D2FD6D15447AEEE45AB1FF4593DE9A2E6D152C64DF45C1F62AB9B67257B2A2115D224850A3AB2FA028F8F9FDE7C9A9FBA2FD291346037A1B4E00B0642B07ED54BFD70F3DCA3D1B8628627859611006DB2DD17A351751F85C60028DCF21481291526B1DEEA4C7CD2D3230653E6FEA1DDBDFE1BC3DA93FBFCDC5A405975A5DC68DA0D8338EFBD6CCDA1F2374D72FBE007599E81CF7D5C37985EA09C561A1EC40A70784FC606FB7C3FCD981F112C599C78B15B7739AF4DE129D489336BFD3966C10363A60E749162D1D8311C5E850B22910B999080DFC86D1787C35768CD5470E9F7A51D4EEBA71241DB57021D6569ED2BF201C06E235D6621B292B686D23E29DA4E81C873371593CB07B3DE46E91FAA3D4A2AA6F62FBF6BBF1954647E731AF4B99EEB3C0FA6385699F8EF2D8E1D7F75161129A1C7F8C7C68B906EAB8DAE8BBB3541FBC65F36BB67ECF19EBEF54BFC2EC4E1130A2E4F36B5644A73CB0E244738B6E5788A4B4457291B57F1FDAD2C11FE5C7DCFD4E742A0AECC460BB660D7BFDDEE4CEA074958AB94B6FA4CCEFE02FC7001D3A2CD013684A1ECC2E2F6D90D246726EFFFA99C12D1FE4AD10A6BE38D70AE3DE5C4843FE6CCEEF587191B56F666C1662F5C6FB03955C557E1B4CE247A2806DE39EC40CF8B97835EB0E3F2D829E0FEA02FE60C934FE72A25930FD6692B9ED979F14536F406F04C3CF0BE98647A5967B81DFAC353A2F8236FE147BFD7D3731C49476C3191981C9AF239AE8C72570C6C53E7AADD48E721E623D6CF11A1E386EA7C30F070E7AC4F63FB42AB74881BFA3FF3E8A35EBEF04D39B853DDE0FB17DD9DAE37A76C96FF55F64669CD9521DA3900B7CB297E813521239D87703CA395CDC8D8CC4EC21CB10A1C672493E013EAC0298F8076C8E0B56AFDF9C31EA01CBC1BDA4AE17FE103C9812E940A34EB321BE7BB288CF8BE7017AA58AD528C9DE09E269B10C6FBFBA5E8B6883FE7E08A0D184F8561FE3F43582CA045DC25CABA52C0157495410382A048BA67D051EA115D867D780CDE5EF512BCDD14489C43604F86D929F83D118B905C63BFF451FF3540E9E220851A402BEA0DB1A7CD94DE0407AEB9CF862BFA3FA703924D0A4803C463AAA827A04B0F09556054F27DB98E22A96D07F81662E0E910836B9423968C3F002E605BB688720FA7CF3167140BC21398B5E4968804F3C3065FAF125BB6D887C869FE3FCC27D88E048FFD0925E748C096C74BFB1E54A8FF6E2C838F16769FA4D8564E5CCC58DAE3B102EA300361EF89EEC689FB5BB0DE16C5CA98A60B8990EEC0006A147036871FC2A6ACFC6A6EC907D28E18A76560A5436BBF9353789C8A5DFE559FCD68C117066EEE5B00F349D6591E104295E78F445FCDD3D6883DF50D1DA6A04541C7E8171523FF36A9C072164147D14985BA30FD449667B580D73B06A5971B720A8B1D2A6896FDC5E4D4DAC78353ADC3449AA53919AAD15EF250AE12E9E40B8487F66AEF0B15E42BF34AA816F559062EEA24EBB01BA369747B29404DC1F1108DEAD021898298E72F4BC1DD821E4C88329D6F03F971F554A87FEC87F34430ECD1CCC6627D8CA49EEE1D5DA6704CE960021C847DAEC2DD544D4EAD2E2086058CF131296B7F4FA4B71A1DC6D6C642A256AE0C0EF9D1211EFA3845B12243BFBCB4F423E913A2976C1015569ECCBC159AFE70F1EDDC3AFAAFDA45CC02EB60BA0DB9EA83EC604113479BE848F381FC63C63B3111DC5179A637E0832A26EA32555908D79B308351CB104C43668371DB32056BB63540B9C3E5551A063D2B525F8A016BBACEB402CE7D7072CB9F37CEC13E1EAF7D867534C013D78B9DFE01C13DDCEC7A3444AFF9E182F12B6901CD9A70F21908FE692E4C0536B069C89685BFA9D973983AA8C1DA461D18ABD27A6A717D9F2122BEAA9BB1742622F51FF616FA2EC3A6D4724A3A9215D7B29A1BA372282CCF60DE90B3834FADE6E3743AD6B2F9B7344F45A29740DD7DB2D642F94998579A5DCCD2EFCD2F7D08486BB327B844EB19ACE3B4FB0D85F8A24FACBF318C98199A0B2C7FC2CCA59AE84A522890E22C2A7207CE91623362C7DD8E9F946817C75B71FB9654E2B7F2E83E46E75ED5638741E414D7F8E70914315F0E37B5B4E3E1CFA8288B1724113E4A00B59B7764C2D61443537849E77083FD13BA652001F39DD9BD4B20AB77CB945C5EBE686A0627ECC52F38A852BC9E1AC8D303E3B96D9D086920A19E5088054DECA635E802385600F673D3BD0A5CBE7A5B9BA8B1C4B73B9246C1A1C1071E5F98ED42041037FAB67184C89BF4FFE3CA0AE2A9BCB020F390F0B76DE2B8AADBC99268D3A1D467A024184CC9A455A8F2FF287A4C9DD1B0C86C8E176BB15B12023B291D44E7FF0C44577F7A6D788D82A75C68C9F5BBE504E7D64FD2AD18BE209E85C45627FC045BC81E3531A2B886173F3C3029D1FA98C792501A4942C72A7A892232F390CCBFD7863AC38D837755011F919AD8934742D0795523E6D48A958BACB9A9F7B9A5A9D914C37114CB111CB536EED3D753D6333219EC993AA5D39BF74E8E9FA02D8BEFF369EDAEC67A5CBD128FC9BA6F82E31A4C59D783A99912C7C389EC708824AC7FF05D56BA6D228C0A9D96324C6D9725E3BE17C44CAC7C4D49235BD15384F95345DC36519466A13110A58300F7E3362295DD7069DC6A88B542F2BC5C9F33328D9D8D1683902C025427F32FD562BE3F0680FA05851296E15C5FC67E96BAC924407AE6BE37E9B61D9A6383FFBDC6E77CC0887726C474AD735BC50039AEC665D827B0F6BCDF7EC87EA6BF793386F2A65C997545FB93F0D53737C53D00685DDC13960AF2632380F105840A1699ABE53999C568978ADAFBE21913193DD0844D89BD582418BF8B6BC430FF1FF7750AE8507495C14DF21A3437AFCA7DCEE7B1F1247C802081FC5ACE5B125AB2BF11ABAC97E201EEC2A8C90ADED920728EE77E1FE2BF31A222A1CA5263586A16FCF80E582258654D0793B1551EA3C24C4EBD27C52956ABCE6ACD05FC2F088273FEE8ADA0256F30B5ADA8768D8E9B70279DF95AE5CC68FFA99934C7520E12F57D213FF18ECA6046A9A3F32E280044023220140E2485A3B3EF7778006B18D4A9DCD177D190CD903CAC1EE0897F58762299A0E026B8EEC6F4F3D0BE1F070C648A2D73869F22DDA21246CCFDEB7A9784AE967F0DD0A2011C637099AF33E0D608AA0A5B2103060CA1A6718328D451368EA3049FF60FB66FE54E778DABC48413966EA14E22083A884E8C8EC33F885093F01B5E34477745A9F82C645C8C5498306AB00B78684252ECD74C163BB8AF9B49AA03E244F4EFC4A2E7099074F512D465C84773DBD1FA96D26053230C192DB289A1596E60B96178DD8CDD72FF14B340FB5830696B393CA319649BA56DCD517F5A08A528350E2D9531B3AC187414FA6E06C0F05D9987BB2FC98F7C8D4F922B8AA45287FA83B900ECB6C9F02669063296F1EA389858F6D2E10228E136FAE35F21DA151EA7AAEC593E5948536B68BE58ABC57771AEB406A0C3F931E7DCF85A350A3558E5C1B1F70E6299EC9FF8B9CC13E905D9902FED957ABFD7D09FB84FF22BF8410D387BA85D8555A75F432EC5789498EA36CF235276176ED48D1E374DB5C2DD1A64714D64FD20D4FDE2A605034E4DF607EC6E11D0465DB25B9D79C83182384D64477C126E9B8558489F69AF29730B4D5650B9860326249777DFE9EA5669736692D0780E9BA346C1727138F5DDD4914487CF32A4E9CB1DDD5617B6B45CF8C981944684BBB7921C88F5A25120047BAF2D9346E220EA08AD168B30A1B82B3B63C4913C708C02258B6AEF1CAC96E2A90EF7D0E1EFC0BC5BBE05D286E143FC0CA4A23833CA12727F0F83079F7BA80D809D6C739EC4D0DD9CF75C4FE30B12A892096BC4B9167F16819694B2CD5DB4B80DE8DE988AD50677695C4FB3E0940913C250645333B6F55E36F649A43C3A39ECAA3DE3EC1FD4F9F65D9F7AAF75B60DCA3BD1EC06495FF5F1D4FD6D83CC6316E40BC469EE5F44E5AE56ADB229A7CA5CA37A1508531E44B0142B4330048350A40FC82279D25A87E043240B4BFA7321340502F0D37073DF068596C4753F8709BAA2A7264ADBCF5F934E857B3225CA47D8A182B80D3DF24C3612FE4931EED565BE563115414CC2B6BD102DC6BCA9F104CEC8B24BA5465FEBB7E9730C928D6FC1144224232A990F8BED27FE6D28AA35A91F90D6A0AFE9A7E37A5BAE51D8AFDEBB7D5670F2521095A56862354D2AD946663B4BBC7049ED1884347734BF3E78ED227428476F1070F4DB011F8DC86EDC5BAE1BEDC9C5D253E4C5C6816347EC96C5F62AA3298588625304118EC32DB2DE0597BF2056046E17C69EAECFD26475066AC54D40A673741BCE72F138DD98F1939598E5D94D565C1337D1179DA057D4453DEE27B5C04777EA710D77B317A6E8DD3B4F26A6A9B3F4917A0E881E5EE528462508DEC6762DE2BC3F8F8C42E8D721BFEF7583C99DFA4D1CB49DE2A303B67AFD505F8A3865D853BF19C4A0F7CFA92F5CB18CD5D8E378A5B041449EC9ECFB80E0865CEC1734D34BC44E664243AA8F605366CE9F849700593C76BE0CB19CA1255B074A8630FC962B50106CD93DB41C6E4DF53B6B1257872B0D8CE9AD5F245C3027A3F75F19DC568ED1E0F60CC20DE625241D300DCDC8C953676363868B680B471C2EE623DA408C7E030833DBAAEE8E701374156A6B785E0EC7D1A0A55A599605BCA0FB517EF99939889C862CD790240709BEE0226DC7E8177F641C747A151A89340A6CCFF6982EF39683325390DE72E4451BBA74E3CB102870F1E9ACED30BDBBEF160A49746A23C432C3ED7EEF580969110AA438D00AA03F54E039195D61B7840222AC994784EEEA538B7E830A6508AA0B460DA4B4C0DD9CB052CE6254774FB147F7E4F80214AF1FAE59F8ADA6509123438E90AC13FF7CE71AAEAEF7A39C434C3824D49B894C389CF320A430A7F84A5F4972FF98C388D61C936E453BB1A340528A9FA5F0B0DA9543275435E91B0F5560E95F9AE4EFCDECDE1584761F8F60F0280ABF40FC5834BFE456EF66AF66ECA1098DD49BA2CC4B12CA9CFE256FBEEC328D049BD6BD19E2358502672F029888DC3AF3350BC2EDF5C4E07D59DF8DB9C14B86F1FE384227953E98978997902C8F237C8BDF300A72248B3DDEFD52577BCC0F99F75B92BC056719243F7EE67932A2DECFB15B59C95B43E183BA3DAA41B97E177D03CA320A5FD5D7E5A88C4D54A8467B883E0CD5924912642A65F191DD4DC2B08DD28EC0AD2B1CDB86EEA3DBBF6D47754B1BF7036A0BE90CC3775D263A5BC688844BBB9B1D9296804176E17C55D6DB888C2BEDA3D546FC496EAC5243AB5D51686AF9B29BF6D4A138BECD49665458B816BB09848CC4318136E6B170BECA544E8ADC35D40DED979111B8B1D4577DE2FADE6A1D97F9E82E9D3F069F3287E559E99224C6494F36233453036DBA617088D619395518B4E6725125850B3121EA957E721244DF53FB343483D27E6C3A53224B38C11C1D64CBFCD7041A44836AA606D170A80E84BBC0973556B9E4B1BD776C6A0876D727BB0526809700A0EB318BED67843CE4A6BE2BC10FE9D8228A4C94D7A506760E580E8A0E544ECCB07DD0810D79443046951C72E017CEE5B2C959754D477D706C3E043298CAD200189F4390F59BA27B0099DC551673B5138AA654E054676BF30DC61CAFF444CA22EB32E5952A598C07AAAEDDB83B8B3789EEF97663ECBD33FE356DE981A24C29DD5217E14DFCA30C0109419D8765A061F747BFFC1E221D3ACC7FE239375A9548483543599C837F48EA189880278AB2E06EA44417EB945F20ACB464CC458E249A8969273A460F063C5FAA907E42C9EE304B27C85BF41FB170708969A2BFDEF37B97DB4A16BBFE07370039369D04D0A9155623AA390ABB75D47FE2394E4606759648954FECDF4554F660D3176AF33153A9D7B0A935753B11E6C7295B0FF5680A18A42ACE577981C500581F741CA23DFDDBF22EB6511E19C016EDC96DA545AD16D5EFB9A8F10C45D78E01C74E3552FFAF35CFA1BC0C3DF9D14C1BDA9D510FC7C7A755C71B5273CD7CAF3AF44AF066DCF18B1B7D6C0D546C9C0B0B1BBE88F512824CB8B512438ACBB23CAE1178DA05DD67DA6392649213805D680AA61D26092BC1B2CE50CECEB7541D7F10808DB2D4A6B12841C8B4B6C5519C8683C998A74AC3BC3CC44D81B606A9A3174929E4AF06E032A24E67E9C66885004F07D4775A6C66A8F42F94920749FF902A8F1C3BC5A1A35BFA24040EF3B7ECD05654CAB696D3323485EF855361DB57A65C5AA0B238DC551ABD6B4A8DA0EB987A82F56E5EF05CEBCB4155181BBC61C645B2A4FA8B316FC6C5B3BA12829E74899D0A42B42821094B57E6D221FFA108D5D0EDE9012A88A2BC361D90673BB3D19D6355B9239131B42FB3CE832DEEA6E4551BF6C6533CD8DE572ED3E5DC51BC1ADA13C0C7E4F723CB964125DA08E0D08F1CFAE124568DE55E2B39B1475DC8F6558ED763FD7EC2DE373F4C54399A0317087630AED2A64BF13D113E8AC32E6318EB7BC0DE20E846C0CACD876F47CBF79DB6FCDFAB75B371156CF74B443E8DACBEAF94203037BA14E821A66244BBB7E989567D176FED12AD0BACF79834D067662C11422631554D1ACD6BCCBE23BF1D0C042C1CACA4B9BD01D6C5757E52877FB5DFC92161C8BB15A60222D12CEEE973812B4920B38547304E720AE246FB503C9F97BBA79640485624DFA2F4D508300BB80C70CF8E271770876062AA1EE0F548F6F7D95CFAA17FF1FAD847CBF6CF90B01D29C33B43473379F4B5491532432F6CAB98C365B84D357B48B416C2A00B25D07594ED4E4CA0E1BA5C92AA2F1DC7A6109AE8D71B9F06440A770FDC2501900B9EE466DDD853CA5482B4636BFD58AD8B24D91852ABAA0A37536D4118A122951DC78F02DDA8EC8029ED938125D759B24C90B0FEBA1F589AA1C10FC9597CB7E703D93AC4AFA43D3C239337AA454BCC471CC6BECF89266F588C3EA71AE50F146097D9CCF21E75790A5F3A252977E4D848DCF5D96DDD4FC1D0CB583A28AF9D7648BDAF8F1E94A83CF5349B1F4AF63AB1C66757B75C58D10F27F8619A5A6BADA67E841B6429AB40A09451313EED76B93166B3A5D5561CFB6421D83A5E343C8D277389950328A1646C3DAED357BCF2E8615695D7E8922030148844058D177D4E68A8EE31D5D810C73D9B38F6863083A8266652DB82A43615A45E6D14EFDF00A4333404DB65194EB432187C1EA7C48F819C34E48EBCB0836C84534A238C42E0B9BADFBB15B220DD0BF40F8C0511BA69EF82FA57D099BA84EE4AB6FC422442C3BE1E8DD910B4117BF4047D49419FCD2380966F665001FE4793F06F272E14E1893D502BD3343AFF5EE94A58CEE04E745E72E51124AE8013EAF2C2141012FAC54CD25E97B6FD3F0891BA1DE663EBF009A7008222F461B4E7D50628133DCCBA7CD0AE44BFE9F675E094D972D896551A1205FFE0CA8FCB739192488D2BDDD4E10493B43C7EFEF60888CB11ED68F34630623206E81ED04D300C2C43B6F27E41F18241651FC6B84C19EE1EB018BFD7A0D4483B0B6DCF57236AB27BF4CA17E52739E4D1C508C78F6B6E9FD53F423AFFAB01F75A9B1AB725C247492DAE3227ECEE2D60EB186BD8972FE455C393919E6D9760AD1BB706138824FC3C9EA0F673C1323366DEAFD260591DAE60AEA2DC22FFE5EA2421F35920550C0FBD78C4F6469092F89FB6908457BC81A175D75B1F97E2750194E68705B9D1E9F762068EE2FA9286BCCD3ABE98007AD1AB27AD2A094C6E164C5BBF88CD4C5F325E4E91FE2867A94E9FE1A78DAE2ED1C11CB4D365EC2F3888612FF58B493268645BE9ED69C196857F8C995A42D5CF4542E609BB35B0BB1B4BB85295ADE635E8FA237C5DF471B8CAD7E98420077BF1DBF6DCDCC1322C8BE1B8DD5E228B6E6E04ADA1D533B0C6221FA83BE7C19273F9AADADE041CEAE389D0572D2317906005BFAA17940026CCBAFAF8C7A4BBFCE30EDBF4EF82902E181B41A1FC006AC01BE64CF6E4A4A14FED995D6F323405242BCC5797E43276ADFBA44EB8E3EEC029292D2DCDC8E6C93AA6C02766308CD367D3"""), TestUtils.hexDecode(""" -367CAC590EE6829B0FE910294F23515114CBA0A04D39CBBAE3BF908DC1A13ABBCD5CE2A9DDD0FDD2A011068C48EEF6BE5B4524ADCBB6F51E9A5B0F57068385D42704B0B48B3CB8D1AB011B8F13AE83726E0EDEA0A5880590AB8FBD689E6495AD68379993C44AB4308D0FB19D3F0E6D98E61BD2EAE1B49EF4229AB10D18CAC1750A60F1CFA9430649A7DE0BE1330A180106BFCC165CF60ED91711E5033E7B8FF29812CAE5A8900CD31A4B254CDF41ED4C5B4506F6FEEE43B389218191246A661CBB86F6C8F790D3D87343A37108E1D79C2DBD9A1533542A5766D56C9D013D74E2D7CB1EE7AABF50221ED657D8C2AABDB26DC3F7662CFBDF5F6484BB9B04060280AB53F0D22093967A19E754EC5180024F3AA2A615A45A0A43AF44D6204BB8BF512CF9F5DFBB8C9E6CA594FA9875E9801B1A3BE7983DC4865F649E3AF8AC28B0780C65314006024569774E8C7909A92539F9A647BE2CA6874B4438E0FDAA7691105C3D6CBE3F355FA37676C65C3508047A521454FC3A5F13F028465FDC9074BDD506365AECE7120980AA4622A7353C366202046CC2EFDC87459641CD56FC9AA723174DF368EF63517CA839813E16072951F53F4A2AC0B54F0E7A5A21683B81ED562358DA14794A798C1C14AA2B51B2F87637446F235316F0B047E757F84D8EA86B35A9F24115387DEC18FA8FDD6F0DF4A918EFFAD381EC87727578185A214B334C77FC5545923463D2601A302BDB21067FBBA672B7E33F3974FE1C2206A0EC233DCC44412A9440D7A09EC3A8ACFC99EC24F9BF021BF3298831AF56F272FC1C7A06DA01B1B38E8C421865EB8092CEDBE376E836B9D8181D853BCD48E97740E8AC046FFD2013691587461DA91FEAD7C840D923B0ED227F5389536FF871859F459FE2FBF24C84A8D290189BDAB6EA31BC1BBD98D64958106FAEED0E8B9BA1C10B66AEB7836063030E641A8E00422E2827D8DF1BD982773E0F13D17BAC5CE3DB813F712C95CEEB0E7CFCA45FD27289EBF6C7269EF58A5E4135A6F651B2139AAE3E1068E19C4EF3191DF10F37872DA952E95B2A831333742864D6FCEA8C0E37BD1CDC2EC902D210E7693D30E36595892CA5724853510B6C01E91763F376F20D650BD1C3A647FD2C29FB3ED1B8A8D15624E60837F55F65E0D0D8B0CEBA1A903293BDDA52B354196A1B138677235E41CC894DB5B1FB474463B168E25E7F55EA5AC0572428768DB4CE75255C47422B2D92C99F8AC8F296F1F823E59591DDEC09DD4440BFB9007B8BC04EBA7A7A959BAA624E2165D6C5C3873DF0589A377C6157A4EC57773F98763745627A51FB36CB82279EB9514E452F381AA65B3EE860D0EA2DFBFC838C98821907C1A99C0C18AC49BCBB6FF01127C46C439BEFE217AB080337B66F6FFBF934FB5A6D16118DDA48CC987A13D52416F7FB4D10C7F22D8F97A9E380C8A3902C2014F3C6B2F36702EBCAD5182E33641FE6D65A2BDC1729FD8230D5814545EE15D6D02907D2615E9DE534EB49D638FE0CCF5497D351C421C7F25FE57A507749640328EDDE3DFD807DACDB335971FC46AA37177C78D179DF12F187B531CD5B02A08A12A0C5B7CDAFEB636A1EFB6CDAFF16F4D128A0C1EC96FB97083C622C94F3F65105F865B1FDC81F69A56427B900EC13EDFA938C0E8FB31DFA821F04CFBADD892B1EEA6F596A6D02947F50B3B66A3F0323B9A1FF95C33F68EC2B833D2CE958552A8205B5BF0E554FDC441EAB46DB0E8FC319C7FFDE01BB3F118413C8FF941C37CFB39A60606780EDB9F5818CA4A26E1240EE6AD117745F173DA5B2936F1B25FF1AB49E10913E9144F6A1C0C547A93408C5C5E1155F02D5C90DC5E750F06BA51746536E351814F1639AE3C845BA88EC3FA60111C7F8285284AD1CBA5997BED7FDD71205032180050C4010FE353CE4695AC49DB104CCAF5309949E2D6B4485C10E92656FA130C7D0A2C424F98683A8A2F4ACCD31EDDE5B11DFE71057983A79DEF73DF46427A00952A69C0403C73707F151EF1C1B3C39121181FBDFEE8EEEFFC74BDCA8DE6078ED56A7968E2B13426CC387776CCE40411220FF01E2ADE27EA9F9445A635EB8C0D073232FEF7F580143EDACE3954AEDF5FD01756102F639FA9643173146FAFD50CA4FE2338584632D433640FCF619D141541B0C15D39C89CE07A47F24F59B3DA68A42E7FF5394A02B77A35DA7A61C2B7C430678FC9956211038CC2EFFC9D7C8E04EB0CD6277210F49940B39395022A226553DB46292774276CE5CC184B29CB598CD85672BDDABE25B8F20486C775DA97B9C3B97B4EB9B729854120555C25F130FE3807BC886A43BF605FDA29898BB7160DE95B927AA7EC5D5A5249E82D4D50ADBE591FBE49C927EDD94E557FB64F73643464E7AF168201C57A16C6A6FF6ABF1FF392F8561A66AFE569E51F820591C0A7A43D841CD13AEE08FC15A8BD8C0EA63C69EC331881697EBEF2C1646660E34B775BF497C9432394393A7E3200E63E477169D9C3FD737BB79C1155ECBCAA73B0C54A5C0A2B8ED6DB93504C5ACD7FBB15181696C9B6EF1A93C002FEFA46007D8DB5DF3A7F659AC032BC3780D8A7C7FF485761E632573E96D052183B287174E96B230025543288C37DEE87D6EB3C44FF58544C598EDD123CABA17B0C17C1D129BD90D72382FA5644FC94CEE6BAA9C152A04F6A1B5F6D167E8B27E2665D861D5E439F2425B562DB155DAF1573B3F69649BFFCCC73DC72F3E3A40900D56A810BB99DBC75A6594840006909E78299F4C56E451147C3FF9F069A65399B296C2B906E5B493FE4DDE19B4831F43BC2F0221A833EE99938E60BB2A71CE0E4E47140D73D5BBA00952E01883D9CD3FDDC0430B9C413455F732FB0AC226BB59DC0A65C73C915023C035C6C62CD6D1F3D5C27F473A0AB4C2D946D726A0B8742E8FCAB04D2CC23DDE5B0BD952D5223501DA188822F481B8F8CC377903EE38A740AE1125F4789777D94176042C70317528ADF14DCE224FF871105257DF7F1385D1508C04F46ECD2C2E1F3E49783181ABB0E2E503FD5DECF38461C9D6E093CC55850DC0239B7F550D7C054097CBB554CB53C3F43FE1E7EDBED3B55491AB564EE3AD7A9CF330BC4D42F2837E56F15E9676A838489F0908E1DC59DCE7AD7E72F57017BF6F610F486FAD183C714F99226889020534972BF58D414E6DB20F22FD60EF8359438FFE56C20F28D966B41717D3B63250DD0B5A961E73E06793AAD1836F8341C5504C15990B1DA9F37DDF87EA2046AB57D894998725CBE7CDBCC1B5F4EF0B48B05E545AB5125CD4A9C883BFB58BD3136F03E3CFE3F225284E17798A1F4B38A91747DC5A2D64AE13E2C72CBC24D25F809AE19100FF0C9B9E9063BBDB08DD776F7CF2900C56201F56269F3BD8C3EF15BAB0821E1330DA0C441CF3A5D0EFDDD4B2B48C0F567C00346B97F8EF9D377A7A590FFE77A6BB2D6FB6AFEFDB7C8260CC1EC3A3EACEFF8AD086CDEA49C39C961DCAC0BC22FE446FD1F7099425D559CBFBFD68EEF03525B01DECB52D5ECB1DE9FF4427C8C607428CD43E33F5DE8DF9D995D033DF6A41F69BF623F36451E53E422BE18F5F9667F5AC1FAE21B4106CDFF91333749AD32978EF6FE73D7AF88D4DE4D9E2BFEACE96D8DB08DA9ADF8BB51A16D326378B3394AE7307587F98FAD697BA01C1B78387DABB5D6E8A1F2CAB663A3ED1B8A833E4F76D11E0AA38CCF4476847741AC8ADEC7A5C4DD802604F690CEF94B014A1CC2FBE8F2F71247F426AA5CFE3745706E744DF24BB7BDB8BBE8BC8EEA92E46F8BFD515D52B3CFFAF81F127C5CB65B1AE5D4925161610CF562B660CCECABB35EB7F8BE085761EFB4A8F29EBECEF2726938606D2562B4ED69044AC08769EC112DCD7D7D54331549C41D7A9A9D9F5B004E4490ED183DF65D917DD1AA8A2B50E86F59576A304606FD527079F60A3D0EC2E36A12D354B6187D1A5301FB1977EA5E5011F3CC02B84BD6A5F21D411B4BB276129A81AE6471EFF6432427A191134542EF23CBFA2E32D2007C2637A189D7AF0A7D3990BAE139BCD2E225A671740F83856825ABC24F6CE908C4AC1FC3A61AAD816281985AB215AFFD2AB0060B66885168260028090FCFF612A034C68E0B2BC83F33585C3FE403A094DA453ECB21CBEFC03B69AFA16942691759701F101BE11478DD5A4DA021781642D9646040D6539A8A8B15868852E8E233178BF9DF56D048D17A88CC5C5FF875B2AEF274D18164B16CBACF4D2C12C2DE37EDF89A76E4273C7F888820B5C56699AFA1D2322D399010926DD5363B6755F75EF1AA5C0DB58D92FFDC0D666E2F466490B7FBDD01D2282B014F08581682A8070F48E69670446E0E8A22D388F2C36FE6B4A0958BC20EBD7D6471D89CC45C01CBCF09F3EB54ECFE1C1211F5A5C27D7C12FE983CB1CB02ECA7E7400F700B78346B9A4B669FE0D7B6DD805BA558DB32952C90EFA3E1DAFD68D8A00F5406A9B127B8BABDBE01FD099549A8F006DD30D20E7773027A3A402D8972FF70A02E33F6285D55990F0D378A56F5CB27F22904A37241C23B2284DFF79EC41895ED8D37EAA794D45C1AD60F6730F423F874AC4F2DCD82539E0EEBA01FA3B1EA2042E31999291E470606C96C23CFF97270972D0CA855DCF5BAA7CAE8205932D42012B0DE47201218528A76C21E5C0685FF03306656A6E5BB15494AA2BE9F01CB9FD740B8B0FF27C852665087EEE29806EF19265EE458275AF2BBEB9848D2E1825E617AE07D14A8B3C1C270F0FB607EA823EED616B90065F2BD545A0F6782E4491994A57D785D40CC92742AE7CCCCF12459461415449C8E59F44A8799CBADB6EB8AC5E0DE34DE602FD536BECA0C2A5DCACB9AA8A46843921A382DFFAF4381776C2EC6A588437D908F0639FA2F23C997FEF001262C996B7E28E074B7A1D2B217FC28E9C72333C89577CE807333F1255095E624530DF50FFF3E3FCF5CC25505E294A022E439611827C869E5D13540348EC4BAEEDF3DCCDD78D771AFB3978D82DA1799A930EEF91CFB315521CD70B194E413FDD1635DBCD193916C3C659F61DAC973A879F189D696D3F175FBBBF0FFAE496A5668A6E20458C9920794B0DDE8D06627AD4E224E112AEFD59BD32AE37BA750624D5AB84611D8031A3C3A377B10E2BCBA5E12AA23D3DFFE6BAF03FFC5BE4EE39E6612F917DA9215CE479AD49F59A34353EF65E82DBE07FC3E9C8D92EE011A5879DC5C9AB26EAC415D520DD2B72DA37E948C56AA177CDDD4B7DA86D1F6E739FEBD5EF78EBDCABEDF4E159D15DC81F2C9EB46079E1DF3010B133CE46CAD6350FB83833D4C33AE8FE4653B4A441800AFE90D4F0CF74C4716FDAC1FA292DA454791CA823136EE844CDC153FF4AB5B2FBBD2924B822A2EA96254CA33C2837041B70B20A3B15830EF876008BE6A8E412CFA7207B35EA6185A7A1AC2B81B4A6EF72A1C2B105836D49B7F96CC9E219D3511FBECCB704DB704961E669EB3FA517A7686DD118AEF575BD351AEC67477283344ED69C0F5308F8B1F82E3DC7A5029542E2F991242B179E92201AB8AE951C0198410A5A5C7C4CAD7CA714D9D706D2F7E0F9E4E2F04CFCDB4A3316F7984AF20F4D2A5BFD44D1B1D043954DA9D6DAD6A53E6B9F3574FD8D98B3DD7C207ACC73118C6C76EDFDE760E87AC11AC8B45F5B654C256FE61CC7F19DBF91E17CAC7261A9D3FED328E2DEAEB1EC2E8AC6865D339922892C680C84C66FAE7CA866468A67BD7AC99E532BDB02A687F3E7DC1DF7B6321598C0CDB20C994F2C1D84B601D8C497264396040670710A7FACB3F245E32044F988F6534766081480EB66208A03BC1B39DAA90200A98A0CB3965FD17031252F9D8E1BA3E5A555195BBFF408C899B138E5EF0F5F83B80AF8B9EE51C7264B2EA53A429CDD28C67020FA23E5D84165409B5EB01D091918648BD630DFF02CB082DF2FFF46E7674EC85F8630D38F5814879EA3B4634B2B60E73AD8540904A4D1AA123F2B21C3607EBD8BC49C4CFB36059E0AB14A528152552611A3B542A31A11FC238BD954A38D671DEB393D8953F0232A5FC11FC99E169B0B47928FE5342C3759CF052DA0C40CC39CBDA11D9C7FC05ACE2AB35454B2BB3F44C647499CC55174085BAC97FC4051E18E48D93F35FCD6DE8CA0FB468B7A5429C3A5845EFD379686F59B5FEBD931CD9AE932336AACC05E2840A8C599A560C25570C1F4B0D4638FF832628A7D9BD88FAB4E94A185C05FD8919C91B9D44FA4B52DCF678DD0182B9F2D3628E751DDB91F3B60C29D5A0B29E745EA2A99C84471E1B0957F1B2C591032BECD263038ACF0AE3BFEF0F28CCA64453CA4A02CB58752AE9C1E3AB98363FCBDA22A23C4B070AE3B92B9145B3C5BBF3B08BE93C42632A54ED8D728F84C5522B313C007B74605BC965A5B2B2C556A12B4D8CBAD54F370E86052C63CF26BB83EB430AD5482C8EC7DAAF302063A455878DAF56D8C93A4C6D34F82ADB4CBFD4A8BB8E3E6E7FC1F2627416ED0021E43516C81B4B6CCF5F822455860779D032033719DC80000000000000000000000000000000000000000070D131A202B3137""") +16c069f82e6f6efe9eb825ae1b6e908e32c28e3b0ffc443e9472356bb19fe58378012592c1afc414e0ff970a13a9b8cb51b968a7ba9a2f7d0c326b5e1d074f5af742c2b548f87b8cf1baf45f86000801486773a4240372f8f1c05e0e9ceb1bf5f18556c62765cd06c472781f73f6c766b44c2f94e436eaedf8612cd1fe381e645689cb6e7befaf031823029f5a6d8913e2245fec9159995956825ee81fd66ecac65d960506f2b3f58aa4e9a6606bae585205b351c5654b9ff455b08aa9ac45ad3b20e7619a3383913defcc42c0d25acb6aa2f3d4e17e4febb6dcb59c31e853fc5db50770059aa70d8d3c58d3b98efea00f9756260d843cfda0c079fbbd4933ff8512ea6e379b7b1b92ed4146cd0135b2c8ac61496cc70b55de5eff005a310eaf50ea88666e342850ec6c22d2d5cfdeaeea40321c8278e341b8422bafdfe71b42cd3483d71df4c1ac8bb0c86a72480055d272dff99203919fc2a7836adc985befb8025e6e491957159183949343d316004c075332466101f14aa78296cba1072799d978c1b36e94f042eec38b989e0c7e40db362fbccdbdb56236397435b65b12cce3f13bf55abc805973dde8f9c65157c3a3751209afd01396ebd7bb20fc16229ab289848c1aa48f5bf86791468df8950ebb317d72c050270f275cc219faad9980c69c377679c4e137810813734726ec78ce545199e43552ed33ab3689b6ac18fc54fe847af97fff3e2d6fd2bd6885fb675278c4d897b507d37b5cd1eb291d6195c03b5beaecfd90244a497c69345f70a118f88ed8568386b1af2bd23c9d0f2763c19b669a7378c42942a242c3721c59a5c0390137077ab10d792e2670da72dcae6042778d691ed96dbe126c2ac03e6f5a71eb1cc363997ce106c6111e3ddf50da12a23447af30d684548536c2402b60b75805cd0a8ff2ce7b4d7863a0baffd5c0b98df8dbe6fecdc37b2c882027f0d5b78ba3bc35a352d419978bee8f39faf096d31196590c415044500140e8ca976340496f084eef29a1a1fdd8df215da732f37e140aa48aaa393e5d3af9b266f98f5ed1410c9b4c88936f1e2b225a6e1c99ee9ddb7aab09b55be15aff94d2f43a8ba09d673b5d1327ea95f42fd26b4e13cd02a6a26c0d20fca8dbea95e71a9d9b6ce80fce8c7c0cf0ccea591916e4b9eceb3b42645615a40fd063d1e0c7753211ffca88a67b3029d6f7e387b11ca34d5357df38f5d92042b2f9a7d8d27ef6c8ebbce9377568cdbdb146d2e15858cd7133b5cf242406a857e4247462d87994959ab3b350cbdbe521f81b9375ee660b53eb534195a7cb0751c54f3af3ba72ef2cb3aa6c748270a64b17685d046641c20156575846e42b93fb1c754140ed6a6a02df039cffd970c21349e2bbcb6323815f1849d38052e6bb143d11890518da4a213434b820c79994586638b70d6c006acd43e43a79821478bba9ec09f9442fb15308d01f533c460b70a28c710da2b3f4ac7449129081081c4c87a241ab2f9483add71974846a3f32c3c96a08ad090098f38021fdfeaf50a36261c728aa6395b2114a88cf9577793cc7bfe45a7e238b997bd35b2ffb0c3992f188de916f7c004c5f83da5aac274a47bb7348df3590668efe9c2503b2c316dc074262fe874ea700b93a9d2545ad3e22b395d294bca1a2b5615d259744c56cd3d736be2c4624a1302cd31ef33f75373d2bf8b22a9e85db1df34ea4d24f0593cf9d494ede243517e2618dd0a6bbd0ff46987995805ccc3439e39babab22a53893223e25eff5276ff7a5eaffb88fdd248f3b2a4936ae56bfac6d778126930b25f05bbf031fb0574aaa129e4614eb1a38171e9d19b7fa0ca5fe7b4860ae3447bf2de8a89b8d0e85c7e130bdeb0f40e6326b1167f744e2b664e370f8a9d31f662364f442f1cda1da1f9437ae6255367e242253a325de08f6a12774612997a2f8b2a6a6e084ba51a07947ee7f4eb68545594756582be6232224172439c1105f46da151fcf9ca328497f952151b38631f4797f6d6ba367ee502dac0b1c5f45137578a5fa947e311cc84b73c56f058a1265ca45c10423aa165f08c53bbbc7ea42309297f7f37a98d146c48a7cbb566e005b76ec243ce6f7b9231428cfc17eb4b1e0b8d3002628e3ed7bda600a5840d4c1b2fd97024bf2f9ed637b521e8e1645400a7037ce6db2bb696b604d6b5f4b40a9e4eb443517c00a5ac6c1859dd18b6fb772155f2d8be3099b638602bdb9e3941d31bbbba3cc52d7060f7b45416c9923ee3697caf14e7f51361051bcd540cda6a14a71cb62e033603bc9d58ecb39ade2144b13d1746f0de2d1742cb6b34d91917adb69634084e08b9b37dd2c62f55eb64ca81a60ab5b71bcafe2c42f9c8d9ce59e6be9c2f0019c3d96c6ab738cc9df2976f0b9c47579fcc2d72161317c541d5f7de0bdc19b6f7d3264db1079cf3deb1619fb6531aa0032b19d2cb2ccef9fd6c1149c12b701cf8387768c6eb004fa6bb876f7ec010abfcf631caa27cf36d30c1738d50e868214ff8989ad497d0b12ed2ae83be1772a531610e4698bd721630dc427f07bf6b4356d720f335ea66969d14b246b757ddd96d1607dcc72d9d36fb10f9a529056255b9f962ba7a02950a0b9c988fd381d801af73d7d9abdd842cac56a77c5e2a9ab91785ad17966a2fc31e42a663ac583488081c236d13b82b09933afc57e25847f8511b0cfcf472ca6b21898ae47ca8fe674a55f8737053ddcf963dce0568839660b47f2dfc9eaced787aab897d16cf1a1e969f4e5fff7a8ec5c3ca33b6047fccd8d32f4c3a61d2c69075e37640d9120330cdb9732ea9325e4fab3e94ed580fc5be75acfb14468fd12f6e4cf87a7ac340f990e33ee4e1d2cc48a793c8c480b59fcc4bec660d101fa1c61a50b423c16c09a29d2dfce1d2011d4e4cae986e4822090379c17ff077cf56d72478a9bd703c2ea037ee7419b8b4464388d3bcd5544d3a2ebf12be85917021388950c180f2b020ed1d6dcb3a7e0770c7c1f5a44030bb4076e568996c307182b103050bd43ae645aa96be787f1d82cdbd629220104bc5167c0a8b8436d828cd70d34c9ab0c039cdb0a1ef137783e92bd7eac1c995268ada3e1e8a494fb00c5d678f5b6010c8687b57bde36d001452b0a73912f6ad0f7076481210a975b44410fceacd0699fcf7c1489e42728ad705600cfe6c2267a9c7979274e73bc2aab80155fa561390cc9460a93f29c4db673b00dd95d5421b8c9ab003fa7b48f82fd6bfaa264f0debe6af3aae7716b66c5533c94bc595e646c38b004bfd638e261b14562ae061164db1716208f79e5ec5e457a9ec47d2b0b7b7b68a62c95de164217b7472fe600a52a3aac43775f267832bf98ee2112ca9db28be3e8a828bb1ac676178ed490e0d27fae273a7d1de1fbca15aabd065890467ad7d4648487c525bf1ded91ae1bd3a99c6c734d580c69895dff04f3409c2f7a3e0416b8a2c53c75dacaa8bc020c803ad12e8a48f850737fe8d88f08643bb6863ae7b23103b0037255cf87f27aecaa703db904d789c61147b8307928bb184bf94ea902f14032d3ab1d6d13066ef6dcfd80cbf155f68024fd9fe95ffa782b2de5c97e1027e7f794c4ad6a2c23e3b5c2de5289a1f96a4f549dd32e9e4cc07771da9d1c170a315ef9d6846bf10dc97c1ec7b748b5cdcecab920d93bcb5a706b23e70bda6ac80b8efc06eb3594e5edfa4326caf3afab8cbd479f5c689e86e20247a42e828e589d831a6f1b2eeaf747f903100540ae7d725b0e48a3d921c303e13cb2a3ab5f8cc20502b90ffbdd69cb42ec092cd2a24ae408436e77565084a7bc20742fe0983744d7c876b646b1385a383bec18fabda857b91088b8c7fdb5ac5591bfd8b4f5c8f880509d0b6a54ce45d15c639f3b818508c08e6ed4a37497b2080364ddf01465df73e2e91a7a9424b10ed9a6bf1f05bf559eced1d0b667c35885c43db657520609a3f55017f8ab363fd83ff7a88974aec48d9b359d25ac9e201302102b8e62ec176918449e7fb745ef5dfc03381237e259f4cf200714830b2ccc4925afed71a4b956d1bc55b9aacfd42aefd9d4815a6e1f6151fdc9379e34faf98911e2d5a64152c426c0e8f386e06a86190fd5aff238128a62f07e02934356511cfa2212cfe3df6d5c87cdef644e7a78b34a95dde40002d4fdb43243a2f33cd3bcbe00d3503451073c3b13bc772f98a579c72116f57f7bbd07f966bafea91fe80541acc19e4010723daf868ea6b5760e66d317090ae218f57ad67c2992b36e84d513052eceee456c29cf57b8336516148ce3835d6ca526913cce6acb9a6fa1e0ecbfd9f34609a6751367c07a6017a78e078f2627e9f7be020482731cb93e778728e0a35a7f5bb2d6c4c9e893f0f7581effe6881f645223b699367feb54b8bae06a68e025a9d8ff507efb1ee6a0b9a74b14d47c8c32a4188f98d9b359ad1dc9967d19aa737355356442e659db0097635fd03e6d2f629380a5a6394e28a13ff69f36ea8f0fc4b70d2d002500f988db49c8d4da0a71e720be07034ebb3389b2c75e3c6254a82e2e841ea0c99755dff1ae01e51367d4e02eecd304932510a947f948007414e2bac773d7359243b8bb9e973cd4a11f7e6406f450e42416ad0927b133e0767adf949efc3dcabd9b523dd92b63add6c12d211edda7dcc73deefa427ac96b72589ae0c9808e7bf62ac31ed8aa5bbbdb33db466bf8a33a7e3b170058b1cfe84c96eacf005ad0796aba2c994c375b79862fcb6cae4d13bad1dab2b838c657a55f85b988892f62c3581cf60f24478735c04288c1fa09896e7fccfe1a102daa51c24924ce9ea1ef8831c91d526a55ba7ef2149e0a5045d8362329b6e3487ce8a7f0c33a428149c55543bbaea26b533ac8103820d405138c17510970cf367b3e3a4c46822d10e05ed47ba4c3bcdd02eb7e4fd990da55a518761335f9d2efa6878f8d0e29b2704d3af11dec3f7a8c2fa9a7104e971ecdb7f18d93ad2a1ecdc8a4d1dcf8ccdd66608859438ed23e5179f6594c631103828dc2d9f8c784d2a4cff15c58084318c18571af7940cee704e9f3cd0bc758ae7cf9d70995f1f1422bdbd2bc441831aa72b66253be6ce186f6e93613f2d3888a555b578481ca324878518dd9537e5e1e7b27094dc5114a4e51a776fa8e5e86c556f45145cc3216569c17fe22bfe281579a6fd70334c574d1d7aa5fe461b3c0262830a2afd4b485d348babfe81a3418bacda574019077cfdcbef5de1e73c8a8bc3eb9113713b563da34073670cde452e84866d688ac9f691916bd443b02c8bf15c672e1e75b50156e1e5254fc23e0b0d6fa530435ae5fe06132d691a3e59489c7102aeec1ae9656aa334321b8f07aac206dc80cabc6b3c8aeae941438ff5cfbfc494fe08661ea496b7a81cfc949d60928251ba6217813140d050fa68c34dc58771b80b84e79f469442584db07c6b5ed39a5f83398965b715966a3ade89570b09a501860accccfe10aada86ae989bae9adc4ca7480916e1bd4733d6484959e4cd199086f413c17b61e16f42ad93a85ab8ee86e09fc1dff1087384ad087a6d95dd845e457f740e538faea88985df42fa2e0ad89c8885de6e0b1514cdfff9e86364dd37ae591a1843f60f71b8e8b6aedc3155ce76d1fd9c4a20d077050d7942e8369cfd9e0cbc19e62e32d15edd34b7f2645dc31c1de6ac3c36c5850d43a6c479e7680f02e23c8870c1730ad163dd31d38e1e7de492ffebab9f3366e85dc9ff42dbdd1eee8bf448abc8017a2bcee2367e958a01986fe9d7083e45e262595937e3287b499090d4ff466f52824b032428757eac7756ffe76ad43e6f70c98b4e0769ab91695a6ead1a1ed45ee36218dfbc4994b7e5227f0fa0536a9b73b01701d10f97d0c4b1bc9adfe7c2bda52e8e042b976a0ba1b9d988acacf9481831cf6881e70b21520cb0abfbca56bc3fde95dfc84de3b3aa9d4f598dc5aea2473ab0b2d9758b4bcf353c3fc2c6a7e487cdf1af90ba9b5a464539e788b86077ad0ef611a2910f784d72c75169ca095e14e4916c346e55cc1bf042b0d578d2923580709536adf49bbcbb7fee7d4c8a61fb39dcac21ee50f80a7bc76e82b285b0bc3f0b0fc9e70563e82ae65345d521a5ecbe211dc07acfc85f707c6d23326124eae586bf2fc77b6021630ccdb6dab8569b00374a1623f1a99138b870bc25d20911836d1aa907e9029436cf0d17dbc9bb350ecaed0bcbf4d48a4a7cb78e602e33d13f243347496765c40c8b786d8bd4ae6d9eb6ab879d4f56a004f9d6a3b6e98e2ab72296b546cc34abb697e7eceea1273f7d8658e60112932673e090be0c212d3d664237b91714d93edc6c86ec4a3c98731f7c102652015d58abca17b412ba07502d79ba43963dabc05bcff231d342951f36dbf8f8097e363595dcf7141215284cb4517474a85e0f0212c2e3c687d868794d51d1fa9b0cf102a62a3de0e2082848b90f31f203291b8bbbcd0eeff6b769095ebf9ff344ca7dee7eb000000000000000000000000000000000000000610151a212b3238""") ), new SigGenTestCase( TestUtils.hexDecode(""" -435FA0487592C90055BDC2DA68F33959F690A4F2724A4363262E2DF99A6073EF6EA41B044DA7B536B18FB802026B7A0DBFE4A80D41CAC87FD98B09A9AE370EF97FA99BD302424B43DA240CF31FD918246429B393D5EA9E01963E7B03547A6E19282B86CBB267B1038DFBBC3AD915C4997F7547CA709F68F4E8534A0E54FDBCC650B690D12005CC14444CC088E2120E43C0511BC391D844721BC6900A0744D930215C082E83066590462164245003A720422209044308129740424888C226615CB831800432983464C844051A3268D148501B326020970008C10101810D0BA41054300299204D0045662245494832104A844D09B9500438701BB889C80248844202191701C0B805422048DAA245A202060A4021DC006A110085A238092496494000411C968181808024B7696086480288701C9811900209A012814AA084CB122481300008314C49124940A62098286D99326E0906299C3804E082294AB09140A84508019011237019171023A45018B491C01601CCC609012601A1884991A06CE4268561120E1CA840CC120D0CA920491048A0A261E3047089460519B6248B446C5C306D5B8608C388444A428123144243C669DC44080CA660DC826D99C885A31092E0446D1BA605C9C870D9A085633269921866DC34508B305158C4211A496049384DA438294192045AA24CC31090DC366180C420D930041C0511C3B085098080D9C25121014C63186E4A16262129510A9185C1886D5B48921AA94121C14998162C98844841B444CB1062CC18324400460315440B252E80348092960422B74458004A12010E4106628B486481389012952109377002B008000651883672C1382ECC24201912700234461C2182092421241150A4B28553165101B2710A8770CC983149224E8C1630993046DCA6704A240944324D521224D2907111436923164A24394C18203223970491B0014AA87140A01011394002302812A365199065114521D882640B30061BA220D3082449402599366D22C06101B34199225223B460D8226818100944282218468AC11406DC46864AC005540260A1C02080304E21417050342001342A0A382590186018154522284418C94898A43092323012004C0192619A102CC816004C906524064A44028954144E21B55084B451E2366C12018D42826C233260DC240EA1A8081A896812359224854818352C9B1492532430203192123390A48228D3B281581849D3A6895C086A90A28C610806D0486CA3242A00076911B831030932211026828288022286D2A87193142C64047200B7088C80114398840C058E803265243631049889DA4881E0825000A765C94401A01648909885588628C8142E1A8380102185A3964903B8480A996C4C92319AA269CC864CD088095400260A80510824250083894B02481B108E12304D908449644490CB289012158A1AA724CC384A59360A42422858128E13804CE1124A51B691D0A46CC4328C1B8861080849239584CB9260200661401840E438204A2070C838888C3852214761A308604B04465194914C82010AB4442385612225024186809C2271D2B689D012691CA2458C420A8BB0885A040E9A926509A22881A220DB42695C42224A325050382D9C362A12262C241446212212CA922D9A166224108AD20825CA9844DC0825919045DB402D09A86504201188A629E014310836491489401B4520492449E2203122B46DD3184D600242981400449610C0880481A65188B0804CA4110A2650133802D0960D1B17264A48410807309396218A086610B29101B32459962094968411818118A090A29210D4806158903103018C893850A4B44140C004C0184200210E13012D0249649C14084A2646CA046C0C316DA1882904C02C4B9621082208A404325B264E9CB20D1AA549198484CC10626106291A1481039964C3124481186640326A220402999611A3902C1B097011206C5A342DE1128A88A4801A49401342849B82911A4391082525A3346DD0B2051A852C4800720800840C376510930050A22D5C04711B426D91804C82C241142632C8C86D8B824800B69090C088509060E3420DC41066640640A18401C202210CB32DA0A824919051A1906189202A12806590182149244683B645E19208C212095B96050942682122905AA020CB98091B302D09C410CB368CE3420623226122B070D4A290440841541208D3326694860C0CCA61EB683B44A65D855C8A8CD65BB1DD44C7E676ED115E302FAE539B8D26405CDB80C936C02CA3ADCB2D45237F170BF28E29C52598FD7B1C389A1A03C415B2B5CB096E345354FB26AC5DE65678CFA22BC9EADE8B1AB9863CA97848EC9D5E343F1C6936186D3C9DE36342175D26A5611E46F424D3319F65787FA40EC6E0C29162F572DAD37CCA44005DA35F5C85920C0463C266C502D2BBD9A697C0E69336290C5818A692CA61F1D60487043756B9F8FB16B807E918C4DA8B0F3360FAC63809682839FA7B52296BCD67F98B5FC0691184670D463143AD983A1ADB5F1AFC845A6FFF947DE0A98CBA74D06387F0BA27FB7F45BF49E89BA49EE6BE6D8F712F976C0C0971B766AD7AACC39C0ECCC4D2F2046E3390076989789C4E8C9FEE60567BB71DEE7CAB410CC1A9AB8D0751E5204D2AE85E38786FE3F436E8818FF7DA12949B52E9D4A3ACFE5E738163BFDDA76965FBD9FE49FE834A0B8C27AD5A00522D0B515E019E4CE8808A828597F25F2973DCAEA91F99F4EAAA101C41B9D9E303C22349FB39E7DFFB916443FBF9F9F231D6A615ABB5DAC5C63636B36D0E493A66930CD8C18B8E30B51E2F35B19B7D0C6118C9CA787F65148A3953DBA871A2B2105052DAF29C09DED9D838448E7459948501A6612013C599F51EA8BFAFDAEE41C94AECA8643623F46CC19A33A20191A9EB4FF98F484A86F7FB60864D5B4DB538A0FE14D6D12FDA1629B2D6BE674A242FF199F3567623C7BB649E229281C2BC355CD19C577A38614267471EAF4A46DE3FED534E150EA30D14E4CCB2C10B5F8CA2B8086B5B6748CC76065CEE5E96B4BB75649247164DCB67750B9597CF7F0C4A883B8D255375B048FB156F4B1E587B7387BA3B5452204F76CDA6DDBA7668284EEEEDFF0A504E19B737D733CAD1503DB662ACF2BBC9B64542EB1EE2D3A589A2DB224188FAF5BB8369245839449AE58C84D907E0F34FA83FABB302ED92BEDF217903C5769581AE4D783D545A8F3DC924119BD7998CE47919824AB5590A74C5AFD2D0A484232408710EED75ACD8E2671CAD9FC7A65788D6E988A621AB764E2B8B7C35D77ADAA684DDAB63B72316861F593609768AC761782E40B4C81D84169E04EF527B631269EC3F787143623311C7181B383FA6ECE49E11722A6C5A5900193E2427B56E961449874240E4E23523BA8B321BE7A0D984E1E84BC51D3844593CC56E61A6EB08F9107A097CDB8CE39FAB34DDD12DCC3475171FE0145152F44B4AE66E4D0226ED9BE6DA532C04DEE1162AE6692F8F94DBFF4A8141CA11936F1D2FD56CD9244036C73CE0B6EE0203CD328A5E1A04E0F6DEBB5FA6D648598EF1F0EFB0D05A16EFF32D527BBABD964425135105E67D0418BB17C3C5E4C53597C5CC9B6CC27B0139B61EF053DE290F511D7C39393A6B8C5D8FA46119C93E79AD18657B199A35A01CC48AD090CD6A68F84CD512A44514F997353A43F1807221B29BFEA62B5FEECC1F9388CB72FEBD181C49BA1DD96FCF24A6116A62563F8088148D5CF697CDF140EB000FBBE2B54FFCC36CD5B90E92AB4BC8B5D6D4C47C74C5329E70D87D8361A3484DCECB0C018C1A9EB6DB8094B8C7E0F8E5B1682948F76BBCFAA1D80C5CDAA1650428E2E1409DECFA7A1AD4AD428469B6A750C74297C46C7F216827197F775CD8D12280193E0471BC7449D8EB97A4B6EE40C5D73DE0C14293DA0B4C40C9543C284F251C2D4ACD332289D10442B72C3FBC564C092F3D0FC86F71E4E4228D7E746EF2153CF2A2FDCFE50E8699A7F5374B872EE9494D5A00BC50D7D9B356F9DBCB7DF82475AC89A88C6515ECF1F2989745EE765D4B347CF8A2BB358579B7C09C797A339CD744E8A69646B122F7C5386634B5F69C2CFE791DDE0EA8540DBD30187C9AA5737B728011160DA202D96D56E21BD38DD33EEA68CF5BF69FC64985FDAD57F329CDEDACE0C8103AACEAFE3AA1CC3F0A79934F6E57B8B5EA73F2DCBD0B4FBA7A7FE06C6707DC5549E0567FA09D1FF4829D127A5B427F2ED0C071A3FB317088B689DE3585240E74CF8920AFAC2E82F16541863DBBFB7FFCDCEF75F43C186DD87C91D917F4B9A25E8AD13FD4D771A427BC43A27054CCA599AFD0F5864B3C92EF3D0F29A5B43079C09BC6BD9A7F8C6757BBC2C99A944AF3A0C34D56C91637B6CD7331FFCDEE817DB1F91F30B5685361DC8C58007FC2A95DE3BE0EE011859652F72A0892DE1FF0B21E81F6155613D0A6A58A5F91272EC3FA864EE9BBCF875405D9CC9F103D0BE1F4CFEE618EB7C9F872FC1DB88DE967CE96B9C6ED273D1916D25A07702CD27D61162FEE2646F7B147EED996F817B0CF5EF4939FE7D13D653D3A8FF35427B50C0FA54E1788CBBFF7EFE8CFD7B7FC17963CFBC817FA2D75E9FE199AD0A92CA95A0AE769D40E71B7D61D4EC90A69FE28003844A0117538FC5CBE6F1B4C65B41D9161477C23D9F601B7B40A8AD23D79699A8A28271C000F160998FFFCEA6B0242ED8449C692AE85B64D3FB0C0DD3F0EEC1FDE20143504043D63EB4DB27DB8C3FB1A9605D1C13EDAB1025784FAA92BE63714F8A013AF297BC0C56AA291A0236E444B197704A03577AE59246F46EE4AC61A0FD9781F13DBFA5BA07E956DC9F7018EF0814B9C5F6F5EE95654D6D222BF1CD75843FC1482A8445C73AA2A82345904FEDEFF0EAABDF4F1936765A2FEE895F8A933A88C485FB39F1D36C9C6C3194B46E9DDF80B5F0C3F63A10C4E2C064D6D81FB4C9243A2C8449272C1B2066BC8E8662DC7130F940EA2B5BE2E7A5E31E1C7919F09FE277B7C0425C4477AC534E083789AD5FD06976D13DD229E93DF2EA8FCD22B501EA1D6A31BDCC34C225C858E6C307368F09071963A431F5DAA9C9CA5C5195AD9545DF69989E23871DB3D6BC793E5CCFEF6D9FF60912CD554416052E3D72865BD9AED12F48FFC38F6E9F0349566692D0E1711005C5925D3F679D6B118EFFA63CFE7C0892BC58A98FC64E1D0853F515CEB10693BC9D25960038A3F0F12D108D0094F0D4AB855847DB4F8B9D334D76589CE2A0F9C17A297FF5429F239DF27899C38C6BB426E459572A4620802BB55210E74D0B23334AB8686F2F0A078BA7668235E60E487F494165BE8BAA98565D7312357E7123443D9E161E663EA4E1F6F46BF36FE77D06A220D6CC7741C96C20925A99D7919588A21AE79F6F279E23D54CFC3BBB14A189974AA6E74853A494E780492F466AB4B49678F66A4C619C3E9BE8B904E9E6B3A0BAA7539C975E23FABE9BC401A4EC308239C73E9419C686A12741D5E75D940F6C59425C20137FC8F7A36E12241CCB1C3C97CC2C6D593C3FA81BF431C976C3369BEC74785BAEC41F8A671B983775416978AB2A779B907D76BEC0B25202ACCFAC15C9EC0CE171C330A1D2079892A4F5AE3F203A941F643C3C50CFF426BEF5833996312D8E34F4C606A9183A9B959136B7CB151E4EEB84361DA76A518285790BA43ECDED59377AB75B2E221D23C8CE880528A24C0E237A7A64FCC4D90BC0508C092D25F3F429A49F8FBE908497122BD8D2DE287FFA11273B61534448061426D37F960CD06A94E374AB6D7F3C69125F2FAA9B76F8A82E32AD4905BA7925415F0BB497F546191F4C6F5283E73D826733F1B6EA5B73A9C3874887E46D7F5BAA12BBAE84474CA1EABD2A5E83DBA51145D723B670187A2D54467ECB82C83F08636586D962147AF49C5AF9971B2F0F391F79FB96E2714C3D559D196511627487DAC91F0C011C8E3D73A6274DE801BE34762FFE9D030AD0282CE0DB79F1FF2543BD92E9EBC0317189C7883450EAF7DC8CAA45554D5E1359BAB98EF23E75A832B1477AFC4BE66C5160FF49E6F50B88EEF8DFC5F4C97BCCEB5BE1A1E9D0866DC8477C6C6F937D7D458CD7356A8770B4513767B2B4D9A8D29D763EF80698CE2605D0716DB6793FC46F46DD361AAB79DDC2EF6E41A1EA9D0A912BBCDA555DF3DE04C09F6AE1154306BCF9BD366FA43A1FC73CBDF41C0D46978C4BE84E999A94F9B36FDF1ECD0F6DD24A974E7719C3D63D6637BC317589EAC60BDEDE1208E05EC87FE382D0EA7179B713EF9C5DE38631081181C8D2E86A6957E5D75B2DB09CA1C1A6A6F6797F059760866B7585F0E2C6754237980B0973486C63DCD260E5846A23A7C9C45053078E0A1CCB4535F3CEADB65CACF20E74755179AA370F4214D81E9425261CBD181D25F192454B1E3BD890518C56D43CF46B2E57662E1BF523D864A6A705EC23F3B57578283807349261BC38FBB0D856BDEEBB18B545C96530722039F129D79F9784B99A960D32598C54FDD6D3F62248EB61DE26BFD73C584FAB4ED339AD7ED4062596E7908C2111E367352338AA3FDCA8248A6958CD153C395546C258DAD42C0FFAE0E5145F14F9883706EA9DA06AEBF193F02B03F27E261DA3A46E13DBE6F20A319230BE1A6E480C159B85261C74A0A4956799D03C70396F9B0F7605A54E4F2A928C7F68A2D4EBC5F930BC381EC7E347706F27C44CDA560A75623324B6C0415B4E78CEB6467BC987845917F63849F2DC6467154E65C8F14BD7D5FDD23547EA2E10DE39EC26C13AA36AC27728826CFB29723EEF5F3CB62809BF3FCBB0DBE718704CAD9AACE7EEAF4E56FF90DBB3E0F383B3F71166C25923580BF42364DD5050DDEF64B48337E0AECE1384DAFD79A00D7903E7B16885AE76134750B9E9E4654C819979E94296EAAA6EA011BC6D6"""), +a01e3186a88928fad593837cd6f24d201ab8aa8cd445521805be6ad197e670b8119552cd53b89c7240f90d6338b72556b13b536a015192d33c5cd605381bbc81a8b98cc0eba107cd87de9f70329dd0fd02079212805b9160fc2a5a9a60d441e3ba26dddb791b77640f153b1b81f3e48274f1d040fbe3bbcac672adc977b3de8fcb26892097491c424624b08419936809c44980422d0bc52858c04d12246de036900b1552c92082e212294a1491d482006244014a884d5284810b928513c5042290485a462608c7086192118b88699ba621a1484823148ecc442e44189091b6090b4701d016901a036218a920a40622d0220611b18110164e8a022c9288410b2690d9882101118551803020392ad188245ba23113110ad4c808d0a281e404026246519b9889a3c068a2b6115a326208344a11c3895a982843940c03021121356c0a218accb24421c42900480aa2004990808002496513010d882011c1386520430644b22d00928c52224a00a8099c822881224020168d031166c49204012011e3104a044641598081414665d31422080788990884d9026588224610812c88462888c44511908014846180162041480a0aa3891c345023b1509c826508c1011c8485a1480502223123464c40304a11256e0312244cb88880226891b4801a21500c27840cc300c2c64082182e40a620589044e1a251c3166d5b964d98820404152180a0649a1862e43812a1b84d503005033989020324d9844514420d24a14424830488949101c22ca3067014284a89340458360c92267282968549482223c50980865040448d09812100048c08a24d021382849604003286c8424ec9464c1c308a193046a0828c18b62543420401c4205b90815b084d220268081405c1980022092c00a1114002819b967001b00520234911c6219092881b8410e1300881840d0a040091a445c99285011330d84850a0b6711888611038108c3472c40040a4326843b0610c186a000600c2a601dcb480240386a000058ab6440cc281182769134565131090c4101201498a10b10922a1511aa92cda28251a844d4a06715c3600198490e2941124176a94164c4212490b0765c1c80c2006240ab38954042c43422601434ce1c44d1ac450c1b040112141c3c461191531e4882c1b260d10118148084e238790caa04d01040d032284c9028d0cc05061a20d8b884082282141b6080c208d993640880229d1a66512c988832828e44022881031c1266554306d19231049804153882c1a9745db264813364dc13851442430dc886c00c349014306221008d296241b124a41128219c705c490898b16209aa06841b48022985059066501801160285101c1459994889b84800c02809c4482099661d4c45063a001e28869413870a1b42118144d90c848581846132966c1380060b41120008409326c442270443600184010e42692a124901a072adb125210498220379124c52c84c2840a3849e380410b2389092892d4a071a2b28000c511d4461151367010b08943088c6110720a014502002611b650d182250a24040383099c3091e39830d1b471818249d21680c44600a4c0209836488912851b920cc222660b302112050918b384193862dac229cc800c62c4681a990920962c10834de2842908222aa132821b09856132512015701b1484a440650b4790dcc8801a10311813404186808292494812698c2470981826a0886d14314602a36003289120098823062ad3268ce20451148970d3366c02a6681245454a3092a4186a5a90111b3864c2109191368e440882008344d2920c143149d4206659404d219444e3325190a0899a322d0cc530c010928c408000162413186c204872d8428404306e18a00cd4b24118c8701b22681b266821c9254c1288220091d4c009191950d8c6081111262388881cc8041125460aa8449c444588124ce4a42d03a311e4b88858928c18966c241521da887023264081100540946403a36864b00149b489dc26614ca440211342d2465214456c59224d0c052882b43159125121120844a049d040290cb270110711d932645b060620216089228c03a911caa464c42401029749c9205098483283b06c19290e61b24044a688448681593810411048c4c22149104591101010c6501a3940cab47120a22084802552b011422050424804d1808d0849324088044200081b804d9136922feecd418babb28c61376c9c351e1bc00c8a240f716116db00b6eccbfdbf5ef2f846486c0b7924448d1d803c741615efea5fcc8e10c6d62b9610bbb81ee811d7893c49735721a490539c6fc0fcbaa4e39437bcf193288a48dfd1a9c0904bc7ead823acfc3c3a8a0d794185088ee6f2d2c3d52c1ffe802dfc3c6e174cdcaf2e9157c43dd2a1ab564566458ba32e883df122b81139981cb3c39d0fbc5ef8d99976f3ca7da7774be9356083ee8a62cd1fb2cb75992485d99e06c3b80e730ae834ba0e9712b03b5043ec23ccff02818b633d08adbfbbca8c73fdc2e13987e7e41059992305dba7197107436c150f7d6d32d5287f9525fc223abacd6b738e5c9e0224f782d572cace63db70ad231c4b4f847813b83f7fc3bfa1773be383ff9ee5f2f4fb6cf285aa29c85f79354c5aebc52ef273a18906ff1c8090772ad99c2b36ac609ce4dadc7bdb5413da59318dc99467c2fa50824362f1d3a90b5687e0a538806c376b66c9c51279429bdf512a95aaf44a6a111d8965155138e204115830bbaed35e48f49a11a005b158d50d9817888aa6c5d0850975a2e83672653b4e96b3714dfd0e7ee462d9e102e68cde6b74a7c2db937139b45bb0a7a5cdec9c78c05c87b3911bc62793ba5b30be3ddcb8f53df6819a5c3caf15d5feffb2a9e604cd56565685cf1073c4a6a055d79f7611f0787a9f14c986fc3bd355aa2798d5b5a82e3455e372bf3a7c464b9df7f7b9afd3f79e897d2289ec7e671b31908dd6922fe5095e78a59295e11bfc99b439199ba20999d792a71bf6c89fd4bab83831a82867ff448a05153f0c08829c8f60651a0bcb758390596686dad84d89b1cbe0f5789b9927bebc1548da0469324aa11c78ff3f71b1ceee67a7b081fa27568e1a931a01c401e28fd054c2c9e06f77486cb1ca8d63f0f9005711391617a8a5492d84fea3bc6fce46bf4dbb35d0533fbf71b84724fa7d633c06855981f6fedf5d27c659d7db2d15c7f5f61bb3543df201e314d29433aa35ae101fb46ba5a72b6c222e5a5e953e3f057c5d8c0e2a22ffb01bc79353fd5d5078e66f110a4053c04a541e6bd274ec4e3d33bf93490564ee3c0fe3eabcaced466947472314fba5fa531cd49b94cd1924924d00503e681a280762f18c05b3e26fe8cb68b40ac0149e1fb912eae03101c763f7b3ff32dae52b9c5c7d616c6c0243536a6f1f5a2b9c68257f3f3f33c966c2892a42940b20a29cd52e418484ffb4f956023e464c60b762580208a340056aea262b14c70bcd5518071d514ab5899f9da5f06c4cb49df15d2bbf9c0da6f65842604861769fe51695bf0c37f986a6f71b75fa7799b24c1b7b04a6f3f5db7d9d3083c503d0a4d35470010cd06ec41e2dd8d071171ee1a3f55077f405b58be9a57e772583f35c4cdfc15cbac417ed746b8117d906df3374d41c48b892dddf227069a6d3e74547e8e197f1a52d4243f124b7505310916e02b3d12a9b67f9def13b19abc0b5047ba0ccff1f2ee7b4a45d820b70c365bdfa6c43affeec05a804f60b95743a40f89af27fc68655f0cde5275b4fc29de0f924d16ba08d1769f97c204773c1ce0024a75bada5480beea6118b9d0ca14b1ae13bc3bc1d5b5c3862738f912aefe10bd34a0f2d7ef421906741b7555a1b1e466f962178210826b67f96dcfe906fb42aa1562d228dec1c3602d1317f2fa064f687387bbc54def6d2ab3cf56c5eee183394e0aa3e9b713631023858156cd6e653dc0f7ac14a352e74777d610ccb627df440f9813f32037176a6d829da5d1e96798c4e11d593fb11703929bce06539f62c3a240ff8ca0afc48295b862181fe5f18561f8afec8d04cef4a21c4d722ef1f28a576c1d3b7ef34b2b929b7413a6cfe17d427a48cc63ecc57a6c319e29a680221dd170a09e5ca741931579159183ab153502131b526e64cb3d9dd2e54d97aa55592ffddd7579596a7c914cd4eb58206bae6ca45ae77fa10bf594551c8fe54e3d19ee186f16e9f4095ed00025f60b2d2eb5a51764220396dcb5eaab8579ea0d4758b0b50745ac6f3eff405abea6f79305a45fa60b3c0b985cba79237464487f42159dbaf40678a493995e2cad9b34077b82d121f5d4c09e43c4655cca7cd101f231352d49155c2048ef22668006cc6468c88d18e584e66bf20fbc8158f12da209d5b46004acc588ee5c57798be1c76e2ff042eef7fddad582181589c38e9bbfaf66178f23425582c4cb32847dd6a97d0c68c3090290c4f195308b98eddfdb785d9cbad02da8a75e91040067ea5b39a0ce35ddb8b335954613957d6e20d4c86517ab282fefd5215f3f67bcde507de19f7591eaab854183561e718bd6b5559548a843d695acaf1ee18627c01df6be8739ee0f613cea0715dbe08909698ec70ede5fbd3a2171ba7270f15283ccdd07532ed99fbddedf8e71a5be19af6901d9e6a3c8cf67f5625649c045fe83ceeab6ce4f7815c04196d9df019197637fca994fbd464b90577ee3c71112e48a308a82cd05748f1c8ccae603c5712ac9e3266c14e1fc6517b21d4b4aa0529848015e88fbf8f23791f8281bbd3b0a15f6857567858aaa1c09de9ff64a21bed7280fa3a8da10a00c1e2100c94e0407e44b5426902aaf628e164efee710488c8195d1c893bd45cbd663618596fb6d0177f4df8d1b33433d5f77a00fe9fdddabd3d244a674a59e307d7beeb0635b3b1a5a62c55ae5a517e1c866cb65a3ecf35140a5e196c5022bb8a453a3893bb706cc203d663da21c5f1fab533260ec6e89d0d0c489ff259c5843a318e9e84d1426c4552a8f3a021cf7e80d6983d9004ba0ad05be45e72e5982a9fc2d27537d63002006f828c984029ef9c68395c352791f26b6148523c107ca06a1c0dc8d7bf456523b172f8723a5fa87c2a67a9567fe88bde24287bc4aab8707bb1d0398b06d1102c008d563c7f20da9eec461a399e752ed46330a22cfb6b771207956225a6a2929127cd2b754ccf529ce917895bf163262f373d788ed13fd935c167ee9dc74bdf86d47d96f4f57514c12f5017ad536f7570272fe531327a44b5186814dcb358fa64b74f2deaab4e02a48678334d394911fdde0fe031f33719a38245891bc88251cc3b5f08c0c112311df85094cdf5ad8176dac30e14db04bf08e208571884b6c760262bff7699081fbe3fad6d6dbea91789718375b7ec126cd202ecce6f45a82e6b0366ca4b38e7babf1f4449a1ab10c24af43238d92daef68a306e291662f946ccee2213070be28c6309b60b71750323473bea788a3a62ebcf36a3f0e385f3a8d73bdfb23a11a25b3d9bb788640917174adb18992ba039ebb8952c9cdfadb09175cd9dc99161cd4226c428716cf286a4a46e690a7344a227abffd8a44c45245dfda6dbbbbbfc43f804964f18890d8598c65a8b2190dc64c63c11843c036fbf78f7d474c7cc4e6bb0061c7c895fa3be6f490394e43f2d3299790f0b4df8c95cbd613a6e4fd14c12f12a819944e9dc5ccafc923190cb81e4965b665a054fe8a31706bc946ad02c22ff82f2e907751ae7bd8d2bf79e89a33e06d64fa609449c7e961e36db8932e47136bc13fe765dfe6c14f10ad5868c6cd0e9e14360057488eb539616fd314681669554c783fc82764026aef71c6da8d2c2450273993dd0d754de43dda5e06903bb545e8a0cf40975b2d5854d00f3fab2de99443c3f3e47f6d2f1aa3c852966997ff83a28e63f72de52d77b59db23d6f8871eb9d003553185a970b7ec3d8ccb378251868decf460cb8e404316be05e401f205b9edfceb56a5e8d9a51c36ebb6d0daf0a825da082d71d49b0fe44d4e6b4d090c225484083abcf40d90762d601c3e9732a03baf44f4946ccd7d2a9a6336a401bd7b710d2925ea48c91d22954ed77027aee78afba4db204b33539c024f0ead4e511e74c8e02de35c3c0a76cb673bd74af6b9d953404b58bab7d1858259f71d3a95c48c5d8f37213b1a921bcd18061126b09596686233fc5261c811c5c027d760798aa529e0f4e38ac364066c4016600d7d627826f1390ca3dfa1977b4eb692592a7242de5c39394e9b6197190f71d86ae8e053e2e212593acff4563a05c60e8c74a6dc1a5b5971533b62f5be776add5901353633c0144b16c3ba55d7858bd9b10157f45651fadc369f6ee6014de59769b57b51c9c7ee4bf95111b96292349cec45d511be4936859844ea45da7b111d37ee78f7da498d0756d30fe337f3b37793d3561219d8809f425baeade422fc4af67b403a8cadffa25ae8a38babb6575b687e3b9c2a714958e9c3fb38200deaf1a49d9f74ffc5f6e4bbe7476f898c86ee7ec497efc4058ac272adac5df5fc8eac3c8313844ce4fb5a17c0c159094f00a64b78869f25fb8b459d56117758ada058009c51af5b0fe8b824929b4ee7237c8a7a78257253bc54187633a25bc9b5c6a826b2f5a904fe692d10b0dcdd5fa77da652b793c1c5b7374fe01cd8043247eefec7c35e96fcfaed4d69e87ce0efaffa9096e3fbda53fb48102306885519d424ee45d3d6af88f362c72e8dd51fd04e6c78849afcf45ac52dbe4273d229642f2ae715367a6365135be67cb68bf251538bf61af416e5dfe6816801a03324d23866be83817f1541b84126131165cad1ada28bcaafbc7f059c4c7ac8dfcd0a92612fa215aefde1861e1ce7ff10ea331019495e02e1c2e27f020ff7c805023f75b340"""), TestUtils.hexDecode(""" 14A8B812B4C9129CED02A09C8AB19443D34DBCEE85AA12528B61F84A2AA9D9DA49011C8E2C3C3856FCF761EA9C9882FB18666F3EC2C8543037E54FEC1F0F944FED3D350CACADA9428B7FB7D9DA4937DA4D1859BEF8C6177F0EC93BD67FC3D5B3D13C34D472D01372246704DA4763FA73BBCEB0F4C3658B2111A7DDC01FCEAA9059FE3DD5BDF2A9FE0D1C2384E82926EB895AA529532FB20E12F1C61BCE208E48ECED036E4F84CD60F8042475749E13D8C3ABE0AE17967D5C6D8C598A53A10231929822FB01EA976A08BCC0D18B1F9B6C7C1ABDD15121E00EE80459E6EFD61CB8D5AF950F0A8FF2807C32CFF7A56661C67348617059D7E128A72C8AF36B149DD8B46537EDE60EB5DE8A16A93349883B73F7C4FB8CAFD01E0C9D7B1EBF6D7C9725651980E0DA598A6ED5114178E47EA4C6ECF870033A03F134461146717C8AEFCB8E8DB1ED4E286C68C7358FA105641EE3ED9B4A5D4826B31706CF0946C152A365B246DC036191613655B829ED1AF8044F5707C320EFA1126B90137EB05FC220F122AA990AB476EBB0BB3AFF5B92442A857F6808E144C60F4B5190794C411C705513BC32447D83B760E907E6FEED63FC0A60C0CCD01734AD55EE178E6BD6D4B8A238ECBE8E4F8A464C381F16F11BFE62DFFC5021FABEA941D24B81CFC3D0F07F00F902FC5042F95A81BB8B795907F8D6BEDB5E5C56D4B2A4353D0188A90C01D7B2781EEAF2BC3D3D58A6F6AD63DF7FD4D32ADBC5A7A2F81EE3F5B98E8052017868EE59D8DCCC0199A006FE4FF39699EECC82DBAA846AC60B51FAB6F456DE4357F5EA43FDCE4B57AED55F2F6EAE49199AE90F6CC4AAF662ACEC2724337AD7F9CF74AC990D3083FE384685A1E616B233752E31CC4FAEB8048EF77480CC849D3376464621E2BF48CBB55E1A7CAE855A216DF4A8D1AE4E4016958F5855FC395C53C23327403720271EFFDF1A90C44E93E74D71BA29D860679E877E410ADE48ABD0EFDECA426DA792271D813116ECC894D799369EA8094C328D7694E8CA47459F31F5065858252C1EEB1AC4750AEDDD327048894F7D79A1D64737EF6E8B93ADEB938C1EF31E38DD60E8B4174AE093697DE4207C7733D82B4FE92590358515D30264A408746AC252ECC0BC28A9C98BFCD76C75845E9611909B0089B571259D1D115EE0D5DC6BD6F3697E1289C4742CD99F97B5D3A22631E33A81734A5D2BD1FF4A819CD6A22A938D3F18AA90794C120F4BE7E14324E89EAD34820070F8160B140E8CD5D68378C081DADABB41D365663AF26C606940E08B20581F4E63AC6E68FB5A7EF5DF86047BAC502223AF08F6CD82E6ACDE60116593046B5CDBFE2411A3FE89C438A1E84CE6D1CD72CFD3E5F67C331E72754F6CF2BF921FDE2C6DD5481F20F509A6852AEBF55BFB4B52D1F8B3E397C9B147433198073049638DDEA7E21C2043C786C88E45E566B6A7E8742209F5ADBCD34FF26962E87CD235CA1052AC02E4BF75DAEE60A06B19A4B0A61A15D9651473DF8AAAC6DB951EB6E669FA5F89175DC1FD4D881D688C477D16CEFE809E623B2F2A996909C3E10CFEF756ECE8E93072AF27B87715953E0C48946DA8E893160CD351E48FFCC6847975621E5C75D5DBEBBFB79297AB368D13BA95308E3D576F1C54CCC1C4D5EF2A41BE63AEA2A9F9A27822ABFF58B06AD99515B97F260843DD2304C855184EFE96BF10420184CBA2CD3ABC38D11B7A74E4A9E40FC26CAF3A84BFE8794477335EB1F4C67ACC9513BDA5D8252E608D03C69D493F8876FFF25D39DCD71442707AF2681CC6D5E117BD24315B0FB5C9E8175CD42AEABF699B7B77C9A8918AB94518B48DEE1777EAD8F18709A824F277BC06CB67915A5A2508E18094B0ADD29FC7CD554D8671CFB47EED2F850FC84B1C0F27767B3052869B653BFFBECBF6D8077697D1F440019E3381FCB917F5C06008A04C8A88B4493698C1964E25A551B03805244570D0EB6999AF2BC467EA4732B460A40F7C2EDD2CBB07A2DFA99B4E5F4663A45F2774C1ACB0C8B965E1053E3AA140E973049714DD644CB9317D9B3252150CC9A525E8729ED4A9A7900B417875391F7BDCEE646B1009CA479A1295555759C5A7597A775A1D1CD8D870A71DA7ACE7CCC7D2F38B18BD66441D80068F76AC194FADB3ED5F4201F26F670621D254264A4D2A88426FA6077895B9BD794C8C84DEF942FC43F2FA115509429A939052200196CC921454A65C4BF1A6E871970A3409FB9773F356BC17E03EDDE8CBF2F91E7D2B548380967F756D36520009DA5032F20D8C8CAFCF4B561A4C2894CA13929DF2AFC2C1C9FC41968746433FACD66309D2A7FB5D90EBCE40ED1E80C12D07BCB075FED76DE423D9EE6B1C787E1039749A0E559B86C4079CCA1CA7E4A3EAACB300C453782071725F6E2DC0652DB5EBE7D1C16B6EE0078004ED1F49DF439107AED04A2E69F70A35057C36A307C8F5BC13FCEA76AA997DFD2E2E4B835677EE961234895BE9C9E7D1486C04ECDE36AF4F7075C0CED9A33C372C33F751C953A2096815D9B6186632D3CAC31AE6D0A931258014D6F88157ABEBEBA1C11B9CB2956253D4950F5B2F64476E4125848F27D9ED4F93035FB5F5DEFE2435E67DADA015F048A90EAA9780B983748CED6056D021D21F6FBCB1A2DE0C627F2D9015B3D9D35CA17C54B0FAF85D0C45A53DC2575E2CB54B9A5681FDB66C9D5A09A3F48DFF29B24E45BE82856C6C76F0B9680F7B666B22221E14DD8B22A15FFFDA1D666F4EC6ADB5B929C2804ED36077E1A39F166C777770124253ADDE6B77083ED159CCE35894597E7BF3DEDB346571C2BBF69AAA9ED133E94AC7E31F2C30AD079EB4B4452232D83E49B43DAB60BBD92673D90F187FA6F3859EEE1630D3A232B99F3F960E8BE49CCA0F1A519156D2D861F8B6C15FEA4C4635C23F2ABEFDE8589A45947D391CD1DC3439F965C6DBB5C5C9AD14192B3D784D1C78B3DF6719D5C474E02D471B9B857611E2FED83869BFE8A2A74493C25D39C78DB019BE93E3BE331131CE85C4586C0D40D676640405FE363646C2264DE6F64365F19F87A8C54C884703DD369FF52F65CD9179B8A09EB92C38C284E06B0537EE686D7BF3BD399FBA8E1703BE3236F8BA262E2C84D55EB1E1E55DC14780DBA04BC1106D98B05593F9164F1651809E8AFA0A04BB0B51F9FFD5062B495133B509A569845CBC3003BFE23A7D7ED433B70C2EAFF5FD898009CF1ECD9E9B6F37CD7794234A098CCC39EF078E3C152017CC73A19B811FAB4A2CEF721029F6200A4D1E4F9E95A0A758A7AFCFA047B6707CE048C3BEA6BC561D152AC4F161347C098F4F44AD92006090324757D73DC074F1E1D445A500AF5A92CBE19EF631D99FFF870C60BCA8515125EEC36D004F22FFB420F5CB01330315F00CECFEE3254E54A047A7FA3C7495E6ACD579A9159F667FCAC4C4448579E7A68148D5518EFE269E97D90D67CEEDC378657A45E9DA855EC55E7BFD0AC3E52DADAF76E800ECFA61F2BF532E7365C4FBC8CE882AB327961C6A48C24CF0F0E6F2C54D732BC9B592008F2E6C80F7EFA788AA6BEEF0B6AB7B21DA3F9D92ED8A8F5F3F4B1D1BED6F66B6BF3ED52E49715C07DBAFD67F4F253DE368619A306C513E645CB5F154F7823781EB3E15F38EE482757009E42CEEEC1530A0159D25F052F4D4326412CBE6CD11C0DCC56B6556DDF806868B83602671C96F81D8210842144757A36CD187EA0900F36A0A9DB85B9609C11DE03A38A9984003EBFDD4E7C07CCA7A7DC7FB5F9F16E6C0C32CF86774B46C56BFE2840D8EC51E9FCB719DD1CAC4206372126DC8EDC9A4A2EDC8FDC8370C7589CE9FABE0DF3C8CEA90E82944B8D489C0F52F73EA3E3BF56BC3644A1BB0AF88F4B556A554851593E5FCAB03E235670638E4AD77BF012AE074F331F67222899694CB5EABBF0D6E6E6CEF75151FAFE89DB9D66DA4464353526116B3C2F382825B11CAB3CBD221DDA588F4BA13548CF627B52478F47D9B61479730CD9CB3F6622702C9A115D69EC232CBEB3FA88AEB832EB266B855A98424B2E08A699453A891C89C45FED7BBA98D6E7A2179A24D41D201C4214444BFFE6D01A15CBE640C3C54458E8DEA5DED484FF7AA78541686C60F9FEE76D1A7ED1F5686A2EC1F0AA037E6CE38FF695DE0C17895C9326415840FEDC1675E9CF30B8C45F8EACA1E65DD18290E8ED826738876FE8B69DC3432174151C051FD23CA4675A75E73F1D3DE4CE172FD657B57D5D03FBF8B29E268B3EBB8E9BEA96A4750168E8AE5AEF6B34701276DD18F1FEB01FFFA2A984D3A59D05A56552639D506BAB3021D507D56D0FBD80DC582B3C20940DF2393AF24FA5233DF073C7FF28B54C7A921949960CB2593AA4F93A06D38D896D547B28E9CAFDB479B7D1BA2EA7B4A6BAD33BA8B59DF8792B22F5FFF41EDB1FAA926FA3CF602FA63ACED78E85DD7C3094ED48D1F3381BCD084A9909613873513657879AD8599403A52ED0D16AF0B3B43C672867700167323D37FD6373C4D51B90327F4981A897CD54C8E35A6A5904F5AE0CDE36440393A59119437016E8CC88894B2A6FF661C10AAD7C7B03B7085B70A8145C305D5E66CAA265AB42B34539CFCC9A62B5D9BD09FA4D3B94BACE361B4C6BF6B550B89922EC01041CF05C0E4632274949D244B7776D6504C9803A67CECF65F750F9876109167CA77D412A7EFF06CBCF129D057143BCF03CB1C1AFAF937E55477F5B15020149D64F53887467AA16C6692FDDE61406D552660B88AADF65C03FE1B8D485C57FEBACF8B11C569622FBC56CA1056FD3600E1BF51084FDAE32876BAA1E97637F73677E8FA1462222DA72FB0936ED66C16A5E892C44093CFE7B4E3EE33F21091E04FC4A07C6CA21E93A500E5D7378EC716A9ACB27A5687BCD7F4559C32F6C82E8C06E82135ED16C35762E94BFD6BC33D5116E4FB209C98C871FA8E9230FA807CF1FD509A75DFDDFBA5CD4F131FF8B666878697B372B92CDDA15D0113E8BB91A7750843B3D14AC4E8C956B44C7A3A26720E774EC1A1F68435B122E539C8A7515A1AC94D456BC4DDD54839AAF6EEDDFF8797C9BA3A15AC70C34DAF78AF1F0C21734DA32A79C1BD3CC8B2636E12B9D2E42AD10446EA1A9FFD45430E03A78D8F38B64B64C9D308D18CDDB4D5DA13F1B4D15157063E58C36DD71677334B4D9BF09D8C765FC68B233B31105D0957F1B675798E5B9E982B1BAF1611EFED0E39E1E9E70BC790886A422DEFEF325A07D97FC603866C2C3682FC651CFFCA09B8122B636A65E2D6B8B9FBE6BB9220959038AEE11AA7003A9C4C4EC9E27F4A8350FEBF1084C292B6BA9A6E03C00979854CDFE566831B077823B025FD1B9C7127BDBBEF34186C74759E32FC222023EAC24A6A6653A7073F4033D77CF83831E8B6BC8F26AACBC3EFB2328C6EC35C3A509FA85E2E04532DB6E466BBF8071FA6020CF5585C70C29320786EBA815EECA6FB2BDF9C9F3A3DDD0F1800E93DEC3C5E6DB4EA5A695865303C48986CE26346B6CEA4A734668D5BED675EB0C2A1FFDBB9E5511EC715BB4BA3604629FA28A53CC0DBA1E819A521AF8B7BFF16B4FBC6766543C0111E232157B7BE4D561618D6ED7D13AC8817641E7AF77042E96C7209F1B65C42D115234F6C63B84D381F1820CD656C88BDEC7CD2A814D6346E90841005F66D6E36E63C5906D19904EA0D33502BDED36E7D77FF5E2592290D6F29200668A25A6B6F44FEA1D3EA00BD4BA165D122455E8F97EDB36061DCB335870F44068EE4A64FDE5695896D6A5B30D7613BD8C8B11DB330AEEB0EF239C105CE6C0B2E1BD81E867A2D823FF88E3E82FCA69923E281A2933D5FDFAC6B217D60958D18ACED57D670851D5A6A445A120F5B563070995793E618F885F149A3A3D498C69A0B9D99D92C16327B7568BA8CC35128500FF515273099B645C683EDA30092C225D01E6337AC652586C0872C9C5EBF09DFECA43697BD97B86FD5463F529CF303A105194BCC3014F4458CD3BEE8088B8B05D58A960334C73E1CEA934CA0ABB2597F703428EAC5DF6983A76A5EFBB4A20221E6EA04F67273D52D0311AB99979CB0EBCE738B0BAD72F0DA80097609F4422D962DE43D5B9E27F2FB3FD55DB5B9E98C1E74533DE23930052446A31E656E150261C6658324BB243E0C55C43BB397367D9E6EE51FF7A3F4FBB008F87FDC3448C07B88F4EC3788FB04944AE1D734E00E1CC58052AD2F908B55B39C0B1FBFB889EE2CF91CC1B3FCFEF11C14B083F8A898BB28B838662274B9974AA8E83579181944CEDA7FCD9C36D5FEE67522E828D6FD9CD28537D9FD57C8ACC7B8F888FAE4673FFDD859F6446B41609135BEEB20804F4331E31AE057171D27D1C338DD976634A460436977192E7FED668FF01B7F996F00958FEF2F89C78367507225C458A7EF81513D849081E4D22013A4A8DA7E6E9AF687918486E785E2E5D4EA5CEC4F92910E6A6F89198FF7911A16D7B46BAC5752AD5F7457E9B65AF0DB57148812FFE9F7C70F5531D11CF96ADF7A3AE1D86039FA5CFD5BD5465AA1649C40A513FAD60B54F7AF15A5A6B34F0935BAB28A1AF631816A0F5F1E53E1A7DDB5FCE521252E25910555D70AE1A309BB1BAFB7ED3856618161CB41206810AACFB9F748B06F6BB8ECA8EAE07B77934CAB2FC72FFDB061D5FEAC548CDD1BCE7CE5D04E9D2E4F38834AAD674F0D540DD6EEA85CEEE4F67B1D572597E9F2B66554F7F835894E81F4081EAB2578CEB8FA95964742436FC6741A5A9D1F2257572E7026360708EAA41D31ECCCB55811D5BB7648EF4021268C8AFF001F2D6BB3E1D4D304374E892E4384D66869CFFAC575398808D2042B2A33A874BF364B6E7A859BBCC67ACD4B5DC3494C1A6B55CE004A354C8EA8F14E9D9A4ED282AC4D78909F42BD38D044FBC1C730F921A1C678062A200CAEDB0EBD42D48C0B758F138EBD6BEEE1E45BF92157E3279C6534232AA6C361953A0AE37E81261832F29CDEE864962D44CC6C3C68C05B16915A8FE35B067EA754777725EAB0BB4E20C3BA7D6E75812C498F29A94D18D90D60F49339CF46DCEC6F0A546A90E0BD6E75B95441CEBC0B25945F2A38F3EEB1A9E20805A81E3008750588397A9A168C73C81C97FEC1BC16659DB16AD7BCE275A884EF801D53868B0DB816FDE421A9D7FE37E61B699736986325592EA93DC18B036D5B237115C35AE3862E355A1F3CBECC5BA89947E6E304A86196E0AD6A113BED701D21E07532A6D02D014C9BDEF9F9060799BB79AFFB218F3B98A4BC9488E5D2CA13531842C6651621484207723F41055274364FE30601C33663A6DA49C8187008BFDB1FFF4B7B3DE89F7FB0BF57F2E273EE84ACF8EE91A5335364BD034DB6A1F8025E6522B4F3D6212F3E75AB34179B21AA28FF6911736724FDD4F3229C6C26142BE5D6F2148C9BEDEEBE6C56B6A20746875A6F74CACCDED95179AF50E1C5E09B942B4E3C5E227C1A9DCA36F04CB89EAC24D5E87D07BB407922341590A739B825AFB80F544F2B1B70D877300B46000E660A568999EB8F54A3809D6879935492CDD67DF15A1FA902AE6ED30D5C5EC1178AAEA8E539068EA2A0132EFE51DA8A43E5D48ECD5D8BBD0FEF8F90288E3068D17EEF4204D639665BA3DB7C172E99913E97613DC4304006CCB37F1E9F62327E1C2B5D97E31822A52298BE0D6457708E0E2EF25A0C4C932F16D25A277C5BFE1AB13FD488BDA7BF30F26E89585F56D827DAFC799D7DE3BEF0B41A3EA3491514ABF11E633D7F4B8A88CB6F3ECA3D48495475A33C9107EF39157D53D447308BA03139C7A1A9AB4ECB178D818DB6F83B4489626E2EE9464D7392C80F8B4B6317095926370681D1ABC3A48D82DE7A810124099E375F39E5C6683F4972556FF258996BFB0FB81C44E3C0C1A814AFAE8CBC041D7E7EA4FD830568DE534B65926D6CB83D306A36861FA2874234E33F4EA5BB8AAE05C3DBAB96CAD63295D7BECC26F5A4E862546A166A09E059293AC85937FEB612178B8812541A929B81A090FFFBB17DFC3C774C5BCEA1398DD530C5286658D326D7BA7DA3F2E15FAEB038B8A397B68AEF622EB10B248DCC942E7BF4B4C942D33A4427B685A0DF2BEE8271E89A366708C9E48F6A3992174E8D401D821DCFE12099D3EF0BA0806E7ECD674422731B0DB2B198C495E9DBA6294FC736F41EAD9232A5E404A8E918A18D7A7846E0BB6716C4343C2FB00286049D7BD823410EE8F71347008A89DF42EFE049C61CEE782102730944DD15C0DA322F6DE4EAD8F9EA549767BF02BEDB1F091252F08B34B6728165B11D2C62805ED24ABE65A8E95441D1D5FBD361FA87B39135A75D749325F09416CD3E1ACBC04F6AC8B989716C55B06FC784B0254A884EA4CCE8ECB2EA278CD32FD1FD99C3085585201EE9492B7F7A2259479B1FF820661466022321457088B202B5F1E67709B763A3A945B19CB5A6EF0A322272D98F8921B775A37B6CF92F66CF86FFD26F84547BBA75AE82411E890A7D8F1B74D657380287606ACC8572D8522B87CF26C0247F25A7F8CA12911081224128ED444C5AED9EADBFF6EEA9FB7485884093C340CB326BD467CFC4F6E6C17D4F13C7F9F76192BF4A10F2F28F538C76BDC1F8528ED1360922E5A6DF1A38AF9FB28542357231478192219477D554507A47E9FCA585730292493A2B3EE225E0DF87C747E0CED460BA677EC691637F444D248805FA183666FA65110AD3ECAEFF59B2F8F619A275034CE415DCEC6E68A3530D17EDE27E93D87EE1EA55D22045CF436A34F907D35264116A848DF0B448E4BBE32A18BBF16A8DAC00CA6B07876ED0720591345223877E26D2DF4C0C3FD8484DF1DC40F1B7D4D49E871D8F527837F1B790CDC9FD95D698231CD090C60915C98F1CE43F7825613FCF8EC929BBAB9BF663A555210868653131556553F7A36368B0D83AED6F9A970CB2D63163C607ED896FC7342A71C6A1C90A53DA0F32141600F28F31A9340ABE97D0C6E8AA3270850B6598670DA455F8E2816EF82D3267D39A8163D34B135221D7D5D98069A8233802810C7605AF9764C6DB44FB55E29470503090CE6A720617DC9D17A5091CD3267DC4DBC1A2B7032B50CE46522A2FBFEE7BE29C3DCFA1FCDD43AE2E09DAE7330D2E6F2B15D10F53EC6D607066504AC50AA7F18D3C290296A8D9ACD1F5A3708BC035979CF03966E0081FC53F654AD68A15A3D17A65A768A4CA5F647BB21872B1ACC5BA3DDB5F69DC215735A5CDCCF50D555FE968551D507A7272FB591587383DC5930C5A572BE9FE0C2797B622DA16C6B87A03EA563845B8201168C45E7603B80E5780E493AE87584A40A09AD6718CDA3759CF1940479545789F08DE83333FACC26D28AEB54E2088934332EB7DBD5829F0ECF89D22C62636063532B4361B9C7C2B1D582E9A7DC72FF7F2DF667D9B7BAA543FFA20AF6BCA1A9CC22B7D7D177B73AAB087F868AC68EA0CA808EDE0C2F931B3B0CCB28E472CB316C0DB0367D4D7FFE0C02977CD2E5B20F28867DB1EE0DA77C5935155175B33D3275426C3CC5B73748426CEBB3ABFC50405E30EC21A53073C83A85EDB485B26AE7B633692326003004A822F261D5E20246F99B03D0AAE36"""), TestUtils.hexDecode(""" -82A8419E4D978417C3C821D056A9393685833E38237A688EBAE52F9D22F6204C7AA8F8BD5898702532B6A56388041730123C978F23EC29A03340C162C9486044FE5263C5BBCB894F856153000923BD19369563F96DBB4E44D2EE7FF2ACFACD81CE7057D8F82DA68C4C06718732002C3441CB07FD7F01F72E28BC170DC10054F8C8F75F0BC4757E2F97B0C8721B8B8462A0452D3E8A9D55EB9342B9D747019A05EA83C6548905F72B2C9D62ECF92103DF350C926D46C4994F35E54D436B51E1B165B5FFA4AB85D5276270CB94973BB49A5589F2CC9919546E51DC629D81573D9A0FFA2D52D31A1CC81A7FDB76FA7A84FD312804BA266A5882E82E71DBDB8C816ABD9A631F8619BB85E91BE69C88ADFF9DB36794D7F97617E7C118BEF10AD3178BAACC2104E11BBDF22642A79F05B56B5827D1790EBE998BBE2821CA1D0D69D5091FCB2677565BB6E50AC4F7F3D1B4DBE411692F289FC0E8DD072C3D93A2D617EFB8E3C914941792E39480391A8033DFCBECBA8710439D83A821D3224965CD0B95EF31A160334458F22C9FE4DAD9126399D2E02D6D539DB4865A780F0A5CC125537B00B581778BF1FC8125C09B319DB6DF5F9AB2DB766589DC7DDADD62CB3E67215B37C34B3D019D85E4E94E4557EB934519679947F09FC5A80AC5EDF04549B4089F14AE3768914D05E22F6FE2AD7D098C90F13E6763E8B230570A13B15F0779525EDCC704F43D8E15EED9E1FD7EE39BE339A3FBB7FE91EC51855BA72859BCE0F78983FD0CE5ED5AEB6FD5F1380507DC37F893FADEB653A5693E16397D1566AACCBD9853FEFDB2FCF300452330D3353344C51ECDFEC3D055B7B113A337A94B43F0CAD1C74FB3317EB9E08D5CF252584D7B3DFBC9577D7E440D5B70D6C2DAB679B9ACDA3545A9AE523EECB01F403F3AB123A3A6A79E89E5D4DAA2D1DE6652C09E4A62EFCD924CEBD48B854A2F17BDDCB2E332F035EAA85810CE6DAC97297129EB4827228F360D4A30F83FE0E5F05A69F115A4315E83A9355D3F02819FAED553EB1AC05C67E89B095D1B09689F1F30F6E5B1E3281C52919866F0E297A6E70A507AA3643C5A7B1217BCE36851BE4A45C2E690FEFFA210A93C8EACD644BBACA1B3668B61612CC299ECAF8413AC3DF9493FB99F1FCF7CD4F261907B6A7E823F5D7DF62856EA94351AC0B1BD24532E8A58B7E9F49BE2C0C8C6D102327CA90FB2A20AA533BBA2CD56AC0222F697914AB7DB037E53975821F4A4D12FA24D5C8E0981B02475ECEE9DEDFD7EBD71A3D8FBD9940717A70681D3A5766082D2012D534949D5EE31E9CDE629B12523C4CE1BBF0EAF468A871C06E4CE30C05D5D5CBC7B75604F0288ED84C49FA80897281F4C1BD56D3ADBEA4532F6DACCA40CAC34575BEA447DA7EB2D7BAA676971D5D6C1B6EAE7F4704E46F9EB0F90A38BA3D4E308A685E0EBC44DD79EAC9E93CD94EBF8E6557C877F5A06F11C9AE05882D653E9214C6BFE82BD52B2E74B6BDB1FC72150720DC9F92B8BBCD96B0FC6AE0C8C51CB35A167FB93E755C7BBF39914D5BF1AD32AF8E2A53C4AD96B73F6BF5987389C4A089FAFC2527779FA3DDFD9C23AF408EB7637B0FC9FE1937B153F63FF3502C70DCBFC15E1E2817F3AF7DA6552F46696EB0E71D992B391B3A550E0C2078FD17994F8F9913ABEC08E8AC2812D2DB1BC7C1A3E718F665158BE3D92199EA226E5C1E2CD56A8B0D7A780A50E2E519A81E13909016A920CC7D557CC10AE56274FD6137C292CF4527172093E8268E1E4ACE29F9635E34EB83799F9E3901D5DB653807BCB6AA5217923A7FFC77D941A878383CFE455E5D84823A5642155097F60768F494C6C4D8737423FC66575940AAA46E62DA5F0EC6F20F517CC5D7F3FF12F7E127E0EAF8CFCACA2A198FA9EE5A0329926B3AD63F2D8EAD33877D8346965E93FA5E985E5171498A4DC3E6FB5CD914595D8FDF971EE1F63B5ED27B4D74D302ED11D518004D4B68A3666658FB3636952387055D0187FFBD7C18B29AC28C8A06B284EB0E9543CEE183BB5E98E4BB4CBE2291964689C98F21FBC4505F309B1EAD2FD6431CE913EC4415C01E3FE2B75586041092E77E2F2D1BEEE3084BF9F5D9E7D035F4E789924396B52EE47C502FE881520895C0026297F7336A50CD0FB46E966D32E5098C665AEF52AB2EFC89FF5D7378B2E6972291A57D4A82629F3F14D98B707B60704B18B48F0093AA2477C297E5798D34E1EAA25E8F440D8B2E2A4C556B8DFFB7D08FC690E15291FA768C960A8C7B962C03632452AC7888F20170CABC04B091D5A173592EFFFCC7860A870691AC48D44AC35F29CB7D57971E5051349D699DD8B511DEA73816A592B7D4E1C66B8406608ACFFC09F872AE6C2B13B0C8DBAA51186CF9BC3EA3AAD2DE618E13F0079984B11CB092CD1C938D3774AD4708ABA354880F98F0B3AE28E6BB4C8E5964FA69ADB78A68B075C30E08DCC8E8849C0631B8C9236E986D2E6FC6C3982F5F1C4683D7C61B8B469B617EC0976876A69C22180C37D9DAABC654A91E991122EC08BE674E9A02CEF4D0EFAB94EF5590D5E797490810BBA7894DF86219E813108BEE6541AB9E43F68AD43477AAF5FC5670FA2FAE1B3A559AC418E674994CF8E57BDD99D2CB349E09C1C68E5568282DF501B34BEA35D00613FE208334573A9E88710BB32E68363EB76F6B9F29297DF743609622345E4395BB52B9E36EBFB5A5A5F7F8EBDDB081C36AF9C26C9078DC7833FA7ECD78A4DD3CDBAE9C56ACCC711E29CDD03B740ECBA5D0A53E3F0F9379B96B9561F80186C4F0C8EE7BE11FE864B6F2E21379698820C32C12B8D8D4AF2E5781830E84F03A9E84B66335A3A454C269976BE5CAECC27894BC71AAD3AD6A6F0774D4DFCE48D6882E2BA9259AC6460801256101A35CC1C56955D8589C91542B9CF947EC7504FAC304C57C8D862A292DB0351DBF5B5B100D037479A401AA81320680C4EBE9E3A954CBE168B24F930E9928E1DA3714BFCA4C2D55DD971EDA243A92122F3648B9E1DAFB6FA303E4C48D4085260984AA0334713C4CED4116BDB3BD10C004451071AEBC2635ED8D401AC9801C694041B8A25398C50D0C1A7A14EC42A403ED3572AEC00CEC00F51C170E3E3738F7DEA1D64CB61270E38172760A71B7A9B52ABC0571541FAC7B96A9C0B3F8682E8BDBAC16E049BD38396787004F4BF722B6ABED9C5B3B058D06D92311EA9D2C67496551F2BEB1D353B52AE714723B1693C7CA78B1D0E5F212D2DD95C34DA583C95ABE1BB4ED435C5CC4105390825F0548D2D960B31AAE5558071DA276F28AF4F96B1FDD20A51499858839C80BDB845F3F799855AEF0069D20F3C9D455F34FF718B953B6B3AD111CC5ED7AF7F0B37969A0E474B21B1908F54806ABB8F6CE24F147C7767D10D1C42EE17FEC645253BD993E85DD82C77483667748E9AD17E463925EF4756A90EEEA62E0B9984CDA389D9B784ADDEFAE9CDE3279BC9DA177D842B9C1964FADF4694D9E1519D40D49D194089D1561FF729B41C6A111B749A14B2F84718892EEE595CCC97CD64048379024D76F04D31AB78348887B53DF69AD1F376C69D7FD86D919C98CF8B6D974C425D6C0F9DCC70DF596C8025E1D60C1D0C240B02DCABF093A7CB2287A5596FA1C0170645D4646584B4A27D65452AB91F79A9AC938B0058C7BD069DF24F5982E923CE56B070C84109C11ABF5BBA299DDC0E9E78E0D34488A564D4313562530828D732D98EA08E73DF307184470E3A010B8A0662BDEDE5CBBD15AA4438552D809164BB6C3D2B2F0A8AE13C3D78305A7D3140925D0A5D7E5F14CC168673E682C5779C9A325D3AF591B88BE881C47A313395FA88B2680DA2625AFE996BCD98748C2E82EDC20A3EBED94CD3FCF8FDBBA910D6EFDF22B66B955FA84D5476686EBF6F8A29D90F679773FC237211A4958FADACAA5C24ECC9A95A3E6D077966577159A32D44DA9FCE2689326C56F748774551E9F121E43D336AA2A2766E0A1E8745B4348BD36169D11A7046A98A22C866B2FB05EFD40BF95543FFC25993F2B516937DFAF8C9211D6CD6E10EE1FC1C4A6CF29999E7A63222433A4C54B98F00941DBB2A8B0AC62FA5C32E9436F9B2A88E1E683E04E36ECACA272B9515DE52A1B5ACBBB0C5946DC21665DC7DC6CDF9FDF40C9A0273BAF5D5F052F955528441311D12A7B92F306BCB08687CBAA3C094BEC781D3A05A3AECB65F22F086382CCD76827F03F1FC251428776FB4BE1AA65FB12A07F288FC4522E3BDA80C0195A2AA683F18BABB2DEA6B8A030A4FBE833300D1F19CD52FA250C178E214484B528BF01CB674607F5D5C36A7F7FC8EB52A25645AB38610104DB09DA179748AD16E35CF972BA3014B683029DE092F966F730124EDDF09F91D145024C74DD7D48A28F5111B73D3566C1F1FEEEFE06AC83D805CA81346C85B07D80559747A94C7AC24DEB3E54CC75A73235453DE3DCE3EB31382E83E398EE877375CFAF27199B51BABB70DAA700B8D0137B46AD7AB1AD0DBCF1686481C770305B2FAB0AF378C9BD4FBF9C11FC744970B5E2716FDD7E79E2FC57749120AD92292750011360A51987CF58998911AC914EE82C56CF3ADD2B8DF00EECEE9FA4C5D1905CC1A97A7223CB86EC5F1ED278141A681D772CE3D5063754C549BEECDDCC422A9C5C7832155D0EAA42D455D7F7D916AAEDB7DE3575345C9B22F6584E169167D818A8BC670B9E2303332B91D52CEA5F26674B819927B6374429FC5AF1BF08E8D9848E92BE742A93118606601D8BD2E42E1783224962DFFB826770D960FC9E0E5F3D68B635AB2C277FE0145CC03523FD06F52597A3D4AAFBB191B9C2BB59CB4E89557D801E77D491BA4A1FF81FADAFB2AA137A1AD099F839F60F74986A4E69E73595F10B7CC6A2FF94DF6D6887FFC45E3F1A39B2B0AE850862022CA4A3495FC0944964E0C5B517130DF7C7ECFFC8327AE8C3AFB665C751471863D3E59D79D8BA048E5C07772705024396930188C65CA8C2A3B9888B9D651483F7C2E96EFFE962CD5C3C26B781C506977D761A3C0E3752F1E45889AF1A74BC14643D44E79120323D0C649AAD09FA903478C7F8A4DB3F96514F78B6D8D46195EE66443B11569170CDC7898B3514B7AD9E7165CA58110EB58801E5E10466DF42E347CC690F6C9B95196F143AF84E3A81BC412F7BFDFDF222F8EA0D6F742C37BD4DBB77EA9BB0A942B10442285BC11F631A19A25C34B01C11552544981A3A6D0BB4DE21FBAAA2FCEAB1D65B961FE7D546C7942FABABD25F3E605100AAB09A0B389F7AB58668D31FC54EEB0433DF42D64869FD5662233DD5D48F7A9495E30068F9C80D4A66FD9BF1C7CBECB9944C6B79DBBA18981F7D0ED9F2945BD2646464D7DA473B2B64A9CC1388A0A7B588328577B644EB7EFF0E62A413B56B422D9FE36AA6B2D0B7F609E11085C4EE889CEA76E41B4B0DCF8CC0E19C656A17EC184FBAA22AA3D6E5DE5EFF0C212FC82BE6BA92653BBD044726D4E87AB68A1CF0A80D0F8B8860EFEEA3A257605578EFFBC43E50A8E86C9663DCAFA6793BA37B116272F8DCC803B5E9A819827B84EE975CAF6367E421B9970175D9593402B7394EA56703B1BB241592830EF0D168A4FCB54C0F3D88A90D5A1C2F977789C2DA3ED638C08F5932E91AE20341FF9CB9F65E0C07656D9F79420EE20AFE7F5C9F49DF3C87B8D23E709D1FD3ABF9375E095ED34BD768F8C07EC0FFE9A9C93453197738E16B76D7E02163B489C6F6426AE9BB86AA9A653F527A1D93FF780411ED5E59C478FEBA710D2C475FE2B2649E1FD940BC1223CDDFB566D94C9D2B4D0C91D3DC2BCC6F73B4C586A5C0BE72DA7B1B5FC1164B3E3091C58BB89529B83C3578A82B11542FD27B33D2ABD1E3D4A45EF0340D912BF8EC24C2D315F6C9F58F68AD0DA46920F896241EFD7F98DA1D10ED22BCBEB6A273CD7B29BF273F8B6895C05A622687B2BE13B3CEBDF6175CE25607CB83E46924C5CB00BFDD6F73F2C5DE790A87DC10FD1C77CCD9C9630C57A1973AF48EE1D283964891859D64D3FFFF8EE500DC4744D8871F7C2A735AC4366DDE9F03690AB740566F611C78D3E238365A017020C3959AFD4E152588F5825F5D8DB0A840FF6C7BB1F7BB87BB7BD1BFACCC806975190166EACB26FD8C388D940591A68C489D32BBE4E607541D05A6381157D53AA2120216C971B94E2FCF834E8D37EFE65EC5F086F30C316C889DB23FFF9B152718897AE049E4A191A043ABE2BBAFA94CE73F1CE17DC47EADAF8C8882D40000E2AA0C703C04D5332F54A0BABB7641A1F4C3376345B5800D737EFF9D99BEB908EE59069F504B6B8625A2343F070E6DAF42BA24FB48B9795332CD5A9EB317FB7DFE4B2663A17F6270BF75F888BCEFB51844E711A1ADBB9A935543ED5BCF134C1F52E8CE1404F789D0BBAB14CD229F8267CD5F631B9BA284F6D633576B6BFEDF1394A5673CBEFF90F172B3256799FBC0239567DB1BDEBFE05ADB6C71E5B7E9DB4B9E0E1015E7CA4CBF706073341750000000000000000000000000000000000000000000000060D151D21292F34""") +e3204112bf82f4849550037d8b6325da7435333c716595e2f17c8a85d66bc4a612e19abd17411d3f4b7e3a8eadad39a819fe5ba968c8640243fb5d18a7674a3368099088c000a1c9906573a2957b57d5132fa2df9423c64e0f7d89a338d0d41e9300f563a82993c8e43009eef3fd91c10dc21bf4524dde27c4013756a1cf7b5c2829aa1698a5ebc4c46b80cce01384678f5c444648ed513a8e0c6e4d29b3b4721627c1c8832d736d98c17f6c00aee528abf0908b030edb381770e6d23a261731817b4ba5e632b1f77e5beb60f2e34bc2f16e6feb6fcf8605367b5d2dbec8668cf6a7b47fe5802a9eb93451f96e2ad72432726c9579cf08c4337ded15690a1906b82df1e07fa995eef43df8edb543bfc3a7403877b4bcca16aa105b625dd23e1d938d4d89293e841245472a0c38b77a6697923e213eada80659269fb642089b311e2818f8ee998b227a2130ba594a27e985aee0c6a3b34652b54581eea40f2c1e235ec06e055247cdc106164d6856fa8798e0da03c1b4a6b89778fef781dd6c5c77147db302df8ae78b819da5b8ce171f53bae732a100211cf232faff1e0588054a0ee99891a26f88b19fccb49693a844270fcb1a43f26677abdbe3c33261ebaf69f8f417ae6df03b55506c463088d49415c0e5f3d9cceea7518692649fbd2e0153b1612a84e229ca9a69eef15882d402425bad02039426358124d0603decfed2101e93876d057725f6cd131ee346f047d7e2e0398a5bbda6e1fc5029b57f78e49a49cab5febc682931f3a2b167d553e4f1b6511b8b07a8f62e4744c20a7b2731b317ebfa1e89825d4b7fec5c775243c9af25fef92f61261f2b4377593dbb3008385c92bb779ec703a7e76b785b8aa46c8c3a2bc5069d69ed865f1e5e6283f2aea3740a62226d341deb55d420eab001398596c88406387b293ebd1663c2bf94041f3c13b8579111fd7d53b66a3528d9bfbc6b97e72730a53ba95e0549473cb4141abca8c8330b1b4e0e0967b2aef589efee973c3718eef61d27b2a355be3c92f7654a6d33e5441e3a0f389911b40f6640080a752ca53ca9db239216dbc3d95eff963ab43973fd8633299d5adad7020a862a594c656e34af356066885494b1a02fd6fc5cb257cdbd56e85e74de7005f2b160f6ec6f0a61083bb046d9ca90c04478d8489cd75e176d027351a84bcb6fff940eca4fcd464dd577780473eea0a72732d435eb41d219ef7c2619400339ad2c30cb4ecd48deb40d713e148b474c4de28b91efef85e4f16750bec38224c0916892032bff8b89a4e0aff665ebc050e46cf7b7cba9fe8dc8696c5842f82e6e6bb6b58663e1669be1e4469cc8982650e468b6c9e5a1d49a44172f86676d9f4731994d74c4eabb9086eeab469a8a7de0e18845797ed73742864149d659df3118658f8cee2cec3c8a8b388432ad98d4d78f3dead445af3fd698fc01bb81d4658624312fe1da6465b7f53ecfa4e6f958b9f474711c9a2ac9fc8abdb0682b5eb282e5ec116c45c3236baba0cdf49a7478400dd8a67fa4704a8e98b29b7dc9913d15f56e613592dc60db932f374b1a0ddc46435feb7412b290587fd9e925987e80d155ff821e27d77de3141b8cf38694e3cd0e7ee0d822c213656fcb7be166767da6522cf9c1f29cf044efd1fe7f0d9e9df64c417aae894e354bad581a66432f4ba9b94226b1b577f64a931c62bcc6c97e5f20f0c53f35ae39f38d33600208a1c6986aca3bd143e920a430e9b6a311a751509316abadd632dbc82abc94ae234243edb75d362928f0d8a7ff9f7ba927780bd7bf62f3849f3fd937960ed08794f8df99dd27c241539c41d27ece05215f2e63e7305d09cc384223a3bdf8df83d0cb1f76231529faebaa18e76b35ef77d9ce6d2973ecdfde9ebb91d7fe2ff38bf0e4ba8f9c3efa3185f6ffb72a10bdab1fb829931858ca37e1d3356bb199d9e5d9d90b11339643ce9c528ff7fda54f907126fc745cffd1d9c60dcb92efc39469c70899ff3d5fdc6c18ccb0b3bf04bbd9d14b34c857467185e5f427b134c95622d34f3bb5fc4bedb7fa8e7c16abc277447ec511acb82de3d1372f63d9a30c40e6485598e707415a572a29ed1c82bf0e138bf6c6267380760f6f2d42040948e96d4a792abb2912ce8dfd5ad3c20bcd63fc84717a5b0c79bf6acf89199cca48e502661a949cb3123506318dcd0079edd930126c0e879cad817ee9faf22a49b11f44b0719554da894a7fde9e67ed576f562c787832b7cdb0ce85dd90ad391abb590cc33c83a57a1e7c088fef90937f39b423977eb5d48028af46a43d664f3ce89be3f153857210668a7f152d94aa8ce1305e5c467b3fe47306dc75cd2717b67f1bdbd77b7acf6d4bc79cdb65b291e7356201f7fc0176f826290cb70b54ee4f2442a658812274e08c0ff222750703f7127c72184fefe2cc8e6b0769c56eaada9bdc39d44e8464c3c789b8254919fccc48d692ee13e70745b790f5e89ccf04eac5708734ef847a00d4bdb4a7773d8a8e14779741b76b1a3be2b5bff279d8ea3f750c4ea5aa82203f55b332b785536e30d5448acc215c10a2e63a6104afc5d9002eb3cd9b98f76f66679766a0562a1e0ef9a69d46a453d0777046097dfe965e1b380cafbd62ba18753ade14c2a663c7ebe2fa88ec4cbdbc841bf49366dfb13162ef6d6dbaae627975d3f5d6ff47f7685c713c59dab2e0629d6a14fbaf1895526ee00a32405d2f4930ebae1d4c0ba243e0b77b0575650c1964cdaa8a09d70592a6e50f0586fa398009bd40a2666f0e9f4512fd9453e54df633b6ed72916cf87455ad6e67bfeb91e5bf15221e01bd61738f5e92d5fbb15d43df14f3355d54bfc97b061a1db68354e06d1a2fe0da4e1a6c0c0c593fff12496e42761235ec1238879a2c9797d97c833a76a3a65bbedb8012722c4c4347c30bab6d0897f9bbc0cd8b20030d7e84507cee4069192cae1437715c2179c6165d38b534c63123e9b6f07fcb4dc1c73c376d35d94fb4ff945d6b9f2e8f41a01ba5b58d7b5afac6f7f74d5aff530e3183a0b8992d2e885bc6c2d5415a572cd8cb8b5f09094998025b86eec33fee6f19e8fa5fa11cb49932508f066f38192afa3d11b033a6b635e9a32cf0dce3512a9d7af02dcca39c3c7d62861402586f8f08e0ca459e96f2767e991f70590a1303917476df719c38b8c7dbcd8f61e787131c093e2ba97cecca4d52c75e18d855c491d1bbf517542494928061f24f142fb8fff689635d57170be21f8bdb1944729eb2c48a66debf5399ca10d883c37c860921feeaa1ce240c419a987f71484762db1f6ab4cfc83c1bd9e4ca85c7730e9a58630150784fccf9faa926a28bdbce010a355ef4e8fe3bec648ee207e187fc3a8f73f80850d254cd0f9d9e92a0bf91e73d63faad0f6fe7908158ced03f396527e7b96ed2bcd521a5ac0e81fb60afbe91bb0e70fa6d5c39317158f67bffc160f0b80663267752bb5a9aa97d85d9e9f40f557a215aacc03d022341baebb7ab7eeec8425af176f3b97eb80351158095708083dd51d896bfc03d308906c31eddcb816ccb28eaac48bcce688a479dedf9417c950a7a8c95ae7b452cf83dc548b64d58b52928e2f6411d4b02466543e361de3db17d8994ef28dff206b493564876d5e274658e69b5cd70a0090d669a865e56e24150b57ea6d3c261b11c1e45d7bc387aee61add50c7f756e593de9c3057855ff761e95760813e5d30b41ad700bf544c451bc6ff51998bcf48bd6046d9bd461924121a3d8daaf3978f792d9cd23978f1c8ccd999bc79d2a10daebb3c9d065d30e970ace94a0f774d872c700949f2ff6a997c6e3193c5782c82a077c4524981e7aa6abb27b86bdc75928dc9599a1376a2a0ab53b6668292e4d34346dd2658fc9d10232b7e39ff5843c620319e530c71052952f75f2ab69fa193ee321c5702b6e3107dfb93b60cc99cc88f1fb48c0bf48c032e2ab5a3085fc9ae1f542f7e0abccc90b8dbedc9a2468da43edd62864be9f7f50149300ae6e2eba570ded34fdfbacdff6bedc092e49810a3e0e860438e3ef56f15dae6a1f3e01d1fc6624602a486d4f2494a3a81694971fad50647f1f0d2bf9e2b4580877b98917b22c55207689da27039b3e46e7f37bc785c338cd0519fffdf11c1bac606dc58f36f5a6902ae32391c7eeb9fe1251ea7575632aa86ce0bf516bc370b3b02ac8a66c2b82a5d69506211c5d3ae15d3c78d47df76babf0c7fb0a5ca3dea741dba47e67851ff66b84c8b3004f8862d6e8f6317c708ddcd6f232f78d081232ad98aeb17402a9ced35420a5e2802381912f9773d0d431544b7466f778ea3f379cd9b095fd51c2a3bb6fe7bdfef1188506047a31905a3a62ab7ddebd4c5655797b90e7fa78cc80dc7e9acb634da42540cb27720f67699e357ddcf45fb4bb9c8c555793cc885c31ffbf6674648615faf691440dc456126a5194ada986c9387e282a3e8c4efd5601f55273296dd8a351adb1e1f954a7d466e75057d8ef0f3d187cd0f8c2203967c7aa3049968ece39674260ec8ce49a25c87cb4fbdb73f1ad1981c19984c8a7fc6ec2e8dbf74889cf6ee30ad325fbaf3ce1be4d06255353742b14128c74765d32ea790b3235a3ca4a6e3adbeb39c26daf148ce4fbcb993b48f04cbbdfc88f67da205c910cc6d0c85b355689d7a5f6794990cd5a8380322d807f4282f79f2d2686deb4d598f072bfa2df4644c8f098a1c9589ee93fb48926675c7e1481de74304aadd8b104384f4df77cadf60df790a394f021889e098f960650e40b9f71193c642c2b28dc8e73934646862a9ed47763ef721c0c01be4da0de58dac976c7e52ac407eae45bf11243f741d05b90ba2a351d19f0d91d115dfb4626e2baa22a8d1a047b7a527ee81cc059756cfd529db5630068c8d5120ea7a6125d5fdc982f6dd91efa9d4f19891986140cc788285f0cc715e9b21f2175360b67dbedc68ff3b41bfbbd1d3adbade1c46083eb973876fcc9ed1e264e8213111bd18beda97fa555b1cd2f9fc8d216358fbcfe430751152c09c02a78b8437616d4326e6d9b87a71e5dc04e61ffcbad9c2dd9e2f9b28885c3b5383d968611de6be2655f24dd0cdf262e134e8cb9db1abb07d6fce167a9dd323b1b8f7232a8355d3ecb3bd4ba9a3ff17bf0d97fa29064762a6c9b7ba14b1264cbcd276d85e985926862c96e322308242ce44679502fe70654f54d41cc4ecfd6933df5eb3b3f2bc47d76e85cac79393bf6d77bba0164f6f06922474c9c1f9ab86da8051a7ceb0a29aac113b4d1430424e8e498a6dc40d46fd0c341b00a069128f37e56a25734e9e446a500e6790ddaf9acb20f5f67037b2267bae2d4003e1f6104067ce5a360e031cc604dc828c7ee79fb9aa5261e14f473d6b5f0cd365c5dbaeab2997624e705b0a09650bd386b78bb38cf7e5a3cd67aee3a985bf25fd1017d3f1870d726d4f211e0987e9251ed9dddc27f5322c68254850b4a4845f1610fe728092d34f6f9b55af7c167bd8f5939f1f5fecc9d1e375f97961a304c775c36bde5c065076245a9d6bc90c8476d958d00f5421f869c4109f6388a8c905850ef8cd80927b44eeb042adfeb13d808dc337b0d3eb738782fb4322becff76b85105e0e737dddfbfb423c11bbf3bf93aeda6af3634ad5d2d49b5d36aa2d9c72537a69fc0db81d8b033b82c8921b7d50a51546415e51e7e5a47f3c71c5da157e25ecb701cb9128400f0a7fe4ef801a306ee61c2cd975143959f7ee2df91fdd3678719597df544a1686aa9a81b81cebaf521deeab903c45659b270b5906698af28afeb37ced3362e43a0adeab50e2c9a2019f338aea7e29195ad472467cd35fc8d7bc8e5e16f86b273e5af3583718cd0967b32e39ede17770e77abc124b0879e997caf22ca684cb60ca3860f4f2525a989434b132c2ff173383c74582cba5dceea5d947263b6980eda24555a778e8d676d2570e5049d38f386d68b13ef53b035a83364d8247a6b32627756bcedf14c9dafaf82a4af23b232e37eb4b4b36f4bdfbc9ab5d1a963bbabfec682c548789b2ada1d73f283aa8b98ad214c7e509f5943daab0b54a5f9d94958a0e3887feb46afcf00bb0202794af85caff85580f7647fa3e0a9183f202487ea5ddb661416be051ca0da39769fe2f99793509acbfc3efa82318c69803f386cad629b4160a33b743594b0e379b7e9d483c2e5d2dee40489b306981aef5541a8639533f46e058b83ccc878600a43f1c97e36aa1a5b65ad3b2dde0362e35063d6ab2018e2b866ee1d13cc204a2949ec14ff98b36408392751962c889e975de56ac5bf00ae7df15768f02d9243685207c530531af5b4d838d63f418e9261fdb9204e14139e7890e290c047a795dd7aa9ed45a2ae86e0a20bb1489b2366d292b5c8cd2401c5039ff21b734600a046696d728ba8e4e9697f9ea7cddcfa1417272b61689d9fdfe5f95c626c92d6ef364447505e6188abd7e544838aaceffe14768e94a6e0ecfd4e5c6b91cfd80000000000000000000000000000070e191f292f373d""") ), new SigGenTestCase( TestUtils.hexDecode(""" -7377D2CE98A125D2293896EA97285838DF426EF6D3E06D3EDBBA7C6BF034FE0C3DA0A5CCB79ED5176DC24ABCE7EE76E7C1CD259CC05A4A784C8E7DE70FE1F4C1CDB96CBC97A40CAE2D0F29CBC084E65111808FC3BF9FAF728738346768C481B8DD506B9845F3A22B533A384D394FA268F6B8C863112AEB94D469DA66C7AEC36703035149C02D0B124CC89825A2A644D4A089010549DBA0885B82898B042094064D209988DA0432D2A80D8CA08922955013A79064222401202D9C144422B16892820D0B821180B66C62284EA2B40C08A35122C760DC20510CB77104446194006523B68058820449064199920D18170C02106E12146D40024D5BC40113056AA310284AC0302180292226455A384E8C040A08980812436ED838491318295A90651B094909B7248CB04909B28C18C34D044989420645A2922191A42019409198246C1B877103B40102048201B14801212D14130C1A204D0B176CCB046A03485112316E0B4572E2325013192C8AA640D98064022001C9320209100E134849429030A114120392445CC84CE24212C00844E0B62918A00514200241080E04456858B0101C1930113320111280028689D84684121168A3A0211009718BA42C0BA1450C279214972D01354E0B230C88C0418320492047660A908889064EC2B8449B206911B20413C32C40322E53162011096611072CE2420CE0106D1947720285254B264E58A4815848861B068E12126453865013338D8298500892285120111019708024214234080C1306CBB46CD808000CB3659042124C82612219296102411A94410980490A2580431450DAA684403249C18008A1067101C38514102EE1B60C99244459006863201104134A0B4104242352929845941872892249D038494C8490200164DCC864D43440A428060BC009E482104C82411BA088192649C4B64822208911986CC9C240A03442D340710492708200651A032C0CC4118CB42CC032051938280AA30D63A04D24C03012864DA4088559380659B868013852C8C4044C900C4A026582283101A7091402449AB8691C85701C414113148E0B4084A012120BC88559C82C22876912A10122950D64B06150120A23344DA1A64151C28408C20DC3825120A96420B325E0829118C94423924C03256EA28444A0000C0A4712A226621B43311C17464BA6458A340E228830C3368518106E09038E01322C01866010C4100AC4204C2282C8C07120B848D1200200426C081200E4A8040C444063A4718A304CC8B421E406521C92509B4889842082CC406108155020B171C2184A4A246C218421A3B004D2B608A1880D63B02C02B4455AC881143606C8C410DA86615B3466203131D9240D20B530021206E0264151040EDA048E4B2822A444319B008ADA822023086D1090888AB411CAC44C980282A016002128928C44325C262159182D101571CB406840C22DCB10669B30024AC00023B84C138724A4B030241764E1120604961161068084000104840D204461C8A610A00469A20285CC14880886481002620895240840401B421120A328D30401E4381051901091948459C8299B40895498681C3712C4A0905A180D04312003B5800BA6699B28244486509B3242930680E04251E2320A99420DD4A248CC929004B9310C366C09185200238600B14C24B7014A887108A1511B850023A328C846529C40848A8045D4C6715344290AC8650B22304C28268B462922008D8844691B230110C0480B492064148024223104466E21448A09430A22056601896989228C24866D23337062288E5082708CC031130341C1022D23007188247141102E09A684133266024661C9B491C0B08403B90CD0821012312249B00C11356A83A6444BB64562A84199444C63A645DAB42DC38601609680441206DAB840233170C338925B1271C8A660A04402A026068A305283A0458A14825B268C43445222272510332E8CC6414BB025521025A0142940486522982811194E14267102336420A80043124C6128241B3952E2C8459C086C90B6050B3452C1C06024210921A06053C68013360202802C80486808A54160488E1B2784518420834244C8C88C443690CB04860A42269CA62D9132101AA9515A320800A5845A8831A2B8641434605A146414152C00C90C02B510D3A229021728E40826E482014B280690B6851B428D10C225D38409C8B029E110882024200C280512454DA807B179BE146E96EC60914E74B78099DC2BB667ED709C1DC39DAE07760FAE0FBB086016F3BE0FD574560A68A9DCAC7A44629362330AE6293A88276F4B82BEAA2A42482D9C708EC75E60DC52DE3B70EF0F8EBAA0F591197273AF0DEAD7CA2BE5F6B7F67C99AAE59A016938F035DAF644ED94B5E9B64E153EB0DC49EFEC8F61BDFCE44B28532FAE0FAA09F430F4DCBDF34CAB952FD7E7C61C8FF1C36D9CB8330B556BAC79C4286331D7BC0023B643325C4E23B6E544D62F8D1E3B8B5F1241BE69A9AAC2F124DEBBDA3127093F4EA42E9DF7C7BA388E44197FB95FA17DCD6E6562D22C933C32A73F0D3FB9081DE04E513C9047F4DBB0F1A085CCBDF80BC0B6BCB652C302400F2D4C0C67B3698C23FC888D4BF06CCACFC202830D84ECD416189D0107B2F27B173D7541335004AAE5DFFC0DC60854298B1FD961D96BB8672A679E0D360150BA1E510B7151A440AD4BCE9A997B5D330DF5EEB6449264BDD4AEE6A86B8B00E0173838F2A645C9D8C4673908F6DBFD634034D840B378B185B21C92BBDCCCA0804ED6286FBC375473C46AEC46415B468CAEB97797FD03C374E422461F0807AA53D4C6CAE6FB5AF4C5EA616D295C5DC7D6886E5816FE47313A90BE1A7B8D528B96B351F1F0379F7F4301D7C669C0D27813EFA58827C26F04A09B4D9FF4B6007FF8BCCD3CB91E7CED0CBC1D0CDAC5F9205E6C9F3A1CD17FDF88CBD0C2554D162BD6BAC9AF0390A80745C6221B1CCAC44C6FD5F68DE32A9613AC4D4F77640A04141CA967061228F4E2D7C514C9FFA349004C0251E631C10B45BE25F148D37B05E14C3DF976B20EA5C26925818058584DF8428A8ADBA8377F74658834B3A72B938DC6C9FF8F923B22E99990730CA9723F531A5BAE5D619725CDEBA78FEF75ACB0C9D3BCD9C5BAAD600282F4145BF3E3BEB2A1BA7AE035659CB10F70D11D7F0A5DF5671466CF6554766C024AF1B9914F87BD74719DEB89014A9FD6247D089063D1578471B5BEDA5907825CD0A024716C21B186F3147F3C1309968782D8AF9CF40024BFC067111A68E27FF2E93D640657F422FC45537D9EFD2383B770E3702E2DCE1BE4530D17E4FC4C3755D47963B6E0184D277ADAB8037117DED146924DB13A05ACA3D7694CEDF95A0603F7B833ABAF05EEFBFC2585FD1E332070F63B486D93FA9D5457A09D9D27F84E80D49DB6548326D5F82A56B259271AD9EA4E90875D38718B2EC45E97F556FBB48FFDEAE2FA95A2A8FE1979DD2F48047685A3362C5F08B4C119305364293A498B4871CB7F5DB4E6B62E909960FC7495AA997EE6B885D5DD0BDAFC89BE1B4FFFE06789F6AA25497BF225B9AEB737F3C21BE2C7FDAF84F495E8EDABECCCDE3B0D60AB7E5958AAF5D0C5C062ED8775DBFC07E7A54EF47C8CEB59004FA347F1799481607497CB029C0A3981E564D4290C61BDE180CFC82F5ED40F6C89AB93635AAD175D488C1BF1C9A787DD3586EE49C028D65BFF792842D76F20E643E4E14312B1A52958DCCA1D9F7E0AEECAAA07B8BE1612AB2D5076A7F079F3872D8CDB5B128835436D14323732FA806B82014022F68E04862315FE6F16EE9254789DB98420BBA3F0DCC51159CFB7EA79E248CA2D21879E262DDBDE7F9C10757164A7096F5343AFA7ED777B8E2F0D13DD0A03ECA6F064EBB01E2FF84DA3542E1DCF62E7F911CE8CF632DEC6E376690C5D05CDDB42F7B0ABB6101D164D2A7CE931A12BCAF8E6BFB3D80E6E4CFD5ACAB85D4807054C406B7A93FA29F3589D5693CA4294834542884BB92BC1C88BC27AEEDD69E3D836130DD467F5CDD6CB82C2529B1E82837864188F6BEA25ECD031A55CF035A9F8523C30D30F93D2AB7BBC53E3E632B8F432BCA0D45F85FCD007CDAD638749DD09F7EC85C8C6B6FC7A4A3D87347515C73F64900C9B788B9E27C73469823C9FB6DAA6760D95626E74F18EDE6CF3E5888AFBE5D4CE686DF584AE67B5C300E8352288BFD55E5B8337A4CCB872BB999E86AAC9EFBC559437B10DC290D9A745692795D178B9134592232A696C5F0FDD653CD10EDABDEDDB746082AE54A800B43235DFD791BF7AA582155794D67204F87D9CCC52E51DF8ABFD24A4769C423C70B256C2E150844659F68E974B277840E98A6879333966F79B7A41ACEB1110E7E8B9DEB3D09C18285BE31A833AF62923E81B2499AC91F6273916B8E067892FC407074D2A99F287E78212194CB3862AC1F48D4B520B592D3BAB72D0101FE8FAF11564C88DDE8856FDA56AEBEFEA67B7F0BC4836190A8E6433F3698C0837F049F04AFFA2313FCCA95D22744C2C6FE08FD296E884E4D8BF1C05C0A7792F077900647B7D496CE3E2FC2690F2EB4402E853DE1BC21BBED13BC4930F1F3672702D9E676EFCFC6DBE120C398D6B335CB7F0C2483E1334FF4D526D59E5DB66E2B6BD865CAFD3A7EAE254536B07B67F7D883B92E0A0F59FB17F1B116626479117418F09F2C158EFE88F082A89957F1A4A625474C970B0C7BDB0AE0552BECE8485640C4BBDBE3E57D23F8D2419D8D5FE63CEFA90B239F611A13D2768212AD616025F3989FECB6834F3644ED914D75F08B3DFBFE497731FAEC81F84136A312BD91EC337E82524FC5E00EDDC07F59823320FF38DB34224BCC5502FD7BD572ADCB0EF53E4C16A35F37AB8B90E908016A649588AD1917FD5FB489C105CD2E59470EED23C90C7D9370F6406BF7EBDE494A658CFA1B93515C9894085DEAD882195E381BDE00DE045D1E1D4378D0DD80076C647C12DFE6441768CA16424331A8E8694C8442280BBD5CB6C1B6D504AE2DA853D089F56100E2ACC709A43FADF2FF110DDE85D2AD3F9F74854931CFD1A45CC769A444CEE253817D66AC7D8D2E0088A63D86608DBE29D1147AE85BB7F8EC87564D70FB2BFE0EB6D130EAECE850E9E030E1714D9E9A5BBA7EEC0FDF5BC660813B7893342B3959D137253F43EFDC6214D20B3C3C905A4813522091FD9D35D41193ED8E8478AAB5CC2650C19E4278EE10FC1F0EF3872C4CEC40DB39DB6384193E67E7E105A781BFAFCDFA8E88E1C85C5B893B8A442B4BEC0ED103F2F01C756B92A8ED8BC184632F9344C16EA3062457171CEC635DF6B1994CD1737C23CB37C32529B8A810DB30AF3376378F3F230BF58FDC564654ACF8AEB082E3C4DF005516D1522A7683F7A7092874861D46C44F605DA94DE8B004141B30152AFADFBE54744B0C1DEAF8F13221C050A9F4C967C1E5BA7BF78F579133C47767DDA12CFA827E76FE8E4CF31483E883ADD009639ED4EED93F4956D93449659C83EC23A7BD30AF8A55C8E6921A3B16959B3F1386A517A8C9416C838362E9AE08827F45BB10C1D222694AEF09B15D79140F8C0AEBCFD88394FB764371B67EF88E64C4140F34012179A394DCACD9E1CACE336BF723BE8FEA3D5E52E455E4F49F3900BED703ACBA38F27BFA3319445C4EC2EDDBF9DE7F9A1168CDC603C2C642764DDD0ACCD7809E98E4D36C838C2A57CDAA9444CAE82CE4DE5CED4377CEEE1922D10C96392262B4A57875A95FC4418A5953BE192580854EE92AF29E0949D4FDDD15AC811279E8E8EFC95183679117FE9C43A26AD455960A07FBA34FAB01386EA50072A0C5C026D1FBDA924525F3DFABAC3BCB69A7D2F800CA81872707D4EE0AF663768506C54A9A036D4D9C3FC3C20F8CC2203CA5F8DE285F70F4919A8044D39FCA06F484084F4F29471C2DFD3DF9E6D1E1AB2DE12287DCEA64E91EAA7C9C4CAA063710F4637983E66269D4C55CF24A1CCD1F02A08FD00EF4154DDDD104040CD15F588C93D030AFB06B35D7B06C3150E00FE3421DD24BCC0BEAEDB8185BB36D4E2F7A4493B98FE5613AB335475DE06B3E75766E9C662973A3BA91C0071606E4FD56EF9CF9E174BE2A42D8158207DCB81EEBDE31DACCC1EBC3BEFCEDF6316F929740C1F54C9C95E1E890D0A12CA2EDD0F265B5C3381DC8B1C2E719A4382862481E9D990F70ACAB53DC63BD502D9C99473CA00C452A604C137921E7BC050A776F03EDEDF95634FAD43D1DF4A239F047595EF220882097B282BBDEBD72AE26AB6DB46930E9ED585943A7CFD3597B134EBD74EA45BED2E3E06601DF441D7C2C9032E182B15E6B82276D4A450146B533BDCC662C9EB3D78EF75CE870272C0271C949DDE533FFA6CB4B9C70224FD877054B500D2D6192126F4659D11DFF75F624CF2304C92CFDCC1FBF02D57BEF75C69AD9502E387AB0F3C8A225D8486BDDF480C5B10F9442BD52A0DA149E1AD34185767A663A721218C7D06AF3E6AE29F5DA9BDB16E70856C3341DC58B8AB7CC133CFCACE0798123CE6C4735477CCD8E10499A0BC2D992E084A5E438605FE967DA5A24D0F66F769F78E2B321282717FFFECE8347B3AA78FCDD633E53B6709C2025C89A6DA9538AA643B833718A85477817AD8AF7B5986034CDAE1A4816C7449C11A628577AF65AD999EB00D08AC57053ADF533B2563001D08B001A65D46970E00DF0F83B692FB8683FBD62211B706E53C4AA30DB159D14235D0AC88FE1FC4FC994277A3838CDD84A0A08061F85CC1575831E7B56B87FFEB5E404E64B72C36966323F98E8A19202FA7F3C187E925DA291FE4C3E34A06C0C5CEB76BB7F8CCC0436A0001DB12B261BD47675C2490C914401694FDC04118372678AD2AE171F40B51C6CB4D40C849320F58B877CB72B222F2E4562AFC4C2FF91267F81BCF6D31DB8BF838F6EC3A3C45"""), +fe28a25123cd888c478aac1d081ea7efc0ad28c299b7cf879c70474654b0bfc86095607a496c78350e34307d09bfe1c2440919feedd0b55e8f495f7da65c3415cc63f6996debcb3c67831c2db563ea863c2ca586cc66742ee69b014ac318e8553fb9a3d3c407f9f27c5fe91702bd52331103624c503cdf2a6dd0e9dac9f27aab90261120b905ccb81043122d21146e1b83308c12220a34521a3646a1942103924d1337700844890b098283a891d980685246458c004912388dd91828d2300e0c82690a3288a29689c8a67190826de2425224b45000306a424292dca22954946483865192b22414c46520a91194a60d0948809984891a160218074e6324845906511931715832615bb091da9229a124861a963008020c23246662a24dca98801a369204c24888221123319064a440caa828233131da344911412913038863b48d8aa6301ba4884c4249041990211745cbb848203509d8463004272a21298d12b26840b22843005211b381d2466c02048d0a1104db260811078a012590014810020210dc84651836024c0622db2208cc96259336280821268222101383900a364d22108dc92802e3126091c465a2a42c9c000613133102c1641a202a11c820149928e1228c5892251c1851c2a0049a982849484200166001996d22a08d8aa804cc184522496dc816910c4331a28268e4466a4cc66052a42449a6250a15468c480d02c72840462cda302da004241a170c1b387161124213158c5b920812886001844d4142600b4891a2948d8b802c08b250811224c4a0911304845b14819c9690213806dc88858ab810113760cb80300c212eca2661213081cc2625e432488834400a808912234e5036121836665cc868d0068199186113a42148206609466064486a13362061447021c601208671d1085194066cc3845059242e641640ccc83050142e98884d52066a8118460180919c2482239550e1400c54b868c3c68c5a3064c81645db422c18448d0a914c1344821c27680b212a5a246c1aa76d4a0226dc44804290311b3464238524c4020d88b28492020253b8311cc91098404ae40030a2924522018ae316429c44719c460451b04c14a63052126edab4511a246d2226714bc891c418249c186e630049221446e40069c8102211262e14c86189a4044bb6901a28861b02604914210b118e0bc18c13252a8236910c47889c246c02988840886059460150b06c11a18041260c03a42c9a300d0c48448a148e41400d633866e3b280a14422ca027011440411814041c609500046d138801112454ca2719136009b4865c1442dc0b084c380405838821ac22cc2124114904de140211c39122414019b1691838671ca30516184642295690b808919c9891280012223325098651a01119b421002a14599c6615804700911012349605ba25118229122996c1a239112048cd4b80503300114888058b6512332445a4491c9464551120cd004812195200bc33140182ce2122a184652a48268a336681a1121db348214446d84a060e13424da400d0ca6090214521a05720b361141804550186699a01110b60c198525d41628d3446240366d5b0286084750cb268da09465d3006d64842922368c1c096ac23011c23024a0949120464dda400c20816591209163086118016e88448e11a5059b148a4b38208004641c4051cc80081b074861824562c84554286ca0340014056d58282c8b021222c20863b804cb4472d2229284982d22885100c421149270532251832682c8366ee296088148319a444e201902002544e02091e2324e080742db0691dc0206a4468ac98011009645a2004a50380558200c1cc76852924d08a74c141700e0462108000a1bc03058964551a86c14153151164624040501097120a88411988503367262209153403109396ac8448e9912099b862550004d63c63108a208143821003982d302862022519c448d58126d624669894026cb2222802868c8106d92100144260d1a93300b166264884409a2415a886c0899040a3929db264d140644a430115c9865211541432865d2a2201ac00542b050c11230e4a8400a4180c004101c90296426919b84409936401236446310628240924ab00dda3066232942da048d223492d8302001900822a98cdab25103174a4cb03104186e924244c4281119a80d1932304120459a8601e1a04c11882412006299a600d0de68d40b4872c5c415d2aca8c2feaa1ae9dc06b16212d382caecea0b4bea0a1a4eedd4ed8203ee52e2e455b5d542a745bec1f76d74a497dc7172059da0fbb4ac038204c13cf6e8c61b590534ad23f02fb6d32ea4964898d9768c319e931861679a1cca240b2c0cb6c01a2474927e1dd15b63475b3fa68924d4502b3511df5b91723e59d9d97e909473f9cdf3e9c27391196d537273b3dbbfd7a16d808425f11f5fbf5e6c89b80e0df01c576db331ee6562b4d2ea4632b5c9132f4b88a409f93612ce7b2a074a3a6e8f498dcd1fe2996d9d7f604f1063d0e803cd71307d3dc882d5ded30fd5a799a52e28896b9312bb53d72f3bc4a7dd9e963e2f4d05d06cc4d80230ecfb70c5b826a2844d714729d9b8e391571adbe98766d5b180d4216e902ebff86c226e0bd5c3d00ec141b00f17b0d1d6f3a4f407a0cb015d70c7ececa5026c143710cd530a15052b4f8c4092de12bfd598693922007139e0a6c924d2a8491d982b653d5ae9b8762939fbe8870aef52714e7fe67a2da7751c91f8ab5fd73b2dce38ef6b21e869dbcf4224b9af61a773553701783a17187e2a5b28c8dfe501946f16e15621ba55f169b10542b6f07c445e44deeb1ed07708ca5d5c14230ddf8dd5faa0eb2e209dc3244039611cc9fce09c2c2b6d56b23c790fccd3787667e252823ce6bf9d60155dbc855a4c7b274883c5e2d7ccabf9b0640f8bfee4acc35f0cf8c7a9d71735e2c22ead23d6be69926de7010323083e66571680d2508d6e9e4c752eba3a3f050d4e53ddd657a4d09cfbfb9d8768ebc539874d27458dcfc8d2fc84e8a78ae7bfe1ffa6c0fbba1fdcb56b65ed5985f2e35243328b4f43771fcd9a735b3a721d84cd92082ae4b4d050d0954d9814627385e5cb538324c5a315474c156f4710be47eb9e5c66bb4eefd2cb13d066838d8ecaf73a4ad25af96c570d9b5ca331eb03040ca41e2d23a469072d506a6496fd33163f391b914c36f681ddbe497b5108bb5363b162c7e333f2172645f4363e8c849adc9c5f53d26ca93146bf967e77acf6106ec06db4c909e97cca3b005eb790ebd994bfbc8316c749b7c3c55849288a18f65004a3a975b3f72a8ae8aad361a1c7c5572a99713af4409b1f91d3d8da85def0360442f46b86bce3bcc53445cd93647d0168bbe1df9b9edd77c7d02596dfda2be9ca70b8d959e06961efb24e2effdc4182b347904587a80bc9a0783cd65fc32b3e6b48f67941b8842d3f48a819d52cae5dbd54d0d2a8479dffd63afdb882ceb95e36211861e4cd3ef0341c373951e8446df7fd2bb43beaa246d0bcfe24770f42861ec978d00efafb27e8b1b4974177f192e490eb75ba2faacefbae949b7a236ca1b4141a625683aa652d90f0876fc8bf90dc843715f869b0db24f9bd9a42ba188b048998e7f0b0691dd0087f0ac1cb770120c63af237a45f9fe45b3687c9f9ae9a66525af9447f0944cb4ecf84f01a2b34068b8457d01051f092834e6be601160a5ee17d94e168f6a9ebabd85686fdae3bd7f60f20aa4f9e669b1fc39da73dce2014dad3820d6f125c0c8bb3386b3ae5de0e193f6ddea02da3a5f8873bf8b0cae80fffb5e1acba58292bdbd9d380deceab59a29147f6b05f26ecd3d69a8e428cbba2b78f2069bbba85a28c441222e649dd7adbb3c3b2b3456a026f806834b9f3d43186b9720a7154ba4a12de629997f9aaca8139e3a773d7330c3da727037021618a2adb7ad5aa119bcaa3c366ba2ece4f48ac6ebee1df641a33e14f9ee478fb59c04a2051c88b09cab337af5b5908b4312abe14e1dce9dfca692cbc59625dd0dd7faca4ae82facae15dc860b4649032ef6bcf1dfeca621962bcb3101d1c263dfcfc8c7f14fe007611df65d8c2f308df5317edb623e18bca8a569c74c2c63e4be52ee4b0df90cef8b31c81271c2ccc8a3b21be2da5b733826f66e29fc91e299ba4f2f3f2701d51ab9283185c02746cc9d4350a3ab0781d3a2ebd37992a2439586abe5c23642dce99a413cbf2e1177b0a396ad5c0ef18949b1cd5c067a9e558de1b235a7b5b86b9abe8cd7cfb77752b692c28248823d09d52158e81205cb4342cb032d655b93db39ddda37d03118f70063e04a3a52b50c6112671643f53098e62078599323b9b63ae618aaccc9c28bf995dda6923287083671b10277b95fcc1649a2694c68cd5c35fd87042fbd83dfa792c71332e7a98fd7d98a85cb4eebd3ed4a3570b99e82e9fd421ef3ba9f7c1693ef62687854b32c3e8d22812726ae71186372a1f7c8af334a62bd1373adc9daa77ad5984aae2adeb45c9ee3f268f1e07f9cd4afaeed2b008dc38322bf820666aca43052f4503d47f2a9e2d78ad3381f5156f52b64fb793715dd812ab19bf7e7d65acae18e0ae092d403a3d7fcb551996becc7a7c1a195a418b91e4f4b8df8a478230b8e7e3383135d5a3084c4da9cfba60229a7bef26032e50a721ffd0b279681c1d8ce2e37afb9f58f5e871be0303d484af6b6cd21f6475d3b1514ac221d6ed2b756346875594b0b4003e6a4a798312fc76833b6c04d5aadf1d731283e898226642436dc59b933fa1dda83f7cf2f5fc4b0f16320e5f963b431ed2211176916937c43ef261ba2a930699555114ffbaa00ac6361d2e35b440ae4c063d6856d837103497c8b487fa00b6360d86251bd5faa7d23a213fd16106f8891a103167f167008c1d09c7e1c9d82fae09e5a3ea7c7193147930fef0b8c04a63ccfb986ea736b5d3fbe7a80a2524994332ecce5f0439c0660f9c7c1245cf622749fff13c132b5190aedca8b19fa660063bb18c7a6a3e469643bacc479c6d9df840dee239b582b5f469333f9abc063052d74f75d98bbb0d06c5c5da6d7b93b617a0f574274b2d8b25aa3b21079d463013e961fab521c67f5183e0a3613cfbd8f5ece6d3791efdb20ba9777c5cd95aa1209a9a95abe030134afe843d15e6a6874f3bc6570ed17df31c7b15ff9f3e4b8ec000cbf520dc164afc8c511cd35efba2b178e613908489cf5a17039df559abef9e8033c8c772052eba33577fb840b276ac325041ffaad171880f37830cb60da1997241cb6ee5594b97fb353bdd575916f9705010d04f9f90835b81bb949b6f35bff409d5588cfa50838a96b22ee7d5b66d973f614f6d323ba3b0581ee407791a20ff4a66cb4c208f049ab46617dc6d26d51c4b6dda716c018b70d6331aa999bcb898511191dcaf47001d1127e1f9886de617c2002e2ba2f27b04d3e53515a504a2d8d31c1fb587a160a9edfd1dd31966c013c2406725e79a7a93a73756b9a29f5e5b8b80e3b9c53977541df0c2043dc42dee4ed68819bb8387a33bc2be6f4b33db215d28a983873e200f685d7794d9a1d2c38608f477dd24178817f05884c01d1f2ea94738b5601ca99fe21f07234c7174c5b20d88986cf717507699ea651de129878b2264083dda1beb6afeca929e98df36308be0c8213ce94d4e5954c6cd1f2a4e19a3ae9e5e9d94178cfb6a9c90bc3bfeae5acc91e0493896bf8e20fc3d78204449eb3aad69261d768c263fdad21b4631d08379bbc27e4070a5bd3b10d8727351831a7ef1decb217366f4bdfad707c9e1698d6869bee22f3579e9a79e7107725303ff48353eec66bec3f00d23f2e56cc872f29d1865550b4584f0079804655375e07738b9bcb4ae00414243cab9ba6b91f3e158e87f8881401da309d549b456290a13e0f9e4d48432663edb082fcb0d84d0eed0a8b0ec2df577240b92638d99ffdc5246f6ee8ddf37af524625abb38c23792133c8a7fea5054040b1e64af208f1f0fd02b4ea1f62197390aeb4275328a32e4c8f6d68001b6b9323d4763a72abb5f7246856ce65faa9431c11e13457ea3698611659ada89b8d755e8ce1711420608b67be66a9e417ddf39bf9b4f9f63c160f679955c6cc80f2ecfd72c280e1c803d1afbaaaa37dbf996b1d612c861b8e42ecb1c1a3d40c35bed6b2378af865d5ea21a3511a4dcc4710769443ca30636c7dd175b6afbb976bbd849073e4f3ecd3095cda97c74682c0307fd13a3b754150e2d282c8b42b6d312e901f74f3fbbab48b92cb40d271588f1f71eb8f68fe494ea9feee165ee9e4c038229e707ec8f4b79bae7f3d908a4c1c71ebd574aff7772bd1d7baba202d472b3c24d44f0f2c459d8b903b171d2b39d5da366bbc8c03c2487fa0620db7346251a86aca3cae7b62ef4d0d487430463640c47748fb7d52a53f683f5a49d3f7eee3cbfe59696ddea73d2956aa9f7322f4828f949d42330e65880a1d7b3ec79eaddba9043ebc9e47b9c010bd230b2b68870401c42694ee96faabd822c5d216cdcab834faa71e3d3c2d24d12f70948e3b7b5a4e5511642c3b43157e2b9d1d54b1ae8a5d7deb3d4aac990a040b8320b0ae049bf25dd0ad3fba1beae1d6ea69c1f1ab631f06dce637a8244a3cbdfaca18d1375e0448992affae4a7d08653f6a475b2ca80057112e77b8e6a7c0f91e365b74504b3c19eb529741d2f6df00d965b611ff000d7e85f087ba0a99f1c4ebd1d3e8c30ebc2e6ed249154a709077d7683173c0b160f8aa7cdf7f6a7b39f85f4ff70ce1fde27e7a6197165a08faa439ae93a3d28cee7b1ba2e20f39ec6217aaa6800e1314408552ceba1f8dbbbc216403b976adde8509cdec0650b70a3d1b5daef27354bf1ff057b9992bd1f8512a04020c45d35684a781a3d2e891"""), TestUtils.hexDecode(""" 4F4C7E0134BE5200C4512299D134770A64A76B73A82463FD8C86594939DCFD9DC55B895B32A2E96B8AFDB8CA83AB857679C372CD88754CD8A7B0A31D2ADDFD7D1BA64556AAF1CDD674F3E8F5FC0BAD2FA38326365918430AB2344CFF785D5F73F2B5D631DB29FAA0F9CCE5CB7FFE0CF4AF1C7A8950EF32F1D72080A492C7A25ABF67F409FF5D4B1E0D77268C0A1B2A32D9DEC61BB71EDAE6BFD58F274707182058F0E6AA31E6D3763732A82BD6F2C76647C7ACAAE7FB4AA51125F0D2D48351B6A3FC7FD18172FA8689AE1602C4EC0CAFA863AA98BDBB1CD8C2681C2B6C5C254E346C18E2A270CAF2606A6504D30C0E2E505C2FF9D18523BBDF21424C645AF0EFB2EA0FD21B5D0CD85C7C1EE176FCF904B481855C4CD739443F3340AE48276E7F4BDC00CD11C2B0D6B97BD00AC962EE1FCF8A73D3DA3CCBB3B72095CB33C5542D86E843641CC98E27545F99188AF064D5FE74739C54F5678F411D96A0EA043652935BFB2E37EC934327C7C841CB0CD04EC17FD06A18E88882177B51B00DB6EF1DA164245A3F2554CEDE8C84DD777F0B92CDA456D922D8B7B8B63B548CBB72CFACA540C0D69F9EF21759F243CFA03EBD6B080D23DD62945E623BC4F8323DAEC1215B251C35EA13A0F081B86E803BF37DAE6D913B7D942BD1C276ABEA3F8F74D0C8727EC21EED2AFD438BB7"""), TestUtils.hexDecode(""" -EC857FE47C6764CF4EBC33AFB24BCB47BD927916A484087D8C0770EB6B0E09427AFC3C3D41F83FAC1FDD609BFEB217C6DA6F54792F0B7C7BD05251CB34001A4B77F1DA65BEBF1C8CC8778C0DD44E8EE655279A96860E333F8EAFA468F3B2C3CDABB00E4444EB8F6E11F4284B17979010335493869C1DAD4D88293C629900A5AF6EFCEE9D0A685D712139FB5CEEDFDF5212C4DD6436376DA5890165B11F47B45251FF9F83F5218B966C0A6CB2C3FBC25D50950D9552DF6AFDDDFB6FFF40CAAFDA74A3A6E697142CFB3F3327293B45528B3D46CE998A24DF46D9BAC9450E64D73FDA9A14307E7CEDCFF2874E65E8CCDCFE66E93A6D07BE6E27494EA75170C4028173C638D7CF1125D3F2FC66025A3B0FB83F80EFD11B483B7CFAF05B86AFA62C2E85C4DEF6049A11C4B76E9CB0E9A959669B8376359D21C26DE603C0CCA5F99BE34872B9279E50A1504C20FA0DEE99BF757F68C0759E1287618F86F157DDF2F8D532D19F77C42914FB6C3E88EED0E52A939BDF22D548937C19185516B9358B4EB34E03D150B0B4AFB629E754BC5E4067284AE7133D0D5EFB3BE5DA06F567A2A4B1E91E8D1E7AF50B463E1ED8967131D6D1C33FEB94011E8ED1074D4EB2E4D30952FB76145541E5CB643750223F6952C196D51393B3184AB35F7E7B4929647721139F7D115A9F02745B46C22BC5C5ED151C7F764064C453179B221935EC48128026525EAF5287311AB4FB87824B772C093CC21DE77E660186B8D5A4493DCF0B4EA7A751187C9AC73953F22785371312FC4D12421A17EAE731FEFAE466BD923E08BF2196A820E94E1D0334B2B86994CACACE28256CFE1B1CC5E56102D16CDF512D5135668803AC9BC931B20162D17B1861C8D5A7584056E462815E9726AE29CE5BE9547FE2A698E366865949169F30430B8CA0D73037223B6D2D97F6552ED21A2FC0A9804A5B12F07AF98D44FBE3CF12927AD586AB80953B25D308E3863D5AC23A54AEA7A0EA0786198F6DDB4CACBC2EEF4987913FA6CFCC6AB0354EE7A226CA9F46FE5C8EFEF7B9D1B3718D27FA1227A47F213794116ACBF4F120175A189DFB83D786C2F89A7CACF23825DE573274F7A964B3A070D66D049C7245D7739611FDBDFFAC21373A1B52D9DD3068A814EC08599EECD46ED0C775AEF19513622DEE75DF2792D7F123A45025378912A35B303708D0B3426C65C69B24358ADDA1708989E2D1217EC7F7BE32C37449BE2D1B843C77555EADC7B29878B71D95C420A9A744CA247E3382DDA1996A4E749F7315942E47EB1383339A1C20A7943543531A9EF0309EA7114AB0B3DC4ED9EDA988D6E978092EB9938815A355087C63149ABF9FE4D1F1B2A37FE3404F7587246F42758BBC7F8B111136092C28400D45D28E50F685240019A30574ABDC1906CDEA07B29155A71700731904CB3B49A3DE0626003E6D903C22FE058F47D8CABF213BECE4C4371A0DBF0EE89C6C018EBD8C6D0C74B548931514AA46B6AFCEDFDC5BEC48A5333476CF48704DD3F8E031F62937214FCE74DB483740CEB6898426635C38C740939EEF69B4E009F8C3D208769AC3017C827BC2073911C3B1AF2BBCDF14334BC9265A38A494B033FB887E7FF7D1C3931C483CD8AB4E5B1374D03C325D7E266F6E9D9ACD06E341AE9E4C4F18E9CF15FFE0DAC5FBBF65F6ECACB4798BEA3AE6C4123B7BDFF4A9B34DBDAC333E3ECF74F892BB91BAADF533161764824970683AD1D513C98063779BBE2F1C80B90B29F9A333CF5FB391354F1838AD2650F3B8C3519A0CDF69E359D73379FC11022EB256FD1DB270EEBED9A0FC2E25F59DA828F8B0D0A756ADCF7F1BD3ACE22811062219CB9DD16FF101BC879B7B057D8C3A53E028469CE476B136B0CC929EFCAE217CC49C941F22953084C50C31F75B9F7E309CCA6AC26A33A66EE8F4FF4B3363D8748C89115D38CB895C653D07BB99677DC919BD6DB824A31FD90BB56BA5C62546E45360AB276729F070456CDF89B5F48B50AA534C8EE341CAE2CBE2A79689464C2CF7D65318C6AB8ACAB5FDA822F132F2B5637963174A628156E1D166654A11C77B3A428B41CC7C618E03C97EA13E8489E3BDEF8AF3EC98B74EB68474191E15019EC80649A04DE49136384EF7C0831E9B3F4582402D5F07F0D75C12B57220C7E762243996065366F5F6663A8621DDE3819A0BD52AB1E64A07FB0006B9FB458761C3255E88BF794141647E7A42A422328C87F6BCCA09B8CA3D435B5815491ECC58B874A264E61EA49BAF9D0F8C75CDF72A68B1DE29BFBC0EC715E2C4B9EAD89B30315D8C5D554ABF4D862CE78EC051D635D6771388B00E50AB1C1FD412FC592ECB7A7C0F36EDB8E9C3EBA02B3FB4784199D7C3984DC56B5B19847CFBF6A889BBD98F3105CE8A4039DAEAB3CE4784DE71E3AE19C2355C09982653A5A85C554F7B86A3839B7928B2E3433BE19C4C4C2B2A23D0BB99FF2297AFF64CA4983CA89F450D5E173F930733F63E83914D771022353D8DB88A28401F785ACB7D6BC3FD5293F600299E22871422C5DC47DEFD4D818AA741E64E8DAB7354CC927FA2A93397218823340CC695998B073DF31808C41A0DA96540B64C10C929FE54C62C99319F628CBF8004977BD13DBDDF029D2902C2DA2C0A0658D85D336CBED91B1A5813C63A5149BA4771E2EBEDFEAE4FBBEE78FADE02E8F1E03BCDDC1C07C6F9C402CEAC52A98FC6CB51D3EFF91F909DADCBC8E469E2E5585DA9914A93CF36838D737CEC90718BFD30CA4E0AD7EF7BB2C6C0A6E26D0C54E2A3C038177057B079B241CC886EA58E145496C932EEF5461D2D68FAA6FEF92BB8A0EB10544E81DE7C3C1FE3BDC25FD0F60DF0B21D55F005AC9F2D0C4E9D39FBF213359AC59FE2C6489149661688918CE6521BA46491296EABA965F6109D3E521B74556CE80ACE4F8A34B57D0FD6913BA3F1C68D56E41735F8D0EDF9E2C293659A73455829F1ACDA870E9F36051DC977C828946B3B89C640340051447B2F67CD5DC2A5AD3B298E655D49019B8A8AD0CE4BB3A3BA7DC10E8A619B12A394027E27060C9CB9C890206114A3F688C154703D468461A9D4A3FCDA140101035923B27498BAF3EE7F0D38A870E85839899052C48809C54D266830EDE8B5BA0F85C7BA5CC857DDC41D6013D51CB64B7F7F1258C9B70C9A2109DEE3416880253E05B4AB7191A4E4411154E84F623138D755CBD55F9CE28CB6560A4B9D8B2D391CB52FF989A147F48BB17587E1C382ACE220619E5DDE43EA51F711CDAAED45F9CC10EC1713DB50FB7DE410CD39F97A6779AFFC4A0B2C889A15C606382F431BDDA0186889DDD99FFC7EF6A871DE751BD0D3825F1290C0853C488675B4F29DB3EE7B6D14BBE454D8BCB005815725CE413F03DE990AD6F2AFAB259E70074CE4B7F9800FF680715F3FD20A605366B32CC7632C2E703F0084A1D821B7F760A324B3AD5E65D9098DACB039C75F9DB9F9A85820CDC9A779D3722E3C35480D8A7286E2D36FEE7E8A14D32F3C192C39E67ECD7693B3280266CA07A06A3BF118DC9EAE1A23F4034CD976B32D334365058AB3C8DF0BF69879C8FDF90FE33F61205ABB6A89369DF4C96476D77B6C79C370F853E4FA49C186C221411F7C504D5CECD66114649119C26FF8000433F4F7392CDC073D51B3D15210ED8BEB5A2EB60645F8A4FA228B971F347D94B9ACD102605968AB2F7ED6635B0A90A7AE75F3E526F86F6A062C77BE9B0391BFA87C219D258E5C3FD64D3CB360F96DEB05311DCAB0B5A0BD9AB1BD36E4F9C4AA62BDAADA7404B08FF4328FF5AA0D9651B676B23855845DF4712980E04262C6D7B6CA5B4F4941EC0F8DC4835355559FEC78D06E41EC597B47B74C1E5AD7C61A987B5A88D1ED4362B3C132967EC09182E4BE876BD86F1D5C3B1632A8F56E13125C0387454E66C6BA34412E509F1736FA4FC9694AC550979AB064389577038662628922316BD7F042B6A69B516F46A56C28C2139A3506AB7B4283BC8A383748C9BC24504993C2B2B42A83C362CFC1798B342A9510BF37654FFC41A2DD3B14AE1F23F349CF7F920A07923AAF8E106A83929A85200E2CCF4BF4D78418A37DE65A5B4F9D270DD3213910E765F8C8FC567B2BA1062153F9DFA639779418EB343924567B0E42D85015BF2F3379027973C080107285650AF8CAEF9B892E607DD3321914EEE134B3DF7282ED9EC79FCAB130A15357A2B858FA77108D9B086263A08B482DCC375F0C4CFC5084D3F1181FD4F64C04B3B8088E9E4D18FB75B376890798DE7BB1E85132A7D92E2E0EACDC92EA04B847FD07B9DB141F0CD1C823C39EB20C0C8F53724DD314305A2849044EFC32F0F0535DB38219C98FD8BBE0A8CD897FE00DC500D9F44288468B03C8E0301E2555E863128FF3F9649F03275EF56204EDAD48B20E05558EA52A2813E998E9BCDBA3426E53D2A3B3C047F42FEE803C5561392887C3FA2449444D6CDFE4A89A9396F7F6BE56747961C021CDED77CDA3230D30CFF132A8A6FF524FF7E1E6335D6C97D5769FD62B1BE97675770286712A4B72D8FD3B3674EB8E71491D70508F9B9A1624C8A4F9EDE2EE27CD3205E6890FF8314D840CD3C270DAB6A4CCF896A7C3195E766F96E67381AF09D303A22C62CB1D6C66DD51028508971E2916DBA5DADF4DDF6AED606B16A34DFFFD8BD79072281351AE4C55A9136683A9B78A240254CF3AE877A9061CD17B33487944BEB504D03DC2F0FA8CDD563E45E4FBBE5DA3AD9B9D5E27A8962915B40997FD64F1A10EAB864DE75F67E948B116384DCC14CC27D8964AE7E8D70BB9B8928883E435E34B923BE01F35140CF7EC5D1CBCD0B8FADF0399453F4C048B9D4009A82B8864359B9A5BB53B98934656DD05CC8B677B87740A84D3DE64C49D802E81F5AE95321DC249A466D87CC6F64C2DCB666B4437A75C42D68E1DB5CCCEB1CCE9C68A6E1F47F920CC7299DE922A18D95CC894823B38A900CFC2AE9F23AFAE8675F89D590B0E9BB69C8BE83B9F9EBEF273D0A7EA30690F66CAA88DAF29CDA9BFD3C88A11B02763602F978500BC2DFA0898D83898C09D4FDBFF5928D2DFE9CF6E058BCC1DD30508E58ED1ED170090E523C9413734AD74CE5CAC2732E012FFA6ABF04C6B689CF70F10C04938CAEF9946973F36B3AC4EAF643FA5922BBBCF32C6B648488207D7E7E236351BA4085EDCCC8C6F3BAF37C2B532A5DFE4AF3F65F65E321AB14E3F7F75B6F2930F47BC93FA683842F45B7AE9B432E9D160F67B45413DC31C319ADCB4E075954C7E5C353AB7DB1E422F123C97B83EE25F8A8A66A8F1880819365A8E53BD398D8C73A5EDC546B84780E0BB633C082AE93B0B03ED6C8CC900FDBCF386062516103F618CD8EDDE18F8885ADC860405234121CAF7AA1F9C31AE56B8BE807D8A51C67DA0370FF637D085CE08BE04834FDD95525164A1741117A6F15795D70585BC8355636448504A5DF0576D94FD542F8103D418E99413873D52D11EBD6E46B23CAACBA7898FDA32B33D0CF8B7A4A25611834F309B1AF06DE37B3993CC77EA755466AC4535C5970DAC912D0F8DF0DB18FFC17F8B9882F1DD7E01583B85662C8003E0F694AD2FC72732490A090D25F5933AE71185ACA1260F4719880BB46F1E22F56661BB341AD226814C73FAAAEA6E054D01A5E0A66B525DA998C8CEB1D90125B54D5599BF4714F5D6CAB9D7D205D90D1D0A1CEF7D241CC987F6F9767E73DBE3D734393DA178C72B1F24DC9C2F1E5ADCF10EB893AF6ABF157477A88DA0853E01B7F7D34DD77F429E76814C4974B8D8C2BA4CD8977FDD1156C5CAD5C75FA438876AC8C4BDD8E44843BED62F649E7C993096D26A77B067B4505B9FF6336E30D2B36D1B0C7FA8202F1FB584E47F8C02D5663AAE87575287C5896E3E6EFD143F7E0DEFEE4389EC579EBC9C8D75BDE56B2F7AC703AC85E97EBC6C08B55A29BA3A06C8165FB2D03889E300E39364BC4CD856D67291524C81E884B5153A45D7B53C66751E863594D40CC00A9B23B9B22E40AEAC1D9F12F4D4EC0A73A1456506AEFC318F8AEBBAFA5F8467209F03AFAEF0571863F7735C858776CA4016370AC39794B42509668791F614ABED4F3B31FD92E52E5790E0EBB47344D62E4254935EC21FD3443B62C6CF46FA9E82CDC3A2B58958FEB91AF1E26537BF98734112E2F8C70A4CDB3AF63F60F746339915AAA60CA846C4E2DA28B43018BA24D9A34D348335A4261CBA82A7C390F86B51FA5478E1053A5D7EDC07F2322AC52E0BCAF24FC665928979A9E51079F71A61144A8F13B7F979303271397998B349F1AD62B53EC90D0DED31B429A9448ACE6672AC28A74FF45CD596CE60D64AC247467AEB4E54C6C9A46719DD4D98D37642BF87AF933EE2D0492115392AA79373948D7D4E3BBF67C46E52B1CAB534FCD662F40C0B1F8EE5465FA0C40D6D49DC0DE315BD972B3EB87CF6BB182D507C8F97FA061BA7AE4FC2E5484C5D769AB5BFED418B95AFC1D2D5EC1B243D40586974A1CBE403092438565E8E90AFC4F0F30C474C507BC9CCFE000000000000000000000000000000070B0E161E28343C""") +74bd615dc15e9ddf76b9f9bfe3092d48d80a2e8fe813b8b54d48297a3a3cc255927f7d8eb3bfacf8ba83c73455ef02ad7fb58606a401c0b29d8ee5c2146dee8824eed0d40dc886a5a0f4cb73a0a25c563fb78d9b347c1b0677d5b1f4fd9b01cde28958ff5ed00199921e2d72a63a4d5a3c43b9f5a47f5e80dcac8db898353bcdc754e89b0fd3279ef60fdc3114761c611f5d51a7c4ec9d4a3616376956a6b755d2e162db6df7c916d1054cc9e624a7b05fab4ae9080358497d8172b90bd2fdd8219e86663deec82ba86c2ecf63624c5d7aeee9f1ac56738c58dbc87d968fa3ee5098c51188169b188120015a00ef3a5bc03c52616cd04579604cc1affd3aa92270491673887b232eb65f3c0b2135157b6e57184b10f262605c26424cdf5c3a5694beb6a74ff252df89bd7693abc92ca4998d9c644cc737e8baa2ec6380d10154c212422c069c9d6fd38aca468ac10e08fb4e49b4d734f284c3e641182276a45be15cb2a75b78d52dc63799a5a2e4e800b30871655a507c2d0b6baeaaef0923d67057574559b87d8765a4c3f87ed76f1ab5bfd5eac40870dd7510b3bfcd84dd9ea15e5845626319e5faac3255bd9aa7686aef2410dba1221f67b3a649c5528a7f87f0ce8556e3f32d5c48622844c113454d08855d8a930b1c7d68522a9d284f1970f8944ed9882d515a877c21d3a85cc247da447d8005d72b688cd17490d88c9028c140f70052416815331fab6c073ed191288bfeebaa7325991edf0ad3520628f91d6aad43411e7ad0f8aeb6825f9b9d63b2f7d5c0f18c67d58634a9d85ef2a932cb231cac3f057656ad2c0e87a35fca332f132b68d60e39822409657c06dcc1cc92fae42a6c940c379e1fc61b6af60022a76e52c1a73033d6877fabcf9b17583aac80b5922148aa45434fcd0212634d5009aa509fb35e57905e033fe1026cfd4e227861d5be4e69838a92e070b96e61c747596e3bf27084e804dbf380aacb659ae79cc4c17f20ae64117088e297c82b8df7235974c4eade96a4567891eaaefdd7fc8ed1185a8ada618e440c4b85b698028f7ba29d46010d2f965d357a8b469281f5a2d3ad786092d5954ac780793f70ec4ce0ba58b2d755c590284c0062374d9a1453119d78b900b33d0ae9a7c2becfb014516d6b5a71da7c16c9215008cd1fa18b0e2d4b1a189c698e0ef49d230b7b284283b54cf907710730020e4c64a935ae5817803ea1f295f19464122c952de6870cef17bb4830f74e253ed99fc9d39618d1755003ce2c6434d5b4815a791df5478388dc9d6b3a72fcb326b71163922a7660304a9b9a0dc3a4df7f7d1d12fca8f3337adad6144add960229ed4b0de6eaca288ffd38a0a0ed6e0454e95527c18efbe3a3b4a18885e5f568577d903583ead64d60b82175aa2b19e100068bef823e2e8972feb348ec9f315b0a46d672d17effae1b47d60fcefef137956df1b4addad9587f6769269ba0d4e8d90090ddc2fe579dcca0980787ff8e41837e4306dda5f10d3f63762cb2f1b88558e749402b37ffa8cc75dec83fb44a6ab62260a15bc5f6e55eb7c1bec665ff4fd2a3d6e5360b3965187daff84ea0e42ebd3c33e57be120002e17e27d23cc5db3519afc91d9a6cdfb04bd7ee04a69ed087c4eab2ceeacbc0a0f4d6997f8471cebc6552bcb17e33ee72a197b5025b1499b1a19183fbca863b749758023dcca325bbf934fd1eee220e10ad10a49a3c5d861e91fcccde741b28ee26065812b371e25ade89e9a4bdb74956b9763ae2ed876b012d9c9e1278845806d9b22774b107443293848f2c510ea69fb45283ee91d08784c88f31de801244012ebb472b1a5032ec6c7404a03e6ba6c804aaa7aafacb204e3dbf5b9b7c455ad35a976706b0b217ddb0009562daa02a09e6a16484d4d85a4b5e5760b8b7e05c5310cb9eb1302447fd94b64963f64e2f182e5cac29ccb93233d43c398a7adc0d782da927a5978f7678b693d3c91988eee0c11f8614d351f48a3b35c8a5d1cd343ddd8f913e91f82f13922d84fe4a1c1599eb4574d1b1c3b0664695ad132627f8e24e0422caa6dbc0631d44244eb1025020f3018a14629eed3ebd1020b65ca21cc46480d958f67dff1926f99c7eafc6ff893dff9d804ab937dd9a5249d377eb2a9dcb8461c3a45e010690e8179343c8fdd033a2ceef78f2fb158087c93533d3b12b0d02417eb067cb63b3f961f56f7924d549e8a4ef12fbed383997e41ca1dc7ef6bc6629c947ea1a4750e3de3477c9d278d35f109f877d8af9dbf8a5be216b7a3511792efe170d79309910206de37a69877079a6d74b2a46192bee571b47e64a1458f590203789137bf3fa3a11defc15c00b976ee977e97a173502a3c13e01d1ab7c385f216ba812263096d0ef9d7c0c61dd2656771bae1edd5073e6a0e61991e4c163b5f6847231dbc2dbe261cddf6f31b614158cf41c3baa1e9b82bc2c4624f1be8322fb23f94912c2b89d82152e84f19ec84eab678fc79cb31ab6ffc25a56056066784fa5356cc4a39b33ee83f41ace4e6ba647d43e5717137c294093ba7c4d5d2f462d63b9ee0fde8b02d430179c84e79c168dec2e0a24578d067b6445972e0576cf5517284498e061ccc215898e15bfb1be5d8eadfdebe789188852a4e596474c0aaf581ada0f472ccd1a1ba6705bbbc6b938e2bf0b115557d73c3f456badae8422835bd12fd4f5a48ade113261eff298097c33dab6320603d813a198bcf6cc7fd9ccb78cdab417e6a8047e11867c91ab4072763d5e63369a58e8a3cd53258aca1c13f153c226a356b3c111a6fdb0bb51e5e6fbb400584fd4258bec8ad1b72796f0920a316564fccbd05e9bd5dd98552e04abc6a402ca47a9ed76bac30bd66df28aff95d7b86d95377349b7ff0a775b32dc5d6f726d16821c217f9deec62138e6b7b659d985dbbd57c7af7d6d0b8d234b47b122a02ea2813bfaeea52fac4100abe3567b18640f0e39828798b9788cc51f2cf987cd41602291195d4cd1fa1d1f152a2130fa6631dbf21fa1ffd933dd9137f7d1cc0c7fa133d3e4d04976ad8270ee85887b3d630576b45be5f2600a5c8159cee9154d7a0e4acb1bac445c033e57827908ae303d59564268f14abbf4b616e21b944c907ac9a30646f37d53b6d512f9c3212254d35e87aaced28d5d3bfebbb3c9e06c806a5b2ca6702e276c74d9900e08f8345001b1f720240813243c78aeaabce954018ddeda0ee6b1d7638e97b6d5b159984a901f297f10921a681ffc28834cf5b51c9fc761d327ee9585bd88c425459ab657095f793c8f07b255c84c5a0baf15c6cbf14335031347a03d11ba6ba49536d6812ec4e35dff2641bf4782f3c57d2d8e4b0d5d16b339caa4517ce6e8fe2f13f7d9837adf95500adcde6aa4191fd0cfd66f866c520ad3871f4f3bfaa5d0b8b3e1954bab44ac6b26713d2af52133c704d5237a32ed5e8ae69b897c29358c4a89ebc7431aaa97a031bf243e1a41658c8de7ba7e769e73b0b57a5b53cca25993c43f63244789e41b9be75859efb110390b8cda0aa314f96bc73b176d8cfe5f0acbbfa245ac49aeddc82e2fcfe9742c26a0f6128afbfd02ced63b67c26ed4755ccac4bb26963bf98f29c5146dbe5593d7a5b372d726d23e2947f6d98fa34454f6b9271a0fff5bb32a91b9140ef7e1751b3efe5571629784b271bac9d4b48c7fb0ac426dbd46dbf86aeb137a8c9b0d3025be5d71d7123581ddddac339535825eec433455a38ca8c6d6ddc59f12f6b4fe4e5ecb35bb3ad77a2bcdeb5315dffc072ba16565ae879e52e7652c9a45cf8ca840e913cd71dda69a81a09faaeb51a44f342812df6e88ddb34ce2e6a9a39b72d8128dd973ee94d6f86ac4b95af05940914f40ff800c3b25f3ef7f8a0261700415391ff4e9f8bca688b4ada9639da8e0ed0c754eee0e1d75f7c4e148971e7a72ab0233ee2aa77a4cfd345fa3062b921a9e49d444acafeb8c7796725dc84f2e5629b91f876fdfea92484aef3f28f9645973b47e9c607ab78877b035f64b8df0789fcab17f8d7ad2bf3a30bebd4233dd9ec3761bf23ff636ce7262974b332cbc3033c38bce5f9452dcfe3ed46aa3ae7c2c133160996e93a83ac01c4a50b0bdb0d6fe30c0d2b88122514aca33083a88b86768a46d11808beaef3412ba771eb77a17bf6328581d8213c5a7271adb13ee318f6b11624ac249857237d13c4308fa3aad7e148d0fe8b7a2c32ec48db9c2fc12fc536f5e9356dc83a8b57fc082a687a854ddb1aaace41e07845600cea04572c98a2a5482301d6c6e77be14bfb481ed5d36d9ead04ebd29e2c72f6855d4e13c58b338608923ff7ce5d366dfa8692b92c5356b6980d7ba133a979cc5f0e5fa066b575b0f7fac0e4eb0b531e404dfe328ee6ef263fc652a5ed151585d7fa47b11edba2b6ea5aca517b2bf5a38785caee5096354f4b703b8f2b6e2e7cec9b3c4fe09b0785734ef10555eca3e0fac89bc0293db20f64891f4b2773e2a2124e64ca5e5904c5d17e5d8dae7bd268c8a537d6fb7f11287a49e63e028186f9686b3bc6ba6c55a851f28804f53a0bd43098a63f5c005c4d3970cef231379a46561d41a94c18b2141843896a3644f1f19675ca47b4bceb6da613c0800c214df0c543dc6449831a7486dce0a6f9a349a4327209ffd5d240344912fe4315d9f38ed9e9995c814864de81e093517ab59e4ac5ff9d3c625c2e3db325092eeb5dacc6c3e5e3841b6df280543ab79b7edaa510dd39fdc44640b37f1cf44160c067432d32e4d83e60064e803a7c2bb5749e8cfb4c65f4fd515a15db304930279e95cbdaf3df8960f59ab547d527031d3d63d94d937a3115d3405e622a3f0a6c14c8aadb7464d5da999f16b327b61e9ed9296b0a8ffa10bf4ee900c2a3b55ac356f98076b705a8712613844aad76f961cf4829a1ba18238f2265a08c74e0f7ae875c19f70e9f73a328e48a7fd22e5657abb9b393bf766557fd834c6e81b07e1d1d92ff689ad1c794a46e6eb85f4d342caf54a0ed148ede130b7bbe1f1c2e868ffb20ea9c20b45f0311b352b85055d3e162944c91a89d00f2f9cf0e9a93743646379eacaa4ab3e54bcbce08e4ff015d0c424462c2acdf08c747fc3b7c7baee4e909af894c09395b570ae516ae687ac6d75c695b06fd8767b871ee41113b9eb7f5eb7d0d46d88369fed3148798736f31678d06b0d3402bb1577dc0f3f19a0a2f9d101a611d1b33ff99aff52937fc21d44e3f2c293d37b9a901ca71bcbe03965f2a458069c9dad2310b58a0c5662dc113d7ba619ce3e2b66b929e6770ecc3f6026e9ccfead7df2e44cd7e7fae06683a4b5c0a3a77bad76c8754133d7c548bee11be8cc084605f24668b294a6a0a633c7fcbf3822443a90477c8c501fd33c8778848f049a710971853bcbc2ae666493faa6426a96483ad0bcf8ed0c4ef0b58164b202650fce31b3ab76dc96edf271415c5a8b0414d7f60a51f01818b4e8c4df3f35f51f7738ffe534b2f9c2fe2acbf7c5e272a2d1fd4996ed30acb03abb0dee3e099b0430dcd620bbd639f3fb8b32d66c02dbdb262596c6e177d4aa7f74a959e90bd1dbfc061363870c42bd573abce58ac853b85766cd52724f158be47d62a90dfb5f0025e208c9daa5a386433ef5072da5d8938ed6683c7131dc5b0c66a4c4c2e14b04dea6fef564dac183478620e5c0ef74497974222f2788c84523ebc5391516ad6dc540095080042a5a52611cd4bc7785fef1768737ff1d9775a29a3a442f97dedf434d0fcaf2d8ec4931960e5ee03b91c6b16bb050bd9b64c9f8858958e1e6884cb916d6fe9643f05887b97f1696a7c111fc949009cad4f2ffd42f891cdb39292e9183b5eaef8c463a9226e71cf2ea4db2a6c66b7564b38aa04ab38d718aaa8ec5cceb4589e4f72e31e80910d209296e4342c65fae64b55be04a8927f0b9e7bab21f37af331218f43439087bd67d639bdeb92c3f774f7fcfb4fb33171659e00f03537983cd481895349a534395c40addddec7404c6adb90ad2a049ee457528a40821d4e57b94224d686a7ba70b5b2d35102b73de70870bafedf2b30ac3fb7f26679a2471afbe8f9c0f645e7d50d2d9b1e921ec8b84a1493e96e3463d1785b452a58077bd78708c1b54a96d8cb5b186e56cffe16f6ef668ed05cc0967305b409714679cd775168333d5042c9ca581c3ae2ef99e76fc7c42221c2ce3e138bc85e202fd3136c35613396fc259c4e223ea528bf7e0d7a48ee2ca96bb81e687813bf2c04dfde469c649a13816d3ea3e13b2f1fc1f6faf526dea7e3e39715ea1d6542e1a3b007fec2051531404040d929fa91c88a73ee9a717a93df44430598fa2d5922564a73b77651f24a4265c83ff09b25daf7c1b682da1498d5377ec73b00b408a4dcc9bfbfeba175220a6928623238412f1937228e9daf416a6c9aeafc06083d4d525c8eaf1f216299aec3d7e9ebf4193a42649fb4b9bbd7dd27367382849ae718394d86adc23270737c8fa8aebbd4001eaad3e4e700000000000000000000000000060e1822292f383e""") ) }; - // Only three are expected to pass, so I repeat to get 10. static SigVerTestCase[] SigVerTestCases87 = new SigVerTestCase[] { new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +f72a05ee9f7d9072a579e3743771e12eb5c748904b15ff67e6a82e1bb77cafc34ea6f06d0f391a3eaef39db6331f1f9660795a5e7415ea21799da7f73b9e11d1f349dd10d258fb5ad40e6421b71a2fb114f893c051929bc4b5e5d9ea311c3c892ab045948fffaf578319fc5a73314fa93a88010bbaca9eb5ad63cf8f88497dd7520d12138628a52a5bb3010a3ee713ae6bd21fbc3ba12e2d444e8d96a3d06be555ac317d856fbfa97b46efcc1b15625457f065c9f8c73c203ea957acd2b865866869399ab9bdae1d30242b31bf8f29e445f07c74afd7e665bc9087d3fc94140393c6b4a81621c534cccbe0018bb3fc3e50342caaaea0f374e23500a2fe2d73dc1b0b0f7047de062b44e2e1362e16dc62306cf4edd306fa423d1b95b847b7974f547f0ee79181a4937094f1efd2864931048f5fc3535434c2b2df5b846ab4c7817b2814c6b4a984b8a3fe290cb63984fa8daed775fe4c2e452548476b2f33c727a0278b4712ce339fa7c68a6db7fb0c25dbd074a9b3bc5f6bbc22232f2ce264246fda6784f18282c904cec36fdbd92a7474733c63ce05a6e7a911cc85cc7ae477a301f069b62da720879f1ee02469ac49a69119c61f4db5bee7f00d93892b05e57ce3f58de9e3429c9432df433d6e111c8eaa02d1583b28a07dc5b3eb57261b7f158df82255cdac5bc7a559ac2fb30706029b843d304cb3e6b4a67f06f465ba45057e0d1220ada4e636075613acf81ed702ca3f1ee717dab24abd513514d7d893c2d10506f95b3988f875200801bf7a4739ac5cff8a30553131b10a317954c11e490793ddb7ce0faafa9f276ef47ba7545422e15653487300d678806f10e5025a7e9667c456fba359d09a11a17b0d0ac75ce9ea941b0fd218d6f3e81761831b9613c641cd85f658a9aae69a8b2b56342a1d879dd21c8485aaa5c3db1f3e19b00d1c83395b2045ce76a2067773e4cbd9408674184b3c333d3e887ce6c0b576808ced66eaeb8a8cd166b94796d60218d37aaa21ef12ef3b3b548bb72a672629583fd994b9f26759d71c7e15de4b10453ca02a64b37448a5eb632913e084db89ebad69eaa9587c1d205436a871a3ebfa7a2ca6a0b657b615a101e4fa29eb7862e804ab0d6e7a61f973c47171eedfe909807c88a0c9f0536f1c2eeb4826b68adbd4f987449e7a5e45b7efe1eaf09226778522a1998f9d79fc62ec7de72a05bd5e99f6aead845fa9ac32929ca2514671db615c916c0046e36951efa903571926766b8fd96db3e187c9c6355b92ca681a2244767e5bf7c1f565940e072536ced11f37a64036749cfeca9cabf0905e39d6d1a434831bd89492e9bf1a5ab9aab5176e697cfd5b0982266ecffd197a20326783972c972be1c21605398685bfe4091332fc53a396111b24f072d0b0e21e67fdc9a8d8088c1f9dee7430e8c75f69f3750aa6ce9ef7dfbaae0d58de48ae87137260e7a5f9ca430e141aa81921cc02a304dd3cbcb1c444eb96b4e689aa61a77f58cf5546b58b51287f4a9bfacc2096e8f555d5f69f50f5e8efc33715bacd6bc920439fd9eaf9968f6771275e16e286606a860263fd947febbdf046247a460f52f3f5e422a7b88b42ca4fc771dde31076254ed22402836af677b32773a9f331a2314c31925957a96c801fc20da62118b5074cffb95c2d31a0b80ae6fac13c13fcabec3cbe4731aebf1fdd3e4fb00e5a30f368d63cf7366631b56d691664e50367cc20753c6e9f6694ab7d090f94d337b54d00413b38531fa4f5bd9e56842e9574f226de48cc283c4c23fec937a8369d9b1a4bb2150ac0ee50b8da8d2dc874b53de33752d7bab603d1fb49c5ea5ccf7b6be07d6fd11e04dab95ef3b087abf23b1983461efd3a5db010317417fbf59e7fec98746be9be60b51381f3e5647ee7ee8b17e3e6c1157d992339f098e424f335bd17703d7cb4cf3d695f0e2d9c112cc71f8ff0d28ae3e2e3a0ad57051396b7b044054d6408a568aa0fe0bac15265c22d9274c5bf3977b4ca5b441da6dcb301e5e14406ee5a1b7f10e682f55c94fd2c0f6b97e6a75a4d7ed7b641cc2d01a2e18adbd02af4cc798a5c11c4d74a342a6e44e85099d4fca4eb68aaf1314f0f9e157c38b15fda038fbbe2bf1f8b3a4464c57104786e92dbd18c6e69c3bf6a6700b1b0873551e5f949ee94bbea0ebda0c036804b4fe6664456fd961e7f3141a0c1ab1b985876c998620944f89dd207ff7baba22bd198636102b3ec3deeac711edd17ea302fe9fd99897487788a3f5fb117b4d2cc64062a7ddc90f2f421a03044ff7d7a864e3a110fd002a9207f7b3d0214406a30dded64c5c76e04d0b09d3fb8782327172d4f27fef14ab8ec3efa160ebe010203460eb6694d0b6994e5053a03df54537101d48cc63930dc35e5360c3de909f8e060e53ec15ec2652b17a12befdd313bfc01335cd678ca4fed253398a61451e4ab83eeb7c29ef8a617b1cd3a09a470b4ede67593aa3f20ebd3e49e65840a2c5c6abc8a7365d4eb18d73e1f6fb5308ac006c8c43d33477a0b4329b6a9271f02ef6094ac6d236df8d5c95b0111dcde62248cc4bece19fdcd7869e9df88047cda20eee20a663d9c48b856cbe1ac561049b8366dae8e811bf9e307a7ee37a2d801e7fa02cf6177940dc6732544dc9293c751c547068f91dc984bb024b0dfa6c9702adb74df91cb6dfbebe498c0f715ab0cc744f364559929fe1a44855dcc43a6afb49e73643e5160b9b5fcf8df8d11ea90f1e573f94ea1a7f472cedfbd8de99b2748370dde471484c58ae5c337d8d5ebe022e3a1b2498a6897d4d0b4a20e2de6f6ebbda6aa83ab221c9f89bd0807d3461580018d83db68d632e0ec538c3d415d022a4411a664e669711513525f89e1fb47d7d3b54b90d227d5bd64d86a4a7b29266116a804f77db66195ac93070fe6b81d7480c360da18b8b57702ffe608010ece065c42695e2033690d1cc14f167de0bb3e5de2b5340c67b2eef8105b4a0f8d4daf5ee3134aa2ae557f1250abb6101d1494a34716d1b91bdb21afd8566662a5b6d4cdd968bdb2500e754ccb42826de1dac6612a43188b847d69ad8aa23b6745aa965d44d7d82b9ad1044706dafb952e1cf8a9db9681414467fed1471cec2fc9c49562529d7b8b22cd7b825f37783747fdfd2f2bb8f8d95b499cda043db9189d59d66b486485192629ce2ae833e9ef0487f8d9735e1b8651a45dcbf9040197c1b026143b3042117e0ec190942c72f120f13265816a6865113b8c7816f14ebe5ba9afb3e772b61330d0494705a5e31fb7a7823b0ea6553ae1736de468ffc67765d1474d8d2dac5140600718ff82d38ff19468c9f0f7747a3ca90db86d7d7c579d2e47bafcaf92d145250a88d11ad6556e24fef74a857fdd216b5b394f229b70e6dc5be32724cbd6b59889685e9ad1c36335f52e3ca2c4e96d332a950fca062cc31360a2fc405e418a25b237df6a393e92c4c02c987c1d8b88778481a825e3537dd8f1013d64ef1aeb966f0f94038e901b8c1814caa1cc8642497591f9c670888a2b7362543ecea4af57b99a5f1144a797157b842220df4b96ca7088c981f030fce4fa85d29ce754638cae597603793062d5d01acdc08aecc52ba59d8e46cf7eb84c5ccfac75f01cb8ec8c45c761d20d6c59e78bf36df162"""), TestUtils.hexDecode(""" -4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), +67D7F4FE3CC57FC8BE9A3D06BCA0FE4A39F39E3A6158D3E4ADA9CCBABEB542CA67CAC48167928336993C569AB5AE55BF95C8291AE1A1AB2B595C90C0FB19041435F3B411609412630D80DB0C832D413D69C8D3C3CA78BD1BDC24167AF590B67449DAC7F6ECBF87698BF3929FBC874F6FD68551B28E4EEEFDE9A0D0E7FE9E569F1F9893D39C17C3BA7A6211B875A7BCAD0C14194C30D60CDDAD640EAF7A02CC9DAC074779345B83F0D282899B2B9B61F8504BEACA3C02A76611C82F2007953D04FD3C54D7A00DF8F6DE554FD83D1EA5DC841645B706C9D900DEE7862D526245215AC6B9D178E60F9602F1931503864D97F582834DB797CAB60DCDBDAFA3FAE8726B525E8BB69B5E0763FC4ED17FE7CD9C9629273AD5B073B9516F6CD7EE729351C213FDD122E3C11DBC58FD2A501B267AA4AB21364BAA856823816E77B81B6061279FEDA6617247B86073E55B19973BC0E725F34ED4BAF0AFB95E436A9B2290A2B316C18CDC0D9F98F9F6F13C5A3FC767EC0A9A49BE1378E92BC9B3010B41AE52AF409AE0FE27CB816EB2614DA41C796D5F4FAC4A743FE34EF7C0B3A78E0E4A5B439659D4AC27B698550E89A1626FAADF71420F559DF2E808144707B5C02090F754C3BD4EFCEBAF6FA4493C5D48F895FE7674C81F069E1F00E455BF5C965BE2926BD19AF76E20533A6115F4BCF2CC5DD3A49E10A2B3FCC9EEBB2B6E4F25118599062F2AA6CC3A9D86167B1BD08DDB2C53A5E46E1BF4E8C1967866320BA66AB67CE581981F2003B812BA058B75924254EE3715BADB8E6B1B9E4F4AA9844D578CA2F0AD12E1C964685FBFFC87108711E022EA7F63330CA72AF86262838863780F4115138672643E6D9B48C782B8637E01D3D20CFD5C98A1B57720762037FFB12742B4EA8E89E4B32EE7DBFCD5C11E4A6E839A83398ABBC32BA39C6A25922649971D88A102D1019B560C96B820C44551E14509468196CEAFE3B7BC8F253ABFC59FFBC01A13008F77C91B19083A9E7BE733C1A5E558C64557389CA19249CAB77014D0569BAC7812862A610DC6EE074C844A055ADCAAD496F6976C932587BAD9D7E2080F8623C5ED8D9D4FB9EFBDDCC4CCC1284D22A2997824577A619905B0D6E451CAA3B2D30DAD9728FC7623F9ED71F80599D65D9F2AA285BAE393D05C15891472B2DD2ED5CA669785EC4D441F3308EB4BBDAE8FC449962EF9787C39A533847540965601D8BCB6B4299AA636589BFE371D3904E18BC9AAC9B3B6EB8B7E8F322C22A6E01E6B26244F9E39586F124AE4E504FBC9D860A61B20B4C127FD0C55EE810AB9803D810233E6126488A6E95F8ADBB3F8E06D113DE6A3E361209E0D36B326E042CE9D2698DEE469DA15464AFF82D5603434C07CCFC4D956A7D55FE79CC127AAD2A56B34EB10E8B85C3CD5163C4BB8C1083BCE5E5EF986AE028837809641A6AF2B8295B743DD9B03931E755673DBDEDE56F6294270532D685DAF1187137CD7D29248F21B290EB8317E3EB28B62E45E140F4AFC6D1438F81E9EBFC6FC0F1A4146AAD83AD1F0EE2952643E7B6872CB2823AB21A155C281ABCD19E20A52611C6FFAA724578A070935B1A0BFEFBF061101A81227187E14E96B016242DA269FC91253FD827A73743A4BC49FB63E2D830D0FF409AA1C73706D7C2297CBC552CED567DFED72CD15060A522F9B88EC910B03CD2794A9FC07A8FFC5CB97817DC769E64D8C474A305035A49D05B1C572363913A315932E391B62AF291DC203B9A40F04F40EBF26A4AE186056CEC45EB7D21D88CF50258DCB5EF40CB2ECF949B18C72626469978FBE0964C8A25E8C2D27149C2266748F2B06746E8C9E7E2F0977BBBFE3FBEC7353F583FD5F7C2B0139EA928AE1F67004706F6D4ED7BD8D13BC68E0F4A49877C0B2F692936BE5FF99544B2B19B23A97EA6B5F585ABC9E69E689EFE25E15804C650444C479E0DC63C9CA2AEC41A316039EC7F675F1FD7C0476707370CFAEC9C3418CCF30B5D85FE0E15056D6C015DA59F9BE9028D9C2D93434F99DD8C1BDB41FA1EB021BFD0FC12EF0D038CA32B0FE1449342D83CD6BAE43A8CC4077074FB1191A8887BF29238D27415D93880682017470A42872D6CFA729AA2B3F8B37038C83583E4C33256FB871A704527594596FE858777A93D3095767BCAD2FE295352C93D227E1766A59ECEB38FB7C2E3664D6DA0DD4C063975FAB3AB4B68D125AF16D233389D96A337DBC18DA11F37F430C1E49BF8AD30258601CAC9215F32771C6FC2B7BC03B55AE9664E0D719C3B40C3E4FA7DEFED8571CE8E46FDE8701975D94319DC5FFBE93B4FC4898E2EFEB3CCFFB3494AC50BBA364C22A3953F052F62E46D0C35692AF40D2FBF899A23C1A4721375F307E2FDE2E588830753F908FAD96EBD5FC360D742E2CB2C38A7E142C95376ACAE29DE8E1034207D1CBC1DBF2968677AECED152B1EC1AFC195F3320352953F2503227152444BAA74EE8F98F2B4512F7ABB43D7F87889CF1F8C12D9BAB91EFCA5AED21058E322CEB4E59DB4DDE13BE46FBDFB225F4AEDF7137B548503008002A36D7A3E98C0ED65ED9322D66FAD4A741125EA4ABBB26A2FDD7AD136590061E7BC0D5228555D1A59F8A6E4B97ABB61F4B1AD9564E84C000585DF8BB31AE61CD25C9D91D1A1FC21A69AD286CBC7E00F592DFC1C65E2BE755DDF041486F3B52C8F72ACA97A149FE0CE1378236D99EF099A668F6847659F7EF617B66192CA452ECE3010AAC18A65D8964381F561B48D044096DECC22736C902D7E23EFFD26245018D9D7EA9E2F907932A1EBB405BCFD29F7A397C71A5E08962ABEDA5203988A81F787B25EDE84A7D85DE92A2B19974EF7D0378877B82BD7CB28B67F45F7EE625CCD054B44B4CD51802B4FE2E219315CA9F4C24065F5578732DC671C3004D31830DB435C763143CA209D7DDF3F5EA42244E68429102F4D90297B7C987EEDFF0DFA7F31964B76432E1DE27FA38570F2BF64D5FA3F12DD9772618ED2B95F51AC90410350320E19084F1596F6B791AF1EFC24DBFA2B7E30015AB14FAF43B568C5149A1152A47D278B5F01786F242858C210D28812147646A1A3A7CD69996809B784BB2F0053CFE18446F060622FE3B9181AE9175D6CFD8033AA752296016E7BBF639842DD4073AB282FF50F94B9E116C63DDED805277D4FD7987F740EF8118946851A5336A9F6F6E2FE3ECABCC518B31E741AA79AB500D9C6DEFCC437569966EAB1D4BD6CFF8AD0E5698D15F1342ED46CB6DA986F0C4B2B427752C18ADC5070043FFEEBA98569E90C79A3D5E0434119A077A097D69DA6E9AD7E32C6E8875A893F6D69424DCF4C0D4EA12605E5E8A9853E4B58E5659FED6D724CBAF582A89A228F99BE89D88F55095D0627B40B29365863C57F82B9EA22FDE731D1A2D8A9037665213F2C410D4AADCE12CF888DD4AF53FF839E962F0F53BEC60F97133D131C2C8EB588AA7D25EC025B9E821DA8E8FD8E550EC5E4D5923BFDDBAC522D1FA64C503078618B52F452B57874285AFD3F6B182CA6C979734C94F040EBAEDFEB547683E98F4D13F12A252E8839317A827CD97A7C3D81962A25DF7D8C62B57812EAFEA9EEAAD7D6A9E755AE4CF3AF42CA2152F663C1BADA0E653EB165F6FB56D86212378C0B9BD5733D4C37178FFB58E7357487B98DEA35127AB58A804B13E61E6D3E385C96884EA91C744DF6CD44B3EFBEFC79ED19C406AA6ECE144A44F1E78B33046C33EB17E3BF61A17D849493D08F0FCF8232AF2922D96213647A47A05A9A08D28AADD3B3BF412F29063C9D78CDD3385BFA9F8BF06DCDA23FF79A5912D867EE1B0D526718EAFA6F0E231CE6C51959BDCD8D201838A50634F1C6BEBE2E4F5235FD01A6D27B90C58C12D8210692BF68FEA5B8A8651E64EFC1DFCE07EE670D473F29AFA63E080F7675F23E7D2866E5F2F9A525BB657E8BE5933FBED1E206C7BA9FF097EC95B91E14612E16F0F4082F70A1B01EB6219D47C716455F4C1C60948CF3228557E787A3186B4758AD35922AF28BDB328693BAED15487F7448D1796BB9DB5C931EFABB4BE436B2710EA280368A8E20C5782A7FE986417003236BE9CADC560B3D7C2CA92341536CF67D412E855B92D0229C45B1C518D8BFC82DFC9F413D3FB23D37EBD96AA0CD0B39EF88B23609AE0FC2BD16FA9E934329558759F05C8D4C8F3F8728335B659D3986E44508322E47121E592C9DBC6F49656B473EF7DA53FF8EF7BAE07D1BBC68EF4AC369D7F8BE60948F34444C0C443A100443EFC444E7FCF0BC4DB6A2C2C64662A538D1F68F4DB95B0B83DFD744ABCCBE5DA343621F0E182CB9E915B2097C186F1B98E7D8F297C347B60EC26D04B6D9C1FFC01EDB2551FB8D11D49E52956F69CDE0E49E2E7DCC8E7C8E78C41A9B2A01483BAB11733A0943A9B765A5811451C07A195D87060F157D114358E478FBA2F2B755A2A455E9831B77EA9D33FAEDC1C562E1CFBD8DE156FAEFF10AF655713E36FB508342D9B4A239D6DB786CF9F57E1C39AE65A7329E434AA88C68F82359E6F057873968F9FB63D898F24BC13C0F7748F92E404C6185CE24C98D4E4D8D4B3C129CB46C614E773A89EAD73CF0C30CD7E6C9F6435F7C83A4C3F877E034755EAFC5F30ECE03F6413F4C7DCCD01649B6ACA9C1C3AC3D112F216AB852A27DB3B846CAED86B76FB699AA7623548EADFE6D16AAF5A3ECCC298D5CAA7E84ADA0B75290FC6ACE736051924DAE8FC5BA6DC9AFEF65F369D054A4A18950E71901F4483A4BDDB2584DEDC31A04C5F8916DA2DE33B37078E5DAF3304344A8AC368A6668464FFD7898A18D10685BDE6D0097F95A3587717F6A3A8827B46653D56E461EF861D6908AB7D865B532DAB37E02A7A6A72A06F25572D83ED6DAA540FE56BFFB2BC9D104A74F135127ECE457991152DD0564BA955971E8C9767DDFAE190052A98A63C4C0DFBD1B51BF60643E4C5EBCA678CE5150F03A6EF09AB0B1C2A0D2C19C2B30A645C7DB9B56B5AACFB862837A38407070DA9C7DDA20B99CAC7B03D10C8F28D6B1C686FD26F9A8FDCEDA6B188D472BC593AD51EA62DCF73D32EED5444484853AD0EFCAA60DD42DD2C50F5AD15DEC7B71BF585581B9F9C68C7C94C154CC7E0D19ABC90508C8EB2DE93F0BE4295973C1F443A1B2419E20F3D5F883912BBD5CDEB938A4452FE0BF2361A9E3B2ADDFBF000DB07EA19B2735CDF0E8E5C7EC5CC7CCE1A9C3E869718272E54CD9875C21DCCBB06FEDE38A4E787D111DC6A253A4604B314FE47A9B6F6FEBA3F8F013A456DBB78B497C4CA7F90CC6145F47C96D266BE5507DEE27E968052CAC85EC87049CDC68D723D8CF89B0C91F67CDE2908C0C71808004A070CFA2EB6408F5FD6108749406FFD3D5DEB6FBEA00FEADDAC4CC0E22A9F6F50B9893CC4CAD028FBB73C1B7BD4292AEAEBEB668859BAD444D0C5FEDE3C469CF28C5C726B59E828C473C8787453BAA3AB2BFC29C691FCAC2CF496ADF3949CC42FB16F3677D456E614B1F88406E6C9DA7DB9937B00764D61C3D347C140FDDABDF8CE5E3E2D385C3FA6FD9F13F3BF8073B5D6AACD5294938DEF9C6ED414FDE4B3C5EC43865A7FB02787E50F94033CFE32A85BBE24B09FAA3B55B8BDDE60E325B691A350F2F128CF74FB5B6DFCD0E946AC7BCFB839B3765616DF35AF29F3AC82F4E2DF7D4AE87A016094719A07B5897105E2B08AE3D807960FED396CF38863E69662238541EE295C06B290404985444F4B28388DD942E51867216C734580B3F1D5BB204B05D4993D6F8ACDC8F16FB77B607FEDA67939A2B6AE285ADB2C98E7D37A81AF0101A5CE39CEB2C67CF99441C1FD980C2C542E7284BD21F1D30E68EF3606C65D3230B5146DAB41D4ECBD5FD89FFC68441BCFED9AD8B4E0B616127A7AA39E84DBD1343E2A41B4DB1AEE0627657438034E890C8EBAE19791705BF6C948C630DB1423D310A34BF151AA8ACF3269253BADDF5B40AB7EB3A7AFE2D7891B925F65EA206F4CA121175E8F348B4162917A68FA768928AEB0504A60C4F42802DA25DCECEC60ACD21FB236080AF1FCC9146BA30AD964416F4B524ACC416B5357206980305555CE3485425EB8F87401FB1D8CCC184C486B5B563242BA9531147D6A2E7C0BEC1A56E083F05344BF97A18D0CE0FE56E8BE869C746D4AAB365225D8871D4F99020DDB1CE2B5D7D2E5DFC8A0DE780CBA0A9B9ABAC87F19C73639965AC2382488387F06199A08F283794E1B8D3580E5CCADE811ABA6881908277624D5395021016DFE21C345B9A21B474043E187403E5B0ECFABE43991865A424BD33D233AC4BD30A3CE73DCF49B58CC4A3D2CE25C54FAB3480FFE0D51A43B71FDB7E1126E66856D263DDC3BF1A31DCDB935DECCF858FA2CE5AC89BF32E36D8009657F11691201290A243B5680E060D2CE30F1BF2444D67DC94A24708F8F9261945D1B5275ECFEAAF40311CED5C3770A1C194EC44501DD25B7F5FE67BCF62D1BF31119F8EA7DEC1CF536C1026A8E72C7B2E167BCAA8673AE5506CF6208F3E1B6057B5D488B29EB84D6F94AB8AF322B8657075B9EAD3297505AA521D601C21540EE71349614CACE0E7F14EF42D6CD5377DDD0241E34CF273A1171135A376B98C53B218503A908577C268F6DD46CA9C26DFF5942998851627474DE9E6B46F49DEDE85CEB993A52D01F6AAD6F96439C18B0DD5A4FD559812227BBC0567A28C1299626B171855AA0C74E2F9B1AAA781D34CA58C72C708AC49F5AE1453902A1FFBB8458E8B4786771780ACAD999F8DB036CF4C3F77AE345817EDA2AD8F7D2AA9228C994F6AEE512F7C2D2AB72F2099EC932D818E495CAC8507B06CDC6702944237DBCE338C20EDC84D958C14233C1884BA09A023BF5284F0B0157048B6AEB508415DF337A553F6435140D0CE5D5CAA77F9137B2C1AD5A02B13738772743F192E53E970DDB401983535CB096F7D98644797F487CFCD18F1B22BA7494D892C1E5AA05E66B1A4326C70E348350C97DBC26CB110AE8289C97CCAAB150020827B7D7AC7913B4FF515583677018949D39CD73BC7DBB90696D5EBDBAE6BD6FC78E3826C8218996F079A387A17456875952B268211891404E80F8360F042EA3D9F7F7BEF772E64FA1EE8B4EBE0A1162A46EC1E9899766BF4D3099AF712A847CC86291B3D6FBF51B3B3CFF87D7DE71E73069619480F6056AAACDB9ED8E228BA075622C2FF242CB050342DF8F02118D071D27D1FDCBFADFF49184F5A100F95E1BCB019864E58E0F02672C8F5FEB97EFA06FBAE6EC3D57A10EC712BE0144323292A2CB27F1B1FCC104140F556D09A6074F853AD4328B00E6F2F24A61A7932311BC999805F2E774DB44ED72ED244A945928B9512556EFCB2BA7BE0E668C41AE7601339F0162CEC0A1AA91C3FEB6A8A40158D7A3560924455B9AFBD4B3881F6C08EC2895C84CEC30CB0F5B499B4A66267C719785F94A9B9F96FCEBEE939AD0FCF42D0E65DC241698DED0EDF1A9BB4147898E6E83851499175105BADFE4CB00B9000404DC92EFB4EBF41D9A9262EDA550DBD0B99353D001F90AA05591100BB678634FDE4E0B1C174222C253870DA3B8A797CAEA9B446309DE5210F9A932D6AD48A4A7361A943C1BC66BFDF75CAF5409034A8768BD535B20996A728A26E28340191E03DB17A7032FFF883EF664FD7351DD37DC2D72F0CC4B80BEDD1DC33BA3046162F5D0003140DF78FA588A9FDBDF778836C6CAE7E5A20FEF030C57867B295712DED14474FB87A301C31214FFBB4F8D166498ED93B6E233A669CB88D441A38A0E5846EF68F5DB20245980CA184878BA8BE1992A0638B058CD3A3A501CACFC818D2B5D7876DB6EB08E9F26430FB06EE0B9E834D1C331B66CD0BCCAD7A66ABF4A9D8F7A872932A3C0B25C5BBCA480159711E0BADCF69A1107B286AB199B210CE95BCBC4244780C074C42B6BD43869F27BD666F9B2541B1561B4C207E9A667EB1E31942697FCEBFD0B920EF80CFBC5CABA6F528187403D7E8262C110458B5382BC376799032362CE57ED39F0D29D7822C408923C29242385CA9749FACA43EB4483E095851E89D24CAC7BA5AAC60815CB5C8C5331CFD66352BC8623D5700F49FD98FFF9E869D5AE173961138D76E00CED6DBA09144083437CC8FF5ACDA10BAEC0081C8BD2F5838666A093B412532C521753C4E11ED0521923D1EE6BEF3B4FABED7467B9C8F75FB24FD8D96759A6146B34EF951C4DF92228C2E58231A8D25E3F08ED5A27BF6041AD7011DB41F815FEA503973D4E7B5798489B261A0AA4D0C32A19D17C584B1702713D1174E542BE4EDCEF27016BFC78118445A63FC1D17FBEE5F71DFF46F1EDCD050239C68DDBDEEFDAE7EB8963B5BB4819186D45191C05AA049E50C4319936C8788AB72744912AF28BBF5CC77C835C35BB4F987DBA6657BC2A7E58B7CE69AF37AF680DC0EA7797B29528AC70D92F295C561E2EE0D0E530854AA19EDC43C01A383035F6A5DFB354E9306962EAECA25EC85B9B78E8A1DF6CA50EEC733F60C81BF812981337F784F8CE07D0C03D8B3E72BEE1FFA55FB92DD0446CEE29D8825CBAF1A6ED295E613FC700FA31167224D99338C4F59B1BB9C1E63CF77476BF84F2001D42E4161F7737B47C1A5F219F6AC8B8E3ADAECA827AFCD6BC0CA09615BCE15F1BD0803BDCBD41E68F781517907EF3DD8E8A33A1E30ED09D7EC1D3605DC72C9232EF9F92475743164E92D953177B98906DFE5E414E134EBB63C79220D4907869CB2D93280F60DBECCC81B532CA336510E2A7F1D631F7BFC517AFF223430F9804C4A4877D8B7A385ED48F390ED9666A56EBD62F6C943D0E52AB1EA247BFB07C05908E99358A51E6111486133F4A6BE3BAF6B2D4C01529925ED911CE728B4CE4E8CF8379BD216108BF964496269BE76379912E94A4984B890A4BBB9692107D56AAADAF27ADE475E98A566C0C9E33DD1970A3DFF0E2F79197F6315E320BEB5E2CA3E3C904B557075981118B363042BA687DC682F13D213974B1647FB43DF7FA168C9D4F599C5BDFF2941C111C6C43FC75E69C290601EBC9F23D665F944A9B75932DF7792CB8A005A7CC83DD071376DB11F9C950B38B270E06C907FAA102AC76722325934755F53F3650B42D0FF293FA37086241C00E99B9C03FCE21F8D7555CFA93D09A0EAEE3733A8A5E4C45E74DD5EBFFD2F75EA60942BE34412BC82FC9959CFA155DC87FFA0AFFC1E7CA5057EE016B9751C16DF25610F1981A08B8E3352254AFA433E9B86D3CC13FE9B5B7FBDAD83CFA0FFE511E44412DFF1636BCBB49E9769FC52B302AFC7A96A3DFB233831007CFD6C302CCABC119DAD45EE63303DFA1F11C39C702AAAE00FCDCA913371F158BE5493A9B5C3B06AF66C8D5DE2BF9563FB617D1490FF6510971203DD25B27E1AFB289DF894396B8C26548BD53B320203AAF053B19CFC815C5D37E3115FD6CF8231B88FE4C330545F131A01124BB2487A3363B3E534BFD38B1D5138F8887EA63776D78783AC45675ED598617077AEAD86206B9FF61E3669C93C3C3A3A8F39E7848A88C0F94878E5D359C22BAE891FC7478BC8227FF320B047D0DFFC8218C1110136FA803EF6395E52DB8326CE8E3AA928CE42FBA04B1E7F1AC7B73296CBC1567090B9E92238859A87686D8E623B780F0376B8537F41B1BB102CC8C480C0B6C069F562468D4E1FE111B24D51F63E9BD38C47F35D8C2B5BE2E737274229974CC4CA63BD0E1F0446F6C4448EDB2498F2376EE26BDD8581242703715AD434E425908D61EAF865FAC5E82578EEB0525F54320B6C264F37DA36B55C2308D4FC6C7FB2F4D12A88CAFD93953193B7CC46804A0C464740B4972A71B7EAB5F6098FF78BDD452540AC5BAA894C10CD69A992217B422C88CC7849B4D8357D86234449B452AB4D49EDB1D2769512CF8A797F5FFF4E1E0A3FBDE292D91722D71322F0BD48C68A3CC998D03F7581EA7B5F5150E7AF58A076D09D103E9F64E61A2D375461007210DB511EA89FC4EEA75FFC71F7BF31400E7783F12F69A1EB5B7228952E2CD1D6FD57109237BDC024780006C229EAD71EBF4B543647FDD9216D98DC78B43CFEAE12166CDEDDE09B52BDCBFF089B1F7427EAECC21CCAF3FD5A35EE72C3107DF0670891E1AE12C1FB81581F3A45480F1FE06BECE6A494074FF3C47F90C961E371E8014707AB0FD004D19166140AF7B1C9D6B7E4B6826601AE104CE18E17939CF77C2A31F711D5C7D5126F4CB642178CE542973466696FAC1A0858ED62E4F2741E47B83B97DCF4610B1E4E262E700A06FDBFC6709BB1D4AFA7C20EFB72E0D623389DCCB049054CBBB322E63B09176E2903DBCE49083B01EB07F140D498B793E149573D8CA91DD2BBF8DEABAD9CECA0F896A7B306C22F8A761A65CE2BC1358A6ED07327AA0FF4C0B6E2906882A12C50D61D021A1316646461013D8169C4B54C61614CC9EDB2CE0AB0BAC96B36908BA3ABDF92D11D96EBBB9A60DA780AA58B804DC6F91E54D82068FE2FB10EC1FED54B794836F54503135A7F91921E2BBC2A61C99B6A0BDC04FBD2D4E7E430F16B5D3C7F06243517452BB7D2D51340BAF550D260A26A2F3B5451AD7D4E3A70CAF63F92E25D137C9E9B1433CAA5502DA269211F58AF2720FE3F899282C2C02B78E66D3302C5B9DC04B98197D3685EC4E6D4603D79B357282932689C2928361022E79C197A470212A69AC2BFC7505366CBB2BAB8D2E31314FFD77A04E85076D76948E836CF2A87918D43208CD856FFA33740FCAFFF9F690B2E6B33F1D89F65C71"""), TestUtils.hexDecode(""" -4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") +a7a908a5bd14b14de2439fdbaba72b5ee9bd54df9c52b17b2e3561949f4739205c112010edf1acd95513c740e1a23beab2269f5db9b432bbbee5db53bddc1fd355d8ee23f018cdf3108404b0d1ddd3b815dfa8b1c724bfc8f9e0c0e610a8b1260ae33ed202e1e270cb27755f10404dd66d3d32c530aed7963b5ae36aa4c1d0ef442b149b71a0756c9e016b7ff63fb4ed25c59edb578d01a0dcf04935a4b5609f4018a32d18f9a59f0edc0d2e90bd7e0ae75b5402652dfa30cc0938c7e35b3666093157f1c2f6ad80024539443557db996783056c63730cfa60c46c86b79ce446e2e66d2b279c192cb4773409fb8cb918e363220c0c1ed95e9a7524d0c0ac53c172eb3fe311b14d16c2460d0e583aa3ce251057b5ca59fee59f72627fb3b1c8e74a8920f10ee9f96a080d6f0a143fdf029c71f20451757b2519fe0c10e006134a2ef8d51cff472dfa63f934e13fa2d9f9705092712bca99be482313668f52a5e996a59511ab9bed2a7a4ec0ec1f17a3df944d4222b32e7c4826cdeb3abdbf325f7f9c76f5b7de28b1d5208ce9e19e853b90c9c7e2a26cd1590152fb61ae4fe56238b5e52fdaa6a17afbe5078d4af5403b620acc4942d01a432849fb5a6bc19bac30efed04e629d3caa74fb0d7c2873a3609c0b6f8c41d88d394bce13f3a144f0fb3d60a5ed31225badb206848c13c156a2b7be5d9df517d5d71ea3b578f90cc85fa72c3057442c95571dd20c9c9b1424566a408f6e135d74728b4b1aa1918aa38dd2108346a3189f54c9ee83684b1630a29a69d6280e47099ef989c3907b95fa9c1119152d97f9d9181fe2bb89759987a7dc16556223bb0738d1a10ad7959270bb737fc7601f2552a322181e1730228c4f0889cf196bb570002cc439ddb83bbea27f5ad9db5e62ef69290368544e271dad0e880a032a188cf4ae1b290f6576ea5c20ff9ac3b3950566fb8081768a4bd804c22539684572105505d2d2507308e5e50d05ddf24655089c2cfa4185265737894310f66d29551e842e9df5dc36d2e1a894d10504099511c68a0a81900c70fc6c2b32e84587d6e4654c97ada0ac1b7493a8efb756a4aa0278b773cd302f0746a6a18e3b1aea24ffcb32a57844955bab9abb85076ebbc568b4c5ecc898f9a1d9e65c6852c64a1995733420e0ba5a61329b191e750e212a68ee37717ca8961593f146e0093d1b70f07cca6b6f2805f48e66c1b3d6405ae5f6a95fe27d427482fcc5bbbc2c5e0e0449c73eadbdc261ee9636bfdea73a13c0a9ad432b4b7037432c799cff8051a331b261028739bfcb17544732bea4c2c3ec1d42685d007740bf49d8f8caa8bc31c7e59f9ca033f27eeb57f03af68b8ca30a27f78c06dd3a7f821f58579353c325982273415975b03cd8649c9632374f25bf010aa1c0bb82eabba168c3e2ed17213734718cff337eafe9e48b6ab79655e98a38bb1f74519aa07ad10529370ea2581f99c59a824a5ee0747fb6bce34396514a6a3dc4755e913304a28f4bf4019a42acda382a7a7211a30b2878264c4266043cbdbe2c711fd0da53106b0b5b16e78bcd1a075b253c98cb0aa9b980af82425751a7192e42f5057d5e5e71a2d0dcc9404035e63a905133c7724ffa110c942c54e8970dcbcf99fe1987931a5fc14e83b731aad5f2ec0a29f6872e43f18a94f5f9f11e2b7508ebe29a803fe159aabe2cdc242a6ffe976044feedd0b5826c129dec3c05764451feb8b99953a635e7250e74772da18755e819be7db6560b5ebe2de9eac9fdd490a6aaeff8bf568a38f70bd0ca443d336ae6776212e0d99593f4123d91dff7ef68222d497d1799ebe6decd2f7acc6c363e43dfdf9f72b88c25e9bf740cd1207421b476ec3b68843cdd285e292986409aa4ef04ce4b6479c95e52ccc8b5b0247afb94f43af536ad9ee79b58b636afa64a2be3fb22fd128f1f1f05b949921bb050892ed61cbcdf66b11ec042eaac3765d7aa524c0cb022d386032ed7449262529d2a6eb8c5a7a539deb3d1db814f0284e9dee64661f8cf3906a9802efb7fb5c4033502eeccdafd77a6d0f6ecbbbd39aa21f14afc3ec5def48b48afcf5ec99acefeb3007a90a54da935eb5d4aaa68502b1c469acb166646a3af67fdbb51d1338085d2798174db7ce74f2ea9c61a50a6fbb718dbf62ac33dcb7fa80aa982924f4310adbc07b2b672438c837d1c58eb8b9093229cab0d6047091b4152a75beffe7b17e44989dbef1c68feacf11a47d9dcbb230b9b180f9a7d10036ccad63454f3da00537078db225cb746466f1d56df35fd9380620e37f4692aa0b9b5bb1784a4cb80a53a25bd9cbd7ffd2d3177ac7023ebd1127adc732ef7d4963f70b130af5c33a824c3b7ed6d2e1bbced1959560cb753917781af33478ffb947488c8372d227e5efc9f5db11bb010c278cb40ead48ae49b2df5f927363a9e78bc125072929ef80efee18c7592271393b6f29cd1e339e512b1214fc5757b1ddf0bd1b9742a0a11ce469a78866b24035d8499c42be66110a624c928641e59078bd1cf6771c7446bd1977578c165695c4d6aa4ba9383ecd2c41677c3c5cf9af096f4c8c9f5f244e5395ef1db825d2593554c7c741ff0e0540f0ec897a1d8cd88d2f86a1aa21e5473b1fd21a8065d49d682d4dce206f4b511f4d466a56be1bd99d1335b17f4170a08899c2015e687f1caf70140770dddc885cac8c29dffa7d5df823b3b8d64e96008f5aed8d52ed710375e34a7743a98f714dbfaf70e78b177156634c0ae931f5082d2c6b7e8d7b1f025802ad9f74c711e218955938b14fec5d0983bd2f44d9288edb72bd1eb41839297ba5915e518a1e57e28a4ef8eadbc6ac4e14b4f61ff5834b1fc6f21a8065f7e84cd99e1d86cc9fb8582fd40eb4f1f1f4e05161cba9e54c823e77f882cdabd8ec501be12e855e0f492fe572311a01e2aa73c9c0c0ef43df7256ce9a41502e15d7fc76a3786dfc2812ba4451ee9a4d159d1052e0fcac791df2027258c5f0ef51d23498d0ef333c59eaba21765783f7fe51db331be068ec4e3e779eb5cd47e036a5bfb6634dae1e4fc719636a3e4944b64af890b1ec70f89b73b33b626d5b3f4c33e45ffae3472929818e1de7eae0f0135937f4e065b2b1dd045ba8372820a294d4a4c9d44af6e321ff565c69ffe8babd43d095509163bbf8a503ec55588ac3c58074a96f3e32499a6845387f9f8b4520cdd3ad129165501d28b68339c1b0b43dd1dac6d02fa89b3c381373a94c1a59ef4839a671b7fcd08c61cb12b6c66edb631988fdead1a818f843f070a66ec46523f8879d43c98e3a4884c8683f9eb73a4d186fb43a343165202bbe8e1735749b64c9ee36f062f2f8129e227ef8d38a7f35677b01f68162d9c5310aec1a8f8ab1365546ae313c90be351030641004c735c2ffb07d7edfdd7434ba984790cc7c3c843c23531593caf985d63c4eef255962825a44a2c9a5c73d1878b6e149fa754a46b77239539851b2adaa293dc29cac659a0d0840bc545401984682144d7b651b125dcbc3ac272edd7e8805e086e7e33e2367beeee06458dd2dd80deb7e36ae6f9d10f84459a9b828aca738136f2dfdec4dddb3dc6c0ca72e2bf19b5b87ed28ff661de8ae64d7dcbfb71f17f362897e12e94f3197e58b2d62eb849a169524ab78962b25288f87321a753241b123b2aee98e60e2ad7341d8e1796a160932c51ab8c6a0c97b188ab05dab278cb64f025a42ff8e40a424858f7e56b27d0eb08746def560c8dfd11bc359b8afb1a3b922bd34dd1f4588572d26401074e4ef4f37500d39456e458b6a9f30b94003fd110987ecec56629a013245b48be1f8df1b2ad80b3097552841186ee787be2e8ebd555253f59e12c255db9967f8f506746b8fa49203e4b2bb48d04bc117338c40a6badaad1bf8f100b8420aff9231d20bdb2e78ce173b12a87c83f0b594ee7225d4d0b975a60ad615f8a21f3a4abf819bad041fd01c740233cbed5e690e6061998af1f0fa406862025feddd62ee72ef314eb3b12d40227d92de05a960cfe96707f9c9fe8d51728fc8258531ad38cb8206d978283436f6b7aea2282cf63b27b639c78abdaa21be576a55388febd14807625391dbb8689896d08ca7d41d28d6cd342426dbcec96d6d44e78739818a757a94f615cfed9134e38c4d34569242c51b8992aa6419c24b4a80c9593ff77d8bc840e6bc7328b69a95354606602f0f8f13d480166c4c69fb5c74fe5874ec7d98a9170f47096fab89d9ada1285aa2ffcc968ba5dab962248471b2de8ac7126988362b845127bee0edadac224e552b0bd83f0a0d9439bf24de27d54243f8106b5e95716d835a7813fe504f195b6f2d28e12dc041f50e31858cc79ed3a143d9c7f4fc8badcfc3a8b756150168ec302ede64999450b0359b368e3acf00bbc9608aea9c5714dda27888d63f60830cfa1ce2b224b854136a204dbed8e034cb5c77f9b86ea2d342bf3a0b37a2fe3978e4a9c7d881655014bb23d8617ff04f6bdf39c01da6a324ac58805396ad35733e42629ef4ceaf840fc83ccdb66e96c6e148256059e3b9eb1e8de429c77f8fff51bc994fe35900059b044c1ef5b336031f3b67d3bd471db0b7c8138b36ece1f56101e9298d7f222fa9f48b9f195f1dd87a869bf8cd0810e424b82cf6841e686f91fa3c443c7e7e547f7b920b774207212de69e7e4ac8d79b45d076b82d8d8d78c9c55aa6f57a7fbfa48e03005bb65fce5548f3fe6ba2af580f5881ff739a098f7c5841e4f1351c5afb3258c39bb39f96e751c043c98b46f218b44aeb90947d291cf6042aecf045cb51fcd687769eb88f07099d3718de8a836f7af203028a5560544f170099475f374f8cd296e4daaf3963d3ac620966584659600233838d0c5c62796df7085b19d42982315cde7335f73178cecd12708124004b937fe29ee2b72fc91b94e2a6a433b2a35449bbe0bae6b866e1a10b4021357e7dabc76c6b9eebf238473e953abcedffb63b4dcf4f73dc21a2beae5036cfec91e22dba6470d2ce404a7b22883b8735567dca179df3d908a725e2e5af4201b6be97f11e9dd58ec44256e2fc223156a07040bb3008aa633a70c76879a4311918a748c98c9f2e485ad45b90b9a59defbfe2741b96904f1619ae66a70180a1c3b550cb2fab06f80d4fd2ec44cfc09ed26da85163f7c51e8357ea149774b77c41a11dca2b70ea2a6f82375f61a4e1815cd019220a8ce7a24b6f94eb3aabab0241c8c585c1d35422268a3c9bb9ef43d3a3490bb231fab37a466723ee47366d71f6131f52dcdb19768a911ae8d9b11e31c946e0a663171d53ec51688603bdea9d2830bc87ebe860c8f7bc1ee1d18980f95ded0b462764d840b70d4dba5e022110993cbf58888ae3bd6dff8f4b2e1acf367df31d03375e45379e33defb73b2a605f402d364d8b9f7e48223c979239ed5b2b9707555a698bffb93200ba565b38453c9452186300ecebb1294db3a092b3ea1ff78ee1bc1f85a51f50d1fca7ca0d634a027ea705ec6cbc10ce51fa13afa4e7e756eed9d19e9c0b8a9daa9f00b11d2248ef3dd74bd01ae7a93ea2ad16fd0f0a8321a67d39b07eb49418f475513075082fd9e0fddb7d225d064d354c2b3f57343220211cfce889e69149b5db154054dde2736df5efc993e743ac1445e676d6401b5039834fe10c49011e3f03bcae6cfc3eb2ecb8f8055d6a17de626ce8caf8d8061f7addb6fc9c229a2b3152bb17e6c40ce3ff89acee7fb5ec800fd18ad698306e2c25146f22aaa62aef8e054ae7730d2dc0477c51b0efe2148ffd7daea402118658bbe0cf265e29a046258d3b3977b0305d30bb496e24e0ed6d997b235c310f36f4cc884abf0fe62b6fd3f164914e6d78c6d4abc9d130a442163b4f2b3234286ab7b361ad062c6d6d4a2908e3033ae5db787717a6a4abbd5975faa48ad91738d0b29f50ae36d0712fcb86ed1820d9bea175e295c0e9213be5226414718842d3539d7eedd89d6459eb50cc34a058b8b453d38890d76893be1de65d6d2cc8d23156e2a414073aebea846bc157a92feee6f6a256fcf4346ea061041774103be4161229c079c5a529e3f375256f9731a60d7c106aea032927baf6b3991c2bfb69433a3f21bdb0271132eb43e027b404cd9a882798995351facc5acea7b2b006b649fd1cdf6628fdca1e4fbbc71006743ac2767501b2116567b911deedf5936175edc26a65a6fcb29dabbc3f8db466a21a08fc34267c557e6371f23b7ab7f698565d9161b0a658cdd82278c7c0f9728f5a63d821260d2b33428f728bfdc32e3f3d3050d2b87e19dfc9603363b2718c039751746396eed60cb7fcf3f7b965503d6ebab7e04faab921a143c37b8fd68260f3f4e6e0ee396876c2df262e5f55d145e410294d1da139ecf80c792e12f121862b6edf6cc5a9de9403a0d141a1d4eb8ca2e8aabb6babc44cad5fd4d647ea147d00e122633575f94b2d0f10a1e34570b0c2232505e7a898bb4bbcf0000000000000000000000000000000000000000000000000000070d111517212531""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +a12619d8176840867fd76c85b14a43f92b39487e19dc0bc5078a6ad5bb20ca92e505b3f93603bb83db02fa9bdf62c7265a7cfaea6cacdcd374e271d3d6ac510ce9158b03163e38327a68a1ecd5250c3d4dd32837d802e124d4fed040f7e14db378d1b8c3609a47c641fb9d9f9895fc968e95dd51c36b55fbbcbb5d0dc8e7067401c983eb0d0e31158e96960541f7bc0a721c2124e88eef835bc88387ce8e50f08da1f192499f6a722f46e2edaf1fa459fa98b753c8bc6c9b494d21d95b76e39e0b296279bfb37a0d7ccbb804d0098461325a53e8c61a098a8a19ef767200de1de9a50867f0860b37f022720d0a050ac9ec738c56f3839a0ecc0a6825adfe08efa4d5aff1314d4345cf74f75d44c2babfd2fe751397ca453a1b835471fb6afa4d33405ec9f3940d03cb1b1baade4088a9958c3fe56dbdef0ef1f7482ad9aab7c05cc5b1d6b537eebcb3453dea0961cfc8c370923dd97b4ed7c37ad628ea456958d98aca0e8a0c94f027e359b3a6d3a0401720899a090cb163b8643b9247f58fffdbab10d76517ac25c3cdb65f8fb9fa8ed5370f4005cdd88ee38c2e6c84ee06857618bb143db9462c256b0242a0be101fd459c180b5f1a1e54a123e0577d38e1616fdcc2480784c25c8e5da8740d132be3f5a498be74eba102bdad5716c9b9af34628c1a9dfe14b44aa52b69e5aa21f482f14d76228d49cf73c4710679e663be5242df2de684f5e1538827f612e7d2e2df673c97b4262990b4af83163041564c8f82abd740f434cdaf68e3ba0b33fa68a63807aee5b998091fb4c6cdfa37b4b9379d4e841054cd0d4df3b353e5c1960cebc031521da09cd4875fcd216ac0a57f3a95db3ccb6415f6da06dcb9cfc1f40d7024bc619a7267a78e0b1b8431e25580915c2dc2b328ad88ca3b551f271b217b0e1f749dd53c6d2de9ac24f93b683f268c2ffdeb1d421dd91ad3b3f9db1af344d27ee4bba7c6add4340277aac9759de7612f64192652e464269e919f73e50372df8d9854471b997fd4d84320fc17eb53da8c7980b36ae1351221d9a8a1f893a897e6043ef1962711cc4babf1b6a08353b03bed793d3d5c1d2da8aa8f6303a5e74fe2570876c9fed2e65db4b73a6285b68aac8d7eae27ea873d07f28d55f98b65bb0e19fd2d4302b5b0258b11d40a5afa0c7661b6394c1d0e533545e45c185a38b98a2f54010c87a58b321b6c5da226b4a326700457410903c2ccd591adda69ed0799543cabd39019314aeaa125ffbe4cd71abb849998e98d781780fb1425d32339f20f5b8562888aaab6beba58ec69c40520ab2f62d1d30b66eef52419196796ca59fd0d990f09f7375a6f32c2a473b2e58ae5ee07d8af938993c1b9b827936d103910719b6d46851d28e9d14189e004637c494f48a0c62cb5cc421ac919222cea674c8bb40fff2021352a7c504160ba7fb11a67b8e7743a11f8be1149e61961e82b284193d965632927a17b0d5dbcbafb732333a7fdbd7b14ad0e74f63999193fbd5613993997fd8cc79fb77b7f1228cef72acb76fcd9187dbb40135d3f6da905dfd5db52c61fad72767aa72c120d8b60e831fcd1e85c2d3a4262fd098e019ff4775f8b2506c33f1ac969da1a5b4dddeaaeae533916c18cc5e986b9f1ec39a374d375a1cfe8b41422ea4b316a50be72f56ab39e6107234ecb087031083b2cdc34076d76b0a25a3dc6523dab07fdc55e88dbd6ab7355f464db2636a6efe2eb2f12502f2ab38acb143058e636536fcbf6bc50fca85b353179f506c8647dbda379e0f1d04df6f785e56486144d5568579250bc18088714653df6350b6618889f28ac4117bd2c82e9f1ee80c29cb9d41541bdf27589b63dc300d49b72e1fd9f9836038396b569b4c02a58ad98e344a5a7a72c907058a193d840388e1f3a23a7ae512ca1e3ae2ad910ef498b19b0678a6b382b0aeffff8aa26851393f602dcf3348a303439b63c4856756b8dfd4fefc601c2f39b68e6274c6bcc58e56859b5d3b22b90ddc5047ddc813baa7fe0302833101a4bd217adfb3de05dccc25bc0f786ba55b8c498fb92203ebf2441b087d28799901452abeb87fbe8e6eca37342e782978f187d471957530379f573fef8d5b059e6a080be35fccd10b1d880609583488c15c49c4ae298a313ee008ff66c7eae1f78a657ab126d5402d4ed70fe9b93f278f2282c20763592bff5e6f51b415717ed651e99a93de7312811a35240b70f8a90449906b62c83a78e6c76449de415c84951001f2bc61c8c99d88c2cfa44858a91d4ce5323a3865e4b85bc281e5139f219d00ae9ef8f850778571fba831394774dfb237ceafeea621d6b32b8480ea566eaa95b4dc31dea36dbcbc8f4a370b7273047dce6ab39ec54ae2225eb64398568358eede9566d2a0a19794b5efa5b4fcf742b6098c800f693a26b3cd8d2834417a471f55c9160bee9ef34792b80f6692a066a951ddc520dd1cfe9354a3229cf030b625e7bc0a2bc60847d7bce334c1629f73b9f4d44ab5f0ba588edbe5a9c477a6c4716e8a8bdc47582b25f9cf94b349ce8aec25c8bf23efd8b393f66ff457a92cab8f04dd039c54ab0d42899410393507733e29d2094dbf57341108082ad11a127edf57d5f9b47e5a31e30c7e8708a00d9dd5d33eac2c3418435ef1f2e9d7b675eced020c4b38abafee74e66c3f6fd18126087a0154a429b40603d4f95a7db725d167690feaec9b9654bcdfd181741af7f0c00b8f8c558f6fffd0fed1b3d3c501ea911f0709bed24e57a68bda19441a3c420bea91f0b43733e4fbf23072727131315314933924a50cdff938c1e4754a05447a09b5b01140b4b095986fa0c5f065d36d83d47974c86c29f09f3bb4306f8927d4c7843d16dc9ad1ea594d742cabef956829042d550137aa38cd98be854b3dc02442c8358a4994ebcf253078dae428d084de52936079da403eca30b93d4ca5f3b0f40ad15052fe501d27c63a6af4f1ec3ce9dd63be7b3c1fcdd539f6d27cb58f9e6487cb95d268caa6f3e98c761bb651627c193e2e9a9b99fa56b4b608990983c8f4d4d14dcbdcc43b56fc8d35c62656188fdacf1970aa4dcd8e4de72ce813150e1ee2c9ee3ce5eca09fdd8e9d518ce0a4c32bccef10e566b305c0a93bb58680908988b84fb90087387fc41b013367d170dd64e11f7f245351f24d054d18ced50faf5fa58c30732874b76163b5e38a0665790c1b49ca13ee419abe708093d80e628d9ecce057ebee211b5dcae6e938575fde133a2ee7a011891c53cd6ad59716a2719c675d36ad09ff8fe60f7821584a21345ffd3072685717efd29f3b977c028606df2a8407c1a60449a60c0bb837dad423d1367429bf85f19eb539997f0d0db1fca77e32014fe50e17b449b0db6a5b5b7efbbe4593e24cffbee6eee071fec63163bd5968431b32a6fa996fbcf270a91e91710bb537ede6c8c84cb7145f78a636c205670dc8cf8db465431b377fa6b1df41c4a44cc89777a1144fa77db35b6ebcd8a98722b3e0d6111037c34fdaa632fe3ebef1c5bbc3c70852ef5cdc9edbf9c280407d213606af1180483e3d6a33781e9a78d8734d72a3675d7575ff567f6944447df15d75e306df470cdc12d6a3dcce7fa21ac11baa4c7f7d081cb0f10f60f02247452bb0e2bd1c676bf47a1ccf2787"""), TestUtils.hexDecode(""" -EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), +36DC7A310D995379B796EB8F9CA346EDF60DEC7F6C00AA311B3E09EF96A6795C4B077C1D371DD8D4A538AEB78B81927D08008E817A6FC6B3F9B14FE56EF9B2664E76112F214EEE848E67EF33B4A4E26A2378E9480CC7D25C369E6C25A2673B946B635B6EECB5F5F1499B484DCCFD5165D6F14CAA8E1EC9A9E4FDE417403720D7B4BB30060AB95C6F227767D671B75A1BB5AC5CC33EF0509C69652748251869B072B9042618071233B48A9BDEBA330F0C450A2FAAE79291B9E2480D1CED11FABE56210A80C39F25E5574356CFAA32E57782145920D6C0D27C3AC7C63DED6A770A5A45119FAA92209F2A066AB90FCB81A886FB87641C550368C1B412E43F4FECC2FD659B2BDA6B7309797575DA2893314DAB058DD92C7470F570EC0B1D9C9A149FE0934D40182CAD14D5B3D98C4B7454CDD2AE7E54EFCD554AA5B458888048BD5201C04E7D6004FC2A597DA781BF15AAC9748B6659EC16602F10AD44145607917C3599A1F53DC95839086A6A4FFD66F8EAC8AF8F11C4F2EBA3B58C46B93D0494C4CDA4E8B8FF7278049D2B4BD7BA16BC57678219EBCB5E211D51A168B5CDF66453412565B9BD606CE29A5A70E60F3D451D4214B0A258D6E9325EA5196C55125F0E115B14FF34FF6B172471C2B4917FC36B0DBDC82D0475AF56249AB9297790535C0F0265D2A853DB0B41B418072D0ECC17CF91FCA86F6E10762EBC520F0AADCC3C79EFC25E9692FC0A66389B15ECDD1377A9C3D744CCCC4BD160FC65A45D4144DDCA04E5408576DBA6D5C875BB4071729361B0514E8B96405E2F48D47138D2D2DCF4DC865F717428FA1262DB0D2B7B1A356E9E76301D38BA506456B4AD70ED09B0D5A1375AA6E132D7E06F8745E7A5B5E4F6455F4282A87D2B372C40A34C09699AA8C2B2E060107BCDE0F9D99B64F17DA5FA01B6DA87B1738882976B21AE12D1BA0AEB37644AAFE5AC20E7F3F631FFC2A24EEFB61DC37485DF27FD9045BD9BB5D3F00B9B2694CB94B01E7A4F0D909B8612DD28BD64E6C1C5A612CB30DF6004276FF58491B8129FCB0B539CDF891A97AB58DDF04AE40BAA5781C3AEC65FD7E84DFD0369A53CF36303270DC80E3E428854D82B08C7AD022BD99AC0851B16C7D8D462DA21126F70D661A59E4D0FE4441806DEC48E37AC4A271F15D916135408A2751CAD53564967196763B512D52240B2B0D3D924B83CF482B5316B7988D73A16B773705097F5ECE0027CCB2C2EFF598B8F61ED4D6BC015E56D4549432A6A95328FE3122EAED0149E2144E4CD2262C7FE7495E41E0AC9FAC9A11E21AC940D25E74AED8EF6FECD21747FF8166589B7038EF1DD504F51E01F1ED911FCCF44949638AA6E8526F0B9DBC5E536FE2AE7D4DA9DEE66402A45CF55D0137FAFDA9207AA7E22FE396455F2F43108961FA6B0339D89EB8ED7EF13B936E3D2DA18E5EAE45B05DCAF5D845DC62CC55553E37CB328AA2C649ABEED0D862E8083962B81B84A85EC12D3CE5B600123AA7CE4764139BA7AFE5CD02F70D06DD9AB0BBE868070A9AACB951D362E2606FD940A8F5BE632393E0A179C2A62151A094901F5625D952D39D7CAA87B77C4919A8633458AD9B6DAA16D1B1CAEAA8075741094FBC0C08D30D9956812C1D3A75926C546ABD78A2B9D44C1B6EF8D6EC2A2EA8B7C23D0EA57E1320ACFB576FB9C575DA98B714D6B01F03364E618A2C03BA84BDF0E5D2A0403B1379416D87B5E022BD958B0C9170E82F8E9A727D39C8F7549E34A14792776AF0D72A27FCF63EA985B3882A717091EF35F5835D4DA127554B6637AC313BA3BAE8170B9E70A6DDA2DBE813A49F045D8C3A65ECFB4D5F71FC75AADEDAA91A81A958273ECF0CDC4512F0D0ACCF9D9D001A30D0B6B2D50BD216D6086AC5C9DE7388A7B1319F2E9E6CE128B1F72F765804E060A8A92C93295A99C66D6D79BD7DD4F7F02317927D60B2E9FD59EC3F95A874337228339EC673BBBF53BF0FE1886A4B14F19CD7FA9B771894377F904EE8BE48D64EE5D40882C684C81DA3198604FA599DA8D4EDEE8EC3294620B6555B3BC9627D4514DBD1F7E3E9DF7B56BDB4CD395A8CCADC184B2B8DEB2AC7CBEC6C96001EDB67E6CF6F872469B110097C69EDE1121D22FB5B5AA4CA540474630651A4F9E8F7B0ABA5DF568D882626BD158F925F8DCE1D81668EF7CF770DC615ED0F5A807E25991EC97BBF2F9E997A532A1BD82A2A616250D2232F72067A17550EE516F28940D8EDA9CCC0E02EEFA496010E499E62C50B03F1D3C1571342DB8A5BDE1F432F7B6163BA3AEF35656434937A42C4E1F473331E38467DEAA483189902364463832ED8C5E04E0195D3435A6FCE75EA3BDBDDB0A0319262083141B1BBC0C278CFD40319647E90BFB51374B0AA5EBF3C564EE95B7AF618669C935756AFF3150A93EDA92F0ADC29253758A6C8A83EF55F97F1A4C0DB566668F30DE59D93D8185BDC1CFFAFAE472E0B0FC4B1E16F0B748220EB2EB85EF127838D576638E738E9F93A05D41CC1264AC6BA03B202D9E3B06946CCC68DC15261A029B0C5E91DD81EC1D79BC51F74BB5EF778F00AC091513443308410F60AC1850F2548C8101DB3B6B4D453541E36F0ED57C2C14F465196F8F1D0D3ACD49CE3252BAA0C10521311B8B8366C579A430526ED58BDE92FED3F0B359ADB31D67BFD212BEDA7236DEE4615ABF13C856CCC93DD02AA28D1CE1F12C2DD69FEA828BDB9F4CBC9242E1017D1063A7BF842B00C75243303EF9060C8EA501BC73B3EE470919443EC91D1F0D6D0F23A899AB86F2E8A0898D318BA520DD15D9B24F4F10A1B9FC52457714A151E075BBE419E4216857500B8354A8445B5FBB526A6E008229F33D8DBA14DD42F424DE3675E704DB308048B2D17904DE46B76622BA08C62F17EBA3E9F414A1B10921858832EEFBC282755B319E176ECCDC32A25CC5E76479AC112570AA86518BB1E6CA3F46E010E8132C0A1E8273403C5C4D7046A05398D461CB6843D70EEF8C94DEA5DF53CA1A4C7842AF5DBBC6451554FC7F9913E56957C51E0A602D882BC389C5E5C7899539DBE6832B0AAB5EF26B2C96CB03D1795179A62F748CA501CFA34D5ABBAE3271AC1F005112645F10863AABB062FD2C781E4573173935B5392CF9E88A1A31989E1B8E94F77CEFBEC591DF6529C6D2FAB72E678C534C4EFF40177C41D02AF0EFEB6371835CB55AE0AA99C0653876CCB56ECA127A0A1DFC0F9EEB49525C9A5786F618DBF57C41C5CAA971A9505BECEA8969D9DB28B0E707C659EDC42280035254E91C522300368F49F2C36211E455FD620DC956AFEE41A2493BDB2B0B8AB78E0B838DA6584FF753BF88CA6A523042A285F84ED90E0FD5E28F75A21B53F618145C16925486DBF6B1E7D76585D0D117EC562E22239E14A49ED714814F01DE2B250E9B3B6A1C99D1A71CEDEEB3ADADF611C4A4F97E1B26AF9780AFED5783129FD58B1232C7E2DB9050AD3D494EAC254DC46B0461A1B4B63840621D45ADE97EE5663C9BD8FB7261152545AE35536611B5C65DD6D66878DB71640EA429F801D6FFE291B06062EBAB9B416DDA7D261A46E58B154684E86176169CFDC4A60EA38300C3D44F9A4C9DCA0CE1BF37DF8F786F28B5B3CC7B0199D3322CFDFD2CF88C5B794C69F59543FB985890471DBC93A313992ABD33691CCF69B96A9396E5F55B54FF7BCA82A31199E5E81CE94B6B523EC5C3E2F2884D8BD744CF0C072E29E4B542DBB370FA5966F68CB20ABF40619E76C099BC7A9A373707707624E8999D4CF0A75D4AEAE113D7823D7D2ABF54FB4E68B8A6A57A198B128DC69584D2DBA473B6725FBB8EC9561D6614D606ADC4FD9CF449008C0D54BE4F62EC1441FF79EB59442AEFBDF1F0976844B4FA3969EEFEA10794FDBE35E89EA52F50AB26319BD1604D3FF5AC660431F1073575ABFAEEA00E1246DCD1D9399939D655C222E19E9DBA5FF42709FC11E7E365D7F7CE2274FBF1738DC5CF5631547549F2BD4DE896C8FE039720F5E0149BD81533022DAEE22B93A3AAB9AA9DA15180EA071D98E9FD176804A5B04D089E9C2D386271A8B13E7D668AA74BFFFFCDA3B4E528937C41D43A87DBB46C2B49B63BEEAAB978415536A87D845F6C2484F21D71D0F904438C46E7B0A3C6DE5ABC01C6F7CBCFF21D3E74AEE96C20C32884DE4EBA0F282C0FAD06BD9CD6B7B5031F149E4788F102D2AC2C99FD09B14A4AE3BD6859CAFE6F5A494EE8CEA29F49D871B79BB66AA6E6EC3718B97E83765E96D5603B209027BBBBCB09EE6FDE3AEB65AB1D73684820AB1FDEF88086B93B6338BEC7088E04F5F6E520E3D715C6C5E5B79E73B9E7AE1C5EDEEE4015860CDB9FA21FB434C3F28AD865042284A7FE9A5FF47E8C6158DD83EDF28BFB18DD5AFA07A48BD5AF25B9644400CC976A9B0FE9D9071E708113802A78CFDAED28378AA4FD6FBD9390D8A17D6500A0E1835652C7E0B332A382576AC4381CAD51A31E64E5E24FEDBC62EF9D0CABA0C8EBD8B94625207D0C8C1C6DF4EA2B20832EE44D1E2DEB799BC97B7245EC404F10764296E5BC4A919EC24B4F5F7D18692FA8DCDD5BBC170A81BE7590B7BF4058DC7BEA0C545BC85F0B3F0936386C37115A333285451CCAFB8397F1AE1B56D0A8F884BC968E729D622D21FA26B89BA2726C91E6886838DC9912797FF2BDF6800665C1D1DADFA4A240BB9BBE21B6DD750389AFA49C5C366ACA5E9C3B31B358FDEC42B0032D9E2C22112E43BED2023B364DAB334BBBE2C3B669EF700702B5D1837A6EC15CEC2B2036D56B8760129F593A669FF00237D26BAD9F9C2F4ED4018D998E555D2C3CA1D53EAD6A1E27906353983D4408904E5FD9D79AFEFEC26ACEA1F39218C36637977F6E2F3F6211AA06AB9D5F991C76F420B152BC95C4BC10047E107CC82E3B00B2325ABBFDB0FFB2966D5FBA0EC7E8DE1DBCC053C4186AF23A6BDF3F14A7186665AC2682FB94B0E10516D500B7F67BE4BD2523E194A1ADD8B5564FAD9105C86B6D16B08AABA604419D55F571F11F4989197144DD12867D1636D12800D54D36FA88C620008095560103366711B8E3AADD5624FBC7FF51318D17311F02A807770466AD559CFDA0AE1439442E4413944855D4D0074D529CA8DD621DA02FA98F46327A7BA600387EAE5E724D64A82E94ABB760C891EE39F27F0CAE8D1AACFE20629DEC5DD9BF4CA91E65BF413FD2A9566B7DCA9E500C2C328F533AF2A957E46D9FB11F0DFE99127656B1D4BE20C946BAFF58E5FE1A9ED282ABEBF6EB35A35AF324DF0A858CA8AF507CE43D228ED81D863F7096044A084DAA37ACB6AEE98E5A94D363963D4F852B955C2F076848092E6199E07990372E56BA1D590BB83D0C7F834C852CBC39B666B801CD32A0C36B034264F3BA6911A719001FD0F4B63D2D628FD0CAD34B4C9355534A8A38512E758B110F48E5A09B504D20D178508E09B1423A1E61164E7D138B4A9455B95EC8EA786F5FFE67806781F1E619505FD7DDE9A904E9003CA7E5EA1077C94C228D36667031502D78B3B52C3B5A09FC398D8B5497B6E3F0C5381BC99DD7B11DADA2DCFAE352DDEA2C749F8CF5AF39587083C2C19576EFFE871AB94D1C7CA2183FABDB74B27A80FC4F20CB86B46B0B7F86384540EFF1C888168F74634F2C0BF7FB54F7002EBF90B6C4B2B25DFF068DFC7D087A27749D6C36AB0A33423044AE027DCA8C42678987005FB9DE5C2774924AD2A5A8FD2E89C288975F89B5C0EF70A20EDAD1925060A12606A9B03626039635BFF332A0E6BDDC4F5DDDA209AF8DAA0FEF045FBEA9523D04458FBB0BD81F65396938436AFF5FA66E997AE58D64E7B5C1B589558B3DFF6D035E31008D2C76CA426B07F1644F609945909DBD16559B36461CE882A361D0415A9D93CB98A5370C56913A299B2DD1AA372CB75C7E590A9629CAA6C439CC5C7D94A21F36F998C6FDEC1C1721ECC500ECE1214EFFDE65E479D38C635EA223286DB326EF9B19B3CB862C96C162D3DE238C2948E7613A0FA4843E39EAC51EF293AD7EEAFF0F522934C982890F83E922B2BD52815136D0A758B33641C54E7D4E0F3B19AA85859B750E7A7FB80892C3DAC5048767132E2DAC5804709B8560A4B3828B1CD25DAF263A2466AF7FE328ABC84EBBA26902FFD92B0D765AACC0C0DCBEF962E1B35B1195676E8A67ED593B23B2B0305B611F9E16633E77E3F31794C58C5309BA07DB5CF9AA1CC108186318A3F16A7141854C2FC8B469BC0F54BCB22976A3CA05FC2C8E23F1B6A891E7527F204ECCA0A5400B68565906E795FE4DAF52ADA95A9883676F9110B14CEEA389CE9BFFBB5D040E60D3D03C4E6D6CBE9ED53EA44B1AB6ED7EDBACD0AE0613DBA5A5C673A534D48B539DC85F48175F13404016C5289348504141338FE958AC28331853AE80ADFEB49A6637936BF82FB26B95295B2E46F4F9534720A4E86FF18B31335877C9CBA96A9B450C1C8C9C9862E51CFEDBE3DE5C8B901D792A179AF9A782C330035A14CE6A710D398BD28416CD72373FE216744F6237B38B97351A77D5D0DEA1A26A0A9A24FE15503240933E1CB5AF458E6FCA8624669A0DF439CD7FC13F7A1F10A0CC7DB8C6AFAD9C99B5FC45A7C565B5DCB74FF0EF426FE7C260D3ACB1E9E83DD8E6E11A642145BFBB7566D582D0540D7931AA28B7F8F682E6E2D90B6E6812FF8B7F15FCD3DEE686DF06E8E6C456C99C6B4215C4E874BCEEE3B4F94BA825C6A45C2A2B4C6DC04F8FF5939C74E7DA37E02D8230340C6E2AB7CB82BD226DDC1A7C7BD0C0FB36F71F9C772233132B8871A0D76728C2A141741C2662438C5CC7B129A6C8FC587A0E475545D176818B51190F0F19E91E05C04477283A0A7D4D646EEDA3BE64459780BAC1862D83E6B99C5731DF91F0CAB454E70A0D94D934D0CD83C8B8301DE282F9A1FFE49E73EDCB520C016FDB4AD02C261DC1A1E73E38809E60F91A4E38C69EC70D2A621DF0D21588F24CCD59D331C69E16F0F6BCAA8F24031DD5718875BD9EDA5B420C116E4316137D4B77623C9D73D182900BD7A0F90A193CD16107E692D469AF09F74702492E22C796B6B4A960D47FDC571B4A264EE3528A0F5A9D66DDAA33FF20C3101D50299EDA3225834C9429976EC8E590C6D48A721A14972BE70955EC1A0348D2F84347C1E8E21EB0C1FE67223B42A6BCCAC43648F3BB5464121180F8E3E682B4B664D91584AF55FD1C7D2E6F79A93C680238D29CB7FF36D259CB703DE03B2EEF6DE0CB77AAA8F49C61EE482A8DAD30824E603411D5F09482DC84BE794BB6EB65A7BC1DA92C8BC8364AA88D4B8212561745BCF3CBA0D6AC8B8AF80373DE3F44EE39CA3CE4C5763F422CD4E8827B1E7BDFF79DB990A52530E4A1E21F6CCDF50A322A086AFDF24EB5FE4D99F1D1BB4D6DA965D168E9726FF7A4C82F327A748DDB1DA5A3D0E9C8E0B060872B009CC9F913D35D94FAA912B0D6FBF233DEA3AE3C2A4E35BBCACE21CA3E5F7A7B9A486AE9D7A7D2E0B79FDB11D87072F1B307402BDB22746B86A1A0E6B41433D5BAEB2048ECA53A1ECF895E9EB9BC5D6AB5D5DF72353566BB90578F12C6A16A163E95CD35DA27C79379756141DD05C315B466871E2B726B8821FB6FB439B49430CB3CA47CD211D03DF40AE4A0BE87B6000BC9C75AD23552E2129F47AB64BC9E5E1620C99405CEDF7BC059547D547E2868A6D470D813AA5095D0AA4BB18D91964988391EE6F05DD47CA1DA0423CA238C5E50D43CFB0527973506B9F1DA4A8055C47D1FA1E0DC783CE3CF75FFAADF574EC2849631E2551368291AFB5F2C40A4F1A184E37A19E511F482B7920F6D51B13065E6327F3C21DAA7F73986F2D1FBF375DFE2505C0FBD35F403D253BDFD0BA1B00CCC5A20B683D4F1E1F2374FD914C7D674901A0F01BDFDC007E8021013BB9A2F885F0699D16805F9F2511A0C7D3CDC06E36679983A2A0F12662C88BB7DC643FBFFB58CB51AAB3CED28553910D063ED8FA37FD756B79AE4151521450E552E4F2B62EB6F6BCC8086BBBD30331F3F2534AB3ADEEACCF2A6E66F205935A167FA1D5C747936050E276E8E4CCAFD9E0A056E4AC2AC08738BC3A598F07E933B0ED285BACE3D24AE6FF7574351758F983FD7EEB3944473EDB4EC9A9828A5FC656BBF04DC623C75F8B8038F3699BD5F255CCD3EEDE4FEFA12AFE8F64436DDB1FF2DF100B09BEC657DC5D2B18E5722D5AB30D075D9A52A576B6F9FC8C8BA3ACA6A92E6596F688FF5D2A7E3183B696AB277B0B17F004843E58760683F90BE0C61DD0D1BF9099A865CAFD1BD1D8AB1B7D4AF2F86D51C18D7868BEFF3F6C53EC68FC46EC9F23D1AE1FE85CD97D8CECFD57A562E7E574ED1D0A7005813EB980C2A46A98CEC602C0E022E87D4A6EDBFD7DE9FDA8C02EF85701BB1CEF6013F4869D32CBA56B0AD6EB007591D03C76A839F9D01985C546C39E49D59395B10346820324F3E298C5CD977FC2FF83BD422CA550DDF2A69607BB8125647B389246ADF0095F22692BF907EC86BF8D70D7E8F2C50E35DC6EF34FD1258E1FEBA0B254470D43C77CB0073AEB2D4CE5F6772D49A101052D8CE943E1C7760F2994071644D27D26BACA88EA07F29B2F2050BAC5E05F2226F1F584D17DB80E4056B7F9C60A5D9DA0CC577C6BC802FAB26E570BF017DCC7236A1173E273397E373640ED02B4F9863C40D2A2A7828C3875D8081AEBEF349143BAAECF9089EE736EFF0EF80078D2CA7942FB24A92071D229A1FDD0F6A87D362E5165D57F62D927757BC31964B5DA63B90EB3591552F2B9902E2269A163FF221863ADEADC9BC92CAC0087ABDA02004C0B9F34E5CA8599DC3C4261489F7527FD27AD2B6501E602FDE47DEEBF3F3EFC0166B1EED95116CF43C8AFC0EF89BDAA9ACFB6DAC613770DEA78960C99C9628C0D21FAF63A0FF7A3F2733EDC0FC07B83F107A811BB3C1DFC6CFBFEC105193272A4BF915B1DAEB232E16216E40FD3F9D9399B15CC4C073BAE8D08A4EC42D91609574EB009A9B52F06D3F428F6EA9B0511D8319A1B1299C154C94B103CB586370A58F18F04F5D21AD3B638660D6C04E99D356A7289E37EFAD643A5EBB488D54F4A0194FBC4283A8C4ABB8D9A1D70150AA50F991204C038AF54B5B74F722CD6515045D62276A9E936476F42B282C3B08D9328089AEA259510240B95BD5E81FB9D7E006DCE0DA832BD9A833799E05CAAFA6305D16DBA4461BE13D3CAA95773B98F09230F2DBE13936495C2DF5BE3A8F3EEB4FD211810F4B07D3E2BE1A11CC87079DF1B32D44B6FE7942DF2627AC19FD9F584E771D7ED98AA4C074A9DA5B7C156F83D90EBBDAE78D636D51EB0CB30C7C7CBC1A96273C0AE0ACAD8E15D1196BCB2EEBDA332896BABAEF76B4275F863732D646C24627AB014AB602A47594D6031795B17144E6E2C23F0341422886C1E2512222ECD530017DA02FC015EBD5BDFB319F3AE942D75A55C21BF347A44B300ACCED7A339007A2527EF4499E3BA5DE334BE58D59918DD0CB55B2F478837F71E9CEFCBBC90808E0BEF8CC7712A3B008B69476C61535FF0787B7833B70C69B1EF506EC4F445B72AA12FAC2589815874E9123BA13A17477D61E41163CB21ADB8151658C99F1422C71A8183B8D0B1D489EF436564C47ED8482A0DE9170CD1BC34D88CE76E1B47B84E770020125F718B4AFB1E4587668634FC7464114762A9D74A93E33A5C0CDFA824CACBEB097B5CAC3B554BC0D41C402812D8E43DB37C730A6219AB6F0BACD096BBF261C78E991DE0A2278DCA7D1BE0E5F2FED72CA38BAA86924A84275BFED3B91FC8DCC5024316EA0587C96E030544F631076DEF65F05F98C7641A958313686B8580CFC20221ED50DE4D2CF32461FAACD0174AC46A6949EF8ADEE6FFA3F537228AEDCFFDB2250D7BDBC848AFDFEA67AE53CE9ACA45F349557E81F70F9DB92926FD0CED8C104E6B7AD180C7B3BEB86171EE84A8DD2C243F6869E04C2DAFDF0C938C0768415C56330C9BB6EE756BB335BAAF96EEAA5CB52E554E39E2435B0731B0062376F4730108DD2F05824A798DA24C239724D19F12C6F2FBDB52652352021E0167F31E0F5941C4687DCD13A81A20A0AF05A55D2533280941865DB4D5715AEC293A64AA2E5151C8F44A14B72C0879499027E67E4E2B487612216F6122361E8D34E92C2163B0C88583E3887DA93A3AA0E77FFAE3FE8FD5455BC86AE6D6D5AC7CB7BDF156A960C98B0BE50E1370A43E7D183636DEB2C64B264FC5922D4BD46A8206F911E7A742E72E4EBDBA39B6151AEDF5A6CB4157B375D9A59899808F1838C61EB4388B923423D3879E8228AFE0CEE9561135849A89363F84B41BCB166EBCD0E65A2A74FE710F2B3B55CA9DE2FA9DC163BFFF4BE91F10493936FCA15F5F39422C75233DB22299456D1EA3BAC26F6671557B2A5FB0E9460997DCA797C67C49DF109CFD597BE34C8E0FA0353F28B815D0CEB31DA93E49EF29CEAF20FEB0A8F5924DCC62E830353463245899900304A8C8DB5830BC0E97AB83853D8EB05660D6A9303833D170E138FF6F1C30D9DD64574D5F875F974225DA81ADE3D97924A38F552276F46A5208403AEF82D1E92959675EA6B353E5C6091034A295D9C12C288241055A2334C30DF0A37D2590626A7D1787A4F591A6E494BF55ABC76842BBBD508FE54C5630D11C54386A487A756ECBFC0AE8957E7CA8678D5B9B044117365AEBE79AFF2E6678001D23624"""), TestUtils.hexDecode(""" -372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") +e8b08c99776fe554292851f9d80f785b8109d6edcf9d30b4b3c8c11fe8b2e024e333272f4d72e697aa20953d03f013c0c3800e840aba56daf36846b0e958f7e1a465deee3fae6e45931424ac278b6d1916dc71760b7518643185cdc7b06b1dc0a54c83597e6a2aee0894c2066b5fb1e2439b2782ceec63aee1742d10f4c36793b845d5b86db9d22a200e12611bbd102cabaa00ed5cd47e6cdbfc06d7bee55e65e4ebcae019ab28f0f05ff2efcc3c44a5c89a5e80fc8758d774ddb3554975346aad922319273ea930b3718562c3a96602645c58e375e8b78f38cf636b42e674ab4c5e1a8da59c64100984605035e1f735d6ebd2948b556b056a07ab86f8d07f8cbc72cb7251543ceb39a9deea50b8189face6b5ff23bf62ea3686fc0f97598f36ca445942cf3c2acc5258f9a870eba919b99c75bf598031edb693552c086377ab84aed818e795b70a62c14f84d5d01fe9257cc9df2f4cb2f40173be7d11592e9289eec23ad30a8e5dfba2f6a779464e79cb5b07e6e5a19dbb9a829eca1ff64c0a672844ed2e636903bac6edfce1315cab8751e9f12635160df14cbf5ddd341824e8033507de1f6cb7dd87c5496342a27a8746e94da455ddbca610c7990ed01ae5dedc90cee503d525ec5033258465e282cacb2c0e0ea7457e62d06c194a958322e64a5433e4936292fa700dad6fb7ea4d5689d4e3efff132d61493859aa5436c9087fa9ac5b67419a836460fc9bbb4d53d0c9b6fefab2d513b76f0600d097b0c3eb7d7a82e01ba3abed5354fcbce02cc7e85fbeedefde5652187fceaef8e6c05b4f37c33a752fea5af6160a7da084e41dc7134534fda67c4e1c6b8dabf7bf05d25a0ab7e05c41c4e0070e8add04f20d8c72bf941ca284eae27cd9568e9938adf4f55ab2c40d03bb49c58c6fd8d74245cc3b4922891b865dad534e256ebbcecdf5227b39ac335005bdefe1be10c2b7c969f4dea6f581c278f8479cd7a40a6d369bc5e1fe5e074230d01795dc664e488e4e360b169976b99a0b9d257badf3f397ac914b15b8ce4b3c38e6c758a169ca015fb6fd339c4255c51013e7430c991a006591fd69a069cc2f966c24ad78b8c0a4f4601ea08ccb683e8d427d1a0db844308e86afb0e3f6965af9ccca755b5e2a8358fd2417b46bce7a69b2edd6e9b3fb617dc5bbbf2803a557e33c907b4ee7fa7a9cfd9f148730d48e471097526e4330515f3dfd5e4f0e6c6dd2c2db73c2c0913c82559032c15b3e580e3b11f5c319db8b04ee4a3dcc87a4251e8ca8f77a8e61d67a5586f2494c3be2d70d95076e6470cd3c3ed1b780ad9217153fda872911bb01edf13c13143e4082cfc9fba96f14e7844f3ab040567faef1f03caf66eb10d92eada39afc6d70d16325008f628489ebd9e80913227e270a8c272709658aa843a486039a21951467dc1e5df0feabc68c28ae9e9cdf95f7db12cff0167657328985f19595b5aa33f44701a8f40242a0f33ff9829078abc53be36c002405557c61b9c5585f7d61d0fae020b2ad18358a278aee3250b12bc7f0887d8cf42137f26ca12a866c35876bdc737a22b8a722e71ef500ce958723728aea23748924eab3552a7cd4142dc7e138c84df1251a2ed8f94c939bc7aa0ea4c0ebb4cbe817aeb65ee5f0f9cd407899459e719f0558f8f40d73b1226a004b910e26648852bcb3b08aa5340f6ac6426aac89acc4945b180dc4f401d97a6fc68e3fa4b8ed65ac74727e3ee5da732b02caec13b88cb167b15e4c7da21dbd937549685e8068c3eccad584698291b9c3410aa8314762fc838f9336b6b09c191409d1aa2dd5e2a075b070413c805f116d42f90af6c7ebf8c322bbaa14a5692ac0749ec7df91e5eddc7ded2dd873907e07b01f14fea1e0efe6d7a1a5ecb95f822be8f3a2f65224c3d801284de6f29a25725c3784d7bccd1253706e107fb9dedbec4620c87c615f4458c4c7078a1e69a0f5178b318fcec51e73995df8dda6ece7b7267d28daa1fbe7f36680fc001974577e4a128282b67819227e5d100baa5101c5a1422f096083b3b522a6b71f8943b536d7798e86e18129d1484cee60ac63cd849f5c9e8a58fa42c0298e3d595c3c4f145aef17f79fba8d7424e5ad7d6831321e51ac88eb1c54c6c1e2f3263c899550b65cfc52da78b7ebfabd474851b3a2b5457f4e646c15ff50efee6a8ad5c99e91853656255fd429e8982c56d65d005cf3ee1a725e224c768e8c92003a72f3060cb088f7a8cffac0d526c028f3dbbe84600d5a9568f03b2304ef37d5ed28941169f8e204a1240e6d910dcdb901932982a6d45a7a10b1630587d31551b6e4424fd929b5a7fee3c4a20929102f5791062acb3c53a6edc93ab5ccc703b8cdaa39857ab06b7f818a59d8324dd1ab342aa1c3b0a32dffa0512b92c1ab9a4f66e57e9bd27734ce2b2788058637cbf94b03b7a1b640f03735f36bb36052bb461c22fff6c0580b6eb4bc572fabc9a141c1964d664168116d9836f7c7581cc9537bba32d1e3e5519e29858f889e282c805084fe3a64db0234bb3e1dbf57956ce4165795648f4865c1232e24a6769e24c0b271aef1146425a9032884393d275fb68e3b3c91599ee82a4cc34338715a8590f436e4185246df9bc4c066ed975f502b967a5761c1b8f5aeee302f96aae3dfdb6f4519aba3e04cfe5c9b2d342048a4c2721484e9b311c9a18ee5f726a512c93a8d37cdaf6ee96928fba315a4680dccdfced6a13f46e06aa162a7ae445bae5b1134f1656a2d700dcb2b5138c780b428d346feb98be8ed911de7aa5ebd72e2a6a8592a81ad4fd6a6da64edd2f5490cead76fc652998181018457f1cc0ec4f4588cb8f418f1b6d801635847914c3f317369027b4c4608e65457f949e08110b23dbb6941632afc1d1292c55c169965f0153ec72d93498f5a68140ce2c8282a59b1011ac705fd5f0a8ed1ecdadd58d4a1fbd4b09e94802a0c67f2f5faf905bc4a35471f886a8f2366c25b710eb43aee8fea692d12b4f94513337b0ea9fce3c255188ab7b432ae37383470eb94abc2554c6f165bb356415a1f8d8790e1bf76f4411c8f32fc550e38a0ea7b8d37537855724c08eff4730484e55accb2f975637b74f29937c19fdedb5aab7d5a3bc9ee1df2c83ae8d0e59782fe18b3a17c82cf649a4299b74f022012e189f19d88b06387314b65add0720aefd0018a09bb3d13cd63f98fb73b8a57564137e89811d59f1c74a047e264ce816b01e942038574a9d1f4fa5408ad1661c31bef7e97742aec79b74df757065e8e1b059b5134e53cc8560bd87e9a68003b124b15afb6534cc6181b6b71eda535ae7a3c107abfd2d8e5886cf8a7d67a4b723ba794c0c5a9d1a63f67a6c42de3e3632b8a9e7bc7eb9a5e404930265a7d04c1e16ac17a7b5e1535e1bc80ddd1800a7ba1b0d73ba053688137e1db64eebfa9b5dd8573a51db93aeb0c6c644c97ba9dc87efb2a5d79b3e3ff396a45ac1f0aab064dd05c1e6ae48b2686d662b8bff1e87db3745c7b3126a091e688091d84d3caa1adb471df496e79e42b276088a600a6f8d2aaf3d31b22f7e7efd2b894fdef314f2258d32371fa022e272760c704997b2a605b0e1a8d0602ad3a134357b0f2785d79c557cb04121fb054354608655afa7a763c8276170c13f9e76dfa711e26ceaa999fc14c686e2ebd61d18e74ed08fa1b872e09246856d9e0477e5e21a72c7869b57785248aef0d516f670978ba4dbac563b77f365cd46cecbce0b7fc7c9fe7373d6ad47d094b3669849dc21084124999ed55f13106d4be1e52433d86ffafbad0e4f221c305aca71063037b7a26ca73ca37129aec69e665cd2e70a94dc5aa8d22e1a425853645a3eb05f8998c6d766806087f14f08fc95ae3b2b9190721bf536ac20cf49222f5a0dd03307995adadefa43a205fe9dc839b5f27447611a93012d3abccf3f5d7a766756111dbdadf6c5920782545c853ae1a550a08b14a87bf296ef0aba7669fabc13a8d0d85d67e36abb24a77bf87bdebbcec1e28c1f82fcb95e82ee936f0c1a60a38ca3ab846eb39cf27acd9a219abc2c6244878ee25efc38a6552773b7444e466c24a15458df3cac856201a12c3bba6483d886482d58112effb0cd72c7aba4df0c11474a41e1fac0419495166d5b88b7e5e169c96c9ea6ac96dc5c2f749c858ad524e7f3d32177aacbc836abbea91ff9dac9d313a8004a186ab52083662a03d42518199bb2b81f9b03501ed8d1e8a8069e6a4fcad2657d4e69c0cd8e4ee56389d026717c72c99f13b2d21780c122bdff75c0469f32a1c519afc5900855539b1c75a3019342b7d5fd8ad7fb02af96fc94ec29583a48b964c65586a6f17af9f268a6cb9bbff237ddf393dc40d03b69ce5925a5fa8af87a6d0f497ae82d6468726714f7b53bfcbb647253c9db17a7bd5e760531ed90d7cf044ec0bdcf9724b640a201f5a08e223ff20e818e16e88fd92300b07e89ca333bbc05e8fd01d847bf9d7ce85da9478833f5566662888c8238b70cc3481ce0b8fb5c5e144d05ca8b8952c4374b261e48352bda2bd2e8de39b6318a0cbcfe3c36e6dd924e52d82928e964930ea6526aae08ca596fb732dfa02f2f6da72a05a227648e1fbf49554117aed210263cc6f5ebdfe2ba852d1c4c4af8f71a8a6501927109026e544432504a5bd066d7c03d443a191629a2c67b00f634023bb07c676294159db4df69555ffbd6c4b5a6d4726a54f9a0ab243cac6ff603e2ffa3c4acc6046a849b099654d0d894ae6536deecfd326aee5164eb1a59838da8cb33724697c17d6735687c860a13c8b8fbe497b99c98b58c8a0f0c67e1239b5a0880c1d4b0e2cbfe268141d035c02047d0a5c64c4fc79f245e50c43f3f64130be4b8def3085330461a12b1cd047afce58b05d2d75ac4980376a2739821149c95e17dee53f6da1afab57c02c7cfa3652784caf90f6f66a93966c636a29df19b2ed5699ffa1aa0cf5de784f5b57c15ccd22f5963924fc55f997b8a508f10d8520c5498f3408daa04028ec66b3885c5495e10666f8125f4761cc09071717244928ebcb985cc8ec8ac777fd411b8a2aa51320c60f6c71bdcbae9f6e37eea62c1f595ed27bb83b25842d2e26988d48217862afade93f152155166ca55c13c143d6c176208157fc8a836ca68ad5094de00d82665b2675baa86a6012fc36593e1c9aeec4da750c5c747643072dea8fd786738f5e788e36767bbd29a87ad1731adc579396eae378f8c4fdfaccdba49304649d108b19dac8caed2d08f116cd33af7bd22091330ff4e99936dec531ca9d735430cb4a0cbc4652a9c1c43168b1ee012a46b1cb92d3035714eb4f7f4d6b63b60589b946e5a47e961f3c575d13e1486d9a388dff8c8e9aa4663e5ed91cdd8d3d59f02deb394ba37ee4a05df162208286c19bf0204f4d609b229087351981b6e62fc580ab06ff34474db029a16466d9630eb263de0b76e8b53239a044f15f90c4836aee8b2203d6db413b583d62c8bbe7d657b2c1185a5720457a79f621bad76674112e28c34ac65abbf65e73f54f918d0b912c429b29c5c32a370ec1810cbb07375a85df5167b32a321844cc54c34ab54b87fa6378924e54a874ab871c928d49e704dcaa40b88d7a7c5774163522a6620abf5d73643338be36e5b2e30659d0e39695fa97a6ff8cb8064e370eee36c5a3b57de7d218fa325646cfa4fa2e9a0622bcf139eca8acc28de6f0a5d2e37dd2b0d6f6b39989eda0de372b20e2cbbde73857ae39b7f0cbb2f4337e04a52f1549bc4daf89e484b06177bc9cd6b199906b62789431e4a29251cbb4539c62ea6fdca9c84721c02b8af585f64e8420a7ec91e6387a897196685ebb760d1b4276cfa36b51f4d3e840e2c5e074c69ec7f6557afad4ef6774dde534f88cd7683a6855bbbf8d43d520cbe0312c9e189f710c75ad64926a97ca0e3b2b575e3aecf7b9145c160c415f8c90160aa5208744addd8b52580645fed9c66a2f6d8b0afe577ff63e3fda7e9a25519f0d2fbc3bffa9f45c40f70452a78b903d923e4f0fa9475659910f75455d144295e4091f8a760e1e68460227d37fa6220b4f0322d61b8fd7a40275c4d9446255862682f775176c67d294ff45205726eb733e5d21302f4df66fec98102611e3bf8084035b42448e86ff9225935ebf7db9a847e8a0f72ed177fa3812f4f5c0dfb7e452acf0e1a23d781607de22bdf31177d5eb5e2840bad442feb2f8baeff6f17bd63ed9495b0351949ccbb6337d907831e22ed31cedaff7cdd13bc3de40421ac6afb536ff89bf041a3026ce04316b6a082c06e0437440313ffd36ff78d6e31a4f5652c52e53f06fbeac2a7f13c64c061dca9ce9dc2e7598ed90a12307e5125397629887f0a3d3bf8d24b675db85ecfbcdf8b3fceb50e96b0a863d30a7791db30ce4cafe8d85999ea1282ba61f667497a8c52a2fa3bfceea070b2e8a9cd8e51a244b73a0a60a1e4076829c1a4668717495adbecde4f4fc0323325d71aae30000000000000000000000000000000000000000000003090f161c222e35""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +f5e15972ad2246b58dc056182273172d39b05662b5048af41a6516a04e042cf2f0c5ddafb57cdadd0def1a82bfc1a4f6fc1c5f2e934016eff45dcaf88535735c50f3bf6e8cf4193e53e118a828cee10640664ac6fe927f1d3317e26333d1320fa0cedacb8cdac09f35aa4ffe425e9d76c4dbcf07f5853c521f80689a8f8dc36b4ee2c2de91cbc3ae01cca416522008a0372515438a42398b3cb6e8162e003dee631a0d6ce6ca42662cc5161aab21dc999bf840665fe093dd7f3eadf35eddbd3d5712b49735724d367ede964eda26337c412310bbb326b1a83454d90dc2c64a477db6c90ef3a451a38ab814cbab44f19e8c2fc24283ec18f60b4b3c683954bc78afb64ab8e0f6817ae0095b14c83604b934cdb75c263e99bdb5cece8382539dce358adddaefdb2a568071347a68f75893fd210057de0bea4c2fa882a86f120934c72a94dfc8629ce6aeb024c5c561e1f5e8230d830b0a593b42ba6d29c52997256bb9186446786566d9224120d95e8c1793aaee0fac3eec75aff47e90547cb7b42cad315ab5c0813ea269cfbbb4eff999002de0541ab117e6d374b9f956f44ac01371fbbb2cbfcc47e6696a16d1d731f878ee362f3355c6b625a9f77a9455b51cf54468d1a71580595dd4c7968149a0c39580016b1d01ad59504db610f7891b5e0d2ffe9bce4a2f32d64894396bc6a91aef4722367ca39e4c723f538d4e8d444d0e53fa8f434040751069e62f42a6d8ec29950b8fba9878533013983c8809af7e8252ed9186919c561c12a39a75be5dd4d1a8a6bffb00d7b305f13be81c188718a128b98c5795b2083fd221e950898c6c929b5b06b1e9649025c68a6fe0ac6b0de9a8acf6d53dc361e3727527ce4100bcd9a99293e85c0cf2c6c4e13b349c1f2b0512278661b3e1d08420d15cdbd0265b6eea3540641b18e5f301b63cb46cd7c404c8a0e5489f072da3cc013f7895f2d368dc37cfe65d50c613b5dd6b2d1d27bfd074cdc20062c00d8a32795e61056a4287bfc455dc0c9a9832f188a1f390a5ff3c7cdd8416ac997480982935480bad96c215079f32cb9dbacf094e0f36fcb701d834ab851d98f478acc3fe5cc352d8c31be7571dea6a4f2dc003264a5673fa9a8254fc0bf489c39baefea294e808fd6ccc6bcfe724042b9bc3e2d57b82ade7f3a85519829a1e39313ed34ffb00853bc3cefb0656529d7cd3557a7a3fea8a07239a9d2eaa4cae666b4e77bdb04e0cfaa75516658d53f1c99d6122ff64fba6f01ed7ad50619a62d9af7325e549ef4d8bdd09284cf10432f58826d29c1e3c06991a04affdc5d1af3aaa7c8bcb5929c20fed0338803db2db0a3ef6cbf4745c511b0824da52874b1f3e3efe9812017b9eb3dda24f12e8713bc5f23c4abc34fea3ff86489c16e12d5d1729549f8140649963dda606affe6884a7759cdbc9c7d1f7c0ea84d0c8b42bc133b43d3cf24a404eff4853c458d795c1a3097b6350223aab7b86aa4e9700aa0794c0993dbab8ffd4ed89277a51112b20feee0fe66207db1e9b98059a80c6b0739f55859eaf867f0a64c08596cf08942266b61b391ec772c2c809319d177b081362e1ee216cabb281e79e896d093d13761fc0b5589db0d72c1995e05fd4b2095b57c24917b8974421ffcead3900834ca801c841dc4aaa46ad0e2b8b64b84d66c8668aa3d78ef19c6e13eff3d3d45be3b35fdbf88845b868df1bcb25f7ba7b7e52542b79e829682ce01d55b254fd66119cb8583ab33177b86b6fd92ceade0a8471016a3ec439df031c9b15439e0295a3050962bc2e9acfff0da13b9ddfdf864b1091df92132e9120573474fcc15594d9248ffaa873d0597e77d63fae88a69c0fb226dbb81b304fb3b9f3869503c18aac521938985af600b55dd67387704faadae2376514a12cba29dd0486c954fd48fb3e36d54d72dc81991275c17db80c900ee6197321ba86faae1404c7d091cab83a0e4b54d39b9f2e3bc7431da20263ecffeb3b732c24e81a814a0f4798739d856d89c976e2ba1910d4fd5fc4090322f7ab5892ba2b45636e0eb9ad7d39a1fe65f6917ce299c862682fcedf6a357f82df9daebac485e5c44213980f1042e0c5f01221ffc73495dffb389a3a49fa323338d123dca12a11109d3c2f983f13b79e35b525ee2496e9e0daa9237ec2556af9fefd3d79fba73bd291b3de7f95326d60d029d418639f0a6724fc6c38f7862a7f1bd84ec9f90f090b5dc56d2186987f4b2ecb491f7f271151c7c270962ca1337ccb7fca3e32985e370b11985dc143d5eee404af8309e102798f8f39c829c693e1e9ceac552d4a782ac70758a851caec473ff3900c52f6f5c372df2a132cd4f216c5ed6cf4c9b827ecbe313b0254dc163389329223769de91631793d8325704768bc824994b45c3084c9498669d5b89a2d39a5fa83d27d41490a2c7232c8d26efde3887f82ce24c7436626ddaa2b4a049e84037a6708db1948ef1b95913366b695e4c097fc73e6d1d24b670c81b57806d0fd4520f0ff772cd9f7833a6165b6a9e4a0b6b8428c9a21f34f195c4057e313da89a55e21aaea8c5fb9165385d0e9d475e9088f7fa701db2bf4fa32cab7851cd538a6851ceeb3a21a44bd89df644c919dc95cde8c946d2b33ff19138b33d5a81421f47b9c8ecc2e2d9cad606216e9e35f4ac025f3c49aab0db157449ac7c471ca4317755b26b3561d279aa193ab67d91da3e33a7ab072888f5df300c0ccaabb9d2cc34522b0e865b55f850bcdb835a10d41befa6fda0f84a86877e6c83de62ebfb5bc7c0f291282a70bf3f6ec5b6109c3d9fb30b5f596c8177f996d3b4a91eb113de00361ee6398ced54b65ad054cbe1bef0a9586f2d6fce45358ac9da2f62a1285e71832c762265128c53836bb3d488bf13a4452053a6b2af4e98a32996a5218a761d3a847b0a2abe9f222970f0cdba9f40e5e04ee155ec9cb3c3d5172408d7b0d99b93d15266be3c174fd25729027fb02b23ce3304b5553680fc6bccbddbf8cf18d0290c865d55d057442e37f02726c89affc7016124ee3e7cafffde04f8f6588f63266bb5cc91169e954d98502a8fdd9cd68e786df2e4d512dc4a05a58945f2a4e66651d4c53f921e234c7f24fda5402570ff610f56c8fe45c5947f217f7935e4f7014bb14815b9c7d49c5c64b1178fdaf39db843f94e711658a13178a9bc5d46f0adbcff5232ab09b84ea33940b94fd8fe885c5c7fea6d0505d675b8d602f4c91893c09170b6596bde36f3f118a8c375563f94ac6d7a19d581f31332588f365608cb09bd01d7f4e5e01655578b28a366379f760e6de3ba8d031cdaba280349f9e4f8091589476323039c7e08f3c2cedbbfb69d64910a7b50ed2654e56a8e119838656a8049ff33dd81e7ed46766e1dfaa7a0480565f0e2ce6575ee811f4f854c8341ab1a72742970a3cbabef8d4e8eadc579eb9ebdffa35ac2860c8168540c0ff06427d3b4f065134b972d97f6ce49fed68b0e99e61d17c0f89952a40d375dbf2f971dbc67d7e64a6ff0ce7ecf4d921d68c67dfd55faf634ed322449a9ee445327be4df5762f17104de608abec72396f450bf60465b04644035ada94d19cdca98a4dbe51c75485b665a8b0fa6174d7ac9b385bbb964255d74f7b61ced4db2a1d7bb37562a2acf0e25070449"""), TestUtils.hexDecode(""" -EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), +CA0104B9DF99E87474389167359968A307F63AA32F0C804A96B18FFBE00C748B1D6894CBE2B7BA06EF17B6947ECE31DDC9F614348F01995FCCE77099A0D88B2BCD1035667631991C2BCAA4C86B4D31074A2FD46C38429B52CF0BFD7CD3E5D194DF22E2B0D57C0C9D624C772B54686AC963447E716C6B4DAFC00AE383CFFC69A2F6F931D616954BC9A140D785F15C5DB28ECC793D88C78D11F8F8452046ADDD3AD26988B21BF895DC810739FA7C45A8062B2931AD363B0C7EAB4CCFAC71CDD0DA3B54CA9A6388DCBF79AF799446395DC7A5B7ED1788188E9D03EB3BF7B80F8CFB9B7F33DA0D4DBE1840B9C6C5D80F6AE64487BBFEC86C596E2ED8E721A11D783F7552A4B01FA24F60B5B683E287BD75EA0DDC15314E014D402F527C5DAD74CFC49B4D824EFA77C359B90AFF15AC89C1AA35959570E2148DF7A09E27E2FC096AB5CB306B4868AB80A24DF745DCF9EDDE57357866182A9AF50796EAF97A1A1051FFE6F9038BE1F6239CADBF0BD81B23E2991941F34D0851AFCEBC4D3F8B472D6259CF61FFDB87F79928C66E69D969B254D57541A87C692160E5D58A837A1FE90A1799758A70F958DBC1BE5D6E6836845940C75E745245FBCE59D1F83462B9578534D7A05DC3F21C34EA93ED78387B32DE09ED3CD2A51EE2B8F7387C8C2D426EAF3795E99B158D467D9A039234FDF207D65D2577D1688E1B1E72B5EB096FB6377DC8EB6B3F51900380BEA561C03D546EE242EB4264C0369AA2D53B2B190E0422FBC4CF896CD549C2A08A37070331F15A9ECFFA0E91B1FC4D5157418914308EB8C6A992B197F33DDD517DF4610E88F2E35E505BA7C7CACB8E76677CA9B39A4094EB4590F6154FAAFA76C1D95D4072B5CE01F42355C47AFE569FA80142EDB49E2ADB34D3C356F4D882A52021C5216B3678AA6A5D52C51CC8BF09E7EAEDD2501A9886FAC977EA5F385F46E8718D39073D8995D392074C2525A4ABBE228F531E6B16AD5BCD5EF5CC4C3C71AA77EAC1747E2B763D0B3D66C7F35458BE43369BAA0ABED23202B733B3C7A111F9CF407A7D62EFF5BE3A5DDC3E49AF130012BC6D5D3641EBF268236473EAB09BE87BAF7707546B7AB194D2ECF5B03A56662B1D6462898DA94747CEE9DDA08A9026538D799F163E1E771EF7EADF8833C0510104FE7AD7EE75F44F8D4572E299A87FB17429718C576B29983B50FF81F8D48D41CC764809429A7CFE05F68168B6B36FF66CD75DC0021D774D07BC716A74F9450EAD2995089FEB89D1EA73A9CEB83155ADBA737B3DE33B6B617EE7F5CB6C6672AFC439990B612A6AE71540FC6D7FF535FC88DED0E6A80A484735F63209D39F12E6E129C4ED2EDD8C8B5A24472B83A058B0F1C86B7F4C53D88927C7E9EDB5C40C5D6C7F0ED8A626C5F35E1D3981936F0F1FE4E8CEE0FC7F66F0016B14F3D1EAA993A5DB9B92C03D99C0A867FEB343D9F43BBBBBD85F58B2380811CF153FE66E5B5DD07D5A87ABCADBBD472692358777BF17AAFB622D487A100062465D9BFBE0E63B9D862A02F09E371EE820D969B29B4E6F6A1120CDA9F9E3FB804B26E2E9C3DE219044D1D6E62A28CBC90C262B76914B8929465FD901777F6F5C112D196A002A0F4C4FFAFD2578B5CAEA21452968400DAD6490E313D32A708A42F64E9CF412EC0E358F6B833EB0190C5933037202C266ABAD212B570E609FB7D338AD3F850EFDEE9347EBCFEBBBCE90E7F27372E244C3F035D4ABF1008055215E573F0C4001FFCDA5E6B6C5B29B7F59132CD86481FD0E1245EE4084DCA3D44A0C9E6B6B14E1BCBF56F470F15609DE76588795D5CB62BFC9C253EEFCC155C116D70CCF9112D8E0A801A3C640C7D16634EA02DA9DB9AC57DC2F7D43F48ABE631D3438C2BD3EC97832244E81223EEE47054878BB2472F64E9ACA0D5A8B0B04F783C5052E0ED6AFADA5274C94084621E989084EF9814128226346996CEB6FA07FB957C7432878505442FAFC4D945A953336F9C92B8ABE4E4A092DA65E2BF1A7A274E1EE9D7958E35334D9B7CF8B314F0AA5C45E93111460A8F5409C0BCB842DF9C9887FE4643BF8958CDB40EB66438BA53972E359EB712BF4C553D871ED702F74C41D1217D7887C891E49043C0826FCCEB2897BFAF9F217DC9F566DE1C416DE9118491162113E2EB56CDD4C024DCA4A33359D88CB0247BDD6802455063DE9666A4C52075359316B3B557D42B7C99700F55CABCB2B802AE4209C6B937C798433AF94159A4EC0A7DE00C809F6E6675A4213A1CE8A7099FB7FE6A0C7FB383233444B64AA120BABA1C4E61C6426001184E897A3C6B0BDCF9759A72146EF848EFA65EF09076A4FF2E6DA518C5A08F2A2A12D904C893297234E53CFFA04F285F350412456C9A13E153421D65DD30B236653AC13CCE3D5CF1EBCB8AB46808414BD3725987D6E464EB4F97321595153DBF9994F7E19AFBD19E9BE929D18563789567B28B1AF05BDB5D2C5C289FCBE8EB159D0017E09DA8FE5E9D49D3A231814778370DFE703ADABFB175859A895A6ED86F9B6B52CCDBBF936622C5E5A01D50E2B6D5730EA4588680EFCCF390211F211472F9E10314482CFB45A24706BBCA8CB515B6A9AA6EE1D2509E8F9AE9D6F545BD3971A02CC26699608FE1F076A925008AB6CA8576CC5A962326A369BDA8ACED3618F02BBC55337FAB2D66050514F904083D4386B43B6EAD553DF5603201C6D684F7156FBD2D3DDE3D7EB0D569AFD42886E57B747F21D44B88AD58FA2370FE6BF2DFA4D94D8FF983A1C2B89876E75AAE3828D1306DB9A639D052EFA6A0EFA0F61737CCC45E0C516815E92E256BA49E7853F9E9D4670593BF9402E59EE80F6CDFF8244D156FAEA8220D483601794A3CB5E1D7B60DCF991A545D2C72F62E5EA05BEAA77FA86A80400A07B97D8159F0EC170913ED885B578767CCA7A5BFB8BFDB7AC99002555145D9DF5011654700D6FBF2EC2BA609C969EBECFCC0EE346FA01B6CF07E6855F3C832BF1DB6E247448438BAEC055FD41CDBE921E5F62D93F4E7964258A9CB3991E8084BFFC2E5B29BD1E32A64E32BF5E27416CBA7FA3DFC143281F3797E1927AE9D9E07FB424833A7911C23F231D676EB0FB061C179C72FF0038E48068D43A805D56C3B6A16F5A2E5E8457F1A3E0F927A8880CD261F0D0AD8F82EF0E52E1BED003661F1D4510F7BCCE680CE84A0181F046366126A53EE67C7309C6982C28966B6CA1F324D03F5E09AEB111486C44B6551B1C36E84C2A72F78AEF5CA31AA66EDFB0792C00579C0C7C1FAE501735706CCFADE03E9A0847E498A24AC1DCBC7DB8FFC946B8D914633559B63E3031C214414BCC1921D2A53726695340648CF6C2BB4FDF132C77BC39E9CEB2E4D22EB138D807D7B79F78CD9713F5BE7512FD32E73E886DE16A9B1B19026B91EE6AB92DE4DE663D9774344B283149AF4890BFA57ABD1C9DFF128F9F169E4CECEBA0FEE1C33D4E34B877EF04DC887F7109B2BA65EF5732ED4B7C6B33131EB5867811D4A8A3536102F5AEFCACAA681A6A45A3BDCB24C4FDBF49A134244044E2B424996CF6F3C514C77EDF2AEC177B8F80A1AB77F6D3D920E508C76EB71ADFE2209A132839E9BB16BD9991A545AA0587B7594E0422647DC84CD355B20983AD582324D4F19E33E9CFA5CEDC739B26F43BBAD1F165720306F48CB15B23B961E5990C2DCC39E5BF58A9BFC10829590A7AA8F60E13EE1DBA85EF5EB9B1F6DDA891ADF7357E16CEEA4ACDC00E20F8F364AE3EA838CB4A0FDCCF8B439A242F8D18B8E0B9FB8E074922E0C25922CBEC46C98A82E93F0E95884BA9853CC738AFADA3F08BFB66C17DE7977EB7CE5495B8620B537B49D1D37EA4B3477B79759EC7D9AF17EFDB2EF89945D453BCBDB349CFC623FBDB8F125EC492CCBAF30006523B543B6A17245CDC5EE7E28EA895654A5EA74781CCB0F30343C73B4BB88CE07BD37DE9220712F11748EFACCE925626FFDD8447D37BD9CF2476437C093BA4CC0AB674E4CF9543CEA67BC25B9BD56946C0D077F0849796EFB74C7F66D5B86CD9A38B8138D816F677CE08DE6A6A911BA4DD1834751548578CEE4CFAC50C11D685E52DECB77A475FF5468C38DB23853BB2118C78AC3D52079042FB7F370B3D0406E402EFA6432D3055C572C81DD999876E8306021118BA87D5D430E4AB9C24670EAA1274ABF4BFB8149D9067C427DCC026A61C5B724CAE1858ADE366FB42CEE52C36F0F99AC02E8BDF784EBF311334B83B2B277982519DFFA3AC35D97F9F30635CC17BF8E017EC4E209EAD104B52C58E8762052CA62BA7A82FD011860E4F298D889A11F6A2BB1B4157CDA42AF9CCD0B5324329A92CB9FD6EB81DB3FC58431BC5C9A6DC1B07F7D2B00B32E5A39960C5E2CD69CA2914F23365B518ED746B27733D713E8ABEAF9D1FFC6D3D9B601FB386A6911F24CC818C0353658CB826F43FEEA792055720065601F1364BB6184699F16E3EE2B359CF0642C85E9115B18E55482356E2F91121C5884578F3D2C45462E47A3D477B3D63448A8C1679E68F9B7AE509100B7B2B142FB6BA20179E599259414520B02B745E592FD10D0D40D780A95C164D651E96A7052B69BBDA979216989A57506638F891336E2EA123303F997194B7AAB4F22CB192AB59A8BDA7CC88D0F43E4DD949146006CA3F91CF28535ED42662A61F630AD6E7319A7B98FF5C7200FECA768F14BFD43BD60DBEC814E22C26F1A8191ACC869A6BCE61991E4F36148908A5B1557A507C407D73A6FE75A548CBB8CACF13E57BA6B01FF0DF900051AE7C0C346D5DADE5F1C1BBFF967236BA5BAEF19A70FEB320BD76035F3A6B11383F13E6DCB8D1533A6529C98334A3F2A9105A5CF1C940659459C405C197130EBA44F0A2881B4614B7A0BBDAD5930DE5C3389A7349265629E29C0123CC89F3F540FE5C9019662A4383A38248F22201967D908EB48D530D17D50A08B35FCAB73AE8ADFDD72A8A7551EC28C7573E2B33EA4F61EE84C3DCA33DD5861B8FB7176C4AFBC174250D51F86B1452903191E39EF099C0CBCC15B3FB5DD30A2822F68AA37D59583BDC1CCDAB1B2E0337BF397647FEA9111A5B94C6A3369E90F3B86C266F4C11C9A7D9E24802B31B5F93B8EA9AEDC6C2944965D6B54601311D251E81C77AC1BB2159263D0A92F377F111DBC8D554C3AF747FE7E82A6E6BF0E4E3743B7AA42C3B5B8D3E5D9C3B427B3290452136E61592609826F4B61D4960B7C3784D0E2508363212AEEAE624489B739D0573CE23B35D30826182DB5F4D09772582E4D6B61938041344EA434614C21B01530327C08539A84F03275D0C4A77FDF230FBE6639CC7A12C34545C5CAD34AABF8E25D64AFCA8206948737DBA643867A146F17ABF81A926294E2368A5A2F0C381E2C244B21843E3ABBA680CC3F1F0509DFAFF4C70B68C82D3D7EF8EE053DBD154376FAAB5D561A19362314B037CFE18DD03BB817444FBF08D771A13B9D745DC066C89C10ACD53597B74916BA719F9EEEBA865252FE13EDDF97978092FDD1524CDD865FD6AE9C14329EB62B322F46905804AF1CFFC13B46B6AF4ABCB107D44DD27B460101F7A38DC786239E34CA9D1A444898673BB3DD92EE88478A3C539A563CEAF5CF499AE8E07BDAC0CD5419DEFE2977105B5E0138D84A8F9BFAD82F58884377B803C8B68164A3E678648C18127A832FA994EBEDCDE4FECE85DAFF8CD6F44F4CE57694522DC30BFC492BF62796D05A9B87BF13A7D538EE5C55E6898D50ED127E8C12F87D160AEEBD3CB126BC4144A51F685079E962DB6FDDE3BA6D0C8038BD6FD8377C4BEFC2EBF1A876833516D206C2E309C61E4CEAB5F86ED83FF20C8723BFE63D8E480798292E6EC6D418D3CEB623AC6983A3F8A3AD568F73E408F15AB88C8F56F3CCF5B32C76BDCEB1FA41357C42E1215CC503A316EA0A83FB341ED6ED20B1154E5001A754F92E97570F9DA7EA8AB7F2EFEE7B79A1DDA705645ABC5B1E04CE4F922BB03435D11FC83EB580CDFF7EDEB78F2CEBBB6053410E84477864C16D4CD7CD9D16B932372FDB99DBCCE2DC3B5CDCCF7DB86AEC9BDCB8E4F27B65ACA9A3FB985CF95C5BAE253797C8474D0C25F0FFBD151E6558E524C6E96267677EB7A3E128C918CD3B09F1DDE311401152C62B4C59EA1D408ACCC4A12A34664D7C0858D7E99A0327724AE9CA55A9322D865EFB4FBFD37FC79F8D7B2BF08B1824D44777153ED6604E05DB1FC9B1ACCE05F8C53C32594A84F32D97AE49E819029204AB7713AF2AF2C281448A34C69D5F3DC76345031D2CC05B6B26303198E182901FE65710EA95793DC8495F1995F0196DC9473B7AB922786BBC61A91868BB0BE05E2034EFFB288502DDFE2595887CCD144E98ECA4D1E0C044C642396F98473BFDEEE796530467F6B5EC0D5B79674EBDF5D1416F94A8EAC7F4833947F1DE610029779CD436729E55AE3D959F99D5438E0E4407D0A870A38AB31E08F16A06345B7BA730CCF55CF1FDA1E9D04833ADE5FD74A34E2629DCB75A3482312860404F7E75D94D7FD2C8215C6A21BD5FCAE81CF4467931A984AA24B927039526B95C2F5F39AB2040A23C76B64CD2D04E95DE6DD9B8EA849F9F7919A619EFAC498E7E3F4A70432E28B1C5DEDB08D122AE503E98D34D13A4E8A69FA267C3E20671077F977F71308D3EA1AAED5DC33B3F41E0ED981050B3B915EDA07AFD71CFD3AF13A2063813039BE85EF98706399299118D2427A7912A131DB7BA731D18DC2838A116E05C4CBC660895294A73D170C060CD83C9AA0884C5F3FE52F4891C2101997D688709F356A556CE202C571E1170BC339F3E2A75A5A13810E3A2F2133438C1705895523D03F00BBE4F4FA9BCE6D7A14517BD54E281F202BAB40DF35253961DC9E94DF5C2C5C3F0E420AC67A85BEC2ED70545B94202AACE5E58180104E42C5AA6F7F59915BEA69AC10F678D40506AD2B502D77EBE4D05CF8253B4795094F04BBDFCC8033EA131BE83F3F647D22D1212C16895F52FEA576EFB344A476D2A8EC74739BA62632C4B5B08076905BC0103CC9B2193EF6C4785685F2B3F79FC39B5ED09B258E5E9BD346557F24CB542B69A3ABE367123179879A02F941F9781935D44BCABCC563BB1F31C44BB77D5E7A4FC7EC2C11D597E7288C6088497DCC97910CFD8245A4F255CFBCB8FFF95905E8224B770E910A253356916EAF1B3277D831BEA5BD6681C6C7D57D363608EE78973B7BBBC156FE5536C963030B6BC8D306F3C1EE72F14163DE0DCD0CE741EF975A9DDA77EE386B991F3096FEC95FD394E26578269F491572B36AF42CEF1D86CDC82D63DF00AA397E1960378763F5CED239BD2A6D0EB7C5BD7CDA2228B684FA57B7FAF497310D510CD386DE6406924CD592ABB1E9753EC8BCC594ED52B70C04F7C53E19B0CB607DEBA79FABD6748A52692CDA34BB7CBF95D1ABBFF8AEF8F8AC7E5D52EF58FC79B0C7662DA90A0F737CBD42E64B648B624AB497162A7B27E41850A9BB4AF0489550773EBF1EC6742CE8D53A20921149563AA74337ED4CF1EE8685F41D36F748B6DED5F894BBC50A8DEC84621B6AAE690D6EE0B392A7266A480CF985295361B14AF0A5CEFC1EB737ED3AEA5E5894FDE80CAE477FE742395CACD1174CF2B345774BDDF71853BA1854EDC8F5CB03D33C5F58EC386ECBAC8E4209F8881473A4FFE306ED3194F455D4441D132B7685425435E58AF1F2964B657C71EB6E28FE3568183F7A0E570821EA49DECFBA3128002E77208749DCBD3F5E15453AB6DE9EB313D7445377B3BA74BD2F67AE31F560ABB628CA0DDB120CAC6CB62EC9CCC65051F70FC41BDCDF29F885FC9A558929F58CDE1200072F96C3D8F22032A0AB3F705884F0D827823FBDB62FFAA39EEBFECD9F57DA083D1ED541CF36465A999558F2299A865456C94D67E74F1EDC7166F91F4CBAC8F89E680BDED946A174E9260DD50C6B0A980A4B886850797149FCAF8871AB3080A76B645E333290A0DF319DE058981B8CFAD7A54FCD62345DFD9C3E6F7A26D212C97FA6F09866E23D5A19EB9CAE760E876B2AAF43BDF9004D5CFDC41570EABACACD4B57662087B6A91B6249CDAF905BC2B1AF5934F1A05D20E6C6784F0FFDA0A3E79A2C0939BF36C55EA0E31B1AE614D44CD413118EA165FA549026574D1549FF7D63B4C464A896C5C0E8D5569AB2B10D1DC56458FD1E069B5F91B1D084F7AE34F67ECDCBF33299B12C102F953CC48B0661AB4EFB493F7E4B2EA8F6FE59C3D5EF7D121B26B912B86BC0AE987B6A3543558F0B935AE62B4711A586DDAC9E5960C48B99CB80191B11F4053527905123D20C549457BA87608948933442CB06BEA0E73FE99E3C4198E9E7C51BBB7074DA46E752E46B3E419FAE2AD60D180303D710C0A59C6B980B24F0BFD39959368B5F56AB3845A2167F4683AA82A9613257BC801F5146CFCA857F2DF4FBEA85C54930D4373F70C083F661077567F1173819EBAA585EA3675F97951CF8C9997887BBEA9B99E17A1E0215DFC2B9A66760A277F68E747141AFE5CAB6B25D73D562B91BADDCC7938F2EA75F1C990E88311549F38FCE2C52933498B22E2810227D1EAFED4BEABCB153324622E107A6D96214F3C6D5DB91855005056A8D1BC5D5518867C373709D24DC1FCE21537C58999E26CDF4FE61ABE5E1225DE80F98D02253999F39A145FF3008F12880C173A7ADEE15025E3E186FF0C2090872A0A51505A09094FA2946AFA1840B0D6D526DEEEA95FD8E259E70B2E794C97F50E7833B165E7BEEAF5D3CAB7C3AA1CEF00003B94159F0F6DCBC74808E3FF237D5C3E94353FC0E700CAF48DA8BD94B991EFFF2DACC9E423A2AD63824CF879EF838C784C7D4C0CEE3DACF5884941BCC14E043082D382AFF598BBE0321DFE9406434DDF558EE2BDC272C2B04CBF8CEF92EF8180D0FEBD3D62E1F73F3B1E7FB0EDF9B50538D49C52CEE53F3000E581FCD7E6FEA1CEEC9DCB4876B3F1D1B1A301A2D395DEAC54D68181406D7ECA05A416D3D8E0EE10228483D8515A0F662D933C53F945B50C65C5B8D51EC45360661C92761A1F74EE06FAF8889244620DABA05593DDD4D6A82A30F34DCEF50B1B1D261CC357AB0673370A38DFEDEF3D591377CA29DF609682EFFA212092ABF84FCAD677DFAD758575CA35046467C6925B6185F9B734D5E194F5CA48DD10D0B84B7E9096703A9EEF0D3EFEFFC0F58C4D38D741F15AE766D06156B26E9C82B464C9F609F0A4FF699D52E0E11E054738476456CB81859ABE457F3595E9D7F1CFEE5D0437094CF093F468C79C093CD615F7409A505C610169010F46E148F3D264FEEA1DF42B3E78D1C4B33C92EE9BBD9C508E89BC4CE0BA0C412F75821EB54730FBB627C6C93694810CD741167D5288768165A68034CE2B16B0E73ABFBF75A905C9A9E577024EF2070EBE8A68076AE37BDF3507C7CB10EAE13D3A05BB3DA33F873F488150CE67AB892D61A11FAF5850B6A26862FF0CE85E4B0AB3EEBDC81F68BFDE39B0582185E4322404A0195BF5951BF7CDDAA6530DB0EFA0A2E6B2A9CF8DCD8B0D15447448847D1EB5FCCDC80EEDF166988D55DCF3BCE37E24A0A5F302F820C2782849E70BA47523A7AA1FF12F144148E9B5A1E05035A346FC4028BDA824B8D5FDECEC4036EB2C3A7DA612A703EFBE4D5E5E17CBCE1EBF546880C227EEE2D9CA4113D0ED61AFA70171700F0F9A1BC7CE7807A081EF09E9CEDA5DFFDDECADAA7CB5ACB2DBBE26550ED006C5B7DD89A2585EBED5995F8F76F3EF8F13B6AE77084727DC894C74268D4D91000155FDC94DEE049E54F4E4D2494EF926F23B73E60EE16CC3711B67B6F6B3A3BA6BA8CE602AE1BA87ACAD58650AA8F7F0F36AEA21080CA8DFC618AAF865B14BBD69FF7B413FFC81DC6C8BF2A7B122EC2C13DD7832610DB9E6EA0E5CACBE1703AF551997E6C51BCE7BAD4B3EB1F392EE12C5691F795090C6F1D6405D0E682F279B3DE64A9F45B1853346D8D337FF8037370CB4DBE5B241959FB8DD985A4F154470833E422AD9EAD7A14EC1CAF6308FCF7E9AAC13ACAFAAD98011148A2D52D40511CF13C7CF0ED1E320617B908BD1A6A442FAFB2E543703844B0D40FCBD1B392CDF5DAC9CE4C2CA69C8F04AA033F5D6D11DC1A5667FB352BE6BF88A9978AAD37B01BF8652A2C475E8516AE1A6E56F8CD596B9A780864ADC65A04F615ABB2BD4BA97301FB0CB7D9AB5423BB14C29030DCD5345C54D556ABB116051C04D79C81402B70AA9F32CD01B6C06FCFB416C4CB7709CEB12DF3E8BC541333C90E6D991B24D7D1D98D0839AA86614F3D91ABBEE5DF138A9DF2C0591204FEB3D9DD546305FD017B72FCA4DF01A7C1728606EDBA07EC101D7172971C9F4ACE7D6D09E06BF9E8552A4CB3ABF6FD84FD350F60A3E1826BBCBA484D4B5B284E2E1EF2A164FEDCD0D22AE77026C4A6596ABCCEBF6ACE68C11ED108BD3C"""), TestUtils.hexDecode(""" -A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") +a3426182a616883300b2c714932258a288d6f9d23c8339e1639f0cb6affa7245fcd901acc5612dfafe3e4fff1171e24db746e388f629bf6ab0e2090deeeef36a3b3c610ef0570193067af930c98accbc0d6830173136316ac7d5459e4a2cdda6f26f6509c35d1232af44470fddd0142b6d584766de939dbfa3edc9c905189e0c861eb16667d53576a9d4a7df0073a5d54058500e1f54d3898faaafc08b116336669568d1d18004d33c2b71acb0686472ad04b23a667d6d3d7d0d9e3a434e34d505d63f17b26933b4427931701aa35f2f6864465b650c9a6673397ff4aeb6af2730206f1049febad306ae06f30c856ef643c8c8ae9e3cb249a10a4646f9b7d985bde15103d57630cdbbb6716f41d0b7b1064346ec31907531bd35fff03872661bba13bba7d9a03031ee4943fb2aa549a208709a528555da3a42020a5c5827b06e7c917eb07c02732f7f559c122c545fc36cd006f33bddc2ec1a2dd67a60355c971e699d400110aa001a442fae92e24d05d1d091eef447f643aaa825d974f4b049e6e0f988ece4d510e79db57ccadf9b5e1a564c64b029cd265845d41474868afd6554996e7dbb2b3e92fa5f544de6f8840e841e886f7a5b77d1afe3b29f74dbab86a3f68cf223f9cbf41715e6f1f14b91146b64475a336fdeb668b27ea28fb87321f340c910b1814ec7305e11a0dfd0eac1283c0d0131092267de75cef5b2586399804afe72f7da133d04c02f19c2289c17bf4a2ab1d01bc2830b34bc77b15edc8fddbd0359587fb9316c3ea1ac8a146fd5229f86c38920907d77eff0b1c581f6925a1bccac2d234c52d159ae44f6d93a11d133edd6d0f6683f5165abf5c7197a50827fdaf713eb3bcd562ee9055be72e879849b7e4105755d0b9052885195e100ce302d3372fa4e41e3ab9e48f61a2ca054fea7132ee7ef77b62d61e02bd8acf7bae2b56cbe5f0224d15c3ef29fa051d2f27d56b0057b846fefa044ec57171549c81d7baa27e59e134c28cf6326d49fcbef62af5937d42953bf5662b60729ffcdb8471733c44cbf34765996a58430c02dacb23c6dbd9d8550eea2dfb669e1738fde0c9fb34f0051fb99cee29bf5ffc1ee95419580dc56c9b2118ea80a7b34c1a2231074195f45dd778dcb1426aa7feadf475e065f9ecc00333d05ec3ca0e0cebb2940fd7ee81e8a18821b59341582acc43ae576cf850f8e7cb040d4c4dab557b2a80fb3891669f86a00879c45c73e6a363ebbad67f99df0c5fadecd53494b5872f902e20f3d41e4be6b7ceccd89783ae2464feaa9fec596440fefa3111bf3efe416481f5e739fff33e3b7ee1c90064acfe18528b8ad3a9f3dfea879308521416da9f6131a3279def7f9ecf8a46373352cd14a0765f4e28ea8f313a988dd751d0a15b525c3f2b19ef0d098298014230bd7c8a042afc6d6eb6886e22449a36ade8b5c8e114cd408dc54ca4554f291882272645f8c1c10eee4ee4d6206525d0656867c0d2b4a134a40ea26019897e6f2bed4b325ada4af846b1db43358d140d54bf61bc8ad585715345aa2fdfc6ff62453bad6d00ba9ea11b053e776d72e0bc28f54056c7e0feb06314b3dd0023b257eed796bfd594d2a2b0ef19ed5eedf68a6dd19558fab24c9a751021c5fd964872e4a8eacbbe9406dbdb98fd505870ce79e64ed57c83887edf6ea916b29ad0c1c34d02f115e9a81b76d70ed6bc0900ada79fb5f7dc069fd7fc2f87ef9ada6be01f3e5c2e87ce02b38bb4c5372fe69fd7cca02898618d952c6706c88bb7a8b05a3ac163baf9deb64a0c5523ea486825f00cc298da63274b4d085b7fc6324b984d86d9e39d2cfce97c2e2a3ad8c3c04399e23af07f4e4c8a49e58971f8c379c88258e7ba25f6c6e9bf8c090eaf06424ace3e91e3ae12bd552193057f2542c6bb89bf1d16b7039395a8f8f54bce4a67caf3baee88af88a4a34ffd0d3673710dad8b1a98aa7a7678675f87da138971b0446e868fe1a39ef268252fb06366eb194d1f69c7a86b7e805761ee0de00c7113a2e1c5f405cea7207ec634cae3a43308d6d3caff7a9baa0670c9256fb90c61a116abb81910fdd638075283bc76928a82074255a4375872f02cc9ff13b75240609fc44125d46e8071a94cfe1e8fc68ec03665daccfd0dc385687c79e5537661bfdca8462d3fd86ce26d599f5add12e57c49c0ab1347c2fd967cd62b6e88613051904a975051309d5a43f9782ee31fdba8ca641f8d5a27c8cac9131e33e24bf5a1425dd771aadde8bf0fb7a0b7b896dceba013aa5c0687e327c27106ffe79e545f2249eaddac393a6e062dc296aaf4496c4936dd0365d3d248dd2811a95b2789797fa05e33cae686819789fd2b1315aa90395b0afb2f6084836ab2c78216b27ba6a65f09b23006957522679a4e372369aa65a3bbbb8c8af19039ff0cbd191ba65c0d7e0acddfb468a253f631c4495a808083e945496432a10195fc221535e240fead5672421cc1ab3010ffd3faa39f818ae105dba8d6a6fb621f0b86ba9abb68dbbeffc24b26e55184d4f21d8ad733ef0fecd4c6cfd5a403e551c91000cb9b6a26c3f6a246eace5717c784921cf154bc7fa61da54cd0eb55846c086a6a134716dcc49f44b55994217d5e92523a07a28733a95efdb2c6ecebc6d3ef790ab10ccd113d4fe96144d0e4caac971370d78331fe91648d32c2373c595ae848ef70a5a786c36c61d5961195b8a2c287608b9596224ee165c22336c07643b08d3c92aa5808bdef9c3c35bb3a5004f386dbff06c9dddc925fceb7f10ada52c9b5e100ce0e45fc23869f18ac4b3ca6561f98c148a86ae197d17066da6421f4d73ff4c16b489e84c4b09afe4c1e8f728f9dc4e4563c36ea110870a341632a390981fc1d114052eacffcc06d550c329bf38d7460c51a3ee0342d87157450989c43788b508e9537d08ba1017bcc0dc4c5a8d99ae5591d82fa8b258cec35a1446054aa449b48371db2f04f25cd618636309b5a40b7a32e589c80b69ef5cf19bfad44da6687abcefdd35603f32028fe079c1e541854e5b0b56998b4bb02ad89b3ef22229c9a8da7a381fda304ecbd458c625c779d7e52c8c44fcc45322a21e7a78d896417b513e298700389d0de1a50c7a3b653c87006bff64fd297a54fca09a4662d9710132d16e2e38ff4eb2a4eee0bf9b9d59da5d828da4cafe77262af02a279fc22a1a83aea33f9887880542e274c950d707e766eafe8610b0cb8aede80cf900f6a36432019e4d1f561f33ba1d273573cf1908a9dfe9922804f9e5ac279270b21d3b5edddd51c1fb2e8aa8789d0cd75c672eda3b06686ff6e8c7f5cc3fd67d2fe91aeda8a22e73aa9624b7b18d0060a64d6ce2ec77657b1d1a878672d5bc033aebbe3b9a7a224b74d859d47d89a360e2f7a1b03a4bb1ae92c063ed85d5d60391d9553e4d3776c5d4628146aac13c22eadd0ac57c46e65c525775ed3edbf0b41a01f83a2758aafb5324c1888a284ef0d47c12b15c6c5d68affe6c330110e0e8bdfc2b1a8f2fd67617e76f975a7d72630cc24e98eb45b5e9c8c442a5af3ebe4b3d3809db4abd88e49004d339a36265898c5a65bf5263d062cc9a307563081ec6b0c46bb45b92eade67a15449e0ba26e280fcd403cab8c29ffa15d306285b4052611ab63ea0549e8aeeb037e29cf23dbf5baaec582754768b2e357187343b3186bd6e1128ff92bd7c707f8b5f7dd9eb88915229eb0c8437d715f1b59d1e478b696da3ae27fb756db092c885b6636f6c11abd70ba3f0bcaa6340aff1acbf2182186981e74490f679c6b619522a85441902f9983231c2319a1420a2c3e050fd62433631a7d9b6947b247571303e22121d25c30c130e90b73fcc0367d4b7747688ec709079d9b28b981576e0fcf89593be1bc2868d12cd9b2159244286f46d3c270ed38bffe97bfd1d51e0254313703439c148f495dc73c6e534d05d0041c3a4f02ddec5fe88842b4ee59284a1cb2dbc3ee0c4c5ff17a5fd6b9ece5b23f8f9548cf537c4dfb6d231c0e8ae2fa7352d2c6df9d78865418415fce33cb613593071d83bbc30ac710d2c313648543a762977d43979b5f48c2608a68769b2abc933046762736a42a9b319c78e98be5500fe55b9dfe9976654e95999eaa2dfcc090500c8155369f49f3b9d296db180268de2bc26e3fbb428803d9075a20582e075330aa8d84fbe36417f9a3ffc3204583ff4d2731c27ae4620cf065acce9df4e8c728dade6eddfd09acb726d27a7abf9409a49739f84044d6403f5b9d1855da0daab9d54e2ac26e4dc9c71e63da692f60a755902e9930c21ed5c3ba5d1afeeb892794c5c948a236a2e01066892cef70267bda3415ff51a404207f2f681bb72fc0a14e2720277558dc201958eab0acf7157cc78ef8a9c12266932d2548a559c401cb4c63b36600638a61cce16da6005fe9d59f6a7ef14fb2a4b860fd7b79f0a27b8a7d631075f6ffdb9fbfd8d2764b069f0e10b78605b25fdfd14bfa6825db8c46cb6aa0c976fde81a5929c92240e0b5dd8d664013e561cfdfc59bc7f09bd499aeb45b8623698ad7242808e50f568d830cbbe864aa4bd403dad6a4eb67c33d7db2180d7ef9df51b91bb946bfcfbe0d216673ec34bf2dd72b2656344311191b8b24b263aa6852d1fafbe14b45e803c2b6d0b6293d4f58de21f6ea849f3e8fda46111416eaf6b8284de908f28e7f07eda6d42e4f6196af945fc41301545a848d76201cb84b3be2be65d14425d7cf0822177be934488a439bcd1120f3131d5c78c213df7bca4f92d39bc4274bf0b984fe7d6a35af08362f07250d98e8941d7859fb19a2fda77481d13563eb44b0ab019801d3535ce9ee1b8c24170196a8d42549345bc4d8af3d7a12f66b3dbab325ba4451c345588878c697f16fdc7c75a0077c31b2542407d339a90db740a9f2f3f696ed9d8729c61d296e0eab52a95eb5d3d6f1a9207cecb9b85661128ce3fd6f53b205783c95b11f3d599639d66967729fabf5e0dc1d4e24d7126c73ff941d6d996592cf26a6f124b5a08272b88d6f9f3869b10a7adfba87cc683f2a99e695bc29220b611203e82f67d80ca3275a79004479802182431d2d7d8dc4859820d17c483cd94b0ea11c286fddf5766a048456390ec48b2d5a94d2a59a236ed193f14a9d65f30e82d3df3571bcf7883da9bfb2d95dc6549cd0b9dde70ac082efdef59beb75299ad178cfe7f00679b9fac03adfd44677b8991f9b2da8e3a74b47b4f41f9a063886073a19a43408362497250e8428cd18ed437643766577306975a566ea499ccd3b78ab89382cd5b0bd9b84edead83285a6954264ab6e602e018e69754776070566408719e16ed075d9129fee670113899015690b3696d55b95b15ce290b2a9e8aaef3b869c215de4e1775a480a05be21e2a699717c7c568a755f4411bc2f05800841284939d08bb3bf552c2630f541cbaf3f5e12a12f907863afc72172bc56166c0ebed4e904c05a767dbf47683af7f8b98a16c859180cda8ee3d92b143aad733bdcafc7fd88fce16c39667e9ad26b73a496de9f5065eee7fdf2e7babf2ec58ce83d3762fdfcf44f76aa8c48a32d546761c1011e785fa09bdd5b9b08acf3e5f407b1c733270d495005d5f8709fbc3b3eeaf3b4845e437ba8d2ad2c20faa5c7f4de572ec1357e9c8ee7fa2987529a72572b59bca31467a6b77720acc272529b0e00ef04331e143946287d0ac080d80240d2b31297687f56a7a199b8f49a727d40cd14b61643b6548aafb0d760f3867829bde610960df12851e32c8ad61a507ce824fffa4656e92ab12dec825104c5a19379e11a2eca89165569d0de12b25a9083a355172c34e4a0e26b32aea3ded77f04bd2a6df6f951e295a6544871a06c4554a645b2e29216b3131832b4291230a0f85af29c1a5bf84e38c0753d8bb381bc5414b458c9c5568837885431d5db43edb64d81ef9bce7c20d89a5e574f376600d3e9b356fb1a819b73f6bc16491f7f0af200b787359e5de299f35567888796ae99b3a6c82e2b579c8338da8ecd499cba4a1ea92dc8090487145ad6965e702f3d9ba5a09f32e18a507a2ba1b40342ea2e3c4e02c908c99a2ac2c4a25d08387d8c444f78a4cd6237c047bc605afedea209df85ed0924489209a3da321dbe671041d827e022dd97ced029b73f6c8bb503bdffeb6d326c6a4cf5bd3716fb01a0d3cc43ee43dbe5692049591171209b47b86154d91cabcb955646479ce9d11ea660c39d7b4bcf1ad8b459b4f1589bcc7e1683bb4966cfdecb626ae1379fb66539a3cd5b28e24a0ebd290d2f214307f3d39c64d15e45d5aa17d339fc6a09a14db59e1dc2f07d16c97b117712c468b1beae5037ec65ccd569262fc9b8e250f6951bfaa7ec3b0511eee88d13001c4fa091efe03e41be5eb09e2a54d56b166ae26b4cea5869937801359193aabe0d17313460697e82b2cce51936393b6ce83167c5eef9131b2f7d85893a464a6bbfe7072fbac1f74c5f6579ebecf3fc000000000000000000000000000000000000000000000611171c22282d35""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +b5ddc2872c67aee1328b8becc910a85ebc35da9cb9ac8d19f282096d0022bc51dfd6718ccc09f953319df7a435f6492f9ab11438f6007646030cfe2d41849d540e6ffa22065d712eb7b36a2974a7e566e8672554c1d5ea9fe6a1f122a6ffa98102dd59d43193333d38fc6a1be550672ff1bcc4bcab186df01a9584c52047693c35e998827c0d855f0274584cb09776311470523e6d35eef3771e1b8d553e19f62c31cf3022113314f25f322d6791a670766f95d3e21c2faa57e714b2d8dc03e28d77bf8d6a102cf218c8a4aa4fded4cf88ba4c9558c66488127b8e52cdaa10487fcf90515a5216d0ba6a6e89756c664d31cd38d281ced994a1b1c72369b82c2a49b606e3cec00fb2746ab6f2b53f7b4ae4ed2838e9d7d08f9bd1709d7cabdf1f3f4113f06a0c8f0c8c8ecd0b516b3d47d9133c3ae054262c7190f23c802fb760c02a3dd60b182be708cb158caa516165a0919fb0738f72bbee1a4a270967461f3c707e5e03c76f8139a6976a5602570f3fe8bb15843301a51625a664bb45af4e80f6beb7be5b30a93f1658443aef86ca794a384a8e391a1f90ba6abba29702cade0c31aa199f4d5e01d4f8f26605f4d1dc03b33e269f27aebe4eca4fb85bc99043ef37a2be5fe91a9c273e1e06e1b38d6ed67ab34ca81975f9e1eba3ae888cb339152b9bece9e90d57154f728d0511aa8d3b210142d11de874a12160d7d61d73c176f35f547fdfda27bd5d5ef1d6fba1aa881e7766847b920c49bc389732fbf636fe3d13440207699b0ad309f7ee917b84b281e9661f920cb8289da2a8b9bd17fa75db956461e16cc494c3a3c46e4f7e2df3b5b21bac9ff26930be68c92315ab527dc603ddca5d4a12f4517a20785e791332bf898e50fe3292c4f1b9b9db4b41c5daab37cc8c75f90d5a586d97d0ba0ea01d9e177cacdb3e5f0e6e9287d3f2fb28fc0e4561139cd41266fe6c861785eeeba1ddcbb6c7bc03a4f268e9834d64c555ed30872e8f0b5643efe0f62afbe2ad9efbc4843c5733838ae72006437c254f968022745a49447365f39d1c189b7a7bec75cf345cc62dda809e64209f2302a3942035d0abce86f627fa07065d064428c02d9a48dac5466175ce9b83bdfcdefc9364da1ad356ff962eae2c22d580e915c8a003a62a20fe204a7fb03fef5c0fa56bff205f4e3cc1cc54d0b27df5450b93261ab21f1e056b9bd913f10d5c57bdedc888a0cd8c3f61febd456ca9d6d9dcebebedd2b732c80d6d5a2a2db403e8176826d47d4e1ed7267092879e5a4880ac9a10dc249adb18dc763ded9275a2dc580da01fdd0d4c60a2a2b918f163d91f423e4740f8d92a1422494842b36189dec000118b468456f43f0c48930065472f71810040d4ce3ccb51c800e62e164367a05f80c3283a562c06e4a8f7017b81ef0b0df71081a672454ffadc60dad337f4170a056935aeee88b0f81f356302e8a577d9cff5ca1e812f9ea7fd01b97d4211686206868403ccea209dfd24b89bc2d437f9ea81e1667b09a2e0893fc9c65f99d7a99ac266ab92983b3c443675f680772d7693864e75071ae430ebf59b56d6c73033e6b00476c0f0a596351fa2bad14517671f6a73206d0896712b824590fe2ff7ebc591fa6d556252c59083622067a1390427719e6301b743199cf14471a551e8962415b4c64c2847f76013409f6504238edcdb4616bb5ae54150b339499b30bcfaa09db9a30b612282cfea47c666735d3ff2994eac8dedaea997c337157e34afe74c563ae5997415ca2d1e59a32a29be23f51b0e5d763a5b0151f0abd44144073602451380ee27524dc89016dcbd5685dc34b18a41da3c483c6610abee38055d6668e9a4d5548047a10128877e57a9e55e3868393814e8e44ab79a099b51694b6196daa5e4d7e8442bb59c53c3b13e899727ca79ff9153fbc9e2810404076f07c60537d4ae110f2fbdc6fb8bf2e73211d5ed153589799db063be2df9378a14ba8704770c141af838cca295f33593739a6f94187827032704e716736c3f9b0af684b485822cb77c87c30f2783bf3fa9d4e1ac2201f8793d85e60049ce8f6ad2c4699e5364f3bd3a225b46d713890cf3d1f7e591893c9563dccf566ae6f880cf87d198e6f2ce29cb8683911858b3518bc4406845393f0e7240470119af07f4a5747249af96cb074a395b21f2a4fbaf50a780e688e8acd342ea93aed5fa9256e366506240738adf50369381520521538a5dbc4b73caba8a52c5e8184d9c40c14f5f0fa8bdb7b93b6e95aef7e1c79491c90b6225307c3fe7727f928f85f728a9480410b805496cf605ff284ab5a160b3fcd9c97ee4a8249cc90e1def62ee4621579ca78760b63ffba86d70e32e642cf4d4bfe3e65d221ff3ba11bf8c5fbe3303d94dd464d08dedbbc3b6e9c223dddb17d84f800e4a4002946baa6e327028d7f96c1299f7b3c8d630a0c56df6d4724d1fa14158f48b0b132eb56a73e8861c18ceed8df1b12c11c1009be26415c1ec76752c60bd8e850ec2337437fcce7e54cb9d0725ab60e0991759e61371ee7f3e90214ada3e2804c0b41eb77910a567a775bc9f548d90c51b1c7cbcc13b7de64dd0912c334f5b0beeb47b8e5bbb8a256403a66354382ae881d794e83d3254423816bed41456acad89388babd6b6365878438066cbec43480d713e0a11aa85cfc9b4937dc962b67d9d286453974cc85bf6b85da2dede72d2e42ef6f02e3bce340a0109fd70892661cbbae2a5aee9a17222e713ccd05e4b1671ee0c7baea4930837083fc33038843b95570a190e60fe1894573dc3e277bf005aebb27212fb4c4f30fa3148840d1600a9ea9b2a2356f1d528f76b0ce13c4c0e700f6192518c324ab0ae21add8f3ab29465e4eba6dc40d8c8d0c03c4f9835d4a941b82ccb86f021338f4297ff378fe6873e582434c6da35d9b854db0a8beb1725e3895f333309ad31bb23a4fdd6e6dc323c2f83865ddea3b60d1d1828c816d305494be5fa15df73b9723d454221e9bb262f2671c412e60e1353f542de2aeb5d379f552b963ea65b630a3b35e4d1dde64583b48e6651b4891000da1339e61f5823390df035f596c25d8f8028b2203b446ca4f35a979f9dded0268222cd3114957d087692517ced7dd73304e1a3861cd85ab9abcfdeab0179f4dc4f58351243ef76215f989d73882eddee5c83751684877353e9c4c55d37efdd4e9f8f8a8e01e8910c5721ad3f2d8cab4102dbd604d8b304090e21afffbbcdf48a87b35499441d8ce0d9680f7f2cb147bf4f28d2b3ab5574a5c51f2415c34fb4fa9a2e97badb824ef46753b012c439ca057768e7318b1bf1c7343955b6a8eb434ec62a236440d83c985f47692a425619e3d6f197c9b24b3720b20dd9bb21858d14e00f577d37b1030e5c39d4b17a01007c32d4fcd982ba4821db371d0bc9a4e13789c8f7481f9a687af04a91a5657a190ec75a12cb973c6123dcbc728d1bcea67afe1d752d05ce6fd53aa510d541907276305066500dfaeae4219876cd42e039e009ecd79acd6cc2a3e4270f1f3b8d9615c0825a13227130e3fbf4b4209ce1aad976a7134ba93455121be23cb7ade9486b9bcb3414645fc1075785bbfcad4389b0eaff8cb54d69a6be42abb56ee6d5a2505fe3658cfbca5d020f824febd71baa578c3fd67e4"""), TestUtils.hexDecode(""" -4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), +D46F4482D570F26C7E9F0F74A354174CA145033097CED3896350DFCE8200CB9448F522B118698DAD51F6C672E1B12A412DB6B7B95CDBDAF6205DEB631E44634412F026CD95440258FE5F0C72C5F3E64FB3FD13E545DD856EC2B7F51AC28C0D5D698C66C700DD3E409BFD96E14A9DAE1677ADEF2CA2CCD178B826AAD3859E569541561073095EFCA329B5B216563D956D8B7BB918224FB479FF7025FD8168F54D14ED1FDF0B399130C6117B5645D0E8DD242C3C7AEC6A8361361CAD9A8FC3B5A40BF7E73F1BBA9AC7F5A583A5B0EB95AD0AB4C1360D0145FC2C3A9AA50186D649B72B41DB7EF392E663497B3166AF9BD0C1AE21650D6CD04DD36532AEA0FD1071D6E9554CBB575B2C1ACEA3DD4E18615FE83AA211F8AD330C78FD32D920ACB40627CA4AC80F840A64C019124079484B053F525A5403383C21B164D0C6BC1B462C0E1C269A1EA0B2438FA64934CEE47149C4EFF566D9C2234E656969C1C89A0B0A4DE124EB920FF534B934172686A18A1A269960C725940D3307B8A913D56B78A6CDCFD559FF97E225B61AFAE7F62B060E7D3E2D4040D8D9233A24827434AB4EB31B0D528CB0085953D9A1A0FFB748588A2DDEBF241F93B41F5C856159EBBBC6571AB12F4EB534ED3C624CD3F5F836A99C7E6E2FFA0369654A5C07C19D44BC9FAD96983660E4D6F95DD9C38D84DE11271D23A6158B685CF050121425AF91C6FFEFD0B2061F54CC4393F99857F3B9775F81B6526444AB705F9CB88A2D276AF2F530B646FC3D93DE7087EBC1FBC7F9A8DB3F3C8FA186F7B636CCEF99FDC4532E54F560519C94B79B1158D85BFBE23D4F36B64F8056BEE7558252DBB3D9A43748E2E6A338162F5E2BC0934E89DC79091180C93D340D3615F82E7780FABF782E5FE2B5D504F3BD1874EB5DB76CB616CC034D9B2B080319FEB8EB97F62FA4498878FF049FA97C56ACACD2414E0BEF018F25A6254448F02E64815E525AA06AEAB53969A66D453B732891E31C36679B5C0A4637611A5983F21F6D4ADA1DA5E890C909A9E968F947C686C17EC73A0F9BAE5C7BF7433133F35F22D2A0B40CC135A7591E2CD216F7D8018969940EB9A5C4BF21579C524C41AFF5DBC0E141FBD02F1BCF376DFFCFBD06F9CD4384E128CF1F03139C853CDD04DEC61EFB8F1DF1A6450E4ABDDDD8A9D85BA79479562A08CDF06BDDD2E740DE7AD9AD1016D72A649A73246E8DAE183AFCD6FBDC64B6B6B2EFDDF525F3B764CAB39BF8D617D47FD3380B4A30081AE6C3165E9437B2F37A73AFC5E596AA626FE5A32D8873712F99910DADD0DE296577D4749F88639D07F83B0F6A05B1668D8008EA749580EE5A629FC2313FAA2F8ADDB5764B242B6B595A39AD76CED4CE5BC34C580069071BED1F98CAF4BDF740A5B1DE3FD30C29DAD808537CB16D0EF22D937F297F50E1681C898375FE0374ADD6EA1B84C10261DBECCCA8E1D224A4709497CE696BCD2BC1369F4135E815A781EA26A055DEA28AFCFDEAF6AB1117085EBF6B8AA6845FD4763FF9274BFE5FC6E377B9F9DA8263DC1F3D53C83F446ABA5EEA4095AFF91F3BE30022B9BBC2C74FC52A3B15CC76F29E541A84C5BF42D499F9B5EA134E24F01E8D866FCD20B7F7A302120B13DE636F48FE8EB99F17ACC153CE4371B266CA61D13E19793CBEF12C0EBA9C728096A3DC6A6750DDB0F52E3807C22EBE4DC6B2407593A1B7BBCED799DC3EAFCE50B483818D903765A63FF572F5D4481357CD6ABD89EC260417306DA1CCF71DA568240D4FD6858BB7833B2C9C98B9E7286FA491F9E318F25D0459071848BBA0D3DB8D2BDDFCB7B8E9C64ED67B4A2B5E1E49B55C6DCBF93394010A078E6F52065AB777C7F6D831DDCC115CF316ACF3680BE8766B4E15574AA383030EDA83CA45B965836FB2374695B50472C4159CB7980FE48B58B40C6CDD2629FE3C6DE6E13ED6728FCE45024C96402B78BAF37E74A1C071F4BCC2A1B84933C872FFCD87C02DBE65438A3E770903A04DF96C569FA69828CCC32D13A0A419FCCE454F06EDE43A97CE5A9A169C6E849F075C66BAB418791778ECB2C158FC19FF5927ADFCA90BFDB3B4216E19BE11157E858610BAA373237B42F811EA97EEB93D735828B2ED092518160A2ED894BB108AD74AB0113A8D5882D99A06CE2313BEE3F902D5CE9CECC835974A47FCF6FD1648C635FE56D1B2404927C49EB53FBD625E0624D5AA04D6C0D5A082C37BD67F477850458B8672C408CEADD9A55CC268B75BC51D7B3D75668D52BB701BD980ED22CC20611EF618277B82624A1192287B46BB5C4468F94C68D96F3CA3ADED476A18BE6CCED70924139F2E16C8A54FD6C9F6695E624499AC8E9AF86A430AB856924A0899E75C1FE4A51DA0DE1588E66044B2465C04809272B2A5C8EDBCAE42B47E439FAE06938810526DDFF4B64C515787B41885BE369A31F90E2D6F6C71528412572A67DF6E155C3705929EB28B80DF15345E0E32540BA9AB7E1D1CF0C015E50C9180372C678CE6C34BDACADF45B0172A1D3082565E16938F57CE6B55D9A711CF72E362A2ABFD45B7B56D48E89A0079E973F597D2E457EFF423E229AD439C3193C264E0BF9A8A1FB50266AE4E0BB671817CAEF10A3BD43452A2FD2DCBB2481D63BB539E0C81F6986400D3A619AA92F250ADDCF661FFEDE7617162B532EE2088A87F58E1FD071F5D720FF1F72335A5B4582F1BEB3BF19DBC9D51A62CDF68A855F7F6DBBE5FEB226C9918E7FFBC8A38079E411EDB44177F843EB8CC1F73B9765A0EAD825B3C43F6760B5F03BB75DC7469701AE555C2B7037952180255612DCC9CD35DDB31F3A9218397E1924791D29C410D2E4C3F5549B7EADF75045EC78D579EA7948D121E8297BC5A3A9F7AA2E2EF5776CAE3B9CB73316170F9B48B657BBE365B352A8129130BF1E718B386AA27E493016ADA86C4B3D3D116B7252A747FD50DC14AA28676F1C25150A86C9F4547189523280A3A897F80FDBBA073EC645C9953B7F8CEC3BD08BC0CA5640545B08F728AA38A860ED38C068F0D"""), TestUtils.hexDecode(""" -4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") +4e4fc796e18a11fe191e08e2e59c8864e0040297897b07d4f62d8a003c50f26e7a6e3d6aac87899b27b308c206efb435b7d48b32a6384e6c733ff5f47bb86ab493d403027cda502831dee50a116708aa01dafa83fefbbbb7aa7411ed417620ce6b035cf27cfa6ad1cbe7e1979f024a436a39fb6a6db40dd21ec16b90a42f61daab8b86efd38ab87121c17fa77bcc761afda7d9196de6d6e4a9b45f32d9cc64ba40aec6c9ec42a4350f841c1e280d60fb1382540f5ea25ad4e7c72333d4a6a4c911a9bf142062a50c2c7f61329ec502e4b4295409392facedf088c321929be05caff934dea89cf0f13b771bbb7832b956aaaa329c666e5582d3e4c51c53bfffe1502559c542f5cd0c6961f1a8a6f4db4e109818519c85f781fc8b81ad4db1a2444016523d79f33b9deadc30030a453bf9c9f48b8bfeac3a563038544141ae621961de26af46860e0d80d4b66bb47607a559dfc34cedbdadf7903ae4271ced072c49c8b91aefac658d1482c913559325be77794481ef2ee6007b643a27a3eddcf29a89237c340867dd3a8bdbbc0a1c8d07586fbc8c3bdba699f08afb44d728376d12aa7547912fd9b8069d5d699773e426f6aad6256853c65a896b5266475b283c17e60dde89a3b79f6b8c262d418b219a9aee8de0718f171d31c24a632e0f9db87dd6ccde3e295241a1f85e439f09a8e17a8cbc8d2e2c5f68147c3cb0138a6b386d42652efcc71315ffcf218630f96734f0c93d0f7ae946a71ba6939401b7d60f9fafab00021628408c3cbdc4c25e2eeb9af29a16871843d124551a4437af15a6042a9b2ccc227190eb7b22eac650a5ff9bdc1bbe867e0ce4222b2ff68d042772f7035ba911f2c4e3f8aa094290584d3902e4e1416f11c313efe437128761e2c9bb160aa58be7f2e3b821c128d69849c6fbd2a4ea4662477491e48c482051ef8f9e1c62fbcb03ea8fc25134e59cdc995575570056cb57fa0460731f3a82af5441759ac4f7c1ab5f2b2f5207e9d1350e1d47cf338c7be3aa05bb9ea4ea2632eac008ec50d7980d681bf91d1bcc583332c949674cf42de62632fcfbed112da44fae1845ee2490801528dc5a9f14f226d18db70a744e5bfe097ae1d17d6e557f670998317d64b45be39b9fae81adddb53aa5c451fa9d525d8205adef6bf5a500adc87a0af2069db0da6dc56a0a8807cbf19172bf8f96992c3c0d2b4e83722463e6f6a702abb058c0f868e9d9080760f2c80a1f85e30018642c3c88b1489145de6d53d27ce3c9f1765dbb459e865d3f8c05afa507d6421f303080c77647486a0611dadaa0a9a58d83d0859dd57b492c941d47f97529d962863821455e52415a231e3704e8d208c15ccd4a1e5cd0c2b434bcf9f82495f0d94f3c91d1cb74cf5da019d0c2a42fd45580db8545366a56febec804a944ade29a2cf87fe5772b3c969495e304c6a7ec148651ee93e2d894342c830849db83f40d9908d11ab2c919704ad55c74aa968501a38069ab310945f0dfe253d1f58fb8dabea9a8160a9fd2b5a0455b6d899a22386c8e814cf50c0aaa35e4b0420c59c339b84332047c9f193de73a9cdaa6463ed2bbc81060a36dec8b10f002161dc56f2085ac03475a6ed6f7ce9695f8a0f4fc044d2494d632598d778afe58221e5d435491ebdc30c2a719f90ce17ec6aad77df11b50232bf1d4eed0195765e3d1c636ae13f0cf95984581fc24a699640ec5ec9374588f8d74baaebb831c219b4df35b73eab7e6e15bd5a17a2803152c0053f3f3aa8096facd15a4ba1d2e0d90300f548180cf9b9ffcacb0cab9d6e4877f7a63d2ffda4d9697149b61f8ccef1daa976f92889c3090c7fc5c69bd87cd39d02d2de8ce16c6eaef9ca623872cf4f91fd426eb23ecc9457ff881da1b25373f1f6959dc4986cb0fbab15f7ed3497896621dd6b45bda78b7ed75c7d38cf7e74443a53ffd456ca84ee9070421b796285e023b5165020d3dec38078e599ac79ab1eda37a09b67d4e20fecf31c0244846fe3ad9b5ff9ed2b2f1400b7647a1a12db22bc24a2a5f1becab6bbd4a911e0faa4f4758219c19d970d07c90efcf8f3de432f526082f73b4a6e6b9b048e00e9887c164a62f3758b8b2a7d0ae30ade451fb5b405fd3a7aa2454a70ac22af75b986e03d8de972814b25ca0ffc3335206d30a7b748a10ea20149477610874348c07fd45ddf69c65d1e1854e3eaa00f6e6e0018c7238c7c311285f1ab9c876c52d212781006a8300bc2ce4c3729121b8b2edff63b99a29a8bc8166351b84ad61b66620fc7d0d5760b6409e42450d5fe58ceeaae5abfe937091d2d2d022057b2bdbca1ff2c6f1413021611e09b3a79455aaf2512c6a3d2a949e45db154ad328ef646db243a3242440159f05ec72ee2f5cd2eead4885f2d6dfe23ddc70ecccedab451645e61b17e88cb39d6bf1f1600b2272e3fa523ee9b570e515d59c8e04ccda564ed5ac3651d206695a0b8eea30a097bda798645d6ce20164a2cae126154fb5d50ca5749ec608db68396d9b6ce620cd8d78b701d6f9dfc701a7900db628fc9c25f06e41a70ba6e9745c4be3c0c9b0913d2c584fb2630582cfa1d74fb598515a104423124ed855a9a900cd6985eca4fe1a921a43188fd87cfa5e9defc046000641f58573a70222f6bc22462fb959df93d1d5c2a2266dd4bb01ba465e4e301c26cb9f49ccd87f92b5d92a30c4e7e4583d95a38ba2fd2fda90c8beb60ea9510a43608b817a51b3c5f05275dea1a857e581cde0a5751a334c9e233353a213bf3f7fc38d6843c839cc06df3c6e76b4b6df73c9aa90bc24196f9668cdc2df584aa10dc8ab41882a532bfe758cfcf16f2e6d0e7ef2fc900a3e5f3e261b4062b1fa3aa49422c7c6baf56d0120710459b949ce7b21089c02a14d5907ffc10c53557477599d59d83f368d5ba349c3f3693da678f2764dc4caa11a669e5b703a97a908ea7abb18175b1f208e448b1b05f1cb3deba9b4f244c5905f4659c51f0152aff9cab8bfffaa61a98150425f14acb154e4db9aa03d73860973750377284c275405d726dd615802c8f4738799fac49515f8c04a9b2fd693d083d3ace8b5e872413767114fcfd32436181f30c25621bd6e808919c0abc67fba98af581aa4383133b47d7d8fb67de035f65d507aafb8e1908c8a3ab305b0b40ebb2f70958cd69ba48c3d0f94807f0159f3c3205affad6b2e48fdd54be8e5a7e5bfdb3f1599f62a52c11819b0a7852a3bc1a424596c4da3b1ea7e6e7989d3c403979263424397ebb5b5a739137c1b3d1566ead912214341ddae970955904d9a5e79a002e3cae156694cd895873fa5559a7a9d21f090ad77d09471d0d00f3ea2238043fbcb76e5ed947a3384b05b838a796410b87971f95910bbee1c6815dfc9b3752382f980d48db75e28ab8efd094046de4725c802e1c3de5fee6503d383acc450ca7d637a1b5a68d7f099ded08791a3e845b0a8f6dbad10395b76745a4576bbb66fd6a8750a83616fb5dcedf961c2aa6d90d602d0526974a93ea30b26b01245c74ad5d060f8cdb3476e2a6c155a676ffe0e4939790daac867517a48271501a702568e7b349507db9383f6001c596077f82458291ec65813d6d7306e8a83c36d76ccf76e7531823e8ba7becaccfce8ff2e25504fe2cf86434d81a43b28daa7d479ade72e302f82030e240bd61a52b84b372d460d606fb4b2f649bdc51ff2cf379274e1c6bad82b5407516b792d7c3cb6545557fb2db306945dea8092e7ba6d033afe77833375214c816a4c463374cf36cbeb77a12ff095e9bc4631a3b459273bd3494b1cd49493a712bafd08c6a4d2c866958fbb773eed52f7398275128622b7436a39eb724c28d70f55694cf22fc3ab311653fc7c210265fd6eee872add33250ac495a2f54c9bb856d1ec8704c1c9fe0208a312ef3a08445ce3e9b4db2ea1c4b1ca4e79aa5ded13ac3c7fb69612e74255e0e6cc3a063d28b8e883fcbe3fea5db704e674497fecf7ca75110199434d79ed8102c510d732e612a18a8ddb3384b60f19aceb88e4cc35cc4af247edde5c8b26101db84dff825f9878761a6e96e104303441b9954091e5406aa9cf5d8e4010b4c075c374cddd31f471f694b3b9191a1f3d7e399693e235898bedc55628de4fe245e59fb02ca5fbf1944ab74e2783d9c9fe59f0e6f0de1b2bd70ced8f5e87c732c82bdac560e714546afa3836b73ad16373b72eae416e31b2ef999b2f3fd13f6f52deac065d0de6562cce840ba490d7fd1121d8fc66a53a27d3cab9db374e5b96d44f64b11232b2859df9468286f268bd4f186d434ed3b3c807cff498d1140d7d4b018a03b7b2b86be6c6b3a76a49c94a821989d2372744b1ed2e93e6e978c9cdd5564104d6ad141415ebd06a2559887af6b20f6b664e0bf7582d0dc1ed3e66661ceab0533f4758ca9d9c20211adfbb18a7eb7ed460539a48a131c59ead08680e8723276c1926a35081573d4e0c057457047e0a8e031861e5305e04c0619a06867be34f58200e4504919916c0f85945d19c7d2b2fc20af7c058e5f99fcf83206607f561e9619219da8867c73c933896e24f55363c0deb0d258c3f05c3ad71b3c03e2005145a6d7aa4546d53dd24109f20f902f7b77c8c475538788d3c0d0cd7cbe07706e144ca238c08b3f95672b90076ed237212adac8751d335320d2ee0ae94e95bc7f5c27af3c8da67b8b5d3630c7c6d006ae3ee184b5ff781ee470b7a2a9fc87f5d64187538100fde4bbd67be7a2f9c25c4a6f8e0301595963c280457395883a80ca695e98af29f0ecdd33dc3b417d09d0b2d01c5e074cc1abaf544ba9048649525f59ed02df6b9baa0b61871c4605678124cf5fd1dad07e892d2b8c0b14c0a9bf031493aa304bac36ea200f8247305394bef54f4608efad7435ef3ed5d5f5393225587e1ac3123dc1d92ee383e17d74f0ecb1bb025fdcfdbe7f2d41d0708f1ad2f766ebf69f4933ec0f8ef6f65abed4d883a38e0127530e8fd6ea36bacf454abd510b1ec49dc1d3bc31bc7d2b76c949a24cbbe7f676ba4677e19198d86ce72628e26f56b7c595cd07daaec87602c78a7838ae0d7d03a8ccaa8f90fc2f9e4cb9555d096bdfeacf4619eb3562d91a5414d2a5ccc90b565453f03a0f08d4ab41e6542bd2c687f62a9f41f348a7382bde0561e7c03700b0102962314b014b83980eb887783858a0c2e7818e7c7435a02c21a004360f29097eb414eed5ad78084a1f3cce2112639ec7f9ee6efaf166b3e31aa4af7925e6866743ff8c22d865f28ca97e47a3c979d0c2ba32eda8f862db63e07acda1757c8c7aa4b61d6011f5169f0fed9638b3662af701e486fddf0d599892d4215ef4252dc3248d9fd9f5ba3b5fb3fdd9ed601ee2a1b2192a5e01373441004841190d4a3b44eb80ead8bfa9c541939732913eae7904374d288645f4d5832691e338c82e2fc2ced10cc75e353103f383cdedb81e22ecb341ee19e400451ad3bbf0d10181a796c3063c66b1db825ea00e197d7b41558eb05a18c8e2accf0592a331055d5d09e436983efca0c334919d44f5cf729a26dc9c2abaa4c9086c7c0bded5814de50b86b86408473172e0e90d5d32fd6f93621a37abe618ccb7dcc2df0573d4006bdc0d832156c82735bcfe95527dd6b10e71f38e8b46ecddaf6eb7175879b7f843d821c7edf653b776cde1d389db91c3333a1c733dc45ead2f72644e125e4e2c7694dc4a80b4bb594cd052b470afa7323c5d9de044e9de8fc307512df126e794fcda65d4906ccd8caa5607eb203d4d183569d9cc530bf8db3989b331c7b4372ad0514614de405634d8cd1dc603189bce42e53584dbd7412dc3a7c9fed69f194bc753f45e24a289db30970a9a68245cb62196cd8a36a02dbed39edd9c40f4f5e6412ea5d9ce4d92505112f6dfc1fc46d0e83916693a35e01deb29b5c0d08c9ffe75aabcfb9af18c35e04611429e52285c5936f782c11f2b849280f009d83911bd6ed58b7c0ec9f8d822a538db8492e5f410020973536cc460861e41515c2e137d1f373e6687136a5057903e1afa8aa7700d5e39a23be933e972dcb1cd67ae7edd452dd3d229d957c5822fc1846175d48a5dd25adbe1963048bdcb5ebbea8bcac5498e7d805a0746a95f6ba9a8386c387d4ef863c424d62276a90c847e9019eb752ac6d844e0e45d78aaaaf567af013c3bd313ef23e06f4fc751537561ba52f7ec15cd460d8ab9ec917e1e33f175c3c1f38ec99a09da921ac62dfa458ef2d0d15d4669aeea8d797ea057ccc86431b4010f56fcaf4e7894b97d542bfe0321886333608e9d56674c8eb885086e9f312c6926713ad129c6faba2b764e4646500b72ad52f4158a071e0c0697dcd50bbb17b4689092a36bca28b1c6c02d39dae78e2484ff6b00ef8b5311cdfbfd061884d23dd65d1b0ca4a9aa491939e13202b515d6c709ed4eb0b86c4ee45484f84b2c8d5ec485686999bcbe0e746acbce53977aaeaf400000000000000000000000000000000000000000000000000000000000000000000020c10181d202429""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +dd746786f61c3e55ab5c50adf85106c1e6b427fcd102ca6495b52558626a21a4fb55fe9ba5eb91b87bce568487ebcc93e0a21fedb007f71d08cfd354477e9037e89d2a29f95069de968d619058963dba16a62b6dea9d773f7c1c269d889c622240233a6a092118c0545a06ffd50ffcb1dbcb5750aa4afd30458502c0d0efd753e7c86819353c71287e31de22e48a98e69c22cd25875844cf29e9a3e19749101a7a0dcab9daa82954a7a9106e274ba1da75e46f9d80ef302b52da908eeaead2fcce93be69c2c62532f0a666d6621a616767f2397973949d7b434773bef0a03c9481bf2574c225b5be10edee03c612dfe8adf07a5e1e6abda7168e04d128aa900cb82687d5f738969360b03626043946caf151717d27a1d3d0172696b9ba476c215fadc652d25298775fd4d7d3e35261d58d081d5393851b955b8f09aba98889fa54f78267d4289043a041fe871521e7f6518ce67a0c3e83ac47895a3fab018425a0532987855d4fe4a549ad372f1aa9483e3c6fca47beba9e2e217d606684c92f56709758f3da75929c37eeb99c031a9b446319e79f07e5a676275a59ad658738634ba8b8a7f8ce6d29eba2889c6d2b7d1914220e60137eeda3f6277f1399677c149fe6cdafff59fe1e31b38c863ba140e35c88fe8e3164b9e0715ee9dcc0815a4e1b3f4ae5b0ef18b1b76501f05d1304ae1e444c62899e74588cf9a262ebf2721badd1f3b684f56efb78cd38845dd3b0f417bf3b3157464b96c04946cd825b2b02278cc88173b7415dcf35ef6948087c84fe130c5a0b28cd6b0c45c3989050afa72c5b406dd2dc4d6ecc65821c716361cc8735d703073c50536e7aed7430eb35be8ee3d193812846ec860b9a0d363b83a3ff8415e2a9512a09fe671945e5b32702e477ba1870a53abd27544af0b431353d2f09f323a6cc69ccb5541da3d29ca3d6608b98640bbcbdcde5979b4d6b7a5b829c10b891f1b4f49eafe6e7464d78ec377b85290889bfd5cb5aeef23c9d6628834813867b7969b6382b9c4a18d81723c8c68d983009b03a1a8c269030d8eef2f84d5b860e8cbad943487ef691c78027e41be206c692e3214a13719b45c2273843b042711c58ba8711d31c0e6055ac73527de16afd81ce41a2882633a8b03fd975c3579fe4beb04fb6530567f5985954702e45734918adfa15431e33f65e10b8bdd9a7ebeaafc57562b47b1db5fdc8436f07c00d1c04d598cb6191c0e1fbfdda1549e5e0fcea7f27b6d4d34296eb39958129dde5b7e61eaf7440a75c07ac5ff2c3c656cb8d424dd992914f530984ed09c62b067f419fcde877e6333ee1875ff5188c7c35921e2e803f3d6abf93ee58326cce90fc22de31640c46bb44de19c20d72bc7672d39a02025eec9010defef580152c84b3763227b1958e2200216e9983dba36009ab592e2a2c9a80084a3595816098e53c424522fb89c154087e8da923672a3a9f3ae7c5225cbcb1cf9b0eed8bf98633da2b4bb5bbced0c08c81fde4156c9c6a5f8203bf52ce662343df25b5dd04c9fb0b814603274d503d6c1c335f71693830fdcb18f14e358d9bd49ec412201713022e00496674d43fed07068409cac95236b117943822590a3b756d9af2051ace8ea5933df1fcccacec0e291be9a4c65ec0e2b30a27768bb41eff2ee1f862ba7274f0a473125f9182461ecddfdbfd8fbe891822f088659acb0f1f36776ba219c4bf07c2a6ff9154f98c447cf0292cef0b698cc91173f5d94a629db45ea1c1ee1de5cd4b29630756fbf5b5ec7afb33dea594d45e7d37ded62efcd6063ce7a33068ebdeb4c444accfd8915bb24eacd7c5e537d4bad580b87a6273f1d0fc76750df29521102fc83ca432b918d9b66327b661ae03363df65256e4d642b55484dbb5203223c957940d3b059c822aa036d6e77178fbbc54fb020df2e81296ae6a7360ac767e2e88b74a88830eafb203ce5837e14a083c46de3bce7e0eecaafa5e7de831564191a8b9166c36df7d6a60343b837aecb8366de91509b54d973c9d6d8b5921a7ded1f2e431fbaeba893d4e5b9363d4bd737ab270cbb2c6d5655b8dea2c4a931a719428f3e9f905e03d885ca15f3d1647cc26a6bf91b7ca400eb3ae4aa03445bce54634cde581b471e3c03040413a7ac5019a113749918c1c8d24c979e7914f677f5135a84fb0535b6781e5bbd96d7ee1cda0afcaf28b1d47ed240cab6f2388e3c826d34fc13adfca7c41d6eda4ccf7021f2121f16057e70a1a68c97943dee4260e783babc3377a9a4a73a4393ca57ad398904f116e33fd83ee291c92602696c5b3806bf5898c4e56216be8a7691cc80c2563cfd1df4a06e437465f8a155a795880c61de03492bc9aa3dc9c6249582ce894b7e55ef06376da4088ac64c4bc227099c2ea30963f99ec6c7149d233276f15f2f0e21af7fba63c8caf54bd96d674f824862417273cfa7547cfe89692ce254bd6986a1cf52f480ab6f4cf8edfeb676fa4bccb0dfb2ddedc87c41cae31c5699a2a6cb413434978dbfe44025a0294db796a8c6e892be55220fe5e2be391366f7506f78cfbaa16f7cf43384182743fca7861a3d4c7af134037e297a55a5f1abda942dc1acb5a4874e5af451465a6dd2840545e9dc9539fffbd34c8db9834e7a7a9a5dc368c80f33ae01ca4453420dd9de645b209c8bc3dab783d7ffad5da47f318bdddad918d4b15608e7681c695418345bb64f67f5c1270fb97708b39973d8b4aaa2dc9c66efbbc6bf7239d781bef6885b8b35f11ee4028dcaf58cf8e23ce27a1b0426087a6408c43fb97ec56565d7c9fd7291ec8d24ef6b6c857f5f830d3a032b06a89f2ff23e62ec34beaacece7d4bd2ec04d70a2586694e208909d0da2190a03915b853bfafb36bb6eb6e9b8386f7d1ef8425d98c0d2af53f50cccc33a7fc4c8422e202038e320af2edde374b80d310f2972cf1cb80c279cb55668a298c9fc4489dafd79361aa4368c8e411b360f5c40eecf727a1850fc8522b210e39a4872a3207f2e73ea761e235031a1c2e33a337a6c1e1e365379fc96c3599bf8ba1af7b4b1000e7b64ead57893e24564201a04416bccc1ebdd8826933e0d7ac15f0ed8e70939c9660d0a23711b4ec8c1659e658e1165d2eac42f99751b4c0c2ae1a444c0e61441956312e279ae940914edad7297480fd44ac29b6a71f97eabbdb7090c3cb45e4a78e223877867227a9dcf8f2476f92b9329cb674b4bfa14079fb6b0acb38ad69dfe947d13424b0820e7860654d2a48dbd09e8d29d2ac1a51a6c1b300a536ea30aab4e26bbe287e47b2601a5822b6aecf3761907924c0906a1f91649b1bab2ee5e6996515118dbd0b77016c1a5622496d2a22e40f66be9963f6cc8f7c85dfbd3402b77b4ca78c59c494ea8703d5a656732279add7f0350bdf0baefa88216f9a09d065a339fc2132a07eb0019ef97fd0663a4b68ffb809f771e95f279f57e3d70d0bef7859ce3f22facd32f4dcb1787bc8a00f0e547c9d40940bda8aa13455e8a82b0a5cf4e482aa422cfe55d163d638fcac3d4abef3278be141a9c67d1588441f5b8c5ccb5930adb6d323fb086834a1cb5c6d2feaa8677e22cbbf992cdc742af799d7d17f0b30bb0f36d6ef7ac3fbe41d696d4896269a4c64825efb9b412d6fe4b3f3ee1386f2b5f1750"""), TestUtils.hexDecode(""" -EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), +78A2B7A4C8441C36E0A9831F65D41773FE6B81B3FA6259A320AB03D460D7E38F4AAB2B93C6142FB0F9584E4D47074670B07F3CC4513675A4367EB8F7F4168F2EF7CA26AC45C8F23B2FD3E970068F21D9A3F7EAF005DB5A7157715CB94F5E83E3C955DD68E0EA689B6F419FACA7CD159237085678FA5883D5330796AD64627CCE7F913D1C2259E1F970E44988B08E78ED1EC01CCC2D0274067100C1C1E3D880B9CA4F3A1FBB345354D4837A6E5FF4D5F5C87985E51C471EB9B0F85075ADB57DEB53A87D85834167A4A538134CBC24FEC2756F7760C3D46248D5BD6022D8F88CE7D037935DB74A6440DA49B97E8FF376101B296E3A9D4D22E70634CFE88142EE5FB6A33F323519EBE3A915AEE5BB687DA4A5E264C657438B0F6AC977A22D0E56882F74E70D981CF37FF0C57D285D8CB07ED7FDF6D7CB1DD39EB0D84F2999DBA9273E0B716CE754A29CBA2FE32BE13BE8B9F2117DD7359494A0E0CE623AB9ADAFD3F15F644545A39055D42C6C5FBDB46D121308D649AF9B86A350B70F77A977C8268FA1E04F4EFBC2C95A2D72BC37E558F0460BB281D33F75D2AEB240086CEB8246E8A44416A5B31EC58AAA88246D355591BF7C622CBEB1CAD3B785026CC04C73E352DFF28D77186CA93870339E132D57B11F0154E0CED426DB31BB2E125C5635BD489B52C5E77593145D3100E48CFC8FE6975FC3F60ABC7FA4A4D9030A2CCADA3854BF9AA213EF11E2F85E9D4E79CBB434C65ADC378F8A7DE33E66B4F8588B73FA7F79AF4130554173975280879FBE0A59D25B969FC45AB20401CBF85463A83578E63D0C8324878F5CFAA191428E7EAE37BB17A18D0459378CFDD4C8C0B23B1429950F054DF5C67174E99AF9FCE6B0D8C98BAA9078D2CA87EB8A014995FB79F7F49D78F2674839E14C8F74588B45C28E4769C439A930B2A187764D87D71200E841263EBF74F7428EC554C12A7352FD3912D95C96E4BB1D325DECEAA9D6FE360DBAE7AB897ED467A300A8F4C6630F8E721F24860D1FBBCFEDAFBD94DC9B4237B91B243A01C41D5E98E67B52B4A8CDF0F1C985EC0EB85131F5E970A6DD6D4E1F525D9D94530157F70B333F5E50B1B95D569A012ABA959456AF773B59BC2891D745CC036D06238AF3F34081A20F00A831422CCF6E4593EB56CAA3B7DDF44B388CD54E5EF9E3FB8A260847BEA5EB5FF9665530A4F4B56726A4C5E669904A933AB1E56C020967FE61E72185D56B38B03D343302712FFC1DF9D857C6F744E3ABABDEB3F65628932D69C65FA112AE3F7D6ABD2B4C3CF572EDA73C959637D0C5C188343415E9A26E698170F8E31CA45A8E6E8E96BD066BDFDFF49C98C491149D61AA7C456D3DAE0C017A32B81CD5668A400127ABD4316F3DCEA171C3F6A3E99B398CCD4AA7E45BB51963C82C43398050B8923CAE2D4E2A2FF5232AC8F2C770C9A775F29C261E1C7DAF54F9FF606560F869638B666C90112B29F469C3620B0912622892A432EAB443F8A93E3E7953235EE78CD3FCDAD3F1391A2487DA621526EE92735284C347853D5F65395ECA2B50B0CFCBD988F99C86B5AC56ECB82813A93208096ACA04F22AC015CD9860889E9006DDAFEE0B472FF7FC3D5677EE089B0AF7C6C2FD5A322D60BED621B8F099C30C2344F453320B6FF405639CF764B101E1CDBD312495C2D4FB30E2FA7B3C345B9935BB28EFEA69C829EB57BF2E2E5E42B8515DED4C32F9C84C33DEBDFB345A4BC592CA56A769533FBA0A631D5D0E07DAEEDD2FD588FAEE648B6391422924D28D08B4CE36084C20E827E6E73A97852BDD7508E1CDC1630094C9D3A2C8517A25A244FBA388EC7DE2CFABF139888EB7372E2BE3BC4FC71788AC3CBBB3EA1CCBD9616E76F2CEB356C13257A8E5490F3C4F7DBEBF942BDB941937C956DFADAF3A78903B49C5DE34F5EDBF0E98E3E04E51021B686325955C14AA335427C4A116CFCB3B89349B1258B8E0E354F13F86C86E5E8EF8F57D7B7501C5D75B1D9615D942B04E1FAC4EACE0FA10E6DE9B9721EB0651EB3C9DE4C61EEAE7D7E17C0D699EBF7EEB122B8C1A599A2CDCBB9B665DD9A653698735D5572EC379ACC6A8470CD7CC8245F871C83E6FD92111F5128A9797AE802889E4362104775CDB69FCF37AAC22EE4532FD0B5ACFDC4DBD56D9CE8B9EE2A8B923F42FC512B54204CB971BBC9677EBC49D287A3F68A31DB8AA49D6477B287285B88AF298E68C6EAC3C73FDEC94F7062D204AB310686144168C155281627F78C883AFB49DA50C0F5139E2A0ACB9A9CEFCCA39C6F4F0F5356D2898A4F5DEA78FDD20B79662F4D066E73EA4069DCE6CAE300B3028F15C98801912A86E0CF34DF53F7F6E1868DAD92DF22A238C710F471596A49843D3E60E4C381F713C21C3910ACB1515E5E30252C94F040F00A9D1A08A4FCA329DFE190B5464521BBAA32932022BCC5E119A96DFC941965CDF3B739F53DA156553C6BCD72927B07CC3CC945FABE44B7348257A9FB41EF85AD5423304E016E74E03D5164D9F15838C3A4BFDC29C6B9F134054B53B29183A6A145CECACB3EAC7C18E31CB4BF78BC8FE60A3B8EF880CB6C1EFE7EFA8D77580CE200ED96713E32FF23B86CF532D8EFA2FFC8DB1A9E65A78EDC30090E3DC02475D84F8D9F2BBC48B114C9E4A01FA79C17FCACCAB1FD304C7F901942B9EF57C918588C9CCEF0DC5FCA7AC84ADAD547982EF9E855F6E88D02751E8E7B8B76C3796F94C9F7B7C6860042A3A33EFFA55AFE1B94C97D68B76DD240346355012F036DA9C7E025C3633CE867510D54CACD36D8638FAA8EE47D315FCA9D5AE4BEFD6150086DFC368DCE8DC623ADEAAA07287F9B291252628F1BDBA5FE6DE45129509651FB048D3A686FFAC5F2299AB0133FCDBEEE8445555F5C649598649678847FFFCE6E0DD9C4E75E2F6E77B1CEE3A1740A94E678C1191EF46FC4D9648887DE6277B11D4C242DC4A427AFAD5459BF213E0A20EC74EB0C210D0A922B9E690EFDCCC2C160E011AB94F709C174F22629969B6332738654A133E8A13EF7C914CE75ACA1C37DE05A84708DA741161EE4D23C025B405CDEBBAF9040A1CB7492294C381FD069C4622BE1EBB0113F25F4E1D5A415C121055CDE5616662599C2364481BCDD35F7E498E80D2350AD3B34C205C5EA73F1B923E6197E07C502BC6F4F4288EB46013BBACC49A5DEE5071ECAE62B192294E904BF3FD7BE08F0C43E3EC6E23A7F68115FEB285AD388A0F8FB94126EDC0331834179C1F10CA5EC54159FC256D7E0AB3129B22E5AA5D662C6A03C7D9A6D066400859EC2D5B091C37E35DE31365F5125793E7F653013C722045F7292C014123246D611A7FD59E9B09EF24221C7EAB249330C91BC9F4D3A223D9C2CBF7130C5C057961BE89894221AFB1EB27A4604BE310EE3C395E479D852CEBA4C2F74D4DF416C8836861BC13D0692863667AFF8EC89BB9194407222589E1C27B9D59AC49131765273228E79C2933445B83D07E48A789FD6E406064593EFBAC4FFEE64614C5AB34E5C2A717C50AFA79A96161203531C161E46D71F447FD28CE4AEEF197A3DCA6BCA306AF09086D6BDF35A861820C469A40958923BA824F3A95CCAF8531E930210BE46D66CF7156EA0728F3448292F47ECF20DAC7C5E78A2A0AD5215FF37594D37A2AF4778B15BB1B5C4E0A44AD5910B62CA3FAC5BCAA4CFF5BF97C8B8CB239126CA09E92492121C9E6977111E6E5248661AD122C87007318BD3D98ADDFA1B2CD60F12AD1E072643FCF82C630C2093CF4A75B2D3F809A0496727E04AD60F14CADC7331B23D9CBE28EEC92C68C97E597C2EBF99F2B"""), TestUtils.hexDecode(""" -372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") +b9e56f9dfe73c5da4ec32b02af5fddebd5c84e216deae6a4f8611a876fa4993b9b333360ee00007dbb16bdacae8af597cc2d3a82359d8dca6582fbf9546b31867497b6cdf6f42ed3b09cfd094672218c40a24c8905ea468ba91c02c677a45abf5aa0421bf5bd398fad978fddc4634f6e9d36a03cb3d6eb64ee2c35f85481b1c4bed1b268de1483ddb4896a89bd9853c8f5beaee8b760c8202d17af8012a859f30c3023507d6bd8e41476174c2fb24fb1c944fc525b35c6e81d090c69713836e236b12106e02792ad51000aac32cea27d42c197e88f500ad336bc6feb4b79dbbd29a90c6e0f30011821357d111ec1cbb395212cad14b339a40fd9fce06bea1397369188c0d79e112f8c453605aaa3e28afb24730578eb8bc738d1c8e699fdf40438a16100e30d023b5d5be050a934d84d735a5650e2f599a52d36d1f9bdd91e46316bd62e774bcbeecdc7f43a89fa59241c12d2788ffa8e7277707c7df292da5141167d130aff17369c49d978add54af557dab19e746391c9f67157a58b4efc7463ac0615368006fb12c3554ecf35902e5752dfd7c34c97846547c3da9020ecd665487607c084ce909c2b7719acd1c3768ab6464c07c17e1329608afffe63a4ca07f6c9ceb74605c02772615de81364524121f8ffae29360d69f8900e5e9fb628e9ab0af8200fecff1ba1bd01fb6f1470a3771ef57d9b8e8103b3c2201d233de6e6602d490ba822b8eb4ec515c46b7b7dd0bf95cb7eed44573cfe11c168217e32961180d74e4f10463a5f38404540afbb48b21c878f1e7cecc13d664b03fddd6a33bb4d8c89023bc54602acc1cc434f5886906b5de13e89b5a414ba0f75d8253bbe031f2d82863e4e2f85f882a8a64ccc90a663ec9b6abd7edf2e8992f9aecb12a24acb52e0b05dee0803f521f833d0c0f238b06dd530c14bbe9a64a38198ce98a91f80358e6af37fa804710f043e7fb8cb5562f0c093d40c57f1b2c476520ab60782702d79423c64c874ea0ea0f4d9bbcf029b54b11bd114d50ffd80f38b21b4caeb54e9b83e0fd4551b7d56aa89ff0ea546433abc7e2b71a1a73897c803709a85b9f2c45996243445b089d8b3a75fce6decd0c42d622b52dedae2dbcc83181fa23a9d7b813127d58457f03b5e0cf4326188ed9bb894b9d468044897ed7397bfb6634808687937c8dc0d9883d9926d1cd63e0755ab868ab1de5a6d8cef72f72ce4e183d626605d6ceb6da8bb821161f3ad12eb124a1f09789b67f71a7b5819c3a285b7a8027d1cbef580779444dec21bf6509f27e7286c9d8274106cd3ad0baec6fc6f40fa3bd30a96c27d48280b8f051ce1679ea89a4981d270cf34eec5ca1ac399c422ff114232e68601d328f4a4c23ad3d52843c963b21f106f82eb38a379442b0ac389c59992c4326c9a54573b54ccdf1358389346df8c5d8c4064dd216f1d5e8f5ffe31205da0724de69187349a54b916fba25bbc4fc9b4518c57d5b715bbbfad14e50f8f48c81baa2246712b02cbc6f83cfb0e033ea90734495c9f82d185038a843a1f2d0a40666168a4df0b8e7c08973f64c4af66006109fe69a016242709877801e73319e1b2409825f9d827fccf2001b4dd0a4f455a92a58d13886f5ce9efe226dce7f3b4e817fb4f2185eb328c3b20192cb01901d5563b83fd7e13d0fbc3cde890cfccf91abfcf6c93a8c9ff31bfbe12a592e6337a0451983fedeecb6ed9ce67b6a3628fe15d9d6e8281097f8200fbd8742eb1138d3e6c70c1ed95c18d156bd9bb879610c28e5087097dd4a40a102a400b7ccea6babd3c419436024052a8a3c6c4233627d967a91bf700e10687a30316b67379fed8f4d208e27cd811cd27021abe8a295245f865655d2956d60d8564902fac029b65a337aabe99073b70162027995799552e779aca9ae9de29a458d6eec2f8d2fee0102786381b4ebe8707bcf9400c0241b83a4724f81e776b996c112226b8c7e1f5c1d090e9fa9b88c26445367935ff26c8d3c08a2347851a8f40b677b6fc5503a48f99782bf182a177fff9f28b5f2224b77454b545f018a131f8a9df7c61f35ac74edd7481a4bc18492cde936d5cefe03c96fe2f60be3edbe53d7b5d3f8b883523ac6235fb777f1d7a41906dbaa1727d1defeb67504a482beb8ac2ccd9261aeb746f422b5e9a11cc21ebd22dbea164c46e59b09bfb5213576955089ade4ba711d4f03646ae86df0c5495e0b5b5356d55628f40089d4d78ee33ba6f0f4080aae73fb20b47e979ad7dafda20c69925ce818ae62d2a534727d146d8bff6276eb02a52b2d56712da8cba1c0b48ed1f3e180d1bb4c365d6f14946b5f76147aeae4c55fd8be9d11b4633659df5a6a2e6dbcb56d32c7bbb88fd102e8515e959f322db8b6ddb21bad4a5c345d43f1b9a244a24578c75c626dbafc3f10e65e023783394a8357a6d5e005962af2e2f8fe8757a7cdc45823b50a0bcbbfcc6a46809d46ad639e918c97d1f038d7a3d9d87fb67ca95023d40793f96aa31c4bd3431d997746d305579495e41fd4d5b08cba5176924025bcdde3e36ff0c7b04b1b157021522d76e61ac37cd4fd8afb8c86609afd86a521f42b6e1892cf64cf278b02a7df422953e45c49cd07b9be6a0694e977d8e38b582c353442e850d488e26403f42fc2b533247eece1bf8dcc3808592ca51e100e71b50ea0714652f15c308b59d2b5936168acd227cf1a069e607fb6fe0fef48d582811106aaa4eb93ac836466319ba1597dd6a21ee2221bb0a6c068aca48b10a71ed42814a5273347e176c860845445c6f3e8dfd85ec2da37cb08fb2fba67bca6ecc5616e937e5f24464e22e4a699f27ca0aa321162bc5dcb799d4eba8f9725f9240dd2a10e1057e625f286bb999db6bad91f53c7abf54ef8e8a7741d5528f1adcff8783e69c535d79f279cd046373a012da01a3530d65c5aa3d0772e773dc7e692d0b8e17892e4808a24188c0bd48dea755b98a92ed4d8bc9046c81c9bd9800d8ebb100baa447a3432c4de07a68f666177230109c733be367d73c724a118fb665c858417512d91e993d83047622a9f5594a9e91467608b62c27bc07988be98187ee0ecaa7120d0ed54531fd9ccb17329b033b1b9c771c32a2bf99be223271c91feafc475656cdf78b4acd5226236cf50e9a4e79d7b4b4d9cfd14622a2638fd2c634acd4ee0b91977802ba013a98fffe5d6744d75d1a20a3cf3c851387d08c79d9b6b4dd418965eaff722b926c02f1a06563f0d963a2e6e99f10228152fd2a6bdd6468fe97955d4e81d0ad1f0ee301b1fe33c6935c3f5f8d4f7cef773550d32825b7ff05867c76e9797c71aafe5fd6da4767bf4f8c1a62ccf588521157c252c6d5431c5d4b1f15fe45ca0780989a9e99b7e1ef1d73cab9906a27f7d92609388d11b6381a9c21da36cd5245b2c9193dbc1c74e7967ef694a0e928720646b90a296dcedb5de5d90541641220e03e2abde8c2cec28ee3e7b04ef380dc913ba595c7c3352a5edde20b85c2d2a7525035e5f6db59d82a01768c7c1be0c57ca4eb389d958e0c96443e60fc6ff57a1e37c3bd0571215097fe26a87b835da2ea03c83fdf607ce72e5c76ec4a89e1378cc042bd70effa1e823f2129feb64e5ed7ed216c0d37fdf8d42a5320dcefecdeb28e99ec636f01973df6610767341da3233f1d2d50a7d922e93b14dd5d713049da206d3f31422f9f8d88014aa6091820525b50d1ba5e1f9d33f084bd2b5b65210c37f352cac249bfdd0c9d38d4d62e6c2bbe3541bd692721458b3743f902ca8ef6a150e8538d9dc348b704475d45ca3480bafe55265c578f3cdac8c0b0e281a6827687f391775f05979791d3e673b2cfb1bea5dcbb1cebec43a32b34b2e3ad97493c179abec83d02a249d52dd10edec00299704f0daf869d28c2bd29597215aced1e184d5e587caba773461499b46ed8c7a036ccb433982cb89af1a7e243a3466b1b2a9243770e427feee9dd64a96a3a8b526bd2df6ce6ce3425a59b7147c86997804cb109f862df5151e94a734020be056df7769e3f164de280bb45d7a5c43da8b8dccc48d4b4bd3400f31aa5c04a76e863fcf9c7d7e7eb04f5d769aa3cce83251a40e3e32f0d437ea9a279fdc21b4331286441faf0e0e18abcf11318b127daab6c8e2a8c2d67aebd6fac6139e5cf996ba502080dee6cb6fa55aed98f8e28211ee175702e9a16a2cdee3d08a7150881ba3b44f785ab768cc857bedecc1ab8f006a1377043f731ad801b23e6f18d6404c58c0d738cf5fad7cfa87cfe6446eceacf44ca811e1a48fdeefd940324c904fccfaf2a36b2bbb2c2383fb8c995051881a7e9d96327ee92ac43832f98932997069b21bb0868403c6c586f986949a43a42fc982d33b5039acff3d3dedd48ef05e61afbecc2d113de784925a101552d5084f05720230b6fcc357b63a72588317af5fbadeb229fd1221c5bc5f7a53efce19ac146d677027a87e0d49876e12830b43392f1f68069d5702699ea0321ac7ea78c18e64af520c333a8f3f591a1835d4b34b428abe29d1f0377c9305e0aca4f903e5127a397149d4be75369cd42135c7415d0298610572c6b95cffec5b0ae2fff70de6e12386db711ec9b676ec483be1cea8ddfa0df57bc60d2c8a76fc87d273c6ae4b724c4d8d3dfaaa11ae2da40f7990f8591adf689cf800ceda9ef2c8faa96de3290a3bedb2b73350846de4b754d3f7ef20c4defed3d9cb5afeaa6e1d686a3d16c4f1b2e65ed51b505dc3fcad64aea1c491338c4a33292088b60bfe491e1e6ff0314252cdd6767e983b53cd660dcaa4fe83bf0433edbc28b53a5efb2f5e6793ab1177f29be6cbe572619c7d191117a7bc4dad806dc102aff25067eb47a5bbb1d492f80d37c5968c2e40e9d600e7910ec77a0bafd7d8fd938ec3e0086d84926a75f9908392764c8dd8a76439f0adc99ffeb7af9d0966bad2b0a924184a5e9415c1abf791e15c700a69c0e7a62a854886797fa0d5c7a42519a6c887a23165808a608d9bc625f7775fe7635b537b5a35eb94eb5e81fd9a7c0b1c74b27d0af81938714761081411cb484ba7387c6c233bf7ce09091ab8673a3f10aac3f126cbb090f55336caabbe31d05695185635fc85d2ac59ed0066e51b023350083b2b2408ba874b19b98bd360c12885d64634d3c8c2f19f0feda4bcab389038ace498af6e2824c101fe5b069f6679044aed84ca5dd4dc2817b3c3e6fcd4e2f1874f6011ad05fe9e6a5b474b6c082e7ce64f3ec5d276074af695b6d3ec3b158a99d6de3f4237592abaf05a460ed2437e66a78fbabb0bacf03aecf9b96b3ea916d96db12d7cc6f8bbee54183459748a9c8837824d5f7c6015b564b146c255cbdf16ca894186566185574273344098aa03acdfcb8679387ed2c98dbacb6f2e6150306ea35f1bc05694110d83394fc1a7b4b93557a969131b70890933c530204ffc2371cdfddb7c6342a06d87c2229473654efb2b53f0826a349ee93d90fc4d4ad3e7e3ff8c16d74ebff6faea4b07dd5e88999bacdb1b51d8a9d9c0b5e5276153ac0483b96ca76dda17b931c526c7b5858bfa793c166bb680a44a0c0c66148f81177d8e9bcfdbfb64346c9179bf45390ac550db7af5d9a9b43bcc168ad29546e0b168cf9a5b44747a36b9c4e1f630c832883f9e6d10e2f89fc436de0c59f3b8e23ee0c156cc395de1c135a9de0e24568cac9c2911b21a0a9cff405a8ac222a3ffdc0d9ffc47aff2a3e89ddfdc6a8cf60cf28b3c7cae78b6bebea7bff5a8a47a3b707f24b8b6c4441718ef88108ccc26034ece28f80517991530273a5888eb1e36352d45e917b0283534830e914c5f083704e87e3c4c4f2205d99e1480d3ccc44f66a5dfb0607ec052a5a114c73d7bace17576b9345149325614c0076d7f044ab3f34482091be999a269a266f86a95d11baeb907e636f85fda7439cbe8d31839816ad20fa2fbac9b9ed2414a28d7e70cbcfa80f8e4e059ed003add7553056f7b94cdb4459f3ac54cc2c003fe60d6a44a7fb6fd0520c50f5c226a2bdae8b6e8eb7f18f94ee1b2692675f1b52c8da3141e5f859f7468b88e25a7d556fe1598137e893ba1c07ddd1af840e7f568db4b139f1d9f791451f76261f3948ba69354b16187cb77996848b629fade50a4d33e5760673e7b7466633f5426b17157e7165933de8547163903aa002df55a20a1a90a5c7c93c25bfb53f3f57e0045dbca341b9f14fbe2710532947e3e1bbf9d98a2f46bc526db5455189fd359f4a9c52dd5e5350650b010cc58b6ba0d5d11bebcd9b6e512d3c2faa728456b7053485f24fb351de898dae7893f08aa5509f808e6d0cf2b3bc46d3a9d3fb73633de694a0ec1d73dcd22e818b61558be653590663c3c66cf008ce3f74f0cdb241a9b54d59e426ec1a0436ed7e7fef471fc927432c09c8a65591531726723e0a46527cbd28527ca0bde9165860839dfa2e405b71728a8d96a1c3eaf516327895fd14476265777e828792a4b2f230638790afdc0312214448b1bac8000000000000000000000000000000050b111d222e343c""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +846d5071be9f3c8a2a99cb9490b9aa8c794e568b4c2da75439df54fb42f6182850b620d6efd426e4a843d6d7ec259d33a3631f45f153b2c1ac14fe1579c5aed8566f5ad80eade4ee8290e3f2cedc98290c92b83f94e0ad6910163f734ebe5f92bf6fb3ab56e03725a86593c35a9f7fc5bb99664beb330b3cab837772dc2ca1fef7747589758898d62e0c53373097fb2b2321f8f8c397d2631c4d0900e9ff7d5a8e3fcb453034e1c70f3bc4451c649cbb31989b8b0a2d3e33b9f138458c5eb2fa76a2b27f9aa34841e8c108daa5ccb0ba3847d2847055bd1553a467e8554ab3c54c0cdcc439ba7ea6a39795d7008239599f09d5c7060410a8a12301dd5e68f65865b7cb636d7cdda135436615bca0a20d982274551e549373f43c435729c98147f87bd0b344411750da35ffe77b73d9d429bafd7f2c7d6f43fb6a00afe8492f45c0be3431db3aea58e945303c5d1d4d4672727848d72e32bf2f7143e2de29e3c00678b64a7a9c275322f1039ea4f751e4b5fbead29b85a823bce1d4c0d1cff1a5084f252b10d8281764c1ee8aff68ababc78567c759095fb64425d4ff00a5491ae6812658478e8b062742442bbdff9ac8e288af8f2a64087c2dda5c116edebe039135c5ed850c190ff60cdcc64a10b3a849a028e0c66420f7643e98aab79dee9d943ce7438e82705dd1d7a8f7c45cfe442ecf3f7b474f0aaaf1891f857351a2438f2d688384ddd33f0821167189edf67908c0f9ab6dc928fb6e0f69ac40363ccc7eb1bba1c38726eaaeddd350f3a5b077800c2f0557f9bb1f116f0256f99ae103bed8e8250f2f1ae4c01dfae76aac4f4025fe9897ebd7baca7a74ef7d6eda19e80c5701c1dc995f0de8c15d7767c11c572d4c5c4af1f8155d8ae1e196f83035d5fd89f2b6e4893d5df8b16b70a36a674892f393cf4f83168c3b12e428e1ee2a16770ee7d4c2bca95763a0ca91452c5643835196ae0c00d6bbb8ba6a76ebbd198577cfafa536b71c8b837f2b501ec08be9470bccb69925b625876812e02254b17ec5a7a7f2aa2f32707bb84831775a8e49ae31d82b006e76bf4c4e965ed437f5298b985248261df1e657b6fdc51f7340be6a56d3d358667f9df996bf97fd6fb4c7870565f49788e600e9e54fcd8c3a487523c6ba49a2d5f0afa819b01f00ca75b846c0f398df771b34e253db4e6f7748c4630b1d32e047b7686bc201ce3e850faeffff7a2a5efc3433a6e5a386fbd8204c18243cc582e9f3ce606be436b0f957ad73dc7cd65b3dd0c0b336556e4d9247cb041aa33ac5e7d8080883b0e7359b7128ff0c6ba39d6f392cb1f7371e4c496bee32f0785eb0134f74ad9bf244a6ef9f1cd67175795b9a965b6316fc008c1c02415a20f44713724e1c9a644a6b5d1150e31cd54c29368afaf2293f7c2ff68906cf99f5d32fea44b7c4ef08f627ff91627f8a0a2d828803e6af4b93905125640a32409fef71e00837a9d89e776b88d50e2c0415534223af6c950bc2a2e8a7cf852bbd21a0f2f20cd03a9fb7e8214df84a3dad03a3345dc44a1d15eaee127f50ed2588269f1c6cf55157b9f96239607cfddbcf55bcf1d24ecd3953e20a54a073ff3749c8882595decd36d8b0fdfd0571807e233208b34324c244a2887adfe1cb5daf8b79440a44a019c872813ac2dce13fef6e58ac58987241ece2a3299024b7adbdc89120d88823e1bc8cb8ce2217b443770e411ea969459c8c56e40346b2899db2abb764cfdfe82c7dbc1ae868baf4bfce840f68826e41e627df189910a780598cff166be972117b5c61c02dcede2d298acc8eab96ee718cbf4614d1bbd93d8f231dc6d18e4d8f4b396b5474e70c229e6219c3af9b41b83bb5525c1ea4f415fd06da7787a9d9d318c298446071e13971f7c742f3ff61d86bbb9a2347e0608fa335f006db2a618b43c2225ccffd8e34d924f8dc60bb1e34c1822bf1860a64df7b8a8c0d09e78a3fa17587d50aac69a6eeac1204a23fd3c4d7f02635988fe5555ee85a247c2bf6e952346b8ec11e76149e672a8be470132a010c73ce62171da95cc84bc086070d13eedc88840540f81d2980fea2cbfa94e5255e475c51732fa82c7a8795df3421ee7e55d391cce70e7daf7a80766a84d23063f93f75119a70bfb8086d41fe9b2840b4a48f0157f6a0382da9c332971d99805f2af01941b654cccafdfd95818131373b3746c00cb663cda6592e913558e61eef2eb5a2bcf2936f86ac5ab935d525fb0202b116e4ef0ea063643c7b58a172923aa8b312ab64be7ab8dcb04dbb35136d7d7a15d9b77ab3fd6ea1d45fe3b8c9f7286456d33f2cdd48c5f777769e570ac0d7ae56543ee4b0c6997041e0c67d82cd21b8b6d6f4399a7372f95ea0b580254704cef65e8d4bfb2ae556cabbc26f513e02c2be2cd9b1352b925dda37310d72df63436289bfbcaeaaeccb84a34ca75552f7b545e97c75add87bc3b93c8c7cb01f0fd813dd47eff1e40ae3e230c203b7d982cd29fd22f2b8548b98699e706155539b05d052c7ffb3150abcb5d990c9171db4f88ee7e42cf56d10eba0cd08c17ae14a7b41da377121902564c2088e647bac379e062b04643acf9d07750d3b95f7132e41434d4e3bb73ce29267761fe66866db875ad5d798c10bd14cb7c382132f19b577f3c24b1994b97bf488a3b3075a1c20c4447618694bc25b4f92283819a6a445fe7b3b389dfc74a544dc26a3429502601d19c38fc7cfdcf5d0aff6c28264cef679daa32d0bd0b80532d02478c09514118d9ef3aa3b093983c1f800d048454c7ab27a8220fc00a4285785230e7b97c415eb2cdc2c98131fb49ad4a7fd96d51b6077ec872cc95935aeb42da23e5e23342d0c5459603cb948d2426f68be756ed544a300474b4de646841b6ebdf4ee27e80d6820212335093eb29a5224ccec99af8cc84c65ab1b648f24aaa48be9c9fdb91dfa44e071a69f127e2206a00171513404f051a829271380a1d0eb14493fbc9ad99a205a2b76049489bce56af1946873a0900ac6294c11acd40a026abfc366198786eea707d5c97cb1bff25471125295d3e3ef6cf9ef7913a71204d162e00a614286c06325439d45ea06fe03e07d97566cf100b7e24ae606ebb7681679003517be905e7faa97a4ec9e57b97793d91b998be6c4d78b72b37dedf10620d57702445655b36476e893b3e212c0dc0b12c1a84b163189f008217945b60108d058029df8affb251756001ce79d5d8b917b20c4cc246548011824ea921d376ec7edb15e35d5e5d66646714244e228bc2f7956291a38f2f36da55f1a2134ede281026b32ed374c6023259c43e85437bc3938a869f6d5df3a50df8f2fc70622e1671a4ea290e36be376a99c681b517aa68bef04a252a4dca9dc19ce11e8a75c8a9f4146d670771855418b2c19a861e4bae7e73587a4aa9036a7d99a261ee745a03a32e5a13008c9b81d0837006beea487668296c8b683c98a44f5c155ee35277a4b97e7beaf690a21c5cb208cfc53d3c7949922cdfe18493efcb1426e8bc5707aa7282ca81b00e9d3d86d33d3b6b3364abaae0d25ff027d471b03abef975e27df7d8aa2ce5f657e2f9e120ad97a6280836754f16e86cce203c1246cffed258b0ce9c1848e05720663034019c43b2a43e25cbe96ab2fc8c7b58485f9bb105f"""), TestUtils.hexDecode(""" -EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), +B5CD00AE06396DEB95C9BE213BEA279AF0D10F1423B5A71854413E99F7216D9EAE76C8AB884545496559B14AC9A69801EE3FD2EEECCC557D7988F34B82D244461388C7D4EB16DAC3C0FCE0783321A1488DC16C3C688126754BB4C26308054545D2E46C6BEE26C25A7C3B701341A0323BEBFC50C718162B7FF3B6FAAE7156FE300F2219655D8D44DE89845393011A2B466233B907355467EC49C9F832044BDFCFCF722D6DE7946FA503861C80037549ECE8FFF95026CDA33C9000FACC334765A60456084A0614455C83E0D5D991F7ED43952B7A69F1E326D7BD33822CF1F286D85FAE78F0B8DE186368EB334CA56070122DEBBEB920C5547C46C1291E78AE48B72C7A39020A1A2E54E59A2E46606C99E652FADB39AAB25399B0830AE733FDFD973294B93F47C30D0824686C735E05FF51A95C1C76467A4BE6BA80C5182353BD510E8D4B60BD43436F7021B3F5980D1A769B2E3BF04E0C257EF577828B327E2AD85E0581787B9B7FE44D6B826BF8405D3D0BF8974D2B1C569006C7FC3D2891DAF38DAC36F64A256E337B660CA59D2B45F1B4AA1C0C72B78495FBCC9EE9CFFA4B5A101F973E3211E728040904B0B2515DA4B1CB3774EBEA1324EB6907324E733C7F17BEF6FAD0F6BCEC1F08F785DC6FFE02FFED5C0B7A631907196835EFFD0730FC8FE020B0545C920DD7B2D705F22D8D205804397F6FCC60386F4A576204949EF60DEAB269905707396CCCD8DA9B895270CB39839BFD3EE64149B0085B96FEDAAF8C738E449E585ADBA037BD560EAAE978A6ED61DF432B6A9C2E50C2EA33A8702A23E6848401F85E2C18C7C767DB15920C9B3B030728FD9511F8903DFC8572A3679F986CA1B684B3AAF489DCD93C622C6C4D475DD60F10C390873B09B5A352B6F5A104C90782E053F8121317EB8D1D4C0145E04E3B68446B69A0EF81097CC6BD0B756AF78963724D9C83C61B7B79647F0844867B605E2B60988D2D7AD07CD6BE2D8F904F0D269187C141AC67C9DCF9961BBFFDDF3BF34D9CC5781D1BEA348F49EA8FF7750F7F3E0624C16FAEFAF1D8B6A818AF5FC5C04E2504A0CF4C2DB54930EFA759A292A2AECA1EC3A08918513D95C44BD133657FF043318A17BE4A5DCAC54B87FF38869D017A4B14DEB60480AF1C5F19A9F87B94B8EFE0DF3F931CFADFFD7AA50AC86D9CAF6D434CC81E6ED123711E34B8295A446B554F6DD5350B44C614324D8727F1CE501743043DE6EA085DB5154AD8E30E114A02CDFC96BEB4F2718033B227CB8638BCF617C73BA4473851E62C8A287CC4F9C659190E60AEC468DE7EA8841E3CEF893F3DC79DDDD56B63102EAA5B2793711A0451EE1655C6768393F59CA6085866FB41541D9997C94BB56F6ED5D731585E7B25B1DC853830DE5DD75F66298BDBD2E505DCB3850F96CCE0D7274633234EE2FA1E2782DA3D6CD8F5DA2C3063A923DCB6A2F82614527CA2A88C1AF21025B88A08C3104C679175DE2CF00602B13E58FAC9376BECAE56A60A6A8F144F1C98C8FBDCDE6FBCA4ED13228FA77CBA5CE631BCDB368AD9219568777FB4397BB40485A9AB63E9E3FB343154108D8117CE25BEA30BC854A241745FC6C26AF0D64124AF10BE4BE01B8A3D842FD9CC4D805B2BE26F8B7BA0631443F48C7F74207F640B215E0DDC42B1954A1EAB2C68E63601DE3AE3EA54E16282BDED00FC7665A9E8B098BF034F5E950ECDC46CDD22210244F102E41E0930FDCB24AD6C72507E5AB6FCCD4D6B2A2703C358EC1B51AC87302A5F507BD01CA6B5FE04EA2A5322EDFAE8161965524C61956CD201C4BF2F01B54F008F5F4B6770D0622099CDBF94D6C41DAB4A5362D630B9BF9CE240ED08D698D1AABF29E60BA533697C3C830521314F13EECD95C7D2600E2A756AF19AD94D9EA39FEEF0E3EAB3EB401225C2E55B2F2A8D7D1A3AA77A38BF9BA31399F6E6458F3F21DE354BBECC2E29740FFF91FBB23E0F61D7E0698CBF82D439AFB018DC5F5011B7BE98993E8B655D83C666FC0CF84A532C7655365746FDB97874D62329B1EFDB0B0C8A46056A85B60E38AF8979FA4910D2D9CACC3B5C1E42049D04C44273953350E0F756081D2DF6429193768802577C381897BFE540BC036293643360C848A1AE388CD17781296A99AF0CF75F81D568D0648C8A15436BDCB16FD83287C6A54F88F2F75E6B28E1C5A3AC03501D6D723AC5EBF90517D194A596F7F95947CC169CFF2A65D2BC9B54CA6AA45BA9E901D4AAC81FFE9E62A479EEC5B3F9BFF24C69FF56EC52F1183B5AC48A5BAA90BF595990B6EBA5B1CB6D88511C7D0D165FDF2615351B0343918B966ED1CA0CEBF6956BD2CA599E18619E1A5930E47CAEA92B8E9647A0262A2B24E955040750E6C7B935982CB742EE756DB65B462F677AE09A7521B0D3A42C2E97890C47148618FA6089975F5D491F4D3F69EBCD54C2B53130698A1F4A47505194F675D68F2DDF5983B008E498AB4A25956CF724F5C1250D5F9C75F3DF9BAA696E300AA86FB4B9378EE18E79D015CDA55D6ABBF5B0BE819F9EE58B49656D3B112AD8FA6651A8905061A8E37760C3F2EBE6DA611BADD44268975B5000051BDF7158EE3DC200B47FBF8568C9F22719FBEFE5906444DE9300689BFA1AD167"""), TestUtils.hexDecode(""" -A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") +fca242816e6b98578837b5592bcd66732c06ac3794932640ca3b71112407c8a4c0989723966ef76b5409a893b8c2981d6b72a1f5cd92d81c12b9cccfc75547f44c27a56431f324a4f73ce4f91da398fdbe6a97ce171f4483fd0c1cbab53fb80c41963798eb10dc422ea82719a0770ba82e1491512bc40d726b83b3cc1887b5648204b00e8231a654b4a796d7c1c0304e93579ae6ba4f0945afcc0812b86cb8872842ee8782ede142087a46dccc78275aa2e52f2e9344a81c4a0ee65d4a9b8ce1ad020ef6fd1e6cbdf8d5e56b1751e67be662b90fba01a983df891eb2eef4886a1da0b6bc0cedc4b44f33df8ad946b68e5389104b46e213690ebad5b50fef7dbf2aa6f51b125657e779d9718244aaeaa55ad0bbacdb76dc66973e331be8aa3e6a13dad7d227121e5fd1edffdaadc6bb667e40d49c1d95c6db663b4cf374a3b93e5f270139c28e98fee799a3ea015ceaafb881807058b199dcf0b447f46d263bd43d02cf232ad1c27c3ca8e0cfc1c07541aece1980c9240e77b9f134694be94bbf05eb6710797a2ea2436cd6c10b18a260bdef24530eafc2618d17f86922e91c9fefe7528de98bcfca9194e53affc13da5787124dfdaa0e95f3924fcf6fdbca78a61aed2b5125c6b94733eab6a215856185ab31106fb293d996c9a8e80f9bd1bb2287a88df24f7f127c371d5c8503622b3986206acd99395bed7633e5f73a918a45362d58c921362053a0d2133a1989516cbb8bc29dd2fdae2dbb94669a122e81ddeec46fd04ba600d149cd728285f2836a3023521ab1362736a8d33635a6fceaf6f9684af304a557225e4a80ca403583b637c4db7e9185df6bb77dbb3b09ff915400bca75a645a8ebe36b99948369cad683c56f0030f4f8b8f6610d20c7662f538c855bd1d08b719df8b34873c4dfed8046372063ef58800ee7abd99ba66b60098e0004395c2646ffb158411526dede3d9c9e1b481a2dc5298f27538c6ed535fd0e7374ebf2ebf214eb14bc3c674f61c1baddef4435344ddbb08d6fc8240ff5e41b817e9795670f399965cee0d8a4540b795580ceeea3a31c61c81e3613331f21b496e8dc833ff7494f50e81f0366718622602759d598f1831042a5779ffa9ada2a00c79b0419ecb05d3ceed113160653bb7db0d06a40fd272afcf7f20fa18dcef490387b84dff70e761dd1bbec5e1b25eb30fe2c4d18135b3c5f315da29a98855f81f9b1e01450557ce6fde5b2471dfc90da07207a6f6d181cd71e33af713c0dc353f7166bd6aa7b90f82eba2c03423144fd12883e80538de76f02a0e12cc65051b981eff9d25a36ff79b4c6c84ea537075886e9be23f700570e43e76e8d61f54b49a576a99a57b464f2be6dc8c993c78a1330ff3580138964a6cc2cd46006ee1a72a268ababe373646674dfb4bf33126fbb8f5dd24f4c79596c783fc88b393a75355ccaaaf698a45d678b01f175bb31bf7d28bd44a766a60dd8d2510f55bed7fed53f6718578fde622c49d17fa64926be1a084dbdff206c025ff726ddd2adeea11a021680f3e75b865bc364dd7d752d3b62b7b240838c5645f5338326897e751e968fca1b99c0baec1c9fb227d6f1fe61abddbe26613e5abdf6bac54d658b22cbf8cd498114019f712027aac6e7b1fab7016aa96ff61bde12a44d540e33c30bcec417f11fec1a0536f61eeba565d4faf3b624eb1205143e3b6e6d22b8a0ab3767739206a89eab990bef3f3d763a816cba5aba2b2d8390235a197362382c2487d80f9f47f0714206b1aa9f40840098c6f94d920fe21950274f7ca9d22a506a76a328cb28a50ba569909897b15ac2964a111ce48ffe137d86c5aac313050e25f43b9c041c93dac0293a8694f76845a7a83b8e14db7fb2a724df1f4e64a772e6c3078e465565e1eacd56c0c4f13a3a90b53bcaa0451b44ee94be4d6d23707057b4eaa6879203ba81ea953090eb450408eb6a9dab8c5bca27c87cc302f286e703be7022044e0ac4559d4e861f4e31f8915831cc9b81dbe937c8b0abc02b61c57debcfd0f5f8ab3d7bf0b05a5eb7fb0bb587de8c2bdc41299e744db3c6f92aaae2008a14f965023f17ea55fb0a5ec6c884c478cb3a95722844dd823be55f15a363354634a1b3171e349ad6c69f1342bb3dcbf0cb44efaa6d06932e064311057a97fccbb1430aff5509d0f34aa57a7cebcd5eb5e9fd373960065c79f52a414d16ce959c97c1fe0101e4bea038dc6b27ee847335073f62a91d1d74ebcdab4965e1cc501c07cf4a6050c406028f6250d24796fd4736144ff84616a63a2136fe4b8ac9652d95965659d55b67355f5de40f6f11e08fbfbc2ef005b3937204345e03c07e67803a8c378368a7cea377f53318bb140e0760bf79fae16f4132bbc88d8af335c07496fdff21e36ca375889ed56faf2622377126d399fd76ef9b2746e1ab666461a949c06727d1ed191e197418ab7574bfe292b92ca61e7972e4d0fbc6001dfc5438f95b54c9f226bda6968fe5e5df06e915fbb58c6123799f6c8624a40b18542c18cf82b89b606ba532584b1542f0b0684be46457fd6f295f0a3e79ab8634b8fd747d5bb87ac0b33902804f691c16874f881a3acc4b1f88183dfc3defe276968bf7f7ed53e59e2e5fc0db0f13dbc772286f6d83cbd47617bd067035c93259ba9daad2f229835f7c9ce8759109bd1db0e71b9d015c55ea94325cae586fb1b50f4792bc4c57569c83c26ba4cd7a809e799b5a45961ffa5387f91d9d653fe2cef5783312e12fb695a1b9d2004bf5d73819dfb406a7d3243613356b851370fa34bc32aec270984c77cb373cbf6c65d1774ef95539d4b4142d50f3cdfc9695e96cd1a0a3844ff8507ece66c2ea7bf27bdf020ea8fa95c6a7cd0dcf37a591f2cdf7a6d7a04de5a89583a094a53f68636bb57fc83968ceb47a53d37aa7099c76633e23b5eb1b828d2efa427fde9cfa24df7518886af10ed7734aa278bec197a60dd8279df60fd5012852167e9038ffd1388f6753af0b75800aec92ccdc0feb08684c28d51ad1ba8a14b33eb0a13ed08020f8416c9817a63dae74a2ad51bd9c9db0c187ba1df3deda995727ee0e8d78c9a3d70d2bbaf759fbde9226646a412500865e2391189e46a671f7a9b2281509c412e5ae2cd89ef17a42414fdaa90d12e39b07ed4744217e4a461a48aab8e427eb7cd1d07cae97886ca0f4b8d2c88c397c96436b0540aad3e6962c78914b3ad092b1a46cd1aea2cadf236c9d0d1e7669bb3035bf8354ccfe5ca70e7e6e6acea47396800a8407017d64c4199cf13155bdf44b06e01b92628836712d34e2ce4c8d635cdf1c3ce21b7a2ff1268c9ee9df0792b79d35e466242f25209bcda6f68f07d80db030e244c479c66cfe823220075e9c08c2f8406ef7a5600677f4a0673b0b5bac9d5e388dda323cf3e2d967cc0b3a705a456cd194c1833855af620952dfa2fd1f147d6a58ac35231377956e4b91ac100e3f9d8b966db4861ca45ccaccc6ea63b0d2d71d4367bfc0911e106ce7cd73f31887536754c880b54b5a6abcd3913c505c2145fbed44a23dd7b04280410cd648b59e7ae00b10099ce56a3d615f031f9091ff00c2248ce6cff217fac3158aef781b88603ce37e9aeb4efabafdd59f0a460859b1f1a1b4369043869a27cbde6a8914d1d3d88e440927af82083950eeb3bab126e9507c8baadc1fe98353f01022df09d8848142ccb7429a5b4a7669c1008d61ac50d6373b258f8afee8d830990853b9cd18b869544bff788f5cef93a9e3debae6afb138bce6ecdd9b071dffb5d629e0fc544bd909bb7bbeb3597d0a285e447eb49f7ddadb510dcad32807d3d0a571a731069e22aab4e730f50e295357813cd46ac3f34c4fe2d5029fc19a772f7e647cb18635fabe67f1588b18a7cd0ebcb6994cf4334316f6a538370887a0f009adf3348257fe9668b7d784ea64e8e9931fba22bf2f673b222196eb5df852ae2715b58cb9b737583c4b8c1003178093fc288736c246fa0357daa68e89150cf7876928b9525a264625991fc403b1b5edcf4f9a58a570925044c669a3f1960c06f35a21b826603086e7e889adae25db3eff02f990af85efb01e1bcfce2eb1520d2846c5de1ad3caa65c968dbcd8af5b925a13871f19524f1db6c914827c818d76b1e05df95ba322ed03061eab164cd501545d3b4ad2c4f9b5d7abe1dfd3d92a422a114ef56a4b2b47d31f5df38fa7e3853ba5b1c1e9e955dd4a294119c3c314fbe4ae14362a6522e34b7fd467d22aef1a31bc8bfda12025701df52ebe6fcc52c1fcfb8ff94d62d2a7b0f1b8db243391320e7fdcc0ec40576caedd0f327c5a0a950ddb2994fc389fa77e54f569217f4139b91e545432cb7ed0d11e1d27e9c4536a9012509d9043557051c01911393c592f36a4f162f131af522f978e940774aebc0b672fe88c590ea572f39dd5c87828d3d9d16e78b9433e54da904418c5ab6e8db7851f4807d4c93c60503ceecd837bc068aad6813206e382e84b6e64510f64f1346b9fad25c37d77be5292f1fd9d5463c640baa331ccd636e7485b752db11ebdebefab0cd9d8b9ae11f724439525661fbce8341badfc03ec2375536876a954a0c553e274027f9f53582bfb7d20520e1b8ea9322fe0abc9179711768bb2e78554eaa5b0be9023e6acd94f5eaa7b74a98adafcfac88fb21d810feb9f38dbc0c8cc006618c771c31fc82aeffd693497bbbcdfba2028cbc73e49ce074f425ca33585c891bde72455606aaa252ed42e2edc7ad7aefbd9ede2a51217f2c6e1ac300f6868cb8d0fb6bb5ebcdab839d4f63255b7079ad483a6fb383c4f0acb7128c500da9fcf7ce9e28068f265d3e266dfeca0e808c0cf8e98de0f61fe495eb160888df53bd872bdd9a7b8c89ba1a5517ae69c2b49753dce1fa1c215d6c1efca5d241cab5229ca657d28a57d34aa16c6fbd829b0aabb4099e472b922387022885de324ca45a8eb9245ad53923beec04f245e4fc6147895e7e0fcd457a3786db95174d8480701e2d659a2131d89ac98c627357851bf57dace645a1d00b3636c45374a5c2229b002a0ad8c9aa148fb6521fe35dc4ed09e3e0d5cc6bcda45925ef6f5df442f1ec4da7583f63bb2381fce6a7a9da4fb79d0ccaf2a4bdceb6cfe584a33b9cdfd6c9f3c4a8b71d4b3da17f174d6fb3b8c48a6a6f6cb78289f3f217bb377d7d210845e09ba7543fae4de9d397bc76b3a46bd7aa47a93a891775898cf4e865c5587746b353ddf1edbd0b6384512e558a9f346ceb265cc3c4d7d37ff83e6f60899f3768c495f49919ae6e80aeba85c4cd34b7d90d311f03a1f4356188df30d402031b916530e0e9da31b17ce87537f0b0b8d918fdabe536ae6bb6b903173f834921f5c998b39dc5cbb74a7ef677d72aa4cbe88a8823a8a0efc7de88713ea127c7e8fd10bfeff3e19334c7fecef45876f89a6800de74276920fcb6c248263b850b5c7a945e1a3a5129e774309c606f6585d037c15e5f824dab8fb74a9cfd49b659c98fb1c66c2484761cbed75343db437eab18ed7b56e5a3c0cc150ea98447c3b5c08c9f9d1801bd6b6ba15fc3be608aacb92c4abe8f3f506e75714b6876f5b2ec036a1456627e567c6e488cb6ace2cf54e42ddd41b6810bc93f83270b40fdbb79be84ce8e60cf527a1d04f89f22c4b936353015a8e05c23799cfbfc7fa58405c07ced8fc16d50004e364a6db3d3d11afec9f6f6037bb7061ae0b0f4f4ba3157728d24f819a3d12e237421a22c0efd8ae99651437bfa486c033e833e360935dd433a1d5aeafef73c71b5326b65d6df9994f988d00a03898d2354f58e3308b3c73b149c8a2b0165309d64ffe190a4bbf89a8633f30d674d73b1910811951b25aef8313e510cebc2f8e4a5c4286e2dd4db0dcb40b1745358f511c29645a0cae474954fbd907345b30203a32ed6848f10b5489f58914397046796e143bd412a2ea5feaa811e0a7ac8a756ce752d75eab8b6606d8d3da0900d621fb42b90e94e3aad05e0c42f9daed64af510f4846a4f66b1782d9d76dce9ac84fa2912808851c9bd23656465a64c5fa582e7bd1fed8c38e7200b601d0504f2578497be90818e69d1dae9a86fb5c2772e891d699f002bb4d579d3023df87651ec9dbb06ee3bd4a9ced0451a1c5e0a658712d704a92c2bf21527417278c8c105671e68b06aa838ead92c6a8566ee5912a18b995e9d1b6f9978fb6e378eb0924143da6fa15198686b8f5620b607e25e0540827f3454ca9dd085adc6e2c10763a20d6c70c5bfe0bb1d1b773bd267ce33a2b9c08a04a254d9c844475cc013c4276f947ceacad1c31976898d198c91e5ebf2623ba825e762665caedf1674775d15310972ddded3c75178dc3fb715d75ed071a292040223fcddf82a3e29af547a18633434534b15bc10334bd1c8504e210b104100c3a4e596573b2c8f11c304eb88ebebfcad0df1b2f5361676f899eddf0233b5d6f80828410172c36397f9495aff2001f4667a209394a585f607bb8e0000000000000000000000000000000090d131d242e333c""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +a163f0cce9b86d8807e6ed09b486e1aa12807f2370f2cb6d886eb2ba3978ee84b7929d54580b5a86b0b7c29360399d37ac01374ee32107c9a97d857a7cdde38bfdd98150c2cedc2f10221a9061eda3b576958b8350cb89e27d4a3c30fff090a550643bdd0075da1b9831f971256805f102a6d59bb803b3201eb312924efda3e379f7b6130da6814c91529c23031ac3909d0e02e2110ad1f9d56abe22a1d359ae7db28ed5b6adfebf17055803967a1127d771f4c9adee662dbb277862240e03f2fcb6915fc99436775c91fdfd84151cf571a728cce6c4055ad18bb9ec10e39e6b3c7094ed3db3193256926a102cc94d2567a37f665dcf052e20863e9f8fc66b56bd471168681fef3ec42b641ec2eac3f42f99f702da13d9aade502e04e41cd57d5b05cde8861406b99e12e37a482014dec0cb4a6b90d97d5ed10153a23a86093105e27da2d7f3f34736f1613c4e86dec37597a85460c104508a5fe555bb77e951eddab081f9cbac0487c76dbe00eaf1c1ad87c06a4d7572c57037e94eb60be1ee07fa39b343335b16cf487f327bcb731f1592db0ea833121b21c2712374aa0fce26d676ef67ebbeb3f220e4c5caed17aadd42f09cef9b2fb7d5b5a6dd983eaf15312bb69186607bb3144dace7e4a603d3f82b7394ccfe67d555057e822c86e68b6ce0f18c218fc5a0145eed4c32a792c3cc8c9a56b6cb5b80fa444314470d72d6d84bed3db7328153899cdc04c2b753285fc44e3eab5d74e77977db248fb774166086bd37856f0be4cc7a0503a901443ae965b183dd75205d8dc86349b38d1b58ca7b8415a5f3ce70fc6fba330cb5b22067ff75cf074d91fc57cd95e74633ae348eb89efdeecb6e2f40cebf31122e0ba834cd30a35cf52478bb9e6a2c7b880a88f76ecc534d928d75f59be681a181d22fa5661a7d58cc9748eaf8d789c1a5741b2ab91219cada5047d815714c1e66e476dab23af40c1275408f3cbf8c8d7e591e571885f64c6548a066eaac99b9f92ed7c5abc4267fa926e961deb28a98fe0492085706aaf4810518bdf965ac32c6666b59eee893e773febcbe5de8db551f409593600659428be7b23951359d5394875f00c31fa7b707929550dbd62fd2696a193c49687f872936907feb2bbde12b3fd874a4e9d72d2765508f9ce08d9fbc2964c9abc93e83556a51f1e446d9b92a2834e316c822fa5f361d44c05948740ecf776794e453ca7057465e20e6819d617c8d0e245d2588e15c71e7a7ddd5cf3613f35da272c437bc8c334d6f9fd186d31cbb9de5a9f739258d44497086deb7e564a0c95d6a5431f31d470a1f872b20bad7af0a8b03c01cdf71567324efa383eba0e1f15f8474bb4e205f6e89f9a85d66eb57c6d9be0e50a958dd4b587ae9b4c3c7899d5bbf7d4d2945598bce9111ae4bede064d57f151fa171736719e0fd27625ecd15fc8b46e06477fc9c8f29c01874eefa8f7bc964ae223ff1e9c98814c01f5ec513509447cdabbc73cf7b96d06166e5524d2d433315c4d4f2e9d709fe0f78e88603336d47c7e301aa91a3fe1dab1eeddefaef17ac096017069e2ef40e3bc17035b80709142d8eed4c34637f41c4045ebedc268f6fb20c339dc5a5e89584722a4a156c26b04ea424426d70580bbfd9a2e095e5aa0ebad35c825d19df64557826f0c5c455107a5c06644afc4ad1115c1a08764d3af872ed3487a2e40e894c1515b16c953d07dc01ea9f2a54b2f2502661260e64b9a58c5000d4adede0347eb75c6af9add72e595fcac36ee0a08d7cd2da6e0bb3a3023b772c5535c3a8e6ccd52b3aed80a1f50a86906eac6a552ba07a8c7b16eb17b62f63f423dec086262bbe90736a47e4d5501682c5147c03d06a8060166790ed0673c2eb8bf54e890c579b2fa77a863411467a09a7673f5234c5213321ccada607a58a55229f8953159d3b67688305268c2a7c799a619a7d3fa69d4ca86969d428033b5adf318db78818f136f651f2696cc3aff43c3012fc1781aacf3de7973b165655f98ac9e7d5158a4edd4cc4b33064bba97b57f30908630624c13dce7627823b9708df52389bc4f1742d86b244f74d48dfe67b2076723294eab5cfc8539c21401480bcb1e745c1fe803e6e1fccbc0dab6273abf1e2f27155534f6b9a2d06aa82a7a7aadd1fc574f42214f3442422e12d3bbf7b2857fdfb8bfe4398b16be9a225f94934615461fd9a430db0c5e50c25beb3e3341e91dea7e8b3f2b05c25af2c1e63448fe311115758432cb09d8330d28398d9cb360eda112c245144742b733f524e8e7368acf8c48c1c1a3641822ff56388f0db4f3988cec2888bdee3d67a75bbf0ae0e6661582c7975e9a05d3b7b50c86359aa4240573cf27d7a6011cd295d3edf1bd0162290c0ea094546dd36d470c63166fcb4950a96f7272cc0b05144ff5d6342a27523787af5f23dd985720e1a8bad426f6dbf2c5f42178d8a71b7f473a0c9dbe278a0ec837da78b9cbe74b230db8a4079b2cc2c49539f78d55a1253995a2a822c7711f46c1cfd379ed523fda80ea91af7c5d872a5b6119cb70cda9bdc3fa8c4a83531c71f5da27ce6d876fe653e2e808eeb7209eeaf4b492c09d47385763775902afb05ab939f6406d582442ac3bf1113f172601c168b1407f701799d16b56c82da29ae0067d6c7f48c2b4a6b34d53fabc300ae7f55ef5f7094e403df40731538204b47f8fdf28f855722263e3c3f058f53e585275dd8cc5457003d60fdf32dc3703696c23fabad72cd64dfe195f2a5a3a54bb5c8e39443fc1c621fa1c140b5291617974f6f2600f47420b3332208c1f39f6155bb0c2502bcc942278ed27434077046d7a9d393ea87ac2990b9f3c7aaaa3107f40614a1fcb5711151f85f595018e48234d567814674aa0ed81a3a1b597d8c410124cec8a45cffc4acfc8a9429ed52008fe6fcedaa856b5001ce12da270aa7b7adf5c079eb88dad4d640064cf3ec2eef00934b75aed8a03cf04bd154ffa5804dc96fe81bcc2fd48b3b59ee470c4cb841b7b73e21e3b35a3c6aa8c793b97f51d552e66b8a5dcea3e138666f957beb6c64c3f8200f147bdd2714dc60d605fc6e47ba644fbe648f5cc8ea2bf52251242bfb4796c6462e48375143fc4f9ddb0543ad0ab15c54bc029b9c95be7da19aca2235085a2157b3a2968f987b738c395f99095c490f8a3f3ac186a86f2d09c8280799e6810c9fec0af33bd5b27b855c70c3b6ffa6cf85b6f76d32f076ca4f11878bc38d58e308676e8ab1587f9f889df68c3712394478987e70c3a15ef5b5249293f8e18ef6024776cf53b10f3611bae24ad3e3a4a78319e7ee8ddd478a43894a7c104e42a5b0f8d0f0774553c4efdc2bf72188e23d954032e2dd1dcbe5282e800057ae0f170e4ea9aa076c60cd4840ea1ee2d887b9a1c95aed4b0df041aa3c88214d47107f8e11315b9cdfdd2f488c88baf8479a163ca994880b3607c99625e1d1cbf59effce1661a520943242c63707f1b1ee6d331c2834e4bad510d04d96159ffe1e76be6ef380afc6234c530c479ebb1431a0eef0dad3b909e75977b25336b76899ed0ffb50897f2d523e8d5e346adc4d5bda3f647bf624b85c66c29797c97c579290f7cbfd5bf20539629ccc65648238b02ca58ebb2a8fc314357747a95d2821b1b04485320d"""), TestUtils.hexDecode(""" -4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), +506462786389055DE2E4AA2A7C80388315711A7B5DCC73F2039DB99380D48D9A3DD8CC8B929B0AB224DAE74EA90808C302197EE9D847261DEFF4136D3B2A37CA32533384443B9D935AF2C384EA63E7160BF4BEB89EC0EE705D10C72F2F65A4E75ED2B1901F14B8C1D21DA9C6B8842DB62443D3DF12969CE4E45298FCFD6FB103B87B0817190C5ADED4D04E3BA4D2C3F60CC49FE0695D6366EACB9C79F28C9121584D997B7A3A7AC3243C3C75FC86AF81CC8B888E90095051F7825294CF7E1A11464BC153548F8195522FEAB9AF5AE93C5F6CF80D9ED76C19A0ED0BFBCFCDF30FF6EBD0E5C20EEEC4992765FD23F13F027E2261C38D11FD1631846142541ABCB82C0EABEE5D675EC130861F9BEE9D9E02305F168C85201DA1DA2E4D21CF1E4BB8C2539BC1F3706194AEE7E3ABB2D7447EA531619FD27F0CC7D09E5FBFFB0DA81432D173321C433391FEE90B92E8EE3F39ED492E78327D8A3586B7052602607EBA79CC9AF21132C7D3A9931D5DB4937FD5C5611F79C722E0CDC48564E416DD251C46C02567C4059A0DC2F59A124A4EBAEB9B1B04277CC47A9F345FF8AC3F8AC844A668AC6F7E1BF1C9889C3E42C1142CBC31A46EDE21CC84F230A483B5CE23A901375B27770BEC8F0AFA25F301B7AB43B714C6D0E98B009FCDDFB75C0E26EBEF7C9DF5ED04CB4183028DFADFC09963AA8CB3A9A1BDA047F62460F2B88FEE1C05D9E68D646137F660B68470308225FFC097474B2B2BC5D50A025724FB2CF70873BE7D04C05AFBF1D7DED56693AA4A4E495B1FAF9762DB83DDA6E75F530ED5351D171B7BD06E5ADF46DEAD06AEA37CF262AA33D062141F8E394E731B3942D084E583090F9CADF87C2B81C4B7F114D150C221A12393BAB92727B828C9EB86600B969E1B80F33E1304CEC68A1B3B474762175EA19A4D67220004FD4EB0B2C643B69C00FF3876E9AF63BBEF8AB6BBBE247668DA8F2E3CFD0B95D6926AA3A2CFF4587C45DA60BDB03DA78DDD9758FCF9926FA1F080A61FC0FC7660BDE9B4913C40534887B04E2DC666E981AEEE38746C52BF46FCE0E2233CE02C9307262499BE567C150CC54FB9D96B81D3A3E200EC8F7E87E28272E7B956600DD7692799473A8C63AEDBC8F3F43542B9E399398349B896BBA16E5F26210558DDFFB984FC924E1B0D272CB8834B1FF641A894EC113460C65C66BAE86248B48F675F1313EA76EB4DD0AB6EE41014FD7589D1A7DAB16CB8F113A3FBE7E01EC67B0B3CCD81C0A8C7E9824658C926736A574E9A0729C3BFCC34E0D4BCB1606E93287494577A6C4B1090FA6B997DA098C6CF555B5574473B1063B739CCD139C2541CC3F962EC42BFB3A40F4E64D322836EADA5F574B48B5722D7809A3A20EF1FDF5F3EBC000E466BC4CA10E0CC6A1390FDF159BCF0182293D9C408A8570789C485DBB977642074C869960E9648641C2A80D8A1C4E474FB98D7A3DD75D7AF01D2605945E89493699EB53E30EBB0F936B63ADF5859D9EA1DCAC44D0BCDBF2A069982BE907F1B560AD8327BAE013FBFE6E2709C9FDD498491F1D8603F9F6C9B1A643F6FAB97DCA752D9BDA1DD6BDBF52B03ED7768D98E46092D556C266E30C77A10E68AF76AC3D359D8752E2453B2E75DFECE6F66E6AB00EF37DA6E6A367FC808E1F4905339F4FA73545D13DA7E7DE49CC0A2A63639A96EA039C4EB643627B7EC4FACA1374EA800A505A80F554B3AB3233FA492ED6C17B5832BDEFB3A99FF1C64B35F1531A023415290124EEE2C9A7E34FE8563528B6A4B64DE425A8FFA91B753973CF0C96FB2A8A3F71D58B77C93C5866DF5CB5152B3A0A32884E349C63870E9CACA82F121EC2ACAD7B6052B0D74E9C28B20C76A7A821D192E11B59A7C8059FC49662C655551A7356046D46FCCCEB4DE1F5FC91F35B950F630D743C8218A10AB25D2FAC25308225540FC24CA794EF171DAD7258C2B7FCF43297F6E77A6E83184114DBDBE408EB644ECF49E04FD79769E4FE9B0530F21F8E3913A51094D0E49DF012144EFEC415B8B2A34AE2462607E7B89BB86F0C733A5553CAAFF9B19E0799A1901657BF4FF5AD6DA7886B477358E90D56BEAC6A963E0669C38EF47173503B0E9255AF1F153E673813053A899418E2BF217D01D9162C073F256CEDB73DC062D201FF6056180A8A6887B286AD6D3BD6B1462231D6223D0DF2BBB7299FA6FEFAA9A297C56ACA28E163533406141EB2E65F0C94A6286A0579C76A3A8EF96DDDAC9DC6A550538AD345FC4AABEBAC04682D4AB0977D439CB14F02FB504E10252C1F3ED01A7C4BFDA6E689D842D9B9086517A84AA4257D1C8CB842E15DFA615D2E3F2464E4012C0067EEE60489C044F43050E5B1AB3E54507422E1368CB3EC8CFB03A887DDF9695AD95378F875F14F7DEECFA54A775C60C6B7025E5D6C0563E0E76C05C93E33C3E5AB6D1E1C051B52D2805D3BE0A4D3E8F0DCE6BBA1DF04C7F76F7E13D8C3CFCB2AB04A1E605D4DAD72A43D5223FCC36EFB34D999095E742FB9DD7B69A28E070FD28138B403DF1DCA75E00A160ECE9562C92091DFD3A24C53645DED8E17B39D8CCA4C20C96F9C9F9D14AD3B45A1E87DA75B831D400AC14BF34A9840936C3277A135BC0E8C65E0F5E670AC912FA586FBB4E149B09F64D338C8C886BA65730039B5DCD0DCAD9D6EF11C228213438A1489F4FDC39395E8447212599BEB570D186883E02B442F8BF97884EF98D3D6E59254B3DDB77DEB8429D110F0689715F3E0A4F65908E5EEC867AC7BBF27CFB965727AF0A1EF37B21EC18CD60A1C87287527BCBF5249596083069315699CAD10FFEB2D87810C4DA090074FB26978E56B7D06186C48BFA4830A0BFCEF8FC7B95E73F64EFF78043E8D93F57EF6DC636C8FF612ED22FB21174EDAA59BCF89D1A60F0E1C15C5F8EB8E6A39139D500E8F28A5DB86C125C6C76A99BC47DAF66E679121557D85F5093806B748B3EA65CAC386B59C0A372AF2FB7C84111F0E0FA2C71E137958239534C4A012B1B421435B7BB8CA577DCD8C8B0A798902BAC9B95AB87B6A0735D1839DEE336996C2357C748F4EDAD858C81E2115595ADBC173782E36D4E720A5D29A5681231F9BEE91D455554A8632F7F02FAFAC0FD9D03804B10DDF4828A69AC1CF0581D2C88877BA30EF2982E0827147766F8B71E264E82C3949BB87562F810DE835CCF78A7E5FAB219E64B1FC615E7C952577B9B482F78C0D0C512833994895A125F43EFF066CEE293004E9E0E5288A61EF209EC52233EC64BC0DE76C78EB2678559724FBC05BB5B43CDBE86F6C481AF3BDA11EBFC0FB384AE00F4ABC212B0518644638F01C38030DD05FB06A7EDC6406CA18878DF38ACE8E974123D3699613ED46673BD04ED51C352F124A8F89DF8C13D2B44245084B7FA02677D5287D22102AEF4A4A0AE046BB1C6D9FC9733AE5066C69A10589B0F33780622C1709F179D4E8857564804BF5C4D83E03484FDBD1CC4D71C6A2421AA59043DA85F0B51EF91FA5DF9555072278331BF3102F5147021662D135F3011FA48DDA7C97087F01B7F86D549F41E244AD7374C7C1F698801CEAD305026D17666435217799A4A5FD0ADDF9B8BF6E31E51B654E4D697554D5F574213CF579EFB1B11CB2C136FDB9EBC0DE4D16DC9DF43E17D88EE22EC88326F65875439066CB47E4C656A3AC59BD9A576D05ECAC5B3E7AB7B1A3C0C1C48807C06F1AE4881158D6BAE9620B08BBFFCB9940B6A6D04396014CFD54E93D863156D16F6F9C1556DB1E13E630326C8B681CAAD146F32B6977200B204B632F6CBCFB2BCE9670D89A9CE043E2004773913188608455FA715D1577E03826A2471EF0143DB3C39E03D890F0CBC85040D1675821D282822F80EAAEFF5CAA49699B68B89422D1BEDBC3041AE2A3D6D5205C72123991B21AFFB312F5EC8F96922EBB44D7A0F8ACC2E390F9E3FD82353276D73E85FEC904AE6319B140E5C54FD5B6F19D17E65DAC5EE270DB3E402534B0F408BB3C554D93BBD32B255D478F33BEDF4A192233294B320393D38284D7D9987708C019742F2FC023C041219FBFE2B603501629BDABB9C4223F5B751DB78C144CC50D3A35370EE563D6DDECFD6D715F08E14A00FC265D8433055083048396F1BD4E9F010EFB974D6102401B2FECD972C26008A4B94952EBC61C35DC846FF7B3E20DD9C6E033BF1185F35A5F02139068E1D4F30C4778FF87057F34CE1D2D40BB61423EC055BB57B56C502DB8D0685B0ADA42F9C52B590610CE2F8237F92B71B3AC2AB75D2E6ABBDBAA1E554D99CDB687B72DE98ED0FCD618AF5D2B0196F1D3C19DB77686F01228C3D1DAB1F171A56DF9311939CCED0F7B22A1B77F473E8DB65C0FD6E307B6F7A0F0FAD69E5C1F87D01EA4699F4D5DE39880CF2D8E910313AA6026C17941C41252C06687A085903A502048726AE8EDDD2D8918B71A19B807889B6C2E866FB818810F427D2A7B6CB137D94746A88BBF068EAD31216A5511A54D81031D36C8139776E0FE29EF7C8A5EAA730C3BBF05988BB892F699F72F098F2931F9B4DA17243404F64C311767A98547284063D44AE74735DD246B0C189DB322058198F1D176EAE6E076965CDE68DD0DF2B284D23B94BADAFB8650F21B148B9C990F7044A777F9BD229F7905B242CC2E267610A42A5C3185C64079DB340D86598C589F9A96F3741356BF3E6D2A811B6551850F917E07E5289A07382B8B506C510C9396DDA81DB336179EAC1F84DB9D0E7BF52B906E82FD132647A84A299BA202DEB338B79F976A8D257E246B2B1B60425161C72D534B04355B2665129AD8A44C09D73AF51DEE7043228EDB62B858399B5A4312DDD7ABDA09A846A60FDA8D0C00E0ECC364A6CA95643FAED93D44BC8BF1264FAFA6D98528CD3BD1BFA352BFE1FBCC202F44496FDAF9F9EC53007915EB67F9F8BFBC88D82100210CD471C48F5092AF4253302475F9E60C287F0A8549DA00538432A342814E1F6043BA4355D72268F6E84A43264EEC3CAC024DD6E79143EB502A58E6F8478AE985797F00A295E84A0F669BD9252A3AAC6B2AFACD7AD398DF546"""), TestUtils.hexDecode(""" -4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") +fdec4bc58e167745f07a2c4e30f8d8ecf9c7a6eeee6793f77c27353dab270398dd811c611b6191d597edf44df73fdc14bdc440529b77ffeaf18ed94a613fc3f340c55dd156e8d56769d509416beb75167dedc3fa35281ba7913e94ff5a374e0647a7f6bc99ea6ac30c3e477e69823f663e8748e8b5fc43f1728612d109a2947019331c718ac31e663d44041f88b7861e074f4e1c12ab2077dc59587fbc451aafd29e9a7d584b744d83d36f794ad034c014bcee229b847e8bdb120407201121f9f58fbd0e17ae318dc1674f1c7d9d3481629cdf02fe819de516854b2819cd6a9e97bb92662757a9861c113f67ffb191a086cc6cf612d13f0147bcda5fea3c05fd29115359bbe08a25c33a58a3b38c3214f8e4379b64fbabb00a7221fb01181c7cc2dac81e6271550bce192958a93f2f5a11035b411a00b610728f704d59d7a7e51ef2b06a2000fce618a6f82a06d18a899f7c59a3d12141979e8ba62aa4485caedbd6b8ae8f2dadfe21b7e27f911daaa80b6e22b91012ee5fa16164c5a734265b81aedcbd820b8fc5c8802a5e7cee4f50adc824dc0f0ffd626aed8fc5173b51ec373dfde19973df541b031dcc238a7fff8c01b36f8df74a0a5705a13880f1b49bb82cda0faebcdb8445048ed05cec1fd95011316a53712241f837f7a544c99c631422072ff58f579e5148885f5df4172044aa9ac4bef20e852b46ebba4410b05a5a8cd5993203f44075b0b96901fb73e1e561fe40b0decdc4b719c16391891957f97bd0eed0ce3c3b82f83d0afc9658d84d5e64bc83b2b68762b00eb2a0a474c2386fbbc87ec8b2dd03432506169f3f58f69f0dc62f140d437ef524700ff0e55e39264aaeeb3fc62940bbddc9fd1a13b9d291d82705ec87507e28c1ea90e15c8d3d6e94a66adc386b10a07c81daffb2b8d1176b958f61370ef1f0189285a49058a31c2257939df230e1218693f3dfdd9820407b509f7307cbf02b1dc1f182f9b3aadebfa7c73a6d6fe4aeffd3aaad272443df14939dd94af7543aae1212bb24dc7962e9e96d70f85a17464639f2e89344cc9b6867a6bdcd4191c91da327a003e62c1117af999f2f027ae14522bfb753bb93def9153c2d6c2a6fb8ffbe7923701e516c6a9c67ca2b2b5f66cee09864b6414716a0684fd2e3c2ff1f1d09731237dddad175b9debb722728049ae1a78401b7dcce662fa33fefc2c647b116467f25a42a932abe1742b1f486df764075ee8e765dd139f58762f3c61564b5fd52d4e511c900eec222116d27ad9dca25517449bda55b1509569677b2f0bc99c4d22de9114a8469a4e401f33e7576057d4f735e1c7661a8e986a5aad28026f6af030242535fb87372ef76023761a2b46fe30002e947a0b208f95663b34f8e92f72f8c6b58a9df690426c3c7352b8100c87b48639c072f0ad37f66d2b0e6c84fdbcb7ff506b911425a260f2a4e3ce3d6abf5d42af4fda4f37d0d4d511efd204c09fdc42d868cb8e036ef79b2425780df904fbef6e22f5117434da776e99253f0d444d1ef9cfb10f4e0782d3a5ae10b1627f7b71b040f081c6f5377dc927e65965bec75a5cbaf4eabe36c65ce71c75476c0b962a278077bd765600330570474fb68a30e9e427030825674408c0534eb2db8dfa2e986d45f06072cbbce4b3a2e03a1209fa8a9eca591128166b40bbb20419d31bb82e30b2ee7962c9fef7e788b55be7b9bac11cfbce39259ec32bf200d0b490fb540e1d218b52d04dbed8c3f650c8310e257d887c472e24ea02d3108712fc88de316657cadaa0d8ebc417da228dbda1ec98a61d1d1989dc7f10a0b4fca9f6dd2c614755bfbfe26586fdf8046bde39a2f8130d5bb9f55f67db1c9d9c7e626641a97b09d4dbc3178039d78e92b5049b7a5cd637cfe35d6c6b86771db2442040d15667c256c6beca875675a5106ca68ec6f7a01257c9c7b3464e01e8146085cc3a9aded04711d2c363cf7f262ef90f17c8ea28a0c15fc2eca9d970b33ab22fc43619cd42839f7ef53660e9aa88a32fbdcc5a74f370c6696922c4981048cde02342bcd5182f0d633cdc90b383068178de2499d41159d32f6c22989d230e0802ef40823a64625003c29b0b6c1d9eb39d15baa69947508c141dd169caf1c617a2ef16149876a56c6b2c4a92be4d48b3d277bb5967fa9931611a57893486fe3b8e8b92a8cae0496b0808b49b712cc6473ad44216ce3d1855d704561abf8988ca52cbcf7cf95d6b071acb061f03aadf2c50c4159380262edda1827050675cc375a82010e3e3299911db2d93727497ca0d75f5e539cf75d412177469afd91b1a8c8f36a2e4ac5484020eb0c7124ec570f94778e8a43e80d8fe145205ade385ea279d4bf6c4ce8998b118147edf888391488596f2737bb381cf46c939db876de724e141dbe7066f4a13c35cde58c718bea1e2b75f6b6d9600fa08835abd0863f2e3fb8f7d776b1604fb068f0c8260672fda6062e5585c595b087e399f6a6d1d26857425f600ab13113528bd2de7b8b78e933aaf344880e0aa06facaa7090627b4bce3b193308f8c152eb82e13573770e3a9171b2177e9593911ef00efee1237166261a38111f07cacd74f6a0c2283757f182a508ff531568cb05572eedc6e5b706c5ee3b3e8139b7ff6fb42a9b87cde81b21ff2e6e48d0f89a8adb77aa4be8db46ebad82b4033e857f6575c1bfc0500ae6b95c4c43843cbe7d83e8684a1275ee586e50b7241ddc72c017bd7d4aad25e468b824a043504ce3950b79a5dd2919fe3411dd250ea82ce01477306b09d0cb9a789bf24d22288e73909a57ffb7a1a395be080518d4bdb46e8648486ca8af29cf0311548690a2800648cff58534afbb5226c2e860178308236beee319c14811354b6b05a324115dbe53ea9bf37b7f8284f4b39dad5ffa4ea97ebd9bdf35d593d63026667da30e0df76941822908f6df732a8dc018bd2a93be0a21d64e33da01292fe3fdb5370a0fcae68f860af88dd8a4055960621524ceffc2391dfc237205efadb78f1df769e070b09431fb7206c2cbe3319312668eedbfdadd9cd246d3d5dd648d20758882ff7f3f156412394b7568dba0150e27fd442b6217495d2c42108e9f16e9167684caa81366cc25a31766e4743c49eeabe051cbccf225016f067939b238fa3e9330e4a7443d36134d7df29f8b260d0b7a3e14345b497de4816cba4921e18dc9dde508075da67ab8c210c730abeaddb040cf4e673ec03bd8d803fded05e1256d90d3c050aea4c223c174dc9242de76e95fe9ad0970c3ef6eb5e7afc8725c77c5fb8d265699779f9cb2bf8bb26a095472c939bb3356bdd218f0b2d99b29f0475a4858dba236123ed647e94ed485a1aaac64b7c2ed19d98f2d24019055c5c7ecc88ed2cca17019388419b3f9819b489eb837bd3c7daccff555c7daf5e5fb5c75694c96f566aebc5ad5a48c6f272f812b4606e21473e295c006c190a6430f7137c9ac20727e68b0eb6fbc8255cbab5cf3832938b7d85e6a4c46e7f7051571981bc3f6f86b9a6b149ae260360d21587485ca40dffc6e93c78e15b875bc82d31e04538863ad8bb8f736c23bed9a9698b51550f91caaab6731bd6feef0226fd3e08b3dcccd33cc6f7c8d8d36e8ac344f851c3596fe6f432017653df0030a64e73b1758322786694613bfe06cf75586e12b92ab563b583161292f328b56ef3648b050f75fb108102f0e28be8c4cb7dfc4283f68eb6bede47696b1c9156194c7152b79a96cd36639488215ec9d49f8abcd5264d89b51d72c447e31ac2011f7223789a82c702340a4ce59a298713aa95e17c6a3e92011f5ec81a3a9b6537f1331ae446965e58c2e1aff4931824fba76940c5f0abdb079f4ba8b32e169e3947594173832dc34e824f296e93099ae8e20437ef564da9fd48d6b6a2cb938a9cf884fcf3327e1ad935257157d0e8e379971cee3d5df59135207930ec1212b7f38b324aab2f172726712a9d60e40a0054f26586d5b3a794edf8f33819da983c209f9f4b514875975e40f72cf9ac1ec28811cca5896e9b4cccff414650d00e71ae2e37c4bb03274df43ea5edb923e157ed3adbfb79b2410b088c6ae9f78b10eb87b0d336c5adb19db50093a7b26fe1f39cb7c6b19001e4baccce386684acd8850cfc64aa0e16ac6cd15625e73b798651fd44828f2d6c4179b21af6dda2262c79322f41a49b9327f8ff0381fddcacc5d1444f449b54d8cd0103140c292aa49bd3a807e5af3fcf33a0176a3bf32ae337c4e187cff519a2589ec5a75bc531ae8092b72fc906f1d82735070b76818d0d5ca9266e7c0f4b9506f8adad55bd8f04f5b9baab4662d20eb3cfab00ab81bca5926b6909b5fd30b14c5581152aa37a3a275642f790913aa9f44f95161bb00c736eae908f7b3c0745514b595d947f97e67758cca97f754cd359d5a4cafe7884c10f379c9233e8f9de5e1a4688dbf92d92a256eccdf06819d7badfadc0f5235b3fb9c66cf65c6d755c5aed48610cea135d8e1bd748fcce6fe74cbea0cde943ef57d26cb7d0699f9069ea14ce1a66a5b57fc442c123409b896535283cc724c27240850ea8b9014d01d4ab2d8d151719f3b2421b60e2ce0792345f88bc26f2e3d4f9cd3a69777a114014ab481459d5c5d74278cf1c0ebbbac2919fc1a77e0997aee5ed24560563448b471e5679b13adf445634742ac1acab6fa5a0b6a0e8e285714c12fc05031c0ee83ed821bfeb0bafe978f785ba36392aedeed53e4cdefca5f4026b535d7a1a1c4ec9155b42f79c8224d286927c8af6b24c0d87e9089d2becaa48f11365e40df4810dc90e12ea6288cbc3cb2b84ac36af1867843be343c3c734eea10a54519d9c6bc0f04cd978360d5eef8c5fff75a3e4748d4dd37735919a1d6c7c4c48f5aa34567737d3084686b1fbe2f23e4a639542cbbe7f99c18a80f97033795a81c9ea029d51e2111e59c7b66a2c78629a1594db70c5ca13f3a55cbddf56f1e66fc9f3176bd073532db09afdea26530bbba27ecac9d5c164ac88f7fc3fd71781dee0612ec04b790d66bef2f748e93a6215408bfab48c4932277e3052dacb3384588456dbf15fde73c3a2036123e99d698ac5785f7027bdc21a130e875870513c1acd7802959f29cc2c3a27c1d9b97256e48666efe178bf7a1b6764cd25a4e8e97f0f55089af7fcc40ac1c3174f9e9d7c2601c8ccdb7c62930ea25e3ad4b63af9c2dcfed98ec7360e85327622f01fdb3617aa4c47ceae1dcb3b64471cd1d810d03540685d2a34cdf58ebed79b81aa1b0d2157f68ffbccbd4e617d61eb23c4c77c5bab60c1bc66e021c67a26e383aa01d3b9f53f20b9ca367d1e571dbff0bc8baf1baf9a934f7cfd06103aff1db525bcabb83b254460909151355d60303b86bce2a5d0642e951a5f1b356fedc9f6cb84fdc9c30e39231b15ca1d5e26730cb175803f4f9df3521e1f15ec7ad77fad4664cc1f96813c119874e5390b2b3b04682bc5ae2a81788426b185f57b308e3b061df87c9e69b1629dcff9b4104146c063143a40219e4c0844a58d2f91cc58dc9012de1b4c7ad6afa9ad0741fa13c651be4f27b09ec40d8bb47196068ce43e9585b1813ac01825dba7b02aded59d3df27ab5a18a7100b5df7f68b51d0557a5c26d794cbe0a63539a16e1c3f612d8a30965271ffc16a088c9b70967ee3229e2404d793086ca6f378cfc5d0c560f9de81493cfebd6349b7923e16980d2f04c5c48f7f85e56853b11f78e21900b9d9dfdba973b87c1db5c860a4c890292c4aa4760cf5aa9972a1db9ebae714c93e29af2d9b3ecea7e9777e6d4fb2550f3f952666686cad6282e0dee72b88d1b68bb1ac9021d89dac8a56a01c0c2138fd71883c7654f30117019dc70c85fe42cb57c23a2a37060402a37f8fae690abd43221fdcc23d992150de4ab217d35aa5752c3bdf2fa3fdca3202f7b0edfa83d6a0938a3e2349c51d6ce1680654c38c8d6bf2659c1885f8ead0bd687cf56144f1fa6f32e90e08f059bcf34e3493f42a85814c24cd68103230430567a960618dc99cda88cadf09e854acd79a2a54dd70dcaa5510e0cc3e4bd32b86bba8f8cef4e08867fea37a14d3412ab5f2c36c61e6e96eae2a00ae94dd5f27d7a914fcc2eb6f88b8a73fb0ecdbef7a4e2d15b7e9263a37880d242f8c230afafda5a7e919260b6e14a8d65381d73878858b0001a581e7add55c06ce1d8e30caf6802b33805e2b78d4b8eeeb20c747f7cef3a27cf17e3c1be070e8fa1adf20ddadf2e46e53d8702d75c637c2e9d9b244e12faa41f1ecabc5d98979dbaf2f0a00d061f1bbd0231c94fa5ca97a75b93a48bb3d2babc9cb0a589df0f8cc72265971e49172b588490752854f599ea4a97e71b0a6d415d058dcc875ef3f09c37fa7e4c0f45045a7bfea8fc0bd9e0c1eb36a0d3e7e03240baed7cb5d3e6aa8ceda0a0b394584bde43190bbd0ec6ea5fb3973799db1f0fc11232c3e588ca4aadaf4f7141831468183a3aed6fa4caceced00000000000000000000000000000000000000000000000000030a0f1219242e32""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +89ad3b5244d66fc84f3dbb02bb51be6fa25bd2ea3deb3bb6d964448351d9821f8b1bb2aac85f6bdd7573795e228fc04b4b30dc6940c3d6fcdd803035a8d61344515b7983ecbafa0c23e961ebcce057ba857d058576d0cd929d9e5538c5b3818c2a697677ca30faa37b887f0309a8f59ebbf7f34b471abc65f533955172ee610971f85662ce59db9b4c7e49e75c5b03239533094362b94d5d399ae4b7f94d0cdfa51e0bd6d720eb3468c177273c3c0afb7569ca5514849053e433464a6136b160b35ff19406613e31e7c3b8265b585792a8e69d53a83498b089da59798b54d62cb669ac1c917f77901392fa1d667545e3103902104103c2ef080025978041f324196cfa0de5d9f4e2929b6a9a67057fa479c9484ce55165c9d0a60265b2ecc69430e3081b1dadc91056c8ea701e2ea48495153c86ee3b317ba127aaebd85349b94cd8fb60e28a4fd027ff1d96da4bd2b8fd1c0ded721f61168dc73823e9b68b8f6dfd3b27769e3f737be70a19c20b5dd06f91c5172eac3077c2273aca458315bceb77f3d2e84e4ef8ab66e26f8194b8fe666e66d34bb779406f1f60245e4014d4aa8b6d265c9ac85df71709d9d09cf9278d1ff37765698879fc3fef617139998f37630fb51e76b47dff86c367e270905643032387bc4fba84a63c539ceee7247b68e95a5c513c43b8b35e2f1228ff1c06478dee9461eec9763a227f9bc90db9c20796dd98c5d178de643df332e229daa52a1bfc0f445e2aa8ea64f233aced5d7197a32dd2954eb8ef28e8ede22aad2edcd334ea41995355eed254bbaa46af4c00c33862ce3c3f88bb2e60f6b1b9997769c91e4aa6e16aaba35688751054abe29545527b761e7b84a25a7c932706a772918994b446e531e75c94a00c1e4d5b2fca578664ad492517d149d656de717c834d6ed62bec4b78a6a7290497c0f6fca54de83cb42cf8480f67e83d0226f5b6f99562a024962920e75d4c6f766a6de0d16f7965d0b68b322743ef29f84dd1f374eb4e2be7b6deed0ec99c778994e2b267edb1b198e49a27d54306a484084d9906425be4232edfb9477651660876dd3b234c16f30496dde0704004c7474ea045ddde3ab0a13f62fc5367a4be561e1ff50a4d035e6360dab880429471ee57ad84898732d9f8f93763624ab53d8ce7e7d03029749ea625d424da59d22c593302cced4b7da41e9727cb9ee5d4a5ff5c7e6e4a2ec98520553d90afc6d0928201576210ed2dea2ace73dd5c072ece53068bbffe6a0ac44767df1433b4353540595f28d0238509f52b4588be42d9eccf8d3480199945e2d83dd64e279e25849e22bd4216af75045c5bc5ace43f3a5045bc15e7b6a8e099a709afa8c86bbb5c153d6d5cc522c115b56dc6eab85f76dddc857369c3355c15d9cdea649208c7a7579380fee044d98f8f1f6b108589a89877ca10d5bf94bda70d5d218efea9a24b9b6a6e724a056343099c04b2a13477d6d87c16817ffbceb55ba0046d1840e1f9d1e316fe35c6f06b4cec777013960a87712e3f33bfdfcca8c214bdb9a646d2eaca0f8ceedbc230d888de849c37035b550f17a927129fc04d4a51508a36ea478127b87e04116076e215aba3a925facb757bb5947c09e1cee47b4987983e1bbff5bba5432178dcb18b4f58c4aea40732ded1ee98858b936998fa5e7539a81b8fa94a852b44d824c3607856f1de4f8bc179673e0370cdb4f57f9c1a958174dced4f50c1f7eee29f8cea9518b48986e0f8867d96b0b497fb83a7feea379ef9fad3792c60d3f0e08fd70f09065396c9e2b1dc3072bdcd85ca66a5e541ce76426a56ba840a1a14f080dd3efedd7b4c1aa80aaab9c51a8878b7d7ba79122fa3356cd59fc8e616587e3214bd925808b5a7ce4dda34f42c76aa8d2916d5605c1d265f9abc7228b680aef5ae5e71b2281cc3765ba98ca9771dc2f0992263622232ae9aea0c790ffbb765028f17409a2e19a9d3ad5bff30c1e82bcb584245183d70cca5b2707384ae504f3ca475d2daedd1feb8ab8bde4e25f25326fe9e2f69557394010d346b025ad480306d46b259329a84d6b9477910529f6ebb7a92c9a196f495700729d71ab94890f1ca2d4a34128d1807bd2987df2b37cd490e7ebc91167b9dbcc34fd896089b748c63d6b6b4c8cc156b3e554f326eb08ac7170894b2eee348c9478f1f2ba488a1c3ce8ff7aa19a31474a8054de2b1b14bee71fe4abb259fac2da5e7e4a43f5b70948d44d03d3be1514da9ee932b4e4415f5f70de11f5ed3f437d2d0885cb7e4131c97760ddf5014b137e25869daaf0302dc26dce0b557187d418799392490c75dfb0d40469eff1b83ccb0dcd48ef1175e9c035b29b5f6c93ac5fe41b2cc2fc2d7cb8912f6a1f79d38ae7fba2600ea9a91be79dee4550fb613a8e29cd90e575cd55b54a3375a10bfe6de49d33f0d1a3f70a9526330c97e191a133a07d49ee12d9fe18c7c1c1ba5b6a74ba57c794e296e95ee063d615d77048e919977011087c419118deab38d7df9f7e79ecf51e45318df85820e2bb7c2d69a11c17d31ed1e86df304a4845bc8cee05d36f59d610a20bdf9b16e428fc267f585faa573b779bbd6e540b3e32ad3d9cd1c24a818ee83de5a91008e33e0a46a511c26a88fc61399efa2fdae38f75d1634fd57f9849c5a361b94f8b97c04cac9c0f7109bcb638775238711867f7b32b852feb3ee5653b0cce063415c9fe9dd7f8add3e4f996db03ba5f37a1cb344693ea95e35357772c68d090feaa3d2c61f4156bc530178b70e4b9a8e75aa1c3738a2219d3fdb5dcfaf5d9d77b541c944eca7c9af42a358222ae334ff5fa5f5eec2367040414d01b4c6876b79a78c006afb5a357a78b96ec3d502de789828b04eeae19cfc5fbfc01441da3e86934c4fe38804751e2d3b47d16c5a9a246ac5731186e97c9671eda1fd0f68ae37c00065b8c4092640153d30023a3298acee9550ada9aa5315c46fa879efa35280074f80b3a689f41a3408881f8b9c42eab59dddb4358776dea5d7a553545ac5a6a9de2ec05f70e29d81627eaf1d3e23eb019f1921752779b71c2a8f24fbeb800a12556cb12cbf7b426d3aea37a32b2782894cc23b5fad1f1dbdadd1adcf9df42afa30a2e2829b12f6050156d6c5c39dbabc32a02dc4383e889b0edd16c3061f730679a7bd95c07b197076675422e480d642c7b1d1865a7c472b30c50cadbf222374ff392d5a9f72dd8441ca3f3d688366e7f918142bc00e5045cbfa5df33abafa9f22a205bbcb1f3009b903480c5a72f804afc37808a29fc5a732fa606cb4b9745dde61e50faf8cace5b203b3c24828aab5140458cb4acd31d4795726dcbe47e27a48705062994584a7f51c3ef1d2e3e64d1149da353fea5ac3fdf544b5faf728e675c77341d0c6ab0dfde580a0cfa07ac93f4280357886c072b2afcae3c0c678c9003ddd1a0d2d9b9a04e93789cbeee7a13a58981c77e6f8b6190895d629606bc1c0f38b2ba1b1507c1a7a02d195c4ca2ecea6de3f793eed2541fcb96cc2ef03f82ce4b23ff0b5536d64c178dd6d24203409f85c8707a319cacc11ede0fd14344f7348908ba8f9179fef6c7ccb52f81c5ac8621467ab977d59ca0ad4bcaf38d36fb2776e4ca7e2c082297905d4fd95a7dff36857b3a4d45025eba22f3a893c748"""), TestUtils.hexDecode(""" -EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), +701B8AE25CD8187095349A4D41A067D4FD48732E62547E491D38845B3507A7A6AD8F8AFC53D139E47FC5AF2723B1BB057FC797519AC93CFB18DEB496BD9735455CBDFFFCA5E69C95990EF89F509728D1CE41F36A4C0364AC8C30E3EF67D3F3776400BF4C838A477231E455FF76C92CFCCE1B69B00F99451B0A8287ED59CD79EF0D6E697C93F7ED38F20204921E6E2F141D3DBDE1C201E5CE7C524370C339753676746DA5DE4A398CFC2CB1F568C16D4DF34A27CF04F0637B1447C6CC83E965A3F86C538CBC235E440CC2D1257CF916421EC75928DD6DA3CA002AC93C8F464ECD522EEF7E048C154D73053DA7BB63A5DD845512D2B6B7D1E7EB5818D170D14A4A698C8922D69A98319A10E0AF558E2318FC390ED990B75ADB50C6199DBEAF5D53B49235DE7CA116932EA38A109322AD05F5D681CE25FFDC9F6A05C4ED2EC6D4242173D2039318EF7D0733D86D57C4E114B3476392D47FC68796C9F66B1F1EC70610E1D57436614D5969564DEB8673686170E40BF5CDE506F7E70964E07258D4551F5EE0BF2651F8BF3D3177DA76AE90FAAA69C4F373E664F0A1FCC62F208A8BE130C499166D13CB34D77FDB32D5A7F3AD38856BFD3A0419B8744DD2F186D03E18634D826A5BC87F1566FEF88D9ED93E74ED4C005EA3EE2EB22FF5DEED283132D00C7A0B131BE1FA38E30EEC68B748AD533BFB23B9A14A936F609D4C560163235367B0D64C2C796F1106A1A9365E8F507B4BE0514C849A81E2C7388C8AF300D98D444BF808C4F9338C47A853222D5AA8ED283F57DBF0689E5FB89A456005B6B95AC3D791077C79BAA2BB42B423F93A7D0D999241AC5B9D64D65274817F9BEFCEFBCB4D5CAA67427F69ECB279553EF0D33A19E14FD4B284A72081F949FBE2A7543497F314CD7496EEE866F33102BEE5CF9C706426EF2365EFDF1AD141552BE65D1DB4373B0E8D449F3FD1733AA164C1F2C24F74E240C5096CD201A11113D6BF5CA19595C4B0A81E1153A4EBF88F38F1812BE517158787F2B378E8E32C9F97432BC9027292E5EDD7DA64FC6A32788154B62E40A85701895E13287BB18883820DBDD7647AE4EE1FC1D43C199EE69B1A2E2A7067AFAC541A8F44E660B2A7C114F402E2054DA7ACC41DDDEDFD7291CD4573DA22739C7785EFC2240B27A90BFCAFD1AFAB6C2B0EF5509D0DDF349C173E9A6C906BAF5692C39F6E0D1442F84AD2FC118A14B12C3AD5DF8A79056017F4FDD76603717B080E3AE560D7A601EE7FCAA36DF7289AEEA59EDD0B73BE91782377150F03C2C2ED40F33A250356CA17E153480A7E848F090DDA29C65FBBFB495FE9B7A2BEE342C7D422F28631A8C9CF643DC76F07F162DA1AD3F24589971032796BCDCD262F55A8C34FFCE05FA9DC001FB35D6FEE75B42DB6DDD2138C0517D003512F0EA8E982C2ADB5E5BC1F19B8ECE67E4AA1681383A97976B6A8F2025EA80B1BFA1796C27F6A54C583711E2EA46D85C515EAAD22ECFD68C5D02853D688302704EAC4863DB1FC69F8C35411EC6F4A9F0A7E7B3385ACF6DF805447BFE863181A945E8E7944770340496F5A19CB7DBD0D9010B7EEA3C585926408FD40F245D852DD208EA97CDAB0C16C1EF80B3E5BE77D953A04C1B6F53A23080B54F439705E417B9874B3FB524794D26DE3DDE88E9DB9FC36B1508754EB51D389FCC46F822F50FCE199DC14E4B4468B8B15A2460EAD05D0C47668C05A2315748897AF99D320E70F2AEB96936D7D739F72ABAA6960DA6A3996988F6A3F7AE7772D49915753B936367E022179E69B6853E1A83B429B42BE19EE03520A5666124B657D2FD6D15447AEEE45AB1FF4593DE9A2E6D152C64DF45C1F62AB9B67257B2A2115D224850A3AB2FA028F8F9FDE7C9A9FBA2FD291346037A1B4E00B0642B07ED54BFD70F3DCA3D1B8628627859611006DB2DD17A351751F85C60028DCF21481291526B1DEEA4C7CD2D3230653E6FEA1DDBDFE1BC3DA93FBFCDC5A405975A5DC68DA0D8338EFBD6CCDA1F2374D72FBE007599E81CF7D5C37985EA09C561A1EC40A70784FC606FB7C3FCD981F112C599C78B15B7739AF4DE129D489336BFD3966C10363A60E749162D1D8311C5E850B22910B999080DFC86D1787C35768CD5470E9F7A51D4EEBA71241DB57021D6569ED2BF201C06E235D6621B292B686D23E29DA4E81C873371593CB07B3DE46E91FAA3D4A2AA6F62FBF6BBF1954647E731AF4B99EEB3C0FA6385699F8EF2D8E1D7F75161129A1C7F8C7C68B906EAB8DAE8BBB3541FBC65F36BB67ECF19EBEF54BFC2EC4E1130A2E4F36B5644A73CB0E244738B6E5788A4B4457291B57F1FDAD2C11FE5C7DCFD4E742A0AECC460BB660D7BFDDEE4CEA074958AB94B6FA4CCEFE02FC7001D3A2CD013684A1ECC2E2F6D90D246726EFFFA99C12D1FE4AD10A6BE38D70AE3DE5C4843FE6CCEEF587191B56F666C1662F5C6FB03955C557E1B4CE247A2806DE39EC40CF8B97835EB0E3F2D829E0FEA02FE60C934FE72A25930FD6692B9ED979F14536F406F04C3CF0BE98647A5967B81DFAC353A2F8236FE147BFD7D3731C49476C3191981C9AF239AE8C72570C6C53E7AADD48E721E623D6CF11A1E386EA7C30F070E7AC4F63FB42AB74881BFA3FF3E8A35EBEF04D39B853DDE0FB17DD9DAE37A76C96FF55F64669CD9521DA3900B7CB297E813521239D87703CA395CDC8D8CC4EC21CB10A1C672493E013EAC0298F8076C8E0B56AFDF9C31EA01CBC1BDA4AE17FE103C9812E940A34EB321BE7BB288CF8BE7017AA58AD528C9DE09E269B10C6FBFBA5E8B6883FE7E08A0D184F8561FE3F43582CA045DC25CABA52C0157495410382A048BA67D051EA115D867D780CDE5EF512BCDD14489C43604F86D929F83D118B905C63BFF451FF3540E9E220851A402BEA0DB1A7CD94DE0407AEB9CF862BFA3FA703924D0A4803C463AAA827A04B0F09556054F27DB98E22A96D07F81662E0E910836B9423968C3F002E605BB688720FA7CF3167140BC21398B5E4968804F3C3065FAF125BB6D887C869FE3FCC27D88E048FFD0925E748C096C74BFB1E54A8FF6E2C838F16769FA4D8564E5CCC58DAE3B102EA300361EF89EEC689FB5BB0DE16C5CA98A60B8990EEC0006A147036871FC2A6ACFC6A6EC907D28E18A76560A5436BBF9353789C8A5DFE559FCD68C117066EEE5B00F349D6591E104295E78F445FCDD3D6883DF50D1DA6A04541C7E8171523FF36A9C072164147D14985BA30FD449667B580D73B06A5971B720A8B1D2A6896FDC5E4D4DAC78353ADC3449AA53919AAD15EF250AE12E9E40B8487F66AEF0B15E42BF34AA816F559062EEA24EBB01BA369747B29404DC1F1108DEAD021898298E72F4BC1DD821E4C88329D6F03F971F554A87FEC87F34430ECD1CCC6627D8CA49EEE1D5DA6704CE960021C847DAEC2DD544D4EAD2E2086058CF131296B7F4FA4B71A1DC6D6C642A256AE0C0EF9D1211EFA3845B12243BFBCB4F423E913A2976C1015569ECCBC159AFE70F1EDDC3AFAAFDA45CC02EB60BA0DB9EA83EC604113479BE848F381FC63C63B3111DC5179A637E0832A26EA32555908D79B308351CB104C43668371DB32056BB63540B9C3E5551A063D2B525F8A016BBACEB402CE7D7072CB9F37CEC13E1EAF7D867534C013D78B9DFE01C13DDCEC7A3444AFF9E182F12B6901CD9A70F21908FE692E4C0536B069C89685BFA9D973983AA8C1DA461D18ABD27A6A717D9F2122BEAA9BB1742622F51FF616FA2EC3A6D4724A3A9215D7B29A1BA372282CCF60DE90B3834FADE6E3743AD6B2F9B7344F45A29740DD7DB2D642F94998579A5DCCD2EFCD2F7D08486BB327B844EB19ACE3B4FB0D85F8A24FACBF318C98199A0B2C7FC2CCA59AE84A522890E22C2A7207CE91623362C7DD8E9F946817C75B71FB9654E2B7F2E83E46E75ED5638741E414D7F8E70914315F0E37B5B4E3E1CFA8288B1724113E4A00B59B7764C2D61443537849E77083FD13BA652001F39DD9BD4B20AB77CB945C5EBE686A0627ECC52F38A852BC9E1AC8D303E3B96D9D086920A19E5088054DECA635E802385600F673D3BD0A5CBE7A5B9BA8B1C4B73B9246C1A1C1071E5F98ED42041037FAB67184C89BF4FFE3CA0AE2A9BCB020F390F0B76DE2B8AADBC99268D3A1D467A024184CC9A455A8F2FF287A4C9DD1B0C86C8E176BB15B12023B291D44E7FF0C44577F7A6D788D82A75C68C9F5BBE504E7D64FD2AD18BE209E85C45627FC045BC81E3531A2B886173F3C3029D1FA98C792501A4942C72A7A892232F390CCBFD7863AC38D837755011F919AD8934742D0795523E6D48A958BACB9A9F7B9A5A9D914C37114CB111CB536EED3D753D6333219EC993AA5D39BF74E8E9FA02D8BEFF369EDAEC67A5CBD128FC9BA6F82E31A4C59D783A99912C7C389EC708824AC7FF05D56BA6D228C0A9D96324C6D9725E3BE17C44CAC7C4D49235BD15384F95345DC36519466A13110A58300F7E3362295DD7069DC6A88B542F2BC5C9F33328D9D8D1683902C025427F32FD562BE3F0680FA05851296E15C5FC67E96BAC924407AE6BE37E9B61D9A6383FFBDC6E77CC0887726C474AD735BC50039AEC665D827B0F6BCDF7EC87EA6BF793386F2A65C997545FB93F0D53737C53D00685DDC13960AF2632380F105840A1699ABE53999C568978ADAFBE21913193DD0844D89BD582418BF8B6BC430FF1FF7750AE8507495C14DF21A3437AFCA7DCEE7B1F1247C802081FC5ACE5B125AB2BF11ABAC97E201EEC2A8C90ADED920728EE77E1FE2BF31A222A1CA5263586A16FCF80E582258654D0793B1551EA3C24C4EBD27C52956ABCE6ACD05FC2F088273FEE8ADA0256F30B5ADA8768D8E9B70279DF95AE5CC68FFA99934C7520E12F57D213FF18ECA6046A9A3F32E280044023220140E2485A3B3EF7778006B18D4A9DCD177D190CD903CAC1EE0897F58762299A0E026B8EEC6F4F3D0BE1F070C648A2D73869F22DDA21246CCFDEB7A9784AE967F0DD0A2011C637099AF33E0D608AA0A5B2103060CA1A6718328D451368EA3049FF60FB66FE54E778DABC48413966EA14E22083A884E8C8EC33F885093F01B5E34477745A9F82C645C8C5498306AB00B78684252ECD74C163BB8AF9B49AA03E244F4EFC4A2E7099074F512D465C84773DBD1FA96D26053230C192DB289A1596E60B96178DD8CDD72FF14B340FB5830696B393CA319649BA56DCD517F5A08A528350E2D9531B3AC187414FA6E06C0F05D9987BB2FC98F7C8D4F922B8AA45287FA83B900ECB6C9F02669063296F1EA389858F6D2E10228E136FAE35F21DA151EA7AAEC593E5948536B68BE58ABC57771AEB406A0C3F931E7DCF85A350A3558E5C1B1F70E6299EC9FF8B9CC13E905D9902FED957ABFD7D09FB84FF22BF8410D387BA85D8555A75F432EC5789498EA36CF235276176ED48D1E374DB5C2DD1A64714D64FD20D4FDE2A605034E4DF607EC6E11D0465DB25B9D79C83182384D64477C126E9B8558489F69AF29730B4D5650B9860326249777DFE9EA5669736692D0780E9BA346C1727138F5DDD4914487CF32A4E9CB1DDD5617B6B45CF8C981944684BBB7921C88F5A25120047BAF2D9346E220EA08AD168B30A1B82B3B63C4913C708C02258B6AEF1CAC96E2A90EF7D0E1EFC0BC5BBE05D286E143FC0CA4A23833CA12727F0F83079F7BA80D809D6C739EC4D0DD9CF75C4FE30B12A892096BC4B9167F16819694B2CD5DB4B80DE8DE988AD50677695C4FB3E0940913C250645333B6F55E36F649A43C3A39ECAA3DE3EC1FD4F9F65D9F7AAF75B60DCA3BD1EC06495FF5F1D4FD6D83CC6316E40BC469EE5F44E5AE56ADB229A7CA5CA37A1508531E44B0142B4330048350A40FC82279D25A87E043240B4BFA7321340502F0D37073DF068596C4753F8709BAA2A7264ADBCF5F934E857B3225CA47D8A182B80D3DF24C3612FE4931EED565BE563115414CC2B6BD102DC6BCA9F104CEC8B24BA5465FEBB7E9730C928D6FC1144224232A990F8BED27FE6D28AA35A91F90D6A0AFE9A7E37A5BAE51D8AFDEBB7D5670F2521095A56862354D2AD946663B4BBC7049ED1884347734BF3E78ED227428476F1070F4DB011F8DC86EDC5BAE1BEDC9C5D253E4C5C6816347EC96C5F62AA3298588625304118EC32DB2DE0597BF2056046E17C69EAECFD26475066AC54D40A673741BCE72F138DD98F1939598E5D94D565C1337D1179DA057D4453DEE27B5C04777EA710D77B317A6E8DD3B4F26A6A9B3F4917A0E881E5EE528462508DEC6762DE2BC3F8F8C42E8D721BFEF7583C99DFA4D1CB49DE2A303B67AFD505F8A3865D853BF19C4A0F7CFA92F5CB18CD5D8E378A5B041449EC9ECFB80E0865CEC1734D34BC44E664243AA8F605366CE9F849700593C76BE0CB19CA1255B074A8630FC962B50106CD93DB41C6E4DF53B6B1257872B0D8CE9AD5F245C3027A3F75F19DC568ED1E0F60CC20DE625241D300DCDC8C953676363868B680B471C2EE623DA408C7E030833DBAAEE8E701374156A6B785E0EC7D1A0A55A599605BCA0FB517EF99939889C862CD790240709BEE0226DC7E8177F641C747A151A89340A6CCFF6982EF39683325390DE72E4451BBA74E3CB102870F1E9ACED30BDBBEF160A49746A23C432C3ED7EEF580969110AA438D00AA03F54E039195D61B7840222AC994784EEEA538B7E830A6508AA0B460DA4B4C0DD9CB052CE6254774FB147F7E4F80214AF1FAE59F8ADA6509123438E90AC13FF7CE71AAEAEF7A39C434C3824D49B894C389CF320A430A7F84A5F4972FF98C388D61C936E453BB1A340528A9FA5F0B0DA9543275435E91B0F5560E95F9AE4EFCDECDE1584761F8F60F0280ABF40FC5834BFE456EF66AF66ECA1098DD49BA2CC4B12CA9CFE256FBEEC328D049BD6BD19E2358502672F029888DC3AF3350BC2EDF5C4E07D59DF8DB9C14B86F1FE384227953E98978997902C8F237C8BDF300A72248B3DDEFD52577BCC0F99F75B92BC056719243F7EE67932A2DECFB15B59C95B43E183BA3DAA41B97E177D03CA320A5FD5D7E5A88C4D54A8467B883E0CD5924912642A65F191DD4DC2B08DD28EC0AD2B1CDB86EEA3DBBF6D47754B1BF7036A0BE90CC3775D263A5BC688844BBB9B1D9296804176E17C55D6DB888C2BEDA3D546FC496EAC5243AB5D51686AF9B29BF6D4A138BECD49665458B816BB09848CC4318136E6B170BECA544E8ADC35D40DED979111B8B1D4577DE2FADE6A1D97F9E82E9D3F069F3287E559E99224C6494F36233453036DBA617088D619395518B4E6725125850B3121EA957E721244DF53FB343483D27E6C3A53224B38C11C1D64CBFCD7041A44836AA606D170A80E84BBC0973556B9E4B1BD776C6A0876D727BB0526809700A0EB318BED67843CE4A6BE2BC10FE9D8228A4C94D7A506760E580E8A0E544ECCB07DD0810D79443046951C72E017CEE5B2C959754D477D706C3E043298CAD200189F4390F59BA27B0099DC551673B5138AA654E054676BF30DC61CAFF444CA22EB32E5952A598C07AAAEDDB83B8B3789EEF97663ECBD33FE356DE981A24C29DD5217E14DFCA30C0109419D8765A061F747BFFC1E221D3ACC7FE239375A9548483543599C837F48EA189880278AB2E06EA44417EB945F20ACB464CC458E249A8969273A460F063C5FAA907E42C9EE304B27C85BF41FB170708969A2BFDEF37B97DB4A16BBFE07370039369D04D0A9155623AA390ABB75D47FE2394E4606759648954FECDF4554F660D3176AF33153A9D7B0A935753B11E6C7295B0FF5680A18A42ACE577981C500581F741CA23DFDDBF22EB6511E19C016EDC96DA545AD16D5EFB9A8F10C45D78E01C74E3552FFAF35CFA1BC0C3DF9D14C1BDA9D510FC7C7A755C71B5273CD7CAF3AF44AF066DCF18B1B7D6C0D546C9C0B0B1BBE88F512824CB8B512438ACBB23CAE1178DA05DD67DA6392649213805D680AA61D26092BC1B2CE50CECEB7541D7F10808DB2D4A6B12841C8B4B6C5519C8683C998A74AC3BC3CC44D81B606A9A3174929E4AF06E032A24E67E9C66885004F07D4775A6C66A8F42F94920749FF902A8F1C3BC5A1A35BFA24040EF3B7ECD05654CAB696D3323485EF855361DB57A65C5AA0B238DC551ABD6B4A8DA0EB987A82F56E5EF05CEBCB4155181BBC61C645B2A4FA8B316FC6C5B3BA12829E74899D0A42B42821094B57E6D221FFA108D5D0EDE9012A88A2BC361D90673BB3D19D6355B9239131B42FB3CE832DEEA6E4551BF6C6533CD8DE572ED3E5DC51BC1ADA13C0C7E4F723CB964125DA08E0D08F1CFAE124568DE55E2B39B1475DC8F6558ED763FD7EC2DE373F4C54399A0317087630AED2A64BF13D113E8AC32E6318EB7BC0DE20E846C0CACD876F47CBF79DB6FCDFAB75B371156CF74B443E8DACBEAF94203037BA14E821A66244BBB7E989567D176FED12AD0BACF79834D067662C11422631554D1ACD6BCCBE23BF1D0C042C1CACA4B9BD01D6C5757E52877FB5DFC92161C8BB15A60222D12CEEE973812B4920B38547304E720AE246FB503C9F97BBA79640485624DFA2F4D508300BB80C70CF8E271770876062AA1EE0F548F6F7D95CFAA17FF1FAD847CBF6CF90B01D29C33B43473379F4B5491532432F6CAB98C365B84D357B48B416C2A00B25D07594ED4E4CA0E1BA5C92AA2F1DC7A6109AE8D71B9F06440A770FDC2501900B9EE466DDD853CA5482B4636BFD58AD8B24D91852ABAA0A37536D4118A122951DC78F02DDA8EC8029ED938125D759B24C90B0FEBA1F589AA1C10FC9597CB7E703D93AC4AFA43D3C239337AA454BCC471CC6BECF89266F588C3EA71AE50F146097D9CCF21E75790A5F3A252977E4D848DCF5D96DDD4FC1D0CB583A28AF9D7648BDAF8F1E94A83CF5349B1F4AF63AB1C66757B75C58D10F27F8619A5A6BADA67E841B6429AB40A09451313EED76B93166B3A5D5561CFB6421D83A5E343C8D277389950328A1646C3DAED357BCF2E8615695D7E8922030148844058D177D4E68A8EE31D5D810C73D9B38F6863083A8266652DB82A43615A45E6D14EFDF00A4333404DB65194EB432187C1EA7C48F819C34E48EBCB0836C84534A238C42E0B9BADFBB15B220DD0BF40F8C0511BA69EF82FA57D099BA84EE4AB6FC422442C3BE1E8DD910B4117BF4047D49419FCD2380966F665001FE4793F06F272E14E1893D502BD3343AFF5EE94A58CEE04E745E72E51124AE8013EAF2C2141012FAC54CD25E97B6FD3F0891BA1DE663EBF009A7008222F461B4E7D50628133DCCBA7CD0AE44BFE9F675E094D972D896551A1205FFE0CA8FCB739192488D2BDDD4E10493B43C7EFEF60888CB11ED68F34630623206E81ED04D300C2C43B6F27E41F18241651FC6B84C19EE1EB018BFD7A0D4483B0B6DCF57236AB27BF4CA17E52739E4D1C508C78F6B6E9FD53F423AFFAB01F75A9B1AB725C247492DAE3227ECEE2D60EB186BD8972FE455C393919E6D9760AD1BB706138824FC3C9EA0F673C1323366DEAFD260591DAE60AEA2DC22FFE5EA2421F35920550C0FBD78C4F6469092F89FB6908457BC81A175D75B1F97E2750194E68705B9D1E9F762068EE2FA9286BCCD3ABE98007AD1AB27AD2A094C6E164C5BBF88CD4C5F325E4E91FE2867A94E9FE1A78DAE2ED1C11CB4D365EC2F3888612FF58B493268645BE9ED69C196857F8C995A42D5CF4542E609BB35B0BB1B4BB85295ADE635E8FA237C5DF471B8CAD7E98420077BF1DBF6DCDCC1322C8BE1B8DD5E228B6E6E04ADA1D533B0C6221FA83BE7C19273F9AADADE041CEAE389D0572D2317906005BFAA17940026CCBAFAF8C7A4BBFCE30EDBF4EF82902E181B41A1FC006AC01BE64CF6E4A4A14FED995D6F323405242BCC5797E43276ADFBA44EB8E3EEC029292D2DCDC8E6C93AA6C02766308CD367D3"""), TestUtils.hexDecode(""" -372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") +16c069f82e6f6efe9eb825ae1b6e908e32c28e3b0ffc443e9472356bb19fe58378012592c1afc414e0ff970a13a9b8cb51b968a7ba9a2f7d0c326b5e1d074f5af742c2b548f87b8cf1baf45f86000801486773a4240372f8f1c05e0e9ceb1bf5f18556c62765cd06c472781f73f6c766b44c2f94e436eaedf8612cd1fe381e645689cb6e7befaf031823029f5a6d8913e2245fec9159995956825ee81fd66ecac65d960506f2b3f58aa4e9a6606bae585205b351c5654b9ff455b08aa9ac45ad3b20e7619a3383913defcc42c0d25acb6aa2f3d4e17e4febb6dcb59c31e853fc5db50770059aa70d8d3c58d3b98efea00f9756260d843cfda0c079fbbd4933ff8512ea6e379b7b1b92ed4146cd0135b2c8ac61496cc70b55de5eff005a310eaf50ea88666e342850ec6c22d2d5cfdeaeea40321c8278e341b8422bafdfe71b42cd3483d71df4c1ac8bb0c86a72480055d272dff99203919fc2a7836adc985befb8025e6e491957159183949343d316004c075332466101f14aa78296cba1072799d978c1b36e94f042eec38b989e0c7e40db362fbccdbdb56236397435b65b12cce3f13bf55abc805973dde8f9c65157c3a3751209afd01396ebd7bb20fc16229ab289848c1aa48f5bf86791468df8950ebb317d72c050270f275cc219faad9980c69c377679c4e137810813734726ec78ce545199e43552ed33ab3689b6ac18fc54fe847af97fff3e2d6fd2bd6885fb675278c4d897b507d37b5cd1eb291d6195c03b5beaecfd90244a497c69345f70a118f88ed8568386b1af2bd23c9d0f2763c19b669a7378c42942a242c3721c59a5c0390137077ab10d792e2670da72dcae6042778d691ed96dbe126c2ac03e6f5a71eb1cc363997ce106c6111e3ddf50da12a23447af30d684548536c2402b60b75805cd0a8ff2ce7b4d7863a0baffd5c0b98df8dbe6fecdc37b2c882027f0d5b78ba3bc35a352d419978bee8f39faf096d31196590c415044500140e8ca976340496f084eef29a1a1fdd8df215da732f37e140aa48aaa393e5d3af9b266f98f5ed1410c9b4c88936f1e2b225a6e1c99ee9ddb7aab09b55be15aff94d2f43a8ba09d673b5d1327ea95f42fd26b4e13cd02a6a26c0d20fca8dbea95e71a9d9b6ce80fce8c7c0cf0ccea591916e4b9eceb3b42645615a40fd063d1e0c7753211ffca88a67b3029d6f7e387b11ca34d5357df38f5d92042b2f9a7d8d27ef6c8ebbce9377568cdbdb146d2e15858cd7133b5cf242406a857e4247462d87994959ab3b350cbdbe521f81b9375ee660b53eb534195a7cb0751c54f3af3ba72ef2cb3aa6c748270a64b17685d046641c20156575846e42b93fb1c754140ed6a6a02df039cffd970c21349e2bbcb6323815f1849d38052e6bb143d11890518da4a213434b820c79994586638b70d6c006acd43e43a79821478bba9ec09f9442fb15308d01f533c460b70a28c710da2b3f4ac7449129081081c4c87a241ab2f9483add71974846a3f32c3c96a08ad090098f38021fdfeaf50a36261c728aa6395b2114a88cf9577793cc7bfe45a7e238b997bd35b2ffb0c3992f188de916f7c004c5f83da5aac274a47bb7348df3590668efe9c2503b2c316dc074262fe874ea700b93a9d2545ad3e22b395d294bca1a2b5615d259744c56cd3d736be2c4624a1302cd31ef33f75373d2bf8b22a9e85db1df34ea4d24f0593cf9d494ede243517e2618dd0a6bbd0ff46987995805ccc3439e39babab22a53893223e25eff5276ff7a5eaffb88fdd248f3b2a4936ae56bfac6d778126930b25f05bbf031fb0574aaa129e4614eb1a38171e9d19b7fa0ca5fe7b4860ae3447bf2de8a89b8d0e85c7e130bdeb0f40e6326b1167f744e2b664e370f8a9d31f662364f442f1cda1da1f9437ae6255367e242253a325de08f6a12774612997a2f8b2a6a6e084ba51a07947ee7f4eb68545594756582be6232224172439c1105f46da151fcf9ca328497f952151b38631f4797f6d6ba367ee502dac0b1c5f45137578a5fa947e311cc84b73c56f058a1265ca45c10423aa165f08c53bbbc7ea42309297f7f37a98d146c48a7cbb566e005b76ec243ce6f7b9231428cfc17eb4b1e0b8d3002628e3ed7bda600a5840d4c1b2fd97024bf2f9ed637b521e8e1645400a7037ce6db2bb696b604d6b5f4b40a9e4eb443517c00a5ac6c1859dd18b6fb772155f2d8be3099b638602bdb9e3941d31bbbba3cc52d7060f7b45416c9923ee3697caf14e7f51361051bcd540cda6a14a71cb62e033603bc9d58ecb39ade2144b13d1746f0de2d1742cb6b34d91917adb69634084e08b9b37dd2c62f55eb64ca81a60ab5b71bcafe2c42f9c8d9ce59e6be9c2f0019c3d96c6ab738cc9df2976f0b9c47579fcc2d72161317c541d5f7de0bdc19b6f7d3264db1079cf3deb1619fb6531aa0032b19d2cb2ccef9fd6c1149c12b701cf8387768c6eb004fa6bb876f7ec010abfcf631caa27cf36d30c1738d50e868214ff8989ad497d0b12ed2ae83be1772a531610e4698bd721630dc427f07bf6b4356d720f335ea66969d14b246b757ddd96d1607dcc72d9d36fb10f9a529056255b9f962ba7a02950a0b9c988fd381d801af73d7d9abdd842cac56a77c5e2a9ab91785ad17966a2fc31e42a663ac583488081c236d13b82b09933afc57e25847f8511b0cfcf472ca6b21898ae47ca8fe674a55f8737053ddcf963dce0568839660b47f2dfc9eaced787aab897d16cf1a1e969f4e5fff7a8ec5c3ca33b6047fccd8d32f4c3a61d2c69075e37640d9120330cdb9732ea9325e4fab3e94ed580fc5be75acfb14468fd12f6e4cf87a7ac340f990e33ee4e1d2cc48a793c8c480b59fcc4bec660d101fa1c61a50b423c16c09a29d2dfce1d2011d4e4cae986e4822090379c17ff077cf56d72478a9bd703c2ea037ee7419b8b4464388d3bcd5544d3a2ebf12be85917021388950c180f2b020ed1d6dcb3a7e0770c7c1f5a44030bb4076e568996c307182b103050bd43ae645aa96be787f1d82cdbd629220104bc5167c0a8b8436d828cd70d34c9ab0c039cdb0a1ef137783e92bd7eac1c995268ada3e1e8a494fb00c5d678f5b6010c8687b57bde36d001452b0a73912f6ad0f7076481210a975b44410fceacd0699fcf7c1489e42728ad705600cfe6c2267a9c7979274e73bc2aab80155fa561390cc9460a93f29c4db673b00dd95d5421b8c9ab003fa7b48f82fd6bfaa264f0debe6af3aae7716b66c5533c94bc595e646c38b004bfd638e261b14562ae061164db1716208f79e5ec5e457a9ec47d2b0b7b7b68a62c95de164217b7472fe600a52a3aac43775f267832bf98ee2112ca9db28be3e8a828bb1ac676178ed490e0d27fae273a7d1de1fbca15aabd065890467ad7d4648487c525bf1ded91ae1bd3a99c6c734d580c69895dff04f3409c2f7a3e0416b8a2c53c75dacaa8bc020c803ad12e8a48f850737fe8d88f08643bb6863ae7b23103b0037255cf87f27aecaa703db904d789c61147b8307928bb184bf94ea902f14032d3ab1d6d13066ef6dcfd80cbf155f68024fd9fe95ffa782b2de5c97e1027e7f794c4ad6a2c23e3b5c2de5289a1f96a4f549dd32e9e4cc07771da9d1c170a315ef9d6846bf10dc97c1ec7b748b5cdcecab920d93bcb5a706b23e70bda6ac80b8efc06eb3594e5edfa4326caf3afab8cbd479f5c689e86e20247a42e828e589d831a6f1b2eeaf747f903100540ae7d725b0e48a3d921c303e13cb2a3ab5f8cc20502b90ffbdd69cb42ec092cd2a24ae408436e77565084a7bc20742fe0983744d7c876b646b1385a383bec18fabda857b91088b8c7fdb5ac5591bfd8b4f5c8f880509d0b6a54ce45d15c639f3b818508c08e6ed4a37497b2080364ddf01465df73e2e91a7a9424b10ed9a6bf1f05bf559eced1d0b667c35885c43db657520609a3f55017f8ab363fd83ff7a88974aec48d9b359d25ac9e201302102b8e62ec176918449e7fb745ef5dfc03381237e259f4cf200714830b2ccc4925afed71a4b956d1bc55b9aacfd42aefd9d4815a6e1f6151fdc9379e34faf98911e2d5a64152c426c0e8f386e06a86190fd5aff238128a62f07e02934356511cfa2212cfe3df6d5c87cdef644e7a78b34a95dde40002d4fdb43243a2f33cd3bcbe00d3503451073c3b13bc772f98a579c72116f57f7bbd07f966bafea91fe80541acc19e4010723daf868ea6b5760e66d317090ae218f57ad67c2992b36e84d513052eceee456c29cf57b8336516148ce3835d6ca526913cce6acb9a6fa1e0ecbfd9f34609a6751367c07a6017a78e078f2627e9f7be020482731cb93e778728e0a35a7f5bb2d6c4c9e893f0f7581effe6881f645223b699367feb54b8bae06a68e025a9d8ff507efb1ee6a0b9a74b14d47c8c32a4188f98d9b359ad1dc9967d19aa737355356442e659db0097635fd03e6d2f629380a5a6394e28a13ff69f36ea8f0fc4b70d2d002500f988db49c8d4da0a71e720be07034ebb3389b2c75e3c6254a82e2e841ea0c99755dff1ae01e51367d4e02eecd304932510a947f948007414e2bac773d7359243b8bb9e973cd4a11f7e6406f450e42416ad0927b133e0767adf949efc3dcabd9b523dd92b63add6c12d211edda7dcc73deefa427ac96b72589ae0c9808e7bf62ac31ed8aa5bbbdb33db466bf8a33a7e3b170058b1cfe84c96eacf005ad0796aba2c994c375b79862fcb6cae4d13bad1dab2b838c657a55f85b988892f62c3581cf60f24478735c04288c1fa09896e7fccfe1a102daa51c24924ce9ea1ef8831c91d526a55ba7ef2149e0a5045d8362329b6e3487ce8a7f0c33a428149c55543bbaea26b533ac8103820d405138c17510970cf367b3e3a4c46822d10e05ed47ba4c3bcdd02eb7e4fd990da55a518761335f9d2efa6878f8d0e29b2704d3af11dec3f7a8c2fa9a7104e971ecdb7f18d93ad2a1ecdc8a4d1dcf8ccdd66608859438ed23e5179f6594c631103828dc2d9f8c784d2a4cff15c58084318c18571af7940cee704e9f3cd0bc758ae7cf9d70995f1f1422bdbd2bc441831aa72b66253be6ce186f6e93613f2d3888a555b578481ca324878518dd9537e5e1e7b27094dc5114a4e51a776fa8e5e86c556f45145cc3216569c17fe22bfe281579a6fd70334c574d1d7aa5fe461b3c0262830a2afd4b485d348babfe81a3418bacda574019077cfdcbef5de1e73c8a8bc3eb9113713b563da34073670cde452e84866d688ac9f691916bd443b02c8bf15c672e1e75b50156e1e5254fc23e0b0d6fa530435ae5fe06132d691a3e59489c7102aeec1ae9656aa334321b8f07aac206dc80cabc6b3c8aeae941438ff5cfbfc494fe08661ea496b7a81cfc949d60928251ba6217813140d050fa68c34dc58771b80b84e79f469442584db07c6b5ed39a5f83398965b715966a3ade89570b09a501860accccfe10aada86ae989bae9adc4ca7480916e1bd4733d6484959e4cd199086f413c17b61e16f42ad93a85ab8ee86e09fc1dff1087384ad087a6d95dd845e457f740e538faea88985df42fa2e0ad89c8885de6e0b1514cdfff9e86364dd37ae591a1843f60f71b8e8b6aedc3155ce76d1fd9c4a20d077050d7942e8369cfd9e0cbc19e62e32d15edd34b7f2645dc31c1de6ac3c36c5850d43a6c479e7680f02e23c8870c1730ad163dd31d38e1e7de492ffebab9f3366e85dc9ff42dbdd1eee8bf448abc8017a2bcee2367e958a01986fe9d7083e45e262595937e3287b499090d4ff466f52824b032428757eac7756ffe76ad43e6f70c98b4e0769ab91695a6ead1a1ed45ee36218dfbc4994b7e5227f0fa0536a9b73b01701d10f97d0c4b1bc9adfe7c2bda52e8e042b976a0ba1b9d988acacf9481831cf6881e70b21520cb0abfbca56bc3fde95dfc84de3b3aa9d4f598dc5aea2473ab0b2d9758b4bcf353c3fc2c6a7e487cdf1af90ba9b5a464539e788b86077ad0ef611a2910f784d72c75169ca095e14e4916c346e55cc1bf042b0d578d2923580709536adf49bbcbb7fee7d4c8a61fb39dcac21ee50f80a7bc76e82b285b0bc3f0b0fc9e70563e82ae65345d521a5ecbe211dc07acfc85f707c6d23326124eae586bf2fc77b6021630ccdb6dab8569b00374a1623f1a99138b870bc25d20911836d1aa907e9029436cf0d17dbc9bb350ecaed0bcbf4d48a4a7cb78e602e33d13f243347496765c40c8b786d8bd4ae6d9eb6ab879d4f56a004f9d6a3b6e98e2ab72296b546cc34abb697e7eceea1273f7d8658e60112932673e090be0c212d3d664237b91714d93edc6c86ec4a3c98731f7c102652015d58abca17b412ba07502d79ba43963dabc05bcff231d342951f36dbf8f8097e363595dcf7141215284cb4517474a85e0f0212c2e3c687d868794d51d1fa9b0cf102a62a3de0e2082848b90f31f203291b8bbbcd0eeff6b769095ebf9ff344ca7dee7eb000000000000000000000000000000000000000610151a212b3238""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +a01e3186a88928fad593837cd6f24d201ab8aa8cd445521805be6ad197e670b8ac1410aac5c88a4469cb7ee7b1e2588fe97a400d5cb948553a8bdd0ace8201d7ad26e7db90c6f841f7a30f31f167e5a3873dab36258655ef0cd745ffc8e3ba7be7f241ba2e97f456aa4292288d0825b921d8b266eec4fd51fc0d5efd1d9f67ce4bce0a521d2e693dfd86f3d3d308bb337ea64625b1404f0121f90c6ff06e14059bbe9cadb32051cd3bc9181d78f7268438729e1570e2bd89ce7e28afb134373120afcc99bf30d963f4bd616d8cf0c02c4f436592395ece85d2bf650553fa720b1ce842b0daad2f610a4a458ed4a4ca98f87eb5ed4bc0a57d892eaf62e9b525e6e6e30f0f9f0a5490ade1c10b8aeedffba0bbd7976aed7a24f1cae8670e9901ea3d72d6a895307ec5caa87b18ffa6286a802248f6e1eda5c5191ad3c8f015bc607b79e91522f729f966b1685752a927ff28b59b0e4584f02f456a6c6a81ca4ab7548e4768ea744461882c24cfd4d4212fb4733786e10b23574a3ed5310e65fe9e32ede340e6a2349b551f5a99b238e4bb0496e56b65d88cce8551b23a89937c534c1f38b2f09958d0b017c06ddd26fe08463dc6737a31c1d74add57eb32fb5acccef4258551bf5bd845a2e872cafd171a030db69944b594fe5c7214b21a0f5edc80ae3d3c6c8472fb546ef13c0d0d764087c8c68c39b61f805de2b3d9cd02a86a00c4cd585416a8c25369c959d2a0911da264404a5a95db3688a2b25461a5f26e941ac9da45f18d1ad2fe82614327ded1ebcdd50471e7ed37d32e3b48d12f090cc550b2e64e3527a81b1e66762ad75198787487c4bc3743ae3d4bbcb6cc2b279f088bbb2624980f9ad78efd1c0dadb870e6732b53e63a025e012628b9cacf5cd0ecc66b21754fcafb6e5fbfc99214b080b0373c5dd5bc70b28b727f943223dd69c8908a54e49c86f74da456492d06dd8e454953033de489dbc3fb7c98613a79f303e28b0f01c82270c671490105ff598f7e6f6bf6a6ea0288ec7ffdb90c4c7c8961874c8f020d7228fa79b9b0f86ca39738b755058d341a90bf63fe98104de55fc04a287905933c49e5d5475a49b873272a8498fdfc1e6b043bc0881bedaae1abde9ac55ba925af591037bcbfc768932e3749f2336ed3affb2530b4bd527cfe1589a0a0ae83320dbb8905d31a48d77c1df191d76311ab02de75591da5f2b9e34e470cfbc6e3459cff655518cd2e070c4b506d24f1281349d57732cdc303af02436dcd57ca2d1b716ba8f70cce68035f1bf9b932618d3913b1dc9a9bb6f60d35a68d90584077d02d93af025f84a414fb939b0246888dac3680534b2ba9f2e224b10e44ca412c94dca680b62845e441d3efad02ffb944950cce3c6fcfcfa14e3c9208e9fabc52b1499830cddb6bf6db50f9899833e2fa09e09d06555978a4006c0188bc13150cbf94232938f382633ebc6d41a8c5a917c4abb86b2b5c160dacbdd4a3a33acd5c158e0d95fca565deddbe2042912079e796b5b67905254bada03057326acd332a7c52492fb6a8b8876ab3a9935d11649475de72816dd6b756f204b6d1aef5f5acbf2ac139568851644f622a945526bcb3c86581fbb2e5298ff01b2aa48fb69b5de1a901167996eb41dd8fac44c5a02c3a36ecdba25a7edb2612a5b01b5e242b1a55a9548a962f93ca3797901ed4beb510c11a90821c5c1586cb82f2f095e87c8a42b81670d342bc34fa7bcccac96b9cfc2966f3b2337fd648534449c8d8d7c6f1c12330c2631201acd5a8c8a20d7b2006507b1ce5204cdf8bcaeee8b3036f9f0b7f47d5aa28df4cc55ca9c82bb2d59aff4436ed8a09ae1d44bcfdca5d13c4d4d8b7803bfabe2f8bb88e25eec965b0dc904e48e17acf9a84f50bd98d6739b312419033087ac252287562e9e88bda07b8de3ed0e503610da09e994a81ebd0ba89467c58dda3c2e9c963190f2afc949ef97e595dc445cde87b7303cd3aba04a35b348ee2a9d8421d1fd69ce0d3bcfec9d93d243f45eff6430e75ab1fcfce14659edc3f7d81efed055f948325d28fddd90fd7efc48812f267b828ae94a9964ae4a8e764fa6463840f8a6cf078b39f12ff36db6e03451d4996226b257094ddd73a323036fbee146e1ea3865dbb6d7a3dbdf85490b04c28908d4ab713fd403d97eccd18955707683723ac946b6d90b4ee63a771dac2bc66ed08cabb29fcd96c2b55513b4e3d9815567f5f8788fd22b6364b8cc3d2a86bf9ed5fe775e131206192a85406208c402937dab551fa4e8ee4e4254546a687b212c538a779f50ff39274d8f22cb2ba5ddd74a6440246b005e7fab095eee8c47243a274e11375232478df603bbcc729ea9b6778a37f64c4f314d963301c9a1f92cc8884dd393f3a4b6d42910110183d5fe41a0b950dfe477d505ab76a31fdb5195d1854b7487cb65c378b0494b45370dc64858041654be2ea89a704a6a903d044c962e3b7e068ac0ac837357ee49ae14d612f1e3a319eca339ddb1bab1104b980aae1ae07ddb27bb6a69ed585e3e7cb2c0987d51409d1fb23c4cce7108f6819153e7c670778852a7c7fb929d1357aab51bc9f0e32006bd7167bb39ddf9ecbde2c63e492a8dae0de0574c364e851b9937820e49459b5e9591f12b16f50c47712b2729e031b4e3de4042c51bb51b0dee5b44fb9cb37e915e64cc0761b9e3a8e0793fa49812d2909e8376db7c0dd611499ad7ec5c527c153f916a020d7c23597fdfc954171cc1ac1116a13c0e182d4660ef724c852a347fe9cd07e512f0712b55eb141ea4fb931ab8915f3dc3fea2fd8deba0640a5c60a8670216ca967fb8f89437cc7acda5db202129181ace745e0357a6884eaafd08e8bb992c8d68bae86a940a4d756526f38e115dd75a2ce0486cf170951130a8344bf3ebd241ca694a84d2af21c77f77460eff8151040be2b3b0922684e5570b1097f0a419af32453da40f52676006addb2b9d9124c206ddaed4cec1dd46d08dbfeaba8fe279e0ea1ceb6ee9722f67ef2f70d9f651fe4219f1732e35b3b824d3709621d42b6472a9a9c5a4cf2bc534464169d3dd3763f8ed1d80d43d656e32790334238c1d1c61f3852eeabcd9424d1f9e12d4a08a1da9d937b35c1ada0feee310836417d241c0d7261446f836ab3e9729797ada42635ab2b86248560724242a044323a078f28321c111340423770ccb36d548b82fb2f3db2f1f7eb2e801e510412a91854b574668205aab9d4719d09568b4392131620f3af1308cd02efde135423523e6b1a243f693364df54744a809f483ad375fb792a651cb7a81ff1590bace3d81d02ef26a33305156c620c7ba256c7bdd6b6567aff0ee45d48c8a087da1e91e39c4012221e2baf5c73c8634db7797043bb106a287d2f0af1389f382a452efe0d5ed1f4eec269bb0183eb6d6c73da1647edaecad7c07760543d4869f80674ae0d2a33834b4995ec00955f954fccde46b6b3c1fb37116b74cce6084ffeb1a9c384360a95b4626cec377a964144c0731c4e74e6eab065411f3a46dd97ee0a8a4635ec2409042e8196dd7e4e254eac645e94b99636fcd084140211d9bc34d0b104f202182baa97413e3cdb139c1b4cf1d88ea229f1acc6040c448c7278fc64f835480b1e7dee06cb1ec3c4244739930ae60b208a"""), TestUtils.hexDecode(""" -EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), +14A8B812B4C9129CED02A09C8AB19443D34DBCEE85AA12528B61F84A2AA9D9DA49011C8E2C3C3856FCF761EA9C9882FB18666F3EC2C8543037E54FEC1F0F944FED3D350CACADA9428B7FB7D9DA4937DA4D1859BEF8C6177F0EC93BD67FC3D5B3D13C34D472D01372246704DA4763FA73BBCEB0F4C3658B2111A7DDC01FCEAA9059FE3DD5BDF2A9FE0D1C2384E82926EB895AA529532FB20E12F1C61BCE208E48ECED036E4F84CD60F8042475749E13D8C3ABE0AE17967D5C6D8C598A53A10231929822FB01EA976A08BCC0D18B1F9B6C7C1ABDD15121E00EE80459E6EFD61CB8D5AF950F0A8FF2807C32CFF7A56661C67348617059D7E128A72C8AF36B149DD8B46537EDE60EB5DE8A16A93349883B73F7C4FB8CAFD01E0C9D7B1EBF6D7C9725651980E0DA598A6ED5114178E47EA4C6ECF870033A03F134461146717C8AEFCB8E8DB1ED4E286C68C7358FA105641EE3ED9B4A5D4826B31706CF0946C152A365B246DC036191613655B829ED1AF8044F5707C320EFA1126B90137EB05FC220F122AA990AB476EBB0BB3AFF5B92442A857F6808E144C60F4B5190794C411C705513BC32447D83B760E907E6FEED63FC0A60C0CCD01734AD55EE178E6BD6D4B8A238ECBE8E4F8A464C381F16F11BFE62DFFC5021FABEA941D24B81CFC3D0F07F00F902FC5042F95A81BB8B795907F8D6BEDB5E5C56D4B2A4353D0188A90C01D7B2781EEAF2BC3D3D58A6F6AD63DF7FD4D32ADBC5A7A2F81EE3F5B98E8052017868EE59D8DCCC0199A006FE4FF39699EECC82DBAA846AC60B51FAB6F456DE4357F5EA43FDCE4B57AED55F2F6EAE49199AE90F6CC4AAF662ACEC2724337AD7F9CF74AC990D3083FE384685A1E616B233752E31CC4FAEB8048EF77480CC849D3376464621E2BF48CBB55E1A7CAE855A216DF4A8D1AE4E4016958F5855FC395C53C23327403720271EFFDF1A90C44E93E74D71BA29D860679E877E410ADE48ABD0EFDECA426DA792271D813116ECC894D799369EA8094C328D7694E8CA47459F31F5065858252C1EEB1AC4750AEDDD327048894F7D79A1D64737EF6E8B93ADEB938C1EF31E38DD60E8B4174AE093697DE4207C7733D82B4FE92590358515D30264A408746AC252ECC0BC28A9C98BFCD76C75845E9611909B0089B571259D1D115EE0D5DC6BD6F3697E1289C4742CD99F97B5D3A22631E33A81734A5D2BD1FF4A819CD6A22A938D3F18AA90794C120F4BE7E14324E89EAD34820070F8160B140E8CD5D68378C081DADABB41D365663AF26C606940E08B20581F4E63AC6E68FB5A7EF5DF86047BAC502223AF08F6CD82E6ACDE60116593046B5CDBFE2411A3FE89C438A1E84CE6D1CD72CFD3E5F67C331E72754F6CF2BF921FDE2C6DD5481F20F509A6852AEBF55BFB4B52D1F8B3E397C9B147433198073049638DDEA7E21C2043C786C88E45E566B6A7E8742209F5ADBCD34FF26962E87CD235CA1052AC02E4BF75DAEE60A06B19A4B0A61A15D9651473DF8AAAC6DB951EB6E669FA5F89175DC1FD4D881D688C477D16CEFE809E623B2F2A996909C3E10CFEF756ECE8E93072AF27B87715953E0C48946DA8E893160CD351E48FFCC6847975621E5C75D5DBEBBFB79297AB368D13BA95308E3D576F1C54CCC1C4D5EF2A41BE63AEA2A9F9A27822ABFF58B06AD99515B97F260843DD2304C855184EFE96BF10420184CBA2CD3ABC38D11B7A74E4A9E40FC26CAF3A84BFE8794477335EB1F4C67ACC9513BDA5D8252E608D03C69D493F8876FFF25D39DCD71442707AF2681CC6D5E117BD24315B0FB5C9E8175CD42AEABF699B7B77C9A8918AB94518B48DEE1777EAD8F18709A824F277BC06CB67915A5A2508E18094B0ADD29FC7CD554D8671CFB47EED2F850FC84B1C0F27767B3052869B653BFFBECBF6D8077697D1F440019E3381FCB917F5C06008A04C8A88B4493698C1964E25A551B03805244570D0EB6999AF2BC467EA4732B460A40F7C2EDD2CBB07A2DFA99B4E5F4663A45F2774C1ACB0C8B965E1053E3AA140E973049714DD644CB9317D9B3252150CC9A525E8729ED4A9A7900B417875391F7BDCEE646B1009CA479A1295555759C5A7597A775A1D1CD8D870A71DA7ACE7CCC7D2F38B18BD66441D80068F76AC194FADB3ED5F4201F26F670621D254264A4D2A88426FA6077895B9BD794C8C84DEF942FC43F2FA115509429A939052200196CC921454A65C4BF1A6E871970A3409FB9773F356BC17E03EDDE8CBF2F91E7D2B548380967F756D36520009DA5032F20D8C8CAFCF4B561A4C2894CA13929DF2AFC2C1C9FC41968746433FACD66309D2A7FB5D90EBCE40ED1E80C12D07BCB075FED76DE423D9EE6B1C787E1039749A0E559B86C4079CCA1CA7E4A3EAACB300C453782071725F6E2DC0652DB5EBE7D1C16B6EE0078004ED1F49DF439107AED04A2E69F70A35057C36A307C8F5BC13FCEA76AA997DFD2E2E4B835677EE961234895BE9C9E7D1486C04ECDE36AF4F7075C0CED9A33C372C33F751C953A2096815D9B6186632D3CAC31AE6D0A931258014D6F88157ABEBEBA1C11B9CB2956253D4950F5B2F64476E4125848F27D9ED4F93035FB5F5DEFE2435E67DADA015F048A90EAA9780B983748CED6056D021D21F6FBCB1A2DE0C627F2D9015B3D9D35CA17C54B0FAF85D0C45A53DC2575E2CB54B9A5681FDB66C9D5A09A3F48DFF29B24E45BE82856C6C76F0B9680F7B666B22221E14DD8B22A15FFFDA1D666F4EC6ADB5B929C2804ED36077E1A39F166C777770124253ADDE6B77083ED159CCE35894597E7BF3DEDB346571C2BBF69AAA9ED133E94AC7E31F2C30AD079EB4B4452232D83E49B43DAB60BBD92673D90F187FA6F3859EEE1630D3A232B99F3F960E8BE49CCA0F1A519156D2D861F8B6C15FEA4C4635C23F2ABEFDE8589A45947D391CD1DC3439F965C6DBB5C5C9AD14192B3D784D1C78B3DF6719D5C474E02D471B9B857611E2FED83869BFE8A2A74493C25D39C78DB019BE93E3BE331131CE85C4586C0D40D676640405FE363646C2264DE6F64365F19F87A8C54C884703DD369FF52F65CD9179B8A09EB92C38C284E06B0537EE686D7BF3BD399FBA8E1703BE3236F8BA262E2C84D55EB1E1E55DC14780DBA04BC1106D98B05593F9164F1651809E8AFA0A04BB0B51F9FFD5062B495133B509A569845CBC3003BFE23A7D7ED433B70C2EAFF5FD898009CF1ECD9E9B6F37CD7794234A098CCC39EF078E3C152017CC73A19B811FAB4A2CEF721029F6200A4D1E4F9E95A0A758A7AFCFA047B6707CE048C3BEA6BC561D152AC4F161347C098F4F44AD92006090324757D73DC074F1E1D445A500AF5A92CBE19EF631D99FFF870C60BCA8515125EEC36D004F22FFB420F5CB01330315F00CECFEE3254E54A047A7FA3C7495E6ACD579A9159F667FCAC4C4448579E7A68148D5518EFE269E97D90D67CEEDC378657A45E9DA855EC55E7BFD0AC3E52DADAF76E800ECFA61F2BF532E7365C4FBC8CE882AB327961C6A48C24CF0F0E6F2C54D732BC9B592008F2E6C80F7EFA788AA6BEEF0B6AB7B21DA3F9D92ED8A8F5F3F4B1D1BED6F66B6BF3ED52E49715C07DBAFD67F4F253DE368619A306C513E645CB5F154F7823781EB3E15F38EE482757009E42CEEEC1530A0159D25F052F4D4326412CBE6CD11C0DCC56B6556DDF806868B83602671C96F81D8210842144757A36CD187EA0900F36A0A9DB85B9609C11DE03A38A9984003EBFDD4E7C07CCA7A7DC7FB5F9F16E6C0C32CF86774B46C56BFE2840D8EC51E9FCB719DD1CAC4206372126DC8EDC9A4A2EDC8FDC8370C7589CE9FABE0DF3C8CEA90E82944B8D489C0F52F73EA3E3BF56BC3644A1BB0AF88F4B556A554851593E5FCAB03E235670638E4AD77BF012AE074F331F67222899694CB5EABBF0D6E6E6CEF75151FAFE89DB9D66DA4464353526116B3C2F382825B11CAB3CBD221DDA588F4BA13548CF627B52478F47D9B61479730CD9CB3F6622702C9A115D69EC232CBEB3FA88AEB832EB266B855A98424B2E08A699453A891C89C45FED7BBA98D6E7A2179A24D41D201C4214444BFFE6D01A15CBE640C3C54458E8DEA5DED484FF7AA78541686C60F9FEE76D1A7ED1F5686A2EC1F0AA037E6CE38FF695DE0C17895C9326415840FEDC1675E9CF30B8C45F8EACA1E65DD18290E8ED826738876FE8B69DC3432174151C051FD23CA4675A75E73F1D3DE4CE172FD657B57D5D03FBF8B29E268B3EBB8E9BEA96A4750168E8AE5AEF6B34701276DD18F1FEB01FFFA2A984D3A59D05A56552639D506BAB3021D507D56D0FBD80DC582B3C20940DF2393AF24FA5233DF073C7FF28B54C7A921949960CB2593AA4F93A06D38D896D547B28E9CAFDB479B7D1BA2EA7B4A6BAD33BA8B59DF8792B22F5FFF41EDB1FAA926FA3CF602FA63ACED78E85DD7C3094ED48D1F3381BCD084A9909613873513657879AD8599403A52ED0D16AF0B3B43C672867700167323D37FD6373C4D51B90327F4981A897CD54C8E35A6A5904F5AE0CDE36440393A59119437016E8CC88894B2A6FF661C10AAD7C7B03B7085B70A8145C305D5E66CAA265AB42B34539CFCC9A62B5D9BD09FA4D3B94BACE361B4C6BF6B550B89922EC01041CF05C0E4632274949D244B7776D6504C9803A67CECF65F750F9876109167CA77D412A7EFF06CBCF129D057143BCF03CB1C1AFAF937E55477F5B15020149D64F53887467AA16C6692FDDE61406D552660B88AADF65C03FE1B8D485C57FEBACF8B11C569622FBC56CA1056FD3600E1BF51084FDAE32876BAA1E97637F73677E8FA1462222DA72FB0936ED66C16A5E892C44093CFE7B4E3EE33F21091E04FC4A07C6CA21E93A500E5D7378EC716A9ACB27A5687BCD7F4559C32F6C82E8C06E82135ED16C35762E94BFD6BC33D5116E4FB209C98C871FA8E9230FA807CF1FD509A75DFDDFBA5CD4F131FF8B666878697B372B92CDDA15D0113E8BB91A7750843B3D14AC4E8C956B44C7A3A26720E774EC1A1F68435B122E539C8A7515A1AC94D456BC4DDD54839AAF6EEDDFF8797C9BA3A15AC70C34DAF78AF1F0C21734DA32A79C1BD3CC8B2636E12B9D2E42AD10446EA1A9FFD45430E03A78D8F38B64B64C9D308D18CDDB4D5DA13F1B4D15157063E58C36DD71677334B4D9BF09D8C765FC68B233B31105D0957F1B675798E5B9E982B1BAF1611EFED0E39E1E9E70BC790886A422DEFEF325A07D97FC603866C2C3682FC651CFFCA09B8122B636A65E2D6B8B9FBE6BB9220959038AEE11AA7003A9C4C4EC9E27F4A8350FEBF1084C292B6BA9A6E03C00979854CDFE566831B077823B025FD1B9C7127BDBBEF34186C74759E32FC222023EAC24A6A6653A7073F4033D77CF83831E8B6BC8F26AACBC3EFB2328C6EC35C3A509FA85E2E04532DB6E466BBF8071FA6020CF5585C70C29320786EBA815EECA6FB2BDF9C9F3A3DDD0F1800E93DEC3C5E6DB4EA5A695865303C48986CE26346B6CEA4A734668D5BED675EB0C2A1FFDBB9E5511EC715BB4BA3604629FA28A53CC0DBA1E819A521AF8B7BFF16B4FBC6766543C0111E232157B7BE4D561618D6ED7D13AC8817641E7AF77042E96C7209F1B65C42D115234F6C63B84D381F1820CD656C88BDEC7CD2A814D6346E90841005F66D6E36E63C5906D19904EA0D33502BDED36E7D77FF5E2592290D6F29200668A25A6B6F44FEA1D3EA00BD4BA165D122455E8F97EDB36061DCB335870F44068EE4A64FDE5695896D6A5B30D7613BD8C8B11DB330AEEB0EF239C105CE6C0B2E1BD81E867A2D823FF88E3E82FCA69923E281A2933D5FDFAC6B217D60958D18ACED57D670851D5A6A445A120F5B563070995793E618F885F149A3A3D498C69A0B9D99D92C16327B7568BA8CC35128500FF515273099B645C683EDA30092C225D01E6337AC652586C0872C9C5EBF09DFECA43697BD97B86FD5463F529CF303A105194BCC3014F4458CD3BEE8088B8B05D58A960334C73E1CEA934CA0ABB2597F703428EAC5DF6983A76A5EFBB4A20221E6EA04F67273D52D0311AB99979CB0EBCE738B0BAD72F0DA80097609F4422D962DE43D5B9E27F2FB3FD55DB5B9E98C1E74533DE23930052446A31E656E150261C6658324BB243E0C55C43BB397367D9E6EE51FF7A3F4FBB008F87FDC3448C07B88F4EC3788FB04944AE1D734E00E1CC58052AD2F908B55B39C0B1FBFB889EE2CF91CC1B3FCFEF11C14B083F8A898BB28B838662274B9974AA8E83579181944CEDA7FCD9C36D5FEE67522E828D6FD9CD28537D9FD57C8ACC7B8F888FAE4673FFDD859F6446B41609135BEEB20804F4331E31AE057171D27D1C338DD976634A460436977192E7FED668FF01B7F996F00958FEF2F89C78367507225C458A7EF81513D849081E4D22013A4A8DA7E6E9AF687918486E785E2E5D4EA5CEC4F92910E6A6F89198FF7911A16D7B46BAC5752AD5F7457E9B65AF0DB57148812FFE9F7C70F5531D11CF96ADF7A3AE1D86039FA5CFD5BD5465AA1649C40A513FAD60B54F7AF15A5A6B34F0935BAB28A1AF631816A0F5F1E53E1A7DDB5FCE521252E25910555D70AE1A309BB1BAFB7ED3856618161CB41206810AACFB9F748B06F6BB8ECA8EAE07B77934CAB2FC72FFDB061D5FEAC548CDD1BCE7CE5D04E9D2E4F38834AAD674F0D540DD6EEA85CEEE4F67B1D572597E9F2B66554F7F835894E81F4081EAB2578CEB8FA95964742436FC6741A5A9D1F2257572E7026360708EAA41D31ECCCB55811D5BB7648EF4021268C8AFF001F2D6BB3E1D4D304374E892E4384D66869CFFAC575398808D2042B2A33A874BF364B6E7A859BBCC67ACD4B5DC3494C1A6B55CE004A354C8EA8F14E9D9A4ED282AC4D78909F42BD38D044FBC1C730F921A1C678062A200CAEDB0EBD42D48C0B758F138EBD6BEEE1E45BF92157E3279C6534232AA6C361953A0AE37E81261832F29CDEE864962D44CC6C3C68C05B16915A8FE35B067EA754777725EAB0BB4E20C3BA7D6E75812C498F29A94D18D90D60F49339CF46DCEC6F0A546A90E0BD6E75B95441CEBC0B25945F2A38F3EEB1A9E20805A81E3008750588397A9A168C73C81C97FEC1BC16659DB16AD7BCE275A884EF801D53868B0DB816FDE421A9D7FE37E61B699736986325592EA93DC18B036D5B237115C35AE3862E355A1F3CBECC5BA89947E6E304A86196E0AD6A113BED701D21E07532A6D02D014C9BDEF9F9060799BB79AFFB218F3B98A4BC9488E5D2CA13531842C6651621484207723F41055274364FE30601C33663A6DA49C8187008BFDB1FFF4B7B3DE89F7FB0BF57F2E273EE84ACF8EE91A5335364BD034DB6A1F8025E6522B4F3D6212F3E75AB34179B21AA28FF6911736724FDD4F3229C6C26142BE5D6F2148C9BEDEEBE6C56B6A20746875A6F74CACCDED95179AF50E1C5E09B942B4E3C5E227C1A9DCA36F04CB89EAC24D5E87D07BB407922341590A739B825AFB80F544F2B1B70D877300B46000E660A568999EB8F54A3809D6879935492CDD67DF15A1FA902AE6ED30D5C5EC1178AAEA8E539068EA2A0132EFE51DA8A43E5D48ECD5D8BBD0FEF8F90288E3068D17EEF4204D639665BA3DB7C172E99913E97613DC4304006CCB37F1E9F62327E1C2B5D97E31822A52298BE0D6457708E0E2EF25A0C4C932F16D25A277C5BFE1AB13FD488BDA7BF30F26E89585F56D827DAFC799D7DE3BEF0B41A3EA3491514ABF11E633D7F4B8A88CB6F3ECA3D48495475A33C9107EF39157D53D447308BA03139C7A1A9AB4ECB178D818DB6F83B4489626E2EE9464D7392C80F8B4B6317095926370681D1ABC3A48D82DE7A810124099E375F39E5C6683F4972556FF258996BFB0FB81C44E3C0C1A814AFAE8CBC041D7E7EA4FD830568DE534B65926D6CB83D306A36861FA2874234E33F4EA5BB8AAE05C3DBAB96CAD63295D7BECC26F5A4E862546A166A09E059293AC85937FEB612178B8812541A929B81A090FFFBB17DFC3C774C5BCEA1398DD530C5286658D326D7BA7DA3F2E15FAEB038B8A397B68AEF622EB10B248DCC942E7BF4B4C942D33A4427B685A0DF2BEE8271E89A366708C9E48F6A3992174E8D401D821DCFE12099D3EF0BA0806E7ECD674422731B0DB2B198C495E9DBA6294FC736F41EAD9232A5E404A8E918A18D7A7846E0BB6716C4343C2FB00286049D7BD823410EE8F71347008A89DF42EFE049C61CEE782102730944DD15C0DA322F6DE4EAD8F9EA549767BF02BEDB1F091252F08B34B6728165B11D2C62805ED24ABE65A8E95441D1D5FBD361FA87B39135A75D749325F09416CD3E1ACBC04F6AC8B989716C55B06FC784B0254A884EA4CCE8ECB2EA278CD32FD1FD99C3085585201EE9492B7F7A2259479B1FF820661466022321457088B202B5F1E67709B763A3A945B19CB5A6EF0A322272D98F8921B775A37B6CF92F66CF86FFD26F84547BBA75AE82411E890A7D8F1B74D657380287606ACC8572D8522B87CF26C0247F25A7F8CA12911081224128ED444C5AED9EADBFF6EEA9FB7485884093C340CB326BD467CFC4F6E6C17D4F13C7F9F76192BF4A10F2F28F538C76BDC1F8528ED1360922E5A6DF1A38AF9FB28542357231478192219477D554507A47E9FCA585730292493A2B3EE225E0DF87C747E0CED460BA677EC691637F444D248805FA183666FA65110AD3ECAEFF59B2F8F619A275034CE415DCEC6E68A3530D17EDE27E93D87EE1EA55D22045CF436A34F907D35264116A848DF0B448E4BBE32A18BBF16A8DAC00CA6B07876ED0720591345223877E26D2DF4C0C3FD8484DF1DC40F1B7D4D49E871D8F527837F1B790CDC9FD95D698231CD090C60915C98F1CE43F7825613FCF8EC929BBAB9BF663A555210868653131556553F7A36368B0D83AED6F9A970CB2D63163C607ED896FC7342A71C6A1C90A53DA0F32141600F28F31A9340ABE97D0C6E8AA3270850B6598670DA455F8E2816EF82D3267D39A8163D34B135221D7D5D98069A8233802810C7605AF9764C6DB44FB55E29470503090CE6A720617DC9D17A5091CD3267DC4DBC1A2B7032B50CE46522A2FBFEE7BE29C3DCFA1FCDD43AE2E09DAE7330D2E6F2B15D10F53EC6D607066504AC50AA7F18D3C290296A8D9ACD1F5A3708BC035979CF03966E0081FC53F654AD68A15A3D17A65A768A4CA5F647BB21872B1ACC5BA3DDB5F69DC215735A5CDCCF50D555FE968551D507A7272FB591587383DC5930C5A572BE9FE0C2797B622DA16C6B87A03EA563845B8201168C45E7603B80E5780E493AE87584A40A09AD6718CDA3759CF1940479545789F08DE83333FACC26D28AEB54E2088934332EB7DBD5829F0ECF89D22C62636063532B4361B9C7C2B1D582E9A7DC72FF7F2DF667D9B7BAA543FFA20AF6BCA1A9CC22B7D7D177B73AAB087F868AC68EA0CA808EDE0C2F931B3B0CCB28E472CB316C0DB0367D4D7FFE0C02977CD2E5B20F28867DB1EE0DA77C5935155175B33D3275426C3CC5B73748426CEBB3ABFC50405E30EC21A53073C83A85EDB485B26AE7B633692326003004A822F261D5E20246F99B03D0AAE36"""), TestUtils.hexDecode(""" -A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") +e3204112bf82f4849550037d8b6325da7435333c716595e2f17c8a85d66bc4a612e19abd17411d3f4b7e3a8eadad39a819fe5ba968c8640243fb5d18a7674a3368099088c000a1c9906573a2957b57d5132fa2df9423c64e0f7d89a338d0d41e9300f563a82993c8e43009eef3fd91c10dc21bf4524dde27c4013756a1cf7b5c2829aa1698a5ebc4c46b80cce01384678f5c444648ed513a8e0c6e4d29b3b4721627c1c8832d736d98c17f6c00aee528abf0908b030edb381770e6d23a261731817b4ba5e632b1f77e5beb60f2e34bc2f16e6feb6fcf8605367b5d2dbec8668cf6a7b47fe5802a9eb93451f96e2ad72432726c9579cf08c4337ded15690a1906b82df1e07fa995eef43df8edb543bfc3a7403877b4bcca16aa105b625dd23e1d938d4d89293e841245472a0c38b77a6697923e213eada80659269fb642089b311e2818f8ee998b227a2130ba594a27e985aee0c6a3b34652b54581eea40f2c1e235ec06e055247cdc106164d6856fa8798e0da03c1b4a6b89778fef781dd6c5c77147db302df8ae78b819da5b8ce171f53bae732a100211cf232faff1e0588054a0ee99891a26f88b19fccb49693a844270fcb1a43f26677abdbe3c33261ebaf69f8f417ae6df03b55506c463088d49415c0e5f3d9cceea7518692649fbd2e0153b1612a84e229ca9a69eef15882d402425bad02039426358124d0603decfed2101e93876d057725f6cd131ee346f047d7e2e0398a5bbda6e1fc5029b57f78e49a49cab5febc682931f3a2b167d553e4f1b6511b8b07a8f62e4744c20a7b2731b317ebfa1e89825d4b7fec5c775243c9af25fef92f61261f2b4377593dbb3008385c92bb779ec703a7e76b785b8aa46c8c3a2bc5069d69ed865f1e5e6283f2aea3740a62226d341deb55d420eab001398596c88406387b293ebd1663c2bf94041f3c13b8579111fd7d53b66a3528d9bfbc6b97e72730a53ba95e0549473cb4141abca8c8330b1b4e0e0967b2aef589efee973c3718eef61d27b2a355be3c92f7654a6d33e5441e3a0f389911b40f6640080a752ca53ca9db239216dbc3d95eff963ab43973fd8633299d5adad7020a862a594c656e34af356066885494b1a02fd6fc5cb257cdbd56e85e74de7005f2b160f6ec6f0a61083bb046d9ca90c04478d8489cd75e176d027351a84bcb6fff940eca4fcd464dd577780473eea0a72732d435eb41d219ef7c2619400339ad2c30cb4ecd48deb40d713e148b474c4de28b91efef85e4f16750bec38224c0916892032bff8b89a4e0aff665ebc050e46cf7b7cba9fe8dc8696c5842f82e6e6bb6b58663e1669be1e4469cc8982650e468b6c9e5a1d49a44172f86676d9f4731994d74c4eabb9086eeab469a8a7de0e18845797ed73742864149d659df3118658f8cee2cec3c8a8b388432ad98d4d78f3dead445af3fd698fc01bb81d4658624312fe1da6465b7f53ecfa4e6f958b9f474711c9a2ac9fc8abdb0682b5eb282e5ec116c45c3236baba0cdf49a7478400dd8a67fa4704a8e98b29b7dc9913d15f56e613592dc60db932f374b1a0ddc46435feb7412b290587fd9e925987e80d155ff821e27d77de3141b8cf38694e3cd0e7ee0d822c213656fcb7be166767da6522cf9c1f29cf044efd1fe7f0d9e9df64c417aae894e354bad581a66432f4ba9b94226b1b577f64a931c62bcc6c97e5f20f0c53f35ae39f38d33600208a1c6986aca3bd143e920a430e9b6a311a751509316abadd632dbc82abc94ae234243edb75d362928f0d8a7ff9f7ba927780bd7bf62f3849f3fd937960ed08794f8df99dd27c241539c41d27ece05215f2e63e7305d09cc384223a3bdf8df83d0cb1f76231529faebaa18e76b35ef77d9ce6d2973ecdfde9ebb91d7fe2ff38bf0e4ba8f9c3efa3185f6ffb72a10bdab1fb829931858ca37e1d3356bb199d9e5d9d90b11339643ce9c528ff7fda54f907126fc745cffd1d9c60dcb92efc39469c70899ff3d5fdc6c18ccb0b3bf04bbd9d14b34c857467185e5f427b134c95622d34f3bb5fc4bedb7fa8e7c16abc277447ec511acb82de3d1372f63d9a30c40e6485598e707415a572a29ed1c82bf0e138bf6c6267380760f6f2d42040948e96d4a792abb2912ce8dfd5ad3c20bcd63fc84717a5b0c79bf6acf89199cca48e502661a949cb3123506318dcd0079edd930126c0e879cad817ee9faf22a49b11f44b0719554da894a7fde9e67ed576f562c787832b7cdb0ce85dd90ad391abb590cc33c83a57a1e7c088fef90937f39b423977eb5d48028af46a43d664f3ce89be3f153857210668a7f152d94aa8ce1305e5c467b3fe47306dc75cd2717b67f1bdbd77b7acf6d4bc79cdb65b291e7356201f7fc0176f826290cb70b54ee4f2442a658812274e08c0ff222750703f7127c72184fefe2cc8e6b0769c56eaada9bdc39d44e8464c3c789b8254919fccc48d692ee13e70745b790f5e89ccf04eac5708734ef847a00d4bdb4a7773d8a8e14779741b76b1a3be2b5bff279d8ea3f750c4ea5aa82203f55b332b785536e30d5448acc215c10a2e63a6104afc5d9002eb3cd9b98f76f66679766a0562a1e0ef9a69d46a453d0777046097dfe965e1b380cafbd62ba18753ade14c2a663c7ebe2fa88ec4cbdbc841bf49366dfb13162ef6d6dbaae627975d3f5d6ff47f7685c713c59dab2e0629d6a14fbaf1895526ee00a32405d2f4930ebae1d4c0ba243e0b77b0575650c1964cdaa8a09d70592a6e50f0586fa398009bd40a2666f0e9f4512fd9453e54df633b6ed72916cf87455ad6e67bfeb91e5bf15221e01bd61738f5e92d5fbb15d43df14f3355d54bfc97b061a1db68354e06d1a2fe0da4e1a6c0c0c593fff12496e42761235ec1238879a2c9797d97c833a76a3a65bbedb8012722c4c4347c30bab6d0897f9bbc0cd8b20030d7e84507cee4069192cae1437715c2179c6165d38b534c63123e9b6f07fcb4dc1c73c376d35d94fb4ff945d6b9f2e8f41a01ba5b58d7b5afac6f7f74d5aff530e3183a0b8992d2e885bc6c2d5415a572cd8cb8b5f09094998025b86eec33fee6f19e8fa5fa11cb49932508f066f38192afa3d11b033a6b635e9a32cf0dce3512a9d7af02dcca39c3c7d62861402586f8f08e0ca459e96f2767e991f70590a1303917476df719c38b8c7dbcd8f61e787131c093e2ba97cecca4d52c75e18d855c491d1bbf517542494928061f24f142fb8fff689635d57170be21f8bdb1944729eb2c48a66debf5399ca10d883c37c860921feeaa1ce240c419a987f71484762db1f6ab4cfc83c1bd9e4ca85c7730e9a58630150784fccf9faa926a28bdbce010a355ef4e8fe3bec648ee207e187fc3a8f73f80850d254cd0f9d9e92a0bf91e73d63faad0f6fe7908158ced03f396527e7b96ed2bcd521a5ac0e81fb60afbe91bb0e70fa6d5c39317158f67bffc160f0b80663267752bb5a9aa97d85d9e9f40f557a215aacc03d022341baebb7ab7eeec8425af176f3b97eb80351158095708083dd51d896bfc03d308906c31eddcb816ccb28eaac48bcce688a479dedf9417c950a7a8c95ae7b452cf83dc548b64d58b52928e2f6411d4b02466543e361de3db17d8994ef28dff206b493564876d5e274658e69b5cd70a0090d669a865e56e24150b57ea6d3c261b11c1e45d7bc387aee61add50c7f756e593de9c3057855ff761e95760813e5d30b41ad700bf544c451bc6ff51998bcf48bd6046d9bd461924121a3d8daaf3978f792d9cd23978f1c8ccd999bc79d2a10daebb3c9d065d30e970ace94a0f774d872c700949f2ff6a997c6e3193c5782c82a077c4524981e7aa6abb27b86bdc75928dc9599a1376a2a0ab53b6668292e4d34346dd2658fc9d10232b7e39ff5843c620319e530c71052952f75f2ab69fa193ee321c5702b6e3107dfb93b60cc99cc88f1fb48c0bf48c032e2ab5a3085fc9ae1f542f7e0abccc90b8dbedc9a2468da43edd62864be9f7f50149300ae6e2eba570ded34fdfbacdff6bedc092e49810a3e0e860438e3ef56f15dae6a1f3e01d1fc6624602a486d4f2494a3a81694971fad50647f1f0d2bf9e2b4580877b98917b22c55207689da27039b3e46e7f37bc785c338cd0519fffdf11c1bac606dc58f36f5a6902ae32391c7eeb9fe1251ea7575632aa86ce0bf516bc370b3b02ac8a66c2b82a5d69506211c5d3ae15d3c78d47df76babf0c7fb0a5ca3dea741dba47e67851ff66b84c8b3004f8862d6e8f6317c708ddcd6f232f78d081232ad98aeb17402a9ced35420a5e2802381912f9773d0d431544b7466f778ea3f379cd9b095fd51c2a3bb6fe7bdfef1188506047a31905a3a62ab7ddebd4c5655797b90e7fa78cc80dc7e9acb634da42540cb27720f67699e357ddcf45fb4bb9c8c555793cc885c31ffbf6674648615faf691440dc456126a5194ada986c9387e282a3e8c4efd5601f55273296dd8a351adb1e1f954a7d466e75057d8ef0f3d187cd0f8c2203967c7aa3049968ece39674260ec8ce49a25c87cb4fbdb73f1ad1981c19984c8a7fc6ec2e8dbf74889cf6ee30ad325fbaf3ce1be4d06255353742b14128c74765d32ea790b3235a3ca4a6e3adbeb39c26daf148ce4fbcb993b48f04cbbdfc88f67da205c910cc6d0c85b355689d7a5f6794990cd5a8380322d807f4282f79f2d2686deb4d598f072bfa2df4644c8f098a1c9589ee93fb48926675c7e1481de74304aadd8b104384f4df77cadf60df790a394f021889e098f960650e40b9f71193c642c2b28dc8e73934646862a9ed47763ef721c0c01be4da0de58dac976c7e52ac407eae45bf11243f741d05b90ba2a351d19f0d91d115dfb4626e2baa22a8d1a047b7a527ee81cc059756cfd529db5630068c8d5120ea7a6125d5fdc982f6dd91efa9d4f19891986140cc788285f0cc715e9b21f2175360b67dbedc68ff3b41bfbbd1d3adbade1c46083eb973876fcc9ed1e264e8213111bd18beda97fa555b1cd2f9fc8d216358fbcfe430751152c09c02a78b8437616d4326e6d9b87a71e5dc04e61ffcbad9c2dd9e2f9b28885c3b5383d968611de6be2655f24dd0cdf262e134e8cb9db1abb07d6fce167a9dd323b1b8f7232a8355d3ecb3bd4ba9a3ff17bf0d97fa29064762a6c9b7ba14b1264cbcd276d85e985926862c96e322308242ce44679502fe70654f54d41cc4ecfd6933df5eb3b3f2bc47d76e85cac79393bf6d77bba0164f6f06922474c9c1f9ab86da8051a7ceb0a29aac113b4d1430424e8e498a6dc40d46fd0c341b00a069128f37e56a25734e9e446a500e6790ddaf9acb20f5f67037b2267bae2d4003e1f6104067ce5a360e031cc604dc828c7ee79fb9aa5261e14f473d6b5f0cd365c5dbaeab2997624e705b0a09650bd386b78bb38cf7e5a3cd67aee3a985bf25fd1017d3f1870d726d4f211e0987e9251ed9dddc27f5322c68254850b4a4845f1610fe728092d34f6f9b55af7c167bd8f5939f1f5fecc9d1e375f97961a304c775c36bde5c065076245a9d6bc90c8476d958d00f5421f869c4109f6388a8c905850ef8cd80927b44eeb042adfeb13d808dc337b0d3eb738782fb4322becff76b85105e0e737dddfbfb423c11bbf3bf93aeda6af3634ad5d2d49b5d36aa2d9c72537a69fc0db81d8b033b82c8921b7d50a51546415e51e7e5a47f3c71c5da157e25ecb701cb9128400f0a7fe4ef801a306ee61c2cd975143959f7ee2df91fdd3678719597df544a1686aa9a81b81cebaf521deeab903c45659b270b5906698af28afeb37ced3362e43a0adeab50e2c9a2019f338aea7e29195ad472467cd35fc8d7bc8e5e16f86b273e5af3583718cd0967b32e39ede17770e77abc124b0879e997caf22ca684cb60ca3860f4f2525a989434b132c2ff173383c74582cba5dceea5d947263b6980eda24555a778e8d676d2570e5049d38f386d68b13ef53b035a83364d8247a6b32627756bcedf14c9dafaf82a4af23b232e37eb4b4b36f4bdfbc9ab5d1a963bbabfec682c548789b2ada1d73f283aa8b98ad214c7e509f5943daab0b54a5f9d94958a0e3887feb46afcf00bb0202794af85caff85580f7647fa3e0a9183f202487ea5ddb661416be051ca0da39769fe2f99793509acbfc3efa82318c69803f386cad629b4160a33b743594b0e379b7e9d483c2e5d2dee40489b306981aef5541a8639533f46e058b83ccc878600a43f1c97e36aa1a5b65ad3b2dde0362e35063d6ab2018e2b866ee1d13cc204a2949ec14ff98b36408392751962c889e975de56ac5bf00ae7df15768f02d9243685207c530531af5b4d838d63f418e9261fdb9204e14139e7890e290c047a795dd7aa9ed45a2ae86e0a20bb1489b2366d292b5c8cd2401c5039ff21b734600a046696d728ba8e4e9697f9ea7cddcfa1417272b61689d9fdfe5f95c626c92d6ef364447505e6188abd7e544838aaceffe14768e94a6e0ecfd4e5c6b91cfd80000000000000000000000000000070e191f292f373d""") ), new SigVerTestCase( TestUtils.hexDecode(""" -59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), +fe28a25123cd888c478aac1d081ea7efc0ad28c299b7cf879c70474654b0bfc8eedcc03981c72ec5378f14a215f090573a961409c287dd8bb9e17b83d8336b047bded3b424e69fb26e750f5f98a9864c906d82f1ed3f136b22048ccb9f3b35c1c184c7f2646fa81ee83701e854b42e3c6d69cf329f742155b37ee4796e5626681e1a56afa9aabfb79eedc3241423864e67e579ae2dd28927246935ae35aa191781800b4133e0e8491e134410da8b724d7b11719721a454e468eb33baa944c28547cbc9cd85b909dbda3c83671400b0de43dab70b1541c97937fcff85510a80d96cb7ecc9f57942d5416f87d0ec5bd6aa0b83ee64a57e64f88576e5560474db63c12166b62b62566dd79f3e4752af1539b09b4f71da54331b00c854e9a43199110889ad7aac60a224a58df58e997792627d4e22ef649ffd9e4853c39965c6a252330109a9148a2d257e6ae7659441abeb74e3528eede0bba8506b8c8e5be6d2d048c4163d161708b4d28175ffa2bb4d226e4510dc3da42c0d8b6b17592ed49f3948ce18ca9d0d8885c2933a3fa3857179f4ad48f6bc834ce21e4efb3a4c0c255b7f826b9525efa9ad6a1899e01c72c3ba4d78247e41b4387df8e664ca190ad641928e58cfc20b94f20b42cb2929c56f61057e85e638dbb09b8816948a95f515992a38e4d0d4419b0ee9884aebcd29df37bea8c60c59fd091453d7f816ba2b6173aa8a684e36bc79420bc640f3f6ea457dd7aa633389a536e6377ce182ab2fd62e610f51c135b549565d3c5dfd5aa83783399604faecc2c4fdfee1c383c8532a8442e004909c24bbd6dd15f2aeb8e3a2c7de11488b08f23453aa38f8689d0e2d80717f38c68128755114b151f2ac8aa2ff6d8f54770c8dc731074391ec6212140ae79c160aa2216cf183fb86f829c01bee4ca9eeb9b1a534a0e68000ebe4d25c5bda0d3e264f634ed56f1ed762bdca4577646344cd069c8947ac1050b62eb43f0ed7d276f5a1eec4a620f5f160e66b11ef24a7fab0f500c7fd1d5831c6d1994f871216c812bbd4eadaa5050dd2e59edb14b6095c51cd6715db572205a644884bc28fb1ca2e73ed5df2a668abc255032ea645c11b85ae3103119d3089875148b1ebeafba87b0560c22b6bca7f981263541fba14cc4416f20394ecaae798bdae4c15962850d49ea1b3d99ac6ae25bd803437703854f514f36b30e73fb59c97d8f542485a434b2292992e78a73d021f074a11a14c9f95e6eedf86a986afb81be2b47f17178de4f21c287f25600e39147608d8fc3d5d8cb0d6409b3a42feebe1dff95b3c588935713c2f7e8f9d3c0a0546c8da656910fda9eeb4415dfbae2f90c9805917698ebe7866b96984ef22f9db48c81deda5c17928ee0d5dd9e88acd2f5147a9d8281acac581b0a0a5028014decb33281915de058d53fc75932fc1a0d4e349c75a7d1313f9ff44bd3c1e9f057bcbf6c0f889bbb0ec75b967de1bc7246eb91c515f8ff5c2ba15ad9df662e29eedeaa1a137a4c1ae62858c583874ce7b4179372289e9331eb8ef3effdd691b8d4410977cf0962ab9f5fa882faef80a2d2334ddbcf5301770197a713625596866432e342f11f6bdb51c6d629dc0cb159c986c55906497ff751a532d922380c3f0171ce058eb25beea093df5e2a45ac8546d815ff08babdf1a0365fef8e12d59ae04f0cb6c373d4e213ab8386b7ca98891c3f5c6c6bb2f5396d131ec9a173a5c2e760cbd8840ac3be5cc21d837d44efb33412a572853782a7e3c6b8f438e4a842f7db269f7ea339ce80d2da2bcbcc8c8da5e68588e136894e4bee6985934ce772fe9250ceb70d5902a49efa797bb3fb0b7021a80daa677807332bb4cb866918892c7b497865ba4df6cc56121315f9dbbcb7d82c9b1986c5ed428cc257b4087a27f1d340bd6e22506985b8b456bd3d726113d0b190491ab8296ce2725a2c62551924b1a85aedff7c3cd0f1b3f5fd8a8b0c1fd04bb5606c3ee0b3a5c8cca67cb2da6ad7eb74be8db03e91f43c315d4fae4d93f71a8eb1be4a54c6d66d44c203fcec2debd53debd527b4d61b2bea59b74865075de444839ee09fc9f6405a0a91021bc328e7aa8cfbe77ac8b49e049c8831689f52d29a7db38ece3f04b994090c636cac358d215cd36f55f44e1f99675137e192a876571a1271e7aae73443f0b6185d918f9b1bde15d313c1eb3c71bb01b98ecd764a1cc1a7c54378be4e3df310cc0a8297283b94bd45a53f19e55c18396a902c906e2f4249b5213a76e547e10648a48498f6b6423ecb8ecdcd707889092f38c735d5b1255670d121e16091ee2571716497a72c4e851beddc42b88fe4ce51b7084a8e9eeffeebafc1bff1bc787b8b289d793e60502880e7c4625f4dfcf8d9e03cf606b0d08a36522a7707985a1dafc3e16683bf1e6c7338b9f5959d94be1e6b36b5d2fc7c5476270c8b4a38d6b8b8545a88bf34e91c765aad1f753b717ddae316df7913c6cc1d02fedded7ca47464e236fa9c627935b0df1cbb6b3f87ee6779afbda2efbecfa7c5ee324f7037e99d65175a1786547659a3d3e039d9b2dfd48b52a4b676d282701e62c895ec730df929c439cfa55831d13760291fb2e87e92fc3e3228daf16c93b3cea4da2a7b089e79d5c2698e6909fbceeadc461180784c83d5d6857e7cf50917143970e4515ad5d19a9d4836ba201e356566dd1ccf5694feafc9f6b33e734925ed69e82f4821e7359ce6c2b5d9fd2fb470fef5cb90336befedccea1a0ecc4236de6e980e584cdde0796c1118da083cf0b064e91898529c486774440b87af2cf8851b455b072f011b008fc9deafdac5d1401653a989babbb5e0aa14e7ea672951d8c87f7c41cbdbe66eb9856a54652027efc81cd20195a31106fe3dddd23671924c58cca3109611cd74e8b212058a616b4571b5f48c8b13ea3c0d69eccf41734e6cd2e4e1502741577982d6ff5b213275178b215019ed430600a6b940145031d3559a83bb9321fd89d98a3a382ac2e3479fd91ecf7dc31a7732adb04d28de1549b96d153f909eb10e024156c28842a3179aff185f008244143614f96a8297cb553141d967e675fe09873850bf28cec3eb8c519586c220be8f365aed6401beb68235d87424d9ca06806a5b3c00f7fbafb951577ce79de9dcdb7e30913815f695d1267e78f72896073f1878fedc4924f86aa6149bcf2c69e9c0df1c2aa17f95501ceb1d9f074fe9e41d474f7f6bf73d1d993975cf58946d02b9417b398464e9239bd446bc77493c9028916ac652692d80229d20172a4c6b86b4573b407ad836d0e01358216520a442dfc2b302f74c16e06a087f46fb40ef6db475754bcf778ffab7b8ef8dfad3af69fa91537c34da59e0727b13cf3d45d48a5af9586471b7db96cbd0d4fcbc5b699c1b549ad74f43ada72884816102bbb41a5063803c7aab173ef368815bb5fc4621b4ffc290602392624ed534aa52a1b51247c78e79edc30c2ba2ac3b0180693edfa1777316b6b45614aa768edee575a6b2e57b90a0137188e83b18bb53f693124c8c84ae595fb5c24841b8d1696117a5ae94b487cf3e56bac558e2c9569d71c692aaba10ce9afac91593d3a2bc9348bc26b8a8620ca43aa4d17fb28c475d3211422a0450cc0a4f0577ff9ede1368f3e2e8cac80877355"""), TestUtils.hexDecode(""" -4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), +4F4C7E0134BE5200C4512299D134770A64A76B73A82463FD8C86594939DCFD9DC55B895B32A2E96B8AFDB8CA83AB857679C372CD88754CD8A7B0A31D2ADDFD7D1BA64556AAF1CDD674F3E8F5FC0BAD2FA38326365918430AB2344CFF785D5F73F2B5D631DB29FAA0F9CCE5CB7FFE0CF4AF1C7A8950EF32F1D72080A492C7A25ABF67F409FF5D4B1E0D77268C0A1B2A32D9DEC61BB71EDAE6BFD58F274707182058F0E6AA31E6D3763732A82BD6F2C76647C7ACAAE7FB4AA51125F0D2D48351B6A3FC7FD18172FA8689AE1602C4EC0CAFA863AA98BDBB1CD8C2681C2B6C5C254E346C18E2A270CAF2606A6504D30C0E2E505C2FF9D18523BBDF21424C645AF0EFB2EA0FD21B5D0CD85C7C1EE176FCF904B481855C4CD739443F3340AE48276E7F4BDC00CD11C2B0D6B97BD00AC962EE1FCF8A73D3DA3CCBB3B72095CB33C5542D86E843641CC98E27545F99188AF064D5FE74739C54F5678F411D96A0EA043652935BFB2E37EC934327C7C841CB0CD04EC17FD06A18E88882177B51B00DB6EF1DA164245A3F2554CEDE8C84DD777F0B92CDA456D922D8B7B8B63B548CBB72CFACA540C0D69F9EF21759F243CFA03EBD6B080D23DD62945E623BC4F8323DAEC1215B251C35EA13A0F081B86E803BF37DAE6D913B7D942BD1C276ABEA3F8F74D0C8727EC21EED2AFD438BB7"""), TestUtils.hexDecode(""" -4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") +74bd615dc15e9ddf76b9f9bfe3092d48d80a2e8fe813b8b54d48297a3a3cc255927f7d8eb3bfacf8ba83c73455ef02ad7fb58606a401c0b29d8ee5c2146dee8824eed0d40dc886a5a0f4cb73a0a25c563fb78d9b347c1b0677d5b1f4fd9b01cde28958ff5ed00199921e2d72a63a4d5a3c43b9f5a47f5e80dcac8db898353bcdc754e89b0fd3279ef60fdc3114761c611f5d51a7c4ec9d4a3616376956a6b755d2e162db6df7c916d1054cc9e624a7b05fab4ae9080358497d8172b90bd2fdd8219e86663deec82ba86c2ecf63624c5d7aeee9f1ac56738c58dbc87d968fa3ee5098c51188169b188120015a00ef3a5bc03c52616cd04579604cc1affd3aa92270491673887b232eb65f3c0b2135157b6e57184b10f262605c26424cdf5c3a5694beb6a74ff252df89bd7693abc92ca4998d9c644cc737e8baa2ec6380d10154c212422c069c9d6fd38aca468ac10e08fb4e49b4d734f284c3e641182276a45be15cb2a75b78d52dc63799a5a2e4e800b30871655a507c2d0b6baeaaef0923d67057574559b87d8765a4c3f87ed76f1ab5bfd5eac40870dd7510b3bfcd84dd9ea15e5845626319e5faac3255bd9aa7686aef2410dba1221f67b3a649c5528a7f87f0ce8556e3f32d5c48622844c113454d08855d8a930b1c7d68522a9d284f1970f8944ed9882d515a877c21d3a85cc247da447d8005d72b688cd17490d88c9028c140f70052416815331fab6c073ed191288bfeebaa7325991edf0ad3520628f91d6aad43411e7ad0f8aeb6825f9b9d63b2f7d5c0f18c67d58634a9d85ef2a932cb231cac3f057656ad2c0e87a35fca332f132b68d60e39822409657c06dcc1cc92fae42a6c940c379e1fc61b6af60022a76e52c1a73033d6877fabcf9b17583aac80b5922148aa45434fcd0212634d5009aa509fb35e57905e033fe1026cfd4e227861d5be4e69838a92e070b96e61c747596e3bf27084e804dbf380aacb659ae79cc4c17f20ae64117088e297c82b8df7235974c4eade96a4567891eaaefdd7fc8ed1185a8ada618e440c4b85b698028f7ba29d46010d2f965d357a8b469281f5a2d3ad786092d5954ac780793f70ec4ce0ba58b2d755c590284c0062374d9a1453119d78b900b33d0ae9a7c2becfb014516d6b5a71da7c16c9215008cd1fa18b0e2d4b1a189c698e0ef49d230b7b284283b54cf907710730020e4c64a935ae5817803ea1f295f19464122c952de6870cef17bb4830f74e253ed99fc9d39618d1755003ce2c6434d5b4815a791df5478388dc9d6b3a72fcb326b71163922a7660304a9b9a0dc3a4df7f7d1d12fca8f3337adad6144add960229ed4b0de6eaca288ffd38a0a0ed6e0454e95527c18efbe3a3b4a18885e5f568577d903583ead64d60b82175aa2b19e100068bef823e2e8972feb348ec9f315b0a46d672d17effae1b47d60fcefef137956df1b4addad9587f6769269ba0d4e8d90090ddc2fe579dcca0980787ff8e41837e4306dda5f10d3f63762cb2f1b88558e749402b37ffa8cc75dec83fb44a6ab62260a15bc5f6e55eb7c1bec665ff4fd2a3d6e5360b3965187daff84ea0e42ebd3c33e57be120002e17e27d23cc5db3519afc91d9a6cdfb04bd7ee04a69ed087c4eab2ceeacbc0a0f4d6997f8471cebc6552bcb17e33ee72a197b5025b1499b1a19183fbca863b749758023dcca325bbf934fd1eee220e10ad10a49a3c5d861e91fcccde741b28ee26065812b371e25ade89e9a4bdb74956b9763ae2ed876b012d9c9e1278845806d9b22774b107443293848f2c510ea69fb45283ee91d08784c88f31de801244012ebb472b1a5032ec6c7404a03e6ba6c804aaa7aafacb204e3dbf5b9b7c455ad35a976706b0b217ddb0009562daa02a09e6a16484d4d85a4b5e5760b8b7e05c5310cb9eb1302447fd94b64963f64e2f182e5cac29ccb93233d43c398a7adc0d782da927a5978f7678b693d3c91988eee0c11f8614d351f48a3b35c8a5d1cd343ddd8f913e91f82f13922d84fe4a1c1599eb4574d1b1c3b0664695ad132627f8e24e0422caa6dbc0631d44244eb1025020f3018a14629eed3ebd1020b65ca21cc46480d958f67dff1926f99c7eafc6ff893dff9d804ab937dd9a5249d377eb2a9dcb8461c3a45e010690e8179343c8fdd033a2ceef78f2fb158087c93533d3b12b0d02417eb067cb63b3f961f56f7924d549e8a4ef12fbed383997e41ca1dc7ef6bc6629c947ea1a4750e3de3477c9d278d35f109f877d8af9dbf8a5be216b7a3511792efe170d79309910206de37a69877079a6d74b2a46192bee571b47e64a1458f590203789137bf3fa3a11defc15c00b976ee977e97a173502a3c13e01d1ab7c385f216ba812263096d0ef9d7c0c61dd2656771bae1edd5073e6a0e61991e4c163b5f6847231dbc2dbe261cddf6f31b614158cf41c3baa1e9b82bc2c4624f1be8322fb23f94912c2b89d82152e84f19ec84eab678fc79cb31ab6ffc25a56056066784fa5356cc4a39b33ee83f41ace4e6ba647d43e5717137c294093ba7c4d5d2f462d63b9ee0fde8b02d430179c84e79c168dec2e0a24578d067b6445972e0576cf5517284498e061ccc215898e15bfb1be5d8eadfdebe789188852a4e596474c0aaf581ada0f472ccd1a1ba6705bbbc6b938e2bf0b115557d73c3f456badae8422835bd12fd4f5a48ade113261eff298097c33dab6320603d813a198bcf6cc7fd9ccb78cdab417e6a8047e11867c91ab4072763d5e63369a58e8a3cd53258aca1c13f153c226a356b3c111a6fdb0bb51e5e6fbb400584fd4258bec8ad1b72796f0920a316564fccbd05e9bd5dd98552e04abc6a402ca47a9ed76bac30bd66df28aff95d7b86d95377349b7ff0a775b32dc5d6f726d16821c217f9deec62138e6b7b659d985dbbd57c7af7d6d0b8d234b47b122a02ea2813bfaeea52fac4100abe3567b18640f0e39828798b9788cc51f2cf987cd41602291195d4cd1fa1d1f152a2130fa6631dbf21fa1ffd933dd9137f7d1cc0c7fa133d3e4d04976ad8270ee85887b3d630576b45be5f2600a5c8159cee9154d7a0e4acb1bac445c033e57827908ae303d59564268f14abbf4b616e21b944c907ac9a30646f37d53b6d512f9c3212254d35e87aaced28d5d3bfebbb3c9e06c806a5b2ca6702e276c74d9900e08f8345001b1f720240813243c78aeaabce954018ddeda0ee6b1d7638e97b6d5b159984a901f297f10921a681ffc28834cf5b51c9fc761d327ee9585bd88c425459ab657095f793c8f07b255c84c5a0baf15c6cbf14335031347a03d11ba6ba49536d6812ec4e35dff2641bf4782f3c57d2d8e4b0d5d16b339caa4517ce6e8fe2f13f7d9837adf95500adcde6aa4191fd0cfd66f866c520ad3871f4f3bfaa5d0b8b3e1954bab44ac6b26713d2af52133c704d5237a32ed5e8ae69b897c29358c4a89ebc7431aaa97a031bf243e1a41658c8de7ba7e769e73b0b57a5b53cca25993c43f63244789e41b9be75859efb110390b8cda0aa314f96bc73b176d8cfe5f0acbbfa245ac49aeddc82e2fcfe9742c26a0f6128afbfd02ced63b67c26ed4755ccac4bb26963bf98f29c5146dbe5593d7a5b372d726d23e2947f6d98fa34454f6b9271a0fff5bb32a91b9140ef7e1751b3efe5571629784b271bac9d4b48c7fb0ac426dbd46dbf86aeb137a8c9b0d3025be5d71d7123581ddddac339535825eec433455a38ca8c6d6ddc59f12f6b4fe4e5ecb35bb3ad77a2bcdeb5315dffc072ba16565ae879e52e7652c9a45cf8ca840e913cd71dda69a81a09faaeb51a44f342812df6e88ddb34ce2e6a9a39b72d8128dd973ee94d6f86ac4b95af05940914f40ff800c3b25f3ef7f8a0261700415391ff4e9f8bca688b4ada9639da8e0ed0c754eee0e1d75f7c4e148971e7a72ab0233ee2aa77a4cfd345fa3062b921a9e49d444acafeb8c7796725dc84f2e5629b91f876fdfea92484aef3f28f9645973b47e9c607ab78877b035f64b8df0789fcab17f8d7ad2bf3a30bebd4233dd9ec3761bf23ff636ce7262974b332cbc3033c38bce5f9452dcfe3ed46aa3ae7c2c133160996e93a83ac01c4a50b0bdb0d6fe30c0d2b88122514aca33083a88b86768a46d11808beaef3412ba771eb77a17bf6328581d8213c5a7271adb13ee318f6b11624ac249857237d13c4308fa3aad7e148d0fe8b7a2c32ec48db9c2fc12fc536f5e9356dc83a8b57fc082a687a854ddb1aaace41e07845600cea04572c98a2a5482301d6c6e77be14bfb481ed5d36d9ead04ebd29e2c72f6855d4e13c58b338608923ff7ce5d366dfa8692b92c5356b6980d7ba133a979cc5f0e5fa066b575b0f7fac0e4eb0b531e404dfe328ee6ef263fc652a5ed151585d7fa47b11edba2b6ea5aca517b2bf5a38785caee5096354f4b703b8f2b6e2e7cec9b3c4fe09b0785734ef10555eca3e0fac89bc0293db20f64891f4b2773e2a2124e64ca5e5904c5d17e5d8dae7bd268c8a537d6fb7f11287a49e63e028186f9686b3bc6ba6c55a851f28804f53a0bd43098a63f5c005c4d3970cef231379a46561d41a94c18b2141843896a3644f1f19675ca47b4bceb6da613c0800c214df0c543dc6449831a7486dce0a6f9a349a4327209ffd5d240344912fe4315d9f38ed9e9995c814864de81e093517ab59e4ac5ff9d3c625c2e3db325092eeb5dacc6c3e5e3841b6df280543ab79b7edaa510dd39fdc44640b37f1cf44160c067432d32e4d83e60064e803a7c2bb5749e8cfb4c65f4fd515a15db304930279e95cbdaf3df8960f59ab547d527031d3d63d94d937a3115d3405e622a3f0a6c14c8aadb7464d5da999f16b327b61e9ed9296b0a8ffa10bf4ee900c2a3b55ac356f98076b705a8712613844aad76f961cf4829a1ba18238f2265a08c74e0f7ae875c19f70e9f73a328e48a7fd22e5657abb9b393bf766557fd834c6e81b07e1d1d92ff689ad1c794a46e6eb85f4d342caf54a0ed148ede130b7bbe1f1c2e868ffb20ea9c20b45f0311b352b85055d3e162944c91a89d00f2f9cf0e9a93743646379eacaa4ab3e54bcbce08e4ff015d0c424462c2acdf08c747fc3b7c7baee4e909af894c09395b570ae516ae687ac6d75c695b06fd8767b871ee41113b9eb7f5eb7d0d46d88369fed3148798736f31678d06b0d3402bb1577dc0f3f19a0a2f9d101a611d1b33ff99aff52937fc21d44e3f2c293d37b9a901ca71bcbe03965f2a458069c9dad2310b58a0c5662dc113d7ba619ce3e2b66b929e6770ecc3f6026e9ccfead7df2e44cd7e7fae06683a4b5c0a3a77bad76c8754133d7c548bee11be8cc084605f24668b294a6a0a633c7fcbf3822443a90477c8c501fd33c8778848f049a710971853bcbc2ae666493faa6426a96483ad0bcf8ed0c4ef0b58164b202650fce31b3ab76dc96edf271415c5a8b0414d7f60a51f01818b4e8c4df3f35f51f7738ffe534b2f9c2fe2acbf7c5e272a2d1fd4996ed30acb03abb0dee3e099b0430dcd620bbd639f3fb8b32d66c02dbdb262596c6e177d4aa7f74a959e90bd1dbfc061363870c42bd573abce58ac853b85766cd52724f158be47d62a90dfb5f0025e208c9daa5a386433ef5072da5d8938ed6683c7131dc5b0c66a4c4c2e14b04dea6fef564dac183478620e5c0ef74497974222f2788c84523ebc5391516ad6dc540095080042a5a52611cd4bc7785fef1768737ff1d9775a29a3a442f97dedf434d0fcaf2d8ec4931960e5ee03b91c6b16bb050bd9b64c9f8858958e1e6884cb916d6fe9643f05887b97f1696a7c111fc949009cad4f2ffd42f891cdb39292e9183b5eaef8c463a9226e71cf2ea4db2a6c66b7564b38aa04ab38d718aaa8ec5cceb4589e4f72e31e80910d209296e4342c65fae64b55be04a8927f0b9e7bab21f37af331218f43439087bd67d639bdeb92c3f774f7fcfb4fb33171659e00f03537983cd481895349a534395c40addddec7404c6adb90ad2a049ee457528a40821d4e57b94224d686a7ba70b5b2d35102b73de70870bafedf2b30ac3fb7f26679a2471afbe8f9c0f645e7d50d2d9b1e921ec8b84a1493e96e3463d1785b452a58077bd78708c1b54a96d8cb5b186e56cffe16f6ef668ed05cc0967305b409714679cd775168333d5042c9ca581c3ae2ef99e76fc7c42221c2ce3e138bc85e202fd3136c35613396fc259c4e223ea528bf7e0d7a48ee2ca96bb81e687813bf2c04dfde469c649a13816d3ea3e13b2f1fc1f6faf526dea7e3e39715ea1d6542e1a3b007fec2051531404040d929fa91c88a73ee9a717a93df44430598fa2d5922564a73b77651f24a4265c83ff09b25daf7c1b682da1498d5377ec73b00b408a4dcc9bfbfeba175220a6928623238412f1937228e9daf416a6c9aeafc06083d4d525c8eaf1f216299aec3d7e9ebf4193a42649fb4b9bbd7dd27367382849ae718394d86adc23270737c8fa8aebbd4001eaad3e4e700000000000000000000000000060e1822292f383e""") ) }; } diff --git a/test/micro/org/openjdk/bench/java/security/MLKEMBench.java b/test/micro/org/openjdk/bench/java/security/MLKEMBench.java index a013aa1bab97f..db87c24b48f33 100644 --- a/test/micro/org/openjdk/bench/java/security/MLKEMBench.java +++ b/test/micro/org/openjdk/bench/java/security/MLKEMBench.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ @State(Scope.Thread) @Warmup(iterations = 5, time = 1) @Measurement(iterations = 5, time = 1) -@Fork(value = 3, jvmArgsAppend = {"--add-opens", "java.base/com.sun.crypto.provider=ALL-UNNAMED"}) +@Fork(value = 3, jvmArgs = {"--add-opens", "java.base/com.sun.crypto.provider=ALL-UNNAMED"}) public class MLKEMBench { @Param({"ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"} ) @@ -357,884 +357,479 @@ record DecapsulateTestCase( static KeygenTestCase[] keygen512TestCases = new KeygenTestCase[] { new KeygenTestCase( - xeh("2CB843A02EF02EE109305F39119FABF49AB90A57FFECB3A0E75E179450F52761"), - xeh("84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7") + xeh("796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"), + xeh("91618fe99a8f9420497b246f735b27a019078a9d3ca6b2a001aec0b9e07e680b") ), new KeygenTestCase( - xeh("9EFF3FF8252400827F3B4389E4EC07E67948257C744278048C889D0789C5BFFA"), - xeh("5D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A") + xeh("60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"), + xeh("2026edec2070fd7a2aa93c55d26aa0cda5c16117ccac98cb86d9c99f5bac2cd2") ), new KeygenTestCase( - xeh("C6636E8C2F87DD52A7F165A2A3BAD562ADB28CF738AA56B996B6062E95F66148"), - xeh("7A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C") + xeh("c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"), + xeh("3ead7c9457670c2bbf1a3d0f38d6c0838098def05d5589bebee67ff5c33b4374") ), new KeygenTestCase( - xeh("EDE2E63FDEE6ADA2FC6EA906AA8D92DE87FA6199AC15446B0B6F075BF9F76148"), - xeh("6E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755") + xeh("ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"), + xeh("f910824d75a213bc1642bcfa5a6d304e4723ce0a2ca16000e66fccf48ba0a925") ), new KeygenTestCase( - xeh("CD568FB1EEC23C436C011A55BE2FD4362EF000C890BDE7611EB5C4618AB74F8B"), - xeh("37B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22") + xeh("78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"), + xeh("8908c5912b74c4f5d1b3043a95ea3fc16bcb8d85414a2f4fc134f18bbcde262f") ), new KeygenTestCase( - xeh("35DEE1F800CA85E482BB12AFDB882FAE62CC77A338E65CA2265D77243ADAE3F3"), - xeh("4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E") + xeh("917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"), + xeh("138e93b1f959dbb22c0fad45bcc828b4d4f07ea2fc109eff6adf423d960558eb") ), new KeygenTestCase( - xeh("D9502C86FB461300B8D142A906B766B0B42481EA9C83AAE2BB74390F882B0509"), - xeh("B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871") + xeh("df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"), + xeh("71668363f77b645c3278b07c0e97e7a3336421e624485f2ec35f34a01c9189d2") ), new KeygenTestCase( - xeh("07A9BEBF21C83F6E5417A73D8CF5B527568C903B5883CEC8347B4ADE73AD92D6"), - xeh("671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A") + xeh("d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"), + xeh("bdc7be9d2b2d3d8e7e616fe2f77f8bf11d4759b8247431b0e9220a7f8e5235bc") ), new KeygenTestCase( - xeh("F682949EBFCFA5DA31368E3F177DD146448D0E62178959FCBA4CD4F02CD8B17E"), - xeh("C02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F") + xeh("865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"), + xeh("1878346fc47148ba7523463ff794a14438c5b5e8500bb6b92b364f90ec8c3d36") ), new KeygenTestCase( - xeh("170CA6BB76C065255DFDCA3EB93C772E57EBEF8C9A291C8F0BC4444BF008C868"), - xeh("70567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19") - ), - new KeygenTestCase( - xeh("176719D76EE1CEA83F7751BC4E3DDD00868B5C504C79AF8730B9F7595E7914A4"), - xeh("71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE") - ), - new KeygenTestCase( - xeh("3C90FC402DA953172300194876B3B3BC958268747751346DE7134566CB8FAA5A"), - xeh("B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C") - ), - new KeygenTestCase( - xeh("24B783E39214CC39910799ADECE53B32408C19CD9ED10DEC039A9FA2CFC1CA30"), - xeh("4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411") - ), - new KeygenTestCase( - xeh("E4F2972F746E028108A5BB98EC97A307DC9363909DEAFC491F040B964675B9FC"), - xeh("9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7") - ), - new KeygenTestCase( - xeh("C5C26DF5BA8BAB4A293292BD070986A8063F736469F6ABBAB684F7127575172B"), - xeh("A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB") - ), - new KeygenTestCase( - xeh("EF0F6EDB707059073378E3419C8D9031D0732CFA931190EBD07FE291B1A3EBD3"), - xeh("80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4") - ), - new KeygenTestCase( - xeh("BEE40356679E3EAE8B0C3FA07C1BFDC8835CEC26CA194D5EFC4301481C256C0E"), - xeh("B923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6") - ), - new KeygenTestCase( - xeh("C6D5B35B90FA9AB9A7B438B57942D653CAE67B314C7FD152013B4E90BEF8201B"), - xeh("1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A") - ), - new KeygenTestCase( - xeh("5C6051E18E28FC5719E3172B967D25BB1649D87743440F7715E860AA212A256C"), - xeh("53F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905") - ), - new KeygenTestCase( - xeh("CA351B0F454DE9DB364E1DAB8AEF6E49C2E69439941935B24C00BB9952E65BB3"), - xeh("9C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C") - ), - new KeygenTestCase( - xeh("C467A43BF9E9CCADCE4581B53F8CA0B605583775AFCD0EBBB587907B3A813D94"), - xeh("97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5") - ), - new KeygenTestCase( - xeh("D732CF45D7F44788E17C3B6DA9987495AB1AEFA233F74EEF8D3BE5B6C0C04E00"), - xeh("973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3") - ), - new KeygenTestCase( - xeh("B670CEB5612A1287C4653B158A3CC522AAA1AA45B34A4C770DCA1E5BF3988F3D"), - xeh("D525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D") - ), - new KeygenTestCase( - xeh("3236CB10279681238E5B0E2F5138A7F743443379F5F1A845F3D76B75D2C2A9DF"), - xeh("9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13") - ), - new KeygenTestCase( - xeh("C155568B6BA74DA317388423F8FB28585977EB858EE306CAE4174120F02A8D72"), - xeh("0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7") - ), + xeh("741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541"), + xeh("6078a65f40993ee3bfce7804086962e5726025b779ca7e62912f244b4162a093") + ) }; static KeygenTestCase[] keygen768TestCases = new KeygenTestCase[] { new KeygenTestCase( - xeh("E34A701C4C87582F42264EE422D3C684D97611F2523EFE0C998AF05056D693DC"), - xeh("A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD") - ), - new KeygenTestCase( - xeh("444F032DD19AE7518C4B35B0732A41DC567845ABA8BD7B04A9C413A0CF2DE0B5"), - xeh("DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C") - ), - new KeygenTestCase( - xeh("092271D05CA63C60880AF404D60BC4BB9539E2EA12969581898D56E0AC9A5A68"), - xeh("5AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F") - ), - new KeygenTestCase( - xeh("BBF7574CF5F32BE49E1F39CE33870D9D6384056D60D223003B6B0C10D5C42180"), - xeh("7CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF") - ), - new KeygenTestCase( - xeh("D12CD9B65B7C58B2195AE0BE0282527BAC06C2D25CB0472628D64715F7F6A378"), - xeh("C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D") - ), - new KeygenTestCase( - xeh("79C006D5470C229AFCE7588546E52204B09F5086974865B426AAAA198C6CBA7A"), - xeh("E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD") - ), - new KeygenTestCase( - xeh("B04F631B330D83991B5C01E7F69452DFC394F9689632F8C7F60DBFAB92A9CEA5"), - xeh("AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED") - ), - new KeygenTestCase( - xeh("3D63BD6C310AFCF684292E5F8E1B98CC75B5A27B21526268444144AB24AB2967"), - xeh("6F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66") - ), - new KeygenTestCase( - xeh("249D48941ABC01C9290719FB34D91B05E774E70E6F0181E1783F2586E2499536"), - xeh("D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901") - ), - new KeygenTestCase( - xeh("E1CFB8195877B2D4FF3363BAC3B4E7BEBA6DC3CBB789B1B24215393F6C9BBFAE"), - xeh("A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE") - ), - new KeygenTestCase( - xeh("ADC4DA59D935DD87420ACEE52AEE19CB371FD0BB498D79BA680159EF7CE37C17"), - xeh("7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A") - ), - new KeygenTestCase( - xeh("76CDCA53F781806D55CA8D3BAFB3F4D389D712F1221E85B5E29D6A46580F978C"), - xeh("51D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE") - ), - new KeygenTestCase( - xeh("78AB6C49354A018BD38A39926F822A1AC4ACC4FF32DFD7C047CE0887A3AC182C"), - xeh("9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF") - ), - new KeygenTestCase( - xeh("13B75620E4CB9AB9A6689F6E2BE44639BAE6C9CB7DD641AC1C9377242D99679A"), - xeh("18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77") + xeh("796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"), + xeh("91618fe99a8f9420497b246f735b27a019078a9d3ca6b2a001aec0b9e07e680b") ), new KeygenTestCase( - xeh("7C345819C7C327AD9571E5DF882449DB243870D686A9764D4129B21E17AC86A9"), - xeh("C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25") + xeh("60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"), + xeh("2026edec2070fd7a2aa93c55d26aa0cda5c16117ccac98cb86d9c99f5bac2cd2") ), new KeygenTestCase( - xeh("8D6DF2EB3DDAF961FE5EB556842B758BEBC7ECB312B6D4628B323F483B77D6F9"), - xeh("EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF") + xeh("c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"), + xeh("3ead7c9457670c2bbf1a3d0f38d6c0838098def05d5589bebee67ff5c33b4374") ), new KeygenTestCase( - xeh("DB4ED8E9C3E1AC7A35EA4B67A4EFCFB46972A984D161F79F084125D6D4AEE7AF"), - xeh("26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294") + xeh("ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"), + xeh("f910824d75a213bc1642bcfa5a6d304e4723ce0a2ca16000e66fccf48ba0a925") ), new KeygenTestCase( - xeh("C6EFA7D5D500E5BF857D80EAE2A6EE6414159947FD4BE589350724FAE5E51805"), - xeh("63435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697") + xeh("78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"), + xeh("8908c5912b74c4f5d1b3043a95ea3fc16bcb8d85414a2f4fc134f18bbcde262f") ), new KeygenTestCase( - xeh("20859B01DFC60B6109E0234F3CAC7A247D8386099D83D2D447E9A21AF9DE48BD"), - xeh("8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709") + xeh("917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"), + xeh("138e93b1f959dbb22c0fad45bcc828b4d4f07ea2fc109eff6adf423d960558eb") ), new KeygenTestCase( - xeh("409E9F3AB58D736E122EFCC4240BF8388FDFDA6759004D42457018014A335BE4"), - xeh("EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7") + xeh("df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"), + xeh("71668363f77b645c3278b07c0e97e7a3336421e624485f2ec35f34a01c9189d2") ), new KeygenTestCase( - xeh("CE2CACEBD54AF1B4E71588DE9F22A6AF2C2E2AD7FD66B9FEC0DF19182E7F57EC"), - xeh("EF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C") + xeh("d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"), + xeh("bdc7be9d2b2d3d8e7e616fe2f77f8bf11d4759b8247431b0e9220a7f8e5235bc") ), new KeygenTestCase( - xeh("7E03015C5D55FD9888E730C1E60F90C5F6C2E3B1E8C7C08D869F0C1D15B540ED"), - xeh("17E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55") + xeh("865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"), + xeh("1878346fc47148ba7523463ff794a14438c5b5e8500bb6b92b364f90ec8c3d36") ), new KeygenTestCase( - xeh("8590BFC9A6FC25EE7E6DAB4870DBF4B51A1F141B7C9E96230C0403E799BC68E0"), - xeh("BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686") - ), - new KeygenTestCase( - xeh("D5FD815092620DC42A223909E387369A74AF7DCA285138CF217BC29F29C42C41"), - xeh("F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1") - ), - new KeygenTestCase( - xeh("D21D5AFED9AFAA3B49FB45245B2BCA1505E4000CDC29094A3600F5CAA49A7B3A"), - xeh("4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E") + xeh("741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541"), + xeh("6078a65f40993ee3bfce7804086962e5726025b779ca7e62912f244b4162a093") ) }; static KeygenTestCase[] keygen1024TestCases = new KeygenTestCase[] { new KeygenTestCase( - xeh("49AC8B99BB1E6A8EA818261F8BE68BDEAA52897E7EC6C40B530BC760AB77DCE3"), - xeh("99E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7") - ), - new KeygenTestCase( - xeh("2D229AB46354901491476CCE8FA96E4A5FBA65AB2F538FEDAA528E35687A782B"), - xeh("007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D") - ), - new KeygenTestCase( - xeh("1D65D0290B15903371D616D7AC3F2FADA8CB24E6C84D52C039A10BC1288C1110"), - xeh("E94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E") + xeh("796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"), + xeh("91618fe99a8f9420497b246f735b27a019078a9d3ca6b2a001aec0b9e07e680b") ), new KeygenTestCase( - xeh("22D19527844F3CDB8A342620A96E902AC7C36E54677ADA6FE8DB08DF4EF3B36B"), - xeh("EC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70") + xeh("60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"), + xeh("2026edec2070fd7a2aa93c55d26aa0cda5c16117ccac98cb86d9c99f5bac2cd2") ), new KeygenTestCase( - xeh("A00D1EE4147DD57B5E76C58A928DED0B720FB2FB6353780B380B5FBC76712E5C"), - xeh("5B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D") + xeh("c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"), + xeh("3ead7c9457670c2bbf1a3d0f38d6c0838098def05d5589bebee67ff5c33b4374") ), new KeygenTestCase( - xeh("2C34B1476753095D0C8A48A00136F358A98D1416E5069CBA4540C6E26FA3634D"), - xeh("384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9") + xeh("ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"), + xeh("f910824d75a213bc1642bcfa5a6d304e4723ce0a2ca16000e66fccf48ba0a925") ), new KeygenTestCase( - xeh("F742E7B69E27A57A43E1034CEB5834CAD57C380ABE259F432F96FAAF27F981A9"), - xeh("63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D") + xeh("78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"), + xeh("8908c5912b74c4f5d1b3043a95ea3fc16bcb8d85414a2f4fc134f18bbcde262f") ), new KeygenTestCase( - xeh("3BFC9A057D979EC03A705A9CC406DD8A46C106941AF6777B1D7F79C1508D7B24"), - xeh("0A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA") + xeh("917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"), + xeh("138e93b1f959dbb22c0fad45bcc828b4d4f07ea2fc109eff6adf423d960558eb") ), new KeygenTestCase( - xeh("7C43F2E7D9B1D8D9C41D9F315E052A254CE3A1F098671773B53717A95220AD55"), - xeh("681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E") + xeh("df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"), + xeh("71668363f77b645c3278b07c0e97e7a3336421e624485f2ec35f34a01c9189d2") ), new KeygenTestCase( - xeh("C2E1A3161F3734F44F3C2F1736E149803F71321122242A1E95E55E5652A91F55"), - xeh("40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F") + xeh("d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"), + xeh("bdc7be9d2b2d3d8e7e616fe2f77f8bf11d4759b8247431b0e9220a7f8e5235bc") ), new KeygenTestCase( - xeh("ACB7FDB596B44A88A60ED74A3FAD9EF745BF5BFA4902CADB891EC5CA45F685F5"), - xeh("E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107") + xeh("865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"), + xeh("1878346fc47148ba7523463ff794a14438c5b5e8500bb6b92b364f90ec8c3d36") ), new KeygenTestCase( - xeh("0AA4E8D918201BB98464963B076E35337FF3265810723E01C435954DB18B14FF"), - xeh("ABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95") - ), - new KeygenTestCase( - xeh("F43EC0E96A791317938761FFBE97332D5D85F52D22BDA6303FE7E7107DB608A6"), - xeh("177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9") - ), - new KeygenTestCase( - xeh("0596F1E214B29A0CB7A641EA0BB157FE01FAB73B4A9BCDC165FA44C8FD5FBF71"), - xeh("79E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95") - ), - new KeygenTestCase( - xeh("D7349F9AD546CFE9830E1197072B6ED9CA21E8E0423F145F1DB84A5AEBA230EC"), - xeh("EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26") - ), - new KeygenTestCase( - xeh("F05117E932CA0E0C202732DFD4F674BF5848219A76C64A0650C27E2E55095513"), - xeh("DDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440") - ), - new KeygenTestCase( - xeh("A405D9B07C5771A5BBDA2BE9F8A40D9566CAD7DA1761ED8076A289063DB4A8E2"), - xeh("FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03") - ), - new KeygenTestCase( - xeh("E66F17317C40783CE0594CFB5920FF86062591C5EA4254021495749642C0D968"), - xeh("08FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424") - ), - new KeygenTestCase( - xeh("F8CF49DA62AA762EC020F3766237520E7FDA4CA3AC11FBE50E6C5F9CAB3CA7B8"), - xeh("EB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6") - ), - new KeygenTestCase( - xeh("08E36AE8586A59B8249A80D7F43506F9711FA4B00A49D182CE06DAD0CF985809"), - xeh("DAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF") - ), - new KeygenTestCase( - xeh("A491FF48028B67A407F1054D5B1CBA733B665DE667E22596EDCC31C227C2DE1B"), - xeh("4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99") - ), - new KeygenTestCase( - xeh("7B2EC50C53A67E0BCCBA98C2E319F5AB46B6E593D2465F14B23FFA03D0E5BE0D"), - xeh("4E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952") - ), - new KeygenTestCase( - xeh("16858AA7C92EBD72FB8CCD0A99D0435EDB2A6EB1B936DBCB637CF43F25D221B1"), - xeh("7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC") - ), - new KeygenTestCase( - xeh("F788F3E21D62E74090582F310BD4FDC8065E56E8D946142B9B9CF8F338F330E8"), - xeh("4CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76") - ), - new KeygenTestCase( - xeh("A72608DF0F025B4FEE7D94BAE77BE94CB974F20DD55006A70FD39F3397A8EF90"), - xeh("D16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8") - ), + xeh("741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541"), + xeh("6078a65f40993ee3bfce7804086962e5726025b779ca7e62912f244b4162a093") + ) }; static EncapsulateTestCase[] encap512TestCases = new EncapsulateTestCase[] { new EncapsulateTestCase( xeh(""" -DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB"""), +c6e8499d78b750e516b8a67709468d3fa3b4d74c0a5f5a4b5cb94d8ca92188437040f9312aa41edcf274f0aace043862471591e84c0e05d61031d69f4fa11f4e8a0977673ab30b2bec0bccefe434b55632c6057842d977027ba616e6a7fec7340bb20c7331b4e2f1044e9692ab0136a0b285fde033ffb25543c5c9ffd83595e380f8e831701b1e16e040600c1c7924b6bc42331d987b7d63c007d76d198c0c32aa3e3663ca7606454a214821b15b8ebb018026aa1a618539c00d0a84c871c1baf016bc426b3d9be7598fd8148d63865bd6b455fb8a47562e95666e18405367d4cd581162fb878d8c0c3d627597a4811eee0963d4926861ea202d46a6a6e94e89b3cfdbf436fa2254f060ce6b80b4bdbb98da80417fb53eba8286b58644d8d84654fcae20906863fcaaf89abd992b176b05b2924bbe566728878b5e816b64a532ce2cd41f5a937ddadc15baf23023a19932b337f508c8fae504a3aa24261a9bd20701a2d3ceb3c72ebcd5807d358c2ed45d0b84092d6c93b74caa20ea4b5db66369d26fe64652270949a930bbd0103ea7d117e6160d9dfccded58476b94ae90036b68a40b9bfa61b15c889467a0a01342f843be8227ae9cfb1593c240a8735d8105a36c2b68e5ab97671b63a1cb1eb07495fd3bcb380aae66d20f3bb096b5db9944d83196b3bb3e321dc76c3b7d6828f366585f75a3c6d370f5580f22b385319483c9c19e6e81cc22690b18782c2d47be5c81cbb1c055cad84db9b06b15355697ea23a2374f027a63197b46f28a85d089a120848e94e9838cc72d1aeacf7d64ba69a93635c6a10ca5745645416e071a48056c78a50a0d4a60412966ab4961819918211a661cb839b01101798583934c9ce0aa447170b870306cfa02a16b9316f4f22d9b958a38b24960f0203cf2418495446c558a6ed8706d8c949e7b14cc168c965293d128ca16412ff7b221cad771d441ae3fc822d86645f5e266aaeb1df56a6185747e3312587d1b5f51e13e23586f9f3b1cf393bfb24173d7e27584b061f4258ff3c29d27167f58999b6b87a820b56fc7846cd3a0953aab07bcd256cd997b4e0172cfbdc0c2fef1b5fc616b03d1c3efaaeb7d48c64a0c839085160b4a5732"""), xeh("6FF02E1DC7FD911BEEE0C692C8BD100C3E5C48964D31DF92994218E80664A6CA") ), new EncapsulateTestCase( xeh(""" -49469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5"""), +1ad51d02065cbbe01bd1025aaaf94bbb2bac27e678fcd7578ef9bf3026700d711aca31cd4a9641a25286b26c034228cd906434c3e2a56f01b54a98878c6842b9bc9c8d95640bd496c0956446a0cd88d344d552a838e29f48850bec6b4667749fc4266ef8d5c47f8b21e7e108f8a58d44394c8711470ce8cfc92b2e49ea5b8b15772e4389564ac8d568b700d11eb5f83d018514d5d3acbd7c63f667ad9340b2dcfb972a333df99ab2dff50f570a4d0001a413a98f4075acc5241b5e6a6132551b9c4c1c22551b5a008df7d5a218783c2810b79a52552afa922de76dc4b89d87761cfabc81d218cc3259457316333c21bc9b650f6383c350e6681c694496565fa7203d05b0caf5a22a4ccb1fe7f00f89297f3dd02915eaa2a881cd41599635abb85890649f1a4710142c4aa4b5e3d71188562ef5205925652ae7606e30dac7099495ec939fc5b0778477be94185c649c858e146cc6750d3a1a98424b2645786681a1b1095979f2313228f96d9daba787a257f4e27a4ed3377dfbc71ccb9ddb227151203798b58f44a280c733a8aa8a631fa303b26c33bae7b088121d917268aba41cc797b7a3336f12101d5ee8900872b3a1710c885811a2d8c4f0a188d4352f259b62da152bf2a022dbb9c913c1c254a44287546c01053bfea0bbe3d05a24f1b70d969feac7c7325ba69ea981c5e179ad564e7ceb4ff38b824f9754af15664ff7a807bc34e62222217b96f364907916be6ef0cc99b014f3527572e0a6be517d2225aa6eb41e4c2a80aef4a212092bdc186598a69b4d0037cfeabfb13b9a9bc0019c5a83ee659100bd76a1da4b30b686ace6291877ab9d834a641abed635b8f3c536bd6394684ba283da1fe7797580924fa6a65e9de87bf833bd2e67c4a9e037aae0b3eb1701bc69add69127a98a5157a6b3f8393cd104c31a24ad3e381997f28c482c5dd6ec24d7747b559a29d56c0f655838fca25c4ad49e6cab35da559b354b55357748edfbca6122601a945d8611863917c48ba20d53b71909746723b4355a620b880cbb63f260ccb10db6d3809a96740ed153dfd07ba60159a3194553fa93ca28513a65b047a7350a0c6f43f7a09f3e2771f461bbba1e3508c8f8931c16ee"""), xeh("4660985A5838041F2E50381CB4E7AC908BAC83CC1E074220C6705E3F5FBFC2EF") ), new EncapsulateTestCase( xeh(""" -C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160B"""), +335b7558ac204e11a305d8b1526835e65a110d813499acc36a5409a15a8de46633bf587a706a7d388c5099c73adab17035a347b041cb82938da6838a11513c5756b3992ca2a40c91a450505be4cb4fd9625d209110888484033d09f8b60eeaca65330beee240f9861e768ac7218a6e41a1205f55b411e275253706c57b97ea650c6e69876f79bffed8759ce30df61465b4408a18bb003a7aa446642c90ea072f955f46044f4ed7b9a9b82749e56ad470b0d21b67b89cc7ac784f9dd016a9ca5d2b025668421c25a100dbc0328084c2e3367c022b60fc6206e40aab3a863ba8eb1f8682265af69d15aa9d173204533a1a7ad94f693310663212e4aa0e63f812f1608e1f9903f0685c9b9a797ea5939869b5421b87dfa1ce818265d5051038a9331168ce01971efc06cf02a59c9e1a03373a600f216f779aa73171be66f95d81808daf63a26cc3709ab58f22659ca9587c01029d915c7554946b217044e65a6c98258f6a0a2608a9cdb4c35a0e06c93b19988c221c96b79729cc227ad5c3d4f558062ca3179b8a0b6c0d6de0aaa466c498065ce690278b8980c7c567d308b181b06667f297ee9caa28ac2f5ab454b8045eea583d20993bf69359be500247b3a2ff0b95e243af49b6a08eb19c00f31f3611837cc64b85d8bc35da9466fc12967b158dba95782ab771c134f9945df0b02644fbc949cc633419c48643764e0679a690cdf0239b3aa49a58e171241a106c151b75197f7432cca3d6c133cca0a4902ed6c299a479224ec7baf4243152877adf3255ea114fa01a65a53ca47e3a6dff072d991730414754c831b3763a6673e9b8f4f7ca4d3891a33c542380cfbfe16a650ab749d79e08570629116ef7d50338f26834e298dec8abbcf588f37b428f211434666a1c6041a3a09918293fbff54d35c75c7dba2720a0a91592af264b446105bc5b41344067bb3e5943d62aaca4374f92933e3d4353f1898868d097e504cbb934cf727a9861169582bc4414e46c50c41693909cec50beeda69aadd6073fc1ca3e1a6a822751a404730c3c90a4ba6a9f4343988280eca4c4600b413cfacb8ce2823f2a2b96f56d9d1effc2d3292c0720e7bfe6aabcd8284abd8c3fe8aaee1bfca3"""), xeh("0D643FF311D83CEDCB3A95BA0F76216A49BCA389A225396F708EC9A51BF18517") ), new EncapsulateTestCase( xeh(""" -E868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354"""), +ae76c67fc7215e493c8645af1c58bec08b66f66a92346b92f873cbd646aa5dc2b9b6e4c2848a4324a8318e9983932055c4f58f42346df1da07977101434a9378d1a1559819756646eef3094b5ba55e33b596b71c04d249be4b8318a4becb008ed71000ae795ed1ac873e244beb7c4071047e83a8b3c6c2be2ab025726063175c4bab391597923d030b5a9238b131383d15dc2a4bb812a8539f9b0b0876a23ae049777e6229c1068a37ab13a2406c6f7ba4591520d8816ca3894bf3c601fdf493e70c5f4b19bead520d25cb6e8439a548f35cafe81497b297341005fffa18b99754cf199ec90504f9f16f8e415cba718318437aeac50ba8413e540b963cca2202a35e356701e177ab0dbacfe6a0c02b506fdd6436982737f903b8a8204cbb07c380340c5f1a84685392a2b62620004caea2c416e61f7c7b0e6e202d92021628cb4c10d57d5b60ba4d771712d552d1f9c6f352779f8c32fed54a8eec59f4b3177c7c3e81e3ab7dc83a396bbe38ac0fa3ccb174442ce638c6a0fc1fc9c426b5eab83d0397b559a97256b2b0817ee115b1e026c445629bf7a8803ff71aad99385a1abfdb22a3be0029503cb44b7a35847bc675f17437d9246cd104bd8608da3005e14a632d69006ed4434c80594b2909fe284203571eac04a00a120c24d050f40952fd53ac0cb39bca50c28ff450a6e208fb26bcacc1ccfa89bd7e05616a395aafd2bfa59cb541975cbe429919b32cae4b1f4a4b4b97858390c164fde76bcdb32b54b3325392c385d647b265578a1c56dfe5a252144ff1c02dc2054bb53525ce4b3bc2ec190e3ba06fbba12f06707f060bb1659607971f3726b9f59191e6e7b252602f51eb281f454f1d80a60ea29eab42752df9a3ce376467f694fcd288c9fc7851c04821b53e693208867604def746f787ada2097740ec8462ac89baf84c0d50bedb539ccab33894408c5b4b91def7955923a283677867a356b78c5a8eec308bfc982c8bbdc9e40d7695b42612ac27f6c118b5379518b49e338738e830fb6a66488b7115d24895963934688d91fa9608d41582e79e5d417ab07c81d39415fdbb870a3f503f1a197bbda81d7c3204a316392fb75016f88565a73a51537728ac7011"""), xeh("AA28DCC71FA83D9997DD733D8B0D0394D84D33A3D3E1B74CB74DC6049628F861") ), new EncapsulateTestCase( xeh(""" -76608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D40"""), +59851028c33af8acbc9ff37ab19a9fbe45a0f08b9cdc2268d6e727665429f16448ed840d0a87c34c3422ed857c69f3168820b0ae998702ac6f55150ae3031a54fb80912ba94fb4bb31604492f406f654855b447b39d26bc81b0d1644c1ce2a7f347c239cecb0cf89ab14917192c12e7a694581021e96fb6868282df0a4850bf3acfde5424781c571e8857cec1f3735a464ec74d859b169142e2e7413d2a02c5e93570e3b9bd18983809129724743a1979794a2500e04a409506ecf0a975f58bb0d08b36c1733927c932e7c73afc47f81b5a87f25878d327d0c375c38d2940aaa543f46b1198345fce7b7bdecad6ad22e12155bc470448f98bac8ebb96bb34b552ab3bfe5255c6783a76425b386613a112ec1dbadbf105ae0ec3cad61c7032bbe0bcca9d3eabf03ac6f0d4c5e500348f6581876e80c531197e62071a9454947b450614761ec95bb7072ab53e81d89e47eb875263ae74ca6a28b2a2a1fd44947756c1f3eb38519c9b2d6d63197e6459bd1427f992680b1a6f1480cdb998006a25cf434346d04942732c5617245033b430b4ca726b94faee24ca54919f0842233e1c6268b4bca31be4ca7be9b52851e2ac0dee573f7959eb896b0bb18064cbb9b71585a319c74b7716de398a8111214ae3130bac5b196e6734d3cca4116bbf67ca42492be22f56b538a8532c6acf4404069a329735246e5eccc2730c2f5690c53510bb2685909015874a8125178c7fc00709b2a6720391e38a0193aa96715f13ed628068ff4bba6e74c7be095a897ba3dc50f88b2b08a353cb4c4bf382a5cd72227cb671ed74227ce245268c38874f53299604c41f15978c522e865333dd0c49cea97289813a828ca76b93dfd3987da9726f0d3492cf13ea72ab8d4e82e73a3987b336f0cd2157de0b9b4209869412b9074736867b10fa82b34e5424c5998295b6a54793e9ab119e9c68049ea2dbef55e27327080c6ae71d69374b8314ce6110369b76fa363dfc201729a700528944f2bc23c464eacf51519f0aed8160d5ceb66d10c865604b3b4ab05f1c2990bf2b5ed84898b6a891ba360af171b051b907d1245770038e379cb727784b219a3c5ce49fe6273600219bcc609c8ffcdf4acbadcb9"""), xeh("A4BAA4C603DA1368C1F2AC552A331F77BF1D598C6BCB540D43CA1E6D4B8BDE77") ), new EncapsulateTestCase( xeh(""" -E331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6"""), +861927e1d996dacb9c04c630b694150f23aa51f26bed8c744c36a7916864b5160e94cc515ae0a03ffb445245c56a434f9351ab64f6bcbb973718ebb612657d64f844df3b85bd484c473a685a0a4a94e9995d865aa5bcafb7dcbc7e9877d63890a86252c691044df94ef7a19c68056ed6315400f8bd38f48abcd09e82f0376816c0aae53a9cc61b466466b63938dbb0b1dd963adae40802216701d094c716211718943b543cbe0888b1dc463c20804c4c402105130dd7a87a48c3c3328f76a8aef2b0c7d22688e7636b88d62897809eadf1ccf2dcb5a0011998099506925dd3b74869f931394bcae43466a49a40b31075f074bda69c0ee2f7bafbf81712969b43f0beacc246b3e71c9df2c47db405e235ae97e1a99c0365076b29e593b39c485521716967751025bba279f3aab85c6bae3800f255396d136459545f192b650d3b142c383669d2547cc2732015bc4645554638284642b918b5bd65a06fb49c5fd267a90b77ac35d12da3512f44d2556e027e6582529cea194df88584190480d9b0b5335fdfa8685894514cf95386cc1cb63131dcd1022f5b568cc621a729423c0567a51313f647918368012a83816a2caf88e062a9a6064fb52d8b31abc270a01d974459b4134be74c41b6a22e72ba1c993924bc43be6509235298431c72943bbceed41a84f9b84ce21abcea516f32280a0586069acee7627b54055515604a9ba112e620783aa76264ab8136759af9dcc75718a9bac22092a645b1b5cf32a92e377ba03a6117ee842172505793f973f84cbf0fa22d3ce116ef4c1012bc69db94c7b2b461d978c27c93044f22972588af42e28dc3748299e7a098b5566d67110a036ca9c6740dac84205109f05104f80585970a7906d7bf93067472a34442780f0fd25729745c7f85198a753836c3381f0592f818916b48278e14b61f1616c32ccb987940550316462257f1daba0574223ed6767b9c696b1c01ed75484c1738cf60afaaf9b3144899c4dc00fdab36fbd792dbd4885ab3af6ed63f8394b66d0a910041b1d606923858432f81c37f57c146db8dba6775ba1899d5904f3a69abee80050d6232d858d95a7bd86ee6af48bf9c372170c7468fc024cfdd552fb21ae23b08"""), xeh("C08584D2F5C950E371668A4FC8F527E20AF1532CC28EE6B5620729155B06389F") ), new EncapsulateTestCase( xeh(""" -83B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5E"""), +ae13099bb82ebe29ad44859860634d62f78fd6b26295d040f8a5c7ff7aa393d127e214aac9107ccc06d029da6a6b998736710c5fc3a6c9ecbdf00069a9eb2942b45b1626b7953886248caa59789f9e988fa26073bff9b703232859463a9335374506ac57a8c2936701fcfc0235d071bf9807e907734e6267d130c9d4b2406e999b6cd15adf7783db2309598c058a93ac043319194ba89857a59eb35fe4a3cd6fa1c9d7d46ba2f6c62ba85ca46cc8d450bfb0170f5ad6a2a0388ebe73a8b58627f6cc5e7477635ce32472a87b4b881ca9fc749ecba012187a5bdc6e9e12b668f32786cbb5fa4055f86590e00bc4340c04b8b0053b189a74d6bb22db2f75f6b32918c0c3ac7da62044db4a9c1c2b0b1ee81b5317b1fd734c33fa3733d7b37bfa36c16578cdb63cc6f73d661a35e6460b74396ec6a07111091071a757d962384940a1a2338a42fa68e81587fca304d8a86282230470c8988cd707437163cd46cb489b010d235fcb976e50b51e0a22c5662800e74903b403c025bc6df9d821752107b2e51874147645687fedb108c1894e0ac3801bc1398c4a187bea7d9949bc5cfb8368b296b2fbcf2b59c71321b5aa2055e5823f86113a1519c956d9c1793a5d52a906a5031e905a862fec5abfa0965fc49a2db189eb6bc69cb8882b703e0ab35e088340fc35812bc0a184956fdb448170a6b32b49ac0e2a65a1041d38d4512dea3fa111c7e428cdf52144ae0708c5c44382a0733de356ab556e0aa141d58cb1321058be25a543d7060252c9e87997c35295596c02bc7b926f5ba05675a5dfea5a3eb62b2521854f21498c428a23048fa38484935399bf07c64fb63f7ee793a63aceb6842bf05077d2b3647714332d259576182f0d9c508cf2321f0090a6c1cb0a5c106647101277a7b1248e74189df6b90c26a612b26555d433bac49a3ebd702e6d9649038233d6da01f77534a8d2038f615a502cca8526c314c5856a033ec97155ad79a2e2a32cc1e734cedbc6c0b94219d13bf985588400cc682294bf21183830b2bb51b87fd9073b9cb6237884df0cbb12b929f81448e5578928b07193ea4141d19b4eed07a956c34b6de59127c5e823bb8f6719ddeaf282650cfda0e26e57"""), xeh("1D51A0CC52E85972001B77047D97DF5F47AE11FFC6C31B4AF42FB0791A3DB40F") ), new EncapsulateTestCase( xeh(""" -28D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACB"""), +d0f903b9113e3b18442e9b125dd762cc4bc2fde8007fca65b4817ef985667bd62bd8806563846ddf61b68a837d35859344e96ac450cc24303d9f116d502135369305a8cc8549641487f88e0f24a31c87cea974547abb569f9c312dac3fab517c85a5521d41b7eac40c62b7cb8a0776d89828e937177785a23ba0599381004c253fc90aa8332172f7366e6c756e6f266f2c5c9bc70a5cf18416c00c83dbe76a8a9c52ec5929217c0d2be88c8e3374c2111c2ac46a2a454ceab38f8d368f2281749d4109e90702bf368d6ba6ce212146d7a21a9ce6767fdba3bf1708fc359fe4e974b676bb9ee04db18b93f60759a071484c134e0ae29b135c5f2546562f6a471a826aaa3568bcfc721d707ccaf9351462098fcb21b441c81f876a7782363ef84eb9c59b2eac7f637ac205f0c1ddab4bc0868f42c4c2ffd0912a0578e9b81dfdb400a6a747c9bc8c97ba3ff8074f454367a5768d48653cad01c30212997553941780b44f3b26b9b79e6bc43cd56683dc9770a1d81ec0601e66326148f8645f820737c2479533a7cc3142341a2fba851cd304423d835bba5c73c3fc617f393e673591040876e670b94585902818883608a773e736f52c496691481b908106609366513ae14b618b8611539b56b3f466f13a5f59e5179fd29ac4ec7a92b5beb004b628e7701b11681cc61fd088a031d80d8e43b36042857155b0c5f207260bbbd30146d83a9c3c17a1bd804b56c96b01e71de75152f4b4990a001a1d8c736e39097771b819e58a2bf4498f1ca346cc851efb29c1551060998a7242c7fb5b04b6c8cf2f703056f18a9df28504752be88860507b1aa517914b278b61704f2e33cb02307a7a898e58a3a87221898cb57243000249709f5e53037728bacc7027dda1b7fbeb7739375811427b3f8c3dbcc0775442323289bd89ea0b668cb458da346dd25a45d4c9d6eb6ad98645a65794a795277480382ad7a99e85ae9e279ff5d38ac9a461d4a8aa2170136e69bb70c2c7734060421388330606763158f0c04788d79ded7b52b79abdbf891c2290b561ab4a6aa02e591637cdac7353798d9e256fd0286389f7d3b079e3e9f89ec0a68010202ca26dd2ea953f551554098ebaea56f782c3"""), xeh("BC2D661E6283B835BAEE160D1448957AC2366DCD087176E252F81F1D11E28781") ), new EncapsulateTestCase( xeh(""" -70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83B"""), +ed8034619a429573756962129b459916f158f0ecb0cae396f60c4c84670ce3fbbe119055f1a4382cf2a619c31cee5842ee8c9c6979193ba82ce9f94337306186b20a276c6d06c04f41a414c3100b31e2a2a9984067fac4a7b3c70747c55b87b2512219d62c8b51a6b628766d63d1096f63bec8806311415919336bf9d1b038022d00d1bb84387888dc10f0290b752627c2d78ca5c8475150bd925240ed94af40b43762a99a3f5b0f41d702db7cb485405d5a247ff48635ba7719aeb8a876f0986f233212c40a3645c3e4ea3b5fd02bb520b9d8aa22c4595849b8a2769b92edabb4ba1528dd067aa86b3bdb6a39985983c89c9c916b41b34018bda438e7815bdd4316f6202c0e3c73d53124ee110ee596a9e3198f24b814dfd77f0a2a7aaab3a918b64c47fa44ff018332557cd13325a8081e0002096e68a293258928896532ac5b0ef4bc28bb43f68505f8a61cde0b5ec9ca8d62c261b5290e16b22a4a978d5b141240043c9b457a89a764d9565067cba987a23d5d6b3016291fddac50c9e5581d988088a368d1c9c633bc594d39c56fc5b4a996b7c110208de1394559915138b7cd8941daccc7382b60b47770272a56f846b15c71704b8b7e08595d51658a10b348617c8b552588a20a07c6e0670416636ba0982726671d796803320e0346bea80578f7808419f14b8be67f8bbb627fe4c5c28074e1458ba909581f317e70a66320ebc5ffdab20202143f374742b77d88c80fa8b9593d74a04e2c7113101400c4afb7893f634565aeac9eb8c144a3a172a1263fbee499d7895e298b195d4caf46514927d39f430aaf13c4bc43735670e5b0350a42506621dfd737177ba3736026d314675947a1b7315844da146af84c4cfa8227bc3211895773082fa22a8c9e7c20d1257ee9577c3f36a6d3097212dc1b149421b9bab30124cb3298a6b1505bf586070f52aab80a71e17c223184b32e9a6aa4627b3b99bf089973ab53be7c461ad57317edc3b79872bc50a391a43bb18ee9bf0ca100f16409caf4abbe0239b98b16a598ce86e7c07b27646de1671e915763ec8dc3c09a20181e0525c571a18d74c74c0e798d11d22db509a0f0519c7440e6787efacb39fb35c8cab4a38302c0"""), xeh("6745F4F0730AE3F14A428A95C9CDFE82717EAA94F65B00A01566A4DCC9ED1E5E") ), new EncapsulateTestCase( xeh(""" -5E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D"""), +e782aff3f25dfd582912a662095a71ab2b81a7b88a0a0b531d0c735e84279a39713e9b78a39679cf2aa956a0bac8a8b8d6330eafe18a20890492b42ff0eaa210a97f931c8c66a4bde05ba317aa5a7c1bc4e7ea9c8a2aafeaea6216d03dacb9b1e17c30c49a58a5d21a05f37912dc336b8739abf4cb74455078655b7d6644f3d5b91f3a97b9317676156dba77747b0cb2ca21c87e7cb0e3238d67811f4e229ccce2303d358164e85a5ba766f91212a8540e800a6e5b829bd097925a01ad99f8af2b8c7832640c0e64cacf5cb5449829ef992bed3a85b3d86fe8689de552acd1b47f58b883e718c61b810a02563484e63a951927210cb5b1e740c1bc2132d026bbb8a9b2099922ea44c2445bb078cbd0accac1c22c0065b99601c07cca67ced147645508a50ba8e7a0012394cec77880a4916c653803266c0635741fe0c98812f37265842e6826ae18d4b27a334246520607dba4452ab7284300f96a01ce809cb4011df18940c6460c7a33aa34e997b89846a287af180ba68f170653e065c1475f48b9763d6bc2643269631729a11aa33aa32a14525641e4a68a61967326698be67d0fd2612daa94dfa9a5bbd3b87bf57ef75639e3c859ba8c0a90f5ac131c94a0644eae3c32811335401ca4c0994df4711c30ca05ca812667d47a8f96beb0a270f75ace7cea1047d4abc944cf71042aa092a041fb60d60976b0ec120600c79c51ce163a6e11e1b972e703ceb5c792482b01b7c617d31922f760e7465fa427ca118431727bce77c12c59b2a7cda287bfbba68c57aef92a4775c6602c87330d693bd10a5d21724ab58bcf03220a14c4463c5226b86a1fe15477e662ca03374287da5b7aa118de1255f574220d0bcc4f68b7d36286761c9ad5d9aebe422b26e95f1f5b67bc012950572374fb8e19575b2a7b911bdc8130d737d4e34ae721c76d131baa9a2f47e208c668215fc2c56f80b16a75114363c3a04918c0072d61f19d22e55d9d1cbfc9210246e12a530ab7c8a7633ca37b20789125573f866b94d872af914007c3ccbe898ba697f63d15b57b2aaa10145c5bd71966d54bb8728b531c87892711e6c0f2f1b554cadd3cfba90def490f706c74c451248631333f0b3f2813fa"""), xeh("C3ED79224CB07A8D37DC9C789BC7AC8E278968E429087E5B2C0E878934DAA53F") - ), - new EncapsulateTestCase( - xeh(""" -F3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B"""), - xeh("41C74E66327238C6F7B2ED2683FC5E88CC35083512BC285CCB7165499F34A0B8") - ), - new EncapsulateTestCase( - xeh(""" -A4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0"""), - xeh("6DB6A3F134471A89ABEC3384BB48A3C405DD3B2A5EF53821A3C1EA74DD562799") - ), - new EncapsulateTestCase( - xeh(""" -34166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B"""), - xeh("121DC782B740EAE666E709EA6E3CC6CEB8EAD204CD7D85D2256839E98CA57003") - ), - new EncapsulateTestCase( - xeh(""" -F3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1"""), - xeh("307C7DF0692D264A8186B8D844C7287B236D0FC7EC148BCFBF261A16B0FB7B61") - ), - new EncapsulateTestCase( - xeh(""" -E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A"""), - xeh("60363F5CDB16BC516A1367DFCE1B72926FB2189B88AA1DEBFD22F440B9CAF0C2") - ), - new EncapsulateTestCase( - xeh(""" -964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC"""), - xeh("579474C123B3381801867203E0021E2B7F15E5F9426D75A3EDA6CBCAECECCF43") - ), - new EncapsulateTestCase( - xeh(""" -87EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C"""), - xeh("E2F0D46B6C4A43E94CF967EF2BAC7B68C6E0424A37DB52F2BC0C1695D1A66B67") - ), - new EncapsulateTestCase( - xeh(""" -FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091"""), - xeh("7B34969C65DB28996B6F9C440DE09074CC98DB4F08BD43E4CD948EE4ECFDE8CA") - ), - new EncapsulateTestCase( - xeh(""" -894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C92"""), - xeh("4F7798D88974637071717FCAD2C0ED5333945D51341FBA4BF1962A3915D986DA") - ), - new EncapsulateTestCase( - xeh(""" -42803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F70"""), - xeh("E20AC1D70FA6A2C8A286EF0E3665C79668A5E6AE80197BBF13A0D0EF553ACF1F") - ), - new EncapsulateTestCase( - xeh(""" -39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF1671"""), - xeh("AC25F29AF8D8A2DBD359600C8A500144D6C0236D729DA016C3F116CBBF621002") - ), - new EncapsulateTestCase( - xeh(""" -0AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6"""), - xeh("7114A4B4195826CFF174FCB75336B25D4D1BF2224D585014CBADB0C4CFBF7729") - ), - new EncapsulateTestCase( - xeh(""" -F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7AC"""), - xeh("C78E7B1E5EE8F20EF0B67089306E1ABAFD15760B2DD2D7A59D2C00D496FA0FE0") - ), - new EncapsulateTestCase( - xeh(""" -F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF401"""), - xeh("D23A22F6DE6C0F3C28F5A7A8E54581BDB312A56BC90CF3B22A5BB39C9ABF420E") - ), - new EncapsulateTestCase( - xeh(""" -305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA"""), - xeh("C0A5ECA859643D0134F2231C8F3764044B7E6073C92C9CDF71BD64FBC59ADDB9") ) }; static EncapsulateTestCase[] encap768TestCases = new EncapsulateTestCase[] { new EncapsulateTestCase( xeh(""" -89D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C4"""), +3189cdb94a4e3048a4e18621c07578243bc5c017af25da2ffce6abc3194c510076b1d0c5b5529a80b3abaa9658de03ad1e151751f54998fb77ac52a2739b09c4f0ca0b8827c04bc280ca4e7d214231547370e98b92006270194ec3c79e96bb16550692f988627b496ea4f4cf7e9511c014c2ef89ba9620896785784fec1da3458a6f5a11d3840ba4f8714610200d3a276679a7e395488d770cd5122d17b37652a9871357594a87662aeb3befecb0e82513ab90b414d60c66fc61e4db22a2a3668c05338ec86018f154c929af387183079a59e201cb512536ea4908dbd559dbc63aae57cbc40437b0d5b54e784cf7488dffd5ae861b86e7b8a57563abf5f76c81b595a144a11c464d17e6b871011f8f82a8851321f2455644d0156ac96fcc944a0ad89d52f896a2e84f5d4a146e61bd132248572c27d823142629337e116f9635a32f4647bbf2b281d6c1058695b49b51e7f602466a107fab60edecb8cafc47bfa6c65643c662026f702ac7b7118bdc6448eb65bfdf8b9eff908f354410c77bb689d9b557439e9704c4d4107cd6559d1cb5a9a10b83f9f24d3e7418d3781eeb8b07cc8c5e38189afaf64db11b20ea072674fb42c3487d74c392f278c274da80f7518f983152101b1ec941baea92c132181a9442106be237198401ce1b652ed41e8f033c3a364519b2a1edc41ebbb36529440ed398207e600e3bd2622d4534d7f06013047b41a895444947ea252f13d40d0b82b82c0405bca2454a8823a0789468f845441089e18cb89f940519756628a8c61db794c9e86c3c4820b61413b1b88af8b20a687524ccd51fb9eb76eac8b958501342c19eb3b6210133c3848a4cc1b2cfa730cd99dc9e5635b3560b0731e202453b31474bcbabb626204ba05b251bb5c63f85a850efac7d3ffc0c8e161d014a441618be32c94d7ed2818e41acbd060cb9c5b43226c05553b5bd31b310fca52389361b8b2389c952e6a275d17408bedc24a01897ff484012e74545eb099fb0620fe7523d7b49288773224a72a01b198a299036889a5d690b994abda1066072f3566a33c944550880681f716c87a9ac546ff218ffbc8ac48a8efe2b11c8c2ae3bc0a76de2173cfc5af328929d540561a588d4337d1bf8748f71140224c2e4aa458aa2958b236a6c0c77492a307f754869d9c8385213240b7a1cf70b3f7aceccbaa50a134064d64750ab5ab35982ed596913d84c74a8c63647a2f5531247373ebe23695ba767d0eca290b94647a4c94e3949b7337fb7e77ff7668f695b9beb8ab87723a58ca62efa3b75a6584768c229f18a3c26ca1a4da72972c02a9205aa08991873b94fa1f995ea6c67b8a015bc3b7a77943435cbada7323309dc74b7a92c92127b35c32879567d4e389fd5b5a6c23b932108ce22505d815c50e8e80d9dfc6c3640b111cb9c5fdaa28d199a00e405f061b6cd601bc602a6a491cf900937fe566fe3bab921c09091152592f6bb7bd951eb960708167d08fc60c40563173c45a76188871c696ce5585dbc66c65906d1c30f1be660ee2560dd6730fa4ac1b0cacb9fc05a17fbbea5d47e1eba4999f964ad5b88f874655b59cfacd4c36b818d96822f56058abd8ca410456c7af21d99462df2a596e235708b49c595eb94eac7573ff3a49697ce2a18d1c318e2340daaeb34"""), xeh("2CE74AD291133518FE60C7DF5D251B9D82ADD48462FF505C6E547E949E6B6BF7") ), new EncapsulateTestCase( xeh(""" -F5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD382"""), +600c29817b4e10241e9fe717ba2cbab8ec2b959a255bb414a2571cdaeaba0db244af9405aa870deef7491b1c5fead4652599c1dacaa309535a073144e5273e932a1877bc2bd3b9125ba658feacc6de45092229bc84a94ba3f5c8bdb37849b5372c205f7bd2588cbb47b87779b004309a0b713cf428bd3083b0d6622b1826446925922b293db9747027b587a7677079cc1871a8a5016c6c04bc5576ccab31a2a0b4a7b1b852319c41f4b7855c2451c27454038515b9876d6fa11820c2c024408735837264148ff7d6062570732d3a4da3a27752f60dc2c93ff7d91607c70a13442fe4929184fb9cc4e33c1684660e1a1f6b575ff35b449c14527352c134a11a155cafeb214d12854753f54bb1a342ebb918acaa17d882074467b475976ea080bd23b256c477a0acf56fc3d9ba9b34297e71cdc37733a3d66f11942017bb8c16229a23c196de8b8411336742328ad6dc5d4ba77108342d6847abde81a4e1a4b9cb8023a1d442e245186d155e9fa0653fc4a6668691e146a6c729507c2589ac12702b08142b9745b2774cc0c44fba928f42381ca7a82d98c3b445bca7e343b0b1334a03485494a3b6661613009201961551ef9c38a2f7cfd46ba9f906c19c59386af69ce0003fdf03c880d482ecd206a0e96f54c28160064d6caa31e2902c7eb03d5f0979262591cf498d51175212aa482045121fb30f18c2274525205d7c746225c920e62c88570a3fe23731c49cdee65afc965883fbcdaf2306344c32d46b403ce050582345e5c0cfb2d08d0018cc33d1acfea146de85c1e93a3a015a1cd9c7580bb1583afa73c175645581c59a801952643da86001f065bfe6bc1d94d510bf3a0a0268a77babb675f74ae426934be0c64b115e3dfbbd2e98632fdc840f3336f31698453641a18b667579ad112490b452c8b7b9bc7086bb19e483453c4007dcb556b013801729ae23924298bac6f8c59e3ca971bca2474323cf636aa02b008fa08d56a500af032801e3157f29505fd93cf3791a210498405813d612858f503857a0300d672414bcb7b98868d0d156935b1921620bbe262223f43f3d906e6bec23235441da41415f050523b3617bd57184719ec9c92ee2b6bb4bf6427d7045c01176723c1283dbcd82782476fb9237f96b7d13697ab710291683b2953dcb9b8ff0cc0cd99a33b5fc54f6d07edac2462beac952848aa6ecacf71a656ef9b2506585665a0fa4b8c74701868070beca33556f12c0be64caefe6a1e2e271e8470c5867852abab93ed925f3837e9dcc04440607a34c4299a44e2a537bea16b8da07187278ae672509d53aad998b0de88a7605c99c1fc36edbbba10884ada971813e64815adac6641630635a73336c44a3e673ac24ad41e85697859f257a2781b95ad9e27c5ce39470ba246bfc3e0dda46260939647355d0024aa21b2063b19967eb7d7a65118f6cada035053374812b995977eb6cf1238e5520b6ceb67f261293dc9ab205c5c548213730585ddcb3b6a0d0b164f9546d079d3ae00079f6abb170603528991d71389f9113c08434d481808a823feb372437975b5624590c183c131507b2894b6a15ba6ac18b7d1a5ff0d16ed0ec41e214c1d055226b4b0063059a7486088fcf467cb1580a201b23912e571b6523869522bfa4dff5fb95aeb9fff2ae41b2"""), xeh("76D04F481E68B2F901ECAB58B6369A2CC31A9DCCED82A1BBD426BE0AEE266AEE") ), new EncapsulateTestCase( xeh(""" -92D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B"""), +425144a91075cd90b31f9696fa1c326a8886765ccd67e119ddfaa185e292131128dd466206d9b4fc62250c6892be09bd6d379e88a86204226aa9449cb1f39efe58021154130e630ef70735ec57cf4f2acb93ec4434c4cd31f1a4fe798aeb50708cf90e5257991a09bdd3963f2fca8292c17f870a4f5af4cf682583ec953f1321b68f90722387136ad46d81e6a44080784b19cb975630116817e81b48051518ede43acdd9b9eab02dd481b200e3093dbb46228cc30d222c81514d1bf319bb239aa8db631f0849654285fa513b81149c19473b43caafd2115939464207076a11b7c6445a9837fcb6fea0930a321a22320658334d958a98c8921e6bea31b53b3d0912cf737c7b08022b0413bf27504eaaec33c7b8bce11427be219b945668baacb1c6e238a0a57b59d48477218db93b28860132647bcd69e8c62712a4abea8316c42e121201fb4a37e0d942464ac4e0c79805d3c61054a7e897809f37295e04ce42464d3096a388ea0b6ff5c04f3c665291012a5c4dd2cbc08d0996054a52d0a26d153aa54eb5a8ce66675bfcb657f0c952f273c5899fba9a01aef2b8934386d6695471dbac20a2b5936847da5b419ee5c34c4b100c36135ee1ca83b0990b7c405570321209a288d284e4bc7e56809591209d07050a39e629b3280574065d0f102788325b0b5b14d1fbcf2ddc0dcb6c9aa959ae2d2b7c011013814a3971d16b4d2c3480aa4c1eb135736c0d70829dea14ac862b46e9267f392ac8f1a2304b7125d7b08ed0839c61b4c02253045c2435990bc1b6d4c27244035a763d63e8ca6291390c417ee0e9beb805915dd737d68530ff27c943a39da835c49d99c0b6c50a770906aac0a5ba988e650caed744066c7a131eb050678837a3fa9b39379ef9e9283e2b0deacabf1b833b358a1a9f1c78bbf20498b9702b259ea5bb1d58844df66519c1bb0323a4b3f4866ae5ca703e6680de0253fc659b9491ae70d307f5aa4c2c888295b9122be209fda3a5a911959f6a9f0c550a3978991737a76ef408c27ccaac7443da67bfa76a79fbbc65ea72b3abb96b2b048ecd4116291852c568b59bfaaa9531524e36644112a76a809f9d0683a7d04a35cc4729017d70f5b1bb76b74b618cc9e181aadc8eb4ba5973a560c0f55dd1681ce91ca3e8e2275c8c71e5a536c7988200b5646afba80fe0c902e86d990a2ae91750409a5ea09645fa5521360051271ac6bc569b6d155fe8a379a418cfd000431cdba989872f73e2771e0b498e9698f0006050b5a06501a4b705434046aff69cc961077454795a6b3184f3ab402a22a819a24ca856c6a9e01d475c76aa7c71bfb692b182bb184b95b0fa363b76a93c7238a41661226c408218576b175e4084ca1d68b3edf79db991107bc106d103b7fa682189ba9f67c21865f2b88de32c6c757bf343b9b15b10e0a792dd3657e3d85be3dc5c3c52650425c8c62a735da286ecaa9aa15054f5245b3b514ef2c309dac712403a9d2999add6e351caacbd80a68995d67fe094a5c542994a88376397a7a15ccf1a9575e20b6a7b5c40c3c9739b02a53ed5abbc502ab66243c304b74fe27fb7ba7348b3a23cd65ad515755744839616a2e87120cb0a1e4f30ce7a6a2fa2488649dacd86c2e5fcd0162d826fb1e6adb4e0d9cd0d417b6e13a9ab1fd3fa"""), xeh("FD3C91294D8C974930B4B6135AB647D4A7885C83FCDCB30CBD38332E14094491") ), new EncapsulateTestCase( xeh(""" -CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD602"""), +12229f38375f8f405bdd3bc19ad9180367aba6988e0276031469512a6514a43902c6d66c06a236f247b077323d5bc1342c93ad1c0638f0b31aecc4a0980a543e488a39e726eceb54d1f807ce3aa556700842f1b2033871d2036ecc567f244c988242641c2aac1e31322cd08d2f95c5d559ba2328808618c5c6d8b49ca64c45082bca908dc5a75cffb1368c82cce0ca1bdd65128e3782d306829d608c2d40cd67e6ad09e79f39dbb6d9e41db559218c8263d1f6a8d4441f465a6e05510208b00522a9a6a77cae073817d99a40f1e84f4224289700a173c415095c7d35a32554678ee8087934c79943c7afdc40141a4810e94602d16c77cb80a2af5363f4444a9c32bfb8bc11e97c0d75435db0e70608dc95d85b70746263cf8c4def024a303807bb6640bee4176142c1be417aead89dcfba17eb319add262441a0c451847dd9e93dcae7c2e9c04f67c098123699df6c39dc90278362558df092c7292364c6c34cd0be104734fb1aca5282bcadc563ac571c8394b6fdeb9372081277b2987f3a26d0a812170303ca09218e842c1d2b886095bb25700e021abf45710550c4851fab4f7968460972144c1b6496f4465a0ab28478b1662b900353ca3fec6ab2c060d64caba43548c28654e1a38da32731d551b9ed03376c01be6466c74d44ce1aba9c2cc694db99cf1b09bc785ac5f0603c0248b352a69599e6b9225c887ec045a1708d73c263fea1bcc3782fd1ba1907064293fc4aced3604fd13c9d831323900f101534454bc7ff071372eba94db771dce7ab21e367925ca77bc3825db071e0f8cf207b2ca519bae8a2625c6b7b593888427a32462c0e98f009eab7b4bc151e7b727b6ba93ed0b686854026418272987069af29712c0c002e1304fa10071147ac1c6b4bbcd3232027ae2a0381a31812fb548360aa45bbbc711a7106c600af77535c51c85aafdbadf8ca6fb2c66bf66cb8856596b292490889a9b079c27d322ecbd34dcd8c2e637a7337eaaccf9c0654f748f73a6bc2921f36e1c6e662456aa66c55642c511c8376868a1a5c829da22e92e9a9af2b6ce7207bc7f94281c46eb76ab742c8ad0374973b36157018b9ba221afa3a3fd80601e85668391b97bfb30912038867b260ffc84c7fa054c0cb1f53d337b2f680d6f627093a21f7c6a065d276279bc83b759ae035288362b63b598e1611a21ae65c62f12948554cfe23bbf282702f87b540248219548fb0c363d19b9aa387353aec231965561397c3b4a41199615f02a27d7a5a6a8a93258b4466f389cd07a5ced1e75306d774c79c0b7b591fa5eb06b544bd4b751a3262481b300d1947a256f5c1a290c4eae87d0cb4b843441ef9f02ebc1100069b696c8ccbfa0958fb4551706306cb5c4d1e417a694718cf0a1e8337067a1a3c7981b81b868c8ebb71d956967e904f82c52f8a0865c05698f0e673ebe48c332293600986967559d9851bf75540cf7704dc35559b024298986d2f612a1ec18ff7f2ce1634482bf626939812c346174134ab65cc0bb7487e87d09ff7965f35a9474416c90a978bf29a5c3150bfa6745289473b485b7650ba78699b843e40c52ab380042cb3533ba8b640295faca956b0556a30be2b624942c97068f9d55db7c2d1acf9cf002c9ea2d973d79a050ba26ae235207358d083e310ab"""), xeh("7DB18CA35A53AB3A65E4C17FA096DDECB19FC7747E657B49D1C1710DBD1D197B") ), new EncapsulateTestCase( xeh(""" -0F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F"""), +772071873b6b97125b613002a38c5bae914cc90630d56673b824a14dd20697f800b13b17769c450a8b0dae472a2b70435643c82b329ca6440e3fd16a23dcba5d859ec8837a49d18f5c61950702846a806318752588f88590f0672fb5cf02f48fc3a8073b50c17dc8ab60c2601ef15ea514cf965a42bd771af7b917cc28a368755771ba3069036f57e1206857159394cf1b9702abfc5df3fc1dcfcbad79f2bcb3b7c9150706eb520a57b547bf217cdc902214c1b58a7c8c585b20ff1242de6525ae10cb857881897319f909870b5a5a732093f17c2172688fb585490307902e1872a4c384624b8b27539e7db3c78c272c14a988f3ab48a2e787a794b83186535970c0d19845b884c5cd427dd5ea699349363c3006656594a48bb22337877917258f0a356a58b0d5da3bd99976dde9357658b1394843c800a2cd1c608877703e3c5ca1f282d8b4b773d1623a39833f393009441c8813698957bb86ec8f4de60a92e0c2e6178e269024ff5896e2475d65854cbe4466b0671684b55490240b158657384b67db1b0b8c0c07422b460d05a1323456ca73cf749a727ad0cb81e1109388af47f321cdd836f008208978430ff1b6aad03163a412f6b93e09bcb6acdb3633b69c47aa5acb004fc7bcc8e3e2a24f949e24d1c23b9346e2c3a32c1791b67cb16f16a96ac58034daae1ca11a838ac0ddd43883976c9ddb799d53abec005b00faa3a15702ac2187d9b13b4e0a3ea8b2c9fc77a1cc23b633f9087c188291c74c9db8622dc03b78f48a35716ab5202cdde6cf3b62464cb87064b7b02a8890af2969c9275adfd28ec6c2940c717c8575a84a5cbbbd983c57183fc2eb1ac35744cda32515c2a66e3c988ed0cdb9e6778e98295f7cca7f283960275ca0222dae433c0035522ca7650606436bd767679b42b4b69912d0553e276f6b6428b7d7ca99b7ba855448e495bc51b1871a627edbf535045b037a698c8833a4696073bbe6740ff222c726c9cc636402c912dc1232b10197b7440490b92ca8e683eb4817a2b866c85a07a38885ba0284da691f99f167e1baa2caf41ad75a7931a43e21a9671bd97a65dc415c03b368d075bab0cd216b9939e4325e1c9c96251d48dc7f064339dc062b4a3777cc24bf01c272d1ca86819027cad3a491600efaf961c815940977074514a022dc40cd503ae778015d3305cd8b04d4c001d410cee5538e9331982ee52fee9857ea5c685b41bf16bc6bd7754dcab4ae99024f69336ddbc42a95079668bb8fccbc6ff66a6b05768d6b83c03c759a2bc6ad2c2205b26b41fdf022da075cf1589d88954ba502875c28ad47c31b857998acc5287da6308f800d53f95797e52d0a29ae4aeb018ee418c4f7cf72696aa286addae756e619aa8121b481ab66f25117970b66e5866b90652190d184669a4def63219c025f02149f287656e0a235cf426c7178ad99c61294a2cbc9e34fe5ea735baa8da8384daf0a13dce458433067b004bc78922c3dcc025e5688b67ab4d7fcbce06756d49772d4ebabd8b94bf07268cee346d252a9161262d38a9f04eacd7bc76a82f477334a0b3c272b4ab84aba7205a1b158319139827b3d219784101456b964929fa96d27d48ab35aa1b6f914c1465ca9548559c9a8d1f7e328029954825a12a8b4f2f4cf320831f0edb16a73"""), xeh("876B17263B409171B746C6936EC65FC94137F958DC974BF98110A1D07F6D95F9") ), new EncapsulateTestCase( xeh(""" -C9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C"""), +05b46c32848d4c14cb6c567b994c1bfb75bf11fc3db2915f890c626ef2bfb14c1aacf9b77914bda70a37e165c65b03727e1834f2d6471f85bc705b8f63c75672336141c44e6c9b7162f0ad93a840987474b7711be7b8b7a587608604acce1b6ef5618495f365f221b5464c41d6448f87986fe8f71d27658f40a15bdd74c7ece1b8992c137e3b43b8c27e228bb9483255a7050a23755c671b4d9854a185b2707b342d051c262d7cc12439b258b30a4c14096e1c91e962944e7ccc11ca35c5d83c937aa0cedacfb89cc6c552011e31b11fc95626fa0d1c04023d8772501402187ab2af9391abe69f988a5daf8114cae6ab0010041ef4af84763e287c4368eba94e6b0bbde17585bac5a8d89e285c4569d9025b65b301374a32018366bb66f54aa4b8cc385f93a34325282f36c5bbe172ad2cb44e32aa876113d8c1000d94b7f0838acd2000a6e386e287cf77226fbc9588a5019b073a237029820bbb77f934be084318e01562eda6b4e0f01d2dc17caf290fc5b2037738a33ed181c6b4aa4d10982c38aad1143ff9530e062ab3f16a9177f145bf0a4b1a1b037682506628ab3fb127df8ccc36d0095074c0db42bf628c690665cebbd232b302802943bec761acb00065b1e07471a39d36449de0c8591de5cddcdcc3a1c43b5107ae30640fa221bc5262a86c0b0124b434da226d959ac55060cba5f32587b1892471300159c9d8045d59cb00cba04821f1a6e19a713609855e3acc0959cb2c88ac19d335b0856d19e34e306602d9c66ad1085edecac34c55443af41e76fc072741ae61950cfc174ff4f3cee652b280a39124ab7bf6f5283f2151b375a2668b71049042a421086db12e7fc7bff4d95605e8b8d5c59bdb47a71d06089e8a13e064040b1289a70b804481bd22ebca2a4340e5a498e83bb0f96c4955f516a5d125408656b72299ae73ca18a2c58342810f9c10808353acf006f93637e0254b6cc216d4c7336d5b5ce5b55fcddca0cc59a0077a6b939484eb64648281b51c3756c9c8bfae53a904f25925ecb719c25a3d378f0cc5634a4470cd839cca90701582383bf27fd2f2bce345481a2a80cfc3b6588a3c328a9d2c0105129472f5231e5b901be663016d79987812c916caa364450301b7ac0f463e87e3971f4a5f13888f66d5c78aab602e4a01a99992fa25cb303cce0624bc69063063c55c16b48deb9a5945f28c614b7e5c83243fb4500b27bbd232baee32638afa0a72f505c1ca7a286c90acba7d3783a33a2b18ceba62dc7287db9aac24a946f0bbcab94c0a2d08c72b437548b9c0d5c41f3fba3d32026bf8db12ac067cc37bc79d143e3a6c40439bc476d5b10724b643ac4d5f230e2a1c14004835963b58a231bc94b008f3f50e9b493e849cca03170a67e90f00d623c9704ee9f788514239c8105938323a78f34751c8960ed420d5821b0db6722ee07a5915110315cd00bbc4ead43719bb3e4fb63afd743c522c6dd03babfd8c9891549814ab2b7e0c66c8661acfd34db8db48feda502bb271ccc03146e7c5423a8182e84554a9349238705c250c8e579079c6c7aea73f38476f46e22c67a67b4eb20dcee2556adac841b67f65421a814c9770f84a683ac0c2db2f26222107d360c1623c9da4922b3f97e33b0bfb50623a2989ec50c6612768f42d5769fb"""), xeh("E0AAD46FDDE0B8E64361C3233263D8A751F5583DBE91AAA6E69E6318FC7A8EE0") ), new EncapsulateTestCase( xeh(""" -B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558"""), +246a3daffa8fecfac4cde76265e37997e53d8137c99ef4cdc8f0194f1984b7b3886ad87fb0227d569ba5783630f248add3b881d16c904f46249ebc73a6151ee2538fdc5b248971b3bbd5af462c36548b273beb06480b28b04b359c03af7df4344cfa28cd469476e3499652ad759b761697861f1479a4400bc034738ab9b674311374374ee5d73349c0a7b9dc0c158c13739a674532b62408bcb5c70ce4c54ae26c30118c8320eb05cb0c1454b7b06bcc013c7892c9b4693f40c6651925b0a3101da97d98c19ac5a5b3f7930061db8d38e37e37e3469ae6b52fb10300da5ab71a16e9d762a2d86473442c752187d33c2809272a16649f8403609e17bbf8003aff87468e8cb4e0e2b3a2fbc20fb8b172e606830666b6550a5c13ac862113b817c2c2f1415da33b9dc1a47451246b434f586a351c55b4c9b465fa1cc9578792368209655397c3761bd7329917497e3f357f0dc8418d474ec2f01af697b5fe30248de409130c3dcb079b50ccc73a1b709ffa5010f1644de0b3c2598e8580050a0b659c034ba7ab1c627cb43736b6b8a754dac647a1b94878529676426175c700896b5d123c5e125404a59507f5fac8acd5bc5de2035a33ceb680c412374c9753aebe423ab515886cbcab2554c9b28c3497b63bfbf7adb8db29b59abfcbb501f318b5c8d61c2f33336652c787348e00c4c15c911f7e2cb67f02ba5c2b8ec9c87ec1fa6d5dfbc05f7961c6c0829d7687df542b4eb42d8d373ecac1aa55d921f7319eaca181ba1c259e4118bc27615a866944a10e28e260f7ec1083229192212ccc9085c5436210a1392918567619b97be71f65c017555a4ae60a81ef0951165a191672c864f2112839596a343edb58885bc58c6406334a385512db7dadac2b7f510830f3b3b3440f73038d53e5ab143a6b53702f30407c6c824196b4bf069a812777a8b2c26e661cc083c52fd3259ae08b9181f06d8c993f14779300ba56b88647a5314066d4b771dbc76250a60fba5afee147b01396e91a0f0dd30ade7c82b6d85f8613a9354630bf669257b57dd563ab6b07c5a2a809cb16990ad98f23f34bebf6064c049f33913d54666892864627f8c4e64b20e06b43a5c5829bfab4eb774907c36ed5eb17ec3101aa8434a5318354510df87cc01a09d06806bd95939235fb635734068f1594a11a624e7b87ffb239dfdc864ba4322ac4357e499e80656db0bb68931159d759806b3c2518a319bde226a3c250ff0c2326750a0d23beb60b442ca595adac6f775cb06cc988718bcbc29c83e39646b99abbd5f7723757b9aaf63857c30e7f0337b8fc949cc0b4ced2260736298675aa8e6a1022aa1b8cfa3104387e429370689b398a317f0bc50d7841005048aa7e29a71d0b03348328c0c268e8f6a64f518ac06c4398d7b2f82abafaa1c9c37bb1e3a147bf870cd10c21cb702aed892346cc47e6928d3f16575f1254dbfcb910aa967a87323208937d1aaf7fa90f1261131ad4b04ff36e9f6696594a2ccf3a021ce852fb9043c194c4d3d704edfc5e3d2ab671b8103e8bcfc631107815790e5733eeb66fa344b9f276c531e5505303b267b6516b00b056780230847aea99cae15bb4faba0b9d461877419ca2d16ca437f0f2963e80f169e7bd65d440b7d6ed512ee105bb1690052a72bc54207b09"""), xeh("90347D478D5D964D66A54BE930FD9F7FD3C2AE1492DAC35A6CBDD02616BCE14A") ), new EncapsulateTestCase( xeh(""" -AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98"""), +d5e216438b4535c69165f884be521e5ccc33f22695aa122e5d918e8d27a390035a42b9c8e4abc9dfaa92f090360c9892fec554851c7e434caf9d41896741aca2f2ad64e8b1e3916827215beae96d2d190f22917ccbfbb3452914078607a0eca4199714ea8040e9c9945c71501bd1b6baa00628c62c220b5dd79846da4399536547b04811f6915045e63abb9575076150bce269c61390cd3a3fb3db7235390b63dc49d041788d25650858a062e49f4d9855cac7c7d403b172044e2234425f503f3f613a5b1a72fb32590c851d71295f0da4113705b306e6524c398a59a83ee6a9893091beaa78470b274680017387eb13b97baff06a23986251a1f1a4f73a72054640d6574b5d070582925b201b37b5a690cecab7bcf72e16e3454eca10fac9b760cc94928307c2853a15c47c6d29ab90e322b3b566a43166428c09a1b3ab3515704bc76778c38b0ed224ae727024f2008cf2b5128cb912a9bd806bad62e78e1d79cc90f3675f863df590210a18b6b629cf91738f23280e93ba04b3661cb0e040709639a5b495c7a36eca739270031c97db9ed9432a4ad86608528a7ff7034652571fc6904662116980201f8073ca003092c19df909989dfc6744274a2e01377099bd618aa443c883bf8b87a9bcc9d35c56aeb49068592d31e16e12c711cc9a1e9780329a92aafa84827e685a21a84156b29233e50f577c54fca9a3f9dc6f4707704b515d9f2492dfc22977a36dde51704ac653764b124cfa615dd5932a05b895987aa714c1bb38c3166b27cba655786c29fb733448381fa7606df0f586c3ab0f2660901ed1444512ca70108e180776078c417cda8ad2241ea9304f820a9964e455d8da350ec30469fa6ec3470ff4848da109cb1060abea4c3a4b733b97d04beda35e769a7f1f84bf98c8790e91199ef04a6ac80bcdd39ad4979c327b84c0e897a4046bcab450eb3cc4d52b83e2f3845bb6c4729b3508e064576a6a8caa9cc12c917118196000a1e478c278257da8a10d78734b44e426335c81a4e6988015a6eff43470d98becc9722d254a6df327ecc91174a3a76ab430ab40678b37cb098926823955d5d8aa8f4c2598eb8ace098da3cc43e84a4a205c00cce1962c7411646a1a4cbac0fe884db3d55cbc0531d4497e562cc0b6f9139c905a8036153ea18570c1164e8b73c15630b4d020380c63cc1847e38a938085bd74338704266a6462163a176efc248c5ea6568056be253306ad8ba7d7d6144622002daa5034cca3af106a7f2b61a0e7b8804677adec1bfe84b09b910f96eca5f090cbc4e14139f12b29b7926225689acbbcd7e4cf2921219841c68d900397a100937687a9d779efa7301c4b1d1f74acfa820445c851bcb874c3c5b6e33297c2b424737b082e31034723b05c6182ee8154f5f13d69e67b25a58f8a543e19f7c279e99eda3c53854791c20a1ed0e95a8db87bca83aa6925658cf4035ca0879d477ab8b4c104e149b550b3209b5f36e149108a1918fc29de294fdb250fc66b691c30c9d6016b36a83e73f9a31df40744b39410201049642380ca752b64a2d536b6af19365b434b326cce1bda94719bae4d418b81cbb28921c8d02b4452556a156aacac7608eb97a2a56949059a5c232a561f842f40228b99be04e4a6a52718dc4ba9689b0020bf1bcb8bef"""), xeh("119BC36B5F856C0A2F136B3EE42041B817125A600E829FF6B4B402131A26ABF1") ), new EncapsulateTestCase( xeh(""" -463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF"""), +cb8ccd08dca5a5e735178993710821454608015b34746800c7f8679d72b0c628757756a50a61186c553febf79c00430bd0709e3741886ee10667aa7f7e4c91d89820e66ca9bbfb029f5cba016b6240e2bfac3815afd613a13b04810a26559a60f6628308fc45238269c77428aa370418f11928d5b3c211cca7bba2de57898e132035a16a8ee780678b213917c725ba8dd1818428199c672b20ac05061a82246e3b55bfea529ba891da6320412108ef0ca184b44736dcb05990031f3496bfc96c50445040e27df4fa2c28205e1d9090034285912b199b909efd088cf4ea4241f5c3052050aff92be505a355b515e5d4ac55b859d5a3cb1a42564d398ef4cb91db1430a7da96f9e96cfa27cfb12664f9f694a36b211a7a79b46c70e0ea14219c119006bd287467c780b7e6e706dc30b230b20c3f8759f2b2326d8422b16c124ad4a8e031412efb450f881302448e26f383fe01d0b26770384638ee1aa51df773fce34a9dd00ca24c584f5512c108109bb9499922019381022a58c4494241b2b62da8ea0b784967d86c7d8fc5c6a8f6055865173854c38d6b407b3199cb44000aa90253d7790011a9d4551d66278d559808835208caf18cb31642b06164558b06fc615953bb1c5fec2600975dfab48e9123b0f3d8757f53555177766e819f9c5487c9700adfc917e5782c82c681ad8105d6427785c862201140c5919addec3f10574617201e4e35372d472f782388c707406d73b462f25e3ac846bf7274a721b1a05c36981093c3a853996552c85b4a90e0c796c790dd881fb255557e0731eaf8aa9747b0fbc64f2db3a7667a11b6c7718200367dd86f0690be472b5a2fa4b914f91622b78be310719ecb81d1eb8b6c76bc4df0116f84179654794b39832701911480601c77229bdb571c1110387a78d4510dc0705d66e189e1f80bf7e5c4952c083693c6908623be31b1d2c63eaec178c3523110ba13bdba64e6903df028a23167594a12b64de601c90b41231a29eb5c2ba2475b09091f8389363030ae56fc686d024a1f838a0fca5914941f72470ac5052b8863aee631a3206c9f79dc479c925d906c86d3e5797eb2ba45499690b3799ce39cc65a9887eb5785c1a6ed660502d85f5b169ace240aa6c492f9bba48c61c81f0722f8377263a33087814dd51070012a103a93160359c3c2a945933c081409cca0963e99883dd27cc2572683881c189861ab10e17e400b5da3d40983821b4c45aad97aadd35b6d7296cf2ba029981182f5a1b189668711d528de7c7b07a71a47056074066193936437016b5afa3fcb245c05764af1d77681325c0fc2bfd2a74f1490c704e216d18345a1e074dd440b730a0464db2bc5852caeec23c0bb0d754cadf8f050ada71d85061d18a6138d8b70f77aaf45aa25ba65c643f6103390168629bcaa10577070bad8119619320762486e9e340d43a04bbb408ab86801ef55647e43cf88a6c0772b8d5f274f1c12593b07bbad80ce3bf1903f24c6dc976cb8c08d2411bffb92221deacc5f2783b6d38078f51d42eb5ff1a6b78a5899f044ad4d57c582a72844a98e9d1bacd4c081abb44117d20a3fd3b18352a1f2943c29d0a4832a8eb4b22cf69030def765bc527aae51010c74cca53b8df382df9ec3e8d9d492fb165aa4df3ee6a45fc8a9953ae5"""), xeh("697CC7445AE2C9ECCA2569B7871F0BBB364E63E4B782F734FAFED4FE33E4AF14") ), new EncapsulateTestCase( xeh(""" -0387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B"""), +2689044d7cb15005ad5928aed39889c195c94ab0366f91910658388798b53c6028343664f5ec4601d4acef04d0b6f2460e75bbf32405a512ab2474b8da27acf70bbfadfcc21db84ea0b73b548066d4e4618a355f9c051b8b54977c3544bc7151e4ba1710e9a00e86a46d1149620c291d3673adc5101499301296cefdc04bfd5ba5d136ccc845b4e69c629d1086e94b622054c5fd662952345b48d988e4b7198f298ef6a925fa1a3f912ccad5b46eddc861e69130424a8d952110f5820c776a0af58c7aaf14922466ceca0aac3bf1261bc73df001bb7a081a9440c80453b8ea8b06e22689127cc9b2ea3d8e5c2bf8b25eef8841a527729dbca2ab815baff343aa74b4b07c06d5158e820c1fc440a86d44826c754a7e3b05d40c1cbf32206971c133c80f8f678d3c30ab99db0656f4ae9ca12ca4fa132265232bca7569c8624730b234065196d773a290a3633605166161d86bb169981c956394aa602d5ad37cc8d800a8770bafa1667b04ab37a668acc268394705e679594445bf0a7987b86cc8c8f48e180279a193a187025648b22f53d9ac5d8b8a760978181a9755e3195754530b907ce992b939fb3740e626ad5534256bb7dd538c6bd2296d5675567c2277552c52930401fa09b581b87c18c70ac8a4076c9ed8dc001478757f01ae8ad3adf49a6ab590a61fb2c5c8645076e78c58740aad2990cf3858e27ab151f797165550b1f4a0fa9b7d47a8c4dc47bb53b359742aa486ab776b3a7582459f229b969038379099c428c53c1486cb23911f50108032796e46ea04842b28a84373332287db410390563c2271be2ff14065f22b7ea32a284cc3d0654ec6ebcbd6412d2f5c29b3720182350b82b8b65fc57de3d90c0cb55455527a469097d913331a7a0cca8692200bb9711008fe5549c945b306fc48f58b8abd835dd339797b9c508bcc8e8d76a32d560cdbf7506b1c2d32fc35170347b71a3f456163bf3116794324a46651f359bfdb4a65cfb754ea47064a2336f85bb82f2947b9fa164e11a55ca10086ec5af899bf9f7a3c5130a9c4880412946ea6ac478258a67c58131df3b7338933b77c064bc9231a49330a1a7c85e864b17c56501697b3e22b1fc468261b8eb8f4b0c6703d6a1ab764496a6eb27f804631071962c4a8062203148cba5acf2226b74b66fb305ea88040f22779a5f3486574a7a2833cecc69af95c64348288bb1925abd5be25878d9585c540134eb2046d7bfc5fe16581677421c1b59f1c69a7717744ab87902480ad1f697cb7f66286c43b73702f42720840d598c3917f25da324e5aca224a9ccd9757e91b2dda2186d56ab2191b46c950c54e7c570a3a0d7805096a4718b57bcaaca5cd6fb1a6e1272ca1ac7fd9ea9cc72440400bb0a35abed71c3ff0b9855058891555c713783386bc591a9663e61bb9bf8055283c2488e198a6e991fcbaadc7885f25295b3d531920d880213b410c1763aee1beebe665abc1ab64c6ab3cdb95555004c40148a8530c22b06341c301f301970f51479199c785a4c616813e6e41bd8fe078a019a33af92df22b207b09972a60443a39bd11c5c38de24770f3a29588abca32283650a0587434b74bcbe6a7bd6d70bfc581848c9b2ecd6184a0623c75c1768e0f3948eae08ad7e7fdfa17684a3c63b6a10dbcfd6213"""), xeh("52CEBDECF06579F4A9351F77CA95B5CEDD034D812F3FB7FB50320CA80E4118D5") - ), - new EncapsulateTestCase( - xeh(""" -82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B"""), - xeh("161889F2E92B1BB28A257B45D179FB76847B664E6D7B5FD9698204A426EE96EC") - ), - new EncapsulateTestCase( - xeh(""" -FC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA"""), - xeh("3349557DA70FF69886ED032A91D8FC23BE9E5245406670679A6E92AED870D369") - ), - new EncapsulateTestCase( - xeh(""" -ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B"""), - xeh("6F1694589DFFCE022DC4DF1852FA49A41C6E8AB9F7887E70DDAEF4232B045DFE") - ), - new EncapsulateTestCase( - xeh(""" -48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA"""), - xeh("D8EF97421196B1A91448B2BA7E2B4D4B035B91DD85AE4E57E8FE3F0B0D524AE7") - ), - new EncapsulateTestCase( - xeh(""" -AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC064"""), - xeh("132E7CDAB9CD5199FF0937C266D50BC50BE764AD027DE45C858E3C2F79B7F07A") - ), - new EncapsulateTestCase( - xeh(""" -11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA4208"""), - xeh("E15BD4603F0EB64E32B3F1D1FA8EF6CC25D673A1D0BB659CEFBA2C153724C1E1") - ), - new EncapsulateTestCase( - xeh(""" -E65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDD"""), - xeh("D176C0836015362D1DEFFC1901127B5C41C14AA518BFEE6C62F2EAEA1F226AB5") - ), - new EncapsulateTestCase( - xeh(""" -6453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B18"""), - xeh("4E302EB2BB5392782E7820868DEDB61F5A6AE558CA307A01ECDE4970E43EB448") - ), - new EncapsulateTestCase( - xeh(""" -409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611"""), - xeh("7B334E045896C00F90D811489D491E8D72C4E3A22ED831C019FD4BD967B7A802") - ), - new EncapsulateTestCase( - xeh(""" -D0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B9"""), - xeh("947AFE33934E8150B06BDD1EAE40CF82EA99C0C0106B101283EA382EDAD94A8E") - ), - new EncapsulateTestCase( - xeh(""" -28C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1B"""), - xeh("DC8510F45528D6981E59C1AA6B743BB844377D7339E359036929F0EEC54FE63C") - ), - new EncapsulateTestCase( - xeh(""" -4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A"""), - xeh("62A2DA94F109C0DEF56DFB275B1A0EEABF82AF8C6CDFFA94085AA93015BC1821") - ), - new EncapsulateTestCase( - xeh(""" -36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70"""), - xeh("F374D3C7172C308D7AC5AB1F1CE5BB9785B98AFCBF4E9120B42EA83BD3BB1867") - ), - new EncapsulateTestCase( - xeh(""" -75F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF"""), - xeh("DD252F728FC9553CFEE90924565E984C8E1462CDE58AD8C4ED8DFCE98A7F39B9") - ), - new EncapsulateTestCase( - xeh(""" -19E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A1"""), - xeh("297ECD18E2880A596F572B66458410A0D827851EFA55F1C9CC513F7991F0DA0A") ) }; static EncapsulateTestCase[] encap1024TestCases = new EncapsulateTestCase[] { new EncapsulateTestCase( xeh(""" -307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983"""), +4f31c22cb34ef4a51478c635302525fc0abfd221ca8b3a6e224338bb0b9116ba54cd581cb7a3813c878d65317d8736881c8a6b6a7030441b44dc6663a6919c7a3574463b706105c332693d1918682d2a0f2e12b1a545a8aca6a38f0b63a216463099558d282dee3c33af3bc160d48b889a9d80e9cb6d83786dd826cf2c58c23c87f0279359026458040ae638c3eb5c5e0f7b6ff2e76ea598bac5143941d50d031a4906bcbc826a364d92641f68cd1b43973fe9b802f778963515cdd47eba329fe6b50c8bc5bf6d3aa02e69965693997afbae7e2c8f06b85435403c827a39d63c8cbc675d4fc31a5a699a0f2381918448a4471eb5aabb24c0685e6a1ce042553c360190ec470b44a7cebc153186be0d8c8996a9b3bf46383aac698758ca7c9b4a993b77e8397cd3a3bfd11b31b961c90875c900157f97e211ee6c853fea2dd83212c3f8861c0a98963820d6d73c7b3693b738519deca589639462db956bca22513b9cab7459a51296443076ff732e3eba57ca767d4374a8b2544c46c54c2f46cd7bc6461b8105f0d41ca4a532c6e4052629929c03bbd0b3c6b52c51cf3195eeea6aa9a55de0d9063bc57722a72409a59747965b4e6a5e14ec112a103bba204977d43822d20c92a2aa0f4882798216cd26a857c6a12bc78ffddab1d73a9b2f91ba4de83bfc54092d4359f03a4416230cd6616dcbd916b989856f3b0672b172e20732be0730d1a3a6a837c59a05b846ec1d600841594b306acc67cce4ab7b9715afe074a75738aed749c1494dd683ab6791522023acd8e5c403f77b23f128f16261a100497e0b1f906b7956c53c1f1a0d65d9422d7a3e234c252675446f085450446393c0c151e751ce25cc05b12a58c334ee1334d16b813c7689c6851b7662084ef05ae30bbebb5c2911859db6dc449165bf8b41626839cb37814768167ebd24300306af259941c7628997bc80156c6b87c758d6c40b55076b74b2b9942093dfc979ae59ca16a6ae33b523a7c687f3f22638f37c69c4946a26bdede88477c7b67538115cc890873ba223a953e1b79f7a902d0b20cda992a25b235f30164312111a01cc5d82d4a6e1c4961ad96bf48b797680bd0d04c83463bf92d86279c994c88b57f5a14c45645f28fc19ee835f0ba480bb04a17f5853c1e00c37f0857e88504166a230344bbd3180e6421432874fb6767d0a0c52c661bff33988d3e3132cb744df5b6c28ec4e7ba2b25c22a179914f043bb93536602d754c92cb6ebe42832f605d6dc99a8065cda1ecbdc589a93ed321c529c5f910ad86b9183b827e1e8005e0ac102a35b5abe533e31acf35e649f967c064963675421990082f4897971ee4204e3611bb3bca7af3a5507b239e9ccd49c5c4e09c14f3a3106bd961d9d649617212832c54f430140c8590dfb1bdd40785390384bc9640e2c8564c4a4f700ac1c6d1895fa40ca309aa5054b04934bfc190a45f78ac1a8811046710ded3246ef4032f3b73231913db1a58f45563e3a62413f6a0598264321b33460578f682ba40d29ce15697d6373bc6220c0931bcfe87326f019c7c746e0136a98a6bbe8c7caaea8a222e80915926c4fca60dad75a3f03a60375c09b5c5b120180b51f185157a345dbb91bb5aa6b704183ea0ac0f374a90c02206668224f975ed605ea1b01c55b9a2c159c2a096b3c4a98c2cb8b81682864188cceb3bafe825016381b8b2bb7df2ab4cf2a71f77347eb84314dda92f6d5a5c34d9cf3a123a16b892099c23dfdcb5b8e67be1087ec5b38b081289fa8c3d8d560a2d882f8b8501b4096d82602e7960a2c433abfe928e769b3e22965cf7f7350a1cb4543c52c8f3983dc84709c1909cb76084771c3a59867208c1bdf869b85548740c8b4390a2a7824d2b8a283606aa04a78b79acbeac33a2e4490a44b2995c70165aec4e37a79ee3224a8c3693056b67b1021c5c473e7fd31551a24a3383741d082366398b835389d4e4a34f7905a4c5808b27b44e86aaf02032ed07ab30452bead1907ac28a1a98a97683895ee583ec59316673213f9b1e5c2339678c0b6770459509ba5478830bba25239c311231b796c8225c9206facc138cbc2f58495f106b019041387982cbc656604e05c06e630b3d84aff82240b7a7cf6c078b9fa99fa426c197a5aaff94a93ebcb61de47f9c1c368b4f0104a0e8d4f20f98b38f6962ea4d6e053a96a8059c6e564a9ebc6c"""), xeh("59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72") ), new EncapsulateTestCase( xeh(""" -16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279"""), +a696835000919f0159cdc7aedd3148ccca020f181b2e3888cb6c3c8e271449bac0da2a2042e230895818cc5bc87e38471d3abc51f6c05fd80bcb43bf65d55a0c4c867ee28163618376fa5dada52c5f4306cdd99f0d4583c1399dcff8175f465a02d61dbb98680de662b49b762a8353ae15bc76bc097b789ab1057d2595363cc043e56c5b44562971c0097188a30e488433a07e7d934b89f4bd74b98822518d2e06932403bf81e97347c203e5413bdbaba6d4107e9ab4aeb1091d77a326d7ecbc09706a98499a70f28300a0c80c3aab68980c4d1cc662091bd370575e7986c38cccae743efaaa63eeb9965ae8605a799b447b76f91a15c8f16b6a52864431a19839543d86ab02c469ed7404d0eb365b7bb643153ee2737b9107a8362c4e3b05c0136c6d1510229497bef7819fc0a30030f899c0bcc6366090d4eab165258fd1447a3b12156bb6a4b3320914d797a2eba18bdc5615c208d1328808b667ec39a283dcc331e83b9d9302e3145fc003230c8a2365a5b3bb52104e698d41662318535dd9557df8907b6161a404e946a4b00a52829c8bf911d79385f254465bdcc77a31974fa6426554a12e399b8ac57e8c94163f3727472baebd458cece806446842c48659ac6c7262304fb693befd3b67b3237fc239a782c83afc72366cf9cea621989d801fa2477d564178d5c13197482f373a9e4ed9b2c276ba88e0348c1708c93a7c54d21bbc64496ac21969b975e5f56d033c287af7ac993cb87965818d26458844103957834760aec8c1572bcb0aaa740cd23b71a1a80396e45bd5a2bd704474f3d232041ab51404a768d404fb295a18275720b205b470778226abb26b775c972505eaa461fc52be230359e736cae2299cf47b1f1c0cbddc7472439ad8033608a8994825326b9297225c8fb4c0ab6a51c74ff2059d60aecac1cb8e9b5b0de1bbe00038bc883c25d23be3198c21648271cba8559c3a451624a403a6c390cac13412b2c788d7ab93de4790e8230bf7491e39019b1feba2a551629a5a012942912d2631b5f64e2965c73205bf25fc451d8836aa944063925a221784a9b5c99f13c381b5ad71c6581f28510ce93366534e8cd137faba6c53d92e25205c9cb43d7be5ca2940997ba3c903c04ea5ea4605503354d4bd63e3070a12840e2551f15c20f6769834761bbaf8a8b11ab94b69807a1ab2dcc396fccc22e3168e35c444efe876dc4b7d22683b6ae49467d88e08b795cd556b975155f4324dde94ac7a89ce5d802a91b4745c2b6a86cab67836030005c70944864c0835f8039c23d7a999d43bdbf7428bbc83e8e65c7b81639ad41bb1f357ce9080c3cb57319c1f37db4a3efc386a40cd60bb7a06ea70c38458bee0baa58a9209682e73fc2cb7a6aa55f863b49acd9cb18186b2b64434a5b7a38a2cab3b8baa47e6da377ffa1d6a432c847c4c0e757d0847933f5962722a92b06abd6ad28adb1736c0a96ac8130caa309f2e5893b0190bd67016f04b17f38218853300a05a00fc30330cd907fa08bed95646db857f4edbaae9847af03729205691eb715c2aacaaeed21419b187c7b99b1fd83ace009abd93586a413de2d9313a854142f076ff76a9661a96bd11c2e8986dd9a7b3d9e1076cc21c0787226a66087f13591c896da8e521f6117a9d7c5028692433e86959450868272445450aa42429478a4df821653067cf61638a1c676b776b9de76c50e99084e1d71202c8a563c9c4afb6bbf49c851bb939311b79a358a5118c945f0b9f54c7a5d0c504192a94e610153041a291f450bb44995050a964264a79818e6717c89b4046f16908d7254fa4f571548b01e9eb37759c7e4544c5e5f98ea014200fe291cf40bbd4c3a61213c2ce862ef907457db3b39f82c87690451c4a872846c86ca53681030ff839b24ea655b8a868fca9188cd2afc719b99fb3020e547ba9e1c35bbb7d153508889c7d33526dc071c4e89632fb5538adc58a6a304b17610558b302efe55a0c631e4760c1be689b843633aa31bba7d9c4144a14d7ea15e8895061c025bce225eae5570dc375b6c449672ba29c9c848ed16aff85785953cdf0891aa5756166db1effc3ac58c0969edb54428588055c9fce4b05c023bd386a9c19c33d33d59044f9893bb98f3a77b35ca101ff518e6eb4b056b816afb48b7b1f4f707d29344dc3cd4fc20ddee4ea9cb19d236d7d13a7846aa22c2872f73b"""), xeh("2E2C821791D3EA49D0AF380B97AA24532F6109D85360A751BB8B4C048C48D26F") ), new EncapsulateTestCase( xeh(""" -54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652"""), +0799b60055b072088af992055fd18766111d70a92dcaa1881c1b5d03807e4a948d0937b9ed4385a6479a23930878102c0c9a04cd1b51bac6a7a81cbae47b15f33a331a5303695a4ab229585d27b3a7105419952bde5c659e089d38789d3a82212e03cd0ed7a6efaa913362b55f386d2e4b8d2565a5781642d8e970f6c9ca25d2acdb8a3da7f493e37331d26432c530bb401a4ce65c463d24194b2b1d708ab2a34009cdb02b1a96a921f42c90488940e7033090bffb30b17b06bf5f3b7115a24baa94a1620434247ac6c9579f42294e1f50cbba44829640bb7713c8ee957174a85b295bb1e44943db036773d91b211537fd9584954726cb83c4498658d1d2a10d2b6b1593348423aad4f6bcf1807d6599a24c4544dff617a2710e119bc17785b0a8c57428ec993e5991f76a9503fc580e4c62a0b296dc52a1a2c83846b7673ca308fc0877d5f473012c5c50a67813424792171e87a7ca555c0bb380ac351baa05074abbecb602610f1c095a4d3aca0bfa11092bb8dac09918449149960dd7d0928dfb2fc23b7b50d85012416e2d237afd47348378c024ac5b14c9ab4c5507a1355685550de7dace35cbbf20a679c9b76fef5b795e0a14c803c36984669cc88acd814d9380646edb1cfee159040c8366e7396af8977673400f5ab2c21980e2a184a472563b1c32886c58a0d68a2d39275529c3fe1a744c877a0605c5da7556dedb89ae8731e729b6911a6194d71102fb42961bbbf770873784af83c596a66c2a94a7c851d9677c779a0ec527bd761dec9bc9d1b22645eab949e31f1968c649c811884a765ae00e98f3228fb03643f47890f78fa6f0369dc37c98b593934a3937084f0664b10c091e7a1315adf4b3f34b5b20123905009c6f24c7f0c601b8f53664b6bd6d48cb487b0d22d45e00f19409a894f3ea32b2b3ad0536ac05e420a74a710dc8375aa9610d2640fc7818ed599598f60e21113670b99cc0d96447f6069e0b193ae79277cb29883506180743678b3c9b53718974210f043140d74392d9be2c08bcf796b462211d60d618faa152e461cebc3aa675ea1260f4585e810cd4ea8415687d3b2405ca72a46129c95f9bafde87061158920c4b13a3c5300918c8de4b0f840410ee91077d611971a4094f3a236230337127c5a789209f36c39b05b6618512ea7c9549aa4552d30ebb5226bf06708b4621a5cc8f58b8153ddca32748682e36363df63bc1249ce1205484048fc8798ba7929fa627404f072a2e0c02abeb48ac9475dc1c087e427309c2b701668a291a54056047def6b10618a34c550235aa6d39f05af809174041b2140640c252b604e81e56f34f2f711ce6d64e56ca0fce0133244481058aa477628022f2c2eb6c544d1045dc61aabeb0aa42127bda479160f582cb075619f810ca2ab886319bf87b12ab710db03b4a1a170be0699f7f333a46b18d71e6832c356fcef57db82430b1bb745f2215fab44571d4b0d9d568fa5cccc2919b2ff6b8d9281e07759069b9a602ba7642f570b20b15a156a1c322447323a4e9fa1219b812b03a5b2e1abe8c5b7ac26a8589733a3fd33480e18ac200362e5a0dfadb1252c0b2d8c139e4532507329ebc3910f05b480ed196bf86166bbb2f4a96a91053b511c81ffb748f420a33a6cb771dd0129cdca037e4533624aa16fc8f18a9bccbb475ef0a8b978ac9090a4539ca1fe06c5501f2b34480b025732a90a01e60ba9dfeabb4e8c61ed5c4396423af0aa79b86157e687c313e5623e6137f67a25680eb6bb841b80530362bd1425ee986b18830509bae9bd9926f020cd02713c7a83e8ca4318a044691637d03386dd28c3ba081481ca7649939bab47668fcd4291a4885317025e5250894e968168447f9f5c73702a5837802cc4593ab99242a59a39fa14935eba3e781a7f2740fbfca7141c821c8921e7c52b4ebe24732118cf57590dc919d09ea18d2ca63a605495bc2a88f9922eb356fe0343e4ac2666c49adaeea898b1c023058bb5bc4437bb6b798f59ecc8b565f811c8ffaa13cf8a4af8374c3221c3e1ab89cd94393053acceb40fd6a2c1d2c4c6316993835b9ade3a4bb396a5040574005ae9f1619c2fa66ecb363be8a7fb424927f8033ef8b2397a691d2670195590e9299375ca9b5dcfacee6eabe078b28e7aa1fa314cf3c866667cfcbbb5b57f2db74fb19e5e0ab5683efda06a93631032380727b6a80"""), xeh("5729B2AF60A4A5EE3BA6D7F255D7D2437812579942FF2C6F48611669135DD695") ), new EncapsulateTestCase( xeh(""" -6914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE"""), +5f0436c441361e37075a75830c1b0310e763205645d482c4870336de131a6cfcb2435119341cadb7e70eb3a7b7207237c654814c9a6e04c5955e5135c9d311786802df76bf33c37a04f84ec0f9311ac371664ca11dd56218f65240b97819165d90b113e955a19834a144e1ba40f97cf815b90b4cb7b06612168c6c46e11d4d79857f04cf00bc8e11b930588216e7ea3a5c99caae7b076a4680bd76aa3e1b806f428c8301641640b938743770b5c1ded957b8b1aae1fa28e6f19a3ac59f50a59a9a346766c9ae68a5c920b0377891511cc3b3fea22a0b7216ab1c1d8d97139d985f13345a073434150083cdea7977d9a5eae98314d6898fa14e89e4cc7d417d4b060baf854840e12505fca30bdc0d60a12fd30bacbd62287533aad397c208b0bbcd50b8f19431fe727460d754668309090cc81d8b7946333cb6fb890e152069624a923476369879f04771a0db28002ab860578fe351a2a1a2a11c198dab6b656a4580caa45e45d3987c4445f312c4d14c7f70505272364aa8341b1753af08040af6501f69e96d108a48ad245ba2663aa154339cb48d4bf55acfb9534ec42c06a11e4d4b3659f65ccda82661b1700090187cc57b17b50d66ebb7a44672191193dee20e9ce21bcb36be9d312941d622062c7906f5ccbeabc861d85ecff006300ca549043dfccc4400118a18b49eadb276ac45469ad69ce16c60bb717368d6c7b2f068bed1b2fa930552731444f08a239bb65f173b7e61730c68bf39656ce5f7425601519a2773aeaa3795d98db1146912683396b6c9232b498b9bcd3adc70f0935d71e56737a422b5792f75b12457f8817d926c44f8a8e2a34573ba7228204cd5ba24c7f245dfa0c1fc50be04e36f407043a4aa7a6f62b271ebc30bd76a80d242b934cb8448535ae51dd43b7614a736d72c14a577915f9c6b62cc10d0315442614a36f32d94077e65978430597a6694410888299939784237c991262d38a540a5e84f326906a7883a6ac3b05bd6051c5a11ae47809b30ac9a31226281a39f63be3876bbb6a896857a5177a94b8193acdb441125236c9cc291f2d7bea99025b282328c571e93f2bcc943b3d1f6ca4e3784f4314e570b48d483b6b20b9dc41280610aaa3a345e2645a3afe5b4f3b507b9c1a3502c84f581617f2449035ba524ca6a454c87c57652db9535b926557a19b157fb3f3896116ac1488a000f20c5251017c34416bf6d13c178204484c83da35817d0975183170a100c0b24404645d7b551ea24569c5d92235e6df27b105c065f66b23f4b119e5aaf6eb9ad73f3ac55826faa55021ee116d9ea096c350ed1c659751bac4a57c8c70126e736ba26f276b5391096541236b3360d9b76bea1b519d141f8fc9f4e8411d02702ff366aa7e1a5629295de395eb251c63e5170c1db22af621dadab30ffac21a9b400c8a7c30beb194f027858569029b19e43929901e18fc45c1d7dd6b464b64b14984f21286ca02124beec214d354ab820b4e4aa8a26a35fded6cf0d95a26f20123a909a7fa708c74580b7984ee082a05f8b481086b109d61b26fbc171844bc29c0ed42bbad4cc167935a9d1524a4e162a4d598a6e23ce1d404cc4a5b9b80481fa3b1e416027a590880b38517ee34e768c61c93cc170c4c8a8d3abf3e79ad2b53e710cc521027d2b8366ba7583e9744d68ebc33b4b45b8f04e44b98f890bbe3bbc0209d93a9d6140e6260cf28740fa35cd68513d4b024d5d5463d664b3d11a261d5bc5c1b8ac71f247eec4c66b72812c308b3b93a633b80e2ecc502813cfb4339c24ab91129c93b56b4d87a132d835986e994bf61432dfa98477dc70f7a66b53f88843e86ab729b5f79cca14e2263dfc868e2b81432bc47fd1aeac51c3a1d49549423d40a86210317e39d9ad15019e90050bcb882ef7dc09377a961465098d357061f8549ccbc7f951639e3a73b3e7a6db109ae463ca41038fa32418ae4777372121a5470622964f514c76c108535d7913fa16954d6668e2e01b16b492dce96a932532baf3a413a3c58967a46b80c5acf276e2a86cbf499009a5685f392dbaeb4621b66d9f1a631a60b59d03a8cef18f87c9c2cfe6290130198e67b8d095019b0484e0d274e488640db473d1402929cb501e9291cc428d37c0264d1c3edaf23921b66855f3b90ee38931192e0b30d24650e4c7c62b62b0bb885e610e1a9e542c7ef8f4f03f8ec11130"""), xeh("FE8AD6E3F3EF1FD1890FB7FF75A8CD9B2A04CAFA7ACEAA99D06D116B81039DEE") ), new EncapsulateTestCase( xeh(""" -DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F065"""), +09d4099084b07199a5cfc53573e6291a7978b848844c008f3fd45aae742d49f4af1229c49189bdfe177ee5c2c5315940f0024009eb4bafa5965a472d87767d4dbcbed6f6af41307cb48ba8f9828f229160df4581b59617d34203450b0426593947fc84d739784528081105c2c0fb9a7af8be6045c8606cb22d1324d5abbdb773c69f4bc88fa15e136509dbeb698ea0bdfed69f8ed67477e10244304f866a912d2c01bb4c428081aa46b862a6d420cbe7386596c34ec87f11084ed0493952a656939c5614e6afe7a022756621b77bc27648be0e86a763e36f8015b9e5e68684f73680773b5d5a9f37e90186fa13c11604e9f231ebe02a9c531370778579649f33c70e4be811ed668e62d28f67f7133f86695b790bfd2a39a0f22a49195ae4a40196a974a1b3424f4c574778b0036b21b356835eb2a142084aa2b736e4a810f08a2199c86c3e8a5ccf8386498592ab3570c6677ef089c0d05b06ccf4049314a8b29c9d9c18ce40933cb857941cb59abcb499ef53869f155bf2f4ae7e1c3e41889bb0682de1b4ba1ada65289669a55807d10672fce9142d1a8a7ca20c332b4064ca8a1fa5a8c4a898c76cb837b44013376fe1577b0104c95b3757c40a8c70d926216c4e9cf072ce4798b8d38776b3786f6136dec4b9c3a35ae088905df969ece6bd26572c91d78242060c54c9573a789d5110b25db9a5ad1474f2694b31553d3dc63d69913650287f6296854c46a10a54acf869757de3bb21342d26825a34704966e5239ad16b57458ad75881157988d5b0577d432b89ec573da15152e89afc7cb0c587a3db87bfe0db286c528c4b211382172064c94210f3b4c698124d860a13e12b87756bdd0002423649d7e7a1f57676c6e53c1ef6bb6152a932a110810ab80c2001aa53cab449a6d8b9a734e48de8f4777fb7c6f7408c2c8928f72482950b6497c2500af7568d514c4c34151f6749a0a6b79ddbc12e03c5563702ea733ea142035ab4149bb58ee56970378727e6215607a64fbbe7888323bb1e265dccea33d1f96b8e797532249092a202f3f9c9e7026483e78251cc57c1977c1e5a4ce4f9bb6eb4983823998101a58b0b785823b3352c6a5e2a8660fc143a5c2653e6a3920a8d75c29247a846f578abf56c2dae289e62d1a581dc561c946f00edc202222e0489b697c786ddd18f38a937c7f9b9cd0a3d85a9960ab2b470e5c57fa15991e74517fa9757a4a62a245392f3361f7601cf0040e391808235a593a88662895140e468e88ac4553908630564e61a89cfa2c2271a27c848a08b97adc0444a7b72bc0051695e197c91eb4af7ab869a4b9325ba36d3636645b23660b0a101eb0af171470dac7e4d72c53bf4070706c840f11d8514913873667f7ac5ffb6c011aa6dbc34c8bd22c597e0814feab71a99b2969b8679c4368282bd5a109781b02561b59164832b6096a13b204de5d8592b9045efa538072331f984b42f43a44d4ca6e2792bf26a4beb24089d046b13c25ec3612a73c19a8332a9fff70d5ff71851da2927a13942e8aac355582fa347920443f9a76c1d942d624c8b696bc3825675a6150cc56b0a3e5a19bd6782ce9781f4f2a4fe6b632de07047828713b23d98c91c99091571d90c3438c8b64592ffd747f29351d8ba91a2d6349da30247db82e2051cde3b0094c4aedf7556596968ae6acba7a790cba9c1de26689cbcaa4d61bec738a17f33b666764a2ffbafb488530f0c1b93617be1677a53cca42908c8c7a051ecb6a894273becd75313420b3d763a57ccb7cc73c8e94aca79ec03873c2ceea96b16d67c34c99f1f3642eb6948f4282e8d50ac30a10a47ab8859d54f86011a652913194c8b5e3139fb65039b4493a07a95b89177a4d1798d35cc1b10c9f0ea8b1afcb5ecb2841b143930c58ce8ac90b3b11f43837645a6b9f6c08b538a2b7b9272464b9707ab4faf9253012cbc985ac5594a7609a1b82c13bb886c564b577247f886382872d32102d0a31ed410942c5b1be910bc63b0212eb918eb0485e6734fc5f736aaf84467692534e0161c4258eeda24763894d0598795d48d99c56771139fcc016e516a29203774d038610bb5a57314a9ce0c677d192143d34c8b2148fc190f9514820bf8c8686a4413387cff6863fce50cc85cad03b350de7548972a4168f154337006e6873a14aabbe7a7f23ddbecee63d35e15fe156d0a508c235b058056ca"""), xeh("0AA3B1F8FFA63F89F949DA18B6D8570BC5811F85A4BFB293E9D411ACD43C3227") ), new EncapsulateTestCase( xeh(""" -8FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941"""), +d3aa9a1476a6b477cf20196569ca9cc4202176926f2e6b76cbf4b4abb4b183847e068c585d7c65ada8c29dec27a32642647901a23c635f6751ae131c34815b362ca00618554c4a9d028a6aeb81c0014815ebfc7f7f7001edeb5890995a25b89332c466c39888b9b542d741954a27b5dfc72a65a0cd453b8ca9529701d49d3cf21922a7a365fa3f73778161534274b3244a31a192c6075f2562f04c6c819111fb1a099c114e07e813a472a802a0af3167c7d1a68583c57305099cf4e9a0a5c724eb2a318ce0582078090f35b856f773194245e6678b9e77160201cdf2fa8d4456671fc9bcca217a2625784e4052e2f339c544a5e589b24faca6e3c332891b2bbb5849c6ab2805a4b8d01199feb49250bb8d30380ac3651c7a07525556c9d925001568a73b804f0d1b0e9b9ca8453c9303669618f398b95ac2e304432256811b910ae2570009c5199a110ad8424f135b93d99c375243c37fd36100ab89b88b1997d3ab9eba0bb6b33a8774b07c33a589c236be155b2df1420e75a0962315eca254a1fb01ed63102fd62f249c79dd051addd531597cac00757014e01366b771d9e06e825082a4a310f8f72b7cf644e56c59f751affa55985e42447adc6775187170aa0093ba12e65b1b3a2aa5b3739cf2b09c3677184d6302141b8eb4985fde8a993782c256f0ce35dc5f973cc7b4987b29a333e38ac3131b63638003c600b5077b6b5b7b9a246a02f466621ed67d4d419c65ac1144054120439424f58d9f776a9a3a2596d10de267b20848c6245350e68b593ec7b49c877e5614be71a624fde99c0423216302b3106a29c85698f1b3a96895aa97c021c9b539fa66230ba8c35b068c5b2565f974b112140db6588be7016bc1b2082be9a0f5394544141643b75270752bfc6920c288468330ca4b3171a715756dcb467ba635f7d17753e0c1d3778114227d8678cf63f580adf5407e9353cbc546068207f83b4f16ac1df250a1f8d499fcc9471de920faf2a23e27055fec098f791ca19b094fd7aef23201041378cb51501ad0691a39870dbc8d6c9ca2d6003de995b2cef5957745c6d04194d067a2c1140d7c6aa3e271b4b95ca49ecb9bb94254e562905a0623cd670befa9c5fb971e2a69151d209fe4494ea753a926b4524b05793fe5c1b55036a44061d8d1668bf0094cb14004d3759f510703bcb22d730091370e09c1022141c3b35035c2a08921e7a23c5899ece95136936b68e839b021a97499bd30dcbb1341141698594225cf52740ba1b68ea20768d7a8cf3af91f7c1b1a49817c04f475014b0b6ae38a81f03260ac672c6c5a7bd2b8f07b3e5243028a0c15aee58ade16c2ac72985de1525bb34f99090d67097c11f3303b219fa68453fcc03ec6c84aab448d7c308d76253fd5078764769fde087b6c955c1399b54ae068de44c0a282a7772154b50177b56c6a6c10a317d292bdfb4d447045072857a0a67dc5b87599424705ca9d6dc18c88134ea1c746ead5018d00bad1eca2b84217b53743fb377765b674d30aca06c79ae5c2bd0cc06e4f8249d8e5acd3177747d65a8692a3db8b1ea49504de28b67fa1ca3c3bb1b1365fbbdb3d40d666ad72b286b221ddcc505388819c993652c72397fb158a175906546e1c212609dc7b00150987b408b479bba5d290e0130d4c98c33f543da186bc514ab453f13404619e841c634b4c5486c2ab80258ade6007c8895554e819b5e894b1b6933692b3eef79571b8b38493c3cebb915c6aa35c5cc543547400b81b6058a6450ac5a7a81e8adb26f9a8367da7bf8cd2496031016ac92fa7853708463911780fc536cd54f498f807a5d029a24bac5c1b300351367e09d1ce68e6af97406c74f5c7ff796f4ecc10227bcb4bbc27044c9c1e7404bc15985cfc2dc166088119989ee32789bcb95fd0103ad969fa164bb5cca5cd5c3e6fb65f989a118d6a2bed2b59121b5000f64fa9fbc723a1969b93ccb83b661ab1b25913bf2f6cb604e0218cec9c8eb2aff60c948864288ab6bf1aa1bc65b7894e1357173ab691630821d63b75380958ca91cc6a9785556e4b63b5920c0e3876646e6833e542a250399b16814236524f31a470ef05cfd2dc0e01ab2b4d5a9b70c4cc5832b72a632e2733829c9753ae5a928106267097bef54b47918aabfcf91c1a6b9ef3f1154f8a7f309babe4a75743409f7b155e6557807d6b428f720e0bf260c6bf"""), xeh("2429F93D29E48EB6A25ABBA3EE2F3423CDDDD0ECF4B2090C6CA5BF4883F4F3BA") ), new EncapsulateTestCase( xeh(""" -FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB388"""), +5b42bbf7fa109a95c24b6a71902c2e2d806d1d2baeb0c2068ef710a989211b64636cf58bcf43a3eac1119f809a26f02a216341f4b60b3c7516a1cc40572c6855bc29d006737ce64739268d0bc59718b9aa34a82fc9834fb05b27593a708ac4756c28342a148b2173b4cd023fad458b0ec6807f421401991dae15cbd8b01181294f95e0a64446710c41671ae3b298202fc44045541ba5be8516c8e52e743c503c9cbf69d6007fe79c61255872d312e1b9843300a6b436a96403bc33f6577bd4ade56bba41ebc964028ae6684c65e0c348c7ac445bc6b3021529676d5c40a3255930f2118d2343a866a6c5f11c3a1c85a790f25c5096c816166d2d08cacb3bc503d83ca9d1ced3aa0372a3235e06ce21f3a8ce609621c954bc383c97b49f23e2329ce9b092037e661b361f9bb13a285cd77c02cbb6cba1e37cae8a6264448e07401ada6896baa3189a527071e52dca12211135b6c360158fc60ec2b692c119042565172ae9c7c5e15e1b1a0952e772d61b57e66680b8359cd4726421930562562913c0c30ee486b023c8e36926bbb00f1fcb4e89600bf7d79905794487ca1dc5d69264fc56872588faa81a755b3227d2532ef54f8b0a91b8a6ae66cb55d34197b7c71e69c7bd39f8276e35117e96775b6c6501034f81267222f54a3f7b94e4a7a3e3ca04948b4f17300b92330d43a41b3de69702c2bfb9272eff89868551beebe890cd002a86d8566ae5cf47a4ceea731ec574684533796162ae9f206dad42272e8a7f7e7c97f93334cc833396324a8654480e5193a8e0918b48015de487df1590b0f7627cea9fab8c3bc1cc31c52a7ae3e7173a7a8c420c7090cb0cfbb0b419d53af678b5db9244dc8b8645f6c093f1b14ba5b65e4c0b8a875d4d86266aba296e648670867b7af5ab2392c4193b9f83052425362c5ce4a45dfc3e5d9960ad3b392ef6348fc7a164b494f75476b78c3f2557cb898a70af6280b7053823727e18a7130fc777b7e81cb8952f23b9b27dc02447bab51dbb9c0dea135db473906987c5ba76b0424848bca4e09864db2cad5e97adbd00629219abf8978dacfb8370f2ac6057477cc7829b6c452d242299c0b314855c5a5c61ee4557555795286c904d08aebfd17edd57195f831321ea02d68493cc994dc8370e219152f5245560875a88c3b919f9ca9a745ee8b942e1316a177a9471cc84984c31b59b8190a9207e4ac1ba253093e7585621878a3004d21851f349805bd70573580f9a98c97d6a2e790c0305316040f64533a6bfdce19d9ab8658ed26dc39837fddc2be9c66012eb76bac7b8f2c05361ca1ea7e0a77ec18187565f3c4b43a6397da9a16a1987ac8c700996124a10789ac7e0932fb820f4f18a9a7675257c7cd08249f4185a1c7ab357470e8a35c688a236b4191ade41bb9271a3798380d4a2a643e302a53396fa8976d5b2096724ce85ca4cb36ba8f7bb470f534fb496a7104675a0367b05f090f4748145ca680a489fdf719612d52e610352462605c1a43d39945adbc42338424146c0707cb28b986888468b85f5347c8ccb6456dc442903baaee62f4bc1b56fb27dbb50c96d9b359894a823b812afeba2ba39b8af7227b8b58580a2603111a6fa511ba7e1c7ac4a037eb53a8caaa31eb551339212048865f4a5c8aa207ad8688c1e0626fee782fb6c0b97f5463d8830747b3eff7136a1a7a83d3c5cf5b32bc42b6bf06b4616055ba6b53fdf365b2c6209fc5239ad269263bc9458bcc2bf45cca868b4eda432d35a0caf361d9145a4200bc9a770b5571095eb18cdcdc407390099d43194fe096df8133a22753b7749c7b51c11b4b7a59427590f71091c969ea619601d494c91cacc34133e0cf75d1d34235a45b6977aa39847a01e1a5fe4e2c2a509a986249c482443cfa8cf3ff9358541757a776efbd7148383ac98289b4d68a579ac3fff02adbe7236e6d06c8416be80445de82619b065436468b0535906ecac1f563b5daa78b89c6ba5d4283b06795b4f88022be4b1b11ac075e8b571fc7af7d91f13334dc18a317ab4794ed69946c45a615c19209302cadc2f50c767840b397a9934bbc74d3d990a13e656d8a1347d4a46c6676402d563a0e860df9a5f0a911a7193be4b162428e0cb68b66b35146de6b2a57871bad3b166bf4a605bf3633912c31d0cb2e100c00ec9501d0be84468dabaf76fa2356a58155898e69a3c0e7d683c"""), xeh("B65043CD3672CF9AE2CACC94F923CEF63B5127ABC63C2A5AE6C064B8C6FE7C57") ), new EncapsulateTestCase( xeh(""" -E7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA"""), +d4f6ab585b2b11fc091bb28a92ab2a5d061a3e4890ba687cf532201369883ff26ffaa019319b6914b8a2d76091aecb59e37a0916e5380f2143cb34176b6310771703be07305869bab8d98fd0532847446fa156446f2ab465499f7aa81f450b09df23ce66d0c0e6b82579425748da4a4cb1a13f711791300d21c0bf8a5191f3a0817ed4519931150e3161bc1b076383056db994a3775a27b61c0cec0e5c3584295b01e9855a188a184f78baff6a4ecbc5cc1b0227a5f12498d0b90ecc450d5a278d74807af78b3ae94bae64a3baec0c6b109a57800297918bf949b69c5c905f944ec8cb7e84865d67382c6e3546bb4c891da34eed09028bb3677ba624a9d5c967e94b65e24b380719517712c12aad85672f20c77b19e477490a411389b5ef63429b15a1a8d680b0082d586955cd67163ea7a7c8c26e661c52eaba8503b14b168c8c79fb7e73109b135c7ef5790afe65853509196b099aabe81a525a0d6b6b3cb2d5400a916416688d8f960d1607c777db22b3b2954cdb9e3932432e24805f02aebf672e8e6640d949221d3570d901acd9863566f439f5a4525367337b718536623b23c16950dc59c4eb9c00b76e0d11a942fa4e531a6152ababe6e54c101433b5b41c038907a548c69b1111aec34d64e084863c950c4903493b768b831a4acc04059083d6e7a25bd71b68dc1d10309f4edb246b7576acc70838034bc0e050ab40808a298ac7571d6a392bfbe57ce2570f18f35a109ac32fb9cb7e5a1da9748cfacc022b15abcdc469e79319bce47262012334478f301c1c42583ce84116a251a0e4d8aa38366561a22552eab180b1634442138a1c370d23a6acd393cdac517f59acedea7e620b4458b03585410d3edc5264f9375ceb6df9f870c8d7393dd0c2394882179c991933b8e474a85ccc6338124604727bab826553927d86541a4da61fea2581c5d15cb70b740e7b38b1787d0ea7acb6843fda6c5dff60ced980b80775501120c46f78cbc49a4ec63a98d324a9a177bbdd74ba0ee0108187ac0e245cfc7420a9294019573453763cd4b9c1bea9366d8cc7c996853c5c172f9b0d667caee2395b7a7c7fa036be9ce7b59b96663d260b69940a2a83624a62623e8906352939338c724a038337a59f59392f759c516cc417478cb7fd8c92ce868127e156ad4abcc714328ce67e2082cf2805c3df4b5be17b29a2446fbe26a50a54afbfc47bfa27855563b64e3846e934311f515f20c68860012c43195e6a45684eda2de3f9af70549d3f41c0b17519b02a7d29b076e49a3f80554c8bd7cfdf12a42d9b511c4ba187845b5b725b1a384febb470e3063312e9a05e846fe28b155dd00253a3afb9c2143ebb0683b03457c937efb1158fa93130058213176cd7888598e457d33cc6a600c2fd465b3629cfe84bc51cb3aa8bc4111626bb57858c00ab7b8b13c729a052bc222b06745b5181bf1c58341d239db92378a83b20a7e1299d407295fb94beb2c111f07c57401e522149f9c2b0a6d369b6f829b09970b660aa3dd6b0792b21797716de834286d662a3b03c38cc9ff1aa982dacc0d6892cf01492dfc506e7c37ecb8b82603c7d65843cd011172033203e294e6920b2007631f377cd003d8b9a4421614cc20e126d07f05205d0c1883910d9172aac4864ff7b7a8b1a1f5a8c773427aaea747db3191d312b4f4a82b7d9b4ba69313e6b7cb310507d03f47f8186a15d49030df21c144b639a7721357aa2fce77149507a7c5430d9611d0e7a5c93e54593314f3749ab0025603417173b13bfd7f32c6f854238e2675a948130ea2213a749da0c18001791f31755ccd829d76c5c62eb58554277f262427506cb17143557c919443922a09c1b735943c1a411e9db8a6b5c0dfc73a06d49c86e5b5fb03677f234bc97a2931af2ac804c0a9d721ac2468058a037e53346175981c879be43400a1c0760ec3096a56c0b2f11c9b97a87bf388058424faba04abf8b4d7f5069a4f26b14e39917b7858465761fd802c7c8cc2ce11cbdd04a519bbed86261f3b3b3b07174c26008b4d71311a951e0584100ea7d97881da990ca3cbc1d9f596a798cb0b1f79353413871e5a4f093b4825a47833a99994848af3378849b089b3843c7b153e4dc10896b4a6aa9848c17cfd3e0a0c491b90587cd2611908fa04bda829f0b494b045f938e08a7bcf1212fd194fac918ead125d88e6c4463a04689"""), xeh("6C8C075658F4257D42010EDFB1D7EA290D3344EE6E4C43DA799366985AD52243") ), new EncapsulateTestCase( xeh(""" -F1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8"""), +bbf41352fb8040963385438d80125b7b78a7bb42515971c90c01323d9b3e75697ee3729f7521301d11518b92154436843987531887631819167405c36c35bc3be88d957053237bcbe1fc59fde76f1fb1c0bb4ab166ba098e6c4b58d26ba606589c568601c507a6fb149e30a9ddf126a4491812813ed0ac12854b3bde1b683cd23c588082066303931941aa5856bb94a0c932c85f9b9a4796b9152172647221d3e611b94b667e0985bac481f69ca20fa04dd57c42adb71ddb51933ff36dff38bb580b9bb0a666e80372c8e2b8c29a711f484d11c1ce58025c17d053196b50ed28342fba9b24b8093b7c286a4c1712346cf886454868ba79d53fa445733af9582113c85408c2e8473a3bc358af200cdeea56e44086e1179ed300204dd6b39815616dda5923dbbacff091970a57166b0ab5f1b25e1c1d2cc495151b97dd1aa87903204cd3b3b19830ff010d4df31ac3c7623ab64d951c9fd502ba14f4c884661d65d249c33b2f8d225c81f99f3bd88fc5a71f40722849b6b838c754a11a3b8bc8673cf900dc92b6f4f66b139c76a420abb5a2be9592ae1f3045a8da088871b45ab66610b64b163b38f641beee8a9a8f13a30996c262b2b9231241b34b5abef4830dfa922ed98a75f61cdd59666e3c728cbc8a6132a343a458beeb0702fc962439b2afe7b971ec62aa593cbe874b8a8c923f963060d1ad64bb6ad1dac893cc3ab5188e7943cf184b7b18ab26133ba4109a57207147f5e25e15302da5e82069aa721f77557c39c760d28cf37715f7a943de605193e29a6a94ae821675eb2b3f08ec4d7f0a99c5e71cb01292b327c107b61e6bf99066d74a9c8b47e99a05d8f2b9a1a5b12723c101220c57b509a42c5b28e853dd75251185661b61499ef978bd1ab9b92864ce013ce2123515ca5aad6b108660b4ff1492bb124f5bfaac592107c2678c5f04c2b658bd31cccb7a09028f48a245e638e8bcad19bbb2dfb6ba3bc10c487359b3b0421eaacdbe033b6d7a8d5d2311bcec5148226d4dec2061265c25b0746af8c63cf99f687a04c237739d648de7919cdb59973ba35d85187d20212ea537cecdd9c68de59345fa0dedd31ac6b21a7053adee561851b7be01770e07daaf903c2738dc835cccb05f5a931e2c4d2541a8328983d26b20de5bca159973bc01301d0541a8e311ef7046ee9b51a0f67d5202d0ea8c8217226a622b32b684066f2a000ae22cb1e29b47176e7973b3e9d4c18f22919a89a6573147129a43998886e8d95c804c15a01084f3d81d7f0288cfb34276536389344ed7c09eb47b9d20300abfea2a0b2878090819477a640e39cb7aa1643d4a59bc6488494a0ec3073dad9706b752c30b123fff3a1e66a8b575587e3b119d83e1b833893056b696ed49a399d11278f23f456b5192fa324fc4222dd247acb005dd50c918893819545f59b8b5550bd0a3d97ec24a5c22d4b8fb12290ce4cc96528893f772dce5c52dc0114f19c6ed026928f1092349475a020739aba5f5a45b8843157a76945dc84e7284572395345e695090b37edd895b22870b39ec07b36867b5dacff5392bede2680d74cc2272713be24ed37a22e33c36a84ca9643a46c68112a9d12aeaf67bc3160080113bea680d9b1bcfdf75be1c18c9f2e44781b18b59a090be8aa957c366a4b24a33b9b6d055674593470f37caf456b367fba266f34160d4cea1605d6140be110a93b2a57e06dc811b67572510549889002ae53dbdcc758fa1aa2e4bce4d6ba0dbd09ff3f736ce630c7b454096d6415ea32b797404f598c4b02a3dd6c98332b7440735a71124178a0622194993b442c5596bca2caaac46d77f6713a547980399c18e5685cd9dc879194cab66b99de4e2888952808b15c1bab5b712ab3e0c781b209162818cb3985b77f4e915e86779ecc5b2096104f512cbf1162b9aeba6a3546397e608d23861fa3aa5847a4cbea7229f5338ac4161b9765d74b175a4e95a68a6cebfd6ce796214163ac5b314c0deb2a3463b1f7e56b6ada724a2827f60647a92ea4f33d36d7683402fb12543f73a2804abd00371073306f06aab9705819091c9afab226514bed5c46f8c3c8046787602501d9d4561582164baf07497d09beaf06cb2a49627663e04cabf05e5bd55f9c0f75ca0a93678ffe69d7f8034b4f0898ce5ca9a26f52b3bae41398ef444b73decfdace24a6d62657cfe717bfbb904ea4bde70"""), xeh("BD990171C3252230BE21FA7F186A121686187B77C234C37CA5122A7AC77E318B") ), new EncapsulateTestCase( xeh(""" -1909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0"""), +b36a6f80ebac6014cff91b17321b0fa32c4d1eccc3dec3707cd34c7bc63e62d2b57ec0314b659dff4263c0f2c5fae2a37a84b0dd415275b3452894904ef146f5728a76a56c9447988767390a693ff7e91fa6e36f3e5a5b42b97f1205704218379231169340c416f4737e06364b935186e79a6bc0912938ac1ef818d57878ee872af70c7f31e8a5da0746ff4137e8f9b6bd7b4b32b47e12660b239c77115c72741c74b8dab0fcd07180c35e0adcbd2d58b726e3775d288a6312aa158620022b623bb29e141c33e0532e5dfa67da9476f49a6f4e6b001597a54371be84d70d04340c2f403db373a1afb102780b5050c841d98b10af489a39f8c2e473c23f202f05a20dfc4844cf1126c562cc9610a98b0a2d5407169db917969b1aa5c314ccc96290d2c27743b1efdc410802c78543ae40686cff6b3dca439e243c867d70bb957086abb6a91b49c7a39bc2dd107f65c7bba534c1216857d2b1a7ee99ca0556b3405b25da0a0941f403d0e34677e49d1ca84f267bc86ff0154614ce5b3526aec88f95285c316175e15b4fb92bb3d2a99d70a0259ed295eb87b90b5b2f5e2a757692262866c70a9cb8d843490e563594344e05a4051b3155fb8817ed53431d5c0318146cc31b0c524b6410d53aa0612a51f1c763941c4cd42628f212c04cae54b6ca05a5afdab8ba54f5666a13396006afe7005f612180002d1005795c468cca3d778938e187b00bc29220266047b22df76b18040160a48e6378c99fc5afa4020fb2b135ca913c78c73363d93d10677bd6764a27221ef2a2600f5b867b52c375cca78846880ac448f1086ff678220b7a238675b740c21bfec76559d573a6a84190c750cb502d9c7663d50987876b607f548ef76b764d03b704781d3b324ed2d7c1ad285a3e1ab1e5d6c7ff49495825b1b41a5ac2f524bf27c2e875aab1023c5f058f1a7881c3e60ab9fb56d15562b6fcb8c8c04a272c8ee6c807baf6227330071e6c49c8c805b89b6acb2025b13c08fd9916cf40191b9520409a6cfbac821fe8951c027f84a11dce4c54db98be7427b724331c64169aec4304cd71128448473f599eeb8239b1463cbd43c0836755170c19b3108dbe42bcc290cf23619a303230f9b0982c3b7307734e940807245bc097649d2eb9ae2b0695fb56b16cf90eecec1a50c5157d48098a063b53158855c9a1f1db9ea92b7bdc2488bdd28c095ac4e3374311c2754cc56dc8e511a5bb4cd486cce605527d594ec1dc1356b9bc938c0488b6b6d53243f2443223ba200b0c32c6f49322545ffa8a2b1bab914a72918a658b6a053d91249fe0c20360116eb3090015c161d4480d492bc7644762a48b3f6b558eb1f9b34cc39398cb266be91c414a3ba790c9c92129e5d40ddbd3150a5c002f763484546519c3a2ed327192bcc80f4710e8690a8d30a36059b12df6c107d1a73d9bc57796ba08fa01fc0c2a4f8b7a63074786729e0596615ff4b7c957959ffb1c5537508b191507e16d33d1bee9eb2148618bc8b279f0e92072b8c037565251992e87db4c0de8775d151ad13b2c375a46688518e5a2c409e32b9f314e3b177d72a908f3fa0010c87724aa2a94ba6a2728824719c6a1b0a2e07c7a364a0a62cc2730966ccdc96eed27341f77389a854fd12b9aefc0aa4c59a8aba457c57222e7065be09b593dea82279c8f67971a46878bf557b8dc095a9a0241d3b64ebe02137ab14eecd7410bc70efd3c08c1d6220f597eeabcaeb4a7b129ca73fd96872077577e44c804bb55d02607234961816b85944913dd83c5c835b1c0cc94f871a29073b8912973dd430246f84780d51ab9e163cfec5bc3472e02377bc9a2760ef5529568a4497c556e9a5f71526396aacc3e86158ea4189906b8ac277a90e383e298c8a1b98623cc909f18c894daa83338bc3f3b57152cc472889ba297a533d0554a3186229a8514c9c4826725249c61e4411963329eb99a37a4337e24c2257e5354ec5c2e4cd85bdea15c4e16cffcc628dad7c3ed9066287b587cbab64f0ab3aceb69494a333d240074c989cde4932d291f8edb065577985f68421d312e429a15cb21b31576c8d0b470c2177cf7369d45ac839c5c191acb40e62a115364c8875883ac507e5dc90a6cdbc6a540b396b422e488bc7d25c8287b79efc32085758d593b33882f218e758a3186d9cf309538fc57b81edc3ad0d228aeef39b32aef07a4054c"""), xeh("135056EAAD8A28DEB1BE77EEA30CDEBC7B3DD89D1444DBAE145F39898256ADB3") - ), - new EncapsulateTestCase( - xeh(""" -11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BA"""), - xeh("54E7B2E3305950EA570F823FE36A7999E419BB36181B5514860BED41F418EE77") - ), - new EncapsulateTestCase( - xeh(""" -4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603"""), - xeh("F2C864FFBDC366EB96BC5F5FDE0D4B3348A07E861D9EBA90E70896F7FFCBD55E") - ), - new EncapsulateTestCase( - xeh(""" -44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1"""), - xeh("EF29D988D373C381541AC8723EB67C68CEDFB9DEC0FF2B40CDC763378B380C12") - ), - new EncapsulateTestCase( - xeh(""" -E2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5"""), - xeh("3D6441A62F1998E2B5B9B1E73A9A5022FD005778204977F66F7A5FCEAF17E30E") - ), - new EncapsulateTestCase( - xeh(""" -53EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD"""), - xeh("637B7A1B57EB76C50417601EB71269E050008F415DF974C07BEF46CEFD08368E") - ), - new EncapsulateTestCase( - xeh(""" -51F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB57"""), - xeh("B5C84B4535CC622A5D6B93229BCE68789D3014D500D3263B6E0F54359D20ECE8") - ), - new EncapsulateTestCase( - xeh(""" -10971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E"""), - xeh("FCB46FB66E388182DF6149F60DBD0FCA88D1BB1A9866A2C97B84848531230B48") - ), - new EncapsulateTestCase( - xeh(""" -54B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F"""), - xeh("4CED177C0A454052BCBD682B39BEA31D0D219A73184BC00C100964C25BD106D3") - ), - new EncapsulateTestCase( - xeh(""" -C701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E98345"""), - xeh("F594FE1E810814496BC73A1523FA1E0FF207AD5F5F0FD4B232C25EB9F6EB5B1C") - ), - new EncapsulateTestCase( - xeh(""" -24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F"""), - xeh("ACDF91D5B4F2047AB9C7A8C2F4809FF69B9D480334C501E6BC66D535D309B100") - ), - new EncapsulateTestCase( - xeh(""" -FE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70D"""), - xeh("696EF6079C573B67BA3531CC69730216A3A8136EB6F647481382A5CD93C6B7AF") - ), - new EncapsulateTestCase( - xeh(""" -FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FD"""), - xeh("B2180DB6D5A468155A4C45C90495F8875538F05B8B8587644B4A668CC8936447") - ), - new EncapsulateTestCase( - xeh(""" -5AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E0"""), - xeh("ACA147DD83685FDC5BE522178384DDB0C8714D0F818A5A20CD1AAA71730D8E36") - ), - new EncapsulateTestCase( - xeh(""" -9EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FC"""), - xeh("B974689F6F36C7AB262C8B97D5469ACD3BCAA3A3454F611FF0B304FE1DF6C66E") - ), - new EncapsulateTestCase( - xeh(""" -A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32D"""), - xeh("7B93EBA796CAD98FDBCEAF0B8F3BFF196C1F89125B2AA88F623A91DC6AEE3771") ) }; static DecapsulateTestCase[] decap512TestCases = new DecapsulateTestCase[] { new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +66c1c53cf37af5756e10648db20895447c40e147649357bc19a947f98a20908360dae890abf92f5db10deee57844b51bf15ca71743cbbbf647f07ba8f627a8e7bc12fa29c941b2809d48448147c94ae3081e772b4321a6be0ca55632af43bc7991483c1b4235be2c4e2582bec03c4531e8beadb504ce55a3d837c8357584d23bb430058833ab8d0c5912255a363d5b623bc88e70a293404c253127abdd3495b2d6cecca2582c7544280cd0c3f779e3facbda109a7b423b29a1c752a632c5e4094063c9a79abdd4947b530c3230ac7e567ca412b6217da030ff8a120e75746f26b8dc2429d76a0a5a06b029f5174c1079487a1432758f699032f2d32f218b625ca593d3d26f5d75b0c5651358ec8a1a6673aa7010af290c1bd1c6ae795d1b7318d4db125d970cff78c2810937a2680beb10b1200782d5682ed8ca1fb288212428918cd3517a7a999cb8ce4d442a9d82c8b13c5337355cc63b549c93c9c6016bfdcc498885baf837b360412e9f517e6f49baf1032620585b3d3270644c9530327382a5bd2ee0a538a03a0226cd1e6103f32b5e2b946e03839e4dd247f6957d357cbd1f1bcc889511306917a2377274c8bf31f41cd66a4bc93a8fb5718e88d88e1664b35cd91a7e324d4cd86a95f93a49d0aae96800a2a23b806542f9f02cc86c0497dc6f9933c772a7b497da3e64385f14c2c9b1624f37092d5c1a473e963b3aa6b67641112f501e7c5981745469163b8830113bc7f77a254750541c9e08b728b834b0cd39528f4a41e862ba4a0cc6d4415dc99a62a86562af7640d4487481c57009e1641376918db323c54b98ffc1a877e4b712d99d6708172fc6400da1761ff6ca603649ccc93824e7c601b75272580202c0434a199ffcec00b2c75da4ba041e766a8e9141785457a148517d58981fe031d332453553abab73ad287cbc610cabeb7822952b7e79db10a1dc4729f8cc39e3003756522de9cee0385383d54fd363613e8727c06a02dde3ab92c8926be48e6a386224daa106884eb18c7cfa1566ebc5ba6f9583c9a745bbc2c642522b0141743e6837e4d9a603fb403aca55bfe509c6e8499d78b750e516b8a67709468d3fa3b4d74c0a5f5a4b5cb94d8ca92188437040f9312aa41edcf274f0aace043862471591e84c0e05d61031d69f4fa11f4e8a0977673ab30b2bec0bccefe434b55632c6057842d977027ba616e6a7fec7340bb20c7331b4e2f1044e9692ab0136a0b285fde033ffb25543c5c9ffd83595e380f8e831701b1e16e040600c1c7924b6bc42331d987b7d63c007d76d198c0c32aa3e3663ca7606454a214821b15b8ebb018026aa1a618539c00d0a84c871c1baf016bc426b3d9be7598fd8148d63865bd6b455fb8a47562e95666e18405367d4cd581162fb878d8c0c3d627597a4811eee0963d4926861ea202d46a6a6e94e89b3cfdbf436fa2254f060ce6b80b4bdbb98da80417fb53eba8286b58644d8d84654fcae20906863fcaaf89abd992b176b05b2924bbe566728878b5e816b64a532ce2cd41f5a937ddadc15baf23023a19932b337f508c8fae504a3aa24261a9bd20701a2d3ceb3c72ebcd5807d358c2ed45d0b84092d6c93b74caa20ea4b5db66369d26fe64652270949a930bbd0103ea7d117e6160d9dfccded58476b94ae90036b68a40b9bfa61b15c889467a0a01342f843be8227ae9cfb1593c240a8735d8105a36c2b68e5ab97671b63a1cb1eb07495fd3bcb380aae66d20f3bb096b5db9944d83196b3bb3e321dc76c3b7d6828f366585f75a3c6d370f5580f22b385319483c9c19e6e81cc22690b18782c2d47be5c81cbb1c055cad84db9b06b15355697ea23a2374f027a63197b46f28a85d089a120848e94e9838cc72d1aeacf7d64ba69a93635c6a10ca5745645416e071a48056c78a50a0d4a60412966ab4961819918211a661cb839b01101798583934c9ce0aa447170b870306cfa02a16b9316f4f22d9b958a38b24960f0203cf2418495446c558a6ed8706d8c949e7b14cc168c965293d128ca16412ff7b221cad771d441ae3fc822d86645f5e266aaeb1df56a6185747e3312587d1b5f51e13e23586f9f3b1cf393bfb24173d7e27584b061f4258ff3c29d27167f58999b6b87a820b56fc7846cd3a0953aab07bcd256cd997b4e0172cfbdc0c2fef1b5fc616b03d1c3efaaeb7d48c64a0c839085160b4a5732eea1a09177c4895f1b454990da691770698b54c8cc8154c652046cff0fb30d40796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"""), xeh(""" -161CD259FEAA7EC6B286498A9A6F69F8B262A2E2093D0FBD76D5DC1C9FDE0DEDB36581004CB48112F852E7F87F649E8A42CD9E0349E7DABDF0A9AC1B521C37EA5241370A8AB2911CC79902C95D28224FA8896AD715209ECDD5D784E91DD9D0BE916B4565F4D5669AEE0DEF931E9768294EEC5258DE8391ECE271E7E4CFD9D23A79FAC3A8E0DB5DDD6E0107235688BBDF7BC5D5632F206C63A0C9564F30965CA58C69FF92D25A4F93A09EAB9B9085947E078A23E4D9C13B8A56E73E18DF42D6949FAF5921F2E373D450C8C09D07B152A97C245447429481D498BEB7256BC47F68F9922B0B1C62D9C23F9F733DD73792CFC7B43CBCEA277D51B2B8AD4A4F522F642CAD5C5DEB21F3627F8AF4D3E5BC9E91D4CB2F124B5BD7C2F4A050CA755BDB8056609663FB9511C9AD83B5039088CC01F0DD54353B0DD7433F0C6CEE0D075959810DEC5416522BB1F1F65547A0C2E9CC9BC17F8D39D29309EBE79F21331B75E12AF2E93F03F74F7F87D360F1DAF86CED736092A211A8158859C42E223CFE2E6E553437D80576CFD1944E97EEFF9B49E5ECCFC678EE165268DFE3D3596B4B86204A81C6063B0CDCE619FDBB96DF7DE6E0BD5270B4D59C4DC508476E7F0708F98C7A4F6645C49D06100C760C599528D1B8BBFE628191CC083C8D225A093F9F17E35574986F86BAA46898B589F3CB7DB46A45F3EDD4FAC20808F4CD0249DA693F8FABFBD4E10C02C65BA8C8610FA8C6DF3DBAEB6763DD482AF41558B1E15CC9C7A72E071685AC19A051F19245B9F77C3038A54E2958623EB8105955609E27D67CF72EC5C4A8E9B9C2924A9E2298508BABA13CF111FDFB062C9607AC1AAA6C637310A8894BF0B96F0C19136186B618DFFB275528BED1CC2715DEF412F77A3CF96645733B048A78474320D1A380F5EEDBDA21FA0125C91D3C37C54BF3752A1F8471C81FCAE2D3EDA966E14E66F223B054D79848FF9411D634024A098970ADE6A88B5F9069F760584DC4CFFFCEA8ECE11BB5566BD2360AB707DF2D21B67488D931F020069176423E6944490CB385E70B358A25346BAFCDD06D402FF24D6C1E5F61A85D""") +ea231b200f36afe0ba1bbd719812ce994d5f6f2e60403c1e4fc1a295423e38a77d66bb06645c4ebd004542d2e39655a1bcc461af8b5d1882b8405902c8c3f63082d29f263cfa9527f04d8ac9eb99b9ed322079c5bd62c8b29c8a22992eee4cd6d7152da756a405bb0565808f3ee3d592c659b6da737b7ebe5f7196b859b04dafaaa10056488d4d455a939cd640a0031dcb9b4e5dd89bd634ad9c8003b924f76702987b6914630c5da035e34ddf40af1bd6fee7eafb0c602d91ad848f45ed222ce1334bfeb6f69a01bc4e5a11d044a421adb30dcb08d86460592f2b61f67ff0f02165b1340e9f6e93f88fa8d9bf1b82da7f21fcdddae82117881416f9b48833cabf7656d138e9dbcb29e0f4d15f11f303227a8ee6d04de284d9c76e0f35103ab4303e67ed76ca2f11c2d440e6df881c39fa1f2fb435b6f8c517c6a341b1cdf45064e7b67c1cad43b2c171e5557bb78c5ddeb9af3ad756451c70f10a60157750d2f40a5ab9fae21621484b110e7232b9ea9c52ed2c1331045d555dfe87ebe3ea13c52966080fc140728a26f4438fd25b4e5559a9ecd0c3a73e23c976abf2cd38a1e2f61e6c17672b569c08f3c2ae49add14370a5c9bdd3e5e6a4c0f7b3369f95dc33c30cda832b349af1f4b8699ceb1e17d3fcf515c2358db02b9cf0ec8b0706675e5003db6cf2182e34dd9d030e90620567fb83d83df293092efe9f0e935d79bda625826d45cd4fba547005b9e416c07112286eff057429dbee4822b935b3e16f9655a5fe6f362c58c7f52c5cbc75b733911378f174f706e4bc0b37848d274a29d9de894f5dcca67f6b80185b371f3b37e43d56e374070d6831f0ae48ae96c15ca80bea4eb6f37fb528064f09eab83f95d40c4a80feba2b1860b6c4bbf44bf3e4d4a72a28755f00126f0e4cf78a81cb1d8ed56f615e043e7b4a4f219c4f0735f68589152b5e0a81241ed434313635924eaddb815d0495d5fe065bcf5c6870b76781e486643a858d972e35d9c61be9f517f28963cf836eecb05f24777f600962ece48ab25cd32b80b9e96924f7ecbc1e3f29e011b086d9627770670fb7ebdab4c5""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +9e28069ea8b958931b9241af966388e1f4c336e0a960b266896b32cf80889750ba87e53272f792a1d0bd68ca5d25035f42d092c37882ef7c627837cdf6c56aa0185facb85d03bb8c353c1d3155a94286245ea0b2476b885d7c298ee079ccc30a717b7826076a95d49f060136529855beb163265851fa256393bc590e2a7f4fa83fb3a0327fa56c3f55bbc833c3341caf82690e1596c52f00a63e49998206431b564542cc0614d7af2437ce879223f529c0db41ac2f8b8ab1449eb8078f391227dc6c62f123950720ac5c841ee96a4f80a383907c81dd6b3e2d4a040b15301fc76aa6b00029217b1d3718644672e19998a74691dc996829d7a918662cc42c43b96a1347a716f41b11c9635f4a425260a1498adc86a6a111b2997522026c6a1a0f4555bbfae0aa262282c04c1058dc9dee882b81f3c8dfea72517717f1f8b778752cef58ca93a31747f833800c632ce9072738040c0a528b7704e0266aeec4c2dd27085a702249934bfa7b47d25b8f03955c2bb42cdd107fa4359131943aa4a78f716c26d2f448eb97249688998cb80439f4124db1cfe2d41221640e82021cff731397f50ce6c9c50b181a4fc8af39680547757f481598c5ac74867b4b25fa30df83192eb57019d36b00164184792b2b1832d107d0a2d404ead54f380aba0deb8fd10a6a018c9ef1b7b7c85ca8b3811ee72730438867b6bb32a8c517175c045ce7b562f9ae7d20ce0eea053b408b5ac745851c0e735c293a7bb89d4007c0761513962816a57f44643e170008bce2a64c6295c37392f1207a9d0bcf9fb0af7c4b7956bc2e1a7cbed9e5363a4a40de2c3e2d4121ad0acf932cb5b3613e052b109038160f9c4f4d5b6daf20a6a6334a7b787a2a1754969930d2a9a8c68b67ef4a4a0aa86e22e28479db632f0c1eb0e96c00dcc309007e4edcc97da65a46227156fcbf7b43898d44c419a099cebc9248050f60fb5e4156679622bdcddb62b70a8edd86a31b766f5818afc89932578a2d0bf845da2508c6e86c08414467694ab04321cbc77fd1762e60553d098b80bdc0cc7ac2bfe3eb02f888a2141377694506ea69341ad51d02065cbbe01bd1025aaaf94bbb2bac27e678fcd7578ef9bf3026700d711aca31cd4a9641a25286b26c034228cd906434c3e2a56f01b54a98878c6842b9bc9c8d95640bd496c0956446a0cd88d344d552a838e29f48850bec6b4667749fc4266ef8d5c47f8b21e7e108f8a58d44394c8711470ce8cfc92b2e49ea5b8b15772e4389564ac8d568b700d11eb5f83d018514d5d3acbd7c63f667ad9340b2dcfb972a333df99ab2dff50f570a4d0001a413a98f4075acc5241b5e6a6132551b9c4c1c22551b5a008df7d5a218783c2810b79a52552afa922de76dc4b89d87761cfabc81d218cc3259457316333c21bc9b650f6383c350e6681c694496565fa7203d05b0caf5a22a4ccb1fe7f00f89297f3dd02915eaa2a881cd41599635abb85890649f1a4710142c4aa4b5e3d71188562ef5205925652ae7606e30dac7099495ec939fc5b0778477be94185c649c858e146cc6750d3a1a98424b2645786681a1b1095979f2313228f96d9daba787a257f4e27a4ed3377dfbc71ccb9ddb227151203798b58f44a280c733a8aa8a631fa303b26c33bae7b088121d917268aba41cc797b7a3336f12101d5ee8900872b3a1710c885811a2d8c4f0a188d4352f259b62da152bf2a022dbb9c913c1c254a44287546c01053bfea0bbe3d05a24f1b70d969feac7c7325ba69ea981c5e179ad564e7ceb4ff38b824f9754af15664ff7a807bc34e62222217b96f364907916be6ef0cc99b014f3527572e0a6be517d2225aa6eb41e4c2a80aef4a212092bdc186598a69b4d0037cfeabfb13b9a9bc0019c5a83ee659100bd76a1da4b30b686ace6291877ab9d834a641abed635b8f3c536bd6394684ba283da1fe7797580924fa6a65e9de87bf833bd2e67c4a9e037aae0b3eb1701bc69add69127a98a5157a6b3f8393cd104c31a24ad3e381997f28c482c5dd6ec24d7747b559a29d56c0f655838fca25c4ad49e6cab35da559b354b55357748edfbca6122601a945d8611863917c48ba20d53b71909746723b4355a620b880cbb63f260ccb10db6d3809a96740ed153dfd07ba60159a3194553fa93ca28513a65b047a7350a0c6f43f7a09f3e2771f461bbba1e3508c8f8931c16ee6c08e1761b10f2eee40190ab3fada5811a768b72674b1725bcf05d76c132f99a60d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"""), xeh(""" -5C26D456C6C7B0E8DF0B125E5D5428FE393655127A5E05BDD1BCAC14C47493783097B6185058FA700555DD8AF10F0F979A39A603826FFEB0B44E9487539F3F1A07C673E96640DDF754C8B98CD83473568B49D095F682C1ACF0E160AB93EB41A16A57D53B419620D351C837315080D530845CF8D63CFCCDB6E9DFBE220A2C14221AA392E6337FA364DF0D2E0398F15AC3DC822B5DD7217081107A45C8CB8EACA51E034117962AEE7EC0EE212FA67A5D4B07D355A0981E4285116ECF5CA9FAB6E3105E4DE4AEC5E32938A1EB91E65CE7B39C3B9829AA1E72B8092C3622E519EE092FAC8106D6597CEB941C763288723CB55044A36D4181052A78B424B0DE1B0260F624A8D3B317095371EE9BEEA9272250D598AC63C2138D23F99087777A902EBA2163171A07546B72FCE7F86EE3B1DC1B8EAC85440B8D241742C3771F91BF981909E4F3E2505C594761259ED3AADA6AA09181B99037A395D66E6EE4BBEF97DE6BA36C53A1808CBA50938038C151603105BD6A4199EA44BF4B08961672598CB708F896E03CD9B8F8AD89DECFBE6BE0EF0006B7BD2F4AA6EB21C0218EDE601D46924CF391AE3A44E43D96EBE84A630937C3409EF0710970C27E3ADD4E64DC64E83942ABEA9CCF498EF1FE72B254043D2775A37E0B5DDD3F596EA131E0734AFA9D0223F4CD9D1AB7304CA979AD37F717BEDC3A9526F8FC94433FE4614F82E709456F39BEE7BACC84E5A70114AF1C2AC8B9B3FAA81C8F35F5A5D24189E1A457F58166473F5F1DF0170AAB5E4AC8FC719F945CCBE6F2FED24B23321D95C4C850B278B8C4EA02E3098D5A599AA3D842CF889B7F284AC5E6E66386D63F2C860B997966B4DF2C32288A50045012B7362727B856AF4F8258509B563758752FFBB1040F3C2AD8B0DED64FC15C95C1A16DE0DAE6625A9EFFCE190FC7F3261D844C114913C6B1152A258A37761B81879B59C37A1DFAC07C3E934510B45DA44C2581A79DAFBF00FABB207306269D9B74B93F4367B3BA22CCC51B362DE16E49D9FDBF8CFF84F6CE6892CA2245D34CEB9C8759E702832B66A572DE9F3016A38F7328700F96B2E947""") +cb7eb96dc952919624e5825a24ca80f9e2a313bbfa357af50438fa22870029c8f876cbc9cef450d124df902e93618d8dbc8d1344cc51fdfcb19788872aba1f13f673c387dd64009e1ef98ed34dd5c29d8849f503dd064424b39a8b55bcb714e6d09877fd5d7d1d721b2b32b871cb453b1b00587038f5c313b807b356bbf7fb9a50a3573a2af83f0e893c32a20cd95b9046cac886f74967e6c73e718b0cf8470312cf1a9241bf25238a3bb54e01b471bfc398b5e23ea7cce32ade3169dc472b25fc7cb68997f2bee116c86415245beb30a01841acac6bd06c82a6644aefa24601a2738fb1bfc2b08199d1574dd87d9b220d12866199c01b6c3372c204855ce8884ac7393da5479818f26dacecb32e43fc0d9affa881b4952aa4b95b8cc563e1cb4b06ac2edd783bf8cc4be2dcd0d3105f73c593f40771bba6432c654f34849f704ed007652628db269bdcc6ac14f1a15fabfbeb7529a5f3d70244fa2e7bfb4efa23199b88defc15821581f6b3ccbcf3fd75e3b41dc8a50bf21309e395d8e616d7655bb3e99e3c4cf09e192725ee5eef558f84fbaecf144c69742fdb40aee854b95c80878904773311d832cc5673ff0078c4f877d4f208a538ad243ffe87b4698af6ab0d207b338715518fd794930a8650fd5cea71f035623fd19dafcfadea4f53db42e76f5e61c46f1da934a497c3142ceaaa1d2b514b9149f34d1bff9c5f71206959b6e24a034e5be92da9713d79bd885c6500ff3dab4082d488e4932420cbd395a5d612245e81e8824d317aacefa6a4c93b82f2d99865dfd5d8a03623b463f0deadc1345d123b8ff876198cfbf945c0366a20a0bf6d5ca3814504591dfd731d033a30e2728b74f859f0b91c9a16bc310450ebd69d4da09931fdaca4b5721ef2627053a47b8a290018ad50a4c2a0e543b130402a323bd94bbae64a175790da350128e99ac8d9636ba12f5de00582a61bbca9acee2eea84be49dbbbdd730e0c078f94af4bf44ff8a8de89003867f94bbfa55bbd905d7a260c23ee448c198fc7a89787ce879c04a7a77f379bd55dd8c33c484b9dd070b116645a4a44506b8488db""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +1ff7b9950a3965da1037cc7e93959b73fb975a63af4069c76ff9b2a97c2727f4bf72aca77874771e938dbbaa1237781a7560c328b6ab6b372a93969a82d9a562043bb60aba1c6a2d35249e0d248e7105421a248ed75cccea32634c4b13d05b64be97689f46c4ed78b224a99b674a2f70a79e82a025a27165a52a3a656067de520a60858f5af6cfa39952360bbf94549e4046c2b65a6683994a5cf45eb465639f13bf7adc494b02384c28c5d321c7090777bce454aab17961cb786ed9845ea29bb8f2a322a34b921420cc800c865706be4b0de4c7c9e6f8bde4f4acb58433dd71031c23553136a25bc7c1af30030f543d3a86785a4791455cae59f8be1abb8e35a4b9ee2900e6c601f76044a3235003d963eb7383bb5a88deab5bf05a621e83c3c091c410c03f07fc8d59ca7def463f69a162c027ac38ecced39754c7a9558f3299ef41c98f779db82aaa7ce75cfecc453b801b0ca77ba505c087cc8a890a6a35d1688f46042ca7755a4804b896053da6114f6acf517136c485000237bbdf4829d966b3b6c97aa0b93046e6903c82ab552bbfdc1aa1bc7635c14c058c16581c771e9ca55115cc1627fca7ff650084c09a8ab4b8cf45a8bbe7162ad99274bc9024a96465b399c94b44af882862eaa8b98b32c7b280ac909aa8c0974116596f348aae2b4f0e533d291c6eb827b8894821595892258809dba111adeb3f184c490e49330441a57ce0b5f2045f4ab182f8764930833ad2c189ed6602e61c3815d57541a5b91beb442275939238c336a220d6f60977b0a0ccc894748abd21aa064644ae7a037c02c1246ea6443b23522886a290103f16c16b5c621aa67872fbe83603c47e6724374eb57c91c14af8265858f19161e756d927417d356a50733326e97ecf7a567736c67efb4fc18558a769cb30c756ab186d0110c10bcb7432e672394146d0e03d67794744f116aacac81ccc1bb04962ca331ce742167a654fbba262ceabcb9db5baffca3e3774898ffb6611c8698ef4af489a94d1e16ca1ec18f9d49083d712fb325f7dc016d5487eabeb33e5d996bdf5b8b45a890f099b0feb3521f82d335b7558ac204e11a305d8b1526835e65a110d813499acc36a5409a15a8de46633bf587a706a7d388c5099c73adab17035a347b041cb82938da6838a11513c5756b3992ca2a40c91a450505be4cb4fd9625d209110888484033d09f8b60eeaca65330beee240f9861e768ac7218a6e41a1205f55b411e275253706c57b97ea650c6e69876f79bffed8759ce30df61465b4408a18bb003a7aa446642c90ea072f955f46044f4ed7b9a9b82749e56ad470b0d21b67b89cc7ac784f9dd016a9ca5d2b025668421c25a100dbc0328084c2e3367c022b60fc6206e40aab3a863ba8eb1f8682265af69d15aa9d173204533a1a7ad94f693310663212e4aa0e63f812f1608e1f9903f0685c9b9a797ea5939869b5421b87dfa1ce818265d5051038a9331168ce01971efc06cf02a59c9e1a03373a600f216f779aa73171be66f95d81808daf63a26cc3709ab58f22659ca9587c01029d915c7554946b217044e65a6c98258f6a0a2608a9cdb4c35a0e06c93b19988c221c96b79729cc227ad5c3d4f558062ca3179b8a0b6c0d6de0aaa466c498065ce690278b8980c7c567d308b181b06667f297ee9caa28ac2f5ab454b8045eea583d20993bf69359be500247b3a2ff0b95e243af49b6a08eb19c00f31f3611837cc64b85d8bc35da9466fc12967b158dba95782ab771c134f9945df0b02644fbc949cc633419c48643764e0679a690cdf0239b3aa49a58e171241a106c151b75197f7432cca3d6c133cca0a4902ed6c299a479224ec7baf4243152877adf3255ea114fa01a65a53ca47e3a6dff072d991730414754c831b3763a6673e9b8f4f7ca4d3891a33c542380cfbfe16a650ab749d79e08570629116ef7d50338f26834e298dec8abbcf588f37b428f211434666a1c6041a3a09918293fbff54d35c75c7dba2720a0a91592af264b446105bc5b41344067bb3e5943d62aaca4374f92933e3d4353f1898868d097e504cbb934cf727a9861169582bc4414e46c50c41693909cec50beeda69aadd6073fc1ca3e1a6a822751a404730c3c90a4ba6a9f4343988280eca4c4600b413cfacb8ce2823f2a2b96f56d9d1effc2d3292c0720e7bfe6aabcd8284abd8c3fe8aaee1bfca30de00ed421da54add2aabcbc9c167ae2c0e8331df9e9acebb960e9169d90c036c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"""), xeh(""" -79E255908B83DAD198AA6EA7219D5C170DA8548B172A2C28D53EB890914E16A6CE4405E8867112D35228DAC037743E25D26D720742C95935218ABBD93B4EB1C145794697EE761EA567BD561C6F5C076A48A34485539C49D23784606432B4913640644CDEE799961E5332E9502E683FEE98C9E1D071D8976E7F652EEE92E736D598F3B4D7217C0ED30FFA7DE590BBADCC0574A7280E502694A13A4E1D5D8837633A2EABDC97F36722D772A380595859134B9ACE346360860F8E60EACAB4AA3F9CF1DA73B5813F773008E0153B1BA0A5940DBC5C9E71E9A46BB4EA04AA9757E8E1AD0209C86334D05FCB611F3A00C7D983C7B9C160B7807CED18E5BC64A52462F4F9438199C2E4C6E9E70EDE2614913BE6D0C28894319B7B646444B5C86FCE61297EC11B21D216AC79159801ED3181667B15A7F30873BFD5727802E7B6588BDD04A5F7CFCD47043E600B4B3A0227E924E2CB92E514547BE4C1236C7AB2139F986AB956C704485DE570841F5857108D2AA57C535B3D44D0535208D501A9B56FFCBE8FDE32B375B90A5578EE44940E1E1888C21A4045D0338149D4C80CEF47BA25558E1842116E1E25499714163C0EE9A95A87A27CA2A61C4BD8D28BB04DE34EFB6E44FA7026B158883019B89AC4A5B5CA8F347A3FE892EE3949BD40D0614B9923052ED174FFBA720F516B6FD1317754A95520C66E3907B32A1648B344C34B3FA2ACEA2C8410DEEB40483529AC7D83351D888E968E457644CD76B8CAA55FC25BA1359F4A50119B1E69242DCE30E93983E50285DC0592537C6202F2E3C9878067A1777EA6A4E5ACC31614AE52787454FEEF503B82492828A736BF22E3278CF2ECAC1D0E11EC67815046CB4A66A8F48D04D4FB3C91CE7C251B37A8F3FB62A37489FFE63BDE22BAA18D4AA5BCCC0D8C709786B6C94D268382B649598A7A6785582CB2C02A2E9BECE29AC919785CCD026ADB6C9D8E85C3332DA956DC20B8470F8DD78B47E19B49BA5B27326D4937E93CC3453BB67EAFE42CAB03A70960DF236C04C344CA7177FD1E72E7E0A2C10D14F0C054337BD14152D4AFE9BB6243260E696EEE1327""") +7ac45cc6b87f431f05a28b0b6f8ec44fa020f8a0f798e4463e084e58c950d643a72fbdcb2a8e442aa2a9efa2345111838129097d942773073581f8828baaafee93d3bee80ed21e13fab0585b329de6348acebdf25e09f13c1edf96789a3e6c7b7e1143e0a5f408e33699c68ba140410e738e9501e4a087390970a86e212e3ccc18c62b4233ab94f3cb7faa3a5a8839d68514d851555704ae8a601d7e1df4f3e31390905945fdd88f0eb8a39afade14b0ebbaa16077acb4e3ffa41931bb057e386297d90045add3ff509df9650d86d2709d89a5fef748b15e5fdb8aa5c2dedd84533b5ba49bbe88ad78224379fefa0b68bedd76379b5b7a06235673f83871201316d9f8f050645f6d8031fd951ffb2fbbe4a66f0010abc8752ec509ea62cbf2a59c3a927918b06ae3524b6d94765f5ad6856f5ddb2cfc036f2520368a4e15cac62089adecca6b83e8b9896b48bb4aa4f33656c7a2ac3c02539c0525ae71481aa87be9b956ef8b6558f0bd2aa62d3be2489a4c477c605220ae63ce5b67b3d517eb53085a747c0566449c06c9a54993a2ab089ceb3183d5e69173b635d52b87d6c1e0dfd4c3f8a15e0cf2d2cccfb2d12429c6c174aed9d59ded4bed6ffb964e8d97d4d10ce0f2cb9124a4f88fb864bcfb6ac358824bf0e7408e19829fe038b481a4b161ef06b584eb720884865abea18a05a00d45b27ac0175ee1667f6feae675d8a4b85c2a181a52cbafd73d5e70becd0ad0b27b08b14ec2185e902bbadbd3c7a6c1d49a3a8e65568e590b44d12d6dff7abebd9158ce588d73a387f8dca572b51c24649e2ff02bdfaa779759b93a70f8d0e302a25b528e26a038298437619e4978f1af582d19a11ea772fd0e705dbcc92129e4e9f88857b0cde3da2055427dd8565b20e1531f701361b731bb2dc093f259a01941e255a1191718098e5477e27f7a3188339a1237e742d71882376b72f55bcc4ecbf03f1b29e79a1f0b969619755fa449f1727635d9eb71b977f4acbd58e5c72e89433689d5a2c759f7feb2051eecb6e4e2d3f37e36d863b4aa86d78df37b4dfcb453cae1c7869a0e67f6af60d90f""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +06f89c5592b91a8c7141b644db94cca7c52b0f36a1bbf6b0025b0b0e994b277b77ceec519e24387b7ac33004b38afaa2d34c6f87f9287ce8bd373a322d55c5f9e79c8f72bc17971c5dc77c2d26aa1cac4de8f7c2a613454105067359cc414a689184af5d5409d1e6bc4bea7dc2a20b11f272887c8491a0c0025163bb1a048d402d2542cb10b261e2f9c446304a98336a422ccad181cb53847275899d3a0c74a167c39245623620242d87a529119727933ec9d1b717c14980fc56dcdb963a48ad13239d7048773cf5269d3a5797016bcefc0466b6b7575024aae92e0c751ba0315505944dad99b54ac516966808197a714c7379e60c7dbedc9b7fb89fcdd96808d2c63ac13130824f5034c8843420abe07c837b4f853615ddb4900cb6abf3368765d0544c67b36570598746cdc8017b2d0a778213b7a15b492f4c9f462aa9ea3a99c9bbcc9f2052c4754cd347adc22b446690908d791b9912123b67cda366bb9ab058aa5285e17018ae498f1c7a1db6846ff7b30d3ef43aaf0c6bf2ccc574e44f29f8855b787ac63ca4e1a05a6b4a972608687b18696ea18ef69a660ff335ab54646f70350e5c236bc29835046f23ca2b46206f227b4d2f1c56e9394ffd70622e22c1180bc2093092307a34b9b4c71f514b8c890205fc001ab4bfdc131f58b751ee4011a55859b000088c6740e9f2cf1639840d0b4b3ef9cb7a133d5358923124cfb7c2131352b7e1fc590e711c575484304b0975415298c7ce558662ec621f9d1548b18188737b96e308c267acca09317453b863393aba3d96c9a99485ece5ce4dbb86675c21bd5a1356ca11e5b7050bd9bdf22418e24c966c04936a39a949f00f322b051dd40fad238a773b23f2f84a63675584a04b88676e0f864fa674658a1c2d5d7990411b7b8fc21c2e08c2d3da45bf55060a3b546ceb8e58f1326c50b861b7aad69607f4580236fc4a51e03b3479c8a25cc294aaacc5b376a3916ec41739ed11bedcbc445419331be39731d6c136d40a65000cbb046e48409f194706c09c6244401877501378751352abb7d8d52fb5fb47a76788cd99a0cf217f029c77ae76c67fc7215e493c8645af1c58bec08b66f66a92346b92f873cbd646aa5dc2b9b6e4c2848a4324a8318e9983932055c4f58f42346df1da07977101434a9378d1a1559819756646eef3094b5ba55e33b596b71c04d249be4b8318a4becb008ed71000ae795ed1ac873e244beb7c4071047e83a8b3c6c2be2ab025726063175c4bab391597923d030b5a9238b131383d15dc2a4bb812a8539f9b0b0876a23ae049777e6229c1068a37ab13a2406c6f7ba4591520d8816ca3894bf3c601fdf493e70c5f4b19bead520d25cb6e8439a548f35cafe81497b297341005fffa18b99754cf199ec90504f9f16f8e415cba718318437aeac50ba8413e540b963cca2202a35e356701e177ab0dbacfe6a0c02b506fdd6436982737f903b8a8204cbb07c380340c5f1a84685392a2b62620004caea2c416e61f7c7b0e6e202d92021628cb4c10d57d5b60ba4d771712d552d1f9c6f352779f8c32fed54a8eec59f4b3177c7c3e81e3ab7dc83a396bbe38ac0fa3ccb174442ce638c6a0fc1fc9c426b5eab83d0397b559a97256b2b0817ee115b1e026c445629bf7a8803ff71aad99385a1abfdb22a3be0029503cb44b7a35847bc675f17437d9246cd104bd8608da3005e14a632d69006ed4434c80594b2909fe284203571eac04a00a120c24d050f40952fd53ac0cb39bca50c28ff450a6e208fb26bcacc1ccfa89bd7e05616a395aafd2bfa59cb541975cbe429919b32cae4b1f4a4b4b97858390c164fde76bcdb32b54b3325392c385d647b265578a1c56dfe5a252144ff1c02dc2054bb53525ce4b3bc2ec190e3ba06fbba12f06707f060bb1659607971f3726b9f59191e6e7b252602f51eb281f454f1d80a60ea29eab42752df9a3ce376467f694fcd288c9fc7851c04821b53e693208867604def746f787ada2097740ec8462ac89baf84c0d50bedb539ccab33894408c5b4b91def7955923a283677867a356b78c5a8eec308bfc982c8bbdc9e40d7695b42612ac27f6c118b5379518b49e338738e830fb6a66488b7115d24895963934688d91fa9608d41582e79e5d417ab07c81d39415fdbb870a3f503f1a197bbda81d7c3204a316392fb75016f88565a73a51537728ac70111a4771134601afa8449cb475bbf9789541ad3f7b5f85a4f54aa3dfe0bfe01174ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"""), xeh(""" -D980E3002A28401678E1641E9E7A34D12CB2B4C9D986C7DB0FAB941AA83E43F42C44368138ED65B7A917B22ABA2DB0FBE44E5E9E7A3DAC3301379F7152585C8C7195031774CBEC61D8E1E093D694970B5377DC94CEDC53B6D3802BAF1C6F9152E05DCF66C1643528155C78118DFB00646B90726C75131DC934DCBB706ADBEC64E07F0D113BF71D4205D8E47DE67B9E01B224B82CA24405AE5591BBB1307D44E405E3866B1BB51ECE5985EE95D54568A81E7F285596DCAEBDC807EE6C8322EF2100EB38D10327DF92BC10A74A2D44842AA02AE9101A24736949D116CEC81F30C3092AAD941FC7F4BA10670CC0894A2F81E3155B9081004B4ADFB6532A1458F727F418D3F8F228E7425ACB7A4E4A3653529D1B9F72E57B8AB5852E35D0093B548FCC354A590C256B50BCADC30B55B5E05A3231611C93D5E34775741374F3E703B6E6362B35A68E33D859918D93EC03633220C61E1B81ED7AB1A5E46D4E640A9DE4E5A19FD11F0C24C556FE8D91F2358E7E78033A3C9FBF68C99DBA351F8F866CFF14E990C29E4A47579376606EB85A9D07D0BFD835C7670A5F4F2D4EA62B2BB13528A27BA3420095B852E3B73AB38E3CD068E276D8BD7A0B85BEFA48FEB72EBFC5240408B069FBC28F48B3A8E6556D7C601ADF98F0E9D64108F0BFE3C3B56C800D76E6DB14736809CEC22FA811EE92EA7950421B22F613E1349D259CF877075D476798C66FF58DBED013675BF6C5D3704528FBBE91486D7E956F785F73EDB6EB42861694F5C27E318C7B481377770125D99F236875D5B26CC8ED9859393BA2D8531E25FD6E2B3560BBC13176EBA638C72626C32D0250AB7F7EFFE661B18A641F75AE279C39771C7F23EAD50CD3AE461BB0EAACDDAD4F9C6436EDA5F2348F0ED4CD9514310AAE609B539368F53EA787ACD630080B832221B1CEF67FEB63CD2DDBA25282B020A3CB418130AD96D66EBAC09F09CB35BE0539B44924CEE15C6DBEAEE04C5BE5B9C43535FCA64B32BB204497AF175513375971B15F107F88980F0C0EB15D34762C98198A94EDCA385F32FD82CE7F6FB36F12B742C1755417A8D3F7D8A9""") +574c9a1db78f7ae6ccfcc6ef48b8246db140f1a0d94a5bfccbe8b807e08889de2b45666e78b96eb159a73916947c2ae930c389b6c858d52144ca1f5c6d66a43f6ddff5c233493592e89f196220ad4360503ace196ef8057800c2d05b5b12e98203986a45c0dccb4ce1bf84b76e3f6a84f6e8356956f0b05c02ef2552e135d90c61264c63033848651c71464108be23aa0004fa1ffac1f4e1022dc915abb7a9f66b8770386e4330d7a94722fe54411fe0388599e6ca1463c9ff6401d9b37d42a3039232b62a7f8dd7ea125a4e54feedea008d51eeda575b4ee42031c908ec52a4bdf61f1ebb051c65cb9f9c4780958f2fbc0fefd38574e7b09f48412a7990246cb64dd8da41d68f0c16468dae921d548240d14b3023c830cbdd130aa7aaa87861f58f2530f9052e84ade036b717b365c8cd897b20166859c95bd90a28ec0316a0784a9d30da3fc1a80e012ecef3d1b12f91766fde1bb4a99f4cb00a94fed0f345870881e777a6852700068f5d321be5311ac813cfb3f5acecc6ed2e0225e016856ca379bb61806e3dd5c264c31190a7f903f0691b92a55ecc40a0a683c09636842df5337b6bb1b2616ddafdf9e526b757bc33831172722d95cffb2162941ddc584e70055b1fe21eadd8ddcd04c2d574ded14fe924c0990ba81c2eb6e146e483d87655f139fc651a1070420de9d3d82e9af7591a981d1bbf650682332f3bec1ee2c291696af40d54289598327ce64c32c2c77a81a6b4818839e8a6145a9eda06570ce5a348a72e8c332015387298eed54daaef0d4950f1c94646e1bc80547209d23d51d50fc86f4fb4e32351ea2b7a6451a8caf36e211df0a7427a46d9ce462335545f133fc6864286ae2349ab61d1a993da4f81ef523b3f1ffc6141742aebf63ad97cd6b78df8d8f73b69a4d6efcfbba2c44da1f1bda3cb41e725221edcb4a7754b9d79fd8ea8bd2a11c73d39c9d10a3abd5af6c145964601a0478d9c18573907fa2d88ec51b56ffca7b51a7a604706fc035dfc12366430234a46863c2fc03f3fb599b7c99b58231c28bc571bc629192fd3f15092bbf5718e2644a76bef5af0a3""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +1e4375ab948b3505593ceb86f6d4938284c069ca2673f272b7b78479dbb923128983d882cac84076ccb047820dd6da22419aae702c6be0274273e1a5ae7badc7456dc8f0a34d8cce6608a4e5605c9bf2b5bc232afa9b32c9225ddfb87c24343104d3b14d3b86f8b72fa336344cf32315f296cb88c3e8a5352882acec72bb68470ad9170689c938f7a9110ec0bb5cc1550e1b5e26f44a99c73d3a5c3fd48b308ef854e70956b2402f1b5990070bb2f365cd057bac1f4599e85c82363ab851fa6f89e0ab188b28be11ce7e52060ad21961c26f037662319950e0f2c56793984a45560c427160315769e71f9e6b3535806bccb497aff0944d004a3f41c16285b803ecaba95789129242e5961ec48cad3a61753b631642065a378155b279874ff038db51a37f1445cd496f7bd220e5796c4bec29dbb9b982d04dc08ccb55283e041350688c9d2ac639498bc5eef46e7ee721f46932ed4c790ac18c0d11cfad286a2b647c37901b841984f7a11c0412ab8fd79ae47375476079d27728b5a01d537a1a37640a95166feba3b16ca16883a4096d511eaf1590e70c6ded992907e6bae99acaf8a55154646056815c8cebaf0fc3c789ab485ac0b8737258692b2fa8db2f69aa1577045769c92d8332906bba0e44cc79de2c69549a4605548e07104ad458c90c29a826e04e2f1442cb170cbbf4ae1bfc50a7a673d633420c56596b7b9cd966480143287b985abac15de74a5db1502da05088613712829500adc46425b54c080bb2a0bb1c9fa53f145a6ae655776df15ee60b38e014abd73579f51718b548cd418a7e7f29ce1c57912d77433aa34b00db00f3f20a00714e0da2a489b091b2e52daeb58dbeb759428c3a85219fe13995d9c0baaa468c5df3bb51c282d3e13166917487a81dcd837bbb7acc75d2c35690ad3aa412c8610a36da87c9d8669f56c68475096f853569914961e795a3795328e33f3e15c1ec940b4c5b4b5756c772d1228fe54f6e05485548675a6461f8a26ba7599f708526d57a0a67c0a20e25ab02dc03100687b8e375358b9d5c149a132a98fd29c2add61da49601d8b70749d18159851028c33af8acbc9ff37ab19a9fbe45a0f08b9cdc2268d6e727665429f16448ed840d0a87c34c3422ed857c69f3168820b0ae998702ac6f55150ae3031a54fb80912ba94fb4bb31604492f406f654855b447b39d26bc81b0d1644c1ce2a7f347c239cecb0cf89ab14917192c12e7a694581021e96fb6868282df0a4850bf3acfde5424781c571e8857cec1f3735a464ec74d859b169142e2e7413d2a02c5e93570e3b9bd18983809129724743a1979794a2500e04a409506ecf0a975f58bb0d08b36c1733927c932e7c73afc47f81b5a87f25878d327d0c375c38d2940aaa543f46b1198345fce7b7bdecad6ad22e12155bc470448f98bac8ebb96bb34b552ab3bfe5255c6783a76425b386613a112ec1dbadbf105ae0ec3cad61c7032bbe0bcca9d3eabf03ac6f0d4c5e500348f6581876e80c531197e62071a9454947b450614761ec95bb7072ab53e81d89e47eb875263ae74ca6a28b2a2a1fd44947756c1f3eb38519c9b2d6d63197e6459bd1427f992680b1a6f1480cdb998006a25cf434346d04942732c5617245033b430b4ca726b94faee24ca54919f0842233e1c6268b4bca31be4ca7be9b52851e2ac0dee573f7959eb896b0bb18064cbb9b71585a319c74b7716de398a8111214ae3130bac5b196e6734d3cca4116bbf67ca42492be22f56b538a8532c6acf4404069a329735246e5eccc2730c2f5690c53510bb2685909015874a8125178c7fc00709b2a6720391e38a0193aa96715f13ed628068ff4bba6e74c7be095a897ba3dc50f88b2b08a353cb4c4bf382a5cd72227cb671ed74227ce245268c38874f53299604c41f15978c522e865333dd0c49cea97289813a828ca76b93dfd3987da9726f0d3492cf13ea72ab8d4e82e73a3987b336f0cd2157de0b9b4209869412b9074736867b10fa82b34e5424c5998295b6a54793e9ab119e9c68049ea2dbef55e27327080c6ae71d69374b8314ce6110369b76fa363dfc201729a700528944f2bc23c464eacf51519f0aed8160d5ceb66d10c865604b3b4ab05f1c2990bf2b5ed84898b6a891ba360af171b051b907d1245770038e379cb727784b219a3c5ce49fe6273600219bcc609c8ffcdf4acbadcb9e5b333bc301e771315f8f9b17882a6ee955159ba457f9f019c41bdfd90776edd78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"""), xeh(""" -E1E906D018CCDE68680DF762DE4612106E918C29FF5D576D8FEF01D5241B666C26CB7B2F80793146AEEB9308511D9BA264A9A05D6621425730A50479B889F8C6E5AF66CFC9A3123D3B7335C06C8CD2F867484240E8B6C19EFBD3C15C33CFD10EA482D1897A516D07E39C3C1AA866C10655736F18689ECE7359D91E6EF5CEE957930258CD890C09EE1714150347A18DC97AD955B60750624755135AC81AFF8352B701EC5FF50AD925ADA003A617AE64DBFD305038E1E40108C6F12CCDD7738A83C9F7A76164F670ED4756097426700E51BA02EE36BF12FF22A316790F2C2FE7216C12F03023D87E2ADB99683229E77D6B1938EACF10D8686CEE46127CD7652A33FC05414FE370A159C516D250F7D345BAE5E1C9628A65FA9F5ED9E39FA10A316620A2D760C5DC128A5C6137F193226D18B5E013E300A41B1F2D1B47D90E3DF8B4FD71A794FAE0404570261477B32DC80CEA32F2DE743ACF7EBDD41EDBB0119EAF7F872A50A5F4C92A8B85DF792DBAC764C3A9A5A5C12D9E3913356C7F5463BEE9BD2A739FD485493B1C0DEEF716E129ED1E085F146E0D70A7E58D924F576F948BEBEF7842ED831FFD58B4656F91686B4D0F832DD3A4E6FA9F11A4870E9602E0DF0EF4FE9312EC4C7EC216D3EEDCA2076D0F0B5C9FE139145222347E816EBDC1AA70CBEB5D65954427A3DF6A78BEA86C410462596950AB8798F9BACE51A46A544C1BD17A86C2995E3BC82A7F965401A599103B0896E1B9EBA540614CE8F218DC7290103A6044E87069286E5BB18CBD89EF562B6AE1C7353F64D8CED183FA8D05D6B6A6633751EF342D839562733CDC1977684317EBC71378EC02B298671F76EEDCC3041E943A76ED9E0C496B798E10B59BAE17A195544C05CD1FA6A161358EA1D4DC7DF454220D79B235C24720021174C1BF47859CA30BCB57FC19CAD92ABF24C051D48B3D9D46779F910D26AAB4543DB2A0044BEDD491E1D72D8FDF361B50F1FD10AF4668D78F56FDC7E96CA16DCCD9BE8C1819DECAEBBECE41C09093DD508191562D6510307FA4685144D9679E84F58929D79E693DA041B12B76F629912B1E49""") +2c3f3d5b5ab52392b227104e8b9c85303e6d579df35c1e7849ebb92e80ecf200ca9d9b9c408d9f68b4f4e5b0875047edb2facbd6a100c1e5a1465df22a88dc1055a663cb2084409d33ffab500c4e20ba796115a2a3f23228542ae90ede48e05dde69197b9d8138b6359d1aaf85443cea446a4a6b0fe769d2ac9de4a6eb1a4f0d307c6277a3fb1e4022667233b90885ad45eea2f6dbaa54d737886bb504c61b53fb24772c6c7efa12a7b13ade4d6c29e410a604fc5ad87f378e703ce9f709f9a7485aa18bf7e0b4d7d1b88968e06f085ae69d49fdd22c40533b07dbd7642444dcaf8e31c5c7c15f6261799663c5b00099261b747635a091c6759e2c1562a10adfaf75d120c33ade725b7cd6fc0edb63862831dbe6e73e356b729cd001289028596900b714f72d47da69306e3e5e823198ca4b45f56e1f60aeefb0827c44e4c16acdc892319b6ff3dfe138305df6bf7c518aa48241a1927171fcd1576f3279cc727fd8c6296b919296dd165ccba9544a8aa01a54df914c7e910d2930e27f7af36ab21929799b4ed216b971a801c11bc1381c205c55a76b9efbca88ee3ed2eca5f3771cce86617b5fbc411afd6d5d2c6e2a73675dbfb26cc7dd2cdf8a1f50ff8644dd1b173e090c8a70184bd14836254b29a489375d1b1a896c3a991a0cbaf86c93c581d0bb922acdac1bda28d3520bda5e4ae8815a72f1afcfd1168c4a4f8c526b12f9cf201e3b146779b2a2ecd35c56bceff5c0986402ac5783e1bee5b044cf6fbd94cdd7dce828b2421addb9bc80cc4aa298b2a95498c165ce241dd64aac62b1f17798d439c46ba24ec1290434e45b2560e8ddb938244c6557b52ce5f2d73d2d6ba3ae46bbd4afdcdf948c27d05b4476cd4fdb879d495c8405abd5ad4691f3853fd95253a22c4e012fea078e3e967ce666a5ebd6492a9fa2019be09923437d59b4ec38dfa71664020ec591a53ab5a2d6d77b3d44da2ba20a098a445182f62171b482cd5583ee290226bb7aa3eba414fc14dd7f0bb56e7b647269d92258a4e272b68cd42eac155f000f936ee48cb625b122c7237bbadfa4359abd3e82ae9899c5""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +96527bfd017c70facf0511955eb04e1c8b6ba35116b6c7242af57a8efb7045577eb101087062518f9421cf2b3f09b681ec2b8793b973c338ac4d39505e296d027cb413981ead738e27202782095589945028b5540dfb3cf120a22cf347c3e225391750c9f93b9799a0367418017164472a762c63a8c209b44260cf9997cd5b33be79fa2dddf177de723644f094f10a95920c2b27ec31e78b0521faad545c2964513fe8839014e9862dcc18c1cb088096b82980a1dc586c44b7610a6a90b10861a081acab7381955410f74970cac1afb52403a0ba7f81177ec65b3e045816361050b4226950a7b1bc474093d9c1df124773c82300778f52e8746a54808826399bb1cb7d7026340283f34baa768b785f62b449b9681193419af289c1eb845f16af7bf709ab3c7d00507f62457d74fa048942556d3877e54332be622274ca89c298b64a46c4594030a031c795523928f11f708ccfcc2b75db1814e087842596a575b35079184b8dd61543a94e93762b5116855a423201b66fedf028e25cc9a3d2733eda6b364c30d3c358fbfc4e563a52be95592c7a1169267fde07436c31250aa22285d229b04a1cef106c15b79681a955dda7028b3c205c188a32081b780500d1cb41df8601b7fc976dd67f9810c9d7b809ec3a725739609cd573c3038095235560e9989a06aa910486da5a24ff041071675f0ac327c6b4154f892f13230b05d37ff7f1867c7908f20a461839864a677d818a81d0b7c871b64de4082ab3d472503bb21535a34145bd2fc664208328745b9a06959340f939b39b2c02239db20204964b9329c3330104bf81aa127f75cbbd1822d96c99aa75a8562aab2a2ca9b5fac442988465232ce1cab05fb9c6abdb4337201a16374b75069bc893913ee28dab8b2e56d309ac2c0d244122ff755ed68474e3c254ffb03dac4c9e73392444daa7f8e7658780a49b44b134750eec8b4780c308587287c8c8c726041e2e70cf6488735a6ca6d300956fa1c027c3679e0ca96a457a1beb8e60f139eb0869f61872fa2c130117c321aa073935131a8c9be7c800e6270e71822492c992bcd26df43478861927e1d996dacb9c04c630b694150f23aa51f26bed8c744c36a7916864b5160e94cc515ae0a03ffb445245c56a434f9351ab64f6bcbb973718ebb612657d64f844df3b85bd484c473a685a0a4a94e9995d865aa5bcafb7dcbc7e9877d63890a86252c691044df94ef7a19c68056ed6315400f8bd38f48abcd09e82f0376816c0aae53a9cc61b466466b63938dbb0b1dd963adae40802216701d094c716211718943b543cbe0888b1dc463c20804c4c402105130dd7a87a48c3c3328f76a8aef2b0c7d22688e7636b88d62897809eadf1ccf2dcb5a0011998099506925dd3b74869f931394bcae43466a49a40b31075f074bda69c0ee2f7bafbf81712969b43f0beacc246b3e71c9df2c47db405e235ae97e1a99c0365076b29e593b39c485521716967751025bba279f3aab85c6bae3800f255396d136459545f192b650d3b142c383669d2547cc2732015bc4645554638284642b918b5bd65a06fb49c5fd267a90b77ac35d12da3512f44d2556e027e6582529cea194df88584190480d9b0b5335fdfa8685894514cf95386cc1cb63131dcd1022f5b568cc621a729423c0567a51313f647918368012a83816a2caf88e062a9a6064fb52d8b31abc270a01d974459b4134be74c41b6a22e72ba1c993924bc43be6509235298431c72943bbceed41a84f9b84ce21abcea516f32280a0586069acee7627b54055515604a9ba112e620783aa76264ab8136759af9dcc75718a9bac22092a645b1b5cf32a92e377ba03a6117ee842172505793f973f84cbf0fa22d3ce116ef4c1012bc69db94c7b2b461d978c27c93044f22972588af42e28dc3748299e7a098b5566d67110a036ca9c6740dac84205109f05104f80585970a7906d7bf93067472a34442780f0fd25729745c7f85198a753836c3381f0592f818916b48278e14b61f1616c32ccb987940550316462257f1daba0574223ed6767b9c696b1c01ed75484c1738cf60afaaf9b3144899c4dc00fdab36fbd792dbd4885ab3af6ed63f8394b66d0a910041b1d606923858432f81c37f57c146db8dba6775ba1899d5904f3a69abee80050d6232d858d95a7bd86ee6af48bf9c372170c7468fc024cfdd552fb21ae23b08c1e38d8ce7232e254e153d4b2c4fa1fbf93c919bdfa47bface7a3a8708917b45917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"""), xeh(""" -3EAE23CC5F424EDC10108FCAE8EA3AC2BE8E90EB6AFC438B5A7DCD8E149AEBA25F0D5B25052C030F8157CC5BFB876A62F6A85B6C1C954F7C0F99EF4E3AE4B48C1CA9AF035543ECA1069B067057FEFB1E50FE0374F4162F0628F1D383A8B111EA9DE854EF33FB79488AA81E75712E5B9B6485290F0956B0574A6A9E1B4D677A832A85717CF7FF5A9E23B205C4FBD4ED7C2F7C5D91F46CD6A1EDB692750A4C1B11DB15C5643C7572FF9B765713C5C97C05BC2B861997CC6CC2C4D82CC62A32EA361630454756138C015D5501E362BC4E2B03A7AD679293658E45CF155B1C4F165954D594871CBF556CFAD2C3E6EB238DA3FF3A8140C5FCB74A278ED495DD14849D4C874C3E1F6E56EE657238F4E927FAE4588F1628DECE45C625AE0A6137868B9E86CFE29CCB4483CCA6FEE905F084B2B03A84DA421417CA5087B19654C803CF072B3C9E37A70B24E30E2F52B1DFCB6817ED05D38BB6FC7558B9B96AFA0CDBE708025D8D0454B90767753524CEEF8372150480BD104F1B7E659AD28EB155842CA81A55E81B707DAAF2F42A0B1CCE0B3BFF23F5ACF984ED20B0970ECF973DD0D5E33D34FBFD1672BFFF6725B5F1F869945FC67C5D01F3ED1CD8CD43A2008181AF7F65B0922D4BC634670AAD8A23A698AC3675EB3452DCE23D7E1A130964CCF4E26A9CD3D424A54ED7861E2D807F9C98E434A78695EFAC8BC86C69CD5911A2F52B5DAF50866151C5D00FAFCAB6219A9BA675413B4BB28619CFFACA38B9ABD1C3647BCE412336C02044EAA752B79248EBA1A7AED403801DAE5377CD55F517432B677A75DE4D4B504EBBF6453E319BB6EDACE30EE44810332CC84CBFFEE2B20548EEEEE1CA131AD87CCC284B3677E7F632D69F776060005439DE5648E466AF68C6616C63144451126D10311798A9B311064301BFAC1E4641830B1FAF4963F14A740529C360A73A351B6D330364BCCD2B012CD2B571ED243BF63F2FC1F1963604923B397A57680290D413FE7413B2C6C01D5BD6A0E314A644ECB10C69418251F48D3C3941211CEDB083F6FCDE24C5F5832034780B539D3FB1493C631F0C10F2F50262FA""") +ab66f3111bf51917775e0b0ddb50f0b1440256896320369968c564019c6f5236f4b951cd4370965a16f62bb2046f67584e4b3c2a6e048071d4c69835076b2bdb5f1c5323ddb937a371a418b0dd84c21ba037c2d94470a279b92e0ac53dac8de04f84ef1632fde456999bd2b596242dfca9484fde789794808c8cc5e6cb80ba87a850ecbee0262440402cd7f4ff1c6ba24879305b4f3542a7bb45c767c78af8d167a5233e42f0ac11d1c3a09aefca29eb25b3870fda30d97c53f988ed4820a7b979d3bb5aa4a3e09a962f98c58e3a2b231e6932fbf68398ee649642268950e7c3538268f02553caa443e6e3e29a32b2123603ea7e194122f0ecdf02f206c95a90c3605978b871ae70710887f46ecdcbe326368d909a062875f3beb750b366884802a0f6dae1ada16e55507ac15431c36ab1e01d54c453936d6857b78ce0384d970439aaa4e422441b1f8706eef30b6e8de22fbeaecd3204f8e9f40f1a6ea0825da1e0c967e3dcedb62ddd1befb3eb1c98d7decbafdf326268b79714b57dd7cd0f753c7619bc0f6ebbc8c4be474a6fbaf3d739c952b7f2ef8522583cea9f0a2690349422aa8b09f55cff3579546b2f3371c8592b459e3c0eabf4f871ada231c2933a6b19dd6c1267498d185f2d6971c1a73b4d61ba9eeb4797fbdaa11b87798e3caa78ad03e5edec0ce389c551855ae967849ada410e996b8cbdfba75cf9eb311220ee294585700d1cd15305a5c9a5925fcc6e46d8b94225fa01b69d70f0666466f69d58b0d3f1466d0972ef697ca0b8a40e19bb14aa83a7348338962882e05a79ae341b622ade01b19239e85ad3ea04d6d5d7d9e0d2db8ddd892b7ee6cb832b8b0911d85ea297e169f8d9623e12b9ec50d6e20a5f5f2a5607159f0ee44563851bd229d05276d87ec69aae43b8246e26d1c634fa5595e68a2c0d8c6f480f8642bb62ff80cdb0337f8f4aed0d12f773dfda04871ca37988b86f2b35c0babf83e45797e5b9edd97112bf079c470dfcd10ad989fb871cc66c696bbab7cd1c76dedb2c136192b6730d07a036fd1e3d176d69313bd3ae595f8b1ad63fb9439f0a53ab41""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +1ba960ba9a80a502090c1ab5d4f72369bb48ede1259a76c54cbb87579b0b623075ae8a1860bab4e39c460927af3e44007671c017778d160aa5f88cc292141eac1c6d417ba6defc66fe160fd64b5734c86fb5e54ae04363bd34982450279e24b4dcb2b6fd8260d385b810493f2506312c52c9486648079609ff972725392c7a0205a850a201e220f40219b3557993c2acc969708960a45e8c7f915562e6c7a42a2495dc499f1acc3c46d20b0b152de840b523c42b1251770956349fe35c8b78768798929df771469a476e997eb44380f19413d3a0a5d0c8c25ca540d6e092ff575e26543863728179b95533b36145a5324313433f7c66f78c66e664176b564babc846f454be93d9341a004bc05c2d067463a529a486fb447309298e26ca2c9105eb306c001cc3a28074af47675c40aa4cc371ba330fdc97bb03c95aab5247eee30cc8cb634d1274a4a2b4ebd6065ad3047701c930f3145b65a392d0956010c23d0c19c4968e22125b71d06087dac0af92af7fec35d008a073e99ffc9cbfcfaa7e25ebbaf0335072c083ebd81664085038121d7fb022aa1c9478254af14170b0d2009aeaa7f081b01e610d970b70e40851ce8743d020c731717bb8984884db8cfd52a79f0bbcc336bb43f27f8e5108d1f4887453126c628300f4ba10fb45b7d511909a035d65a2f6961e065a8492895699c539d7a78d4ba1912fa9c30bc43534b3c7be252f4aa27e78021e97a423e9ac6d9b57ae5262af73022eeddc4918b18a25c77032762c184c861d924c519a01bfa3618ea01d9b370c13934f2f6199487c58b5459cfe80c60daac2a364cd51d766cc90afb5796524a8320205b83bc9a6695b51e5f1ce8089beb6c403dbe50ffc557e49020d5e6586524976638b8d4ec1816e34bc373515a1bc98a21a51dab17df2971d64e63aff742a243c890ea06363bbc4994ba1b45c233e187ae78b0d44677254740e221998c6e3370446bcc21684593026b8bb2d32556137323e9ce258668c7d18c44330c59d567265ad60c317bc2d083a3a599cac8cbc87d0192907209b851638a50a32e7d76d29da291f861cc7b979ae13099bb82ebe29ad44859860634d62f78fd6b26295d040f8a5c7ff7aa393d127e214aac9107ccc06d029da6a6b998736710c5fc3a6c9ecbdf00069a9eb2942b45b1626b7953886248caa59789f9e988fa26073bff9b703232859463a9335374506ac57a8c2936701fcfc0235d071bf9807e907734e6267d130c9d4b2406e999b6cd15adf7783db2309598c058a93ac043319194ba89857a59eb35fe4a3cd6fa1c9d7d46ba2f6c62ba85ca46cc8d450bfb0170f5ad6a2a0388ebe73a8b58627f6cc5e7477635ce32472a87b4b881ca9fc749ecba012187a5bdc6e9e12b668f32786cbb5fa4055f86590e00bc4340c04b8b0053b189a74d6bb22db2f75f6b32918c0c3ac7da62044db4a9c1c2b0b1ee81b5317b1fd734c33fa3733d7b37bfa36c16578cdb63cc6f73d661a35e6460b74396ec6a07111091071a757d962384940a1a2338a42fa68e81587fca304d8a86282230470c8988cd707437163cd46cb489b010d235fcb976e50b51e0a22c5662800e74903b403c025bc6df9d821752107b2e51874147645687fedb108c1894e0ac3801bc1398c4a187bea7d9949bc5cfb8368b296b2fbcf2b59c71321b5aa2055e5823f86113a1519c956d9c1793a5d52a906a5031e905a862fec5abfa0965fc49a2db189eb6bc69cb8882b703e0ab35e088340fc35812bc0a184956fdb448170a6b32b49ac0e2a65a1041d38d4512dea3fa111c7e428cdf52144ae0708c5c44382a0733de356ab556e0aa141d58cb1321058be25a543d7060252c9e87997c35295596c02bc7b926f5ba05675a5dfea5a3eb62b2521854f21498c428a23048fa38484935399bf07c64fb63f7ee793a63aceb6842bf05077d2b3647714332d259576182f0d9c508cf2321f0090a6c1cb0a5c106647101277a7b1248e74189df6b90c26a612b26555d433bac49a3ebd702e6d9649038233d6da01f77534a8d2038f615a502cca8526c314c5856a033ec97155ad79a2e2a32cc1e734cedbc6c0b94219d13bf985588400cc682294bf21183830b2bb51b87fd9073b9cb6237884df0cbb12b929f81448e5578928b07193ea4141d19b4eed07a956c34b6de59127c5e823bb8f6719ddeaf282650cfda0e26e57a7165b1afbf3fa9fdcfd677e3b27a966fc034fb10c5f08a5c2cfe2fd02d9289fdf022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"""), xeh(""" -B3B6B84D9A33C59758CBEEF8EA26540D4E3D4A45BDC623CA1D0AC05D8E780D2DA1FAB26A0E250527FB0B9BD56B2A0686BD0FD310164A17244374B82FC9A93FC0AC6067929C4718B2054C7AA4AF1FDBC9EBCC55A787F7C0B98A8E6181E5604E8F7108B181AD1385422EB747286FF72BD1EF650AB88865BFC37EA5536A220C29ACE17F8AA82A77F92E0A031E526171C44BD5FA1E7946CD063B1A7E113FAEAF92015CB3CCFBDD9C5E0329CD3DBD1B8CA90EC226ACC27716615B5998E0F5A5BFBA347FDD3DD851682B8968858F4A73FE5FD952CE7FF597185855E4B7F76F44BC1B24DB7C8C3A37217DBDF0BA7168D91B59DE9EA219195D29A5C67327D51D4E05131119C81722794D825B9F01DDA93C74B176545E32E638243891EE09E2AC1A9693C83D4BEFACCF25C81554802FC422C75812E18BCCF4D3CF208BE6EB16FB4E82C4ECE33C838A0B3D3EA4C027F41B4027643D9E4B6A7EFBD8D42A65B29786F4A00C16ED4492F4E945469C6E03A9A297AD9763333A2B9725DB5C6F8DF1CA7B0E77F5E6364FB6E8E528578350A04E4E4617E72E5FD67FE029AE2D738D8DFE24730D9D737D8E30ADCB602102FE2D99B915C9B04CDA463D444ED9C6E6A71BCAAFE503BF1D15270DEF8B9D7AA5557177EDEAD75E2FB01A4635A46D2F95DEA6314DE4965EBA8358210F79E64933AB4B6600856124363A47C6063433BB670266AA8FB968D947AD96D97C4003A50B0D1119E3A73E00363AE5EE85B5815A5BD944280031F0DC9B98F1F5C589F259A486BFE26EE1446D937EEDAE41275AB72E0CD15EAA6368F59686DE08E147CE2F5978B366D0A4F98ACD7D4004D1D0A4897A0DF5B1AF9F811BBAC64952D10E36A3EF78D379EF0E95DCD2D804C07AD8D1A8882FE1F2FF188F31B886BB597FF16F4D597EB337319AB4E81565EE4AC0A9BB3B6C3184C9C66511D7313555EF703194A747D0857DD27F92A6DE12DB311828B684FF3F1D848D5E92E0EFD7BC6B3EA7039296D587A075781880039A7C0DD6DB66EDEE3A22F7F2EF02B267429F6BEE16F214A59EB96CA79EC5065784445ED2FB631BADF6645991736BE7ED""") +697f53fe475ffe22de8a70436eb11099547e47df00dbb25b9ccf2c3ba3a48f8876694671779a72d10510bd703ab015a425ae50d413e9dc5e87548d70b84cb124e4950c1d546249c8c8d60fd06513bbbf6648230538bc5e88269ca0a961b9c8186abc70286289d58b96df28c39f158c1a707f75dd20371c63ff038d0ad388a22449ec4fd8f73fc82c75f1e3e6e1c9f510f3ad8ca3124aa47edf0cf150f7a664a4bd38bc73dc94a722b878b1ea51db19260f17120fbb99916e596ced350107d43bb26beca35978db929df046400f8094391830c99cf2d5cd0e1527f97419550ad1d1c31f94cbb95d3cc5ba06bdeeb973ee20b7961feee5b4c05e08b0320ea8b3be528b52bce8750fabccd59fa7f8bc9bb8f475e25f1884ce4255d4191863e20156318276d5fa1e7d2385c2744ef31c9950ab071f031d78cf28ac07c54f997ae8f07915b16b8490f1cc028ae6b4ebbe42e5d7b5d988abecd8ac22bae7887658f7af5c488d91993c72df113a6b7f435bdc3d90cb32af64d6dd617e5d0b0f611ec2a0575b347c1cd89f92c72bfa3e7ef1e3e3be4bf68ae05fef6da532ff76c9e9d7f7d354b2e638803509ec7757c78c35dee3c1149d2b25f8d18a8b6ba7b03a519d0ec7f18f895d575fe3c557d8dba332e2454281b676a96b3eb0d38ae2de00893649e1764e2cfe0b1d08ab1d69cf65049d3a2b7ba894910c6fea7eb94e64ff8a71c64ed4c9b6b4ad71597adefcddf0904364c50084bc6687affe770ddbf0e8e9268a64e70a9481d6065d2a93072daaa9583d9b2a20db31cb7d5edd37c59e4fd607ba897dd5afbc2a6403af20deccb1d4b3abeb9502c40b5440e5e9a7f850a38633bd5fa75bacadbaa330e7a401978a7d10c9332daf141580f8317fbe7c06da656e7942ea7d5d49a5bc28ffd15d17cd0dc337f7fe2f20d37ee71b51bb536f4692588acca8a3fc498de1d23c9a1b95c7efbdbca3874e91658cdb7755f5bd51553e1747737b1ce2c44604987e3c04d819d7449b6a40fbeef7b3cf7bef8df39926830c558591de535b8c5d482101a5c6a0715ec13910a243ed0d64efc997d2d2342032b8""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +6a7863ee2a8102b695afb7842cfc7ba822bbd8526522e76f3cb9884c2454da31b967f939a09c837bf2add1c9a5b5a4c13dc7742167c74678144d05b830b6756ac963d7567dc23860c8baacd3328bb209a4720c5294a665bd731213b5cee4a5c51e58b0d19891c8ba3ba2e4c1f43b9478100067681801a386474b834a2ac3ea03961f7b34263c1ed08bb9623203e920b56054a2dd7cb9caa59ec2e25d21f1442d24847080ac45b80ad2caa4025aadf282cb23853da2221d3a5782c3e34bdc3478f0e77dd77696b97c4a0273bd9ee375085c50140ca1bcda9b14117747163923b4612318c6e6417d51ba0b94202c98575699a337ef379f2e46aa32d60c1af81edfc31c35cbaacc0726179b8be68ab1cec3457cccb0ac2888fca66b94d83216b00457a28b9dc064e59157761b4c91070a7d52a9b4337d661674c497b5dc2b5bfeaa71e362882830458f215c4e75157877aab7030a2b47c36c4176df159f8c5c9f8b726335548697d004ea03893b2ba0b54317ed45863f17b5be19b5cd712b8f833755b06e33da356d1ccef0379cf7838dddb9306bd482ecf16b52a8530ff6bce2a1ca269c318f707ee0ebc4145811ad92a21b3b009606191da83dd5857d6a4849b21713e5868da4aa78702a28b33b3dfa4c34ce4a642767517bf90550c687039787d54079f6054e5e2cae5eea711a2736d8c32d3f46b84b33c41761314e91aeff51cf10191310e1c3829c8560e0c5dcf0724dd00ee2364fc82001e1e4b4d577c9768a6ab516a643d45c4f731cb9503be1a71f6bd78987427cf253a4d54a202e3c389a0c48c386793ca79af99a1f1c70130e583fa36b2e0f1ba809bcbcb9da0c19042c3d9061873b104fa7070677159edc93e00b414906c774c6c221e187b8e7b4d5636667aa10e8e89425da282399504b48ae6c690ba216bd27aaa4eb39ab09d99b85f396e21a6afa874b8fb642bca82ddac76539f236ef349534769487d99741b1c43abb21911b27eb0abe41a453dc4876a2a26dd3b93fdfa7a1817c747a2acb62e96f013675b988547f3b8a24a008b726c971b797edf0850073a94b397804aba8d0f903b9113e3b18442e9b125dd762cc4bc2fde8007fca65b4817ef985667bd62bd8806563846ddf61b68a837d35859344e96ac450cc24303d9f116d502135369305a8cc8549641487f88e0f24a31c87cea974547abb569f9c312dac3fab517c85a5521d41b7eac40c62b7cb8a0776d89828e937177785a23ba0599381004c253fc90aa8332172f7366e6c756e6f266f2c5c9bc70a5cf18416c00c83dbe76a8a9c52ec5929217c0d2be88c8e3374c2111c2ac46a2a454ceab38f8d368f2281749d4109e90702bf368d6ba6ce212146d7a21a9ce6767fdba3bf1708fc359fe4e974b676bb9ee04db18b93f60759a071484c134e0ae29b135c5f2546562f6a471a826aaa3568bcfc721d707ccaf9351462098fcb21b441c81f876a7782363ef84eb9c59b2eac7f637ac205f0c1ddab4bc0868f42c4c2ffd0912a0578e9b81dfdb400a6a747c9bc8c97ba3ff8074f454367a5768d48653cad01c30212997553941780b44f3b26b9b79e6bc43cd56683dc9770a1d81ec0601e66326148f8645f820737c2479533a7cc3142341a2fba851cd304423d835bba5c73c3fc617f393e673591040876e670b94585902818883608a773e736f52c496691481b908106609366513ae14b618b8611539b56b3f466f13a5f59e5179fd29ac4ec7a92b5beb004b628e7701b11681cc61fd088a031d80d8e43b36042857155b0c5f207260bbbd30146d83a9c3c17a1bd804b56c96b01e71de75152f4b4990a001a1d8c736e39097771b819e58a2bf4498f1ca346cc851efb29c1551060998a7242c7fb5b04b6c8cf2f703056f18a9df28504752be88860507b1aa517914b278b61704f2e33cb02307a7a898e58a3a87221898cb57243000249709f5e53037728bacc7027dda1b7fbeb7739375811427b3f8c3dbcc0775442323289bd89ea0b668cb458da346dd25a45d4c9d6eb6ad98645a65794a795277480382ad7a99e85ae9e279ff5d38ac9a461d4a8aa2170136e69bb70c2c7734060421388330606763158f0c04788d79ded7b52b79abdbf891c2290b561ab4a6aa02e591637cdac7353798d9e256fd0286389f7d3b079e3e9f89ec0a68010202ca26dd2ea953f551554098ebaea56f782c33b11b3def6e61889bc262dd4337801b55bcf0b5eb53996785555ccca66272809d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"""), xeh(""" -FA42A8B407B527A8CD9351560BA4DA60756B27FEF326BC549B3A4429B2E58EAF22B3A36AE554B416DCE209E8CC708846312992DCDD43AB177347363F81578B94F451F1D046233BEEC6B42C9E0D55F3D741A55F7C564C4A9D5ECF6B067723E4403A17CBCFAA00E2F8D2EDFE1E236AE861011A5DB659042AA23BEB01A0471D178DB91039EEE5FC7EE85AC6FF3845959E5001C61CD1756EC681C97F4A70887884157D664A505ED7E4E1F4598EBF8BCDC0BEDE7FC0A89B3E14237187CED97BB0C0E54D21F4DF47BC8FC3F863978DBB673835D17931B7819535C1ACCD8706F8726BB0A0DE20BB824560AE5BAAE2F0BF0E3E676FF74C681474534C857837E7040C33B7F031AD9900A29DCB71BC305DB0ABF92CEB5DD2EB8E644F23AC0BFD8DCD2B44101FD7CB8A287318979BAE754661FFB13097B2A52B50236094693A754DC97CFAB550877A4D8C6CBA8B4A2E3D719ABF0EB13D40976B9E3F6C433DB1E16D794466D2C023988528AD0336CE43636DD50FA6A5E899578EACEFACA5FFC5B6FCC8C53E21503B83ABEDF2174FE08B4B960476934C5D6021829AB7AA7767492FAFBEE492A08524FBED46E8D0451C6BE1BE02B55653326735B0D8CCE951A5CF534E3547731EE36EB9BA38E0AE253B8CEC35001EECE0058E634A11F59FD6F21C1A3882E291F59B1FE3EC7F55315E0A65F9D011210462A8CAFC9779208452FD4F3B64FF456EA8588D2CB394A9169F1392646880A1C63721A2277FDA432FC6EBB61FF87AD473FF41D831DD95111CF0A1D69F001A008C3FD00B46F5342EDB8DADC818E6470D21C915F3E91992806E5B18DB314F9592E0EC8B8F0DEAF92DC89C194449A2539BE7C6A1B01B6F3DC496CF33CA25825B66971880652BC6E4FBD901A286C50D625F0F682B0B4CC769EB00940C45ADE947844175A3BBE8DB92BA6DAE5BE456CEA41384BB29A8C9D4E08F1375D4865A69A59619724900DDFAE48A2D12975C789E76104AE114F30ED4F836E46BCD8CA7520F4838651225894595C4F7BEFD7ED41EAF6F395EDE40F988CBDA7E08122A61E552801C7F3E84039FFF17E3534610D3434B996312""") +e31362859b08dfcc50ad8f9dba1bfab3249b8e0b15347ae776b41dcdfaaf8596cdd6ad0eef2098b4759f8b168178d75f5a3d13c2e9af1c94d3e8598b779f14a5951928874d86a95b757816a5d74e086f81bc3313e72a1ecb637cac0212e57b3eb756056663ba1a1b066557816a8bc3c73615193bfb16543901948f7e0932eff974bd678be5002cbf91320d055e6f6245a6e3f384d88a70f0916dad162cd4b959894366032e0cc949e1e2b32a660717ef5cccb890df1357698c5f19afbe9742b87b0a077a67d2fab90488813517a8c4e35e2c58384e66d8076594ae713fcebf4c590c209c2eb015c24ade0eb37c341c922eda2220cf09a278aa4c63f97d317cf86bdb6129af96432fd53fdbf305cbd2d7ed9439760cd297d54d10cf7cb22434d51ffc04babf2b04b5acdc1aff426e9eb91e604149c8311b42ffaf14136322d8678e3fb5542423716ff4750c37c2e64fd4b772723b8c67c5876e3d99f29c8aacc118dd9998d11a0a7a18a29d593cfb1ec9a4ffa16efae2ecb4f9fed432edad543cdeb00025a734cd7f7b4c7ac96901468050ae981ac5846a6b7840ae674f97ceb5fd22efbb1ce9a003693883b84034eaaf39e87aa2ab39e782f8984b32ff7ee9cc832181da7589ffcf52562519c63ad3aadcbc04f479924b4ffff5d04fd683bc7f0c0612ae7b1d711edd39dd543efe54d87e6232005b2d9bde0ecf7ec6c0139da18161fff97055fad31f9d8952d370e25990b7322c8ee1ff5d4766e5c3ffa8b036aa0233d031787c5a6d4e788e0793f5bca432934029921014209478c6cfa5b4aa77311edb604fb3e794b61bb1a1a8e58ae4a537404df32a7ef520a8cfaed3cf45a1ed7d08059425c9bee99120d9f528c603acfadab24170c8f6cba3fd01a223324a63b5345a6def27bd5f27686deb78d0bf673f434201b9b1c24658e3f6b7f6fe2110e3cf4d8ed16c02ac9005ce57652c3307fc86f533469bd972a6d90ce8b256a9fdc42da4dee12be96954e71fc3f2a5f8192a97a7a22067bc2503cb51c5ab63e7b6f909166615b407a29b8cc8a2e9792f77836899b8f120852a53df8d4b3df6""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +6a7863ee2a8102b695afb7842cfc7ba822bbd8526522e76f3cb9884c2454da31b967f939a09c837bf2add1c9a5b5a4c13dc7742167c74678144d05b830b6756ac963d7567dc23860c8baacd3328bb209a4720c5294a665bd731213b5cee4a5c51e58b0d19891c8ba3ba2e4c1f43b9478100067681801a386474b834a2ac3ea03961f7b34263c1ed08bb9623203e920b56054a2dd7cb9caa59ec2e25d21f1442d24847080ac45b80ad2caa4025aadf282cb23853da2221d3a5782c3e34bdc3478f0e77dd77696b97c4a0273bd9ee375085c50140ca1bcda9b14117747163923b4612318c6e6417d51ba0b94202c98575699a337ef379f2e46aa32d60c1af81edfc31c35cbaacc0726179b8be68ab1cec3457cccb0ac2888fca66b94d83216b00457a28b9dc064e59157761b4c91070a7d52a9b4337d661674c497b5dc2b5bfeaa71e362882830458f215c4e75157877aab7030a2b47c36c4176df159f8c5c9f8b726335548697d004ea03893b2ba0b54317ed45863f17b5be19b5cd712b8f833755b06e33da356d1ccef0379cf7838dddb9306bd482ecf16b52a8530ff6bce2a1ca269c318f707ee0ebc4145811ad92a21b3b009606191da83dd5857d6a4849b21713e5868da4aa78702a28b33b3dfa4c34ce4a642767517bf90550c687039787d54079f6054e5e2cae5eea711a2736d8c32d3f46b84b33c41761314e91aeff51cf10191310e1c3829c8560e0c5dcf0724dd00ee2364fc82001e1e4b4d577c9768a6ab516a643d45c4f731cb9503be1a71f6bd78987427cf253a4d54a202e3c389a0c48c386793ca79af99a1f1c70130e583fa36b2e0f1ba809bcbcb9da0c19042c3d9061873b104fa7070677159edc93e00b414906c774c6c221e187b8e7b4d5636667aa10e8e89425da282399504b48ae6c690ba216bd27aaa4eb39ab09d99b85f396e21a6afa874b8fb642bca82ddac76539f236ef349534769487d99741b1c43abb21911b27eb0abe41a453dc4876a2a26dd3b93fdfa7a1817c747a2acb62e96f013675b988547f3b8a24a008b726c971b797edf0850073a94b397804aba8d0f903b9113e3b18442e9b125dd762cc4bc2fde8007fca65b4817ef985667bd62bd8806563846ddf61b68a837d35859344e96ac450cc24303d9f116d502135369305a8cc8549641487f88e0f24a31c87cea974547abb569f9c312dac3fab517c85a5521d41b7eac40c62b7cb8a0776d89828e937177785a23ba0599381004c253fc90aa8332172f7366e6c756e6f266f2c5c9bc70a5cf18416c00c83dbe76a8a9c52ec5929217c0d2be88c8e3374c2111c2ac46a2a454ceab38f8d368f2281749d4109e90702bf368d6ba6ce212146d7a21a9ce6767fdba3bf1708fc359fe4e974b676bb9ee04db18b93f60759a071484c134e0ae29b135c5f2546562f6a471a826aaa3568bcfc721d707ccaf9351462098fcb21b441c81f876a7782363ef84eb9c59b2eac7f637ac205f0c1ddab4bc0868f42c4c2ffd0912a0578e9b81dfdb400a6a747c9bc8c97ba3ff8074f454367a5768d48653cad01c30212997553941780b44f3b26b9b79e6bc43cd56683dc9770a1d81ec0601e66326148f8645f820737c2479533a7cc3142341a2fba851cd304423d835bba5c73c3fc617f393e673591040876e670b94585902818883608a773e736f52c496691481b908106609366513ae14b618b8611539b56b3f466f13a5f59e5179fd29ac4ec7a92b5beb004b628e7701b11681cc61fd088a031d80d8e43b36042857155b0c5f207260bbbd30146d83a9c3c17a1bd804b56c96b01e71de75152f4b4990a001a1d8c736e39097771b819e58a2bf4498f1ca346cc851efb29c1551060998a7242c7fb5b04b6c8cf2f703056f18a9df28504752be88860507b1aa517914b278b61704f2e33cb02307a7a898e58a3a87221898cb57243000249709f5e53037728bacc7027dda1b7fbeb7739375811427b3f8c3dbcc0775442323289bd89ea0b668cb458da346dd25a45d4c9d6eb6ad98645a65794a795277480382ad7a99e85ae9e279ff5d38ac9a461d4a8aa2170136e69bb70c2c7734060421388330606763158f0c04788d79ded7b52b79abdbf891c2290b561ab4a6aa02e591637cdac7353798d9e256fd0286389f7d3b079e3e9f89ec0a68010202ca26dd2ea953f551554098ebaea56f782c33b11b3def6e61889bc262dd4337801b55bcf0b5eb53996785555ccca66272809d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"""), xeh(""" -9F972164967C0CD03A3DD68714FE0B4EE0EDF9ACF63AA068C10FA947F8A03264B4309EE61C8C9B0C03C5FEDFC7B77AA862DDEFEFE394FB09A2396097452585ACD0CE510324A03F36904AF07B765575DCB3B1A84131C352EF14C2572E39DDBC8118875ECFD7EF7D2E41D9C9BE858FF08DBFABF8A80BCF18FDA8735F440D9B8FCAE0E67C5BF0171B99800BBF0F3EADF76F9FD69BB0734F1356C53EA9CD64E86C14C084BC3B1FEF040E5FA939F8F0D5171AD02628AFD8B02DB7D7B5C3B32F1A8EF3AD4116ADD4502414163C14D49EC73E5F4B25C5BAAB82C73401975F2119C569E1F2873DA202F32BDFB76F9AF49F22604D1B1BB173DDF6ED70D82B360C13822F5F9BC4C4D5F2391E4FB6BCB723A56666087A55E033E50202EFBBE7DAAF96AC541C855AA4154E37CDA55B1BEAB005554947F781512E2873B5CD8B118EE0932DB2FF427A15BD114D7DA79C7D899FD820A0222DF90D8E85CEAD8A1BD96A88D6D58C0A4FBDE3AA55DFA1E4B12AE6964DEDE20FE337E4BA5EE8B67CE1ADAE9851D021A56B999DED62D0E4471CD928E9AA4AEEC5C878199149D82C3CF4FCB68F63DF27842C37E52182A7E3B332F24948F3646874326B4FDF215524A1095A224F6EB02355974A6DE9746824A3954B700903292DA43D5DD51DD9D8E98E63DD01C357E4913855190049E0F1A8D9725B095ADAC4885FE832E0BEE82BF3DC355668093B475FFCF7D92228FDEDF0451C441B345372D6EE58408462E2C3BF22A095E5E23A159397FC959C126CAF936A3E64552003FEB2B963AF7F915885445EB25B934D659900DD0506A5FCB7168392824945AABFCCD01D9EA8A2256FC8E7AAF0C4243025A9F47F295F9D2713D5257D626057E904E34B8C0530A11DF2D15AE6BF1ADA6971B233B5DFB59EF8B9EB813E7E52794883BD6D676119B5B86333CBE6427F97ED719C432127805A9790837A1EB04B82907A59CED1286164A9F02716CDAAEE48799599CB09F5CA8BDE83CE8278382776CC3246EB2C0EA91C1A9D0CD7406B419A22CD6115018B9641405F9F44E13D2CD6AB457825326FC5CDE85C94DF86097BFB5204530FE8""") +e31362859b08dfcc50ad8f9dba1bfab3249b8e0b15347ae776b41dcdfaaf8596cdd6ad0eef2098b4759f8b168178d75f5a3d13c2e9af1c94d3e8598b779f14a5951928874d86a95b757816a5d74e086f81bc3313e72a1ecb637cac0212e57b3eb756056663ba1a1b066557816a8bc3c73615193bfb16543901948f7e0932eff974bd678be5002cbf91320d055e6f6245a6e3f384d88a70f0916dad162cd4b959894366032e0cc949e1e2b32a660717ef5cccb890df1357698c5f19afbe9742b87b0a077a67d2fab90488813517a8c4e35e2c58384e66d8076594ae713fcebf4c590c209c2eb015c24ade0eb37c341c922eda2220cf09a278aa4c63f97d317cf86bdb6129af96432fd53fdbf305cbd2d7ed9439760cd297d54d10cf7cb22434d51ffc04babf2b04b5acdc1aff426e9eb91e604149c8311b42ffaf14136322d8678e3fb5542423716ff4750c37c2e64fd4b772723b8c67c5876e3d99f29c8aacc118dd9998d11a0a7a18a29d593cfb1ec9a4ffa16efae2ecb4f9fed432edad543cdeb00025a734cd7f7b4c7ac96901468050ae981ac5846a6b7840ae674f97ceb5fd22efbb1ce9a003693883b84034eaaf39e87aa2ab39e782f8984b32ff7ee9cc832181da7589ffcf52562519c63ad3aadcbc04f479924b4ffff5d04fd683bc7f0c0612ae7b1d711edd39dd543efe54d87e6232005b2d9bde0ecf7ec6c0139da18161fff97055fad31f9d8952d370e25990b7322c8ee1ff5d4766e5c3ffa8b036aa0233d031787c5a6d4e788e0793f5bca432934029921014209478c6cfa5b4aa77311edb604fb3e794b61bb1a1a8e58ae4a537404df32a7ef520a8cfaed3cf45a1ed7d08059425c9bee99120d9f528c603acfadab24170c8f6cba3fd01a223324a63b5345a6def27bd5f27686deb78d0bf673f434201b9b1c24658e3f6b7f6fe2110e3cf4d8ed16c02ac9005ce57652c3307fc86f533469bd972a6d90ce8b256a9fdc42da4dee12be96954e71fc3f2a5f8192a97a7a22067bc2503cb51c5ab63e7b6f909166615b407a29b8cc8a2e9792f77836899b8f120852a53df8d4b3df6""") ), new DecapsulateTestCase( xeh(""" -69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), +14b4a7b64bba73d61fe5d4cb3d890e4b67784e9a76c69c9a6cc53d16d2ca27c149e2fc0f6ad163d4b9ce51d96cc1cb2d48821fba89823a440e04d9415c675500091bfae270fa457a2432375e42c6b49879684c98cb37a82a794293a5c3b3abb1e6694a42a6924f372c79c370a60091840c752f287468fbaad7f907c444cd88f7cf4c8a56406ab7aefc4f7c90ad7eb669c36267f2c7a50a5441627990432b823d5a0a16f8a344b68cb54439dc3727b622179de14b7478ce14059966312b2d6719bc80008c689a7f4a590fe7726dcabb05e463c9d20e92c190bd1379db03acc0a90404e4c1b7dc07ce710b93f9161325815df392bb28562faa79670601b8cb2c33e8a8d384b2458cb45b8c09e7831cc2f6beae566357e0661f980ea2f32f13d23cc5ca75d461aa69b31e3e55cf6a9baf127022114a206e918675b522e11ac9a85092f381662596b56bf71f1c119a45f32f45239f82055889c3194a4555b6d68caa549487da6b2f61567a92ca9c938d25ea0b0316990274a348b75b70c100bec44c5612249c4697649635b641693a54741e471f45e579e6d343587a3cd1789dd984bab0d126f6e99a205a3077b1467e252cd4624dbc0b88c630a9604691a01c490157c928239ef1a140cc25507cb267ae897b1a030ce09b99749a3cc0119232678877951fbc33a6a0ab19730b6849447620497ce4a5605b11844d91b5c5c2490e99495b61baee6820c1eac72a544e72a168ec093e5cc44e9ac018d2b63d79d01b6f8a1b6f2273751767fa35120f43aab38876bebca28d7cba27e4590a8c05448a897cc0a963eb9eca5c31cb52815cd88be80a93356b4082c33c43db0ce94b0d1470ba2761ce6400616ae35bd992693522cf873956112449e5d4845a012422240887016d28bc73423237759384c280184775a481f6c97da1038e07b8afb0a4e5936093755aca20802438156258b5bc607d1d171246e2a1f4d7bb18e9c8095b69c36b06bea680b4e32b6fb8bfaa2269dbb9422ef686a1da9649414ae5215434c75d96f38b373ba2735a60a2505297493afc37228ad883749b558b990cb5d1911b5322ed8034619a429573756962129b459916f158f0ecb0cae396f60c4c84670ce3fbbe119055f1a4382cf2a619c31cee5842ee8c9c6979193ba82ce9f94337306186b20a276c6d06c04f41a414c3100b31e2a2a9984067fac4a7b3c70747c55b87b2512219d62c8b51a6b628766d63d1096f63bec8806311415919336bf9d1b038022d00d1bb84387888dc10f0290b752627c2d78ca5c8475150bd925240ed94af40b43762a99a3f5b0f41d702db7cb485405d5a247ff48635ba7719aeb8a876f0986f233212c40a3645c3e4ea3b5fd02bb520b9d8aa22c4595849b8a2769b92edabb4ba1528dd067aa86b3bdb6a39985983c89c9c916b41b34018bda438e7815bdd4316f6202c0e3c73d53124ee110ee596a9e3198f24b814dfd77f0a2a7aaab3a918b64c47fa44ff018332557cd13325a8081e0002096e68a293258928896532ac5b0ef4bc28bb43f68505f8a61cde0b5ec9ca8d62c261b5290e16b22a4a978d5b141240043c9b457a89a764d9565067cba987a23d5d6b3016291fddac50c9e5581d988088a368d1c9c633bc594d39c56fc5b4a996b7c110208de1394559915138b7cd8941daccc7382b60b47770272a56f846b15c71704b8b7e08595d51658a10b348617c8b552588a20a07c6e0670416636ba0982726671d796803320e0346bea80578f7808419f14b8be67f8bbb627fe4c5c28074e1458ba909581f317e70a66320ebc5ffdab20202143f374742b77d88c80fa8b9593d74a04e2c7113101400c4afb7893f634565aeac9eb8c144a3a172a1263fbee499d7895e298b195d4caf46514927d39f430aaf13c4bc43735670e5b0350a42506621dfd737177ba3736026d314675947a1b7315844da146af84c4cfa8227bc3211895773082fa22a8c9e7c20d1257ee9577c3f36a6d3097212dc1b149421b9bab30124cb3298a6b1505bf586070f52aab80a71e17c223184b32e9a6aa4627b3b99bf089973ab53be7c461ad57317edc3b79872bc50a391a43bb18ee9bf0ca100f16409caf4abbe0239b98b16a598ce86e7c07b27646de1671e915763ec8dc3c09a20181e0525c571a18d74c74c0e798d11d22db509a0f0519c7440e6787efacb39fb35c8cab4a38302c0a9e1969f65545a404ceb25db8ea6c1d0939019e0fb29d41885757f5ffc81000f865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"""), xeh(""" -082411FFADCEE22B6C33277C32130E4C77CCB1849A2E7BDCE47EB519CAAACAAAA8DF129C5D876EAA7495ADED159D27F525EDD5F1F86B7A4FD50AC0B1F7B07C23F726D96F82D17818EEE6F032D0AEAD04D0F56EC244218905FD779268B259E29BAEF8BC66B42F47DC5BBFEA06620F38E0F373BA3F598CA7244A9F5B6823CA293BDACDD6D7B2E49BB2D00D1811C0F7FB2736876699D3F115C1D5AC58EBCFF10F514D863A56901F3DEE1328ACEF5D37DFEF841392BB29A88324CB51820A0CB30A4C222F7450F321B6617EEE7E722004AEBB5A52ABC3A984B8A142F0193EB90654FF86B8799EF7BDC01BBCD7C151587557334E01B833E950260C5E126C2BBF35EC030BBACFEF2812819A20960A9CA4E8D4836A7282F8F99AAC18BC02F6275582C7D1E6197938F67A80FB2363BF77A96355FA9E0AB19883CEA65A3010795E4A48A8B22FD04EC4578DA4452DC1B851C03A93AB147F3A34981515B75AB80D10A96570C2BF9ACB2E1662CF86E077EA455ED1B130D59CCA1F603A3471C408A342C42BE1AF6BA3E096E78CCF36CFCF6705078800E4E968FF372CE836AF5090E2442CF73E565146C69CBC0F55DB89BE1179CDF24DB6DD2C73371B00BD8CEC89FBBFAB3537DD0F50156FFA2D604BD135B91728DC93AAF31EBB51BCA15C02270D93051FBC0CF006C57F6BDDF5B8E60866E7A051358C4D0363ECB9A5EC3B6C745C41A3EFA2887B6B5AD8DC68E3C3FA17291D3D044D7085C6E2D3EB12FC3536CA8A6BEAC7B55BC2DD77B6F102C577B988E03AD963FF34CE4DFAF5194A05F12606D8E62FA7E20329E6630177BD60BCE780E014A856207A2745E5A22801A680CDBF0653EFC71F263E795AD7C495A90B7A5BECE0CC3F879B411A39A4346C677F53094298C0B2596DA1B136A32415E68A249161217414CC0F5F4D40614E162A3A757BDA41A80FCD17202AE062832D971FFD0A2F66D5EE94A26B1B78582E9F79F65A20D94EAC98DCC54D62B191DA89108126143E810AF6F8345723C69C009C481837FCED2408A8E37C96A248D7DDEFC7BBF73A5A91BFC10163813D22B0B26D5C6E380CCFCD6598844913""") +a93e00395f1aa0795a82b149b5c8ad8dd0d51c577b2b394adc282b8482a3cc3a8cb8aa2bba8a40bc799074e5b30d17b567895533cb28fbb11c05e07da2c8e080ecaaed70fd5ab2c15b33b32de50b2072a04c084b4740893c7caaf5b5fd037f91b75149cd8ce00512c4fc12f5a67eca00523e00dc7d4e60908189983848e2f529ef5688ee182ab82c44e4f5e57b3a37e6599d34fe299705de154ad6ed4e5d424ac6843925d4df9b5de48688397a39dd487ab020f38d7dbfb8a021e099d9e87aea4531c3bad076c0726667b3aae460a8bad9c5597dc49105abf2d82992bc73638322f3399d86cc6dcf5a5a8646e7100426d6f587b688d8196c8df3ac141878561d144ce12a49ac8292fa309a9b0910a23781f686e8b4915b96ec71372a9f0645caa8e0fb5e4a3a67f465f000aedbf2923bc9af8cb5682fa2fbce090600f4534bd3e384829f9caa5b9ad9c100078071256bb1bc0c93267b4a1885283a4e3d9157d48d19dc97203f19a28a9454ef99536f8a669dfe4432051950fd911939ed2e4e28d46a78d1395dd2acddc031f3218ddd4441bd5be01830277d11927e5d32d7f45494e3c3319b2516b2fb1dd7945ab16cc8227b43d356a12fe6f8c5e4e36752aeb900a02109427cd384ae6aca3869b3be2a90021137deb1f1b9abbfa0ee4fb9b4da554d83b37e0d9ad6cc28d2190d2e8f24e0c26e716270b1ba0312ace2632922a2d5d5343efbd2c37b5b4e8d1463cb8c925bcf9cc90b65625eb91e723e8a9284d165392db21b1b1d2430f06632dc0a3b87182997613b94508954cc95863a1b93808ec0c384abbb3bbb829ea6ac74864b2b5e75907d3ccfe077e461981ea59b78d7d4d521ea2bc68f47bbe403d7419876486d56a28ec5f84526e45745a6fb23cd61b3558f0fcfb408ea6963b8eeeb4ba095d30fcb9fbb81235fee1b0bafafd718e602b5a2343fd6c884b3c084ce9f1cb310f8b9811dbd94778ecba5db61e3ebdae372763e64a0e5543e949d0fd6d4b5e4a165a2ce597c704bbe6c632fb312361a211242271d8a5fc2eb638ddcaaa43586388b98087221ad59a924c5fcacbfcf9176""") ) }; static DecapsulateTestCase[] decap768TestCases = new DecapsulateTestCase[] { new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +2b3a0ad58903e3700b00ba4a6658209391cb5f7685e7f780d7bb8233e4989c0b2d2f8c9d59db9bc13ab81a87acc6981e4400033129a79552132e592834ac6933228bff548938c59869faa14467068bf8c4cf0a5dbb0a8fae2866067c2e406c3b353a4c34058c0a21792ee65c8d289df275b9fb231a5aca54469455efcb6e7ca619a1664bfdc31591e3318bba2bbb61670337a63bcc477dc20abefc5d04e816802084e185886fe08bcb620cf44c810cf786d20020c5f8458e191dc5ab42ab11b930d3658907bacfd28c0dc292e9e327d7c019fb770719f28961f019ed3cb4b78abef0a05c3e548586529f0e182cfa3ba0bcd6604dfbccf26182a1c3334c56b6fe571227b106acb7358156bdb6d1604f000f5da2928d099fba809b07912e80672c0cd07919dc41ef902d01779e9fe9a9dcd64648f02b5fb16db639422f168f96ea0b2887b2ba5a9437608b3279463ec17efe729f7421b161e98ae57764b75875727a1bd0024bc44a9b56bbc159f088d78080afa62fcb6095d2da8055645a8ffcce56fa8c04203024e406c5ea21cc4045e8e1550d016514924d7fea345d7c45c25410cff51450739155231f4ba73908c62f7c0343ab4800b3bb2269840cb3e05ab759ce5c8a9d62ac7200f8bb19b63b27707454f37dcd7c7e1f685aee256bba2c00ee076dc0d26399592f5a3591a128cb01e68830e66896e13be87205b33078efc44cfa1374a43896a3397219122a0ab030d1b2126f31112ac6690e996286568082c88b35259d23419d632b3aac7120dffb24ccec217e9883de4769a8086a8152363f42cbfecc2a13ac6ad9b6a4a8aa3287f322042c8671d6624c0490b1e2a27b81342672ac651236537b63cdda77166c585cc340a3090012f647affb818ac43d4e3bc559f0acd6157d12a86ba0640b4fd2b28694b7296738dd25089d33208002177819b46132217e6194c92085940435aebc77644aab97a432b184b172ca5370144ca9d501fd7b22b9c65b4b56796d854941a478e6d23ce561894b536b86013f1328059e7804f75bb2726302daf2b278e55dccf7a28e8192f2222f1cf335efec810e8b6521764e1e6174372a61c2d3314c53afb0755bd03bb48a280f0b3142efc08ddd6a0b6e3044ee4724831b43b0c965862b9dd9d88a4944c8d649c560d796a2372b3a065fd3c2480e1c0b32bb9625b47c5fb4c0adb0557427bc523bc97ac77edb00c3f5d6ca4a492009e182a1e6349f0090bbab3bdb0054b376712f1277c93397ca737ef1d612c7443be82996d2f95e1b26af9934c67a78a84b2559afaa1b73074040b052fbf0ab6dc546f042b1ef474769b235642480ea94ad7ddb0607f39258f73363b52e21b1577c2b5f1aa1829603647b9ba1eb17a6863350ac98c5c695cd86b090d3972c32d39b0370619998a030b2cba8998fd16c58c943af8a63c0b44acf7ad02c5bb5205795668ef97cd16aa67a47cb1b36977eeb905378a88b37af1a1a8281ebb28e5a05b248c9dd57b8836041082195922aaf073a04d8b2b5bb2c5be7cba621f08078651f9ab3a385cc0ac9ca33a0024f72c1895a698109478a9e4b7d3066466d28313bbc67e9319369f355eaf268e6d785ccc576a1344e38271a3189cdb94a4e3048a4e18621c07578243bc5c017af25da2ffce6abc3194c510076b1d0c5b5529a80b3abaa9658de03ad1e151751f54998fb77ac52a2739b09c4f0ca0b8827c04bc280ca4e7d214231547370e98b92006270194ec3c79e96bb16550692f988627b496ea4f4cf7e9511c014c2ef89ba9620896785784fec1da3458a6f5a11d3840ba4f8714610200d3a276679a7e395488d770cd5122d17b37652a9871357594a87662aeb3befecb0e82513ab90b414d60c66fc61e4db22a2a3668c05338ec86018f154c929af387183079a59e201cb512536ea4908dbd559dbc63aae57cbc40437b0d5b54e784cf7488dffd5ae861b86e7b8a57563abf5f76c81b595a144a11c464d17e6b871011f8f82a8851321f2455644d0156ac96fcc944a0ad89d52f896a2e84f5d4a146e61bd132248572c27d823142629337e116f9635a32f4647bbf2b281d6c1058695b49b51e7f602466a107fab60edecb8cafc47bfa6c65643c662026f702ac7b7118bdc6448eb65bfdf8b9eff908f354410c77bb689d9b557439e9704c4d4107cd6559d1cb5a9a10b83f9f24d3e7418d3781eeb8b07cc8c5e38189afaf64db11b20ea072674fb42c3487d74c392f278c274da80f7518f983152101b1ec941baea92c132181a9442106be237198401ce1b652ed41e8f033c3a364519b2a1edc41ebbb36529440ed398207e600e3bd2622d4534d7f06013047b41a895444947ea252f13d40d0b82b82c0405bca2454a8823a0789468f845441089e18cb89f940519756628a8c61db794c9e86c3c4820b61413b1b88af8b20a687524ccd51fb9eb76eac8b958501342c19eb3b6210133c3848a4cc1b2cfa730cd99dc9e5635b3560b0731e202453b31474bcbabb626204ba05b251bb5c63f85a850efac7d3ffc0c8e161d014a441618be32c94d7ed2818e41acbd060cb9c5b43226c05553b5bd31b310fca52389361b8b2389c952e6a275d17408bedc24a01897ff484012e74545eb099fb0620fe7523d7b49288773224a72a01b198a299036889a5d690b994abda1066072f3566a33c944550880681f716c87a9ac546ff218ffbc8ac48a8efe2b11c8c2ae3bc0a76de2173cfc5af328929d540561a588d4337d1bf8748f71140224c2e4aa458aa2958b236a6c0c77492a307f754869d9c8385213240b7a1cf70b3f7aceccbaa50a134064d64750ab5ab35982ed596913d84c74a8c63647a2f5531247373ebe23695ba767d0eca290b94647a4c94e3949b7337fb7e77ff7668f695b9beb8ab87723a58ca62efa3b75a6584768c229f18a3c26ca1a4da72972c02a9205aa08991873b94fa1f995ea6c67b8a015bc3b7a77943435cbada7323309dc74b7a92c92127b35c32879567d4e389fd5b5a6c23b932108ce22505d815c50e8e80d9dfc6c3640b111cb9c5fdaa28d199a00e405f061b6cd601bc602a6a491cf900937fe566fe3bab921c09091152592f6bb7bd951eb960708167d08fc60c40563173c45a76188871c696ce5585dbc66c65906d1c30f1be660ee2560dd6730fa4ac1b0cacb9fc05a17fbbea5d47e1eba4999f964ad5b88f874655b59cfacd4c36b818d96822f56058abd8ca410456c7af21d99462df2a596e235708b49c595eb94eac7573ff3a49697ce2a18d1c318e2340daaeb3475826b896ccff7a233709656603e1fb143844f26fb42a8b3803fc87b0e870632796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"""), xeh(""" -74A26C7D27146A22C7EAB420134E973799CEC1DA2DF61AE0FA7905A3A47485A063076BFA22D6E4FE5059DE0A32E38F11ABD63F990E91BD0E3A5BC6E710DFE5DC0F6D4A18147EBC2E2D9B179374D83692C53EFBD45F28A2A928C2494F903576C410EB1773895EBEADB119960EEBDA9C3C710795A6D9B781FC58B30D08107F4E20944A382AFB079F31D21724F2C26E6A53412F0A908BE7586F2B3D6D7C1DEA0270E98AA209244BD88ED68AAE01432342BA5F49E015CB476B5B78D15EA77A354CC9E9FD07137D8760BE42FD4746C62C02028E7B405DDC95DF3D021921CFEDDB3D961B957ECA302A263DAB2DC117BEB3E79EFACFCF936DFC09FC0D19C358D724FA381EA06CA067C384E944302C3907AB15A1DA4B41352692ADD59B061541F07EFF25EC42F46E1A0E370CAD06FF3FD997D4D2C5648AF762231B382D0593401936CBA21551A2AE30D8E8EFFCF43916B83138BB5E610364429879FA9CDD5B7D3CF2FEABAA1DC8D50CE69402E21103E795DF7074D1FCF65F8A4E18986D5417780602C63BE5A044863384BD3D8FFB685EAC567ED8349DCF2CEB702B7375B145729998049D13E2CD466CF2231B9D3A20018EE908F8514A6C6A89DF7232F91FCD84B81EBC8BC539E9A37A4324755564BE1BF4FA1FB4571E0ABBC9B52F9D090C33BE599DE6C8532C7CB7EC8B4E2D3C07505280E99923865903FFD18BC13B9C8164AA1EAE84E38D3F57FDB8801785F105A6A8574BD2FE9BF305848E525330BC2D24F0257E47A4950F433A9233E8CDEBA81DBAE7D8C1A06D01F70DE6EF663207D84952827BAB3D451CBEA0990007FBDB4240FE899A706F7C1563E05C70BE9D575189EF83E0CF76195F6652491CCE04F1CE2092170A92E0DD7301246A4C44FC0B4EE6AAA63FC7027840ABD2EC25F654589738CD38B9E10B975CFB6C1D2EB4DA97736998F84FDDDD810D72DA3C5AB13507420DDBFAA4F7750C1FAE9C7DFB30F40A12AEA689FC78DA900020E3ABB32A364D5C6B3C7544A1B5734A41E95C8314B448CD0B738D829AF772A8F81C51ADBA2D85F326C8F5D6961CF12D44A9BEDEA00D1DF5B48F429B1CE0C15EA5F5BC10B017247BA2C6BE922B0563B8E9698677CB6C45CCF2081BF84219D2904C11FF92199F8AEFAD62D8608E200802C5A07202CC820E9E520E31BF36A83002ECA4018B0B3A398801562AA86C77AB0D50A8FBC3768B0A643B97E7F9072168DE29B8175999C9AA48D301A3F0303172E9C7D4F16329D5CA9D42397C3982E10C9DA42DE88BD6C2AB91C1E71E778E58BB8F801F207A88A9B47F9C687AFBBA34EDA6D2899E4FA0008AA2B539711753DC7C07F614E814F683D6C037562AE1FBBE6D7D5FA54B7A6D9451E11B01AACCC3BF2ED64742DD100E0EAB2DF6CCCF937B6D5981ECA0E01F3245CF26A72AD1ADF066C8F5430D72F509963A657D85E554C14E26E8BEC5D5F3AB998C9B29F16B04747D80749B30E51FD2A7F690C22F9986AAF6358D6FAB8DED54971B32641DE2B258590EEAA6BF1F32324A7C4C983F49466D86""") +d746c132b3940573e9dd81e355b4154e076d40bc7f84637981d39a1375b4b51f73aaa3e69bffbfe7dc06eacc4d80f96a5a89d8d682635b0ec84b2ef60f08cb6e29ec7b8c4aadd9e3f22851fafebfb22f7d6a78a85245337a9c8f64e94d73d2a20c39efe83532b96210b7439c39cfe6c5c7ea5badc2838fbaf8c31ea91484ecf476a2c46d52678e0752f9d011c38e702ec0f866e6da2acc91b4f2ad8b09a9f2cbdb7668ec16c62d584e6a5e8a6c7ab3b6e387e67649f402e706ef89f07e231eb0614339cfd389be92e2da2021613a38b6dafe4cb35c8af8462cf1b620f120ae07e7e97ccceea635f685ed28082a63591272426006107beb094ea22142e12d22f5f34ccbc72d444ccc26a3f1aa828f1de50a47f97fae14b6c77435b3127d248574a9a991b0d2311e334477a8e63d3524fa1d832b3308902cf0ec8826df24cfeed36b4dcc7c28ddfe4a1c85c13c87dbbfabbc16a36364d365c7a549ec92743f1eda2aeeb933be4179975a97ab436808d63b1f82e9cca1f7586369c23027ff45b66932798b31c1f06f0e001b47f59f6d66e182038620bbbf647b1003b3f57900dbff42fd0c9b73346a2f8d1168ff709e12c9e297315b084a60691d7846d3c881be21e9a38cd1a84454b848d4147242b0cc38562990ad4a52ba51d461090628af98fc5d3c66ed3144b420f639598261e947aced555e33dbd61433e1314145f9147b397e46dda0465a75782c40ebea2cf20afa74678cd9682568787a0dcd79318aa37da264d09af928d6c27127638c8e6b1d202cfe6f96a8f37367d5c275d6a5860ea2c2cf600d9f75c42756e36c4a32cac23c78ace15688f5f4d3fe9553b264bf29f09f2d8e5cecb1a7b775b69c10c66169435d238beff7b5efdd079a04202fe6c2ad0cf59309ee28d67591b62e763e634775f88171abeb7e607b6bf87adecb75c1306efd0c0f02307663a76b2e56b7c14ac40e6dcd180d778a0244fadd14ee68b23f13eeb6b7495edfb42529e61567b76c7fcc9fc2f8ca0b85e647481456edbef8305b6032f2afaf2863b4de0bf9f3e7279e6e4dc468291ba2ebd4be7dd0e1ede6918d9fa7e60017e88d2a982073c131da47a76b59604989854dc4663bb70bb42da22a1c15bc9dd7d0e856261195c2e726c72ae055fb4245a2702c2b63cdd3238ca040800631ff7f48ad62ef611042842d1ac379f51f6811f8d95b6f1f618962f2421d4eed7b8d42e6d942c62492adf6bc9a586ac4a3a4336490aafb115df5646bb3c69097e33a5771207eaefb5588741cc3e7bd92e123cf9e8ccc0f9db5ea2d4580a82baa36930a86865cda996dbddcb626edd51a698c352b834f0a198e0d8abec074287b0ff5516e1416590d889b61a4e1668d00ab94d5df6b57c834488a4f13b802abfe3eb507214081452ab04e528c9305752a72090673b1168ea70329749c07fc83ff1d1bd7b92ecc65212fd8c6bd972f3159c04e78e1f94ea0b70806e499dbad1915bf85311ded1df041fc0924d461d30c358d7f4819d1425afc0739f76566""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +d44c7828421af9298976b2c4cf623bb149a5bc26a2c9c451b270294ae97422277547c09eaca491ac6ab4d793747d1106b0b9a6e5e2cbac9a69e1aa6f2c2691b6db3448fb8ca79226f3c477318504302a34975c8bc8407ac9fb4bf1ab0c99370c319801b20177ca5561c2ab0000133792abb7ee81a76c0b9d870c6e96c40963ac9b2ce230f8b3b365765ea07b45b80b8b2d70624c3acd6491170e94bfaabac2f9274d4df0b1edec5bc213b3c9f3b507e14360804e51f28d2c9c6a46a6810f47ccf09956fa361fbcb5be19d3c921d707b5948a39682443401f4f13a259982f73887fce1a522d21670ba2a3e1987912319a6c32b0b2444009064c30f2bdcbb93563e135738865c30a749347c55d69357df88ccb22bdd2d004f6a730c7950aefd5039870a9dd203b1458aa39e0a4a5a4b460048861b6a189d89240c59da830a9881365fb2b800cdc01775b61d4e35dde4b0d0b4a49813796f773134004841540cd3aeb31c6f6ad0390cf57d5bde23a5117640300dc7077287c4257566ab29bc736c0201b63636568fb2cb642f64cb7eaa24ebbcbdd2a424ff2b595972af3f5cc6c6789a88154dce59787331e6fa98a1ba53c0927c9ef859ded2b6c9c5a316a7291865452735c18cb575d49b1cf0c2012f9f0ab8eb85e3428a1d59375bb740d4868c7cdd5843128815ae592cf2a329c51c819868745203547b012410a26e3d2b0ab4905317351cfb6233da8c05cb88cd353abd84820cbe25c56c504ab4ab78f9777e74051ae222dd6c56529b56515f77a48a9a069c65785339d05baa517d97c3d40737fe07d2229330d3719422a619cc189ab72b7ac496510432a6ce3ced0eb47d4b908d8fba18aa3b60de06fb23b9534ab4c07141f7cd1c440b0734de911bcb2b48d71afd9418f0a446361071eab130756f0cad5452690b5ad61b0988ce91d2c415a621061d9104cbf3a9c1ee684a2e2432fa8c49e59129be3b72d23934520ca59ea83dd11ab51c57b338408143962620c50e6499bede76d3307be180640f3648325dbba887539aaea5fc44a16073c1dc113c587e522be274ba69b80eaeaa61d69074a96ca9faa0299048add04b9bf9948b8a3be4860cc64b30b7346019fbb61f07850b5591ffad7c2b7118b0adb9ecaa00a1dea3f40bba75c5168aab405fd8b4911d11b01f3c1a997cc35f15dc0a4863e611239abc22b774a9ed81f695879519cb995e27daeb793efc5247e6b0956fc444ab8832c980857a951b139a11b444b338531cfe72b6c66ada8268680e7147a67a9293b8a91d6b1cfa0ad7b7788d17977420b09b5db6142f0997db61f33637a16394202056df3930072e30cda7a7ed60c7b362b113105be60b713c525484a482f6ea2897bb7552f473a0bba354bea3688450218f25163b32fbc7a17d8e348107305246337c6e344c131789829a110373ac83605e24666e308785fc64975b50910791b40563ed141ca2e8154dd879495a26b9de249c58100eba91398a67ed41475c43c7593a7402bb88893b919e6d147995897602c729da851ecacc6d7b67a0aa278b635453080371e302b9a131af18520b47c294a44180a0caf2db37638d4c7f8270b9940b7a452a01dc0bcb9fa4ae0c659600c29817b4e10241e9fe717ba2cbab8ec2b959a255bb414a2571cdaeaba0db244af9405aa870deef7491b1c5fead4652599c1dacaa309535a073144e5273e932a1877bc2bd3b9125ba658feacc6de45092229bc84a94ba3f5c8bdb37849b5372c205f7bd2588cbb47b87779b004309a0b713cf428bd3083b0d6622b1826446925922b293db9747027b587a7677079cc1871a8a5016c6c04bc5576ccab31a2a0b4a7b1b852319c41f4b7855c2451c27454038515b9876d6fa11820c2c024408735837264148ff7d6062570732d3a4da3a27752f60dc2c93ff7d91607c70a13442fe4929184fb9cc4e33c1684660e1a1f6b575ff35b449c14527352c134a11a155cafeb214d12854753f54bb1a342ebb918acaa17d882074467b475976ea080bd23b256c477a0acf56fc3d9ba9b34297e71cdc37733a3d66f11942017bb8c16229a23c196de8b8411336742328ad6dc5d4ba77108342d6847abde81a4e1a4b9cb8023a1d442e245186d155e9fa0653fc4a6668691e146a6c729507c2589ac12702b08142b9745b2774cc0c44fba928f42381ca7a82d98c3b445bca7e343b0b1334a03485494a3b6661613009201961551ef9c38a2f7cfd46ba9f906c19c59386af69ce0003fdf03c880d482ecd206a0e96f54c28160064d6caa31e2902c7eb03d5f0979262591cf498d51175212aa482045121fb30f18c2274525205d7c746225c920e62c88570a3fe23731c49cdee65afc965883fbcdaf2306344c32d46b403ce050582345e5c0cfb2d08d0018cc33d1acfea146de85c1e93a3a015a1cd9c7580bb1583afa73c175645581c59a801952643da86001f065bfe6bc1d94d510bf3a0a0268a77babb675f74ae426934be0c64b115e3dfbbd2e98632fdc840f3336f31698453641a18b667579ad112490b452c8b7b9bc7086bb19e483453c4007dcb556b013801729ae23924298bac6f8c59e3ca971bca2474323cf636aa02b008fa08d56a500af032801e3157f29505fd93cf3791a210498405813d612858f503857a0300d672414bcb7b98868d0d156935b1921620bbe262223f43f3d906e6bec23235441da41415f050523b3617bd57184719ec9c92ee2b6bb4bf6427d7045c01176723c1283dbcd82782476fb9237f96b7d13697ab710291683b2953dcb9b8ff0cc0cd99a33b5fc54f6d07edac2462beac952848aa6ecacf71a656ef9b2506585665a0fa4b8c74701868070beca33556f12c0be64caefe6a1e2e271e8470c5867852abab93ed925f3837e9dcc04440607a34c4299a44e2a537bea16b8da07187278ae672509d53aad998b0de88a7605c99c1fc36edbbba10884ada971813e64815adac6641630635a73336c44a3e673ac24ad41e85697859f257a2781b95ad9e27c5ce39470ba246bfc3e0dda46260939647355d0024aa21b2063b19967eb7d7a65118f6cada035053374812b995977eb6cf1238e5520b6ceb67f261293dc9ab205c5c548213730585ddcb3b6a0d0b164f9546d079d3ae00079f6abb170603528991d71389f9113c08434d481808a823feb372437975b5624590c183c131507b2894b6a15ba6ac18b7d1a5ff0d16ed0ec41e214c1d055226b4b0063059a7486088fcf467cb1580a201b23912e571b6523869522bfa4dff5fb95aeb9fff2ae41b26e9f4a0c89217af42c53174292774edf2b4d334aecad2ae1838f6b7927d8c92060d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"""), xeh(""" -39EFB90089F1DC32A54370B3EEDF2B12880DC7D657F0404E41F7DAAA73E7F06CB90BBEEC7544160768EC3B56681D057AE1DB58F0123286D3A8CDD0B414CF9894FDA1CFF3A37CF67B82C5C7AD3427F2F2B393978B94E524F33334E4A98AFFEA8D7514D6E12E85086E58A0C078EBA64435441F3E3702EA27EEA984E46893BB886572491F22AE09F8D50774B4DDD5CF478CB0B2D070437E86645EF62AA83599093732F81A75D1D5DE15C31EC81AC4D67852FDE089D580B71E3DB07C71394424E0936BF74D0C9405BD3DFB60B920E7EFA38C72D5912BBD301BD3F3709CBEEEB7BFD0767B77A8639913E8C228FBB7E3E13C423BF05AC65B7E75F29C9048F161AF1B4B41C495ADB53FECC57FED0DCF792050A2A586C33AA4A7F6BCDA9068EA295FB692BDCA756FCC47CA0A8C84DB5DCB6A616605F3D3A34C4D23EC14942492C07EF123C8D084DF21F3B2141D277FA16E3CF4D5A3AB8D78CE8370F411DF737647A2D6123120AEE1CCF7DEFC35A5408FA6013E94703E8E04C50BADCBBF2E1FF0FB82DB4AAC595B9EAA9E370C9C6175CEF20B1D0B8A4309AB91918451E6C8A6DF04AE468D446FD9E83F9252F145A2B44A19E7B27DA56044717DB5A6ED5F6E5CDD90208ABC324290292B1F2E84FB69F5989D9921DCB4F058DCAF7B99DF71B26BD1090E457767954B8ACC84FDDFD663D64027528077B3C9E370600942E4C1175B487FBF25E267474B5238576010CCCE3315CEDD5634658B2028F3FB9959D77FA23756DB4878697C9BC491DBD68986B9073D187F2A9E72C943D94C97DA865CFD9C23508105637FED62E56E745555909A49D23B86E620D48FD55A92CC2266C38B857F5DF9BB683D60B084819CF04F5BB8CBED05AC6F48C518EDB5B222F5E6DCBB438182A7BA3B2279E5856828CBE9BDA6009A70D20DA082D2FFBD092EDAD4B272E46D215B8ECC26222499F024327A391CEB007789757FF8FA8267429F0534F305F75709DCC4229803EA8E612F55890C5FDF8252794D5C9C4058C2258A5599BA858A02F89A6FDB35C4F2364A4C6B326A31F7D04F62C2FAFE51D280CD7A4CAB66404FDFD033EADD07974BCAA7F0CB7401B9484DAF9F325B6BA53FBF41219384B264F24AA8D65281693295E6F71FCA885F808026829A3FC32DC9603F0CED36F0B58A296B44ADDA3AAF10638C31F354D1A5AC34E77D4D0154C9546709E920258F73E039FBC223EE74A270840165F64E3051B10B5E63F9ACCF5D1EF40E43F5823B15F8C25CAFCE698A64F9AE316D3905B8E510C56CF7544CA94719735A640F2B8C3A2B828A04E0568863937595E5B9DADA33533D9D676AA657FE69152E93159A00C5962F4DFF9C901A9AB32DB28B93F4BA780E44A2F73878AA76E112E3490205AF83000EFD889FCEEA5E87AE9AE01EE1CCF6BA0461A8D8654B7702C09BB41C4F61A00D05F031B244EDED8D1CAC7916BEB9AA67A3880F4C3516A8D8204932EA00EFB3AA20369FB6BE404843C7411E88428568AB9A39124EAD115298D49C998651E5EF613A6819336683""") +086f65f0cab0b99ae1bb3c2ce201813dadc0b42886de6f834962d0b0f556ddb4e83ae7c9e85d6b2eaa9f9c630a95ecf30fb88a00e0dd473053738838980d24e3c94e751df4cf8026b38e81a72ae86bcabce780273e00f3e5b821c1758f9eeb5ddf61e4cf878faabca05fca24b8735d3ac03c1206cf9155e7ac758069f48eee8b3767b48bf22721ef43394df758066e657d2baf6797e6f489469393754b22d702fd85e4cbf635500bf3cfc448a535eff7f6a2f5d9f0cbebc1e364a4a37a11f4f209a59fe109b3b07ea354c671f1f5a5cc4ac37d18184b4e487ae59ef8dae1efd296100d0c059cbce1b2342914863cd5a86b17442c616d8110f1f6c58788ca7c74970a9aa7acbb8826a1dabb80916d7f8d0c8f1dd07cdabb898cd79c64adf7dc6475e7a1d6994364ead883d520a6bc67fdd7fbdd0a2c151586c09084c6e7cf63af35bda610fe2b393d2df26b2234d7a8bda45732632d7d705ec7d76ae77e4f3536571e587cfa029a758911aeb657aa638ccbc9ffd1ad76a4af195d483cab979c3fde5180761989fa347ea8fb9fc7cec768e5e48e74604317504f7c402e44ba4281b09a0925e7a6389ff5cac489cf0beccbb8c5d6c2a45c671320b177b465148782edd926f1596d177e0710cac012d742d5d9de53ebd5aaab0a7c66499a27ce5a896ee605547296639a067762787cdca8d2147c47e53501ca453ddbe82be5691edc94df900bca5f3ff49d7a6186bf803f91cb3006ee8dc93afd3596d71beaa477afa91c6bcd43272598c887e8fa190dc898f85309720e5381ae27a15c8dad038e388e2b45c895cb64c2b6a0547867ac33d4338cf25ab834d17d4d657066408c75e146e442cd0d4305a31bf43cc20fce7b74d0edeb820cd83dc1895e12d1c254c1a9bb6f266d069ff867c4e86181622561649601635d260e868cbdbd5cef6334cea88b692f7616b0328633fb6e7e5cf94f130d090d31b61a1b31c7411c78001ed8aa6b569e42c465a60ffd94610f61ec8edbb8f86db60b99deb2cfa8660a3129eb654d775a4cd04287e4990e48f65db3c7821aed88021734ee3393582c425c2f0299907ffdd6891b7517d16203776c0c95a6a0c4100b7c358013598467af2320a8618e0f29744f519ee6d401f0eb742ccac23d23b0c985a5472cb9a4582a325abf00b6f0c1a88f3022617b75b8a20335cd2b38da0bc8c3d85340dfc85d15623c6a8ee3cb955ec6d1b4b01bea20e85353f8daacc821a40866d5590ef1ad289ed2c8c4f4e2213b395bf9758b6ad9fb44eec1515ef73a5316093f4893177761b4d0c5e43443c5a128dc2f79d6108e1540b20228c4058a4e2180fd02eae9127294567adfad6b7a393c915be347fa293d6eb68e18557bd89c19cf80f003eaa761a94783a731926fd69df099aa0a081747ea01e91a881e07df083c1781cc2607c2ebdd867d52d8ff276802c653dcc497535c96bcb6a16425adff31fe8611c55f598575e72ca06e0229f92f57b129fbd7f6a33c4716763bca05102b74afa9082eb03492f91c""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +337a1214847b4e068928d41e57d48b75296989f7b093760518b160b21515dec6aab4ac6ead05bdb5252e84f6a1ac02528efc6b87491f881ba1233b6d4fccbdaf6691b8c1883fa7bd47b1b9f2440811cc08763345cd6433d8bac1e0975d854b9f0b219d44fa19636616788b3e104a4b7ed32b80161a57e9452f5c3257c1b31663c54df544dd47b8477374e6618670d37cad3c4820910f88e870971555ca664b63409c8da2aeb7f78e52fb5bdff17d0862bc042bc6ad2a54d6d2292b4ca0d5859510c74536c605d78755d383993981aadd947682d3c6e33c1415725dd2c3730edc040b676422a8a88e33be28323e39acb2678a561fba2594d2244e7c73ab5c181050264da26159f6ce627a9e04f53fbfa5b7e5e116189c0606b315c1293949824429f340b5826eb3674333d7c62d5a2e7a9a5d0fe7bcb7f48eb39712dd53b691f62d67179f84f2848e9b2fd140115bfb9f8df6cdf05cc2f808b50b5470e1089aca044b8074ccbde39708fb2188e8352611a298d59b44680417dc35ddc93dc5a709fdc553d3e95987c1b149251d56c11d59c845eec726da222e2966886d33969885209e8972e26113a9634ac367a3fccc74007d7061e34fc939cf7f354d3465083ee143356a664d58a4c2897c77909d0f23929a2247f36c2f0f792654167a97d75aa93b1b13543e3e8591cfd29deaf56a5974c93bf165c73873db956619d6a982285084bc7cf2c4b58681a6e6913333595a07315f15d79ba0b27d590a146dc3b55354443ed74e524c2b486984e2e06622b0a00bacb8f654a205faa67a77609d89a1c12538c2f6cf6e019d11b54db176b9cdd3382c999a61a81e16126eeaca5320c44f44e77ed20117556b0929d538759619a8b57688c685bfdb8f918b0064029047d2043f2398f9539610302463a7b7bf436f58a8112cf1bcaaebcc19e94d0c3a8a53651d08b0782eb138d9741f8891b069e0b38fb24336d8a6cd1439f53b7b259c2eef718857112d9290ae9e402e8b5150cefa7496f224dba899abea69826490bc024b0dc080e5dab3a1a767ae3a22e49961a91257b80a04fa6aa48f3428e6041d6d64507c322b866899cf26adf5c48735dbc74f667d1e836447751a0da66e29548cae37a6f7c5aab572abc4e67bd58cbb5c65c2e41acf01b82019fc6c75f2931161cbbac2916250bc5472ccf7655b45d78402973da4c01b66134687f3b51349869bccb8cf4021c560209b184da65cba0928b01c45293f0b5e937b8cb6ec4a7e7a9c54a3b26d81c0fed81f18b764e639b0cca22824d09b90089995aaa2c9584f34a76d44e1092ad6cc6e99b4a6b43d58dc28a6c276f2140bebb9065ac6ad296a47cbd20df07a3cfc58556228b2bea47b19fc4646363ce4cc6bd286b912a608603bc2ac5a43eac45ff272be155969dbc764e630c0ab83197060caad34bd22b24beb25b2e7ac688ea552e8513b6422b9825112f39779dec761b92b391782bb239c99957a127352b68d77c55c013eaedc39efea650a7a214f0a8e55dc2848f84e792310aac629f6b2473a9b42783c6f870a33a197397e95652df3b646c3a9a2569d4dd333b7c62b7c7ba9198c2ba4c1110ef182c9ac645262b23ae8760753c4b88b55425144a91075cd90b31f9696fa1c326a8886765ccd67e119ddfaa185e292131128dd466206d9b4fc62250c6892be09bd6d379e88a86204226aa9449cb1f39efe58021154130e630ef70735ec57cf4f2acb93ec4434c4cd31f1a4fe798aeb50708cf90e5257991a09bdd3963f2fca8292c17f870a4f5af4cf682583ec953f1321b68f90722387136ad46d81e6a44080784b19cb975630116817e81b48051518ede43acdd9b9eab02dd481b200e3093dbb46228cc30d222c81514d1bf319bb239aa8db631f0849654285fa513b81149c19473b43caafd2115939464207076a11b7c6445a9837fcb6fea0930a321a22320658334d958a98c8921e6bea31b53b3d0912cf737c7b08022b0413bf27504eaaec33c7b8bce11427be219b945668baacb1c6e238a0a57b59d48477218db93b28860132647bcd69e8c62712a4abea8316c42e121201fb4a37e0d942464ac4e0c79805d3c61054a7e897809f37295e04ce42464d3096a388ea0b6ff5c04f3c665291012a5c4dd2cbc08d0996054a52d0a26d153aa54eb5a8ce66675bfcb657f0c952f273c5899fba9a01aef2b8934386d6695471dbac20a2b5936847da5b419ee5c34c4b100c36135ee1ca83b0990b7c405570321209a288d284e4bc7e56809591209d07050a39e629b3280574065d0f102788325b0b5b14d1fbcf2ddc0dcb6c9aa959ae2d2b7c011013814a3971d16b4d2c3480aa4c1eb135736c0d70829dea14ac862b46e9267f392ac8f1a2304b7125d7b08ed0839c61b4c02253045c2435990bc1b6d4c27244035a763d63e8ca6291390c417ee0e9beb805915dd737d68530ff27c943a39da835c49d99c0b6c50a770906aac0a5ba988e650caed744066c7a131eb050678837a3fa9b39379ef9e9283e2b0deacabf1b833b358a1a9f1c78bbf20498b9702b259ea5bb1d58844df66519c1bb0323a4b3f4866ae5ca703e6680de0253fc659b9491ae70d307f5aa4c2c888295b9122be209fda3a5a911959f6a9f0c550a3978991737a76ef408c27ccaac7443da67bfa76a79fbbc65ea72b3abb96b2b048ecd4116291852c568b59bfaaa9531524e36644112a76a809f9d0683a7d04a35cc4729017d70f5b1bb76b74b618cc9e181aadc8eb4ba5973a560c0f55dd1681ce91ca3e8e2275c8c71e5a536c7988200b5646afba80fe0c902e86d990a2ae91750409a5ea09645fa5521360051271ac6bc569b6d155fe8a379a418cfd000431cdba989872f73e2771e0b498e9698f0006050b5a06501a4b705434046aff69cc961077454795a6b3184f3ab402a22a819a24ca856c6a9e01d475c76aa7c71bfb692b182bb184b95b0fa363b76a93c7238a41661226c408218576b175e4084ca1d68b3edf79db991107bc106d103b7fa682189ba9f67c21865f2b88de32c6c757bf343b9b15b10e0a792dd3657e3d85be3dc5c3c52650425c8c62a735da286ecaa9aa15054f5245b3b514ef2c309dac712403a9d2999add6e351caacbd80a68995d67fe094a5c542994a88376397a7a15ccf1a9575e20b6a7b5c40c3c9739b02a53ed5abbc502ab66243c304b74fe27fb7ba7348b3a23cd65ad515755744839616a2e87120cb0a1e4f30ce7a6a2fa2488649dacd86c2e5fcd0162d826fb1e6adb4e0d9cd0d417b6e13a9ab1fd3fa49ecded0d3a19da325bac1a7b566823256fd56cc6b3a3696c752c98d221b9486c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"""), xeh(""" -A5C81C76C24305E1CE5D8135D41523682E9EE6D7B40AD41DF1F37C9B17DCE78076019A6B0B7C95C9BE7AF29507B2D5A6987C8EE3259190855243E6E56F5620608C52D96FAB103A8700FBA1A87DCA6078118A0871762C9534C0C0C3978C91C3A01F0F608DCF757815438FE8957C8A859183B1B6721A0865BEBC799D4E5C0E7BD3EAE4858E6AB6A2E7658ED80D4ED158B036B93FA03AFA6AE3136CF3D693C911BCC75905E5B0CB2865B9E9884522A77777613E53111D5A1C7D3DAB734CEB03657AE0C89763E99471054776BAE7D51B0E73A5BB35AEC30FF6BC93684916FEF1162586452F426653E2CA844D5744307FF9AEB287A6447783B21A0E939C81421D631F5DCB452E51ED34E3DAD1CF504E0A3B0F4711A8DC6499D1691D109569336CE1558A4C0A464E2087EA8F9E3B18F747EF61F4576AEB42B17CADB7F0FD84DA8E3A6F471D95EDFA65BE9E6C9F6AE756A22A4F1A5C543C26BA7BAD88E16D5F5B7E12E2D4CA34B3A64D17F87CCFC4FF8C5E4F53752A077C68721E8CC817F9FF24876170FF2AF89FA95855A5B1DE347C07FDDBCFE7264AA5ED6401491561D831538F852B0ED7B9E8EBAFFC060284F22D2BAEE56FA9F6D01432A115A2D6A64C38AE0A50BA362FB57B53E3E855B83CE8C42274045599F65FA6A8921D85F94ED230B516712DB6FD2FF28B3A3371D9BE058AE75C2FA591B7EC3C3DAA1F7642BC26C324C08090607E6662154DB37CF747967A1F9FC29089F570EBE60EEEF89FD24481028C85AEF1DC3B09F22CD3691BBBB821C7A8A0F35AD12BE1DD199B977048F3D48C16BB2CA94CECB8928770D5BB329A0327E0B286FAA1C65281031A31C84F2EDC9C04D475ED4E128E51EFA97D0148CBA6C95F674C589F301C265BED708E9AD8DA3C5CECBDEEED35EF1E253132BA89920D786B88230B013BCF2DC92D6B157AFA8DA8592CD0743D4982BE60D7C2D5C472AB9FA7F4CC3D12B0EBAF0ABE555C75805426844DD9428643F84406A1B8D6FAEDFD8AE6E73A72772A2159ACABD972AEB6F7DE091AC5FDD7F49A3DC6641CDF62446B4B04A31F73B80A62F80A404A8CB18CE3E65480EF7B52BF0091117E5D08EAE1B0AABB72E6DFFFF76F6E44BBD7EA570D6604BC2E74318BAFA315A38861AA1B21AFB2A53F2614F1D640075984AE62E2FCA1D1B4DB369F15705CE7D4DF8AE98264501051C0DEF21D645D49625AF02CA428D9F0C2CD9FBAEEAB97E8E9151662B6992B4C99AB1B925D08920363373F76D3FDF0828CAA69C8B1BDC6F521DF641CF1C8A4E7EF0C23289A4E2CF18ACEBBE4C1E68369BD5235120142ECDD1A73811E2E533A647D7AEE16DAA03B683639DCF1E1F1E71CFAED48F69AEC3E831733DA19CEBEC1DDBF71CBAE0800F2F6D64A096EC495D62F4344F7AA5621B322353A795AA099EA3A070272D053D4653A20CF210EAAF12CAE6023D8E5118DF04B384A44D1EDB91C44989EF7EE57F2BF81A24BDC76807DA967EE6525410C5C485067EFC3D39A9AD42CC753BAA59A1FD28AF35C00D18A406A28FC79BA""") +df7636e15fc4dc76d7e29df36ec563fc89a4698147ee234b22cc444c389126bc96d2ce9c972fc6069cd53f83e2d4990fe1974e56fb71b3a6051c4841e0b9058abd922a9991fe7ac05fc9a84bfb04487e7d6b4bbfab626a8ae016319af35d498ad76ba40ce005a4392c2900a716d16cad3fe32c80a7648de0ddacbe00f6ba77a1b7d9963772c1a08a8b1f367a48f59533a0fb64e40bb9b1eb6d855d2dfca71559eaec8105e5d8150489ad8b58774c6eea083f37fbdb6ee4c2ed4eb7042eb656e4992613cc467363571bc2462d260b793664058b723af3eba417da947b8003482665e8bc16045bf3f7f6c1f3014cc15b53053ec1bdb450df8aaaa7761eb06aba76117fe6c68dd9a138ec9d6b48551ed911e931e384d186953d180f3dd484e37dac5355fb922de719c8e2660b490f903a7d40464ce7058b322977063392415a8558d97cda6d576fafcb9df2f64b3e7b8387ee99fb39dc603a717e6411b7cbe812b4afa69bb8c096d2217d146b79dd30fe285b2426f3a44240982de43ee6383940ffbfef3323bd7a9eac6c0cfb4ef222288baa0361246888911d91b4b6b76d21ea11dd80a36b12381b31d1305842262437c97e501cb9fcab443ec26ddd18597170f2827b5b1840a94ff76f0a9c52d57d9adff6b522df25fc7797335844fa90901502878d6bb89b0beb7da8365d6127d453cbd7cffe728d477fad58633ab3ff9cda39a84cd5664662c2d4a3715c3ba00b390b8fdcc1b6ffe6d4f5a70d0191630d2e4e2ef1d499521aab477596d0c8ac3110a37b018dd616af42f39c06e862fa5804522603ac1d6beae7d68fd6b4995fc6479b5ca9a8009208775b4ff90c613a47563554cb2868e17929ddb722786251658ae59e643226fbce24178cf44f534e55ee0853bf7ae8c6d2074af6c10697ebfbc14c25b80105d32a98c88ab81545c5ff80e94564f223d72165b975b96d68986d4861fdbe94e2ad7a39cdd1de612c4426bb6e17c22cfdc9dbde43187f009f8d85bf30408731ae68afb69d08150f63d4ec4d4493e6a5f4cbb350b935101cf8d43136c7df534614272ffed99a686823cfca16758ad5349d0db3ebe3a63bec25615f5f2c0000a8f9d2150aa4478119603b151fad12c582490be381944b52670c0e10e18a4db0fb44c463e14f71f7cb7182c5d58692edd26ecf3fb40e2b42a4d4f79e3044fe11a85a87703e8b1606b7940ea0cf57067f28a1c99430f7220fb5be10833040ec9e1bffbda6e791d3c200f6a83a271ad1eb164f046a4184c9168af5ee6b5497d7372bdd1199f1d684a912c45ac70bbca360c1ed65c433dbf2cc2ef2e0a94be79c581fb6b31f6d43acc43ebd8e8e62e7b8ce5128aab3f20cba3df5e433b5b64dcbbacffc7b0858184834d42412c09cc6f68499a7792e8471501fda7eb07f3c0f7fba7bf3ff6dee1435269e20ce5da5577dbe68a0869b211c9fce3e8d456fe661e5710fa964c9ac304c28b7d84b0063e175bb4de4fb6859a2a30fa4b15e5d4bdbe6241760829584c594c201b65312011c""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +dffb727bba946a7a3a4066a2b14c31225806cec0a9f685a1d5d9a4ebbb4b98245dbd7a7303f13254302d7f428dfcc702c3b85780fb1a962529c0607461bc84269ac640f0a3741a342c960050940f06674dc4c449709a13449b190a28c8b89678df4924fe8288e7c37788e368b8c3a202db001cc56f70d7003bd6ca96c5114b28b19b13957231508ccc266ecac54f69120c76ab71bc9a1de3b9ad4c8b9c4c092845306ec68d46d077eaabac99e30d2133014d6061a507a0b1a4be09dcacfdf0cacdb24d612badd31cab6d710cd703b18b695a0d65caf440c735511cf6499288e45baa00cbbd904e629b8ffa40aad3799a5dbcaea9d3073a2b47a7502d2e53318168395576a65fd0c6639c9a513a87065c6657f822853a40ab25abb33a1fb834a14e2469c9d1a06127b4be271a09f7c70a948897729a93451ee67ac7834c05c44862bc291a89a7c27b829e7ce585cf4538d75c98c6e7975f62c3f0120a462cc93922156015b8f8615808c9ac8011c7282937ee3620e379c1227208fc2690030b46c71a6b08cb75f34347462763fb1c16ac23c7c37cc0f538584cc9b19be520f7b8186f1cba050c8da4d9576ae60c83d19563f620f50c0135a485a10425de995ec95b919443b1b7d87a27c3ad8046290a6677d3c8391be43f7ba4b46cdaa0431477ee94678f94a224ba1435b01b62444815022f9037a307054934640443207b0521ae9c9b0b4c1067da3151a30323bc5086cdc11ad549515b7b1455cacb3edcc4765b69aef4ab35094436a40b27d018b5fc77dcf951ebd214a72508fc554648679c9ee8089286635c45864ae591be1b5e8e981577a10ec7412273924a005b3219c7682e3c0671a975c463755e9941025b4b5a6cbbef5bb351a10ae38c5c19d113b13a8c11b36c40eb18a7b2ae2ad748ddc80e9ae011157c3c8c4041d0b2713156ac24a50e770b60c87a0d438a8b4570990993900d35421fa47f8283a9d4b9abbd0c5bb1ec02c0d9967ebab566e0a1a916cfa1ea52c7f9aed2152b852500a7581fe3fb4ec1b22b825c4af329abe6db87b2858d605459bf89bbe2580fb2e055387c6c33929ec0c60f269a6ca51c2323686c73e280aaa8138f8b2cea4cc27efb644c17b6cc646ba863aab91bb5dda711292a09257997f24a18b653910122965e873b09325ffee4b802da084c31a28fa6ce83da615b230cf1c11e16d9384be526e520c0e96059fc25653caa51a28657f96921f69c9f64f86805938166e03a81601b1f51a13eaaaaeaf420f83808429119fe017d9198915a6753cb35942f20b6ddac2e566b7d29b974ea96262f2a092a12592a73c383dc774cf6ae386200581a093abb9d7d5bc7d1fc694a909965c987dfd6b502fca685a6431fbaaeb85087c72a5dd4484e81b556b357b52fb76d234a24ec4991ec5863b66b7a09000e3b5804b575a5d06a0d60806e7b310e7804aaacf37d86e4c013f692d7f70912a1941ea0a7aeb5130ab43b3eb93b0e56c5cb242542b1bc3e9c9270b71fcf4028981ba7d9b60c3a6081731407acf2274021b607672528bb47afc2b39fe097f5c12f32c0c744961117212307525ab2e7a8f5f5302f2b90bceb84436a34b77cb1cae82fd6c63a44bb7312229f38375f8f405bdd3bc19ad9180367aba6988e0276031469512a6514a43902c6d66c06a236f247b077323d5bc1342c93ad1c0638f0b31aecc4a0980a543e488a39e726eceb54d1f807ce3aa556700842f1b2033871d2036ecc567f244c988242641c2aac1e31322cd08d2f95c5d559ba2328808618c5c6d8b49ca64c45082bca908dc5a75cffb1368c82cce0ca1bdd65128e3782d306829d608c2d40cd67e6ad09e79f39dbb6d9e41db559218c8263d1f6a8d4441f465a6e05510208b00522a9a6a77cae073817d99a40f1e84f4224289700a173c415095c7d35a32554678ee8087934c79943c7afdc40141a4810e94602d16c77cb80a2af5363f4444a9c32bfb8bc11e97c0d75435db0e70608dc95d85b70746263cf8c4def024a303807bb6640bee4176142c1be417aead89dcfba17eb319add262441a0c451847dd9e93dcae7c2e9c04f67c098123699df6c39dc90278362558df092c7292364c6c34cd0be104734fb1aca5282bcadc563ac571c8394b6fdeb9372081277b2987f3a26d0a812170303ca09218e842c1d2b886095bb25700e021abf45710550c4851fab4f7968460972144c1b6496f4465a0ab28478b1662b900353ca3fec6ab2c060d64caba43548c28654e1a38da32731d551b9ed03376c01be6466c74d44ce1aba9c2cc694db99cf1b09bc785ac5f0603c0248b352a69599e6b9225c887ec045a1708d73c263fea1bcc3782fd1ba1907064293fc4aced3604fd13c9d831323900f101534454bc7ff071372eba94db771dce7ab21e367925ca77bc3825db071e0f8cf207b2ca519bae8a2625c6b7b593888427a32462c0e98f009eab7b4bc151e7b727b6ba93ed0b686854026418272987069af29712c0c002e1304fa10071147ac1c6b4bbcd3232027ae2a0381a31812fb548360aa45bbbc711a7106c600af77535c51c85aafdbadf8ca6fb2c66bf66cb8856596b292490889a9b079c27d322ecbd34dcd8c2e637a7337eaaccf9c0654f748f73a6bc2921f36e1c6e662456aa66c55642c511c8376868a1a5c829da22e92e9a9af2b6ce7207bc7f94281c46eb76ab742c8ad0374973b36157018b9ba221afa3a3fd80601e85668391b97bfb30912038867b260ffc84c7fa054c0cb1f53d337b2f680d6f627093a21f7c6a065d276279bc83b759ae035288362b63b598e1611a21ae65c62f12948554cfe23bbf282702f87b540248219548fb0c363d19b9aa387353aec231965561397c3b4a41199615f02a27d7a5a6a8a93258b4466f389cd07a5ced1e75306d774c79c0b7b591fa5eb06b544bd4b751a3262481b300d1947a256f5c1a290c4eae87d0cb4b843441ef9f02ebc1100069b696c8ccbfa0958fb4551706306cb5c4d1e417a694718cf0a1e8337067a1a3c7981b81b868c8ebb71d956967e904f82c52f8a0865c05698f0e673ebe48c332293600986967559d9851bf75540cf7704dc35559b024298986d2f612a1ec18ff7f2ce1634482bf626939812c346174134ab65cc0bb7487e87d09ff7965f35a9474416c90a978bf29a5c3150bfa6745289473b485b7650ba78699b843e40c52ab380042cb3533ba8b640295faca956b0556a30be2b624942c97068f9d55db7c2d1acf9cf002c9ea2d973d79a050ba26ae235207358d083e310abc910d1bad823383a5154c8b9ceb2e525dcdc6e0a0eb8cdf10603a6185a3631d4ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"""), xeh(""" -0BAF0F6E91ECAE3199F4921631891A14C13B418B53384992DA3A8DADA7DEFFB9E1E5F559D27344B60BE81ECD01CAB1E316573D571ED46F59248F4023DB0282207E730549CDB60E793E4CD17AC6F2800E2D1FFB83477A6FE1D73992682123EA730C63269DB13088D6DA46D086CCEA2176398EAC663270B8B2F337A55E19F4C500DE066B5441794C2D0CCADFE5ABDE7D93FD7D6468BC4F925633366D9316788B90B110A4D99485E7E578537A267744FB266A4F243FA02E3A81DA67ED477923B36B37BE21DDA21EB51DCA1F0CE41652145F4C542B2E5C922617033608246BBE2B5250A368804ABDB2EF6C31C491CE3DD852AEABF6EEF1530F4C99286B4B595D57CF3A99580B59AAA2C55E080B5230EA19CF2701D21A37FEFD6F9709657A21ADD063ECBC197B5AD068BE502A2E090D83F4156B671E46617BE6D6A17D0425FAC565C4A0E48966E9D900CB2C2B0D296E0BAA9D6C5E0514CD78834053058A97D3DDF81529079858737440812670E818C9891681D350ECEC93DAE389D534A5C78F01811917061CAC0003D2BEA390EB63FA0FE9BABCD7FF302D4B66567B2BFA67B20F962847D010AA4193CBE9F8CC1B14F8B237C22675B298A8376DFB6037BF7CEA36BDEAD5B505111F67730824B4964815D00F63EE98B9BEA0F2F47CC007D5606ED7F967CB15CCD4AFBC99881CFD297BDC2A509ED3CB320DF58DC4A5BCD1CB100B9D6418CB8E0F40DEF293DA2370CA729B0FAB071FA6AEB0F3F5D1925AB2DF732F98DDBFF23D5411E4921A1C506F2F93251E822C4CF83998B000FE65ED386F5745B1D4D91AD9F98B45E713C8D944409E9D354F42FDB9749A5107C8831562E683498C55E1475E552AC10858AB9867BF8003FB88B3B09F6E8AD8E94CE82E342B1780D68EC8565FC0684AB6C798BF09FA65BE62C37A0862ABFE99D7DBE1431B4CFE007B7EC7930B14F6D161BDCAAE2217D69D9FDBB4F882B9F464F8642ACD9BA018B93A8E3A965194ACCD96E661CF0CF4A2662076E20E8BC319693F1953DAB93FEB9BCAD666832DF42F250FADBCFAF742D68642021BD6FFD97720C3E5AB86D82CE8B14C0289DBF51B50C13CFCEC12A3922DCD2DE8473329AEB23580B22F9C36B4F06D6579751BE0593120F808F0E145D94D1DDBBE1D489B744CF6C35964C3DD96D95FB693543C69766877DA80BDE8ACDF62C366D0A4A553187461F671376F7E70F554965D57760CDF5C6F6366E33B3BFB550CC1F93D98D250F90D7D36BC01581C49417546BF6BBA9D10D41C0A008855F321547BDD5A6CFA2A2516F71415B5BC2D5FA1B9B79FDC7F2B78AA113375EC1717F0F273BD8CBEF59139518A4E8A67DB4D071257000336BB07497F72FAAC2C1FC0F553B2EBA53475F466A2B36AFE0B72B4342E995C544E6E14FF7D327F80E7AC6F65190045F380B5978F50E33272484626266125A39DA08B46256624CE34223BB17299B8B8162753812F2644C9A13C51430B02ABD188DD1A4547C920BA27CDAF145BDEBC6F45EEE3F2F55553010F7B35AC63A3C7C61C""") +03788c19316364d84eae260acedabd726bed19087292fa3e1a00098d0e2d83f0001d7595ed9f43af93b801d06a1902ae53dc57bb9a6876c195473092bf794e390556ac245a5b8c25ff873d98f9736c2098852fe7aecba0264c080d9a94b353827f9eb6022e184a4825d708c64b4516b43de8badb525a1c97b2a449c9f0ec09908bef2904f609cc94728b7083d0c522bfc17f8d16b223ea19f494eaa917558e8c885c3409ea091cf7abfd250f3fd4d7d5ea41cdabe560bd2499cdced93e9bafc80fe740c43d6ef8eadd853785e6f3333bf1490e72191f139a591d08b68980f7ce8bbd4ef1a89c58ca403812f6b099ca5d9e1b80e4cb3be036b724142a90038abd5a9588e4540f8f0531714a039e9eae4b20b4fd7edc391fb366a1a2171d24bd627d9af4cd0da0b49e743d521b4d9c57f4bf82d3aeb1d0d58eb32f529587534e2ab9387bedb33feeabb68fcfe34b9e24758ec825060a1271639876ee6fe3295bc6c944d43ac028b6fcee8d127a2d54661bb2c2e91e4aee79bf7a122ed32c2ef6fc20ea01168af4a3e0d1ffb14d86682a9d7b450bf0d3c36af16f488c7d5cf0c3d6a02b0e88b85d2f92e6632df585bb4d3e2a7686447949db152ddad5a1266284fc1c37767d2a4d964dd1dacebec917bf84e92e7498cec4342e180510108acbac38b8beebde7271faf0a74cbfeb66241c6b27753135989e1f4c16cb062273c21666d5b1d68e34fdc1c34354c539d52f2de1d9c8b80b16a9065479e78406e766fcecb04017c31a2a31f7649f32315bdc6ffe2832f7aba29a76066df4fe473f47489ec783e36f591b607f5d93048bf48f54908cc645ee3f727c08549db2b07200d0ab3d7b31961418ee46dc954f493efa33296e722c72e4b69ae9c224b8b4ad9117f4aaa2c29578f8c20c95b3218f6970294064f9cc03b874a8c0907e232874164d4b8d8e1a573a2a894a3f8b5844e94a731daa17ad0d4c68443ea8d7a12fc74c7d930bdc9da13b322d2c12267a245d5c86456dfbd353f244f383324533ceb6ecb67552f9a9186bad91cce2c06ef328fc16159dda99984e03e624f8557db1dea2a42257e02c820939d1ff744fa6becadf1df969495411e141eecebad74201a81dcbb9ad80fd2ee2cdd2a34656d599cad9a62a96e83d10d6dbd1f2f0d6725f0c268627c6c6df9ae95cd972ab4e75277d47dd7e97a56a61ee3c75220c733b739ae941fea7e992c4513444aa6144eaefca06e26f998a503f33ee9840a66c0b4f0f305d55875a61c30156af670dfb236c32675d8ec124ef78e668abc8bfd20793f9b4a706de79733e4af44dcc003e55981f912fe43b298c46575aade5db5501582ecfd7314d4f62f9decace0b2992b17a0ae2c0c33e51cf4c25a93fc72cca2ab17125be2a781adcc8f686455a5bb0d328808bfe3273657c59aced7a486ed08ebb1427106d47278b058773be9bca944caccbece003b812846c81464de46cf2fd495e2edba200f92397d4c42565671ea688609267355287206d341213fa544ecdd0e4a900f7""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +e9f8ce5f78cfd9f8bcc28488b4fc383bc2433228019c49827382628b9c77bfa29035cac08802594704bee56911d587b71b351e6e1c1bd9dc1b44aa876f25c7e9d4811359631993c0aa31214960adf186ad50f10b933b46197b365c631a5803c502875e00a364f60c179086a9164b3106687752b017771a2b1c702cbd457a113abcc380020b427e7ca04523965a1f797f5675721c588e17a812f1d96b1a272b290479c78612f1987ddc9818ffe53a4921c71f9325cba7c975d392dadc18f174aee598286ffa29f0412a21fb96d7e0776708ccdc615ed4d87145425992ba8c77709ca4495de1b75de367c704654c0f1b391d766101f65535ebc9a8e4795402ceaf06a0328240713565070552adf02749964cf851ab2f2b37162b52d260a556634ff26b22b3aa28745624f74139fbb1ac976b1fb54b7590632ff7150de75ba0d6507bd8f029056232a73493dcfc70582126f2c7933b919172d465ce1acbdc3c8a2a372b13b6813df686c495b915c8a7bc089abf732b7bc38f7d6a15e07022df5922a801c943364f942b43eac13930d3c827b8a5b0fbab35e62391204ca333648a21b13c01abcfe8800b4593b52a0560373059678a8d645267a9c74d98a2c2bb94940137ae68a1e441c4fa30a7cf1433774762501b588a07ae98c493e4b9003133a441acc50c4ac6b69c7eccd1c84729693d097280338c133b91c4531b812a40e5c31ba41a436a71cdd07813f5a8bf85142c4c03a6a9f338a5b1caae9422f8f30e523c34b4741937a9b0037b39bd4731d73a97cfda20bd3534db05bffe4b4ac879cd50c758035c3f912467a83c9d071184c43bb525483a4f0575da39b11c6b942479b56c413d54aa3c455aab2e5287768c7195221caa13512174a4ee7164e0eb3c0d32417470a388da4013f51c00e31d87452d7855541d2846d53a0446921412fb4a7e492e9c0637bad68f33ab424b0898645b824c996f40133dcb73a9cc95472ab067b32b20b939ba3d9265154b114a8b20fde59e7dc5b0af6092f90b93630ca416f0b648ec0c4d5711d652a2375243ee76804b3a63382a2aa260a99b11782ca88ddfa5cd8658b1f2baba58405ba2fb46ddb113373cbadb737f34f6bcae676ce1b659ad57bffe64c79b648ee44552a051296b839baeb1a20c3777420b4a8a342ad693b23db1a074605f6cb282bb8a360fc2cf5b5ac3d0541832791af9580a1f099d98f5443ab7c246a3a510a84cfbc9a06a57938f5608cdb33725b03d700abaad2c8145732f82d575de539bf66943402c8aa4f9021a144976350f37cc407ed3787079c701cca78c606f31f2bda660c7f75b6407f18b8fb81ddddb7aa013b725fbc1d3b62e2a9988cbf8c443eb8c12a0ab2cf04095c622f2b48c01641df12a940d067c6af0c0a3bc0243bbb30e477af82c18e32695867a9cf18107f0469b9b95111c2a1d3eb40921b155e0f5986e25cd036c85f176850e57289e868d27585b965b721832862e4317de0c7d6db76e657166e4b81b5f57bed27a7e097482e5260be91767a7e7a37649726a8b79b71473cd1a25aae10aa2f480bfa65f4a010595435eec287ea586070b9a5f31f05b72c743288cbfaacacbbc5792ecc6c568ca3438e812772071873b6b97125b613002a38c5bae914cc90630d56673b824a14dd20697f800b13b17769c450a8b0dae472a2b70435643c82b329ca6440e3fd16a23dcba5d859ec8837a49d18f5c61950702846a806318752588f88590f0672fb5cf02f48fc3a8073b50c17dc8ab60c2601ef15ea514cf965a42bd771af7b917cc28a368755771ba3069036f57e1206857159394cf1b9702abfc5df3fc1dcfcbad79f2bcb3b7c9150706eb520a57b547bf217cdc902214c1b58a7c8c585b20ff1242de6525ae10cb857881897319f909870b5a5a732093f17c2172688fb585490307902e1872a4c384624b8b27539e7db3c78c272c14a988f3ab48a2e787a794b83186535970c0d19845b884c5cd427dd5ea699349363c3006656594a48bb22337877917258f0a356a58b0d5da3bd99976dde9357658b1394843c800a2cd1c608877703e3c5ca1f282d8b4b773d1623a39833f393009441c8813698957bb86ec8f4de60a92e0c2e6178e269024ff5896e2475d65854cbe4466b0671684b55490240b158657384b67db1b0b8c0c07422b460d05a1323456ca73cf749a727ad0cb81e1109388af47f321cdd836f008208978430ff1b6aad03163a412f6b93e09bcb6acdb3633b69c47aa5acb004fc7bcc8e3e2a24f949e24d1c23b9346e2c3a32c1791b67cb16f16a96ac58034daae1ca11a838ac0ddd43883976c9ddb799d53abec005b00faa3a15702ac2187d9b13b4e0a3ea8b2c9fc77a1cc23b633f9087c188291c74c9db8622dc03b78f48a35716ab5202cdde6cf3b62464cb87064b7b02a8890af2969c9275adfd28ec6c2940c717c8575a84a5cbbbd983c57183fc2eb1ac35744cda32515c2a66e3c988ed0cdb9e6778e98295f7cca7f283960275ca0222dae433c0035522ca7650606436bd767679b42b4b69912d0553e276f6b6428b7d7ca99b7ba855448e495bc51b1871a627edbf535045b037a698c8833a4696073bbe6740ff222c726c9cc636402c912dc1232b10197b7440490b92ca8e683eb4817a2b866c85a07a38885ba0284da691f99f167e1baa2caf41ad75a7931a43e21a9671bd97a65dc415c03b368d075bab0cd216b9939e4325e1c9c96251d48dc7f064339dc062b4a3777cc24bf01c272d1ca86819027cad3a491600efaf961c815940977074514a022dc40cd503ae778015d3305cd8b04d4c001d410cee5538e9331982ee52fee9857ea5c685b41bf16bc6bd7754dcab4ae99024f69336ddbc42a95079668bb8fccbc6ff66a6b05768d6b83c03c759a2bc6ad2c2205b26b41fdf022da075cf1589d88954ba502875c28ad47c31b857998acc5287da6308f800d53f95797e52d0a29ae4aeb018ee418c4f7cf72696aa286addae756e619aa8121b481ab66f25117970b66e5866b90652190d184669a4def63219c025f02149f287656e0a235cf426c7178ad99c61294a2cbc9e34fe5ea735baa8da8384daf0a13dce458433067b004bc78922c3dcc025e5688b67ab4d7fcbce06756d49772d4ebabd8b94bf07268cee346d252a9161262d38a9f04eacd7bc76a82f477334a0b3c272b4ab84aba7205a1b158319139827b3d219784101456b964929fa96d27d48ab35aa1b6f914c1465ca9548559c9a8d1f7e328029954825a12a8b4f2f4cf320831f0edb16a7359738889b1cf1870ea47583387ef1a1a3f7e78a70c9da0aec4b2d1bd6f4200cc78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"""), xeh(""" -2513DE1E55ED0E862614587FE47F308C90A1F426470CA1293BDDF7B9DDD6C368DC152F45C71354904ED48E15A1CB449B4C45D0F201ED5C7D3A047A72F080265D66C47D39469097EEEABBAA3B07ED1F1AEAB80C7D24552FA8889C674A5D4840289DE6B0FA9A222E693708D1F252DFE8B993956883C07067C1C0844EF0BEB49F63534D21D471D6B727FFC59477F9E89E5BEB2AF0CBEB052F003414DA4070008753CFC0C6D0FA9D1C15388FE5886EADD3474F28E4682C0E01784A037DC3799330EA380767B0D0B6EDFC9730E04D1039548A6F83889098522EBAB684DA6FE26A4A6891D86D40FCD9A24F743D74B23B1596810727C81BB3F9F3BADFAE9997949EE0E24987FA182A00D73DCEADF667E90E5AE76A1F83A91FCEA78C96269F0C9501F1D4CE682506A7EA89302A1480E18CDC1F6D57B5312EAF808895B20897E9A782F916CD75B4981DA1381F14EB1EC248B27F0E6966A0CD75414A735928B2120615D88FA57AF5C40E61750F0A0F8E605747E7C32D5A23F14124969C072E949C8475E3108D689D2D20797FE14618811E9A497FD26B9E71355852D4B36340B61695E3745F8D07644AC6E2C18B3FC276D4D19DB69A7CF26086F172E2BCE1618A740A0C739FD504F72C2A72ADB5564BC85DAB4C9CE790D78D14D3BD242DF04106D96CE7C3B392CCED9B99DF359FD51F306CBCBD5B46B8487CD7B7EDD3C5C02965C84630DA1B6B8B317FE55F7C79E05CDAC9E863023DAF470E9C3FB8C01FDF3AEDF2193BFA69A806E2E70151ABCF96D31CF6A317C059CA8C7D456A8E5EBAA6C1283A319F188AAA80D8301E321754E5FB4E0B25594B01BC5F82FF25B064C766424D658459EFD7A20B65DB181811E6D5A4BD153F7066BD7757D2D417D21F83D7C4CB6A0703A42032F0FD198D9D8B0F91B359FBE908432C3286E1EF9D601702157EFBAB68E0E7136BFC90D26BD8A9A7018DE4C4BF05CE465F917D20A4F221A4EE78813A1E8A117C8470929701CCC201A85E7F18B6BC96FE80B1E074661525D3FD0CE2565AB11155DAFE4D3410328D6DBB4DD99A84FE96283D32322522B88B3AA2A11C0324B1D5556EF408D37B0DF802D163FE38D7C38916A26810BD175D22762353C3175DC6040C899E07A339CD4DDBD4D5549E02C0D691263936A9F63111412B60AA9F57486334E40B2BC1B8EAA487A094E45C3F77F72EA741CE225ECBE2B5E4A1FC080070A658FDF9E2B388722855267B30D94B63C3ED35D475B7EB22E3D2462ABA9CF2A86B738EBB270AB29708A2614A557E33A620B507286E5D4CA57E2CEEDB9965FF1C3E1777F980CDFB1445BBE0B6ACBA0216980F962FBFABE265B3ADFE8641088287468827AE601B6A165DEED39C0E8773BF2046BBF63634BDBCAF98358D25FDE475781733DDE8C6D6383D13B6D48FF1B65E2FF13AAA9CCCFC3C626935C5270F9E23A71A87CF2BD793CB175D23EA5FBD82C18A1822428C32DB9E31B94BE3144ABB00F5ACAAA431C17386719C3FF47C38720B1AB01889DAD877BADC9FC716F648FC8B551F""") +14b590d4c6aec9d35b258fac481f7fd76aab8734de44fdb50372c7d51a5c89e0eab0492d73a81289b2e144dfc808e57e4c2678d3d10a1174f11c08c67716faaf021a44538a85834cb1ba3185f03db791df8f1c0f2ba3515eaa1ff3d478f457112efee587d47ffbb0296d23153730f74923eac6a51234fa13e8ff0f849672e0e5b6fbc7c10acbbd9e422515cadcbf93709f6cb3b92f81fa4dfb44286752bf430e384058f6f5f0125a13bc7b86c3171cee73de2aeab726af76d8ad62492389fb1f29839938eddecadfcd2168bce9a954d9aa56d99cde981cbe9d33b3aa79f1751030699981ee68f4ff3dc3efa17cf8f93e3dd4b70aa8327358196fc77431f900c7741cf5d9c11bd0659920f2ca5f60e023dcfd6931f6202d9dc0fdec8b835dfef83b99d188935ecc9f4ed03b993bea634ff0fb77f9d2496a5125a3ea541b54f020442151d864ccd3231141a203496fa7a40196e9dc8618dd3a891677d48f1e694097569db4a52081ab1ff1396c3d930d3ee635500675ab1662f68f921b2ab6730de901b23121de37ef9ddd40cf62b13f8f48bd7e4ac2a38ad53f977afe961260de547be03d709e8316c7ea9b5415e48b240f5b97e2600c8d5f2172bc4d10f1a2814f650dd07373ef6da5486621f5131722add069526d3b24e97cfbb8ab5ae5cdfc16d944c524013bc71da81afe1bc9648dd7a5b0f0c509bc0251c08ed15baaf8fb9bd3db9ec006a445ceb115562f5ce1978781e1ee6cde9cd1ea2d5d32be612e7f2d9ee1a94dad192019cc031ef44fe5c1b3de9fd76062faa5f25b5a8da1342addaeaa095ff3295bd5002b7d8a2335a04f1c811d8e7c6cd7f3a43e1e4af1efffab01015256540b9c0b430ee65830fb8d1732c903520319776daccde5b9628416b422a36cfd5708ea263067a064fa753e35f08ec3b2a7a1839d1137b000e7ff2f95ab3484e9f1aee634fc08e217168450b2419955e8260dcb9b386c2e5dacdcdc1de195200e5ed96809bb89754ecff2d02be76226ca99b1be92123ae79a63e8332adfacbcd9adfc04a486b9c4defea6c2887db85e5215db4b32650199361a3fbe20ceaa0d6d578ab6125145d730e78566ff25427718d5a0fcd9c6adfa3db7f23017e5887ea5c4cec213abbf1784f548677ad209cb32c09d478c629e14944d9b4e699196ea771a4549d9b00d7acfb3cca68adddf4945dd63a6f72ba74da32113bd4f8631df7b750fc56ca49059839be96103e9f4266ae7bb7ec257136ef895dbb07ff91a63aaff2a5ea6f8fc35f345c52e0ffdb7e44b82755e80697b9a35c3f34a378c45b99ca31d009d6ebf23f923d27b3a10102e2e82cab80cd52d68f83e908c43e379f15c011e138de668eb2c74928356473cddccc209afacc181a054cdc6085af4933cf1177000abdcb405e9478e05ecf5b3f1a441d0c0069915352bd33a5613fe93eec63b6df41be11ca585b4354311569e866f2c188552bd287520b52b949ba6752e723ba887897787a53eeb114627c08621ba96aa69962abd5917ef33e7e9""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +a52bafa1cc917ba04e1db8b8e4c308863025978b8d048242a744c60b50cf651b7670cb488519815a74b6a0ca7c8b82abdd168e9be479556743e80bca927503aff16714e60962c2c9e93576cdca27336796076568e0b5bef71a7434e532274a500ba9109a8a0b7b771e5643516de322da248334f1cb70d27312242e0fba31d07113d3299b388b3be33b7941721ba36c863849a32425939dfacd4851976bb000e61cbca9c6034267cffd30872462c780785506506b87d270ee0095e88641f877a838b5837c2418a3ea005b2a5fc62c9fd1861a85c152adc63637273a8db69e4b6273f11c6a902b120b6374154b7392b0483a664e36a88e4ac5aeefc2c3f765af3ed68369d5c1c1928cad77227da1c4265062cce00f1cd03b169a782fd48d8cea5c80560af611597e71cba97ba1e163c3fd318d9c904d281a5c75b79b3d1b71f6fa9bf20915c5c148ac441150e63741177cabb720ccc72505f3890f1a2696d672012cb2a73b9d7dd05d0bd93930c77bab408078b077711b6d08176cbd227f1bd24e56603d8481939852a7bb98a72c073b622244fc4476cd633383f19784e399c24b55db12bd30f4aaee90c714c75342435b509b38fc7911aef43dfa169cda1402258c5835515907b3b11be48e4a7770ede4492c7b5cb9739e2310c3bd9a414b4678883ba7d374975a269021ac5d300b0a8a9071b2262d26b49f336a6f79e68a1e5c2203e296c960ce3ec71a5ef794838ccd79c758181b67c7988f96f858a365a9ba48290009af0bab82a4a4b18a7990d9ba0fd4e23da9d5c6e0d353b2fc4caa1a5eea00a7a0baa2ae1576fac5c6e229ba8b71b23b247072e0b3f92279e6100921895a0025b23d334098d92793fc5a50ccaf588cb2fb51c3a07c005261696985aa1e90a167a7803c588839d4c555c18f73579b3e422ff1202717d4842e48a846c9cd1d6c2f647b98a48c7e47a0204cc6b6d007b027f1c1721388d5a3ae615ca2cdec18e3f09dbdc66249d77ee6240c8240cc10021a6dfb4358d7740558517658c28f507f3504007f619fe51947b2681f3d48c1a81412fe6a09bf9cb56ff648810b5fe5686bbea352e102bb9803440367353646b300122f9b16b2631329e8563a5abc29fd477b8bcb5f0ef95987d4ae71243979b201b0cb27f07c839703bdce9a738eb4738d6457b937a2e65a011389737df46aad436689b69fd7680180ba0770c0484c085e9499adbf7026da72b48ef1cf45021f8d604f2a761d8fac10e6ba71e215712bbc73c5aa1f4b801dcf278063690d31617cd863237ac91556f492484238111a9da46ab6a1c3c1e00620b62102bcb1082ffb54f1ca840518a3a75b845a59ad45111170921f65704f2c83a8281b43facc0b2b007b0e88206bacbd3c6a78faf904f6475d328bc935d01de6033f9931b3bd5a3e10a406eb9290d1052eeb374ef71b96755446f4a98b6e4c9702f7c7acd64755478824855d3d25c9f8733f55f788e8e91913737bda97c1811b6cadd10e9e90072eb81c37611168ca0699c24d1426a1b3f6ab8b346d0a287ed4a04869d94dba7160ca32ca3b7a8ef8b896148419e3a80d217c1304394273e10d54365e83f9bd09119736f05e36218d70f9086e178c05b46c32848d4c14cb6c567b994c1bfb75bf11fc3db2915f890c626ef2bfb14c1aacf9b77914bda70a37e165c65b03727e1834f2d6471f85bc705b8f63c75672336141c44e6c9b7162f0ad93a840987474b7711be7b8b7a587608604acce1b6ef5618495f365f221b5464c41d6448f87986fe8f71d27658f40a15bdd74c7ece1b8992c137e3b43b8c27e228bb9483255a7050a23755c671b4d9854a185b2707b342d051c262d7cc12439b258b30a4c14096e1c91e962944e7ccc11ca35c5d83c937aa0cedacfb89cc6c552011e31b11fc95626fa0d1c04023d8772501402187ab2af9391abe69f988a5daf8114cae6ab0010041ef4af84763e287c4368eba94e6b0bbde17585bac5a8d89e285c4569d9025b65b301374a32018366bb66f54aa4b8cc385f93a34325282f36c5bbe172ad2cb44e32aa876113d8c1000d94b7f0838acd2000a6e386e287cf77226fbc9588a5019b073a237029820bbb77f934be084318e01562eda6b4e0f01d2dc17caf290fc5b2037738a33ed181c6b4aa4d10982c38aad1143ff9530e062ab3f16a9177f145bf0a4b1a1b037682506628ab3fb127df8ccc36d0095074c0db42bf628c690665cebbd232b302802943bec761acb00065b1e07471a39d36449de0c8591de5cddcdcc3a1c43b5107ae30640fa221bc5262a86c0b0124b434da226d959ac55060cba5f32587b1892471300159c9d8045d59cb00cba04821f1a6e19a713609855e3acc0959cb2c88ac19d335b0856d19e34e306602d9c66ad1085edecac34c55443af41e76fc072741ae61950cfc174ff4f3cee652b280a39124ab7bf6f5283f2151b375a2668b71049042a421086db12e7fc7bff4d95605e8b8d5c59bdb47a71d06089e8a13e064040b1289a70b804481bd22ebca2a4340e5a498e83bb0f96c4955f516a5d125408656b72299ae73ca18a2c58342810f9c10808353acf006f93637e0254b6cc216d4c7336d5b5ce5b55fcddca0cc59a0077a6b939484eb64648281b51c3756c9c8bfae53a904f25925ecb719c25a3d378f0cc5634a4470cd839cca90701582383bf27fd2f2bce345481a2a80cfc3b6588a3c328a9d2c0105129472f5231e5b901be663016d79987812c916caa364450301b7ac0f463e87e3971f4a5f13888f66d5c78aab602e4a01a99992fa25cb303cce0624bc69063063c55c16b48deb9a5945f28c614b7e5c83243fb4500b27bbd232baee32638afa0a72f505c1ca7a286c90acba7d3783a33a2b18ceba62dc7287db9aac24a946f0bbcab94c0a2d08c72b437548b9c0d5c41f3fba3d32026bf8db12ac067cc37bc79d143e3a6c40439bc476d5b10724b643ac4d5f230e2a1c14004835963b58a231bc94b008f3f50e9b493e849cca03170a67e90f00d623c9704ee9f788514239c8105938323a78f34751c8960ed420d5821b0db6722ee07a5915110315cd00bbc4ead43719bb3e4fb63afd743c522c6dd03babfd8c9891549814ab2b7e0c66c8661acfd34db8db48feda502bb271ccc03146e7c5423a8182e84554a9349238705c250c8e579079c6c7aea73f38476f46e22c67a67b4eb20dcee2556adac841b67f65421a814c9770f84a683ac0c2db2f26222107d360c1623c9da4922b3f97e33b0bfb50623a2989ec50c6612768f42d5769fbb7ca62b31fa837d30774f7ec8feafbcdbf5805c634c0c430d47b759eda5d1f98917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"""), xeh(""" -8A4336FDDB3F55D16ADBBE54C6EF0DB27F20679393D86EA4590CB6F5F09BC4EB76181A13C9826FBD2A7174BE8A11F13759EE23DA15337A4C5612480E0A843CC6D04F3A902E144EFDC0AC118BF8553B984E758E6D7ED1373B20A5726271C5F4B542FCCD6379671CE37A5D0128F55539B9A855172CA2DA3BB6823484A87DC2333F56CBADF4A694A5DAE341A0E3FBB3D852929FBAFBF4A5C12CD3494CDF910010A0FAFBC09B375BABFFDEACCD12E6E7BD347CBFBD0C84CDABB5004CA11DDC6D14C1BD700FE3EB2371E3293F7185E2A065532C3B6529E60240E7AB6456139D66745F17B94FDF2C54B13EE4DEBF1B77099718804BAEAAACD2BC60A190487CDC76AF2EEB906E4C9F2664A30FAFB65013B8CA393793B650CAC4A93377A6511D739C2136CEC59E1BD14584989A591E1F3B7F6D7237AEDB556880810FABDB1D7F8250B61A2D16A3337DA65AEA644D7E2226BE5F24CBE01C8A33A4CCA06F6F646A3F5453FE2D9FDEA8D8613F491BCF2AEA950DB1D9B43C7C3F86FA2F4A51CB44EB9761363C38723852925247D92E37FC694D2CB00248023D5448CDE2867125250B17388440C188F7E500CEF7747A101E0BF2521E2C8A2D04F42D834C0274ECBC73E94612CCDB1C4B908BAF63C09C945AD4645912A0666E9844A1614B7F34415C1842F9B1C7DAF7EE4459A8724B7050F6B5833341691019149F351A7F11AE2416DCD5B36F18B1A4B82CC3E924114CFC126CA309E319D497A594B0AB2AFB58C19DEF3BC3AD885B29AEAC81F346A19683B8577F4A1E0F30BDC85A3814CD1196E6B29E55E5C0E4E028872477CB675B2408E136D15E54C85E8A468423CB795D9348BFCC975B4EC20A23991E6E9EF91D676983AC26B66C71548FB46C4BF06E280D7C55E7B8DB90743A8F893F95AEB4DED1DC65C5E0B61FBAD9DA0DDAC274591AA6CF23C79C09414356584F0BE02CE9B500A3EE6BD4FA0119783F50E800ED36D3A4445934DCFD87A31AF3ABC02CAC39C4B28068EECC6D16B6FA187A073BA143209C0F38AFE100BC700D461B1B364ED298AAFDFC716FA6E3870E6258B66645091FCF9413EDF6BC79B75132A46D1DFBBCE3CE9B0558EF003929CC6E3D57BC4FD3092EEAC4ED71B7B7FC70D0E65901DC9196928C5B8CF4A63C62797727C192CF1CE4315120A57D4C8CFD03143AF8754432EEBADCADBCD26C2E3A14BB43A951AFDC19EE67AAEC5DE0722E9D11E3627AD1B624ADF0FB6FD2A6733B2B1B1411DD14EE87AD3BCBBCAD2EB4A38EA00575BFA99332400083FC519C3733F6EDCCAAF71D09A7164E18A9E9587A8D9B9A46563FD3F14BFA2F2B8EBD9FDEAAEF466E591F502151E43A7E1123273E5E0574814B20253A17917D7BDF8370BC50461AC8D86127DC527B8290FE386F1AC1E6E9D7B493BB7FEDEC9E5A82DC1402DEAE71B18AB4B658E43F707259039EB9978D4FB0D62839A0DD8E3A1183CE330D57BC7927F7CCF06BA10A0478B7E2EC818195171AFF75C29B283E759F4D2F5D55F0FFC35E0581D98E582107BF64A6D80603""") +9059c2e3a96472cd2e7bd86c3e78574ea36e2586c919b94a386dd22c9a816b3c9e70842584959abdebc1e208ea779851efa48a70258fc3f7d76c327d536e0f253f06c33698c8af6bf3eab1c4835e5ad76bef5da6e23a6f14f5d47d047a4a2b71ce626207e1f5d6619a992ba98205c6d1e27ba4ea52d450099988ad9a2800f3a18af4d4349ed0b7c04bb4a76b7c7f339898749aa56b8a6d274931904eb1e75e1f497c1ee28abd951b34fcc0dbc5885ebf91bc6eafe79d2286e69416c128ab3915124f80b6c19159064327433105fa13d97ff255b672fa51b6ad3722967f413dbb13a02a9014f6755c89559c40a7c6e9b61f4c48559529f1f9413824a2e466ad3dc3c8086f113edd0160bcf00574087db6b7288b1ad665781412086a2847f24286a11aa37f39088ad167344d0591ef98b458b75f5d8a4410fcfaa83d613166f7fa41ed17cf17ce4673f9cfda45592242d6f36df8f658dc6825d2ccc30d24be4cc553ac655e64477ff91fc70a26a7fe53a6ec2cdacc75872a7a2e6a30387443db17c694bbd9578971f1319e636439cffce1f46aad2f34d60ce2a8d96186b48e64240d1d0a5af878e7636e15664905f7cbceea895d97610cdcb4767c9288e0f8fb0e059bea8363f5cc036347eb2ff8652c68acd16ef5e0a77724449f8a143b23533209b050d3187e5a3ef08c9c5dc11d9836b6396f15d4218c98bd5b440853ae5ab0a921d476b0b143ba87d355b5bde28f751695c9a392bd2e29cd60e15d5133f0a636bc05c014cd623ce9c1ba5ffd69470767a9b779b03bd00971ea534ba1c5bcc0f66d3db1aa731566fe3049850aac69a461f648df35d295f91438ff2ea8b74de1937e29582b9abf960c3c74d41b63955348822c31d350b03de0b50e4233f8bbb3e3acdb2eeb1a6b5c68cc89816ad7266277a8068a8633af85f7faffb9d94efdfb61360d1960393f71050fb4a1fe964377860a0877d18f6449833f02228bcaf8b4eeb2bfb79fea35a4a117b6e5cd8c68262696fc3a011a64b5c73a524221c38b42f6e8219f418044419a08f670fded4634ab006403d85e8d03ed1a0d1550dc5ca41271f63fbf2b9361b5e196f765a18e35dfabbdb2a4b4b6ae7ce176a3a88eddde4591e5ed0936ba88e5be7b05862cdeff319dc9a4ec0f3446d8fd6545c3a240689872b9e92486a1837bec167ac6bad6dacd3e114b7da845b86a4b9a92ec3d7e37327012caba3dd22b8c4c2d2fc1c69f4d6ae6913f966444de9915d3d4a0185d82999277690ce9fbb9187436d8317460428cfb8e5869b9c9a48ec7f3d7c8e16b7d3c1111a5fa6b4f5ad80e5f2cd6c0a331afe0c554c01c61057bead42283e9f115689948129065b38ef077cb246c83a6e5156bc14c134a470ea44aba6c6f6d6b38138d0ada2ea680af00ca499801470beb646f820a427512146c60a857f812f7cbd89989d5a13311851baaa0deb66e7e2bd5f03edb21a9dce53d486434538ac17ce82e7c1ca87a39e31e039159b6f9b1318b5fa4122c3a7af4aee297d2ee2f6219""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +5b6a031b4405919bcf0a292e27c28187e3a4b1541be42bc0d972c2d8580253b9658c80089d39ce86021ce1504c6838a4f2ba1e956290d7895255ca0e1a14394ab8c00a1506211b9943c98e90838dbc70c6a9c329a9589c54f81c405608935c4c5fea378dd30a4ed60a5933c512967867b283425a8e222b50128c5d4385266af316add0c4b60895970944b6378cfce8838922325d15c74d20a27e912661796cdb959da71b96a34c514e561d306903eb07b04a394bab33ce952939f5ca616f37b81fd79b7b988712a86b80c639a4815fb288689fda7c9e3017edba542f59bf1ca9a6c950b26cb5a45bc5bb20a9b9fbeace65885037519a9bb72842ccb21928105d10279a500e5036131c97cae02caed6a9725556ca31415a683b16149723d1e7be1128c177497a9d942b727c1361f65e8a186a8d612be43044f24c4f977001d43446ed6968a49312e4cb9683db08c731ab0cd17b63a7b0ee19b30bcc0ed2505bf5fb915be7410a9948ea31570574029c531675b64dd5b529ee221bf4e06ec5030b8de52d932281bac9a5c7582bc2b781c7b89517c1b0a2d8146695a694f7670b3796130c171a949aa0f4b8ab9b8c894acabc10be1eb9c879b3bbca990b74f941f2782d6df8300dec9eaf51a48f72cf0c01c1cab4c420d650bbe23eee7181a71872713006e334b968a22d9d3883a241b72aa0ab81847683b077e26731f69734c6579ff7490009f05928ebc9afd499525b09729056768b9cd713a5a1186ae1e89b7157291b8698a4e2a675014b864a4106b02317994da8d7cb9fe2960cf01c6aeb67ea2b5108c52970ba2c9062cc523c59e3725480d528f75c9d5cd19399e8352baa5bc1662eb9e62153fc044b65a4ce2681cf122324d3c69fc02f5572b3695718fad2808e1abef8157b2e3904e22c11844c1df8d639d0c6712a190da9b75a6dd62212fc6e2a52ba111280d5a801224860e54836ea650d2e25cd89eb5b65f21d206c4e8b5a3b60c1ba0663b458e805a14927a0894575e2cf7c191e92bc20f6d7b81aba73ca28155a4b3feec403523a1d671aada5a5a1863cccd060bc4fb0009082ac282a43b951c2e54a7c865636cf91a617f3863e50c9ac3c67252365ce19ca690286cf5ac7e8355b5fe5426e1031c000318b09b982b59cd7c0cff3e5927b030db1078c625aad57976f3a03a300fa796e2740178b4125d38754367707c5c9f08b8135b3ab6859575bb0c54985186eacb46bec4499d1136bd49965678d62c7c53725a0039727f51c4760751d8c418d8170c55d44c0ae02cfcff87292069728694efad712306929a71045a9736e08e6346f148a0d23316de7b839c9c4fbf35ac38b32e4a394ca61b686208af5fa3cf6e86d56b4cf008d74684c175b178a2fa6576bd7742cc5c0679425a3283361d47956565758f507afd76f3a3747f1369f89c857098040722a9901518ce2290e03375c7d29118a11527ac024a40c8cede69f54c4af2e69134a2aae6e0134f8c6cb53d6ccfb36765d137ca6e982ec85a7d4986f1744b3b6a8b352eac726c9729b571e47556521d76a2705a10eb43d9ccb35fe0ba3b6461b83425294bb6f0ab9b8aecc7fc2d9685840ba2a94167f4684b9a173d954c7246a3daffa8fecfac4cde76265e37997e53d8137c99ef4cdc8f0194f1984b7b3886ad87fb0227d569ba5783630f248add3b881d16c904f46249ebc73a6151ee2538fdc5b248971b3bbd5af462c36548b273beb06480b28b04b359c03af7df4344cfa28cd469476e3499652ad759b761697861f1479a4400bc034738ab9b674311374374ee5d73349c0a7b9dc0c158c13739a674532b62408bcb5c70ce4c54ae26c30118c8320eb05cb0c1454b7b06bcc013c7892c9b4693f40c6651925b0a3101da97d98c19ac5a5b3f7930061db8d38e37e37e3469ae6b52fb10300da5ab71a16e9d762a2d86473442c752187d33c2809272a16649f8403609e17bbf8003aff87468e8cb4e0e2b3a2fbc20fb8b172e606830666b6550a5c13ac862113b817c2c2f1415da33b9dc1a47451246b434f586a351c55b4c9b465fa1cc9578792368209655397c3761bd7329917497e3f357f0dc8418d474ec2f01af697b5fe30248de409130c3dcb079b50ccc73a1b709ffa5010f1644de0b3c2598e8580050a0b659c034ba7ab1c627cb43736b6b8a754dac647a1b94878529676426175c700896b5d123c5e125404a59507f5fac8acd5bc5de2035a33ceb680c412374c9753aebe423ab515886cbcab2554c9b28c3497b63bfbf7adb8db29b59abfcbb501f318b5c8d61c2f33336652c787348e00c4c15c911f7e2cb67f02ba5c2b8ec9c87ec1fa6d5dfbc05f7961c6c0829d7687df542b4eb42d8d373ecac1aa55d921f7319eaca181ba1c259e4118bc27615a866944a10e28e260f7ec1083229192212ccc9085c5436210a1392918567619b97be71f65c017555a4ae60a81ef0951165a191672c864f2112839596a343edb58885bc58c6406334a385512db7dadac2b7f510830f3b3b3440f73038d53e5ab143a6b53702f30407c6c824196b4bf069a812777a8b2c26e661cc083c52fd3259ae08b9181f06d8c993f14779300ba56b88647a5314066d4b771dbc76250a60fba5afee147b01396e91a0f0dd30ade7c82b6d85f8613a9354630bf669257b57dd563ab6b07c5a2a809cb16990ad98f23f34bebf6064c049f33913d54666892864627f8c4e64b20e06b43a5c5829bfab4eb774907c36ed5eb17ec3101aa8434a5318354510df87cc01a09d06806bd95939235fb635734068f1594a11a624e7b87ffb239dfdc864ba4322ac4357e499e80656db0bb68931159d759806b3c2518a319bde226a3c250ff0c2326750a0d23beb60b442ca595adac6f775cb06cc988718bcbc29c83e39646b99abbd5f7723757b9aaf63857c30e7f0337b8fc949cc0b4ced2260736298675aa8e6a1022aa1b8cfa3104387e429370689b398a317f0bc50d7841005048aa7e29a71d0b03348328c0c268e8f6a64f518ac06c4398d7b2f82abafaa1c9c37bb1e3a147bf870cd10c21cb702aed892346cc47e6928d3f16575f1254dbfcb910aa967a87323208937d1aaf7fa90f1261131ad4b04ff36e9f6696594a2ccf3a021ce852fb9043c194c4d3d704edfc5e3d2ab671b8103e8bcfc631107815790e5733eeb66fa344b9f276c531e5505303b267b6516b00b056780230847aea99cae15bb4faba0b9d461877419ca2d16ca437f0f2963e80f169e7bd65d440b7d6ed512ee105bb1690052a72bc54207b09e402819946c6be8ad1896c231bd52d35277981d8b9f8b4b3115c3316a7cdd3dddf022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"""), xeh(""" -6095A951753A644DD898D69138B4E521A704DCFAAD44EB53E284F836A469349C5B9279248AFC57AC93FA34A643DE02B724615CF5865927FED60A6B41E4AB15B4DA3599F13D2C1996C6D6989443BE6FB81F5BA03BDD53462BE5812A3E177876A102B0EBDFCB16DE7B29B5123A79DD82E5CD47ABA02759FAF5401E3BF03144A90AE957EC04DB9864ADE1C5A700CEC7872CCB64FF931984DDC3FB8D4971D761E5544130278C75A1B04E641E070A747789A71E09409C155C7D341D5F828A575EE74439155930DF22FD7716185BDF917472432A30A6762C9FE1A254442F755804D295B1698B47A67BBFDE178200F9CC3D4C705F4AC1B00C372D468E16ED3CBAAA862A2574A9574A7280878BB82DA7BD1B2A58943456838F2E6AA9F6EF1827C5B24FA09DE07E9B3153B0F44A4F2AEA7610F9CCA92565740E7295BA3AC5764A20A44D4E1862E55B1DF7913B279F438B3B34E0C22FD90E06497F7DCF8D62352447C2B8C51C214796194CDF66D5001278D0D55F82FA31DAA72BA6CDA34E60D696ED79C7056BFE97265F3D1BC07719B745ADD4A83404D91A184E629FC24AE236CF6AFAE46295D24B431D819E366F51E1BB2B44B1FB7A3060091DEA1D416268CA550EE4E41FCA1F387E941DBE4EBAE222D3CF625632D1A61414038FD437BFA20005EBC404ADCDE2DC10DB741A3B7534C40822520C4703FDFB6B380F7DB72B725B330D0C20DF256BBDDC31E0EA20E636A9FAE310185A5081923BAFE041AC6FCD4E73F5F7237142B74681F637996D28C3FDE6052243269D19316C56993722EADF19A985E579ED559F971E69EB5125937EBC80ECD15A4F80D7067905A4D39C6220EFE43883CF22E9A366F8911E21D0491B8FF61FD07B733E707A08DB400E438DAA00D481C5AC62064CF47AFE3AB08027B3890E8C8835CEAF8128F9D887A6CB7FDE879D9611C01281A0F02DE0E969C9131F8512138036EC1967DCA45AA30BE8C5B1008113E17A91D9F8E9995C07C0B13A45668C96356F09C3E08FE4C7DF5F7230E0C93EEF08E8958B55E213718C516E624B57765257D21696A3458FFBA11DE708C4EE9AF2EDC5F37458DEC8B985076882D3F4DEB00BFD8E7EA4D57BAEAEC6BABC0E28C15419CCD785CF6ACEC96D1111CDD1DA9A151F59A7366B64A53F0497D3B5A8ECB60D7C220E99126CDE82938C7E131BD841300AE461A1817703ED5B0510B47F2C2980F1E11CFBECB524B295C42187F15B0C9F6B0EB1E70B3EC43ED955528B1E42E2BCB31F3A1CFB5E9C807E8D366E9227A87784748B277D6C885B1385C6C691B3DBD7841DD89721B3A8BF96EBA99C53D4BB3B41DB9409B992BCC2D8FC53E70723CA1FDC1341A3E608D7F62F2322C6A9BA1316639690A22AECEE364B4F13949A0310FBA1A0E35DDA5FF840DABAC55041B0931D9EBEC89B78DD930512340B4B5D0877AF546FF0F342FB76B647D604EE2E20207924F39907D6E72DD4A9A1ED0B6D7364CCE69981F56CBDEDD51CBAF6FDDB36E327AD65D4FE283D253E6BF3C7969FFF1F34DCC742""") +90bd8c5e14744ddc8675a988db156ef227b724ca2e01095cb11f06a97e889db1e4f9de9ab6204f3c283e33d9de36249010686787e14282d3b7c2b074db1f0a509fcebae53c0b35dee8e46033a1f253f475eb9f09994c7d3e209cedc8d2b591739ff1a62e1f4c8cd833b8da55c8881ae07b3c84e26458384102722916451c642d19b47bfa713e815b37d63d2a9a7e4a5304ea1fab3eed37567d09ad16a4dcac45605b7ddcc65cff7aa8844c82e5999ed28f5d1109e7fd9e425b5409af85622420d21585cad96afa841584256682fbc10037a4989a55d2afa09a12bf007c569b25b937720623cb58456ad565f5b5fe9e475d00e67f7414411913b30949954d952a596985bc2786b7a6e697cdb6d82f24ffa4d1ccc6d8db78de1ac91991f22c254e3f3b5a0d3716e645af3c12c41a495e98115558013d12893c5fc8c21be7dea6d2f55befe296ecb980e3ba40267bd1aac40f378c67d64cbb0d053ad33f9949cf8c1d43b69c6e15a5aa2446681eedeee320c953a8f8aa8085d8454d9a6037dcd887c3499cc8e6e91e485fa8a5e7ce6492964dbbfaa9cc93a45b3488bcba7384787e1ec10635a092f51370421122dca671a5d670dc4a3735b04d977b1e378360282212024ad3fff86345a92f570069f8ff9f2ea5c28c44935a57e36db1caf6908cddeaf3896524c9042f3120f4a921e22b3ed73ae062b863f4fff402976fcd1e818a9069e594501d1776ea50377de97f71d9093bd7bebeb70a21154aa1c5b12d2b33540bf65e5fcd460c9a3e48386ad670c37b750fe72ac71b93b7f8c468692d95a3a4393b68b44919bd1e9e87492d9debb7fd09bc1d68cc758c82789e50027bc73a6df171de78958a112d50d50b9e32ca68c490061a4da36fe6bf7b0d1e8a8825045dbc1b5f6af55b953f9344794dde62414ee2ceda0c22301d8a84c01fdeb67cb8f3b5b3f66289d99a556985e09150ae36610f0ec8ee2d6b53ad1cd7780331f813f4397f5380ea5f1cd838e7cf58144bbe9db4366c126221ab1adce2b0a140a780495f1d8b2f41a6b5602e3fe66e449aed2e8cc141c7462c290d8f9b4b14a8705fc0cd689930f6686a102f3d90c6eeab216576d27112b6cec886241514c7341ea4d6198247d9eeb1e78af0d717a1de3b87af12536c37eef2242fe6d811126d4d587f601bdf739a0432d37597a56d518e4c5898037966a1bfe756f87ddaae26d382a04244564b90b103963a0798cb7237e4af9ac2fd1408b2b75583ecada700d9fef4b8f7fc130c3ae123a77f36c8bc3604fc9b517c7dea1bddf2fc0f820ae58fd889b68e079257b0dfaa0fd57fd2a4356b3eaedd37b1afdf48d85939a4b66466faee18f9c01c24409974f5e9e0b2caccb24c355f93a17dd899aa140191a036dce3d61a7bda069aebb7d24e1aca67751f2230e2ab9288e0a6f82489e8bf7a7409ade15e7b5c17c301e56e9e22f28c50047f2806f5f4283f42b9dc26d00783beeae516eb1f52c95a97de787d3491215b1007a3f42f80c969a926d2f56e81279f8013""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +57c70235fb2cdbdb64c2f2c8aa3933f94a9607104169371c182b7997018335aab5bbe8ba7050a5d97538a3f0a1819a56433b1870f6718b63c688860b7e55960c3b80d7a0029f973058b9bc09868b454b9d549603a5187704b904151c62d36516c0bc195d53ca93a0455eb02eb194295bb5a27b51be81b45d865ac7c76a0e81131528c54e14266c49e10bef401211438ce8d969dc240a0812297b88a4439667dd8325406b97a0f91eb9938b3ea71621cb329b24cac98311ac443373b86e7c2a7825532abb0357636ac4276655f3b2b9349054d4c6c25211876359cfce44bb61c41e40316509d6349761633c58958e2546e314ccf24139ccc48c70313fea782dd7c41cd3f9ca2cc7ae61b65aad856d122bbd4d973ac47c0389baa0f7e84fbaf7c57bd38d66127c7c1a226d396e5c363fa76515a67494a52a74fda7ccce919a027843ab5b1293d6709e60176f78887ba4b2456bc5422c49fd289260527d7497ac9ae89c10456d2d018b0b0a365d92061f9744272c92a6388a7b884ce8f722a0e999495b2322f088b7c561c2eb632c322b4898ab3df25d90e5b1677aa4ace1a0bfa91b50a4ad721943da175fc4969ee8435315acb1a923bfb30101f6080ce191c91b18b79a09561b3a7fef5879f3ab59a34177a6f0087681080e9799a4e874dcf26ca671392f5830cf384602636b5b9118916ba7c9880d0202a5f8cb38efa2608f68553dd28d1cc26eb6e06f18d8886839c342447ae4468c1800b64ab89348a8ba111c5740361fe182812a3716c1b577ec75c9f14c1ed62182fff0aacc20c2e9635c18e6a44ba541ec748059d386c91bb94901a7477b6343e6cd97cc711871084faa40887b28721176d8762e993b7831151d4287c31050491228b6af6b4913428646b66309d055e0b470d3c3584e960b17530d63c530fa352d6cec88b4e93019dacc39ccb10a04718026762c255b5e515d1e381dd6d948cca73210b184782528a5340feeecc236e6495bd7850ada82d138b3fdfc5e9aaa5310db28fdc9cd9d7ac69ca869ac376f153c0db1e97632ab7b4b1965ece9b7024c2eb280cd6962639b661c9dd719c7cc39e576450201ce3b5747d982b9fdbb728b23c30457c7e537c3cb5a0580fcb211b43fae656d9560296f1c6e7d0319e5697a3202461a0c52d8488de70ab842970c559026fa88004eeb746920402725501146b182a2696909cd7a75260f78cb1124a73cb4b22cf35aa60ab6d4a612e56a4f135391367a64003a0113cb2fc2a2a27c4bcb9e01a6d17623be3119f2795dff488c733c7f1299344fdc80f5a8cf5ad7b15ef76a72cba0abb181f9c6ca064a9e5366cb7758af1ec0400cc1380c837dfbea20b2e2b2deb9419fbac7fab5b4e33691872a8d8db27f1799500a938d309c50dd364e70b3709c9c67a6c1b721848bd3cc8b0636879c965be513a12c973b2c17b07a7901919a9ffb70b101d5314e508f9d1979fdfa36dc7790b4b034fba6ac85a015cd82684a573fd142a05a934eb647143d9070ee99bbe034530e281a075c70e5ab266858c3c57c22b9703464497b229acd7997bf6a31b08fb1cf206b569ebc7ff62108b0f404dca30dd0d51a8800503370cdd3090710d5a180d8cad5e216438b4535c69165f884be521e5ccc33f22695aa122e5d918e8d27a390035a42b9c8e4abc9dfaa92f090360c9892fec554851c7e434caf9d41896741aca2f2ad64e8b1e3916827215beae96d2d190f22917ccbfbb3452914078607a0eca4199714ea8040e9c9945c71501bd1b6baa00628c62c220b5dd79846da4399536547b04811f6915045e63abb9575076150bce269c61390cd3a3fb3db7235390b63dc49d041788d25650858a062e49f4d9855cac7c7d403b172044e2234425f503f3f613a5b1a72fb32590c851d71295f0da4113705b306e6524c398a59a83ee6a9893091beaa78470b274680017387eb13b97baff06a23986251a1f1a4f73a72054640d6574b5d070582925b201b37b5a690cecab7bcf72e16e3454eca10fac9b760cc94928307c2853a15c47c6d29ab90e322b3b566a43166428c09a1b3ab3515704bc76778c38b0ed224ae727024f2008cf2b5128cb912a9bd806bad62e78e1d79cc90f3675f863df590210a18b6b629cf91738f23280e93ba04b3661cb0e040709639a5b495c7a36eca739270031c97db9ed9432a4ad86608528a7ff7034652571fc6904662116980201f8073ca003092c19df909989dfc6744274a2e01377099bd618aa443c883bf8b87a9bcc9d35c56aeb49068592d31e16e12c711cc9a1e9780329a92aafa84827e685a21a84156b29233e50f577c54fca9a3f9dc6f4707704b515d9f2492dfc22977a36dde51704ac653764b124cfa615dd5932a05b895987aa714c1bb38c3166b27cba655786c29fb733448381fa7606df0f586c3ab0f2660901ed1444512ca70108e180776078c417cda8ad2241ea9304f820a9964e455d8da350ec30469fa6ec3470ff4848da109cb1060abea4c3a4b733b97d04beda35e769a7f1f84bf98c8790e91199ef04a6ac80bcdd39ad4979c327b84c0e897a4046bcab450eb3cc4d52b83e2f3845bb6c4729b3508e064576a6a8caa9cc12c917118196000a1e478c278257da8a10d78734b44e426335c81a4e6988015a6eff43470d98becc9722d254a6df327ecc91174a3a76ab430ab40678b37cb098926823955d5d8aa8f4c2598eb8ace098da3cc43e84a4a205c00cce1962c7411646a1a4cbac0fe884db3d55cbc0531d4497e562cc0b6f9139c905a8036153ea18570c1164e8b73c15630b4d020380c63cc1847e38a938085bd74338704266a6462163a176efc248c5ea6568056be253306ad8ba7d7d6144622002daa5034cca3af106a7f2b61a0e7b8804677adec1bfe84b09b910f96eca5f090cbc4e14139f12b29b7926225689acbbcd7e4cf2921219841c68d900397a100937687a9d779efa7301c4b1d1f74acfa820445c851bcb874c3c5b6e33297c2b424737b082e31034723b05c6182ee8154f5f13d69e67b25a58f8a543e19f7c279e99eda3c53854791c20a1ed0e95a8db87bca83aa6925658cf4035ca0879d477ab8b4c104e149b550b3209b5f36e149108a1918fc29de294fdb250fc66b691c30c9d6016b36a83e73f9a31df40744b39410201049642380ca752b64a2d536b6af19365b434b326cce1bda94719bae4d418b81cbb28921c8d02b4452556a156aacac7608eb97a2a56949059a5c232a561f842f40228b99be04e4a6a52718dc4ba9689b0020bf1bcb8bef492e4cb5232db76cf0a8602a85d8427b11ae9d75a2be6796ac7f8931f1f19668d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"""), xeh(""" -2AACD2E6B884BE6A3DDD80155BDCA80EBAF0E2BF714312BBA30D5B367F2D95AC7BEC3965AB05AFA370A42A512B5EFE4B0DEFF3E163AF186B725BCAFD2AFB2BD2A0DBAB74C2BF9362E27D69B6B4B5AA6500EBC9316EA4112745F1C6E98F2DEF9132C7C0BFFEAAFAF994C89B96D3F436B875178963FBC18D2E06ECAF3871787C1AE93B3210896837EC1DA87F0FD8F14AB7C5CB2531E90F415FEBDA378E5492E1DEC8243FE2E8A7BAA6FB6A034D9C524E99D848A804F150915BFD66067C8603B5DB0FE29E27D3F6CA629E96BF3E9C77A5919701EC19646C69A73DFAAB0ABA28FE3E9EAAEB475A441B9B0D62B259DC6B77DEC964AB57D5D776988D54E6246C526F1E8EFDF454E7F0DDAED5363CE02B279CD3B554C251793C3A616C07A7BABA8062919A2B46C64C152BC887A27E382254EA6D50CCC0702B7BC0994BAC09B7891FA64A773AE0B4FBF8204C13A4950FC2C4DF60CEFED7582FD9FBB8C83442517BA0E3B60D9A04FBB24ABCECB303E3FDD37F1037741FD2489F632192A6B9C122A7344CB781A0F61D5011EB0251A842AD4838F9B8D52E21A783F0D839E8BA221CCDD6B968A2B5FD21B8458BF53C9C8076AC0C52C0F53097ED1C25C9F6F12407772D6743EB8E0CE8B1A926F0FDD0DB00482D9590675E56D4509CB5E5F32FC3B4A2DAB2BA080F9A7CDD0B611742A8F83CEE1B091E629D2A0371FDB5A64412B5FA63716961527640D02885C4A09B04A3A6F5EC01A9E0DBB8FC4DDD9E05BDB240AC4878F0D41461C4661777417D6150422FEAB6A39F156CADB5F5D3BEBE417BABCEFF5AAD1B7A624FC23ABE28B2AB2E8273E8F44636A60CDAD9236DCB02FCF87722C899AA321C564B25BC33B4976BC9603BB8B8AB18B5B04625981FB38B2A42722CE2358FC0BA99EF4B122C7B70BB347D0D482DA30638EF8B9C1D9121D83BCDBBEB2A608617054F4B3FDD33E9A08F8DF999A98E715DBF04F8EFACF123BBEB37B9038E9AD906E3C570BB398C10E6D36647A2B0B2731FD39F726171EFC7321BC67D936F7989EA58336E549A34B73F097E3EA2C25887EC6A2E9FED5D2CFF475E99F392162D959DE1C4A4DAD3C96542756AEC3367F7B2515F2225BF7B704B780A6D0B279B8B4EE4879A9BBB2F3303216CBADEA00D229C03E3E2843892FA8E5B0A600D0E3EBDD14FA229819CE9C10B8D5F393DE0119A5B509B80D56B06783447F931177123824910C9BFDE9A29FBA0252E69A90B3E717832866115C06EA73B033EC3B0D45DFDB69A76B484DB0BE7A81215B3817E1C02F9A5DEE8967B147DF9F63C93A6E396DE4251A5A706DFDE9670B8B2F6C4C3E2509142256FDDA905C125FBBB294EB29A3B4D9BE3B67762AFC049B96B3F41B8C31BC5D7B522DCD1AD12B252370A8A57E42F6A9AC26FF784B374DA4B86FFDB65CC753CD049F1A21CF832447E1DF7BA7D0D11E403FC18BC545501E16568595AEB6BD7811C214CF2FB1CDFB07BB32321F536E3896B6EF4D16130ADD71B271CD1027E35538D9E475A3A53DFEA430C151DF7D516CD0D9B""") +b51200c43aff424af193d24559a9be52ec5a72f4cf45eb15f8d4deef3c3d80bc9d0c433e595f4a3f796cfa7a4f23eb5f8bc60b3124be513d7e5bcbf4fe34b8a97fc1a434acd645e4306d3c2e07473e321434ce4358ae05e1efd9c6fc50b7e46cc228c782472b52493287046cf91e202fd997e67a75e50ca3843ac1790fe02d2c0ea71dcac6d65969022ad8f9d832e8a7f1b872b97be28ff9f4519e705adcd341fcb021cddab2de4ea394decb80ce66ebff3b3734482d1acbf57fe6d4f548e81e831ef1eb854a6e05e1e05863a4dbc9f69351c4b7ea3ad95bcf64521bfbf337bd9c590f0c5354638f42cfbfa2cc31a5312aa208e2056ff61204374aef66943e96e2b9585a3245ef2c7b909fc5ffaff94ce682ede6a377fd71746e5410b1e6471b8f075f848e427438ac2138f9e24b10b0a7cbea823d6ee74cddb33ea9e92f81d5dceef0700eee3ab0ff8d97cd3334523d1fb7ec8b3b594a5a0d6dabb2b003a9bf156668b8c4881c9b9d23987262957ad351b9e576ce59416b2936877823bcdeef302ee78a74e8f8fa7adeb7615dc43eec2fcb5e8f328f7a865bc036ba9ce0f8f35257a9f78969dca4efda0617403c8767b97df223a2d40bbcc378f41f7ec4fa0425c04f61b976c0822185319a924808191f6f719f006c856a4f35b97f7fe64639dd7ce5916ecc5dfdef2dacbd0c95589c51d28e93099201bffc80e146e4d5d8f6db0ca7d26814f682de0a5bd2511acda58dbec969df0cdf826b957c69f1cfe409280f63cdbe0794c7c5a0593cca1b0f85129940d553bbc2f29d09a3c6c364d396a39decb13d29e9c649eba58c67f080396dfbd21cc83bbbbcf68c87ce2819cd12b10d7511ff6f73cc58f16eb72e2d689fe9a0e24ab338b034a7d0368f4750c30b9793202180c499db4e92c34803f94d2f2c9bec1e8bd7830f16f77102781c4555f9908c4c41caf3d62b2912bce732a83dc92a70b21a3dc173ce1ef3aff1f69f415ad749affde5e97ddbf7ca79fe3f0411826505a718a237eb81af0d8c4f09548dd37830ef49c34449d29e191a4f0b98cee0dad5ceec6b87707f8cceb2b886b33f7008eaf93243ea0ac326399dce281dd275d2555861e6c5f04c7b480dd563e3684585c73e28fad560950dc111d9444bc7e2ba960cbfc914e81b7844af5c290adcdff7840bd545db2d9318f2fad141e531ee95638b507b94f7dc7c0056dc56c614b06cd3639d6edcd21567dd810c252214a7a9405aebe8a19a703a9aadf60aaa44821d2e54038f9dde2bfb580aefa1bc595619678b5a98942d8f6284fa54726fc22912efd39d58d71aa6e5671125f51a23290e3aae9f3a3edb2a37daf9aebf4b278e5c7bf70881f093b64209dbd943d76a60018445496725d40d6eb37f2ae27fd706569bd467364b7fe89a944cf08dd3091a914b0bf36e6204c798dc98ef3ef0e395bb2f855f2cd1f6be7554c9402ee190100048d69827dea7b33d5433bccf14a0f1d40866f35e2474bb9d374b526353f80711bc76d9b29ff0e2418686a40a3b19""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +966853f02206fc71828a50115622706162598f8a876df00138caa8211c4d023a22127a0d611bb3800059eb2cb9a23b6f03510ec9f064067b39418c9d806a7de70b9e9b5acaca2b9a279797ca347c9035716ea92141340672d52b19689b7f025d9493323ba034511a4bbbc78ff0fc915baa9fe01078e0b511a4127a744a7fd04c4ae3d84212146e7c529ced97660aa49dc5b0a0d9560029c2a9eeb11f4943a5f80a4f2517cef8a91a3f9a0613f99558c43870e80b23d01fd720930f616943e15d6b8458a4e51fb5d784a0b35588d19eaf088dd04aa6564a038fc8219d81adb9091bda455058276655fc3d21902ad257426d25436ea6621709bc6647949123486b642a13f51b17f5545f61c66e095b2bd938d6825ef8427e0dc13bfe2ba0e61305b477a9aac566e86411d06b4304f6a3c4092a9a845a0700b722e1af1db3cecec69879fa29db9997db1836fd6766772b93a1d713c93667a6f2495425bebaa4a91c500151f2abb1d6443e1676f294b9cb261103ca3761da75dc718c5fda2a8203c4231356fa03be4016a9d6a24a2b04418c279a94911bce16507e450c3da684941a4a1ecc2fa8f39996c185af609e0867c24bb42cb428049497012180a942f81180c3a87480524b22b6a4dc5b6c5112c3289ebc819ab6ea7302e835dfebc525531b6bc80a84a196df896106d73b63020bbe794adfd08ad6cb0429dc3ac0f11bbd3c5d9dfb6c736386842303b15246d9a57df7d2971e169a2611bf179432a6462d5c9303fae68790a4769ab58c3cf670d6847240549ceb78432f63b3c4632d18f9a15f42532648794d056a138788eba86c1f71286f06979621a41d866765a5726f5ca0976268f505c92c01aea855a32f74c4f05454ed1b232803afaa672a0f841d0fb0824a512dd98c8adfd06269c92b71880aee691fc546b2e6c0c99ee18c41db8fd3aa3108a48c4f60b2698b501b8a39629cb1b3b027ec00c9f181bf38c25767419e6bfa4a2de982f5952396ba076b0b0b0e891fe041a5d7235f8ffa573595b02c550e2df02ff6c9a78707565cb5be1d5234a45b9a9d250679d5cadad2638f9706a8dc558029a9602c6638f366333ab989817ad64860151442acc4083d991867a65915a52b74409344498bca11433cbac3a82458c0ea647d8b9a7db51023a8b6b5e3356ffa3fd6d3ca7b0466518a4f8cc78f6dab6d33a6cc3cdb8aa1acafcff9cb22b3090561179f9aa777b3b6272c9f45f1cfb848b7840a020b51a7a017be69660997ccb96096cd1a92b55a4c5d1a831e2734b11ee46c16128123480b03e714cbbb632ce487e4a906a358a6f5bc14e4e92039575a43f7b96d46711aca37207439e3531a5d877ba1d60bfb8a0d58247727e7212db9410ad6ce66ec3def428d644b15a497bb81954a53bb95d2e51f2e7559c165c61713453959a51319bdc4138aba87149341cb4b114a22150133924fd5544749141a9abc5cc3336f89834119250a1a537718301fd25888e2b78efd3b0c6f42c9ef3524780049ea4609478333c5d386550b9ffad18f24520158330eaaa7110fe649e1aca827f16cac8b73105bbefe23c48752cc1ff65f4913616bab71458122e2dc0a24e54137c5737cfc0d9aa743cb8ccd08dca5a5e735178993710821454608015b34746800c7f8679d72b0c628757756a50a61186c553febf79c00430bd0709e3741886ee10667aa7f7e4c91d89820e66ca9bbfb029f5cba016b6240e2bfac3815afd613a13b04810a26559a60f6628308fc45238269c77428aa370418f11928d5b3c211cca7bba2de57898e132035a16a8ee780678b213917c725ba8dd1818428199c672b20ac05061a82246e3b55bfea529ba891da6320412108ef0ca184b44736dcb05990031f3496bfc96c50445040e27df4fa2c28205e1d9090034285912b199b909efd088cf4ea4241f5c3052050aff92be505a355b515e5d4ac55b859d5a3cb1a42564d398ef4cb91db1430a7da96f9e96cfa27cfb12664f9f694a36b211a7a79b46c70e0ea14219c119006bd287467c780b7e6e706dc30b230b20c3f8759f2b2326d8422b16c124ad4a8e031412efb450f881302448e26f383fe01d0b26770384638ee1aa51df773fce34a9dd00ca24c584f5512c108109bb9499922019381022a58c4494241b2b62da8ea0b784967d86c7d8fc5c6a8f6055865173854c38d6b407b3199cb44000aa90253d7790011a9d4551d66278d559808835208caf18cb31642b06164558b06fc615953bb1c5fec2600975dfab48e9123b0f3d8757f53555177766e819f9c5487c9700adfc917e5782c82c681ad8105d6427785c862201140c5919addec3f10574617201e4e35372d472f782388c707406d73b462f25e3ac846bf7274a721b1a05c36981093c3a853996552c85b4a90e0c796c790dd881fb255557e0731eaf8aa9747b0fbc64f2db3a7667a11b6c7718200367dd86f0690be472b5a2fa4b914f91622b78be310719ecb81d1eb8b6c76bc4df0116f84179654794b39832701911480601c77229bdb571c1110387a78d4510dc0705d66e189e1f80bf7e5c4952c083693c6908623be31b1d2c63eaec178c3523110ba13bdba64e6903df028a23167594a12b64de601c90b41231a29eb5c2ba2475b09091f8389363030ae56fc686d024a1f838a0fca5914941f72470ac5052b8863aee631a3206c9f79dc479c925d906c86d3e5797eb2ba45499690b3799ce39cc65a9887eb5785c1a6ed660502d85f5b169ace240aa6c492f9bba48c61c81f0722f8377263a33087814dd51070012a103a93160359c3c2a945933c081409cca0963e99883dd27cc2572683881c189861ab10e17e400b5da3d40983821b4c45aad97aadd35b6d7296cf2ba029981182f5a1b189668711d528de7c7b07a71a47056074066193936437016b5afa3fcb245c05764af1d77681325c0fc2bfd2a74f1490c704e216d18345a1e074dd440b730a0464db2bc5852caeec23c0bb0d754cadf8f050ada71d85061d18a6138d8b70f77aaf45aa25ba65c643f6103390168629bcaa10577070bad8119619320762486e9e340d43a04bbb408ab86801ef55647e43cf88a6c0772b8d5f274f1c12593b07bbad80ce3bf1903f24c6dc976cb8c08d2411bffb92221deacc5f2783b6d38078f51d42eb5ff1a6b78a5899f044ad4d57c582a72844a98e9d1bacd4c081abb44117d20a3fd3b18352a1f2943c29d0a4832a8eb4b22cf69030def765bc527aae51010c74cca53b8df382df9ec3e8d9d492fb165aa4df3ee6a45fc8a9953ae56be2651a7ba8719c565e02579ec454f32be2888fd5dd95ac20b8079a1567b365865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"""), xeh(""" -8FFBC80E4662864D6F373DC8837AA91B3CC26B68124ABD73DAD025A1D1C18829DCF077D303579E5F39F4BE101BB9E355DFB5323882EACB3D184E6812C03A7BEBE25166D55F821A00F80B8D2BAB1A7EEC83D384AFDF30F6BBC9960C4662067EF7E200E37268B9F5348FF484642799258B45E541101A21FDD6FBFAA2374A28FAA97204953B95BBD1BB519785210DA7C8A09D071D8AFC9B29F2C3C2909A4C53671408B8083BCF5AE03D45C0CFBA399F44D24A06321BB74F6863B7D4BF0BFE73C8AF8EE1DDA45212E3F9C853D4D0E16F8EBDB8581C4ADEEE833D81A9E0A9E8587E9C19E689E6DF715564BCE27CFA73BA16226A77CE44DC496992F41AB918643C6D86A8B26ABA6F94F3502D22DD94FE55483F67C635B307745D33F17133293639118E70CE42C6DB7332D4862C73D5B84415454AD51F89B5559B5C85D6B6ED47B6958F21FBC2ADF8C8A9D43FD2E1B0C02418D227B83F85CBC3A81C719E8602781AE71E15E6D714919E52FCCCFD9A68B4751825BFBB53B7940B15B546158DBBC612E602F660B9E0FF439E0156C4C8792346014BA1B4838C7425AB34744DE51D854CBBA58B7E67E014122518036CE1541A1675AFEAE4F29A5318602ABBD0A1540F33176C984E306098DBD08E822ABB55F9FF38D9E31EA4695150F2CB60BC2EB5F4780CBEBB210CF48662C454C7A42360F306FB03617C998AD8A9297D6B71A71285F7AE8DFB336FA922540C92DC71F777D3B4D11D87B8D082FA8A00DF647CF7FEB27403D3CF50D829EEE3575A01E2CCA57849B11B14F001BE180DD5FA13C03B98EDEA6358C5AB30A526027CB45E33E646B37988CC84B979CC5CFC3BFDA05BD2C7B8CB1B11AFEE007E20FCCF8D0F764F4A6D2F6A8B74281800CBDCBBCF0DF1EC9D27E6A94968604D9EFD37928B6856C48F0108155595D03231DFC22DC0C8EE614090F37E0828B48A4DD371C677B5DBA95E417F12C9A396875FB05623F7A544AEAE41A0AA536FB8D767BA2E14752C84E147149F655AE7B903CAA591AE00267ADD3EA816612AB0B9A5FB263C70C4367062F7794274C75AC66F706AE93699859D55B2E4960E9D538F38A2FAEE366B80DC78BB673A9E1B057D711F9DDB3770947E6DD7BCFB425B96670506758AEA39A5ECB33A1B76B822AF903787DA3B61A7B9263C0FAE1B729B1A2E16FEB50C32A8728181D4E8A9F8376C39F6AABC2C022306B05E494CF9B6ADEEEC95887440508981D6A74707FCEFA24B9F0DC3AABC984E9C44174E6DFB51FCF4588C57F9659A8E7A6FAEAFBAE7ABE4600444936B3763463D4AE411DDC1C98585E0DE58867251079BE72075973275141801B98F7B9397C096A56B8CD83CFBD374E182F7DCC9A7C764DBBF4D7576A1CC9239848E7295D29CF034A1A7AE33A386C3DDC24A535168ED23D7ADE9433B50DC5694C969F4C546EF2293CD842F4B62B6B7435F597CF5C1733884E0A6AA47FA31887DEDC6C402D8ED013E49E5CAD7718CCEFEE0E6A041715CC9ADD79965413049ABCE88636AA7543EE2601F162838EF6B""") +ddf623ebb88ef5e69f87faaf620a10bed3440299b2c788981fd5f782671a5d2db99576baa8455f70250ded987e3e94d9822bad551c86346af95b86a4e0143da4a4ee58b66b289c37e1180b14a2594dbdb1fc468964375d466229c95182dd5d02b85b75b9eb413ba4e04a927798eaff56362d804fad7534ea1f2bfdb3c73cfe4b3c04406a425a3d94b71617100493f9ecfbfc9101a1c63b9d6cb991aee3e94983b4f162ce01a151658c49a465f01a5dd9b7a888e55480de880cefff5151086557c1665e818d9ca4e0b50859f8020a6023fb8039cdcfb1e8951c5ee63f2bb1be2076bd35462a7cd225c1c8b299ef2f394714aedb8e37c21a1ba751633fb94c745ef30f6a3a13d8023311a5602e5fe23ac7d652213a1d8ac19ea24022b2502f982f45fe0261679fea76d0ec9b988080e7dd018e7cce9c0ec7ca496daa1a11d86f9cfc9df15e2924b585fbcfeb5bc2ce2d66cd7cf2ab3aee35b26e1c17dfdb6da77cc464f454d91595fc82d53d7148333d9cf8d3bc7528108c635a960be9b5d243d4423f2692c41c441b4d0f52eb4a170707b8004fe323548bd9f4aa8aa608a5e2e39ac77495f62511223c9d5615ed888c73250a513e07f6c0867bcd84561ccfc2f7684c655a1104dd59347b6e0ae57496d45a93576b1b5e7469914eb924f5a391da1fea99f8f42343bc85957529b41bc8d12010ae1338b142fda8bcb0e6249fe47ec6217027f60b27a45b7da221038569f7ef6b8d5669e71af465f0c373695e2dc699697d07bab7a28ec7438b3ece4126f549dd3ebfc181ea6e13f31024a226d499b69f8f41f1b2c66643c0d8a3051e3ec97e52573aeead5c3fd2f762e0205af6418f2cc10086cb9aed95a413687f20683ce21b02c695dac6a079768982183beb0fbf92d65e28c6bb9ea294a2cab22497efb34a1bb8979fdb36fe968985b26f4567bbf103be28f02b1f709d3dcade83349be35d3771355f541b48745d86a3d04a9ff9e8e2742e4874861eae4efd2ffcd966855864cf212145365f003e0c95564e36476e69371ce9ac72056936ebddaa41c8ef74e341de5400988bfed7b06566980419b355d9088313d1610c4cc5872406dfd5bab0d2e6842fa7a6d9935b1b9bd4bc543689123a1cdde023a3606a79809909873175eed8580f4c5a987cda884551e90cea3ce850c689fff7fe7c43577a2b09ef4c864f83b1c52641b81625208fb47029138c6dac1af70c92a391dbb1e80996012151aee86bc7e4039941e3149d3ca3709858b18c77eeef230b5482d3399baaa7862197c0d82af8be727763583a3964dd5ca88a11804fcad1d9a6f86901ee78a7482f6bb47fa33aa21288bf27eb60d92e5e9d64bd5440dddf8b4ab9836a42e027a8d96e999661a888d08e816a5d217f4b94543868f56b3e5a9c348204277090fd4d3175d72f1ea2cb51693e6a29c808fb2d518f206a49198504d44b71285701d70ca36fa695023e6c1d79dcd761d1941996d7f7f099471b30e9f5448f7322b44977dcfcd7a56491144f57233f26e613""") ), new DecapsulateTestCase( xeh(""" -1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), +89cbb4263b87fb3abd58177936748efc870d2fdc7f1ef00a58ba3a607b5ee49cb69de049b5d88f29503afb655ba6b844bd991ef17c13277594e3082c8c7342733447530617d6e9b5c2013fb33a4b7a20618e078ebc046e841547f6093746f8b79a987c31fc341172a1b6768ded603d11f52ed9a399c9b23aa984b0f3995545196e7e0080ad6c884a5cbb120cb1db4aa729b6ab1a0849fd24b8e178124a7921ea357944d35b778b823c10cf3da46562fabc7ca28b5cb8b6f295417cecbb6ba4885e08a9032460558a0364a1c3e2a749f2da4dd7eaa76347414fa868f7819bf5d91650969fec1a4c5b01c0df820bc63cb6d391086d49741c84bc28aaaae11a29141204b025a4bf867f259749ec99043c520c1ca46e73c2aa12f9a4a6f009f5a5557c60c1fccb148e0c8080e9aa685212ce6108689618e718278b48222bc59ed4a4b541a8c0e4fa8e383303d8677156607a3281b2b2f7979fe22ba62742c8c734d17b159ce0552e713f7eab01821a0b71aa6a418a4381f572abcbce44e586431cb45f0b933d1c75299c041fd50a97f030ade1ac46e07bafebb6a98c7414e13a99467adcba6390379206441e1027012d967eaf747ebe6428f7518236e34a8c37ca0e92648b10be47bbad8c28b49cd93340e8180064b2e0362439824e332c379c3003bcc69018329e4a657b75f2b1ccf26b24207a008d04dcaca70993332808014c355013d492a52a879f1bc784bc354c30b4523a590c652d4083b532c79e8c4a554f052cb3ab43abd734f8d920de834ced2692c8310c8ac229b04aa6b533b2c3abadaaaa65e3794bacccbdd39cb2b6d47ac7aaa266a2145d054fd30c9612c451bc0a5ec7a3b10dac389005b27b6b7f99e7766f813823b36b797cad73c71f83229ad6ab46e1224d80aa0bc42b2cd0b66a3c322f4a35a6544b3132c9aaaf2311480c86d2393ee2544a329192c1f3201e082fb94b5484907600516a05b7b9a8c26d3452bcf8b1cda0331adbf713ff023af0132010ec3f810c85492a7341c0294c81773469c2da3a74f0e9ab46d45028823e83aa016d57cece757dc7461a88b688a8e97ff756afdc291b8d755ca1536a355a571e721c042472f87b4b32a31423f2c7ef896658296f1b520cd515acd01ba6f7c1b34aeac799441ed54a6232172306c3c0b51220dff0391a1526cbeb64bca256f5919eb8b7655b142e36e95b8a479e7f596d481aaddfd653ad7922dc988333ca77bfa1bbd49966c25775211332a81194b452297cc2a8c8f7b9a2d013eda34d4f5bc7d9213d7cb721fe18b532757bad4229585527ff202240ea09eca0740656b189b82a68c75a82065b40e127842059453447f4b144f002a01d69c7f7f62c8104346067ca6b899bd04c075fec6a462a0735a54d36541f3b556e4f0189ca8c8b2a366799e1a72661851635250b4317f0da80ed014283f4132896974578b4b3f2b0870bab58c3acafe84737aaa8a614533b61b471e10cf02c87b88c940f5620c4e81542041f8971ae6880a71bac55064a4a91a2347e020be3e81158997e07d32d80d8b47fc52b19cb8e84e09f08d14da2459934bb5adcbc7b6ce833e0da95ccc2266343257e124e3861b8041288b148c1aa8c5c2689044d7cb15005ad5928aed39889c195c94ab0366f91910658388798b53c6028343664f5ec4601d4acef04d0b6f2460e75bbf32405a512ab2474b8da27acf70bbfadfcc21db84ea0b73b548066d4e4618a355f9c051b8b54977c3544bc7151e4ba1710e9a00e86a46d1149620c291d3673adc5101499301296cefdc04bfd5ba5d136ccc845b4e69c629d1086e94b622054c5fd662952345b48d988e4b7198f298ef6a925fa1a3f912ccad5b46eddc861e69130424a8d952110f5820c776a0af58c7aaf14922466ceca0aac3bf1261bc73df001bb7a081a9440c80453b8ea8b06e22689127cc9b2ea3d8e5c2bf8b25eef8841a527729dbca2ab815baff343aa74b4b07c06d5158e820c1fc440a86d44826c754a7e3b05d40c1cbf32206971c133c80f8f678d3c30ab99db0656f4ae9ca12ca4fa132265232bca7569c8624730b234065196d773a290a3633605166161d86bb169981c956394aa602d5ad37cc8d800a8770bafa1667b04ab37a668acc268394705e679594445bf0a7987b86cc8c8f48e180279a193a187025648b22f53d9ac5d8b8a760978181a9755e3195754530b907ce992b939fb3740e626ad5534256bb7dd538c6bd2296d5675567c2277552c52930401fa09b581b87c18c70ac8a4076c9ed8dc001478757f01ae8ad3adf49a6ab590a61fb2c5c8645076e78c58740aad2990cf3858e27ab151f797165550b1f4a0fa9b7d47a8c4dc47bb53b359742aa486ab776b3a7582459f229b969038379099c428c53c1486cb23911f50108032796e46ea04842b28a84373332287db410390563c2271be2ff14065f22b7ea32a284cc3d0654ec6ebcbd6412d2f5c29b3720182350b82b8b65fc57de3d90c0cb55455527a469097d913331a7a0cca8692200bb9711008fe5549c945b306fc48f58b8abd835dd339797b9c508bcc8e8d76a32d560cdbf7506b1c2d32fc35170347b71a3f456163bf3116794324a46651f359bfdb4a65cfb754ea47064a2336f85bb82f2947b9fa164e11a55ca10086ec5af899bf9f7a3c5130a9c4880412946ea6ac478258a67c58131df3b7338933b77c064bc9231a49330a1a7c85e864b17c56501697b3e22b1fc468261b8eb8f4b0c6703d6a1ab764496a6eb27f804631071962c4a8062203148cba5acf2226b74b66fb305ea88040f22779a5f3486574a7a2833cecc69af95c64348288bb1925abd5be25878d9585c540134eb2046d7bfc5fe16581677421c1b59f1c69a7717744ab87902480ad1f697cb7f66286c43b73702f42720840d598c3917f25da324e5aca224a9ccd9757e91b2dda2186d56ab2191b46c950c54e7c570a3a0d7805096a4718b57bcaaca5cd6fb1a6e1272ca1ac7fd9ea9cc72440400bb0a35abed71c3ff0b9855058891555c713783386bc591a9663e61bb9bf8055283c2488e198a6e991fcbaadc7885f25295b3d531920d880213b410c1763aee1beebe665abc1ab64c6ab3cdb95555004c40148a8530c22b06341c301f301970f51479199c785a4c616813e6e41bd8fe078a019a33af92df22b207b09972a60443a39bd11c5c38de24770f3a29588abca32283650a0587434b74bcbe6a7bd6d70bfc581848c9b2ecd6184a0623c75c1768e0f3948eae08ad7e7fdfa17684a3c63b6a10dbcfd6213163b473bc3d8caf0196f53711e7354f6151a7a2235bfca5f2c1b1d6ac7b65ca6741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541"""), xeh(""" -17976BAC62F66CEF2B6F947C121079B6F2E9350C137E738BFD884FF2BA6E211640A30FBF2695EDF7046E1F5234AB1C8A9B0E8A3FF88EF18C1E5512D5F69E4A36CC9362F00920481E5460B1FB0C2B9FF0CD0D95718966AF7EC1F76B8DA93F6AB179A5DE70DEE34C579E284AE8504ED96E1A85898076F69AAFEC1357533EBB636FBA2372204DAB87C47AF27D4D9EB1B4FF4286D6A9FA7FD506C9FEBA596D2047DB765C1EBF1F7921867D394487F6BE926E6B0323058CB591195436ECC805C8B88615C7A03833AABF490337063DFEED698F7DA8DD589A794C956C2BF8D8CA4AE18B0A7767693802BD6DD53F543E105EC526C1D1D00AC9C0B606BD9B3A1D52CB8C56F8535ECADD8239308F2FE7E1D7BFAC5848B547B4579AFC13A0B2BEDEFA46322F92E2B73980695369C5F48D37F9345F20C7820DB6DE09D5E8313B73ED705B33646FB14CC4D40D65290A4C27360FBBD080E61A16BB15E9560A097E4AEC16F8B8030FAE1D47E024F10C33E6A1C56AEB8EC2F6AD6EF4B8FF04C67307B23E470FB3E5BCB6F533F955C36FDB46516A07DFF2956130AD0924158CC2A083378FB9AE32DE89CF774D82C2FC70DA48536372299C61927A5AE67E55E792B64FE61F06EFFC1F216CC9D739ADBF3B2190E1D080E00F169F145FE32AF7EC7CBA1D76FA6839D5FD2068E1DFFF557755FF2F4271204A5468C79C7BB8D00FAD63938F12D53B243B3FF866556913EB57AD2AE034F8B62B1A1B9DA2B1D45800B4CEF1E1943A0C92F0EF2EE924F80CF67EBD3D0199D45ED4DCC00140829A0992DB43616CC468508B852EB822066A05CC91D6BC2B47E5622B774F8128ECBBB94CADD15588B36A71E9FD97B05D69E8BAF00D30A3D3C00E663E00AFC9F5E1BAC8534ED5F6E5AB47D7EFDF6537753408299A9E8D5F5AE0FE36A9EC41C6DC9F78A891BFA9C8E90AA1A457A0C01AF70CBC9E55B68A5D8CC5CD3BD6886AE11FF510C6ED0EB2F5C081B25989518BA217BC1C153864E5BB312EF0D43D6DA4A0FDE44F1157CD238E8D70BEB420BD310F8E5DB9D74EF4EC9980CBA74358FC77C5D4FAE3036E176647D78C73900C79BFBF0BC545ABF7CBB4DC7F6041D4FA3B66E4D4655E24B11DC30B0061C452A605CE73362F2A3F052370D873FC68DFFCD3999FDEDB45DD9F2A02B4699BCF1FC5F888B019B5028465F30AEFAD946D481285D1122EA78F3BD8B1982558C38FA3DF0F058B12EEBB11F4C7809F6334EA1D7FE0B529C0BC9C67044648178D2AE9232E4E88DD6D0016D8A590B7703F1A017A4A2671BBB24FA97ADE1B61C489AFE9B3E63CF4CCC42168C98880921C2C0EA7D24DB6DD676B77F7B6C0525C8D0578C7F5A20DBF2F82873904D7CF2522CE6360397B254B18C3059A4BEA169A44D9BA17CFDA1827EABECD269FD391CBC0D49D71FA81AC16F9A0DED9E72A58D1BC2262979D8D7E531D1C46A8F107BDA18A1D2CCD17334183DD3E79D905ACA7DAD348BC6D5CE124A1397EB3B89BE7580720B5DD00BD3A63DAD813E0E967EFEDF17F3D960E70A4F83F""") +04ca3f0c74332cf9356674d23c5a99177a03dadb1763b9cd6ab7804cd81cc84d079ef30cd3e536f0d6b119629f6c6afe1a982abf3f5738a1f686883766fd009b393c556f92e90cfe6ffa41439bffe299c162051231c6439d83d6b542204c532c4bb997247e18b85b467c3f19d6f583ecda477268ef89a9512daaa80533e19fa7fa5146a0f23d17df32afd12cbe17f93ce23d9f8d2b9a1f9b6a2f3b7413c0245df5d243b632e95d7f6d16d6324c594a989953ebd02e491e61c0b0e31f33659c57c3fbfbbce1d9fb20ad217d3236dd9418723a3799d7cd1bf119d2cf0dd2044ea2ef490a4e5d432e467cc5bf7a8340a2769184ea1782487f2fa91352b82a787955e35c156d5ab42d57aa1dcbc032634cf53dc4a64d080f057b023d453b34f179fd685d9fa6d57760d56e91b773295c10b90ddc4ff84d4228e55eb51654d8c0bffc2a4574d80a45d6d48ca8bf1825b46b16afe264dfff1d1c75c7ca83cc40df842f8c5db6aa3f92e74bd1dd5db25d8370ca1d25f5bed0c8db2223c75e43fd245be2088b3d9f25c8742f356a5abdd43328884835d135781db0393262d7e3fd859ca637ff54d833c03381d2e4b8ea9390d720b94f014f09ec691d07f77f2bb7eb792e45155548f4ac8da20540007c83ad66ccb403f9f93d7cab15a5203e4d0852c07f0c350f2da9f4477482777c14ff9f79db9d6e41a42c39631705c2307d26e54fab94aa002a5d1eb7376025133e737a93e88427fe3c3ac651cde934bd7a13f65a5af6de7e8d687c95207942af7b2c7d4a5dc1ecca1c61893f461f8744a76f45546a0ab023f7c07191be7ab9e3cb18b0e2ae1e3ab485966b2f93384ab93e331bfb7f7e65aeb7e0a6299f7b4ab81e25d95ed51502b9cb8d7ae752459d0164700cfc0f983d1a4f28b41b1e279dc71996b77b53f8e2bf67dfd7efa14886e43dc327793ce965018367973108056ced3ee94cd4aff4ee43d1b720ecf57097b0296e14433c2636c8d08c5fd37a1624d6b90309f93ef1d0b7de7e140694865b1f31c1cf4a972839a3e6462c053209498834cf5cf34d7b45b174ed86019371bbfd1a7415951d05fe7ab3bf59e25a67e5bcd72ec9206d6da4677fbbae005fa465fb0a55683b47d07bab6537c276477d0b660ab92a003d55bc8e645145e93ab0eef825475f7d53b173aa45fb6975cfe46c28c76fae8d0b70640467cef9256fb1755ae34c280f83c2898e908eb0d8680e25d982448f2e044543751daab8d7cdf2525c9d3f1fa96b7828d0ebb59785056c0b27b2f396e410df72291342e5bdf91f73b865a64a519aa0196997066e5cdc29cf2af335585fee2b6ba6eb3fc2bd57bd1cc4a2b27dd291a3f1296e7074b8f58204c0b62a4e016ebae22319f7ce4e147a4823bf70e5724c97d0b5441fca2e33831fec1cf2c34a95f2c6b78c6f714035b0f9d50e1fcb2549bb621de83581a498a79c1fe5d44288ff57c80245d5350e5af2b20d9983f4613ec85114c6c5afd3cc3272ef984ede02ba3fccf9315f8cb9f586ec036e68b8aa73""") ) }; static DecapsulateTestCase[] decap1024TestCases = new DecapsulateTestCase[] { new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +63d3868f4a29b1b1a87dfbb469d278ebbb928f612c1cfca80174a1d19396fe53cf33a8c1f1a88478c667e784567f43794aac9d135293bd754efd504f7b668f8a55bc51054573c95940a977a26255c0188456e2a1d110538939227711180dd36cad815221e47e8e8a48e61c7596b019d2b84e8995c3c7c9c690008207d78cb5640e428c36e92a67a6eab32e2164e35730eababa199743a4297f81b471961076474080ff6735c2e8cbd43138c3710e002829a7a5bc3efb9854c25d318657889940f58259b6466ec1b823a5d7aa835b76dd232f3ec9979005cc15ca84568785207963e476a93e585933129d25488c02d822093480e06b7459739fcecc65fea4b88ca58af5588ed577cbf15270003c0e02bb082dac7d84a19dc24137f7650e0a43c7ad064043e02fd73b1ac3460cba0b5948c0192d3851c36105144026d6a5a16ddb7fc963ca91800aee7b96ce04786780971359aa6862b6ecbabd74b5729510714867c77df98d3097b33c62b0dc7bccce1b10d0a518f1a2652c01609a3958ed95414c73b2a8b6307805504b6cbc5603649ca60e24672b4fe4bf88a3cf82909f13e2725094ce628ca2c0f48f91448a1db937653c4472d21107450926505dbb79742d38391d254703c2ba2279b522dc6f27523c8e6c193ab16d8c188dd5d452d5700310e22dac04bd3d98778923931758645098a71e4388cb5891b03b37f0ccb33fa75e3fac3627ec58310b4a6600c0b3c15bdc25c24ee245969264213c42efc96e09a9989515a632eb33e3692ca7fa67fb1319e7d82ba4708aaf611c6f4818a3798b7c27b828a57a4e2a49b8115be8002a420bc48d353a27411774341891021037d72a5940b8a41b5859aca1b142a80f26722d65588a1cc6e5a97be59cb116c6b8d4e88bd7d6061c6cb4f877cdba907abde86b5c2c73cd03382a50ac1debc15200a7a9d45b7f87ad046ba2d347a2ad899d51e73c48560f42b989d1d92ce9193ffb746a808145655028e392024673a8186c3e8bb63b30dcbf2302998591435bf534a19779683898a7a28d015b5aff84c229cc4f8784b198b25a47e0b1d2e3cc065b8c4a108c4bb64612da64db905e88b13e4f0b18f9f133452229bc02ad9049a8fe44b16581137684b3fd081dabdb389d663097f405eb2378112b2ef9751f8fa4ce6464220c1a8ebaf91ab5b3736cb465f9e4c9a4720ccf6338cca11d786725e7203770ba5e1111a84b75048c9399a94c014ffb8d2f5c516b4638a06067a5138265c98861ba50038804f7505b198c4a2775cdce2623100b8b92d489290b076c5a5566c62a969b4717124e8cd220ccd05d7977b2db0534a958183285cbcf1a6665cc2ce7d1193e16288ae06810640da7665cde163e20008659da76aae4c1ab787984704c6eb28d5b5078b971aebd77b20793117ca55671267c511480401a0a2285577ea36815d39a41d23537648f9eba50603a2360b2ce98952c34b2250dc876c5bbb7fed6708fa7cddcb15f732a77524001c972cb7533b9ab9c8f5a894d5a9c336b0c942249a39c039a59e789df2a6474610d9fc2bc4826cbf8812b90f5317359678ac78b6818b5b744b35773aedd3585aae724863818de706b05272459ca6ced128092d1b016fc76594461185c27a0433d2c7b36e807bec3fc527267a76d9a58edf3ccae8c251ba71517aac370902ec3f3600d5b995ca1b7b2a6ad833107b39ba6db71bf3d025a5fc81acfca9b465909740ba18df95a342a26f5437453fc0826209ce13c69b7b988f5d1a68fd484a2b1854a62ad09d96d6dd37795e29e83f9501aa21a89a31994b34a9131b65a2ab13d142c6099aff44b34d9a62905ea883102881f380c2bfb5e357040a29b7a2d1b039fe35aaad9936246cba4fc84af5066ae1c5cd7371bd1bb305d18873472b969e3727f17bb6feba5191680612822ccd96734b549f0c193c2fc0e496067ae05c75f9c39537533b07c297b463fc1e25fdec2526b30adf908bc8fe125092166939ba8257b33dee403b0d53f766b384a2a3503e9ca43f042d289bf2414b276657671a5c8c9f3a924c26286624f0e99cf413914cfeb4995994d082a6ea3020ca97a52ada836bcb28b53239724d712f690122591a7b1d7261ab798f644cf58076d75c39384f3433eb1b99e3b3a2d190492b5398bb9144f31c22cb34ef4a51478c635302525fc0abfd221ca8b3a6e224338bb0b9116ba54cd581cb7a3813c878d65317d8736881c8a6b6a7030441b44dc6663a6919c7a3574463b706105c332693d1918682d2a0f2e12b1a545a8aca6a38f0b63a216463099558d282dee3c33af3bc160d48b889a9d80e9cb6d83786dd826cf2c58c23c87f0279359026458040ae638c3eb5c5e0f7b6ff2e76ea598bac5143941d50d031a4906bcbc826a364d92641f68cd1b43973fe9b802f778963515cdd47eba329fe6b50c8bc5bf6d3aa02e69965693997afbae7e2c8f06b85435403c827a39d63c8cbc675d4fc31a5a699a0f2381918448a4471eb5aabb24c0685e6a1ce042553c360190ec470b44a7cebc153186be0d8c8996a9b3bf46383aac698758ca7c9b4a993b77e8397cd3a3bfd11b31b961c90875c900157f97e211ee6c853fea2dd83212c3f8861c0a98963820d6d73c7b3693b738519deca589639462db956bca22513b9cab7459a51296443076ff732e3eba57ca767d4374a8b2544c46c54c2f46cd7bc6461b8105f0d41ca4a532c6e4052629929c03bbd0b3c6b52c51cf3195eeea6aa9a55de0d9063bc57722a72409a59747965b4e6a5e14ec112a103bba204977d43822d20c92a2aa0f4882798216cd26a857c6a12bc78ffddab1d73a9b2f91ba4de83bfc54092d4359f03a4416230cd6616dcbd916b989856f3b0672b172e20732be0730d1a3a6a837c59a05b846ec1d600841594b306acc67cce4ab7b9715afe074a75738aed749c1494dd683ab6791522023acd8e5c403f77b23f128f16261a100497e0b1f906b7956c53c1f1a0d65d9422d7a3e234c252675446f085450446393c0c151e751ce25cc05b12a58c334ee1334d16b813c7689c6851b7662084ef05ae30bbebb5c2911859db6dc449165bf8b41626839cb37814768167ebd24300306af259941c7628997bc80156c6b87c758d6c40b55076b74b2b9942093dfc979ae59ca16a6ae33b523a7c687f3f22638f37c69c4946a26bdede88477c7b67538115cc890873ba223a953e1b79f7a902d0b20cda992a25b235f30164312111a01cc5d82d4a6e1c4961ad96bf48b797680bd0d04c83463bf92d86279c994c88b57f5a14c45645f28fc19ee835f0ba480bb04a17f5853c1e00c37f0857e88504166a230344bbd3180e6421432874fb6767d0a0c52c661bff33988d3e3132cb744df5b6c28ec4e7ba2b25c22a179914f043bb93536602d754c92cb6ebe42832f605d6dc99a8065cda1ecbdc589a93ed321c529c5f910ad86b9183b827e1e8005e0ac102a35b5abe533e31acf35e649f967c064963675421990082f4897971ee4204e3611bb3bca7af3a5507b239e9ccd49c5c4e09c14f3a3106bd961d9d649617212832c54f430140c8590dfb1bdd40785390384bc9640e2c8564c4a4f700ac1c6d1895fa40ca309aa5054b04934bfc190a45f78ac1a8811046710ded3246ef4032f3b73231913db1a58f45563e3a62413f6a0598264321b33460578f682ba40d29ce15697d6373bc6220c0931bcfe87326f019c7c746e0136a98a6bbe8c7caaea8a222e80915926c4fca60dad75a3f03a60375c09b5c5b120180b51f185157a345dbb91bb5aa6b704183ea0ac0f374a90c02206668224f975ed605ea1b01c55b9a2c159c2a096b3c4a98c2cb8b81682864188cceb3bafe825016381b8b2bb7df2ab4cf2a71f77347eb84314dda92f6d5a5c34d9cf3a123a16b892099c23dfdcb5b8e67be1087ec5b38b081289fa8c3d8d560a2d882f8b8501b4096d82602e7960a2c433abfe928e769b3e22965cf7f7350a1cb4543c52c8f3983dc84709c1909cb76084771c3a59867208c1bdf869b85548740c8b4390a2a7824d2b8a283606aa04a78b79acbeac33a2e4490a44b2995c70165aec4e37a79ee3224a8c3693056b67b1021c5c473e7fd31551a24a3383741d082366398b835389d4e4a34f7905a4c5808b27b44e86aaf02032ed07ab30452bead1907ac28a1a98a97683895ee583ec59316673213f9b1e5c2339678c0b6770459509ba5478830bba25239c311231b796c8225c9206facc138cbc2f58495f106b019041387982cbc656604e05c06e630b3d84aff82240b7a7cf6c078b9fa99fa426c197a5aaff94a93ebcb61de47f9c1c368b4f0104a0e8d4f20f98b38f6962ea4d6e053a96a8059c6e564a9ebc6cdc60c0de1d36c87ca4279906279ca2baf7abe635ebd3b63eee5bb0d48f6dae10796732acba3efdf731bf7c242aeeddf5eba5b131da90e36af23a3bce9c7aa93a"""), xeh(""" -0C681B4AA81F26ADFB645EC24B3752F6B32C68645AA5E7A999B62036A53DC5CB060A473C08E5DA5C0F5AF0E5170C6597E50EC08060F99B0C00EE9BDDAD7E7D25A22B226F90149B4CE887C72FB60AFF2144EA2A72383B3118F922D032A16F554289902A14CF7755512BB1186BAFAFFE794D2B6CDE90109E6582D39CE0C96197484B3FA07FC91D394FC8D88E7FC4BE002E2DB56F0C4D9D3FBDA274536A0B86ABC6E39BDA52931AEBB8F1084C5C1F7CB3177788B7F331B7074361163491D428E78BCBB57B630841AA987333377CF09569CFD14CC2A11C501BDF82C93DE05BEA20060DE89C686B824571CEF94AB3FDAFA8512619813669D4F53637FEFA4D028CB233E56930E2235F7E6034CA94B143B77AD4A68756E8A9184DBA61A89F91EDFB51A39211402473A5F89145736B2BF8569C705B0CDB8980A447E4E1EAAD3E7E0578F5F86B8D03C9DAFE875E339B4423845616799EDCE05F31B92664C5A59253A60E9D89548A300C1ADB6D190A775C5EE6E8A89B6E779B034C3400A625F4BBEDBF919C45B2BCD14C669248FC43C3EF47E100758942E75E8ED6075A96D70D4EBD2B61358224DDA1EC4C19C2A92898176FEB3C02EDCB9908BAE49BD94AF028EDF8CFC2E5F2E0BD375006986AD49E717548E746FEF49C868BCEA2790AA97E04061B75605CB39EFD463D7B3D68BA574434FF7BE8E2B84BFC47E67E9CD15F3ED450C61AFBA79A20B0B6F287777C72F4AD248174F1959477AA7A7C97F122C50447C7484F382BC47D81FCC9C7E892C8839D37B35394B53E6B2B1895ABB0DE8C98F2633DC4413A8D5735DFC9A64026B6F34779D6AC8AD99CC31AA898C2E7057F3DB8A1A8A98527A79E43552F28D1023E1F6A6B84855CF5E6DF889BA269F048946E84021C65C5A93B007B07741C1EE176C73949110F548EF4332DCDD491D2CEFD0248883F5E9525BC91F30AF17CF5A98DD44EF9A71F99BB732985BA10A723EF476FCF966DA9456B24978E33050D0EC90D3CE46378851C9ECFCFD36C895D44E9E506993082523D26185766B23568CB95E64108F89D1014747C67B6F3C8767BE5FC341227DE9488861C5FE811409F80957D07522A72CF6AB0378D0F2F28AF548185C3936777994466A019D33B18A54F380A33892AB4D4BD507B5A61D0D358341AC92F07B43B8F6AFC6991BB6A1EAC23CA6F73E91F2464BD119098D7E768E77ECE53FB899BEB42265ECF7B271F66546282D472C36239006BB0ABABCCA24550BAA0A601348C810FF5F9EE504BF7155DEE4141A11605A4F3509AC9CAEF6624D21DE332D5D50828B52E92885D3B90553B14463AFB1EDCCD3B569B5A7F00BB66769DADAC23AD8BB5D73A6F390E6FC2F6F8EE3CF4009A5C3E1EF60E8F040672D262E6490379BBC70495DFF237BECD9952CD7EDEB6D1DFC360B3FC8B0AF480FFE024AEEFCD4E9CE95D9B469C9A70E5110DA0BAC124FC3741DCF49116261796504D5F490B433C33C40EDCE2B75151DA256A868A5E35F86226B8151C91934CCC3DACA391DECCA745375660B6EC41AE5D810838CBEEFFA12557884412357B1008363D32B237AA1DD8E2D9C6367ADA09B2C95060206CEC3EED391FDC5DBEF6F08BDF0408E585AE5EBC8E9745D44FECA975ABBC140BB37B8ADD16FCC2956910DC72BB3F02E9A130C9A84F9CCB74D134CDF40AFCBA2009C8F0040239BC99220EF64C4DCCDE2E2E5C9B68602FBE8EF4C98B3468C79DF4E078511BFB8AA3DA09597A02511E7C21A7CF66A93843A94868F19E8552552E3ACDF6CB810634DB97CBC4BB569709DAD4845645446FA8D289FC59307B801E60CE2A91E06E9C22C16E2E59BDE38A416BB1B4AC5457438FDC5D64450A89ECB832C1BB279DBF59334681776AC00409846D09D6F687772E340850AB8673384215E12C8D0F531C451E58493E0EE415AD594DF38C34408C7ED9F0C392F1534604EAC3D9C15465A9A46632214B536990D78078E5BD7EAE2013FFF8FDD8B275C89D97C9353DF3C42A28E814D8468E2B48DB0976D88F5EECEFEAFB8F7F4AF291A728F6249ECF5622339269AA945329E919F8B441C83D5507F30DF0FD2B13FF806F522DAA11AF676A513C149C70F0D6E99A880450A54E0417FE3C1E513E9D920E30A8B42891267A2DC50AD81F98044920C099DF22C73998A25C581A5178C72B17AC875BC68548A0FB0CBEE38F05017B12433343A658F1980C8124EA6DD81F""") +e7264e0af8a23070a8c6e9a34aee33c43edd08518807c80517f919f0b4594b220e17825d8fbec1e0d915a64ec7c248f2337184a2c13faf74b1f7d39034daada6422850ee9fe4e631ae7cf4921aa8d2304b85af8ecd09cc8dc87970181af62ff056a03a21dc1ddb2b4624c0f4abee83a4f040b98bcc1620a037486379c4e9555242583190bb6e952467cba25a05f9440b41d8dbfa34ae84687156d44e8a08cfa4449904fd04604481e5072942d85fe0f0ba90326c8a9fcb8dfefd1a391f80fb5dc1e6ac7eff332295558a0567dfd1218e421d7442853cb777f36bb112c854859711b988a9b58e07594e3b33484cec55c2ed39d54a762dd518137e91572d9265c71cd5a039e56a9702afa2f9059a655bae01ce9c0057c9ae8302dcef0ae6063f08757d30dc8d2b32e53e88b2e80739e8c715af7221fabf57df76b960b21db21c9d85db13f5336b0ad56b7e50b888f044823c5233759f0056775d8baf2efeef1d6028c6ef27964e01ae23290c1de232c564124544e9224bf4616e5d54af0e013f41b7b3986d1a8ac822d8a842e825b3f1bce18171626caff262275cc30bb5f18eddefab0cafde8ce6e7a0feace3d3cdb47757c756b15a2df7127e0d21d232082daec8fc33a1f0606c0d18d2767ad7890d196bf0735d97ed36c994d21fa28c3c3a79c10dfdc8b83d40b93023a8ec9e44b26ffe6a959ef6e1017f77bdfac76633d4d33f7d90be2c4476e0e80e76b66054f37a08a9b75fb11895c6c2c42da00947458b151ea2901d0e407429935854b2008e25427d924b4649cb2130a5b3edf43a0a0051b431ba6f8abb0951ceceeb1dde5a29058d85bb7e40db68846fd94aa38cda27979ab1298ec80b1118f2659c5ec9e8ab2cb538a64c0b695a6902b27c00ad1be5a200b0f9b26d6934a55ce6acb44cb3a97fd3f0a68261cfdb32fd986ebcb8ef537fc2b78477ea72fa2d3c5336a62db5876d3f0451866c27f1d460c5d9a473442f908176fb1162247ff5f116849ed6b7ef943197c1d0811386942f8d8b2e88f6c780aad8a648d6dc1533dabb0d05b333cd436f7b0711fb2c4f604052f0c9ecac0e0317c893d87922b23b84ecb074d1b7d12093c802b3666ee0a9a37b33f0cc033c4218fa2a8d735252f2f3869126c949d4af918f70a3be928ecb25bccdaeb29d87a5a8995f4d33510e133027188972998f0e9efa5fa311b4193d29e25a84e25fe203120d1dd9b83d1a3d70f8131db19ed072cd2c84b95b1808e325d74b675b2de30b54f0e739a54960bf32a523a2991ff55ec23e459aba6d3f84c1effd79ceb2f821d9330e4c6dd5be2bac39e8cedbfbd731294effbd53af271422397395806644a1f7086f2ed55032fbe7840139676b79dd84c3837a4dde7f5ec6926c9223283b48d26af7c6109cc290f8aa201e5e953334304e6c49b8fabd194e0151702e50381ff8bb8391e157f072b3c31ae01a5766f5f27dccfc293a8846e279fa43deb6937f14e3208b3111dfa7530f9b53e05ecf55d61bad2a2f5776edf33e511613d2441f19994930c00b4c992dd4245171566da2f536766ca4f2f9d6fcee7afb81197abfbda64e841a14370ee08ee2a60013ca6166f825efd339459f206f1e43e3dd85cdc5053a84a8aee21764c258404318baf94ff261545933a0f6db252e24104e11d7eac64d1c6e091f66366b2c3d671e28d7d6c6b39da5e94ad94e81cd0371c44e940169c2971b384c398786a8fc1fec41e212302b421acd0a6cadf9696937abfae7ca60ce0a09c3d487fbcd100b0b34e24eee164b484f7e665bb623bd3ae914966cb42ce2d176d30eeec62f717ab6af75557df9ec572b20c59b6bcc302af8dc828a3d9ee5613325044ce0f28b6748750aa4a25813f97c168efe87dcda7135019b5a5e399dfe8b176d811e771805aef02432bec8c5b45c956b27916ddf67cfda2733e87d2d5998cabc88e08b6dc8a843a125323f66c50af9801a6e43b1b959bd14bcb497e5f6712890358d1b60d660f62980b2f1b1d158db5ba0d3db1457efdfd7f45e7cc7a2ffc3b4a85518b9403adf9a901397e761af1b653f4b9405a2a2aa07fbc517a16155d9bead37d314f22720ae353f4a600ad50e1e3fd26d27235352314be1f54f97966d0dcdac7678632d8768c00dc80b54b1220ea459111e9612ba4b0d4c693e7e32192e3b339181bf0a9f9b54ddb274a21c9bfce46846fa3a84f46b""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +1a320473966c4aa3087e3212af70b1b11ccd746a08a4c738e39b06e74685bbb4a9ca6a6e43c27cbc4bb3ef3ccb6eaa1ad714cad82a2d7adc59db821b32d747a9da182b7503f1706b6db1c2e518734f60b41d6cacd61c1451676a49d838f6e2c7e9f2ac376a312e7a7d6179a8f6b498d7f2198d2815e3517442bcc5778ba5c45642983430c5125b7760c5b523284358617f1cc5004bb237fb1ac7d938e210294033728fb69c98789c2c05cec3ea565b145f6eb2a662300a1ac877be0b73dbb01c7c0a2e3718aaf45a770f02c51d579c630332a87b6d79855651f695c77bb55676b953f749827b4f039593b04124282801bbdac214fa2d73a30e7513b919304f954349f1c9bec729970fa90538b2a7c9e85d510231b12bbf8965933ddacd221a1c7c635468180d752ca46f586c78a41c06d83f9dd553aadbcdf36b5733087891870b3b661b600458b7ca234ad604213165f265476c493c235a6d9410a43a641150a93788950e8905042840aa55d0ba5beb78e9f03cbe290875505806863ead88c660144317e1c40a2bb9c966a22e956e1eaa28e9bc10f0b7ca466828451266dc2510ae677cad9375d93261a68136a617bec3e3c2d160033e477d33223e5b0013d859b40d187d6dd50d1580632724ca3d3201dc1bc2b4f59cbe164668952e85f3152370018ccc0b686b052d2165752b40e9bc58ff6c6093a4257a824ce4338b2e366c60e313a683870739391caa98f623aebeec020a15c1f74a538f71634093a9af37ba7d9530ebc363296a60e4818e8d4a0d5fac200947842304bcc68b2eb4a797f14a9accc53375d9445625b49da5663d7659ea600f972766c9b839053a57ce30975a1b45f84b0433267d4ce2ad20e0adbdbb0aa37092e8c486f78a508882a1c7f34334785991827d4529c98c5c40e75883d35246fb5b8615567382574b1113cefdc8bf41a48c8d7585eec6bda67295d6c0ac5eb699f2f9bb9f6568aad661d638943e211106a42867b26cf0cbbc986c2437212c5f9b83b445bb21a7a056074d969182265a55d6179f50d327e6f39098cb304c6a02abbb046c9ca42420b2707056020a2c3fe973a974c1008d955941cbe2001937b7215b106396392724e305df7792834aae28003115208b2a853821ab3c4485ba7e8b2b0a715803ac25dfeb23c8ba6f46e093b3e30abdf20b4f31ca93ecacfc1509b1a9a3ef7c8dbb9aa3f9108b042b7f89232781198750e5597e78651a46217eb9b462696056262f3f4b4c7d36ba6b59b375bc8b64d8387301a00b36c2afc36c7f061b27482ddbeb55bebb3144c43a72042e3893895f823d90f3ac0c18504bb52dc2f574744a98c73183c01257b2746936f530a51ba57f6a487a007f86633796509f714420e143ca2178bb04173c941c768308804ce92b9ef05e89b36510ba2a8c8c7c8ad46fd3e614f0baaff2582d2821785814c2a7c40f6f224a08d4a732a306a53b2f03f556eb0b86f6f05c7a20b5ece842550521960301f0d3cf71460211635a5b2a699c2ac952e06fd017b811ea4a14841048c2637d3123fe3b6b67848b18ba49128a8f42db474ea455bd801603381a450504a137c82e71501cea1403a5a4ad22cb6d032c84b2c62f8552a3d02922d9491fe6673d121895b55e188219432c4a5f00922b57956bb292798c41eb2273a066a1ed06a25eb60540042fd201cdc3986345f80d28b99bc80bcdc2ea41d166a72abc9ed546207c17317858b79be46b33f7156bf511de1bc18cdc883095aa47d3cdbb3a582292b0b1c67cc722b7d3731a4f3bb63bb4009562925b4b2a68b3331328244879bd34c258d6b28e8e54a3e59c552be15e97454c083b846cf50581c373f7f73f3ea8158f92aee5bb43905c728125adba1c0d7d4110b6e04b0040a9ec365c9e8b74c4059e78950bacab2c69a5709b379323365311613dde867e6d44094961c876db6b021b203beca1cad38c2d565fea49bcf59697ffe180f3f6b6bce65ed6212c6cb60dcfa0a787280e7eec0e36e7733e246b6b1a99fe91a053338d43ec3b1808c9a782aa44bbbeecc84930e568d58705a560ba11901265885956086feab13795822c14754009b28806e5cfd6f223607525a6fc087ff4874cc6b995b9c7f2645578987b5b6c3fd485834287817dca09cb75a0c0e00fdcf30ea696835000919f0159cdc7aedd3148ccca020f181b2e3888cb6c3c8e271449bac0da2a2042e230895818cc5bc87e38471d3abc51f6c05fd80bcb43bf65d55a0c4c867ee28163618376fa5dada52c5f4306cdd99f0d4583c1399dcff8175f465a02d61dbb98680de662b49b762a8353ae15bc76bc097b789ab1057d2595363cc043e56c5b44562971c0097188a30e488433a07e7d934b89f4bd74b98822518d2e06932403bf81e97347c203e5413bdbaba6d4107e9ab4aeb1091d77a326d7ecbc09706a98499a70f28300a0c80c3aab68980c4d1cc662091bd370575e7986c38cccae743efaaa63eeb9965ae8605a799b447b76f91a15c8f16b6a52864431a19839543d86ab02c469ed7404d0eb365b7bb643153ee2737b9107a8362c4e3b05c0136c6d1510229497bef7819fc0a30030f899c0bcc6366090d4eab165258fd1447a3b12156bb6a4b3320914d797a2eba18bdc5615c208d1328808b667ec39a283dcc331e83b9d9302e3145fc003230c8a2365a5b3bb52104e698d41662318535dd9557df8907b6161a404e946a4b00a52829c8bf911d79385f254465bdcc77a31974fa6426554a12e399b8ac57e8c94163f3727472baebd458cece806446842c48659ac6c7262304fb693befd3b67b3237fc239a782c83afc72366cf9cea621989d801fa2477d564178d5c13197482f373a9e4ed9b2c276ba88e0348c1708c93a7c54d21bbc64496ac21969b975e5f56d033c287af7ac993cb87965818d26458844103957834760aec8c1572bcb0aaa740cd23b71a1a80396e45bd5a2bd704474f3d232041ab51404a768d404fb295a18275720b205b470778226abb26b775c972505eaa461fc52be230359e736cae2299cf47b1f1c0cbddc7472439ad8033608a8994825326b9297225c8fb4c0ab6a51c74ff2059d60aecac1cb8e9b5b0de1bbe00038bc883c25d23be3198c21648271cba8559c3a451624a403a6c390cac13412b2c788d7ab93de4790e8230bf7491e39019b1feba2a551629a5a012942912d2631b5f64e2965c73205bf25fc451d8836aa944063925a221784a9b5c99f13c381b5ad71c6581f28510ce93366534e8cd137faba6c53d92e25205c9cb43d7be5ca2940997ba3c903c04ea5ea4605503354d4bd63e3070a12840e2551f15c20f6769834761bbaf8a8b11ab94b69807a1ab2dcc396fccc22e3168e35c444efe876dc4b7d22683b6ae49467d88e08b795cd556b975155f4324dde94ac7a89ce5d802a91b4745c2b6a86cab67836030005c70944864c0835f8039c23d7a999d43bdbf7428bbc83e8e65c7b81639ad41bb1f357ce9080c3cb57319c1f37db4a3efc386a40cd60bb7a06ea70c38458bee0baa58a9209682e73fc2cb7a6aa55f863b49acd9cb18186b2b64434a5b7a38a2cab3b8baa47e6da377ffa1d6a432c847c4c0e757d0847933f5962722a92b06abd6ad28adb1736c0a96ac8130caa309f2e5893b0190bd67016f04b17f38218853300a05a00fc30330cd907fa08bed95646db857f4edbaae9847af03729205691eb715c2aacaaeed21419b187c7b99b1fd83ace009abd93586a413de2d9313a854142f076ff76a9661a96bd11c2e8986dd9a7b3d9e1076cc21c0787226a66087f13591c896da8e521f6117a9d7c5028692433e86959450868272445450aa42429478a4df821653067cf61638a1c676b776b9de76c50e99084e1d71202c8a563c9c4afb6bbf49c851bb939311b79a358a5118c945f0b9f54c7a5d0c504192a94e610153041a291f450bb44995050a964264a79818e6717c89b4046f16908d7254fa4f571548b01e9eb37759c7e4544c5e5f98ea014200fe291cf40bbd4c3a61213c2ce862ef907457db3b39f82c87690451c4a872846c86ca53681030ff839b24ea655b8a868fca9188cd2afc719b99fb3020e547ba9e1c35bbb7d153508889c7d33526dc071c4e89632fb5538adc58a6a304b17610558b302efe55a0c631e4760c1be689b843633aa31bba7d9c4144a14d7ea15e8895061c025bce225eae5570dc375b6c449672ba29c9c848ed16aff85785953cdf0891aa5756166db1effc3ac58c0969edb54428588055c9fce4b05c023bd386a9c19c33d33d59044f9893bb98f3a77b35ca101ff518e6eb4b056b816afb48b7b1f4f707d29344dc3cd4fc20ddee4ea9cb19d236d7d13a7846aa22c2872f73bdcef6fc0ae6bcb0db78f453b452335a651c8329fa3a35d69d60c44b61ecbb96360d235ddc4f334bfd91d6b7df1a4fed84c88c2933806f13fe06ef15aed96c9e1"""), xeh(""" -4F90106FF7C3DC4E47417F31AB56B1C5E426C1ECD5878AAD2B705E75062DA5FA6F4D18B704C941C6C6D941FD21191A69210BC39E24950D9F851B6DE8CE30023DC7536439104D42245F3E04E6AA6763F8AC97ADBD04CC69547BCE0BF290FFB5D12946301174AF1B0868C14D4293FA9DCC5B23F809B02CC78DEFE7F27935B9B681E531FC21CCB2AF8EF6144D8498E63E0EE48AF8D4CEF7AC1F669AC740B06F79DDB58E794F2FC2CA832E05A0374C18A4F2CC78343EEA064ABC5F468F4DD11E0B6E8FA1D18A221D8241450C05EB9EDF90D9D7F666AC82E7FD44AF9328E0BC6004D5B114E80E9B980D18E081D771DFCB2ACFD40142A2EB33234F75733EAB7D8EE8A5A6F796681A4A8AF85CCE86971B821D4AD8371049E94E280B77B15D111A42AEADFC08D4F804BD78885443E81A393DF7C8754C460915846E09A0596587460038F55D06EC21434A1C2DF44D0C16706E8D2B83F0E7833976EF05BF1D9F0DDC9A37597E401B817C2BEC8E02EB9DF7591E239F25F8648E7F2F4F673093BD9CB703DA32B353F58514C6AB55748B194E52F153D52F5F33FE95C5F9F65EA97BA721E8DDF333B64D233A867A12701E00C5D8A9B5AE344F3D847C27C079DCC9C3B40EC4604A9F041E7987E8B930C658B9A132DE4E422C0E27553A2A0EAB8C859EB0E5677E83272725C5C1652E61B9BBF5C9C59BC2357A4D1DB9C607F34DC1BA074B84DFC69E4097A7AD2BA9A58000027296AD39FC1CE218A5EEC7ADFA8AA3B9100B0B603CFC83C152589E12E6BD9EE10C49131A701D315DFEC38E018328916F9FFAA7305CFB66781707D2D1020EB782F9F003DB4E46B87D693F62E8BDE170141FF71F26DDF5310C00C9163655F5217DD2C8B0466AC89DB55BD7FB3B0964BC9009E9686185117DCB50D6D0297753CF7F1217E819EE60E3F0FAEC4A5AF0C2EA83CCDE15CF045C6961DE8FF6235C9D93BA4C89B7A82A7471FCFB0B8EAD54D56E8A1DE21B3933AC5B4A0689EEF3598926E17BBB16AEC61EC30A2CCC0E0323EC282887C108C3A4E83E3666493D8653D0E92443808C79D770BFF48A49E65AE089FEC790BBA4C66354EF67A334C1EA5C6C5707B6928EBD1BDB6A940FA242C6EBD7F3E71272421C9082841A6CAD2894BB8AC85F105D8BBC9E6F0A3DF0D7C46F6E2F4CAB904ED157AFA85D4A852220A9636E1E8821643A9E4028D87A430432F09354B3973182385CF5ABFC8F84982BEE0BCBF5D18637399163A09EB45711E07C4458498C76979107CF91B3FC590EA4AD715D656D5E56DC32146580101C952E02ED7017960D54CAACCC70607196980ADBDAEA420A52C0559ED23C9514F8CA7AB7F3BAAFD2FAB58960A64128D5A50E9AD8DB7D23A90CE64C1BC349D118D3603358377F84FF5A64457FA1CF41B27094BCA72360BD429415B9EF9ACCB7A5D7B9E5F5FDCA8FCFA4592E91D7E5120DF7E3C6675AF2211BB94D856A5D2285FBBB36984A1345590930B13232565D54812A9345324C232653190323CC67C840E478D09E6DDBCF999F7AA3B556F80332E67ACA41EC0661088D7696BB64E9A98A0749FAA9854D9B48754023BACAF3C8081A46157C6453BDC89341D3092F3B5337874CE5DE559A56A2FFB7F401F6E28EECAF4FDE5B60DEA73D6B2182EF68E07A8297F3C959E17139B5DEDC72C7A0E103AFF866E89D1F62A1F6B97B61BC059BDE5A2A06087EF783A441F23DD191C692D03C097FF9EE831F7715C6E508BF475E79A8353E84B06A9356045C8FD09FBA35879069B9A3F478FBD051143C13D753BC45F3040E85985EFD6B149EFA9455A18E2894E6EA0BE58F451FF1156F93CC7117B5D091E9DD50D41BFCCD44F2C4EB7812AEFD13C8B68D7F0103BB6CA38D233B6AADD01845B7E44D13C1CB1577D6C4354B063991344787F8C0BE667A7440B98917AD64CC2EF2BC82EFC3398B3B1B238540756CE9FC5EDD26CC20E761D592A1A0530AA8BEFCFE8DADBAC99A417CA0827F4983FF5BE656669F2B5F985FF6B16C44BBEA131D1FCC70FC53BF31EF225D1F5D41863B51B57EA65C6164F7531AE492EFA64161B7DABA3EF4586F3459BE8A962367DC276597B98E91FF594EFE8849BAD4CF91B9E5F244CF03CA9615BE128E96958533544A56E735994B92E4EF0D5FAB54B78EC66641C7463F225D261C144F00A0270741D7A511994833635A8A9B670CBFBEF239BF83327E247943B205DA68DB94E3F3""") +c79699b8ef9b89c2e49b1453fe7ab6858b2da61696644d42d0cdc229fc9d8ed9f38043053da70a864565598b4d4a819187e5e5e78026cae4d4f3a1e7c0775e249b364683de669993e18a50cdfcffae79a31e1aa288a4b6f8827b28cbee6345db8e91d8201b19d1d80454574f170aaef523cdc9ff92b10bbe28fb8ab5e6e7db3e68041e5a9c2e47573ad50e15805d1564837819acc59de70cdc254a283670d1b6aaf2819b225d925449e373cda59460b7609ca12d6b22deba14849de7c6eefded5b1e1b208bf788e999e6307b6ada075c6c94b7deeeaaa423084a4e8359cbb5dd15cc17c50d2bc266da206e5325e6cbe0f6f60017342cf5c1f62536934aee341f184069608fb6f012c3d01056abb74f93eb014aab9ecb011a236d3c1a06280ac2e568d77492cf890846f5cc693a1195c99505ffd7ca8c0ef8440cec1cd3f98058e30295697aafd6dc09a5094670c5d289cee2ab00d0bca1be7c11d85d0017eabf6ebede1700a5b7fee55766785ba95a082a7335c44e313efdfa61e220a288820577b01194d7a581de47c8b238bf14e0eb6d3d19f8f6c5c4c0addac509c93f2873171397f2e9acf784ff75eb9f4004699bc0dd6a44157e48a8b4ba4a43beaf34be3b1702e43f454f6984de2e62493c92fada8649364e46587f0d9218e67382f07e0b332a2096ac209c41e0e7f11be7e7fcc10d11f4875e772a23d2fa91dc9adc605bf1b430e8ffb01172ee90ca1cc99ddb896dab2143b65041c7f4c3d59ccdcb15de31ca6c58f763525ea0406b1333cdf4242db129df0d2dff792d323963d185be073fe8278a8a41ec4e2b92e2ef9c7ec455d63d957af57362d717d4fddc772158117737e5592dbdb75f577cff804adf7e33a0363a505b4cc9839b7d5af46671203e894bee7ef6f49f4158f2b0dc740d008eba3ccffa57e2adf670e71d0391b237fb0385f2dbc6e23b5d425d446e71e1455a0d42071969c08d625f1ef2b448ccc9e7811a1e2a37f645bffbdbf924ce82cb529586f2e3cbc20f27b943b21eaa9cd18019308bb48bf77f0862b92ad3cb47e7391d57f5769b064d72b77cfe21c301aaf15939bf9700b39c9f9a4540dd7a98e99770c5035dec99463d716c8419fe26f6809029ad924f69283172e65e2fb6fa468e13050a0a28245d39c5fa5e4d8914772442f7efcede8155d7eda49d443e8bae0d324f845acc04bb20b462ea33e26e96d3d7c7d7639887d2209072fa81ef756f17af18a7c309a6d24d5448c9552da0bf8d753c7e5d00a4ccec78da0e98ff7545556d014083704ba4725e24810aa3fc407b7c69f8dd40ec0c992c1f56bc66acf78c1dc8444b93ce924bba5356127b4ac3dcbddac6e50962cd4815343b4c07c1894703459fa00b39f7ac8f2476a373910573490e0c27de4252f93a0397195311ca501de3fbf2e8dc54cab6259e1005024934c056b6a84d8e27bcafe8d645ad3a30866cd3f3f85b1685718006242d5ec834afd8a310f2a1451a0f453861575bd1148230320f80f9bf32be14a7e60bb0861840c9a578eb0b1ad3307b4f3ab6e9da924ccdfeb95ce969e6756de4f50a2ef107a19eed220de2a75bd0fc29f5af6b7d45ae9f2189c311bca2b3762b85d4e118662c6790d042ce4ba139e57f4527ef413bc2d369478a2bdfbd13678efd2ee9aac0c327f38dd7d7215378df392c55d003d29a33a3ba8f5dc802008cc15948e19e927c05ab1b877f2b8b7470832d832f3becf92969e5615c16ee4889b6eab1db8d979b5920d8510213dbb7fbef97113faf3f921d250c62a1fc09f331581e38f22bb4dc0721424806741cbb1184736280828474fe39a94c8545a63797a36eeccd6a285187665c06bb78294c40c33e23619c58b8894afa386e7608c374e0f47711c8ef2ae63c18a4974d3f1026d9d32847b9d0b99f00d56f4d249c661bef930d4989e16711c0fba50762b00699802a2a4477762deffd425c4cb737597e2f3c4c4ebf04d4e6225668a95d5180f7cc983e3aad5166a713460d6db2598a220e8f979c484415f5eae35447db6df2cfec6a1fc6c891a1a41a14e7f717b0550afdc112c78111f2116b9143100f4dc03e0e07f9f1bc14387c0873bfa3664f7dd3967c912a78552837a148c9951e8b5e082f194a640baf620da0a0c591df26397ce8f4dad2a421827f65ad7a674236ecde9638a6404e9b3337debd0fc92a1cb9b8d8a49a1d9357""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +15fb53c5e0be680103b2fab23e8c1f8a7c9c06c089a1929eb4c8184030abfaea1be6ac4fd64b7b46a2ac0b84a86fac8b2da83535ec3e2b833433f047a5a62cb3f01a9467ca71907644d2832d628433f90b4d047aa6c1854eb61b085b09dfd6c2fb03b82c429f93949d55c993c94645bda692e67c2fde953960d0617ce613b0f51a0e300850bc1f233046898035a0e37b8f1064ed67caa3fa181999a9501c281b8386467835a0d3598cb98e361ac800ad4fa794943bfbaec427809739c5d21253ea721a8ad75db9f5a88baa356bfa5494081e3dd4bb5ce1444fb8258cc867eea28522da5acd855ba744572f28b0b3772a195836804a585351b1db059aa2463e21bc00ddbb177bd7848b7895727472e0730d52a058b3d9b2e8534e29062b84da503fc219729641e2a94890cbbdd8613b47c24795aa5012f813a8607b4ee3873a472167379c7feb14c661cbcf094a38473b624c9f3d1c13719b361cca2a788b914e71626032aacf02143376a331674c00121dd1e2cc27f6aa5ae7604fb224c55a56e6c6ac4e112259666a450728abea1c2ba0b215a5532407334fc823f2f538b19c41bdc769bb39016c6b80e979448c2303e5b369a0745cd2a52e09ea78a31656b5eb1b9911cdece131f012b2c1a4b58c7b5fd6935d3dd4537388aa6ffb2aec95046b93a42c98b1616c50ea3381d5a663c28c1ff5a6c539d762a2e069b79514dcdc897192b27b6704764c0e3272cfd76b06f18a52f10b843d2c245451155da8a2ae11bfa6595e686799c7a5a2e9710881008190974052d2be87f30cc7193f85364f3e7691ace93e546c4a5208bd0b18ac8da883fff99c555b4990822627904bbbe577766ba2b1865a787a2019bc7f70829a17ba325ac65b3b8ca922f2937e01179ac7184e596485fa326ff10320e68609c87560c58a281c7786a36105278789544ba33237e45b7f0f6c51d7aac94b4c4b189bcc6d01a74cb4841d1cc35475735d88a8ba650b8053693cf3680ac01a7a23024746ce36e7a86d49a9843bce16374e2fa845277207c6d949aa869ea7bc560da4872daa20e882330f6250a7cc9fe879a805974907b7bc3e0a06f1436370557a90842c0f6a5460917021e975ba21682339240db26c9a20b8b453487555aa2a1c5928b0304d4aa4d009cf290c006fdb5f64b94824ec1e2f51c3774656433b811cd33c54821800f81e5d48a5d43035d6dc36bf6466c231690fcb48d086aa5fcc69f5a70e5871b29c469e232478a684a09a4683f84933002b2196db7b37f08a2a82a494a15ab69ca901ea289985b500a40edb592628a16c4f827b3fe29a0f92718a8ac57195bf8bd5bedb9c9035c3a68300181d404be29427f02027506079fb9534e882715b388edcb05e5281674f161d739039232a57afc2ab8c3bcf03182463592ad5d0375e098c3c951e1e1284cf2b604475afc2a9af4da0ab3cc583b3991ebdb0babd1c92df9104b0c1a3abb8a95bd96a711c99b7b62ad244cb4fb243cf1c6714db4fb2a7c9a21784135a5e00b1b33857ca4a948bca6abbd212b1c06aad751b4f787b9a7169aeb8094b14f93869481c9e66a4c97c1a7fbc18fc0443679827320689b8901544eb2eca55c9450c1f5a4379907a66def76ec3f917ab7c39a791a44171a549f93ba9a5c8bbc19998bbc2bcd712b224cfe6eb3874130965972dd54ba21f5886be038f73698e3eb519578593a5444e918880c345be03e19f45b5028ce557f454b2aac808b1f98fcfb3c19c214a2db082c492ba02d9986a570b66c574d2081d80165c72f9053061c6454561d280558fa1bd7921b572c78773513560638691657b632b8110bc31a372a0ec6b3b8a3a9259c148450c8427a62fda54490ebb6acc42804721801bf83c7b656419f0801ae2a722db4037937d08064cdc3216e6216d402aaceca387bc56123954b8f724368ada1e7f01265d0682ffe847fc44565e5577125b815eca0c97f2555ff1520e2c4c5e6467ac09143bc797ac6326c68066035ca14663a335b5137544b876e9156942a3cbc9ca8734ce6f76b9f51b0a758b9b50877f925c4842828a7afa4219928173b92a3a7692477ba098c966a42001103b198b1a2094c42a9dd6cc1cf46c84945aa40bbe71e48a20913d0ea600a33164eeda16a811168fb123ef887496d20f0799b60055b072088af992055fd18766111d70a92dcaa1881c1b5d03807e4a948d0937b9ed4385a6479a23930878102c0c9a04cd1b51bac6a7a81cbae47b15f33a331a5303695a4ab229585d27b3a7105419952bde5c659e089d38789d3a82212e03cd0ed7a6efaa913362b55f386d2e4b8d2565a5781642d8e970f6c9ca25d2acdb8a3da7f493e37331d26432c530bb401a4ce65c463d24194b2b1d708ab2a34009cdb02b1a96a921f42c90488940e7033090bffb30b17b06bf5f3b7115a24baa94a1620434247ac6c9579f42294e1f50cbba44829640bb7713c8ee957174a85b295bb1e44943db036773d91b211537fd9584954726cb83c4498658d1d2a10d2b6b1593348423aad4f6bcf1807d6599a24c4544dff617a2710e119bc17785b0a8c57428ec993e5991f76a9503fc580e4c62a0b296dc52a1a2c83846b7673ca308fc0877d5f473012c5c50a67813424792171e87a7ca555c0bb380ac351baa05074abbecb602610f1c095a4d3aca0bfa11092bb8dac09918449149960dd7d0928dfb2fc23b7b50d85012416e2d237afd47348378c024ac5b14c9ab4c5507a1355685550de7dace35cbbf20a679c9b76fef5b795e0a14c803c36984669cc88acd814d9380646edb1cfee159040c8366e7396af8977673400f5ab2c21980e2a184a472563b1c32886c58a0d68a2d39275529c3fe1a744c877a0605c5da7556dedb89ae8731e729b6911a6194d71102fb42961bbbf770873784af83c596a66c2a94a7c851d9677c779a0ec527bd761dec9bc9d1b22645eab949e31f1968c649c811884a765ae00e98f3228fb03643f47890f78fa6f0369dc37c98b593934a3937084f0664b10c091e7a1315adf4b3f34b5b20123905009c6f24c7f0c601b8f53664b6bd6d48cb487b0d22d45e00f19409a894f3ea32b2b3ad0536ac05e420a74a710dc8375aa9610d2640fc7818ed599598f60e21113670b99cc0d96447f6069e0b193ae79277cb29883506180743678b3c9b53718974210f043140d74392d9be2c08bcf796b462211d60d618faa152e461cebc3aa675ea1260f4585e810cd4ea8415687d3b2405ca72a46129c95f9bafde87061158920c4b13a3c5300918c8de4b0f840410ee91077d611971a4094f3a236230337127c5a789209f36c39b05b6618512ea7c9549aa4552d30ebb5226bf06708b4621a5cc8f58b8153ddca32748682e36363df63bc1249ce1205484048fc8798ba7929fa627404f072a2e0c02abeb48ac9475dc1c087e427309c2b701668a291a54056047def6b10618a34c550235aa6d39f05af809174041b2140640c252b604e81e56f34f2f711ce6d64e56ca0fce0133244481058aa477628022f2c2eb6c544d1045dc61aabeb0aa42127bda479160f582cb075619f810ca2ab886319bf87b12ab710db03b4a1a170be0699f7f333a46b18d71e6832c356fcef57db82430b1bb745f2215fab44571d4b0d9d568fa5cccc2919b2ff6b8d9281e07759069b9a602ba7642f570b20b15a156a1c322447323a4e9fa1219b812b03a5b2e1abe8c5b7ac26a8589733a3fd33480e18ac200362e5a0dfadb1252c0b2d8c139e4532507329ebc3910f05b480ed196bf86166bbb2f4a96a91053b511c81ffb748f420a33a6cb771dd0129cdca037e4533624aa16fc8f18a9bccbb475ef0a8b978ac9090a4539ca1fe06c5501f2b34480b025732a90a01e60ba9dfeabb4e8c61ed5c4396423af0aa79b86157e687c313e5623e6137f67a25680eb6bb841b80530362bd1425ee986b18830509bae9bd9926f020cd02713c7a83e8ca4318a044691637d03386dd28c3ba081481ca7649939bab47668fcd4291a4885317025e5250894e968168447f9f5c73702a5837802cc4593ab99242a59a39fa14935eba3e781a7f2740fbfca7141c821c8921e7c52b4ebe24732118cf57590dc919d09ea18d2ca63a605495bc2a88f9922eb356fe0343e4ac2666c49adaeea898b1c023058bb5bc4437bb6b798f59ecc8b565f811c8ffaa13cf8a4af8374c3221c3e1ab89cd94393053acceb40fd6a2c1d2c4c6316993835b9ade3a4bb396a5040574005ae9f1619c2fa66ecb363be8a7fb424927f8033ef8b2397a691d2670195590e9299375ca9b5dcfacee6eabe078b28e7aa1fa314cf3c866667cfcbbb5b57f2db74fb19e5e0ab5683efda06a93631032380727b6a801b309e8e810537ee79b47e8007d436502f14e7a898d48484c4c8886f0310cba2c14612e7a22ec88bb5e9dcf865776c37cd5b1c6d1b18798be80b9562ba4752e1"""), xeh(""" -26CC4F22E035BC00687D557655C46B6E1C447ACB824204FEF7582EB8DBC704D7CE72B0A5FFE54FB89BD7B779B5B1DD1573010B227473FDEFFFB74DF7DCC1E6B48B554563C6C23004AE2CB1996943821F480E91081F1A6765E08A8AAB7F203E95DEEA49A1129A676DCB21540D2AAE1B21223DDDF1453150483176F3EA3580CE631FC85508690D8DDCBC9513A4A5951A440232223FB2ED9E0E5A8ACFEE113D22548B8E98131EE1F45A33656F079870A146F12819BFDDF8792C3C9AC3BBEA3A92B8606FF2B7296DB9D9782C8E788AF4C961840041735DE456A35E5536D861CA118D67408E84D8BB9128B65F2C11C7147EAC928599979EF195A7979CFC48277CF1FDF4B0CAAEB3F8A172A3CA25A3A8C39AAB4495A70E0AFD3861C41A8C01FAD1E9D81281CAE1C33572BA4BCA9A5294000FFD040545B021AF583F56434ACCD4CB7B788517243B09737D355ECE53273FC0C492F251FA02E47EA846121DFF00CBF2767D4DEB25F705591D26FB1B6F839A58EBA4572745A618CB2EBE02CC0CB1C62AA9F0EFB794C385BC47E440BEB38BA742C7357A97CF33098E2EA4D823BD0B9699FB1EBFA806D64FAB18E106D4A97B23A889355C7A2635A9D3BB330A1B8EE5E707DC32C20CACFED68C8DE783562488A64400A4528EF568D833D73E456A9AC22431B2C22441EF5BCE3E77CCEC99D2D1C092ED8A28D686214313F683D4A020FA714459C36A257DDFF7B19B7ED05A16FCACA2570279A11E1439D07F2F23B88411404749C37836585182F31AD65CFEADCFEC3FA905CD4BFE2B6ECAE99D469F3EFC55615D45D19360EBB7C68C73ABD4562EEDA283776C887E70A971176DDC10FC399EAD6B9E247353C25289C0836C626E5376326FE5630C3098436556D61F5C75DA6057008A6E1D50B4F270FCB86F868D5F235428B4D7E13010D20175D4CF0759F56422CF955A721792DEB8EC887E5225F6E52CDFF40B8BD3FEE4DEBC7B363574FD1F3CC113A3B4281F4E8DC3AEBE4B67500ACB50B5DB1BB64F0634B19D4612F597DE2B4CAEEE8A3258DDF8436ACADF3677B46E7E5CF41071DEAD3FBCE2A73388E19AC0C7748E10E3F586E2EB844ADFC079EC0A2CD8C9BAC8E859460DCDAB688AAAA179882B91111A604F75198F55B17C79AD4BE3FDB493B59775ED449BF938B594D87A1C9F721D1C39868591496E62BDBF5CC2947DD81B65ED8CA0BAF0A64E924B5F4FFA88BE86C3594EA7472B822D2D84CDBFC7A2C5039FEC6EBB14FAE2D5D7E9CAF1C2B8788E7354BB6A12C4EA1ABDF0811417586F01553AFD9D8B1EA233066023BC45FA4BC064E7D289AE9DDAF1F985E4BAA86C55BA1F1866E010C55E166C3AA29A682A81195819B7165DF6CC72045D143135EDABA08ACF9DD9FCB8CE732F9CDF1A99C772A2EDAB78647132C33B80E7F03C84A044491B311BC6F3571E7935C6EDFB283BC59F29DD5CCFF9DD6A9640139B173E64F2755F6BBD977F15AF1524827DCE4C2FDF1EBB7C35F0F34800E5A07FC83821FA6CD41695B322F0909D55251372DB8B3CB147FBBF6264BF764B1A20BFA41EFB84D109D4E374564C760AAB66EE823970EE7BFC1D9DB860840BC4767E4A46F1855526A7D902D4FA954C7F337C7C1205FD4AAA70D7F5D904F1D0CF1DBFB63675991B26B590260714920A7249E75D21199D8C002BD702C5398C45A359965D367FA15A73B83197DB3BF3AE9E987479CD81283419E557F993884EA4F17996CCA39FBA8941EDD70FC86E3A46C84C656F77E9DFA5DB31D8761A8FC1D5A2FE9C1CF67DDA1408A212951A5A1D5E9260BF367FD824ECBE8534AA5C63F3E9E2EE4EC53CB42663A79706088A846614B10EDB58B45BF063ACEF64DBB5ED8808588B51A80EC327B95DB34A2107FA96776F1DD0340C7918D0B846883EED35F5730D67165D4A51DC50533458F045E1266CE5C1CA6A30D931DA81732A876987482F2DB58694C574731E92CE6F9083A5EAD8143F244A8DF04C6DE1B2B07ED86D5593CAFC2A7B3E819C03C70B7B32AC0D576AC2E2E5843A39E4D36EFACBCE679307A1998F9C9DED50BF39CD29A529A82F26B5B4538F9CBBD547B9E4D5F7F31B555A8FCA1F9ABDEF3483640DE77D558735C15A588D944F9D76B06E417B1DA873F38A21321CDACE8D4BDDC49EBA4165D40820BA19A437D65B337B8C037041631D09F8ADD1400524F4A3BC33F9213AC7926548B9C43A4BC0148807D9""") +6828da82ecdc732f9f2bfc44c3d6348f43edd227f8de2c883b9be7f10b00fd82d457c2cc8c8bb275ea493eb0bab179eed34c870bfed6feb8de10c782e20182e3525bc437fe2d042807afb232cb9d93671583781bb83caa6205c4b7d800edbac31fba90c06ed3cdaaad0a876ed6b0b36baa080cb98709e2bcbed2422dcaf3dd4c43661b71996e246ae507c6abec79be6cf0569ab80e959e4efa0f1fc70ee620595ca82c77d86f23f958f7696f3d02c98b4fefb8c0605211df49d87f03284ea641f66ee2463ca442872bebb75c69d3b86f5e0fdb4c87423464362daf809a818f4a6f123c852e37e5695113f200b3a5563863942f41225d11277c456d238815a6ac53b4d0af38d7ab3109991ae2e36fdf04abffdf4b79efa8b10c52029dea1ea3119681531451fad6a51eb06ec1d162cdc4e11d842e283a7bd4be32cb8e2b086d45484710ab0d23dad66816d914f1b69ba17f9fc8c607bf8807e17f615ccc449866103ffa2c72cbb7efd44df0d62d6c2d8d801fd75e3bbfb5ec7e28498719c28a86cf1d69275f08116125f1a72f5a6c19b38da8a3561f8cfe2d4efaccf39f77e9e7a3413d6a556386a5350f62ca7c33591f94c7853bd6d4e5256a13ccf4cecfd2ba450ec6c03d7a3a48305981634ffb33533fea02d8100eb1ad574628a56f986dbb5eb9c603e52d7327490212ee4d1632ed4f5f85969b53d3549c63d73eda74479a2e9c91239b30c50aba979fb2f6209c35973822982ab252acb8138a0e574a201249fe2e0987e37705d714fe74892dc690e4c2b8dc6493b55a75d100aaaa160ba1e5e71af05400c35a04f3b76d103ddfc79435ef7e83f2db5541ea16830d00554ea942dae48b9485182634312e70c4f0de7a9a9381652f3c6732034f768a07883ed3afb5bad9fcf9fc19963db92fe4c23772e5d6859deca5359964597ec9dbc06c0b988fba9c26d03457c89cf1418b5c2552e51fbe66a5d49a39d69279edbbc01c8dba250dd2218aa0bd60bdf9ae3c22e6e4cbc2b074818614be6a9e6acefde06b7a734efe82d061e479fab45d255381098d7672007d672df5a08b0d659544340de907aa63a803f188c8ecf09b27ac79dfb10ce0ddb09b71b14d839874cad31af07f6b13e4c6aef06f79359d131db5f56653fd135b0b553bc03cf9c8c24847239247c6b29f646e56c08fa9735c218c9f3ff895738555640518fe8f3a21f5752a04708ff5b157a5f725ad3c0786240b25d8e4033028349691cf58b5a17939560ea81e8d721940405d44f6e093c46946e496f2ddc4fd77c0e059138b5527ff2809b8f415f00049d07a24c97e4162c2023859d4b1dc18e45d8553a478dc9fb93427356bd77da7e641011863db2158a75ab3664496ccb0dbda445faffcca2d841438d6988ac1f636993d833cc8d44e7ce92108d7b904a59944ff47312f117850268bbe7676dedbc5bd17a8ff5040107ff13b61c5280be9d21b9d9c9ccdbbf3031327ed1d2a639c1fab9c3688eb514be79ede525d65408c913cf936d219f0b8d46d4861e109a80489a7de53de3b55809cf5e2ee1d0e4af20416c51d3d4d5f5a94e42279fb39af570bdf558527f9df41642cad191302d3c23d5f1a819996dbbae5a29e44dd9edb8a32f703d0868ab6a8d6714948b6ceeac635539ec9baae0b365698065c5091275002b43df42cb83447a7e26fe865834070be51b75e066b00524505b01b9005c346e662b874837f53b9996effacbc37ba75d271f3af3de97d0c1f6bacd3c8394c7fbd5218e637089175b74f493f7006229231c21688721a5254498fb616ec915d7b5f04ac18520dcd8f6a025c6564e6109fe19d0a746450454f76fe192e4e90aaeb38f070a65b8bce90c956ba2c007659e2d3d729ddaa117895c8e0fb8f757604bf39eeef565ef96ddf146a7a71f0004dcfa36a504701bd3d36d1444dd95848b7a2eb796dc311dce1b83ed731684d485e1d860ed2573509c15a71dd89bb0199f92c54636222ce4ad5c034806167d925b47625b00de711455c077abec03568acc201af169d36815c78c885604151973b305ae5a80f0cf5ad11834a48b8023ae6a4f0a60f087dc96fc6fb52167f251a3308f09ff1ab754eb87356ab68f6dc88603049479a5f2d535c10184924034b51e3824b71cda2373000ce341e0199781074a869953386a6d0ae36b6f692c38913ff9a69c061042612a80bbb4f9b4d39""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +9a17699301bda8f100aeec84b6c2ca606648db979a4c7410f29c28d6c5ac1b2b86f6e8a1fe878a5a7014ebea98d9069e88705f9271422cd62f51579357f5035477ce73c2cb94d422b921b5efccc962a81f1ea74f57c8457023887b93c61d02178cb5833c2ab733b00604a84ee3a556032063685a710df1712b74aee69007f1bb23bc7b2930e7c54224b5a9f3b204c070a2fc82cc5bb16b9602c37a659dfbaa31976c44619fa2d8997a08176a4a383761c3295c114a2965b1b11ad32b4e20b32b4d39692772c173a1c0bc45a87a7a9e4cd86b537a226fb165bab458f5a46ab0aa050338a94df46d46a31e059382860bbac2ecaced47959b98213b2855553b351ae60f4a2653571772e0421cc9f78d34500cea44cbdd5934535678cf642594050babfcc176e30325a96cc0b360081bb9ce618f51d23eae86c8ff7a4bbc37cd98351530bbb8888264c46ccbe02b4a638ca614702238a240c85909ecdb3994d8b1b34ac30de4481c08944f454d95d761a8a05b024bc563f5afde38124916c5f4011a8fca0e44eb1292458f1c72bdbe15c2812b017611a09de22942112df5fa8b7b314c50aa4107828ec70380bff6750e5963581b9c26813ca81b5a4c7436b5b5962169ce0047bbe6c07f76a69cd4674721c2244a09cbac849c3dd730167233aefc6ee7b72b81896b56279d9b861a97939057cb4a2b6782ad485c597932963738abc022b5b2c463ea1dcbfa4edec34bd1595363a7800d6c32030ac6aae65ca671c896336f07666aa2f9617e924c08e93084586afe98b1ab184f951a1f485943262728e1b5c7c1209a02c247e24caf0f74445a22991fa1624010a12dab52ed45523d28c5d3902cd77b87402bb3e9d6b422ea41f033364d645cd6240e2813c8307347a0954bc3907c31770b9afb4e1d907bf9da59da9cce0e8a1396879e3706662022b67d489e7a501e46580cf7c4037573c1d597b32b92caf8b87106251e40e897c491072c358aa0723f942badd4920cb252042b330a9283b6f4859494a453d22c5d70f03d75b93495985c6aa0b0c7093b4b103d4efc4dc3d079d4d2b23ef44c5b002b41d80f0e45919c76939df63ada491ce4a4225ed87487d1931cc28b3b2658a6c46704aa327dc3870a7067c6114ba86c95ab42bab5690bbb171491136db0e50266595faf8a171fca4d9200052a668590021882904365e6195ad2bfdbc26dd518790ad447c44a28cc770094b738ac5b9bc7b0c64e4cca7161a99b2c26ab28535514a277c983c3833f726b9017e98a53a93e27652dbab4675e304bd2e798b50b27aafac6386bb70367b58e2853d71228b19b9b4a747d6c81041c16a5947a0bba44a26d761a2f87a66d4bc272ccc79f1b292827a7f1e93a7967b563f8437b859f911176849b33777a1921d73e5ca0914f137e2159cf4ce575464147f9dc66610abca6061127d126264326e4e404e5fb351caa251ec20808366ec9f447673a89d52b521b54a3d87184f4aca669f16c9e48be599060d5d82277163d6cda0a2d5805ef65043ae704d992839d28a1a49a675f843a2a063f05cb84ee234218cca032f32ea8e31b84d59506312aa668130579cda14cab0808406df9b5fd5c5679c92053d1769830c5a565b5db96522aa16f9edc1aa638073d7b875a4c5989d57be049a2c52a51406958bff911ae72b90e790f9b21ce15400ba4ab0fffd00cbcac8e4c6bba6543ab4da9488d6017d95abe7e477901ccc3ab935d67086c2ab8c576e1a1af4b9ceb31857302a91bbac2d02066681a5464eb0491b893f3611a94e8b2140ba407eb074164bacf341d4b375e143a57d149a424f00fbb5730646a6bcd1b07ab25993e29ac7f29a93c954b796830a4848b78c0c1a40a5b3bd3c329d33669c07b47154e2d2c129efa6d46600e3655438e98243b02a1ce85c73b05072652c9a68072c9b01088581fe919cbc55b859631a42b93410ea5493d8a1b1b36a1f200523bd2bb6d5993a6305610fa20de08b2302b9e64b5ccf76274bb20279a7b4a3e39a498c662cf6b095633ab7ca05977c36e55b9c20b226e5c648bddc3ca6934630b389815c38b89c8001933b4c715cab439c78fc55c81d003065054d5061d1d80afbe083ff9071ac28c47b1ea8ba836961c97ba6039325df1b79bd51b66790760e74b8315a75f0436c441361e37075a75830c1b0310e763205645d482c4870336de131a6cfcb2435119341cadb7e70eb3a7b7207237c654814c9a6e04c5955e5135c9d311786802df76bf33c37a04f84ec0f9311ac371664ca11dd56218f65240b97819165d90b113e955a19834a144e1ba40f97cf815b90b4cb7b06612168c6c46e11d4d79857f04cf00bc8e11b930588216e7ea3a5c99caae7b076a4680bd76aa3e1b806f428c8301641640b938743770b5c1ded957b8b1aae1fa28e6f19a3ac59f50a59a9a346766c9ae68a5c920b0377891511cc3b3fea22a0b7216ab1c1d8d97139d985f13345a073434150083cdea7977d9a5eae98314d6898fa14e89e4cc7d417d4b060baf854840e12505fca30bdc0d60a12fd30bacbd62287533aad397c208b0bbcd50b8f19431fe727460d754668309090cc81d8b7946333cb6fb890e152069624a923476369879f04771a0db28002ab860578fe351a2a1a2a11c198dab6b656a4580caa45e45d3987c4445f312c4d14c7f70505272364aa8341b1753af08040af6501f69e96d108a48ad245ba2663aa154339cb48d4bf55acfb9534ec42c06a11e4d4b3659f65ccda82661b1700090187cc57b17b50d66ebb7a44672191193dee20e9ce21bcb36be9d312941d622062c7906f5ccbeabc861d85ecff006300ca549043dfccc4400118a18b49eadb276ac45469ad69ce16c60bb717368d6c7b2f068bed1b2fa930552731444f08a239bb65f173b7e61730c68bf39656ce5f7425601519a2773aeaa3795d98db1146912683396b6c9232b498b9bcd3adc70f0935d71e56737a422b5792f75b12457f8817d926c44f8a8e2a34573ba7228204cd5ba24c7f245dfa0c1fc50be04e36f407043a4aa7a6f62b271ebc30bd76a80d242b934cb8448535ae51dd43b7614a736d72c14a577915f9c6b62cc10d0315442614a36f32d94077e65978430597a6694410888299939784237c991262d38a540a5e84f326906a7883a6ac3b05bd6051c5a11ae47809b30ac9a31226281a39f63be3876bbb6a896857a5177a94b8193acdb441125236c9cc291f2d7bea99025b282328c571e93f2bcc943b3d1f6ca4e3784f4314e570b48d483b6b20b9dc41280610aaa3a345e2645a3afe5b4f3b507b9c1a3502c84f581617f2449035ba524ca6a454c87c57652db9535b926557a19b157fb3f3896116ac1488a000f20c5251017c34416bf6d13c178204484c83da35817d0975183170a100c0b24404645d7b551ea24569c5d92235e6df27b105c065f66b23f4b119e5aaf6eb9ad73f3ac55826faa55021ee116d9ea096c350ed1c659751bac4a57c8c70126e736ba26f276b5391096541236b3360d9b76bea1b519d141f8fc9f4e8411d02702ff366aa7e1a5629295de395eb251c63e5170c1db22af621dadab30ffac21a9b400c8a7c30beb194f027858569029b19e43929901e18fc45c1d7dd6b464b64b14984f21286ca02124beec214d354ab820b4e4aa8a26a35fded6cf0d95a26f20123a909a7fa708c74580b7984ee082a05f8b481086b109d61b26fbc171844bc29c0ed42bbad4cc167935a9d1524a4e162a4d598a6e23ce1d404cc4a5b9b80481fa3b1e416027a590880b38517ee34e768c61c93cc170c4c8a8d3abf3e79ad2b53e710cc521027d2b8366ba7583e9744d68ebc33b4b45b8f04e44b98f890bbe3bbc0209d93a9d6140e6260cf28740fa35cd68513d4b024d5d5463d664b3d11a261d5bc5c1b8ac71f247eec4c66b72812c308b3b93a633b80e2ecc502813cfb4339c24ab91129c93b56b4d87a132d835986e994bf61432dfa98477dc70f7a66b53f88843e86ab729b5f79cca14e2263dfc868e2b81432bc47fd1aeac51c3a1d49549423d40a86210317e39d9ad15019e90050bcb882ef7dc09377a961465098d357061f8549ccbc7f951639e3a73b3e7a6db109ae463ca41038fa32418ae4777372121a5470622964f514c76c108535d7913fa16954d6668e2e01b16b492dce96a932532baf3a413a3c58967a46b80c5acf276e2a86cbf499009a5685f392dbaeb4621b66d9f1a631a60b59d03a8cef18f87c9c2cfe6290130198e67b8d095019b0484e0d274e488640db473d1402929cb501e9291cc428d37c0264d1c3edaf23921b66855f3b90ee38931192e0b30d24650e4c7c62b62b0bb885e610e1a9e542c7ef8f4f03f8ec111302c342652fbfc5c1267c0776f8f71fecf641804590c1fe43f2ff453bcb84289c9ed5bf4a40e4ce8d367598819be8ec4ed706df4d26819f69729c2acf274515c8e"""), xeh(""" -B36564F2BBECFE4DD315E84612BD765E3F2E84F5D8D86FC0708F72FCAF284A0850708CE6E11D0BE154C00F930D18C0A8D8071B612556238A64B679A083B2FC1A204079EE19A4095E71E0EED695B3CA764F4F4E5D7366430A8933F0356DB074C2D68048E046481E5481E4F5A2F365EA9C4C7A6BEA51CDBF1BF31366F863327126DDD101F8220034FB4A3C68232C5CC84229EB1E35F19AC2016A8E4805A87797F940B72A472F129FF5B751964AEEC96847B0BCA5D7F391CA9053380DE83CBC31F341599FEFE36A1CD83B30A1B7CB588874CCC5F443F73ADFA2CE7E7271A5726272A7E5FC721E85D9755D672F5B2A0EAC8065D2C3835B7F0B2F7C77A27AAC438E345BAA378A572AA676632434737FA59A7E197135BD6AF2619A828AAC865D7F34AFB771BB55B5B7E93B9489AE98C694EAA26C6A86F41D0C53522DA4D90F2AB267675BABFBE963C4C68534A24D1EAEA2BE97702E28CABE5FD080DA6B3C432EB0E55F9FE8C1C0422A44F57002A1F96E6D53E8AB9539E909346D150082DF69F54D27017B9A7633B7BD9F7E6274B1F97D7CB4BF5FC2E34E77ECA1317E7854304C75C388CCD1386C694E93CADC856E136C2C0EE7E113A125C79443C5D1A80A9698BF58248B0903A45961603D1EA0E89E3C0650EA3E82368A6C477CCD1B0180542401BB1DE70E25F64A5DE41D62D0467353EE488E1F692EB60778452B53088473B084D0819B725268AAE752FC8CB56384C7AF9D319CAAEC958FC3EAEF57E0F35F1BFE1BABAA2C64A2D9813EE16F22A94C1C00B29EE82F11C47224A9C5424E647B9883918C9CF2CAF51B7FA825121C5D13ECEB5F66E4EA11526E0C37DBCD464C5BA78A36A31A62B2DECC7DF51C24843EC2325C74A771A7D73D35BF2AC4578932A6C2A7323375A2B7679188CFE804E5EFF4A04B7E14F8851770048F076B32BA4F19F4530364C0529EC3FB2D0DDABDC85DE2257F4DF05686AB498FDBEAE3A1439627DD8885E4C8744156C2B155BD2F965AF0F2017F163A6016C274E8532CA43C784B7AD4747A58253EDFB739D68E376D7ED246E5474454F463F4212090DF4F4D7F88C097B18180B05F2E89EEBB834B9BB6DD9E5F6036ECDD5908CA4962609C208A557A36B7FBC72158A6D86322F4303434F6AFFB34527E47E0599DDC88EAD31814646A81188E79E1B6D562E01FE1EF148FE8825758CFA5BD7B738E3BECDDDCA4C59093CA24581E531667DBA2C295B565951445E410FBC99D795887BD48AB87D6D413B64957993CD7525A0A0A5D393CA1EDF7788E4DFACDFA7B394B6163BB948C9C6779BDDCC8F26BC073BEAD0FC87236704A0DC0D89DEB4F8174E91D249C4DCD9260BC7C86CFB35B985813E1689D83083949927303741550CB782E256E79800F41B5C7D981D68E60978E5190A2C51C812DCC3952AA34212625834B2F8CF8CE8019AD6CE8F00FF910CCCF0CAF5A3596AF8DF947EFDE954F361665458F77787E528937BC52C59950746C783D8C5216570E6F0A944E6BD661F23C7A9AF3C602DF851EA2E5627186A6CCBCC470E07B290E4F754D5A8D6BAD8C34F39B4BA838CB467681B0173C33FA51ABE122BAE3DC06660950CFA5C228CDBA2F5EEF2613D2850DF9B5FEBE7333BE93F90E4DEE219AD18425DEE4006FA3009666C83DF7EDFB2EA4F99902C694248F9D51C7B6FBE53780EB218732C11368C33449D051489FDB01B1A1064FB06DED747ADE38F7A12DCDAA92D64DB4C2C43DFE53068A77339E1479C8C93192793B1C752FA7FB23B57DB5B428622D27CBF608CD7406FDB543FF3BD26FD7ED7269427C6B93491BE6724D071F58AF434FDAD2F0FAD5730A60F3EEF94C59CBC5884F36274C4CD984303EEAAD17E1785914DC804BBAF35406995E3D56094F0FDD71C7650A6C37393C0EF4C167CD2FBC28EB4EDD34B5383CA3D1B89D7BADB0270065B5AE2D461E6DEE53291230ED3CC3B616A7E8A86A4265A98C10A44066301470BBCDB257F35489BA5DCA320A390AF23CEF6ABA8B291538D9C4E965969087E394EDA44C060E28220BF72AB98F1C055159892DFF079D283C52997DCFDC2FD8291FFDF322809BE3CDC113DE9D495EA5F9FA5DDE5052192CA6F26BD510433B197131A7E954AEC5E58F0A341D7E4602BAE46BB1987B5C1D845E6AE5569DC2AFE0C7984DDD9B0B184CD6ABC0AADF5E13E0F110E8876D572200DD837FEF193278119B861C196C7522""") +6bc2d2cab5f1a65e54cef43e6e70d79e001ef07e360312b952de8f41e1ab8b58ca8926a0e5f037ff2c7fe755b47e46a7f28d2993d22f0e538415adf94d3dcbad32584fc0706fa28bafaf0f29ae6cdc97811406ca855f7ceee962c863e0b3cc1e107a75d213a550265c5ca4ddbc573e3ea0c7fbf5f7ad15a470b71452ff4af1c0fea5b9082a210988b7374b1541c6a36111884697b9780793b1fb755623a3e2119afe55d031d751b24a8c77f5fd15f7ebec6f9bdd4debf944930afe82e0afab87a9f7629bb146d6ae4135e1a3a280479347c409fc5ee0f811a267bd959a9b476e7ec49df9e616430451c56e220d49f4271b8e8c59ec7d640fa582683e42d7b07d5cac0aa26eb98c17e7c3c94a2627d1fb3b76748856cd1a5c5e1f6b0b1fbfb396c681e809a60090dabbf2021627ca06950216cb8c5d51e689ca76ef9734b23e3afab0069982b6e033b852e7494ce6bcf3812ba88a24edf15caa59b1d2ac146b18a32ef7ab377c12a44e0809790826672610d212f675a42df93e149a18f610ee55f68a08b350a79416174a488618daf2ec8c93f1f466627dfaf870c293e4a94e38d144cf38c2ae4949384c930dfdc17c9165d78144cab97daf68143f3c40e957220521dc28f8c82f3e14091cfb78a5ebc4c481dc2717616c36ae8acc74421ef4a9d88a4bcaf42882e39cff6a0eb52a9b6571b0c2c9ac18fbee2e9a8d7c17d2008912f89801f822c28d0751397e5283b02c70b33d736bc5ef99fa41348bcb68238b47d32a915f8e0999bf9c5e9afc497d7de87fc8f78ed60aca03d5831316aece8bb1bd5ea82ee05694497d90d337ec3142ee6614971f925156cbe074e416c9e052865910f03c9057c8fd6c8cf12c2f03560403d73e3e96e9e71994f03d0b8faeda1c866ccbc77feb536eea7103031b0037e9d0c4d6ebaa3db432fd1258fe7bae3c4ebb639ffc7b7a5660efeda0483ed89a256041cfbd8aae8add367160efd72a5332c8386725ed754fa6e2057ee5cc0b3d0f87961cc2e22065aa1cb22f72888ac5a509b9f302645bbfa64eaf2825c6c30f10059935bc7a41be3471c7e8dbe0922a1d6a8beb91b21e2181c9900c93caf5640d8a886312451b7c620b0516fef8088d9ab966559be634d965df184fc581062fcead1b9675a4c620ec5c66582ff023fdef67153de6124abff36ef884ff2abdac8c1b29425616b6ff8893c2ad7cde0f2a0140baaf912a1a158df9fcd45104766ca3faf2f22279e70505e6fedd1bcdf005d33d0ec89c8f82084335e6f69396d2ad1da31a577c64c3c60afd20022067af6007f7a35e8fb410cc0e1e906a9ef77034096e8a4f32544517f75e3833210cc8e5989f440fc1d92e2106244c00ae40e566080be0b2d14544a02e950ce73dd3653168575f8ab0f6931b58cdac707574a432bdf9d4c6bf2b61ae8ae4dc54f7e48cef7639b29ec5d918a06f468c8162cd7b33a627bcab108dc94a4976f1be7a9b376f8982de227462c47cf07f7070816be5256c59eb2b4ec6268fae1b50978722558abd117f5399b071a5f7f878530dc877394e9209c7e4f4c1b5c417c402ccf0ddb247b07e203f71e7a94b7d41ce97755b983fb376e0da89afb76b5df6f166a822b15c7e614afdd9c004f1883fdc8ca12c264892e1d82ae2e675e8d5c9ba11836ea336150a8b49f29b0b7d98122cb4fbf6594723de1f1cdcb4fe0a44976a5b40b087df6c30241ab081b1313c396bfaebe92021151f8e2ff5a917458afe820f9bd709b4c8510f3801e091942c626a802179d704bcd65c1ee123fbe72a68012dd5a98c0d97908b1484c56ff7bbebcfb6d2aa1426ed7c901d61f01926d348f20a35ea40a186a1a16cd872e9bb53f0fb9f44dc5f098503f9115dbad301363ed7d60efacbeb8ff02db264b9b23baf595f273360d093a36f0276154e88d413cc6cbc9cf64d133eb4cf6ed845827263cde49c116c6e6f4c25f8ce9a611ece5aca8bcc348d57a884ab926c96251e534a5313e52aa7b46d61b85d66c5edc065c7fc6a62909257fc8b6c0b171283e25212e3a96224d7da12ffc3bf303f16f5dd96101a7b816b260774a22c449e25cfc991ca4153a093058a64ac5d3fe2113646f598315f3e1e54bedd65680c6a2614e1c8af922519fac6bfc0e589bc28e3e70b53dab591e6a8942b2bf62bbb9a18c09b20cbfa4be5d7cb0f2fbd8fe948c3f2d9411845f61cf371""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +8398ce8a287994fbb98d1515027626ad0bbc20d68e8954ac322789e8ea8264e6b060279df7eb3109f63d68d8126d336e1f0ca4dde11bdbf11378d0ac967063f8b91563ea8ec51346e3b21e886cab1d39b368f77cbcc021252299d8e5a571f74a9e2a173566194fd161bf1850b24925fa85058da68f4720626c3c96c729cbc7bc7798d3725e2411eab78843056904b6b760137e790b0595960915a4934351ae7d0b098dc9c603e1879efa3685480a1a3b3492c5bdef811bc55c28e0ec9ed2546512736552427944a1bbe21593e8b630d4dc25ca2b31310423d44223a751bc11d0b9d4f60cdda5477e6406d47b7dad2b9deca294786c41aa4047ae664c86a05128eb1916b6999c12499e3993f4c15200507b51f237703507db46a881f4630d079cbc95825f91a89579ba30004ca7478786d00126d22759487ffc192c2e77c81d40a05a33b613152a91b15f293027d8354df9754abe701c89c583858627a50c5913850288d07279865bfda15750ca82e7db9dd2ca535f882a75a6ad8c8a51d0232eda653e033ab3afc242c3e77940258b355554a1eb84657bba96ac255645373139b1c38b14ca3c773d90012503579a69c0e42c4b263c23d8dc6fcc09491ea83543028f757838fac956e3052659ec2f6c66380d9b51df627e7a80560a4728c4f583a4434eb8f38a258117f88639669ccc55a67e309c2e788319ac543966b77fb498c43ac6a2f7d02d3d88b4dc85a57aa17286947dc2d7a40088c26922cb3b0a53b02074621314f6c4c431dcc6af3549ec5158368155ffac9bc31941b8c60e2147a73f61183cb67fd144ba0090832958056a65c88eda50518a54ec637d8c934a2230a608e526b55b3b2c515fb4db3ceb528661e17b2c44c1b1e5a7763cbffcca5211321f4aa9252138cce7bbc1e234bb473a845775a2fee466195ccaf6e8c0c198c434a389cd8577cef4a800a984f6c002397c3c2706cfe96743520ab2a9257206f8c6cb387bc4b8ca913a992616296e502d4aeb8ac5b96ce5e283b6b98d289a2097b02007e17d10129a55dc0e41781b8cd292292c542a2b9e180a95aa5bbec8e6a4cda47ace3536e8b6c6ece51537551bb1d47f82f5c0962259fc4909cd85b2378a4d4416ba2536829db4c8e1f561677ab24f21b853c93bb6a54111583cc7a6721abb300964959ba667a45508b81b15b2f30e6dc2562d5131f7b7255d4cb769c47e05a9509bf2c3416212dd2a3cfa788b76f44692959019ac16f240892eda8807f93b86c6c92c2b595e55c349463db2bc453bb137d3dc94c8c15f54221df02b8dfae58e6d49b87e71cef6e48336686a1e68cd841a49ed107e91fa26e29488d98c281bf27997c173a6f9043c024676ea75965b7bf5ac221a291ddfdb2debc3b2694c36373235ab8a7e1979678c6cc9fe767b16491069f59f6cf54476770528f84222f223685307df567806c64f4d334abc3955b7772f7446059e316bdf6ccf69b6169a52724e05a050fc4c5bba010089a2e35b8313952f68a3197ff95556f29c85d5a397b54f05c9940cb655270121b3c48e6af77e7a321bc77a90286548268843942b5e80514a01dc12c1015a8e1abc83e684e97274d7866f513a12aeec103e59bf7a6b1bc49672fa5486d2eb436acc3a6d356a1b238fa3a5648dc9ca6821b902cc1167c52764426783b3a39fd5285fc142859637ece183da73c899b78b20485ee80a502c419a70db4547114ae71aa6cda695310459d67ba841963189d75d32f7a767a1603567534521cfd68511e23a1728c693ff316a1a21751162501bac2f6f97548e0c5eff67b2fcea8814b12c38d4680a54a1a28a64c159521ea08c901a0336355c8fd87b003c8e49068455c733975512e516b4a7c542f2592cdc7885e1299e1ce310eabc295dd0416e673e564c2f37ec9482f880d772643c779eeeeb0c8a06606c956b2556936c7ab0871416dfa9a9465279930621dfd4bdc4548f4715297ba30fe4d9a23f460fa4c00e61335ad50c86a9a707713b3ad32aa7f45a2a376184be72caf154b3ff93b873543c1c5c90fcf77f0be2b5f66b54ec6754c7a50ed0fbb99f720f36335e634857fc8c9e3b1cc8bfa5b53d371bd51c67ee564855c57b3a250022056868f2160cb65b758a9663438fccf2c39b866062f668d194a29dd1c809d4099084b07199a5cfc53573e6291a7978b848844c008f3fd45aae742d49f4af1229c49189bdfe177ee5c2c5315940f0024009eb4bafa5965a472d87767d4dbcbed6f6af41307cb48ba8f9828f229160df4581b59617d34203450b0426593947fc84d739784528081105c2c0fb9a7af8be6045c8606cb22d1324d5abbdb773c69f4bc88fa15e136509dbeb698ea0bdfed69f8ed67477e10244304f866a912d2c01bb4c428081aa46b862a6d420cbe7386596c34ec87f11084ed0493952a656939c5614e6afe7a022756621b77bc27648be0e86a763e36f8015b9e5e68684f73680773b5d5a9f37e90186fa13c11604e9f231ebe02a9c531370778579649f33c70e4be811ed668e62d28f67f7133f86695b790bfd2a39a0f22a49195ae4a40196a974a1b3424f4c574778b0036b21b356835eb2a142084aa2b736e4a810f08a2199c86c3e8a5ccf8386498592ab3570c6677ef089c0d05b06ccf4049314a8b29c9d9c18ce40933cb857941cb59abcb499ef53869f155bf2f4ae7e1c3e41889bb0682de1b4ba1ada65289669a55807d10672fce9142d1a8a7ca20c332b4064ca8a1fa5a8c4a898c76cb837b44013376fe1577b0104c95b3757c40a8c70d926216c4e9cf072ce4798b8d38776b3786f6136dec4b9c3a35ae088905df969ece6bd26572c91d78242060c54c9573a789d5110b25db9a5ad1474f2694b31553d3dc63d69913650287f6296854c46a10a54acf869757de3bb21342d26825a34704966e5239ad16b57458ad75881157988d5b0577d432b89ec573da15152e89afc7cb0c587a3db87bfe0db286c528c4b211382172064c94210f3b4c698124d860a13e12b87756bdd0002423649d7e7a1f57676c6e53c1ef6bb6152a932a110810ab80c2001aa53cab449a6d8b9a734e48de8f4777fb7c6f7408c2c8928f72482950b6497c2500af7568d514c4c34151f6749a0a6b79ddbc12e03c5563702ea733ea142035ab4149bb58ee56970378727e6215607a64fbbe7888323bb1e265dccea33d1f96b8e797532249092a202f3f9c9e7026483e78251cc57c1977c1e5a4ce4f9bb6eb4983823998101a58b0b785823b3352c6a5e2a8660fc143a5c2653e6a3920a8d75c29247a846f578abf56c2dae289e62d1a581dc561c946f00edc202222e0489b697c786ddd18f38a937c7f9b9cd0a3d85a9960ab2b470e5c57fa15991e74517fa9757a4a62a245392f3361f7601cf0040e391808235a593a88662895140e468e88ac4553908630564e61a89cfa2c2271a27c848a08b97adc0444a7b72bc0051695e197c91eb4af7ab869a4b9325ba36d3636645b23660b0a101eb0af171470dac7e4d72c53bf4070706c840f11d8514913873667f7ac5ffb6c011aa6dbc34c8bd22c597e0814feab71a99b2969b8679c4368282bd5a109781b02561b59164832b6096a13b204de5d8592b9045efa538072331f984b42f43a44d4ca6e2792bf26a4beb24089d046b13c25ec3612a73c19a8332a9fff70d5ff71851da2927a13942e8aac355582fa347920443f9a76c1d942d624c8b696bc3825675a6150cc56b0a3e5a19bd6782ce9781f4f2a4fe6b632de07047828713b23d98c91c99091571d90c3438c8b64592ffd747f29351d8ba91a2d6349da30247db82e2051cde3b0094c4aedf7556596968ae6acba7a790cba9c1de26689cbcaa4d61bec738a17f33b666764a2ffbafb488530f0c1b93617be1677a53cca42908c8c7a051ecb6a894273becd75313420b3d763a57ccb7cc73c8e94aca79ec03873c2ceea96b16d67c34c99f1f3642eb6948f4282e8d50ac30a10a47ab8859d54f86011a652913194c8b5e3139fb65039b4493a07a95b89177a4d1798d35cc1b10c9f0ea8b1afcb5ecb2841b143930c58ce8ac90b3b11f43837645a6b9f6c08b538a2b7b9272464b9707ab4faf9253012cbc985ac5594a7609a1b82c13bb886c564b577247f886382872d32102d0a31ed410942c5b1be910bc63b0212eb918eb0485e6734fc5f736aaf84467692534e0161c4258eeda24763894d0598795d48d99c56771139fcc016e516a29203774d038610bb5a57314a9ce0c677d192143d34c8b2148fc190f9514820bf8c8686a4413387cff6863fce50cc85cad03b350de7548972a4168f154337006e6873a14aabbe7a7f23ddbecee63d35e15fe156d0a508c235b058056ca100bdf10442a08ad6ba0238be525e8f98c76ffde6e11557835660824ccc66d3e78981182b43d78c40b828554c36d70b960a02c66490c15a4caa6a7d5f1e9ce34"""), xeh(""" -4B30E5256A941008BAD9BD14060445AD208769EDEA1C5B6E4ED506FB334A2378520B5EDC9217D626E1377839A18F2D21C0CC8902622E4AB79E83DEC449FFFD45A4CBF3AC253142D935DD310B5E4C5D591A9BD61795F8ABF00AA04EBAF96195B6CC7D7C3910FD7D75E25A9D0D79FA453178B06FC6B1E99F189CDA90276D6B69FBEA28D68CC82707A46CBEAB819239BE69BA76D749E27CAC9E5FFE88064B9972DB77C49679D6DDC6E6B03DAA0DDF0106B1A61141DF827E96AC542DC90A69CB316EB4F78C611C0155F9138F527006121DA16DB46531ADEC2FF599378A819CFBE3B079C9FE7E368B91A9E40F97A3E79A4F1F05574CE2AC3A525C206D9E55CE16D42D2F0F4863F896E808FE168B34A102BB81BD607BD02CCFFBA5C189497502A55F3E601F8F61B40A5202BAF9AC87D058E67B9E1CDEA0E4B02FF2DEED7477609A9AE2116512C42079D87AD74B05622E02979EF0A0F1D6375D93576EB6553FB1AC70ABDACBFBDB18735E949EC6D1667E978547A5CEAF2F4DCA6FF5D8346A960CE6925BF2B3F316238D6BC8ACBE67BC1AACD5A9A5D130A3D3B39C3BD7C1B06227A59BF4723AE9656D9922D9228A3404D4856E39702DFDC01C6E8CB6000E0779364BAD4F021BCFD7288CE7049D544E8423B2890C3083FDDB9BC720AC4C6A1A4EEA6BA1927B307E6CB72131B6B831AAD036A50A54608D106EDACD83EBDF104AA80C917314D295E903FDF36CD04EB786CF93AFF1279C2172002F7EE92DFAB3A99BF42C2BE7B7D0EDDD38029AB5AE18F5CFF8A2F1D2EA2EC7F34770FBA8A8BEEB0E1FF6F1C1A036F1BD84030004696BF4FB4161F252436C0401AEC911CBF1D7530D9D801B1B9B3A682329AE2F6930191E48189CD40706256B864D6F016597B4AA86FEE4F0E2362D8BCC743E98531EB2B335DE2DD299F231FAA808F6BC7D8F13DE8EAA30C5698D64E508D3534935B9941C2E40A458BEA82DAE4151ECF6DCD40320E1009BD9FBEE248F4EB6DB4437482BDFD83FDAF8367CC1845E64A23A310F904D5FAAD67241AA7748764C26EC881788D1EE0A39944071E5ACB656AB8CEA285C282545030EBBE6FB595E296E1EA37D7AE529B96CAECED11331D80C92D3DACDD7DC93237D815A9C6CEB9209C0BF3548ED1AD691929B2C1035E80A21477747E313049DEAD43A40B0960A96BF3C3E9BADEBC3B4D424FE7DC4DE5CE7788E31AEA3EC8965740D424CEB66D4A5678260051BFEFF09A3CB24C1AB7782AFBFEDE5EE1ED4EB14AD2A13142E8201CD1B52CE064F05ACFB019E21A73D84A80E30FAA48ABEFECA970BBF17FFA6F3A90AEF80EFA31C494E721231289143416AB9621737FC016380E6079EC6CD962BF7CC0750582EB218F869CE117D399DEF9AA66F7D2F07FD22BEB9E50B94CA5FC758C9DD4D2984A156748C52307731FC78F8539F8264BAD6DD56C0C23937A9A850E66BA298C3D39105ECACA9A573D887C9A4FE33D487F2126097B165594E1F8106C937758AB6EE75EDF39D2BCDE78AB611A034A72FDBEE67A80F3315571AB4DB94C56A19EFB63B8E7708566412F73D4974B160183FB5B6C44C8CED990B29C57BBEEAC5EABDCB11CCED9A17322B6EF197121B4094D7EA4A1B4EC44A68B447FE4C8119A6A33BFB66EA6844DB5B6094119AD1DE89449DE922B9A0D1253EA18C62418EB87330C6B33EEE02D4486F62A4D31CA24F098BE2F187CA6019025AD6E1C2FE69800D8BFA2C646F9FC6BCB3D369A78310084FF163D2065631C41748E7E3B25E8F2C9EDA2E107AA2046FE3F5DCC0A9A39FCE41813C8F1946C3AC07A22A6A56C4AFC626E68FF8CBC4982C1E60C3A9F288D1C4F2B8D7187EF2FAE30B77C4DD73499C2B3793B24014CFFEF6D80063DD1C1F3AC7F14FB61E5E81F850AB865BA873404BEB898FF7A2DCFA3B955DDB161B5781AFE8EF127BA2C8BFDBC2FB1C7D80FC650420214314023F6F65C17FC48927BBAE88D48D2E1976119C2F8310232942DD4C3AD4518D1E4DA9DD588691837122F5E5DE0FF1FA685DE134DFD1348CE3B5BE60B18BBF474074829E7D81AE087F149259122D47B728F369D1D8455EE571F715788C254F2EF438034BFF0A11F2F008E19B370BBEEE135A00DBE7F3C2970208F5F5D0E2765C395CA81B2FD80FC384AD046564229C759315B6CFFAD03A56996556E7714DABDE28F7A9BB5DE2C05B1F3596AF66C747D9A9313673F19AD4BAC6EAA7""") +7f0a07ea9e9359fa3b7aceb9b0ab5c41ccb755a103f6becbcb4d4a5a1b288add3448e1376688839a711536f82b6b1fd4b24294a074f0ffda82d2f8d4f7f5ef11068736efc9b9206c032b942de82f4abde3fcbce845ba7a32b4eb943b0f5051fe5cd99040ba07bf75fc6347968666c2afb8af6ffd55cecc84ec7858e5621d0db6918077aa12a475840c4258559ccfd14fd8afc65011c8862a50393755eb9ab5d297069627df3a673318b1582e2200b14fcd61b1ffc814080515c2b4fe189acf5d194b69a402b93963ef951d86f80897cf85c4e09e054620fc7e2581bc54949b58cdbcde49da1997cb4085d32609d71ca1a210f1e47c06d407539bc6fc2e58b6f42d96bdbb40e1a338299886e1eb57ada636334f8936b0432a6853df768f33b0ac4b4e393f3004aeeb993f9f9e230dcd99cd6d34f9131de3dff2789f2a1d55d57c2181ef8531d56201fdd1743abaef92ba6ccf2b38b66d330d5011ca0733ff24cd806d9ef90c60306234f34053ebc8bcb79e4878259871a0be9222bed289daa932556ba1b3cd11242f2e3ffe56b0223e8c62285dc000e206eab3c3a271b4638c4d3af6b738791bb1988b32e57af74f1009ef5352bd48419934c8ba18074c8de0e61695e2ce0d0ab6a0924e39d69e8ab93d135b5e142cd1593eaad8d130920e74fbb063a66c21999e421d74898f031d98e0947e4a91954e7b9fdea147e840a931fe0ab5e59324d18280df15e1736e03b0644cc0a84d87c52a348f5c82953a3c86a63d456f83a772b7f83fae2c2b21ab5a9fec90a3947616754028be3592cc094016e1cb6079910773d9ac5957c2c6fbb11693c9c3e49fad6d14718608287af29b743f68d5cd5080b838a50d292ff62fc67fa898a4cab37c547e25146ca7362a54c8ea1362c03992101da3e84f1b4839b092603a32e21f99239f98bf1d01cde96a550b70264eac372cb1b9dbb034a0dfa3737b82588fff82cb80bc6c8f38c15ce4d3dd7aca813f12996f903a0f4ce0023f33653a9328d5885ef2752c14e58dd8d6e95ee95e74edba1487bbb46974bccb3108223cb685b0b8518e8320b36f4664f2d45d6d0f9d4035de9ddcd09e567efa1d8905295130026bd2d05cc6b40615572428b4ee33a57a993faa3a0eebd0dfe8be4ec4672dc824a22bedd8a8f956f6dd3842e1e5143cd64dcaa728805ddbaa09632d8d2a1b4a8198da00d0e0fe275e83cf1d1127d249d4539b34a704a1ab78c4e2bf1dcd716ec5aaadedbdccde9c08ec394d17500a49d08772257fac9d354adf15e3b3f1a5623bbcc393c0d3769101c9e9345f2a15cb5d664fb22b12009d72f9ce0132d9b04a8b7fd1e7d87e42795521a9dc20f54ad9c7150a29df970717b0e37bd746163c5048ca029e2e9355923ec9ce36ee5a6d0c5bca5dcdd2e3050eaf2dc8f010bbf22fefa270427b090fcf3b4d3823c1c335c6a0794ab7119224a5f7b6cc7af188b97567d47969401f62eed6e1e4ffca075a7fdff17e12923a03d4f70165d9202d6e0816d97ed71943c54a0c5137a3f7e723b3fa178a7680845d56460cc9d05e87e92df648443a9430b91994d9cc55caf0fb56976bf75a1fbdf90a7e6655de4d2d37ae2b785ed31a1058c7f80fe89c042fb940c4c11e91d3eb18e0be27b8321c6c999953fbdd428f57b0f52b254def8e4620c07f5fffbb373eca6b57b6a8f6f6189bc6f9770ed1015ad089e9759c70163d1b9f2d4756c75f82693a13676e752db4b09d855b60e38337000c2d126665f794430fc261c0032886a4a76e6693f17cfdf2261a052f33aea417e7ef8a9675d851b8545d65d19f458623d7b94dd1e4a587b416385dd8b2b9528e0f827e66f4b5fc350fcf7366f17135321b6c998b203019b21e0e62e11851273441d4d6d0830a16cd0951b0d5b69adc27de6818229057f9f96c89911a64a9caa6b50ba5ae2265b8a6c63bd844dcba7977ea0bf1b8304c1412239056602e80889a26ab42f73d7444954b9ecbe9b329998bd15f8fbc4fca07ae0be6381c044dc30d7947da3efbc552189bca550580ce843f946f783e06169167c068f0b844a7c807e28ea93b31cc1056781bd076ab4496e4cfc1fa582016f080a80e86b8b7b4ed0b6e7f44ffcf9288ffbb75a0c7d719952c463c92fb19386649db9afd7855e9b18e235b46208fc3d39108fe6e33f0c4e446021a5ad0114a3ce7b1967c191f415e9f7db613a2d9""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +d6424525c08d11e26c59b4cf74c0b97165a85cd9c4aab72ca566240c3a8d248012e8ca8c75927021936901682a9fb98124e6b00ad2aa6afc20c9d15501d127186042c6e0b13a073e7bd100a2882759e487f8b70dbb391711ac6ccd77b07ba72c9d8c1bde14ae224ac302aa4609d77bfb176062616ba7589eb597475f1732acb5a3392582af7064a6d23bc1820be326572b403573378586d4cae5db40c1d91285dc4a3a9ac43c07362761a5925043d7b63030113a9775513160042ff79fc3b1155b9c2df8c75338817d174774fce4cc0508958c49412675845ceab7fd9b0b9d1abd0a6057a1e5079b266162f281d9f399062b672c6754a21b79e5423069117fe785985ae7cd5eb43fc92268140747b20983b85205ae063cb9e18a59a2577b4c7e889b16d189894e5788d459070f498eab465d1250812a155d33dc4b97b45889c11a98e6183232993b56007aa6544d8527244ba9ab55c3d2b39a839a1fb6988244e6c96648a2872202c37a35f2204386ec414686a52c8a0b9f976237070ff4762c21875508384c626262c38aa248090a7d523e429c8ab417a3097b230990c9c3810b0ef01cc9c29d8549cd4dd3caab37c5ed650d41158e34443492082e91ca574e96938cd05e3fd1bcd6c57ceaa2b3b657cf35707cd12485b4605e06100a5de0b8d0abbb6fd74d2a93042f8c68f88502953a66d3d11ebd06bb981c1250d0abcb86824358c77fcb5f1df96b93c2c833d51aaa36cb9a5508eee473ac6b8768b49fec81690242006391a3ff6a7b968802275c6274fa965c3958c3d7b9009910a7785801988c5239882bb2c4a79a8db3d09d25208a9e585e379c108a925716ab107379a3fb8404ba1393213166e9a5c58a8a9a90a41f4b530e67604ee8f249e8448c63e52841a8b1d35c8b91d4344bb1262a8b2fc513b7b20636b46708bfb347394cb5a257ce738c72aa4c53726a3c931777d1a02e68b49d18b2a81c89206847342f22c1330b883fecc1f8db292ebb51cb021329c38520a0a232ac1dde91552a64752a2a4246e877ee9a7028737e9f2bce4c7bb37f4848a14a5885aacabea49e6146ad9bc255e02b8f38375800912b23b2659f94a3935307f9932c0d8b1a9360b133b6528ed8732e48b44af7733f1416c98202a6aa127e6c8b110c879ca17039746b3832c9b916aa99e668a9b7ce78bc44b8000213e2ac5ba752fe3704d94b61fb0985510200b4f1a4bdb9aaed09704c9cbec39b09d468c5eed73a4947a48d57519be1afd4aabaa406542ec819acebc4b7d9b8b99133a6337c48ca1d2e5520089512b8daadbc3ba0de3941d1fa0e261bcd6f3825f29166852227f2283666019596941be6a807e39cc1dc23a7d472b56c71a2791a316ada15753a102911a32d843c51a2c6a8b947f65152b2941a5794548acb64e30961faf40e89d5354e658b858b1263911092c43d6ee8230512423d69ba49d865a1228402ab954b839c45bca4d83162ca083e910c05e88247809bb7aa7055ec8b7d4f996cd9ac59e2f982efb015d822c388eb4acc13870b9527ac70794f109fe58caa71817469b97debf66996c551284aa6a2505500927b3ad2595ca152f19825a90733b4f838019a754873a8bc15b160c5621759344fd31f96b4b648622f709c6541c09a4c949a34f82530f65b39285ab721ae74d83eb8ca5d12a01aa734bad0b15c2633addf7a92dc598adb817575926f9d021e4130b246e202bef3460ac7454a54cf66110ea87734f0c90f45374872950a3ec7b436c60c06b9bd25fb44d1f96b0383bf7736cd2f21b5f2306fbe88718b26cf45b31b32e8059fd87f17e70ecc74222642a54cc99a849012ccd818bc8006218b3deb12bbc92038735288195c5789fc932e0174f35b1975b611cb56a1eac5638492caf349abba8c526fb7280ef556c3b69ae2d15e9e108613466de9fb45d620b676f81c79598954e11091d2904a63749eb414987a2a44997d5ab40e7fd98d4ca276f892bfe4a35509fca06364444c7770a0c13570826c7ceb3f65b6b77637bf0d28a3a227bce187810386b40c0418b2e27a3ab183e8a28db4ea7ff8278c64a3164fcbc7df682ed98862aa965ff5d107b230b73e745339122b99897264ba067c186bfb95be4ce1435ecb23c1cbc67c181066e3c408da9a2ce36a32f1bbd3aa9a1476a6b477cf20196569ca9cc4202176926f2e6b76cbf4b4abb4b183847e068c585d7c65ada8c29dec27a32642647901a23c635f6751ae131c34815b362ca00618554c4a9d028a6aeb81c0014815ebfc7f7f7001edeb5890995a25b89332c466c39888b9b542d741954a27b5dfc72a65a0cd453b8ca9529701d49d3cf21922a7a365fa3f73778161534274b3244a31a192c6075f2562f04c6c819111fb1a099c114e07e813a472a802a0af3167c7d1a68583c57305099cf4e9a0a5c724eb2a318ce0582078090f35b856f773194245e6678b9e77160201cdf2fa8d4456671fc9bcca217a2625784e4052e2f339c544a5e589b24faca6e3c332891b2bbb5849c6ab2805a4b8d01199feb49250bb8d30380ac3651c7a07525556c9d925001568a73b804f0d1b0e9b9ca8453c9303669618f398b95ac2e304432256811b910ae2570009c5199a110ad8424f135b93d99c375243c37fd36100ab89b88b1997d3ab9eba0bb6b33a8774b07c33a589c236be155b2df1420e75a0962315eca254a1fb01ed63102fd62f249c79dd051addd531597cac00757014e01366b771d9e06e825082a4a310f8f72b7cf644e56c59f751affa55985e42447adc6775187170aa0093ba12e65b1b3a2aa5b3739cf2b09c3677184d6302141b8eb4985fde8a993782c256f0ce35dc5f973cc7b4987b29a333e38ac3131b63638003c600b5077b6b5b7b9a246a02f466621ed67d4d419c65ac1144054120439424f58d9f776a9a3a2596d10de267b20848c6245350e68b593ec7b49c877e5614be71a624fde99c0423216302b3106a29c85698f1b3a96895aa97c021c9b539fa66230ba8c35b068c5b2565f974b112140db6588be7016bc1b2082be9a0f5394544141643b75270752bfc6920c288468330ca4b3171a715756dcb467ba635f7d17753e0c1d3778114227d8678cf63f580adf5407e9353cbc546068207f83b4f16ac1df250a1f8d499fcc9471de920faf2a23e27055fec098f791ca19b094fd7aef23201041378cb51501ad0691a39870dbc8d6c9ca2d6003de995b2cef5957745c6d04194d067a2c1140d7c6aa3e271b4b95ca49ecb9bb94254e562905a0623cd670befa9c5fb971e2a69151d209fe4494ea753a926b4524b05793fe5c1b55036a44061d8d1668bf0094cb14004d3759f510703bcb22d730091370e09c1022141c3b35035c2a08921e7a23c5899ece95136936b68e839b021a97499bd30dcbb1341141698594225cf52740ba1b68ea20768d7a8cf3af91f7c1b1a49817c04f475014b0b6ae38a81f03260ac672c6c5a7bd2b8f07b3e5243028a0c15aee58ade16c2ac72985de1525bb34f99090d67097c11f3303b219fa68453fcc03ec6c84aab448d7c308d76253fd5078764769fde087b6c955c1399b54ae068de44c0a282a7772154b50177b56c6a6c10a317d292bdfb4d447045072857a0a67dc5b87599424705ca9d6dc18c88134ea1c746ead5018d00bad1eca2b84217b53743fb377765b674d30aca06c79ae5c2bd0cc06e4f8249d8e5acd3177747d65a8692a3db8b1ea49504de28b67fa1ca3c3bb1b1365fbbdb3d40d666ad72b286b221ddcc505388819c993652c72397fb158a175906546e1c212609dc7b00150987b408b479bba5d290e0130d4c98c33f543da186bc514ab453f13404619e841c634b4c5486c2ab80258ade6007c8895554e819b5e894b1b6933692b3eef79571b8b38493c3cebb915c6aa35c5cc543547400b81b6058a6450ac5a7a81e8adb26f9a8367da7bf8cd2496031016ac92fa7853708463911780fc536cd54f498f807a5d029a24bac5c1b300351367e09d1ce68e6af97406c74f5c7ff796f4ecc10227bcb4bbc27044c9c1e7404bc15985cfc2dc166088119989ee32789bcb95fd0103ad969fa164bb5cca5cd5c3e6fb65f989a118d6a2bed2b59121b5000f64fa9fbc723a1969b93ccb83b661ab1b25913bf2f6cb604e0218cec9c8eb2aff60c948864288ab6bf1aa1bc65b7894e1357173ab691630821d63b75380958ca91cc6a9785556e4b63b5920c0e3876646e6833e542a250399b16814236524f31a470ef05cfd2dc0e01ab2b4d5a9b70c4cc5832b72a632e2733829c9753ae5a928106267097bef54b47918aabfcf91c1a6b9ef3f1154f8a7f309babe4a75743409f7b155e6557807d6b428f720e0bf260c6bf3de22d70d55541a6240ba4023d046d7bf1c7158a3cbfb7b8bd2a552495311db5917a2234587c5969cc1ed10d51b0dcf8b3017143ebf31687930f3e2c610a4850"""), xeh(""" -CA9564B54F15561C8238E6CFD88137EBD4D277FD5D64BAFC33D6E575947F0FF9F93E3B0A4023DDB6FE480D7D6A2B9ABCD6E6E011EF37C0699A6D60D9AB4B05BC685B0A9AF7D3BD999C7AC1CDF017E6AF1DCF0313759CBB21539D7774C31D7ED8C039AC34D0C6A5F7590A3DFE193D73FA96B3458A364DE1555284D85A2BAE7BA9E57ABA00134E6B09C09777F2F1D7125AF858D81D14C71E34E8F668468997334B72E002920FD3FAD8D588355343FA949F1CC0BC263C7F7A7FEA6AD708DB756AF983B16A593EC224F7D69208938A4526400E326CBED532A777301DDEB5E539CFCE60DB8A022AFC52204C71710C204968FD1457919EB71CA15522AD56ED6B60404D62D1DAD0D06E4A2AD6BC746B28859A77226B774BF56BF7F019F2837F51509E9EBE9EB069DA27401CD1D7BF2A74CBE8341A7F213D061619F4E5F52984FE47066D910F1146CCD8DB48210FA2518D6B9FADFF16ED9D389292C07C8A7021F32BCD538AB06A6D5ADB13D7A96F65A4062A17E26B301CC8AD420732126D7CB801DD489AFF2D717D07A2748B4B01D162D228D5F1533CD5FEE8DFF8F032DFB270B61095785E44CEBBD4EA27158362D2A27582CE78594D4D7428B6AD958A9F1604EBA76A8CC0530E1001AC97E5ACC5EE670D5DC6A78AA45300A2BD5F0802CDEE564FA640A19FB554383A4E4CCF2E5BB3A41879C9428CBDB8DE1F4D3FDEFC18C2A8BAE42C096244279E57B307614C843B341BCCF530F6B187121DD83A9A160A3579C3188A98FE2F49A85A2705B9F76DEF04D5D04676D8319F243DFC99A5F90771B34D2A45EFF92C0CA8E4B542B8ED4C2AFBC92C26F8DD20B26B15F9E719AF22F571EE5B9573D5BD1931138D6315C5104BF80AECF830548E98AB23DFA44E5A23C6CF57740926D1E146937AF8D220684919FD89082E260286AB66F66F8A1B81BEE07A85907D07FCCFB9A1002CDD47A33535C9FC0938E3CDDED04D3FABE6326CBF5643373BAE1151704220E49E177C4D0C6168647E5976670DB7F6D0C12F169955E31F553A53A76093DA2A9A0C589F9AFDCCAAD9EC5449ACC01E12A70BCEB389AC104407415782AF2EA3C73D9EB2797CE6D3C005061C5059AB625DD7D273D4D92D1F4EB411A4033492F19921F60D0317AF286866B865E33B6235F0E3528228CF9DB242124F0A6375D50CAB3851DD2A3A022C1E636E332C90D97FBBFC2CF0B971AB1A89014BC2D942FDF015555431ACB3E7A6F258B816BA84892A1DFE3780A0E0C2E6C06149218E70D60D62573BB51856716C0DDA63A983C4008982E842E655E5767DD203DB3490E1E6BDBEC16350296D879F017BA695FC1CB3BBE516B741A67CA6CE09314AE27F718DF68DE698198289B457884FFF1E439F30D9117D19ED7E466084BD5A73E26B5E1567B148D4C7ACD1368B1CE2709B3AF233679E61914202D0DCFC81EF3ACC250DCEA602103C7E529FD6F31A186927E790E3DEE09DCE87DF694ADA7A3B7BB3BEC64456EE983E25DC6CA1CBCD752D72ABE6FDA2FC81A46F81E83AA9738D528C6FA3E69C453346D0C9A0734DF36BB7650D1D2AFA8A5C4C5A936D41258BD4193DA74FFB180CFF582A32D6F6ACB93836E009E8C880592BE61532215F1F6FA50E8FFBB82208A94D8510F70DC6633DC04F9D94C6AC46EDDD4EB36873E064CBBE65D343957CA7B75024EEBB56F589C3DD2253D68D12DC892ABB1FA4BF033B9B732E89A8B89541F04C6462F62F13B09C6705B31036294F1AC38EDC0C2298D7C6F4374C3B5C368D10DA8D371383CBFB4491126A83D1F75DF44F29BCD39349A9BF6526D14B339FCB440647A5FAB63A370089DF162DDBCEAC8966648DDAD6669E1EADC1C8A33E9B7378693E229C6B715F2F0AE54A67455E79FF8970F23E655E7A540D28958E2E102DC99B5CE5772D00831671CC6F7024BBAE8B04173E439054C96AB3BE918C40C5A8D42A9122CA29C56044D340420D2EAAEB738EEF70331D488169FE91B521835297D7326CA272B2614144EAA0B7A75CC7F3849138255B8A1D7DB875BC7C25D28EE5941DE89BF7B063046CA0CFF31A99D7B1846E01B519137B67647F024B3F6DC70045B6950EC6ADBD68F43F67464858D515D6E3EC5F99D9F1C849831BEB4224FEDB01236712E1D715F6A752D0682169A0E83F064FD6F081F338837FE654BCE7C8CAAA8CA90C8505945D9BB3EA58661102FF0ED3F0DE30C4013122D8CF08E0""") +645008486a43ea6c461d7f98a471fd6227b43772ee680a0a0becaf2d2115b94b33ad85482d86bd3b2217f17b94bf38f229f4ebb984609a000a02eac5b2220aeffbb7c771672db10fb779f1823246961702d4e314c98f98b38055ca88090b51deeac33d4c899d57499863f9b1e02dfdc96750f923ce68fccdb9bc01631b3a5444fe45d6b6d347b4097f657a2e3bb7fbf48e9fa687291da77da8998d292776409912d8e44c6623a50be758c677404aabed063de84b4f96e641690dcc9184e6d1e13372eceea41873039bc8b7cc2aaf6eb00908967f8d6ed8a1e4aa087f3a81af329ced0eb5dbf8191994fcde14636c307992bc859cbef1f1807b8c1df4422f0a1863c4b47715149f466fecf32d4060c648d5bf90d3806e253df269d4c19be5e3b3455a7162c197f1ba307fa2969f5797a04ebe6412dec4ebaa507542f86eb2d28fc704bf5ac58965cfad57ac8f019de27f82c79cc2c232f0b3389917c3777722ddfa6801c14b3240e73c24a68a1d22e374241ecb8ebabde5c3c638f678227d34870facacd1696d011d2e387ee8fbf61f121a7cbebada4138c48309d8f0a9b0f5e0b71aba21c538e91f3f0dcb49ad2747ce9f9a99cd810d3a264e468082c000d4d3cf1136fe900e73eec013323ea8998fbef7d5ad3f62286571bc24f9b45f4c07a19037038045b5de6e69002f3c6361bf34fcde13ab18937ee0a7827ad14b705d6c6f4d2bd0a3aba60749f0f9212e64717d2a03cd0b1bc621202d91e46e44afc5db28559e2e37f13be40681694d5b431ec4430f4f737734c36d683f22b12240e727eae9f70955cb958b2dfb9e1b702040c1af17dd23db44bf71ea0f1a52313b3cc1c75036f668b7c19d7a9678fad74758b50942e85735b218491b85b1ed4d142d1a2081557f18753d6fb0d1807324fb4c7125b46b9bdaaeb414e302b347251a35fa6236e15fe1996cfc9827afc1d7a153c1f8a3f9a0ed306e5f3b2d0909f7316980572ca4cd2f304150c4150b5b14de007e9ec913a0ceb71c4dfe8d91d3fb211bce71aa501d469ef70649013650da608373f19753692418256879e6063c40a0d16139574ea818d49ae4d1174596bd33d71fb052fa08ce51483169974f8c298e5ec9fe87042927e899f22ce51ac22bded7a685dc8a1181a4f7b4a43c1df697577d73736306596ad7d475b484358251718dca8f3b4fb264ef960f14f0c25a2129c40aaa54bfe51018ba6df19024b7642641129b6b6d0486f8722803045fcf2447c0852e4476d93d3301da71b5f1ab1bb8b7e613d50e081198249bba6d8cc30cb70991163d3d4870285f949fbaa6152e356c0acf3212fce4d8524b97b1638938cc9cc63780b63766245402ba09f8f0fba311016dab14375d023178b42a7b59e72d7141a89c98f37cfb1e4868550d16c8c8fb3351ff6c12e5fcd8364330b8e0f049d8990bf2df53dc3b08d3db78f8d2885004a5e05a7ce25dd34ada644669937ce7b426a5f432c95fda3b004d453ea51806add6267f9cd1c1a645282dc5a069b9721166962004ada462a588c84f54d6bde421ed35d81b0ed6b864a9442876b5a71f4cb12d2c3af3e5523e08e1b2ac8a1bfd9174a708f106106384fd644beb561d6e4a544e14cec57c897af99ba7925c25bb256a092314c5081c156154d3a7bf4bf8209246919cbe90ca4471cd65b93d4ae28595aab093c788d4feac9844287dd1307775ed3a86a27febcdbde0581a4a90b53ac8f9d6e680727973b3ae8a2b3bfe261536a878c7ed9922a3daba30c826c6e2790c88c07dc7bc4e9e716bfe509c4b8b98330b9ad6952d542b8a512f7eeb6dfba79237262babd8226c64e76c8ae04783bc4b494ec5c8f82b30e2ca87147fa4c2b32beb2214d80de46add116748027533cc7fa4ad0448c3b482c80807514a4b1f9252798dc53b83fef7cf9561532435ae15dc19abc799f43729ac98a11c786556e3bfede9220a4966356815bb16f887bd462bab989527b02beb9f9e8a9fc548eb9022d187b66835df6b22edc93829306ff84977303505c3c13336c8d558651a5b2bd0e1653effff06bf7bfdf78f9abdecc6c66c232fb9ab6e8b7a89bfbfe55795c27fa596866d308ada3856adf93a9661cbdf61486e9c2b255e689de3cd28f327f059c353b30441197ed3f04bacb6a27710c231e2cd0e159642518a5a50df24f1191faa68c570abfa808616911e0058f7ac1d""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +19a1c59df3428e937d18d8571a5b12540a27073275dc343dd0c862a9e150f57b768a4059a3441716d0401e6a92499948ca2b84d2fc687b08a929476fd3905fb1a207dd357275b03307a2295ee619ed04acde08722da7a4dc86be267400b5f7103b6a613a067dfc406b311b42dd699acb022decdb3b6d37793275c945dac6387323d0b6a3d06044969770b2a7ab47165c983267f5d515d3758f6097a2e6a8405a4222b2f92cef4b0d28316c69ac4f4e275812e6caa1284dbfa490a1ba0bdd1b2b9cf9aa8641a34de7816690b3d4317d5c899ea95b61570139bddc86eb83863c0a88e59b3fcce28084c3b8decb9050a657c7e7637acb49d9ecb7542224f82a9938880744652f361a9b39ecc5bffa6193e79db43ab89b681a10d69e1ab26bf2ca7e665193da9c6a6a558654314f7bb8c8a555b133235f50965026c080725391c2e75870fb3ad5668e2274690b076cce04a657eb7bd763c40cc418dab5c278032a7d1225eee448fbb849e847096a58064cfab6f3830f7f286b2fcb0e82902a9a0b052fd49afd3134557510686123e7c5ac88605910b94131a61c39008c3181cecfb2679a187ae809c03f9a02c856709a24a4355c7f0dfc3465401c15332fa0a7073c05bc4a23b7666b83881556445caae0d2be25672fb6134385c41d4e187630b67a96e35658760d261a4ea71bb5485b4fdcf74c0e739258441f2f50a08762b13d965f4fd12252123901e4cbde1a2ad47601b1a685eed55efbc78bac0b06bf803e6dd585f11259ab3b4c17286c1502c47419979b37852ec2661cd827dc97629b4104a59ac162e24f0e4c1dda2923af8c624c0653e479a46fa80418bbb9f1f29ab0faa0135c57cbdc09e4955a4df04f540845012056951315c3854a16ba69ba092cd2b6016b74a3dfaa94d43767ef2050166b146ab1bf48d0a61bf39ace177d1f061732fc4341637f60317a0a736fff931618a0733ec8115a3b5c0bea4b8f8b47906988543164bf0a1135901a057691829234db396b2d543b78fb5eed054791d29d0514170fbb9acad0670a058dcf264c0525c13f883bc69960ccc6888a2a7796753297e33799ca223f54400634b8eabac16c70b9757b91a03046378a6295203af5d787fda68323b11311bb8720ea21130b9684a0510973bf27304dbb86818b3c8952865f34d6288f64b2525358c77a503f95b2dd599d86c02794d1cd5d40285e587ee4a7880ed515c031a6296b7d3cb92cf0a1519fc14657f7c1290bc2e7148502822fed447cb1078b40118f257554ff4304da892bda891baca5a47536796bc55856c48982e7b02a719837ea43242ac246f04d69e06692565f97596d35ca49633abc0cd941ce84aae080934d671760b41d7c93972a9854e81372c4c979e2f4332a19b19606743c61a5ca456cb4baae8f2bbd35161f44ca4ea58c5c3d7cc395933e6584582a8994d6470848a9c127bb35ba3323053678f7909a95ac06e87c52cfdb84c8ec97b244a51f47c3255bc80469c85660510c2093c15bb138e0ba93f3a816d22ec6680a61257ebffc8a5f1a7b78e36c8ad46d34708a4ac730ba61878a357fc0079eca75c0e1f225d878b852a3a0e3cc06f0b7c5b553547b133ec5f1a26cb85203a94e53a24b91b89fb3027da3a7788eb0751e45be61ab03c234117e20c30bd3b064aa6134b59c2d6cb6d347640d715c92056e901984ead919e93a3630700e60830583191449734305293cdab0b69c266eb0b9b6c742a342472335b29adba00225678dbb6a3383c57be74c2c0832c003f3125785b7720c3ecd804aea15173b19b9825b5d7ec6a63d4447398549639a86ab241d1d400a608730d771abeba84d6a8894440585cf16a02e856ef13a8197b343922b40986b9f3a2873ff29816a682ed6e9753f392c3ffba79a116382197d71e39ec79c7aa9da19cba825f527c9eef3272c0129b9f281a0c574aac0b938776e6adb3bdd88ab3fb1a4f0913a2e4c53e76a7c03294b97b1bcc4276254c5ba27c7acd53c212a118801450fcd160e11c41364a5803bdcb277452a5c5193d0114f0e9247fc3abaa98acd43c9784a7c5eb3a508162c602091271926a52b01951dc4a5862767c863c7af6397c5a2b8953b4aead8480d520f111b85938b4de50a6a5724354844b3ffc12b2b420287a6798220905b42bbf7fa109a95c24b6a71902c2e2d806d1d2baeb0c2068ef710a989211b64636cf58bcf43a3eac1119f809a26f02a216341f4b60b3c7516a1cc40572c6855bc29d006737ce64739268d0bc59718b9aa34a82fc9834fb05b27593a708ac4756c28342a148b2173b4cd023fad458b0ec6807f421401991dae15cbd8b01181294f95e0a64446710c41671ae3b298202fc44045541ba5be8516c8e52e743c503c9cbf69d6007fe79c61255872d312e1b9843300a6b436a96403bc33f6577bd4ade56bba41ebc964028ae6684c65e0c348c7ac445bc6b3021529676d5c40a3255930f2118d2343a866a6c5f11c3a1c85a790f25c5096c816166d2d08cacb3bc503d83ca9d1ced3aa0372a3235e06ce21f3a8ce609621c954bc383c97b49f23e2329ce9b092037e661b361f9bb13a285cd77c02cbb6cba1e37cae8a6264448e07401ada6896baa3189a527071e52dca12211135b6c360158fc60ec2b692c119042565172ae9c7c5e15e1b1a0952e772d61b57e66680b8359cd4726421930562562913c0c30ee486b023c8e36926bbb00f1fcb4e89600bf7d79905794487ca1dc5d69264fc56872588faa81a755b3227d2532ef54f8b0a91b8a6ae66cb55d34197b7c71e69c7bd39f8276e35117e96775b6c6501034f81267222f54a3f7b94e4a7a3e3ca04948b4f17300b92330d43a41b3de69702c2bfb9272eff89868551beebe890cd002a86d8566ae5cf47a4ceea731ec574684533796162ae9f206dad42272e8a7f7e7c97f93334cc833396324a8654480e5193a8e0918b48015de487df1590b0f7627cea9fab8c3bc1cc31c52a7ae3e7173a7a8c420c7090cb0cfbb0b419d53af678b5db9244dc8b8645f6c093f1b14ba5b65e4c0b8a875d4d86266aba296e648670867b7af5ab2392c4193b9f83052425362c5ce4a45dfc3e5d9960ad3b392ef6348fc7a164b494f75476b78c3f2557cb898a70af6280b7053823727e18a7130fc777b7e81cb8952f23b9b27dc02447bab51dbb9c0dea135db473906987c5ba76b0424848bca4e09864db2cad5e97adbd00629219abf8978dacfb8370f2ac6057477cc7829b6c452d242299c0b314855c5a5c61ee4557555795286c904d08aebfd17edd57195f831321ea02d68493cc994dc8370e219152f5245560875a88c3b919f9ca9a745ee8b942e1316a177a9471cc84984c31b59b8190a9207e4ac1ba253093e7585621878a3004d21851f349805bd70573580f9a98c97d6a2e790c0305316040f64533a6bfdce19d9ab8658ed26dc39837fddc2be9c66012eb76bac7b8f2c05361ca1ea7e0a77ec18187565f3c4b43a6397da9a16a1987ac8c700996124a10789ac7e0932fb820f4f18a9a7675257c7cd08249f4185a1c7ab357470e8a35c688a236b4191ade41bb9271a3798380d4a2a643e302a53396fa8976d5b2096724ce85ca4cb36ba8f7bb470f534fb496a7104675a0367b05f090f4748145ca680a489fdf719612d52e610352462605c1a43d39945adbc42338424146c0707cb28b986888468b85f5347c8ccb6456dc442903baaee62f4bc1b56fb27dbb50c96d9b359894a823b812afeba2ba39b8af7227b8b58580a2603111a6fa511ba7e1c7ac4a037eb53a8caaa31eb551339212048865f4a5c8aa207ad8688c1e0626fee782fb6c0b97f5463d8830747b3eff7136a1a7a83d3c5cf5b32bc42b6bf06b4616055ba6b53fdf365b2c6209fc5239ad269263bc9458bcc2bf45cca868b4eda432d35a0caf361d9145a4200bc9a770b5571095eb18cdcdc407390099d43194fe096df8133a22753b7749c7b51c11b4b7a59427590f71091c969ea619601d494c91cacc34133e0cf75d1d34235a45b6977aa39847a01e1a5fe4e2c2a509a986249c482443cfa8cf3ff9358541757a776efbd7148383ac98289b4d68a579ac3fff02adbe7236e6d06c8416be80445de82619b065436468b0535906ecac1f563b5daa78b89c6ba5d4283b06795b4f88022be4b1b11ac075e8b571fc7af7d91f13334dc18a317ab4794ed69946c45a615c19209302cadc2f50c767840b397a9934bbc74d3d990a13e656d8a1347d4a46c6676402d563a0e860df9a5f0a911a7193be4b162428e0cb68b66b35146de6b2a57871bad3b166bf4a605bf3633912c31d0cb2e100c00ec9501d0be84468dabaf76fa2356a58155898e69a3c0e7d683cbecf451f22d5fbfe5c268257c663f42d4b0855590a07919c4363de5890b4d5b3df022c3c86b725c5f2b54196b7d68684b9fde93be78e38beaeef18195321f4e2"""), xeh(""" -C18D7D95DB69D4FE1E6DB385024D83C01F4790E2BFD25DB3F5DD5A208ABE06551BE0936A84091F081308471E82AC9ED6BAA90824D5525701AE0B638003C21D5EBBCBC17FCA8F522BE4F9FE5ECF38BB66131578163D50994E532D0776B187498C5A85AFF617D4550345F3855F968A8964B4F3CACCFFEC82C92BC8617C78C98E10C91AB505A92CEFE0AD6C8B66406AEA4C3FBC5275047B3E983AD42BCD31838A39B92E1C61E9E62443DF3A45044819D9E289B5514D4F74E08FC3914C0B66D2352CF8B1FABB4AC9B0748A43547BECD29D447D01083803D34E8B7EC89B4F0D78B88AEB33E308989BED2D7A78E1C06A11F3BE808F0B9D9712C80D63DA10475849DDF6CB0DBB1007FCDEDCA3C4220386B78D9EC6E380B4F57731D964470B42CF7D4B4E6D98A12A9021121C8BACC4B132A274941DA57D824FCB60B83565F5CE05D140653DD4C70F385B55D485D24935F3631AC63FA12FF50BCF4E431EE4074B2A05A2A97354C7B4169B13EB225F1727F8424F7CA6317A04C355FE785248E67E053C4D4BDBBC47DC7760AC71DFA2502FBAD1180F2B095425198A26BD5A0F7DFAB70524B8F076E7C7F215B0536B0023F8A9F7784809FF4DA245C2EAC5F9E0AB85D987C5B6FEBDB3DF197347BDFB8D5F1547FD2A59D4B434FA7ECF8D8535903D3892868BA0632F194AD6E4D5A3B30E5A6B92F829642DD4A3031358F9F0D9D46530602A35CE455F0E360C14A754828972D85561AA835D87275AC510856D26192EA319FEB45709346929DA5C5919510CB2A482CBB0F1CB4BF6FCC0343F6DBDFDE734919EF335356ABE82F80786EF0CA22E5B03A05963E7051E1FA7EA4BC3141B5746D264BE1A32CCCD39DFF8F9E5E2AB4C5F51CEFEDE3C1CD118351F9A8ED30649D407FD31F6C4BDA3AF44888ADFC3D118BBD04412FF810A7E106EC32F7524E4750DC5F35A9C55541421B5E412E57BAF24622627F02633F524FF854F71011580598C5CE01190258310BB12D7DB5F95E9EBE5F72C97E89287C2F9007A9332EC51DEF1AA2F2CADA9A8A547C3508B4D294364EAFC858B98C60C5469CC7C3CE3ED659B5A54E889FEFAF825FC777AA74A8896C9447704CA7300FC5DF5810681E3ABE083C1285B3B97EFB0E21F78F45409D00B2E1680DA79439734190AFF0D68E062970F8F6B0F1E84A559B09ACD9938913FC26484DF2125FB6D7FC2E3F0DCBD72D9E5DEDBE7E44CE7D895CC9CF6945BDE0C52F92340F9FAD3009BC90D4C2D3DEF7C1F10A862F9D71681537FE4E2716912DAAB8C9DCBD81A083220F68B05F7502F3911B1B6E3B26DA14EF646DCE67852FAB6145BBE7E21725C21CBB2849C63D01AEAD932F8EE9345D8666786AF06AD0C89B08495A6EA95992301E2D8B6A14426971C7B31626BC93BBE76CF3DB9487B5BFC5BAF298F1A92FC3BE276983E53701F9A550E2961E6E2F07317381364719BF3FC741E2A5A0664D8873120D0C11287E92DB12126332D43F35407C01F7F85DF7916B651EE4A30D602E71227733EC9252EC8346361DEFC23397CEAD0C23AF44C77A4C97242C7FA9065BF0C81983AF3E516C1B8FFF3DD5A6C43B6ED5AD8BB3327A09B6B459168F3E497DCB65FE7593E8AB429B8EB2B31F76DF08A6A8F35EC4CA994037493A8C04A73D8191D682542FCBE16E657D3E477A7D25A1D650450E94FAF485CB76FE7110BAA902D74C335FEE1546D076163B5540D8495E16E909E1D28C15BFB421756B921778A784E16207BAD407B64B9CD83AFB0A602374DE06F5C836F4A1ADFD495012DA8D3FA4B829F735B31BAA6364A2AC11BD18E40628DCF82238D86B0B5EE9DF6D179103E1D12F5191475FE3008A5382CC24648CBB24F2298758823B7F93DF10B380C3179F07DC3277021E9EEA2BE5CED646260165B57A18C26E259F83576938828D4C7617623006682CAA613AAB770791874B55E2D0BB32DDB628919B42C09BB7DAE1FBEE8661CC13F8B6A47CF5D6085A2AED796E305738B508599673DCD03AFC267023814FB1DF7EB928D5762BBAB4515921D81C6CAF551DC6EA16C1D31125B99299ADE63FBFB9BC1CE46331394CE472DE6DCEFB2BF9B3828B0110246419C47D2A1FEF16097B943A310C0664A92A155C8273402E83CB94D7E733E4527E7525E9BAB219B69676804C1F67088184038668D55AC4F6E04CEC0EED4B05DE649A9C2064F241AAF9732B09B0EE4E5BB2C0386E45FBD44""") +f1c15b3bf410c7218777a21f73ea71a361f62f85b7c47b2fc9c6f3c197cde8d13933da55d11496e10946e0e8a4dd59ec816afb6b28222cadb9f4a50591a4c3a9a8c8c4fe5819e1803f7190861d624757322be0fa7c8ce617d581136a4f939e0a5f4f1707fe493bf47a4b099f073fe10021f3690332f9cf77939e955a38f84271f4b260d90dc9195288d932e41edda41694b7772fc1f61bd5bb93ea9fe413b676b737dec76d94193982cd5fbcdc8986b107046755f1936b283768638b16a4dc16daa7f6c0b05fd11da8040cd0a25058fea49c576f6336a456584b0b5d9a38971d0e686b12a901c7daac4e2faa85160832582732b044f9360a8754c2d0a1dd5871b3d5048a3cd6e8eb5cef0739f1f6dadb83d3e65dcd3462b29c12abb026f5cc762466c25016129d0b92e0c10afbc70ddc6fcf33f434091798cd2ffabb10b8923dbcf890eba3faff2b2ec8e1dbf170c58768f8e37559e228660408be1ed5a93d7328a2ab1f48f9387056c5a51ee52f34178e2212bc85caa9312f50513878dbcb2ebb9e4479a8e9ac2abc42591c98e1b35ad5dd24da6d8c6c2fc0d7b964385f5b9596f6c76f5f681974ef8e5363f58cbf507fda58ceea9e3dced21dc95c75ba63c459b23cfb66bed7890c0b0aa078d77c7180ff9101d5762628e8140071ce861da0359db6b349c14a5399002486f54a77a6ccbaa01c1fef5c172e0737d19f9f68e7d20ec7ac9d211d81cae09a0a2f7086a4a8952e81dfc0c2ada2c9ee06d47421602fa9009bd221e02e33ccc0c47f670b5e05973236f3e74e768a0a84d890bbf908e835aa1644b418dd228bc3a9b06afc0e292f9d71fbfd5955b2765ce90df64ba9baac0cb5d5802b919cc0955c20bbbfdd624d5f6e0b0db3bdc01fc1dad5baa6482b71c247cc103f08db1064ca5144276b8062f31ad4e8adeb6543f85074a7aea53cfe360f71cdae05b99ab8d5acbb9312fd136920ca09a654d962e5623b7ffed22ee0773f3e4814bb232b112736b9a9fc66ba6e00b898a8b9258d2823022766c595ca5183be62be21c27b5abb0808eb0978d0541a66c294646ffea3ac2a480e8f9d3f0c58eee4d0bebd002c435d1f8802b854d953c3e9242495805ac0874d74837febffa135af5916702cbdec1d7b6f60880f85d6482302ef8c2fcdaea831d70e821055be0b5db3ec0797fcee74f652bcfb559416586bf09960662c408cadb7c41d36ce7ce803b9c9fc5ddb2d7274867eac6ae12ac08cd318735f2645c752c02dd74f2eb45293ef165d2bddfde7e5d235ca7480139554fe134577a430a5644a9704cb162cccff0550e738d79f8d01ac56edf07ce9561afa24294c7ea61f6e90ca071df601e83288acfb0bf69be559a2e788f7c18f25138584739dee13a307135d60df207ac6784f201826de1c7d48467cbeb721e711c7edae6443471f862b2867a8af1687aa2afde61a8c7d8431b2080b2a119b5d5c43e6743d1ada10027870d4ca0803646cfcb0712c692a6ea22a94b7fb5a455b6fb121c0afe8c176c8db060e200be7f59f9c075327a6f2e1e1b3a06df1684956a60332e86282872b18013898e004fe6dda04ecdd243fd45552cb2a705682f049383284ff382d6c68673987d6e880f0ede4c85b6f01ba89fee8b1fc2e9e091289438221079edaadca58b845da049475fff9dc5283f7db3c34c5816b87f83804f2acca031e06463cba06f97fbdba8e4d17040807b380ef7e87712f1124b43570b8f36be0818ffa1ae107964befe8f0568ee037d185cc6f6df9abb0f8547be4205d0778441ae56983272f4051165c9710c7bc2dce963717b3a9487a02bba79042ba5f255430202520134ca0f5276be9580174760b3aa4a7befc6efdac17f9d70f420a4c9106db961af42853c07c92f4ff6dc65a19b75228e34c43d70a44b61f6897fd6ad59817c919293af8c51b869666ce236e018edb3703452ce0c021aa1007d68fc575046eedb9e43c14e1d6202d0fb49cb40e7f6d78a062ec8cfe12e8936c928a8bf501c2362b62fd7a7d313c1343806736931d5dafff16471dfb637285286db906e3747ec089e29b0b4e15e3ef7a1ddce3996ecf7e7f834afbb004e59ec0fa83d6a0862b2838feb896cd83b5c4dc69077ec8641e9d5406aa683c68de2ee59ee254419b3a38719b40637349b6adf63a28a0b3893d661ff2589b5365e8ec9059081783cf3b4fa5abfb4d48be""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +fcc4a70fd4395ea9728287b502e92bf9d77d3da38e0685858de5cbc8f286530cca0c683d13328aea540b77d41b806627139592d2672323c0b94be3cb9320454e334c4ffb6a12e12e63a96d1273cc8d4a6359263e91963ad472aa8cf2a96b3a62a079835535444541ca9e434348f3c6ed4a981ed70c59c33c27f25be9e407e6e7cb52a0274f1b7403f3bd3dc32de1f807b3317e7b5ca5e3864ea4739be575605f023273b17e2b9135f5b13bd09a00fec6283e0a744b784cf4595060c657abd8ab38270979606f7c0b1ee85b5cf1b2696db43e5eb21ac523bba172bab8223917508018d85b4afa10435bcdbd6405b9ac64f423adca6b7b9326adb5110809f12daea8270e48419d463c7bc264ed5b208880b8a515422ec9319b245f1331ae9ef80f46da776b4c83dc351622ec349b0b2e7be0c101b36c8bdca3573087d0960e7837579d451be25101cd45313b6b24c3630e18bc88407a75a16cacdf1664d19b56d9593fd2bc7bacd1cad8d96ad29c7c4d29c898220ec610479fe984da083863062b57b83b1a2b97c6789429a87b575365995223470c4d43c401cf27a910c31464f200b362434a8492b8126b965689b722c663342bee757f23112092a3486181047296328772b3a02b398d617cc69ba5bd252bb1879a7fe48ce8d47404f3414c79935c109e22d18790c9c07f606de7b69bca824ccba0a111059faaa36363052f811ac12fec42062820d88c4ccc787410d884d8e06812eb3fe676860ab0b069ac312ed332eae3059320956385ad2d502e11510cffec2fcf514180d46caff1044878ab667a56aba86be9e93957d929a15950fbf2a1333665a4525e6f592b1f9ba45df02843aa2541e233437522ad16383b991e0093c87c061df7127bca8275ab0234ee9bbf4986447c72cd65d657422a2b095c0703265bd129a019ea398152ba09ab9665e62163d862fc334c60d09894eb106be946fbd08f726a4fe01203ac34b560a1218543460d687c3b64929352456c65c55f52828677b99b412d07e250a969800ea7b5ec3053c99ab169cc913387933e29b52138a57214c99bb87be8c4ccf3337398c6cf3cd5c37df09bef147fcbc71829da53021c8b7ff04bace1c24b862e1b233b52985d11370842a89f9f33829c534f62828dcd91304966b045499c43046e822997d34105e1b31b49613682215a17ba2284d162b77996aee868ff3b25a7d5c5a740bc79771592f83570e682fedaab2528c3c427a04ac109576634e2846c1f43bbeb4226105713470b9b2556cd65b7c178f918d47b4307126578a81d02d99feaa5065bc0b492b4a9d08783af447827075b83890c6630619d9cc97daaae2bf91f7f021040858c99404dc6dc2e3c7a18a9345bc3308662f78032fa3a0328400a84982e86bb1cb08359f7455929863515343731c42c8a58ea3b0a5abc23cd7a8e8e029807fac289e3b9fa1a54e0f652b371c5e20839e84c9faf0685b4053b4e54741a916b76d398c76a26d572ccf2a4c83546c4ed8a6b88458db9523e65f676eaa1a74f731f74758c86a82662987fec79b287e02444dbc4a032a18c1ba4bd5a8c45dbac2f58a379649992056172c986361c0ea21935782756c4d00aeab17ac6ca938b063a27c00a4aea7e7e307145138fb68a697be49bb026a8b5c31700026d1026475ac98672554b0d8b2e9eec61ab891cb4911c19381b053b4a49b8559aac9791575c3b71154997ae5a65770e1b28ea601c2ed76a72974fea67a2e7f610442b749f8b3dbc725ba2528602978b05cc846ea634f625807b15a9100a1b743b6daef06d37479f9ce65accfb1de08c3d432a6403f06ebd423e6e357821150f448c6078d565068c8b343a2a5c609cad649945934bff443f19442e3eba04ed1227dc112e4ae670e2e20777f89c124cb3716a4465e84f0b86a78fa68ed83ab67841a76aa9b909f5a242d7c0ad499c81f5811ba94ee3a5c44d8818a0808522544f540106c89884da8890c6fb3b03887a62aa218537a18240789ed98acf313108884eefa00017fa4eab371d94e5410b118b095b2489448c55f45b511906d0c4caa9aa4ae20861ee3586a2da74e5098a50d543f1d16db01577f1525f649074adcacfb6283c69b41a73ca1ed97412c2002ee54192e34b71f95b0603d1858cf808b55584625ba1d4f6ab585b2b11fc091bb28a92ab2a5d061a3e4890ba687cf532201369883ff26ffaa019319b6914b8a2d76091aecb59e37a0916e5380f2143cb34176b6310771703be07305869bab8d98fd0532847446fa156446f2ab465499f7aa81f450b09df23ce66d0c0e6b82579425748da4a4cb1a13f711791300d21c0bf8a5191f3a0817ed4519931150e3161bc1b076383056db994a3775a27b61c0cec0e5c3584295b01e9855a188a184f78baff6a4ecbc5cc1b0227a5f12498d0b90ecc450d5a278d74807af78b3ae94bae64a3baec0c6b109a57800297918bf949b69c5c905f944ec8cb7e84865d67382c6e3546bb4c891da34eed09028bb3677ba624a9d5c967e94b65e24b380719517712c12aad85672f20c77b19e477490a411389b5ef63429b15a1a8d680b0082d586955cd67163ea7a7c8c26e661c52eaba8503b14b168c8c79fb7e73109b135c7ef5790afe65853509196b099aabe81a525a0d6b6b3cb2d5400a916416688d8f960d1607c777db22b3b2954cdb9e3932432e24805f02aebf672e8e6640d949221d3570d901acd9863566f439f5a4525367337b718536623b23c16950dc59c4eb9c00b76e0d11a942fa4e531a6152ababe6e54c101433b5b41c038907a548c69b1111aec34d64e084863c950c4903493b768b831a4acc04059083d6e7a25bd71b68dc1d10309f4edb246b7576acc70838034bc0e050ab40808a298ac7571d6a392bfbe57ce2570f18f35a109ac32fb9cb7e5a1da9748cfacc022b15abcdc469e79319bce47262012334478f301c1c42583ce84116a251a0e4d8aa38366561a22552eab180b1634442138a1c370d23a6acd393cdac517f59acedea7e620b4458b03585410d3edc5264f9375ceb6df9f870c8d7393dd0c2394882179c991933b8e474a85ccc6338124604727bab826553927d86541a4da61fea2581c5d15cb70b740e7b38b1787d0ea7acb6843fda6c5dff60ced980b80775501120c46f78cbc49a4ec63a98d324a9a177bbdd74ba0ee0108187ac0e245cfc7420a9294019573453763cd4b9c1bea9366d8cc7c996853c5c172f9b0d667caee2395b7a7c7fa036be9ce7b59b96663d260b69940a2a83624a62623e8906352939338c724a038337a59f59392f759c516cc417478cb7fd8c92ce868127e156ad4abcc714328ce67e2082cf2805c3df4b5be17b29a2446fbe26a50a54afbfc47bfa27855563b64e3846e934311f515f20c68860012c43195e6a45684eda2de3f9af70549d3f41c0b17519b02a7d29b076e49a3f80554c8bd7cfdf12a42d9b511c4ba187845b5b725b1a384febb470e3063312e9a05e846fe28b155dd00253a3afb9c2143ebb0683b03457c937efb1158fa93130058213176cd7888598e457d33cc6a600c2fd465b3629cfe84bc51cb3aa8bc4111626bb57858c00ab7b8b13c729a052bc222b06745b5181bf1c58341d239db92378a83b20a7e1299d407295fb94beb2c111f07c57401e522149f9c2b0a6d369b6f829b09970b660aa3dd6b0792b21797716de834286d662a3b03c38cc9ff1aa982dacc0d6892cf01492dfc506e7c37ecb8b82603c7d65843cd011172033203e294e6920b2007631f377cd003d8b9a4421614cc20e126d07f05205d0c1883910d9172aac4864ff7b7a8b1a1f5a8c773427aaea747db3191d312b4f4a82b7d9b4ba69313e6b7cb310507d03f47f8186a15d49030df21c144b639a7721357aa2fce77149507a7c5430d9611d0e7a5c93e54593314f3749ab0025603417173b13bfd7f32c6f854238e2675a948130ea2213a749da0c18001791f31755ccd829d76c5c62eb58554277f262427506cb17143557c919443922a09c1b735943c1a411e9db8a6b5c0dfc73a06d49c86e5b5fb03677f234bc97a2931af2ac804c0a9d721ac2468058a037e53346175981c879be43400a1c0760ec3096a56c0b2f11c9b97a87bf388058424faba04abf8b4d7f5069a4f26b14e39917b7858465761fd802c7c8cc2ce11cbdd04a519bbed86261f3b3b3b07174c26008b4d71311a951e0584100ea7d97881da990ca3cbc1d9f596a798cb0b1f79353413871e5a4f093b4825a47833a99994848af3378849b089b3843c7b153e4dc10896b4a6aa9848c17cfd3e0a0c491b90587cd2611908fa04bda829f0b494b045f938e08a7bcf1212fd194fac918ead125d88e6c4463a046899d659644d8f67504e278e1ecc03c50e807ee0dfa346aedb596d90d0dbaf82f24d69702e666f4086d18d3da173a6d0b44bbebfac8edad421aab72b823fc63d600"""), xeh(""" -E7B361D043C4A0B3A780121E9648DCF38DFC10ED5E47EE4DB5523C1EE1F53552640C89D9D7EFB9DFAA8EBAC7AF137A850AE41A0FF8F8CE31FDFD3E671555180EE46AB58322FE4E5F525146F9D4CDD1D1CA01413C5AC7259E1A2604A5951755F47D1761ED16B26D3DCFF79A263BC38852007BD3F381FC3B79B46A4B372918AF3117180726117BDB33C063BF5EE5D69CB48D267929CEDC890B743DEA43205EAD46FFA69D9B30C1AA5F146CBA3B0B7C4D4A50FA8D120777F1661430DA1B9D1C1DB4E10C5C3C2436D381EB13DDCC61EEB3F9AB46B60D2FB714929139E9C27F8730684EE17B077BDC003500027FAC94DA80870B382EFE41BAAD902A491C29DC95A8F80BB075A4E61C8F100FA738BED869B48F897ABC9CCE08917B5073229A94F3790947FC1AB6C2DEB5B012D60EC156A8A041DE151EED8884EC616089CB08EAEE37C006F5BBD10ACE9596A34FB09345A14FC4EA674E4A74699BA5240FF1282ED1E64360BDC9F7336051A33DD48809CF0011BEB3CE8C681588AB29F5F26175A8A6FD7884CB96CE3964FF10A67FC4A4E14CA516162C16D8127CBC45BCF7C88C89C8602032298B53C19FD099809814BE0504BCFD2407F48F2F24C5ACB89DB4F54A018DD586D871C58CC0D998FB4B0E5F5DAC631BE8367DDE88ED711F069FC8A80EBB573A7DA12AD8F13A4CA1E8A22D9EB53C55B80F700C58E6EADE6CDEB35C262EB42C903AD854F843547B79464524833A05E3FDC46092E41D8E339E7662D1209D338B8A02994D15A10439C1DC02A5B0EDEA58AF197866F43269A57C747DF389EC597F523211770E9C7E4CEFC5E43EEF791897EE43CA6146F3F757B66B9E7592E728565325D1740A1736CD0E678BBAA043F4C355FDE27094F74FAE27AD8C270930DF637C652BC1957F958DB013C146F2A4C5F451AB58A55C2B638A82755C11991B049E82F8D3CD3E7D3571FD5A83B60280E92031B610FADAC9E5F61DA469DC4C51381C970E03F09CA560E5D69D9B32AD6C1DDB6FBE9F8FC0551A909187AD65AFDC067EC6AA01AD684AE4C4F2E1F64046083D3EB347A6B6B23BBBF14668B9650D9364A6A7666593DB86FEB59628A91169F8AE24F67680789D316338B2F27766A83957831D98C88C837215AE3BD49767ADCADE758320ACE76D7F39E2970EDD19657F0EC12583164C325F0A000D065036BA2522F960C87F9852F30BC6BB5419CD8C0A1F9757BD358E748CB244A5E677AB9F9319A43A9BAC847A566052CA42C1C1DB36A0D97F144BED3BC5F11A5C8BEF7A74A4CC67748F1DF53F8B4714E0A04256B36A814B08B78A9737757E3F1347F9E5535DF1AC98B08ACC1409278B925F3B6C7863BC0969520FC6183E216B4E8E449B0FB999F1C65567AE2064774454EFDA67E1749FB24A91B55DFFE7DB75C4E24E8EF2389214EC3E95972CD53234CDAF8958D651A7A95802E65499A8A7811A65ABBA90129D5EC4247D8183316EF818E79BE839BB3379E4B8F4EE9438BFE310105C91F8703AE94D8F9D53096E2341E74E0237DB2665F16954B9713DD9638B05970A9A96261586B04F9FF369028DCC43D35B51F95E69B0323A1CEACC4A5E2EF640CDAF3407BF5F5E14C9042FF299786BC55965EB7C8BB161487FCD7911BDC2FBB65100F2200E16C690F801EA6615F9130EB99DF816B188B06E9A3105B78212B76609DF190FF102CCC451746CBAD16464E8E2F647B75777F664DE86F5089C37E3A54A6AA8B456CB98B42DEB5529C06DA45C2D2A13060BE56A061CE210ECD307FF5AD5BE39CDD8D27B4A3403323D4F53BE35FB4E31670F73CCE74CF73CFBB29A5FC2EECB5F852CA911942066D826404B77251BE5BC5980D0A6E0DB4D753D86490D4250536DACF05D82064A28324B49AD4AD202CD0FC939BB7A3CD9FB1E3E196348EF336DCDBE4BC831DF5847070D0B2BE1C4910FE1C69F58C6A7A2E7FEBD51BE1D0E050D5D721D7537A0325E7ED30AECA75A2A81BBD86EBF91CAFE4483D2729271ABDBB65C2CD9973627D2820DC7ADE3E26CA2F466EB117B2BA98EC868DC728ABC6907D49E2495504133FAA7F8758FD23076D1A65A91C75512F89EE4E2F3E480D6ECB0EE90793F4F93FFB75DF58A7072C91D5A1D9EF0C3B1DDAE79EF576E6A276F78CDC24664897F07B3A20691601EAD2F499C50589BDBCEC74FCADED1A8AFDFC061C2712ED599D48A3ACB3D86515D664D0CF3FA349A1910CB""") +683607bb0aaaefc605290b064fb9b57f641f6303e7f36b8af42a63985f1c3b202fb40733ef308bc517dace0777b0c5ca164a8a1adac8dc44a320a4d81f924cea669ac48fb2d8ed8fd357e86e8c1c8dbd1fd3087f5287d24a78dbb9dfaac25abde3144d7c5f686afb07d4e407007363d2bd1e5477df4a49c4f6334a687f8a16964df2bc6e368de4b979d7491bc070292335dcbe09af01a54a759679f019d97b73eebba8aac0e8d10efe4855b54d5a74afbc70650ebb26370ae701c7647e4d5efb29697e31be934f4713bcfaa7969d9aac9bb021e73d5894819379bd03f05e8a724049a3e66fd5a0daea65448778121c41dda31d8dc805674bb44538970b2348858b2a0e323a1801d16eef04d97b4cdc8736b645fa242d333ebfb0b61c279d0efc19fb7f928e63c36a1c05746a3d29ec7d7abf8f3f5d3dc394bdda5708ad7757d79c29a40569e79791612a3cfa514b05b355051d7fddf24a0bde67e76dbd0884ceb3226fb61d48219f032909f979365cd2d33452dabac242fa9474bcd86d41738a1e23b373e85f1eaa6470c9ad08e84f212c71d49381bc6f29e813882cc5ed33148a40f9044f5b713460c21896c4ec5fc5edb5eb19da83212e01469f560d468817b5d4fd4af0665d2a47aa2faa618dc43abea75d0051a087b4ac513d8327e5a747a8c8ca0c6baa5cd6e8f0179bca470764795f42c48b5027e9506685c030c1ed45a197b566eb658fc1d3cbf27f585ac28f70fe942e2074403ebcf5d06065c6ba22b16e11bc2fef932c32ff316c95989054926ca812967e0447980a24ed6496e3930ec307de1785a72feb21664ed88bac3993f5e0845f53514963409e5ea751757b2c91b8d797fb7e2be34ba545ffcfc2191ea909265f2f056383b8f974096fb60eb01535718e60af1db55a8ac8cf8d2b753e9366521bc78cf6e9857391dde51021c7eab027e05999f570a68c851b8bbf3fa1e9ad605c07f9287506d456f2e8f25c8d391c3d6db6b12a8a306a1e642ebbb1a6ac481a5f844ac4aa3bf797b784e8d21d105fbaf699b342d37bf713e06384fe473a46f2eca96b09a64e3a05b46b24d0c795cbf2dad7e5ea935d414d162a8b74a3c47447a4c39bbce215fe864547dc4f647e0a8f29cbc6d29a2319ac497dbdda3a7b1b9f6154edb773cea671c353fe76ca6f4a5e160e01a2c82e2d5788628d17c077be6bd131c07a2011b5d40bd8caf784f456960de5d757cce1f0fd7cd3e1e1bbe08f00e20b4bbbb8b09c717036009b749bb8881938c3e0c49eed2949a93d3025e350a2aa2b2ba1cc55a60c13e63f614eb2e7861ea1afb2ca493ab36a6fa62ba85c7b737b061a465d8a719a16c68471c66fad823652b676d8a86350bfe4798f948dd794156d0461552b2e9726e3dc01ccbf1d805249c0eb46af62c2456109b57bbd75289062251b760ed80f1d5ffbb8a2b93923bda87bf5619fb8025c4128e7b3a4e4c2c5643b149fa9b1d0a4c06b7575f893d5f144104d313c47fe8e4275c4cd9caff44e0f234f970834f168bc7dd9a82f173d2a65c3f4ddbb1058ce70b37af74c7ee763d4398c777c38e111770de22bf654f44de171c6a49b405400b280e639f66b6376bf3b18dd9818302cad3d22fc2911246d89b82dca8a155790d3da8a6b12d65b3158494c8a84deeffccf53bba29d9fb83a62fd0666fcec097a75aaa7f6aca01a909b2f0865ad37652c90e339207bcd6a1ac7c7676fa26c7cd809cb4d1606172d40d2508ec259050ac3cf23210c6f977c52d121a5a1b4c26c597f8e6ba7fdaf9d4d83a2f605b1548bf58ba62c8e57f6e93629d01c3dc8420cfc5b2f8c5c193edfcdd3e3cb696aefbe19de337176994c6a7c4926d4579f9bb228b28f1b5ce23def5c67232d79023b91ac2a6f46fb6eeb47894c2b7cc46c8c14e3b3800a20760724004e20b9d5e17dba258528572bd2ba5013fda9ad0c5368d38252327fbd1340f0475382cd4cbb608605deebc5df36483a37e71a7544eb4bf861641b1704eb976fbeceeb295bb955e11cafa9b781eaa8dee2eaa9cec3643088d6e15b7dda593550f1197a1d08fc1084c30465a95701fb59b39aba26252131c2725788eae129c553789112108c433dc5cce3a5067ccf7802acf4c98b2951bf3e41f24abb2d840295fda825b1cea22248a71950411389ead7e2d55282d90491d9669519f4c0a8955826cc1351de731b2c4a8d2bd8""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +dcfa84201ba9bf3915847c6755f8868b513fb5abc116920451f113e2c481d599129c1439e36bb5f0470e44f09a581c46cfb63d935ccfbdb26da9977ed53c6c56717805caca6056b007db45c261932b62a7d0c09ad99317b5ec82d7c61b2d3b13f0480d65abc07376a2552c21317a4426e868925829bdb661cae4ad4dd111f8080f05018f7dd976725941d5aac3ae00c9e0f15681e8bfa3db983a29390c108059d2696c3118c3a4ca0d970c5c603bad8c109563b58e0a1291868e2283447017938a3acd4442008f7b13536c75b3353918469933588602ba5b856aab04e2a7735786f5bc0f30a616369cb405c35250644ec9687488c781179b42dc9801793b80af048ee1e9488b7c755a985b27b55b71761cb5c101692362c1dcc1f86b147e1c708df38acf9179248551927a49dd0a333237b0705b0311a632acb5990b674ef55427bf64c86ed90089c5b6ccb12dea12565979c6492a0ac8106cef2b432ba6654c65c9fb40913727ba261c82aedcce19369d479aac4c403f45584fa71a238207a332b8b9b7685ded0661844911bb4a052678810ab6c879279e3442cf92f26b1041cc2f6c30c1f1b8c394271f19309c26270d9bc59d81628998575788ca4fd59a09a54c1c78cfc4260e1b149c9c7a00953029fd62064f74cc56765ef9c01596692b12b144d20b97ae050c7a2b51aa16a1a037939e91a8253acf29218b1a760dca0ba5143bc59154bbb86c36bf161794966f42c8b50a4a51f9b6939970c16a846fc728aa8d6064e9e8a57ce5647288cba6339eaacba7d1e56073aa17b629344dd87799e28e97245d92235abccbbe490a55b0f02b4c95642dfa0c674118031c457027cf37435c586918e5480cc20542af3a47adc66f216b5f2fb29d63d874967814f85738e76b7a2fb04bfbfb3ade632d4aba4b435102f4b07def648351bab8c329c957eb7d423964ee61cc8245c963ca666331c10c1ca922a4595d962647271c34753434b06ac9bb2e0a3c84b89604e90b24fd366d65616be48b953a657fde9a87e0e0a59e770194644af2018a3cec7a3cf902261538ba8b6f96545112331b335926dbc1b9d89007c2ca32f21955a739995db6a7ec2300fea40317905eec95ad690592d8c8c2d4012703b0c99c571c9ed859e9a040787c00a1b055ef8cb5ab7a15b10064d550b27e076752ea8fea36496afb6951827d2ec90e07875fe0bbb2e1ac4498619272705db8232423473e90d9a61e23ac5aba208b984fc5f5779052a7f14a39106cc718c9178fe2159c824e59045b4246c9309318456735f1434c6c78c41ba09d04833a37540afc77a55bb39e6450aa65c3305160a18e7c84f095b2a34699a8303cdcf75394032e0e8474268602f56a8ce12026f4d73d4d02bdbf1699acc65ff289cd45b0c3e958ad85327869385b58c9a19a1a119755480c0a72f12c6587bc00ed8a9c0224773a0a892053722a58509e746422f6a3f21a5d6c199c583c302ef2a07096b90f10821ee036cd26b45445afce6c12ff935615ba1c77921457f119645021f880806969533e06a044695feb4857e94016010b4b7724849303c48ba2ba64e17d2738cac6711fe79b049c740869993d8b158295f42fa2a37f808022e698764b476d81aaa63971586f84a5ebcb0b578caf2f6a80dd384050cba2663c90b9a713fce515d7058494d5a82a160750f5825e5a907b1c523131a6494bc03954886c10c520fccf48e97f90f04346f7c3890338dc30688d93a350db4bf9a31244ba7d4ed1510a381f13180856a188036526f7c10bafb11284e87656f736a9764a67b963db67ba284cc13b734a6eb1a9094c2a5d342c2e504d87781f87c8320f21057dd21f884186c014ced432242d618b09c4237bf50b720a97b2d86934213bf5d044d25673c26068150228b19219f4f6a6de8729d10c04a7055d7bd3a5b3716f702c6db5f8c93b1536739535e8c83da1d03eb01c514b330592656a81077fc64b9682a5877006b5d7464867ec27c7238e0ee7761c8183a6fc468098917a620161ca01ad34c54da2bf82ac01bf32c14589b188cb338b7294527a34c971826111a6160793fab4772e264779f29ee2bbc6cf822dcdd5cc0b76c8c2fa8234724856f89108e79bd23a1a2ba163d1c988ff98c4980842126889b92681c523358d22adbbf41352fb8040963385438d80125b7b78a7bb42515971c90c01323d9b3e75697ee3729f7521301d11518b92154436843987531887631819167405c36c35bc3be88d957053237bcbe1fc59fde76f1fb1c0bb4ab166ba098e6c4b58d26ba606589c568601c507a6fb149e30a9ddf126a4491812813ed0ac12854b3bde1b683cd23c588082066303931941aa5856bb94a0c932c85f9b9a4796b9152172647221d3e611b94b667e0985bac481f69ca20fa04dd57c42adb71ddb51933ff36dff38bb580b9bb0a666e80372c8e2b8c29a711f484d11c1ce58025c17d053196b50ed28342fba9b24b8093b7c286a4c1712346cf886454868ba79d53fa445733af9582113c85408c2e8473a3bc358af200cdeea56e44086e1179ed300204dd6b39815616dda5923dbbacff091970a57166b0ab5f1b25e1c1d2cc495151b97dd1aa87903204cd3b3b19830ff010d4df31ac3c7623ab64d951c9fd502ba14f4c884661d65d249c33b2f8d225c81f99f3bd88fc5a71f40722849b6b838c754a11a3b8bc8673cf900dc92b6f4f66b139c76a420abb5a2be9592ae1f3045a8da088871b45ab66610b64b163b38f641beee8a9a8f13a30996c262b2b9231241b34b5abef4830dfa922ed98a75f61cdd59666e3c728cbc8a6132a343a458beeb0702fc962439b2afe7b971ec62aa593cbe874b8a8c923f963060d1ad64bb6ad1dac893cc3ab5188e7943cf184b7b18ab26133ba4109a57207147f5e25e15302da5e82069aa721f77557c39c760d28cf37715f7a943de605193e29a6a94ae821675eb2b3f08ec4d7f0a99c5e71cb01292b327c107b61e6bf99066d74a9c8b47e99a05d8f2b9a1a5b12723c101220c57b509a42c5b28e853dd75251185661b61499ef978bd1ab9b92864ce013ce2123515ca5aad6b108660b4ff1492bb124f5bfaac592107c2678c5f04c2b658bd31cccb7a09028f48a245e638e8bcad19bbb2dfb6ba3bc10c487359b3b0421eaacdbe033b6d7a8d5d2311bcec5148226d4dec2061265c25b0746af8c63cf99f687a04c237739d648de7919cdb59973ba35d85187d20212ea537cecdd9c68de59345fa0dedd31ac6b21a7053adee561851b7be01770e07daaf903c2738dc835cccb05f5a931e2c4d2541a8328983d26b20de5bca159973bc01301d0541a8e311ef7046ee9b51a0f67d5202d0ea8c8217226a622b32b684066f2a000ae22cb1e29b47176e7973b3e9d4c18f22919a89a6573147129a43998886e8d95c804c15a01084f3d81d7f0288cfb34276536389344ed7c09eb47b9d20300abfea2a0b2878090819477a640e39cb7aa1643d4a59bc6488494a0ec3073dad9706b752c30b123fff3a1e66a8b575587e3b119d83e1b833893056b696ed49a399d11278f23f456b5192fa324fc4222dd247acb005dd50c918893819545f59b8b5550bd0a3d97ec24a5c22d4b8fb12290ce4cc96528893f772dce5c52dc0114f19c6ed026928f1092349475a020739aba5f5a45b8843157a76945dc84e7284572395345e695090b37edd895b22870b39ec07b36867b5dacff5392bede2680d74cc2272713be24ed37a22e33c36a84ca9643a46c68112a9d12aeaf67bc3160080113bea680d9b1bcfdf75be1c18c9f2e44781b18b59a090be8aa957c366a4b24a33b9b6d055674593470f37caf456b367fba266f34160d4cea1605d6140be110a93b2a57e06dc811b67572510549889002ae53dbdcc758fa1aa2e4bce4d6ba0dbd09ff3f736ce630c7b454096d6415ea32b797404f598c4b02a3dd6c98332b7440735a71124178a0622194993b442c5596bca2caaac46d77f6713a547980399c18e5685cd9dc879194cab66b99de4e2888952808b15c1bab5b712ab3e0c781b209162818cb3985b77f4e915e86779ecc5b2096104f512cbf1162b9aeba6a3546397e608d23861fa3aa5847a4cbea7229f5338ac4161b9765d74b175a4e95a68a6cebfd6ce796214163ac5b314c0deb2a3463b1f7e56b6ada724a2827f60647a92ea4f33d36d7683402fb12543f73a2804abd00371073306f06aab9705819091c9afab226514bed5c46f8c3c8046787602501d9d4561582164baf07497d09beaf06cb2a49627663e04cabf05e5bd55f9c0f75ca0a93678ffe69d7f8034b4f0898ce5ca9a26f52b3bae41398ef444b73decfdace24a6d62657cfe717bfbb904ea4bde70180c895d3559ae762a856ae7a8fb57e1ea35ba8d4386aac7d50bee0032580858865f638c38f0852d2d712a708ffbd7d96f0df21071d8bfec74c2302ea4c5adba"""), xeh(""" -EDD3FAB8AEB1240FB31B836CD1603E1F904BD1F87318DCB02A7DE18B4044385CDB51E343787E583CB043EE23899658420F9DEDB23CAB2BCD1013F573C0C7978521596631F6590105CB7B281AB1591B7056BE068DF838E0B1679F3B88D95208EF4B3019625EEA7704CE79F33AF339AB883B0C48B3C4413921F43AF2515A85023B5D98D06E619238C8D033FB7DD19611CC60CF395A03B0681913B299531B13728B278D353FA093C633710B65000772DD6D7CA59C85DB62196DCCE1B75559ECD3FB42DDD8E57EB4CF3B4E35B57EA3D6063221B81F1B802DD7D76DE308CB0A738C3B5833E9F4427AF3C3D79B521E7E665B052B9A365DCDFE5A688B06EDCDFA2143C938F852E32D6B49808CFFD01A8655B767034F8C638E8AF94BF3EB9EA39AED1D2D22E181888DD608BF9392FD73822303A41996F41D51A924FA6EF76A9C82709A21BEF1DD004693EC9468B335F9BD1FD94D5E6D89D570FC6D23B7F5CAD2975F418B8C4A0EB82EA2A3C979B1C15B0FB0A23F844764DDD49A8B89C0D4BC8C311BB43725EE9BAACC4796F58C0F1180A4F6AFEF45178659B35A74FF34A8E93A64FA4CD003269EC67C5BD528E015B2311B5E2D33472638CD65FC7D5127335EDA862BDEA05F4290EF9B370BE69DC89E7D71DD2522E669700D5D02D8DCD75FE2AD9EDC307225D61C7805CE1EBBC806A08BD360F86FD27B599582B22C57DDE77B08F7537482FB5D75BDB9F3F4EA07DFB0711C25AD1950058EAAA2E17D8F676BE6B72B1687383D8E0DD60A8277F6FDA202D6F8957EE21308AE81ABF72A89924DB44238B262D2FCE733E12E5413C31FDEF94860D5BB0FB0AEDCB1EFA8F87CCC76189FA5D8157FB4FB14652DC188157B2B746B596FE6F2FEB197DE139B80922C2EC14B58E743E3335893ABF85B99BC4566FA1BEED449658C5993CD08BF78F7DBFF808F611D6EB8F0BD7977E854BC195D711C03EA532403547B6ABEAE827481BB5D53C867710215835260097B6CA730FC722A74E230434B08F38EB1ABAF555CD4CC6CB9310E32F93E0ACAC1E915A4B57E0774B013BE7DD435B5C6AF6018944349841F84E8C28260149F266C99FC05E0DB8D5A63DE362CDE45F5BDFB6F30D55A84ACA22E8640A1287DA51714F2C8D4B184A5F671E0E907134E34D875C9A4709ECE3B7FE15713A0DD972505298C18A9D35956149EC9AF45C475016D7C8B5CBFFE2108882B86FFD380A79892BA1909489E016CF9933705E2FA72ACC8569501553401C397648DC47948935C0197D6F162464DE42BA537611CCB67A988030ABF6081946FDD1ED8C6B23691EA160E8543735894839F13C270B3E1F68607A7EECE09AF06A34F4FC9096D4EFFE4905BE56F3EB397C13472F6621F3EE45A59C8001ABF9302E036BEDEB2E0EC92A03FFE0DF52262621728C6791C4E7D8C226D17A04B6E7EB2FF8586585D639B449C85224EEC67E30537ABE85C8F7E2306DB80E968D8585CED3A9E21622BBC38D43A7D79E2457C67307CC208064D3568C476ED79359CD0A4B0BECA02FA702661056E187A51C2D154638F9000DF856ABB82CFE12C47543E46FFDBADD2DC69EBB3FF444E7E1E95235541015E6CC7A0429C82EBD6942C6420AD598C08080DCEC800509C142ED5A642951F491E748B5436148B90ACCBEC35D0D85FAF4E472ED3F1A089113808D3ECDF77EEF3E089FA5A1635B90EF99034AAA49D4D13058EAA5A8797E37C59CEB86C7CCFE1F574E1086DB9BE744BDE5067AD5D6C450FADFF2338DB110736FBBD86B41B29C29D3899CE60E9BEDF775416541350AAA9BD9B5D57573C542375BB0297912863C86AAE39D153CCB29F1811CDE58978951CE8EEFA6F9D10121AD1FB89F02AF8E96AC08DD10E3274E8CA79D910667166797468D3D3BD6D7EF5F2C6FC4F110268A2716CB273F29BBC347050BD98BDD88F30A96E7A9E840A55087F42A09B03D04E612640BA4D86BE87DA6D20ED0ECCCA2523EE7C4E9D2A96E7378BF71308850832769417EB6250FC768B0EDF92FD45216A235435A3E32AE5B22BF913027D81B0D5508D2AF88120A50206DD7837B79C45B21DB4FE59D23F4AB051BF012B13F6EE5B34C83C8D8CC9BB35266D0EF3834F52CE6CC5BCB7C5989198465A9E9DEE1A1F262FAB26FE0D0964E624869DF2607858815418F85A1F503BE5217794CED29D02E19D40C4BC8E65C46FE3815C1E548976649D4332B1841EA03022""") +744266fc2795dae658efa879de343d6831d4d4d778afb0f064fda23d22d976434ad41868ba11ac4e73588ff2398b2985150eed716b430f34daff5d1f7365d3f28777e2cba704d43963e2a906a197af491e192d8308401b5cbe38a6b48053a62308e54593935665e78e70636146fb726096e90c796e88c0462827cfee8462b9e6e0762b061aa685261aa38bb6364ca84e14e07c81d0d02cc65a14e49683095573e628d54938bfb4997381461a3801306a2fcffcfc54cb834a98efd328fb516d04c6f8334b839a7f0fcf340874cd94060cd926c24a201e98901890c4fcdf8e55c8a485e245a37a618ca074097dffd436b1caa2b900538a8b35096a9fda5c98ed5031bb25d8ba86f5285a003a7aad4470bdf7dceafbdb46450020723bcbe8a44babd45faaf3ab416acdcf0564c0b513203c8b3bdae283145063b8de3bb045e2595d2e72eb324fa2c4ee7d7bf5685684dbd69ab1ff5aa2a91f22a9177c053e5a9b30aaf7334425fa01f223b8dd846435615dd7434053397cf0b9e4ad650365b847298672b80950a9cb89b4258a10b9e44248f2d06a6921c7b87441f72caa127e741958fbe42565770eae9b2198370c2d422e7c3baffa8fc1139d2da25e3693648da40dfb8f18eeb84c70276c198a31a0ad3372285d50aad40d7355985c574694abd8452231ad2b862545bb3a620e477ec23dd592ab6ab2e91d1ad0b185f8c918484a4b44b2351d8292f00a025c23f758fec9be75398e83df275f52b8be0d9dacf3d2aa57e0055e67cfa0f872d60bab9b6c3904906547d5a610e7b0f1be8f6d081b608edd81ec0b0c6c45f625c9da548a4a1a119f3d9b2793112a4d7f77c9c7ae4ae7e48678a1e536658ef5584bcf8a7ae9f9af9629f697fcc932d365c7d238834c633a703c5b29e9a8e4fbe1ec1c42ff5ecbb9eaaa70903c92b9f66dc6660eeff2b4e8a563d5b39cb355e8df23b017eb7d38e422288c11e4a03803b0ed6526148b25c847968f554ede044c91ee8bdb9a1717fa253e65f2e5387eb19e84a6ccc5929e1366b4bf1e1af72a60ed2e674e54d256da46772b474dc8858967edbaf79c6780a839b2a20e44a02f06d1981b03229af586ed809da1b34d154e2ca64a1460f3d14bad117c39438922fb300398cb9a17dc266ccfde46da47f4dcc6cf54ed01374d3d16284eec4f5ceffad0ddd92b4b7cc0cabe0992b076e1f06ad2d746917ec8c0915c73121a57217a425dbb672de08414c22a38753d6a0738f9609bd15f26be584290829650025e2bd61a121dce852ed9ba96ef487b1cfe28d682e01e375753059a78e6dfdc3f9a703c02e8ce4565cc9cc3086ce2f0a692b4a791c622f73a8dac791440a1dd625f64f7ee8af1e4a9cd8aca89bb697d0295c40489be97453e46e1648998aea2bc2a53c053b6f89e33c9dbee8d5ee607b3d9b212322c5d6c1573612179964f316131b0a1f3cc7f107a03ace199b1033b64b6a36b456f17028a53699b729a663ca99e30c72d35dd277509adb62646647c2e4f2b4d31a7ae3e83b9d82ab3c0785ece85c765a2a1473af5bac7cffb1a790c73161221b45acc0b1dac261959b1e2ae2a18dc4bab57ac5e793c4d58661ef836fdcde7d8a187345cdb357e5cc9d32fa16a194873fe32a03fa31c8c194f7b63cd9640398518a1b12ca69ec6ef28c4a1547883277a94ffba92416aab83b240b034ea3597c8dab9fc0859f8c5fcef50eb00705a5b21a015939a9319929729bc43b43f36032b17781cc062b46b23a1533c981e4bbefa2ab32a81b30a4ff5655070f765af27022b4a7352189e52ba9e7e7a2c1f5eb1d5238814677802356a8f7ca849402430bc2a5e6c7323a9a2b23401876f4c5e4cfe56214fd667622a2b5e1eb054552fe10fb96788be387a68564e1516d9be5b99a76cd0431f65cdf85de40a45491d5b25071efbafc7c385902b913105b9ae0ef20c67006d72dacd4097df75e5d378fc174099079cd126729e6981c0f9a82314debdd86bf5041eae98aeb754999db6e426dc8e3a6fc5b17cede84d4b1b65ac1ef519a325dc5abe2f4ccb32b5cbfe457c7441b156f39dd4181743a4378361681fbbd186479b7e958472fcef7a0f6ab47afc8a858a5fc2e5c64d55a916c9484978b5e747cf885bfc9d2426443e38cd3cf13d57bd18e0d0c5478a86e20b1db35856388c4963fa1586175765cc8293fe5379cc7193d19e97e6bd34""") ), new DecapsulateTestCase( xeh(""" -8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), +c58540ef1a9e5dc496f0a413f8001e0731abc1b169a1f0ab030564ce03bb10d75a621bb8410b2a6186c6ca081944463aeeba6a45494fe1f1c9db2c48cf089cfb928d3de1cc6d02556ac7607af731cce7cceb00627e9a55a85c6eaa430dcdc068d79a8bcc8b4820f61cdc7214c64caae4a096d71390b95ca1bf243f4b3598b800a38804ac2ba7c2484b0a9d2790c3b91df06a40f5eccd52a36dd524b1a2831e915643063103961a01192a1fafa56c48e90828c359944857226a62f93b053bf550d5247077643171100b01309a3d344995b85fd1238fb14a73f2f03b4e201cd736c4f73c5ff3206c6c89a878178d4010a94963c025f090f2d32db71252a06acc88d7657d1a811b5052240ace860a217597a29d5041868a6bc5b278f0b04726414383807617b81bf7623186e44ef0695b97291827e0bc9fd92acb014714e151162a7b4e1ba04d5221bda5b2faf2ab4657853daa21f2b726f54a9bc35ba271d917a2bc1ec357957c094dbc683f03a5710344bba6242fc678809cc71d9a2a76a2a64bb0b8c5f66212a5a35c5e309b61c264cdf418bc27635d7751771cc875318c9f1b0df70073019a89a6e124c349a279f431f14b431ff11b0cb17ec3eab1a2a4a5bac45415825c4ec76016ca5f25581c89083f43a863c08092a8849d45f512be71870be0c25416be17c02e20e75cd519a3c43a419a3ab6d0c55752702612e298489559effc83f244510c987b247009b7d74e43fa56ee0179e5949a050b2a961c6a74819451058f1a624e9dcb47bee04411cc3bef260efd21acc3485d99d87f48a04512e9642eb37ab5d21cdbb21cfbb15df320cf887a9befc60a366a331e3b3be06a96ce46cf0fe559a6205677c62e30b964c53b669ac82a1e900c13364552c50c9da3a8355a0bfb97ac13695dfea28abec17016d381ccfa785e070a2f5568d1fabae0b6128d820cee749300bc482988b735e10a6629408f4242796925fe5a64d2d47b46db6e7c078c294aa6b0f87271a80f2b4015967564f30378768553f290b3df99a0c7008e99f1c026f7796ffbbd43b092c009821b58cbdee8670a1894f47192b4587429d3a99efa95bc176af901558db0280e0c62fea04474ac084ee960fb6604327b391c2ab2fce53eb5345966d8bdda98a107a210cde574b91012ea51b5860bb86c136b2389cb0565ba0e29871ba1b8b733755a3aae23e330a2a3b98af8204537aaae670fbb087e38767961641718c469eb7ab99616c402c8abc8544c47f733374661eaf0b6025084b2407fd4680a1fb57b17681d65ea7bab457eb2858e41fb9863646f30c2aca073b894f4723f727ff2b52c59e33987c4508696caac603f37dc854c3c6c98da6b69e5b20f917537a7ac2f37bc941303d9b4c38662174ea7c4af651d751684fdaa12cc6b6e0deabbbcb868165a28584410dcc33db62b446d23917a503daa2b633dda7eea324926c773140355a0571cb24117ec433aa1f2425d90081c45a47dba89106ba82d1060661a681b26c899766b13a000e6d9c0fcb588ceea0cdcd703b9600adf105819608cf4b81bc8c8c14ad38ec3b0b7def92f67f5adcfea5dd85a058a87151573075fc5916dba1208724202316ea14104570aba447339280c5d6a580137378390ec4439251f93326c423c1b84c4abefb78ccfc0783856b3793c23ee401da23c5eaed04302395b672316719429d8b66b7b33198792af7257b3d8ab9077d13a055c40fcd1874b8a8aa8201dfb76a396b534a1b2aef9824107f04a81dbb87984433b4c8e1e7799e2f7c8a284b02780704ca3218333894c1571c96671e2e0195d3a01aab22739c8917409c794072c83ec90ca1a78b7b1c6ccf48340dac772f46c33c524dd6a58e9e281249111fa772b1781cbeb1653876122f0146448d81c63f1279510a7ec528f78328605a21a7f8a0844d30b96a118c775832cb6b281cc3e965924cc4c6847651d3dfb434f100b509c0c3d66537d47219a77ba9922a15e5c97550bd0fe561b9109bbf89c555c4637daabc2a9620fac81ab69dab4de54529a957b8f0184c790403a379793704135b357cd8155517254255c254c982dcab7a05647ad73e1184e1aba78fa5c8ee24ef5183e873105a89c54b085c7f8404278697f212678fd3948d423707f957880b54611d04e05965db36a6f80ebac6014cff91b17321b0fa32c4d1eccc3dec3707cd34c7bc63e62d2b57ec0314b659dff4263c0f2c5fae2a37a84b0dd415275b3452894904ef146f5728a76a56c9447988767390a693ff7e91fa6e36f3e5a5b42b97f1205704218379231169340c416f4737e06364b935186e79a6bc0912938ac1ef818d57878ee872af70c7f31e8a5da0746ff4137e8f9b6bd7b4b32b47e12660b239c77115c72741c74b8dab0fcd07180c35e0adcbd2d58b726e3775d288a6312aa158620022b623bb29e141c33e0532e5dfa67da9476f49a6f4e6b001597a54371be84d70d04340c2f403db373a1afb102780b5050c841d98b10af489a39f8c2e473c23f202f05a20dfc4844cf1126c562cc9610a98b0a2d5407169db917969b1aa5c314ccc96290d2c27743b1efdc410802c78543ae40686cff6b3dca439e243c867d70bb957086abb6a91b49c7a39bc2dd107f65c7bba534c1216857d2b1a7ee99ca0556b3405b25da0a0941f403d0e34677e49d1ca84f267bc86ff0154614ce5b3526aec88f95285c316175e15b4fb92bb3d2a99d70a0259ed295eb87b90b5b2f5e2a757692262866c70a9cb8d843490e563594344e05a4051b3155fb8817ed53431d5c0318146cc31b0c524b6410d53aa0612a51f1c763941c4cd42628f212c04cae54b6ca05a5afdab8ba54f5666a13396006afe7005f612180002d1005795c468cca3d778938e187b00bc29220266047b22df76b18040160a48e6378c99fc5afa4020fb2b135ca913c78c73363d93d10677bd6764a27221ef2a2600f5b867b52c375cca78846880ac448f1086ff678220b7a238675b740c21bfec76559d573a6a84190c750cb502d9c7663d50987876b607f548ef76b764d03b704781d3b324ed2d7c1ad285a3e1ab1e5d6c7ff49495825b1b41a5ac2f524bf27c2e875aab1023c5f058f1a7881c3e60ab9fb56d15562b6fcb8c8c04a272c8ee6c807baf6227330071e6c49c8c805b89b6acb2025b13c08fd9916cf40191b9520409a6cfbac821fe8951c027f84a11dce4c54db98be7427b724331c64169aec4304cd71128448473f599eeb8239b1463cbd43c0836755170c19b3108dbe42bcc290cf23619a303230f9b0982c3b7307734e940807245bc097649d2eb9ae2b0695fb56b16cf90eecec1a50c5157d48098a063b53158855c9a1f1db9ea92b7bdc2488bdd28c095ac4e3374311c2754cc56dc8e511a5bb4cd486cce605527d594ec1dc1356b9bc938c0488b6b6d53243f2443223ba200b0c32c6f49322545ffa8a2b1bab914a72918a658b6a053d91249fe0c20360116eb3090015c161d4480d492bc7644762a48b3f6b558eb1f9b34cc39398cb266be91c414a3ba790c9c92129e5d40ddbd3150a5c002f763484546519c3a2ed327192bcc80f4710e8690a8d30a36059b12df6c107d1a73d9bc57796ba08fa01fc0c2a4f8b7a63074786729e0596615ff4b7c957959ffb1c5537508b191507e16d33d1bee9eb2148618bc8b279f0e92072b8c037565251992e87db4c0de8775d151ad13b2c375a46688518e5a2c409e32b9f314e3b177d72a908f3fa0010c87724aa2a94ba6a2728824719c6a1b0a2e07c7a364a0a62cc2730966ccdc96eed27341f77389a854fd12b9aefc0aa4c59a8aba457c57222e7065be09b593dea82279c8f67971a46878bf557b8dc095a9a0241d3b64ebe02137ab14eecd7410bc70efd3c08c1d6220f597eeabcaeb4a7b129ca73fd96872077577e44c804bb55d02607234961816b85944913dd83c5c835b1c0cc94f871a29073b8912973dd430246f84780d51ab9e163cfec5bc3472e02377bc9a2760ef5529568a4497c556e9a5f71526396aacc3e86158ea4189906b8ac277a90e383e298c8a1b98623cc909f18c894daa83338bc3f3b57152cc472889ba297a533d0554a3186229a8514c9c4826725249c61e4411963329eb99a37a4337e24c2257e5354ec5c2e4cd85bdea15c4e16cffcc628dad7c3ed9066287b587cbab64f0ab3aceb69494a333d240074c989cde4932d291f8edb065577985f68421d312e429a15cb21b31576c8d0b470c2177cf7369d45ac839c5c191acb40e62a115364c8875883ac507e5dc90a6cdbc6a540b396b422e488bc7d25c8287b79efc32085758d593b33882f218e758a3186d9cf309538fc57b81edc3ad0d228aeef39b32aef07a4054c55a1b8e412d907ce76b043fc9b10de7a9d3005a20d9c70d011dbad1e53a7637a741a60c9f1715c42a5a9e67b4e69e5f128372002a6c4f54ae5869500171e2541"""), xeh(""" -C72FA15560FEE6B014E73F5F93C307F74EF9C49AA8F7DF578C002AF20419040D6AB6AC46F78FB03F56A9C5C95902D8CBCE34D79853EDF0C319AF5469E32D0B9FC3C41628970E0B3A6C408B509C74DFA218BD23FA7A11DEA2D2277B3522BEF6606E3415D0DD51556440CC1AF59CAE6F23368BCAC3E1509503368354D1E3EC9E91F8B2D377DCC323D578DEB222585E43F97A6D1855B576297F3EC39F5F9EA1B2F72A0E701DB35D633DBCC5FFF76A2D39AE9DF2A3F6326B7671A4C0BB7177897DFF4FAF9FE5CFBCC94966BD298EA2627CF19C1CA866E5927C6E41970F544479D9A6D814AB72E2963F959CBEF37BF905BE98D8C8F3C25FAD3983F71D0C0D27D9FF17E4B34C2F8664406151E92ECA980F6CBE8F8926638398C9BCE9C69A92A30CE82F28CB4FE4110EAC40437BD64D38412030FB8DB3A4242672807737E707E59A0ACFA782127EFCB7BCEC39DFEC55C3109F958E86E0D381C4E9E9FE43110517778C08A140CF440F209011768EE34E5742ECC1E4CED045922D698A29E5557A29C237885D8559F110E4B540FE1298B97920EDF59BC8EBCA11EB91F471B6647864B384AE5A6BB494942BB1F537301B39EDD6F664E4A7877C173614B09D981401D5AA98A8BA4BF1992DD7B7A65BCE7E87FCDFC7B29AB69ADDC9036D71BB9BC08F4E7D9A57B784911CEE7D0EE5A559332981B6475290FB4410D8BA1F00FFC4850031708EB6A83AF524447F491CC25F23FBED71476FBA5C64BCD50D88A3ACD2BE1DF461B11F6D537B2929D073FCFB9E2545E1B097A12F52C411B2AF6C20A27ECD1C084568F4A76A87A4A79F7711012CBEDA777D913CC6B15E6C4E9BCE2C773991946CB9CEFB7F105B15FD2CD3E721E6C1DF69B66BEDF2157ACAD45458FD8C9C1AF910394A13C300696BBBB5B1E1145076BC6B9E3D30A680EA29B6370618B47AF77108EDE6BFCEBFBCFEDDD27FD9F0DA6D289060095C4E309DC3D26DCBFB9E8AF34E12BDD335FAC434663D4D802C8B04AC884352D27739C4DF22F3D7DB38084BAE2C0A15485DF4E356DF2FFBB5BBACA78D0B4886909C4482A6366991776B788C0941437BF858DD83AAA50104D725171C09B7DB521AA65CCCA3CDAFB2E61CDEF66B55D80E201DF44654E7B1FFCA29EFC1E44A8CBA406C8DAC6207C0BD5DA964FBE137ACCD84405A94F5F51D82CE701DD16774BA5F0A7A2BED7F9BB9A4F25C3095D1F8980721A7ECBCE957825A9BE9F4F818E56D35909A3F9DE5487DA0011EBCF9F4D768B72D236042175ED599D731AAFCD45D3D837FB8B64304ED7F22A8C3949BFA25B83A8C05FE9748F63A38201B460E16FFE4329C8464C9BF07D45DF2BA9AE7A84DCFC4CAB7BE42CBD360F61051CD56F68A71FE9E78231986832C9564D02B973EA2D3FCDBAEC374612C1B74DD483F08BAC30F6C9306E7092CC8FE1D20B937AFA4BC605ED4398A8B81A470870E97EA7D51562111D04BF9D09D9BC07533FCDA1E8DA2F2823AD621DB169C99FB112E44FDEFD597B61160815A1776139B685DA9DF6B4C22F6FF6CA3CC46B3264E456E98FF1F301122C88D42928403ED0E0E5F49BB0B450429980ACEFA1A80DA26638B5D2310FCADB0836223CB0894E6FA014D351AE052A70AB5F515641F153509FFB90B8DE495B946AB8C7D7CFEF56D3C66DC871F1D3A38494EF6AB82066E96B9F2782D6B5931B78B7117C389D155759CBC1690897DA66E50D0865209887552C8A6035B8F6911760F8D0A450FB926096721D962877FBFD87D92C37C71836B8BB9FCE92B4637785DC8E8C1D379081C14C73872E676A1C854F1BB68649BD552B48D12F62B17E9A48CCAF63885899C7B781DC3A6D7DE7DA28E286C9FD644D3521F0320B7ECA8FD0AAFFFFF90DAEC85BA80868A2EC69CC73AE00AE29FF5BA37D94510CA19E1EDAA64F30CD79A58B42FC9A6402CE31AF54BAE84DFED8D0C76142A347542265B794A0AEF4A08B4B5DFCADBD56757ECD98F175D80B44121257964293F300FF750107C1B72463D4634EBEDF4705F76C908844763D0D6813FFBE5411FBBFE16C08F32BD1BB3FB8EA5C5339A1B0194DA543E64C1F8065CE526D2754EF95A287DDC97B790FF34EA37863BB166BF0BD99E3A961BC91C1A4F84B63700C9EF5D8D31CEC9E1AE33C554BE638D5C1217CD2DBA13CC143F969DCBF285407A9B608F859812E7F668D4538BE179D11ED767A6971A2AA9CBB545EA01998E""") +0ddcfac2dca44756fc1b11c740a2d9f197a04eb49fb236e8a72761c343e2cf6c0a15ece304fbceba5619f1eebf2ec4285dca695fdf201ec2e89ff040a0983603abc1ca303ffd8ffea696953ecba82d866e9299cf793de3be15122de05aad7f939c382305d89c25dfe2f056f788c7911d44926d15b80052249e76de754d408cd05f5a8e067a38ce8d37174a7b90c393d1f72cad0834a97659b08917d07c363fe2efbd2fe95b1f717b7283aa8963bb3bfc22d2de515494882d9e1b76ef5d29ac625e2f0c0f67be70fc406302c0002ca7ba7cfbe08c308a11a6543df01235697fd05f94feb7c9f9f7bca1fc216214bb4e96f4e9f265cc2b4f411a4393607c39b6e6113a354b3c3b93090d13824c05813c8b4b353f5accac0062d9927a3dc3ded66c35567bf0b21fa0933af66369beed10f17c08f1bf96dd65da973608ce1ceff65a8e6e6b65f7f335b9593752bc4bac179b8d6594a93cdcfedb26c010769d75744d4c8e422dde126c698df3d791b51ec526cd2e4e58a0d6727e0df79db80c876ca598d5e3ae73313b91764bae84e76556883e6f4f82206f367b041e5b53753316cc54dccb87189bda18a31e76b6c1579a90fa2d54bb901c82257b608ed3b79eadb9aa2cc6a96e107cfed0fd1cf906cef7abc6519bb674f5a0eabfd10efa47cbd6c13b21185085ea8efa498732e1a19c1d3fa85856f4f4704f65a920889cf96a7b52fefc3e2d926c5eeb9139ac247a8c0b73667e3b0e438da939ffe8bbf849c112aead11d8354d04201d34319f4c65c3e4a1125b018a22e2e246c1aba3943dbf5db4797b97daf73451a6067a669941c06d19531ad8b74d523e2bc7ee512cc9bb749ad4d2ed87357d0dba42098b5533d95419aa18ac3965b87ef2b41dcec80e9661a10ff077a098cb55a604d1f9059c8260b6b1a388d8ca3a83288cb956d2ebb0a5076132fefad9c8eba00eeed61a8a8b7d59bc342f56f6df694b5d85dc28ef87da73e8d5e9a29af336cb5996c9b1485c93a1f8a1a3cfcd17842d17635a15fc5b63cca2ad560824210aaa27ad7bb8aa3e16cad96be489fdc43d8245cfc3fa439d4b473992dbd1d3b913282756e2c60ee2fb125663f5837c4e12da4232ea51b75710da1436fce145ff43637f166b3227c1ed590d2bca27bf14a028940c81de99487a6b501a9106255eb81ee939ce7f9e2bbd6be754aad73bc287ad27430625e171bc3239575353f3782be69cf21d829c0ddafb8bd96614aaa1f9fd5ba1b0429e379d32cb76119da0b3f9fd76dc1b92b25057fa695be31fa5fdb50464d6ba4a71d6726be84382b84bbf63f538b5a2cc9d91eb449841afb18ab8279b4eb9e80155cf1eaa11a2d4a421d880c85d037995cb9303a3f5d071a226ca55031334fc1c4a1f2be30f7a4268441a987cee3233651e988abd40e3b1306f492cf412a207d644fb66243efbac5eaa2e6ac045283889888a59ad47bde45a7262c0b9470d427ae8aab1a1c589653bfc20c17dbe7e6306ef97c0f6c925f1a38b146cde1f6216deeba31ffd5cf6276e82a5c69f5c6e4b69899505e03a528f23483d0bf414ac0031fc329cb9971b33ce94bd2dcdf42b88a084725a98eb9565bc90f34fde114514d5b81f7916294745b42c2c81b8cfede599200ecf50c2a8f369713cf2a3ab69e8c8a1f0c967112500790e905d958457a04e046bae97b5f14ef782eeebd4454a4a4114ed46debc56e4c3d4beccda4a9e5ed3127a9e53f2906e3755e4a75ad6c387aba579a19493a089b0e75c7bbf906f73fc017272e3f739b6ddd46e027ada7b86b91ebdd70a5ebfdec11d1ef9434d305be66e2a6889028382e39536405137dee759636f437f5a2da8bc5f883ffeacc1d8ff9bde31010906add2a5d06bfae7c9921cba9e67725c17870998257afc64409481f562a04d4f3acac8d6b65d6c7db7422792207ae376e6b6a5f80d417c4cf08ac90a0518b8d852a8f4e6c6cc28c975e0080d911d24b06cb05952035f7ce53cf1a14c7079b52bfdca9bae9accd71175031cc28d359d89067ebc2ff1b5d6ee6249e64a42227599f54f36a278a73bb416f5d136cd370b77b432b57c7ed9b69f34d5e14b2f0f8b008e0ef5d9afab188a532a5b63ded634e8821adcae833ef5c5ebbb166bf0d0db45612f6bb5fc498b9478f903e305479c878cd8bef22c248336cb457601d5129d818e9a06074577c9c151087aacaa1f24""") ) }; } diff --git a/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java b/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java index 5d2acc1616393..1b8f838997474 100644 --- a/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java +++ b/test/micro/org/openjdk/bench/java/time/format/ZonedDateTimeFormatterBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ public class ZonedDateTimeFormatterBenchmark { private static final DateTimeFormatter df = new DateTimeFormatterBuilder() .appendPattern("yyyy:MM:dd:HH:mm:v") .toFormatter(); - private static final String TEXT = "2015:03:10:12:13:ECT"; + private static final String TEXT = "2015:03:10:12:13:PST"; @Setup public void setUp() { diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java b/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java index f04e5d015a22e..0977d2bc46270 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java +++ b/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidParameterSpecException; -@Fork(jvmArgsAppend = {"-Xms20g", "-Xmx20g", "-XX:+UseZGC"}) +@Fork(jvmArgs = {"-Xms20g", "-Xmx20g", "-XX:+UseZGC"}) public class AESBench extends CryptoBase { public static final int SET_SIZE = 8; diff --git a/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java b/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java index 9d7955f398199..95593b38b3be0 100644 --- a/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java +++ b/test/micro/org/openjdk/bench/javax/xml/AbstractXMLMicro.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,15 +38,13 @@ @State(Scope.Benchmark) public abstract class AbstractXMLMicro { - public static final String BUILDIMPL = "build-impl.xml"; - public static final String LOGCOMP = "log_comp.xml"; public static final String MESSAGE12 = "message_12.xml"; public static final String MSGATTACH = "msgAttach.xml"; public static final String REZ = "reZ003vExc23082309.xml"; protected static final ConcurrentHashMap byteCache = new ConcurrentHashMap<>(); - @Param({BUILDIMPL,LOGCOMP,MESSAGE12,MSGATTACH,REZ}) + @Param({MESSAGE12,MSGATTACH,REZ}) protected String doc; /** diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java index f3c934d9c658d..ea361b4975b02 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,8 +44,6 @@ @Warmup(iterations = 2) @Measurement(iterations = 4) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) @State(Scope.Benchmark) diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java index 55c33b36805a3..680d1626b2c62 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AdaptNull.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,10 +35,6 @@ public class AdaptNull extends AbstractCorpusBenchmark { @Param({ // "ARRAYCOPY", - "ASM_1", - "ASM_3", - "ASM_UNSHARED_3", -// "ASM_TREE", "SHARED_1", "SHARED_2", "SHARED_3", diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java index 4165785135cea..a134e04bd5adb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,12 +29,6 @@ import java.lang.classfile.CompoundElement; import java.lang.classfile.MethodModel; import java.lang.classfile.instruction.LoadInstruction; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.tree.ClassNode; -import jdk.internal.org.objectweb.asm.tree.MethodNode; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -45,55 +39,6 @@ */ public class ReadDeep extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - var visitor = new ClassVisitor(Opcodes.ASM9) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return mv; - } - }; - cr.accept(visitor, 0); - bh.consume(mv.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountLoads(Blackhole bh) { - for (byte[] bytes : classes) { - var mv = new MethodVisitor(Opcodes.ASM9) { - int count = 0; - - @Override - public void visitVarInsn(int opcode, int var) { - ++count; - } - }; - - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (MethodNode mn : node.methods) { - mn.accept(mv); - } - bh.consume(mv.count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkElementsCountLoads(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java index 08b1b6312b1c0..0a12c5214e7bb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,42 +27,11 @@ import java.lang.classfile.ClassModel; import java.lang.classfile.ClassFile; import java.lang.classfile.FieldModel; -import jdk.internal.org.objectweb.asm.*; -import jdk.internal.org.objectweb.asm.tree.*; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; public class ReadMetadata extends AbstractCorpusBenchmark { - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - String theName; - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - theName = name; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.theName); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeReadName(Blackhole bh) { - for (byte[] bytes : classes) { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - bh.consume(node.name); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkReadName(Blackhole bh) { @@ -90,43 +59,6 @@ public void jdkReadMemberNames(Blackhole bh) { } } - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmStreamCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - ClassReader cr = new ClassReader(bytes); - var visitor = new ClassVisitor(Opcodes.ASM9) { - int count; - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - if ((access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - return null; - } - }; - cr.accept(visitor, 0); - bh.consume(visitor.count); - } - } - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public void asmTreeCountFields(Blackhole bh) { - for (byte[] bytes : classes) { - int count = 0; - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - for (FieldNode fn : node.fields) - if ((fn.access & Opcodes.ACC_PUBLIC) != 1) { - ++count; - } - bh.consume(count); - } - } - @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkTreeCountFields(Blackhole bh) { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java index 8af03a8b874c4..19c8744203983 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,27 +41,12 @@ import java.lang.classfile.MethodModel; import java.lang.classfile.MethodTransform; import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.ModuleVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.RecordComponentVisitor; -import jdk.internal.org.objectweb.asm.TypePath; -import jdk.internal.org.objectweb.asm.tree.ClassNode; /** * Transforms */ public class Transforms { - static int ASM9 = 9 << 16 | 0 << 8; - public static final ClassTransform threeLevelNoop = (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { @@ -123,38 +108,6 @@ public enum NoOpTransform { UNSHARED_3(false, threeLevelNoop), SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), - ASM_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_1(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - return cw.toByteArray(); - }), - ASM_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_UNSHARED_3(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new CustomClassVisitor(cw), 0); - return cw.toByteArray(); - }), - ASM_TREE(bytes -> { - ClassNode node = new ClassNode(); - ClassReader cr = new ClassReader(bytes); - cr.accept(node, 0); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - node.accept(cw); - return cw.toByteArray(); - }), CLASS_REMAPPER(bytes -> ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); @@ -186,12 +139,6 @@ public enum NoOpTransform { } public enum InjectNopTransform { - ASM_NOP_SHARED(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(new NopClassVisitor(cw), 0); - return cw.toByteArray(); - }), NOP_SHARED(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -226,13 +173,6 @@ public void accept(CodeElement e) { } public enum SimpleTransform { - ASM_ADD_FIELD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - cr.accept(cw, 0); - cw.visitField(0, "argleBargleWoogaWooga", "I", null, null); - return cw.toByteArray(); - }), HIGH_SHARED_ADD_FIELD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -257,20 +197,6 @@ public void atEnd(ClassBuilder builder) { cb.withField("argleBargleWoogaWooga", ConstantDescs.CD_int, b -> { }); }); }), - ASM_DEL_METHOD(bytes -> { - ClassReader cr = new ClassReader(bytes); - jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); - ClassVisitor v = new ClassVisitor(ASM9, cw) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return (name.equals("hashCode") && descriptor.equals("()Z")) - ? null - : super.visitMethod(access, name, descriptor, signature, exceptions); - } - }; - cr.accept(cw, 0); - return cw.toByteArray(); - }), HIGH_SHARED_DEL_METHOD(bytes -> { var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); @@ -303,277 +229,4 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } } - static class CustomClassVisitor extends ClassVisitor { - - public CustomClassVisitor(ClassVisitor writer) { - super(ASM9, writer); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - } - - @Override - public ModuleVisitor visitModule(String name, int access, String version) { - return super.visitModule(name, access, version); - } - - @Override - public void visitNestHost(String nestHost) { - super.visitNestHost(nestHost); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - super.visitOuterClass(owner, name, descriptor); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitNestMember(String nestMember) { - super.visitNestMember(nestMember); - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) { - return super.visitRecordComponent(name, descriptor, signature); - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - return super.visitField(access, name, descriptor, signature, value); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new CustomMethodVisitor(mv); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - - static class CustomMethodVisitor extends MethodVisitor { - - public CustomMethodVisitor(MethodVisitor methodVisitor) { - super(ASM9, methodVisitor); - } - - @Override - public void visitParameter(String name, int access) { - super.visitParameter(name, access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - return super.visitAnnotationDefault(); - } - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - return super.visitAnnotation(descriptor, visible); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitAnnotableParameterCount(int parameterCount, boolean visible) { - super.visitAnnotableParameterCount(parameterCount, visible); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) { - return super.visitParameterAnnotation(parameter, descriptor, visible); - } - - @Override - public void visitAttribute(Attribute attribute) { - super.visitAttribute(attribute); - } - - @Override - public void visitCode() { - super.visitCode(); - } - - @Override - public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) { - super.visitFrame(type, numLocal, local, numStack, stack); - } - - @Override - public void visitInsn(int opcode) { - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { - super.visitFieldInsn(opcode, owner, name, descriptor); - } - - @Override - @SuppressWarnings("deprecation") - public void visitMethodInsn(int opcode, String owner, String name, String descriptor) { - super.visitMethodInsn(opcode, owner, name, descriptor); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - - @Override - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLabel(Label label) { - super.visitLabel(label); - } - - @Override - public void visitLdcInsn(Object value) { - super.visitLdcInsn(value); - } - - @Override - public void visitIincInsn(int var, int increment) { - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String descriptor, int numDimensions) { - super.visitMultiANewArrayInsn(descriptor, numDimensions); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { - super.visitTryCatchBlock(start, end, handler, type); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) { - return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible); - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) { - return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible); - } - - @Override - public void visitLineNumber(int line, Label start) { - super.visitLineNumber(line, start); - } - - @Override - public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(maxStack, maxLocals); - } - - @Override - public void visitEnd() { - super.visitEnd(); - } - }; - - static class NopClassVisitor extends CustomClassVisitor { - - public NopClassVisitor(ClassVisitor writer) { - super(writer); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); - return new NopMethodVisitor(mv); - } - } - - static class NopMethodVisitor extends CustomMethodVisitor { - - public NopMethodVisitor(MethodVisitor methodVisitor) { - super(methodVisitor); - } - - @Override - public void visitCode() { - super.visitCode(); - visitInsn(Opcodes.NOP); - } - } - } diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Write.java b/test/micro/org/openjdk/bench/jdk/classfile/Write.java index ffd5b8f1c5ed5..9317ef78806eb 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Write.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Write.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ import java.lang.reflect.AccessFlag; import java.lang.classfile.ClassFile; import java.lang.classfile.attribute.SourceFileAttribute; -import jdk.internal.org.objectweb.asm.*; import org.openjdk.jmh.annotations.*; import java.io.FileOutputStream; import static java.lang.classfile.ClassFile.ACC_PUBLIC; @@ -57,8 +56,6 @@ @Warmup(iterations = 3) @Measurement(iterations = 5) @Fork(value = 1, jvmArgs = { - "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) public class Write { static final int REPEATS = 40; @@ -70,76 +67,9 @@ public class Write { } METHOD_NAMES = names; } - static String checkFileAsm = "/tmp/asw/MyClass.class"; static String checkFileBc = "/tmp/byw/MyClass.class"; - static boolean writeClassAsm = Files.exists(Paths.get(checkFileAsm).getParent()); static boolean writeClassBc = Files.exists(Paths.get(checkFileBc).getParent()); - - @Benchmark - @BenchmarkMode(Mode.Throughput) - public byte[] asmStream() { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V12, Opcodes.ACC_PUBLIC, "MyClass", null, "java/lang/Object", null); - cw.visitSource("MyClass.java", null); - - { - MethodVisitor mv = cw.visitMethod(0, INIT_NAME, "()V", null, null); - mv.visitCode(); - Label startLabel = new Label(); - Label endLabel = new Label(); - mv.visitLabel(startLabel); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", INIT_NAME, "()V", false); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(endLabel); - mv.visitLocalVariable("this", "LMyClass;", null, startLabel, endLabel, 1); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - - for (int xi = 0; xi < REPEATS; ++xi) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, METHOD_NAMES[xi], "([Ljava/lang/String;)V", null, null); - mv.visitCode(); - Label loopTop = new Label(); - Label loopEnd = new Label(); - Label startLabel = new Label(); - Label endLabel = new Label(); - Label iStart = new Label(); - mv.visitLabel(startLabel); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitLabel(iStart); - mv.visitInsn(Opcodes.ICONST_1); - mv.visitVarInsn(Opcodes.ISTORE, 2); - mv.visitLabel(loopTop); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitIntInsn(Opcodes.BIPUSH, 10); - mv.visitJumpInsn(Opcodes.IF_ICMPGE, loopEnd); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitVarInsn(Opcodes.ILOAD, 2); - mv.visitInsn(Opcodes.IMUL); - mv.visitVarInsn(Opcodes.ISTORE, 1); - mv.visitIincInsn(2, 1); - mv.visitJumpInsn(Opcodes.GOTO, loopTop); - mv.visitLabel(loopEnd); - mv.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System", "out", "Ljava/io/PrintStream;"); - mv.visitVarInsn(Opcodes.ILOAD, 1); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false); - mv.visitLabel(endLabel); - mv.visitInsn(Opcodes.RETURN); - mv.visitLocalVariable("fac", "I", null, startLabel, endLabel, 1); - mv.visitLocalVariable("i", "I", null, iStart, loopEnd, 2); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - if (writeClassAsm) writeClass(bytes, checkFileAsm); - return bytes; - } - @Benchmark @BenchmarkMode(Mode.Throughput) public byte[] jdkTree() { diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/ColumnFilterBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/ColumnFilterBenchmark.java index e78bd2172a08e..6c6fd50069f8c 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/ColumnFilterBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/ColumnFilterBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Thread) -@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector", "-XX:UseAVX=2"}) +@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:UseAVX=2"}) public class ColumnFilterBenchmark { @Param({"1024", "2047", "4096"}) int size; diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java new file mode 100644 index 0000000000000..a0a462ad6b1e9 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/Float16OperationsBenchmark.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.stream.IntStream; +import java.util.concurrent.TimeUnit; +import jdk.incubator.vector.*; +import org.openjdk.jmh.annotations.*; +import static jdk.incubator.vector.Float16.*; +import static java.lang.Float.*; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector", "-Xbatch", "-XX:-TieredCompilation"}) +public class Float16OperationsBenchmark { + @Param({"256", "512", "1024", "2048"}) + int vectorDim; + + int [] rexp; + short [] vectorRes; + short [] vector1; + short [] vector2; + short [] vector3; + boolean [] vectorPredicate; + + static final short f16_one = Float.floatToFloat16(1.0f); + static final short f16_two = Float.floatToFloat16(2.0f); + + @Setup(Level.Trial) + public void BmSetup() { + rexp = new int[vectorDim]; + vectorRes = new short[vectorDim]; + vector1 = new short[vectorDim]; + vector2 = new short[vectorDim]; + vector3 = new short[vectorDim]; + vectorPredicate = new boolean[vectorDim]; + + IntStream.range(0, vectorDim).forEach(i -> {vector1[i] = Float.floatToFloat16((float)i);}); + IntStream.range(0, vectorDim).forEach(i -> {vector2[i] = Float.floatToFloat16((float)i);}); + IntStream.range(0, vectorDim).forEach(i -> {vector3[i] = Float.floatToFloat16((float)i);}); + + // Special Values + Float16 [] specialValues = {Float16.NaN, Float16.NEGATIVE_INFINITY, Float16.valueOf(0.0), Float16.valueOf(-0.0), Float16.POSITIVE_INFINITY}; + IntStream.range(0, vectorDim).forEach( + i -> { + if ((i % 64) == 0) { + int idx1 = i % specialValues.length; + int idx2 = (i + 1) % specialValues.length; + int idx3 = (i + 2) % specialValues.length; + vector1[i] = float16ToRawShortBits(specialValues[idx1]); + vector2[i] = float16ToRawShortBits(specialValues[idx2]); + vector3[i] = float16ToRawShortBits(specialValues[idx3]); + } + } + ); + } + + @Benchmark + public void addBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(add(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void subBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(subtract(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void mulBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(multiply(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void divBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(divide(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void fmaBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(fma(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]), shortBitsToFloat16(vector3[i]))); + } + } + + @Benchmark + public boolean isInfiniteBenchmark() { + boolean res = true; + for (int i = 0; i < vectorDim; i++) { + res &= isInfinite(shortBitsToFloat16(vector1[i])); + } + return res; + } + + @Benchmark + public boolean isFiniteBenchmark() { + boolean res = true; + for (int i = 0; i < vectorDim; i++) { + res &= isFinite(shortBitsToFloat16(vector1[i])); + } + return res; + } + + @Benchmark + public boolean isNaNBenchmark() { + boolean res = true; + for (int i = 0; i < vectorDim; i++) { + res &= isNaN(shortBitsToFloat16(vector1[i])); + } + return res; + } + + @Benchmark + public void isNaNStoreBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorPredicate[i] = Float16.isNaN(shortBitsToFloat16(vector1[i])); + } + } + + + @Benchmark + public void isNaNCMovBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = Float16.isNaN(shortBitsToFloat16(vector1[i])) ? f16_one : f16_two; + } + } + + + @Benchmark + public void isInfiniteStoreBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorPredicate[i] = Float16.isInfinite(shortBitsToFloat16(vector1[i])); + } + } + + + @Benchmark + public void isInfiniteCMovBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = Float16.isInfinite(shortBitsToFloat16(vector1[i])) ? f16_one : f16_two; + } + } + + + @Benchmark + public void isFiniteStoreBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorPredicate[i] = Float16.isFinite(shortBitsToFloat16(vector1[i])); + } + } + + + @Benchmark + public void isFiniteCMovBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = Float16.isFinite(shortBitsToFloat16(vector1[i])) ? f16_one : f16_two; + } + } + + @Benchmark + public void maxBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(max(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void minBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(min(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + } + } + + @Benchmark + public void sqrtBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(sqrt(shortBitsToFloat16(vector1[i]))); + } + } + + @Benchmark + public void negateBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(negate(shortBitsToFloat16(vector1[i]))); + } + } + + @Benchmark + public void absBenchmark() { + for (int i = 0; i < vectorDim; i++) { + vectorRes[i] = float16ToRawShortBits(abs(shortBitsToFloat16(vector1[i]))); + } + } + + @Benchmark + public void getExponentBenchmark() { + for (int i = 0; i < vectorDim; i++) { + rexp[i] = getExponent(shortBitsToFloat16(vector1[i])); + } + } + + @Benchmark + public short cosineSimilarityDoubleRoundingFP16() { + short macRes = floatToFloat16(0.0f); + short vector1Square = floatToFloat16(0.0f); + short vector2Square = floatToFloat16(0.0f); + for (int i = 0; i < vectorDim; i++) { + // Explicit add and multiply operation ensures double rounding. + Float16 vec1 = shortBitsToFloat16(vector1[i]); + Float16 vec2 = shortBitsToFloat16(vector2[i]); + macRes = float16ToRawShortBits(add(multiply(vec1, vec2), shortBitsToFloat16(macRes))); + vector1Square = float16ToRawShortBits(add(multiply(vec1, vec1), shortBitsToFloat16(vector1Square))); + vector2Square = float16ToRawShortBits(add(multiply(vec2, vec2), shortBitsToFloat16(vector2Square))); + } + return float16ToRawShortBits(divide(shortBitsToFloat16(macRes), add(shortBitsToFloat16(vector1Square), shortBitsToFloat16(vector2Square)))); + } + + @Benchmark + public short cosineSimilaritySingleRoundingFP16() { + short macRes = floatToFloat16(0.0f); + short vector1Square = floatToFloat16(0.0f); + short vector2Square = floatToFloat16(0.0f); + for (int i = 0; i < vectorDim; i++) { + Float16 vec1 = shortBitsToFloat16(vector1[i]); + Float16 vec2 = shortBitsToFloat16(vector2[i]); + macRes = float16ToRawShortBits(fma(vec1, vec2, shortBitsToFloat16(macRes))); + vector1Square = float16ToRawShortBits(fma(vec1, vec1, shortBitsToFloat16(vector1Square))); + vector2Square = float16ToRawShortBits(fma(vec2, vec2, shortBitsToFloat16(vector2Square))); + } + return float16ToRawShortBits(divide(shortBitsToFloat16(macRes), add(shortBitsToFloat16(vector1Square), shortBitsToFloat16(vector2Square)))); + } + + @Benchmark + public short cosineSimilarityDequantizedFP16() { + float macRes = 0.0f; + float vector1Square = 0.0f; + float vector2Square = 0.0f; + for (int i = 0; i < vectorDim; i++) { + float vec1 = float16ToFloat(vector1[i]); + float vec2 = float16ToFloat(vector2[i]); + macRes = Math.fma(vec1, vec2, macRes); + vector1Square = Math.fma(vec1, vec1, vector1Square); + vector2Square = Math.fma(vec2, vec2, vector2Square); + } + return floatToFloat16(macRes / (vector1Square + vector2Square)); + } + + @Benchmark + public short euclideanDistanceFP16() { + short distRes = floatToFloat16(0.0f); + short squareRes = floatToFloat16(0.0f); + for (int i = 0; i < vectorDim; i++) { + squareRes = float16ToRawShortBits(subtract(shortBitsToFloat16(vector1[i]), shortBitsToFloat16(vector2[i]))); + distRes = float16ToRawShortBits(fma(shortBitsToFloat16(squareRes), shortBitsToFloat16(squareRes), shortBitsToFloat16(distRes))); + } + return float16ToRawShortBits(sqrt(shortBitsToFloat16(distRes))); + } + + @Benchmark + public short euclideanDistanceDequantizedFP16() { + float distRes = 0.0f; + float squareRes = 0.0f; + for (int i = 0; i < vectorDim; i++) { + squareRes = float16ToFloat(vector1[i]) - float16ToFloat(vector2[i]); + distRes = distRes + squareRes * squareRes; + } + return float16ToRawShortBits(sqrt(shortBitsToFloat16(floatToFloat16(distRes)))); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java index 9f717908569a6..447eab012de24 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/SpiltReplicate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(1) +@Fork(value=1, jvmArgs={"--add-modules=jdk.incubator.vector"}) public class SpiltReplicate { @CompilerControl(CompilerControl.Mode.DONT_INLINE) public long broadcastInt() { diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorCommutativeOperSharingBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorCommutativeOperSharingBenchmark.java new file mode 100644 index 0000000000000..91851efa4f378 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorCommutativeOperSharingBenchmark.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.Random; +import java.util.Arrays; +import jdk.incubator.vector.*; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class VectorCommutativeOperSharingBenchmark { + @Param({"1024","2048"}) + int size; + + byte[] bytesrc1; + byte[] bytesrc2; + byte[] byteres; + + short[] shortsrc1; + short[] shortsrc2; + short[] shortres; + + int[] intsrc1; + int[] intsrc2; + int[] intres; + + long[] longsrc1; + long[] longsrc2; + long[] longres; + + @Setup(Level.Trial) + public void BmSetup() { + Random r = new Random(1024); + bytesrc1 = new byte[size]; + bytesrc2 = new byte[size]; + byteres = new byte[size]; + + shortsrc1 = new short[size]; + shortsrc2 = new short[size]; + shortres = new short[size]; + + intsrc1 = new int[size]; + intsrc2 = new int[size]; + intres = new int[size]; + + longsrc1 = new long[size]; + longsrc2 = new long[size]; + longres = new long[size]; + + Arrays.fill(bytesrc1, (byte)1); + Arrays.fill(bytesrc2, (byte)2); + + Arrays.fill(shortsrc1, (short)1); + Arrays.fill(shortsrc2, (short)2); + + Arrays.fill(intsrc1, 1); + Arrays.fill(intsrc2, 2); + + Arrays.fill(longsrc1, 1); + Arrays.fill(longsrc2, 2); + } + + @Benchmark + public void commutativeByteOperationShairing() { + for (int i = 0; i < size; i += ByteVector.SPECIES_PREFERRED.length()) { + ByteVector vec1 = ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc1, i); + ByteVector vec2 = ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc2, i); + vec1.lanewise(VectorOperators.ADD, vec2) + .lanewise(VectorOperators.ADD, vec2.lanewise(VectorOperators.ADD, vec1)) + .lanewise(VectorOperators.MUL, vec1.lanewise(VectorOperators.MUL, vec2)) + .lanewise(VectorOperators.MUL, vec2.lanewise(VectorOperators.MUL, vec1)) + .lanewise(VectorOperators.AND, vec1.lanewise(VectorOperators.AND, vec2)) + .lanewise(VectorOperators.AND, vec2.lanewise(VectorOperators.AND, vec1)) + .lanewise(VectorOperators.OR, vec1.lanewise(VectorOperators.OR, vec2)) + .lanewise(VectorOperators.OR, vec2.lanewise(VectorOperators.OR, vec1)) + .intoArray(byteres, i); + } + } + + @Benchmark + public void commutativeShortOperationShairing() { + for (int i = 0; i < size; i += ShortVector.SPECIES_PREFERRED.length()) { + ShortVector vec1 = ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc1, i); + ShortVector vec2 = ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc2, i); + vec1.lanewise(VectorOperators.ADD, vec2) + .lanewise(VectorOperators.ADD, vec2.lanewise(VectorOperators.ADD, vec1)) + .lanewise(VectorOperators.MUL, vec1.lanewise(VectorOperators.MUL, vec2)) + .lanewise(VectorOperators.MUL, vec2.lanewise(VectorOperators.MUL, vec1)) + .lanewise(VectorOperators.AND, vec1.lanewise(VectorOperators.AND, vec2)) + .lanewise(VectorOperators.AND, vec2.lanewise(VectorOperators.AND, vec1)) + .lanewise(VectorOperators.OR, vec1.lanewise(VectorOperators.OR, vec2)) + .lanewise(VectorOperators.OR, vec2.lanewise(VectorOperators.OR, vec1)) + .intoArray(shortres, i); + } + } + + @Benchmark + public void commutativeIntOperationShairing() { + for (int i = 0; i < size; i += IntVector.SPECIES_PREFERRED.length()) { + IntVector vec1 = IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc1, i); + IntVector vec2 = IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc2, i); + vec1.lanewise(VectorOperators.ADD, vec2) + .lanewise(VectorOperators.ADD, vec2.lanewise(VectorOperators.ADD, vec1)) + .lanewise(VectorOperators.MUL, vec1.lanewise(VectorOperators.MUL, vec2)) + .lanewise(VectorOperators.MUL, vec2.lanewise(VectorOperators.MUL, vec1)) + .lanewise(VectorOperators.AND, vec1.lanewise(VectorOperators.AND, vec2)) + .lanewise(VectorOperators.AND, vec2.lanewise(VectorOperators.AND, vec1)) + .lanewise(VectorOperators.OR, vec1.lanewise(VectorOperators.OR, vec2)) + .lanewise(VectorOperators.OR, vec2.lanewise(VectorOperators.OR, vec1)) + .intoArray(intres, i); + } + } + + @Benchmark + public void commutativeLongOperationShairing() { + for (int i = 0; i < size; i += LongVector.SPECIES_PREFERRED.length()) { + LongVector vec1 = LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc1, i); + LongVector vec2 = LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc2, i); + vec1.lanewise(VectorOperators.ADD, vec2) + .lanewise(VectorOperators.ADD, vec2.lanewise(VectorOperators.ADD, vec1)) + .lanewise(VectorOperators.MUL, vec1.lanewise(VectorOperators.MUL, vec2)) + .lanewise(VectorOperators.MUL, vec2.lanewise(VectorOperators.MUL, vec1)) + .lanewise(VectorOperators.AND, vec1.lanewise(VectorOperators.AND, vec2)) + .lanewise(VectorOperators.AND, vec2.lanewise(VectorOperators.AND, vec1)) + .lanewise(VectorOperators.OR, vec1.lanewise(VectorOperators.OR, vec2)) + .lanewise(VectorOperators.OR, vec2.lanewise(VectorOperators.OR, vec1)) + .intoArray(longres, i); + } + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java index 51f8300a0446a..a6c2db965f0e0 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ @State(Scope.Benchmark) @Warmup(iterations = 3, time = 1) @Measurement(iterations = 5, time = 1) -@Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +@Fork(value = 1, jvmArgs = {"--add-modules=jdk.incubator.vector"}) public class VectorMultiplyOptBenchmark { @Param({"1024", "2048", "4096"}) private int SIZE; diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java index 32056da49aaa2..8a40e0fd95b89 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ @State(Scope.Benchmark) @Warmup(iterations = 3, time = 1) @Measurement(iterations = 5, time = 1) -@Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +@Fork(value = 1, jvmArgs = {"--add-modules=jdk.incubator.vector"}) public class VectorXXH3HashingBenchmark { @Param({"1024", "2048", "4096", "8192"}) private int SIZE; diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java new file mode 100644 index 0000000000000..293a25ca7d0b0 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeLoadBench.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Alibaba Group Holding Limited. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import jdk.internal.misc.Unsafe; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +public class MergeLoadBench { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + + final static int NUMBERS = 8192; + + final byte[] bytes4 = new byte[NUMBERS * 4]; + final byte[] bytes8 = new byte[NUMBERS * 8]; + final int [] ints = new int [NUMBERS ]; + final long[] longs = new long[NUMBERS ]; + + @Setup + public void setup() { + Random r = new Random(); + for (int i = 0; i < ints.length; i++) { + ints[i] = r.nextInt(); + INT_L.set(bytes4, i * 4, i); + } + + for (int i = 0; i < longs.length; i++) { + longs[i] = r.nextLong(); + LONG_L.set(bytes8, i * 8, i); + } + } + + /* + * The names of these cases have the following `B/L/V/U` suffixes, which are: + * ``` + * B BigEndian + * L LittleEndian + * V VarHandle + * U Unsafe + * R ReverseBytes + * C Unsafe.getChar & putChar + * S Unsafe.getShort & putShort + * ``` + */ + + @Benchmark + public void getIntB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntBV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_B.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntLV(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (int) INT_L.get(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRB(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRB(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRBU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRBU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRL(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRL(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRLU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += getIntRLU(bytes4, i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getIntRU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += Integer.reverseBytes( + UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); + } + BH.consume(sum); + } + + @Benchmark + public void getIntU(Blackhole BH) { + int sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); + } + BH.consume(sum); + } + + @Benchmark + public void getLongB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_B.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < ints.length; i++) { + sum += (long) LONG_L.get(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRB(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRBU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRL(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += getLongRLU(bytes8, i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getLongRU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += Long.reverseBytes( + UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); + } + BH.consume(sum); + } + + @Benchmark + public void getLongU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); + } + BH.consume(sum); + } + + @Benchmark + public void getCharB(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharB(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_B.get(bytes4, i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharBU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharBU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharL(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharL(bytes4, i); + sum += c; + } + BH.consume(sum); + } + @Benchmark + public void getCharLU(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = getCharLU(bytes4, i); + sum += c; + } + BH.consume(sum); + } + + + @Benchmark + public void getCharLV(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = (char) CHAR_L.get(bytes4, i * 2); + sum += c; + } + BH.consume(sum); + } + + @Benchmark + public void getCharC(Blackhole BH) { + long sum = 0; + for (int i = 0; i < longs.length; i++) { + char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); + sum += c; + } + BH.consume(sum); + } + + static int getIntB(byte[] array, int offset) { + return ((array[offset ] & 0xff) << 24) + | ((array[offset + 1] & 0xff) << 16) + | ((array[offset + 2] & 0xff) << 8) + | ((array[offset + 3] & 0xff) ); + } + + static int getIntBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) << 24) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 3) & 0xff) ); + } + + static int getIntL(byte[] array, int offset) { + return ((array[offset ] & 0xff) ) + | ((array[offset + 1] & 0xff) << 8) + | ((array[offset + 2] & 0xff) << 16) + | ((array[offset + 3] & 0xff) << 24); + } + + static int getIntRB(byte[] array, int offset) { + return Integer.reverseBytes(getIntB(array, offset)); + } + + static int getIntRBU(byte[] array, int offset) { + return Integer.reverseBytes(getIntBU(array, offset)); + } + + static int getIntRL(byte[] array, int offset) { + return Integer.reverseBytes(getIntL(array, offset)); + } + + static int getIntRLU(byte[] array, int offset) { + return Integer.reverseBytes(getIntLU(array, offset)); + } + + static long getLongB(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) << 56) + | (((long) array[offset + 1] & 0xff) << 48) + | (((long) array[offset + 2] & 0xff) << 40) + | (((long) array[offset + 3] & 0xff) << 32) + | (((long) array[offset + 4] & 0xff) << 24) + | (((long) array[offset + 5] & 0xff) << 16) + | (((long) array[offset + 6] & 0xff) << 8) + | (((long) array[offset + 7] & 0xff) ); + } + + static long getLongBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); + } + + public static long getLongL(byte[] array, int offset) { + return (((long) array[offset ] & 0xff) ) + | (((long) array[offset + 1] & 0xff) << 8) + | (((long) array[offset + 2] & 0xff) << 16) + | (((long) array[offset + 3] & 0xff) << 24) + | (((long) array[offset + 4] & 0xff) << 32) + | (((long) array[offset + 5] & 0xff) << 40) + | (((long) array[offset + 6] & 0xff) << 48) + | (((long) array[offset + 7] & 0xff) << 56); + } + + static long getLongLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) + | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) + | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) + | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) + | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) + | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) + | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) + | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); + } + + static long getLongRB(byte[] array, int offset) { + return getLongB(array, offset); + } + + static long getLongRBU(byte[] array, int offset) { + return getLongBU(array, offset); + } + + static long getLongRL(byte[] array, int offset) { + return getLongL(array, offset); + } + + static long getLongRLU(byte[] array, int offset) { + return getLongLU(array, offset); + } + + public static int getIntLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + return ((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) + | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); + } + + public static char getCharB(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff) << 8) + | ((val[index + 1] & 0xff))); + } + + public static char getCharBR(byte[] val, int index) { + return Character.reverseBytes(getCharB(val, index)); + } + + public static char getCharL(byte[] val, int index) { + index <<= 1; + return (char)(((val[index ] & 0xff)) + | ((val[index + 1] & 0xff) << 8)); + } + + public static char getCharLR(byte[] val, int index) { + return Character.reverseBytes(getCharL(val, index)); + } + + public static char getCharBU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) + | ((UNSAFE.getByte(array, address + 1) & 0xff) )); + } + + public static char getCharLU(byte[] array, int offset) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) + | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + } +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java index 870422de25683..88b6886881363 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeStoreBench.java @@ -25,13 +25,9 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.lang.reflect.Field; import java.nio.ByteOrder; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -41,18 +37,19 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Thread) -@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS) -@Fork(value = 3, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) +@Fork(value = 1, jvmArgs = {"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"}) public class MergeStoreBench { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - final static VarHandle INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN); - final static VarHandle INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN); - final static VarHandle LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN); - final static VarHandle CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN); - final static VarHandle CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); + final static VarHandle + INT_L = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.LITTLE_ENDIAN), + INT_B = MethodHandles.byteArrayViewVarHandle(int[].class , ByteOrder.BIG_ENDIAN), + LONG_L = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN), + LONG_B = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN), + CHAR_L = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.LITTLE_ENDIAN), + CHAR_B = MethodHandles.byteArrayViewVarHandle(char[].class, ByteOrder.BIG_ENDIAN); final static int NUMBERS = 8192; @@ -89,115 +86,6 @@ public void setup() { * ``` */ - @Benchmark - public void getIntB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_B.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntLV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (int) INT_L.get(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRB(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRB(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRBU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRL(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += getIntRLU(bytes4, i * 4); - } - BH.consume(sum); - } - - @Benchmark - public void getIntRU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += Integer.reverseBytes( - UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4)); - } - BH.consume(sum); - } - - @Benchmark - public void getIntU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += UNSAFE.getInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4); - } - BH.consume(sum); - } - @Benchmark public void setIntB(Blackhole BH) { int sum = 0; @@ -211,613 +99,396 @@ public void setIntB(Blackhole BH) { @Benchmark public void setIntBU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntBV(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_B.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_B.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntL(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntL(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLU(Blackhole BH) { - int sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - INT_L.set(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + INT_L.set(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRB(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRB(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRBU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRBU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRL(bytes4, i * 4, ints[i]); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRL(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - setIntRLU(bytes4, i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + setIntRLU(bytes4, off, ints[i]); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - v = Integer.reverseBytes(v); - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Integer.reverseBytes(ints[i])); + off += 4; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setIntU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - int v = ints[i]; - UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 4, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_B.get(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < ints.length; i++) { - sum += (long) LONG_L.get(bytes8, i * 8); + int off = 0; + for (int i = ints.length - 1; i >= 0; i--) { + UNSAFE.putInt(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, ints[i]); + off += 4; } - BH.consume(sum); - } - - @Benchmark - public void getLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRB(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRBU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRL(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += getLongRLU(bytes8, i * 8); - } - BH.consume(sum); - } - - @Benchmark - public void getLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += Long.reverseBytes( - UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8)); - } - BH.consume(sum); - } - - @Benchmark - public void getLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - sum += UNSAFE.getLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8); - } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_B.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_B.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - LONG_L.set(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + LONG_L.set(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRB(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRB(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRBU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRBU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRL(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRL(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - setLongRLU(bytes8, i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + setLongRLU(bytes8, off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongRU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - v = Long.reverseBytes(v); - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, Long.reverseBytes(longs[i])); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark public void setLongU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - long v = longs[i]; - UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 8, v); - sum += v; - } - BH.consume(sum); - } - - @Benchmark - public void getCharB(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharB(bytes4, i); - sum += c; + int off = 0; + for (int i = longs.length - 1; i >= 0; i--) { + UNSAFE.putLong(bytes8, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, longs[i]); + off += 8; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_B.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; - } - BH.consume(sum); - } - - @Benchmark - public void getCharBU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharBU(bytes4, i); - sum += c; + public void setCharBS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortB(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharL(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharL(bytes4, i); - sum += c; - } - BH.consume(sum); - } - @Benchmark - public void getCharLU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = getCharLU(bytes4, i); - sum += c; + public void setCharBV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_B.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } - @Benchmark - public void getCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = (char) CHAR_L.get(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLS(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + putShortL(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void getCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - char c = UNSAFE.getChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2); - sum += c; + public void setCharLV(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + CHAR_L.set(bytes4, off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharBS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortB(bytes4, i * 2, c); - sum += c; + public void setCharC(Blackhole BH) { + int off = 0; + for (int i = chars.length - 1; i >= 0; i--) { + UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + off, chars[i]); + off += 2; } - BH.consume(sum); + BH.consume(off); } + /* + * putChars4 and putBytes4 Test whether four constant chars can be MergeStored + * + */ @Benchmark - public void setCharBV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_B.set(bytes4, i * 2, c); - sum += c; + public void putBytes4(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLS(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - putShortL(bytes4, i * 2, c); - sum += c; + public void putBytes4X(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4X(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharLV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - CHAR_L.set(bytes4, i * 2, c); - sum += c; + public void putBytes4U(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putBytes4U(bytes4, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark - public void setCharC(Blackhole BH) { - long sum = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - UNSAFE.putChar(bytes4, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * 2, c); - sum += c; + @SuppressWarnings("deprecation") + public void putBytes4GetBytes(Blackhole BH) { + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + "null".getBytes(0, 4, bytes4, off); + off += 4; } - BH.consume(sum); + BH.consume(off); } - /* - * putChars4 Test whether four constant chars can be MergeStored - * - */ @Benchmark public void putChars4B(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4B(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4B(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4BV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4BV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4BV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4L(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4L(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4L(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LU(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LU(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LU(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4LV(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4LV(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4LV(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4C(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4C(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4C(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); + BH.consume(off); } @Benchmark public void putChars4S(Blackhole BH) { - long sum = 0; - for (int i = 0; i < longs.length; i++) { - putChars4S(bytes8, i * 4); - sum += longs[i]; + int off = 0; + for (int i = 0; i < NUMBERS; i++) { + off = putChars4S(bytes8, off, 'n', 'u', 'l', 'l'); } - BH.consume(sum); - } - - static int getIntB(byte[] array, int offset) { - return ((array[offset ] & 0xff) << 24) - | ((array[offset + 1] & 0xff) << 16) - | ((array[offset + 2] & 0xff) << 8) - | ((array[offset + 3] & 0xff) ); - } - - static int getIntBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) << 24) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 3) & 0xff) ); - } - - static int getIntL(byte[] array, int offset) { - return ((array[offset ] & 0xff) ) - | ((array[offset + 1] & 0xff) << 8) - | ((array[offset + 2] & 0xff) << 16) - | ((array[offset + 3] & 0xff) << 24); - } - - static int getIntRB(byte[] array, int offset) { - return Integer.reverseBytes(getIntB(array, offset)); - } - - static int getIntRBU(byte[] array, int offset) { - return Integer.reverseBytes(getIntBU(array, offset)); - } - - static int getIntRL(byte[] array, int offset) { - return Integer.reverseBytes(getIntL(array, offset)); - } - - static int getIntRLU(byte[] array, int offset) { - return Integer.reverseBytes(getIntLU(array, offset)); + BH.consume(off); } static void setIntB(byte[] array, int offset, int value) { @@ -870,68 +541,6 @@ public static void setIntRBU(byte[] array, int offset, int value) { setIntBU(array, offset, value); } - static long getLongB(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) << 56) - | (((long) array[offset + 1] & 0xff) << 48) - | (((long) array[offset + 2] & 0xff) << 40) - | (((long) array[offset + 3] & 0xff) << 32) - | (((long) array[offset + 4] & 0xff) << 24) - | (((long) array[offset + 5] & 0xff) << 16) - | (((long) array[offset + 6] & 0xff) << 8) - | (((long) array[offset + 7] & 0xff) ); - } - - static long getLongBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address) & 0xff)) << 56) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) ); - } - - public static long getLongL(byte[] array, int offset) { - return (((long) array[offset ] & 0xff) ) - | (((long) array[offset + 1] & 0xff) << 8) - | (((long) array[offset + 2] & 0xff) << 16) - | (((long) array[offset + 3] & 0xff) << 24) - | (((long) array[offset + 4] & 0xff) << 32) - | (((long) array[offset + 5] & 0xff) << 40) - | (((long) array[offset + 6] & 0xff) << 48) - | (((long) array[offset + 7] & 0xff) << 56); - } - - static long getLongLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return (((long)(UNSAFE.getByte(array, address ) & 0xff)) ) - | (((long)(UNSAFE.getByte(array, address + 1) & 0xff)) << 8) - | (((long)(UNSAFE.getByte(array, address + 2) & 0xff)) << 16) - | (((long)(UNSAFE.getByte(array, address + 3) & 0xff)) << 24) - | (((long)(UNSAFE.getByte(array, address + 4) & 0xff)) << 32) - | (((long)(UNSAFE.getByte(array, address + 5) & 0xff)) << 40) - | (((long)(UNSAFE.getByte(array, address + 6) & 0xff)) << 48) - | (((long)(UNSAFE.getByte(array, address + 7) & 0xff)) << 56); - } - - static long getLongRB(byte[] array, int offset) { - return getLongB(array, offset); - } - - static long getLongRBU(byte[] array, int offset) { - return getLongBU(array, offset); - } - - static long getLongRL(byte[] array, int offset) { - return getLongL(array, offset); - } - - static long getLongRLU(byte[] array, int offset) { - return getLongLU(array, offset); - } - static void setLongB(byte[] array, int offset, long value) { array[offset] = (byte) (value >> 56); array[offset + 1] = (byte) (value >> 48); @@ -998,112 +607,95 @@ public static void setLongLU(byte[] array, int offset, long value) { UNSAFE.putByte(array, address + 7, (byte) (value >> 56)); } - public static int getIntLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; - return ((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 2) & 0xff) << 16) - | ((UNSAFE.getByte(array, address + 3) & 0xff) << 24); - } - - public static char getCharB(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff) << 8) - | ((val[index + 1] & 0xff))); - } - - public static char getCharBR(byte[] val, int index) { - return Character.reverseBytes(getCharB(val, index)); - } - - public static char getCharL(byte[] val, int index) { - index <<= 1; - return (char)(((val[index ] & 0xff)) - | ((val[index + 1] & 0xff) << 8)); + public int putBytes4(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset ] = (byte) c0; + bytes[offset + 1] = (byte) c1; + bytes[offset + 2] = (byte) c2; + bytes[offset + 3] = (byte) c3; + return offset + 4; } - public static char getCharLR(byte[] val, int index) { - return Character.reverseBytes(getCharL(val, index)); + public int putBytes4X(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + bytes[offset++] = (byte) c0; + bytes[offset++] = (byte) c1; + bytes[offset++] = (byte) c2; + bytes[offset++] = (byte) c3; + return offset; } - public static char getCharBU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) << 8) - | ((UNSAFE.getByte(array, address + 1) & 0xff) )); - } - - public static char getCharLU(byte[] array, int offset) { - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); - return (char) (((UNSAFE.getByte(array, address ) & 0xff) ) - | ((UNSAFE.getByte(array, address + 1) & 0xff) << 8)); + public int putBytes4U(byte[] bytes, int offset, int c0, int c1, int c2, int c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; + UNSAFE.putByte(bytes, address , (byte) c0); + UNSAFE.putByte(bytes, address + 1, (byte) c1); + UNSAFE.putByte(bytes, address + 2, (byte) c2); + UNSAFE.putByte(bytes, address + 3, (byte) c3); + return offset + 4; } - public void putChars4B(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4B(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortB(bytes, offset , c0); putShortB(bytes, offset + 1, c1); putShortB(bytes, offset + 2, c2); putShortB(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4BU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortBU(bytes, offset , c0); putShortBU(bytes, offset + 1, c1); putShortBU(bytes, offset + 2, c2); putShortBU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4BV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; - CHAR_B.set(bytes, offset , c0); + public int putChars4BV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + CHAR_B.set(bytes, offset , c0); CHAR_B.set(bytes, offset + 2, c1); CHAR_B.set(bytes, offset + 4, c2); CHAR_B.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4L(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4L(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortL(bytes, offset , c0); putShortL(bytes, offset + 1, c1); putShortL(bytes, offset + 2, c2); putShortL(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4LV(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - offset <<= 1; + public int putChars4LV(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { CHAR_L.set(bytes, offset , c0); CHAR_L.set(bytes, offset + 2, c1); CHAR_L.set(bytes, offset + 4, c2); CHAR_L.set(bytes, offset + 6, c3); + return offset + 8; } - public void putChars4LU(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; + public int putChars4LU(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { putShortLU(bytes, offset , c0); putShortLU(bytes, offset + 1, c1); putShortLU(bytes, offset + 2, c2); putShortLU(bytes, offset + 3, c3); + return offset + 4; } - public void putChars4C(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4C(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putChar(bytes, address , c0); UNSAFE.putChar(bytes, address + 2, c1); UNSAFE.putChar(bytes, address + 4, c2); UNSAFE.putChar(bytes, address + 6, c3); + return offset + 8; } - public void putChars4S(byte[] bytes, int offset) { - char c0 = 'n', c1 = 'u', c2 = 'l', c3 = 'l'; - final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + (offset << 1); + public int putChars4S(byte[] bytes, int offset, char c0, char c1, char c2, char c3) { + final long address = Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; UNSAFE.putShort(bytes, address , (short) c0); UNSAFE.putShort(bytes, address + 2, (short) c1); UNSAFE.putShort(bytes, address + 4, (short) c2); UNSAFE.putShort(bytes, address + 6, (short) c3); + return offset + 8; } private static void putShortB(byte[] val, int index, int c) { @@ -1129,4 +721,9 @@ public static void putShortLU(byte[] array, int offset, int c) { UNSAFE.putByte(array, address , (byte) (c )); UNSAFE.putByte(array, address + 1, (byte) (c >> 8)); } + + @Fork(value = 1, jvmArgs = { + "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:+UnlockDiagnosticVMOptions", "-XX:-MergeStores" + }) + public static class MergeStoresDisabled extends MergeStoreBench {} } diff --git a/test/micro/org/openjdk/bench/vm/compiler/MergeStores.java b/test/micro/org/openjdk/bench/vm/compiler/MergeStores.java index 809ec01f495ca..679502c121d51 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/MergeStores.java +++ b/test/micro/org/openjdk/bench/vm/compiler/MergeStores.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -743,8 +743,10 @@ public void store_unsafe_native_B8_L_offs_noalloc_unsafe() { UNSAFE.putLongUnaligned(null, native_adr + offset + 0, vL); } - @Fork(value = 1, jvmArgsPrepend = { - "-XX:+UnlockDiagnosticVMOptions", "-XX:-MergeStores" + @Fork(value = 1, jvmArgs = { + "-XX:+UnlockDiagnosticVMOptions", "-XX:-MergeStores", + "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "--add-exports", "java.base/jdk.internal.util=ALL-UNNAMED" }) public static class MergeStoresDisabled extends MergeStores {} } diff --git a/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java index 686706b46c48c..683c597cba949 100644 --- a/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java +++ b/test/micro/org/openjdk/bench/vm/compiler/WriteBarrier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.CompilerControl; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; @@ -42,7 +43,7 @@ @Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) @Fork(value = 3) -public class WriteBarrier { +public abstract class WriteBarrier { // For array references public static final int NUM_REFERENCES_SMALL = 32; @@ -50,15 +51,14 @@ public class WriteBarrier { // For array update tests private Object[] theArraySmall; - private Object[] realReferencesSmall; - private Object[] nullReferencesSmall; private int[] indicesSmall; private Object[] theArrayLarge; - private Object[] realReferencesLarge; - private Object[] nullReferencesLarge; private int[] indicesLarge; + private Object nullRef; + private Object realRef; + // For field update tests public Referencer head = null; public Referencer tail = null; @@ -84,13 +84,9 @@ void clear() { @Setup public void setup() { theArraySmall = new Object[NUM_REFERENCES_SMALL]; - realReferencesSmall = new Object[NUM_REFERENCES_SMALL]; - nullReferencesSmall = new Object[NUM_REFERENCES_SMALL]; indicesSmall = new int[NUM_REFERENCES_SMALL]; theArrayLarge = new Object[NUM_REFERENCES_LARGE]; - realReferencesLarge = new Object[NUM_REFERENCES_LARGE]; - nullReferencesLarge = new Object[NUM_REFERENCES_LARGE]; indicesLarge = new int[NUM_REFERENCES_LARGE]; m_w = (int) System.currentTimeMillis(); @@ -99,14 +95,14 @@ public void setup() { for (int i = 0; i < NUM_REFERENCES_SMALL; i++) { indicesSmall[i] = get_random() % (NUM_REFERENCES_SMALL - 1); - realReferencesSmall[i] = new Object(); } for (int i = 0; i < NUM_REFERENCES_LARGE; i++) { indicesLarge[i] = get_random() % (NUM_REFERENCES_LARGE - 1); - realReferencesLarge[i] = new Object(); } + realRef = new Object(); + // Build a small linked structure this.head = new Referencer(); this.tail = new Referencer(); @@ -124,31 +120,40 @@ private int get_random() { return Math.abs((m_z << 16) + m_w); /* 32-bit result */ } + // This and the other testArrayWriteBarrierFast benchmarks below should not + // be inlined into the JMH-generated harness method. If the methods were + // inlined, we might spill in the main loop (on x64) depending on very + // subtle conditions (such as whether LinuxPerfAsmProfiler is enabled!), + // which could distort the results. @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) public void testArrayWriteBarrierFastPathRealSmall() { for (int i = 0; i < NUM_REFERENCES_SMALL; i++) { - theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = realReferencesSmall[indicesSmall[i]]; + theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = realRef; } } @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) public void testArrayWriteBarrierFastPathNullSmall() { for (int i = 0; i < NUM_REFERENCES_SMALL; i++) { - theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = nullReferencesSmall[indicesSmall[i]]; + theArraySmall[indicesSmall[NUM_REFERENCES_SMALL - i - 1]] = nullRef; } } @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) public void testArrayWriteBarrierFastPathRealLarge() { for (int i = 0; i < NUM_REFERENCES_LARGE; i++) { - theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = realReferencesLarge[indicesLarge[i]]; + theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = realRef; } } @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) public void testArrayWriteBarrierFastPathNullLarge() { for (int i = 0; i < NUM_REFERENCES_LARGE; i++) { - theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = nullReferencesLarge[indicesLarge[i]]; + theArrayLarge[indicesLarge[NUM_REFERENCES_LARGE - i - 1]] = nullRef; } } @@ -160,4 +165,15 @@ public void testFieldWriteBarrierFastPath() { this.head.append(this.tail); this.tail.clear(); } + + // This run is useful to compare different GC barrier models without being + // affected by C2 unrolling the main loop differently for each model. + @Fork(value = 3, jvmArgs = {"-XX:LoopUnrollLimit=1"}) + public static class WithoutUnrolling extends WriteBarrier {} + + // This run is useful to study the interaction of GC barriers and loop + // unrolling. Check that the main loop in the testArray benchmarks is + // unrolled (or not) as expected for the studied GC barrier model. + @Fork(value = 3) + public static class WithDefaultUnrolling extends WriteBarrier {} } diff --git a/test/setup_aot/TestSetupAOT.java b/test/setup_aot/TestSetupAOT.java new file mode 100644 index 0000000000000..1cae8bae2461f --- /dev/null +++ b/test/setup_aot/TestSetupAOT.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.spi.ToolProvider; + +// This program is executed by make/RunTests.gmk to support running HotSpot tests +// in the "AOT mode", for example: +// +// make test JTREG=AOT_JDK=true TEST=open/test/hotspot/jtreg/runtime/invokedynamic +// +// All JDK classes touched by this program will be stored into a customized AOT cache. +// This is a larger set of classes than those stored in the JDK's default CDS archive. +// This customized cache can also have additional optimizations that are not +// enabled in the default CDS archive. For example, AOT-linked classes and lambda +// expressions. In the future, it can also contain AOT profiles and AOT compiled methods. +// +// We can use this customized AOT cache to run various HotSpot tests to improve +// coverage on AOT. +// +// Note that make/RunTests.gmk loads this class using an implicit classpath of ".", so +// this class will be excluded from the customized AOT cache. As a result, +// the customized AOT cache contains *only* classes from the JDK itself. + +public class TestSetupAOT { + public static void main(String[] args) throws Throwable { + String[] tools = { + "javac", "javap", "jlink", "jar", + }; + // TODO: we should do more substantial work than just running with "--help". + // E.g., use javac to compile a program. + for (String tool : tools) { + ToolProvider t = ToolProvider.findFirst(tool) + .orElseThrow(() -> new RuntimeException(tool + " not found")); + t.run(System.out, System.out, "--help"); + } + } +}